aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore79
-rw-r--r--.travis.yml2
-rw-r--r--CMakeLists.txt25
-rw-r--r--Makefile26
-rw-r--r--README.md289
-rw-r--r--config/CMakeLists.txt42
-rw-r--r--config/config.h.in217
-rw-r--r--config/pathdef.c.in7
-rw-r--r--scripts/common.sh50
-rw-r--r--scripts/get-libuv.sh16
-rw-r--r--src/CMakeLists.txt33
-rw-r--r--src/arabic.c1134
-rw-r--r--src/arabic.h258
-rw-r--r--src/ascii.h96
-rw-r--r--src/blowfish.c637
-rw-r--r--src/buffer.c4517
-rw-r--r--src/charset.c1653
-rw-r--r--src/diff.c2296
-rw-r--r--src/digraph.c2074
-rw-r--r--src/edit.c8419
-rw-r--r--src/eval.c20483
-rw-r--r--src/ex_cmds.c5679
-rw-r--r--src/ex_cmds.h1191
-rw-r--r--src/ex_cmds2.c3613
-rw-r--r--src/ex_docmd.c9398
-rw-r--r--src/ex_eval.c2113
-rw-r--r--src/ex_getln.c5486
-rw-r--r--src/farsi.c2183
-rw-r--r--src/farsi.h226
-rw-r--r--src/fileio.c8496
-rw-r--r--src/fold.c3104
-rw-r--r--src/getchar.c4273
-rw-r--r--src/globals.h1199
-rw-r--r--src/hangulin.c1518
-rw-r--r--src/hardcopy.c3258
-rw-r--r--src/hashtab.c416
-rw-r--r--src/if_cscope.c2352
-rw-r--r--src/if_cscope.h72
-rw-r--r--src/keymap.h499
-rw-r--r--src/macros.h190
-rw-r--r--src/main.c2382
-rw-r--r--src/mark.c1563
-rw-r--r--src/mbyte.c4217
-rw-r--r--src/memfile.c1366
-rw-r--r--src/memline.c4681
-rw-r--r--src/menu.c1646
-rw-r--r--src/message.c4004
-rw-r--r--src/misc1.c9097
-rw-r--r--src/misc2.c5505
-rw-r--r--src/move.c2215
-rw-r--r--src/normal.c7585
-rw-r--r--src/ops.c5275
-rw-r--r--src/option.c8298
-rw-r--r--src/option.h768
-rw-r--r--src/os_unix.c4008
-rw-r--r--src/os_unix.h372
-rw-r--r--src/os_unixx.h122
-rw-r--r--src/po/Makefile292
-rw-r--r--src/po/af.po5393
-rw-r--r--src/po/ca.po6201
-rw-r--r--src/po/check.vim88
-rw-r--r--src/po/cleanup.vim19
-rw-r--r--src/po/cs.cp1250.po4664
-rw-r--r--src/po/cs.po4664
-rw-r--r--src/po/de.po6117
-rw-r--r--src/po/en_GB.po290
-rw-r--r--src/po/eo.po6825
-rw-r--r--src/po/es.po8279
-rw-r--r--src/po/fi.po6526
-rw-r--r--src/po/fr.po7091
-rw-r--r--src/po/ga.po6503
-rw-r--r--src/po/it.po6803
-rw-r--r--src/po/ja.euc-jp.po6808
-rw-r--r--src/po/ja.po6808
-rw-r--r--src/po/ja.sjis.po6808
-rw-r--r--src/po/ko.UTF-8.po6447
-rw-r--r--src/po/ko.po6447
-rw-r--r--src/po/nb.po6166
-rw-r--r--src/po/nl.po5852
-rw-r--r--src/po/no.po6166
-rw-r--r--src/po/pl.UTF-8.po6904
-rw-r--r--src/po/pl.cp1250.po6904
-rw-r--r--src/po/pl.po6904
-rw-r--r--src/po/pt_BR.po6236
-rw-r--r--src/po/ru.cp1251.po6893
-rw-r--r--src/po/ru.po6893
-rw-r--r--src/po/sjiscorr.c50
-rw-r--r--src/po/sk.cp1250.po5821
-rw-r--r--src/po/sk.po5821
-rw-r--r--src/po/sv.po6148
-rw-r--r--src/po/uk.cp1251.po7027
-rw-r--r--src/po/uk.po7027
-rw-r--r--src/po/vi.po5196
-rw-r--r--src/po/zh_CN.UTF-8.po6139
-rw-r--r--src/po/zh_CN.cp936.po6140
-rw-r--r--src/po/zh_CN.po6140
-rw-r--r--src/po/zh_TW.UTF-8.po5282
-rw-r--r--src/po/zh_TW.po5275
-rw-r--r--src/popupmnu.c617
-rw-r--r--src/proto.h137
-rw-r--r--src/proto/blowfish.pro10
-rw-r--r--src/proto/buffer.pro81
-rw-r--r--src/proto/charset.pro64
-rw-r--r--src/proto/diff.pro30
-rw-r--r--src/proto/digraph.pro9
-rw-r--r--src/proto/edit.pro46
-rw-r--r--src/proto/eval.pro150
-rw-r--r--src/proto/ex_cmds.pro72
-rw-r--r--src/proto/ex_cmds2.pro93
-rw-r--r--src/proto/ex_docmd.pro69
-rw-r--r--src/proto/ex_eval.pro38
-rw-r--r--src/proto/ex_getln.pro66
-rw-r--r--src/proto/fileio.pro82
-rw-r--r--src/proto/fold.pro50
-rw-r--r--src/proto/getchar.pro74
-rw-r--r--src/proto/hangulin.pro9
-rw-r--r--src/proto/hardcopy.pro21
-rw-r--r--src/proto/hashtab.pro15
-rw-r--r--src/proto/if_cscope.pro13
-rw-r--r--src/proto/main.pro27
-rw-r--r--src/proto/mark.pro34
-rw-r--r--src/proto/mbyte.pro100
-rw-r--r--src/proto/memfile.pro18
-rw-r--r--src/proto/memline.pro41
-rw-r--r--src/proto/menu.pro23
-rw-r--r--src/proto/message.pro80
-rw-r--r--src/proto/misc1.pro117
-rw-r--r--src/proto/misc2.pro133
-rw-r--r--src/proto/move.pro41
-rw-r--r--src/proto/normal.pro29
-rw-r--r--src/proto/ops.pro66
-rw-r--r--src/proto/option.pro74
-rw-r--r--src/proto/os_unix.pro80
-rw-r--r--src/proto/popupmnu.pro8
-rw-r--r--src/proto/quickfix.pro33
-rw-r--r--src/proto/regexp.pro24
-rw-r--r--src/proto/screen.pro66
-rw-r--r--src/proto/search.pro49
-rw-r--r--src/proto/sha256.pro12
-rw-r--r--src/proto/spell.pro30
-rw-r--r--src/proto/syntax.pro58
-rw-r--r--src/proto/tag.pro15
-rw-r--r--src/proto/term.pro65
-rw-r--r--src/proto/ui.pro67
-rw-r--r--src/proto/undo.pro31
-rw-r--r--src/proto/version.pro10
-rw-r--r--src/proto/window.pro93
-rw-r--r--src/quickfix.c3750
-rw-r--r--src/regexp.c7178
-rw-r--r--src/regexp.h152
-rw-r--r--src/regexp_nfa.c6550
-rw-r--r--src/screen.c7936
-rw-r--r--src/search.c4717
-rw-r--r--src/sha256.c417
-rw-r--r--src/spell.c14426
-rw-r--r--src/structs.h2047
-rw-r--r--src/syntax.c7924
-rw-r--r--src/tag.c3107
-rw-r--r--src/term.c4787
-rw-r--r--src/term.h156
-rw-r--r--src/testdir/Makefile110
-rw-r--r--src/testdir/dotest.in3
-rw-r--r--src/testdir/sautest/autoload/footest.vim5
-rw-r--r--src/testdir/test1.in57
-rw-r--r--src/testdir/test1.ok1
-rw-r--r--src/testdir/test10.in114
-rw-r--r--src/testdir/test10.ok23
-rw-r--r--src/testdir/test100.in42
-rw-r--r--src/testdir/test100.ok41
-rw-r--r--src/testdir/test101.in45
-rw-r--r--src/testdir/test101.ok11
-rw-r--r--src/testdir/test102.in12
-rw-r--r--src/testdir/test102.ok3
-rw-r--r--src/testdir/test103.in37
-rw-r--r--src/testdir/test103.ok2
-rw-r--r--src/testdir/test10a.in73
-rw-r--r--src/testdir/test10a.ok23
-rw-r--r--src/testdir/test11.in84
-rw-r--r--src/testdir/test11.ok61
-rw-r--r--src/testdir/test12.in52
-rw-r--r--src/testdir/test12.ok10
-rw-r--r--src/testdir/test13.in58
-rw-r--r--src/testdir/test13.ok30
-rw-r--r--src/testdir/test14.in99
-rw-r--r--src/testdir/test14.ok26
-rw-r--r--src/testdir/test15.in136
-rw-r--r--src/testdir/test15.ok111
-rw-r--r--src/testdir/test16.in15
-rw-r--r--src/testdir/test16.ok2
-rw-r--r--src/testdir/test17.in141
-rw-r--r--src/testdir/test17.ok33
-rw-r--r--src/testdir/test17a.in3
-rw-r--r--src/testdir/test18.in16
-rw-r--r--src/testdir/test18.ok4
-rw-r--r--src/testdir/test19.in33
-rw-r--r--src/testdir/test19.ok10
-rw-r--r--src/testdir/test2.in29
-rw-r--r--src/testdir/test2.ok4
-rw-r--r--src/testdir/test20.in28
-rw-r--r--src/testdir/test20.ok10
-rw-r--r--src/testdir/test21.in19
-rw-r--r--src/testdir/test21.ok2
-rw-r--r--src/testdir/test22.in13
-rw-r--r--src/testdir/test22.ok4
-rw-r--r--src/testdir/test23.in15
-rw-r--r--src/testdir/test23.ok2
-rw-r--r--src/testdir/test24.inbin0 -> 1301 bytes
-rw-r--r--src/testdir/test24.ok32
-rw-r--r--src/testdir/test25.in31
-rw-r--r--src/testdir/test25.ok1
-rw-r--r--src/testdir/test26.in44
-rw-r--r--src/testdir/test26.ok10
-rw-r--r--src/testdir/test27.in20
-rw-r--r--src/testdir/test27.ok2
-rw-r--r--src/testdir/test28.inbin0 -> 364 bytes
-rw-r--r--src/testdir/test28.ok2
-rw-r--r--src/testdir/test29.in202
-rw-r--r--src/testdir/test29.ok88
-rw-r--r--src/testdir/test3.in2056
-rw-r--r--src/testdir/test3.ok1820
-rw-r--r--src/testdir/test30.in222
-rw-r--r--src/testdir/test30.ok121
-rw-r--r--src/testdir/test31.in75
-rw-r--r--src/testdir/test31.ok12
-rw-r--r--src/testdir/test32.in60
-rw-r--r--src/testdir/test32.ok15
-rw-r--r--src/testdir/test33.in34
-rw-r--r--src/testdir/test33.ok23
-rw-r--r--src/testdir/test34.in87
-rw-r--r--src/testdir/test34.ok10
-rw-r--r--src/testdir/test35.in21
-rw-r--r--src/testdir/test35.ok4
-rw-r--r--src/testdir/test36.in105
-rw-r--r--src/testdir/test36.ok96
-rw-r--r--src/testdir/test37.in116
-rw-r--r--src/testdir/test37.ok33
-rw-r--r--src/testdir/test38.in35
-rw-r--r--src/testdir/test38.ok13
-rw-r--r--src/testdir/test39.in83
-rw-r--r--src/testdir/test39.okbin0 -> 432 bytes
-rw-r--r--src/testdir/test4.in31
-rw-r--r--src/testdir/test4.ok17
-rw-r--r--src/testdir/test40.in63
-rw-r--r--src/testdir/test40.ok11
-rw-r--r--src/testdir/test41.in24
-rw-r--r--src/testdir/test41.ok3
-rw-r--r--src/testdir/test42.inbin0 -> 2368 bytes
-rw-r--r--src/testdir/test42.okbin0 -> 409 bytes
-rw-r--r--src/testdir/test43.in34
-rw-r--r--src/testdir/test43.ok11
-rw-r--r--src/testdir/test44.in68
-rw-r--r--src/testdir/test44.ok24
-rw-r--r--src/testdir/test45.in80
-rw-r--r--src/testdir/test45.ok18
-rw-r--r--src/testdir/test46.in27
-rw-r--r--src/testdir/test46.ok13
-rw-r--r--src/testdir/test47.in62
-rw-r--r--src/testdir/test47.ok4
-rw-r--r--src/testdir/test48.in78
-rw-r--r--src/testdir/test48.ok22
-rw-r--r--src/testdir/test49.in30
-rw-r--r--src/testdir/test49.ok99
-rw-r--r--src/testdir/test49.vim9852
-rw-r--r--src/testdir/test5.in29
-rw-r--r--src/testdir/test5.ok9
-rw-r--r--src/testdir/test50.in90
-rw-r--r--src/testdir/test50.ok14
-rw-r--r--src/testdir/test51.in36
-rw-r--r--src/testdir/test51.ok20
-rw-r--r--src/testdir/test52.in65
-rw-r--r--src/testdir/test52.ok18
-rw-r--r--src/testdir/test53.in84
-rw-r--r--src/testdir/test53.ok33
-rw-r--r--src/testdir/test54.in22
-rw-r--r--src/testdir/test54.ok1
-rw-r--r--src/testdir/test55.in402
-rw-r--r--src/testdir/test55.ok126
-rw-r--r--src/testdir/test56.in21
-rw-r--r--src/testdir/test56.ok2
-rw-r--r--src/testdir/test57.in500
-rw-r--r--src/testdir/test57.ok459
-rw-r--r--src/testdir/test58.in639
-rw-r--r--src/testdir/test58.ok283
-rw-r--r--src/testdir/test59.in626
-rw-r--r--src/testdir/test59.ok270
-rw-r--r--src/testdir/test6.in24
-rw-r--r--src/testdir/test6.ok18
-rw-r--r--src/testdir/test60.in600
-rw-r--r--src/testdir/test60.ok206
-rw-r--r--src/testdir/test60.vim98
-rw-r--r--src/testdir/test61.in113
-rw-r--r--src/testdir/test61.ok49
-rw-r--r--src/testdir/test62.in190
-rw-r--r--src/testdir/test62.ok88
-rw-r--r--src/testdir/test63.in157
-rw-r--r--src/testdir/test63.ok11
-rw-r--r--src/testdir/test64.in633
-rw-r--r--src/testdir/test64.ok1084
-rw-r--r--src/testdir/test65.in95
-rw-r--r--src/testdir/test65.ok73
-rw-r--r--src/testdir/test66.in33
-rw-r--r--src/testdir/test66.ok16
-rw-r--r--src/testdir/test67.in33
-rw-r--r--src/testdir/test67.ok10
-rw-r--r--src/testdir/test68.in131
-rw-r--r--src/testdir/test68.ok77
-rw-r--r--src/testdir/test69.in175
-rw-r--r--src/testdir/test69.ok159
-rw-r--r--src/testdir/test7.in26
-rw-r--r--src/testdir/test7.ok12
-rw-r--r--src/testdir/test70.in63
-rw-r--r--src/testdir/test70.ok6
-rw-r--r--src/testdir/test71.in67
-rw-r--r--src/testdir/test71.ok10
-rw-r--r--src/testdir/test71a.in14
-rw-r--r--src/testdir/test72.in115
-rw-r--r--src/testdir/test72.ok27
-rw-r--r--src/testdir/test73.in176
-rw-r--r--src/testdir/test73.ok21
-rw-r--r--src/testdir/test74.in36
-rw-r--r--src/testdir/test74.ok5
-rw-r--r--src/testdir/test75.in24
-rw-r--r--src/testdir/test75.ok6
-rw-r--r--src/testdir/test76.in46
-rw-r--r--src/testdir/test76.ok4
-rw-r--r--src/testdir/test77.in30
-rw-r--r--src/testdir/test77.ok1
-rw-r--r--src/testdir/test78.in46
-rw-r--r--src/testdir/test78.ok3
-rw-r--r--src/testdir/test79.inbin0 -> 2713 bytes
-rw-r--r--src/testdir/test79.okbin0 -> 421 bytes
-rw-r--r--src/testdir/test8.in46
-rw-r--r--src/testdir/test8.ok7
-rw-r--r--src/testdir/test80.in199
-rw-r--r--src/testdir/test80.ok128
-rw-r--r--src/testdir/test81.in22
-rw-r--r--src/testdir/test81.ok6
-rw-r--r--src/testdir/test82.in103
-rw-r--r--src/testdir/test82.ok5
-rw-r--r--src/testdir/test83-tags22
-rw-r--r--src/testdir/test83-tags3102
-rw-r--r--src/testdir/test83.in76
-rw-r--r--src/testdir/test83.ok4
-rw-r--r--src/testdir/test84.in35
-rw-r--r--src/testdir/test84.ok3
-rw-r--r--src/testdir/test85.in85
-rw-r--r--src/testdir/test85.ok7
-rw-r--r--src/testdir/test86.in1429
-rw-r--r--src/testdir/test86.ok1266
-rw-r--r--src/testdir/test87.in1406
-rw-r--r--src/testdir/test87.ok1266
-rw-r--r--src/testdir/test88.in88
-rw-r--r--src/testdir/test88.ok24
-rw-r--r--src/testdir/test89.in71
-rw-r--r--src/testdir/test89.ok28
-rw-r--r--src/testdir/test9.in12
-rw-r--r--src/testdir/test9.ok2
-rw-r--r--src/testdir/test90.in53
-rw-r--r--src/testdir/test90.ok6
-rw-r--r--src/testdir/test91.in111
-rw-r--r--src/testdir/test91.ok48
-rw-r--r--src/testdir/test92.in48
-rw-r--r--src/testdir/test92.ok26
-rw-r--r--src/testdir/test93.in48
-rw-r--r--src/testdir/test93.ok26
-rw-r--r--src/testdir/test94.in95
-rw-r--r--src/testdir/test94.ok20
-rw-r--r--src/testdir/test95.in135
-rw-r--r--src/testdir/test95.ok122
-rw-r--r--src/testdir/test96.in142
-rw-r--r--src/testdir/test96.ok9
-rw-r--r--src/testdir/test97.in17
-rw-r--r--src/testdir/test97.ok5
-rw-r--r--src/testdir/test98.in43
-rw-r--r--src/testdir/test98.ok1
-rw-r--r--src/testdir/test99.in68
-rw-r--r--src/testdir/test99.ok24
-rw-r--r--src/testdir/unix.vim3
-rw-r--r--src/ui.c1176
-rw-r--r--src/undo.c2973
-rw-r--r--src/version.c1001
-rw-r--r--src/version.h40
-rw-r--r--src/vim.h1605
-rw-r--r--src/window.c5640
-rw-r--r--third-party/libuv/.gitignore62
-rw-r--r--third-party/libuv/.mailmap (renamed from .mailmap)0
-rw-r--r--third-party/libuv/AUTHORS (renamed from AUTHORS)0
-rw-r--r--third-party/libuv/CONTRIBUTING.md (renamed from CONTRIBUTING.md)0
-rw-r--r--third-party/libuv/ChangeLog (renamed from ChangeLog)0
-rw-r--r--third-party/libuv/LICENSE (renamed from LICENSE)0
-rw-r--r--third-party/libuv/Makefile.am (renamed from Makefile.am)0
-rw-r--r--third-party/libuv/Makefile.mingw (renamed from Makefile.mingw)0
-rw-r--r--third-party/libuv/README.md143
-rwxr-xr-xthird-party/libuv/android-configure (renamed from android-configure)0
-rwxr-xr-xthird-party/libuv/autogen.sh (renamed from autogen.sh)0
-rwxr-xr-xthird-party/libuv/checksparse.sh (renamed from checksparse.sh)0
-rw-r--r--third-party/libuv/common.gypi (renamed from common.gypi)0
-rw-r--r--third-party/libuv/configure.ac (renamed from configure.ac)0
-rwxr-xr-xthird-party/libuv/gyp_uv.py (renamed from gyp_uv.py)0
-rw-r--r--third-party/libuv/include/pthread-fixes.h (renamed from include/pthread-fixes.h)0
-rw-r--r--third-party/libuv/include/stdint-msvc2008.h (renamed from include/stdint-msvc2008.h)0
-rw-r--r--third-party/libuv/include/tree.h (renamed from include/tree.h)0
-rw-r--r--third-party/libuv/include/uv-bsd.h (renamed from include/uv-bsd.h)0
-rw-r--r--third-party/libuv/include/uv-darwin.h (renamed from include/uv-darwin.h)0
-rw-r--r--third-party/libuv/include/uv-errno.h (renamed from include/uv-errno.h)0
-rw-r--r--third-party/libuv/include/uv-linux.h (renamed from include/uv-linux.h)0
-rw-r--r--third-party/libuv/include/uv-sunos.h (renamed from include/uv-sunos.h)0
-rw-r--r--third-party/libuv/include/uv-unix.h (renamed from include/uv-unix.h)0
-rw-r--r--third-party/libuv/include/uv-win.h (renamed from include/uv-win.h)0
-rw-r--r--third-party/libuv/include/uv.h (renamed from include/uv.h)0
-rw-r--r--third-party/libuv/libuv.pc.in (renamed from libuv.pc.in)0
-rw-r--r--third-party/libuv/m4/.gitignore (renamed from m4/.gitignore)0
-rw-r--r--third-party/libuv/m4/dtrace.m4 (renamed from m4/dtrace.m4)0
-rw-r--r--third-party/libuv/samples/.gitignore (renamed from samples/.gitignore)0
-rw-r--r--third-party/libuv/samples/socks5-proxy/.gitignore (renamed from samples/socks5-proxy/.gitignore)0
-rw-r--r--third-party/libuv/samples/socks5-proxy/LICENSE (renamed from samples/socks5-proxy/LICENSE)0
-rw-r--r--third-party/libuv/samples/socks5-proxy/Makefile (renamed from samples/socks5-proxy/Makefile)0
-rw-r--r--third-party/libuv/samples/socks5-proxy/build.gyp (renamed from samples/socks5-proxy/build.gyp)0
-rw-r--r--third-party/libuv/samples/socks5-proxy/client.c (renamed from samples/socks5-proxy/client.c)0
-rw-r--r--third-party/libuv/samples/socks5-proxy/defs.h (renamed from samples/socks5-proxy/defs.h)0
-rw-r--r--third-party/libuv/samples/socks5-proxy/getopt.c (renamed from samples/socks5-proxy/getopt.c)0
-rw-r--r--third-party/libuv/samples/socks5-proxy/main.c (renamed from samples/socks5-proxy/main.c)0
-rw-r--r--third-party/libuv/samples/socks5-proxy/s5.c (renamed from samples/socks5-proxy/s5.c)0
-rw-r--r--third-party/libuv/samples/socks5-proxy/s5.h (renamed from samples/socks5-proxy/s5.h)0
-rw-r--r--third-party/libuv/samples/socks5-proxy/server.c (renamed from samples/socks5-proxy/server.c)0
-rw-r--r--third-party/libuv/samples/socks5-proxy/util.c (renamed from samples/socks5-proxy/util.c)0
-rw-r--r--third-party/libuv/src/fs-poll.c (renamed from src/fs-poll.c)0
-rw-r--r--third-party/libuv/src/inet.c (renamed from src/inet.c)0
-rw-r--r--third-party/libuv/src/queue.h (renamed from src/queue.h)0
-rw-r--r--third-party/libuv/src/unix/aix.c (renamed from src/unix/aix.c)0
-rw-r--r--third-party/libuv/src/unix/async.c (renamed from src/unix/async.c)0
-rw-r--r--third-party/libuv/src/unix/atomic-ops.h (renamed from src/unix/atomic-ops.h)0
-rw-r--r--third-party/libuv/src/unix/core.c (renamed from src/unix/core.c)0
-rw-r--r--third-party/libuv/src/unix/darwin-proctitle.c (renamed from src/unix/darwin-proctitle.c)0
-rw-r--r--third-party/libuv/src/unix/darwin.c (renamed from src/unix/darwin.c)0
-rw-r--r--third-party/libuv/src/unix/dl.c (renamed from src/unix/dl.c)0
-rw-r--r--third-party/libuv/src/unix/freebsd.c (renamed from src/unix/freebsd.c)0
-rw-r--r--third-party/libuv/src/unix/fs.c (renamed from src/unix/fs.c)0
-rw-r--r--third-party/libuv/src/unix/fsevents.c (renamed from src/unix/fsevents.c)0
-rw-r--r--third-party/libuv/src/unix/getaddrinfo.c (renamed from src/unix/getaddrinfo.c)0
-rw-r--r--third-party/libuv/src/unix/internal.h (renamed from src/unix/internal.h)0
-rw-r--r--third-party/libuv/src/unix/kqueue.c (renamed from src/unix/kqueue.c)0
-rw-r--r--third-party/libuv/src/unix/linux-core.c (renamed from src/unix/linux-core.c)0
-rw-r--r--third-party/libuv/src/unix/linux-inotify.c (renamed from src/unix/linux-inotify.c)0
-rw-r--r--third-party/libuv/src/unix/linux-syscalls.c (renamed from src/unix/linux-syscalls.c)0
-rw-r--r--third-party/libuv/src/unix/linux-syscalls.h (renamed from src/unix/linux-syscalls.h)0
-rw-r--r--third-party/libuv/src/unix/loop-watcher.c (renamed from src/unix/loop-watcher.c)0
-rw-r--r--third-party/libuv/src/unix/loop.c (renamed from src/unix/loop.c)0
-rw-r--r--third-party/libuv/src/unix/netbsd.c (renamed from src/unix/netbsd.c)0
-rw-r--r--third-party/libuv/src/unix/openbsd.c (renamed from src/unix/openbsd.c)0
-rw-r--r--third-party/libuv/src/unix/pipe.c (renamed from src/unix/pipe.c)0
-rw-r--r--third-party/libuv/src/unix/poll.c (renamed from src/unix/poll.c)0
-rw-r--r--third-party/libuv/src/unix/process.c (renamed from src/unix/process.c)0
-rw-r--r--third-party/libuv/src/unix/proctitle.c (renamed from src/unix/proctitle.c)0
-rw-r--r--third-party/libuv/src/unix/pthread-fixes.c (renamed from src/unix/pthread-fixes.c)0
-rw-r--r--third-party/libuv/src/unix/signal.c (renamed from src/unix/signal.c)0
-rw-r--r--third-party/libuv/src/unix/spinlock.h (renamed from src/unix/spinlock.h)0
-rw-r--r--third-party/libuv/src/unix/stream.c (renamed from src/unix/stream.c)0
-rw-r--r--third-party/libuv/src/unix/sunos.c (renamed from src/unix/sunos.c)0
-rw-r--r--third-party/libuv/src/unix/tcp.c (renamed from src/unix/tcp.c)0
-rw-r--r--third-party/libuv/src/unix/thread.c (renamed from src/unix/thread.c)0
-rw-r--r--third-party/libuv/src/unix/threadpool.c (renamed from src/unix/threadpool.c)0
-rw-r--r--third-party/libuv/src/unix/timer.c (renamed from src/unix/timer.c)0
-rw-r--r--third-party/libuv/src/unix/tty.c (renamed from src/unix/tty.c)0
-rw-r--r--third-party/libuv/src/unix/udp.c (renamed from src/unix/udp.c)0
-rw-r--r--third-party/libuv/src/unix/uv-dtrace.d (renamed from src/unix/uv-dtrace.d)0
-rw-r--r--third-party/libuv/src/uv-common.c (renamed from src/uv-common.c)0
-rw-r--r--third-party/libuv/src/uv-common.h (renamed from src/uv-common.h)0
-rw-r--r--third-party/libuv/src/version.c63
-rw-r--r--third-party/libuv/src/win/async.c (renamed from src/win/async.c)0
-rw-r--r--third-party/libuv/src/win/atomicops-inl.h (renamed from src/win/atomicops-inl.h)0
-rw-r--r--third-party/libuv/src/win/core.c (renamed from src/win/core.c)0
-rw-r--r--third-party/libuv/src/win/dl.c (renamed from src/win/dl.c)0
-rw-r--r--third-party/libuv/src/win/error.c (renamed from src/win/error.c)0
-rw-r--r--third-party/libuv/src/win/fs-event.c (renamed from src/win/fs-event.c)0
-rw-r--r--third-party/libuv/src/win/fs.c (renamed from src/win/fs.c)0
-rw-r--r--third-party/libuv/src/win/getaddrinfo.c (renamed from src/win/getaddrinfo.c)0
-rw-r--r--third-party/libuv/src/win/handle-inl.h (renamed from src/win/handle-inl.h)0
-rw-r--r--third-party/libuv/src/win/handle.c (renamed from src/win/handle.c)0
-rw-r--r--third-party/libuv/src/win/internal.h (renamed from src/win/internal.h)0
-rw-r--r--third-party/libuv/src/win/loop-watcher.c (renamed from src/win/loop-watcher.c)0
-rw-r--r--third-party/libuv/src/win/pipe.c (renamed from src/win/pipe.c)0
-rw-r--r--third-party/libuv/src/win/poll.c (renamed from src/win/poll.c)0
-rw-r--r--third-party/libuv/src/win/process-stdio.c (renamed from src/win/process-stdio.c)0
-rw-r--r--third-party/libuv/src/win/process.c (renamed from src/win/process.c)0
-rw-r--r--third-party/libuv/src/win/req-inl.h (renamed from src/win/req-inl.h)0
-rw-r--r--third-party/libuv/src/win/req.c (renamed from src/win/req.c)0
-rw-r--r--third-party/libuv/src/win/signal.c (renamed from src/win/signal.c)0
-rw-r--r--third-party/libuv/src/win/stream-inl.h (renamed from src/win/stream-inl.h)0
-rw-r--r--third-party/libuv/src/win/stream.c (renamed from src/win/stream.c)0
-rw-r--r--third-party/libuv/src/win/tcp.c (renamed from src/win/tcp.c)0
-rw-r--r--third-party/libuv/src/win/thread.c (renamed from src/win/thread.c)0
-rw-r--r--third-party/libuv/src/win/threadpool.c (renamed from src/win/threadpool.c)0
-rw-r--r--third-party/libuv/src/win/timer.c (renamed from src/win/timer.c)0
-rw-r--r--third-party/libuv/src/win/tty.c (renamed from src/win/tty.c)0
-rw-r--r--third-party/libuv/src/win/udp.c (renamed from src/win/udp.c)0
-rw-r--r--third-party/libuv/src/win/util.c (renamed from src/win/util.c)0
-rw-r--r--third-party/libuv/src/win/winapi.c (renamed from src/win/winapi.c)0
-rw-r--r--third-party/libuv/src/win/winapi.h (renamed from src/win/winapi.h)0
-rw-r--r--third-party/libuv/src/win/winsock.c (renamed from src/win/winsock.c)0
-rw-r--r--third-party/libuv/src/win/winsock.h (renamed from src/win/winsock.h)0
-rw-r--r--third-party/libuv/test/benchmark-async-pummel.c (renamed from test/benchmark-async-pummel.c)0
-rw-r--r--third-party/libuv/test/benchmark-async.c (renamed from test/benchmark-async.c)0
-rw-r--r--third-party/libuv/test/benchmark-fs-stat.c (renamed from test/benchmark-fs-stat.c)0
-rw-r--r--third-party/libuv/test/benchmark-getaddrinfo.c (renamed from test/benchmark-getaddrinfo.c)0
-rw-r--r--third-party/libuv/test/benchmark-list.h (renamed from test/benchmark-list.h)0
-rw-r--r--third-party/libuv/test/benchmark-loop-count.c (renamed from test/benchmark-loop-count.c)0
-rw-r--r--third-party/libuv/test/benchmark-million-async.c (renamed from test/benchmark-million-async.c)0
-rw-r--r--third-party/libuv/test/benchmark-million-timers.c (renamed from test/benchmark-million-timers.c)0
-rw-r--r--third-party/libuv/test/benchmark-multi-accept.c (renamed from test/benchmark-multi-accept.c)0
-rw-r--r--third-party/libuv/test/benchmark-ping-pongs.c (renamed from test/benchmark-ping-pongs.c)0
-rw-r--r--third-party/libuv/test/benchmark-pound.c (renamed from test/benchmark-pound.c)0
-rw-r--r--third-party/libuv/test/benchmark-pump.c (renamed from test/benchmark-pump.c)0
-rw-r--r--third-party/libuv/test/benchmark-sizes.c (renamed from test/benchmark-sizes.c)0
-rw-r--r--third-party/libuv/test/benchmark-spawn.c (renamed from test/benchmark-spawn.c)0
-rw-r--r--third-party/libuv/test/benchmark-tcp-write-batch.c (renamed from test/benchmark-tcp-write-batch.c)0
-rw-r--r--third-party/libuv/test/benchmark-thread.c (renamed from test/benchmark-thread.c)0
-rw-r--r--third-party/libuv/test/benchmark-udp-pummel.c (renamed from test/benchmark-udp-pummel.c)0
-rw-r--r--third-party/libuv/test/blackhole-server.c (renamed from test/blackhole-server.c)0
-rw-r--r--third-party/libuv/test/dns-server.c (renamed from test/dns-server.c)0
-rw-r--r--third-party/libuv/test/echo-server.c (renamed from test/echo-server.c)0
-rw-r--r--third-party/libuv/test/fixtures/empty_file (renamed from test/fixtures/empty_file)0
-rw-r--r--third-party/libuv/test/fixtures/load_error.node (renamed from test/fixtures/load_error.node)0
-rw-r--r--third-party/libuv/test/run-benchmarks.c (renamed from test/run-benchmarks.c)0
-rw-r--r--third-party/libuv/test/run-tests.c (renamed from test/run-tests.c)0
-rw-r--r--third-party/libuv/test/runner-unix.c (renamed from test/runner-unix.c)0
-rw-r--r--third-party/libuv/test/runner-unix.h (renamed from test/runner-unix.h)0
-rw-r--r--third-party/libuv/test/runner-win.c (renamed from test/runner-win.c)0
-rw-r--r--third-party/libuv/test/runner-win.h (renamed from test/runner-win.h)0
-rw-r--r--third-party/libuv/test/runner.c (renamed from test/runner.c)0
-rw-r--r--third-party/libuv/test/runner.h (renamed from test/runner.h)0
-rw-r--r--third-party/libuv/test/task.h (renamed from test/task.h)0
-rw-r--r--third-party/libuv/test/test-active.c (renamed from test/test-active.c)0
-rw-r--r--third-party/libuv/test/test-async-null-cb.c (renamed from test/test-async-null-cb.c)0
-rw-r--r--third-party/libuv/test/test-async.c (renamed from test/test-async.c)0
-rw-r--r--third-party/libuv/test/test-barrier.c (renamed from test/test-barrier.c)0
-rw-r--r--third-party/libuv/test/test-callback-order.c (renamed from test/test-callback-order.c)0
-rw-r--r--third-party/libuv/test/test-callback-stack.c (renamed from test/test-callback-stack.c)0
-rw-r--r--third-party/libuv/test/test-close-fd.c (renamed from test/test-close-fd.c)0
-rw-r--r--third-party/libuv/test/test-close-order.c (renamed from test/test-close-order.c)0
-rw-r--r--third-party/libuv/test/test-condvar.c (renamed from test/test-condvar.c)0
-rw-r--r--third-party/libuv/test/test-connection-fail.c (renamed from test/test-connection-fail.c)0
-rw-r--r--third-party/libuv/test/test-cwd-and-chdir.c (renamed from test/test-cwd-and-chdir.c)0
-rw-r--r--third-party/libuv/test/test-delayed-accept.c (renamed from test/test-delayed-accept.c)0
-rw-r--r--third-party/libuv/test/test-dlerror.c (renamed from test/test-dlerror.c)0
-rw-r--r--third-party/libuv/test/test-embed.c (renamed from test/test-embed.c)0
-rw-r--r--third-party/libuv/test/test-emfile.c (renamed from test/test-emfile.c)0
-rw-r--r--third-party/libuv/test/test-error.c (renamed from test/test-error.c)0
-rw-r--r--third-party/libuv/test/test-fail-always.c (renamed from test/test-fail-always.c)0
-rw-r--r--third-party/libuv/test/test-fs-event.c (renamed from test/test-fs-event.c)0
-rw-r--r--third-party/libuv/test/test-fs-poll.c (renamed from test/test-fs-poll.c)0
-rw-r--r--third-party/libuv/test/test-fs.c (renamed from test/test-fs.c)0
-rw-r--r--third-party/libuv/test/test-get-currentexe.c (renamed from test/test-get-currentexe.c)0
-rw-r--r--third-party/libuv/test/test-get-loadavg.c (renamed from test/test-get-loadavg.c)0
-rw-r--r--third-party/libuv/test/test-get-memory.c (renamed from test/test-get-memory.c)0
-rw-r--r--third-party/libuv/test/test-getaddrinfo.c (renamed from test/test-getaddrinfo.c)0
-rw-r--r--third-party/libuv/test/test-getsockname.c (renamed from test/test-getsockname.c)0
-rw-r--r--third-party/libuv/test/test-hrtime.c (renamed from test/test-hrtime.c)0
-rw-r--r--third-party/libuv/test/test-idle.c (renamed from test/test-idle.c)0
-rw-r--r--third-party/libuv/test/test-ip4-addr.c (renamed from test/test-ip4-addr.c)0
-rw-r--r--third-party/libuv/test/test-ip6-addr.c (renamed from test/test-ip6-addr.c)0
-rw-r--r--third-party/libuv/test/test-ipc-send-recv.c (renamed from test/test-ipc-send-recv.c)0
-rw-r--r--third-party/libuv/test/test-ipc.c (renamed from test/test-ipc.c)0
-rw-r--r--third-party/libuv/test/test-list.h (renamed from test/test-list.h)0
-rw-r--r--third-party/libuv/test/test-loop-alive.c (renamed from test/test-loop-alive.c)0
-rw-r--r--third-party/libuv/test/test-loop-handles.c (renamed from test/test-loop-handles.c)0
-rw-r--r--third-party/libuv/test/test-loop-stop.c (renamed from test/test-loop-stop.c)0
-rw-r--r--third-party/libuv/test/test-loop-time.c (renamed from test/test-loop-time.c)0
-rw-r--r--third-party/libuv/test/test-multiple-listen.c (renamed from test/test-multiple-listen.c)0
-rw-r--r--third-party/libuv/test/test-mutexes.c (renamed from test/test-mutexes.c)0
-rw-r--r--third-party/libuv/test/test-osx-select.c (renamed from test/test-osx-select.c)0
-rw-r--r--third-party/libuv/test/test-pass-always.c (renamed from test/test-pass-always.c)0
-rw-r--r--third-party/libuv/test/test-ping-pong.c (renamed from test/test-ping-pong.c)0
-rw-r--r--third-party/libuv/test/test-pipe-bind-error.c (renamed from test/test-pipe-bind-error.c)0
-rw-r--r--third-party/libuv/test/test-pipe-connect-error.c (renamed from test/test-pipe-connect-error.c)0
-rw-r--r--third-party/libuv/test/test-pipe-server-close.c (renamed from test/test-pipe-server-close.c)0
-rw-r--r--third-party/libuv/test/test-platform-output.c (renamed from test/test-platform-output.c)0
-rw-r--r--third-party/libuv/test/test-poll-close.c (renamed from test/test-poll-close.c)0
-rw-r--r--third-party/libuv/test/test-poll.c (renamed from test/test-poll.c)0
-rw-r--r--third-party/libuv/test/test-process-title.c (renamed from test/test-process-title.c)0
-rw-r--r--third-party/libuv/test/test-ref.c (renamed from test/test-ref.c)0
-rw-r--r--third-party/libuv/test/test-run-nowait.c (renamed from test/test-run-nowait.c)0
-rw-r--r--third-party/libuv/test/test-run-once.c (renamed from test/test-run-once.c)0
-rw-r--r--third-party/libuv/test/test-semaphore.c (renamed from test/test-semaphore.c)0
-rw-r--r--third-party/libuv/test/test-shutdown-close.c (renamed from test/test-shutdown-close.c)0
-rw-r--r--third-party/libuv/test/test-shutdown-eof.c (renamed from test/test-shutdown-eof.c)0
-rw-r--r--third-party/libuv/test/test-signal-multiple-loops.c (renamed from test/test-signal-multiple-loops.c)0
-rw-r--r--third-party/libuv/test/test-signal.c (renamed from test/test-signal.c)0
-rw-r--r--third-party/libuv/test/test-spawn.c (renamed from test/test-spawn.c)0
-rw-r--r--third-party/libuv/test/test-stdio-over-pipes.c (renamed from test/test-stdio-over-pipes.c)0
-rw-r--r--third-party/libuv/test/test-tcp-bind-error.c (renamed from test/test-tcp-bind-error.c)0
-rw-r--r--third-party/libuv/test/test-tcp-bind6-error.c (renamed from test/test-tcp-bind6-error.c)0
-rw-r--r--third-party/libuv/test/test-tcp-close-accept.c (renamed from test/test-tcp-close-accept.c)0
-rw-r--r--third-party/libuv/test/test-tcp-close-while-connecting.c (renamed from test/test-tcp-close-while-connecting.c)0
-rw-r--r--third-party/libuv/test/test-tcp-close.c (renamed from test/test-tcp-close.c)0
-rw-r--r--third-party/libuv/test/test-tcp-connect-error-after-write.c (renamed from test/test-tcp-connect-error-after-write.c)0
-rw-r--r--third-party/libuv/test/test-tcp-connect-error.c (renamed from test/test-tcp-connect-error.c)0
-rw-r--r--third-party/libuv/test/test-tcp-connect-timeout.c (renamed from test/test-tcp-connect-timeout.c)0
-rw-r--r--third-party/libuv/test/test-tcp-connect6-error.c (renamed from test/test-tcp-connect6-error.c)0
-rw-r--r--third-party/libuv/test/test-tcp-flags.c (renamed from test/test-tcp-flags.c)0
-rw-r--r--third-party/libuv/test/test-tcp-open.c (renamed from test/test-tcp-open.c)0
-rw-r--r--third-party/libuv/test/test-tcp-read-stop.c (renamed from test/test-tcp-read-stop.c)0
-rw-r--r--third-party/libuv/test/test-tcp-shutdown-after-write.c (renamed from test/test-tcp-shutdown-after-write.c)0
-rw-r--r--third-party/libuv/test/test-tcp-try-write.c (renamed from test/test-tcp-try-write.c)0
-rw-r--r--third-party/libuv/test/test-tcp-unexpected-read.c (renamed from test/test-tcp-unexpected-read.c)0
-rw-r--r--third-party/libuv/test/test-tcp-write-to-half-open-connection.c (renamed from test/test-tcp-write-to-half-open-connection.c)0
-rw-r--r--third-party/libuv/test/test-tcp-writealot.c (renamed from test/test-tcp-writealot.c)0
-rw-r--r--third-party/libuv/test/test-thread.c (renamed from test/test-thread.c)0
-rw-r--r--third-party/libuv/test/test-threadpool-cancel.c (renamed from test/test-threadpool-cancel.c)0
-rw-r--r--third-party/libuv/test/test-threadpool.c (renamed from test/test-threadpool.c)0
-rw-r--r--third-party/libuv/test/test-timer-again.c (renamed from test/test-timer-again.c)0
-rw-r--r--third-party/libuv/test/test-timer-from-check.c (renamed from test/test-timer-from-check.c)0
-rw-r--r--third-party/libuv/test/test-timer.c (renamed from test/test-timer.c)0
-rw-r--r--third-party/libuv/test/test-tty.c (renamed from test/test-tty.c)0
-rw-r--r--third-party/libuv/test/test-udp-dgram-too-big.c (renamed from test/test-udp-dgram-too-big.c)0
-rw-r--r--third-party/libuv/test/test-udp-ipv6.c (renamed from test/test-udp-ipv6.c)0
-rw-r--r--third-party/libuv/test/test-udp-multicast-join.c (renamed from test/test-udp-multicast-join.c)0
-rw-r--r--third-party/libuv/test/test-udp-multicast-ttl.c (renamed from test/test-udp-multicast-ttl.c)0
-rw-r--r--third-party/libuv/test/test-udp-open.c (renamed from test/test-udp-open.c)0
-rw-r--r--third-party/libuv/test/test-udp-options.c (renamed from test/test-udp-options.c)0
-rw-r--r--third-party/libuv/test/test-udp-send-and-recv.c (renamed from test/test-udp-send-and-recv.c)0
-rw-r--r--third-party/libuv/test/test-walk-handles.c (renamed from test/test-walk-handles.c)0
-rw-r--r--third-party/libuv/test/test-watcher-cross-stop.c (renamed from test/test-watcher-cross-stop.c)0
-rw-r--r--third-party/libuv/uv.gyp (renamed from uv.gyp)0
-rw-r--r--third-party/libuv/vcbuild.bat (renamed from vcbuild.bat)0
-rw-r--r--vim-license.txt78
626 files changed, 501414 insertions, 192 deletions
diff --git a/.gitignore b/.gitignore
index d11c90bbf0..b013dd8c3c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,62 +1,25 @@
-*.swp
-*.[oa]
-*.l[oa]
-*.opensdf
-*.orig
-*.pyc
-*.sdf
-*.suo
-core
-vgcore.*
-.buildstamp
-.dirstamp
+# Build/deps dir
+build/
.deps/
-/.libs/
-/aclocal.m4
-/ar-lib
-/autom4te.cache/
-/compile
-/config.guess
-/config.log
-/config.status
-/config.sub
-/configure
-/depcomp
-/install-sh
-/libtool
-/libuv.a
-/libuv.dylib
-/libuv.pc
-/libuv.so
-/ltmain.sh
-/missing
-/test-driver
-Makefile
-Makefile.in
-
-# Generated by dtrace(1) when doing an in-tree build.
-/include/uv-dtrace.h
-# Generated by gyp for android
-*.target.mk
-
-/out/
-/build/gyp
+*.rej
+*.orig
+*.mo
+*.swp
+*~
+*.pyc
+src/po/vim.pot
-/run-tests
-/run-tests.exe
-/run-tests.dSYM
-/run-benchmarks
-/run-benchmarks.exe
-/run-benchmarks.dSYM
+src/po/*.ck
-*.sln
-*.vcproj
-*.vcxproj
-*.vcxproj.filters
-*.vcxproj.user
-_UpgradeReport_Files/
-UpgradeLog*.XML
-Debug
-Release
-ipch
+# Files generated by the tests
+src/testdir/mbyte.vim
+src/testdir/mzscheme.vim
+src/testdir/lua.vim
+src/testdir/small.vim
+src/testdir/tiny.vim
+src/testdir/test*.out
+src/testdir/test.log
+src/testdir/test.ok
+src/testdir/*.failed
+src/testdir/X*
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000000..bb82ce1e4c
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,2 @@
+language: c
+script: make cmake && make test
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000000..adb9894a3c
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,25 @@
+cmake_minimum_required (VERSION 2.6)
+project (NEOVIM)
+
+set(NEOVIM_VERSION_MAJOR 0)
+set(NEOVIM_VERSION_MINOR 0)
+set(NEOVIM_VERSION_PATCH 0)
+
+set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
+
+add_definitions(-DHAVE_CONFIG_H -Wall -std=gnu99)
+if(CMAKE_BUILD_TYPE MATCHES Debug)
+ # cmake automatically appends -g to the compiler flags
+ set(DEBUG 1)
+else()
+ set(DEBUG 0)
+endif()
+
+# add dependencies to include/lib directories
+link_directories ("${PROJECT_SOURCE_DIR}/.deps/usr/lib")
+include_directories ("${PROJECT_SOURCE_DIR}/.deps/usr/include")
+
+include_directories ("${PROJECT_BINARY_DIR}/config")
+
+add_subdirectory(src)
+add_subdirectory(config)
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000000..6e456022c2
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,26 @@
+CMAKE_FLAGS := -DCMAKE_BUILD_TYPE=Debug
+
+build/src/vim: deps
+ cd build && make
+
+test: build/src/vim
+ cd src/testdir && make
+
+deps: .deps/usr/lib/libuv.a
+
+.deps/usr/lib/libuv.a:
+ sh -e scripts/get-libuv.sh
+
+cmake: clean
+ mkdir build
+ cd build && cmake $(CMAKE_FLAGS) ../
+
+clean:
+ rm -rf build
+ for file in lua mbyte mzscheme small tiny; do \
+ rm -f src/testdir/$$file.vim; \
+ done
+
+.PHONY: test deps cmake
+
+.DEFAULT: build/src/vim
diff --git a/README.md b/README.md
index 5704c39e27..e3ca041283 100644
--- a/README.md
+++ b/README.md
@@ -1,143 +1,250 @@
-# libuv
+# neovim ([bountysource fundraiser](https://www.bountysource.com/fundraisers/539-neovim-first-iteration))
-libuv is a multi-platform support library with a focus on asynchronous I/O. It
-was primarily developed for use by [Node.js](http://nodejs.org), but it's also
-used by Mozilla's [Rust language](http://www.rust-lang.org/),
-[Luvit](http://luvit.io/), [Julia](http://julialang.org/),
-[pyuv](https://crate.io/packages/pyuv/), and [others](https://github.com/joyent/libuv/wiki/Projects-that-use-libuv).
+[![Build Status](https://travis-ci.org/neovim/neovim.png?branch=master)](https://travis-ci.org/neovim/neovim)
-## Feature highlights
+### Introduction
- * Full-featured event loop backed by epoll, kqueue, IOCP, event ports.
+Vim is a powerful text editor with a big community that is constantly growing. Even though the editor is about two decades old, people still extend and want to improve it, mostly using vimscript or one of the supported scripting languages.
- * Asynchronous TCP and UDP sockets
+### Problem
- * Asynchronous DNS resolution
+Over its more than 20 years of life, vim has accumulated about 300k lines of scary C89 code that very few people understand or have the guts to mess with.
- * Asynchronous file and file system operations
+Another issue, is that as the only person responsible for maintaining vim's big codebase, Bram Moolenaar has to be extra-careful before accepting patches, because once merged, the new code will be his responsibility.
- * File system events
+These problems make it very difficult to have new features and bug fixes merged into the core. Vim just can't keep up with the development speed of its plugin ecosystem.
- * ANSI escape code controlled TTY
+### Solution
- * IPC with socket sharing, using Unix domain sockets or named pipes (Windows)
+Neovim is a project that seeks to aggressively refactor vim source code in order to achieve the following goals:
- * Child processes
+- Simplify maintenance to improve the speed that bug fixes and features get merged.
+- Split the work between multiple developers.
+- Enable the implementation of new/modern user interfaces without any modifications to the core source.
+- Improve the extensibility power with a new plugin architecture based on coprocesses. Plugins will be written in any programming language without any explicit support from the editor.
- * Thread pool
+By achieving those goals new developers will soon join the community, consequently improving the editor for all users.
- * Signal handling
+It is important to emphasize that this is not a project to rewrite vim from scratch or transform it into an IDE (though the new features provided will enable IDE-like distributions of the editor). The changes implemented here should have little impact on vim's editing model or vimscript in general. Most vimscript plugins should continue to work normally.
- * High resolution clock
+The following topics contain brief explanations of the major changes (and motivations) that will be performed in the first iteration:
- * Threading and synchronization primitives
+* <a href="#build"><b>Migrate to a cmake-based build</b></a>
+* <a href="#legacy"><b>Legacy support and compile-time features</b></a>
+* <a href="#platform"><b>Platform-specific code</b></a>
+* <a href="#plugins"><b>New plugin architecture</b></a>
+* <a href="#gui"><b>New GUI architecture</b></a>
+* <a href="#development"><b>Development on github</b></a>
+<a name="build"></a>
+##### Migrate to a cmake-based build
-## Community
+The source tree has dozens (if not hundreds) of files dedicated to building vim with on various platforms with different configurations, and many of these files look abandoned or outdated. Most users don't care about selecting individual features and just compile using '--with-features=huge', which still generates an executable that is small enough even for lightweight systems by today's standards.
- * [Mailing list](http://groups.google.com/group/libuv)
+All those files will be removed and vim will be built using [cmake](http://www.cmake.org), a modern build system that generates build scripts for the most relevant platforms.
-## Documentation
+<a name="legacy"></a>
+##### Legacy support and compile-time features
- * [include/uv.h](https://github.com/joyent/libuv/blob/master/include/uv.h)
- &mdash; API documentation in the form of detailed header comments.
- * [An Introduction to libuv](http://nikhilm.github.com/uvbook/)
- &mdash; An overview of libuv with tutorials.
- * [LXJS 2012 talk](http://www.youtube.com/watch?v=nGn60vDSxQ4)
- &mdash; High-level introductory talk about libuv.
- * [Tests and benchmarks](https://github.com/joyent/libuv/tree/master/test)
- &mdash; API specification and usage examples.
- * [libuv-dox](https://github.com/thlorenz/libuv-dox)
- &mdash; Documenting types and methods of libuv, mostly by reading uv.h.
+Vim has a significant amount of code dedicated to supporting legacy systems and compilers. All that code increases the maintenance burden and will be removed.
-## Build Instructions
+Most optional features will no longer be optional (see above), with the exception of some broken and useless features (eg: netbeans integration, sun workshop) which will be removed permanently. Vi emulation will also be removed (setting 'nocompatible' will be a no-op).
-For GCC there are two methods building: via autotools or via [GYP][].
-GYP is a meta-build system which can generate MSVS, Makefile, and XCode
-backends. It is best used for integration into other projects.
+These changes wont affect most users. Those that only have a C89 compiler installed or use vim on legacy systems such as Amiga, BeOS or MSDOS will have two options:
-To build with autotools:
+- Upgrade their software
+- Continue using vim
- $ sh autogen.sh
- $ ./configure
- $ make
- $ make check
- $ make install
+<a name="platform"></a>
+##### Platform-specific code
-### Windows
+Most of the platform-specific code will be removed and [libuv](https://github.com/joyent/libuv) will be used to handle system differences.
-First, Python 2.6 or 2.7 must be installed as it is required by [GYP][].
+libuv is a modern multi-platform library with functions to perform common system tasks, and supports most unixes and windows, so the vast majority of vim's community will be covered.
-Also, the directory for the preferred Python executable must be specified
-by the `PYTHON` or `Path` environment variables.
+<a name="plugins"></a>
+##### New plugin architecture
-To build with Visual Studio, launch a git shell (e.g. Cmd or PowerShell)
-and run vcbuild.bat which will checkout the GYP code into build/gyp and
-generate uv.sln as well as related project files.
+All code supporting embedded scripting language interpreters will be replaced by a new plugin system that will support extensions written in any programming language.
-To have GYP generate build script for another system, checkout GYP into the
-project tree manually:
+Compatibility layers will be provided for vim plugins written in some of the currently supported scripting languages such as python or ruby. Most plugins should work on neovim with little modifications, if any.
- $ mkdir -p build
- $ git clone https://git.chromium.org/external/gyp.git build/gyp
+This is how the new plugin system will work:
-### Unix
+- Plugins are long-running programs/jobs (coprocesses) that communicate with vim through stdin/stdout using msgpack-rpc or json-rpc.
+- Vim will discover and run these programs at startup, keeping two-way communication channels with each plugin through its lifetime.
+- Plugins will be able to listen to events and send commands to vim asynchronously.
-Run:
+This system will be built on top of a job control mechanism similar to the one implemented by the [job control patch](https://groups.google.com/forum/#!topic/vim_dev/QF7Bzh1YABU)
- $ ./gyp_uv.py -f make
- $ make -C out
+Here's an idea of how a plugin session might work using [json-rpc](http://www.jsonrpc.org/specification) (jsonrpc version omitted):
-### OS X
+```js
+plugin -> neovim: {"id": 1, "method": "listenEvent", "params": {"eventName": "keyPressed"}}
+neovim -> plugin: {"id": 1, "result": true}
+neovim -> plugin: {"method": "event", "params": {"name": "keyPressed", "eventArgs": {"keys": ["C"]}}}
+neovim -> plugin: {"method": "event", "params": {"name": "keyPressed", "eventArgs": {"keys": ["Ctrl", "Space"]}}}
+plugin -> neovim: {"id": 2, "method": "showPopup", "params": {"size": {"width": 10, "height": 2} "position": {"column": 2, "line": 3}, "items": ["Completion1", "Completion2"]}}
+plugin -> neovim: {"id": 2, "result": true}}
+```
-Run:
+That shows an hypothetical conversation between neovim and completion plugin that displays completions when the user presses Ctrl+Space. The above scheme gives neovim near limitless extensibility and also improves stability as plugins will automatically be isolated from the main executable.
- $ ./gyp_uv.py -f xcode
- $ xcodebuild -ARCHS="x86_64" -project uv.xcodeproj \
- -configuration Release -target All
+This system can also easily emulate the current scripting languages interfaces to vim. For example, a plugin can emulate the python interface by running python scripts sent by vim in its own context and by exposing a 'vim' module with an API matching the current one. Calls to the API would simply be translated to json-rpc messages sent to vim.
-Note to OS X users:
-Make sure that you specify the architecture you wish to build for in the
-"ARCHS" flag. You can specify more than one by delimiting with a space
-(e.g. "x86_64 i386").
+<a name="gui"></a>
+##### New GUI architecture
-### Android
+Another contributing factor to vim's huge codebase is the explicit support for dozens of widget toolkits for GUI interfaces. Like the legacy code support, gui-specific code will be removed.
-Run:
+Neovim will handle GUIs similarly to how it will handle plugins:
- $ source ./android-configure NDK_PATH gyp
- $ make -C out
+- GUIs are separate programs, possibly written in different programming languages.
+- Neovim will use its own stdin/stdout to receive input and send updates, again using json-rpc or msgpack-rpc.
-Note for UNIX users: compile your project with `-D_LARGEFILE_SOURCE` and
-`-D_FILE_OFFSET_BITS=64`. GYP builds take care of that automatically.
+The difference between plugins and GUIs is that plugins will be started by neovim, where neovim will be started by programs running the GUI. Here's a sample diagram of the process tree:
-### Running tests
+```
+GUI program
+ |
+ ---> Neovim
+ |
+ ---> Plugin 1
+ |
+ ---> Plugin 2
+ |
+ ---> Plugin 3
+```
-Run:
+Hypothetical GUI session:
- $ ./gyp_uv.py -f make
- $ make -C out
- $ ./out/Debug/run-tests
+```js
+gui -> vim: {"id": 1, "method": "initClient", "params": {"size": {"rows": 20, "columns": 25}}}
+vim -> gui: {"id": 1, "result": {"clientId": 1}}
+vim -> gui: {"method": "redraw", "params": {"clientId": 1, "lines": {"5": " Welcome to neovim! "}}}
+gui -> vim: {"id": 2, "method": "keyPress", "params": {"keys": ["H", "e", "l", "l", "o"]}}
+vim -> gui: {"method": "redraw", "params": {"clientId": 1, "lines": {"1": "Hello ", "5": " "}}}
+```
-## Supported Platforms
+This new GUI architecture creates many interesting possibilities:
-Microsoft Windows operating systems since Windows XP SP2. It can be built
-with either Visual Studio or MinGW. Consider using
-[Visual Studio Express 2010][] or later if you do not have a full Visual
-Studio license.
+- Modern GUIs written in high-level programming languages that integrate better with the operating system. We can have GUIs written using C#/WPF on Windows or Ruby/Cocoa on Mac, for example.
+- Plugins will be able to emit custom events that may be handled directly by GUIs. This will enable the implementation of advanced features such as sublime's minimap.
+- A multiplexing daemon could keep neovim instances running in a headless server, while multiple remote GUIs could attach/detach to share editing sessions.
+- Simplified headless testing.
+- Embedding the editor into other programs. In fact, a GUI can be seen as a program that embeds neovim.
-Linux using the GCC toolchain.
+Here's a diagram that illustrates how a client-server process tree might look like:
-OS X using the GCC or XCode toolchain.
+```
+Server daemon listening on tcp sockets <------ GUI 1 (attach/detach to running instances using tcp sockets)
+ | |
+ ---> Neovim |
+ | GUI 2 (sharing the same session with GUI 1)
+ ---> Plugin 1
+ |
+ ---> Plugin 2
+ |
+ ---> Plugin 3
+```
-Solaris 121 and later using GCC toolchain.
-## patches
+<a name="development"></a>
+##### Development on Github
-See the [guidelines for contributing][].
+Development will happen on the [github organization](https://github.com/neovim), and the code will be split across many repositories, unlike the current vim source tree.
+
+There will be separate repositories for GUIs, plugins, runtime files (official vimscript) and distributions. This will let the editor receive improvements much faster as the patches don't have to go all through a single person for approval.
+
+Travis will also be used for continuous integration, so pull requests will be automatically checked.
+
+### Status
+
+Here's a list of things that have been done so far:
+
+- Source tree was cleaned up, leaving only files necessary for compilation/testing of the core.
+- Source files were processed with [unifdef](http://freecode.com/projects/unifdef) to remove tons of `FEAT_*` macros
+- Files were processed with [uncrustify](http://uncrustify.sourceforge.net/) to normalize source code formatting.
+- The autotools build system was replaced by [cmake](http://www.cmake.org/)
+
+and what is currently being worked on:
+
+- Port all IO to libuv
+
+### Dependencies
+
+#### For Debian/Ubuntu:
+
+ sudo apt-get install libtool autoconf cmake libncurses5-dev g++
+
+#### For FreeBSD 10:
+
+ sudo pkg install cmake libtool sha
+
+#### For OS X:
+
+* Install [Xcode](https://developer.apple.com/)
+* Install sha1sum
+
+ Via MacPorts:
+
+ sudo port install md5sha1sum cmake libtool automake
+
+ Via Homebrew:
+
+ brew install md5sha1sum cmake libtool automake
+
+If you run into wget certificate errors, you may be missing the root SSL
+certificates or have not set them up correctly:
+
+ Via MacPorts:
+
+ sudo port install curl-ca-bundle
+ echo CA_CERTIFICATE=/opt/local/share/curl/curl-ca-bundle.crt >> ~/.wgetrc
+
+ Via Homebrew:
+
+ brew install curl-ca-bundle
+ echo CA_CERTIFICATE=/usr/local/opt/curl-ca-bundle/share/ca-bundle.crt >> ~/.wgetrc
+
+#### For Arch Linux:
+
+ sudo pacman -S base-devel cmake ncurses
+
+### Building
+
+To generate the `Makefile`s:
+
+ make cmake
+
+To build and run the tests:
+
+ make test
+
+### Community
+
+Join the community on IRC in #neovim on Freenode.
+
+### Contributing
+
+...would be awesome! See [the wiki](https://github.com/neovim/neovim/wiki/Contributing) for more details.
+
+### License
+
+Vim itself is distributed under the terms of the Vim License.
+See vim-license.txt for details.
+
+Vim also includes a message along the following lines:
+
+ Vim is Charityware. You can use and copy it as much as you like, but you are
+ encouraged to make a donation for needy children in Uganda. Please see the
+ kcc section of the vim docs or visit the ICCF web site, available at these URLs:
+
+ http://iccf-holland.org/
+ http://www.vim.org/iccf/
+ http://www.iccf.nl/
+
+ You can also sponsor the development of Vim. Vim sponsors can vote for
+ features. The money goes to Uganda anyway.
-[node.js]: http://nodejs.org/
-[GYP]: http://code.google.com/p/gyp/
-[Visual Studio Express 2010]: http://www.microsoft.com/visualstudio/eng/products/visual-studio-2010-express
-[guidelines for contributing]: https://github.com/joyent/libuv/blob/master/CONTRIBUTING.md
diff --git a/config/CMakeLists.txt b/config/CMakeLists.txt
new file mode 100644
index 0000000000..36ffb0c810
--- /dev/null
+++ b/config/CMakeLists.txt
@@ -0,0 +1,42 @@
+include(CheckTypeSize)
+include(CheckCSourceCompiles)
+
+check_type_size("int" SIZEOF_INT)
+check_type_size("long" SIZEOF_LONG)
+check_type_size("time_t" SIZEOF_TIME_T)
+check_type_size("off_t" SIZEOF_OFF_T)
+
+check_c_source_compiles("
+#include <libintl.h>
+
+int main(int argc, char** argv) {
+ gettext(\"foo\");
+ bindtextdomain(\"foo\", \"bar\");
+ bind_textdomain_codeset(\"foo\", \"bar\");
+ textdomain(\"foo\");
+}" HAVE_WORKING_LIBINTL)
+
+# generate configuration header and update include directories
+configure_file (
+ "${PROJECT_SOURCE_DIR}/config/config.h.in"
+ "${PROJECT_BINARY_DIR}/config/auto/config.h"
+ )
+# generate pathdef.c
+find_program(WHOAMI_PROG whoami)
+find_program(HOSTNAME_PROG hostname)
+
+if (EXISTS ${WHOAMI_PROG})
+ execute_process(COMMAND ${WHOAMI_PROG}
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ OUTPUT_VARIABLE USERNAME)
+endif()
+if (EXISTS ${HOSTNAME_PROG})
+ execute_process(COMMAND ${HOSTNAME_PROG}
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ OUTPUT_VARIABLE HOSTNAME)
+endif()
+
+configure_file (
+ "${PROJECT_SOURCE_DIR}/config/pathdef.c.in"
+ "${PROJECT_BINARY_DIR}/config/auto/pathdef.c"
+ ESCAPE_QUOTES)
diff --git a/config/config.h.in b/config/config.h.in
new file mode 100644
index 0000000000..60729562af
--- /dev/null
+++ b/config/config.h.in
@@ -0,0 +1,217 @@
+#define NEOVIM_VERSION_MAJOR @NEOVIM_VERSION_MAJOR@
+#define NEOVIM_VERSION_MINOR @NEOVIM_VERSION_MINOR@
+#define NEOVIM_VERSION_PATCH @NEOVIM_VERSION_PATCH@
+
+#if @DEBUG@
+#define DEBUG
+#endif
+
+#define SIZEOF_INT @SIZEOF_INT@
+#define SIZEOF_LONG @SIZEOF_LONG@
+#define SIZEOF_TIME_T @SIZEOF_TIME_T@
+#define SIZEOF_OFF_T @SIZEOF_OFF_T@
+
+#define _FILE_OFFSET_BITS 64
+#define HAVE_ATTRIBUTE_UNUSED 1
+#define HAVE_BCMP 1
+#define HAVE_DATE_TIME 1
+#define HAVE_DIRENT_H 1
+#define HAVE_DLFCN_H 1
+#define HAVE_DLOPEN 1
+#define HAVE_DLSYM 1
+#define HAVE_ERRNO_H 1
+#define HAVE_FCHDIR 1
+#define HAVE_FCHOWN 1
+#define HAVE_FCNTL_H 1
+#define HAVE_FD_CLOEXEC 1
+#define HAVE_FLOAT_FUNCS 1
+#define HAVE_FSEEKO 1
+#define HAVE_FSYNC 1
+#define HAVE_GETCWD 1
+#define HAVE_GETPWENT 1
+#define HAVE_GETPWNAM 1
+#define HAVE_GETPWUID 1
+#define HAVE_GETRLIMIT 1
+#define HAVE_GETTIMEOFDAY 1
+#define HAVE_GETWD 1
+#define HAVE_ICONV 1
+#define HAVE_ICONV_H 1
+#define HAVE_INTTYPES_H 1
+#define HAVE_ISWUPPER 1
+#define HAVE_LANGINFO_H 1
+#define HAVE_LIBGEN_H 1
+#define HAVE_LIBINTL_H 1
+#define HAVE_LOCALE_H 1
+#define HAVE_LSTAT 1
+#define HAVE_MATH_H 1
+#define HAVE_MEMCMP 1
+#define HAVE_MEMSET 1
+#define HAVE_MKDTEMP 1
+#define HAVE_NANOSLEEP 1
+#define HAVE_NL_LANGINFO_CODESET 1
+#define HAVE_NL_MSG_CAT_CNTR 1
+#define HAVE_OPENDIR 1
+#define HAVE_OSPEED 1
+#define HAVE_POLL_H 1
+#define HAVE_PUTENV 1
+#define HAVE_PWD_H 1
+#define HAVE_QSORT 1
+#define HAVE_READLINK 1
+#define HAVE_RENAME 1
+#define HAVE_SELECT 1
+// TODO: add proper cmake check
+// #define HAVE_SELINUX 1
+#define HAVE_SETENV 1
+#define HAVE_SETJMP_H 1
+#define HAVE_SETPGID 1
+#define HAVE_SETSID 1
+#define HAVE_SGTTY_H 1
+#define HAVE_SIGACTION 1
+#define HAVE_SIGALTSTACK 1
+#define HAVE_SIGCONTEXT 1
+#define HAVE_SIGSTACK 1
+#define HAVE_SIGVEC 1
+#define HAVE_ST_BLKSIZE 1
+#define HAVE_STDARG_H 1
+#define HAVE_STDINT_H 1
+#define HAVE_STDLIB_H 1
+#define HAVE_STRCASECMP 1
+#define HAVE_STRERROR 1
+#define HAVE_STRFTIME 1
+#define HAVE_STRING_H 1
+#define HAVE_STRINGS_H 1
+#define HAVE_STRNCASECMP 1
+// TODO: add proper cmake check
+// #define HAVE_STROPTS_H 1
+#define HAVE_STRPBRK 1
+#define HAVE_STRTOL 1
+#define HAVE_SVR4_PTYS 1
+// TODO: add proper cmake check
+// #define HAVE_SYSCONF 1
+#define HAVE_SYSINFO 1
+#define HAVE_SYSINFO_MEM_UNIT 1
+#define HAVE_SYS_IOCTL_H 1
+#define HAVE_SYS_PARAM_H 1
+#define HAVE_SYS_POLL_H 1
+#define HAVE_SYS_RESOURCE_H 1
+#define HAVE_SYS_SELECT_H 1
+#define HAVE_SYS_STATFS_H 1
+#define HAVE_SYS_SYSCTL_H 1
+// TODO: add proper cmake check
+// #define HAVE_SYS_SYSINFO_H 1
+#define HAVE_SYS_TIME_H 1
+#define HAVE_SYS_TYPES_H 1
+#define HAVE_SYS_UTSNAME_H 1
+#define HAVE_SYS_WAIT_H 1
+#define HAVE_TERMCAP_H 1
+#define HAVE_TERMIO_H 1
+#define HAVE_TERMIOS_H 1
+#define HAVE_TGETENT 1
+#define HAVE_TOWLOWER 1
+#define HAVE_TOWUPPER 1
+#define HAVE_UNISTD_H 1
+#define HAVE_UP_BC_PC 1
+#define HAVE_USLEEP 1
+#define HAVE_UTIME 1
+#define HAVE_UTIME_H 1
+#define HAVE_UTIMES 1
+#define HAVE_WCHAR_H 1
+#define HAVE_WCTYPE_H 1
+#cmakedefine HAVE_WORKING_LIBINTL
+#define RETSIGTYPE void
+#define SIGRETURN return
+#define SYS_SELECT_WITH_SYS_TIME 1
+#define TERMINFO 1
+#define TGETENT_ZERO_ERR 0
+#define TIME_WITH_SYS_TIME 1
+#define UNIX 1
+#define USEMAN_S 1
+#define USEMEMMOVE 1
+
+#define FEAT_ARABIC
+#define FEAT_AUTOCHDIR
+#define FEAT_AUTOCMD
+#define FEAT_BROWSE
+#define FEAT_BROWSE_CMD
+#define FEAT_BYTEOFF
+#define FEAT_CINDENT
+#define FEAT_CMDHIST
+#define FEAT_CMDL_COMPL
+#define FEAT_CMDL_INFO
+#define FEAT_CMDWIN
+#define FEAT_COMMENTS
+#define FEAT_COMPL_FUNC
+#define FEAT_CONCEAL
+#define FEAT_CON_DIALOG
+#define FEAT_CRYPT
+#define FEAT_CSCOPE
+#define FEAT_CURSORBIND
+#define FEAT_DIFF
+#define FEAT_DIGRAPHS
+#define FEAT_EVAL
+#define FEAT_EX_EXTRA
+#define FEAT_FIND_ID
+#define FEAT_FKMAP
+#define FEAT_FLOAT
+#define FEAT_FOLDING
+#define FEAT_GETTEXT
+#define FEAT_HANGULIN
+#define FEAT_INS_EXPAND
+#define FEAT_JUMPLIST
+#define FEAT_KEYMAP
+#define FEAT_LANGMAP
+#define FEAT_LINEBREAK
+#define FEAT_LISP
+#define FEAT_LISTCMDS
+#define FEAT_LOCALMAP
+#define FEAT_MBYTE
+#define FEAT_MENU
+#define FEAT_MODIFY_FNAME
+#define FEAT_MOUSE
+#define FEAT_MOUSE_DEC
+#define FEAT_MOUSE_NET
+#define FEAT_MOUSE_SGR
+#define FEAT_MOUSE_TTY
+#define FEAT_MOUSE_URXVT
+#define FEAT_MOUSE_XTERM
+#define FEAT_MULTI_LANG
+#define FEAT_PATH_EXTRA
+#define FEAT_PERSISTENT_UNDO
+#define FEAT_POSTSCRIPT
+#define FEAT_PRINTER
+#define FEAT_PROFILE
+#define FEAT_QUICKFIX
+#define FEAT_RELTIME
+#define FEAT_RIGHTLEFT
+#define FEAT_SCROLLBIND
+#define FEAT_SEARCHPATH
+#define FEAT_SEARCH_EXTRA
+#define FEAT_SESSION
+#define FEAT_SMARTINDENT
+#define FEAT_SPELL
+#define FEAT_STL_OPT
+#define FEAT_SYN_HL
+#define FEAT_TAG_BINS
+#define FEAT_TAG_OLDSTATIC
+#define FEAT_TERMRESPONSE
+#define FEAT_TEXTOBJ
+#define FEAT_TITLE
+#define FEAT_USR_CMDS
+#define FEAT_VERTSPLIT
+#define FEAT_VIMINFO
+#define FEAT_VIRTUALEDIT
+#define FEAT_VISUAL
+#define FEAT_VISUALEXTRA
+#define FEAT_VREPLACE
+#define FEAT_WAK
+#define FEAT_WILDIGN
+#define FEAT_WILDMENU
+#define FEAT_WINDOWS
+#define FEAT_WRITEBACK
+#define FEAT_HUGE
+#define FEAT_BIG
+#define FEAT_NORMAL
+#define FEAT_SMALL
+#define FEAT_TINY
+#define FEAT_WRITEBACKUP
+#define VIM_BACKTICK /* internal backtick expansion */
diff --git a/config/pathdef.c.in b/config/pathdef.c.in
new file mode 100644
index 0000000000..6ba5358689
--- /dev/null
+++ b/config/pathdef.c.in
@@ -0,0 +1,7 @@
+#include "${PROJECT_SOURCE_DIR}/src/vim.h"
+char_u *default_vim_dir = (char_u *)"${CMAKE_INSTALL_PREFIX}/share/vim";
+char_u *default_vimruntime_dir = (char_u *)"";
+char_u *all_cflags = (char_u *)"${COMPILER_FLAGS}";
+char_u *all_lflags = (char_u *)"${LINKER_FLAGS}";
+char_u *compiled_user = (char_u *)"${USERNAME}";
+char_u *compiled_sys = (char_u *)"${HOSTNAME}";
diff --git a/scripts/common.sh b/scripts/common.sh
new file mode 100644
index 0000000000..8c5d8a61ab
--- /dev/null
+++ b/scripts/common.sh
@@ -0,0 +1,50 @@
+platform='unknown'
+unameval=`uname`
+if [ "$unameval" == 'Linux' ]; then
+ platform='linux'
+elif [ "$unameval" == 'FreeBSD' ]; then
+ platform='freebsd'
+fi
+
+sha1sumcmd='sha1sum'
+if [ "$platform" == 'freebsd' ]; then
+ sha1sumcmd='shasum'
+fi
+
+pkgroot="$(pwd)"
+deps="$pkgroot/.deps"
+prefix="$deps/usr"
+export PATH="$prefix/bin:$PATH"
+
+download() {
+ local url=$1
+ local tgt=$2
+ local sha1=$3
+
+ if [ ! -d "$tgt" ]; then
+ mkdir -p "$tgt"
+ if which wget > /dev/null 2>&1; then
+ tmp_dir=$(mktemp -d "/tmp/download_sha1check_XXXXXXX")
+ fifo="$tmp_dir/fifo"
+ mkfifo "$fifo"
+ # download, untar and calculate sha1 sum in one pass
+ (wget "$url" -O - | tee "$fifo" | \
+ (cd "$tgt"; tar --strip-components=1 -xvzf -)) &
+ sum=$("$sha1sumcmd" < "$fifo" | cut -d ' ' -f1)
+ rm -rf "$tmp_dir"
+ if [ "$sum" != "$sha1" ]; then
+ echo "SHA1 sum doesn't match, expected '$sha1' got '$sum'"
+ exit 1
+ fi
+ else
+ echo "Missing wget utility"
+ exit 1
+ fi
+ fi
+}
+
+github_download() {
+ local repo=$1
+ local ver=$2
+ download "https://github.com/${repo}/archive/${ver}.tar.gz" "$3" "$4"
+}
diff --git a/scripts/get-libuv.sh b/scripts/get-libuv.sh
new file mode 100644
index 0000000000..9f3eceb218
--- /dev/null
+++ b/scripts/get-libuv.sh
@@ -0,0 +1,16 @@
+. scripts/common.sh
+
+uv_repo=joyent/libuv
+uv_ver=v0.11.19
+uv_dir="$deps/uv-$uv_ver"
+uv_sha1=5539d8e99e22b438cf4a412d4cec70ac6bb519fc
+
+rm -rf "$uv_dir"
+
+github_download "$uv_repo" "$uv_ver" "$uv_dir" "$uv_sha1"
+cd "$uv_dir"
+sh autogen.sh
+./configure --prefix="$prefix"
+make
+make install
+rm "$prefix/lib/"libuv*.{so,dylib} "$prefix/lib/"libuv*.{so,dylib}.* || true
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
new file mode 100644
index 0000000000..1c7829e7d6
--- /dev/null
+++ b/src/CMakeLists.txt
@@ -0,0 +1,33 @@
+file( GLOB NEOVIM_SOURCES *.c )
+
+foreach(sfile ${NEOVIM_SOURCES})
+ get_filename_component(f ${sfile} NAME)
+ if(${f} MATCHES "^(regexp_nfa.c|farsi.c|arabic.c)$")
+ list(APPEND to_remove ${sfile})
+ endif()
+endforeach()
+
+list(REMOVE_ITEM NEOVIM_SOURCES ${to_remove})
+list(APPEND NEOVIM_SOURCES "${PROJECT_BINARY_DIR}/config/auto/pathdef.c")
+
+file( GLOB IO_SOURCES io/*.c )
+
+add_executable (vim ${NEOVIM_SOURCES} ${IO_SOURCES})
+
+target_link_libraries (vim m uv pthread)
+
+include(CheckLibraryExists)
+check_library_exists(termcap tgetent "" HAVE_LIBTERMCAP)
+
+if (HAVE_LIBTERMCAP)
+ target_link_libraries(vim termcap)
+else()
+ check_library_exists(curses tgetent "" HAVE_LIBCURSES)
+ if (HAVE_LIBCURSES)
+ target_link_libraries(vim curses)
+ else()
+ message(FATAL_ERROR "can't find something resembling -ltermcap")
+ endif()
+endif()
+
+include_directories ("${PROJECT_SOURCE_DIR}/src/proto")
diff --git a/src/arabic.c b/src/arabic.c
new file mode 100644
index 0000000000..c8d3fc2a69
--- /dev/null
+++ b/src/arabic.c
@@ -0,0 +1,1134 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * 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.
+ */
+
+/*
+ * arabic.c: functions for Arabic language
+ *
+ * Included by main.c, when FEAT_ARABIC & FEAT_GUI is defined.
+ *
+ * --
+ *
+ * Author: Nadim Shaikli & Isam Bayazidi
+ *
+ */
+
+static int A_is_a __ARGS((int cur_c));
+static int A_is_s __ARGS((int cur_c));
+static int A_is_f __ARGS((int cur_c));
+static int chg_c_a2s __ARGS((int cur_c));
+static int chg_c_a2i __ARGS((int cur_c));
+static int chg_c_a2m __ARGS((int cur_c));
+static int chg_c_a2f __ARGS((int cur_c));
+static int chg_c_i2m __ARGS((int cur_c));
+static int chg_c_f2m __ARGS((int cur_c));
+static int chg_c_laa2i __ARGS((int hid_c));
+static int chg_c_laa2f __ARGS((int hid_c));
+static int half_shape __ARGS((int c));
+static int A_firstc_laa __ARGS((int c1, int c));
+static int A_is_harakat __ARGS((int c));
+static int A_is_iso __ARGS((int c));
+static int A_is_formb __ARGS((int c));
+static int A_is_ok __ARGS((int c));
+static int A_is_valid __ARGS((int c));
+static int A_is_special __ARGS((int c));
+
+
+/*
+ * Returns True if c is an ISO-8859-6 shaped ARABIC letter (user entered)
+ */
+static int A_is_a(cur_c)
+int cur_c;
+{
+ switch (cur_c) {
+ case a_HAMZA:
+ case a_ALEF_MADDA:
+ case a_ALEF_HAMZA_ABOVE:
+ case a_WAW_HAMZA:
+ case a_ALEF_HAMZA_BELOW:
+ case a_YEH_HAMZA:
+ case a_ALEF:
+ case a_BEH:
+ case a_TEH_MARBUTA:
+ case a_TEH:
+ case a_THEH:
+ case a_JEEM:
+ case a_HAH:
+ case a_KHAH:
+ case a_DAL:
+ case a_THAL:
+ case a_REH:
+ case a_ZAIN:
+ case a_SEEN:
+ case a_SHEEN:
+ case a_SAD:
+ case a_DAD:
+ case a_TAH:
+ case a_ZAH:
+ case a_AIN:
+ case a_GHAIN:
+ case a_TATWEEL:
+ case a_FEH:
+ case a_QAF:
+ case a_KAF:
+ case a_LAM:
+ case a_MEEM:
+ case a_NOON:
+ case a_HEH:
+ case a_WAW:
+ case a_ALEF_MAKSURA:
+ case a_YEH:
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+/*
+ * Returns True if c is an Isolated Form-B ARABIC letter
+ */
+static int A_is_s(cur_c)
+int cur_c;
+{
+ switch (cur_c) {
+ case a_s_HAMZA:
+ case a_s_ALEF_MADDA:
+ case a_s_ALEF_HAMZA_ABOVE:
+ case a_s_WAW_HAMZA:
+ case a_s_ALEF_HAMZA_BELOW:
+ case a_s_YEH_HAMZA:
+ case a_s_ALEF:
+ case a_s_BEH:
+ case a_s_TEH_MARBUTA:
+ case a_s_TEH:
+ case a_s_THEH:
+ case a_s_JEEM:
+ case a_s_HAH:
+ case a_s_KHAH:
+ case a_s_DAL:
+ case a_s_THAL:
+ case a_s_REH:
+ case a_s_ZAIN:
+ case a_s_SEEN:
+ case a_s_SHEEN:
+ case a_s_SAD:
+ case a_s_DAD:
+ case a_s_TAH:
+ case a_s_ZAH:
+ case a_s_AIN:
+ case a_s_GHAIN:
+ case a_s_FEH:
+ case a_s_QAF:
+ case a_s_KAF:
+ case a_s_LAM:
+ case a_s_MEEM:
+ case a_s_NOON:
+ case a_s_HEH:
+ case a_s_WAW:
+ case a_s_ALEF_MAKSURA:
+ case a_s_YEH:
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+/*
+ * Returns True if c is a Final shape of an ARABIC letter
+ */
+static int A_is_f(cur_c)
+int cur_c;
+{
+ switch (cur_c) {
+ case a_f_ALEF_MADDA:
+ case a_f_ALEF_HAMZA_ABOVE:
+ case a_f_WAW_HAMZA:
+ case a_f_ALEF_HAMZA_BELOW:
+ case a_f_YEH_HAMZA:
+ case a_f_ALEF:
+ case a_f_BEH:
+ case a_f_TEH_MARBUTA:
+ case a_f_TEH:
+ case a_f_THEH:
+ case a_f_JEEM:
+ case a_f_HAH:
+ case a_f_KHAH:
+ case a_f_DAL:
+ case a_f_THAL:
+ case a_f_REH:
+ case a_f_ZAIN:
+ case a_f_SEEN:
+ case a_f_SHEEN:
+ case a_f_SAD:
+ case a_f_DAD:
+ case a_f_TAH:
+ case a_f_ZAH:
+ case a_f_AIN:
+ case a_f_GHAIN:
+ case a_f_FEH:
+ case a_f_QAF:
+ case a_f_KAF:
+ case a_f_LAM:
+ case a_f_MEEM:
+ case a_f_NOON:
+ case a_f_HEH:
+ case a_f_WAW:
+ case a_f_ALEF_MAKSURA:
+ case a_f_YEH:
+ 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:
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+/*
+ * Change shape - from ISO-8859-6/Isolated to Form-B Isolated
+ */
+static int chg_c_a2s(cur_c)
+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;
+ }
+
+ return tempc;
+}
+
+
+/*
+ * Change shape - from ISO-8859-6/Isolated to Initial
+ */
+static int chg_c_a2i(cur_c)
+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;
+ }
+
+ return tempc;
+}
+
+
+/*
+ * Change shape - from ISO-8859-6/Isolated to Medial
+ */
+static int chg_c_a2m(cur_c)
+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;
+ }
+
+ return tempc;
+}
+
+
+/*
+ * Change shape - from ISO-8859-6/Isolated to final
+ */
+static int chg_c_a2f(cur_c)
+int cur_c;
+{
+ int tempc;
+
+ /* NOTE: these encodings need to be accounted for
+
+ a_f_ALEF_MADDA;
+ a_f_ALEF_HAMZA_ABOVE;
+ a_f_ALEF_HAMZA_BELOW;
+ a_f_LAM_ALEF_MADDA_ABOVE;
+ a_f_LAM_ALEF_HAMZA_ABOVE;
+ 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;
+ }
+
+ return tempc;
+}
+
+
+/*
+ * Change shape - from Initial to Medial
+ */
+static int chg_c_i2m(cur_c)
+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;
+ }
+
+ return tempc;
+}
+
+
+/*
+ * Change shape - from Final to Medial
+ */
+static int chg_c_f2m(cur_c)
+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_WAW_HAMZA: /* exceptions */
+ case a_f_ALEF:
+ case a_f_TEH_MARBUTA:
+ case a_f_DAL:
+ case a_f_THAL:
+ case a_f_REH:
+ 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;
+ /* 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;
+}
+
+
+/*
+ * Change shape - from Combination (2 char) to an Isolated
+ */
+static int chg_c_laa2i(hid_c)
+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;
+ }
+
+ return tempc;
+}
+
+
+/*
+ * Change shape - from Combination-Isolated to Final
+ */
+static int chg_c_laa2f(hid_c)
+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;
+ }
+
+ return tempc;
+}
+
+/*
+ * Do "half-shaping" on character "c". Return zero if no shaping.
+ */
+static int half_shape(c)
+int c;
+{
+ if (A_is_a(c))
+ return chg_c_a2i(c);
+ if (A_is_valid(c) && A_is_f(c))
+ return chg_c_f2m(c);
+ return 0;
+}
+
+/*
+ * Do Arabic shaping on character "c". Returns the shaped character.
+ * out: "ccp" points to the first byte of the character to be shaped.
+ * in/out: "c1p" points to the first composing char for "c".
+ * in: "prev_c" is the previous character (not shaped)
+ * in: "prev_c1" is the first composing char for the previous char
+ * (not shaped)
+ * in: "next_c" is the next character (not shaped).
+ */
+int arabic_shape(c, ccp, c1p, prev_c, prev_c1, next_c)
+int c;
+int *ccp;
+int *c1p;
+int prev_c;
+int prev_c1;
+int next_c;
+{
+ int curr_c;
+ int shape_c;
+ int curr_laa;
+ int prev_laa;
+
+ /* Deal only with Arabic character, pass back all others */
+ if (!A_is_ok(c))
+ return c;
+
+ /* half-shape current and previous character */
+ shape_c = half_shape(prev_c);
+
+ /* Save away current character */
+ curr_c = c;
+
+ curr_laa = A_firstc_laa(c, *c1p);
+ prev_laa = A_firstc_laa(prev_c, prev_c1);
+
+ if (curr_laa) {
+ if (A_is_valid(prev_c) && !A_is_f(shape_c)
+ && !A_is_s(shape_c) && !prev_laa)
+ curr_c = chg_c_laa2f(curr_laa);
+ else
+ curr_c = chg_c_laa2i(curr_laa);
+
+ /* Remove the composing character */
+ *c1p = 0;
+ } else if (!A_is_valid(prev_c) && A_is_valid(next_c))
+ curr_c = chg_c_a2i(c);
+ 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))
+ curr_c = A_is_iso(c) ? chg_c_a2m(c) : chg_c_i2m(c);
+ else if (A_is_valid(prev_c))
+ curr_c = chg_c_a2f(c);
+ else
+ curr_c = chg_c_a2s(c);
+
+ /* Sanity check -- curr_c should, in the future, never be 0.
+ * We should, in the future, insert a fatal error here. */
+ if (curr_c == NUL)
+ curr_c = c;
+
+ if (curr_c != c && ccp != NULL) {
+ char_u buf[MB_MAXBYTES + 1];
+
+ /* Update the first byte of the character. */
+ (*mb_char2bytes)(curr_c, buf);
+ *ccp = buf[0];
+ }
+
+ /* Return the shaped character */
+ return curr_c;
+}
+
+
+/*
+ * A_firstc_laa returns first character of LAA combination if it exists
+ */
+static int A_firstc_laa(c, c1)
+int c; /* base character */
+int c1; /* first composing character */
+{
+ if (c1 != NUL && c == a_LAM && !A_is_harakat(c1))
+ return c1;
+ return 0;
+}
+
+
+/*
+ * A_is_harakat returns TRUE if 'c' is an Arabic Harakat character
+ * (harakat/tanween)
+ */
+static int A_is_harakat(c)
+int c;
+{
+ return c >= a_FATHATAN && c <= a_SUKUN;
+}
+
+
+/*
+ * A_is_iso returns TRUE if 'c' is an Arabic ISO-8859-6 character
+ * (alphabet/number/punctuation)
+ */
+static int A_is_iso(c)
+int c;
+{
+ return (c >= a_HAMZA && c <= a_GHAIN)
+ || (c >= a_TATWEEL && c <= a_HAMZA_BELOW)
+ || c == a_MINI_ALEF;
+}
+
+
+/*
+ * A_is_formb returns TRUE if 'c' is an Arabic 10646-1 FormB character
+ * (alphabet/number/punctuation)
+ */
+static int A_is_formb(c)
+int c;
+{
+ return (c >= a_s_FATHATAN && c <= a_s_DAMMATAN)
+ || c == a_s_KASRATAN
+ || (c >= a_s_FATHA && c <= a_f_LAM_ALEF)
+ || c == a_BYTE_ORDER_MARK;
+}
+
+
+/*
+ * A_is_ok returns TRUE if 'c' is an Arabic 10646 (8859-6 or Form-B)
+ */
+static int A_is_ok(c)
+int c;
+{
+ return A_is_iso(c) || A_is_formb(c);
+}
+
+
+/*
+ * A_is_valid returns TRUE if 'c' is an Arabic 10646 (8859-6 or Form-B)
+ * with some exceptions/exclusions
+ */
+static int A_is_valid(c)
+int c;
+{
+ return A_is_ok(c) && !A_is_special(c);
+}
+
+
+/*
+ * A_is_special returns TRUE if 'c' is not a special Arabic character.
+ * Specials don't adhere to most of the rules.
+ */
+static int A_is_special(c)
+int c;
+{
+ return c == a_HAMZA || c == a_s_HAMZA;
+}
diff --git a/src/arabic.h b/src/arabic.h
new file mode 100644
index 0000000000..6b277351cf
--- /dev/null
+++ b/src/arabic.h
@@ -0,0 +1,258 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * 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.
+ */
+
+/*
+ * Arabic characters are categorized into following types:
+ *
+ * Isolated - iso-8859-6 form char denoted with a_*
+ * Initial - unicode form-B start char denoted with a_i_*
+ * Medial - unicode form-B middle char denoted with a_m_*
+ * Final - unicode form-B final char denoted with a_f_*
+ * Stand-Alone - unicode form-B isolated char denoted with a_s_* (NOT USED)
+ *
+ * --
+ *
+ * Author: Nadim Shaikli & Isam Bayazidi
+ * - (based on Unicode)
+ *
+ */
+
+/*
+ * Arabic ISO-10646-1 character set definition
+ */
+
+/*
+ * Arabic ISO-8859-6 (subset of 10646; 0600 - 06FF)
+ */
+#define a_COMMA 0x060C
+#define a_SEMICOLON 0x061B
+#define a_QUESTION 0x061F
+#define a_HAMZA 0x0621
+#define a_ALEF_MADDA 0x0622
+#define a_ALEF_HAMZA_ABOVE 0x0623
+#define a_WAW_HAMZA 0x0624
+#define a_ALEF_HAMZA_BELOW 0x0625
+#define a_YEH_HAMZA 0x0626
+#define a_ALEF 0x0627
+#define a_BEH 0x0628
+#define a_TEH_MARBUTA 0x0629
+#define a_TEH 0x062a
+#define a_THEH 0x062b
+#define a_JEEM 0x062c
+#define a_HAH 0x062d
+#define a_KHAH 0x062e
+#define a_DAL 0x062f
+#define a_THAL 0x0630
+#define a_REH 0x0631
+#define a_ZAIN 0x0632
+#define a_SEEN 0x0633
+#define a_SHEEN 0x0634
+#define a_SAD 0x0635
+#define a_DAD 0x0636
+#define a_TAH 0x0637
+#define a_ZAH 0x0638
+#define a_AIN 0x0639
+#define a_GHAIN 0x063a
+#define a_TATWEEL 0x0640
+#define a_FEH 0x0641
+#define a_QAF 0x0642
+#define a_KAF 0x0643
+#define a_LAM 0x0644
+#define a_MEEM 0x0645
+#define a_NOON 0x0646
+#define a_HEH 0x0647
+#define a_WAW 0x0648
+#define a_ALEF_MAKSURA 0x0649
+#define a_YEH 0x064a
+
+#define a_FATHATAN 0x064b
+#define a_DAMMATAN 0x064c
+#define a_KASRATAN 0x064d
+#define a_FATHA 0x064e
+#define a_DAMMA 0x064f
+#define a_KASRA 0x0650
+#define a_SHADDA 0x0651
+#define a_SUKUN 0x0652
+
+#define a_MADDA_ABOVE 0x0653
+#define a_HAMZA_ABOVE 0x0654
+#define a_HAMZA_BELOW 0x0655
+
+#define a_ZERO 0x0660
+#define a_ONE 0x0661
+#define a_TWO 0x0662
+#define a_THREE 0x0663
+#define a_FOUR 0x0664
+#define a_FIVE 0x0665
+#define a_SIX 0x0666
+#define a_SEVEN 0x0667
+#define a_EIGHT 0x0668
+#define a_NINE 0x0669
+#define a_PERCENT 0x066a
+#define a_DECIMAL 0x066b
+#define a_THOUSANDS 0x066c
+#define a_STAR 0x066d
+#define a_MINI_ALEF 0x0670
+/* Rest of 8859-6 does not relate to Arabic */
+
+/*
+ * Arabic Presentation Form-B (subset of 10646; FE70 - FEFF)
+ *
+ * s -> isolated
+ * i -> initial
+ * m -> medial
+ * f -> final
+ *
+ */
+#define a_s_FATHATAN 0xfe70
+#define a_m_TATWEEL_FATHATAN 0xfe71
+#define a_s_DAMMATAN 0xfe72
+
+#define a_s_KASRATAN 0xfe74
+
+#define a_s_FATHA 0xfe76
+#define a_m_FATHA 0xfe77
+#define a_s_DAMMA 0xfe78
+#define a_m_DAMMA 0xfe79
+#define a_s_KASRA 0xfe7a
+#define a_m_KASRA 0xfe7b
+#define a_s_SHADDA 0xfe7c
+#define a_m_SHADDA 0xfe7d
+#define a_s_SUKUN 0xfe7e
+#define a_m_SUKUN 0xfe7f
+
+#define a_s_HAMZA 0xfe80
+#define a_s_ALEF_MADDA 0xfe81
+#define a_f_ALEF_MADDA 0xfe82
+#define a_s_ALEF_HAMZA_ABOVE 0xfe83
+#define a_f_ALEF_HAMZA_ABOVE 0xfe84
+#define a_s_WAW_HAMZA 0xfe85
+#define a_f_WAW_HAMZA 0xfe86
+#define a_s_ALEF_HAMZA_BELOW 0xfe87
+#define a_f_ALEF_HAMZA_BELOW 0xfe88
+#define a_s_YEH_HAMZA 0xfe89
+#define a_f_YEH_HAMZA 0xfe8a
+#define a_i_YEH_HAMZA 0xfe8b
+#define a_m_YEH_HAMZA 0xfe8c
+#define a_s_ALEF 0xfe8d
+#define a_f_ALEF 0xfe8e
+#define a_s_BEH 0xfe8f
+#define a_f_BEH 0xfe90
+#define a_i_BEH 0xfe91
+#define a_m_BEH 0xfe92
+#define a_s_TEH_MARBUTA 0xfe93
+#define a_f_TEH_MARBUTA 0xfe94
+#define a_s_TEH 0xfe95
+#define a_f_TEH 0xfe96
+#define a_i_TEH 0xfe97
+#define a_m_TEH 0xfe98
+#define a_s_THEH 0xfe99
+#define a_f_THEH 0xfe9a
+#define a_i_THEH 0xfe9b
+#define a_m_THEH 0xfe9c
+#define a_s_JEEM 0xfe9d
+#define a_f_JEEM 0xfe9e
+#define a_i_JEEM 0xfe9f
+#define a_m_JEEM 0xfea0
+#define a_s_HAH 0xfea1
+#define a_f_HAH 0xfea2
+#define a_i_HAH 0xfea3
+#define a_m_HAH 0xfea4
+#define a_s_KHAH 0xfea5
+#define a_f_KHAH 0xfea6
+#define a_i_KHAH 0xfea7
+#define a_m_KHAH 0xfea8
+#define a_s_DAL 0xfea9
+#define a_f_DAL 0xfeaa
+#define a_s_THAL 0xfeab
+#define a_f_THAL 0xfeac
+#define a_s_REH 0xfead
+#define a_f_REH 0xfeae
+#define a_s_ZAIN 0xfeaf
+#define a_f_ZAIN 0xfeb0
+#define a_s_SEEN 0xfeb1
+#define a_f_SEEN 0xfeb2
+#define a_i_SEEN 0xfeb3
+#define a_m_SEEN 0xfeb4
+#define a_s_SHEEN 0xfeb5
+#define a_f_SHEEN 0xfeb6
+#define a_i_SHEEN 0xfeb7
+#define a_m_SHEEN 0xfeb8
+#define a_s_SAD 0xfeb9
+#define a_f_SAD 0xfeba
+#define a_i_SAD 0xfebb
+#define a_m_SAD 0xfebc
+#define a_s_DAD 0xfebd
+#define a_f_DAD 0xfebe
+#define a_i_DAD 0xfebf
+#define a_m_DAD 0xfec0
+#define a_s_TAH 0xfec1
+#define a_f_TAH 0xfec2
+#define a_i_TAH 0xfec3
+#define a_m_TAH 0xfec4
+#define a_s_ZAH 0xfec5
+#define a_f_ZAH 0xfec6
+#define a_i_ZAH 0xfec7
+#define a_m_ZAH 0xfec8
+#define a_s_AIN 0xfec9
+#define a_f_AIN 0xfeca
+#define a_i_AIN 0xfecb
+#define a_m_AIN 0xfecc
+#define a_s_GHAIN 0xfecd
+#define a_f_GHAIN 0xfece
+#define a_i_GHAIN 0xfecf
+#define a_m_GHAIN 0xfed0
+#define a_s_FEH 0xfed1
+#define a_f_FEH 0xfed2
+#define a_i_FEH 0xfed3
+#define a_m_FEH 0xfed4
+#define a_s_QAF 0xfed5
+#define a_f_QAF 0xfed6
+#define a_i_QAF 0xfed7
+#define a_m_QAF 0xfed8
+#define a_s_KAF 0xfed9
+#define a_f_KAF 0xfeda
+#define a_i_KAF 0xfedb
+#define a_m_KAF 0xfedc
+#define a_s_LAM 0xfedd
+#define a_f_LAM 0xfede
+#define a_i_LAM 0xfedf
+#define a_m_LAM 0xfee0
+#define a_s_MEEM 0xfee1
+#define a_f_MEEM 0xfee2
+#define a_i_MEEM 0xfee3
+#define a_m_MEEM 0xfee4
+#define a_s_NOON 0xfee5
+#define a_f_NOON 0xfee6
+#define a_i_NOON 0xfee7
+#define a_m_NOON 0xfee8
+#define a_s_HEH 0xfee9
+#define a_f_HEH 0xfeea
+#define a_i_HEH 0xfeeb
+#define a_m_HEH 0xfeec
+#define a_s_WAW 0xfeed
+#define a_f_WAW 0xfeee
+#define a_s_ALEF_MAKSURA 0xfeef
+#define a_f_ALEF_MAKSURA 0xfef0
+#define a_s_YEH 0xfef1
+#define a_f_YEH 0xfef2
+#define a_i_YEH 0xfef3
+#define a_m_YEH 0xfef4
+#define a_s_LAM_ALEF_MADDA_ABOVE 0xfef5
+#define a_f_LAM_ALEF_MADDA_ABOVE 0xfef6
+#define a_s_LAM_ALEF_HAMZA_ABOVE 0xfef7
+#define a_f_LAM_ALEF_HAMZA_ABOVE 0xfef8
+#define a_s_LAM_ALEF_HAMZA_BELOW 0xfef9
+#define a_f_LAM_ALEF_HAMZA_BELOW 0xfefa
+#define a_s_LAM_ALEF 0xfefb
+#define a_f_LAM_ALEF 0xfefc
+
+#define a_BYTE_ORDER_MARK 0xfeff
+
+/* Range of Arabic characters that might be shaped. */
+#define ARABIC_CHAR(c) ((c) >= a_HAMZA && (c) <= a_MINI_ALEF)
diff --git a/src/ascii.h b/src/ascii.h
new file mode 100644
index 0000000000..0904521ccf
--- /dev/null
+++ b/src/ascii.h
@@ -0,0 +1,96 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * 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.
+ */
+
+/*
+ * Definitions of various common control characters.
+ * For EBCDIC we have to use different values.
+ */
+
+
+/* IF_EB(ASCII_constant, EBCDIC_constant) */
+#define IF_EB(a, b) a
+
+#define CharOrd(x) ((x) < 'a' ? (x) - 'A' : (x) - 'a')
+#define CharOrdLow(x) ((x) - 'a')
+#define CharOrdUp(x) ((x) - 'A')
+#define ROT13(c, a) (((((c) - (a)) + 13) % 26) + (a))
+
+#define NUL '\000'
+#define BELL '\007'
+#define BS '\010'
+#define TAB '\011'
+#define NL '\012'
+#define NL_STR (char_u *)"\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 DEL 0x7f
+#define DEL_STR (char_u *)"\177"
+#define CSI 0x9b /* Control Sequence Introducer */
+#define CSI_STR "\233"
+#define DCS 0x90 /* Device Control String */
+#define STERM 0x9c /* String Terminator */
+
+#define POUND 0xA3
+
+#define Ctrl_chr(x) (TOUPPER_ASC(x) ^ 0x40) /* '?' -> DEL, '@' -> ^@, etc. */
+#define Meta(x) ((x) | 0x80)
+
+#define CTRL_F_STR "\006"
+#define CTRL_H_STR "\010"
+#define CTRL_V_STR "\026"
+
+#define Ctrl_AT 0 /* @ */
+#define Ctrl_A 1
+#define Ctrl_B 2
+#define Ctrl_C 3
+#define Ctrl_D 4
+#define Ctrl_E 5
+#define Ctrl_F 6
+#define Ctrl_G 7
+#define Ctrl_H 8
+#define Ctrl_I 9
+#define Ctrl_J 10
+#define Ctrl_K 11
+#define Ctrl_L 12
+#define Ctrl_M 13
+#define Ctrl_N 14
+#define Ctrl_O 15
+#define Ctrl_P 16
+#define Ctrl_Q 17
+#define Ctrl_R 18
+#define Ctrl_S 19
+#define Ctrl_T 20
+#define Ctrl_U 21
+#define Ctrl_V 22
+#define Ctrl_W 23
+#define Ctrl_X 24
+#define Ctrl_Y 25
+#define Ctrl_Z 26
+/* CTRL- [ Left Square Bracket == ESC*/
+#define Ctrl_BSL 28 /* \ BackSLash */
+#define Ctrl_RSB 29 /* ] Right Square Bracket */
+#define Ctrl_HAT 30 /* ^ */
+#define Ctrl__ 31
+
+
+/*
+ * Character that separates dir names in a path.
+ * For MS-DOS, WIN32 and OS/2 we use a backslash. A slash mostly works
+ * fine, but there are places where it doesn't (e.g. in a command name).
+ * For Acorn we use a dot.
+ */
+#ifdef BACKSLASH_IN_FILENAME
+# define PATHSEP psepc
+# define PATHSEPSTR pseps
+#else
+# define PATHSEP '/'
+# define PATHSEPSTR "/"
+#endif
diff --git a/src/blowfish.c b/src/blowfish.c
new file mode 100644
index 0000000000..2e4d8cf1af
--- /dev/null
+++ b/src/blowfish.c
@@ -0,0 +1,637 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * 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.
+ *
+ * Blowfish encryption for Vim; in Blowfish output feedback mode.
+ * Contributed by Mohsin Ahmed, http://www.cs.albany.edu/~mosh
+ * Based on http://www.schneier.com/blowfish.html by Bruce Schneier.
+ */
+
+#include "vim.h"
+
+
+#define ARRAY_LENGTH(A) (sizeof(A)/sizeof(A[0]))
+
+#define BF_BLOCK 8
+#define BF_BLOCK_MASK 7
+#define BF_OFB_LEN (8*(BF_BLOCK))
+
+typedef union {
+ UINT32_T ul[2];
+ char_u uc[8];
+} block8;
+
+
+static void bf_e_block __ARGS((UINT32_T *p_xl, UINT32_T *p_xr));
+static void bf_e_cblock __ARGS((char_u *block));
+static int bf_check_tables __ARGS((UINT32_T a_ipa[18], UINT32_T a_sbi[4][256],
+ UINT32_T val));
+static int bf_self_test __ARGS((void));
+
+/* Blowfish code */
+static UINT32_T pax[18];
+static UINT32_T ipa[18] = {
+ 0x243f6a88u, 0x85a308d3u, 0x13198a2eu,
+ 0x03707344u, 0xa4093822u, 0x299f31d0u,
+ 0x082efa98u, 0xec4e6c89u, 0x452821e6u,
+ 0x38d01377u, 0xbe5466cfu, 0x34e90c6cu,
+ 0xc0ac29b7u, 0xc97c50ddu, 0x3f84d5b5u,
+ 0xb5470917u, 0x9216d5d9u, 0x8979fb1bu
+};
+
+static UINT32_T sbx[4][256];
+static UINT32_T sbi[4][256] = {
+ {0xd1310ba6u, 0x98dfb5acu, 0x2ffd72dbu, 0xd01adfb7u,
+ 0xb8e1afedu, 0x6a267e96u, 0xba7c9045u, 0xf12c7f99u,
+ 0x24a19947u, 0xb3916cf7u, 0x0801f2e2u, 0x858efc16u,
+ 0x636920d8u, 0x71574e69u, 0xa458fea3u, 0xf4933d7eu,
+ 0x0d95748fu, 0x728eb658u, 0x718bcd58u, 0x82154aeeu,
+ 0x7b54a41du, 0xc25a59b5u, 0x9c30d539u, 0x2af26013u,
+ 0xc5d1b023u, 0x286085f0u, 0xca417918u, 0xb8db38efu,
+ 0x8e79dcb0u, 0x603a180eu, 0x6c9e0e8bu, 0xb01e8a3eu,
+ 0xd71577c1u, 0xbd314b27u, 0x78af2fdau, 0x55605c60u,
+ 0xe65525f3u, 0xaa55ab94u, 0x57489862u, 0x63e81440u,
+ 0x55ca396au, 0x2aab10b6u, 0xb4cc5c34u, 0x1141e8ceu,
+ 0xa15486afu, 0x7c72e993u, 0xb3ee1411u, 0x636fbc2au,
+ 0x2ba9c55du, 0x741831f6u, 0xce5c3e16u, 0x9b87931eu,
+ 0xafd6ba33u, 0x6c24cf5cu, 0x7a325381u, 0x28958677u,
+ 0x3b8f4898u, 0x6b4bb9afu, 0xc4bfe81bu, 0x66282193u,
+ 0x61d809ccu, 0xfb21a991u, 0x487cac60u, 0x5dec8032u,
+ 0xef845d5du, 0xe98575b1u, 0xdc262302u, 0xeb651b88u,
+ 0x23893e81u, 0xd396acc5u, 0x0f6d6ff3u, 0x83f44239u,
+ 0x2e0b4482u, 0xa4842004u, 0x69c8f04au, 0x9e1f9b5eu,
+ 0x21c66842u, 0xf6e96c9au, 0x670c9c61u, 0xabd388f0u,
+ 0x6a51a0d2u, 0xd8542f68u, 0x960fa728u, 0xab5133a3u,
+ 0x6eef0b6cu, 0x137a3be4u, 0xba3bf050u, 0x7efb2a98u,
+ 0xa1f1651du, 0x39af0176u, 0x66ca593eu, 0x82430e88u,
+ 0x8cee8619u, 0x456f9fb4u, 0x7d84a5c3u, 0x3b8b5ebeu,
+ 0xe06f75d8u, 0x85c12073u, 0x401a449fu, 0x56c16aa6u,
+ 0x4ed3aa62u, 0x363f7706u, 0x1bfedf72u, 0x429b023du,
+ 0x37d0d724u, 0xd00a1248u, 0xdb0fead3u, 0x49f1c09bu,
+ 0x075372c9u, 0x80991b7bu, 0x25d479d8u, 0xf6e8def7u,
+ 0xe3fe501au, 0xb6794c3bu, 0x976ce0bdu, 0x04c006bau,
+ 0xc1a94fb6u, 0x409f60c4u, 0x5e5c9ec2u, 0x196a2463u,
+ 0x68fb6fafu, 0x3e6c53b5u, 0x1339b2ebu, 0x3b52ec6fu,
+ 0x6dfc511fu, 0x9b30952cu, 0xcc814544u, 0xaf5ebd09u,
+ 0xbee3d004u, 0xde334afdu, 0x660f2807u, 0x192e4bb3u,
+ 0xc0cba857u, 0x45c8740fu, 0xd20b5f39u, 0xb9d3fbdbu,
+ 0x5579c0bdu, 0x1a60320au, 0xd6a100c6u, 0x402c7279u,
+ 0x679f25feu, 0xfb1fa3ccu, 0x8ea5e9f8u, 0xdb3222f8u,
+ 0x3c7516dfu, 0xfd616b15u, 0x2f501ec8u, 0xad0552abu,
+ 0x323db5fau, 0xfd238760u, 0x53317b48u, 0x3e00df82u,
+ 0x9e5c57bbu, 0xca6f8ca0u, 0x1a87562eu, 0xdf1769dbu,
+ 0xd542a8f6u, 0x287effc3u, 0xac6732c6u, 0x8c4f5573u,
+ 0x695b27b0u, 0xbbca58c8u, 0xe1ffa35du, 0xb8f011a0u,
+ 0x10fa3d98u, 0xfd2183b8u, 0x4afcb56cu, 0x2dd1d35bu,
+ 0x9a53e479u, 0xb6f84565u, 0xd28e49bcu, 0x4bfb9790u,
+ 0xe1ddf2dau, 0xa4cb7e33u, 0x62fb1341u, 0xcee4c6e8u,
+ 0xef20cadau, 0x36774c01u, 0xd07e9efeu, 0x2bf11fb4u,
+ 0x95dbda4du, 0xae909198u, 0xeaad8e71u, 0x6b93d5a0u,
+ 0xd08ed1d0u, 0xafc725e0u, 0x8e3c5b2fu, 0x8e7594b7u,
+ 0x8ff6e2fbu, 0xf2122b64u, 0x8888b812u, 0x900df01cu,
+ 0x4fad5ea0u, 0x688fc31cu, 0xd1cff191u, 0xb3a8c1adu,
+ 0x2f2f2218u, 0xbe0e1777u, 0xea752dfeu, 0x8b021fa1u,
+ 0xe5a0cc0fu, 0xb56f74e8u, 0x18acf3d6u, 0xce89e299u,
+ 0xb4a84fe0u, 0xfd13e0b7u, 0x7cc43b81u, 0xd2ada8d9u,
+ 0x165fa266u, 0x80957705u, 0x93cc7314u, 0x211a1477u,
+ 0xe6ad2065u, 0x77b5fa86u, 0xc75442f5u, 0xfb9d35cfu,
+ 0xebcdaf0cu, 0x7b3e89a0u, 0xd6411bd3u, 0xae1e7e49u,
+ 0x00250e2du, 0x2071b35eu, 0x226800bbu, 0x57b8e0afu,
+ 0x2464369bu, 0xf009b91eu, 0x5563911du, 0x59dfa6aau,
+ 0x78c14389u, 0xd95a537fu, 0x207d5ba2u, 0x02e5b9c5u,
+ 0x83260376u, 0x6295cfa9u, 0x11c81968u, 0x4e734a41u,
+ 0xb3472dcau, 0x7b14a94au, 0x1b510052u, 0x9a532915u,
+ 0xd60f573fu, 0xbc9bc6e4u, 0x2b60a476u, 0x81e67400u,
+ 0x08ba6fb5u, 0x571be91fu, 0xf296ec6bu, 0x2a0dd915u,
+ 0xb6636521u, 0xe7b9f9b6u, 0xff34052eu, 0xc5855664u,
+ 0x53b02d5du, 0xa99f8fa1u, 0x08ba4799u, 0x6e85076au},
+ {0x4b7a70e9u, 0xb5b32944u, 0xdb75092eu, 0xc4192623u,
+ 0xad6ea6b0u, 0x49a7df7du, 0x9cee60b8u, 0x8fedb266u,
+ 0xecaa8c71u, 0x699a17ffu, 0x5664526cu, 0xc2b19ee1u,
+ 0x193602a5u, 0x75094c29u, 0xa0591340u, 0xe4183a3eu,
+ 0x3f54989au, 0x5b429d65u, 0x6b8fe4d6u, 0x99f73fd6u,
+ 0xa1d29c07u, 0xefe830f5u, 0x4d2d38e6u, 0xf0255dc1u,
+ 0x4cdd2086u, 0x8470eb26u, 0x6382e9c6u, 0x021ecc5eu,
+ 0x09686b3fu, 0x3ebaefc9u, 0x3c971814u, 0x6b6a70a1u,
+ 0x687f3584u, 0x52a0e286u, 0xb79c5305u, 0xaa500737u,
+ 0x3e07841cu, 0x7fdeae5cu, 0x8e7d44ecu, 0x5716f2b8u,
+ 0xb03ada37u, 0xf0500c0du, 0xf01c1f04u, 0x0200b3ffu,
+ 0xae0cf51au, 0x3cb574b2u, 0x25837a58u, 0xdc0921bdu,
+ 0xd19113f9u, 0x7ca92ff6u, 0x94324773u, 0x22f54701u,
+ 0x3ae5e581u, 0x37c2dadcu, 0xc8b57634u, 0x9af3dda7u,
+ 0xa9446146u, 0x0fd0030eu, 0xecc8c73eu, 0xa4751e41u,
+ 0xe238cd99u, 0x3bea0e2fu, 0x3280bba1u, 0x183eb331u,
+ 0x4e548b38u, 0x4f6db908u, 0x6f420d03u, 0xf60a04bfu,
+ 0x2cb81290u, 0x24977c79u, 0x5679b072u, 0xbcaf89afu,
+ 0xde9a771fu, 0xd9930810u, 0xb38bae12u, 0xdccf3f2eu,
+ 0x5512721fu, 0x2e6b7124u, 0x501adde6u, 0x9f84cd87u,
+ 0x7a584718u, 0x7408da17u, 0xbc9f9abcu, 0xe94b7d8cu,
+ 0xec7aec3au, 0xdb851dfau, 0x63094366u, 0xc464c3d2u,
+ 0xef1c1847u, 0x3215d908u, 0xdd433b37u, 0x24c2ba16u,
+ 0x12a14d43u, 0x2a65c451u, 0x50940002u, 0x133ae4ddu,
+ 0x71dff89eu, 0x10314e55u, 0x81ac77d6u, 0x5f11199bu,
+ 0x043556f1u, 0xd7a3c76bu, 0x3c11183bu, 0x5924a509u,
+ 0xf28fe6edu, 0x97f1fbfau, 0x9ebabf2cu, 0x1e153c6eu,
+ 0x86e34570u, 0xeae96fb1u, 0x860e5e0au, 0x5a3e2ab3u,
+ 0x771fe71cu, 0x4e3d06fau, 0x2965dcb9u, 0x99e71d0fu,
+ 0x803e89d6u, 0x5266c825u, 0x2e4cc978u, 0x9c10b36au,
+ 0xc6150ebau, 0x94e2ea78u, 0xa5fc3c53u, 0x1e0a2df4u,
+ 0xf2f74ea7u, 0x361d2b3du, 0x1939260fu, 0x19c27960u,
+ 0x5223a708u, 0xf71312b6u, 0xebadfe6eu, 0xeac31f66u,
+ 0xe3bc4595u, 0xa67bc883u, 0xb17f37d1u, 0x018cff28u,
+ 0xc332ddefu, 0xbe6c5aa5u, 0x65582185u, 0x68ab9802u,
+ 0xeecea50fu, 0xdb2f953bu, 0x2aef7dadu, 0x5b6e2f84u,
+ 0x1521b628u, 0x29076170u, 0xecdd4775u, 0x619f1510u,
+ 0x13cca830u, 0xeb61bd96u, 0x0334fe1eu, 0xaa0363cfu,
+ 0xb5735c90u, 0x4c70a239u, 0xd59e9e0bu, 0xcbaade14u,
+ 0xeecc86bcu, 0x60622ca7u, 0x9cab5cabu, 0xb2f3846eu,
+ 0x648b1eafu, 0x19bdf0cau, 0xa02369b9u, 0x655abb50u,
+ 0x40685a32u, 0x3c2ab4b3u, 0x319ee9d5u, 0xc021b8f7u,
+ 0x9b540b19u, 0x875fa099u, 0x95f7997eu, 0x623d7da8u,
+ 0xf837889au, 0x97e32d77u, 0x11ed935fu, 0x16681281u,
+ 0x0e358829u, 0xc7e61fd6u, 0x96dedfa1u, 0x7858ba99u,
+ 0x57f584a5u, 0x1b227263u, 0x9b83c3ffu, 0x1ac24696u,
+ 0xcdb30aebu, 0x532e3054u, 0x8fd948e4u, 0x6dbc3128u,
+ 0x58ebf2efu, 0x34c6ffeau, 0xfe28ed61u, 0xee7c3c73u,
+ 0x5d4a14d9u, 0xe864b7e3u, 0x42105d14u, 0x203e13e0u,
+ 0x45eee2b6u, 0xa3aaabeau, 0xdb6c4f15u, 0xfacb4fd0u,
+ 0xc742f442u, 0xef6abbb5u, 0x654f3b1du, 0x41cd2105u,
+ 0xd81e799eu, 0x86854dc7u, 0xe44b476au, 0x3d816250u,
+ 0xcf62a1f2u, 0x5b8d2646u, 0xfc8883a0u, 0xc1c7b6a3u,
+ 0x7f1524c3u, 0x69cb7492u, 0x47848a0bu, 0x5692b285u,
+ 0x095bbf00u, 0xad19489du, 0x1462b174u, 0x23820e00u,
+ 0x58428d2au, 0x0c55f5eau, 0x1dadf43eu, 0x233f7061u,
+ 0x3372f092u, 0x8d937e41u, 0xd65fecf1u, 0x6c223bdbu,
+ 0x7cde3759u, 0xcbee7460u, 0x4085f2a7u, 0xce77326eu,
+ 0xa6078084u, 0x19f8509eu, 0xe8efd855u, 0x61d99735u,
+ 0xa969a7aau, 0xc50c06c2u, 0x5a04abfcu, 0x800bcadcu,
+ 0x9e447a2eu, 0xc3453484u, 0xfdd56705u, 0x0e1e9ec9u,
+ 0xdb73dbd3u, 0x105588cdu, 0x675fda79u, 0xe3674340u,
+ 0xc5c43465u, 0x713e38d8u, 0x3d28f89eu, 0xf16dff20u,
+ 0x153e21e7u, 0x8fb03d4au, 0xe6e39f2bu, 0xdb83adf7u},
+ {0xe93d5a68u, 0x948140f7u, 0xf64c261cu, 0x94692934u,
+ 0x411520f7u, 0x7602d4f7u, 0xbcf46b2eu, 0xd4a20068u,
+ 0xd4082471u, 0x3320f46au, 0x43b7d4b7u, 0x500061afu,
+ 0x1e39f62eu, 0x97244546u, 0x14214f74u, 0xbf8b8840u,
+ 0x4d95fc1du, 0x96b591afu, 0x70f4ddd3u, 0x66a02f45u,
+ 0xbfbc09ecu, 0x03bd9785u, 0x7fac6dd0u, 0x31cb8504u,
+ 0x96eb27b3u, 0x55fd3941u, 0xda2547e6u, 0xabca0a9au,
+ 0x28507825u, 0x530429f4u, 0x0a2c86dau, 0xe9b66dfbu,
+ 0x68dc1462u, 0xd7486900u, 0x680ec0a4u, 0x27a18deeu,
+ 0x4f3ffea2u, 0xe887ad8cu, 0xb58ce006u, 0x7af4d6b6u,
+ 0xaace1e7cu, 0xd3375fecu, 0xce78a399u, 0x406b2a42u,
+ 0x20fe9e35u, 0xd9f385b9u, 0xee39d7abu, 0x3b124e8bu,
+ 0x1dc9faf7u, 0x4b6d1856u, 0x26a36631u, 0xeae397b2u,
+ 0x3a6efa74u, 0xdd5b4332u, 0x6841e7f7u, 0xca7820fbu,
+ 0xfb0af54eu, 0xd8feb397u, 0x454056acu, 0xba489527u,
+ 0x55533a3au, 0x20838d87u, 0xfe6ba9b7u, 0xd096954bu,
+ 0x55a867bcu, 0xa1159a58u, 0xcca92963u, 0x99e1db33u,
+ 0xa62a4a56u, 0x3f3125f9u, 0x5ef47e1cu, 0x9029317cu,
+ 0xfdf8e802u, 0x04272f70u, 0x80bb155cu, 0x05282ce3u,
+ 0x95c11548u, 0xe4c66d22u, 0x48c1133fu, 0xc70f86dcu,
+ 0x07f9c9eeu, 0x41041f0fu, 0x404779a4u, 0x5d886e17u,
+ 0x325f51ebu, 0xd59bc0d1u, 0xf2bcc18fu, 0x41113564u,
+ 0x257b7834u, 0x602a9c60u, 0xdff8e8a3u, 0x1f636c1bu,
+ 0x0e12b4c2u, 0x02e1329eu, 0xaf664fd1u, 0xcad18115u,
+ 0x6b2395e0u, 0x333e92e1u, 0x3b240b62u, 0xeebeb922u,
+ 0x85b2a20eu, 0xe6ba0d99u, 0xde720c8cu, 0x2da2f728u,
+ 0xd0127845u, 0x95b794fdu, 0x647d0862u, 0xe7ccf5f0u,
+ 0x5449a36fu, 0x877d48fau, 0xc39dfd27u, 0xf33e8d1eu,
+ 0x0a476341u, 0x992eff74u, 0x3a6f6eabu, 0xf4f8fd37u,
+ 0xa812dc60u, 0xa1ebddf8u, 0x991be14cu, 0xdb6e6b0du,
+ 0xc67b5510u, 0x6d672c37u, 0x2765d43bu, 0xdcd0e804u,
+ 0xf1290dc7u, 0xcc00ffa3u, 0xb5390f92u, 0x690fed0bu,
+ 0x667b9ffbu, 0xcedb7d9cu, 0xa091cf0bu, 0xd9155ea3u,
+ 0xbb132f88u, 0x515bad24u, 0x7b9479bfu, 0x763bd6ebu,
+ 0x37392eb3u, 0xcc115979u, 0x8026e297u, 0xf42e312du,
+ 0x6842ada7u, 0xc66a2b3bu, 0x12754cccu, 0x782ef11cu,
+ 0x6a124237u, 0xb79251e7u, 0x06a1bbe6u, 0x4bfb6350u,
+ 0x1a6b1018u, 0x11caedfau, 0x3d25bdd8u, 0xe2e1c3c9u,
+ 0x44421659u, 0x0a121386u, 0xd90cec6eu, 0xd5abea2au,
+ 0x64af674eu, 0xda86a85fu, 0xbebfe988u, 0x64e4c3feu,
+ 0x9dbc8057u, 0xf0f7c086u, 0x60787bf8u, 0x6003604du,
+ 0xd1fd8346u, 0xf6381fb0u, 0x7745ae04u, 0xd736fcccu,
+ 0x83426b33u, 0xf01eab71u, 0xb0804187u, 0x3c005e5fu,
+ 0x77a057beu, 0xbde8ae24u, 0x55464299u, 0xbf582e61u,
+ 0x4e58f48fu, 0xf2ddfda2u, 0xf474ef38u, 0x8789bdc2u,
+ 0x5366f9c3u, 0xc8b38e74u, 0xb475f255u, 0x46fcd9b9u,
+ 0x7aeb2661u, 0x8b1ddf84u, 0x846a0e79u, 0x915f95e2u,
+ 0x466e598eu, 0x20b45770u, 0x8cd55591u, 0xc902de4cu,
+ 0xb90bace1u, 0xbb8205d0u, 0x11a86248u, 0x7574a99eu,
+ 0xb77f19b6u, 0xe0a9dc09u, 0x662d09a1u, 0xc4324633u,
+ 0xe85a1f02u, 0x09f0be8cu, 0x4a99a025u, 0x1d6efe10u,
+ 0x1ab93d1du, 0x0ba5a4dfu, 0xa186f20fu, 0x2868f169u,
+ 0xdcb7da83u, 0x573906feu, 0xa1e2ce9bu, 0x4fcd7f52u,
+ 0x50115e01u, 0xa70683fau, 0xa002b5c4u, 0x0de6d027u,
+ 0x9af88c27u, 0x773f8641u, 0xc3604c06u, 0x61a806b5u,
+ 0xf0177a28u, 0xc0f586e0u, 0x006058aau, 0x30dc7d62u,
+ 0x11e69ed7u, 0x2338ea63u, 0x53c2dd94u, 0xc2c21634u,
+ 0xbbcbee56u, 0x90bcb6deu, 0xebfc7da1u, 0xce591d76u,
+ 0x6f05e409u, 0x4b7c0188u, 0x39720a3du, 0x7c927c24u,
+ 0x86e3725fu, 0x724d9db9u, 0x1ac15bb4u, 0xd39eb8fcu,
+ 0xed545578u, 0x08fca5b5u, 0xd83d7cd3u, 0x4dad0fc4u,
+ 0x1e50ef5eu, 0xb161e6f8u, 0xa28514d9u, 0x6c51133cu,
+ 0x6fd5c7e7u, 0x56e14ec4u, 0x362abfceu, 0xddc6c837u,
+ 0xd79a3234u, 0x92638212u, 0x670efa8eu, 0x406000e0u},
+ {0x3a39ce37u, 0xd3faf5cfu, 0xabc27737u, 0x5ac52d1bu,
+ 0x5cb0679eu, 0x4fa33742u, 0xd3822740u, 0x99bc9bbeu,
+ 0xd5118e9du, 0xbf0f7315u, 0xd62d1c7eu, 0xc700c47bu,
+ 0xb78c1b6bu, 0x21a19045u, 0xb26eb1beu, 0x6a366eb4u,
+ 0x5748ab2fu, 0xbc946e79u, 0xc6a376d2u, 0x6549c2c8u,
+ 0x530ff8eeu, 0x468dde7du, 0xd5730a1du, 0x4cd04dc6u,
+ 0x2939bbdbu, 0xa9ba4650u, 0xac9526e8u, 0xbe5ee304u,
+ 0xa1fad5f0u, 0x6a2d519au, 0x63ef8ce2u, 0x9a86ee22u,
+ 0xc089c2b8u, 0x43242ef6u, 0xa51e03aau, 0x9cf2d0a4u,
+ 0x83c061bau, 0x9be96a4du, 0x8fe51550u, 0xba645bd6u,
+ 0x2826a2f9u, 0xa73a3ae1u, 0x4ba99586u, 0xef5562e9u,
+ 0xc72fefd3u, 0xf752f7dau, 0x3f046f69u, 0x77fa0a59u,
+ 0x80e4a915u, 0x87b08601u, 0x9b09e6adu, 0x3b3ee593u,
+ 0xe990fd5au, 0x9e34d797u, 0x2cf0b7d9u, 0x022b8b51u,
+ 0x96d5ac3au, 0x017da67du, 0xd1cf3ed6u, 0x7c7d2d28u,
+ 0x1f9f25cfu, 0xadf2b89bu, 0x5ad6b472u, 0x5a88f54cu,
+ 0xe029ac71u, 0xe019a5e6u, 0x47b0acfdu, 0xed93fa9bu,
+ 0xe8d3c48du, 0x283b57ccu, 0xf8d56629u, 0x79132e28u,
+ 0x785f0191u, 0xed756055u, 0xf7960e44u, 0xe3d35e8cu,
+ 0x15056dd4u, 0x88f46dbau, 0x03a16125u, 0x0564f0bdu,
+ 0xc3eb9e15u, 0x3c9057a2u, 0x97271aecu, 0xa93a072au,
+ 0x1b3f6d9bu, 0x1e6321f5u, 0xf59c66fbu, 0x26dcf319u,
+ 0x7533d928u, 0xb155fdf5u, 0x03563482u, 0x8aba3cbbu,
+ 0x28517711u, 0xc20ad9f8u, 0xabcc5167u, 0xccad925fu,
+ 0x4de81751u, 0x3830dc8eu, 0x379d5862u, 0x9320f991u,
+ 0xea7a90c2u, 0xfb3e7bceu, 0x5121ce64u, 0x774fbe32u,
+ 0xa8b6e37eu, 0xc3293d46u, 0x48de5369u, 0x6413e680u,
+ 0xa2ae0810u, 0xdd6db224u, 0x69852dfdu, 0x09072166u,
+ 0xb39a460au, 0x6445c0ddu, 0x586cdecfu, 0x1c20c8aeu,
+ 0x5bbef7ddu, 0x1b588d40u, 0xccd2017fu, 0x6bb4e3bbu,
+ 0xdda26a7eu, 0x3a59ff45u, 0x3e350a44u, 0xbcb4cdd5u,
+ 0x72eacea8u, 0xfa6484bbu, 0x8d6612aeu, 0xbf3c6f47u,
+ 0xd29be463u, 0x542f5d9eu, 0xaec2771bu, 0xf64e6370u,
+ 0x740e0d8du, 0xe75b1357u, 0xf8721671u, 0xaf537d5du,
+ 0x4040cb08u, 0x4eb4e2ccu, 0x34d2466au, 0x0115af84u,
+ 0xe1b00428u, 0x95983a1du, 0x06b89fb4u, 0xce6ea048u,
+ 0x6f3f3b82u, 0x3520ab82u, 0x011a1d4bu, 0x277227f8u,
+ 0x611560b1u, 0xe7933fdcu, 0xbb3a792bu, 0x344525bdu,
+ 0xa08839e1u, 0x51ce794bu, 0x2f32c9b7u, 0xa01fbac9u,
+ 0xe01cc87eu, 0xbcc7d1f6u, 0xcf0111c3u, 0xa1e8aac7u,
+ 0x1a908749u, 0xd44fbd9au, 0xd0dadecbu, 0xd50ada38u,
+ 0x0339c32au, 0xc6913667u, 0x8df9317cu, 0xe0b12b4fu,
+ 0xf79e59b7u, 0x43f5bb3au, 0xf2d519ffu, 0x27d9459cu,
+ 0xbf97222cu, 0x15e6fc2au, 0x0f91fc71u, 0x9b941525u,
+ 0xfae59361u, 0xceb69cebu, 0xc2a86459u, 0x12baa8d1u,
+ 0xb6c1075eu, 0xe3056a0cu, 0x10d25065u, 0xcb03a442u,
+ 0xe0ec6e0eu, 0x1698db3bu, 0x4c98a0beu, 0x3278e964u,
+ 0x9f1f9532u, 0xe0d392dfu, 0xd3a0342bu, 0x8971f21eu,
+ 0x1b0a7441u, 0x4ba3348cu, 0xc5be7120u, 0xc37632d8u,
+ 0xdf359f8du, 0x9b992f2eu, 0xe60b6f47u, 0x0fe3f11du,
+ 0xe54cda54u, 0x1edad891u, 0xce6279cfu, 0xcd3e7e6fu,
+ 0x1618b166u, 0xfd2c1d05u, 0x848fd2c5u, 0xf6fb2299u,
+ 0xf523f357u, 0xa6327623u, 0x93a83531u, 0x56cccd02u,
+ 0xacf08162u, 0x5a75ebb5u, 0x6e163697u, 0x88d273ccu,
+ 0xde966292u, 0x81b949d0u, 0x4c50901bu, 0x71c65614u,
+ 0xe6c6c7bdu, 0x327a140au, 0x45e1d006u, 0xc3f27b9au,
+ 0xc9aa53fdu, 0x62a80f00u, 0xbb25bfe2u, 0x35bdd2f6u,
+ 0x71126905u, 0xb2040222u, 0xb6cbcf7cu, 0xcd769c2bu,
+ 0x53113ec0u, 0x1640e3d3u, 0x38abbd60u, 0x2547adf0u,
+ 0xba38209cu, 0xf746ce76u, 0x77afa1c5u, 0x20756060u,
+ 0x85cbfe4eu, 0x8ae88dd8u, 0x7aaaf9b0u, 0x4cf9aa7eu,
+ 0x1948c25cu, 0x02fb8a8cu, 0x01c36ae4u, 0xd6ebe1f9u,
+ 0x90d4f869u, 0xa65cdea0u, 0x3f09252du, 0xc208e69fu,
+ 0xb74e6132u, 0xce77e25bu, 0x578fdfe3u, 0x3ac372e6u}
+};
+
+
+#define F1(i) \
+ xl ^= pax[i]; \
+ xr ^= ((sbx[0][xl >> 24] + \
+ sbx[1][(xl & 0xFF0000) >> 16]) ^ \
+ sbx[2][(xl & 0xFF00) >> 8]) + \
+ sbx[3][xl & 0xFF];
+
+#define F2(i) \
+ xr ^= pax[i]; \
+ xl ^= ((sbx[0][xr >> 24] + \
+ sbx[1][(xr & 0xFF0000) >> 16]) ^ \
+ sbx[2][(xr & 0xFF00) >> 8]) + \
+ sbx[3][xr & 0xFF];
+
+
+static void bf_e_block(p_xl, p_xr)
+UINT32_T *p_xl;
+UINT32_T *p_xr;
+{
+ UINT32_T temp, xl = *p_xl, xr = *p_xr;
+
+ F1(0) F2(1) F1(2) F2(3) F1(4) F2(5) F1(6) F2(7)
+ F1(8) F2(9) F1(10) F2(11) F1(12) F2(13) F1(14) F2(15)
+ xl ^= pax[16];
+ xr ^= pax[17];
+ temp = xl;
+ xl = xr;
+ xr = temp;
+ *p_xl = xl;
+ *p_xr = xr;
+}
+
+
+
+#ifdef WORDS_BIGENDIAN
+# define htonl2(x) \
+ x = ((((x) & 0xffL) << 24) | (((x) & 0xff00L) << 8) | \
+ (((x) & 0xff0000L) >> 8) | (((x) & 0xff000000L) >> 24))
+#else
+# define htonl2(x)
+#endif
+
+static void bf_e_cblock(block)
+char_u *block;
+{
+ block8 bk;
+
+ memcpy(bk.uc, block, 8);
+ htonl2(bk.ul[0]);
+ htonl2(bk.ul[1]);
+ bf_e_block(&bk.ul[0], &bk.ul[1]);
+ htonl2(bk.ul[0]);
+ htonl2(bk.ul[1]);
+ memcpy(block, bk.uc, 8);
+}
+
+
+/*
+ * Initialize the crypt method using "password" as the encryption key and
+ * "salt[salt_len]" as the salt.
+ */
+void bf_key_init(password, salt, salt_len)
+char_u *password;
+char_u *salt;
+int salt_len;
+{
+ int i, j, keypos = 0;
+ unsigned u;
+ UINT32_T val, data_l, data_r;
+ char_u *key;
+ int keylen;
+
+ /* Process the key 1000 times.
+ * See http://en.wikipedia.org/wiki/Key_strengthening. */
+ key = sha256_key(password, salt, salt_len);
+ for (i = 0; i < 1000; i++)
+ key = sha256_key(key, salt, salt_len);
+
+ /* Convert the key from 64 hex chars to 32 binary chars. */
+ keylen = (int)STRLEN(key) / 2;
+ if (keylen == 0) {
+ EMSG(_("E831: bf_key_init() called with empty password"));
+ return;
+ }
+ for (i = 0; i < keylen; i++) {
+ sscanf((char *)&key[i * 2], "%2x", &u);
+ key[i] = u;
+ }
+
+ mch_memmove(sbx, sbi, 4 * 4 * 256);
+
+ for (i = 0; i < 18; ++i) {
+ val = 0;
+ for (j = 0; j < 4; ++j)
+ val = (val << 8) | key[keypos++ % keylen];
+ pax[i] = ipa[i] ^ val;
+ }
+
+ data_l = data_r = 0;
+ for (i = 0; i < 18; i += 2) {
+ bf_e_block(&data_l, &data_r);
+ pax[i + 0] = data_l;
+ pax[i + 1] = data_r;
+ }
+
+ for (i = 0; i < 4; ++i) {
+ for (j = 0; j < 256; j += 2) {
+ bf_e_block(&data_l, &data_r);
+ sbx[i][j + 0] = data_l;
+ sbx[i][j + 1] = data_r;
+ }
+ }
+}
+
+/*
+ * BF Self test for corrupted tables or instructions
+ */
+static int bf_check_tables(a_ipa, a_sbi, val)
+UINT32_T a_ipa[18];
+UINT32_T a_sbi[4][256];
+UINT32_T val;
+{
+ int i, j;
+ UINT32_T c = 0;
+
+ for (i = 0; i < 18; i++)
+ c ^= a_ipa[i];
+ for (i = 0; i < 4; i++)
+ for (j = 0; j < 256; j++)
+ c ^= a_sbi[i][j];
+ return c == val;
+}
+
+typedef struct {
+ char_u password[64];
+ char_u salt[9];
+ char_u plaintxt[9];
+ char_u cryptxt[9];
+ char_u badcryptxt[9]; /* cryptxt when big/little endian is wrong */
+ UINT32_T keysum;
+} struct_bf_test_data;
+
+/*
+ * Assert bf(password, plaintxt) is cryptxt.
+ * Assert csum(pax sbx(password)) is keysum.
+ */
+static struct_bf_test_data bf_test_data[] = {
+ {
+ "password",
+ "salt",
+ "plaintxt",
+ "\xad\x3d\xfa\x7f\xe8\xea\x40\xf6", /* cryptxt */
+ "\x72\x50\x3b\x38\x10\x60\x22\xa7", /* badcryptxt */
+ 0x56701b5du /* keysum */
+ },
+};
+
+/*
+ * Return FAIL when there is something wrong with blowfish encryption.
+ */
+static int bf_self_test() {
+ int i, bn;
+ int err = 0;
+ block8 bk;
+ UINT32_T ui = 0xffffffffUL;
+
+ /* We can't simply use sizeof(UINT32_T), it would generate a compiler
+ * warning. */
+ if (ui != 0xffffffffUL || ui + 1 != 0) {
+ err++;
+ EMSG(_("E820: sizeof(uint32_t) != 4"));
+ }
+
+ if (!bf_check_tables(ipa, sbi, 0x6ffa520a))
+ err++;
+
+ bn = ARRAY_LENGTH(bf_test_data);
+ for (i = 0; i < bn; i++) {
+ bf_key_init((char_u *)(bf_test_data[i].password),
+ bf_test_data[i].salt,
+ (int)STRLEN(bf_test_data[i].salt));
+ if (!bf_check_tables(pax, sbx, bf_test_data[i].keysum))
+ err++;
+
+ /* Don't modify bf_test_data[i].plaintxt, self test is idempotent. */
+ memcpy(bk.uc, bf_test_data[i].plaintxt, 8);
+ bf_e_cblock(bk.uc);
+ if (memcmp(bk.uc, bf_test_data[i].cryptxt, 8) != 0) {
+ if (err == 0 && memcmp(bk.uc, bf_test_data[i].badcryptxt, 8) == 0)
+ EMSG(_("E817: Blowfish big/little endian use wrong"));
+ err++;
+ }
+ }
+
+ return err > 0 ? FAIL : OK;
+}
+
+/* Output feedback mode. */
+static int randbyte_offset = 0;
+static int update_offset = 0;
+static char_u ofb_buffer[BF_OFB_LEN]; /* 64 bytes */
+
+/*
+ * Initialize with seed "iv[iv_len]".
+ */
+void bf_ofb_init(iv, iv_len)
+char_u *iv;
+int iv_len;
+{
+ int i, mi;
+
+ randbyte_offset = update_offset = 0;
+ vim_memset(ofb_buffer, 0, BF_OFB_LEN);
+ if (iv_len > 0) {
+ mi = iv_len > BF_OFB_LEN ? iv_len : BF_OFB_LEN;
+ for (i = 0; i < mi; i++)
+ ofb_buffer[i % BF_OFB_LEN] ^= iv[i % iv_len];
+ }
+}
+
+#define BF_OFB_UPDATE(c) { \
+ ofb_buffer[update_offset] ^= (char_u)c; \
+ if (++update_offset == BF_OFB_LEN) \
+ update_offset = 0; \
+}
+
+#define BF_RANBYTE(t) { \
+ if ((randbyte_offset & BF_BLOCK_MASK) == 0) \
+ bf_e_cblock(&ofb_buffer[randbyte_offset]); \
+ t = ofb_buffer[randbyte_offset]; \
+ if (++randbyte_offset == BF_OFB_LEN) \
+ randbyte_offset = 0; \
+}
+
+/*
+ * Encrypt "from[len]" into "to[len]".
+ * "from" and "to" can be equal to encrypt in place.
+ */
+void bf_crypt_encode(from, len, to)
+char_u *from;
+size_t len;
+char_u *to;
+{
+ size_t i;
+ int ztemp, t;
+
+ for (i = 0; i < len; ++i) {
+ ztemp = from[i];
+ BF_RANBYTE(t);
+ BF_OFB_UPDATE(ztemp);
+ to[i] = t ^ ztemp;
+ }
+}
+
+/*
+ * Decrypt "ptr[len]" in place.
+ */
+void bf_crypt_decode(ptr, len)
+char_u *ptr;
+long len;
+{
+ char_u *p;
+ int t;
+
+ for (p = ptr; p < ptr + len; ++p) {
+ BF_RANBYTE(t);
+ *p ^= t;
+ BF_OFB_UPDATE(*p);
+ }
+}
+
+/*
+ * Initialize the encryption keys and the random header according to
+ * the given password.
+ */
+void bf_crypt_init_keys(passwd)
+char_u *passwd; /* password string with which to modify keys */
+{
+ char_u *p;
+
+ for (p = passwd; *p != NUL; ++p) {
+ BF_OFB_UPDATE(*p);
+ }
+}
+
+static int save_randbyte_offset;
+static int save_update_offset;
+static char_u save_ofb_buffer[BF_OFB_LEN];
+static UINT32_T save_pax[18];
+static UINT32_T save_sbx[4][256];
+
+/*
+ * Save the current crypt state. Can only be used once before
+ * bf_crypt_restore().
+ */
+void bf_crypt_save() {
+ save_randbyte_offset = randbyte_offset;
+ save_update_offset = update_offset;
+ mch_memmove(save_ofb_buffer, ofb_buffer, BF_OFB_LEN);
+ mch_memmove(save_pax, pax, 4 * 18);
+ mch_memmove(save_sbx, sbx, 4 * 4 * 256);
+}
+
+/*
+ * Restore the current crypt state. Can only be used after
+ * bf_crypt_save().
+ */
+void bf_crypt_restore() {
+ randbyte_offset = save_randbyte_offset;
+ update_offset = save_update_offset;
+ mch_memmove(ofb_buffer, save_ofb_buffer, BF_OFB_LEN);
+ mch_memmove(pax, save_pax, 4 * 18);
+ mch_memmove(sbx, save_sbx, 4 * 4 * 256);
+}
+
+/*
+ * Run a test to check if the encryption works as expected.
+ * Give an error and return FAIL when not.
+ */
+int blowfish_self_test() {
+ if (sha256_self_test() == FAIL) {
+ EMSG(_("E818: sha256 test failed"));
+ return FAIL;
+ }
+ if (bf_self_test() == FAIL) {
+ EMSG(_("E819: Blowfish test failed"));
+ return FAIL;
+ }
+ return OK;
+}
+
diff --git a/src/buffer.c b/src/buffer.c
new file mode 100644
index 0000000000..bffae5388d
--- /dev/null
+++ b/src/buffer.c
@@ -0,0 +1,4517 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * 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.
+ */
+
+/*
+ * buffer.c: functions for dealing with the buffer structure
+ */
+
+/*
+ * The buffer list is a double linked list of all buffers.
+ * Each buffer can be in one of these states:
+ * never loaded: BF_NEVERLOADED is set, only the file name is valid
+ * not loaded: b_ml.ml_mfp == NULL, no memfile allocated
+ * hidden: b_nwindows == 0, loaded but not displayed in a window
+ * normal: loaded and displayed in a window
+ *
+ * Instead of storing file names all over the place, each file name is
+ * stored in the buffer list. It can be referenced by a number.
+ *
+ * The current implementation remembers all file names ever used.
+ */
+
+#include "vim.h"
+
+static char_u *buflist_match __ARGS((regprog_T *prog, buf_T *buf));
+# define HAVE_BUFLIST_MATCH
+static char_u *fname_match __ARGS((regprog_T *prog, char_u *name));
+static void buflist_setfpos __ARGS((buf_T *buf, win_T *win, linenr_T lnum,
+ colnr_T col,
+ int copy_options));
+static wininfo_T *find_wininfo __ARGS((buf_T *buf, int skip_diff_buffer));
+#ifdef UNIX
+static buf_T *buflist_findname_stat __ARGS((char_u *ffname, struct stat *st));
+static int otherfile_buf __ARGS((buf_T *buf, char_u *ffname, struct stat *stp));
+static int buf_same_ino __ARGS((buf_T *buf, struct stat *stp));
+#else
+static int otherfile_buf __ARGS((buf_T *buf, char_u *ffname));
+#endif
+static int ti_change __ARGS((char_u *str, char_u **last));
+static int append_arg_number __ARGS((win_T *wp, char_u *buf, int buflen,
+ int add_file));
+static void free_buffer __ARGS((buf_T *));
+static void free_buffer_stuff __ARGS((buf_T *buf, int free_options));
+static void clear_wininfo __ARGS((buf_T *buf));
+
+#ifdef UNIX
+# define dev_T dev_t
+#else
+# define dev_T unsigned
+#endif
+
+
+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");
+
+/*
+ * Open current buffer, that is: open the memfile and read the file into
+ * memory.
+ * Return FAIL for failure, OK otherwise.
+ */
+int open_buffer(read_stdin, eap, flags)
+int read_stdin; /* read file from stdin */
+exarg_T *eap; /* for forced 'ff' and 'fenc' or NULL */
+int flags; /* extra flags for readfile() */
+{
+ int retval = OK;
+ buf_T *old_curbuf;
+ long old_tw = curbuf->b_p_tw;
+
+ /*
+ * The 'readonly' flag is only set when BF_NEVERLOADED is being reset.
+ * When re-entering the same buffer, it should not change, because the
+ * user may have reset the flag by hand.
+ */
+ if (readonlymode && curbuf->b_ffname != NULL
+ && (curbuf->b_flags & BF_NEVERLOADED))
+ curbuf->b_p_ro = TRUE;
+
+ if (ml_open(curbuf) == FAIL) {
+ /*
+ * There MUST be a memfile, otherwise we can't do anything
+ * If we can't create one for the current buffer, take another buffer
+ */
+ close_buffer(NULL, curbuf, 0, FALSE);
+ for (curbuf = firstbuf; curbuf != NULL; curbuf = curbuf->b_next)
+ if (curbuf->b_ml.ml_mfp != NULL)
+ break;
+ /*
+ * if there is no memfile at all, exit
+ * This is OK, since there are no changes to lose.
+ */
+ if (curbuf == NULL) {
+ EMSG(_("E82: Cannot allocate any buffer, exiting..."));
+ getout(2);
+ }
+ EMSG(_("E83: Cannot allocate buffer, using other one..."));
+ enter_buffer(curbuf);
+ if (old_tw != curbuf->b_p_tw)
+ check_colorcolumn(curwin);
+ return FAIL;
+ }
+
+ /* The autocommands in readfile() may change the buffer, but only AFTER
+ * reading the file. */
+ old_curbuf = curbuf;
+ modified_was_set = FALSE;
+
+ /* mark cursor position as being invalid */
+ curwin->w_valid = 0;
+
+ if (curbuf->b_ffname != NULL
+ ) {
+ retval = readfile(curbuf->b_ffname, curbuf->b_fname,
+ (linenr_T)0, (linenr_T)0, (linenr_T)MAXLNUM, eap,
+ flags | READ_NEW);
+ /* Help buffer is filtered. */
+ if (curbuf->b_help)
+ 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.
+ * Then read from that same buffer and append at the end. This makes
+ * it possible to retry when 'fileformat' or 'fileencoding' was
+ * guessed wrong.
+ */
+ curbuf->b_p_bin = TRUE;
+ retval = readfile(NULL, NULL, (linenr_T)0,
+ (linenr_T)0, (linenr_T)MAXLNUM, NULL,
+ 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);
+ }
+ }
+
+ /* if first time loading this buffer, init b_chartab[] */
+ if (curbuf->b_flags & BF_NEVERLOADED) {
+ (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 | gview -".
+ * 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)
+ )
+ changed();
+ else if (retval != FAIL && !read_stdin)
+ unchanged(curbuf, FALSE);
+ save_file_ff(curbuf); /* keep this fileformat */
+
+ /* require "!" to overwrite the file, because it wasn't read completely */
+ if (aborting())
+ curbuf->b_flags |= BF_READERR;
+
+ /* Need to update automatic folding. Do this before the autocommands,
+ * they may use the fold info. */
+ foldUpdateAll(curwin);
+
+ /* need to set w_topline, unless some autocommand already did that. */
+ if (!(curwin->w_valid & VALID_TOPLINE)) {
+ curwin->w_topline = 1;
+ curwin->w_topfill = 0;
+ }
+ apply_autocmds_retval(EVENT_BUFENTER, NULL, NULL, FALSE, curbuf, &retval);
+
+ if (retval != FAIL) {
+ /*
+ * 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) {
+ aco_save_T aco;
+
+ /* Go to the buffer that was opened. */
+ aucmd_prepbuf(&aco, old_curbuf);
+ do_modelines(0);
+ curbuf->b_flags &= ~(BF_CHECK_RO | BF_NEVERLOADED);
+
+ apply_autocmds_retval(EVENT_BUFWINENTER, NULL, NULL, FALSE, curbuf,
+ &retval);
+
+ /* restore curwin/curbuf and a few other things */
+ aucmd_restbuf(&aco);
+ }
+ }
+
+ return retval;
+}
+
+/*
+ * Return TRUE if "buf" points to a valid buffer (in the buffer list).
+ */
+int buf_valid(buf)
+buf_T *buf;
+{
+ buf_T *bp;
+
+ for (bp = firstbuf; bp != NULL; bp = bp->b_next)
+ if (bp == buf)
+ return TRUE;
+ 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, buf, action, abort_if_last)
+win_T *win; /* if not NULL, set b_last_cursor */
+buf_T *buf;
+int action;
+int abort_if_last UNUSED;
+{
+ int is_curbuf;
+ int nwindows;
+ int unload_buf = (action != 0);
+ int del_buf = (action == DOBUF_DEL || action == DOBUF_WIPE);
+ int wipe_buf = (action == DOBUF_WIPE);
+
+ /*
+ * Force unloading or deleting when 'bufhidden' says so.
+ * The caller must take care of NOT deleting/freeing when 'bufhidden' is
+ * "hide" (otherwise we could never free or delete a buffer).
+ */
+ if (buf->b_p_bh[0] == 'd') { /* 'bufhidden' == "delete" */
+ del_buf = TRUE;
+ unload_buf = TRUE;
+ } else if (buf->b_p_bh[0] == 'w') { /* 'bufhidden' == "wipe" */
+ del_buf = TRUE;
+ unload_buf = TRUE;
+ wipe_buf = TRUE;
+ } else if (buf->b_p_bh[0] == 'u') /* 'bufhidden' == "unload" */
+ unload_buf = TRUE;
+
+ if (win != NULL) {
+ /* 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);
+ }
+
+ /* 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. */
+aucmd_abort:
+ EMSG(_(e_auabort));
+ return;
+ }
+ buf->b_closing = FALSE;
+ if (abort_if_last && one_window())
+ /* Autocommands made this the only window. */
+ goto aucmd_abort;
+
+ /* 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. */
+ goto aucmd_abort;
+ buf->b_closing = FALSE;
+ if (abort_if_last && one_window())
+ /* Autocommands made this the only window. */
+ goto aucmd_abort;
+ }
+ if (aborting()) /* autocmds may abort script processing */
+ return;
+ }
+ nwindows = buf->b_nwindows;
+
+ /* decrease the link count from windows (unless not in any window) */
+ if (buf->b_nwindows > 0)
+ --buf->b_nwindows;
+
+ /* Return when a window is displaying the buffer or when it's not
+ * unloaded. */
+ if (buf->b_nwindows > 0 || !unload_buf)
+ return;
+
+ /* Always remove the buffer when there is no file name. */
+ if (buf->b_ffname == NULL)
+ del_buf = TRUE;
+
+ /*
+ * Free all things allocated for this buffer.
+ * Also calls the "BufDelete" autocommands when del_buf is TRUE.
+ */
+ /* Remember if we are closing the current buffer. Restore the number of
+ * windows, so that autocommands in buf_freeall() don't get confused. */
+ is_curbuf = (buf == curbuf);
+ 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))
+ return;
+ 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.
+ * This might cause the previous curbuf to be deleted unexpectedly. But
+ * in some cases it's OK to delete the curbuf, because a new one is
+ * obtained anyway. Therefore only return if curbuf changed to the
+ * deleted buffer.
+ */
+ if (buf == curbuf && !is_curbuf)
+ return;
+
+ /* Change directories when the 'acd' option is set. */
+ DO_AUTOCHDIR
+
+ /*
+ * Remove the buffer from the list.
+ */
+ if (wipe_buf) {
+ vim_free(buf->b_ffname);
+ vim_free(buf->b_sfname);
+ if (buf->b_prev == NULL)
+ firstbuf = buf->b_next;
+ else
+ buf->b_prev->b_next = buf->b_next;
+ if (buf->b_next == NULL)
+ lastbuf = buf->b_prev;
+ else
+ buf->b_next->b_prev = buf->b_prev;
+ free_buffer(buf);
+ } else {
+ if (del_buf) {
+ /* Free all internal variables and reset option values, to make
+ * ":bdel" compatible with Vim 5.7. */
+ free_buffer_stuff(buf, TRUE);
+
+ /* Make it look like a new buffer. */
+ buf->b_flags = BF_CHECK_RO | BF_NEVERLOADED;
+
+ /* Init the options when loaded again. */
+ buf->b_p_initialized = FALSE;
+ }
+ buf_clear_file(buf);
+ if (del_buf)
+ buf->b_p_bl = FALSE;
+ }
+}
+
+/*
+ * Make buffer not contain a file.
+ */
+void buf_clear_file(buf)
+buf_T *buf;
+{
+ buf->b_ml.ml_line_count = 1;
+ unchanged(buf, TRUE);
+#ifndef SHORT_FNAME
+ buf->b_shortname = FALSE;
+#endif
+ buf->b_p_eol = TRUE;
+ buf->b_start_eol = TRUE;
+ buf->b_p_bomb = FALSE;
+ buf->b_start_bomb = FALSE;
+ buf->b_ml.ml_mfp = NULL;
+ 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
+ */
+void buf_freeall(buf, flags)
+buf_T *buf;
+int flags;
+{
+ int is_curbuf = (buf == curbuf);
+
+ 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 */
+ 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;
+ }
+ buf->b_closing = FALSE;
+ if (aborting()) /* autocmds may abort script processing */
+ return;
+
+ /*
+ * It's possible that autocommands change curbuf to the one being deleted.
+ * This might cause curbuf to be deleted unexpectedly. But in some cases
+ * it's OK to delete the curbuf, because a new one is obtained anyway.
+ * Therefore only return if curbuf changed to the deleted buffer.
+ */
+ 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)
+ reset_synblock(curwin);
+
+ /* No folds in an empty buffer. */
+ {
+ win_T *win;
+ tabpage_T *tp;
+
+ FOR_ALL_TAB_WINDOWS(tp, win)
+ if (win->w_buffer == buf)
+ clearFolding(win);
+ }
+
+ ml_close(buf, TRUE); /* close and delete the memline/memfile */
+ buf->b_ml.ml_line_count = 0; /* no lines in buffer */
+ if ((flags & BFA_KEEP_UNDO) == 0) {
+ u_blockfree(buf); /* free the memory allocated for undo */
+ u_clearall(buf); /* reset all undo information */
+ }
+ syntax_clear(&buf->b_s); /* reset syntax info */
+ buf->b_flags &= ~BF_READERR; /* a read error is no longer relevant */
+}
+
+/*
+ * Free a buffer structure and the things it contains related to the buffer
+ * itself (not the file, that must have been done already).
+ */
+static void free_buffer(buf)
+buf_T *buf;
+{
+ free_buffer_stuff(buf, TRUE);
+ unref_var_dict(buf->b_vars);
+ aubuflocal_remove(buf);
+ vim_free(buf);
+}
+
+/*
+ * Free stuff in the buffer for ":bdel" and when wiping out the buffer.
+ */
+static void free_buffer_stuff(buf, free_options)
+buf_T *buf;
+int free_options; /* free options as well */
+{
+ if (free_options) {
+ clear_wininfo(buf); /* including window-local options */
+ free_buf_options(buf, TRUE);
+ ga_clear(&buf->b_s.b_langp);
+ }
+ vars_clear(&buf->b_vars->dv_hashtab); /* free all internal variables */
+ hash_init(&buf->b_vars->dv_hashtab);
+ uc_clear(&buf->b_ucmds); /* clear local user commands */
+ map_clear_int(buf, MAP_ALL_MODES, TRUE, FALSE); /* clear local mappings */
+ map_clear_int(buf, MAP_ALL_MODES, TRUE, TRUE); /* clear local abbrevs */
+ vim_free(buf->b_start_fenc);
+ buf->b_start_fenc = NULL;
+}
+
+/*
+ * Free the b_wininfo list for buffer "buf".
+ */
+static void clear_wininfo(buf)
+buf_T *buf;
+{
+ wininfo_T *wip;
+
+ while (buf->b_wininfo != NULL) {
+ wip = buf->b_wininfo;
+ buf->b_wininfo = wip->wi_next;
+ if (wip->wi_optset) {
+ clear_winopt(&wip->wi_opt);
+ deleteFoldRecurse(&wip->wi_folds);
+ }
+ vim_free(wip);
+ }
+}
+
+/*
+ * Go to another buffer. Handles the result of the ATTENTION dialog.
+ */
+void goto_buffer(eap, start, dir, count)
+exarg_T *eap;
+int start;
+int dir;
+int count;
+{
+# if defined(FEAT_WINDOWS) && defined(HAS_SWAP_EXISTS_ACTION)
+ buf_T *old_curbuf = curbuf;
+
+ swap_exists_action = SEA_DIALOG;
+# endif
+ (void)do_buffer(*eap->cmd == 's' ? DOBUF_SPLIT : DOBUF_GOTO,
+ start, dir, count, eap->forceit);
+# if defined(FEAT_WINDOWS) && defined(HAS_SWAP_EXISTS_ACTION)
+ if (swap_exists_action == SEA_QUIT && *eap->cmd == 's') {
+ cleanup_T cs;
+
+ /* Reset the error/interrupt/exception state here so that
+ * aborting() returns FALSE when closing a window. */
+ enter_cleanup(&cs);
+
+ /* Quitting means closing the split window, nothing else. */
+ win_close(curwin, TRUE);
+ swap_exists_action = SEA_NONE;
+ swap_exists_did_quit = TRUE;
+
+ /* Restore the error/interrupt/exception state if not discarded by a
+ * new aborting error, interrupt, or uncaught exception. */
+ leave_cleanup(&cs);
+ } else
+ handle_swap_exists(old_curbuf);
+# endif
+}
+
+#if defined(HAS_SWAP_EXISTS_ACTION) || defined(PROTO)
+/*
+ * Handle the situation of swap_exists_action being set.
+ * It is allowed for "old_curbuf" to be NULL or invalid.
+ */
+void handle_swap_exists(old_curbuf)
+buf_T *old_curbuf;
+{
+ cleanup_T cs;
+ long old_tw = curbuf->b_p_tw;
+
+ 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)
+ check_colorcolumn(curwin);
+ }
+ /* If "old_curbuf" is NULL we are in big trouble here... */
+
+ /* Restore the error/interrupt/exception state if not discarded by a
+ * new aborting error, interrupt, or uncaught exception. */
+ leave_cleanup(&cs);
+ } else if (swap_exists_action == SEA_RECOVER) {
+ /* Reset the error/interrupt/exception state here so that
+ * aborting() returns FALSE when closing a buffer. */
+ enter_cleanup(&cs);
+
+ /* User selected Recover at ATTENTION prompt. */
+ msg_scroll = TRUE;
+ ml_recover();
+ MSG_PUTS("\n"); /* don't overwrite the last message */
+ cmdline_row = msg_row;
+ do_modelines(0);
+
+ /* Restore the error/interrupt/exception state if not discarded by a
+ * new aborting error, interrupt, or uncaught exception. */
+ leave_cleanup(&cs);
+ }
+ swap_exists_action = SEA_NONE;
+}
+#endif
+
+/*
+ * do_bufdel() - delete or unload buffer(s)
+ *
+ * addr_count == 0: ":bdel" - delete current buffer
+ * addr_count == 1: ":N bdel" or ":bdel N [N ..]" - first delete
+ * buffer "end_bnr", then any other arguments.
+ * addr_count == 2: ":N,N bdel" - delete buffers in range
+ *
+ * command can be DOBUF_UNLOAD (":bunload"), DOBUF_WIPE (":bwipeout") or
+ * DOBUF_DEL (":bdel")
+ *
+ * Returns error message or NULL
+ */
+char_u * do_bufdel(command, arg, addr_count, start_bnr, end_bnr, forceit)
+int command;
+char_u *arg; /* pointer to extra arguments */
+int addr_count;
+int start_bnr; /* first buffer number in a range */
+int end_bnr; /* buffer nr or last buffer nr in a range */
+int forceit;
+{
+ int do_current = 0; /* delete current buffer? */
+ int deleted = 0; /* number of buffers deleted */
+ char_u *errormsg = NULL; /* return value */
+ int bnr; /* buffer number */
+ char_u *p;
+
+ if (addr_count == 0) {
+ (void)do_buffer(command, DOBUF_CURRENT, FORWARD, 0, forceit);
+ } else {
+ if (addr_count == 2) {
+ if (*arg) /* both range and argument is not allowed */
+ return (char_u *)_(e_trailing);
+ bnr = start_bnr;
+ } else /* addr_count == 1 */
+ bnr = end_bnr;
+
+ for (; !got_int; ui_breakcheck()) {
+ /*
+ * delete the current buffer last, otherwise when the
+ * current buffer is deleted, the next buffer becomes
+ * the current one and will be loaded, which may then
+ * also be deleted, etc.
+ */
+ if (bnr == curbuf->b_fnum)
+ do_current = bnr;
+ else if (do_buffer(command, DOBUF_FIRST, FORWARD, (int)bnr,
+ forceit) == OK)
+ ++deleted;
+
+ /*
+ * find next buffer number to delete/unload
+ */
+ if (addr_count == 2) {
+ if (++bnr > end_bnr)
+ break;
+ } else { /* addr_count == 1 */
+ arg = skipwhite(arg);
+ if (*arg == NUL)
+ break;
+ if (!VIM_ISDIGIT(*arg)) {
+ p = skiptowhite_esc(arg);
+ bnr = buflist_findpat(arg, p, command == DOBUF_WIPE,
+ FALSE, FALSE);
+ if (bnr < 0) /* failed */
+ break;
+ arg = p;
+ } else
+ bnr = getdigits(&arg);
+ }
+ }
+ if (!got_int && do_current && do_buffer(command, DOBUF_FIRST,
+ FORWARD, do_current, forceit) == OK)
+ ++deleted;
+
+ if (deleted == 0) {
+ if (command == DOBUF_UNLOAD)
+ STRCPY(IObuff, _("E515: No buffers were unloaded"));
+ else if (command == DOBUF_DEL)
+ STRCPY(IObuff, _("E516: No buffers were deleted"));
+ else
+ STRCPY(IObuff, _("E517: No buffers were wiped out"));
+ errormsg = IObuff;
+ } else if (deleted >= p_report) {
+ if (command == DOBUF_UNLOAD) {
+ if (deleted == 1)
+ MSG(_("1 buffer unloaded"));
+ else
+ smsg((char_u *)_("%d buffers unloaded"), deleted);
+ } else if (command == DOBUF_DEL) {
+ if (deleted == 1)
+ MSG(_("1 buffer deleted"));
+ else
+ smsg((char_u *)_("%d buffers deleted"), deleted);
+ } else {
+ if (deleted == 1)
+ MSG(_("1 buffer wiped out"));
+ else
+ smsg((char_u *)_("%d buffers wiped out"), deleted);
+ }
+ }
+ }
+
+
+ return errormsg;
+}
+
+#if defined(FEAT_LISTCMDS) || defined(FEAT_PYTHON) \
+ || defined(FEAT_PYTHON3) || defined(PROTO)
+
+static int empty_curbuf __ARGS((int close_others, int forceit, int action));
+
+/*
+ * Make the current buffer empty.
+ * Used when it is wiped out and it's the last buffer.
+ */
+static int empty_curbuf(close_others, forceit, action)
+int close_others;
+int forceit;
+int action;
+{
+ int retval;
+ buf_T *buf = curbuf;
+
+ if (action == DOBUF_UNLOAD) {
+ EMSG(_("E90: Cannot unload last buffer"));
+ return FAIL;
+ }
+
+ if (close_others) {
+ /* Close any other windows on this buffer, then make it empty. */
+ close_windows(buf, TRUE);
+ }
+
+ setpcmark();
+ 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;
+ return retval;
+}
+/*
+ * Implementation of the commands for the buffer list.
+ *
+ * action == DOBUF_GOTO go to specified buffer
+ * action == DOBUF_SPLIT split window and go to specified buffer
+ * action == DOBUF_UNLOAD unload specified buffer(s)
+ * action == DOBUF_DEL delete specified buffer(s) from buffer list
+ * action == DOBUF_WIPE delete specified buffer(s) really
+ *
+ * start == DOBUF_CURRENT go to "count" buffer from current buffer
+ * start == DOBUF_FIRST go to "count" buffer from first buffer
+ * start == DOBUF_LAST go to "count" buffer from last buffer
+ * start == DOBUF_MOD go to "count" modified buffer from current buffer
+ *
+ * Return FAIL or OK.
+ */
+int do_buffer(action, start, dir, count, forceit)
+int action;
+int start;
+int dir; /* FORWARD or BACKWARD */
+int count; /* buffer number or number of buffers */
+int forceit; /* TRUE for :...! */
+{
+ buf_T *buf;
+ buf_T *bp;
+ int unload = (action == DOBUF_UNLOAD || action == DOBUF_DEL
+ || action == DOBUF_WIPE);
+
+ switch (start) {
+ case DOBUF_FIRST: buf = firstbuf; break;
+ case DOBUF_LAST: buf = lastbuf; break;
+ default: buf = curbuf; break;
+ }
+ if (start == DOBUF_MOD) { /* find next modified buffer */
+ while (count-- > 0) {
+ do {
+ buf = buf->b_next;
+ if (buf == NULL)
+ buf = firstbuf;
+ } while (buf != curbuf && !bufIsChanged(buf));
+ }
+ if (!bufIsChanged(buf)) {
+ EMSG(_("E84: No modified buffer found"));
+ return FAIL;
+ }
+ } else if (start == DOBUF_FIRST && count) { /* find specified buffer number */
+ while (buf != NULL && buf->b_fnum != count)
+ buf = buf->b_next;
+ } else {
+ bp = NULL;
+ while (count > 0 || (!unload && !buf->b_p_bl && bp != buf)) {
+ /* remember the buffer where we start, we come back there when all
+ * buffers are unlisted. */
+ if (bp == NULL)
+ bp = buf;
+ if (dir == FORWARD) {
+ buf = buf->b_next;
+ if (buf == NULL)
+ buf = firstbuf;
+ } else {
+ buf = buf->b_prev;
+ if (buf == NULL)
+ buf = lastbuf;
+ }
+ /* don't count unlisted buffers */
+ if (unload || buf->b_p_bl) {
+ --count;
+ bp = NULL; /* use this buffer as new starting point */
+ }
+ if (bp == buf) {
+ /* back where we started, didn't find anything. */
+ EMSG(_("E85: There is no listed buffer"));
+ return FAIL;
+ }
+ }
+ }
+
+ if (buf == NULL) { /* could not find it */
+ if (start == DOBUF_FIRST) {
+ /* don't warn when deleting */
+ if (!unload)
+ EMSGN(_("E86: Buffer %ld does not exist"), count);
+ } else if (dir == FORWARD)
+ EMSG(_("E87: Cannot go beyond last buffer"));
+ else
+ EMSG(_("E88: Cannot go before first buffer"));
+ return FAIL;
+ }
+
+
+ /*
+ * delete buffer buf from memory and/or the list
+ */
+ if (unload) {
+ int forward;
+
+ /* When unloading or deleting a buffer that's already unloaded and
+ * unlisted: fail silently. */
+ if (action != DOBUF_WIPE && buf->b_ml.ml_mfp == NULL && !buf->b_p_bl)
+ return FAIL;
+
+ if (!forceit && bufIsChanged(buf)) {
+ if ((p_confirm || cmdmod.confirm) && p_write) {
+ dialog_changed(buf, FALSE);
+ if (!buf_valid(buf))
+ /* 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))
+ return FAIL;
+ } else {
+ EMSGN(_(
+ "E89: No write since last change for buffer %ld (add ! to override)"),
+ buf->b_fnum);
+ return FAIL;
+ }
+ }
+
+ /*
+ * If deleting the last (listed) buffer, make it empty.
+ * The last (listed) buffer cannot be unloaded.
+ */
+ for (bp = firstbuf; bp != NULL; bp = bp->b_next)
+ if (bp->b_p_bl && bp != buf)
+ break;
+ if (bp == NULL && buf == curbuf)
+ return empty_curbuf(TRUE, forceit, action);
+
+ /*
+ * If the deleted buffer is the current one, close the current window
+ * (unless it's the only window). Repeat this so long as we end up in
+ * 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)
+ break;
+ }
+
+ /*
+ * 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);
+ 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) {
+ int jumpidx;
+
+ jumpidx = curwin->w_jumplistidx - 1;
+ if (jumpidx < 0)
+ jumpidx = curwin->w_jumplistlen - 1;
+
+ forward = jumpidx;
+ while (jumpidx != curwin->w_jumplistidx) {
+ buf = buflist_findnr(curwin->w_jumplist[jumpidx].fmark.fnum);
+ if (buf != NULL) {
+ if (buf == curbuf || !buf->b_p_bl)
+ buf = NULL; /* skip current and unlisted bufs */
+ else if (buf->b_ml.ml_mfp == NULL) {
+ /* skip unloaded buf, but may keep it for later */
+ if (bp == NULL)
+ bp = buf;
+ buf = NULL;
+ }
+ }
+ if (buf != NULL) /* found a valid buffer: stop searching */
+ break;
+ /* advance to older entry in jump list */
+ if (!jumpidx && curwin->w_jumplistidx == curwin->w_jumplistlen)
+ break;
+ if (--jumpidx < 0)
+ jumpidx = curwin->w_jumplistlen - 1;
+ if (jumpidx == forward) /* List exhausted for sure */
+ break;
+ }
+ }
+
+ if (buf == NULL) { /* No previous buffer, Try 2'nd approach */
+ forward = TRUE;
+ buf = curbuf->b_next;
+ for (;; ) {
+ if (buf == NULL) {
+ if (!forward) /* tried both directions */
+ break;
+ buf = curbuf->b_prev;
+ forward = FALSE;
+ continue;
+ }
+ /* in non-help buffer, try to skip help buffers, and vv */
+ if (buf->b_help == curbuf->b_help && buf->b_p_bl) {
+ if (buf->b_ml.ml_mfp != NULL) /* found loaded buffer */
+ break;
+ if (bp == NULL) /* remember unloaded buf for later */
+ bp = buf;
+ }
+ if (forward)
+ buf = buf->b_next;
+ else
+ buf = buf->b_prev;
+ }
+ }
+ if (buf == NULL) /* No loaded buffer, use unloaded one */
+ buf = bp;
+ if (buf == NULL) { /* No loaded buffer, find listed one */
+ for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+ if (buf->b_p_bl && buf != curbuf)
+ break;
+ }
+ if (buf == NULL) { /* Still no buffer, just take one */
+ if (curbuf->b_next != NULL)
+ buf = curbuf->b_next;
+ else
+ buf = curbuf->b_prev;
+ }
+ }
+
+ if (buf == NULL) {
+ /* Autocommands must have wiped out all other buffers. Only option
+ * now is to make the current buffer empty. */
+ return empty_curbuf(FALSE, forceit, action);
+ }
+
+ /*
+ * make buf current buffer
+ */
+ if (action == DOBUF_SPLIT) { /* split window first */
+ /* If 'switchbuf' contains "useopen": jump to first window containing
+ * "buf" if one exists */
+ if ((swb_flags & SWB_USEOPEN) && buf_jump_open_win(buf))
+ return OK;
+ /* If 'switchbuf' contains "usetab": jump to first window in any tab
+ * page containing "buf" if one exists */
+ if ((swb_flags & SWB_USETAB) && buf_jump_open_tab(buf))
+ return OK;
+ if (win_split(0, 0) == FAIL)
+ return FAIL;
+ }
+
+ /* go to current buffer - nothing to do */
+ if (buf == curbuf)
+ return OK;
+
+ /*
+ * Check if the current buffer may be abandoned.
+ */
+ 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! */
+ return FAIL;
+ }
+ if (bufIsChanged(curbuf)) {
+ EMSG(_(e_nowrtmsg));
+ return FAIL;
+ }
+ }
+
+ /* Go to the other buffer. */
+ set_curbuf(buf, action);
+
+#if defined(FEAT_LISTCMDS) \
+ && (defined(FEAT_SCROLLBIND) || defined(FEAT_CURSORBIND))
+ if (action == DOBUF_SPLIT) {
+ RESET_BINDING(curwin); /* reset 'scrollbind' and 'cursorbind' */
+ }
+#endif
+
+ if (aborting()) /* autocmds may abort script processing */
+ return FAIL;
+
+ return OK;
+}
+#endif
+
+/*
+ * Set current buffer to "buf". Executes autocommands and closes current
+ * buffer. "action" tells how to close the current buffer:
+ * DOBUF_GOTO free or hide it
+ * DOBUF_SPLIT nothing
+ * DOBUF_UNLOAD unload it
+ * DOBUF_DEL delete it
+ * DOBUF_WIPE wipe it out
+ */
+void set_curbuf(buf, action)
+buf_T *buf;
+int action;
+{
+ buf_T *prevbuf;
+ int unload = (action == DOBUF_UNLOAD || action == DOBUF_DEL
+ || action == DOBUF_WIPE);
+ long old_tw = curbuf->b_p_tw;
+
+ setpcmark();
+ if (!cmdmod.keepalt)
+ curwin->w_alt_fnum = curbuf->b_fnum; /* remember alternate file */
+ buflist_altfpos(curwin); /* remember curpos */
+
+ /* Don't restart Select mode after switching to another buffer. */
+ VIsual_reselect = FALSE;
+
+ /* close_windows() or apply_autocmds() may change curbuf */
+ prevbuf = curbuf;
+
+ apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, FALSE, curbuf);
+ if (buf_valid(prevbuf) && !aborting()) {
+ if (prevbuf == curwin->w_buffer)
+ reset_synblock(curwin);
+ if (unload)
+ close_windows(prevbuf, FALSE);
+ if (buf_valid(prevbuf) && !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! */
+ curwin = previouswin;
+ }
+ }
+ /* An autocommand may have deleted "buf", already entered it (e.g., when
+ * it did ":bunload") or aborted the script processing!
+ * If curwin->w_buffer is null, enter_buffer() will make it valid again */
+ if ((buf_valid(buf) && buf != curbuf
+ && !aborting()
+ ) || curwin->w_buffer == NULL
+ ) {
+ enter_buffer(buf);
+ if (old_tw != curbuf->b_p_tw)
+ check_colorcolumn(curwin);
+ }
+}
+
+/*
+ * Enter a new current buffer.
+ * Old curbuf must have been abandoned already! This also means "curbuf" may
+ * be pointing to freed memory.
+ */
+void enter_buffer(buf)
+buf_T *buf;
+{
+ /* Copy buffer and window local option values. Not for a help buffer. */
+ buf_copy_options(buf, BCO_ENTER | BCO_NOHELP);
+ if (!buf->b_help)
+ get_winopts(buf);
+ else
+ /* Remove all folds in the window. */
+ clearFolding(curwin);
+ foldUpdateAll(curwin); /* update folds (later). */
+
+ /* Get the buffer in the current window. */
+ curwin->w_buffer = buf;
+ curbuf = buf;
+ ++curbuf->b_nwindows;
+
+ if (curwin->w_p_diff)
+ diff_buf_add(curbuf);
+
+ curwin->w_s = &(buf->b_s);
+
+ /* Cursor on first line by default. */
+ curwin->w_cursor.lnum = 1;
+ curwin->w_cursor.col = 0;
+ curwin->w_cursor.coladd = 0;
+ curwin->w_set_curswant = TRUE;
+ curwin->w_topline_was_set = FALSE;
+
+ /* mark cursor position as being invalid */
+ curwin->w_valid = 0;
+
+ /* 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
+ * ":ball" used in a autocommand. If there already is a filetype we
+ * might prefer to keep it. */
+ if (*curbuf->b_p_ft == NUL)
+ did_filetype = FALSE;
+
+ open_buffer(FALSE, NULL, 0);
+ } else {
+ if (!msg_silent)
+ need_fileinfo = TRUE; /* display file info after redraw */
+ (void)buf_check_timestamp(curbuf, FALSE); /* check if file changed */
+ curwin->w_topline = 1;
+ curwin->w_topfill = 0;
+ apply_autocmds(EVENT_BUFENTER, NULL, NULL, FALSE, curbuf);
+ apply_autocmds(EVENT_BUFWINENTER, NULL, NULL, FALSE, curbuf);
+ }
+
+ /* If autocommands did not change the cursor position, restore cursor lnum
+ * and possibly cursor col. */
+ if (curwin->w_cursor.lnum == 1 && inindent(0))
+ buflist_getfpos();
+
+ check_arg_idx(curwin); /* check for valid arg_idx */
+ maketitle();
+ /* when autocmds didn't change it */
+ if (curwin->w_topline == 1 && !curwin->w_topline_was_set)
+ scroll_cursor_halfway(FALSE); /* redisplay at correct position */
+
+
+ /* Change directories when the 'acd' option is set. */
+ DO_AUTOCHDIR
+
+ if (curbuf->b_kmap_state & KEYMAP_INIT)
+ (void)keymap_init();
+ /* May need to set the spell language. Can only do this after the buffer
+ * has been properly setup. */
+ if (!curbuf->b_help && curwin->w_p_spell && *curwin->w_s->b_p_spl != NUL)
+ (void)did_set_spelllang(curwin);
+
+ redraw_later(NOT_VALID);
+}
+
+/*
+ * Change to the directory of the current buffer.
+ */
+void do_autochdir() {
+ if (curbuf->b_ffname != NULL && vim_chdirfile(curbuf->b_ffname) == OK)
+ shorten_fnames(TRUE);
+}
+
+/*
+ * 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(ffname, sfname, lnum, flags)
+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 */
+{
+ buf_T *buf;
+#ifdef UNIX
+ struct stat st;
+#endif
+
+ fname_expand(curbuf, &ffname, &sfname); /* will allocate ffname */
+
+ /*
+ * If file name already exists in the list, update the entry.
+ */
+#ifdef UNIX
+ /* On Unix we can use inode numbers when the file exists. Works better
+ * for hard links. */
+ if (sfname == NULL || mch_stat((char *)sfname, &st) < 0)
+ st.st_dev = (dev_T)-1;
+#endif
+ if (ffname != NULL && !(flags & BLN_DUMMY) && (buf =
+#ifdef UNIX
+ buflist_findname_stat(ffname,
+ &st)
+#else
+ buflist_findname(ffname)
+#endif
+ ) != NULL) {
+ vim_free(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 ((flags & BLN_LISTED) && !buf->b_p_bl) {
+ buf->b_p_bl = TRUE;
+ if (!(flags & BLN_DUMMY))
+ apply_autocmds(EVENT_BUFADD, NULL, NULL, FALSE, buf);
+ }
+ return buf;
+ }
+
+ /*
+ * If the current buffer has no name and no contents, use the current
+ * buffer. Otherwise: Need to allocate a new buffer structure.
+ *
+ * This is the ONLY place where a new buffer structure is allocated!
+ * (A spell file buffer is allocated in spell.c, but that's not a normal
+ * buffer.)
+ */
+ buf = NULL;
+ if ((flags & BLN_CURBUF)
+ && curbuf != NULL
+ && curbuf->b_ffname == NULL
+ && curbuf->b_nwindows <= 1
+ && (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. */
+ if (curbuf->b_p_bl)
+ apply_autocmds(EVENT_BUFDELETE, NULL, NULL, FALSE, curbuf);
+ if (buf == curbuf)
+ apply_autocmds(EVENT_BUFWIPEOUT, NULL, NULL, FALSE, curbuf);
+ if (aborting()) /* autocmds may abort script processing */
+ return NULL;
+ if (buf == curbuf) {
+ /* Make sure 'bufhidden' and 'buftype' are empty */
+ clear_string_option(&buf->b_p_bh);
+ clear_string_option(&buf->b_p_bt);
+ }
+ }
+ if (buf != curbuf || curbuf == NULL) {
+ buf = (buf_T *)alloc_clear((unsigned)sizeof(buf_T));
+ if (buf == NULL) {
+ vim_free(ffname);
+ return NULL;
+ }
+ /* init b: variables */
+ buf->b_vars = dict_alloc();
+ if (buf->b_vars == NULL) {
+ vim_free(ffname);
+ vim_free(buf);
+ return NULL;
+ }
+ init_var_dict(buf->b_vars, &buf->b_bufvar, VAR_SCOPE);
+ }
+
+ if (ffname != NULL) {
+ buf->b_ffname = ffname;
+ buf->b_sfname = vim_strsave(sfname);
+ }
+
+ clear_wininfo(buf);
+ buf->b_wininfo = (wininfo_T *)alloc_clear((unsigned)sizeof(wininfo_T));
+
+ if ((ffname != NULL && (buf->b_ffname == NULL || buf->b_sfname == NULL))
+ || buf->b_wininfo == NULL) {
+ vim_free(buf->b_ffname);
+ buf->b_ffname = NULL;
+ vim_free(buf->b_sfname);
+ buf->b_sfname = NULL;
+ if (buf != curbuf)
+ free_buffer(buf);
+ return NULL;
+ }
+
+ if (buf == curbuf) {
+ /* free all things allocated for this buffer */
+ buf_freeall(buf, 0);
+ if (buf != curbuf) /* autocommands deleted the buffer! */
+ return NULL;
+ if (aborting()) /* autocmds may abort script processing */
+ return NULL;
+ /* buf->b_nwindows = 0; why was this here? */
+ free_buffer_stuff(buf, FALSE); /* delete local variables et al. */
+
+ /* Init the options. */
+ buf->b_p_initialized = FALSE;
+ buf_copy_options(buf, BCO_ENTER);
+
+ /* need to reload lmaps and set b:keymap_name */
+ curbuf->b_kmap_state |= KEYMAP_INIT;
+ } else {
+ /*
+ * put new buffer at the end of the buffer list
+ */
+ buf->b_next = NULL;
+ if (firstbuf == NULL) { /* buffer list is empty */
+ buf->b_prev = NULL;
+ firstbuf = buf;
+ } else { /* append new buffer at end of list */
+ lastbuf->b_next = buf;
+ buf->b_prev = lastbuf;
+ }
+ lastbuf = buf;
+
+ buf->b_fnum = top_file_num++;
+ if (top_file_num < 0) { /* wrap around (may cause duplicates) */
+ EMSG(_("W14: Warning: List of file names overflow"));
+ if (emsg_silent == 0) {
+ out_flush();
+ ui_delay(3000L, TRUE); /* make sure it is noticed */
+ }
+ top_file_num = 1;
+ }
+
+ /*
+ * Always copy the options from the current buffer.
+ */
+ buf_copy_options(buf, BCO_ALWAYS);
+ }
+
+ buf->b_wininfo->wi_fpos.lnum = lnum;
+ buf->b_wininfo->wi_win = curwin;
+
+ hash_init(&buf->b_s.b_keywtab);
+ hash_init(&buf->b_s.b_keywtab_ic);
+
+ buf->b_fname = buf->b_sfname;
+#ifdef UNIX
+ if (st.st_dev == (dev_T)-1)
+ buf->b_dev_valid = FALSE;
+ else {
+ buf->b_dev_valid = TRUE;
+ buf->b_dev = st.st_dev;
+ buf->b_ino = st.st_ino;
+ }
+#endif
+ buf->b_u_synced = TRUE;
+ buf->b_flags = BF_CHECK_RO | BF_NEVERLOADED;
+ 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' */
+ if (!(flags & BLN_DUMMY)) {
+ apply_autocmds(EVENT_BUFNEW, NULL, NULL, FALSE, buf);
+ if (flags & BLN_LISTED)
+ apply_autocmds(EVENT_BUFADD, NULL, NULL, FALSE, buf);
+ if (aborting()) /* autocmds may abort script processing */
+ return NULL;
+ }
+
+ return buf;
+}
+
+/*
+ * Free the memory for the options of a buffer.
+ * If "free_p_ff" is TRUE also free 'fileformat', 'buftype' and
+ * 'fileencoding'.
+ */
+void free_buf_options(buf, free_p_ff)
+buf_T *buf;
+int free_p_ff;
+{
+ if (free_p_ff) {
+ clear_string_option(&buf->b_p_fenc);
+ clear_string_option(&buf->b_p_ff);
+ clear_string_option(&buf->b_p_bh);
+ clear_string_option(&buf->b_p_bt);
+ }
+ clear_string_option(&buf->b_p_def);
+ clear_string_option(&buf->b_p_inc);
+ 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_cm);
+ clear_string_option(&buf->b_p_fex);
+ clear_string_option(&buf->b_p_key);
+ clear_string_option(&buf->b_p_kp);
+ clear_string_option(&buf->b_p_mps);
+ clear_string_option(&buf->b_p_fo);
+ clear_string_option(&buf->b_p_flp);
+ clear_string_option(&buf->b_p_isk);
+ clear_string_option(&buf->b_p_keymap);
+ ga_clear(&buf->b_kmap_ga);
+ clear_string_option(&buf->b_p_com);
+ clear_string_option(&buf->b_p_cms);
+ clear_string_option(&buf->b_p_nf);
+ clear_string_option(&buf->b_p_syn);
+ clear_string_option(&buf->b_s.b_p_spc);
+ clear_string_option(&buf->b_s.b_p_spf);
+ vim_regfree(buf->b_s.b_cap_prog);
+ buf->b_s.b_cap_prog = NULL;
+ clear_string_option(&buf->b_s.b_p_spl);
+ clear_string_option(&buf->b_p_sua);
+ clear_string_option(&buf->b_p_ft);
+ clear_string_option(&buf->b_p_cink);
+ clear_string_option(&buf->b_p_cino);
+ clear_string_option(&buf->b_p_cinw);
+ clear_string_option(&buf->b_p_cpt);
+ clear_string_option(&buf->b_p_cfu);
+ clear_string_option(&buf->b_p_ofu);
+ clear_string_option(&buf->b_p_gp);
+ clear_string_option(&buf->b_p_mp);
+ clear_string_option(&buf->b_p_efm);
+ clear_string_option(&buf->b_p_ep);
+ clear_string_option(&buf->b_p_path);
+ clear_string_option(&buf->b_p_tags);
+ clear_string_option(&buf->b_p_dict);
+ clear_string_option(&buf->b_p_tsr);
+ clear_string_option(&buf->b_p_qe);
+ buf->b_p_ar = -1;
+ buf->b_p_ul = NO_LOCAL_UNDOLEVEL;
+}
+
+/*
+ * 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(n, lnum, options, forceit)
+int n;
+linenr_T lnum;
+int options;
+int forceit;
+{
+ buf_T *buf;
+ win_T *wp = NULL;
+ pos_T *fpos;
+ colnr_T col;
+
+ buf = buflist_findnr(n);
+ if (buf == NULL) {
+ if ((options & GETF_ALT) && n == 0)
+ EMSG(_(e_noalt));
+ else
+ EMSGN(_("E92: Buffer %ld not found"), n);
+ return FAIL;
+ }
+
+ /* if alternate file is the current buffer, nothing to do */
+ if (buf == curbuf)
+ return OK;
+
+ if (text_locked()) {
+ text_locked_msg();
+ return FAIL;
+ }
+ if (curbuf_locked())
+ return FAIL;
+
+ /* altfpos may be changed by getfile(), get it now */
+ if (lnum == 0) {
+ fpos = buflist_findfpos(buf);
+ lnum = fpos->lnum;
+ col = fpos->col;
+ } else
+ col = 0;
+
+ if (options & GETF_SWITCH) {
+ /* If 'switchbuf' contains "useopen": jump to first window containing
+ * "buf" if one exists */
+ if (swb_flags & SWB_USEOPEN)
+ wp = buf_jump_open_win(buf);
+ /* If 'switchbuf' contains "usetab": jump to first window in any tab
+ * page containing "buf" if one exists */
+ if (wp == NULL && (swb_flags & SWB_USETAB))
+ wp = buf_jump_open_tab(buf);
+ /* If 'switchbuf' contains "split" or "newtab" and the current buffer
+ * isn't empty: open new window */
+ if (wp == NULL && (swb_flags & (SWB_SPLIT | SWB_NEWTAB)) && !bufempty()) {
+ if (swb_flags & SWB_NEWTAB) /* Open in a new tab */
+ tabpage_new();
+ else if (win_split(0, 0) == FAIL) /* Open in a new window */
+ return FAIL;
+ RESET_BINDING(curwin);
+ }
+ }
+
+ ++RedrawingDisabled;
+ if (getfile(buf->b_fnum, NULL, NULL, (options & GETF_SETMARK),
+ lnum, forceit) <= 0) {
+ --RedrawingDisabled;
+
+ /* cursor is at to BOL and w_cursor.lnum is checked due to getfile() */
+ if (!p_sol && col != 0) {
+ curwin->w_cursor.col = col;
+ check_cursor_col();
+ curwin->w_cursor.coladd = 0;
+ curwin->w_set_curswant = TRUE;
+ }
+ return OK;
+ }
+ --RedrawingDisabled;
+ return FAIL;
+}
+
+/*
+ * go to the last know line number for the current buffer
+ */
+void buflist_getfpos() {
+ pos_T *fpos;
+
+ fpos = buflist_findfpos(curbuf);
+
+ curwin->w_cursor.lnum = fpos->lnum;
+ check_cursor_lnum();
+
+ if (p_sol)
+ curwin->w_cursor.col = 0;
+ else {
+ curwin->w_cursor.col = fpos->col;
+ check_cursor_col();
+ curwin->w_cursor.coladd = 0;
+ curwin->w_set_curswant = TRUE;
+ }
+}
+
+/*
+ * Find file in buffer list by name (it has to be for the current window).
+ * Returns NULL if not found.
+ */
+buf_T * buflist_findname_exp(fname)
+char_u *fname;
+{
+ char_u *ffname;
+ buf_T *buf = NULL;
+
+ /* First make the name into a full path name */
+ ffname = FullName_save(fname,
+#ifdef UNIX
+ TRUE /* force expansion, get rid of symbolic links */
+#else
+ FALSE
+#endif
+ );
+ if (ffname != NULL) {
+ buf = buflist_findname(ffname);
+ vim_free(ffname);
+ }
+ return buf;
+}
+
+/*
+ * Find file in buffer list by name (it has to be for the current window).
+ * "ffname" must have a full path.
+ * Skips dummy buffers.
+ * Returns NULL if not found.
+ */
+buf_T * buflist_findname(ffname)
+char_u *ffname;
+{
+#ifdef UNIX
+ struct stat st;
+
+ if (mch_stat((char *)ffname, &st) < 0)
+ st.st_dev = (dev_T)-1;
+ return buflist_findname_stat(ffname, &st);
+}
+
+/*
+ * Same as buflist_findname(), but pass the stat structure to avoid getting it
+ * twice for the same file.
+ * Returns NULL if not found.
+ */
+static buf_T * buflist_findname_stat(ffname, stp)
+char_u *ffname;
+struct stat *stp;
+{
+#endif
+ buf_T *buf;
+
+ for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+ if ((buf->b_flags & BF_DUMMY) == 0 && !otherfile_buf(buf, ffname
+#ifdef UNIX
+ , stp
+#endif
+ ))
+ return buf;
+ return NULL;
+}
+
+#if defined(FEAT_LISTCMDS) || defined(FEAT_EVAL) || defined(FEAT_PERL) \
+ || defined(PROTO)
+/*
+ * Find file in buffer list by a regexp pattern.
+ * Return fnum of the found buffer.
+ * Return < 0 for error.
+ */
+int buflist_findpat(pattern, pattern_end, unlisted, diffmode, curtab_only)
+char_u *pattern;
+char_u *pattern_end; /* pointer to first char after pattern */
+int unlisted; /* find unlisted buffers */
+int diffmode UNUSED; /* find diff-mode buffers only */
+int curtab_only; /* find buffers in current tab only */
+{
+ buf_T *buf;
+ regprog_T *prog;
+ int match = -1;
+ int find_listed;
+ char_u *pat;
+ char_u *patend;
+ int attempt;
+ char_u *p;
+ int toggledollar;
+
+ if (pattern_end == pattern + 1 && (*pattern == '%' || *pattern == '#')) {
+ if (*pattern == '%')
+ match = curbuf->b_fnum;
+ else
+ match = curwin->w_alt_fnum;
+ if (diffmode && !diff_mode_buf(buflist_findnr(match)))
+ match = -1;
+ }
+ /*
+ * Try four ways of matching a listed buffer:
+ * attempt == 0: without '^' or '$' (at any position)
+ * attempt == 1: with '^' at start (only at position 0)
+ * attempt == 2: with '$' at end (only match at end)
+ * attempt == 3: with '^' at start and '$' at end (only full match)
+ * Repeat this for finding an unlisted buffer if there was no matching
+ * listed buffer.
+ */
+ else {
+ pat = file_pat_to_reg_pat(pattern, pattern_end, NULL, FALSE);
+ if (pat == NULL)
+ return -1;
+ patend = pat + STRLEN(pat) - 1;
+ toggledollar = (patend > pat && *patend == '$');
+
+ /* First try finding a listed buffer. If not found and "unlisted"
+ * is TRUE, try finding an unlisted buffer. */
+ find_listed = TRUE;
+ for (;; ) {
+ for (attempt = 0; attempt <= 3; ++attempt) {
+ /* may add '^' and '$' */
+ if (toggledollar)
+ *patend = (attempt < 2) ? NUL : '$'; /* add/remove '$' */
+ p = pat;
+ if (*p == '^' && !(attempt & 1)) /* add/remove '^' */
+ ++p;
+ prog = vim_regcomp(p, p_magic ? RE_MAGIC : 0);
+ if (prog == NULL) {
+ vim_free(pat);
+ return -1;
+ }
+
+ for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+ if (buf->b_p_bl == find_listed
+ && (!diffmode || diff_mode_buf(buf))
+ && buflist_match(prog, buf) != NULL) {
+ if (curtab_only) {
+ /* Ignore the match if the buffer is not open in
+ * the current tab. */
+ win_T *wp;
+
+ for (wp = firstwin; wp != NULL; wp = wp->w_next)
+ if (wp->w_buffer == buf)
+ break;
+ if (wp == NULL)
+ continue;
+ }
+ if (match >= 0) { /* already found a match */
+ match = -2;
+ break;
+ }
+ match = buf->b_fnum; /* remember first match */
+ }
+
+ vim_regfree(prog);
+ if (match >= 0) /* found one match */
+ break;
+ }
+
+ /* Only search for unlisted buffers if there was no match with
+ * a listed buffer. */
+ if (!unlisted || !find_listed || match != -1)
+ break;
+ find_listed = FALSE;
+ }
+
+ vim_free(pat);
+ }
+
+ if (match == -2)
+ EMSG2(_("E93: More than one match for %s"), pattern);
+ else if (match < 0)
+ EMSG2(_("E94: No matching buffer for %s"), pattern);
+ return match;
+}
+#endif
+
+
+/*
+ * Find all buffer names that match.
+ * For command line expansion of ":buf" and ":sbuf".
+ * Return OK if matches found, FAIL otherwise.
+ */
+int ExpandBufnames(pat, num_file, file, options)
+char_u *pat;
+int *num_file;
+char_u ***file;
+int options;
+{
+ int count = 0;
+ buf_T *buf;
+ int round;
+ char_u *p;
+ int attempt;
+ regprog_T *prog;
+ char_u *patc;
+
+ *num_file = 0; /* return values in case of FAIL */
+ *file = NULL;
+
+ /* Make a copy of "pat" and change "^" to "\(^\|[\/]\)". */
+ if (*pat == '^') {
+ patc = alloc((unsigned)STRLEN(pat) + 11);
+ if (patc == NULL)
+ return FAIL;
+ STRCPY(patc, "\\(^\\|[\\/]\\)");
+ STRCPY(patc + 11, pat + 1);
+ } else
+ patc = pat;
+
+ /*
+ * attempt == 0: try match with '\<', match at start of word
+ * attempt == 1: try match without '\<', match anywhere
+ */
+ for (attempt = 0; attempt <= 1; ++attempt) {
+ if (attempt > 0 && patc == pat)
+ break; /* there was no anchor, no need to try again */
+ prog = vim_regcomp(patc + attempt * 11, RE_MAGIC);
+ if (prog == NULL) {
+ if (patc != pat)
+ vim_free(patc);
+ return FAIL;
+ }
+
+ /*
+ * round == 1: Count the matches.
+ * round == 2: Build the array to keep the matches.
+ */
+ for (round = 1; round <= 2; ++round) {
+ count = 0;
+ for (buf = firstbuf; buf != NULL; buf = buf->b_next) {
+ if (!buf->b_p_bl) /* skip unlisted buffers */
+ continue;
+ p = buflist_match(prog, buf);
+ if (p != NULL) {
+ if (round == 1)
+ ++count;
+ else {
+ if (options & WILD_HOME_REPLACE)
+ p = home_replace_save(buf, p);
+ else
+ p = vim_strsave(p);
+ (*file)[count++] = p;
+ }
+ }
+ }
+ if (count == 0) /* no match found, break here */
+ break;
+ if (round == 1) {
+ *file = (char_u **)alloc((unsigned)(count * sizeof(char_u *)));
+ if (*file == NULL) {
+ vim_regfree(prog);
+ if (patc != pat)
+ vim_free(patc);
+ return FAIL;
+ }
+ }
+ }
+ vim_regfree(prog);
+ if (count) /* match(es) found, break here */
+ break;
+ }
+
+ if (patc != pat)
+ vim_free(patc);
+
+ *num_file = count;
+ return count == 0 ? FAIL : OK;
+}
+
+
+#ifdef HAVE_BUFLIST_MATCH
+/*
+ * Check for a match on the file name for buffer "buf" with regprog "prog".
+ */
+static char_u * buflist_match(prog, buf)
+regprog_T *prog;
+buf_T *buf;
+{
+ char_u *match;
+
+ /* First try the short file name, then the long file name. */
+ match = fname_match(prog, buf->b_sfname);
+ if (match == NULL)
+ match = fname_match(prog, buf->b_ffname);
+
+ return match;
+}
+
+/*
+ * Try matching the regexp in "prog" with file name "name".
+ * Return "name" when there is a match, NULL when not.
+ */
+static char_u * fname_match(prog, name)
+regprog_T *prog;
+char_u *name;
+{
+ char_u *match = NULL;
+ char_u *p;
+ regmatch_T regmatch;
+
+ if (name != NULL) {
+ regmatch.regprog = prog;
+ regmatch.rm_ic = p_fic; /* ignore case when 'fileignorecase' is set */
+ if (vim_regexec(&regmatch, name, (colnr_T)0))
+ match = name;
+ else {
+ /* Replace $(HOME) with '~' and try matching again. */
+ p = home_replace_save(NULL, name);
+ if (p != NULL && vim_regexec(&regmatch, p, (colnr_T)0))
+ match = name;
+ vim_free(p);
+ }
+ }
+
+ return match;
+}
+#endif
+
+/*
+ * find file in buffer list by number
+ */
+buf_T * buflist_findnr(nr)
+int nr;
+{
+ buf_T *buf;
+
+ if (nr == 0)
+ nr = curwin->w_alt_fnum;
+ for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+ if (buf->b_fnum == nr)
+ return buf;
+ return NULL;
+}
+
+/*
+ * Get name of file 'n' in the buffer list.
+ * When the file has no name an empty string is returned.
+ * home_replace() is used to shorten the file name (used for marks).
+ * Returns a pointer to allocated memory, of NULL when failed.
+ */
+char_u * buflist_nr2name(n, fullname, helptail)
+int n;
+int fullname;
+int helptail; /* for help buffers return tail only */
+{
+ buf_T *buf;
+
+ buf = buflist_findnr(n);
+ if (buf == NULL)
+ return NULL;
+ return home_replace_save(helptail ? buf : NULL,
+ fullname ? buf->b_ffname : buf->b_fname);
+}
+
+/*
+ * Set the "lnum" and "col" for the buffer "buf" and the current window.
+ * When "copy_options" is TRUE save the local window option values.
+ * When "lnum" is 0 only do the options.
+ */
+static void buflist_setfpos(buf, win, lnum, col, copy_options)
+buf_T *buf;
+win_T *win;
+linenr_T lnum;
+colnr_T col;
+int copy_options;
+{
+ wininfo_T *wip;
+
+ for (wip = buf->b_wininfo; wip != NULL; wip = wip->wi_next)
+ if (wip->wi_win == win)
+ break;
+ if (wip == NULL) {
+ /* allocate a new entry */
+ wip = (wininfo_T *)alloc_clear((unsigned)sizeof(wininfo_T));
+ if (wip == NULL)
+ return;
+ wip->wi_win = win;
+ if (lnum == 0) /* set lnum even when it's 0 */
+ lnum = 1;
+ } else {
+ /* remove the entry from the list */
+ if (wip->wi_prev)
+ wip->wi_prev->wi_next = wip->wi_next;
+ else
+ buf->b_wininfo = wip->wi_next;
+ if (wip->wi_next)
+ wip->wi_next->wi_prev = wip->wi_prev;
+ if (copy_options && wip->wi_optset) {
+ clear_winopt(&wip->wi_opt);
+ deleteFoldRecurse(&wip->wi_folds);
+ }
+ }
+ if (lnum != 0) {
+ wip->wi_fpos.lnum = lnum;
+ wip->wi_fpos.col = col;
+ }
+ if (copy_options) {
+ /* Save the window-specific option values. */
+ copy_winopt(&win->w_onebuf_opt, &wip->wi_opt);
+ wip->wi_fold_manual = win->w_fold_manual;
+ cloneFoldGrowArray(&win->w_folds, &wip->wi_folds);
+ wip->wi_optset = TRUE;
+ }
+
+ /* insert the entry in front of the list */
+ wip->wi_next = buf->b_wininfo;
+ buf->b_wininfo = wip;
+ wip->wi_prev = NULL;
+ if (wip->wi_next)
+ wip->wi_next->wi_prev = wip;
+
+ return;
+}
+
+static int wininfo_other_tab_diff __ARGS((wininfo_T *wip));
+
+/*
+ * Return TRUE when "wip" has 'diff' set and the diff is only for another tab
+ * page. That's because a diff is local to a tab page.
+ */
+static int wininfo_other_tab_diff(wip)
+wininfo_T *wip;
+{
+ win_T *wp;
+
+ if (wip->wi_opt.wo_diff) {
+ for (wp = firstwin; wp != NULL; wp = wp->w_next)
+ /* return FALSE when it's a window in the current tab page, thus
+ * the buffer was in diff mode here */
+ if (wip->wi_win == wp)
+ return FALSE;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*
+ * Find info for the current window in buffer "buf".
+ * If not found, return the info for the most recently used window.
+ * When "skip_diff_buffer" is TRUE avoid windows with 'diff' set that is in
+ * another tab page.
+ * Returns NULL when there isn't any info.
+ */
+static wininfo_T * find_wininfo(buf, skip_diff_buffer)
+buf_T *buf;
+int skip_diff_buffer UNUSED;
+{
+ wininfo_T *wip;
+
+ for (wip = buf->b_wininfo; wip != NULL; wip = wip->wi_next)
+ if (wip->wi_win == curwin
+ && (!skip_diff_buffer || !wininfo_other_tab_diff(wip))
+ )
+ break;
+
+ /* If no wininfo for curwin, use the first in the list (that doesn't have
+ * 'diff' set and is in another tab page). */
+ if (wip == NULL) {
+ if (skip_diff_buffer) {
+ for (wip = buf->b_wininfo; wip != NULL; wip = wip->wi_next)
+ if (!wininfo_other_tab_diff(wip))
+ break;
+ } else
+ wip = buf->b_wininfo;
+ }
+ return wip;
+}
+
+/*
+ * Reset the local window options to the values last used in this window.
+ * If the buffer wasn't used in this window before, use the values from
+ * the most recently used window. If the values were never set, use the
+ * global values for the window.
+ */
+void get_winopts(buf)
+buf_T *buf;
+{
+ wininfo_T *wip;
+
+ clear_winopt(&curwin->w_onebuf_opt);
+ clearFolding(curwin);
+
+ wip = find_wininfo(buf, TRUE);
+ 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;
+ cloneFoldGrowArray(&wip->wi_folds, &curwin->w_folds);
+ } else
+ copy_winopt(&curwin->w_allbuf_opt, &curwin->w_onebuf_opt);
+
+ /* Set 'foldlevel' to 'foldlevelstart' if it's not negative. */
+ if (p_fdls >= 0)
+ curwin->w_p_fdl = p_fdls;
+ check_colorcolumn(curwin);
+}
+
+/*
+ * Find the position (lnum and col) for the buffer 'buf' for the current
+ * window.
+ * Returns a pointer to no_position if no position is found.
+ */
+pos_T * buflist_findfpos(buf)
+buf_T *buf;
+{
+ wininfo_T *wip;
+ static pos_T no_position = INIT_POS_T(1, 0, 0);
+
+ wip = find_wininfo(buf, FALSE);
+ if (wip != NULL)
+ return &(wip->wi_fpos);
+ else
+ return &no_position;
+}
+
+/*
+ * Find the lnum for the buffer 'buf' for the current window.
+ */
+linenr_T buflist_findlnum(buf)
+buf_T *buf;
+{
+ return buflist_findfpos(buf)->lnum;
+}
+
+/*
+ * List all know file names (for :files and :buffers command).
+ */
+void buflist_list(eap)
+exarg_T *eap;
+{
+ buf_T *buf;
+ int len;
+ int i;
+
+ for (buf = firstbuf; buf != NULL && !got_int; buf = buf->b_next) {
+ /* skip unlisted buffers, unless ! was used */
+ if (!buf->b_p_bl && !eap->forceit)
+ continue;
+ msg_putchar('\n');
+ if (buf_spname(buf) != NULL)
+ vim_strncpy(NameBuff, buf_spname(buf), MAXPATHL - 1);
+ else
+ home_replace(buf, buf->b_fname, NameBuff, MAXPATHL, TRUE);
+
+ len = vim_snprintf((char *)IObuff, IOSIZE - 20, "%3d%c%c%c%c%c \"%s\"",
+ buf->b_fnum,
+ buf->b_p_bl ? ' ' : 'u',
+ buf == curbuf ? '%' :
+ (curwin->w_alt_fnum == buf->b_fnum ? '#' : ' '),
+ buf->b_ml.ml_mfp == NULL ? ' ' :
+ (buf->b_nwindows == 0 ? 'h' : 'a'),
+ !buf->b_p_ma ? '-' : (buf->b_p_ro ? '=' : ' '),
+ (buf->b_flags & BF_READERR) ? 'x'
+ : (bufIsChanged(buf) ? '+' : ' '),
+ NameBuff);
+
+ /* put "line 999" in column 40 or after the file name */
+ i = 40 - vim_strsize(IObuff);
+ do {
+ IObuff[len++] = ' ';
+ } while (--i > 0 && len < IOSIZE - 18);
+ vim_snprintf((char *)IObuff + len, (size_t)(IOSIZE - len),
+ _("line %ld"), buf == curbuf ? curwin->w_cursor.lnum
+ : (long)buflist_findlnum(buf));
+ msg_outtrans(IObuff);
+ out_flush(); /* output one line at a time */
+ ui_breakcheck();
+ }
+}
+
+/*
+ * Get file name and line number for file 'fnum'.
+ * Used by DoOneCmd() for translating '%' and '#'.
+ * Used by insert_reg() and cmdline_paste() for '#' register.
+ * Return FAIL if not found, OK for success.
+ */
+int buflist_name_nr(fnum, fname, lnum)
+int fnum;
+char_u **fname;
+linenr_T *lnum;
+{
+ buf_T *buf;
+
+ buf = buflist_findnr(fnum);
+ if (buf == NULL || buf->b_fname == NULL)
+ return FAIL;
+
+ *fname = buf->b_fname;
+ *lnum = buflist_findlnum(buf);
+
+ return OK;
+}
+
+/*
+ * Set the file name for "buf"' to 'ffname', short file name to 'sfname'.
+ * The file name with the full path is also remembered, for when :cd is used.
+ * Returns FAIL for failure (file name already in use by other buffer)
+ * OK otherwise.
+ */
+int setfname(buf, ffname, sfname, message)
+buf_T *buf;
+char_u *ffname, *sfname;
+int message; /* give message when buffer already exists */
+{
+ buf_T *obuf = NULL;
+#ifdef UNIX
+ struct stat st;
+#endif
+
+ if (ffname == NULL || *ffname == NUL) {
+ /* Removing the name. */
+ vim_free(buf->b_ffname);
+ vim_free(buf->b_sfname);
+ buf->b_ffname = NULL;
+ buf->b_sfname = NULL;
+#ifdef UNIX
+ st.st_dev = (dev_T)-1;
+#endif
+ } else {
+ fname_expand(buf, &ffname, &sfname); /* will allocate ffname */
+ if (ffname == NULL) /* out of memory */
+ return FAIL;
+
+ /*
+ * if the file name is already used in another buffer:
+ * - if the buffer is loaded, fail
+ * - if the buffer is not loaded, delete it from the list
+ */
+#ifdef UNIX
+ if (mch_stat((char *)ffname, &st) < 0)
+ st.st_dev = (dev_T)-1;
+#endif
+ if (!(buf->b_flags & BF_DUMMY))
+#ifdef UNIX
+ obuf = buflist_findname_stat(ffname, &st);
+#else
+ obuf = buflist_findname(ffname);
+#endif
+ if (obuf != NULL && obuf != buf) {
+ if (obuf->b_ml.ml_mfp != NULL) { /* it's loaded, fail */
+ if (message)
+ EMSG(_("E95: Buffer with this name already exists"));
+ vim_free(ffname);
+ return FAIL;
+ }
+ /* delete from the list */
+ close_buffer(NULL, obuf, DOBUF_WIPE, FALSE);
+ }
+ sfname = vim_strsave(sfname);
+ if (ffname == NULL || sfname == NULL) {
+ vim_free(sfname);
+ vim_free(ffname);
+ return FAIL;
+ }
+#ifdef USE_FNAME_CASE
+# ifdef USE_LONG_FNAME
+ if (USE_LONG_FNAME)
+# endif
+ fname_case(sfname, 0); /* set correct case for short file name */
+#endif
+ vim_free(buf->b_ffname);
+ vim_free(buf->b_sfname);
+ buf->b_ffname = ffname;
+ buf->b_sfname = sfname;
+ }
+ buf->b_fname = buf->b_sfname;
+#ifdef UNIX
+ if (st.st_dev == (dev_T)-1)
+ buf->b_dev_valid = FALSE;
+ else {
+ buf->b_dev_valid = TRUE;
+ buf->b_dev = st.st_dev;
+ buf->b_ino = st.st_ino;
+ }
+#endif
+
+#ifndef SHORT_FNAME
+ buf->b_shortname = FALSE;
+#endif
+
+ buf_name_changed(buf);
+ return OK;
+}
+
+/*
+ * Crude way of changing the name of a buffer. Use with care!
+ * The name should be relative to the current directory.
+ */
+void buf_set_name(fnum, name)
+int fnum;
+char_u *name;
+{
+ buf_T *buf;
+
+ buf = buflist_findnr(fnum);
+ if (buf != NULL) {
+ vim_free(buf->b_sfname);
+ vim_free(buf->b_ffname);
+ buf->b_ffname = vim_strsave(name);
+ buf->b_sfname = NULL;
+ /* Allocate ffname and expand into full path. Also resolves .lnk
+ * files on Win32. */
+ fname_expand(buf, &buf->b_ffname, &buf->b_sfname);
+ buf->b_fname = buf->b_sfname;
+ }
+}
+
+/*
+ * Take care of what needs to be done when the name of buffer "buf" has
+ * changed.
+ */
+void buf_name_changed(buf)
+buf_T *buf;
+{
+ /*
+ * If the file name changed, also change the name of the swapfile
+ */
+ if (buf->b_ml.ml_mfp != NULL)
+ ml_setname(buf);
+
+ if (curwin->w_buffer == buf)
+ check_arg_idx(curwin); /* check file name for arg list */
+ maketitle(); /* set window title */
+ status_redraw_all(); /* status lines need to be redrawn */
+ fmarks_check_names(buf); /* check named file marks */
+ ml_timestamp(buf); /* reset timestamp */
+}
+
+/*
+ * set alternate file name for current window
+ *
+ * Used by do_one_cmd(), do_write() and do_ecmd().
+ * Return the buffer.
+ */
+buf_T * setaltfname(ffname, sfname, lnum)
+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 */
+ buf = buflist_new(ffname, sfname, lnum, 0);
+ if (buf != NULL && !cmdmod.keepalt)
+ curwin->w_alt_fnum = buf->b_fnum;
+ return buf;
+}
+
+/*
+ * Get alternate file name for current window.
+ * Return NULL if there isn't any, and give error message if requested.
+ */
+char_u * getaltfname(errmsg)
+int errmsg; /* give error message */
+{
+ char_u *fname;
+ linenr_T dummy;
+
+ if (buflist_name_nr(0, &fname, &dummy) == FAIL) {
+ if (errmsg)
+ EMSG(_(e_noalt));
+ return NULL;
+ }
+ return fname;
+}
+
+/*
+ * Add a file name to the buflist and return its number.
+ * Uses same flags as buflist_new(), except BLN_DUMMY.
+ *
+ * used by qf_init(), main() and doarglist()
+ */
+int buflist_add(fname, flags)
+char_u *fname;
+int flags;
+{
+ buf_T *buf;
+
+ buf = buflist_new(fname, NULL, (linenr_T)0, flags);
+ if (buf != NULL)
+ return buf->b_fnum;
+ return 0;
+}
+
+#if defined(BACKSLASH_IN_FILENAME) || defined(PROTO)
+/*
+ * Adjust slashes in file names. Called after 'shellslash' was set.
+ */
+void buflist_slash_adjust() {
+ buf_T *bp;
+
+ for (bp = firstbuf; bp != NULL; bp = bp->b_next) {
+ if (bp->b_ffname != NULL)
+ slash_adjust(bp->b_ffname);
+ if (bp->b_sfname != NULL)
+ slash_adjust(bp->b_sfname);
+ }
+}
+
+#endif
+
+/*
+ * Set alternate cursor position for the current buffer and window "win".
+ * Also save the local window option values.
+ */
+void buflist_altfpos(win)
+win_T *win;
+{
+ buflist_setfpos(curbuf, win, win->w_cursor.lnum, win->w_cursor.col, TRUE);
+}
+
+/*
+ * Return TRUE if 'ffname' is not the same file as current file.
+ * Fname must have a full path (expanded by mch_FullName()).
+ */
+int otherfile(ffname)
+char_u *ffname;
+{
+ return otherfile_buf(curbuf, ffname
+#ifdef UNIX
+ , NULL
+#endif
+ );
+}
+
+static int otherfile_buf(buf, ffname
+#ifdef UNIX
+ , stp
+#endif
+ )
+buf_T *buf;
+char_u *ffname;
+#ifdef UNIX
+struct stat *stp;
+#endif
+{
+ /* no name is different */
+ if (ffname == NULL || *ffname == NUL || buf->b_ffname == NULL)
+ return TRUE;
+ if (fnamecmp(ffname, buf->b_ffname) == 0)
+ return FALSE;
+#ifdef UNIX
+ {
+ struct stat st;
+
+ /* If no struct stat given, get it now */
+ if (stp == NULL) {
+ if (!buf->b_dev_valid || mch_stat((char *)ffname, &st) < 0)
+ st.st_dev = (dev_T)-1;
+ stp = &st;
+ }
+ /* Use dev/ino to check if the files are the same, even when the names
+ * are different (possible with links). Still need to compare the
+ * name above, for when the file doesn't exist yet.
+ * Problem: The dev/ino changes when a file is deleted (and created
+ * again) and remains the same when renamed/moved. We don't want to
+ * mch_stat() each buffer each time, that would be too slow. Get the
+ * dev/ino again when they appear to match, but not when they appear
+ * to be different: Could skip a buffer when it's actually the same
+ * file. */
+ if (buf_same_ino(buf, stp)) {
+ buf_setino(buf);
+ if (buf_same_ino(buf, stp))
+ return FALSE;
+ }
+ }
+#endif
+ return TRUE;
+}
+
+#if defined(UNIX) || defined(PROTO)
+/*
+ * Set inode and device number for a buffer.
+ * Must always be called when b_fname is changed!.
+ */
+void buf_setino(buf)
+buf_T *buf;
+{
+ struct stat st;
+
+ if (buf->b_fname != NULL && mch_stat((char *)buf->b_fname, &st) >= 0) {
+ buf->b_dev_valid = TRUE;
+ buf->b_dev = st.st_dev;
+ buf->b_ino = st.st_ino;
+ } else
+ buf->b_dev_valid = FALSE;
+}
+
+/*
+ * Return TRUE if dev/ino in buffer "buf" matches with "stp".
+ */
+static int buf_same_ino(buf, stp)
+buf_T *buf;
+struct stat *stp;
+{
+ return buf->b_dev_valid
+ && stp->st_dev == buf->b_dev
+ && stp->st_ino == buf->b_ino;
+}
+#endif
+
+/*
+ * Print info about the current buffer.
+ */
+void fileinfo(fullname, shorthelp, dont_truncate)
+int fullname; /* when non-zero print full path */
+int shorthelp;
+int dont_truncate;
+{
+ char_u *name;
+ int n;
+ char_u *p;
+ char_u *buffer;
+ size_t len;
+
+ buffer = alloc(IOSIZE);
+ if (buffer == NULL)
+ return;
+
+ if (fullname > 1) { /* 2 CTRL-G: include buffer number */
+ vim_snprintf((char *)buffer, IOSIZE, "buf %d: ", curbuf->b_fnum);
+ p = buffer + STRLEN(buffer);
+ } else
+ p = buffer;
+
+ *p++ = '"';
+ if (buf_spname(curbuf) != NULL)
+ vim_strncpy(p, buf_spname(curbuf), IOSIZE - (p - buffer) - 1);
+ else {
+ if (!fullname && curbuf->b_fname != NULL)
+ name = curbuf->b_fname;
+ else
+ name = curbuf->b_ffname;
+ home_replace(shorthelp ? curbuf : NULL, name, p,
+ (int)(IOSIZE - (p - buffer)), TRUE);
+ }
+
+ vim_snprintf_add((char *)buffer, IOSIZE, "\"%s%s%s%s%s%s",
+ curbufIsChanged() ? (shortmess(SHM_MOD)
+ ? " [+]" : _(" [Modified]")) : " ",
+ (curbuf->b_flags & BF_NOTEDITED)
+ && !bt_dontwrite(curbuf)
+ ? _("[Not edited]") : "",
+ (curbuf->b_flags & BF_NEW)
+ && !bt_dontwrite(curbuf)
+ ? _("[New file]") : "",
+ (curbuf->b_flags & BF_READERR) ? _("[Read errors]") : "",
+ curbuf->b_p_ro ? (shortmess(SHM_RO) ? _("[RO]")
+ : _("[readonly]")) : "",
+ (curbufIsChanged() || (curbuf->b_flags & BF_WRITE_MASK)
+ || curbuf->b_p_ro) ?
+ " " : "");
+ /* With 32 bit longs and more than 21,474,836 lines multiplying by 100
+ * causes an overflow, thus for large numbers divide instead. */
+ if (curwin->w_cursor.lnum > 1000000L)
+ n = (int)(((long)curwin->w_cursor.lnum) /
+ ((long)curbuf->b_ml.ml_line_count / 100L));
+ else
+ n = (int)(((long)curwin->w_cursor.lnum * 100L) /
+ (long)curbuf->b_ml.ml_line_count);
+ if (curbuf->b_ml.ml_flags & ML_EMPTY) {
+ vim_snprintf_add((char *)buffer, IOSIZE, "%s", _(no_lines_msg));
+ } else if (p_ru) {
+ /* Current line and column are already on the screen -- webb */
+ if (curbuf->b_ml.ml_line_count == 1)
+ vim_snprintf_add((char *)buffer, IOSIZE, _("1 line --%d%%--"), n);
+ else
+ vim_snprintf_add((char *)buffer, IOSIZE, _("%ld lines --%d%%--"),
+ (long)curbuf->b_ml.ml_line_count, n);
+ } else {
+ vim_snprintf_add((char *)buffer, IOSIZE,
+ _("line %ld of %ld --%d%%-- col "),
+ (long)curwin->w_cursor.lnum,
+ (long)curbuf->b_ml.ml_line_count,
+ n);
+ validate_virtcol();
+ len = STRLEN(buffer);
+ col_print(buffer + len, IOSIZE - len,
+ (int)curwin->w_cursor.col + 1, (int)curwin->w_virtcol + 1);
+ }
+
+ (void)append_arg_number(curwin, buffer, IOSIZE, !shortmess(SHM_FILE));
+
+ if (dont_truncate) {
+ /* Temporarily set msg_scroll to avoid the message being truncated.
+ * First call msg_start() to get the message in the right place. */
+ msg_start();
+ n = msg_scroll;
+ msg_scroll = TRUE;
+ msg(buffer);
+ msg_scroll = n;
+ } else {
+ p = msg_trunc_attr(buffer, FALSE, 0);
+ if (restart_edit != 0 || (msg_scrolled && !need_wait_return))
+ /* Need to repeat the message after redrawing when:
+ * - 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);
+ }
+
+ vim_free(buffer);
+}
+
+void col_print(buf, buflen, col, vcol)
+char_u *buf;
+size_t buflen;
+int col;
+int vcol;
+{
+ if (col == vcol)
+ vim_snprintf((char *)buf, buflen, "%d", col);
+ else
+ vim_snprintf((char *)buf, buflen, "%d-%d", col, vcol);
+}
+
+/*
+ * put file name in title bar of window and in icon title
+ */
+
+static char_u *lasttitle = NULL;
+static char_u *lasticon = NULL;
+
+void maketitle() {
+ 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;
+
+ if (!redrawing()) {
+ /* Postpone updating the title when 'lazyredraw' is set. */
+ need_maketitle = TRUE;
+ return;
+ }
+
+ need_maketitle = FALSE;
+ if (!p_title && !p_icon && lasttitle == NULL && lasticon == NULL)
+ return;
+
+ if (p_title) {
+ if (p_titlelen > 0) {
+ maxlen = 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 |= save_called_emsg;
+ } 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)
+ vim_strncpy(buf, (char_u *)_("[No Name]"), SPACE_FOR_FNAME);
+ else {
+ p = transstr(gettail(curbuf->b_fname));
+ vim_strncpy(buf, p, SPACE_FOR_FNAME);
+ vim_free(p);
+ }
+
+ switch (bufIsChanged(curbuf)
+ + (curbuf->b_p_ro * 2)
+ + (!curbuf->b_p_ma * 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;
+ }
+
+ 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);
+#ifdef BACKSLASH_IN_FILENAME
+ /* avoid "c:/name" to be reduced to "c" */
+ if (isalpha(buf[off]) && buf[off + 1] == ':')
+ off += 2;
+#endif
+ /* remove the file name */
+ p = gettail_sep(buf + off);
+ if (p == buf + off)
+ /* must be a help buffer */
+ vim_strncpy(buf + off, (char_u *)_("help"),
+ (size_t)(SPACE_FOR_DIR - off - 1));
+ 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);
+ vim_strncpy(buf + off, p, (size_t)(SPACE_FOR_DIR - off));
+ vim_free(p);
+ } else {
+ vim_strncpy(buf + off, (char_u *)"...",
+ (size_t)(SPACE_FOR_ARGNR - off));
+ }
+ STRCAT(buf, ")");
+ }
+
+ append_arg_number(curwin, buf, SPACE_FOR_ARGNR, FALSE);
+
+ STRCAT(buf, " - VIM");
+
+ if (maxlen > 0) {
+ /* make it shorter by removing a bit in the middle */
+ if (vim_strsize(buf) > maxlen)
+ trunc_string(buf, buf, maxlen, IOSIZE);
+ }
+ }
+ }
+ mustset = ti_change(t_str, &lasttitle);
+
+ if (p_icon) {
+ i_str = buf;
+ if (*p_iconstring != NUL) {
+ if (stl_syntax & STL_IN_ICON) {
+ int use_sandbox = FALSE;
+ int save_called_emsg = called_emsg;
+
+ use_sandbox = was_set_insecurely((char_u *)"iconstring", 0);
+ called_emsg = FALSE;
+ build_stl_str_hl(curwin, i_str, sizeof(buf),
+ p_iconstring, use_sandbox,
+ 0, 0, NULL, NULL);
+ if (called_emsg)
+ set_string_option_direct((char_u *)"iconstring", -1,
+ (char_u *)"", OPT_FREE, SID_ERROR);
+ called_emsg |= save_called_emsg;
+ } else
+ i_str = p_iconstring;
+ } else {
+ if (buf_spname(curbuf) != NULL)
+ i_name = buf_spname(curbuf);
+ else /* use file name only in icon */
+ i_name = gettail(curbuf->b_ffname);
+ *i_str = NUL;
+ /* Truncate name at 100 bytes. */
+ len = (int)STRLEN(i_name);
+ if (len > 100) {
+ len -= 100;
+ if (has_mbyte)
+ len += (*mb_tail_off)(i_name, i_name + len) + 1;
+ i_name += len;
+ }
+ STRCPY(i_str, i_name);
+ trans_characters(i_str, IOSIZE);
+ }
+ }
+
+ mustset |= ti_change(i_str, &lasticon);
+
+ if (mustset)
+ resettitle();
+}
+
+/*
+ * Used for title and icon: Check if "str" differs from "*last". Set "*last"
+ * from "str" if it does.
+ * Return TRUE when "*last" changed.
+ */
+static int ti_change(str, last)
+char_u *str;
+char_u **last;
+{
+ if ((str == NULL) != (*last == NULL)
+ || (str != NULL && *last != NULL && STRCMP(str, *last) != 0)) {
+ vim_free(*last);
+ if (str == NULL)
+ *last = NULL;
+ else
+ *last = vim_strsave(str);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*
+ * Put current window title back (used after calling a shell)
+ */
+void resettitle() {
+ mch_settitle(lasttitle, lasticon);
+}
+
+# if defined(EXITFREE) || defined(PROTO)
+void free_titles() {
+ vim_free(lasttitle);
+ vim_free(lasticon);
+}
+
+# endif
+
+
+/*
+ * Build a string from the status line items in "fmt".
+ * Return length of string in screen cells.
+ *
+ * Normally works for window "wp", except when working for 'tabline' then it
+ * is "curwin".
+ *
+ * Items are drawn interspersed with the text that surrounds it
+ * Specials: %-<wid>(xxx%) => group, %= => middle marker, %< => truncation
+ * Item: %-<minwid>.<maxwid><itemch> All but <itemch> are optional
+ *
+ * If maxwidth is not zero, the string will be filled at any middle marker
+ * or truncated if too long, fillchar is used for all whitespace.
+ */
+int build_stl_str_hl(wp, out, outlen, fmt, use_sandbox, fillchar,
+ maxwidth, hltab, tabtab)
+win_T *wp;
+char_u *out; /* buffer to write into != NameBuff */
+size_t outlen; /* length of out[] */
+char_u *fmt;
+int use_sandbox UNUSED; /* "fmt" was set insecurely, use sandbox */
+int fillchar;
+int maxwidth;
+struct stl_hlrec *hltab; /* return: HL attributes (can be NULL) */
+struct stl_hlrec *tabtab; /* return: tab page nrs (can be NULL) */
+{
+ char_u *p;
+ char_u *s;
+ char_u *t;
+ int byteval;
+ win_T *o_curwin;
+ buf_T *o_curbuf;
+ int empty_line;
+ colnr_T virtcol;
+ long l;
+ long n;
+ int prevchar_isflag;
+ int prevchar_isitem;
+ int itemisflag;
+ int fillable;
+ char_u *str;
+ long num;
+ int width;
+ int itemcnt;
+ int curitem;
+ int groupitem[STL_MAX_ITEM];
+ int groupdepth;
+ struct stl_item {
+ char_u *start;
+ int minwid;
+ int maxwid;
+ enum {
+ Normal,
+ Empty,
+ Group,
+ Middle,
+ Highlight,
+ TabPage,
+ Trunc
+ } type;
+ } item[STL_MAX_ITEM];
+ int minwid;
+ int maxwid;
+ int zeropad;
+ char_u base;
+ char_u opt;
+#define TMPLEN 70
+ char_u tmp[TMPLEN];
+ char_u *usefmt = fmt;
+ struct stl_hlrec *sp;
+
+ /*
+ * When the format starts with "%!" then evaluate it as an expression and
+ * use the result as the actual format string.
+ */
+ if (fmt[0] == '%' && fmt[1] == '!') {
+ usefmt = eval_to_string_safe(fmt + 2, NULL, use_sandbox);
+ if (usefmt == NULL)
+ usefmt = fmt;
+ }
+
+ if (fillchar == 0)
+ fillchar = ' ';
+ /* Can't handle a multi-byte fill character yet. */
+ else if (mb_char2len(fillchar) > 1)
+ fillchar = '-';
+
+ /* Get line & check if empty (cursorpos will show "0-1"). Note that
+ * p will become invalid when getting another buffer line. */
+ p = ml_get_buf(wp->w_buffer, wp->w_cursor.lnum, FALSE);
+ empty_line = (*p == NUL);
+
+ /* Get the byte value now, in case we need it below. This is more
+ * efficient than making a copy of the line. */
+ if (wp->w_cursor.col > (colnr_T)STRLEN(p))
+ byteval = 0;
+ else
+ byteval = (*mb_ptr2char)(p + wp->w_cursor.col);
+
+ groupdepth = 0;
+ p = out;
+ curitem = 0;
+ prevchar_isflag = TRUE;
+ prevchar_isitem = FALSE;
+ for (s = usefmt; *s; ) {
+ if (curitem == STL_MAX_ITEM) {
+ /* There are too many items. Add the error code to the statusline
+ * to give the user a hint about what went wrong. */
+ if (p + 6 < out + outlen) {
+ mch_memmove(p, " E541", (size_t)5);
+ p += 5;
+ }
+ break;
+ }
+
+ if (*s != NUL && *s != '%')
+ prevchar_isflag = prevchar_isitem = FALSE;
+
+ /*
+ * Handle up to the next '%' or the end.
+ */
+ while (*s != NUL && *s != '%' && p + 1 < out + outlen)
+ *p++ = *s++;
+ if (*s == NUL || p + 1 >= out + outlen)
+ break;
+
+ /*
+ * Handle one '%' item.
+ */
+ s++;
+ if (*s == NUL) /* ignore trailing % */
+ break;
+ if (*s == '%') {
+ if (p + 1 >= out + outlen)
+ break;
+ *p++ = *s++;
+ prevchar_isflag = prevchar_isitem = FALSE;
+ continue;
+ }
+ if (*s == STL_MIDDLEMARK) {
+ s++;
+ if (groupdepth > 0)
+ continue;
+ item[curitem].type = Middle;
+ item[curitem++].start = p;
+ continue;
+ }
+ if (*s == STL_TRUNCMARK) {
+ s++;
+ item[curitem].type = Trunc;
+ item[curitem++].start = p;
+ continue;
+ }
+ if (*s == ')') {
+ s++;
+ if (groupdepth < 1)
+ continue;
+ groupdepth--;
+
+ t = item[groupitem[groupdepth]].start;
+ *p = NUL;
+ l = vim_strsize(t);
+ if (curitem > groupitem[groupdepth] + 1
+ && item[groupitem[groupdepth]].minwid == 0) {
+ /* remove group if all items are empty */
+ for (n = groupitem[groupdepth] + 1; n < curitem; n++)
+ if (item[n].type == Normal)
+ break;
+ if (n == curitem) {
+ p = t;
+ l = 0;
+ }
+ }
+ if (l > item[groupitem[groupdepth]].maxwid) {
+ /* truncate, remove n bytes of text at the start */
+ if (has_mbyte) {
+ /* Find the first character that should be included. */
+ n = 0;
+ while (l >= item[groupitem[groupdepth]].maxwid) {
+ l -= ptr2cells(t + n);
+ n += (*mb_ptr2len)(t + n);
+ }
+ } else
+ n = (long)(p - t) - item[groupitem[groupdepth]].maxwid + 1;
+
+ *t = '<';
+ mch_memmove(t + 1, t + n, (size_t)(p - (t + n)));
+ p = p - n + 1;
+ /* Fill up space left over by half a double-wide char. */
+ while (++l < item[groupitem[groupdepth]].minwid)
+ *p++ = fillchar;
+
+ /* correct the start of the items for the truncation */
+ for (l = groupitem[groupdepth] + 1; l < curitem; l++) {
+ item[l].start -= n;
+ if (item[l].start < t)
+ item[l].start = t;
+ }
+ } else if (abs(item[groupitem[groupdepth]].minwid) > l) {
+ /* fill */
+ n = item[groupitem[groupdepth]].minwid;
+ if (n < 0) {
+ /* fill by appending characters */
+ n = 0 - n;
+ while (l++ < n && p + 1 < out + outlen)
+ *p++ = fillchar;
+ } else {
+ /* fill by inserting characters */
+ mch_memmove(t + n - l, t, (size_t)(p - t));
+ l = n - l;
+ if (p + l >= out + outlen)
+ l = (long)((out + outlen) - p - 1);
+ p += l;
+ for (n = groupitem[groupdepth] + 1; n < curitem; n++)
+ item[n].start += l;
+ for (; l > 0; l--)
+ *t++ = fillchar;
+ }
+ }
+ continue;
+ }
+ minwid = 0;
+ maxwid = 9999;
+ zeropad = FALSE;
+ l = 1;
+ if (*s == '0') {
+ s++;
+ zeropad = TRUE;
+ }
+ if (*s == '-') {
+ s++;
+ l = -1;
+ }
+ if (VIM_ISDIGIT(*s)) {
+ minwid = (int)getdigits(&s);
+ if (minwid < 0) /* overflow */
+ minwid = 0;
+ }
+ if (*s == STL_USER_HL) {
+ item[curitem].type = Highlight;
+ item[curitem].start = p;
+ item[curitem].minwid = minwid > 9 ? 1 : minwid;
+ s++;
+ curitem++;
+ continue;
+ }
+ if (*s == STL_TABPAGENR || *s == STL_TABCLOSENR) {
+ if (*s == STL_TABCLOSENR) {
+ if (minwid == 0) {
+ /* %X ends the close label, go back to the previously
+ * define tab label nr. */
+ for (n = curitem - 1; n >= 0; --n)
+ if (item[n].type == TabPage && item[n].minwid >= 0) {
+ minwid = item[n].minwid;
+ break;
+ }
+ } else
+ /* close nrs are stored as negative values */
+ minwid = -minwid;
+ }
+ item[curitem].type = TabPage;
+ item[curitem].start = p;
+ item[curitem].minwid = minwid;
+ s++;
+ curitem++;
+ continue;
+ }
+ if (*s == '.') {
+ s++;
+ if (VIM_ISDIGIT(*s)) {
+ maxwid = (int)getdigits(&s);
+ if (maxwid <= 0) /* overflow */
+ maxwid = 50;
+ }
+ }
+ minwid = (minwid > 50 ? 50 : minwid) * l;
+ if (*s == '(') {
+ groupitem[groupdepth++] = curitem;
+ item[curitem].type = Group;
+ item[curitem].start = p;
+ item[curitem].minwid = minwid;
+ item[curitem].maxwid = maxwid;
+ s++;
+ curitem++;
+ continue;
+ }
+ if (vim_strchr(STL_ALL, *s) == NULL) {
+ s++;
+ continue;
+ }
+ opt = *s++;
+
+ /* OK - now for the real work */
+ base = 'D';
+ itemisflag = FALSE;
+ fillable = TRUE;
+ num = -1;
+ str = NULL;
+ switch (opt) {
+ case STL_FILEPATH:
+ case STL_FULLPATH:
+ case STL_FILENAME:
+ fillable = FALSE; /* don't change ' ' to fillchar */
+ if (buf_spname(wp->w_buffer) != NULL)
+ vim_strncpy(NameBuff, buf_spname(wp->w_buffer), MAXPATHL - 1);
+ else {
+ t = (opt == STL_FULLPATH) ? wp->w_buffer->b_ffname
+ : wp->w_buffer->b_fname;
+ home_replace(wp->w_buffer, t, NameBuff, MAXPATHL, TRUE);
+ }
+ trans_characters(NameBuff, MAXPATHL);
+ if (opt != STL_FILENAME)
+ str = NameBuff;
+ else
+ str = gettail(NameBuff);
+ break;
+
+ case STL_VIM_EXPR: /* '{' */
+ itemisflag = TRUE;
+ t = p;
+ while (*s != '}' && *s != NUL && p + 1 < out + outlen)
+ *p++ = *s++;
+ if (*s != '}') /* missing '}' or out of space */
+ break;
+ s++;
+ *p = 0;
+ p = t;
+
+ vim_snprintf((char *)tmp, sizeof(tmp), "%d", curbuf->b_fnum);
+ set_internal_string_var((char_u *)"actual_curbuf", tmp);
+
+ o_curbuf = curbuf;
+ o_curwin = curwin;
+ curwin = wp;
+ curbuf = wp->w_buffer;
+
+ str = eval_to_string_safe(p, &t, use_sandbox);
+
+ curwin = o_curwin;
+ curbuf = o_curbuf;
+ do_unlet((char_u *)"g:actual_curbuf", TRUE);
+
+ if (str != NULL && *str != 0) {
+ if (*skipdigits(str) == NUL) {
+ num = atoi((char *)str);
+ vim_free(str);
+ str = NULL;
+ itemisflag = FALSE;
+ }
+ }
+ break;
+
+ case STL_LINE:
+ num = (wp->w_buffer->b_ml.ml_flags & ML_EMPTY)
+ ? 0L : (long)(wp->w_cursor.lnum);
+ break;
+
+ case STL_NUMLINES:
+ num = wp->w_buffer->b_ml.ml_line_count;
+ break;
+
+ case STL_COLUMN:
+ num = !(State & INSERT) && empty_line
+ ? 0 : (int)wp->w_cursor.col + 1;
+ break;
+
+ case STL_VIRTCOL:
+ case STL_VIRTCOL_ALT:
+ /* In list mode virtcol needs to be recomputed */
+ virtcol = wp->w_virtcol;
+ if (wp->w_p_list && lcs_tab1 == NUL) {
+ wp->w_p_list = FALSE;
+ getvcol(wp, &wp->w_cursor, NULL, &virtcol, NULL);
+ wp->w_p_list = TRUE;
+ }
+ ++virtcol;
+ /* Don't display %V if it's the same as %c. */
+ if (opt == STL_VIRTCOL_ALT
+ && (virtcol == (colnr_T)(!(State & INSERT) && empty_line
+ ? 0 : (int)wp->w_cursor.col + 1)))
+ break;
+ num = (long)virtcol;
+ break;
+
+ case STL_PERCENTAGE:
+ num = (int)(((long)wp->w_cursor.lnum * 100L) /
+ (long)wp->w_buffer->b_ml.ml_line_count);
+ break;
+
+ case STL_ALTPERCENT:
+ str = tmp;
+ get_rel_pos(wp, str, TMPLEN);
+ break;
+
+ case STL_ARGLISTSTAT:
+ fillable = FALSE;
+ tmp[0] = 0;
+ if (append_arg_number(wp, tmp, (int)sizeof(tmp), FALSE))
+ str = tmp;
+ break;
+
+ case STL_KEYMAP:
+ fillable = FALSE;
+ if (get_keymap_str(wp, tmp, TMPLEN))
+ str = tmp;
+ break;
+ case STL_PAGENUM:
+ num = printer_page_num;
+ break;
+
+ case STL_BUFNO:
+ num = wp->w_buffer->b_fnum;
+ break;
+
+ case STL_OFFSET_X:
+ base = 'X';
+ case STL_OFFSET:
+ l = ml_find_line_or_offset(wp->w_buffer, wp->w_cursor.lnum, NULL);
+ 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);
+ break;
+
+ case STL_BYTEVAL_X:
+ base = 'X';
+ case STL_BYTEVAL:
+ num = byteval;
+ if (num == NL)
+ num = 0;
+ else if (num == CAR && get_fileformat(wp->w_buffer) == EOL_MAC)
+ num = NL;
+ break;
+
+ case STL_ROFLAG:
+ case STL_ROFLAG_ALT:
+ itemisflag = TRUE;
+ if (wp->w_buffer->b_p_ro)
+ str = (char_u *)((opt == STL_ROFLAG_ALT) ? ",RO" : _("[RO]"));
+ break;
+
+ case STL_HELPFLAG:
+ case STL_HELPFLAG_ALT:
+ itemisflag = TRUE;
+ if (wp->w_buffer->b_help)
+ str = (char_u *)((opt == STL_HELPFLAG_ALT) ? ",HLP"
+ : _("[Help]"));
+ break;
+
+ case STL_FILETYPE:
+ if (*wp->w_buffer->b_p_ft != NUL
+ && STRLEN(wp->w_buffer->b_p_ft) < TMPLEN - 3) {
+ vim_snprintf((char *)tmp, sizeof(tmp), "[%s]",
+ wp->w_buffer->b_p_ft);
+ str = tmp;
+ }
+ break;
+
+ case STL_FILETYPE_ALT:
+ itemisflag = TRUE;
+ if (*wp->w_buffer->b_p_ft != NUL
+ && STRLEN(wp->w_buffer->b_p_ft) < TMPLEN - 2) {
+ vim_snprintf((char *)tmp, sizeof(tmp), ",%s",
+ wp->w_buffer->b_p_ft);
+ for (t = tmp; *t != 0; t++)
+ *t = TOUPPER_LOC(*t);
+ str = tmp;
+ }
+ break;
+
+ case STL_PREVIEWFLAG:
+ case STL_PREVIEWFLAG_ALT:
+ itemisflag = TRUE;
+ if (wp->w_p_pvw)
+ str = (char_u *)((opt == STL_PREVIEWFLAG_ALT) ? ",PRV"
+ : _("[Preview]"));
+ break;
+
+ case STL_QUICKFIX:
+ if (bt_quickfix(wp->w_buffer))
+ str = (char_u *)(wp->w_llist_ref
+ ? _(msg_loclist)
+ : _(msg_qflist));
+ break;
+
+ case STL_MODIFIED:
+ case STL_MODIFIED_ALT:
+ itemisflag = TRUE;
+ switch ((opt == STL_MODIFIED_ALT)
+ + bufIsChanged(wp->w_buffer) * 2
+ + (!wp->w_buffer->b_p_ma) * 4) {
+ case 2: str = (char_u *)"[+]"; break;
+ case 3: str = (char_u *)",+"; break;
+ case 4: str = (char_u *)"[-]"; break;
+ case 5: str = (char_u *)",-"; break;
+ case 6: str = (char_u *)"[+-]"; break;
+ case 7: str = (char_u *)",+-"; break;
+ }
+ break;
+
+ case STL_HIGHLIGHT:
+ t = s;
+ while (*s != '#' && *s != NUL)
+ ++s;
+ if (*s == '#') {
+ item[curitem].type = Highlight;
+ item[curitem].start = p;
+ item[curitem].minwid = -syn_namen2id(t, (int)(s - t));
+ curitem++;
+ }
+ if (*s != NUL)
+ ++s;
+ continue;
+ }
+
+ item[curitem].start = p;
+ item[curitem].type = Normal;
+ if (str != NULL && *str) {
+ t = str;
+ if (itemisflag) {
+ if ((t[0] && t[1])
+ && ((!prevchar_isitem && *t == ',')
+ || (prevchar_isflag && *t == ' ')))
+ t++;
+ prevchar_isflag = TRUE;
+ }
+ l = vim_strsize(t);
+ if (l > 0)
+ prevchar_isitem = TRUE;
+ if (l > maxwid) {
+ while (l >= maxwid)
+ if (has_mbyte) {
+ l -= ptr2cells(t);
+ t += (*mb_ptr2len)(t);
+ } else
+ l -= byte2cells(*t++);
+ if (p + 1 >= out + outlen)
+ break;
+ *p++ = '<';
+ }
+ if (minwid > 0) {
+ for (; l < minwid && p + 1 < out + outlen; l++) {
+ /* Don't put a "-" in front of a digit. */
+ if (l + 1 == minwid && fillchar == '-' && VIM_ISDIGIT(*t))
+ *p++ = ' ';
+ else
+ *p++ = fillchar;
+ }
+ minwid = 0;
+ } else
+ minwid *= -1;
+ while (*t && p + 1 < out + outlen) {
+ *p++ = *t++;
+ /* Change a space by fillchar, unless fillchar is '-' and a
+ * digit follows. */
+ if (fillable && p[-1] == ' '
+ && (!VIM_ISDIGIT(*t) || fillchar != '-'))
+ p[-1] = fillchar;
+ }
+ for (; l < minwid && p + 1 < out + outlen; l++)
+ *p++ = fillchar;
+ } else if (num >= 0) {
+ int nbase = (base == 'D' ? 10 : (base == 'O' ? 8 : 16));
+ char_u nstr[20];
+
+ if (p + 20 >= out + outlen)
+ break; /* not sufficient space */
+ prevchar_isitem = TRUE;
+ t = nstr;
+ if (opt == STL_VIRTCOL_ALT) {
+ *t++ = '-';
+ minwid--;
+ }
+ *t++ = '%';
+ if (zeropad)
+ *t++ = '0';
+ *t++ = '*';
+ *t++ = nbase == 16 ? base : (char_u)(nbase == 8 ? 'o' : 'd');
+ *t = 0;
+
+ for (n = num, l = 1; n >= nbase; n /= nbase)
+ l++;
+ if (opt == STL_VIRTCOL_ALT)
+ l++;
+ if (l > maxwid) {
+ l += 2;
+ n = l - maxwid;
+ while (l-- > maxwid)
+ num /= nbase;
+ *t++ = '>';
+ *t++ = '%';
+ *t = t[-3];
+ *++t = 0;
+ vim_snprintf((char *)p, outlen - (p - out), (char *)nstr,
+ 0, num, n);
+ } else
+ vim_snprintf((char *)p, outlen - (p - out), (char *)nstr,
+ minwid, num);
+ p += STRLEN(p);
+ } else
+ item[curitem].type = Empty;
+
+ if (opt == STL_VIM_EXPR)
+ vim_free(str);
+
+ if (num >= 0 || (!itemisflag && str && *str))
+ prevchar_isflag = FALSE; /* Item not NULL, but not a flag */
+ curitem++;
+ }
+ *p = NUL;
+ itemcnt = curitem;
+
+ if (usefmt != fmt)
+ vim_free(usefmt);
+
+ width = vim_strsize(out);
+ if (maxwidth > 0 && width > maxwidth) {
+ /* Result is too long, must truncate somewhere. */
+ l = 0;
+ if (itemcnt == 0)
+ s = out;
+ else {
+ for (; l < itemcnt; l++)
+ if (item[l].type == Trunc) {
+ /* Truncate at %< item. */
+ s = item[l].start;
+ break;
+ }
+ if (l == itemcnt) {
+ /* No %< item, truncate first item. */
+ s = item[0].start;
+ l = 0;
+ }
+ }
+
+ if (width - vim_strsize(s) >= maxwidth) {
+ /* Truncation mark is beyond max length */
+ if (has_mbyte) {
+ s = out;
+ width = 0;
+ for (;; ) {
+ width += ptr2cells(s);
+ if (width >= maxwidth)
+ break;
+ s += (*mb_ptr2len)(s);
+ }
+ /* Fill up for half a double-wide character. */
+ while (++width < maxwidth)
+ *s++ = fillchar;
+ } else
+ s = out + maxwidth - 1;
+ for (l = 0; l < itemcnt; l++)
+ if (item[l].start > s)
+ break;
+ itemcnt = l;
+ *s++ = '>';
+ *s = 0;
+ } else {
+ if (has_mbyte) {
+ n = 0;
+ while (width >= maxwidth) {
+ width -= ptr2cells(s + n);
+ n += (*mb_ptr2len)(s + n);
+ }
+ } else
+ n = width - maxwidth + 1;
+ p = s + n;
+ STRMOVE(s + 1, p);
+ *s = '<';
+
+ /* Fill up for half a double-wide character. */
+ while (++width < maxwidth) {
+ s = s + STRLEN(s);
+ *s++ = fillchar;
+ *s = NUL;
+ }
+
+ --n; /* count the '<' */
+ for (; l < itemcnt; l++) {
+ if (item[l].start - n >= s)
+ item[l].start -= n;
+ else
+ item[l].start = s;
+ }
+ }
+ width = maxwidth;
+ } else if (width < maxwidth && STRLEN(out) + maxwidth - width + 1 <
+ outlen) {
+ /* Apply STL_MIDDLE if any */
+ for (l = 0; l < itemcnt; l++)
+ if (item[l].type == Middle)
+ break;
+ if (l < itemcnt) {
+ p = item[l].start + maxwidth - width;
+ STRMOVE(p, item[l].start);
+ for (s = item[l].start; s < p; s++)
+ *s = fillchar;
+ for (l++; l < itemcnt; l++)
+ item[l].start += maxwidth - width;
+ width = maxwidth;
+ }
+ }
+
+ /* Store the info about highlighting. */
+ if (hltab != NULL) {
+ sp = hltab;
+ for (l = 0; l < itemcnt; l++) {
+ if (item[l].type == Highlight) {
+ sp->start = item[l].start;
+ sp->userhl = item[l].minwid;
+ sp++;
+ }
+ }
+ sp->start = NULL;
+ sp->userhl = 0;
+ }
+
+ /* Store the info about tab pages labels. */
+ if (tabtab != NULL) {
+ sp = tabtab;
+ for (l = 0; l < itemcnt; l++) {
+ if (item[l].type == TabPage) {
+ sp->start = item[l].start;
+ sp->userhl = item[l].minwid;
+ sp++;
+ }
+ }
+ sp->start = NULL;
+ sp->userhl = 0;
+ }
+
+ return width;
+}
+
+#if defined(FEAT_STL_OPT) || defined(FEAT_CMDL_INFO) \
+ || defined(FEAT_GUI_TABLINE) || defined(PROTO)
+/*
+ * Get relative cursor position in window into "buf[buflen]", in the form 99%,
+ * using "Top", "Bot" or "All" when appropriate.
+ */
+void get_rel_pos(wp, buf, buflen)
+win_T *wp;
+char_u *buf;
+int buflen;
+{
+ long above; /* number of lines above window */
+ long below; /* number of lines below window */
+
+ above = wp->w_topline - 1;
+ above += diff_check_fill(wp, wp->w_topline) - wp->w_topfill;
+ below = wp->w_buffer->b_ml.ml_line_count - wp->w_botline + 1;
+ if (below <= 0)
+ vim_strncpy(buf, (char_u *)(above == 0 ? _("All") : _("Bot")),
+ (size_t)(buflen - 1));
+ else if (above <= 0)
+ vim_strncpy(buf, (char_u *)_("Top"), (size_t)(buflen - 1));
+ else
+ vim_snprintf((char *)buf, (size_t)buflen, "%2d%%", above > 1000000L
+ ? (int)(above / ((above + below) / 100L))
+ : (int)(above * 100L / (above + below)));
+}
+#endif
+
+/*
+ * Append (file 2 of 8) to "buf[buflen]", if editing more than one file.
+ * Return TRUE if it was appended.
+ */
+static int append_arg_number(wp, buf, buflen, add_file)
+win_T *wp;
+char_u *buf;
+int buflen;
+int add_file; /* Add "file" before the arg number */
+{
+ char_u *p;
+
+ if (ARGCOUNT <= 1) /* nothing to do */
+ return FALSE;
+
+ p = buf + STRLEN(buf); /* go to the end of the buffer */
+ if (p - buf + 35 >= buflen) /* getting too long */
+ return FALSE;
+ *p++ = ' ';
+ *p++ = '(';
+ if (add_file) {
+ STRCPY(p, "file ");
+ p += 5;
+ }
+ vim_snprintf((char *)p, (size_t)(buflen - (p - buf)),
+ wp->w_arg_idx_invalid ? "(%d) of %d)"
+ : "%d of %d)", wp->w_arg_idx + 1, ARGCOUNT);
+ return TRUE;
+}
+
+/*
+ * If fname is not a full path, make it a full path.
+ * Returns pointer to allocated memory (NULL for failure).
+ */
+char_u * fix_fname(fname)
+char_u *fname;
+{
+ /*
+ * Force expanding the path always for Unix, because symbolic links may
+ * mess up the full path name, even though it starts with a '/'.
+ * Also expand when there is ".." in the file name, try to remove it,
+ * because "c:/src/../README" is equal to "c:/README".
+ * Similarly "c:/src//file" is equal to "c:/src/file".
+ * For MS-Windows also expand names like "longna~1" to "longname".
+ */
+#ifdef UNIX
+ return FullName_save(fname, TRUE);
+#else
+ if (!vim_isAbsName(fname)
+ || strstr((char *)fname, "..") != NULL
+ || strstr((char *)fname, "//") != NULL
+# ifdef BACKSLASH_IN_FILENAME
+ || strstr((char *)fname, "\\\\") != NULL
+# endif
+ )
+ return FullName_save(fname, FALSE);
+
+ fname = vim_strsave(fname);
+
+# ifdef USE_FNAME_CASE
+# ifdef USE_LONG_FNAME
+ if (USE_LONG_FNAME)
+# endif
+ {
+ if (fname != NULL)
+ fname_case(fname, 0); /* set correct case for file name */
+ }
+# endif
+
+ return fname;
+#endif
+}
+
+/*
+ * Make "ffname" a full file name, set "sfname" to "ffname" if not NULL.
+ * "ffname" becomes a pointer to allocated memory (or NULL).
+ */
+void fname_expand(buf, ffname, sfname)
+buf_T *buf UNUSED;
+char_u **ffname;
+char_u **sfname;
+{
+ if (*ffname == NULL) /* if no file name given, nothing to do */
+ return;
+ if (*sfname == NULL) /* if no short file name given, use ffname */
+ *sfname = *ffname;
+ *ffname = fix_fname(*ffname); /* expand to full path */
+
+#ifdef FEAT_SHORTCUT
+ 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 (rfname != NULL) {
+ vim_free(*ffname);
+ *ffname = rfname;
+ *sfname = rfname;
+ }
+ }
+#endif
+}
+
+/*
+ * Get the file name for an argument list entry.
+ */
+char_u * alist_name(aep)
+aentry_T *aep;
+{
+ buf_T *bp;
+
+ /* Use the name from the associated buffer if it exists. */
+ bp = buflist_findnr(aep->ae_fnum);
+ if (bp == NULL || bp->b_fname == NULL)
+ return aep->ae_fname;
+ return bp->b_fname;
+}
+
+/*
+ * do_arg_all(): Open up to 'count' windows, one for each argument.
+ */
+void do_arg_all(count, forceit, keep_tabs)
+int count;
+int forceit; /* hide buffers in current windows */
+int keep_tabs; /* keep current tabs, for ":tab drop file" */
+{
+ int i;
+ win_T *wp, *wpnext;
+ char_u *opened; /* Array of weight for which args are open:
+ * 0: not opened
+ * 1: opened in other tab
+ * 2: opened in curtab
+ * 3: opened in curtab and curwin
+ */
+ int opened_len; /* length of opened[] */
+ int use_firstwin = FALSE; /* use first window for arglist */
+ int split_ret = OK;
+ int p_ea_save;
+ alist_T *alist; /* argument list to be used */
+ buf_T *buf;
+ tabpage_T *tpnext;
+ int had_tab = cmdmod.tab;
+ win_T *old_curwin, *last_curwin;
+ tabpage_T *old_curtab, *last_curtab;
+ win_T *new_curwin = NULL;
+ tabpage_T *new_curtab = NULL;
+
+ if (ARGCOUNT <= 0) {
+ /* Don't give an error message. We don't want it when the ":all"
+ * command is in the .vimrc. */
+ return;
+ }
+ setpcmark();
+
+ opened_len = ARGCOUNT;
+ opened = alloc_clear((unsigned)opened_len);
+ if (opened == NULL)
+ return;
+
+ /* 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
+ * watch out for its size to be changed. */
+ alist = curwin->w_alist;
+ ++alist->al_refcount;
+
+ old_curwin = curwin;
+ old_curtab = curtab;
+
+
+ /*
+ * Try closing all windows that are not in the argument list.
+ * Also close windows that are not full width;
+ * When 'hidden' or "forceit" set the buffer becomes hidden.
+ * Windows that have a changed buffer and can't be hidden won't be closed.
+ * When the ":tab" modifier was used do this for all tab pages.
+ */
+ if (had_tab > 0)
+ goto_tabpage_tp(first_tabpage, TRUE, TRUE);
+ for (;; ) {
+ tpnext = curtab->tp_next;
+ for (wp = firstwin; wp != NULL; wp = wpnext) {
+ wpnext = wp->w_next;
+ buf = wp->w_buffer;
+ if (buf->b_ffname == NULL
+ || (!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 */
+ for (i = 0; i < opened_len; ++i) {
+ if (i < alist->al_ga.ga_len
+ && (AARGLIST(alist)[i].ae_fnum == buf->b_fnum
+ || fullpathcmp(alist_name(&AARGLIST(alist)[i]),
+ buf->b_ffname, TRUE) & FPC_SAME)) {
+ int weight = 1;
+
+ if (old_curtab == curtab) {
+ ++weight;
+ if (old_curwin == wp)
+ ++weight;
+ }
+
+ if (weight > (int)opened[i]) {
+ opened[i] = (char_u)weight;
+ if (i == 0) {
+ if (new_curwin != NULL)
+ new_curwin->w_arg_idx = opened_len;
+ new_curwin = wp;
+ new_curtab = curtab;
+ }
+ } else if (keep_tabs)
+ i = opened_len;
+
+ if (wp->w_alist != alist) {
+ /* Use the current argument list for all windows
+ * containing a file from it. */
+ alist_unlink(wp->w_alist);
+ wp->w_alist = alist;
+ ++wp->w_alist->al_refcount;
+ }
+ break;
+ }
+ }
+ }
+ wp->w_arg_idx = i;
+
+ if (i == opened_len && !keep_tabs) { /* close this window */
+ if (P_HID(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... */
+ 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... */
+ }
+ }
+ }
+ }
+
+ /* Without the ":tab" modifier only do the current tab page. */
+ if (had_tab == 0 || tpnext == NULL)
+ break;
+
+ /* check if autocommands removed the next tab page */
+ if (!valid_tabpage(tpnext))
+ tpnext = first_tabpage; /* start all over...*/
+ goto_tabpage_tp(tpnext, TRUE, TRUE);
+ }
+
+ /*
+ * Open a window for files in the argument list that don't have one.
+ * ARGCOUNT may change while doing this, because of autocommands.
+ */
+ if (count > opened_len || count <= 0)
+ count = opened_len;
+
+ /* Don't execute Win/Buf Enter/Leave autocommands here. */
+ ++autocmd_no_enter;
+ ++autocmd_no_leave;
+ 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;
+ if (opened[i] > 0) {
+ /* Move the already present window to below the current window */
+ if (curwin->w_arg_idx != i) {
+ for (wpnext = firstwin; wpnext != NULL; wpnext = wpnext->w_next) {
+ if (wpnext->w_arg_idx == i) {
+ if (keep_tabs) {
+ new_curwin = wpnext;
+ new_curtab = curtab;
+ } else
+ win_move_after(wpnext, curwin);
+ break;
+ }
+ }
+ }
+ } else if (split_ret == OK) {
+ if (!use_firstwin) { /* split current window */
+ p_ea_save = p_ea;
+ p_ea = TRUE; /* use space from all windows */
+ split_ret = win_split(0, WSP_ROOM | WSP_BELOW);
+ p_ea = p_ea_save;
+ if (split_ret == FAIL)
+ continue;
+ } else /* first window: do autocmd for leaving this buffer */
+ --autocmd_no_leave;
+
+ /*
+ * edit file "i"
+ */
+ curwin->w_arg_idx = i;
+ if (i == 0) {
+ 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;
+ }
+ ui_breakcheck();
+
+ /* When ":tab" was used open a new tab for a new window repeatedly. */
+ if (had_tab > 0 && tabpage_index(NULL) <= p_tpm)
+ cmdmod.tab = 9999;
+ }
+
+ /* Remove the "lock" on the argument list. */
+ alist_unlink(alist);
+
+ --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))
+ win_enter(last_curwin, FALSE);
+ }
+ /* to window with first arg */
+ if (valid_tabpage(new_curtab))
+ goto_tabpage_tp(new_curtab, TRUE, TRUE);
+ if (win_valid(new_curwin))
+ win_enter(new_curwin, FALSE);
+
+ --autocmd_no_leave;
+ vim_free(opened);
+}
+
+/*
+ * Open a window for a number of buffers.
+ */
+void ex_buffer_all(eap)
+exarg_T *eap;
+{
+ buf_T *buf;
+ win_T *wp, *wpnext;
+ int split_ret = OK;
+ int 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. */
+ int had_tab = cmdmod.tab;
+ tabpage_T *tpnext;
+
+ if (eap->addr_count == 0) /* make as many windows as possible */
+ count = 9999;
+ else
+ count = eap->line2; /* make as many windows as specified */
+ if (eap->cmdidx == CMD_unhide || eap->cmdidx == CMD_sunhide)
+ all = FALSE;
+ else
+ all = TRUE;
+
+ setpcmark();
+
+
+ /*
+ * Close superfluous windows (two windows for the same buffer).
+ * Also close windows that are not full-width.
+ */
+ if (had_tab > 0)
+ goto_tabpage_tp(first_tabpage, TRUE, TRUE);
+ for (;; ) {
+ tpnext = curtab->tp_next;
+ for (wp = firstwin; wp != NULL; wp = wpnext) {
+ wpnext = wp->w_next;
+ if ((wp->w_buffer->b_nwindows > 1
+ || ((cmdmod.split & WSP_VERT)
+ ? 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)
+ ) {
+ 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;
+ }
+
+ /* Without the ":tab" modifier only do the current tab page. */
+ if (had_tab == 0 || tpnext == NULL)
+ break;
+ goto_tabpage_tp(tpnext, TRUE, TRUE);
+ }
+
+ /*
+ * Go through the buffer list. When a buffer doesn't have a window yet,
+ * open one. Otherwise move the window to the right position.
+ * Watch out for autocommands that delete buffers or windows!
+ */
+ /* Don't execute Win/Buf Enter/Leave autocommands here. */
+ ++autocmd_no_enter;
+ win_enter(lastwin, FALSE);
+ ++autocmd_no_leave;
+ for (buf = firstbuf; buf != NULL && open_wins < count; buf = buf->b_next) {
+ /* Check if this buffer needs a window */
+ if ((!all && buf->b_ml.ml_mfp == NULL) || !buf->b_p_bl)
+ continue;
+
+ if (had_tab != 0) {
+ /* With the ":tab" modifier don't move the window. */
+ if (buf->b_nwindows > 0)
+ wp = lastwin; /* buffer has a window, skip it */
+ else
+ wp = NULL;
+ } else {
+ /* Check if this buffer already has a window */
+ for (wp = firstwin; wp != NULL; wp = wp->w_next)
+ if (wp->w_buffer == buf)
+ break;
+ /* If the buffer already has a window, move it */
+ if (wp != NULL)
+ win_move_after(wp, curwin);
+ }
+
+ if (wp == NULL && split_ret == OK) {
+ /* 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);
+ ++open_wins;
+ p_ea = p_ea_save;
+ if (split_ret == FAIL)
+ continue;
+
+ /* Open the buffer in this window. */
+#if defined(HAS_SWAP_EXISTS_ACTION)
+ swap_exists_action = SEA_DIALOG;
+#endif
+ set_curbuf(buf, DOBUF_GOTO);
+ if (!buf_valid(buf)) { /* autocommands deleted the buffer!!! */
+#if defined(HAS_SWAP_EXISTS_ACTION)
+ swap_exists_action = SEA_NONE;
+# endif
+ break;
+ }
+#if defined(HAS_SWAP_EXISTS_ACTION)
+ if (swap_exists_action == SEA_QUIT) {
+ cleanup_T cs;
+
+ /* Reset the error/interrupt/exception state here so that
+ * 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;
+ swap_exists_action = SEA_NONE;
+ swap_exists_did_quit = TRUE;
+
+ /* Restore the error/interrupt/exception state if not
+ * discarded by a new aborting error, interrupt, or uncaught
+ * exception. */
+ leave_cleanup(&cs);
+ } else
+ handle_swap_exists(NULL);
+#endif
+ }
+
+ ui_breakcheck();
+ if (got_int) {
+ (void)vgetc(); /* only break the file loading, not the rest */
+ break;
+ }
+ /* Autocommands deleted the buffer or aborted script processing!!! */
+ if (aborting())
+ break;
+ /* When ":tab" was used open a new tab for a new window repeatedly. */
+ if (had_tab > 0 && tabpage_index(NULL) <= p_tpm)
+ cmdmod.tab = 9999;
+ }
+ --autocmd_no_enter;
+ win_enter(firstwin, FALSE); /* back to first window */
+ --autocmd_no_leave;
+
+ /*
+ * 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);
+ 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;
+ wp = lastwin;
+ } else {
+ wp = wp->w_prev;
+ if (wp == NULL)
+ break;
+ }
+ }
+}
+
+
+static int chk_modeline __ARGS((linenr_T, int));
+
+/*
+ * do_modelines() - process mode lines for the current file
+ *
+ * "flags" can be:
+ * OPT_WINONLY only set options local to window
+ * OPT_NOWIN don't set options local to window
+ *
+ * Returns immediately if the "ml" option isn't set.
+ */
+void do_modelines(flags)
+int flags;
+{
+ linenr_T lnum;
+ int nmlines;
+ static int entered = 0;
+
+ if (!curbuf->b_p_ml || (nmlines = (int)p_mls) == 0)
+ return;
+
+ /* Disallow recursive entry here. Can happen when executing a modeline
+ * triggers an autocommand, which reloads modelines with a ":do". */
+ if (entered)
+ return;
+
+ ++entered;
+ for (lnum = 1; lnum <= curbuf->b_ml.ml_line_count && lnum <= nmlines;
+ ++lnum)
+ if (chk_modeline(lnum, flags) == FAIL)
+ nmlines = 0;
+
+ for (lnum = curbuf->b_ml.ml_line_count; lnum > 0 && lnum > nmlines
+ && lnum > curbuf->b_ml.ml_line_count - nmlines; --lnum)
+ if (chk_modeline(lnum, flags) == FAIL)
+ nmlines = 0;
+ --entered;
+}
+
+#include "version.h" /* for version number */
+
+/*
+ * chk_modeline() - check a single line for a mode string
+ * Return FAIL if an error encountered.
+ */
+static int chk_modeline(lnum, flags)
+linenr_T lnum;
+int flags; /* Same as for do_modelines(). */
+{
+ char_u *s;
+ char_u *e;
+ char_u *linecopy; /* local copy of any modeline found */
+ int prev;
+ int vers;
+ int end;
+ int retval = OK;
+ char_u *save_sourcing_name;
+ linenr_T save_sourcing_lnum;
+ scid_T save_SID;
+
+ prev = -1;
+ for (s = ml_get(lnum); *s != NUL; ++s) {
+ if (prev == -1 || vim_isspace(prev)) {
+ if ((prev != -1 && STRNCMP(s, "ex:", (size_t)3) == 0)
+ || STRNCMP(s, "vi:", (size_t)3) == 0)
+ break;
+ /* Accept both "vim" and "Vim". */
+ if ((s[0] == 'v' || s[0] == 'V') && s[1] == 'i' && s[2] == 'm') {
+ if (s[3] == '<' || s[3] == '=' || s[3] == '>')
+ e = s + 4;
+ else
+ e = s + 3;
+ vers = getdigits(&e);
+ if (*e == ':'
+ && (s[0] != 'V'
+ || STRNCMP(skipwhite(e + 1), "set", 3) == 0)
+ && (s[3] == ':'
+ || (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] == '=')))
+ break;
+ }
+ }
+ prev = *s;
+ }
+
+ if (*s) {
+ do /* skip over "ex:", "vi:" or "vim:" */
+ ++s;
+ while (s[-1] != ':');
+
+ s = linecopy = vim_strsave(s); /* copy the line, it will change */
+ if (linecopy == NULL)
+ return FAIL;
+
+ save_sourcing_lnum = sourcing_lnum;
+ save_sourcing_name = sourcing_name;
+ sourcing_lnum = lnum; /* prepare for emsg() */
+ sourcing_name = (char_u *)"modelines";
+
+ end = FALSE;
+ while (end == FALSE) {
+ s = skipwhite(s);
+ if (*s == NUL)
+ break;
+
+ /*
+ * Find end of set command: ':' or end of line.
+ * Skip over "\:", replacing it with ":".
+ */
+ for (e = s; *e != ':' && *e != NUL; ++e)
+ if (e[0] == '\\' && e[1] == ':')
+ STRMOVE(e, e + 1);
+ if (*e == NUL)
+ end = TRUE;
+
+ /*
+ * If there is a "set" command, require a terminating ':' and
+ * ignore the stuff after the ':'.
+ * "vi:set opt opt opt: foo" -- foo not interpreted
+ * "vi:opt opt opt: foo" -- foo interpreted
+ * Accept "se" for compatibility with Elvis.
+ */
+ if (STRNCMP(s, "set ", (size_t)4) == 0
+ || STRNCMP(s, "se ", (size_t)3) == 0) {
+ if (*e != ':') /* no terminating ':'? */
+ break;
+ end = TRUE;
+ s = vim_strchr(s, ' ') + 1;
+ }
+ *e = NUL; /* truncate the set command */
+
+ if (*s != NUL) { /* skip over an empty "::" */
+ save_SID = current_SID;
+ current_SID = SID_MODELINE;
+ retval = do_set(s, OPT_MODELINE | OPT_LOCAL | flags);
+ current_SID = save_SID;
+ if (retval == FAIL) /* stop if error found */
+ break;
+ }
+ s = e + 1; /* advance to next part */
+ }
+
+ sourcing_lnum = save_sourcing_lnum;
+ sourcing_name = save_sourcing_name;
+
+ vim_free(linecopy);
+ }
+ return retval;
+}
+
+int read_viminfo_bufferlist(virp, writing)
+vir_T *virp;
+int writing;
+{
+ char_u *tab;
+ linenr_T lnum;
+ colnr_T col;
+ buf_T *buf;
+ char_u *sfname;
+ char_u *xline;
+
+ /* Handle long line and escaped characters. */
+ xline = viminfo_readstring(virp, 1, FALSE);
+
+ /* don't read in if there are files on the command-line or if writing: */
+ if (xline != NULL && !writing && ARGCOUNT == 0
+ && find_viminfo_parameter('%') != NULL) {
+ /* Format is: <fname> Tab <lnum> Tab <col>.
+ * Watch out for a Tab in the file name, work from the end. */
+ lnum = 0;
+ col = 0;
+ tab = vim_strrchr(xline, '\t');
+ if (tab != NULL) {
+ *tab++ = '\0';
+ col = (colnr_T)atoi((char *)tab);
+ tab = vim_strrchr(xline, '\t');
+ if (tab != NULL) {
+ *tab++ = '\0';
+ lnum = atol((char *)tab);
+ }
+ }
+
+ /* Expand "~/" in the file name at "line + 1" to a full path.
+ * Then try shortening it by comparing with the current directory */
+ expand_env(xline, NameBuff, MAXPATHL);
+ sfname = shorten_fname1(NameBuff);
+
+ buf = buflist_new(NameBuff, sfname, (linenr_T)0, BLN_LISTED);
+ if (buf != NULL) { /* just in case... */
+ buf->b_last_cursor.lnum = lnum;
+ buf->b_last_cursor.col = col;
+ buflist_setfpos(buf, curwin, lnum, col, FALSE);
+ }
+ }
+ vim_free(xline);
+
+ return viminfo_readline(virp);
+}
+
+void write_viminfo_bufferlist(fp)
+FILE *fp;
+{
+ buf_T *buf;
+ win_T *win;
+ tabpage_T *tp;
+ char_u *line;
+ int max_buffers;
+
+ if (find_viminfo_parameter('%') == NULL)
+ return;
+
+ /* Without a number -1 is returned: do all buffers. */
+ max_buffers = get_viminfo_parameter('%');
+
+ /* Allocate room for the file name, lnum and col. */
+#define LINE_BUF_LEN (MAXPATHL + 40)
+ line = alloc(LINE_BUF_LEN);
+ if (line == NULL)
+ return;
+
+ FOR_ALL_TAB_WINDOWS(tp, win)
+ set_last_cursor(win);
+
+ fputs(_("\n# Buffer list:\n"), fp);
+ for (buf = firstbuf; buf != NULL; buf = buf->b_next) {
+ if (buf->b_fname == NULL
+ || !buf->b_p_bl
+ || bt_quickfix(buf)
+ || removable(buf->b_ffname))
+ continue;
+
+ if (max_buffers-- == 0)
+ break;
+ putc('%', fp);
+ home_replace(NULL, buf->b_ffname, line, MAXPATHL, TRUE);
+ vim_snprintf_add((char *)line, LINE_BUF_LEN, "\t%ld\t%d",
+ (long)buf->b_last_cursor.lnum,
+ buf->b_last_cursor.col);
+ viminfo_writestring(fp, line);
+ }
+ vim_free(line);
+}
+
+
+/*
+ * Return special buffer name.
+ * Returns NULL when the buffer has a normal file name.
+ */
+char_u * buf_spname(buf)
+buf_T *buf;
+{
+ if (bt_quickfix(buf)) {
+ win_T *win;
+ tabpage_T *tp;
+
+ /*
+ * For location list window, w_llist_ref points to the location list.
+ * For quickfix window, w_llist_ref is NULL.
+ */
+ if (find_win_for_buf(buf, &win, &tp) == OK && win->w_llist_ref != NULL)
+ return (char_u *)_(msg_loclist);
+ else
+ return (char_u *)_(msg_qflist);
+ }
+ /* There is no _file_ when 'buftype' is "nofile", b_sfname
+ * contains the name as specified by the user */
+ if (bt_nofile(buf)) {
+ if (buf->b_sfname != NULL)
+ return buf->b_sfname;
+ return (char_u *)_("[Scratch]");
+ }
+ if (buf->b_fname == NULL)
+ return (char_u *)_("[No Name]");
+ return NULL;
+}
+
+#if (defined(FEAT_QUICKFIX) && defined(FEAT_WINDOWS)) \
+ || defined(FEAT_PYTHON) || defined(FEAT_PYTHON3) \
+ || defined(PROTO)
+/*
+ * Find a window for buffer "buf".
+ * If found OK is returned and "wp" and "tp" are set to the window and tabpage.
+ * If not found FAIL is returned.
+ */
+int find_win_for_buf(buf, wp, tp)
+buf_T *buf;
+win_T **wp;
+tabpage_T **tp;
+{
+ FOR_ALL_TAB_WINDOWS(*tp, *wp)
+ if ((*wp)->w_buffer == buf)
+ goto win_found;
+ return FAIL;
+win_found:
+ return OK;
+}
+#endif
+
+
+/*
+ * Set 'buflisted' for curbuf to "on" and trigger autocommands if it changed.
+ */
+void set_buflisted(on)
+int on;
+{
+ if (on != curbuf->b_p_bl) {
+ curbuf->b_p_bl = on;
+ if (on)
+ apply_autocmds(EVENT_BUFADD, NULL, NULL, FALSE, curbuf);
+ else
+ apply_autocmds(EVENT_BUFDELETE, NULL, NULL, FALSE, curbuf);
+ }
+}
+
+/*
+ * Read the file for "buf" again and check if the contents changed.
+ * Return TRUE if it changed or this could not be checked.
+ */
+int buf_contents_changed(buf)
+buf_T *buf;
+{
+ buf_T *newbuf;
+ int differ = TRUE;
+ linenr_T lnum;
+ aco_save_T aco;
+ exarg_T ea;
+
+ /* Allocate a buffer without putting it in the buffer list. */
+ newbuf = buflist_new(NULL, NULL, (linenr_T)1, BLN_DUMMY);
+ if (newbuf == NULL)
+ return TRUE;
+
+ /* Force the 'fileencoding' and 'fileformat' to be equal. */
+ if (prep_exarg(&ea, buf) == FAIL) {
+ wipe_buffer(newbuf, FALSE);
+ return TRUE;
+ }
+
+ /* set curwin/curbuf to buf and save a few things */
+ aucmd_prepbuf(&aco, newbuf);
+
+ if (ml_open(curbuf) == OK
+ && readfile(buf->b_ffname, buf->b_fname,
+ (linenr_T)0, (linenr_T)0, (linenr_T)MAXLNUM,
+ &ea, READ_NEW | READ_DUMMY) == OK) {
+ /* compare the two files line by line */
+ if (buf->b_ml.ml_line_count == curbuf->b_ml.ml_line_count) {
+ differ = FALSE;
+ for (lnum = 1; lnum <= curbuf->b_ml.ml_line_count; ++lnum)
+ if (STRCMP(ml_get_buf(buf, lnum, FALSE), ml_get(lnum)) != 0) {
+ differ = TRUE;
+ break;
+ }
+ }
+ }
+ vim_free(ea.cmd);
+
+ /* restore curwin/curbuf and a few other things */
+ aucmd_restbuf(&aco);
+
+ if (curbuf != newbuf) /* safety check */
+ wipe_buffer(newbuf, FALSE);
+
+ return differ;
+}
+
+/*
+ * Wipe out a buffer and decrement the last buffer number if it was used for
+ * this buffer. Call this to wipe out a temp buffer that does not contain any
+ * marks.
+ */
+void wipe_buffer(buf, aucmd)
+buf_T *buf;
+int aucmd UNUSED; /* When TRUE trigger autocommands. */
+{
+ if (buf->b_fnum == top_file_num - 1)
+ --top_file_num;
+
+ if (!aucmd) /* Don't trigger BufDelete autocommands here. */
+ block_autocmds();
+ close_buffer(NULL, buf, DOBUF_WIPE, FALSE);
+ if (!aucmd)
+ unblock_autocmds();
+}
diff --git a/src/charset.c b/src/charset.c
new file mode 100644
index 0000000000..1eee20f66c
--- /dev/null
+++ b/src/charset.c
@@ -0,0 +1,1653 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * 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.
+ */
+
+#include "vim.h"
+
+static int win_chartabsize __ARGS((win_T *wp, char_u *p, colnr_T col));
+
+# if defined(HAVE_WCHAR_H)
+# include <wchar.h> /* for towupper() and towlower() */
+# endif
+static int win_nolbr_chartabsize __ARGS((win_T *wp, char_u *s, colnr_T col,
+ int *headp));
+
+static unsigned nr2hex __ARGS((unsigned c));
+
+static int chartab_initialized = FALSE;
+
+/* b_chartab[] is an array of 32 bytes, each bit representing one of the
+ * characters 0-255. */
+#define SET_CHARTAB(buf, c) (buf)->b_chartab[(unsigned)(c) >> \
+ 3] |= (1 << ((c) & 0x7))
+#define RESET_CHARTAB(buf, c) (buf)->b_chartab[(unsigned)(c) >> \
+ 3] &= ~(1 << ((c) & 0x7))
+#define GET_CHARTAB(buf, \
+ c) ((buf)->b_chartab[(unsigned)(c) >> 3] & (1 << ((c) & 0x7)))
+
+/*
+ * Fill 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 contents of 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
+ * translate the character before displaying it). Note that only DBCS
+ * characters can have 2 display cells and still be printable.
+ * - CT_FNAME_CHAR bit is set when the character can be in a file name.
+ * - CT_ID_CHAR bit is set when the character can be in an identifier.
+ *
+ * Return FAIL if 'iskeyword', 'isident', 'isfname' or 'isprint' option has an
+ * error, OK otherwise.
+ */
+int init_chartab() {
+ return buf_init_chartab(curbuf, TRUE);
+}
+
+int buf_init_chartab(buf, global)
+buf_T *buf;
+int global; /* FALSE: only set buf->b_chartab[] */
+{
+ int c;
+ int c2;
+ char_u *p;
+ int i;
+ int tilde;
+ int do_isalpha;
+
+ if (global) {
+ /*
+ * Set the default size for printable characters:
+ * From <Space> to '~' is 1 (printable), others are 2 (not printable).
+ * This also inits all 'isident' and 'isfname' flags to FALSE.
+ *
+ * EBCDIC: all chars below ' ' are not printable, all others are
+ * printable.
+ */
+ c = 0;
+ while (c < ' ')
+ chartab[c++] = (dy_flags & DY_UHEX) ? 4 : 2;
+ while (c <= '~')
+ chartab[c++] = 1 + CT_PRINT_CHAR;
+ if (p_altkeymap) {
+ while (c < YE)
+ chartab[c++] = 1 + CT_PRINT_CHAR;
+ }
+ while (c < 256) {
+ /* UTF-8: bytes 0xa0 - 0xff are printable (latin1) */
+ if (enc_utf8 && c >= 0xa0)
+ chartab[c++] = CT_PRINT_CHAR + 1;
+ /* euc-jp characters starting with 0x8e are single width */
+ else if (enc_dbcs == DBCS_JPNU && c == 0x8e)
+ chartab[c++] = CT_PRINT_CHAR + 1;
+ /* other double-byte chars can be printable AND double-width */
+ else if (enc_dbcs != 0 && MB_BYTE2LEN(c) == 2)
+ chartab[c++] = CT_PRINT_CHAR + 2;
+ else
+ /* the rest is unprintable by default */
+ 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;
+ }
+
+ /*
+ * Init word char flags all to FALSE
+ */
+ vim_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, '-');
+
+ /* 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) {
+ if (i == 0)
+ p = p_isi; /* first round: 'isident' */
+ else if (i == 1)
+ p = p_isp; /* second round: 'isprint' */
+ else if (i == 2)
+ p = p_isf; /* third round: 'isfname' */
+ else /* i == 3 */
+ p = buf->b_p_isk; /* fourth round: 'iskeyword' */
+
+ while (*p) {
+ tilde = FALSE;
+ do_isalpha = FALSE;
+ if (*p == '^' && p[1] != NUL) {
+ tilde = TRUE;
+ ++p;
+ }
+ if (VIM_ISDIGIT(*p))
+ c = getdigits(&p);
+ else if (has_mbyte)
+ c = mb_ptr2char_adv(&p);
+ else
+ c = *p++;
+ c2 = -1;
+ if (*p == '-' && p[1] != NUL) {
+ ++p;
+ if (VIM_ISDIGIT(*p))
+ c2 = getdigits(&p);
+ else if (has_mbyte)
+ c2 = mb_ptr2char_adv(&p);
+ else
+ c2 = *p++;
+ }
+ if (c <= 0 || c >= 256 || (c2 < c && c2 != -1) || c2 >= 256
+ || !(*p == NUL || *p == ','))
+ return FAIL;
+
+ if (c2 == -1) { /* not a range */
+ /*
+ * A single '@' (not "@-@"):
+ * Decide on letters being ID/printable/keyword chars with
+ * standard function isalpha(). This takes care of locale for
+ * single-byte characters).
+ */
+ if (c == '@') {
+ do_isalpha = TRUE;
+ c = 1;
+ c2 = 255;
+ } else
+ c2 = c;
+ }
+ while (c <= c2) {
+ /* Use the MB_ functions here, because isalpha() doesn't
+ * work properly when 'encoding' is "latin1" and the locale is
+ * "C". */
+ if (!do_isalpha || 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] &= ~CT_ID_CHAR;
+ else
+ chartab[c] |= CT_ID_CHAR;
+ } else if (i == 1) { /* (re)set printable */
+ if ((c < ' '
+ || c > '~'
+ || (p_altkeymap
+ && (F_isalpha(c) || F_isdigit(c)))
+ )
+ /* For double-byte we keep the cell width, so
+ * that we can detect it from the first byte. */
+ && !(enc_dbcs && MB_BYTE2LEN(c) == 2)
+ ) {
+ if (tilde) {
+ chartab[c] = (chartab[c] & ~CT_CELL_MASK)
+ + ((dy_flags & DY_UHEX) ? 4 : 2);
+ chartab[c] &= ~CT_PRINT_CHAR;
+ } else {
+ chartab[c] = (chartab[c] & ~CT_CELL_MASK) + 1;
+ chartab[c] |= CT_PRINT_CHAR;
+ }
+ }
+ } else if (i == 2) { /* (re)set fname flag */
+ if (tilde)
+ chartab[c] &= ~CT_FNAME_CHAR;
+ else
+ chartab[c] |= CT_FNAME_CHAR;
+ } else { /* i == 3 */ /* (re)set keyword flag */
+ if (tilde)
+ RESET_CHARTAB(buf, c);
+ else
+ SET_CHARTAB(buf, c);
+ }
+ }
+ ++c;
+ }
+
+ c = *p;
+ p = skip_to_option_part(p);
+ if (c == ',' && *p == NUL)
+ /* Trailing comma is not allowed. */
+ return FAIL;
+ }
+ }
+ chartab_initialized = TRUE;
+ return OK;
+}
+
+/*
+ * Translate any special characters in buf[bufsize] in-place.
+ * The result is a string with only printable characters, but if there is not
+ * enough room, not all characters will be translated.
+ */
+void trans_characters(buf, bufsize)
+char_u *buf;
+int bufsize;
+{
+ int len; /* length of string needing translation */
+ int room; /* room in buffer after string */
+ char_u *trs; /* translated character */
+ int trs_len; /* length of trs[] */
+
+ len = (int)STRLEN(buf);
+ room = bufsize - len;
+ while (*buf != 0) {
+ /* Assume a multi-byte character doesn't need translation. */
+ if (has_mbyte && (trs_len = (*mb_ptr2len)(buf)) > 1)
+ len -= trs_len;
+ else {
+ trs = transchar_byte(*buf);
+ trs_len = (int)STRLEN(trs);
+ if (trs_len > 1) {
+ room -= trs_len - 1;
+ if (room <= 0)
+ return;
+ mch_memmove(buf + trs_len, buf + 1, (size_t)len);
+ }
+ mch_memmove(buf, trs, (size_t)trs_len);
+ --len;
+ }
+ buf += trs_len;
+ }
+}
+
+#if defined(FEAT_EVAL) || defined(FEAT_TITLE) || defined(FEAT_INS_EXPAND) \
+ || defined(PROTO)
+/*
+ * Translate a string into allocated memory, replacing special chars with
+ * printable chars. Returns NULL when out of memory.
+ */
+char_u * transstr(s)
+char_u *s;
+{
+ char_u *res;
+ char_u *p;
+ int l, len, c;
+ char_u hexbuf[11];
+
+ if (has_mbyte) {
+ /* Compute the length of the result, taking account of unprintable
+ * multi-byte characters. */
+ len = 0;
+ p = s;
+ while (*p != NUL) {
+ if ((l = (*mb_ptr2len)(p)) > 1) {
+ c = (*mb_ptr2char)(p);
+ p += l;
+ if (vim_isprintc(c))
+ len += l;
+ else {
+ transchar_hex(hexbuf, c);
+ len += (int)STRLEN(hexbuf);
+ }
+ } else {
+ l = byte2cells(*p++);
+ if (l > 0)
+ len += l;
+ else
+ len += 4; /* illegal byte sequence */
+ }
+ }
+ res = alloc((unsigned)(len + 1));
+ } else
+ res = alloc((unsigned)(vim_strsize(s) + 1));
+ if (res != NULL) {
+ *res = NUL;
+ p = s;
+ while (*p != NUL) {
+ if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1) {
+ c = (*mb_ptr2char)(p);
+ if (vim_isprintc(c))
+ STRNCAT(res, p, l); /* append printable multi-byte char */
+ else
+ transchar_hex(res + STRLEN(res), c);
+ p += l;
+ } else
+ STRCAT(res, transchar_byte(*p++));
+ }
+ }
+ return res;
+}
+#endif
+
+/*
+ * Convert the string "str[orglen]" to do ignore-case comparing. Uses the
+ * current locale.
+ * When "buf" is NULL returns an allocated string (NULL for out-of-memory).
+ * Otherwise puts the result in "buf[buflen]".
+ */
+char_u * str_foldcase(str, orglen, buf, buflen)
+char_u *str;
+int orglen;
+char_u *buf;
+int buflen;
+{
+ garray_T ga;
+ int i;
+ int len = orglen;
+
+#define GA_CHAR(i) ((char_u *)ga.ga_data)[i]
+#define GA_PTR(i) ((char_u *)ga.ga_data + i)
+#define STR_CHAR(i) (buf == NULL ? GA_CHAR(i) : buf[i])
+#define STR_PTR(i) (buf == NULL ? GA_PTR(i) : buf + i)
+
+ /* Copy "str" into "buf" or allocated memory, unmodified. */
+ if (buf == NULL) {
+ ga_init2(&ga, 1, 10);
+ if (ga_grow(&ga, len + 1) == FAIL)
+ return NULL;
+ mch_memmove(ga.ga_data, str, (size_t)len);
+ ga.ga_len = len;
+ } else {
+ if (len >= buflen) /* Ugly! */
+ len = buflen - 1;
+ mch_memmove(buf, str, (size_t)len);
+ }
+ if (buf == NULL)
+ GA_CHAR(len) = NUL;
+ else
+ buf[len] = NUL;
+
+ /* 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) == FAIL
+ : 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;
+ }
+ }
+ }
+ (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) = TOLOWER_LOC(GA_CHAR(i));
+ else
+ buf[i] = TOLOWER_LOC(buf[i]);
+ ++i;
+ }
+ }
+
+ if (buf == NULL)
+ return (char_u *)ga.ga_data;
+ return buf;
+}
+
+/*
+ * Catch 22: 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[].
+ * 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];
+
+char_u * transchar(c)
+int c;
+{
+ int i;
+
+ i = 0;
+ if (IS_SPECIAL(c)) { /* special key code, display as ~@ char */
+ transchar_buf[0] = '~';
+ transchar_buf[1] = '@';
+ i = 2;
+ c = K_SECOND(c);
+ }
+
+ if ((!chartab_initialized && (
+ (c >= ' ' && c <= '~')
+ || F_ischar(c)
+ )) || (c < 256 && vim_isprintc_strict(c))) {
+ /* printable character */
+ transchar_buf[i] = c;
+ transchar_buf[i + 1] = NUL;
+ } else
+ transchar_nonprint(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.
+ */
+char_u * transchar_byte(c)
+int c;
+{
+ if (enc_utf8 && 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.
+ */
+void transchar_nonprint(buf, c)
+char_u *buf;
+int c;
+{
+ if (c == NL)
+ c = NUL; /* we use newline in place of a NUL */
+ else if (c == CAR && get_fileformat(curbuf) == EOL_MAC)
+ c = NL; /* we use CR in place of NL in this case */
+
+ if (dy_flags & DY_UHEX) /* 'display' has "uhex" */
+ transchar_hex(buf, c);
+
+ else if (c <= 0x7f) { /* 0x00 - 0x1f and 0x7f */
+ buf[0] = '^';
+ buf[1] = c ^ 0x40; /* DEL displayed as ^? */
+
+ 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] = c - 0x80;
+ buf[2] = NUL;
+ } else { /* 0x80 - 0x9f and 0xff */
+ /*
+ * TODO: EBCDIC I don't know what to do with this chars, so I display
+ * them as '~?' for now
+ */
+ buf[0] = '~';
+ buf[1] = (c - 0x80) ^ 0x40; /* 0xff displayed as ~? */
+ buf[2] = NUL;
+ }
+}
+
+void transchar_hex(buf, c)
+char_u *buf;
+int c;
+{
+ int i = 0;
+
+ buf[0] = '<';
+ if (c > 255) {
+ buf[++i] = nr2hex((unsigned)c >> 12);
+ buf[++i] = nr2hex((unsigned)c >> 8);
+ }
+ buf[++i] = nr2hex((unsigned)c >> 4);
+ buf[++i] = nr2hex((unsigned)c);
+ buf[++i] = '>';
+ buf[++i] = NUL;
+}
+
+/*
+ * 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.
+ */
+static unsigned nr2hex(c)
+unsigned c;
+{
+ if ((c & 0xf) <= 9)
+ return (c & 0xf) + '0';
+ return (c & 0xf) - 10 + 'a';
+}
+
+/*
+ * Return number of display cells occupied by byte "b".
+ * 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.
+ */
+int byte2cells(b)
+int b;
+{
+ if (enc_utf8 && b >= 0x80)
+ return 0;
+ return chartab[b] & CT_CELL_MASK;
+}
+
+/*
+ * Return number of display cells occupied by character "c".
+ * "c" can be a special key (negative number) in which case 3 or 4 is returned.
+ * A TAB is counted as two cells: "^I" or four: "<09>".
+ */
+int char2cells(c)
+int c;
+{
+ if (IS_SPECIAL(c))
+ return char2cells(K_SECOND(c)) + 2;
+ 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 chartab[c & 0xff] & CT_CELL_MASK;
+}
+
+/*
+ * Return number of display cells occupied by character at "*p".
+ * A TAB is counted as two cells: "^I" or four: "<09>".
+ */
+int ptr2cells(p)
+char_u *p;
+{
+ /* For UTF-8 we need to look at more bytes if the first byte is >= 0x80. */
+ if (enc_utf8 && *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 the number of character cells string "s" will take on the screen,
+ * counting TABs as two characters: "^I".
+ */
+int vim_strsize(s)
+char_u *s;
+{
+ return vim_strnsize(s, (int)MAXCOL);
+}
+
+/*
+ * Return the number of character cells string "s[len]" will take on the
+ * screen, counting TABs as two characters: "^I".
+ */
+int vim_strnsize(s, len)
+char_u *s;
+int len;
+{
+ 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++);
+ }
+ return size;
+}
+
+/*
+ * Return the number of characters 'c' will take on the screen, taking
+ * into account the size of a tab.
+ * Use a define to make it fast, this is used very often!!!
+ * Also see getvcol() below.
+ */
+
+#define RET_WIN_BUF_CHARTABSIZE(wp, buf, p, col) \
+ if (*(p) == TAB && (!(wp)->w_p_list || lcs_tab1)) \
+ { \
+ int ts; \
+ ts = (buf)->b_p_ts; \
+ return (int)(ts - (col % ts)); \
+ } \
+ else \
+ return ptr2cells(p);
+
+#if defined(FEAT_VREPLACE) || defined(FEAT_EX_EXTRA) || defined(FEAT_GUI) \
+ || defined(FEAT_VIRTUALEDIT) || defined(PROTO)
+int chartabsize(p, col)
+char_u *p;
+colnr_T col;
+{
+ RET_WIN_BUF_CHARTABSIZE(curwin, curbuf, p, col)
+}
+#endif
+
+static int win_chartabsize(wp, p, col)
+win_T *wp;
+char_u *p;
+colnr_T col;
+{
+ RET_WIN_BUF_CHARTABSIZE(wp, wp->w_buffer, p, col)
+}
+
+/*
+ * Return the number of characters the string 's' will take on the screen,
+ * taking into account the size of a tab.
+ */
+int linetabsize(s)
+char_u *s;
+{
+ return linetabsize_col(0, s);
+}
+
+/*
+ * Like linetabsize(), but starting at column "startcol".
+ */
+int linetabsize_col(startcol, s)
+int startcol;
+char_u *s;
+{
+ colnr_T col = startcol;
+
+ while (*s != NUL)
+ col += lbr_chartabsize_adv(&s, col);
+ return (int)col;
+}
+
+/*
+ * Like linetabsize(), but for a given window instead of the current one.
+ */
+int win_linetabsize(wp, p, len)
+win_T *wp;
+char_u *p;
+colnr_T len;
+{
+ colnr_T col = 0;
+ char_u *s;
+
+ for (s = p; *s != NUL && (len == MAXCOL || s < p + len); mb_ptr_adv(s))
+ col += win_lbr_chartabsize(wp, s, col, NULL);
+ return (int)col;
+}
+
+/*
+ * Return TRUE if 'c' is a normal identifier character:
+ * Letters and characters from the 'isident' option.
+ */
+int vim_isIDc(c)
+int c;
+{
+ return c > 0 && c < 0x100 && (chartab[c] & CT_ID_CHAR);
+}
+
+/*
+ * return TRUE if 'c' is a keyword character: Letters and characters from
+ * 'iskeyword' option for current buffer.
+ * For multi-byte characters mb_get_class() is used (builtin rules).
+ */
+int vim_iswordc(c)
+int c;
+{
+ return vim_iswordc_buf(c, curbuf);
+}
+
+int vim_iswordc_buf(c, buf)
+int c;
+buf_T *buf;
+{
+ 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;
+}
+
+/*
+ * Just like vim_iswordc() but uses a pointer to the (multi-byte) character.
+ */
+int vim_iswordp(p)
+char_u *p;
+{
+ if (has_mbyte && MB_BYTE2LEN(*p) > 1)
+ return mb_get_class(p) >= 2;
+ return GET_CHARTAB(curbuf, *p) != 0;
+}
+
+int vim_iswordp_buf(p, buf)
+char_u *p;
+buf_T *buf;
+{
+ if (has_mbyte && MB_BYTE2LEN(*p) > 1)
+ return mb_get_class(p) >= 2;
+ return GET_CHARTAB(buf, *p) != 0;
+}
+
+/*
+ * return TRUE if 'c' is a valid file-name character
+ * Assume characters above 0x100 are valid (multi-byte).
+ */
+int vim_isfilec(c)
+int c;
+{
+ return c >= 0x100 || (c > 0 && (chartab[c] & CT_FNAME_CHAR));
+}
+
+/*
+ * return TRUE if 'c' is a valid file-name character or a wildcard character
+ * Assume characters above 0x100 are valid (multi-byte).
+ * Explicitly interpret ']' as a wildcard character as mch_has_wildcard("]")
+ * returns false.
+ */
+int vim_isfilec_or_wc(c)
+int c;
+{
+ char_u buf[2];
+
+ buf[0] = (char_u)c;
+ buf[1] = NUL;
+ return vim_isfilec(c) || c == ']' || mch_has_wildcard(buf);
+}
+
+/*
+ * return TRUE if 'c' is a printable character
+ * Assume characters above 0x100 are printable (multi-byte), except for
+ * Unicode.
+ */
+int vim_isprintc(c)
+int c;
+{
+ if (enc_utf8 && c >= 0x100)
+ return utf_printable(c);
+ return c >= 0x100 || (c > 0 && (chartab[c] & CT_PRINT_CHAR));
+}
+
+/*
+ * Strict version of vim_isprintc(c), don't return TRUE if "c" is the head
+ * byte of a double-byte character.
+ */
+int vim_isprintc_strict(c)
+int c;
+{
+ if (enc_dbcs != 0 && c < 0x100 && MB_BYTE2LEN(c) > 1)
+ return FALSE;
+ if (enc_utf8 && c >= 0x100)
+ return utf_printable(c);
+ return c >= 0x100 || (c > 0 && (chartab[c] & CT_PRINT_CHAR));
+}
+
+/*
+ * like chartabsize(), but also check for line breaks on the screen
+ */
+int lbr_chartabsize(s, col)
+unsigned char *s;
+colnr_T col;
+{
+ if (!curwin->w_p_lbr && *p_sbr == NUL) {
+ if (curwin->w_p_wrap)
+ return win_nolbr_chartabsize(curwin, s, col, NULL);
+ RET_WIN_BUF_CHARTABSIZE(curwin, curbuf, s, col)
+ }
+ return win_lbr_chartabsize(curwin, s, col, NULL);
+}
+
+/*
+ * Call lbr_chartabsize() and advance the pointer.
+ */
+int lbr_chartabsize_adv(s, col)
+char_u **s;
+colnr_T col;
+{
+ int retval;
+
+ retval = lbr_chartabsize(*s, col);
+ mb_ptr_adv(*s);
+ return retval;
+}
+
+/*
+ * This function is used very often, keep it fast!!!!
+ *
+ * If "headp" not NULL, set *headp to the size of what we for 'showbreak'
+ * string at start of line. Warning: *headp is only set if it's a non-zero
+ * value, init to 0 before calling.
+ */
+int win_lbr_chartabsize(wp, s, col, headp)
+win_T *wp;
+char_u *s;
+colnr_T col;
+int *headp UNUSED;
+{
+ int c;
+ int size;
+ colnr_T col2;
+ colnr_T colmax;
+ int added;
+ int mb_added = 0;
+ int numberextra;
+ char_u *ps;
+ int tab_corr = (*s == TAB);
+ int n;
+
+ /*
+ * No 'linebreak' and 'showbreak': return quickly.
+ */
+ if (!wp->w_p_lbr && *p_sbr == NUL) {
+ if (wp->w_p_wrap)
+ return win_nolbr_chartabsize(wp, s, col, headp);
+ RET_WIN_BUF_CHARTABSIZE(wp, wp->w_buffer, s, col)
+ }
+
+ /*
+ * First get normal size, without 'linebreak'
+ */
+ size = win_chartabsize(wp, s, col);
+ c = *s;
+
+ /*
+ * If 'linebreak' set check at a blank before a non-blank if the line
+ * needs a break here
+ */
+ if (wp->w_p_lbr
+ && vim_isbreak(c)
+ && !vim_isbreak(s[1])
+ && !wp->w_p_list
+ && wp->w_p_wrap
+ && wp->w_width != 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)(W_WIDTH(wp) - numberextra);
+ if (col >= colmax) {
+ n = colmax + win_col_off2(wp);
+ if (n > 0)
+ colmax += (((col - colmax) / n) + 1) * n;
+ }
+
+ for (;; ) {
+ ps = s;
+ mb_ptr_adv(s);
+ c = *s;
+ if (!(c != NUL
+ && (vim_isbreak(c)
+ || (!vim_isbreak(c)
+ && (col2 == col || !vim_isbreak(*ps))))))
+ break;
+
+ col2 += win_chartabsize(wp, s, col2);
+ if (col2 >= colmax) { /* doesn't fit */
+ size = colmax - col;
+ tab_corr = FALSE;
+ break;
+ }
+ }
+ } else if (has_mbyte && size == 2 && MB_BYTE2LEN(*s) > 1
+ && wp->w_p_wrap && in_win_border(wp, col)) {
+ ++size; /* Count the ">" in the last column. */
+ mb_added = 1;
+ }
+
+ /*
+ * May have to add something for 'showbreak' string at start of line
+ * Set *headp to the size of what we add.
+ */
+ added = 0;
+ if (*p_sbr != NUL && wp->w_p_wrap && col != 0) {
+ numberextra = win_col_off(wp);
+ col += numberextra + mb_added;
+ if (col >= (colnr_T)W_WIDTH(wp)) {
+ col -= W_WIDTH(wp);
+ numberextra = W_WIDTH(wp) - (numberextra - win_col_off2(wp));
+ if (numberextra > 0)
+ col = col % numberextra;
+ }
+ if (col == 0 || col + size > (colnr_T)W_WIDTH(wp)) {
+ added = vim_strsize(p_sbr);
+ if (tab_corr)
+ size += (added / wp->w_buffer->b_p_ts) * wp->w_buffer->b_p_ts;
+ else
+ size += added;
+ if (col != 0)
+ added = 0;
+ }
+ }
+ if (headp != NULL)
+ *headp = added + mb_added;
+ return size;
+}
+
+/*
+ * Like win_lbr_chartabsize(), except that we know 'linebreak' is off and
+ * 'wrap' is on. This means we need to check for a double-byte character that
+ * doesn't fit at the end of the screen line.
+ */
+static int win_nolbr_chartabsize(wp, s, col, headp)
+win_T *wp;
+char_u *s;
+colnr_T col;
+int *headp;
+{
+ int n;
+
+ if (*s == TAB && (!wp->w_p_list || lcs_tab1)) {
+ n = wp->w_buffer->b_p_ts;
+ return (int)(n - (col % n));
+ }
+ n = ptr2cells(s);
+ /* Add one cell for a double-width character in the last column of the
+ * window, displayed with a ">". */
+ if (n == 2 && MB_BYTE2LEN(*s) > 1 && in_win_border(wp, col)) {
+ if (headp != NULL)
+ *headp = 1;
+ return 3;
+ }
+ return n;
+}
+
+/*
+ * Return TRUE if virtual column "vcol" is in the rightmost column of window
+ * "wp".
+ */
+int in_win_border(wp, vcol)
+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) /* there is no border */
+ return FALSE;
+ width1 = W_WIDTH(wp) - win_col_off(wp);
+ if ((int)vcol < width1 - 1)
+ return FALSE;
+ if ((int)vcol == width1 - 1)
+ return TRUE;
+ width2 = width1 + win_col_off2(wp);
+ if (width2 <= 0)
+ return FALSE;
+ return (vcol - width1) % width2 == width2 - 1;
+}
+
+/*
+ * Get virtual column number of pos.
+ * start: on the first position of this character (TAB, ctrl)
+ * cursor: where the cursor is on this character (first char, except for TAB)
+ * end: on the last position of this character (TAB, ctrl)
+ *
+ * This is used very often, keep it fast!
+ */
+void getvcol(wp, pos, start, cursor, end)
+win_T *wp;
+pos_T *pos;
+colnr_T *start;
+colnr_T *cursor;
+colnr_T *end;
+{
+ colnr_T vcol;
+ char_u *ptr; /* points to current char */
+ char_u *posptr; /* points to char at pos->col */
+ int incr;
+ int head;
+ int ts = wp->w_buffer->b_p_ts;
+ int c;
+
+ vcol = 0;
+ ptr = ml_get_buf(wp->w_buffer, pos->lnum, FALSE);
+ if (pos->col == MAXCOL)
+ posptr = NULL; /* continue until the NUL */
+ else
+ posptr = ptr + pos->col;
+
+ /*
+ * This function is used very often, do some speed optimizations.
+ * When 'list', 'linebreak' and 'showbreak' are not set use a simple loop.
+ * Also use this when 'list' is set but tabs take their normal size.
+ */
+ if ((!wp->w_p_list || lcs_tab1 != NUL)
+ && !wp->w_p_lbr && *p_sbr == NUL
+ ) {
+ for (;; ) {
+ head = 0;
+ c = *ptr;
+ /* make sure we don't go past the end of the line */
+ if (c == NUL) {
+ incr = 1; /* NUL at end of line only takes one column */
+ break;
+ }
+ /* A tab gets expanded, depending on the current column */
+ 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;
+ }
+ } else
+ incr = CHARSIZE(c);
+ }
+
+ if (posptr != NULL && ptr >= posptr) /* character at pos->col */
+ break;
+
+ vcol += incr;
+ mb_ptr_adv(ptr);
+ }
+ } else {
+ for (;; ) {
+ /* A tab gets expanded, depending on the current column */
+ head = 0;
+ incr = win_lbr_chartabsize(wp, ptr, vcol, &head);
+ /* make sure we don't go past the end of the line */
+ if (*ptr == NUL) {
+ incr = 1; /* NUL at end of line only takes one column */
+ break;
+ }
+
+ if (posptr != NULL && ptr >= posptr) /* character at pos->col */
+ break;
+
+ vcol += incr;
+ mb_ptr_adv(ptr);
+ }
+ }
+ if (start != NULL)
+ *start = vcol + head;
+ if (end != NULL)
+ *end = vcol + incr - 1;
+ if (cursor != NULL) {
+ if (*ptr == TAB
+ && (State & NORMAL)
+ && !wp->w_p_list
+ && !virtual_active()
+ && !(VIsual_active
+ && (*p_sel == 'e' || ltoreq(*pos, VIsual)))
+ )
+ *cursor = vcol + incr - 1; /* cursor at end */
+ else
+ *cursor = vcol + head; /* cursor at start */
+ }
+}
+
+/*
+ * Get virtual cursor column in the current window, pretending 'list' is off.
+ */
+colnr_T getvcol_nolist(posp)
+pos_T *posp;
+{
+ int list_save = curwin->w_p_list;
+ colnr_T vcol;
+
+ curwin->w_p_list = FALSE;
+ getvcol(curwin, posp, NULL, &vcol, NULL);
+ curwin->w_p_list = list_save;
+ return vcol;
+}
+
+/*
+ * Get virtual column in virtual mode.
+ */
+void getvvcol(wp, pos, start, cursor, end)
+win_T *wp;
+pos_T *pos;
+colnr_T *start;
+colnr_T *cursor;
+colnr_T *end;
+{
+ colnr_T col;
+ colnr_T coladd;
+ colnr_T endadd;
+ char_u *ptr;
+
+ if (virtual_active()) {
+ /* For virtual mode, only want one value */
+ getvcol(wp, pos, &col, NULL, NULL);
+
+ coladd = pos->coladd;
+ endadd = 0;
+ /* Cannot put the cursor on part of a wide character. */
+ ptr = ml_get_buf(wp->w_buffer, pos->lnum, FALSE);
+ if (pos->col < (colnr_T)STRLEN(ptr)) {
+ int c = (*mb_ptr2char)(ptr + pos->col);
+
+ if (c != TAB && vim_isprintc(c)) {
+ endadd = (colnr_T)(char2cells(c) - 1);
+ if (coladd > endadd) /* past end of line */
+ endadd = 0;
+ else
+ coladd = 0;
+ }
+ }
+ col += coladd;
+ if (start != NULL)
+ *start = col;
+ if (cursor != NULL)
+ *cursor = col;
+ if (end != NULL)
+ *end = col + endadd;
+ } else
+ getvcol(wp, pos, start, cursor, end);
+}
+
+/*
+ * Get the leftmost and rightmost virtual column of pos1 and pos2.
+ * Used for Visual block mode.
+ */
+void getvcols(wp, pos1, pos2, left, right)
+win_T *wp;
+pos_T *pos1, *pos2;
+colnr_T *left, *right;
+{
+ colnr_T from1, from2, to1, to2;
+
+ if (ltp(pos1, pos2)) {
+ getvvcol(wp, pos1, &from1, NULL, &to1);
+ getvvcol(wp, pos2, &from2, NULL, &to2);
+ } else {
+ getvvcol(wp, pos2, &from1, NULL, &to1);
+ getvvcol(wp, pos1, &from2, NULL, &to2);
+ }
+ if (from2 < from1)
+ *left = from2;
+ else
+ *left = from1;
+ if (to2 > to1) {
+ if (*p_sel == 'e' && from2 - 1 >= to1)
+ *right = from2 - 1;
+ else
+ *right = to2;
+ } else
+ *right = to1;
+}
+
+/*
+ * skipwhite: skip over ' ' and '\t'.
+ */
+char_u * skipwhite(q)
+char_u *q;
+{
+ char_u *p = q;
+
+ while (vim_iswhite(*p)) /* skip to next non-white */
+ ++p;
+ return p;
+}
+
+/*
+ * skip over digits
+ */
+char_u * skipdigits(q)
+char_u *q;
+{
+ char_u *p = q;
+
+ while (VIM_ISDIGIT(*p)) /* skip to next non-digit */
+ ++p;
+ return p;
+}
+
+/*
+ * skip over digits and hex characters
+ */
+char_u * skiphex(q)
+char_u *q;
+{
+ char_u *p = q;
+
+ while (vim_isxdigit(*p)) /* skip to next non-digit */
+ ++p;
+ return p;
+}
+
+/*
+ * skip to digit (or NUL after the string)
+ */
+char_u * skiptodigit(q)
+char_u *q;
+{
+ char_u *p = q;
+
+ while (*p != NUL && !VIM_ISDIGIT(*p)) /* skip to next digit */
+ ++p;
+ return p;
+}
+
+/*
+ * skip to hex character (or NUL after the string)
+ */
+char_u * skiptohex(q)
+char_u *q;
+{
+ char_u *p = q;
+
+ while (*p != NUL && !vim_isxdigit(*p)) /* skip to next digit */
+ ++p;
+ return p;
+}
+
+/*
+ * Variant of isdigit() that can handle characters > 0x100.
+ * We don't use isdigit() here, because on some systems it also considers
+ * superscript 1 to be a digit.
+ * Use the VIM_ISDIGIT() macro for simple arguments.
+ */
+int vim_isdigit(c)
+int c;
+{
+ return c >= '0' && c <= '9';
+}
+
+/*
+ * Variant of isxdigit() that can handle characters > 0x100.
+ * We don't use isxdigit() here, because on some systems it also considers
+ * superscript 1 to be a digit.
+ */
+int vim_isxdigit(c)
+int c;
+{
+ return (c >= '0' && c <= '9')
+ || (c >= 'a' && c <= 'f')
+ || (c >= 'A' && c <= 'F');
+}
+
+/*
+ * 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";
+
+int vim_islower(c)
+int c;
+{
+ if (c <= '@')
+ return FALSE;
+ if (c >= 0x80) {
+ if (enc_utf8)
+ return utf_islower(c);
+ if (c >= 0x100) {
+#ifdef HAVE_ISWLOWER
+ if (has_mbyte)
+ return iswlower(c);
+#endif
+ /* islower() can't handle these chars and may crash */
+ return FALSE;
+ }
+ if (enc_latin1like)
+ return (latin1flags[c] & LATIN1LOWER) == LATIN1LOWER;
+ }
+ return islower(c);
+}
+
+int vim_isupper(c)
+int c;
+{
+ if (c <= '@')
+ return FALSE;
+ if (c >= 0x80) {
+ if (enc_utf8)
+ return utf_isupper(c);
+ if (c >= 0x100) {
+#ifdef HAVE_ISWUPPER
+ if (has_mbyte)
+ return iswupper(c);
+#endif
+ /* islower() can't handle these chars and may crash */
+ return FALSE;
+ }
+ if (enc_latin1like)
+ return (latin1flags[c] & LATIN1UPPER) == LATIN1UPPER;
+ }
+ return isupper(c);
+}
+
+int vim_toupper(c)
+int c;
+{
+ if (c <= '@')
+ return c;
+ if (c >= 0x80) {
+ if (enc_utf8)
+ return utf_toupper(c);
+ if (c >= 0x100) {
+#ifdef HAVE_TOWUPPER
+ if (has_mbyte)
+ return towupper(c);
+#endif
+ /* toupper() can't handle these chars and may crash */
+ return c;
+ }
+ if (enc_latin1like)
+ return latin1upper[c];
+ }
+ return TOUPPER_LOC(c);
+}
+
+int vim_tolower(c)
+int c;
+{
+ if (c <= '@')
+ return c;
+ if (c >= 0x80) {
+ if (enc_utf8)
+ return utf_tolower(c);
+ if (c >= 0x100) {
+#ifdef HAVE_TOWLOWER
+ if (has_mbyte)
+ return towlower(c);
+#endif
+ /* 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.
+ */
+char_u * skiptowhite(p)
+char_u *p;
+{
+ while (*p != ' ' && *p != '\t' && *p != NUL)
+ ++p;
+ return p;
+}
+
+#if defined(FEAT_LISTCMDS) || defined(FEAT_SIGNS) || defined(FEAT_SNIFF) \
+ || defined(PROTO)
+/*
+ * skiptowhite_esc: Like skiptowhite(), but also skip escaped chars
+ */
+char_u * skiptowhite_esc(p)
+char_u *p;
+{
+ while (*p != ' ' && *p != '\t' && *p != NUL) {
+ if ((*p == '\\' || *p == Ctrl_V) && *(p + 1) != NUL)
+ ++p;
+ ++p;
+ }
+ return p;
+}
+#endif
+
+/*
+ * Getdigits: Get a number from a string and skip over it.
+ * Note: the argument is a pointer to a char_u pointer!
+ */
+long getdigits(pp)
+char_u **pp;
+{
+ char_u *p;
+ long retval;
+
+ p = *pp;
+ retval = atol((char *)p);
+ if (*p == '-') /* skip negative sign */
+ ++p;
+ p = skipdigits(p); /* skip to next non-digit */
+ *pp = p;
+ return retval;
+}
+
+/*
+ * Return TRUE if "lbuf" is empty or only contains blanks.
+ */
+int vim_isblankline(lbuf)
+char_u *lbuf;
+{
+ char_u *p;
+
+ p = skipwhite(lbuf);
+ return *p == NUL || *p == '\r' || *p == '\n';
+}
+
+/*
+ * Convert a string into a long and/or unsigned long, taking care of
+ * hexadecimal and octal numbers. Accepts a '-' sign.
+ * If "hexp" is not NULL, returns a flag to indicate the type of the number:
+ * 0 decimal
+ * '0' octal
+ * 'X' hex
+ * 'x' hex
+ * If "len" is not NULL, the length of the number in characters is returned.
+ * If "nptr" is not NULL, the signed result is returned in it.
+ * If "unptr" is not NULL, the unsigned result is returned in it.
+ * If "dooct" is non-zero recognize octal numbers, when > 1 always assume
+ * octal number.
+ * If "dohex" is non-zero recognize hex numbers, when > 1 always assume
+ * hex number.
+ */
+void vim_str2nr(start, hexp, len, dooct, dohex, nptr, unptr)
+char_u *start;
+int *hexp; /* return: type of number 0 = decimal, 'x'
+ or 'X' is hex, '0' = octal */
+int *len; /* return: detected length of number */
+int dooct; /* recognize octal number */
+int dohex; /* recognize hex number */
+long *nptr; /* return: signed result */
+unsigned long *unptr; /* return: unsigned result */
+{
+ char_u *ptr = start;
+ int hex = 0; /* default is decimal */
+ int negative = FALSE;
+ unsigned long un = 0;
+ int n;
+
+ if (ptr[0] == '-') {
+ negative = TRUE;
+ ++ptr;
+ }
+
+ /* Recognize hex and octal. */
+ if (ptr[0] == '0' && ptr[1] != '8' && ptr[1] != '9') {
+ hex = ptr[1];
+ if (dohex && (hex == 'X' || hex == 'x') && vim_isxdigit(ptr[2]))
+ ptr += 2; /* hexadecimal */
+ else {
+ hex = 0; /* default is decimal */
+ if (dooct) {
+ /* Don't interpret "0", "08" or "0129" as octal. */
+ for (n = 1; VIM_ISDIGIT(ptr[n]); ++n) {
+ if (ptr[n] > '7') {
+ hex = 0; /* can't be octal */
+ break;
+ }
+ if (ptr[n] >= '0')
+ hex = '0'; /* assume octal */
+ }
+ }
+ }
+ }
+
+ /*
+ * Do the string-to-numeric conversion "manually" to avoid sscanf quirks.
+ */
+ if (hex == '0' || dooct > 1) {
+ /* octal */
+ while ('0' <= *ptr && *ptr <= '7') {
+ un = 8 * un + (unsigned long)(*ptr - '0');
+ ++ptr;
+ }
+ } else if (hex != 0 || dohex > 1) {
+ /* hex */
+ while (vim_isxdigit(*ptr)) {
+ un = 16 * un + (unsigned long)hex2nr(*ptr);
+ ++ptr;
+ }
+ } else {
+ /* decimal */
+ while (VIM_ISDIGIT(*ptr)) {
+ un = 10 * un + (unsigned long)(*ptr - '0');
+ ++ptr;
+ }
+ }
+
+ if (hexp != NULL)
+ *hexp = hex;
+ if (len != NULL)
+ *len = (int)(ptr - start);
+ if (nptr != NULL) {
+ if (negative) /* account for leading '-' for decimal numbers */
+ *nptr = -(long)un;
+ else
+ *nptr = (long)un;
+ }
+ if (unptr != NULL)
+ *unptr = un;
+}
+
+/*
+ * Return the value of a single hex character.
+ * Only valid when the argument is '0' - '9', 'A' - 'F' or 'a' - 'f'.
+ */
+int hex2nr(c)
+int c;
+{
+ if (c >= 'a' && c <= 'f')
+ return c - 'a' + 10;
+ if (c >= 'A' && c <= 'F')
+ return c - 'A' + 10;
+ return c - '0';
+}
+
+#if defined(FEAT_TERMRESPONSE) \
+ || (defined(FEAT_GUI_GTK) && defined(FEAT_WINDOWS)) || defined(PROTO)
+/*
+ * Convert two hex characters to a byte.
+ * Return -1 if one of the characters is not hex.
+ */
+int hexhex2nr(p)
+char_u *p;
+{
+ if (!vim_isxdigit(p[0]) || !vim_isxdigit(p[1]))
+ return -1;
+ return (hex2nr(p[0]) << 4) + hex2nr(p[1]);
+}
+#endif
+
+/*
+ * Return TRUE if "str" starts with a backslash that should be removed.
+ * For MS-DOS, WIN32 and OS/2 this is only done when the character after the
+ * backslash is not a normal file name character.
+ * '$' is a valid file name character, we don't remove the backslash before
+ * it. This means it is not possible to use an environment variable after a
+ * backslash. "C:\$VIM\doc" is taken literally, only "$VIM\doc" works.
+ * Although "\ name" is valid, the backslash in "Program\ files" must be
+ * removed. Assume a file name doesn't start with a space.
+ * For multi-byte names, never remove a backslash before a non-ascii
+ * character, assume that all multi-byte characters are valid file name
+ * characters.
+ */
+int rem_backslash(str)
+char_u *str;
+{
+#ifdef BACKSLASH_IN_FILENAME
+ return str[0] == '\\'
+ && str[1] < 0x80
+ && (str[1] == ' '
+ || (str[1] != NUL
+ && str[1] != '*'
+ && str[1] != '?'
+ && !vim_isfilec(str[1])));
+#else
+ return str[0] == '\\' && str[1] != NUL;
+#endif
+}
+
+/*
+ * Halve the number of backslashes in a file name argument.
+ * For MS-DOS we only do this if the character after the backslash
+ * is not a normal file character.
+ */
+void backslash_halve(p)
+char_u *p;
+{
+ for (; *p; ++p)
+ if (rem_backslash(p))
+ STRMOVE(p, p + 1);
+}
+
+/*
+ * backslash_halve() plus save the result in allocated memory.
+ */
+char_u * backslash_halve_save(p)
+char_u *p;
+{
+ char_u *res;
+
+ res = vim_strsave(p);
+ if (res == NULL)
+ return p;
+ backslash_halve(res);
+ return res;
+}
+
diff --git a/src/diff.c b/src/diff.c
new file mode 100644
index 0000000000..ad31128575
--- /dev/null
+++ b/src/diff.c
@@ -0,0 +1,2296 @@
+/* vim:set ts=8 sts=4 sw=4:
+ *
+ * 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.
+ */
+
+/*
+ * diff.c: code for diff'ing two, three or four buffers.
+ */
+
+#include "vim.h"
+
+
+static int diff_busy = FALSE; /* ex_diffgetput() is busy */
+
+/* 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 LBUFLEN 50 /* length of line in diff file */
+
+static int diff_a_works = MAYBE; /* TRUE when "diff -a" works, FALSE when it
+ doesn't work, MAYBE when not checked yet */
+
+static int diff_buf_idx __ARGS((buf_T *buf));
+static int diff_buf_idx_tp __ARGS((buf_T *buf, tabpage_T *tp));
+static void diff_mark_adjust_tp __ARGS((tabpage_T *tp, int idx, linenr_T line1,
+ linenr_T line2, long amount,
+ long amount_after));
+static void diff_check_unchanged __ARGS((tabpage_T *tp, diff_T *dp));
+static int diff_check_sanity __ARGS((tabpage_T *tp, diff_T *dp));
+static void diff_redraw __ARGS((int dofold));
+static int diff_write __ARGS((buf_T *buf, char_u *fname));
+static void diff_file __ARGS((char_u *tmp_orig, char_u *tmp_new,
+ char_u *tmp_diff));
+static int diff_equal_entry __ARGS((diff_T *dp, int idx1, int idx2));
+static int diff_cmp __ARGS((char_u *s1, char_u *s2));
+static void diff_fold_update __ARGS((diff_T *dp, int skip_idx));
+static void diff_read __ARGS((int idx_orig, int idx_new, char_u *fname));
+static void diff_copy_entry __ARGS((diff_T *dprev, diff_T *dp, int idx_orig,
+ int idx_new));
+static diff_T *diff_alloc_new __ARGS((tabpage_T *tp, diff_T *dprev, diff_T *dp));
+
+#ifndef USE_CR
+# define tag_fgets vim_fgets
+#endif
+
+/*
+ * Called when deleting or unloading a buffer: No longer make a diff with it.
+ */
+void diff_buf_delete(buf)
+buf_T *buf;
+{
+ int i;
+ tabpage_T *tp;
+
+ for (tp = first_tabpage; tp != NULL; tp = tp->tp_next) {
+ i = diff_buf_idx_tp(buf, tp);
+ if (i != DB_COUNT) {
+ tp->tp_diffbuf[i] = NULL;
+ tp->tp_diff_invalid = TRUE;
+ if (tp == curtab)
+ diff_redraw(TRUE);
+ }
+ }
+}
+
+/*
+ * Check if the current buffer should be added to or removed from the list of
+ * diff buffers.
+ */
+void diff_buf_adjust(win)
+win_T *win;
+{
+ win_T *wp;
+ int i;
+
+ if (!win->w_p_diff) {
+ /* When there is no window showing a diff for this buffer, remove
+ * it from the diffs. */
+ for (wp = firstwin; wp != NULL; wp = wp->w_next)
+ if (wp->w_buffer == win->w_buffer && wp->w_p_diff)
+ break;
+ if (wp == NULL) {
+ i = diff_buf_idx(win->w_buffer);
+ if (i != DB_COUNT) {
+ curtab->tp_diffbuf[i] = NULL;
+ curtab->tp_diff_invalid = TRUE;
+ diff_redraw(TRUE);
+ }
+ }
+ } else
+ diff_buf_add(win->w_buffer);
+}
+
+/*
+ * Add a buffer to make diffs for.
+ * Call this when a new buffer is being edited in the current window where
+ * 'diff' is set.
+ * Marks the current buffer as being part of the diff and requiring updating.
+ * This must be done before any autocmd, because a command may use info
+ * about the screen contents.
+ */
+void diff_buf_add(buf)
+buf_T *buf;
+{
+ int i;
+
+ if (diff_buf_idx(buf) != DB_COUNT)
+ return; /* It's already there. */
+
+ 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);
+ return;
+ }
+
+ EMSGN(_("E96: Can not diff more than %ld buffers"), DB_COUNT);
+}
+
+/*
+ * Find buffer "buf" in the list of diff buffers for the current tab page.
+ * Return its index or DB_COUNT if not found.
+ */
+static int diff_buf_idx(buf)
+buf_T *buf;
+{
+ int idx;
+
+ for (idx = 0; idx < DB_COUNT; ++idx)
+ if (curtab->tp_diffbuf[idx] == buf)
+ break;
+ return idx;
+}
+
+/*
+ * Find buffer "buf" in the list of diff buffers for tab page "tp".
+ * Return its index or DB_COUNT if not found.
+ */
+static int diff_buf_idx_tp(buf, tp)
+buf_T *buf;
+tabpage_T *tp;
+{
+ int idx;
+
+ for (idx = 0; idx < DB_COUNT; ++idx)
+ if (tp->tp_diffbuf[idx] == buf)
+ break;
+ return idx;
+}
+
+/*
+ * Mark the diff info involving buffer "buf" as invalid, it will be updated
+ * when info is requested.
+ */
+void diff_invalidate(buf)
+buf_T *buf;
+{
+ tabpage_T *tp;
+ int i;
+
+ for (tp = first_tabpage; tp != NULL; tp = tp->tp_next) {
+ i = diff_buf_idx_tp(buf, tp);
+ if (i != DB_COUNT) {
+ tp->tp_diff_invalid = TRUE;
+ if (tp == curtab)
+ diff_redraw(TRUE);
+ }
+ }
+}
+
+/*
+ * Called by mark_adjust(): update line numbers in "curbuf".
+ */
+void diff_mark_adjust(line1, line2, amount, amount_after)
+linenr_T line1;
+linenr_T line2;
+long amount;
+long amount_after;
+{
+ int idx;
+ tabpage_T *tp;
+
+ /* Handle all tab pages that use the current buffer in a diff. */
+ for (tp = first_tabpage; tp != NULL; tp = tp->tp_next) {
+ idx = diff_buf_idx_tp(curbuf, tp);
+ if (idx != DB_COUNT)
+ diff_mark_adjust_tp(tp, idx, line1, line2, amount, amount_after);
+ }
+}
+
+/*
+ * Update line numbers in tab page "tp" for "curbuf" with index "idx".
+ * This attempts to update the changes as much as possible:
+ * When inserting/deleting lines outside of existing change blocks, create a
+ * new change block and update the line numbers in following blocks.
+ * When inserting/deleting lines in existing change blocks, update them.
+ */
+static void diff_mark_adjust_tp(tp, idx, line1, line2, amount, amount_after)
+tabpage_T *tp;
+int idx;
+linenr_T line1;
+linenr_T line2;
+long amount;
+long amount_after;
+{
+ diff_T *dp;
+ diff_T *dprev;
+ diff_T *dnext;
+ int i;
+ int inserted, deleted;
+ int n, off;
+ linenr_T last;
+ linenr_T lnum_deleted = line1; /* lnum of remaining deletion */
+ int check_unchanged;
+
+ if (line2 == MAXLNUM) {
+ /* mark_adjust(99, MAXLNUM, 9, 0): insert lines */
+ inserted = amount;
+ deleted = 0;
+ } else if (amount_after > 0) {
+ /* mark_adjust(99, 98, MAXLNUM, 9): a change that inserts lines*/
+ inserted = amount_after;
+ deleted = 0;
+ } else {
+ /* mark_adjust(98, 99, MAXLNUM, -2): delete lines */
+ inserted = 0;
+ deleted = -amount_after;
+ }
+
+ dprev = NULL;
+ dp = tp->tp_first_diff;
+ for (;; ) {
+ /* If the change is after the previous diff block and before the next
+ * diff block, thus not touching an existing change, create a new diff
+ * block. Don't do this when ex_diffgetput() is busy. */
+ if ((dp == NULL || dp->df_lnum[idx] - 1 > line2
+ || (line2 == MAXLNUM && dp->df_lnum[idx] > line1))
+ && (dprev == NULL
+ || dprev->df_lnum[idx] + dprev->df_count[idx] < line1)
+ && !diff_busy) {
+ dnext = diff_alloc_new(tp, dprev, dp);
+ if (dnext == NULL)
+ return;
+
+ dnext->df_lnum[idx] = line1;
+ dnext->df_count[idx] = inserted;
+ for (i = 0; i < DB_COUNT; ++i)
+ if (tp->tp_diffbuf[i] != NULL && i != idx) {
+ if (dprev == NULL)
+ dnext->df_lnum[i] = line1;
+ else
+ dnext->df_lnum[i] = line1
+ + (dprev->df_lnum[i] + dprev->df_count[i])
+ - (dprev->df_lnum[idx] + dprev->df_count[idx]);
+ dnext->df_count[i] = deleted;
+ }
+ }
+
+ /* if at end of the list, quit */
+ if (dp == NULL)
+ break;
+
+ /*
+ * 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
+ */
+ /* compute last line of this change */
+ last = dp->df_lnum[idx] + dp->df_count[idx] - 1;
+
+ /* 1. change completely above line1: nothing to do */
+ if (last >= line1 - 1) {
+ /* 6. change below line2: only adjust for amount_after; also when
+ * "deleted" became zero when deleted all lines between two diffs */
+ if (dp->df_lnum[idx] - (deleted + inserted != 0) > line2) {
+ if (amount_after == 0)
+ break; /* nothing left to change */
+ dp->df_lnum[idx] += amount_after;
+ } else {
+ check_unchanged = FALSE;
+
+ /* 2. 3. 4. 5.: inserted/deleted lines touching this diff. */
+ if (deleted > 0) {
+ if (dp->df_lnum[idx] >= line1) {
+ off = dp->df_lnum[idx] - lnum_deleted;
+ if (last <= line2) {
+ /* 4. delete all lines of diff */
+ if (dp->df_next != NULL
+ && dp->df_next->df_lnum[idx] - 1 <= line2) {
+ /* delete continues in next diff, only do
+ * lines until that one */
+ n = dp->df_next->df_lnum[idx] - lnum_deleted;
+ deleted -= n;
+ n -= dp->df_count[idx];
+ lnum_deleted = dp->df_next->df_lnum[idx];
+ } else
+ n = deleted - dp->df_count[idx];
+ dp->df_count[idx] = 0;
+ } else {
+ /* 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;
+ }
+ dp->df_lnum[idx] = line1;
+ } else {
+ off = 0;
+ if (last < line2) {
+ /* 2. delete at end of of diff */
+ dp->df_count[idx] -= last - lnum_deleted + 1;
+ if (dp->df_next != NULL
+ && dp->df_next->df_lnum[idx] - 1 <= line2) {
+ /* delete continues in next diff, only do
+ * lines until that one */
+ n = dp->df_next->df_lnum[idx] - 1 - last;
+ deleted -= dp->df_next->df_lnum[idx]
+ - lnum_deleted;
+ lnum_deleted = dp->df_next->df_lnum[idx];
+ } else
+ n = line2 - last;
+ check_unchanged = TRUE;
+ } else {
+ /* 3. delete lines inside the diff */
+ n = 0;
+ dp->df_count[idx] -= deleted;
+ }
+ }
+
+ for (i = 0; i < DB_COUNT; ++i)
+ if (tp->tp_diffbuf[i] != NULL && i != idx) {
+ dp->df_lnum[i] -= off;
+ dp->df_count[i] += n;
+ }
+ } else {
+ if (dp->df_lnum[idx] <= line1) {
+ /* inserted lines somewhere in this diff */
+ dp->df_count[idx] += inserted;
+ check_unchanged = TRUE;
+ } else
+ /* inserted lines somewhere above this diff */
+ dp->df_lnum[idx] += inserted;
+ }
+
+ if (check_unchanged)
+ /* Check if inserted lines are equal, may reduce the
+ * size of the diff. TODO: also check for equal lines
+ * in the middle and perhaps split the block. */
+ diff_check_unchanged(tp, dp);
+ }
+ }
+
+ /* check if this block touches the previous one, may merge them. */
+ if (dprev != NULL && dprev->df_lnum[idx] + dprev->df_count[idx]
+ == dp->df_lnum[idx]) {
+ for (i = 0; i < DB_COUNT; ++i)
+ if (tp->tp_diffbuf[i] != NULL)
+ dprev->df_count[i] += dp->df_count[i];
+ dprev->df_next = dp->df_next;
+ vim_free(dp);
+ dp = dprev->df_next;
+ } else {
+ /* Advance to next entry. */
+ dprev = dp;
+ dp = dp->df_next;
+ }
+ }
+
+ dprev = NULL;
+ dp = tp->tp_first_diff;
+ while (dp != NULL) {
+ /* All counts are zero, remove this entry. */
+ for (i = 0; i < DB_COUNT; ++i)
+ if (tp->tp_diffbuf[i] != NULL && dp->df_count[i] != 0)
+ break;
+ if (i == DB_COUNT) {
+ dnext = dp->df_next;
+ vim_free(dp);
+ dp = dnext;
+ if (dprev == NULL)
+ tp->tp_first_diff = dnext;
+ else
+ dprev->df_next = dnext;
+ } else {
+ /* Advance to next entry. */
+ dprev = dp;
+ dp = dp->df_next;
+ }
+
+ }
+
+ if (tp == curtab) {
+ 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;
+ }
+}
+
+/*
+ * Allocate a new diff block and link it between "dprev" and "dp".
+ */
+static diff_T * diff_alloc_new(tp, dprev, dp)
+tabpage_T *tp;
+diff_T *dprev;
+diff_T *dp;
+{
+ diff_T *dnew;
+
+ dnew = (diff_T *)alloc((unsigned)sizeof(diff_T));
+ if (dnew != NULL) {
+ dnew->df_next = dp;
+ if (dprev == NULL)
+ tp->tp_first_diff = dnew;
+ else
+ dprev->df_next = dnew;
+ }
+ return dnew;
+}
+
+/*
+ * Check if the diff block "dp" can be made smaller for lines at the start and
+ * end that are equal. Called after inserting lines.
+ * This may result in a change where all buffers have zero lines, the caller
+ * must take care of removing it.
+ */
+static void diff_check_unchanged(tp, dp)
+tabpage_T *tp;
+diff_T *dp;
+{
+ int i_org;
+ int i_new;
+ int off_org, off_new;
+ char_u *line_org;
+ int dir = FORWARD;
+
+ /* Find the first buffers, use it as the original, compare the other
+ * buffer lines against this one. */
+ for (i_org = 0; i_org < DB_COUNT; ++i_org)
+ if (tp->tp_diffbuf[i_org] != NULL)
+ break;
+ if (i_org == DB_COUNT) /* safety check */
+ return;
+
+ if (diff_check_sanity(tp, dp) == FAIL)
+ return;
+
+ /* First check lines at the top, then at the bottom. */
+ off_org = 0;
+ off_new = 0;
+ for (;; ) {
+ /* Repeat until a line is found which is different or the number of
+ * lines has become zero. */
+ while (dp->df_count[i_org] > 0) {
+ /* Copy the line, the next ml_get() will invalidate it. */
+ if (dir == BACKWARD)
+ off_org = dp->df_count[i_org] - 1;
+ line_org = vim_strsave(ml_get_buf(tp->tp_diffbuf[i_org],
+ dp->df_lnum[i_org] + off_org, FALSE));
+ if (line_org == NULL)
+ return;
+ for (i_new = i_org + 1; i_new < DB_COUNT; ++i_new) {
+ if (tp->tp_diffbuf[i_new] == NULL)
+ continue;
+ if (dir == BACKWARD)
+ off_new = dp->df_count[i_new] - 1;
+ /* if other buffer doesn't have this line, it was inserted */
+ if (off_new < 0 || off_new >= dp->df_count[i_new])
+ break;
+ if (diff_cmp(line_org, ml_get_buf(tp->tp_diffbuf[i_new],
+ dp->df_lnum[i_new] + off_new, FALSE)) != 0)
+ break;
+ }
+ vim_free(line_org);
+
+ /* Stop when a line isn't equal in all diff buffers. */
+ if (i_new != DB_COUNT)
+ break;
+
+ /* Line matched in all buffers, remove it from the diff. */
+ for (i_new = i_org; i_new < DB_COUNT; ++i_new)
+ if (tp->tp_diffbuf[i_new] != NULL) {
+ if (dir == FORWARD)
+ ++dp->df_lnum[i_new];
+ --dp->df_count[i_new];
+ }
+ }
+ if (dir == BACKWARD)
+ break;
+ dir = BACKWARD;
+ }
+}
+
+/*
+ * Check if a diff block doesn't contain invalid line numbers.
+ * This can happen when the diff program returns invalid results.
+ */
+static int diff_check_sanity(tp, dp)
+tabpage_T *tp;
+diff_T *dp;
+{
+ int i;
+
+ for (i = 0; i < DB_COUNT; ++i)
+ if (tp->tp_diffbuf[i] != NULL)
+ if (dp->df_lnum[i] + dp->df_count[i] - 1
+ > tp->tp_diffbuf[i]->b_ml.ml_line_count)
+ return FAIL;
+ return OK;
+}
+
+/*
+ * Mark all diff buffers in the current tab page for redraw.
+ */
+static void diff_redraw(dofold)
+int dofold; /* also recompute the folds */
+{
+ win_T *wp;
+ int n;
+
+ for (wp = firstwin; wp != NULL; wp = wp->w_next)
+ if (wp->w_p_diff) {
+ redraw_win_later(wp, SOME_VALID);
+ if (dofold && foldmethodIsDiff(wp))
+ foldUpdateAll(wp);
+ /* A change may have made filler lines invalid, need to take care
+ * of that for other windows. */
+ n = diff_check(wp, wp->w_topline);
+ if ((wp != curwin && wp->w_topfill > 0) || n > 0) {
+ if (wp->w_topfill > n)
+ wp->w_topfill = (n < 0 ? 0 : n);
+ else if (n > 0 && n > wp->w_topfill)
+ wp->w_topfill = n;
+ }
+ }
+}
+
+/*
+ * Write buffer "buf" to file "name".
+ * Always use 'fileformat' set to "unix".
+ * Return FAIL for failure
+ */
+static int diff_write(buf, fname)
+buf_T *buf;
+char_u *fname;
+{
+ int r;
+ char_u *save_ff;
+
+ save_ff = buf->b_p_ff;
+ buf->b_p_ff = vim_strsave((char_u *)FF_UNIX);
+ r = buf_write(buf, 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;
+}
+
+/*
+ * 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).
+ */
+void ex_diffupdate(eap)
+exarg_T *eap UNUSED; /* can be NULL */
+{
+ buf_T *buf;
+ int idx_orig;
+ int idx_new;
+ char_u *tmp_orig;
+ char_u *tmp_new;
+ char_u *tmp_diff;
+ FILE *fd;
+ int ok;
+ int io_error = FALSE;
+
+ /* Delete all diffblocks. */
+ diff_clear(curtab);
+ curtab->tp_diff_invalid = FALSE;
+
+ /* Use the first buffer as the original text. */
+ for (idx_orig = 0; idx_orig < DB_COUNT; ++idx_orig)
+ if (curtab->tp_diffbuf[idx_orig] != NULL)
+ break;
+ if (idx_orig == DB_COUNT)
+ return;
+
+ /* Only need to do something when there is another buffer. */
+ for (idx_new = idx_orig + 1; idx_new < DB_COUNT; ++idx_new)
+ if (curtab->tp_diffbuf[idx_new] != NULL)
+ break;
+ if (idx_new == DB_COUNT)
+ return;
+
+ /* We need three temp file names. */
+ tmp_orig = vim_tempname('o');
+ tmp_new = vim_tempname('n');
+ tmp_diff = vim_tempname('d');
+ if (tmp_orig == NULL || tmp_new == NULL || tmp_diff == NULL)
+ goto theend;
+
+ /*
+ * 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.
+ * May try twice, first with "-a" and then without.
+ */
+ for (;; ) {
+ ok = FALSE;
+ fd = mch_fopen((char *)tmp_orig, "w");
+ if (fd == NULL)
+ io_error = TRUE;
+ else {
+ if (fwrite("line1\n", (size_t)6, (size_t)1, fd) != 1)
+ io_error = TRUE;
+ fclose(fd);
+ fd = mch_fopen((char *)tmp_new, "w");
+ if (fd == NULL)
+ io_error = TRUE;
+ else {
+ if (fwrite("line2\n", (size_t)6, (size_t)1, fd) != 1)
+ io_error = TRUE;
+ fclose(fd);
+ diff_file(tmp_orig, tmp_new, tmp_diff);
+ fd = mch_fopen((char *)tmp_diff, "r");
+ if (fd == NULL)
+ io_error = TRUE;
+ else {
+ char_u linebuf[LBUFLEN];
+
+ for (;; ) {
+ /* There must be a line that contains "1c1". */
+ if (tag_fgets(linebuf, LBUFLEN, fd))
+ break;
+ if (STRNCMP(linebuf, "1c1", 3) == 0)
+ ok = TRUE;
+ }
+ fclose(fd);
+ }
+ mch_remove(tmp_diff);
+ mch_remove(tmp_new);
+ }
+ mch_remove(tmp_orig);
+ }
+
+ /* When using 'diffexpr' break here. */
+ if (*p_dex != NUL)
+ break;
+
+
+ /* If we checked if "-a" works already, break here. */
+ if (diff_a_works != MAYBE)
+ break;
+ diff_a_works = ok;
+
+ /* If "-a" works break here, otherwise retry without "-a". */
+ if (ok)
+ break;
+ }
+ if (!ok) {
+ if (io_error)
+ 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 = curtab->tp_diffbuf[idx_new];
+ if (buf_valid(buf))
+ buf_check_timestamp(buf, FALSE);
+ }
+
+ /* Write the first buffer to a tempfile. */
+ buf = curtab->tp_diffbuf[idx_orig];
+ if (diff_write(buf, tmp_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)
+ continue;
+ if (diff_write(buf, tmp_new) == FAIL)
+ continue;
+ diff_file(tmp_orig, tmp_new, tmp_diff);
+
+ /* Read the diff output and add each entry to the diff list. */
+ diff_read(idx_orig, idx_new, tmp_diff);
+ mch_remove(tmp_diff);
+ mch_remove(tmp_new);
+ }
+ mch_remove(tmp_orig);
+
+ /* force updating cursor position on screen */
+ curwin->w_valid_cursor.lnum = 0;
+
+ diff_redraw(TRUE);
+
+theend:
+ vim_free(tmp_orig);
+ vim_free(tmp_new);
+ vim_free(tmp_diff);
+}
+
+/*
+ * Make a diff between files "tmp_orig" and "tmp_new", results in "tmp_diff".
+ */
+static void diff_file(tmp_orig, tmp_new, tmp_diff)
+char_u *tmp_orig;
+char_u *tmp_new;
+char_u *tmp_diff;
+{
+ char_u *cmd;
+ size_t len;
+
+ if (*p_dex != NUL)
+ /* Use 'diffexpr' to generate the diff file. */
+ eval_diff(tmp_orig, tmp_new, tmp_diff);
+ else {
+ len = STRLEN(tmp_orig) + STRLEN(tmp_new)
+ + STRLEN(tmp_diff) + STRLEN(p_srr) + 27;
+ cmd = alloc((unsigned)len);
+ if (cmd != NULL) {
+ /* We don't want $DIFF_OPTIONS to get in the way. */
+ if (getenv("DIFF_OPTIONS"))
+ vim_setenv((char_u *)"DIFF_OPTIONS", (char_u *)"");
+
+ /* 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",
+ diff_a_works == FALSE ? "" : "-a ",
+ "",
+ (diff_flags & DIFF_IWHITE) ? "-b " : "",
+ (diff_flags & DIFF_ICASE) ? "-i " : "",
+ tmp_orig, tmp_new);
+ append_redir(cmd, (int)len, p_srr, tmp_diff);
+ block_autocmds(); /* Avoid ShellCmdPost stuff */
+ (void)call_shell(cmd, SHELL_FILTER|SHELL_SILENT|SHELL_DOOUT);
+ unblock_autocmds();
+ vim_free(cmd);
+ }
+ }
+}
+
+/*
+ * Create a new version of a file from the current buffer and a diff file.
+ * The buffer is written to a file, also for unmodified buffers (the file
+ * could have been produced by autocommands, e.g. the netrw plugin).
+ */
+void ex_diffpatch(eap)
+exarg_T *eap;
+{
+ char_u *tmp_orig; /* name of original temp file */
+ char_u *tmp_new; /* name of patched temp file */
+ char_u *buf = NULL;
+ size_t buflen;
+ win_T *old_curwin = curwin;
+ char_u *newname = NULL; /* name of patched file buffer */
+#ifdef UNIX
+ char_u dirbuf[MAXPATHL];
+ char_u *fullname = NULL;
+#endif
+ struct stat st;
+
+
+ /* We need two temp file names. */
+ tmp_orig = vim_tempname('o');
+ tmp_new = vim_tempname('n');
+ if (tmp_orig == NULL || tmp_new == NULL)
+ goto theend;
+
+ /* 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)
+ goto theend;
+
+#ifdef UNIX
+ /* Get the absolute path of the patchfile, changing directory below. */
+ fullname = FullName_save(eap->arg, FALSE);
+#endif
+ buflen = STRLEN(tmp_orig) + (
+# ifdef UNIX
+ fullname != NULL ? STRLEN(fullname) :
+# endif
+ STRLEN(eap->arg)) + STRLEN(tmp_new) + 16;
+ buf = alloc((unsigned)buflen);
+ if (buf == NULL)
+ goto theend;
+
+#ifdef UNIX
+ /* 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
+ * exit (any .rej files created). Don't change directory if we can't
+ * return to the current. */
+ if (mch_dirname(dirbuf, MAXPATHL) != OK || mch_chdir((char *)dirbuf) != 0)
+ dirbuf[0] = NUL;
+ else {
+# ifdef TEMPDIRNAMES
+ if (vim_tempdir != NULL)
+ ignored = mch_chdir((char *)vim_tempdir);
+ else
+# endif
+ ignored = mch_chdir("/tmp");
+ shorten_fnames(TRUE);
+ }
+#endif
+
+ if (*p_pex != NUL)
+ /* Use 'patchexpr' to generate the new file. */
+ eval_patch(tmp_orig,
+# ifdef UNIX
+ fullname != NULL ? fullname :
+# endif
+ eap->arg, tmp_new);
+ else {
+ /* Build the patch command and execute it. Ignore errors. Switch to
+ * cooked mode to allow the user to respond to prompts. */
+ vim_snprintf((char *)buf, buflen, "patch -o %s %s < \"%s\"",
+ tmp_new, tmp_orig,
+# ifdef UNIX
+ fullname != NULL ? fullname :
+# endif
+ eap->arg);
+ block_autocmds(); /* Avoid ShellCmdPost stuff */
+ (void)call_shell(buf, SHELL_FILTER | SHELL_COOKED);
+ unblock_autocmds();
+ }
+
+#ifdef UNIX
+ if (dirbuf[0] != NUL) {
+ if (mch_chdir((char *)dirbuf) != 0)
+ EMSG(_(e_prev_dir));
+ shorten_fnames(TRUE);
+ }
+#endif
+
+ /* patch probably has written over the screen */
+ redraw_later(CLEAR);
+
+ /* Delete any .orig or .rej file created. */
+ STRCPY(buf, tmp_new);
+ STRCAT(buf, ".orig");
+ mch_remove(buf);
+ STRCPY(buf, tmp_new);
+ STRCAT(buf, ".rej");
+ mch_remove(buf);
+
+ /* Only continue if the output file was created. */
+ if (mch_stat((char *)tmp_new, &st) < 0 || st.st_size == 0)
+ EMSG(_("E816: Cannot read patch output"));
+ else {
+ if (curbuf->b_fname != NULL) {
+ newname = vim_strnsave(curbuf->b_fname,
+ (int)(STRLEN(curbuf->b_fname) + 4));
+ if (newname != NULL)
+ STRCAT(newname, ".new");
+ }
+
+ /* don't use a new tab page, each tab page has its own diffs */
+ cmdmod.tab = 0;
+
+ if (win_split(0, (diff_flags & DIFF_VERTICAL) ? WSP_VERT : 0) != FAIL) {
+ /* Pretend it was a ":split fname" command */
+ eap->cmdidx = CMD_split;
+ eap->arg = tmp_new;
+ do_exedit(eap, old_curwin);
+
+ /* 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);
+
+ if (newname != NULL) {
+ /* do a ":file filename.new" on the patched buffer */
+ eap->arg = newname;
+ ex_file(eap);
+
+ /* Do filetype detection with the new name. */
+ if (au_has_group((char_u *)"filetypedetect"))
+ do_cmdline_cmd((char_u *)":doau filetypedetect BufRead");
+ }
+ }
+ }
+ }
+
+theend:
+ if (tmp_orig != NULL)
+ mch_remove(tmp_orig);
+ vim_free(tmp_orig);
+ if (tmp_new != NULL)
+ mch_remove(tmp_new);
+ vim_free(tmp_new);
+ vim_free(newname);
+ vim_free(buf);
+#ifdef UNIX
+ vim_free(fullname);
+#endif
+}
+
+/*
+ * Split the window and edit another file, setting options to show the diffs.
+ */
+void ex_diffsplit(eap)
+exarg_T *eap;
+{
+ win_T *old_curwin = curwin;
+
+ /* don't use a new tab page, each tab page has its own diffs */
+ cmdmod.tab = 0;
+
+ 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;
+ do_exedit(eap, old_curwin);
+
+ if (curwin != old_curwin) { /* split must have worked */
+ /* Set 'diff', 'scrollbind' on and 'wrap' off. */
+ diff_win_options(curwin, TRUE);
+ diff_win_options(old_curwin, TRUE);
+ }
+ }
+}
+
+/*
+ * Set options to show diffs for the current window.
+ */
+void ex_diffthis(eap)
+exarg_T *eap UNUSED;
+{
+ /* Set 'diff', 'scrollbind' on and 'wrap' off. */
+ diff_win_options(curwin, TRUE);
+}
+
+/*
+ * Set options in window "wp" for diff mode.
+ */
+void diff_win_options(wp, addbuf)
+win_T *wp;
+int addbuf; /* Add buffer to diff. */
+{
+ win_T *old_curwin = curwin;
+
+ /* close the manually opened folds */
+ curwin = wp;
+ newFoldLevel();
+ curwin = old_curwin;
+
+ wp->w_p_diff = TRUE;
+
+ /* Use 'scrollbind' and 'cursorbind' when available */
+ if (!wp->w_p_diff_saved)
+ wp->w_p_scb_save = wp->w_p_scb;
+ wp->w_p_scb = TRUE;
+ if (!wp->w_p_diff_saved)
+ wp->w_p_crb_save = wp->w_p_crb;
+ wp->w_p_crb = TRUE;
+ if (!wp->w_p_diff_saved)
+ wp->w_p_wrap_save = wp->w_p_wrap;
+ wp->w_p_wrap = FALSE;
+ curwin = wp;
+ curbuf = curwin->w_buffer;
+ if (!wp->w_p_diff_saved)
+ wp->w_p_fdm_save = vim_strsave(wp->w_p_fdm);
+ set_string_option_direct((char_u *)"fdm", -1, (char_u *)"diff",
+ OPT_LOCAL|OPT_FREE, 0);
+ curwin = old_curwin;
+ curbuf = curwin->w_buffer;
+ if (!wp->w_p_diff_saved) {
+ wp->w_p_fdc_save = wp->w_p_fdc;
+ wp->w_p_fen_save = wp->w_p_fen;
+ wp->w_p_fdl_save = wp->w_p_fdl;
+ }
+ wp->w_p_fdc = diff_foldcolumn;
+ wp->w_p_fen = TRUE;
+ wp->w_p_fdl = 0;
+ foldUpdateAll(wp);
+ /* make sure topline is not halfway a fold */
+ changed_window_setting_win(wp);
+ if (vim_strchr(p_sbo, 'h') == NULL)
+ do_cmdline_cmd((char_u *)"set sbo+=hor");
+ /* Saved the current values, to be restored in ex_diffoff(). */
+ wp->w_p_diff_saved = TRUE;
+
+ if (addbuf)
+ diff_buf_add(wp->w_buffer);
+ redraw_win_later(wp, NOT_VALID);
+}
+
+/*
+ * Set options not to show diffs. For the current window or all windows.
+ * Only in the current tab page.
+ */
+void ex_diffoff(eap)
+exarg_T *eap;
+{
+ win_T *wp;
+ win_T *old_curwin = curwin;
+ int diffwin = FALSE;
+
+ for (wp = firstwin; wp != NULL; wp = wp->w_next) {
+ if (eap->forceit ? wp->w_p_diff : wp == curwin) {
+ /* Set 'diff', 'scrollbind' off and 'wrap' on. If option values
+ * were saved in diff_win_options() restore them. */
+ wp->w_p_diff = FALSE;
+
+ if (wp->w_p_scb)
+ wp->w_p_scb = wp->w_p_diff_saved ? wp->w_p_scb_save : FALSE;
+ if (wp->w_p_crb)
+ wp->w_p_crb = wp->w_p_diff_saved ? wp->w_p_crb_save : FALSE;
+ if (!wp->w_p_wrap)
+ wp->w_p_wrap = wp->w_p_diff_saved ? wp->w_p_wrap_save : TRUE;
+ curwin = wp;
+ curbuf = curwin->w_buffer;
+ if (wp->w_p_diff_saved) {
+ free_string_option(wp->w_p_fdm);
+ wp->w_p_fdm = wp->w_p_fdm_save;
+ wp->w_p_fdm_save = empty_option;
+ } else
+ set_string_option_direct((char_u *)"fdm", -1,
+ (char_u *)"manual", OPT_LOCAL|OPT_FREE, 0);
+ curwin = old_curwin;
+ curbuf = curwin->w_buffer;
+ if (wp->w_p_fdc == diff_foldcolumn)
+ wp->w_p_fdc = wp->w_p_diff_saved ? wp->w_p_fdc_save : 0;
+ if (wp->w_p_fdl == 0 && wp->w_p_diff_saved)
+ wp->w_p_fdl = wp->w_p_fdl_save;
+
+ if (wp->w_p_fen) {
+ /* Only restore 'foldenable' when 'foldmethod' is not
+ * "manual", otherwise we continue to show the diff folds. */
+ if (foldmethodIsManual(wp) || !wp->w_p_diff_saved)
+ wp->w_p_fen = FALSE;
+ else
+ wp->w_p_fen = wp->w_p_fen_save;
+ }
+
+ foldUpdateAll(wp);
+ /* make sure topline is not halfway a fold */
+ changed_window_setting_win(wp);
+ /* Note: 'sbo' is not restored, it's a global option. */
+ diff_buf_adjust(wp);
+
+ wp->w_p_diff_saved = FALSE;
+ }
+ diffwin |= wp->w_p_diff;
+ }
+
+ /* Remove "hor" from from 'scrollopt' if there are no diff windows left. */
+ if (!diffwin && vim_strchr(p_sbo, 'h') != NULL)
+ do_cmdline_cmd((char_u *)"set sbo-=hor");
+}
+
+/*
+ * Read the diff output and add each entry to the diff list.
+ */
+static void diff_read(idx_orig, idx_new, fname)
+int idx_orig; /* idx of original file */
+int idx_new; /* idx of new file */
+char_u *fname; /* name of diff output file */
+{
+ FILE *fd;
+ 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;
+ 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;
+ }
+
+ for (;; ) {
+ if (tag_fgets(linebuf, LBUFLEN, fd))
+ break; /* end of file */
+ if (!isdigit(*linebuf))
+ continue; /* not the start of a diff block */
+
+ /* 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(&p);
+ if (*p == ',') {
+ ++p;
+ l1 = getdigits(&p);
+ } else
+ l1 = f1;
+ if (*p != 'a' && *p != 'c' && *p != 'd')
+ continue; /* invalid diff format */
+ difftype = *p++;
+ f2 = getdigits(&p);
+ if (*p == ',') {
+ ++p;
+ l2 = getdigits(&p);
+ } else
+ l2 = f2;
+ if (l1 < f1 || l2 < f2)
+ continue; /* invalid line range */
+
+ 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;
+ }
+
+ /* Go over blocks before the change, for which orig and new are equal.
+ * Copy blocks from orig to new. */
+ while (dp != NULL
+ && lnum_orig > dp->df_lnum[idx_orig] + dp->df_count[idx_orig]) {
+ if (notset)
+ diff_copy_entry(dprev, dp, idx_orig, idx_new);
+ dprev = dp;
+ dp = dp->df_next;
+ notset = TRUE;
+ }
+
+ if (dp != NULL
+ && lnum_orig <= dp->df_lnum[idx_orig] + dp->df_count[idx_orig]
+ && lnum_orig + count_orig >= dp->df_lnum[idx_orig]) {
+ /* New block overlaps with existing block(s).
+ * First find last block that overlaps. */
+ for (dpl = dp; dpl->df_next != NULL; dpl = dpl->df_next)
+ if (lnum_orig + count_orig < dpl->df_next->df_lnum[idx_orig])
+ break;
+
+ /* If the newly found block starts before the old one, set the
+ * start back a number of lines. */
+ off = dp->df_lnum[idx_orig] - lnum_orig;
+ if (off > 0) {
+ for (i = idx_orig; i < idx_new; ++i)
+ if (curtab->tp_diffbuf[i] != NULL)
+ dp->df_lnum[i] -= off;
+ dp->df_lnum[idx_new] = lnum_new;
+ dp->df_count[idx_new] = count_new;
+ } else if (notset) {
+ /* new block inside existing one, adjust new block */
+ dp->df_lnum[idx_new] = lnum_new + off;
+ dp->df_count[idx_new] = count_new - off;
+ } else
+ /* second overlap of new block with existing block */
+ dp->df_count[idx_new] += count_new - count_orig
+ + dpl->df_lnum[idx_orig] +
+ dpl->df_count[idx_orig]
+ - (dp->df_lnum[idx_orig] +
+ dp->df_count[idx_orig]);
+
+ /* Adjust the size of the block to include all the lines to the
+ * end of the existing block or the new diff, whatever ends last. */
+ off = (lnum_orig + count_orig)
+ - (dpl->df_lnum[idx_orig] + dpl->df_count[idx_orig]);
+ if (off < 0) {
+ /* new change ends in existing block, adjust the end if not
+ * done already */
+ if (notset)
+ dp->df_count[idx_new] += -off;
+ off = 0;
+ }
+ for (i = idx_orig; i < idx_new; ++i)
+ if (curtab->tp_diffbuf[i] != NULL)
+ dp->df_count[i] = dpl->df_lnum[i] + dpl->df_count[i]
+ - dp->df_lnum[i] + off;
+
+ /* Delete the diff blocks that have been merged into one. */
+ dn = dp->df_next;
+ dp->df_next = dpl->df_next;
+ while (dn != dp->df_next) {
+ dpl = dn->df_next;
+ vim_free(dn);
+ dn = dpl;
+ }
+ } else {
+ /* Allocate a new diffblock. */
+ dp = diff_alloc_new(curtab, dprev, dp);
+ if (dp == NULL)
+ goto done;
+
+ dp->df_lnum[idx_orig] = lnum_orig;
+ dp->df_count[idx_orig] = count_orig;
+ dp->df_lnum[idx_new] = lnum_new;
+ dp->df_count[idx_new] = count_new;
+
+ /* Set values for other buffers, these must be equal to the
+ * original buffer, otherwise there would have been a change
+ * already. */
+ for (i = idx_orig + 1; i < idx_new; ++i)
+ if (curtab->tp_diffbuf[i] != NULL)
+ diff_copy_entry(dprev, dp, idx_orig, i);
+ }
+ notset = FALSE; /* "*dp" has been set */
+ }
+
+ /* for remaining diff blocks orig and new are equal */
+ while (dp != NULL) {
+ if (notset)
+ diff_copy_entry(dprev, dp, idx_orig, idx_new);
+ dprev = dp;
+ dp = dp->df_next;
+ notset = TRUE;
+ }
+
+done:
+ fclose(fd);
+}
+
+/*
+ * Copy an entry at "dp" from "idx_orig" to "idx_new".
+ */
+static void diff_copy_entry(dprev, dp, idx_orig, idx_new)
+diff_T *dprev;
+diff_T *dp;
+int idx_orig;
+int idx_new;
+{
+ long off;
+
+ if (dprev == NULL)
+ off = 0;
+ else
+ off = (dprev->df_lnum[idx_orig] + dprev->df_count[idx_orig])
+ - (dprev->df_lnum[idx_new] + dprev->df_count[idx_new]);
+ dp->df_lnum[idx_new] = dp->df_lnum[idx_orig] - off;
+ dp->df_count[idx_new] = dp->df_count[idx_orig];
+}
+
+/*
+ * Clear the list of diffblocks for tab page "tp".
+ */
+void diff_clear(tp)
+tabpage_T *tp;
+{
+ diff_T *p, *next_p;
+
+ for (p = tp->tp_first_diff; p != NULL; p = next_p) {
+ next_p = p->df_next;
+ vim_free(p);
+ }
+ tp->tp_first_diff = NULL;
+}
+
+/*
+ * Check diff status for line "lnum" in buffer "buf":
+ * Returns 0 for nothing special
+ * Returns -1 for a line that should be highlighted as changed.
+ * Returns -2 for a line that should be highlighted as added/deleted.
+ * Returns > 0 for inserting that many filler lines above it (never happens
+ * when 'diffopt' doesn't contain "filler").
+ * This should only be used for windows where 'diff' is set.
+ */
+int diff_check(wp, lnum)
+win_T *wp;
+linenr_T lnum;
+{
+ int idx; /* index in tp_diffbuf[] for this buffer */
+ diff_T *dp;
+ int maxcount;
+ int i;
+ buf_T *buf = wp->w_buffer;
+ int cmp;
+
+ if (curtab->tp_diff_invalid)
+ ex_diffupdate(NULL); /* update after a big change */
+
+ if (curtab->tp_first_diff == NULL || !wp->w_p_diff) /* no diffs at all */
+ return 0;
+
+ /* safety check: "lnum" must be a buffer line */
+ if (lnum < 1 || lnum > buf->b_ml.ml_line_count + 1)
+ return 0;
+
+ idx = diff_buf_idx(buf);
+ if (idx == DB_COUNT)
+ return 0; /* no diffs for buffer "buf" */
+
+ /* A closed fold never has filler lines. */
+ if (hasFoldingWin(wp, lnum, NULL, NULL, TRUE, NULL))
+ return 0;
+
+ /* search for a change that includes "lnum" in the list of diffblocks. */
+ for (dp = curtab->tp_first_diff; dp != NULL; dp = dp->df_next)
+ if (lnum <= dp->df_lnum[idx] + dp->df_count[idx])
+ break;
+ if (dp == NULL || lnum < dp->df_lnum[idx])
+ return 0;
+
+ if (lnum < dp->df_lnum[idx] + dp->df_count[idx]) {
+ 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;
+ for (i = 0; i < DB_COUNT; ++i)
+ if (i != idx && curtab->tp_diffbuf[i] != NULL) {
+ if (dp->df_count[i] == 0)
+ zero = TRUE;
+ else {
+ if (dp->df_count[i] != dp->df_count[idx])
+ return -1; /* nr of lines changed. */
+ cmp = TRUE;
+ }
+ }
+ if (cmp) {
+ /* Compare all lines. If they are equal the lines were inserted
+ * in some buffers, deleted in others, but not changed. */
+ for (i = 0; i < DB_COUNT; ++i)
+ if (i != idx && curtab->tp_diffbuf[i] != NULL && dp->df_count[i] != 0)
+ if (!diff_equal_entry(dp, idx, i))
+ return -1;
+ }
+ /* If there is no buffer with zero lines then there is no difference
+ * any longer. Happens when making a change (or undo) that removes
+ * the difference. Can't remove the entry here, we might be halfway
+ * updating the window. Just report the text as unchanged. Other
+ * windows might still show the change though. */
+ if (zero == FALSE)
+ return 0;
+ return -2;
+ }
+
+ /* If 'diffopt' doesn't contain "filler", return 0. */
+ if (!(diff_flags & DIFF_FILLER))
+ return 0;
+
+ /* Insert filler lines above the line just below the change. Will return
+ * 0 when this buf had the max count. */
+ maxcount = 0;
+ for (i = 0; i < DB_COUNT; ++i)
+ if (curtab->tp_diffbuf[i] != NULL && dp->df_count[i] > maxcount)
+ maxcount = dp->df_count[i];
+ return maxcount - dp->df_count[idx];
+}
+
+/*
+ * Compare two entries in diff "*dp" and return TRUE if they are equal.
+ */
+static int diff_equal_entry(dp, idx1, idx2)
+diff_T *dp;
+int idx1;
+int idx2;
+{
+ int i;
+ char_u *line;
+ int cmp;
+
+ if (dp->df_count[idx1] != dp->df_count[idx2])
+ return FALSE;
+ if (diff_check_sanity(curtab, dp) == FAIL)
+ return FALSE;
+ for (i = 0; i < dp->df_count[idx1]; ++i) {
+ line = vim_strsave(ml_get_buf(curtab->tp_diffbuf[idx1],
+ dp->df_lnum[idx1] + i, FALSE));
+ if (line == NULL)
+ return FALSE;
+ cmp = diff_cmp(line, ml_get_buf(curtab->tp_diffbuf[idx2],
+ dp->df_lnum[idx2] + i, FALSE));
+ vim_free(line);
+ if (cmp != 0)
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/*
+ * Compare strings "s1" and "s2" according to 'diffopt'.
+ * Return non-zero when they are different.
+ */
+static int diff_cmp(s1, s2)
+char_u *s1;
+char_u *s2;
+{
+ char_u *p1, *p2;
+ int l;
+
+ if ((diff_flags & (DIFF_ICASE | DIFF_IWHITE)) == 0)
+ return STRCMP(s1, s2);
+ if ((diff_flags & DIFF_ICASE) && !(diff_flags & DIFF_IWHITE))
+ return MB_STRICMP(s1, s2);
+
+ /* Ignore white space changes and possibly ignore case. */
+ p1 = s1;
+ p2 = s2;
+ while (*p1 != NUL && *p2 != NUL) {
+ if (vim_iswhite(*p1) && vim_iswhite(*p2)) {
+ p1 = skipwhite(p1);
+ p2 = skipwhite(p2);
+ } else {
+ l = (*mb_ptr2len)(p1);
+ if (l != (*mb_ptr2len)(p2))
+ 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;
+ }
+ }
+ }
+
+ /* Ignore trailing white space. */
+ p1 = skipwhite(p1);
+ p2 = skipwhite(p2);
+ if (*p1 != NUL || *p2 != NUL)
+ return 1;
+ return 0;
+}
+
+/*
+ * Return the number of filler lines above "lnum".
+ */
+int diff_check_fill(wp, lnum)
+win_T *wp;
+linenr_T lnum;
+{
+ int n;
+
+ /* be quick when there are no filler lines */
+ if (!(diff_flags & DIFF_FILLER))
+ return 0;
+ n = diff_check(wp, lnum);
+ if (n <= 0)
+ return 0;
+ return n;
+}
+
+/*
+ * Set the topline of "towin" to match the position in "fromwin", so that they
+ * show the same diff'ed lines.
+ */
+void diff_set_topline(fromwin, towin)
+win_T *fromwin;
+win_T *towin;
+{
+ buf_T *frombuf = fromwin->w_buffer;
+ linenr_T lnum = fromwin->w_topline;
+ int fromidx;
+ int toidx;
+ diff_T *dp;
+ int max_count;
+ int i;
+
+ fromidx = diff_buf_idx(frombuf);
+ if (fromidx == DB_COUNT)
+ return; /* safety check */
+
+ if (curtab->tp_diff_invalid)
+ ex_diffupdate(NULL); /* update after a big change */
+
+ towin->w_topfill = 0;
+
+ /* search for a change that includes "lnum" in the list of diffblocks. */
+ for (dp = curtab->tp_first_diff; dp != NULL; dp = dp->df_next)
+ if (lnum <= dp->df_lnum[fromidx] + dp->df_count[fromidx])
+ break;
+ if (dp == NULL) {
+ /* After last change, compute topline relative to end of file; no
+ * filler lines. */
+ towin->w_topline = towin->w_buffer->b_ml.ml_line_count
+ - (frombuf->b_ml.ml_line_count - lnum);
+ } else {
+ /* Find index for "towin". */
+ toidx = diff_buf_idx(towin->w_buffer);
+ if (toidx == DB_COUNT)
+ return; /* safety check */
+
+ towin->w_topline = lnum + (dp->df_lnum[toidx] - dp->df_lnum[fromidx]);
+ if (lnum >= dp->df_lnum[fromidx]) {
+ /* Inside a change: compute filler lines. With three or more
+ * buffers we need to know the largest count. */
+ max_count = 0;
+ for (i = 0; i < DB_COUNT; ++i)
+ if (curtab->tp_diffbuf[i] != NULL
+ && max_count < dp->df_count[i])
+ max_count = dp->df_count[i];
+
+ if (dp->df_count[toidx] == dp->df_count[fromidx]) {
+ /* same number of lines: use same filler count */
+ towin->w_topfill = fromwin->w_topfill;
+ } else if (dp->df_count[toidx] > dp->df_count[fromidx]) {
+ if (lnum == dp->df_lnum[fromidx] + dp->df_count[fromidx]) {
+ /* more lines in towin and fromwin doesn't show diff
+ * lines, only filler lines */
+ if (max_count - fromwin->w_topfill >= dp->df_count[toidx]) {
+ /* towin also only shows filler lines */
+ towin->w_topline = dp->df_lnum[toidx]
+ + dp->df_count[toidx];
+ towin->w_topfill = fromwin->w_topfill;
+ } else
+ /* towin still has some diff lines to show */
+ towin->w_topline = dp->df_lnum[toidx]
+ + max_count - fromwin->w_topfill;
+ }
+ } else if (towin->w_topline >= dp->df_lnum[toidx]
+ + dp->df_count[toidx]) {
+ /* less lines in towin and no diff lines to show: compute
+ * filler lines */
+ towin->w_topline = dp->df_lnum[toidx] + dp->df_count[toidx];
+ if (diff_flags & DIFF_FILLER) {
+ if (lnum == dp->df_lnum[fromidx] + dp->df_count[fromidx])
+ /* fromwin is also out of diff lines */
+ towin->w_topfill = fromwin->w_topfill;
+ else
+ /* fromwin has some diff lines */
+ towin->w_topfill = dp->df_lnum[fromidx]
+ + max_count - lnum;
+ }
+ }
+ }
+ }
+
+ /* safety check (if diff info gets outdated strange things may happen) */
+ towin->w_botfill = FALSE;
+ if (towin->w_topline > towin->w_buffer->b_ml.ml_line_count) {
+ towin->w_topline = towin->w_buffer->b_ml.ml_line_count;
+ towin->w_botfill = TRUE;
+ }
+ if (towin->w_topline < 1) {
+ towin->w_topline = 1;
+ towin->w_topfill = 0;
+ }
+
+ /* When w_topline changes need to recompute w_botline and cursor position */
+ invalidate_botline_win(towin);
+ changed_line_abv_curs_win(towin);
+
+ check_topfill(towin, FALSE);
+ (void)hasFoldingWin(towin, towin->w_topline, &towin->w_topline,
+ NULL, TRUE, NULL);
+}
+
+/*
+ * This is called when 'diffopt' is changed.
+ */
+int diffopt_changed() {
+ char_u *p;
+ int diff_context_new = 6;
+ int diff_flags_new = 0;
+ int diff_foldcolumn_new = 2;
+ tabpage_T *tp;
+
+ p = p_dip;
+ while (*p != NUL) {
+ if (STRNCMP(p, "filler", 6) == 0) {
+ p += 6;
+ diff_flags_new |= DIFF_FILLER;
+ } else if (STRNCMP(p, "context:", 8) == 0 && VIM_ISDIGIT(p[8])) {
+ p += 8;
+ diff_context_new = getdigits(&p);
+ } else if (STRNCMP(p, "icase", 5) == 0) {
+ p += 5;
+ diff_flags_new |= DIFF_ICASE;
+ } else if (STRNCMP(p, "iwhite", 6) == 0) {
+ p += 6;
+ diff_flags_new |= DIFF_IWHITE;
+ } else if (STRNCMP(p, "horizontal", 10) == 0) {
+ p += 10;
+ diff_flags_new |= DIFF_HORIZONTAL;
+ } else if (STRNCMP(p, "vertical", 8) == 0) {
+ p += 8;
+ diff_flags_new |= DIFF_VERTICAL;
+ } else if (STRNCMP(p, "foldcolumn:", 11) == 0 && VIM_ISDIGIT(p[11])) {
+ p += 11;
+ diff_foldcolumn_new = getdigits(&p);
+ }
+ if (*p != ',' && *p != NUL)
+ return FAIL;
+ if (*p == ',')
+ ++p;
+ }
+
+ /* 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)
+ for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
+ tp->tp_diff_invalid = TRUE;
+
+ diff_flags = diff_flags_new;
+ diff_context = diff_context_new;
+ diff_foldcolumn = diff_foldcolumn_new;
+
+ diff_redraw(TRUE);
+
+ /* recompute the scroll binding with the new option value, may
+ * remove or add filler lines */
+ check_scrollbind((linenr_T)0, 0L);
+
+ return OK;
+}
+
+/*
+ * Return TRUE if 'diffopt' contains "horizontal".
+ */
+int diffopt_horizontal() {
+ return (diff_flags & DIFF_HORIZONTAL) != 0;
+}
+
+/*
+ * Find the difference within a changed line.
+ * Returns TRUE if the line was added, no other buffer has it.
+ */
+int diff_find_change(wp, lnum, startp, endp)
+win_T *wp;
+linenr_T lnum;
+int *startp; /* first char of the change */
+int *endp; /* last char of the change */
+{
+ char_u *line_org;
+ char_u *line_new;
+ int i;
+ int si_org, si_new;
+ int ei_org, ei_new;
+ diff_T *dp;
+ int idx;
+ int off;
+ int added = TRUE;
+
+ /* Make a copy of the line, the next ml_get() will invalidate it. */
+ line_org = vim_strsave(ml_get_buf(wp->w_buffer, lnum, FALSE));
+ if (line_org == NULL)
+ return FALSE;
+
+ idx = diff_buf_idx(wp->w_buffer);
+ if (idx == DB_COUNT) { /* cannot happen */
+ vim_free(line_org);
+ return FALSE;
+ }
+
+ /* search for a change that includes "lnum" in the list of diffblocks. */
+ for (dp = curtab->tp_first_diff; dp != NULL; dp = dp->df_next)
+ if (lnum <= dp->df_lnum[idx] + dp->df_count[idx])
+ break;
+ if (dp == NULL || diff_check_sanity(curtab, dp) == FAIL) {
+ vim_free(line_org);
+ return FALSE;
+ }
+
+ off = lnum - dp->df_lnum[idx];
+
+ for (i = 0; i < DB_COUNT; ++i)
+ if (curtab->tp_diffbuf[i] != NULL && i != idx) {
+ /* Skip lines that are not in the other change (filler lines). */
+ if (off >= dp->df_count[i])
+ continue;
+ added = FALSE;
+ line_new = ml_get_buf(curtab->tp_diffbuf[i],
+ 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)
+ && vim_iswhite(line_org[si_org])
+ && vim_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])
+ break;
+ ++si_org;
+ ++si_new;
+ }
+ }
+ 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);
+ }
+ if (*startp > si_org)
+ *startp = si_org;
+
+ /* Search for end of difference, if any. */
+ if (line_org[si_org] != NUL || line_new[si_new] != NUL) {
+ ei_org = (int)STRLEN(line_org);
+ ei_new = (int)STRLEN(line_new);
+ while (ei_org >= *startp && ei_new >= si_new
+ && ei_org >= 0 && ei_new >= 0) {
+ if ((diff_flags & DIFF_IWHITE)
+ && vim_iswhite(line_org[ei_org])
+ && vim_iswhite(line_new[ei_new])) {
+ while (ei_org >= *startp
+ && vim_iswhite(line_org[ei_org]))
+ --ei_org;
+ while (ei_new >= si_new
+ && vim_iswhite(line_new[ei_new]))
+ --ei_new;
+ } else {
+ if (line_org[ei_org] != line_new[ei_new])
+ break;
+ --ei_org;
+ --ei_new;
+ }
+ }
+ if (*endp < ei_org)
+ *endp = ei_org;
+ }
+ }
+
+ vim_free(line_org);
+ return added;
+}
+
+/*
+ * Return TRUE if line "lnum" is not close to a diff block, this line should
+ * be in a fold.
+ * Return FALSE if there are no diff blocks at all in this window.
+ */
+int diff_infold(wp, lnum)
+win_T *wp;
+linenr_T lnum;
+{
+ int i;
+ int idx = -1;
+ int other = FALSE;
+ diff_T *dp;
+
+ /* Return if 'diff' isn't set. */
+ if (!wp->w_p_diff)
+ return FALSE;
+
+ for (i = 0; i < DB_COUNT; ++i) {
+ if (curtab->tp_diffbuf[i] == wp->w_buffer)
+ idx = i;
+ else if (curtab->tp_diffbuf[i] != NULL)
+ other = TRUE;
+ }
+
+ /* return here if there are no diffs in the window */
+ if (idx == -1 || !other)
+ return FALSE;
+
+ if (curtab->tp_diff_invalid)
+ ex_diffupdate(NULL); /* update after a big change */
+
+ /* Return if there are no diff blocks. All lines will be folded. */
+ if (curtab->tp_first_diff == NULL)
+ return TRUE;
+
+ for (dp = curtab->tp_first_diff; dp != NULL; dp = dp->df_next) {
+ /* If this change is below the line there can't be any further match. */
+ if (dp->df_lnum[idx] - diff_context > lnum)
+ break;
+ /* If this change ends before the line we have a match. */
+ if (dp->df_lnum[idx] + dp->df_count[idx] + diff_context > lnum)
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/*
+ * "dp" and "do" commands.
+ */
+void nv_diffgetput(put)
+int put;
+{
+ exarg_T ea;
+
+ ea.arg = (char_u *)"";
+ if (put)
+ ea.cmdidx = CMD_diffput;
+ else
+ ea.cmdidx = CMD_diffget;
+ ea.addr_count = 0;
+ ea.line1 = curwin->w_cursor.lnum;
+ ea.line2 = curwin->w_cursor.lnum;
+ ex_diffgetput(&ea);
+}
+
+/*
+ * ":diffget"
+ * ":diffput"
+ */
+void ex_diffgetput(eap)
+exarg_T *eap;
+{
+ linenr_T lnum;
+ int count;
+ linenr_T off = 0;
+ diff_T *dp;
+ diff_T *dprev;
+ diff_T *dfree;
+ int idx_cur;
+ int idx_other;
+ int idx_from;
+ int idx_to;
+ int i;
+ int added;
+ char_u *p;
+ aco_save_T aco;
+ buf_T *buf;
+ int start_skip, end_skip;
+ int new_count;
+ int buf_empty;
+ int found_not_ma = FALSE;
+
+ /* Find the current buffer in the list of diff buffers. */
+ idx_cur = diff_buf_idx(curbuf);
+ if (idx_cur == DB_COUNT) {
+ EMSG(_("E99: Current buffer is not in diff mode"));
+ return;
+ }
+
+ if (*eap->arg == NUL) {
+ /* No argument: Find the other buffer in the list of diff buffers. */
+ for (idx_other = 0; idx_other < DB_COUNT; ++idx_other)
+ if (curtab->tp_diffbuf[idx_other] != curbuf
+ && curtab->tp_diffbuf[idx_other] != NULL) {
+ if (eap->cmdidx != CMD_diffput
+ || curtab->tp_diffbuf[idx_other]->b_p_ma)
+ break;
+ found_not_ma = TRUE;
+ }
+ if (idx_other == DB_COUNT) {
+ if (found_not_ma)
+ EMSG(_("E793: No other buffer in diff mode is modifiable"));
+ else
+ EMSG(_("E100: No other buffer in diff mode"));
+ return;
+ }
+
+ /* Check that there isn't a third buffer in the list */
+ for (i = idx_other + 1; i < DB_COUNT; ++i)
+ if (curtab->tp_diffbuf[i] != curbuf
+ && curtab->tp_diffbuf[i] != NULL
+ && (eap->cmdidx != CMD_diffput || curtab->tp_diffbuf[i]->b_p_ma)) {
+ EMSG(_(
+ "E101: More than two buffers in diff mode, don't know which one to use"));
+ return;
+ }
+ } else {
+ /* Buffer number or pattern given. Ignore trailing white space. */
+ p = eap->arg + STRLEN(eap->arg);
+ while (p > eap->arg && vim_iswhite(p[-1]))
+ --p;
+ for (i = 0; vim_isdigit(eap->arg[i]) && eap->arg + i < p; ++i)
+ ;
+ if (eap->arg + i == p) /* digits only */
+ i = atol((char *)eap->arg);
+ else {
+ i = buflist_findpat(eap->arg, p, FALSE, TRUE, FALSE);
+ if (i < 0)
+ return; /* error message already given */
+ }
+ buf = buflist_findnr(i);
+ if (buf == NULL) {
+ EMSG2(_("E102: Can't find buffer \"%s\""), eap->arg);
+ return;
+ }
+ if (buf == curbuf)
+ return; /* nothing to do */
+ idx_other = diff_buf_idx(buf);
+ if (idx_other == DB_COUNT) {
+ EMSG2(_("E103: Buffer \"%s\" is not in diff mode"), eap->arg);
+ return;
+ }
+ }
+
+ diff_busy = TRUE;
+
+ /* When no range given include the line above or below the cursor. */
+ if (eap->addr_count == 0) {
+ /* Make it possible that ":diffget" on the last line gets line below
+ * the cursor line when there is no difference above the cursor. */
+ if (eap->cmdidx == CMD_diffget
+ && eap->line1 == curbuf->b_ml.ml_line_count
+ && diff_check(curwin, eap->line1) == 0
+ && (eap->line1 == 1 || diff_check(curwin, eap->line1 - 1) == 0))
+ ++eap->line2;
+ else if (eap->line1 > 0)
+ --eap->line1;
+ }
+
+ if (eap->cmdidx == CMD_diffget) {
+ idx_from = idx_other;
+ idx_to = idx_cur;
+ } else {
+ idx_from = idx_cur;
+ idx_to = idx_other;
+ /* Need to make the other buffer the current buffer to be able to make
+ * changes in it. */
+ /* set curwin/curbuf to buf and save a few things */
+ aucmd_prepbuf(&aco, curtab->tp_diffbuf[idx_other]);
+ }
+
+ /* May give the warning for a changed buffer here, which can trigger the
+ * FileChangedRO autocommand, which may do nasty things and mess
+ * everything up. */
+ if (!curbuf->b_changed) {
+ change_warning(0);
+ if (diff_buf_idx(curbuf) != idx_to) {
+ EMSG(_("E787: Buffer changed unexpectedly"));
+ return;
+ }
+ }
+
+ dprev = NULL;
+ for (dp = curtab->tp_first_diff; dp != NULL; ) {
+ if (dp->df_lnum[idx_cur] > eap->line2 + off)
+ break; /* past the range that was specified */
+
+ dfree = NULL;
+ lnum = dp->df_lnum[idx_to];
+ count = dp->df_count[idx_to];
+ if (dp->df_lnum[idx_cur] + dp->df_count[idx_cur] > eap->line1 + off
+ && u_save(lnum - 1, lnum + count) != FAIL) {
+ /* Inside the specified range and saving for undo worked. */
+ start_skip = 0;
+ end_skip = 0;
+ if (eap->addr_count > 0) {
+ /* A range was specified: check if lines need to be skipped. */
+ start_skip = eap->line1 + off - dp->df_lnum[idx_cur];
+ if (start_skip > 0) {
+ /* range starts below start of current diff block */
+ if (start_skip > count) {
+ lnum += count;
+ count = 0;
+ } else {
+ count -= start_skip;
+ lnum += start_skip;
+ }
+ } else
+ start_skip = 0;
+
+ end_skip = dp->df_lnum[idx_cur] + dp->df_count[idx_cur] - 1
+ - (eap->line2 + off);
+ if (end_skip > 0) {
+ /* range ends above end of current/from diff block */
+ if (idx_cur == idx_from) { /* :diffput */
+ i = dp->df_count[idx_cur] - start_skip - end_skip;
+ if (count > i)
+ count = i;
+ } else { /* :diffget */
+ count -= end_skip;
+ end_skip = dp->df_count[idx_from] - start_skip - count;
+ if (end_skip < 0)
+ end_skip = 0;
+ }
+ } else
+ end_skip = 0;
+ }
+
+ buf_empty = FALSE;
+ 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);
+ --added;
+ }
+ for (i = 0; i < dp->df_count[idx_from] - start_skip - end_skip; ++i) {
+ linenr_T nr;
+
+ nr = dp->df_lnum[idx_from] + start_skip + i;
+ 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));
+ if (p != NULL) {
+ ml_append(lnum + i - 1, p, 0, FALSE);
+ vim_free(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);
+ }
+ }
+ }
+ new_count = dp->df_count[idx_to] + added;
+ dp->df_count[idx_to] = new_count;
+
+ if (start_skip == 0 && end_skip == 0) {
+ /* Check if there are any other buffers and if the diff is
+ * equal in them. */
+ for (i = 0; i < DB_COUNT; ++i)
+ if (curtab->tp_diffbuf[i] != NULL && i != idx_from
+ && i != idx_to
+ && !diff_equal_entry(dp, idx_from, i))
+ break;
+ if (i == DB_COUNT) {
+ /* delete the diff entry, the buffers are now equal here */
+ dfree = dp;
+ dp = dp->df_next;
+ if (dprev == NULL)
+ curtab->tp_first_diff = dp;
+ else
+ dprev->df_next = dp;
+ }
+ }
+
+ /* Adjust marks. This will change the following entries! */
+ if (added != 0) {
+ mark_adjust(lnum, lnum + count - 1, (long)MAXLNUM, (long)added);
+ if (curwin->w_cursor.lnum >= lnum) {
+ /* Adjust the cursor position if it's in/after the changed
+ * lines. */
+ if (curwin->w_cursor.lnum >= lnum + count)
+ curwin->w_cursor.lnum += added;
+ else if (added < 0)
+ curwin->w_cursor.lnum = lnum;
+ }
+ }
+ changed_lines(lnum, 0, lnum + count, (long)added);
+
+ if (dfree != NULL) {
+ /* Diff is deleted, update folds in other windows. */
+ diff_fold_update(dfree, idx_to);
+ vim_free(dfree);
+ } else
+ /* mark_adjust() may have changed the count in a wrong way */
+ dp->df_count[idx_to] = new_count;
+
+ /* When changing the current buffer, keep track of line numbers */
+ if (idx_cur == idx_to)
+ off += added;
+ }
+
+ /* If before the range or not deleted, go to next diff. */
+ if (dfree == NULL) {
+ dprev = dp;
+ dp = dp->df_next;
+ }
+ }
+
+ /* restore curwin/curbuf and a few other things */
+ if (eap->cmdidx != CMD_diffget) {
+ /* Syncing undo only works for the current buffer, but we change
+ * 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);
+ aucmd_restbuf(&aco);
+ }
+
+ diff_busy = FALSE;
+
+ /* 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_cursor();
+ changed_line_abv_curs();
+
+ /* Also need to redraw the other buffers. */
+ diff_redraw(FALSE);
+}
+
+/*
+ * Update folds for all diff buffers for entry "dp".
+ * Skip buffer with index "skip_idx".
+ * When there are no diffs, all folds are removed.
+ */
+static void diff_fold_update(dp, skip_idx)
+diff_T *dp;
+int skip_idx;
+{
+ int i;
+ win_T *wp;
+
+ for (wp = firstwin; wp != NULL; wp = wp->w_next)
+ for (i = 0; i < DB_COUNT; ++i)
+ if (curtab->tp_diffbuf[i] == wp->w_buffer && i != skip_idx)
+ foldUpdate(wp, dp->df_lnum[i],
+ dp->df_lnum[i] + dp->df_count[i]);
+}
+
+/*
+ * Return TRUE if buffer "buf" is in diff-mode.
+ */
+int diff_mode_buf(buf)
+buf_T *buf;
+{
+ tabpage_T *tp;
+
+ for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
+ if (diff_buf_idx_tp(buf, tp) != DB_COUNT)
+ return TRUE;
+ return FALSE;
+}
+
+/*
+ * Move "count" times in direction "dir" to the next diff block.
+ * Return FAIL if there isn't such a diff block.
+ */
+int diff_move_to(dir, count)
+int dir;
+long count;
+{
+ int idx;
+ linenr_T lnum = curwin->w_cursor.lnum;
+ diff_T *dp;
+
+ idx = diff_buf_idx(curbuf);
+ if (idx == DB_COUNT || curtab->tp_first_diff == NULL)
+ return FAIL;
+
+ if (curtab->tp_diff_invalid)
+ ex_diffupdate(NULL); /* update after a big change */
+
+ if (curtab->tp_first_diff == NULL) /* no diffs today */
+ return FAIL;
+
+ while (--count >= 0) {
+ /* Check if already before first diff. */
+ if (dir == BACKWARD && lnum <= curtab->tp_first_diff->df_lnum[idx])
+ break;
+
+ for (dp = curtab->tp_first_diff;; dp = dp->df_next) {
+ if (dp == NULL)
+ break;
+ if ((dir == FORWARD && lnum < dp->df_lnum[idx])
+ || (dir == BACKWARD
+ && (dp->df_next == NULL
+ || lnum <= dp->df_next->df_lnum[idx]))) {
+ lnum = dp->df_lnum[idx];
+ break;
+ }
+ }
+ }
+
+ /* don't end up past the end of the file */
+ if (lnum > curbuf->b_ml.ml_line_count)
+ lnum = curbuf->b_ml.ml_line_count;
+
+ /* When the cursor didn't move at all we fail. */
+ if (lnum == curwin->w_cursor.lnum)
+ return FAIL;
+
+ setpcmark();
+ curwin->w_cursor.lnum = lnum;
+ curwin->w_cursor.col = 0;
+
+ return OK;
+}
+
+linenr_T diff_get_corresponding_line(buf1, lnum1, buf2, lnum3)
+buf_T *buf1;
+linenr_T lnum1;
+buf_T *buf2;
+linenr_T lnum3;
+{
+ int idx1;
+ int idx2;
+ diff_T *dp;
+ int baseline = 0;
+ linenr_T lnum2;
+
+ idx1 = diff_buf_idx(buf1);
+ idx2 = diff_buf_idx(buf2);
+ if (idx1 == DB_COUNT || idx2 == DB_COUNT || curtab->tp_first_diff == NULL)
+ return lnum1;
+
+ if (curtab->tp_diff_invalid)
+ ex_diffupdate(NULL); /* update after a big change */
+
+ if (curtab->tp_first_diff == NULL) /* no diffs today */
+ return lnum1;
+
+ 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) {
+ /* Inside the diffblock */
+ baseline = lnum1 - dp->df_lnum[idx1];
+ if (baseline > dp->df_count[idx2])
+ baseline = dp->df_count[idx2];
+
+ 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))
+ /*
+ * 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;
+ baseline = (dp->df_lnum[idx1] + dp->df_count[idx1])
+ - (dp->df_lnum[idx2] + dp->df_count[idx2]);
+ }
+
+ /* If we get here then the cursor is after the last diff */
+ 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;
+}
+
+/*
+ * For line "lnum" in the current window find the equivalent lnum in window
+ * "wp", compensating for inserted/deleted lines.
+ */
+linenr_T diff_lnum_win(lnum, wp)
+linenr_T lnum;
+win_T *wp;
+{
+ diff_T *dp;
+ int idx;
+ int i;
+ linenr_T n;
+
+ idx = diff_buf_idx(curbuf);
+ if (idx == DB_COUNT) /* safety check */
+ return (linenr_T)0;
+
+ if (curtab->tp_diff_invalid)
+ ex_diffupdate(NULL); /* update after a big change */
+
+ /* search for a change that includes "lnum" in the list of diffblocks. */
+ for (dp = curtab->tp_first_diff; dp != NULL; dp = dp->df_next)
+ if (lnum <= dp->df_lnum[idx] + dp->df_count[idx])
+ break;
+
+ /* When after the last change, compute relative to the last line number. */
+ if (dp == NULL)
+ return wp->w_buffer->b_ml.ml_line_count
+ - (curbuf->b_ml.ml_line_count - lnum);
+
+ /* Find index for "wp". */
+ i = diff_buf_idx(wp->w_buffer);
+ if (i == DB_COUNT) /* safety check */
+ return (linenr_T)0;
+
+ n = lnum + (dp->df_lnum[i] - dp->df_lnum[idx]);
+ if (n > dp->df_lnum[i] + dp->df_count[i])
+ n = dp->df_lnum[i] + dp->df_count[i];
+ return n;
+}
+
diff --git a/src/digraph.c b/src/digraph.c
new file mode 100644
index 0000000000..4584973526
--- /dev/null
+++ b/src/digraph.c
@@ -0,0 +1,2074 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * 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.
+ */
+
+/*
+ * digraph.c: code for digraphs
+ */
+
+#include "vim.h"
+
+
+typedef int result_T;
+
+typedef struct digraph {
+ char_u char1;
+ char_u char2;
+ result_T result;
+} digr_T;
+
+static int getexactdigraph __ARGS((int, int, int));
+static void printdigraph __ARGS((digr_T *));
+
+/* digraphs added by the user */
+static garray_T user_digraphs = {0, 0, (int)sizeof(digr_T), 10, NULL};
+
+/*
+ * Note: Characters marked with XX are not included literally, because some
+ * compilers cannot handle them (Amiga SAS/C is the most picky one).
+ */
+static digr_T digraphdefault[] =
+# ifdef HPUX_DIGRAPHS
+
+/*
+ * different HPUX digraphs
+ */
+{{'A', '`', 161}, /* ¡ */
+ {'A', '^', 162}, /* ¢ */
+ {'E', '`', 163}, /* £ */
+ {'E', '^', 164}, /* ¤ */
+ {'E', '"', 165}, /* ¥ */
+ {'I', '^', 166}, /* ¦ */
+ {'I', '"', 167}, /* § */
+ {'\'', '\'', 168}, /* ¨ */
+ {'`', '`', 169}, /* © */
+ {'^', '^', 170}, /* ª */
+ {'"', '"', 171}, /* « */
+ {'~', '~', 172}, /* ¬ */
+ {'U', '`', 173}, /* ­ */
+ {'U', '^', 174}, /* ® */
+ {'L', '=', 175}, /* ¯ */
+ {'~', '_', 176}, /* ° */
+ {'Y', '\'', 177}, /* ± */
+ {'y', '\'', 178}, /* ² */
+ {'~', 'o', 179}, /* ³ */
+ {'C', ',', 180}, /* ´ */
+ {'c', ',', 181}, /* µ */
+ {'N', '~', 182}, /* ¶ */
+ {'n', '~', 183}, /* · */
+ {'~', '!', 184}, /* ¸ */
+ {'~', '?', 185}, /* ¹ */
+ {'o', 'x', 186}, /* º */
+ {'L', '-', 187}, /* » */
+ {'Y', '=', 188}, /* ¼ */
+ {'p', 'p', 189}, /* ½ */
+ {'f', 'l', 190}, /* ¾ */
+ {'c', '|', 191}, /* ¿ */
+ {'a', '^', 192}, /* À */
+ {'e', '^', 193}, /* Á */
+ {'o', '^', 194}, /* Â */
+ {'u', '^', 195}, /* Ã */
+ {'a', '\'', 196}, /* Ä */
+ {'e', '\'', 197}, /* Å */
+ {'o', '\'', 198}, /* Æ */
+ {'u', '\'', 199}, /* Ç */
+ {'a', '`', 200}, /* È */
+ {'e', '`', 201}, /* É */
+ {'o', '`', 202}, /* Ê */
+ {'u', '`', 203}, /* Ë */
+ {'a', '"', 204}, /* Ì */
+ {'e', '"', 205}, /* Í */
+ {'o', '"', 206}, /* Î */
+ {'u', '"', 207}, /* Ï */
+ {'A', 'o', 208}, /* Ð */
+ {'i', '^', 209}, /* Ñ */
+ {'O', '/', 210}, /* Ò */
+ {'A', 'E', 211}, /* Ó */
+ {'a', 'o', 212}, /* Ô */
+ {'i', '\'', 213}, /* Õ */
+ {'o', '/', 214}, /* Ö */
+ {'a', 'e', 215}, /* × */
+ {'A', '"', 216}, /* Ø */
+ {'i', '`', 217}, /* Ù */
+ {'O', '"', 218}, /* Ú */
+ {'U', '"', 219}, /* Û */
+ {'E', '\'', 220}, /* Ü */
+ {'i', '"', 221}, /* Ý */
+ {'s', 's', 222}, /* Þ */
+ {'O', '^', 223}, /* ß */
+ {'A', '\'', 224}, /* à */
+ {'A', '~', 225}, /* á */
+ {'a', '~', 226}, /* â */
+ {'D', '-', 227}, /* ã */
+ {'d', '-', 228}, /* ä */
+ {'I', '\'', 229}, /* å */
+ {'I', '`', 230}, /* æ */
+ {'O', '\'', 231}, /* ç */
+ {'O', '`', 232}, /* è */
+ {'O', '~', 233}, /* é */
+ {'o', '~', 234}, /* ê */
+ {'S', '~', 235}, /* ë */
+ {'s', '~', 236}, /* ì */
+ {'U', '\'', 237}, /* í */
+ {'Y', '"', 238}, /* î */
+ {'y', '"', 239}, /* ï */
+ {'p', '-', 240}, /* ð */
+ {'p', '~', 241}, /* ñ */
+ {'~', '.', 242}, /* ò */
+ {'j', 'u', 243}, /* ó */
+ {'P', 'p', 244}, /* ô */
+ {'3', '4', 245}, /* õ */
+ {'-', '-', 246}, /* ö */
+ {'1', '4', 247}, /* ÷ */
+ {'1', '2', 248}, /* ø */
+ {'a', '_', 249}, /* ù */
+ {'o', '_', 250}, /* ú */
+ {'<', '<', 251}, /* û */
+ {'x', 'x', 252}, /* ü */
+ {'>', '>', 253}, /* ý */
+ {'+', '-', 254}, /* þ */
+ {'n', 'u', 255}, /* x XX */
+ {NUL, NUL, NUL}};
+
+# else /* !HPUX_DIGRAPHS */
+
+
+# ifdef OLD_DIGRAPHS
+
+/*
+ * digraphs compatible with Vim 5.x
+ */
+{{'~', '!', 161}, /* ¡ */
+ {'c', '|', 162}, /* ¢ */
+ {'$', '$', 163}, /* £ */
+ {'o', 'x', 164}, /* ¤ - currency symbol in ISO 8859-1 */
+ {'e', '=', 164}, /* ¤ - euro symbol in ISO 8859-15 */
+ {'Y', '-', 165}, /* ¥ */
+ {'|', '|', 166}, /* ¦ */
+ {'p', 'a', 167}, /* § */
+ {'"', '"', 168}, /* ¨ */
+ {'c', 'O', 169}, /* © */
+ {'a', '-', 170}, /* ª */
+ {'<', '<', 171}, /* « */
+ {'-', ',', 172}, /* ¬ */
+ {'-', '-', 173}, /* ­ */
+ {'r', 'O', 174}, /* ® */
+ {'-', '=', 175}, /* ¯ */
+ {'~', 'o', 176}, /* ° */
+ {'+', '-', 177}, /* ± */
+ {'2', '2', 178}, /* ² */
+ {'3', '3', 179}, /* ³ */
+ {'\'', '\'', 180}, /* ´ */
+ {'j', 'u', 181}, /* µ */
+ {'p', 'p', 182}, /* ¶ */
+ {'~', '.', 183}, /* · */
+ {',', ',', 184}, /* ¸ */
+ {'1', '1', 185}, /* ¹ */
+ {'o', '-', 186}, /* º */
+ {'>', '>', 187}, /* » */
+ {'1', '4', 188}, /* ¼ */
+ {'1', '2', 189}, /* ½ */
+ {'3', '4', 190}, /* ¾ */
+ {'~', '?', 191}, /* ¿ */
+ {'A', '`', 192}, /* À */
+ {'A', '\'', 193}, /* Á */
+ {'A', '^', 194}, /* Â */
+ {'A', '~', 195}, /* Ã */
+ {'A', '"', 196}, /* Ä */
+ {'A', '@', 197}, /* Å */
+ {'A', 'A', 197}, /* Å */
+ {'A', 'E', 198}, /* Æ */
+ {'C', ',', 199}, /* Ç */
+ {'E', '`', 200}, /* È */
+ {'E', '\'', 201}, /* É */
+ {'E', '^', 202}, /* Ê */
+ {'E', '"', 203}, /* Ë */
+ {'I', '`', 204}, /* Ì */
+ {'I', '\'', 205}, /* Í */
+ {'I', '^', 206}, /* Î */
+ {'I', '"', 207}, /* Ï */
+ {'D', '-', 208}, /* Ð */
+ {'N', '~', 209}, /* Ñ */
+ {'O', '`', 210}, /* Ò */
+ {'O', '\'', 211}, /* Ó */
+ {'O', '^', 212}, /* Ô */
+ {'O', '~', 213}, /* Õ */
+ {'O', '"', 214}, /* Ö */
+ {'/', '\\', 215}, /* × - multiplication symbol in ISO 8859-1 */
+ {'O', 'E', 215}, /* × - OE in ISO 8859-15 */
+ {'O', '/', 216}, /* Ø */
+ {'U', '`', 217}, /* Ù */
+ {'U', '\'', 218}, /* Ú */
+ {'U', '^', 219}, /* Û */
+ {'U', '"', 220}, /* Ü */
+ {'Y', '\'', 221}, /* Ý */
+ {'I', 'p', 222}, /* Þ */
+ {'s', 's', 223}, /* ß */
+ {'a', '`', 224}, /* à */
+ {'a', '\'', 225}, /* á */
+ {'a', '^', 226}, /* â */
+ {'a', '~', 227}, /* ã */
+ {'a', '"', 228}, /* ä */
+ {'a', '@', 229}, /* å */
+ {'a', 'a', 229}, /* å */
+ {'a', 'e', 230}, /* æ */
+ {'c', ',', 231}, /* ç */
+ {'e', '`', 232}, /* è */
+ {'e', '\'', 233}, /* é */
+ {'e', '^', 234}, /* ê */
+ {'e', '"', 235}, /* ë */
+ {'i', '`', 236}, /* ì */
+ {'i', '\'', 237}, /* í */
+ {'i', '^', 238}, /* î */
+ {'i', '"', 239}, /* ï */
+ {'d', '-', 240}, /* ð */
+ {'n', '~', 241}, /* ñ */
+ {'o', '`', 242}, /* ò */
+ {'o', '\'', 243}, /* ó */
+ {'o', '^', 244}, /* ô */
+ {'o', '~', 245}, /* õ */
+ {'o', '"', 246}, /* ö */
+ {':', '-', 247}, /* ÷ - division symbol in ISO 8859-1 */
+ {'o', 'e', 247}, /* ÷ - oe in ISO 8859-15 */
+ {'o', '/', 248}, /* ø */
+ {'u', '`', 249}, /* ù */
+ {'u', '\'', 250}, /* ú */
+ {'u', '^', 251}, /* û */
+ {'u', '"', 252}, /* ü */
+ {'y', '\'', 253}, /* ý */
+ {'i', 'p', 254}, /* þ */
+ {'y', '"', 255}, /* x XX */
+ {NUL, NUL, NUL}};
+# else /* OLD_DIGRAPHS */
+
+/*
+ * digraphs for Unicode from RFC1345
+ * (also work for ISO-8859-1 aka latin1)
+ */
+{
+ {'N', 'U', 0x0a}, /* LF for NUL */
+ {'S', 'H', 0x01},
+ {'S', 'X', 0x02},
+ {'E', 'X', 0x03},
+ {'E', 'T', 0x04},
+ {'E', 'Q', 0x05},
+ {'A', 'K', 0x06},
+ {'B', 'L', 0x07},
+ {'B', 'S', 0x08},
+ {'H', 'T', 0x09},
+ {'L', 'F', 0x0a},
+ {'V', 'T', 0x0b},
+ {'F', 'F', 0x0c},
+ {'C', 'R', 0x0d},
+ {'S', 'O', 0x0e},
+ {'S', 'I', 0x0f},
+ {'D', 'L', 0x10},
+ {'D', '1', 0x11},
+ {'D', '2', 0x12},
+ {'D', '3', 0x13},
+ {'D', '4', 0x14},
+ {'N', 'K', 0x15},
+ {'S', 'Y', 0x16},
+ {'E', 'B', 0x17},
+ {'C', 'N', 0x18},
+ {'E', 'M', 0x19},
+ {'S', 'B', 0x1a},
+ {'E', 'C', 0x1b},
+ {'F', 'S', 0x1c},
+ {'G', 'S', 0x1d},
+ {'R', 'S', 0x1e},
+ {'U', 'S', 0x1f},
+ {'S', 'P', 0x20},
+ {'N', 'b', 0x23},
+ {'D', 'O', 0x24},
+ {'A', 't', 0x40},
+ {'<', '(', 0x5b},
+ {'/', '/', 0x5c},
+ {')', '>', 0x5d},
+ {'\'', '>', 0x5e},
+ {'\'', '!', 0x60},
+ {'(', '!', 0x7b},
+ {'!', '!', 0x7c},
+ {'!', ')', 0x7d},
+ {'\'', '?', 0x7e},
+ {'D', 'T', 0x7f},
+ {'P', 'A', 0x80},
+ {'H', 'O', 0x81},
+ {'B', 'H', 0x82},
+ {'N', 'H', 0x83},
+ {'I', 'N', 0x84},
+ {'N', 'L', 0x85},
+ {'S', 'A', 0x86},
+ {'E', 'S', 0x87},
+ {'H', 'S', 0x88},
+ {'H', 'J', 0x89},
+ {'V', 'S', 0x8a},
+ {'P', 'D', 0x8b},
+ {'P', 'U', 0x8c},
+ {'R', 'I', 0x8d},
+ {'S', '2', 0x8e},
+ {'S', '3', 0x8f},
+ {'D', 'C', 0x90},
+ {'P', '1', 0x91},
+ {'P', '2', 0x92},
+ {'T', 'S', 0x93},
+ {'C', 'C', 0x94},
+ {'M', 'W', 0x95},
+ {'S', 'G', 0x96},
+ {'E', 'G', 0x97},
+ {'S', 'S', 0x98},
+ {'G', 'C', 0x99},
+ {'S', 'C', 0x9a},
+ {'C', 'I', 0x9b},
+ {'S', 'T', 0x9c},
+ {'O', 'C', 0x9d},
+ {'P', 'M', 0x9e},
+ {'A', 'C', 0x9f},
+ {'N', 'S', 0xa0},
+ {'!', 'I', 0xa1},
+ {'C', 't', 0xa2},
+ {'P', 'd', 0xa3},
+ {'C', 'u', 0xa4},
+ {'Y', 'e', 0xa5},
+ {'B', 'B', 0xa6},
+ {'S', 'E', 0xa7},
+ {'\'', ':', 0xa8},
+ {'C', 'o', 0xa9},
+ {'-', 'a', 0xaa},
+ {'<', '<', 0xab},
+ {'N', 'O', 0xac},
+ {'-', '-', 0xad},
+ {'R', 'g', 0xae},
+ {'\'', 'm', 0xaf},
+ {'D', 'G', 0xb0},
+ {'+', '-', 0xb1},
+ {'2', 'S', 0xb2},
+ {'3', 'S', 0xb3},
+ {'\'', '\'', 0xb4},
+ {'M', 'y', 0xb5},
+ {'P', 'I', 0xb6},
+ {'.', 'M', 0xb7},
+ {'\'', ',', 0xb8},
+ {'1', 'S', 0xb9},
+ {'-', 'o', 0xba},
+ {'>', '>', 0xbb},
+ {'1', '4', 0xbc},
+ {'1', '2', 0xbd},
+ {'3', '4', 0xbe},
+ {'?', 'I', 0xbf},
+ {'A', '!', 0xc0},
+ {'A', '\'', 0xc1},
+ {'A', '>', 0xc2},
+ {'A', '?', 0xc3},
+ {'A', ':', 0xc4},
+ {'A', 'A', 0xc5},
+ {'A', 'E', 0xc6},
+ {'C', ',', 0xc7},
+ {'E', '!', 0xc8},
+ {'E', '\'', 0xc9},
+ {'E', '>', 0xca},
+ {'E', ':', 0xcb},
+ {'I', '!', 0xcc},
+ {'I', '\'', 0xcd},
+ {'I', '>', 0xce},
+ {'I', ':', 0xcf},
+ {'D', '-', 0xd0},
+ {'N', '?', 0xd1},
+ {'O', '!', 0xd2},
+ {'O', '\'', 0xd3},
+ {'O', '>', 0xd4},
+ {'O', '?', 0xd5},
+ {'O', ':', 0xd6},
+ {'*', 'X', 0xd7},
+ {'O', '/', 0xd8},
+ {'U', '!', 0xd9},
+ {'U', '\'', 0xda},
+ {'U', '>', 0xdb},
+ {'U', ':', 0xdc},
+ {'Y', '\'', 0xdd},
+ {'T', 'H', 0xde},
+ {'s', 's', 0xdf},
+ {'a', '!', 0xe0},
+ {'a', '\'', 0xe1},
+ {'a', '>', 0xe2},
+ {'a', '?', 0xe3},
+ {'a', ':', 0xe4},
+ {'a', 'a', 0xe5},
+ {'a', 'e', 0xe6},
+ {'c', ',', 0xe7},
+ {'e', '!', 0xe8},
+ {'e', '\'', 0xe9},
+ {'e', '>', 0xea},
+ {'e', ':', 0xeb},
+ {'i', '!', 0xec},
+ {'i', '\'', 0xed},
+ {'i', '>', 0xee},
+ {'i', ':', 0xef},
+ {'d', '-', 0xf0},
+ {'n', '?', 0xf1},
+ {'o', '!', 0xf2},
+ {'o', '\'', 0xf3},
+ {'o', '>', 0xf4},
+ {'o', '?', 0xf5},
+ {'o', ':', 0xf6},
+ {'-', ':', 0xf7},
+ {'o', '/', 0xf8},
+ {'u', '!', 0xf9},
+ {'u', '\'', 0xfa},
+ {'u', '>', 0xfb},
+ {'u', ':', 0xfc},
+ {'y', '\'', 0xfd},
+ {'t', 'h', 0xfe},
+ {'y', ':', 0xff},
+
+# define USE_UNICODE_DIGRAPHS
+
+ {'A', '-', 0x0100},
+ {'a', '-', 0x0101},
+ {'A', '(', 0x0102},
+ {'a', '(', 0x0103},
+ {'A', ';', 0x0104},
+ {'a', ';', 0x0105},
+ {'C', '\'', 0x0106},
+ {'c', '\'', 0x0107},
+ {'C', '>', 0x0108},
+ {'c', '>', 0x0109},
+ {'C', '.', 0x010a},
+ {'c', '.', 0x010b},
+ {'C', '<', 0x010c},
+ {'c', '<', 0x010d},
+ {'D', '<', 0x010e},
+ {'d', '<', 0x010f},
+ {'D', '/', 0x0110},
+ {'d', '/', 0x0111},
+ {'E', '-', 0x0112},
+ {'e', '-', 0x0113},
+ {'E', '(', 0x0114},
+ {'e', '(', 0x0115},
+ {'E', '.', 0x0116},
+ {'e', '.', 0x0117},
+ {'E', ';', 0x0118},
+ {'e', ';', 0x0119},
+ {'E', '<', 0x011a},
+ {'e', '<', 0x011b},
+ {'G', '>', 0x011c},
+ {'g', '>', 0x011d},
+ {'G', '(', 0x011e},
+ {'g', '(', 0x011f},
+ {'G', '.', 0x0120},
+ {'g', '.', 0x0121},
+ {'G', ',', 0x0122},
+ {'g', ',', 0x0123},
+ {'H', '>', 0x0124},
+ {'h', '>', 0x0125},
+ {'H', '/', 0x0126},
+ {'h', '/', 0x0127},
+ {'I', '?', 0x0128},
+ {'i', '?', 0x0129},
+ {'I', '-', 0x012a},
+ {'i', '-', 0x012b},
+ {'I', '(', 0x012c},
+ {'i', '(', 0x012d},
+ {'I', ';', 0x012e},
+ {'i', ';', 0x012f},
+ {'I', '.', 0x0130},
+ {'i', '.', 0x0131},
+ {'I', 'J', 0x0132},
+ {'i', 'j', 0x0133},
+ {'J', '>', 0x0134},
+ {'j', '>', 0x0135},
+ {'K', ',', 0x0136},
+ {'k', ',', 0x0137},
+ {'k', 'k', 0x0138},
+ {'L', '\'', 0x0139},
+ {'l', '\'', 0x013a},
+ {'L', ',', 0x013b},
+ {'l', ',', 0x013c},
+ {'L', '<', 0x013d},
+ {'l', '<', 0x013e},
+ {'L', '.', 0x013f},
+ {'l', '.', 0x0140},
+ {'L', '/', 0x0141},
+ {'l', '/', 0x0142},
+ {'N', '\'', 0x0143},
+ {'n', '\'', 0x0144},
+ {'N', ',', 0x0145},
+ {'n', ',', 0x0146},
+ {'N', '<', 0x0147},
+ {'n', '<', 0x0148},
+ {'\'', 'n', 0x0149},
+ {'N', 'G', 0x014a},
+ {'n', 'g', 0x014b},
+ {'O', '-', 0x014c},
+ {'o', '-', 0x014d},
+ {'O', '(', 0x014e},
+ {'o', '(', 0x014f},
+ {'O', '"', 0x0150},
+ {'o', '"', 0x0151},
+ {'O', 'E', 0x0152},
+ {'o', 'e', 0x0153},
+ {'R', '\'', 0x0154},
+ {'r', '\'', 0x0155},
+ {'R', ',', 0x0156},
+ {'r', ',', 0x0157},
+ {'R', '<', 0x0158},
+ {'r', '<', 0x0159},
+ {'S', '\'', 0x015a},
+ {'s', '\'', 0x015b},
+ {'S', '>', 0x015c},
+ {'s', '>', 0x015d},
+ {'S', ',', 0x015e},
+ {'s', ',', 0x015f},
+ {'S', '<', 0x0160},
+ {'s', '<', 0x0161},
+ {'T', ',', 0x0162},
+ {'t', ',', 0x0163},
+ {'T', '<', 0x0164},
+ {'t', '<', 0x0165},
+ {'T', '/', 0x0166},
+ {'t', '/', 0x0167},
+ {'U', '?', 0x0168},
+ {'u', '?', 0x0169},
+ {'U', '-', 0x016a},
+ {'u', '-', 0x016b},
+ {'U', '(', 0x016c},
+ {'u', '(', 0x016d},
+ {'U', '0', 0x016e},
+ {'u', '0', 0x016f},
+ {'U', '"', 0x0170},
+ {'u', '"', 0x0171},
+ {'U', ';', 0x0172},
+ {'u', ';', 0x0173},
+ {'W', '>', 0x0174},
+ {'w', '>', 0x0175},
+ {'Y', '>', 0x0176},
+ {'y', '>', 0x0177},
+ {'Y', ':', 0x0178},
+ {'Z', '\'', 0x0179},
+ {'z', '\'', 0x017a},
+ {'Z', '.', 0x017b},
+ {'z', '.', 0x017c},
+ {'Z', '<', 0x017d},
+ {'z', '<', 0x017e},
+ {'O', '9', 0x01a0},
+ {'o', '9', 0x01a1},
+ {'O', 'I', 0x01a2},
+ {'o', 'i', 0x01a3},
+ {'y', 'r', 0x01a6},
+ {'U', '9', 0x01af},
+ {'u', '9', 0x01b0},
+ {'Z', '/', 0x01b5},
+ {'z', '/', 0x01b6},
+ {'E', 'D', 0x01b7},
+ {'A', '<', 0x01cd},
+ {'a', '<', 0x01ce},
+ {'I', '<', 0x01cf},
+ {'i', '<', 0x01d0},
+ {'O', '<', 0x01d1},
+ {'o', '<', 0x01d2},
+ {'U', '<', 0x01d3},
+ {'u', '<', 0x01d4},
+ {'A', '1', 0x01de},
+ {'a', '1', 0x01df},
+ {'A', '7', 0x01e0},
+ {'a', '7', 0x01e1},
+ {'A', '3', 0x01e2},
+ {'a', '3', 0x01e3},
+ {'G', '/', 0x01e4},
+ {'g', '/', 0x01e5},
+ {'G', '<', 0x01e6},
+ {'g', '<', 0x01e7},
+ {'K', '<', 0x01e8},
+ {'k', '<', 0x01e9},
+ {'O', ';', 0x01ea},
+ {'o', ';', 0x01eb},
+ {'O', '1', 0x01ec},
+ {'o', '1', 0x01ed},
+ {'E', 'Z', 0x01ee},
+ {'e', 'z', 0x01ef},
+ {'j', '<', 0x01f0},
+ {'G', '\'', 0x01f4},
+ {'g', '\'', 0x01f5},
+ {';', 'S', 0x02bf},
+ {'\'', '<', 0x02c7},
+ {'\'', '(', 0x02d8},
+ {'\'', '.', 0x02d9},
+ {'\'', '0', 0x02da},
+ {'\'', ';', 0x02db},
+ {'\'', '"', 0x02dd},
+ {'A', '%', 0x0386},
+ {'E', '%', 0x0388},
+ {'Y', '%', 0x0389},
+ {'I', '%', 0x038a},
+ {'O', '%', 0x038c},
+ {'U', '%', 0x038e},
+ {'W', '%', 0x038f},
+ {'i', '3', 0x0390},
+ {'A', '*', 0x0391},
+ {'B', '*', 0x0392},
+ {'G', '*', 0x0393},
+ {'D', '*', 0x0394},
+ {'E', '*', 0x0395},
+ {'Z', '*', 0x0396},
+ {'Y', '*', 0x0397},
+ {'H', '*', 0x0398},
+ {'I', '*', 0x0399},
+ {'K', '*', 0x039a},
+ {'L', '*', 0x039b},
+ {'M', '*', 0x039c},
+ {'N', '*', 0x039d},
+ {'C', '*', 0x039e},
+ {'O', '*', 0x039f},
+ {'P', '*', 0x03a0},
+ {'R', '*', 0x03a1},
+ {'S', '*', 0x03a3},
+ {'T', '*', 0x03a4},
+ {'U', '*', 0x03a5},
+ {'F', '*', 0x03a6},
+ {'X', '*', 0x03a7},
+ {'Q', '*', 0x03a8},
+ {'W', '*', 0x03a9},
+ {'J', '*', 0x03aa},
+ {'V', '*', 0x03ab},
+ {'a', '%', 0x03ac},
+ {'e', '%', 0x03ad},
+ {'y', '%', 0x03ae},
+ {'i', '%', 0x03af},
+ {'u', '3', 0x03b0},
+ {'a', '*', 0x03b1},
+ {'b', '*', 0x03b2},
+ {'g', '*', 0x03b3},
+ {'d', '*', 0x03b4},
+ {'e', '*', 0x03b5},
+ {'z', '*', 0x03b6},
+ {'y', '*', 0x03b7},
+ {'h', '*', 0x03b8},
+ {'i', '*', 0x03b9},
+ {'k', '*', 0x03ba},
+ {'l', '*', 0x03bb},
+ {'m', '*', 0x03bc},
+ {'n', '*', 0x03bd},
+ {'c', '*', 0x03be},
+ {'o', '*', 0x03bf},
+ {'p', '*', 0x03c0},
+ {'r', '*', 0x03c1},
+ {'*', 's', 0x03c2},
+ {'s', '*', 0x03c3},
+ {'t', '*', 0x03c4},
+ {'u', '*', 0x03c5},
+ {'f', '*', 0x03c6},
+ {'x', '*', 0x03c7},
+ {'q', '*', 0x03c8},
+ {'w', '*', 0x03c9},
+ {'j', '*', 0x03ca},
+ {'v', '*', 0x03cb},
+ {'o', '%', 0x03cc},
+ {'u', '%', 0x03cd},
+ {'w', '%', 0x03ce},
+ {'\'', 'G', 0x03d8},
+ {',', 'G', 0x03d9},
+ {'T', '3', 0x03da},
+ {'t', '3', 0x03db},
+ {'M', '3', 0x03dc},
+ {'m', '3', 0x03dd},
+ {'K', '3', 0x03de},
+ {'k', '3', 0x03df},
+ {'P', '3', 0x03e0},
+ {'p', '3', 0x03e1},
+ {'\'', '%', 0x03f4},
+ {'j', '3', 0x03f5},
+ {'I', 'O', 0x0401},
+ {'D', '%', 0x0402},
+ {'G', '%', 0x0403},
+ {'I', 'E', 0x0404},
+ {'D', 'S', 0x0405},
+ {'I', 'I', 0x0406},
+ {'Y', 'I', 0x0407},
+ {'J', '%', 0x0408},
+ {'L', 'J', 0x0409},
+ {'N', 'J', 0x040a},
+ {'T', 's', 0x040b},
+ {'K', 'J', 0x040c},
+ {'V', '%', 0x040e},
+ {'D', 'Z', 0x040f},
+ {'A', '=', 0x0410},
+ {'B', '=', 0x0411},
+ {'V', '=', 0x0412},
+ {'G', '=', 0x0413},
+ {'D', '=', 0x0414},
+ {'E', '=', 0x0415},
+ {'Z', '%', 0x0416},
+ {'Z', '=', 0x0417},
+ {'I', '=', 0x0418},
+ {'J', '=', 0x0419},
+ {'K', '=', 0x041a},
+ {'L', '=', 0x041b},
+ {'M', '=', 0x041c},
+ {'N', '=', 0x041d},
+ {'O', '=', 0x041e},
+ {'P', '=', 0x041f},
+ {'R', '=', 0x0420},
+ {'S', '=', 0x0421},
+ {'T', '=', 0x0422},
+ {'U', '=', 0x0423},
+ {'F', '=', 0x0424},
+ {'H', '=', 0x0425},
+ {'C', '=', 0x0426},
+ {'C', '%', 0x0427},
+ {'S', '%', 0x0428},
+ {'S', 'c', 0x0429},
+ {'=', '"', 0x042a},
+ {'Y', '=', 0x042b},
+ {'%', '"', 0x042c},
+ {'J', 'E', 0x042d},
+ {'J', 'U', 0x042e},
+ {'J', 'A', 0x042f},
+ {'a', '=', 0x0430},
+ {'b', '=', 0x0431},
+ {'v', '=', 0x0432},
+ {'g', '=', 0x0433},
+ {'d', '=', 0x0434},
+ {'e', '=', 0x0435},
+ {'z', '%', 0x0436},
+ {'z', '=', 0x0437},
+ {'i', '=', 0x0438},
+ {'j', '=', 0x0439},
+ {'k', '=', 0x043a},
+ {'l', '=', 0x043b},
+ {'m', '=', 0x043c},
+ {'n', '=', 0x043d},
+ {'o', '=', 0x043e},
+ {'p', '=', 0x043f},
+ {'r', '=', 0x0440},
+ {'s', '=', 0x0441},
+ {'t', '=', 0x0442},
+ {'u', '=', 0x0443},
+ {'f', '=', 0x0444},
+ {'h', '=', 0x0445},
+ {'c', '=', 0x0446},
+ {'c', '%', 0x0447},
+ {'s', '%', 0x0448},
+ {'s', 'c', 0x0449},
+ {'=', '\'', 0x044a},
+ {'y', '=', 0x044b},
+ {'%', '\'', 0x044c},
+ {'j', 'e', 0x044d},
+ {'j', 'u', 0x044e},
+ {'j', 'a', 0x044f},
+ {'i', 'o', 0x0451},
+ {'d', '%', 0x0452},
+ {'g', '%', 0x0453},
+ {'i', 'e', 0x0454},
+ {'d', 's', 0x0455},
+ {'i', 'i', 0x0456},
+ {'y', 'i', 0x0457},
+ {'j', '%', 0x0458},
+ {'l', 'j', 0x0459},
+ {'n', 'j', 0x045a},
+ {'t', 's', 0x045b},
+ {'k', 'j', 0x045c},
+ {'v', '%', 0x045e},
+ {'d', 'z', 0x045f},
+ {'Y', '3', 0x0462},
+ {'y', '3', 0x0463},
+ {'O', '3', 0x046a},
+ {'o', '3', 0x046b},
+ {'F', '3', 0x0472},
+ {'f', '3', 0x0473},
+ {'V', '3', 0x0474},
+ {'v', '3', 0x0475},
+ {'C', '3', 0x0480},
+ {'c', '3', 0x0481},
+ {'G', '3', 0x0490},
+ {'g', '3', 0x0491},
+ {'A', '+', 0x05d0},
+ {'B', '+', 0x05d1},
+ {'G', '+', 0x05d2},
+ {'D', '+', 0x05d3},
+ {'H', '+', 0x05d4},
+ {'W', '+', 0x05d5},
+ {'Z', '+', 0x05d6},
+ {'X', '+', 0x05d7},
+ {'T', 'j', 0x05d8},
+ {'J', '+', 0x05d9},
+ {'K', '%', 0x05da},
+ {'K', '+', 0x05db},
+ {'L', '+', 0x05dc},
+ {'M', '%', 0x05dd},
+ {'M', '+', 0x05de},
+ {'N', '%', 0x05df},
+ {'N', '+', 0x05e0},
+ {'S', '+', 0x05e1},
+ {'E', '+', 0x05e2},
+ {'P', '%', 0x05e3},
+ {'P', '+', 0x05e4},
+ {'Z', 'j', 0x05e5},
+ {'Z', 'J', 0x05e6},
+ {'Q', '+', 0x05e7},
+ {'R', '+', 0x05e8},
+ {'S', 'h', 0x05e9},
+ {'T', '+', 0x05ea},
+ {',', '+', 0x060c},
+ {';', '+', 0x061b},
+ {'?', '+', 0x061f},
+ {'H', '\'', 0x0621},
+ {'a', 'M', 0x0622},
+ {'a', 'H', 0x0623},
+ {'w', 'H', 0x0624},
+ {'a', 'h', 0x0625},
+ {'y', 'H', 0x0626},
+ {'a', '+', 0x0627},
+ {'b', '+', 0x0628},
+ {'t', 'm', 0x0629},
+ {'t', '+', 0x062a},
+ {'t', 'k', 0x062b},
+ {'g', '+', 0x062c},
+ {'h', 'k', 0x062d},
+ {'x', '+', 0x062e},
+ {'d', '+', 0x062f},
+ {'d', 'k', 0x0630},
+ {'r', '+', 0x0631},
+ {'z', '+', 0x0632},
+ {'s', '+', 0x0633},
+ {'s', 'n', 0x0634},
+ {'c', '+', 0x0635},
+ {'d', 'd', 0x0636},
+ {'t', 'j', 0x0637},
+ {'z', 'H', 0x0638},
+ {'e', '+', 0x0639},
+ {'i', '+', 0x063a},
+ {'+', '+', 0x0640},
+ {'f', '+', 0x0641},
+ {'q', '+', 0x0642},
+ {'k', '+', 0x0643},
+ {'l', '+', 0x0644},
+ {'m', '+', 0x0645},
+ {'n', '+', 0x0646},
+ {'h', '+', 0x0647},
+ {'w', '+', 0x0648},
+ {'j', '+', 0x0649},
+ {'y', '+', 0x064a},
+ {':', '+', 0x064b},
+ {'"', '+', 0x064c},
+ {'=', '+', 0x064d},
+ {'/', '+', 0x064e},
+ {'\'', '+', 0x064f},
+ {'1', '+', 0x0650},
+ {'3', '+', 0x0651},
+ {'0', '+', 0x0652},
+ {'a', 'S', 0x0670},
+ {'p', '+', 0x067e},
+ {'v', '+', 0x06a4},
+ {'g', 'f', 0x06af},
+ {'0', 'a', 0x06f0},
+ {'1', 'a', 0x06f1},
+ {'2', 'a', 0x06f2},
+ {'3', 'a', 0x06f3},
+ {'4', 'a', 0x06f4},
+ {'5', 'a', 0x06f5},
+ {'6', 'a', 0x06f6},
+ {'7', 'a', 0x06f7},
+ {'8', 'a', 0x06f8},
+ {'9', 'a', 0x06f9},
+ {'B', '.', 0x1e02},
+ {'b', '.', 0x1e03},
+ {'B', '_', 0x1e06},
+ {'b', '_', 0x1e07},
+ {'D', '.', 0x1e0a},
+ {'d', '.', 0x1e0b},
+ {'D', '_', 0x1e0e},
+ {'d', '_', 0x1e0f},
+ {'D', ',', 0x1e10},
+ {'d', ',', 0x1e11},
+ {'F', '.', 0x1e1e},
+ {'f', '.', 0x1e1f},
+ {'G', '-', 0x1e20},
+ {'g', '-', 0x1e21},
+ {'H', '.', 0x1e22},
+ {'h', '.', 0x1e23},
+ {'H', ':', 0x1e26},
+ {'h', ':', 0x1e27},
+ {'H', ',', 0x1e28},
+ {'h', ',', 0x1e29},
+ {'K', '\'', 0x1e30},
+ {'k', '\'', 0x1e31},
+ {'K', '_', 0x1e34},
+ {'k', '_', 0x1e35},
+ {'L', '_', 0x1e3a},
+ {'l', '_', 0x1e3b},
+ {'M', '\'', 0x1e3e},
+ {'m', '\'', 0x1e3f},
+ {'M', '.', 0x1e40},
+ {'m', '.', 0x1e41},
+ {'N', '.', 0x1e44},
+ {'n', '.', 0x1e45},
+ {'N', '_', 0x1e48},
+ {'n', '_', 0x1e49},
+ {'P', '\'', 0x1e54},
+ {'p', '\'', 0x1e55},
+ {'P', '.', 0x1e56},
+ {'p', '.', 0x1e57},
+ {'R', '.', 0x1e58},
+ {'r', '.', 0x1e59},
+ {'R', '_', 0x1e5e},
+ {'r', '_', 0x1e5f},
+ {'S', '.', 0x1e60},
+ {'s', '.', 0x1e61},
+ {'T', '.', 0x1e6a},
+ {'t', '.', 0x1e6b},
+ {'T', '_', 0x1e6e},
+ {'t', '_', 0x1e6f},
+ {'V', '?', 0x1e7c},
+ {'v', '?', 0x1e7d},
+ {'W', '!', 0x1e80},
+ {'w', '!', 0x1e81},
+ {'W', '\'', 0x1e82},
+ {'w', '\'', 0x1e83},
+ {'W', ':', 0x1e84},
+ {'w', ':', 0x1e85},
+ {'W', '.', 0x1e86},
+ {'w', '.', 0x1e87},
+ {'X', '.', 0x1e8a},
+ {'x', '.', 0x1e8b},
+ {'X', ':', 0x1e8c},
+ {'x', ':', 0x1e8d},
+ {'Y', '.', 0x1e8e},
+ {'y', '.', 0x1e8f},
+ {'Z', '>', 0x1e90},
+ {'z', '>', 0x1e91},
+ {'Z', '_', 0x1e94},
+ {'z', '_', 0x1e95},
+ {'h', '_', 0x1e96},
+ {'t', ':', 0x1e97},
+ {'w', '0', 0x1e98},
+ {'y', '0', 0x1e99},
+ {'A', '2', 0x1ea2},
+ {'a', '2', 0x1ea3},
+ {'E', '2', 0x1eba},
+ {'e', '2', 0x1ebb},
+ {'E', '?', 0x1ebc},
+ {'e', '?', 0x1ebd},
+ {'I', '2', 0x1ec8},
+ {'i', '2', 0x1ec9},
+ {'O', '2', 0x1ece},
+ {'o', '2', 0x1ecf},
+ {'U', '2', 0x1ee6},
+ {'u', '2', 0x1ee7},
+ {'Y', '!', 0x1ef2},
+ {'y', '!', 0x1ef3},
+ {'Y', '2', 0x1ef6},
+ {'y', '2', 0x1ef7},
+ {'Y', '?', 0x1ef8},
+ {'y', '?', 0x1ef9},
+ {';', '\'', 0x1f00},
+ {',', '\'', 0x1f01},
+ {';', '!', 0x1f02},
+ {',', '!', 0x1f03},
+ {'?', ';', 0x1f04},
+ {'?', ',', 0x1f05},
+ {'!', ':', 0x1f06},
+ {'?', ':', 0x1f07},
+ {'1', 'N', 0x2002},
+ {'1', 'M', 0x2003},
+ {'3', 'M', 0x2004},
+ {'4', 'M', 0x2005},
+ {'6', 'M', 0x2006},
+ {'1', 'T', 0x2009},
+ {'1', 'H', 0x200a},
+ {'-', '1', 0x2010},
+ {'-', 'N', 0x2013},
+ {'-', 'M', 0x2014},
+ {'-', '3', 0x2015},
+ {'!', '2', 0x2016},
+ {'=', '2', 0x2017},
+ {'\'', '6', 0x2018},
+ {'\'', '9', 0x2019},
+ {'.', '9', 0x201a},
+ {'9', '\'', 0x201b},
+ {'"', '6', 0x201c},
+ {'"', '9', 0x201d},
+ {':', '9', 0x201e},
+ {'9', '"', 0x201f},
+ {'/', '-', 0x2020},
+ {'/', '=', 0x2021},
+ {'.', '.', 0x2025},
+ {'%', '0', 0x2030},
+ {'1', '\'', 0x2032},
+ {'2', '\'', 0x2033},
+ {'3', '\'', 0x2034},
+ {'1', '"', 0x2035},
+ {'2', '"', 0x2036},
+ {'3', '"', 0x2037},
+ {'C', 'a', 0x2038},
+ {'<', '1', 0x2039},
+ {'>', '1', 0x203a},
+ {':', 'X', 0x203b},
+ {'\'', '-', 0x203e},
+ {'/', 'f', 0x2044},
+ {'0', 'S', 0x2070},
+ {'4', 'S', 0x2074},
+ {'5', 'S', 0x2075},
+ {'6', 'S', 0x2076},
+ {'7', 'S', 0x2077},
+ {'8', 'S', 0x2078},
+ {'9', 'S', 0x2079},
+ {'+', 'S', 0x207a},
+ {'-', 'S', 0x207b},
+ {'=', 'S', 0x207c},
+ {'(', 'S', 0x207d},
+ {')', 'S', 0x207e},
+ {'n', 'S', 0x207f},
+ {'0', 's', 0x2080},
+ {'1', 's', 0x2081},
+ {'2', 's', 0x2082},
+ {'3', 's', 0x2083},
+ {'4', 's', 0x2084},
+ {'5', 's', 0x2085},
+ {'6', 's', 0x2086},
+ {'7', 's', 0x2087},
+ {'8', 's', 0x2088},
+ {'9', 's', 0x2089},
+ {'+', 's', 0x208a},
+ {'-', 's', 0x208b},
+ {'=', 's', 0x208c},
+ {'(', 's', 0x208d},
+ {')', 's', 0x208e},
+ {'L', 'i', 0x20a4},
+ {'P', 't', 0x20a7},
+ {'W', '=', 0x20a9},
+ {'=', 'e', 0x20ac}, /* euro */
+ {'E', 'u', 0x20ac}, /* euro */
+ {'o', 'C', 0x2103},
+ {'c', 'o', 0x2105},
+ {'o', 'F', 0x2109},
+ {'N', '0', 0x2116},
+ {'P', 'O', 0x2117},
+ {'R', 'x', 0x211e},
+ {'S', 'M', 0x2120},
+ {'T', 'M', 0x2122},
+ {'O', 'm', 0x2126},
+ {'A', 'O', 0x212b},
+ {'1', '3', 0x2153},
+ {'2', '3', 0x2154},
+ {'1', '5', 0x2155},
+ {'2', '5', 0x2156},
+ {'3', '5', 0x2157},
+ {'4', '5', 0x2158},
+ {'1', '6', 0x2159},
+ {'5', '6', 0x215a},
+ {'1', '8', 0x215b},
+ {'3', '8', 0x215c},
+ {'5', '8', 0x215d},
+ {'7', '8', 0x215e},
+ {'1', 'R', 0x2160},
+ {'2', 'R', 0x2161},
+ {'3', 'R', 0x2162},
+ {'4', 'R', 0x2163},
+ {'5', 'R', 0x2164},
+ {'6', 'R', 0x2165},
+ {'7', 'R', 0x2166},
+ {'8', 'R', 0x2167},
+ {'9', 'R', 0x2168},
+ {'a', 'R', 0x2169},
+ {'b', 'R', 0x216a},
+ {'c', 'R', 0x216b},
+ {'1', 'r', 0x2170},
+ {'2', 'r', 0x2171},
+ {'3', 'r', 0x2172},
+ {'4', 'r', 0x2173},
+ {'5', 'r', 0x2174},
+ {'6', 'r', 0x2175},
+ {'7', 'r', 0x2176},
+ {'8', 'r', 0x2177},
+ {'9', 'r', 0x2178},
+ {'a', 'r', 0x2179},
+ {'b', 'r', 0x217a},
+ {'c', 'r', 0x217b},
+ {'<', '-', 0x2190},
+ {'-', '!', 0x2191},
+ {'-', '>', 0x2192},
+ {'-', 'v', 0x2193},
+ {'<', '>', 0x2194},
+ {'U', 'D', 0x2195},
+ {'<', '=', 0x21d0},
+ {'=', '>', 0x21d2},
+ {'=', '=', 0x21d4},
+ {'F', 'A', 0x2200},
+ {'d', 'P', 0x2202},
+ {'T', 'E', 0x2203},
+ {'/', '0', 0x2205},
+ {'D', 'E', 0x2206},
+ {'N', 'B', 0x2207},
+ {'(', '-', 0x2208},
+ {'-', ')', 0x220b},
+ {'*', 'P', 0x220f},
+ {'+', 'Z', 0x2211},
+ {'-', '2', 0x2212},
+ {'-', '+', 0x2213},
+ {'*', '-', 0x2217},
+ {'O', 'b', 0x2218},
+ {'S', 'b', 0x2219},
+ {'R', 'T', 0x221a},
+ {'0', '(', 0x221d},
+ {'0', '0', 0x221e},
+ {'-', 'L', 0x221f},
+ {'-', 'V', 0x2220},
+ {'P', 'P', 0x2225},
+ {'A', 'N', 0x2227},
+ {'O', 'R', 0x2228},
+ {'(', 'U', 0x2229},
+ {')', 'U', 0x222a},
+ {'I', 'n', 0x222b},
+ {'D', 'I', 0x222c},
+ {'I', 'o', 0x222e},
+ {'.', ':', 0x2234},
+ {':', '.', 0x2235},
+ {':', 'R', 0x2236},
+ {':', ':', 0x2237},
+ {'?', '1', 0x223c},
+ {'C', 'G', 0x223e},
+ {'?', '-', 0x2243},
+ {'?', '=', 0x2245},
+ {'?', '2', 0x2248},
+ {'=', '?', 0x224c},
+ {'H', 'I', 0x2253},
+ {'!', '=', 0x2260},
+ {'=', '3', 0x2261},
+ {'=', '<', 0x2264},
+ {'>', '=', 0x2265},
+ {'<', '*', 0x226a},
+ {'*', '>', 0x226b},
+ {'!', '<', 0x226e},
+ {'!', '>', 0x226f},
+ {'(', 'C', 0x2282},
+ {')', 'C', 0x2283},
+ {'(', '_', 0x2286},
+ {')', '_', 0x2287},
+ {'0', '.', 0x2299},
+ {'0', '2', 0x229a},
+ {'-', 'T', 0x22a5},
+ {'.', 'P', 0x22c5},
+ {':', '3', 0x22ee},
+ {'.', '3', 0x22ef},
+ {'E', 'h', 0x2302},
+ {'<', '7', 0x2308},
+ {'>', '7', 0x2309},
+ {'7', '<', 0x230a},
+ {'7', '>', 0x230b},
+ {'N', 'I', 0x2310},
+ {'(', 'A', 0x2312},
+ {'T', 'R', 0x2315},
+ {'I', 'u', 0x2320},
+ {'I', 'l', 0x2321},
+ {'<', '/', 0x2329},
+ {'/', '>', 0x232a},
+ {'V', 's', 0x2423},
+ {'1', 'h', 0x2440},
+ {'3', 'h', 0x2441},
+ {'2', 'h', 0x2442},
+ {'4', 'h', 0x2443},
+ {'1', 'j', 0x2446},
+ {'2', 'j', 0x2447},
+ {'3', 'j', 0x2448},
+ {'4', 'j', 0x2449},
+ {'1', '.', 0x2488},
+ {'2', '.', 0x2489},
+ {'3', '.', 0x248a},
+ {'4', '.', 0x248b},
+ {'5', '.', 0x248c},
+ {'6', '.', 0x248d},
+ {'7', '.', 0x248e},
+ {'8', '.', 0x248f},
+ {'9', '.', 0x2490},
+ {'h', 'h', 0x2500},
+ {'H', 'H', 0x2501},
+ {'v', 'v', 0x2502},
+ {'V', 'V', 0x2503},
+ {'3', '-', 0x2504},
+ {'3', '_', 0x2505},
+ {'3', '!', 0x2506},
+ {'3', '/', 0x2507},
+ {'4', '-', 0x2508},
+ {'4', '_', 0x2509},
+ {'4', '!', 0x250a},
+ {'4', '/', 0x250b},
+ {'d', 'r', 0x250c},
+ {'d', 'R', 0x250d},
+ {'D', 'r', 0x250e},
+ {'D', 'R', 0x250f},
+ {'d', 'l', 0x2510},
+ {'d', 'L', 0x2511},
+ {'D', 'l', 0x2512},
+ {'L', 'D', 0x2513},
+ {'u', 'r', 0x2514},
+ {'u', 'R', 0x2515},
+ {'U', 'r', 0x2516},
+ {'U', 'R', 0x2517},
+ {'u', 'l', 0x2518},
+ {'u', 'L', 0x2519},
+ {'U', 'l', 0x251a},
+ {'U', 'L', 0x251b},
+ {'v', 'r', 0x251c},
+ {'v', 'R', 0x251d},
+ {'V', 'r', 0x2520},
+ {'V', 'R', 0x2523},
+ {'v', 'l', 0x2524},
+ {'v', 'L', 0x2525},
+ {'V', 'l', 0x2528},
+ {'V', 'L', 0x252b},
+ {'d', 'h', 0x252c},
+ {'d', 'H', 0x252f},
+ {'D', 'h', 0x2530},
+ {'D', 'H', 0x2533},
+ {'u', 'h', 0x2534},
+ {'u', 'H', 0x2537},
+ {'U', 'h', 0x2538},
+ {'U', 'H', 0x253b},
+ {'v', 'h', 0x253c},
+ {'v', 'H', 0x253f},
+ {'V', 'h', 0x2542},
+ {'V', 'H', 0x254b},
+ {'F', 'D', 0x2571},
+ {'B', 'D', 0x2572},
+ {'T', 'B', 0x2580},
+ {'L', 'B', 0x2584},
+ {'F', 'B', 0x2588},
+ {'l', 'B', 0x258c},
+ {'R', 'B', 0x2590},
+ {'.', 'S', 0x2591},
+ {':', 'S', 0x2592},
+ {'?', 'S', 0x2593},
+ {'f', 'S', 0x25a0},
+ {'O', 'S', 0x25a1},
+ {'R', 'O', 0x25a2},
+ {'R', 'r', 0x25a3},
+ {'R', 'F', 0x25a4},
+ {'R', 'Y', 0x25a5},
+ {'R', 'H', 0x25a6},
+ {'R', 'Z', 0x25a7},
+ {'R', 'K', 0x25a8},
+ {'R', 'X', 0x25a9},
+ {'s', 'B', 0x25aa},
+ {'S', 'R', 0x25ac},
+ {'O', 'r', 0x25ad},
+ {'U', 'T', 0x25b2},
+ {'u', 'T', 0x25b3},
+ {'P', 'R', 0x25b6},
+ {'T', 'r', 0x25b7},
+ {'D', 't', 0x25bc},
+ {'d', 'T', 0x25bd},
+ {'P', 'L', 0x25c0},
+ {'T', 'l', 0x25c1},
+ {'D', 'b', 0x25c6},
+ {'D', 'w', 0x25c7},
+ {'L', 'Z', 0x25ca},
+ {'0', 'm', 0x25cb},
+ {'0', 'o', 0x25ce},
+ {'0', 'M', 0x25cf},
+ {'0', 'L', 0x25d0},
+ {'0', 'R', 0x25d1},
+ {'S', 'n', 0x25d8},
+ {'I', 'c', 0x25d9},
+ {'F', 'd', 0x25e2},
+ {'B', 'd', 0x25e3},
+ {'*', '2', 0x2605},
+ {'*', '1', 0x2606},
+ {'<', 'H', 0x261c},
+ {'>', 'H', 0x261e},
+ {'0', 'u', 0x263a},
+ {'0', 'U', 0x263b},
+ {'S', 'U', 0x263c},
+ {'F', 'm', 0x2640},
+ {'M', 'l', 0x2642},
+ {'c', 'S', 0x2660},
+ {'c', 'H', 0x2661},
+ {'c', 'D', 0x2662},
+ {'c', 'C', 0x2663},
+ {'M', 'd', 0x2669},
+ {'M', '8', 0x266a},
+ {'M', '2', 0x266b},
+ {'M', 'b', 0x266d},
+ {'M', 'x', 0x266e},
+ {'M', 'X', 0x266f},
+ {'O', 'K', 0x2713},
+ {'X', 'X', 0x2717},
+ {'-', 'X', 0x2720},
+ {'I', 'S', 0x3000},
+ {',', '_', 0x3001},
+ {'.', '_', 0x3002},
+ {'+', '"', 0x3003},
+ {'+', '_', 0x3004},
+ {'*', '_', 0x3005},
+ {';', '_', 0x3006},
+ {'0', '_', 0x3007},
+ {'<', '+', 0x300a},
+ {'>', '+', 0x300b},
+ {'<', '\'', 0x300c},
+ {'>', '\'', 0x300d},
+ {'<', '"', 0x300e},
+ {'>', '"', 0x300f},
+ {'(', '"', 0x3010},
+ {')', '"', 0x3011},
+ {'=', 'T', 0x3012},
+ {'=', '_', 0x3013},
+ {'(', '\'', 0x3014},
+ {')', '\'', 0x3015},
+ {'(', 'I', 0x3016},
+ {')', 'I', 0x3017},
+ {'-', '?', 0x301c},
+ {'A', '5', 0x3041},
+ {'a', '5', 0x3042},
+ {'I', '5', 0x3043},
+ {'i', '5', 0x3044},
+ {'U', '5', 0x3045},
+ {'u', '5', 0x3046},
+ {'E', '5', 0x3047},
+ {'e', '5', 0x3048},
+ {'O', '5', 0x3049},
+ {'o', '5', 0x304a},
+ {'k', 'a', 0x304b},
+ {'g', 'a', 0x304c},
+ {'k', 'i', 0x304d},
+ {'g', 'i', 0x304e},
+ {'k', 'u', 0x304f},
+ {'g', 'u', 0x3050},
+ {'k', 'e', 0x3051},
+ {'g', 'e', 0x3052},
+ {'k', 'o', 0x3053},
+ {'g', 'o', 0x3054},
+ {'s', 'a', 0x3055},
+ {'z', 'a', 0x3056},
+ {'s', 'i', 0x3057},
+ {'z', 'i', 0x3058},
+ {'s', 'u', 0x3059},
+ {'z', 'u', 0x305a},
+ {'s', 'e', 0x305b},
+ {'z', 'e', 0x305c},
+ {'s', 'o', 0x305d},
+ {'z', 'o', 0x305e},
+ {'t', 'a', 0x305f},
+ {'d', 'a', 0x3060},
+ {'t', 'i', 0x3061},
+ {'d', 'i', 0x3062},
+ {'t', 'U', 0x3063},
+ {'t', 'u', 0x3064},
+ {'d', 'u', 0x3065},
+ {'t', 'e', 0x3066},
+ {'d', 'e', 0x3067},
+ {'t', 'o', 0x3068},
+ {'d', 'o', 0x3069},
+ {'n', 'a', 0x306a},
+ {'n', 'i', 0x306b},
+ {'n', 'u', 0x306c},
+ {'n', 'e', 0x306d},
+ {'n', 'o', 0x306e},
+ {'h', 'a', 0x306f},
+ {'b', 'a', 0x3070},
+ {'p', 'a', 0x3071},
+ {'h', 'i', 0x3072},
+ {'b', 'i', 0x3073},
+ {'p', 'i', 0x3074},
+ {'h', 'u', 0x3075},
+ {'b', 'u', 0x3076},
+ {'p', 'u', 0x3077},
+ {'h', 'e', 0x3078},
+ {'b', 'e', 0x3079},
+ {'p', 'e', 0x307a},
+ {'h', 'o', 0x307b},
+ {'b', 'o', 0x307c},
+ {'p', 'o', 0x307d},
+ {'m', 'a', 0x307e},
+ {'m', 'i', 0x307f},
+ {'m', 'u', 0x3080},
+ {'m', 'e', 0x3081},
+ {'m', 'o', 0x3082},
+ {'y', 'A', 0x3083},
+ {'y', 'a', 0x3084},
+ {'y', 'U', 0x3085},
+ {'y', 'u', 0x3086},
+ {'y', 'O', 0x3087},
+ {'y', 'o', 0x3088},
+ {'r', 'a', 0x3089},
+ {'r', 'i', 0x308a},
+ {'r', 'u', 0x308b},
+ {'r', 'e', 0x308c},
+ {'r', 'o', 0x308d},
+ {'w', 'A', 0x308e},
+ {'w', 'a', 0x308f},
+ {'w', 'i', 0x3090},
+ {'w', 'e', 0x3091},
+ {'w', 'o', 0x3092},
+ {'n', '5', 0x3093},
+ {'v', 'u', 0x3094},
+ {'"', '5', 0x309b},
+ {'0', '5', 0x309c},
+ {'*', '5', 0x309d},
+ {'+', '5', 0x309e},
+ {'a', '6', 0x30a1},
+ {'A', '6', 0x30a2},
+ {'i', '6', 0x30a3},
+ {'I', '6', 0x30a4},
+ {'u', '6', 0x30a5},
+ {'U', '6', 0x30a6},
+ {'e', '6', 0x30a7},
+ {'E', '6', 0x30a8},
+ {'o', '6', 0x30a9},
+ {'O', '6', 0x30aa},
+ {'K', 'a', 0x30ab},
+ {'G', 'a', 0x30ac},
+ {'K', 'i', 0x30ad},
+ {'G', 'i', 0x30ae},
+ {'K', 'u', 0x30af},
+ {'G', 'u', 0x30b0},
+ {'K', 'e', 0x30b1},
+ {'G', 'e', 0x30b2},
+ {'K', 'o', 0x30b3},
+ {'G', 'o', 0x30b4},
+ {'S', 'a', 0x30b5},
+ {'Z', 'a', 0x30b6},
+ {'S', 'i', 0x30b7},
+ {'Z', 'i', 0x30b8},
+ {'S', 'u', 0x30b9},
+ {'Z', 'u', 0x30ba},
+ {'S', 'e', 0x30bb},
+ {'Z', 'e', 0x30bc},
+ {'S', 'o', 0x30bd},
+ {'Z', 'o', 0x30be},
+ {'T', 'a', 0x30bf},
+ {'D', 'a', 0x30c0},
+ {'T', 'i', 0x30c1},
+ {'D', 'i', 0x30c2},
+ {'T', 'U', 0x30c3},
+ {'T', 'u', 0x30c4},
+ {'D', 'u', 0x30c5},
+ {'T', 'e', 0x30c6},
+ {'D', 'e', 0x30c7},
+ {'T', 'o', 0x30c8},
+ {'D', 'o', 0x30c9},
+ {'N', 'a', 0x30ca},
+ {'N', 'i', 0x30cb},
+ {'N', 'u', 0x30cc},
+ {'N', 'e', 0x30cd},
+ {'N', 'o', 0x30ce},
+ {'H', 'a', 0x30cf},
+ {'B', 'a', 0x30d0},
+ {'P', 'a', 0x30d1},
+ {'H', 'i', 0x30d2},
+ {'B', 'i', 0x30d3},
+ {'P', 'i', 0x30d4},
+ {'H', 'u', 0x30d5},
+ {'B', 'u', 0x30d6},
+ {'P', 'u', 0x30d7},
+ {'H', 'e', 0x30d8},
+ {'B', 'e', 0x30d9},
+ {'P', 'e', 0x30da},
+ {'H', 'o', 0x30db},
+ {'B', 'o', 0x30dc},
+ {'P', 'o', 0x30dd},
+ {'M', 'a', 0x30de},
+ {'M', 'i', 0x30df},
+ {'M', 'u', 0x30e0},
+ {'M', 'e', 0x30e1},
+ {'M', 'o', 0x30e2},
+ {'Y', 'A', 0x30e3},
+ {'Y', 'a', 0x30e4},
+ {'Y', 'U', 0x30e5},
+ {'Y', 'u', 0x30e6},
+ {'Y', 'O', 0x30e7},
+ {'Y', 'o', 0x30e8},
+ {'R', 'a', 0x30e9},
+ {'R', 'i', 0x30ea},
+ {'R', 'u', 0x30eb},
+ {'R', 'e', 0x30ec},
+ {'R', 'o', 0x30ed},
+ {'W', 'A', 0x30ee},
+ {'W', 'a', 0x30ef},
+ {'W', 'i', 0x30f0},
+ {'W', 'e', 0x30f1},
+ {'W', 'o', 0x30f2},
+ {'N', '6', 0x30f3},
+ {'V', 'u', 0x30f4},
+ {'K', 'A', 0x30f5},
+ {'K', 'E', 0x30f6},
+ {'V', 'a', 0x30f7},
+ {'V', 'i', 0x30f8},
+ {'V', 'e', 0x30f9},
+ {'V', 'o', 0x30fa},
+ {'.', '6', 0x30fb},
+ {'-', '6', 0x30fc},
+ {'*', '6', 0x30fd},
+ {'+', '6', 0x30fe},
+ {'b', '4', 0x3105},
+ {'p', '4', 0x3106},
+ {'m', '4', 0x3107},
+ {'f', '4', 0x3108},
+ {'d', '4', 0x3109},
+ {'t', '4', 0x310a},
+ {'n', '4', 0x310b},
+ {'l', '4', 0x310c},
+ {'g', '4', 0x310d},
+ {'k', '4', 0x310e},
+ {'h', '4', 0x310f},
+ {'j', '4', 0x3110},
+ {'q', '4', 0x3111},
+ {'x', '4', 0x3112},
+ {'z', 'h', 0x3113},
+ {'c', 'h', 0x3114},
+ {'s', 'h', 0x3115},
+ {'r', '4', 0x3116},
+ {'z', '4', 0x3117},
+ {'c', '4', 0x3118},
+ {'s', '4', 0x3119},
+ {'a', '4', 0x311a},
+ {'o', '4', 0x311b},
+ {'e', '4', 0x311c},
+ {'a', 'i', 0x311e},
+ {'e', 'i', 0x311f},
+ {'a', 'u', 0x3120},
+ {'o', 'u', 0x3121},
+ {'a', 'n', 0x3122},
+ {'e', 'n', 0x3123},
+ {'a', 'N', 0x3124},
+ {'e', 'N', 0x3125},
+ {'e', 'r', 0x3126},
+ {'i', '4', 0x3127},
+ {'u', '4', 0x3128},
+ {'i', 'u', 0x3129},
+ {'v', '4', 0x312a},
+ {'n', 'G', 0x312b},
+ {'g', 'n', 0x312c},
+ {'1', 'c', 0x3220},
+ {'2', 'c', 0x3221},
+ {'3', 'c', 0x3222},
+ {'4', 'c', 0x3223},
+ {'5', 'c', 0x3224},
+ {'6', 'c', 0x3225},
+ {'7', 'c', 0x3226},
+ {'8', 'c', 0x3227},
+ {'9', 'c', 0x3228},
+ /* code points 0xe000 - 0xefff excluded, they have no assigned
+ * characters, only used in proposals. */
+ {'f', 'f', 0xfb00},
+ {'f', 'i', 0xfb01},
+ {'f', 'l', 0xfb02},
+ {'f', 't', 0xfb05},
+ {'s', 't', 0xfb06},
+
+ /* Vim 5.x compatible digraphs that don't conflict with the above */
+ {'~', '!', 161}, /* ¡ */
+ {'c', '|', 162}, /* ¢ */
+ {'$', '$', 163}, /* £ */
+ {'o', 'x', 164}, /* ¤ - currency symbol in ISO 8859-1 */
+ {'Y', '-', 165}, /* ¥ */
+ {'|', '|', 166}, /* ¦ */
+ {'c', 'O', 169}, /* © */
+ {'-', ',', 172}, /* ¬ */
+ {'-', '=', 175}, /* ¯ */
+ {'~', 'o', 176}, /* ° */
+ {'2', '2', 178}, /* ² */
+ {'3', '3', 179}, /* ³ */
+ {'p', 'p', 182}, /* ¶ */
+ {'~', '.', 183}, /* · */
+ {'1', '1', 185}, /* ¹ */
+ {'~', '?', 191}, /* ¿ */
+ {'A', '`', 192}, /* À */
+ {'A', '^', 194}, /* Â */
+ {'A', '~', 195}, /* Ã */
+ {'A', '"', 196}, /* Ä */
+ {'A', '@', 197}, /* Å */
+ {'E', '`', 200}, /* È */
+ {'E', '^', 202}, /* Ê */
+ {'E', '"', 203}, /* Ë */
+ {'I', '`', 204}, /* Ì */
+ {'I', '^', 206}, /* Î */
+ {'I', '"', 207}, /* Ï */
+ {'N', '~', 209}, /* Ñ */
+ {'O', '`', 210}, /* Ò */
+ {'O', '^', 212}, /* Ô */
+ {'O', '~', 213}, /* Õ */
+ {'/', '\\', 215}, /* × - multiplication symbol in ISO 8859-1 */
+ {'U', '`', 217}, /* Ù */
+ {'U', '^', 219}, /* Û */
+ {'I', 'p', 222}, /* Þ */
+ {'a', '`', 224}, /* à */
+ {'a', '^', 226}, /* â */
+ {'a', '~', 227}, /* ã */
+ {'a', '"', 228}, /* ä */
+ {'a', '@', 229}, /* å */
+ {'e', '`', 232}, /* è */
+ {'e', '^', 234}, /* ê */
+ {'e', '"', 235}, /* ë */
+ {'i', '`', 236}, /* ì */
+ {'i', '^', 238}, /* î */
+ {'n', '~', 241}, /* ñ */
+ {'o', '`', 242}, /* ò */
+ {'o', '^', 244}, /* ô */
+ {'o', '~', 245}, /* õ */
+ {'u', '`', 249}, /* ù */
+ {'u', '^', 251}, /* û */
+ {'y', '"', 255}, /* x XX */
+
+ {NUL, NUL, NUL}
+};
+
+# endif /* OLD_DIGRAPHS */
+
+# endif /* !HPUX_DIGRAPHS */
+
+/*
+ * handle digraphs after typing a character
+ */
+int do_digraph(c)
+int c;
+{
+ static int backspaced; /* character before K_BS */
+ static int lastchar; /* last typed character */
+
+ if (c == -1) { /* init values */
+ backspaced = -1;
+ } else if (p_dg) {
+ if (backspaced >= 0)
+ c = getdigraph(backspaced, c, FALSE);
+ backspaced = -1;
+ if ((c == K_BS || c == Ctrl_H) && lastchar >= 0)
+ backspaced = lastchar;
+ }
+ lastchar = c;
+ return c;
+}
+
+/*
+ * Get a digraph. Used after typing CTRL-K on the command line or in normal
+ * mode.
+ * Returns composed character, or NUL when ESC was used.
+ */
+int get_digraph(cmdline)
+int cmdline; /* TRUE when called from the cmdline */
+{
+ int c, cc;
+
+ ++no_mapping;
+ ++allow_keys;
+ c = plain_vgetc();
+ --no_mapping;
+ --allow_keys;
+ if (c != ESC) { /* ESC cancels CTRL-K */
+ if (IS_SPECIAL(c)) /* insert special key code */
+ return c;
+ if (cmdline) {
+ if (char2cells(c) == 1
+ && cmdline_star == 0
+ )
+ putcmdline(c, TRUE);
+ } else
+ add_to_showcmd(c);
+ ++no_mapping;
+ ++allow_keys;
+ cc = plain_vgetc();
+ --no_mapping;
+ --allow_keys;
+ if (cc != ESC) /* ESC cancels CTRL-K */
+ return getdigraph(c, cc, TRUE);
+ }
+ return NUL;
+}
+
+/*
+ * Lookup the pair "char1", "char2" in the digraph tables.
+ * If no match, return "char2".
+ * If "meta_char" is TRUE and "char1" is a space, return "char2" | 0x80.
+ */
+static int getexactdigraph(char1, char2, meta_char)
+int char1;
+int char2;
+int meta_char;
+{
+ int i;
+ int retval = 0;
+ digr_T *dp;
+
+ if (IS_SPECIAL(char1) || IS_SPECIAL(char2))
+ return char2;
+
+ /*
+ * Search user digraphs first.
+ */
+ dp = (digr_T *)user_digraphs.ga_data;
+ for (i = 0; i < user_digraphs.ga_len; ++i) {
+ if ((int)dp->char1 == char1 && (int)dp->char2 == char2) {
+ retval = dp->result;
+ break;
+ }
+ ++dp;
+ }
+
+ /*
+ * Search default digraphs.
+ */
+ if (retval == 0) {
+ dp = digraphdefault;
+ for (i = 0; dp->char1 != 0; ++i) {
+ if ((int)dp->char1 == char1 && (int)dp->char2 == char2) {
+ retval = dp->result;
+ break;
+ }
+ ++dp;
+ }
+ }
+# ifdef USE_UNICODE_DIGRAPHS
+ if (retval != 0 && !enc_utf8) {
+ char_u buf[6], *to;
+ vimconv_T vc;
+
+ /*
+ * Convert the Unicode digraph to 'encoding'.
+ */
+ 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;
+ to = string_convert(&vc, buf, &i);
+ if (to != NULL) {
+ retval = (*mb_ptr2char)(to);
+ vim_free(to);
+ }
+ (void)convert_setup(&vc, NULL, NULL);
+ }
+ }
+# endif
+
+ /* 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) /* <space> <char> --> meta-char */
+ return char2 | 0x80;
+ return char2;
+ }
+ return retval;
+}
+
+/*
+ * Get digraph.
+ * Allow for both char1-char2 and char2-char1
+ */
+int getdigraph(char1, char2, meta_char)
+int char1;
+int char2;
+int meta_char;
+{
+ int retval;
+
+ if (((retval = getexactdigraph(char1, char2, meta_char)) == char2)
+ && (char1 != char2)
+ && ((retval = getexactdigraph(char2, char1, meta_char)) == char1))
+ return char2;
+ return retval;
+}
+
+/*
+ * Add the digraphs in the argument to the digraph table.
+ * format: {c1}{c2} char {c1}{c2} char ...
+ */
+void putdigraph(str)
+char_u *str;
+{
+ int char1, char2, n;
+ int i;
+ digr_T *dp;
+
+ while (*str != NUL) {
+ str = skipwhite(str);
+ if (*str == NUL)
+ return;
+ char1 = *str++;
+ char2 = *str++;
+ if (char2 == 0) {
+ EMSG(_(e_invarg));
+ return;
+ }
+ if (char1 == ESC || char2 == ESC) {
+ EMSG(_("E104: Escape not allowed in digraph"));
+ return;
+ }
+ str = skipwhite(str);
+ if (!VIM_ISDIGIT(*str)) {
+ EMSG(_(e_number_exp));
+ return;
+ }
+ n = getdigits(&str);
+
+ /* If the digraph already exists, replace the result. */
+ dp = (digr_T *)user_digraphs.ga_data;
+ for (i = 0; i < user_digraphs.ga_len; ++i) {
+ if ((int)dp->char1 == char1 && (int)dp->char2 == char2) {
+ dp->result = n;
+ break;
+ }
+ ++dp;
+ }
+
+ /* Add a new digraph to the table. */
+ if (i == user_digraphs.ga_len) {
+ if (ga_grow(&user_digraphs, 1) == OK) {
+ dp = (digr_T *)user_digraphs.ga_data + user_digraphs.ga_len;
+ dp->char1 = char1;
+ dp->char2 = char2;
+ dp->result = n;
+ ++user_digraphs.ga_len;
+ }
+ }
+ }
+}
+
+void listdigraphs() {
+ int i;
+ digr_T *dp;
+
+ msg_putchar('\n');
+
+ dp = digraphdefault;
+ for (i = 0; dp->char1 != NUL && !got_int; ++i) {
+#if defined(USE_UNICODE_DIGRAPHS) && defined(FEAT_MBYTE)
+ digr_T tmp;
+
+ /* May need to convert the result to 'encoding'. */
+ tmp.char1 = dp->char1;
+ tmp.char2 = dp->char2;
+ tmp.result = getexactdigraph(tmp.char1, tmp.char2, FALSE);
+ if (tmp.result != 0 && tmp.result != tmp.char2
+ && (has_mbyte || tmp.result <= 255))
+ printdigraph(&tmp);
+#else
+
+ if (getexactdigraph(dp->char1, dp->char2, FALSE) == dp->result
+ && (has_mbyte || dp->result <= 255)
+ )
+ printdigraph(dp);
+#endif
+ ++dp;
+ ui_breakcheck();
+ }
+
+ dp = (digr_T *)user_digraphs.ga_data;
+ for (i = 0; i < user_digraphs.ga_len && !got_int; ++i) {
+ printdigraph(dp);
+ ui_breakcheck();
+ ++dp;
+ }
+ must_redraw = CLEAR; /* clear screen, because some digraphs may be
+ wrong, in which case we messed up ScreenLines */
+}
+
+static void printdigraph(dp)
+digr_T *dp;
+{
+ char_u buf[30];
+ char_u *p;
+
+ int list_width;
+
+ if ((dy_flags & DY_UHEX)
+ || has_mbyte
+ )
+ list_width = 13;
+ else
+ list_width = 11;
+
+ if (dp->result != 0) {
+ if (msg_col > Columns - list_width)
+ msg_putchar('\n');
+ if (msg_col)
+ while (msg_col % list_width != 0)
+ msg_putchar(' ');
+
+ p = buf;
+ *p++ = dp->char1;
+ *p++ = dp->char2;
+ *p++ = ' ';
+ 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;
+ if (char2cells(dp->result) == 1)
+ *p++ = ' ';
+ vim_snprintf((char *)p, sizeof(buf) - (p - buf), " %3d", dp->result);
+ msg_outtrans(buf);
+ }
+}
+
+
+
+/* structure used for b_kmap_ga.ga_data */
+typedef struct {
+ char_u *from;
+ char_u *to;
+} kmap_T;
+
+#define KMAP_MAXLEN 20 /* maximum length of "from" or "to" */
+
+static void keymap_unload __ARGS((void));
+
+/*
+ * Set up key mapping tables for the 'keymap' option.
+ * Returns NULL if OK, an error message for failure. This only needs to be
+ * used when setting the option, not later when the value has already been
+ * checked.
+ */
+char_u * keymap_init() {
+ curbuf->b_kmap_state &= ~KEYMAP_INIT;
+
+ if (*curbuf->b_p_keymap == NUL) {
+ /* Stop any active keymap and clear the table. Also remove
+ * b:keymap_name, as no keymap is active now. */
+ keymap_unload();
+ do_cmdline_cmd((char_u *)"unlet! b:keymap_name");
+ } else {
+ char_u *buf;
+ size_t buflen;
+
+ /* Source the keymap file. It will contain a ":loadkeymap" command
+ * which will call ex_loadkeymap() below. */
+ buflen = STRLEN(curbuf->b_p_keymap)
+ + STRLEN(p_enc)
+ + 14;
+ buf = alloc((unsigned)buflen);
+ if (buf == NULL)
+ return e_outofmem;
+
+ /* try finding "keymap/'keymap'_'encoding'.vim" in 'runtimepath' */
+ vim_snprintf((char *)buf, buflen, "keymap/%s_%s.vim",
+ curbuf->b_p_keymap, p_enc);
+ if (source_runtime(buf, FALSE) == FAIL) {
+ /* try finding "keymap/'keymap'.vim" in 'runtimepath' */
+ vim_snprintf((char *)buf, buflen, "keymap/%s.vim",
+ curbuf->b_p_keymap);
+ if (source_runtime(buf, FALSE) == FAIL) {
+ vim_free(buf);
+ return (char_u *)N_("E544: Keymap file not found");
+ }
+ }
+ vim_free(buf);
+ }
+
+ return NULL;
+}
+
+/*
+ * ":loadkeymap" command: load the following lines as the keymap.
+ */
+void ex_loadkeymap(eap)
+exarg_T *eap;
+{
+ char_u *line;
+ char_u *p;
+ char_u *s;
+ kmap_T *kp;
+#define KMAP_LLEN 200 /* max length of "to" and "from" together */
+ char_u buf[KMAP_LLEN + 11];
+ int i;
+ char_u *save_cpo = p_cpo;
+
+ if (!getline_equal(eap->getline, eap->cookie, getsourceline)) {
+ EMSG(_("E105: Using :loadkeymap not in a sourced file"));
+ return;
+ }
+
+ /*
+ * Stop any active keymap and clear the table.
+ */
+ keymap_unload();
+
+ curbuf->b_kmap_state = 0;
+ ga_init2(&curbuf->b_kmap_ga, (int)sizeof(kmap_T), 20);
+
+ /* Set 'cpoptions' to "C" to avoid line continuation. */
+ p_cpo = (char_u *)"C";
+
+ /*
+ * Get each line of the sourced file, break at the end.
+ */
+ for (;; ) {
+ line = eap->getline(0, eap->cookie, 0);
+ if (line == NULL)
+ break;
+
+ p = skipwhite(line);
+ if (*p != '"' && *p != NUL && ga_grow(&curbuf->b_kmap_ga, 1) == OK) {
+ kp = (kmap_T *)curbuf->b_kmap_ga.ga_data + curbuf->b_kmap_ga.ga_len;
+ s = skiptowhite(p);
+ kp->from = vim_strnsave(p, (int)(s - p));
+ p = skipwhite(s);
+ s = skiptowhite(p);
+ kp->to = vim_strnsave(p, (int)(s - p));
+
+ if (kp->from == NULL || kp->to == NULL
+ || STRLEN(kp->from) + STRLEN(kp->to) >= KMAP_LLEN
+ || *kp->from == NUL || *kp->to == NUL) {
+ if (kp->to != NULL && *kp->to == NUL)
+ EMSG(_("E791: Empty keymap entry"));
+ vim_free(kp->from);
+ vim_free(kp->to);
+ } else
+ ++curbuf->b_kmap_ga.ga_len;
+ }
+ vim_free(line);
+ }
+
+ /*
+ * setup ":lnoremap" to map the keys
+ */
+ for (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);
+ }
+
+ p_cpo = save_cpo;
+
+ curbuf->b_kmap_state |= KEYMAP_LOADED;
+ status_redraw_curbuf();
+}
+
+/*
+ * Stop using 'keymap'.
+ */
+static void keymap_unload() {
+ char_u buf[KMAP_MAXLEN + 10];
+ int i;
+ char_u *save_cpo = p_cpo;
+ kmap_T *kp;
+
+ if (!(curbuf->b_kmap_state & KEYMAP_LOADED))
+ return;
+
+ /* Set 'cpoptions' to "C" to avoid line continuation. */
+ p_cpo = (char_u *)"C";
+
+ /* clear the ":lmap"s */
+ kp = (kmap_T *)curbuf->b_kmap_ga.ga_data;
+ for (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);
+ vim_free(kp[i].from);
+ vim_free(kp[i].to);
+ }
+
+ p_cpo = save_cpo;
+
+ ga_clear(&curbuf->b_kmap_ga);
+ curbuf->b_kmap_state &= ~KEYMAP_LOADED;
+ status_redraw_curbuf();
+}
+
diff --git a/src/edit.c b/src/edit.c
new file mode 100644
index 0000000000..4d245fbfaf
--- /dev/null
+++ b/src/edit.c
@@ -0,0 +1,8419 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * 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.
+ */
+
+/*
+ * edit.c: functions for Insert mode
+ */
+
+#include "vim.h"
+
+/*
+ * definitions used for CTRL-X submode
+ */
+#define CTRL_X_WANT_IDENT 0x100
+
+#define CTRL_X_NOT_DEFINED_YET 1
+#define CTRL_X_SCROLL 2
+#define CTRL_X_WHOLE_LINE 3
+#define CTRL_X_FILES 4
+#define CTRL_X_TAGS (5 + CTRL_X_WANT_IDENT)
+#define CTRL_X_PATH_PATTERNS (6 + CTRL_X_WANT_IDENT)
+#define CTRL_X_PATH_DEFINES (7 + CTRL_X_WANT_IDENT)
+#define CTRL_X_FINISHED 8
+#define CTRL_X_DICTIONARY (9 + CTRL_X_WANT_IDENT)
+#define CTRL_X_THESAURUS (10 + CTRL_X_WANT_IDENT)
+#define CTRL_X_CMDLINE 11
+#define CTRL_X_FUNCTION 12
+#define CTRL_X_OMNI 13
+#define CTRL_X_SPELL 14
+#define CTRL_X_LOCAL_MSG 15 /* only used in "ctrl_x_msgs" */
+
+#define CTRL_X_MSG(i) ctrl_x_msgs[(i) & ~CTRL_X_WANT_IDENT]
+
+static char *ctrl_x_msgs[] =
+{
+ N_(" Keyword completion (^N^P)"), /* ctrl_x_mode == 0, ^P/^N compl. */
+ N_(" ^X mode (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)"),
+ NULL,
+ N_(" Whole line completion (^L^N^P)"),
+ N_(" File name completion (^F^N^P)"),
+ N_(" Tag completion (^]^N^P)"),
+ N_(" Path pattern completion (^N^P)"),
+ N_(" Definition completion (^D^N^P)"),
+ NULL,
+ N_(" Dictionary completion (^K^N^P)"),
+ N_(" Thesaurus completion (^T^N^P)"),
+ N_(" Command-line completion (^V^N^P)"),
+ N_(" User defined completion (^U^N^P)"),
+ N_(" Omni completion (^O^N^P)"),
+ N_(" Spelling suggestion (s^N^P)"),
+ N_(" Keyword Local completion (^N^P)"),
+};
+
+static char e_hitend[] = N_("Hit end of paragraph");
+static char e_complwin[] = N_("E839: Completion function changed window");
+static char e_compldel[] = N_("E840: Completion function deleted text");
+
+/*
+ * Structure used to store one match for insert completion.
+ */
+typedef struct compl_S compl_T;
+struct compl_S {
+ compl_T *cp_next;
+ compl_T *cp_prev;
+ char_u *cp_str; /* matched text */
+ char cp_icase; /* TRUE or FALSE: ignore case */
+ char_u *(cp_text[CPT_COUNT]); /* text for the menu */
+ char_u *cp_fname; /* file containing the match, allocated when
+ * cp_flags has FREE_FNAME */
+ int cp_flags; /* ORIGINAL_TEXT, CONT_S_IPOS or FREE_FNAME */
+ int cp_number; /* sequence number */
+};
+
+#define ORIGINAL_TEXT (1) /* the original text when the expansion begun */
+#define FREE_FNAME (2)
+
+/*
+ * All the current matches are stored in a list.
+ * "compl_first_match" points to the start of the list.
+ * "compl_curr_match" points to the currently selected entry.
+ * "compl_shown_match" is different from compl_curr_match during
+ * ins_compl_get_exp().
+ */
+static compl_T *compl_first_match = NULL;
+static compl_T *compl_curr_match = NULL;
+static compl_T *compl_shown_match = NULL;
+
+/* After using a cursor key <Enter> selects a match in the popup menu,
+ * otherwise it inserts a line break. */
+static int compl_enter_selects = FALSE;
+
+/* When "compl_leader" is not NULL only matches that start with this string
+ * are used. */
+static char_u *compl_leader = NULL;
+
+static int compl_get_longest = FALSE; /* put longest common string
+ in compl_leader */
+
+static int compl_used_match; /* Selected one of the matches. When
+ FALSE the match was edited or using
+ the longest common string. */
+
+static int compl_was_interrupted = FALSE; /* didn't finish finding
+ completions. */
+
+static int compl_restarting = FALSE; /* don't insert match */
+
+/* When the first completion is done "compl_started" is set. When it's
+ * FALSE the word to be completed must be located. */
+static int compl_started = FALSE;
+
+/* Set when doing something for completion that may call edit() recursively,
+ * which is not allowed. */
+static int compl_busy = FALSE;
+
+static int compl_matches = 0;
+static char_u *compl_pattern = NULL;
+static int compl_direction = FORWARD;
+static int compl_shows_dir = FORWARD;
+static int compl_pending = 0; /* > 1 for postponed CTRL-N */
+static pos_T compl_startpos;
+static colnr_T compl_col = 0; /* column where the text starts
+ * that is being completed */
+static char_u *compl_orig_text = NULL; /* text as it was before
+ * completion started */
+static int compl_cont_mode = 0;
+static expand_T compl_xp;
+
+static int compl_opt_refresh_always = FALSE;
+
+static void ins_ctrl_x __ARGS((void));
+static int has_compl_option __ARGS((int dict_opt));
+static int ins_compl_accept_char __ARGS((int c));
+static int ins_compl_add __ARGS((char_u *str, int len, int icase, char_u *fname,
+ char_u **cptext, int cdir, int flags,
+ int adup));
+static int ins_compl_equal __ARGS((compl_T *match, char_u *str, int len));
+static void ins_compl_longest_match __ARGS((compl_T *match));
+static void ins_compl_add_matches __ARGS((int num_matches, char_u **matches,
+ int icase));
+static int ins_compl_make_cyclic __ARGS((void));
+static void ins_compl_upd_pum __ARGS((void));
+static void ins_compl_del_pum __ARGS((void));
+static int pum_wanted __ARGS((void));
+static int pum_enough_matches __ARGS((void));
+static void ins_compl_dictionaries __ARGS((char_u *dict, char_u *pat, int flags,
+ int thesaurus));
+static void ins_compl_files __ARGS((int count, char_u **files, int thesaurus,
+ int flags, regmatch_T *regmatch, char_u *
+ buf,
+ int *dir));
+static char_u *find_line_end __ARGS((char_u *ptr));
+static void ins_compl_free __ARGS((void));
+static void ins_compl_clear __ARGS((void));
+static int ins_compl_bs __ARGS((void));
+static int ins_compl_need_restart __ARGS((void));
+static void ins_compl_new_leader __ARGS((void));
+static void ins_compl_addleader __ARGS((int c));
+static int ins_compl_len __ARGS((void));
+static void ins_compl_restart __ARGS((void));
+static void ins_compl_set_original_text __ARGS((char_u *str));
+static void ins_compl_addfrommatch __ARGS((void));
+static int ins_compl_prep __ARGS((int c));
+static void ins_compl_fixRedoBufForLeader __ARGS((char_u *ptr_arg));
+static buf_T *ins_compl_next_buf __ARGS((buf_T *buf, int flag));
+static void ins_compl_add_list __ARGS((list_T *list));
+static void ins_compl_add_dict __ARGS((dict_T *dict));
+static int ins_compl_get_exp __ARGS((pos_T *ini));
+static void ins_compl_delete __ARGS((void));
+static void ins_compl_insert __ARGS((void));
+static int ins_compl_next __ARGS((int allow_get_expansion, int count,
+ int insert_match));
+static int ins_compl_key2dir __ARGS((int c));
+static int ins_compl_pum_key __ARGS((int c));
+static int ins_compl_key2count __ARGS((int c));
+static int ins_compl_use_match __ARGS((int c));
+static int ins_complete __ARGS((int c));
+static unsigned quote_meta __ARGS((char_u *dest, char_u *str, int len));
+
+#define BACKSPACE_CHAR 1
+#define BACKSPACE_WORD 2
+#define BACKSPACE_WORD_NOT_SPACE 3
+#define BACKSPACE_LINE 4
+
+static void ins_redraw __ARGS((int ready));
+static void ins_ctrl_v __ARGS((void));
+static void undisplay_dollar __ARGS((void));
+static void insert_special __ARGS((int, int, int));
+static void internal_format __ARGS((int textwidth, int second_indent, int flags,
+ int format_only,
+ int c));
+static void check_auto_format __ARGS((int));
+static void redo_literal __ARGS((int c));
+static void start_arrow __ARGS((pos_T *end_insert_pos));
+static void check_spell_redraw __ARGS((void));
+static void spell_back_to_badword __ARGS((void));
+static int spell_bad_len = 0; /* length of located bad word */
+static void stop_insert __ARGS((pos_T *end_insert_pos, int esc, int nomove));
+static int echeck_abbr __ARGS((int));
+static int replace_pop __ARGS((void));
+static void replace_join __ARGS((int off));
+static void replace_pop_ins __ARGS((void));
+static void mb_replace_pop_ins __ARGS((int cc));
+static void replace_flush __ARGS((void));
+static void replace_do_bs __ARGS((int limit_col));
+static int del_char_after_col __ARGS((int limit_col));
+static int cindent_on __ARGS((void));
+static void ins_reg __ARGS((void));
+static void ins_ctrl_g __ARGS((void));
+static void ins_ctrl_hat __ARGS((void));
+static int ins_esc __ARGS((long *count, int cmdchar, int nomove));
+static void ins_ctrl_ __ARGS((void));
+static int ins_start_select __ARGS((int c));
+static void ins_insert __ARGS((int replaceState));
+static void ins_ctrl_o __ARGS((void));
+static void ins_shift __ARGS((int c, int lastc));
+static void ins_del __ARGS((void));
+static int ins_bs __ARGS((int c, int mode, int *inserted_space_p));
+static void ins_mouse __ARGS((int c));
+static void ins_mousescroll __ARGS((int dir));
+static void ins_left __ARGS((void));
+static void ins_home __ARGS((int c));
+static void ins_end __ARGS((int c));
+static void ins_s_left __ARGS((void));
+static void ins_right __ARGS((void));
+static void ins_s_right __ARGS((void));
+static void ins_up __ARGS((int startcol));
+static void ins_pageup __ARGS((void));
+static void ins_down __ARGS((int startcol));
+static void ins_pagedown __ARGS((void));
+static int ins_tab __ARGS((void));
+static int ins_eol __ARGS((int c));
+static int ins_digraph __ARGS((void));
+static int ins_ctrl_ey __ARGS((int tc));
+static void ins_try_si __ARGS((int c));
+static colnr_T get_nolist_virtcol __ARGS((void));
+static char_u *do_insert_char_pre __ARGS((int c));
+
+static colnr_T Insstart_textlen; /* length of line when insert started */
+static colnr_T Insstart_blank_vcol; /* vcol for first inserted blank */
+
+static char_u *last_insert = NULL; /* the text of the previous insert,
+ K_SPECIAL and CSI are escaped */
+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 int old_indent = 0; /* for ^^D command in insert mode */
+
+static int revins_on; /* reverse insert mode on */
+static int revins_chars; /* how much to skip after edit */
+static int revins_legal; /* was the last char 'legal'? */
+static int revins_scol; /* start column of revins session */
+
+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 */
+
+/*
+ * edit(): Start inserting text.
+ *
+ * "cmdchar" can be:
+ * 'i' normal insert command
+ * 'a' normal append command
+ * 'R' replace command
+ * 'r' "r<CR>" command: insert one <CR>. Note: count can be > 1, for redo,
+ * but still only one <CR> is inserted. The <Esc> is not used for redo.
+ * 'g' "gI" command.
+ * 'V' "gR" command for Virtual Replace mode.
+ * 'v' "gr" command for single character Virtual Replace mode.
+ *
+ * This function is not called recursively. For CTRL-O commands, it returns
+ * and lets the caller handle the Normal-mode command.
+ *
+ * Return TRUE if a CTRL-O command caused the return (insert mode pending).
+ */
+int edit(cmdchar, startln, count)
+int cmdchar;
+int startln; /* if set, insert at start of line */
+long count;
+{
+ int c = 0;
+ char_u *ptr;
+ int lastc;
+ int mincol;
+ static linenr_T o_lnum = 0;
+ int i;
+ int did_backspace = TRUE; /* previous char was backspace */
+ int line_is_white = FALSE; /* line is empty before insert */
+ linenr_T old_topline = 0; /* topline before insertion */
+ int old_topfill = -1;
+ int inserted_space = FALSE; /* just inserted a space */
+ int replaceState = REPLACE;
+ int nomove = FALSE; /* don't move cursor on return */
+
+ /* Remember whether editing was restarted after CTRL-O. */
+ did_restart_edit = restart_edit;
+
+ /* sleep before redrawing, needed for "CTRL-O :" that results in an
+ * error message */
+ check_for_delay(TRUE);
+
+#ifdef HAVE_SANDBOX
+ /* Don't allow inserting in the sandbox. */
+ if (sandbox != 0) {
+ EMSG(_(e_sandbox));
+ return FALSE;
+ }
+#endif
+ /* Don't allow changes in the buffer while editing the cmdline. The
+ * caller of getcmdline() may get confused. */
+ if (textlock != 0) {
+ EMSG(_(e_secure));
+ return FALSE;
+ }
+
+ /* Don't allow recursive insert mode when busy with completion. */
+ if (compl_started || compl_busy || pum_visible()) {
+ EMSG(_(e_secure));
+ return FALSE;
+ }
+ ins_compl_clear(); /* clear stuff for CTRL-X mode */
+
+ /*
+ * Trigger InsertEnter autocommands. Do not do this for "r<CR>" or "grx".
+ */
+ if (cmdchar != 'r' && cmdchar != 'v') {
+ pos_T save_cursor = curwin->w_cursor;
+
+ if (cmdchar == 'R')
+ ptr = (char_u *)"r";
+ else if (cmdchar == 'V')
+ ptr = (char_u *)"v";
+ else
+ ptr = (char_u *)"i";
+ set_vim_var_string(VV_INSERTMODE, ptr, 1);
+ set_vim_var_string(VV_CHAR, NULL, -1); /* clear v:char */
+ apply_autocmds(EVENT_INSERTENTER, NULL, NULL, FALSE, curbuf);
+
+ /* 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
+ * a call to check_cursor_col() may move the cursor, especially with
+ * the "A" command, thus set State to avoid that. Also check that the
+ * line number is still valid (lines may have been deleted).
+ * Do not restore if v:char was set to a non-empty string. */
+ if (!equalpos(curwin->w_cursor, save_cursor)
+ && *get_vim_var_str(VV_CHAR) == NUL
+ && save_cursor.lnum <= curbuf->b_ml.ml_line_count) {
+ int save_state = State;
+
+ curwin->w_cursor = save_cursor;
+ State = INSERT;
+ check_cursor_col();
+ State = save_state;
+ }
+ }
+
+ /* 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)
+ Insstart = where_paste_started;
+ else {
+ Insstart = curwin->w_cursor;
+ if (startln)
+ Insstart.col = 0;
+ }
+ Insstart_textlen = (colnr_T)linetabsize(ml_get_curline());
+ Insstart_blank_vcol = MAXCOL;
+ if (!did_ai)
+ ai_col = 0;
+
+ if (cmdchar != NUL && restart_edit == 0) {
+ ResetRedobuff();
+ AppendNumberToRedobuff(count);
+ if (cmdchar == 'V' || cmdchar == 'v') {
+ /* "gR" or "gr" command */
+ AppendCharToRedobuff('g');
+ AppendCharToRedobuff((cmdchar == 'v') ? 'r' : 'R');
+ } else {
+ AppendCharToRedobuff(cmdchar);
+ if (cmdchar == 'g') /* "gI" command */
+ AppendCharToRedobuff('I');
+ else if (cmdchar == 'r') /* "r<CR>" command */
+ count = 1; /* insert only one <CR> */
+ }
+ }
+
+ if (cmdchar == 'R') {
+ if (p_fkmap && p_ri) {
+ beep_flush();
+ EMSG(farsi_text_3); /* encoded in Farsi */
+ State = INSERT;
+ } else
+ State = REPLACE;
+ } else if (cmdchar == 'V' || cmdchar == 'v') {
+ State = VREPLACE;
+ replaceState = VREPLACE;
+ orig_line_count = curbuf->b_ml.ml_line_count;
+ vr_lines_changed = 1;
+ } else
+ State = INSERT;
+
+ stop_insert_mode = FALSE;
+
+ /*
+ * Need to recompute the cursor position, it might move when the cursor is
+ * on a TAB or special character.
+ */
+ curs_columns(TRUE);
+
+ /*
+ * Enable langmap or IME, indicated by 'iminsert'.
+ * Note that IME may enabled/disabled without us noticing here, thus the
+ * 'iminsert' value may not reflect what is actually used. It is updated
+ * when hitting <Esc>.
+ */
+ if (curbuf->b_p_iminsert == B_IMODE_LMAP)
+ State |= LANGMAP;
+#ifdef USE_IM_CONTROL
+ im_set_active(curbuf->b_p_iminsert == B_IMODE_IM);
+#endif
+
+ setmouse();
+ clear_showcmd();
+ /* there is no reverse replace mode */
+ revins_on = (State == INSERT && p_ri);
+ if (revins_on)
+ undisplay_dollar();
+ revins_chars = 0;
+ revins_legal = 0;
+ revins_scol = -1;
+
+ /*
+ * Handle restarting Insert mode.
+ * Don't do this for "CTRL-O ." (repeat an insert): we get here with
+ * restart_edit non-zero, and something in the stuff buffer.
+ */
+ if (restart_edit != 0 && stuff_empty()) {
+ /*
+ * After a paste we consider text typed to be part of the insert for
+ * the pasted text. You can backspace over the pasted text too.
+ */
+ if (where_paste_started.lnum)
+ arrow_used = FALSE;
+ else
+ arrow_used = TRUE;
+ restart_edit = 0;
+
+ /*
+ * If the cursor was after the end-of-line before the CTRL-O and it is
+ * now at the end-of-line, put it after the end-of-line (this is not
+ * correct in very rare cases).
+ * Also do this if curswant is greater than the current virtual
+ * column. Eg after "^O$" or "^O80|".
+ */
+ validate_virtcol();
+ update_curswant();
+ if (((ins_at_eol && curwin->w_cursor.lnum == o_lnum)
+ || curwin->w_curswant > curwin->w_virtcol)
+ && *(ptr = ml_get_curline() + curwin->w_cursor.col) != NUL) {
+ if (ptr[1] == NUL)
+ ++curwin->w_cursor.col;
+ else if (has_mbyte) {
+ i = (*mb_ptr2len)(ptr);
+ if (ptr[i] == NUL)
+ curwin->w_cursor.col += i;
+ }
+ }
+ ins_at_eol = FALSE;
+ } else
+ arrow_used = FALSE;
+
+ /* we are in insert mode now, don't need to start it anymore */
+ need_start_insertmode = FALSE;
+
+ /* Need to save the line for undo before inserting the first char. */
+ ins_need_undo = TRUE;
+
+ where_paste_started.lnum = 0;
+ can_cindent = TRUE;
+ /* The cursor line is not in a closed fold, unless 'insertmode' is set or
+ * restarting. */
+ if (!p_im && did_restart_edit == 0)
+ foldOpenCursor();
+
+ /*
+ * If 'showmode' is set, show the current (insert/replace/..) mode.
+ * A warning message for changing a readonly file is given here, before
+ * actually changing anything. It's put after the mode, if any.
+ */
+ i = 0;
+ if (p_smd && msg_silent == 0)
+ i = showmode();
+
+ if (!p_im && did_restart_edit == 0)
+ change_warning(i == 0 ? 0 : i + 1);
+
+#ifdef CURSOR_SHAPE
+ ui_cursor_shape(); /* may show different cursor shape */
+#endif
+ do_digraph(-1); /* clear digraphs */
+
+ /*
+ * Get the current length of the redo buffer, those characters have to be
+ * skipped if we want to get to the inserted characters.
+ */
+ ptr = get_inserted();
+ if (ptr == NULL)
+ new_insert_skip = 0;
+ else {
+ new_insert_skip = (int)STRLEN(ptr);
+ vim_free(ptr);
+ }
+
+ old_indent = 0;
+
+ /*
+ * Main loop in Insert mode: repeat until Insert mode is left.
+ */
+ for (;; ) {
+ if (!revins_legal)
+ revins_scol = -1; /* reset on illegal motions */
+ else
+ revins_legal = 0;
+ if (arrow_used) /* don't repeat insert when arrow key used */
+ count = 0;
+
+ if (stop_insert_mode) {
+ /* ":stopinsert" used or 'insertmode' reset */
+ count = 0;
+ goto doESCkey;
+ }
+
+ /* set curwin->w_curswant for next K_DOWN or K_UP */
+ if (!arrow_used)
+ curwin->w_set_curswant = TRUE;
+
+ /* If there is no typeahead may check for timestamps (e.g., for when a
+ * menu invoked a shell command). */
+ if (stuff_empty()) {
+ did_check_timestamps = FALSE;
+ if (need_check_timestamps)
+ check_timestamps(FALSE);
+ }
+
+ /*
+ * When emsg() was called msg_scroll will have been set.
+ */
+ msg_scroll = FALSE;
+
+
+ /* Open fold at the cursor line, according to 'foldopen'. */
+ if (fdo_flags & FDO_INSERT)
+ foldOpenCursor();
+ /* Close folds where the cursor isn't, according to 'foldclose' */
+ if (!char_avail())
+ foldCheckClose();
+
+ /*
+ * If we inserted a character at the last position of the last line in
+ * the window, scroll the window one line up. This avoids an extra
+ * redraw.
+ * This is detected when the cursor column is smaller after inserting
+ * something.
+ * Don't do this when the topline changed already, it has
+ * already been adjusted (by insertchar() calling open_line())).
+ */
+ if (curbuf->b_mod_set
+ && curwin->w_p_wrap
+ && !did_backspace
+ && curwin->w_topline == old_topline
+ && curwin->w_topfill == old_topfill
+ ) {
+ mincol = curwin->w_wcol;
+ validate_cursor_col();
+
+ if ((int)curwin->w_wcol < mincol - curbuf->b_p_ts
+ && curwin->w_wrow == W_WINROW(curwin)
+ + curwin->w_height - 1 - p_so
+ && (curwin->w_cursor.lnum != curwin->w_topline
+ || curwin->w_topfill > 0
+ )) {
+ if (curwin->w_topfill > 0)
+ --curwin->w_topfill;
+ else if (hasFolding(curwin->w_topline, NULL, &old_topline))
+ set_topline(curwin, old_topline + 1);
+ else
+ set_topline(curwin, curwin->w_topline + 1);
+ }
+ }
+
+ /* May need to adjust w_topline to show the cursor. */
+ update_topline();
+
+ did_backspace = FALSE;
+
+ validate_cursor(); /* may set must_redraw */
+
+ /*
+ * Redraw the display when no characters are waiting.
+ * Also shows mode, ruler and positions cursor.
+ */
+ ins_redraw(TRUE);
+
+ if (curwin->w_p_scb)
+ do_check_scrollbind(TRUE);
+
+ if (curwin->w_p_crb)
+ do_check_cursorbind();
+ update_curswant();
+ old_topline = curwin->w_topline;
+ old_topfill = curwin->w_topfill;
+
+#ifdef USE_ON_FLY_SCROLL
+ dont_scroll = FALSE; /* allow scrolling here */
+#endif
+
+ /*
+ * Get a character for Insert mode. Ignore K_IGNORE.
+ */
+ lastc = c; /* remember previous char for CTRL-D */
+ do {
+ c = safe_vgetc();
+ } while (c == K_IGNORE);
+
+ /* Don't want K_CURSORHOLD for the second key, e.g., after CTRL-V. */
+ did_cursorhold = TRUE;
+
+ if (p_hkmap && KeyTyped)
+ c = hkmap(c); /* Hebrew mode mapping */
+ if (p_fkmap && KeyTyped)
+ c = fkmap(c); /* Farsi mode mapping */
+
+ /*
+ * Special handling of keys while the popup menu is visible or wanted
+ * and the cursor is still in the completed word. Only when there is
+ * a match, skip this when no matches were found.
+ */
+ if (compl_started
+ && pum_wanted()
+ && curwin->w_cursor.col >= compl_col
+ && (compl_shown_match == NULL
+ || compl_shown_match != compl_shown_match->cp_next)) {
+ /* BS: Delete one character from "compl_leader". */
+ if ((c == K_BS || c == Ctrl_H)
+ && curwin->w_cursor.col > compl_col
+ && (c = ins_compl_bs()) == NUL)
+ continue;
+
+ /* When no match was selected or it was edited. */
+ if (!compl_used_match) {
+ /* CTRL-L: Add one character from the current match to
+ * "compl_leader". Except when at the original match and
+ * there is nothing to add, CTRL-L works like CTRL-P then. */
+ if (c == Ctrl_L
+ && (ctrl_x_mode != CTRL_X_WHOLE_LINE
+ || (int)STRLEN(compl_shown_match->cp_str)
+ > curwin->w_cursor.col - compl_col)) {
+ ins_compl_addfrommatch();
+ continue;
+ }
+
+ /* A non-white character that fits in with the current
+ * completion: Add to "compl_leader". */
+ if (ins_compl_accept_char(c)) {
+ /* Trigger InsertCharPre. */
+ char_u *str = do_insert_char_pre(c);
+ char_u *p;
+
+ if (str != NULL) {
+ for (p = str; *p != NUL; mb_ptr_adv(p))
+ ins_compl_addleader(PTR2CHAR(p));
+ vim_free(str);
+ } else
+ ins_compl_addleader(c);
+ continue;
+ }
+
+ /* Pressing CTRL-Y selects the current match. When
+ * compl_enter_selects is set the Enter key does the same. */
+ if (c == Ctrl_Y || (compl_enter_selects
+ && (c == CAR || c == K_KENTER || c == NL))) {
+ ins_compl_delete();
+ ins_compl_insert();
+ }
+ }
+ }
+
+ /* Prepare for or stop CTRL-X mode. This doesn't do completion, but
+ * it does fix up the text when finishing completion. */
+ compl_get_longest = FALSE;
+ if (ins_compl_prep(c))
+ continue;
+
+ /* CTRL-\ CTRL-N goes to Normal mode,
+ * CTRL-\ CTRL-G goes to mode selected with 'insertmode',
+ * CTRL-\ CTRL-O is like CTRL-O but without moving the cursor. */
+ if (c == Ctrl_BSL) {
+ /* may need to redraw when no more chars available now */
+ ins_redraw(FALSE);
+ ++no_mapping;
+ ++allow_keys;
+ c = plain_vgetc();
+ --no_mapping;
+ --allow_keys;
+ if (c != Ctrl_N && c != Ctrl_G && c != Ctrl_O) {
+ /* it's something else */
+ vungetc(c);
+ c = Ctrl_BSL;
+ } else if (c == Ctrl_G && p_im)
+ continue;
+ else {
+ if (c == Ctrl_O) {
+ ins_ctrl_o();
+ ins_at_eol = FALSE; /* cursor keeps its column */
+ nomove = TRUE;
+ }
+ count = 0;
+ goto doESCkey;
+ }
+ }
+
+ c = do_digraph(c);
+
+ if ((c == Ctrl_V || c == Ctrl_Q) && ctrl_x_mode == CTRL_X_CMDLINE)
+ goto docomplete;
+ if (c == Ctrl_V || c == Ctrl_Q) {
+ ins_ctrl_v();
+ c = Ctrl_V; /* pretend CTRL-V is last typed character */
+ continue;
+ }
+
+ if (cindent_on()
+ && ctrl_x_mode == 0
+ ) {
+ /* A key name preceded by a bang means this key is not to be
+ * inserted. Skip ahead to the re-indenting below.
+ * A key name preceded by a star means that indenting has to be
+ * done before inserting the key. */
+ line_is_white = inindent(0);
+ if (in_cinkeys(c, '!', line_is_white))
+ goto force_cindent;
+ if (can_cindent && in_cinkeys(c, '*', line_is_white)
+ && stop_arrow() == OK)
+ do_c_expr_indent();
+ }
+
+ if (curwin->w_p_rl)
+ switch (c) {
+ case K_LEFT: c = K_RIGHT; break;
+ case K_S_LEFT: c = K_S_RIGHT; break;
+ case K_C_LEFT: c = K_C_RIGHT; break;
+ case K_RIGHT: c = K_LEFT; break;
+ case K_S_RIGHT: c = K_S_LEFT; break;
+ case K_C_RIGHT: c = K_C_LEFT; break;
+ }
+
+ /*
+ * If 'keymodel' contains "startsel", may start selection. If it
+ * does, a CTRL-O and c will be stuffed, we need to get these
+ * characters.
+ */
+ if (ins_start_select(c))
+ continue;
+
+ /*
+ * The big switch to handle a character in insert mode.
+ */
+ switch (c) {
+ case ESC: /* End input mode */
+ if (echeck_abbr(ESC + ABBR_OFF))
+ break;
+ /*FALLTHROUGH*/
+
+ case Ctrl_C: /* End input mode */
+ if (c == Ctrl_C && cmdwin_type != 0) {
+ /* Close the cmdline window. */
+ cmdwin_result = K_IGNORE;
+ got_int = FALSE; /* don't stop executing autocommands et al. */
+ nomove = TRUE;
+ goto doESCkey;
+ }
+
+#ifdef UNIX
+do_intr:
+#endif
+ /* when 'insertmode' set, and not halfway a mapping, don't leave
+ * Insert mode */
+ if (goto_im()) {
+ if (got_int) {
+ (void)vgetc(); /* flush all buffers */
+ got_int = FALSE;
+ } else
+ vim_beep();
+ break;
+ }
+doESCkey:
+ /*
+ * This is the ONLY return from edit()!
+ */
+ /* 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)
+ o_lnum = curwin->w_cursor.lnum;
+
+ if (ins_esc(&count, cmdchar, nomove)) {
+ if (cmdchar != 'r' && cmdchar != 'v')
+ apply_autocmds(EVENT_INSERTLEAVE, NULL, NULL,
+ FALSE, curbuf);
+ did_cursorhold = FALSE;
+ return c == Ctrl_O;
+ }
+ continue;
+
+ case Ctrl_Z: /* suspend when 'insertmode' set */
+ if (!p_im)
+ goto normalchar; /* insert CTRL-Z as normal char */
+ stuffReadbuff((char_u *)":st\r");
+ c = Ctrl_O;
+ /*FALLTHROUGH*/
+
+ case Ctrl_O: /* execute one command */
+ if (ctrl_x_mode == CTRL_X_OMNI)
+ goto docomplete;
+ if (echeck_abbr(Ctrl_O + ABBR_OFF))
+ break;
+ ins_ctrl_o();
+
+ /* don't move the cursor left when 'virtualedit' has "onemore". */
+ if (ve_flags & VE_ONEMORE) {
+ ins_at_eol = FALSE;
+ nomove = TRUE;
+ }
+ count = 0;
+ goto doESCkey;
+
+ case K_INS: /* toggle insert/replace mode */
+ case K_KINS:
+ ins_insert(replaceState);
+ break;
+
+ case K_SELECT: /* end of Select mode mapping - ignore */
+ break;
+
+
+ case K_HELP: /* Help key works like <ESC> <Help> */
+ case K_F1:
+ case K_XF1:
+ stuffcharReadbuff(K_HELP);
+ if (p_im)
+ need_start_insertmode = TRUE;
+ goto doESCkey;
+
+
+ case K_ZERO: /* Insert the previously inserted text. */
+ case NUL:
+ case Ctrl_A:
+ /* For ^@ the trailing ESC will end the insert, unless there is an
+ * error. */
+ if (stuff_inserted(NUL, 1L, (c == Ctrl_A)) == FAIL
+ && c != Ctrl_A && !p_im)
+ goto doESCkey; /* quit insert mode */
+ inserted_space = FALSE;
+ break;
+
+ case Ctrl_R: /* insert the contents of a register */
+ ins_reg();
+ auto_format(FALSE, TRUE);
+ inserted_space = FALSE;
+ break;
+
+ case Ctrl_G: /* commands starting with CTRL-G */
+ ins_ctrl_g();
+ break;
+
+ case Ctrl_HAT: /* switch input mode and/or langmap */
+ ins_ctrl_hat();
+ break;
+
+ case Ctrl__: /* switch between languages */
+ if (!p_ari)
+ goto normalchar;
+ ins_ctrl_();
+ break;
+
+ case Ctrl_D: /* Make indent one shiftwidth smaller. */
+ if (ctrl_x_mode == CTRL_X_PATH_DEFINES)
+ goto docomplete;
+ /* FALLTHROUGH */
+
+ case Ctrl_T: /* Make indent one shiftwidth greater. */
+ if (c == Ctrl_T && ctrl_x_mode == CTRL_X_THESAURUS) {
+ if (has_compl_option(FALSE))
+ goto docomplete;
+ break;
+ }
+ ins_shift(c, lastc);
+ auto_format(FALSE, TRUE);
+ inserted_space = FALSE;
+ break;
+
+ case K_DEL: /* delete character under the cursor */
+ case K_KDEL:
+ ins_del();
+ auto_format(FALSE, TRUE);
+ break;
+
+ case K_BS: /* delete character before the cursor */
+ case Ctrl_H:
+ did_backspace = ins_bs(c, BACKSPACE_CHAR, &inserted_space);
+ auto_format(FALSE, TRUE);
+ break;
+
+ case Ctrl_W: /* delete word before the cursor */
+ did_backspace = ins_bs(c, BACKSPACE_WORD, &inserted_space);
+ auto_format(FALSE, TRUE);
+ break;
+
+ case Ctrl_U: /* delete all inserted text in current line */
+ /* CTRL-X CTRL-U completes with 'completefunc'. */
+ if (ctrl_x_mode == CTRL_X_FUNCTION)
+ goto docomplete;
+ did_backspace = ins_bs(c, BACKSPACE_LINE, &inserted_space);
+ auto_format(FALSE, TRUE);
+ inserted_space = FALSE;
+ break;
+
+ case K_LEFTMOUSE: /* mouse keys */
+ case K_LEFTMOUSE_NM:
+ case K_LEFTDRAG:
+ case K_LEFTRELEASE:
+ case K_LEFTRELEASE_NM:
+ case K_MIDDLEMOUSE:
+ case K_MIDDLEDRAG:
+ case K_MIDDLERELEASE:
+ case K_RIGHTMOUSE:
+ case K_RIGHTDRAG:
+ case K_RIGHTRELEASE:
+ case K_X1MOUSE:
+ case K_X1DRAG:
+ case K_X1RELEASE:
+ case K_X2MOUSE:
+ case K_X2DRAG:
+ case K_X2RELEASE:
+ ins_mouse(c);
+ break;
+
+ case K_MOUSEDOWN: /* Default action for scroll wheel up: scroll up */
+ ins_mousescroll(MSCR_DOWN);
+ break;
+
+ case K_MOUSEUP: /* Default action for scroll wheel down: scroll down */
+ ins_mousescroll(MSCR_UP);
+ break;
+
+ case K_MOUSELEFT: /* Scroll wheel left */
+ ins_mousescroll(MSCR_LEFT);
+ break;
+
+ case K_MOUSERIGHT: /* Scroll wheel right */
+ ins_mousescroll(MSCR_RIGHT);
+ break;
+
+ case K_IGNORE: /* Something mapped to nothing */
+ break;
+
+ case K_CURSORHOLD: /* Didn't type something for a while. */
+ apply_autocmds(EVENT_CURSORHOLDI, NULL, NULL, FALSE, curbuf);
+ did_cursorhold = TRUE;
+ break;
+
+
+
+ case K_HOME: /* <Home> */
+ case K_KHOME:
+ case K_S_HOME:
+ case K_C_HOME:
+ ins_home(c);
+ break;
+
+ case K_END: /* <End> */
+ case K_KEND:
+ case K_S_END:
+ case K_C_END:
+ ins_end(c);
+ break;
+
+ case K_LEFT: /* <Left> */
+ if (mod_mask & (MOD_MASK_SHIFT|MOD_MASK_CTRL))
+ ins_s_left();
+ else
+ ins_left();
+ break;
+
+ case K_S_LEFT: /* <S-Left> */
+ case K_C_LEFT:
+ ins_s_left();
+ break;
+
+ case K_RIGHT: /* <Right> */
+ if (mod_mask & (MOD_MASK_SHIFT|MOD_MASK_CTRL))
+ ins_s_right();
+ else
+ ins_right();
+ break;
+
+ case K_S_RIGHT: /* <S-Right> */
+ case K_C_RIGHT:
+ ins_s_right();
+ break;
+
+ case K_UP: /* <Up> */
+ if (pum_visible())
+ goto docomplete;
+ if (mod_mask & MOD_MASK_SHIFT)
+ ins_pageup();
+ else
+ ins_up(FALSE);
+ break;
+
+ case K_S_UP: /* <S-Up> */
+ case K_PAGEUP:
+ case K_KPAGEUP:
+ if (pum_visible())
+ goto docomplete;
+ ins_pageup();
+ break;
+
+ case K_DOWN: /* <Down> */
+ if (pum_visible())
+ goto docomplete;
+ if (mod_mask & MOD_MASK_SHIFT)
+ ins_pagedown();
+ else
+ ins_down(FALSE);
+ break;
+
+ case K_S_DOWN: /* <S-Down> */
+ case K_PAGEDOWN:
+ case K_KPAGEDOWN:
+ if (pum_visible())
+ goto docomplete;
+ ins_pagedown();
+ break;
+
+
+ case K_S_TAB: /* When not mapped, use like a normal TAB */
+ c = TAB;
+ /* FALLTHROUGH */
+
+ case TAB: /* TAB or Complete patterns along path */
+ if (ctrl_x_mode == CTRL_X_PATH_PATTERNS)
+ goto docomplete;
+ inserted_space = FALSE;
+ if (ins_tab())
+ goto normalchar; /* insert TAB as a normal char */
+ auto_format(FALSE, TRUE);
+ break;
+
+ case K_KENTER: /* <Enter> */
+ c = CAR;
+ /* FALLTHROUGH */
+ case CAR:
+ case NL:
+ /* In a quickfix window a <CR> jumps to the error under the
+ * cursor. */
+ if (bt_quickfix(curbuf) && c == CAR) {
+ if (curwin->w_llist_ref == NULL) /* quickfix window */
+ do_cmdline_cmd((char_u *)".cc");
+ else /* location list window */
+ do_cmdline_cmd((char_u *)".ll");
+ break;
+ }
+ if (cmdwin_type != 0) {
+ /* Execute the command in the cmdline window. */
+ cmdwin_result = CAR;
+ goto doESCkey;
+ }
+ if (ins_eol(c) && !p_im)
+ goto doESCkey; /* out of memory */
+ auto_format(FALSE, FALSE);
+ inserted_space = FALSE;
+ break;
+
+ case Ctrl_K: /* digraph or keyword completion */
+ if (ctrl_x_mode == CTRL_X_DICTIONARY) {
+ if (has_compl_option(TRUE))
+ goto docomplete;
+ break;
+ }
+ c = ins_digraph();
+ if (c == NUL)
+ break;
+ goto normalchar;
+
+ case Ctrl_X: /* Enter CTRL-X mode */
+ ins_ctrl_x();
+ break;
+
+ case Ctrl_RSB: /* Tag name completion after ^X */
+ if (ctrl_x_mode != CTRL_X_TAGS)
+ goto normalchar;
+ goto docomplete;
+
+ case Ctrl_F: /* File name completion after ^X */
+ if (ctrl_x_mode != CTRL_X_FILES)
+ goto normalchar;
+ goto docomplete;
+
+ case 's': /* Spelling completion after ^X */
+ case Ctrl_S:
+ if (ctrl_x_mode != CTRL_X_SPELL)
+ goto normalchar;
+ goto docomplete;
+
+ case Ctrl_L: /* Whole line completion after ^X */
+ if (ctrl_x_mode != CTRL_X_WHOLE_LINE) {
+ /* CTRL-L with 'insertmode' set: Leave Insert mode */
+ if (p_im) {
+ if (echeck_abbr(Ctrl_L + ABBR_OFF))
+ break;
+ goto doESCkey;
+ }
+ goto normalchar;
+ }
+ /* FALLTHROUGH */
+
+ case Ctrl_P: /* Do previous/next pattern completion */
+ case Ctrl_N:
+ /* if 'complete' is empty then plain ^P is no longer special,
+ * but it is under other ^X modes */
+ if (*curbuf->b_p_cpt == NUL
+ && ctrl_x_mode != 0
+ && !(compl_cont_status & CONT_LOCAL))
+ goto normalchar;
+
+docomplete:
+ compl_busy = TRUE;
+ if (ins_complete(c) == FAIL)
+ compl_cont_status = 0;
+ compl_busy = FALSE;
+ break;
+
+ case Ctrl_Y: /* copy from previous line or scroll down */
+ case Ctrl_E: /* copy from next line or scroll up */
+ c = ins_ctrl_ey(c);
+ break;
+
+ default:
+#ifdef UNIX
+ if (c == intr_char) /* special interrupt char */
+ goto do_intr;
+#endif
+
+normalchar:
+ /*
+ * Insert a normal character.
+ */
+ if (!p_paste) {
+ /* Trigger InsertCharPre. */
+ char_u *str = do_insert_char_pre(c);
+ char_u *p;
+
+ 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)) {
+ c = PTR2CHAR(p);
+ if (c == CAR || c == K_KENTER || c == NL)
+ ins_eol(c);
+ else
+ ins_char(c);
+ }
+ AppendToRedobuffLit(str, -1);
+ }
+ vim_free(str);
+ c = NUL;
+ }
+
+ /* If the new value is already inserted or an empty string
+ * then don't insert any character. */
+ if (c == NUL)
+ break;
+ }
+ /* Try to perform smart-indenting. */
+ ins_try_si(c);
+
+ if (c == ' ') {
+ inserted_space = TRUE;
+ if (inindent(0))
+ can_cindent = FALSE;
+ if (Insstart_blank_vcol == MAXCOL
+ && curwin->w_cursor.lnum == Insstart.lnum)
+ Insstart_blank_vcol = get_nolist_virtcol();
+ }
+
+ /* Insert a normal character and check for abbreviations on a
+ * special character. Let CTRL-] expand abbreviations without
+ * inserting it. */
+ if (vim_iswordc(c) || (!echeck_abbr(
+ /* Add ABBR_OFF for characters above 0x100, this is
+ * what check_abbr() expects. */
+ (has_mbyte && c >= 0x100) ? (c + ABBR_OFF) :
+ c) && c != Ctrl_RSB)) {
+ insert_special(c, FALSE, FALSE);
+ revins_legal++;
+ revins_chars++;
+ }
+
+ auto_format(FALSE, TRUE);
+
+ /* When inserting a character the cursor line must never be in a
+ * closed fold. */
+ foldOpenCursor();
+ break;
+ } /* end of switch (c) */
+
+ /* If typed something may trigger CursorHoldI again. */
+ if (c != K_CURSORHOLD)
+ did_cursorhold = FALSE;
+
+ /* If the cursor was moved we didn't just insert a space */
+ if (arrow_used)
+ inserted_space = FALSE;
+
+ if (can_cindent && cindent_on()
+ && ctrl_x_mode == 0
+ ) {
+force_cindent:
+ /*
+ * Indent now if a key was typed that is in 'cinkeys'.
+ */
+ if (in_cinkeys(c, ' ', line_is_white)) {
+ if (stop_arrow() == OK)
+ /* re-indent the current line */
+ do_c_expr_indent();
+ }
+ }
+
+ } /* for (;;) */
+ /* NOTREACHED */
+}
+
+/*
+ * Redraw for Insert mode.
+ * This is postponed until getting the next character to make '$' in the 'cpo'
+ * option work correctly.
+ * Only redraw when there are no characters available. This speeds up
+ * inserting sequences of characters (e.g., for CTRL-R).
+ */
+static void ins_redraw(ready)
+int ready UNUSED; /* not busy with something */
+{
+ linenr_T conceal_old_cursor_line = 0;
+ linenr_T conceal_new_cursor_line = 0;
+ int conceal_update_lines = FALSE;
+
+ if (char_avail())
+ return;
+
+ /* Trigger CursorMoved if the cursor moved. Not when the popup menu is
+ * visible, the command might delete it. */
+ if (ready && (
+ has_cursormovedI()
+ ||
+ curwin->w_p_cole > 0
+ )
+ && !equalpos(last_cursormoved, curwin->w_cursor)
+ && !pum_visible()
+ ) {
+ /* Need to update the screen first, to make sure syntax
+ * highlighting is correct after making a change (e.g., inserting
+ * a "(". The autocommand may also require a redraw, so it's done
+ * again below, unfortunately. */
+ if (syntax_present(curwin) && must_redraw)
+ update_screen(0);
+ if (has_cursormovedI())
+ 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;
+ }
+ last_cursormoved = curwin->w_cursor;
+ }
+
+ /* Trigger TextChangedI if b_changedtick differs. */
+ if (ready && has_textchangedI()
+ && last_changedtick != curbuf->b_changedtick
+ && !pum_visible()
+ ) {
+ if (last_changedtick_buf == curbuf)
+ apply_autocmds(EVENT_TEXTCHANGEDI, NULL, NULL, FALSE, curbuf);
+ last_changedtick_buf = curbuf;
+ last_changedtick = curbuf->b_changedtick;
+ }
+
+ 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);
+ setcursor();
+ emsg_on_display = FALSE; /* may remove error message now */
+}
+
+/*
+ * Handle a CTRL-V or CTRL-Q typed in Insert mode.
+ */
+static void ins_ctrl_v() {
+ int c;
+ int did_putchar = FALSE;
+
+ /* may need to redraw when no more chars available now */
+ ins_redraw(FALSE);
+
+ if (redrawing() && !char_avail()) {
+ edit_putchar('^', TRUE);
+ did_putchar = TRUE;
+ }
+ AppendToRedobuff((char_u *)CTRL_V_STR); /* CTRL-V */
+
+ add_to_showcmd_c(Ctrl_V);
+
+ c = get_literal();
+ if (did_putchar)
+ /* when the line fits in 'columns' the '^' is at the start of the next
+ * line and will not removed by the redraw */
+ edit_unputchar();
+ clear_showcmd();
+ insert_special(c, FALSE, TRUE);
+ revins_chars++;
+ revins_legal++;
+}
+
+/*
+ * Put a character directly onto the screen. It's not stored in a buffer.
+ * Used while handling CTRL-K, CTRL-V, etc. in Insert mode.
+ */
+static int pc_status;
+#define PC_STATUS_UNSET 0 /* pc_bytes was not set */
+#define PC_STATUS_RIGHT 1 /* right halve of double-wide char */
+#define PC_STATUS_LEFT 2 /* left halve of double-wide char */
+#define PC_STATUS_SET 3 /* pc_bytes was filled */
+static char_u pc_bytes[MB_MAXBYTES + 1]; /* saved bytes */
+static int pc_attr;
+static int pc_row;
+static int pc_col;
+
+void edit_putchar(c, highlight)
+int c;
+int highlight;
+{
+ int attr;
+
+ if (ScreenLines != NULL) {
+ update_topline(); /* just in case w_topline isn't valid */
+ validate_cursor();
+ if (highlight)
+ attr = hl_attr(HLF_8);
+ else
+ attr = 0;
+ pc_row = W_WINROW(curwin) + curwin->w_wrow;
+ pc_col = W_WINCOL(curwin);
+ pc_status = PC_STATUS_UNSET;
+ if (curwin->w_p_rl) {
+ pc_col += W_WIDTH(curwin) - 1 - curwin->w_wcol;
+ if (has_mbyte) {
+ int fix_col = mb_fix_col(pc_col, pc_row);
+
+ if (fix_col != pc_col) {
+ screen_putchar(' ', 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))
+ 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);
+ pc_status = PC_STATUS_SET;
+ }
+ screen_putchar(c, pc_row, pc_col, attr);
+ }
+}
+
+/*
+ * Undo the previous edit_putchar().
+ */
+void edit_unputchar() {
+ 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);
+ }
+}
+
+/*
+ * Called when p_dollar is set: display a '$' at the end of the changed text
+ * Only works when cursor is in the line that changes.
+ */
+void display_dollar(col)
+colnr_T col;
+{
+ colnr_T save_col;
+
+ if (!redrawing())
+ return;
+
+ cursor_off();
+ 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 = ml_get_curline();
+ curwin->w_cursor.col -= (*mb_head_off)(p, p + col);
+ }
+ curs_columns(FALSE); /* recompute w_wrow and w_wcol */
+ if (curwin->w_wcol < W_WIDTH(curwin)) {
+ edit_putchar('$', FALSE);
+ dollar_vcol = curwin->w_virtcol;
+ }
+ curwin->w_cursor.col = save_col;
+}
+
+/*
+ * Call this function before moving the cursor from the normal insert position
+ * in insert mode.
+ */
+static void undisplay_dollar() {
+ if (dollar_vcol >= 0) {
+ dollar_vcol = -1;
+ redrawWinline(curwin->w_cursor.lnum, FALSE);
+ }
+}
+
+/*
+ * Insert an indent (for <Tab> or CTRL-T) or delete an indent (for CTRL-D).
+ * Keep the cursor on the same character.
+ * type == INDENT_INC increase indent (for CTRL-T or <Tab>)
+ * type == INDENT_DEC decrease indent (for CTRL-D)
+ * type == INDENT_SET set indent to "amount"
+ * if round is TRUE, round the indent to 'shiftwidth' (only with _INC and _Dec).
+ */
+void change_indent(type, amount, round, replaced, call_changed_bytes)
+int type;
+int amount;
+int round;
+int replaced; /* replaced character, put on replace stack */
+int call_changed_bytes; /* call changed_bytes() */
+{
+ int vcol;
+ int last_vcol;
+ int insstart_less; /* reduction for Insstart.col */
+ int new_cursor_col;
+ int i;
+ char_u *ptr;
+ int save_p_list;
+ int start_col;
+ colnr_T vc;
+ colnr_T orig_col = 0; /* init for GCC */
+ char_u *new_line, *orig_line = NULL; /* init for GCC */
+
+ /* VREPLACE mode needs to know what the line was like before changing */
+ if (State & VREPLACE_FLAG) {
+ orig_line = vim_strsave(ml_get_curline()); /* Deal with NULL below */
+ orig_col = curwin->w_cursor.col;
+ }
+
+ /* for the following tricks we don't want list mode */
+ save_p_list = curwin->w_p_list;
+ curwin->w_p_list = FALSE;
+ vc = getvcol_nolist(&curwin->w_cursor);
+ vcol = vc;
+
+ /*
+ * For Replace mode we need to fix the replace stack later, which is only
+ * possible when the cursor is in the indent. Remember the number of
+ * characters before the cursor if it's possible.
+ */
+ start_col = curwin->w_cursor.col;
+
+ /* determine offset from first non-blank */
+ new_cursor_col = curwin->w_cursor.col;
+ beginline(BL_WHITE);
+ new_cursor_col -= curwin->w_cursor.col;
+
+ insstart_less = curwin->w_cursor.col;
+
+ /*
+ * If the cursor is in the indent, compute how many screen columns the
+ * cursor is to the left of the first non-blank.
+ */
+ if (new_cursor_col < 0)
+ vcol = get_indent() - vcol;
+
+ if (new_cursor_col > 0) /* can't fix replace stack */
+ start_col = -1;
+
+ /*
+ * Set the new indent. The cursor will be put on the first non-blank.
+ */
+ if (type == INDENT_SET)
+ (void)set_indent(amount, call_changed_bytes ? SIN_CHANGED : 0);
+ else {
+ int save_State = State;
+
+ /* Avoid being called recursively. */
+ if (State & VREPLACE_FLAG)
+ State = INSERT;
+ shift_line(type == INDENT_DEC, round, 1, call_changed_bytes);
+ State = save_State;
+ }
+ insstart_less -= curwin->w_cursor.col;
+
+ /*
+ * Try to put cursor on same character.
+ * If the cursor is at or after the first non-blank in the line,
+ * compute the cursor column relative to the column of the first
+ * non-blank character.
+ * If we are not in insert mode, leave the cursor on the first non-blank.
+ * If the cursor is before the first non-blank, position it relative
+ * to the first non-blank, counted in screen columns.
+ */
+ if (new_cursor_col >= 0) {
+ /*
+ * When changing the indent while the cursor is touching it, reset
+ * Insstart_col to 0.
+ */
+ if (new_cursor_col == 0)
+ insstart_less = MAXCOL;
+ new_cursor_col += curwin->w_cursor.col;
+ } else if (!(State & INSERT))
+ new_cursor_col = curwin->w_cursor.col;
+ else {
+ /*
+ * Compute the screen column where the cursor should be.
+ */
+ vcol = get_indent() - vcol;
+ curwin->w_virtcol = (colnr_T)((vcol < 0) ? 0 : vcol);
+
+ /*
+ * Advance the cursor until we reach the right screen column.
+ */
+ vcol = last_vcol = 0;
+ new_cursor_col = -1;
+ ptr = ml_get_curline();
+ while (vcol <= (int)curwin->w_virtcol) {
+ last_vcol = vcol;
+ if (has_mbyte && new_cursor_col >= 0)
+ new_cursor_col += (*mb_ptr2len)(ptr + new_cursor_col);
+ else
+ ++new_cursor_col;
+ vcol += lbr_chartabsize(ptr + new_cursor_col, (colnr_T)vcol);
+ }
+ vcol = last_vcol;
+
+ /*
+ * May need to insert spaces to be able to position the cursor on
+ * the right screen column.
+ */
+ if (vcol != (int)curwin->w_virtcol) {
+ curwin->w_cursor.col = (colnr_T)new_cursor_col;
+ i = (int)curwin->w_virtcol - vcol;
+ ptr = alloc((unsigned)(i + 1));
+ if (ptr != NULL) {
+ new_cursor_col += i;
+ ptr[i] = NUL;
+ while (--i >= 0)
+ ptr[i] = ' ';
+ ins_str(ptr);
+ vim_free(ptr);
+ }
+ }
+
+ /*
+ * When changing the indent while the cursor is in it, reset
+ * Insstart_col to 0.
+ */
+ insstart_less = MAXCOL;
+ }
+
+ curwin->w_p_list = save_p_list;
+
+ if (new_cursor_col <= 0)
+ curwin->w_cursor.col = 0;
+ else
+ curwin->w_cursor.col = (colnr_T)new_cursor_col;
+ curwin->w_set_curswant = TRUE;
+ changed_cline_bef_curs();
+
+ /*
+ * May have to adjust the start of the insert.
+ */
+ if (State & INSERT) {
+ if (curwin->w_cursor.lnum == Insstart.lnum && Insstart.col != 0) {
+ if ((int)Insstart.col <= insstart_less)
+ Insstart.col = 0;
+ else
+ Insstart.col -= insstart_less;
+ }
+ if ((int)ai_col <= insstart_less)
+ ai_col = 0;
+ else
+ ai_col -= insstart_less;
+ }
+
+ /*
+ * For REPLACE mode, may have to fix the replace stack, if it's possible.
+ * If the number of characters before the cursor decreased, need to pop a
+ * few characters from the replace stack.
+ * If the number of characters before the cursor increased, need to push a
+ * few NULs onto the replace stack.
+ */
+ if (REPLACE_NORMAL(State) && start_col >= 0) {
+ while (start_col > (int)curwin->w_cursor.col) {
+ replace_join(0); /* remove a NUL from the replace stack */
+ --start_col;
+ }
+ while (start_col < (int)curwin->w_cursor.col || replaced) {
+ replace_push(NUL);
+ if (replaced) {
+ replace_push(replaced);
+ replaced = NUL;
+ }
+ ++start_col;
+ }
+ }
+
+ /*
+ * For VREPLACE mode, we also have to fix the replace stack. In this case
+ * it is always possible because we backspace over the whole line and then
+ * put it back again the way we wanted it.
+ */
+ if (State & VREPLACE_FLAG) {
+ /* If orig_line didn't allocate, just return. At least we did the job,
+ * even if you can't backspace. */
+ if (orig_line == NULL)
+ return;
+
+ /* Save new line */
+ new_line = vim_strsave(ml_get_curline());
+ if (new_line == NULL)
+ return;
+
+ /* 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);
+ curwin->w_cursor.col = orig_col;
+
+ /* Backspace from cursor to start of line */
+ backspace_until_column(0);
+
+ /* Insert new stuff into line again */
+ ins_bytes(new_line);
+
+ vim_free(new_line);
+ }
+}
+
+/*
+ * Truncate the space at the end of a line. This is to be used only in an
+ * insert mode. It handles fixing the replace stack for REPLACE and VREPLACE
+ * modes.
+ */
+void truncate_spaces(line)
+char_u *line;
+{
+ int i;
+
+ /* find start of trailing white space */
+ for (i = (int)STRLEN(line) - 1; i >= 0 && vim_iswhite(line[i]); i--) {
+ if (State & REPLACE_FLAG)
+ replace_join(0); /* remove a NUL from the replace stack */
+ }
+ line[i + 1] = NUL;
+}
+
+#if defined(FEAT_VREPLACE) || defined(FEAT_INS_EXPAND) \
+ || defined(FEAT_COMMENTS) || defined(PROTO)
+/*
+ * Backspace the cursor until the given column. Handles REPLACE and VREPLACE
+ * modes correctly. May also be used when not in insert mode at all.
+ * Will attempt not to go before "col" even when there is a composing
+ * character.
+ */
+void backspace_until_column(col)
+int col;
+{
+ while ((int)curwin->w_cursor.col > col) {
+ curwin->w_cursor.col--;
+ if (State & REPLACE_FLAG)
+ replace_do_bs(col);
+ else if (!del_char_after_col(col))
+ break;
+ }
+}
+#endif
+
+/*
+ * Like del_char(), but make sure not to go before column "limit_col".
+ * Only matters when there are composing characters.
+ * Return TRUE when something was deleted.
+ */
+static int del_char_after_col(limit_col)
+int limit_col UNUSED;
+{
+ if (enc_utf8 && limit_col >= 0) {
+ colnr_T ecol = curwin->w_cursor.col + 1;
+
+ /* Make sure the cursor is at the start of a character, but
+ * skip forward again when going too far back because of a
+ * composing character. */
+ mb_adjust_cursor();
+ while (curwin->w_cursor.col < (colnr_T)limit_col) {
+ int l = utf_ptr2len(ml_get_cursor());
+
+ if (l == 0) /* end of line */
+ break;
+ curwin->w_cursor.col += l;
+ }
+ if (*ml_get_cursor() == NUL || curwin->w_cursor.col == ecol)
+ return FALSE;
+ del_bytes((long)((int)ecol - curwin->w_cursor.col), FALSE, TRUE);
+ } else
+ (void)del_char(FALSE);
+ return TRUE;
+}
+
+/*
+ * CTRL-X pressed in Insert mode.
+ */
+static void ins_ctrl_x() {
+ /* CTRL-X after CTRL-X CTRL-V doesn't do anything, so that CTRL-X
+ * CTRL-V works like CTRL-N */
+ if (ctrl_x_mode != CTRL_X_CMDLINE) {
+ /* if the next ^X<> won't ADD nothing, then reset
+ * compl_cont_status */
+ if (compl_cont_status & CONT_N_ADDS)
+ compl_cont_status |= CONT_INTRPT;
+ else
+ compl_cont_status = 0;
+ /* We're not sure which CTRL-X mode it will be yet */
+ ctrl_x_mode = CTRL_X_NOT_DEFINED_YET;
+ edit_submode = (char_u *)_(CTRL_X_MSG(ctrl_x_mode));
+ edit_submode_pre = NULL;
+ showmode();
+ }
+}
+
+/*
+ * Return TRUE if the 'dict' or 'tsr' option can be used.
+ */
+static int has_compl_option(dict_opt)
+int dict_opt;
+{
+ if (dict_opt ? (*curbuf->b_p_dict == NUL && *p_dict == NUL
+ && !curwin->w_p_spell
+ )
+ : (*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));
+ if (emsg_silent == 0) {
+ vim_beep();
+ setcursor();
+ out_flush();
+ ui_delay(2000L, FALSE);
+ }
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/*
+ * Is the character 'c' a valid key to go to or keep us in CTRL-X mode?
+ * This depends on the current mode.
+ */
+int vim_is_ctrl_x_key(c)
+int c;
+{
+ /* Always allow ^R - let it's results then be checked */
+ if (c == Ctrl_R)
+ return TRUE;
+
+ /* Accept <PageUp> and <PageDown> if the popup menu is visible. */
+ if (ins_compl_pum_key(c))
+ return TRUE;
+
+ switch (ctrl_x_mode) {
+ case 0: /* Not in any CTRL-X mode */
+ return c == Ctrl_N || c == Ctrl_P || c == Ctrl_X;
+ case CTRL_X_NOT_DEFINED_YET:
+ return c == Ctrl_X || c == Ctrl_Y || c == Ctrl_E
+ || c == Ctrl_L || c == Ctrl_F || c == Ctrl_RSB
+ || c == Ctrl_I || c == Ctrl_D || c == Ctrl_P
+ || c == Ctrl_N || c == Ctrl_T || c == Ctrl_V
+ || c == Ctrl_Q || c == Ctrl_U || c == Ctrl_O
+ || c == Ctrl_S || c == Ctrl_K || c == 's';
+ case CTRL_X_SCROLL:
+ return c == Ctrl_Y || c == Ctrl_E;
+ case CTRL_X_WHOLE_LINE:
+ return c == Ctrl_L || c == Ctrl_P || c == Ctrl_N;
+ case CTRL_X_FILES:
+ return c == Ctrl_F || c == Ctrl_P || c == Ctrl_N;
+ case CTRL_X_DICTIONARY:
+ return c == Ctrl_K || c == Ctrl_P || c == Ctrl_N;
+ case CTRL_X_THESAURUS:
+ return c == Ctrl_T || c == Ctrl_P || c == Ctrl_N;
+ case CTRL_X_TAGS:
+ return c == Ctrl_RSB || c == Ctrl_P || c == Ctrl_N;
+ case CTRL_X_PATH_PATTERNS:
+ return c == Ctrl_P || c == Ctrl_N;
+ case CTRL_X_PATH_DEFINES:
+ return c == Ctrl_D || c == Ctrl_P || c == Ctrl_N;
+ case CTRL_X_CMDLINE:
+ return c == Ctrl_V || c == Ctrl_Q || c == Ctrl_P || c == Ctrl_N
+ || c == Ctrl_X;
+ case CTRL_X_FUNCTION:
+ return c == Ctrl_U || c == Ctrl_P || c == Ctrl_N;
+ case CTRL_X_OMNI:
+ return c == Ctrl_O || c == Ctrl_P || c == Ctrl_N;
+ case CTRL_X_SPELL:
+ return c == Ctrl_S || c == Ctrl_P || c == Ctrl_N;
+ }
+ EMSG(_(e_internal));
+ return FALSE;
+}
+
+/*
+ * Return TRUE when character "c" is part of the item currently being
+ * completed. Used to decide whether to abandon complete mode when the menu
+ * is visible.
+ */
+static int ins_compl_accept_char(c)
+int c;
+{
+ if (ctrl_x_mode & CTRL_X_WANT_IDENT)
+ /* When expanding an identifier only accept identifier chars. */
+ return vim_isIDc(c);
+
+ switch (ctrl_x_mode) {
+ case CTRL_X_FILES:
+ /* When expanding file name only accept file name chars. But not
+ * path separators, so that "proto/<Tab>" expands files in
+ * "proto", not "proto/" as a whole */
+ return vim_isfilec(c) && !vim_ispathsep(c);
+
+ case CTRL_X_CMDLINE:
+ case CTRL_X_OMNI:
+ /* Command line and Omni completion can work with just about any
+ * printable character, but do stop at white space. */
+ return vim_isprintc(c) && !vim_iswhite(c);
+
+ case CTRL_X_WHOLE_LINE:
+ /* For while line completion a space can be part of the line. */
+ return vim_isprintc(c);
+ }
+ return vim_iswordc(c);
+}
+
+/*
+ * This is like ins_compl_add(), but if 'ic' and 'inf' are set, then the
+ * case of the originally typed text is used, and the case of the completed
+ * text is inferred, ie this tries to work out what case you probably wanted
+ * the rest of the word to be in -- webb
+ */
+int ins_compl_add_infercase(str, len, icase, fname, dir, flags)
+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. */
+ int min_len;
+ int *wca; /* Wide character array. */
+ int has_lower = FALSE;
+ int was_letter = FALSE;
+
+ if (p_ic && curbuf->b_p_inf && len > 0) {
+ /* Infer case of completed part. */
+
+ /* Find actual length of completion. */
+ if (has_mbyte) {
+ p = str;
+ actual_len = 0;
+ while (*p != NUL) {
+ mb_ptr_adv(p);
+ ++actual_len;
+ }
+ } else
+ actual_len = len;
+
+ /* Find actual length of original text. */
+ if (has_mbyte) {
+ p = compl_orig_text;
+ actual_compl_length = 0;
+ while (*p != NUL) {
+ mb_ptr_adv(p);
+ ++actual_compl_length;
+ }
+ } else
+ actual_compl_length = compl_length;
+
+ /* "actual_len" may be smaller than "actual_compl_length" when using
+ * thesaurus, only use the minimum when comparing. */
+ min_len = actual_len < actual_compl_length
+ ? actual_len : actual_compl_length;
+
+ /* Allocate wide character array for the completion and fill it. */
+ wca = (int *)alloc((unsigned)(actual_len * sizeof(int)));
+ if (wca != NULL) {
+ 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 (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;
+ }
+ }
+ }
+
+ /*
+ * Rule 2: No lower case, 2nd consecutive letter converted to
+ * upper case.
+ */
+ if (!has_lower) {
+ p = compl_orig_text;
+ for (i = 0; i < min_len; ++i) {
+ if (has_mbyte)
+ c = mb_ptr2char_adv(&p);
+ else
+ c = *(p++);
+ 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 = 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 (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;
+
+ vim_free(wca);
+ }
+
+ return ins_compl_add(IObuff, len, icase, fname, NULL, dir,
+ flags, FALSE);
+ }
+ return ins_compl_add(str, len, icase, fname, NULL, 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,
+ * maybe because alloc() returns NULL, then FAIL is returned.
+ */
+static int ins_compl_add(str, len, icase, fname, cptext, cdir, flags, adup)
+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 */
+{
+ compl_T *match;
+ int dir = (cdir == 0 ? compl_direction : cdir);
+
+ ui_breakcheck();
+ if (got_int)
+ return FAIL;
+ if (len < 0)
+ len = (int)STRLEN(str);
+
+ /*
+ * If the same match is already present, don't add it.
+ */
+ 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)
+ return NOTDONE;
+ match = match->cp_next;
+ } while (match != NULL && match != compl_first_match);
+ }
+
+ /* Remove any popup menu before changing the list of matches. */
+ ins_compl_del_pum();
+
+ /*
+ * Allocate a new match structure.
+ * Copy the values to the new match structure.
+ */
+ match = (compl_T *)alloc_clear((unsigned)sizeof(compl_T));
+ if (match == NULL)
+ return FAIL;
+ match->cp_number = -1;
+ if (flags & ORIGINAL_TEXT)
+ match->cp_number = 0;
+ if ((match->cp_str = vim_strnsave(str, len)) == NULL) {
+ vim_free(match);
+ return FAIL;
+ }
+ match->cp_icase = icase;
+
+ /* match-fname is:
+ * - compl_curr_match->cp_fname if it is a string equal to fname.
+ * - a copy of fname, FREE_FNAME is set to free later THE allocated mem.
+ * - NULL otherwise. --Acevedo */
+ if (fname != NULL
+ && compl_curr_match != NULL
+ && compl_curr_match->cp_fname != NULL
+ && STRCMP(fname, compl_curr_match->cp_fname) == 0)
+ match->cp_fname = compl_curr_match->cp_fname;
+ else if (fname != NULL) {
+ match->cp_fname = vim_strsave(fname);
+ flags |= FREE_FNAME;
+ } 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]);
+ }
+
+ /*
+ * Link the new match structure in the list of matches.
+ */
+ if (compl_first_match == NULL)
+ match->cp_next = match->cp_prev = NULL;
+ else if (dir == FORWARD) {
+ match->cp_next = compl_curr_match->cp_next;
+ match->cp_prev = compl_curr_match;
+ } else { /* BACKWARD */
+ match->cp_next = compl_curr_match;
+ match->cp_prev = compl_curr_match->cp_prev;
+ }
+ if (match->cp_next)
+ match->cp_next->cp_prev = match;
+ if (match->cp_prev)
+ match->cp_prev->cp_next = match;
+ else /* if there's nothing before, it is the first match */
+ compl_first_match = match;
+ compl_curr_match = match;
+
+ /*
+ * Find the longest common string if still doing that.
+ */
+ if (compl_get_longest && (flags & ORIGINAL_TEXT) == 0)
+ ins_compl_longest_match(match);
+
+ return OK;
+}
+
+/*
+ * Return TRUE if "str[len]" matches with match->cp_str, considering
+ * match->cp_icase.
+ */
+static int ins_compl_equal(match, str, len)
+compl_T *match;
+char_u *str;
+int len;
+{
+ if (match->cp_icase)
+ return STRNICMP(match->cp_str, str, (size_t)len) == 0;
+ return STRNCMP(match->cp_str, str, (size_t)len) == 0;
+}
+
+/*
+ * Reduce the longest common string for match "match".
+ */
+static void ins_compl_longest_match(match)
+compl_T *match;
+{
+ char_u *p, *s;
+ int c1, c2;
+ int had_match;
+
+ if (compl_leader == NULL) {
+ /* First match, use it as a whole. */
+ compl_leader = vim_strsave(match->cp_str);
+ if (compl_leader != NULL) {
+ had_match = (curwin->w_cursor.col > compl_col);
+ ins_compl_delete();
+ ins_bytes(compl_leader + ins_compl_len());
+ ins_redraw(FALSE);
+
+ /* When the match isn't there (to avoid matching itself) remove it
+ * again after redrawing. */
+ if (!had_match)
+ ins_compl_delete();
+ compl_used_match = FALSE;
+ }
+ } else {
+ /* Reduce the text if this match differs from compl_leader. */
+ 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 ? (MB_TOLOWER(c1) != MB_TOLOWER(c2))
+ : (c1 != c2))
+ break;
+ if (has_mbyte) {
+ mb_ptr_adv(p);
+ mb_ptr_adv(s);
+ } else {
+ ++p;
+ ++s;
+ }
+ }
+
+ if (*p != NUL) {
+ /* Leader was shortened, need to change the inserted text. */
+ *p = NUL;
+ had_match = (curwin->w_cursor.col > compl_col);
+ ins_compl_delete();
+ ins_bytes(compl_leader + ins_compl_len());
+ ins_redraw(FALSE);
+
+ /* When the match isn't there (to avoid matching itself) remove it
+ * again after redrawing. */
+ if (!had_match)
+ ins_compl_delete();
+ }
+
+ compl_used_match = FALSE;
+ }
+}
+
+/*
+ * Add an array of matches to the list of matches.
+ * Frees matches[].
+ */
+static void ins_compl_add_matches(num_matches, matches, icase)
+int num_matches;
+char_u **matches;
+int icase;
+{
+ int i;
+ int add_r = OK;
+ int dir = compl_direction;
+
+ 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 */
+ dir = FORWARD;
+ FreeWild(num_matches, matches);
+}
+
+/* Make the completion list cyclic.
+ * Return the number of matches (excluding the original).
+ */
+static int ins_compl_make_cyclic() {
+ compl_T *match;
+ int count = 0;
+
+ if (compl_first_match != NULL) {
+ /*
+ * Find the end of the list.
+ */
+ match = compl_first_match;
+ /* there's always an entry for the compl_orig_text, it doesn't count. */
+ while (match->cp_next != NULL && match->cp_next != compl_first_match) {
+ match = match->cp_next;
+ ++count;
+ }
+ match->cp_next = compl_first_match;
+ compl_first_match->cp_prev = match;
+ }
+ return count;
+}
+
+/*
+ * Start completion for the complete() function.
+ * "startcol" is where the matched text starts (1 is first column).
+ * "list" is the list of matches.
+ */
+void set_completion(startcol, list)
+colnr_T startcol;
+list_T *list;
+{
+ /* If already doing completions stop it. */
+ if (ctrl_x_mode != 0)
+ ins_compl_prep(' ');
+ ins_compl_clear();
+
+ if (stop_arrow() == FAIL)
+ return;
+
+ compl_direction = FORWARD;
+ if (startcol > curwin->w_cursor.col)
+ startcol = curwin->w_cursor.col;
+ compl_col = startcol;
+ compl_length = (int)curwin->w_cursor.col - (int)startcol;
+ /* compl_pattern doesn't need to be set */
+ compl_orig_text = vim_strnsave(ml_get_curline() + compl_col, compl_length);
+ if (compl_orig_text == NULL || ins_compl_add(compl_orig_text,
+ -1, p_ic, NULL, NULL, 0, ORIGINAL_TEXT, FALSE) != OK)
+ return;
+
+ /* Handle like dictionary completion. */
+ ctrl_x_mode = CTRL_X_WHOLE_LINE;
+
+ ins_compl_add_list(list);
+ compl_matches = ins_compl_make_cyclic();
+ compl_started = TRUE;
+ compl_used_match = TRUE;
+ compl_cont_status = 0;
+
+ compl_curr_match = compl_first_match;
+ ins_complete(Ctrl_N);
+ out_flush();
+}
+
+
+/* "compl_match_array" points the currently displayed list of entries in the
+ * popup menu. It is NULL when there is no popup menu. */
+static pumitem_T *compl_match_array = NULL;
+static int compl_match_arraysize;
+
+/*
+ * Update the screen and when there is any scrolling remove the popup menu.
+ */
+static void ins_compl_upd_pum() {
+ int h;
+
+ if (compl_match_array != NULL) {
+ h = curwin->w_cline_height;
+ update_screen(0);
+ if (h != curwin->w_cline_height)
+ ins_compl_del_pum();
+ }
+}
+
+/*
+ * Remove any popup menu.
+ */
+static void ins_compl_del_pum() {
+ if (compl_match_array != NULL) {
+ pum_undisplay();
+ vim_free(compl_match_array);
+ compl_match_array = NULL;
+ }
+}
+
+/*
+ * Return TRUE if the popup menu should be displayed.
+ */
+static int pum_wanted() {
+ /* 'completeopt' must contain "menu" or "menuone" */
+ if (vim_strchr(p_cot, 'm') == NULL)
+ return FALSE;
+
+ /* The display looks bad on a B&W display. */
+ if (t_colors < 8
+ )
+ return FALSE;
+ return TRUE;
+}
+
+/*
+ * Return TRUE if there are two or more matches to be shown in the popup menu.
+ * One if 'completopt' contains "menuone".
+ */
+static int pum_enough_matches() {
+ compl_T *compl;
+ int i;
+
+ /* Don't display the popup menu if there are no matches or there is only
+ * one (ignoring the original text). */
+ compl = compl_first_match;
+ i = 0;
+ do {
+ if (compl == NULL
+ || ((compl->cp_flags & ORIGINAL_TEXT) == 0 && ++i == 2))
+ break;
+ compl = compl->cp_next;
+ } while (compl != compl_first_match);
+
+ if (strstr((char *)p_cot, "menuone") != NULL)
+ return i >= 1;
+ return i >= 2;
+}
+
+/*
+ * Show the popup menu for the list of matches.
+ * Also adjusts "compl_shown_match" to an entry that is actually displayed.
+ */
+void ins_compl_show_pum() {
+ compl_T *compl;
+ compl_T *shown_compl = NULL;
+ int did_find_shown_match = FALSE;
+ int shown_match_ok = FALSE;
+ int i;
+ int cur = -1;
+ colnr_T col;
+ int lead_len = 0;
+
+ if (!pum_wanted() || !pum_enough_matches())
+ return;
+
+ /* Dirty hard-coded hack: remove any matchparen highlighting. */
+ do_cmdline_cmd((char_u *)"if exists('g:loaded_matchparen')|3match none|endif");
+
+ /* Update the screen before drawing the popup menu over it. */
+ update_screen(0);
+
+ if (compl_match_array == NULL) {
+ /* Need to build the popup menu list. */
+ compl_match_arraysize = 0;
+ compl = compl_first_match;
+ if (compl_leader != NULL)
+ lead_len = (int)STRLEN(compl_leader);
+ do {
+ if ((compl->cp_flags & ORIGINAL_TEXT) == 0
+ && (compl_leader == NULL
+ || ins_compl_equal(compl, compl_leader, lead_len)))
+ ++compl_match_arraysize;
+ compl = compl->cp_next;
+ } while (compl != NULL && compl != compl_first_match);
+ if (compl_match_arraysize == 0)
+ return;
+ compl_match_array = (pumitem_T *)alloc_clear(
+ (unsigned)(sizeof(pumitem_T)
+ * compl_match_arraysize));
+ if (compl_match_array != NULL) {
+ /* If the current match is the original text don't find the first
+ * match after it, don't highlight anything. */
+ if (compl_shown_match->cp_flags & ORIGINAL_TEXT)
+ shown_match_ok = TRUE;
+
+ i = 0;
+ compl = compl_first_match;
+ do {
+ if ((compl->cp_flags & ORIGINAL_TEXT) == 0
+ && (compl_leader == NULL
+ || ins_compl_equal(compl, compl_leader, lead_len))) {
+ if (!shown_match_ok) {
+ if (compl == compl_shown_match || did_find_shown_match) {
+ /* This item is the shown match or this is the
+ * first displayed item after the shown match. */
+ compl_shown_match = compl;
+ did_find_shown_match = TRUE;
+ shown_match_ok = TRUE;
+ } else
+ /* Remember this displayed match for when the
+ * shown match is just below it. */
+ shown_compl = compl;
+ cur = i;
+ }
+
+ if (compl->cp_text[CPT_ABBR] != NULL)
+ compl_match_array[i].pum_text =
+ compl->cp_text[CPT_ABBR];
+ else
+ compl_match_array[i].pum_text = compl->cp_str;
+ compl_match_array[i].pum_kind = compl->cp_text[CPT_KIND];
+ compl_match_array[i].pum_info = compl->cp_text[CPT_INFO];
+ if (compl->cp_text[CPT_MENU] != NULL)
+ compl_match_array[i++].pum_extra =
+ compl->cp_text[CPT_MENU];
+ else
+ compl_match_array[i++].pum_extra = compl->cp_fname;
+ }
+
+ if (compl == compl_shown_match) {
+ did_find_shown_match = TRUE;
+
+ /* When the original text is the shown match don't set
+ * compl_shown_match. */
+ if (compl->cp_flags & ORIGINAL_TEXT)
+ shown_match_ok = TRUE;
+
+ if (!shown_match_ok && shown_compl != NULL) {
+ /* The shown match isn't displayed, set it to the
+ * previously displayed match. */
+ compl_shown_match = shown_compl;
+ shown_match_ok = TRUE;
+ }
+ }
+ compl = compl->cp_next;
+ } while (compl != NULL && compl != compl_first_match);
+
+ if (!shown_match_ok) /* no displayed match at all */
+ cur = -1;
+ }
+ } else {
+ /* popup menu already exists, only need to find the current item.*/
+ for (i = 0; i < compl_match_arraysize; ++i)
+ if (compl_match_array[i].pum_text == compl_shown_match->cp_str
+ || compl_match_array[i].pum_text
+ == compl_shown_match->cp_text[CPT_ABBR]) {
+ cur = i;
+ break;
+ }
+ }
+
+ if (compl_match_array != NULL) {
+ /* Compute the screen column of the start of the completed text.
+ * 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);
+ curwin->w_cursor.col = col;
+ }
+}
+
+#define DICT_FIRST (1) /* use just first element in "dict" */
+#define DICT_EXACT (2) /* "dict" is the exact name of a file */
+
+/*
+ * Add any identifiers that match the given pattern in the list of dictionary
+ * files "dict_start" to the list of completions.
+ */
+static void ins_compl_dictionaries(dict_start, pat, flags, thesaurus)
+char_u *dict_start;
+char_u *pat;
+int flags; /* DICT_FIRST and/or DICT_EXACT */
+int thesaurus; /* Thesaurus completion */
+{
+ char_u *dict = dict_start;
+ char_u *ptr;
+ char_u *buf;
+ regmatch_T regmatch;
+ char_u **files;
+ int count;
+ int save_p_scs;
+ int dir = compl_direction;
+
+ if (*dict == NUL) {
+ /* When 'dictionary' is empty and spell checking is enabled use
+ * "spell". */
+ if (!thesaurus && curwin->w_p_spell)
+ dict = (char_u *)"spell";
+ else
+ return;
+ }
+
+ buf = alloc(LSIZE);
+ if (buf == NULL)
+ return;
+ regmatch.regprog = NULL; /* so that we can goto theend */
+
+ /* If 'infercase' is set, don't use 'smartcase' here */
+ save_p_scs = p_scs;
+ if (curbuf->b_p_inf)
+ p_scs = FALSE;
+
+ /* When invoked to match whole lines for CTRL-X CTRL-L adjust the pattern
+ * to only match at the start of a line. Otherwise just match the
+ * pattern. Also need to double backslashes. */
+ if (ctrl_x_mode == CTRL_X_WHOLE_LINE) {
+ char_u *pat_esc = vim_strsave_escaped(pat, (char_u *)"\\");
+ size_t len;
+
+ if (pat_esc == NULL)
+ goto theend;
+ len = STRLEN(pat_esc) + 10;
+ ptr = alloc((unsigned)len);
+ if (ptr == NULL) {
+ vim_free(pat_esc);
+ goto theend;
+ }
+ vim_snprintf((char *)ptr, len, "^\\s*\\zs\\V%s", pat_esc);
+ regmatch.regprog = vim_regcomp(ptr, RE_MAGIC);
+ vim_free(pat_esc);
+ vim_free(ptr);
+ } else {
+ regmatch.regprog = vim_regcomp(pat, p_magic ? RE_MAGIC : 0);
+ if (regmatch.regprog == NULL)
+ goto theend;
+ }
+
+ /* ignore case depends on 'ignorecase', 'smartcase' and "pat" */
+ regmatch.rm_ic = ignorecase(pat);
+ while (*dict != NUL && !got_int && !compl_interrupted) {
+ /* copy one dictionary file name into buf */
+ if (flags == DICT_EXACT) {
+ count = 1;
+ files = &dict;
+ } else {
+ /* Expand wildcards in the dictionary name, but do not allow
+ * backticks (for security, the 'dict' option may have been set in
+ * a modeline). */
+ copy_option_part(&dict, buf, LSIZE, ",");
+ if (!thesaurus && STRCMP(buf, "spell") == 0)
+ count = -1;
+ else if (vim_strchr(buf, '`') != NULL
+ || expand_wildcards(1, &buf, &count, &files,
+ EW_FILE|EW_SILENT) != OK)
+ count = 0;
+ }
+
+ if (count == -1) {
+ /* Complete from active spelling. Skip "\<" in the pattern, we
+ * don't use it as a RE. */
+ if (pat[0] == '\\' && pat[1] == '<')
+ ptr = pat + 2;
+ else
+ ptr = pat;
+ spell_dump_compl(ptr, regmatch.rm_ic, &dir, 0);
+ } else if (count > 0) { /* avoid warning for using "files" uninit */
+ ins_compl_files(count, files, thesaurus, flags,
+ &regmatch, buf, &dir);
+ if (flags != DICT_EXACT)
+ FreeWild(count, files);
+ }
+ if (flags != 0)
+ break;
+ }
+
+theend:
+ p_scs = save_p_scs;
+ vim_regfree(regmatch.regprog);
+ vim_free(buf);
+}
+
+static void ins_compl_files(count, files, thesaurus, flags, regmatch, buf, dir)
+int count;
+char_u **files;
+int thesaurus;
+int flags;
+regmatch_T *regmatch;
+char_u *buf;
+int *dir;
+{
+ char_u *ptr;
+ int i;
+ FILE *fp;
+ int add_r;
+
+ for (i = 0; i < count && !got_int && !compl_interrupted; i++) {
+ 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));
+ }
+
+ if (fp != NULL) {
+ /*
+ * Read dictionary file line by line.
+ * Check each line for a match.
+ */
+ while (!got_int && !compl_interrupted
+ && !vim_fgets(buf, LSIZE, fp)) {
+ ptr = buf;
+ while (vim_regexec(regmatch, buf, (colnr_T)(ptr - buf))) {
+ ptr = regmatch->startp[0];
+ if (ctrl_x_mode == CTRL_X_WHOLE_LINE)
+ ptr = find_line_end(ptr);
+ else
+ ptr = find_word_end(ptr);
+ add_r = ins_compl_add_infercase(regmatch->startp[0],
+ (int)(ptr - regmatch->startp[0]),
+ p_ic, files[i], *dir, 0);
+ if (thesaurus) {
+ char_u *wstart;
+
+ /*
+ * Add the other matches on the line
+ */
+ ptr = buf;
+ while (!got_int) {
+ /* Find start of the next word. Skip white
+ * space and punctuation. */
+ ptr = find_word_start(ptr);
+ if (*ptr == NUL || *ptr == NL)
+ break;
+ wstart = ptr;
+
+ /* Find end of the word. */
+ if (has_mbyte)
+ /* Japanese words may have characters in
+ * different classes, only separate words
+ * with single-byte non-word characters. */
+ while (*ptr != NUL) {
+ int l = (*mb_ptr2len)(ptr);
+
+ if (l < 2 && !vim_iswordc(*ptr))
+ break;
+ ptr += l;
+ }
+ else
+ ptr = find_word_end(ptr);
+
+ /* Add the word. Skip the regexp match. */
+ if (wstart != regmatch->startp[0])
+ add_r = ins_compl_add_infercase(wstart,
+ (int)(ptr - wstart),
+ p_ic, files[i], *dir, 0);
+ }
+ }
+ if (add_r == OK)
+ /* if dir was BACKWARD then honor it just once */
+ *dir = FORWARD;
+ else if (add_r == FAIL)
+ break;
+ /* avoid expensive call to vim_regexec() when at end
+ * of line */
+ if (*ptr == '\n' || got_int)
+ break;
+ }
+ line_breakcheck();
+ ins_compl_check_keys(50);
+ }
+ fclose(fp);
+ }
+ }
+}
+
+/*
+ * Find the start of the next word.
+ * Returns a pointer to the first char of the word. Also stops at a NUL.
+ */
+char_u * find_word_start(ptr)
+char_u *ptr;
+{
+ if (has_mbyte)
+ while (*ptr != NUL && *ptr != '\n' && mb_get_class(ptr) <= 1)
+ ptr += (*mb_ptr2len)(ptr);
+ else
+ while (*ptr != NUL && *ptr != '\n' && !vim_iswordc(*ptr))
+ ++ptr;
+ return ptr;
+}
+
+/*
+ * Find the end of the word. Assumes it starts inside a word.
+ * Returns a pointer to just after the word.
+ */
+char_u * find_word_end(ptr)
+char_u *ptr;
+{
+ int start_class;
+
+ if (has_mbyte) {
+ start_class = mb_get_class(ptr);
+ if (start_class > 1)
+ while (*ptr != NUL) {
+ ptr += (*mb_ptr2len)(ptr);
+ if (mb_get_class(ptr) != start_class)
+ break;
+ }
+ } else
+ while (vim_iswordc(*ptr))
+ ++ptr;
+ return ptr;
+}
+
+/*
+ * Find the end of the line, omitting CR and NL at the end.
+ * Returns a pointer to just after the line.
+ */
+static char_u * find_line_end(ptr)
+char_u *ptr;
+{
+ char_u *s;
+
+ s = ptr + STRLEN(ptr);
+ while (s > ptr && (s[-1] == CAR || s[-1] == NL))
+ --s;
+ return s;
+}
+
+/*
+ * Free the list of completions
+ */
+static void ins_compl_free() {
+ compl_T *match;
+ int i;
+
+ vim_free(compl_pattern);
+ compl_pattern = NULL;
+ vim_free(compl_leader);
+ compl_leader = NULL;
+
+ if (compl_first_match == NULL)
+ return;
+
+ ins_compl_del_pum();
+ pum_clear();
+
+ compl_curr_match = compl_first_match;
+ do {
+ match = compl_curr_match;
+ compl_curr_match = compl_curr_match->cp_next;
+ vim_free(match->cp_str);
+ /* several entries may use the same fname, free it just once. */
+ if (match->cp_flags & FREE_FNAME)
+ vim_free(match->cp_fname);
+ for (i = 0; i < CPT_COUNT; ++i)
+ vim_free(match->cp_text[i]);
+ vim_free(match);
+ } while (compl_curr_match != NULL && compl_curr_match != compl_first_match);
+ compl_first_match = compl_curr_match = NULL;
+ compl_shown_match = NULL;
+}
+
+static void ins_compl_clear() {
+ compl_cont_status = 0;
+ compl_started = FALSE;
+ compl_matches = 0;
+ vim_free(compl_pattern);
+ compl_pattern = NULL;
+ vim_free(compl_leader);
+ compl_leader = NULL;
+ edit_submode_extra = NULL;
+ vim_free(compl_orig_text);
+ compl_orig_text = NULL;
+ compl_enter_selects = FALSE;
+}
+
+/*
+ * Return TRUE when Insert completion is active.
+ */
+int ins_compl_active() {
+ return compl_started;
+}
+
+/*
+ * Delete one character before the cursor and show the subset of the matches
+ * that match the word that is now before the cursor.
+ * Returns the character to be used, NUL if the work is done and another char
+ * to be got from the user.
+ */
+static int ins_compl_bs() {
+ char_u *line;
+ char_u *p;
+
+ line = ml_get_curline();
+ p = line + curwin->w_cursor.col;
+ 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. */
+ if ((int)(p - line) - (int)compl_col < 0
+ || ((int)(p - line) - (int)compl_col == 0
+ && (ctrl_x_mode & CTRL_X_OMNI) == 0))
+ return K_BS;
+
+ /* Deleted more than what was used to find matches or didn't finish
+ * finding all matches: need to look for matches all over again. */
+ if (curwin->w_cursor.col <= compl_col + compl_length
+ || ins_compl_need_restart())
+ ins_compl_restart();
+
+ vim_free(compl_leader);
+ compl_leader = vim_strnsave(line + compl_col, (int)(p - line) - compl_col);
+ if (compl_leader != NULL) {
+ ins_compl_new_leader();
+ if (compl_shown_match != NULL)
+ /* Make sure current match is not a hidden item. */
+ compl_curr_match = compl_shown_match;
+ return NUL;
+ }
+ return K_BS;
+}
+
+/*
+ * Return TRUE when we need to find matches again, ins_compl_restart() is to
+ * be called.
+ */
+static int ins_compl_need_restart() {
+ /* Return TRUE if we didn't complete finding matches or when the
+ * 'completefunc' returned "always" in the "refresh" dictionary item. */
+ return compl_was_interrupted
+ || ((ctrl_x_mode == CTRL_X_FUNCTION || ctrl_x_mode == CTRL_X_OMNI)
+ && compl_opt_refresh_always);
+}
+
+/*
+ * Called after changing "compl_leader".
+ * Show the popup menu with a different set of matches.
+ * May also search for matches again if the previous search was interrupted.
+ */
+static void ins_compl_new_leader() {
+ ins_compl_del_pum();
+ ins_compl_delete();
+ ins_bytes(compl_leader + ins_compl_len());
+ compl_used_match = FALSE;
+
+ if (compl_started)
+ ins_compl_set_original_text(compl_leader);
+ else {
+ spell_bad_len = 0; /* need to redetect bad word */
+ /*
+ * Matches were cleared, need to search for them now. First display
+ * the changed text before the cursor. Set "compl_restarting" to
+ * avoid that the first match is inserted.
+ */
+ update_screen(0);
+ compl_restarting = TRUE;
+ if (ins_complete(Ctrl_N) == FAIL)
+ compl_cont_status = 0;
+ compl_restarting = FALSE;
+ }
+
+ compl_enter_selects = !compl_used_match;
+
+ /* Show the popup menu with a different set of matches. */
+ ins_compl_show_pum();
+
+ /* Don't let Enter select the original text when there is no popup menu. */
+ if (compl_match_array == NULL)
+ compl_enter_selects = FALSE;
+}
+
+/*
+ * Return the length of the completion, from the completion start column to
+ * the cursor column. Making sure it never goes below zero.
+ */
+static int ins_compl_len() {
+ int off = (int)curwin->w_cursor.col - (int)compl_col;
+
+ if (off < 0)
+ return 0;
+ return off;
+}
+
+/*
+ * Append one character to the match leader. May reduce the number of
+ * matches.
+ */
+static void ins_compl_addleader(c)
+int c;
+{
+ int cc;
+
+ if (has_mbyte && (cc = (*mb_char2len)(c)) > 1) {
+ char_u buf[MB_MAXBYTES + 1];
+
+ (*mb_char2bytes)(c, buf);
+ buf[cc] = NUL;
+ ins_char_bytes(buf, cc);
+ if (compl_opt_refresh_always)
+ AppendToRedobuff(buf);
+ } else {
+ ins_char(c);
+ if (compl_opt_refresh_always)
+ AppendCharToRedobuff(c);
+ }
+
+ /* If we didn't complete finding matches we must search again. */
+ if (ins_compl_need_restart())
+ ins_compl_restart();
+
+ /* When 'always' is set, don't reset compl_leader. While completing,
+ * cursor doesn't point original position, changing compl_leader would
+ * break redo. */
+ if (!compl_opt_refresh_always) {
+ vim_free(compl_leader);
+ compl_leader = vim_strnsave(ml_get_curline() + compl_col,
+ (int)(curwin->w_cursor.col - compl_col));
+ if (compl_leader != NULL)
+ ins_compl_new_leader();
+ }
+}
+
+/*
+ * Setup for finding completions again without leaving CTRL-X mode. Used when
+ * BS or a key was typed while still searching for matches.
+ */
+static void ins_compl_restart() {
+ ins_compl_free();
+ compl_started = FALSE;
+ compl_matches = 0;
+ compl_cont_status = 0;
+ compl_cont_mode = 0;
+}
+
+/*
+ * Set the first match, the original text.
+ */
+static void ins_compl_set_original_text(str)
+char_u *str;
+{
+ char_u *p;
+
+ /* Replace the original text entry. */
+ if (compl_first_match->cp_flags & ORIGINAL_TEXT) { /* safety check */
+ p = vim_strsave(str);
+ if (p != NULL) {
+ vim_free(compl_first_match->cp_str);
+ compl_first_match->cp_str = p;
+ }
+ }
+}
+
+/*
+ * Append one character to the match leader. May reduce the number of
+ * matches.
+ */
+static void ins_compl_addfrommatch() {
+ char_u *p;
+ int len = (int)curwin->w_cursor.col - (int)compl_col;
+ int c;
+ compl_T *cp;
+
+ p = compl_shown_match->cp_str;
+ if ((int)STRLEN(p) <= len) { /* the match is too short */
+ /* When still at the original match use the first entry that matches
+ * the leader. */
+ if (compl_shown_match->cp_flags & ORIGINAL_TEXT) {
+ p = NULL;
+ for (cp = compl_shown_match->cp_next; cp != NULL
+ && cp != compl_first_match; cp = cp->cp_next) {
+ if (compl_leader == NULL
+ || ins_compl_equal(cp, compl_leader,
+ (int)STRLEN(compl_leader))) {
+ p = cp->cp_str;
+ break;
+ }
+ }
+ if (p == NULL || (int)STRLEN(p) <= len)
+ return;
+ } else
+ return;
+ }
+ p += len;
+ c = PTR2CHAR(p);
+ ins_compl_addleader(c);
+}
+
+/*
+ * Prepare for Insert mode completion, or stop it.
+ * Called just after typing a character in Insert mode.
+ * Returns TRUE when the character is not to be inserted;
+ */
+static int ins_compl_prep(c)
+int c;
+{
+ char_u *ptr;
+ int want_cindent;
+ int retval = FALSE;
+
+ /* Forget any previous 'special' messages if this is actually
+ * a ^X mode key - bar ^R, in which case we wait to see what it gives us.
+ */
+ if (c != Ctrl_R && vim_is_ctrl_x_key(c))
+ edit_submode_extra = NULL;
+
+ /* 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)
+ return retval;
+
+ /* Set "compl_get_longest" when finding the first matches. */
+ if (ctrl_x_mode == CTRL_X_NOT_DEFINED_YET
+ || (ctrl_x_mode == 0 && !compl_started)) {
+ compl_get_longest = (vim_strchr(p_cot, 'l') != NULL);
+ compl_used_match = TRUE;
+ }
+
+ if (ctrl_x_mode == CTRL_X_NOT_DEFINED_YET) {
+ /*
+ * We have just typed CTRL-X and aren't quite sure which CTRL-X mode
+ * it will be yet. Now we decide.
+ */
+ switch (c) {
+ case Ctrl_E:
+ case Ctrl_Y:
+ ctrl_x_mode = CTRL_X_SCROLL;
+ if (!(State & REPLACE_FLAG))
+ edit_submode = (char_u *)_(" (insert) Scroll (^E/^Y)");
+ else
+ edit_submode = (char_u *)_(" (replace) Scroll (^E/^Y)");
+ edit_submode_pre = NULL;
+ showmode();
+ break;
+ case Ctrl_L:
+ ctrl_x_mode = CTRL_X_WHOLE_LINE;
+ break;
+ case Ctrl_F:
+ ctrl_x_mode = CTRL_X_FILES;
+ break;
+ case Ctrl_K:
+ ctrl_x_mode = CTRL_X_DICTIONARY;
+ break;
+ case Ctrl_R:
+ /* Simply allow ^R to happen without affecting ^X mode */
+ break;
+ case Ctrl_T:
+ ctrl_x_mode = CTRL_X_THESAURUS;
+ break;
+ case Ctrl_U:
+ ctrl_x_mode = CTRL_X_FUNCTION;
+ break;
+ case Ctrl_O:
+ ctrl_x_mode = CTRL_X_OMNI;
+ break;
+ case 's':
+ case Ctrl_S:
+ ctrl_x_mode = CTRL_X_SPELL;
+ ++emsg_off; /* Avoid getting the E756 error twice. */
+ spell_back_to_badword();
+ --emsg_off;
+ break;
+ case Ctrl_RSB:
+ ctrl_x_mode = CTRL_X_TAGS;
+ break;
+ case Ctrl_I:
+ case K_S_TAB:
+ ctrl_x_mode = CTRL_X_PATH_PATTERNS;
+ break;
+ case Ctrl_D:
+ ctrl_x_mode = CTRL_X_PATH_DEFINES;
+ break;
+ case Ctrl_V:
+ case Ctrl_Q:
+ ctrl_x_mode = CTRL_X_CMDLINE;
+ break;
+ case Ctrl_P:
+ case Ctrl_N:
+ /* ^X^P means LOCAL expansion if nothing interrupted (eg we
+ * just started ^X mode, or there were enough ^X's to cancel
+ * the previous mode, say ^X^F^X^X^P or ^P^X^X^X^P, see below)
+ * do normal expansion when interrupting a different mode (say
+ * ^X^F^X^P or ^P^X^X^P, see below)
+ * nothing changes if interrupting mode 0, (eg, the flag
+ * doesn't change when going to ADDING mode -- Acevedo */
+ if (!(compl_cont_status & CONT_INTRPT))
+ compl_cont_status |= CONT_LOCAL;
+ else if (compl_cont_mode != 0)
+ compl_cont_status &= ~CONT_LOCAL;
+ /* 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
+ * mode).
+ * For mode 0, we set "compl_cont_mode" to an impossible
+ * value, in both cases ^X^X can be used to restart the same
+ * mode (avoiding ADDING mode).
+ * Undocumented feature: In a mode != 0 ^X^P and ^X^X^P start
+ * 'complete' and local ^P expansions respectively.
+ * In mode 0 an extra ^X is needed since ^X^P goes to ADDING
+ * mode -- Acevedo */
+ if (c == Ctrl_X) {
+ if (compl_cont_mode != 0)
+ compl_cont_status = 0;
+ else
+ compl_cont_mode = CTRL_X_NOT_DEFINED_YET;
+ }
+ ctrl_x_mode = 0;
+ edit_submode = NULL;
+ showmode();
+ break;
+ }
+ } else if (ctrl_x_mode != 0) {
+ /* We're already in CTRL-X mode, do we stay in it? */
+ if (!vim_is_ctrl_x_key(c)) {
+ if (ctrl_x_mode == CTRL_X_SCROLL)
+ ctrl_x_mode = 0;
+ else
+ ctrl_x_mode = CTRL_X_FINISHED;
+ edit_submode = NULL;
+ }
+ showmode();
+ }
+
+ if (compl_started || ctrl_x_mode == CTRL_X_FINISHED) {
+ /* Show error message from attempted keyword completion (probably
+ * 'Pattern not found') until another key is hit, then go back to
+ * showing what mode we are in. */
+ showmode();
+ if ((ctrl_x_mode == 0 && c != Ctrl_N && c != Ctrl_P && c != Ctrl_R
+ && !ins_compl_pum_key(c))
+ || ctrl_x_mode == CTRL_X_FINISHED) {
+ /* Get here when we have finished typing a sequence of ^N and
+ * ^P or other completion characters in CTRL-X mode. Free up
+ * memory that was used, and make sure we can redo the insert. */
+ if (compl_curr_match != NULL || compl_leader != NULL || c == Ctrl_E) {
+ /*
+ * If any of the original typed text has been changed, eg when
+ * ignorecase is set, we must add back-spaces to the redo
+ * buffer. We add as few as necessary to delete just the part
+ * of the original text that has changed.
+ * When using the longest match, edited the match or used
+ * CTRL-E then don't use the current match.
+ */
+ if (compl_curr_match != NULL && compl_used_match && c != Ctrl_E)
+ ptr = compl_curr_match->cp_str;
+ else
+ ptr = NULL;
+ ins_compl_fixRedoBufForLeader(ptr);
+ }
+
+ want_cindent = (can_cindent && cindent_on());
+ /*
+ * When completing whole lines: fix indent for 'cindent'.
+ * Otherwise, break line if it's too long.
+ */
+ if (compl_cont_mode == CTRL_X_WHOLE_LINE) {
+ /* re-indent the current line */
+ if (want_cindent) {
+ do_c_expr_indent();
+ want_cindent = FALSE; /* don't do it again */
+ }
+ } else {
+ int prev_col = curwin->w_cursor.col;
+
+ /* put the cursor on the last char, for 'tw' formatting */
+ if (prev_col > 0)
+ dec_cursor();
+ if (stop_arrow() == OK)
+ insertchar(NUL, 0, -1);
+ if (prev_col > 0
+ && ml_get_curline()[curwin->w_cursor.col] != NUL)
+ inc_cursor();
+ }
+
+ /* If the popup menu is displayed pressing CTRL-Y means accepting
+ * the selection without inserting anything. When
+ * compl_enter_selects is set the Enter key does the same. */
+ if ((c == Ctrl_Y || (compl_enter_selects
+ && (c == CAR || c == K_KENTER || c == NL)))
+ && pum_visible())
+ retval = TRUE;
+
+ /* CTRL-E means completion is Ended, go back to the typed text. */
+ if (c == Ctrl_E) {
+ ins_compl_delete();
+ if (compl_leader != NULL)
+ ins_bytes(compl_leader + ins_compl_len());
+ else if (compl_first_match != NULL)
+ ins_bytes(compl_orig_text + ins_compl_len());
+ retval = TRUE;
+ }
+
+ auto_format(FALSE, TRUE);
+
+ ins_compl_free();
+ compl_started = FALSE;
+ compl_matches = 0;
+ msg_clr_cmdline(); /* necessary for "noshowmode" */
+ ctrl_x_mode = 0;
+ compl_enter_selects = FALSE;
+ if (edit_submode != NULL) {
+ edit_submode = NULL;
+ showmode();
+ }
+
+ /*
+ * Indent now if a key was typed that is in 'cinkeys'.
+ */
+ if (want_cindent && in_cinkeys(KEY_COMPLETE, ' ', inindent(0)))
+ 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);
+ }
+ } 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);
+
+ /* reset continue_* if we left expansion-mode, if we stay they'll be
+ * (re)set properly in ins_complete() */
+ if (!vim_is_ctrl_x_key(c)) {
+ compl_cont_status = 0;
+ compl_cont_mode = 0;
+ }
+
+ return retval;
+}
+
+/*
+ * Fix the redo buffer for the completion leader replacing some of the typed
+ * text. This inserts backspaces and appends the changed text.
+ * "ptr" is the known leader text or NUL.
+ */
+static void ins_compl_fixRedoBufForLeader(ptr_arg)
+char_u *ptr_arg;
+{
+ int len;
+ char_u *p;
+ char_u *ptr = ptr_arg;
+
+ if (ptr == NULL) {
+ if (compl_leader != NULL)
+ ptr = compl_leader;
+ else
+ return; /* nothing to do */
+ }
+ 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))
+ AppendCharToRedobuff(K_BS);
+ } else
+ len = 0;
+ if (ptr != NULL)
+ AppendToRedobuffLit(ptr + len, -1);
+}
+
+/*
+ * Loops through the list of windows, loaded-buffers or non-loaded-buffers
+ * (depending on flag) starting from buf and looking for a non-scanned
+ * buffer (other than curbuf). curbuf is special, if it is called with
+ * buf=curbuf then it has to be the first call for a given flag/expansion.
+ *
+ * Returns the buffer to scan, if any, otherwise returns curbuf -- Acevedo
+ */
+static buf_T * ins_compl_next_buf(buf, flag)
+buf_T *buf;
+int flag;
+{
+ static win_T *wp;
+
+ if (flag == 'w') { /* just windows */
+ if (buf == curbuf) /* first call for this flag/expansion */
+ wp = curwin;
+ while ((wp = (wp->w_next != NULL ? wp->w_next : firstwin)) != curwin
+ && wp->w_buffer->b_scanned)
+ ;
+ buf = wp->w_buffer;
+ } else
+ /* 'b' (just loaded buffers), 'u' (just non-loaded buffers) or 'U'
+ * (unlisted buffers)
+ * When completing whole lines skip unloaded buffers. */
+ while ((buf = (buf->b_next != NULL ? buf->b_next : firstbuf)) != curbuf
+ && ((flag == 'U'
+ ? buf->b_p_bl
+ : (!buf->b_p_bl
+ || (buf->b_ml.ml_mfp == NULL) != (flag == 'u')))
+ || buf->b_scanned))
+ ;
+ return buf;
+}
+
+static void expand_by_function __ARGS((int type, char_u *base));
+
+/*
+ * Execute user defined complete function 'completefunc' or 'omnifunc', and
+ * get matches in "matches".
+ */
+static void expand_by_function(type, base)
+int type; /* CTRL_X_OMNI or CTRL_X_FUNCTION */
+char_u *base;
+{
+ 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;
+
+ 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;
+
+ pos = curwin->w_cursor;
+ curwin_save = curwin;
+ curbuf_save = curbuf;
+
+ /* Call a function, which returns a list or dict. */
+ if (call_vim_function(funcname, 2, args, FALSE, FALSE, &rettv) == OK) {
+ switch (rettv.v_type) {
+ case VAR_LIST:
+ matchlist = rettv.vval.v_list;
+ break;
+ case VAR_DICT:
+ matchdict = rettv.vval.v_dict;
+ break;
+ default:
+ /* TODO: Give error message? */
+ clear_tv(&rettv);
+ break;
+ }
+ }
+
+ if (curwin_save != curwin || curbuf_save != curbuf) {
+ EMSG(_(e_complwin));
+ goto theend;
+ }
+ curwin->w_cursor = pos; /* restore the cursor position */
+ check_cursor();
+ if (!equalpos(curwin->w_cursor, pos)) {
+ EMSG(_(e_compldel));
+ goto theend;
+ }
+
+ if (matchlist != NULL)
+ ins_compl_add_list(matchlist);
+ else if (matchdict != NULL)
+ ins_compl_add_dict(matchdict);
+
+theend:
+ if (matchdict != NULL)
+ dict_unref(matchdict);
+ if (matchlist != NULL)
+ list_unref(matchlist);
+}
+
+/*
+ * Add completions from a list.
+ */
+static void ins_compl_add_list(list)
+list_T *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 */
+ dir = FORWARD;
+ else if (did_emsg)
+ break;
+ }
+}
+
+/*
+ * Add completions from a dict.
+ */
+static void ins_compl_add_dict(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);
+ if (di_refresh != NULL && di_refresh->di_tv.v_type == VAR_STRING) {
+ char_u *v = di_refresh->di_tv.vval.v_string;
+
+ if (v != NULL && STRCMP(v, (char_u *)"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)
+ 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,
+ * maybe because alloc() returns NULL, then FAIL is returned.
+ */
+int ins_compl_add_tv(tv, dir)
+typval_T *tv;
+int dir;
+{
+ char_u *word;
+ int icase = FALSE;
+ int adup = FALSE;
+ int aempty = FALSE;
+ char_u *(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");
+ } else {
+ word = get_tv_string_chk(tv);
+ vim_memset(cptext, 0, sizeof(cptext));
+ }
+ if (word == NULL || (!aempty && *word == NUL))
+ return FAIL;
+ return ins_compl_add(word, -1, icase, NULL, cptext, dir, 0, adup);
+}
+
+/*
+ * Get the next expansion(s), using "compl_pattern".
+ * The search starts at position "ini" in curbuf and in the direction
+ * compl_direction.
+ * When "compl_started" is FALSE start at that position, otherwise continue
+ * where we stopped searching before.
+ * This may return before finding all the matches.
+ * Return the total number of matches or -1 if still unknown -- Acevedo
+ */
+static int ins_compl_get_exp(ini)
+pos_T *ini;
+{
+ static pos_T first_match_pos;
+ static pos_T last_match_pos;
+ static char_u *e_cpt = (char_u *)""; /* curr. entry in 'complete' */
+ static int found_all = FALSE; /* Found all matches of a
+ certain type. */
+ static buf_T *ins_buf = NULL; /* buffer being scanned */
+
+ pos_T *pos;
+ char_u **matches;
+ int save_p_scs;
+ int save_p_ws;
+ int save_p_ic;
+ int i;
+ int num_matches;
+ int len;
+ int found_new_match;
+ int type = ctrl_x_mode;
+ char_u *ptr;
+ char_u *dict = NULL;
+ int dict_f = 0;
+ compl_T *old_match;
+ int set_match_pos;
+
+ if (!compl_started) {
+ for (ins_buf = firstbuf; ins_buf != NULL; ins_buf = ins_buf->b_next)
+ ins_buf->b_scanned = 0;
+ found_all = FALSE;
+ ins_buf = curbuf;
+ e_cpt = (compl_cont_status & CONT_LOCAL)
+ ? (char_u *)"." : curbuf->b_p_cpt;
+ last_match_pos = first_match_pos = *ini;
+ }
+
+ 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 (;; ) {
+ found_new_match = FAIL;
+ set_match_pos = FALSE;
+
+ /* For ^N/^P pick a new entry from e_cpt if compl_started is off,
+ * or if found_all says this entry is done. For ^X^L only use the
+ * entries from 'complete' that look in loaded buffers. */
+ if ((ctrl_x_mode == 0 || ctrl_x_mode == CTRL_X_WHOLE_LINE)
+ && (!compl_started || found_all)) {
+ found_all = FALSE;
+ while (*e_cpt == ',' || *e_cpt == ' ')
+ e_cpt++;
+ if (*e_cpt == '.' && !curbuf->b_scanned) {
+ ins_buf = curbuf;
+ first_match_pos = *ini;
+ /* So that ^N can match word immediately after cursor */
+ if (ctrl_x_mode == 0)
+ dec(&first_match_pos);
+ last_match_pos = first_match_pos;
+ type = 0;
+
+ /* Remember the first match so that the loop stops when we
+ * wrap and come back there a second time. */
+ set_match_pos = TRUE;
+ } else if (vim_strchr((char_u *)"buwU", *e_cpt) != NULL
+ && (ins_buf =
+ ins_compl_next_buf(ins_buf, *e_cpt)) != curbuf) {
+ /* Scan a buffer, but not the current one. */
+ if (ins_buf->b_ml.ml_mfp != NULL) { /* loaded buffer */
+ compl_started = TRUE;
+ first_match_pos.col = last_match_pos.col = 0;
+ first_match_pos.lnum = ins_buf->b_ml.ml_line_count + 1;
+ last_match_pos.lnum = 0;
+ type = 0;
+ } else { /* unloaded buffer, scan like dictionary */
+ found_all = TRUE;
+ if (ins_buf->b_fname == NULL)
+ continue;
+ type = CTRL_X_DICTIONARY;
+ dict = ins_buf->b_fname;
+ 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)
+ break;
+ else {
+ if (ctrl_x_mode == CTRL_X_WHOLE_LINE)
+ type = -1;
+ else if (*e_cpt == 'k' || *e_cpt == 's') {
+ if (*e_cpt == 'k')
+ type = CTRL_X_DICTIONARY;
+ else
+ type = CTRL_X_THESAURUS;
+ if (*++e_cpt != ',' && *e_cpt != NUL) {
+ dict = e_cpt;
+ dict_f = DICT_FIRST;
+ }
+ } else if (*e_cpt == 'i')
+ type = CTRL_X_PATH_PATTERNS;
+ else if (*e_cpt == 'd')
+ type = CTRL_X_PATH_DEFINES;
+ 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
+ type = -1;
+
+ /* in any case e_cpt is advanced to the next entry */
+ (void)copy_option_part(&e_cpt, IObuff, IOSIZE, ",");
+
+ found_all = TRUE;
+ if (type == -1)
+ continue;
+ }
+ }
+
+ switch (type) {
+ case -1:
+ break;
+ case CTRL_X_PATH_PATTERNS:
+ case CTRL_X_PATH_DEFINES:
+ find_pattern_in_path(compl_pattern, compl_direction,
+ (int)STRLEN(compl_pattern), FALSE, FALSE,
+ (type == CTRL_X_PATH_DEFINES
+ && !(compl_cont_status & CONT_SOL))
+ ? FIND_DEFINE : FIND_ANY, 1L, ACTION_EXPAND,
+ (linenr_T)1, (linenr_T)MAXLNUM);
+ break;
+
+ case CTRL_X_DICTIONARY:
+ case CTRL_X_THESAURUS:
+ ins_compl_dictionaries(
+ dict != NULL ? dict
+ : (type == CTRL_X_THESAURUS
+ ? (*curbuf->b_p_tsr == NUL
+ ? p_tsr
+ : curbuf->b_p_tsr)
+ : (*curbuf->b_p_dict == NUL
+ ? p_dict
+ : curbuf->b_p_dict)),
+ compl_pattern,
+ dict != NULL ? dict_f
+ : 0, type == CTRL_X_THESAURUS);
+ dict = NULL;
+ break;
+
+ case CTRL_X_TAGS:
+ /* set p_ic according to p_ic, p_scs and pat for find_tags(). */
+ save_p_ic = p_ic;
+ p_ic = ignorecase(compl_pattern);
+
+ /* Find up to TAG_MANY matches. Avoids that an enormous number
+ * of matches is found when compl_pattern is empty */
+ if (find_tags(compl_pattern, &num_matches, &matches,
+ TAG_REGEXP | TAG_NAMES | TAG_NOIC |
+ TAG_INS_COMP | (ctrl_x_mode ? TAG_VERBOSE : 0),
+ TAG_MANY, curbuf->b_ffname) == OK && num_matches > 0) {
+ ins_compl_add_matches(num_matches, matches, p_ic);
+ }
+ p_ic = save_p_ic;
+ break;
+
+ case CTRL_X_FILES:
+ if (expand_wildcards(1, &compl_pattern, &num_matches, &matches,
+ EW_FILE|EW_DIR|EW_ADDSLASH|EW_SILENT) == OK) {
+
+ /* May change home directory back to "~". */
+ tilde_replace(compl_pattern, num_matches, matches);
+ ins_compl_add_matches(num_matches, matches, p_fic || p_wic);
+ }
+ break;
+
+ case CTRL_X_CMDLINE:
+ if (expand_cmdline(&compl_xp, compl_pattern,
+ (int)STRLEN(compl_pattern),
+ &num_matches, &matches) == EXPAND_OK)
+ ins_compl_add_matches(num_matches, matches, FALSE);
+ break;
+
+ case CTRL_X_FUNCTION:
+ case CTRL_X_OMNI:
+ expand_by_function(type, compl_pattern);
+ break;
+
+ case CTRL_X_SPELL:
+ num_matches = expand_spelling(first_match_pos.lnum,
+ compl_pattern, &matches);
+ if (num_matches > 0)
+ ins_compl_add_matches(num_matches, matches, p_ic);
+ break;
+
+ default: /* normal ^P/^N and ^X^L */
+ /*
+ * If 'infercase' is set, don't use 'smartcase' here
+ */
+ save_p_scs = p_scs;
+ if (ins_buf->b_p_inf)
+ p_scs = FALSE;
+
+ /* Buffers other than curbuf are scanned from the beginning or the
+ * end but never from the middle, thus setting nowrapscan in this
+ * buffers is a good idea, on the other hand, we always set
+ * wrapscan for curbuf to avoid missing matches -- Acevedo,Webb */
+ save_p_ws = p_ws;
+ if (ins_buf != curbuf)
+ p_ws = FALSE;
+ else if (*e_cpt == '.')
+ p_ws = TRUE;
+ for (;; ) {
+ int flags = 0;
+
+ ++msg_silent; /* Don't want messages for wrapscan. */
+
+ /* ctrl_x_mode == CTRL_X_WHOLE_LINE || word-wise search that
+ * has added a word that was at the beginning of the line */
+ if ( ctrl_x_mode == CTRL_X_WHOLE_LINE
+ || (compl_cont_status & CONT_SOL))
+ found_new_match = search_for_exact_line(ins_buf, pos,
+ compl_direction, compl_pattern);
+ else
+ found_new_match = searchit(NULL, ins_buf, pos,
+ compl_direction,
+ compl_pattern, 1L, SEARCH_KEEP + SEARCH_NFMSG,
+ RE_LAST, (linenr_T)0, NULL);
+ --msg_silent;
+ if (!compl_started || set_match_pos) {
+ /* set "compl_started" even on fail */
+ compl_started = TRUE;
+ first_match_pos = *pos;
+ last_match_pos = *pos;
+ set_match_pos = FALSE;
+ } else if (first_match_pos.lnum == last_match_pos.lnum
+ && first_match_pos.col == last_match_pos.col)
+ found_new_match = FAIL;
+ if (found_new_match == FAIL) {
+ if (ins_buf == curbuf)
+ found_all = TRUE;
+ break;
+ }
+
+ /* when ADDING, the text before the cursor matches, skip it */
+ if ( (compl_cont_status & CONT_ADDING) && ins_buf == curbuf
+ && ini->lnum == pos->lnum
+ && ini->col == pos->col)
+ continue;
+ ptr = ml_get_buf(ins_buf, pos->lnum, FALSE) + pos->col;
+ if (ctrl_x_mode == CTRL_X_WHOLE_LINE) {
+ if (compl_cont_status & CONT_ADDING) {
+ if (pos->lnum >= ins_buf->b_ml.ml_line_count)
+ continue;
+ ptr = ml_get_buf(ins_buf, pos->lnum + 1, FALSE);
+ if (!p_paste)
+ ptr = skipwhite(ptr);
+ }
+ len = (int)STRLEN(ptr);
+ } else {
+ char_u *tmp_ptr = ptr;
+
+ if (compl_cont_status & CONT_ADDING) {
+ tmp_ptr += compl_length;
+ /* Skip if already inside a word. */
+ if (vim_iswordp(tmp_ptr))
+ continue;
+ /* Find start of next word. */
+ tmp_ptr = find_word_start(tmp_ptr);
+ }
+ /* Find end of this word. */
+ tmp_ptr = find_word_end(tmp_ptr);
+ len = (int)(tmp_ptr - ptr);
+
+ 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 */
+ STRNCPY(IObuff, ptr, len);
+ 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);
+ /* Find end of next word. */
+ tmp_ptr = find_word_end(tmp_ptr);
+ if (tmp_ptr > ptr) {
+ if (*ptr != ')' && IObuff[len - 1] != TAB) {
+ if (IObuff[len - 1] != ' ')
+ IObuff[len++] = ' ';
+ /* IObuf =~ "\k.* ", thus len >= 2 */
+ if (p_js
+ && (IObuff[len - 2] == '.'
+ || (vim_strchr(p_cpo, CPO_JOINSP)
+ == NULL
+ && (IObuff[len - 2] == '?'
+ || IObuff[len - 2] == '!'))))
+ IObuff[len++] = ' ';
+ }
+ /* copy as much as possible of the new word */
+ if (tmp_ptr - ptr >= IOSIZE - len)
+ tmp_ptr = ptr + IOSIZE - len - 1;
+ STRNCPY(IObuff + len, ptr, tmp_ptr - ptr);
+ len += (int)(tmp_ptr - ptr);
+ flags |= CONT_S_IPOS;
+ }
+ IObuff[len] = NUL;
+ ptr = IObuff;
+ }
+ if (len == compl_length)
+ continue;
+ }
+ }
+ if (ins_compl_add_infercase(ptr, len, p_ic,
+ ins_buf == curbuf ? NULL : ins_buf->b_sfname,
+ 0, flags) != NOTDONE) {
+ found_new_match = OK;
+ break;
+ }
+ }
+ p_scs = save_p_scs;
+ 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)
+ found_new_match = OK;
+
+ /* break the loop for specialized modes (use 'complete' just for the
+ * generic ctrl_x_mode == 0) or when we've found a new match */
+ if ((ctrl_x_mode != 0 && ctrl_x_mode != CTRL_X_WHOLE_LINE)
+ || found_new_match != FAIL) {
+ if (got_int)
+ break;
+ /* Fill the popup menu as soon as possible. */
+ if (type != -1)
+ ins_compl_check_keys(0);
+
+ if ((ctrl_x_mode != 0 && ctrl_x_mode != CTRL_X_WHOLE_LINE)
+ || compl_interrupted)
+ break;
+ compl_started = TRUE;
+ } else {
+ /* Mark a buffer scanned when it has been scanned completely */
+ if (type == 0 || type == CTRL_X_PATH_PATTERNS)
+ ins_buf->b_scanned = TRUE;
+
+ compl_started = FALSE;
+ }
+ }
+ compl_started = TRUE;
+
+ if ((ctrl_x_mode == 0 || ctrl_x_mode == CTRL_X_WHOLE_LINE)
+ && *e_cpt == NUL) /* Got to end of 'complete' */
+ found_new_match = FAIL;
+
+ i = -1; /* total of matches, unknown */
+ if (found_new_match == FAIL
+ || (ctrl_x_mode != 0 && ctrl_x_mode != CTRL_X_WHOLE_LINE))
+ 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;
+ return i;
+}
+
+/* Delete the old text being completed. */
+static void ins_compl_delete() {
+ int i;
+
+ /*
+ * 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);
+ changed_cline_bef_curs();
+}
+
+/* Insert the new text being completed. */
+static void ins_compl_insert() {
+ ins_bytes(compl_shown_match->cp_str + ins_compl_len());
+ if (compl_shown_match->cp_flags & ORIGINAL_TEXT)
+ compl_used_match = FALSE;
+ else
+ compl_used_match = TRUE;
+}
+
+/*
+ * Fill in the next completion in the current direction.
+ * If "allow_get_expansion" is TRUE, then we may call ins_compl_get_exp() to
+ * get more completions. If it is FALSE, then we just do nothing when there
+ * are no more completions in a given direction. The latter case is used when
+ * we are still in the middle of finding completions, to allow browsing
+ * through the ones found so far.
+ * Return the total number of matches, or -1 if still unknown -- webb.
+ *
+ * compl_curr_match is currently being used by ins_compl_get_exp(), so we use
+ * compl_shown_match here.
+ *
+ * Note that this function may be called recursively once only. First with
+ * "allow_get_expansion" TRUE, which calls ins_compl_get_exp(), which in turn
+ * calls this function with "allow_get_expansion" FALSE.
+ */
+static int ins_compl_next(allow_get_expansion, count, insert_match)
+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 num_matches = -1;
+ int i;
+ int todo = count;
+ compl_T *found_compl = NULL;
+ int found_end = FALSE;
+ int advance;
+
+ /* When user complete function return -1 for findstart which is next
+ * time of 'always', compl_shown_match become NULL. */
+ if (compl_shown_match == NULL)
+ return -1;
+
+ if (compl_leader != NULL
+ && (compl_shown_match->cp_flags & ORIGINAL_TEXT) == 0) {
+ /* Set "compl_shown_match" to the actually shown match, it may differ
+ * when "compl_leader" is used to omit some of the matches. */
+ while (!ins_compl_equal(compl_shown_match,
+ compl_leader, (int)STRLEN(compl_leader))
+ && compl_shown_match->cp_next != NULL
+ && compl_shown_match->cp_next != compl_first_match)
+ compl_shown_match = compl_shown_match->cp_next;
+
+ /* If we didn't find it searching forward, and compl_shows_dir is
+ * backward, find the last match. */
+ if (compl_shows_dir == BACKWARD
+ && !ins_compl_equal(compl_shown_match,
+ compl_leader, (int)STRLEN(compl_leader))
+ && (compl_shown_match->cp_next == NULL
+ || compl_shown_match->cp_next == compl_first_match)) {
+ while (!ins_compl_equal(compl_shown_match,
+ compl_leader, (int)STRLEN(compl_leader))
+ && compl_shown_match->cp_prev != NULL
+ && compl_shown_match->cp_prev != compl_first_match)
+ compl_shown_match = compl_shown_match->cp_prev;
+ }
+ }
+
+ if (allow_get_expansion && insert_match
+ && (!(compl_get_longest || compl_restarting) || compl_used_match))
+ /* Delete old text to be replaced */
+ ins_compl_delete();
+
+ /* When finding the longest common text we stick at the original text,
+ * don't let CTRL-N or CTRL-P move to the first match. */
+ advance = count != 1 || !allow_get_expansion || !compl_get_longest;
+
+ /* When restarting the search don't insert the first match either. */
+ if (compl_restarting) {
+ advance = FALSE;
+ compl_restarting = FALSE;
+ }
+
+ /* Repeat this for when <PageUp> or <PageDown> is typed. But don't wrap
+ * around. */
+ while (--todo >= 0) {
+ if (compl_shows_dir == FORWARD && compl_shown_match->cp_next != NULL) {
+ compl_shown_match = compl_shown_match->cp_next;
+ found_end = (compl_first_match != NULL
+ && (compl_shown_match->cp_next == compl_first_match
+ || compl_shown_match == compl_first_match));
+ } else if (compl_shows_dir == BACKWARD
+ && compl_shown_match->cp_prev != NULL) {
+ found_end = (compl_shown_match == compl_first_match);
+ compl_shown_match = compl_shown_match->cp_prev;
+ found_end |= (compl_shown_match == compl_first_match);
+ } else {
+ if (!allow_get_expansion) {
+ if (advance) {
+ if (compl_shows_dir == BACKWARD)
+ compl_pending -= todo + 1;
+ else
+ compl_pending += todo + 1;
+ }
+ return -1;
+ }
+
+ if (advance) {
+ if (compl_shows_dir == BACKWARD)
+ --compl_pending;
+ else
+ ++compl_pending;
+ }
+
+ /* Find matches. */
+ num_matches = ins_compl_get_exp(&compl_startpos);
+
+ /* handle any pending completions */
+ while (compl_pending != 0 && compl_direction == compl_shows_dir
+ && advance) {
+ if (compl_pending > 0 && compl_shown_match->cp_next != NULL) {
+ compl_shown_match = compl_shown_match->cp_next;
+ --compl_pending;
+ }
+ if (compl_pending < 0 && compl_shown_match->cp_prev != NULL) {
+ compl_shown_match = compl_shown_match->cp_prev;
+ ++compl_pending;
+ } else
+ break;
+ }
+ found_end = FALSE;
+ }
+ if ((compl_shown_match->cp_flags & ORIGINAL_TEXT) == 0
+ && compl_leader != NULL
+ && !ins_compl_equal(compl_shown_match,
+ compl_leader, (int)STRLEN(compl_leader)))
+ ++todo;
+ else
+ /* Remember a matching item. */
+ found_compl = compl_shown_match;
+
+ /* Stop at the end of the list when we found a usable match. */
+ if (found_end) {
+ if (found_compl != NULL) {
+ compl_shown_match = found_compl;
+ break;
+ }
+ todo = 1; /* use first usable match after wrapping around */
+ }
+ }
+
+ /* Insert the text of the new completion, or the compl_leader. */
+ if (insert_match) {
+ if (!compl_get_longest || compl_used_match)
+ ins_compl_insert();
+ else
+ ins_bytes(compl_leader + ins_compl_len());
+ } else
+ compl_used_match = FALSE;
+
+ if (!allow_get_expansion) {
+ /* may undisplay the popup menu first */
+ ins_compl_upd_pum();
+
+ /* redraw to show the user what was inserted */
+ update_screen(0);
+
+ /* display the updated popup menu */
+ ins_compl_show_pum();
+
+ /* Delete old text to be replaced, since we're still searching and
+ * don't want to match ourselves! */
+ ins_compl_delete();
+ }
+
+ /* Enter will select a match when the match wasn't inserted and the popup
+ * menu is visible. */
+ compl_enter_selects = !insert_match && compl_match_array != NULL;
+
+ /*
+ * Show the file name for the match (if any)
+ * 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! */
+ }
+
+ 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(frequency)
+int frequency;
+{
+ static int count = 0;
+
+ int c;
+
+ /* Don't check when reading keys from a script. That would break the test
+ * scripts */
+ if (using_script())
+ return;
+
+ /* Only do this at regular intervals */
+ if (++count < frequency)
+ return;
+ count = 0;
+
+ /* Check for a typed key. Do use mappings, otherwise vim_is_ctrl_x_key()
+ * can't do its work correctly. */
+ c = vpeekc_any();
+ if (c != NUL) {
+ 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);
+ } else {
+ /* Need to get the character to have KeyTyped set. We'll put it
+ * back with vungetc() below. But skip K_IGNORE. */
+ c = safe_vgetc();
+ if (c != K_IGNORE) {
+ /* Don't interrupt completion when the character wasn't typed,
+ * e.g., when doing @q to replay keys. */
+ if (c != Ctrl_R && KeyTyped)
+ compl_interrupted = TRUE;
+
+ vungetc(c);
+ }
+ }
+ }
+ if (compl_pending != 0 && !got_int) {
+ int todo = compl_pending > 0 ? compl_pending : -compl_pending;
+
+ compl_pending = 0;
+ (void)ins_compl_next(FALSE, todo, TRUE);
+ }
+}
+
+/*
+ * Decide the direction of Insert mode complete from the key typed.
+ * Returns BACKWARD or FORWARD.
+ */
+static int ins_compl_key2dir(c)
+int c;
+{
+ if (c == Ctrl_P || c == Ctrl_L
+ || (pum_visible() && (c == K_PAGEUP || c == K_KPAGEUP
+ || c == K_S_UP || c == K_UP)))
+ return BACKWARD;
+ return FORWARD;
+}
+
+/*
+ * Return TRUE for keys that are used for completion only when the popup menu
+ * is visible.
+ */
+static int ins_compl_pum_key(c)
+int c;
+{
+ return pum_visible() && (c == K_PAGEUP || c == K_KPAGEUP || c == K_S_UP
+ || c == K_PAGEDOWN || c == K_KPAGEDOWN || c ==
+ K_S_DOWN
+ || c == K_UP || c == K_DOWN);
+}
+
+/*
+ * Decide the number of completions to move forward.
+ * Returns 1 for most keys, height of the popup menu for page-up/down keys.
+ */
+static int ins_compl_key2count(c)
+int c;
+{
+ int h;
+
+ if (ins_compl_pum_key(c) && c != K_UP && c != K_DOWN) {
+ h = pum_get_height();
+ if (h > 3)
+ h -= 2; /* keep some context */
+ return h;
+ }
+ return 1;
+}
+
+/*
+ * Return TRUE if completion with "c" should insert the match, FALSE if only
+ * to change the currently selected completion.
+ */
+static int ins_compl_use_match(c)
+int c;
+{
+ switch (c) {
+ case K_UP:
+ case K_DOWN:
+ case K_PAGEDOWN:
+ case K_KPAGEDOWN:
+ case K_S_DOWN:
+ case K_PAGEUP:
+ case K_KPAGEUP:
+ case K_S_UP:
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/*
+ * Do Insert mode completion.
+ * Called when character "c" was typed, which has a meaning for completion.
+ * Returns OK if completion was done, FAIL if something failed (out of mem).
+ */
+static int ins_complete(c)
+int c;
+{
+ char_u *line;
+ int startcol = 0; /* column where searched text starts */
+ colnr_T curs_col; /* cursor column */
+ int n;
+ int save_w_wrow;
+
+ compl_direction = ins_compl_key2dir(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)
+ return FAIL;
+
+ line = ml_get(curwin->w_cursor.lnum);
+ curs_col = curwin->w_cursor.col;
+ compl_pending = 0;
+
+ /* If this same ctrl_x_mode has been interrupted use the text from
+ * "compl_startpos" to the cursor as a pattern to add a new word
+ * instead of expand the one before the cursor, in word-wise if
+ * "compl_startpos" is not in the same line as the cursor then fix it
+ * (the line has been split because it was longer than 'tw'). if SOL
+ * is set then skip the previous pattern, a word at the beginning of
+ * the line has been inserted, we'll look for that -- Acevedo. */
+ if ((compl_cont_status & CONT_INTRPT) == CONT_INTRPT
+ && compl_cont_mode == ctrl_x_mode) {
+ /*
+ * it is a continued search
+ */
+ compl_cont_status &= ~CONT_INTRPT; /* remove INTRPT */
+ if (ctrl_x_mode == 0 || ctrl_x_mode == CTRL_X_PATH_PATTERNS
+ || ctrl_x_mode == CTRL_X_PATH_DEFINES) {
+ if (compl_startpos.lnum != curwin->w_cursor.lnum) {
+ /* line (probably) wrapped, set compl_startpos to the
+ * 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_startpos.col = compl_col;
+ compl_startpos.lnum = curwin->w_cursor.lnum;
+ compl_cont_status &= ~CONT_SOL; /* clear SOL if present */
+ } else {
+ /* S_IPOS was set when we inserted a word that was at the
+ * beginning of the line, which means that we'll go to SOL
+ * mode but first we need to redefine compl_startpos */
+ if (compl_cont_status & CONT_S_IPOS) {
+ compl_cont_status |= CONT_SOL;
+ compl_startpos.col = (colnr_T)(skipwhite(
+ line + compl_length
+ + compl_startpos.col) - line);
+ }
+ compl_col = compl_startpos.col;
+ }
+ compl_length = curwin->w_cursor.col - (int)compl_col;
+ /* IObuff is used to add a "word from the next line" would we
+ * have enough space? just being paranoid */
+#define MIN_SPACE 75
+ if (compl_length > (IOSIZE - MIN_SPACE)) {
+ compl_cont_status &= ~CONT_SOL;
+ compl_length = (IOSIZE - MIN_SPACE);
+ compl_col = curwin->w_cursor.col - compl_length;
+ }
+ compl_cont_status |= CONT_ADDING | CONT_N_ADDS;
+ if (compl_length < 1)
+ compl_cont_status &= CONT_LOCAL;
+ } else if (ctrl_x_mode == CTRL_X_WHOLE_LINE)
+ compl_cont_status = CONT_ADDING | CONT_N_ADDS;
+ else
+ compl_cont_status = 0;
+ } else
+ compl_cont_status &= CONT_LOCAL;
+
+ if (!(compl_cont_status & CONT_ADDING)) { /* normal expansion */
+ compl_cont_mode = ctrl_x_mode;
+ if (ctrl_x_mode != 0) /* Remove LOCAL if ctrl_x_mode != 0 */
+ compl_cont_status = 0;
+ compl_cont_status |= CONT_N_ADDS;
+ compl_startpos = curwin->w_cursor;
+ startcol = (int)curs_col;
+ compl_col = 0;
+ }
+
+ /* Work out completion pattern and original text -- webb */
+ if (ctrl_x_mode == 0 || (ctrl_x_mode & CTRL_X_WANT_IDENT)) {
+ if ((compl_cont_status & CONT_SOL)
+ || ctrl_x_mode == CTRL_X_PATH_DEFINES) {
+ if (!(compl_cont_status & CONT_ADDING)) {
+ while (--startcol >= 0 && vim_isIDc(line[startcol]))
+ ;
+ compl_col += ++startcol;
+ compl_length = curs_col - startcol;
+ }
+ if (p_ic)
+ compl_pattern = str_foldcase(line + compl_col,
+ compl_length, NULL, 0);
+ else
+ compl_pattern = vim_strnsave(line + compl_col,
+ compl_length);
+ if (compl_pattern == NULL)
+ return FAIL;
+ } else if (compl_cont_status & CONT_ADDING) {
+ char_u *prefix = (char_u *)"\\<";
+
+ /* we need up to 2 extra chars for the prefix */
+ compl_pattern = alloc(quote_meta(NULL, line + compl_col,
+ compl_length) + 2);
+ if (compl_pattern == NULL)
+ return FAIL;
+ if (!vim_iswordp(line + compl_col)
+ || (compl_col > 0
+ && (
+ vim_iswordp(mb_prevptr(line, line + compl_col))
+ )))
+ prefix = (char_u *)"";
+ STRCPY((char *)compl_pattern, prefix);
+ (void)quote_meta(compl_pattern + STRLEN(prefix),
+ line + compl_col, compl_length);
+ } else if (--startcol < 0 ||
+ !vim_iswordp(mb_prevptr(line, line + startcol + 1))
+ ) {
+ /* Match any word of at least two chars */
+ compl_pattern = vim_strsave((char_u *)"\\<\\k\\k");
+ if (compl_pattern == NULL)
+ return FAIL;
+ 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;
+ }
+ } else
+ while (--startcol >= 0 && vim_iswordc(line[startcol]))
+ ;
+ compl_col += ++startcol;
+ compl_length = (int)curs_col - startcol;
+ if (compl_length == 1) {
+ /* Only match word with at least two chars -- webb
+ * there's no need to call quote_meta,
+ * alloc(7) is enough -- Acevedo
+ */
+ compl_pattern = alloc(7);
+ if (compl_pattern == NULL)
+ return FAIL;
+ STRCPY((char *)compl_pattern, "\\<");
+ (void)quote_meta(compl_pattern + 2, line + compl_col, 1);
+ STRCAT((char *)compl_pattern, "\\k");
+ } else {
+ compl_pattern = alloc(quote_meta(NULL, line + compl_col,
+ compl_length) + 2);
+ if (compl_pattern == NULL)
+ return FAIL;
+ STRCPY((char *)compl_pattern, "\\<");
+ (void)quote_meta(compl_pattern + 2, line + compl_col,
+ compl_length);
+ }
+ }
+ } else if (ctrl_x_mode == CTRL_X_WHOLE_LINE) {
+ compl_col = (colnr_T)(skipwhite(line) - line);
+ compl_length = (int)curs_col - (int)compl_col;
+ if (compl_length < 0) /* cursor in indent: empty pattern */
+ compl_length = 0;
+ if (p_ic)
+ compl_pattern = str_foldcase(line + compl_col, compl_length,
+ NULL, 0);
+ else
+ compl_pattern = vim_strnsave(line + compl_col, compl_length);
+ if (compl_pattern == NULL)
+ return FAIL;
+ } else if (ctrl_x_mode == CTRL_X_FILES) {
+ /* Go back to just before the first filename character. */
+ 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)))
+ startcol = 0;
+ else
+ startcol = (int)(p - line) + 1;
+ }
+
+ compl_col += startcol;
+ compl_length = (int)curs_col - startcol;
+ compl_pattern = addstar(line + compl_col, compl_length,
+ EXPAND_FILES);
+ if (compl_pattern == NULL)
+ return FAIL;
+ } else if (ctrl_x_mode == CTRL_X_CMDLINE) {
+ compl_pattern = vim_strnsave(line, curs_col);
+ if (compl_pattern == NULL)
+ return FAIL;
+ set_cmd_context(&compl_xp, compl_pattern,
+ (int)STRLEN(compl_pattern), curs_col);
+ 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_col = curs_col;
+ 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) {
+ /*
+ * 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;
+
+ /* Call 'completefunc' or 'omnifunc' and get pattern length as a
+ * string */
+ funcname = ctrl_x_mode == CTRL_X_FUNCTION
+ ? curbuf->b_p_cfu : curbuf->b_p_ofu;
+ if (*funcname == NUL) {
+ EMSG2(_(e_notset), ctrl_x_mode == CTRL_X_FUNCTION
+ ? "completefunc" : "omnifunc");
+ return FAIL;
+ }
+
+ args[0] = (char_u *)"1";
+ args[1] = NULL;
+ pos = curwin->w_cursor;
+ curwin_save = curwin;
+ curbuf_save = curbuf;
+ col = call_func_retnr(funcname, 2, args, FALSE);
+ if (curwin_save != curwin || curbuf_save != curbuf) {
+ EMSG(_(e_complwin));
+ return FAIL;
+ }
+ curwin->w_cursor = pos; /* restore the cursor position */
+ check_cursor();
+ if (!equalpos(curwin->w_cursor, pos)) {
+ EMSG(_(e_compldel));
+ return FAIL;
+ }
+
+ /* Return value -2 means the user complete function wants to
+ * cancel the complete without an error.
+ * Return value -3 does the same as -2 and leaves CTRL-X mode.*/
+ if (col == -2)
+ return FAIL;
+ if (col == -3) {
+ ctrl_x_mode = 0;
+ edit_submode = NULL;
+ msg_clr_cmdline();
+ return FAIL;
+ }
+
+ /*
+ * Reset extended parameters of completion, when start new
+ * completion.
+ */
+ compl_opt_refresh_always = FALSE;
+
+ if (col < 0)
+ col = curs_col;
+ compl_col = col;
+ if (compl_col > curs_col)
+ compl_col = curs_col;
+
+ /* Setup variables for completion. Need to obtain "line" again,
+ * it may have become invalid. */
+ line = ml_get(curwin->w_cursor.lnum);
+ compl_length = curs_col - compl_col;
+ compl_pattern = vim_strnsave(line + compl_col, compl_length);
+ if (compl_pattern == NULL)
+ return FAIL;
+ } else if (ctrl_x_mode == CTRL_X_SPELL) {
+ if (spell_bad_len > 0)
+ compl_col = curs_col - spell_bad_len;
+ else
+ compl_col = spell_word_start(startcol);
+ if (compl_col >= (colnr_T)startcol) {
+ compl_length = 0;
+ compl_col = curs_col;
+ } else {
+ spell_expand_check_cap(compl_col);
+ compl_length = (int)curs_col - compl_col;
+ }
+ /* Need to obtain "line" again, it may have become invalid. */
+ line = ml_get(curwin->w_cursor.lnum);
+ compl_pattern = vim_strnsave(line + compl_col, compl_length);
+ if (compl_pattern == NULL)
+ return FAIL;
+ } else {
+ EMSG2(_(e_intern2), "ins_complete()");
+ return FAIL;
+ }
+
+ if (compl_cont_status & CONT_ADDING) {
+ edit_submode_pre = (char_u *)_(" Adding");
+ if (ctrl_x_mode == CTRL_X_WHOLE_LINE) {
+ /* Insert a new line, keep indentation but ignore 'comments' */
+ char_u *old = curbuf->b_p_com;
+
+ curbuf->b_p_com = (char_u *)"";
+ compl_startpos.lnum = curwin->w_cursor.lnum;
+ compl_startpos.col = compl_col;
+ ins_eol('\r');
+ curbuf->b_p_com = old;
+ compl_length = 0;
+ compl_col = curwin->w_cursor.col;
+ }
+ } else {
+ edit_submode_pre = NULL;
+ compl_startpos.col = compl_col;
+ }
+
+ if (compl_cont_status & CONT_LOCAL)
+ edit_submode = (char_u *)_(ctrl_x_msgs[CTRL_X_LOCAL_MSG]);
+ else
+ edit_submode = (char_u *)_(CTRL_X_MSG(ctrl_x_mode));
+
+ /* If any of the original typed text has been changed we need to fix
+ * the redo buffer. */
+ ins_compl_fixRedoBufForLeader(NULL);
+
+ /* Always add completion for the original text. */
+ vim_free(compl_orig_text);
+ compl_orig_text = vim_strnsave(line + compl_col, compl_length);
+ if (compl_orig_text == NULL || ins_compl_add(compl_orig_text,
+ -1, p_ic, NULL, NULL, 0, ORIGINAL_TEXT, FALSE) != OK) {
+ vim_free(compl_pattern);
+ compl_pattern = NULL;
+ vim_free(compl_orig_text);
+ compl_orig_text = NULL;
+ return FAIL;
+ }
+
+ /* 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_submode_extra = (char_u *)_("-- Searching...");
+ edit_submode_highl = HLF_COUNT;
+ showmode();
+ edit_submode_extra = NULL;
+ out_flush();
+ }
+
+ compl_shown_match = compl_curr_match;
+ compl_shows_dir = compl_direction;
+
+ /*
+ * 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));
+
+ /* may undisplay the popup menu */
+ ins_compl_upd_pum();
+
+ if (n > 1) /* all matches have been found */
+ compl_matches = n;
+ compl_curr_match = compl_shown_match;
+ compl_direction = compl_shows_dir;
+
+ /* Eat the ESC that vgetc() returns after a CTRL-C to avoid leaving Insert
+ * mode. */
+ if (got_int && !global_busy) {
+ (void)vgetc();
+ got_int = FALSE;
+ }
+
+ /* we found no match if the list has only the "compl_orig_text"-entry */
+ if (compl_first_match == compl_first_match->cp_next) {
+ edit_submode_extra = (compl_cont_status & CONT_ADDING)
+ && compl_length > 1
+ ? (char_u *)_(e_hitend) : (char_u *)_(e_patnotf);
+ edit_submode_highl = HLF_E;
+ /* remove N_ADDS flag, so next ^X<> won't try to go to ADDING mode,
+ * because we couldn't expand anything at first place, but if we used
+ * ^P, ^N, ^X^I or ^X^D we might want to add-expand a single-char-word
+ * (such as M in M'exico) if not tried already. -- Acevedo */
+ if ( compl_length > 1
+ || (compl_cont_status & CONT_ADDING)
+ || (ctrl_x_mode != 0
+ && ctrl_x_mode != CTRL_X_PATH_PATTERNS
+ && ctrl_x_mode != CTRL_X_PATH_DEFINES))
+ compl_cont_status &= ~CONT_N_ADDS;
+ }
+
+ if (compl_curr_match->cp_flags & CONT_S_IPOS)
+ compl_cont_status |= CONT_S_IPOS;
+ else
+ compl_cont_status &= ~CONT_S_IPOS;
+
+ if (edit_submode_extra == NULL) {
+ if (compl_curr_match->cp_flags & ORIGINAL_TEXT) {
+ edit_submode_extra = (char_u *)_("Back at original");
+ edit_submode_highl = HLF_W;
+ } else if (compl_cont_status & CONT_S_IPOS) {
+ edit_submode_extra = (char_u *)_("Word from other line");
+ edit_submode_highl = HLF_COUNT;
+ } else if (compl_curr_match->cp_next == compl_curr_match->cp_prev) {
+ edit_submode_extra = (char_u *)_("The only match");
+ edit_submode_highl = HLF_COUNT;
+ } else {
+ /* Update completion sequence number when needed. */
+ if (compl_curr_match->cp_number == -1) {
+ int number = 0;
+ compl_T *match;
+
+ if (compl_direction == FORWARD) {
+ /* search backwards for the first valid (!= -1) number.
+ * This should normally succeed already at the first loop
+ * cycle, so it's fast! */
+ for (match = compl_curr_match->cp_prev; match != NULL
+ && match != compl_first_match;
+ match = match->cp_prev)
+ if (match->cp_number != -1) {
+ number = match->cp_number;
+ break;
+ }
+ if (match != NULL)
+ /* go up and assign all numbers which are not assigned
+ * yet */
+ for (match = match->cp_next;
+ match != NULL && match->cp_number == -1;
+ match = match->cp_next)
+ match->cp_number = ++number;
+ } else { /* BACKWARD */
+ /* search forwards (upwards) for the first valid (!= -1)
+ * number. This should normally succeed already at the
+ * first loop cycle, so it's fast! */
+ for (match = compl_curr_match->cp_next; match != NULL
+ && match != compl_first_match;
+ match = match->cp_next)
+ if (match->cp_number != -1) {
+ number = match->cp_number;
+ break;
+ }
+ if (match != NULL)
+ /* go down and assign all numbers which are not
+ * assigned yet */
+ for (match = match->cp_prev; match
+ && match->cp_number == -1;
+ match = match->cp_prev)
+ match->cp_number = ++number;
+ }
+ }
+
+ /* The match should always have a sequence number now, this is
+ * just a safety check. */
+ if (compl_curr_match->cp_number != -1) {
+ /* Space for 10 text chars. + 2x10-digit no.s = 31.
+ * Translations may need more than twice that. */
+ static char_u match_ref[81];
+
+ if (compl_matches > 0)
+ vim_snprintf((char *)match_ref, sizeof(match_ref),
+ _("match %d of %d"),
+ compl_curr_match->cp_number, compl_matches);
+ else
+ vim_snprintf((char *)match_ref, sizeof(match_ref),
+ _("match %d"),
+ compl_curr_match->cp_number);
+ edit_submode_extra = match_ref;
+ edit_submode_highl = HLF_R;
+ if (dollar_vcol >= 0)
+ curs_columns(FALSE);
+ }
+ }
+ }
+
+ /* Show a message about what (completion) mode we're in. */
+ showmode();
+ if (edit_submode_extra != NULL) {
+ if (!p_smd)
+ msg_attr(edit_submode_extra,
+ edit_submode_highl < HLF_COUNT
+ ? hl_attr(edit_submode_highl) : 0);
+ } else
+ msg_clr_cmdline(); /* necessary for "noshowmode" */
+
+ /* Show the popup menu, unless we got interrupted. */
+ if (!compl_interrupted) {
+ /* RedrawingDisabled may be set when invoked through complete(). */
+ n = RedrawingDisabled;
+ RedrawingDisabled = 0;
+
+ /* If the cursor moved we need to remove the pum first. */
+ setcursor();
+ if (save_w_wrow != curwin->w_wrow)
+ ins_compl_del_pum();
+
+ ins_compl_show_pum();
+ setcursor();
+ RedrawingDisabled = n;
+ }
+ compl_was_interrupted = compl_interrupted;
+ compl_interrupted = FALSE;
+
+ return OK;
+}
+
+/*
+ * Looks in the first "len" chars. of "src" for search-metachars.
+ * If dest is not NULL the chars. are copied there quoting (with
+ * a backslash) the metachars, and dest would be NUL terminated.
+ * Returns the length (needed) of dest
+ */
+static unsigned quote_meta(dest, src, len)
+char_u *dest;
+char_u *src;
+int len;
+{
+ unsigned m = (unsigned)len + 1; /* one extra for the NUL */
+
+ for (; --len >= 0; src++) {
+ switch (*src) {
+ case '.':
+ case '*':
+ case '[':
+ if (ctrl_x_mode == CTRL_X_DICTIONARY
+ || ctrl_x_mode == CTRL_X_THESAURUS)
+ break;
+ case '~':
+ if (!p_magic) /* quote these only if magic is set */
+ break;
+ case '\\':
+ if (ctrl_x_mode == CTRL_X_DICTIONARY
+ || ctrl_x_mode == CTRL_X_THESAURUS)
+ break;
+ case '^': /* currently it's not needed. */
+ case '$':
+ m++;
+ if (dest != NULL)
+ *dest++ = '\\';
+ break;
+ }
+ if (dest != NULL)
+ *dest++ = *src;
+ /* Copy remaining bytes of a multibyte character. */
+ if (has_mbyte) {
+ int i, mb_len;
+
+ mb_len = (*mb_ptr2len)(src) - 1;
+ if (mb_len > 0 && len >= mb_len)
+ for (i = 0; i < mb_len; ++i) {
+ --len;
+ ++src;
+ if (dest != NULL)
+ *dest++ = *src;
+ }
+ }
+ }
+ if (dest != NULL)
+ *dest = NUL;
+
+ return m;
+}
+
+/*
+ * Next character is interpreted literally.
+ * A one, two or three digit decimal number is interpreted as its byte value.
+ * If one or two digits are entered, the next character is given to vungetc().
+ * For Unicode a character > 255 may be returned.
+ */
+int get_literal() {
+ int cc;
+ int nc;
+ int i;
+ int hex = FALSE;
+ int octal = FALSE;
+ int unicode = 0;
+
+ if (got_int)
+ return Ctrl_C;
+
+#ifdef USE_ON_FLY_SCROLL
+ dont_scroll = TRUE; /* disallow scrolling here */
+#endif
+ ++no_mapping; /* don't map the next key hits */
+ cc = 0;
+ i = 0;
+ for (;; ) {
+ nc = plain_vgetc();
+ if (!(State & CMDLINE)
+ && MB_BYTE2LEN_CHECK(nc) == 1
+ )
+ add_to_showcmd(nc);
+ if (nc == 'x' || nc == 'X')
+ hex = TRUE;
+ else if (nc == 'o' || nc == 'O')
+ octal = TRUE;
+ else if (nc == 'u' || nc == 'U')
+ unicode = nc;
+ else {
+ if (hex
+ || unicode != 0
+ ) {
+ if (!vim_isxdigit(nc))
+ break;
+ cc = cc * 16 + hex2nr(nc);
+ } else if (octal) {
+ if (nc < '0' || nc > '7')
+ break;
+ cc = cc * 8 + nc - '0';
+ } else {
+ if (!VIM_ISDIGIT(nc))
+ break;
+ cc = cc * 10 + nc - '0';
+ }
+
+ ++i;
+ }
+
+ if (cc > 255
+ && unicode == 0
+ )
+ cc = 255; /* limit range to 0-255 */
+ nc = 0;
+
+ if (hex) { /* hex: up to two chars */
+ if (i >= 2)
+ break;
+ } else if (unicode) { /* Unicode: up to four or eight chars */
+ if ((unicode == 'u' && i >= 4) || (unicode == 'U' && i >= 8))
+ break;
+ } else if (i >= 3) /* decimal or octal: up to three chars */
+ break;
+ }
+ if (i == 0) { /* no number entered */
+ if (nc == K_ZERO) { /* NUL is stored as NL */
+ cc = '\n';
+ nc = 0;
+ } else {
+ cc = nc;
+ nc = 0;
+ }
+ }
+
+ if (cc == 0) /* NUL is stored as NL */
+ cc = '\n';
+ if (enc_dbcs && (cc & 0xff) == 0)
+ cc = '?'; /* don't accept an illegal DBCS char, the NUL in the
+ second byte will cause trouble! */
+
+ --no_mapping;
+ if (nc)
+ vungetc(nc);
+ got_int = FALSE; /* CTRL-C typed after CTRL-V is not an interrupt */
+ return cc;
+}
+
+/*
+ * Insert character, taking care of special keys and mod_mask
+ */
+static void insert_special(c, allow_modmask, ctrlv)
+int c;
+int allow_modmask;
+int ctrlv; /* c was typed after CTRL-V */
+{
+ 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.
+ */
+ if (IS_SPECIAL(c) || (mod_mask && allow_modmask)) {
+ p = get_special_key_name(c, mod_mask);
+ len = (int)STRLEN(p);
+ c = p[len - 1];
+ if (len > 2) {
+ if (stop_arrow() == FAIL)
+ return;
+ p[len - 1] = NUL;
+ ins_str(p);
+ AppendToRedobuffLit(p, -1);
+ ctrlv = FALSE;
+ }
+ }
+ if (stop_arrow() == OK)
+ insertchar(c, ctrlv ? INSCHAR_CTRLV : 0, -1);
+}
+
+/*
+ * Special characters in this context are those that need processing other
+ * than the simple insertion that can be performed here. This includes ESC
+ * which terminates the insert, and CR/NL which need special processing to
+ * open up a new line. This routine tries to optimize insertions performed by
+ * the "redo", "undo" or "put" commands, so it needs to know when it should
+ * stop and defer processing to the "normal" mechanism.
+ * '0' and '^' are special, because they can be followed by CTRL-D.
+ */
+# define ISSPECIAL(c) ((c) < ' ' || (c) >= DEL || (c) == '0' || (c) == '^')
+
+# define WHITECHAR(cc) (vim_iswhite(cc) && \
+ (!enc_utf8 || \
+ !utf_iscomposing(utf_ptr2char(ml_get_cursor() + 1))))
+
+/*
+ * "flags": INSCHAR_FORMAT - force formatting
+ * INSCHAR_CTRLV - char typed just after CTRL-V
+ * INSCHAR_NO_FEX - don't use 'formatexpr'
+ *
+ * NOTE: passes the flags value straight through to internal_format() which,
+ * beside INSCHAR_FORMAT (above), is also looking for these:
+ * INSCHAR_DO_COM - format comments
+ * INSCHAR_COM_LIST - format comments with num list or 2nd line indent
+ */
+void insertchar(c, flags, second_indent)
+int c; /* character to insert or NUL */
+int flags; /* INSCHAR_FORMAT, etc. */
+int second_indent; /* indent for second line if >= 0 */
+{
+ int textwidth;
+ char_u *p;
+ int fo_ins_blank;
+
+ textwidth = comp_textwidth(flags & INSCHAR_FORMAT);
+ fo_ins_blank = has_format_option(FO_INS_BLANK);
+
+ /*
+ * Try to break the line in two or more pieces when:
+ * - Always do this if we have been called to do formatting only.
+ * - Always do this when 'formatoptions' has the 'a' flag and the line
+ * ends in white space.
+ * - Otherwise:
+ * - Don't do this if inserting a blank
+ * - Don't do this if an existing character is being replaced, unless
+ * we're in VREPLACE mode.
+ * - Do this if the cursor is not on the line where insert started
+ * or - 'formatoptions' doesn't have 'l' or the line was not too long
+ * before the insert.
+ * - 'formatoptions' doesn't have 'b' or a blank was inserted at or
+ * before 'textwidth'
+ */
+ if (textwidth > 0
+ && ((flags & INSCHAR_FORMAT)
+ || (!vim_iswhite(c)
+ && !((State & REPLACE_FLAG)
+ && !(State & VREPLACE_FLAG)
+ && *ml_get_cursor() != NUL)
+ && (curwin->w_cursor.lnum != Insstart.lnum
+ || ((!has_format_option(FO_INS_LONG)
+ || Insstart_textlen <= (colnr_T)textwidth)
+ && (!fo_ins_blank
+ || Insstart_blank_vcol <= (colnr_T)textwidth
+ )))))) {
+ /* Format with 'formatexpr' when it's set. Use internal formatting
+ * when 'formatexpr' isn't set or it returns non-zero. */
+ int do_internal = TRUE;
+
+ if (*curbuf->b_p_fex != NUL && (flags & INSCHAR_NO_FEX) == 0) {
+ do_internal = (fex_format(curwin->w_cursor.lnum, 1L, c) != 0);
+ /* It may be required to save for undo again, e.g. when setline()
+ * was called. */
+ ins_need_undo = TRUE;
+ }
+ if (do_internal)
+ internal_format(textwidth, second_indent, flags, c == NUL, c);
+ }
+
+ if (c == NUL) /* only formatting was wanted */
+ return;
+
+ /* Check whether this character should end a comment. */
+ if (did_ai && (int)c == end_comment_pending) {
+ char_u *line;
+ char_u lead_end[COM_MAX_LEN]; /* end-comment string */
+ int middle_len, end_len;
+ int i;
+
+ /*
+ * Need to remove existing (middle) comment leader and insert end
+ * comment leader. First, check what comment leader we can find.
+ */
+ i = get_leader_len(line = ml_get_curline(), &p, FALSE, TRUE);
+ if (i > 0 && vim_strchr(p, COM_MIDDLE) != NULL) { /* Just checking */
+ /* Skip middle-comment string */
+ while (*p && p[-1] != ':') /* find end of middle flags */
+ ++p;
+ middle_len = copy_option_part(&p, lead_end, COM_MAX_LEN, ",");
+ /* Don't count trailing white space for middle_len */
+ while (middle_len > 0 && vim_iswhite(lead_end[middle_len - 1]))
+ --middle_len;
+
+ /* Find the end-comment string */
+ while (*p && p[-1] != ':') /* find end of end flags */
+ ++p;
+ end_len = copy_option_part(&p, lead_end, COM_MAX_LEN, ",");
+
+ /* Skip white space before the cursor */
+ i = curwin->w_cursor.col;
+ while (--i >= 0 && vim_iswhite(line[i]))
+ ;
+ i++;
+
+ /* Skip to before the middle leader */
+ i -= middle_len;
+
+ /* Check some expected things before we go on */
+ if (i >= 0 && lead_end[end_len - 1] == end_comment_pending) {
+ /* Backspace over all the stuff we want to replace */
+ backspace_until_column(i);
+
+ /*
+ * Insert the end-comment string, except for the last
+ * character, which will get inserted as normal later.
+ */
+ ins_bytes_len(lead_end, end_len - 1);
+ }
+ }
+ }
+ end_comment_pending = NUL;
+
+ 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.
+ * Don't do this when 'cindent' or 'indentexpr' is set, because we might
+ * need to re-indent at a ':', or any other character (but not what
+ * 'paste' is set)..
+ * Don't do this when there an InsertCharPre autocommand is defined,
+ * because we need to fire the event for every character.
+ */
+#ifdef USE_ON_FLY_SCROLL
+ dont_scroll = FALSE; /* allow scrolling here */
+#endif
+
+ if ( !ISSPECIAL(c)
+ && (!has_mbyte || (*mb_char2len)(c) == 1)
+ && vpeekc() != NUL
+ && !(State & REPLACE_FLAG)
+ && !cindent_on()
+ && !p_ri
+ && !has_insertcharpre()
+ ) {
+#define INPUT_BUFLEN 100
+ char_u buf[INPUT_BUFLEN + 1];
+ int i;
+ colnr_T virtcol = 0;
+
+ buf[0] = c;
+ i = 1;
+ 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]))) {
+ c = vgetc();
+ if (p_hkmap && KeyTyped)
+ c = hkmap(c); /* Hebrew mode mapping */
+ if (p_fkmap && KeyTyped)
+ c = fkmap(c); /* Farsi mode mapping */
+ buf[i++] = c;
+ }
+
+ do_digraph(-1); /* clear digraphs */
+ do_digraph(buf[i-1]); /* may be the start of a digraph */
+ buf[i] = NUL;
+ ins_str(buf);
+ if (flags & INSCHAR_CTRLV) {
+ redo_literal(*buf);
+ i = 1;
+ } else
+ i = 0;
+ if (buf[i] != NUL)
+ AppendToRedobuffLit(buf + i, -1);
+ } else {
+ int cc;
+
+ if (has_mbyte && (cc = (*mb_char2len)(c)) > 1) {
+ char_u buf[MB_MAXBYTES + 1];
+
+ (*mb_char2bytes)(c, buf);
+ buf[cc] = NUL;
+ ins_char_bytes(buf, cc);
+ AppendCharToRedobuff(c);
+ } else {
+ ins_char(c);
+ if (flags & INSCHAR_CTRLV)
+ redo_literal(c);
+ else
+ AppendCharToRedobuff(c);
+ }
+ }
+}
+
+/*
+ * Format text at the current insert position.
+ *
+ * If the INSCHAR_COM_LIST flag is present, then the value of second_indent
+ * will be the comment leader length sent to open_line().
+ */
+static void internal_format(textwidth, second_indent, flags, format_only, c)
+int textwidth;
+int second_indent;
+int flags;
+int format_only;
+int c; /* character to be inserted (can be NUL) */
+{
+ int cc;
+ int save_char = NUL;
+ int 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);
+ int first_line = TRUE;
+ colnr_T leader_len;
+ int no_leader = FALSE;
+ int do_comments = (flags & INSCHAR_DO_COM);
+
+ /*
+ * When 'ai' is off we don't want a space under the cursor to be
+ * deleted. Replace it with an 'x' temporarily.
+ */
+ if (!curbuf->b_p_ai
+ && !(State & VREPLACE_FLAG)
+ ) {
+ cc = gchar_cursor();
+ if (vim_iswhite(cc)) {
+ save_char = cc;
+ pchar_cursor('x');
+ }
+ }
+
+ /*
+ * Repeat breaking lines, until the current line is not too long.
+ */
+ while (!got_int) {
+ int startcol; /* Cursor column at entry */
+ int wantcol; /* column at textwidth border */
+ int foundcol; /* column for start of spaces */
+ int end_foundcol = 0; /* column for start of word */
+ colnr_T len;
+ colnr_T virtcol;
+ int orig_col = 0;
+ char_u *saved_text = NULL;
+ colnr_T col;
+ colnr_T end_col;
+
+ virtcol = get_nolist_virtcol()
+ + char2cells(c != NUL ? c : gchar_cursor());
+ if (virtcol <= (colnr_T)textwidth)
+ break;
+
+ if (no_leader)
+ do_comments = FALSE;
+ else if (!(flags & INSCHAR_FORMAT)
+ && has_format_option(FO_WRAP_COMS))
+ do_comments = TRUE;
+
+ /* Don't break until after the comment leader */
+ if (do_comments)
+ leader_len = get_leader_len(ml_get_curline(), NULL, FALSE, TRUE);
+ else
+ leader_len = 0;
+
+ /* If the line doesn't start with a comment leader, then don't
+ * start one in a following broken line. Avoids that a %word
+ * moved to the start of the next line causes all following lines
+ * to start with %. */
+ if (leader_len == 0)
+ no_leader = TRUE;
+ if (!(flags & INSCHAR_FORMAT)
+ && leader_len == 0
+ && !has_format_option(FO_WRAP))
+
+ break;
+ if ((startcol = curwin->w_cursor.col) == 0)
+ break;
+
+ /* find column of textwidth border */
+ coladvance((colnr_T)textwidth);
+ wantcol = curwin->w_cursor.col;
+
+ curwin->w_cursor.col = startcol;
+ foundcol = 0;
+
+ /*
+ * Find position to break at.
+ * Stop at first entered white when 'formatoptions' has 'v'
+ */
+ while ((!fo_ins_blank && !has_format_option(FO_INS_VI))
+ || (flags & INSCHAR_FORMAT)
+ || curwin->w_cursor.lnum != Insstart.lnum
+ || curwin->w_cursor.col >= Insstart.col) {
+ if (curwin->w_cursor.col == startcol && c != NUL)
+ cc = c;
+ else
+ cc = gchar_cursor();
+ if (WHITECHAR(cc)) {
+ /* remember position of blank just before text */
+ end_col = curwin->w_cursor.col;
+
+ /* find start of sequence of blanks */
+ while (curwin->w_cursor.col > 0 && WHITECHAR(cc)) {
+ dec_cursor();
+ cc = gchar_cursor();
+ }
+ if (curwin->w_cursor.col == 0 && WHITECHAR(cc))
+ break; /* only spaces in front of text */
+ /* Don't break until after the comment leader */
+ if (curwin->w_cursor.col < leader_len)
+ break;
+ if (has_format_option(FO_ONE_LETTER)) {
+ /* do not break after one-letter words */
+ if (curwin->w_cursor.col == 0)
+ break; /* one-letter word at begin */
+ /* do not break "#a b" when 'tw' is 2 */
+ if (curwin->w_cursor.col <= leader_len)
+ break;
+ col = curwin->w_cursor.col;
+ dec_cursor();
+ cc = gchar_cursor();
+
+ if (WHITECHAR(cc))
+ continue; /* one-letter, continue */
+ curwin->w_cursor.col = col;
+ }
+
+ inc_cursor();
+
+ end_foundcol = end_col + 1;
+ foundcol = curwin->w_cursor.col;
+ if (curwin->w_cursor.col <= (colnr_T)wantcol)
+ break;
+ } else if (cc >= 0x100 && fo_multibyte) {
+ /* Break after or before a multi-byte character. */
+ if (curwin->w_cursor.col != startcol) {
+ /* Don't break until after the comment leader */
+ if (curwin->w_cursor.col < leader_len)
+ break;
+ col = curwin->w_cursor.col;
+ inc_cursor();
+ /* Don't change end_foundcol if already set. */
+ if (foundcol != curwin->w_cursor.col) {
+ foundcol = curwin->w_cursor.col;
+ end_foundcol = foundcol;
+ if (curwin->w_cursor.col <= (colnr_T)wantcol)
+ break;
+ }
+ curwin->w_cursor.col = col;
+ }
+
+ if (curwin->w_cursor.col == 0)
+ break;
+
+ col = curwin->w_cursor.col;
+
+ dec_cursor();
+ cc = gchar_cursor();
+
+ if (WHITECHAR(cc))
+ continue; /* break with space */
+ /* Don't break until after the comment leader */
+ if (curwin->w_cursor.col < leader_len)
+ break;
+
+ curwin->w_cursor.col = col;
+
+ foundcol = curwin->w_cursor.col;
+ end_foundcol = foundcol;
+ if (curwin->w_cursor.col <= (colnr_T)wantcol)
+ break;
+ }
+ if (curwin->w_cursor.col == 0)
+ break;
+ dec_cursor();
+ }
+
+ if (foundcol == 0) { /* no spaces, cannot break line */
+ curwin->w_cursor.col = startcol;
+ break;
+ }
+
+ /* Going to break the line, remove any "$" now. */
+ undisplay_dollar();
+
+ /*
+ * Offset between cursor position and line break is used by replace
+ * stack functions. VREPLACE does not use this, and backspaces
+ * over the text instead.
+ */
+ if (State & VREPLACE_FLAG)
+ orig_col = startcol; /* Will start backspacing from here */
+ else
+ replace_offset = startcol - end_foundcol;
+
+ /*
+ * adjust startcol for spaces that will be deleted and
+ * characters that will remain on top line
+ */
+ curwin->w_cursor.col = foundcol;
+ while ((cc = gchar_cursor(), WHITECHAR(cc))
+ && (!fo_white_par || curwin->w_cursor.col < startcol))
+ inc_cursor();
+ startcol -= curwin->w_cursor.col;
+ if (startcol < 0)
+ startcol = 0;
+
+ if (State & VREPLACE_FLAG) {
+ /*
+ * In VREPLACE mode, we will backspace over the text to be
+ * wrapped, so save a copy now to put on the next line.
+ */
+ saved_text = vim_strsave(ml_get_cursor());
+ curwin->w_cursor.col = orig_col;
+ if (saved_text == NULL)
+ break; /* Can't do it, out of memory */
+ saved_text[startcol] = NUL;
+
+ /* Backspace over characters that will move to the next line */
+ if (!fo_white_par)
+ backspace_until_column(foundcol);
+ } else {
+ /* put cursor after pos. to break line */
+ if (!fo_white_par)
+ curwin->w_cursor.col = foundcol;
+ }
+
+ /*
+ * Split the line just before the margin.
+ * Only insert/delete lines, but don't really redraw the window.
+ */
+ open_line(FORWARD, OPENLINE_DELSPACES + OPENLINE_MARKFIX
+ + (fo_white_par ? OPENLINE_KEEPTRAIL : 0)
+ + (do_comments ? OPENLINE_DO_COM : 0)
+ + ((flags & INSCHAR_COM_LIST) ? OPENLINE_COM_LIST : 0)
+ , ((flags & INSCHAR_COM_LIST) ? second_indent : old_indent));
+ if (!(flags & INSCHAR_COM_LIST))
+ old_indent = 0;
+
+ replace_offset = 0;
+ if (first_line) {
+ if (!(flags & INSCHAR_COM_LIST)) {
+ /*
+ * This section is for auto-wrap of numeric lists. When not
+ * in insert mode (i.e. format_lines()), the INSCHAR_COM_LIST
+ * flag will be set and open_line() will handle it (as seen
+ * above). The code here (and in get_number_indent()) will
+ * recognize comments if needed...
+ */
+ if (second_indent < 0 && has_format_option(FO_Q_NUMBER))
+ second_indent =
+ get_number_indent(curwin->w_cursor.lnum - 1);
+ if (second_indent >= 0) {
+ if (State & VREPLACE_FLAG)
+ change_indent(INDENT_SET, second_indent,
+ FALSE, NUL, TRUE);
+ else if (leader_len > 0 && second_indent - leader_len > 0) {
+ int i;
+ int padding = second_indent - leader_len;
+
+ /* We started at the first_line of a numbered list
+ * that has a comment. the open_line() function has
+ * inserted the proper comment leader and positioned
+ * the cursor at the end of the split line. Now we
+ * add the additional whitespace needed after the
+ * comment leader for the numbered list. */
+ for (i = 0; i < padding; i++)
+ ins_str((char_u *)" ");
+ changed_bytes(curwin->w_cursor.lnum, leader_len);
+ } else {
+ (void)set_indent(second_indent, SIN_CHANGED);
+ }
+ }
+ }
+ first_line = FALSE;
+ }
+
+ if (State & VREPLACE_FLAG) {
+ /*
+ * In VREPLACE mode we have backspaced over the text to be
+ * moved, now we re-insert it into the new line.
+ */
+ ins_bytes(saved_text);
+ vim_free(saved_text);
+ } else {
+ /*
+ * Check if cursor is not past the NUL off the line, cindent
+ * may have added or removed indent.
+ */
+ curwin->w_cursor.col += startcol;
+ len = (colnr_T)STRLEN(ml_get_curline());
+ if (curwin->w_cursor.col > len)
+ 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;
+ line_breakcheck();
+ }
+
+ if (save_char != NUL) /* put back space after cursor */
+ pchar_cursor(save_char);
+
+ if (!format_only && haveto_redraw) {
+ update_topline();
+ redraw_curbuf_later(VALID);
+ }
+}
+
+/*
+ * Called after inserting or deleting text: When 'formatoptions' includes the
+ * 'a' flag format from the current line until the end of the paragraph.
+ * Keep the cursor at the same position relative to the text.
+ * The caller must have saved the cursor line for undo, following ones will be
+ * saved here.
+ */
+void auto_format(trailblank, prev_line)
+int trailblank; /* when TRUE also format with trailing blank */
+int prev_line; /* may start in previous line */
+{
+ pos_T pos;
+ colnr_T len;
+ char_u *old;
+ char_u *new, *pnew;
+ int wasatend;
+ int cc;
+
+ if (!has_format_option(FO_AUTO))
+ return;
+
+ pos = curwin->w_cursor;
+ old = ml_get_curline();
+
+ /* 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
+ * in 'formatoptions' and there is a single character before the cursor.
+ * Otherwise the line would be broken and when typing another non-white
+ * next they are not joined back together. */
+ wasatend = (pos.col == (colnr_T)STRLEN(old));
+ if (*old != NUL && !trailblank && wasatend) {
+ dec_cursor();
+ cc = gchar_cursor();
+ if (!WHITECHAR(cc) && curwin->w_cursor.col > 0
+ && has_format_option(FO_ONE_LETTER))
+ dec_cursor();
+ cc = gchar_cursor();
+ if (WHITECHAR(cc)) {
+ curwin->w_cursor = pos;
+ return;
+ }
+ curwin->w_cursor = pos;
+ }
+
+ /* With the 'c' flag in 'formatoptions' and 't' missing: only format
+ * comments. */
+ if (has_format_option(FO_WRAP_COMS) && !has_format_option(FO_WRAP)
+ && get_leader_len(old, NULL, FALSE, TRUE) == 0)
+ return;
+
+ /*
+ * May start formatting in a previous line, so that after "x" a word is
+ * moved to the previous line if it fits there now. Only when this is not
+ * the start of a paragraph.
+ */
+ if (prev_line && !paragraph_start(curwin->w_cursor.lnum)) {
+ --curwin->w_cursor.lnum;
+ if (u_save_cursor() == FAIL)
+ return;
+ }
+
+ /*
+ * Do the formatting and restore the cursor position. "saved_cursor" will
+ * be adjusted for the text formatting.
+ */
+ saved_cursor = pos;
+ format_lines((linenr_T)-1, FALSE);
+ curwin->w_cursor = saved_cursor;
+ saved_cursor.lnum = 0;
+
+ if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count) {
+ /* "cannot happen" */
+ curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
+ coladvance((colnr_T)MAXCOL);
+ } else
+ check_cursor_col();
+
+ /* Insert mode: If the cursor is now after the end of the line while it
+ * previously wasn't, the line was broken. Because of the rule above we
+ * need to add a space when 'w' is in 'formatoptions' to keep a paragraph
+ * formatted. */
+ if (!wasatend && has_format_option(FO_WHITE_PAR)) {
+ new = ml_get_curline();
+ len = (colnr_T)STRLEN(new);
+ if (curwin->w_cursor.col == len) {
+ 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);
+ }
+
+ check_cursor();
+}
+
+/*
+ * When an extra space was added to continue a paragraph for auto-formatting,
+ * delete it now. The space must be under the cursor, just after the insert
+ * position.
+ */
+static void check_auto_format(end_insert)
+int end_insert; /* TRUE when ending Insert mode */
+{
+ int c = ' ';
+ int cc;
+
+ if (did_add_space) {
+ cc = gchar_cursor();
+ 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;
+ }
+ }
+ }
+}
+
+/*
+ * Find out textwidth to be used for formatting:
+ * if 'textwidth' option is set, use it
+ * else if 'wrapmargin' option is set, use W_WIDTH(curwin) - 'wrapmargin'
+ * if invalid value, use 0.
+ * Set default to window width (maximum 79) for "gq" operator.
+ */
+int comp_textwidth(ff)
+int ff; /* force formatting (for "gq" command) */
+{
+ int textwidth;
+
+ textwidth = curbuf->b_p_tw;
+ 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 = W_WIDTH(curwin) - curbuf->b_p_wm;
+ if (cmdwin_type != 0)
+ textwidth -= 1;
+ textwidth -= curwin->w_p_fdc;
+ if (curwin->w_p_nu || curwin->w_p_rnu)
+ textwidth -= 8;
+ }
+ if (textwidth < 0)
+ textwidth = 0;
+ if (ff && textwidth == 0) {
+ textwidth = W_WIDTH(curwin) - 1;
+ if (textwidth > 79)
+ textwidth = 79;
+ }
+ return textwidth;
+}
+
+/*
+ * Put a character in the redo buffer, for when just after a CTRL-V.
+ */
+static void redo_literal(c)
+int c;
+{
+ char_u buf[10];
+
+ /* Only digits need special treatment. Translate them into a string of
+ * three digits. */
+ if (VIM_ISDIGIT(c)) {
+ vim_snprintf((char *)buf, sizeof(buf), "%03d", c);
+ AppendToRedobuff(buf);
+ } else
+ AppendCharToRedobuff(c);
+}
+
+/*
+ * start_arrow() is called when an arrow key is used in insert mode.
+ * For undo/redo it resembles hitting the <ESC> key.
+ */
+static void start_arrow(end_insert_pos)
+pos_T *end_insert_pos; /* can be NULL */
+{
+ if (!arrow_used) { /* something has been inserted */
+ AppendToRedobuff(ESC_STR);
+ stop_insert(end_insert_pos, FALSE, FALSE);
+ arrow_used = TRUE; /* this means we stopped the current insert */
+ }
+ check_spell_redraw();
+}
+
+/*
+ * If we skipped highlighting word at cursor, do it now.
+ * It may be skipped again, thus reset spell_redraw_lnum first.
+ */
+static void check_spell_redraw() {
+ if (spell_redraw_lnum != 0) {
+ linenr_T lnum = spell_redraw_lnum;
+
+ spell_redraw_lnum = 0;
+ redrawWinline(lnum, FALSE);
+ }
+}
+
+/*
+ * Called when starting CTRL_X_SPELL mode: Move backwards to a previous badly
+ * spelled word, if there is one.
+ */
+static void spell_back_to_badword() {
+ pos_T tpos = curwin->w_cursor;
+
+ spell_bad_len = spell_move_to(curwin, BACKWARD, TRUE, TRUE, NULL);
+ if (curwin->w_cursor.col != tpos.col)
+ start_arrow(&tpos);
+}
+
+/*
+ * stop_arrow() is called before a change is made in insert mode.
+ * If an arrow key has been used, start a new insertion.
+ * Returns FAIL if undo is impossible, shouldn't insert then.
+ */
+int stop_arrow() {
+ if (arrow_used) {
+ if (u_save_cursor() == OK) {
+ arrow_used = FALSE;
+ ins_need_undo = FALSE;
+ }
+ Insstart = curwin->w_cursor; /* new insertion starts here */
+ Insstart_textlen = (colnr_T)linetabsize(ml_get_curline());
+ ai_col = 0;
+ if (State & VREPLACE_FLAG) {
+ orig_line_count = curbuf->b_ml.ml_line_count;
+ vr_lines_changed = 1;
+ }
+ ResetRedobuff();
+ AppendToRedobuff((char_u *)"1i"); /* pretend we start an insertion */
+ new_insert_skip = 2;
+ } else if (ins_need_undo) {
+ if (u_save_cursor() == OK)
+ ins_need_undo = FALSE;
+ }
+
+ /* Always open fold at the cursor line when inserting something. */
+ foldOpenCursor();
+
+ return arrow_used || ins_need_undo ? FAIL : OK;
+}
+
+/*
+ * Do a few things to stop inserting.
+ * "end_insert_pos" is where insert ended. It is NULL when we already jumped
+ * to another window/buffer.
+ */
+static void stop_insert(end_insert_pos, esc, nomove)
+pos_T *end_insert_pos;
+int esc; /* called by ins_esc() */
+int nomove; /* <c-\><c-o>, don't move cursor */
+{
+ int cc;
+ char_u *ptr;
+
+ stop_redo_ins();
+ replace_flush(); /* abandon replace stack */
+
+ /*
+ * Save the inserted text for later redo with ^@ and CTRL-A.
+ * Don't do it when "restart_edit" was set and nothing was inserted,
+ * otherwise CTRL-O w and then <Left> will clear "last_insert".
+ */
+ ptr = get_inserted();
+ if (did_restart_edit == 0 || (ptr != NULL
+ && (int)STRLEN(ptr) > new_insert_skip)) {
+ vim_free(last_insert);
+ last_insert = ptr;
+ last_insert_skip = new_insert_skip;
+ } else
+ vim_free(ptr);
+
+ if (!arrow_used && end_insert_pos != NULL) {
+ /* Auto-format now. It may seem strange to do this when stopping an
+ * insertion (or moving the cursor), but it's required when appending
+ * a line and having it end in a space. But only do it when something
+ * was actually inserted, otherwise undo won't work. */
+ if (!ins_need_undo && has_format_option(FO_AUTO)) {
+ pos_T tpos = curwin->w_cursor;
+
+ /* When the cursor is at the end of the line after a space the
+ * formatting will move it to the following word. Avoid that by
+ * moving the cursor onto the space. */
+ cc = 'x';
+ if (curwin->w_cursor.col > 0 && gchar_cursor() == NUL) {
+ dec_cursor();
+ cc = gchar_cursor();
+ if (!vim_iswhite(cc))
+ curwin->w_cursor = tpos;
+ }
+
+ auto_format(TRUE, FALSE);
+
+ if (vim_iswhite(cc)) {
+ if (gchar_cursor() != NUL)
+ inc_cursor();
+ /* If the cursor is still at the same character, also keep
+ * the "coladd". */
+ if (gchar_cursor() == NUL
+ && curwin->w_cursor.lnum == tpos.lnum
+ && curwin->w_cursor.col == tpos.col)
+ curwin->w_cursor.coladd = tpos.coladd;
+ }
+ }
+
+ /* 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.
+ * Do this when ESC was used or moving the cursor up/down.
+ * Check for the old position still being valid, just in case the text
+ * got changed unexpectedly. */
+ if (!nomove && did_ai && (esc || (vim_strchr(p_cpo, CPO_INDENT) == NULL
+ && curwin->w_cursor.lnum !=
+ end_insert_pos->lnum))
+ && end_insert_pos->lnum <= curbuf->b_ml.ml_line_count) {
+ pos_T tpos = curwin->w_cursor;
+
+ curwin->w_cursor = *end_insert_pos;
+ check_cursor_col(); /* make sure it is not past the line */
+ for (;; ) {
+ if (gchar_cursor() == NUL && curwin->w_cursor.col > 0)
+ --curwin->w_cursor.col;
+ cc = gchar_cursor();
+ if (!vim_iswhite(cc))
+ break;
+ if (del_char(TRUE) == FAIL)
+ break; /* should not happen */
+ }
+ if (curwin->w_cursor.lnum != tpos.lnum)
+ curwin->w_cursor = tpos;
+ else if (cc != NUL)
+ ++curwin->w_cursor.col; /* put cursor back on the NUL */
+
+ /* <C-S-Right> may have started Visual mode, adjust the position for
+ * deleted characters. */
+ if (VIsual_active && VIsual.lnum == curwin->w_cursor.lnum) {
+ int len = (int)STRLEN(ml_get_curline());
+
+ if (VIsual.col > len) {
+ VIsual.col = len;
+ VIsual.coladd = 0;
+ }
+ }
+ }
+ }
+ 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. */
+ if (end_insert_pos != NULL) {
+ curbuf->b_op_start = Insstart;
+ curbuf->b_op_end = *end_insert_pos;
+ }
+}
+
+/*
+ * Set the last inserted text to a single character.
+ * Used for the replace command.
+ */
+void set_last_insert(c)
+int c;
+{
+ char_u *s;
+
+ vim_free(last_insert);
+ last_insert = alloc(MB_MAXBYTES * 3 + 5);
+ if (last_insert != NULL) {
+ s = last_insert;
+ /* Use the CTRL-V only when entering a special char */
+ if (c < ' ' || c == DEL)
+ *s++ = Ctrl_V;
+ s = add_char2buf(c, s);
+ *s++ = ESC;
+ *s++ = NUL;
+ last_insert_skip = 0;
+ }
+}
+
+#if defined(EXITFREE) || defined(PROTO)
+void free_last_insert() {
+ vim_free(last_insert);
+ last_insert = NULL;
+ vim_free(compl_orig_text);
+ compl_orig_text = NULL;
+}
+
+#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.
+ */
+char_u * add_char2buf(c, s)
+int c;
+char_u *s;
+{
+ char_u temp[MB_MAXBYTES + 1];
+ int i;
+ int len;
+
+ len = (*mb_char2bytes)(c, temp);
+ for (i = 0; i < len; ++i) {
+ c = temp[i];
+ /* 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
+ *s++ = c;
+ }
+ return s;
+}
+
+/*
+ * move cursor to start of line
+ * if flags & BL_WHITE move to first non-white
+ * if flags & BL_SOL move to first non-white if startofline is set,
+ * otherwise keep "curswant" column
+ * if flags & BL_FIX don't leave the cursor on a NUL.
+ */
+void beginline(flags)
+int flags;
+{
+ if ((flags & BL_SOL) && !p_sol)
+ coladvance(curwin->w_curswant);
+ else {
+ curwin->w_cursor.col = 0;
+ curwin->w_cursor.coladd = 0;
+
+ if (flags & (BL_WHITE | BL_SOL)) {
+ char_u *ptr;
+
+ for (ptr = ml_get_curline(); vim_iswhite(*ptr)
+ && !((flags & BL_FIX) && ptr[1] == NUL); ++ptr)
+ ++curwin->w_cursor.col;
+ }
+ curwin->w_set_curswant = TRUE;
+ }
+}
+
+/*
+ * oneright oneleft cursor_down cursor_up
+ *
+ * Move one char {right,left,down,up}.
+ * Doesn't move onto the NUL past the end of the line, unless it is allowed.
+ * Return OK when successful, FAIL when we hit a line of file boundary.
+ */
+
+int oneright() {
+ char_u *ptr;
+ int l;
+
+ if (virtual_active()) {
+ pos_T prevpos = curwin->w_cursor;
+
+ /* Adjust for multi-wide char (excluding TAB) */
+ ptr = ml_get_cursor();
+ 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). */
+ return (prevpos.col != curwin->w_cursor.col
+ || prevpos.coladd != curwin->w_cursor.coladd) ? OK : FAIL;
+ }
+
+ ptr = ml_get_cursor();
+ if (*ptr == NUL)
+ return FAIL; /* already at the very end */
+
+ if (has_mbyte)
+ l = (*mb_ptr2len)(ptr);
+ else
+ l = 1;
+
+ /* move "l" bytes right, but don't end up on the NUL, unless 'virtualedit'
+ * contains "onemore". */
+ if (ptr[l] == NUL
+ && (ve_flags & VE_ONEMORE) == 0
+ )
+ return FAIL;
+ curwin->w_cursor.col += l;
+
+ curwin->w_set_curswant = TRUE;
+ return OK;
+}
+
+int oneleft() {
+ if (virtual_active()) {
+ int width;
+ int v = getviscol();
+
+ if (v == 0)
+ return FAIL;
+
+ /* We might get stuck on 'showbreak', skip over it. */
+ width = 1;
+ for (;; ) {
+ coladvance(v - width);
+ /* getviscol() is slow, skip it when 'showbreak' is empty and
+ * there are no multi-byte characters */
+ if ((*p_sbr == NUL
+ && !has_mbyte
+ ) || getviscol() < v)
+ break;
+ ++width;
+ }
+
+ if (curwin->w_cursor.coladd == 1) {
+ char_u *ptr;
+
+ /* Adjust for multi-wide char (not a TAB) */
+ ptr = ml_get_cursor();
+ if (*ptr != TAB && vim_isprintc(
+ (*mb_ptr2char)(ptr)
+ ) && ptr2cells(ptr) > 1)
+ curwin->w_cursor.coladd = 0;
+ }
+
+ curwin->w_set_curswant = TRUE;
+ return OK;
+ }
+
+ if (curwin->w_cursor.col == 0)
+ return FAIL;
+
+ curwin->w_set_curswant = TRUE;
+ --curwin->w_cursor.col;
+
+ /* if the character on the left of the current cursor is a multi-byte
+ * character, move to its first byte */
+ if (has_mbyte)
+ mb_adjust_cursor();
+ return OK;
+}
+
+int cursor_up(n, upd_topline)
+long n;
+int upd_topline; /* When TRUE: update topline */
+{
+ linenr_T lnum;
+
+ if (n > 0) {
+ lnum = curwin->w_cursor.lnum;
+ /* This fails if the cursor is already in the first line or the count
+ * is larger than the line number and '-' is in 'cpoptions' */
+ if (lnum <= 1 || (n >= lnum && vim_strchr(p_cpo, CPO_MINUS) != NULL))
+ return FAIL;
+ if (n >= lnum)
+ lnum = 1;
+ else if (hasAnyFolding(curwin)) {
+ /*
+ * Count each sequence of folded lines as one logical line.
+ */
+ /* go to the start of the current fold */
+ (void)hasFolding(lnum, &lnum, NULL);
+
+ while (n--) {
+ /* move up one line */
+ --lnum;
+ if (lnum <= 1)
+ break;
+ /* If we entered a fold, move to the beginning, unless in
+ * Insert mode or when 'foldopen' contains "all": it will open
+ * in a moment. */
+ if (n > 0 || !((State & INSERT) || (fdo_flags & FDO_ALL)))
+ (void)hasFolding(lnum, &lnum, NULL);
+ }
+ if (lnum < 1)
+ lnum = 1;
+ } else
+ lnum -= n;
+ curwin->w_cursor.lnum = lnum;
+ }
+
+ /* try to advance to the column we want to be at */
+ coladvance(curwin->w_curswant);
+
+ if (upd_topline)
+ update_topline(); /* make sure curwin->w_topline is valid */
+
+ return OK;
+}
+
+/*
+ * Cursor down a number of logical lines.
+ */
+int cursor_down(n, upd_topline)
+long n;
+int upd_topline; /* When TRUE: update topline */
+{
+ linenr_T lnum;
+
+ if (n > 0) {
+ lnum = curwin->w_cursor.lnum;
+ /* Move to last line of fold, will fail if it's the end-of-file. */
+ (void)hasFolding(lnum, NULL, &lnum);
+ /* This fails if the cursor is already in the last line or would move
+ * beyond the last line and '-' is in 'cpoptions' */
+ if (lnum >= curbuf->b_ml.ml_line_count
+ || (lnum + n > curbuf->b_ml.ml_line_count
+ && vim_strchr(p_cpo, CPO_MINUS) != NULL))
+ return FAIL;
+ if (lnum + n >= curbuf->b_ml.ml_line_count)
+ lnum = curbuf->b_ml.ml_line_count;
+ else if (hasAnyFolding(curwin)) {
+ linenr_T last;
+
+ /* count each sequence of folded lines as one logical line */
+ while (n--) {
+ if (hasFolding(lnum, NULL, &last))
+ lnum = last + 1;
+ else
+ ++lnum;
+ if (lnum >= curbuf->b_ml.ml_line_count)
+ break;
+ }
+ if (lnum > curbuf->b_ml.ml_line_count)
+ lnum = curbuf->b_ml.ml_line_count;
+ } else
+ lnum += n;
+ curwin->w_cursor.lnum = lnum;
+ }
+
+ /* try to advance to the column we want to be at */
+ coladvance(curwin->w_curswant);
+
+ if (upd_topline)
+ update_topline(); /* make sure curwin->w_topline is valid */
+
+ return OK;
+}
+
+/*
+ * Stuff the last inserted text in the read buffer.
+ * Last_insert actually is a copy of the redo buffer, so we
+ * first have to remove the command.
+ */
+int stuff_inserted(c, count, no_esc)
+int c; /* Command character to be inserted */
+long count; /* Repeat this many times */
+int no_esc; /* Don't add an ESC at the end */
+{
+ char_u *esc_ptr;
+ char_u *ptr;
+ char_u *last_ptr;
+ char_u last = NUL;
+
+ ptr = get_last_insert();
+ if (ptr == NULL) {
+ EMSG(_(e_noinstext));
+ return FAIL;
+ }
+
+ /* 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 */
+
+ /* 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"
+ * starts with ^D. -- Acevedo
+ */
+ last_ptr = (esc_ptr ? esc_ptr : ptr + STRLEN(ptr)) - 1;
+ if (last_ptr >= ptr && (*last_ptr == '0' || *last_ptr == '^')
+ && (no_esc || (*ptr == Ctrl_D && count > 1))) {
+ last = *last_ptr;
+ *last_ptr = NUL;
+ }
+
+ do {
+ stuffReadbuff(ptr);
+ /* a trailing "0" is inserted as "<C-V>048", "^" as "<C-V>^" */
+ if (last)
+ stuffReadbuff((char_u *)(last == '0'
+ ? IF_EB("\026\060\064\070", CTRL_V_STR "xf0")
+ : IF_EB("\026^", CTRL_V_STR "^")));
+ } while (--count > 0);
+
+ if (last)
+ *last_ptr = last;
+
+ if (esc_ptr != NULL)
+ *esc_ptr = ESC; /* put the ESC back */
+
+ /* may want to stuff a trailing ESC, to get out of Insert mode */
+ if (!no_esc)
+ stuffcharReadbuff(ESC);
+
+ return OK;
+}
+
+char_u * get_last_insert() {
+ if (last_insert == NULL)
+ return NULL;
+ return last_insert + last_insert_skip;
+}
+
+/*
+ * Get last inserted string, and remove trailing <Esc>.
+ * Returns pointer to allocated memory (must be freed) or NULL.
+ */
+char_u * get_last_insert_save() {
+ char_u *s;
+ int len;
+
+ if (last_insert == NULL)
+ return NULL;
+ s = vim_strsave(last_insert + last_insert_skip);
+ if (s != NULL) {
+ len = (int)STRLEN(s);
+ if (len > 0 && s[len - 1] == ESC) /* remove trailing ESC */
+ s[len - 1] = NUL;
+ }
+ return s;
+}
+
+/*
+ * Check the word in front of the cursor for an abbreviation.
+ * Called when the non-id character "c" has been entered.
+ * When an abbreviation is recognized it is removed from the text and
+ * the replacement string is inserted in typebuf.tb_buf[], followed by "c".
+ */
+static int echeck_abbr(c)
+int c;
+{
+ /* Don't check for abbreviation in paste mode, when disabled and just
+ * after moving around with cursor keys. */
+ if (p_paste || no_abbr || arrow_used)
+ return FALSE;
+
+ return check_abbr(c, ml_get_curline(), curwin->w_cursor.col,
+ curwin->w_cursor.lnum == Insstart.lnum ? Insstart.col : 0);
+}
+
+/*
+ * replace-stack functions
+ *
+ * When replacing characters, the replaced characters are remembered for each
+ * new character. This is used to re-insert the old text when backspacing.
+ *
+ * There is a NUL headed list of characters for each character that is
+ * currently in the file after the insertion point. When BS is used, one NUL
+ * headed list is put back for the deleted character.
+ *
+ * For a newline, there are two NUL headed lists. One contains the characters
+ * that the NL replaced. The extra one stores the characters after the cursor
+ * that were deleted (always white space).
+ *
+ * Replace_offset is normally 0, in which case replace_push will add a new
+ * character at the end of the stack. If replace_offset is not 0, that many
+ * characters will be left on the stack above the newly inserted character.
+ */
+
+static char_u *replace_stack = NULL;
+static long replace_stack_nr = 0; /* next entry in replace stack */
+static long replace_stack_len = 0; /* max. number of entries */
+
+void replace_push(c)
+int c; /* character that is replaced (NUL is none) */
+{
+ char_u *p;
+
+ if (replace_stack_nr < replace_offset) /* nothing to do */
+ return;
+ if (replace_stack_len <= replace_stack_nr) {
+ replace_stack_len += 50;
+ p = lalloc(sizeof(char_u) * replace_stack_len, TRUE);
+ if (p == NULL) { /* out of memory */
+ replace_stack_len -= 50;
+ return;
+ }
+ if (replace_stack != NULL) {
+ mch_memmove(p, replace_stack,
+ (size_t)(replace_stack_nr * sizeof(char_u)));
+ vim_free(replace_stack);
+ }
+ replace_stack = p;
+ }
+ p = replace_stack + replace_stack_nr - replace_offset;
+ if (replace_offset)
+ mch_memmove(p + 1, p, (size_t)(replace_offset * sizeof(char_u)));
+ *p = c;
+ ++replace_stack_nr;
+}
+
+/*
+ * Push a character onto the replace stack. Handles a multi-byte character in
+ * reverse byte order, so that the first byte is popped off first.
+ * Return the number of bytes done (includes composing characters).
+ */
+int replace_push_mb(p)
+char_u *p;
+{
+ int l = (*mb_ptr2len)(p);
+ int j;
+
+ for (j = l - 1; j >= 0; --j)
+ replace_push(p[j]);
+ return l;
+}
+
+/*
+ * Pop one item from the replace stack.
+ * return -1 if stack empty
+ * return replaced character or NUL otherwise
+ */
+static int replace_pop() {
+ if (replace_stack_nr == 0)
+ return -1;
+ return (int)replace_stack[--replace_stack_nr];
+}
+
+/*
+ * Join the top two items on the replace stack. This removes to "off"'th NUL
+ * encountered.
+ */
+static void replace_join(off)
+int off; /* offset for which NUL to remove */
+{
+ int i;
+
+ for (i = replace_stack_nr; --i >= 0; )
+ if (replace_stack[i] == NUL && off-- <= 0) {
+ --replace_stack_nr;
+ mch_memmove(replace_stack + i, replace_stack + i + 1,
+ (size_t)(replace_stack_nr - i));
+ return;
+ }
+}
+
+/*
+ * Pop bytes from the replace stack until a NUL is found, and insert them
+ * before the cursor. Can only be used in REPLACE or VREPLACE mode.
+ */
+static void replace_pop_ins() {
+ int cc;
+ int oldState = State;
+
+ State = NORMAL; /* don't want REPLACE here */
+ while ((cc = replace_pop()) > 0) {
+ mb_replace_pop_ins(cc);
+ dec_cursor();
+ }
+ State = oldState;
+}
+
+/*
+ * Insert bytes popped from the replace stack. "cc" is the first byte. If it
+ * indicates a multi-byte char, pop the other bytes too.
+ */
+static void mb_replace_pop_ins(cc)
+int cc;
+{
+ int n;
+ char_u buf[MB_MAXBYTES + 1];
+ int i;
+ int c;
+
+ if (has_mbyte && (n = MB_BYTE2LEN(cc)) > 1) {
+ buf[0] = cc;
+ for (i = 1; i < n; ++i)
+ buf[i] = replace_pop();
+ ins_bytes_len(buf, n);
+ } else
+ ins_char(cc);
+
+ if (enc_utf8)
+ /* Handle composing chars. */
+ for (;; ) {
+ c = replace_pop();
+ if (c == -1) /* stack empty */
+ break;
+ if ((n = MB_BYTE2LEN(c)) == 1) {
+ /* Not a multi-byte char, put it back. */
+ replace_push(c);
+ break;
+ } else {
+ buf[0] = c;
+ for (i = 1; i < n; ++i)
+ buf[i] = replace_pop();
+ if (utf_iscomposing(utf_ptr2char(buf)))
+ ins_bytes_len(buf, n);
+ else {
+ /* Not a composing char, put it back. */
+ for (i = n - 1; i >= 0; --i)
+ replace_push(buf[i]);
+ break;
+ }
+ }
+ }
+}
+
+/*
+ * make the replace stack empty
+ * (called when exiting replace mode)
+ */
+static void replace_flush() {
+ vim_free(replace_stack);
+ replace_stack = NULL;
+ replace_stack_len = 0;
+ replace_stack_nr = 0;
+}
+
+/*
+ * Handle doing a BS for one character.
+ * cc < 0: replace stack empty, just move cursor
+ * cc == 0: character was inserted, delete it
+ * cc > 0: character was replaced, put cc (first byte of original char) back
+ * and check for more characters to be put back
+ * When "limit_col" is >= 0, don't delete before this column. Matters when
+ * using composing characters, use del_char_after_col() instead of del_char().
+ */
+static void replace_do_bs(limit_col)
+int limit_col;
+{
+ int cc;
+ int orig_len = 0;
+ int ins_len;
+ int orig_vcols = 0;
+ colnr_T start_vcol;
+ char_u *p;
+ int i;
+ int vcol;
+
+ cc = replace_pop();
+ if (cc > 0) {
+ if (State & VREPLACE_FLAG) {
+ /* Get the number of screen cells used by the character we are
+ * going to delete. */
+ getvcol(curwin, &curwin->w_cursor, NULL, &start_vcol, NULL);
+ orig_vcols = chartabsize(ml_get_cursor(), start_vcol);
+ }
+ if (has_mbyte) {
+ (void)del_char_after_col(limit_col);
+ if (State & VREPLACE_FLAG)
+ orig_len = (int)STRLEN(ml_get_cursor());
+ replace_push(cc);
+ } else {
+ pchar_cursor(cc);
+ if (State & VREPLACE_FLAG)
+ orig_len = (int)STRLEN(ml_get_cursor()) - 1;
+ }
+ replace_pop_ins();
+
+ if (State & VREPLACE_FLAG) {
+ /* Get the number of screen cells used by the inserted characters */
+ p = ml_get_cursor();
+ ins_len = (int)STRLEN(p) - orig_len;
+ vcol = start_vcol;
+ for (i = 0; i < ins_len; ++i) {
+ vcol += chartabsize(p + i, vcol);
+ i += (*mb_ptr2len)(p) - 1;
+ }
+ vcol -= start_vcol;
+
+ /* Delete spaces that were inserted after the cursor to keep the
+ * text aligned. */
+ curwin->w_cursor.col += ins_len;
+ while (vcol > orig_vcols && gchar_cursor() == ' ') {
+ del_char(FALSE);
+ ++orig_vcols;
+ }
+ curwin->w_cursor.col -= ins_len;
+ }
+
+ /* mark the buffer as changed and prepare for displaying */
+ changed_bytes(curwin->w_cursor.lnum, curwin->w_cursor.col);
+ } else if (cc == 0)
+ (void)del_char_after_col(limit_col);
+}
+
+/*
+ * Return TRUE if C-indenting is on.
+ */
+static int cindent_on() {
+ return !p_paste && (curbuf->b_p_cin
+ || *curbuf->b_p_inde != NUL
+ );
+}
+
+/*
+ * Re-indent the current line, based on the current contents of it and the
+ * surrounding lines. Fixing the cursor position seems really easy -- I'm very
+ * confused what all the part that handles Control-T is doing that I'm not.
+ * "get_the_indent" should be get_c_indent, get_expr_indent or get_lisp_indent.
+ */
+
+void fixthisline(get_the_indent)
+int (*get_the_indent)__ARGS((void));
+{
+ change_indent(INDENT_SET, get_the_indent(), FALSE, 0, TRUE);
+ if (linewhite(curwin->w_cursor.lnum))
+ did_ai = TRUE; /* delete the indent if the line stays empty */
+}
+
+void fix_indent() {
+ if (p_paste)
+ return;
+ if (curbuf->b_p_lisp && curbuf->b_p_ai)
+ fixthisline(get_lisp_indent);
+ else if (cindent_on())
+ do_c_expr_indent();
+}
+
+/*
+ * return TRUE if 'cinkeys' contains the key "keytyped",
+ * when == '*': Only if key is preceded with '*' (indent before insert)
+ * when == '!': Only if key is preceded with '!' (don't insert)
+ * when == ' ': Only if key is not preceded with '*'(indent afterwards)
+ *
+ * "keytyped" can have a few special values:
+ * KEY_OPEN_FORW
+ * KEY_OPEN_BACK
+ * KEY_COMPLETE just finished completion.
+ *
+ * If line_is_empty is TRUE accept keys with '0' before them.
+ */
+int in_cinkeys(keytyped, when, line_is_empty)
+int keytyped;
+int when;
+int line_is_empty;
+{
+ char_u *look;
+ int try_match;
+ int try_match_word;
+ char_u *p;
+ char_u *line;
+ int icase;
+ int i;
+
+ if (keytyped == NUL)
+ /* Can happen with CTRL-Y and CTRL-E on a short line. */
+ return FALSE;
+
+ if (*curbuf->b_p_inde != NUL)
+ look = curbuf->b_p_indk; /* 'indentexpr' set: use 'indentkeys' */
+ else
+ look = curbuf->b_p_cink; /* 'indentexpr' empty: use 'cinkeys' */
+ while (*look) {
+ /*
+ * Find out if we want to try a match with this key, depending on
+ * 'when' and a '*' or '!' before the key.
+ */
+ switch (when) {
+ case '*': try_match = (*look == '*'); break;
+ case '!': try_match = (*look == '!'); break;
+ default: try_match = (*look != '*'); break;
+ }
+ if (*look == '*' || *look == '!')
+ ++look;
+
+ /*
+ * If there is a '0', only accept a match if the line is empty.
+ * But may still match when typing last char of a word.
+ */
+ if (*look == '0') {
+ try_match_word = try_match;
+ if (!line_is_empty)
+ try_match = FALSE;
+ ++look;
+ } else
+ try_match_word = FALSE;
+
+ /*
+ * does it look like a control character?
+ */
+ if (*look == '^'
+ && look[1] >= '?' && look[1] <= '_'
+ ) {
+ if (try_match && keytyped == Ctrl_chr(look[1]))
+ return TRUE;
+ look += 2;
+ }
+ /*
+ * 'o' means "o" command, open forward.
+ * 'O' means "O" command, open backward.
+ */
+ else if (*look == 'o') {
+ if (try_match && keytyped == KEY_OPEN_FORW)
+ return TRUE;
+ ++look;
+ } else if (*look == 'O') {
+ if (try_match && keytyped == KEY_OPEN_BACK)
+ return TRUE;
+ ++look;
+ }
+ /*
+ * 'e' means to check for "else" at start of line and just before the
+ * cursor.
+ */
+ else if (*look == 'e') {
+ if (try_match && keytyped == 'e' && curwin->w_cursor.col >= 4) {
+ p = ml_get_curline();
+ if (skipwhite(p) == p + curwin->w_cursor.col - 4 &&
+ STRNCMP(p + curwin->w_cursor.col - 4, "else", 4) == 0)
+ return TRUE;
+ }
+ ++look;
+ }
+ /*
+ * ':' only causes an indent if it is at the end of a label or case
+ * statement, or when it was before typing the ':' (to fix
+ * class::method for C++).
+ */
+ else if (*look == ':') {
+ if (try_match && keytyped == ':') {
+ p = ml_get_curline();
+ if (cin_iscase(p, FALSE) || cin_isscopedecl(p) || cin_islabel())
+ return TRUE;
+ /* Need to get the line again after cin_islabel(). */
+ p = ml_get_curline();
+ if (curwin->w_cursor.col > 2
+ && p[curwin->w_cursor.col - 1] == ':'
+ && p[curwin->w_cursor.col - 2] == ':') {
+ p[curwin->w_cursor.col - 1] = ' ';
+ i = (cin_iscase(p, FALSE) || cin_isscopedecl(p)
+ || cin_islabel());
+ p = ml_get_curline();
+ p[curwin->w_cursor.col - 1] = ':';
+ if (i)
+ return TRUE;
+ }
+ }
+ ++look;
+ }
+ /*
+ * Is it a key in <>, maybe?
+ */
+ else if (*look == '<') {
+ if (try_match) {
+ /*
+ * make up some named keys <o>, <O>, <e>, <0>, <>>, <<>, <*>,
+ * <:> and <!> so that people can re-indent on o, O, e, 0, <,
+ * >, *, : and ! keys if they really really want to.
+ */
+ if (vim_strchr((char_u *)"<>!*oOe0:", look[1]) != NULL
+ && keytyped == look[1])
+ return TRUE;
+
+ if (keytyped == get_special_key_code(look + 1))
+ return TRUE;
+ }
+ while (*look && *look != '>')
+ look++;
+ while (*look == '>')
+ look++;
+ }
+ /*
+ * Is it a word: "=word"?
+ */
+ else if (*look == '=' && look[1] != ',' && look[1] != NUL) {
+ ++look;
+ if (*look == '~') {
+ icase = TRUE;
+ ++look;
+ } else
+ icase = FALSE;
+ p = vim_strchr(look, ',');
+ if (p == NULL)
+ p = look + STRLEN(look);
+ if ((try_match || try_match_word)
+ && curwin->w_cursor.col >= (colnr_T)(p - look)) {
+ int match = FALSE;
+
+ if (keytyped == KEY_COMPLETE) {
+ char_u *s;
+
+ /* Just completed a word, check if it starts with "look".
+ * search back for the start of a word. */
+ line = ml_get_curline();
+ if (has_mbyte) {
+ char_u *n;
+
+ for (s = line + curwin->w_cursor.col; s > line; s = n) {
+ n = mb_prevptr(line, s);
+ if (!vim_iswordp(n))
+ break;
+ }
+ } else
+ for (s = line + curwin->w_cursor.col; s > line; --s)
+ if (!vim_iswordc(s[-1]))
+ break;
+ if (s + (p - look) <= line + curwin->w_cursor.col
+ && (icase
+ ? MB_STRNICMP(s, look, 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 = ml_get_cursor();
+ if ((curwin->w_cursor.col == (colnr_T)(p - look)
+ || !vim_iswordc(line[-(p - look) - 1]))
+ && (icase
+ ? MB_STRNICMP(line - (p - look), look, 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 = ml_get_curline();
+ if ((int)(skipwhite(line) - line) !=
+ (int)(curwin->w_cursor.col - (p - look)))
+ match = FALSE;
+ }
+ if (match)
+ return TRUE;
+ }
+ look = p;
+ }
+ /*
+ * ok, it's a boring generic character.
+ */
+ else {
+ if (try_match && *look == keytyped)
+ return TRUE;
+ ++look;
+ }
+
+ /*
+ * Skip over ", ".
+ */
+ look = skip_to_option_part(look);
+ }
+ return FALSE;
+}
+
+/*
+ * Map Hebrew keyboard when in hkmap mode.
+ */
+int hkmap(c)
+int c;
+{
+ if (p_hkmapp) { /* phonetic mapping, by Ilya Dogolazky */
+ enum {hALEF=0, BET, GIMEL, DALET, HEI, VAV, ZAIN, HET, TET, IUD,
+ KAFsofit, hKAF, LAMED, MEMsofit, MEM, NUNsofit, NUN, SAMEH, AIN,
+ PEIsofit, PEI, ZADIsofit, ZADI, KOF, RESH, hSHIN, TAV};
+ static char_u map[26] =
+ {(char_u)hALEF /*a*/, (char_u)BET /*b*/, (char_u)hKAF /*c*/,
+ (char_u)DALET /*d*/, (char_u)-1 /*e*/, (char_u)PEIsofit /*f*/,
+ (char_u)GIMEL /*g*/, (char_u)HEI /*h*/, (char_u)IUD /*i*/,
+ (char_u)HET /*j*/, (char_u)KOF /*k*/, (char_u)LAMED /*l*/,
+ (char_u)MEM /*m*/, (char_u)NUN /*n*/, (char_u)SAMEH /*o*/,
+ (char_u)PEI /*p*/, (char_u)-1 /*q*/, (char_u)RESH /*r*/,
+ (char_u)ZAIN /*s*/, (char_u)TAV /*t*/, (char_u)TET /*u*/,
+ (char_u)VAV /*v*/, (char_u)hSHIN /*w*/, (char_u)-1 /*x*/,
+ (char_u)AIN /*y*/, (char_u)ZADI /*z*/};
+
+ if (c == 'N' || c == 'M' || c == 'P' || c == 'C' || c == 'Z')
+ return (int)(map[CharOrd(c)] - 1 + p_aleph);
+ /* '-1'='sofit' */
+ else if (c == 'x')
+ return 'X';
+ else if (c == 'q')
+ return '\''; /* {geresh}={'} */
+ else if (c == 246)
+ return ' '; /* \"o --> ' ' for a german keyboard */
+ else if (c == 228)
+ return ' '; /* \"a --> ' ' -- / -- */
+ else if (c == 252)
+ return ' '; /* \"u --> ' ' -- / -- */
+ /* NOTE: islower() does not do the right thing for us on Linux so we
+ * do this the same was as 5.7 and previous, so it works correctly on
+ * all systems. Specifically, the e.g. Delete and Arrow keys are
+ * munged and won't work if e.g. searching for Hebrew text.
+ */
+ else if (c >= 'a' && c <= 'z')
+ return (int)(map[CharOrdLow(c)] + p_aleph);
+ else
+ return c;
+ } else {
+ switch (c) {
+ case '`': return ';';
+ case '/': return '.';
+ case '\'': return ',';
+ case 'q': return '/';
+ case 'w': return '\'';
+
+ /* Hebrew letters - set offset from 'a' */
+ case ',': c = '{'; break;
+ case '.': c = 'v'; break;
+ case ';': c = 't'; break;
+ default: {
+ static char str[] = "zqbcxlsjphmkwonu ydafe rig";
+
+ if (c < 'a' || c > 'z')
+ return c;
+ c = str[CharOrdLow(c)];
+ break;
+ }
+ }
+
+ return (int)(CharOrdLow(c) + p_aleph);
+ }
+}
+
+static void ins_reg() {
+ int need_redraw = FALSE;
+ int regname;
+ int literally = 0;
+ int vis_active = VIsual_active;
+
+ /*
+ * If we are going to wait for a character, show a '"'.
+ */
+ pc_status = PC_STATUS_UNSET;
+ if (redrawing() && !char_avail()) {
+ /* may need to redraw when no more chars available now */
+ ins_redraw(FALSE);
+
+ edit_putchar('"', TRUE);
+ add_to_showcmd_c(Ctrl_R);
+ }
+
+#ifdef USE_ON_FLY_SCROLL
+ dont_scroll = TRUE; /* disallow scrolling here */
+#endif
+
+ /*
+ * Don't map the register name. This also prevents the mode message to be
+ * deleted when ESC is hit.
+ */
+ ++no_mapping;
+ regname = plain_vgetc();
+ LANGMAP_ADJUST(regname, TRUE);
+ if (regname == Ctrl_R || regname == Ctrl_O || regname == Ctrl_P) {
+ /* Get a third key for literal register insertion */
+ literally = regname;
+ add_to_showcmd_c(literally);
+ regname = plain_vgetc();
+ LANGMAP_ADJUST(regname, TRUE);
+ }
+ --no_mapping;
+
+ /* Don't call u_sync() while typing the expression or giving an error
+ * message for it. Only call it explicitly. */
+ ++no_u_sync;
+ if (regname == '=') {
+# ifdef USE_IM_CONTROL
+ int im_on = im_get_status();
+# endif
+ /* Sync undo when evaluating the expression calls setline() or
+ * append(), so that it can be undone separately. */
+ u_sync_once = 2;
+
+ regname = get_expr_register();
+# ifdef USE_IM_CONTROL
+ /* Restore the Input Method. */
+ if (im_on)
+ im_set_active(TRUE);
+# endif
+ }
+ if (regname == NUL || !valid_yank_reg(regname, FALSE)) {
+ vim_beep();
+ need_redraw = TRUE; /* remove the '"' */
+ } else {
+ if (literally == Ctrl_O || literally == Ctrl_P) {
+ /* Append the command to the redo buffer. */
+ AppendCharToRedobuff(Ctrl_R);
+ AppendCharToRedobuff(literally);
+ AppendCharToRedobuff(regname);
+
+ do_put(regname, BACKWARD, 1L,
+ (literally == Ctrl_P ? PUT_FIXINDENT : 0) | PUT_CURSEND);
+ } else if (insert_reg(regname, literally) == FAIL) {
+ vim_beep();
+ need_redraw = TRUE; /* remove the '"' */
+ } else if (stop_insert_mode)
+ /* When the '=' register was used and a function was invoked that
+ * did ":stopinsert" then stuff_empty() returns FALSE but we won't
+ * insert anything, need to remove the '"' */
+ need_redraw = TRUE;
+
+ }
+ --no_u_sync;
+ if (u_sync_once == 1)
+ ins_need_undo = TRUE;
+ u_sync_once = 0;
+ clear_showcmd();
+
+ /* If the inserted register is empty, we need to remove the '"' */
+ if (need_redraw || stuff_empty())
+ edit_unputchar();
+
+ /* Disallow starting Visual mode here, would get a weird mode. */
+ if (!vis_active && VIsual_active)
+ end_visual_mode();
+}
+
+/*
+ * CTRL-G commands in Insert mode.
+ */
+static void ins_ctrl_g() {
+ int c;
+
+ /* Right after CTRL-X the cursor will be after the ruler. */
+ setcursor();
+
+ /*
+ * Don't map the second key. This also prevents the mode message to be
+ * deleted when ESC is hit.
+ */
+ ++no_mapping;
+ c = plain_vgetc();
+ --no_mapping;
+ switch (c) {
+ /* CTRL-G k and CTRL-G <Up>: cursor up to Insstart.col */
+ case K_UP:
+ case Ctrl_K:
+ case 'k': ins_up(TRUE);
+ break;
+
+ /* CTRL-G j and CTRL-G <Down>: cursor down to Insstart.col */
+ case K_DOWN:
+ case Ctrl_J:
+ case 'j': ins_down(TRUE);
+ break;
+
+ /* CTRL-G u: start new undoable edit */
+ case 'u': u_sync(TRUE);
+ ins_need_undo = TRUE;
+
+ /* Need to reset Insstart, esp. because a BS that joins
+ * a line to the previous one must save for undo. */
+ Insstart = curwin->w_cursor;
+ break;
+
+ /* Unknown CTRL-G command, reserved for future expansion. */
+ default: vim_beep();
+ }
+}
+
+/*
+ * CTRL-^ in Insert mode.
+ */
+static void ins_ctrl_hat() {
+ if (map_to_exists_mode((char_u *)"", LANGMAP, FALSE)) {
+ /* ":lmap" mappings exists, Toggle use of ":lmap" mappings. */
+ if (State & LANGMAP) {
+ curbuf->b_p_iminsert = B_IMODE_NONE;
+ State &= ~LANGMAP;
+ } else {
+ curbuf->b_p_iminsert = B_IMODE_LMAP;
+ State |= LANGMAP;
+#ifdef USE_IM_CONTROL
+ im_set_active(FALSE);
+#endif
+ }
+ }
+#ifdef USE_IM_CONTROL
+ else {
+ /* There are no ":lmap" mappings, toggle IM */
+ if (im_get_status()) {
+ curbuf->b_p_iminsert = B_IMODE_NONE;
+ im_set_active(FALSE);
+ } else {
+ curbuf->b_p_iminsert = B_IMODE_IM;
+ State &= ~LANGMAP;
+ im_set_active(TRUE);
+ }
+ }
+#endif
+ set_iminsert_global();
+ showmode();
+ /* Show/unshow value of 'keymap' in status lines. */
+ status_redraw_curbuf();
+}
+
+/*
+ * Handle ESC in insert mode.
+ * Returns TRUE when leaving insert mode, FALSE when going to repeat the
+ * insert.
+ */
+static int ins_esc(count, cmdchar, nomove)
+long *count;
+int cmdchar;
+int nomove; /* don't move cursor */
+{
+ int temp;
+ static int disabled_redraw = FALSE;
+
+ check_spell_redraw();
+# if defined(ESC_CHG_TO_ENG_MODE)
+ hangul_input_state_set(0);
+# endif
+ if (composing_hangul) {
+ push_raw_key(composing_hangul_buffer, 2);
+ composing_hangul = 0;
+ }
+
+ temp = curwin->w_cursor.col;
+ if (disabled_redraw) {
+ --RedrawingDisabled;
+ 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);
+
+ /*
+ * Repeating insert may take a long time. Check for
+ * interrupt now and then.
+ */
+ if (*count > 0) {
+ line_breakcheck();
+ if (got_int)
+ *count = 0;
+ }
+
+ if (--*count > 0) { /* repeat what was typed */
+ /* Vi repeats the insert without replacing characters. */
+ if (vim_strchr(p_cpo, CPO_REPLCNT) != NULL)
+ State &= ~REPLACE_FLAG;
+
+ (void)start_redo_ins();
+ if (cmdchar == 'r' || cmdchar == 'v')
+ stuffReadbuff(ESC_STR); /* no ESC in redo buffer */
+ ++RedrawingDisabled;
+ disabled_redraw = TRUE;
+ return FALSE; /* repeat the insert */
+ }
+ stop_insert(&curwin->w_cursor, TRUE, nomove);
+ undisplay_dollar();
+ }
+
+ /* When an autoindent was removed, curswant stays after the
+ * indent */
+ if (restart_edit == NUL && (colnr_T)temp == curwin->w_cursor.col)
+ curwin->w_set_curswant = TRUE;
+
+ /* Remember the last Insert position in the '^ mark. */
+ if (!cmdmod.keepjumps)
+ curbuf->b_last_insert = curwin->w_cursor;
+
+ /*
+ * The cursor should end up on the last inserted character.
+ * Don't do it for CTRL-O, unless past the end of the line.
+ */
+ if (!nomove
+ && (curwin->w_cursor.col != 0
+ || curwin->w_cursor.coladd > 0
+ )
+ && (restart_edit == NUL
+ || (gchar_cursor() == NUL
+ && !VIsual_active
+ ))
+ && !revins_on
+ ) {
+ if (curwin->w_cursor.coladd > 0 || ve_flags == VE_ALL) {
+ oneleft();
+ if (restart_edit != NUL)
+ ++curwin->w_cursor.coladd;
+ } else {
+ --curwin->w_cursor.col;
+ /* Correct cursor for multi-byte character. */
+ if (has_mbyte)
+ mb_adjust_cursor();
+ }
+ }
+
+#ifdef USE_IM_CONTROL
+ /* Disable IM to allow typing English directly for Normal mode commands.
+ * When ":lmap" is enabled don't change 'iminsert' (IM can be enabled as
+ * well). */
+ if (!(State & LANGMAP))
+ im_save_status(&curbuf->b_p_iminsert);
+ im_set_active(FALSE);
+#endif
+
+ State = NORMAL;
+ /* need to position cursor again (e.g. when on a TAB ) */
+ changed_cline_bef_curs();
+
+ setmouse();
+#ifdef CURSOR_SHAPE
+ ui_cursor_shape(); /* may show different cursor shape */
+#endif
+
+ /*
+ * When recording or for CTRL-O, need to display the new mode.
+ * Otherwise remove the mode message.
+ */
+ if (Recording || restart_edit != NUL)
+ showmode();
+ else if (p_smd)
+ MSG("");
+
+ return TRUE; /* exit Insert mode */
+}
+
+/*
+ * Toggle language: hkmap and revins_on.
+ * Move to end of reverse inserted text.
+ */
+static void ins_ctrl_() {
+ if (revins_on && revins_chars && revins_scol >= 0) {
+ while (gchar_cursor() != NUL && revins_chars--)
+ ++curwin->w_cursor.col;
+ }
+ p_ri = !p_ri;
+ revins_on = (State == INSERT && p_ri);
+ if (revins_on) {
+ revins_scol = curwin->w_cursor.col;
+ revins_legal++;
+ revins_chars = 0;
+ undisplay_dollar();
+ } else
+ revins_scol = -1;
+ if (p_altkeymap) {
+ /*
+ * to be consistent also for redo command, using '.'
+ * set arrow_used to true and stop it - causing to redo
+ * characters entered in one mode (normal/reverse insert).
+ */
+ arrow_used = TRUE;
+ (void)stop_arrow();
+ p_fkmap = curwin->w_p_rl ^ p_ri;
+ if (p_fkmap && p_ri)
+ State = INSERT;
+ } else
+ p_hkmap = curwin->w_p_rl ^ p_ri; /* be consistent! */
+ showmode();
+}
+
+/*
+ * If 'keymodel' contains "startsel", may start selection.
+ * Returns TRUE when a CTRL-O and other keys stuffed.
+ */
+static int ins_start_select(c)
+int c;
+{
+ if (km_startsel)
+ switch (c) {
+ case K_KHOME:
+ case K_KEND:
+ case K_PAGEUP:
+ case K_KPAGEUP:
+ case K_PAGEDOWN:
+ case K_KPAGEDOWN:
+ if (!(mod_mask & MOD_MASK_SHIFT))
+ break;
+ /* FALLTHROUGH */
+ case K_S_LEFT:
+ case K_S_RIGHT:
+ case K_S_UP:
+ case K_S_DOWN:
+ case K_S_END:
+ case K_S_HOME:
+ /* Start selection right away, the cursor can move with
+ * CTRL-O when beyond the end of the line. */
+ start_selection();
+
+ /* Execute the key in (insert) Select mode. */
+ stuffcharReadbuff(Ctrl_O);
+ if (mod_mask) {
+ char_u buf[4];
+
+ buf[0] = K_SPECIAL;
+ buf[1] = KS_MODIFIER;
+ buf[2] = mod_mask;
+ buf[3] = NUL;
+ stuffReadbuff(buf);
+ }
+ stuffcharReadbuff(c);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*
+ * <Insert> key in Insert mode: toggle insert/replace mode.
+ */
+static void ins_insert(replaceState)
+int replaceState;
+{
+ if (p_fkmap && p_ri) {
+ beep_flush();
+ EMSG(farsi_text_3); /* encoded in Farsi */
+ return;
+ }
+
+ set_vim_var_string(VV_INSERTMODE,
+ (char_u *)((State & REPLACE_FLAG) ? "i" :
+ replaceState == VREPLACE ? "v" :
+ "r"), 1);
+ apply_autocmds(EVENT_INSERTCHANGE, NULL, NULL, FALSE, curbuf);
+ if (State & REPLACE_FLAG)
+ State = INSERT | (State & LANGMAP);
+ else
+ State = replaceState | (State & LANGMAP);
+ AppendCharToRedobuff(K_INS);
+ showmode();
+#ifdef CURSOR_SHAPE
+ ui_cursor_shape(); /* may show different cursor shape */
+#endif
+}
+
+/*
+ * Pressed CTRL-O in Insert mode.
+ */
+static void ins_ctrl_o() {
+ if (State & VREPLACE_FLAG)
+ restart_edit = 'V';
+ else if (State & REPLACE_FLAG)
+ restart_edit = 'R';
+ else
+ restart_edit = 'I';
+ if (virtual_active())
+ ins_at_eol = FALSE; /* cursor always keeps its column */
+ else
+ ins_at_eol = (gchar_cursor() == NUL);
+}
+
+/*
+ * If the cursor is on an indent, ^T/^D insert/delete one
+ * shiftwidth. Otherwise ^T/^D behave like a "<<" or ">>".
+ * Always round the indent to 'shiftwidth', this is compatible
+ * with vi. But vi only supports ^T and ^D after an
+ * autoindent, we support it everywhere.
+ */
+static void ins_shift(c, lastc)
+int c;
+int lastc;
+{
+ if (stop_arrow() == FAIL)
+ return;
+ AppendCharToRedobuff(c);
+
+ /*
+ * 0^D and ^^D: remove all indent.
+ */
+ 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)
+ replace_pop_ins();
+ 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(ml_get_curline()) != 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() {
+ int temp;
+
+ if (stop_arrow() == FAIL)
+ return;
+ if (gchar_cursor() == NUL) { /* delete newline */
+ temp = curwin->w_cursor.col;
+ if (!can_bs(BS_EOL) /* only if "eol" included */
+ || do_join(2, FALSE, TRUE, FALSE) == FAIL)
+ vim_beep();
+ else
+ curwin->w_cursor.col = temp;
+ } else if (del_char(FALSE) == FAIL) /* delete char under cursor */
+ vim_beep();
+ did_ai = FALSE;
+ did_si = FALSE;
+ can_si = FALSE;
+ can_si_back = FALSE;
+ AppendCharToRedobuff(K_DEL);
+}
+
+static void ins_bs_one __ARGS((colnr_T *vcolp));
+
+/*
+ * Delete one character for ins_bs().
+ */
+static void ins_bs_one(vcolp)
+colnr_T *vcolp;
+{
+ dec_cursor();
+ getvcol(curwin, &curwin->w_cursor, vcolp, NULL, NULL);
+ if (State & REPLACE_FLAG) {
+ /* Don't delete characters before the insert point when in
+ * Replace mode */
+ if (curwin->w_cursor.lnum != Insstart.lnum
+ || curwin->w_cursor.col >= Insstart.col)
+ replace_do_bs(-1);
+ } else
+ (void)del_char(FALSE);
+}
+
+/*
+ * Handle Backspace, delete-word and delete-line in Insert mode.
+ * Return TRUE when backspace was actually used.
+ */
+static int ins_bs(c, mode, inserted_space_p)
+int c;
+int mode;
+int *inserted_space_p;
+{
+ linenr_T lnum;
+ int cc;
+ int temp = 0; /* init for GCC */
+ colnr_T save_col;
+ colnr_T mincol;
+ int did_backspace = FALSE;
+ int in_indent;
+ 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()
+ || (
+ !revins_on &&
+ ((curwin->w_cursor.lnum == 1 && curwin->w_cursor.col == 0)
+ || (!can_bs(BS_START)
+ && (arrow_used
+ || (curwin->w_cursor.lnum == Insstart.lnum
+ && curwin->w_cursor.col <= Insstart.col)))
+ || (!can_bs(BS_INDENT) && !arrow_used && ai_col > 0
+ && curwin->w_cursor.col <= ai_col)
+ || (!can_bs(BS_EOL) && curwin->w_cursor.col == 0)))) {
+ vim_beep();
+ return FALSE;
+ }
+
+ if (stop_arrow() == FAIL)
+ return FALSE;
+ in_indent = inindent(0);
+ if (in_indent)
+ can_cindent = FALSE;
+ end_comment_pending = NUL; /* After BS, don't auto-end comment */
+ if (revins_on) /* put cursor after last inserted char */
+ inc_cursor();
+
+ /* Virtualedit:
+ * BACKSPACE_CHAR eats a virtual space
+ * BACKSPACE_WORD eats all coladd
+ * BACKSPACE_LINE eats all coladd and keeps going
+ */
+ if (curwin->w_cursor.coladd > 0) {
+ if (mode == BACKSPACE_CHAR) {
+ --curwin->w_cursor.coladd;
+ return TRUE;
+ }
+ if (mode == BACKSPACE_WORD) {
+ curwin->w_cursor.coladd = 0;
+ return TRUE;
+ }
+ curwin->w_cursor.coladd = 0;
+ }
+
+ /*
+ * delete newline!
+ */
+ if (curwin->w_cursor.col == 0) {
+ lnum = Insstart.lnum;
+ if (curwin->w_cursor.lnum == Insstart.lnum
+ || revins_on
+ ) {
+ if (u_save((linenr_T)(curwin->w_cursor.lnum - 2),
+ (linenr_T)(curwin->w_cursor.lnum + 1)) == FAIL)
+ return FALSE;
+ --Insstart.lnum;
+ Insstart.col = MAXCOL;
+ }
+ /*
+ * In replace mode:
+ * cc < 0: NL was inserted, delete it
+ * cc >= 0: NL was replaced, put original characters back
+ */
+ cc = -1;
+ if (State & REPLACE_FLAG)
+ cc = replace_pop(); /* returns -1 if NL was inserted */
+ /*
+ * In replace mode, in the line we started replacing, we only move the
+ * cursor.
+ */
+ if ((State & REPLACE_FLAG) && curwin->w_cursor.lnum <= lnum) {
+ dec_cursor();
+ } else {
+ if (!(State & VREPLACE_FLAG)
+ || curwin->w_cursor.lnum > orig_line_count) {
+ temp = gchar_cursor(); /* remember current char */
+ --curwin->w_cursor.lnum;
+
+ /* When "aw" is in 'formatoptions' we must delete the space at
+ * the end of the line, otherwise the line will be broken
+ * again when auto-formatting. */
+ if (has_format_option(FO_AUTO)
+ && has_format_option(FO_WHITE_PAR)) {
+ char_u *ptr = ml_get_buf(curbuf, curwin->w_cursor.lnum,
+ TRUE);
+ int len;
+
+ len = (int)STRLEN(ptr);
+ if (len > 0 && ptr[len - 1] == ' ')
+ ptr[len - 1] = NUL;
+ }
+
+ (void)do_join(2, FALSE, FALSE, FALSE);
+ if (temp == NUL && gchar_cursor() != NUL)
+ inc_cursor();
+ } else
+ dec_cursor();
+
+ /*
+ * In REPLACE mode we have to put back the text that was replaced
+ * by the NL. On the replace stack is first a NUL-terminated
+ * sequence of characters that were deleted and then the
+ * characters that NL replaced.
+ */
+ if (State & REPLACE_FLAG) {
+ /*
+ * Do the next ins_char() in NORMAL state, to
+ * prevent ins_char() from replacing characters and
+ * avoiding showmatch().
+ */
+ oldState = State;
+ State = NORMAL;
+ /*
+ * restore characters (blanks) deleted after cursor
+ */
+ while (cc > 0) {
+ save_col = curwin->w_cursor.col;
+ mb_replace_pop_ins(cc);
+ curwin->w_cursor.col = save_col;
+ cc = replace_pop();
+ }
+ /* restore the characters that NL replaced */
+ replace_pop_ins();
+ State = oldState;
+ }
+ }
+ did_ai = FALSE;
+ } else {
+ /*
+ * Delete character(s) before the cursor.
+ */
+ if (revins_on) /* put cursor on last inserted char */
+ dec_cursor();
+ mincol = 0;
+ /* keep indent */
+ if (mode == BACKSPACE_LINE
+ && (curbuf->b_p_ai
+ || cindent_on()
+ )
+ && !revins_on
+ ) {
+ save_col = curwin->w_cursor.col;
+ beginline(BL_WHITE);
+ if (curwin->w_cursor.col < save_col)
+ mincol = curwin->w_cursor.col;
+ curwin->w_cursor.col = save_col;
+ }
+
+ /*
+ * Handle deleting one 'shiftwidth' or 'softtabstop'.
+ */
+ if ( mode == BACKSPACE_CHAR
+ && ((p_sta && in_indent)
+ || (get_sts_value() != 0
+ && curwin->w_cursor.col > 0
+ && (*(ml_get_cursor() - 1) == TAB
+ || (*(ml_get_cursor() - 1) == ' '
+ && (!*inserted_space_p
+ || arrow_used)))))) {
+ int ts;
+ colnr_T vcol;
+ colnr_T want_vcol;
+ colnr_T start_vcol;
+
+ *inserted_space_p = FALSE;
+ if (p_sta && in_indent)
+ ts = (int)get_sw_value(curbuf);
+ else
+ ts = (int)get_sts_value();
+ /* Compute the virtual column where we want to be. Since
+ * 'showbreak' may get in the way, need to get the last column of
+ * the previous character. */
+ getvcol(curwin, &curwin->w_cursor, &vcol, NULL, NULL);
+ start_vcol = vcol;
+ dec_cursor();
+ getvcol(curwin, &curwin->w_cursor, NULL, NULL, &want_vcol);
+ inc_cursor();
+ want_vcol = (want_vcol / ts) * ts;
+
+ /* delete characters until we are at or before want_vcol */
+ while (vcol > want_vcol
+ && (cc = *(ml_get_cursor() - 1), vim_iswhite(cc)))
+ ins_bs_one(&vcol);
+
+ /* insert extra spaces until we are at want_vcol */
+ while (vcol < want_vcol) {
+ /* Remember the first char we inserted */
+ if (curwin->w_cursor.lnum == Insstart.lnum
+ && curwin->w_cursor.col < Insstart.col)
+ Insstart.col = curwin->w_cursor.col;
+
+ if (State & VREPLACE_FLAG)
+ ins_char(' ');
+ else {
+ ins_str((char_u *)" ");
+ if ((State & REPLACE_FLAG))
+ replace_push(NUL);
+ }
+ getvcol(curwin, &curwin->w_cursor, &vcol, NULL, NULL);
+ }
+
+ /* If we are now back where we started delete one character. Can
+ * happen when using 'sts' and 'linebreak'. */
+ if (vcol >= start_vcol)
+ ins_bs_one(&vcol);
+ }
+ /*
+ * Delete upto starting point, start of line or previous word.
+ */
+ else do {
+ if (!revins_on) /* put cursor on char to be deleted */
+ dec_cursor();
+
+ /* start of word? */
+ if (mode == BACKSPACE_WORD && !vim_isspace(gchar_cursor())) {
+ mode = BACKSPACE_WORD_NOT_SPACE;
+ temp = vim_iswordc(gchar_cursor());
+ }
+ /* end of word? */
+ else if (mode == BACKSPACE_WORD_NOT_SPACE
+ && (vim_isspace(cc = gchar_cursor())
+ || vim_iswordc(cc) != temp)) {
+ if (!revins_on)
+ inc_cursor();
+ else if (State & REPLACE_FLAG)
+ dec_cursor();
+ break;
+ }
+ if (State & REPLACE_FLAG)
+ replace_do_bs(-1);
+ else {
+ if (enc_utf8 && p_deco)
+ (void)utfc_ptr2char(ml_get_cursor(), 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 (enc_utf8 && p_deco && cpc[0] != NUL)
+ inc_cursor();
+ if (revins_chars) {
+ revins_chars--;
+ revins_legal++;
+ }
+ if (revins_on && gchar_cursor() == NUL)
+ break;
+ }
+ /* Just a single backspace?: */
+ if (mode == BACKSPACE_CHAR)
+ break;
+ } while (
+ revins_on ||
+ (curwin->w_cursor.col > mincol
+ && (curwin->w_cursor.lnum != Insstart.lnum
+ || curwin->w_cursor.col != Insstart.col)));
+ did_backspace = TRUE;
+ }
+ did_si = FALSE;
+ can_si = FALSE;
+ can_si_back = FALSE;
+ if (curwin->w_cursor.col <= 1)
+ did_ai = FALSE;
+ /*
+ * It's a little strange to put backspaces into the redo
+ * buffer, but it makes auto-indent a lot easier to deal
+ * with.
+ */
+ AppendCharToRedobuff(c);
+
+ /* If deleted before the insertion point, adjust it */
+ if (curwin->w_cursor.lnum == Insstart.lnum
+ && curwin->w_cursor.col < Insstart.col)
+ Insstart.col = curwin->w_cursor.col;
+
+ /* vi behaviour: the cursor moves backward but the character that
+ * was there remains visible
+ * Vim behaviour: the cursor moves backward and the character that
+ * was there is erased from the screen.
+ * We can emulate the vi behaviour by pretending there is a dollar
+ * displayed even when there isn't.
+ * --pkv Sun Jan 19 01:56:40 EST 2003 */
+ if (vim_strchr(p_cpo, CPO_BACKSPACE) != NULL && dollar_vcol == -1)
+ dollar_vcol = curwin->w_virtcol;
+
+ /* When deleting a char the cursor line must never be in a closed fold.
+ * E.g., when 'foldmethod' is indent and deleting the first non-white
+ * char before a Tab. */
+ if (did_backspace)
+ foldOpenCursor();
+
+ return did_backspace;
+}
+
+static void ins_mouse(c)
+int c;
+{
+ pos_T tpos;
+ win_T *old_curwin = curwin;
+
+ if (!mouse_has(MOUSE_INSERT))
+ return;
+
+ undisplay_dollar();
+ tpos = curwin->w_cursor;
+ if (do_mouse(NULL, c, BACKWARD, 1L, 0)) {
+ win_T *new_curwin = curwin;
+
+ if (curwin != old_curwin && win_valid(old_curwin)) {
+ /* Mouse took us to another window. We need to go back to the
+ * previous one to stop insert there properly. */
+ curwin = old_curwin;
+ curbuf = curwin->w_buffer;
+ }
+ start_arrow(curwin == old_curwin ? &tpos : NULL);
+ if (curwin != new_curwin && win_valid(new_curwin)) {
+ curwin = new_curwin;
+ curbuf = curwin->w_buffer;
+ }
+ can_cindent = TRUE;
+ }
+
+ /* redraw status lines (in case another window became active) */
+ redraw_statuslines();
+}
+
+static void ins_mousescroll(dir)
+int dir;
+{
+ pos_T tpos;
+ win_T *old_curwin = curwin;
+ int did_scroll = FALSE;
+
+ tpos = curwin->w_cursor;
+
+ if (mouse_row >= 0 && mouse_col >= 0) {
+ int row, col;
+
+ row = mouse_row;
+ col = mouse_col;
+
+ /* find the window at the pointer coordinates */
+ curwin = mouse_find_win(&row, &col);
+ curbuf = curwin->w_buffer;
+ }
+ if (curwin == old_curwin)
+ undisplay_dollar();
+
+ /* Don't scroll the window in which completion is being done. */
+ if (!pum_visible()
+ || curwin != old_curwin
+ ) {
+ if (dir == MSCR_DOWN || dir == MSCR_UP) {
+ if (mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL))
+ scroll_redraw(dir,
+ (long)(curwin->w_botline - curwin->w_topline));
+ else
+ scroll_redraw(dir, 3L);
+ }
+ did_scroll = TRUE;
+ }
+
+ curwin->w_redr_status = TRUE;
+
+ curwin = old_curwin;
+ curbuf = curwin->w_buffer;
+
+ /* The popup menu may overlay the window, need to redraw it.
+ * TODO: Would be more efficient to only redraw the windows that are
+ * overlapped by the popup menu. */
+ if (pum_visible() && did_scroll) {
+ redraw_all_later(NOT_VALID);
+ ins_compl_show_pum();
+ }
+
+ if (!equalpos(curwin->w_cursor, tpos)) {
+ start_arrow(&tpos);
+ can_cindent = TRUE;
+ }
+}
+
+
+
+static void ins_left() {
+ pos_T tpos;
+
+ if ((fdo_flags & FDO_HOR) && KeyTyped)
+ foldOpenCursor();
+ undisplay_dollar();
+ tpos = curwin->w_cursor;
+ if (oneleft() == OK) {
+ start_arrow(&tpos);
+ /* If exit reversed string, position is fixed */
+ if (revins_scol != -1 && (int)curwin->w_cursor.col >= revins_scol)
+ revins_legal++;
+ revins_chars++;
+ }
+ /*
+ * if 'whichwrap' set for cursor in insert mode may go to
+ * previous line
+ */
+ else if (vim_strchr(p_ww, '[') != NULL && curwin->w_cursor.lnum > 1) {
+ start_arrow(&tpos);
+ --(curwin->w_cursor.lnum);
+ coladvance((colnr_T)MAXCOL);
+ curwin->w_set_curswant = TRUE; /* so we stay at the end */
+ } else
+ vim_beep();
+}
+
+static void ins_home(c)
+int c;
+{
+ pos_T tpos;
+
+ if ((fdo_flags & FDO_HOR) && KeyTyped)
+ foldOpenCursor();
+ undisplay_dollar();
+ tpos = curwin->w_cursor;
+ if (c == K_C_HOME)
+ curwin->w_cursor.lnum = 1;
+ curwin->w_cursor.col = 0;
+ curwin->w_cursor.coladd = 0;
+ curwin->w_curswant = 0;
+ start_arrow(&tpos);
+}
+
+static void ins_end(c)
+int c;
+{
+ pos_T tpos;
+
+ if ((fdo_flags & FDO_HOR) && KeyTyped)
+ foldOpenCursor();
+ undisplay_dollar();
+ tpos = curwin->w_cursor;
+ if (c == K_C_END)
+ curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
+ coladvance((colnr_T)MAXCOL);
+ curwin->w_curswant = MAXCOL;
+
+ start_arrow(&tpos);
+}
+
+static void ins_s_left() {
+ if ((fdo_flags & FDO_HOR) && KeyTyped)
+ foldOpenCursor();
+ undisplay_dollar();
+ if (curwin->w_cursor.lnum > 1 || curwin->w_cursor.col > 0) {
+ start_arrow(&curwin->w_cursor);
+ (void)bck_word(1L, FALSE, FALSE);
+ curwin->w_set_curswant = TRUE;
+ } else
+ vim_beep();
+}
+
+static void ins_right() {
+ if ((fdo_flags & FDO_HOR) && KeyTyped)
+ foldOpenCursor();
+ undisplay_dollar();
+ if (gchar_cursor() != NUL
+ || virtual_active()
+ ) {
+ start_arrow(&curwin->w_cursor);
+ curwin->w_set_curswant = TRUE;
+ if (virtual_active())
+ oneright();
+ else {
+ if (has_mbyte)
+ curwin->w_cursor.col += (*mb_ptr2len)(ml_get_cursor());
+ else
+ ++curwin->w_cursor.col;
+ }
+
+ revins_legal++;
+ if (revins_chars)
+ revins_chars--;
+ }
+ /* if 'whichwrap' set for cursor in insert mode, may move the
+ * cursor to the next line */
+ else if (vim_strchr(p_ww, ']') != NULL
+ && curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count) {
+ start_arrow(&curwin->w_cursor);
+ curwin->w_set_curswant = TRUE;
+ ++curwin->w_cursor.lnum;
+ curwin->w_cursor.col = 0;
+ } else
+ vim_beep();
+}
+
+static void ins_s_right() {
+ if ((fdo_flags & FDO_HOR) && KeyTyped)
+ foldOpenCursor();
+ undisplay_dollar();
+ if (curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count
+ || gchar_cursor() != NUL) {
+ start_arrow(&curwin->w_cursor);
+ (void)fwd_word(1L, FALSE, 0);
+ curwin->w_set_curswant = TRUE;
+ } else
+ vim_beep();
+}
+
+static void ins_up(startcol)
+int startcol; /* when TRUE move to Insstart.col */
+{
+ pos_T tpos;
+ linenr_T old_topline = curwin->w_topline;
+ int old_topfill = curwin->w_topfill;
+
+ undisplay_dollar();
+ tpos = curwin->w_cursor;
+ if (cursor_up(1L, TRUE) == OK) {
+ if (startcol)
+ coladvance(getvcol_nolist(&Insstart));
+ if (old_topline != curwin->w_topline
+ || old_topfill != curwin->w_topfill
+ )
+ redraw_later(VALID);
+ start_arrow(&tpos);
+ can_cindent = TRUE;
+ } else
+ vim_beep();
+}
+
+static void ins_pageup() {
+ pos_T tpos;
+
+ undisplay_dollar();
+
+ if (mod_mask & MOD_MASK_CTRL) {
+ /* <C-PageUp>: tab page back */
+ if (first_tabpage->tp_next != NULL) {
+ start_arrow(&curwin->w_cursor);
+ goto_tabpage(-1);
+ }
+ return;
+ }
+
+ tpos = curwin->w_cursor;
+ if (onepage(BACKWARD, 1L) == OK) {
+ start_arrow(&tpos);
+ can_cindent = TRUE;
+ } else
+ vim_beep();
+}
+
+static void ins_down(startcol)
+int startcol; /* when TRUE move to Insstart.col */
+{
+ pos_T tpos;
+ linenr_T old_topline = curwin->w_topline;
+ int old_topfill = curwin->w_topfill;
+
+ undisplay_dollar();
+ tpos = curwin->w_cursor;
+ if (cursor_down(1L, TRUE) == OK) {
+ if (startcol)
+ coladvance(getvcol_nolist(&Insstart));
+ if (old_topline != curwin->w_topline
+ || old_topfill != curwin->w_topfill
+ )
+ redraw_later(VALID);
+ start_arrow(&tpos);
+ can_cindent = TRUE;
+ } else
+ vim_beep();
+}
+
+static void ins_pagedown() {
+ pos_T tpos;
+
+ undisplay_dollar();
+
+ if (mod_mask & MOD_MASK_CTRL) {
+ /* <C-PageDown>: tab page forward */
+ if (first_tabpage->tp_next != NULL) {
+ start_arrow(&curwin->w_cursor);
+ goto_tabpage(0);
+ }
+ return;
+ }
+
+ tpos = curwin->w_cursor;
+ if (onepage(FORWARD, 1L) == OK) {
+ start_arrow(&tpos);
+ can_cindent = TRUE;
+ } else
+ vim_beep();
+}
+
+/*
+ * Handle TAB in Insert or Replace mode.
+ * Return TRUE when the TAB needs to be inserted like a normal character.
+ */
+static int ins_tab() {
+ int ind;
+ int i;
+ int temp;
+
+ if (Insstart_blank_vcol == MAXCOL && curwin->w_cursor.lnum == Insstart.lnum)
+ Insstart_blank_vcol = get_nolist_virtcol();
+ if (echeck_abbr(TAB + ABBR_OFF))
+ return FALSE;
+
+ ind = inindent(0);
+ if (ind)
+ can_cindent = FALSE;
+
+ /*
+ * When nothing special, insert TAB like a normal character
+ */
+ if (!curbuf->b_p_et
+ && !(p_sta && ind && curbuf->b_p_ts != get_sw_value(curbuf))
+ && get_sts_value() == 0)
+ return TRUE;
+
+ if (stop_arrow() == FAIL)
+ return TRUE;
+
+ did_ai = FALSE;
+ did_si = FALSE;
+ can_si = FALSE;
+ can_si_back = FALSE;
+ AppendToRedobuff((char_u *)"\t");
+
+ if (p_sta && ind) /* insert tab in indent, use 'shiftwidth' */
+ temp = (int)get_sw_value(curbuf);
+ else if (curbuf->b_p_sts != 0) /* use 'softtabstop' when set */
+ temp = (int)get_sts_value();
+ else /* otherwise use 'tabstop' */
+ temp = (int)curbuf->b_p_ts;
+ temp -= get_nolist_virtcol() % temp;
+
+ /*
+ * Insert the first space with ins_char(). It will delete one char in
+ * replace mode. Insert the rest with ins_str(); it will not delete any
+ * chars. For VREPLACE mode, we use ins_char() for all characters.
+ */
+ ins_char(' ');
+ while (--temp > 0) {
+ if (State & VREPLACE_FLAG)
+ ins_char(' ');
+ else {
+ ins_str((char_u *)" ");
+ if (State & REPLACE_FLAG) /* no char replaced */
+ replace_push(NUL);
+ }
+ }
+
+ /*
+ * When 'expandtab' not set: Replace spaces by TABs where possible.
+ */
+ if (!curbuf->b_p_et && (get_sts_value() || (p_sta && ind))) {
+ char_u *ptr;
+ char_u *saved_line = NULL; /* init for GCC */
+ pos_T pos;
+ pos_T fpos;
+ pos_T *cursor;
+ colnr_T want_vcol, vcol;
+ int change_col = -1;
+ int save_list = curwin->w_p_list;
+
+ /*
+ * Get the current line. For VREPLACE mode, don't make real changes
+ * yet, just work on a copy of the line.
+ */
+ if (State & VREPLACE_FLAG) {
+ pos = curwin->w_cursor;
+ cursor = &pos;
+ saved_line = vim_strsave(ml_get_curline());
+ if (saved_line == NULL)
+ return FALSE;
+ ptr = saved_line + pos.col;
+ } else {
+ ptr = ml_get_cursor();
+ cursor = &curwin->w_cursor;
+ }
+
+ /* When 'L' is not in 'cpoptions' a tab always takes up 'ts' spaces. */
+ if (vim_strchr(p_cpo, CPO_LISTWM) == NULL)
+ curwin->w_p_list = FALSE;
+
+ /* Find first white before the cursor */
+ fpos = curwin->w_cursor;
+ while (fpos.col > 0 && vim_iswhite(ptr[-1])) {
+ --fpos.col;
+ --ptr;
+ }
+
+ /* In Replace mode, don't change characters before the insert point. */
+ if ((State & REPLACE_FLAG)
+ && fpos.lnum == Insstart.lnum
+ && fpos.col < Insstart.col) {
+ ptr += Insstart.col - fpos.col;
+ fpos.col = Insstart.col;
+ }
+
+ /* compute virtual column numbers of first white and cursor */
+ getvcol(curwin, &fpos, &vcol, NULL, NULL);
+ getvcol(curwin, cursor, &want_vcol, NULL, NULL);
+
+ /* Use as many TABs as possible. Beware of 'showbreak' and
+ * 'linebreak' adding extra virtual columns. */
+ while (vim_iswhite(*ptr)) {
+ i = lbr_chartabsize((char_u *)"\t", vcol);
+ if (vcol + i > want_vcol)
+ break;
+ if (*ptr != TAB) {
+ *ptr = TAB;
+ if (change_col < 0) {
+ change_col = fpos.col; /* Column of first change */
+ /* May have to adjust Insstart */
+ if (fpos.lnum == Insstart.lnum && fpos.col < Insstart.col)
+ Insstart.col = fpos.col;
+ }
+ }
+ ++fpos.col;
+ ++ptr;
+ vcol += i;
+ }
+
+ if (change_col >= 0) {
+ int repl_off = 0;
+
+ /* Skip over the spaces we need. */
+ while (vcol < want_vcol && *ptr == ' ') {
+ vcol += lbr_chartabsize(ptr, vcol);
+ ++ptr;
+ ++repl_off;
+ }
+ if (vcol > want_vcol) {
+ /* Must have a char with 'showbreak' just before it. */
+ --ptr;
+ --repl_off;
+ }
+ fpos.col += repl_off;
+
+ /* Delete following spaces. */
+ i = cursor->col - fpos.col;
+ if (i > 0) {
+ STRMOVE(ptr, ptr + i);
+ /* correct replace stack. */
+ if ((State & REPLACE_FLAG)
+ && !(State & VREPLACE_FLAG)
+ )
+ for (temp = i; --temp >= 0; )
+ replace_join(repl_off);
+ }
+ cursor->col -= i;
+
+ /*
+ * In VREPLACE mode, we haven't changed anything yet. Do it now by
+ * backspacing over the changed spacing and then inserting the new
+ * spacing.
+ */
+ if (State & VREPLACE_FLAG) {
+ /* Backspace from real cursor to change_col */
+ backspace_until_column(change_col);
+
+ /* Insert each char in saved_line from changed_col to
+ * ptr-cursor */
+ ins_bytes_len(saved_line + change_col,
+ cursor->col - change_col);
+ }
+ }
+
+ if (State & VREPLACE_FLAG)
+ vim_free(saved_line);
+ curwin->w_p_list = save_list;
+ }
+
+ return FALSE;
+}
+
+/*
+ * Handle CR or NL in insert mode.
+ * Return TRUE when out of memory or can't undo.
+ */
+static int ins_eol(c)
+int c;
+{
+ int i;
+
+ if (echeck_abbr(c + ABBR_OFF))
+ return FALSE;
+ if (stop_arrow() == FAIL)
+ return TRUE;
+ undisplay_dollar();
+
+ /*
+ * Strange Vi behaviour: In Replace mode, typing a NL will not delete the
+ * character under the cursor. Only push a NUL on the replace stack,
+ * nothing to put back when the NL is deleted.
+ */
+ if ((State & REPLACE_FLAG)
+ && !(State & VREPLACE_FLAG)
+ )
+ replace_push(NUL);
+
+ /*
+ * In VREPLACE mode, a NL replaces the rest of the line, and starts
+ * replacing the next line, so we push all of the characters left on the
+ * line onto the replace stack. This is not done here though, it is done
+ * in open_line().
+ */
+
+ /* Put cursor on NUL if on the last char and coladd is 1 (happens after
+ * CTRL-O). */
+ if (virtual_active() && curwin->w_cursor.coladd > 0)
+ coladvance(getviscol());
+
+ if (p_altkeymap && p_fkmap)
+ fkmap(NL);
+ /* NL in reverse insert will always start in the end of
+ * current line. */
+ if (revins_on)
+ curwin->w_cursor.col += (colnr_T)STRLEN(ml_get_cursor());
+
+ AppendToRedobuff(NL_STR);
+ i = open_line(FORWARD,
+ 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. */
+ foldOpenCursor();
+
+ return !i;
+}
+
+/*
+ * Handle digraph in insert mode.
+ * Returns character still to be inserted, or NUL when nothing remaining to be
+ * done.
+ */
+static int ins_digraph() {
+ int c;
+ int cc;
+ int did_putchar = FALSE;
+
+ pc_status = PC_STATUS_UNSET;
+ if (redrawing() && !char_avail()) {
+ /* may need to redraw when no more chars available now */
+ ins_redraw(FALSE);
+
+ edit_putchar('?', TRUE);
+ did_putchar = TRUE;
+ add_to_showcmd_c(Ctrl_K);
+ }
+
+#ifdef USE_ON_FLY_SCROLL
+ dont_scroll = TRUE; /* disallow scrolling here */
+#endif
+
+ /* don't map the digraph chars. This also prevents the
+ * mode message to be deleted when ESC is hit */
+ ++no_mapping;
+ ++allow_keys;
+ 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 */
+ edit_unputchar();
+
+ if (IS_SPECIAL(c) || mod_mask) { /* special key */
+ clear_showcmd();
+ insert_special(c, TRUE, FALSE);
+ return NUL;
+ }
+ if (c != ESC) {
+ did_putchar = FALSE;
+ if (redrawing() && !char_avail()) {
+ /* may need to redraw when no more chars available now */
+ ins_redraw(FALSE);
+
+ if (char2cells(c) == 1) {
+ ins_redraw(FALSE);
+ edit_putchar(c, TRUE);
+ did_putchar = TRUE;
+ }
+ add_to_showcmd_c(c);
+ }
+ ++no_mapping;
+ ++allow_keys;
+ 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 */
+ edit_unputchar();
+ if (cc != ESC) {
+ AppendToRedobuff((char_u *)CTRL_V_STR);
+ c = getdigraph(c, cc, TRUE);
+ clear_showcmd();
+ return c;
+ }
+ }
+ clear_showcmd();
+ return NUL;
+}
+
+/*
+ * Handle CTRL-E and CTRL-Y in Insert mode: copy char from other line.
+ * Returns the char to be inserted, or NUL if none found.
+ */
+int ins_copychar(lnum)
+linenr_T lnum;
+{
+ int c;
+ int temp;
+ char_u *ptr, *prev_ptr;
+
+ if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count) {
+ vim_beep();
+ return NUL;
+ }
+
+ /* try to advance to the cursor column */
+ temp = 0;
+ ptr = ml_get(lnum);
+ prev_ptr = ptr;
+ validate_virtcol();
+ while ((colnr_T)temp < curwin->w_virtcol && *ptr != NUL) {
+ prev_ptr = ptr;
+ temp += lbr_chartabsize_adv(&ptr, (colnr_T)temp);
+ }
+ if ((colnr_T)temp > curwin->w_virtcol)
+ ptr = prev_ptr;
+
+ c = (*mb_ptr2char)(ptr);
+ if (c == NUL)
+ vim_beep();
+ return c;
+}
+
+/*
+ * CTRL-Y or CTRL-E typed in Insert mode.
+ */
+static int ins_ctrl_ey(tc)
+int tc;
+{
+ int c = tc;
+
+ if (ctrl_x_mode == CTRL_X_SCROLL) {
+ if (c == Ctrl_Y)
+ scrolldown_clamp();
+ else
+ scrollup_clamp();
+ redraw_later(VALID);
+ } else {
+ c = ins_copychar(curwin->w_cursor.lnum + (c == Ctrl_Y ? -1 : 1));
+ 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 */
+ tw_save = curbuf->b_p_tw;
+ curbuf->b_p_tw = -1;
+ insert_special(c, TRUE, FALSE);
+ curbuf->b_p_tw = tw_save;
+ revins_chars++;
+ revins_legal++;
+ c = Ctrl_V; /* pretend CTRL-V is last character */
+ auto_format(FALSE, TRUE);
+ }
+ }
+ return c;
+}
+
+/*
+ * Try to do some very smart auto-indenting.
+ * Used when inserting a "normal" character.
+ */
+static void ins_try_si(c)
+int c;
+{
+ pos_T *pos, old_pos;
+ char_u *ptr;
+ int i;
+ int temp;
+
+ /*
+ * do some very smart indenting when entering '{' or '}'
+ */
+ if (((did_si || can_si_back) && c == '{') || (can_si && c == '}')) {
+ /*
+ * for '}' set indent equal to indent of line containing matching '{'
+ */
+ if (c == '}' && (pos = findmatch(NULL, '{')) != NULL) {
+ old_pos = curwin->w_cursor;
+ /*
+ * If the matching '{' has a ')' immediately before it (ignoring
+ * white-space), then line up with the start of the line
+ * containing the matching '(' if there is one. This handles the
+ * case where an "if (..\n..) {" statement continues over multiple
+ * lines -- webb
+ */
+ ptr = ml_get(pos->lnum);
+ i = pos->col;
+ if (i > 0) /* skip blanks before '{' */
+ while (--i > 0 && vim_iswhite(ptr[i]))
+ ;
+ curwin->w_cursor.lnum = pos->lnum;
+ curwin->w_cursor.col = i;
+ if (ptr[i] == ')' && (pos = findmatch(NULL, '(')) != NULL)
+ curwin->w_cursor = *pos;
+ i = get_indent();
+ curwin->w_cursor = old_pos;
+ if (State & VREPLACE_FLAG)
+ change_indent(INDENT_SET, i, FALSE, NUL, TRUE);
+ else
+ (void)set_indent(i, SIN_CHANGED);
+ } else if (curwin->w_cursor.col > 0) {
+ /*
+ * when inserting '{' after "O" reduce indent, but not
+ * more than indent of previous line
+ */
+ temp = TRUE;
+ if (c == '{' && can_si_back && curwin->w_cursor.lnum > 1) {
+ old_pos = curwin->w_cursor;
+ i = get_indent();
+ while (curwin->w_cursor.lnum > 1) {
+ ptr = skipwhite(ml_get(--(curwin->w_cursor.lnum)));
+
+ /* ignore empty lines and lines starting with '#'. */
+ if (*ptr != '#' && *ptr != NUL)
+ break;
+ }
+ if (get_indent() >= i)
+ temp = FALSE;
+ curwin->w_cursor = old_pos;
+ }
+ if (temp)
+ shift_line(TRUE, FALSE, 1, TRUE);
+ }
+ }
+
+ /*
+ * set indent of '#' always to 0
+ */
+ if (curwin->w_cursor.col > 0 && can_si && c == '#') {
+ /* remember current indent for next line */
+ old_indent = get_indent();
+ (void)set_indent(0, SIN_CHANGED);
+ }
+
+ /* Adjust ai_col, the char at this position can be deleted. */
+ if (ai_col > curwin->w_cursor.col)
+ ai_col = curwin->w_cursor.col;
+}
+
+/*
+ * Get the value that w_virtcol would have when 'list' is off.
+ * Unless 'cpo' contains the 'L' flag.
+ */
+static colnr_T get_nolist_virtcol() {
+ if (curwin->w_p_list && vim_strchr(p_cpo, CPO_LISTWM) == NULL)
+ return getvcol_nolist(&curwin->w_cursor);
+ validate_virtcol();
+ return curwin->w_virtcol;
+}
+
+/*
+ * Handle the InsertCharPre autocommand.
+ * "c" is the character that was typed.
+ * Return a pointer to allocated memory with the replacement string.
+ * Return NULL to continue inserting "c".
+ */
+static char_u * do_insert_char_pre(c)
+int c;
+{
+ char_u *res;
+ char_u buf[MB_MAXBYTES + 1];
+
+ /* Return quickly when there is nothing to do. */
+ if (!has_insertcharpre())
+ return NULL;
+
+ if (has_mbyte)
+ buf[(*mb_char2bytes)(c, buf)] = NUL;
+ else {
+ buf[0] = c;
+ buf[1] = NUL;
+ }
+
+ /* Lock the text to avoid weird things from happening. */
+ ++textlock;
+ set_vim_var_string(VV_CHAR, buf, -1); /* set v:char */
+
+ 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)
+ res = vim_strsave(get_vim_var_str(VV_CHAR));
+ }
+
+ set_vim_var_string(VV_CHAR, NULL, -1); /* clear v:char */
+ --textlock;
+
+ return res;
+}
diff --git a/src/eval.c b/src/eval.c
new file mode 100644
index 0000000000..bcf9c75730
--- /dev/null
+++ b/src/eval.c
@@ -0,0 +1,20483 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * 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.
+ */
+
+/*
+ * eval.c: Expression evaluation.
+ */
+
+#include "vim.h"
+
+
+
+
+
+#if defined(FEAT_FLOAT) && defined(HAVE_MATH_H)
+# include <math.h>
+#endif
+
+#define DICT_MAXNEST 100 /* maximum nesting of lists and dicts */
+
+#define DO_NOT_FREE_CNT 99999 /* refcount for dict or list that should not
+ be freed. */
+
+/*
+ * In a hashtab item "hi_key" points to "di_key" in a dictitem.
+ * This avoids adding a pointer to the hashtab item.
+ * DI2HIKEY() converts a dictitem pointer to a hashitem key pointer.
+ * HIKEY2DI() converts a hashitem key pointer to a dictitem pointer.
+ * HI2DI() converts a hashitem pointer to a dictitem pointer.
+ */
+static dictitem_T dumdi;
+#define DI2HIKEY(di) ((di)->di_key)
+#define HIKEY2DI(p) ((dictitem_T *)(p - (dumdi.di_key - (char_u *)&dumdi)))
+#define HI2DI(hi) HIKEY2DI((hi)->hi_key)
+
+/*
+ * Structure returned by get_lval() and used by set_var_lval().
+ * For a plain name:
+ * "name" points to the variable name.
+ * "exp_name" is NULL.
+ * "tv" is NULL
+ * For a magic braces name:
+ * "name" points to the expanded variable name.
+ * "exp_name" is non-NULL, to be freed later.
+ * "tv" is NULL
+ * For an index in a list:
+ * "name" points to the (expanded) variable name.
+ * "exp_name" NULL or non-NULL, to be freed later.
+ * "tv" points to the (first) list item value
+ * "li" points to the (first) list item
+ * "range", "n1", "n2" and "empty2" indicate what items are used.
+ * For an existing Dict item:
+ * "name" points to the (expanded) variable name.
+ * "exp_name" NULL or non-NULL, to be freed later.
+ * "tv" points to the dict item value
+ * "newkey" is NULL
+ * For a non-existing Dict item:
+ * "name" points to the (expanded) variable name.
+ * "exp_name" NULL or non-NULL, to be freed later.
+ * "tv" points to the Dictionary typval_T
+ * "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. */
+} lval_T;
+
+
+static char *e_letunexp = N_("E18: Unexpected characters in :let");
+static char *e_listidx = N_("E684: list index out of range: %ld");
+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_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_(
+ "E122: Function %s already exists, add ! to replace it");
+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 dictitem_T globvars_var; /* variable used for g: */
+#define globvarht globvardict.dv_hashtab
+
+/*
+ * Old Vim variables such as "v:version" are also available without the "v:".
+ * Also in functions. We need a special hashtable for them.
+ */
+static hashtab_T compat_hashtab;
+
+/*
+ * When recursively copying lists and dicts we need to remember which ones we
+ * have done to avoid endless recursiveness. This unique ID is used for that.
+ * The last bit is used for previous_funccal, ignored when comparing.
+ */
+static int current_copyID = 0;
+#define COPYID_INC 2
+#define COPYID_MASK (~0x1)
+
+/*
+ * 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;
+ dict_T sv_dict;
+} scriptvar_T;
+
+static garray_T ga_scripts = {0, 0, sizeof(scriptvar_T *), 4, NULL};
+#define SCRIPT_SV(id) (((scriptvar_T **)ga_scripts.ga_data)[(id) - 1])
+#define SCRIPT_VARS(id) (SCRIPT_SV(id)->sv_dict.dv_hashtab)
+
+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 */
+
+/*
+ * 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) */
+};
+
+/* 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" */
+
+/*
+ * All user-defined functions are found in this hashtable.
+ */
+static hashtab_T func_hashtab;
+
+/* 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 */
+
+/* From user function to hashitem and back. */
+static ufunc_T dumuf;
+#define UF2HIKEY(fp) ((fp)->uf_name)
+#define HIKEY2UF(p) ((ufunc_T *)(p - (dumuf.uf_name - (char_u *)&dumuf)))
+#define HI2UF(hi) HIKEY2UF((hi)->hi_key)
+
+#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 MAX_FUNC_ARGS 20 /* maximum number of function arguments */
+#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;
+
+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 */
+};
+
+/*
+ * Info used by a ":for" loop.
+ */
+typedef struct {
+ int fi_semicolon; /* TRUE if ending in '; var]' */
+ int fi_varcount; /* nr of variables in the list */
+ listwatch_T fi_lw; /* keep an eye on the item used. */
+ list_T *fi_list; /* list being used */
+} 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;
+
+
+/*
+ * Array to hold the value of v: variables.
+ * The value is in a dictitem, so that it can also be used in the v: scope.
+ * The reason to use this table anyway is for very quick access to the
+ * variables with the VV_ defines.
+ */
+#include "version.h"
+
+/* values for vv_flags: */
+#define VV_COMPAT 1 /* compatible, also used without "v:" */
+#define VV_RO 2 /* read-only */
+#define VV_RO_SBX 4 /* read-only in the sandbox */
+
+#define VV_NAME(s, t) s, {{t, 0, {0}}, 0, {0}}, {0}
+
+static struct vimvar {
+ char *vv_name; /* name of variable, without v: */
+ dictitem_T vv_di; /* value and name for key */
+ char vv_filler[16]; /* space for LONGEST name below!!! */
+ char vv_flags; /* VV_COMPAT, VV_RO, VV_RO_SBX */
+} vimvars[VV_LEN] =
+{
+ /*
+ * The order here must match the VV_ defines in vim.h!
+ * Initializing a union does not work, leave tv.vval empty to get zero's.
+ */
+ {VV_NAME("count", VAR_NUMBER), VV_COMPAT+VV_RO},
+ {VV_NAME("count1", VAR_NUMBER), VV_RO},
+ {VV_NAME("prevcount", VAR_NUMBER), VV_RO},
+ {VV_NAME("errmsg", VAR_STRING), VV_COMPAT},
+ {VV_NAME("warningmsg", VAR_STRING), 0},
+ {VV_NAME("statusmsg", VAR_STRING), 0},
+ {VV_NAME("shell_error", VAR_NUMBER), VV_COMPAT+VV_RO},
+ {VV_NAME("this_session", VAR_STRING), VV_COMPAT},
+ {VV_NAME("version", VAR_NUMBER), VV_COMPAT+VV_RO},
+ {VV_NAME("lnum", VAR_NUMBER), VV_RO_SBX},
+ {VV_NAME("termresponse", VAR_STRING), VV_RO},
+ {VV_NAME("fname", VAR_STRING), VV_RO},
+ {VV_NAME("lang", VAR_STRING), VV_RO},
+ {VV_NAME("lc_time", VAR_STRING), VV_RO},
+ {VV_NAME("ctype", VAR_STRING), VV_RO},
+ {VV_NAME("charconvert_from", VAR_STRING), VV_RO},
+ {VV_NAME("charconvert_to", VAR_STRING), VV_RO},
+ {VV_NAME("fname_in", VAR_STRING), VV_RO},
+ {VV_NAME("fname_out", VAR_STRING), VV_RO},
+ {VV_NAME("fname_new", VAR_STRING), VV_RO},
+ {VV_NAME("fname_diff", VAR_STRING), VV_RO},
+ {VV_NAME("cmdarg", VAR_STRING), VV_RO},
+ {VV_NAME("foldstart", VAR_NUMBER), VV_RO_SBX},
+ {VV_NAME("foldend", VAR_NUMBER), VV_RO_SBX},
+ {VV_NAME("folddashes", VAR_STRING), VV_RO_SBX},
+ {VV_NAME("foldlevel", VAR_NUMBER), VV_RO_SBX},
+ {VV_NAME("progname", VAR_STRING), VV_RO},
+ {VV_NAME("servername", VAR_STRING), VV_RO},
+ {VV_NAME("dying", VAR_NUMBER), VV_RO},
+ {VV_NAME("exception", VAR_STRING), VV_RO},
+ {VV_NAME("throwpoint", VAR_STRING), VV_RO},
+ {VV_NAME("register", VAR_STRING), VV_RO},
+ {VV_NAME("cmdbang", VAR_NUMBER), VV_RO},
+ {VV_NAME("insertmode", VAR_STRING), VV_RO},
+ {VV_NAME("val", VAR_UNKNOWN), VV_RO},
+ {VV_NAME("key", VAR_UNKNOWN), VV_RO},
+ {VV_NAME("profiling", VAR_NUMBER), VV_RO},
+ {VV_NAME("fcs_reason", VAR_STRING), VV_RO},
+ {VV_NAME("fcs_choice", VAR_STRING), 0},
+ {VV_NAME("beval_bufnr", VAR_NUMBER), VV_RO},
+ {VV_NAME("beval_winnr", VAR_NUMBER), VV_RO},
+ {VV_NAME("beval_lnum", VAR_NUMBER), VV_RO},
+ {VV_NAME("beval_col", VAR_NUMBER), VV_RO},
+ {VV_NAME("beval_text", VAR_STRING), VV_RO},
+ {VV_NAME("scrollstart", VAR_STRING), 0},
+ {VV_NAME("swapname", VAR_STRING), VV_RO},
+ {VV_NAME("swapchoice", VAR_STRING), 0},
+ {VV_NAME("swapcommand", VAR_STRING), VV_RO},
+ {VV_NAME("char", VAR_STRING), 0},
+ {VV_NAME("mouse_win", VAR_NUMBER), 0},
+ {VV_NAME("mouse_lnum", VAR_NUMBER), 0},
+ {VV_NAME("mouse_col", VAR_NUMBER), 0},
+ {VV_NAME("operator", VAR_STRING), VV_RO},
+ {VV_NAME("searchforward", VAR_NUMBER), 0},
+ {VV_NAME("hlsearch", VAR_NUMBER), 0},
+ {VV_NAME("oldfiles", VAR_LIST), 0},
+ {VV_NAME("windowid", VAR_NUMBER), VV_RO},
+};
+
+/* shorthand */
+#define vv_type vv_di.di_tv.v_type
+#define vv_nr vv_di.di_tv.vval.v_number
+#define vv_float vv_di.di_tv.vval.v_float
+#define vv_str vv_di.di_tv.vval.v_string
+#define vv_list vv_di.di_tv.vval.v_list
+#define vv_tv vv_di.di_tv
+
+static dictitem_T vimvars_var; /* variable used for v: */
+#define vimvarht vimvardict.dv_hashtab
+
+static void prepare_vimvar __ARGS((int idx, typval_T *save_tv));
+static void restore_vimvar __ARGS((int idx, typval_T *save_tv));
+static int ex_let_vars __ARGS((char_u *arg, typval_T *tv, int copy,
+ int semicolon, int var_count,
+ char_u *nextchars));
+static char_u *skip_var_list __ARGS((char_u *arg, int *var_count,
+ int *semicolon));
+static char_u *skip_var_one __ARGS((char_u *arg));
+static void list_hashtable_vars __ARGS((hashtab_T *ht, char_u *prefix,
+ int empty,
+ int *first));
+static void list_glob_vars __ARGS((int *first));
+static void list_buf_vars __ARGS((int *first));
+static void list_win_vars __ARGS((int *first));
+static void list_tab_vars __ARGS((int *first));
+static void list_vim_vars __ARGS((int *first));
+static void list_script_vars __ARGS((int *first));
+static void list_func_vars __ARGS((int *first));
+static char_u *list_arg_vars __ARGS((exarg_T *eap, char_u *arg, int *first));
+static char_u *ex_let_one __ARGS((char_u *arg, typval_T *tv, int copy, char_u *
+ endchars,
+ char_u *op));
+static int check_changedtick __ARGS((char_u *arg));
+static char_u *get_lval __ARGS((char_u *name, typval_T *rettv, lval_T *lp,
+ int unlet, int skip, int flags,
+ int fne_flags));
+static void clear_lval __ARGS((lval_T *lp));
+static void set_var_lval __ARGS((lval_T *lp, char_u *endp, typval_T *rettv,
+ int copy,
+ char_u *op));
+static int tv_op __ARGS((typval_T *tv1, typval_T *tv2, char_u *op));
+static void list_fix_watch __ARGS((list_T *l, listitem_T *item));
+static void ex_unletlock __ARGS((exarg_T *eap, char_u *argstart, int deep));
+static int do_unlet_var __ARGS((lval_T *lp, char_u *name_end, int forceit));
+static int do_lock_var __ARGS((lval_T *lp, char_u *name_end, int deep, int lock));
+static void item_lock __ARGS((typval_T *tv, int deep, int lock));
+static int tv_islocked __ARGS((typval_T *tv));
+
+static int eval0 __ARGS((char_u *arg, typval_T *rettv, char_u **nextcmd,
+ int evaluate));
+static int eval1 __ARGS((char_u **arg, typval_T *rettv, int evaluate));
+static int eval2 __ARGS((char_u **arg, typval_T *rettv, int evaluate));
+static int eval3 __ARGS((char_u **arg, typval_T *rettv, int evaluate));
+static int eval4 __ARGS((char_u **arg, typval_T *rettv, int evaluate));
+static int eval5 __ARGS((char_u **arg, typval_T *rettv, int evaluate));
+static int eval6 __ARGS((char_u **arg, typval_T *rettv, int evaluate,
+ int want_string));
+static int eval7 __ARGS((char_u **arg, typval_T *rettv, int evaluate,
+ int want_string));
+
+static int eval_index __ARGS((char_u **arg, typval_T *rettv, int evaluate,
+ int verbose));
+static int get_option_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate));
+static int get_string_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate));
+static int get_lit_string_tv __ARGS((char_u **arg, typval_T *rettv,
+ int evaluate));
+static int get_list_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate));
+static int rettv_list_alloc __ARGS((typval_T *rettv));
+static long list_len __ARGS((list_T *l));
+static int list_equal __ARGS((list_T *l1, list_T *l2, int ic, int recursive));
+static int dict_equal __ARGS((dict_T *d1, dict_T *d2, int ic, int recursive));
+static int tv_equal __ARGS((typval_T *tv1, typval_T *tv2, int ic, int recursive));
+static long list_find_nr __ARGS((list_T *l, long idx, int *errorp));
+static long list_idx_of_item __ARGS((list_T *l, listitem_T *item));
+static int list_append_number __ARGS((list_T *l, varnumber_T n));
+static int list_extend __ARGS((list_T *l1, list_T *l2, listitem_T *bef));
+static int list_concat __ARGS((list_T *l1, list_T *l2, typval_T *tv));
+static list_T *list_copy __ARGS((list_T *orig, int deep, int copyID));
+static char_u *list2string __ARGS((typval_T *tv, int copyID));
+static int list_join_inner __ARGS((garray_T *gap, list_T *l, char_u *sep,
+ int echo_style, int copyID,
+ garray_T *join_gap));
+static int list_join __ARGS((garray_T *gap, list_T *l, char_u *sep, int echo,
+ int copyID));
+static int free_unref_items __ARGS((int copyID));
+static int rettv_dict_alloc __ARGS((typval_T *rettv));
+static dictitem_T *dictitem_copy __ARGS((dictitem_T *org));
+static void dictitem_remove __ARGS((dict_T *dict, dictitem_T *item));
+static dict_T *dict_copy __ARGS((dict_T *orig, int deep, int copyID));
+static long dict_len __ARGS((dict_T *d));
+static char_u *dict2string __ARGS((typval_T *tv, int copyID));
+static int get_dict_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate));
+static char_u *echo_string __ARGS((typval_T *tv, char_u **tofree, char_u *
+ numbuf,
+ int copyID));
+static char_u *tv2string __ARGS((typval_T *tv, char_u **tofree, char_u *numbuf,
+ int copyID));
+static char_u *string_quote __ARGS((char_u *str, int function));
+static int string2float __ARGS((char_u *text, float_T *value));
+static int get_env_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate));
+static int find_internal_func __ARGS((char_u *name));
+static char_u *deref_func_name __ARGS((char_u *name, int *lenp, int no_autoload));
+static int get_func_tv __ARGS((char_u *name, int len, typval_T *rettv, char_u *
+ *arg, linenr_T firstline, linenr_T lastline,
+ int *doesrange, int evaluate,
+ dict_T *selfdict));
+static int call_func __ARGS((char_u *funcname, int len, typval_T *rettv,
+ int argcount, typval_T *argvars,
+ linenr_T firstline, linenr_T lastline,
+ int *doesrange, int evaluate,
+ dict_T *selfdict));
+static void emsg_funcname __ARGS((char *ermsg, char_u *name));
+static int non_zero_arg __ARGS((typval_T *argvars));
+
+static void f_abs __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_acos __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_add __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_and __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_append __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_argc __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_argidx __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_argv __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_asin __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_atan __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_atan2 __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_browse __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_browsedir __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_bufexists __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_buflisted __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_bufloaded __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_bufname __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_bufnr __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_bufwinnr __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_byte2line __ARGS((typval_T *argvars, typval_T *rettv));
+static void byteidx __ARGS((typval_T *argvars, typval_T *rettv, int comp));
+static void f_byteidx __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_byteidxcomp __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_call __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_ceil __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_changenr __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_char2nr __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_cindent __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_clearmatches __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_col __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_complete __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_complete_add __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_complete_check __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_confirm __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_copy __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_cos __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_cosh __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_count __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_cscope_connection __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_cursor __ARGS((typval_T *argsvars, typval_T *rettv));
+static void f_deepcopy __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_delete __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_did_filetype __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_diff_filler __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_diff_hlID __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_empty __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_escape __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_eval __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_eventhandler __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_executable __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_exists __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_exp __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_expand __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_extend __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_feedkeys __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_filereadable __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_filewritable __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_filter __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_finddir __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_findfile __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_float2nr __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_floor __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_fmod __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_fnameescape __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_fnamemodify __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_foldclosed __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_foldclosedend __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_foldlevel __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_foldtext __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_foldtextresult __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_foreground __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_function __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_garbagecollect __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_get __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_getbufline __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_getbufvar __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_getchar __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_getcharmod __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_getcmdline __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_getcmdpos __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_getcmdtype __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_getcwd __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_getfontname __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_getfperm __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_getfsize __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_getftime __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_getftype __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_getline __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_getmatches __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_getpid __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_getpos __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_getqflist __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_getreg __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_getregtype __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_gettabvar __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_gettabwinvar __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_getwinposx __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_getwinposy __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_getwinvar __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_glob __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_globpath __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_has __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_has_key __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_haslocaldir __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_hasmapto __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_histadd __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_histdel __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_histget __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_histnr __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_hlID __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_hlexists __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_hostname __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_iconv __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_indent __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_index __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_input __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_inputdialog __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_inputlist __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_inputrestore __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_inputsave __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_inputsecret __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_insert __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_invert __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_isdirectory __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_islocked __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_items __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_join __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_keys __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_last_buffer_nr __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_len __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_libcall __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_libcallnr __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_line __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_line2byte __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_lispindent __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_localtime __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_log __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_log10 __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_map __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_maparg __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_mapcheck __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_match __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_matchadd __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_matcharg __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_matchdelete __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_matchend __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_matchlist __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_matchstr __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_max __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_min __ARGS((typval_T *argvars, typval_T *rettv));
+#ifdef vim_mkdir
+static void f_mkdir __ARGS((typval_T *argvars, typval_T *rettv));
+#endif
+static void f_mode __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_nextnonblank __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_nr2char __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_or __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_pathshorten __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_pow __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_prevnonblank __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_printf __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_pumvisible __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_range __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_readfile __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_reltime __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_reltimestr __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_remote_expr __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_remote_foreground __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_remote_peek __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_remote_read __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_remote_send __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_remove __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_rename __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_repeat __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_resolve __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_reverse __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_round __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_screenattr __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_screenchar __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_screencol __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_screenrow __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_search __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_searchdecl __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_searchpair __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_searchpairpos __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_searchpos __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_server2client __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_serverlist __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_setbufvar __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_setcmdpos __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_setline __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_setloclist __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_setmatches __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_setpos __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_setqflist __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_setreg __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_settabvar __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_settabwinvar __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_setwinvar __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_sha256 __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_shellescape __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_shiftwidth __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_simplify __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_sin __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_sinh __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_sort __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_soundfold __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_spellbadword __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_spellsuggest __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_split __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_sqrt __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_str2float __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_str2nr __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_strchars __ARGS((typval_T *argvars, typval_T *rettv));
+#ifdef HAVE_STRFTIME
+static void f_strftime __ARGS((typval_T *argvars, typval_T *rettv));
+#endif
+static void f_stridx __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_string __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_strlen __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_strpart __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_strridx __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_strtrans __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_strdisplaywidth __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_strwidth __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_submatch __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_substitute __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_synID __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_synIDattr __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_synIDtrans __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_synstack __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_synconcealed __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_system __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_tabpagebuflist __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_tabpagenr __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_tabpagewinnr __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_taglist __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_tagfiles __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_tempname __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_test __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_tan __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_tanh __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_tolower __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_toupper __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_tr __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_trunc __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_type __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_undofile __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_undotree __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_values __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_virtcol __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_visualmode __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_wildmenumode __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_winbufnr __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_wincol __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_winheight __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_winline __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_winnr __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_winrestcmd __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_winrestview __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_winsaveview __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_winwidth __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_writefile __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_xor __ARGS((typval_T *argvars, typval_T *rettv));
+
+static int list2fpos __ARGS((typval_T *arg, pos_T *posp, int *fnump));
+static pos_T *var2fpos __ARGS((typval_T *varp, int dollar_lnum, int *fnum));
+static int get_env_len __ARGS((char_u **arg));
+static int get_id_len __ARGS((char_u **arg));
+static int get_name_len __ARGS((char_u **arg, char_u **alias, int evaluate,
+ int verbose));
+static char_u *find_name_end __ARGS((char_u *arg, char_u **expr_start, char_u *
+ *expr_end,
+ int flags));
+#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 char_u *
+make_expanded_name __ARGS((char_u *in_start, char_u *expr_start, char_u *
+ expr_end,
+ char_u *in_end));
+static int eval_isnamec __ARGS((int c));
+static int eval_isnamec1 __ARGS((int c));
+static int get_var_tv __ARGS((char_u *name, int len, typval_T *rettv,
+ int verbose,
+ int no_autoload));
+static int handle_subscript __ARGS((char_u **arg, typval_T *rettv, int evaluate,
+ int verbose));
+static typval_T *alloc_tv __ARGS((void));
+static typval_T *alloc_string_tv __ARGS((char_u *string));
+static void init_tv __ARGS((typval_T *varp));
+static long get_tv_number __ARGS((typval_T *varp));
+static linenr_T get_tv_lnum __ARGS((typval_T *argvars));
+static linenr_T get_tv_lnum_buf __ARGS((typval_T *argvars, buf_T *buf));
+static char_u *get_tv_string __ARGS((typval_T *varp));
+static char_u *get_tv_string_buf __ARGS((typval_T *varp, char_u *buf));
+static char_u *get_tv_string_buf_chk __ARGS((typval_T *varp, char_u *buf));
+static dictitem_T *find_var __ARGS((char_u *name, hashtab_T **htp,
+ int no_autoload));
+static dictitem_T *find_var_in_ht __ARGS((hashtab_T *ht, int htname, char_u *
+ varname,
+ int no_autoload));
+static hashtab_T *find_var_ht __ARGS((char_u *name, char_u **varname));
+static void vars_clear_ext __ARGS((hashtab_T *ht, int free_val));
+static void delete_var __ARGS((hashtab_T *ht, hashitem_T *hi));
+static void list_one_var __ARGS((dictitem_T *v, char_u *prefix, int *first));
+static void list_one_var_a __ARGS((char_u *prefix, char_u *name, int type,
+ char_u *string,
+ int *first));
+static void set_var __ARGS((char_u *name, typval_T *varp, int copy));
+static int var_check_ro __ARGS((int flags, char_u *name));
+static int var_check_fixed __ARGS((int flags, char_u *name));
+static int var_check_func_name __ARGS((char_u *name, int new_var));
+static int valid_varname __ARGS((char_u *varname));
+static int tv_check_lock __ARGS((int lock, char_u *name));
+static int item_copy __ARGS((typval_T *from, typval_T *to, int deep, int copyID));
+static char_u *find_option_end __ARGS((char_u **arg, int *opt_flags));
+static char_u *trans_function_name __ARGS((char_u **pp, int skip, int flags,
+ funcdict_T *fd));
+static int eval_fname_script __ARGS((char_u *p));
+static int eval_fname_sid __ARGS((char_u *p));
+static void list_func_head __ARGS((ufunc_T *fp, int indent));
+static ufunc_T *find_func __ARGS((char_u *name));
+static int function_exists __ARGS((char_u *name));
+static int builtin_function __ARGS((char_u *name));
+static void func_do_profile __ARGS((ufunc_T *fp));
+static void prof_sort_list __ARGS((FILE *fd, ufunc_T **sorttab, int st_len,
+ char *title,
+ int prefer_self));
+static void prof_func_line __ARGS((FILE *fd, int count, proftime_T *total,
+ proftime_T *self,
+ int prefer_self));
+static int
+prof_total_cmp __ARGS((const void *s1, const void *s2));
+static int
+prof_self_cmp __ARGS((const void *s1, const void *s2));
+static int script_autoload __ARGS((char_u *name, int reload));
+static char_u *autoload_name __ARGS((char_u *name));
+static void cat_func_name __ARGS((char_u *buf, ufunc_T *fp));
+static void func_free __ARGS((ufunc_T *fp));
+static void call_user_func __ARGS((ufunc_T *fp, int argcount, typval_T *argvars,
+ typval_T *rettv, linenr_T firstline,
+ linenr_T lastline,
+ dict_T *selfdict));
+static int can_free_funccal __ARGS((funccall_T *fc, int copyID));
+static void free_funccal __ARGS((funccall_T *fc, int free_val));
+static void add_nr_var __ARGS((dict_T *dp, dictitem_T *v, char *name,
+ varnumber_T nr));
+static win_T *find_win_by_nr __ARGS((typval_T *vp, tabpage_T *tp));
+static void getwinvar __ARGS((typval_T *argvars, typval_T *rettv, int off));
+static int searchpair_cmn __ARGS((typval_T *argvars, pos_T *match_pos));
+static int search_cmn __ARGS((typval_T *argvars, pos_T *match_pos, int *flagsp));
+static void setwinvar __ARGS((typval_T *argvars, typval_T *rettv, int off));
+
+
+
+/*
+ * Initialize the global and v: variables.
+ */
+void eval_init() {
+ int i;
+ struct vimvar *p;
+
+ init_var_dict(&globvardict, &globvars_var, VAR_DEF_SCOPE);
+ init_var_dict(&vimvardict, &vimvars_var, VAR_SCOPE);
+ vimvardict.dv_lock = VAR_FIXED;
+ hash_init(&compat_hashtab);
+ hash_init(&func_hashtab);
+
+ for (i = 0; i < VV_LEN; ++i) {
+ p = &vimvars[i];
+ 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;
+ else if (p->vv_flags & VV_RO_SBX)
+ p->vv_di.di_flags = DI_FLAGS_RO_SBX | DI_FLAGS_FIX;
+ else
+ p->vv_di.di_flags = DI_FLAGS_FIX;
+
+ /* add to v: scope dict, unless the value is not always available */
+ if (p->vv_type != VAR_UNKNOWN)
+ hash_add(&vimvarht, p->vv_di.di_key);
+ if (p->vv_flags & VV_COMPAT)
+ /* add to compat scope dict */
+ hash_add(&compat_hashtab, p->vv_di.di_key);
+ }
+ set_vim_var_nr(VV_SEARCHFORWARD, 1L);
+ set_vim_var_nr(VV_HLSEARCH, 1L);
+ set_reg_var(0); /* default for v:register is not 0 but '"' */
+
+}
+
+#if defined(EXITFREE) || defined(PROTO)
+void eval_clear() {
+ int i;
+ struct vimvar *p;
+
+ for (i = 0; i < VV_LEN; ++i) {
+ p = &vimvars[i];
+ if (p->vv_di.di_tv.v_type == VAR_STRING) {
+ vim_free(p->vv_str);
+ p->vv_str = NULL;
+ } else if (p->vv_di.di_tv.v_type == VAR_LIST) {
+ list_unref(p->vv_list);
+ p->vv_list = NULL;
+ }
+ }
+ hash_clear(&vimvarht);
+ hash_init(&vimvarht); /* garbage_collect() will access it */
+ hash_clear(&compat_hashtab);
+
+ free_scriptnames();
+ free_locales();
+
+ /* global variables */
+ vars_clear(&globvarht);
+
+ /* autoloaded script names */
+ ga_clear_strings(&ga_loaded);
+
+ /* Script-local variables. First clear all the variables and in a second
+ * loop free the scriptvar_T, because a variable in one script might hold
+ * a reference to the whole scope of another script. */
+ for (i = 1; i <= ga_scripts.ga_len; ++i)
+ vars_clear(&SCRIPT_VARS(i));
+ for (i = 1; i <= ga_scripts.ga_len; ++i)
+ vim_free(SCRIPT_SV(i));
+ ga_clear(&ga_scripts);
+
+ /* unreferenced lists and dicts */
+ (void)garbage_collect();
+
+ /* functions */
+ free_all_functions();
+ hash_clear(&func_hashtab);
+}
+
+#endif
+
+/*
+ * Return the name of the executed function.
+ */
+char_u * func_name(cookie)
+void *cookie;
+{
+ return ((funccall_T *)cookie)->func->uf_name;
+}
+
+/*
+ * Return the address holding the next breakpoint line for a funccall cookie.
+ */
+linenr_T * func_breakpoint(cookie)
+void *cookie;
+{
+ return &((funccall_T *)cookie)->breakpoint;
+}
+
+/*
+ * Return the address holding the debug tick for a funccall cookie.
+ */
+int * func_dbg_tick(cookie)
+void *cookie;
+{
+ return &((funccall_T *)cookie)->dbg_tick;
+}
+
+/*
+ * Return the nesting level for a funccall cookie.
+ */
+int func_level(cookie)
+void *cookie;
+{
+ return ((funccall_T *)cookie)->level;
+}
+
+/* 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. */
+funccall_T *previous_funccal = NULL;
+
+/*
+ * Return TRUE when a function was ended by a ":return" command.
+ */
+int current_func_returned() {
+ return current_funccal->returned;
+}
+
+/*
+ * Set an internal variable to a string value. Creates the variable if it does
+ * not already exist.
+ */
+void set_internal_string_var(name, value)
+char_u *name;
+char_u *value;
+{
+ char_u *val;
+ typval_T *tvp;
+
+ val = vim_strsave(value);
+ if (val != NULL) {
+ tvp = alloc_string_tv(val);
+ if (tvp != NULL) {
+ set_var(name, tvp, FALSE);
+ free_tv(tvp);
+ }
+ }
+}
+
+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 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(name, append)
+char_u *name;
+int append; /* append to an existing variable */
+{
+ int save_emsg;
+ int err;
+ typval_T tv;
+
+ /* Catch a bad name early. */
+ if (!eval_isnamec1(*name)) {
+ EMSG(_(e_invarg));
+ return FAIL;
+ }
+
+ /* Make a copy of the name, it is used in redir_lval until redir ends. */
+ redir_varname = vim_strsave(name);
+ if (redir_varname == NULL)
+ return FAIL;
+
+ redir_lval = (lval_T *)alloc_clear((unsigned)sizeof(lval_T));
+ if (redir_lval == NULL) {
+ var_redir_stop();
+ return FAIL;
+ }
+
+ /* The output is stored in growarray "redir_ga" until redirection ends. */
+ ga_init2(&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) {
+ clear_lval(redir_lval);
+ if (redir_endp != NULL && *redir_endp != NUL)
+ /* Trailing characters are present after the variable name */
+ EMSG(_(e_trailing));
+ else
+ EMSG(_(e_invarg));
+ redir_endp = NULL; /* don't store a value, only cleanup */
+ var_redir_stop();
+ return FAIL;
+ }
+
+ /* check if we can write to the variable: set it to or append an empty
+ * string */
+ save_emsg = did_emsg;
+ did_emsg = FALSE;
+ tv.v_type = VAR_STRING;
+ tv.vval.v_string = (char_u *)"";
+ if (append)
+ set_var_lval(redir_lval, redir_endp, &tv, TRUE, (char_u *)".");
+ else
+ set_var_lval(redir_lval, redir_endp, &tv, TRUE, (char_u *)"=");
+ clear_lval(redir_lval);
+ err = did_emsg;
+ did_emsg |= save_emsg;
+ if (err) {
+ redir_endp = NULL; /* don't store a value, only cleanup */
+ var_redir_stop();
+ return FAIL;
+ }
+
+ return OK;
+}
+
+/*
+ * Append "value[value_len]" to the variable set by var_redir_start().
+ * The actual appending is postponed until redirection ends, because the value
+ * appended may in fact be the string we write to, changing it may cause freed
+ * memory to be used:
+ * :redir => foo
+ * :let foo
+ * :redir END
+ */
+void var_redir_str(value, value_len)
+char_u *value;
+int value_len;
+{
+ int len;
+
+ if (redir_lval == NULL)
+ return;
+
+ if (value_len == -1)
+ len = (int)STRLEN(value); /* Append the entire string */
+ else
+ len = value_len; /* Append only "value_len" characters */
+
+ if (ga_grow(&redir_ga, len) == OK) {
+ mch_memmove((char *)redir_ga.ga_data + redir_ga.ga_len, value, len);
+ redir_ga.ga_len += len;
+ } else
+ var_redir_stop();
+}
+
+/*
+ * Stop redirecting command output to a variable.
+ * Frees the allocated memory.
+ */
+void var_redir_stop() {
+ typval_T tv;
+
+ if (redir_lval != NULL) {
+ /* If there was no error: assign the text to the variable. */
+ if (redir_endp != NULL) {
+ 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 *)".");
+ clear_lval(redir_lval);
+ }
+
+ /* free the collected output */
+ vim_free(redir_ga.ga_data);
+ redir_ga.ga_data = NULL;
+
+ vim_free(redir_lval);
+ redir_lval = NULL;
+ }
+ vim_free(redir_varname);
+ redir_varname = NULL;
+}
+
+int eval_charconvert(enc_from, enc_to, fname_from, fname_to)
+char_u *enc_from;
+char_u *enc_to;
+char_u *fname_from;
+char_u *fname_to;
+{
+ int err = FALSE;
+
+ set_vim_var_string(VV_CC_FROM, enc_from, -1);
+ set_vim_var_string(VV_CC_TO, enc_to, -1);
+ set_vim_var_string(VV_FNAME_IN, fname_from, -1);
+ set_vim_var_string(VV_FNAME_OUT, fname_to, -1);
+ if (eval_to_bool(p_ccv, &err, NULL, FALSE))
+ err = TRUE;
+ set_vim_var_string(VV_CC_FROM, NULL, -1);
+ set_vim_var_string(VV_CC_TO, NULL, -1);
+ set_vim_var_string(VV_FNAME_IN, NULL, -1);
+ set_vim_var_string(VV_FNAME_OUT, NULL, -1);
+
+ if (err)
+ return FAIL;
+ return OK;
+}
+
+int eval_printexpr(fname, args)
+char_u *fname;
+char_u *args;
+{
+ int err = FALSE;
+
+ set_vim_var_string(VV_FNAME_IN, fname, -1);
+ set_vim_var_string(VV_CMDARG, args, -1);
+ if (eval_to_bool(p_pexpr, &err, NULL, FALSE))
+ err = TRUE;
+ set_vim_var_string(VV_FNAME_IN, NULL, -1);
+ set_vim_var_string(VV_CMDARG, NULL, -1);
+
+ if (err) {
+ mch_remove(fname);
+ return FAIL;
+ }
+ return OK;
+}
+
+void eval_diff(origfile, newfile, outfile)
+char_u *origfile;
+char_u *newfile;
+char_u *outfile;
+{
+ int err = FALSE;
+
+ set_vim_var_string(VV_FNAME_IN, origfile, -1);
+ set_vim_var_string(VV_FNAME_NEW, newfile, -1);
+ set_vim_var_string(VV_FNAME_OUT, outfile, -1);
+ (void)eval_to_bool(p_dex, &err, NULL, FALSE);
+ set_vim_var_string(VV_FNAME_IN, NULL, -1);
+ set_vim_var_string(VV_FNAME_NEW, NULL, -1);
+ set_vim_var_string(VV_FNAME_OUT, NULL, -1);
+}
+
+void eval_patch(origfile, difffile, outfile)
+char_u *origfile;
+char_u *difffile;
+char_u *outfile;
+{
+ int err;
+
+ set_vim_var_string(VV_FNAME_IN, origfile, -1);
+ set_vim_var_string(VV_FNAME_DIFF, difffile, -1);
+ set_vim_var_string(VV_FNAME_OUT, outfile, -1);
+ (void)eval_to_bool(p_pex, &err, NULL, FALSE);
+ set_vim_var_string(VV_FNAME_IN, NULL, -1);
+ set_vim_var_string(VV_FNAME_DIFF, NULL, -1);
+ set_vim_var_string(VV_FNAME_OUT, NULL, -1);
+}
+
+/*
+ * Top level evaluation function, returning a boolean.
+ * Sets "error" to TRUE if there was an error.
+ * Return TRUE or FALSE.
+ */
+int eval_to_bool(arg, error, nextcmd, skip)
+char_u *arg;
+int *error;
+char_u **nextcmd;
+int skip; /* only parse, don't execute */
+{
+ typval_T tv;
+ int retval = 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);
+ }
+ }
+ 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(arg, nextcmd, skip)
+char_u *arg;
+char_u **nextcmd;
+int skip; /* only parse, don't execute */
+{
+ typval_T tv;
+ char_u *retval;
+
+ if (skip)
+ ++emsg_skip;
+ if (eval0(arg, &tv, nextcmd, !skip) == FAIL || skip)
+ retval = NULL;
+ else {
+ retval = vim_strsave(get_tv_string(&tv));
+ clear_tv(&tv);
+ }
+ if (skip)
+ --emsg_skip;
+
+ return retval;
+}
+
+/*
+ * Skip over an expression at "*pp".
+ * Return FAIL for an error, OK otherwise.
+ */
+int skip_expr(pp)
+char_u **pp;
+{
+ typval_T rettv;
+
+ *pp = skipwhite(*pp);
+ return eval1(pp, &rettv, FALSE);
+}
+
+/*
+ * Top level evaluation function, returning a string.
+ * When "convert" is TRUE convert a List into a sequence of lines and convert
+ * a Float to a String.
+ * Return pointer to allocated memory, or NULL for failure.
+ */
+char_u * eval_to_string(arg, nextcmd, convert)
+char_u *arg;
+char_u **nextcmd;
+int convert;
+{
+ typval_T tv;
+ char_u *retval;
+ garray_T ga;
+ char_u numbuf[NUMBUFLEN];
+
+ if (eval0(arg, &tv, nextcmd, TRUE) == FAIL)
+ retval = NULL;
+ else {
+ if (convert && tv.v_type == VAR_LIST) {
+ ga_init2(&ga, (int)sizeof(char), 80);
+ if (tv.vval.v_list != NULL) {
+ list_join(&ga, tv.vval.v_list, (char_u *)"\n", TRUE, 0);
+ if (tv.vval.v_list->lv_len > 0)
+ ga_append(&ga, NL);
+ }
+ ga_append(&ga, NUL);
+ retval = (char_u *)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);
+ }
+
+ return retval;
+}
+
+/*
+ * Call eval_to_string() without using current local variables and using
+ * textlock. When "use_sandbox" is TRUE use the sandbox.
+ */
+char_u * eval_to_string_safe(arg, nextcmd, use_sandbox)
+char_u *arg;
+char_u **nextcmd;
+int use_sandbox;
+{
+ char_u *retval;
+ void *save_funccalp;
+
+ save_funccalp = save_funccal();
+ if (use_sandbox)
+ ++sandbox;
+ ++textlock;
+ retval = eval_to_string(arg, nextcmd, FALSE);
+ if (use_sandbox)
+ --sandbox;
+ --textlock;
+ restore_funccal(save_funccalp);
+ return retval;
+}
+
+/*
+ * Top level evaluation function, returning a number.
+ * Evaluates "expr" silently.
+ * Returns -1 for an error.
+ */
+int eval_to_number(expr)
+char_u *expr;
+{
+ typval_T rettv;
+ int retval;
+ char_u *p = skipwhite(expr);
+
+ ++emsg_off;
+
+ if (eval1(&p, &rettv, TRUE) == FAIL)
+ retval = -1;
+ else {
+ retval = get_tv_number_chk(&rettv, NULL);
+ clear_tv(&rettv);
+ }
+ --emsg_off;
+
+ return retval;
+}
+
+/*
+ * Prepare v: variable "idx" to be used.
+ * Save the current typeval in "save_tv".
+ * When not used yet add the variable to the v: hashtable.
+ */
+static void prepare_vimvar(idx, save_tv)
+int idx;
+typval_T *save_tv;
+{
+ *save_tv = vimvars[idx].vv_tv;
+ if (vimvars[idx].vv_type == VAR_UNKNOWN)
+ hash_add(&vimvarht, vimvars[idx].vv_di.di_key);
+}
+
+/*
+ * Restore v: variable "idx" to typeval "save_tv".
+ * When no longer defined, remove the variable from the v: hashtable.
+ */
+static void restore_vimvar(idx, save_tv)
+int idx;
+typval_T *save_tv;
+{
+ hashitem_T *hi;
+
+ 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
+ hash_remove(&vimvarht, hi);
+ }
+}
+
+/*
+ * Evaluate an expression to a list with suggestions.
+ * For the "expr:" part of 'spellsuggest'.
+ * Returns NULL when there is an error.
+ */
+list_T * eval_spell_expr(badword, expr)
+char_u *badword;
+char_u *expr;
+{
+ typval_T save_val;
+ typval_T rettv;
+ list_T *list = NULL;
+ char_u *p = skipwhite(expr);
+
+ /* Set "v:val" to the bad word. */
+ prepare_vimvar(VV_VAL, &save_val);
+ vimvars[VV_VAL].vv_type = VAR_STRING;
+ vimvars[VV_VAL].vv_str = badword;
+ if (p_verbose == 0)
+ ++emsg_off;
+
+ if (eval1(&p, &rettv, TRUE) == OK) {
+ if (rettv.v_type != VAR_LIST)
+ clear_tv(&rettv);
+ else
+ list = rettv.vval.v_list;
+ }
+
+ if (p_verbose == 0)
+ --emsg_off;
+ restore_vimvar(VV_VAL, &save_val);
+
+ 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, pp)
+list_T *list;
+char_u **pp;
+{
+ listitem_T *li;
+
+ li = list->lv_first;
+ if (li == NULL)
+ return -1;
+ *pp = get_tv_string(&li->li_tv);
+
+ li = li->li_next;
+ if (li == 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(arg, nextcmd)
+char_u *arg;
+char_u **nextcmd;
+{
+ typval_T *tv;
+
+ tv = (typval_T *)alloc(sizeof(typval_T));
+ if (tv != NULL && eval0(arg, tv, nextcmd, TRUE) == FAIL) {
+ vim_free(tv);
+ tv = NULL;
+ }
+
+ return tv;
+}
+
+
+/*
+ * Call some vimL function and return the result in "*rettv".
+ * Uses argv[argc] for the function arguments. Only Number and String
+ * arguments are currently supported.
+ * Returns OK or FAIL.
+ */
+int call_vim_function(func, argc, argv, safe, str_arg_only, rettv)
+char_u *func;
+int argc;
+char_u **argv;
+int safe; /* use the sandbox */
+int str_arg_only; /* all arguments are strings */
+typval_T *rettv;
+{
+ typval_T *argvars;
+ long n;
+ int len;
+ int i;
+ int doesrange;
+ void *save_funccalp = NULL;
+ int ret;
+
+ argvars = (typval_T *)alloc((unsigned)((argc + 1) * sizeof(typval_T)));
+ if (argvars == NULL)
+ return FAIL;
+
+ for (i = 0; i < argc; i++) {
+ /* Pass a NULL or empty argument as an empty string */
+ if (argv[i] == NULL || *argv[i] == NUL) {
+ argvars[i].v_type = VAR_STRING;
+ argvars[i].vval.v_string = (char_u *)"";
+ continue;
+ }
+
+ if (str_arg_only)
+ len = 0;
+ else
+ /* Recognize a number argument, the others must be strings. */
+ vim_str2nr(argv[i], NULL, &len, TRUE, TRUE, &n, NULL);
+ 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];
+ }
+ }
+
+ if (safe) {
+ save_funccalp = save_funccal();
+ ++sandbox;
+ }
+
+ rettv->v_type = VAR_UNKNOWN; /* clear_tv() uses this */
+ ret = call_func(func, (int)STRLEN(func), rettv, argc, argvars,
+ curwin->w_cursor.lnum, curwin->w_cursor.lnum,
+ &doesrange, TRUE, NULL);
+ if (safe) {
+ --sandbox;
+ restore_funccal(save_funccalp);
+ }
+ vim_free(argvars);
+
+ if (ret == FAIL)
+ clear_tv(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(func, argc, argv, safe)
+char_u *func;
+int argc;
+char_u **argv;
+int safe; /* use the sandbox */
+{
+ typval_T rettv;
+ long 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);
+ return retval;
+}
+
+#if (defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL)) \
+ || defined(FEAT_COMPL_FUNC) || defined(PROTO)
+
+/*
+ * 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(func, argc, argv, safe)
+char_u *func;
+int argc;
+char_u **argv;
+int safe; /* use the sandbox */
+{
+ 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)
+ return NULL;
+
+ retval = vim_strsave(get_tv_string(&rettv));
+ clear_tv(&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(func, argc, argv, safe)
+char_u *func;
+int argc;
+char_u **argv;
+int safe; /* use the sandbox */
+{
+ typval_T rettv;
+
+ /* All arguments are passed as strings, no conversion to number. */
+ if (call_vim_function(func, argc, argv, safe, TRUE, &rettv) == FAIL)
+ return NULL;
+
+ if (rettv.v_type != VAR_LIST) {
+ clear_tv(&rettv);
+ return NULL;
+ }
+
+ return rettv.vval.v_list;
+}
+#endif
+
+/*
+ * Save the current function call pointer, and set it to NULL.
+ * Used when executing autocommands and for ":source".
+ */
+void * save_funccal() {
+ funccall_T *fc = current_funccal;
+
+ current_funccal = NULL;
+ return (void *)fc;
+}
+
+void restore_funccal(vfc)
+void *vfc;
+{
+ funccall_T *fc = (funccall_T *)vfc;
+
+ current_funccal = fc;
+}
+
+/*
+ * Prepare profiling for entering a child or something else that is not
+ * counted for the script/function itself.
+ * Should always be called in pair with prof_child_exit().
+ */
+void prof_child_enter(tm)
+proftime_T *tm; /* place to store waittime */
+{
+ funccall_T *fc = current_funccal;
+
+ if (fc != NULL && fc->func->uf_profiling)
+ profile_start(&fc->prof_child);
+ script_prof_save(tm);
+}
+
+/*
+ * Take care of time spent in a child.
+ * Should always be called after prof_child_enter().
+ */
+void prof_child_exit(tm)
+proftime_T *tm; /* where waittime was stored */
+{
+ funccall_T *fc = current_funccal;
+
+ if (fc != NULL && fc->func->uf_profiling) {
+ profile_end(&fc->prof_child);
+ profile_sub_wait(tm, &fc->prof_child); /* don't count waiting time */
+ profile_add(&fc->func->uf_tm_children, &fc->prof_child);
+ profile_add(&fc->func->uf_tml_children, &fc->prof_child);
+ }
+ script_prof_restore(tm);
+}
+
+
+/*
+ * Evaluate 'foldexpr'. Returns the foldlevel, and any character preceding
+ * it in "*cp". Doesn't give error messages.
+ */
+int eval_foldexpr(arg, cp)
+char_u *arg;
+int *cp;
+{
+ typval_T tv;
+ int retval;
+ char_u *s;
+ int use_sandbox = was_set_insecurely((char_u *)"foldexpr",
+ OPT_LOCAL);
+
+ ++emsg_off;
+ if (use_sandbox)
+ ++sandbox;
+ ++textlock;
+ *cp = NUL;
+ if (eval0(arg, &tv, NULL, TRUE) == FAIL)
+ retval = 0;
+ else {
+ /* If the result is a number, just return the number. */
+ if (tv.v_type == VAR_NUMBER)
+ retval = tv.vval.v_number;
+ else if (tv.v_type != VAR_STRING || tv.vval.v_string == NULL)
+ retval = 0;
+ else {
+ /* If the result is a string, check if there is a non-digit before
+ * the number. */
+ s = tv.vval.v_string;
+ if (!VIM_ISDIGIT(*s) && *s != '-')
+ *cp = *s++;
+ retval = atol((char *)s);
+ }
+ clear_tv(&tv);
+ }
+ --emsg_off;
+ if (use_sandbox)
+ --sandbox;
+ --textlock;
+
+ return retval;
+}
+
+/*
+ * ":let" list all variable values
+ * ":let var1 var2" list variable values
+ * ":let var = expr" assignment command.
+ * ":let var += expr" assignment command.
+ * ":let var -= expr" assignment command.
+ * ":let var .= expr" assignment command.
+ * ":let [var1, var2] = expr" unpack list.
+ */
+void ex_let(eap)
+exarg_T *eap;
+{
+ char_u *arg = eap->arg;
+ char_u *expr = NULL;
+ typval_T rettv;
+ int i;
+ int var_count = 0;
+ int semicolon = 0;
+ char_u op[2];
+ char_u *argend;
+ int first = TRUE;
+
+ argend = skip_var_list(arg, &var_count, &semicolon);
+ if (argend == NULL)
+ return;
+ if (argend > arg && argend[-1] == '.') /* for var.='str' */
+ --argend;
+ expr = vim_strchr(argend, '=');
+ if (expr == NULL) {
+ /*
+ * ":let" without "=": list variables
+ */
+ 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" */
+ list_glob_vars(&first);
+ list_buf_vars(&first);
+ list_win_vars(&first);
+ list_tab_vars(&first);
+ list_script_vars(&first);
+ list_func_vars(&first);
+ list_vim_vars(&first);
+ }
+ eap->nextcmd = check_nextcmd(arg);
+ } else {
+ op[0] = '=';
+ op[1] = NUL;
+ if (expr > argend) {
+ if (vim_strchr((char_u *)"+-.", expr[-1]) != NULL)
+ op[0] = expr[-1]; /* +=, -= or .= */
+ }
+ expr = skipwhite(expr + 1);
+
+ if (eap->skip)
+ ++emsg_skip;
+ i = eval0(expr, &rettv, &eap->nextcmd, !eap->skip);
+ if (eap->skip) {
+ if (i != FAIL)
+ clear_tv(&rettv);
+ --emsg_skip;
+ } else if (i != FAIL) {
+ (void)ex_let_vars(eap->arg, &rettv, FALSE, semicolon, var_count,
+ op);
+ clear_tv(&rettv);
+ }
+ }
+}
+
+/*
+ * Assign the typevalue "tv" to the variable or variables at "arg_start".
+ * Handles both "var" with any type and "[var, var; var]" with a list type.
+ * When "nextchars" is not NULL it points to a string with characters that
+ * must appear after the variable(s). Use "+", "-" or "." for add, subtract
+ * or concatenate.
+ * Returns OK or FAIL;
+ */
+static int ex_let_vars(arg_start, tv, copy, semicolon, var_count, nextchars)
+char_u *arg_start;
+typval_T *tv;
+int copy; /* copy values from "tv", don't move */
+int semicolon; /* from skip_var_list() */
+int var_count; /* from skip_var_list() */
+char_u *nextchars;
+{
+ char_u *arg = arg_start;
+ list_T *l;
+ int i;
+ listitem_T *item;
+ typval_T ltv;
+
+ if (*arg != '[') {
+ /*
+ * ":let var = expr" or ":for var in list"
+ */
+ if (ex_let_one(arg, tv, copy, nextchars, nextchars) == NULL)
+ return FAIL;
+ return OK;
+ }
+
+ /*
+ * ":let [v1, v2] = list" or ":for [v1, v2] in listlist"
+ */
+ if (tv->v_type != VAR_LIST || (l = tv->vval.v_list) == NULL) {
+ EMSG(_(e_listreq));
+ return FAIL;
+ }
+
+ i = list_len(l);
+ if (semicolon == 0 && var_count < i) {
+ EMSG(_("E687: Less targets than List items"));
+ return FAIL;
+ }
+ if (var_count - semicolon > i) {
+ EMSG(_("E688: More targets than List items"));
+ return FAIL;
+ }
+
+ item = l->lv_first;
+ 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)
+ return FAIL;
+
+ 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();
+ if (l == NULL)
+ return FAIL;
+ while (item != NULL) {
+ list_append_tv(l, &item->li_tv);
+ item = item->li_next;
+ }
+
+ 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)
+ return FAIL;
+ break;
+ } else if (*arg != ',' && *arg != ']') {
+ EMSG2(_(e_intern2), "ex_let_vars()");
+ return FAIL;
+ }
+ }
+
+ return OK;
+}
+
+/*
+ * Skip over assignable variable "var" or list of variables "[var, var]".
+ * Used for ":let varvar = expr" and ":for varvar in expr".
+ * For "[var, var]" increment "*var_count" for each variable.
+ * for "[var, var; var]" set "semicolon".
+ * Return NULL for an error.
+ */
+static char_u * skip_var_list(arg, var_count, semicolon)
+char_u *arg;
+int *var_count;
+int *semicolon;
+{
+ char_u *p, *s;
+
+ if (*arg == '[') {
+ /* "[var, var]": find the matching ']'. */
+ p = arg;
+ for (;; ) {
+ p = skipwhite(p + 1); /* skip whites after '[', ';' or ',' */
+ s = skip_var_one(p);
+ if (s == p) {
+ EMSG2(_(e_invarg2), p);
+ return NULL;
+ }
+ ++*var_count;
+
+ p = skipwhite(s);
+ if (*p == ']')
+ break;
+ else if (*p == ';') {
+ if (*semicolon == 1) {
+ EMSG(_("Double ; in list of variables"));
+ return NULL;
+ }
+ *semicolon = 1;
+ } else if (*p != ',') {
+ EMSG2(_(e_invarg2), p);
+ return NULL;
+ }
+ }
+ return p + 1;
+ } else
+ return skip_var_one(arg);
+}
+
+/*
+ * Skip one (assignable) variable name, including @r, $VAR, &option, d.key,
+ * l[idx].
+ */
+static char_u * skip_var_one(arg)
+char_u *arg;
+{
+ if (*arg == '@' && arg[1] != NUL)
+ return arg + 2;
+ return find_name_end(*arg == '$' || *arg == '&' ? arg + 1 : arg,
+ NULL, NULL, FNE_INCL_BR | FNE_CHECK_START);
+}
+
+/*
+ * List variables for hashtab "ht" with prefix "prefix".
+ * If "empty" is TRUE also list NULL strings as empty strings.
+ */
+static void list_hashtable_vars(ht, prefix, empty, first)
+hashtab_T *ht;
+char_u *prefix;
+int empty;
+int *first;
+{
+ hashitem_T *hi;
+ dictitem_T *di;
+ int todo;
+
+ todo = (int)ht->ht_used;
+ for (hi = ht->ht_array; todo > 0 && !got_int; ++hi) {
+ if (!HASHITEM_EMPTY(hi)) {
+ --todo;
+ di = HI2DI(hi);
+ if (empty || di->di_tv.v_type != VAR_STRING
+ || di->di_tv.vval.v_string != NULL)
+ list_one_var(di, prefix, first);
+ }
+ }
+}
+
+/*
+ * List global variables.
+ */
+static void list_glob_vars(first)
+int *first;
+{
+ list_hashtable_vars(&globvarht, (char_u *)"", TRUE, first);
+}
+
+/*
+ * List buffer variables.
+ */
+static void list_buf_vars(first)
+int *first;
+{
+ char_u numbuf[NUMBUFLEN];
+
+ list_hashtable_vars(&curbuf->b_vars->dv_hashtab, (char_u *)"b:",
+ TRUE, first);
+
+ sprintf((char *)numbuf, "%ld", (long)curbuf->b_changedtick);
+ list_one_var_a((char_u *)"b:", (char_u *)"changedtick", VAR_NUMBER,
+ numbuf, first);
+}
+
+/*
+ * List window variables.
+ */
+static void list_win_vars(first)
+int *first;
+{
+ list_hashtable_vars(&curwin->w_vars->dv_hashtab,
+ (char_u *)"w:", TRUE, first);
+}
+
+/*
+ * List tab page variables.
+ */
+static void list_tab_vars(first)
+int *first;
+{
+ list_hashtable_vars(&curtab->tp_vars->dv_hashtab,
+ (char_u *)"t:", TRUE, first);
+}
+
+/*
+ * List Vim variables.
+ */
+static void list_vim_vars(first)
+int *first;
+{
+ list_hashtable_vars(&vimvarht, (char_u *)"v:", FALSE, first);
+}
+
+/*
+ * List script-local variables, if there is a script.
+ */
+static void list_script_vars(first)
+int *first;
+{
+ if (current_SID > 0 && current_SID <= ga_scripts.ga_len)
+ list_hashtable_vars(&SCRIPT_VARS(current_SID),
+ (char_u *)"s:", FALSE, first);
+}
+
+/*
+ * List function variables, if there is a function.
+ */
+static void list_func_vars(first)
+int *first;
+{
+ if (current_funccal != NULL)
+ list_hashtable_vars(&current_funccal->l_vars.dv_hashtab,
+ (char_u *)"l:", FALSE, first);
+}
+
+/*
+ * List variables in "arg".
+ */
+static char_u * list_arg_vars(eap, arg, first)
+exarg_T *eap;
+char_u *arg;
+int *first;
+{
+ int error = FALSE;
+ int len;
+ char_u *name;
+ char_u *name_start;
+ char_u *arg_subsc;
+ char_u *tofree;
+ 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);
+ if (!vim_iswhite(*arg) && !ends_excmd(*arg)) {
+ emsg_severe = TRUE;
+ EMSG(_(e_trailing));
+ break;
+ }
+ } else {
+ /* get_name_len() takes care of expanding curly braces */
+ name_start = name = arg;
+ 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. */
+ if (len < 0 && !aborting()) {
+ emsg_severe = TRUE;
+ EMSG2(_(e_invarg2), arg);
+ break;
+ }
+ error = TRUE;
+ } else {
+ if (tofree != NULL)
+ name = tofree;
+ if (get_var_tv(name, len, &tv, 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 {
+ if (arg == arg_subsc && len == 2 && name[1] == ':') {
+ switch (*name) {
+ case 'g': list_glob_vars(first); break;
+ case 'b': list_buf_vars(first); break;
+ case 'w': list_win_vars(first); break;
+ case 't': list_tab_vars(first); break;
+ case 'v': list_vim_vars(first); break;
+ case 's': list_script_vars(first); break;
+ case 'l': list_func_vars(first); break;
+ default:
+ EMSG2(_("E738: Can't list variables for %s"), name);
+ }
+ } else {
+ char_u numbuf[NUMBUFLEN];
+ char_u *tf;
+ int c;
+ char_u *s;
+
+ s = echo_string(&tv, &tf, numbuf, 0);
+ 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;
+ vim_free(tf);
+ }
+ clear_tv(&tv);
+ }
+ }
+ }
+
+ vim_free(tofree);
+ }
+
+ arg = skipwhite(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(arg, tv, copy, endchars, op)
+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;
+ int len;
+ int opt_flags;
+ 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)
+ EMSG2(_(e_invarg2), name - 1);
+ else {
+ if (op != NULL && (*op == '+' || *op == '-'))
+ EMSG2(_(e_letwrong), op);
+ else if (endchars != NULL
+ && vim_strchr(endchars, *skipwhite(arg)) == NULL)
+ EMSG(_(e_letunexp));
+ else if (!check_secure()) {
+ c1 = name[len];
+ name[len] = NUL;
+ p = get_tv_string_chk(tv);
+ if (p != NULL && op != NULL && *op == '.') {
+ int mustfree = FALSE;
+ char_u *s = vim_getenv(name, &mustfree);
+
+ if (s != NULL) {
+ p = tofree = concat_str(s, p);
+ if (mustfree)
+ vim_free(s);
+ }
+ }
+ if (p != NULL) {
+ 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;
+ arg_end = arg;
+ }
+ name[len] = c1;
+ vim_free(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))
+ EMSG(_(e_letunexp));
+ else {
+ long n;
+ int opt_type;
+ long numval;
+ char_u *stringval = NULL;
+ char_u *s;
+
+ c1 = *p;
+ *p = NUL;
+
+ n = get_tv_number(tv);
+ s = get_tv_string_chk(tv); /* != NULL if number or string */
+ if (s != NULL && op != NULL && *op != '=') {
+ opt_type = get_option_value(arg, &numval,
+ &stringval, opt_flags);
+ if ((opt_type == 1 && *op == '.')
+ || (opt_type == 0 && *op != '.'))
+ EMSG2(_(e_letwrong), op);
+ else {
+ if (opt_type == 1) { /* number */
+ if (*op == '+')
+ n = numval + n;
+ else
+ n = numval - n;
+ } else if (opt_type == 0 && stringval != NULL) { /* string */
+ s = concat_str(stringval, s);
+ vim_free(stringval);
+ stringval = s;
+ }
+ }
+ }
+ if (s != NULL) {
+ set_option_value(arg, n, s, opt_flags);
+ arg_end = p;
+ }
+ *p = c1;
+ vim_free(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)
+ EMSG(_(e_letunexp));
+ else {
+ char_u *ptofree = NULL;
+ char_u *s;
+
+ p = get_tv_string_chk(tv);
+ if (p != NULL && op != NULL && *op == '.') {
+ s = get_reg_contents(*arg == '@' ? '"' : *arg, TRUE, TRUE);
+ if (s != NULL) {
+ p = ptofree = concat_str(s, p);
+ vim_free(s);
+ }
+ }
+ if (p != NULL) {
+ write_reg_contents(*arg == '@' ? '"' : *arg, p, -1, FALSE);
+ arg_end = arg + 1;
+ }
+ vim_free(ptofree);
+ }
+ }
+ /*
+ * ":let var = expr": Set internal variable.
+ * ":let {expr} = expr": Idem, name made with curly braces
+ */
+ else if (eval_isnamec1(*arg) || *arg == '{') {
+ lval_T lv;
+
+ 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)
+ EMSG(_(e_letunexp));
+ else {
+ set_var_lval(&lv, p, tv, copy, op);
+ arg_end = p;
+ }
+ }
+ clear_lval(&lv);
+ } else
+ EMSG2(_(e_invarg2), arg);
+
+ return arg_end;
+}
+
+/*
+ * If "arg" is equal to "b:changedtick" give an error and return TRUE.
+ */
+static int check_changedtick(arg)
+char_u *arg;
+{
+ if (STRNCMP(arg, "b:changedtick", 13) == 0 && !eval_isnamec(arg[13])) {
+ EMSG2(_(e_readonlyvar), arg);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*
+ * 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(name, rettv, lp, unlet, skip, flags, fne_flags)
+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() */
+{
+ 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;
+
+ /* Clear everything in "lp". */
+ vim_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);
+ }
+
+ /* Find the end of the name. */
+ p = find_name_end(name, &expr_start, &expr_end, fne_flags);
+ if (expr_start != NULL) {
+ /* Don't expand the name when we already know there is an error. */
+ if (unlet && !vim_iswhite(*p) && !ends_excmd(*p)
+ && *p != '[' && *p != '.') {
+ EMSG(_(e_trailing));
+ return NULL;
+ }
+
+ lp->ll_exp_name = make_expanded_name(name, expr_start, expr_end, p);
+ if (lp->ll_exp_name == NULL) {
+ /* Report an invalid expression in braces, unless the
+ * expression evaluation has been cancelled due to an
+ * aborting error, an interrupt, or an exception. */
+ if (!aborting() && !quiet) {
+ emsg_severe = TRUE;
+ EMSG2(_(e_invarg2), name);
+ return NULL;
+ }
+ }
+ lp->ll_name = lp->ll_exp_name;
+ } else
+ lp->ll_name = name;
+
+ /* 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)
+ return NULL;
+
+ /*
+ * Loop until no more [idx] or .key is following.
+ */
+ lp->ll_tv = &v->di_tv;
+ 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
+ && lp->ll_tv->vval.v_dict != NULL)) {
+ if (!quiet)
+ EMSG(_("E689: Can only index a List or Dictionary"));
+ return NULL;
+ }
+ if (lp->ll_range) {
+ if (!quiet)
+ EMSG(_("E708: [:] must come last"));
+ return NULL;
+ }
+
+ len = -1;
+ if (*p == '.') {
+ key = p + 1;
+ for (len = 0; ASCII_ISALNUM(key[len]) || key[len] == '_'; ++len)
+ ;
+ if (len == 0) {
+ if (!quiet)
+ EMSG(_(e_emptykey));
+ 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! */
+ return NULL;
+ if (get_tv_string_chk(&var1) == NULL) {
+ /* not a number or string */
+ clear_tv(&var1);
+ return NULL;
+ }
+ }
+
+ /* Optionally get the second index [ :expr]. */
+ if (*p == ':') {
+ if (lp->ll_tv->v_type == VAR_DICT) {
+ if (!quiet)
+ EMSG(_(e_dictrange));
+ if (!empty1)
+ clear_tv(&var1);
+ return NULL;
+ }
+ if (rettv != NULL && (rettv->v_type != VAR_LIST
+ || rettv->vval.v_list == NULL)) {
+ if (!quiet)
+ EMSG(_("E709: [:] requires a List value"));
+ if (!empty1)
+ clear_tv(&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);
+ return NULL;
+ }
+ if (get_tv_string_chk(&var2) == NULL) {
+ /* not a number or string */
+ if (!empty1)
+ clear_tv(&var1);
+ clear_tv(&var2);
+ return NULL;
+ }
+ }
+ lp->ll_range = TRUE;
+ } else
+ lp->ll_range = FALSE;
+
+ if (*p != ']') {
+ if (!quiet)
+ EMSG(_(e_missbrac));
+ if (!empty1)
+ clear_tv(&var1);
+ if (lp->ll_range && !lp->ll_empty2)
+ clear_tv(&var2);
+ return NULL;
+ }
+
+ /* Skip to past ']'. */
+ ++p;
+ }
+
+ 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;
+ }
+ }
+ lp->ll_list = NULL;
+ lp->ll_dict = lp->ll_tv->vval.v_dict;
+ lp->ll_di = dict_find(lp->ll_dict, 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
+ * g: dictionary). Disallow overwriting a builtin function. */
+ if (rettv != NULL && lp->ll_dict->dv_scope != 0) {
+ int prevval;
+ int wrong;
+
+ 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)
+ key[len] = prevval;
+ if (wrong)
+ return NULL;
+ }
+
+ if (lp->ll_di == NULL) {
+ /* Can't add "v:" variable. */
+ if (lp->ll_dict == &vimvardict) {
+ EMSG2(_(e_illvar), name);
+ return NULL;
+ }
+
+ /* 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);
+ return NULL;
+ }
+ if (len == -1)
+ lp->ll_newkey = vim_strsave(key);
+ else
+ lp->ll_newkey = vim_strnsave(key, len);
+ if (len == -1)
+ clear_tv(&var1);
+ if (lp->ll_newkey == NULL)
+ p = NULL;
+ break;
+ }
+ /* existing variable, need to check if it can be changed */
+ else if (var_check_ro(lp->ll_di->di_flags, name))
+ return NULL;
+
+ if (len == -1)
+ clear_tv(&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)
+ lp->ll_n1 = 0;
+ else {
+ lp->ll_n1 = get_tv_number(&var1); /* is number or string */
+ clear_tv(&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);
+ 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);
+ }
+ }
+ if (lp->ll_li == NULL) {
+ if (lp->ll_range && !lp->ll_empty2)
+ clear_tv(&var2);
+ if (!quiet)
+ EMSGN(_(e_listidx), lp->ll_n1);
+ return NULL;
+ }
+
+ /*
+ * May need to find the item or absolute index for the second
+ * index of a range.
+ * When no index given: "lp->ll_empty2" is TRUE.
+ * 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);
+ if (lp->ll_n2 < 0) {
+ ni = 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);
+ }
+
+ /* 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);
+ if (lp->ll_n2 < lp->ll_n1) {
+ if (!quiet)
+ EMSGN(_(e_listidx), lp->ll_n2);
+ return NULL;
+ }
+ }
+
+ lp->ll_tv = &lp->ll_li->li_tv;
+ }
+ }
+
+ return p;
+}
+
+/*
+ * Clear lval "lp" that was filled by get_lval().
+ */
+static void clear_lval(lp)
+lval_T *lp;
+{
+ vim_free(lp->ll_exp_name);
+ vim_free(lp->ll_newkey);
+}
+
+/*
+ * 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(lp, endp, rettv, copy, op)
+lval_T *lp;
+char_u *endp;
+typval_T *rettv;
+int copy;
+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 .= */
+ if (get_var_tv(lp->ll_name, (int)STRLEN(lp->ll_name),
+ &tv, TRUE, FALSE) == OK) {
+ if (tv_op(&tv, rettv, op) == OK)
+ set_var(lp->ll_name, &tv, FALSE);
+ clear_tv(&tv);
+ }
+ } else
+ set_var(lp->ll_name, 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))
+ ;
+ else if (lp->ll_range) {
+ /*
+ * 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);
+ }
+ ri = ri->li_next;
+ 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. */
+ if (list_append_number(lp->ll_list, 0) == FAIL) {
+ ri = NULL;
+ break;
+ }
+ }
+ lp->ll_li = lp->ll_li->li_next;
+ ++lp->ll_n1;
+ }
+ 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)
+ EMSG(_("E711: List value has not enough items"));
+ } else {
+ /*
+ * 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 (di == NULL)
+ return;
+ if (dict_add(lp->ll_tv->vval.v_dict, di) == FAIL) {
+ vim_free(di);
+ return;
+ }
+ lp->ll_tv = &di->di_tv;
+ } else if (op != NULL && *op != '=') {
+ tv_op(lp->ll_tv, rettv, op);
+ return;
+ } else
+ clear_tv(lp->ll_tv);
+
+ /*
+ * Assign the value to the variable or list item.
+ */
+ if (copy)
+ copy_tv(rettv, lp->ll_tv);
+ else {
+ *lp->ll_tv = *rettv;
+ lp->ll_tv->v_lock = 0;
+ init_tv(rettv);
+ }
+ }
+}
+
+/*
+ * Handle "tv1 += tv2", "tv1 -= tv2" and "tv1 .= tv2"
+ * Returns OK or FAIL.
+ */
+static int tv_op(tv1, tv2, 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 or a Dict on the right. */
+ if (tv2->v_type != VAR_FUNC && tv2->v_type != VAR_DICT) {
+ switch (tv1->v_type) {
+ case VAR_DICT:
+ case VAR_FUNC:
+ 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;
+ }
+ }
+
+ EMSG2(_(e_letwrong), op);
+ return FAIL;
+}
+
+/*
+ * Add a watcher to a list.
+ */
+void list_add_watch(l, lw)
+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(l, lwrem)
+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(l, item)
+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;
+}
+
+/*
+ * Evaluate the expression used in a ":for var in expr" command.
+ * "arg" points to "var".
+ * 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(arg, errp, nextcmdp, skip)
+char_u *arg;
+int *errp;
+char_u **nextcmdp;
+int skip;
+{
+ forinfo_T *fi;
+ char_u *expr;
+ typval_T tv;
+ list_T *l;
+
+ *errp = TRUE; /* default: there is an error */
+
+ fi = (forinfo_T *)alloc_clear(sizeof(forinfo_T));
+ if (fi == NULL)
+ return NULL;
+
+ expr = skip_var_list(arg, &fi->fi_varcount, &fi->fi_semicolon);
+ if (expr == NULL)
+ return fi;
+
+ expr = skipwhite(expr);
+ if (expr[0] != 'i' || expr[1] != 'n' || !vim_iswhite(expr[2])) {
+ EMSG(_("E690: Missing \"in\" after :for"));
+ return fi;
+ }
+
+ if (skip)
+ ++emsg_skip;
+ if (eval0(skipwhite(expr + 2), &tv, nextcmdp, !skip) == OK) {
+ *errp = FALSE;
+ if (!skip) {
+ l = tv.vval.v_list;
+ if (tv.v_type != VAR_LIST || l == NULL) {
+ EMSG(_(e_listreq));
+ clear_tv(&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;
+ }
+ }
+ }
+ if (skip)
+ --emsg_skip;
+
+ return fi;
+}
+
+/*
+ * 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(fi_void, arg)
+void *fi_void;
+char_u *arg;
+{
+ forinfo_T *fi = (forinfo_T *)fi_void;
+ int result;
+ listitem_T *item;
+
+ 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);
+ }
+ return result;
+}
+
+/*
+ * Free the structure used to store info used by ":for".
+ */
+void free_for_info(fi_void)
+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);
+ }
+ vim_free(fi);
+}
+
+
+void set_context_for_expression(xp, arg, cmdidx)
+expand_T *xp;
+char_u *arg;
+cmdidx_T cmdidx;
+{
+ int got_eq = FALSE;
+ int c;
+ char_u *p;
+
+ if (cmdidx == CMD_let) {
+ xp->xp_context = EXPAND_USER_VARS;
+ if (vim_strpbrk(arg, (char_u *)"\"'+-*/%.=!?~|&$([<>,#") == NULL) {
+ /* ":let var1 var2 ...": find last space. */
+ for (p = arg + STRLEN(arg); p >= arg; ) {
+ xp->xp_pattern = p;
+ mb_ptr_back(arg, p);
+ if (vim_iswhite(*p))
+ break;
+ }
+ return;
+ }
+ } else
+ xp->xp_context = cmdidx == CMD_call ? EXPAND_FUNCTIONS
+ : EXPAND_EXPRESSION;
+ while ((xp->xp_pattern = vim_strpbrk(arg,
+ (char_u *)"\"'+-*/%.=!?~|&$([<>,#")) != NULL) {
+ c = *xp->xp_pattern;
+ if (c == '&') {
+ c = xp->xp_pattern[1];
+ if (c == '&') {
+ ++xp->xp_pattern;
+ xp->xp_context = cmdidx != CMD_let || got_eq
+ ? EXPAND_EXPRESSION : EXPAND_NOTHING;
+ } else if (c != ' ') {
+ xp->xp_context = EXPAND_SETTINGS;
+ if ((c == 'l' || c == 'g') && xp->xp_pattern[2] == ':')
+ xp->xp_pattern += 2;
+
+ }
+ } else if (c == '$') {
+ /* environment variable */
+ xp->xp_context = EXPAND_ENV_VARS;
+ } else if (c == '=') {
+ got_eq = TRUE;
+ xp->xp_context = EXPAND_EXPRESSION;
+ } else if (c == '<'
+ && xp->xp_context == EXPAND_FUNCTIONS
+ && vim_strchr(xp->xp_pattern, '(') == NULL) {
+ /* Function name can start with "<SNR>" */
+ break;
+ } else if (cmdidx != CMD_let || got_eq) {
+ if (c == '"') { /* string */
+ while ((c = *++xp->xp_pattern) != NUL && c != '"')
+ if (c == '\\' && xp->xp_pattern[1] != NUL)
+ ++xp->xp_pattern;
+ xp->xp_context = EXPAND_NOTHING;
+ } else if (c == '\'') { /* literal string */
+ /* Trick: '' is like stopping and starting a literal string. */
+ while ((c = *++xp->xp_pattern) != NUL && c != '\'')
+ /* skip */;
+ xp->xp_context = EXPAND_NOTHING;
+ } else if (c == '|') {
+ if (xp->xp_pattern[1] == '|') {
+ ++xp->xp_pattern;
+ xp->xp_context = EXPAND_EXPRESSION;
+ } else
+ xp->xp_context = EXPAND_COMMANDS;
+ } else
+ xp->xp_context = EXPAND_EXPRESSION;
+ } else
+ /* Doesn't look like something valid, expand as an expression
+ * anyway. */
+ xp->xp_context = EXPAND_EXPRESSION;
+ arg = xp->xp_pattern;
+ if (*arg != NUL)
+ while ((c = *++arg) != NUL && (c == ' ' || c == '\t'))
+ /* skip */;
+ }
+ xp->xp_pattern = arg;
+}
+
+
+/*
+ * ":1,25call func(arg1, arg2)" function call.
+ */
+void ex_call(eap)
+exarg_T *eap;
+{
+ char_u *arg = eap->arg;
+ char_u *startarg;
+ char_u *name;
+ char_u *tofree;
+ int len;
+ typval_T rettv;
+ linenr_T lnum;
+ int doesrange;
+ int failed = FALSE;
+ funcdict_T fudi;
+
+ 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;
+ return;
+ }
+
+ tofree = trans_function_name(&arg, eap->skip, TFN_INT, &fudi);
+ if (fudi.fd_newkey != NULL) {
+ /* Still need to give an error message for missing key. */
+ EMSG2(_(e_dictkey), fudi.fd_newkey);
+ vim_free(fudi.fd_newkey);
+ }
+ 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;
+
+ /* If it is the name of a variable of type VAR_FUNC use its contents. */
+ len = (int)STRLEN(tofree);
+ name = deref_func_name(tofree, &len, FALSE);
+
+ /* 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 */
+
+ 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) {
+ 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;
+ break;
+ }
+
+ /* Handle a function returning a Funcref, Dictionary or List. */
+ if (handle_subscript(&arg, &rettv, !eap->skip, TRUE) == FAIL) {
+ failed = TRUE;
+ break;
+ }
+
+ clear_tv(&rettv);
+ if (doesrange || eap->skip)
+ 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())
+ break;
+ }
+ if (eap->skip)
+ --emsg_skip;
+
+ if (!failed) {
+ /* Check for trailing illegal characters and a following command. */
+ if (!ends_excmd(*arg)) {
+ emsg_severe = TRUE;
+ EMSG(_(e_trailing));
+ } else
+ eap->nextcmd = check_nextcmd(arg);
+ }
+
+end:
+ dict_unref(fudi.fd_dict);
+ vim_free(tofree);
+}
+
+/*
+ * ":unlet[!] var1 ... " command.
+ */
+void ex_unlet(eap)
+exarg_T *eap;
+{
+ ex_unletlock(eap, eap->arg, 0);
+}
+
+/*
+ * ":lockvar" and ":unlockvar" commands
+ */
+void ex_lockvar(eap)
+exarg_T *eap;
+{
+ char_u *arg = eap->arg;
+ int deep = 2;
+
+ if (eap->forceit)
+ deep = -1;
+ else if (vim_isdigit(*arg)) {
+ deep = getdigits(&arg);
+ arg = skipwhite(arg);
+ }
+
+ ex_unletlock(eap, arg, deep);
+}
+
+/*
+ * ":unlet", ":lockvar" and ":unlockvar" are quite similar.
+ */
+static void ex_unletlock(eap, argstart, deep)
+exarg_T *eap;
+char_u *argstart;
+int deep;
+{
+ char_u *arg = argstart;
+ char_u *name_end;
+ int 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 (name_end == NULL || (!vim_iswhite(*name_end)
+ && !ends_excmd(*name_end))) {
+ if (name_end != NULL) {
+ emsg_severe = TRUE;
+ EMSG(_(e_trailing));
+ }
+ if (!(eap->skip || error))
+ clear_lval(&lv);
+ break;
+ }
+
+ if (!error && !eap->skip) {
+ if (eap->cmdidx == CMD_unlet) {
+ if (do_unlet_var(&lv, name_end, eap->forceit) == FAIL)
+ error = TRUE;
+ } else {
+ if (do_lock_var(&lv, name_end, deep,
+ eap->cmdidx == CMD_lockvar) == FAIL)
+ error = TRUE;
+ }
+ }
+
+ if (!eap->skip)
+ clear_lval(&lv);
+
+ arg = skipwhite(name_end);
+ } while (!ends_excmd(*arg));
+
+ eap->nextcmd = check_nextcmd(arg);
+}
+
+static int do_unlet_var(lp, name_end, forceit)
+lval_T *lp;
+char_u *name_end;
+int forceit;
+{
+ int ret = OK;
+ int cc;
+
+ if (lp->ll_tv == NULL) {
+ 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)
+ ret = FAIL;
+ *name_end = cc;
+ } else if (tv_check_lock(lp->ll_tv->v_lock, lp->ll_name))
+ return FAIL;
+ else if (lp->ll_range) {
+ listitem_T *li;
+
+ /* 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;
+ }
+ } else {
+ if (lp->ll_list != NULL)
+ /* unlet a List item. */
+ listitem_remove(lp->ll_list, lp->ll_li);
+ else
+ /* unlet a Dictionary item. */
+ dictitem_remove(lp->ll_dict, lp->ll_di);
+ }
+
+ 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(name, forceit)
+char_u *name;
+int forceit;
+{
+ hashtab_T *ht;
+ hashitem_T *hi;
+ char_u *varname;
+ dictitem_T *di;
+
+ ht = find_var_ht(name, &varname);
+ if (ht != NULL && *varname != NUL) {
+ hi = hash_find(ht, varname);
+ if (!HASHITEM_EMPTY(hi)) {
+ di = HI2DI(hi);
+ if (var_check_fixed(di->di_flags, name)
+ || var_check_ro(di->di_flags, name))
+ return FAIL;
+ delete_var(ht, hi);
+ return OK;
+ }
+ }
+ if (forceit)
+ return OK;
+ EMSG2(_("E108: No such variable: \"%s\""), name);
+ return FAIL;
+}
+
+/*
+ * 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(lp, name_end, deep, lock)
+lval_T *lp;
+char_u *name_end;
+int deep;
+int lock;
+{
+ int ret = OK;
+ int cc;
+ dictitem_T *di;
+
+ 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))
+ 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);
+ }
+ }
+ *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;
+ }
+ } else if (lp->ll_list != NULL)
+ /* (un)lock a List item. */
+ item_lock(&lp->ll_li->li_tv, deep, lock);
+ else
+ /* un(lock) a Dictionary item. */
+ 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(tv, deep, 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);
+ }
+ }
+ }
+ }
+ }
+ --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(tv)
+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() {
+ 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);
+ }
+ }
+ hash_unlock(&globvarht);
+}
+
+/*
+ * Local string buffer for the next two functions to store a variable name
+ * with its prefix. Allocated in cat_prefix_varname(), freed later in
+ * get_user_var_name().
+ */
+
+static char_u *cat_prefix_varname __ARGS((int prefix, char_u *name));
+
+static char_u *varnamebuf = NULL;
+static int varnamebuflen = 0;
+
+/*
+ * Function to concatenate a prefix and a variable name.
+ */
+static char_u * cat_prefix_varname(prefix, name)
+int prefix;
+char_u *name;
+{
+ int len;
+
+ len = (int)STRLEN(name) + 3;
+ if (len > varnamebuflen) {
+ vim_free(varnamebuf);
+ len += 10; /* some additional space */
+ varnamebuf = alloc(len);
+ if (varnamebuf == NULL) {
+ varnamebuflen = 0;
+ return NULL;
+ }
+ varnamebuflen = len;
+ }
+ *varnamebuf = prefix;
+ varnamebuf[1] = ':';
+ STRCPY(varnamebuf + 2, name);
+ return varnamebuf;
+}
+
+/*
+ * Function given to ExpandGeneric() to obtain the list of user defined
+ * (global/buffer/window/built-in) variable names.
+ */
+char_u * get_user_var_name(xp, idx)
+expand_T *xp;
+int idx;
+{
+ static long_u gdone;
+ static long_u bdone;
+ static long_u wdone;
+ static long_u tdone;
+ static int vidx;
+ static hashitem_T *hi;
+ hashtab_T *ht;
+
+ if (idx == 0) {
+ gdone = bdone = wdone = vidx = 0;
+ tdone = 0;
+ }
+
+ /* Global variables */
+ if (gdone < globvarht.ht_used) {
+ if (gdone++ == 0)
+ hi = globvarht.ht_array;
+ else
+ ++hi;
+ while (HASHITEM_EMPTY(hi))
+ ++hi;
+ if (STRNCMP("g:", xp->xp_pattern, 2) == 0)
+ return cat_prefix_varname('g', hi->hi_key);
+ return hi->hi_key;
+ }
+
+ /* b: variables */
+ ht = &curbuf->b_vars->dv_hashtab;
+ if (bdone < ht->ht_used) {
+ if (bdone++ == 0)
+ hi = ht->ht_array;
+ else
+ ++hi;
+ while (HASHITEM_EMPTY(hi))
+ ++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;
+ if (wdone < ht->ht_used) {
+ if (wdone++ == 0)
+ hi = ht->ht_array;
+ else
+ ++hi;
+ while (HASHITEM_EMPTY(hi))
+ ++hi;
+ return cat_prefix_varname('w', hi->hi_key);
+ }
+
+ /* t: variables */
+ ht = &curtab->tp_vars->dv_hashtab;
+ if (tdone < ht->ht_used) {
+ if (tdone++ == 0)
+ hi = ht->ht_array;
+ else
+ ++hi;
+ while (HASHITEM_EMPTY(hi))
+ ++hi;
+ return cat_prefix_varname('t', hi->hi_key);
+ }
+
+ /* v: variables */
+ if (vidx < VV_LEN)
+ return cat_prefix_varname('v', (char_u *)vimvars[vidx++].vv_name);
+
+ vim_free(varnamebuf);
+ varnamebuf = NULL;
+ varnamebuflen = 0;
+ return NULL;
+}
+
+
+/*
+ * types for expressions.
+ */
+typedef enum {
+ TYPE_UNKNOWN = 0
+ , TYPE_EQUAL /* == */
+ , TYPE_NEQUAL /* != */
+ , TYPE_GREATER /* > */
+ , TYPE_GEQUAL /* >= */
+ , TYPE_SMALLER /* < */
+ , TYPE_SEQUAL /* <= */
+ , TYPE_MATCH /* =~ */
+ , TYPE_NOMATCH /* !~ */
+} exptype_T;
+
+/*
+ * The "evaluate" argument: When FALSE, the argument is only parsed but not
+ * executed. The function may return OK, but the rettv will be of type
+ * VAR_UNKNOWN. The function still returns FAIL for a syntax error.
+ */
+
+/*
+ * Handle zero level expression.
+ * This calls eval1() and handles error message and nextcmd.
+ * Put the result in "rettv" when returning OK and "evaluate" is TRUE.
+ * Note: "rettv.v_lock" is not set.
+ * Return OK or FAIL.
+ */
+static int eval0(arg, rettv, nextcmd, evaluate)
+char_u *arg;
+typval_T *rettv;
+char_u **nextcmd;
+int evaluate;
+{
+ int ret;
+ char_u *p;
+
+ 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);
+ ret = FAIL;
+ }
+ if (nextcmd != NULL)
+ *nextcmd = check_nextcmd(p);
+
+ return ret;
+}
+
+/*
+ * Handle top level expression:
+ * expr2 ? expr1 : expr1
+ *
+ * "arg" must point to the first non-white of the expression.
+ * "arg" is advanced to the next non-white after the recognized expression.
+ *
+ * Note: "rettv.v_lock" is not set.
+ *
+ * Return OK or FAIL.
+ */
+static int eval1(arg, rettv, evaluate)
+char_u **arg;
+typval_T *rettv;
+int evaluate;
+{
+ int result;
+ typval_T var2;
+
+ /*
+ * Get the first variable.
+ */
+ if (eval2(arg, rettv, evaluate) == FAIL)
+ return FAIL;
+
+ if ((*arg)[0] == '?') {
+ result = FALSE;
+ if (evaluate) {
+ int error = FALSE;
+
+ if (get_tv_number_chk(rettv, &error) != 0)
+ result = TRUE;
+ clear_tv(rettv);
+ if (error)
+ return FAIL;
+ }
+
+ /*
+ * Get the second variable.
+ */
+ *arg = skipwhite(*arg + 1);
+ if (eval1(arg, rettv, evaluate && result) == FAIL) /* recursive! */
+ return FAIL;
+
+ /*
+ * Check for the ":".
+ */
+ if ((*arg)[0] != ':') {
+ EMSG(_("E109: Missing ':' after '?'"));
+ if (evaluate && result)
+ clear_tv(rettv);
+ return FAIL;
+ }
+
+ /*
+ * Get the third variable.
+ */
+ *arg = skipwhite(*arg + 1);
+ if (eval1(arg, &var2, evaluate && !result) == FAIL) { /* recursive! */
+ if (evaluate && result)
+ clear_tv(rettv);
+ return FAIL;
+ }
+ if (evaluate && !result)
+ *rettv = var2;
+ }
+
+ return OK;
+}
+
+/*
+ * Handle first level expression:
+ * expr2 || expr2 || expr2 logical OR
+ *
+ * "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 eval2(arg, rettv, evaluate)
+char_u **arg;
+typval_T *rettv;
+int evaluate;
+{
+ typval_T var2;
+ long result;
+ int first;
+ int error = FALSE;
+
+ /*
+ * Get the first variable.
+ */
+ if (eval3(arg, rettv, evaluate) == FAIL)
+ return FAIL;
+
+ /*
+ * Repeat until there is no following "||".
+ */
+ first = TRUE;
+ 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)
+ return FAIL;
+ first = FALSE;
+ }
+
+ /*
+ * Get the second variable.
+ */
+ *arg = skipwhite(*arg + 2);
+ if (eval3(arg, &var2, evaluate && !result) == FAIL)
+ return FAIL;
+
+ /*
+ * Compute the result.
+ */
+ if (evaluate && !result) {
+ if (get_tv_number_chk(&var2, &error) != 0)
+ result = TRUE;
+ clear_tv(&var2);
+ if (error)
+ return FAIL;
+ }
+ if (evaluate) {
+ rettv->v_type = VAR_NUMBER;
+ rettv->vval.v_number = result;
+ }
+ }
+
+ return OK;
+}
+
+/*
+ * Handle second level expression:
+ * expr3 && expr3 && expr3 logical AND
+ *
+ * "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 eval3(arg, rettv, evaluate)
+char_u **arg;
+typval_T *rettv;
+int evaluate;
+{
+ typval_T var2;
+ long result;
+ int first;
+ int error = FALSE;
+
+ /*
+ * Get the first variable.
+ */
+ if (eval4(arg, rettv, evaluate) == FAIL)
+ return FAIL;
+
+ /*
+ * Repeat until there is no following "&&".
+ */
+ first = TRUE;
+ 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)
+ return FAIL;
+ first = FALSE;
+ }
+
+ /*
+ * Get the second variable.
+ */
+ *arg = skipwhite(*arg + 2);
+ if (eval4(arg, &var2, evaluate && result) == FAIL)
+ return FAIL;
+
+ /*
+ * Compute the result.
+ */
+ if (evaluate && result) {
+ if (get_tv_number_chk(&var2, &error) == 0)
+ result = FALSE;
+ clear_tv(&var2);
+ if (error)
+ return FAIL;
+ }
+ if (evaluate) {
+ rettv->v_type = VAR_NUMBER;
+ rettv->vval.v_number = result;
+ }
+ }
+
+ return OK;
+}
+
+/*
+ * Handle third level expression:
+ * var1 == var2
+ * var1 =~ var2
+ * var1 != var2
+ * var1 !~ var2
+ * var1 > var2
+ * var1 >= var2
+ * var1 < var2
+ * var1 <= var2
+ * var1 is var2
+ * var1 isnot var2
+ *
+ * "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 eval4(arg, rettv, evaluate)
+char_u **arg;
+typval_T *rettv;
+int evaluate;
+{
+ typval_T var2;
+ char_u *p;
+ int i;
+ 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;
+ int ic;
+ char_u *save_cpo;
+
+ /*
+ * Get the first variable.
+ */
+ if (eval5(arg, rettv, evaluate) == FAIL)
+ return FAIL;
+
+ p = *arg;
+ switch (p[0]) {
+ case '=': if (p[1] == '=')
+ type = TYPE_EQUAL;
+ else if (p[1] == '~')
+ type = TYPE_MATCH;
+ break;
+ case '!': if (p[1] == '=')
+ type = TYPE_NEQUAL;
+ else if (p[1] == '~')
+ type = TYPE_NOMATCH;
+ break;
+ case '>': if (p[1] != '=') {
+ type = TYPE_GREATER;
+ len = 1;
+ } else
+ type = TYPE_GEQUAL;
+ break;
+ case '<': if (p[1] != '=') {
+ type = TYPE_SMALLER;
+ len = 1;
+ } else
+ type = TYPE_SEQUAL;
+ break;
+ case 'i': if (p[1] == 's') {
+ if (p[2] == 'n' && p[3] == 'o' && p[4] == 't')
+ len = 5;
+ if (!vim_isIDc(p[len])) {
+ type = len == 2 ? TYPE_EQUAL : TYPE_NEQUAL;
+ type_is = TRUE;
+ }
+ }
+ break;
+ }
+
+ /*
+ * If there is a comparative operator, use it.
+ */
+ if (type != TYPE_UNKNOWN) {
+ /* extra question mark appended: ignore case */
+ if (p[len] == '?') {
+ ic = TRUE;
+ ++len;
+ }
+ /* extra '#' appended: match case */
+ else if (p[len] == '#') {
+ ic = FALSE;
+ ++len;
+ }
+ /* nothing appended: use 'ignorecase' */
+ else
+ ic = p_ic;
+
+ /*
+ * Get the second variable.
+ */
+ *arg = skipwhite(p + len);
+ if (eval5(arg, &var2, evaluate) == FAIL) {
+ clear_tv(rettv);
+ return FAIL;
+ }
+
+ if (evaluate) {
+ if (type_is && rettv->v_type != var2.v_type) {
+ /* For "is" a different type always means FALSE, for "notis"
+ * it means TRUE. */
+ n1 = (type == TYPE_NEQUAL);
+ } else if (rettv->v_type == VAR_LIST || var2.v_type == VAR_LIST) {
+ if (type_is) {
+ n1 = (rettv->v_type == var2.v_type
+ && rettv->vval.v_list == var2.vval.v_list);
+ if (type == TYPE_NEQUAL)
+ n1 = !n1;
+ } else if (rettv->v_type != var2.v_type
+ || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) {
+ if (rettv->v_type != var2.v_type)
+ EMSG(_("E691: Can only compare List with List"));
+ else
+ EMSG(_("E692: Invalid operation for Lists"));
+ clear_tv(rettv);
+ clear_tv(&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)
+ n1 = !n1;
+ }
+ } else if (rettv->v_type == VAR_DICT || var2.v_type == VAR_DICT) {
+ if (type_is) {
+ n1 = (rettv->v_type == var2.v_type
+ && rettv->vval.v_dict == var2.vval.v_dict);
+ if (type == TYPE_NEQUAL)
+ n1 = !n1;
+ } else if (rettv->v_type != var2.v_type
+ || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) {
+ if (rettv->v_type != var2.v_type)
+ EMSG(_("E735: Can only compare Dictionary with Dictionary"));
+ else
+ EMSG(_("E736: Invalid operation for Dictionary"));
+ clear_tv(rettv);
+ clear_tv(&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)
+ 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);
+ return FAIL;
+ } 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;
+ }
+ }
+ /*
+ * If one of the two variables is a float, compare as a float.
+ * When using "=~" or "!~", always compare as string.
+ */
+ else if ((rettv->v_type == VAR_FLOAT || var2.v_type == VAR_FLOAT)
+ && type != TYPE_MATCH && type != TYPE_NOMATCH) {
+ float_T f1, f2;
+
+ if (rettv->v_type == VAR_FLOAT)
+ f1 = rettv->vval.v_float;
+ else
+ f1 = get_tv_number(rettv);
+ if (var2.v_type == VAR_FLOAT)
+ f2 = var2.vval.v_float;
+ else
+ f2 = get_tv_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 */
+ }
+ }
+ /*
+ * If one of the two variables is a number, compare as a number.
+ * When using "=~" or "!~", always compare as string.
+ */
+ 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);
+ 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 */
+ }
+ } 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
+ i = 0;
+ 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)
+ n1 = !n1;
+ }
+ p_cpo = save_cpo;
+ break;
+
+ case TYPE_UNKNOWN: break; /* avoid gcc warning */
+ }
+ }
+ clear_tv(rettv);
+ clear_tv(&var2);
+ rettv->v_type = VAR_NUMBER;
+ rettv->vval.v_number = n1;
+ }
+ }
+
+ return OK;
+}
+
+/*
+ * Handle fourth level expression:
+ * + number addition
+ * - number subtraction
+ * . string concatenation
+ *
+ * "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 eval5(arg, rettv, evaluate)
+char_u **arg;
+typval_T *rettv;
+int evaluate;
+{
+ typval_T var2;
+ typval_T var3;
+ int op;
+ long n1, n2;
+ float_T f1 = 0, f2 = 0;
+ char_u *s1, *s2;
+ char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN];
+ char_u *p;
+
+ /*
+ * Get the first variable.
+ */
+ if (eval6(arg, rettv, evaluate, FALSE) == FAIL)
+ return FAIL;
+
+ /*
+ * Repeat computing, until no '+', '-' or '.' is following.
+ */
+ for (;; ) {
+ op = **arg;
+ if (op != '+' && op != '-' && op != '.')
+ 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);
+ return FAIL;
+ }
+ }
+
+ /*
+ * Get the second variable.
+ */
+ *arg = skipwhite(*arg + 1);
+ if (eval6(arg, &var2, evaluate, op == '.') == FAIL) {
+ clear_tv(rettv);
+ return FAIL;
+ }
+
+ if (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);
+ return FAIL;
+ }
+ p = concat_str(s1, s2);
+ clear_tv(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);
+ return FAIL;
+ }
+ clear_tv(rettv);
+ *rettv = var3;
+ } else {
+ int error = FALSE;
+
+ if (rettv->v_type == VAR_FLOAT) {
+ f1 = rettv->vval.v_float;
+ n1 = 0;
+ } else {
+ n1 = get_tv_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);
+ return FAIL;
+ }
+ if (var2.v_type == VAR_FLOAT)
+ f1 = n1;
+ }
+ if (var2.v_type == VAR_FLOAT) {
+ f2 = var2.vval.v_float;
+ n2 = 0;
+ } else {
+ n2 = get_tv_number_chk(&var2, &error);
+ if (error) {
+ clear_tv(rettv);
+ clear_tv(&var2);
+ return FAIL;
+ }
+ if (rettv->v_type == VAR_FLOAT)
+ f2 = n2;
+ }
+ clear_tv(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) {
+ if (op == '+')
+ f1 = f1 + f2;
+ else
+ f1 = f1 - f2;
+ rettv->v_type = VAR_FLOAT;
+ rettv->vval.v_float = f1;
+ } else {
+ if (op == '+')
+ n1 = n1 + n2;
+ else
+ n1 = n1 - n2;
+ rettv->v_type = VAR_NUMBER;
+ rettv->vval.v_number = n1;
+ }
+ }
+ clear_tv(&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(arg, rettv, evaluate, want_string)
+char_u **arg;
+typval_T *rettv;
+int evaluate;
+int want_string; /* after "." operator */
+{
+ typval_T var2;
+ int op;
+ long n1, n2;
+ int use_float = FALSE;
+ float_T f1 = 0, f2;
+ int error = FALSE;
+
+ /*
+ * Get the first variable.
+ */
+ if (eval7(arg, rettv, evaluate, want_string) == FAIL)
+ return FAIL;
+
+ /*
+ * Repeat computing, until no '*', '/' or '%' is following.
+ */
+ for (;; ) {
+ op = **arg;
+ if (op != '*' && op != '/' && op != '%')
+ break;
+
+ if (evaluate) {
+ if (rettv->v_type == VAR_FLOAT) {
+ f1 = rettv->vval.v_float;
+ use_float = TRUE;
+ n1 = 0;
+ } else
+ n1 = get_tv_number_chk(rettv, &error);
+ clear_tv(rettv);
+ if (error)
+ return FAIL;
+ } else
+ n1 = 0;
+
+ /*
+ * Get the second variable.
+ */
+ *arg = skipwhite(*arg + 1);
+ if (eval7(arg, &var2, evaluate, FALSE) == FAIL)
+ return FAIL;
+
+ if (evaluate) {
+ if (var2.v_type == VAR_FLOAT) {
+ if (!use_float) {
+ f1 = n1;
+ use_float = TRUE;
+ }
+ f2 = var2.vval.v_float;
+ n2 = 0;
+ } else {
+ n2 = get_tv_number_chk(&var2, &error);
+ clear_tv(&var2);
+ if (error)
+ return FAIL;
+ if (use_float)
+ f2 = n2;
+ }
+
+ /*
+ * Compute the result.
+ * When either side is a float the result is a float.
+ */
+ if (use_float) {
+ if (op == '*')
+ f1 = f1 * f2;
+ else if (op == '/') {
+ /* We rely on the floating point library to handle divide
+ * by zero to result in "inf" and not a crash. */
+ f1 = f1 / f2;
+ } else {
+ EMSG(_("E804: Cannot use '%' with Float"));
+ return FAIL;
+ }
+ rettv->v_type = VAR_FLOAT;
+ rettv->vval.v_float = f1;
+ } else {
+ 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
+ n1 = n1 / n2;
+ } else {
+ if (n2 == 0) /* give an error message? */
+ n1 = 0;
+ else
+ n1 = n1 % n2;
+ }
+ rettv->v_type = VAR_NUMBER;
+ rettv->vval.v_number = n1;
+ }
+ }
+ }
+
+ return OK;
+}
+
+/*
+ * Handle sixth level expression:
+ * number number constant
+ * "string" string constant
+ * 'string' literal string constant
+ * &option-name option value
+ * @r register contents
+ * identifier variable value
+ * function() function call
+ * $VAR environment variable
+ * (expression) nested expression
+ * [expr, expr] List
+ * {key: val, key: val} Dictionary
+ *
+ * Also handle:
+ * ! in front logical NOT
+ * - in front unary minus
+ * + in front unary plus (ignored)
+ * trailing [] subscript in String or List
+ * trailing .name entry in Dictionary
+ *
+ * "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 eval7(arg, rettv, evaluate, want_string)
+char_u **arg;
+typval_T *rettv;
+int evaluate;
+int want_string UNUSED; /* after "." operator */
+{
+ long 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
+ * string and free a string that isn't there.
+ */
+ rettv->v_type = VAR_UNKNOWN;
+
+ /*
+ * Skip '!' and '-' characters. They are handled later.
+ */
+ start_leader = *arg;
+ while (**arg == '!' || **arg == '-' || **arg == '+')
+ *arg = skipwhite(*arg + 1);
+ end_leader = *arg;
+
+ switch (**arg) {
+ /*
+ * Number constant.
+ */
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ {
+ char_u *p = skipdigits(*arg + 1);
+ int get_float = FALSE;
+
+ /* We accept a float when the format matches
+ * "[0-9]\+\.[0-9]\+\([eE][+-]\?[0-9]\+\)\?". This is very
+ * strict to avoid backwards compatibility problems.
+ * Don't look for a float after the "." operator, so that
+ * ":let vers = 1.2.3" doesn't fail. */
+ if (!want_string && p[0] == '.' && vim_isdigit(p[1])) {
+ get_float = TRUE;
+ p = skipdigits(p + 2);
+ if (*p == 'e' || *p == 'E') {
+ ++p;
+ if (*p == '-' || *p == '+')
+ ++p;
+ if (!vim_isdigit(*p))
+ get_float = FALSE;
+ else
+ p = skipdigits(p + 1);
+ }
+ if (ASCII_ISALPHA(*p) || *p == '.')
+ get_float = FALSE;
+ }
+ if (get_float) {
+ float_T f;
+
+ *arg += string2float(*arg, &f);
+ if (evaluate) {
+ rettv->v_type = VAR_FLOAT;
+ rettv->vval.v_float = f;
+ }
+ } else {
+ vim_str2nr(*arg, NULL, &len, TRUE, TRUE, &n, NULL);
+ *arg += len;
+ if (evaluate) {
+ rettv->v_type = VAR_NUMBER;
+ rettv->vval.v_number = n;
+ }
+ }
+ break;
+ }
+
+ /*
+ * String constant: "string".
+ */
+ case '"': ret = get_string_tv(arg, rettv, evaluate);
+ break;
+
+ /*
+ * Literal string constant: 'str''ing'.
+ */
+ case '\'': ret = get_lit_string_tv(arg, rettv, evaluate);
+ break;
+
+ /*
+ * List: [expr, expr]
+ */
+ case '[': ret = get_list_tv(arg, rettv, evaluate);
+ break;
+
+ /*
+ * Dictionary: {key: val, key: val}
+ */
+ case '{': ret = get_dict_tv(arg, rettv, evaluate);
+ break;
+
+ /*
+ * Option value: &name
+ */
+ case '&': ret = get_option_tv(arg, rettv, evaluate);
+ break;
+
+ /*
+ * Environment variable: $VAR.
+ */
+ case '$': ret = get_env_tv(arg, rettv, evaluate);
+ break;
+
+ /*
+ * Register contents: @r.
+ */
+ case '@': ++*arg;
+ if (evaluate) {
+ rettv->v_type = VAR_STRING;
+ rettv->vval.v_string = get_reg_contents(**arg, TRUE, TRUE);
+ }
+ if (**arg != NUL)
+ ++*arg;
+ break;
+
+ /*
+ * nested expression: (expression).
+ */
+ case '(': *arg = skipwhite(*arg + 1);
+ ret = eval1(arg, rettv, evaluate); /* recursive! */
+ if (**arg == ')')
+ ++*arg;
+ else if (ret == OK) {
+ EMSG(_("E110: Missing ')'"));
+ clear_tv(rettv);
+ ret = FAIL;
+ }
+ break;
+
+ default: ret = NOTDONE;
+ break;
+ }
+
+ if (ret == NOTDONE) {
+ /*
+ * 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);
+ if (alias != NULL)
+ s = alias;
+
+ if (len <= 0)
+ ret = FAIL;
+ else {
+ if (**arg == '(') { /* recursive! */
+ /* If "s" is the name of a variable of type VAR_FUNC
+ * use its contents. */
+ s = deref_func_name(s, &len, FALSE);
+
+ /* Invoke the function. */
+ ret = get_func_tv(s, len, rettv, arg,
+ curwin->w_cursor.lnum, curwin->w_cursor.lnum,
+ &len, evaluate, NULL);
+
+ /* 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 = vim_strsave((char_u *)"");
+ rettv->v_type = VAR_FUNC;
+ }
+
+ /* 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);
+ ret = FAIL;
+ }
+ } else if (evaluate)
+ ret = get_var_tv(s, len, rettv, TRUE, FALSE);
+ else
+ ret = OK;
+ }
+ vim_free(alias);
+ }
+
+ *arg = skipwhite(*arg);
+
+ /* Handle following '[', '(' and '.' for expr[expr], expr.name,
+ * expr(expr). */
+ if (ret == OK)
+ ret = handle_subscript(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;
+ float_T f = 0.0;
+
+ if (rettv->v_type == VAR_FLOAT)
+ f = rettv->vval.v_float;
+ else
+ val = get_tv_number_chk(rettv, &error);
+ if (error) {
+ clear_tv(rettv);
+ ret = FAIL;
+ } else {
+ while (end_leader > start_leader) {
+ --end_leader;
+ if (*end_leader == '!') {
+ if (rettv->v_type == VAR_FLOAT)
+ f = !f;
+ else
+ val = !val;
+ } else if (*end_leader == '-') {
+ if (rettv->v_type == VAR_FLOAT)
+ f = -f;
+ else
+ val = -val;
+ }
+ }
+ if (rettv->v_type == VAR_FLOAT) {
+ clear_tv(rettv);
+ rettv->vval.v_float = f;
+ } else {
+ clear_tv(rettv);
+ rettv->v_type = VAR_NUMBER;
+ rettv->vval.v_number = val;
+ }
+ }
+ }
+
+ return ret;
+}
+
+/*
+ * 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(arg, rettv, evaluate, verbose)
+char_u **arg;
+typval_T *rettv;
+int evaluate;
+int verbose; /* give error messages */
+{
+ int empty1 = FALSE, empty2 = FALSE;
+ typval_T var1, var2;
+ long n1, n2 = 0;
+ long len = -1;
+ int range = FALSE;
+ char_u *s;
+ char_u *key = NULL;
+
+ if (rettv->v_type == VAR_FUNC) {
+ if (verbose)
+ EMSG(_("E695: Cannot index a Funcref"));
+ return FAIL;
+ } else if (rettv->v_type == VAR_FLOAT) {
+ if (verbose)
+ EMSG(_(e_float_as_string));
+ return FAIL;
+ }
+
+ if (**arg == '.') {
+ /*
+ * dict.name
+ */
+ key = *arg + 1;
+ for (len = 0; ASCII_ISALNUM(key[len]) || key[len] == '_'; ++len)
+ ;
+ if (len == 0)
+ return FAIL;
+ *arg = skipwhite(key + len);
+ } else {
+ /*
+ * something[idx]
+ *
+ * Get the (first) variable from inside the [].
+ */
+ *arg = skipwhite(*arg + 1);
+ 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);
+ return FAIL;
+ }
+
+ /*
+ * Get the second variable from inside the [:].
+ */
+ 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);
+ return FAIL;
+ } else if (evaluate && get_tv_string_chk(&var2) == NULL) {
+ /* not a number or string */
+ if (!empty1)
+ clear_tv(&var1);
+ clear_tv(&var2);
+ return FAIL;
+ }
+ }
+
+ /* Check for the ']'. */
+ if (**arg != ']') {
+ if (verbose)
+ EMSG(_(e_missbrac));
+ clear_tv(&var1);
+ if (range)
+ clear_tv(&var2);
+ return FAIL;
+ }
+ *arg = skipwhite(*arg + 1); /* skip the ']' */
+ }
+
+ if (evaluate) {
+ n1 = 0;
+ if (!empty1 && rettv->v_type != VAR_DICT) {
+ n1 = get_tv_number(&var1);
+ clear_tv(&var1);
+ }
+ if (range) {
+ if (empty2)
+ n2 = -1;
+ else {
+ n2 = get_tv_number(&var2);
+ clear_tv(&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. */
+ 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;
+ }
+ 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();
+ if (l == NULL)
+ return FAIL;
+ for (item = list_find(rettv->vval.v_list, n1);
+ n1 <= n2; ++n1) {
+ if (list_append_tv(l, &item->li_tv) == FAIL) {
+ list_free(l, TRUE);
+ return FAIL;
+ }
+ item = item->li_next;
+ }
+ 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;
+ }
+ {
+ dictitem_T *item;
+
+ if (len == -1) {
+ key = get_tv_string(&var1);
+ if (*key == NUL) {
+ if (verbose)
+ EMSG(_(e_emptykey));
+ clear_tv(&var1);
+ return FAIL;
+ }
+ }
+
+ item = dict_find(rettv->vval.v_dict, key, (int)len);
+
+ if (item == NULL && verbose)
+ EMSG2(_(e_dictkey), key);
+ if (len == -1)
+ clear_tv(&var1);
+ if (item == NULL)
+ return FAIL;
+
+ copy_tv(&item->di_tv, &var1);
+ clear_tv(rettv);
+ *rettv = var1;
+ }
+ break;
+ }
+ }
+
+ 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(arg, rettv, evaluate)
+char_u **arg;
+typval_T *rettv; /* when NULL, only check if option exists */
+int evaluate;
+{
+ char_u *option_end;
+ long numval;
+ char_u *stringval;
+ int opt_type;
+ int c;
+ int 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);
+ if (option_end == NULL) {
+ if (rettv != NULL)
+ EMSG2(_("E112: Option name missing: %s"), *arg);
+ return FAIL;
+ }
+
+ if (!evaluate) {
+ *arg = option_end;
+ return OK;
+ }
+
+ c = *option_end;
+ *option_end = NUL;
+ opt_type = get_option_value(*arg, &numval,
+ rettv == NULL ? NULL : &stringval, opt_flags);
+
+ if (opt_type == -3) { /* invalid name */
+ if (rettv != NULL)
+ EMSG2(_("E113: Unknown option: %s"), *arg);
+ ret = FAIL;
+ } else if (rettv != NULL) {
+ if (opt_type == -2) { /* hidden string option */
+ rettv->v_type = VAR_STRING;
+ rettv->vval.v_string = NULL;
+ } else if (opt_type == -1) { /* hidden number option */
+ rettv->v_type = VAR_NUMBER;
+ rettv->vval.v_number = 0;
+ } else if (opt_type == 1) { /* number option */
+ rettv->v_type = VAR_NUMBER;
+ rettv->vval.v_number = numval;
+ } else { /* string option */
+ rettv->v_type = VAR_STRING;
+ rettv->vval.v_string = stringval;
+ }
+ } else if (working && (opt_type == -2 || opt_type == -1))
+ ret = FAIL;
+
+ *option_end = c; /* put back for error messages */
+ *arg = option_end;
+
+ return ret;
+}
+
+/*
+ * Allocate a variable for a string constant.
+ * Return OK or FAIL.
+ */
+static int get_string_tv(arg, rettv, evaluate)
+char_u **arg;
+typval_T *rettv;
+int evaluate;
+{
+ char_u *p;
+ char_u *name;
+ int extra = 0;
+
+ /*
+ * Find the end of the string, skipping backslashed characters.
+ */
+ 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
+ * to 6 characters: reserve space for 2 extra */
+ if (*p == '<')
+ extra += 2;
+ }
+ }
+
+ if (*p != '"') {
+ EMSG2(_("E114: Missing quote: %s"), *arg);
+ return FAIL;
+ }
+
+ /* If only parsing, set *arg and return here */
+ if (!evaluate) {
+ *arg = p + 1;
+ return OK;
+ }
+
+ /*
+ * Copy the string into allocated memory, handling backslashed
+ * characters.
+ */
+ name = alloc((unsigned)(p - *arg + extra));
+ if (name == NULL)
+ return FAIL;
+ rettv->v_type = VAR_STRING;
+ rettv->vval.v_string = name;
+
+ for (p = *arg + 1; *p != NUL && *p != '"'; ) {
+ if (*p == '\\') {
+ switch (*++p) {
+ case 'b': *name++ = BS; ++p; break;
+ case 'e': *name++ = ESC; ++p; break;
+ case 'f': *name++ = FF; ++p; break;
+ case 'n': *name++ = NL; ++p; break;
+ case 'r': *name++ = CAR; ++p; break;
+ case 't': *name++ = TAB; ++p; break;
+
+ case 'X': /* hex: "\x1", "\x12" */
+ case 'x':
+ case 'u': /* Unicode: "\u0023" */
+ case 'U':
+ if (vim_isxdigit(p[1])) {
+ int n, nr;
+ int c = toupper(*p);
+
+ if (c == 'X')
+ n = 2;
+ else
+ n = 4;
+ nr = 0;
+ while (--n >= 0 && vim_isxdigit(p[1])) {
+ ++p;
+ nr = (nr << 4) + hex2nr(*p);
+ }
+ ++p;
+ /* For "\u" store the number according to
+ * 'encoding'. */
+ if (c != 'X')
+ name += (*mb_char2bytes)(nr, name);
+ else
+ *name++ = nr;
+ }
+ break;
+
+ /* octal: "\1", "\12", "\123" */
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7': *name = *p++ - '0';
+ if (*p >= '0' && *p <= '7') {
+ *name = (*name << 3) + *p++ - '0';
+ if (*p >= '0' && *p <= '7')
+ *name = (*name << 3) + *p++ - '0';
+ }
+ ++name;
+ break;
+
+ /* Special key, e.g.: "\<C-W>" */
+ case '<': extra = trans_special(&p, name, TRUE);
+ if (extra != 0) {
+ name += extra;
+ break;
+ }
+ /* FALLTHROUGH */
+
+ default: MB_COPY_CHAR(p, name);
+ break;
+ }
+ } else
+ MB_COPY_CHAR(p, name);
+
+ }
+ *name = NUL;
+ *arg = p + 1;
+
+ return OK;
+}
+
+/*
+ * Allocate a variable for a 'str''ing' constant.
+ * Return OK or FAIL.
+ */
+static int get_lit_string_tv(arg, rettv, evaluate)
+char_u **arg;
+typval_T *rettv;
+int evaluate;
+{
+ char_u *p;
+ char_u *str;
+ int reduce = 0;
+
+ /*
+ * Find the end of the string, skipping ''.
+ */
+ for (p = *arg + 1; *p != NUL; mb_ptr_adv(p)) {
+ if (*p == '\'') {
+ if (p[1] != '\'')
+ break;
+ ++reduce;
+ ++p;
+ }
+ }
+
+ if (*p != '\'') {
+ EMSG2(_("E115: Missing quote: %s"), *arg);
+ return FAIL;
+ }
+
+ /* If only parsing return after setting "*arg" */
+ if (!evaluate) {
+ *arg = p + 1;
+ return OK;
+ }
+
+ /*
+ * Copy the string into allocated memory, handling '' to ' reduction.
+ */
+ str = alloc((unsigned)((p - *arg) - reduce));
+ if (str == NULL)
+ return FAIL;
+ rettv->v_type = VAR_STRING;
+ rettv->vval.v_string = str;
+
+ for (p = *arg + 1; *p != NUL; ) {
+ if (*p == '\'') {
+ if (p[1] != '\'')
+ break;
+ ++p;
+ }
+ MB_COPY_CHAR(p, str);
+ }
+ *str = NUL;
+ *arg = p + 1;
+
+ return OK;
+}
+
+/*
+ * Allocate a variable for a List and fill it from "*arg".
+ * Return OK or FAIL.
+ */
+static int get_list_tv(arg, rettv, evaluate)
+char_u **arg;
+typval_T *rettv;
+int evaluate;
+{
+ list_T *l = NULL;
+ typval_T tv;
+ listitem_T *item;
+
+ if (evaluate) {
+ l = list_alloc();
+ if (l == NULL)
+ return FAIL;
+ }
+
+ *arg = skipwhite(*arg + 1);
+ while (**arg != ']' && **arg != NUL) {
+ if (eval1(arg, &tv, evaluate) == FAIL) /* recursive! */
+ goto failret;
+ if (evaluate) {
+ item = listitem_alloc();
+ if (item != NULL) {
+ item->li_tv = tv;
+ item->li_tv.v_lock = 0;
+ list_append(l, item);
+ } else
+ clear_tv(&tv);
+ }
+
+ if (**arg == ']')
+ break;
+ if (**arg != ',') {
+ EMSG2(_("E696: Missing comma in List: %s"), *arg);
+ goto failret;
+ }
+ *arg = skipwhite(*arg + 1);
+ }
+
+ if (**arg != ']') {
+ EMSG2(_("E697: Missing end of List ']': %s"), *arg);
+failret:
+ if (evaluate)
+ list_free(l, TRUE);
+ return FAIL;
+ }
+
+ *arg = skipwhite(*arg + 1);
+ if (evaluate) {
+ rettv->v_type = VAR_LIST;
+ rettv->vval.v_list = l;
+ ++l->lv_refcount;
+ }
+
+ return OK;
+}
+
+/*
+ * Allocate an empty header for a list.
+ * Caller should take care of the reference count.
+ */
+list_T * list_alloc() {
+ list_T *l;
+
+ l = (list_T *)alloc_clear(sizeof(list_T));
+ if (l != NULL) {
+ /* Prepend the list to the list of lists for garbage collection. */
+ if (first_list != NULL)
+ first_list->lv_used_prev = l;
+ l->lv_used_prev = NULL;
+ l->lv_used_next = first_list;
+ first_list = l;
+ }
+ return l;
+}
+
+/*
+ * Allocate an empty list for a return value.
+ * Returns OK or FAIL.
+ */
+static int rettv_list_alloc(rettv)
+typval_T *rettv;
+{
+ list_T *l = list_alloc();
+
+ if (l == NULL)
+ return FAIL;
+
+ rettv->vval.v_list = l;
+ rettv->v_type = VAR_LIST;
+ ++l->lv_refcount;
+ return OK;
+}
+
+/*
+ * Unreference a list: decrement the reference count and free it when it
+ * becomes zero.
+ */
+void list_unref(l)
+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(l, recurse)
+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);
+ vim_free(item);
+ }
+ vim_free(l);
+}
+
+/*
+ * Allocate a list item.
+ */
+listitem_T * listitem_alloc() {
+ return (listitem_T *)alloc(sizeof(listitem_T));
+}
+
+/*
+ * Free a list item. Also clears the value. Does not notify watchers.
+ */
+void listitem_free(item)
+listitem_T *item;
+{
+ clear_tv(&item->li_tv);
+ vim_free(item);
+}
+
+/*
+ * Remove a list item from a List and free it. Also clears the value.
+ */
+void listitem_remove(l, item)
+list_T *l;
+listitem_T *item;
+{
+ list_remove(l, item, item);
+ listitem_free(item);
+}
+
+/*
+ * Get the number of items in a list.
+ */
+static long list_len(l)
+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(l1, l2, ic, recursive)
+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;
+}
+
+#if defined(FEAT_RUBY) || defined(FEAT_PYTHON) || defined(FEAT_PYTHON3) \
+ || defined(FEAT_MZSCHEME) || defined(FEAT_LUA) || defined(PROTO)
+/*
+ * Return the dictitem that an entry in a hashtable points to.
+ */
+dictitem_T * dict_lookup(hi)
+hashitem_T *hi;
+{
+ return HI2DI(hi);
+}
+#endif
+
+/*
+ * Return TRUE when two dictionaries have exactly the same key/values.
+ */
+static int dict_equal(d1, d2, ic, recursive)
+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(tv1, tv2, ic, recursive)
+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;
+ }
+
+ EMSG2(_(e_intern2), "tv_equal()");
+ return TRUE;
+}
+
+/*
+ * 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(l, n)
+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(l, idx, errorp)
+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(l, idx)
+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(l, 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(l, item)
+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".
+ * Return FAIL when out of memory.
+ */
+int list_append_tv(l, tv)
+list_T *l;
+typval_T *tv;
+{
+ listitem_T *li = listitem_alloc();
+
+ if (li == NULL)
+ return FAIL;
+ copy_tv(tv, &li->li_tv);
+ list_append(l, li);
+ return OK;
+}
+
+/*
+ * Add a dictionary to a list. Used by getqflist().
+ * Return FAIL when out of memory.
+ */
+int list_append_dict(list, dict)
+list_T *list;
+dict_T *dict;
+{
+ listitem_T *li = listitem_alloc();
+
+ if (li == NULL)
+ return FAIL;
+ 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;
+ return OK;
+}
+
+/*
+ * Make a copy of "str" and append it as an item to list "l".
+ * When "len" >= 0 use "str[len]".
+ * Returns FAIL when out of memory.
+ */
+int list_append_string(l, str, len)
+list_T *l;
+char_u *str;
+int len;
+{
+ listitem_T *li = listitem_alloc();
+
+ if (li == NULL)
+ return FAIL;
+ list_append(l, li);
+ li->li_tv.v_type = VAR_STRING;
+ li->li_tv.v_lock = 0;
+ if (str == NULL)
+ li->li_tv.vval.v_string = NULL;
+ else if ((li->li_tv.vval.v_string = (len >= 0 ? vim_strnsave(str, len)
+ : vim_strsave(str))) == NULL)
+ return FAIL;
+ return OK;
+}
+
+/*
+ * Append "n" to list "l".
+ * Returns FAIL when out of memory.
+ */
+static int list_append_number(l, n)
+list_T *l;
+varnumber_T n;
+{
+ listitem_T *li;
+
+ li = listitem_alloc();
+ if (li == NULL)
+ return FAIL;
+ li->li_tv.v_type = VAR_NUMBER;
+ li->li_tv.v_lock = 0;
+ li->li_tv.vval.v_number = n;
+ list_append(l, li);
+ return OK;
+}
+
+/*
+ * Insert typval_T "tv" in list "l" before "item".
+ * If "item" is NULL append at the end.
+ * Return FAIL when out of memory.
+ */
+int list_insert_tv(l, tv, item)
+list_T *l;
+typval_T *tv;
+listitem_T *item;
+{
+ listitem_T *ni = listitem_alloc();
+
+ if (ni == NULL)
+ return FAIL;
+ copy_tv(tv, &ni->li_tv);
+ list_insert(l, ni, item);
+ return OK;
+}
+
+void list_insert(l, ni, item)
+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;
+ }
+ item->li_prev = ni;
+ ++l->lv_len;
+ }
+}
+
+/*
+ * Extend "l1" with "l2".
+ * If "bef" is NULL append at the end, otherwise insert before this item.
+ * Returns FAIL when out of memory.
+ */
+static int list_extend(l1, l2, bef)
+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)
+ if (list_insert_tv(l1, &item->li_tv, bef) == FAIL)
+ return FAIL;
+ return OK;
+}
+
+/*
+ * Concatenate lists "l1" and "l2" into a new list, stored in "tv".
+ * Return FAIL when out of memory.
+ */
+static int list_concat(l1, l2, tv)
+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(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 */
+ return list_extend(l, l2, NULL);
+}
+
+/*
+ * Make a copy of list "orig". Shallow if "deep" is FALSE.
+ * The refcount of the new list is set to 1.
+ * See item_copy() for "copyID".
+ * Returns NULL when out of memory.
+ */
+static list_T * list_copy(orig, deep, copyID)
+list_T *orig;
+int deep;
+int copyID;
+{
+ list_T *copy;
+ listitem_T *item;
+ listitem_T *ni;
+
+ if (orig == NULL)
+ return NULL;
+
+ copy = list_alloc();
+ if (copy != NULL) {
+ 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 (ni == NULL)
+ break;
+ if (deep) {
+ if (item_copy(&item->li_tv, &ni->li_tv, deep, copyID) == FAIL) {
+ vim_free(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".
+ * Does not free the listitem or the value!
+ */
+void list_remove(l, item, item2)
+list_T *l;
+listitem_T *item;
+listitem_T *item2;
+{
+ listitem_T *ip;
+
+ /* notify watchers */
+ for (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;
+ l->lv_idx_item = NULL;
+}
+
+/*
+ * Return an allocated string with the string representation of a list.
+ * May return NULL.
+ */
+static char_u * list2string(tv, copyID)
+typval_T *tv;
+int copyID;
+{
+ garray_T ga;
+
+ if (tv->vval.v_list == NULL)
+ return NULL;
+ ga_init2(&ga, (int)sizeof(char), 80);
+ ga_append(&ga, '[');
+ if (list_join(&ga, tv->vval.v_list, (char_u *)", ", FALSE, copyID) == FAIL) {
+ vim_free(ga.ga_data);
+ return NULL;
+ }
+ ga_append(&ga, ']');
+ ga_append(&ga, NUL);
+ return (char_u *)ga.ga_data;
+}
+
+typedef struct join_S {
+ char_u *s;
+ char_u *tofree;
+} join_T;
+
+static int list_join_inner(gap, l, sep, echo_style, copyID, join_gap)
+garray_T *gap; /* to store the result in */
+list_T *l;
+char_u *sep;
+int echo_style;
+int copyID;
+garray_T *join_gap; /* to keep each list item string */
+{
+ int i;
+ join_T *p;
+ int len;
+ int sumlen = 0;
+ int first = TRUE;
+ char_u *tofree;
+ char_u numbuf[NUMBUFLEN];
+ listitem_T *item;
+ char_u *s;
+
+ /* Stringify each item in the list. */
+ for (item = l->lv_first; item != NULL && !got_int; item = item->li_next) {
+ if (echo_style)
+ s = echo_string(&item->li_tv, &tofree, numbuf, copyID);
+ else
+ s = tv2string(&item->li_tv, &tofree, numbuf, copyID);
+ if (s == NULL)
+ return FAIL;
+
+ len = (int)STRLEN(s);
+ sumlen += len;
+
+ ga_grow(join_gap, 1);
+ p = ((join_T *)join_gap->ga_data) + (join_gap->ga_len++);
+ if (tofree != NULL || s != numbuf) {
+ p->s = s;
+ p->tofree = tofree;
+ } else {
+ p->s = vim_strnsave(s, len);
+ p->tofree = p->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 += (int)STRLEN(sep) * (join_gap->ga_len - 1);
+ if (ga_grow(gap, sumlen + 2) == FAIL)
+ return FAIL;
+
+ for (i = 0; i < join_gap->ga_len && !got_int; ++i) {
+ if (first)
+ first = FALSE;
+ else
+ ga_concat(gap, sep);
+ p = ((join_T *)join_gap->ga_data) + i;
+
+ if (p->s != NULL)
+ ga_concat(gap, p->s);
+ line_breakcheck();
+ }
+
+ return OK;
+}
+
+/*
+ * Join list "l" into a string in "*gap", using separator "sep".
+ * When "echo_style" is TRUE use String as echoed, otherwise as inside a List.
+ * Return FAIL or OK.
+ */
+static int list_join(gap, l, sep, echo_style, copyID)
+garray_T *gap;
+list_T *l;
+char_u *sep;
+int echo_style;
+int copyID;
+{
+ garray_T join_ga;
+ int retval;
+ join_T *p;
+ int i;
+
+ ga_init2(&join_ga, (int)sizeof(join_T), l->lv_len);
+ retval = list_join_inner(gap, l, sep, echo_style, copyID, &join_ga);
+
+ /* Dispose each item in join_ga. */
+ if (join_ga.ga_data != NULL) {
+ p = (join_T *)join_ga.ga_data;
+ for (i = 0; i < join_ga.ga_len; ++i) {
+ vim_free(p->tofree);
+ ++p;
+ }
+ ga_clear(&join_ga);
+ }
+
+ return retval;
+}
+
+/*
+ * Garbage collection for lists and dictionaries.
+ *
+ * We use reference counts to be able to free most items right away when they
+ * are no longer used. But for composite items it's possible that it becomes
+ * unused while the reference count is > 0: When there is a recursive
+ * reference. Example:
+ * :let l = [1, 2, 3]
+ * :let d = {9: l}
+ * :let l[1] = d
+ *
+ * Since this is quite unusual we handle this with garbage collection: every
+ * once in a while find out which lists and dicts are not referenced from any
+ * variable.
+ *
+ * Here is a good reference text about garbage collection (refers to Python
+ * but it applies to all reference-counting mechanisms):
+ * http://python.ca/nas/python/gc/
+ */
+
+/*
+ * Do garbage collection for lists and dicts.
+ * Return TRUE if some memory was freed.
+ */
+int garbage_collect() {
+ int copyID;
+ buf_T *buf;
+ win_T *wp;
+ int i;
+ funccall_T *fc, **pfc;
+ int did_free;
+ int did_free_funccal = FALSE;
+ tabpage_T *tp;
+
+ /* 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. */
+ current_copyID += COPYID_INC;
+ copyID = current_copyID;
+
+ /*
+ * 1. Go through all accessible variables and mark all lists and dicts
+ * with copyID.
+ */
+
+ /* Don't free variables in the previous_funccal list unless they are only
+ * referenced through previous_funccal. This must be first, because if
+ * the item is referenced elsewhere the funccal must not be freed. */
+ for (fc = previous_funccal; fc != NULL; fc = fc->caller) {
+ set_ref_in_ht(&fc->l_vars.dv_hashtab, copyID + 1);
+ set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID + 1);
+ }
+
+ /* script-local variables */
+ for (i = 1; i <= ga_scripts.ga_len; ++i)
+ set_ref_in_ht(&SCRIPT_VARS(i), copyID);
+
+ /* buffer-local variables */
+ for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+ set_ref_in_item(&buf->b_bufvar.di_tv, copyID);
+
+ /* window-local variables */
+ FOR_ALL_TAB_WINDOWS(tp, wp)
+ set_ref_in_item(&wp->w_winvar.di_tv, copyID);
+ if (aucmd_win != NULL)
+ set_ref_in_item(&aucmd_win->w_winvar.di_tv, copyID);
+
+ /* tabpage-local variables */
+ for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
+ set_ref_in_item(&tp->tp_winvar.di_tv, copyID);
+
+ /* global variables */
+ set_ref_in_ht(&globvarht, copyID);
+
+ /* function-local variables */
+ for (fc = current_funccal; fc != NULL; fc = fc->caller) {
+ set_ref_in_ht(&fc->l_vars.dv_hashtab, copyID);
+ set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID);
+ }
+
+ /* v: vars */
+ set_ref_in_ht(&vimvarht, copyID);
+
+
+
+
+ /*
+ * 2. Free lists and dictionaries that are not referenced.
+ */
+ did_free = free_unref_items(copyID);
+
+ /*
+ * 3. Check if any funccal can be freed now.
+ */
+ for (pfc = &previous_funccal; *pfc != NULL; ) {
+ if (can_free_funccal(*pfc, copyID)) {
+ fc = *pfc;
+ *pfc = fc->caller;
+ free_funccal(fc, TRUE);
+ did_free = TRUE;
+ did_free_funccal = TRUE;
+ } else
+ pfc = &(*pfc)->caller;
+ }
+ if (did_free_funccal)
+ /* When a funccal was freed some more items might be garbage
+ * collected, so run again. */
+ (void)garbage_collect();
+
+ return did_free;
+}
+
+/*
+ * Free lists and dictionaries that are no longer referenced.
+ */
+static int free_unref_items(copyID)
+int copyID;
+{
+ dict_T *dd;
+ list_T *ll;
+ int did_free = FALSE;
+
+ /*
+ * Go through the list of dicts and free items without the copyID.
+ */
+ for (dd = first_dict; dd != NULL; )
+ 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_free(dd, FALSE);
+ did_free = TRUE;
+
+ /* restart, next dict may also have been freed */
+ dd = first_dict;
+ } 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 (ll = first_list; ll != NULL; )
+ if ((ll->lv_copyID & COPYID_MASK) != (copyID & COPYID_MASK)
+ && ll->lv_watch == NULL) {
+ /* 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_free(ll, FALSE);
+ did_free = TRUE;
+
+ /* restart, next list may also have been freed */
+ ll = first_list;
+ } else
+ ll = ll->lv_used_next;
+
+ return did_free;
+}
+
+/*
+ * Mark all lists and dicts referenced through hashtab "ht" with "copyID".
+ */
+void set_ref_in_ht(ht, copyID)
+hashtab_T *ht;
+int copyID;
+{
+ int todo;
+ hashitem_T *hi;
+
+ todo = (int)ht->ht_used;
+ for (hi = ht->ht_array; todo > 0; ++hi)
+ if (!HASHITEM_EMPTY(hi)) {
+ --todo;
+ set_ref_in_item(&HI2DI(hi)->di_tv, copyID);
+ }
+}
+
+/*
+ * Mark all lists and dicts referenced through list "l" with "copyID".
+ */
+void set_ref_in_list(l, copyID)
+list_T *l;
+int copyID;
+{
+ listitem_T *li;
+
+ for (li = l->lv_first; li != NULL; li = li->li_next)
+ set_ref_in_item(&li->li_tv, copyID);
+}
+
+/*
+ * Mark all lists and dicts referenced through typval "tv" with "copyID".
+ */
+void set_ref_in_item(tv, copyID)
+typval_T *tv;
+int copyID;
+{
+ dict_T *dd;
+ list_T *ll;
+
+ switch (tv->v_type) {
+ case VAR_DICT:
+ dd = tv->vval.v_dict;
+ if (dd != NULL && dd->dv_copyID != copyID) {
+ /* Didn't see this dict yet. */
+ dd->dv_copyID = copyID;
+ set_ref_in_ht(&dd->dv_hashtab, copyID);
+ }
+ break;
+
+ case VAR_LIST:
+ ll = tv->vval.v_list;
+ if (ll != NULL && ll->lv_copyID != copyID) {
+ /* Didn't see this list yet. */
+ ll->lv_copyID = copyID;
+ set_ref_in_list(ll, copyID);
+ }
+ break;
+ }
+ return;
+}
+
+/*
+ * Allocate an empty header for a dictionary.
+ */
+dict_T * dict_alloc() {
+ dict_T *d;
+
+ d = (dict_T *)alloc(sizeof(dict_T));
+ if (d != NULL) {
+ /* 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;
+ }
+ return d;
+}
+
+/*
+ * Allocate an empty dict for a return value.
+ * Returns OK or FAIL.
+ */
+static int rettv_dict_alloc(rettv)
+typval_T *rettv;
+{
+ dict_T *d = dict_alloc();
+
+ if (d == NULL)
+ return FAIL;
+
+ rettv->vval.v_dict = d;
+ rettv->v_type = VAR_DICT;
+ ++d->dv_refcount;
+ return OK;
+}
+
+
+/*
+ * Unreference a Dictionary: decrement the reference count and free it when it
+ * becomes zero.
+ */
+void dict_unref(d)
+dict_T *d;
+{
+ 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(d, recurse)
+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);
+ 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);
+ vim_free(di);
+ --todo;
+ }
+ }
+ hash_clear(&d->dv_hashtab);
+ vim_free(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!
+ * Returns NULL when out of memory.
+ */
+dictitem_T * dictitem_alloc(key)
+char_u *key;
+{
+ dictitem_T *di;
+
+ di = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) + STRLEN(key)));
+ if (di != NULL) {
+ STRCPY(di->di_key, key);
+ di->di_flags = 0;
+ }
+ return di;
+}
+
+/*
+ * Make a copy of a Dictionary item.
+ */
+static dictitem_T * dictitem_copy(org)
+dictitem_T *org;
+{
+ dictitem_T *di;
+
+ di = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T)
+ + STRLEN(org->di_key)));
+ if (di != NULL) {
+ STRCPY(di->di_key, org->di_key);
+ di->di_flags = 0;
+ copy_tv(&org->di_tv, &di->di_tv);
+ }
+ return di;
+}
+
+/*
+ * Remove item "item" from Dictionary "dict" and free it.
+ */
+static void dictitem_remove(dict, item)
+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(item)
+dictitem_T *item;
+{
+ clear_tv(&item->di_tv);
+ vim_free(item);
+}
+
+/*
+ * Make a copy of dict "d". Shallow if "deep" is FALSE.
+ * The refcount of the new dict is set to 1.
+ * See item_copy() for "copyID".
+ * Returns NULL when out of memory.
+ */
+static dict_T * dict_copy(orig, deep, copyID)
+dict_T *orig;
+int deep;
+int copyID;
+{
+ dict_T *copy;
+ dictitem_T *di;
+ int todo;
+ hashitem_T *hi;
+
+ if (orig == NULL)
+ return NULL;
+
+ copy = dict_alloc();
+ if (copy != NULL) {
+ 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;
+
+ di = dictitem_alloc(hi->hi_key);
+ if (di == NULL)
+ break;
+ if (deep) {
+ if (item_copy(&HI2DI(hi)->di_tv, &di->di_tv, deep,
+ copyID) == FAIL) {
+ vim_free(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 out of memory and when key already exists.
+ */
+int dict_add(d, item)
+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 out of memory and when key already exists.
+ */
+int dict_add_nr_str(d, key, nr, str)
+dict_T *d;
+char *key;
+long nr;
+char_u *str;
+{
+ dictitem_T *item;
+
+ item = dictitem_alloc((char_u *)key);
+ if (item == NULL)
+ return FAIL;
+ 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 out of memory and when key already exists.
+ */
+int dict_add_list(d, key, list)
+dict_T *d;
+char *key;
+list_T *list;
+{
+ dictitem_T *item;
+
+ item = dictitem_alloc((char_u *)key);
+ if (item == NULL)
+ return FAIL;
+ 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;
+}
+
+/*
+ * Get the number of items in a Dictionary.
+ */
+static long dict_len(d)
+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(d, key, len)
+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);
+ if (akey == NULL)
+ return NULL;
+ } else {
+ /* Avoid a malloc/free by using buf[]. */
+ vim_strncpy(buf, key, len);
+ akey = buf;
+ }
+
+ hi = hash_find(&d->dv_hashtab, akey);
+ vim_free(tofree);
+ if (HASHITEM_EMPTY(hi))
+ return NULL;
+ return HI2DI(hi);
+}
+
+/*
+ * Get a string item from a dictionary.
+ * When "save" is TRUE allocate memory for it.
+ * Returns NULL if the entry doesn't exist or out of memory.
+ */
+char_u * get_dict_string(d, key, save)
+dict_T *d;
+char_u *key;
+int save;
+{
+ dictitem_T *di;
+ char_u *s;
+
+ di = dict_find(d, key, -1);
+ if (di == NULL)
+ return NULL;
+ s = get_tv_string(&di->di_tv);
+ if (save && s != NULL)
+ s = vim_strsave(s);
+ return s;
+}
+
+/*
+ * Get a number item from a dictionary.
+ * Returns 0 if the entry doesn't exist or out of memory.
+ */
+long get_dict_number(d, key)
+dict_T *d;
+char_u *key;
+{
+ dictitem_T *di;
+
+ di = dict_find(d, key, -1);
+ if (di == NULL)
+ return 0;
+ return get_tv_number(&di->di_tv);
+}
+
+/*
+ * Return an allocated string with the string representation of a Dictionary.
+ * May return NULL.
+ */
+static char_u * dict2string(tv, copyID)
+typval_T *tv;
+int copyID;
+{
+ garray_T ga;
+ int first = TRUE;
+ char_u *tofree;
+ char_u numbuf[NUMBUFLEN];
+ hashitem_T *hi;
+ char_u *s;
+ dict_T *d;
+ int todo;
+
+ if ((d = tv->vval.v_dict) == NULL)
+ return NULL;
+ ga_init2(&ga, (int)sizeof(char), 80);
+ ga_append(&ga, '{');
+
+ todo = (int)d->dv_hashtab.ht_used;
+ for (hi = d->dv_hashtab.ht_array; todo > 0 && !got_int; ++hi) {
+ if (!HASHITEM_EMPTY(hi)) {
+ --todo;
+
+ if (first)
+ first = FALSE;
+ else
+ ga_concat(&ga, (char_u *)", ");
+
+ tofree = string_quote(hi->hi_key, FALSE);
+ if (tofree != NULL) {
+ ga_concat(&ga, tofree);
+ vim_free(tofree);
+ }
+ ga_concat(&ga, (char_u *)": ");
+ s = tv2string(&HI2DI(hi)->di_tv, &tofree, numbuf, copyID);
+ if (s != NULL)
+ ga_concat(&ga, s);
+ vim_free(tofree);
+ if (s == NULL)
+ break;
+ }
+ }
+ if (todo > 0) {
+ vim_free(ga.ga_data);
+ return NULL;
+ }
+
+ ga_append(&ga, '}');
+ ga_append(&ga, NUL);
+ return (char_u *)ga.ga_data;
+}
+
+/*
+ * Allocate a variable for a Dictionary and fill it from "*arg".
+ * Return OK or FAIL. Returns NOTDONE for {expr}.
+ */
+static int get_dict_tv(arg, rettv, evaluate)
+char_u **arg;
+typval_T *rettv;
+int evaluate;
+{
+ dict_T *d = NULL;
+ typval_T tvkey;
+ typval_T tv;
+ char_u *key = NULL;
+ dictitem_T *item;
+ char_u *start = skipwhite(*arg + 1);
+ char_u buf[NUMBUFLEN];
+
+ /*
+ * First check if it's not a curly-braces thing: {expr}.
+ * Must do this without evaluating, otherwise a function may be called
+ * twice. Unfortunately this means we need to call eval1() twice for the
+ * first item.
+ * But {} is an empty Dictionary.
+ */
+ if (*start != '}') {
+ if (eval1(&start, &tv, FALSE) == FAIL) /* recursive! */
+ return FAIL;
+ if (*start == '}')
+ return NOTDONE;
+ }
+
+ if (evaluate) {
+ d = dict_alloc();
+ if (d == NULL)
+ return FAIL;
+ }
+ tvkey.v_type = VAR_UNKNOWN;
+ tv.v_type = VAR_UNKNOWN;
+
+ *arg = skipwhite(*arg + 1);
+ while (**arg != '}' && **arg != NUL) {
+ if (eval1(arg, &tvkey, evaluate) == FAIL) /* recursive! */
+ goto failret;
+ if (**arg != ':') {
+ EMSG2(_("E720: Missing colon in Dictionary: %s"), *arg);
+ clear_tv(&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);
+ goto failret;
+ }
+ }
+
+ *arg = skipwhite(*arg + 1);
+ if (eval1(arg, &tv, evaluate) == FAIL) { /* recursive! */
+ if (evaluate)
+ clear_tv(&tvkey);
+ goto failret;
+ }
+ if (evaluate) {
+ item = dict_find(d, key, -1);
+ if (item != NULL) {
+ EMSG2(_("E721: Duplicate key in Dictionary: \"%s\""), key);
+ clear_tv(&tvkey);
+ clear_tv(&tv);
+ goto failret;
+ }
+ item = dictitem_alloc(key);
+ clear_tv(&tvkey);
+ if (item != NULL) {
+ item->di_tv = tv;
+ item->di_tv.v_lock = 0;
+ if (dict_add(d, item) == FAIL)
+ dictitem_free(item);
+ }
+ }
+
+ if (**arg == '}')
+ break;
+ if (**arg != ',') {
+ EMSG2(_("E722: Missing comma in Dictionary: %s"), *arg);
+ goto failret;
+ }
+ *arg = skipwhite(*arg + 1);
+ }
+
+ if (**arg != '}') {
+ EMSG2(_("E723: Missing end of Dictionary '}': %s"), *arg);
+failret:
+ if (evaluate)
+ dict_free(d, TRUE);
+ return FAIL;
+ }
+
+ *arg = skipwhite(*arg + 1);
+ if (evaluate) {
+ rettv->v_type = VAR_DICT;
+ rettv->vval.v_dict = d;
+ ++d->dv_refcount;
+ }
+
+ return OK;
+}
+
+/*
+ * Return a string with the string representation of a variable.
+ * If the memory is allocated "tofree" is set to it, otherwise NULL.
+ * "numbuf" is used for a number.
+ * Does not put quotes around strings, as ":echo" displays values.
+ * When "copyID" is not NULL replace recursive lists and dicts with "...".
+ * May return NULL.
+ */
+static char_u * echo_string(tv, tofree, numbuf, copyID)
+typval_T *tv;
+char_u **tofree;
+char_u *numbuf;
+int copyID;
+{
+ static int recurse = 0;
+ char_u *r = NULL;
+
+ if (recurse >= DICT_MAXNEST) {
+ EMSG(_("E724: variable nested too deep for displaying"));
+ *tofree = NULL;
+ return NULL;
+ }
+ ++recurse;
+
+ switch (tv->v_type) {
+ case VAR_FUNC:
+ *tofree = NULL;
+ r = tv->vval.v_string;
+ break;
+
+ case VAR_LIST:
+ if (tv->vval.v_list == NULL) {
+ *tofree = NULL;
+ r = NULL;
+ } else if (copyID != 0 && tv->vval.v_list->lv_copyID == copyID) {
+ *tofree = NULL;
+ r = (char_u *)"[...]";
+ } else {
+ tv->vval.v_list->lv_copyID = copyID;
+ *tofree = list2string(tv, copyID);
+ r = *tofree;
+ }
+ break;
+
+ case VAR_DICT:
+ if (tv->vval.v_dict == NULL) {
+ *tofree = NULL;
+ r = NULL;
+ } else if (copyID != 0 && tv->vval.v_dict->dv_copyID == copyID) {
+ *tofree = NULL;
+ r = (char_u *)"{...}";
+ } else {
+ tv->vval.v_dict->dv_copyID = copyID;
+ *tofree = dict2string(tv, copyID);
+ r = *tofree;
+ }
+ break;
+
+ case VAR_STRING:
+ case VAR_NUMBER:
+ *tofree = NULL;
+ r = get_tv_string_buf(tv, numbuf);
+ break;
+
+ case VAR_FLOAT:
+ *tofree = NULL;
+ vim_snprintf((char *)numbuf, NUMBUFLEN, "%g", tv->vval.v_float);
+ r = numbuf;
+ break;
+
+ default:
+ EMSG2(_(e_intern2), "echo_string()");
+ *tofree = NULL;
+ }
+
+ --recurse;
+ return r;
+}
+
+/*
+ * Return a string with the string representation of a variable.
+ * If the memory is allocated "tofree" is set to it, otherwise NULL.
+ * "numbuf" is used for a number.
+ * Puts quotes around strings, so that they can be parsed back by eval().
+ * May return NULL.
+ */
+static char_u * tv2string(tv, tofree, numbuf, copyID)
+typval_T *tv;
+char_u **tofree;
+char_u *numbuf;
+int copyID;
+{
+ switch (tv->v_type) {
+ case VAR_FUNC:
+ *tofree = string_quote(tv->vval.v_string, TRUE);
+ return *tofree;
+ case VAR_STRING:
+ *tofree = string_quote(tv->vval.v_string, FALSE);
+ return *tofree;
+ case VAR_FLOAT:
+ *tofree = NULL;
+ vim_snprintf((char *)numbuf, NUMBUFLEN - 1, "%g", tv->vval.v_float);
+ return numbuf;
+ case VAR_NUMBER:
+ case VAR_LIST:
+ case VAR_DICT:
+ break;
+ default:
+ EMSG2(_(e_intern2), "tv2string()");
+ }
+ return echo_string(tv, tofree, numbuf, copyID);
+}
+
+/*
+ * Return string "str" in ' quotes, doubling ' characters.
+ * If "str" is NULL an empty string is assumed.
+ * If "function" is TRUE make it function('string').
+ */
+static char_u * string_quote(str, function)
+char_u *str;
+int function;
+{
+ unsigned len;
+ char_u *p, *r, *s;
+
+ len = (function ? 13 : 3);
+ if (str != NULL) {
+ len += (unsigned)STRLEN(str);
+ for (p = str; *p != NUL; mb_ptr_adv(p))
+ if (*p == '\'')
+ ++len;
+ }
+ s = r = alloc(len);
+ if (r != NULL) {
+ if (function) {
+ STRCPY(r, "function('");
+ r += 10;
+ } else
+ *r++ = '\'';
+ if (str != NULL)
+ for (p = str; *p != NUL; ) {
+ if (*p == '\'')
+ *r++ = '\'';
+ MB_COPY_CHAR(p, r);
+ }
+ *r++ = '\'';
+ if (function)
+ *r++ = ')';
+ *r++ = NUL;
+ }
+ return s;
+}
+
+/*
+ * Convert the string "text" to a floating point number.
+ * This uses strtod(). setlocale(LC_NUMERIC, "C") has been used to make sure
+ * this always uses a decimal point.
+ * Returns the length of the text that was consumed.
+ */
+static int string2float(text, value)
+char_u *text;
+float_T *value; /* result stored here */
+{
+ char *s = (char *)text;
+ float_T f;
+
+ f = strtod(s, &s);
+ *value = f;
+ return (int)((char_u *)s - text);
+}
+
+/*
+ * Get the value of an environment variable.
+ * "arg" is pointing to the '$'. It is advanced to after the name.
+ * If the environment variable was not set, silently assume it is empty.
+ * Always return OK.
+ */
+static int get_env_tv(arg, rettv, evaluate)
+char_u **arg;
+typval_T *rettv;
+int evaluate;
+{
+ char_u *string = NULL;
+ int len;
+ int cc;
+ char_u *name;
+ int mustfree = FALSE;
+
+ ++*arg;
+ name = *arg;
+ len = get_env_len(arg);
+ if (evaluate) {
+ if (len != 0) {
+ cc = name[len];
+ name[len] = NUL;
+ /* first try vim_getenv(), fast for normal environment vars */
+ string = vim_getenv(name, &mustfree);
+ if (string != NULL && *string != NUL) {
+ if (!mustfree)
+ string = vim_strsave(string);
+ } else {
+ if (mustfree)
+ vim_free(string);
+
+ /* next try expanding things like $VIM and ${HOME} */
+ string = expand_env_save(name - 1);
+ if (string != NULL && *string == '$') {
+ vim_free(string);
+ string = NULL;
+ }
+ }
+ name[len] = cc;
+ }
+ rettv->v_type = VAR_STRING;
+ rettv->vval.v_string = string;
+ }
+
+ 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)__ARGS((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},
+ {"append", 2, 2, f_append},
+ {"argc", 0, 0, f_argc},
+ {"argidx", 0, 0, f_argidx},
+ {"argv", 0, 1, f_argv},
+ {"asin", 1, 1, f_asin}, /* WJMc */
+ {"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},
+ {"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, 1, f_delete},
+ {"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},
+ {"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},
+ {"getcmdline", 0, 0, f_getcmdline},
+ {"getcmdpos", 0, 0, f_getcmdpos},
+ {"getcmdtype", 0, 0, f_getcmdtype},
+ {"getcwd", 0, 0, 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, 2, 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, 3, f_glob},
+ {"globpath", 2, 3, f_globpath},
+ {"has", 1, 1, f_has},
+ {"has_key", 2, 2, f_has_key},
+ {"haslocaldir", 0, 0, 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},
+ {"join", 1, 2, f_join},
+ {"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, 4, f_matchadd},
+ {"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},
+#ifdef vim_mkdir
+ {"mkdir", 1, 3, f_mkdir},
+#endif
+ {"mode", 0, 1, f_mode},
+ {"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, 19, f_printf},
+ {"pumvisible", 0, 0, f_pumvisible},
+ {"range", 1, 3, f_range},
+ {"readfile", 1, 3, f_readfile},
+ {"reltime", 0, 2, f_reltime},
+ {"reltimestr", 1, 1, f_reltimestr},
+ {"remote_expr", 2, 3, f_remote_expr},
+ {"remote_foreground", 1, 1, f_remote_foreground},
+ {"remote_peek", 1, 2, f_remote_peek},
+ {"remote_read", 1, 1, f_remote_read},
+ {"remote_send", 2, 3, f_remote_send},
+ {"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},
+ {"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},
+ {"server2client", 2, 2, f_server2client},
+ {"serverlist", 0, 0, f_serverlist},
+ {"setbufvar", 3, 3, f_setbufvar},
+ {"setcmdpos", 1, 1, f_setcmdpos},
+ {"setline", 2, 2, f_setline},
+ {"setloclist", 2, 3, f_setloclist},
+ {"setmatches", 1, 1, f_setmatches},
+ {"setpos", 2, 2, f_setpos},
+ {"setqflist", 1, 2, 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, 1, f_strchars},
+ {"strdisplaywidth", 1, 2, f_strdisplaywidth},
+#ifdef HAVE_STRFTIME
+ {"strftime", 1, 2, f_strftime},
+#endif
+ {"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, 1, 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},
+ {"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},
+ {"test", 1, 1, f_test},
+ {"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},
+ {"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},
+ {"writefile", 2, 3, f_writefile},
+ {"xor", 2, 2, f_xor},
+};
+
+
+/*
+ * Function given to ExpandGeneric() to obtain the list of internal
+ * or user defined function names.
+ */
+char_u * get_function_name(xp, idx)
+expand_T *xp;
+int idx;
+{
+ static int intidx = -1;
+ char_u *name;
+
+ if (idx == 0)
+ intidx = -1;
+ if (intidx < 0) {
+ name = get_user_func_name(xp, idx);
+ if (name != NULL)
+ return name;
+ }
+ if (++intidx < (int)(sizeof(functions) / sizeof(struct fst))) {
+ STRCPY(IObuff, functions[intidx].f_name);
+ STRCAT(IObuff, "(");
+ if (functions[intidx].f_max_argc == 0)
+ STRCAT(IObuff, ")");
+ return IObuff;
+ }
+
+ return NULL;
+}
+
+/*
+ * Function given to ExpandGeneric() to obtain the list of internal or
+ * user defined variable or function names.
+ */
+char_u * get_expr_name(xp, idx)
+expand_T *xp;
+int idx;
+{
+ static int intidx = -1;
+ char_u *name;
+
+ if (idx == 0)
+ intidx = -1;
+ if (intidx < 0) {
+ name = get_function_name(xp, idx);
+ if (name != NULL)
+ return name;
+ }
+ 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(name)
+char_u *name; /* name of the function */
+{
+ int first = 0;
+ int last = (int)(sizeof(functions) / sizeof(struct fst)) - 1;
+ int cmp;
+ int x;
+
+ /*
+ * Find the function name in the table. Binary search.
+ */
+ while (first <= last) {
+ x = first + ((unsigned)(last - first) >> 1);
+ 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;
+}
+
+/*
+ * 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(name, lenp, no_autoload)
+char_u *name;
+int *lenp;
+int no_autoload;
+{
+ dictitem_T *v;
+ int cc;
+
+ cc = name[*lenp];
+ name[*lenp] = NUL;
+ v = find_var(name, NULL, no_autoload);
+ name[*lenp] = cc;
+ if (v != NULL && v->di_tv.v_type == VAR_FUNC) {
+ if (v->di_tv.vval.v_string == NULL) {
+ *lenp = 0;
+ return (char_u *)""; /* just in case */
+ }
+ *lenp = (int)STRLEN(v->di_tv.vval.v_string);
+ return v->di_tv.vval.v_string;
+ }
+
+ return name;
+}
+
+/*
+ * Allocate a variable for the result of a function.
+ * Return OK or FAIL.
+ */
+static int get_func_tv(name, len, rettv, arg, firstline, lastline, doesrange,
+ evaluate, selfdict)
+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 */
+int evaluate;
+dict_T *selfdict; /* Dictionary for "self" */
+{
+ char_u *argp;
+ int ret = OK;
+ typval_T argvars[MAX_FUNC_ARGS + 1]; /* vars for arguments */
+ int argcount = 0; /* number of arguments found */
+
+ /*
+ * Get the arguments.
+ */
+ argp = *arg;
+ while (argcount < MAX_FUNC_ARGS) {
+ argp = skipwhite(argp + 1); /* skip the '(' or ',' */
+ if (*argp == ')' || *argp == ',' || *argp == NUL)
+ break;
+ if (eval1(&argp, &argvars[argcount], evaluate) == FAIL) {
+ ret = FAIL;
+ break;
+ }
+ ++argcount;
+ if (*argp != ',')
+ break;
+ }
+ if (*argp == ')')
+ ++argp;
+ 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)
+ emsg_funcname(N_("E740: Too many arguments for function %s"), name);
+ else
+ emsg_funcname(N_("E116: Invalid arguments for function %s"), name);
+ }
+
+ while (--argcount >= 0)
+ clear_tv(&argvars[argcount]);
+
+ *arg = skipwhite(argp);
+ return ret;
+}
+
+
+/*
+ * 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.
+ */
+static int call_func(funcname, len, rettv, argcount, argvars, firstline,
+ lastline,
+ doesrange, evaluate,
+ selfdict)
+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);
+ if (name == NULL)
+ return ret;
+
+ /*
+ * 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);
+ 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, "%ld_", (long)current_SID);
+ i = (int)STRLEN(fname_buf);
+ }
+ }
+ if (i + STRLEN(name + llen) < FLEN_FIXED) {
+ STRCPY(fname_buf + i, name + llen);
+ fname = fname_buf;
+ } else {
+ fname = alloc((unsigned)(i + STRLEN(name + llen) + 1));
+ if (fname == NULL)
+ error = ERROR_OTHER;
+ else {
+ mch_memmove(fname, fname_buf, (size_t)i);
+ STRCPY(fname + i, name + llen);
+ }
+ }
+ } else
+ fname = name;
+
+ *doesrange = FALSE;
+
+
+ /* execute the function if no errors detected and executing */
+ if (evaluate && error == ERROR_NONE) {
+ rettv->v_type = VAR_NUMBER; /* default rettv is number zero */
+ rettv->vval.v_number = 0;
+ error = ERROR_UNKNOWN;
+
+ if (!builtin_function(fname)) {
+ /*
+ * User defined function.
+ */
+ fp = find_func(fname);
+
+ /* Trigger FuncUndefined event, may load the function. */
+ if (fp == NULL
+ && apply_autocmds(EVENT_FUNCUNDEFINED,
+ fname, fname, TRUE, NULL)
+ && !aborting()) {
+ /* executed an autocommand, search for the function again */
+ fp = find_func(fname);
+ }
+ /* Try loading a package. */
+ if (fp == NULL && script_autoload(fname, TRUE) && !aborting()) {
+ /* loaded a package, search for the function again */
+ fp = find_func(fname);
+ }
+
+ if (fp != NULL) {
+ 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)
+ error = ERROR_TOOMANY;
+ else if ((fp->uf_flags & FC_DICT) && selfdict == NULL)
+ error = ERROR_DICT;
+ else {
+ /*
+ * Call the user function.
+ * Save and restore search patterns, script variables and
+ * redo buffer.
+ */
+ save_search_patterns();
+ saveRedobuff();
+ ++fp->uf_calls;
+ call_user_func(fp, argcount, argvars, rettv,
+ firstline, lastline,
+ (fp->uf_flags & FC_DICT) ? selfdict : NULL);
+ if (--fp->uf_calls <= 0 && isdigit(*fp->uf_name)
+ && fp->uf_refcount <= 0)
+ /* Function was unreferenced while being used, free it
+ * now. */
+ func_free(fp);
+ restoreRedobuff();
+ restore_search_patterns();
+ 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)
+ error = ERROR_TOOFEW;
+ else if (argcount > functions[i].f_max_argc)
+ error = ERROR_TOOMANY;
+ else {
+ argvars[argcount].v_type = VAR_UNKNOWN;
+ functions[i].f_func(argvars, rettv);
+ error = ERROR_NONE;
+ }
+ }
+ }
+ /*
+ * The function call (or "FuncUndefined" autocommand sequence) might
+ * have been aborted by an error, an interrupt, or an explicitly thrown
+ * exception that has not been caught so far. This situation can be
+ * tested for by calling aborting(). For an error in an internal
+ * function or for the "E132" error in call_user_func(), however, the
+ * throw point at which the "force_abort" flag (temporarily reset by
+ * emsg()) is normally updated has not been reached yet. We need to
+ * update that flag first to make aborting() reliable.
+ */
+ update_force_abort();
+ }
+ if (error == ERROR_NONE)
+ ret = OK;
+
+ /*
+ * Report an error unless the argument evaluation or function call has been
+ * cancelled due to an aborting error, an interrupt, or an exception.
+ */
+ if (!aborting()) {
+ switch (error) {
+ case ERROR_UNKNOWN:
+ emsg_funcname(N_("E117: Unknown function: %s"), name);
+ break;
+ case ERROR_TOOMANY:
+ emsg_funcname(e_toomanyarg, name);
+ break;
+ case ERROR_TOOFEW:
+ emsg_funcname(N_("E119: Not enough arguments for function: %s"),
+ name);
+ break;
+ case ERROR_SCRIPT:
+ emsg_funcname(N_("E120: Using <SID> not in a script context: %s"),
+ name);
+ break;
+ case ERROR_DICT:
+ emsg_funcname(N_("E725: Calling dict function without Dictionary: %s"),
+ name);
+ break;
+ }
+ }
+
+ if (fname != name && fname != fname_buf)
+ vim_free(fname);
+ vim_free(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 _().
+ */
+static void emsg_funcname(ermsg, name)
+char *ermsg;
+char_u *name;
+{
+ char_u *p;
+
+ if (*name == K_SPECIAL)
+ p = concat_str((char_u *)"<SNR>", name + 3);
+ else
+ p = name;
+ EMSG2(_(ermsg), p);
+ if (p != name)
+ vim_free(p);
+}
+
+/*
+ * Return TRUE for a non-zero Number and a non-empty String.
+ */
+static int non_zero_arg(argvars)
+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);
+}
+
+/*********************************************
+ * Implementation of the built-in functions
+ */
+
+static int get_float_arg __ARGS((typval_T *argvars, float_T *f));
+
+/*
+ * Get the float value of "argvars[0]" into "f".
+ * Returns FAIL when the argument is not a Number or Float.
+ */
+static int get_float_arg(argvars, f)
+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;
+}
+
+/*
+ * "abs(expr)" function
+ */
+static void f_abs(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ if (argvars[0].v_type == VAR_FLOAT) {
+ rettv->v_type = VAR_FLOAT;
+ rettv->vval.v_float = fabs(argvars[0].vval.v_float);
+ } else {
+ varnumber_T n;
+ int error = FALSE;
+
+ n = get_tv_number_chk(&argvars[0], &error);
+ if (error)
+ rettv->vval.v_number = -1;
+ else if (n > 0)
+ rettv->vval.v_number = n;
+ else
+ rettv->vval.v_number = -n;
+ }
+}
+
+/*
+ * "acos()" function
+ */
+static void f_acos(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ float_T f;
+
+ rettv->v_type = VAR_FLOAT;
+ if (get_float_arg(argvars, &f) == OK)
+ rettv->vval.v_float = acos(f);
+ else
+ rettv->vval.v_float = 0.0;
+}
+
+/*
+ * "add(list, item)" function
+ */
+static void f_add(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ list_T *l;
+
+ 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 *)_("add() argument"))
+ && list_append_tv(l, &argvars[1]) == OK)
+ copy_tv(&argvars[0], rettv);
+ } else
+ EMSG(_(e_listreq));
+}
+
+/*
+ * "and(expr, expr)" function
+ */
+static void f_and(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ rettv->vval.v_number = get_tv_number_chk(&argvars[0], NULL)
+ & get_tv_number_chk(&argvars[1], NULL);
+}
+
+/*
+ * "append(lnum, string/list)" function
+ */
+static void f_append(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ long lnum;
+ char_u *line;
+ list_T *l = NULL;
+ listitem_T *li = NULL;
+ typval_T *tv;
+ long added = 0;
+
+ /* When coming here from Insert mode, sync undo, so that this can be
+ * undone separately from what was previously inserted. */
+ if (u_sync_once == 2) {
+ u_sync_once = 1; /* notify that u_sync() was called */
+ u_sync(TRUE);
+ }
+
+ lnum = get_tv_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)
+ return;
+ li = l->lv_first;
+ }
+ 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 */
+ break;
+ }
+ ml_append(lnum + added, line, (colnr_T)0, FALSE);
+ ++added;
+ if (l == NULL)
+ break;
+ li = li->li_next;
+ }
+
+ appended_lines_mark(lnum, added);
+ if (curwin->w_cursor.lnum > lnum)
+ curwin->w_cursor.lnum += added;
+ } else
+ rettv->vval.v_number = 1; /* Failed */
+}
+
+/*
+ * "argc()" function
+ */
+static void f_argc(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv;
+{
+ rettv->vval.v_number = ARGCOUNT;
+}
+
+/*
+ * "argidx()" function
+ */
+static void f_argidx(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv;
+{
+ rettv->vval.v_number = curwin->w_arg_idx;
+}
+
+/*
+ * "argv(nr)" function
+ */
+static void f_argv(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ 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
+ rettv->vval.v_string = NULL;
+ rettv->v_type = VAR_STRING;
+ } else if (rettv_list_alloc(rettv) == OK)
+ for (idx = 0; idx < ARGCOUNT; ++idx)
+ list_append_string(rettv->vval.v_list,
+ alist_name(&ARGLIST[idx]), -1);
+}
+
+/*
+ * "asin()" function
+ */
+static void f_asin(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ float_T f;
+
+ rettv->v_type = VAR_FLOAT;
+ if (get_float_arg(argvars, &f) == OK)
+ rettv->vval.v_float = asin(f);
+ else
+ rettv->vval.v_float = 0.0;
+}
+
+/*
+ * "atan()" function
+ */
+static void f_atan(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ float_T f;
+
+ rettv->v_type = VAR_FLOAT;
+ if (get_float_arg(argvars, &f) == OK)
+ rettv->vval.v_float = atan(f);
+ else
+ rettv->vval.v_float = 0.0;
+}
+
+/*
+ * "atan2()" function
+ */
+static void f_atan2(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ float_T fx, fy;
+
+ rettv->v_type = VAR_FLOAT;
+ if (get_float_arg(argvars, &fx) == OK
+ && get_float_arg(&argvars[1], &fy) == OK)
+ rettv->vval.v_float = atan2(fx, fy);
+ else
+ rettv->vval.v_float = 0.0;
+}
+
+/*
+ * "browse(save, title, initdir, default)" function
+ */
+static void f_browse(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv;
+{
+ rettv->vval.v_string = NULL;
+ rettv->v_type = VAR_STRING;
+}
+
+/*
+ * "browsedir(title, initdir)" function
+ */
+static void f_browsedir(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv;
+{
+ rettv->vval.v_string = NULL;
+ rettv->v_type = VAR_STRING;
+}
+
+static buf_T *find_buffer __ARGS((typval_T *avar));
+
+/*
+ * Find a buffer by number or exact name.
+ */
+static buf_T * find_buffer(avar)
+typval_T *avar;
+{
+ buf_T *buf = NULL;
+
+ if (avar->v_type == VAR_NUMBER)
+ buf = buflist_findnr((int)avar->vval.v_number);
+ else if (avar->v_type == VAR_STRING && avar->vval.v_string != NULL) {
+ buf = buflist_findname_exp(avar->vval.v_string);
+ if (buf == NULL) {
+ /* No full path name match, try a match with a URL or a "nofile"
+ * buffer, these don't use the full path. */
+ for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+ if (buf->b_fname != NULL
+ && (path_with_url(buf->b_fname)
+ || bt_nofile(buf)
+ )
+ && STRCMP(buf->b_fname, avar->vval.v_string) == 0)
+ break;
+ }
+ }
+ return buf;
+}
+
+/*
+ * "bufexists(expr)" function
+ */
+static void f_bufexists(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ rettv->vval.v_number = (find_buffer(&argvars[0]) != NULL);
+}
+
+/*
+ * "buflisted(expr)" function
+ */
+static void f_buflisted(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ buf_T *buf;
+
+ buf = find_buffer(&argvars[0]);
+ rettv->vval.v_number = (buf != NULL && buf->b_p_bl);
+}
+
+/*
+ * "bufloaded(expr)" function
+ */
+static void f_bufloaded(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ buf_T *buf;
+
+ buf = find_buffer(&argvars[0]);
+ rettv->vval.v_number = (buf != NULL && buf->b_ml.ml_mfp != NULL);
+}
+
+static buf_T *get_buf_tv __ARGS((typval_T *tv, int curtab_only));
+
+/*
+ * Get buffer by number or pattern.
+ */
+static buf_T * get_buf_tv(tv, curtab_only)
+typval_T *tv;
+int curtab_only;
+{
+ char_u *name = tv->vval.v_string;
+ int save_magic;
+ char_u *save_cpo;
+ buf_T *buf;
+
+ if (tv->v_type == VAR_NUMBER)
+ return buflist_findnr((int)tv->vval.v_number);
+ if (tv->v_type != VAR_STRING)
+ return NULL;
+ if (name == NULL || *name == NUL)
+ return curbuf;
+ if (name[0] == '$' && name[1] == NUL)
+ return lastbuf;
+
+ /* Ignore 'magic' and 'cpoptions' here to make scripts portable */
+ save_magic = p_magic;
+ p_magic = TRUE;
+ save_cpo = p_cpo;
+ p_cpo = (char_u *)"";
+
+ buf = buflist_findnr(buflist_findpat(name, name + STRLEN(name),
+ TRUE, FALSE, curtab_only));
+
+ p_magic = save_magic;
+ p_cpo = save_cpo;
+
+ /* If not found, try expanding the name, like done for bufexists(). */
+ if (buf == NULL)
+ buf = find_buffer(tv);
+
+ return buf;
+}
+
+/*
+ * "bufname(expr)" function
+ */
+static void f_bufname(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ 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;
+}
+
+/*
+ * "bufnr(expr)" function
+ */
+static void f_bufnr(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ buf_T *buf;
+ int error = FALSE;
+ char_u *name;
+
+ (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */
+ ++emsg_off;
+ buf = get_buf_tv(&argvars[0], FALSE);
+ --emsg_off;
+
+ /* If the buffer isn't found and the second argument is not zero create a
+ * new buffer. */
+ if (buf == NULL
+ && argvars[1].v_type != VAR_UNKNOWN
+ && get_tv_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);
+
+ if (buf != NULL)
+ rettv->vval.v_number = buf->b_fnum;
+ else
+ rettv->vval.v_number = -1;
+}
+
+/*
+ * "bufwinnr(nr)" function
+ */
+static void f_bufwinnr(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ win_T *wp;
+ int winnr = 0;
+ buf_T *buf;
+
+ (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */
+ ++emsg_off;
+ buf = get_buf_tv(&argvars[0], TRUE);
+ for (wp = firstwin; wp; wp = wp->w_next) {
+ ++winnr;
+ if (wp->w_buffer == buf)
+ break;
+ }
+ rettv->vval.v_number = (wp != NULL ? winnr : -1);
+ --emsg_off;
+}
+
+/*
+ * "byte2line(byte)" function
+ */
+static void f_byte2line(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv;
+{
+ long boff = 0;
+
+ boff = get_tv_number(&argvars[0]) - 1; /* boff gets -1 on type error */
+ if (boff < 0)
+ rettv->vval.v_number = -1;
+ else
+ rettv->vval.v_number = ml_find_line_or_offset(curbuf,
+ (linenr_T)0, &boff);
+}
+
+static void byteidx(argvars, rettv, comp)
+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);
+ rettv->vval.v_number = -1;
+ if (str == NULL || idx < 0)
+ return;
+
+ t = str;
+ for (; idx > 0; idx--) {
+ if (*t == NUL) /* EOL reached */
+ return;
+ if (enc_utf8 && comp)
+ t += utf_ptr2len(t);
+ else
+ t += (*mb_ptr2len)(t);
+ }
+ rettv->vval.v_number = (varnumber_T)(t - str);
+}
+
+/*
+ * "byteidx()" function
+ */
+static void f_byteidx(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ byteidx(argvars, rettv, FALSE);
+}
+
+/*
+ * "byteidxcomp()" function
+ */
+static void f_byteidxcomp(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ byteidx(argvars, rettv, TRUE);
+}
+
+int func_call(name, args, selfdict, rettv)
+char_u *name;
+typval_T *args;
+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) {
+ EMSG(_("E699: Too many arguments"));
+ break;
+ }
+ /* 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++]);
+ }
+
+ if (item == NULL)
+ r = call_func(name, (int)STRLEN(name), rettv, argc, argv,
+ curwin->w_cursor.lnum, curwin->w_cursor.lnum,
+ &dummy, TRUE, selfdict);
+
+ /* Free the arguments. */
+ while (argc > 0)
+ clear_tv(&argv[--argc]);
+
+ return r;
+}
+
+/*
+ * "call(func, arglist)" function
+ */
+static void f_call(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ 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)
+ return;
+
+ 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 */
+
+ if (argvars[2].v_type != VAR_UNKNOWN) {
+ if (argvars[2].v_type != VAR_DICT) {
+ EMSG(_(e_dictreq));
+ return;
+ }
+ selfdict = argvars[2].vval.v_dict;
+ }
+
+ (void)func_call(func, &argvars[1], selfdict, rettv);
+}
+
+/*
+ * "ceil({float})" function
+ */
+static void f_ceil(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ float_T f;
+
+ rettv->v_type = VAR_FLOAT;
+ if (get_float_arg(argvars, &f) == OK)
+ rettv->vval.v_float = ceil(f);
+ else
+ rettv->vval.v_float = 0.0;
+}
+
+/*
+ * "changenr()" function
+ */
+static void f_changenr(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv;
+{
+ rettv->vval.v_number = curbuf->b_u_seq_cur;
+}
+
+/*
+ * "char2nr(string)" function
+ */
+static void f_char2nr(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ if (has_mbyte) {
+ int utf8 = 0;
+
+ if (argvars[1].v_type != VAR_UNKNOWN)
+ utf8 = get_tv_number_chk(&argvars[1], NULL);
+
+ 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];
+}
+
+/*
+ * "cindent(lnum)" function
+ */
+static void f_cindent(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv;
+{
+ pos_T pos;
+ linenr_T lnum;
+
+ pos = curwin->w_cursor;
+ lnum = get_tv_lnum(argvars);
+ if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) {
+ curwin->w_cursor.lnum = lnum;
+ rettv->vval.v_number = get_c_indent();
+ curwin->w_cursor = pos;
+ } else
+ rettv->vval.v_number = -1;
+}
+
+/*
+ * "clearmatches()" function
+ */
+static void f_clearmatches(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv UNUSED;
+{
+ clear_matches(curwin);
+}
+
+/*
+ * "col(string)" function
+ */
+static void f_col(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ colnr_T col = 0;
+ pos_T *fp;
+ int fnum = curbuf->b_fnum;
+
+ fp = var2fpos(&argvars[0], FALSE, &fnum);
+ if (fp != NULL && fnum == curbuf->b_fnum) {
+ if (fp->col == MAXCOL) {
+ /* '> can be MAXCOL, get the length of the line then */
+ if (fp->lnum <= curbuf->b_ml.ml_line_count)
+ col = (colnr_T)STRLEN(ml_get(fp->lnum)) + 1;
+ else
+ col = MAXCOL;
+ } else {
+ col = fp->col + 1;
+ /* col(".") when the cursor is on the NUL at the end of the line
+ * because of "coladd" can be seen as an extra column. */
+ if (virtual_active() && fp == &curwin->w_cursor) {
+ char_u *p = ml_get_cursor();
+
+ if (curwin->w_cursor.coladd >= (colnr_T)chartabsize(p,
+ curwin->w_virtcol - curwin->w_cursor.coladd)) {
+ int l;
+
+ if (*p != NUL && p[(l = (*mb_ptr2len)(p))] == NUL)
+ col += l;
+ }
+ }
+ }
+ }
+ rettv->vval.v_number = col;
+}
+
+/*
+ * "complete()" function
+ */
+static void f_complete(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv UNUSED;
+{
+ int startcol;
+
+ if ((State & INSERT) == 0) {
+ EMSG(_("E785: complete() can only be used in Insert mode"));
+ return;
+ }
+
+ /* Check for undo allowed here, because if something was already inserted
+ * the line was already saved for undo and this check isn't done. */
+ if (!undo_allowed())
+ return;
+
+ if (argvars[1].v_type != VAR_LIST || argvars[1].vval.v_list == NULL) {
+ EMSG(_(e_invarg));
+ return;
+ }
+
+ startcol = get_tv_number_chk(&argvars[0], NULL);
+ if (startcol <= 0)
+ return;
+
+ set_completion(startcol - 1, argvars[1].vval.v_list);
+}
+
+/*
+ * "complete_add()" function
+ */
+static void f_complete_add(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ rettv->vval.v_number = ins_compl_add_tv(&argvars[0], 0);
+}
+
+/*
+ * "complete_check()" function
+ */
+static void f_complete_check(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv;
+{
+ int saved = RedrawingDisabled;
+
+ RedrawingDisabled = 0;
+ ins_compl_check_keys(0);
+ rettv->vval.v_number = compl_interrupted;
+ RedrawingDisabled = saved;
+}
+
+/*
+ * "confirm(message, buttons[, default [, type]])" function
+ */
+static void f_confirm(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv UNUSED;
+{
+ char_u *message;
+ char_u *buttons = NULL;
+ char_u buf[NUMBUFLEN];
+ char_u buf2[NUMBUFLEN];
+ int def = 1;
+ int type = VIM_GENERIC;
+ char_u *typestr;
+ int error = FALSE;
+
+ message = get_tv_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;
+ if (argvars[2].v_type != VAR_UNKNOWN) {
+ def = get_tv_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 {
+ 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;
+ }
+ }
+ }
+ }
+ }
+
+ if (buttons == NULL || *buttons == NUL)
+ buttons = (char_u *)_("&Ok");
+
+ if (!error)
+ rettv->vval.v_number = do_dialog(type, NULL, message, buttons,
+ def, NULL, FALSE);
+}
+
+/*
+ * "copy()" function
+ */
+static void f_copy(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ item_copy(&argvars[0], rettv, FALSE, 0);
+}
+
+/*
+ * "cos()" function
+ */
+static void f_cos(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ float_T f;
+
+ rettv->v_type = VAR_FLOAT;
+ if (get_float_arg(argvars, &f) == OK)
+ rettv->vval.v_float = cos(f);
+ else
+ rettv->vval.v_float = 0.0;
+}
+
+/*
+ * "cosh()" function
+ */
+static void f_cosh(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ float_T f;
+
+ rettv->v_type = VAR_FLOAT;
+ if (get_float_arg(argvars, &f) == OK)
+ rettv->vval.v_float = cosh(f);
+ else
+ rettv->vval.v_float = 0.0;
+}
+
+/*
+ * "count()" function
+ */
+static void f_count(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ long n = 0;
+ int ic = FALSE;
+
+ 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;
+ 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);
+ if (!error) {
+ li = 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;
+ }
+ } else if (argvars[0].v_type == VAR_DICT) {
+ int todo;
+ dict_T *d;
+ 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)
+ 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;
+ }
+ }
+ }
+ } else
+ EMSG2(_(e_listdictarg), "count()");
+ rettv->vval.v_number = n;
+}
+
+/*
+ * "cscope_connection([{num} , {dbpath} [, {prepend}]])" function
+ *
+ * Checks the existence of a cscope connection.
+ */
+static void f_cscope_connection(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv UNUSED;
+{
+ int num = 0;
+ char_u *dbpath = NULL;
+ char_u *prepend = NULL;
+ char_u 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);
+ }
+
+ rettv->vval.v_number = cs_connection(num, dbpath, prepend);
+}
+
+/*
+ * "cursor(lnum, col)" function
+ *
+ * Moves the cursor to the specified line and column.
+ * Returns 0 when the position could be set, -1 otherwise.
+ */
+static void f_cursor(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ long line, col;
+ long coladd = 0;
+
+ rettv->vval.v_number = -1;
+ if (argvars[1].v_type == VAR_UNKNOWN) {
+ pos_T pos;
+
+ if (list2fpos(argvars, &pos, NULL) == FAIL)
+ return;
+ line = pos.lnum;
+ col = pos.col;
+ coladd = pos.coladd;
+ } else {
+ line = get_tv_lnum(argvars);
+ col = get_tv_number_chk(&argvars[1], NULL);
+ if (argvars[2].v_type != VAR_UNKNOWN)
+ coladd = get_tv_number_chk(&argvars[2], NULL);
+ }
+ if (line < 0 || col < 0
+ || coladd < 0
+ )
+ return; /* type error; errmsg already given */
+ if (line > 0)
+ curwin->w_cursor.lnum = line;
+ if (col > 0)
+ curwin->w_cursor.col = col - 1;
+ curwin->w_cursor.coladd = coladd;
+
+ /* Make sure the cursor is in a valid position. */
+ check_cursor();
+ /* Correct cursor for multi-byte character. */
+ if (has_mbyte)
+ mb_adjust_cursor();
+
+ curwin->w_set_curswant = TRUE;
+ rettv->vval.v_number = 0;
+}
+
+/*
+ * "deepcopy()" function
+ */
+static void f_deepcopy(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ int noref = 0;
+
+ if (argvars[1].v_type != VAR_UNKNOWN)
+ noref = get_tv_number_chk(&argvars[1], NULL);
+ if (noref < 0 || noref > 1)
+ EMSG(_(e_invarg));
+ else {
+ current_copyID += COPYID_INC;
+ item_copy(&argvars[0], rettv, TRUE, noref == 0 ? current_copyID : 0);
+ }
+}
+
+/*
+ * "delete()" function
+ */
+static void f_delete(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ if (check_restricted() || check_secure())
+ rettv->vval.v_number = -1;
+ else
+ rettv->vval.v_number = mch_remove(get_tv_string(&argvars[0]));
+}
+
+/*
+ * "did_filetype()" function
+ */
+static void f_did_filetype(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv UNUSED;
+{
+ rettv->vval.v_number = did_filetype;
+}
+
+/*
+ * "diff_filler()" function
+ */
+static void f_diff_filler(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv UNUSED;
+{
+ rettv->vval.v_number = diff_check_fill(curwin, get_tv_lnum(argvars));
+}
+
+/*
+ * "diff_hlID()" function
+ */
+static void f_diff_hlID(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv UNUSED;
+{
+ linenr_T lnum = get_tv_lnum(argvars);
+ static linenr_T prev_lnum = 0;
+ static int changedtick = 0;
+ static int fnum = 0;
+ static int change_start = 0;
+ static int change_end = 0;
+ static hlf_T hlID = (hlf_T)0;
+ int filler_lines;
+ int col;
+
+ if (lnum < 0) /* ignore type error in {lnum} arg */
+ lnum = 0;
+ if (lnum != prev_lnum
+ || changedtick != curbuf->b_changedtick
+ || fnum != curbuf->b_fnum) {
+ /* New line, buffer, change: need to get the values. */
+ filler_lines = diff_check(curwin, lnum);
+ if (filler_lines < 0) {
+ if (filler_lines == -1) {
+ change_start = MAXCOL;
+ change_end = -1;
+ if (diff_find_change(curwin, lnum, &change_start, &change_end))
+ hlID = HLF_ADD; /* added line */
+ else
+ hlID = HLF_CHD; /* changed line */
+ } else
+ hlID = HLF_ADD; /* added line */
+ } else
+ hlID = (hlf_T)0;
+ prev_lnum = lnum;
+ changedtick = curbuf->b_changedtick;
+ 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 */
+ }
+ rettv->vval.v_number = hlID == (hlf_T)0 ? 0 : (int)hlID;
+}
+
+/*
+ * "empty({expr})" function
+ */
+static void f_empty(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ int n;
+
+ 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;
+ default:
+ EMSG2(_(e_intern2), "f_empty()");
+ n = 0;
+ }
+
+ rettv->vval.v_number = n;
+}
+
+/*
+ * "escape({string}, {chars})" function
+ */
+static void f_escape(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ char_u buf[NUMBUFLEN];
+
+ rettv->vval.v_string = vim_strsave_escaped(get_tv_string(&argvars[0]),
+ get_tv_string_buf(&argvars[1], buf));
+ rettv->v_type = VAR_STRING;
+}
+
+/*
+ * "eval()" function
+ */
+static void f_eval(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ char_u *s;
+
+ s = get_tv_string_chk(&argvars[0]);
+ if (s != NULL)
+ s = skipwhite(s);
+
+ if (s == NULL || eval1(&s, rettv, TRUE) == FAIL) {
+ rettv->v_type = VAR_NUMBER;
+ rettv->vval.v_number = 0;
+ } else if (*s != NUL)
+ EMSG(_(e_trailing));
+}
+
+/*
+ * "eventhandler()" function
+ */
+static void f_eventhandler(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv;
+{
+ rettv->vval.v_number = vgetc_busy;
+}
+
+/*
+ * "executable()" function
+ */
+static void f_executable(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ rettv->vval.v_number = mch_can_exe(get_tv_string(&argvars[0]));
+}
+
+/*
+ * "exists()" function
+ */
+static void f_exists(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ char_u *p;
+ char_u *name;
+ int n = FALSE;
+ int len = 0;
+
+ p = get_tv_string(&argvars[0]);
+ if (*p == '$') { /* environment variable */
+ /* first try "normal" environment variables (fast) */
+ if (mch_getenv(p + 1) != NULL)
+ n = TRUE;
+ else {
+ /* try expanding things like $VIM and ${HOME} */
+ p = expand_env_save(p);
+ if (p != NULL && *p != '$')
+ n = TRUE;
+ vim_free(p);
+ }
+ } 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 == ':') {
+ n = cmd_exists(p + 1);
+ } else if (*p == '#') {
+ if (p[1] == '#')
+ n = autocmd_supported(p + 2);
+ else
+ n = au_exists(p + 1);
+ } else { /* internal variable */
+ char_u *tofree;
+ typval_T tv;
+
+ /* get_name_len() takes care of expanding curly braces */
+ name = p;
+ len = get_name_len(&p, &tofree, TRUE, FALSE);
+ if (len > 0) {
+ if (tofree != NULL)
+ name = tofree;
+ n = (get_var_tv(name, len, &tv, 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);
+ }
+ }
+ if (*p != NUL)
+ n = FALSE;
+
+ vim_free(tofree);
+ }
+
+ rettv->vval.v_number = n;
+}
+
+/*
+ * "exp()" function
+ */
+static void f_exp(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ float_T f;
+
+ rettv->v_type = VAR_FLOAT;
+ if (get_float_arg(argvars, &f) == OK)
+ rettv->vval.v_float = exp(f);
+ else
+ rettv->vval.v_float = 0.0;
+}
+
+/*
+ * "expand()" function
+ */
+static void f_expand(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ char_u *s;
+ int len;
+ char_u *errormsg;
+ int options = WILD_SILENT|WILD_USE_NL|WILD_LIST_NOTFOUND;
+ expand_T xpc;
+ int 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)
+ && !error) {
+ rettv->v_type = VAR_LIST;
+ rettv->vval.v_list = NULL;
+ }
+
+ s = get_tv_string(&argvars[0]);
+ if (*s == '%' || *s == '#' || *s == '<') {
+ ++emsg_off;
+ result = eval_vars(s, s, &len, NULL, &errormsg, NULL);
+ --emsg_off;
+ if (rettv->v_type == VAR_LIST) {
+ if (rettv_list_alloc(rettv) != FAIL && result != NULL)
+ list_append_string(rettv->vval.v_list, result, -1);
+ else
+ vim_free(result);
+ } else
+ rettv->vval.v_string = result;
+ } else {
+ /* 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))
+ options |= WILD_KEEP_ALL;
+ if (!error) {
+ ExpandInit(&xpc);
+ xpc.xp_context = EXPAND_FILES;
+ if (p_wic)
+ options += WILD_ICASE;
+ if (rettv->v_type == VAR_STRING)
+ rettv->vval.v_string = ExpandOne(&xpc, s, NULL,
+ options, WILD_ALL);
+ else if (rettv_list_alloc(rettv) != FAIL) {
+ int i;
+
+ ExpandOne(&xpc, s, NULL, options, WILD_ALL_KEEP);
+ for (i = 0; i < xpc.xp_numfiles; i++)
+ list_append_string(rettv->vval.v_list, xpc.xp_files[i], -1);
+ ExpandCleanup(&xpc);
+ }
+ } 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(d1, d2, action)
+dict_T *d1;
+dict_T *d2;
+char_u *action;
+{
+ dictitem_T *di1;
+ hashitem_T *hi2;
+ int todo;
+
+ 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 (di1 != NULL && dict_add(d1, di1) == FAIL)
+ dictitem_free(di1);
+ } else if (*action == 'e') {
+ EMSG2(_("E737: Key already exists: %s"), hi2->hi_key);
+ break;
+ } else if (*action == 'f' && HI2DI(hi2) != di1) {
+ clear_tv(&di1->di_tv);
+ copy_tv(&HI2DI(hi2)->di_tv, &di1->di_tv);
+ }
+ }
+ }
+}
+
+/*
+ * "extend(list, list [, idx])" function
+ * "extend(dict, dict [, action])" function
+ */
+static void f_extend(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ char *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;
+
+ l1 = argvars[0].vval.v_list;
+ l2 = argvars[1].vval.v_list;
+ if (l1 != NULL && !tv_check_lock(l1->lv_lock, (char_u *)_(arg_errmsg))
+ && l2 != NULL) {
+ if (argvars[2].v_type != VAR_UNKNOWN) {
+ before = get_tv_number_chk(&argvars[2], &error);
+ if (error)
+ return; /* type error; errmsg already given */
+
+ if (before == l1->lv_len)
+ item = NULL;
+ else {
+ item = list_find(l1, before);
+ if (item == NULL) {
+ EMSGN(_(e_listidx), before);
+ return;
+ }
+ }
+ } else
+ item = NULL;
+ list_extend(l1, l2, item);
+
+ copy_tv(&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, (char_u *)_(arg_errmsg))
+ && d2 != NULL) {
+ /* Check the third argument. */
+ if (argvars[2].v_type != VAR_UNKNOWN) {
+ static char *(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)
+ break;
+ if (i == 3) {
+ EMSG2(_(e_invarg2), action);
+ return;
+ }
+ } else
+ action = (char_u *)"force";
+
+ dict_extend(d1, d2, action);
+
+ copy_tv(&argvars[0], rettv);
+ }
+ } else
+ EMSG2(_(e_listdictarg), "extend()");
+}
+
+/*
+ * "feedkeys()" function
+ */
+static void f_feedkeys(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv UNUSED;
+{
+ int remap = TRUE;
+ char_u *keys, *flags;
+ char_u nbuf[NUMBUFLEN];
+ int typed = FALSE;
+ char_u *keys_esc;
+
+ /* 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);
+ for (; *flags != NUL; ++flags) {
+ switch (*flags) {
+ case 'n': remap = FALSE; break;
+ case 'm': remap = TRUE; break;
+ case 't': typed = TRUE; break;
+ }
+ }
+ }
+
+ /* Need to escape K_SPECIAL and CSI before putting the string in the
+ * typeahead buffer. */
+ keys_esc = vim_strsave_escape_csi(keys);
+ if (keys_esc != NULL) {
+ ins_typebuf(keys_esc, (remap ? REMAP_YES : REMAP_NONE),
+ typebuf.tb_len, !typed, FALSE);
+ vim_free(keys_esc);
+ if (vgetc_busy)
+ typebuf_was_filled = TRUE;
+ }
+ }
+}
+
+/*
+ * "filereadable()" function
+ */
+static void f_filereadable(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ int fd;
+ char_u *p;
+ int n;
+
+#ifndef O_NONBLOCK
+# define O_NONBLOCK 0
+#endif
+ p = get_tv_string(&argvars[0]);
+ if (*p && !mch_isdir(p) && (fd = mch_open((char *)p,
+ O_RDONLY | O_NONBLOCK, 0)) >= 0) {
+ n = TRUE;
+ close(fd);
+ } else
+ n = FALSE;
+
+ rettv->vval.v_number = n;
+}
+
+/*
+ * Return 0 for not writable, 1 for writable file, 2 for a dir which we have
+ * rights to write into.
+ */
+static void f_filewritable(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ rettv->vval.v_number = filewritable(get_tv_string(&argvars[0]));
+}
+
+static void findfilendir __ARGS((typval_T *argvars, typval_T *rettv,
+ int find_what));
+
+static void findfilendir(argvars, rettv, find_what)
+typval_T *argvars UNUSED;
+typval_T *rettv;
+int find_what UNUSED;
+{
+ 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];
+ int count = 1;
+ int first = TRUE;
+ int error = FALSE;
+
+ rettv->vval.v_string = NULL;
+ rettv->v_type = VAR_STRING;
+
+ fname = get_tv_string(&argvars[0]);
+
+ 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;
+
+ if (argvars[2].v_type != VAR_UNKNOWN)
+ count = get_tv_number_chk(&argvars[2], &error);
+ }
+ }
+
+ if (count < 0 && rettv_list_alloc(rettv) == FAIL)
+ error = TRUE;
+
+ if (*fname != NUL && !error) {
+ do {
+ if (rettv->v_type == VAR_STRING || rettv->v_type == VAR_LIST)
+ vim_free(fresult);
+ fresult = find_file_in_path_option(first ? fname : NULL,
+ first ? (int)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);
+
+ } while ((rettv->v_type == VAR_LIST || --count > 0) && fresult != NULL);
+ }
+
+ if (rettv->v_type == VAR_STRING)
+ rettv->vval.v_string = fresult;
+}
+
+static void filter_map __ARGS((typval_T *argvars, typval_T *rettv, int map));
+static int filter_map_one __ARGS((typval_T *tv, char_u *expr, int map,
+ int *remp));
+
+/*
+ * Implementation of map() and filter().
+ */
+static void filter_map(argvars, rettv, map)
+typval_T *argvars;
+typval_T *rettv;
+int map;
+{
+ char_u buf[NUMBUFLEN];
+ char_u *expr;
+ listitem_T *li, *nli;
+ list_T *l = NULL;
+ dictitem_T *di;
+ hashtab_T *ht;
+ hashitem_T *hi;
+ dict_T *d = NULL;
+ typval_T save_val;
+ typval_T save_key;
+ int rem;
+ int todo;
+ char_u *ermsg = (char_u *)(map ? "map()" : "filter()");
+ char *arg_errmsg = (map ? N_("map() argument")
+ : N_("filter() argument"));
+ int save_did_emsg;
+ int idx = 0;
+
+ if (argvars[0].v_type == VAR_LIST) {
+ if ((l = argvars[0].vval.v_list) == NULL
+ || tv_check_lock(l->lv_lock, (char_u *)_(arg_errmsg)))
+ return;
+ } else if (argvars[0].v_type == VAR_DICT) {
+ if ((d = argvars[0].vval.v_dict) == NULL
+ || tv_check_lock(d->dv_lock, (char_u *)_(arg_errmsg)))
+ return;
+ } else {
+ EMSG2(_(e_listdictarg), ermsg);
+ 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) {
+ 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. */
+ save_did_emsg = did_emsg;
+ did_emsg = FALSE;
+
+ prepare_vimvar(VV_KEY, &save_key);
+ if (argvars[0].v_type == VAR_DICT) {
+ vimvars[VV_KEY].vv_type = VAR_STRING;
+
+ ht = &d->dv_hashtab;
+ hash_lock(ht);
+ todo = (int)ht->ht_used;
+ for (hi = ht->ht_array; todo > 0; ++hi) {
+ if (!HASHITEM_EMPTY(hi)) {
+ --todo;
+ di = HI2DI(hi);
+ if (tv_check_lock(di->di_tv.v_lock,
+ (char_u *)_(arg_errmsg)))
+ break;
+ vimvars[VV_KEY].vv_str = vim_strsave(di->di_key);
+ if (filter_map_one(&di->di_tv, expr, map, &rem) == FAIL
+ || did_emsg)
+ break;
+ if (!map && rem)
+ dictitem_remove(d, di);
+ clear_tv(&vimvars[VV_KEY].vv_tv);
+ }
+ }
+ hash_unlock(ht);
+ } else {
+ vimvars[VV_KEY].vv_type = VAR_NUMBER;
+
+ for (li = l->lv_first; li != NULL; li = nli) {
+ if (tv_check_lock(li->li_tv.v_lock, (char_u *)_(arg_errmsg)))
+ break;
+ nli = li->li_next;
+ vimvars[VV_KEY].vv_nr = idx;
+ if (filter_map_one(&li->li_tv, expr, map, &rem) == FAIL
+ || did_emsg)
+ break;
+ if (!map && rem)
+ listitem_remove(l, li);
+ ++idx;
+ }
+ }
+
+ restore_vimvar(VV_KEY, &save_key);
+ restore_vimvar(VV_VAL, &save_val);
+
+ did_emsg |= save_did_emsg;
+ }
+
+ copy_tv(&argvars[0], rettv);
+}
+
+static int filter_map_one(tv, expr, map, remp)
+typval_T *tv;
+char_u *expr;
+int map;
+int *remp;
+{
+ typval_T rettv;
+ char_u *s;
+ int retval = FAIL;
+
+ 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);
+ goto theend;
+ }
+ if (map) {
+ /* map(): replace the list item value */
+ clear_tv(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)
+ goto theend;
+ }
+ retval = OK;
+theend:
+ clear_tv(&vimvars[VV_VAL].vv_tv);
+ return retval;
+}
+
+/*
+ * "filter()" function
+ */
+static void f_filter(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ filter_map(argvars, rettv, FALSE);
+}
+
+/*
+ * "finddir({fname}[, {path}[, {count}]])" function
+ */
+static void f_finddir(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ findfilendir(argvars, rettv, FINDFILE_DIR);
+}
+
+/*
+ * "findfile({fname}[, {path}[, {count}]])" function
+ */
+static void f_findfile(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ findfilendir(argvars, rettv, FINDFILE_FILE);
+}
+
+/*
+ * "float2nr({float})" function
+ */
+static void f_float2nr(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ 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
+ rettv->vval.v_number = (varnumber_T)f;
+ }
+}
+
+/*
+ * "floor({float})" function
+ */
+static void f_floor(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ float_T f;
+
+ rettv->v_type = VAR_FLOAT;
+ if (get_float_arg(argvars, &f) == OK)
+ rettv->vval.v_float = floor(f);
+ else
+ rettv->vval.v_float = 0.0;
+}
+
+/*
+ * "fmod()" function
+ */
+static void f_fmod(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ float_T fx, fy;
+
+ rettv->v_type = VAR_FLOAT;
+ if (get_float_arg(argvars, &fx) == OK
+ && get_float_arg(&argvars[1], &fy) == OK)
+ rettv->vval.v_float = fmod(fx, fy);
+ else
+ rettv->vval.v_float = 0.0;
+}
+
+/*
+ * "fnameescape({string})" function
+ */
+static void f_fnameescape(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ rettv->vval.v_string = vim_strsave_fnameescape(
+ get_tv_string(&argvars[0]), FALSE);
+ rettv->v_type = VAR_STRING;
+}
+
+/*
+ * "fnamemodify({fname}, {mods})" function
+ */
+static void f_fnamemodify(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ char_u *fname;
+ char_u *mods;
+ int usedlen = 0;
+ int 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)
+ fname = NULL;
+ else {
+ len = (int)STRLEN(fname);
+ (void)modify_fname(mods, &usedlen, &fname, &fbuf, &len);
+ }
+
+ rettv->v_type = VAR_STRING;
+ if (fname == NULL)
+ rettv->vval.v_string = NULL;
+ else
+ rettv->vval.v_string = vim_strnsave(fname, len);
+ vim_free(fbuf);
+}
+
+static void foldclosed_both __ARGS((typval_T *argvars, typval_T *rettv, int end));
+
+/*
+ * "foldclosed()" function
+ */
+static void foldclosed_both(argvars, rettv, end)
+typval_T *argvars UNUSED;
+typval_T *rettv;
+int end UNUSED;
+{
+ linenr_T lnum;
+ linenr_T first, last;
+
+ lnum = get_tv_lnum(argvars);
+ if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) {
+ if (hasFoldingWin(curwin, lnum, &first, &last, FALSE, NULL)) {
+ if (end)
+ rettv->vval.v_number = (varnumber_T)last;
+ else
+ rettv->vval.v_number = (varnumber_T)first;
+ return;
+ }
+ }
+ rettv->vval.v_number = -1;
+}
+
+/*
+ * "foldclosed()" function
+ */
+static void f_foldclosed(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ foldclosed_both(argvars, rettv, FALSE);
+}
+
+/*
+ * "foldclosedend()" function
+ */
+static void f_foldclosedend(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ foldclosed_both(argvars, rettv, TRUE);
+}
+
+/*
+ * "foldlevel()" function
+ */
+static void f_foldlevel(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv UNUSED;
+{
+ linenr_T lnum;
+
+ lnum = get_tv_lnum(argvars);
+ if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count)
+ rettv->vval.v_number = foldLevel(lnum);
+}
+
+/*
+ * "foldtext()" function
+ */
+static void f_foldtext(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv;
+{
+ linenr_T lnum;
+ char_u *s;
+ char_u *r;
+ 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))
+ break;
+ ++lnum;
+ }
+
+ /* Find interesting text in this line. */
+ s = skipwhite(ml_get(lnum));
+ /* 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) {
+ s = skipwhite(ml_get(lnum + 1));
+ if (*s == '*')
+ s = skipwhite(s + 1);
+ }
+ }
+ txt = _("+-%s%3ld lines: ");
+ r = alloc((unsigned)(STRLEN(txt)
+ + STRLEN(vimvars[VV_FOLDDASHES].vv_str) /* for %s */
+ + 20 /* for %3ld */
+ + STRLEN(s))); /* concatenated */
+ if (r != NULL) {
+ 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));
+ len = (int)STRLEN(r);
+ STRCAT(r, s);
+ /* remove 'foldmarker' and 'commentstring' */
+ foldtext_cleanup(r + len);
+ rettv->vval.v_string = r;
+ }
+ }
+}
+
+/*
+ * "foldtextresult(lnum)" function
+ */
+static void f_foldtextresult(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv;
+{
+ linenr_T lnum;
+ char_u *text;
+ char_u buf[51];
+ foldinfo_T foldinfo;
+ int fold_count;
+
+ 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)
+ 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 = vim_strsave(text);
+ rettv->vval.v_string = text;
+ }
+}
+
+/*
+ * "foreground()" function
+ */
+static void f_foreground(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv UNUSED;
+{
+}
+
+/*
+ * "function()" function
+ */
+static void f_function(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ char_u *s;
+
+ s = get_tv_string(&argvars[0]);
+ if (s == NULL || *s == NUL || VIM_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 {
+ 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>%ld_", (long)current_SID);
+ rettv->vval.v_string =
+ alloc((int)(STRLEN(sid_buf) + STRLEN(s + off) + 1));
+ if (rettv->vval.v_string != NULL) {
+ 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;
+ }
+}
+
+/*
+ * "garbagecollect()" function
+ */
+static void f_garbagecollect(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv UNUSED;
+{
+ /* 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 && get_tv_number(&argvars[0]) == 1)
+ garbage_collect_at_exit = TRUE;
+}
+
+/*
+ * "get()" function
+ */
+static void f_get(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ listitem_T *li;
+ list_T *l;
+ dictitem_T *di;
+ dict_T *d;
+ typval_T *tv = NULL;
+
+ if (argvars[0].v_type == VAR_LIST) {
+ if ((l = argvars[0].vval.v_list) != NULL) {
+ int error = FALSE;
+
+ li = list_find(l, get_tv_number_chk(&argvars[1], &error));
+ if (!error && li != NULL)
+ tv = &li->li_tv;
+ }
+ } 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)
+ tv = &di->di_tv;
+ }
+ } 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);
+}
+
+static void get_buffer_lines __ARGS((buf_T *buf, linenr_T start, linenr_T end,
+ int retlist,
+ typval_T *rettv));
+
+/*
+ * Get line or list of lines from buffer "buf" into "rettv".
+ * Return a range (from start to end) of lines in rettv from the specified
+ * buffer.
+ * If 'retlist' is TRUE, then the lines are returned as a Vim List.
+ */
+static void get_buffer_lines(buf, start, end, retlist, rettv)
+buf_T *buf;
+linenr_T start;
+linenr_T end;
+int retlist;
+typval_T *rettv;
+{
+ char_u *p;
+
+ rettv->v_type = VAR_STRING;
+ rettv->vval.v_string = NULL;
+ if (retlist && rettv_list_alloc(rettv) == FAIL)
+ return;
+
+ if (buf == NULL || buf->b_ml.ml_mfp == NULL || start < 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)
+ start = 1;
+ if (end > buf->b_ml.ml_line_count)
+ end = buf->b_ml.ml_line_count;
+ while (start <= end)
+ if (list_append_string(rettv->vval.v_list,
+ ml_get_buf(buf, start++, FALSE), -1) == FAIL)
+ break;
+ }
+}
+
+/*
+ * "getbufline()" function
+ */
+static void f_getbufline(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ linenr_T lnum;
+ linenr_T end;
+ buf_T *buf;
+
+ (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */
+ ++emsg_off;
+ buf = get_buf_tv(&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);
+
+ get_buffer_lines(buf, lnum, end, TRUE, rettv);
+}
+
+/*
+ * "getbufvar()" function
+ */
+static void f_getbufvar(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ 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);
+
+ rettv->v_type = VAR_STRING;
+ rettv->vval.v_string = NULL;
+
+ if (buf != NULL && varname != NULL) {
+ /* set curbuf to be our buf, temporarily */
+ 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;
+ } 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);
+ if (v != NULL) {
+ copy_tv(&v->di_tv, rettv);
+ done = TRUE;
+ }
+ }
+
+ /* restore previous notion of curbuf */
+ curbuf = save_curbuf;
+ }
+
+ if (!done && argvars[2].v_type != VAR_UNKNOWN)
+ /* use the default value */
+ copy_tv(&argvars[2], rettv);
+
+ --emsg_off;
+}
+
+/*
+ * "getchar()" function
+ */
+static void f_getchar(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ varnumber_T n;
+ int error = FALSE;
+
+ /* Position the cursor. Needed after a message that ends in a space. */
+ windgoto(msg_row, msg_col);
+
+ ++no_mapping;
+ ++allow_keys;
+ for (;; ) {
+ if (argvars[0].v_type == VAR_UNKNOWN)
+ /* getchar(): blocking wait. */
+ n = safe_vgetc();
+ else if (get_tv_number_chk(&argvars[0], &error) == 1)
+ /* getchar(1): only check if char avail */
+ n = vpeekc();
+ else if (error || vpeekc() == NUL)
+ /* illegal argument or getchar(0) and no char avail: return zero */
+ n = 0;
+ else
+ /* getchar(0) and char avail: return char */
+ n = safe_vgetc();
+ if (n == K_IGNORE)
+ continue;
+ break;
+ }
+ --no_mapping;
+ --allow_keys;
+
+ vimvars[VV_MOUSE_WIN].vv_nr = 0;
+ vimvars[VV_MOUSE_LNUM].vv_nr = 0;
+ vimvars[VV_MOUSE_COL].vv_nr = 0;
+
+ rettv->vval.v_number = n;
+ if (IS_SPECIAL(n) || mod_mask != 0) {
+ char_u temp[10]; /* modifier: 3, mbyte-char: 6, NUL: 1 */
+ int i = 0;
+
+ /* Turn a special key into three bytes, plus modifier. */
+ if (mod_mask != 0) {
+ temp[i++] = K_SPECIAL;
+ temp[i++] = KS_MODIFIER;
+ temp[i++] = mod_mask;
+ }
+ if (IS_SPECIAL(n)) {
+ 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;
+ temp[i++] = NUL;
+ rettv->v_type = VAR_STRING;
+ rettv->vval.v_string = vim_strsave(temp);
+
+ if (is_mouse_key(n)) {
+ int row = mouse_row;
+ int col = mouse_col;
+ win_T *win;
+ linenr_T lnum;
+ win_T *wp;
+ int winnr = 1;
+
+ if (row >= 0 && col >= 0) {
+ /* Find the window at the mouse coordinates and compute the
+ * text position. */
+ win = mouse_find_win(&row, &col);
+ (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_LNUM].vv_nr = lnum;
+ vimvars[VV_MOUSE_COL].vv_nr = col + 1;
+ }
+ }
+ }
+}
+
+/*
+ * "getcharmod()" function
+ */
+static void f_getcharmod(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv;
+{
+ rettv->vval.v_number = mod_mask;
+}
+
+/*
+ * "getcmdline()" function
+ */
+static void f_getcmdline(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv;
+{
+ rettv->v_type = VAR_STRING;
+ rettv->vval.v_string = get_cmdline_str();
+}
+
+/*
+ * "getcmdpos()" function
+ */
+static void f_getcmdpos(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv;
+{
+ rettv->vval.v_number = get_cmdline_pos() + 1;
+}
+
+/*
+ * "getcmdtype()" function
+ */
+static void f_getcmdtype(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv;
+{
+ rettv->v_type = VAR_STRING;
+ rettv->vval.v_string = alloc(2);
+ if (rettv->vval.v_string != NULL) {
+ rettv->vval.v_string[0] = get_cmdline_type();
+ rettv->vval.v_string[1] = NUL;
+ }
+}
+
+/*
+ * "getcwd()" function
+ */
+static void f_getcwd(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv;
+{
+ char_u *cwd;
+
+ rettv->v_type = VAR_STRING;
+ rettv->vval.v_string = NULL;
+ cwd = alloc(MAXPATHL);
+ if (cwd != NULL) {
+ if (mch_dirname(cwd, MAXPATHL) != FAIL) {
+ rettv->vval.v_string = vim_strsave(cwd);
+#ifdef BACKSLASH_IN_FILENAME
+ if (rettv->vval.v_string != NULL)
+ slash_adjust(rettv->vval.v_string);
+#endif
+ }
+ vim_free(cwd);
+ }
+}
+
+/*
+ * "getfontname()" function
+ */
+static void f_getfontname(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv;
+{
+ rettv->v_type = VAR_STRING;
+ rettv->vval.v_string = NULL;
+}
+
+/*
+ * "getfperm({fname})" function
+ */
+static void f_getfperm(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ char_u *fname;
+ struct stat st;
+ char_u *perm = NULL;
+ char_u flags[] = "rwx";
+ int i;
+
+ fname = get_tv_string(&argvars[0]);
+
+ rettv->v_type = VAR_STRING;
+ if (mch_stat((char *)fname, &st) >= 0) {
+ perm = vim_strsave((char_u *)"---------");
+ if (perm != NULL) {
+ for (i = 0; i < 9; i++) {
+ if (st.st_mode & (1 << (8 - i)))
+ perm[i] = flags[i % 3];
+ }
+ }
+ }
+ rettv->vval.v_string = perm;
+}
+
+/*
+ * "getfsize({fname})" function
+ */
+static void f_getfsize(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ char_u *fname;
+ struct stat st;
+
+ fname = get_tv_string(&argvars[0]);
+
+ rettv->v_type = VAR_NUMBER;
+
+ if (mch_stat((char *)fname, &st) >= 0) {
+ if (mch_isdir(fname))
+ rettv->vval.v_number = 0;
+ else {
+ rettv->vval.v_number = (varnumber_T)st.st_size;
+
+ /* non-perfect check for overflow */
+ if ((off_t)rettv->vval.v_number != (off_t)st.st_size)
+ rettv->vval.v_number = -2;
+ }
+ } else
+ rettv->vval.v_number = -1;
+}
+
+/*
+ * "getftime({fname})" function
+ */
+static void f_getftime(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ char_u *fname;
+ struct stat st;
+
+ fname = get_tv_string(&argvars[0]);
+
+ if (mch_stat((char *)fname, &st) >= 0)
+ rettv->vval.v_number = (varnumber_T)st.st_mtime;
+ else
+ rettv->vval.v_number = -1;
+}
+
+/*
+ * "getftype({fname})" function
+ */
+static void f_getftype(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ char_u *fname;
+ struct stat st;
+ char_u *type = NULL;
+ char *t;
+
+ fname = get_tv_string(&argvars[0]);
+
+ rettv->v_type = VAR_STRING;
+ if (mch_lstat((char *)fname, &st) >= 0) {
+#ifdef S_ISREG
+ if (S_ISREG(st.st_mode))
+ t = "file";
+ else if (S_ISDIR(st.st_mode))
+ t = "dir";
+# ifdef S_ISLNK
+ else if (S_ISLNK(st.st_mode))
+ t = "link";
+# endif
+# ifdef S_ISBLK
+ else if (S_ISBLK(st.st_mode))
+ t = "bdev";
+# endif
+# ifdef S_ISCHR
+ else if (S_ISCHR(st.st_mode))
+ t = "cdev";
+# endif
+# ifdef S_ISFIFO
+ else if (S_ISFIFO(st.st_mode))
+ t = "fifo";
+# endif
+# ifdef S_ISSOCK
+ else if (S_ISSOCK(st.st_mode))
+ t = "fifo";
+# endif
+ else
+ t = "other";
+#else
+# ifdef S_IFMT
+ switch (st.st_mode & S_IFMT) {
+ case S_IFREG: t = "file"; break;
+ case S_IFDIR: t = "dir"; break;
+# ifdef S_IFLNK
+ case S_IFLNK: t = "link"; break;
+# endif
+# ifdef S_IFBLK
+ case S_IFBLK: t = "bdev"; break;
+# endif
+# ifdef S_IFCHR
+ case S_IFCHR: t = "cdev"; break;
+# endif
+# ifdef S_IFIFO
+ case S_IFIFO: t = "fifo"; break;
+# endif
+# ifdef S_IFSOCK
+ case S_IFSOCK: t = "socket"; break;
+# endif
+ default: t = "other";
+ }
+# else
+ if (mch_isdir(fname))
+ t = "dir";
+ else
+ t = "file";
+# endif
+#endif
+ type = vim_strsave((char_u *)t);
+ }
+ rettv->vval.v_string = type;
+}
+
+/*
+ * "getline(lnum, [end])" function
+ */
+static void f_getline(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ linenr_T lnum;
+ linenr_T end;
+ int retlist;
+
+ lnum = get_tv_lnum(argvars);
+ if (argvars[1].v_type == VAR_UNKNOWN) {
+ end = 0;
+ retlist = FALSE;
+ } else {
+ end = get_tv_lnum(&argvars[1]);
+ retlist = TRUE;
+ }
+
+ get_buffer_lines(curbuf, lnum, end, retlist, rettv);
+}
+
+/*
+ * "getmatches()" function
+ */
+static void f_getmatches(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv UNUSED;
+{
+ dict_T *dict;
+ matchitem_T *cur = curwin->w_match_head;
+
+ if (rettv_list_alloc(rettv) == OK) {
+ while (cur != NULL) {
+ dict = dict_alloc();
+ if (dict == NULL)
+ return;
+ dict_add_nr_str(dict, "group", 0L, syn_id2name(cur->hlg_id));
+ dict_add_nr_str(dict, "pattern", 0L, cur->pattern);
+ dict_add_nr_str(dict, "priority", (long)cur->priority, NULL);
+ dict_add_nr_str(dict, "id", (long)cur->id, NULL);
+ list_append_dict(rettv->vval.v_list, dict);
+ cur = cur->next;
+ }
+ }
+}
+
+/*
+ * "getpid()" function
+ */
+static void f_getpid(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv;
+{
+ rettv->vval.v_number = mch_get_pid();
+}
+
+/*
+ * "getpos(string)" function
+ */
+static void f_getpos(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ pos_T *fp;
+ list_T *l;
+ int fnum = -1;
+
+ if (rettv_list_alloc(rettv) == OK) {
+ l = rettv->vval.v_list;
+ fp = var2fpos(&argvars[0], TRUE, &fnum);
+ if (fnum != -1)
+ list_append_number(l, (varnumber_T)fnum);
+ else
+ list_append_number(l, (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);
+ } else
+ rettv->vval.v_number = FALSE;
+}
+
+/*
+ * "getqflist()" and "getloclist()" functions
+ */
+static void f_getqflist(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv UNUSED;
+{
+ win_T *wp;
+
+ if (rettv_list_alloc(rettv) == OK) {
+ 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);
+ }
+}
+
+/*
+ * "getreg()" function
+ */
+static void f_getreg(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ char_u *strregname;
+ int regname;
+ int arg2 = FALSE;
+ int error = FALSE;
+
+ if (argvars[0].v_type != VAR_UNKNOWN) {
+ strregname = get_tv_string_chk(&argvars[0]);
+ error = strregname == NULL;
+ if (argvars[1].v_type != VAR_UNKNOWN)
+ arg2 = get_tv_number_chk(&argvars[1], &error);
+ } else
+ strregname = vimvars[VV_REG].vv_str;
+ regname = (strregname == NULL ? '"' : *strregname);
+ if (regname == 0)
+ regname = '"';
+
+ rettv->v_type = VAR_STRING;
+ rettv->vval.v_string = error ? NULL :
+ get_reg_contents(regname, TRUE, arg2);
+}
+
+/*
+ * "getregtype()" function
+ */
+static void f_getregtype(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ char_u *strregname;
+ int regname;
+ char_u buf[NUMBUFLEN + 2];
+ long reglen = 0;
+
+ if (argvars[0].v_type != VAR_UNKNOWN) {
+ strregname = get_tv_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;
+
+ regname = (strregname == NULL ? '"' : *strregname);
+ if (regname == 0)
+ regname = '"';
+
+ buf[0] = NUL;
+ buf[1] = NUL;
+ switch (get_reg_type(regname, &reglen)) {
+ case MLINE: buf[0] = 'V'; break;
+ case MCHAR: buf[0] = 'v'; break;
+ case MBLOCK:
+ buf[0] = Ctrl_V;
+ sprintf((char *)buf + 1, "%ld", reglen + 1);
+ break;
+ }
+ rettv->v_type = VAR_STRING;
+ rettv->vval.v_string = vim_strsave(buf);
+}
+
+/*
+ * "gettabvar()" function
+ */
+static void f_gettabvar(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ tabpage_T *tp;
+ dictitem_T *v;
+ char_u *varname;
+ int 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));
+ if (tp != NULL && varname != NULL) {
+ /* look up the variable */
+ v = find_var_in_ht(&tp->tp_vars->dv_hashtab, 0, varname, FALSE);
+ if (v != NULL) {
+ copy_tv(&v->di_tv, rettv);
+ done = TRUE;
+ }
+ }
+
+ if (!done && argvars[2].v_type != VAR_UNKNOWN)
+ copy_tv(&argvars[2], rettv);
+}
+
+/*
+ * "gettabwinvar()" function
+ */
+static void f_gettabwinvar(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ getwinvar(argvars, rettv, 1);
+}
+
+/*
+ * "getwinposx()" function
+ */
+static void f_getwinposx(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv;
+{
+ rettv->vval.v_number = -1;
+}
+
+/*
+ * "getwinposy()" function
+ */
+static void f_getwinposy(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv;
+{
+ rettv->vval.v_number = -1;
+}
+
+/*
+ * Find window specified by "vp" in tabpage "tp".
+ */
+static win_T * find_win_by_nr(vp, tp)
+typval_T *vp;
+tabpage_T *tp UNUSED; /* NULL for current tab page */
+{
+ win_T *wp;
+ int nr;
+
+ nr = get_tv_number_chk(vp, NULL);
+
+ if (nr < 0)
+ return NULL;
+ if (nr == 0)
+ return curwin;
+
+ for (wp = (tp == NULL || tp == curtab) ? firstwin : tp->tp_firstwin;
+ wp != NULL; wp = wp->w_next)
+ if (--nr <= 0)
+ break;
+ return wp;
+}
+
+/*
+ * "getwinvar()" function
+ */
+static void f_getwinvar(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ getwinvar(argvars, rettv, 0);
+}
+
+/*
+ * getwinvar() and gettabwinvar()
+ */
+static void getwinvar(argvars, rettv, off)
+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;
+ int done = FALSE;
+
+ if (off == 1)
+ tp = find_tabpage((int)get_tv_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;
+
+ rettv->v_type = VAR_STRING;
+ rettv->vval.v_string = NULL;
+
+ if (win != NULL && varname != NULL) {
+ /* Set curwin to be our win, temporarily. Also set the tabpage,
+ * otherwise the window is not valid. */
+ switch_win(&oldcurwin, &oldtabpage, win, tp, TRUE);
+
+ if (*varname == '&') { /* window-local-option */
+ if (get_option_tv(&varname, rettv, 1) == OK)
+ 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);
+ if (v != NULL) {
+ copy_tv(&v->di_tv, rettv);
+ done = TRUE;
+ }
+ }
+
+ /* restore previous notion of curwin */
+ restore_win(oldcurwin, oldtabpage, TRUE);
+ }
+
+ if (!done && argvars[off + 2].v_type != VAR_UNKNOWN)
+ /* use the default return value */
+ copy_tv(&argvars[off + 2], rettv);
+
+ --emsg_off;
+}
+
+/*
+ * "glob()" function
+ */
+static void f_glob(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ int options = WILD_SILENT|WILD_USE_NL;
+ expand_T xpc;
+ int 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))
+ options |= WILD_KEEP_ALL;
+ if (argvars[2].v_type != VAR_UNKNOWN
+ && get_tv_number_chk(&argvars[2], &error)) {
+ rettv->v_type = VAR_LIST;
+ rettv->vval.v_list = NULL;
+ }
+ }
+ if (!error) {
+ ExpandInit(&xpc);
+ 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 if (rettv_list_alloc(rettv) != FAIL) {
+ int i;
+
+ ExpandOne(&xpc, get_tv_string(&argvars[0]),
+ NULL, options, WILD_ALL_KEEP);
+ for (i = 0; i < xpc.xp_numfiles; i++)
+ list_append_string(rettv->vval.v_list, xpc.xp_files[i], -1);
+
+ ExpandCleanup(&xpc);
+ }
+ } else
+ rettv->vval.v_string = NULL;
+}
+
+/*
+ * "globpath()" function
+ */
+static void f_globpath(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ int flags = 0;
+ char_u buf1[NUMBUFLEN];
+ char_u *file = get_tv_string_buf_chk(&argvars[1], buf1);
+ int 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. */
+ if (argvars[2].v_type != VAR_UNKNOWN
+ && get_tv_number_chk(&argvars[2], &error))
+ flags |= WILD_KEEP_ALL;
+ rettv->v_type = VAR_STRING;
+ if (file == NULL || error)
+ rettv->vval.v_string = NULL;
+ else
+ rettv->vval.v_string = globpath(get_tv_string(&argvars[0]), file,
+ flags);
+}
+
+/*
+ * "has()" function
+ */
+static void f_has(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ int i;
+ char_u *name;
+ int n = FALSE;
+ static char *(has_list[]) =
+ {
+#ifdef UNIX
+ "unix",
+#endif
+#if defined(WIN64) || defined(_WIN64)
+ "win64",
+#endif
+#ifndef CASE_INSENSITIVE_FILENAME
+ "fname_case",
+#endif
+#ifdef HAVE_ACL
+ "acl",
+#endif
+ "arabic",
+ "autocmd",
+#if defined(SOME_BUILTIN_TCAPS) || defined(ALL_BUILTIN_TCAPS)
+ "builtin_terms",
+# ifdef ALL_BUILTIN_TCAPS
+ "all_builtin_terms",
+# endif
+#endif
+#if defined(FEAT_BROWSE) && (defined(USE_FILE_CHOOSER) \
+ || defined(FEAT_GUI_W32) \
+ || defined(FEAT_GUI_MOTIF))
+ "browsefilter",
+#endif
+ "byte_offset",
+ "cindent",
+ "cmdline_compl",
+ "cmdline_hist",
+ "comments",
+ "conceal",
+ "cryptv",
+ "cscope",
+ "cursorbind",
+#ifdef CURSOR_SHAPE
+ "cursorshape",
+#endif
+#ifdef DEBUG
+ "debug",
+#endif
+ "dialog_con",
+ "diff",
+ "digraphs",
+ "eval", /* always present, of course! */
+ "ex_extra",
+ "extra_search",
+ "farsi",
+ "file_in_path",
+ "find_in_path",
+ "float",
+ "folding",
+#if !defined(USE_SYSTEM) && defined(UNIX)
+ "fork",
+#endif
+ "gettext",
+ "hangul_input",
+#if defined(HAVE_ICONV_H) && defined(USE_ICONV)
+ "iconv",
+#endif
+ "insert_expand",
+ "jumplist",
+ "keymap",
+ "langmap",
+#ifdef FEAT_LIBCALL
+ "libcall",
+#endif
+ "linebreak",
+ "lispindent",
+ "listcmds",
+ "localmap",
+ "menu",
+ "mksession",
+ "modify_fname",
+ "mouse",
+#if defined(UNIX) || defined(VMS)
+ "mouse_dec",
+# ifdef FEAT_MOUSE_JSB
+ "mouse_jsbterm",
+# endif
+ "mouse_netterm",
+ "mouse_sgr",
+ "mouse_urxvt",
+ "mouse_xterm",
+#endif
+ "multi_byte",
+ "multi_lang",
+#ifdef FEAT_OLE
+ "ole",
+#endif
+ "path_extra",
+ "persistent_undo",
+ "postscript",
+ "printer",
+ "profile",
+ "reltime",
+ "quickfix",
+ "rightleft",
+ "scrollbind",
+ "showcmd",
+ "cmdline_info",
+ "smartindent",
+#ifdef STARTUPTIME
+ "startuptime",
+#endif
+ "statusline",
+ "spell",
+ "syntax",
+#if defined(USE_SYSTEM) || !defined(UNIX)
+ "system",
+#endif
+ "tag_binary",
+ "tag_old_static",
+#ifdef FEAT_TAG_ANYWHITE
+ "tag_any_white",
+#endif
+#ifdef TERMINFO
+ "terminfo",
+#endif
+ "termresponse",
+ "textobjects",
+#ifdef HAVE_TGETENT
+ "tgetent",
+#endif
+ "title",
+ "user-commands", /* was accidentally included in 5.4 */
+ "user_commands",
+ "viminfo",
+ "vertsplit",
+ "virtualedit",
+ "visual",
+ "visualextra",
+ "vreplace",
+ "wildignore",
+ "wildmenu",
+ "windows",
+ "winaltkeys",
+ "writebackup",
+#ifdef FEAT_XPM_W32
+ "xpm",
+ "xpm_w32", /* for backward compatibility */
+#else
+#endif
+#ifdef FEAT_XTERM_SAVE
+ "xterm_save",
+#endif
+ NULL
+ };
+
+ name = get_tv_string(&argvars[0]);
+ for (i = 0; has_list[i] != NULL; ++i)
+ if (STRICMP(name, has_list[i]) == 0) {
+ n = TRUE;
+ break;
+ }
+
+ if (n == FALSE) {
+ if (STRNICMP(name, "patch", 5) == 0)
+ n = has_patch(atoi((char *)name + 5));
+ else if (STRICMP(name, "vim_starting") == 0)
+ n = (starting != 0);
+ else if (STRICMP(name, "multi_byte_encoding") == 0)
+ n = has_mbyte;
+#ifdef DYNAMIC_TCL
+ else if (STRICMP(name, "tcl") == 0)
+ n = tcl_enabled(FALSE);
+#endif
+#if defined(USE_ICONV) && defined(DYNAMIC_ICONV)
+ else if (STRICMP(name, "iconv") == 0)
+ n = iconv_enabled(FALSE);
+#endif
+#ifdef DYNAMIC_MZSCHEME
+ else if (STRICMP(name, "mzscheme") == 0)
+ n = mzscheme_enabled(FALSE);
+#endif
+ else if (STRICMP(name, "syntax_items") == 0)
+ n = syntax_present(curwin);
+ }
+
+ rettv->vval.v_number = n;
+}
+
+/*
+ * "has_key()" function
+ */
+static void f_has_key(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ if (argvars[0].v_type != VAR_DICT) {
+ EMSG(_(e_dictreq));
+ return;
+ }
+ 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;
+}
+
+/*
+ * "haslocaldir()" function
+ */
+static void f_haslocaldir(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv;
+{
+ rettv->vval.v_number = (curwin->w_localdir != NULL);
+}
+
+/*
+ * "hasmapto()" function
+ */
+static void f_hasmapto(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ 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]);
+ }
+
+ if (map_to_exists(name, mode, abbr))
+ rettv->vval.v_number = TRUE;
+ else
+ rettv->vval.v_number = FALSE;
+}
+
+/*
+ * "histadd()" function
+ */
+static void f_histadd(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv;
+{
+ int 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) : -1;
+ if (histype >= 0) {
+ str = get_tv_string_buf(&argvars[1], buf);
+ if (*str != NUL) {
+ init_history();
+ add_to_history(histype, str, FALSE, NUL);
+ rettv->vval.v_number = TRUE;
+ return;
+ }
+ }
+}
+
+/*
+ * "histdel()" function
+ */
+static void f_histdel(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv UNUSED;
+{
+ int n;
+ char_u buf[NUMBUFLEN];
+ char_u *str;
+
+ str = get_tv_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));
+ else if (argvars[1].v_type == VAR_NUMBER)
+ /* index given: remove that entry */
+ n = del_history_idx(get_histtype(str),
+ (int)get_tv_number(&argvars[1]));
+ else
+ /* string given: remove all matching entries */
+ n = del_history_entry(get_histtype(str),
+ get_tv_string_buf(&argvars[1], buf));
+ rettv->vval.v_number = n;
+}
+
+/*
+ * "histget()" function
+ */
+static void f_histget(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv;
+{
+ int type;
+ int idx;
+ char_u *str;
+
+ str = get_tv_string_chk(&argvars[0]); /* NULL on type error */
+ if (str == NULL)
+ rettv->vval.v_string = NULL;
+ else {
+ type = get_histtype(str);
+ if (argvars[1].v_type == VAR_UNKNOWN)
+ idx = get_history_idx(type);
+ else
+ idx = (int)get_tv_number_chk(&argvars[1], NULL);
+ /* -1 on type error */
+ rettv->vval.v_string = vim_strsave(get_history_entry(type, idx));
+ }
+ rettv->v_type = VAR_STRING;
+}
+
+/*
+ * "histnr()" function
+ */
+static void f_histnr(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv;
+{
+ int i;
+
+ char_u *history = get_tv_string_chk(&argvars[0]);
+
+ i = history == NULL ? HIST_CMD - 1 : get_histtype(history);
+ if (i >= HIST_CMD && i < HIST_COUNT)
+ i = get_history_idx(i);
+ else
+ i = -1;
+ rettv->vval.v_number = i;
+}
+
+/*
+ * "highlightID(name)" function
+ */
+static void f_hlID(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ rettv->vval.v_number = syn_name2id(get_tv_string(&argvars[0]));
+}
+
+/*
+ * "highlight_exists()" function
+ */
+static void f_hlexists(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ rettv->vval.v_number = highlight_exists(get_tv_string(&argvars[0]));
+}
+
+/*
+ * "hostname()" function
+ */
+static void f_hostname(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv;
+{
+ char_u hostname[256];
+
+ mch_get_host_name(hostname, 256);
+ rettv->v_type = VAR_STRING;
+ rettv->vval.v_string = vim_strsave(hostname);
+}
+
+/*
+ * iconv() function
+ */
+static void f_iconv(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv;
+{
+ 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)));
+ 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);
+
+ convert_setup(&vimconv, NULL, NULL);
+ vim_free(from);
+ vim_free(to);
+}
+
+/*
+ * "indent()" function
+ */
+static void f_indent(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ linenr_T lnum;
+
+ lnum = get_tv_lnum(argvars);
+ if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count)
+ rettv->vval.v_number = get_indent_lnum(lnum);
+ else
+ rettv->vval.v_number = -1;
+}
+
+/*
+ * "index()" function
+ */
+static void f_index(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ list_T *l;
+ listitem_T *item;
+ long idx = 0;
+ int ic = FALSE;
+
+ rettv->vval.v_number = -1;
+ if (argvars[0].v_type != VAR_LIST) {
+ EMSG(_(e_listreq));
+ return;
+ }
+ l = argvars[0].vval.v_list;
+ if (l != NULL) {
+ item = l->lv_first;
+ if (argvars[2].v_type != VAR_UNKNOWN) {
+ int 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)
+ item = NULL;
+ }
+
+ for (; item != NULL; item = item->li_next, ++idx)
+ if (tv_equal(&item->li_tv, &argvars[1], ic, FALSE)) {
+ rettv->vval.v_number = idx;
+ break;
+ }
+ }
+}
+
+static int inputsecret_flag = 0;
+
+static void get_user_input __ARGS((typval_T *argvars, typval_T *rettv,
+ int inputdialog));
+
+/*
+ * This function is used by f_input() and f_inputdialog() functions. The third
+ * argument to f_input() specifies the type of completion to use at the
+ * prompt. The third argument to f_inputdialog() specifies the value to return
+ * when the user cancels the prompt.
+ */
+static void get_user_input(argvars, rettv, inputdialog)
+typval_T *argvars;
+typval_T *rettv;
+int inputdialog;
+{
+ 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;
+
+#ifdef NO_CONSOLE_INPUT
+ /* While starting up, there is no place to enter text. */
+ if (no_console_input())
+ return;
+#endif
+
+ 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;
+ }
+ 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;
+ long 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)
+ return;
+ }
+ }
+
+ 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;
+ }
+ 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));
+
+ vim_free(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;
+}
+
+/*
+ * "input()" function
+ * Also handles inputsecret() when inputsecret is set.
+ */
+static void f_input(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ get_user_input(argvars, rettv, FALSE);
+}
+
+/*
+ * "inputdialog()" function
+ */
+static void f_inputdialog(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ get_user_input(argvars, rettv, TRUE);
+}
+
+/*
+ * "inputlist()" function
+ */
+static void f_inputlist(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ listitem_T *li;
+ int selected;
+ int mouse_used;
+
+#ifdef NO_CONSOLE_INPUT
+ /* While starting up, there is no place to enter text. */
+ if (no_console_input())
+ return;
+#endif
+ if (argvars[0].v_type != VAR_LIST || argvars[0].vval.v_list == NULL) {
+ EMSG2(_(e_listarg), "inputlist()");
+ return;
+ }
+
+ msg_start();
+ msg_row = Rows - 1; /* for when 'cmdheight' > 1 */
+ lines_left = Rows; /* avoid more prompt */
+ 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));
+ msg_putchar('\n');
+ }
+
+ /* Ask for choice. */
+ selected = prompt_for_number(&mouse_used);
+ if (mouse_used)
+ selected -= lines_left;
+
+ rettv->vval.v_number = selected;
+}
+
+
+static garray_T ga_userinput = {0, 0, sizeof(tasave_T), 4, NULL};
+
+/*
+ * "inputrestore()" function
+ */
+static void f_inputrestore(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv;
+{
+ if (ga_userinput.ga_len > 0) {
+ --ga_userinput.ga_len;
+ restore_typeahead((tasave_T *)(ga_userinput.ga_data)
+ + ga_userinput.ga_len);
+ /* default return is zero == OK */
+ } else if (p_verbose > 1) {
+ verb_msg((char_u *)_("called inputrestore() more often than inputsave()"));
+ rettv->vval.v_number = 1; /* Failed */
+ }
+}
+
+/*
+ * "inputsave()" function
+ */
+static void f_inputsave(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv;
+{
+ /* Add an entry to the stack of typeahead storage. */
+ if (ga_grow(&ga_userinput, 1) == OK) {
+ save_typeahead((tasave_T *)(ga_userinput.ga_data)
+ + ga_userinput.ga_len);
+ ++ga_userinput.ga_len;
+ /* default return is zero == OK */
+ } else
+ rettv->vval.v_number = 1; /* Failed */
+}
+
+/*
+ * "inputsecret()" function
+ */
+static void f_inputsecret(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ ++cmdline_star;
+ ++inputsecret_flag;
+ f_input(argvars, rettv);
+ --cmdline_star;
+ --inputsecret_flag;
+}
+
+/*
+ * "insert()" function
+ */
+static void f_insert(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ long before = 0;
+ listitem_T *item;
+ list_T *l;
+ int 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 *)_("insert() argument"))) {
+ if (argvars[2].v_type != VAR_UNKNOWN)
+ before = get_tv_number_chk(&argvars[2], &error);
+ if (error)
+ return; /* type error; errmsg already given */
+
+ if (before == l->lv_len)
+ item = NULL;
+ else {
+ item = 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);
+ }
+ }
+}
+
+/*
+ * "invert(expr)" function
+ */
+static void f_invert(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ rettv->vval.v_number = ~get_tv_number_chk(&argvars[0], NULL);
+}
+
+/*
+ * "isdirectory()" function
+ */
+static void f_isdirectory(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ rettv->vval.v_number = mch_isdir(get_tv_string(&argvars[0]));
+}
+
+/*
+ * "islocked()" function
+ */
+static void f_islocked(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ 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);
+ if (end != NULL && lv.ll_name != NULL) {
+ if (*end != NUL)
+ EMSG(_(e_trailing));
+ 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));
+ }
+ }
+ } else if (lv.ll_range)
+ EMSG(_("E786: Range not allowed"));
+ 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. */
+ rettv->vval.v_number = tv_islocked(&lv.ll_di->di_tv);
+ }
+ }
+
+ clear_lval(&lv);
+}
+
+static void dict_list __ARGS((typval_T *argvars, typval_T *rettv, int what));
+
+/*
+ * 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(argvars, rettv, what)
+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) {
+ EMSG(_(e_dictreq));
+ return;
+ }
+ if ((d = argvars[0].vval.v_dict) == NULL)
+ return;
+
+ if (rettv_list_alloc(rettv) == FAIL)
+ return;
+
+ 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();
+ if (li == NULL)
+ break;
+ 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;
+ if (l2 == NULL)
+ break;
+ ++l2->lv_refcount;
+
+ li2 = listitem_alloc();
+ if (li2 == NULL)
+ break;
+ 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);
+
+ li2 = listitem_alloc();
+ if (li2 == NULL)
+ break;
+ list_append(l2, li2);
+ copy_tv(&di->di_tv, &li2->li_tv);
+ }
+ }
+ }
+}
+
+/*
+ * "items(dict)" function
+ */
+static void f_items(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ dict_list(argvars, rettv, 2);
+}
+
+/*
+ * "join()" function
+ */
+static void f_join(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ 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]);
+
+ rettv->v_type = VAR_STRING;
+
+ if (sep != NULL) {
+ ga_init2(&ga, (int)sizeof(char), 80);
+ list_join(&ga, argvars[0].vval.v_list, sep, TRUE, 0);
+ ga_append(&ga, NUL);
+ rettv->vval.v_string = (char_u *)ga.ga_data;
+ } else
+ rettv->vval.v_string = NULL;
+}
+
+/*
+ * "keys()" function
+ */
+static void f_keys(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ dict_list(argvars, rettv, 0);
+}
+
+/*
+ * "last_buffer_nr()" function.
+ */
+static void f_last_buffer_nr(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv;
+{
+ int n = 0;
+ buf_T *buf;
+
+ for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+ if (n < buf->b_fnum)
+ n = buf->b_fnum;
+
+ rettv->vval.v_number = n;
+}
+
+/*
+ * "len()" function
+ */
+static void f_len(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ 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;
+ default:
+ EMSG(_("E701: Invalid type for len()"));
+ break;
+ }
+}
+
+static void libcall_common __ARGS((typval_T *argvars, typval_T *rettv, int type));
+
+static void libcall_common(argvars, rettv, type)
+typval_T *argvars;
+typval_T *rettv;
+int type;
+{
+#ifdef FEAT_LIBCALL
+ char_u *string_in;
+ char_u **string_result;
+ int nr_result;
+#endif
+
+ rettv->v_type = type;
+ if (type != VAR_NUMBER)
+ rettv->vval.v_string = NULL;
+
+ if (check_restricted() || check_secure())
+ return;
+
+#ifdef FEAT_LIBCALL
+ /* The first two args must be strings, otherwise its meaningless */
+ if (argvars[0].v_type == VAR_STRING && argvars[1].v_type == VAR_STRING) {
+ string_in = NULL;
+ if (argvars[2].v_type == VAR_STRING)
+ string_in = argvars[2].vval.v_string;
+ if (type == VAR_NUMBER)
+ string_result = NULL;
+ else
+ string_result = &rettv->vval.v_string;
+ if (mch_libcall(argvars[0].vval.v_string,
+ argvars[1].vval.v_string,
+ string_in,
+ argvars[2].vval.v_number,
+ string_result,
+ &nr_result) == OK
+ && type == VAR_NUMBER)
+ rettv->vval.v_number = nr_result;
+ }
+#endif
+}
+
+/*
+ * "libcall()" function
+ */
+static void f_libcall(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ libcall_common(argvars, rettv, VAR_STRING);
+}
+
+/*
+ * "libcallnr()" function
+ */
+static void f_libcallnr(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ libcall_common(argvars, rettv, VAR_NUMBER);
+}
+
+/*
+ * "line(string)" function
+ */
+static void f_line(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ linenr_T lnum = 0;
+ pos_T *fp;
+ int fnum;
+
+ fp = var2fpos(&argvars[0], TRUE, &fnum);
+ if (fp != NULL)
+ lnum = fp->lnum;
+ rettv->vval.v_number = lnum;
+}
+
+/*
+ * "line2byte(lnum)" function
+ */
+static void f_line2byte(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv;
+{
+ linenr_T lnum;
+
+ lnum = get_tv_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;
+}
+
+/*
+ * "lispindent(lnum)" function
+ */
+static void f_lispindent(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv;
+{
+ pos_T pos;
+ linenr_T lnum;
+
+ pos = curwin->w_cursor;
+ lnum = get_tv_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
+ rettv->vval.v_number = -1;
+}
+
+/*
+ * "localtime()" function
+ */
+static void f_localtime(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv;
+{
+ rettv->vval.v_number = (varnumber_T)time(NULL);
+}
+
+static void get_maparg __ARGS((typval_T *argvars, typval_T *rettv, int exact));
+
+static void get_maparg(argvars, rettv, exact)
+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;
+ int mode;
+ int abbr = FALSE;
+ int get_dict = FALSE;
+ mapblock_T *mp;
+ int buffer_local;
+
+ /* return empty string for failure */
+ rettv->v_type = VAR_STRING;
+ rettv->vval.v_string = NULL;
+
+ keys = get_tv_string(&argvars[0]);
+ if (*keys == NUL)
+ return;
+
+ if (argvars[1].v_type != VAR_UNKNOWN) {
+ which = get_tv_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]);
+ }
+ } else
+ which = (char_u *)"";
+ if (which == NULL)
+ return;
+
+ mode = get_map_mode(&which, 0);
+
+ keys = replace_termcodes(keys, &keys_buf, TRUE, TRUE, FALSE);
+ rhs = check_map(keys, mode, exact, FALSE, abbr, &mp, &buffer_local);
+ vim_free(keys_buf);
+
+ if (!get_dict) {
+ /* Return a string. */
+ if (rhs != NULL)
+ rettv->vval.v_string = str2special_save(rhs, FALSE);
+
+ } else if (rettv_dict_alloc(rettv) != FAIL && 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);
+
+ vim_free(lhs);
+ vim_free(mapmode);
+ }
+}
+
+/*
+ * "log()" function
+ */
+static void f_log(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ float_T f;
+
+ rettv->v_type = VAR_FLOAT;
+ if (get_float_arg(argvars, &f) == OK)
+ rettv->vval.v_float = log(f);
+ else
+ rettv->vval.v_float = 0.0;
+}
+
+/*
+ * "log10()" function
+ */
+static void f_log10(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ float_T f;
+
+ rettv->v_type = VAR_FLOAT;
+ if (get_float_arg(argvars, &f) == OK)
+ rettv->vval.v_float = log10(f);
+ else
+ rettv->vval.v_float = 0.0;
+}
+
+
+/*
+ * "map()" function
+ */
+static void f_map(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ filter_map(argvars, rettv, TRUE);
+}
+
+/*
+ * "maparg()" function
+ */
+static void f_maparg(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ get_maparg(argvars, rettv, TRUE);
+}
+
+/*
+ * "mapcheck()" function
+ */
+static void f_mapcheck(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ get_maparg(argvars, rettv, FALSE);
+}
+
+static void find_some_match __ARGS((typval_T *argvars, typval_T *rettv,
+ int start));
+
+static void find_some_match(argvars, rettv, type)
+typval_T *argvars;
+typval_T *rettv;
+int type;
+{
+ char_u *str = NULL;
+ char_u *expr = NULL;
+ char_u *pat;
+ regmatch_T regmatch;
+ char_u patbuf[NUMBUFLEN];
+ char_u strbuf[NUMBUFLEN];
+ char_u *save_cpo;
+ long start = 0;
+ long nth = 1;
+ colnr_T startcol = 0;
+ int match = 0;
+ list_T *l = NULL;
+ listitem_T *li = NULL;
+ long idx = 0;
+ char_u *tofree = NULL;
+
+ /* Make 'cpoptions' empty, the 'l' flag should not be used here. */
+ save_cpo = p_cpo;
+ p_cpo = (char_u *)"";
+
+ rettv->vval.v_number = -1;
+ if (type == 3) {
+ /* return empty list when there are no matches */
+ if (rettv_list_alloc(rettv) == FAIL)
+ goto theend;
+ } else if (type == 2) {
+ rettv->v_type = VAR_STRING;
+ rettv->vval.v_string = NULL;
+ }
+
+ if (argvars[0].v_type == VAR_LIST) {
+ if ((l = argvars[0].vval.v_list) == NULL)
+ goto theend;
+ li = l->lv_first;
+ } else
+ expr = str = get_tv_string(&argvars[0]);
+
+ pat = get_tv_string_buf_chk(&argvars[1], patbuf);
+ if (pat == NULL)
+ goto theend;
+
+ if (argvars[2].v_type != VAR_UNKNOWN) {
+ int error = FALSE;
+
+ start = get_tv_number_chk(&argvars[2], &error);
+ if (error)
+ goto theend;
+ if (l != NULL) {
+ li = list_find(l, start);
+ if (li == NULL)
+ goto theend;
+ idx = l->lv_idx; /* use the cached index */
+ } else {
+ if (start < 0)
+ start = 0;
+ if (start > (long)STRLEN(str))
+ goto theend;
+ /* When "count" argument is there ignore matches before "start",
+ * otherwise skip part of the string. Differs when pattern is "^"
+ * or "\<". */
+ if (argvars[3].v_type != VAR_UNKNOWN)
+ startcol = start;
+ else
+ str += start;
+ }
+
+ if (argvars[3].v_type != VAR_UNKNOWN)
+ nth = get_tv_number_chk(&argvars[3], &error);
+ if (error)
+ goto theend;
+ }
+
+ regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING);
+ if (regmatch.regprog != NULL) {
+ regmatch.rm_ic = p_ic;
+
+ for (;; ) {
+ if (l != NULL) {
+ if (li == NULL) {
+ match = FALSE;
+ break;
+ }
+ vim_free(tofree);
+ str = echo_string(&li->li_tv, &tofree, strbuf, 0);
+ if (str == NULL)
+ break;
+ }
+
+ match = vim_regexec_nl(&regmatch, str, (colnr_T)startcol);
+
+ if (match && --nth <= 0)
+ break;
+ if (l == NULL && !match)
+ break;
+
+ /* Advance to just after the match. */
+ if (l != NULL) {
+ li = li->li_next;
+ ++idx;
+ } else {
+ startcol = (colnr_T)(regmatch.startp[0]
+ + (*mb_ptr2len)(regmatch.startp[0]) - str);
+ }
+ }
+
+ 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) {
+ if (list_append_string(rettv->vval.v_list,
+ (char_u *)"", 0) == FAIL)
+ break;
+ } else if (list_append_string(rettv->vval.v_list,
+ regmatch.startp[i],
+ (int)(regmatch.endp[i] - regmatch.startp[i]))
+ == FAIL)
+ 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:
+ vim_free(tofree);
+ p_cpo = save_cpo;
+}
+
+/*
+ * "match()" function
+ */
+static void f_match(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ find_some_match(argvars, rettv, 1);
+}
+
+/*
+ * "matchadd()" function
+ */
+static void f_matchadd(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv UNUSED;
+{
+ 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 */
+ int id = -1;
+ int error = FALSE;
+
+ rettv->vval.v_number = -1;
+
+ if (grp == NULL || pat == 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 (error == TRUE)
+ return;
+ if (id >= 1 && id <= 3) {
+ EMSGN("E798: ID is reserved for \":match\": %ld", id);
+ return;
+ }
+
+ rettv->vval.v_number = match_add(curwin, grp, pat, prio, id);
+}
+
+/*
+ * "matcharg()" function
+ */
+static void f_matcharg(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv;
+{
+ if (rettv_list_alloc(rettv) == OK) {
+ int id = get_tv_number(&argvars[0]);
+ matchitem_T *m;
+
+ if (id >= 1 && id <= 3) {
+ 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);
+ } else {
+ list_append_string(rettv->vval.v_list, NULL, -1);
+ list_append_string(rettv->vval.v_list, NULL, -1);
+ }
+ }
+ }
+}
+
+/*
+ * "matchdelete()" function
+ */
+static void f_matchdelete(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv UNUSED;
+{
+ rettv->vval.v_number = match_delete(curwin,
+ (int)get_tv_number(&argvars[0]), TRUE);
+}
+
+/*
+ * "matchend()" function
+ */
+static void f_matchend(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ find_some_match(argvars, rettv, 0);
+}
+
+/*
+ * "matchlist()" function
+ */
+static void f_matchlist(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ find_some_match(argvars, rettv, 3);
+}
+
+/*
+ * "matchstr()" function
+ */
+static void f_matchstr(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ find_some_match(argvars, rettv, 2);
+}
+
+static void max_min __ARGS((typval_T *argvars, typval_T *rettv, int domax));
+
+static void max_min(argvars, rettv, domax)
+typval_T *argvars;
+typval_T *rettv;
+int domax;
+{
+ long n = 0;
+ long i;
+ int error = FALSE;
+
+ if (argvars[0].v_type == VAR_LIST) {
+ list_T *l;
+ listitem_T *li;
+
+ 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;
+ }
+ }
+ }
+ } 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;
+ }
+ }
+ }
+ } else
+ EMSG(_(e_listdictarg));
+ rettv->vval.v_number = error ? 0 : n;
+}
+
+/*
+ * "max()" function
+ */
+static void f_max(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ max_min(argvars, rettv, TRUE);
+}
+
+/*
+ * "min()" function
+ */
+static void f_min(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ max_min(argvars, rettv, FALSE);
+}
+
+static int mkdir_recurse __ARGS((char_u *dir, int prot));
+
+/*
+ * Create the directory in which "dir" is located, and higher levels when
+ * needed.
+ */
+static int mkdir_recurse(dir, prot)
+char_u *dir;
+int prot;
+{
+ char_u *p;
+ char_u *updir;
+ int r = FAIL;
+
+ /* Get end of directory name in "dir".
+ * We're done when it's "/" or "c:/". */
+ p = gettail_sep(dir);
+ if (p <= get_past_head(dir))
+ return OK;
+
+ /* If the directory exists we're done. Otherwise: create it.*/
+ updir = vim_strnsave(dir, (int)(p - dir));
+ if (updir == NULL)
+ return FAIL;
+ if (mch_isdir(updir))
+ r = OK;
+ else if (mkdir_recurse(updir, prot) == OK)
+ r = vim_mkdir_emsg(updir, prot);
+ vim_free(updir);
+ return r;
+}
+
+#ifdef vim_mkdir
+/*
+ * "mkdir()" function
+ */
+static void f_mkdir(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ char_u *dir;
+ char_u buf[NUMBUFLEN];
+ int prot = 0755;
+
+ rettv->vval.v_number = FAIL;
+ if (check_restricted() || check_secure())
+ return;
+
+ dir = get_tv_string_buf(&argvars[0], buf);
+ if (*dir == NUL)
+ rettv->vval.v_number = FAIL;
+ else {
+ if (*gettail(dir) == NUL)
+ /* remove trailing slashes */
+ *gettail_sep(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)
+ mkdir_recurse(dir, prot);
+ }
+ rettv->vval.v_number = prot == -1 ? FAIL : vim_mkdir_emsg(dir, prot);
+ }
+}
+#endif
+
+/*
+ * "mode()" function
+ */
+static void f_mode(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ char_u buf[3];
+
+ buf[1] = NUL;
+ buf[2] = NUL;
+
+ 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 {
+ 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]))
+ buf[1] = NUL;
+
+ rettv->vval.v_string = vim_strsave(buf);
+ rettv->v_type = VAR_STRING;
+}
+
+
+/*
+ * "nextnonblank()" function
+ */
+static void f_nextnonblank(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ linenr_T lnum;
+
+ for (lnum = get_tv_lnum(argvars);; ++lnum) {
+ if (lnum < 0 || lnum > curbuf->b_ml.ml_line_count) {
+ lnum = 0;
+ break;
+ }
+ if (*skipwhite(ml_get(lnum)) != NUL)
+ break;
+ }
+ rettv->vval.v_number = lnum;
+}
+
+/*
+ * "nr2char()" function
+ */
+static void f_nr2char(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ char_u buf[NUMBUFLEN];
+
+ if (has_mbyte) {
+ int utf8 = 0;
+
+ 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;
+ }
+ rettv->v_type = VAR_STRING;
+ rettv->vval.v_string = vim_strsave(buf);
+}
+
+/*
+ * "or(expr, expr)" function
+ */
+static void f_or(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ rettv->vval.v_number = get_tv_number_chk(&argvars[0], NULL)
+ | get_tv_number_chk(&argvars[1], NULL);
+}
+
+/*
+ * "pathshorten()" function
+ */
+static void f_pathshorten(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ char_u *p;
+
+ rettv->v_type = VAR_STRING;
+ p = get_tv_string_chk(&argvars[0]);
+ if (p == NULL)
+ rettv->vval.v_string = NULL;
+ else {
+ p = vim_strsave(p);
+ rettv->vval.v_string = p;
+ if (p != NULL)
+ shorten_dir(p);
+ }
+}
+
+/*
+ * "pow()" function
+ */
+static void f_pow(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ float_T fx, fy;
+
+ rettv->v_type = VAR_FLOAT;
+ if (get_float_arg(argvars, &fx) == OK
+ && get_float_arg(&argvars[1], &fy) == OK)
+ rettv->vval.v_float = pow(fx, fy);
+ else
+ rettv->vval.v_float = 0.0;
+}
+
+/*
+ * "prevnonblank()" function
+ */
+static void f_prevnonblank(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ linenr_T lnum;
+
+ lnum = get_tv_lnum(argvars);
+ if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count)
+ lnum = 0;
+ else
+ while (lnum >= 1 && *skipwhite(ml_get(lnum)) == NUL)
+ --lnum;
+ rettv->vval.v_number = lnum;
+}
+
+#ifdef HAVE_STDARG_H
+/* 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;
+#endif
+
+/*
+ * "printf()" function
+ */
+static void f_printf(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ rettv->v_type = VAR_STRING;
+ rettv->vval.v_string = NULL;
+#ifdef HAVE_STDARG_H /* only very old compilers can't do this */
+ {
+ char_u buf[NUMBUFLEN];
+ int len;
+ char_u *s;
+ 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);
+ if (!did_emsg) {
+ s = alloc(len + 1);
+ if (s != NULL) {
+ rettv->vval.v_string = s;
+ (void)vim_vsnprintf((char *)s, len + 1, fmt, ap, argvars + 1);
+ }
+ }
+ did_emsg |= saved_did_emsg;
+ }
+#endif
+}
+
+/*
+ * "pumvisible()" function
+ */
+static void f_pumvisible(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv UNUSED;
+{
+ if (pum_visible())
+ rettv->vval.v_number = 1;
+}
+
+
+
+/*
+ * "range()" function
+ */
+static void f_range(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ long start;
+ long end;
+ long stride = 1;
+ long i;
+ int error = FALSE;
+
+ start = get_tv_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);
+ }
+
+ 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)
+ EMSG(_("E727: Start past end"));
+ else {
+ if (rettv_list_alloc(rettv) == OK)
+ for (i = start; stride > 0 ? i <= end : i >= end; i += stride)
+ if (list_append_number(rettv->vval.v_list,
+ (varnumber_T)i) == FAIL)
+ break;
+ }
+}
+
+/*
+ * "readfile()" function
+ */
+static void f_readfile(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ int binary = FALSE;
+ int failed = FALSE;
+ char_u *fname;
+ FILE *fd;
+ char_u buf[(IOSIZE/256)*256]; /* rounded to avoid odd + 1 */
+ int io_size = sizeof(buf);
+ int readlen; /* size of last fread() */
+ char_u *prev = NULL; /* previously read bytes, if any */
+ 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 (rettv_list_alloc(rettv) == FAIL)
+ return;
+
+ /* 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);
+ return;
+ }
+
+ while (cnt < maxline || maxline < 0) {
+ 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. */
+ for (p = buf, start = buf;
+ p < buf + readlen || (readlen <= 0 && (prevlen > 0 || binary));
+ ++p) {
+ if (*p == '\n' || readlen <= 0) {
+ listitem_T *li;
+ char_u *s = NULL;
+ long_u len = p - start;
+
+ /* Finished a line. Remove CRs before NL. */
+ if (readlen > 0 && !binary) {
+ while (len > 0 && start[len - 1] == '\r')
+ --len;
+ /* removal may cross back to the "prev" string */
+ if (len == 0)
+ while (prevlen > 0 && prev[prevlen - 1] == '\r')
+ --prevlen;
+ }
+ if (prevlen == 0)
+ s = vim_strnsave(start, (int)len);
+ else {
+ /* Change "prev" buffer to be the right size. This way
+ * the bytes are only copied once, and very long lines are
+ * allocated only once. */
+ if ((s = vim_realloc(prev, prevlen + len + 1)) != NULL) {
+ mch_memmove(s + prevlen, start, len);
+ s[prevlen + len] = NUL;
+ prev = NULL; /* the list will own the string */
+ prevlen = prevsize = 0;
+ }
+ }
+ if (s == NULL) {
+ do_outofmem_msg((long_u) prevlen + len + 1);
+ failed = TRUE;
+ break;
+ }
+
+ if ((li = listitem_alloc()) == NULL) {
+ vim_free(s);
+ failed = TRUE;
+ break;
+ }
+ 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)
+ break;
+ } 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. */
+ char_u back1 = p >= buf + 1 ? p[-1]
+ : prevlen >= 1 ? prev[prevlen - 1] : NUL;
+ char_u back2 = p >= buf + 2 ? p[-2]
+ : p == buf + 1 && prevlen >= 1 ? prev[prevlen - 1]
+ : prevlen >= 2 ? prev[prevlen - 2] : NUL;
+
+ if (back2 == 0xef && back1 == 0xbb) {
+ char_u *dest = p - 2;
+
+ /* Usually a BOM is at the beginning of a file, and so at
+ * the beginning of a line; then we can just step over it.
+ */
+ if (start == dest)
+ start = p + 1;
+ else {
+ /* have to shuffle buf to close gap */
+ int adjust_prevlen = 0;
+
+ if (dest < buf) {
+ adjust_prevlen = (int)(buf - dest); /* must be 1 or 2 */
+ dest = buf;
+ }
+ if (readlen > p - buf + 1)
+ mch_memmove(dest, p + 1, readlen - (p - buf) - 1);
+ readlen -= 3 - adjust_prevlen;
+ prevlen -= adjust_prevlen;
+ p = dest - 1;
+ }
+ }
+ }
+ } /* for */
+
+ if (failed || (cnt >= maxline && maxline >= 0) || readlen <= 0)
+ break;
+ if (start < p) {
+ /* There's part of a line in buf, store it in "prev". */
+ if (p - start + prevlen >= prevsize) {
+ /* need bigger "prev" buffer */
+ char_u *newprev;
+
+ /* A common use case is ordinary text files and "prev" gets a
+ * fragment of a line, so the first allocation is made
+ * small, to avoid repeatedly 'allocing' large and
+ * 'reallocing' small. */
+ if (prevsize == 0)
+ prevsize = (long)(p - start);
+ else {
+ long grow50pc = (prevsize * 3) / 2;
+ long growmin = (long)((p - start) * 2 + prevlen);
+ prevsize = grow50pc > growmin ? grow50pc : growmin;
+ }
+ newprev = prev == NULL ? alloc(prevsize)
+ : vim_realloc(prev, prevsize);
+ if (newprev == NULL) {
+ do_outofmem_msg((long_u)prevsize);
+ failed = TRUE;
+ break;
+ }
+ prev = newprev;
+ }
+ /* Add the line part to end of "prev". */
+ mch_memmove(prev + prevlen, start, p - start);
+ prevlen += (long)(p - start);
+ }
+ } /* while */
+
+ /*
+ * For a negative line count use only the lines at the end of the file,
+ * free the rest.
+ */
+ if (!failed && maxline < 0)
+ while (cnt > -maxline) {
+ listitem_remove(rettv->vval.v_list, rettv->vval.v_list->lv_first);
+ --cnt;
+ }
+
+ if (failed) {
+ list_free(rettv->vval.v_list, TRUE);
+ /* readfile doc says an empty list is returned on error */
+ rettv->vval.v_list = list_alloc();
+ }
+
+ vim_free(prev);
+ fclose(fd);
+}
+
+static int list2proftime __ARGS((typval_T *arg, proftime_T *tm));
+
+/*
+ * Convert a List to proftime_T.
+ * Return FAIL when there is something wrong.
+ */
+static int list2proftime(arg, tm)
+typval_T *arg;
+proftime_T *tm;
+{
+ long n1, n2;
+ int error = FALSE;
+
+ if (arg->v_type != VAR_LIST || arg->vval.v_list == NULL
+ || arg->vval.v_list->lv_len != 2)
+ return FAIL;
+ n1 = list_find_nr(arg->vval.v_list, 0L, &error);
+ n2 = list_find_nr(arg->vval.v_list, 1L, &error);
+ tm->tv_sec = n1;
+ tm->tv_usec = n2;
+ return error ? FAIL : OK;
+}
+
+/*
+ * "reltime()" function
+ */
+static void f_reltime(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv UNUSED;
+{
+ proftime_T res;
+ proftime_T start;
+
+ if (argvars[0].v_type == VAR_UNKNOWN) {
+ /* No arguments: get current time. */
+ profile_start(&res);
+ } else if (argvars[1].v_type == VAR_UNKNOWN) {
+ if (list2proftime(&argvars[0], &res) == FAIL)
+ return;
+ profile_end(&res);
+ } else {
+ /* Two arguments: compute the difference. */
+ if (list2proftime(&argvars[0], &start) == FAIL
+ || list2proftime(&argvars[1], &res) == FAIL)
+ return;
+ profile_sub(&res, &start);
+ }
+
+ if (rettv_list_alloc(rettv) == OK) {
+ long n1, n2;
+
+ n1 = res.tv_sec;
+ n2 = res.tv_usec;
+ list_append_number(rettv->vval.v_list, (varnumber_T)n1);
+ list_append_number(rettv->vval.v_list, (varnumber_T)n2);
+ }
+}
+
+/*
+ * "reltimestr()" function
+ */
+static void f_reltimestr(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv;
+{
+ proftime_T tm;
+
+ rettv->v_type = VAR_STRING;
+ rettv->vval.v_string = NULL;
+ if (list2proftime(&argvars[0], &tm) == OK)
+ rettv->vval.v_string = vim_strsave((char_u *)profile_msg(&tm));
+}
+
+
+
+/*
+ * "remote_expr()" function
+ */
+static void f_remote_expr(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv;
+{
+ rettv->v_type = VAR_STRING;
+ rettv->vval.v_string = NULL;
+}
+
+/*
+ * "remote_foreground()" function
+ */
+static void f_remote_foreground(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv UNUSED;
+{
+}
+
+static void f_remote_peek(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv;
+{
+ rettv->vval.v_number = -1;
+}
+
+static void f_remote_read(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv;
+{
+ char_u *r = NULL;
+
+ rettv->v_type = VAR_STRING;
+ rettv->vval.v_string = r;
+}
+
+/*
+ * "remote_send()" function
+ */
+static void f_remote_send(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv;
+{
+ rettv->v_type = VAR_STRING;
+ rettv->vval.v_string = NULL;
+}
+
+/*
+ * "remove()" function
+ */
+static void f_remove(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ list_T *l;
+ listitem_T *item, *item2;
+ listitem_T *li;
+ long idx;
+ long end;
+ char_u *key;
+ dict_T *d;
+ dictitem_T *di;
+ char *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, (char_u *)_(arg_errmsg))) {
+ key = get_tv_string_chk(&argvars[1]);
+ if (key != NULL) {
+ di = dict_find(d, key, -1);
+ if (di == NULL)
+ EMSG2(_(e_dictkey), key);
+ else {
+ *rettv = di->di_tv;
+ init_tv(&di->di_tv);
+ dictitem_remove(d, di);
+ }
+ }
+ }
+ } 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, (char_u *)_(arg_errmsg))) {
+ int error = 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)
+ EMSGN(_(e_listidx), idx);
+ else {
+ if (argvars[2].v_type == VAR_UNKNOWN) {
+ /* Remove one item, return its value. */
+ list_remove(l, item, item);
+ *rettv = item->li_tv;
+ vim_free(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)
+ EMSGN(_(e_listidx), end);
+ else {
+ int cnt = 0;
+
+ for (li = item; li != NULL; li = li->li_next) {
+ ++cnt;
+ if (li == item2)
+ break;
+ }
+ if (li == NULL) /* didn't find "item2" after "item" */
+ EMSG(_(e_invrange));
+ else {
+ list_remove(l, item, item2);
+ if (rettv_list_alloc(rettv) == OK) {
+ l = rettv->vval.v_list;
+ l->lv_first = item;
+ l->lv_last = item2;
+ item->li_prev = NULL;
+ item2->li_next = NULL;
+ l->lv_len = cnt;
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+/*
+ * "rename({from}, {to})" function
+ */
+static void f_rename(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ char_u buf[NUMBUFLEN];
+
+ 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));
+}
+
+/*
+ * "repeat()" function
+ */
+static void f_repeat(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ char_u *p;
+ int n;
+ int slen;
+ int len;
+ char_u *r;
+ int i;
+
+ n = get_tv_number(&argvars[1]);
+ if (argvars[0].v_type == VAR_LIST) {
+ if (rettv_list_alloc(rettv) == OK && argvars[0].vval.v_list != NULL)
+ while (n-- > 0)
+ if (list_extend(rettv->vval.v_list,
+ argvars[0].vval.v_list, NULL) == FAIL)
+ break;
+ } else {
+ p = get_tv_string(&argvars[0]);
+ rettv->v_type = VAR_STRING;
+ rettv->vval.v_string = NULL;
+
+ slen = (int)STRLEN(p);
+ len = slen * n;
+ if (len <= 0)
+ return;
+
+ r = alloc(len + 1);
+ if (r != NULL) {
+ for (i = 0; i < n; i++)
+ mch_memmove(r + i * slen, p, (size_t)slen);
+ r[len] = NUL;
+ }
+
+ rettv->vval.v_string = r;
+ }
+}
+
+/*
+ * "resolve()" function
+ */
+static void f_resolve(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ char_u *p;
+#ifdef HAVE_READLINK
+ char_u *buf = NULL;
+#endif
+
+ p = get_tv_string(&argvars[0]);
+#ifdef FEAT_SHORTCUT
+ {
+ 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);
+ }
+#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;
+ int limit = 100;
+
+ p = vim_strsave(p);
+
+ if (p[0] == '.' && (vim_ispathsep(p[1])
+ || (p[1] == '.' && (vim_ispathsep(p[2])))))
+ is_relative_to_current = TRUE;
+
+ len = STRLEN(p);
+ if (len > 0 && after_pathsep(p, p + len)) {
+ has_trailing_pathsep = TRUE;
+ p[len - 1] = NUL; /* the trailing slash breaks readlink() */
+ }
+
+ q = getnextcomp(p);
+ if (*q != NUL) {
+ /* Separate the first path component in "p", and keep the
+ * remainder (beginning with the path separator). */
+ remain = vim_strsave(q - 1);
+ q[-1] = NUL;
+ }
+
+ buf = alloc(MAXPATHL + 1);
+ if (buf == NULL)
+ goto fail;
+
+ for (;; ) {
+ for (;; ) {
+ len = readlink((char *)p, (char *)buf, MAXPATHL);
+ if (len <= 0)
+ break;
+ buf[len] = NUL;
+
+ if (limit-- == 0) {
+ vim_free(p);
+ vim_free(remain);
+ EMSG(_("E655: Too many symbolic links (cycle?)"));
+ rettv->vval.v_string = NULL;
+ goto fail;
+ }
+
+ /* 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 = getnextcomp(vim_ispathsep(*buf) ? buf + 1 : buf);
+ if (*q != NUL) {
+ if (remain == NULL)
+ remain = vim_strsave(q - 1);
+ else {
+ cpy = concat_str(q - 1, remain);
+ if (cpy != NULL) {
+ vim_free(remain);
+ remain = cpy;
+ }
+ }
+ q[-1] = NUL;
+ }
+
+ q = gettail(p);
+ if (q > p && *q == NUL) {
+ /* Ignore trailing path separator. */
+ q[-1] = NUL;
+ q = gettail(p);
+ }
+ if (q > p && !mch_isFullName(buf)) {
+ /* symlink is relative to directory of argument */
+ cpy = alloc((unsigned)(STRLEN(p) + STRLEN(buf) + 1));
+ if (cpy != NULL) {
+ STRCPY(cpy, p);
+ STRCPY(gettail(cpy), buf);
+ vim_free(p);
+ p = cpy;
+ }
+ } else {
+ vim_free(p);
+ p = vim_strsave(buf);
+ }
+ }
+
+ if (remain == NULL)
+ break;
+
+ /* Append the first path component of "remain" to "p". */
+ q = getnextcomp(remain + 1);
+ len = q - remain - (*q != NUL);
+ cpy = vim_strnsave(p, STRLEN(p) + len);
+ if (cpy != NULL) {
+ STRNCAT(cpy, remain, len);
+ vim_free(p);
+ p = cpy;
+ }
+ /* Shorten "remain". */
+ if (*q != NUL)
+ STRMOVE(remain, q - 1);
+ else {
+ vim_free(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 (!vim_ispathsep(*p)) {
+ if (is_relative_to_current
+ && *p != NUL
+ && !(p[0] == '.'
+ && (p[1] == NUL
+ || vim_ispathsep(p[1])
+ || (p[1] == '.'
+ && (p[2] == NUL
+ || vim_ispathsep(p[2])))))) {
+ /* Prepend "./". */
+ cpy = concat_str((char_u *)"./", p);
+ if (cpy != NULL) {
+ vim_free(p);
+ p = cpy;
+ }
+ } else if (!is_relative_to_current) {
+ /* Strip leading "./". */
+ q = p;
+ while (q[0] == '.' && vim_ispathsep(q[1]))
+ q += 2;
+ 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 "//". */
+ if (!has_trailing_pathsep) {
+ q = p + STRLEN(p);
+ if (after_pathsep(p, q))
+ *gettail_sep(p) = NUL;
+ }
+
+ rettv->vval.v_string = p;
+ }
+# else
+ rettv->vval.v_string = vim_strsave(p);
+# endif
+#endif
+
+ simplify_filename(rettv->vval.v_string);
+
+#ifdef HAVE_READLINK
+fail:
+ vim_free(buf);
+#endif
+ rettv->v_type = VAR_STRING;
+}
+
+/*
+ * "reverse({list})" function
+ */
+static void f_reverse(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ list_T *l;
+ listitem_T *li, *ni;
+
+ 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 *)_("reverse() argument"))) {
+ 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;
+ }
+}
+
+#define SP_NOMOVE 0x01 /* don't move cursor */
+#define SP_REPEAT 0x02 /* repeat to find outer pair */
+#define SP_RETCOUNT 0x04 /* return matchcount */
+#define SP_SETPCMARK 0x08 /* set previous context mark */
+#define SP_START 0x10 /* accept match at start position */
+#define SP_SUBPAT 0x20 /* return nr of matching sub-pattern */
+#define SP_END 0x40 /* leave cursor at end of match */
+
+static int get_search_arg __ARGS((typval_T *varp, int *flagsp));
+
+/*
+ * Get flags for a search function.
+ * Possibly sets "p_ws".
+ * Returns BACKWARD, FORWARD or zero (for an error).
+ */
+static int get_search_arg(varp, flagsp)
+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 */
+ 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;
+ }
+ if (mask == 0) {
+ EMSG2(_(e_invarg2), flags);
+ dir = 0;
+ } else
+ *flagsp |= mask;
+ }
+ if (dir == 0)
+ break;
+ ++flags;
+ }
+ }
+ return dir;
+}
+
+/*
+ * Shared by search() and searchpos() functions
+ */
+static int search_cmn(argvars, match_pos, flagsp)
+typval_T *argvars;
+pos_T *match_pos;
+int *flagsp;
+{
+ int flags;
+ char_u *pat;
+ pos_T pos;
+ pos_T save_cursor;
+ int save_p_ws = p_ws;
+ int dir;
+ int retval = 0; /* default: FAIL */
+ long lnum_stop = 0;
+ proftime_T tm;
+ long time_limit = 0;
+ 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)
+ goto theend;
+ flags = *flagsp;
+ if (flags & SP_START)
+ options |= SEARCH_START;
+ if (flags & SP_END)
+ options |= SEARCH_END;
+
+ /* 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)
+ goto theend;
+ if (argvars[3].v_type != VAR_UNKNOWN) {
+ time_limit = get_tv_number_chk(&argvars[3], NULL);
+ if (time_limit < 0)
+ goto theend;
+ }
+ }
+
+ /* Set the time limit, if there is one. */
+ profile_setlimit(time_limit, &tm);
+
+ /*
+ * This function does not accept SP_REPEAT and SP_RETCOUNT flags.
+ * Check to make sure only those flags are set.
+ * Also, Only the SP_NOMOVE or the SP_SETPCMARK flag can be set. Both
+ * flags cannot be set. Check for that condition also.
+ */
+ if (((flags & (SP_REPEAT | SP_RETCOUNT)) != 0)
+ || ((flags & SP_NOMOVE) && (flags & SP_SETPCMARK))) {
+ EMSG2(_(e_invarg2), get_tv_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);
+ if (subpatnum != FAIL) {
+ if (flags & SP_SUBPAT)
+ retval = subpatnum;
+ else
+ retval = pos.lnum;
+ if (flags & SP_SETPCMARK)
+ setpcmark();
+ curwin->w_cursor = pos;
+ if (match_pos != NULL) {
+ /* Store the match cursor position */
+ match_pos->lnum = pos.lnum;
+ match_pos->col = pos.col + 1;
+ }
+ /* "/$" will put the cursor after the end of the line, may need to
+ * correct that here */
+ check_cursor();
+ }
+
+ /* If 'n' flag is used: restore cursor position. */
+ if (flags & SP_NOMOVE)
+ curwin->w_cursor = save_cursor;
+ else
+ curwin->w_set_curswant = TRUE;
+theend:
+ p_ws = save_p_ws;
+
+ return retval;
+}
+
+
+/*
+ * round() is not in C90, use ceil() or floor() instead.
+ */
+float_T vim_round(f)
+float_T f;
+{
+ return f > 0 ? floor(f + 0.5) : ceil(f - 0.5);
+}
+
+/*
+ * "round({float})" function
+ */
+static void f_round(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ float_T f;
+
+ rettv->v_type = VAR_FLOAT;
+ if (get_float_arg(argvars, &f) == OK)
+ rettv->vval.v_float = vim_round(f);
+ else
+ rettv->vval.v_float = 0.0;
+}
+
+/*
+ * "screenattr()" function
+ */
+static void f_screenattr(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv;
+{
+ 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)
+ c = -1;
+ else
+ c = ScreenAttrs[LineOffset[row] + col];
+ rettv->vval.v_number = c;
+}
+
+/*
+ * "screenchar()" function
+ */
+static void f_screenchar(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv;
+{
+ 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)
+ c = -1;
+ else {
+ off = LineOffset[row] + col;
+ if (enc_utf8 && ScreenLinesUC[off] != 0)
+ c = ScreenLinesUC[off];
+ else
+ c = ScreenLines[off];
+ }
+ rettv->vval.v_number = c;
+}
+
+/*
+ * "screencol()" function
+ *
+ * First column is 1 to be consistent with virtcol().
+ */
+static void f_screencol(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv;
+{
+ rettv->vval.v_number = screen_screencol() + 1;
+}
+
+/*
+ * "screenrow()" function
+ */
+static void f_screenrow(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv;
+{
+ rettv->vval.v_number = screen_screenrow() + 1;
+}
+
+/*
+ * "search()" function
+ */
+static void f_search(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ int flags = 0;
+
+ rettv->vval.v_number = search_cmn(argvars, NULL, &flags);
+}
+
+/*
+ * "searchdecl()" function
+ */
+static void f_searchdecl(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ int locally = 1;
+ int thisblock = 0;
+ int error = FALSE;
+ char_u *name;
+
+ rettv->vval.v_number = 1; /* default: FAIL */
+
+ name = get_tv_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;
+ }
+ if (!error && name != NULL)
+ rettv->vval.v_number = find_decl(name, (int)STRLEN(name),
+ locally, thisblock, SEARCH_KEEP) == FAIL;
+}
+
+/*
+ * Used by searchpair() and searchpairpos()
+ */
+static int searchpair_cmn(argvars, match_pos)
+typval_T *argvars;
+pos_T *match_pos;
+{
+ char_u *spat, *mpat, *epat;
+ char_u *skip;
+ int 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 */
+ 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 */
+
+ /* 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.
+ */
+ if ((flags & (SP_END | SP_SUBPAT)) != 0
+ || ((flags & SP_NOMOVE) && (flags & SP_SETPCMARK))) {
+ EMSG2(_(e_invarg2), get_tv_string(&argvars[3]));
+ goto theend;
+ }
+
+ /* Using 'r' implies 'W', otherwise it doesn't work. */
+ if (flags & SP_REPEAT)
+ p_ws = FALSE;
+
+ /* Optional fifth argument: skip expression */
+ 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);
+ if (argvars[5].v_type != VAR_UNKNOWN) {
+ lnum_stop = get_tv_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)
+ goto theend;
+ }
+ }
+ }
+ if (skip == NULL)
+ goto theend; /* type error */
+
+ retval = do_searchpair(spat, mpat, epat, dir, skip, flags,
+ match_pos, lnum_stop, time_limit);
+
+theend:
+ p_ws = save_p_ws;
+
+ return retval;
+}
+
+/*
+ * "searchpair()" function
+ */
+static void f_searchpair(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ rettv->vval.v_number = searchpair_cmn(argvars, NULL);
+}
+
+/*
+ * "searchpairpos()" function
+ */
+static void f_searchpairpos(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ pos_T match_pos;
+ int lnum = 0;
+ int col = 0;
+
+ if (rettv_list_alloc(rettv) == FAIL)
+ return;
+
+ 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);
+}
+
+/*
+ * Search for a start/middle/end thing.
+ * Used by searchpair(), see its documentation for the details.
+ * Returns 0 or -1 for no match,
+ */
+long do_searchpair(spat, mpat, epat, dir, skip, flags, match_pos,
+ lnum_stop, time_limit)
+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 UNUSED; /* stop after this many msec */
+{
+ char_u *save_cpo;
+ char_u *pat, *pat2 = NULL, *pat3 = NULL;
+ long retval = 0;
+ pos_T pos;
+ pos_T firstpos;
+ pos_T foundpos;
+ pos_T save_cursor;
+ pos_T save_pos;
+ int n;
+ int r;
+ int nest = 1;
+ int err;
+ int options = SEARCH_KEEP;
+ proftime_T tm;
+
+ /* Make 'cpoptions' empty, the 'l' flag should not be used here. */
+ save_cpo = p_cpo;
+ p_cpo = empty_option;
+
+ /* Set the time limit, if there is one. */
+ profile_setlimit(time_limit, &tm);
+
+ /* Make two search patterns: start/end (pat2, for in nested pairs) and
+ * start/middle/end (pat3, for the top pair). */
+ pat2 = alloc((unsigned)(STRLEN(spat) + STRLEN(epat) + 15));
+ pat3 = alloc((unsigned)(STRLEN(spat) + STRLEN(mpat) + STRLEN(epat) + 23));
+ if (pat2 == NULL || pat3 == NULL)
+ goto theend;
+ sprintf((char *)pat2, "\\(%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)
+ options |= SEARCH_START;
+
+ save_cursor = curwin->w_cursor;
+ pos = curwin->w_cursor;
+ clearpos(&firstpos);
+ clearpos(&foundpos);
+ pat = pat3;
+ for (;; ) {
+ n = searchit(curwin, curbuf, &pos, dir, pat, 1L,
+ options, RE_SEARCH, lnum_stop, &tm);
+ if (n == FAIL || (firstpos.lnum != 0 && equalpos(pos, firstpos)))
+ /* didn't find it or found the first match again: FAIL */
+ break;
+
+ if (firstpos.lnum == 0)
+ firstpos = pos;
+ if (equalpos(pos, foundpos)) {
+ /* Found the same position again. Can happen with a pattern that
+ * has "\zs" at the end and searching backwards. Advance one
+ * character and try again. */
+ if (dir == BACKWARD)
+ decl(&pos);
+ else
+ incl(&pos);
+ }
+ foundpos = pos;
+
+ /* clear the start flag to avoid getting stuck here */
+ options &= ~SEARCH_START;
+
+ /* If the skip pattern matches, ignore this match. */
+ if (*skip != NUL) {
+ save_pos = curwin->w_cursor;
+ curwin->w_cursor = pos;
+ r = eval_to_bool(skip, &err, NULL, FALSE);
+ curwin->w_cursor = save_pos;
+ if (err) {
+ /* Evaluating {skip} caused an error, break here. */
+ curwin->w_cursor = save_cursor;
+ retval = -1;
+ break;
+ }
+ if (r)
+ continue;
+ }
+
+ if ((dir == BACKWARD && n == 3) || (dir == FORWARD && n == 2)) {
+ /* Found end when searching backwards or start when searching
+ * forward: nested pair. */
+ ++nest;
+ pat = pat2; /* nested, don't search for middle */
+ } else {
+ /* Found end when searching forward or start when searching
+ * backward: end of (nested) pair; or found middle in outer pair. */
+ if (--nest == 1)
+ pat = pat3; /* outer level, search for middle */
+ }
+
+ if (nest == 0) {
+ /* Found the match: return matchcount or line number. */
+ if (flags & SP_RETCOUNT)
+ ++retval;
+ else
+ retval = pos.lnum;
+ if (flags & SP_SETPCMARK)
+ setpcmark();
+ curwin->w_cursor = pos;
+ if (!(flags & SP_REPEAT))
+ break;
+ nest = 1; /* search for next unmatched */
+ }
+ }
+
+ if (match_pos != NULL) {
+ /* Store the match cursor position */
+ match_pos->lnum = curwin->w_cursor.lnum;
+ match_pos->col = curwin->w_cursor.col + 1;
+ }
+
+ /* If 'n' flag is used or search failed: restore cursor position. */
+ if ((flags & SP_NOMOVE) || retval == 0)
+ curwin->w_cursor = save_cursor;
+
+theend:
+ vim_free(pat2);
+ vim_free(pat3);
+ if (p_cpo == empty_option)
+ p_cpo = save_cpo;
+ else
+ /* Darn, evaluating the {skip} expression changed the value. */
+ free_string_option(save_cpo);
+
+ return retval;
+}
+
+/*
+ * "searchpos()" function
+ */
+static void f_searchpos(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ pos_T match_pos;
+ int lnum = 0;
+ int col = 0;
+ int n;
+ int flags = 0;
+
+ if (rettv_list_alloc(rettv) == FAIL)
+ return;
+
+ n = search_cmn(argvars, &match_pos, &flags);
+ if (n > 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);
+ if (flags & SP_SUBPAT)
+ list_append_number(rettv->vval.v_list, (varnumber_T)n);
+}
+
+
+static void f_server2client(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv;
+{
+ rettv->vval.v_number = -1;
+}
+
+static void f_serverlist(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv;
+{
+ char_u *r = NULL;
+
+ rettv->v_type = VAR_STRING;
+ rettv->vval.v_string = r;
+}
+
+/*
+ * "setbufvar()" function
+ */
+static void f_setbufvar(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv UNUSED;
+{
+ buf_T *buf;
+ aco_save_T aco;
+ char_u *varname, *bufvarname;
+ typval_T *varp;
+ char_u nbuf[NUMBUFLEN];
+
+ if (check_restricted() || check_secure())
+ 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);
+
+ if (*varname == '&') {
+ long numval;
+ char_u *strval;
+ int error = FALSE;
+
+ ++varname;
+ numval = get_tv_number_chk(varp, &error);
+ strval = get_tv_string_buf_chk(varp, nbuf);
+ if (!error && strval != NULL)
+ set_option_value(varname, numval, strval, OPT_LOCAL);
+ } else {
+ bufvarname = alloc((unsigned)STRLEN(varname) + 3);
+ if (bufvarname != NULL) {
+ STRCPY(bufvarname, "b:");
+ STRCPY(bufvarname + 2, varname);
+ set_var(bufvarname, varp, TRUE);
+ vim_free(bufvarname);
+ }
+ }
+
+ /* reset notion of buffer */
+ aucmd_restbuf(&aco);
+ }
+}
+
+/*
+ * "setcmdpos()" function
+ */
+static void f_setcmdpos(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ int pos = (int)get_tv_number(&argvars[0]) - 1;
+
+ if (pos >= 0)
+ rettv->vval.v_number = set_cmdline_pos(pos);
+}
+
+/*
+ * "setline()" function
+ */
+static void f_setline(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ 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]);
+ 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]);
+
+ /* default result is zero == OK */
+ for (;; ) {
+ if (l != NULL) {
+ /* list argument, get next string */
+ if (li == NULL)
+ break;
+ line = get_tv_string_chk(&li->li_tv);
+ li = li->li_next;
+ }
+
+ 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. */
+ if (u_sync_once == 2) {
+ u_sync_once = 1; /* notify that u_sync() was called */
+ u_sync(TRUE);
+ }
+
+ if (lnum <= curbuf->b_ml.ml_line_count) {
+ /* existing line, replace it */
+ if (u_savesub(lnum) == OK && ml_replace(lnum, 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 */
+ }
+
+ if (l == NULL) /* only one string argument */
+ break;
+ ++lnum;
+ }
+
+ if (added > 0)
+ appended_lines_mark(lcount, added);
+}
+
+static void set_qf_ll_list __ARGS((win_T *wp, typval_T *list_arg, typval_T *
+ action_arg,
+ typval_T *rettv));
+
+/*
+ * Used by "setqflist()" and "setloclist()" functions
+ */
+static void set_qf_ll_list(wp, list_arg, action_arg, rettv)
+win_T *wp UNUSED;
+typval_T *list_arg UNUSED;
+typval_T *action_arg UNUSED;
+typval_T *rettv;
+{
+ char_u *act;
+ int action = ' ';
+
+ rettv->vval.v_number = -1;
+
+ if (list_arg->v_type != VAR_LIST)
+ EMSG(_(e_listreq));
+ else {
+ list_T *l = list_arg->vval.v_list;
+
+ if (action_arg->v_type == VAR_STRING) {
+ act = get_tv_string_chk(action_arg);
+ if (act == NULL)
+ return; /* type error; errmsg already given */
+ if (*act == 'a' || *act == 'r')
+ action = *act;
+ }
+
+ if (l != NULL && set_errorlist(wp, l, action,
+ (char_u *)(wp == NULL ? "setqflist()" : "setloclist()")) == OK)
+ rettv->vval.v_number = 0;
+ }
+}
+
+/*
+ * "setloclist()" function
+ */
+static void f_setloclist(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ win_T *win;
+
+ rettv->vval.v_number = -1;
+
+ win = find_win_by_nr(&argvars[0], NULL);
+ if (win != NULL)
+ set_qf_ll_list(win, &argvars[1], &argvars[2], rettv);
+}
+
+/*
+ * "setmatches()" function
+ */
+static void f_setmatches(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv UNUSED;
+{
+ list_T *l;
+ listitem_T *li;
+ dict_T *d;
+
+ rettv->vval.v_number = -1;
+ if (argvars[0].v_type != VAR_LIST) {
+ 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 *)"priority", -1) != NULL
+ && dict_find(d, (char_u *)"id", -1) != NULL)) {
+ EMSG(_(e_invarg));
+ return;
+ }
+ li = li->li_next;
+ }
+
+ clear_matches(curwin);
+ li = l->lv_first;
+ while (li != NULL) {
+ d = li->li_tv.vval.v_dict;
+ match_add(curwin, get_dict_string(d, (char_u *)"group", FALSE),
+ get_dict_string(d, (char_u *)"pattern", FALSE),
+ (int)get_dict_number(d, (char_u *)"priority"),
+ (int)get_dict_number(d, (char_u *)"id"));
+ li = li->li_next;
+ }
+ rettv->vval.v_number = 0;
+ }
+}
+
+/*
+ * "setpos()" function
+ */
+static void f_setpos(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ pos_T pos;
+ int fnum;
+ char_u *name;
+
+ rettv->vval.v_number = -1;
+ name = get_tv_string_chk(argvars);
+ if (name != NULL) {
+ if (list2fpos(&argvars[1], &pos, &fnum) == 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;
+ check_cursor();
+ rettv->vval.v_number = 0;
+ } else
+ EMSG(_(e_invarg));
+ } else if (name[0] == '\'' && name[1] != NUL && name[2] == NUL) {
+ /* set mark */
+ if (setmark_pos(name[1], &pos, fnum) == OK)
+ rettv->vval.v_number = 0;
+ } else
+ EMSG(_(e_invarg));
+ }
+ }
+}
+
+/*
+ * "setqflist()" function
+ */
+static void f_setqflist(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ set_qf_ll_list(NULL, &argvars[0], &argvars[1], rettv);
+}
+
+/*
+ * "setreg()" function
+ */
+static void f_setreg(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ int regname;
+ char_u *strregname;
+ char_u *stropt;
+ char_u *strval;
+ int append;
+ char_u yank_type;
+ long block_len;
+
+ block_len = -1;
+ yank_type = MAUTO;
+ append = FALSE;
+
+ strregname = get_tv_string_chk(argvars);
+ rettv->vval.v_number = 1; /* FAIL is default */
+
+ if (strregname == NULL)
+ return; /* type error; errmsg already given */
+ regname = *strregname;
+ if (regname == 0 || regname == '@')
+ regname = '"';
+ else if (regname == '=')
+ return;
+
+ if (argvars[2].v_type != VAR_UNKNOWN) {
+ stropt = get_tv_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 = MCHAR;
+ break;
+ case 'V': case 'l': /* line-wise selection */
+ yank_type = MLINE;
+ break;
+ case 'b': case Ctrl_V: /* block-wise selection */
+ yank_type = MBLOCK;
+ if (VIM_ISDIGIT(stropt[1])) {
+ ++stropt;
+ block_len = getdigits(&stropt) - 1;
+ --stropt;
+ }
+ break;
+ }
+ }
+
+ strval = get_tv_string_chk(&argvars[1]);
+ if (strval != NULL)
+ write_reg_contents_ex(regname, strval, -1,
+ append, yank_type, block_len);
+ rettv->vval.v_number = 0;
+}
+
+/*
+ * "settabvar()" function
+ */
+static void f_settabvar(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ tabpage_T *save_curtab;
+ tabpage_T *tp;
+ char_u *varname, *tabvarname;
+ typval_T *varp;
+
+ rettv->vval.v_number = 0;
+
+ 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];
+
+ if (varname != NULL && varp != NULL
+ && tp != NULL
+ ) {
+ save_curtab = curtab;
+ goto_tabpage_tp(tp, FALSE, FALSE);
+
+ tabvarname = alloc((unsigned)STRLEN(varname) + 3);
+ if (tabvarname != NULL) {
+ STRCPY(tabvarname, "t:");
+ STRCPY(tabvarname + 2, varname);
+ set_var(tabvarname, varp, TRUE);
+ vim_free(tabvarname);
+ }
+
+ /* Restore current tabpage */
+ if (valid_tabpage(save_curtab))
+ goto_tabpage_tp(save_curtab, FALSE, FALSE);
+ }
+}
+
+/*
+ * "settabwinvar()" function
+ */
+static void f_settabwinvar(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ setwinvar(argvars, rettv, 1);
+}
+
+/*
+ * "setwinvar()" function
+ */
+static void f_setwinvar(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ setwinvar(argvars, rettv, 0);
+}
+
+/*
+ * "setwinvar()" and "settabwinvar()" functions
+ */
+
+static void setwinvar(argvars, rettv, off)
+typval_T *argvars;
+typval_T *rettv UNUSED;
+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())
+ return;
+
+ if (off == 1)
+ tp = find_tabpage((int)get_tv_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];
+
+ if (win != NULL && varname != NULL && varp != NULL) {
+ if (switch_win(&save_curwin, &save_curtab, win, tp, TRUE) == FAIL)
+ return;
+
+ if (*varname == '&') {
+ long numval;
+ char_u *strval;
+ int error = FALSE;
+
+ ++varname;
+ numval = get_tv_number_chk(varp, &error);
+ strval = get_tv_string_buf_chk(varp, nbuf);
+ if (!error && strval != NULL)
+ set_option_value(varname, numval, strval, OPT_LOCAL);
+ } else {
+ winvarname = alloc((unsigned)STRLEN(varname) + 3);
+ if (winvarname != NULL) {
+ STRCPY(winvarname, "w:");
+ STRCPY(winvarname + 2, varname);
+ set_var(winvarname, varp, TRUE);
+ vim_free(winvarname);
+ }
+ }
+
+ restore_win(save_curwin, save_curtab, TRUE);
+ }
+}
+
+/*
+ * "sha256({string})" function
+ */
+static void f_sha256(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ char_u *p;
+
+ p = get_tv_string(&argvars[0]);
+ rettv->vval.v_string = vim_strsave(
+ sha256_bytes(p, (int)STRLEN(p), NULL, 0));
+ rettv->v_type = VAR_STRING;
+}
+
+/*
+ * "shellescape({string})" function
+ */
+static void f_shellescape(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ rettv->vval.v_string = vim_strsave_shellescape(
+ get_tv_string(&argvars[0]), non_zero_arg(&argvars[1]));
+ rettv->v_type = VAR_STRING;
+}
+
+/*
+ * shiftwidth() function
+ */
+static void f_shiftwidth(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv;
+{
+ rettv->vval.v_number = get_sw_value(curbuf);
+}
+
+/*
+ * "simplify()" function
+ */
+static void f_simplify(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ 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 */
+ rettv->v_type = VAR_STRING;
+}
+
+/*
+ * "sin()" function
+ */
+static void f_sin(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ float_T f;
+
+ rettv->v_type = VAR_FLOAT;
+ if (get_float_arg(argvars, &f) == OK)
+ rettv->vval.v_float = sin(f);
+ else
+ rettv->vval.v_float = 0.0;
+}
+
+/*
+ * "sinh()" function
+ */
+static void f_sinh(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ float_T f;
+
+ rettv->v_type = VAR_FLOAT;
+ if (get_float_arg(argvars, &f) == OK)
+ rettv->vval.v_float = sinh(f);
+ else
+ rettv->vval.v_float = 0.0;
+}
+
+static int
+item_compare __ARGS((const void *s1, const void *s2));
+static int
+item_compare2 __ARGS((const void *s1, const void *s2));
+
+static int item_compare_ic;
+static char_u *item_compare_func;
+static dict_T *item_compare_selfdict;
+static int item_compare_func_err;
+#define ITEM_COMPARE_FAIL 999
+
+/*
+ * Compare functions for f_sort() below.
+ */
+static int item_compare(s1, s2)
+const void *s1;
+const void *s2;
+{
+ char_u *p1, *p2;
+ char_u *tofree1, *tofree2;
+ int res;
+ char_u numbuf1[NUMBUFLEN];
+ char_u numbuf2[NUMBUFLEN];
+
+ p1 = tv2string(&(*(listitem_T **)s1)->li_tv, &tofree1, numbuf1, 0);
+ p2 = tv2string(&(*(listitem_T **)s2)->li_tv, &tofree2, numbuf2, 0);
+ if (p1 == NULL)
+ p1 = (char_u *)"";
+ if (p2 == NULL)
+ p2 = (char_u *)"";
+ if (item_compare_ic)
+ res = STRICMP(p1, p2);
+ else
+ res = STRCMP(p1, p2);
+ vim_free(tofree1);
+ vim_free(tofree2);
+ return res;
+}
+
+static int item_compare2(s1, s2)
+const void *s1;
+const void *s2;
+{
+ int res;
+ typval_T rettv;
+ typval_T argv[3];
+ int dummy;
+
+ /* shortcut after failure in previous call; compare all items equal */
+ if (item_compare_func_err)
+ return 0;
+
+ /* 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(&(*(listitem_T **)s1)->li_tv, &argv[0]);
+ copy_tv(&(*(listitem_T **)s2)->li_tv, &argv[1]);
+
+ rettv.v_type = VAR_UNKNOWN; /* clear_tv() uses this */
+ res = call_func(item_compare_func, (int)STRLEN(item_compare_func),
+ &rettv, 2, argv, 0L, 0L, &dummy, TRUE,
+ item_compare_selfdict);
+ clear_tv(&argv[0]);
+ clear_tv(&argv[1]);
+
+ if (res == FAIL)
+ res = ITEM_COMPARE_FAIL;
+ else
+ res = get_tv_number_chk(&rettv, &item_compare_func_err);
+ if (item_compare_func_err)
+ res = ITEM_COMPARE_FAIL; /* return value has wrong type */
+ clear_tv(&rettv);
+ return res;
+}
+
+/*
+ * "sort({list})" function
+ */
+static void f_sort(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ list_T *l;
+ listitem_T *li;
+ listitem_T **ptrs;
+ long len;
+ long i;
+
+ if (argvars[0].v_type != VAR_LIST)
+ EMSG2(_(e_listarg), "sort()");
+ else {
+ l = argvars[0].vval.v_list;
+ if (l == NULL || tv_check_lock(l->lv_lock,
+ (char_u *)_("sort() argument")))
+ return;
+ rettv->vval.v_list = l;
+ rettv->v_type = VAR_LIST;
+ ++l->lv_refcount;
+
+ len = list_len(l);
+ if (len <= 1)
+ return; /* short list sorts pretty quickly */
+
+ item_compare_ic = FALSE;
+ item_compare_func = NULL;
+ item_compare_selfdict = NULL;
+ if (argvars[1].v_type != VAR_UNKNOWN) {
+ /* optional second argument: {func} */
+ if (argvars[1].v_type == VAR_FUNC)
+ item_compare_func = argvars[1].vval.v_string;
+ else {
+ int error = FALSE;
+
+ i = get_tv_number_chk(&argvars[1], &error);
+ if (error)
+ return; /* type error; errmsg already given */
+ if (i == 1)
+ item_compare_ic = TRUE;
+ else
+ item_compare_func = get_tv_string(&argvars[1]);
+ }
+
+ if (argvars[2].v_type != VAR_UNKNOWN) {
+ /* optional third argument: {dict} */
+ if (argvars[2].v_type != VAR_DICT) {
+ EMSG(_(e_dictreq));
+ return;
+ }
+ item_compare_selfdict = argvars[2].vval.v_dict;
+ }
+ }
+
+ /* Make an array with each entry pointing to an item in the List. */
+ ptrs = (listitem_T **)alloc((int)(len * sizeof(listitem_T *)));
+ if (ptrs == NULL)
+ return;
+ i = 0;
+ for (li = l->lv_first; li != NULL; li = li->li_next)
+ ptrs[i++] = li;
+
+ item_compare_func_err = FALSE;
+ /* test the compare function */
+ if (item_compare_func != NULL
+ && item_compare2((void *)&ptrs[0], (void *)&ptrs[1])
+ == ITEM_COMPARE_FAIL)
+ EMSG(_("E702: Sort compare function failed"));
+ else {
+ /* Sort the array with item pointers. */
+ qsort((void *)ptrs, (size_t)len, sizeof(listitem_T *),
+ item_compare_func == NULL ? item_compare : item_compare2);
+
+ if (!item_compare_func_err) {
+ /* Clear the List and append the items in the sorted order. */
+ l->lv_first = l->lv_last = l->lv_idx_item = NULL;
+ l->lv_len = 0;
+ for (i = 0; i < len; ++i)
+ list_append(l, ptrs[i]);
+ }
+ }
+
+ vim_free(ptrs);
+ }
+}
+
+/*
+ * "soundfold({word})" function
+ */
+static void f_soundfold(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ char_u *s;
+
+ rettv->v_type = VAR_STRING;
+ s = get_tv_string(&argvars[0]);
+ rettv->vval.v_string = eval_soundfold(s);
+}
+
+/*
+ * "spellbadword()" function
+ */
+static void f_spellbadword(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv;
+{
+ char_u *word = (char_u *)"";
+ hlf_T attr = HLF_COUNT;
+ int len = 0;
+
+ if (rettv_list_alloc(rettv) == FAIL)
+ return;
+
+ 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 = ml_get_cursor();
+ } else if (curwin->w_p_spell && *curbuf->b_s.b_p_spl != NUL) {
+ char_u *str = get_tv_string_chk(&argvars[0]);
+ int capcol = -1;
+
+ if (str != NULL) {
+ /* Check the argument for spelling. */
+ while (*str != NUL) {
+ len = spell_check(curwin, str, &attr, &capcol, FALSE);
+ if (attr != HLF_COUNT) {
+ word = str;
+ break;
+ }
+ str += len;
+ }
+ }
+ }
+
+ list_append_string(rettv->vval.v_list, word, 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);
+}
+
+/*
+ * "spellsuggest()" function
+ */
+static void f_spellsuggest(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv;
+{
+ char_u *str;
+ int typeerr = FALSE;
+ int maxcount;
+ garray_T ga;
+ int i;
+ listitem_T *li;
+ int need_capital = FALSE;
+
+ if (rettv_list_alloc(rettv) == FAIL)
+ return;
+
+ if (curwin->w_p_spell && *curwin->w_s->b_p_spl != NUL) {
+ str = get_tv_string(&argvars[0]);
+ if (argvars[1].v_type != VAR_UNKNOWN) {
+ maxcount = get_tv_number_chk(&argvars[1], &typeerr);
+ if (maxcount <= 0)
+ return;
+ if (argvars[2].v_type != VAR_UNKNOWN) {
+ need_capital = get_tv_number_chk(&argvars[2], &typeerr);
+ if (typeerr)
+ return;
+ }
+ } else
+ maxcount = 25;
+
+ spell_suggest_list(&ga, str, maxcount, need_capital, FALSE);
+
+ for (i = 0; i < ga.ga_len; ++i) {
+ str = ((char_u **)ga.ga_data)[i];
+
+ li = listitem_alloc();
+ if (li == NULL)
+ vim_free(str);
+ else {
+ 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);
+ }
+}
+
+static void f_split(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ 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;
+
+ /* 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]);
+ 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);
+ }
+ if (pat == NULL || *pat == NUL)
+ pat = (char_u *)"[\\x01- ]\\+";
+
+ if (rettv_list_alloc(rettv) == FAIL)
+ return;
+ if (typeerr)
+ return;
+
+ regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING);
+ 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])) {
+ if (list_append_string(rettv->vval.v_list, str,
+ (int)(end - str)) == FAIL)
+ break;
+ }
+ if (!match)
+ break;
+ /* Advance to just after the match. */
+ if (regmatch.endp[0] > str)
+ col = 0;
+ else {
+ /* Don't get stuck at the same match. */
+ col = (*mb_ptr2len)(regmatch.endp[0]);
+ }
+ str = regmatch.endp[0];
+ }
+
+ vim_regfree(regmatch.regprog);
+ }
+
+ p_cpo = save_cpo;
+}
+
+/*
+ * "sqrt()" function
+ */
+static void f_sqrt(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ float_T f;
+
+ rettv->v_type = VAR_FLOAT;
+ if (get_float_arg(argvars, &f) == OK)
+ rettv->vval.v_float = sqrt(f);
+ else
+ rettv->vval.v_float = 0.0;
+}
+
+/*
+ * "str2float()" function
+ */
+static void f_str2float(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ char_u *p = skipwhite(get_tv_string(&argvars[0]));
+
+ if (*p == '+')
+ p = skipwhite(p + 1);
+ (void)string2float(p, &rettv->vval.v_float);
+ rettv->v_type = VAR_FLOAT;
+}
+
+/*
+ * "str2nr()" function
+ */
+static void f_str2nr(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ int base = 10;
+ char_u *p;
+ long n;
+
+ if (argvars[1].v_type != VAR_UNKNOWN) {
+ base = get_tv_number(&argvars[1]);
+ if (base != 8 && base != 10 && base != 16) {
+ EMSG(_(e_invarg));
+ return;
+ }
+ }
+
+ p = skipwhite(get_tv_string(&argvars[0]));
+ if (*p == '+')
+ p = skipwhite(p + 1);
+ vim_str2nr(p, NULL, NULL, base == 8 ? 2 : 0, base == 16 ? 2 : 0, &n, NULL);
+ rettv->vval.v_number = n;
+}
+
+#ifdef HAVE_STRFTIME
+/*
+ * "strftime({format}[, {time}])" function
+ */
+static void f_strftime(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ char_u result_buf[256];
+ struct tm *curtime;
+ time_t seconds;
+ char_u *p;
+
+ rettv->v_type = VAR_STRING;
+
+ p = get_tv_string(&argvars[0]);
+ if (argvars[1].v_type == VAR_UNKNOWN)
+ seconds = time(NULL);
+ else
+ seconds = (time_t)get_tv_number(&argvars[1]);
+ curtime = localtime(&seconds);
+ /* MSVC returns NULL for an invalid value of seconds. */
+ if (curtime == NULL)
+ rettv->vval.v_string = vim_strsave((char_u *)_("(Invalid)"));
+ else {
+ vimconv_T conv;
+ char_u *enc;
+
+ 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);
+ else
+ result_buf[0] = NUL;
+
+ if (conv.vc_type != CONV_NONE)
+ vim_free(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);
+
+ /* Release conversion descriptors */
+ convert_setup(&conv, NULL, NULL);
+ vim_free(enc);
+ }
+}
+#endif
+
+/*
+ * "stridx()" function
+ */
+static void f_stridx(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ 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 */
+
+ if (argvars[2].v_type != VAR_UNKNOWN) {
+ int error = FALSE;
+
+ start_idx = get_tv_number_chk(&argvars[2], &error);
+ if (error || start_idx >= (int)STRLEN(haystack))
+ return;
+ 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);
+}
+
+/*
+ * "string()" function
+ */
+static void f_string(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ char_u *tofree;
+ char_u numbuf[NUMBUFLEN];
+
+ rettv->v_type = VAR_STRING;
+ rettv->vval.v_string = tv2string(&argvars[0], &tofree, numbuf, 0);
+ /* Make a copy if we have a value but it's not in allocated memory. */
+ if (rettv->vval.v_string != NULL && tofree == NULL)
+ rettv->vval.v_string = vim_strsave(rettv->vval.v_string);
+}
+
+/*
+ * "strlen()" function
+ */
+static void f_strlen(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ rettv->vval.v_number = (varnumber_T)(STRLEN(
+ get_tv_string(&argvars[0])));
+}
+
+/*
+ * "strchars()" function
+ */
+static void f_strchars(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ char_u *s = get_tv_string(&argvars[0]);
+ varnumber_T len = 0;
+
+ while (*s != NUL) {
+ mb_cptr2char_adv(&s);
+ ++len;
+ }
+ rettv->vval.v_number = len;
+}
+
+/*
+ * "strdisplaywidth()" function
+ */
+static void f_strdisplaywidth(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ char_u *s = get_tv_string(&argvars[0]);
+ int col = 0;
+
+ if (argvars[1].v_type != VAR_UNKNOWN)
+ col = get_tv_number(&argvars[1]);
+
+ rettv->vval.v_number = (varnumber_T)(linetabsize_col(col, s) - col);
+}
+
+/*
+ * "strwidth()" function
+ */
+static void f_strwidth(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ char_u *s = get_tv_string(&argvars[0]);
+
+ rettv->vval.v_number = (varnumber_T)(
+ mb_string2cells(s, -1)
+ );
+}
+
+/*
+ * "strpart()" function
+ */
+static void f_strpart(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ char_u *p;
+ int n;
+ int len;
+ int slen;
+ int error = FALSE;
+
+ p = get_tv_string(&argvars[0]);
+ slen = (int)STRLEN(p);
+
+ n = get_tv_number_chk(&argvars[1], &error);
+ 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. */
+
+ /*
+ * Only return the overlap between the specified part and the actual
+ * string.
+ */
+ if (n < 0) {
+ len += n;
+ n = 0;
+ } else if (n > slen)
+ n = slen;
+ if (len < 0)
+ len = 0;
+ else if (n + len > slen)
+ len = slen - n;
+
+ rettv->v_type = VAR_STRING;
+ rettv->vval.v_string = vim_strnsave(p + n, len);
+}
+
+/*
+ * "strridx()" function
+ */
+static void f_strridx(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ 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);
+
+ rettv->vval.v_number = -1;
+ if (needle == NULL || haystack == NULL)
+ return; /* type error; errmsg already given */
+
+ haystack_len = (int)STRLEN(haystack);
+ 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;
+
+ if (*needle == NUL) {
+ /* Empty string matches past the end. */
+ lastmatch = haystack + end_idx;
+ } else {
+ for (rest = haystack; *rest != '\0'; ++rest) {
+ rest = (char_u *)strstr((char *)rest, (char *)needle);
+ if (rest == NULL || rest > haystack + end_idx)
+ break;
+ lastmatch = rest;
+ }
+ }
+
+ if (lastmatch == NULL)
+ rettv->vval.v_number = -1;
+ else
+ rettv->vval.v_number = (varnumber_T)(lastmatch - haystack);
+}
+
+/*
+ * "strtrans()" function
+ */
+static void f_strtrans(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ rettv->v_type = VAR_STRING;
+ rettv->vval.v_string = transstr(get_tv_string(&argvars[0]));
+}
+
+/*
+ * "submatch()" function
+ */
+static void f_submatch(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ rettv->v_type = VAR_STRING;
+ rettv->vval.v_string =
+ reg_submatch((int)get_tv_number_chk(&argvars[0], NULL));
+}
+
+/*
+ * "substitute()" function
+ */
+static void f_substitute(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ char_u patbuf[NUMBUFLEN];
+ char_u subbuf[NUMBUFLEN];
+ char_u flagsbuf[NUMBUFLEN];
+
+ 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);
+
+ rettv->v_type = VAR_STRING;
+ if (str == NULL || pat == NULL || sub == NULL || flg == NULL)
+ rettv->vval.v_string = NULL;
+ else
+ rettv->vval.v_string = do_string_sub(str, pat, sub, flg);
+}
+
+/*
+ * "synID(lnum, col, trans)" function
+ */
+static void f_synID(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv;
+{
+ int id = 0;
+ long lnum;
+ long col;
+ int trans;
+ int transerr = FALSE;
+
+ 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);
+
+ 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);
+
+ rettv->vval.v_number = id;
+}
+
+/*
+ * "synIDattr(id, what [, mode])" function
+ */
+static void f_synIDattr(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv;
+{
+ char_u *p = NULL;
+ int id;
+ char_u *what;
+ char_u *mode;
+ char_u modebuf[NUMBUFLEN];
+ 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);
+ modec = TOLOWER_ASC(mode[0]);
+ if (modec != 't' && modec != 'c' && modec != 'g')
+ modec = 0; /* replace invalid with current */
+ } else {
+ if (t_colors > 1)
+ modec = 'c';
+ else
+ modec = 't';
+ }
+
+
+ switch (TOLOWER_ASC(what[0])) {
+ 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);
+ 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(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;
+ }
+
+ if (p != NULL)
+ p = vim_strsave(p);
+ rettv->v_type = VAR_STRING;
+ rettv->vval.v_string = p;
+}
+
+/*
+ * "synIDtrans(id)" function
+ */
+static void f_synIDtrans(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv;
+{
+ int id;
+
+ id = get_tv_number(&argvars[0]);
+
+ if (id > 0)
+ id = syn_get_final_id(id);
+ else
+ id = 0;
+
+ rettv->vval.v_number = id;
+}
+
+/*
+ * "synconcealed(lnum, col)" function
+ */
+static void f_synconcealed(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv;
+{
+ 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;
+
+ lnum = get_tv_lnum(argvars); /* -1 on type error */
+ col = get_tv_number(&argvars[1]) - 1; /* -1 on type error */
+
+ vim_memset(str, NUL, sizeof(str));
+
+ if (rettv_list_alloc(rettv) != FAIL) {
+ 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);
+ 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) {
+ if (has_mbyte)
+ (*mb_char2bytes)(cchar, str);
+ else
+ str[0] = cchar;
+ }
+ }
+ }
+
+ 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);
+ }
+}
+
+/*
+ * "synstack(lnum, col)" function
+ */
+static void f_synstack(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv;
+{
+ long lnum;
+ long col;
+ int i;
+ int id;
+
+ rettv->v_type = VAR_LIST;
+ rettv->vval.v_list = NULL;
+
+ lnum = get_tv_lnum(argvars); /* -1 on type error */
+ col = get_tv_number(&argvars[1]) - 1; /* -1 on type error */
+
+ if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count
+ && col >= 0 && col <= (long)STRLEN(ml_get(lnum))
+ && rettv_list_alloc(rettv) != FAIL) {
+ (void)syn_get_id(curwin, lnum, (colnr_T)col, FALSE, NULL, TRUE);
+ for (i = 0;; ++i) {
+ id = syn_get_stack_item(i);
+ if (id < 0)
+ break;
+ if (list_append_number(rettv->vval.v_list, id) == FAIL)
+ break;
+ }
+ }
+}
+
+/*
+ * "system()" function
+ */
+static void f_system(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ char_u *res = NULL;
+ char_u *p;
+ char_u *infile = NULL;
+ char_u buf[NUMBUFLEN];
+ int err = FALSE;
+ FILE *fd;
+
+ if (check_restricted() || check_secure())
+ goto done;
+
+ if (argvars[1].v_type != VAR_UNKNOWN) {
+ /*
+ * Write the string to a temp file, to be used for input of the shell
+ * command.
+ */
+ if ((infile = vim_tempname('i')) == NULL) {
+ EMSG(_(e_notmp));
+ goto done;
+ }
+
+ fd = mch_fopen((char *)infile, WRITEBIN);
+ if (fd == NULL) {
+ EMSG2(_(e_notopen), infile);
+ goto done;
+ }
+ p = get_tv_string_buf_chk(&argvars[1], buf);
+ if (p == NULL) {
+ fclose(fd);
+ goto done; /* type error; errmsg already given */
+ }
+ if (fwrite(p, STRLEN(p), 1, fd) != 1)
+ err = TRUE;
+ if (fclose(fd) != 0)
+ err = TRUE;
+ if (err) {
+ EMSG(_("E677: Error writing temp file"));
+ goto done;
+ }
+ }
+
+ res = get_cmd_output(get_tv_string(&argvars[0]), infile,
+ SHELL_SILENT | SHELL_COOKED);
+
+#ifdef USE_CR
+ /* translate <CR> into <NL> */
+ if (res != NULL) {
+ char_u *s;
+
+ for (s = res; *s; ++s) {
+ if (*s == CAR)
+ *s = NL;
+ }
+ }
+#else
+# ifdef USE_CRNL
+ /* translate <CR><NL> into <NL> */
+ if (res != NULL) {
+ char_u *s, *d;
+
+ d = res;
+ for (s = res; *s; ++s) {
+ if (s[0] == CAR && s[1] == NL)
+ ++s;
+ *d++ = *s;
+ }
+ *d = NUL;
+ }
+# endif
+#endif
+
+done:
+ if (infile != NULL) {
+ mch_remove(infile);
+ vim_free(infile);
+ }
+ rettv->v_type = VAR_STRING;
+ rettv->vval.v_string = res;
+}
+
+/*
+ * "tabpagebuflist()" function
+ */
+static void f_tabpagebuflist(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv UNUSED;
+{
+ tabpage_T *tp;
+ win_T *wp = NULL;
+
+ if (argvars[0].v_type == VAR_UNKNOWN)
+ wp = firstwin;
+ else {
+ tp = find_tabpage((int)get_tv_number(&argvars[0]));
+ if (tp != NULL)
+ wp = (tp == curtab) ? firstwin : tp->tp_firstwin;
+ }
+ if (wp != NULL && rettv_list_alloc(rettv) != FAIL) {
+ for (; wp != NULL; wp = wp->w_next)
+ if (list_append_number(rettv->vval.v_list,
+ wp->w_buffer->b_fnum) == FAIL)
+ break;
+ }
+}
+
+
+/*
+ * "tabpagenr()" function
+ */
+static void f_tabpagenr(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv;
+{
+ int nr = 1;
+ char_u *arg;
+
+ if (argvars[0].v_type != VAR_UNKNOWN) {
+ arg = get_tv_string_chk(&argvars[0]);
+ nr = 0;
+ if (arg != NULL) {
+ if (STRCMP(arg, "$") == 0)
+ nr = tabpage_index(NULL) - 1;
+ else
+ EMSG2(_(e_invexpr2), arg);
+ }
+ } else
+ nr = tabpage_index(curtab);
+ rettv->vval.v_number = nr;
+}
+
+
+static int get_winnr __ARGS((tabpage_T *tp, typval_T *argvar));
+
+/*
+ * Common code for tabpagewinnr() and winnr().
+ */
+static int get_winnr(tp, argvar)
+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)
+ twin = (tp == curtab) ? lastwin : tp->tp_lastwin;
+ else if (STRCMP(arg, "#") == 0) {
+ twin = (tp == curtab) ? prevwin : tp->tp_prevwin;
+ if (twin == NULL)
+ nr = 0;
+ } else {
+ EMSG2(_(e_invexpr2), arg);
+ nr = 0;
+ }
+ }
+
+ if (nr > 0)
+ for (wp = (tp == curtab) ? firstwin : tp->tp_firstwin;
+ wp != twin; wp = wp->w_next) {
+ if (wp == NULL) {
+ /* didn't find it in this tabpage */
+ nr = 0;
+ break;
+ }
+ ++nr;
+ }
+ return nr;
+}
+
+/*
+ * "tabpagewinnr()" function
+ */
+static void f_tabpagewinnr(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv;
+{
+ int nr = 1;
+ tabpage_T *tp;
+
+ tp = find_tabpage((int)get_tv_number(&argvars[0]));
+ if (tp == NULL)
+ nr = 0;
+ else
+ nr = get_winnr(tp, &argvars[1]);
+ rettv->vval.v_number = nr;
+}
+
+
+/*
+ * "tagfiles()" function
+ */
+static void f_tagfiles(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv;
+{
+ char_u *fname;
+ tagname_T tn;
+ int first;
+
+ if (rettv_list_alloc(rettv) == FAIL)
+ return;
+ fname = alloc(MAXPATHL);
+ if (fname == NULL)
+ return;
+
+ for (first = TRUE;; first = FALSE)
+ if (get_tagfname(&tn, first, fname) == FAIL
+ || list_append_string(rettv->vval.v_list, fname, -1) == FAIL)
+ break;
+ tagname_free(&tn);
+ vim_free(fname);
+}
+
+/*
+ * "taglist()" function
+ */
+static void f_taglist(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ char_u *tag_pattern;
+
+ tag_pattern = get_tv_string(&argvars[0]);
+
+ rettv->vval.v_number = FALSE;
+ if (*tag_pattern == NUL)
+ return;
+
+ if (rettv_list_alloc(rettv) == OK)
+ (void)get_tags(rettv->vval.v_list, tag_pattern);
+}
+
+/*
+ * "tempname()" function
+ */
+static void f_tempname(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv;
+{
+ static int x = 'A';
+
+ rettv->v_type = VAR_STRING;
+ rettv->vval.v_string = vim_tempname(x);
+
+ /* Advance 'x' to use A-Z and 0-9, so that there are at least 34 different
+ * names. Skip 'I' and 'O', they are used for shell redirection. */
+ do {
+ if (x == 'Z')
+ x = '0';
+ else if (x == '9')
+ x = 'A';
+ else {
+ ++x;
+ }
+ } while (x == 'I' || x == 'O');
+}
+
+/*
+ * "test(list)" function: Just checking the walls...
+ */
+static void f_test(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv UNUSED;
+{
+ /* Used for unit testing. Change the code below to your liking. */
+}
+
+/*
+ * "tan()" function
+ */
+static void f_tan(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ float_T f;
+
+ rettv->v_type = VAR_FLOAT;
+ if (get_float_arg(argvars, &f) == OK)
+ rettv->vval.v_float = tan(f);
+ else
+ rettv->vval.v_float = 0.0;
+}
+
+/*
+ * "tanh()" function
+ */
+static void f_tanh(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ float_T f;
+
+ rettv->v_type = VAR_FLOAT;
+ if (get_float_arg(argvars, &f) == OK)
+ rettv->vval.v_float = tanh(f);
+ else
+ rettv->vval.v_float = 0.0;
+}
+
+/*
+ * "tolower(string)" function
+ */
+static void f_tolower(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ char_u *p;
+
+ p = vim_strsave(get_tv_string(&argvars[0]));
+ rettv->v_type = VAR_STRING;
+ rettv->vval.v_string = p;
+
+ if (p != NULL)
+ 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;
+ }
+ }
+}
+
+/*
+ * "toupper(string)" function
+ */
+static void f_toupper(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ rettv->v_type = VAR_STRING;
+ rettv->vval.v_string = strup_save(get_tv_string(&argvars[0]));
+}
+
+/*
+ * "tr(string, fromstr, tostr)" function
+ */
+static void f_tr(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ 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;
+
+ 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);
+
+ /* 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 */
+ ga_init2(&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;
+ }
+
+ /* fromstr and tostr have to contain the same number of chars */
+ 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);
+ if (fromlen == inlen && STRNCMP(in_str, p, inlen) == 0) {
+ for (p = tostr; *p != NUL; p += tolen) {
+ tolen = (*mb_ptr2len)(p);
+ if (idx-- == 0) {
+ cplen = tolen;
+ cpstr = p;
+ break;
+ }
+ }
+ if (*p == NUL) /* tostr is shorter than fromstr */
+ goto error;
+ break;
+ }
+ ++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;
+ }
+ if (idx != 0)
+ goto error;
+ }
+
+ ga_grow(&ga, cplen);
+ mch_memmove((char *)ga.ga_data + ga.ga_len, cpstr, (size_t)cplen);
+ ga.ga_len += cplen;
+
+ in_str += inlen;
+ } else {
+ /* When not using multi-byte chars we can do it faster. */
+ p = vim_strchr(fromstr, *in_str);
+ if (p != NULL)
+ ga_append(&ga, tostr[p - fromstr]);
+ else
+ ga_append(&ga, *in_str);
+ ++in_str;
+ }
+ }
+
+ /* add a terminating NUL */
+ ga_grow(&ga, 1);
+ ga_append(&ga, NUL);
+
+ rettv->vval.v_string = ga.ga_data;
+}
+
+/*
+ * "trunc({float})" function
+ */
+static void f_trunc(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ float_T f;
+
+ rettv->v_type = VAR_FLOAT;
+ if (get_float_arg(argvars, &f) == OK)
+ /* trunc() is not in C90, use floor() or ceil() instead. */
+ rettv->vval.v_float = f > 0 ? floor(f) : ceil(f);
+ else
+ rettv->vval.v_float = 0.0;
+}
+
+/*
+ * "type(expr)" function
+ */
+static void f_type(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ int n;
+
+ 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;
+ default: EMSG2(_(e_intern2), "f_type()"); n = 0; break;
+ }
+ rettv->vval.v_number = n;
+}
+
+/*
+ * "undofile(name)" function
+ */
+static void f_undofile(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv;
+{
+ rettv->v_type = VAR_STRING;
+ {
+ char_u *fname = get_tv_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_u *ffname = FullName_save(fname, FALSE);
+
+ if (ffname != NULL)
+ rettv->vval.v_string = u_get_undo_file_name(ffname, FALSE);
+ vim_free(ffname);
+ }
+ }
+}
+
+/*
+ * "undotree()" function
+ */
+static void f_undotree(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv;
+{
+ if (rettv_dict_alloc(rettv) == OK) {
+ 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);
+
+ list = list_alloc();
+ if (list != NULL) {
+ u_eval_tree(curbuf->b_u_oldhead, list);
+ dict_add_list(dict, "entries", list);
+ }
+ }
+}
+
+/*
+ * "values(dict)" function
+ */
+static void f_values(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ dict_list(argvars, rettv, 1);
+}
+
+/*
+ * "virtcol(string)" function
+ */
+static void f_virtcol(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ colnr_T vcol = 0;
+ pos_T *fp;
+ int fnum = curbuf->b_fnum;
+
+ fp = var2fpos(&argvars[0], FALSE, &fnum);
+ if (fp != NULL && fp->lnum <= curbuf->b_ml.ml_line_count
+ && fnum == curbuf->b_fnum) {
+ getvvcol(curwin, fp, NULL, NULL, &vcol);
+ ++vcol;
+ }
+
+ rettv->vval.v_number = vcol;
+}
+
+/*
+ * "visualmode()" function
+ */
+static void f_visualmode(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv UNUSED;
+{
+ char_u str[2];
+
+ rettv->v_type = VAR_STRING;
+ str[0] = curbuf->b_visual_mode_eval;
+ str[1] = NUL;
+ rettv->vval.v_string = vim_strsave(str);
+
+ /* A non-zero number or non-empty string argument: reset mode. */
+ if (non_zero_arg(&argvars[0]))
+ curbuf->b_visual_mode_eval = NUL;
+}
+
+/*
+ * "wildmenumode()" function
+ */
+static void f_wildmenumode(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv UNUSED;
+{
+ if (wild_menu_showing)
+ rettv->vval.v_number = 1;
+}
+
+/*
+ * "winbufnr(nr)" function
+ */
+static void f_winbufnr(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ win_T *wp;
+
+ wp = find_win_by_nr(&argvars[0], NULL);
+ if (wp == NULL)
+ rettv->vval.v_number = -1;
+ else
+ rettv->vval.v_number = wp->w_buffer->b_fnum;
+}
+
+/*
+ * "wincol()" function
+ */
+static void f_wincol(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv;
+{
+ validate_cursor();
+ rettv->vval.v_number = curwin->w_wcol + 1;
+}
+
+/*
+ * "winheight(nr)" function
+ */
+static void f_winheight(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ win_T *wp;
+
+ wp = find_win_by_nr(&argvars[0], NULL);
+ if (wp == NULL)
+ rettv->vval.v_number = -1;
+ else
+ rettv->vval.v_number = wp->w_height;
+}
+
+/*
+ * "winline()" function
+ */
+static void f_winline(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv;
+{
+ validate_cursor();
+ rettv->vval.v_number = curwin->w_wrow + 1;
+}
+
+/*
+ * "winnr()" function
+ */
+static void f_winnr(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv;
+{
+ int nr = 1;
+
+ nr = get_winnr(curtab, &argvars[0]);
+ rettv->vval.v_number = nr;
+}
+
+/*
+ * "winrestcmd()" function
+ */
+static void f_winrestcmd(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv;
+{
+ win_T *wp;
+ int winnr = 1;
+ garray_T ga;
+ char_u buf[50];
+
+ ga_init2(&ga, (int)sizeof(char), 70);
+ for (wp = firstwin; wp != NULL; wp = wp->w_next) {
+ sprintf((char *)buf, "%dresize %d|", winnr, wp->w_height);
+ ga_concat(&ga, buf);
+ sprintf((char *)buf, "vert %dresize %d|", winnr, wp->w_width);
+ ga_concat(&ga, buf);
+ ++winnr;
+ }
+ ga_append(&ga, NUL);
+
+ rettv->vval.v_string = ga.ga_data;
+ rettv->v_type = VAR_STRING;
+}
+
+/*
+ * "winrestview()" function
+ */
+static void f_winrestview(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv UNUSED;
+{
+ dict_T *dict;
+
+ if (argvars[0].v_type != VAR_DICT
+ || (dict = argvars[0].vval.v_dict) == NULL)
+ EMSG(_(e_invarg));
+ else {
+ curwin->w_cursor.lnum = get_dict_number(dict, (char_u *)"lnum");
+ curwin->w_cursor.col = get_dict_number(dict, (char_u *)"col");
+ curwin->w_cursor.coladd = get_dict_number(dict, (char_u *)"coladd");
+ curwin->w_curswant = get_dict_number(dict, (char_u *)"curswant");
+ curwin->w_set_curswant = FALSE;
+
+ set_topline(curwin, get_dict_number(dict, (char_u *)"topline"));
+ curwin->w_topfill = get_dict_number(dict, (char_u *)"topfill");
+ curwin->w_leftcol = get_dict_number(dict, (char_u *)"leftcol");
+ curwin->w_skipcol = get_dict_number(dict, (char_u *)"skipcol");
+
+ check_cursor();
+ win_new_height(curwin, curwin->w_height);
+ win_new_width(curwin, W_WIDTH(curwin));
+ changed_window_setting();
+
+ if (curwin->w_topline == 0)
+ curwin->w_topline = 1;
+ if (curwin->w_topline > curbuf->b_ml.ml_line_count)
+ curwin->w_topline = curbuf->b_ml.ml_line_count;
+ check_topfill(curwin, TRUE);
+ }
+}
+
+/*
+ * "winsaveview()" function
+ */
+static void f_winsaveview(argvars, rettv)
+typval_T *argvars UNUSED;
+typval_T *rettv;
+{
+ dict_T *dict;
+
+ if (rettv_dict_alloc(rettv) == FAIL)
+ return;
+ 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);
+ update_curswant();
+ dict_add_nr_str(dict, "curswant", (long)curwin->w_curswant, NULL);
+
+ 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);
+}
+
+/*
+ * "winwidth(nr)" function
+ */
+static void f_winwidth(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ win_T *wp;
+
+ wp = find_win_by_nr(&argvars[0], NULL);
+ if (wp == NULL)
+ rettv->vval.v_number = -1;
+ else
+ rettv->vval.v_number = wp->w_width;
+}
+
+/*
+ * "writefile()" function
+ */
+static void f_writefile(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ int binary = FALSE;
+ char_u *fname;
+ FILE *fd;
+ listitem_T *li;
+ char_u *s;
+ int ret = 0;
+ int c;
+
+ if (check_restricted() || check_secure())
+ return;
+
+ if (argvars[0].v_type != VAR_LIST) {
+ EMSG2(_(e_listarg), "writefile()");
+ return;
+ }
+ if (argvars[0].vval.v_list == NULL)
+ return;
+
+ if (argvars[2].v_type != VAR_UNKNOWN
+ && STRCMP(get_tv_string(&argvars[2]), "b") == 0)
+ binary = TRUE;
+
+ /* Always open the file in binary mode, library functions have a mind of
+ * their own about CR-LF conversion. */
+ fname = get_tv_string(&argvars[1]);
+ if (*fname == NUL || (fd = mch_fopen((char *)fname, WRITEBIN)) == NULL) {
+ EMSG2(_(e_notcreate), *fname == NUL ? (char_u *)_("<empty>") : fname);
+ ret = -1;
+ } else {
+ for (li = argvars[0].vval.v_list->lv_first; li != NULL;
+ li = li->li_next) {
+ for (s = get_tv_string(&li->li_tv); *s != NUL; ++s) {
+ if (*s == '\n')
+ c = putc(NUL, fd);
+ else
+ c = putc(*s, fd);
+ if (c == EOF) {
+ ret = -1;
+ break;
+ }
+ }
+ if (!binary || li->li_next != NULL)
+ if (putc('\n', fd) == EOF) {
+ ret = -1;
+ break;
+ }
+ if (ret < 0) {
+ EMSG(_(e_write));
+ break;
+ }
+ }
+ fclose(fd);
+ }
+
+ rettv->vval.v_number = ret;
+}
+
+/*
+ * "xor(expr, expr)" function
+ */
+static void f_xor(argvars, rettv)
+typval_T *argvars;
+typval_T *rettv;
+{
+ rettv->vval.v_number = get_tv_number_chk(&argvars[0], NULL)
+ ^ get_tv_number_chk(&argvars[1], NULL);
+}
+
+
+/*
+ * Translate a String variable into a position.
+ * Returns NULL when there is an error.
+ */
+static pos_T * var2fpos(varp, dollar_lnum, fnum)
+typval_T *varp;
+int dollar_lnum; /* TRUE when $ is last line */
+int *fnum; /* set to fnum for '0, 'A, etc. */
+{
+ char_u *name;
+ static pos_T pos;
+ pos_T *pp;
+
+ /* Argument can be [lnum, col, coladd]. */
+ if (varp->v_type == VAR_LIST) {
+ list_T *l;
+ int len;
+ int error = FALSE;
+ listitem_T *li;
+
+ l = varp->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 column number */
+ pos.col = 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)
+ 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;
+
+ /* Get the virtual offset. Defaults to zero. */
+ pos.coladd = list_find_nr(l, 2L, &error);
+ if (error)
+ pos.coladd = 0;
+
+ return &pos;
+ }
+
+ name = get_tv_string_chk(varp);
+ if (name == NULL)
+ return NULL;
+ if (name[0] == '.') /* cursor */
+ return &curwin->w_cursor;
+ 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)
+ return NULL;
+ return pp;
+ }
+
+ pos.coladd = 0;
+
+ if (name[0] == 'w' && dollar_lnum) {
+ pos.col = 0;
+ if (name[1] == '0') { /* "w0": first visible line */
+ update_topline();
+ pos.lnum = curwin->w_topline;
+ return &pos;
+ } else if (name[1] == '$') { /* "w$": last visible line */
+ validate_botline();
+ pos.lnum = curwin->w_botline - 1;
+ return &pos;
+ }
+ } else if (name[0] == '$') { /* last column or line */
+ if (dollar_lnum) {
+ pos.lnum = curbuf->b_ml.ml_line_count;
+ pos.col = 0;
+ } else {
+ pos.lnum = curwin->w_cursor.lnum;
+ pos.col = (colnr_T)STRLEN(ml_get_curline());
+ }
+ return &pos;
+ }
+ return NULL;
+}
+
+/*
+ * Convert list in "arg" into a position and optional file number.
+ * When "fnump" is NULL there is no file number, only 3 items.
+ * Note that the column is passed on as-is, the caller may want to decrement
+ * it to use 1 for the first column.
+ * Return FAIL when conversion is not possible, doesn't check the position for
+ * validity.
+ */
+static int list2fpos(arg, posp, fnump)
+typval_T *arg;
+pos_T *posp;
+int *fnump;
+{
+ list_T *l = arg->vval.v_list;
+ long i = 0;
+ long n;
+
+ /* List must be: [fnum, lnum, col, coladd], where "fnum" is only there
+ * when "fnump" isn't NULL and "coladd" is optional. */
+ if (arg->v_type != VAR_LIST
+ || l == NULL
+ || l->lv_len < (fnump == NULL ? 2 : 3)
+ || l->lv_len > (fnump == NULL ? 3 : 4))
+ return FAIL;
+
+ if (fnump != NULL) {
+ n = list_find_nr(l, i++, NULL); /* fnum */
+ if (n < 0)
+ return FAIL;
+ if (n == 0)
+ n = curbuf->b_fnum; /* current buffer */
+ *fnump = n;
+ }
+
+ n = 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)
+ return FAIL;
+ posp->col = n;
+
+ n = list_find_nr(l, i, NULL);
+ if (n < 0)
+ posp->coladd = 0;
+ else
+ posp->coladd = n;
+
+ return OK;
+}
+
+/*
+ * Get the length of an environment variable name.
+ * Advance "arg" to the first character after the name.
+ * Return 0 for error.
+ */
+static int get_env_len(arg)
+char_u **arg;
+{
+ char_u *p;
+ int len;
+
+ for (p = *arg; vim_isIDc(*p); ++p)
+ ;
+ if (p == *arg) /* no name found */
+ return 0;
+
+ len = (int)(p - *arg);
+ *arg = p;
+ return len;
+}
+
+/*
+ * 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(arg)
+char_u **arg;
+{
+ char_u *p;
+ int len;
+
+ /* Find the end of the name. */
+ for (p = *arg; eval_isnamec(*p); ++p)
+ ;
+ if (p == *arg) /* no name found */
+ return 0;
+
+ len = (int)(p - *arg);
+ *arg = skipwhite(p);
+
+ return len;
+}
+
+/*
+ * Get the length of the name of a variable or function.
+ * Only the name is recognized, does not handle ".key" or "[idx]".
+ * "arg" is advanced to the first non-white character after the name.
+ * Return -1 if curly braces expansion failed.
+ * Return 0 if something else is wrong.
+ * 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(arg, alias, evaluate, verbose)
+char_u **arg;
+char_u **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 */
+ *arg += 3;
+ return get_id_len(arg) + 3;
+ }
+ len = eval_fname_script(*arg);
+ if (len > 0) {
+ /* literal "<SID>", "s:" or "<SNR>" */
+ *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);
+ if (expr_start != NULL) {
+ char_u *temp_string;
+
+ if (!evaluate) {
+ len += (int)(p - *arg);
+ *arg = skipwhite(p);
+ return len;
+ }
+
+ /*
+ * 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)
+ return -1;
+ *alias = temp_string;
+ *arg = skipwhite(p);
+ return (int)STRLEN(temp_string);
+ }
+
+ len += get_id_len(arg);
+ if (len == 0 && verbose)
+ EMSG2(_(e_invexpr2), *arg);
+
+ return len;
+}
+
+/*
+ * Find the end of a variable or function name, taking care of magic braces.
+ * If "expr_start" is not NULL then "expr_start" and "expr_end" are set to the
+ * start and end of the first magic braces item.
+ * "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(arg, expr_start, expr_end, flags)
+char_u *arg;
+char_u **expr_start;
+char_u **expr_end;
+int flags;
+{
+ int mb_nest = 0;
+ int br_nest = 0;
+ char_u *p;
+
+ if (expr_start != NULL) {
+ *expr_start = NULL;
+ *expr_end = NULL;
+ }
+
+ /* Quick check for valid starting character. */
+ if ((flags & FNE_CHECK_START) && !eval_isnamec1(*arg) && *arg != '{')
+ return arg;
+
+ 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)) {
+ 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)
+ 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))
+ if (*p == '\\' && p[1] != NUL)
+ ++p;
+ if (*p == NUL)
+ break;
+ }
+
+ if (mb_nest == 0) {
+ if (*p == '[')
+ ++br_nest;
+ else if (*p == ']')
+ --br_nest;
+ }
+
+ if (br_nest == 0) {
+ if (*p == '{') {
+ mb_nest++;
+ if (expr_start != NULL && *expr_start == NULL)
+ *expr_start = p;
+ } else if (*p == '}') {
+ mb_nest--;
+ if (expr_start != NULL && mb_nest == 0 && *expr_end == NULL)
+ *expr_end = p;
+ }
+ }
+ }
+
+ return p;
+}
+
+/*
+ * Expands out the 'magic' {}'s in a variable/function name.
+ * Note that this can call itself recursively, to deal with
+ * constructs like foo{bar}{baz}{bam}
+ * The four pointer arguments point to "foo{expre}ss{ion}bar"
+ * "in_start" ^
+ * "expr_start" ^
+ * "expr_end" ^
+ * "in_end" ^
+ *
+ * Returns a new allocated string, which the caller must free.
+ * Returns NULL for failure.
+ */
+static char_u * make_expanded_name(in_start, expr_start, expr_end, in_end)
+char_u *in_start;
+char_u *expr_start;
+char_u *expr_end;
+char_u *in_end;
+{
+ char_u c1;
+ char_u *retval = NULL;
+ char_u *temp_result;
+ char_u *nextcmd = NULL;
+
+ if (expr_end == NULL || in_end == NULL)
+ return NULL;
+ *expr_start = NUL;
+ *expr_end = NUL;
+ c1 = *in_end;
+ *in_end = NUL;
+
+ temp_result = eval_to_string(expr_start + 1, &nextcmd, FALSE);
+ if (temp_result != NULL && nextcmd == NULL) {
+ retval = alloc((unsigned)(STRLEN(temp_result) + (expr_start - in_start)
+ + (in_end - expr_end) + 1));
+ if (retval != NULL) {
+ STRCPY(retval, in_start);
+ STRCAT(retval, temp_result);
+ STRCAT(retval, expr_end + 1);
+ }
+ }
+ vim_free(temp_result);
+
+ *in_end = c1; /* put char back for error messages */
+ *expr_start = '{';
+ *expr_end = '}';
+
+ if (retval != NULL) {
+ temp_result = find_name_end(retval, &expr_start, &expr_end, 0);
+ if (expr_start != NULL) {
+ /* Further expansion! */
+ temp_result = make_expanded_name(retval, expr_start,
+ expr_end, temp_result);
+ vim_free(retval);
+ retval = temp_result;
+ }
+ }
+
+ return retval;
+}
+
+/*
+ * Return TRUE if character "c" can be used in a variable or function name.
+ * Does not include '{' or '}' for magic braces.
+ */
+static int eval_isnamec(c)
+int c;
+{
+ return ASCII_ISALNUM(c) || c == '_' || c == ':' || c == AUTOLOAD_CHAR;
+}
+
+/*
+ * Return TRUE if character "c" can be used as the first character in a
+ * variable or function name (excluding '{' and '}').
+ */
+static int eval_isnamec1(c)
+int c;
+{
+ return ASCII_ISALPHA(c) || c == '_';
+}
+
+/*
+ * Set number v: variable to "val".
+ */
+void set_vim_var_nr(idx, val)
+int idx;
+long val;
+{
+ vimvars[idx].vv_nr = val;
+}
+
+/*
+ * Get number v: variable value.
+ */
+long get_vim_var_nr(idx)
+int idx;
+{
+ return vimvars[idx].vv_nr;
+}
+
+/*
+ * Get string v: variable value. Uses a static buffer, can only be used once.
+ */
+char_u * get_vim_var_str(idx)
+int idx;
+{
+ return get_tv_string(&vimvars[idx].vv_tv);
+}
+
+/*
+ * Get List v: variable value. Caller must take care of reference count when
+ * needed.
+ */
+list_T * get_vim_var_list(idx)
+int idx;
+{
+ return vimvars[idx].vv_list;
+}
+
+/*
+ * Set v:char to character "c".
+ */
+void set_vim_var_char(c)
+int c;
+{
+ char_u buf[MB_MAXBYTES + 1];
+
+ if (has_mbyte)
+ buf[(*mb_char2bytes)(c, buf)] = NUL;
+ else {
+ buf[0] = c;
+ buf[1] = NUL;
+ }
+ set_vim_var_string(VV_CHAR, buf, -1);
+}
+
+/*
+ * Set v:count to "count" and v:count1 to "count1".
+ * When "set_prevcount" is TRUE first set v:prevcount from v:count.
+ */
+void set_vcount(count, count1, set_prevcount)
+long count;
+long count1;
+int set_prevcount;
+{
+ if (set_prevcount)
+ vimvars[VV_PREVCOUNT].vv_nr = vimvars[VV_COUNT].vv_nr;
+ vimvars[VV_COUNT].vv_nr = count;
+ vimvars[VV_COUNT1].vv_nr = count1;
+}
+
+/*
+ * Set string v: variable to a copy of "val".
+ */
+void set_vim_var_string(idx, val, len)
+int idx;
+char_u *val;
+int len; /* length of "val" to use or -1 (whole string) */
+{
+ /* Need to do this (at least) once, since we can't initialize a union.
+ * Will always be invoked when "v:progname" is set. */
+ vimvars[VV_VERSION].vv_nr = VIM_VERSION_100;
+
+ vim_free(vimvars[idx].vv_str);
+ if (val == NULL)
+ vimvars[idx].vv_str = NULL;
+ else if (len == -1)
+ vimvars[idx].vv_str = vim_strsave(val);
+ else
+ vimvars[idx].vv_str = vim_strnsave(val, len);
+}
+
+/*
+ * Set List v: variable to "val".
+ */
+void set_vim_var_list(idx, val)
+int idx;
+list_T *val;
+{
+ list_unref(vimvars[idx].vv_list);
+ vimvars[idx].vv_list = val;
+ if (val != NULL)
+ ++val->lv_refcount;
+}
+
+/*
+ * Set v:register if needed.
+ */
+void set_reg_var(c)
+int c;
+{
+ char_u regname;
+
+ if (c == 0 || c == ' ')
+ regname = '"';
+ else
+ regname = c;
+ /* Avoid free/alloc when the value is already right. */
+ if (vimvars[VV_REG].vv_str == NULL || vimvars[VV_REG].vv_str[0] != c)
+ set_vim_var_string(VV_REG, &regname, 1);
+}
+
+/*
+ * Get or set v:exception. If "oldval" == NULL, return the current value.
+ * Otherwise, restore the value to "oldval" and return NULL.
+ * Must always be called in pairs to save and restore v:exception! Does not
+ * take care of memory allocations.
+ */
+char_u * v_exception(oldval)
+char_u *oldval;
+{
+ if (oldval == NULL)
+ return vimvars[VV_EXCEPTION].vv_str;
+
+ vimvars[VV_EXCEPTION].vv_str = oldval;
+ return NULL;
+}
+
+/*
+ * Get or set v:throwpoint. If "oldval" == NULL, return the current value.
+ * Otherwise, restore the value to "oldval" and return NULL.
+ * Must always be called in pairs to save and restore v:throwpoint! Does not
+ * take care of memory allocations.
+ */
+char_u * v_throwpoint(oldval)
+char_u *oldval;
+{
+ if (oldval == NULL)
+ return vimvars[VV_THROWPOINT].vv_str;
+
+ vimvars[VV_THROWPOINT].vv_str = oldval;
+ return NULL;
+}
+
+/*
+ * Set v:cmdarg.
+ * If "eap" != NULL, use "eap" to generate the value and return the old value.
+ * If "oldarg" != NULL, restore the value to "oldarg" and return NULL.
+ * Must always be called in pairs!
+ */
+char_u * set_cmdarg(eap, oldarg)
+exarg_T *eap;
+char_u *oldarg;
+{
+ char_u *oldval;
+ char_u *newval;
+ unsigned len;
+
+ oldval = vimvars[VV_CMDARG].vv_str;
+ if (eap == NULL) {
+ vim_free(oldval);
+ vimvars[VV_CMDARG].vv_str = oldarg;
+ return NULL;
+ }
+
+ if (eap->force_bin == FORCE_BIN)
+ len = 6;
+ else if (eap->force_bin == FORCE_NOBIN)
+ len = 8;
+ else
+ len = 0;
+
+ if (eap->read_edit)
+ len += 7;
+
+ if (eap->force_ff != 0)
+ len += (unsigned)STRLEN(eap->cmd + eap->force_ff) + 6;
+ if (eap->force_enc != 0)
+ len += (unsigned)STRLEN(eap->cmd + eap->force_enc) + 7;
+ if (eap->bad_char != 0)
+ len += 7 + 4; /* " ++bad=" + "keep" or "drop" */
+
+ newval = alloc(len + 1);
+ if (newval == NULL)
+ return NULL;
+
+ if (eap->force_bin == FORCE_BIN)
+ sprintf((char *)newval, " ++bin");
+ else if (eap->force_bin == FORCE_NOBIN)
+ sprintf((char *)newval, " ++nobin");
+ else
+ *newval = NUL;
+
+ if (eap->read_edit)
+ STRCAT(newval, " ++edit");
+
+ if (eap->force_ff != 0)
+ sprintf((char *)newval + STRLEN(newval), " ++ff=%s",
+ eap->cmd + eap->force_ff);
+ if (eap->force_enc != 0)
+ sprintf((char *)newval + STRLEN(newval), " ++enc=%s",
+ eap->cmd + eap->force_enc);
+ if (eap->bad_char == BAD_KEEP)
+ STRCPY(newval + STRLEN(newval), " ++bad=keep");
+ else if (eap->bad_char == BAD_DROP)
+ STRCPY(newval + STRLEN(newval), " ++bad=drop");
+ else if (eap->bad_char != 0)
+ sprintf((char *)newval + STRLEN(newval), " ++bad=%c", eap->bad_char);
+ vimvars[VV_CMDARG].vv_str = newval;
+ return oldval;
+}
+
+/*
+ * Get the value of internal variable "name".
+ * Return OK or FAIL.
+ */
+static int get_var_tv(name, len, rettv, verbose, no_autoload)
+char_u *name;
+int len; /* length of "name" */
+typval_T *rettv; /* NULL when only checking existence */
+int verbose; /* may give error message */
+int no_autoload; /* do not use script autoloading */
+{
+ 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 (tv == NULL) {
+ if (rettv != NULL && verbose)
+ EMSG2(_(e_undefvar), name);
+ ret = FAIL;
+ } else if (rettv != NULL)
+ copy_tv(tv, rettv);
+
+ name[len] = cc;
+
+ 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(arg, rettv, evaluate, verbose)
+char_u **arg;
+typval_T *rettv;
+int evaluate; /* do more than finding the end */
+int verbose; /* give error messages */
+{
+ int ret = OK;
+ dict_T *selfdict = NULL;
+ char_u *s;
+ int len;
+ typval_T functv;
+
+ while (ret == OK
+ && (**arg == '['
+ || (**arg == '.' && rettv->v_type == VAR_DICT)
+ || (**arg == '(' && (!evaluate || rettv->v_type == VAR_FUNC)))
+ && !vim_iswhite(*(*arg - 1))) {
+ if (**arg == '(') {
+ /* 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
+ s = (char_u *)"";
+ ret = get_func_tv(s, (int)STRLEN(s), rettv, arg,
+ curwin->w_cursor.lnum, curwin->w_cursor.lnum,
+ &len, evaluate, selfdict);
+
+ /* Clear the funcref afterwards, so that deleting it while
+ * evaluating the arguments is possible (see test55). */
+ if (evaluate)
+ clear_tv(&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);
+ ret = FAIL;
+ }
+ dict_unref(selfdict);
+ selfdict = NULL;
+ } else { /* **arg == '[' || **arg == '.' */
+ 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);
+ ret = FAIL;
+ }
+ }
+ }
+ dict_unref(selfdict);
+ return ret;
+}
+
+/*
+ * Allocate memory for a variable type-value, and make it empty (0 or NULL
+ * value).
+ */
+static typval_T * alloc_tv() {
+ return (typval_T *)alloc_clear((unsigned)sizeof(typval_T));
+}
+
+/*
+ * Allocate memory for a variable type-value, and assign a string to it.
+ * The string "s" must have been allocated, it is consumed.
+ * Return NULL for out of memory, the variable otherwise.
+ */
+static typval_T * alloc_string_tv(s)
+char_u *s;
+{
+ typval_T *rettv;
+
+ rettv = alloc_tv();
+ if (rettv != NULL) {
+ rettv->v_type = VAR_STRING;
+ rettv->vval.v_string = s;
+ } else
+ vim_free(s);
+ return rettv;
+}
+
+/*
+ * Free the memory for a variable type-value.
+ */
+void free_tv(varp)
+typval_T *varp;
+{
+ if (varp != NULL) {
+ switch (varp->v_type) {
+ case VAR_FUNC:
+ func_unref(varp->vval.v_string);
+ /*FALLTHROUGH*/
+ case VAR_STRING:
+ vim_free(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_NUMBER:
+ case VAR_FLOAT:
+ case VAR_UNKNOWN:
+ break;
+ default:
+ EMSG2(_(e_intern2), "free_tv()");
+ break;
+ }
+ vim_free(varp);
+ }
+}
+
+/*
+ * Free the memory for a variable value and set the value to NULL or 0.
+ */
+void clear_tv(varp)
+typval_T *varp;
+{
+ if (varp != NULL) {
+ switch (varp->v_type) {
+ case VAR_FUNC:
+ func_unref(varp->vval.v_string);
+ /*FALLTHROUGH*/
+ case VAR_STRING:
+ vim_free(varp->vval.v_string);
+ varp->vval.v_string = NULL;
+ break;
+ case VAR_LIST:
+ list_unref(varp->vval.v_list);
+ varp->vval.v_list = NULL;
+ break;
+ case VAR_DICT:
+ dict_unref(varp->vval.v_dict);
+ varp->vval.v_dict = NULL;
+ break;
+ case VAR_NUMBER:
+ varp->vval.v_number = 0;
+ break;
+ case VAR_FLOAT:
+ varp->vval.v_float = 0.0;
+ break;
+ case VAR_UNKNOWN:
+ break;
+ default:
+ EMSG2(_(e_intern2), "clear_tv()");
+ }
+ varp->v_lock = 0;
+ }
+}
+
+/*
+ * Set the value of a variable to NULL without freeing items.
+ */
+static void init_tv(varp)
+typval_T *varp;
+{
+ if (varp != NULL)
+ vim_memset(varp, 0, sizeof(typval_T));
+}
+
+/*
+ * 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(varp)
+typval_T *varp;
+{
+ int error = FALSE;
+
+ return get_tv_number_chk(varp, &error); /* return 0L on error */
+}
+
+long get_tv_number_chk(varp, denote)
+typval_T *varp;
+int *denote;
+{
+ long n = 0L;
+
+ 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,
+ TRUE, TRUE, &n, NULL);
+ 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;
+ default:
+ EMSG2(_(e_intern2), "get_tv_number()");
+ break;
+ }
+ if (denote == NULL) /* useful for values that must be unsigned */
+ n = -1;
+ else
+ *denote = TRUE;
+ return n;
+}
+
+/*
+ * 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(argvars)
+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);
+ }
+ 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(argvars, 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(varp)
+typval_T *varp;
+{
+ static char_u mybuf[NUMBUFLEN];
+
+ return get_tv_string_buf(varp, mybuf);
+}
+
+static char_u * get_tv_string_buf(varp, buf)
+typval_T *varp;
+char_u *buf;
+{
+ char_u *res = get_tv_string_buf_chk(varp, buf);
+
+ return res != NULL ? res : (char_u *)"";
+}
+
+char_u * get_tv_string_chk(varp)
+typval_T *varp;
+{
+ static char_u mybuf[NUMBUFLEN];
+
+ return get_tv_string_buf_chk(varp, mybuf);
+}
+
+static char_u * get_tv_string_buf_chk(varp, buf)
+typval_T *varp;
+char_u *buf;
+{
+ switch (varp->v_type) {
+ case VAR_NUMBER:
+ sprintf((char *)buf, "%ld", (long)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 *)"";
+ default:
+ EMSG2(_(e_intern2), "get_tv_string_buf()");
+ break;
+ }
+ 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(name, htp, no_autoload)
+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);
+}
+
+/*
+ * Find variable "varname" in hashtab "ht" with name "htname".
+ * Returns NULL if not found.
+ */
+static dictitem_T * find_var_in_ht(ht, htname, varname, no_autoload)
+hashtab_T *ht;
+int htname;
+char_u *varname;
+int no_autoload;
+{
+ hashitem_T *hi;
+
+ if (*varname == NUL) {
+ /* 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;
+ }
+ return NULL;
+ }
+
+ hi = hash_find(ht, varname);
+ 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. */
+ 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())
+ return NULL;
+ hi = hash_find(ht, varname);
+ }
+ if (HASHITEM_EMPTY(hi))
+ return NULL;
+ }
+ return HI2DI(hi);
+}
+
+/*
+ * Find the hashtab used for a variable name.
+ * Set "varname" to the start of name without ':'.
+ */
+static hashtab_T * find_var_ht(name, varname)
+char_u *name;
+char_u **varname;
+{
+ hashitem_T *hi;
+
+ if (name[1] != ':') {
+ /* The name must not start with a colon or #. */
+ if (name[0] == ':' || name[0] == AUTOLOAD_CHAR)
+ return NULL;
+ *varname = name;
+
+ /* "version" is "v:version" in all scopes */
+ hi = hash_find(&compat_hashtab, name);
+ if (!HASHITEM_EMPTY(hi))
+ return &compat_hashtab;
+
+ if (current_funccal == NULL)
+ return &globvarht; /* global variable */
+ return &current_funccal->l_vars.dv_hashtab; /* l: variable */
+ }
+ *varname = name + 2;
+ if (*name == 'g') /* global variable */
+ return &globvarht;
+ /* There must be no ':' or '#' in the rest of the name, unless g: is used
+ */
+ if (vim_strchr(name + 2, ':') != NULL
+ || vim_strchr(name + 2, AUTOLOAD_CHAR) != NULL)
+ return NULL;
+ if (*name == 'b') /* buffer variable */
+ return &curbuf->b_vars->dv_hashtab;
+ if (*name == 'w') /* window variable */
+ return &curwin->w_vars->dv_hashtab;
+ if (*name == 't') /* tab page variable */
+ return &curtab->tp_vars->dv_hashtab;
+ if (*name == 'v') /* v: variable */
+ return &vimvarht;
+ if (*name == 'a' && current_funccal != NULL) /* function argument */
+ return &current_funccal->l_avars.dv_hashtab;
+ if (*name == 'l' && current_funccal != NULL) /* local function variable */
+ return &current_funccal->l_vars.dv_hashtab;
+ if (*name == 's' /* script variable */
+ && current_SID > 0 && current_SID <= ga_scripts.ga_len)
+ return &SCRIPT_VARS(current_SID);
+ return NULL;
+}
+
+/*
+ * Get the string value of a (global/local) variable.
+ * Note: see get_tv_string() for how long the pointer remains valid.
+ * Returns NULL when it doesn't exist.
+ */
+char_u * get_var_value(name)
+char_u *name;
+{
+ dictitem_T *v;
+
+ v = find_var(name, NULL, FALSE);
+ if (v == NULL)
+ return NULL;
+ return get_tv_string(&v->di_tv);
+}
+
+/*
+ * Allocate a new hashtab for a sourced script. It will be used while
+ * sourcing this script and when executing functions defined in the script.
+ */
+void new_script_vars(id)
+scid_T id;
+{
+ int i;
+ hashtab_T *ht;
+ scriptvar_T *sv;
+
+ if (ga_grow(&ga_scripts, (int)(id - ga_scripts.ga_len)) == OK) {
+ /* Re-allocating ga_data means that an ht_array pointing to
+ * ht_smallarray becomes invalid. We can recognize this: ht_mask is
+ * at its init value. Also reset "v_dict", it's always the same. */
+ for (i = 1; i <= ga_scripts.ga_len; ++i) {
+ ht = &SCRIPT_VARS(i);
+ if (ht->ht_mask == HT_INIT_SIZE - 1)
+ ht->ht_array = ht->ht_smallarray;
+ sv = SCRIPT_SV(i);
+ sv->sv_var.di_tv.vval.v_dict = &sv->sv_dict;
+ }
+
+ while (ga_scripts.ga_len < id) {
+ sv = SCRIPT_SV(ga_scripts.ga_len + 1) =
+ (scriptvar_T *)alloc_clear(sizeof(scriptvar_T));
+ init_var_dict(&sv->sv_dict, &sv->sv_var, VAR_SCOPE);
+ ++ga_scripts.ga_len;
+ }
+ }
+}
+
+/*
+ * Initialize dictionary "dict" as a scope and set variable "dict_var" to
+ * point to it.
+ */
+void init_var_dict(dict, dict_var, scope)
+dict_T *dict;
+dictitem_T *dict_var;
+int scope;
+{
+ hash_init(&dict->dv_hashtab);
+ dict->dv_lock = 0;
+ dict->dv_scope = scope;
+ dict->dv_refcount = DO_NOT_FREE_CNT;
+ dict->dv_copyID = 0;
+ dict_var->di_tv.vval.v_dict = dict;
+ dict_var->di_tv.v_type = VAR_DICT;
+ dict_var->di_tv.v_lock = VAR_FIXED;
+ dict_var->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX;
+ dict_var->di_key[0] = NUL;
+}
+
+/*
+ * Unreference a dictionary initialized by init_var_dict().
+ */
+void unref_var_dict(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);
+}
+
+/*
+ * Clean up a list of internal variables.
+ * Frees all allocated variables and the value they contain.
+ * Clears hashtab "ht", does not free it.
+ */
+void vars_clear(ht)
+hashtab_T *ht;
+{
+ vars_clear_ext(ht, TRUE);
+}
+
+/*
+ * Like vars_clear(), but only free the value if "free_val" is TRUE.
+ */
+static void vars_clear_ext(ht, free_val)
+hashtab_T *ht;
+int free_val;
+{
+ int todo;
+ hashitem_T *hi;
+ dictitem_T *v;
+
+ hash_lock(ht);
+ todo = (int)ht->ht_used;
+ for (hi = ht->ht_array; todo > 0; ++hi) {
+ if (!HASHITEM_EMPTY(hi)) {
+ --todo;
+
+ /* 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);
+ if (free_val)
+ clear_tv(&v->di_tv);
+ if ((v->di_flags & DI_FLAGS_FIX) == 0)
+ vim_free(v);
+ }
+ }
+ hash_clear(ht);
+ ht->ht_used = 0;
+}
+
+/*
+ * Delete a variable from hashtab "ht" at item "hi".
+ * Clear the variable value and free the dictitem.
+ */
+static void delete_var(ht, hi)
+hashtab_T *ht;
+hashitem_T *hi;
+{
+ dictitem_T *di = HI2DI(hi);
+
+ hash_remove(ht, hi);
+ clear_tv(&di->di_tv);
+ vim_free(di);
+}
+
+/*
+ * List the value of one internal variable.
+ */
+static void list_one_var(v, prefix, first)
+dictitem_T *v;
+char_u *prefix;
+int *first;
+{
+ char_u *tofree;
+ char_u *s;
+ char_u numbuf[NUMBUFLEN];
+
+ current_copyID += COPYID_INC;
+ s = echo_string(&v->di_tv, &tofree, numbuf, current_copyID);
+ list_one_var_a(prefix, v->di_key, v->di_tv.v_type,
+ s == NULL ? (char_u *)"" : s, first);
+ vim_free(tofree);
+}
+
+static void list_one_var_a(prefix, name, type, string, first)
+char_u *prefix;
+char_u *name;
+int type;
+char_u *string;
+int *first; /* when TRUE clear rest of screen and set to FALSE */
+{
+ /* 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);
+ msg_putchar(' ');
+ msg_advance(22);
+ if (type == VAR_NUMBER)
+ msg_putchar('#');
+ else if (type == VAR_FUNC)
+ msg_putchar('*');
+ else if (type == VAR_LIST) {
+ msg_putchar('[');
+ if (*string == '[')
+ ++string;
+ } else if (type == VAR_DICT) {
+ msg_putchar('{');
+ if (*string == '{')
+ ++string;
+ } else
+ msg_putchar(' ');
+
+ msg_outtrans(string);
+
+ if (type == VAR_FUNC)
+ msg_puts((char_u *)"()");
+ 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(name, tv, copy)
+char_u *name;
+typval_T *tv;
+int copy; /* make copy of value in "tv" */
+{
+ dictitem_T *v;
+ char_u *varname;
+ hashtab_T *ht;
+
+ ht = find_var_ht(name, &varname);
+ if (ht == NULL || *varname == NUL) {
+ EMSG2(_(e_illvar), name);
+ return;
+ }
+ v = find_var_in_ht(ht, 0, varname, TRUE);
+
+ if (tv->v_type == VAR_FUNC && var_check_func_name(name, v == NULL))
+ return;
+
+ if (v != NULL) {
+ /* existing variable, need to clear the value */
+ if (var_check_ro(v->di_flags, name)
+ || tv_check_lock(v->di_tv.v_lock, name))
+ 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);
+ return;
+ }
+
+ /*
+ * Handle setting internal v: variables separately: we don't change
+ * the type.
+ */
+ if (ht == &vimvarht) {
+ if (v->di_tv.v_type == VAR_STRING) {
+ vim_free(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. */
+ v->di_tv.vval.v_string = tv->vval.v_string;
+ tv->vval.v_string = NULL;
+ }
+ } else if (v->di_tv.v_type != VAR_NUMBER)
+ EMSG2(_(e_intern2), "set_var()");
+ else {
+ v->di_tv.vval.v_number = get_tv_number(tv);
+ if (STRCMP(varname, "searchforward") == 0)
+ set_search_direction(v->di_tv.vval.v_number ? '/' : '?');
+ else if (STRCMP(varname, "hlsearch") == 0) {
+ no_hlsearch = !v->di_tv.vval.v_number;
+ redraw_all_later(SOME_VALID);
+ }
+ }
+ return;
+ }
+
+ clear_tv(&v->di_tv);
+ } else { /* add a new variable */
+ /* Can't add "v:" variable. */
+ if (ht == &vimvarht) {
+ EMSG2(_(e_illvar), name);
+ return;
+ }
+
+ /* Make sure the variable name is valid. */
+ if (!valid_varname(varname))
+ return;
+
+ v = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T)
+ + STRLEN(varname)));
+ if (v == NULL)
+ return;
+ STRCPY(v->di_key, varname);
+ if (hash_add(ht, DI2HIKEY(v)) == FAIL) {
+ vim_free(v);
+ return;
+ }
+ v->di_flags = 0;
+ }
+
+ if (copy || tv->v_type == VAR_NUMBER || tv->v_type == VAR_FLOAT)
+ copy_tv(tv, &v->di_tv);
+ else {
+ v->di_tv = *tv;
+ v->di_tv.v_lock = 0;
+ init_tv(tv);
+ }
+}
+
+/*
+ * Return TRUE if di_flags "flags" indicates variable "name" is read-only.
+ * Also give an error message.
+ */
+static int var_check_ro(flags, name)
+int flags;
+char_u *name;
+{
+ if (flags & DI_FLAGS_RO) {
+ EMSG2(_(e_readonlyvar), name);
+ return TRUE;
+ }
+ if ((flags & DI_FLAGS_RO_SBX) && sandbox) {
+ EMSG2(_(e_readonlysbx), name);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*
+ * Return TRUE if di_flags "flags" indicates variable "name" is fixed.
+ * Also give an error message.
+ */
+static int var_check_fixed(flags, name)
+int flags;
+char_u *name;
+{
+ if (flags & DI_FLAGS_FIX) {
+ EMSG2(_("E795: Cannot delete variable %s"), 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(name, new_var)
+char_u *name; /* points to start of variable name */
+int new_var; /* TRUE when creating the variable */
+{
+ if (!(vim_strchr((char_u *)"wbs", 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;
+ }
+ /* 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)) {
+ EMSG2(_("E705: Variable name conflicts with existing function: %s"),
+ name);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*
+ * Check if a variable name is valid.
+ * Return FALSE and give an error if not.
+ */
+static int valid_varname(varname)
+char_u *varname;
+{
+ char_u *p;
+
+ for (p = varname; *p != NUL; ++p)
+ if (!eval_isnamec1(*p) && (p == varname || !VIM_ISDIGIT(*p))
+ && *p != AUTOLOAD_CHAR) {
+ EMSG2(_(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".
+ */
+static int tv_check_lock(lock, name)
+int lock;
+char_u *name;
+{
+ if (lock & VAR_LOCKED) {
+ EMSG2(_("E741: Value is locked: %s"),
+ name == NULL ? (char_u *)_("Unknown") : name);
+ return TRUE;
+ }
+ if (lock & VAR_FIXED) {
+ EMSG2(_("E742: Cannot change value of %s"),
+ name == NULL ? (char_u *)_("Unknown") : 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(from, to)
+typval_T *from;
+typval_T *to;
+{
+ to->v_type = from->v_type;
+ to->v_lock = 0;
+ switch (from->v_type) {
+ case VAR_NUMBER:
+ to->vval.v_number = from->vval.v_number;
+ break;
+ case VAR_FLOAT:
+ to->vval.v_float = from->vval.v_float;
+ break;
+ case VAR_STRING:
+ case VAR_FUNC:
+ if (from->vval.v_string == NULL)
+ to->vval.v_string = NULL;
+ else {
+ 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 = NULL;
+ else {
+ to->vval.v_list = from->vval.v_list;
+ ++to->vval.v_list->lv_refcount;
+ }
+ break;
+ case VAR_DICT:
+ if (from->vval.v_dict == NULL)
+ to->vval.v_dict = NULL;
+ else {
+ to->vval.v_dict = from->vval.v_dict;
+ ++to->vval.v_dict->dv_refcount;
+ }
+ break;
+ default:
+ EMSG2(_(e_intern2), "copy_tv()");
+ break;
+ }
+}
+
+/*
+ * Make a copy of an item.
+ * Lists and Dictionaries are also copied. A deep copy if "deep" is set.
+ * For deepcopy() "copyID" is zero for a full copy or the ID for when a
+ * reference to an already copied list/dict can be used.
+ * Returns FAIL or OK.
+ */
+static int item_copy(from, to, deep, copyID)
+typval_T *from;
+typval_T *to;
+int deep;
+int copyID;
+{
+ static int recurse = 0;
+ int ret = OK;
+
+ if (recurse >= DICT_MAXNEST) {
+ EMSG(_("E698: variable nested too deep for making a copy"));
+ return FAIL;
+ }
+ ++recurse;
+
+ switch (from->v_type) {
+ case VAR_NUMBER:
+ case VAR_FLOAT:
+ case VAR_STRING:
+ case VAR_FUNC:
+ copy_tv(from, to);
+ break;
+ case VAR_LIST:
+ to->v_type = VAR_LIST;
+ to->v_lock = 0;
+ 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
+ to->vval.v_list = list_copy(from->vval.v_list, deep, copyID);
+ if (to->vval.v_list == NULL)
+ ret = FAIL;
+ break;
+ case VAR_DICT:
+ to->v_type = VAR_DICT;
+ to->v_lock = 0;
+ if (from->vval.v_dict == NULL)
+ to->vval.v_dict = NULL;
+ else if (copyID != 0 && from->vval.v_dict->dv_copyID == copyID) {
+ /* use the copy made earlier */
+ to->vval.v_dict = from->vval.v_dict->dv_copydict;
+ ++to->vval.v_dict->dv_refcount;
+ } else
+ to->vval.v_dict = dict_copy(from->vval.v_dict, deep, copyID);
+ if (to->vval.v_dict == NULL)
+ ret = FAIL;
+ break;
+ default:
+ EMSG2(_(e_intern2), "item_copy()");
+ ret = FAIL;
+ }
+ --recurse;
+ return ret;
+}
+
+/*
+ * ":echo expr1 ..." print each argument separated with a space, add a
+ * newline at the end.
+ * ":echon expr1 ..." print each argument plain.
+ */
+void ex_echo(eap)
+exarg_T *eap;
+{
+ char_u *arg = eap->arg;
+ typval_T rettv;
+ char_u *tofree;
+ char_u *p;
+ int needclr = TRUE;
+ int atstart = TRUE;
+ char_u numbuf[NUMBUFLEN];
+
+ if (eap->skip)
+ ++emsg_skip;
+ while (*arg != NUL && *arg != '|' && *arg != '\n' && !got_int) {
+ /* If eval1() causes an error message the text from the command may
+ * 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;
+ }
+ need_clr_eos = FALSE;
+
+ if (!eap->skip) {
+ if (atstart) {
+ atstart = FALSE;
+ /* Call msg_start() after eval1(), evaluating the expression
+ * may cause a message to appear. */
+ if (eap->cmdidx == CMD_echo) {
+ /* Mark the 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();
+ msg_start();
+ }
+ } else if (eap->cmdidx == CMD_echo)
+ msg_puts_attr((char_u *)" ", echo_attr);
+ current_copyID += COPYID_INC;
+ p = echo_string(&rettv, &tofree, numbuf, current_copyID);
+ if (p != NULL)
+ for (; *p != NUL && !got_int; ++p) {
+ if (*p == '\n' || *p == '\r' || *p == TAB) {
+ if (*p != TAB && needclr) {
+ /* remove any text still there from the command */
+ msg_clr_eos();
+ needclr = FALSE;
+ }
+ msg_putchar_attr(*p, echo_attr);
+ } else {
+ if (has_mbyte) {
+ int i = (*mb_ptr2len)(p);
+
+ (void)msg_outtrans_len_attr(p, i, echo_attr);
+ p += i - 1;
+ } else
+ (void)msg_outtrans_len_attr(p, 1, echo_attr);
+ }
+ }
+ vim_free(tofree);
+ }
+ clear_tv(&rettv);
+ arg = skipwhite(arg);
+ }
+ eap->nextcmd = check_nextcmd(arg);
+
+ if (eap->skip)
+ --emsg_skip;
+ else {
+ /* remove text that may still be there from the command */
+ if (needclr)
+ msg_clr_eos();
+ if (eap->cmdidx == CMD_echo)
+ msg_end();
+ }
+}
+
+/*
+ * ":echohl {name}".
+ */
+void ex_echohl(eap)
+exarg_T *eap;
+{
+ int id;
+
+ id = syn_name2id(eap->arg);
+ if (id == 0)
+ echo_attr = 0;
+ else
+ echo_attr = syn_id2attr(id);
+}
+
+/*
+ * ":execute expr1 ..." execute the result of an expression.
+ * ":echomsg expr1 ..." Print a message
+ * ":echoerr expr1 ..." Print an error
+ * Each gets spaces around each argument and a newline at the end for
+ * echo commands
+ */
+void ex_execute(eap)
+exarg_T *eap;
+{
+ char_u *arg = eap->arg;
+ typval_T rettv;
+ int ret = OK;
+ char_u *p;
+ garray_T ga;
+ int len;
+ int save_did_emsg;
+
+ ga_init2(&ga, 1, 80);
+
+ if (eap->skip)
+ ++emsg_skip;
+ while (*arg != NUL && *arg != '|' && *arg != '\n') {
+ 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);
+ ret = FAIL;
+ break;
+ }
+
+ if (!eap->skip) {
+ p = get_tv_string(&rettv);
+ len = (int)STRLEN(p);
+ if (ga_grow(&ga, len + 2) == FAIL) {
+ clear_tv(&rettv);
+ ret = FAIL;
+ break;
+ }
+ if (ga.ga_len)
+ ((char_u *)(ga.ga_data))[ga.ga_len++] = ' ';
+ STRCPY((char_u *)(ga.ga_data) + ga.ga_len, p);
+ ga.ga_len += len;
+ }
+
+ clear_tv(&rettv);
+ arg = skipwhite(arg);
+ }
+
+ if (ret != FAIL && ga.ga_data != NULL) {
+ if (eap->cmdidx == CMD_echomsg) {
+ MSG_ATTR(ga.ga_data, echo_attr);
+ out_flush();
+ } else if (eap->cmdidx == CMD_echoerr) {
+ /* We don't want to abort following commands, restore did_emsg. */
+ save_did_emsg = did_emsg;
+ EMSG((char_u *)ga.ga_data);
+ if (!force_abort)
+ did_emsg = save_did_emsg;
+ } else if (eap->cmdidx == CMD_execute)
+ do_cmdline((char_u *)ga.ga_data,
+ eap->getline, eap->cookie, DOCMD_NOWAIT|DOCMD_VERBOSE);
+ }
+
+ ga_clear(&ga);
+
+ if (eap->skip)
+ --emsg_skip;
+
+ eap->nextcmd = check_nextcmd(arg);
+}
+
+/*
+ * Skip over the name of an option: "&option", "&g:option" or "&l:option".
+ * "arg" points to the "&" or '+' when called, to "option" when returning.
+ * Returns NULL when no option name found. Otherwise pointer to the char
+ * after the option name.
+ */
+static char_u * find_option_end(arg, opt_flags)
+char_u **arg;
+int *opt_flags;
+{
+ char_u *p = *arg;
+
+ ++p;
+ if (*p == 'g' && p[1] == ':') {
+ *opt_flags = OPT_GLOBAL;
+ p += 2;
+ } else if (*p == 'l' && p[1] == ':') {
+ *opt_flags = OPT_LOCAL;
+ p += 2;
+ } else
+ *opt_flags = 0;
+
+ 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;
+ return p;
+}
+
+/*
+ * ":function"
+ */
+void ex_function(eap)
+exarg_T *eap;
+{
+ char_u *theline;
+ int i;
+ int j;
+ int c;
+ int saved_did_emsg;
+ int saved_wait_return = need_wait_return;
+ char_u *name = NULL;
+ char_u *p;
+ char_u *arg;
+ char_u *line_arg = NULL;
+ garray_T newargs;
+ garray_T newlines;
+ int varargs = FALSE;
+ int mustend = FALSE;
+ int flags = 0;
+ ufunc_T *fp;
+ int indent;
+ int nesting;
+ char_u *skip_until = NULL;
+ dictitem_T *v;
+ funcdict_T fudi;
+ static int func_nr = 0; /* number for nameless function */
+ int paren;
+ hashtab_T *ht;
+ int todo;
+ hashitem_T *hi;
+ int sourcing_lnum_off;
+
+ /*
+ * ":function" without argument: list functions.
+ */
+ if (ends_excmd(*eap->arg)) {
+ if (!eap->skip) {
+ 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 (!isdigit(*fp->uf_name))
+ list_func_head(fp, FALSE);
+ }
+ }
+ }
+ eap->nextcmd = check_nextcmd(eap->arg);
+ return;
+ }
+
+ /*
+ * ":function /pat": list functions matching pattern.
+ */
+ if (*eap->arg == '/') {
+ p = skip_regexp(eap->arg + 1, '/', TRUE, NULL);
+ if (!eap->skip) {
+ regmatch_T regmatch;
+
+ c = *p;
+ *p = NUL;
+ regmatch.regprog = vim_regcomp(eap->arg + 1, RE_MAGIC);
+ *p = c;
+ if (regmatch.regprog != NULL) {
+ regmatch.rm_ic = p_ic;
+
+ 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 (!isdigit(*fp->uf_name)
+ && vim_regexec(&regmatch, fp->uf_name, 0))
+ list_func_head(fp, FALSE);
+ }
+ }
+ vim_regfree(regmatch.regprog);
+ }
+ }
+ if (*p == '/')
+ ++p;
+ eap->nextcmd = check_nextcmd(p);
+ return;
+ }
+
+ /*
+ * Get the function name. There are these situations:
+ * func normal function name
+ * "name" == func, "fudi.fd_dict" == NULL
+ * dict.func new dictionary entry
+ * "name" == NULL, "fudi.fd_dict" set,
+ * "fudi.fd_di" == NULL, "fudi.fd_newkey" == func
+ * dict.func existing dict entry with a Funcref
+ * "name" == func, "fudi.fd_dict" set,
+ * "fudi.fd_di" set, "fudi.fd_newkey" == NULL
+ * dict.func existing dict entry that's not a Funcref
+ * "name" == NULL, "fudi.fd_dict" set,
+ * "fudi.fd_di" set, "fudi.fd_newkey" == NULL
+ */
+ p = eap->arg;
+ name = trans_function_name(&p, eap->skip, 0, &fudi);
+ paren = (vim_strchr(p, '(') != NULL);
+ if (name == NULL && (fudi.fd_dict == NULL || !paren) && !eap->skip) {
+ /*
+ * Return on an invalid expression in braces, unless the expression
+ * evaluation has been cancelled due to an aborting error, an
+ * interrupt, or an exception.
+ */
+ if (!aborting()) {
+ if (!eap->skip && fudi.fd_newkey != NULL)
+ EMSG2(_(e_dictkey), fudi.fd_newkey);
+ vim_free(fudi.fd_newkey);
+ return;
+ } else
+ eap->skip = TRUE;
+ }
+
+ /* An error in a function call during evaluation of an expression in magic
+ * braces should not cause the function not to be defined. */
+ saved_did_emsg = did_emsg;
+ did_emsg = FALSE;
+
+ /*
+ * ":function func" with only function name: list function.
+ */
+ if (!paren) {
+ if (!ends_excmd(*skipwhite(p))) {
+ EMSG(_(e_trailing));
+ goto ret_free;
+ }
+ eap->nextcmd = check_nextcmd(p);
+ if (eap->nextcmd != NULL)
+ *p = NUL;
+ if (!eap->skip && !got_int) {
+ fp = find_func(name);
+ if (fp != NULL) {
+ list_func_head(fp, TRUE);
+ for (j = 0; j < fp->uf_lines.ga_len && !got_int; ++j) {
+ if (FUNCLINE(fp, j) == NULL)
+ continue;
+ msg_putchar('\n');
+ msg_outnum((long)(j + 1));
+ if (j < 9)
+ msg_putchar(' ');
+ if (j < 99)
+ msg_putchar(' ');
+ msg_prt_line(FUNCLINE(fp, j), FALSE);
+ out_flush(); /* show a line at a time */
+ ui_breakcheck();
+ }
+ if (!got_int) {
+ msg_putchar('\n');
+ msg_puts((char_u *)" endfunction");
+ }
+ } else
+ emsg_funcname(N_("E123: Undefined function: %s"), name);
+ }
+ goto ret_free;
+ }
+
+ /*
+ * ":function name(arg1, arg2)" Define function.
+ */
+ p = skipwhite(p);
+ if (*p != '(') {
+ if (!eap->skip) {
+ EMSG2(_("E124: Missing '(': %s"), eap->arg);
+ goto ret_free;
+ }
+ /* attempt to continue by skipping some text */
+ if (vim_strchr(p, '(') != NULL)
+ p = vim_strchr(p, '(');
+ }
+ p = skipwhite(p + 1);
+
+ ga_init2(&newargs, (int)sizeof(char_u *), 3);
+ ga_init2(&newlines, (int)sizeof(char_u *), 3);
+
+ if (!eap->skip) {
+ /* Check the name of the function. Unless it's a dictionary function
+ * (that we are overwriting). */
+ if (name != NULL)
+ 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 == K_SPECIAL)
+ j = 3;
+ else
+ j = 0;
+ while (arg[j] != NUL && (j == 0 ? eval_isnamec1(arg[j])
+ : eval_isnamec(arg[j])))
+ ++j;
+ if (arg[j] != NUL)
+ emsg_funcname((char *)e_invarg2, arg);
+ }
+ /* Disallow using the g: dict. */
+ if (fudi.fd_dict != NULL && fudi.fd_dict->dv_scope == VAR_DEF_SCOPE)
+ 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;
+ }
+ if (ga_grow(&newargs, 1) == FAIL)
+ goto erret;
+ c = *p;
+ *p = NUL;
+ arg = vim_strsave(arg);
+ if (arg == NULL)
+ goto erret;
+
+ /* 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);
+ 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;
+ }
+ }
+ ++p; /* skip the ')' */
+
+ /* find extra arguments "range", "dict" and "abort" */
+ for (;; ) {
+ p = skipwhite(p);
+ if (STRNCMP(p, "range", 5) == 0) {
+ flags |= FC_RANGE;
+ p += 5;
+ } else if (STRNCMP(p, "dict", 4) == 0) {
+ flags |= FC_DICT;
+ p += 4;
+ } else if (STRNCMP(p, "abort", 5) == 0) {
+ flags |= FC_ABORT;
+ p += 5;
+ } 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')
+ line_arg = p + 1;
+ else if (*p != NUL && *p != '"' && !eap->skip && !did_emsg)
+ EMSG(_(e_trailing));
+
+ /*
+ * Read the body of the function, until ":endfunction" is found.
+ */
+ if (KeyTyped) {
+ /* Check if the function already exists, don't let the user type the
+ * whole function before telling him it doesn't work! For a script we
+ * need to skip the body to be able to find what follows. */
+ if (!eap->skip && !eap->forceit) {
+ if (fudi.fd_dict != NULL && fudi.fd_newkey == NULL)
+ EMSG(_(e_funcdict));
+ else if (name != NULL && find_func(name) != NULL)
+ emsg_funcname(e_funcexts, name);
+ }
+
+ if (!eap->skip && did_emsg)
+ goto erret;
+
+ msg_putchar('\n'); /* don't overwrite the function name */
+ cmdline_row = msg_row;
+ }
+
+ indent = 2;
+ nesting = 0;
+ for (;; ) {
+ if (KeyTyped) {
+ msg_scroll = TRUE;
+ saved_wait_return = FALSE;
+ }
+ need_wait_return = FALSE;
+ sourcing_lnum_off = sourcing_lnum;
+
+ if (line_arg != NULL) {
+ /* Use eap->arg, split up in parts by line breaks. */
+ theline = line_arg;
+ p = vim_strchr(theline, '\n');
+ if (p == NULL)
+ line_arg += STRLEN(line_arg);
+ else {
+ *p = NUL;
+ line_arg = p + 1;
+ }
+ } else if (eap->getline == NULL)
+ theline = getcmdline(':', 0L, indent);
+ else
+ theline = eap->getline(':', eap->cookie, indent);
+ if (KeyTyped)
+ lines_left = Rows - 1;
+ if (theline == NULL) {
+ EMSG(_("E126: Missing :endfunction"));
+ goto erret;
+ }
+
+ /* Detect line continuation: sourcing_lnum increased more than one. */
+ if (sourcing_lnum > sourcing_lnum_off + 1)
+ sourcing_lnum_off = sourcing_lnum - sourcing_lnum_off - 1;
+ else
+ sourcing_lnum_off = 0;
+
+ if (skip_until != NULL) {
+ /* between ":append" and "." and between ":python <<EOF" and "EOF"
+ * don't check for ":endfunc". */
+ if (STRCMP(theline, skip_until) == 0) {
+ vim_free(skip_until);
+ skip_until = NULL;
+ }
+ } else {
+ /* skip ':' and blanks*/
+ for (p = theline; vim_iswhite(*p) || *p == ':'; ++p)
+ ;
+
+ /* Check for "endfunction". */
+ if (checkforcmd(&p, "endfunction", 4) && nesting-- == 0) {
+ if (line_arg == NULL)
+ vim_free(theline);
+ break;
+ }
+
+ /* Increase indent inside "if", "while", "for" and "try", decrease
+ * at "end". */
+ if (indent > 2 && STRNCMP(p, "end", 3) == 0)
+ indent -= 2;
+ else if (STRNCMP(p, "if", 2) == 0
+ || STRNCMP(p, "wh", 2) == 0
+ || STRNCMP(p, "for", 3) == 0
+ || STRNCMP(p, "try", 3) == 0)
+ indent += 2;
+
+ /* Check for defining a function inside this function. */
+ if (checkforcmd(&p, "function", 2)) {
+ if (*p == '!')
+ p = skipwhite(p + 1);
+ p += eval_fname_script(p);
+ if (ASCII_ISALPHA(*p)) {
+ vim_free(trans_function_name(&p, TRUE, 0, NULL));
+ if (*skipwhite(p) == '(') {
+ ++nesting;
+ indent += 2;
+ }
+ }
+ }
+
+ /* Check for ":append" or ":insert". */
+ p = skip_range(p, NULL);
+ if ((p[0] == 'a' && (!ASCII_ISALPHA(p[1]) || p[1] == 'p'))
+ || (p[0] == 'i'
+ && (!ASCII_ISALPHA(p[1]) || (p[1] == 'n'
+ && (!ASCII_ISALPHA(p[2]) ||
+ (p[2] == 's'))))))
+ skip_until = vim_strsave((char_u *)".");
+
+ /* Check for ":python <<EOF", ":tcl <<EOF", etc. */
+ arg = skipwhite(skiptowhite(p));
+ if (arg[0] == '<' && arg[1] =='<'
+ && ((p[0] == 'p' && p[1] == 'y'
+ && (!ASCII_ISALPHA(p[2]) || p[2] == 't'))
+ || (p[0] == 'p' && p[1] == 'e'
+ && (!ASCII_ISALPHA(p[2]) || p[2] == 'r'))
+ || (p[0] == 't' && p[1] == 'c'
+ && (!ASCII_ISALPHA(p[2]) || p[2] == 'l'))
+ || (p[0] == 'l' && p[1] == 'u' && p[2] == 'a'
+ && !ASCII_ISALPHA(p[3]))
+ || (p[0] == 'r' && p[1] == 'u' && p[2] == 'b'
+ && (!ASCII_ISALPHA(p[3]) || p[3] == 'y'))
+ || (p[0] == 'm' && p[1] == 'z'
+ && (!ASCII_ISALPHA(p[2]) || p[2] == 's'))
+ )) {
+ /* ":python <<" continues until a dot, like ":append" */
+ p = skipwhite(arg + 2);
+ if (*p == NUL)
+ skip_until = vim_strsave((char_u *)".");
+ else
+ skip_until = vim_strsave(p);
+ }
+ }
+
+ /* Add the line to the function. */
+ if (ga_grow(&newlines, 1 + sourcing_lnum_off) == FAIL) {
+ if (line_arg == NULL)
+ vim_free(theline);
+ goto erret;
+ }
+
+ /* Copy the line to newly allocated memory. get_one_sourceline()
+ * allocates 250 bytes per line, this saves 80% on average. The cost
+ * is an extra alloc/free. */
+ p = vim_strsave(theline);
+ if (p != NULL) {
+ if (line_arg == NULL)
+ vim_free(theline);
+ theline = p;
+ }
+
+ ((char_u **)(newlines.ga_data))[newlines.ga_len++] = theline;
+
+ /* Add NULL lines for continuation lines, so that the line count is
+ * equal to the index in the growarray. */
+ while (sourcing_lnum_off-- > 0)
+ ((char_u **)(newlines.ga_data))[newlines.ga_len++] = NULL;
+
+ /* Check for end of eap->arg. */
+ if (line_arg != NULL && *line_arg == NUL)
+ line_arg = NULL;
+ }
+
+ /* Don't define the function when skipping commands or when an error was
+ * detected. */
+ if (eap->skip || did_emsg)
+ goto erret;
+
+ /*
+ * If there are no errors, add the function
+ */
+ if (fudi.fd_dict == NULL) {
+ v = find_var(name, &ht, FALSE);
+ if (v != NULL && v->di_tv.v_type == VAR_FUNC) {
+ emsg_funcname(N_("E707: Function name conflicts with variable: %s"),
+ name);
+ goto erret;
+ }
+
+ fp = find_func(name);
+ if (fp != NULL) {
+ if (!eap->forceit) {
+ emsg_funcname(e_funcexts, name);
+ goto erret;
+ }
+ 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));
+ vim_free(name);
+ name = NULL;
+ }
+ } else {
+ char numbuf[20];
+
+ fp = NULL;
+ if (fudi.fd_newkey == NULL && !eap->forceit) {
+ EMSG(_(e_funcdict));
+ goto erret;
+ }
+ if (fudi.fd_di == NULL) {
+ /* Can't add a function to a locked dictionary */
+ if (tv_check_lock(fudi.fd_dict->dv_lock, eap->arg))
+ goto erret;
+ }
+ /* Can't change an existing function if it is locked */
+ else if (tv_check_lock(fudi.fd_di->di_tv.v_lock, eap->arg))
+ goto erret;
+
+ /* Give the function a sequential number. Can only be used with a
+ * Funcref! */
+ vim_free(name);
+ sprintf(numbuf, "%d", ++func_nr);
+ name = vim_strsave((char_u *)numbuf);
+ if (name == NULL)
+ goto erret;
+ }
+
+ if (fp == NULL) {
+ if (fudi.fd_dict == NULL && vim_strchr(name, AUTOLOAD_CHAR) != NULL) {
+ int slen, plen;
+ char_u *scriptname;
+
+ /* Check that the autoload name matches the script name. */
+ j = FAIL;
+ if (sourcing_name != NULL) {
+ scriptname = autoload_name(name);
+ if (scriptname != NULL) {
+ p = vim_strchr(scriptname, '/');
+ plen = (int)STRLEN(p);
+ slen = (int)STRLEN(sourcing_name);
+ if (slen > plen && fnamecmp(p,
+ sourcing_name + slen - plen) == 0)
+ j = OK;
+ vim_free(scriptname);
+ }
+ }
+ if (j == FAIL) {
+ EMSG2(_(
+ "E746: Function name does not match script file name: %s"),
+ name);
+ goto erret;
+ }
+ }
+
+ fp = (ufunc_T *)alloc((unsigned)(sizeof(ufunc_T) + STRLEN(name)));
+ if (fp == NULL)
+ goto erret;
+
+ if (fudi.fd_dict != NULL) {
+ if (fudi.fd_di == NULL) {
+ /* add new dict entry */
+ fudi.fd_di = dictitem_alloc(fudi.fd_newkey);
+ if (fudi.fd_di == NULL) {
+ vim_free(fp);
+ goto erret;
+ }
+ if (dict_add(fudi.fd_dict, fudi.fd_di) == FAIL) {
+ vim_free(fudi.fd_di);
+ vim_free(fp);
+ goto erret;
+ }
+ } else
+ /* overwrite existing dict entry */
+ clear_tv(&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);
+ fp->uf_refcount = 1;
+
+ /* behave like "dict" was used */
+ flags |= FC_DICT;
+ }
+
+ /* insert the new function in the function list */
+ STRCPY(fp->uf_name, name);
+ hash_add(&func_hashtab, UF2HIKEY(fp));
+ }
+ fp->uf_args = newargs;
+ fp->uf_lines = newlines;
+ 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 = varargs;
+ fp->uf_flags = flags;
+ fp->uf_calls = 0;
+ fp->uf_script_ID = current_SID;
+ goto ret_free;
+
+erret:
+ ga_clear_strings(&newargs);
+ ga_clear_strings(&newlines);
+ret_free:
+ vim_free(skip_until);
+ vim_free(fudi.fd_newkey);
+ vim_free(name);
+ did_emsg |= saved_did_emsg;
+ need_wait_return |= saved_wait_return;
+}
+
+/*
+ * 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).
+ */
+static char_u * trans_function_name(pp, skip, flags, fdp)
+char_u **pp;
+int skip; /* only find the end, don't evaluate */
+int flags;
+funcdict_T *fdp; /* return: info about dictionary used */
+{
+ char_u *name = NULL;
+ char_u *start;
+ char_u *end;
+ int lead;
+ char_u sid_buf[20];
+ int len;
+ lval_T lv;
+
+ if (fdp != NULL)
+ vim_memset(fdp, 0, sizeof(funcdict_T));
+ start = *pp;
+
+ /* Check for hard coded <SNR>: already translated function ID (from a user
+ * command). */
+ 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);
+ }
+
+ /* 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)
+ 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);
+ if (end == start) {
+ if (!skip)
+ EMSG(_("E129: Function name required"));
+ goto theend;
+ }
+ if (end == NULL || (lv.ll_tv != NULL && (lead > 2 || lv.ll_range))) {
+ /*
+ * Report an invalid expression in braces, unless the expression
+ * evaluation has been cancelled due to an aborting error, an
+ * interrupt, or an exception.
+ */
+ if (!aborting()) {
+ if (end != NULL)
+ EMSG2(_(e_invarg2), start);
+ } else
+ *pp = find_name_end(start, NULL, NULL, FNE_INCL_BR);
+ goto theend;
+ }
+
+ if (lv.ll_tv != NULL) {
+ if (fdp != NULL) {
+ fdp->fd_dict = lv.ll_dict;
+ fdp->fd_newkey = lv.ll_newkey;
+ lv.ll_newkey = NULL;
+ fdp->fd_di = lv.ll_di;
+ }
+ 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;
+ } else {
+ if (!skip && !(flags & TFN_QUIET) && (fdp == NULL
+ || lv.ll_dict == NULL ||
+ fdp->fd_newkey == NULL))
+ EMSG(_(e_funcref));
+ else
+ *pp = end;
+ name = NULL;
+ }
+ goto theend;
+ }
+
+ if (lv.ll_name == NULL) {
+ /* Error found, but continue after the function name. */
+ *pp = 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)
+ name = NULL;
+ } else {
+ len = (int)(end - *pp);
+ name = deref_func_name(*pp, &len, flags & TFN_NO_AUTOLOAD);
+ if (name == *pp)
+ name = NULL;
+ }
+ if (name != NULL) {
+ name = vim_strsave(name);
+ *pp = end;
+ goto theend;
+ }
+
+ if (lv.ll_exp_name != NULL) {
+ 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 += 2;
+ len -= 2;
+ lead = 2;
+ }
+ } else {
+ if (lead == 2) /* skip over "s:" */
+ lv.ll_name += 2;
+ len = (int)(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) {
+ lead = 3;
+ if ((lv.ll_exp_name != NULL && eval_fname_sid(lv.ll_exp_name))
+ || eval_fname_sid(*pp)) {
+ /* It's "s:" or "<SID>" */
+ if (current_SID <= 0) {
+ EMSG(_(e_usingsid));
+ goto theend;
+ }
+ sprintf((char *)sid_buf, "%ld_", (long)current_SID);
+ lead += (int)STRLEN(sid_buf);
+ }
+ } else if (!(flags & TFN_INT) && builtin_function(lv.ll_name)) {
+ EMSG2(_(
+ "E128: Function name must start with a capital or contain a colon: %s"),
+ lv.ll_name);
+ goto theend;
+ }
+ name = alloc((unsigned)(len + lead + 1));
+ if (name != NULL) {
+ if (lead > 0) {
+ 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);
+ }
+ mch_memmove(name + lead, lv.ll_name, (size_t)len);
+ name[len + lead] = NUL;
+ }
+ *pp = end;
+
+theend:
+ clear_lval(&lv);
+ return name;
+}
+
+/*
+ * Return 5 if "p" starts with "<SID>" or "<SNR>" (ignoring case).
+ * Return 2 if "p" starts with "s:".
+ * Return 0 otherwise.
+ */
+static int eval_fname_script(p)
+char_u *p;
+{
+ if (p[0] == '<' && (STRNICMP(p + 1, "SID>", 4) == 0
+ || STRNICMP(p + 1, "SNR>", 4) == 0))
+ return 5;
+ 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(p)
+char_u *p;
+{
+ return *p == 's' || TOUPPER_ASC(p[2]) == 'I';
+}
+
+/*
+ * List the head of the function: "name(arg1, arg2)".
+ */
+static void list_func_head(fp, indent)
+ufunc_T *fp;
+int indent;
+{
+ int j;
+
+ msg_start();
+ if (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_putchar('(');
+ for (j = 0; j < fp->uf_args.ga_len; ++j) {
+ if (j)
+ MSG_PUTS(", ");
+ msg_puts(FUNCARG(fp, j));
+ }
+ if (fp->uf_varargs) {
+ 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");
+ 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(name)
+char_u *name;
+{
+ hashitem_T *hi;
+
+ hi = hash_find(&func_hashtab, name);
+ if (!HASHITEM_EMPTY(hi))
+ return HI2UF(hi);
+ return NULL;
+}
+
+#if defined(EXITFREE) || defined(PROTO)
+void free_all_functions() {
+ hashitem_T *hi;
+
+ /* 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)
+ if (!HASHITEM_EMPTY(hi)) {
+ func_free(HI2UF(hi));
+ break;
+ }
+}
+
+#endif
+
+int translated_function_exists(name)
+char_u *name;
+{
+ if (builtin_function(name))
+ return find_internal_func(name) >= 0;
+ return find_func(name) != NULL;
+}
+
+/*
+ * Return TRUE if a function "name" exists.
+ */
+static int function_exists(name)
+char_u *name;
+{
+ char_u *nm = name;
+ char_u *p;
+ int n = FALSE;
+
+ p = trans_function_name(&nm, FALSE, TFN_INT|TFN_QUIET|TFN_NO_AUTOLOAD,
+ NULL);
+ nm = skipwhite(nm);
+
+ /* Only accept "funcname", "funcname ", "funcname (..." and
+ * "funcname(...", not "funcname!...". */
+ if (p != NULL && (*nm == NUL || *nm == '('))
+ n = translated_function_exists(p);
+ vim_free(p);
+ return n;
+}
+
+char_u * get_expanded_name(name, check)
+char_u *name;
+int check;
+{
+ char_u *nm = name;
+ char_u *p;
+
+ p = trans_function_name(&nm, FALSE, TFN_INT|TFN_QUIET, NULL);
+
+ if (p != NULL && *nm == NUL)
+ if (!check || translated_function_exists(p))
+ return p;
+
+ vim_free(p);
+ return NULL;
+}
+
+/*
+ * Return TRUE if "name" looks like a builtin function name: starts with a
+ * lower case letter and doesn't contain a ':' or AUTOLOAD_CHAR.
+ */
+static int builtin_function(name)
+char_u *name;
+{
+ return ASCII_ISLOWER(name[0]) && vim_strchr(name, ':') == NULL
+ && vim_strchr(name, AUTOLOAD_CHAR) == NULL;
+}
+
+/*
+ * Start profiling function "fp".
+ */
+static void func_do_profile(fp)
+ufunc_T *fp;
+{
+ int len = fp->uf_lines.ga_len;
+
+ if (len == 0)
+ len = 1; /* avoid getting error for allocating zero bytes */
+ fp->uf_tm_count = 0;
+ profile_zero(&fp->uf_tm_self);
+ profile_zero(&fp->uf_tm_total);
+ if (fp->uf_tml_count == NULL)
+ fp->uf_tml_count = (int *)alloc_clear((unsigned) (sizeof(int) * len));
+ if (fp->uf_tml_total == NULL)
+ fp->uf_tml_total = (proftime_T *)alloc_clear((unsigned)
+ (sizeof(proftime_T) * len));
+ if (fp->uf_tml_self == NULL)
+ fp->uf_tml_self = (proftime_T *)alloc_clear((unsigned)
+ (sizeof(proftime_T) * len));
+ fp->uf_tml_idx = -1;
+ if (fp->uf_tml_count == NULL || fp->uf_tml_total == NULL
+ || fp->uf_tml_self == NULL)
+ return; /* out of memory */
+
+ fp->uf_profiling = TRUE;
+}
+
+/*
+ * Dump the profiling results for all functions in file "fd".
+ */
+void func_dump_profile(fd)
+FILE *fd;
+{
+ hashitem_T *hi;
+ int todo;
+ ufunc_T *fp;
+ int i;
+ ufunc_T **sorttab;
+ int st_len = 0;
+
+ todo = (int)func_hashtab.ht_used;
+ if (todo == 0)
+ return; /* nothing to dump */
+
+ sorttab = (ufunc_T **)alloc((unsigned)(sizeof(ufunc_T) * todo));
+
+ for (hi = func_hashtab.ht_array; todo > 0; ++hi) {
+ if (!HASHITEM_EMPTY(hi)) {
+ --todo;
+ fp = HI2UF(hi);
+ if (fp->uf_profiling) {
+ if (sorttab != NULL)
+ sorttab[st_len++] = fp;
+
+ if (fp->uf_name[0] == K_SPECIAL)
+ fprintf(fd, "FUNCTION <SNR>%s()\n", fp->uf_name + 3);
+ else
+ fprintf(fd, "FUNCTION %s()\n", fp->uf_name);
+ if (fp->uf_tm_count == 1)
+ fprintf(fd, "Called 1 time\n");
+ else
+ fprintf(fd, "Called %d times\n", fp->uf_tm_count);
+ fprintf(fd, "Total time: %s\n", profile_msg(&fp->uf_tm_total));
+ fprintf(fd, " Self time: %s\n", profile_msg(&fp->uf_tm_self));
+ fprintf(fd, "\n");
+ fprintf(fd, "count total (s) self (s)\n");
+
+ for (i = 0; i < fp->uf_lines.ga_len; ++i) {
+ if (FUNCLINE(fp, i) == NULL)
+ continue;
+ prof_func_line(fd, fp->uf_tml_count[i],
+ &fp->uf_tml_total[i], &fp->uf_tml_self[i], TRUE);
+ fprintf(fd, "%s\n", FUNCLINE(fp, i));
+ }
+ fprintf(fd, "\n");
+ }
+ }
+ }
+
+ if (sorttab != NULL && st_len > 0) {
+ qsort((void *)sorttab, (size_t)st_len, sizeof(ufunc_T *),
+ prof_total_cmp);
+ prof_sort_list(fd, sorttab, st_len, "TOTAL", FALSE);
+ qsort((void *)sorttab, (size_t)st_len, sizeof(ufunc_T *),
+ prof_self_cmp);
+ prof_sort_list(fd, sorttab, st_len, "SELF", TRUE);
+ }
+
+ vim_free(sorttab);
+}
+
+static void prof_sort_list(fd, sorttab, st_len, title, prefer_self)
+FILE *fd;
+ufunc_T **sorttab;
+int st_len;
+char *title;
+int prefer_self; /* when equal print only self time */
+{
+ int i;
+ ufunc_T *fp;
+
+ fprintf(fd, "FUNCTIONS SORTED ON %s TIME\n", title);
+ fprintf(fd, "count total (s) self (s) function\n");
+ for (i = 0; i < 20 && i < st_len; ++i) {
+ fp = sorttab[i];
+ prof_func_line(fd, fp->uf_tm_count, &fp->uf_tm_total, &fp->uf_tm_self,
+ prefer_self);
+ if (fp->uf_name[0] == K_SPECIAL)
+ fprintf(fd, " <SNR>%s()\n", fp->uf_name + 3);
+ else
+ fprintf(fd, " %s()\n", fp->uf_name);
+ }
+ fprintf(fd, "\n");
+}
+
+/*
+ * Print the count and times for one function or function line.
+ */
+static void prof_func_line(fd, count, total, self, prefer_self)
+FILE *fd;
+int count;
+proftime_T *total;
+proftime_T *self;
+int prefer_self; /* when equal print only self time */
+{
+ if (count > 0) {
+ fprintf(fd, "%5d ", count);
+ if (prefer_self && profile_equal(total, self))
+ fprintf(fd, " ");
+ else
+ fprintf(fd, "%s ", profile_msg(total));
+ if (!prefer_self && profile_equal(total, self))
+ fprintf(fd, " ");
+ else
+ fprintf(fd, "%s ", profile_msg(self));
+ } else
+ fprintf(fd, " ");
+}
+
+/*
+ * Compare function for total time sorting.
+ */
+static int prof_total_cmp(s1, s2)
+const void *s1;
+const void *s2;
+{
+ ufunc_T *p1, *p2;
+
+ p1 = *(ufunc_T **)s1;
+ p2 = *(ufunc_T **)s2;
+ return profile_cmp(&p1->uf_tm_total, &p2->uf_tm_total);
+}
+
+/*
+ * Compare function for self time sorting.
+ */
+static int prof_self_cmp(s1, s2)
+const void *s1;
+const void *s2;
+{
+ ufunc_T *p1, *p2;
+
+ p1 = *(ufunc_T **)s1;
+ p2 = *(ufunc_T **)s2;
+ return profile_cmp(&p1->uf_tm_self, &p2->uf_tm_self);
+}
+
+
+/*
+ * If "name" has a package name try autoloading the script for it.
+ * Return TRUE if a package was loaded.
+ */
+static int script_autoload(name, reload)
+char_u *name;
+int reload; /* load script again when already loaded */
+{
+ 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;
+
+ tofree = scriptname = autoload_name(name);
+
+ /* 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)
+ break;
+ 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_grow(&ga_loaded, 1) == OK) {
+ ((char_u **)ga_loaded.ga_data)[ga_loaded.ga_len++] = scriptname;
+ tofree = NULL;
+ }
+
+ /* Try loading the package from $VIMRUNTIME/autoload/<name>.vim */
+ if (source_runtime(scriptname, FALSE) == OK)
+ ret = TRUE;
+ }
+
+ vim_free(tofree);
+ return ret;
+}
+
+/*
+ * Return the autoload script name for a function or variable name.
+ * Returns NULL when out of memory.
+ */
+static char_u * autoload_name(name)
+char_u *name;
+{
+ char_u *p;
+ char_u *scriptname;
+
+ /* Get the script file name: replace '#' with '/', append ".vim". */
+ scriptname = alloc((unsigned)(STRLEN(name) + 14));
+ if (scriptname == NULL)
+ return FALSE;
+ STRCPY(scriptname, "autoload/");
+ STRCAT(scriptname, name);
+ *vim_strrchr(scriptname, AUTOLOAD_CHAR) = NUL;
+ STRCAT(scriptname, ".vim");
+ while ((p = vim_strchr(scriptname, AUTOLOAD_CHAR)) != NULL)
+ *p = '/';
+ return scriptname;
+}
+
+
+/*
+ * Function given to ExpandGeneric() to obtain the list of user defined
+ * function names.
+ */
+char_u * get_user_func_name(xp, idx)
+expand_T *xp;
+int idx;
+{
+ static long_u done;
+ static hashitem_T *hi;
+ ufunc_T *fp;
+
+ if (idx == 0) {
+ done = 0;
+ hi = func_hashtab.ht_array;
+ }
+ if (done < func_hashtab.ht_used) {
+ if (done++ > 0)
+ ++hi;
+ while (HASHITEM_EMPTY(hi))
+ ++hi;
+ fp = HI2UF(hi);
+
+ if (fp->uf_flags & FC_DICT)
+ return (char_u *)""; /* don't show dict functions */
+
+ if (STRLEN(fp->uf_name) + 4 >= IOSIZE)
+ return fp->uf_name; /* prevents overflow */
+
+ cat_func_name(IObuff, fp);
+ if (xp->xp_context != EXPAND_USER_FUNC) {
+ STRCAT(IObuff, "(");
+ if (!fp->uf_varargs && fp->uf_args.ga_len == 0)
+ STRCAT(IObuff, ")");
+ }
+ return IObuff;
+ }
+ return NULL;
+}
+
+
+/*
+ * Copy the function name of "fp" to buffer "buf".
+ * "buf" must be able to hold the function name plus three bytes.
+ * Takes care of script-local function names.
+ */
+static void cat_func_name(buf, fp)
+char_u *buf;
+ufunc_T *fp;
+{
+ if (fp->uf_name[0] == K_SPECIAL) {
+ STRCPY(buf, "<SNR>");
+ STRCAT(buf, fp->uf_name + 3);
+ } else
+ STRCPY(buf, fp->uf_name);
+}
+
+/*
+ * ":delfunction {name}"
+ */
+void ex_delfunction(eap)
+exarg_T *eap;
+{
+ ufunc_T *fp = NULL;
+ char_u *p;
+ char_u *name;
+ funcdict_T fudi;
+
+ p = eap->arg;
+ name = trans_function_name(&p, eap->skip, 0, &fudi);
+ vim_free(fudi.fd_newkey);
+ if (name == NULL) {
+ if (fudi.fd_dict != NULL && !eap->skip)
+ EMSG(_(e_funcref));
+ return;
+ }
+ if (!ends_excmd(*skipwhite(p))) {
+ vim_free(name);
+ EMSG(_(e_trailing));
+ return;
+ }
+ eap->nextcmd = check_nextcmd(p);
+ if (eap->nextcmd != NULL)
+ *p = NUL;
+
+ if (!eap->skip)
+ fp = find_func(name);
+ vim_free(name);
+
+ if (!eap->skip) {
+ if (fp == NULL) {
+ EMSG2(_(e_nofunc), eap->arg);
+ return;
+ }
+ if (fp->uf_calls > 0) {
+ EMSG2(_("E131: Cannot delete function %s: It is in use"), eap->arg);
+ return;
+ }
+
+ 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);
+ }
+}
+
+/*
+ * Free a function and remove it from the list of functions.
+ */
+static void func_free(fp)
+ufunc_T *fp;
+{
+ hashitem_T *hi;
+
+ /* clear this function */
+ ga_clear_strings(&(fp->uf_args));
+ ga_clear_strings(&(fp->uf_lines));
+ vim_free(fp->uf_tml_count);
+ vim_free(fp->uf_tml_total);
+ vim_free(fp->uf_tml_self);
+
+ /* 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);
+
+ vim_free(fp);
+}
+
+/*
+ * Unreference a Function: decrement the reference count and free it when it
+ * becomes zero. Only for numbered functions.
+ */
+void func_unref(name)
+char_u *name;
+{
+ ufunc_T *fp;
+
+ if (name != NULL && isdigit(*name)) {
+ fp = find_func(name);
+ if (fp == NULL)
+ EMSG2(_(e_intern2), "func_unref()");
+ else if (--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);
+ }
+ }
+}
+
+/*
+ * Count a reference to a Function.
+ */
+void func_ref(name)
+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;
+ }
+}
+
+/*
+ * Call a user function.
+ */
+static void call_user_func(fp, argcount, argvars, rettv, firstline, lastline,
+ selfdict)
+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" */
+{
+ char_u *save_sourcing_name;
+ linenr_T save_sourcing_lnum;
+ scid_T save_current_SID;
+ funccall_T *fc;
+ int save_did_emsg;
+ static int depth = 0;
+ dictitem_T *v;
+ int fixvar_idx = 0; /* index in fixvar[] */
+ int i;
+ int ai;
+ char_u numbuf[NUMBUFLEN];
+ char_u *name;
+ proftime_T wait_start;
+ proftime_T call_start;
+
+ /* If depth of calling is getting too high, don't execute the function */
+ if (depth >= p_mfd) {
+ EMSG(_("E132: Function call depth is higher than 'maxfuncdepth'"));
+ rettv->v_type = VAR_NUMBER;
+ rettv->vval.v_number = -1;
+ return;
+ }
+ ++depth;
+
+ line_breakcheck(); /* check for CTRL-C hit */
+
+ fc = (funccall_T *)alloc(sizeof(funccall_T));
+ fc->caller = current_funccal;
+ current_funccal = fc;
+ fc->func = fp;
+ fc->rettv = rettv;
+ rettv->vval.v_number = 0;
+ fc->linenr = 0;
+ fc->returned = FALSE;
+ fc->level = ex_nesting_level;
+ /* Check if this function has a breakpoint. */
+ 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.
+ */
+ 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;
+ name = v->di_key;
+ STRCPY(name, "self");
+ v->di_flags = DI_FLAGS_RO + DI_FLAGS_FIX;
+ hash_add(&fc->l_vars.dv_hashtab, DI2HIKEY(v));
+ v->di_tv.v_type = VAR_DICT;
+ v->di_tv.v_lock = 0;
+ v->di_tv.vval.v_dict = selfdict;
+ ++selfdict->dv_refcount;
+ }
+
+ /*
+ * Init a: variables.
+ * Set a:0 to "argcount".
+ * 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;
+ name = v->di_key;
+ STRCPY(name, "000");
+ v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX;
+ hash_add(&fc->l_avars.dv_hashtab, DI2HIKEY(v));
+ v->di_tv.v_type = VAR_LIST;
+ v->di_tv.v_lock = VAR_FIXED;
+ v->di_tv.vval.v_list = &fc->l_varlist;
+ vim_memset(&fc->l_varlist, 0, sizeof(list_T));
+ fc->l_varlist.lv_refcount = DO_NOT_FREE_CNT;
+ fc->l_varlist.lv_lock = 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, &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 (i = 0; i < argcount; ++i) {
+ ai = i - fp->uf_args.ga_len;
+ if (ai < 0)
+ /* named argument a:name */
+ name = FUNCARG(fp, i);
+ else {
+ /* "..." argument a:1, a:2, etc. */
+ sprintf((char *)numbuf, "%d", ai + 1);
+ name = numbuf;
+ }
+ if (fixvar_idx < FIXVAR_CNT && STRLEN(name) <= VAR_SHORT_LEN) {
+ v = &fc->fixvar[fixvar_idx++].var;
+ v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX;
+ } else {
+ v = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T)
+ + STRLEN(name)));
+ if (v == NULL)
+ break;
+ v->di_flags = DI_FLAGS_RO;
+ }
+ 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. */
+ v->di_tv = argvars[i];
+ v->di_tv.v_lock = VAR_FIXED;
+
+ 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;
+ }
+ }
+
+ /* Don't redraw while executing the function. */
+ ++RedrawingDisabled;
+ save_sourcing_name = sourcing_name;
+ save_sourcing_lnum = sourcing_lnum;
+ sourcing_lnum = 1;
+ sourcing_name = alloc((unsigned)((save_sourcing_name == NULL ? 0
+ : STRLEN(save_sourcing_name)) +
+ STRLEN(fp->uf_name) + 13));
+ if (sourcing_name != NULL) {
+ if (save_sourcing_name != NULL
+ && STRNCMP(save_sourcing_name, "function ", 9) == 0)
+ sprintf((char *)sourcing_name, "%s..", save_sourcing_name);
+ else
+ STRCPY(sourcing_name, "function ");
+ cat_func_name(sourcing_name + STRLEN(sourcing_name), fp);
+
+ if (p_verbose >= 12) {
+ ++no_wait_return;
+ verbose_enter_scroll();
+
+ smsg((char_u *)_("calling %s"), sourcing_name);
+ if (p_verbose >= 14) {
+ char_u buf[MSG_BUF_LEN];
+ char_u numbuf2[NUMBUFLEN];
+ char_u *tofree;
+ char_u *s;
+
+ msg_puts((char_u *)"(");
+ for (i = 0; i < argcount; ++i) {
+ if (i > 0)
+ msg_puts((char_u *)", ");
+ if (argvars[i].v_type == VAR_NUMBER)
+ msg_outnum((long)argvars[i].vval.v_number);
+ else {
+ s = tv2string(&argvars[i], &tofree, numbuf2, 0);
+ if (s != NULL) {
+ if (vim_strsize(s) > MSG_BUF_CLEN) {
+ trunc_string(s, buf, MSG_BUF_CLEN, MSG_BUF_LEN);
+ s = buf;
+ }
+ msg_puts(s);
+ vim_free(tofree);
+ }
+ }
+ }
+ msg_puts((char_u *)")");
+ }
+ msg_puts((char_u *)"\n"); /* don't overwrite this either */
+
+ verbose_leave_scroll();
+ --no_wait_return;
+ }
+ }
+ if (do_profiling == PROF_YES) {
+ if (!fp->uf_profiling && has_profiling(FALSE, fp->uf_name, NULL))
+ func_do_profile(fp);
+ if (fp->uf_profiling
+ || (fc->caller != NULL && fc->caller->func->uf_profiling)) {
+ ++fp->uf_tm_count;
+ profile_start(&call_start);
+ profile_zero(&fp->uf_tm_children);
+ }
+ script_prof_save(&wait_start);
+ }
+
+ save_current_SID = current_SID;
+ current_SID = fp->uf_script_ID;
+ save_did_emsg = did_emsg;
+ did_emsg = FALSE;
+
+ /* call do_cmdline() to execute the lines */
+ do_cmdline(NULL, get_func_line, (void *)fc,
+ DOCMD_NOWAIT|DOCMD_VERBOSE|DOCMD_REPEAT);
+
+ --RedrawingDisabled;
+
+ /* 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);
+ rettv->v_type = VAR_NUMBER;
+ rettv->vval.v_number = -1;
+ }
+
+ if (do_profiling == PROF_YES && (fp->uf_profiling
+ || (fc->caller != NULL &&
+ fc->caller->func->uf_profiling))) {
+ profile_end(&call_start);
+ profile_sub_wait(&wait_start, &call_start);
+ profile_add(&fp->uf_tm_total, &call_start);
+ profile_self(&fp->uf_tm_self, &call_start, &fp->uf_tm_children);
+ if (fc->caller != NULL && fc->caller->func->uf_profiling) {
+ profile_add(&fc->caller->func->uf_tm_children, &call_start);
+ profile_add(&fc->caller->func->uf_tml_children, &call_start);
+ }
+ }
+
+ /* when being verbose, mention the return value */
+ if (p_verbose >= 12) {
+ ++no_wait_return;
+ verbose_enter_scroll();
+
+ if (aborting())
+ smsg((char_u *)_("%s aborted"), sourcing_name);
+ else if (fc->rettv->v_type == VAR_NUMBER)
+ smsg((char_u *)_("%s returning #%ld"), sourcing_name,
+ (long)fc->rettv->vval.v_number);
+ else {
+ char_u buf[MSG_BUF_LEN];
+ char_u numbuf2[NUMBUFLEN];
+ char_u *tofree;
+ char_u *s;
+
+ /* The value may be very long. Skip the middle part, so that we
+ * have some idea how it starts and ends. smsg() would always
+ * truncate it at the end. */
+ s = tv2string(fc->rettv, &tofree, numbuf2, 0);
+ if (s != NULL) {
+ if (vim_strsize(s) > MSG_BUF_CLEN) {
+ trunc_string(s, buf, MSG_BUF_CLEN, MSG_BUF_LEN);
+ s = buf;
+ }
+ smsg((char_u *)_("%s returning %s"), sourcing_name, s);
+ vim_free(tofree);
+ }
+ }
+ msg_puts((char_u *)"\n"); /* don't overwrite this either */
+
+ verbose_leave_scroll();
+ --no_wait_return;
+ }
+
+ vim_free(sourcing_name);
+ sourcing_name = save_sourcing_name;
+ sourcing_lnum = save_sourcing_lnum;
+ current_SID = save_current_SID;
+ if (do_profiling == PROF_YES)
+ script_prof_restore(&wait_start);
+
+ if (p_verbose >= 12 && sourcing_name != NULL) {
+ ++no_wait_return;
+ verbose_enter_scroll();
+
+ smsg((char_u *)_("continuing in %s"), sourcing_name);
+ msg_puts((char_u *)"\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;
+
+ /* "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;
+
+ /* 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);
+ }
+}
+
+/*
+ * 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(fc, copyID)
+funccall_T *fc;
+int copyID;
+{
+ return fc->l_varlist.lv_copyID != copyID
+ && fc->l_vars.dv_copyID != copyID
+ && fc->l_avars.dv_copyID != copyID;
+}
+
+/*
+ * Free "fc" and what it contains.
+ */
+static void free_funccal(fc, free_val)
+funccall_T *fc;
+int free_val; /* a: vars were allocated */
+{
+ listitem_T *li;
+
+ /* 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 */
+ 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);
+
+ vim_free(fc);
+}
+
+/*
+ * Add a number variable "name" to dict "dp" with value "nr".
+ */
+static void add_nr_var(dp, v, name, nr)
+dict_T *dp;
+dictitem_T *v;
+char *name;
+varnumber_T nr;
+{
+ STRCPY(v->di_key, name);
+ v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX;
+ hash_add(&dp->dv_hashtab, DI2HIKEY(v));
+ v->di_tv.v_type = VAR_NUMBER;
+ v->di_tv.v_lock = VAR_FIXED;
+ v->di_tv.vval.v_number = nr;
+}
+
+/*
+ * ":return [expr]"
+ */
+void ex_return(eap)
+exarg_T *eap;
+{
+ char_u *arg = eap->arg;
+ typval_T rettv;
+ int returning = FALSE;
+
+ if (current_funccal == NULL) {
+ EMSG(_("E133: :return not inside a function"));
+ return;
+ }
+
+ if (eap->skip)
+ ++emsg_skip;
+
+ 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);
+ }
+
+ /* When skipping or the return gets pending, advance to the next command
+ * in this line (!returning). Otherwise, ignore the rest of the line.
+ * Following lines will be ignored by get_func_line(). */
+ if (returning)
+ eap->nextcmd = NULL;
+ else if (eap->nextcmd == NULL) /* no argument */
+ eap->nextcmd = check_nextcmd(arg);
+
+ if (eap->skip)
+ --emsg_skip;
+}
+
+/*
+ * Return from a function. Possibly makes the return pending. Also called
+ * for a pending return at the ":endtry" or after returning from an extra
+ * do_cmdline(). "reanimate" is used in the latter case. "is_cmd" is set
+ * when called due to a ":return" command. "rettv" may point to a typval_T
+ * with the return rettv. Returns TRUE when the return can be carried out,
+ * FALSE when the return gets pending.
+ */
+int do_return(eap, reanimate, is_cmd, rettv)
+exarg_T *eap;
+int reanimate;
+int is_cmd;
+void *rettv;
+{
+ int idx;
+ struct condstack *cstack = eap->cstack;
+
+ if (reanimate)
+ /* Undo the return. */
+ current_funccal->returned = FALSE;
+
+ /*
+ * Cleanup (and inactivate) conditionals, but stop when a try conditional
+ * not in its finally clause (which then is to be executed next) is found.
+ * In this case, make the ":return" pending for execution at the ":endtry".
+ * Otherwise, return normally.
+ */
+ idx = cleanup_conditionals(eap->cstack, 0, TRUE);
+ if (idx >= 0) {
+ cstack->cs_pending[idx] = CSTP_RETURN;
+
+ if (!is_cmd && !reanimate)
+ /* A pending return again gets pending. "rettv" points to an
+ * allocated variable with the rettv of the original ":return"'s
+ * argument if present or is NULL else. */
+ cstack->cs_rettv[idx] = rettv;
+ else {
+ /* When undoing a return in order to make it pending, get the stored
+ * return rettv. */
+ if (reanimate)
+ rettv = current_funccal->rettv;
+
+ if (rettv != NULL) {
+ /* Store the value of the pending return. */
+ if ((cstack->cs_rettv[idx] = alloc_tv()) != NULL)
+ *(typval_T *)cstack->cs_rettv[idx] = *(typval_T *)rettv;
+ else
+ EMSG(_(e_outofmem));
+ } else
+ cstack->cs_rettv[idx] = NULL;
+
+ if (reanimate) {
+ /* The pending return value could be overwritten by a ":return"
+ * without argument in a finally clause; reset the default
+ * return value. */
+ current_funccal->rettv->v_type = VAR_NUMBER;
+ current_funccal->rettv->vval.v_number = 0;
+ }
+ }
+ report_make_pending(CSTP_RETURN, rettv);
+ } else {
+ current_funccal->returned = TRUE;
+
+ /* If the return is carried out now, store the return value. For
+ * a return immediately after reanimation, the value is already
+ * there. */
+ if (!reanimate && rettv != NULL) {
+ clear_tv(current_funccal->rettv);
+ *current_funccal->rettv = *(typval_T *)rettv;
+ if (!is_cmd)
+ vim_free(rettv);
+ }
+ }
+
+ return idx < 0;
+}
+
+/*
+ * Free the variable with a pending return value.
+ */
+void discard_pending_return(rettv)
+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.
+ */
+char_u * get_return_cmd(rettv)
+void *rettv;
+{
+ char_u *s = NULL;
+ char_u *tofree = NULL;
+ char_u numbuf[NUMBUFLEN];
+
+ if (rettv != NULL)
+ s = echo_string((typval_T *)rettv, &tofree, numbuf, 0);
+ if (s == NULL)
+ s = (char_u *)"";
+
+ STRCPY(IObuff, ":return ");
+ STRNCPY(IObuff + 8, s, IOSIZE - 8);
+ if (STRLEN(s) + 8 >= IOSIZE)
+ STRCPY(IObuff + IOSIZE - 4, "...");
+ vim_free(tofree);
+ return vim_strsave(IObuff);
+}
+
+/*
+ * Get next function line.
+ * Called by do_cmdline() to get the next line.
+ * Returns allocated string, or NULL for end of function.
+ */
+char_u * get_func_line(c, cookie, indent)
+int c UNUSED;
+void *cookie;
+int indent UNUSED;
+{
+ funccall_T *fcp = (funccall_T *)cookie;
+ ufunc_T *fp = fcp->func;
+ char_u *retval;
+ garray_T *gap; /* growarray with function lines */
+
+ /* If breakpoints have been added/deleted need to check for it. */
+ if (fcp->dbg_tick != debug_tick) {
+ fcp->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name,
+ sourcing_lnum);
+ fcp->dbg_tick = debug_tick;
+ }
+ if (do_profiling == PROF_YES)
+ func_line_end(cookie);
+
+ gap = &fp->uf_lines;
+ if (((fp->uf_flags & FC_ABORT) && did_emsg && !aborted_in_try())
+ || fcp->returned)
+ retval = NULL;
+ else {
+ /* Skip NULL lines (continuation lines). */
+ while (fcp->linenr < gap->ga_len
+ && ((char_u **)(gap->ga_data))[fcp->linenr] == NULL)
+ ++fcp->linenr;
+ if (fcp->linenr >= gap->ga_len)
+ retval = NULL;
+ else {
+ retval = vim_strsave(((char_u **)(gap->ga_data))[fcp->linenr++]);
+ sourcing_lnum = fcp->linenr;
+ if (do_profiling == PROF_YES)
+ func_line_start(cookie);
+ }
+ }
+
+ /* Did we encounter a breakpoint? */
+ if (fcp->breakpoint != 0 && fcp->breakpoint <= sourcing_lnum) {
+ dbg_breakpoint(fp->uf_name, sourcing_lnum);
+ /* Find next breakpoint. */
+ fcp->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name,
+ sourcing_lnum);
+ fcp->dbg_tick = debug_tick;
+ }
+
+ return retval;
+}
+
+/*
+ * Called when starting to read a function line.
+ * "sourcing_lnum" must be correct!
+ * When skipping lines it may not actually be executed, but we won't find out
+ * until later and we need to store the time now.
+ */
+void func_line_start(cookie)
+void *cookie;
+{
+ funccall_T *fcp = (funccall_T *)cookie;
+ ufunc_T *fp = fcp->func;
+
+ if (fp->uf_profiling && sourcing_lnum >= 1
+ && sourcing_lnum <= fp->uf_lines.ga_len) {
+ fp->uf_tml_idx = sourcing_lnum - 1;
+ /* Skip continuation lines. */
+ while (fp->uf_tml_idx > 0 && FUNCLINE(fp, fp->uf_tml_idx) == NULL)
+ --fp->uf_tml_idx;
+ fp->uf_tml_execed = FALSE;
+ profile_start(&fp->uf_tml_start);
+ profile_zero(&fp->uf_tml_children);
+ profile_get_wait(&fp->uf_tml_wait);
+ }
+}
+
+/*
+ * Called when actually executing a function line.
+ */
+void func_line_exec(cookie)
+void *cookie;
+{
+ funccall_T *fcp = (funccall_T *)cookie;
+ ufunc_T *fp = fcp->func;
+
+ if (fp->uf_profiling && fp->uf_tml_idx >= 0)
+ fp->uf_tml_execed = TRUE;
+}
+
+/*
+ * Called when done with a function line.
+ */
+void func_line_end(cookie)
+void *cookie;
+{
+ funccall_T *fcp = (funccall_T *)cookie;
+ ufunc_T *fp = fcp->func;
+
+ if (fp->uf_profiling && fp->uf_tml_idx >= 0) {
+ if (fp->uf_tml_execed) {
+ ++fp->uf_tml_count[fp->uf_tml_idx];
+ profile_end(&fp->uf_tml_start);
+ profile_sub_wait(&fp->uf_tml_wait, &fp->uf_tml_start);
+ profile_add(&fp->uf_tml_total[fp->uf_tml_idx], &fp->uf_tml_start);
+ profile_self(&fp->uf_tml_self[fp->uf_tml_idx], &fp->uf_tml_start,
+ &fp->uf_tml_children);
+ }
+ fp->uf_tml_idx = -1;
+ }
+}
+
+/*
+ * Return TRUE if the currently active function should be ended, because a
+ * return was encountered or an error occurred. Used inside a ":while".
+ */
+int func_has_ended(cookie)
+void *cookie;
+{
+ funccall_T *fcp = (funccall_T *)cookie;
+
+ /* Ignore the "abort" flag if the abortion behavior has been changed due to
+ * an error inside a try conditional. */
+ return ((fcp->func->uf_flags & FC_ABORT) && did_emsg && !aborted_in_try())
+ || fcp->returned;
+}
+
+/*
+ * return TRUE if cookie indicates a function which "abort"s on errors.
+ */
+int func_has_abort(cookie)
+void *cookie;
+{
+ return ((funccall_T *)cookie)->func->uf_flags & FC_ABORT;
+}
+
+typedef enum {
+ VAR_FLAVOUR_DEFAULT, /* doesn't start with uppercase */
+ VAR_FLAVOUR_SESSION, /* starts with uppercase, some lower */
+ VAR_FLAVOUR_VIMINFO /* all uppercase */
+} var_flavour_T;
+
+static var_flavour_T var_flavour __ARGS((char_u *varname));
+
+static var_flavour_T var_flavour(varname)
+char_u *varname;
+{
+ char_u *p = varname;
+
+ if (ASCII_ISUPPER(*p)) {
+ while (*(++p))
+ if (ASCII_ISLOWER(*p))
+ return VAR_FLAVOUR_SESSION;
+ return VAR_FLAVOUR_VIMINFO;
+ } else
+ return VAR_FLAVOUR_DEFAULT;
+}
+
+/*
+ * Restore global vars that start with a capital from the viminfo file
+ */
+int read_viminfo_varlist(virp, writing)
+vir_T *virp;
+int writing;
+{
+ char_u *tab;
+ int type = VAR_NUMBER;
+ typval_T tv;
+
+ if (!writing && (find_viminfo_parameter('!') != NULL)) {
+ tab = vim_strchr(virp->vir_line + 1, '\t');
+ if (tab != NULL) {
+ *tab++ = '\0'; /* isolate the variable name */
+ switch (*tab) {
+ case 'S': type = VAR_STRING; break;
+ case 'F': type = VAR_FLOAT; break;
+ case 'D': type = VAR_DICT; break;
+ case 'L': type = VAR_LIST; break;
+ }
+
+ tab = vim_strchr(tab, '\t');
+ if (tab != NULL) {
+ tv.v_type = type;
+ if (type == VAR_STRING || type == VAR_DICT || type == VAR_LIST)
+ tv.vval.v_string = viminfo_readstring(virp,
+ (int)(tab - virp->vir_line + 1), TRUE);
+ else if (type == VAR_FLOAT)
+ (void)string2float(tab + 1, &tv.vval.v_float);
+ else
+ tv.vval.v_number = atol((char *)tab + 1);
+ if (type == VAR_DICT || type == VAR_LIST) {
+ typval_T *etv = eval_expr(tv.vval.v_string, NULL);
+
+ if (etv == NULL)
+ /* Failed to parse back the dict or list, use it as a
+ * string. */
+ tv.v_type = VAR_STRING;
+ else {
+ vim_free(tv.vval.v_string);
+ tv = *etv;
+ vim_free(etv);
+ }
+ }
+
+ set_var(virp->vir_line + 1, &tv, FALSE);
+
+ if (tv.v_type == VAR_STRING)
+ vim_free(tv.vval.v_string);
+ else if (tv.v_type == VAR_DICT || tv.v_type == VAR_LIST)
+ clear_tv(&tv);
+ }
+ }
+ }
+
+ return viminfo_readline(virp);
+}
+
+/*
+ * Write global vars that start with a capital to the viminfo file
+ */
+void write_viminfo_varlist(fp)
+FILE *fp;
+{
+ hashitem_T *hi;
+ dictitem_T *this_var;
+ int todo;
+ char *s;
+ char_u *p;
+ char_u *tofree;
+ char_u numbuf[NUMBUFLEN];
+
+ if (find_viminfo_parameter('!') == NULL)
+ return;
+
+ fputs(_("\n# global variables:\n"), fp);
+
+ todo = (int)globvarht.ht_used;
+ for (hi = globvarht.ht_array; todo > 0; ++hi) {
+ if (!HASHITEM_EMPTY(hi)) {
+ --todo;
+ this_var = HI2DI(hi);
+ if (var_flavour(this_var->di_key) == VAR_FLAVOUR_VIMINFO) {
+ switch (this_var->di_tv.v_type) {
+ case VAR_STRING: s = "STR"; break;
+ case VAR_NUMBER: s = "NUM"; break;
+ case VAR_FLOAT: s = "FLO"; break;
+ case VAR_DICT: s = "DIC"; break;
+ case VAR_LIST: s = "LIS"; break;
+ default: continue;
+ }
+ fprintf(fp, "!%s\t%s\t", this_var->di_key, s);
+ p = echo_string(&this_var->di_tv, &tofree, numbuf, 0);
+ if (p != NULL)
+ viminfo_writestring(fp, p);
+ vim_free(tofree);
+ }
+ }
+ }
+}
+
+int store_session_globals(fd)
+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");
+ if (p == NULL) /* out of memory */
+ break;
+ 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) {
+ vim_free(p);
+ return FAIL;
+ }
+ vim_free(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;
+}
+
+/*
+ * Display script name where an item was last set.
+ * Should only be invoked when 'verbose' is non-zero.
+ */
+void last_set_msg(scriptID)
+scid_T scriptID;
+{
+ char_u *p;
+
+ if (scriptID != 0) {
+ p = home_replace_save(NULL, get_scriptname(scriptID));
+ if (p != NULL) {
+ verbose_enter();
+ MSG_PUTS(_("\n\tLast set from "));
+ MSG_PUTS(p);
+ vim_free(p);
+ verbose_leave();
+ }
+ }
+}
+
+/*
+ * List v:oldfiles in a nice way.
+ */
+void ex_oldfiles(eap)
+exarg_T *eap UNUSED;
+{
+ list_T *l = vimvars[VV_OLDFILES].vv_list;
+ listitem_T *li;
+ int 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((long)++nr);
+ MSG_PUTS(": ");
+ msg_outtrans(get_tv_string(&li->li_tv));
+ msg_putchar('\n');
+ out_flush(); /* output one line at a time */
+ ui_breakcheck();
+ }
+ /* Assume "got_int" was set to truncate the listing. */
+ got_int = FALSE;
+
+ }
+}
+
+
+
+
+
+/*
+ * Adjust a filename, according to a string of modifiers.
+ * *fnamep must be NUL terminated when called. When returning, the length is
+ * determined by *fnamelen.
+ * Returns VALID_ flags or -1 for failure.
+ * When there is an error, *fnamep is set to NULL.
+ */
+int modify_fname(src, usedlen, fnamep, bufp, fnamelen)
+char_u *src; /* string with modifiers */
+int *usedlen; /* characters after src that are used */
+char_u **fnamep; /* file name so far */
+char_u **bufp; /* buffer for allocated file name or NULL */
+int *fnamelen; /* length of fnamep */
+{
+ int valid = 0;
+ char_u *tail;
+ char_u *s, *p, *pbuf;
+ char_u dirname[MAXPATHL];
+ int c;
+ int has_fullname = 0;
+
+repeat:
+ /* ":p" - full path/file_name */
+ if (src[*usedlen] == ':' && src[*usedlen + 1] == 'p') {
+ has_fullname = 1;
+
+ valid |= VALID_PATH;
+ *usedlen += 2;
+
+ /* Expand "~/path" for all systems and "~user/path" for Unix and VMS */
+ if ((*fnamep)[0] == '~'
+#if !defined(UNIX) && !(defined(VMS) && defined(USER_HOME))
+ && ((*fnamep)[1] == '/'
+# ifdef BACKSLASH_IN_FILENAME
+ || (*fnamep)[1] == '\\'
+# endif
+ || (*fnamep)[1] == NUL)
+
+#endif
+ ) {
+ *fnamep = expand_env_save(*fnamep);
+ vim_free(*bufp); /* free any allocated file name */
+ *bufp = *fnamep;
+ if (*fnamep == NULL)
+ return -1;
+ }
+
+ /* 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])))))
+ break;
+ }
+
+ /* FullName_save() is slow, don't use it when not needed. */
+ if (*p != NUL || !vim_isAbsName(*fnamep)) {
+ *fnamep = FullName_save(*fnamep, *p != NUL);
+ vim_free(*bufp); /* free any allocated file name */
+ *bufp = *fnamep;
+ if (*fnamep == NULL)
+ return -1;
+ }
+
+ /* Append a path separator to a directory. */
+ if (mch_isdir(*fnamep)) {
+ /* Make room for one or two extra characters. */
+ *fnamep = vim_strnsave(*fnamep, (int)STRLEN(*fnamep) + 2);
+ vim_free(*bufp); /* free any allocated file name */
+ *bufp = *fnamep;
+ if (*fnamep == NULL)
+ return -1;
+ add_pathsep(*fnamep);
+ }
+ }
+
+ /* ":." - path relative to the current directory */
+ /* ":~" - path relative to the home directory */
+ /* ":8" - shortname path - postponed till after */
+ while (src[*usedlen] == ':'
+ && ((c = src[*usedlen + 1]) == '.' || c == '~' || c == '8')) {
+ *usedlen += 2;
+ if (c == '8') {
+ continue;
+ }
+ pbuf = NULL;
+ /* Need full path first (use expand_env() to remove a "~/") */
+ if (!has_fullname) {
+ if (c == '.' && **fnamep == '~')
+ p = pbuf = expand_env_save(*fnamep);
+ else
+ p = pbuf = FullName_save(*fnamep, FALSE);
+ } else
+ p = *fnamep;
+
+ has_fullname = 0;
+
+ if (p != NULL) {
+ if (c == '.') {
+ mch_dirname(dirname, MAXPATHL);
+ s = shorten_fname(p, dirname);
+ if (s != NULL) {
+ *fnamep = s;
+ if (pbuf != NULL) {
+ vim_free(*bufp); /* free any allocated file name */
+ *bufp = pbuf;
+ pbuf = NULL;
+ }
+ }
+ } else {
+ home_replace(NULL, p, dirname, MAXPATHL, TRUE);
+ /* Only replace it when it starts with '~' */
+ if (*dirname == '~') {
+ s = vim_strsave(dirname);
+ if (s != NULL) {
+ *fnamep = s;
+ vim_free(*bufp);
+ *bufp = s;
+ }
+ }
+ }
+ vim_free(pbuf);
+ }
+ }
+
+ tail = gettail(*fnamep);
+ *fnamelen = (int)STRLEN(*fnamep);
+
+ /* ":h" - head, remove "/file_name", can be repeated */
+ /* Don't remove the first "/" or "c:\" */
+ while (src[*usedlen] == ':' && src[*usedlen + 1] == 'h') {
+ valid |= VALID_HEAD;
+ *usedlen += 2;
+ s = get_past_head(*fnamep);
+ while (tail > s && after_pathsep(s, tail))
+ mb_ptr_back(*fnamep, tail);
+ *fnamelen = (int)(tail - *fnamep);
+ if (*fnamelen == 0) {
+ /* Result is empty. Turn it into "." to make ":cd %:h" work. */
+ p = vim_strsave((char_u *)".");
+ if (p == NULL)
+ return -1;
+ vim_free(*bufp);
+ *bufp = *fnamep = tail = p;
+ *fnamelen = 1;
+ } else {
+ while (tail > s && !after_pathsep(s, tail))
+ mb_ptr_back(*fnamep, tail);
+ }
+ }
+
+ /* ":8" - shortname */
+ if (src[*usedlen] == ':' && src[*usedlen + 1] == '8') {
+ *usedlen += 2;
+ }
+
+
+ /* ":t" - tail, just the basename */
+ if (src[*usedlen] == ':' && src[*usedlen + 1] == 't') {
+ *usedlen += 2;
+ *fnamelen -= (int)(tail - *fnamep);
+ *fnamep = tail;
+ }
+
+ /* ":e" - extension, can be repeated */
+ /* ":r" - root, without extension, can be repeated */
+ while (src[*usedlen] == ':'
+ && (src[*usedlen + 1] == 'e' || src[*usedlen + 1] == 'r')) {
+ /* find a '.' in the tail:
+ * - for second :e: before the current fname
+ * - otherwise: The last '.'
+ */
+ if (src[*usedlen + 1] == 'e' && *fnamep > tail)
+ s = *fnamep - 2;
+ else
+ s = *fnamep + *fnamelen - 1;
+ for (; s > tail; --s)
+ if (s[0] == '.')
+ break;
+ if (src[*usedlen + 1] == 'e') { /* :e */
+ if (s > tail) {
+ *fnamelen += (int)(*fnamep - (s + 1));
+ *fnamep = s + 1;
+ } else if (*fnamep <= tail)
+ *fnamelen = 0;
+ } else { /* :r */
+ if (s > tail) /* remove one extension */
+ *fnamelen = (int)(s - *fnamep);
+ }
+ *usedlen += 2;
+ }
+
+ /* ":s?pat?foo?" - substitute */
+ /* ":gs?pat?foo?" - global substitute */
+ if (src[*usedlen] == ':'
+ && (src[*usedlen + 1] == 's'
+ || (src[*usedlen + 1] == 'g' && src[*usedlen + 2] == 's'))) {
+ char_u *str;
+ char_u *pat;
+ char_u *sub;
+ int sep;
+ char_u *flags;
+ int didit = FALSE;
+
+ flags = (char_u *)"";
+ s = src + *usedlen + 2;
+ if (src[*usedlen + 1] == 'g') {
+ flags = (char_u *)"g";
+ ++s;
+ }
+
+ sep = *s++;
+ if (sep) {
+ /* find end of pattern */
+ p = vim_strchr(s, sep);
+ if (p != NULL) {
+ pat = vim_strnsave(s, (int)(p - s));
+ if (pat != NULL) {
+ s = p + 1;
+ /* find end of substitution */
+ p = vim_strchr(s, sep);
+ if (p != NULL) {
+ sub = vim_strnsave(s, (int)(p - s));
+ str = vim_strnsave(*fnamep, *fnamelen);
+ if (sub != NULL && str != NULL) {
+ *usedlen = (int)(p + 1 - src);
+ s = do_string_sub(str, pat, sub, flags);
+ if (s != NULL) {
+ *fnamep = s;
+ *fnamelen = (int)STRLEN(s);
+ vim_free(*bufp);
+ *bufp = s;
+ didit = TRUE;
+ }
+ }
+ vim_free(sub);
+ vim_free(str);
+ }
+ vim_free(pat);
+ }
+ }
+ /* after using ":s", repeat all the modifiers */
+ if (didit)
+ goto 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(str, pat, sub, flags)
+char_u *str;
+char_u *pat;
+char_u *sub;
+char_u *flags;
+{
+ int sublen;
+ regmatch_T regmatch;
+ int i;
+ int do_all;
+ char_u *tail;
+ garray_T ga;
+ char_u *ret;
+ char_u *save_cpo;
+ char_u *zero_width = NULL;
+
+ /* Make 'cpoptions' empty, so that the 'l' flag doesn't work here */
+ save_cpo = p_cpo;
+ p_cpo = empty_option;
+
+ ga_init2(&ga, 1, 200);
+
+ do_all = (flags[0] == 'g');
+
+ regmatch.rm_ic = p_ic;
+ regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING);
+ if (regmatch.regprog != NULL) {
+ tail = str;
+ while (vim_regexec_nl(&regmatch, str, (colnr_T)(tail - str))) {
+ /* Skip empty match except for first match. */
+ if (regmatch.startp[0] == regmatch.endp[0]) {
+ if (zero_width == regmatch.startp[0]) {
+ /* avoid getting stuck on a match with an empty string */
+ *((char_u *)ga.ga_data + ga.ga_len) = *tail++;
+ ++ga.ga_len;
+ continue;
+ }
+ 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);
+ if (ga_grow(&ga, (int)(STRLEN(tail) + sublen -
+ (regmatch.endp[0] - regmatch.startp[0]))) ==
+ FAIL) {
+ ga_clear(&ga);
+ break;
+ }
+
+ /* copy the text up to where the match is */
+ i = (int)(regmatch.startp[0] - tail);
+ mch_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);
+ ga.ga_len += i + sublen - 1;
+ tail = regmatch.endp[0];
+ if (*tail == NUL)
+ break;
+ if (!do_all)
+ break;
+ }
+
+ if (ga.ga_data != NULL)
+ STRCPY((char *)ga.ga_data + ga.ga_len, tail);
+
+ vim_regfree(regmatch.regprog);
+ }
+
+ ret = vim_strsave(ga.ga_data == NULL ? str : (char_u *)ga.ga_data);
+ ga_clear(&ga);
+ if (p_cpo == empty_option)
+ p_cpo = save_cpo;
+ else
+ /* Darn, evaluating {sub} expression changed the value. */
+ free_string_option(save_cpo);
+
+ return ret;
+}
+
diff --git a/src/ex_cmds.c b/src/ex_cmds.c
new file mode 100644
index 0000000000..d791d777dc
--- /dev/null
+++ b/src/ex_cmds.c
@@ -0,0 +1,5679 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * 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.
+ */
+
+/*
+ * ex_cmds.c: some functions for command line commands
+ */
+
+#include "vim.h"
+#include "version.h"
+
+static int linelen __ARGS((int *has_tab));
+static void do_filter __ARGS((linenr_T line1, linenr_T line2, exarg_T *eap,
+ char_u *cmd, int do_in,
+ int do_out));
+static char_u *viminfo_filename __ARGS((char_u *));
+static void do_viminfo __ARGS((FILE *fp_in, FILE *fp_out, int flags));
+static int viminfo_encoding __ARGS((vir_T *virp));
+static int read_viminfo_up_to_marks __ARGS((vir_T *virp, int forceit,
+ int writing));
+
+static int check_readonly __ARGS((int *forceit, buf_T *buf));
+static void delbuf_msg __ARGS((char_u *name));
+static int
+help_compare __ARGS((const void *s1, const void *s2));
+
+/*
+ * ":ascii" and "ga".
+ */
+void do_ascii(eap)
+exarg_T *eap UNUSED;
+{
+ int c;
+ int cval;
+ char buf1[20];
+ char buf2[20];
+ char_u buf3[7];
+ int cc[MAX_MCO];
+ int ci = 0;
+ int len;
+
+ if (enc_utf8)
+ c = utfc_ptr2char(ml_get_cursor(), cc);
+ else
+ c = gchar_cursor();
+ 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 */
+ 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 > '~'
+ )) {
+ transchar_nonprint(buf3, c);
+ vim_snprintf(buf1, sizeof(buf1), " <%s>", (char *)buf3);
+ } 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 (enc_utf8)
+ c = cc[ci++];
+ else
+ c = 0;
+ }
+
+ /* Repeat for combining characters. */
+ while (has_mbyte && (c >= 0x100 || (enc_utf8 && c >= 0x80))) {
+ len = (int)STRLEN(IObuff);
+ /* This assumes every multi-byte char is printable... */
+ if (len > 0)
+ IObuff[len++] = ' ';
+ IObuff[len++] = '<';
+ if (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)
+ break;
+ if (enc_utf8)
+ c = cc[ci++];
+ else
+ c = 0;
+ }
+
+ msg(IObuff);
+}
+
+/*
+ * ":left", ":center" and ":right": align text.
+ */
+void ex_align(eap)
+exarg_T *eap;
+{
+ pos_T save_curpos;
+ int len;
+ int indent = 0;
+ int new_indent;
+ int has_tab;
+ int width;
+
+ if (curwin->w_p_rl) {
+ /* switch left and right aligning */
+ if (eap->cmdidx == CMD_right)
+ eap->cmdidx = CMD_left;
+ else if (eap->cmdidx == CMD_left)
+ eap->cmdidx = CMD_right;
+ }
+
+ width = atoi((char *)eap->arg);
+ save_curpos = curwin->w_cursor;
+ if (eap->cmdidx == CMD_left) { /* width is used for new indent */
+ if (width >= 0)
+ indent = width;
+ } else {
+ /*
+ * if 'textwidth' set, use it
+ * else if 'wrapmargin' set, use it
+ * if invalid value, use 80
+ */
+ if (width <= 0)
+ width = curbuf->b_p_tw;
+ if (width == 0 && curbuf->b_p_wm > 0)
+ width = W_WIDTH(curwin) - curbuf->b_p_wm;
+ if (width <= 0)
+ width = 80;
+ }
+
+ if (u_save((linenr_T)(eap->line1 - 1), (linenr_T)(eap->line2 + 1)) == FAIL)
+ return;
+
+ for (curwin->w_cursor.lnum = eap->line1;
+ curwin->w_cursor.lnum <= eap->line2; ++curwin->w_cursor.lnum) {
+ if (eap->cmdidx == CMD_left) /* left align */
+ new_indent = indent;
+ else {
+ has_tab = FALSE; /* avoid uninit warnings */
+ len = linelen(eap->cmdidx == CMD_right ? &has_tab
+ : NULL) - get_indent();
+
+ if (len <= 0) /* skip blank lines */
+ continue;
+
+ if (eap->cmdidx == CMD_center)
+ new_indent = (width - len) / 2;
+ else {
+ new_indent = width - len; /* right align */
+
+ /*
+ * Make sure that embedded TABs don't make the text go too far
+ * to the right.
+ */
+ if (has_tab)
+ while (new_indent > 0) {
+ (void)set_indent(new_indent, 0);
+ if (linelen(NULL) <= width) {
+ /*
+ * Now try to move the line as much as possible to
+ * the right. Stop when it moves too far.
+ */
+ do
+ (void)set_indent(++new_indent, 0);
+ while (linelen(NULL) <= width);
+ --new_indent;
+ break;
+ }
+ --new_indent;
+ }
+ }
+ }
+ if (new_indent < 0)
+ new_indent = 0;
+ (void)set_indent(new_indent, 0); /* set indent */
+ }
+ changed_lines(eap->line1, 0, eap->line2 + 1, 0L);
+ curwin->w_cursor = save_curpos;
+ beginline(BL_WHITE | BL_FIX);
+}
+
+/*
+ * Get the length of the current line, excluding trailing white space.
+ */
+static int linelen(has_tab)
+int *has_tab;
+{
+ char_u *line;
+ char_u *first;
+ char_u *last;
+ int save;
+ int len;
+
+ /* find the first non-blank character */
+ line = ml_get_curline();
+ first = skipwhite(line);
+
+ /* find the character after the last non-blank character */
+ for (last = first + STRLEN(first);
+ last > first && vim_iswhite(last[-1]); --last)
+ ;
+ 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);
+ *last = save;
+
+ return len;
+}
+
+/* Buffer for two lines used during sorting. They are allocated to
+ * contain the longest line being sorted. */
+static char_u *sortbuf1;
+static char_u *sortbuf2;
+
+static int sort_ic; /* ignore case */
+static int sort_nr; /* sort on number */
+static int sort_rx; /* sort on regex instead of skipping it */
+
+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 */
+} sorti_T;
+
+static int
+sort_compare __ARGS((const void *s1, const void *s2));
+
+static int sort_compare(s1, s2)
+const void *s1;
+const void *s2;
+{
+ sorti_T l1 = *(sorti_T *)s1;
+ sorti_T l2 = *(sorti_T *)s2;
+ int result = 0;
+
+ /* If the user interrupts, there's no way to stop qsort() immediately, but
+ * if we return 0 every time, qsort will assume it's done sorting and
+ * exit. */
+ if (sort_abort)
+ return 0;
+ fast_breakcheck();
+ if (got_int)
+ sort_abort = TRUE;
+
+ /* When sorting numbers "start_col_nr" is the number, not the column
+ * number. */
+ if (sort_nr)
+ result = l1.start_col_nr == l2.start_col_nr ? 0
+ : l1.start_col_nr > l2.start_col_nr ? 1 : -1;
+ else {
+ /* 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.start_col_nr,
+ l1.end_col_nr - l1.start_col_nr + 1);
+ sortbuf1[l1.end_col_nr - l1.start_col_nr] = 0;
+ STRNCPY(sortbuf2, ml_get(l2.lnum) + l2.start_col_nr,
+ l2.end_col_nr - l2.start_col_nr + 1);
+ sortbuf2[l2.end_col_nr - l2.start_col_nr] = 0;
+
+ result = sort_ic ? STRICMP(sortbuf1, sortbuf2)
+ : STRCMP(sortbuf1, sortbuf2);
+ }
+
+ /* If two lines have the same value, preserve the original line order. */
+ if (result == 0)
+ return (int)(l1.lnum - l2.lnum);
+ return result;
+}
+
+/*
+ * ":sort".
+ */
+void ex_sort(eap)
+exarg_T *eap;
+{
+ regmatch_T regmatch;
+ int len;
+ linenr_T lnum;
+ long maxlen = 0;
+ sorti_T *nrs;
+ size_t count = (size_t)(eap->line2 - eap->line1 + 1);
+ size_t i;
+ char_u *p;
+ char_u *s;
+ char_u *s2;
+ char_u c; /* temporary character storage */
+ int unique = FALSE;
+ long deleted;
+ colnr_T start_col;
+ colnr_T end_col;
+ int sort_oct; /* sort on octal number */
+ int sort_hex; /* sort on hex number */
+
+ /* Sorting one line is really quick! */
+ if (count <= 1)
+ return;
+
+ if (u_save((linenr_T)(eap->line1 - 1), (linenr_T)(eap->line2 + 1)) == FAIL)
+ return;
+ sortbuf1 = NULL;
+ sortbuf2 = NULL;
+ regmatch.regprog = NULL;
+ nrs = (sorti_T *)lalloc((long_u)(count * sizeof(sorti_T)), TRUE);
+ if (nrs == NULL)
+ goto sortend;
+
+ sort_abort = sort_ic = sort_rx = sort_nr = sort_oct = sort_hex = 0;
+
+ for (p = eap->arg; *p != NUL; ++p) {
+ if (vim_iswhite(*p))
+ ;
+ else if (*p == 'i')
+ sort_ic = TRUE;
+ else if (*p == 'r')
+ sort_rx = TRUE;
+ else if (*p == 'n')
+ sort_nr = 2;
+ else if (*p == 'o')
+ sort_oct = 2;
+ else if (*p == 'x')
+ sort_hex = 2;
+ else if (*p == 'u')
+ unique = TRUE;
+ else if (*p == '"') /* comment start */
+ break;
+ else if (check_nextcmd(p) != NULL) {
+ eap->nextcmd = check_nextcmd(p);
+ break;
+ } else if (!ASCII_ISALPHA(*p) && regmatch.regprog == NULL) {
+ s = skip_regexp(p + 1, *p, TRUE, NULL);
+ if (*s != *p) {
+ EMSG(_(e_invalpat));
+ goto sortend;
+ }
+ *s = NUL;
+ /* Use last search pattern if sort pattern is empty. */
+ if (s == p + 1) {
+ if (last_search_pat() == NULL) {
+ EMSG(_(e_noprevre));
+ goto sortend;
+ }
+ regmatch.regprog = vim_regcomp(last_search_pat(), RE_MAGIC);
+ } else
+ regmatch.regprog = vim_regcomp(p + 1, RE_MAGIC);
+ if (regmatch.regprog == NULL)
+ goto sortend;
+ p = s; /* continue after the regexp */
+ regmatch.rm_ic = p_ic;
+ } else {
+ EMSG2(_(e_invarg2), p);
+ goto sortend;
+ }
+ }
+
+ /* Can only have one of 'n', 'o' and 'x'. */
+ if (sort_nr + sort_oct + sort_hex > 2) {
+ EMSG(_(e_invarg));
+ goto sortend;
+ }
+
+ /* From here on "sort_nr" is used as a flag for any number sorting. */
+ sort_nr += sort_oct + sort_hex;
+
+ /*
+ * Make an array with all line numbers. This avoids having to copy all
+ * the lines into allocated memory.
+ * When sorting on strings "start_col_nr" is the offset in the line, for
+ * numbers sorting it's the number to sort on. This means the pattern
+ * matching and number conversion only has to be done once per line.
+ * Also get the longest line length for allocating "sortbuf".
+ */
+ for (lnum = eap->line1; lnum <= eap->line2; ++lnum) {
+ s = ml_get(lnum);
+ len = (int)STRLEN(s);
+ if (maxlen < len)
+ maxlen = len;
+
+ start_col = 0;
+ end_col = len;
+ if (regmatch.regprog != NULL && vim_regexec(&regmatch, s, 0)) {
+ if (sort_rx) {
+ start_col = (colnr_T)(regmatch.startp[0] - s);
+ end_col = (colnr_T)(regmatch.endp[0] - s);
+ } else
+ start_col = (colnr_T)(regmatch.endp[0] - s);
+ } else if (regmatch.regprog != NULL)
+ end_col = 0;
+
+ if (sort_nr) {
+ /* Make sure vim_str2nr doesn't read any digits past the end
+ * of the match, by temporarily terminating the string there */
+ s2 = s + end_col;
+ c = *s2;
+ *s2 = NUL;
+ /* Sorting on number: Store the number itself. */
+ p = s + start_col;
+ if (sort_hex)
+ s = skiptohex(p);
+ else
+ s = skiptodigit(p);
+ if (s > p && s[-1] == '-')
+ --s; /* include preceding negative sign */
+ if (*s == NUL)
+ /* empty line should sort before any number */
+ nrs[lnum - eap->line1].start_col_nr = -MAXLNUM;
+ else
+ vim_str2nr(s, NULL, NULL, sort_oct, sort_hex,
+ &nrs[lnum - eap->line1].start_col_nr, NULL);
+ *s2 = c;
+ } else {
+ /* Store the column to sort at. */
+ nrs[lnum - eap->line1].start_col_nr = start_col;
+ nrs[lnum - eap->line1].end_col_nr = end_col;
+ }
+
+ nrs[lnum - eap->line1].lnum = lnum;
+
+ if (regmatch.regprog != NULL)
+ fast_breakcheck();
+ if (got_int)
+ goto sortend;
+ }
+
+ /* Allocate a buffer that can hold the longest line. */
+ sortbuf1 = alloc((unsigned)maxlen + 1);
+ if (sortbuf1 == NULL)
+ goto sortend;
+ sortbuf2 = alloc((unsigned)maxlen + 1);
+ if (sortbuf2 == NULL)
+ goto sortend;
+
+ /* Sort the array of line numbers. Note: can't be interrupted! */
+ qsort((void *)nrs, count, sizeof(sorti_T), sort_compare);
+
+ if (sort_abort)
+ goto sortend;
+
+ /* 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);
+ if (!unique || i == 0
+ || (sort_ic ? STRICMP(s, sortbuf1) : STRCMP(s, sortbuf1)) != 0) {
+ if (ml_append(lnum++, s, (colnr_T)0, FALSE) == FAIL)
+ break;
+ if (unique)
+ STRCPY(sortbuf1, s);
+ }
+ fast_breakcheck();
+ if (got_int)
+ goto sortend;
+ }
+
+ /* delete the original lines if appending worked */
+ if (i == count)
+ for (i = 0; i < count; ++i)
+ ml_delete(eap->line1, FALSE);
+ else
+ count = 0;
+
+ /* 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);
+ else if (deleted < 0)
+ mark_adjust(eap->line2, MAXLNUM, -deleted, 0L);
+ changed_lines(eap->line1, 0, eap->line2 + 1, -deleted);
+
+ curwin->w_cursor.lnum = eap->line1;
+ beginline(BL_WHITE | BL_FIX);
+
+sortend:
+ vim_free(nrs);
+ vim_free(sortbuf1);
+ vim_free(sortbuf2);
+ vim_regfree(regmatch.regprog);
+ if (got_int)
+ EMSG(_(e_interr));
+}
+
+/*
+ * ":retab".
+ */
+void ex_retab(eap)
+exarg_T *eap;
+{
+ linenr_T lnum;
+ int got_tab = FALSE;
+ long num_spaces = 0;
+ long num_tabs;
+ long len;
+ long col;
+ long vcol;
+ long start_col = 0; /* For start of white-space string */
+ long start_vcol = 0; /* For start of white-space string */
+ int temp;
+ long old_len;
+ char_u *ptr;
+ char_u *new_line = (char_u *)1; /* init to non-NULL */
+ int did_undo; /* called u_save for current line */
+ int new_ts;
+ int save_list;
+ linenr_T first_line = 0; /* first changed line */
+ linenr_T last_line = 0; /* last changed line */
+
+ save_list = curwin->w_p_list;
+ curwin->w_p_list = 0; /* don't want list mode here */
+
+ new_ts = getdigits(&(eap->arg));
+ if (new_ts < 0) {
+ EMSG(_(e_positive));
+ return;
+ }
+ if (new_ts == 0)
+ new_ts = curbuf->b_p_ts;
+ for (lnum = eap->line1; !got_int && lnum <= eap->line2; ++lnum) {
+ ptr = ml_get(lnum);
+ col = 0;
+ vcol = 0;
+ did_undo = FALSE;
+ for (;; ) {
+ if (vim_iswhite(ptr[col])) {
+ if (!got_tab && num_spaces == 0) {
+ /* First consecutive white-space */
+ start_vcol = vcol;
+ start_col = col;
+ }
+ if (ptr[col] == ' ')
+ num_spaces++;
+ else
+ got_tab = TRUE;
+ } else {
+ if (got_tab || (eap->forceit && num_spaces > 1)) {
+ /* Retabulate this string of white-space */
+
+ /* len is virtual length of white string */
+ len = num_spaces = vcol - start_vcol;
+ num_tabs = 0;
+ if (!curbuf->b_p_et) {
+ temp = new_ts - (start_vcol % new_ts);
+ if (num_spaces >= temp) {
+ num_spaces -= temp;
+ num_tabs++;
+ }
+ num_tabs += num_spaces / new_ts;
+ num_spaces -= (num_spaces / new_ts) * new_ts;
+ }
+ if (curbuf->b_p_et || got_tab ||
+ (num_spaces + num_tabs < len)) {
+ if (did_undo == FALSE) {
+ did_undo = TRUE;
+ if (u_save((linenr_T)(lnum - 1),
+ (linenr_T)(lnum + 1)) == FAIL) {
+ new_line = NULL; /* flag out-of-memory */
+ break;
+ }
+ }
+
+ /* len is actual number of white characters used */
+ len = num_spaces + num_tabs;
+ old_len = (long)STRLEN(ptr);
+ new_line = lalloc(old_len - col + start_col + len + 1,
+ TRUE);
+ if (new_line == NULL)
+ break;
+ if (start_col > 0)
+ mch_memmove(new_line, ptr, (size_t)start_col);
+ mch_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++)
+ ptr[col] = (col < num_tabs) ? '\t' : ' ';
+ ml_replace(lnum, new_line, FALSE);
+ if (first_line == 0)
+ first_line = lnum;
+ last_line = lnum;
+ ptr = new_line;
+ col = start_col + len;
+ }
+ }
+ got_tab = FALSE;
+ num_spaces = 0;
+ }
+ if (ptr[col] == NUL)
+ break;
+ vcol += chartabsize(ptr + col, (colnr_T)vcol);
+ if (has_mbyte)
+ col += (*mb_ptr2len)(ptr + col);
+ else
+ ++col;
+ }
+ if (new_line == NULL) /* out of memory */
+ break;
+ line_breakcheck();
+ }
+ if (got_int)
+ EMSG(_(e_interr));
+
+ 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);
+
+ curwin->w_p_list = save_list; /* restore 'list' */
+
+ curbuf->b_p_ts = new_ts;
+ coladvance(curwin->w_curswant);
+
+ u_clearline();
+}
+
+/*
+ * :move command - move lines line1-line2 to line dest
+ *
+ * return FAIL for failure, OK otherwise
+ */
+int do_move(line1, line2, dest)
+linenr_T line1;
+linenr_T line2;
+linenr_T dest;
+{
+ char_u *str;
+ linenr_T l;
+ linenr_T extra; /* Num lines added before line1 */
+ linenr_T num_lines; /* Num lines moved */
+ linenr_T last_line; /* Last line in file after adding new text */
+
+ if (dest >= line1 && dest < line2) {
+ EMSG(_("E134: Move lines into themselves"));
+ return FAIL;
+ }
+
+ num_lines = line2 - line1 + 1;
+
+ /*
+ * First we copy the old text to its new location -- webb
+ * Also copy the flag that ":global" command uses.
+ */
+ if (u_save(dest, dest + 1) == FAIL)
+ return FAIL;
+ for (extra = 0, l = line1; l <= line2; l++) {
+ str = vim_strsave(ml_get(l + extra));
+ if (str != NULL) {
+ ml_append(dest + l - line1, str, (colnr_T)0, FALSE);
+ vim_free(str);
+ if (dest < line1)
+ extra++;
+ }
+ }
+
+ /*
+ * Now we must be careful adjusting our marks so that we don't overlap our
+ * mark_adjust() calls.
+ *
+ * We adjust the marks within the old text so that they refer to the
+ * last lines of the file (temporarily), because we know no other marks
+ * will be set there since these line numbers did not exist until we added
+ * our new lines.
+ *
+ * Then we adjust the marks on lines between the old and new text positions
+ * (either forwards or backwards).
+ *
+ * And Finally we adjust the marks we put at the end of the file back to
+ * 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);
+ if (dest >= line2) {
+ mark_adjust(line2 + 1, dest, -num_lines, 0L);
+ 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);
+ 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);
+
+ /*
+ * Now we delete the original text -- webb
+ */
+ if (u_save(line1 + extra - 1, line2 + extra + 1) == FAIL)
+ return FAIL;
+
+ for (l = line1; l <= line2; l++)
+ ml_delete(line1 + extra, TRUE);
+
+ if (!global_busy && num_lines > p_report) {
+ if (num_lines == 1)
+ MSG(_("1 line moved"));
+ else
+ smsg((char_u *)_("%ld lines moved"), num_lines);
+ }
+
+ /*
+ * Leave the cursor on the last of the moved lines.
+ */
+ if (dest >= line1)
+ curwin->w_cursor.lnum = dest;
+ else
+ curwin->w_cursor.lnum = dest + (line2 - line1) + 1;
+
+ if (line1 < dest) {
+ dest += num_lines + 1;
+ last_line = curbuf->b_ml.ml_line_count;
+ if (dest > last_line + 1)
+ dest = last_line + 1;
+ changed_lines(line1, 0, dest, 0L);
+ } else
+ changed_lines(dest + 1, 0, line1 + num_lines, 0L);
+
+ return OK;
+}
+
+/*
+ * ":copy"
+ */
+void ex_copy(line1, line2, n)
+linenr_T line1;
+linenr_T line2;
+linenr_T n;
+{
+ linenr_T count;
+ char_u *p;
+
+ count = line2 - line1 + 1;
+ curbuf->b_op_start.lnum = n + 1;
+ curbuf->b_op_end.lnum = n + count;
+ curbuf->b_op_start.col = curbuf->b_op_end.col = 0;
+
+ /*
+ * there are three situations:
+ * 1. destination is above line1
+ * 2. destination is between line1 and line2
+ * 3. destination is below line2
+ *
+ * n = destination (when starting)
+ * curwin->w_cursor.lnum = destination (while copying)
+ * line1 = start of source (while copying)
+ * line2 = end of source (while copying)
+ */
+ if (u_save(n, n + 1) == FAIL)
+ return;
+
+ curwin->w_cursor.lnum = n;
+ while (line1 <= line2) {
+ /* need to use vim_strsave() because the line will be unlocked within
+ * ml_append() */
+ p = vim_strsave(ml_get(line1));
+ if (p != NULL) {
+ ml_append(curwin->w_cursor.lnum, p, (colnr_T)0, FALSE);
+ vim_free(p);
+ }
+ /* situation 2: skip already copied lines */
+ if (line1 == n)
+ line1 = curwin->w_cursor.lnum;
+ ++line1;
+ if (curwin->w_cursor.lnum < line1)
+ ++line1;
+ if (curwin->w_cursor.lnum < line2)
+ ++line2;
+ ++curwin->w_cursor.lnum;
+ }
+
+ appended_lines_mark(n, count);
+
+ msgmore((long)count);
+}
+
+static char_u *prevcmd = NULL; /* the previous command */
+
+#if defined(EXITFREE) || defined(PROTO)
+void free_prev_shellcmd() {
+ vim_free(prevcmd);
+}
+
+#endif
+
+/*
+ * Handle the ":!cmd" command. Also for ":r !cmd" and ":w !cmd"
+ * Bangs in the argument are replaced with the previously entered command.
+ * Remember the argument.
+ */
+void do_bang(addr_count, eap, forceit, do_in, do_out)
+int addr_count;
+exarg_T *eap;
+int forceit;
+int do_in, do_out;
+{
+ char_u *arg = eap->arg; /* command */
+ linenr_T line1 = eap->line1; /* start of range */
+ linenr_T line2 = eap->line2; /* end of range */
+ char_u *newcmd = NULL; /* the new command */
+ int free_newcmd = FALSE; /* need to free() newcmd */
+ int ins_prevcmd;
+ char_u *t;
+ char_u *p;
+ char_u *trailarg;
+ int len;
+ int scroll_save = msg_scroll;
+
+ /*
+ * Disallow shell commands for "rvim".
+ * Disallow shell commands from .exrc and .vimrc in current directory for
+ * security reasons.
+ */
+ if (check_restricted() || check_secure())
+ return;
+
+ if (addr_count == 0) { /* :! */
+ msg_scroll = FALSE; /* don't scroll here */
+ autowrite_all();
+ msg_scroll = scroll_save;
+ }
+
+ /*
+ * Try to find an embedded bang, like in :!<cmd> ! [args]
+ * (:!! is indicated by the 'forceit' variable)
+ */
+ ins_prevcmd = forceit;
+ trailarg = arg;
+ do {
+ len = (int)STRLEN(trailarg) + 1;
+ if (newcmd != NULL)
+ len += (int)STRLEN(newcmd);
+ if (ins_prevcmd) {
+ if (prevcmd == NULL) {
+ EMSG(_(e_noprev));
+ vim_free(newcmd);
+ return;
+ }
+ len += (int)STRLEN(prevcmd);
+ }
+ if ((t = alloc((unsigned)len)) == NULL) {
+ vim_free(newcmd);
+ return;
+ }
+ *t = NUL;
+ if (newcmd != NULL)
+ STRCAT(t, newcmd);
+ if (ins_prevcmd)
+ STRCAT(t, prevcmd);
+ p = t + STRLEN(t);
+ STRCAT(t, trailarg);
+ vim_free(newcmd);
+ newcmd = t;
+
+ /*
+ * Scan the rest of the argument for '!', which is replaced by the
+ * previous command. "\!" is replaced by "!" (this is vi compatible).
+ */
+ trailarg = NULL;
+ while (*p) {
+ if (*p == '!') {
+ if (p > newcmd && p[-1] == '\\')
+ STRMOVE(p - 1, p);
+ else {
+ trailarg = p;
+ *trailarg++ = NUL;
+ ins_prevcmd = TRUE;
+ break;
+ }
+ }
+ ++p;
+ }
+ } while (trailarg != NULL);
+
+ vim_free(prevcmd);
+ prevcmd = newcmd;
+
+ if (bangredo) { /* put cmd in redo buffer for ! command */
+ AppendToRedobuffLit(prevcmd, -1);
+ AppendToRedobuff((char_u *)"\n");
+ bangredo = FALSE;
+ }
+ /*
+ * Add quotes around the command, for shells that need them.
+ */
+ if (*p_shq != NUL) {
+ newcmd = alloc((unsigned)(STRLEN(prevcmd) + 2 * STRLEN(p_shq) + 1));
+ if (newcmd == NULL)
+ return;
+ STRCPY(newcmd, p_shq);
+ STRCAT(newcmd, prevcmd);
+ STRCAT(newcmd, p_shq);
+ free_newcmd = TRUE;
+ }
+ if (addr_count == 0) { /* :! */
+ /* echo the command */
+ msg_start();
+ msg_putchar(':');
+ msg_putchar('!');
+ msg_outtrans(newcmd);
+ msg_clr_eos();
+ windgoto(msg_row, msg_col);
+
+ do_shell(newcmd, 0);
+ } else { /* :range! */
+ /* Careful: This may recursively call do_bang() again! (because of
+ * autocommands) */
+ do_filter(line1, line2, eap, newcmd, do_in, do_out);
+ apply_autocmds(EVENT_SHELLFILTERPOST, NULL, NULL, FALSE, curbuf);
+ }
+ if (free_newcmd)
+ vim_free(newcmd);
+}
+
+/*
+ * do_filter: filter lines through a command given by the user
+ *
+ * We mostly use temp files and the call_shell() routine here. This would
+ * normally be done using pipes on a UNIX machine, but this is more portable
+ * to non-unix machines. The call_shell() routine needs to be able
+ * to deal with redirection somehow, and should handle things like looking
+ * at the PATH env. variable, and adding reasonable extensions to the
+ * command name given by the user. All reasonable versions of call_shell()
+ * do this.
+ * Alternatively, if on Unix and redirecting input or output, but not both,
+ * and the 'shelltemp' option isn't set, use pipes.
+ * We use input redirection if do_in is TRUE.
+ * We use output redirection if do_out is TRUE.
+ */
+static void do_filter(line1, line2, eap, cmd, do_in, do_out)
+linenr_T line1, line2;
+exarg_T *eap; /* for forced 'ff' and 'fenc' */
+char_u *cmd;
+int do_in, do_out;
+{
+ char_u *itmp = NULL;
+ char_u *otmp = NULL;
+ linenr_T linecount;
+ linenr_T read_linecount;
+ pos_T cursor_save;
+ char_u *cmd_buf;
+ buf_T *old_curbuf = curbuf;
+ int shell_flags = 0;
+
+ if (*cmd == NUL) /* no filter command */
+ return;
+
+
+ cursor_save = curwin->w_cursor;
+ linecount = line2 - line1 + 1;
+ curwin->w_cursor.lnum = line1;
+ curwin->w_cursor.col = 0;
+ changed_line_abv_curs();
+ invalidate_botline();
+
+ /*
+ * When using temp files:
+ * 1. * Form temp file names
+ * 2. * Write the lines to a temp file
+ * 3. Run the filter command on the temp file
+ * 4. * Read the output of the command into the buffer
+ * 5. * Delete the original lines to be filtered
+ * 6. * Remove the temp files
+ *
+ * When writing the input with a pipe or when catching the output with a
+ * pipe only need to do 3.
+ */
+
+ if (do_out)
+ shell_flags |= SHELL_DOOUT;
+
+ if ((do_in && (itmp = vim_tempname('i')) == NULL)
+ || (do_out && (otmp = vim_tempname('o')) == NULL)) {
+ EMSG(_(e_notmp));
+ goto filterend;
+ }
+
+ /*
+ * The writing and reading of temp files will not be shown.
+ * Vi also doesn't do this and the messages are not very informative.
+ */
+ ++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 */
+ goto filterend;
+ }
+ if (curbuf != old_curbuf)
+ goto filterend;
+
+ if (!do_out)
+ msg_putchar('\n');
+
+ /* Create the shell command in allocated memory. */
+ cmd_buf = make_filter_cmd(cmd, itmp, otmp);
+ if (cmd_buf == NULL)
+ goto filterend;
+
+ windgoto((int)Rows - 1, 0);
+ cursor_on();
+
+ /*
+ * 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) {
+ vim_free(cmd_buf);
+ goto error;
+ }
+ redraw_curbuf_later(VALID);
+ }
+ 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 SHELL_DOOUT flag when the output is being redirected.
+ */
+ if (call_shell(cmd_buf, SHELL_FILTER | SHELL_COOKED | shell_flags)) {
+ redraw_later_clear();
+ wait_return(FALSE);
+ }
+ vim_free(cmd_buf);
+
+ did_check_timestamps = FALSE;
+ need_check_timestamps = TRUE;
+
+ /* When interrupting the shell command, it may still have produced some
+ * useful output. Reset got_int here, so that readfile() won't cancel
+ * reading. */
+ ui_breakcheck();
+ got_int = FALSE;
+
+ if (do_out) {
+ if (otmp != NULL) {
+ if (readfile(otmp, NULL, line2, (linenr_T)0, (linenr_T)MAXLNUM,
+ eap, READ_FILTER) == FAIL) {
+ if (!aborting()) {
+ msg_putchar('\n');
+ EMSG2(_(e_notread), otmp);
+ }
+ goto error;
+ }
+ if (curbuf != old_curbuf)
+ goto filterend;
+ }
+
+ read_linecount = curbuf->b_ml.ml_line_count - read_linecount;
+
+ if (shell_flags & SHELL_READ) {
+ curbuf->b_op_start.lnum = line2 + 1;
+ curbuf->b_op_end.lnum = curwin->w_cursor.lnum;
+ appended_lines_mark(line2, read_linecount);
+ }
+
+ 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);
+ }
+ }
+
+ /*
+ * Put cursor on first filtered line for ":range!cmd".
+ * Adjust '[ and '] (set by buf_write()).
+ */
+ curwin->w_cursor.lnum = line1;
+ del_lines(linecount, TRUE);
+ curbuf->b_op_start.lnum -= linecount; /* adjust '[ */
+ curbuf->b_op_end.lnum -= linecount; /* adjust '] */
+ write_lnum_adjust(-linecount); /* adjust last line
+ for next write */
+ foldUpdate(curwin, curbuf->b_op_start.lnum, curbuf->b_op_end.lnum);
+ } else {
+ /*
+ * Put cursor on last new line for ":r !cmd".
+ */
+ linecount = curbuf->b_op_end.lnum - curbuf->b_op_start.lnum + 1;
+ curwin->w_cursor.lnum = curbuf->b_op_end.lnum;
+ }
+
+ beginline(BL_WHITE | BL_FIX); /* cursor on first non-blank */
+ --no_wait_return;
+
+ if (linecount > p_report) {
+ if (do_in) {
+ vim_snprintf((char *)msg_buf, sizeof(msg_buf),
+ _("%ld lines filtered"), (long)linecount);
+ if (msg(msg_buf) && !msg_scroll)
+ /* save message to display it after redraw */
+ set_keep_msg(msg_buf, 0);
+ } else
+ msgmore((long)linecount);
+ }
+ } else {
+error:
+ /* put cursor back in same position for ":w !cmd" */
+ curwin->w_cursor = cursor_save;
+ --no_wait_return;
+ wait_return(FALSE);
+ }
+
+filterend:
+
+ if (curbuf != old_curbuf) {
+ --no_wait_return;
+ EMSG(_("E135: *Filter* Autocommands must not change current buffer"));
+ }
+ if (itmp != NULL)
+ mch_remove(itmp);
+ if (otmp != NULL)
+ mch_remove(otmp);
+ vim_free(itmp);
+ vim_free(otmp);
+}
+
+/*
+ * Call a shell to execute a command.
+ * When "cmd" is NULL start an interactive shell.
+ */
+void do_shell(cmd, flags)
+char_u *cmd;
+int flags; /* may be SHELL_DOOUT when output is redirected */
+{
+ buf_T *buf;
+ int save_nwr;
+
+ /*
+ * Disallow shell commands for "rvim".
+ * Disallow shell commands from .exrc and .vimrc in current directory for
+ * security reasons.
+ */
+ if (check_restricted() || check_secure()) {
+ msg_end();
+ return;
+ }
+
+
+ /*
+ * For autocommands we want to get the output on the current screen, to
+ * avoid having to type return below.
+ */
+ msg_putchar('\r'); /* put cursor at start of line */
+ if (!autocmd_busy) {
+ stoptermcap();
+ }
+ msg_putchar('\n'); /* may shift screen one line up */
+
+ /* warning message before calling the shell */
+ if (p_warn
+ && !autocmd_busy
+ && msg_silent == 0)
+ for (buf = firstbuf; buf; buf = buf->b_next)
+ if (bufIsChanged(buf)) {
+ MSG_PUTS(_("[No write since last change]\n"));
+ break;
+ }
+
+ /* This windgoto is required for when the '\n' resulted in a "delete line
+ * 1" command to the terminal. */
+ if (!swapping_screen())
+ windgoto(msg_row, msg_col);
+ cursor_on();
+ (void)call_shell(cmd, SHELL_COOKED | flags);
+ did_check_timestamps = FALSE;
+ need_check_timestamps = TRUE;
+
+ /*
+ * put the message cursor at the end of the screen, avoids wait_return()
+ * to overwrite the text that the external command showed
+ */
+ if (!swapping_screen()) {
+ 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;
+ if (swapping_screen())
+ no_wait_return = FALSE;
+ wait_return(msg_silent == 0);
+ no_wait_return = save_nwr;
+ }
+
+ starttermcap(); /* start termcap if not done by wait_return() */
+
+ /*
+ * In an Amiga window redrawing is caused by asking the window size.
+ * If we got an interrupt this will not work. The chance that the
+ * window size is wrong is very small, but we need to redraw the
+ * screen. Don't do this if ':' hit in wait_return(). THIS IS UGLY
+ * but it saves an extra redraw.
+ */
+ }
+
+ /* display any error messages now */
+ display_errors();
+
+ apply_autocmds(EVENT_SHELLCMDPOST, NULL, NULL, FALSE, curbuf);
+}
+
+/*
+ * Create a shell command from a command string, input redirection file and
+ * output redirection file.
+ * Returns an allocated string with the shell command, or NULL for failure.
+ */
+char_u * make_filter_cmd(cmd, itmp, otmp)
+char_u *cmd; /* command */
+char_u *itmp; /* NULL or name of input file */
+char_u *otmp; /* NULL or name of output file */
+{
+ char_u *buf;
+ long_u len;
+
+ len = (long_u)STRLEN(cmd) + 3; /* "()" + NUL */
+ if (itmp != NULL)
+ len += (long_u)STRLEN(itmp) + 9; /* " { < " + " } " */
+ if (otmp != NULL)
+ len += (long_u)STRLEN(otmp) + (long_u)STRLEN(p_srr) + 2; /* " " */
+ buf = lalloc(len, TRUE);
+ if (buf == NULL)
+ return NULL;
+
+#if (defined(UNIX) && !defined(ARCHIE)) || defined(OS2)
+ /*
+ * Put braces around the command (for concatenated commands) when
+ * redirecting input and/or output.
+ */
+ if (itmp != NULL || otmp != NULL)
+ vim_snprintf((char *)buf, len, "(%s)", (char *)cmd);
+ else
+ STRCPY(buf, cmd);
+ if (itmp != NULL) {
+ STRCAT(buf, " < ");
+ STRCAT(buf, itmp);
+ }
+#else
+ /*
+ * for shells that don't understand braces around commands, at least allow
+ * the use of commands in a pipe.
+ */
+ STRCPY(buf, cmd);
+ 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 = vim_strchr(buf, '|');
+ if (p != NULL)
+ *p = NUL;
+ }
+ STRCAT(buf, " <"); /* " < " causes problems on Amiga */
+ STRCAT(buf, itmp);
+ if (*p_shq == NUL) {
+ p = vim_strchr(cmd, '|');
+ if (p != NULL) {
+ STRCAT(buf, " "); /* insert a space before the '|' for DOS */
+ STRCAT(buf, p);
+ }
+ }
+ }
+#endif
+ if (otmp != NULL)
+ append_redir(buf, (int)len, p_srr, otmp);
+
+ return buf;
+}
+
+/*
+ * Append output redirection for file "fname" to the end of string buffer
+ * "buf[buflen]"
+ * Works with the 'shellredir' and 'shellpipe' options.
+ * The caller should make sure that there is enough room:
+ * STRLEN(opt) + STRLEN(fname) + 3
+ */
+void append_redir(buf, buflen, opt, fname)
+char_u *buf;
+int buflen;
+char_u *opt;
+char_u *fname;
+{
+ char_u *p;
+ char_u *end;
+
+ end = buf + STRLEN(buf);
+ /* find "%s" */
+ for (p = opt; (p = vim_strchr(p, '%')) != NULL; ++p) {
+ if (p[1] == 's') /* found %s */
+ break;
+ if (p[1] == '%') /* skip %% */
+ ++p;
+ }
+ if (p != NULL) {
+ *end = ' '; /* not really needed? Not with sh, ksh or bash */
+ vim_snprintf((char *)end + 1, (size_t)(buflen - (end + 1 - buf)),
+ (char *)opt, (char *)fname);
+ } else
+ vim_snprintf((char *)end, (size_t)(buflen - (end - buf)),
+ " %s %s",
+ (char *)opt, (char *)fname);
+}
+
+
+static int no_viminfo __ARGS((void));
+static int viminfo_errcnt;
+
+static int no_viminfo() {
+ /* "vim -i NONE" does not read or write a viminfo file */
+ return use_viminfo != NULL && STRCMP(use_viminfo, "NONE") == 0;
+}
+
+/*
+ * Report an error for reading a viminfo file.
+ * Count the number of errors. When there are more than 10, return TRUE.
+ */
+int viminfo_error(errnum, message, line)
+char *errnum;
+char *message;
+char_u *line;
+{
+ vim_snprintf((char *)IObuff, IOSIZE, _("%sviminfo: %s in line: "),
+ errnum, message);
+ STRNCAT(IObuff, line, IOSIZE - STRLEN(IObuff) - 1);
+ if (IObuff[STRLEN(IObuff) - 1] == '\n')
+ IObuff[STRLEN(IObuff) - 1] = NUL;
+ emsg(IObuff);
+ if (++viminfo_errcnt >= 10) {
+ EMSG(_("E136: viminfo: Too many errors, skipping rest of file"));
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*
+ * read_viminfo() -- Read the viminfo file. Registers etc. which are already
+ * set are not over-written unless "flags" includes VIF_FORCEIT. -- webb
+ */
+int read_viminfo(file, flags)
+char_u *file; /* file name or NULL to use default name */
+int flags; /* VIF_WANT_INFO et al. */
+{
+ FILE *fp;
+ char_u *fname;
+
+ if (no_viminfo())
+ return FAIL;
+
+ fname = viminfo_filename(file); /* get file name in allocated buffer */
+ if (fname == NULL)
+ return FAIL;
+ fp = mch_fopen((char *)fname, READBIN);
+
+ if (p_verbose > 0) {
+ verbose_enter();
+ smsg((char_u *)_("Reading viminfo file \"%s\"%s%s%s"),
+ fname,
+ (flags & VIF_WANT_INFO) ? _(" info") : "",
+ (flags & VIF_WANT_MARKS) ? _(" marks") : "",
+ (flags & VIF_GET_OLDFILES) ? _(" oldfiles") : "",
+ fp == NULL ? _(" FAILED") : "");
+ verbose_leave();
+ }
+
+ vim_free(fname);
+ if (fp == NULL)
+ return FAIL;
+
+ viminfo_errcnt = 0;
+ do_viminfo(fp, NULL, flags);
+
+ fclose(fp);
+ return OK;
+}
+
+/*
+ * Write the viminfo file. The old one is read in first so that effectively a
+ * merge of current info and old info is done. This allows multiple vims to
+ * run simultaneously, without losing any marks etc.
+ * If "forceit" is TRUE, then the old file is not read in, and only internal
+ * info is written to the file.
+ */
+void write_viminfo(file, forceit)
+char_u *file;
+int forceit;
+{
+ char_u *fname;
+ FILE *fp_in = NULL; /* input viminfo file, if any */
+ FILE *fp_out = NULL; /* output viminfo file */
+ char_u *tempname = NULL; /* name of temp viminfo file */
+ struct stat st_new; /* mch_stat() of potential new file */
+ char_u *wp;
+#if defined(UNIX) || defined(VMS)
+ mode_t umask_save;
+#endif
+#ifdef UNIX
+ int shortname = FALSE; /* use 8.3 file name */
+ struct stat st_old; /* mch_stat() of existing viminfo file */
+#endif
+
+ if (no_viminfo())
+ return;
+
+ fname = viminfo_filename(file); /* may set to default if NULL */
+ if (fname == NULL)
+ return;
+
+ fp_in = mch_fopen((char *)fname, READBIN);
+ if (fp_in == NULL) {
+ /* if it does exist, but we can't read it, don't try writing */
+ if (mch_stat((char *)fname, &st_new) == 0)
+ goto end;
+#if defined(UNIX) || defined(VMS)
+ /*
+ * For Unix we create the .viminfo non-accessible for others,
+ * because it may contain text from non-accessible documents.
+ */
+ umask_save = umask(077);
+#endif
+ fp_out = mch_fopen((char *)fname, WRITEBIN);
+#if defined(UNIX) || defined(VMS)
+ (void)umask(umask_save);
+#endif
+ } else {
+ /*
+ * There is an existing viminfo file. Create a temporary file to
+ * write the new viminfo into, in the same directory as the
+ * existing viminfo file, which will be renamed later.
+ */
+#ifdef UNIX
+ /*
+ * For Unix we check the owner of the file. It's not very nice to
+ * overwrite a user's viminfo file after a "su root", with a
+ * viminfo file that the user can't read.
+ */
+ st_old.st_dev = (dev_t)0;
+ st_old.st_ino = 0;
+ st_old.st_mode = 0600;
+ if (mch_stat((char *)fname, &st_old) == 0
+ && getuid() != ROOT_UID
+ && !(st_old.st_uid == getuid()
+ ? (st_old.st_mode & 0200)
+ : (st_old.st_gid == getgid()
+ ? (st_old.st_mode & 0020)
+ : (st_old.st_mode & 0002)))) {
+ int tt = msg_didany;
+
+ /* avoid a wait_return for this message, it's annoying */
+ EMSG2(_("E137: Viminfo file is not writable: %s"), fname);
+ msg_didany = tt;
+ fclose(fp_in);
+ goto end;
+ }
+#endif
+
+ /*
+ * Make tempname.
+ * May try twice: Once normal and once with shortname set, just in
+ * case somebody puts his viminfo file in an 8.3 filesystem.
+ */
+ for (;; ) {
+ tempname = buf_modname(
+#ifdef UNIX
+ shortname,
+#else
+# ifdef SHORT_FNAME
+ TRUE,
+# else
+ FALSE,
+# endif
+#endif
+ fname,
+ (char_u *)".tmp",
+ FALSE);
+ if (tempname == NULL) /* out of memory */
+ break;
+
+ /*
+ * Check if tempfile already exists. Never overwrite an
+ * existing file!
+ */
+ if (mch_stat((char *)tempname, &st_new) == 0) {
+#ifdef UNIX
+ /*
+ * Check if tempfile is same as original file. May happen
+ * when modname() gave the same file back. E.g. silly
+ * link, or file name-length reached. Try again with
+ * shortname set.
+ */
+ if (!shortname && st_new.st_dev == st_old.st_dev
+ && st_new.st_ino == st_old.st_ino) {
+ vim_free(tempname);
+ tempname = NULL;
+ shortname = TRUE;
+ continue;
+ }
+#endif
+ /*
+ * Try another name. Change one character, just before
+ * the extension. This should also work for an 8.3
+ * file name, when after adding the extension it still is
+ * the same file as the original.
+ */
+ wp = tempname + STRLEN(tempname) - 5;
+ if (wp < gettail(tempname)) /* empty file name? */
+ wp = gettail(tempname);
+ for (*wp = 'z'; mch_stat((char *)tempname, &st_new) == 0;
+ --*wp) {
+ /*
+ * They all exist? Must be something wrong! Don't
+ * write the viminfo file then.
+ */
+ if (*wp == 'a') {
+ vim_free(tempname);
+ tempname = NULL;
+ break;
+ }
+ }
+ }
+ break;
+ }
+
+ if (tempname != NULL) {
+ int fd;
+
+ /* Use mch_open() to be able to use O_NOFOLLOW and set file
+ * protection:
+ * Unix: same as original file, but strip s-bit. Reset umask to
+ * avoid it getting in the way.
+ * Others: r&w for user only. */
+# ifdef UNIX
+ umask_save = umask(0);
+ fd = mch_open((char *)tempname,
+ O_CREAT|O_EXTRA|O_EXCL|O_WRONLY|O_NOFOLLOW,
+ (int)((st_old.st_mode & 0777) | 0600));
+ (void)umask(umask_save);
+# else
+ fd = mch_open((char *)tempname,
+ O_CREAT|O_EXTRA|O_EXCL|O_WRONLY|O_NOFOLLOW, 0600);
+# endif
+ if (fd < 0)
+ fp_out = NULL;
+ else
+ fp_out = fdopen(fd, WRITEBIN);
+
+ /*
+ * If we can't create in the same directory, try creating a
+ * "normal" temp file.
+ */
+ if (fp_out == NULL) {
+ vim_free(tempname);
+ if ((tempname = vim_tempname('o')) != NULL)
+ fp_out = mch_fopen((char *)tempname, WRITEBIN);
+ }
+
+#if defined(UNIX) && defined(HAVE_FCHOWN)
+ /*
+ * Make sure the owner can read/write it. This only works for
+ * root.
+ */
+ if (fp_out != NULL)
+ ignored = fchown(fileno(fp_out), st_old.st_uid, st_old.st_gid);
+#endif
+ }
+ }
+
+ /*
+ * Check if the new viminfo file can be written to.
+ */
+ if (fp_out == NULL) {
+ EMSG2(_("E138: Can't write viminfo file %s!"),
+ (fp_in == NULL || tempname == NULL) ? fname : tempname);
+ if (fp_in != NULL)
+ fclose(fp_in);
+ goto end;
+ }
+
+ if (p_verbose > 0) {
+ verbose_enter();
+ smsg((char_u *)_("Writing viminfo file \"%s\""), fname);
+ verbose_leave();
+ }
+
+ viminfo_errcnt = 0;
+ do_viminfo(fp_in, fp_out, forceit ? 0 : (VIF_WANT_INFO | VIF_WANT_MARKS));
+
+ fclose(fp_out); /* errors are ignored !? */
+ if (fp_in != NULL) {
+ fclose(fp_in);
+
+ /*
+ * In case of an error keep the original viminfo file.
+ * Otherwise rename the newly written file.
+ */
+ if (viminfo_errcnt || vim_rename(tempname, fname) == -1)
+ mch_remove(tempname);
+
+ }
+
+end:
+ vim_free(fname);
+ vim_free(tempname);
+}
+
+/*
+ * Get the viminfo file name to use.
+ * If "file" is given and not empty, use it (has already been expanded by
+ * cmdline functions).
+ * Otherwise use "-i file_name", value from 'viminfo' or the default, and
+ * expand environment variables.
+ * Returns an allocated string. NULL when out of memory.
+ */
+static char_u * viminfo_filename(file)
+char_u *file;
+{
+ if (file == NULL || *file == NUL) {
+ if (use_viminfo != NULL)
+ file = use_viminfo;
+ else if ((file = find_viminfo_parameter('n')) == NULL || *file == NUL) {
+#ifdef VIMINFO_FILE2
+ /* don't use $HOME when not defined (turned into "c:/"!). */
+ if (mch_getenv((char_u *)"HOME") == NULL) {
+ /* don't use $VIM when not available. */
+ expand_env((char_u *)"$VIM", NameBuff, MAXPATHL);
+ if (STRCMP("$VIM", NameBuff) != 0) /* $VIM was expanded */
+ file = (char_u *)VIMINFO_FILE2;
+ else
+ file = (char_u *)VIMINFO_FILE;
+ } else
+#endif
+ file = (char_u *)VIMINFO_FILE;
+ }
+ expand_env(file, NameBuff, MAXPATHL);
+ file = NameBuff;
+ }
+ return vim_strsave(file);
+}
+
+/*
+ * do_viminfo() -- Should only be called from read_viminfo() & write_viminfo().
+ */
+static void do_viminfo(fp_in, fp_out, flags)
+FILE *fp_in;
+FILE *fp_out;
+int flags;
+{
+ int count = 0;
+ int eof = FALSE;
+ vir_T vir;
+ int merge = FALSE;
+
+ if ((vir.vir_line = alloc(LSIZE)) == NULL)
+ return;
+ vir.vir_fd = fp_in;
+ vir.vir_conv.vc_type = CONV_NONE;
+
+ if (fp_in != NULL) {
+ if (flags & VIF_WANT_INFO) {
+ eof = read_viminfo_up_to_marks(&vir,
+ flags & VIF_FORCEIT, fp_out != NULL);
+ merge = TRUE;
+ } else if (flags != 0)
+ /* Skip info, find start of marks */
+ while (!(eof = viminfo_readline(&vir))
+ && vir.vir_line[0] != '>')
+ ;
+ }
+ if (fp_out != NULL) {
+ /* Write the info: */
+ fprintf(fp_out, _("# This viminfo file was generated by Vim %s.\n"),
+ VIM_VERSION_MEDIUM);
+ fputs(_("# You may edit it if you're careful!\n\n"), fp_out);
+ fputs(_("# Value of 'encoding' when this file was written\n"), fp_out);
+ fprintf(fp_out, "*encoding=%s\n\n", p_enc);
+ write_viminfo_search_pattern(fp_out);
+ write_viminfo_sub_string(fp_out);
+ write_viminfo_history(fp_out, merge);
+ write_viminfo_registers(fp_out);
+ write_viminfo_varlist(fp_out);
+ write_viminfo_filemarks(fp_out);
+ write_viminfo_bufferlist(fp_out);
+ count = write_viminfo_marks(fp_out);
+ }
+ if (fp_in != NULL
+ && (flags & (VIF_WANT_MARKS | VIF_GET_OLDFILES | VIF_FORCEIT)))
+ copy_viminfo_marks(&vir, fp_out, count, eof, flags);
+
+ vim_free(vir.vir_line);
+ if (vir.vir_conv.vc_type != CONV_NONE)
+ convert_setup(&vir.vir_conv, NULL, NULL);
+}
+
+/*
+ * read_viminfo_up_to_marks() -- Only called from do_viminfo(). Reads in the
+ * first part of the viminfo file which contains everything but the marks that
+ * are local to a file. Returns TRUE when end-of-file is reached. -- webb
+ */
+static int read_viminfo_up_to_marks(virp, forceit, writing)
+vir_T *virp;
+int forceit;
+int writing;
+{
+ int eof;
+ buf_T *buf;
+
+ prepare_viminfo_history(forceit ? 9999 : 0, writing);
+ eof = viminfo_readline(virp);
+ while (!eof && virp->vir_line[0] != '>') {
+ switch (virp->vir_line[0]) {
+ /* Characters reserved for future expansion, ignored now */
+ case '+': /* "+40 /path/dir file", for running vim without args */
+ case '|': /* to be defined */
+ case '^': /* to be defined */
+ case '<': /* long line - ignored */
+ /* A comment or empty line. */
+ case NUL:
+ case '\r':
+ case '\n':
+ case '#':
+ eof = viminfo_readline(virp);
+ break;
+ case '*': /* "*encoding=value" */
+ eof = viminfo_encoding(virp);
+ break;
+ case '!': /* global variable */
+ eof = read_viminfo_varlist(virp, writing);
+ break;
+ case '%': /* entry for buffer list */
+ eof = read_viminfo_bufferlist(virp, writing);
+ break;
+ case '"':
+ eof = read_viminfo_register(virp, forceit);
+ break;
+ case '/': /* Search string */
+ case '&': /* Substitute search string */
+ case '~': /* Last search string, followed by '/' or '&' */
+ eof = read_viminfo_search_pattern(virp, forceit);
+ break;
+ case '$':
+ eof = read_viminfo_sub_string(virp, forceit);
+ break;
+ case ':':
+ case '?':
+ case '=':
+ case '@':
+ eof = read_viminfo_history(virp, writing);
+ break;
+ case '-':
+ case '\'':
+ eof = read_viminfo_filemark(virp, forceit);
+ break;
+ default:
+ if (viminfo_error("E575: ", _("Illegal starting char"),
+ virp->vir_line))
+ eof = TRUE;
+ else
+ eof = viminfo_readline(virp);
+ break;
+ }
+ }
+
+ /* Finish reading history items. */
+ if (!writing)
+ finish_viminfo_history();
+
+ /* Change file names to buffer numbers for fmarks. */
+ for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+ fmarks_check_names(buf);
+
+ return eof;
+}
+
+/*
+ * Compare the 'encoding' value in the viminfo file with the current value of
+ * 'encoding'. If different and the 'c' flag is in 'viminfo', setup for
+ * conversion of text with iconv() in viminfo_readstring().
+ */
+static int viminfo_encoding(virp)
+vir_T *virp;
+{
+ char_u *p;
+ int i;
+
+ if (get_viminfo_parameter('c') != 0) {
+ p = vim_strchr(virp->vir_line, '=');
+ if (p != NULL) {
+ /* remove trailing newline */
+ ++p;
+ for (i = 0; vim_isprintc(p[i]); ++i)
+ ;
+ p[i] = NUL;
+
+ convert_setup(&virp->vir_conv, p, p_enc);
+ }
+ }
+ return viminfo_readline(virp);
+}
+
+/*
+ * Read a line from the viminfo file.
+ * Returns TRUE for end-of-file;
+ */
+int viminfo_readline(virp)
+vir_T *virp;
+{
+ return vim_fgets(virp->vir_line, LSIZE, virp->vir_fd);
+}
+
+/*
+ * check string read from viminfo file
+ * remove '\n' at the end of the line
+ * - replace CTRL-V CTRL-V with CTRL-V
+ * - replace CTRL-V 'n' with '\n'
+ *
+ * Check for a long line as written by viminfo_writestring().
+ *
+ * Return the string in allocated memory (NULL when out of memory).
+ */
+char_u * viminfo_readstring(virp, off, convert)
+vir_T *virp;
+int off; /* offset for virp->vir_line */
+int convert UNUSED; /* convert the string */
+{
+ char_u *retval;
+ char_u *s, *d;
+ long len;
+
+ if (virp->vir_line[off] == Ctrl_V && vim_isdigit(virp->vir_line[off + 1])) {
+ len = atol((char *)virp->vir_line + off + 1);
+ retval = lalloc(len, TRUE);
+ if (retval == NULL) {
+ /* Line too long? File messed up? Skip next line. */
+ (void)vim_fgets(virp->vir_line, 10, virp->vir_fd);
+ return NULL;
+ }
+ (void)vim_fgets(retval, (int)len, virp->vir_fd);
+ s = retval + 1; /* Skip the leading '<' */
+ } else {
+ retval = vim_strsave(virp->vir_line + off);
+ if (retval == NULL)
+ return NULL;
+ s = retval;
+ }
+
+ /* Change CTRL-V CTRL-V to CTRL-V and CTRL-V n to \n in-place. */
+ d = retval;
+ while (*s != NUL && *s != '\n') {
+ if (s[0] == Ctrl_V && s[1] != NUL) {
+ if (s[1] == 'n')
+ *d++ = '\n';
+ else
+ *d++ = Ctrl_V;
+ s += 2;
+ } else
+ *d++ = *s++;
+ }
+ *d = NUL;
+
+ if (convert && virp->vir_conv.vc_type != CONV_NONE && *retval != NUL) {
+ d = string_convert(&virp->vir_conv, retval, NULL);
+ if (d != NULL) {
+ vim_free(retval);
+ retval = d;
+ }
+ }
+
+ return retval;
+}
+
+/*
+ * write string to viminfo file
+ * - replace CTRL-V with CTRL-V CTRL-V
+ * - replace '\n' with CTRL-V 'n'
+ * - add a '\n' at the end
+ *
+ * For a long line:
+ * - write " CTRL-V <length> \n " in first line
+ * - write " < <string> \n " in second line
+ */
+void viminfo_writestring(fd, p)
+FILE *fd;
+char_u *p;
+{
+ int c;
+ char_u *s;
+ int len = 0;
+
+ for (s = p; *s != NUL; ++s) {
+ if (*s == Ctrl_V || *s == '\n')
+ ++len;
+ ++len;
+ }
+
+ /* If the string will be too long, write its length and put it in the next
+ * line. Take into account that some room is needed for what comes before
+ * the string (e.g., variable name). Add something to the length for the
+ * '<', NL and trailing NUL. */
+ if (len > LSIZE / 2)
+ fprintf(fd, IF_EB("\026%d\n<", CTRL_V_STR "%d\n<"), len + 3);
+
+ while ((c = *p++) != NUL) {
+ if (c == Ctrl_V || c == '\n') {
+ putc(Ctrl_V, fd);
+ if (c == '\n')
+ c = 'n';
+ }
+ putc(c, fd);
+ }
+ putc('\n', fd);
+}
+
+/*
+ * Implementation of ":fixdel", also used by get_stty().
+ * <BS> resulting <Del>
+ * ^? ^H
+ * not ^? ^?
+ */
+void do_fixdel(eap)
+exarg_T *eap UNUSED;
+{
+ char_u *p;
+
+ p = find_termcode((char_u *)"kb");
+ add_termcode((char_u *)"kD", p != NULL
+ && *p == DEL ? (char_u *)CTRL_H_STR : DEL_STR, FALSE);
+}
+
+void print_line_no_prefix(lnum, use_number, list)
+linenr_T lnum;
+int use_number;
+int list;
+{
+ char_u 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 */
+ }
+ msg_prt_line(ml_get(lnum), list);
+}
+
+/*
+ * Print a text line. Also in silent mode ("ex -s").
+ */
+void print_line(lnum, use_number, list)
+linenr_T lnum;
+int use_number;
+int list;
+{
+ int save_silent = silent_mode;
+
+ msg_start();
+ silent_mode = FALSE;
+ info_message = TRUE; /* use mch_msg(), not mch_errmsg() */
+ print_line_no_prefix(lnum, use_number, list);
+ if (save_silent) {
+ msg_putchar('\n');
+ cursor_on(); /* msg_start() switches it off */
+ out_flush();
+ silent_mode = save_silent;
+ }
+ info_message = FALSE;
+}
+
+int rename_buffer(new_fname)
+char_u *new_fname;
+{
+ char_u *fname, *sfname, *xfname;
+ buf_T *buf;
+
+ buf = curbuf;
+ apply_autocmds(EVENT_BUFFILEPRE, NULL, NULL, FALSE, curbuf);
+ /* buffer changed, don't change name now */
+ if (buf != curbuf)
+ return FAIL;
+ if (aborting()) /* autocmds may abort script processing */
+ return FAIL;
+ /*
+ * The name of the current buffer will be changed.
+ * A new (unlisted) buffer entry needs to be made to hold the old file
+ * name, which will become the alternate file name.
+ * But don't set the alternate file name if the buffer didn't have a
+ * name.
+ */
+ fname = curbuf->b_ffname;
+ sfname = curbuf->b_sfname;
+ xfname = curbuf->b_fname;
+ curbuf->b_ffname = NULL;
+ curbuf->b_sfname = NULL;
+ if (setfname(curbuf, new_fname, NULL, TRUE) == FAIL) {
+ curbuf->b_ffname = fname;
+ curbuf->b_sfname = sfname;
+ return FAIL;
+ }
+ 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)
+ curwin->w_alt_fnum = buf->b_fnum;
+ }
+ vim_free(fname);
+ vim_free(sfname);
+ apply_autocmds(EVENT_BUFFILEPOST, NULL, NULL, FALSE, curbuf);
+ /* Change directories when the 'acd' option is set. */
+ DO_AUTOCHDIR
+ return OK;
+}
+
+/*
+ * ":file[!] [fname]".
+ */
+void ex_file(eap)
+exarg_T *eap;
+{
+ /* ":0file" removes the file name. Check for illegal uses ":3file",
+ * "0file name", etc. */
+ if (eap->addr_count > 0
+ && (*eap->arg != NUL
+ || eap->line2 > 0
+ || eap->addr_count > 1)) {
+ EMSG(_(e_invarg));
+ return;
+ }
+
+ if (*eap->arg != NUL || eap->addr_count == 1) {
+ if (rename_buffer(eap->arg) == FAIL)
+ return;
+ }
+ /* print full file name if :cd used */
+ fileinfo(FALSE, FALSE, eap->forceit);
+}
+
+/*
+ * ":update".
+ */
+void ex_update(eap)
+exarg_T *eap;
+{
+ if (curbufIsChanged())
+ (void)do_write(eap);
+}
+
+/*
+ * ":write" and ":saveas".
+ */
+void ex_write(eap)
+exarg_T *eap;
+{
+ if (eap->usefilter) /* input lines to shell command */
+ do_bang(1, eap, FALSE, TRUE, FALSE);
+ else
+ (void)do_write(eap);
+}
+
+/*
+ * write current buffer to file 'eap->arg'
+ * if 'eap->append' is TRUE, append to the file
+ *
+ * if *eap->arg == NUL write to current file
+ *
+ * return FAIL for failure, OK otherwise
+ */
+int do_write(eap)
+exarg_T *eap;
+{
+ int other;
+ char_u *fname = NULL; /* init to shut up gcc */
+ char_u *ffname;
+ int retval = FAIL;
+ char_u *free_fname = NULL;
+ buf_T *alt_buf = NULL;
+
+ if (not_writing()) /* check 'write' option */
+ return FAIL;
+
+ ffname = eap->arg;
+ if (*ffname == NUL) {
+ if (eap->cmdidx == CMD_saveas) {
+ EMSG(_(e_argreq));
+ goto theend;
+ }
+ other = FALSE;
+ } else {
+ fname = ffname;
+ free_fname = fix_fname(ffname);
+ /*
+ * When out-of-memory, keep unexpanded file name, because we MUST be
+ * able to write the file in this situation.
+ */
+ if (free_fname != NULL)
+ ffname = free_fname;
+ other = otherfile(ffname);
+ }
+
+ /*
+ * If we have a new file, put its name in the list of alternate file names.
+ */
+ if (other) {
+ if (vim_strchr(p_cpo, CPO_ALTWRITE) != NULL
+ || eap->cmdidx == CMD_saveas)
+ alt_buf = setaltfname(ffname, fname, (linenr_T)1);
+ else
+ alt_buf = buflist_findname(ffname);
+ if (alt_buf != NULL && alt_buf->b_ml.ml_mfp != NULL) {
+ /* Overwriting a file that is loaded in another buffer is not a
+ * good idea. */
+ EMSG(_(e_bufloaded));
+ goto theend;
+ }
+ }
+
+ /*
+ * Writing to the current file is not allowed in readonly mode
+ * and a file name is required.
+ * "nofile" and "nowrite" buffers cannot be written implicitly either.
+ */
+ if (!other && (
+ bt_dontwrite_msg(curbuf) ||
+ check_fname() == FAIL || check_readonly(&eap->forceit, curbuf)))
+ goto theend;
+
+ if (!other) {
+ ffname = curbuf->b_ffname;
+ fname = curbuf->b_fname;
+ /*
+ * Not writing the whole file is only allowed with '!'.
+ */
+ if ( (eap->line1 != 1
+ || eap->line2 != curbuf->b_ml.ml_line_count)
+ && !eap->forceit
+ && !eap->append
+ && !p_wa) {
+ if (p_confirm || cmdmod.confirm) {
+ if (vim_dialog_yesno(VIM_QUESTION, NULL,
+ (char_u *)_("Write partial file?"), 2) != VIM_YES)
+ goto theend;
+ eap->forceit = TRUE;
+ } else {
+ EMSG(_("E140: Use ! to write partial buffer"));
+ goto theend;
+ }
+ }
+ }
+
+ if (check_overwrite(eap, curbuf, fname, ffname, other) == OK) {
+ if (eap->cmdidx == CMD_saveas && alt_buf != NULL) {
+ buf_T *was_curbuf = curbuf;
+
+ apply_autocmds(EVENT_BUFFILEPRE, NULL, NULL, FALSE, curbuf);
+ apply_autocmds(EVENT_BUFFILEPRE, NULL, NULL, FALSE, alt_buf);
+ if (curbuf != was_curbuf || aborting()) {
+ /* buffer changed, don't change name now */
+ retval = FAIL;
+ goto theend;
+ }
+ /* Exchange the file names for the current and the alternate
+ * buffer. This makes it look like we are now editing the buffer
+ * under the new name. Must be done before buf_write(), because
+ * if there is no file name and 'cpo' contains 'F', it will set
+ * the file name. */
+ fname = alt_buf->b_fname;
+ alt_buf->b_fname = curbuf->b_fname;
+ curbuf->b_fname = fname;
+ fname = alt_buf->b_ffname;
+ alt_buf->b_ffname = curbuf->b_ffname;
+ curbuf->b_ffname = fname;
+ fname = alt_buf->b_sfname;
+ alt_buf->b_sfname = curbuf->b_sfname;
+ curbuf->b_sfname = fname;
+ buf_name_changed(curbuf);
+ apply_autocmds(EVENT_BUFFILEPOST, NULL, NULL, FALSE, curbuf);
+ apply_autocmds(EVENT_BUFFILEPOST, NULL, NULL, FALSE, alt_buf);
+ if (!alt_buf->b_p_bl) {
+ alt_buf->b_p_bl = TRUE;
+ apply_autocmds(EVENT_BUFADD, NULL, NULL, FALSE, alt_buf);
+ }
+ if (curbuf != was_curbuf || aborting()) {
+ /* buffer changed, don't write the file */
+ retval = FAIL;
+ goto theend;
+ }
+
+ /* 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);
+ do_modelines(0);
+ }
+
+ /* Autocommands may have changed buffer names, esp. when
+ * 'autochdir' is set. */
+ fname = curbuf->b_sfname;
+ }
+
+ retval = buf_write(curbuf, ffname, fname, eap->line1, eap->line2,
+ eap, eap->append, eap->forceit, TRUE, FALSE);
+
+ /* After ":saveas fname" reset 'readonly'. */
+ if (eap->cmdidx == CMD_saveas) {
+ if (retval == OK) {
+ curbuf->b_p_ro = FALSE;
+ redraw_tabline = TRUE;
+ }
+ /* Change directories when the 'acd' option is set. */
+ DO_AUTOCHDIR
+ }
+ }
+
+theend:
+ vim_free(free_fname);
+ return retval;
+}
+
+/*
+ * Check if it is allowed to overwrite a file. If b_flags has BF_NOTEDITED,
+ * BF_NEW or BF_READERR, check for overwriting current file.
+ * 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(eap, buf, fname, ffname, other)
+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 */
+{
+ /*
+ * write to other file or b_flags set or not writing the whole file:
+ * overwriting only allowed with '!'
+ */
+ if ( (other
+ || (buf->b_flags & BF_NOTEDITED)
+ || ((buf->b_flags & BF_NEW)
+ && vim_strchr(p_cpo, CPO_OVERNEW) == NULL)
+ || (buf->b_flags & BF_READERR))
+ && !p_wa
+ && !bt_nofile(buf)
+ && vim_fexists(ffname)) {
+ if (!eap->forceit && !eap->append) {
+#ifdef UNIX
+ /* with UNIX it is possible to open a directory */
+ if (mch_isdir(ffname)) {
+ EMSG2(_(e_isadir2), ffname);
+ return FAIL;
+ }
+#endif
+ if (p_confirm || cmdmod.confirm) {
+ char_u buff[DIALOG_MSG_SIZE];
+
+ dialog_msg(buff, _("Overwrite existing file \"%s\"?"), fname);
+ if (vim_dialog_yesno(VIM_QUESTION, NULL, buff, 2) != VIM_YES)
+ return FAIL;
+ eap->forceit = TRUE;
+ } else {
+ EMSG(_(e_exists));
+ return FAIL;
+ }
+ }
+
+ /* For ":w! filename" check that no swap file exists for "filename". */
+ if (other && !emsg_silent) {
+ char_u *dir;
+ char_u *p;
+ int r;
+ char_u *swapname;
+
+ /* We only try the first entry in 'directory', without checking if
+ * it's writable. If the "." directory is not writable the write
+ * will probably fail anyway.
+ * Use 'shortname' of the current buffer, since there is no buffer
+ * for the written file. */
+ if (*p_dir == NUL) {
+ dir = alloc(5);
+ if (dir == NULL)
+ return FAIL;
+ STRCPY(dir, ".");
+ } else {
+ dir = alloc(MAXPATHL);
+ if (dir == NULL)
+ return FAIL;
+ p = p_dir;
+ copy_option_part(&p, dir, MAXPATHL, ",");
+ }
+ swapname = makeswapname(fname, ffname, curbuf, dir);
+ vim_free(dir);
+ r = vim_fexists(swapname);
+ if (r) {
+ if (p_confirm || cmdmod.confirm) {
+ char_u buff[DIALOG_MSG_SIZE];
+
+ dialog_msg(buff,
+ _("Swap file \"%s\" exists, overwrite anyway?"),
+ swapname);
+ if (vim_dialog_yesno(VIM_QUESTION, NULL, buff, 2)
+ != VIM_YES) {
+ vim_free(swapname);
+ return FAIL;
+ }
+ eap->forceit = TRUE;
+ } else {
+ EMSG2(_("E768: Swap file exists: %s (:silent! overrides)"),
+ swapname);
+ vim_free(swapname);
+ return FAIL;
+ }
+ }
+ vim_free(swapname);
+ }
+ }
+ return OK;
+}
+
+/*
+ * Handle ":wnext", ":wNext" and ":wprevious" commands.
+ */
+void ex_wnext(eap)
+exarg_T *eap;
+{
+ int i;
+
+ if (eap->cmd[1] == 'n')
+ i = curwin->w_arg_idx + (int)eap->line2;
+ else
+ i = curwin->w_arg_idx - (int)eap->line2;
+ eap->line1 = 1;
+ eap->line2 = curbuf->b_ml.ml_line_count;
+ if (do_write(eap) != FAIL)
+ do_argfile(eap, i);
+}
+
+/*
+ * ":wall", ":wqall" and ":xall": Write all changed files (and exit).
+ */
+void do_wqall(eap)
+exarg_T *eap;
+{
+ buf_T *buf;
+ int error = 0;
+ int save_forceit = eap->forceit;
+
+ if (eap->cmdidx == CMD_xall || eap->cmdidx == CMD_wqall)
+ exiting = TRUE;
+
+ for (buf = firstbuf; buf != NULL; buf = buf->b_next) {
+ if (bufIsChanged(buf)) {
+ /*
+ * Check if there is a reason the buffer cannot be written:
+ * 1. if the 'write' option is set
+ * 2. if there is no file name (even after browsing)
+ * 3. if the 'readonly' is set (even after a dialog)
+ * 4. if overwriting is allowed (even after a dialog)
+ */
+ if (not_writing()) {
+ ++error;
+ break;
+ }
+ if (buf->b_ffname == NULL) {
+ EMSGN(_("E141: No file name for buffer %ld"), (long)buf->b_fnum);
+ ++error;
+ } else if (check_readonly(&eap->forceit, buf)
+ || check_overwrite(eap, buf, buf->b_fname, buf->b_ffname,
+ FALSE) == FAIL) {
+ ++error;
+ } else {
+ if (buf_write_all(buf, eap->forceit) == FAIL)
+ ++error;
+ /* an autocommand may have deleted the buffer */
+ if (!buf_valid(buf))
+ buf = firstbuf;
+ }
+ eap->forceit = save_forceit; /* check_overwrite() may set it */
+ }
+ }
+ if (exiting) {
+ if (!error)
+ getout(0); /* exit Vim */
+ not_exiting();
+ }
+}
+
+/*
+ * Check the 'write' option.
+ * Return TRUE and give a message when it's not st.
+ */
+int not_writing() {
+ if (p_write)
+ return FALSE;
+ EMSG(_("E142: File not written: Writing is disabled by 'write' option"));
+ return TRUE;
+}
+
+/*
+ * Check if a buffer is read-only (either 'readonly' option is set or file is
+ * read-only). Ask for overruling in a dialog. Return TRUE and give an error
+ * message when the buffer is readonly.
+ */
+static int check_readonly(forceit, buf)
+int *forceit;
+buf_T *buf;
+{
+ struct stat st;
+
+ /* Handle a file being readonly when the 'readonly' option is set or when
+ * the file exists and permissions are read-only.
+ * We will send 0777 to check_file_readonly(), as the "perm" variable is
+ * important for device checks but not here. */
+ if (!*forceit && (buf->b_p_ro
+ || (mch_stat((char *)buf->b_ffname, &st) >= 0
+ && check_file_readonly(buf->b_ffname, 0777)))) {
+ if ((p_confirm || cmdmod.confirm) && buf->b_fname != NULL) {
+ char_u buff[DIALOG_MSG_SIZE];
+
+ if (buf->b_p_ro)
+ dialog_msg(buff,
+ _(
+ "'readonly' option is set for \"%s\".\nDo you wish to write anyway?"),
+ buf->b_fname);
+ else
+ dialog_msg(buff,
+ _(
+ "File permissions of \"%s\" are read-only.\nIt may still be possible to write it.\nDo you wish to try?"),
+ buf->b_fname);
+
+ if (vim_dialog_yesno(VIM_QUESTION, NULL, buff, 2) == VIM_YES) {
+ /* Set forceit, to force the writing of a readonly file */
+ *forceit = TRUE;
+ return FALSE;
+ } else
+ return TRUE;
+ } else if (buf->b_p_ro)
+ EMSG(_(e_readonly));
+ else
+ EMSG2(_("E505: \"%s\" is read-only (add ! to override)"),
+ buf->b_fname);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/*
+ * Try to abandon current file and edit a new or existing file.
+ * 'fnum' is the number of the file, if zero use ffname/sfname.
+ *
+ * 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).
+ */
+int getfile(fnum, ffname, sfname, setpm, lnum, forceit)
+int fnum;
+char_u *ffname;
+char_u *sfname;
+int setpm;
+linenr_T lnum;
+int forceit;
+{
+ int other;
+ int retval;
+ char_u *free_me = NULL;
+
+ if (text_locked())
+ return 1;
+ if (curbuf_locked())
+ return 1;
+
+ if (fnum == 0) {
+ /* make ffname full path, set sfname */
+ fname_expand(curbuf, &ffname, &sfname);
+ other = otherfile(ffname);
+ free_me = ffname; /* has been allocated, free() later */
+ } 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)
+ && curbufIsChanged() && autowrite(curbuf, forceit) == FAIL) {
+ if (p_confirm && p_write)
+ dialog_changed(curbuf, FALSE);
+ if (curbufIsChanged()) {
+ if (other)
+ --no_wait_return;
+ EMSG(_(e_nowrtmsg));
+ retval = 2; /* file has been changed */
+ goto theend;
+ }
+ }
+ if (other)
+ --no_wait_return;
+ if (setpm)
+ setpcmark();
+ if (!other) {
+ if (lnum != 0)
+ curwin->w_cursor.lnum = lnum;
+ check_cursor_lnum();
+ beginline(BL_SOL | BL_FIX);
+ retval = 0; /* 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 */
+
+theend:
+ vim_free(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(fnum, ffname, sfname, eap, newlnum, flags, oldwin)
+int fnum;
+char_u *ffname;
+char_u *sfname;
+exarg_T *eap; /* can be NULL! */
+linenr_T newlnum;
+int flags;
+win_T *oldwin;
+{
+ int other_file; /* TRUE if editing another file */
+ int oldbuf; /* TRUE if using existing buffer */
+ int auto_buf = FALSE; /* TRUE if autocommands brought us
+ into the buffer unexpectedly */
+ char_u *new_name = NULL;
+ int did_set_swapcommand = FALSE;
+ buf_T *buf;
+ buf_T *old_curbuf = curbuf;
+ char_u *free_fname = NULL;
+ int retval = FAIL;
+ long n;
+ linenr_T lnum;
+ linenr_T topline = 0;
+ int newcol = -1;
+ int solcol = -1;
+ pos_T *pos;
+ char_u *command = NULL;
+ int did_get_winopts = FALSE;
+ int readfile_flags = 0;
+
+ if (eap != NULL)
+ command = eap->do_ecmd_cmd;
+
+ if (fnum != 0) {
+ if (fnum == curbuf->b_fnum) /* file is already being edited */
+ return OK; /* nothing to do */
+ other_file = TRUE;
+ } else {
+ /* if no short name given, use ffname for short name */
+ if (sfname == NULL)
+ sfname = ffname;
+#ifdef USE_FNAME_CASE
+# ifdef USE_LONG_FNAME
+ if (USE_LONG_FNAME)
+# endif
+ if (sfname != NULL)
+ fname_case(sfname, 0); /* set correct case for sfname */
+#endif
+
+ if ((flags & ECMD_ADDBUF) && (ffname == NULL || *ffname == NUL))
+ goto theend;
+
+ if (ffname == NULL)
+ other_file = TRUE;
+ /* there is no file name */
+ else if (*ffname == NUL && curbuf->b_ffname == NULL)
+ other_file = FALSE;
+ else {
+ if (*ffname == NUL) { /* re-edit with same file name */
+ ffname = curbuf->b_ffname;
+ sfname = curbuf->b_fname;
+ }
+ free_fname = fix_fname(ffname); /* may expand to full path name */
+ if (free_fname != NULL)
+ ffname = free_fname;
+ other_file = otherfile(ffname);
+ }
+ }
+
+ /*
+ * if the file was changed we may not be allowed to abandon it
+ * - if we are going to re-edit the same file
+ * - or if we are the only window on this file and if ECMD_HIDE is FALSE
+ */
+ if ( ((!other_file && !(flags & ECMD_OLDBUF))
+ || (curbuf->b_nwindows == 1
+ && !(flags & (ECMD_HIDE | ECMD_ADDBUF))))
+ && check_changed(curbuf, (p_awa ? CCGD_AW : 0)
+ | (other_file ? 0 : CCGD_MULTWIN)
+ | ((flags & ECMD_FORCEIT) ? CCGD_FORCEIT : 0)
+ | (eap == NULL ? 0 : CCGD_EXCMD))) {
+ if (fnum == 0 && other_file && ffname != NULL)
+ (void)setaltfname(ffname, sfname, newlnum < 0 ? 0 : newlnum);
+ goto theend;
+ }
+
+ /*
+ * End Visual mode before switching to another buffer, so the text can be
+ * copied into the GUI selection buffer.
+ */
+ reset_VIsual();
+
+ if ((command != NULL || newlnum > (linenr_T)0)
+ && *get_vim_var_str(VV_SWAPCOMMAND) == NUL) {
+ int len;
+ char_u *p;
+
+ /* Set v:swapcommand for the SwapExists autocommands. */
+ if (command != NULL)
+ len = (int)STRLEN(command) + 3;
+ else
+ len = 30;
+ p = alloc((unsigned)len);
+ if (p != NULL) {
+ if (command != NULL)
+ vim_snprintf((char *)p, len, ":%s\r", command);
+ else
+ vim_snprintf((char *)p, len, "%ldG", (long)newlnum);
+ set_vim_var_string(VV_SWAPCOMMAND, p, -1);
+ did_set_swapcommand = TRUE;
+ vim_free(p);
+ }
+ }
+
+ /*
+ * If we are starting to edit another file, open a (new) buffer.
+ * Otherwise we re-use the current buffer.
+ */
+ if (other_file) {
+ if (!(flags & ECMD_ADDBUF)) {
+ if (!cmdmod.keepalt)
+ curwin->w_alt_fnum = curbuf->b_fnum;
+ if (oldwin != NULL)
+ buflist_altfpos(oldwin);
+ }
+
+ if (fnum)
+ buf = buflist_findnr(fnum);
+ else {
+ if (flags & ECMD_ADDBUF) {
+ linenr_T tlnum = 1L;
+
+ if (command != NULL) {
+ tlnum = atol((char *)command);
+ if (tlnum <= 0)
+ tlnum = 1L;
+ }
+ (void)buflist_new(ffname, sfname, tlnum, BLN_LISTED);
+ goto theend;
+ }
+ buf = buflist_new(ffname, sfname, 0L,
+ BLN_CURBUF | ((flags & ECMD_SET_HELP) ? 0 : BLN_LISTED));
+ }
+ if (buf == NULL)
+ goto theend;
+ if (buf->b_ml.ml_mfp == NULL) { /* no memfile yet */
+ oldbuf = FALSE;
+ buf->b_nwindows = 0;
+ } 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
+ )
+ goto theend;
+ if (aborting()) /* autocmds may abort script processing */
+ goto theend;
+ }
+
+ /* May jump to last used line number for a loaded buffer or when asked
+ * for explicitly */
+ if ((oldbuf && newlnum == ECMD_LASTL) || newlnum == ECMD_LAST) {
+ pos = buflist_findfpos(buf);
+ newlnum = pos->lnum;
+ solcol = pos->col;
+ }
+
+ /*
+ * Make the (new) buffer the one used by the current window.
+ * If the old buffer becomes unused, free it if ECMD_HIDE is FALSE.
+ * If the current buffer was empty and has no file name, curbuf
+ * is returned by buflist_new().
+ */
+ if (buf != curbuf) {
+ /*
+ * Be careful: The autocommands may delete any buffer and change
+ * the current buffer.
+ * - If the buffer we are going to edit is deleted, give up.
+ * - If the current buffer is deleted, prefer to load the new
+ * buffer when loading a buffer is required. This avoids
+ * loading another buffer which then must be closed again.
+ * - If we ended up in the new buffer already, need to skip a few
+ * things, set auto_buf.
+ */
+ 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 */
+ goto theend;
+ }
+ if (aborting()) { /* autocmds may abort script processing */
+ vim_free(new_name);
+ goto theend;
+ }
+ if (buf == curbuf) /* already in new buffer */
+ auto_buf = TRUE;
+ else {
+ if (curbuf == old_curbuf)
+ buf_copy_options(buf, BCO_ENTER);
+
+ /* close the link to the current buffer */
+ u_sync(FALSE);
+ close_buffer(oldwin, curbuf,
+ (flags & ECMD_HIDE) ? 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) && oldwin->w_buffer == NULL)
+ win_close(oldwin, FALSE);
+
+ if (aborting()) { /* autocmds may abort script processing */
+ vim_free(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 */
+ goto theend;
+ }
+ if (buf == curbuf) /* already in new buffer */
+ auto_buf = TRUE;
+ else {
+ /*
+ * <VN> We could instead free the synblock
+ * and re-attach to buffer, perhaps.
+ */
+ if (curwin->w_s == &(curwin->w_buffer->b_s))
+ curwin->w_s = &(buf->b_s);
+ curwin->w_buffer = buf;
+ curbuf = buf;
+ ++curbuf->b_nwindows;
+
+ /* Set 'fileformat', 'binary' and 'fenc' when forced. */
+ if (!oldbuf && eap != NULL) {
+ set_file_options(TRUE, eap);
+ set_forced_fenc(eap);
+ }
+ }
+
+ /* May get the window options from the last time this buffer
+ * was in this window (or another window). If not used
+ * before, reset the local window options to the global
+ * values. Also restores old folding stuff. */
+ get_winopts(curbuf);
+ did_get_winopts = TRUE;
+
+ }
+ vim_free(new_name);
+ au_new_curbuf = NULL;
+ } else
+ ++curbuf->b_nwindows;
+
+ curwin->w_pcmark.lnum = 1;
+ curwin->w_pcmark.col = 0;
+ } else { /* !other_file */
+ if (
+ (flags & ECMD_ADDBUF) ||
+ check_fname() == FAIL)
+ goto theend;
+ oldbuf = (flags & ECMD_OLDBUF);
+ }
+
+ if ((flags & ECMD_SET_HELP) || keep_help_flag) {
+ char_u *p;
+
+ curbuf->b_help = TRUE;
+ set_string_option_direct((char_u *)"buftype", -1,
+ (char_u *)"help", OPT_FREE|OPT_LOCAL, 0);
+
+ /*
+ * Always set these options after jumping to a help tag, because the
+ * user may have an autocommand that gets in the way.
+ * Accept all ASCII chars for keywords, except ' ', '*', '"', '|', and
+ * latin1 word characters (for translated help files).
+ * Only set it when needed, buf_init_chartab() is some work.
+ */
+ p =
+ (char_u *)"!-~,^*,^|,^\",192-255";
+ if (STRCMP(curbuf->b_p_isk, p) != 0) {
+ set_string_option_direct((char_u *)"isk", -1, p,
+ OPT_FREE|OPT_LOCAL, 0);
+ check_buf_options(curbuf);
+ (void)buf_init_chartab(curbuf, FALSE);
+ }
+
+ curbuf->b_p_ts = 8; /* 'tabstop' is 8 */
+ curwin->w_p_list = FALSE; /* no list mode */
+
+ curbuf->b_p_ma = FALSE; /* not modifiable */
+ curbuf->b_p_bin = FALSE; /* reset 'bin' before reading file */
+ curwin->w_p_nu = 0; /* no line numbers */
+ curwin->w_p_rnu = 0; /* no relative line numbers */
+ RESET_BINDING(curwin); /* no scroll or cursor binding */
+ curwin->w_p_arab = FALSE; /* no arabic mode */
+ curwin->w_p_rl = FALSE; /* help window is left-to-right */
+ curwin->w_p_fen = FALSE; /* No folding in the help window */
+ curwin->w_p_diff = FALSE; /* No 'diff' */
+ curwin->w_p_spell = FALSE; /* No spell checking */
+
+ buf = curbuf;
+ set_buflisted(FALSE);
+ } else {
+ buf = curbuf;
+ /* Don't make a buffer listed if it's a help buffer. Useful when
+ * using CTRL-O to go back to a help file. */
+ if (!curbuf->b_help)
+ set_buflisted(TRUE);
+ }
+
+ /* If autocommands change buffers under our fingers, forget about
+ * editing the file. */
+ if (buf != curbuf)
+ goto theend;
+ if (aborting()) /* autocmds may abort script processing */
+ goto theend;
+
+ /* Since we are starting to edit a file, consider the filetype to be
+ * unset. Helps for when an autocommand changes files and expects syntax
+ * highlighting to work in the other file. */
+ did_filetype = FALSE;
+
+ /*
+ * other_file oldbuf
+ * FALSE FALSE re-edit same file, buffer is re-used
+ * FALSE TRUE re-edit same file, nothing changes
+ * TRUE FALSE start editing new file, new buffer
+ * TRUE TRUE start editing in existing buffer (nothing to do)
+ */
+ if (!other_file && !oldbuf) { /* re-use the buffer */
+ set_last_cursor(curwin); /* may set b_last_cursor */
+ if (newlnum == ECMD_LAST || newlnum == ECMD_LASTL) {
+ newlnum = curwin->w_cursor.lnum;
+ solcol = curwin->w_cursor.col;
+ }
+ buf = curbuf;
+ if (buf->b_fname != NULL)
+ new_name = vim_strsave(buf->b_fname);
+ else
+ new_name = NULL;
+ 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)
+ goto theend;
+ u_unchanged(curbuf);
+ buf_freeall(curbuf, BFA_KEEP_UNDO);
+
+ /* 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 */
+ goto theend;
+ }
+ vim_free(new_name);
+
+ /* If autocommands change buffers under our fingers, forget about
+ * re-editing the file. Should do the buf_clear_file(), but perhaps
+ * the autocommands changed the buffer... */
+ if (buf != curbuf)
+ goto theend;
+ if (aborting()) /* autocmds may abort script processing */
+ goto theend;
+ buf_clear_file(curbuf);
+ curbuf->b_op_start.lnum = 0; /* clear '[ and '] marks */
+ curbuf->b_op_end.lnum = 0;
+ }
+
+ /*
+ * 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);
+
+ if (!auto_buf) {
+ /*
+ * Set cursor and init window before reading the file and executing
+ * autocommands. This allows for the autocommands to position the
+ * cursor.
+ */
+ curwin_init();
+
+ /* It's possible that all lines in the buffer changed. Need to update
+ * automatic folding for all windows where it's used. */
+ {
+ win_T *win;
+ tabpage_T *tp;
+
+ FOR_ALL_TAB_WINDOWS(tp, win)
+ if (win->w_buffer == curbuf)
+ foldUpdateAll(win);
+ }
+
+ /* Change directories when the 'acd' option is set. */
+ DO_AUTOCHDIR
+
+ /*
+ * Careful: open_buffer() and apply_autocmds() may change the current
+ * buffer and window.
+ */
+ lnum = curwin->w_cursor.lnum;
+ topline = curwin->w_topline;
+ if (!oldbuf) { /* need to read the file */
+#if defined(HAS_SWAP_EXISTS_ACTION)
+ swap_exists_action = SEA_DIALOG;
+#endif
+ curbuf->b_flags |= BF_CHECK_RO; /* set/reset 'ro' flag */
+
+ /*
+ * Open the buffer and read the file.
+ */
+ if (should_abort(open_buffer(FALSE, eap, readfile_flags)))
+ retval = FAIL;
+
+#if defined(HAS_SWAP_EXISTS_ACTION)
+ if (swap_exists_action == SEA_QUIT)
+ retval = FAIL;
+ handle_swap_exists(old_curbuf);
+#endif
+ } else {
+ /* Read the modelines, but only to set window-local options. Any
+ * buffer-local options have already been set and may have been
+ * changed by the user. */
+ do_modelines(OPT_WINONLY);
+
+ apply_autocmds_retval(EVENT_BUFENTER, NULL, NULL, FALSE, curbuf,
+ &retval);
+ apply_autocmds_retval(EVENT_BUFWINENTER, NULL, NULL, FALSE, curbuf,
+ &retval);
+ }
+ check_arg_idx(curwin);
+
+ /*
+ * If autocommands change the cursor position or topline, we should
+ * keep it.
+ */
+ if (curwin->w_cursor.lnum != lnum) {
+ newlnum = curwin->w_cursor.lnum;
+ newcol = curwin->w_cursor.col;
+ }
+ if (curwin->w_topline == topline)
+ topline = 0;
+
+ /* Even when cursor didn't move we need to recompute topline. */
+ changed_line_abv_curs();
+
+ maketitle();
+ }
+
+ /* Tell the diff stuff that this buffer is new and/or needs updating.
+ * Also needed when re-editing the same buffer, because unloading will
+ * have removed it as a diff buffer. */
+ if (curwin->w_p_diff) {
+ diff_buf_add(curbuf);
+ diff_invalidate(curbuf);
+ }
+
+ /* If the window options were changed may need to set the spell language.
+ * Can only do this after the buffer has been properly setup. */
+ if (did_get_winopts && curwin->w_p_spell && *curwin->w_s->b_p_spl != NUL)
+ (void)did_set_spelllang(curwin);
+
+ if (command == NULL) {
+ if (newcol >= 0) { /* position set by autocommands */
+ curwin->w_cursor.lnum = newlnum;
+ curwin->w_cursor.col = newcol;
+ check_cursor();
+ } else if (newlnum > 0) { /* line number from caller or old position */
+ curwin->w_cursor.lnum = newlnum;
+ check_cursor_lnum();
+ if (solcol >= 0 && !p_sol) {
+ /* 'sol' is off: Use last known column. */
+ curwin->w_cursor.col = solcol;
+ check_cursor_col();
+ curwin->w_cursor.coladd = 0;
+ curwin->w_set_curswant = TRUE;
+ } else
+ beginline(BL_SOL | BL_FIX);
+ } else { /* no line number, go to last line in Ex mode */
+ if (exmode_active)
+ curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
+ beginline(BL_WHITE | BL_FIX);
+ }
+ }
+
+ /* Check if cursors in other windows on the same buffer are still valid */
+ check_lnums(FALSE);
+
+ /*
+ * Did not read the file, need to show some info about the file.
+ * Do this after setting the cursor.
+ */
+ if (oldbuf
+ && !auto_buf
+ ) {
+ int msg_scroll_save = msg_scroll;
+
+ /* Obey the 'O' flag in 'cpoptions': overwrite any previous file
+ * message. */
+ if (shortmess(SHM_OVERALL) && !exiting && p_verbose == 0)
+ msg_scroll = FALSE;
+ if (!msg_scroll) /* wait a bit when overwriting an error msg */
+ check_for_delay(FALSE);
+ msg_start();
+ msg_scroll = msg_scroll_save;
+ msg_scrolled_ign = TRUE;
+
+ fileinfo(FALSE, TRUE, FALSE);
+
+ msg_scrolled_ign = FALSE;
+ }
+
+ if (command != NULL)
+ do_cmdline(command, NULL, NULL, DOCMD_VERBOSE);
+
+ if (curbuf->b_kmap_state & KEYMAP_INIT)
+ (void)keymap_init();
+
+ --RedrawingDisabled;
+ if (!skip_redraw) {
+ n = p_so;
+ if (topline == 0 && command == NULL)
+ p_so = 999; /* force cursor halfway the window */
+ update_topline();
+ curwin->w_scbind_pos = curwin->w_topline;
+ p_so = n;
+ redraw_curbuf_later(NOT_VALID); /* redraw this buffer later */
+ }
+
+ if (p_im)
+ need_start_insertmode = TRUE;
+
+ /* Change directories when the 'acd' option is set. */
+ DO_AUTOCHDIR
+
+
+theend:
+ if (did_set_swapcommand)
+ set_vim_var_string(VV_SWAPCOMMAND, NULL, -1);
+ vim_free(free_fname);
+ return retval;
+}
+
+static void delbuf_msg(name)
+char_u *name;
+{
+ EMSG2(_("E143: Autocommands unexpectedly deleted new buffer %s"),
+ name == NULL ? (char_u *)"" : name);
+ vim_free(name);
+ au_new_curbuf = NULL;
+}
+
+static int append_indent = 0; /* autoindent for first line */
+
+/*
+ * ":insert" and ":append", also used by ":change"
+ */
+void ex_append(eap)
+exarg_T *eap;
+{
+ char_u *theline;
+ int did_undo = FALSE;
+ linenr_T lnum = eap->line2;
+ int indent = 0;
+ char_u *p;
+ int vcol;
+ int empty = (curbuf->b_ml.ml_flags & ML_EMPTY);
+
+ /* the ! flag toggles autoindent */
+ if (eap->forceit)
+ curbuf->b_p_ai = !curbuf->b_p_ai;
+
+ /* First autoindent comes from the line we start on */
+ if (eap->cmdidx != CMD_change && curbuf->b_p_ai && lnum > 0)
+ append_indent = get_indent_lnum(lnum);
+
+ if (eap->cmdidx != CMD_append)
+ --lnum;
+
+ /* when the buffer is empty append to line 0 and delete the dummy line */
+ if (empty && lnum == 1)
+ lnum = 0;
+
+ State = INSERT; /* behave like in Insert mode */
+ if (curbuf->b_p_iminsert == B_IMODE_LMAP)
+ State |= LANGMAP;
+
+ for (;; ) {
+ msg_scroll = TRUE;
+ need_wait_return = FALSE;
+ if (curbuf->b_p_ai) {
+ if (append_indent >= 0) {
+ indent = append_indent;
+ append_indent = -1;
+ } else if (lnum > 0)
+ indent = get_indent_lnum(lnum);
+ }
+ ex_keep_indent = FALSE;
+ if (eap->getline == NULL) {
+ /* No getline() function, use the lines that follow. This ends
+ * when there is no more. */
+ if (eap->nextcmd == NULL || *eap->nextcmd == NUL)
+ break;
+ p = vim_strchr(eap->nextcmd, NL);
+ if (p == NULL)
+ p = eap->nextcmd + STRLEN(eap->nextcmd);
+ theline = vim_strnsave(eap->nextcmd, (int)(p - eap->nextcmd));
+ if (*p != NUL)
+ ++p;
+ eap->nextcmd = p;
+ } else
+ theline = eap->getline(
+ eap->cstack->cs_looplevel > 0 ? -1 :
+ NUL, eap->cookie, indent);
+ lines_left = Rows - 1;
+ if (theline == NULL)
+ break;
+
+ /* Using ^ CTRL-D in getexmodeline() makes us repeat the indent. */
+ if (ex_keep_indent)
+ append_indent = indent;
+
+ /* Look for the "." after automatic indent. */
+ vcol = 0;
+ for (p = theline; indent > vcol; ++p) {
+ if (*p == ' ')
+ ++vcol;
+ else if (*p == TAB)
+ vcol += 8 - vcol % 8;
+ else
+ break;
+ }
+ if ((p[0] == '.' && p[1] == NUL)
+ || (!did_undo && u_save(lnum, lnum + 1 + (empty ? 1 : 0))
+ == FAIL)) {
+ vim_free(theline);
+ break;
+ }
+
+ /* don't use autoindent if nothing was typed. */
+ if (p[0] == NUL)
+ theline[0] = NUL;
+
+ did_undo = TRUE;
+ ml_append(lnum, theline, (colnr_T)0, FALSE);
+ appended_lines_mark(lnum, 1L);
+
+ vim_free(theline);
+ ++lnum;
+
+ if (empty) {
+ ml_delete(2L, FALSE);
+ empty = FALSE;
+ }
+ }
+ State = NORMAL;
+
+ if (eap->forceit)
+ curbuf->b_p_ai = !curbuf->b_p_ai;
+
+ /* "start" is set to eap->line2+1 unless that position is invalid (when
+ * eap->line2 pointed to the end of the buffer and nothing was appended)
+ * "end" is set to lnum when something has been appended, otherwise
+ * it is the same than "start" -- Acevedo */
+ curbuf->b_op_start.lnum = (eap->line2 < curbuf->b_ml.ml_line_count) ?
+ eap->line2 + 1 : curbuf->b_ml.ml_line_count;
+ if (eap->cmdidx != CMD_append)
+ --curbuf->b_op_start.lnum;
+ curbuf->b_op_end.lnum = (eap->line2 < lnum)
+ ? lnum : curbuf->b_op_start.lnum;
+ curbuf->b_op_start.col = curbuf->b_op_end.col = 0;
+ curwin->w_cursor.lnum = lnum;
+ check_cursor_lnum();
+ beginline(BL_SOL | BL_FIX);
+
+ need_wait_return = FALSE; /* don't use wait_return() now */
+ ex_no_reprint = TRUE;
+}
+
+/*
+ * ":change"
+ */
+void ex_change(eap)
+exarg_T *eap;
+{
+ linenr_T lnum;
+
+ if (eap->line2 >= eap->line1
+ && u_save(eap->line1 - 1, eap->line2 + 1) == FAIL)
+ return;
+
+ /* the ! flag toggles autoindent */
+ if (eap->forceit ? !curbuf->b_p_ai : curbuf->b_p_ai)
+ append_indent = get_indent_lnum(eap->line1);
+
+ for (lnum = eap->line2; lnum >= eap->line1; --lnum) {
+ if (curbuf->b_ml.ml_flags & ML_EMPTY) /* nothing to delete */
+ break;
+ ml_delete(eap->line1, FALSE);
+ }
+
+ /* make sure the cursor is not beyond the end of the file now */
+ check_cursor_lnum();
+ deleted_lines_mark(eap->line1, (long)(eap->line2 - lnum));
+
+ /* ":append" on the line above the deleted lines. */
+ eap->line2 = eap->line1;
+ ex_append(eap);
+}
+
+void ex_z(eap)
+exarg_T *eap;
+{
+ char_u *x;
+ int 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)
+ bigness = curwin->w_p_scr * 2;
+ else
+ bigness = curwin->w_height - 3;
+ if (bigness < 1)
+ bigness = 1;
+
+ x = eap->arg;
+ kind = x;
+ if (*kind == '-' || *kind == '+' || *kind == '='
+ || *kind == '^' || *kind == '.')
+ ++x;
+ while (*x == '-' || *x == '+')
+ ++x;
+
+ if (*x != 0) {
+ if (!VIM_ISDIGIT(*x)) {
+ EMSG(_("E144: non-numeric argument to :z"));
+ return;
+ } else {
+ bigness = atoi((char *)x);
+ p_window = bigness;
+ if (*kind == '=')
+ bigness += 2;
+ }
+ }
+
+ /* the number of '-' and '+' multiplies the distance */
+ if (*kind == '-' || *kind == '+')
+ for (x = kind + 1; *x == *kind; ++x)
+ ;
+
+ switch (*kind) {
+ case '-':
+ start = lnum - bigness * (linenr_T)(x - kind) + 1;
+ end = start + bigness - 1;
+ curs = end;
+ break;
+
+ case '=':
+ start = lnum - (bigness + 1) / 2 + 1;
+ end = lnum + (bigness + 1) / 2 - 1;
+ curs = lnum;
+ minus = 1;
+ break;
+
+ case '^':
+ start = lnum - bigness * 2;
+ end = lnum - bigness;
+ curs = lnum - bigness;
+ break;
+
+ case '.':
+ start = lnum - (bigness + 1) / 2 + 1;
+ end = lnum + (bigness + 1) / 2 - 1;
+ curs = end;
+ break;
+
+ default: /* '+' */
+ start = lnum;
+ if (*kind == '+')
+ start += bigness * (linenr_T)(x - kind - 1) + 1;
+ else if (eap->addr_count == 0)
+ ++start;
+ end = start + bigness - 1;
+ curs = end;
+ break;
+ }
+
+ if (start < 1)
+ start = 1;
+
+ if (end > curbuf->b_ml.ml_line_count)
+ end = curbuf->b_ml.ml_line_count;
+
+ if (curs > curbuf->b_ml.ml_line_count)
+ curs = curbuf->b_ml.ml_line_count;
+
+ for (i = start; i <= end; i++) {
+ if (minus && i == lnum) {
+ msg_putchar('\n');
+
+ for (j = 1; j < Columns; j++)
+ msg_putchar('-');
+ }
+
+ print_line(i, eap->flags & EXFLAG_NR, eap->flags & EXFLAG_LIST);
+
+ if (minus && i == lnum) {
+ msg_putchar('\n');
+
+ for (j = 1; j < Columns; j++)
+ msg_putchar('-');
+ }
+ }
+
+ curwin->w_cursor.lnum = curs;
+ ex_no_reprint = TRUE;
+}
+
+/*
+ * Check if the restricted flag is set.
+ * If so, give an error message and return TRUE.
+ * Otherwise, return FALSE.
+ */
+int check_restricted() {
+ if (restricted) {
+ EMSG(_("E145: Shell commands not allowed in rvim"));
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*
+ * Check if the secure flag is set (.exrc or .vimrc in current directory).
+ * If so, give an error message and return TRUE.
+ * Otherwise, return FALSE.
+ */
+int check_secure() {
+ if (secure) {
+ secure = 2;
+ EMSG(_(e_curdir));
+ return TRUE;
+ }
+#ifdef HAVE_SANDBOX
+ /*
+ * In the sandbox more things are not allowed, including the things
+ * disallowed in secure mode.
+ */
+ if (sandbox != 0) {
+ EMSG(_(e_sandbox));
+ return TRUE;
+ }
+#endif
+ return FALSE;
+}
+
+static char_u *old_sub = NULL; /* previous substitute pattern */
+static int global_need_beginline; /* call beginline() after ":g" */
+
+/* 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(eap)
+exarg_T *eap;
+{
+ 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 int 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 */
+ char_u *pat = NULL, *sub = NULL; /* init for GCC */
+ int delimiter;
+ int sublen;
+ int got_quit = FALSE;
+ int got_match = FALSE;
+ int temp;
+ 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 */
+ 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 */
+ pos_T old_cursor = curwin->w_cursor;
+ int start_nsubs;
+ int save_ma = 0;
+
+ cmd = eap->arg;
+ if (!global_busy) {
+ sub_nsubs = 0;
+ sub_nlines = 0;
+ }
+ start_nsubs = sub_nsubs;
+
+ if (eap->cmdidx == CMD_tilde)
+ which_pat = RE_LAST; /* use last used regexp */
+ else
+ which_pat = RE_SUBST; /* use last substitute regexp */
+
+ /* new pattern and substitution */
+ if (eap->cmd[0] == 's' && *cmd != NUL && !vim_iswhite(*cmd)
+ && vim_strchr((char_u *)"0123456789cegriIp|\"", *cmd) == NULL) {
+ /* don't accept alphanumeric for separator */
+ if (isalpha(*cmd)) {
+ EMSG(_("E146: Regular expressions can't be delimited by letters"));
+ return;
+ }
+ /*
+ * undocumented vi feature:
+ * "\/sub/" and "\?sub?" use last used search pattern (almost like
+ * //sub/r). "\&sub&" use last substitute pattern (like //sub/).
+ */
+ if (*cmd == '\\') {
+ ++cmd;
+ if (vim_strchr((char_u *)"/?&", *cmd) == NULL) {
+ EMSG(_(e_backslash));
+ return;
+ }
+ 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)
+ lrF_sub(cmd);
+ 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 */
+ }
+
+ /*
+ * Small incompatibility: vi sees '\n' as end of the command, but in
+ * Vim we want to use '\n' to find/substitute a NUL.
+ */
+ sub = cmd; /* remember the start of the substitution */
+
+ while (cmd[0]) {
+ if (cmd[0] == delimiter) { /* end delimiter found */
+ *cmd++ = NUL; /* replace it with a NUL */
+ break;
+ }
+ if (cmd[0] == '\\' && cmd[1] != 0) /* skip escaped characters */
+ ++cmd;
+ mb_ptr_adv(cmd);
+ }
+
+ if (!eap->skip) {
+ /* In POSIX vi ":s/pat/%/" uses the previous subst. string. */
+ if (STRCMP(sub, "%") == 0
+ && vim_strchr(p_cpo, CPO_SUBPERCENT) != NULL) {
+ if (old_sub == NULL) { /* there is no previous command */
+ EMSG(_(e_nopresub));
+ return;
+ }
+ sub = old_sub;
+ } else {
+ vim_free(old_sub);
+ old_sub = vim_strsave(sub);
+ }
+ }
+ } else if (!eap->skip) { /* use previous pattern and substitution */
+ if (old_sub == NULL) { /* there is no previous command */
+ EMSG(_(e_nopresub));
+ return;
+ }
+ pat = NULL; /* search_regcomp() will use previous pattern */
+ sub = old_sub;
+
+ /* Vi compatibility quirk: repeating with ":s" keeps the cursor in the
+ * last column after using "$". */
+ endcolumn = (curwin->w_curswant == MAXCOL);
+ }
+
+ /*
+ * Find trailing options. When '&' is used, keep old options.
+ */
+ if (*cmd == '&')
+ ++cmd;
+ else {
+ if (!p_ed) {
+ if (p_gd) /* default is global on */
+ do_all = TRUE;
+ else
+ do_all = 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, also when p_ed is off.
+ * '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;
+
+ /*
+ * check for a trailing count
+ */
+ cmd = skipwhite(cmd);
+ if (VIM_ISDIGIT(*cmd)) {
+ i = getdigits(&cmd);
+ if (i <= 0 && !eap->skip && do_error) {
+ EMSG(_(e_zerocount));
+ return;
+ }
+ eap->line1 = eap->line2;
+ eap->line2 += i - 1;
+ if (eap->line2 > curbuf->b_ml.ml_line_count)
+ eap->line2 = curbuf->b_ml.ml_line_count;
+ }
+
+ /*
+ * check for trailing command or garbage
+ */
+ cmd = skipwhite(cmd);
+ if (*cmd && *cmd != '"') { /* if not end-of-line or comment */
+ eap->nextcmd = check_nextcmd(cmd);
+ if (eap->nextcmd == NULL) {
+ EMSG(_(e_trailing));
+ return;
+ }
+ }
+
+ if (eap->skip) /* not executing commands, only parsing */
+ return;
+
+ if (!do_count && !curbuf->b_p_ma) {
+ /* Substitution is not allowed in non-'modifiable' buffer */
+ EMSG(_(e_modifiable));
+ return;
+ }
+
+ if (search_regcomp(pat, RE_SUBST, which_pat, SEARCH_HIS,
+ &regmatch) == FAIL) {
+ if (do_error)
+ EMSG(_(e_invcmd));
+ return;
+ }
+
+ /* 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;
+
+ sub_firstline = NULL;
+
+ /*
+ * ~ in the substitute pattern is replaced with the old pattern.
+ * We do it here once to avoid it to be replaced over and over again.
+ * But don't do it when it starts with "\=", then it's an expression.
+ */
+ 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);
+ 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 */
+
+ /*
+ * The new text is build up step by step, to avoid too much
+ * copying. There are these pieces:
+ * sub_firstline The old text, unmodified.
+ * copycol Column in the old text where we started
+ * looking for a match; from here old text still
+ * needs to be copied to the new text.
+ * matchcol Column number of the old text where to look
+ * for the next match. It's just after the
+ * previous match or one further.
+ * prev_matchcol Column just after the previous match (if any).
+ * Mostly equal to matchcol, except for the first
+ * match and after skipping an empty match.
+ * regmatch.*pos Where the pattern matched in the old text.
+ * new_start The new text, all that has been produced so
+ * far.
+ * new_end The new text, where to append new text.
+ *
+ * lnum The line number where we found the start of
+ * the match. Can be below the line we searched
+ * when there is a \n before a \zs in the
+ * pattern.
+ * sub_firstlnum The line number in the buffer where to look
+ * for a match. Can be different from "lnum"
+ * when the pattern or substitute string contains
+ * line breaks.
+ *
+ * Special situations:
+ * - When the substitute string contains a line break, the part up
+ * to the line break is inserted in the text, but the copy of
+ * the original line is kept. "sub_firstlnum" is adjusted for
+ * the inserted lines.
+ * - When the matched pattern contains a line break, the old line
+ * is taken from the line at the end of the pattern. The lines
+ * in the match are deleted later, "sub_firstlnum" is adjusted
+ * accordingly.
+ *
+ * The new text is built up in new_start[]. It has some extra
+ * room to avoid using alloc()/free() too often. new_start_len is
+ * the length of the allocated memory at new_start.
+ *
+ * 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_"
+ * pointers point into this copy.
+ */
+ sub_firstlnum = lnum;
+ copycol = 0;
+ matchcol = 0;
+
+ /* At first match, remember current cursor position. */
+ if (!got_match) {
+ setpcmark();
+ got_match = TRUE;
+ }
+
+ /*
+ * Loop until nothing more to replace in this line.
+ * 1. Handle match with empty string.
+ * 2. If do_ask is set, ask for confirmation.
+ * 3. substitute the string.
+ * 4. if 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. */
+ if (regmatch.startpos[0].lnum > 0) {
+ lnum += regmatch.startpos[0].lnum;
+ sub_firstlnum += regmatch.startpos[0].lnum;
+ nmatch -= regmatch.startpos[0].lnum;
+ vim_free(sub_firstline);
+ sub_firstline = NULL;
+ }
+
+ if (sub_firstline == NULL) {
+ sub_firstline = vim_strsave(ml_get(sub_firstlnum));
+ if (sub_firstline == NULL) {
+ vim_free(new_start);
+ goto outofmem;
+ }
+ }
+
+ /* Save the line number of the last change for the final
+ * cursor position (just like Vi). */
+ curwin->w_cursor.lnum = lnum;
+ do_again = FALSE;
+
+ /*
+ * 1. Match empty string does not count, except for first
+ * match. This reproduces the strange vi behaviour.
+ * This also catches endless loops.
+ */
+ if (matchcol == prev_matchcol
+ && regmatch.endpos[0].lnum == 0
+ && matchcol == regmatch.endpos[0].col) {
+ if (sub_firstline[matchcol] == NUL)
+ /* We already were at the end of the line. Don't look
+ * for a match in this line again. */
+ skip_match = TRUE;
+ else {
+ /* search for a match at next column */
+ if (has_mbyte)
+ matchcol += mb_ptr2len(sub_firstline + matchcol);
+ else
+ ++matchcol;
+ }
+ goto skip;
+ }
+
+ /* Normally we continue searching for a match just after the
+ * previous match. */
+ 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. */
+ if (nmatch > 1) {
+ matchcol = (colnr_T)STRLEN(sub_firstline);
+ nmatch = 1;
+ skip_match = TRUE;
+ }
+ sub_nsubs++;
+ did_sub = TRUE;
+ /* Skip the substitution, unless an expression is used,
+ * then it is evaluated in the sandbox. */
+ if (!(sub[0] == '\\' && sub[1] == '='))
+ goto skip;
+ }
+
+ if (do_ask) {
+ int typed = 0;
+
+ /* change State to CONFIRM, so that the mouse works
+ * properly */
+ save_State = State;
+ State = CONFIRM;
+ setmouse(); /* disable mouse in xterm */
+ curwin->w_cursor.col = regmatch.startpos[0].col;
+
+ /* When 'cpoptions' contains "u" don't sync undo when
+ * asking for confirmation. */
+ if (vim_strchr(p_cpo, CPO_UNDO) != NULL)
+ ++no_u_sync;
+
+ /*
+ * Loop until 'y', 'n', 'q', CTRL-E or CTRL-Y typed.
+ */
+ while (do_ask) {
+ if (exmode_active) {
+ char_u *resp;
+ colnr_T sc, ec;
+
+ print_line_no_prefix(lnum, do_number, do_list);
+
+ getvcol(curwin, &curwin->w_cursor, &sc, NULL, NULL);
+ curwin->w_cursor.col = regmatch.endpos[0].col - 1;
+ getvcol(curwin, &curwin->w_cursor, NULL, NULL, &ec);
+ if (do_number || curwin->w_p_nu) {
+ int numw = number_width(curwin) + 1;
+ sc += numw;
+ ec += numw;
+ }
+ msg_start();
+ for (i = 0; i < (long)sc; ++i)
+ msg_putchar(' ');
+ for (; i <= (long)ec; ++i)
+ msg_putchar('^');
+
+ resp = getexmodeline('?', NULL, 0);
+ if (resp != NULL) {
+ typed = *resp;
+ vim_free(resp);
+ }
+ } else {
+ char_u *orig_line = NULL;
+ int len_change = 0;
+ int save_p_fen = curwin->w_p_fen;
+
+ curwin->w_p_fen = FALSE;
+ /* Invert the matched string.
+ * Remove the inversion afterwards. */
+ temp = RedrawingDisabled;
+ RedrawingDisabled = 0;
+
+ if (new_start != NULL) {
+ /* There already was a substitution, we would
+ * like to show this to the user. We cannot
+ * really update the line, it would change
+ * what matches. Temporarily replace the line
+ * and change it back afterwards. */
+ orig_line = vim_strsave(ml_get(lnum));
+ if (orig_line != NULL) {
+ char_u *new_line = concat_str(new_start,
+ sub_firstline + copycol);
+
+ if (new_line == NULL) {
+ vim_free(orig_line);
+ orig_line = NULL;
+ } else {
+ /* Position the cursor relative to the
+ * end of the line, the previous
+ * substitute may have inserted or
+ * deleted characters 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);
+ }
+ }
+ }
+
+ search_match_lines = regmatch.endpos[0].lnum
+ - regmatch.startpos[0].lnum;
+ search_match_endcol = regmatch.endpos[0].col
+ + len_change;
+ highlight_match = TRUE;
+
+ update_topline();
+ validate_cursor();
+ update_screen(SOME_VALID);
+ highlight_match = FALSE;
+ redraw_later(SOME_VALID);
+
+ curwin->w_p_fen = save_p_fen;
+ if (msg_row == Rows - 1)
+ msg_didout = FALSE; /* avoid a scroll-up */
+ msg_starthere();
+ i = msg_scroll;
+ msg_scroll = 0; /* truncate msg when
+ needed */
+ msg_no_more = TRUE;
+ /* write message same highlighting as for
+ * wait_return */
+ smsg_attr(hl_attr(HLF_R),
+ (char_u *)_("replace with %s (y/n/a/q/l/^E/^Y)?"), sub);
+ msg_no_more = FALSE;
+ msg_scroll = i;
+ showruler(TRUE);
+ windgoto(msg_row, msg_col);
+ RedrawingDisabled = temp;
+
+#ifdef USE_ON_FLY_SCROLL
+ dont_scroll = FALSE; /* allow scrolling here */
+#endif
+ ++no_mapping; /* don't map this key */
+ ++allow_keys; /* allow special keys */
+ typed = plain_vgetc();
+ --allow_keys;
+ --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);
+ }
+
+ 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;
+ break;
+ }
+ if (typed == 'n')
+ break;
+ if (typed == 'y')
+ break;
+ if (typed == 'l') {
+ /* last: replace and then stop */
+ do_all = FALSE;
+ line2 = lnum;
+ break;
+ }
+ if (typed == 'a') {
+ do_ask = FALSE;
+ break;
+ }
+ if (typed == Ctrl_E)
+ scrollup_clamp();
+ else if (typed == Ctrl_Y)
+ scrolldown_clamp();
+ }
+ State = save_State;
+ setmouse();
+ if (vim_strchr(p_cpo, CPO_UNDO) != NULL)
+ --no_u_sync;
+
+ if (typed == 'n') {
+ /* 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" and ":%s/\n/,\r/gc"
+ * get stuck when pressing 'n'. */
+ if (nmatch > 1) {
+ matchcol = (colnr_T)STRLEN(sub_firstline);
+ skip_match = TRUE;
+ }
+ goto skip;
+ }
+ if (got_quit)
+ goto skip;
+ }
+
+ /* Move the cursor to the start of the match, so that we can
+ * 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. */
+ if (nmatch > curbuf->b_ml.ml_line_count - sub_firstlnum + 1) {
+ nmatch = curbuf->b_ml.ml_line_count - sub_firstlnum + 1;
+ 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 alloc()/free()).
+ */
+ new_start_len = needed_len + 50;
+ if ((new_start = alloc_check(new_start_len)) == NULL)
+ goto outofmem;
+ *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 alloc()/free()).
+ */
+ len = (unsigned)STRLEN(new_start);
+ needed_len += len;
+ if (needed_len > (int)new_start_len) {
+ new_start_len = needed_len + 50;
+ if ((p1 = alloc_check(new_start_len)) == NULL) {
+ vim_free(new_start);
+ goto outofmem;
+ }
+ mch_memmove(p1, new_start, (size_t)(len + 1));
+ vim_free(new_start);
+ new_start = p1;
+ }
+ new_end = new_start + len;
+ }
+
+ /*
+ * copy the text up to the part that matched
+ */
+ mch_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;
+ vim_free(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;
+ }
+
+ /* 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. */
+ vim_free(sub_firstline);
+ sub_firstline = vim_strsave((char_u *)"");
+ copycol = 0;
+ }
+
+ /*
+ * 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;
+ }
+ /* 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;
+ }
+
+ /*
+ * 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.
+ */
+skip:
+ /* We already know that we did the last subst when we are at
+ * the end of the line, except that a pattern like
+ * "bar\|\nfoo" may match at the NUL. "lnum" can be below
+ * "line2" when there is a \zs in the pattern after a line
+ * break. */
+ lastone = (skip_match
+ || got_int
+ || got_quit
+ || lnum > line2
+ || !(do_all || do_again)
+ || (sub_firstline[matchcol] == NUL && nmatch <= 1
+ && !re_multiline(regmatch.regprog)));
+ nmatch = -1;
+
+ /*
+ * Replace the line in the buffer when needed. This is
+ * skipped when there are more matches.
+ * The check for nmatch_tl is needed for when multi-line
+ * matching must replace the lines before trying to do another
+ * match, otherwise "\@<=" won't work.
+ * When the match starts below where we start searching also
+ * need to replace the line first (using \zs after \n).
+ */
+ if (lastone
+ || nmatch_tl > 0
+ || (nmatch = vim_regexec_multi(&regmatch, curwin,
+ curbuf, sub_firstlnum,
+ matchcol, NULL)) == 0
+ || regmatch.startpos[0].lnum > 0) {
+ if (new_start != NULL) {
+ /*
+ * Copy the rest of the line, that didn't match.
+ * "matchcol" has to be adjusted, we use the end of
+ * the line as reference, because the substitute may
+ * have changed the number of characters. Same for
+ * "prev_matchcol".
+ */
+ STRCAT(new_start, sub_firstline + copycol);
+ matchcol = (colnr_T)STRLEN(sub_firstline) - matchcol;
+ prev_matchcol = (colnr_T)STRLEN(sub_firstline)
+ - prev_matchcol;
+
+ if (u_savesub(lnum) != OK)
+ break;
+ ml_replace(lnum, new_start, TRUE);
+
+ if (nmatch_tl > 0) {
+ /*
+ * Matched lines have now been substituted and are
+ * useless, delete them. The part after the match
+ * has been appended to new_start, we don't need
+ * it in the buffer.
+ */
+ ++lnum;
+ if (u_savedel(lnum, nmatch_tl) != OK)
+ break;
+ 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)
+ deleted_lines(lnum, nmatch_tl);
+ --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)
+ changed_bytes(lnum, 0);
+ else {
+ if (first_line == 0)
+ first_line = lnum;
+ last_line = lnum + 1;
+ }
+
+ sub_firstlnum = lnum;
+ vim_free(sub_firstline); /* free the temp buffer */
+ sub_firstline = new_start;
+ new_start = NULL;
+ matchcol = (colnr_T)STRLEN(sub_firstline) - matchcol;
+ prev_matchcol = (colnr_T)STRLEN(sub_firstline)
+ - prev_matchcol;
+ copycol = 0;
+ }
+ if (nmatch == -1 && !lastone)
+ nmatch = vim_regexec_multi(&regmatch, curwin, curbuf,
+ sub_firstlnum, matchcol, NULL);
+
+ /*
+ * 5. break if there isn't another match in this line
+ */
+ if (nmatch <= 0) {
+ /* If the match found didn't start where we were
+ * searching, do the next search in the line where we
+ * found the match. */
+ if (nmatch == -1)
+ lnum -= regmatch.startpos[0].lnum;
+ break;
+ }
+ }
+
+ line_breakcheck();
+ }
+
+ if (did_sub)
+ ++sub_nlines;
+ vim_free(new_start); /* for when substitute was cancelled */
+ vim_free(sub_firstline); /* free the copy of the original line */
+ sub_firstline = NULL;
+ }
+
+ line_breakcheck();
+ }
+
+ if (first_line != 0) {
+ /* Need to subtract the number of added lines from "last_line" to get
+ * 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);
+ }
+
+outofmem:
+ vim_free(sub_firstline); /* may have to free allocated copy of the line */
+
+ /* ":s/pat//n" doesn't move the cursor */
+ if (do_count)
+ curwin->w_cursor = old_cursor;
+
+ if (sub_nsubs > start_nsubs) {
+ /* Set the '[ and '] marks. */
+ curbuf->b_op_start.lnum = eap->line1;
+ curbuf->b_op_end.lnum = line2;
+ 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)
+ coladvance((colnr_T)MAXCOL);
+ else
+ beginline(BL_WHITE | BL_FIX);
+ }
+ if (!do_sub_msg(do_count) && do_ask)
+ MSG("");
+ } else
+ global_need_beginline = TRUE;
+ if (do_print)
+ print_line(curwin->w_cursor.lnum, do_number, do_list);
+ } else if (!global_busy) {
+ if (got_int) /* interrupted */
+ EMSG(_(e_interr));
+ else if (got_match) /* did find something but nothing substituted */
+ MSG("");
+ else if (do_error) /* nothing found */
+ EMSG2(_(e_patnotf2), get_search_pat());
+ }
+
+ if (do_ask && hasAnyFolding(curwin))
+ /* Cursor position may require updating */
+ changed_window_setting();
+
+ vim_regfree(regmatch.regprog);
+}
+
+/*
+ * Give message for number of substitutions.
+ * Can also be used after a ":global" command.
+ * Return TRUE if a message was given.
+ */
+int do_sub_msg(count_only)
+int count_only; /* used 'n' flag for ":s" */
+{
+ /*
+ * Only report substitutions when:
+ * - more than 'report' substitutions
+ * - command was typed by user, or number of changed lines > 'report'
+ * - giving messages is not disabled by 'lazyredraw'
+ */
+ if (((sub_nsubs > p_report && (KeyTyped || sub_nlines > 1 || p_report < 1))
+ || count_only)
+ && messaging()) {
+ if (got_int)
+ STRCPY(msg_buf, _("(Interrupted) "));
+ else
+ *msg_buf = NUL;
+ if (sub_nsubs == 1)
+ vim_snprintf_add((char *)msg_buf, sizeof(msg_buf),
+ "%s", count_only ? _("1 match") : _("1 substitution"));
+ else
+ vim_snprintf_add((char *)msg_buf, sizeof(msg_buf),
+ count_only ? _("%ld matches") : _("%ld substitutions"),
+ sub_nsubs);
+ if (sub_nlines == 1)
+ vim_snprintf_add((char *)msg_buf, sizeof(msg_buf),
+ "%s", _(" on 1 line"));
+ else
+ vim_snprintf_add((char *)msg_buf, sizeof(msg_buf),
+ _(" on %ld lines"), (long)sub_nlines);
+ if (msg(msg_buf))
+ /* save message to display it after redraw */
+ set_keep_msg(msg_buf, 0);
+ return TRUE;
+ }
+ if (got_int) {
+ EMSG(_(e_interr));
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*
+ * Execute a global command of the form:
+ *
+ * g/pattern/X : execute X on all lines where pattern matches
+ * v/pattern/X : execute X on all lines where pattern does not match
+ *
+ * where 'X' is an EX command
+ *
+ * The command character (as well as the trailing slash) is optional, and
+ * is assumed to be 'p' if missing.
+ *
+ * This is implemented in two passes: first we scan the file for the pattern and
+ * set a mark for each line that (not) matches. Secondly we execute the command
+ * for each line that has a mark. This is required because after deleting
+ * lines we do not know where to search for the next match.
+ */
+void ex_global(eap)
+exarg_T *eap;
+{
+ linenr_T lnum; /* line number according to old situation */
+ int ndone = 0;
+ int type; /* first char of cmd: 'v' or 'g' */
+ char_u *cmd; /* command argument */
+
+ char_u delim; /* delimiter, normally '/' */
+ char_u *pat;
+ regmmatch_T regmatch;
+ int match;
+ int which_pat;
+
+ if (global_busy) {
+ EMSG(_("E147: Cannot do :global recursive")); /* will increment global_busy */
+ return;
+ }
+
+ if (eap->forceit) /* ":global!" is like ":vglobal" */
+ type = 'v';
+ else
+ type = *eap->cmd;
+ cmd = eap->arg;
+ which_pat = RE_LAST; /* default: use last used regexp */
+
+ /*
+ * undocumented vi feature:
+ * "\/" and "\?": use previous search pattern.
+ * "\&": use previous substitute pattern.
+ */
+ if (*cmd == '\\') {
+ ++cmd;
+ if (vim_strchr((char_u *)"/?&", *cmd) == NULL) {
+ EMSG(_(e_backslash));
+ return;
+ }
+ if (*cmd == '&')
+ which_pat = RE_SUBST; /* use previous substitute pattern */
+ else
+ which_pat = RE_SEARCH; /* use previous search pattern */
+ ++cmd;
+ pat = (char_u *)"";
+ } else if (*cmd == NUL) {
+ EMSG(_("E148: Regular expression missing from global"));
+ return;
+ } else {
+ delim = *cmd; /* get the delimiter */
+ if (delim)
+ ++cmd; /* skip delimiter if there is one */
+ pat = cmd; /* remember start of pattern */
+ cmd = skip_regexp(cmd, delim, p_magic, &eap->arg);
+ if (cmd[0] == delim) /* end delimiter found */
+ *cmd++ = NUL; /* replace it with a NUL */
+ }
+
+ if (p_altkeymap && curwin->w_p_rl)
+ lrFswap(pat,0);
+
+ if (search_regcomp(pat, RE_BOTH, which_pat, SEARCH_HIS, &regmatch) == FAIL) {
+ EMSG(_(e_invcmd));
+ 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? */
+ 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();
+ }
+
+ /*
+ * 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((char_u *)_("Pattern found in every line: %s"), pat);
+ else
+ smsg((char_u *)_("Pattern not found: %s"), pat);
+ } else
+ global_exe(cmd);
+
+ ml_clearmarked(); /* clear rest of the marks */
+ vim_regfree(regmatch.regprog);
+}
+
+/*
+ * Execute "cmd" on lines marked with ml_setmarked().
+ */
+void global_exe(cmd)
+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.
+ */
+ setpcmark();
+
+ /* When the command writes a message, don't overwrite the command. */
+ msg_didout = TRUE;
+
+ sub_nsubs = 0;
+ sub_nlines = 0;
+ 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);
+ ui_breakcheck();
+ }
+
+ global_busy = 0;
+ if (global_need_beginline)
+ beginline(BL_WHITE | BL_FIX);
+ 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 */
+ 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 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);
+}
+
+int read_viminfo_sub_string(virp, force)
+vir_T *virp;
+int force;
+{
+ if (force)
+ vim_free(old_sub);
+ if (force || old_sub == NULL)
+ old_sub = viminfo_readstring(virp, 1, TRUE);
+ return viminfo_readline(virp);
+}
+
+void write_viminfo_sub_string(fp)
+FILE *fp;
+{
+ if (get_viminfo_parameter('/') != 0 && old_sub != NULL) {
+ fputs(_("\n# Last Substitute String:\n$"), fp);
+ viminfo_writestring(fp, old_sub);
+ }
+}
+
+#if defined(EXITFREE) || defined(PROTO)
+void free_old_sub() {
+ vim_free(old_sub);
+}
+
+#endif
+
+/*
+ * Set up for a tagpreview.
+ * Return TRUE when it was created.
+ */
+int prepare_tagpreview(undo_sync)
+int undo_sync; /* sync undo when leaving the window */
+{
+ win_T *wp;
+
+
+ /*
+ * If there is already a preview window open, use that one.
+ */
+ if (!curwin->w_p_pvw) {
+ for (wp = firstwin; wp != NULL; wp = wp->w_next)
+ if (wp->w_p_pvw)
+ break;
+ if (wp != NULL)
+ win_enter(wp, undo_sync);
+ else {
+ /*
+ * There is no preview window open yet. Create one.
+ */
+ if (win_split(g_do_tagpreview > 0 ? g_do_tagpreview : 0, 0)
+ == FAIL)
+ return FALSE;
+ curwin->w_p_pvw = TRUE;
+ curwin->w_p_wfh = TRUE;
+ RESET_BINDING(curwin); /* don't take over 'scrollbind'
+ and 'cursorbind' */
+ curwin->w_p_diff = FALSE; /* no 'diff' */
+ curwin->w_p_fdc = 0; /* no 'foldcolumn' */
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+
+
+/*
+ * ":help": open a read-only window on a help file
+ */
+void ex_help(eap)
+exarg_T *eap;
+{
+ char_u *arg;
+ char_u *tag;
+ FILE *helpfd; /* file descriptor of help file */
+ int n;
+ int i;
+ win_T *wp;
+ int num_matches;
+ char_u **matches;
+ char_u *p;
+ int empty_fnum = 0;
+ int alt_fnum = 0;
+ buf_T *buf;
+ int len;
+ char_u *lang;
+ int old_KeyTyped = KeyTyped;
+
+ if (eap != NULL) {
+ /*
+ * A ":help" command ends at the first LF, or at a '|' that is
+ * followed by some text. Set nextcmd to the following command.
+ */
+ for (arg = eap->arg; *arg; ++arg) {
+ if (*arg == '\n' || *arg == '\r'
+ || (*arg == '|' && arg[1] != NUL && arg[1] != '|')) {
+ *arg++ = NUL;
+ eap->nextcmd = arg;
+ break;
+ }
+ }
+ arg = eap->arg;
+
+ if (eap->forceit && *arg == NUL && !curbuf->b_help) {
+ EMSG(_("E478: Don't panic!"));
+ return;
+ }
+
+ if (eap->skip) /* not executing commands */
+ return;
+ } else
+ arg = (char_u *)"";
+
+ /* remove trailing blanks */
+ p = arg + STRLEN(arg) - 1;
+ while (p > arg && vim_iswhite(*p) && p[-1] != '\\')
+ *p-- = NUL;
+
+ /* Check for a specified language */
+ lang = check_help_lang(arg);
+
+ /* When no argument given go to the index. */
+ if (*arg == NUL)
+ arg = (char_u *)"help.txt";
+
+ /*
+ * Check if there is a match for the argument.
+ */
+ n = find_help_tags(arg, &num_matches, &matches,
+ eap != NULL && eap->forceit);
+
+ i = 0;
+ if (n != FAIL && lang != NULL)
+ /* Find first item with the requested language. */
+ for (i = 0; i < num_matches; ++i) {
+ len = (int)STRLEN(matches[i]);
+ if (len > 3 && matches[i][len - 3] == '@'
+ && STRICMP(matches[i] + len - 2, lang) == 0)
+ break;
+ }
+ if (i >= num_matches || n == FAIL) {
+ if (lang != NULL)
+ EMSG3(_("E661: Sorry, no '%s' help for %s"), lang, arg);
+ else
+ EMSG2(_("E149: Sorry, no help for %s"), arg);
+ if (n != FAIL)
+ FreeWild(num_matches, matches);
+ return;
+ }
+
+ /* The first match (in the requested language) is the best match. */
+ tag = vim_strsave(matches[i]);
+ FreeWild(num_matches, matches);
+
+
+ /*
+ * 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
+ || 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)
+ break;
+ 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.
+ */
+ if ((helpfd = mch_fopen((char *)p_hf, READBIN)) == NULL) {
+ smsg((char_u *)_("Sorry, help file \"%s\" not found"), p_hf);
+ goto erret;
+ }
+ fclose(helpfd);
+
+ /* Split off help window; put it at far top if no position
+ * specified, the current window is vertically split and
+ * narrow. */
+ n = WSP_HELP;
+ if (cmdmod.split == 0 && curwin->w_width != Columns
+ && curwin->w_width < 80)
+ n |= WSP_TOP;
+ if (win_split(0, n) == FAIL)
+ goto erret;
+
+ if (curwin->w_height < p_hh)
+ win_setheight((int)p_hh);
+
+ /*
+ * Open help file (do_ecmd() will set b_help flag, readfile() will
+ * set b_p_ro flag).
+ * Set the alternate file to the previously edited file.
+ */
+ alt_fnum = curbuf->b_fnum;
+ (void)do_ecmd(0, NULL, NULL, NULL, ECMD_LASTL,
+ ECMD_HIDE + ECMD_SET_HELP,
+ NULL /* buffer is still open, don't store info */
+ );
+ if (!cmdmod.keepalt)
+ curwin->w_alt_fnum = alt_fnum;
+ empty_fnum = curbuf->b_fnum;
+ }
+ }
+
+ if (!p_im)
+ restart_edit = 0; /* don't want insert mode in help file */
+
+ /* Restore KeyTyped, setting 'filetype=help' may reset it.
+ * It is needed for do_tag top open folds under the cursor. */
+ KeyTyped = old_KeyTyped;
+
+ if (tag != NULL)
+ do_tag(tag, DT_HELP, 1, FALSE, TRUE);
+
+ /* Delete the empty buffer if we're not using it. Careful: autocommands
+ * may have jumped to another window, check that the buffer is not in a
+ * window. */
+ if (empty_fnum != 0 && curbuf->b_fnum != empty_fnum) {
+ buf = buflist_findnr(empty_fnum);
+ if (buf != NULL && buf->b_nwindows == 0)
+ wipe_buffer(buf, TRUE);
+ }
+
+ /* keep the previous alternate file */
+ if (alt_fnum != 0 && curwin->w_alt_fnum == empty_fnum && !cmdmod.keepalt)
+ curwin->w_alt_fnum = alt_fnum;
+
+erret:
+ vim_free(tag);
+}
+
+
+/*
+ * In an argument search for a language specifiers in the form "@xx".
+ * Changes the "@" to NUL if found, and returns a pointer to "xx".
+ * Returns NULL if not found.
+ */
+char_u * check_help_lang(arg)
+char_u *arg;
+{
+ int len = (int)STRLEN(arg);
+
+ if (len >= 3 && arg[len - 3] == '@' && ASCII_ISALPHA(arg[len - 2])
+ && ASCII_ISALPHA(arg[len - 1])) {
+ arg[len - 3] = NUL; /* remove the '@' */
+ return arg + len - 2;
+ }
+ return NULL;
+}
+
+/*
+ * Return a heuristic indicating how well the given string matches. The
+ * smaller the number, the better the match. This is the order of priorities,
+ * from best match to worst match:
+ * - Match with least alpha-numeric characters is better.
+ * - Match with least total characters is better.
+ * - Match towards the start is better.
+ * - Match starting with "+" is worse (feature instead of command)
+ * 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(matched_string, offset, wrong_case)
+char_u *matched_string;
+int offset; /* offset for match */
+int wrong_case; /* no matching case */
+{
+ int num_letters;
+ char_u *p;
+
+ num_letters = 0;
+ for (p = matched_string; *p; p++)
+ if (ASCII_ISALNUM(*p))
+ num_letters++;
+
+ /*
+ * Multiply the number of letters by 100 to give it a much bigger
+ * weighting than the number of characters.
+ * If there only is a match while ignoring case, add 5000.
+ * If the match starts in the middle of a word, add 10000 to put it
+ * somewhere in the last half.
+ * If the match is more than 2 chars from the start, multiply by 200 to
+ * put it after matches at the start.
+ */
+ if (ASCII_ISALNUM(matched_string[offset]) && offset > 0
+ && ASCII_ISALNUM(matched_string[offset - 1]))
+ offset += 10000;
+ else if (offset > 2)
+ offset *= 200;
+ if (wrong_case)
+ offset += 5000;
+ /* Features are less interesting than the subjects themselves, but "+"
+ * alone is not a feature. */
+ if (matched_string[0] == '+' && matched_string[1] != NUL)
+ offset += 100;
+ return (int)(100 * num_letters + STRLEN(matched_string) + offset);
+}
+
+/*
+ * Compare functions for qsort() below, that checks the help heuristics number
+ * that has been put after the tagname by find_tags().
+ */
+static int help_compare(s1, s2)
+const void *s1;
+const void *s2;
+{
+ char *p1;
+ char *p2;
+
+ p1 = *(char **)s1 + strlen(*(char **)s1) + 1;
+ p2 = *(char **)s2 + strlen(*(char **)s2) + 1;
+ 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(arg, num_matches, matches, keep_lang)
+char_u *arg;
+int *num_matches;
+char_u ***matches;
+int keep_lang;
+{
+ char_u *s, *d;
+ int i;
+ static char *(mtable[]) = {"*", "g*", "[*", "]*", ":*",
+ "/*", "/\\*", "\"*", "**",
+ "cpo-*", "/\\(\\)", "/\\%(\\)",
+ "?", ":?", "?<CR>", "g?", "g?g?", "g??", "z?",
+ "/\\?", "/\\z(\\)", "\\=", ":s\\=",
+ "[count]", "[quotex]", "[range]",
+ "[pattern]", "\\|", "\\%$"};
+ static char *(rtable[]) = {"star", "gstar", "[star", "]star", ":star",
+ "/star", "/\\\\star", "quotestar", "starstar",
+ "cpo-star", "/\\\\(\\\\)", "/\\\\%(\\\\)",
+ "?", ":?", "?<CR>", "g?", "g?g?", "g??", "z?",
+ "/\\\\?", "/\\\\z(\\\\)", "\\\\=", ":s\\\\=",
+ "\\[count]", "\\[quotex]", "\\[range]",
+ "\\[pattern]", "\\\\bar", "/\\\\%\\$"};
+ 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)(sizeof(mtable) / sizeof(char *)); --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.
+ * Also replace "\%^" and "\%(", they match every tag too.
+ * Also "\zs", "\z1", etc.
+ * Also "\@<", "\@=", "\@<=", etc.
+ * And also "\_$" and "\_^". */
+ if (arg[0] == '\\'
+ && ((arg[1] != NUL && arg[2] == NUL)
+ || (vim_strchr((char_u *)"%_z@", arg[1]) != NULL
+ && arg[2] != NUL))) {
+ STRCPY(d, "/\\\\");
+ STRCPY(d + 3, arg + 1);
+ /* Check for "/\\_$", should be "/\\_\$" */
+ if (d[3] == '_' && d[4] == '$')
+ STRCPY(d + 4, "\\$");
+ } else {
+ /* Replace:
+ * "[:...:]" with "\[:...:]"
+ * "[++...]" with "\[++...]"
+ * "\{" with "\\{"
+ */
+ if ((arg[0] == '[' && (arg[1] == ':'
+ || (arg[1] == '+' && arg[2] == '+')))
+ || (arg[0] == '\\' && arg[1] == '{'))
+ *d++ = '\\';
+
+ for (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
+ * completion.
+ * Insert a backslash before '~', '$' and '.' to avoid their
+ * special meaning.
+ */
+ if (d - IObuff > IOSIZE - 10) /* getting too long!? */
+ break;
+ switch (*s) {
+ case '|': STRCPY(d, "bar");
+ d += 3;
+ continue;
+ case '"': STRCPY(d, "quote");
+ d += 5;
+ continue;
+ case '*': *d++ = '.';
+ break;
+ case '?': *d++ = '.';
+ continue;
+ case '$':
+ case '.':
+ case '~': *d++ = '\\';
+ break;
+ }
+
+ /*
+ * Replace "^x" by "CTRL-X". Don't do this for "^_" to make
+ * ":help i_^_CTRL-D" work.
+ * Insert '-' before and after "CTRL-X" when applicable.
+ */
+ if (*s < ' ' || (*s == '^' && s[1] && (ASCII_ISALPHA(s[1])
+ || vim_strchr((char_u *)
+ "?@[\\]^",
+ s[1]) != NULL))) {
+ if (d > IObuff && d[-1] != '_' && d[-1] != '\\')
+ *d++ = '_'; /* prepend a '_' to make x_CTRL-x */
+ STRCPY(d, "CTRL-");
+ d += 5;
+ if (*s < ' ') {
+ *d++ = *s + '@';
+ if (d[-1] == '\\')
+ *d++ = '\\'; /* double a backslash */
+ } else
+ *d++ = *++s;
+ if (s[1] != NUL && s[1] != '_')
+ *d++ = '_'; /* append a '_' */
+ continue;
+ } else if (*s == '^') /* "^" or "CTRL-^" or "^_" */
+ *d++ = '\\';
+
+ /*
+ * Insert a backslash before a backslash after a slash, for search
+ * pattern tags: "/\|" --> "/\\|".
+ */
+ else if (s[0] == '\\' && s[1] != '\\'
+ && *arg == '/' && s == arg + 1)
+ *d++ = '\\';
+
+ /* "CTRL-\_" -> "CTRL-\\_" to avoid the special meaning of "\_" in
+ * "CTRL-\_CTRL-N" */
+ if (STRNICMP(s, "CTRL-\\_", 7) == 0) {
+ STRCPY(d, "CTRL-\\\\");
+ d += 7;
+ s += 6;
+ }
+
+ *d++ = *s;
+
+ /*
+ * If tag starts with ', toss everything after a second '. Fixes
+ * CTRL-] on 'option'. (would include the trailing '.').
+ */
+ if (*s == '\'' && s > arg && *arg == '\'')
+ break;
+ }
+ *d = NUL;
+
+ if (*IObuff == '`') {
+ if (d > IObuff + 2 && d[-1] == '`') {
+ /* remove the backticks from `command` */
+ mch_memmove(IObuff, IObuff + 1, STRLEN(IObuff));
+ d[-2] = NUL;
+ } else if (d > IObuff + 3 && d[-2] == '`' && d[-1] == ',') {
+ /* remove the backticks and comma from `command`, */
+ mch_memmove(IObuff, IObuff + 1, STRLEN(IObuff));
+ d[-3] = NUL;
+ } else if (d > IObuff + 4 && d[-3] == '`'
+ && d[-2] == '\\' && d[-1] == '.') {
+ /* remove the backticks and dot from `command`\. */
+ mch_memmove(IObuff, IObuff + 1, STRLEN(IObuff));
+ d[-4] = NUL;
+ }
+ }
+ }
+ }
+
+ *matches = (char_u **)"";
+ *num_matches = 0;
+ 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
+ * tag name. */
+ qsort((void *)*matches, (size_t)*num_matches,
+ sizeof(char_u *), help_compare);
+ /* Delete more than TAG_MANY to reduce the size of the listing. */
+ while (*num_matches > TAG_MANY)
+ vim_free((*matches)[--*num_matches]);
+ }
+ return OK;
+}
+
+/*
+ * After reading a help file: May cleanup a help buffer when syntax
+ * highlighting is not used.
+ */
+void fix_help_buffer() {
+ linenr_T lnum;
+ char_u *line;
+ int in_example = FALSE;
+ int len;
+ char_u *fname;
+ char_u *p;
+ char_u *rt;
+ int mustfree;
+
+ /* set filetype to "help". */
+ set_option_value((char_u *)"ft", 0L, (char_u *)"help", OPT_LOCAL);
+
+ 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);
+ if (in_example && len > 0 && !vim_iswhite(line[0])) {
+ /* End of example: non-white or '<' in first column. */
+ if (line[0] == '<') {
+ /* blank-out a '<' in the first column */
+ line = ml_get_buf(curbuf, lnum, TRUE);
+ line[0] = ' ';
+ }
+ 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;
+ } else if (line[len - 1] == '~') {
+ /* blank-out a '~' at the end of line (header marker) */
+ line = ml_get_buf(curbuf, lnum, TRUE);
+ line[len - 1] = ' ';
+ }
+ }
+ }
+ }
+
+ /*
+ * 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 = gettail(curbuf->b_fname);
+ if (fnamecmp(fname, "help.txt") == 0
+ || (fnamencmp(fname, "help.", 5) == 0
+ && ASCII_ISALPHA(fname[5])
+ && ASCII_ISALPHA(fname[6])
+ && TOLOWER_ASC(fname[7]) == 'x'
+ && fname[8] == NUL)
+ ) {
+ for (lnum = 1; lnum < curbuf->b_ml.ml_line_count; ++lnum) {
+ line = ml_get_buf(curbuf, lnum, FALSE);
+ if (strstr((char *)line, "*local-additions*") == NULL)
+ continue;
+
+ /* Go through all directories in 'runtimepath', skipping
+ * $VIMRUNTIME. */
+ p = p_rtp;
+ while (*p != NUL) {
+ copy_option_part(&p, NameBuff, MAXPATHL, ",");
+ mustfree = FALSE;
+ rt = vim_getenv((char_u *)"VIMRUNTIME", &mustfree);
+ if (fullpathcmp(rt, NameBuff, FALSE) != FPC_SAME) {
+ 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(NameBuff);
+ STRCAT(NameBuff, "doc/*.??[tx]");
+ if (gen_expand_wildcards(1, &NameBuff, &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)
+ continue;
+ if (fnames[i1] == NULL || fnames[i2] == NULL)
+ continue;
+ f1 = fnames[i1];
+ f2 = fnames[i2];
+ t1 = gettail(f1);
+ if (fnamencmp(f1, f2, t1 - f1) != 0)
+ continue;
+ e1 = vim_strrchr(t1, '.');
+ e2 = vim_strrchr(gettail(f2), '.');
+ if (e1 == NUL || e2 == NUL)
+ continue;
+ if (fnamecmp(e1, ".txt") != 0
+ && fnamecmp(e1, fname + 4) != 0) {
+ /* Not .txt and not .abx, remove it. */
+ vim_free(fnames[i1]);
+ fnames[i1] = NULL;
+ continue;
+ }
+ if (fnamencmp(f1, f2, e1 - f1) != 0)
+ continue;
+ if (fnamecmp(e1, ".txt") == 0
+ && fnamecmp(e2, fname + 4) == 0) {
+ /* use .abx instead of .txt */
+ vim_free(fnames[i1]);
+ fnames[i1] = NULL;
+ }
+ }
+ }
+ for (fi = 0; fi < fcount; ++fi) {
+ if (fnames[fi] == NULL)
+ continue;
+ fd = mch_fopen((char *)fnames[fi], "r");
+ if (fd != NULL) {
+ vim_fgets(IObuff, IOSIZE, fd);
+ if (IObuff[0] == '*'
+ && (s = vim_strchr(IObuff + 1, '*'))
+ != NULL) {
+ int this_utf = MAYBE;
+ /* Change tag definition to a
+ * reference and remove <CR>/<NL>. */
+ IObuff[0] = '|';
+ *s = '|';
+ while (*s != NUL) {
+ if (*s == '\r' || *s == '\n')
+ *s = NUL;
+ /* The text is utf-8 when a byte
+ * 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;
+ s += l - 1;
+ }
+ ++s;
+ }
+ /* The help file is latin1 or utf-8;
+ * 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. */
+ cp = IObuff;
+ else {
+ /* Do the conversion. If it fails
+ * use the unconverted text. */
+ cp = string_convert(&vc, IObuff,
+ NULL);
+ if (cp == NULL)
+ cp = IObuff;
+ }
+ convert_setup(&vc, NULL, NULL);
+
+ ml_append(lnum, cp, (colnr_T)0, FALSE);
+ if (cp != IObuff)
+ vim_free(cp);
+ ++lnum;
+ }
+ fclose(fd);
+ }
+ }
+ FreeWild(fcount, fnames);
+ }
+ }
+ if (mustfree)
+ vim_free(rt);
+ }
+ break;
+ }
+ }
+}
+
+/*
+ * ":exusage"
+ */
+void ex_exusage(eap)
+exarg_T *eap UNUSED;
+{
+ do_cmdline_cmd((char_u *)"help ex-cmd-index");
+}
+
+/*
+ * ":viusage"
+ */
+void ex_viusage(eap)
+exarg_T *eap UNUSED;
+{
+ do_cmdline_cmd((char_u *)"help normal-index");
+}
+
+static void helptags_one __ARGS((char_u *dir, char_u *ext, char_u *lang,
+ int add_help_tags));
+
+/*
+ * ":helptags"
+ */
+void ex_helptags(eap)
+exarg_T *eap;
+{
+ garray_T ga;
+ int i, j;
+ int len;
+ char_u lang[2];
+ expand_T xpc;
+ char_u *dirname;
+ char_u ext[5];
+ char_u fname[8];
+ int filecount;
+ char_u **files;
+ int add_help_tags = FALSE;
+
+ /* Check for ":helptags ++t {dir}". */
+ if (STRNCMP(eap->arg, "++t", 3) == 0 && vim_iswhite(eap->arg[3])) {
+ add_help_tags = TRUE;
+ eap->arg = skipwhite(eap->arg + 3);
+ }
+
+ ExpandInit(&xpc);
+ xpc.xp_context = EXPAND_DIRECTORIES;
+ dirname = ExpandOne(&xpc, eap->arg, NULL,
+ WILD_LIST_NOTFOUND|WILD_SILENT, WILD_EXPAND_FREE);
+ if (dirname == NULL || !mch_isdir(dirname)) {
+ EMSG2(_("E150: Not a directory: %s"), eap->arg);
+ return;
+ }
+
+ /* Get a list of all files in the help directory and in subdirectories. */
+ STRCPY(NameBuff, dirname);
+ add_pathsep(NameBuff);
+ STRCAT(NameBuff, "**");
+ if (gen_expand_wildcards(1, &NameBuff, &filecount, &files,
+ EW_FILE|EW_SILENT) == FAIL
+ || filecount == 0) {
+ EMSG2("E151: No match: %s", NameBuff);
+ vim_free(dirname);
+ return;
+ }
+
+ /* Go over all files in the directory to find out what languages are
+ * present. */
+ ga_init2(&ga, 1, 10);
+ for (i = 0; i < filecount; ++i) {
+ len = (int)STRLEN(files[i]);
+ if (len > 4) {
+ if (STRICMP(files[i] + len - 4, ".txt") == 0) {
+ /* ".txt" -> language "en" */
+ lang[0] = 'e';
+ lang[1] = 'n';
+ } else if (files[i][len - 4] == '.'
+ && ASCII_ISALPHA(files[i][len - 3])
+ && ASCII_ISALPHA(files[i][len - 2])
+ && TOLOWER_ASC(files[i][len - 1]) == 'x') {
+ /* ".abx" -> language "ab" */
+ lang[0] = TOLOWER_ASC(files[i][len - 3]);
+ lang[1] = TOLOWER_ASC(files[i][len - 2]);
+ } else
+ continue;
+
+ /* Did we find this language already? */
+ for (j = 0; j < ga.ga_len; j += 2)
+ if (STRNCMP(lang, ((char_u *)ga.ga_data) + j, 2) == 0)
+ break;
+ if (j == ga.ga_len) {
+ /* New language, add it. */
+ if (ga_grow(&ga, 2) == FAIL)
+ break;
+ ((char_u *)ga.ga_data)[ga.ga_len++] = lang[0];
+ ((char_u *)ga.ga_data)[ga.ga_len++] = lang[1];
+ }
+ }
+ }
+
+ /*
+ * Loop over the found languages to generate a tags file for each one.
+ */
+ for (j = 0; j < ga.ga_len; j += 2) {
+ STRCPY(fname, "tags-xx");
+ fname[5] = ((char_u *)ga.ga_data)[j];
+ fname[6] = ((char_u *)ga.ga_data)[j + 1];
+ if (fname[5] == 'e' && fname[6] == 'n') {
+ /* English is an exception: use ".txt" and "tags". */
+ fname[4] = NUL;
+ STRCPY(ext, ".txt");
+ } else {
+ /* Language "ab" uses ".abx" and "tags-ab". */
+ STRCPY(ext, ".xxx");
+ ext[1] = fname[5];
+ ext[2] = fname[6];
+ }
+ helptags_one(dirname, ext, fname, add_help_tags);
+ }
+
+ ga_clear(&ga);
+ FreeWild(filecount, files);
+
+ vim_free(dirname);
+}
+
+static void helptags_one(dir, ext, tagfname, add_help_tags)
+char_u *dir; /* doc directory */
+char_u *ext; /* suffix, ".txt", ".itx", ".frx", etc. */
+char_u *tagfname; /* "tags" for English, "tags-fr" for French. */
+int add_help_tags; /* add "help-tags" tag */
+{
+ FILE *fd_tags;
+ FILE *fd;
+ garray_T ga;
+ int filecount;
+ char_u **files;
+ char_u *p1, *p2;
+ int fi;
+ char_u *s;
+ int i;
+ char_u *fname;
+ int dirlen;
+ int utf8 = MAYBE;
+ int this_utf8;
+ int firstline;
+ int mix = FALSE; /* detected mixed encodings */
+
+ /*
+ * Find all *.txt files.
+ */
+ dirlen = (int)STRLEN(dir);
+ STRCPY(NameBuff, dir);
+ STRCAT(NameBuff, "/**/*");
+ STRCAT(NameBuff, ext);
+ if (gen_expand_wildcards(1, &NameBuff, &filecount, &files,
+ EW_FILE|EW_SILENT) == FAIL
+ || filecount == 0) {
+ 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(NameBuff);
+ STRCAT(NameBuff, tagfname);
+ fd_tags = mch_fopen((char *)NameBuff, "w");
+ if (fd_tags == NULL) {
+ EMSG2(_("E152: Cannot open %s for writing"), NameBuff);
+ FreeWild(filecount, files);
+ return;
+ }
+
+ /*
+ * If using the "++t" argument or generating tags for "$VIMRUNTIME/doc"
+ * add the "help-tags" tag.
+ */
+ ga_init2(&ga, (int)sizeof(char_u *), 100);
+ if (add_help_tags || fullpathcmp((char_u *)"$VIMRUNTIME/doc",
+ dir, FALSE) == FPC_SAME) {
+ if (ga_grow(&ga, 1) == FAIL)
+ got_int = TRUE;
+ else {
+ s = alloc(18 + (unsigned)STRLEN(tagfname));
+ if (s == NULL)
+ got_int = TRUE;
+ else {
+ sprintf((char *)s, "help-tags\t%s\t1\n", tagfname);
+ ((char_u **)ga.ga_data)[ga.ga_len] = s;
+ ++ga.ga_len;
+ }
+ }
+ }
+
+ /*
+ * Go over all the files and extract the tags.
+ */
+ for (fi = 0; fi < filecount && !got_int; ++fi) {
+ 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;
+
+ 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)
+ if (*s >= 0x80) {
+ int l;
+
+ this_utf8 = TRUE;
+ l = utf_ptr2len(s);
+ if (l == 1) {
+ /* Illegal UTF-8 byte sequence. */
+ this_utf8 = FALSE;
+ break;
+ }
+ s += l - 1;
+ }
+ if (this_utf8 == MAYBE) /* only ASCII characters found */
+ this_utf8 = FALSE;
+ if (utf8 == MAYBE) /* first file */
+ 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;
+ }
+ 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 == '|')
+ break;
+
+ /*
+ * Only accept a *tag* when it consists of valid
+ * characters, there is white space before it and is
+ * followed by a white character or end-of-line.
+ */
+ if (s == p2
+ && (p1 == IObuff || p1[-1] == ' ' || p1[-1] == '\t')
+ && (vim_strchr((char_u *)" \t\n\r", s[1]) != NULL
+ || s[1] == '\0')) {
+ *p2 = '\0';
+ ++p1;
+ if (ga_grow(&ga, 1) == FAIL) {
+ got_int = TRUE;
+ break;
+ }
+ s = alloc((unsigned)(p2 - p1 + STRLEN(fname) + 2));
+ if (s == NULL) {
+ got_int = TRUE;
+ break;
+ }
+ ((char_u **)ga.ga_data)[ga.ga_len] = s;
+ ++ga.ga_len;
+ sprintf((char *)s, "%s\t%s", p1, fname);
+
+ /* find next '*' */
+ p2 = vim_strchr(p2 + 1, '*');
+ }
+ }
+ p1 = p2;
+ }
+ line_breakcheck();
+ }
+
+ fclose(fd);
+ }
+
+ FreeWild(filecount, files);
+
+ if (!got_int) {
+ /*
+ * Sort the tags.
+ */
+ sort_strings((char_u **)ga.ga_data, ga.ga_len);
+
+ /*
+ * Check for duplicates.
+ */
+ for (i = 1; i < ga.ga_len; ++i) {
+ p1 = ((char_u **)ga.ga_data)[i - 1];
+ p2 = ((char_u **)ga.ga_data)[i];
+ while (*p1 == *p2) {
+ if (*p2 == '\t') {
+ *p2 = NUL;
+ vim_snprintf((char *)NameBuff, MAXPATHL,
+ _("E154: Duplicate tag \"%s\" in file %s/%s"),
+ ((char_u **)ga.ga_data)[i], dir, p2 + 1);
+ EMSG(NameBuff);
+ *p2 = '\t';
+ break;
+ }
+ ++p1;
+ ++p2;
+ }
+ }
+
+ if (utf8 == TRUE)
+ fprintf(fd_tags, "!_TAG_FILE_ENCODING\tutf-8\t//\n");
+
+ /*
+ * Write the tags into the file.
+ */
+ for (i = 0; i < ga.ga_len; ++i) {
+ s = ((char_u **)ga.ga_data)[i];
+ if (STRNCMP(s, "help-tags\t", 10) == 0)
+ /* help-tags entry was added in formatted form */
+ fputs((char *)s, fd_tags);
+ else {
+ fprintf(fd_tags, "%s\t/*", s);
+ for (p1 = s; *p1 != '\t'; ++p1) {
+ /* insert backslash before '\\' and '/' */
+ if (*p1 == '\\' || *p1 == '/')
+ putc('\\', fd_tags);
+ putc(*p1, fd_tags);
+ }
+ fprintf(fd_tags, "*\n");
+ }
+ }
+ }
+ if (mix)
+ got_int = FALSE; /* continue with other languages */
+
+ for (i = 0; i < ga.ga_len; ++i)
+ vim_free(((char_u **)ga.ga_data)[i]);
+ ga_clear(&ga);
+ fclose(fd_tags); /* there is no check for an error... */
+}
+
+
diff --git a/src/ex_cmds.h b/src/ex_cmds.h
new file mode 100644
index 0000000000..a560789fef
--- /dev/null
+++ b/src/ex_cmds.h
@@ -0,0 +1,1191 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * 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.
+ */
+
+/*
+ * This file defines the Ex commands.
+ * When DO_DECLARE_EXCMD is defined, the table with ex command names and
+ * options results.
+ * When DO_DECLARE_EXCMD is NOT defined, the enum with all the Ex commands
+ * results.
+ * This clever trick was invented by Ron Aaron.
+ */
+
+/*
+ * When adding an Ex command:
+ * 1. Add an entry in the table below. Keep it sorted on the shortest
+ * version of the command name that works. If it doesn't start with a
+ * lower case letter, add it at the end.
+ * 2. Add a "case: CMD_xxx" in the big switch in ex_docmd.c.
+ * 3. Add an entry in the index for Ex commands at ":help ex-cmd-index".
+ * 4. Add documentation in ../doc/xxx.txt. Add a tag for both the short and
+ * long name of the command.
+ */
+
+#ifdef RANGE
+# undef RANGE /* SASC on Amiga defines it */
+#endif
+
+#define RANGE 0x001 /* allow a linespecs */
+#define BANG 0x002 /* allow a ! after the command name */
+#define EXTRA 0x004 /* allow extra args after command name */
+#define XFILE 0x008 /* expand wildcards in extra part */
+#define NOSPC 0x010 /* no spaces allowed in the extra part */
+#define DFLALL 0x020 /* default file range is 1,$ */
+#define WHOLEFOLD 0x040 /* extend range to include whole fold also
+ when less than two numbers given */
+#define NEEDARG 0x080 /* argument required */
+#define TRLBAR 0x100 /* check for trailing vertical bar */
+#define REGSTR 0x200 /* allow "x for register designation */
+#define COUNT 0x400 /* allow count in argument, after command */
+#define NOTRLCOM 0x800 /* no trailing comment allowed */
+#define ZEROR 0x1000 /* zero line number allowed */
+#define USECTRLV 0x2000 /* do not remove CTRL-V from argument */
+#define NOTADR 0x4000 /* number before command is not an address */
+#define EDITCMD 0x8000 /* allow "+command" argument */
+#define BUFNAME 0x10000L /* accepts buffer name */
+#define BUFUNL 0x20000L /* accepts unlisted buffer too */
+#define ARGOPT 0x40000L /* allow "++opt=val" argument */
+#define SBOXOK 0x80000L /* allowed in the sandbox */
+#define CMDWIN 0x100000L /* allowed in cmdline window */
+#define MODIFY 0x200000L /* forbidden in non-'modifiable' buffer */
+#define EXFLAGS 0x400000L /* allow flags after count in argument */
+#define FILES (XFILE | EXTRA) /* multiple extra files allowed */
+#define WORD1 (EXTRA | NOSPC) /* one extra word allowed */
+#define FILE1 (FILES | NOSPC) /* 1 file allowed, defaults to current file */
+
+#ifndef DO_DECLARE_EXCMD
+typedef struct exarg exarg_T;
+#endif
+
+/*
+ * This array maps ex command names to command codes.
+ * The order in which command names are listed below is significant --
+ * ambiguous abbreviations are always resolved to be the first possible match
+ * (e.g. "r" is taken to mean "read", not "rewind", because "read" comes
+ * before "rewind").
+ * Not supported commands are included to avoid ambiguities.
+ */
+#ifdef EX
+# undef EX /* just in case */
+#endif
+#ifdef DO_DECLARE_EXCMD
+# define EX(a, b, c, d) {(char_u *)b, c, (long_u)(d)}
+
+typedef void (*ex_func_T) __ARGS ((exarg_T *eap));
+
+static struct cmdname {
+ char_u *cmd_name; /* name of the command */
+ ex_func_T cmd_func; /* function for this command */
+ long_u cmd_argt; /* flags declared above */
+}
+cmdnames[] =
+#else
+# define EX(a, b, c, d) a
+enum CMD_index
+#endif
+{
+ EX(CMD_append, "append", ex_append,
+ BANG|RANGE|ZEROR|TRLBAR|CMDWIN|MODIFY),
+ EX(CMD_abbreviate, "abbreviate", ex_abbreviate,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_abclear, "abclear", ex_abclear,
+ EXTRA|TRLBAR|CMDWIN),
+ EX(CMD_aboveleft, "aboveleft", ex_wrongmodifier,
+ NEEDARG|EXTRA|NOTRLCOM),
+ EX(CMD_all, "all", ex_all,
+ BANG|RANGE|NOTADR|COUNT|TRLBAR),
+ EX(CMD_amenu, "amenu", ex_menu,
+ RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_anoremenu, "anoremenu", ex_menu,
+ RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_args, "args", ex_args,
+ BANG|FILES|EDITCMD|ARGOPT|TRLBAR),
+ EX(CMD_argadd, "argadd", ex_argadd,
+ BANG|NEEDARG|RANGE|NOTADR|ZEROR|FILES|TRLBAR),
+ EX(CMD_argdelete, "argdelete", ex_argdelete,
+ BANG|RANGE|NOTADR|FILES|TRLBAR),
+ EX(CMD_argdo, "argdo", ex_listdo,
+ BANG|NEEDARG|EXTRA|NOTRLCOM),
+ EX(CMD_argedit, "argedit", ex_argedit,
+ BANG|NEEDARG|RANGE|NOTADR|FILE1|EDITCMD|ARGOPT|TRLBAR),
+ EX(CMD_argglobal, "argglobal", ex_args,
+ BANG|FILES|EDITCMD|ARGOPT|TRLBAR),
+ EX(CMD_arglocal, "arglocal", ex_args,
+ BANG|FILES|EDITCMD|ARGOPT|TRLBAR),
+ EX(CMD_argument, "argument", ex_argument,
+ BANG|RANGE|NOTADR|COUNT|EXTRA|EDITCMD|ARGOPT|TRLBAR),
+ EX(CMD_ascii, "ascii", do_ascii,
+ TRLBAR|SBOXOK|CMDWIN),
+ EX(CMD_autocmd, "autocmd", ex_autocmd,
+ BANG|EXTRA|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_augroup, "augroup", ex_autocmd,
+ BANG|WORD1|TRLBAR|CMDWIN),
+ EX(CMD_aunmenu, "aunmenu", ex_menu,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_buffer, "buffer", ex_buffer,
+ BANG|RANGE|NOTADR|BUFNAME|BUFUNL|COUNT|EXTRA|TRLBAR),
+ EX(CMD_bNext, "bNext", ex_bprevious,
+ BANG|RANGE|NOTADR|COUNT|TRLBAR),
+ EX(CMD_ball, "ball", ex_buffer_all,
+ RANGE|NOTADR|COUNT|TRLBAR),
+ EX(CMD_badd, "badd", ex_edit,
+ NEEDARG|FILE1|EDITCMD|TRLBAR|CMDWIN),
+ EX(CMD_bdelete, "bdelete", ex_bunload,
+ BANG|RANGE|NOTADR|BUFNAME|COUNT|EXTRA|TRLBAR),
+ EX(CMD_behave, "behave", ex_behave,
+ NEEDARG|WORD1|TRLBAR|CMDWIN),
+ EX(CMD_belowright, "belowright", ex_wrongmodifier,
+ NEEDARG|EXTRA|NOTRLCOM),
+ EX(CMD_bfirst, "bfirst", ex_brewind,
+ BANG|RANGE|NOTADR|TRLBAR),
+ EX(CMD_blast, "blast", ex_blast,
+ BANG|RANGE|NOTADR|TRLBAR),
+ EX(CMD_bmodified, "bmodified", ex_bmodified,
+ BANG|RANGE|NOTADR|COUNT|TRLBAR),
+ EX(CMD_bnext, "bnext", ex_bnext,
+ BANG|RANGE|NOTADR|COUNT|TRLBAR),
+ EX(CMD_botright, "botright", ex_wrongmodifier,
+ NEEDARG|EXTRA|NOTRLCOM),
+ EX(CMD_bprevious, "bprevious", ex_bprevious,
+ BANG|RANGE|NOTADR|COUNT|TRLBAR),
+ EX(CMD_brewind, "brewind", ex_brewind,
+ BANG|RANGE|NOTADR|TRLBAR),
+ EX(CMD_break, "break", ex_break,
+ TRLBAR|SBOXOK|CMDWIN),
+ EX(CMD_breakadd, "breakadd", ex_breakadd,
+ EXTRA|TRLBAR|CMDWIN),
+ EX(CMD_breakdel, "breakdel", ex_breakdel,
+ EXTRA|TRLBAR|CMDWIN),
+ EX(CMD_breaklist, "breaklist", ex_breaklist,
+ EXTRA|TRLBAR|CMDWIN),
+ EX(CMD_browse, "browse", ex_wrongmodifier,
+ NEEDARG|EXTRA|NOTRLCOM|CMDWIN),
+ EX(CMD_buffers, "buffers", buflist_list,
+ BANG|TRLBAR|CMDWIN),
+ EX(CMD_bufdo, "bufdo", ex_listdo,
+ BANG|NEEDARG|EXTRA|NOTRLCOM),
+ EX(CMD_bunload, "bunload", ex_bunload,
+ BANG|RANGE|NOTADR|BUFNAME|COUNT|EXTRA|TRLBAR),
+ EX(CMD_bwipeout, "bwipeout", ex_bunload,
+ BANG|RANGE|NOTADR|BUFNAME|BUFUNL|COUNT|EXTRA|TRLBAR),
+ EX(CMD_change, "change", ex_change,
+ BANG|WHOLEFOLD|RANGE|COUNT|TRLBAR|CMDWIN|MODIFY),
+ EX(CMD_cNext, "cNext", ex_cnext,
+ RANGE|NOTADR|COUNT|TRLBAR|BANG),
+ EX(CMD_cNfile, "cNfile", ex_cnext,
+ RANGE|NOTADR|COUNT|TRLBAR|BANG),
+ EX(CMD_cabbrev, "cabbrev", ex_abbreviate,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_cabclear, "cabclear", ex_abclear,
+ EXTRA|TRLBAR|CMDWIN),
+ EX(CMD_caddbuffer, "caddbuffer", ex_cbuffer,
+ RANGE|NOTADR|WORD1|TRLBAR),
+ EX(CMD_caddexpr, "caddexpr", ex_cexpr,
+ NEEDARG|WORD1|NOTRLCOM|TRLBAR),
+ EX(CMD_caddfile, "caddfile", ex_cfile,
+ TRLBAR|FILE1),
+ EX(CMD_call, "call", ex_call,
+ RANGE|NEEDARG|EXTRA|NOTRLCOM|SBOXOK|CMDWIN),
+ EX(CMD_catch, "catch", ex_catch,
+ EXTRA|SBOXOK|CMDWIN),
+ EX(CMD_cbuffer, "cbuffer", ex_cbuffer,
+ BANG|RANGE|NOTADR|WORD1|TRLBAR),
+ EX(CMD_cc, "cc", ex_cc,
+ RANGE|NOTADR|COUNT|TRLBAR|BANG),
+ EX(CMD_cclose, "cclose", ex_cclose,
+ RANGE|NOTADR|COUNT|TRLBAR),
+ EX(CMD_cd, "cd", ex_cd,
+ BANG|FILE1|TRLBAR|CMDWIN),
+ EX(CMD_center, "center", ex_align,
+ TRLBAR|RANGE|WHOLEFOLD|EXTRA|CMDWIN|MODIFY),
+ EX(CMD_cexpr, "cexpr", ex_cexpr,
+ NEEDARG|WORD1|NOTRLCOM|TRLBAR|BANG),
+ EX(CMD_cfile, "cfile", ex_cfile,
+ TRLBAR|FILE1|BANG),
+ EX(CMD_cfirst, "cfirst", ex_cc,
+ RANGE|NOTADR|COUNT|TRLBAR|BANG),
+ EX(CMD_cgetfile, "cgetfile", ex_cfile,
+ TRLBAR|FILE1),
+ EX(CMD_cgetbuffer, "cgetbuffer", ex_cbuffer,
+ RANGE|NOTADR|WORD1|TRLBAR),
+ EX(CMD_cgetexpr, "cgetexpr", ex_cexpr,
+ NEEDARG|WORD1|NOTRLCOM|TRLBAR),
+ EX(CMD_chdir, "chdir", ex_cd,
+ BANG|FILE1|TRLBAR|CMDWIN),
+ EX(CMD_changes, "changes", ex_changes,
+ TRLBAR|CMDWIN),
+ EX(CMD_checkpath, "checkpath", ex_checkpath,
+ TRLBAR|BANG|CMDWIN),
+ EX(CMD_checktime, "checktime", ex_checktime,
+ RANGE|NOTADR|BUFNAME|COUNT|EXTRA|TRLBAR),
+ EX(CMD_clist, "clist", qf_list,
+ BANG|EXTRA|TRLBAR|CMDWIN),
+ EX(CMD_clast, "clast", ex_cc,
+ RANGE|NOTADR|COUNT|TRLBAR|BANG),
+ EX(CMD_close, "close", ex_close,
+ BANG|TRLBAR|CMDWIN),
+ EX(CMD_cmap, "cmap", ex_map,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_cmapclear, "cmapclear", ex_mapclear,
+ EXTRA|TRLBAR|CMDWIN),
+ EX(CMD_cmenu, "cmenu", ex_menu,
+ RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_cnext, "cnext", ex_cnext,
+ RANGE|NOTADR|COUNT|TRLBAR|BANG),
+ EX(CMD_cnewer, "cnewer", qf_age,
+ RANGE|NOTADR|COUNT|TRLBAR),
+ EX(CMD_cnfile, "cnfile", ex_cnext,
+ RANGE|NOTADR|COUNT|TRLBAR|BANG),
+ EX(CMD_cnoremap, "cnoremap", ex_map,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_cnoreabbrev, "cnoreabbrev", ex_abbreviate,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_cnoremenu, "cnoremenu", ex_menu,
+ RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_copy, "copy", ex_copymove,
+ RANGE|WHOLEFOLD|EXTRA|TRLBAR|CMDWIN|MODIFY),
+ EX(CMD_colder, "colder", qf_age,
+ RANGE|NOTADR|COUNT|TRLBAR),
+ EX(CMD_colorscheme, "colorscheme", ex_colorscheme,
+ WORD1|TRLBAR|CMDWIN),
+ EX(CMD_command, "command", ex_command,
+ EXTRA|BANG|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_comclear, "comclear", ex_comclear,
+ TRLBAR|CMDWIN),
+ EX(CMD_compiler, "compiler", ex_compiler,
+ BANG|TRLBAR|WORD1|CMDWIN),
+ EX(CMD_continue, "continue", ex_continue,
+ TRLBAR|SBOXOK|CMDWIN),
+ EX(CMD_confirm, "confirm", ex_wrongmodifier,
+ NEEDARG|EXTRA|NOTRLCOM|CMDWIN),
+ EX(CMD_copen, "copen", ex_copen,
+ RANGE|NOTADR|COUNT|TRLBAR),
+ EX(CMD_cprevious, "cprevious", ex_cnext,
+ RANGE|NOTADR|COUNT|TRLBAR|BANG),
+ EX(CMD_cpfile, "cpfile", ex_cnext,
+ RANGE|NOTADR|COUNT|TRLBAR|BANG),
+ EX(CMD_cquit, "cquit", ex_cquit,
+ TRLBAR|BANG),
+ EX(CMD_crewind, "crewind", ex_cc,
+ RANGE|NOTADR|COUNT|TRLBAR|BANG),
+ EX(CMD_cscope, "cscope", do_cscope,
+ EXTRA|NOTRLCOM|XFILE),
+ EX(CMD_cstag, "cstag", do_cstag,
+ BANG|TRLBAR|WORD1),
+ EX(CMD_cunmap, "cunmap", ex_unmap,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_cunabbrev, "cunabbrev", ex_abbreviate,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_cunmenu, "cunmenu", ex_menu,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_cwindow, "cwindow", ex_cwindow,
+ RANGE|NOTADR|COUNT|TRLBAR),
+ EX(CMD_delete, "delete", ex_operators,
+ RANGE|WHOLEFOLD|REGSTR|COUNT|TRLBAR|CMDWIN|MODIFY),
+ EX(CMD_delmarks, "delmarks", ex_delmarks,
+ BANG|EXTRA|TRLBAR|CMDWIN),
+ EX(CMD_debug, "debug", ex_debug,
+ NEEDARG|EXTRA|NOTRLCOM|SBOXOK|CMDWIN),
+ EX(CMD_debuggreedy, "debuggreedy", ex_debuggreedy,
+ RANGE|NOTADR|ZEROR|TRLBAR|CMDWIN),
+ EX(CMD_delcommand, "delcommand", ex_delcommand,
+ NEEDARG|WORD1|TRLBAR|CMDWIN),
+ EX(CMD_delfunction, "delfunction", ex_delfunction,
+ NEEDARG|WORD1|CMDWIN),
+ EX(CMD_display, "display", ex_display,
+ EXTRA|NOTRLCOM|TRLBAR|SBOXOK|CMDWIN),
+ EX(CMD_diffupdate, "diffupdate", ex_diffupdate,
+ BANG|TRLBAR),
+ EX(CMD_diffget, "diffget", ex_diffgetput,
+ RANGE|EXTRA|TRLBAR|MODIFY),
+ EX(CMD_diffoff, "diffoff", ex_diffoff,
+ BANG|TRLBAR),
+ EX(CMD_diffpatch, "diffpatch", ex_diffpatch,
+ EXTRA|FILE1|TRLBAR|MODIFY),
+ EX(CMD_diffput, "diffput", ex_diffgetput,
+ RANGE|EXTRA|TRLBAR),
+ EX(CMD_diffsplit, "diffsplit", ex_diffsplit,
+ EXTRA|FILE1|TRLBAR),
+ EX(CMD_diffthis, "diffthis", ex_diffthis,
+ TRLBAR),
+ EX(CMD_digraphs, "digraphs", ex_digraphs,
+ EXTRA|TRLBAR|CMDWIN),
+ EX(CMD_djump, "djump", ex_findpat,
+ BANG|RANGE|DFLALL|WHOLEFOLD|EXTRA),
+ EX(CMD_dlist, "dlist", ex_findpat,
+ BANG|RANGE|DFLALL|WHOLEFOLD|EXTRA|CMDWIN),
+ EX(CMD_doautocmd, "doautocmd", ex_doautocmd,
+ EXTRA|TRLBAR|CMDWIN),
+ EX(CMD_doautoall, "doautoall", ex_doautoall,
+ EXTRA|TRLBAR|CMDWIN),
+ EX(CMD_drop, "drop", ex_drop,
+ FILES|EDITCMD|NEEDARG|ARGOPT|TRLBAR),
+ EX(CMD_dsearch, "dsearch", ex_findpat,
+ BANG|RANGE|DFLALL|WHOLEFOLD|EXTRA|CMDWIN),
+ EX(CMD_dsplit, "dsplit", ex_findpat,
+ BANG|RANGE|DFLALL|WHOLEFOLD|EXTRA),
+ EX(CMD_edit, "edit", ex_edit,
+ BANG|FILE1|EDITCMD|ARGOPT|TRLBAR),
+ EX(CMD_earlier, "earlier", ex_later,
+ TRLBAR|EXTRA|NOSPC|CMDWIN),
+ EX(CMD_echo, "echo", ex_echo,
+ EXTRA|NOTRLCOM|SBOXOK|CMDWIN),
+ EX(CMD_echoerr, "echoerr", ex_execute,
+ EXTRA|NOTRLCOM|SBOXOK|CMDWIN),
+ EX(CMD_echohl, "echohl", ex_echohl,
+ EXTRA|TRLBAR|SBOXOK|CMDWIN),
+ EX(CMD_echomsg, "echomsg", ex_execute,
+ EXTRA|NOTRLCOM|SBOXOK|CMDWIN),
+ EX(CMD_echon, "echon", ex_echo,
+ EXTRA|NOTRLCOM|SBOXOK|CMDWIN),
+ EX(CMD_else, "else", ex_else,
+ TRLBAR|SBOXOK|CMDWIN),
+ EX(CMD_elseif, "elseif", ex_else,
+ EXTRA|NOTRLCOM|SBOXOK|CMDWIN),
+ EX(CMD_emenu, "emenu", ex_emenu,
+ NEEDARG|EXTRA|TRLBAR|NOTRLCOM|RANGE|NOTADR|CMDWIN),
+ EX(CMD_endif, "endif", ex_endif,
+ TRLBAR|SBOXOK|CMDWIN),
+ EX(CMD_endfunction, "endfunction", ex_endfunction,
+ TRLBAR|CMDWIN),
+ EX(CMD_endfor, "endfor", ex_endwhile,
+ TRLBAR|SBOXOK|CMDWIN),
+ EX(CMD_endtry, "endtry", ex_endtry,
+ TRLBAR|SBOXOK|CMDWIN),
+ EX(CMD_endwhile, "endwhile", ex_endwhile,
+ TRLBAR|SBOXOK|CMDWIN),
+ EX(CMD_enew, "enew", ex_edit,
+ BANG|TRLBAR),
+ EX(CMD_ex, "ex", ex_edit,
+ BANG|FILE1|EDITCMD|ARGOPT|TRLBAR),
+ EX(CMD_execute, "execute", ex_execute,
+ EXTRA|NOTRLCOM|SBOXOK|CMDWIN),
+ EX(CMD_exit, "exit", ex_exit,
+ RANGE|WHOLEFOLD|BANG|FILE1|ARGOPT|DFLALL|TRLBAR|CMDWIN),
+ EX(CMD_exusage, "exusage", ex_exusage,
+ TRLBAR),
+ EX(CMD_file, "file", ex_file,
+ RANGE|NOTADR|ZEROR|BANG|FILE1|TRLBAR),
+ EX(CMD_files, "files", buflist_list,
+ BANG|TRLBAR|CMDWIN),
+ EX(CMD_filetype, "filetype", ex_filetype,
+ EXTRA|TRLBAR|CMDWIN),
+ EX(CMD_find, "find", ex_find,
+ RANGE|NOTADR|BANG|FILE1|EDITCMD|ARGOPT|TRLBAR),
+ EX(CMD_finally, "finally", ex_finally,
+ TRLBAR|SBOXOK|CMDWIN),
+ EX(CMD_finish, "finish", ex_finish,
+ TRLBAR|SBOXOK|CMDWIN),
+ EX(CMD_first, "first", ex_rewind,
+ EXTRA|BANG|EDITCMD|ARGOPT|TRLBAR),
+ EX(CMD_fixdel, "fixdel", do_fixdel,
+ TRLBAR|CMDWIN),
+ EX(CMD_fold, "fold", ex_fold,
+ RANGE|WHOLEFOLD|TRLBAR|SBOXOK|CMDWIN),
+ EX(CMD_foldclose, "foldclose", ex_foldopen,
+ RANGE|BANG|WHOLEFOLD|TRLBAR|SBOXOK|CMDWIN),
+ EX(CMD_folddoopen, "folddoopen", ex_folddo,
+ RANGE|DFLALL|NEEDARG|EXTRA|NOTRLCOM),
+ EX(CMD_folddoclosed, "folddoclosed", ex_folddo,
+ RANGE|DFLALL|NEEDARG|EXTRA|NOTRLCOM),
+ EX(CMD_foldopen, "foldopen", ex_foldopen,
+ RANGE|BANG|WHOLEFOLD|TRLBAR|SBOXOK|CMDWIN),
+ EX(CMD_for, "for", ex_while,
+ EXTRA|NOTRLCOM|SBOXOK|CMDWIN),
+ EX(CMD_function, "function", ex_function,
+ EXTRA|BANG|CMDWIN),
+ EX(CMD_global, "global", ex_global,
+ RANGE|WHOLEFOLD|BANG|EXTRA|DFLALL|SBOXOK|CMDWIN),
+ EX(CMD_goto, "goto", ex_goto,
+ RANGE|NOTADR|COUNT|TRLBAR|SBOXOK|CMDWIN),
+ EX(CMD_grep, "grep", ex_make,
+ RANGE|NOTADR|BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE),
+ EX(CMD_grepadd, "grepadd", ex_make,
+ RANGE|NOTADR|BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE),
+ EX(CMD_gui, "gui", ex_gui,
+ BANG|FILES|EDITCMD|ARGOPT|TRLBAR|CMDWIN),
+ EX(CMD_gvim, "gvim", ex_gui,
+ BANG|FILES|EDITCMD|ARGOPT|TRLBAR|CMDWIN),
+ EX(CMD_help, "help", ex_help,
+ BANG|EXTRA|NOTRLCOM),
+ EX(CMD_helpfind, "helpfind", ex_helpfind,
+ EXTRA|NOTRLCOM),
+ EX(CMD_helpgrep, "helpgrep", ex_helpgrep,
+ EXTRA|NOTRLCOM|NEEDARG),
+ EX(CMD_helptags, "helptags", ex_helptags,
+ NEEDARG|FILES|TRLBAR|CMDWIN),
+ EX(CMD_hardcopy, "hardcopy", ex_hardcopy,
+ RANGE|COUNT|EXTRA|TRLBAR|DFLALL|BANG),
+ EX(CMD_highlight, "highlight", ex_highlight,
+ BANG|EXTRA|TRLBAR|SBOXOK|CMDWIN),
+ EX(CMD_hide, "hide", ex_hide,
+ BANG|EXTRA|NOTRLCOM),
+ EX(CMD_history, "history", ex_history,
+ EXTRA|TRLBAR|CMDWIN),
+ EX(CMD_insert, "insert", ex_append,
+ BANG|RANGE|TRLBAR|CMDWIN|MODIFY),
+ EX(CMD_iabbrev, "iabbrev", ex_abbreviate,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_iabclear, "iabclear", ex_abclear,
+ EXTRA|TRLBAR|CMDWIN),
+ EX(CMD_if, "if", ex_if,
+ EXTRA|NOTRLCOM|SBOXOK|CMDWIN),
+ EX(CMD_ijump, "ijump", ex_findpat,
+ BANG|RANGE|DFLALL|WHOLEFOLD|EXTRA),
+ EX(CMD_ilist, "ilist", ex_findpat,
+ BANG|RANGE|DFLALL|WHOLEFOLD|EXTRA|CMDWIN),
+ EX(CMD_imap, "imap", ex_map,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_imapclear, "imapclear", ex_mapclear,
+ EXTRA|TRLBAR|CMDWIN),
+ EX(CMD_imenu, "imenu", ex_menu,
+ RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_inoremap, "inoremap", ex_map,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_inoreabbrev, "inoreabbrev", ex_abbreviate,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_inoremenu, "inoremenu", ex_menu,
+ RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_intro, "intro", ex_intro,
+ TRLBAR|CMDWIN),
+ EX(CMD_isearch, "isearch", ex_findpat,
+ BANG|RANGE|DFLALL|WHOLEFOLD|EXTRA|CMDWIN),
+ EX(CMD_isplit, "isplit", ex_findpat,
+ BANG|RANGE|DFLALL|WHOLEFOLD|EXTRA),
+ EX(CMD_iunmap, "iunmap", ex_unmap,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_iunabbrev, "iunabbrev", ex_abbreviate,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_iunmenu, "iunmenu", ex_menu,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_join, "join", ex_join,
+ BANG|RANGE|WHOLEFOLD|COUNT|EXFLAGS|TRLBAR|CMDWIN|MODIFY),
+ EX(CMD_jumps, "jumps", ex_jumps,
+ TRLBAR|CMDWIN),
+ EX(CMD_k, "k", ex_mark,
+ RANGE|WORD1|TRLBAR|SBOXOK|CMDWIN),
+ EX(CMD_keepmarks, "keepmarks", ex_wrongmodifier,
+ NEEDARG|EXTRA|NOTRLCOM),
+ EX(CMD_keepjumps, "keepjumps", ex_wrongmodifier,
+ NEEDARG|EXTRA|NOTRLCOM),
+ EX(CMD_keeppatterns, "keeppatterns", ex_wrongmodifier,
+ NEEDARG|EXTRA|NOTRLCOM),
+ EX(CMD_keepalt, "keepalt", ex_wrongmodifier,
+ NEEDARG|EXTRA|NOTRLCOM),
+ EX(CMD_list, "list", ex_print,
+ RANGE|WHOLEFOLD|COUNT|EXFLAGS|TRLBAR|CMDWIN),
+ EX(CMD_lNext, "lNext", ex_cnext,
+ RANGE|NOTADR|COUNT|TRLBAR|BANG),
+ EX(CMD_lNfile, "lNfile", ex_cnext,
+ RANGE|NOTADR|COUNT|TRLBAR|BANG),
+ EX(CMD_last, "last", ex_last,
+ EXTRA|BANG|EDITCMD|ARGOPT|TRLBAR),
+ EX(CMD_language, "language", ex_language,
+ EXTRA|TRLBAR|CMDWIN),
+ EX(CMD_laddexpr, "laddexpr", ex_cexpr,
+ NEEDARG|WORD1|NOTRLCOM|TRLBAR),
+ EX(CMD_laddbuffer, "laddbuffer", ex_cbuffer,
+ RANGE|NOTADR|WORD1|TRLBAR),
+ EX(CMD_laddfile, "laddfile", ex_cfile,
+ TRLBAR|FILE1),
+ EX(CMD_later, "later", ex_later,
+ TRLBAR|EXTRA|NOSPC|CMDWIN),
+ EX(CMD_lbuffer, "lbuffer", ex_cbuffer,
+ BANG|RANGE|NOTADR|WORD1|TRLBAR),
+ EX(CMD_lcd, "lcd", ex_cd,
+ BANG|FILE1|TRLBAR|CMDWIN),
+ EX(CMD_lchdir, "lchdir", ex_cd,
+ BANG|FILE1|TRLBAR|CMDWIN),
+ EX(CMD_lclose, "lclose", ex_cclose,
+ RANGE|NOTADR|COUNT|TRLBAR),
+ EX(CMD_lcscope, "lcscope", do_cscope,
+ EXTRA|NOTRLCOM|XFILE),
+ EX(CMD_left, "left", ex_align,
+ TRLBAR|RANGE|WHOLEFOLD|EXTRA|CMDWIN|MODIFY),
+ EX(CMD_leftabove, "leftabove", ex_wrongmodifier,
+ NEEDARG|EXTRA|NOTRLCOM),
+ EX(CMD_let, "let", ex_let,
+ EXTRA|NOTRLCOM|SBOXOK|CMDWIN),
+ EX(CMD_lexpr, "lexpr", ex_cexpr,
+ NEEDARG|WORD1|NOTRLCOM|TRLBAR|BANG),
+ EX(CMD_lfile, "lfile", ex_cfile,
+ TRLBAR|FILE1|BANG),
+ EX(CMD_lfirst, "lfirst", ex_cc,
+ RANGE|NOTADR|COUNT|TRLBAR|BANG),
+ EX(CMD_lgetfile, "lgetfile", ex_cfile,
+ TRLBAR|FILE1),
+ EX(CMD_lgetbuffer, "lgetbuffer", ex_cbuffer,
+ RANGE|NOTADR|WORD1|TRLBAR),
+ EX(CMD_lgetexpr, "lgetexpr", ex_cexpr,
+ NEEDARG|WORD1|NOTRLCOM|TRLBAR),
+ EX(CMD_lgrep, "lgrep", ex_make,
+ RANGE|NOTADR|BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE),
+ EX(CMD_lgrepadd, "lgrepadd", ex_make,
+ RANGE|NOTADR|BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE),
+ EX(CMD_lhelpgrep, "lhelpgrep", ex_helpgrep,
+ EXTRA|NOTRLCOM|NEEDARG),
+ EX(CMD_ll, "ll", ex_cc,
+ RANGE|NOTADR|COUNT|TRLBAR|BANG),
+ EX(CMD_llast, "llast", ex_cc,
+ RANGE|NOTADR|COUNT|TRLBAR|BANG),
+ EX(CMD_llist, "llist", qf_list,
+ BANG|EXTRA|TRLBAR|CMDWIN),
+ EX(CMD_lmap, "lmap", ex_map,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_lmapclear, "lmapclear", ex_mapclear,
+ EXTRA|TRLBAR|CMDWIN),
+ EX(CMD_lmake, "lmake", ex_make,
+ BANG|EXTRA|NOTRLCOM|TRLBAR|XFILE),
+ EX(CMD_lnoremap, "lnoremap", ex_map,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_lnext, "lnext", ex_cnext,
+ RANGE|NOTADR|COUNT|TRLBAR|BANG),
+ EX(CMD_lnewer, "lnewer", qf_age,
+ RANGE|NOTADR|COUNT|TRLBAR),
+ EX(CMD_lnfile, "lnfile", ex_cnext,
+ RANGE|NOTADR|COUNT|TRLBAR|BANG),
+ EX(CMD_loadview, "loadview", ex_loadview,
+ FILE1|TRLBAR),
+ EX(CMD_loadkeymap, "loadkeymap", ex_loadkeymap,
+ CMDWIN),
+ EX(CMD_lockmarks, "lockmarks", ex_wrongmodifier,
+ NEEDARG|EXTRA|NOTRLCOM),
+ EX(CMD_lockvar, "lockvar", ex_lockvar,
+ BANG|EXTRA|NEEDARG|SBOXOK|CMDWIN),
+ EX(CMD_lolder, "lolder", qf_age,
+ RANGE|NOTADR|COUNT|TRLBAR),
+ EX(CMD_lopen, "lopen", ex_copen,
+ RANGE|NOTADR|COUNT|TRLBAR),
+ EX(CMD_lprevious, "lprevious", ex_cnext,
+ RANGE|NOTADR|COUNT|TRLBAR|BANG),
+ EX(CMD_lpfile, "lpfile", ex_cnext,
+ RANGE|NOTADR|COUNT|TRLBAR|BANG),
+ EX(CMD_lrewind, "lrewind", ex_cc,
+ RANGE|NOTADR|COUNT|TRLBAR|BANG),
+ EX(CMD_ltag, "ltag", ex_tag,
+ NOTADR|TRLBAR|BANG|WORD1),
+ EX(CMD_lua, "lua", ex_lua,
+ RANGE|EXTRA|NEEDARG|CMDWIN),
+ EX(CMD_luado, "luado", ex_luado,
+ RANGE|DFLALL|EXTRA|NEEDARG|CMDWIN),
+ EX(CMD_luafile, "luafile", ex_luafile,
+ RANGE|FILE1|NEEDARG|CMDWIN),
+ EX(CMD_lunmap, "lunmap", ex_unmap,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_lvimgrep, "lvimgrep", ex_vimgrep,
+ RANGE|NOTADR|BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE),
+ EX(CMD_lvimgrepadd, "lvimgrepadd", ex_vimgrep,
+ RANGE|NOTADR|BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE),
+ EX(CMD_lwindow, "lwindow", ex_cwindow,
+ RANGE|NOTADR|COUNT|TRLBAR),
+ EX(CMD_ls, "ls", buflist_list,
+ BANG|TRLBAR|CMDWIN),
+ EX(CMD_move, "move", ex_copymove,
+ RANGE|WHOLEFOLD|EXTRA|TRLBAR|CMDWIN|MODIFY),
+ EX(CMD_mark, "mark", ex_mark,
+ RANGE|WORD1|TRLBAR|SBOXOK|CMDWIN),
+ EX(CMD_make, "make", ex_make,
+ BANG|EXTRA|NOTRLCOM|TRLBAR|XFILE),
+ EX(CMD_map, "map", ex_map,
+ BANG|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_mapclear, "mapclear", ex_mapclear,
+ EXTRA|BANG|TRLBAR|CMDWIN),
+ EX(CMD_marks, "marks", do_marks,
+ EXTRA|TRLBAR|CMDWIN),
+ EX(CMD_match, "match", ex_match,
+ RANGE|NOTADR|EXTRA|CMDWIN),
+ EX(CMD_menu, "menu", ex_menu,
+ RANGE|NOTADR|ZEROR|BANG|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_menutranslate, "menutranslate", ex_menutranslate,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_messages, "messages", ex_messages,
+ TRLBAR|CMDWIN),
+ EX(CMD_mkexrc, "mkexrc", ex_mkrc,
+ BANG|FILE1|TRLBAR|CMDWIN),
+ EX(CMD_mksession, "mksession", ex_mkrc,
+ BANG|FILE1|TRLBAR),
+ EX(CMD_mkspell, "mkspell", ex_mkspell,
+ BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE),
+ EX(CMD_mkvimrc, "mkvimrc", ex_mkrc,
+ BANG|FILE1|TRLBAR|CMDWIN),
+ EX(CMD_mkview, "mkview", ex_mkrc,
+ BANG|FILE1|TRLBAR),
+ EX(CMD_mode, "mode", ex_mode,
+ WORD1|TRLBAR|CMDWIN),
+ EX(CMD_mzscheme, "mzscheme", ex_mzscheme,
+ RANGE|EXTRA|DFLALL|NEEDARG|CMDWIN|SBOXOK),
+ EX(CMD_mzfile, "mzfile", ex_mzfile,
+ RANGE|FILE1|NEEDARG|CMDWIN),
+ EX(CMD_next, "next", ex_next,
+ RANGE|NOTADR|BANG|FILES|EDITCMD|ARGOPT|TRLBAR),
+ EX(CMD_nbkey, "nbkey", ex_nbkey,
+ EXTRA|NOTADR|NEEDARG),
+ EX(CMD_nbclose, "nbclose", ex_nbclose,
+ TRLBAR|CMDWIN),
+ EX(CMD_nbstart, "nbstart", ex_nbstart,
+ WORD1|TRLBAR|CMDWIN),
+ EX(CMD_new, "new", ex_splitview,
+ BANG|FILE1|RANGE|NOTADR|EDITCMD|ARGOPT|TRLBAR),
+ EX(CMD_nmap, "nmap", ex_map,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_nmapclear, "nmapclear", ex_mapclear,
+ EXTRA|TRLBAR|CMDWIN),
+ EX(CMD_nmenu, "nmenu", ex_menu,
+ RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_nnoremap, "nnoremap", ex_map,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_nnoremenu, "nnoremenu", ex_menu,
+ RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_noremap, "noremap", ex_map,
+ BANG|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_noautocmd, "noautocmd", ex_wrongmodifier,
+ NEEDARG|EXTRA|NOTRLCOM),
+ EX(CMD_nohlsearch, "nohlsearch", ex_nohlsearch,
+ TRLBAR|SBOXOK|CMDWIN),
+ EX(CMD_noreabbrev, "noreabbrev", ex_abbreviate,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_noremenu, "noremenu", ex_menu,
+ RANGE|NOTADR|ZEROR|BANG|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_normal, "normal", ex_normal,
+ RANGE|BANG|EXTRA|NEEDARG|NOTRLCOM|USECTRLV|SBOXOK|CMDWIN),
+ EX(CMD_number, "number", ex_print,
+ RANGE|WHOLEFOLD|COUNT|EXFLAGS|TRLBAR|CMDWIN),
+ EX(CMD_nunmap, "nunmap", ex_unmap,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_nunmenu, "nunmenu", ex_menu,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_open, "open", ex_open,
+ RANGE|BANG|EXTRA),
+ EX(CMD_oldfiles, "oldfiles", ex_oldfiles,
+ BANG|TRLBAR|SBOXOK|CMDWIN),
+ EX(CMD_omap, "omap", ex_map,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_omapclear, "omapclear", ex_mapclear,
+ EXTRA|TRLBAR|CMDWIN),
+ EX(CMD_omenu, "omenu", ex_menu,
+ RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_only, "only", ex_only,
+ BANG|TRLBAR),
+ EX(CMD_onoremap, "onoremap", ex_map,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_onoremenu, "onoremenu", ex_menu,
+ RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_options, "options", ex_options,
+ TRLBAR),
+ EX(CMD_ounmap, "ounmap", ex_unmap,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_ounmenu, "ounmenu", ex_menu,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_ownsyntax, "ownsyntax", ex_ownsyntax,
+ EXTRA|NOTRLCOM|SBOXOK|CMDWIN),
+ EX(CMD_print, "print", ex_print,
+ RANGE|WHOLEFOLD|COUNT|EXFLAGS|TRLBAR|CMDWIN|SBOXOK),
+ EX(CMD_pclose, "pclose", ex_pclose,
+ BANG|TRLBAR),
+ EX(CMD_perl, "perl", ex_perl,
+ RANGE|EXTRA|DFLALL|NEEDARG|SBOXOK|CMDWIN),
+ EX(CMD_perldo, "perldo", ex_perldo,
+ RANGE|EXTRA|DFLALL|NEEDARG|CMDWIN),
+ EX(CMD_pedit, "pedit", ex_pedit,
+ BANG|FILE1|EDITCMD|ARGOPT|TRLBAR),
+ EX(CMD_pop, "pop", ex_tag,
+ RANGE|NOTADR|BANG|COUNT|TRLBAR|ZEROR),
+ EX(CMD_popup, "popup", ex_popup,
+ NEEDARG|EXTRA|BANG|TRLBAR|NOTRLCOM|CMDWIN),
+ EX(CMD_ppop, "ppop", ex_ptag,
+ RANGE|NOTADR|BANG|COUNT|TRLBAR|ZEROR),
+ EX(CMD_preserve, "preserve", ex_preserve,
+ TRLBAR),
+ EX(CMD_previous, "previous", ex_previous,
+ EXTRA|RANGE|NOTADR|COUNT|BANG|EDITCMD|ARGOPT|TRLBAR),
+ EX(CMD_promptfind, "promptfind", gui_mch_find_dialog,
+ EXTRA|NOTRLCOM|CMDWIN),
+ EX(CMD_promptrepl, "promptrepl", gui_mch_replace_dialog,
+ EXTRA|NOTRLCOM|CMDWIN),
+ EX(CMD_profile, "profile", ex_profile,
+ BANG|EXTRA|TRLBAR|CMDWIN),
+ EX(CMD_profdel, "profdel", ex_breakdel,
+ EXTRA|TRLBAR|CMDWIN),
+ EX(CMD_psearch, "psearch", ex_psearch,
+ BANG|RANGE|WHOLEFOLD|DFLALL|EXTRA),
+ EX(CMD_ptag, "ptag", ex_ptag,
+ RANGE|NOTADR|BANG|WORD1|TRLBAR|ZEROR),
+ EX(CMD_ptNext, "ptNext", ex_ptag,
+ RANGE|NOTADR|BANG|TRLBAR|ZEROR),
+ EX(CMD_ptfirst, "ptfirst", ex_ptag,
+ RANGE|NOTADR|BANG|TRLBAR|ZEROR),
+ EX(CMD_ptjump, "ptjump", ex_ptag,
+ BANG|TRLBAR|WORD1),
+ EX(CMD_ptlast, "ptlast", ex_ptag,
+ BANG|TRLBAR),
+ EX(CMD_ptnext, "ptnext", ex_ptag,
+ RANGE|NOTADR|BANG|TRLBAR|ZEROR),
+ EX(CMD_ptprevious, "ptprevious", ex_ptag,
+ RANGE|NOTADR|BANG|TRLBAR|ZEROR),
+ EX(CMD_ptrewind, "ptrewind", ex_ptag,
+ RANGE|NOTADR|BANG|TRLBAR|ZEROR),
+ EX(CMD_ptselect, "ptselect", ex_ptag,
+ BANG|TRLBAR|WORD1),
+ EX(CMD_put, "put", ex_put,
+ RANGE|WHOLEFOLD|BANG|REGSTR|TRLBAR|ZEROR|CMDWIN|MODIFY),
+ EX(CMD_pwd, "pwd", ex_pwd,
+ TRLBAR|CMDWIN),
+ EX(CMD_python, "python", ex_python,
+ RANGE|EXTRA|NEEDARG|CMDWIN),
+ EX(CMD_pydo, "pydo", ex_pydo,
+ RANGE|DFLALL|EXTRA|NEEDARG|CMDWIN),
+ EX(CMD_pyfile, "pyfile", ex_pyfile,
+ RANGE|FILE1|NEEDARG|CMDWIN),
+ EX(CMD_py3, "py3", ex_py3,
+ RANGE|EXTRA|NEEDARG|CMDWIN),
+ EX(CMD_py3do, "py3do", ex_py3do,
+ RANGE|DFLALL|EXTRA|NEEDARG|CMDWIN),
+ EX(CMD_python3, "python3", ex_py3,
+ RANGE|EXTRA|NEEDARG|CMDWIN),
+ EX(CMD_py3file, "py3file", ex_py3file,
+ RANGE|FILE1|NEEDARG|CMDWIN),
+ EX(CMD_quit, "quit", ex_quit,
+ BANG|TRLBAR|CMDWIN),
+ EX(CMD_quitall, "quitall", ex_quit_all,
+ BANG|TRLBAR),
+ EX(CMD_qall, "qall", ex_quit_all,
+ BANG|TRLBAR|CMDWIN),
+ EX(CMD_read, "read", ex_read,
+ BANG|RANGE|WHOLEFOLD|FILE1|ARGOPT|TRLBAR|ZEROR|CMDWIN|MODIFY),
+ EX(CMD_recover, "recover", ex_recover,
+ BANG|FILE1|TRLBAR),
+ EX(CMD_redo, "redo", ex_redo,
+ TRLBAR|CMDWIN),
+ EX(CMD_redir, "redir", ex_redir,
+ BANG|FILES|TRLBAR|CMDWIN),
+ EX(CMD_redraw, "redraw", ex_redraw,
+ BANG|TRLBAR|CMDWIN),
+ EX(CMD_redrawstatus, "redrawstatus", ex_redrawstatus,
+ BANG|TRLBAR|CMDWIN),
+ EX(CMD_registers, "registers", ex_display,
+ EXTRA|NOTRLCOM|TRLBAR|CMDWIN),
+ EX(CMD_resize, "resize", ex_resize,
+ RANGE|NOTADR|TRLBAR|WORD1),
+ EX(CMD_retab, "retab", ex_retab,
+ TRLBAR|RANGE|WHOLEFOLD|DFLALL|BANG|WORD1|CMDWIN|MODIFY),
+ EX(CMD_return, "return", ex_return,
+ EXTRA|NOTRLCOM|SBOXOK|CMDWIN),
+ EX(CMD_rewind, "rewind", ex_rewind,
+ EXTRA|BANG|EDITCMD|ARGOPT|TRLBAR),
+ EX(CMD_right, "right", ex_align,
+ TRLBAR|RANGE|WHOLEFOLD|EXTRA|CMDWIN|MODIFY),
+ EX(CMD_rightbelow, "rightbelow", ex_wrongmodifier,
+ NEEDARG|EXTRA|NOTRLCOM),
+ EX(CMD_runtime, "runtime", ex_runtime,
+ BANG|NEEDARG|FILES|TRLBAR|SBOXOK|CMDWIN),
+ EX(CMD_ruby, "ruby", ex_ruby,
+ RANGE|EXTRA|NEEDARG|CMDWIN),
+ EX(CMD_rubydo, "rubydo", ex_rubydo,
+ RANGE|DFLALL|EXTRA|NEEDARG|CMDWIN),
+ EX(CMD_rubyfile, "rubyfile", ex_rubyfile,
+ RANGE|FILE1|NEEDARG|CMDWIN),
+ EX(CMD_rundo, "rundo", ex_rundo,
+ NEEDARG|FILE1),
+ EX(CMD_rviminfo, "rviminfo", ex_viminfo,
+ BANG|FILE1|TRLBAR|CMDWIN),
+ EX(CMD_substitute, "substitute", do_sub,
+ RANGE|WHOLEFOLD|EXTRA|CMDWIN),
+ EX(CMD_sNext, "sNext", ex_previous,
+ EXTRA|RANGE|NOTADR|COUNT|BANG|EDITCMD|ARGOPT|TRLBAR),
+ EX(CMD_sargument, "sargument", ex_argument,
+ BANG|RANGE|NOTADR|COUNT|EXTRA|EDITCMD|ARGOPT|TRLBAR),
+ EX(CMD_sall, "sall", ex_all,
+ BANG|RANGE|NOTADR|COUNT|TRLBAR),
+ EX(CMD_sandbox, "sandbox", ex_wrongmodifier,
+ NEEDARG|EXTRA|NOTRLCOM),
+ EX(CMD_saveas, "saveas", ex_write,
+ BANG|DFLALL|FILE1|ARGOPT|CMDWIN|TRLBAR),
+ EX(CMD_sbuffer, "sbuffer", ex_buffer,
+ BANG|RANGE|NOTADR|BUFNAME|BUFUNL|COUNT|EXTRA|TRLBAR),
+ EX(CMD_sbNext, "sbNext", ex_bprevious,
+ RANGE|NOTADR|COUNT|TRLBAR),
+ EX(CMD_sball, "sball", ex_buffer_all,
+ RANGE|NOTADR|COUNT|TRLBAR),
+ EX(CMD_sbfirst, "sbfirst", ex_brewind,
+ TRLBAR),
+ EX(CMD_sblast, "sblast", ex_blast,
+ TRLBAR),
+ EX(CMD_sbmodified, "sbmodified", ex_bmodified,
+ RANGE|NOTADR|COUNT|TRLBAR),
+ EX(CMD_sbnext, "sbnext", ex_bnext,
+ RANGE|NOTADR|COUNT|TRLBAR),
+ EX(CMD_sbprevious, "sbprevious", ex_bprevious,
+ RANGE|NOTADR|COUNT|TRLBAR),
+ EX(CMD_sbrewind, "sbrewind", ex_brewind,
+ TRLBAR),
+ EX(CMD_scriptnames, "scriptnames", ex_scriptnames,
+ TRLBAR|CMDWIN),
+ EX(CMD_scriptencoding, "scriptencoding", ex_scriptencoding,
+ WORD1|TRLBAR|CMDWIN),
+ EX(CMD_scscope, "scscope", do_scscope,
+ EXTRA|NOTRLCOM),
+ EX(CMD_set, "set", ex_set,
+ TRLBAR|EXTRA|CMDWIN|SBOXOK),
+ EX(CMD_setfiletype, "setfiletype", ex_setfiletype,
+ TRLBAR|EXTRA|NEEDARG|CMDWIN),
+ EX(CMD_setglobal, "setglobal", ex_set,
+ TRLBAR|EXTRA|CMDWIN|SBOXOK),
+ EX(CMD_setlocal, "setlocal", ex_set,
+ TRLBAR|EXTRA|CMDWIN|SBOXOK),
+ EX(CMD_sfind, "sfind", ex_splitview,
+ BANG|FILE1|RANGE|NOTADR|EDITCMD|ARGOPT|TRLBAR),
+ EX(CMD_sfirst, "sfirst", ex_rewind,
+ EXTRA|BANG|EDITCMD|ARGOPT|TRLBAR),
+ EX(CMD_shell, "shell", ex_shell,
+ TRLBAR|CMDWIN),
+ EX(CMD_simalt, "simalt", ex_simalt,
+ NEEDARG|WORD1|TRLBAR|CMDWIN),
+ EX(CMD_sign, "sign", ex_sign,
+ NEEDARG|RANGE|NOTADR|EXTRA|CMDWIN),
+ EX(CMD_silent, "silent", ex_wrongmodifier,
+ NEEDARG|EXTRA|BANG|NOTRLCOM|SBOXOK|CMDWIN),
+ EX(CMD_sleep, "sleep", ex_sleep,
+ RANGE|NOTADR|COUNT|EXTRA|TRLBAR|CMDWIN),
+ EX(CMD_slast, "slast", ex_last,
+ EXTRA|BANG|EDITCMD|ARGOPT|TRLBAR),
+ EX(CMD_smagic, "smagic", ex_submagic,
+ RANGE|WHOLEFOLD|EXTRA|CMDWIN),
+ EX(CMD_smap, "smap", ex_map,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_smapclear, "smapclear", ex_mapclear,
+ EXTRA|TRLBAR|CMDWIN),
+ EX(CMD_smenu, "smenu", ex_menu,
+ RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_snext, "snext", ex_next,
+ RANGE|NOTADR|BANG|FILES|EDITCMD|ARGOPT|TRLBAR),
+ EX(CMD_sniff, "sniff", ex_sniff,
+ EXTRA|TRLBAR),
+ EX(CMD_snomagic, "snomagic", ex_submagic,
+ RANGE|WHOLEFOLD|EXTRA|CMDWIN),
+ EX(CMD_snoremap, "snoremap", ex_map,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_snoremenu, "snoremenu", ex_menu,
+ RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_source, "source", ex_source,
+ BANG|FILE1|TRLBAR|SBOXOK|CMDWIN),
+ EX(CMD_sort, "sort", ex_sort,
+ RANGE|DFLALL|WHOLEFOLD|BANG|EXTRA|NOTRLCOM|MODIFY),
+ EX(CMD_split, "split", ex_splitview,
+ BANG|FILE1|RANGE|NOTADR|EDITCMD|ARGOPT|TRLBAR),
+ EX(CMD_spellgood, "spellgood", ex_spell,
+ BANG|RANGE|NOTADR|NEEDARG|EXTRA|TRLBAR),
+ EX(CMD_spelldump, "spelldump", ex_spelldump,
+ BANG|TRLBAR),
+ EX(CMD_spellinfo, "spellinfo", ex_spellinfo,
+ TRLBAR),
+ EX(CMD_spellrepall, "spellrepall", ex_spellrepall,
+ TRLBAR),
+ EX(CMD_spellundo, "spellundo", ex_spell,
+ BANG|RANGE|NOTADR|NEEDARG|EXTRA|TRLBAR),
+ EX(CMD_spellwrong, "spellwrong", ex_spell,
+ BANG|RANGE|NOTADR|NEEDARG|EXTRA|TRLBAR),
+ EX(CMD_sprevious, "sprevious", ex_previous,
+ EXTRA|RANGE|NOTADR|COUNT|BANG|EDITCMD|ARGOPT|TRLBAR),
+ EX(CMD_srewind, "srewind", ex_rewind,
+ EXTRA|BANG|EDITCMD|ARGOPT|TRLBAR),
+ EX(CMD_stop, "stop", ex_stop,
+ TRLBAR|BANG|CMDWIN),
+ EX(CMD_stag, "stag", ex_stag,
+ RANGE|NOTADR|BANG|WORD1|TRLBAR|ZEROR),
+ EX(CMD_startinsert, "startinsert", ex_startinsert,
+ BANG|TRLBAR|CMDWIN),
+ EX(CMD_startgreplace, "startgreplace", ex_startinsert,
+ BANG|TRLBAR|CMDWIN),
+ EX(CMD_startreplace, "startreplace", ex_startinsert,
+ BANG|TRLBAR|CMDWIN),
+ EX(CMD_stopinsert, "stopinsert", ex_stopinsert,
+ BANG|TRLBAR|CMDWIN),
+ EX(CMD_stjump, "stjump", ex_stag,
+ BANG|TRLBAR|WORD1),
+ EX(CMD_stselect, "stselect", ex_stag,
+ BANG|TRLBAR|WORD1),
+ EX(CMD_sunhide, "sunhide", ex_buffer_all,
+ RANGE|NOTADR|COUNT|TRLBAR),
+ EX(CMD_sunmap, "sunmap", ex_unmap,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_sunmenu, "sunmenu", ex_menu,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_suspend, "suspend", ex_stop,
+ TRLBAR|BANG|CMDWIN),
+ EX(CMD_sview, "sview", ex_splitview,
+ BANG|FILE1|RANGE|NOTADR|EDITCMD|ARGOPT|TRLBAR),
+ EX(CMD_swapname, "swapname", ex_swapname,
+ TRLBAR|CMDWIN),
+ EX(CMD_syntax, "syntax", ex_syntax,
+ EXTRA|NOTRLCOM|CMDWIN),
+ EX(CMD_syntime, "syntime", ex_syntime,
+ NEEDARG|WORD1|TRLBAR|CMDWIN),
+ EX(CMD_syncbind, "syncbind", ex_syncbind,
+ TRLBAR),
+ EX(CMD_t, "t", ex_copymove,
+ RANGE|WHOLEFOLD|EXTRA|TRLBAR|CMDWIN|MODIFY),
+ EX(CMD_tNext, "tNext", ex_tag,
+ RANGE|NOTADR|BANG|TRLBAR|ZEROR),
+ EX(CMD_tag, "tag", ex_tag,
+ RANGE|NOTADR|BANG|WORD1|TRLBAR|ZEROR),
+ EX(CMD_tags, "tags", do_tags,
+ TRLBAR|CMDWIN),
+ EX(CMD_tab, "tab", ex_wrongmodifier,
+ NEEDARG|EXTRA|NOTRLCOM),
+ EX(CMD_tabclose, "tabclose", ex_tabclose,
+ RANGE|NOTADR|COUNT|BANG|TRLBAR|CMDWIN),
+ EX(CMD_tabdo, "tabdo", ex_listdo,
+ NEEDARG|EXTRA|NOTRLCOM),
+ EX(CMD_tabedit, "tabedit", ex_splitview,
+ BANG|FILE1|RANGE|NOTADR|ZEROR|EDITCMD|ARGOPT|TRLBAR),
+ EX(CMD_tabfind, "tabfind", ex_splitview,
+ BANG|FILE1|RANGE|NOTADR|ZEROR|EDITCMD|ARGOPT|NEEDARG|TRLBAR),
+ EX(CMD_tabfirst, "tabfirst", ex_tabnext,
+ TRLBAR),
+ EX(CMD_tabmove, "tabmove", ex_tabmove,
+ RANGE|NOTADR|ZEROR|EXTRA|NOSPC|TRLBAR),
+ EX(CMD_tablast, "tablast", ex_tabnext,
+ TRLBAR),
+ EX(CMD_tabnext, "tabnext", ex_tabnext,
+ RANGE|NOTADR|COUNT|TRLBAR),
+ EX(CMD_tabnew, "tabnew", ex_splitview,
+ BANG|FILE1|RANGE|NOTADR|ZEROR|EDITCMD|ARGOPT|TRLBAR),
+ EX(CMD_tabonly, "tabonly", ex_tabonly,
+ BANG|TRLBAR|CMDWIN),
+ EX(CMD_tabprevious, "tabprevious", ex_tabnext,
+ RANGE|NOTADR|COUNT|TRLBAR),
+ EX(CMD_tabNext, "tabNext", ex_tabnext,
+ RANGE|NOTADR|COUNT|TRLBAR),
+ EX(CMD_tabrewind, "tabrewind", ex_tabnext,
+ TRLBAR),
+ EX(CMD_tabs, "tabs", ex_tabs,
+ TRLBAR|CMDWIN),
+ EX(CMD_tcl, "tcl", ex_tcl,
+ RANGE|EXTRA|NEEDARG|CMDWIN),
+ EX(CMD_tcldo, "tcldo", ex_tcldo,
+ RANGE|DFLALL|EXTRA|NEEDARG|CMDWIN),
+ EX(CMD_tclfile, "tclfile", ex_tclfile,
+ RANGE|FILE1|NEEDARG|CMDWIN),
+ EX(CMD_tearoff, "tearoff", ex_tearoff,
+ NEEDARG|EXTRA|TRLBAR|NOTRLCOM|CMDWIN),
+ EX(CMD_tfirst, "tfirst", ex_tag,
+ RANGE|NOTADR|BANG|TRLBAR|ZEROR),
+ EX(CMD_throw, "throw", ex_throw,
+ EXTRA|NEEDARG|SBOXOK|CMDWIN),
+ EX(CMD_tjump, "tjump", ex_tag,
+ BANG|TRLBAR|WORD1),
+ EX(CMD_tlast, "tlast", ex_tag,
+ BANG|TRLBAR),
+ EX(CMD_tmenu, "tmenu", ex_menu,
+ RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_tnext, "tnext", ex_tag,
+ RANGE|NOTADR|BANG|TRLBAR|ZEROR),
+ EX(CMD_topleft, "topleft", ex_wrongmodifier,
+ NEEDARG|EXTRA|NOTRLCOM),
+ EX(CMD_tprevious, "tprevious", ex_tag,
+ RANGE|NOTADR|BANG|TRLBAR|ZEROR),
+ EX(CMD_trewind, "trewind", ex_tag,
+ RANGE|NOTADR|BANG|TRLBAR|ZEROR),
+ EX(CMD_try, "try", ex_try,
+ TRLBAR|SBOXOK|CMDWIN),
+ EX(CMD_tselect, "tselect", ex_tag,
+ BANG|TRLBAR|WORD1),
+ EX(CMD_tunmenu, "tunmenu", ex_menu,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_undo, "undo", ex_undo,
+ RANGE|NOTADR|COUNT|ZEROR|TRLBAR|CMDWIN),
+ EX(CMD_undojoin, "undojoin", ex_undojoin,
+ TRLBAR|CMDWIN),
+ EX(CMD_undolist, "undolist", ex_undolist,
+ TRLBAR|CMDWIN),
+ EX(CMD_unabbreviate, "unabbreviate", ex_abbreviate,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_unhide, "unhide", ex_buffer_all,
+ RANGE|NOTADR|COUNT|TRLBAR),
+ EX(CMD_unlet, "unlet", ex_unlet,
+ BANG|EXTRA|NEEDARG|SBOXOK|CMDWIN),
+ EX(CMD_unlockvar, "unlockvar", ex_lockvar,
+ BANG|EXTRA|NEEDARG|SBOXOK|CMDWIN),
+ EX(CMD_unmap, "unmap", ex_unmap,
+ BANG|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_unmenu, "unmenu", ex_menu,
+ BANG|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_unsilent, "unsilent", ex_wrongmodifier,
+ NEEDARG|EXTRA|NOTRLCOM|SBOXOK|CMDWIN),
+ EX(CMD_update, "update", ex_update,
+ RANGE|WHOLEFOLD|BANG|FILE1|ARGOPT|DFLALL|TRLBAR),
+ EX(CMD_vglobal, "vglobal", ex_global,
+ RANGE|WHOLEFOLD|EXTRA|DFLALL|CMDWIN),
+ EX(CMD_version, "version", ex_version,
+ EXTRA|TRLBAR|CMDWIN),
+ EX(CMD_verbose, "verbose", ex_wrongmodifier,
+ NEEDARG|RANGE|NOTADR|EXTRA|NOTRLCOM|SBOXOK|CMDWIN),
+ EX(CMD_vertical, "vertical", ex_wrongmodifier,
+ NEEDARG|EXTRA|NOTRLCOM),
+ EX(CMD_visual, "visual", ex_edit,
+ BANG|FILE1|EDITCMD|ARGOPT|TRLBAR),
+ EX(CMD_view, "view", ex_edit,
+ BANG|FILE1|EDITCMD|ARGOPT|TRLBAR),
+ EX(CMD_vimgrep, "vimgrep", ex_vimgrep,
+ RANGE|NOTADR|BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE),
+ EX(CMD_vimgrepadd, "vimgrepadd", ex_vimgrep,
+ RANGE|NOTADR|BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE),
+ EX(CMD_viusage, "viusage", ex_viusage,
+ TRLBAR),
+ EX(CMD_vmap, "vmap", ex_map,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_vmapclear, "vmapclear", ex_mapclear,
+ EXTRA|TRLBAR|CMDWIN),
+ EX(CMD_vmenu, "vmenu", ex_menu,
+ RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_vnoremap, "vnoremap", ex_map,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_vnew, "vnew", ex_splitview,
+ BANG|FILE1|RANGE|NOTADR|EDITCMD|ARGOPT|TRLBAR),
+ EX(CMD_vnoremenu, "vnoremenu", ex_menu,
+ RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_vsplit, "vsplit", ex_splitview,
+ BANG|FILE1|RANGE|NOTADR|EDITCMD|ARGOPT|TRLBAR),
+ EX(CMD_vunmap, "vunmap", ex_unmap,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_vunmenu, "vunmenu", ex_menu,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_write, "write", ex_write,
+ RANGE|WHOLEFOLD|BANG|FILE1|ARGOPT|DFLALL|TRLBAR|CMDWIN),
+ EX(CMD_wNext, "wNext", ex_wnext,
+ RANGE|WHOLEFOLD|NOTADR|BANG|FILE1|ARGOPT|TRLBAR),
+ EX(CMD_wall, "wall", do_wqall,
+ BANG|TRLBAR|CMDWIN),
+ EX(CMD_while, "while", ex_while,
+ EXTRA|NOTRLCOM|SBOXOK|CMDWIN),
+ EX(CMD_winsize, "winsize", ex_winsize,
+ EXTRA|NEEDARG|TRLBAR),
+ EX(CMD_wincmd, "wincmd", ex_wincmd,
+ NEEDARG|WORD1|RANGE|NOTADR),
+ EX(CMD_windo, "windo", ex_listdo,
+ BANG|NEEDARG|EXTRA|NOTRLCOM),
+ EX(CMD_winpos, "winpos", ex_winpos,
+ EXTRA|TRLBAR|CMDWIN),
+ EX(CMD_wnext, "wnext", ex_wnext,
+ RANGE|NOTADR|BANG|FILE1|ARGOPT|TRLBAR),
+ EX(CMD_wprevious, "wprevious", ex_wnext,
+ RANGE|NOTADR|BANG|FILE1|ARGOPT|TRLBAR),
+ EX(CMD_wq, "wq", ex_exit,
+ RANGE|WHOLEFOLD|BANG|FILE1|ARGOPT|DFLALL|TRLBAR),
+ EX(CMD_wqall, "wqall", do_wqall,
+ BANG|FILE1|ARGOPT|DFLALL|TRLBAR),
+ EX(CMD_wsverb, "wsverb", ex_wsverb,
+ EXTRA|NOTADR|NEEDARG),
+ EX(CMD_wundo, "wundo", ex_wundo,
+ BANG|NEEDARG|FILE1),
+ EX(CMD_wviminfo, "wviminfo", ex_viminfo,
+ BANG|FILE1|TRLBAR|CMDWIN),
+ EX(CMD_xit, "xit", ex_exit,
+ RANGE|WHOLEFOLD|BANG|FILE1|ARGOPT|DFLALL|TRLBAR|CMDWIN),
+ EX(CMD_xall, "xall", do_wqall,
+ BANG|TRLBAR),
+ EX(CMD_xmap, "xmap", ex_map,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_xmapclear, "xmapclear", ex_mapclear,
+ EXTRA|TRLBAR|CMDWIN),
+ EX(CMD_xmenu, "xmenu", ex_menu,
+ RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_xnoremap, "xnoremap", ex_map,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_xnoremenu, "xnoremenu", ex_menu,
+ RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_xunmap, "xunmap", ex_unmap,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_xunmenu, "xunmenu", ex_menu,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_yank, "yank", ex_operators,
+ RANGE|WHOLEFOLD|REGSTR|COUNT|TRLBAR|CMDWIN),
+ EX(CMD_z, "z", ex_z,
+ RANGE|WHOLEFOLD|EXTRA|EXFLAGS|TRLBAR|CMDWIN),
+
+ /* commands that don't start with a lowercase letter */
+ EX(CMD_bang, "!", ex_bang,
+ RANGE|WHOLEFOLD|BANG|FILES|CMDWIN),
+ EX(CMD_pound, "#", ex_print,
+ RANGE|WHOLEFOLD|COUNT|EXFLAGS|TRLBAR|CMDWIN),
+ EX(CMD_and, "&", do_sub,
+ RANGE|WHOLEFOLD|EXTRA|CMDWIN|MODIFY),
+ EX(CMD_star, "*", ex_at,
+ RANGE|WHOLEFOLD|EXTRA|TRLBAR|CMDWIN),
+ EX(CMD_lshift, "<", ex_operators,
+ RANGE|WHOLEFOLD|COUNT|EXFLAGS|TRLBAR|CMDWIN|MODIFY),
+ EX(CMD_equal, "=", ex_equal,
+ RANGE|TRLBAR|DFLALL|EXFLAGS|CMDWIN),
+ EX(CMD_rshift, ">", ex_operators,
+ RANGE|WHOLEFOLD|COUNT|EXFLAGS|TRLBAR|CMDWIN|MODIFY),
+ EX(CMD_at, "@", ex_at,
+ RANGE|WHOLEFOLD|EXTRA|TRLBAR|CMDWIN),
+ EX(CMD_Next, "Next", ex_previous,
+ EXTRA|RANGE|NOTADR|COUNT|BANG|EDITCMD|ARGOPT|TRLBAR),
+ EX(CMD_Print, "Print", ex_print,
+ RANGE|WHOLEFOLD|COUNT|EXFLAGS|TRLBAR|CMDWIN),
+ EX(CMD_X, "X", ex_X,
+ TRLBAR),
+ EX(CMD_tilde, "~", do_sub,
+ RANGE|WHOLEFOLD|EXTRA|CMDWIN|MODIFY),
+
+#ifndef DO_DECLARE_EXCMD
+ CMD_SIZE, /* MUST be after all real commands! */
+ CMD_USER = -1, /* User-defined command */
+ CMD_USER_BUF = -2 /* User-defined command local to buffer */
+#endif
+};
+
+#define USER_CMDIDX(idx) ((int)(idx) < 0)
+
+#ifndef DO_DECLARE_EXCMD
+typedef enum CMD_index cmdidx_T;
+
+/*
+ * Arguments used for Ex commands.
+ */
+struct exarg {
+ char_u *arg; /* argument of the command */
+ char_u *nextcmd; /* next command (NULL if none) */
+ char_u *cmd; /* the name of the command (except for :make) */
+ char_u **cmdlinep; /* pointer to pointer of allocated cmdline */
+ cmdidx_T cmdidx; /* the index for the command */
+ long argt; /* flags for the command */
+ int skip; /* don't execute the command, only parse it */
+ int forceit; /* TRUE if ! present */
+ int addr_count; /* the number of addresses given */
+ linenr_T line1; /* the first line number */
+ linenr_T line2; /* the second line number or count */
+ int flags; /* extra flags after count: EXFLAG_ */
+ char_u *do_ecmd_cmd; /* +command arg to be used in edited file */
+ linenr_T do_ecmd_lnum; /* the line number in an edited file */
+ int append; /* TRUE with ":w >>file" command */
+ int usefilter; /* TRUE with ":w !command" and ":r!command" */
+ int amount; /* number of '>' or '<' for shift command */
+ int regname; /* register name (NUL if none) */
+ int force_bin; /* 0, FORCE_BIN or FORCE_NOBIN */
+ int read_edit; /* ++edit argument */
+ int force_ff; /* ++ff= argument (index in cmd[]) */
+ int force_enc; /* ++enc= argument (index in cmd[]) */
+ int bad_char; /* BAD_KEEP, BAD_DROP or replacement byte */
+ int useridx; /* user command index */
+ char_u *errmsg; /* returned error message */
+ char_u *(*getline)__ARGS((int, void *, int));
+ void *cookie; /* argument for getline() */
+ 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 */
+
+#endif
diff --git a/src/ex_cmds2.c b/src/ex_cmds2.c
new file mode 100644
index 0000000000..209fcddd67
--- /dev/null
+++ b/src/ex_cmds2.c
@@ -0,0 +1,3613 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * 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.
+ */
+
+/*
+ * ex_cmds2.c: some more functions for command line commands
+ */
+
+#include "vim.h"
+#include "version.h"
+
+static void cmd_source __ARGS((char_u *fname, exarg_T *eap));
+
+/* Growarray to store info about already sourced scripts.
+ * For Unix also store the dev/ino, so that we don't have to stat() each
+ * script when going through the list. */
+typedef struct scriptitem_S {
+ char_u *sn_name;
+# ifdef UNIX
+ int sn_dev_valid;
+ dev_t sn_dev;
+ ino_t sn_ino;
+# endif
+ int sn_prof_on; /* TRUE when script is/was profiled */
+ int sn_pr_force; /* forceit: profile functions in this script */
+ proftime_T sn_pr_child; /* time set when going into first child */
+ int sn_pr_nest; /* nesting for sn_pr_child */
+ /* profiling the script as a whole */
+ int sn_pr_count; /* nr of times sourced */
+ proftime_T sn_pr_total; /* time spent in script + children */
+ proftime_T sn_pr_self; /* time spent in script itself */
+ proftime_T sn_pr_start; /* time at script start */
+ proftime_T sn_pr_children; /* time in children after script start */
+ /* profiling the script per line */
+ garray_T sn_prl_ga; /* things stored for every line */
+ proftime_T sn_prl_start; /* start time for current line */
+ proftime_T sn_prl_children; /* time spent in children for this line */
+ proftime_T sn_prl_wait; /* wait start time for current line */
+ int sn_prl_idx; /* index of line being timed; -1 if none */
+ int sn_prl_execed; /* line being timed was executed */
+} scriptitem_T;
+
+static garray_T script_items = {0, 0, sizeof(scriptitem_T), 4, NULL};
+#define SCRIPT_ITEM(id) (((scriptitem_T *)script_items.ga_data)[(id) - 1])
+
+/* Struct used in sn_prl_ga for every line of a script. */
+typedef struct sn_prl_S {
+ int snp_count; /* nr of times line was executed */
+ proftime_T sn_prl_total; /* time spent in a line + children */
+ proftime_T sn_prl_self; /* time spent in a line itself */
+} sn_prl_T;
+
+# define PRL_ITEM(si, idx) (((sn_prl_T *)(si)->sn_prl_ga.ga_data)[(idx)])
+
+static int debug_greedy = FALSE; /* batch mode debugging: don't save
+ and restore typeahead. */
+
+/*
+ * do_debug(): Debug mode.
+ * Repeatedly get Ex commands, until told to continue normal execution.
+ */
+void do_debug(cmd)
+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;
+ int save_msg_silent = msg_silent;
+ int save_emsg_silent = emsg_silent;
+ int save_redir_off = redir_off;
+ tasave_T typeaheadbuf;
+ int typeahead_saved = FALSE;
+ int save_ignore_script = 0;
+ int save_ex_normal_busy;
+ int n;
+ char_u *cmdline = NULL;
+ char_u *p;
+ char *tail = NULL;
+ static int last_cmd = 0;
+#define CMD_CONT 1
+#define CMD_NEXT 2
+#define CMD_STEP 3
+#define CMD_FINISH 4
+#define CMD_QUIT 5
+#define CMD_INTERRUPT 6
+
+
+ /* Make sure we are in raw mode and start termcap mode. Might have side
+ * effects... */
+ settmode(TMODE_RAW);
+ starttermcap();
+
+ ++RedrawingDisabled; /* don't redisplay the window */
+ ++no_wait_return; /* don't wait for return */
+ did_emsg = FALSE; /* don't use error from debugged stuff */
+ cmd_silent = FALSE; /* display commands */
+ msg_silent = FALSE; /* display messages */
+ emsg_silent = FALSE; /* display error messages */
+ redir_off = TRUE; /* don't redirect debug commands */
+
+ State = NORMAL;
+
+ if (!debug_did_msg)
+ MSG(_("Entering Debug mode. Type \"cont\" to continue."));
+ if (sourcing_name != NULL)
+ msg(sourcing_name);
+ if (sourcing_lnum != 0)
+ smsg((char_u *)_("line %ld: %s"), (long)sourcing_lnum, cmd);
+ else
+ smsg((char_u *)_("cmd: %s"), cmd);
+
+ /*
+ * Repeat getting a command and executing it.
+ */
+ for (;; ) {
+ msg_scroll = TRUE;
+ need_wait_return = FALSE;
+ /* Save the current typeahead buffer and replace it with an empty one.
+ * This makes sure we get input from the user here and don't interfere
+ * with the commands being executed. Reset "ex_normal_busy" to avoid
+ * the side effects of using ":normal". Save the stuff buffer and make
+ * it empty. Set ignore_script to avoid reading from script input. */
+ save_ex_normal_busy = ex_normal_busy;
+ ex_normal_busy = 0;
+ if (!debug_greedy) {
+ save_typeahead(&typeaheadbuf);
+ typeahead_saved = TRUE;
+ save_ignore_script = ignore_script;
+ ignore_script = TRUE;
+ }
+
+ cmdline = getcmdline_prompt('>', NULL, 0, EXPAND_NOTHING, NULL);
+
+ if (typeahead_saved) {
+ restore_typeahead(&typeaheadbuf);
+ ignore_script = save_ignore_script;
+ }
+ ex_normal_busy = save_ex_normal_busy;
+
+ cmdline_row = msg_row;
+ if (cmdline != NULL) {
+ /* If this is a debug command, set "last_cmd".
+ * If not, reset "last_cmd".
+ * For a blank line use previous command. */
+ p = skipwhite(cmdline);
+ if (*p != NUL) {
+ switch (*p) {
+ case 'c': last_cmd = CMD_CONT;
+ tail = "ont";
+ break;
+ case 'n': last_cmd = CMD_NEXT;
+ tail = "ext";
+ break;
+ case 's': last_cmd = CMD_STEP;
+ tail = "tep";
+ break;
+ case 'f': last_cmd = CMD_FINISH;
+ tail = "inish";
+ break;
+ case 'q': last_cmd = CMD_QUIT;
+ tail = "uit";
+ break;
+ case 'i': last_cmd = CMD_INTERRUPT;
+ tail = "nterrupt";
+ break;
+ default: last_cmd = 0;
+ }
+ if (last_cmd != 0) {
+ /* Check that the tail matches. */
+ ++p;
+ while (*p != NUL && *p == *tail) {
+ ++p;
+ ++tail;
+ }
+ if (ASCII_ISALPHA(*p))
+ last_cmd = 0;
+ }
+ }
+
+ if (last_cmd != 0) {
+ /* Execute debug command: decided where to break next and
+ * return. */
+ switch (last_cmd) {
+ case CMD_CONT:
+ debug_break_level = -1;
+ break;
+ case CMD_NEXT:
+ debug_break_level = ex_nesting_level;
+ break;
+ case CMD_STEP:
+ debug_break_level = 9999;
+ break;
+ case CMD_FINISH:
+ debug_break_level = ex_nesting_level - 1;
+ break;
+ case CMD_QUIT:
+ got_int = TRUE;
+ debug_break_level = -1;
+ break;
+ case CMD_INTERRUPT:
+ got_int = TRUE;
+ debug_break_level = 9999;
+ /* Do not repeat ">interrupt" cmd, continue stepping. */
+ last_cmd = CMD_STEP;
+ break;
+ }
+ break;
+ }
+
+ /* don't debug this command */
+ n = debug_break_level;
+ debug_break_level = -1;
+ (void)do_cmdline(cmdline, getexline, NULL,
+ DOCMD_VERBOSE|DOCMD_EXCRESET);
+ debug_break_level = n;
+
+ vim_free(cmdline);
+ }
+ lines_left = Rows - 1;
+ }
+ vim_free(cmdline);
+
+ --RedrawingDisabled;
+ --no_wait_return;
+ redraw_all_later(NOT_VALID);
+ need_wait_return = FALSE;
+ msg_scroll = save_msg_scroll;
+ lines_left = Rows - 1;
+ State = save_State;
+ did_emsg = save_did_emsg;
+ cmd_silent = save_cmd_silent;
+ msg_silent = save_msg_silent;
+ emsg_silent = save_emsg_silent;
+ redir_off = save_redir_off;
+
+ /* Only print the message again when typing a command before coming back
+ * here. */
+ debug_did_msg = TRUE;
+}
+
+/*
+ * ":debug".
+ */
+void ex_debug(eap)
+exarg_T *eap;
+{
+ int debug_break_level_save = debug_break_level;
+
+ debug_break_level = 9999;
+ do_cmdline_cmd(eap->arg);
+ debug_break_level = debug_break_level_save;
+}
+
+static char_u *debug_breakpoint_name = NULL;
+static linenr_T debug_breakpoint_lnum;
+
+/*
+ * When debugging or a breakpoint is set on a skipped command, no debug prompt
+ * is shown by do_one_cmd(). This situation is indicated by debug_skipped, and
+ * debug_skipped_name is then set to the source name in the breakpoint case. If
+ * a skipped command decides itself that a debug prompt should be displayed, it
+ * can do so by calling dbg_check_skipped().
+ */
+static int debug_skipped;
+static char_u *debug_skipped_name;
+
+/*
+ * Go to debug mode when a breakpoint was encountered or "ex_nesting_level" is
+ * at or below the break level. But only when the line is actually
+ * executed. Return TRUE and set breakpoint_name for skipped commands that
+ * decide to execute something themselves.
+ * Called from do_one_cmd() before executing a command.
+ */
+void dbg_check_breakpoint(eap)
+exarg_T *eap;
+{
+ char_u *p;
+
+ debug_skipped = FALSE;
+ if (debug_breakpoint_name != NULL) {
+ if (!eap->skip) {
+ /* replace K_SNR with "<SNR>" */
+ if (debug_breakpoint_name[0] == K_SPECIAL
+ && debug_breakpoint_name[1] == KS_EXTRA
+ && debug_breakpoint_name[2] == (int)KE_SNR)
+ p = (char_u *)"<SNR>";
+ else
+ p = (char_u *)"";
+ smsg((char_u *)_("Breakpoint in \"%s%s\" line %ld"),
+ p,
+ debug_breakpoint_name + (*p == NUL ? 0 : 3),
+ (long)debug_breakpoint_lnum);
+ debug_breakpoint_name = NULL;
+ do_debug(eap->cmd);
+ } else {
+ debug_skipped = TRUE;
+ debug_skipped_name = debug_breakpoint_name;
+ debug_breakpoint_name = NULL;
+ }
+ } else if (ex_nesting_level <= debug_break_level) {
+ if (!eap->skip)
+ do_debug(eap->cmd);
+ else {
+ debug_skipped = TRUE;
+ debug_skipped_name = NULL;
+ }
+ }
+}
+
+/*
+ * Go to debug mode if skipped by dbg_check_breakpoint() because eap->skip was
+ * set. Return TRUE when the debug mode is entered this time.
+ */
+int dbg_check_skipped(eap)
+exarg_T *eap;
+{
+ int prev_got_int;
+
+ if (debug_skipped) {
+ /*
+ * Save the value of got_int and reset it. We don't want a previous
+ * interruption cause flushing the input buffer.
+ */
+ prev_got_int = got_int;
+ got_int = FALSE;
+ debug_breakpoint_name = debug_skipped_name;
+ /* eap->skip is TRUE */
+ eap->skip = FALSE;
+ (void)dbg_check_breakpoint(eap);
+ eap->skip = TRUE;
+ got_int |= prev_got_int;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*
+ * The list of breakpoints: dbg_breakp.
+ * This is a grow-array of structs.
+ */
+struct debuggy {
+ int dbg_nr; /* breakpoint number */
+ int dbg_type; /* DBG_FUNC or DBG_FILE */
+ char_u *dbg_name; /* function or file name */
+ regprog_T *dbg_prog; /* regexp program */
+ linenr_T dbg_lnum; /* line number in function or file */
+ int dbg_forceit; /* ! used */
+};
+
+static garray_T dbg_breakp = {0, 0, sizeof(struct debuggy), 4, NULL};
+#define BREAKP(idx) (((struct debuggy *)dbg_breakp.ga_data)[idx])
+#define DEBUGGY(gap, idx) (((struct debuggy *)gap->ga_data)[idx])
+static int last_breakp = 0; /* nr of last defined breakpoint */
+
+/* Profiling uses file and func names similar to breakpoints. */
+static garray_T prof_ga = {0, 0, sizeof(struct debuggy), 4, NULL};
+#define DBG_FUNC 1
+#define DBG_FILE 2
+
+static int dbg_parsearg __ARGS((char_u *arg, garray_T *gap));
+static linenr_T debuggy_find __ARGS((int file,char_u *fname, linenr_T after,
+ garray_T *gap,
+ int *fp));
+
+/*
+ * Parse the arguments of ":profile", ":breakadd" or ":breakdel" and put them
+ * in the entry just after the last one in dbg_breakp. Note that "dbg_name"
+ * is allocated.
+ * Returns FAIL for failure.
+ */
+static int dbg_parsearg(arg, gap)
+char_u *arg;
+garray_T *gap; /* either &dbg_breakp or &prof_ga */
+{
+ char_u *p = arg;
+ char_u *q;
+ struct debuggy *bp;
+ int here = FALSE;
+
+ if (ga_grow(gap, 1) == FAIL)
+ return FAIL;
+ bp = &DEBUGGY(gap, gap->ga_len);
+
+ /* Find "func" or "file". */
+ if (STRNCMP(p, "func", 4) == 0)
+ bp->dbg_type = DBG_FUNC;
+ else if (STRNCMP(p, "file", 4) == 0)
+ bp->dbg_type = DBG_FILE;
+ else if (
+ gap != &prof_ga &&
+ STRNCMP(p, "here", 4) == 0) {
+ if (curbuf->b_ffname == NULL) {
+ EMSG(_(e_noname));
+ return FAIL;
+ }
+ bp->dbg_type = DBG_FILE;
+ here = TRUE;
+ } else {
+ EMSG2(_(e_invarg2), p);
+ return FAIL;
+ }
+ p = skipwhite(p + 4);
+
+ /* Find optional line number. */
+ if (here)
+ bp->dbg_lnum = curwin->w_cursor.lnum;
+ else if (
+ gap != &prof_ga &&
+ VIM_ISDIGIT(*p)) {
+ bp->dbg_lnum = getdigits(&p);
+ p = skipwhite(p);
+ } else
+ bp->dbg_lnum = 0;
+
+ /* Find the function or file name. Don't accept a function name with (). */
+ if ((!here && *p == NUL)
+ || (here && *p != NUL)
+ || (bp->dbg_type == DBG_FUNC && strstr((char *)p, "()") != NULL)) {
+ EMSG2(_(e_invarg2), arg);
+ return FAIL;
+ }
+
+ if (bp->dbg_type == DBG_FUNC)
+ bp->dbg_name = vim_strsave(p);
+ else if (here)
+ bp->dbg_name = vim_strsave(curbuf->b_ffname);
+ else {
+ /* Expand the file name in the same way as do_source(). This means
+ * doing it twice, so that $DIR/file gets expanded when $DIR is
+ * "~/dir". */
+ q = expand_env_save(p);
+ if (q == NULL)
+ return FAIL;
+ p = expand_env_save(q);
+ vim_free(q);
+ if (p == NULL)
+ return FAIL;
+ if (*p != '*') {
+ bp->dbg_name = fix_fname(p);
+ vim_free(p);
+ } else
+ bp->dbg_name = p;
+ }
+
+ if (bp->dbg_name == NULL)
+ return FAIL;
+ return OK;
+}
+
+/*
+ * ":breakadd".
+ */
+void ex_breakadd(eap)
+exarg_T *eap;
+{
+ struct debuggy *bp;
+ char_u *pat;
+ garray_T *gap;
+
+ gap = &dbg_breakp;
+ if (eap->cmdidx == CMD_profile)
+ gap = &prof_ga;
+
+ if (dbg_parsearg(eap->arg, gap) == OK) {
+ bp = &DEBUGGY(gap, gap->ga_len);
+ bp->dbg_forceit = eap->forceit;
+
+ pat = file_pat_to_reg_pat(bp->dbg_name, NULL, NULL, FALSE);
+ if (pat != NULL) {
+ bp->dbg_prog = vim_regcomp(pat, RE_MAGIC + RE_STRING);
+ vim_free(pat);
+ }
+ if (pat == NULL || bp->dbg_prog == NULL)
+ vim_free(bp->dbg_name);
+ else {
+ if (bp->dbg_lnum == 0) /* default line number is 1 */
+ bp->dbg_lnum = 1;
+ if (eap->cmdidx != CMD_profile) {
+ DEBUGGY(gap, gap->ga_len).dbg_nr = ++last_breakp;
+ ++debug_tick;
+ }
+ ++gap->ga_len;
+ }
+ }
+}
+
+/*
+ * ":debuggreedy".
+ */
+void ex_debuggreedy(eap)
+exarg_T *eap;
+{
+ if (eap->addr_count == 0 || eap->line2 != 0)
+ debug_greedy = TRUE;
+ else
+ debug_greedy = FALSE;
+}
+
+/*
+ * ":breakdel" and ":profdel".
+ */
+void ex_breakdel(eap)
+exarg_T *eap;
+{
+ struct debuggy *bp, *bpi;
+ int nr;
+ int todel = -1;
+ int del_all = FALSE;
+ int i;
+ linenr_T best_lnum = 0;
+ garray_T *gap;
+
+ gap = &dbg_breakp;
+ if (eap->cmdidx == CMD_profdel) {
+ gap = &prof_ga;
+ }
+
+ if (vim_isdigit(*eap->arg)) {
+ /* ":breakdel {nr}" */
+ nr = atol((char *)eap->arg);
+ for (i = 0; i < gap->ga_len; ++i)
+ if (DEBUGGY(gap, i).dbg_nr == nr) {
+ todel = i;
+ break;
+ }
+ } else if (*eap->arg == '*') {
+ todel = 0;
+ del_all = TRUE;
+ } else {
+ /* ":breakdel {func|file} [lnum] {name}" */
+ if (dbg_parsearg(eap->arg, gap) == FAIL)
+ return;
+ bp = &DEBUGGY(gap, gap->ga_len);
+ for (i = 0; i < gap->ga_len; ++i) {
+ bpi = &DEBUGGY(gap, i);
+ if (bp->dbg_type == bpi->dbg_type
+ && STRCMP(bp->dbg_name, bpi->dbg_name) == 0
+ && (bp->dbg_lnum == bpi->dbg_lnum
+ || (bp->dbg_lnum == 0
+ && (best_lnum == 0
+ || bpi->dbg_lnum < best_lnum)))) {
+ todel = i;
+ best_lnum = bpi->dbg_lnum;
+ }
+ }
+ vim_free(bp->dbg_name);
+ }
+
+ if (todel < 0)
+ EMSG2(_("E161: Breakpoint not found: %s"), eap->arg);
+ else {
+ while (gap->ga_len > 0) {
+ vim_free(DEBUGGY(gap, todel).dbg_name);
+ vim_regfree(DEBUGGY(gap, todel).dbg_prog);
+ --gap->ga_len;
+ if (todel < gap->ga_len)
+ mch_memmove(&DEBUGGY(gap, todel), &DEBUGGY(gap, todel + 1),
+ (gap->ga_len - todel) * sizeof(struct debuggy));
+ if (eap->cmdidx == CMD_breakdel)
+ ++debug_tick;
+ if (!del_all)
+ break;
+ }
+
+ /* If all breakpoints were removed clear the array. */
+ if (gap->ga_len == 0)
+ ga_clear(gap);
+ }
+}
+
+/*
+ * ":breaklist".
+ */
+void ex_breaklist(eap)
+exarg_T *eap UNUSED;
+{
+ struct debuggy *bp;
+ int i;
+
+ if (dbg_breakp.ga_len == 0)
+ MSG(_("No breakpoints defined"));
+ else
+ for (i = 0; i < dbg_breakp.ga_len; ++i) {
+ bp = &BREAKP(i);
+ if (bp->dbg_type == DBG_FILE)
+ home_replace(NULL, bp->dbg_name, NameBuff, MAXPATHL, TRUE);
+ smsg((char_u *)_("%3d %s %s line %ld"),
+ bp->dbg_nr,
+ bp->dbg_type == DBG_FUNC ? "func" : "file",
+ bp->dbg_type == DBG_FUNC ? bp->dbg_name : NameBuff,
+ (long)bp->dbg_lnum);
+ }
+}
+
+/*
+ * Find a breakpoint for a function or sourced file.
+ * Returns line number at which to break; zero when no matching breakpoint.
+ */
+linenr_T dbg_find_breakpoint(file, fname, after)
+int file; /* TRUE for a file, FALSE for a function */
+char_u *fname; /* file or function name */
+linenr_T after; /* after this line number */
+{
+ return debuggy_find(file, fname, after, &dbg_breakp, NULL);
+}
+
+/*
+ * Return TRUE if profiling is on for a function or sourced file.
+ */
+int has_profiling(file, fname, fp)
+int file; /* TRUE for a file, FALSE for a function */
+char_u *fname; /* file or function name */
+int *fp; /* return: forceit */
+{
+ return debuggy_find(file, fname, (linenr_T)0, &prof_ga, fp)
+ != (linenr_T)0;
+}
+
+/*
+ * Common code for dbg_find_breakpoint() and has_profiling().
+ */
+static linenr_T debuggy_find(file, fname, after, gap, fp)
+int file; /* TRUE for a file, FALSE for a function */
+char_u *fname; /* file or function name */
+linenr_T after; /* after this line number */
+garray_T *gap; /* either &dbg_breakp or &prof_ga */
+int *fp; /* if not NULL: return forceit */
+{
+ struct debuggy *bp;
+ int i;
+ linenr_T lnum = 0;
+ regmatch_T regmatch;
+ char_u *name = fname;
+ int prev_got_int;
+
+ /* Return quickly when there are no breakpoints. */
+ if (gap->ga_len == 0)
+ return (linenr_T)0;
+
+ /* Replace K_SNR in function name with "<SNR>". */
+ if (!file && fname[0] == K_SPECIAL) {
+ name = alloc((unsigned)STRLEN(fname) + 3);
+ if (name == NULL)
+ name = fname;
+ else {
+ STRCPY(name, "<SNR>");
+ STRCPY(name + 5, fname + 3);
+ }
+ }
+
+ for (i = 0; i < gap->ga_len; ++i) {
+ /* Skip entries that are not useful or are for a line that is beyond
+ * an already found breakpoint. */
+ bp = &DEBUGGY(gap, i);
+ if (((bp->dbg_type == DBG_FILE) == file && (
+ gap == &prof_ga ||
+ (bp->dbg_lnum > after && (lnum == 0 || bp->dbg_lnum < lnum))))) {
+ regmatch.regprog = bp->dbg_prog;
+ regmatch.rm_ic = FALSE;
+ /*
+ * Save the value of got_int and reset it. We don't want a
+ * previous interruption cancel matching, only hitting CTRL-C
+ * while matching should abort it.
+ */
+ prev_got_int = got_int;
+ got_int = FALSE;
+ if (vim_regexec(&regmatch, name, (colnr_T)0)) {
+ lnum = bp->dbg_lnum;
+ if (fp != NULL)
+ *fp = bp->dbg_forceit;
+ }
+ got_int |= prev_got_int;
+ }
+ }
+ if (name != fname)
+ vim_free(name);
+
+ return lnum;
+}
+
+/*
+ * Called when a breakpoint was encountered.
+ */
+void dbg_breakpoint(name, lnum)
+char_u *name;
+linenr_T lnum;
+{
+ /* We need to check if this line is actually executed in do_one_cmd() */
+ debug_breakpoint_name = name;
+ debug_breakpoint_lnum = lnum;
+}
+
+
+/*
+ * Store the current time in "tm".
+ */
+void profile_start(tm)
+proftime_T *tm;
+{
+ gettimeofday(tm, NULL);
+}
+
+/*
+ * Compute the elapsed time from "tm" till now and store in "tm".
+ */
+void profile_end(tm)
+proftime_T *tm;
+{
+ proftime_T now;
+
+ gettimeofday(&now, NULL);
+ tm->tv_usec = now.tv_usec - tm->tv_usec;
+ tm->tv_sec = now.tv_sec - tm->tv_sec;
+ if (tm->tv_usec < 0) {
+ tm->tv_usec += 1000000;
+ --tm->tv_sec;
+ }
+}
+
+/*
+ * Subtract the time "tm2" from "tm".
+ */
+void profile_sub(tm, tm2)
+proftime_T *tm, *tm2;
+{
+ tm->tv_usec -= tm2->tv_usec;
+ tm->tv_sec -= tm2->tv_sec;
+ if (tm->tv_usec < 0) {
+ tm->tv_usec += 1000000;
+ --tm->tv_sec;
+ }
+}
+
+/*
+ * Return a string that represents the time in "tm".
+ * Uses a static buffer!
+ */
+char * profile_msg(tm)
+proftime_T *tm;
+{
+ static char buf[50];
+
+ sprintf(buf, "%3ld.%06ld", (long)tm->tv_sec, (long)tm->tv_usec);
+ return buf;
+}
+
+/*
+ * Put the time "msec" past now in "tm".
+ */
+void profile_setlimit(msec, tm)
+long msec;
+proftime_T *tm;
+{
+ if (msec <= 0) /* no limit */
+ profile_zero(tm);
+ else {
+ long usec;
+
+ gettimeofday(tm, NULL);
+ usec = (long)tm->tv_usec + (long)msec * 1000;
+ tm->tv_usec = usec % 1000000L;
+ tm->tv_sec += usec / 1000000L;
+ }
+}
+
+/*
+ * Return TRUE if the current time is past "tm".
+ */
+int profile_passed_limit(tm)
+proftime_T *tm;
+{
+ proftime_T now;
+
+ if (tm->tv_sec == 0) /* timer was not set */
+ return FALSE;
+ gettimeofday(&now, NULL);
+ return now.tv_sec > tm->tv_sec
+ || (now.tv_sec == tm->tv_sec && now.tv_usec > tm->tv_usec);
+}
+
+/*
+ * Set the time in "tm" to zero.
+ */
+void profile_zero(tm)
+proftime_T *tm;
+{
+ tm->tv_usec = 0;
+ tm->tv_sec = 0;
+}
+
+
+# if defined(HAVE_MATH_H)
+# include <math.h>
+# endif
+
+/*
+ * Divide the time "tm" by "count" and store in "tm2".
+ */
+void profile_divide(tm, count, tm2)
+proftime_T *tm;
+proftime_T *tm2;
+int count;
+{
+ if (count == 0)
+ profile_zero(tm2);
+ else {
+ double usec = (tm->tv_sec * 1000000.0 + tm->tv_usec) / count;
+
+ tm2->tv_sec = floor(usec / 1000000.0);
+ tm2->tv_usec = vim_round(usec - (tm2->tv_sec * 1000000.0));
+ }
+}
+
+/*
+ * Functions for profiling.
+ */
+static void script_do_profile __ARGS((scriptitem_T *si));
+static void script_dump_profile __ARGS((FILE *fd));
+static proftime_T prof_wait_time;
+
+/*
+ * Add the time "tm2" to "tm".
+ */
+void profile_add(tm, tm2)
+proftime_T *tm, *tm2;
+{
+ tm->tv_usec += tm2->tv_usec;
+ tm->tv_sec += tm2->tv_sec;
+ if (tm->tv_usec >= 1000000) {
+ tm->tv_usec -= 1000000;
+ ++tm->tv_sec;
+ }
+}
+
+/*
+ * Add the "self" time from the total time and the children's time.
+ */
+void profile_self(self, total, children)
+proftime_T *self, *total, *children;
+{
+ /* Check that the result won't be negative. Can happen with recursive
+ * calls. */
+ if (total->tv_sec < children->tv_sec
+ || (total->tv_sec == children->tv_sec
+ && total->tv_usec <= children->tv_usec))
+ return;
+ profile_add(self, total);
+ profile_sub(self, children);
+}
+
+/*
+ * Get the current waittime.
+ */
+void profile_get_wait(tm)
+proftime_T *tm;
+{
+ *tm = prof_wait_time;
+}
+
+/*
+ * Subtract the passed waittime since "tm" from "tma".
+ */
+void profile_sub_wait(tm, tma)
+proftime_T *tm, *tma;
+{
+ proftime_T tm3 = prof_wait_time;
+
+ profile_sub(&tm3, tm);
+ profile_sub(tma, &tm3);
+}
+
+/*
+ * Return TRUE if "tm1" and "tm2" are equal.
+ */
+int profile_equal(tm1, tm2)
+proftime_T *tm1, *tm2;
+{
+ return tm1->tv_usec == tm2->tv_usec && tm1->tv_sec == tm2->tv_sec;
+}
+
+/*
+ * Return <0, 0 or >0 if "tm1" < "tm2", "tm1" == "tm2" or "tm1" > "tm2"
+ */
+int profile_cmp(tm1, tm2)
+const proftime_T *tm1, *tm2;
+{
+ if (tm1->tv_sec == tm2->tv_sec)
+ return tm2->tv_usec - tm1->tv_usec;
+ return tm2->tv_sec - tm1->tv_sec;
+}
+
+static char_u *profile_fname = NULL;
+static proftime_T pause_time;
+
+/*
+ * ":profile cmd args"
+ */
+void ex_profile(eap)
+exarg_T *eap;
+{
+ char_u *e;
+ int len;
+
+ e = skiptowhite(eap->arg);
+ len = (int)(e - eap->arg);
+ e = skipwhite(e);
+
+ if (len == 5 && STRNCMP(eap->arg, "start", 5) == 0 && *e != NUL) {
+ vim_free(profile_fname);
+ profile_fname = vim_strsave(e);
+ do_profiling = PROF_YES;
+ profile_zero(&prof_wait_time);
+ set_vim_var_nr(VV_PROFILING, 1L);
+ } else if (do_profiling == PROF_NONE)
+ EMSG(_("E750: First use \":profile start {fname}\""));
+ else if (STRCMP(eap->arg, "pause") == 0) {
+ if (do_profiling == PROF_YES)
+ profile_start(&pause_time);
+ do_profiling = PROF_PAUSED;
+ } else if (STRCMP(eap->arg, "continue") == 0) {
+ if (do_profiling == PROF_PAUSED) {
+ profile_end(&pause_time);
+ profile_add(&prof_wait_time, &pause_time);
+ }
+ do_profiling = PROF_YES;
+ } else {
+ /* The rest is similar to ":breakadd". */
+ ex_breakadd(eap);
+ }
+}
+
+/* Command line expansion for :profile. */
+static enum {
+ PEXP_SUBCMD, /* expand :profile sub-commands */
+ PEXP_FUNC /* expand :profile func {funcname} */
+} pexpand_what;
+
+static char *pexpand_cmds[] = {
+ "start",
+#define PROFCMD_START 0
+ "pause",
+#define PROFCMD_PAUSE 1
+ "continue",
+#define PROFCMD_CONTINUE 2
+ "func",
+#define PROFCMD_FUNC 3
+ "file",
+#define PROFCMD_FILE 4
+ NULL
+#define PROFCMD_LAST 5
+};
+
+/*
+ * Function given to ExpandGeneric() to obtain the profile command
+ * specific expansion.
+ */
+char_u * get_profile_name(xp, idx)
+expand_T *xp UNUSED;
+int idx;
+{
+ switch (pexpand_what) {
+ case PEXP_SUBCMD:
+ return (char_u *)pexpand_cmds[idx];
+ /* case PEXP_FUNC: TODO */
+ default:
+ return NULL;
+ }
+}
+
+/*
+ * Handle command line completion for :profile command.
+ */
+void set_context_in_profile_cmd(xp, arg)
+expand_T *xp;
+char_u *arg;
+{
+ char_u *end_subcmd;
+
+ /* Default: expand subcommands. */
+ xp->xp_context = EXPAND_PROFILE;
+ pexpand_what = PEXP_SUBCMD;
+ xp->xp_pattern = arg;
+
+ end_subcmd = skiptowhite(arg);
+ if (*end_subcmd == NUL)
+ return;
+
+ if (end_subcmd - arg == 5 && STRNCMP(arg, "start", 5) == 0) {
+ xp->xp_context = EXPAND_FILES;
+ xp->xp_pattern = skipwhite(end_subcmd);
+ return;
+ }
+
+ /* TODO: expand function names after "func" */
+ xp->xp_context = EXPAND_NOTHING;
+}
+
+/*
+ * Dump the profiling info.
+ */
+void profile_dump() {
+ FILE *fd;
+
+ if (profile_fname != NULL) {
+ fd = mch_fopen((char *)profile_fname, "w");
+ if (fd == NULL)
+ EMSG2(_(e_notopen), profile_fname);
+ else {
+ script_dump_profile(fd);
+ func_dump_profile(fd);
+ fclose(fd);
+ }
+ }
+}
+
+/*
+ * Start profiling script "fp".
+ */
+static void script_do_profile(si)
+scriptitem_T *si;
+{
+ si->sn_pr_count = 0;
+ profile_zero(&si->sn_pr_total);
+ profile_zero(&si->sn_pr_self);
+
+ ga_init2(&si->sn_prl_ga, sizeof(sn_prl_T), 100);
+ si->sn_prl_idx = -1;
+ si->sn_prof_on = TRUE;
+ si->sn_pr_nest = 0;
+}
+
+/*
+ * save time when starting to invoke another script or function.
+ */
+void script_prof_save(tm)
+proftime_T *tm; /* place to store wait time */
+{
+ scriptitem_T *si;
+
+ if (current_SID > 0 && current_SID <= script_items.ga_len) {
+ si = &SCRIPT_ITEM(current_SID);
+ if (si->sn_prof_on && si->sn_pr_nest++ == 0)
+ profile_start(&si->sn_pr_child);
+ }
+ profile_get_wait(tm);
+}
+
+/*
+ * Count time spent in children after invoking another script or function.
+ */
+void script_prof_restore(tm)
+proftime_T *tm;
+{
+ scriptitem_T *si;
+
+ if (current_SID > 0 && current_SID <= script_items.ga_len) {
+ si = &SCRIPT_ITEM(current_SID);
+ if (si->sn_prof_on && --si->sn_pr_nest == 0) {
+ profile_end(&si->sn_pr_child);
+ profile_sub_wait(tm, &si->sn_pr_child); /* don't count wait time */
+ profile_add(&si->sn_pr_children, &si->sn_pr_child);
+ profile_add(&si->sn_prl_children, &si->sn_pr_child);
+ }
+ }
+}
+
+static proftime_T inchar_time;
+
+/*
+ * Called when starting to wait for the user to type a character.
+ */
+void prof_inchar_enter() {
+ profile_start(&inchar_time);
+}
+
+/*
+ * Called when finished waiting for the user to type a character.
+ */
+void prof_inchar_exit() {
+ profile_end(&inchar_time);
+ profile_add(&prof_wait_time, &inchar_time);
+}
+
+/*
+ * Dump the profiling results for all scripts in file "fd".
+ */
+static void script_dump_profile(fd)
+FILE *fd;
+{
+ int id;
+ scriptitem_T *si;
+ int i;
+ FILE *sfd;
+ sn_prl_T *pp;
+
+ for (id = 1; id <= script_items.ga_len; ++id) {
+ si = &SCRIPT_ITEM(id);
+ if (si->sn_prof_on) {
+ fprintf(fd, "SCRIPT %s\n", si->sn_name);
+ if (si->sn_pr_count == 1)
+ fprintf(fd, "Sourced 1 time\n");
+ else
+ fprintf(fd, "Sourced %d times\n", si->sn_pr_count);
+ fprintf(fd, "Total time: %s\n", profile_msg(&si->sn_pr_total));
+ fprintf(fd, " Self time: %s\n", profile_msg(&si->sn_pr_self));
+ fprintf(fd, "\n");
+ fprintf(fd, "count total (s) self (s)\n");
+
+ sfd = mch_fopen((char *)si->sn_name, "r");
+ if (sfd == NULL)
+ fprintf(fd, "Cannot open file!\n");
+ else {
+ for (i = 0; i < si->sn_prl_ga.ga_len; ++i) {
+ if (vim_fgets(IObuff, IOSIZE, sfd))
+ break;
+ pp = &PRL_ITEM(si, i);
+ if (pp->snp_count > 0) {
+ fprintf(fd, "%5d ", pp->snp_count);
+ if (profile_equal(&pp->sn_prl_total, &pp->sn_prl_self))
+ fprintf(fd, " ");
+ else
+ fprintf(fd, "%s ", profile_msg(&pp->sn_prl_total));
+ fprintf(fd, "%s ", profile_msg(&pp->sn_prl_self));
+ } else
+ fprintf(fd, " ");
+ fprintf(fd, "%s", IObuff);
+ }
+ fclose(sfd);
+ }
+ fprintf(fd, "\n");
+ }
+ }
+}
+
+/*
+ * Return TRUE when a function defined in the current script should be
+ * profiled.
+ */
+int prof_def_func() {
+ if (current_SID > 0)
+ return SCRIPT_ITEM(current_SID).sn_pr_force;
+ return FALSE;
+}
+
+/*
+ * If 'autowrite' option set, try to write the file.
+ * Careful: autocommands may make "buf" invalid!
+ *
+ * return FAIL for failure, OK otherwise
+ */
+int autowrite(buf, forceit)
+buf_T *buf;
+int forceit;
+{
+ int r;
+
+ if (!(p_aw || p_awa) || !p_write
+ /* never autowrite a "nofile" or "nowrite" buffer */
+ || bt_dontwrite(buf)
+ || (!forceit && buf->b_p_ro) || buf->b_ffname == NULL)
+ return FAIL;
+ 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))
+ r = FAIL;
+ return r;
+}
+
+/*
+ * flush all buffers, except the ones that are readonly
+ */
+void autowrite_all() {
+ buf_T *buf;
+
+ if (!(p_aw || p_awa) || !p_write)
+ return;
+ for (buf = firstbuf; buf; buf = buf->b_next)
+ if (bufIsChanged(buf) && !buf->b_p_ro) {
+ (void)buf_write_all(buf, FALSE);
+ /* an autocommand may have deleted the buffer */
+ if (!buf_valid(buf))
+ buf = firstbuf;
+ }
+}
+
+/*
+ * Return TRUE if buffer was changed and cannot be abandoned.
+ * For flags use the CCGD_ values.
+ */
+int check_changed(buf, flags)
+buf_T *buf;
+int flags;
+{
+ int forceit = (flags & CCGD_FORCEIT);
+
+ if ( !forceit
+ && bufIsChanged(buf)
+ && ((flags & CCGD_MULTWIN) || buf->b_nwindows <= 1)
+ && (!(flags & CCGD_AW) || autowrite(buf, forceit) == FAIL)) {
+ if ((p_confirm || cmdmod.confirm) && p_write) {
+ buf_T *buf2;
+ int count = 0;
+
+ if (flags & CCGD_ALLBUF)
+ for (buf2 = firstbuf; buf2 != NULL; buf2 = buf2->b_next)
+ if (bufIsChanged(buf2)
+ && (buf2->b_ffname != NULL
+ ))
+ ++count;
+ if (!buf_valid(buf))
+ /* Autocommand deleted buffer, oops! It's not changed now. */
+ return FALSE;
+ dialog_changed(buf, count > 1);
+ if (!buf_valid(buf))
+ /* Autocommand deleted buffer, oops! It's not changed now. */
+ return FALSE;
+ return bufIsChanged(buf);
+ }
+ if (flags & CCGD_EXCMD)
+ EMSG(_(e_nowrtmsg));
+ else
+ EMSG(_(e_nowrtmsg_nobang));
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+
+/*
+ * Ask the user what to do when abandoning a changed buffer.
+ * Must check 'write' option first!
+ */
+void dialog_changed(buf, checkall)
+buf_T *buf;
+int checkall; /* may abandon all changed buffers */
+{
+ char_u buff[DIALOG_MSG_SIZE];
+ int ret;
+ buf_T *buf2;
+ exarg_T ea;
+
+ dialog_msg(buff, _("Save changes to \"%s\"?"),
+ (buf->b_fname != NULL) ?
+ buf->b_fname : (char_u *)_("Untitled"));
+ if (checkall)
+ ret = vim_dialog_yesnoallcancel(VIM_QUESTION, NULL, buff, 1);
+ else
+ ret = vim_dialog_yesnocancel(VIM_QUESTION, NULL, buff, 1);
+
+ /* Init ea pseudo-structure, this is needed for the check_overwrite()
+ * function. */
+ ea.append = ea.forceit = FALSE;
+
+ if (ret == VIM_YES) {
+ if (buf->b_fname != NULL && check_overwrite(&ea, buf,
+ buf->b_fname, buf->b_ffname, FALSE) == OK)
+ /* didn't hit Cancel */
+ (void)buf_write_all(buf, FALSE);
+ } else if (ret == VIM_NO) {
+ unchanged(buf, TRUE);
+ } else if (ret == VIM_ALL) {
+ /*
+ * Write all modified files that can be written.
+ * Skip readonly buffers, these need to be confirmed
+ * individually.
+ */
+ for (buf2 = firstbuf; buf2 != NULL; buf2 = buf2->b_next) {
+ if (bufIsChanged(buf2)
+ && (buf2->b_ffname != NULL
+ )
+ && !buf2->b_p_ro) {
+ if (buf2->b_fname != NULL && check_overwrite(&ea, buf2,
+ buf2->b_fname, buf2->b_ffname, FALSE) == OK)
+ /* didn't hit Cancel */
+ (void)buf_write_all(buf2, FALSE);
+ /* an autocommand may have deleted the buffer */
+ if (!buf_valid(buf2))
+ buf2 = firstbuf;
+ }
+ }
+ } else if (ret == VIM_DISCARDALL) {
+ /*
+ * mark all buffers as unchanged
+ */
+ for (buf2 = firstbuf; buf2 != NULL; buf2 = buf2->b_next)
+ unchanged(buf2, TRUE);
+ }
+}
+
+/*
+ * Return TRUE if the buffer "buf" can be abandoned, either by making it
+ * hidden, autowriting it or unloading it.
+ */
+int can_abandon(buf, forceit)
+buf_T *buf;
+int forceit;
+{
+ return P_HID(buf)
+ || !bufIsChanged(buf)
+ || buf->b_nwindows > 1
+ || autowrite(buf, forceit) == OK
+ || forceit;
+}
+
+static void add_bufnum __ARGS((int *bufnrs, int *bufnump, int nr));
+
+/*
+ * Add a buffer number to "bufnrs", unless it's already there.
+ */
+static void add_bufnum(bufnrs, bufnump, nr)
+int *bufnrs;
+int *bufnump;
+int nr;
+{
+ int i;
+
+ for (i = 0; i < *bufnump; ++i)
+ if (bufnrs[i] == nr)
+ return;
+ bufnrs[*bufnump] = nr;
+ *bufnump = *bufnump + 1;
+}
+
+/*
+ * Return TRUE if any buffer was changed and cannot be abandoned.
+ * That changed buffer becomes the current buffer.
+ */
+int check_changed_any(hidden)
+int hidden; /* Only check hidden buffers */
+{
+ int ret = FALSE;
+ buf_T *buf;
+ int save;
+ int i;
+ int bufnum = 0;
+ int bufcount = 0;
+ int *bufnrs;
+ tabpage_T *tp;
+ win_T *wp;
+
+ for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+ ++bufcount;
+
+ if (bufcount == 0)
+ return FALSE;
+
+ bufnrs = (int *)alloc(sizeof(int) * bufcount);
+ if (bufnrs == NULL)
+ return FALSE;
+
+ /* curbuf */
+ bufnrs[bufnum++] = curbuf->b_fnum;
+ /* buf in curtab */
+ FOR_ALL_WINDOWS(wp)
+ if (wp->w_buffer != curbuf)
+ add_bufnum(bufnrs, &bufnum, wp->w_buffer->b_fnum);
+
+ /* buf in other tab */
+ for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
+ if (tp != curtab)
+ for (wp = tp->tp_firstwin; wp != NULL; wp = wp->w_next)
+ add_bufnum(bufnrs, &bufnum, wp->w_buffer->b_fnum);
+ /* any other buf */
+ for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+ add_bufnum(bufnrs, &bufnum, buf->b_fnum);
+
+ for (i = 0; i < bufnum; ++i) {
+ buf = buflist_findnr(bufnrs[i]);
+ if (buf == NULL)
+ continue;
+ if ((!hidden || buf->b_nwindows == 0) && bufIsChanged(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))
+ break; /* didn't save - still changes */
+ }
+ }
+
+ if (i >= bufnum)
+ goto theend;
+
+ ret = TRUE;
+ exiting = FALSE;
+ /*
+ * When ":confirm" used, don't give an error message.
+ */
+ if (!(p_confirm || cmdmod.confirm)) {
+ /* There must be a wait_return for this message, do_buffer()
+ * may cause a redraw. But wait_return() is a no-op when vgetc()
+ * is busy (Quit used from window menu), then make sure we don't
+ * cause a scroll up. */
+ if (vgetc_busy > 0) {
+ msg_row = cmdline_row;
+ msg_col = 0;
+ msg_didout = FALSE;
+ }
+ if (EMSG2(_("E162: No write since last change for buffer \"%s\""),
+ buf_spname(buf) != NULL ? buf_spname(buf) : buf->b_fname)) {
+ save = no_wait_return;
+ no_wait_return = FALSE;
+ wait_return(FALSE);
+ no_wait_return = save;
+ }
+ }
+
+ /* Try to find a window that contains the buffer. */
+ if (buf != curbuf)
+ FOR_ALL_TAB_WINDOWS(tp, wp)
+ if (wp->w_buffer == buf) {
+ goto_tabpage_win(tp, wp);
+ /* Paranoia: did autocms wipe out the buffer with changes? */
+ if (!buf_valid(buf)) {
+ goto theend;
+ }
+ goto buf_found;
+ }
+buf_found:
+
+ /* Open the changed buffer in the current window. */
+ if (buf != curbuf)
+ set_curbuf(buf, DOBUF_GOTO);
+
+theend:
+ vim_free(bufnrs);
+ return ret;
+}
+
+/*
+ * return FAIL if there is no file name, OK if there is one
+ * give error message for FAIL
+ */
+int check_fname() {
+ if (curbuf->b_ffname == NULL) {
+ EMSG(_(e_noname));
+ return FAIL;
+ }
+ return OK;
+}
+
+/*
+ * flush the contents of a buffer, unless it has no file name
+ *
+ * return FAIL for failure, OK otherwise
+ */
+int buf_write_all(buf, forceit)
+buf_T *buf;
+int forceit;
+{
+ int retval;
+ buf_T *old_curbuf = curbuf;
+
+ retval = (buf_write(buf, buf->b_ffname, buf->b_fname,
+ (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(_("Warning: Entered other buffer unexpectedly (check autocommands)"));
+ }
+ return retval;
+}
+
+/*
+ * Code to handle the argument list.
+ */
+
+static char_u *do_one_arg __ARGS((char_u *str));
+static int do_arglist __ARGS((char_u *str, int what, int after));
+static void alist_check_arg_idx __ARGS((void));
+static int editing_arg_idx __ARGS((win_T *win));
+static int alist_add_list __ARGS((int count, char_u **files, int after));
+#define AL_SET 1
+#define AL_ADD 2
+#define AL_DEL 3
+
+/*
+ * Isolate one argument, taking backticks.
+ * Changes the argument in-place, puts a NUL after it. Backticks remain.
+ * Return a pointer to the start of the next argument.
+ */
+static char_u * do_one_arg(str)
+char_u *str;
+{
+ char_u *p;
+ int inbacktick;
+
+ inbacktick = FALSE;
+ for (p = str; *str; ++str) {
+ /* When the backslash is used for escaping the special meaning of a
+ * character we need to keep it until wildcard expansion. */
+ if (rem_backslash(str)) {
+ *p++ = *str++;
+ *p++ = *str;
+ } else {
+ /* An item ends at a space not in backticks */
+ if (!inbacktick && vim_isspace(*str))
+ break;
+ if (*str == '`')
+ inbacktick ^= TRUE;
+ *p++ = *str;
+ }
+ }
+ str = skipwhite(str);
+ *p = NUL;
+
+ return str;
+}
+
+/*
+ * Separate the arguments in "str" and return a list of pointers in the
+ * growarray "gap".
+ */
+int get_arglist(gap, str)
+garray_T *gap;
+char_u *str;
+{
+ ga_init2(gap, (int)sizeof(char_u *), 20);
+ while (*str != NUL) {
+ if (ga_grow(gap, 1) == FAIL) {
+ ga_clear(gap);
+ return FAIL;
+ }
+ ((char_u **)gap->ga_data)[gap->ga_len++] = str;
+
+ /* Isolate one argument, change it in-place, put a NUL after it. */
+ str = do_one_arg(str);
+ }
+ return OK;
+}
+
+/*
+ * Parse a list of arguments (file names), expand them and return in
+ * "fnames[fcountp]". When "wig" is TRUE, removes files matching 'wildignore'.
+ * Return FAIL or OK.
+ */
+int get_arglist_exp(str, fcountp, fnamesp, wig)
+char_u *str;
+int *fcountp;
+char_u ***fnamesp;
+int wig;
+{
+ garray_T ga;
+ int i;
+
+ if (get_arglist(&ga, str) == FAIL)
+ return FAIL;
+ if (wig == TRUE)
+ i = expand_wildcards(ga.ga_len, (char_u **)ga.ga_data,
+ fcountp, fnamesp, EW_FILE|EW_NOTFOUND);
+ else
+ i = gen_expand_wildcards(ga.ga_len, (char_u **)ga.ga_data,
+ fcountp, fnamesp, EW_FILE|EW_NOTFOUND);
+
+ ga_clear(&ga);
+ return i;
+}
+
+
+/*
+ * "what" == AL_SET: Redefine the argument list to 'str'.
+ * "what" == AL_ADD: add files in 'str' to the argument list after "after".
+ * "what" == AL_DEL: remove files in 'str' from the argument list.
+ *
+ * Return FAIL for failure, OK otherwise.
+ */
+static int do_arglist(str, what, after)
+char_u *str;
+int what UNUSED;
+int after UNUSED; /* 0 means before first one */
+{
+ garray_T new_ga;
+ int exp_count;
+ char_u **exp_files;
+ int i;
+ char_u *p;
+ int match;
+
+ /*
+ * Collect all file name arguments in "new_ga".
+ */
+ if (get_arglist(&new_ga, str) == FAIL)
+ return FAIL;
+
+ if (what == AL_DEL) {
+ regmatch_T regmatch;
+ int didone;
+
+ /*
+ * Delete the items: use each item as a regexp and find a match in the
+ * argument list.
+ */
+ regmatch.rm_ic = p_fic; /* ignore case when 'fileignorecase' is set */
+ for (i = 0; i < new_ga.ga_len && !got_int; ++i) {
+ p = ((char_u **)new_ga.ga_data)[i];
+ p = file_pat_to_reg_pat(p, NULL, NULL, FALSE);
+ if (p == NULL)
+ break;
+ regmatch.regprog = vim_regcomp(p, p_magic ? RE_MAGIC : 0);
+ if (regmatch.regprog == NULL) {
+ vim_free(p);
+ break;
+ }
+
+ didone = FALSE;
+ for (match = 0; match < ARGCOUNT; ++match)
+ if (vim_regexec(&regmatch, alist_name(&ARGLIST[match]),
+ (colnr_T)0)) {
+ didone = TRUE;
+ vim_free(ARGLIST[match].ae_fname);
+ mch_memmove(ARGLIST + match, ARGLIST + match + 1,
+ (ARGCOUNT - match - 1) * sizeof(aentry_T));
+ --ALIST(curwin)->al_ga.ga_len;
+ if (curwin->w_arg_idx > match)
+ --curwin->w_arg_idx;
+ --match;
+ }
+
+ vim_regfree(regmatch.regprog);
+ vim_free(p);
+ if (!didone)
+ EMSG2(_(e_nomatch2), ((char_u **)new_ga.ga_data)[i]);
+ }
+ ga_clear(&new_ga);
+ } else {
+ i = expand_wildcards(new_ga.ga_len, (char_u **)new_ga.ga_data,
+ &exp_count, &exp_files, EW_DIR|EW_FILE|EW_ADDSLASH|EW_NOTFOUND);
+ ga_clear(&new_ga);
+ if (i == FAIL)
+ return FAIL;
+ if (exp_count == 0) {
+ EMSG(_(e_nomatch));
+ return FAIL;
+ }
+
+ if (what == AL_ADD) {
+ (void)alist_add_list(exp_count, exp_files, after);
+ vim_free(exp_files);
+ } else /* what == AL_SET */
+ alist_set(ALIST(curwin), exp_count, exp_files, FALSE, NULL, 0);
+ }
+
+ alist_check_arg_idx();
+
+ return OK;
+}
+
+/*
+ * Check the validity of the arg_idx for each other window.
+ */
+static void alist_check_arg_idx() {
+ win_T *win;
+ tabpage_T *tp;
+
+ FOR_ALL_TAB_WINDOWS(tp, win)
+ if (win->w_alist == curwin->w_alist)
+ check_arg_idx(win);
+}
+
+/*
+ * Return TRUE if window "win" is editing the file at the current argument
+ * index.
+ */
+static int editing_arg_idx(win)
+win_T *win;
+{
+ return !(win->w_arg_idx >= WARGCOUNT(win)
+ || (win->w_buffer->b_fnum
+ != WARGLIST(win)[win->w_arg_idx].ae_fnum
+ && (win->w_buffer->b_ffname == NULL
+ || !(fullpathcmp(
+ alist_name(&WARGLIST(win)[win->w_arg_idx]),
+ win->w_buffer->b_ffname, TRUE) & FPC_SAME))));
+}
+
+/*
+ * Check if window "win" is editing the w_arg_idx file in its argument list.
+ */
+void check_arg_idx(win)
+win_T *win;
+{
+ if (WARGCOUNT(win) > 1 && !editing_arg_idx(win)) {
+ /* We are not editing the current entry in the argument list.
+ * Set "arg_had_last" if we are editing the last one. */
+ win->w_arg_idx_invalid = TRUE;
+ if (win->w_arg_idx != WARGCOUNT(win) - 1
+ && arg_had_last == FALSE
+ && ALIST(win) == &global_alist
+ && GARGCOUNT > 0
+ && win->w_arg_idx < GARGCOUNT
+ && (win->w_buffer->b_fnum == GARGLIST[GARGCOUNT - 1].ae_fnum
+ || (win->w_buffer->b_ffname != NULL
+ && (fullpathcmp(alist_name(&GARGLIST[GARGCOUNT - 1]),
+ win->w_buffer->b_ffname, TRUE) & FPC_SAME))))
+ arg_had_last = TRUE;
+ } else {
+ /* We are editing the current entry in the argument list.
+ * Set "arg_had_last" if it's also the last one */
+ win->w_arg_idx_invalid = FALSE;
+ if (win->w_arg_idx == WARGCOUNT(win) - 1
+ && win->w_alist == &global_alist
+ )
+ arg_had_last = TRUE;
+ }
+}
+
+/*
+ * ":args", ":argslocal" and ":argsglobal".
+ */
+void ex_args(eap)
+exarg_T *eap;
+{
+ int i;
+
+ if (eap->cmdidx != CMD_args) {
+ alist_unlink(ALIST(curwin));
+ if (eap->cmdidx == CMD_argglobal)
+ ALIST(curwin) = &global_alist;
+ else /* eap->cmdidx == CMD_arglocal */
+ alist_new();
+ }
+
+ if (!ends_excmd(*eap->arg)) {
+ /*
+ * ":args file ..": define new argument list, handle like ":next"
+ * Also for ":argslocal file .." and ":argsglobal file ..".
+ */
+ ex_next(eap);
+ } else if (eap->cmdidx == CMD_args) {
+ /*
+ * ":args": list arguments.
+ */
+ if (ARGCOUNT > 0) {
+ /* Overwrite the command, for a short list there is no scrolling
+ * required and no wait_return(). */
+ gotocmdline(TRUE);
+ for (i = 0; i < ARGCOUNT; ++i) {
+ if (i == curwin->w_arg_idx)
+ msg_putchar('[');
+ msg_outtrans(alist_name(&ARGLIST[i]));
+ if (i == curwin->w_arg_idx)
+ msg_putchar(']');
+ msg_putchar(' ');
+ }
+ }
+ } else if (eap->cmdidx == CMD_arglocal) {
+ garray_T *gap = &curwin->w_alist->al_ga;
+
+ /*
+ * ":argslocal": make a local copy of the global argument list.
+ */
+ if (ga_grow(gap, GARGCOUNT) == OK)
+ for (i = 0; i < GARGCOUNT; ++i)
+ if (GARGLIST[i].ae_fname != NULL) {
+ AARGLIST(curwin->w_alist)[gap->ga_len].ae_fname =
+ vim_strsave(GARGLIST[i].ae_fname);
+ AARGLIST(curwin->w_alist)[gap->ga_len].ae_fnum =
+ GARGLIST[i].ae_fnum;
+ ++gap->ga_len;
+ }
+ }
+}
+
+/*
+ * ":previous", ":sprevious", ":Next" and ":sNext".
+ */
+void ex_previous(eap)
+exarg_T *eap;
+{
+ /* If past the last one already, go to the last one. */
+ if (curwin->w_arg_idx - (int)eap->line2 >= ARGCOUNT)
+ do_argfile(eap, ARGCOUNT - 1);
+ else
+ do_argfile(eap, curwin->w_arg_idx - (int)eap->line2);
+}
+
+/*
+ * ":rewind", ":first", ":sfirst" and ":srewind".
+ */
+void ex_rewind(eap)
+exarg_T *eap;
+{
+ do_argfile(eap, 0);
+}
+
+/*
+ * ":last" and ":slast".
+ */
+void ex_last(eap)
+exarg_T *eap;
+{
+ do_argfile(eap, ARGCOUNT - 1);
+}
+
+/*
+ * ":argument" and ":sargument".
+ */
+void ex_argument(eap)
+exarg_T *eap;
+{
+ int i;
+
+ if (eap->addr_count > 0)
+ i = eap->line2 - 1;
+ else
+ i = curwin->w_arg_idx;
+ do_argfile(eap, i);
+}
+
+/*
+ * Edit file "argn" of the argument lists.
+ */
+void do_argfile(eap, argn)
+exarg_T *eap;
+int argn;
+{
+ int other;
+ char_u *p;
+ int old_arg_idx = curwin->w_arg_idx;
+
+ if (argn < 0 || argn >= ARGCOUNT) {
+ if (ARGCOUNT <= 1)
+ EMSG(_("E163: There is only one file to edit"));
+ else if (argn < 0)
+ EMSG(_("E164: Cannot go before first file"));
+ else
+ EMSG(_("E165: Cannot go beyond last file"));
+ } else {
+ setpcmark();
+
+ /* split window or create new tab page first */
+ if (*eap->cmd == 's' || cmdmod.tab != 0) {
+ if (win_split(0, 0) == FAIL)
+ return;
+ RESET_BINDING(curwin);
+ } else {
+ /*
+ * if 'hidden' set, only check for changed file when re-editing
+ * the same buffer
+ */
+ other = TRUE;
+ if (P_HID(curbuf)) {
+ p = fix_fname(alist_name(&ARGLIST[argn]));
+ other = otherfile(p);
+ vim_free(p);
+ }
+ if ((!P_HID(curbuf) || !other)
+ && check_changed(curbuf, CCGD_AW
+ | (other ? 0 : CCGD_MULTWIN)
+ | (eap->forceit ? CCGD_FORCEIT : 0)
+ | CCGD_EXCMD))
+ return;
+ }
+
+ curwin->w_arg_idx = argn;
+ if (argn == ARGCOUNT - 1
+ && curwin->w_alist == &global_alist
+ )
+ arg_had_last = TRUE;
+
+ /* Edit the file; always use the last known line number.
+ * When it fails (e.g. Abort for already edited file) restore the
+ * 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)
+ + (eap->forceit ? ECMD_FORCEIT : 0), curwin) == FAIL)
+ curwin->w_arg_idx = old_arg_idx;
+ /* like Vi: set the mark where the cursor is in the file. */
+ else if (eap->cmdidx != CMD_argdo)
+ setmark('\'');
+ }
+}
+
+/*
+ * ":next", and commands that behave like it.
+ */
+void ex_next(eap)
+exarg_T *eap;
+{
+ int i;
+
+ /*
+ * check for changed buffer now, if this fails the argument list is not
+ * redefined.
+ */
+ if ( P_HID(curbuf)
+ || eap->cmdidx == CMD_snext
+ || !check_changed(curbuf, CCGD_AW
+ | (eap->forceit ? CCGD_FORCEIT : 0)
+ | CCGD_EXCMD)) {
+ if (*eap->arg != NUL) { /* redefine file list */
+ if (do_arglist(eap->arg, AL_SET, 0) == FAIL)
+ return;
+ i = 0;
+ } else
+ i = curwin->w_arg_idx + (int)eap->line2;
+ do_argfile(eap, i);
+ }
+}
+
+/*
+ * ":argedit"
+ */
+void ex_argedit(eap)
+exarg_T *eap;
+{
+ int fnum;
+ int i;
+ char_u *s;
+
+ /* 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);
+ if (s == NULL)
+ return;
+ i = alist_add_list(1, &s,
+ eap->addr_count > 0 ? (int)eap->line2 : curwin->w_arg_idx + 1);
+ if (i < 0)
+ return;
+ curwin->w_arg_idx = i;
+ }
+
+ alist_check_arg_idx();
+
+ /* Edit the argument. */
+ do_argfile(eap, i);
+}
+
+/*
+ * ":argadd"
+ */
+void ex_argadd(eap)
+exarg_T *eap;
+{
+ do_arglist(eap->arg, AL_ADD,
+ eap->addr_count > 0 ? (int)eap->line2 : curwin->w_arg_idx + 1);
+ maketitle();
+}
+
+/*
+ * ":argdelete"
+ */
+void ex_argdelete(eap)
+exarg_T *eap;
+{
+ int i;
+ int n;
+
+ if (eap->addr_count > 0) {
+ /* ":1,4argdel": Delete all arguments in the range. */
+ if (eap->line2 > ARGCOUNT)
+ eap->line2 = ARGCOUNT;
+ n = eap->line2 - eap->line1 + 1;
+ if (*eap->arg != NUL || n <= 0)
+ EMSG(_(e_invarg));
+ else {
+ for (i = eap->line1; i <= eap->line2; ++i)
+ vim_free(ARGLIST[i - 1].ae_fname);
+ mch_memmove(ARGLIST + eap->line1 - 1, ARGLIST + eap->line2,
+ (size_t)((ARGCOUNT - eap->line2) * sizeof(aentry_T)));
+ ALIST(curwin)->al_ga.ga_len -= n;
+ if (curwin->w_arg_idx >= eap->line2)
+ curwin->w_arg_idx -= n;
+ else if (curwin->w_arg_idx > eap->line1)
+ curwin->w_arg_idx = eap->line1;
+ }
+ } else if (*eap->arg == NUL)
+ EMSG(_(e_argreq));
+ else
+ do_arglist(eap->arg, AL_DEL, 0);
+ maketitle();
+}
+
+/*
+ * ":argdo", ":windo", ":bufdo", ":tabdo"
+ */
+void ex_listdo(eap)
+exarg_T *eap;
+{
+ int i;
+ win_T *wp;
+ tabpage_T *tp;
+ buf_T *buf;
+ int next_fnum = 0;
+ char_u *save_ei = NULL;
+ char_u *p_shm_save;
+
+
+ if (eap->cmdidx != CMD_windo && eap->cmdidx != CMD_tabdo)
+ /* Don't do syntax HL autocommands. Skipping the syntax file is a
+ * great speed improvement. */
+ save_ei = au_event_disable(",Syntax");
+
+ if (eap->cmdidx == CMD_windo
+ || eap->cmdidx == CMD_tabdo
+ || P_HID(curbuf)
+ || !check_changed(curbuf, CCGD_AW
+ | (eap->forceit ? CCGD_FORCEIT : 0)
+ | CCGD_EXCMD)) {
+ /* start at the first argument/window/buffer */
+ i = 0;
+ wp = firstwin;
+ tp = first_tabpage;
+ /* set pcmark now */
+ if (eap->cmdidx == CMD_bufdo)
+ goto_buffer(eap, DOBUF_FIRST, FORWARD, 0);
+ else
+ setpcmark();
+ listcmd_busy = TRUE; /* avoids setting pcmark below */
+
+ while (!got_int) {
+ if (eap->cmdidx == CMD_argdo) {
+ /* go to argument "i" */
+ if (i == ARGCOUNT)
+ break;
+ /* Don't call do_argfile() when already there, it will try
+ * reloading the file. */
+ if (curwin->w_arg_idx != i || !editing_arg_idx(curwin)) {
+ /* 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);
+ do_argfile(eap, i);
+ set_option_value((char_u *)"shm", 0L, p_shm_save, 0);
+ vim_free(p_shm_save);
+ }
+ if (curwin->w_arg_idx != i)
+ break;
+ ++i;
+ } else if (eap->cmdidx == CMD_windo) {
+ /* go to window "wp" */
+ if (!win_valid(wp))
+ break;
+ win_goto(wp);
+ if (curwin != wp)
+ break; /* something must be wrong */
+ wp = curwin->w_next;
+ } else if (eap->cmdidx == CMD_tabdo) {
+ /* go to window "tp" */
+ if (!valid_tabpage(tp))
+ break;
+ goto_tabpage_tp(tp, TRUE, TRUE);
+ tp = tp->tp_next;
+ } else if (eap->cmdidx == CMD_bufdo) {
+ /* Remember the number of the next listed buffer, in case
+ * ":bwipe" is used or autocommands do something strange. */
+ next_fnum = -1;
+ for (buf = curbuf->b_next; buf != NULL; buf = buf->b_next)
+ if (buf->b_p_bl) {
+ next_fnum = buf->b_fnum;
+ break;
+ }
+ }
+
+ /* execute the command */
+ do_cmdline(eap->arg, eap->getline, eap->cookie,
+ DOCMD_VERBOSE + DOCMD_NOWAIT);
+
+ if (eap->cmdidx == CMD_bufdo) {
+ /* Done? */
+ if (next_fnum < 0)
+ break;
+ /* Check if the buffer still exists. */
+ for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+ if (buf->b_fnum == next_fnum)
+ break;
+ if (buf == NULL)
+ break;
+
+ /* 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);
+ goto_buffer(eap, DOBUF_FIRST, FORWARD, next_fnum);
+ set_option_value((char_u *)"shm", 0L, p_shm_save, 0);
+ vim_free(p_shm_save);
+
+ /* If autocommands took us elsewhere, quit here */
+ if (curbuf->b_fnum != next_fnum)
+ break;
+ }
+
+ if (eap->cmdidx == CMD_windo) {
+ validate_cursor(); /* cursor may have moved */
+ /* required when 'scrollbind' has been set */
+ if (curwin->w_p_scb)
+ do_check_scrollbind(TRUE);
+ }
+ }
+ listcmd_busy = FALSE;
+ }
+
+ if (save_ei != NULL) {
+ au_event_restore(save_ei);
+ apply_autocmds(EVENT_SYNTAX, curbuf->b_p_syn,
+ curbuf->b_fname, TRUE, curbuf);
+ }
+}
+
+/*
+ * Add files[count] to the arglist of the current window after arg "after".
+ * The file names in files[count] must have been allocated and are taken over.
+ * Files[] itself is not taken over.
+ * Returns index of first added argument. Returns -1 when failed (out of mem).
+ */
+static int alist_add_list(count, files, after)
+int count;
+char_u **files;
+int after; /* where to add: 0 = before first one */
+{
+ int i;
+
+ if (ga_grow(&ALIST(curwin)->al_ga, count) == OK) {
+ if (after < 0)
+ after = 0;
+ if (after > ARGCOUNT)
+ after = ARGCOUNT;
+ if (after < ARGCOUNT)
+ mch_memmove(&(ARGLIST[after + count]), &(ARGLIST[after]),
+ (ARGCOUNT - after) * sizeof(aentry_T));
+ for (i = 0; i < count; ++i) {
+ ARGLIST[after + i].ae_fname = files[i];
+ ARGLIST[after + i].ae_fnum = buflist_add(files[i], BLN_LISTED);
+ }
+ ALIST(curwin)->al_ga.ga_len += count;
+ if (curwin->w_arg_idx >= after)
+ ++curwin->w_arg_idx;
+ return after;
+ }
+
+ for (i = 0; i < count; ++i)
+ vim_free(files[i]);
+ return -1;
+}
+
+
+/*
+ * ":compiler[!] {name}"
+ */
+void ex_compiler(eap)
+exarg_T *eap;
+{
+ char_u *buf;
+ char_u *old_cur_comp = NULL;
+ char_u *p;
+
+ if (*eap->arg == NUL) {
+ /* List all compiler scripts. */
+ do_cmdline_cmd((char_u *)"echo globpath(&rtp, 'compiler/*.vim')");
+ /* ) keep the indenter happy... */
+ } else {
+ buf = alloc((unsigned)(STRLEN(eap->arg) + 14));
+ if (buf != NULL) {
+ if (eap->forceit) {
+ /* ":compiler! {name}" sets global options */
+ do_cmdline_cmd((char_u *)
+ "command -nargs=* CompilerSet set <args>");
+ } else {
+ /* ":compiler! {name}" sets local options.
+ * To remain backwards compatible "current_compiler" is always
+ * used. A user's compiler plugin may set it, the distributed
+ * 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");
+ if (old_cur_comp != NULL)
+ old_cur_comp = vim_strsave(old_cur_comp);
+ do_cmdline_cmd((char_u *)
+ "command -nargs=* CompilerSet setlocal <args>");
+ }
+ do_unlet((char_u *)"g:current_compiler", TRUE);
+ do_unlet((char_u *)"b:current_compiler", TRUE);
+
+ sprintf((char *)buf, "compiler/%s.vim", eap->arg);
+ if (source_runtime(buf, TRUE) == FAIL)
+ EMSG2(_("E666: compiler not supported: %s"), eap->arg);
+ vim_free(buf);
+
+ do_cmdline_cmd((char_u *)":delcommand CompilerSet");
+
+ /* Set "b:current_compiler" from "current_compiler". */
+ p = get_var_value((char_u *)"g:current_compiler");
+ if (p != NULL)
+ set_internal_string_var((char_u *)"b:current_compiler", p);
+
+ /* Restore "current_compiler" for ":compiler {name}". */
+ if (!eap->forceit) {
+ if (old_cur_comp != NULL) {
+ set_internal_string_var((char_u *)"g:current_compiler",
+ old_cur_comp);
+ vim_free(old_cur_comp);
+ } else
+ do_unlet((char_u *)"g:current_compiler", TRUE);
+ }
+ }
+ }
+}
+
+/*
+ * ":runtime {name}"
+ */
+void ex_runtime(eap)
+exarg_T *eap;
+{
+ source_runtime(eap->arg, eap->forceit);
+}
+
+static void source_callback __ARGS((char_u *fname, void *cookie));
+
+static void source_callback(fname, cookie)
+char_u *fname;
+void *cookie UNUSED;
+{
+ (void)do_source(fname, FALSE, DOSO_NONE);
+}
+
+/*
+ * Source the file "name" from all directories in 'runtimepath'.
+ * "name" can contain wildcards.
+ * When "all" is TRUE, source all files, otherwise only the first one.
+ * return FAIL when no file could be sourced, OK otherwise.
+ */
+int source_runtime(name, all)
+char_u *name;
+int all;
+{
+ return do_in_runtimepath(name, all, source_callback, NULL);
+}
+
+/*
+ * Find "name" in 'runtimepath'. When found, invoke the callback function for
+ * it: callback(fname, "cookie")
+ * When "all" is TRUE 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
+ * passed by reference in this case, setting it to NULL indicates that callback
+ * has done its job.
+ */
+int do_in_runtimepath(name, all, callback, cookie)
+char_u *name;
+int all;
+void (*callback)__ARGS((char_u *fname, void *ck));
+void *cookie;
+{
+ char_u *rtp;
+ char_u *np;
+ char_u *buf;
+ char_u *rtp_copy;
+ char_u *tail;
+ int num_files;
+ char_u **files;
+ int i;
+ int did_one = FALSE;
+
+ /* Make a copy of 'runtimepath'. Invoking the callback may change the
+ * value. */
+ rtp_copy = vim_strsave(p_rtp);
+ buf = alloc(MAXPATHL);
+ if (buf != NULL && rtp_copy != NULL) {
+ if (p_verbose > 1 && name != NULL) {
+ verbose_enter();
+ smsg((char_u *)_("Searching for \"%s\" in \"%s\""),
+ (char *)name, (char *)p_rtp);
+ verbose_leave();
+ }
+
+ /* Loop over all entries in 'runtimepath'. */
+ rtp = rtp_copy;
+ while (*rtp != NUL && (all || !did_one)) {
+ /* Copy the path from 'runtimepath' to buf[]. */
+ copy_option_part(&rtp, buf, MAXPATHL, ",");
+ if (name == NULL) {
+ (*callback)(buf, (void *) &cookie);
+ if (!did_one)
+ did_one = (cookie == NULL);
+ } else if (STRLEN(buf) + STRLEN(name) + 2 < MAXPATHL) {
+ add_pathsep(buf);
+ tail = buf + STRLEN(buf);
+
+ /* Loop over all patterns in "name" */
+ np = name;
+ while (*np != NUL && (all || !did_one)) {
+ /* Append the pattern from "name" to buf[]. */
+ copy_option_part(&np, tail, (int)(MAXPATHL - (tail - buf)),
+ "\t ");
+
+ if (p_verbose > 2) {
+ verbose_enter();
+ smsg((char_u *)_("Searching for \"%s\""), buf);
+ verbose_leave();
+ }
+
+ /* Expand wildcards, invoke the callback for each match. */
+ if (gen_expand_wildcards(1, &buf, &num_files, &files,
+ EW_FILE) == OK) {
+ for (i = 0; i < num_files; ++i) {
+ (*callback)(files[i], cookie);
+ did_one = TRUE;
+ if (!all)
+ break;
+ }
+ FreeWild(num_files, files);
+ }
+ }
+ }
+ }
+ }
+ vim_free(buf);
+ vim_free(rtp_copy);
+ if (p_verbose > 0 && !did_one && name != NULL) {
+ verbose_enter();
+ smsg((char_u *)_("not found in 'runtimepath': \"%s\""), name);
+ verbose_leave();
+ }
+
+
+ return did_one ? OK : FAIL;
+}
+
+/*
+ * ":options"
+ */
+void ex_options(eap)
+exarg_T *eap UNUSED;
+{
+ cmd_source((char_u *)SYS_OPTWIN_FILE, NULL);
+}
+
+/*
+ * ":source {fname}"
+ */
+void ex_source(eap)
+exarg_T *eap;
+{
+ cmd_source(eap->arg, eap);
+}
+
+static void cmd_source(fname, eap)
+char_u *fname;
+exarg_T *eap;
+{
+ if (*fname == NUL)
+ EMSG(_(e_argreq));
+
+ else if (eap != NULL && eap->forceit)
+ /* ":source!": read Normal mode commands
+ * Need to execute the commands directly. This is required at least
+ * for:
+ * - ":g" command busy
+ * - after ":argdo", ":windo" or ":bufdo"
+ * - another command follows
+ * - inside a loop
+ */
+ openscript(fname, global_busy || listcmd_busy || eap->nextcmd != NULL
+ || eap->cstack->cs_idx >= 0
+ );
+
+ /* ":source" read ex commands */
+ else if (do_source(fname, FALSE, DOSO_NONE) == FAIL)
+ EMSG2(_(e_notopen), fname);
+}
+
+/*
+ * ":source" and associated commands.
+ */
+/*
+ * Structure used to store info for each sourced file.
+ * It is shared between do_source() and getsourceline().
+ * This is required, because it needs to be handed to do_cmdline() and
+ * sourcing can be done recursively.
+ */
+struct source_cookie {
+ FILE *fp; /* opened file for sourcing */
+ char_u *nextline; /* if not NULL: line that was read ahead */
+ int finished; /* ":finish" used */
+#if defined(USE_CRNL) || defined(USE_CR)
+ int fileformat; /* EOL_UNKNOWN, EOL_UNIX or EOL_DOS */
+ int error; /* TRUE if LF found after CR-LF */
+#endif
+ linenr_T breakpoint; /* next line with breakpoint or zero */
+ char_u *fname; /* name of sourced file */
+ int dbg_tick; /* debug_tick when breakpoint was set */
+ int level; /* top nesting level of sourced file */
+ vimconv_T conv; /* type of conversion */
+};
+
+/*
+ * Return the address holding the next breakpoint line for a source cookie.
+ */
+linenr_T * source_breakpoint(cookie)
+void *cookie;
+{
+ return &((struct source_cookie *)cookie)->breakpoint;
+}
+
+/*
+ * Return the address holding the debug tick for a source cookie.
+ */
+int * source_dbg_tick(cookie)
+void *cookie;
+{
+ return &((struct source_cookie *)cookie)->dbg_tick;
+}
+
+/*
+ * Return the nesting level for a source cookie.
+ */
+int source_level(cookie)
+void *cookie;
+{
+ return ((struct source_cookie *)cookie)->level;
+}
+
+static char_u *get_one_sourceline __ARGS((struct source_cookie *sp));
+
+#if (defined(WIN32) && defined(FEAT_CSCOPE)) || defined(HAVE_FD_CLOEXEC)
+# define USE_FOPEN_NOINH
+static FILE *fopen_noinh_readbin __ARGS((char *filename));
+
+/*
+ * Special function to open a file without handle inheritance.
+ * When possible the handle is closed on exec().
+ */
+static FILE * fopen_noinh_readbin(filename)
+char *filename;
+{
+ int fd_tmp = mch_open(filename, O_RDONLY, 0);
+
+ if (fd_tmp == -1)
+ return NULL;
+
+# ifdef HAVE_FD_CLOEXEC
+ {
+ int fdflags = fcntl(fd_tmp, F_GETFD);
+ if (fdflags >= 0 && (fdflags & FD_CLOEXEC) == 0)
+ fcntl(fd_tmp, F_SETFD, fdflags | FD_CLOEXEC);
+ }
+# endif
+
+ return fdopen(fd_tmp, READBIN);
+}
+#endif
+
+
+/*
+ * do_source: Read the file "fname" and execute its lines as EX commands.
+ *
+ * This function may be called recursively!
+ *
+ * return FAIL if file could not be opened, OK otherwise
+ */
+int do_source(fname, check_other, is_vimrc)
+char_u *fname;
+int check_other; /* check for .vimrc and _vimrc */
+int is_vimrc; /* DOSO_ value */
+{
+ struct source_cookie cookie;
+ char_u *save_sourcing_name;
+ linenr_T save_sourcing_lnum;
+ char_u *p;
+ char_u *fname_exp;
+ char_u *firstline = NULL;
+ int retval = FAIL;
+ scid_T save_current_SID;
+ static scid_T last_current_SID = 0;
+ void *save_funccalp;
+ int save_debug_break_level = debug_break_level;
+ scriptitem_T *si = NULL;
+# ifdef UNIX
+ struct stat st;
+ int stat_ok;
+# endif
+#ifdef STARTUPTIME
+ struct timeval tv_rel;
+ struct timeval tv_start;
+#endif
+ proftime_T wait_start;
+
+ p = expand_env_save(fname);
+ if (p == NULL)
+ return retval;
+ fname_exp = fix_fname(p);
+ vim_free(p);
+ if (fname_exp == NULL)
+ return retval;
+ if (mch_isdir(fname_exp)) {
+ smsg((char_u *)_("Cannot source a directory: \"%s\""), fname);
+ goto theend;
+ }
+
+ /* Apply SourceCmd autocommands, they should get the file and source it. */
+ if (has_autocmd(EVENT_SOURCECMD, fname_exp, NULL)
+ && apply_autocmds(EVENT_SOURCECMD, fname_exp, fname_exp,
+ FALSE, curbuf)) {
+ retval = aborting() ? FAIL : OK;
+ goto theend;
+ }
+
+ /* Apply SourcePre autocommands, they may get the file. */
+ apply_autocmds(EVENT_SOURCEPRE, fname_exp, fname_exp, FALSE, curbuf);
+
+#ifdef USE_FOPEN_NOINH
+ cookie.fp = fopen_noinh_readbin((char *)fname_exp);
+#else
+ cookie.fp = mch_fopen((char *)fname_exp, READBIN);
+#endif
+ if (cookie.fp == NULL && check_other) {
+ /*
+ * Try again, replacing file name ".vimrc" by "_vimrc" or vice versa,
+ * and ".exrc" by "_exrc" or vice versa.
+ */
+ p = gettail(fname_exp);
+ if ((*p == '.' || *p == '_')
+ && (STRICMP(p + 1, "vimrc") == 0
+ || STRICMP(p + 1, "gvimrc") == 0
+ || STRICMP(p + 1, "exrc") == 0)) {
+ if (*p == '_')
+ *p = '.';
+ else
+ *p = '_';
+#ifdef USE_FOPEN_NOINH
+ cookie.fp = fopen_noinh_readbin((char *)fname_exp);
+#else
+ cookie.fp = mch_fopen((char *)fname_exp, READBIN);
+#endif
+ }
+ }
+
+ if (cookie.fp == NULL) {
+ if (p_verbose > 0) {
+ verbose_enter();
+ if (sourcing_name == NULL)
+ smsg((char_u *)_("could not source \"%s\""), fname);
+ else
+ smsg((char_u *)_("line %ld: could not source \"%s\""),
+ sourcing_lnum, fname);
+ verbose_leave();
+ }
+ goto theend;
+ }
+
+ /*
+ * The file exists.
+ * - In verbose mode, give a message.
+ * - For a vimrc file, may want to set 'compatible', call vimrc_found().
+ */
+ if (p_verbose > 1) {
+ verbose_enter();
+ if (sourcing_name == NULL)
+ smsg((char_u *)_("sourcing \"%s\""), fname);
+ else
+ smsg((char_u *)_("line %ld: sourcing \"%s\""),
+ sourcing_lnum, fname);
+ verbose_leave();
+ }
+ if (is_vimrc == DOSO_VIMRC)
+ vimrc_found(fname_exp, (char_u *)"MYVIMRC");
+ else if (is_vimrc == DOSO_GVIMRC)
+ vimrc_found(fname_exp, (char_u *)"MYGVIMRC");
+
+#ifdef USE_CRNL
+ /* If no automatic file format: Set default to CR-NL. */
+ if (*p_ffs == NUL)
+ cookie.fileformat = EOL_DOS;
+ else
+ cookie.fileformat = EOL_UNKNOWN;
+ cookie.error = FALSE;
+#endif
+
+#ifdef USE_CR
+ /* If no automatic file format: Set default to CR. */
+ if (*p_ffs == NUL)
+ cookie.fileformat = EOL_MAC;
+ else
+ cookie.fileformat = EOL_UNKNOWN;
+ cookie.error = FALSE;
+#endif
+
+ cookie.nextline = NULL;
+ cookie.finished = FALSE;
+
+ /*
+ * Check if this script has a breakpoint.
+ */
+ cookie.breakpoint = dbg_find_breakpoint(TRUE, fname_exp, (linenr_T)0);
+ cookie.fname = fname_exp;
+ cookie.dbg_tick = debug_tick;
+
+ cookie.level = ex_nesting_level;
+
+ /*
+ * Keep the sourcing name/lnum, for recursive calls.
+ */
+ save_sourcing_name = sourcing_name;
+ sourcing_name = fname_exp;
+ 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);
+ if (p != NULL) {
+ vim_free(firstline);
+ firstline = p;
+ }
+ }
+
+#ifdef STARTUPTIME
+ if (time_fd != NULL)
+ time_push(&tv_rel, &tv_start);
+#endif
+
+ if (do_profiling == PROF_YES)
+ prof_child_enter(&wait_start); /* entering a child now */
+
+ /* Don't use local function variables, if called from a function.
+ * Also starts profiling timer for nested script. */
+ save_funccalp = save_funccal();
+
+ /*
+ * Check if this script was sourced before to finds its SID.
+ * If it's new, generate a new SID.
+ */
+ save_current_SID = current_SID;
+# ifdef UNIX
+ stat_ok = (mch_stat((char *)fname_exp, &st) >= 0);
+# endif
+ for (current_SID = script_items.ga_len; current_SID > 0; --current_SID) {
+ si = &SCRIPT_ITEM(current_SID);
+ if (si->sn_name != NULL
+ && (
+# ifdef UNIX
+ /* Compare dev/ino when possible, it catches symbolic
+ * links. Also compare file names, the inode may change
+ * when the file was edited. */
+ ((stat_ok && si->sn_dev_valid)
+ && (si->sn_dev == st.st_dev
+ && si->sn_ino == st.st_ino)) ||
+# endif
+ fnamecmp(si->sn_name, fname_exp) == 0))
+ break;
+ }
+ if (current_SID == 0) {
+ current_SID = ++last_current_SID;
+ if (ga_grow(&script_items, (int)(current_SID - script_items.ga_len))
+ == FAIL)
+ goto almosttheend;
+ while (script_items.ga_len < current_SID) {
+ ++script_items.ga_len;
+ SCRIPT_ITEM(script_items.ga_len).sn_name = NULL;
+ SCRIPT_ITEM(script_items.ga_len).sn_prof_on = FALSE;
+ }
+ si = &SCRIPT_ITEM(current_SID);
+ si->sn_name = fname_exp;
+ fname_exp = NULL;
+# ifdef UNIX
+ if (stat_ok) {
+ si->sn_dev_valid = TRUE;
+ si->sn_dev = st.st_dev;
+ si->sn_ino = st.st_ino;
+ } else
+ si->sn_dev_valid = FALSE;
+# endif
+
+ /* Allocate the local script variables to use for this script. */
+ new_script_vars(current_SID);
+ }
+
+ if (do_profiling == PROF_YES) {
+ int forceit;
+
+ /* Check if we do profiling for this script. */
+ if (!si->sn_prof_on && has_profiling(TRUE, si->sn_name, &forceit)) {
+ script_do_profile(si);
+ si->sn_pr_force = forceit;
+ }
+ if (si->sn_prof_on) {
+ ++si->sn_pr_count;
+ profile_start(&si->sn_pr_start);
+ profile_zero(&si->sn_pr_children);
+ }
+ }
+
+ /*
+ * Call do_cmdline, which will call getsourceline() to get the lines.
+ */
+ do_cmdline(firstline, getsourceline, (void *)&cookie,
+ DOCMD_VERBOSE|DOCMD_NOWAIT|DOCMD_REPEAT);
+ retval = OK;
+
+ if (do_profiling == PROF_YES) {
+ /* Get "si" again, "script_items" may have been reallocated. */
+ si = &SCRIPT_ITEM(current_SID);
+ if (si->sn_prof_on) {
+ profile_end(&si->sn_pr_start);
+ profile_sub_wait(&wait_start, &si->sn_pr_start);
+ profile_add(&si->sn_pr_total, &si->sn_pr_start);
+ profile_self(&si->sn_pr_self, &si->sn_pr_start,
+ &si->sn_pr_children);
+ }
+ }
+
+ if (got_int)
+ EMSG(_(e_interr));
+ sourcing_name = save_sourcing_name;
+ sourcing_lnum = save_sourcing_lnum;
+ if (p_verbose > 1) {
+ verbose_enter();
+ smsg((char_u *)_("finished sourcing %s"), fname);
+ if (sourcing_name != NULL)
+ smsg((char_u *)_("continuing in %s"), sourcing_name);
+ verbose_leave();
+ }
+#ifdef STARTUPTIME
+ if (time_fd != NULL) {
+ vim_snprintf((char *)IObuff, IOSIZE, "sourcing %s", fname);
+ time_msg((char *)IObuff, &tv_start);
+ time_pop(&tv_rel);
+ }
+#endif
+
+ /*
+ * After a "finish" in debug mode, need to break at first command of next
+ * sourced file.
+ */
+ if (save_debug_break_level > ex_nesting_level
+ && debug_break_level == ex_nesting_level)
+ ++debug_break_level;
+
+almosttheend:
+ current_SID = save_current_SID;
+ restore_funccal(save_funccalp);
+ if (do_profiling == PROF_YES)
+ prof_child_exit(&wait_start); /* leaving a child now */
+ fclose(cookie.fp);
+ vim_free(cookie.nextline);
+ vim_free(firstline);
+ convert_setup(&cookie.conv, NULL, NULL);
+
+theend:
+ vim_free(fname_exp);
+ return retval;
+}
+
+
+/*
+ * ":scriptnames"
+ */
+void ex_scriptnames(eap)
+exarg_T *eap UNUSED;
+{
+ int i;
+
+ for (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,
+ NameBuff, MAXPATHL, TRUE);
+ smsg((char_u *)"%3d: %s", i, NameBuff);
+ }
+}
+
+# if defined(BACKSLASH_IN_FILENAME) || defined(PROTO)
+/*
+ * Fix slashes in the list of script names for 'shellslash'.
+ */
+void scriptnames_slash_adjust() {
+ int i;
+
+ for (i = 1; i <= script_items.ga_len; ++i)
+ if (SCRIPT_ITEM(i).sn_name != NULL)
+ slash_adjust(SCRIPT_ITEM(i).sn_name);
+}
+
+# endif
+
+/*
+ * Get a pointer to a script name. Used for ":verbose set".
+ */
+char_u * get_scriptname(id)
+scid_T id;
+{
+ 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");
+ return SCRIPT_ITEM(id).sn_name;
+}
+
+# if defined(EXITFREE) || defined(PROTO)
+void free_scriptnames() {
+ int i;
+
+ for (i = script_items.ga_len; i > 0; --i)
+ vim_free(SCRIPT_ITEM(i).sn_name);
+ ga_clear(&script_items);
+}
+
+# endif
+
+
+#if defined(USE_CR) || defined(PROTO)
+
+# if defined(__MSL__) && (__MSL__ >= 22)
+/*
+ * Newer version of the Metrowerks library handle DOS and UNIX files
+ * without help.
+ * Test with earlier versions, MSL 2.2 is the library supplied with
+ * Codewarrior Pro 2.
+ */
+char * fgets_cr(s, n, stream)
+char *s;
+int n;
+FILE *stream;
+{
+ return fgets(s, n, stream);
+}
+# else
+/*
+ * Version of fgets() which also works for lines ending in a <CR> only
+ * (Macintosh format).
+ * For older versions of the Metrowerks library.
+ * At least CodeWarrior 9 needed this code.
+ */
+char * fgets_cr(s, n, stream)
+char *s;
+int n;
+FILE *stream;
+{
+ int c = 0;
+ int char_read = 0;
+
+ while (!feof(stream) && c != '\r' && c != '\n' && char_read < n - 1) {
+ c = fgetc(stream);
+ s[char_read++] = c;
+ /* If the file is in DOS format, we need to skip a NL after a CR. I
+ * thought it was the other way around, but this appears to work... */
+ if (c == '\n') {
+ c = fgetc(stream);
+ if (c != '\r')
+ ungetc(c, stream);
+ }
+ }
+
+ s[char_read] = 0;
+ if (char_read == 0)
+ return NULL;
+
+ if (feof(stream) && char_read == 1)
+ return NULL;
+
+ return s;
+}
+# endif
+#endif
+
+/*
+ * Get one full line from a sourced file.
+ * Called by do_cmdline() when it's called from do_source().
+ *
+ * Return a pointer to the line in allocated memory.
+ * Return NULL for end-of-file or some error.
+ */
+char_u * getsourceline(c, cookie, indent)
+int c UNUSED;
+void *cookie;
+int indent UNUSED;
+{
+ struct source_cookie *sp = (struct source_cookie *)cookie;
+ char_u *line;
+ char_u *p;
+
+ /* If breakpoints have been added/deleted need to check for it. */
+ if (sp->dbg_tick < debug_tick) {
+ sp->breakpoint = dbg_find_breakpoint(TRUE, sp->fname, sourcing_lnum);
+ sp->dbg_tick = debug_tick;
+ }
+ if (do_profiling == PROF_YES)
+ script_line_end();
+ /*
+ * Get current line. If there is a read-ahead line, use it, otherwise get
+ * one now.
+ */
+ if (sp->finished)
+ line = NULL;
+ else if (sp->nextline == NULL)
+ line = get_one_sourceline(sp);
+ else {
+ line = sp->nextline;
+ sp->nextline = NULL;
+ ++sourcing_lnum;
+ }
+ if (line != NULL && do_profiling == PROF_YES)
+ script_line_start();
+
+ /* Only concatenate lines starting with a \ when 'cpoptions' doesn't
+ * contain the 'C' flag. */
+ if (line != NULL && (vim_strchr(p_cpo, CPO_CONCAT) == NULL)) {
+ /* compensate for the one line read-ahead */
+ --sourcing_lnum;
+
+ /* Get the next line and concatenate it when it starts with a
+ * backslash. We always need to read the next line, keep it in
+ * sp->nextline. */
+ sp->nextline = get_one_sourceline(sp);
+ if (sp->nextline != NULL && *(p = skipwhite(sp->nextline)) == '\\') {
+ garray_T ga;
+
+ ga_init2(&ga, (int)sizeof(char_u), 400);
+ ga_concat(&ga, line);
+ ga_concat(&ga, p + 1);
+ for (;; ) {
+ vim_free(sp->nextline);
+ sp->nextline = get_one_sourceline(sp);
+ if (sp->nextline == NULL)
+ break;
+ p = skipwhite(sp->nextline);
+ if (*p != '\\')
+ break;
+ /* Adjust the growsize to the current length to speed up
+ * concatenating many lines. */
+ if (ga.ga_len > 400) {
+ if (ga.ga_len > 8000)
+ ga.ga_growsize = 8000;
+ else
+ ga.ga_growsize = ga.ga_len;
+ }
+ ga_concat(&ga, p + 1);
+ }
+ ga_append(&ga, NUL);
+ vim_free(line);
+ line = ga.ga_data;
+ }
+ }
+
+ if (line != NULL && sp->conv.vc_type != CONV_NONE) {
+ char_u *s;
+
+ /* Convert the encoding of the script line. */
+ s = string_convert(&sp->conv, line, NULL);
+ if (s != NULL) {
+ vim_free(line);
+ line = s;
+ }
+ }
+
+ /* Did we encounter a breakpoint? */
+ if (sp->breakpoint != 0 && sp->breakpoint <= sourcing_lnum) {
+ dbg_breakpoint(sp->fname, sourcing_lnum);
+ /* Find next breakpoint. */
+ sp->breakpoint = dbg_find_breakpoint(TRUE, sp->fname, sourcing_lnum);
+ sp->dbg_tick = debug_tick;
+ }
+
+ return line;
+}
+
+static char_u * get_one_sourceline(sp)
+struct source_cookie *sp;
+{
+ garray_T ga;
+ int len;
+ int c;
+ char_u *buf;
+#ifdef USE_CRNL
+ int has_cr; /* CR-LF found */
+#endif
+#ifdef USE_CR
+ char_u *scan;
+#endif
+ int have_read = FALSE;
+
+ /* use a growarray to store the sourced line */
+ ga_init2(&ga, 1, 250);
+
+ /*
+ * Loop until there is a finished line (or end-of-file).
+ */
+ sourcing_lnum++;
+ for (;; ) {
+ /* make room to read at least 120 (more) characters */
+ if (ga_grow(&ga, 120) == FAIL)
+ break;
+ buf = (char_u *)ga.ga_data;
+
+#ifdef USE_CR
+ if (sp->fileformat == EOL_MAC) {
+ if (fgets_cr((char *)buf + ga.ga_len, ga.ga_maxlen - ga.ga_len,
+ sp->fp) == NULL)
+ break;
+ } else
+#endif
+ if (fgets((char *)buf + ga.ga_len, ga.ga_maxlen - ga.ga_len,
+ sp->fp) == NULL)
+ break;
+ len = ga.ga_len + (int)STRLEN(buf + ga.ga_len);
+#ifdef USE_CRNL
+ /* Ignore a trailing CTRL-Z, when in Dos mode. Only recognize the
+ * CTRL-Z by its own, or after a NL. */
+ if ( (len == 1 || (len >= 2 && buf[len - 2] == '\n'))
+ && sp->fileformat == EOL_DOS
+ && buf[len - 1] == Ctrl_Z) {
+ buf[len - 1] = NUL;
+ break;
+ }
+#endif
+
+#ifdef USE_CR
+ /* If the read doesn't stop on a new line, and there's
+ * some CR then we assume a Mac format */
+ if (sp->fileformat == EOL_UNKNOWN) {
+ if (buf[len - 1] != '\n' && vim_strchr(buf, '\r') != NULL)
+ sp->fileformat = EOL_MAC;
+ else
+ sp->fileformat = EOL_UNIX;
+ }
+
+ if (sp->fileformat == EOL_MAC) {
+ scan = vim_strchr(buf, '\r');
+
+ if (scan != NULL) {
+ *scan = '\n';
+ if (*(scan + 1) != 0) {
+ *(scan + 1) = 0;
+ fseek(sp->fp, (long)(scan - buf - len + 1), SEEK_CUR);
+ }
+ }
+ len = STRLEN(buf);
+ }
+#endif
+
+ have_read = TRUE;
+ ga.ga_len = len;
+
+ /* If the line was longer than the buffer, read more. */
+ if (ga.ga_maxlen - ga.ga_len == 1 && buf[len - 1] != '\n')
+ continue;
+
+ if (len >= 1 && buf[len - 1] == '\n') { /* remove trailing NL */
+#ifdef USE_CRNL
+ has_cr = (len >= 2 && buf[len - 2] == '\r');
+ if (sp->fileformat == EOL_UNKNOWN) {
+ if (has_cr)
+ sp->fileformat = EOL_DOS;
+ else
+ sp->fileformat = EOL_UNIX;
+ }
+
+ if (sp->fileformat == EOL_DOS) {
+ if (has_cr) { /* replace trailing CR */
+ buf[len - 2] = '\n';
+ --len;
+ --ga.ga_len;
+ } else { /* lines like ":map xx yy^M" will have failed */
+ if (!sp->error) {
+ msg_source(hl_attr(HLF_W));
+ EMSG(_("W15: Warning: Wrong line separator, ^M may be missing"));
+ }
+ sp->error = TRUE;
+ sp->fileformat = EOL_UNIX;
+ }
+ }
+#endif
+ /* The '\n' is escaped if there is an odd number of ^V's just
+ * before it, first set "c" just before the 'V's and then check
+ * len&c parities (is faster than ((len-c)%2 == 0)) -- Acevedo */
+ for (c = len - 2; c >= 0 && buf[c] == Ctrl_V; c--)
+ ;
+ if ((len & 1) != (c & 1)) { /* escaped NL, read more */
+ sourcing_lnum++;
+ continue;
+ }
+
+ buf[len - 1] = NUL; /* remove the NL */
+ }
+
+ /*
+ * Check for ^C here now and then, so recursive :so can be broken.
+ */
+ line_breakcheck();
+ break;
+ }
+
+ if (have_read)
+ return (char_u *)ga.ga_data;
+
+ vim_free(ga.ga_data);
+ return NULL;
+}
+
+/*
+ * Called when starting to read a script line.
+ * "sourcing_lnum" must be correct!
+ * When skipping lines it may not actually be executed, but we won't find out
+ * until later and we need to store the time now.
+ */
+void script_line_start() {
+ scriptitem_T *si;
+ sn_prl_T *pp;
+
+ if (current_SID <= 0 || current_SID > script_items.ga_len)
+ return;
+ si = &SCRIPT_ITEM(current_SID);
+ 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));
+ 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) {
+ /* Zero counters for a line that was not used before. */
+ pp = &PRL_ITEM(si, si->sn_prl_ga.ga_len);
+ pp->snp_count = 0;
+ profile_zero(&pp->sn_prl_total);
+ profile_zero(&pp->sn_prl_self);
+ ++si->sn_prl_ga.ga_len;
+ }
+ si->sn_prl_execed = FALSE;
+ profile_start(&si->sn_prl_start);
+ profile_zero(&si->sn_prl_children);
+ profile_get_wait(&si->sn_prl_wait);
+ }
+}
+
+/*
+ * Called when actually executing a function line.
+ */
+void script_line_exec() {
+ scriptitem_T *si;
+
+ if (current_SID <= 0 || current_SID > script_items.ga_len)
+ return;
+ si = &SCRIPT_ITEM(current_SID);
+ if (si->sn_prof_on && si->sn_prl_idx >= 0)
+ si->sn_prl_execed = TRUE;
+}
+
+/*
+ * Called when done with a function line.
+ */
+void script_line_end() {
+ scriptitem_T *si;
+ sn_prl_T *pp;
+
+ if (current_SID <= 0 || current_SID > script_items.ga_len)
+ return;
+ si = &SCRIPT_ITEM(current_SID);
+ if (si->sn_prof_on && si->sn_prl_idx >= 0
+ && si->sn_prl_idx < si->sn_prl_ga.ga_len) {
+ if (si->sn_prl_execed) {
+ pp = &PRL_ITEM(si, si->sn_prl_idx);
+ ++pp->snp_count;
+ profile_end(&si->sn_prl_start);
+ profile_sub_wait(&si->sn_prl_wait, &si->sn_prl_start);
+ profile_add(&pp->sn_prl_total, &si->sn_prl_start);
+ profile_self(&pp->sn_prl_self, &si->sn_prl_start,
+ &si->sn_prl_children);
+ }
+ si->sn_prl_idx = -1;
+ }
+}
+
+/*
+ * ":scriptencoding": Set encoding conversion for a sourced script.
+ * Without the multi-byte feature it's simply ignored.
+ */
+void ex_scriptencoding(eap)
+exarg_T *eap UNUSED;
+{
+ struct source_cookie *sp;
+ char_u *name;
+
+ if (!getline_equal(eap->getline, eap->cookie, getsourceline)) {
+ EMSG(_("E167: :scriptencoding used outside of a sourced file"));
+ return;
+ }
+
+ if (*eap->arg != NUL) {
+ name = enc_canonize(eap->arg);
+ if (name == NULL) /* out of memory */
+ return;
+ } else
+ name = eap->arg;
+
+ /* Setup for conversion from the specified encoding to 'encoding'. */
+ sp = (struct source_cookie *)getline_cookie(eap->getline, eap->cookie);
+ convert_setup(&sp->conv, name, p_enc);
+
+ if (name != eap->arg)
+ vim_free(name);
+}
+
+/*
+ * ":finish": Mark a sourced file as finished.
+ */
+void ex_finish(eap)
+exarg_T *eap;
+{
+ if (getline_equal(eap->getline, eap->cookie, getsourceline))
+ do_finish(eap, FALSE);
+ else
+ EMSG(_("E168: :finish used outside of a sourced file"));
+}
+
+/*
+ * Mark a sourced file as finished. Possibly makes the ":finish" pending.
+ * Also called for a pending finish at the ":endtry" or after returning from
+ * an extra do_cmdline(). "reanimate" is used in the latter case.
+ */
+void do_finish(eap, reanimate)
+exarg_T *eap;
+int reanimate;
+{
+ int idx;
+
+ if (reanimate)
+ ((struct source_cookie *)getline_cookie(eap->getline,
+ eap->cookie))->finished = FALSE;
+
+ /*
+ * Cleanup (and inactivate) conditionals, but stop when a try conditional
+ * not in its finally clause (which then is to be executed next) is found.
+ * In this case, make the ":finish" pending for execution at the ":endtry".
+ * Otherwise, finish normally.
+ */
+ idx = cleanup_conditionals(eap->cstack, 0, TRUE);
+ if (idx >= 0) {
+ eap->cstack->cs_pending[idx] = CSTP_FINISH;
+ report_make_pending(CSTP_FINISH, NULL);
+ } else
+ ((struct source_cookie *)getline_cookie(eap->getline,
+ eap->cookie))->finished = TRUE;
+}
+
+
+/*
+ * Return TRUE when a sourced file had the ":finish" command: Don't give error
+ * message for missing ":endif".
+ * Return FALSE when not sourcing a file.
+ */
+int source_finished(fgetline, cookie)
+char_u *(*fgetline)__ARGS((int, void *, int));
+void *cookie;
+{
+ return getline_equal(fgetline, cookie, getsourceline)
+ && ((struct source_cookie *)getline_cookie(
+ fgetline, cookie))->finished;
+}
+
+/*
+ * ":checktime [buffer]"
+ */
+void ex_checktime(eap)
+exarg_T *eap;
+{
+ buf_T *buf;
+ int save_no_check_timestamps = no_check_timestamps;
+
+ no_check_timestamps = 0;
+ if (eap->addr_count == 0) /* default is all buffers */
+ check_timestamps(FALSE);
+ else {
+ buf = buflist_findnr((int)eap->line2);
+ if (buf != NULL) /* cannot happen? */
+ (void)buf_check_timestamp(buf, FALSE);
+ }
+ no_check_timestamps = save_no_check_timestamps;
+}
+
+#if (defined(HAVE_LOCALE_H) || defined(X_LOCALE)) \
+ && (defined(FEAT_EVAL) || defined(FEAT_MULTI_LANG))
+# define HAVE_GET_LOCALE_VAL
+static char *get_locale_val __ARGS((int what));
+
+static char * get_locale_val(what)
+int what;
+{
+ char *loc;
+
+ /* Obtain the locale value from the libraries. For DJGPP this is
+ * redefined and it doesn't use the arguments. */
+ loc = setlocale(what, NULL);
+
+
+ return loc;
+}
+#endif
+
+
+
+/*
+ * Obtain the current messages language. Used to set the default for
+ * 'helplang'. May return NULL or an empty string.
+ */
+char_u * get_mess_lang() {
+ char_u *p;
+
+# ifdef HAVE_GET_LOCALE_VAL
+# if defined(LC_MESSAGES)
+ p = (char_u *)get_locale_val(LC_MESSAGES);
+# else
+ /* This is necessary for Win32, where LC_MESSAGES is not defined and $LANG
+ * may be set to the LCID number. LC_COLLATE is the best guess, LC_TIME
+ * and LC_MONETARY may be set differently for a Japanese working in the
+ * US. */
+ p = (char_u *)get_locale_val(LC_COLLATE);
+# endif
+# else
+ p = mch_getenv((char_u *)"LC_ALL");
+ if (p == NULL || *p == NUL) {
+ p = mch_getenv((char_u *)"LC_MESSAGES");
+ if (p == NULL || *p == NUL)
+ p = mch_getenv((char_u *)"LANG");
+ }
+# endif
+ return p;
+}
+
+/* Complicated #if; matches with where get_mess_env() is used below. */
+#ifdef HAVE_WORKING_LIBINTL
+static char_u *get_mess_env __ARGS((void));
+
+/*
+ * Get the language used for messages from the environment.
+ */
+static char_u * get_mess_env() {
+ char_u *p;
+
+ p = mch_getenv((char_u *)"LC_ALL");
+ if (p == NULL || *p == NUL) {
+ p = mch_getenv((char_u *)"LC_MESSAGES");
+ if (p == NULL || *p == NUL) {
+ p = mch_getenv((char_u *)"LANG");
+ if (p != NULL && VIM_ISDIGIT(*p))
+ p = NULL; /* ignore something like "1043" */
+# ifdef HAVE_GET_LOCALE_VAL
+ if (p == NULL || *p == NUL)
+ p = (char_u *)get_locale_val(LC_CTYPE);
+# endif
+ }
+ }
+ return p;
+}
+
+#endif
+
+
+/*
+ * Set the "v:lang" variable according to the current locale setting.
+ * Also do "v:lc_time"and "v:ctype".
+ */
+void set_lang_var() {
+ char_u *loc;
+
+# ifdef HAVE_GET_LOCALE_VAL
+ loc = (char_u *)get_locale_val(LC_CTYPE);
+# else
+ /* setlocale() not supported: use the default value */
+ loc = (char_u *)"C";
+# endif
+ set_vim_var_string(VV_CTYPE, loc, -1);
+
+ /* When LC_MESSAGES isn't defined use the value from $LC_MESSAGES, fall
+ * back to LC_CTYPE if it's empty. */
+# ifdef HAVE_WORKING_LIBINTL
+ loc = get_mess_env();
+# else
+ loc = (char_u *)get_locale_val(LC_MESSAGES);
+# endif
+ set_vim_var_string(VV_LANG, loc, -1);
+
+# ifdef HAVE_GET_LOCALE_VAL
+ loc = (char_u *)get_locale_val(LC_TIME);
+# endif
+ set_vim_var_string(VV_LC_TIME, loc, -1);
+}
+
+#ifdef HAVE_WORKING_LIBINTL
+/*
+ * ":language": Set the language (locale).
+ */
+void ex_language(eap)
+exarg_T *eap;
+{
+ char *loc;
+ char_u *p;
+ char_u *name;
+ int what = LC_ALL;
+ char *whatstr = "";
+#ifdef LC_MESSAGES
+# define VIM_LC_MESSAGES LC_MESSAGES
+#else
+# define VIM_LC_MESSAGES 6789
+#endif
+
+ name = eap->arg;
+
+ /* Check for "messages {name}", "ctype {name}" or "time {name}" argument.
+ * Allow abbreviation, but require at least 3 characters to avoid
+ * confusion with a two letter language name "me" or "ct". */
+ p = skiptowhite(eap->arg);
+ if ((*p == NUL || vim_iswhite(*p)) && p - eap->arg >= 3) {
+ if (STRNICMP(eap->arg, "messages", p - eap->arg) == 0) {
+ what = VIM_LC_MESSAGES;
+ name = skipwhite(p);
+ whatstr = "messages ";
+ } else if (STRNICMP(eap->arg, "ctype", p - eap->arg) == 0) {
+ what = LC_CTYPE;
+ name = skipwhite(p);
+ whatstr = "ctype ";
+ } else if (STRNICMP(eap->arg, "time", p - eap->arg) == 0) {
+ what = LC_TIME;
+ name = skipwhite(p);
+ whatstr = "time ";
+ }
+ }
+
+ if (*name == NUL) {
+#ifdef HAVE_WORKING_LIBINTL
+ if (what == VIM_LC_MESSAGES)
+ p = get_mess_env();
+ else
+#endif
+ p = (char_u *)setlocale(what, NULL);
+ if (p == NULL || *p == NUL)
+ p = (char_u *)"Unknown";
+ smsg((char_u *)_("Current %slanguage: \"%s\""), whatstr, p);
+ } else {
+#ifndef LC_MESSAGES
+ if (what == VIM_LC_MESSAGES)
+ loc = "";
+ else
+#endif
+ {
+ loc = setlocale(what, (char *)name);
+#if defined(FEAT_FLOAT) && defined(LC_NUMERIC)
+ /* Make sure strtod() uses a decimal point, not a comma. */
+ setlocale(LC_NUMERIC, "C");
+#endif
+ }
+ if (loc == NULL)
+ EMSG2(_("E197: Cannot set language to \"%s\""), name);
+ else {
+#ifdef HAVE_NL_MSG_CAT_CNTR
+ /* Need to do this for GNU gettext, otherwise cached translations
+ * will be used again. */
+ extern int _nl_msg_cat_cntr;
+
+ ++_nl_msg_cat_cntr;
+#endif
+ /* Reset $LC_ALL, otherwise it would overrule everything. */
+ vim_setenv((char_u *)"LC_ALL", (char_u *)"");
+
+ if (what != LC_TIME) {
+ /* Tell gettext() what to translate to. It apparently doesn't
+ * use the currently effective locale. Also do this when
+ * FEAT_GETTEXT isn't defined, so that shell commands use this
+ * value. */
+ if (what == LC_ALL) {
+ vim_setenv((char_u *)"LANG", name);
+
+ /* Clear $LANGUAGE because GNU gettext uses it. */
+ vim_setenv((char_u *)"LANGUAGE", (char_u *)"");
+ }
+ if (what != LC_CTYPE) {
+ char_u *mname;
+ mname = name;
+ vim_setenv((char_u *)"LC_MESSAGES", mname);
+ set_helplang_default(mname);
+ }
+ }
+
+ /* Set v:lang, v:lc_time and v:ctype to the final result. */
+ set_lang_var();
+ maketitle();
+ }
+ }
+}
+
+
+static char_u **locales = NULL; /* Array of all available locales */
+static int did_init_locales = FALSE;
+
+static void init_locales __ARGS((void));
+static char_u **find_locales __ARGS((void));
+
+/*
+ * Lazy initialization of all available locales.
+ */
+static void init_locales() {
+ if (!did_init_locales) {
+ did_init_locales = TRUE;
+ locales = find_locales();
+ }
+}
+
+/* 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() {
+ garray_T locales_ga;
+ char_u *loc;
+
+ /* Find all available locales by running command "locale -a". If this
+ * doesn't work we won't have completion. */
+ char_u *locale_a = get_cmd_output((char_u *)"locale -a",
+ NULL, SHELL_SILENT);
+ if (locale_a == NULL)
+ return NULL;
+ ga_init2(&locales_ga, sizeof(char_u *), 20);
+
+ /* Transform locale_a string where each locale is separated by "\n"
+ * into an array of locale strings. */
+ loc = (char_u *)strtok((char *)locale_a, "\n");
+
+ while (loc != NULL) {
+ if (ga_grow(&locales_ga, 1) == FAIL)
+ break;
+ loc = vim_strsave(loc);
+ if (loc == NULL)
+ break;
+
+ ((char_u **)locales_ga.ga_data)[locales_ga.ga_len++] = loc;
+ loc = (char_u *)strtok(NULL, "\n");
+ }
+ vim_free(locale_a);
+ if (ga_grow(&locales_ga, 1) == FAIL) {
+ ga_clear(&locales_ga);
+ return NULL;
+ }
+ ((char_u **)locales_ga.ga_data)[locales_ga.ga_len] = NULL;
+ return (char_u **)locales_ga.ga_data;
+}
+
+# if defined(EXITFREE) || defined(PROTO)
+void free_locales() {
+ int i;
+ if (locales != NULL) {
+ for (i = 0; locales[i] != NULL; i++)
+ vim_free(locales[i]);
+ vim_free(locales);
+ locales = NULL;
+ }
+}
+
+# endif
+
+/*
+ * Function given to ExpandGeneric() to obtain the possible arguments of the
+ * ":language" command.
+ */
+char_u * get_lang_arg(xp, idx)
+expand_T *xp UNUSED;
+int idx;
+{
+ if (idx == 0)
+ return (char_u *)"messages";
+ if (idx == 1)
+ return (char_u *)"ctype";
+ if (idx == 2)
+ return (char_u *)"time";
+
+ init_locales();
+ if (locales == NULL)
+ return NULL;
+ return locales[idx - 3];
+}
+
+/*
+ * Function given to ExpandGeneric() to obtain the available locales.
+ */
+char_u * get_locales(xp, idx)
+expand_T *xp UNUSED;
+int idx;
+{
+ init_locales();
+ if (locales == NULL)
+ return NULL;
+ return locales[idx];
+}
+
+#endif
diff --git a/src/ex_docmd.c b/src/ex_docmd.c
new file mode 100644
index 0000000000..88fe8e1c5d
--- /dev/null
+++ b/src/ex_docmd.c
@@ -0,0 +1,9398 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * 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.
+ */
+
+/*
+ * ex_docmd.c: functions for executing an Ex command line.
+ */
+
+#include "vim.h"
+
+static int quitmore = 0;
+static int ex_pressedreturn = FALSE;
+
+typedef struct ucmd {
+ char_u *uc_name; /* The command name */
+ long_u uc_argt; /* The argument type */
+ char_u *uc_rep; /* The command's replacement string */
+ long uc_def; /* The default value for a range/count */
+ int uc_compl; /* completion type */
+ scid_T uc_scriptID; /* SID where the command was defined */
+ char_u *uc_compl_arg; /* completion argument if any */
+} ucmd_T;
+
+#define UC_BUFFER 1 /* -buffer: local to current buffer */
+
+static garray_T ucmds = {0, 0, sizeof(ucmd_T), 4, NULL};
+
+#define USER_CMD(i) (&((ucmd_T *)(ucmds.ga_data))[i])
+#define USER_CMD_GA(gap, i) (&((ucmd_T *)((gap)->ga_data))[i])
+
+static void do_ucmd __ARGS((exarg_T *eap));
+static void ex_command __ARGS((exarg_T *eap));
+static void ex_delcommand __ARGS((exarg_T *eap));
+static char_u *get_user_command_name __ARGS((int idx));
+
+
+static char_u *do_one_cmd __ARGS((char_u **, int, struct condstack *,
+ char_u *(*fgetline)(int, void *, int),
+ void *cookie));
+static void append_command __ARGS((char_u *cmd));
+static char_u *find_command __ARGS((exarg_T *eap, int *full));
+
+static void ex_abbreviate __ARGS((exarg_T *eap));
+static void ex_map __ARGS((exarg_T *eap));
+static void ex_unmap __ARGS((exarg_T *eap));
+static void ex_mapclear __ARGS((exarg_T *eap));
+static void ex_abclear __ARGS((exarg_T *eap));
+static void ex_autocmd __ARGS((exarg_T *eap));
+static void ex_doautocmd __ARGS((exarg_T *eap));
+static void ex_bunload __ARGS((exarg_T *eap));
+static void ex_buffer __ARGS((exarg_T *eap));
+static void ex_bmodified __ARGS((exarg_T *eap));
+static void ex_bnext __ARGS((exarg_T *eap));
+static void ex_bprevious __ARGS((exarg_T *eap));
+static void ex_brewind __ARGS((exarg_T *eap));
+static void ex_blast __ARGS((exarg_T *eap));
+static char_u *getargcmd __ARGS((char_u **));
+static char_u *skip_cmd_arg __ARGS((char_u *p, int rembs));
+static int getargopt __ARGS((exarg_T *eap));
+
+static int check_more __ARGS((int, int));
+static linenr_T get_address __ARGS((char_u **, int skip, int to_other_file));
+static void get_flags __ARGS((exarg_T *eap));
+#if !defined(FEAT_PERL) \
+ || !defined(FEAT_PYTHON) || !defined(FEAT_PYTHON3) \
+ || !defined(FEAT_TCL) \
+ || !defined(FEAT_RUBY) \
+ || !defined(FEAT_LUA) \
+ || !defined(FEAT_MZSCHEME)
+# define HAVE_EX_SCRIPT_NI
+static void ex_script_ni __ARGS((exarg_T *eap));
+#endif
+static char_u *invalid_range __ARGS((exarg_T *eap));
+static void correct_range __ARGS((exarg_T *eap));
+static char_u *replace_makeprg __ARGS((exarg_T *eap, char_u *p,
+ char_u **cmdlinep));
+static char_u *repl_cmdline __ARGS((exarg_T *eap, char_u *src, int srclen,
+ char_u *repl,
+ char_u **cmdlinep));
+static void ex_highlight __ARGS((exarg_T *eap));
+static void ex_colorscheme __ARGS((exarg_T *eap));
+static void ex_quit __ARGS((exarg_T *eap));
+static void ex_cquit __ARGS((exarg_T *eap));
+static void ex_quit_all __ARGS((exarg_T *eap));
+static void ex_close __ARGS((exarg_T *eap));
+static void ex_win_close __ARGS((int forceit, win_T *win, tabpage_T *tp));
+static void ex_only __ARGS((exarg_T *eap));
+static void ex_resize __ARGS((exarg_T *eap));
+static void ex_stag __ARGS((exarg_T *eap));
+static void ex_tabclose __ARGS((exarg_T *eap));
+static void ex_tabonly __ARGS((exarg_T *eap));
+static void ex_tabnext __ARGS((exarg_T *eap));
+static void ex_tabmove __ARGS((exarg_T *eap));
+static void ex_tabs __ARGS((exarg_T *eap));
+static void ex_pclose __ARGS((exarg_T *eap));
+static void ex_ptag __ARGS((exarg_T *eap));
+static void ex_pedit __ARGS((exarg_T *eap));
+static void ex_hide __ARGS((exarg_T *eap));
+static void ex_stop __ARGS((exarg_T *eap));
+static void ex_exit __ARGS((exarg_T *eap));
+static void ex_print __ARGS((exarg_T *eap));
+static void ex_goto __ARGS((exarg_T *eap));
+static void ex_shell __ARGS((exarg_T *eap));
+static void ex_preserve __ARGS((exarg_T *eap));
+static void ex_recover __ARGS((exarg_T *eap));
+static void ex_mode __ARGS((exarg_T *eap));
+static void ex_wrongmodifier __ARGS((exarg_T *eap));
+static void ex_find __ARGS((exarg_T *eap));
+static void ex_open __ARGS((exarg_T *eap));
+static void ex_edit __ARGS((exarg_T *eap));
+# define ex_drop ex_ni
+# define ex_gui ex_nogui
+static void ex_nogui __ARGS((exarg_T *eap));
+# define ex_tearoff ex_ni
+# define ex_popup ex_ni
+# define ex_simalt ex_ni
+# define gui_mch_find_dialog ex_ni
+# define gui_mch_replace_dialog ex_ni
+# define ex_helpfind ex_ni
+# define ex_lua ex_script_ni
+# define ex_luado ex_ni
+# define ex_luafile ex_ni
+# define ex_mzscheme ex_script_ni
+# define ex_mzfile ex_ni
+# define ex_perl ex_script_ni
+# define ex_perldo ex_ni
+# define ex_python ex_script_ni
+# define ex_pydo ex_ni
+# define ex_pyfile ex_ni
+# define ex_py3 ex_script_ni
+# define ex_py3do ex_ni
+# define ex_py3file ex_ni
+# define ex_tcl ex_script_ni
+# define ex_tcldo ex_ni
+# define ex_tclfile ex_ni
+# define ex_ruby ex_script_ni
+# define ex_rubydo ex_ni
+# define ex_rubyfile ex_ni
+# define ex_sniff ex_ni
+static void ex_swapname __ARGS((exarg_T *eap));
+static void ex_syncbind __ARGS((exarg_T *eap));
+static void ex_read __ARGS((exarg_T *eap));
+static void ex_pwd __ARGS((exarg_T *eap));
+static void ex_equal __ARGS((exarg_T *eap));
+static void ex_sleep __ARGS((exarg_T *eap));
+static void do_exmap __ARGS((exarg_T *eap, int isabbrev));
+static void ex_winsize __ARGS((exarg_T *eap));
+static void ex_wincmd __ARGS((exarg_T *eap));
+#if defined(FEAT_GUI) || defined(UNIX) || defined(VMS) || defined(MSWIN)
+static void ex_winpos __ARGS((exarg_T *eap));
+#else
+# define ex_winpos ex_ni
+#endif
+static void ex_operators __ARGS((exarg_T *eap));
+static void ex_put __ARGS((exarg_T *eap));
+static void ex_copymove __ARGS((exarg_T *eap));
+static void ex_may_print __ARGS((exarg_T *eap));
+static void ex_submagic __ARGS((exarg_T *eap));
+static void ex_join __ARGS((exarg_T *eap));
+static void ex_at __ARGS((exarg_T *eap));
+static void ex_bang __ARGS((exarg_T *eap));
+static void ex_undo __ARGS((exarg_T *eap));
+static void ex_wundo __ARGS((exarg_T *eap));
+static void ex_rundo __ARGS((exarg_T *eap));
+static void ex_redo __ARGS((exarg_T *eap));
+static void ex_later __ARGS((exarg_T *eap));
+static void ex_redir __ARGS((exarg_T *eap));
+static void ex_redraw __ARGS((exarg_T *eap));
+static void ex_redrawstatus __ARGS((exarg_T *eap));
+static void close_redir __ARGS((void));
+static void ex_mkrc __ARGS((exarg_T *eap));
+static void ex_mark __ARGS((exarg_T *eap));
+static char_u *uc_fun_cmd __ARGS((void));
+static char_u *find_ucmd __ARGS((exarg_T *eap, char_u *p, int *full,
+ expand_T *xp,
+ int *compl));
+static void ex_normal __ARGS((exarg_T *eap));
+static void ex_startinsert __ARGS((exarg_T *eap));
+static void ex_stopinsert __ARGS((exarg_T *eap));
+static void ex_checkpath __ARGS((exarg_T *eap));
+static void ex_findpat __ARGS((exarg_T *eap));
+static void ex_psearch __ARGS((exarg_T *eap));
+static void ex_tag __ARGS((exarg_T *eap));
+static void ex_tag_cmd __ARGS((exarg_T *eap, char_u *name));
+static char_u *arg_all __ARGS((void));
+static int makeopens __ARGS((FILE *fd, char_u *dirnow));
+static int put_view __ARGS((FILE *fd, win_T *wp, int add_edit, unsigned *flagp,
+ int current_arg_idx));
+static void ex_loadview __ARGS((exarg_T *eap));
+static char_u *get_view_file __ARGS((int c));
+static int did_lcd; /* whether ":lcd" was produced for a session */
+static void ex_viminfo __ARGS((exarg_T *eap));
+static void ex_behave __ARGS((exarg_T *eap));
+static void ex_filetype __ARGS((exarg_T *eap));
+static void ex_setfiletype __ARGS((exarg_T *eap));
+static void ex_digraphs __ARGS((exarg_T *eap));
+static void ex_set __ARGS((exarg_T *eap));
+static void ex_nohlsearch __ARGS((exarg_T *eap));
+static void ex_match __ARGS((exarg_T *eap));
+static void ex_X __ARGS((exarg_T *eap));
+static void ex_fold __ARGS((exarg_T *eap));
+static void ex_foldopen __ARGS((exarg_T *eap));
+static void ex_folddo __ARGS((exarg_T *eap));
+#ifndef HAVE_WORKING_LIBINTL
+# define ex_language ex_ni
+#endif
+# define ex_sign ex_ni
+# define ex_wsverb ex_ni
+# define ex_nbclose ex_ni
+# define ex_nbkey ex_ni
+# define ex_nbstart ex_ni
+
+
+
+
+/*
+ * Declare cmdnames[].
+ */
+#define DO_DECLARE_EXCMD
+#include "ex_cmds.h"
+
+/*
+ * Table used to quickly search for a command, based on its first character.
+ */
+static cmdidx_T cmdidxs[27] =
+{
+ CMD_append,
+ CMD_buffer,
+ CMD_change,
+ CMD_delete,
+ CMD_edit,
+ CMD_file,
+ CMD_global,
+ CMD_help,
+ CMD_insert,
+ CMD_join,
+ CMD_k,
+ CMD_list,
+ CMD_move,
+ CMD_next,
+ CMD_open,
+ CMD_print,
+ CMD_quit,
+ CMD_read,
+ CMD_substitute,
+ CMD_t,
+ CMD_undo,
+ CMD_vglobal,
+ CMD_write,
+ CMD_xit,
+ CMD_yank,
+ CMD_z,
+ CMD_bang
+};
+
+static char_u dollar_command[2] = {'$', 0};
+
+
+/* Struct for storing a line inside a while/for loop */
+typedef struct {
+ char_u *line; /* command line */
+ linenr_T lnum; /* sourcing_lnum of the line */
+} wcmd_T;
+
+/*
+ * Structure used to store info for line position in a while or for loop.
+ * This is required, because do_one_cmd() may invoke ex_function(), which
+ * reads more lines that may come from the while/for loop.
+ */
+struct loop_cookie {
+ garray_T *lines_gap; /* growarray with line info */
+ int current_line; /* last read line from growarray */
+ int repeating; /* TRUE when looping a second time */
+ /* When "repeating" is FALSE use "getline" and "cookie" to get lines */
+ char_u *(*getline)__ARGS((int, void *, int));
+ void *cookie;
+};
+
+static char_u *get_loop_line __ARGS((int c, void *cookie, int indent));
+static int store_loop_line __ARGS((garray_T *gap, char_u *line));
+static void free_cmdlines __ARGS((garray_T *gap));
+
+/* Struct to save a few things while debugging. Used in do_cmdline() only. */
+struct dbg_stuff {
+ int trylevel;
+ int force_abort;
+ except_T *caught_stack;
+ char_u *vv_exception;
+ char_u *vv_throwpoint;
+ int did_emsg;
+ int got_int;
+ int did_throw;
+ int need_rethrow;
+ int check_cstack;
+ except_T *current_exception;
+};
+
+static void save_dbg_stuff __ARGS((struct dbg_stuff *dsp));
+static void restore_dbg_stuff __ARGS((struct dbg_stuff *dsp));
+
+static void save_dbg_stuff(dsp)
+struct dbg_stuff *dsp;
+{
+ dsp->trylevel = trylevel; trylevel = 0;
+ dsp->force_abort = force_abort; force_abort = FALSE;
+ dsp->caught_stack = caught_stack; caught_stack = NULL;
+ 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;
+ dsp->current_exception = current_exception; current_exception = NULL;
+}
+
+static void restore_dbg_stuff(dsp)
+struct dbg_stuff *dsp;
+{
+ suppress_errthrow = FALSE;
+ trylevel = dsp->trylevel;
+ force_abort = dsp->force_abort;
+ caught_stack = dsp->caught_stack;
+ (void)v_exception(dsp->vv_exception);
+ (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(improved)
+int improved; /* TRUE for "improved Ex" mode */
+{
+ int save_msg_scroll;
+ int prev_msg_row;
+ linenr_T prev_line;
+ int changedtick;
+
+ if (improved)
+ exmode_active = EXMODE_VIM;
+ else
+ exmode_active = EXMODE_NORMAL;
+ State = NORMAL;
+
+ /* When using ":global /pat/ visual" and then "Q" we return to continue
+ * the :global command. */
+ if (global_busy)
+ return;
+
+ save_msg_scroll = msg_scroll;
+ ++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) {
+ /* Check for a ":normal" command and no more characters left. */
+ if (ex_normal_busy > 0 && typebuf.tb_len == 0) {
+ exmode_active = FALSE;
+ break;
+ }
+ msg_scroll = TRUE;
+ need_wait_return = FALSE;
+ ex_pressedreturn = FALSE;
+ ex_no_reprint = FALSE;
+ changedtick = curbuf->b_changedtick;
+ 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);
+ 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)
+ EMSG(_(e_emptybuf));
+ else {
+ if (ex_pressedreturn) {
+ /* go up one line, to overwrite the ":<CR>" line, so the
+ * output doesn't contain empty lines. */
+ msg_row = prev_msg_row;
+ if (prev_msg_row == Rows - 1)
+ msg_row--;
+ }
+ msg_col = 0;
+ print_line_no_prefix(curwin->w_cursor.lnum, FALSE, FALSE);
+ msg_clr_eos();
+ }
+ } else if (ex_pressedreturn && !ex_no_reprint) { /* must be at EOF */
+ if (curbuf->b_ml.ml_flags & ML_EMPTY)
+ EMSG(_(e_emptybuf));
+ else
+ EMSG(_("E501: At end-of-file"));
+ }
+ }
+
+ --RedrawingDisabled;
+ --no_wait_return;
+ update_screen(CLEAR);
+ need_wait_return = FALSE;
+ msg_scroll = save_msg_scroll;
+}
+
+/*
+ * Execute a simple command line. Used for translated commands like "*".
+ */
+int do_cmdline_cmd(cmd)
+char_u *cmd;
+{
+ return do_cmdline(cmd, NULL, NULL,
+ DOCMD_VERBOSE|DOCMD_NOWAIT|DOCMD_KEYTYPED);
+}
+
+/*
+ * do_cmdline(): execute one Ex command line
+ *
+ * 1. Execute "cmdline" when it is not NULL.
+ * If "cmdline" is NULL, or more lines are needed, fgetline() is used.
+ * 2. Split up in parts separated with '|'.
+ *
+ * This function can be called recursively!
+ *
+ * flags:
+ * DOCMD_VERBOSE - The command will be included in the error message.
+ * DOCMD_NOWAIT - Don't call wait_return() and friends.
+ * DOCMD_REPEAT - Repeat execution until fgetline() returns NULL.
+ * DOCMD_KEYTYPED - Don't reset KeyTyped.
+ * DOCMD_EXCRESET - Reset the exception environment (used for debugging).
+ * DOCMD_KEEPLINE - Store first typed line (for repeating with ".").
+ *
+ * return FAIL if cmdline could not be executed, OK otherwise
+ */
+int do_cmdline(cmdline, fgetline, cookie, flags)
+char_u *cmdline;
+char_u *(*fgetline)__ARGS((int, void *, int));
+void *cookie; /* argument for fgetline() */
+int flags;
+{
+ char_u *next_cmdline; /* next cmd to execute */
+ char_u *cmdline_copy = NULL; /* copy of cmd line */
+ int used_getline = FALSE; /* used "fgetline" to obtain command */
+ static int recursive = 0; /* recursive depth */
+ int msg_didout_before_start = 0;
+ int count = 0; /* line number count */
+ int did_inc = FALSE; /* incremented RedrawingDisabled */
+ int retval = OK;
+ struct condstack cstack; /* conditional stack */
+ garray_T lines_ga; /* keep lines for ":while"/":for" */
+ int current_line = 0; /* active line in lines_ga */
+ char_u *fname = NULL; /* function or script name */
+ linenr_T *breakpoint = NULL; /* ptr to breakpoint field in cookie */
+ int *dbg_tick = NULL; /* ptr to dbg_tick field in cookie */
+ struct dbg_stuff debug_saved; /* saved things for debug mode */
+ int initial_trylevel;
+ struct msglist **saved_msg_list = NULL;
+ struct msglist *private_msg_list;
+
+ /* "fgetline" and "cookie" passed to do_one_cmd() */
+ char_u *(*cmd_getline)__ARGS((int, void *, int));
+ void *cmd_cookie;
+ struct loop_cookie cmd_loop_cookie;
+ void *real_cookie;
+ int getline_is_func;
+ static int call_depth = 0; /* recursiveness */
+
+ /* For every pair of do_cmdline()/do_one_cmd() calls, use an extra memory
+ * location for storing error messages to be converted to an exception.
+ * This ensures that the do_errthrow() call in do_one_cmd() does not
+ * combine the messages stored by an earlier invocation of do_one_cmd()
+ * with the command name of the later one. This would happen when
+ * BufWritePost autocommands are executed after a write error. */
+ saved_msg_list = msg_list;
+ 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) {
+ 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. */
+ do_errthrow((struct condstack *)NULL, (char_u *)NULL);
+ msg_list = saved_msg_list;
+ return FAIL;
+ }
+ ++call_depth;
+
+ cstack.cs_idx = -1;
+ cstack.cs_looplevel = 0;
+ cstack.cs_trylevel = 0;
+ cstack.cs_emsg_silent_list = NULL;
+ cstack.cs_lflags = 0;
+ ga_init2(&lines_ga, (int)sizeof(wcmd_T), 10);
+
+ real_cookie = getline_cookie(fgetline, cookie);
+
+ /* Inside a function use a higher nesting level. */
+ getline_is_func = getline_equal(fgetline, cookie, get_func_line);
+ if (getline_is_func && ex_nesting_level == func_level(real_cookie))
+ ++ex_nesting_level;
+
+ /* Get the function or script name and the address where the next breakpoint
+ * line and the debug tick for a function or script are stored. */
+ if (getline_is_func) {
+ fname = func_name(real_cookie);
+ breakpoint = func_breakpoint(real_cookie);
+ dbg_tick = func_dbg_tick(real_cookie);
+ } else if (getline_equal(fgetline, cookie, getsourceline)) {
+ fname = sourcing_name;
+ breakpoint = source_breakpoint(real_cookie);
+ dbg_tick = source_dbg_tick(real_cookie);
+ }
+
+ /*
+ * Initialize "force_abort" and "suppress_errthrow" at the top level.
+ */
+ if (!recursive) {
+ force_abort = FALSE;
+ suppress_errthrow = FALSE;
+ }
+
+ /*
+ * If requested, store and reset the global values controlling the
+ * exception handling (used when debugging). Otherwise clear it to avoid
+ * a bogus compiler warning when the optimizer uses inline functions...
+ */
+ if (flags & DOCMD_EXCRESET)
+ save_dbg_stuff(&debug_saved);
+ else
+ vim_memset(&debug_saved, 0, 1);
+
+ 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;
+
+ /*
+ * KeyTyped is only set when calling vgetc(). Reset it here when not
+ * calling vgetc() (sourced command lines).
+ */
+ if (!(flags & DOCMD_KEYTYPED)
+ && !getline_equal(fgetline, cookie, getexline))
+ KeyTyped = FALSE;
+
+ /*
+ * Continue executing command lines:
+ * - when inside an ":if", ":while" or ":for"
+ * - for multiple commands on one line, separated with '|'
+ * - when repeating until there are no more lines (for ":source")
+ */
+ next_cmdline = cmdline;
+ do {
+ getline_is_func = getline_equal(fgetline, cookie, get_func_line);
+
+ /* stop skipping cmds for an error msg after all endif/while/for */
+ if (next_cmdline == NULL
+ && !force_abort
+ && cstack.cs_idx < 0
+ && !(getline_is_func && func_has_abort(real_cookie))
+ )
+ did_emsg = FALSE;
+
+ /*
+ * 1. If repeating a line in a loop, get a line from lines_ga.
+ * 2. If no line given: Get an allocated line with fgetline().
+ * 3. If a line is given: Make a copy, so we can mess with it.
+ */
+
+ /* 1. If repeating, get a previous line from lines_ga. */
+ if (cstack.cs_looplevel > 0 && current_line < lines_ga.ga_len) {
+ /* Each '|' separated command is stored separately in lines_ga, to
+ * be able to jump to it. Don't use next_cmdline now. */
+ vim_free(cmdline_copy);
+ cmdline_copy = NULL;
+
+ /* Check if a function has returned or, unless it has an unclosed
+ * try conditional, aborted. */
+ if (getline_is_func) {
+ if (do_profiling == PROF_YES)
+ func_line_end(real_cookie);
+ if (func_has_ended(real_cookie)) {
+ retval = FAIL;
+ break;
+ }
+ } else if (do_profiling == PROF_YES
+ && getline_equal(fgetline, cookie, getsourceline))
+ script_line_end();
+
+ /* Check if a sourced file hit a ":finish" command. */
+ if (source_finished(fgetline, cookie)) {
+ retval = FAIL;
+ break;
+ }
+
+ /* If breakpoints have been added/deleted need to check for it. */
+ if (breakpoint != NULL && dbg_tick != NULL
+ && *dbg_tick != debug_tick) {
+ *breakpoint = dbg_find_breakpoint(
+ getline_equal(fgetline, cookie, getsourceline),
+ fname, sourcing_lnum);
+ *dbg_tick = debug_tick;
+ }
+
+ next_cmdline = ((wcmd_T *)(lines_ga.ga_data))[current_line].line;
+ sourcing_lnum = ((wcmd_T *)(lines_ga.ga_data))[current_line].lnum;
+
+ /* Did we encounter a breakpoint? */
+ if (breakpoint != NULL && *breakpoint != 0
+ && *breakpoint <= sourcing_lnum) {
+ dbg_breakpoint(fname, sourcing_lnum);
+ /* Find next breakpoint. */
+ *breakpoint = dbg_find_breakpoint(
+ getline_equal(fgetline, cookie, getsourceline),
+ fname, sourcing_lnum);
+ *dbg_tick = debug_tick;
+ }
+ if (do_profiling == PROF_YES) {
+ if (getline_is_func)
+ func_line_start(real_cookie);
+ else if (getline_equal(fgetline, cookie, getsourceline))
+ script_line_start();
+ }
+ }
+
+ if (cstack.cs_looplevel > 0) {
+ /* Inside a while/for loop we need to store the lines and use them
+ * again. Pass a different "fgetline" function to do_one_cmd()
+ * below, so that it stores lines in or reads them from
+ * "lines_ga". Makes it possible to define a function inside a
+ * while/for loop. */
+ cmd_getline = get_loop_line;
+ cmd_cookie = (void *)&cmd_loop_cookie;
+ cmd_loop_cookie.lines_gap = &lines_ga;
+ cmd_loop_cookie.current_line = current_line;
+ cmd_loop_cookie.getline = fgetline;
+ cmd_loop_cookie.cookie = cookie;
+ cmd_loop_cookie.repeating = (current_line < lines_ga.ga_len);
+ } else {
+ cmd_getline = fgetline;
+ cmd_cookie = cookie;
+ }
+
+ /* 2. If no line given, get an allocated line with fgetline(). */
+ if (next_cmdline == NULL) {
+ /*
+ * Need to set msg_didout for the first line after an ":if",
+ * otherwise the ":if" will be overwritten.
+ */
+ if (count == 1 && getline_equal(fgetline, cookie, getexline))
+ msg_didout = TRUE;
+ if (fgetline == NULL || (next_cmdline = fgetline(':', cookie,
+ cstack.cs_idx <
+ 0 ? 0 : (cstack.cs_idx + 1) * 2
+ )) == NULL) {
+ /* Don't call wait_return for aborted command line. The NULL
+ * returned for the end of a sourced file or executed function
+ * doesn't do this. */
+ if (KeyTyped && !(flags & DOCMD_REPEAT))
+ need_wait_return = FALSE;
+ retval = FAIL;
+ break;
+ }
+ used_getline = TRUE;
+
+ /*
+ * Keep the first typed line. Clear it when more lines are typed.
+ */
+ if (flags & DOCMD_KEEPLINE) {
+ vim_free(repeat_cmdline);
+ if (count == 0)
+ repeat_cmdline = vim_strsave(next_cmdline);
+ else
+ repeat_cmdline = NULL;
+ }
+ }
+ /* 3. Make a copy of the command so we can mess with it. */
+ else if (cmdline_copy == NULL) {
+ next_cmdline = vim_strsave(next_cmdline);
+ if (next_cmdline == NULL) {
+ EMSG(_(e_outofmem));
+ retval = FAIL;
+ break;
+ }
+ }
+ cmdline_copy = next_cmdline;
+
+ /*
+ * Save the current line when inside a ":while" or ":for", and when
+ * the command looks like a ":while" or ":for", because we may need it
+ * later. When there is a '|' and another command, it is stored
+ * separately, because we need to be able to jump back to it from an
+ * :endwhile/:endfor.
+ */
+ if (current_line == lines_ga.ga_len
+ && (cstack.cs_looplevel || has_loop_cmd(next_cmdline))) {
+ if (store_loop_line(&lines_ga, next_cmdline) == FAIL) {
+ retval = FAIL;
+ break;
+ }
+ }
+ did_endif = FALSE;
+
+ if (count++ == 0) {
+ /*
+ * All output from the commands is put below each other, without
+ * waiting for a return. Don't do this when executing commands
+ * from a script or when being called recursive (e.g. for ":e
+ * +command file").
+ */
+ if (!(flags & DOCMD_NOWAIT) && !recursive) {
+ msg_didout_before_start = msg_didout;
+ msg_didany = FALSE; /* no output yet */
+ msg_start();
+ msg_scroll = TRUE; /* put messages below each other */
+ ++no_wait_return; /* don't wait for return until finished */
+ ++RedrawingDisabled;
+ did_inc = TRUE;
+ }
+ }
+
+ if (p_verbose >= 15 && sourcing_name != NULL) {
+ ++no_wait_return;
+ verbose_enter_scroll();
+
+ smsg((char_u *)_("line %ld: %s"),
+ (long)sourcing_lnum, cmdline_copy);
+ if (msg_silent == 0)
+ msg_puts((char_u *)"\n"); /* don't overwrite this */
+
+ verbose_leave_scroll();
+ --no_wait_return;
+ }
+
+ /*
+ * 2. Execute one '|' separated command.
+ * 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;
+
+ if (cmd_cookie == (void *)&cmd_loop_cookie)
+ /* Use "current_line" from "cmd_loop_cookie", it may have been
+ * incremented when defining a function. */
+ current_line = cmd_loop_cookie.current_line;
+
+ if (next_cmdline == NULL) {
+ vim_free(cmdline_copy);
+ cmdline_copy = NULL;
+ /*
+ * If the command was typed, remember it for the ':' register.
+ * Do this AFTER executing the command to make :@: work.
+ */
+ if (getline_equal(fgetline, cookie, getexline)
+ && new_last_cmdline != NULL) {
+ vim_free(last_cmdline);
+ last_cmdline = new_last_cmdline;
+ new_last_cmdline = NULL;
+ }
+ } else {
+ /* need to copy the command after the '|' to cmdline_copy, for the
+ * next do_one_cmd() */
+ STRMOVE(cmdline_copy, next_cmdline);
+ next_cmdline = cmdline_copy;
+ }
+
+
+ /* reset did_emsg for a function that is not aborted by an error */
+ if (did_emsg && !force_abort
+ && getline_equal(fgetline, cookie, get_func_line)
+ && !func_has_abort(real_cookie))
+ did_emsg = FALSE;
+
+ if (cstack.cs_looplevel > 0) {
+ ++current_line;
+
+ /*
+ * An ":endwhile", ":endfor" and ":continue" is handled here.
+ * If we were executing commands, jump back to the ":while" or
+ * ":for".
+ * If we were not executing commands, decrement cs_looplevel.
+ */
+ if (cstack.cs_lflags & (CSL_HAD_CONT | CSL_HAD_ENDLOOP)) {
+ cstack.cs_lflags &= ~(CSL_HAD_CONT | CSL_HAD_ENDLOOP);
+
+ /* Jump back to the matching ":while" or ":for". Be careful
+ * 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
+ && cstack.cs_idx >= 0
+ && (cstack.cs_flags[cstack.cs_idx]
+ & (CSF_WHILE | CSF_FOR))
+ && cstack.cs_line[cstack.cs_idx] >= 0
+ && (cstack.cs_flags[cstack.cs_idx] & CSF_ACTIVE)) {
+ current_line = cstack.cs_line[cstack.cs_idx];
+ /* remember we jumped there */
+ cstack.cs_lflags |= CSL_HAD_LOOP;
+ line_breakcheck(); /* check if CTRL-C typed */
+
+ /* Check for the next breakpoint at or after the ":while"
+ * or ":for". */
+ if (breakpoint != NULL) {
+ *breakpoint = dbg_find_breakpoint(
+ getline_equal(fgetline, cookie, getsourceline),
+ fname,
+ ((wcmd_T *)lines_ga.ga_data)[current_line].lnum-1);
+ *dbg_tick = debug_tick;
+ }
+ } else {
+ /* can only get here with ":endwhile" or ":endfor" */
+ if (cstack.cs_idx >= 0)
+ rewind_conditionals(&cstack, cstack.cs_idx - 1,
+ CSF_WHILE | CSF_FOR, &cstack.cs_looplevel);
+ }
+ }
+ /*
+ * For a ":while" or ":for" we need to remember the line number.
+ */
+ else if (cstack.cs_lflags & CSL_HAD_LOOP) {
+ cstack.cs_lflags &= ~CSL_HAD_LOOP;
+ cstack.cs_line[cstack.cs_idx] = current_line - 1;
+ }
+ }
+
+ /*
+ * When not inside any ":while" loop, clear remembered lines.
+ */
+ if (cstack.cs_looplevel == 0) {
+ if (lines_ga.ga_len > 0) {
+ sourcing_lnum =
+ ((wcmd_T *)lines_ga.ga_data)[lines_ga.ga_len - 1].lnum;
+ free_cmdlines(&lines_ga);
+ }
+ current_line = 0;
+ }
+
+ /*
+ * A ":finally" makes did_emsg, got_int, and did_throw 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
+ * ":endfor" was detected by the ":finally" itself.
+ */
+ 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;
+ cstack.cs_flags[cstack.cs_idx] |= CSF_ACTIVE | CSF_FINALLY;
+ }
+
+ /* Update global "trylevel" for recursive calls to do_cmdline() from
+ * 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;
+
+ /* Convert an interrupt to an exception if appropriate. */
+ (void)do_intthrow(&cstack);
+
+ }
+ /*
+ * Continue executing command lines when:
+ * - no CTRL-C typed, no aborting error, no exception thrown or try
+ * conditionals need to be checked for executing finally clauses or
+ * catching an interrupt exception
+ * - didn't get an error message or lines are not typed
+ * - 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
+ )
+ && !(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
+ * the :endtry to be missed. */
+ && (cstack.cs_trylevel == 0 || did_emsg_syntax)
+ && used_getline
+ && (getline_equal(fgetline, cookie, getexmodeline)
+ || getline_equal(fgetline, cookie, getexline)))
+ && (next_cmdline != NULL
+ || cstack.cs_idx >= 0
+ || (flags & DOCMD_REPEAT)));
+
+ vim_free(cmdline_copy);
+ did_emsg_syntax = FALSE;
+ free_cmdlines(&lines_ga);
+ ga_clear(&lines_ga);
+
+ if (cstack.cs_idx >= 0) {
+ /*
+ * If a sourced file or executed function ran to its end, report the
+ * unclosed conditional.
+ */
+ if (!got_int && !did_throw
+ && ((getline_equal(fgetline, cookie, getsourceline)
+ && !source_finished(fgetline, cookie))
+ || (getline_equal(fgetline, cookie, get_func_line)
+ && !func_has_ended(real_cookie)))) {
+ if (cstack.cs_flags[cstack.cs_idx] & CSF_TRY)
+ EMSG(_(e_endtry));
+ else if (cstack.cs_flags[cstack.cs_idx] & CSF_WHILE)
+ EMSG(_(e_endwhile));
+ else if (cstack.cs_flags[cstack.cs_idx] & CSF_FOR)
+ EMSG(_(e_endfor));
+ else
+ EMSG(_(e_endif));
+ }
+
+ /*
+ * Reset "trylevel" in case of a ":finish" or ":return" or a missing
+ * ":endtry" in a sourced file or executed function. If the try
+ * conditional is in its finally clause, ignore anything pending.
+ * If it is in a catch clause, finish the caught exception.
+ * Also cleanup any "cs_forinfo" structures.
+ */
+ do {
+ int idx = cleanup_conditionals(&cstack, 0, TRUE);
+
+ if (idx >= 0)
+ --idx; /* remove try block not in its finally clause */
+ rewind_conditionals(&cstack, idx, CSF_WHILE | CSF_FOR,
+ &cstack.cs_looplevel);
+ } while (cstack.cs_idx >= 0);
+ trylevel = initial_trylevel;
+ }
+
+ /* If a missing ":endtry", ":endwhile", ":endfor", or ":endif" or a memory
+ * lack was reported above and the error message is to be converted to an
+ * exception, do this now after rewinding the cstack. */
+ do_errthrow(&cstack, getline_equal(fgetline, cookie, get_func_line)
+ ? (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;
+ int saved_sourcing_lnum;
+ struct msglist *messages = NULL, *next;
+
+ /*
+ * If the uncaught exception is a user exception, report it as an
+ * error. If it is an error exception, display the saved error
+ * message now. For an interrupt exception, do nothing; the
+ * interrupt message is given elsewhere.
+ */
+ switch (current_exception->type) {
+ case ET_USER:
+ vim_snprintf((char *)IObuff, IOSIZE,
+ _("E605: Exception not caught: %s"),
+ current_exception->value);
+ p = vim_strsave(IObuff);
+ break;
+ case ET_ERROR:
+ messages = current_exception->messages;
+ current_exception->messages = NULL;
+ break;
+ case ET_INTERRUPT:
+ break;
+ default:
+ p = vim_strsave((char_u *)_(e_internal));
+ }
+
+ saved_sourcing_name = sourcing_name;
+ saved_sourcing_lnum = sourcing_lnum;
+ sourcing_name = current_exception->throw_name;
+ sourcing_lnum = current_exception->throw_lnum;
+ current_exception->throw_name = NULL;
+
+ discard_current_exception(); /* uses IObuff if 'verbose' */
+ suppress_errthrow = TRUE;
+ force_abort = TRUE;
+
+ if (messages != NULL) {
+ do {
+ next = messages->next;
+ emsg(messages->msg);
+ vim_free(messages->msg);
+ vim_free(messages);
+ messages = next;
+ } while (messages != NULL);
+ } else if (p != NULL) {
+ emsg(p);
+ vim_free(p);
+ }
+ vim_free(sourcing_name);
+ sourcing_name = saved_sourcing_name;
+ sourcing_lnum = saved_sourcing_lnum;
+ }
+ /*
+ * On an interrupt or an aborting error not converted to an exception,
+ * disable the conversion of errors to exceptions. (Interrupts are not
+ * converted any more, here.) This enables also the interrupt message
+ * when force_abort is set and did_emsg unset in case of an interrupt
+ * from a finally clause after an error.
+ */
+ else if (got_int || (did_emsg && force_abort))
+ 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;
+ 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;
+ } else {
+ /* When leaving a function, reduce nesting level. */
+ if (getline_equal(fgetline, cookie, get_func_line))
+ --ex_nesting_level;
+ /*
+ * Go to debug mode when returning from a function in which we are
+ * single-stepping.
+ */
+ if ((getline_equal(fgetline, cookie, getsourceline)
+ || getline_equal(fgetline, cookie, get_func_line))
+ && ex_nesting_level + 1 <= debug_break_level)
+ do_debug(getline_equal(fgetline, cookie, getsourceline)
+ ? (char_u *)_("End of sourced file")
+ : (char_u *)_("End of function"));
+ }
+
+ /*
+ * Restore the exception environment (done after returning from the
+ * debugger).
+ */
+ if (flags & DOCMD_EXCRESET)
+ restore_dbg_stuff(&debug_saved);
+
+ msg_list = saved_msg_list;
+
+ /*
+ * If there was too much output to fit on the command line, ask the user to
+ * hit return before redrawing the screen. With the ":global" command we do
+ * this only once after the command is finished.
+ */
+ if (did_inc) {
+ --RedrawingDisabled;
+ --no_wait_return;
+ msg_scroll = FALSE;
+
+ /*
+ * When just finished an ":if"-":else" which was typed, no need to
+ * wait for hit-return. Also for an error situation.
+ */
+ if (retval == FAIL
+ || (did_endif && KeyTyped && !did_emsg)
+ ) {
+ need_wait_return = FALSE;
+ msg_didany = FALSE; /* don't wait when restarting edit */
+ } else if (need_wait_return) {
+ /*
+ * The msg_start() above clears msg_didout. The wait_return we do
+ * here should not overwrite the command that may be shown before
+ * doing that.
+ */
+ msg_didout |= msg_didout_before_start;
+ wait_return(FALSE);
+ }
+ }
+
+ did_endif = FALSE; /* in case do_cmdline used recursively */
+
+ --call_depth;
+ return retval;
+}
+
+/*
+ * Obtain a line when inside a ":while" or ":for" loop.
+ */
+static char_u * get_loop_line(c, cookie, indent)
+int c;
+void *cookie;
+int indent;
+{
+ struct loop_cookie *cp = (struct loop_cookie *)cookie;
+ wcmd_T *wp;
+ char_u *line;
+
+ if (cp->current_line + 1 >= cp->lines_gap->ga_len) {
+ if (cp->repeating)
+ return NULL; /* trying to read past ":endwhile"/":endfor" */
+
+ /* First time inside the ":while"/":for": get line normally. */
+ if (cp->getline == NULL)
+ line = getcmdline(c, 0L, indent);
+ else
+ line = cp->getline(c, cp->cookie, indent);
+ if (line != NULL && store_loop_line(cp->lines_gap, line) == OK)
+ ++cp->current_line;
+
+ return 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);
+}
+
+/*
+ * Store a line in "gap" so that a ":while" loop can execute it again.
+ */
+static int store_loop_line(gap, line)
+garray_T *gap;
+char_u *line;
+{
+ if (ga_grow(gap, 1) == FAIL)
+ return FAIL;
+ ((wcmd_T *)(gap->ga_data))[gap->ga_len].line = vim_strsave(line);
+ ((wcmd_T *)(gap->ga_data))[gap->ga_len].lnum = sourcing_lnum;
+ ++gap->ga_len;
+ return OK;
+}
+
+/*
+ * Free the lines stored for a ":while" or ":for" loop.
+ */
+static void free_cmdlines(gap)
+garray_T *gap;
+{
+ while (gap->ga_len > 0) {
+ vim_free(((wcmd_T *)(gap->ga_data))[gap->ga_len - 1].line);
+ --gap->ga_len;
+ }
+}
+
+/*
+ * If "fgetline" is get_loop_line(), return TRUE if the getline it uses equals
+ * "func". * Otherwise return TRUE when "fgetline" equals "func".
+ */
+int getline_equal(fgetline, cookie, func)
+char_u *(*fgetline)__ARGS((int, void *, int));
+void *cookie UNUSED; /* argument for fgetline() */
+char_u *(*func)__ARGS((int, void *, int));
+{
+ char_u *(*gp)__ARGS((int, void *, int));
+ struct loop_cookie *cp;
+
+ /* When "fgetline" is "get_loop_line()" use the "cookie" to find the
+ * function that's originally used to obtain the lines. This may be
+ * nested several levels. */
+ gp = fgetline;
+ cp = (struct loop_cookie *)cookie;
+ while (gp == get_loop_line) {
+ gp = cp->getline;
+ cp = cp->cookie;
+ }
+ return gp == func;
+}
+
+/*
+ * If "fgetline" is get_loop_line(), return the cookie used by the original
+ * getline function. Otherwise return "cookie".
+ */
+void * getline_cookie(fgetline, cookie)
+char_u *(*fgetline)__ARGS((int, void *, int)) UNUSED;
+void *cookie; /* argument for fgetline() */
+{
+ char_u *(*gp)__ARGS((int, void *, int));
+ struct loop_cookie *cp;
+
+ /* When "fgetline" is "get_loop_line()" use the "cookie" to find the
+ * cookie that's originally used to obtain the lines. This may be nested
+ * several levels. */
+ gp = fgetline;
+ cp = (struct loop_cookie *)cookie;
+ while (gp == get_loop_line) {
+ gp = cp->getline;
+ cp = cp->cookie;
+ }
+ return cp;
+}
+
+/*
+ * Execute one Ex command.
+ *
+ * If 'sourcing' is TRUE, the command will be included in the error message.
+ *
+ * 1. skip comment lines and leading space
+ * 2. handle command modifiers
+ * 3. parse range
+ * 4. parse command
+ * 5. parse arguments
+ * 6. switch on command name
+ *
+ * Note: "fgetline" can be NULL.
+ *
+ * This function may be called recursively!
+ */
+static char_u * do_one_cmd(cmdlinep, sourcing,
+ cstack,
+ fgetline, cookie)
+char_u **cmdlinep;
+int sourcing;
+struct condstack *cstack;
+char_u *(*fgetline)__ARGS((int, void *, int));
+void *cookie; /* argument for fgetline() */
+{
+ char_u *p;
+ linenr_T lnum;
+ long n;
+ char_u *errormsg = NULL; /* error message */
+ exarg_T ea; /* Ex command arguments */
+ long verbose_save = -1;
+ int save_msg_scroll = msg_scroll;
+ int save_msg_silent = -1;
+ int did_esilent = 0;
+#ifdef HAVE_SANDBOX
+ int did_sandbox = FALSE;
+#endif
+ cmdmod_T save_cmdmod;
+ int ni; /* set when Not Implemented */
+
+ vim_memset(&ea, 0, sizeof(ea));
+ ea.line1 = 1;
+ ea.line2 = 1;
+ ++ex_nesting_level;
+
+ /* When the last file has not been edited :q has to be typed twice. */
+ if (quitmore
+ /* avoid that a function call in 'statusline' does this */
+ && !getline_equal(fgetline, cookie, get_func_line)
+ /* avoid that an autocommand, e.g. QuitPre, does this */
+ && !getline_equal(fgetline, cookie, getnextac)
+ )
+ --quitmore;
+
+ /*
+ * Reset browse, confirm, etc.. They are restored when returning, for
+ * recursive calls.
+ */
+ save_cmdmod = cmdmod;
+ vim_memset(&cmdmod, 0, sizeof(cmdmod));
+
+ /* "#!anything" is handled like a comment. */
+ if ((*cmdlinep)[0] == '#' && (*cmdlinep)[1] == '!')
+ goto doend;
+
+ /*
+ * Repeat until no more command modifiers are found.
+ */
+ ea.cmd = *cmdlinep;
+ for (;; ) {
+ /*
+ * 1. skip comment lines and leading white space and colons
+ */
+ while (*ea.cmd == ' ' || *ea.cmd == '\t' || *ea.cmd == ':')
+ ++ea.cmd;
+
+ /* in ex mode, an empty line works like :+ */
+ if (*ea.cmd == NUL && exmode_active
+ && (getline_equal(fgetline, cookie, getexmodeline)
+ || getline_equal(fgetline, cookie, getexline))
+ && curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count) {
+ ea.cmd = (char_u *)"+";
+ ex_pressedreturn = TRUE;
+ }
+
+ /* ignore comment and empty lines */
+ if (*ea.cmd == '"')
+ goto doend;
+ if (*ea.cmd == NUL) {
+ ex_pressedreturn = TRUE;
+ goto doend;
+ }
+
+ /*
+ * 2. handle command modifiers.
+ */
+ p = ea.cmd;
+ if (VIM_ISDIGIT(*ea.cmd))
+ p = skipwhite(skipdigits(ea.cmd));
+ switch (*p) {
+ /* When adding an entry, also modify cmd_exists(). */
+ case 'a': if (!checkforcmd(&ea.cmd, "aboveleft", 3))
+ break;
+ cmdmod.split |= WSP_ABOVE;
+ continue;
+
+ case 'b': if (checkforcmd(&ea.cmd, "belowright", 3)) {
+ cmdmod.split |= WSP_BELOW;
+ continue;
+ }
+ if (checkforcmd(&ea.cmd, "browse", 3)) {
+ continue;
+ }
+ if (!checkforcmd(&ea.cmd, "botright", 2))
+ break;
+ cmdmod.split |= WSP_BOT;
+ continue;
+
+ case 'c': if (!checkforcmd(&ea.cmd, "confirm", 4))
+ break;
+ cmdmod.confirm = TRUE;
+ continue;
+
+ case 'k': if (checkforcmd(&ea.cmd, "keepmarks", 3)) {
+ cmdmod.keepmarks = TRUE;
+ continue;
+ }
+ if (checkforcmd(&ea.cmd, "keepalt", 5)) {
+ cmdmod.keepalt = TRUE;
+ continue;
+ }
+ if (checkforcmd(&ea.cmd, "keeppatterns", 5)) {
+ cmdmod.keeppatterns = TRUE;
+ continue;
+ }
+ if (!checkforcmd(&ea.cmd, "keepjumps", 5))
+ break;
+ cmdmod.keepjumps = TRUE;
+ 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;
+ continue;
+
+ case 'l': if (checkforcmd(&ea.cmd, "lockmarks", 3)) {
+ cmdmod.lockmarks = TRUE;
+ continue;
+ }
+
+ if (!checkforcmd(&ea.cmd, "leftabove", 5))
+ break;
+ cmdmod.split |= WSP_ABOVE;
+ continue;
+
+ case 'n': if (!checkforcmd(&ea.cmd, "noautocmd", 3))
+ break;
+ if (cmdmod.save_ei == NULL) {
+ /* Set 'eventignore' to "all". Restore the
+ * existing option value later. */
+ cmdmod.save_ei = vim_strsave(p_ei);
+ set_string_option_direct((char_u *)"ei", -1,
+ (char_u *)"all", OPT_FREE, SID_NONE);
+ }
+ continue;
+
+ case 'r': if (!checkforcmd(&ea.cmd, "rightbelow", 6))
+ break;
+ cmdmod.split |= WSP_BELOW;
+ continue;
+
+ case 's': if (checkforcmd(&ea.cmd, "sandbox", 3)) {
+#ifdef HAVE_SANDBOX
+ if (!did_sandbox)
+ ++sandbox;
+ did_sandbox = TRUE;
+#endif
+ continue;
+ }
+ if (!checkforcmd(&ea.cmd, "silent", 3))
+ break;
+ if (save_msg_silent == -1)
+ save_msg_silent = msg_silent;
+ ++msg_silent;
+ if (*ea.cmd == '!' && !vim_iswhite(ea.cmd[-1])) {
+ /* ":silent!", but not "silent !cmd" */
+ ea.cmd = skipwhite(ea.cmd + 1);
+ ++emsg_silent;
+ ++did_esilent;
+ }
+ continue;
+
+ case 't': if (checkforcmd(&p, "tab", 3)) {
+ if (vim_isdigit(*ea.cmd))
+ cmdmod.tab = atoi((char *)ea.cmd) + 1;
+ else
+ cmdmod.tab = tabpage_index(curtab) + 1;
+ ea.cmd = p;
+ continue;
+ }
+ if (!checkforcmd(&ea.cmd, "topleft", 2))
+ break;
+ cmdmod.split |= WSP_TOP;
+ continue;
+
+ case 'u': if (!checkforcmd(&ea.cmd, "unsilent", 3))
+ break;
+ if (save_msg_silent == -1)
+ save_msg_silent = msg_silent;
+ msg_silent = 0;
+ continue;
+
+ case 'v': if (checkforcmd(&ea.cmd, "vertical", 4)) {
+ cmdmod.split |= WSP_VERT;
+ continue;
+ }
+ if (!checkforcmd(&p, "verbose", 4))
+ break;
+ if (verbose_save < 0)
+ verbose_save = p_verbose;
+ if (vim_isdigit(*ea.cmd))
+ p_verbose = atoi((char *)ea.cmd);
+ else
+ p_verbose = 1;
+ ea.cmd = p;
+ continue;
+ }
+ break;
+ }
+
+ ea.skip = did_emsg || got_int || did_throw || (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) {
+ if (getline_equal(fgetline, cookie, get_func_line))
+ func_line_exec(getline_cookie(fgetline, cookie));
+ else if (getline_equal(fgetline, cookie, getsourceline))
+ script_line_exec();
+ }
+
+ /* May go to debug mode. If this happens and the ">quit" debug command is
+ * used, throw an interrupt exception and skip the next command. */
+ dbg_check_breakpoint(&ea);
+ if (!ea.skip && got_int) {
+ ea.skip = TRUE;
+ (void)do_intthrow(cstack);
+ }
+
+ /*
+ * 3. parse a range specifier of the form: addr [,addr] [;addr] ..
+ *
+ * where 'addr' is:
+ *
+ * % (entire file)
+ * $ [+-NUM]
+ * 'x [+-NUM] (where x denotes a currently defined mark)
+ * . [+-NUM]
+ * [+-NUM]..
+ * NUM
+ *
+ * The ea.cmd pointer is updated to point to the first character following the
+ * range spec. If an initial address is found, but no second, the upper bound
+ * is equal to the lower.
+ */
+
+ /* repeat for all ',' or ';' separated addresses */
+ for (;; ) {
+ ea.line1 = ea.line2;
+ ea.line2 = curwin->w_cursor.lnum; /* default is current line number */
+ ea.cmd = skipwhite(ea.cmd);
+ lnum = get_address(&ea.cmd, ea.skip, ea.addr_count == 0);
+ if (ea.cmd == NULL) /* error detected */
+ goto doend;
+ if (lnum == MAXLNUM) {
+ if (*ea.cmd == '%') { /* '%' - all lines */
+ ++ea.cmd;
+ ea.line1 = 1;
+ ea.line2 = curbuf->b_ml.ml_line_count;
+ ++ea.addr_count;
+ }
+ /* '*' - visual area */
+ else if (*ea.cmd == '*' && vim_strchr(p_cpo, CPO_STAR) == NULL) {
+ pos_T *fp;
+
+ ++ea.cmd;
+ if (!ea.skip) {
+ fp = getmark('<', FALSE);
+ if (check_mark(fp) == FAIL)
+ goto doend;
+ ea.line1 = fp->lnum;
+ fp = getmark('>', FALSE);
+ if (check_mark(fp) == FAIL)
+ goto doend;
+ ea.line2 = fp->lnum;
+ ++ea.addr_count;
+ }
+ }
+ } else
+ ea.line2 = lnum;
+ ea.addr_count++;
+
+ if (*ea.cmd == ';') {
+ if (!ea.skip)
+ curwin->w_cursor.lnum = ea.line2;
+ } else if (*ea.cmd != ',')
+ break;
+ ++ea.cmd;
+ }
+
+ /* One address given: set start and end lines */
+ if (ea.addr_count == 1) {
+ ea.line1 = ea.line2;
+ /* ... but only implicit: really no address given */
+ if (lnum == MAXLNUM)
+ ea.addr_count = 0;
+ }
+
+ /* Don't leave the cursor on an illegal line (caused by ';') */
+ check_cursor_lnum();
+
+ /*
+ * 4. parse command
+ */
+
+ /*
+ * Skip ':' and any white space
+ */
+ ea.cmd = skipwhite(ea.cmd);
+ while (*ea.cmd == ':')
+ ea.cmd = skipwhite(ea.cmd + 1);
+
+ /*
+ * If we got a line, but no command, then go to the line.
+ * If we find a '|' or '\n' we set ea.nextcmd.
+ */
+ if (*ea.cmd == NUL || *ea.cmd == '"' ||
+ (ea.nextcmd = check_nextcmd(ea.cmd)) != NULL) {
+ /*
+ * strange vi behaviour:
+ * ":3" jumps to line 3
+ * ":3|..." prints line 3
+ * ":|" prints current line
+ */
+ if (ea.skip) /* skip this if inside :if */
+ goto doend;
+ if (*ea.cmd == '|' || (exmode_active && ea.line1 != ea.line2)) {
+ ea.cmdidx = CMD_print;
+ ea.argt = RANGE+COUNT+TRLBAR;
+ if ((errormsg = invalid_range(&ea)) == NULL) {
+ correct_range(&ea);
+ ex_print(&ea);
+ }
+ } else if (ea.addr_count != 0) {
+ if (ea.line2 > curbuf->b_ml.ml_line_count) {
+ /* With '-' in 'cpoptions' a line number past the file is an
+ * error, otherwise put it at the end of the file. */
+ if (vim_strchr(p_cpo, CPO_MINUS) != NULL)
+ ea.line2 = -1;
+ else
+ ea.line2 = curbuf->b_ml.ml_line_count;
+ }
+
+ if (ea.line2 < 0)
+ errormsg = (char_u *)_(e_invrange);
+ else {
+ if (ea.line2 == 0)
+ curwin->w_cursor.lnum = 1;
+ else
+ curwin->w_cursor.lnum = ea.line2;
+ beginline(BL_SOL | BL_FIX);
+ }
+ }
+ goto doend;
+ }
+
+ /* Find the command and let "p" point to after it. */
+ p = find_command(&ea, NULL);
+
+ if (p == NULL) {
+ if (!ea.skip)
+ 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;
+ }
+ if (ea.cmdidx == CMD_SIZE) {
+ if (!ea.skip) {
+ STRCPY(IObuff, _("E492: Not an editor command"));
+ if (!sourcing)
+ append_command(*cmdlinep);
+ errormsg = IObuff;
+ did_emsg_syntax = TRUE;
+ }
+ goto doend;
+ }
+
+ ni = (
+ !USER_CMDIDX(ea.cmdidx) &&
+ (cmdnames[ea.cmdidx].cmd_func == ex_ni
+#ifdef HAVE_EX_SCRIPT_NI
+ || cmdnames[ea.cmdidx].cmd_func == ex_script_ni
+#endif
+ ));
+
+
+ /* forced commands */
+ if (*p == '!' && ea.cmdidx != CMD_substitute
+ && ea.cmdidx != CMD_smagic && ea.cmdidx != CMD_snomagic) {
+ ++p;
+ ea.forceit = TRUE;
+ } else
+ ea.forceit = FALSE;
+
+ /*
+ * 5. parse arguments
+ */
+ if (!USER_CMDIDX(ea.cmdidx))
+ ea.argt = (long)cmdnames[(int)ea.cmdidx].cmd_argt;
+
+ if (!ea.skip) {
+#ifdef HAVE_SANDBOX
+ if (sandbox != 0 && !(ea.argt & SBOXOK)) {
+ /* Command not allowed in sandbox. */
+ errormsg = (char_u *)_(e_sandbox);
+ goto doend;
+ }
+#endif
+ if (!curbuf->b_p_ma && (ea.argt & MODIFY)) {
+ /* Command not allowed in non-'modifiable' buffer */
+ errormsg = (char_u *)_(e_modifiable);
+ goto doend;
+ }
+
+ if (text_locked() && !(ea.argt & CMDWIN)
+ && !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);
+ goto doend;
+ }
+ /* Disallow editing another buffer when "curbuf_lock" is set.
+ * Do allow ":edit" (check for argument later).
+ * Do allow ":checktime" (it's postponed). */
+ if (!(ea.argt & CMDWIN)
+ && ea.cmdidx != CMD_edit
+ && ea.cmdidx != CMD_checktime
+ && !USER_CMDIDX(ea.cmdidx)
+ && curbuf_locked())
+ goto doend;
+
+ if (!ni && !(ea.argt & RANGE) && ea.addr_count > 0) {
+ /* no range allowed */
+ errormsg = (char_u *)_(e_norange);
+ goto doend;
+ }
+ }
+
+ if (!ni && !(ea.argt & BANG) && ea.forceit) { /* no <!> allowed */
+ errormsg = (char_u *)_(e_nobang);
+ goto doend;
+ }
+
+ /*
+ * Don't complain about the range if it is not used
+ * (could happen if line_count is accidentally set to 0).
+ */
+ if (!ea.skip && !ni) {
+ /*
+ * If the range is backwards, ask for confirmation and, if given, swap
+ * ea.line1 & ea.line2 so it's forwards again.
+ * When global command is busy, don't ask, will fail below.
+ */
+ if (!global_busy && ea.line1 > ea.line2) {
+ if (msg_silent == 0) {
+ if (sourcing || exmode_active) {
+ errormsg = (char_u *)_("E493: Backwards range given");
+ goto doend;
+ }
+ if (ask_yesno((char_u *)
+ _("Backwards range given, OK to swap"), FALSE) != 'y')
+ goto doend;
+ }
+ lnum = ea.line1;
+ ea.line1 = ea.line2;
+ ea.line2 = lnum;
+ }
+ if ((errormsg = invalid_range(&ea)) != NULL)
+ goto doend;
+ }
+
+ if ((ea.argt & NOTADR) && ea.addr_count == 0) /* default is 1, not cursor */
+ ea.line2 = 1;
+
+ correct_range(&ea);
+
+ if (((ea.argt & WHOLEFOLD) || ea.addr_count >= 2) && !global_busy) {
+ /* Put the first line at the start of a closed fold, put the last line
+ * at the end of a closed fold. */
+ (void)hasFolding(ea.line1, &ea.line1, NULL);
+ (void)hasFolding(ea.line2, NULL, &ea.line2);
+ }
+
+ /*
+ * For the ":make" and ":grep" commands we insert the 'makeprg'/'grepprg'
+ * option here, so things like % get expanded.
+ */
+ p = replace_makeprg(&ea, p, cmdlinep);
+ if (p == NULL)
+ goto doend;
+
+ /*
+ * Skip to start of argument.
+ * Don't do this for the ":!" command, because ":!! -l" needs the space.
+ */
+ if (ea.cmdidx == CMD_bang)
+ ea.arg = p;
+ else
+ ea.arg = skipwhite(p);
+
+ /*
+ * Check for "++opt=val" argument.
+ * Must be first, allow ":w ++enc=utf8 !cmd"
+ */
+ if (ea.argt & ARGOPT)
+ while (ea.arg[0] == '+' && ea.arg[1] == '+')
+ if (getargopt(&ea) == FAIL && !ni) {
+ errormsg = (char_u *)_(e_invarg);
+ goto doend;
+ }
+
+ if (ea.cmdidx == CMD_write || ea.cmdidx == CMD_update) {
+ if (*ea.arg == '>') { /* append */
+ if (*++ea.arg != '>') { /* typed wrong */
+ errormsg = (char_u *)_("E494: Use w or w>>");
+ goto doend;
+ }
+ ea.arg = skipwhite(ea.arg + 1);
+ ea.append = TRUE;
+ } else if (*ea.arg == '!' && ea.cmdidx == CMD_write) { /* :w !filter */
+ ++ea.arg;
+ ea.usefilter = TRUE;
+ }
+ }
+
+ if (ea.cmdidx == CMD_read) {
+ if (ea.forceit) {
+ ea.usefilter = TRUE; /* :r! filter if ea.forceit */
+ ea.forceit = FALSE;
+ } else if (*ea.arg == '!') { /* :r !filter */
+ ++ea.arg;
+ ea.usefilter = TRUE;
+ }
+ }
+
+ if (ea.cmdidx == CMD_lshift || ea.cmdidx == CMD_rshift) {
+ ea.amount = 1;
+ while (*ea.arg == *ea.cmd) { /* count number of '>' or '<' */
+ ++ea.arg;
+ ++ea.amount;
+ }
+ ea.arg = skipwhite(ea.arg);
+ }
+
+ /*
+ * Check for "+command" argument, before checking for next command.
+ * Don't do this for ":read !cmd" and ":write !cmd".
+ */
+ if ((ea.argt & EDITCMD) && !ea.usefilter)
+ ea.do_ecmd_cmd = getargcmd(&ea.arg);
+
+ /*
+ * Check for '|' to separate commands and '"' to start comments.
+ * Don't do this for ":read !cmd" and ":write !cmd".
+ */
+ if ((ea.argt & TRLBAR) && !ea.usefilter)
+ separate_nextcmd(&ea);
+
+ /*
+ * Check for <newline> to end a shell command.
+ * Also do this for ":read !cmd", ":write !cmd" and ":global".
+ * Any others?
+ */
+ else if (ea.cmdidx == CMD_bang
+ || ea.cmdidx == CMD_global
+ || ea.cmdidx == CMD_vglobal
+ || ea.usefilter) {
+ for (p = ea.arg; *p; ++p) {
+ /* Remove one backslash before a newline, so that it's possible to
+ * pass a newline to the shell and also a newline that is preceded
+ * with a backslash. This makes it impossible to end a shell
+ * command in a backslash, but that doesn't appear useful.
+ * Halving the number of backslashes is incompatible with previous
+ * versions. */
+ if (*p == '\\' && p[1] == '\n')
+ STRMOVE(p, p + 1);
+ else if (*p == '\n') {
+ ea.nextcmd = p + 1;
+ *p = NUL;
+ break;
+ }
+ }
+ }
+
+ if ((ea.argt & DFLALL) && ea.addr_count == 0) {
+ ea.line1 = 1;
+ ea.line2 = curbuf->b_ml.ml_line_count;
+ }
+
+ /* accept numbered register only when no count allowed (:put) */
+ if ( (ea.argt & REGSTR)
+ && *ea.arg != NUL
+ /* Do not allow register = for user commands */
+ && (!USER_CMDIDX(ea.cmdidx) || *ea.arg != '=')
+ && !((ea.argt & COUNT) && VIM_ISDIGIT(*ea.arg))) {
+ /* check these explicitly for a more specific error message */
+ if (*ea.arg == '*' || *ea.arg == '+') {
+ errormsg = (char_u *)_(e_invalidreg);
+ goto doend;
+ }
+ if (
+ valid_yank_reg(*ea.arg, (ea.cmdidx != CMD_put
+ && USER_CMDIDX(ea.cmdidx)))
+ ) {
+ ea.regname = *ea.arg++;
+ /* for '=' register: accept the rest of the line as an expression */
+ if (ea.arg[-1] == '=' && ea.arg[0] != NUL) {
+ set_expr_line(vim_strsave(ea.arg));
+ ea.arg += STRLEN(ea.arg);
+ }
+ ea.arg = skipwhite(ea.arg);
+ }
+ }
+
+ /*
+ * Check for a count. When accepting a BUFNAME, don't use "123foo" as a
+ * count, it's a buffer name.
+ */
+ if ((ea.argt & COUNT) && VIM_ISDIGIT(*ea.arg)
+ && (!(ea.argt & BUFNAME) || *(p = skipdigits(ea.arg)) == NUL
+ || vim_iswhite(*p))) {
+ n = getdigits(&ea.arg);
+ ea.arg = skipwhite(ea.arg);
+ if (n <= 0 && !ni && (ea.argt & ZEROR) == 0) {
+ errormsg = (char_u *)_(e_zerocount);
+ goto doend;
+ }
+ if (ea.argt & NOTADR) { /* e.g. :buffer 2, :sleep 3 */
+ ea.line2 = n;
+ if (ea.addr_count == 0)
+ ea.addr_count = 1;
+ } else {
+ 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)
+ ea.line2 = curbuf->b_ml.ml_line_count;
+ }
+ }
+
+ /*
+ * Check for flags: 'l', 'p' and '#'.
+ */
+ if (ea.argt & EXFLAGS)
+ get_flags(&ea);
+ /* no arguments allowed */
+ if (!ni && !(ea.argt & EXTRA) && *ea.arg != NUL
+ && *ea.arg != '"' && (*ea.arg != '|' || (ea.argt & TRLBAR) == 0)) {
+ errormsg = (char_u *)_(e_trailing);
+ goto doend;
+ }
+
+ if (!ni && (ea.argt & NEEDARG) && *ea.arg == NUL) {
+ errormsg = (char_u *)_(e_argreq);
+ goto doend;
+ }
+
+ /*
+ * Skip the command when it's not going to be executed.
+ * The commands like :if, :endif, etc. always need to be executed.
+ * Also make an exception for commands that handle a trailing command
+ * themselves.
+ */
+ if (ea.skip) {
+ switch (ea.cmdidx) {
+ /* commands that need evaluation */
+ case CMD_while:
+ case CMD_endwhile:
+ case CMD_for:
+ case CMD_endfor:
+ case CMD_if:
+ case CMD_elseif:
+ case CMD_else:
+ case CMD_endif:
+ case CMD_try:
+ case CMD_catch:
+ case CMD_finally:
+ case CMD_endtry:
+ case CMD_function:
+ break;
+
+ /* Commands that handle '|' themselves. Check: A command should
+ * either have the TRLBAR flag, appear in this list or appear in
+ * the list at ":help :bar". */
+ case CMD_aboveleft:
+ case CMD_and:
+ case CMD_belowright:
+ case CMD_botright:
+ case CMD_browse:
+ case CMD_call:
+ case CMD_confirm:
+ case CMD_delfunction:
+ case CMD_djump:
+ case CMD_dlist:
+ case CMD_dsearch:
+ case CMD_dsplit:
+ case CMD_echo:
+ case CMD_echoerr:
+ case CMD_echomsg:
+ case CMD_echon:
+ case CMD_execute:
+ case CMD_help:
+ case CMD_hide:
+ case CMD_ijump:
+ case CMD_ilist:
+ case CMD_isearch:
+ case CMD_isplit:
+ case CMD_keepalt:
+ case CMD_keepjumps:
+ case CMD_keepmarks:
+ case CMD_keeppatterns:
+ case CMD_leftabove:
+ case CMD_let:
+ case CMD_lockmarks:
+ case CMD_lua:
+ case CMD_match:
+ case CMD_mzscheme:
+ case CMD_perl:
+ case CMD_psearch:
+ case CMD_python:
+ case CMD_py3:
+ case CMD_python3:
+ case CMD_return:
+ case CMD_rightbelow:
+ case CMD_ruby:
+ case CMD_silent:
+ case CMD_smagic:
+ case CMD_snomagic:
+ case CMD_substitute:
+ case CMD_syntax:
+ case CMD_tab:
+ case CMD_tcl:
+ case CMD_throw:
+ case CMD_tilde:
+ case CMD_topleft:
+ case CMD_unlet:
+ case CMD_verbose:
+ case CMD_vertical:
+ case CMD_wincmd:
+ break;
+
+ default: goto doend;
+ }
+ }
+
+ if (ea.argt & XFILE) {
+ if (expand_filename(&ea, cmdlinep, &errormsg) == FAIL)
+ goto doend;
+ }
+
+ /*
+ * Accept buffer name. Cannot be used at the same time with a buffer
+ * number. Don't do this for a user command.
+ */
+ if ((ea.argt & BUFNAME) && *ea.arg != NUL && ea.addr_count == 0
+ && !USER_CMDIDX(ea.cmdidx)
+ ) {
+ /*
+ * :bdelete, :bwipeout and :bunload take several arguments, separated
+ * by spaces: find next space (skipping over escaped characters).
+ * The others take one argument: ignore trailing spaces.
+ */
+ if (ea.cmdidx == CMD_bdelete || ea.cmdidx == CMD_bwipeout
+ || ea.cmdidx == CMD_bunload)
+ p = skiptowhite_esc(ea.arg);
+ else {
+ p = ea.arg + STRLEN(ea.arg);
+ while (p > ea.arg && vim_iswhite(p[-1]))
+ --p;
+ }
+ ea.line2 = buflist_findpat(ea.arg, p, (ea.argt & BUFUNL) != 0,
+ FALSE, FALSE);
+ if (ea.line2 < 0) /* failed */
+ goto doend;
+ ea.addr_count = 1;
+ ea.arg = skipwhite(p);
+ }
+
+ /*
+ * 6. switch on command name
+ *
+ * The "ea" structure holds the arguments that can be used.
+ */
+ ea.cmdlinep = cmdlinep;
+ ea.getline = fgetline;
+ ea.cookie = cookie;
+ ea.cstack = cstack;
+
+ if (USER_CMDIDX(ea.cmdidx)) {
+ /*
+ * Execute a user-defined command.
+ */
+ do_ucmd(&ea);
+ } else {
+ /*
+ * Call the function to execute the command.
+ */
+ ea.errmsg = NULL;
+ (cmdnames[ea.cmdidx].cmd_func)(&ea);
+ if (ea.errmsg != NULL)
+ errormsg = (char_u *)_(ea.errmsg);
+ }
+
+ /*
+ * If the command just executed called do_cmdline(), any throw or ":return"
+ * or ":finish" encountered there must also check the cstack of the still
+ * active do_cmdline() that called this do_one_cmd(). Rethrow an uncaught
+ * exception, or reanimate a returned function or finished script file and
+ * return or finish it again.
+ */
+ if (need_rethrow)
+ do_throw(cstack);
+ else if (check_cstack) {
+ if (source_finished(fgetline, cookie))
+ do_finish(&ea, TRUE);
+ else if (getline_equal(fgetline, cookie, get_func_line)
+ && current_func_returned())
+ do_return(&ea, TRUE, FALSE, NULL);
+ }
+ need_rethrow = check_cstack = FALSE;
+
+doend:
+ if (curwin->w_cursor.lnum == 0) /* can happen with zero line number */
+ curwin->w_cursor.lnum = 1;
+
+ if (errormsg != NULL && *errormsg != NUL && !did_emsg) {
+ if (sourcing) {
+ if (errormsg != IObuff) {
+ STRCPY(IObuff, errormsg);
+ errormsg = IObuff;
+ }
+ append_command(*cmdlinep);
+ }
+ emsg(errormsg);
+ }
+ do_errthrow(cstack,
+ (ea.cmdidx != CMD_SIZE
+ && !USER_CMDIDX(ea.cmdidx)
+ ) ? cmdnames[(int)ea.cmdidx].cmd_name : (char_u *)NULL);
+
+ if (verbose_save >= 0)
+ p_verbose = verbose_save;
+ if (cmdmod.save_ei != NULL) {
+ /* Restore 'eventignore' to the value before ":noautocmd". */
+ set_string_option_direct((char_u *)"ei", -1, cmdmod.save_ei,
+ OPT_FREE, SID_NONE);
+ free_string_option(cmdmod.save_ei);
+ }
+
+ cmdmod = save_cmdmod;
+
+ if (save_msg_silent != -1) {
+ /* messages could be enabled for a serious error, need to check if the
+ * counters don't become negative */
+ if (!did_emsg || msg_silent > save_msg_silent)
+ msg_silent = save_msg_silent;
+ emsg_silent -= did_esilent;
+ if (emsg_silent < 0)
+ emsg_silent = 0;
+ /* Restore msg_scroll, it's set by file I/O commands, even when no
+ * message is actually displayed. */
+ msg_scroll = save_msg_scroll;
+
+ /* "silent reg" or "silent echo x" inside "redir" leaves msg_col
+ * somewhere in the line. Put it back in the first column. */
+ if (redirecting())
+ msg_col = 0;
+ }
+
+#ifdef HAVE_SANDBOX
+ if (did_sandbox)
+ --sandbox;
+#endif
+
+ if (ea.nextcmd && *ea.nextcmd == NUL) /* not really a next command */
+ ea.nextcmd = NULL;
+
+ --ex_nesting_level;
+
+ return ea.nextcmd;
+}
+
+/*
+ * Check for an Ex command with optional tail.
+ * If there is a match advance "pp" to the argument and return TRUE.
+ */
+int checkforcmd(pp, cmd, len)
+char_u **pp; /* start of command */
+char *cmd; /* name of command */
+int len; /* required length */
+{
+ int i;
+
+ for (i = 0; cmd[i] != NUL; ++i)
+ if (((char_u *)cmd)[i] != (*pp)[i])
+ break;
+ if (i >= len && !isalpha((*pp)[i])) {
+ *pp = skipwhite(*pp + i);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*
+ * Append "cmd" to the error message in IObuff.
+ * Takes care of limiting the length and handling 0xa0, which would be
+ * invisible otherwise.
+ */
+static void append_command(cmd)
+char_u *cmd;
+{
+ char_u *s = cmd;
+ char_u *d;
+
+ STRCAT(IObuff, ": ");
+ d = IObuff + STRLEN(IObuff);
+ while (*s != NUL && d - IObuff < IOSIZE - 7) {
+ if (
+ enc_utf8 ? (s[0] == 0xc2 && s[1] == 0xa0) :
+ *s == 0xa0) {
+ s +=
+ enc_utf8 ? 2 :
+ 1;
+ STRCPY(d, "<a0>");
+ d += 4;
+ } else
+ MB_COPY_CHAR(s, d);
+ }
+ *d = NUL;
+}
+
+/*
+ * Find an Ex command by its name, either built-in or user.
+ * Start of the name can be found at eap->cmd.
+ * Returns pointer to char after the command name.
+ * "full" is set to TRUE if the whole command name matched.
+ * Returns NULL for an ambiguous user command.
+ */
+static char_u * find_command(eap, full)
+exarg_T *eap;
+int *full UNUSED;
+{
+ int len;
+ char_u *p;
+ int i;
+
+ /*
+ * Isolate the command and search for it in the command table.
+ * Exceptions:
+ * - the 'k' command can directly be followed by any character.
+ * - the 's' command can be followed directly by 'c', 'g', 'i', 'I' or 'r'
+ * but :sre[wind] is another command, as are :scrip[tnames],
+ * :scs[cope], :sim[alt], :sig[ns] and :sil[ent].
+ * - the "d" command can directly be followed by 'l' or 'p' flag.
+ */
+ p = eap->cmd;
+ if (*p == 'k') {
+ eap->cmdidx = CMD_k;
+ ++p;
+ } else if (p[0] == 's'
+ && ((p[1] == 'c' && p[2] != 's' && p[2] != 'r'
+ && p[3] != 'i' && p[4] != 'p')
+ || p[1] == 'g'
+ || (p[1] == 'i' && p[2] != 'm' && p[2] != 'l' && p[2] != 'g')
+ || p[1] == 'I'
+ || (p[1] == 'r' && p[2] != 'e'))) {
+ eap->cmdidx = CMD_substitute;
+ ++p;
+ } else {
+ while (ASCII_ISALPHA(*p))
+ ++p;
+ /* for python 3.x support ":py3", ":python3", ":py3file", etc. */
+ if (eap->cmd[0] == 'p' && eap->cmd[1] == 'y')
+ while (ASCII_ISALNUM(*p))
+ ++p;
+
+ /* check for non-alpha command */
+ if (p == eap->cmd && vim_strchr((char_u *)"@*!=><&~#", *p) != NULL)
+ ++p;
+ len = (int)(p - eap->cmd);
+ if (*eap->cmd == 'd' && (p[-1] == 'l' || p[-1] == 'p')) {
+ /* Check for ":dl", ":dell", etc. to ":deletel": that's
+ * :delete with the 'l' flag. Same for 'p'. */
+ for (i = 0; i < len; ++i)
+ if (eap->cmd[i] != ((char_u *)"delete")[i])
+ break;
+ if (i == len - 1) {
+ --len;
+ if (p[-1] == 'l')
+ eap->flags |= EXFLAG_LIST;
+ else
+ eap->flags |= EXFLAG_PRINT;
+ }
+ }
+
+ if (ASCII_ISLOWER(*eap->cmd))
+ eap->cmdidx = cmdidxs[CharOrdLow(*eap->cmd)];
+ else
+ eap->cmdidx = cmdidxs[26];
+
+ for (; (int)eap->cmdidx < (int)CMD_SIZE;
+ eap->cmdidx = (cmdidx_T)((int)eap->cmdidx + 1))
+ if (STRNCMP(cmdnames[(int)eap->cmdidx].cmd_name, (char *)eap->cmd,
+ (size_t)len) == 0) {
+ if (full != NULL
+ && cmdnames[(int)eap->cmdidx].cmd_name[len] == NUL)
+ *full = TRUE;
+ break;
+ }
+
+ /* Look for a user defined command as a last resort. Let ":Print" be
+ * overruled by a user defined command. */
+ if ((eap->cmdidx == CMD_SIZE || eap->cmdidx == CMD_Print)
+ && *eap->cmd >= 'A' && *eap->cmd <= 'Z') {
+ /* User defined commands may contain digits. */
+ while (ASCII_ISALNUM(*p))
+ ++p;
+ p = find_ucmd(eap, p, full, NULL, NULL);
+ }
+ if (p == eap->cmd)
+ eap->cmdidx = CMD_SIZE;
+ }
+
+ return p;
+}
+
+/*
+ * Search for a user command that matches "eap->cmd".
+ * Return cmdidx in "eap->cmdidx", flags in "eap->argt", idx in "eap->useridx".
+ * Return a pointer to just after the command.
+ * Return NULL if there is no matching command.
+ */
+static char_u * find_ucmd(eap, p, full, xp, compl)
+exarg_T *eap;
+char_u *p; /* end of the command (possibly including count) */
+int *full; /* set to TRUE for a full match */
+expand_T *xp; /* used for completion, NULL otherwise */
+int *compl; /* completion flags or NULL */
+{
+ int len = (int)(p - eap->cmd);
+ int j, k, matchlen = 0;
+ ucmd_T *uc;
+ int found = FALSE;
+ int possible = FALSE;
+ char_u *cp, *np; /* Point into typed cmd and test name */
+ garray_T *gap;
+ int amb_local = FALSE; /* Found ambiguous buffer-local command,
+ only full match global is accepted. */
+
+ /*
+ * Look for buffer-local user commands first, then global ones.
+ */
+ gap = &curbuf->b_ucmds;
+ for (;; ) {
+ for (j = 0; j < gap->ga_len; ++j) {
+ uc = USER_CMD_GA(gap, j);
+ cp = eap->cmd;
+ np = uc->uc_name;
+ k = 0;
+ while (k < len && *np != NUL && *cp++ == *np++)
+ k++;
+ if (k == len || (*np == NUL && vim_isdigit(eap->cmd[k]))) {
+ /* If finding a second match, the command is ambiguous. But
+ * not if a buffer-local command wasn't a full match and a
+ * global command is a full match. */
+ if (k == len && found && *np != NUL) {
+ if (gap == &ucmds)
+ return NULL;
+ amb_local = TRUE;
+ }
+
+ if (!found || (k == len && *np == NUL)) {
+ /* If we matched up to a digit, then there could
+ * be another command including the digit that we
+ * should use instead.
+ */
+ if (k == len)
+ found = TRUE;
+ else
+ possible = TRUE;
+
+ if (gap == &ucmds)
+ eap->cmdidx = CMD_USER;
+ else
+ eap->cmdidx = CMD_USER_BUF;
+ eap->argt = (long)uc->uc_argt;
+ eap->useridx = j;
+
+ if (compl != NULL)
+ *compl = uc->uc_compl;
+ if (xp != NULL) {
+ xp->xp_arg = uc->uc_compl_arg;
+ xp->xp_scriptID = uc->uc_scriptID;
+ }
+ /* Do not search for further abbreviations
+ * if this is an exact match. */
+ matchlen = k;
+ if (k == len && *np == NUL) {
+ if (full != NULL)
+ *full = TRUE;
+ amb_local = FALSE;
+ break;
+ }
+ }
+ }
+ }
+
+ /* Stop if we found a full match or searched all. */
+ if (j < gap->ga_len || gap == &ucmds)
+ break;
+ gap = &ucmds;
+ }
+
+ /* Only found ambiguous matches. */
+ if (amb_local) {
+ if (xp != NULL)
+ xp->xp_context = EXPAND_UNSUCCESSFUL;
+ return NULL;
+ }
+
+ /* The match we found may be followed immediately by a number. Move "p"
+ * back to point to it. */
+ if (found || possible)
+ return p + (matchlen - len);
+ return p;
+}
+
+static struct cmdmod {
+ char *name;
+ 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},
+ {"rightbelow", 6, FALSE},
+ {"sandbox", 3, FALSE},
+ {"silent", 3, FALSE},
+ {"tab", 3, TRUE},
+ {"topleft", 2, FALSE},
+ {"unsilent", 3, FALSE},
+ {"verbose", 4, TRUE},
+ {"vertical", 4, FALSE},
+};
+
+/*
+ * Return length of a command modifier (including optional count).
+ * Return zero when it's not a modifier.
+ */
+int modifier_len(cmd)
+char_u *cmd;
+{
+ int i, j;
+ char_u *p = cmd;
+
+ if (VIM_ISDIGIT(*cmd))
+ p = skipwhite(skipdigits(cmd));
+ for (i = 0; i < (int)(sizeof(cmdmods) / sizeof(struct cmdmod)); ++i) {
+ for (j = 0; p[j] != NUL; ++j)
+ if (p[j] != cmdmods[i].name[j])
+ break;
+ if (!ASCII_ISALPHA(p[j]) && j >= cmdmods[i].minlen
+ && (p == cmd || cmdmods[i].has_count))
+ return j + (int)(p - cmd);
+ }
+ return 0;
+}
+
+/*
+ * Return > 0 if an Ex command "name" exists.
+ * Return 2 if there is an exact match.
+ * Return 3 if there is an ambiguous match.
+ */
+int cmd_exists(name)
+char_u *name;
+{
+ exarg_T ea;
+ int full = FALSE;
+ int i;
+ int j;
+ char_u *p;
+
+ /* Check command modifiers. */
+ for (i = 0; i < (int)(sizeof(cmdmods) / sizeof(struct cmdmod)); ++i) {
+ for (j = 0; name[j] != NUL; ++j)
+ if (name[j] != cmdmods[i].name[j])
+ break;
+ 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.cmdidx = (cmdidx_T)0;
+ p = find_command(&ea, &full);
+ if (p == NULL)
+ return 3;
+ if (vim_isdigit(*name) && ea.cmdidx != CMD_match)
+ return 0;
+ if (*skipwhite(p) != NUL)
+ return 0; /* trailing garbage */
+ return ea.cmdidx == CMD_SIZE ? 0 : (full ? 2 : 1);
+}
+
+/*
+ * This is all pretty much copied from do_one_cmd(), with all the extra stuff
+ * we don't need/want deleted. Maybe this could be done better if we didn't
+ * repeat all this stuff. The only problem is that they may not stay
+ * perfectly compatible with each other, but then the command line syntax
+ * probably won't change that much -- webb.
+ */
+char_u * set_one_cmd_context(xp, buff)
+expand_T *xp;
+char_u *buff; /* buffer for command string */
+{
+ char_u *p;
+ char_u *cmd, *arg;
+ int len = 0;
+ exarg_T ea;
+ int compl = EXPAND_NOTHING;
+ int delim;
+ int forceit = FALSE;
+ int usefilter = FALSE; /* filter instead of file name */
+
+ ExpandInit(xp);
+ xp->xp_pattern = 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;
+
+ if (*cmd == NUL)
+ return NULL;
+ if (*cmd == '"') { /* ignore comment lines */
+ xp->xp_context = EXPAND_NOTHING;
+ return NULL;
+ }
+
+ /*
+ * 3. parse a range specifier of the form: addr [,addr] [;addr] ..
+ */
+ cmd = skip_range(cmd, &xp->xp_context);
+
+ /*
+ * 4. parse command
+ */
+ xp->xp_pattern = cmd;
+ if (*cmd == NUL)
+ return NULL;
+ if (*cmd == '"') {
+ xp->xp_context = EXPAND_NOTHING;
+ return NULL;
+ }
+
+ if (*cmd == '|' || *cmd == '\n')
+ return cmd + 1; /* There's another command */
+
+ /*
+ * Isolate the command and search for it in the command table.
+ * Exceptions:
+ * - the 'k' command can directly be followed by any character, but
+ * do accept "keepmarks", "keepalt" and "keepjumps".
+ * - the 's' command can be followed directly by 'c', 'g', 'i', 'I' or 'r'
+ */
+ if (*cmd == 'k' && cmd[1] != 'e') {
+ ea.cmdidx = CMD_k;
+ p = cmd + 1;
+ } else {
+ p = cmd;
+ while (ASCII_ISALPHA(*p) || *p == '*') /* Allow * wild card */
+ ++p;
+ /* check for non-alpha command */
+ if (p == cmd && vim_strchr((char_u *)"@*!=><&~#", *p) != NULL)
+ ++p;
+ /* for python 3.x: ":py3*" commands completion */
+ if (cmd[0] == 'p' && cmd[1] == 'y' && p == cmd + 2 && *p == '3') {
+ ++p;
+ while (ASCII_ISALPHA(*p) || *p == '*')
+ ++p;
+ }
+ len = (int)(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)
+ break;
+
+ if (cmd[0] >= 'A' && cmd[0] <= 'Z')
+ while (ASCII_ISALNUM(*p) || *p == '*') /* Allow * wild card */
+ ++p;
+ }
+
+ /*
+ * If the cursor is touching the command, and it ends in an alpha-numeric
+ * character, complete the command name.
+ */
+ if (*p == NUL && ASCII_ISALNUM(p[-1]))
+ return NULL;
+
+ if (ea.cmdidx == CMD_SIZE) {
+ if (*cmd == 's' && vim_strchr((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 */
+ }
+ }
+ if (ea.cmdidx == CMD_SIZE) {
+ /* Not still touching the command and it was an illegal one */
+ xp->xp_context = EXPAND_UNSUCCESSFUL;
+ return NULL;
+ }
+
+ xp->xp_context = EXPAND_NOTHING; /* Default now that we're past command */
+
+ if (*p == '!') { /* forced commands */
+ forceit = TRUE;
+ ++p;
+ }
+
+ /*
+ * 5. parse arguments
+ */
+ if (!USER_CMDIDX(ea.cmdidx))
+ ea.argt = (long)cmdnames[(int)ea.cmdidx].cmd_argt;
+
+ arg = skipwhite(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 (ea.cmdidx == CMD_read) {
+ 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);
+ }
+
+ /* 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);
+
+ /* Still touching the command after '+'? */
+ if (*arg == NUL)
+ return p;
+
+ /* Skip space(s) after +command to get to the real argument */
+ arg = skipwhite(arg);
+ }
+
+ /*
+ * Check for '|' to separate commands and '"' to start comments.
+ * Don't do this for ":read !cmd" and ":write !cmd".
+ */
+ if ((ea.argt & TRLBAR) && !usefilter) {
+ p = arg;
+ /* ":redir @" is not the start of a comment */
+ if (ea.cmdidx == CMD_redir && p[0] == '@' && p[1] == '"')
+ p += 2;
+ while (*p) {
+ if (*p == Ctrl_V) {
+ if (p[1] != NUL)
+ ++p;
+ } else if ( (*p == '"' && !(ea.argt & NOTRLCOM))
+ || *p == '|' || *p == '\n') {
+ if (*(p - 1) != '\\') {
+ if (*p == '|' || *p == '\n')
+ return p + 1;
+ return NULL; /* It's a comment */
+ }
+ }
+ mb_ptr_adv(p);
+ }
+ }
+
+ /* no arguments allowed */
+ if (!(ea.argt & EXTRA) && *arg != NUL &&
+ vim_strchr((char_u *)"|\"", *arg) == NULL)
+ return NULL;
+
+ /* Find start of last argument (argument just before cursor): */
+ p = buff;
+ xp->xp_pattern = p;
+ len = (int)STRLEN(buff);
+ while (*p && p < buff + len) {
+ if (*p == ' ' || *p == TAB) {
+ /* argument starts after a space */
+ xp->xp_pattern = ++p;
+ } else {
+ 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 */
+
+ /*
+ * Allow spaces within back-quotes to count as part of the argument
+ * being expanded.
+ */
+ xp->xp_pattern = skipwhite(arg);
+ p = 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 == '`') {
+ if (!in_quote) {
+ xp->xp_pattern = p;
+ bow = p + 1;
+ }
+ in_quote = !in_quote;
+ }
+ /* An argument can contain just about everything, except
+ * characters that end the command and white space. */
+ else if (c == '|' || c == '\n' || c == '"' || (vim_iswhite(c)
+#ifdef SPACE_IN_FILENAME
+ && (!(ea.argt & NOSPC) ||
+ usefilter)
+#endif
+ )) {
+ 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))
+ break;
+ if (has_mbyte)
+ len = (*mb_ptr2len)(p);
+ else
+ len = 1;
+ mb_ptr_adv(p);
+ }
+ if (in_quote)
+ bow = p;
+ else
+ xp->xp_pattern = p;
+ p -= len;
+ }
+ 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;
+ xp->xp_context = EXPAND_FILES;
+
+ /* For a shell command more chars need to be escaped. */
+ if (usefilter || ea.cmdidx == CMD_bang) {
+#ifndef BACKSLASH_IN_FILENAME
+ xp->xp_shell = TRUE;
+#endif
+ /* When still after the command name expand executables. */
+ if (xp->xp_pattern == skipwhite(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))
+ 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;
+ }
+ }
+ /* 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) {
+ xp->xp_context = EXPAND_USER;
+ ++xp->xp_pattern;
+ }
+ }
+ }
+
+ /*
+ * 6. switch on command name
+ */
+ switch (ea.cmdidx) {
+ case CMD_find:
+ case CMD_sfind:
+ case CMD_tabfind:
+ if (xp->xp_context == EXPAND_FILES)
+ xp->xp_context = EXPAND_FILES_IN_PATH;
+ break;
+ case CMD_cd:
+ case CMD_chdir:
+ case CMD_lcd:
+ case CMD_lchdir:
+ if (xp->xp_context == EXPAND_FILES)
+ xp->xp_context = EXPAND_DIRECTORIES;
+ break;
+ case CMD_help:
+ xp->xp_context = EXPAND_HELP;
+ xp->xp_pattern = arg;
+ break;
+
+ /* Command modifiers: return the argument.
+ * Also for commands with an argument that is a command. */
+ case CMD_aboveleft:
+ case CMD_argdo:
+ case CMD_belowright:
+ case CMD_botright:
+ case CMD_browse:
+ case CMD_bufdo:
+ case CMD_confirm:
+ case CMD_debug:
+ case CMD_folddoclosed:
+ case CMD_folddoopen:
+ case CMD_hide:
+ case CMD_keepalt:
+ case CMD_keepjumps:
+ case CMD_keepmarks:
+ case CMD_keeppatterns:
+ case CMD_leftabove:
+ case CMD_lockmarks:
+ case CMD_rightbelow:
+ case CMD_sandbox:
+ case CMD_silent:
+ case CMD_tab:
+ case CMD_tabdo:
+ case CMD_topleft:
+ case CMD_verbose:
+ case CMD_vertical:
+ case CMD_windo:
+ return arg;
+
+ case CMD_match:
+ if (*arg == NUL || !ends_excmd(*arg)) {
+ /* also complete "None" */
+ set_context_in_echohl_cmd(xp, arg);
+ arg = skipwhite(skiptowhite(arg));
+ if (*arg != NUL) {
+ xp->xp_context = EXPAND_NOTHING;
+ arg = skip_regexp(arg + 1, *arg, p_magic, NULL);
+ }
+ }
+ return find_nextcmd(arg);
+
+ /*
+ * All completion for the +cmdline_compl feature goes here.
+ */
+
+ case CMD_command:
+ /* Check for attributes */
+ while (*arg == '-') {
+ arg++; /* Skip "-" */
+ p = skiptowhite(arg);
+ if (*p == NUL) {
+ /* Cursor is still in the attribute */
+ p = vim_strchr(arg, '=');
+ if (p == NULL) {
+ /* No "=", so complete attribute names */
+ xp->xp_context = EXPAND_USER_CMD_FLAGS;
+ xp->xp_pattern = arg;
+ return NULL;
+ }
+
+ /* For the -complete and -nargs attributes, we complete
+ * their arguments as well.
+ */
+ if (STRNICMP(arg, "complete", p - arg) == 0) {
+ xp->xp_context = EXPAND_USER_COMPLETE;
+ xp->xp_pattern = p + 1;
+ return NULL;
+ } else if (STRNICMP(arg, "nargs", p - arg) == 0) {
+ xp->xp_context = EXPAND_USER_NARGS;
+ xp->xp_pattern = p + 1;
+ return NULL;
+ }
+ return NULL;
+ }
+ arg = skipwhite(p);
+ }
+
+ /* After the attributes comes the new command name */
+ p = skiptowhite(arg);
+ if (*p == NUL) {
+ xp->xp_context = EXPAND_USER_COMMANDS;
+ xp->xp_pattern = arg;
+ break;
+ }
+
+ /* And finally comes a normal command */
+ return skipwhite(p);
+
+ case CMD_delcommand:
+ xp->xp_context = EXPAND_USER_COMMANDS;
+ xp->xp_pattern = arg;
+ break;
+
+ case CMD_global:
+ case CMD_vglobal:
+ delim = *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;
+ }
+ if (arg[0] != NUL)
+ return arg + 1;
+ break;
+ case CMD_and:
+ case CMD_substitute:
+ delim = *arg;
+ if (delim) {
+ /* skip "from" part */
+ ++arg;
+ arg = skip_regexp(arg, delim, p_magic, NULL);
+ }
+ /* skip "to" part */
+ while (arg[0] != NUL && 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)
+ return arg;
+ break;
+ case CMD_isearch:
+ case CMD_dsearch:
+ case CMD_ilist:
+ case CMD_dlist:
+ case CMD_ijump:
+ case CMD_psearch:
+ 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)
+ arg++;
+ if (*arg) {
+ arg = skipwhite(arg + 1);
+
+ /* Check for trailing illegal characters */
+ if (*arg && vim_strchr((char_u *)"|\"\n", *arg) == NULL)
+ xp->xp_context = EXPAND_NOTHING;
+ else
+ return arg;
+ }
+ }
+ break;
+ case CMD_autocmd:
+ return set_context_in_autocmd(xp, arg, FALSE);
+
+ case CMD_doautocmd:
+ case CMD_doautoall:
+ return set_context_in_autocmd(xp, arg, TRUE);
+ case CMD_set:
+ set_context_in_set_cmd(xp, arg, 0);
+ break;
+ case CMD_setglobal:
+ set_context_in_set_cmd(xp, arg, OPT_GLOBAL);
+ break;
+ case CMD_setlocal:
+ set_context_in_set_cmd(xp, arg, OPT_LOCAL);
+ break;
+ case CMD_tag:
+ case CMD_stag:
+ case CMD_ptag:
+ case CMD_ltag:
+ case CMD_tselect:
+ case CMD_stselect:
+ case CMD_ptselect:
+ case CMD_tjump:
+ case CMD_stjump:
+ case CMD_ptjump:
+ if (*p_wop != NUL)
+ xp->xp_context = EXPAND_TAGS_LISTFILES;
+ else
+ xp->xp_context = EXPAND_TAGS;
+ xp->xp_pattern = arg;
+ break;
+ case CMD_augroup:
+ xp->xp_context = EXPAND_AUGROUP;
+ xp->xp_pattern = arg;
+ break;
+ case CMD_syntax:
+ set_context_in_syntax_cmd(xp, arg);
+ break;
+ case CMD_let:
+ case CMD_if:
+ case CMD_elseif:
+ case CMD_while:
+ case CMD_for:
+ case CMD_echo:
+ case CMD_echon:
+ case CMD_execute:
+ case CMD_echomsg:
+ case CMD_echoerr:
+ case CMD_call:
+ case CMD_return:
+ set_context_for_expression(xp, arg, ea.cmdidx);
+ break;
+
+ case CMD_unlet:
+ while ((xp->xp_pattern = vim_strchr(arg, ' ')) != NULL)
+ arg = xp->xp_pattern + 1;
+ xp->xp_context = EXPAND_USER_VARS;
+ xp->xp_pattern = arg;
+ break;
+
+ case CMD_function:
+ case CMD_delfunction:
+ xp->xp_context = EXPAND_USER_FUNC;
+ xp->xp_pattern = arg;
+ break;
+
+ case CMD_echohl:
+ set_context_in_echohl_cmd(xp, arg);
+ break;
+ case CMD_highlight:
+ set_context_in_highlight_cmd(xp, arg);
+ break;
+ case CMD_cscope:
+ case CMD_lcscope:
+ case CMD_scscope:
+ set_context_in_cscope_cmd(xp, arg, ea.cmdidx);
+ break;
+ case CMD_bdelete:
+ case CMD_bwipeout:
+ case CMD_bunload:
+ while ((xp->xp_pattern = vim_strchr(arg, ' ')) != NULL)
+ arg = xp->xp_pattern + 1;
+ /*FALLTHROUGH*/
+ case CMD_buffer:
+ case CMD_sbuffer:
+ case CMD_checktime:
+ xp->xp_context = EXPAND_BUFFERS;
+ xp->xp_pattern = arg;
+ break;
+ case CMD_USER:
+ case CMD_USER_BUF:
+ if (compl != 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)
+ 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. */
+ p = arg;
+ while (*p) {
+ 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);
+ }
+ xp->xp_pattern = arg;
+ }
+ xp->xp_context = compl;
+ }
+ break;
+ case CMD_map: case CMD_noremap:
+ case CMD_nmap: case CMD_nnoremap:
+ case CMD_vmap: case CMD_vnoremap:
+ case CMD_omap: case CMD_onoremap:
+ case CMD_imap: case CMD_inoremap:
+ case CMD_cmap: case CMD_cnoremap:
+ 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);
+ case CMD_unmap:
+ case CMD_nunmap:
+ case CMD_vunmap:
+ case CMD_ounmap:
+ case CMD_iunmap:
+ case CMD_cunmap:
+ case CMD_lunmap:
+ case CMD_sunmap:
+ case CMD_xunmap:
+ return set_context_in_map_cmd(xp, cmd, arg, forceit,
+ FALSE, TRUE, ea.cmdidx);
+ 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);
+ case CMD_unabbreviate:
+ case CMD_cunabbrev:
+ case CMD_iunabbrev:
+ return set_context_in_map_cmd(xp, cmd, 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:
+ case CMD_vmenu: case CMD_vnoremenu: case CMD_vunmenu:
+ case CMD_omenu: case CMD_onoremenu: case CMD_ounmenu:
+ case CMD_imenu: case CMD_inoremenu: case CMD_iunmenu:
+ case CMD_cmenu: case CMD_cnoremenu: case CMD_cunmenu:
+ case CMD_tmenu: case CMD_tunmenu:
+ case CMD_popup: case CMD_tearoff: case CMD_emenu:
+ return set_context_in_menu_cmd(xp, cmd, arg, forceit);
+
+ case CMD_colorscheme:
+ xp->xp_context = EXPAND_COLORS;
+ xp->xp_pattern = arg;
+ break;
+
+ case CMD_compiler:
+ xp->xp_context = EXPAND_COMPILER;
+ xp->xp_pattern = arg;
+ break;
+
+ case CMD_ownsyntax:
+ xp->xp_context = EXPAND_OWNSYNTAX;
+ xp->xp_pattern = arg;
+ break;
+
+ case CMD_setfiletype:
+ xp->xp_context = EXPAND_FILETYPE;
+ xp->xp_pattern = arg;
+ break;
+
+#ifdef HAVE_WORKING_LIBINTL
+ case CMD_language:
+ p = skiptowhite(arg);
+ if (*p == NUL) {
+ xp->xp_context = EXPAND_LANGUAGE;
+ xp->xp_pattern = arg;
+ } else {
+ 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_context = EXPAND_NOTHING;
+ }
+ break;
+#endif
+ case CMD_profile:
+ set_context_in_profile_cmd(xp, arg);
+ break;
+ case CMD_behave:
+ xp->xp_context = EXPAND_BEHAVE;
+ xp->xp_pattern = arg;
+ break;
+
+ case CMD_history:
+ xp->xp_context = EXPAND_HISTORY;
+ xp->xp_pattern = arg;
+ break;
+ case CMD_syntime:
+ xp->xp_context = EXPAND_SYNTIME;
+ xp->xp_pattern = arg;
+ break;
+
+
+ default:
+ break;
+ }
+ return NULL;
+}
+
+/*
+ * skip a range specifier of the form: addr [,addr] [;addr] ..
+ *
+ * Backslashed delimiters after / or ? will be skipped, and commands will
+ * not be expanded between /'s and ?'s or after "'".
+ *
+ * Also skip white space and ":" characters.
+ * Returns the "cmd" pointer advanced to beyond the range.
+ */
+char_u * skip_range(cmd, ctx)
+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)
+ *ctx = EXPAND_NOTHING;
+ } else if (*cmd == '/' || *cmd == '?') {
+ delim = *cmd++;
+ while (*cmd != NUL && *cmd != delim)
+ if (*cmd++ == '\\' && *cmd != NUL)
+ ++cmd;
+ if (*cmd == NUL && ctx != NULL)
+ *ctx = EXPAND_NOTHING;
+ }
+ if (*cmd != NUL)
+ ++cmd;
+ }
+
+ /* Skip ":" and white space. */
+ while (*cmd == ':')
+ cmd = skipwhite(cmd + 1);
+
+ return cmd;
+}
+
+/*
+ * get a single EX address
+ *
+ * Set ptr to the next character after the part that was interpreted.
+ * Set ptr to NULL when an error is encountered.
+ *
+ * Return MAXLNUM when no Ex address was found.
+ */
+static linenr_T get_address(ptr, skip, to_other_file)
+char_u **ptr;
+int skip; /* only skip the address, don't use it */
+int to_other_file; /* flag: may jump to other file */
+{
+ int c;
+ int i;
+ long n;
+ char_u *cmd;
+ pos_T pos;
+ pos_T *fp;
+ linenr_T lnum;
+
+ cmd = skipwhite(*ptr);
+ lnum = MAXLNUM;
+ do {
+ switch (*cmd) {
+ case '.': /* '.' - Cursor position */
+ ++cmd;
+ lnum = curwin->w_cursor.lnum;
+ break;
+
+ case '$': /* '$' - last line */
+ ++cmd;
+ lnum = curbuf->b_ml.ml_line_count;
+ break;
+
+ case '\'': /* ''' - mark */
+ if (*++cmd == NUL) {
+ cmd = NULL;
+ goto error;
+ }
+ if (skip)
+ ++cmd;
+ else {
+ /* Only accept a mark in another file when it is
+ * used by itself: ":'M". */
+ fp = getmark(*cmd, to_other_file && cmd[1] == NUL);
+ ++cmd;
+ if (fp == (pos_T *)-1)
+ /* Jumped to another file. */
+ lnum = curwin->w_cursor.lnum;
+ else {
+ if (check_mark(fp) == FAIL) {
+ cmd = NULL;
+ goto error;
+ }
+ lnum = fp->lnum;
+ }
+ }
+ break;
+
+ case '/':
+ case '?': /* '/' or '?' - search */
+ c = *cmd++;
+ if (skip) { /* skip "/pat/" */
+ cmd = skip_regexp(cmd, c, (int)p_magic, NULL);
+ if (*cmd == c)
+ ++cmd;
+ } else {
+ pos = curwin->w_cursor; /* save curwin->w_cursor */
+ /*
+ * When '/' or '?' follows another address, start
+ * from there.
+ */
+ 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 == '/')
+ curwin->w_cursor.col = MAXCOL;
+ else
+ curwin->w_cursor.col = 0;
+ searchcmdlen = 0;
+ if (!do_search(NULL, c, cmd, 1L,
+ SEARCH_HIS | SEARCH_MSG, NULL)) {
+ curwin->w_cursor = pos;
+ cmd = NULL;
+ goto error;
+ }
+ lnum = curwin->w_cursor.lnum;
+ curwin->w_cursor = pos;
+ /* adjust command string pointer */
+ cmd += searchcmdlen;
+ }
+ break;
+
+ case '\\': /* "\?", "\/" or "\&", repeat search */
+ ++cmd;
+ if (*cmd == '&')
+ i = RE_SUBST;
+ else if (*cmd == '?' || *cmd == '/')
+ i = RE_SEARCH;
+ else {
+ EMSG(_(e_backslash));
+ cmd = NULL;
+ goto error;
+ }
+
+ if (!skip) {
+ /*
+ * When search follows another address, start from
+ * there.
+ */
+ if (lnum != MAXLNUM)
+ pos.lnum = lnum;
+ else
+ pos.lnum = curwin->w_cursor.lnum;
+
+ /*
+ * Start the search just like for the above
+ * do_search().
+ */
+ if (*cmd != '?')
+ pos.col = MAXCOL;
+ else
+ pos.col = 0;
+ if (searchit(curwin, curbuf, &pos,
+ *cmd == '?' ? BACKWARD : FORWARD,
+ (char_u *)"", 1L, SEARCH_MSG,
+ i, (linenr_T)0, NULL) != FAIL)
+ lnum = pos.lnum;
+ else {
+ cmd = NULL;
+ goto error;
+ }
+ }
+ ++cmd;
+ break;
+
+ default:
+ if (VIM_ISDIGIT(*cmd)) /* absolute line number */
+ lnum = getdigits(&cmd);
+ }
+
+ for (;; ) {
+ cmd = skipwhite(cmd);
+ if (*cmd != '-' && *cmd != '+' && !VIM_ISDIGIT(*cmd))
+ break;
+
+ if (lnum == MAXLNUM)
+ lnum = curwin->w_cursor.lnum; /* "+1" is same as ".+1" */
+ if (VIM_ISDIGIT(*cmd))
+ i = '+'; /* "number" is same as "+number" */
+ else
+ i = *cmd++;
+ if (!VIM_ISDIGIT(*cmd)) /* '+' is '+1', but '+0' is not '+1' */
+ n = 1;
+ else
+ n = getdigits(&cmd);
+ if (i == '-')
+ lnum -= n;
+ else
+ lnum += n;
+ }
+ } while (*cmd == '/' || *cmd == '?');
+
+error:
+ *ptr = cmd;
+ return lnum;
+}
+
+/*
+ * Get flags from an Ex command argument.
+ */
+static void get_flags(eap)
+exarg_T *eap;
+{
+ while (vim_strchr((char_u *)"lp#", *eap->arg) != NULL) {
+ if (*eap->arg == 'l')
+ eap->flags |= EXFLAG_LIST;
+ else if (*eap->arg == 'p')
+ eap->flags |= EXFLAG_PRINT;
+ else
+ eap->flags |= EXFLAG_NR;
+ eap->arg = skipwhite(eap->arg + 1);
+ }
+}
+
+/*
+ * Function called for command which is Not Implemented. NI!
+ */
+void ex_ni(eap)
+exarg_T *eap;
+{
+ if (!eap->skip)
+ eap->errmsg = (char_u *)N_(
+ "E319: Sorry, the command is not available in this version");
+}
+
+#ifdef HAVE_EX_SCRIPT_NI
+/*
+ * Function called for script command which is Not Implemented. NI!
+ * Skips over ":perl <<EOF" constructs.
+ */
+static void ex_script_ni(eap)
+exarg_T *eap;
+{
+ if (!eap->skip)
+ ex_ni(eap);
+ else
+ vim_free(script_get(eap, eap->arg));
+}
+#endif
+
+/*
+ * Check range in Ex command for validity.
+ * Return NULL when valid, error message when invalid.
+ */
+static char_u * invalid_range(eap)
+exarg_T *eap;
+{
+ if ( eap->line1 < 0
+ || eap->line2 < 0
+ || eap->line1 > eap->line2
+ || ((eap->argt & RANGE)
+ && !(eap->argt & NOTADR)
+ && eap->line2 > curbuf->b_ml.ml_line_count
+ + (eap->cmdidx == CMD_diffget)
+ ))
+ return (char_u *)_(e_invrange);
+ return NULL;
+}
+
+/*
+ * Correct the range for zero line number, if required.
+ */
+static void correct_range(eap)
+exarg_T *eap;
+{
+ if (!(eap->argt & ZEROR)) { /* zero in range not allowed */
+ if (eap->line1 == 0)
+ eap->line1 = 1;
+ if (eap->line2 == 0)
+ eap->line2 = 1;
+ }
+}
+
+static char_u *skip_grep_pat __ARGS((exarg_T *eap));
+
+/*
+ * For a ":vimgrep" or ":vimgrepadd" command return a pointer past the
+ * pattern. Otherwise return eap->arg.
+ */
+static char_u * skip_grep_pat(eap)
+exarg_T *eap;
+{
+ char_u *p = eap->arg;
+
+ if (*p != NUL && (eap->cmdidx == CMD_vimgrep || eap->cmdidx == CMD_lvimgrep
+ || eap->cmdidx == CMD_vimgrepadd
+ || eap->cmdidx == CMD_lvimgrepadd
+ || grep_internal(eap->cmdidx))) {
+ p = skip_vimgrep_pat(p, NULL, NULL);
+ if (p == NULL)
+ p = eap->arg;
+ }
+ return p;
+}
+
+/*
+ * For the ":make" and ":grep" commands insert the 'makeprg'/'grepprg' option
+ * in the command line, so that things like % get expanded.
+ */
+static char_u * replace_makeprg(eap, p, cmdlinep)
+exarg_T *eap;
+char_u *p;
+char_u **cmdlinep;
+{
+ char_u *new_cmdline;
+ char_u *program;
+ char_u *pos;
+ char_u *ptr;
+ int len;
+ int i;
+
+ /*
+ * Don't do it when ":vimgrep" is used for ":grep".
+ */
+ if ((eap->cmdidx == CMD_make || eap->cmdidx == CMD_lmake
+ || eap->cmdidx == CMD_grep || eap->cmdidx == CMD_lgrep
+ || eap->cmdidx == CMD_grepadd
+ || eap->cmdidx == CMD_lgrepadd)
+ && !grep_internal(eap->cmdidx)) {
+ if (eap->cmdidx == CMD_grep || eap->cmdidx == CMD_lgrep
+ || eap->cmdidx == CMD_grepadd || eap->cmdidx == CMD_lgrepadd) {
+ if (*curbuf->b_p_gp == NUL)
+ program = p_gp;
+ else
+ program = curbuf->b_p_gp;
+ } else {
+ if (*curbuf->b_p_mp == NUL)
+ program = p_mp;
+ else
+ program = curbuf->b_p_mp;
+ }
+
+ p = skipwhite(p);
+
+ if ((pos = (char_u *)strstr((char *)program, "$*")) != NULL) {
+ /* replace $* by given arguments */
+ i = 1;
+ while ((pos = (char_u *)strstr((char *)pos + 2, "$*")) != NULL)
+ ++i;
+ len = (int)STRLEN(p);
+ new_cmdline = alloc((int)(STRLEN(program) + i * (len - 2) + 1));
+ if (new_cmdline == NULL)
+ return NULL; /* out of memory */
+ ptr = new_cmdline;
+ while ((pos = (char_u *)strstr((char *)program, "$*")) != NULL) {
+ i = (int)(pos - program);
+ STRNCPY(ptr, program, i);
+ STRCPY(ptr += i, p);
+ ptr += len;
+ program = pos + 2;
+ }
+ STRCPY(ptr, program);
+ } else {
+ new_cmdline = alloc((int)(STRLEN(program) + STRLEN(p) + 2));
+ if (new_cmdline == NULL)
+ return NULL; /* out of memory */
+ STRCPY(new_cmdline, program);
+ STRCAT(new_cmdline, " ");
+ STRCAT(new_cmdline, p);
+ }
+ msg_make(p);
+
+ /* 'eap->cmd' is not set here, because it is not used at CMD_make */
+ vim_free(*cmdlinep);
+ *cmdlinep = new_cmdline;
+ p = new_cmdline;
+ }
+ return p;
+}
+
+/*
+ * Expand file name in Ex command argument.
+ * Return FAIL for failure, OK otherwise.
+ */
+int expand_filename(eap, cmdlinep, errormsgp)
+exarg_T *eap;
+char_u **cmdlinep;
+char_u **errormsgp;
+{
+ int has_wildcards; /* need to expand wildcards */
+ char_u *repl;
+ int srclen;
+ char_u *p;
+ int n;
+ int escaped;
+
+ /* Skip a regexp pattern for ":vimgrep[add] pat file..." */
+ p = skip_grep_pat(eap);
+
+ /*
+ * Decide to expand wildcards *before* replacing '%', '#', etc. If
+ * the file name contains a wildcard it should not cause expanding.
+ * (it will be expanded anyway if there is a wildcard before replacing).
+ */
+ has_wildcards = mch_has_wildcard(p);
+ while (*p != NUL) {
+ /* Skip over `=expr`, wildcards in it are not expanded. */
+ if (p[0] == '`' && p[1] == '=') {
+ p += 2;
+ (void)skip_expr(&p);
+ if (*p == '`')
+ ++p;
+ continue;
+ }
+ /*
+ * Quick check if this cannot be the start of a special string.
+ * Also removes backslash before '%', '#' and '<'.
+ */
+ if (vim_strchr((char_u *)"%#<", *p) == NULL) {
+ ++p;
+ continue;
+ }
+
+ /*
+ * Try to find a match at this position.
+ */
+ repl = eval_vars(p, eap->arg, &srclen, &(eap->do_ecmd_lnum),
+ errormsgp, &escaped);
+ if (*errormsgp != NULL) /* error detected */
+ return FAIL;
+ if (repl == NULL) { /* no match found */
+ p += srclen;
+ continue;
+ }
+
+ /* Wildcards won't be expanded below, the replacement is taken
+ * literally. But do expand "~/file", "~user/file" and "$HOME/file". */
+ if (vim_strchr(repl, '$') != NULL || vim_strchr(repl, '~') != NULL) {
+ char_u *l = repl;
+
+ repl = expand_env_save(repl);
+ vim_free(l);
+ }
+
+ /* Need to escape white space et al. with a backslash.
+ * 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
+ && eap->cmdidx != CMD_bang
+ && eap->cmdidx != CMD_make
+ && eap->cmdidx != CMD_lmake
+ && eap->cmdidx != CMD_grep
+ && eap->cmdidx != CMD_lgrep
+ && eap->cmdidx != CMD_grepadd
+ && eap->cmdidx != CMD_lgrepadd
+#ifndef UNIX
+ && !(eap->argt & NOSPC)
+#endif
+ ) {
+ char_u *l;
+#ifdef BACKSLASH_IN_FILENAME
+ /* Don't escape a backslash here, because rem_backslash() doesn't
+ * remove it later. */
+ static char_u *nobslash = (char_u *)" \t\"|";
+# define ESCAPE_CHARS nobslash
+#else
+# define ESCAPE_CHARS escape_chars
+#endif
+
+ for (l = repl; *l; ++l)
+ if (vim_strchr(ESCAPE_CHARS, *l) != NULL) {
+ l = vim_strsave_escaped(repl, ESCAPE_CHARS);
+ if (l != NULL) {
+ vim_free(repl);
+ repl = l;
+ }
+ break;
+ }
+ }
+
+ /* For a shell command a '!' must be escaped. */
+ if ((eap->usefilter || eap->cmdidx == CMD_bang)
+ && vim_strpbrk(repl, (char_u *)"!&;()<>") != NULL) {
+ char_u *l;
+
+ l = vim_strsave_escaped(repl, (char_u *)"!&;()<>");
+ if (l != NULL) {
+ vim_free(repl);
+ repl = l;
+ /* For a sh-like shell escape "!" another time. */
+ if (strstr((char *)p_sh, "sh") != NULL) {
+ l = vim_strsave_escaped(repl, (char_u *)"!");
+ if (l != NULL) {
+ vim_free(repl);
+ repl = l;
+ }
+ }
+ }
+ }
+
+ p = repl_cmdline(eap, p, srclen, repl, cmdlinep);
+ vim_free(repl);
+ if (p == NULL)
+ return FAIL;
+ }
+
+ /*
+ * One file argument: Expand wildcards.
+ * Don't do this with ":r !command" or ":w !command".
+ */
+ if ((eap->argt & NOSPC) && !eap->usefilter) {
+ /*
+ * May do this twice:
+ * 1. Replace environment variables.
+ * 2. Replace any other wildcards, remove backslashes.
+ */
+ for (n = 1; n <= 2; ++n) {
+ if (n == 2) {
+#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 (vim_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 and OS/2, when wildcards are expanded, this is
+ * done by ExpandOne() below.
+ */
+#if defined(UNIX) || defined(OS2)
+ if (!has_wildcards)
+#endif
+ backslash_halve(eap->arg);
+ }
+
+ if (has_wildcards) {
+ if (n == 1) {
+ /*
+ * First loop: May expand environment variables. This
+ * can be done much faster with expand_env() than with
+ * something else (e.g., calling a shell).
+ * After expanding environment variables, check again
+ * if there are still wildcards present.
+ */
+ if (vim_strchr(eap->arg, '$') != NULL
+ || vim_strchr(eap->arg, '~') != NULL) {
+ expand_env_esc(eap->arg, NameBuff, MAXPATHL,
+ TRUE, TRUE, NULL);
+ has_wildcards = mch_has_wildcard(NameBuff);
+ p = NameBuff;
+ } else
+ p = NULL;
+ } else { /* n == 2 */
+ expand_T xpc;
+ int options = WILD_LIST_NOTFOUND|WILD_ADD_SLASH;
+
+ ExpandInit(&xpc);
+ xpc.xp_context = EXPAND_FILES;
+ if (p_wic)
+ options += WILD_ICASE;
+ p = ExpandOne(&xpc, eap->arg, NULL,
+ options, WILD_EXPAND_FREE);
+ if (p == NULL)
+ return FAIL;
+ }
+ if (p != NULL) {
+ (void)repl_cmdline(eap, eap->arg, (int)STRLEN(eap->arg),
+ p, cmdlinep);
+ if (n == 2) /* p came from ExpandOne() */
+ vim_free(p);
+ }
+ }
+ }
+ }
+ return OK;
+}
+
+/*
+ * Replace part of the command line, keeping eap->cmd, eap->arg and
+ * eap->nextcmd correct.
+ * "src" points to the part that is to be replaced, of length "srclen".
+ * "repl" is the replacement string.
+ * Returns a pointer to the character after the replaced string.
+ * Returns NULL for failure.
+ */
+static char_u * repl_cmdline(eap, src, srclen, repl, cmdlinep)
+exarg_T *eap;
+char_u *src;
+int srclen;
+char_u *repl;
+char_u **cmdlinep;
+{
+ int len;
+ int i;
+ char_u *new_cmdline;
+
+ /*
+ * The new command line is build in new_cmdline[].
+ * First allocate it.
+ * Careful: a "+cmd" argument may have been NUL terminated.
+ */
+ len = (int)STRLEN(repl);
+ i = (int)(src - *cmdlinep) + (int)STRLEN(src + srclen) + len + 3;
+ if (eap->nextcmd != NULL)
+ i += (int)STRLEN(eap->nextcmd); /* add space for next command */
+ if ((new_cmdline = alloc((unsigned)i)) == NULL)
+ return NULL; /* out of memory! */
+
+ /*
+ * Copy the stuff before the expanded part.
+ * Copy the expanded stuff.
+ * Copy what came after the expanded part.
+ * Copy the next commands, if there are any.
+ */
+ i = (int)(src - *cmdlinep); /* length of part before match */
+ mch_memmove(new_cmdline, *cmdlinep, (size_t)i);
+
+ mch_memmove(new_cmdline + i, repl, (size_t)len);
+ i += len; /* remember the end of the string */
+ STRCPY(new_cmdline + i, src + srclen);
+ src = new_cmdline + i; /* remember where to continue */
+
+ if (eap->nextcmd != NULL) { /* append next command */
+ i = (int)STRLEN(new_cmdline) + 1;
+ STRCPY(new_cmdline + i, eap->nextcmd);
+ eap->nextcmd = new_cmdline + i;
+ }
+ eap->cmd = new_cmdline + (eap->cmd - *cmdlinep);
+ eap->arg = new_cmdline + (eap->arg - *cmdlinep);
+ if (eap->do_ecmd_cmd != NULL && eap->do_ecmd_cmd != dollar_command)
+ eap->do_ecmd_cmd = new_cmdline + (eap->do_ecmd_cmd - *cmdlinep);
+ vim_free(*cmdlinep);
+ *cmdlinep = new_cmdline;
+
+ return src;
+}
+
+/*
+ * Check for '|' to separate commands and '"' to start comments.
+ */
+void separate_nextcmd(eap)
+exarg_T *eap;
+{
+ char_u *p;
+
+ p = skip_grep_pat(eap);
+
+ for (; *p; mb_ptr_adv(p)) {
+ if (*p == Ctrl_V) {
+ if (eap->argt & (USECTRLV | XFILE))
+ ++p; /* skip CTRL-V and next char */
+ else
+ /* remove CTRL-V and skip next char */
+ STRMOVE(p, p + 1);
+ if (*p == NUL) /* stop at NUL after CTRL-V */
+ break;
+ }
+ /* Skip over `=expr` when wildcards are expanded. */
+ else if (p[0] == '`' && p[1] == '=' && (eap->argt & XFILE)) {
+ p += 2;
+ (void)skip_expr(&p);
+ }
+ /* Check for '"': start of comment or '|': next command */
+ /* :@" and :*" do not start a comment!
+ * :redir @" doesn't either. */
+ else if ((*p == '"' && !(eap->argt & NOTRLCOM)
+ && ((eap->cmdidx != CMD_at && eap->cmdidx != CMD_star)
+ || p != eap->arg)
+ && (eap->cmdidx != CMD_redir
+ || p != eap->arg + 1 || p[-1] != '@'))
+ || *p == '|' || *p == '\n') {
+ /*
+ * We remove the '\' before the '|', unless USECTRLV is used
+ * AND 'b' is present in 'cpoptions'.
+ */
+ if ((vim_strchr(p_cpo, CPO_BAR) == NULL
+ || !(eap->argt & USECTRLV)) && *(p - 1) == '\\') {
+ STRMOVE(p - 1, p); /* remove the '\' */
+ --p;
+ } else {
+ eap->nextcmd = check_nextcmd(p);
+ *p = NUL;
+ break;
+ }
+ }
+ }
+
+ if (!(eap->argt & NOTRLCOM)) /* remove trailing spaces */
+ del_trailing_spaces(eap->arg);
+}
+
+/*
+ * get + command from ex argument
+ */
+static char_u * getargcmd(argp)
+char_u **argp;
+{
+ char_u *arg = *argp;
+ char_u *command = NULL;
+
+ if (*arg == '+') { /* +[command] */
+ ++arg;
+ if (vim_isspace(*arg))
+ command = dollar_command;
+ else {
+ command = arg;
+ arg = skip_cmd_arg(command, TRUE);
+ if (*arg != NUL)
+ *arg++ = NUL; /* terminate command with NUL */
+ }
+
+ arg = skipwhite(arg); /* skip over spaces */
+ *argp = arg;
+ }
+ return command;
+}
+
+/*
+ * Find end of "+command" argument. Skip over "\ " and "\\".
+ */
+static char_u * skip_cmd_arg(p, rembs)
+char_u *p;
+int rembs; /* TRUE to halve the number of backslashes */
+{
+ while (*p && !vim_isspace(*p)) {
+ if (*p == '\\' && p[1] != NUL) {
+ if (rembs)
+ STRMOVE(p, p + 1);
+ else
+ ++p;
+ }
+ mb_ptr_adv(p);
+ }
+ return p;
+}
+
+/*
+ * Get "++opt=arg" argument.
+ * Return FAIL or OK.
+ */
+static int getargopt(eap)
+exarg_T *eap;
+{
+ char_u *arg = eap->arg + 2;
+ int *pp = NULL;
+ int bad_char_idx;
+ char_u *p;
+
+ /* ":edit ++[no]bin[ary] file" */
+ if (STRNCMP(arg, "bin", 3) == 0 || STRNCMP(arg, "nobin", 5) == 0) {
+ if (*arg == 'n') {
+ arg += 2;
+ eap->force_bin = FORCE_NOBIN;
+ } else
+ eap->force_bin = FORCE_BIN;
+ if (!checkforcmd(&arg, "binary", 3))
+ return FAIL;
+ eap->arg = skipwhite(arg);
+ return OK;
+ }
+
+ /* ":read ++edit file" */
+ if (STRNCMP(arg, "edit", 4) == 0) {
+ eap->read_edit = TRUE;
+ eap->arg = skipwhite(arg + 4);
+ return OK;
+ }
+
+ if (STRNCMP(arg, "ff", 2) == 0) {
+ arg += 2;
+ pp = &eap->force_ff;
+ } else if (STRNCMP(arg, "fileformat", 10) == 0) {
+ arg += 10;
+ pp = &eap->force_ff;
+ } else if (STRNCMP(arg, "enc", 3) == 0) {
+ if (STRNCMP(arg, "encoding", 8) == 0)
+ arg += 8;
+ else
+ arg += 3;
+ pp = &eap->force_enc;
+ } else if (STRNCMP(arg, "bad", 3) == 0) {
+ arg += 3;
+ pp = &bad_char_idx;
+ }
+
+ if (pp == NULL || *arg != '=')
+ return FAIL;
+
+ ++arg;
+ *pp = (int)(arg - eap->cmd);
+ arg = skip_cmd_arg(arg, FALSE);
+ eap->arg = skipwhite(arg);
+ *arg = NUL;
+
+ if (pp == &eap->force_ff) {
+ if (check_ff_value(eap->cmd + eap->force_ff) == FAIL)
+ return FAIL;
+ } else if (pp == &eap->force_enc) {
+ /* Make 'fileencoding' lower case. */
+ for (p = eap->cmd + eap->force_enc; *p != NUL; ++p)
+ *p = TOLOWER_ASC(*p);
+ } else {
+ /* Check ++bad= argument. Must be a single-byte character, "keep" or
+ * "drop". */
+ p = eap->cmd + bad_char_idx;
+ if (STRICMP(p, "keep") == 0)
+ eap->bad_char = BAD_KEEP;
+ else if (STRICMP(p, "drop") == 0)
+ eap->bad_char = BAD_DROP;
+ else if (MB_BYTE2LEN(*p) == 1 && p[1] == NUL)
+ eap->bad_char = *p;
+ else
+ return FAIL;
+ }
+
+ return OK;
+}
+
+/*
+ * ":abbreviate" and friends.
+ */
+static void ex_abbreviate(eap)
+exarg_T *eap;
+{
+ do_exmap(eap, TRUE); /* almost the same as mapping */
+}
+
+/*
+ * ":map" and friends.
+ */
+static void ex_map(eap)
+exarg_T *eap;
+{
+ /*
+ * If we are sourcing .exrc or .vimrc in current directory we
+ * print the mappings for security reasons.
+ */
+ if (secure) {
+ secure = 2;
+ msg_outtrans(eap->cmd);
+ msg_putchar('\n');
+ }
+ do_exmap(eap, FALSE);
+}
+
+/*
+ * ":unmap" and friends.
+ */
+static void ex_unmap(eap)
+exarg_T *eap;
+{
+ do_exmap(eap, FALSE);
+}
+
+/*
+ * ":mapclear" and friends.
+ */
+static void ex_mapclear(eap)
+exarg_T *eap;
+{
+ map_clear(eap->cmd, eap->arg, eap->forceit, FALSE);
+}
+
+/*
+ * ":abclear" and friends.
+ */
+static void ex_abclear(eap)
+exarg_T *eap;
+{
+ map_clear(eap->cmd, eap->arg, TRUE, TRUE);
+}
+
+static void ex_autocmd(eap)
+exarg_T *eap;
+{
+ /*
+ * Disallow auto commands from .exrc and .vimrc in current
+ * directory for security reasons.
+ */
+ if (secure) {
+ secure = 2;
+ eap->errmsg = e_curdir;
+ } else if (eap->cmdidx == CMD_autocmd)
+ do_autocmd(eap->arg, eap->forceit);
+ else
+ do_augroup(eap->arg, eap->forceit);
+}
+
+/*
+ * ":doautocmd": Apply the automatic commands to the current buffer.
+ */
+static void ex_doautocmd(eap)
+exarg_T *eap;
+{
+ char_u *arg = eap->arg;
+ int call_do_modelines = check_nomodeline(&arg);
+
+ (void)do_doautocmd(arg, TRUE);
+ if (call_do_modelines) /* Only when there is no <nomodeline>. */
+ do_modelines(0);
+}
+
+/*
+ * :[N]bunload[!] [N] [bufname] unload buffer
+ * :[N]bdelete[!] [N] [bufname] delete buffer from buffer list
+ * :[N]bwipeout[!] [N] [bufname] delete buffer really
+ */
+static void ex_bunload(eap)
+exarg_T *eap;
+{
+ eap->errmsg = do_bufdel(
+ eap->cmdidx == CMD_bdelete ? DOBUF_DEL
+ : eap->cmdidx == CMD_bwipeout ? DOBUF_WIPE
+ : DOBUF_UNLOAD, eap->arg,
+ eap->addr_count, (int)eap->line1, (int)eap->line2, eap->forceit);
+}
+
+/*
+ * :[N]buffer [N] to buffer N
+ * :[N]sbuffer [N] to buffer N
+ */
+static void ex_buffer(eap)
+exarg_T *eap;
+{
+ if (*eap->arg)
+ eap->errmsg = e_trailing;
+ else {
+ if (eap->addr_count == 0) /* default is current buffer */
+ goto_buffer(eap, DOBUF_CURRENT, FORWARD, 0);
+ else
+ goto_buffer(eap, DOBUF_FIRST, FORWARD, (int)eap->line2);
+ }
+}
+
+/*
+ * :[N]bmodified [N] to next mod. buffer
+ * :[N]sbmodified [N] to next mod. buffer
+ */
+static void ex_bmodified(eap)
+exarg_T *eap;
+{
+ goto_buffer(eap, DOBUF_MOD, FORWARD, (int)eap->line2);
+}
+
+/*
+ * :[N]bnext [N] to next buffer
+ * :[N]sbnext [N] split and to next buffer
+ */
+static void ex_bnext(eap)
+exarg_T *eap;
+{
+ goto_buffer(eap, DOBUF_CURRENT, FORWARD, (int)eap->line2);
+}
+
+/*
+ * :[N]bNext [N] to previous buffer
+ * :[N]bprevious [N] to previous buffer
+ * :[N]sbNext [N] split and to previous buffer
+ * :[N]sbprevious [N] split and to previous buffer
+ */
+static void ex_bprevious(eap)
+exarg_T *eap;
+{
+ goto_buffer(eap, DOBUF_CURRENT, BACKWARD, (int)eap->line2);
+}
+
+/*
+ * :brewind to first buffer
+ * :bfirst to first buffer
+ * :sbrewind split and to first buffer
+ * :sbfirst split and to first buffer
+ */
+static void ex_brewind(eap)
+exarg_T *eap;
+{
+ goto_buffer(eap, DOBUF_FIRST, FORWARD, 0);
+}
+
+/*
+ * :blast to last buffer
+ * :sblast split and to last buffer
+ */
+static void ex_blast(eap)
+exarg_T *eap;
+{
+ goto_buffer(eap, DOBUF_LAST, BACKWARD, 0);
+}
+
+int ends_excmd(c)
+int c;
+{
+ return c == NUL || c == '|' || c == '"' || c == '\n';
+}
+
+#if defined(FEAT_SYN_HL) || defined(FEAT_SEARCH_EXTRA) || defined(FEAT_EVAL) \
+ || defined(PROTO)
+/*
+ * Return the next command, after the first '|' or '\n'.
+ * Return NULL if not found.
+ */
+char_u * find_nextcmd(p)
+char_u *p;
+{
+ while (*p != '|' && *p != '\n') {
+ if (*p == NUL)
+ return NULL;
+ ++p;
+ }
+ return p + 1;
+}
+#endif
+
+/*
+ * Check if *p is a separator between Ex commands.
+ * Return NULL if it isn't, (p + 1) if it is.
+ */
+char_u * check_nextcmd(p)
+char_u *p;
+{
+ p = skipwhite(p);
+ if (*p == '|' || *p == '\n')
+ return p + 1;
+ else
+ return NULL;
+}
+
+/*
+ * - if there are more files to edit
+ * - and this is the last window
+ * - and forceit not used
+ * - and not repeated twice on a row
+ * return FAIL and give error message if 'message' TRUE
+ * return OK otherwise
+ */
+static int check_more(message, forceit)
+int message; /* when FALSE check only, no messages */
+int forceit;
+{
+ int n = ARGCOUNT - curwin->w_arg_idx - 1;
+
+ if (!forceit && only_one_window()
+ && ARGCOUNT > 1 && !arg_had_last && n >= 0 && quitmore == 0) {
+ if (message) {
+ if ((p_confirm || cmdmod.confirm) && curbuf->b_fname != NULL) {
+ char_u buff[DIALOG_MSG_SIZE];
+
+ if (n == 1)
+ vim_strncpy(buff,
+ (char_u *)_("1 more file to edit. Quit anyway?"),
+ DIALOG_MSG_SIZE - 1);
+ else
+ vim_snprintf((char *)buff, DIALOG_MSG_SIZE,
+ _("%d more files to edit. Quit anyway?"), n);
+ if (vim_dialog_yesno(VIM_QUESTION, NULL, buff, 1) == VIM_YES)
+ return OK;
+ return FAIL;
+ }
+ if (n == 1)
+ EMSG(_("E173: 1 more file to edit"));
+ else
+ EMSGN(_("E173: %ld more files to edit"), n);
+ quitmore = 2; /* next try to quit is allowed */
+ }
+ return FAIL;
+ }
+ return OK;
+}
+
+/*
+ * Function given to ExpandGeneric() to obtain the list of command names.
+ */
+char_u * get_command_name(xp, idx)
+expand_T *xp UNUSED;
+int idx;
+{
+ if (idx >= (int)CMD_SIZE)
+ return get_user_command_name(idx);
+ return cmdnames[idx].cmd_name;
+}
+
+static int uc_add_command __ARGS((char_u *name, size_t name_len, char_u *rep,
+ long argt, long def, int flags, int compl,
+ char_u *compl_arg,
+ int force));
+static void uc_list __ARGS((char_u *name, size_t name_len));
+static int uc_scan_attr __ARGS((char_u *attr, size_t len, long *argt, long *def,
+ int *flags, int *compl,
+ char_u **compl_arg));
+static char_u *uc_split_args __ARGS((char_u *arg, size_t *lenp));
+static size_t uc_check_code __ARGS((char_u *code, size_t len, char_u *buf,
+ ucmd_T *cmd, exarg_T *eap, char_u *
+ *split_buf,
+ size_t *split_len));
+
+static int uc_add_command(name, name_len, rep, argt, def, flags, compl,
+ compl_arg,
+ force)
+char_u *name;
+size_t name_len;
+char_u *rep;
+long argt;
+long def;
+int flags;
+int compl;
+char_u *compl_arg;
+int force;
+{
+ ucmd_T *cmd = NULL;
+ char_u *p;
+ int i;
+ int cmp = 1;
+ char_u *rep_buf = NULL;
+ garray_T *gap;
+
+ replace_termcodes(rep, &rep_buf, FALSE, FALSE, FALSE);
+ if (rep_buf == NULL) {
+ /* Can't replace termcodes - try using the string as is */
+ rep_buf = vim_strsave(rep);
+
+ /* Give up if out of memory */
+ if (rep_buf == NULL)
+ return FAIL;
+ }
+
+ /* get address of growarray: global or in curbuf */
+ if (flags & UC_BUFFER) {
+ gap = &curbuf->b_ucmds;
+ if (gap->ga_itemsize == 0)
+ ga_init2(gap, (int)sizeof(ucmd_T), 4);
+ } else
+ gap = &ucmds;
+
+ /* Search for the command in the already defined commands. */
+ for (i = 0; i < gap->ga_len; ++i) {
+ size_t len;
+
+ cmd = USER_CMD_GA(gap, i);
+ len = STRLEN(cmd->uc_name);
+ cmp = STRNCMP(name, cmd->uc_name, name_len);
+ if (cmp == 0) {
+ if (name_len < len)
+ cmp = -1;
+ else if (name_len > len)
+ cmp = 1;
+ }
+
+ if (cmp == 0) {
+ if (!force) {
+ EMSG(_("E174: Command already exists: add ! to replace it"));
+ goto fail;
+ }
+
+ vim_free(cmd->uc_rep);
+ cmd->uc_rep = NULL;
+ vim_free(cmd->uc_compl_arg);
+ cmd->uc_compl_arg = NULL;
+ break;
+ }
+
+ /* Stop as soon as we pass the name to add */
+ if (cmp < 0)
+ break;
+ }
+
+ /* Extend the array unless we're replacing an existing command */
+ if (cmp != 0) {
+ if (ga_grow(gap, 1) != OK)
+ goto fail;
+ if ((p = vim_strnsave(name, (int)name_len)) == NULL)
+ goto fail;
+
+ cmd = USER_CMD_GA(gap, i);
+ mch_memmove(cmd + 1, cmd, (gap->ga_len - i) * sizeof(ucmd_T));
+
+ ++gap->ga_len;
+
+ cmd->uc_name = p;
+ }
+
+ cmd->uc_rep = rep_buf;
+ cmd->uc_argt = argt;
+ cmd->uc_def = def;
+ cmd->uc_compl = compl;
+ cmd->uc_scriptID = current_SID;
+ cmd->uc_compl_arg = compl_arg;
+
+ return OK;
+
+fail:
+ vim_free(rep_buf);
+ vim_free(compl_arg);
+ return FAIL;
+}
+
+/*
+ * 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"},
+#ifdef HAVE_WORKING_LIBINTL
+ {EXPAND_LOCALES, "locale"},
+#endif
+ {EXPAND_MAPPINGS, "mapping"},
+ {EXPAND_MENUS, "menu"},
+ {EXPAND_OWNSYNTAX, "syntax"},
+ {EXPAND_SYNTIME, "syntime"},
+ {EXPAND_SETTINGS, "option"},
+ {EXPAND_SHELLCMD, "shellcmd"},
+ {EXPAND_TAGS, "tag"},
+ {EXPAND_TAGS_LISTFILES, "tag_listfiles"},
+ {EXPAND_USER, "user"},
+ {EXPAND_USER_VARS, "var"},
+ {0, NULL}
+};
+
+static void uc_list(name, name_len)
+char_u *name;
+size_t name_len;
+{
+ int i, j;
+ int found = FALSE;
+ ucmd_T *cmd;
+ int len;
+ long a;
+ garray_T *gap;
+
+ gap = &curbuf->b_ucmds;
+ for (;; ) {
+ for (i = 0; i < gap->ga_len; ++i) {
+ cmd = USER_CMD_GA(gap, i);
+ a = (long)cmd->uc_argt;
+
+ /* Skip commands which don't match the requested prefix */
+ if (STRNCMP(name, cmd->uc_name, name_len) != 0)
+ continue;
+
+ /* Put out the title first time */
+ if (!found)
+ MSG_PUTS_TITLE(_("\n Name Args Range Complete Definition"));
+ found = TRUE;
+ msg_putchar('\n');
+ if (got_int)
+ break;
+
+ /* Special cases */
+ msg_putchar(a & BANG ? '!' : ' ');
+ msg_putchar(a & REGSTR ? '"' : ' ');
+ msg_putchar(gap != &ucmds ? 'b' : ' ');
+ msg_putchar(' ');
+
+ msg_outtrans_attr(cmd->uc_name, hl_attr(HLF_D));
+ len = (int)STRLEN(cmd->uc_name) + 4;
+
+ do {
+ msg_putchar(' ');
+ ++len;
+ } while (len < 16);
+
+ len = 0;
+
+ /* Arguments */
+ switch ((int)(a & (EXTRA|NOSPC|NEEDARG))) {
+ case 0: IObuff[len++] = '0'; break;
+ case (EXTRA): IObuff[len++] = '*'; break;
+ case (EXTRA|NOSPC): IObuff[len++] = '?'; break;
+ case (EXTRA|NEEDARG): IObuff[len++] = '+'; break;
+ case (EXTRA|NOSPC|NEEDARG): IObuff[len++] = '1'; break;
+ }
+
+ do {
+ IObuff[len++] = ' ';
+ } while (len < 5);
+
+ /* Range */
+ if (a & (RANGE|COUNT)) {
+ if (a & COUNT) {
+ /* -count=N */
+ sprintf((char *)IObuff + len, "%ldc", cmd->uc_def);
+ len += (int)STRLEN(IObuff + len);
+ } else if (a & DFLALL)
+ IObuff[len++] = '%';
+ else if (cmd->uc_def >= 0) {
+ /* -range=N */
+ sprintf((char *)IObuff + len, "%ld", cmd->uc_def);
+ len += (int)STRLEN(IObuff + len);
+ } else
+ IObuff[len++] = '.';
+ }
+
+ do {
+ IObuff[len++] = ' ';
+ } while (len < 11);
+
+ /* 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;
+ }
+
+ do {
+ IObuff[len++] = ' ';
+ } while (len < 21);
+
+ IObuff[len] = '\0';
+ msg_outtrans(IObuff);
+
+ msg_outtrans_special(cmd->uc_rep, FALSE);
+ if (p_verbose > 0)
+ last_set_msg(cmd->uc_scriptID);
+ out_flush();
+ ui_breakcheck();
+ if (got_int)
+ break;
+ }
+ if (gap == &ucmds || i < gap->ga_len)
+ break;
+ gap = &ucmds;
+ }
+
+ if (!found)
+ MSG(_("No user-defined commands found"));
+}
+
+static char_u * uc_fun_cmd() {
+ 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(attr, len, argt, def, flags, compl, compl_arg)
+char_u *attr;
+size_t len;
+long *argt;
+long *def;
+int *flags;
+int *compl;
+char_u **compl_arg;
+{
+ char_u *p;
+
+ if (len == 0) {
+ EMSG(_("E175: No attribute specified"));
+ return FAIL;
+ }
+
+ /* First, try the simple attributes (no arguments) */
+ if (STRNICMP(attr, "bang", len) == 0)
+ *argt |= BANG;
+ else if (STRNICMP(attr, "buffer", len) == 0)
+ *flags |= UC_BUFFER;
+ else if (STRNICMP(attr, "register", len) == 0)
+ *argt |= REGSTR;
+ else if (STRNICMP(attr, "bar", len) == 0)
+ *argt |= TRLBAR;
+ else {
+ int i;
+ char_u *val = NULL;
+ size_t vallen = 0;
+ size_t attrlen = len;
+
+ /* Look for the attribute name - which is the part before any '=' */
+ for (i = 0; i < (int)len; ++i) {
+ if (attr[i] == '=') {
+ val = &attr[i + 1];
+ vallen = len - i - 1;
+ attrlen = i;
+ break;
+ }
+ }
+
+ if (STRNICMP(attr, "nargs", attrlen) == 0) {
+ if (vallen == 1) {
+ if (*val == '0')
+ /* Do nothing - this is the default */;
+ else if (*val == '1')
+ *argt |= (EXTRA | NOSPC | NEEDARG);
+ else if (*val == '*')
+ *argt |= EXTRA;
+ else if (*val == '?')
+ *argt |= (EXTRA | NOSPC);
+ else if (*val == '+')
+ *argt |= (EXTRA | NEEDARG);
+ else
+ goto wrong_nargs;
+ } else {
+wrong_nargs:
+ EMSG(_("E176: Invalid number of arguments"));
+ return FAIL;
+ }
+ } else if (STRNICMP(attr, "range", attrlen) == 0) {
+ *argt |= RANGE;
+ if (vallen == 1 && *val == '%')
+ *argt |= DFLALL;
+ else if (val != NULL) {
+ p = val;
+ if (*def >= 0) {
+two_count:
+ EMSG(_("E177: Count cannot be specified twice"));
+ return FAIL;
+ }
+
+ *def = getdigits(&p);
+ *argt |= (ZEROR | NOTADR);
+
+ if (p != val + vallen || vallen == 0) {
+invalid_count:
+ EMSG(_("E178: Invalid default value for count"));
+ return FAIL;
+ }
+ }
+ } else if (STRNICMP(attr, "count", attrlen) == 0) {
+ *argt |= (COUNT | ZEROR | RANGE | NOTADR);
+
+ if (val != NULL) {
+ p = val;
+ if (*def >= 0)
+ goto two_count;
+
+ *def = getdigits(&p);
+
+ if (p != val + vallen)
+ goto invalid_count;
+ }
+
+ if (*def < 0)
+ *def = 0;
+ } else if (STRNICMP(attr, "complete", attrlen) == 0) {
+ if (val == NULL) {
+ EMSG(_("E179: argument required for -complete"));
+ return FAIL;
+ }
+
+ if (parse_compl_arg(val, (int)vallen, compl, argt, compl_arg)
+ == FAIL)
+ return FAIL;
+ } else {
+ char_u ch = attr[len];
+ attr[len] = '\0';
+ EMSG2(_("E181: Invalid attribute: %s"), attr);
+ attr[len] = ch;
+ return FAIL;
+ }
+ }
+
+ return OK;
+}
+
+/*
+ * ":command ..."
+ */
+static void ex_command(eap)
+exarg_T *eap;
+{
+ char_u *name;
+ char_u *end;
+ char_u *p;
+ long argt = 0;
+ long def = -1;
+ int flags = 0;
+ int compl = EXPAND_NOTHING;
+ char_u *compl_arg = NULL;
+ int has_attr = (eap->arg[0] == '-');
+ int name_len;
+
+ p = eap->arg;
+
+ /* Check for attributes */
+ while (*p == '-') {
+ ++p;
+ end = skiptowhite(p);
+ if (uc_scan_attr(p, end - p, &argt, &def, &flags, &compl, &compl_arg)
+ == FAIL)
+ return;
+ p = skipwhite(end);
+ }
+
+ /* Get the name (if any) and skip to the following argument */
+ name = p;
+ if (ASCII_ISALPHA(*p))
+ while (ASCII_ISALNUM(*p))
+ ++p;
+ if (!ends_excmd(*p) && !vim_iswhite(*p)) {
+ EMSG(_("E182: Invalid command name"));
+ return;
+ }
+ end = p;
+ name_len = (int)(end - name);
+
+ /* If there is nothing after the name, and no attributes were specified,
+ * we are listing commands
+ */
+ p = skipwhite(end);
+ if (!has_attr && ends_excmd(*p)) {
+ uc_list(name, end - name);
+ } else if (!ASCII_ISUPPER(*name)) {
+ 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)) {
+ EMSG(_("E841: Reserved name, cannot be used for user defined command"));
+ return;
+ } else
+ uc_add_command(name, end - name, p, argt, def, flags, compl, compl_arg,
+ eap->forceit);
+}
+
+/*
+ * ":comclear"
+ * Clear all user commands, global and for current buffer.
+ */
+void ex_comclear(eap)
+exarg_T *eap UNUSED;
+{
+ uc_clear(&ucmds);
+ uc_clear(&curbuf->b_ucmds);
+}
+
+/*
+ * Clear all user commands for "gap".
+ */
+void uc_clear(gap)
+garray_T *gap;
+{
+ int i;
+ ucmd_T *cmd;
+
+ for (i = 0; i < gap->ga_len; ++i) {
+ cmd = USER_CMD_GA(gap, i);
+ vim_free(cmd->uc_name);
+ vim_free(cmd->uc_rep);
+ vim_free(cmd->uc_compl_arg);
+ }
+ ga_clear(gap);
+}
+
+static void ex_delcommand(eap)
+exarg_T *eap;
+{
+ int i = 0;
+ ucmd_T *cmd = NULL;
+ int cmp = -1;
+ garray_T *gap;
+
+ gap = &curbuf->b_ucmds;
+ for (;; ) {
+ for (i = 0; i < gap->ga_len; ++i) {
+ cmd = USER_CMD_GA(gap, i);
+ cmp = STRCMP(eap->arg, cmd->uc_name);
+ if (cmp <= 0)
+ break;
+ }
+ if (gap == &ucmds || cmp == 0)
+ break;
+ gap = &ucmds;
+ }
+
+ if (cmp != 0) {
+ EMSG2(_("E184: No such user-defined command: %s"), eap->arg);
+ return;
+ }
+
+ vim_free(cmd->uc_name);
+ vim_free(cmd->uc_rep);
+ vim_free(cmd->uc_compl_arg);
+
+ --gap->ga_len;
+
+ if (i < gap->ga_len)
+ mch_memmove(cmd, cmd + 1, (gap->ga_len - i) * sizeof(ucmd_T));
+}
+
+/*
+ * split and quote args for <f-args>
+ */
+static char_u * uc_split_args(arg, lenp)
+char_u *arg;
+size_t *lenp;
+{
+ char_u *buf;
+ char_u *p;
+ char_u *q;
+ int len;
+
+ /* Precalculate length */
+ p = arg;
+ len = 2; /* Initial and final quotes */
+
+ while (*p) {
+ if (p[0] == '\\' && p[1] == '\\') {
+ len += 2;
+ p += 2;
+ } else if (p[0] == '\\' && vim_iswhite(p[1])) {
+ len += 1;
+ p += 2;
+ } else if (*p == '\\' || *p == '"') {
+ len += 2;
+ p += 1;
+ } else if (vim_iswhite(*p)) {
+ p = skipwhite(p);
+ if (*p == NUL)
+ break;
+ len += 3; /* "," */
+ } else {
+ int charlen = (*mb_ptr2len)(p);
+ len += charlen;
+ p += charlen;
+ }
+ }
+
+ buf = alloc(len + 1);
+ if (buf == NULL) {
+ *lenp = 0;
+ return buf;
+ }
+
+ p = arg;
+ q = buf;
+ *q++ = '"';
+ while (*p) {
+ if (p[0] == '\\' && p[1] == '\\') {
+ *q++ = '\\';
+ *q++ = '\\';
+ p += 2;
+ } else if (p[0] == '\\' && vim_iswhite(p[1])) {
+ *q++ = p[1];
+ p += 2;
+ } else if (*p == '\\' || *p == '"') {
+ *q++ = '\\';
+ *q++ = *p++;
+ } else if (vim_iswhite(*p)) {
+ p = skipwhite(p);
+ if (*p == NUL)
+ break;
+ *q++ = '"';
+ *q++ = ',';
+ *q++ = '"';
+ } else {
+ MB_COPY_CHAR(p, q);
+ }
+ }
+ *q++ = '"';
+ *q = 0;
+
+ *lenp = len;
+ return buf;
+}
+
+/*
+ * Check for a <> code in a user command.
+ * "code" points to the '<'. "len" the length of the <> (inclusive).
+ * "buf" is where the result is to be added.
+ * "split_buf" points to a buffer used for splitting, caller should free it.
+ * "split_len" is the length of what "split_buf" contains.
+ * 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(code, len, buf, cmd, eap, split_buf, split_len)
+char_u *code;
+size_t len;
+char_u *buf;
+ucmd_T *cmd; /* the user command we're expanding */
+exarg_T *eap; /* ex arguments */
+char_u **split_buf;
+size_t *split_len;
+{
+ size_t result = 0;
+ 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;
+
+ if ((vim_strchr((char_u *)"qQfF", *p) != NULL) && p[1] == '-') {
+ quote = (*p == 'q' || *p == 'Q') ? 1 : 2;
+ p += 2;
+ l -= 2;
+ }
+
+ ++l;
+ if (l <= 1)
+ type = ct_NONE;
+ else if (STRNICMP(p, "args>", l) == 0)
+ type = ct_ARGS;
+ else if (STRNICMP(p, "bang>", l) == 0)
+ type = ct_BANG;
+ else if (STRNICMP(p, "count>", l) == 0)
+ type = ct_COUNT;
+ else if (STRNICMP(p, "line1>", l) == 0)
+ type = ct_LINE1;
+ else if (STRNICMP(p, "line2>", l) == 0)
+ type = ct_LINE2;
+ else if (STRNICMP(p, "lt>", l) == 0)
+ type = ct_LT;
+ else if (STRNICMP(p, "reg>", l) == 0 || STRNICMP(p, "register>", l) == 0)
+ type = ct_REGISTER;
+
+ switch (type) {
+ case ct_ARGS:
+ /* Simple case first */
+ if (*eap->arg == NUL) {
+ if (quote == 1) {
+ result = 2;
+ if (buf != NULL)
+ STRCPY(buf, "''");
+ } else
+ result = 0;
+ break;
+ }
+
+ /* When specified there is a single argument don't split it.
+ * Works for ":Cmd %" when % is "a b c". */
+ if ((eap->argt & NOSPC) && quote == 2)
+ quote = 1;
+
+ switch (quote) {
+ case 0: /* No quoting, no splitting */
+ result = STRLEN(eap->arg);
+ if (buf != NULL)
+ STRCPY(buf, eap->arg);
+ break;
+ case 1: /* Quote, but don't split */
+ result = STRLEN(eap->arg) + 2;
+ for (p = eap->arg; *p; ++p) {
+ if (enc_dbcs != 0 && (*mb_ptr2len)(p) == 2)
+ /* DBCS can contain \ in a trail byte, skip the
+ * double-byte character. */
+ ++p;
+ else if (*p == '\\' || *p == '"')
+ ++result;
+ }
+
+ if (buf != NULL) {
+ *buf++ = '"';
+ for (p = eap->arg; *p; ++p) {
+ if (enc_dbcs != 0 && (*mb_ptr2len)(p) == 2)
+ /* DBCS can contain \ in a trail byte, copy the
+ * double-byte character to avoid escaping. */
+ *buf++ = *p++;
+ else if (*p == '\\' || *p == '"')
+ *buf++ = '\\';
+ *buf++ = *p;
+ }
+ *buf = '"';
+ }
+
+ break;
+ case 2: /* Quote and split (<f-args>) */
+ /* This is hard, so only do it once, and cache the result */
+ if (*split_buf == NULL)
+ *split_buf = uc_split_args(eap->arg, split_len);
+
+ result = *split_len;
+ if (buf != NULL && result != 0)
+ STRCPY(buf, *split_buf);
+
+ break;
+ }
+ break;
+
+ case ct_BANG:
+ result = eap->forceit ? 1 : 0;
+ if (quote)
+ result += 2;
+ if (buf != NULL) {
+ if (quote)
+ *buf++ = '"';
+ if (eap->forceit)
+ *buf++ = '!';
+ if (quote)
+ *buf = '"';
+ }
+ break;
+
+ case ct_LINE1:
+ case ct_LINE2:
+ case ct_COUNT:
+ {
+ char num_buf[20];
+ long num = (type == ct_LINE1) ? eap->line1 :
+ (type == ct_LINE2) ? eap->line2 :
+ (eap->addr_count > 0) ? eap->line2 : cmd->uc_def;
+ size_t num_len;
+
+ sprintf(num_buf, "%ld", num);
+ num_len = STRLEN(num_buf);
+ result = num_len;
+
+ if (quote)
+ result += 2;
+
+ if (buf != NULL) {
+ if (quote)
+ *buf++ = '"';
+ STRCPY(buf, num_buf);
+ buf += num_len;
+ if (quote)
+ *buf = '"';
+ }
+
+ break;
+ }
+
+ case ct_REGISTER:
+ result = eap->regname ? 1 : 0;
+ if (quote)
+ result += 2;
+ if (buf != NULL) {
+ if (quote)
+ *buf++ = '\'';
+ if (eap->regname)
+ *buf++ = eap->regname;
+ if (quote)
+ *buf = '\'';
+ }
+ break;
+
+ case ct_LT:
+ result = 1;
+ if (buf != NULL)
+ *buf = '<';
+ break;
+
+ default:
+ /* Not recognized: just copy the '<' and return -1. */
+ result = (size_t)-1;
+ if (buf != NULL)
+ *buf = '<';
+ break;
+ }
+
+ return result;
+}
+
+static void do_ucmd(eap)
+exarg_T *eap;
+{
+ char_u *buf;
+ char_u *p;
+ char_u *q;
+
+ char_u *start;
+ char_u *end = NULL;
+ char_u *ksp;
+ size_t len, totlen;
+
+ size_t split_len = 0;
+ char_u *split_buf = NULL;
+ ucmd_T *cmd;
+ scid_T save_current_SID = current_SID;
+
+ if (eap->cmdidx == CMD_USER)
+ cmd = USER_CMD(eap->useridx);
+ else
+ cmd = USER_CMD_GA(&curbuf->b_ucmds, eap->useridx);
+
+ /*
+ * Replace <> in the command by the arguments.
+ * First round: "buf" is NULL, compute length, allocate "buf".
+ * Second round: copy result into "buf".
+ */
+ buf = NULL;
+ for (;; ) {
+ p = cmd->uc_rep; /* source */
+ q = buf; /* destination */
+ totlen = 0;
+
+ for (;; ) {
+ start = vim_strchr(p, '<');
+ if (start != NULL)
+ end = vim_strchr(start + 1, '>');
+ if (buf != NULL) {
+ 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. */
+ len = ksp - p;
+ if (len > 0) {
+ mch_memmove(q, p, len);
+ q += len;
+ }
+ *q++ = ksp[1] == KS_SPECIAL ? K_SPECIAL : CSI;
+ p = ksp + 3;
+ continue;
+ }
+ }
+
+ /* break if there no <item> is found */
+ if (start == NULL || end == NULL)
+ break;
+
+ /* Include the '>' */
+ ++end;
+
+ /* Take everything up to the '<' */
+ len = start - p;
+ if (buf == NULL)
+ totlen += len;
+ else {
+ mch_memmove(q, p, len);
+ q += len;
+ }
+
+ len = uc_check_code(start, end - start, q, cmd, eap,
+ &split_buf, &split_len);
+ if (len == (size_t)-1) {
+ /* no match, continue after '<' */
+ p = start + 1;
+ len = 1;
+ } else
+ p = end;
+ if (buf == NULL)
+ totlen += len;
+ else
+ q += len;
+ }
+ if (buf != NULL) { /* second time here, finished */
+ STRCPY(q, p);
+ break;
+ }
+
+ totlen += STRLEN(p); /* Add on the trailing characters */
+ buf = alloc((unsigned)(totlen + 1));
+ if (buf == NULL) {
+ vim_free(split_buf);
+ return;
+ }
+ }
+
+ current_SID = cmd->uc_scriptID;
+ (void)do_cmdline(buf, eap->getline, eap->cookie,
+ DOCMD_VERBOSE|DOCMD_NOWAIT|DOCMD_KEYTYPED);
+ current_SID = save_current_SID;
+ vim_free(buf);
+ vim_free(split_buf);
+}
+
+static char_u * get_user_command_name(idx)
+int idx;
+{
+ return get_user_commands(NULL, idx - (int)CMD_SIZE);
+}
+
+/*
+ * Function given to ExpandGeneric() to obtain the list of user command names.
+ */
+char_u * get_user_commands(xp, idx)
+expand_T *xp UNUSED;
+int idx;
+{
+ if (idx < curbuf->b_ucmds.ga_len)
+ return USER_CMD_GA(&curbuf->b_ucmds, idx)->uc_name;
+ idx -= curbuf->b_ucmds.ga_len;
+ if (idx < ucmds.ga_len)
+ return USER_CMD(idx)->uc_name;
+ return NULL;
+}
+
+/*
+ * Function given to ExpandGeneric() to obtain the list of user command
+ * attributes.
+ */
+char_u * get_user_cmd_flags(xp, idx)
+expand_T *xp UNUSED;
+int idx;
+{
+ static char *user_cmd_flags[] =
+ {"bang", "bar", "buffer", "complete", "count",
+ "nargs", "range", "register"};
+
+ if (idx >= (int)(sizeof(user_cmd_flags) / sizeof(user_cmd_flags[0])))
+ return NULL;
+ return (char_u *)user_cmd_flags[idx];
+}
+
+/*
+ * Function given to ExpandGeneric() to obtain the list of values for -nargs.
+ */
+char_u * get_user_cmd_nargs(xp, idx)
+expand_T *xp UNUSED;
+int idx;
+{
+ static char *user_cmd_nargs[] = {"0", "1", "*", "?", "+"};
+
+ if (idx >= (int)(sizeof(user_cmd_nargs) / sizeof(user_cmd_nargs[0])))
+ return NULL;
+ return (char_u *)user_cmd_nargs[idx];
+}
+
+/*
+ * Function given to ExpandGeneric() to obtain the list of values for -complete.
+ */
+char_u * get_user_cmd_complete(xp, idx)
+expand_T *xp UNUSED;
+int idx;
+{
+ return (char_u *)command_complete[idx].name;
+}
+
+
+/*
+ * Parse a completion argument "value[vallen]".
+ * The detected completion goes in "*complp", argument type in "*argt".
+ * When there is an argument, for function and user defined completion, it's
+ * copied to allocated memory and stored in "*compl_arg".
+ * Returns FAIL if something is wrong.
+ */
+int parse_compl_arg(value, vallen, complp, argt, compl_arg)
+char_u *value;
+int vallen;
+int *complp;
+long *argt;
+char_u **compl_arg UNUSED;
+{
+ char_u *arg = NULL;
+ size_t arglen = 0;
+ int i;
+ int valend = vallen;
+
+ /* Look for any argument part - which is the part after any ',' */
+ for (i = 0; i < vallen; ++i) {
+ if (value[i] == ',') {
+ arg = &value[i + 1];
+ arglen = vallen - i - 1;
+ valend = i;
+ break;
+ }
+ }
+
+ 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)
+ *argt |= BUFNAME;
+ else if (command_complete[i].expand == EXPAND_DIRECTORIES
+ || command_complete[i].expand == EXPAND_FILES)
+ *argt |= XFILE;
+ break;
+ }
+ }
+
+ if (command_complete[i].expand == 0) {
+ EMSG2(_("E180: Invalid complete value: %s"), value);
+ return FAIL;
+ }
+
+ if (*complp != EXPAND_USER_DEFINED && *complp != EXPAND_USER_LIST
+ && arg != NULL) {
+ EMSG(_("E468: Completion argument only allowed for custom completion"));
+ return FAIL;
+ }
+
+ if ((*complp == EXPAND_USER_DEFINED || *complp == EXPAND_USER_LIST)
+ && arg == NULL) {
+ EMSG(_("E467: Custom completion requires a function argument"));
+ return FAIL;
+ }
+
+ if (arg != NULL)
+ *compl_arg = vim_strnsave(arg, (int)arglen);
+ return OK;
+}
+
+static void ex_colorscheme(eap)
+exarg_T *eap;
+{
+ if (*eap->arg == NUL) {
+ char_u *expr = vim_strsave((char_u *)"g:colors_name");
+ char_u *p = NULL;
+
+ if (expr != NULL) {
+ ++emsg_off;
+ p = eval_to_string(expr, NULL, FALSE);
+ --emsg_off;
+ vim_free(expr);
+ }
+ if (p != NULL) {
+ MSG(p);
+ vim_free(p);
+ } else
+ MSG("default");
+ } else if (load_colors(eap->arg) == FAIL)
+ EMSG2(_("E185: Cannot find color scheme '%s'"), eap->arg);
+}
+
+static void ex_highlight(eap)
+exarg_T *eap;
+{
+ if (*eap->arg == NUL && eap->cmd[2] == '!')
+ MSG(_("Greetings, Vim user!"));
+ do_highlight(eap->arg, eap->forceit, FALSE);
+}
+
+
+/*
+ * Call this function if we thought we were going to exit, but we won't
+ * (because of an error). May need to restore the terminal mode.
+ */
+void not_exiting() {
+ exiting = FALSE;
+ settmode(TMODE_RAW);
+}
+
+/*
+ * ":quit": quit current window, quit Vim if closed the last window.
+ */
+static void ex_quit(eap)
+exarg_T *eap;
+{
+ if (cmdwin_type != 0) {
+ cmdwin_result = Ctrl_C;
+ return;
+ }
+ /* Don't quit while editing the command line. */
+ if (text_locked()) {
+ 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))
+ 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)
+ | (eap->forceit ? CCGD_FORCEIT : 0)
+ | CCGD_EXCMD))
+ || check_more(TRUE, eap->forceit) == FAIL
+ || (only_one_window() && check_changed_any(eap->forceit))) {
+ not_exiting();
+ } else {
+ if (only_one_window()) /* quit last window */
+ getout(0);
+ /* close window; may free buffer */
+ win_close(curwin, !P_HID(curwin->w_buffer) || eap->forceit);
+ }
+}
+
+/*
+ * ":cquit".
+ */
+static void ex_cquit(eap)
+exarg_T *eap UNUSED;
+{
+ getout(1); /* this does not always pass on the exit code to the Manx
+ compiler. why? */
+}
+
+/*
+ * ":qall": try to quit all windows
+ */
+static void ex_quit_all(eap)
+exarg_T *eap;
+{
+ if (cmdwin_type != 0) {
+ if (eap->forceit)
+ cmdwin_result = K_XF1; /* ex_window() takes care of this */
+ else
+ cmdwin_result = K_XF2;
+ return;
+ }
+
+ /* Don't quit while editing the command line. */
+ if (text_locked()) {
+ 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))
+ return;
+
+ exiting = TRUE;
+ if (eap->forceit || !check_changed_any(FALSE))
+ getout(0);
+ not_exiting();
+}
+
+/*
+ * ":close": close current window, unless it is the last one
+ */
+static void ex_close(eap)
+exarg_T *eap;
+{
+ if (cmdwin_type != 0)
+ cmdwin_result = Ctrl_C;
+ else if (!text_locked()
+ && !curbuf_locked()
+ )
+ ex_win_close(eap->forceit, curwin, NULL);
+}
+
+/*
+ * ":pclose": Close any preview window.
+ */
+static void ex_pclose(eap)
+exarg_T *eap;
+{
+ win_T *win;
+
+ for (win = firstwin; win != NULL; win = win->w_next)
+ if (win->w_p_pvw) {
+ ex_win_close(eap->forceit, win, NULL);
+ break;
+ }
+}
+
+/*
+ * Close window "win" and take care of handling closing the last window for a
+ * modified buffer.
+ */
+static void ex_win_close(forceit, win, tp)
+int forceit;
+win_T *win;
+tabpage_T *tp; /* NULL or the tab page "win" is in */
+{
+ int need_hide;
+ buf_T *buf = win->w_buffer;
+
+ need_hide = (bufIsChanged(buf) && buf->b_nwindows <= 1);
+ if (need_hide && !P_HID(buf) && !forceit) {
+ if ((p_confirm || cmdmod.confirm) && p_write) {
+ dialog_changed(buf, FALSE);
+ if (buf_valid(buf) && bufIsChanged(buf))
+ return;
+ need_hide = FALSE;
+ } else {
+ EMSG(_(e_nowrtmsg));
+ return;
+ }
+ }
+
+
+ /* 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);
+}
+
+/*
+ * ":tabclose": close current tab page, unless it is the last one.
+ * ":tabclose N": close tab page N.
+ */
+static void ex_tabclose(eap)
+exarg_T *eap;
+{
+ tabpage_T *tp;
+
+ if (cmdwin_type != 0)
+ cmdwin_result = K_IGNORE;
+ 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);
+ if (tp == NULL) {
+ beep_flush();
+ return;
+ }
+ if (tp != curtab) {
+ tabpage_close_other(tp, eap->forceit);
+ return;
+ }
+ }
+ if (!text_locked()
+ && !curbuf_locked()
+ )
+ tabpage_close(eap->forceit);
+ }
+}
+
+/*
+ * ":tabonly": close all tab pages except the current one
+ */
+static void ex_tabonly(eap)
+exarg_T *eap;
+{
+ tabpage_T *tp;
+ int done;
+
+ if (cmdwin_type != 0)
+ cmdwin_result = K_IGNORE;
+ else if (first_tabpage->tp_next == NULL)
+ MSG(_("Already only one tab page"));
+ else {
+ /* Repeat this up to a 1000 times, because autocommands may mess
+ * up the lists. */
+ for (done = 0; done < 1000; ++done) {
+ for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
+ 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;
+ }
+ if (first_tabpage->tp_next == NULL)
+ break;
+ }
+ }
+}
+
+/*
+ * Close the current tab page.
+ */
+void tabpage_close(forceit)
+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)
+ ex_win_close(forceit, curwin, NULL);
+}
+
+/*
+ * Close tab page "tp", which is not the current tab page.
+ * Note that autocommands may make "tp" invalid.
+ * Also takes care of the tab pages line disappearing when closing the
+ * last-but-one tab page.
+ */
+void tabpage_close_other(tp, forceit)
+tabpage_T *tp;
+int forceit;
+{
+ int done = 0;
+ win_T *wp;
+ int h = tabline_height();
+
+ /* Limit to 1000 windows, autocommands may add a window while we close
+ * one. OK, so I'm paranoid... */
+ while (++done < 1000) {
+ wp = tp->tp_firstwin;
+ ex_win_close(forceit, wp, tp);
+
+ /* Autocommands may delete the tab page under our fingers and we may
+ * fail to close a window with a modified buffer. */
+ if (!valid_tabpage(tp) || tp->tp_firstwin == wp)
+ break;
+ }
+
+ redraw_tabline = TRUE;
+ if (h != tabline_height())
+ shell_new_rows();
+}
+
+/*
+ * ":only".
+ */
+static void ex_only(eap)
+exarg_T *eap;
+{
+ close_others(TRUE, eap->forceit);
+}
+
+/*
+ * ":all" and ":sall".
+ * Also used for ":tab drop file ..." after setting the argument list.
+ */
+void ex_all(eap)
+exarg_T *eap;
+{
+ if (eap->addr_count == 0)
+ eap->line2 = 9999;
+ do_arg_all((int)eap->line2, eap->forceit, eap->cmdidx == CMD_drop);
+}
+
+static void ex_hide(eap)
+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);
+ if (!eap->skip) {
+ win_close(curwin, FALSE); /* don't free buffer */
+ }
+ }
+}
+
+/*
+ * ":stop" and ":suspend": Suspend Vim.
+ */
+static void ex_stop(eap)
+exarg_T *eap;
+{
+ /*
+ * Disallow suspending for "rvim".
+ */
+ if (!check_restricted()
+ ) {
+ if (!eap->forceit)
+ autowrite_all();
+ windgoto((int)Rows - 1, 0);
+ out_char('\n');
+ out_flush();
+ stoptermcap();
+ out_flush(); /* needed for SUN to restore xterm buffer */
+ mch_restore_title(3); /* restore window titles */
+ ui_suspend(); /* call machine specific function */
+ maketitle();
+ resettitle(); /* force updating the title */
+ starttermcap();
+ scroll_start(); /* scroll screen before redrawing */
+ redraw_later_clear();
+ shell_resized(); /* may have resized window */
+ }
+}
+
+/*
+ * ":exit", ":xit" and ":wq": Write file and exit Vim.
+ */
+static void ex_exit(eap)
+exarg_T *eap;
+{
+ if (cmdwin_type != 0) {
+ cmdwin_result = Ctrl_C;
+ return;
+ }
+ /* Don't quit while editing the command line. */
+ if (text_locked()) {
+ 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))
+ return;
+
+ /*
+ * if more files or windows we won't exit
+ */
+ if (check_more(FALSE, eap->forceit) == OK && only_one_window())
+ exiting = TRUE;
+ if ( ((eap->cmdidx == CMD_wq
+ || curbufIsChanged())
+ && do_write(eap) == FAIL)
+ || check_more(TRUE, eap->forceit) == FAIL
+ || (only_one_window() && check_changed_any(eap->forceit))) {
+ not_exiting();
+ } else {
+ if (only_one_window()) /* quit last window, exit Vim */
+ getout(0);
+ /* Quit current window, may free the buffer. */
+ win_close(curwin, !P_HID(curwin->w_buffer));
+ }
+}
+
+/*
+ * ":print", ":list", ":number".
+ */
+static void ex_print(eap)
+exarg_T *eap;
+{
+ if (curbuf->b_ml.ml_flags & ML_EMPTY)
+ EMSG(_(e_emptybuf));
+ else {
+ for (; !got_int; ui_breakcheck()) {
+ print_line(eap->line1,
+ (eap->cmdidx == CMD_number || eap->cmdidx == CMD_pound
+ || (eap->flags & EXFLAG_NR)),
+ eap->cmdidx == CMD_list || (eap->flags & EXFLAG_LIST));
+ if (++eap->line1 > eap->line2)
+ break;
+ out_flush(); /* show one line at a time */
+ }
+ setpcmark();
+ /* put cursor at last line */
+ curwin->w_cursor.lnum = eap->line2;
+ beginline(BL_SOL | BL_FIX);
+ }
+
+ ex_no_reprint = TRUE;
+}
+
+static void ex_goto(eap)
+exarg_T *eap;
+{
+ goto_byte(eap->line2);
+}
+
+/*
+ * ":shell".
+ */
+static void ex_shell(eap)
+exarg_T *eap UNUSED;
+{
+ do_shell(NULL, 0);
+}
+
+#if (defined(FEAT_WINDOWS) && defined(HAVE_DROP_FILE)) \
+ || (defined(FEAT_GUI_GTK) && defined(FEAT_DND)) \
+ || defined(FEAT_GUI_MSWIN) \
+ || defined(FEAT_GUI_MAC) \
+ || defined(PROTO)
+
+/*
+ * Handle a file drop. The code is here because a drop is *nearly* like an
+ * :args command, but not quite (we have a list of exact filenames, so we
+ * don't want to (a) parse a command line, or (b) expand wildcards. So the
+ * code is very similar to :args and hence needs access to a lot of the static
+ * functions in this file.
+ *
+ * The list should be allocated using alloc(), as should each item in the
+ * list. This function takes over responsibility for freeing the list.
+ *
+ * XXX The list is made into the argument list. This is freed using
+ * FreeWild(), which does a series of vim_free() calls, unless the two defines
+ * __EMX__ and __ALWAYS_HAS_TRAILING_NUL_POINTER are set. In this case, a
+ * routine _fnexplodefree() is used. This may cause problems, but as the drop
+ * file functionality is (currently) not in EMX this is not presently a
+ * problem.
+ */
+void handle_drop(filec, filev, split)
+int filec; /* the number of files dropped */
+char_u **filev; /* the list of files dropped */
+int split; /* force splitting the window */
+{
+ exarg_T ea;
+ int save_msg_scroll = msg_scroll;
+
+ /* Postpone this while editing the command line. */
+ if (text_locked())
+ return;
+ if (curbuf_locked())
+ return;
+ /* When the screen is being updated we should not change buffers and
+ * windows structures, it may cause freed memory to be used. */
+ if (updating_screen)
+ return;
+
+ /* Check whether the current buffer is changed. If so, we will need
+ * to split the current window or data could be lost.
+ * We don't need to check if the 'hidden' option is set, as in this
+ * case the buffer won't be lost.
+ */
+ if (!P_HID(curbuf) && !split) {
+ ++emsg_off;
+ split = check_changed(curbuf, CCGD_AW);
+ --emsg_off;
+ }
+ if (split) {
+ if (win_split(0, 0) == FAIL)
+ return;
+ RESET_BINDING(curwin);
+
+ /* When splitting the window, create a new alist. Otherwise the
+ * existing one is overwritten. */
+ alist_unlink(curwin->w_alist);
+ alist_new();
+ }
+
+ /*
+ * Set up the new argument list.
+ */
+ alist_set(ALIST(curwin), filec, filev, FALSE, NULL, 0);
+
+ /*
+ * Move to the first file.
+ */
+ /* Fake up a minimal "next" command for do_argfile() */
+ vim_memset(&ea, 0, sizeof(ea));
+ ea.cmd = (char_u *)"next";
+ do_argfile(&ea, 0);
+
+ /* do_ecmd() may set need_start_insertmode, but since we never left Insert
+ * mode that is not needed here. */
+ need_start_insertmode = FALSE;
+
+ /* Restore msg_scroll, otherwise a following command may cause scrolling
+ * unexpectedly. The screen will be redrawn by the caller, thus
+ * msg_scroll being set by displaying a message is irrelevant. */
+ msg_scroll = save_msg_scroll;
+}
+#endif
+
+/*
+ * Clear an argument list: free all file names and reset it to zero entries.
+ */
+void alist_clear(al)
+alist_T *al;
+{
+ while (--al->al_ga.ga_len >= 0)
+ vim_free(AARGLIST(al)[al->al_ga.ga_len].ae_fname);
+ ga_clear(&al->al_ga);
+}
+
+/*
+ * Init an argument list.
+ */
+void alist_init(al)
+alist_T *al;
+{
+ ga_init2(&al->al_ga, (int)sizeof(aentry_T), 5);
+}
+
+
+/*
+ * Remove a reference from an argument list.
+ * Ignored when the argument list is the global one.
+ * If the argument list is no longer used by any window, free it.
+ */
+void alist_unlink(al)
+alist_T *al;
+{
+ if (al != &global_alist && --al->al_refcount <= 0) {
+ alist_clear(al);
+ vim_free(al);
+ }
+}
+
+/*
+ * Create a new argument list and use it for the current window.
+ */
+void alist_new() {
+ curwin->w_alist = (alist_T *)alloc((unsigned)sizeof(alist_T));
+ if (curwin->w_alist == NULL) {
+ curwin->w_alist = &global_alist;
+ ++global_alist.al_refcount;
+ } else {
+ curwin->w_alist->al_refcount = 1;
+ alist_init(curwin->w_alist);
+ }
+}
+
+#if (!defined(UNIX) && !defined(__EMX__)) || defined(ARCHIE) || defined(PROTO)
+/*
+ * Expand the file names in the global argument list.
+ * If "fnum_list" is not NULL, use "fnum_list[fnum_len]" as a list of buffer
+ * numbers to be re-used.
+ */
+void alist_expand(fnum_list, fnum_len)
+int *fnum_list;
+int fnum_len;
+{
+ char_u **old_arg_files;
+ int old_arg_count;
+ char_u **new_arg_files;
+ int new_arg_file_count;
+ char_u *save_p_su = p_su;
+ int i;
+
+ /* Don't use 'suffixes' here. This should work like the shell did the
+ * expansion. Also, the vimrc file isn't read yet, thus the user
+ * can't set the options. */
+ p_su = empty_option;
+ old_arg_files = (char_u **)alloc((unsigned)(sizeof(char_u *) * GARGCOUNT));
+ if (old_arg_files != NULL) {
+ for (i = 0; i < GARGCOUNT; ++i)
+ old_arg_files[i] = vim_strsave(GARGLIST[i].ae_fname);
+ old_arg_count = GARGCOUNT;
+ if (expand_wildcards(old_arg_count, old_arg_files,
+ &new_arg_file_count, &new_arg_files,
+ EW_FILE|EW_NOTFOUND|EW_ADDSLASH|EW_NOERROR) == OK
+ && new_arg_file_count > 0) {
+ alist_set(&global_alist, new_arg_file_count, new_arg_files,
+ TRUE, fnum_list, fnum_len);
+ FreeWild(old_arg_count, old_arg_files);
+ }
+ }
+ p_su = save_p_su;
+}
+#endif
+
+/*
+ * Set the argument list for the current window.
+ * Takes over the allocated files[] and the allocated fnames in it.
+ */
+void alist_set(al, count, files, use_curbuf, fnum_list, fnum_len)
+alist_T *al;
+int count;
+char_u **files;
+int use_curbuf;
+int *fnum_list;
+int fnum_len;
+{
+ int i;
+
+ alist_clear(al);
+ if (ga_grow(&al->al_ga, count) == OK) {
+ for (i = 0; i < count; ++i) {
+ if (got_int) {
+ /* When adding many buffers this can take a long time. Allow
+ * interrupting here. */
+ while (i < count)
+ vim_free(files[i++]);
+ break;
+ }
+
+ /* May set buffer name of a buffer previously used for the
+ * argument list, so that it's re-used by alist_add. */
+ if (fnum_list != NULL && i < fnum_len)
+ buf_set_name(fnum_list[i], files[i]);
+
+ alist_add(al, files[i], use_curbuf ? 2 : 1);
+ ui_breakcheck();
+ }
+ vim_free(files);
+ } else
+ FreeWild(count, files);
+ if (al == &global_alist)
+ arg_had_last = FALSE;
+}
+
+/*
+ * Add file "fname" to argument list "al".
+ * "fname" must have been allocated and "al" must have been checked for room.
+ */
+void alist_add(al, fname, set_fnum)
+alist_T *al;
+char_u *fname;
+int set_fnum; /* 1: set buffer number; 2: re-use curbuf */
+{
+ if (fname == NULL) /* don't add NULL file names */
+ return;
+#ifdef BACKSLASH_IN_FILENAME
+ slash_adjust(fname);
+#endif
+ AARGLIST(al)[al->al_ga.ga_len].ae_fname = fname;
+ if (set_fnum > 0)
+ AARGLIST(al)[al->al_ga.ga_len].ae_fnum =
+ buflist_add(fname, BLN_LISTED | (set_fnum == 2 ? BLN_CURBUF : 0));
+ ++al->al_ga.ga_len;
+}
+
+#if defined(BACKSLASH_IN_FILENAME) || defined(PROTO)
+/*
+ * Adjust slashes in file names. Called after 'shellslash' was set.
+ */
+void alist_slash_adjust() {
+ int i;
+ win_T *wp;
+ tabpage_T *tp;
+
+ for (i = 0; i < GARGCOUNT; ++i)
+ if (GARGLIST[i].ae_fname != NULL)
+ slash_adjust(GARGLIST[i].ae_fname);
+ FOR_ALL_TAB_WINDOWS(tp, wp)
+ if (wp->w_alist != &global_alist)
+ for (i = 0; i < WARGCOUNT(wp); ++i)
+ if (WARGLIST(wp)[i].ae_fname != NULL)
+ slash_adjust(WARGLIST(wp)[i].ae_fname);
+}
+
+#endif
+
+/*
+ * ":preserve".
+ */
+static void ex_preserve(eap)
+exarg_T *eap UNUSED;
+{
+ curbuf->b_flags |= BF_PRESERVED;
+ ml_preserve(curbuf, TRUE);
+}
+
+/*
+ * ":recover".
+ */
+static void ex_recover(eap)
+exarg_T *eap;
+{
+ /* Set recoverymode right away to avoid the ATTENTION prompt. */
+ recoverymode = TRUE;
+ if (!check_changed(curbuf, (p_awa ? CCGD_AW : 0)
+ | CCGD_MULTWIN
+ | (eap->forceit ? CCGD_FORCEIT : 0)
+ | CCGD_EXCMD)
+
+ && (*eap->arg == NUL
+ || setfname(curbuf, eap->arg, NULL, TRUE) == OK))
+ ml_recover();
+ recoverymode = FALSE;
+}
+
+/*
+ * Command modifier used in a wrong way.
+ */
+static void ex_wrongmodifier(eap)
+exarg_T *eap;
+{
+ eap->errmsg = e_invcmd;
+}
+
+/*
+ * :sview [+command] file split window with new file, read-only
+ * :split [[+command] file] split window with current or new file
+ * :vsplit [[+command] file] split window vertically with current or new file
+ * :new [[+command] file] split window with no or new file
+ * :vnew [[+command] file] split vertically window with no or new file
+ * :sfind [+command] file split window with file in 'path'
+ *
+ * :tabedit open new Tab page with empty window
+ * :tabedit [+command] file open new Tab page and edit "file"
+ * :tabnew [[+command] file] just like :tabedit
+ * :tabfind [+command] file open new Tab page and find "file"
+ */
+void ex_splitview(eap)
+exarg_T *eap;
+{
+ win_T *old_curwin = curwin;
+ char_u *fname = NULL;
+
+
+
+ /* A ":split" in the quickfix window works like ":new". Don't want two
+ * quickfix windows. But it's OK when doing ":tab split". */
+ if (bt_quickfix(curbuf) && cmdmod.tab == 0) {
+ if (eap->cmdidx == CMD_split)
+ eap->cmdidx = CMD_new;
+ if (eap->cmdidx == CMD_vsplit)
+ eap->cmdidx = CMD_vnew;
+ }
+
+ if (eap->cmdidx == CMD_sfind || eap->cmdidx == CMD_tabfind) {
+ fname = find_file_in_path(eap->arg, (int)STRLEN(eap->arg),
+ FNAME_MESS, TRUE, curbuf->b_ffname);
+ if (fname == NULL)
+ goto theend;
+ eap->arg = fname;
+ }
+
+ /*
+ * Either open new tab page or split the window.
+ */
+ if (eap->cmdidx == CMD_tabedit
+ || eap->cmdidx == CMD_tabfind
+ || eap->cmdidx == CMD_tabnew) {
+ if (win_new_tabpage(cmdmod.tab != 0 ? cmdmod.tab
+ : eap->addr_count == 0 ? 0
+ : (int)eap->line2 + 1) != FAIL) {
+ do_exedit(eap, old_curwin);
+
+ /* set the alternate buffer for the window we came from */
+ if (curwin != old_curwin
+ && win_valid(old_curwin)
+ && old_curwin->w_buffer != curbuf
+ && !cmdmod.keepalt)
+ old_curwin->w_alt_fnum = curbuf->b_fnum;
+ }
+ } else if (win_split(eap->addr_count > 0 ? (int)eap->line2 : 0,
+ *eap->cmd == 'v' ? WSP_VERT : 0) != FAIL) {
+ /* Reset 'scrollbind' when editing another file, but keep it when
+ * doing ":split" without arguments. */
+ if (*eap->arg != NUL
+ ) {
+ RESET_BINDING(curwin);
+ } else
+ do_check_scrollbind(FALSE);
+ do_exedit(eap, old_curwin);
+ }
+
+
+theend:
+ vim_free(fname);
+}
+
+/*
+ * Open a new tab page.
+ */
+void tabpage_new() {
+ exarg_T ea;
+
+ vim_memset(&ea, 0, sizeof(ea));
+ ea.cmdidx = CMD_tabnew;
+ ea.cmd = (char_u *)"tabn";
+ ea.arg = (char_u *)"";
+ ex_splitview(&ea);
+}
+
+/*
+ * :tabnext command
+ */
+static void ex_tabnext(eap)
+exarg_T *eap;
+{
+ switch (eap->cmdidx) {
+ case CMD_tabfirst:
+ case CMD_tabrewind:
+ goto_tabpage(1);
+ break;
+ case CMD_tablast:
+ goto_tabpage(9999);
+ 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(eap)
+exarg_T *eap;
+{
+ int tab_number = 9999;
+
+ 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 (p == skipdigits(p)) {
+ /* No numbers as argument. */
+ eap->errmsg = e_invarg;
+ return;
+ }
+
+ tab_number = getdigits(&p);
+ if (relative != 0)
+ tab_number = tab_number * relative + tabpage_index(curtab) - 1; ;
+ } else if (eap->addr_count != 0)
+ tab_number = eap->line2;
+
+ tabpage_move(tab_number);
+}
+
+/*
+ * :tabs command: List tabs and their contents.
+ */
+static void ex_tabs(eap)
+exarg_T *eap UNUSED;
+{
+ tabpage_T *tp;
+ win_T *wp;
+ int tabcount = 1;
+
+ msg_start();
+ msg_scroll = TRUE;
+ for (tp = first_tabpage; tp != NULL && !got_int; tp = tp->tp_next) {
+ msg_putchar('\n');
+ vim_snprintf((char *)IObuff, IOSIZE, _("Tab page %d"), tabcount++);
+ msg_outtrans_attr(IObuff, hl_attr(HLF_T));
+ out_flush(); /* output one line at a time */
+ ui_breakcheck();
+
+ if (tp == curtab)
+ wp = firstwin;
+ else
+ wp = tp->tp_firstwin;
+ for (; wp != NULL && !got_int; wp = wp->w_next) {
+ msg_putchar('\n');
+ msg_putchar(wp == curwin ? '>' : ' ');
+ msg_putchar(' ');
+ msg_putchar(bufIsChanged(wp->w_buffer) ? '+' : ' ');
+ msg_putchar(' ');
+ if (buf_spname(wp->w_buffer) != NULL)
+ vim_strncpy(IObuff, buf_spname(wp->w_buffer), IOSIZE - 1);
+ else
+ home_replace(wp->w_buffer, wp->w_buffer->b_fname,
+ IObuff, IOSIZE, TRUE);
+ msg_outtrans(IObuff);
+ out_flush(); /* output one line at a time */
+ ui_breakcheck();
+ }
+ }
+}
+
+
+/*
+ * ":mode": Set screen mode.
+ * If no argument given, just get the screen size and redraw.
+ */
+static void ex_mode(eap)
+exarg_T *eap;
+{
+ if (*eap->arg == NUL)
+ shell_resized();
+ else
+ mch_screenmode(eap->arg);
+}
+
+/*
+ * ":resize".
+ * set, increment or decrement current window height
+ */
+static void ex_resize(eap)
+exarg_T *eap;
+{
+ int n;
+ win_T *wp = curwin;
+
+ if (eap->addr_count > 0) {
+ n = eap->line2;
+ for (wp = firstwin; wp->w_next != NULL && --n > 0; wp = wp->w_next)
+ ;
+ }
+
+ n = atol((char *)eap->arg);
+ if (cmdmod.split & WSP_VERT) {
+ if (*eap->arg == '-' || *eap->arg == '+')
+ n += W_WIDTH(curwin);
+ else if (n == 0 && eap->arg[0] == NUL) /* default is very wide */
+ n = 9999;
+ win_setwidth_win((int)n, wp);
+ } else {
+ if (*eap->arg == '-' || *eap->arg == '+')
+ n += curwin->w_height;
+ else if (n == 0 && eap->arg[0] == NUL) /* default is very wide */
+ n = 9999;
+ win_setheight_win((int)n, wp);
+ }
+}
+
+/*
+ * ":find [+command] <file>" command.
+ */
+static void ex_find(eap)
+exarg_T *eap;
+{
+ char_u *fname;
+ int count;
+
+ fname = find_file_in_path(eap->arg, (int)STRLEN(eap->arg), FNAME_MESS,
+ TRUE, curbuf->b_ffname);
+ if (eap->addr_count > 0) {
+ /* Repeat finding the file "count" times. This matters when it
+ * appears several times in the path. */
+ count = eap->line2;
+ while (fname != NULL && --count > 0) {
+ vim_free(fname);
+ fname = find_file_in_path(NULL, 0, FNAME_MESS,
+ FALSE, curbuf->b_ffname);
+ }
+ }
+
+ if (fname != NULL) {
+ eap->arg = fname;
+ do_exedit(eap, NULL);
+ vim_free(fname);
+ }
+}
+
+/*
+ * ":open" simulation: for now just work like ":visual".
+ */
+static void ex_open(eap)
+exarg_T *eap;
+{
+ regmatch_T regmatch;
+ char_u *p;
+
+ curwin->w_cursor.lnum = eap->line2;
+ beginline(BL_SOL | BL_FIX);
+ if (*eap->arg == '/') {
+ /* ":open /pattern/": put cursor in column found with pattern */
+ ++eap->arg;
+ p = skip_regexp(eap->arg, '/', p_magic, NULL);
+ *p = NUL;
+ regmatch.regprog = vim_regcomp(eap->arg, p_magic ? RE_MAGIC : 0);
+ if (regmatch.regprog != NULL) {
+ regmatch.rm_ic = p_ic;
+ p = ml_get_curline();
+ if (vim_regexec(&regmatch, p, (colnr_T)0))
+ curwin->w_cursor.col = (colnr_T)(regmatch.startp[0] - p);
+ else
+ EMSG(_(e_nomatch));
+ vim_regfree(regmatch.regprog);
+ }
+ /* Move to the NUL, ignore any other arguments. */
+ eap->arg += STRLEN(eap->arg);
+ }
+ check_cursor();
+
+ eap->cmdidx = CMD_visual;
+ do_exedit(eap, NULL);
+}
+
+/*
+ * ":edit", ":badd", ":visual".
+ */
+static void ex_edit(eap)
+exarg_T *eap;
+{
+ do_exedit(eap, NULL);
+}
+
+/*
+ * ":edit <file>" command and alikes.
+ */
+void do_exedit(eap, old_curwin)
+exarg_T *eap;
+win_T *old_curwin; /* curwin before doing a split or NULL */
+{
+ int n;
+ int need_hide;
+ int exmode_was = exmode_active;
+
+ /*
+ * ":vi" command ends Ex mode.
+ */
+ if (exmode_active && (eap->cmdidx == CMD_visual
+ || eap->cmdidx == CMD_view)) {
+ exmode_active = FALSE;
+ if (*eap->arg == NUL) {
+ /* Special case: ":global/pat/visual\NLvi-commands" */
+ if (global_busy) {
+ int rd = RedrawingDisabled;
+ int nwr = no_wait_return;
+ int ms = msg_scroll;
+
+ if (eap->nextcmd != NULL) {
+ stuffReadbuff(eap->nextcmd);
+ eap->nextcmd = NULL;
+ }
+
+ if (exmode_was != EXMODE_VIM)
+ settmode(TMODE_RAW);
+ RedrawingDisabled = 0;
+ no_wait_return = 0;
+ need_wait_return = FALSE;
+ msg_scroll = 0;
+ must_redraw = CLEAR;
+
+ main_loop(FALSE, TRUE);
+
+ RedrawingDisabled = rd;
+ no_wait_return = nwr;
+ msg_scroll = ms;
+ }
+ return;
+ }
+ }
+
+ if ((eap->cmdidx == CMD_new
+ || eap->cmdidx == CMD_tabnew
+ || eap->cmdidx == CMD_tabedit
+ || eap->cmdidx == CMD_vnew
+ ) && *eap->arg == NUL) {
+ /* ":new" or ":tabnew" without argument: edit an new empty buffer */
+ setpcmark();
+ (void)do_ecmd(0, NULL, NULL, eap, ECMD_ONE,
+ ECMD_HIDE + (eap->forceit ? ECMD_FORCEIT : 0),
+ old_curwin == NULL ? curwin : NULL);
+ } else if ((eap->cmdidx != CMD_split
+ && eap->cmdidx != CMD_vsplit
+ )
+ || *eap->arg != NUL
+ ) {
+ /* 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())
+ return;
+ n = readonlymode;
+ if (eap->cmdidx == CMD_view || eap->cmdidx == CMD_sview)
+ readonlymode = TRUE;
+ else if (eap->cmdidx == CMD_enew)
+ readonlymode = FALSE; /* 'readonly' doesn't make sense in an
+ empty buffer */
+ setpcmark();
+ if (do_ecmd(0, (eap->cmdidx == CMD_enew ? NULL : eap->arg),
+ NULL, eap,
+ /* ":edit" goes to first line if Vi compatible */
+ (*eap->arg == NUL && eap->do_ecmd_lnum == 0
+ && vim_strchr(p_cpo, CPO_GOTO1) != NULL)
+ ? ECMD_ONE : eap->do_ecmd_lnum,
+ (P_HID(curbuf) ? ECMD_HIDE : 0)
+ + (eap->forceit ? ECMD_FORCEIT : 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)) {
+ 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));
+
+ /* Restore the error/interrupt/exception state if not
+ * discarded by a new aborting error, interrupt, or
+ * uncaught exception. */
+ leave_cleanup(&cs);
+ }
+ }
+ } else if (readonlymode && curbuf->b_nwindows == 1) {
+ /* When editing an already visited buffer, 'readonly' won't be set
+ * but the previous value is kept. With ":view" and ":sview" we
+ * want the file to be readonly, except when another window is
+ * editing the same buffer. */
+ curbuf->b_p_ro = TRUE;
+ }
+ readonlymode = n;
+ } else {
+ if (eap->do_ecmd_cmd != NULL)
+ do_cmdline_cmd(eap->do_ecmd_cmd);
+ n = curwin->w_arg_idx_invalid;
+ check_arg_idx(curwin);
+ if (n != curwin->w_arg_idx_invalid)
+ maketitle();
+ }
+
+ /*
+ * if ":split file" worked, set alternate file name in old window to new
+ * file
+ */
+ if (old_curwin != NULL
+ && *eap->arg != NUL
+ && curwin != old_curwin
+ && win_valid(old_curwin)
+ && old_curwin->w_buffer != curbuf
+ && !cmdmod.keepalt)
+ old_curwin->w_alt_fnum = curbuf->b_fnum;
+
+ ex_no_reprint = TRUE;
+}
+
+/*
+ * ":gui" and ":gvim" when there is no GUI.
+ */
+static void ex_nogui(eap)
+exarg_T *eap;
+{
+ eap->errmsg = e_nogvim;
+}
+
+
+
+static void ex_swapname(eap)
+exarg_T *eap UNUSED;
+{
+ if (curbuf->b_ml.ml_mfp == NULL || curbuf->b_ml.ml_mfp->mf_fname == NULL)
+ MSG(_("No swap file"));
+ else
+ msg(curbuf->b_ml.ml_mfp->mf_fname);
+}
+
+/*
+ * ":syncbind" forces all 'scrollbind' windows to have the same relative
+ * offset.
+ * (1998-11-02 16:21:01 R. Edward Ralston <eralston@computer.org>)
+ */
+static void ex_syncbind(eap)
+exarg_T *eap UNUSED;
+{
+ win_T *wp;
+ win_T *save_curwin = curwin;
+ buf_T *save_curbuf = curbuf;
+ long topline;
+ long y;
+ linenr_T old_linenr = curwin->w_cursor.lnum;
+
+ setpcmark();
+
+ /*
+ * determine max topline
+ */
+ if (curwin->w_p_scb) {
+ topline = curwin->w_topline;
+ for (wp = firstwin; wp; wp = wp->w_next) {
+ if (wp->w_p_scb && wp->w_buffer) {
+ y = wp->w_buffer->b_ml.ml_line_count - p_so;
+ if (topline > y)
+ topline = y;
+ }
+ }
+ if (topline < 1)
+ topline = 1;
+ } else {
+ topline = 1;
+ }
+
+
+ /*
+ * Set all scrollbind windows to the same topline.
+ */
+ for (curwin = firstwin; curwin; curwin = curwin->w_next) {
+ if (curwin->w_p_scb) {
+ curbuf = curwin->w_buffer;
+ y = topline - curwin->w_topline;
+ if (y > 0)
+ scrollup(y, TRUE);
+ else
+ scrolldown(-y, TRUE);
+ curwin->w_scbind_pos = topline;
+ redraw_later(VALID);
+ cursor_correct();
+ curwin->w_redr_status = TRUE;
+ }
+ }
+ curwin = save_curwin;
+ curbuf = save_curbuf;
+ if (curwin->w_p_scb) {
+ did_syncbind = TRUE;
+ checkpcmark();
+ if (old_linenr != curwin->w_cursor.lnum) {
+ char_u ctrl_o[2];
+
+ ctrl_o[0] = Ctrl_O;
+ ctrl_o[1] = 0;
+ ins_typebuf(ctrl_o, REMAP_NONE, 0, TRUE, FALSE);
+ }
+ }
+}
+
+
+static void ex_read(eap)
+exarg_T *eap;
+{
+ int i;
+ int empty = (curbuf->b_ml.ml_flags & ML_EMPTY);
+ linenr_T lnum;
+
+ if (eap->usefilter) /* :r!cmd */
+ do_bang(1, eap, FALSE, FALSE, TRUE);
+ else {
+ if (u_save(eap->line2, (linenr_T)(eap->line2 + 1)) == FAIL)
+ return;
+
+ if (*eap->arg == NUL) {
+ if (check_fname() == FAIL) /* check for no file name */
+ return;
+ i = readfile(curbuf->b_ffname, curbuf->b_fname,
+ eap->line2, (linenr_T)0, (linenr_T)MAXLNUM, eap, 0);
+ } else {
+ if (vim_strchr(p_cpo, CPO_ALTREAD) != NULL)
+ (void)setaltfname(eap->arg, eap->arg, (linenr_T)1);
+ i = readfile(eap->arg, NULL,
+ eap->line2, (linenr_T)0, (linenr_T)MAXLNUM, eap, 0);
+
+ }
+ if (i == FAIL) {
+ if (!aborting())
+ EMSG2(_(e_notopen), eap->arg);
+ } else {
+ if (empty && exmode_active) {
+ /* Delete the empty line that remains. Historically ex does
+ * this but vi doesn't. */
+ if (eap->line2 == 0)
+ lnum = curbuf->b_ml.ml_line_count;
+ else
+ lnum = 1;
+ if (*ml_get(lnum) == NUL && u_savedel(lnum, 1L) == OK) {
+ ml_delete(lnum, FALSE);
+ if (curwin->w_cursor.lnum > 1
+ && curwin->w_cursor.lnum >= lnum)
+ --curwin->w_cursor.lnum;
+ deleted_lines_mark(lnum, 1L);
+ }
+ }
+ redraw_curbuf_later(VALID);
+ }
+ }
+}
+
+static char_u *prev_dir = NULL;
+
+#if defined(EXITFREE) || defined(PROTO)
+void free_cd_dir() {
+ vim_free(prev_dir);
+ prev_dir = NULL;
+
+ vim_free(globaldir);
+ globaldir = NULL;
+}
+
+#endif
+
+/*
+ * Deal with the side effects of changing the current directory.
+ * When "local" is TRUE then this was after an ":lcd" command.
+ */
+void post_chdir(local)
+int local;
+{
+ vim_free(curwin->w_localdir);
+ curwin->w_localdir = NULL;
+ if (local) {
+ /* If still in global directory, need to remember current
+ * directory as global directory. */
+ if (globaldir == NULL && prev_dir != NULL)
+ globaldir = vim_strsave(prev_dir);
+ /* Remember this local directory for the window. */
+ if (mch_dirname(NameBuff, MAXPATHL) == OK)
+ curwin->w_localdir = vim_strsave(NameBuff);
+ } else {
+ /* We are now in the global directory, no need to remember its
+ * name. */
+ vim_free(globaldir);
+ globaldir = NULL;
+ }
+
+ shorten_fnames(TRUE);
+}
+
+
+/*
+ * ":cd", ":lcd", ":chdir" and ":lchdir".
+ */
+void ex_cd(eap)
+exarg_T *eap;
+{
+ char_u *new_dir;
+ char_u *tofree;
+
+ new_dir = eap->arg;
+#if !defined(UNIX) && !defined(VMS)
+ /* for non-UNIX ":cd" means: print current directory */
+ if (*new_dir == NUL)
+ ex_pwd(NULL);
+ else
+#endif
+ {
+ if (allbuf_locked())
+ return;
+ if (vim_strchr(p_cpo, CPO_CHDIR) != NULL && curbufIsChanged()
+ && !eap->forceit) {
+ EMSG(_(
+ "E747: Cannot change directory, buffer is modified (add ! to override)"));
+ return;
+ }
+
+ /* ":cd -": Change to previous directory */
+ if (STRCMP(new_dir, "-") == 0) {
+ if (prev_dir == NULL) {
+ EMSG(_("E186: No previous directory"));
+ return;
+ }
+ new_dir = prev_dir;
+ }
+
+ /* Save current directory for next ":cd -" */
+ tofree = prev_dir;
+ if (mch_dirname(NameBuff, MAXPATHL) == OK)
+ prev_dir = vim_strsave(NameBuff);
+ else
+ prev_dir = NULL;
+
+#if defined(UNIX) || defined(VMS)
+ /* for UNIX ":cd" means: go to home directory */
+ if (*new_dir == NUL) {
+ /* use NameBuff for home directory name */
+ expand_env((char_u *)"$HOME", NameBuff, MAXPATHL);
+ new_dir = NameBuff;
+ }
+#endif
+ if (new_dir == NULL || vim_chdir(new_dir))
+ EMSG(_(e_failed));
+ else {
+ post_chdir(eap->cmdidx == CMD_lcd || eap->cmdidx == CMD_lchdir);
+
+ /* Echo the new current directory if the command was typed. */
+ if (KeyTyped || p_verbose >= 5)
+ ex_pwd(eap);
+ }
+ vim_free(tofree);
+ }
+}
+
+/*
+ * ":pwd".
+ */
+static void ex_pwd(eap)
+exarg_T *eap UNUSED;
+{
+ if (mch_dirname(NameBuff, MAXPATHL) == OK) {
+#ifdef BACKSLASH_IN_FILENAME
+ slash_adjust(NameBuff);
+#endif
+ msg(NameBuff);
+ } else
+ EMSG(_("E187: Unknown"));
+}
+
+/*
+ * ":=".
+ */
+static void ex_equal(eap)
+exarg_T *eap;
+{
+ smsg((char_u *)"%ld", (long)eap->line2);
+ ex_may_print(eap);
+}
+
+static void ex_sleep(eap)
+exarg_T *eap;
+{
+ int n;
+ long len;
+
+ if (cursor_valid()) {
+ n = W_WINROW(curwin) + curwin->w_wrow - msg_scrolled;
+ if (n >= 0)
+ windgoto((int)n, curwin->w_wcol);
+ }
+
+ len = eap->line2;
+ switch (*eap->arg) {
+ case 'm': break;
+ case NUL: len *= 1000L; break;
+ default: EMSG2(_(e_invarg2), eap->arg); return;
+ }
+ do_sleep(len);
+}
+
+/*
+ * Sleep for "msec" milliseconds, but keep checking for a CTRL-C every second.
+ */
+void do_sleep(msec)
+long msec;
+{
+ long done;
+
+ cursor_on();
+ out_flush();
+ for (done = 0; !got_int && done < msec; done += 1000L) {
+ ui_delay(msec - done > 1000L ? 1000L : msec - done, TRUE);
+ ui_breakcheck();
+ }
+}
+
+static void do_exmap(eap, isabbrev)
+exarg_T *eap;
+int isabbrev;
+{
+ int mode;
+ char_u *cmdp;
+
+ cmdp = eap->cmd;
+ mode = get_map_mode(&cmdp, eap->forceit || isabbrev);
+
+ switch (do_map((*cmdp == 'n') ? 2 : (*cmdp == 'u'),
+ eap->arg, mode, isabbrev)) {
+ case 1: EMSG(_(e_invarg));
+ break;
+ case 2: EMSG(isabbrev ? _(e_noabbr) : _(e_nomap));
+ break;
+ }
+}
+
+/*
+ * ":winsize" command (obsolete).
+ */
+static void ex_winsize(eap)
+exarg_T *eap;
+{
+ int w, h;
+ char_u *arg = eap->arg;
+ char_u *p;
+
+ w = getdigits(&arg);
+ arg = skipwhite(arg);
+ p = arg;
+ h = getdigits(&arg);
+ if (*p != NUL && *arg == NUL)
+ set_shellsize(w, h, TRUE);
+ else
+ EMSG(_("E465: :winsize requires two number arguments"));
+}
+
+static void ex_wincmd(eap)
+exarg_T *eap;
+{
+ int xchar = NUL;
+ char_u *p;
+
+ if (*eap->arg == 'g' || *eap->arg == Ctrl_G) {
+ /* CTRL-W g and CTRL-W CTRL-G have an extra command character */
+ if (eap->arg[1] == NUL) {
+ EMSG(_(e_invarg));
+ return;
+ }
+ xchar = eap->arg[1];
+ p = eap->arg + 2;
+ } else
+ p = eap->arg + 1;
+
+ eap->nextcmd = check_nextcmd(p);
+ p = skipwhite(p);
+ if (*p != NUL && *p != '"' && eap->nextcmd == NULL)
+ EMSG(_(e_invarg));
+ else if (!eap->skip) {
+ /* Pass flags on for ":vertical wincmd ]". */
+ postponed_split_flags = cmdmod.split;
+ postponed_split_tab = cmdmod.tab;
+ do_window(*eap->arg, eap->addr_count > 0 ? eap->line2 : 0L, xchar);
+ postponed_split_flags = 0;
+ postponed_split_tab = 0;
+ }
+}
+
+#if defined(FEAT_GUI) || defined(UNIX) || defined(VMS) || defined(MSWIN)
+/*
+ * ":winpos".
+ */
+static void ex_winpos(eap)
+exarg_T *eap;
+{
+ int x, y;
+ char_u *arg = eap->arg;
+ char_u *p;
+
+ if (*arg == NUL) {
+ EMSG(_("E188: Obtaining window position not implemented for this platform"));
+ } else {
+ x = getdigits(&arg);
+ arg = skipwhite(arg);
+ p = arg;
+ y = getdigits(&arg);
+ if (*p == NUL || *arg != NUL) {
+ EMSG(_("E466: :winpos requires two number arguments"));
+ return;
+ }
+# ifdef HAVE_TGETENT
+ if (*T_CWP)
+ term_set_winpos(x, y);
+# endif
+ }
+}
+#endif
+
+/*
+ * Handle command that work like operators: ":delete", ":yank", ":>" and ":<".
+ */
+static void ex_operators(eap)
+exarg_T *eap;
+{
+ oparg_T oa;
+
+ clear_oparg(&oa);
+ oa.regname = eap->regname;
+ oa.start.lnum = eap->line1;
+ oa.end.lnum = eap->line2;
+ oa.line_count = eap->line2 - eap->line1 + 1;
+ oa.motion_type = MLINE;
+ virtual_op = FALSE;
+ if (eap->cmdidx != CMD_yank) { /* position cursor for undo */
+ setpcmark();
+ curwin->w_cursor.lnum = eap->line1;
+ beginline(BL_SOL | BL_FIX);
+ }
+
+ if (VIsual_active)
+ end_visual_mode();
+
+ switch (eap->cmdidx) {
+ case CMD_delete:
+ oa.op_type = OP_DELETE;
+ op_delete(&oa);
+ break;
+
+ case CMD_yank:
+ oa.op_type = OP_YANK;
+ (void)op_yank(&oa, FALSE, TRUE);
+ break;
+
+ default: /* CMD_rshift or CMD_lshift */
+ if (
+ (eap->cmdidx == CMD_rshift) ^ curwin->w_p_rl
+ )
+ oa.op_type = OP_RSHIFT;
+ else
+ oa.op_type = OP_LSHIFT;
+ op_shift(&oa, FALSE, eap->amount);
+ break;
+ }
+ virtual_op = MAYBE;
+ ex_may_print(eap);
+}
+
+/*
+ * ":put".
+ */
+static void ex_put(eap)
+exarg_T *eap;
+{
+ /* ":0put" works like ":1put!". */
+ if (eap->line2 == 0) {
+ eap->line2 = 1;
+ eap->forceit = TRUE;
+ }
+ curwin->w_cursor.lnum = eap->line2;
+ do_put(eap->regname, eap->forceit ? BACKWARD : FORWARD, 1L,
+ PUT_LINE|PUT_CURSLINE);
+}
+
+/*
+ * Handle ":copy" and ":move".
+ */
+static void ex_copymove(eap)
+exarg_T *eap;
+{
+ long n;
+
+ n = get_address(&eap->arg, FALSE, FALSE);
+ if (eap->arg == NULL) { /* error detected */
+ eap->nextcmd = NULL;
+ return;
+ }
+ get_flags(eap);
+
+ /*
+ * move or copy lines from 'eap->line1'-'eap->line2' to below line 'n'
+ */
+ if (n == MAXLNUM || n < 0 || n > curbuf->b_ml.ml_line_count) {
+ EMSG(_(e_invaddr));
+ return;
+ }
+
+ if (eap->cmdidx == CMD_move) {
+ if (do_move(eap->line1, eap->line2, n) == FAIL)
+ return;
+ } else
+ ex_copy(eap->line1, eap->line2, n);
+ u_clearline();
+ beginline(BL_SOL | BL_FIX);
+ ex_may_print(eap);
+}
+
+/*
+ * Print the current line if flags were given to the Ex command.
+ */
+static void ex_may_print(eap)
+exarg_T *eap;
+{
+ if (eap->flags != 0) {
+ print_line(curwin->w_cursor.lnum, (eap->flags & EXFLAG_NR),
+ (eap->flags & EXFLAG_LIST));
+ ex_no_reprint = TRUE;
+ }
+}
+
+/*
+ * ":smagic" and ":snomagic".
+ */
+static void ex_submagic(eap)
+exarg_T *eap;
+{
+ int magic_save = p_magic;
+
+ p_magic = (eap->cmdidx == CMD_smagic);
+ do_sub(eap);
+ p_magic = magic_save;
+}
+
+/*
+ * ":join".
+ */
+static void ex_join(eap)
+exarg_T *eap;
+{
+ curwin->w_cursor.lnum = eap->line1;
+ if (eap->line1 == eap->line2) {
+ if (eap->addr_count >= 2) /* :2,2join does nothing */
+ return;
+ if (eap->line2 == curbuf->b_ml.ml_line_count) {
+ beep_flush();
+ return;
+ }
+ ++eap->line2;
+ }
+ (void)do_join(eap->line2 - eap->line1 + 1, !eap->forceit, TRUE, TRUE);
+ beginline(BL_WHITE | BL_FIX);
+ ex_may_print(eap);
+}
+
+/*
+ * ":[addr]@r" or ":[addr]*r": execute register
+ */
+static void ex_at(eap)
+exarg_T *eap;
+{
+ int c;
+ int prev_len = typebuf.tb_len;
+
+ curwin->w_cursor.lnum = eap->line2;
+
+#ifdef USE_ON_FLY_SCROLL
+ dont_scroll = TRUE; /* disallow scrolling here */
+#endif
+
+ /* get the register name. No name means to use the previous one */
+ c = *eap->arg;
+ if (c == NUL || (c == '*' && *eap->cmd == '*'))
+ c = '@';
+ /* Put the register in the typeahead buffer with the "silent" flag. */
+ if (do_execreg(c, TRUE, vim_strchr(p_cpo, CPO_EXECBUF) != NULL, TRUE)
+ == FAIL) {
+ beep_flush();
+ } else {
+ int save_efr = exec_from_reg;
+
+ exec_from_reg = TRUE;
+
+ /*
+ * Execute from the typeahead buffer.
+ * Continue until the stuff buffer is empty and all added characters
+ * have been consumed.
+ */
+ while (!stuff_empty() || typebuf.tb_len > prev_len)
+ (void)do_cmdline(NULL, getexline, NULL, DOCMD_NOWAIT|DOCMD_VERBOSE);
+
+ exec_from_reg = save_efr;
+ }
+}
+
+/*
+ * ":!".
+ */
+static void ex_bang(eap)
+exarg_T *eap;
+{
+ do_bang(eap->addr_count, eap, eap->forceit, TRUE, TRUE);
+}
+
+/*
+ * ":undo".
+ */
+static void ex_undo(eap)
+exarg_T *eap UNUSED;
+{
+ if (eap->addr_count == 1) /* :undo 123 */
+ undo_time(eap->line2, FALSE, FALSE, TRUE);
+ else
+ u_undo(1);
+}
+
+static void ex_wundo(eap)
+exarg_T *eap;
+{
+ char_u hash[UNDO_HASH_SIZE];
+
+ u_compute_hash(hash);
+ u_write_undo(eap->arg, eap->forceit, curbuf, hash);
+}
+
+static void ex_rundo(eap)
+exarg_T *eap;
+{
+ char_u hash[UNDO_HASH_SIZE];
+
+ u_compute_hash(hash);
+ u_read_undo(eap->arg, hash, NULL);
+}
+
+/*
+ * ":redo".
+ */
+static void ex_redo(eap)
+exarg_T *eap UNUSED;
+{
+ u_redo(1);
+}
+
+/*
+ * ":earlier" and ":later".
+ */
+static void ex_later(eap)
+exarg_T *eap;
+{
+ long count = 0;
+ int sec = FALSE;
+ int file = FALSE;
+ char_u *p = eap->arg;
+
+ if (*p == NUL)
+ count = 1;
+ else if (isdigit(*p)) {
+ count = getdigits(&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;
+ }
+ }
+
+ if (*p != NUL)
+ EMSG2(_(e_invarg2), eap->arg);
+ else
+ undo_time(eap->cmdidx == CMD_earlier ? -count : count,
+ sec, file, FALSE);
+}
+
+/*
+ * ":redir": start/stop redirection.
+ */
+static void ex_redir(eap)
+exarg_T *eap;
+{
+ char *mode;
+ char_u *fname;
+ char_u *arg = eap->arg;
+
+ if (STRICMP(eap->arg, "END") == 0)
+ close_redir();
+ else {
+ if (*arg == '>') {
+ ++arg;
+ if (*arg == '>') {
+ ++arg;
+ mode = "a";
+ } else
+ mode = "w";
+ arg = skipwhite(arg);
+
+ close_redir();
+
+ /* Expand environment variables and "~/". */
+ fname = expand_env_save(arg);
+ if (fname == NULL)
+ return;
+
+ redir_fd = open_exfile(fname, eap->forceit, mode);
+ vim_free(fname);
+ } else if (*arg == '@') {
+ /* redirect to a register a-z (resp. A-Z for appending) */
+ close_redir();
+ ++arg;
+ if (ASCII_ISALPHA(*arg)
+ || *arg == '"') {
+ redir_reg = *arg++;
+ if (*arg == '>' && arg[1] == '>') /* append */
+ arg += 2;
+ else {
+ /* Can use both "@a" and "@a>". */
+ if (*arg == '>')
+ arg++;
+ /* Make register empty when not using @A-@Z and the
+ * command is valid. */
+ if (*arg == NUL && !isupper(redir_reg))
+ write_reg_contents(redir_reg, (char_u *)"", -1, FALSE);
+ }
+ }
+ if (*arg != NUL) {
+ redir_reg = 0;
+ EMSG2(_(e_invarg2), eap->arg);
+ }
+ } else if (*arg == '=' && arg[1] == '>') {
+ int append;
+
+ /* redirect to a variable */
+ close_redir();
+ arg += 2;
+
+ if (*arg == '>') {
+ ++arg;
+ append = TRUE;
+ } else
+ append = FALSE;
+
+ if (var_redir_start(skipwhite(arg), append) == OK)
+ redir_vname = 1;
+ }
+ /* TODO: redirect to a buffer */
+ else
+ EMSG2(_(e_invarg2), eap->arg);
+ }
+
+ /* Make sure redirection is not off. Can happen for cmdline completion
+ * that indirectly invokes a command to catch its output. */
+ if (redir_fd != NULL
+ || redir_reg || redir_vname
+ )
+ redir_off = FALSE;
+}
+
+/*
+ * ":redraw": force redraw
+ */
+static void ex_redraw(eap)
+exarg_T *eap;
+{
+ int r = RedrawingDisabled;
+ int p = p_lz;
+
+ RedrawingDisabled = 0;
+ p_lz = FALSE;
+ update_topline();
+ update_screen(eap->forceit ? CLEAR :
+ VIsual_active ? INVERTED :
+ 0);
+ if (need_maketitle)
+ maketitle();
+ RedrawingDisabled = r;
+ p_lz = p;
+
+ /* Reset msg_didout, so that a message that's there is overwritten. */
+ msg_didout = FALSE;
+ msg_col = 0;
+
+ /* No need to wait after an intentional redraw. */
+ need_wait_return = FALSE;
+
+ out_flush();
+}
+
+/*
+ * ":redrawstatus": force redraw of status line(s)
+ */
+static void ex_redrawstatus(eap)
+exarg_T *eap UNUSED;
+{
+ int r = RedrawingDisabled;
+ int p = p_lz;
+
+ RedrawingDisabled = 0;
+ p_lz = FALSE;
+ if (eap->forceit)
+ status_redraw_all();
+ else
+ status_redraw_curbuf();
+ update_screen(
+ VIsual_active ? INVERTED :
+ 0);
+ RedrawingDisabled = r;
+ p_lz = p;
+ out_flush();
+}
+
+static void close_redir() {
+ if (redir_fd != NULL) {
+ fclose(redir_fd);
+ redir_fd = NULL;
+ }
+ redir_reg = 0;
+ if (redir_vname) {
+ var_redir_stop();
+ redir_vname = 0;
+ }
+}
+
+#if defined(FEAT_SESSION) && defined(USE_CRNL)
+# define MKSESSION_NL
+static int mksession_nl = FALSE; /* use NL only in put_eol() */
+#endif
+
+/*
+ * ":mkexrc", ":mkvimrc", ":mkview" and ":mksession".
+ */
+static void ex_mkrc(eap)
+exarg_T *eap;
+{
+ FILE *fd;
+ int failed = FALSE;
+ char_u *fname;
+ int view_session = FALSE;
+ int using_vdir = FALSE; /* using 'viewdir'? */
+ char_u *viewFile = NULL;
+ unsigned *flagp;
+
+ if (eap->cmdidx == CMD_mksession || eap->cmdidx == CMD_mkview) {
+ view_session = TRUE;
+ }
+
+ /* Use the short file name until ":lcd" is used. We also don't use the
+ * short file name when 'acd' is set, that is checked later. */
+ did_lcd = FALSE;
+
+ /* ":mkview" or ":mkview 9": generate file name with 'viewdir' */
+ if (eap->cmdidx == CMD_mkview
+ && (*eap->arg == NUL
+ || (vim_isdigit(*eap->arg) && eap->arg[1] == NUL))) {
+ eap->forceit = TRUE;
+ fname = get_view_file(*eap->arg);
+ if (fname == NULL)
+ return;
+ viewFile = fname;
+ using_vdir = TRUE;
+ } else if (*eap->arg != NUL)
+ fname = eap->arg;
+ else if (eap->cmdidx == CMD_mkvimrc)
+ fname = (char_u *)VIMRC_FILE;
+ else if (eap->cmdidx == CMD_mksession)
+ fname = (char_u *)SESSION_FILE;
+ else
+ fname = (char_u *)EXRC_FILE;
+
+
+#if defined(FEAT_SESSION) && defined(vim_mkdir)
+ /* When using 'viewdir' may have to create the directory. */
+ if (using_vdir && !mch_isdir(p_vdir))
+ vim_mkdir_emsg(p_vdir, 0755);
+#endif
+
+ fd = open_exfile(fname, eap->forceit, WRITEBIN);
+ if (fd != NULL) {
+ if (eap->cmdidx == CMD_mkview)
+ flagp = &vop_flags;
+ else
+ flagp = &ssop_flags;
+
+#ifdef MKSESSION_NL
+ /* "unix" in 'sessionoptions': use NL line separator */
+ if (view_session && (*flagp & SSOP_UNIX))
+ mksession_nl = TRUE;
+#endif
+
+ /* Write the version command for :mkvimrc */
+ if (eap->cmdidx == CMD_mkvimrc)
+ (void)put_line(fd, "version 6.0");
+
+ if (eap->cmdidx == CMD_mksession) {
+ if (put_line(fd, "let SessionLoad = 1") == FAIL)
+ failed = TRUE;
+ }
+
+ if (eap->cmdidx != CMD_mkview) {
+ /* Write setting 'compatible' first, because it has side effects.
+ * For that same reason only do it when needed. */
+ if (p_cp)
+ (void)put_line(fd, "if !&cp | set cp | endif");
+ else
+ (void)put_line(fd, "if &cp | set nocp | endif");
+ }
+
+ if (!view_session
+ || (eap->cmdidx == CMD_mksession
+ && (*flagp & SSOP_OPTIONS)))
+ failed |= (makemap(fd, NULL) == FAIL
+ || makeset(fd, OPT_GLOBAL, FALSE) == FAIL);
+
+ if (!failed && view_session) {
+ if (put_line(fd,
+ "let s:so_save = &so | let s:siso_save = &siso | set so=0 siso=0")
+ == FAIL)
+ failed = TRUE;
+ if (eap->cmdidx == CMD_mksession) {
+ char_u *dirnow; /* current directory */
+
+ dirnow = alloc(MAXPATHL);
+ if (dirnow == NULL)
+ failed = TRUE;
+ else {
+ /*
+ * Change to session file's dir.
+ */
+ if (mch_dirname(dirnow, MAXPATHL) == FAIL
+ || mch_chdir((char *)dirnow) != 0)
+ *dirnow = NUL;
+ if (*dirnow != NUL && (ssop_flags & SSOP_SESDIR)) {
+ if (vim_chdirfile(fname) == OK)
+ shorten_fnames(TRUE);
+ } else if (*dirnow != NUL
+ && (ssop_flags & SSOP_CURDIR) && globaldir != NULL) {
+ if (mch_chdir((char *)globaldir) == 0)
+ shorten_fnames(TRUE);
+ }
+
+ failed |= (makeopens(fd, dirnow) == FAIL);
+
+ /* restore original dir */
+ if (*dirnow != NUL && ((ssop_flags & SSOP_SESDIR)
+ || ((ssop_flags & SSOP_CURDIR) && globaldir !=
+ NULL))) {
+ if (mch_chdir((char *)dirnow) != 0)
+ EMSG(_(e_prev_dir));
+ shorten_fnames(TRUE);
+ }
+ vim_free(dirnow);
+ }
+ } else {
+ failed |= (put_view(fd, curwin, !using_vdir, flagp,
+ -1) == FAIL);
+ }
+ if (put_line(fd, "let &so = s:so_save | let &siso = s:siso_save")
+ == FAIL)
+ failed = TRUE;
+ if (put_line(fd, "doautoall SessionLoadPost") == FAIL)
+ failed = TRUE;
+ if (eap->cmdidx == CMD_mksession) {
+ if (put_line(fd, "unlet SessionLoad") == FAIL)
+ failed = TRUE;
+ }
+ }
+ if (put_line(fd, "\" vim: set ft=vim :") == FAIL)
+ failed = TRUE;
+
+ failed |= fclose(fd);
+
+ if (failed)
+ EMSG(_(e_write));
+ else if (eap->cmdidx == CMD_mksession) {
+ /* successful session write - set this_session var */
+ char_u *tbuf;
+
+ tbuf = alloc(MAXPATHL);
+ if (tbuf != NULL) {
+ if (vim_FullName(fname, tbuf, MAXPATHL, FALSE) == OK)
+ set_vim_var_string(VV_THIS_SESSION, tbuf, -1);
+ vim_free(tbuf);
+ }
+ }
+#ifdef MKSESSION_NL
+ mksession_nl = FALSE;
+#endif
+ }
+
+ vim_free(viewFile);
+}
+
+#if ((defined(FEAT_SESSION) || defined(FEAT_EVAL)) && defined(vim_mkdir)) \
+ || defined(PROTO)
+int vim_mkdir_emsg(name, prot)
+char_u *name;
+int prot UNUSED;
+{
+ if (vim_mkdir(name, prot) != 0) {
+ EMSG2(_("E739: Cannot create directory: %s"), name);
+ return FAIL;
+ }
+ return OK;
+}
+#endif
+
+/*
+ * Open a file for writing for an Ex command, with some checks.
+ * Return file descriptor, or NULL on failure.
+ */
+FILE * open_exfile(fname, forceit, mode)
+char_u *fname;
+int forceit;
+char *mode; /* "w" for create new file or "a" for append */
+{
+ FILE *fd;
+
+#ifdef UNIX
+ /* with Unix it is possible to open a directory */
+ if (mch_isdir(fname)) {
+ EMSG2(_(e_isadir2), fname);
+ return NULL;
+ }
+#endif
+ if (!forceit && *mode != 'a' && vim_fexists(fname)) {
+ EMSG2(_("E189: \"%s\" exists (add ! to override)"), fname);
+ return NULL;
+ }
+
+ if ((fd = mch_fopen((char *)fname, mode)) == NULL)
+ EMSG2(_("E190: Cannot open \"%s\" for writing"), fname);
+
+ return fd;
+}
+
+/*
+ * ":mark" and ":k".
+ */
+static void ex_mark(eap)
+exarg_T *eap;
+{
+ pos_T pos;
+
+ if (*eap->arg == NUL) /* No argument? */
+ EMSG(_(e_argreq));
+ else if (eap->arg[1] != NUL) /* more than one character? */
+ EMSG(_(e_trailing));
+ else {
+ pos = curwin->w_cursor; /* save curwin->w_cursor */
+ curwin->w_cursor.lnum = eap->line2;
+ beginline(BL_WHITE | BL_FIX);
+ if (setmark(*eap->arg) == FAIL) /* set mark */
+ EMSG(_("E191: Argument must be a letter or forward/backward quote"));
+ curwin->w_cursor = pos; /* restore curwin->w_cursor */
+ }
+}
+
+/*
+ * Update w_topline, w_leftcol and the cursor position.
+ */
+void update_topline_cursor() {
+ check_cursor(); /* put cursor on valid line */
+ update_topline();
+ if (!curwin->w_p_wrap)
+ validate_cursor();
+ update_curswant();
+}
+
+/*
+ * ":normal[!] {commands}": Execute normal mode commands.
+ */
+static void ex_normal(eap)
+exarg_T *eap;
+{
+ int save_msg_scroll = msg_scroll;
+ int save_restart_edit = restart_edit;
+ int save_msg_didout = msg_didout;
+ int save_State = State;
+ tasave_T tabuf;
+ int save_insertmode = p_im;
+ int save_finish_op = finish_op;
+ int save_opcount = opcount;
+ char_u *arg = NULL;
+ int l;
+ char_u *p;
+
+ if (ex_normal_lock > 0) {
+ EMSG(_(e_secure));
+ return;
+ }
+ if (ex_normal_busy >= p_mmd) {
+ EMSG(_("E192: Recursive use of :normal too deep"));
+ return;
+ }
+ ++ex_normal_busy;
+
+ msg_scroll = FALSE; /* no msg scrolling in Normal mode */
+ restart_edit = 0; /* don't go to Insert mode */
+ p_im = FALSE; /* don't use 'insertmode' */
+
+ /*
+ * vgetc() expects a CSI and K_SPECIAL to have been escaped. Don't do
+ * this for the K_SPECIAL leading byte, otherwise special keys will not
+ * work.
+ */
+ if (has_mbyte) {
+ int len = 0;
+
+ /* Count the number of characters to be escaped. */
+ for (p = eap->arg; *p != NUL; ++p) {
+ for (l = (*mb_ptr2len)(p) - 1; l > 0; --l)
+ if (*++p == K_SPECIAL /* trailbyte K_SPECIAL or CSI */
+ )
+ len += 2;
+ }
+ if (len > 0) {
+ arg = alloc((unsigned)(STRLEN(eap->arg) + len + 1));
+ if (arg != NULL) {
+ len = 0;
+ for (p = eap->arg; *p != NUL; ++p) {
+ arg[len++] = *p;
+ for (l = (*mb_ptr2len)(p) - 1; l > 0; --l) {
+ arg[len++] = *++p;
+ if (*p == K_SPECIAL) {
+ arg[len++] = KS_SPECIAL;
+ arg[len++] = KE_FILLER;
+ }
+ }
+ arg[len] = NUL;
+ }
+ }
+ }
+ }
+
+ /*
+ * Save the current typeahead. This is required to allow using ":normal"
+ * from an event handler and makes sure we don't hang when the argument
+ * ends with half a command.
+ */
+ save_typeahead(&tabuf);
+ if (tabuf.typebuf_valid) {
+ /*
+ * Repeat the :normal command for each line in the range. When no
+ * range given, execute it just once, without positioning the cursor
+ * first.
+ */
+ do {
+ if (eap->addr_count != 0) {
+ curwin->w_cursor.lnum = eap->line1++;
+ curwin->w_cursor.col = 0;
+ }
+
+ exec_normal_cmd(
+ arg != NULL ? arg :
+ eap->arg, eap->forceit ? REMAP_NONE : REMAP_YES, FALSE);
+ } while (eap->addr_count > 0 && eap->line1 <= eap->line2 && !got_int);
+ }
+
+ /* Might not return to the main loop when in an event handler. */
+ update_topline_cursor();
+
+ /* Restore the previous typeahead. */
+ restore_typeahead(&tabuf);
+
+ --ex_normal_busy;
+ msg_scroll = save_msg_scroll;
+ restart_edit = save_restart_edit;
+ p_im = save_insertmode;
+ finish_op = save_finish_op;
+ opcount = save_opcount;
+ msg_didout |= save_msg_didout; /* don't reset msg_didout now */
+
+ /* Restore the state (needed when called from a function executed for
+ * 'indentexpr'). */
+ State = save_State;
+ vim_free(arg);
+}
+
+/*
+ * ":startinsert", ":startreplace" and ":startgreplace"
+ */
+static void ex_startinsert(eap)
+exarg_T *eap;
+{
+ if (eap->forceit) {
+ coladvance((colnr_T)MAXCOL);
+ curwin->w_curswant = MAXCOL;
+ curwin->w_set_curswant = FALSE;
+ }
+
+ /* Ignore the command when already in Insert mode. Inserting an
+ * expression register that invokes a function can do this. */
+ if (State & INSERT)
+ return;
+
+ if (eap->cmdidx == CMD_startinsert)
+ restart_edit = 'a';
+ else if (eap->cmdidx == CMD_startreplace)
+ restart_edit = 'R';
+ else
+ restart_edit = 'V';
+
+ if (!eap->forceit) {
+ if (eap->cmdidx == CMD_startinsert)
+ restart_edit = 'i';
+ curwin->w_curswant = 0; /* avoid MAXCOL */
+ }
+}
+
+/*
+ * ":stopinsert"
+ */
+static void ex_stopinsert(eap)
+exarg_T *eap UNUSED;
+{
+ restart_edit = 0;
+ stop_insert_mode = TRUE;
+}
+
+/*
+ * Execute normal mode command "cmd".
+ * "remap" can be REMAP_NONE or REMAP_YES.
+ */
+void exec_normal_cmd(cmd, remap, silent)
+char_u *cmd;
+int remap;
+int silent;
+{
+ oparg_T oa;
+
+ /*
+ * Stuff the argument into the typeahead buffer.
+ * Execute normal_cmd() until there is no typeahead left.
+ */
+ clear_oparg(&oa);
+ finish_op = FALSE;
+ ins_typebuf(cmd, remap, 0, TRUE, silent);
+ while ((!stuff_empty() || (!typebuf_typed() && typebuf.tb_len > 0))
+ && !got_int) {
+ update_topline_cursor();
+ normal_cmd(&oa, TRUE); /* execute a Normal mode cmd */
+ }
+}
+
+static void ex_checkpath(eap)
+exarg_T *eap;
+{
+ find_pattern_in_path(NULL, 0, 0, FALSE, FALSE, CHECK_PATH, 1L,
+ eap->forceit ? ACTION_SHOW_ALL : ACTION_SHOW,
+ (linenr_T)1, (linenr_T)MAXLNUM);
+}
+
+/*
+ * ":psearch"
+ */
+static void ex_psearch(eap)
+exarg_T *eap;
+{
+ g_do_tagpreview = p_pvh;
+ ex_findpat(eap);
+ g_do_tagpreview = 0;
+}
+
+static void ex_findpat(eap)
+exarg_T *eap;
+{
+ int whole = TRUE;
+ long n;
+ char_u *p;
+ int action;
+
+ switch (cmdnames[eap->cmdidx].cmd_name[2]) {
+ case 'e': /* ":psearch", ":isearch" and ":dsearch" */
+ if (cmdnames[eap->cmdidx].cmd_name[0] == 'p')
+ action = ACTION_GOTO;
+ else
+ action = ACTION_SHOW;
+ break;
+ case 'i': /* ":ilist" and ":dlist" */
+ action = ACTION_SHOW_ALL;
+ break;
+ case 'u': /* ":ijump" and ":djump" */
+ action = ACTION_GOTO;
+ break;
+ default: /* ":isplit" and ":dsplit" */
+ action = ACTION_SPLIT;
+ break;
+ }
+
+ n = 1;
+ if (vim_isdigit(*eap->arg)) { /* get count */
+ n = getdigits(&eap->arg);
+ eap->arg = skipwhite(eap->arg);
+ }
+ if (*eap->arg == '/') { /* Match regexp, not just whole words */
+ whole = FALSE;
+ ++eap->arg;
+ p = skip_regexp(eap->arg, '/', p_magic, NULL);
+ if (*p) {
+ *p++ = NUL;
+ p = skipwhite(p);
+
+ /* Check for trailing illegal characters */
+ if (!ends_excmd(*p))
+ eap->errmsg = e_trailing;
+ else
+ eap->nextcmd = check_nextcmd(p);
+ }
+ }
+ if (!eap->skip)
+ find_pattern_in_path(eap->arg, 0, (int)STRLEN(eap->arg),
+ whole, !eap->forceit,
+ *eap->cmd == 'd' ? FIND_DEFINE : FIND_ANY,
+ n, action, eap->line1, eap->line2);
+}
+
+
+/*
+ * ":ptag", ":ptselect", ":ptjump", ":ptnext", etc.
+ */
+static void ex_ptag(eap)
+exarg_T *eap;
+{
+ g_do_tagpreview = p_pvh; /* will be reset to 0 in ex_tag_cmd() */
+ ex_tag_cmd(eap, cmdnames[eap->cmdidx].cmd_name + 1);
+}
+
+/*
+ * ":pedit"
+ */
+static void ex_pedit(eap)
+exarg_T *eap;
+{
+ win_T *curwin_save = curwin;
+
+ g_do_tagpreview = p_pvh;
+ prepare_tagpreview(TRUE);
+ keep_help_flag = curwin_save->w_buffer->b_help;
+ do_exedit(eap, NULL);
+ keep_help_flag = FALSE;
+ if (curwin != curwin_save && win_valid(curwin_save)) {
+ /* Return cursor to where we were */
+ validate_cursor();
+ redraw_later(VALID);
+ win_enter(curwin_save, TRUE);
+ }
+ g_do_tagpreview = 0;
+}
+
+/*
+ * ":stag", ":stselect" and ":stjump".
+ */
+static void ex_stag(eap)
+exarg_T *eap;
+{
+ postponed_split = -1;
+ postponed_split_flags = cmdmod.split;
+ postponed_split_tab = cmdmod.tab;
+ ex_tag_cmd(eap, cmdnames[eap->cmdidx].cmd_name + 1);
+ postponed_split_flags = 0;
+ postponed_split_tab = 0;
+}
+
+/*
+ * ":tag", ":tselect", ":tjump", ":tnext", etc.
+ */
+static void ex_tag(eap)
+exarg_T *eap;
+{
+ ex_tag_cmd(eap, cmdnames[eap->cmdidx].cmd_name);
+}
+
+static void ex_tag_cmd(eap, name)
+exarg_T *eap;
+char_u *name;
+{
+ int cmd;
+
+ switch (name[1]) {
+ case 'j': cmd = DT_JUMP; /* ":tjump" */
+ break;
+ case 's': cmd = DT_SELECT; /* ":tselect" */
+ break;
+ case 'p': cmd = DT_PREV; /* ":tprevious" */
+ break;
+ case 'N': cmd = DT_PREV; /* ":tNext" */
+ break;
+ case 'n': cmd = DT_NEXT; /* ":tnext" */
+ break;
+ case 'o': cmd = DT_POP; /* ":pop" */
+ break;
+ case 'f': /* ":tfirst" */
+ case 'r': cmd = DT_FIRST; /* ":trewind" */
+ break;
+ case 'l': cmd = DT_LAST; /* ":tlast" */
+ break;
+ default: /* ":tag" */
+ if (p_cst && *eap->arg != NUL) {
+ do_cstag(eap);
+ return;
+ }
+ cmd = DT_TAG;
+ break;
+ }
+
+ if (name[0] == 'l') {
+ cmd = DT_LTAG;
+ }
+
+ do_tag(eap->arg, cmd, eap->addr_count > 0 ? (int)eap->line2 : 1,
+ eap->forceit, TRUE);
+}
+
+/*
+ * Check "str" for starting with a special cmdline variable.
+ * If found return one of the SPEC_ values and set "*usedlen" to the length of
+ * the variable. Otherwise return -1 and "*usedlen" is unchanged.
+ */
+int find_cmdline_var(src, usedlen)
+char_u *src;
+int *usedlen;
+{
+ int len;
+ int i;
+ static char *(spec_str[]) = {
+ "%",
+#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
+ };
+
+ for (i = 0; i < (int)(sizeof(spec_str) / sizeof(char *)); ++i) {
+ len = (int)STRLEN(spec_str[i]);
+ if (STRNCMP(src, spec_str[i], len) == 0) {
+ *usedlen = len;
+ return i;
+ }
+ }
+ return -1;
+}
+
+/*
+ * Evaluate cmdline variables.
+ *
+ * change '%' to curbuf->b_ffname
+ * '#' to curwin->w_altfile
+ * '<cword>' to word under the cursor
+ * '<cWORD>' to WORD under the cursor
+ * '<cfile>' to path name under the cursor
+ * '<sfile>' to sourced file name
+ * '<slnum>' to sourced file line number
+ * '<afile>' to file name for autocommand
+ * '<abuf>' to buffer number for autocommand
+ * '<amatch>' to matching name for autocommand
+ *
+ * When an error is detected, "errormsg" is set to a non-NULL pointer (may be
+ * "" for error without a message) and NULL is returned.
+ * Returns an allocated string if a valid match was found.
+ * Returns NULL if no match was found. "usedlen" then still contains the
+ * number of characters to skip.
+ */
+char_u * eval_vars(src, srcstart, usedlen, lnump, errormsg, escaped)
+char_u *src; /* pointer into commandline */
+char_u *srcstart; /* beginning of valid memory for src */
+int *usedlen; /* characters after src that are used */
+linenr_T *lnump; /* line number for :e command, or NULL */
+char_u **errormsg; /* pointer to error message */
+int *escaped; /* return value has escaped white space (can
+ * be NULL) */
+{
+ int i;
+ char_u *s;
+ char_u *result;
+ char_u *resultbuf = NULL;
+ int resultlen;
+ buf_T *buf;
+ int valid = VALID_HEAD + VALID_PATH; /* assume valid result */
+ int spec_idx;
+ int skip_mod = FALSE;
+ char_u strbuf[30];
+
+ *errormsg = NULL;
+ if (escaped != NULL)
+ *escaped = FALSE;
+
+ /*
+ * Check if there is something to do.
+ */
+ spec_idx = find_cmdline_var(src, usedlen);
+ if (spec_idx < 0) { /* no match */
+ *usedlen = 1;
+ return NULL;
+ }
+
+ /*
+ * Skip when preceded with a backslash "\%" and "\#".
+ * Note: In "\\%" the % is also not recognized!
+ */
+ if (src > srcstart && src[-1] == '\\') {
+ *usedlen = 0;
+ STRMOVE(src - 1, src); /* remove backslash */
+ return NULL;
+ }
+
+ /*
+ * 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 (resultlen == 0) {
+ *errormsg = (char_u *)"";
+ return NULL;
+ }
+ }
+ /*
+ * '#': Alternate file name
+ * '%': Current file name
+ * File name under the cursor
+ * File name for autocommand
+ * and following modifiers
+ */
+ else {
+ switch (spec_idx) {
+ case SPEC_PERC: /* '%': current file */
+ if (curbuf->b_fname == NULL) {
+ result = (char_u *)"";
+ valid = 0; /* Must have ":p:h" to be valid */
+ } else
+ result = curbuf->b_fname;
+ break;
+
+ case SPEC_HASH: /* '#' or "#99": alternate file */
+ if (src[1] == '#') { /* "##": the argument list */
+ result = arg_all();
+ resultbuf = result;
+ *usedlen = 2;
+ if (escaped != NULL)
+ *escaped = TRUE;
+ skip_mod = TRUE;
+ break;
+ }
+ s = src + 1;
+ if (*s == '<') /* "#<99" uses v:oldfiles */
+ ++s;
+ i = (int)getdigits(&s);
+ *usedlen = (int)(s - src); /* length of what we expand */
+
+ if (src[1] == '<') {
+ 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);
+ if (result == NULL) {
+ *errormsg = (char_u *)"";
+ return NULL;
+ }
+ } else {
+ buf = buflist_findnr(i);
+ if (buf == NULL) {
+ *errormsg = (char_u *)_(
+ "E194: No alternate file name to substitute for '#'");
+ return NULL;
+ }
+ if (lnump != NULL)
+ *lnump = ECMD_LAST;
+ if (buf->b_fname == NULL) {
+ result = (char_u *)"";
+ valid = 0; /* Must have ":p:h" to be valid */
+ } else
+ result = buf->b_fname;
+ }
+ break;
+
+ case SPEC_CFILE: /* file name under cursor */
+ result = file_name_at_cursor(FNAME_MESS|FNAME_HYP, 1L, NULL);
+ if (result == NULL) {
+ *errormsg = (char_u *)"";
+ return NULL;
+ }
+ 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 = FullName_save(autocmd_fname, FALSE);
+ vim_free(autocmd_fname);
+ autocmd_fname = result;
+ }
+ if (result == NULL) {
+ *errormsg = (char_u *)_(
+ "E495: no autocommand file name to substitute for \"<afile>\"");
+ return NULL;
+ }
+ result = shorten_fname1(result);
+ break;
+
+ case SPEC_ABUF: /* buffer number for autocommand */
+ if (autocmd_bufnr <= 0) {
+ *errormsg = (char_u *)_(
+ "E496: no autocommand buffer number to substitute for \"<abuf>\"");
+ return NULL;
+ }
+ sprintf((char *)strbuf, "%d", autocmd_bufnr);
+ result = strbuf;
+ break;
+
+ case SPEC_AMATCH: /* match name for autocommand */
+ result = autocmd_match;
+ if (result == NULL) {
+ *errormsg = (char_u *)_(
+ "E497: no autocommand match name to substitute for \"<amatch>\"");
+ return NULL;
+ }
+ break;
+
+ case SPEC_SFILE: /* file name for ":so" command */
+ result = sourcing_name;
+ if (result == NULL) {
+ *errormsg = (char_u *)_(
+ "E498: no :source file name to substitute for \"<sfile>\"");
+ return NULL;
+ }
+ break;
+ case SPEC_SLNUM: /* line in file for ":so" command */
+ if (sourcing_name == NULL || sourcing_lnum == 0) {
+ *errormsg = (char_u *)_("E842: no line number to use for \"<slnum>\"");
+ return NULL;
+ }
+ sprintf((char *)strbuf, "%ld", (long)sourcing_lnum);
+ result = strbuf;
+ break;
+ }
+
+ resultlen = (int)STRLEN(result); /* length of new string */
+ if (src[*usedlen] == '<') { /* remove the file name extension */
+ ++*usedlen;
+ if ((s = vim_strrchr(result, '.')) != NULL && s >= gettail(result))
+ resultlen = (int)(s - result);
+ } else if (!skip_mod) {
+ valid |= modify_fname(src, usedlen, &result, &resultbuf,
+ &resultlen);
+ if (result == NULL) {
+ *errormsg = (char_u *)"";
+ return NULL;
+ }
+ }
+ }
+
+ if (resultlen == 0 || valid != VALID_HEAD + VALID_PATH) {
+ if (valid != VALID_HEAD + VALID_PATH)
+ /* xgettext:no-c-format */
+ *errormsg = (char_u *)_(
+ "E499: Empty file name for '%' or '#', only works with \":p:h\"");
+ else
+ *errormsg = (char_u *)_("E500: Evaluates to an empty string");
+ result = NULL;
+ } else
+ result = vim_strnsave(result, resultlen);
+ vim_free(resultbuf);
+ return result;
+}
+
+/*
+ * Concatenate all files in the argument list, separated by spaces, and return
+ * it in one allocated string.
+ * Spaces and backslashes in the file names are escaped with a backslash.
+ * Returns NULL when out of memory.
+ */
+static char_u * arg_all() {
+ int len;
+ int idx;
+ char_u *retval = NULL;
+ char_u *p;
+
+ /*
+ * Do this loop two times:
+ * first time: compute the total length
+ * second time: concatenate the names
+ */
+ for (;; ) {
+ len = 0;
+ for (idx = 0; idx < ARGCOUNT; ++idx) {
+ p = alist_name(&ARGLIST[idx]);
+ if (p != NULL) {
+ if (len > 0) {
+ /* insert a space in between names */
+ if (retval != NULL)
+ retval[len] = ' ';
+ ++len;
+ }
+ for (; *p != NUL; ++p) {
+ if (*p == ' ' || *p == '\\') {
+ /* insert a backslash */
+ if (retval != NULL)
+ retval[len] = '\\';
+ ++len;
+ }
+ if (retval != NULL)
+ retval[len] = *p;
+ ++len;
+ }
+ }
+ }
+
+ /* second time: break here */
+ if (retval != NULL) {
+ retval[len] = NUL;
+ break;
+ }
+
+ /* allocate memory */
+ retval = alloc((unsigned)len + 1);
+ if (retval == NULL)
+ break;
+ }
+
+ return retval;
+}
+
+/*
+ * Expand the <sfile> string in "arg".
+ *
+ * Returns an allocated string, or NULL for any error.
+ */
+char_u * expand_sfile(arg)
+char_u *arg;
+{
+ char_u *errormsg;
+ int len;
+ char_u *result;
+ char_u *newres;
+ char_u *repl;
+ int srclen;
+ char_u *p;
+
+ result = vim_strsave(arg);
+ if (result == NULL)
+ return NULL;
+
+ for (p = result; *p; ) {
+ if (STRNCMP(p, "<sfile>", 7) != 0)
+ ++p;
+ else {
+ /* replace "<sfile>" with the sourced file name, and do ":" stuff */
+ repl = eval_vars(p, result, &srclen, NULL, &errormsg, NULL);
+ if (errormsg != NULL) {
+ if (*errormsg)
+ emsg(errormsg);
+ vim_free(result);
+ return NULL;
+ }
+ if (repl == NULL) { /* no match (cannot happen) */
+ p += srclen;
+ continue;
+ }
+ len = (int)STRLEN(result) - srclen + (int)STRLEN(repl) + 1;
+ newres = alloc(len);
+ if (newres == NULL) {
+ vim_free(repl);
+ vim_free(result);
+ return NULL;
+ }
+ mch_memmove(newres, result, (size_t)(p - result));
+ STRCPY(newres + (p - result), repl);
+ len = (int)STRLEN(newres);
+ STRCAT(newres, p + srclen);
+ vim_free(repl);
+ vim_free(result);
+ result = newres;
+ p = newres + len; /* continue after the match */
+ }
+ }
+
+ return result;
+}
+
+static int ses_winsizes __ARGS((FILE *fd, int restore_size,
+ win_T *tab_firstwin));
+static int ses_win_rec __ARGS((FILE *fd, frame_T *fr));
+static frame_T *ses_skipframe __ARGS((frame_T *fr));
+static int ses_do_frame __ARGS((frame_T *fr));
+static int ses_do_win __ARGS((win_T *wp));
+static int ses_arglist __ARGS((FILE *fd, char *cmd, garray_T *gap, int fullname,
+ unsigned *flagp));
+static int ses_put_fname __ARGS((FILE *fd, char_u *name, unsigned *flagp));
+static int ses_fname __ARGS((FILE *fd, buf_T *buf, unsigned *flagp));
+
+/*
+ * Write openfile commands for the current buffers to an .exrc file.
+ * Return FAIL on error, OK otherwise.
+ */
+static int makeopens(fd, dirnow)
+FILE *fd;
+char_u *dirnow; /* Current directory name */
+{
+ buf_T *buf;
+ int only_save_windows = TRUE;
+ int nr;
+ int cnr = 1;
+ int restore_size = TRUE;
+ win_T *wp;
+ char_u *sname;
+ win_T *edited_win = NULL;
+ int tabnr;
+ win_T *tab_firstwin;
+ frame_T *tab_topframe;
+ int cur_arg_idx = 0;
+ int next_arg_idx = 0;
+
+ 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)
+ return FAIL;
+ if (ssop_flags & SSOP_GLOBALS)
+ if (store_session_globals(fd) == FAIL)
+ return FAIL;
+
+ /*
+ * Close all windows but one.
+ */
+ if (put_line(fd, "silent only") == FAIL)
+ return FAIL;
+
+ /*
+ * Now a :cd command to the session directory or the current directory
+ */
+ if (ssop_flags & SSOP_SESDIR) {
+ if (put_line(fd, "exe \"cd \" . escape(expand(\"<sfile>:p:h\"), ' ')")
+ == FAIL)
+ return FAIL;
+ } else if (ssop_flags & SSOP_CURDIR) {
+ sname = home_replace_save(NULL, globaldir != NULL ? globaldir : dirnow);
+ if (sname == NULL
+ || fputs("cd ", fd) < 0
+ || ses_put_fname(fd, sname, &ssop_flags) == FAIL
+ || put_eol(fd) == FAIL) {
+ vim_free(sname);
+ return FAIL;
+ }
+ vim_free(sname);
+ }
+
+ /*
+ * If there is an empty, unnamed buffer we will wipe it out later.
+ * Remember the buffer number.
+ */
+ if (put_line(fd,
+ "if expand('%') == '' && !&modified && line('$') <= 1 && getline(1) == ''")
+ ==
+ FAIL)
+ return FAIL;
+ if (put_line(fd, " let s:wipebuf = bufnr('%')") == FAIL)
+ return FAIL;
+ if (put_line(fd, "endif") == FAIL)
+ return FAIL;
+
+ /*
+ * Now save the current files, current buffer first.
+ */
+ if (put_line(fd, "set shortmess=aoO") == FAIL)
+ return FAIL;
+
+ /* Now put the other buffers into the buffer list */
+ for (buf = firstbuf; buf != NULL; buf = buf->b_next) {
+ if (!(only_save_windows && buf->b_nwindows == 0)
+ && !(buf->b_help && !(ssop_flags & SSOP_HELP))
+ && buf->b_fname != NULL
+ && buf->b_p_bl) {
+ if (fprintf(fd, "badd +%ld ", buf->b_wininfo == NULL ? 1L
+ : buf->b_wininfo->wi_fpos.lnum) < 0
+ || ses_fname(fd, buf, &ssop_flags) == FAIL)
+ return FAIL;
+ }
+ }
+
+ /* the global argument list */
+ if (ses_arglist(fd, "args", &global_alist.al_ga,
+ !(ssop_flags & SSOP_CURDIR), &ssop_flags) == FAIL)
+ return FAIL;
+
+ if (ssop_flags & SSOP_RESIZE) {
+ /* Note: after the restore we still check it worked!*/
+ if (fprintf(fd, "set lines=%ld columns=%ld", Rows, Columns) < 0
+ || put_eol(fd) == FAIL)
+ return FAIL;
+ }
+
+
+ /*
+ * May repeat putting Windows for each tab, when "tabpages" is in
+ * 'sessionoptions'.
+ * Don't use goto_tabpage(), it may change directory and trigger
+ * autocommands.
+ */
+ tab_firstwin = firstwin; /* first window in tab page "tabnr" */
+ tab_topframe = topframe;
+ for (tabnr = 1;; ++tabnr) {
+ int need_tabnew = FALSE;
+
+ 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;
+ } else {
+ tab_firstwin = tp->tp_firstwin;
+ tab_topframe = tp->tp_topframe;
+ }
+ if (tabnr > 1)
+ need_tabnew = TRUE;
+ }
+
+ /*
+ * Before creating the window layout, try loading one file. If this
+ * is aborted we don't end up with a number of useless windows.
+ * This may have side effects! (e.g., compressed or network file).
+ */
+ for (wp = tab_firstwin; wp != NULL; wp = wp->w_next) {
+ if (ses_do_win(wp)
+ && wp->w_buffer->b_ffname != NULL
+ && !wp->w_buffer->b_help
+ && !bt_nofile(wp->w_buffer)
+ ) {
+ if (fputs(need_tabnew ? "tabedit " : "edit ", fd) < 0
+ || ses_fname(fd, wp->w_buffer, &ssop_flags) == FAIL)
+ return FAIL;
+ need_tabnew = FALSE;
+ if (!wp->w_arg_idx_invalid)
+ edited_win = wp;
+ break;
+ }
+ }
+
+ /* If no file got edited create an empty tab page. */
+ if (need_tabnew && put_line(fd, "tabnew") == FAIL)
+ return FAIL;
+
+ /*
+ * Save current window layout.
+ */
+ if (put_line(fd, "set splitbelow splitright") == FAIL)
+ return FAIL;
+ if (ses_win_rec(fd, tab_topframe) == FAIL)
+ return FAIL;
+ if (!p_sb && put_line(fd, "set nosplitbelow") == FAIL)
+ return FAIL;
+ if (!p_spr && put_line(fd, "set nosplitright") == FAIL)
+ return FAIL;
+
+ /*
+ * Check if window sizes can be restored (no windows omitted).
+ * Remember the window number of the current window after restoring.
+ */
+ nr = 0;
+ for (wp = tab_firstwin; wp != NULL; wp = W_NEXT(wp)) {
+ if (ses_do_win(wp))
+ ++nr;
+ else
+ restore_size = FALSE;
+ if (curwin == wp)
+ cnr = nr;
+ }
+
+ /* Go to the first window. */
+ 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)
+ return FAIL;
+ if (nr > 1 && ses_winsizes(fd, restore_size, tab_firstwin) == FAIL)
+ return FAIL;
+
+ /*
+ * Restore the view of the window (options, file, cursor, etc.).
+ */
+ for (wp = tab_firstwin; wp != NULL; wp = wp->w_next) {
+ if (!ses_do_win(wp))
+ continue;
+ if (put_view(fd, wp, wp != edited_win, &ssop_flags,
+ cur_arg_idx) == FAIL)
+ return FAIL;
+ if (nr > 1 && put_line(fd, "wincmd w") == FAIL)
+ return FAIL;
+ next_arg_idx = wp->w_arg_idx;
+ }
+
+ /* The argument index in the first tab page is zero, need to set it in
+ * each window. For further tab pages it's the window where we do
+ * "tabedit". */
+ cur_arg_idx = next_arg_idx;
+
+ /*
+ * Restore cursor to the current window if it's not the first one.
+ */
+ if (cnr > 1 && (fprintf(fd, "%dwincmd w", cnr) < 0
+ || put_eol(fd) == FAIL))
+ return FAIL;
+
+ /*
+ * Restore window sizes again after jumping around in windows, because
+ * the current window has a minimum size while others may not.
+ */
+ if (nr > 1 && ses_winsizes(fd, restore_size, tab_firstwin) == 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))
+ break;
+ }
+
+ if (ssop_flags & SSOP_TABPAGES) {
+ if (fprintf(fd, "tabnext %d", tabpage_index(curtab)) < 0
+ || put_eol(fd) == FAIL)
+ return FAIL;
+ }
+
+ /*
+ * Wipe out an empty unnamed buffer we started in.
+ */
+ if (put_line(fd, "if exists('s:wipebuf')") == FAIL)
+ return FAIL;
+ if (put_line(fd, " silent exe 'bwipe ' . s:wipebuf") == FAIL)
+ return FAIL;
+ if (put_line(fd, "endif") == FAIL)
+ return FAIL;
+ if (put_line(fd, "unlet! s:wipebuf") == FAIL)
+ return FAIL;
+
+ /* Re-apply 'winheight', 'winwidth' and 'shortmess'. */
+ if (fprintf(fd, "set winheight=%ld winwidth=%ld shortmess=%s",
+ p_wh, p_wiw, p_shm) < 0 || put_eol(fd) == FAIL)
+ return FAIL;
+
+ /*
+ * Lastly, execute the x.vim file if it exists.
+ */
+ if (put_line(fd, "let s:sx = expand(\"<sfile>:p:r\").\"x.vim\"") == FAIL
+ || put_line(fd, "if file_readable(s:sx)") == FAIL
+ || put_line(fd, " exe \"source \" . fnameescape(s:sx)") == FAIL
+ || put_line(fd, "endif") == FAIL)
+ return FAIL;
+
+ return OK;
+}
+
+static int ses_winsizes(fd, restore_size, tab_firstwin)
+FILE *fd;
+int restore_size;
+win_T *tab_firstwin;
+{
+ int n = 0;
+ win_T *wp;
+
+ if (restore_size && (ssop_flags & SSOP_WINSIZE)) {
+ for (wp = tab_firstwin; wp != NULL; wp = wp->w_next) {
+ if (!ses_do_win(wp))
+ continue;
+ ++n;
+
+ /* restore height when not full height */
+ if (wp->w_height + wp->w_status_height < topframe->fr_height
+ && (fprintf(fd,
+ "exe '%dresize ' . ((&lines * %ld + %ld) / %ld)",
+ n, (long)wp->w_height, Rows / 2, Rows) < 0
+ || put_eol(fd) == FAIL))
+ return FAIL;
+
+ /* restore width when not full width */
+ if (wp->w_width < Columns && (fprintf(fd,
+ "exe 'vert %dresize ' . ((&columns * %ld + %ld) / %ld)",
+ n, (long)wp->w_width, Columns / 2,
+ Columns) < 0
+ || put_eol(fd) == FAIL))
+ return FAIL;
+ }
+ } else {
+ /* Just equalise window sizes */
+ if (put_line(fd, "wincmd =") == FAIL)
+ return FAIL;
+ }
+ return OK;
+}
+
+/*
+ * Write commands to "fd" to recursively create windows for frame "fr",
+ * horizontally and vertically split.
+ * After the commands the last window in the frame is the current window.
+ * Returns FAIL when writing the commands to "fd" fails.
+ */
+static int ses_win_rec(fd, fr)
+FILE *fd;
+frame_T *fr;
+{
+ frame_T *frc;
+ int count = 0;
+
+ if (fr->fr_layout != FR_LEAF) {
+ /* Find first frame that's not skipped and then create a window for
+ * each following one (first frame is already there). */
+ frc = ses_skipframe(fr->fr_child);
+ if (frc != NULL)
+ while ((frc = ses_skipframe(frc->fr_next)) != NULL) {
+ /* Make window as big as possible so that we have lots of room
+ * to split. */
+ if (put_line(fd, "wincmd _ | wincmd |") == FAIL
+ || put_line(fd, fr->fr_layout == FR_COL
+ ? "split" : "vsplit") == FAIL)
+ return FAIL;
+ ++count;
+ }
+
+ /* Go back to the first window. */
+ if (count > 0 && (fprintf(fd, fr->fr_layout == FR_COL
+ ? "%dwincmd k" : "%dwincmd h", count) < 0
+ || put_eol(fd) == FAIL))
+ return FAIL;
+
+ /* Recursively create frames/windows in each window of this column or
+ * row. */
+ frc = ses_skipframe(fr->fr_child);
+ while (frc != NULL) {
+ ses_win_rec(fd, frc);
+ frc = ses_skipframe(frc->fr_next);
+ /* Go to next window. */
+ if (frc != NULL && put_line(fd, "wincmd w") == FAIL)
+ return FAIL;
+ }
+ }
+ return OK;
+}
+
+/*
+ * Skip frames that don't contain windows we want to save in the Session.
+ * Returns NULL when there none.
+ */
+static frame_T * ses_skipframe(fr)
+frame_T *fr;
+{
+ frame_T *frc;
+
+ for (frc = fr; frc != NULL; frc = frc->fr_next)
+ if (ses_do_frame(frc))
+ break;
+ return frc;
+}
+
+/*
+ * Return TRUE if frame "fr" has a window somewhere that we want to save in
+ * the Session.
+ */
+static int ses_do_frame(fr)
+frame_T *fr;
+{
+ frame_T *frc;
+
+ if (fr->fr_layout == FR_LEAF)
+ return ses_do_win(fr->fr_win);
+ for (frc = fr->fr_child; frc != NULL; frc = frc->fr_next)
+ if (ses_do_frame(frc))
+ return TRUE;
+ return FALSE;
+}
+
+/*
+ * Return non-zero if window "wp" is to be stored in the Session.
+ */
+static int ses_do_win(wp)
+win_T *wp;
+{
+ if (wp->w_buffer->b_fname == NULL
+ /* When 'buftype' is "nofile" can't restore the window contents. */
+ || bt_nofile(wp->w_buffer)
+ )
+ return ssop_flags & SSOP_BLANK;
+ if (wp->w_buffer->b_help)
+ return ssop_flags & SSOP_HELP;
+ return TRUE;
+}
+
+/*
+ * Write commands to "fd" to restore the view of a window.
+ * Caller must make sure 'scrolloff' is zero.
+ */
+static int put_view(fd, wp, add_edit, flagp, current_arg_idx)
+FILE *fd;
+win_T *wp;
+int add_edit; /* add ":edit" command to view */
+unsigned *flagp; /* vop_flags or ssop_flags */
+int current_arg_idx; /* current argument index of the window, use
+ * -1 if unknown */
+{
+ win_T *save_curwin;
+ int f;
+ int do_cursor;
+ int did_next = FALSE;
+
+ /* Always restore cursor position for ":mksession". For ":mkview" only
+ * when 'viewoptions' contains "cursor". */
+ do_cursor = (flagp == &ssop_flags || *flagp & SSOP_CURSOR);
+
+ /*
+ * Local argument list.
+ */
+ if (wp->w_alist == &global_alist) {
+ if (put_line(fd, "argglobal") == FAIL)
+ return FAIL;
+ } else {
+ if (ses_arglist(fd, "arglocal", &wp->w_alist->al_ga,
+ flagp == &vop_flags
+ || !(*flagp & SSOP_CURDIR)
+ || wp->w_localdir != NULL, flagp) == FAIL)
+ return FAIL;
+ }
+
+ /* Only when part of a session: restore the argument index. Some
+ * arguments may have been deleted, check if the index is valid. */
+ if (wp->w_arg_idx != current_arg_idx && wp->w_arg_idx < WARGCOUNT(wp)
+ && flagp == &ssop_flags) {
+ if (fprintf(fd, "%ldargu", (long)wp->w_arg_idx + 1) < 0
+ || put_eol(fd) == FAIL)
+ return FAIL;
+ did_next = TRUE;
+ }
+
+ /* Edit the file. Skip this when ":next" already did it. */
+ if (add_edit && (!did_next || wp->w_arg_idx_invalid)) {
+ /*
+ * Load the file.
+ */
+ if (wp->w_buffer->b_ffname != NULL
+ && !bt_nofile(wp->w_buffer)
+ ) {
+ /*
+ * 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)
+ return FAIL;
+ } else {
+ /* 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. */
+ if (fputs("file ", fd) < 0
+ || ses_fname(fd, wp->w_buffer, flagp) == FAIL)
+ return FAIL;
+ }
+ do_cursor = FALSE;
+ }
+ }
+
+ /*
+ * Local mappings and abbreviations.
+ */
+ if ((*flagp & (SSOP_OPTIONS | SSOP_LOCALOPTIONS))
+ && makemap(fd, wp->w_buffer) == FAIL)
+ return FAIL;
+
+ /*
+ * Local options. Need to go to the window temporarily.
+ * Store only local values when using ":mkview" and when ":mksession" is
+ * used and 'sessionoptions' doesn't include "options".
+ * Some folding options are always stored when "folds" is included,
+ * otherwise the folds would not be restored correctly.
+ */
+ save_curwin = curwin;
+ curwin = wp;
+ curbuf = curwin->w_buffer;
+ if (*flagp & (SSOP_OPTIONS | SSOP_LOCALOPTIONS))
+ f = makeset(fd, OPT_LOCAL,
+ flagp == &vop_flags || !(*flagp & SSOP_OPTIONS));
+ else if (*flagp & SSOP_FOLDS)
+ f = makefoldset(fd);
+ else
+ f = OK;
+ curwin = save_curwin;
+ curbuf = curwin->w_buffer;
+ if (f == FAIL)
+ return FAIL;
+
+ /*
+ * Save Folds when 'buftype' is empty and for help files.
+ */
+ if ((*flagp & SSOP_FOLDS)
+ && wp->w_buffer->b_ffname != NULL
+ && (*wp->w_buffer->b_p_bt == NUL || wp->w_buffer->b_help)
+ ) {
+ if (put_folds(fd, wp) == FAIL)
+ return FAIL;
+ }
+
+ /*
+ * Set the cursor after creating folds, since that moves the cursor.
+ */
+ if (do_cursor) {
+
+ /* Restore the cursor line in the file and relatively in the
+ * window. Don't use "G", it changes the jumplist. */
+ if (fprintf(fd, "let s:l = %ld - ((%ld * winheight(0) + %ld) / %ld)",
+ (long)wp->w_cursor.lnum,
+ (long)(wp->w_cursor.lnum - wp->w_topline),
+ (long)wp->w_height / 2, (long)wp->w_height) < 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
+ || put_line(fd, "normal! zt") == FAIL
+ || fprintf(fd, "%ld", (long)wp->w_cursor.lnum) < 0
+ || put_eol(fd) == FAIL)
+ return FAIL;
+ /* Restore the cursor column and left offset when not wrapping. */
+ if (wp->w_cursor.col == 0) {
+ if (put_line(fd, "normal! 0") == FAIL)
+ return FAIL;
+ } else {
+ if (!wp->w_p_wrap && wp->w_leftcol > 0 && wp->w_width > 0) {
+ if (fprintf(fd,
+ "let s:c = %ld - ((%ld * winwidth(0) + %ld) / %ld)",
+ (long)wp->w_virtcol + 1,
+ (long)(wp->w_virtcol - wp->w_leftcol),
+ (long)wp->w_width / 2, (long)wp->w_width) < 0
+ || put_eol(fd) == FAIL
+ || put_line(fd, "if s:c > 0") == FAIL
+ || fprintf(fd,
+ " exe 'normal! ' . s:c . '|zs' . %ld . '|'",
+ (long)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_line(fd, "endif") == FAIL)
+ return FAIL;
+ } else {
+ if (fprintf(fd, "normal! 0%d|", wp->w_virtcol + 1) < 0
+ || put_eol(fd) == FAIL)
+ return FAIL;
+ }
+ }
+ }
+
+ /*
+ * Local directory.
+ */
+ if (wp->w_localdir != NULL) {
+ if (fputs("lcd ", fd) < 0
+ || ses_put_fname(fd, wp->w_localdir, flagp) == FAIL
+ || put_eol(fd) == FAIL)
+ return FAIL;
+ did_lcd = TRUE;
+ }
+
+ return OK;
+}
+
+/*
+ * Write an argument list to the session file.
+ * Returns FAIL if writing fails.
+ */
+static int ses_arglist(fd, cmd, gap, fullname, flagp)
+FILE *fd;
+char *cmd;
+garray_T *gap;
+int fullname; /* TRUE: use full path name */
+unsigned *flagp;
+{
+ int i;
+ char_u *buf = NULL;
+ char_u *s;
+
+ if (gap->ga_len == 0)
+ return put_line(fd, "silent! argdel *");
+ if (fputs(cmd, fd) < 0)
+ return FAIL;
+ for (i = 0; i < gap->ga_len; ++i) {
+ /* NULL file names are skipped (only happens when out of memory). */
+ s = alist_name(&((aentry_T *)gap->ga_data)[i]);
+ if (s != NULL) {
+ if (fullname) {
+ buf = alloc(MAXPATHL);
+ if (buf != NULL) {
+ (void)vim_FullName(s, buf, MAXPATHL, FALSE);
+ s = buf;
+ }
+ }
+ if (fputs(" ", fd) < 0 || ses_put_fname(fd, s, flagp) == FAIL) {
+ vim_free(buf);
+ return FAIL;
+ }
+ vim_free(buf);
+ }
+ }
+ return put_eol(fd);
+}
+
+/*
+ * Write a buffer name to the session file.
+ * Also ends the line.
+ * Returns FAIL if writing fails.
+ */
+static int ses_fname(fd, buf, flagp)
+FILE *fd;
+buf_T *buf;
+unsigned *flagp;
+{
+ char_u *name;
+
+ /* Use the short file name if the current directory is known at the time
+ * the session file will be sourced.
+ * Don't do this for ":mkview", we don't know the current directory.
+ * Don't do this after ":lcd", we don't keep track of what the current
+ * directory is. */
+ if (buf->b_sfname != NULL
+ && flagp == &ssop_flags
+ && (ssop_flags & (SSOP_CURDIR | SSOP_SESDIR))
+ && !p_acd
+ && !did_lcd)
+ name = buf->b_sfname;
+ else
+ name = buf->b_ffname;
+ if (ses_put_fname(fd, name, flagp) == FAIL || put_eol(fd) == FAIL)
+ return FAIL;
+ return OK;
+}
+
+/*
+ * Write a file name to the session file.
+ * Takes care of the "slash" option in 'sessionoptions' and escapes special
+ * characters.
+ * Returns FAIL if writing fails or out of memory.
+ */
+static int ses_put_fname(fd, name, flagp)
+FILE *fd;
+char_u *name;
+unsigned *flagp;
+{
+ char_u *sname;
+ char_u *p;
+ int retval = OK;
+
+ sname = home_replace_save(NULL, name);
+ if (sname == NULL)
+ return FAIL;
+
+ if (*flagp & SSOP_SLASH) {
+ /* 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);
+ vim_free(sname);
+ if (p == NULL)
+ return FAIL;
+
+ /* write the result */
+ if (fputs((char *)p, fd) < 0)
+ retval = FAIL;
+
+ vim_free(p);
+ return retval;
+}
+
+/*
+ * ":loadview [nr]"
+ */
+static void ex_loadview(eap)
+exarg_T *eap;
+{
+ char_u *fname;
+
+ fname = get_view_file(*eap->arg);
+ if (fname != NULL) {
+ do_source(fname, FALSE, DOSO_NONE);
+ vim_free(fname);
+ }
+}
+
+/*
+ * Get the name of the view file for the current buffer.
+ */
+static char_u * get_view_file(c)
+int c;
+{
+ int len = 0;
+ char_u *p, *s;
+ char_u *retval;
+ char_u *sname;
+
+ if (curbuf->b_ffname == NULL) {
+ EMSG(_(e_noname));
+ return NULL;
+ }
+ sname = home_replace_save(NULL, curbuf->b_ffname);
+ if (sname == NULL)
+ return NULL;
+
+ /*
+ * We want a file name without separators, because we're not going to make
+ * a directory.
+ * "normal" path separator -> "=+"
+ * "=" -> "=="
+ * ":" path separator -> "=-"
+ */
+ for (p = sname; *p; ++p)
+ if (*p == '=' || vim_ispathsep(*p))
+ ++len;
+ retval = alloc((unsigned)(STRLEN(sname) + len + STRLEN(p_vdir) + 9));
+ if (retval != NULL) {
+ STRCPY(retval, p_vdir);
+ add_pathsep(retval);
+ s = retval + STRLEN(retval);
+ for (p = sname; *p; ++p) {
+ if (*p == '=') {
+ *s++ = '=';
+ *s++ = '=';
+ } else if (vim_ispathsep(*p)) {
+ *s++ = '=';
+#if defined(BACKSLASH_IN_FILENAME) || defined(AMIGA) || defined(VMS)
+ if (*p == ':')
+ *s++ = '-';
+ else
+#endif
+ *s++ = '+';
+ } else
+ *s++ = *p;
+ }
+ *s++ = '=';
+ *s++ = c;
+ STRCPY(s, ".vim");
+ }
+
+ vim_free(sname);
+ return retval;
+}
+
+
+/*
+ * Write end-of-line character(s) for ":mkexrc", ":mkvimrc" and ":mksession".
+ * Return FAIL for a write error.
+ */
+int put_eol(fd)
+FILE *fd;
+{
+ if (
+#ifdef USE_CRNL
+ (
+# ifdef MKSESSION_NL
+ !mksession_nl &&
+# endif
+ (putc('\r', fd) < 0)) ||
+#endif
+ (putc('\n', fd) < 0))
+ return FAIL;
+ return OK;
+}
+
+/*
+ * Write a line to "fd".
+ * Return FAIL for a write error.
+ */
+int put_line(fd, s)
+FILE *fd;
+char *s;
+{
+ if (fputs(s, fd) < 0 || put_eol(fd) == FAIL)
+ return FAIL;
+ return OK;
+}
+
+/*
+ * ":rviminfo" and ":wviminfo".
+ */
+static void ex_viminfo(eap)
+exarg_T *eap;
+{
+ char_u *save_viminfo;
+
+ save_viminfo = p_viminfo;
+ if (*p_viminfo == NUL)
+ p_viminfo = (char_u *)"'100";
+ if (eap->cmdidx == CMD_rviminfo) {
+ if (read_viminfo(eap->arg, VIF_WANT_INFO | VIF_WANT_MARKS
+ | (eap->forceit ? VIF_FORCEIT : 0)) == FAIL)
+ EMSG(_("E195: Cannot open viminfo file for reading"));
+ } else
+ write_viminfo(eap->arg, eap->forceit);
+ p_viminfo = save_viminfo;
+}
+
+/*
+ * Make a dialog message in "buff[DIALOG_MSG_SIZE]".
+ * "format" must contain "%s".
+ */
+void dialog_msg(buff, format, fname)
+char_u *buff;
+char *format;
+char_u *fname;
+{
+ if (fname == NULL)
+ fname = (char_u *)_("Untitled");
+ vim_snprintf((char *)buff, DIALOG_MSG_SIZE, format, fname);
+}
+
+/*
+ * ":behave {mswin,xterm}"
+ */
+static void ex_behave(eap)
+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);
+ } 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
+ EMSG2(_(e_invarg2), eap->arg);
+}
+
+/*
+ * Function given to ExpandGeneric() to obtain the possible arguments of the
+ * ":behave {mswin,xterm}" command.
+ */
+char_u * get_behave_arg(xp, idx)
+expand_T *xp UNUSED;
+int idx;
+{
+ if (idx == 0)
+ return (char_u *)"mswin";
+ if (idx == 1)
+ return (char_u *)"xterm";
+ return NULL;
+}
+
+static int filetype_detect = FALSE;
+static int filetype_plugin = FALSE;
+static int filetype_indent = FALSE;
+
+/*
+ * ":filetype [plugin] [indent] {on,off,detect}"
+ * on: Load the filetype.vim file to install autocommands for file types.
+ * off: Load the ftoff.vim file to remove all autocommands for file types.
+ * plugin on: load filetype.vim and ftplugin.vim
+ * plugin off: load ftplugof.vim
+ * indent on: load filetype.vim and indent.vim
+ * indent off: load indoff.vim
+ */
+static void ex_filetype(eap)
+exarg_T *eap;
+{
+ char_u *arg = eap->arg;
+ int plugin = FALSE;
+ int indent = FALSE;
+
+ if (*eap->arg == NUL) {
+ /* Print current status. */
+ smsg((char_u *)"filetype detection:%s plugin:%s indent:%s",
+ filetype_detect ? "ON" : "OFF",
+ filetype_plugin ? (filetype_detect ? "ON" : "(on)") : "OFF",
+ filetype_indent ? (filetype_detect ? "ON" : "(on)") : "OFF");
+ return;
+ }
+
+ /* Accept "plugin" and "indent" in any order. */
+ for (;; ) {
+ if (STRNCMP(arg, "plugin", 6) == 0) {
+ plugin = TRUE;
+ arg = skipwhite(arg + 6);
+ continue;
+ }
+ if (STRNCMP(arg, "indent", 6) == 0) {
+ indent = TRUE;
+ arg = skipwhite(arg + 6);
+ continue;
+ }
+ break;
+ }
+ if (STRCMP(arg, "on") == 0 || STRCMP(arg, "detect") == 0) {
+ if (*arg == 'o' || !filetype_detect) {
+ source_runtime((char_u *)FILETYPE_FILE, TRUE);
+ filetype_detect = TRUE;
+ if (plugin) {
+ source_runtime((char_u *)FTPLUGIN_FILE, TRUE);
+ filetype_plugin = TRUE;
+ }
+ if (indent) {
+ source_runtime((char_u *)INDENT_FILE, TRUE);
+ filetype_indent = TRUE;
+ }
+ }
+ if (*arg == 'd') {
+ (void)do_doautocmd((char_u *)"filetypedetect BufRead", TRUE);
+ do_modelines(0);
+ }
+ } else if (STRCMP(arg, "off") == 0) {
+ if (plugin || indent) {
+ if (plugin) {
+ source_runtime((char_u *)FTPLUGOF_FILE, TRUE);
+ filetype_plugin = FALSE;
+ }
+ if (indent) {
+ source_runtime((char_u *)INDOFF_FILE, TRUE);
+ filetype_indent = FALSE;
+ }
+ } else {
+ source_runtime((char_u *)FTOFF_FILE, TRUE);
+ filetype_detect = FALSE;
+ }
+ } else
+ EMSG2(_(e_invarg2), arg);
+}
+
+/*
+ * ":setfiletype {name}"
+ */
+static void ex_setfiletype(eap)
+exarg_T *eap;
+{
+ if (!did_filetype)
+ set_option_value((char_u *)"filetype", 0L, eap->arg, OPT_LOCAL);
+}
+
+static void ex_digraphs(eap)
+exarg_T *eap UNUSED;
+{
+ if (*eap->arg != NUL)
+ putdigraph(eap->arg);
+ else
+ listdigraphs();
+}
+
+static void ex_set(eap)
+exarg_T *eap;
+{
+ int flags = 0;
+
+ if (eap->cmdidx == CMD_setlocal)
+ flags = OPT_LOCAL;
+ else if (eap->cmdidx == CMD_setglobal)
+ flags = OPT_GLOBAL;
+ (void)do_set(eap->arg, flags);
+}
+
+/*
+ * ":nohlsearch"
+ */
+static void ex_nohlsearch(eap)
+exarg_T *eap UNUSED;
+{
+ SET_NO_HLSEARCH(TRUE);
+ redraw_all_later(SOME_VALID);
+}
+
+/*
+ * ":[N]match {group} {pattern}"
+ * Sets nextcmd to the start of the next command, if any. Also called when
+ * skipping commands to find the next command.
+ */
+static void ex_match(eap)
+exarg_T *eap;
+{
+ char_u *p;
+ char_u *g = NULL;
+ char_u *end;
+ int c;
+ int id;
+
+ if (eap->line2 <= 3)
+ id = eap->line2;
+ else {
+ EMSG(e_invcmd);
+ return;
+ }
+
+ /* First clear any old pattern. */
+ if (!eap->skip)
+ match_delete(curwin, id, FALSE);
+
+ if (ends_excmd(*eap->arg))
+ end = eap->arg;
+ else if ((STRNICMP(eap->arg, "none", 4) == 0
+ && (vim_iswhite(eap->arg[4]) || ends_excmd(eap->arg[4]))))
+ end = eap->arg + 4;
+ else {
+ p = skiptowhite(eap->arg);
+ if (!eap->skip)
+ g = vim_strnsave(eap->arg, (int)(p - eap->arg));
+ p = skipwhite(p);
+ if (*p == NUL) {
+ /* There must be two arguments. */
+ EMSG2(_(e_invarg2), eap->arg);
+ return;
+ }
+ end = skip_regexp(p + 1, *p, TRUE, NULL);
+ if (!eap->skip) {
+ if (*end != NUL && !ends_excmd(*skipwhite(end + 1))) {
+ eap->errmsg = e_trailing;
+ return;
+ }
+ if (*end != *p) {
+ EMSG2(_(e_invarg2), p);
+ return;
+ }
+
+ c = *end;
+ *end = NUL;
+ match_add(curwin, g, p + 1, 10, id);
+ vim_free(g);
+ *end = c;
+ }
+ }
+ eap->nextcmd = find_nextcmd(end);
+}
+
+/*
+ * ":X": Get crypt key
+ */
+static void ex_X(eap)
+exarg_T *eap UNUSED;
+{
+ if (get_crypt_method(curbuf) == 0 || blowfish_self_test() == OK)
+ (void)get_crypt_key(TRUE, TRUE);
+}
+
+static void ex_fold(eap)
+exarg_T *eap;
+{
+ if (foldManualAllowed(TRUE))
+ foldCreate(eap->line1, eap->line2);
+}
+
+static void ex_foldopen(eap)
+exarg_T *eap;
+{
+ opFoldRange(eap->line1, eap->line2, eap->cmdidx == CMD_foldopen,
+ eap->forceit, FALSE);
+}
+
+static void ex_folddo(eap)
+exarg_T *eap;
+{
+ linenr_T lnum;
+
+ /* 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))
+ ml_setmarked(lnum);
+
+ /* Execute the command on the marked lines. */
+ global_exe(eap->arg);
+ ml_clearmarked(); /* clear rest of the marks */
+}
diff --git a/src/ex_eval.c b/src/ex_eval.c
new file mode 100644
index 0000000000..5f845c3f33
--- /dev/null
+++ b/src/ex_eval.c
@@ -0,0 +1,2113 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * 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.
+ */
+
+/*
+ * ex_eval.c: functions for Ex command line for the +eval feature.
+ */
+
+#include "vim.h"
+
+
+static void free_msglist __ARGS((struct msglist *l));
+static int throw_exception __ARGS((void *, int, char_u *));
+static char_u *get_end_emsg __ARGS((struct condstack *cstack));
+
+/*
+ * 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
+
+static void catch_exception __ARGS((except_T *excp));
+static void finish_exception __ARGS((except_T *excp));
+static void discard_exception __ARGS((except_T *excp, int was_finished));
+static void report_pending __ARGS((int action, int pending, void *value));
+
+/*
+ * When several errors appear in a row, setting "force_abort" is delayed until
+ * the failing command returned. "cause_abort" is set to TRUE meanwhile, in
+ * order to indicate that situation. This is useful when "force_abort" was set
+ * during execution of a function call from an expression: the aborting of the
+ * expression evaluation is done without producing any error messages, but all
+ * error messages on parsing errors during the expression evaluation are given
+ * (even if a try conditional is active).
+ */
+static int cause_abort = FALSE;
+
+/*
+ * Return TRUE when immediately aborting on error, or when an interrupt
+ * occurred or an exception was thrown but not caught. Use for ":{range}call"
+ * to check whether an aborted function that does not handle a range itself
+ * should be called again for the next line in the range. Also used for
+ * cancelling expression evaluation after a function call caused an immediate
+ * abort. Note that the first emsg() call temporarily resets "force_abort"
+ * until the throw point for error messages has been reached. That is, during
+ * cancellation of an expression evaluation after an aborting function call or
+ * due to a parsing error, aborting() always returns the same value.
+ */
+int aborting() {
+ return (did_emsg && force_abort) || got_int || did_throw;
+}
+
+/*
+ * The value of "force_abort" is temporarily reset by the first emsg() call
+ * during an expression evaluation, and "cause_abort" is used instead. It might
+ * be necessary to restore "force_abort" even before the throw point for the
+ * error message has been reached. update_force_abort() should be called then.
+ */
+void update_force_abort() {
+ if (cause_abort)
+ force_abort = TRUE;
+}
+
+/*
+ * Return TRUE if a command with a subcommand resulting in "retcode" should
+ * abort the script processing. Can be used to suppress an autocommand after
+ * execution of a failing subcommand as long as the error message has not been
+ * displayed and actually caused the abortion.
+ */
+int should_abort(retcode)
+int retcode;
+{
+ return (retcode == FAIL && trylevel != 0 && !emsg_silent) || aborting();
+}
+
+/*
+ * Return TRUE if a function with the "abort" flag should not be considered
+ * ended on an error. This means that parsing commands is continued in order
+ * to find finally clauses to be executed, and that some errors in skipped
+ * commands are still reported.
+ */
+int aborted_in_try() {
+ /* This function is only called after an error. In this case, "force_abort"
+ * determines whether searching for finally clauses is necessary. */
+ return force_abort;
+}
+
+/*
+ * cause_errthrow(): Cause a throw of an error exception if appropriate.
+ * Return TRUE if the error message should not be displayed by emsg().
+ * Sets "ignore", if the emsg() call should be ignored completely.
+ *
+ * When several messages appear in the same command, the first is usually the
+ * most specific one and used as the exception value. The "severe" flag can be
+ * set to TRUE, if a later but severer message should be used instead.
+ */
+int cause_errthrow(mesg, severe, ignore)
+char_u *mesg;
+int severe;
+int *ignore;
+{
+ struct msglist *elem;
+ struct msglist **plist;
+
+ /*
+ * Do nothing when displaying the interrupt message or reporting an
+ * uncaught exception (which has already been discarded then) at the top
+ * level. Also when no exception can be thrown. The message will be
+ * displayed by emsg().
+ */
+ if (suppress_errthrow)
+ return FALSE;
+
+ /*
+ * If emsg() has not been called previously, temporarily reset
+ * "force_abort" until the throw point for error messages has been
+ * reached. This ensures that aborting() returns the same value for all
+ * errors that appear in the same command. This means particularly that
+ * for parsing errors during expression evaluation emsg() will be called
+ * multiply, even when the expression is evaluated from a finally clause
+ * that was activated due to an aborting error, interrupt, or exception.
+ */
+ if (!did_emsg) {
+ cause_abort = force_abort;
+ force_abort = FALSE;
+ }
+
+ /*
+ * If no try conditional is active and no exception is being thrown and
+ * there has not been an error in a try conditional or a throw so far, do
+ * nothing (for compatibility of non-EH scripts). The message will then
+ * be displayed by emsg(). When ":silent!" was used and we are not
+ * 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;
+
+ /*
+ * Ignore an interrupt message when inside a try conditional or when an
+ * exception is being thrown or when an error in a try conditional or
+ * throw has been detected previously. This is important in order that an
+ * interrupt exception is catchable by the innermost try conditional and
+ * not replaced by an interrupt message error exception.
+ */
+ if (mesg == (char_u *)_(e_interr)) {
+ *ignore = TRUE;
+ return TRUE;
+ }
+
+ /*
+ * Ensure that all commands in nested function calls and sourced files
+ * are aborted immediately.
+ */
+ cause_abort = TRUE;
+
+ /*
+ * When an exception is being thrown, some commands (like conditionals) are
+ * not skipped. Errors in those commands may affect what of the subsequent
+ * commands are regarded part of catch and finally clauses. Catching the
+ * exception would then cause execution of commands not intended by the
+ * user, who wouldn't even get aware of the problem. Therefor, discard the
+ * 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;
+ discard_current_exception();
+ }
+
+#ifdef THROW_TEST
+ if (!THROW_ON_ERROR) {
+ /*
+ * Print error message immediately without searching for a matching
+ * catch clause; just finally clauses are executed before the script
+ * is terminated.
+ */
+ return FALSE;
+ } else
+#endif
+ {
+ /*
+ * Prepare the throw of an error exception, so that everything will
+ * be aborted (except for executing finally clauses), until the error
+ * exception is caught; if still uncaught at the top level, the error
+ * message will be displayed and the script processing terminated
+ * then. - This function has no access to the conditional stack.
+ * Thus, the actual throw is made after the failing command has
+ * returned. - Throw only the first of several errors in a row, except
+ * a severe error is following.
+ */
+ if (msg_list != NULL) {
+ plist = msg_list;
+ while (*plist != NULL)
+ plist = &(*plist)->next;
+
+ elem = (struct msglist *)alloc((unsigned)sizeof(struct msglist));
+ if (elem == NULL) {
+ suppress_errthrow = TRUE;
+ EMSG(_(e_outofmem));
+ } else {
+ elem->msg = vim_strsave(mesg);
+ if (elem->msg == NULL) {
+ vim_free(elem);
+ suppress_errthrow = TRUE;
+ EMSG(_(e_outofmem));
+ } else {
+ elem->next = NULL;
+ elem->throw_msg = NULL;
+ *plist = elem;
+ if (plist == msg_list || severe) {
+ char_u *tmsg;
+
+ /* Skip the extra "Vim " prefix for message "E458". */
+ tmsg = elem->msg;
+ if (STRNCMP(tmsg, "Vim E", 5) == 0
+ && VIM_ISDIGIT(tmsg[5])
+ && VIM_ISDIGIT(tmsg[6])
+ && VIM_ISDIGIT(tmsg[7])
+ && tmsg[8] == ':'
+ && tmsg[9] == ' ')
+ (*msg_list)->throw_msg = &tmsg[4];
+ else
+ (*msg_list)->throw_msg = tmsg;
+ }
+ }
+ }
+ }
+ return TRUE;
+ }
+}
+
+/*
+ * Free a "msg_list" and the messages it contains.
+ */
+static void free_msglist(l)
+struct msglist *l;
+{
+ struct msglist *messages, *next;
+
+ messages = l;
+ while (messages != NULL) {
+ next = messages->next;
+ vim_free(messages->msg);
+ vim_free(messages);
+ messages = next;
+ }
+}
+
+/*
+ * Free global "*msg_list" and the messages it contains, then set "*msg_list"
+ * to NULL.
+ */
+void free_global_msglist() {
+ free_msglist(*msg_list);
+ *msg_list = NULL;
+}
+
+/*
+ * Throw the message specified in the call to cause_errthrow() above as an
+ * error exception. If cstack is NULL, postpone the throw until do_cmdline()
+ * has returned (see do_one_cmd()).
+ */
+void do_errthrow(cstack, cmdname)
+struct condstack *cstack;
+char_u *cmdname;
+{
+ /*
+ * Ensure that all commands in nested function calls and sourced files
+ * are aborted immediately.
+ */
+ if (cause_abort) {
+ cause_abort = FALSE;
+ force_abort = TRUE;
+ }
+
+ /* If no exception is to be thrown or the conversion should be done after
+ * returning to a previous invocation of do_one_cmd(), do nothing. */
+ if (msg_list == NULL || *msg_list == NULL)
+ return;
+
+ if (throw_exception(*msg_list, ET_ERROR, cmdname) == FAIL)
+ free_msglist(*msg_list);
+ else {
+ if (cstack != NULL)
+ do_throw(cstack);
+ else
+ need_rethrow = TRUE;
+ }
+ *msg_list = NULL;
+}
+
+/*
+ * do_intthrow(): Replace the current exception by an interrupt or interrupt
+ * exception if appropriate. Return TRUE if the current exception is discarded,
+ * FALSE otherwise.
+ */
+int do_intthrow(cstack)
+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;
+
+#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)
+ discard_current_exception();
+ } 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;
+
+ /* An interrupt exception replaces any user or error exception. */
+ discard_current_exception();
+ }
+ if (throw_exception("Vim:Interrupt", ET_INTERRUPT, NULL) != FAIL)
+ do_throw(cstack);
+ }
+
+ return TRUE;
+}
+
+/*
+ * Get an exception message that is to be stored in current_exception->value.
+ */
+char_u * get_exception_string(value, type, cmdname, should_free)
+void *value;
+int type;
+char_u *cmdname;
+int *should_free;
+{
+ char_u *ret, *mesg;
+ int cmdlen;
+ char_u *p, *val;
+
+ if (type == ET_ERROR) {
+ *should_free = FALSE;
+ mesg = ((struct msglist *)value)->throw_msg;
+ if (cmdname != NULL && *cmdname != NUL) {
+ cmdlen = (int)STRLEN(cmdname);
+ ret = vim_strnsave((char_u *)"Vim(",
+ 4 + cmdlen + 2 + (int)STRLEN(mesg));
+ if (ret == NULL)
+ return ret;
+ STRCPY(&ret[4], cmdname);
+ STRCPY(&ret[4 + cmdlen], "):");
+ val = ret + 4 + cmdlen + 2;
+ } else {
+ ret = vim_strnsave((char_u *)"Vim:", 4 + (int)STRLEN(mesg));
+ if (ret == NULL)
+ return ret;
+ val = ret + 4;
+ }
+
+ /* msg_add_fname may have been used to prefix the message with a file
+ * name in quotes. In the exception value, put the file name in
+ * parentheses and move it to the end. */
+ for (p = mesg;; p++) {
+ if (*p == NUL
+ || (*p == 'E'
+ && VIM_ISDIGIT(p[1])
+ && (p[2] == ':'
+ || (VIM_ISDIGIT(p[2])
+ && (p[3] == ':'
+ || (VIM_ISDIGIT(p[3])
+ && p[4] == ':')))))) {
+ if (*p == NUL || p == mesg)
+ STRCAT(val, mesg); /* 'E123' missing or at beginning */
+ else {
+ /* '"filename" E123: message text' */
+ if (mesg[0] != '"' || p-2 < &mesg[1] ||
+ p[-2] != '"' || p[-1] != ' ')
+ /* "E123:" is part of the file name. */
+ continue;
+
+ STRCAT(val, p);
+ p[-2] = NUL;
+ sprintf((char *)(val + STRLEN(p)), " (%s)", &mesg[1]);
+ p[-2] = '"';
+ }
+ break;
+ }
+ }
+ } else {
+ *should_free = FALSE;
+ ret = (char_u *) value;
+ }
+
+ return ret;
+}
+
+
+/*
+ * 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(value, type, cmdname)
+void *value;
+int type;
+char_u *cmdname;
+{
+ except_T *excp;
+ int should_free;
+
+ /*
+ * Disallow faking Interrupt or error exceptions as user exceptions. They
+ * would be treated differently from real interrupt or error exceptions
+ * when no active try block is found, see do_cmdline().
+ */
+ if (type == ET_USER) {
+ if (STRNCMP((char_u *)value, "Vim", 3) == 0
+ && (((char_u *)value)[3] == NUL || ((char_u *)value)[3] == ':'
+ || ((char_u *)value)[3] == '(')) {
+ EMSG(_("E608: Cannot :throw exceptions with 'Vim' prefix"));
+ goto fail;
+ }
+ }
+
+ excp = (except_T *)alloc((unsigned)sizeof(except_T));
+ if (excp == NULL)
+ goto nomem;
+
+ if (type == ET_ERROR)
+ /* Store the original message and prefix the exception value with
+ * "Vim:" or, if a command name is given, "Vim(cmdname):". */
+ excp->messages = (struct msglist *)value;
+
+ excp->value = get_exception_string(value, type, cmdname, &should_free);
+ if (excp->value == NULL && should_free)
+ goto nomem;
+
+ excp->type = type;
+ excp->throw_name = vim_strsave(sourcing_name == NULL
+ ? (char_u *)"" : sourcing_name);
+ if (excp->throw_name == NULL) {
+ if (should_free)
+ vim_free(excp->value);
+ goto nomem;
+ }
+ excp->throw_lnum = sourcing_lnum;
+
+ if (p_verbose >= 13 || debug_break_level > 0) {
+ int save_msg_silent = msg_silent;
+
+ if (debug_break_level > 0)
+ msg_silent = FALSE; /* display messages */
+ else
+ verbose_enter();
+ ++no_wait_return;
+ if (debug_break_level > 0 || *p_vfile == NUL)
+ msg_scroll = TRUE; /* always scroll up, don't overwrite */
+
+ smsg((char_u *)_("Exception thrown: %s"), excp->value);
+ msg_puts((char_u *)"\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)
+ msg_silent = save_msg_silent;
+ else
+ verbose_leave();
+ }
+
+ current_exception = excp;
+ return OK;
+
+nomem:
+ vim_free(excp);
+ suppress_errthrow = TRUE;
+ EMSG(_(e_outofmem));
+fail:
+ current_exception = NULL;
+ return FAIL;
+}
+
+/*
+ * Discard an exception. "was_finished" is set when the exception has been
+ * caught and the catch clause has been ended normally.
+ */
+static void discard_exception(excp, was_finished)
+except_T *excp;
+int was_finished;
+{
+ char_u *saved_IObuff;
+
+ if (excp == NULL) {
+ EMSG(_(e_internal));
+ return;
+ }
+
+ if (p_verbose >= 13 || debug_break_level > 0) {
+ int save_msg_silent = msg_silent;
+
+ saved_IObuff = vim_strsave(IObuff);
+ if (debug_break_level > 0)
+ msg_silent = FALSE; /* display messages */
+ else
+ verbose_enter();
+ ++no_wait_return;
+ if (debug_break_level > 0 || *p_vfile == NUL)
+ msg_scroll = TRUE; /* always scroll up, don't overwrite */
+ smsg(was_finished
+ ? (char_u *)_("Exception finished: %s")
+ : (char_u *)_("Exception discarded: %s"),
+ excp->value);
+ msg_puts((char_u *)"\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)
+ msg_silent = save_msg_silent;
+ else
+ verbose_leave();
+ STRCPY(IObuff, saved_IObuff);
+ vim_free(saved_IObuff);
+ }
+ if (excp->type != ET_INTERRUPT)
+ vim_free(excp->value);
+ if (excp->type == ET_ERROR)
+ free_msglist(excp->messages);
+ vim_free(excp->throw_name);
+ vim_free(excp);
+}
+
+/*
+ * Discard the exception currently being thrown.
+ */
+void discard_current_exception() {
+ discard_exception(current_exception, FALSE);
+ current_exception = NULL;
+ did_throw = FALSE;
+ need_rethrow = FALSE;
+}
+
+/*
+ * Put an exception on the caught stack.
+ */
+static void catch_exception(excp)
+except_T *excp;
+{
+ excp->caught = caught_stack;
+ caught_stack = excp;
+ set_vim_var_string(VV_EXCEPTION, excp->value, -1);
+ if (*excp->throw_name != NUL) {
+ if (excp->throw_lnum != 0)
+ vim_snprintf((char *)IObuff, IOSIZE, _("%s, line %ld"),
+ excp->throw_name, (long)excp->throw_lnum);
+ else
+ vim_snprintf((char *)IObuff, IOSIZE, "%s", excp->throw_name);
+ set_vim_var_string(VV_THROWPOINT, IObuff, -1);
+ } else
+ /* throw_name not set on an exception from a command that was typed. */
+ set_vim_var_string(VV_THROWPOINT, NULL, -1);
+
+ if (p_verbose >= 13 || debug_break_level > 0) {
+ int save_msg_silent = msg_silent;
+
+ if (debug_break_level > 0)
+ msg_silent = FALSE; /* display messages */
+ else
+ verbose_enter();
+ ++no_wait_return;
+ if (debug_break_level > 0 || *p_vfile == NUL)
+ msg_scroll = TRUE; /* always scroll up, don't overwrite */
+
+ smsg((char_u *)_("Exception caught: %s"), excp->value);
+ msg_puts((char_u *)"\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)
+ msg_silent = save_msg_silent;
+ else
+ verbose_leave();
+ }
+}
+
+/*
+ * Remove an exception from the caught stack.
+ */
+static void finish_exception(excp)
+except_T *excp;
+{
+ if (excp != caught_stack)
+ EMSG(_(e_internal));
+ caught_stack = caught_stack->caught;
+ if (caught_stack != NULL) {
+ set_vim_var_string(VV_EXCEPTION, caught_stack->value, -1);
+ if (*caught_stack->throw_name != NUL) {
+ if (caught_stack->throw_lnum != 0)
+ vim_snprintf((char *)IObuff, IOSIZE,
+ _("%s, line %ld"), caught_stack->throw_name,
+ (long)caught_stack->throw_lnum);
+ else
+ vim_snprintf((char *)IObuff, IOSIZE, "%s",
+ caught_stack->throw_name);
+ set_vim_var_string(VV_THROWPOINT, IObuff, -1);
+ } else
+ /* throw_name not set on an exception from a command that was
+ * typed. */
+ set_vim_var_string(VV_THROWPOINT, NULL, -1);
+ } else {
+ set_vim_var_string(VV_EXCEPTION, NULL, -1);
+ set_vim_var_string(VV_THROWPOINT, NULL, -1);
+ }
+
+ /* Discard the exception, but use the finish message for 'verbose'. */
+ discard_exception(excp, TRUE);
+}
+
+/*
+ * Flags specifying the message displayed by report_pending.
+ */
+#define RP_MAKE 0
+#define RP_RESUME 1
+#define RP_DISCARD 2
+
+/*
+ * Report information about something pending in a finally clause if required by
+ * the 'verbose' option or when debugging. "action" tells whether something is
+ * made pending or something pending is resumed or discarded. "pending" tells
+ * what is pending. "value" specifies the return value for a pending ":return"
+ * or the exception value for a pending exception.
+ */
+static void report_pending(action, pending, value)
+int action;
+int pending;
+void *value;
+{
+ char_u *mesg;
+ char *s;
+ int save_msg_silent;
+
+
+ switch (action) {
+ case RP_MAKE:
+ mesg = (char_u *)_("%s made pending");
+ break;
+ case RP_RESUME:
+ mesg = (char_u *)_("%s resumed");
+ break;
+ /* case RP_DISCARD: */
+ default:
+ mesg = (char_u *)_("%s discarded");
+ break;
+ }
+
+ switch (pending) {
+ case CSTP_NONE:
+ return;
+
+ case CSTP_CONTINUE:
+ s = ":continue";
+ break;
+ case CSTP_BREAK:
+ s = ":break";
+ break;
+ case CSTP_FINISH:
+ s = ":finish";
+ break;
+ case CSTP_RETURN:
+ /* ":return" command producing value, allocated */
+ s = (char *)get_return_cmd(value);
+ break;
+
+ default:
+ if (pending & CSTP_THROW) {
+ vim_snprintf((char *)IObuff, IOSIZE,
+ (char *)mesg, _("Exception"));
+ mesg = vim_strnsave(IObuff, (int)STRLEN(IObuff) + 4);
+ STRCAT(mesg, ": %s");
+ s = (char *)((except_T *)value)->value;
+ } else if ((pending & CSTP_ERROR) && (pending & CSTP_INTERRUPT))
+ s = _("Error and interrupt");
+ else if (pending & CSTP_ERROR)
+ s = _("Error");
+ else /* if (pending & CSTP_INTERRUPT) */
+ s = _("Interrupt");
+ }
+
+ save_msg_silent = msg_silent;
+ if (debug_break_level > 0)
+ msg_silent = FALSE; /* display messages */
+ ++no_wait_return;
+ msg_scroll = TRUE; /* always scroll up, don't overwrite */
+ smsg(mesg, (char_u *)s);
+ msg_puts((char_u *)"\n"); /* don't overwrite this either */
+ cmdline_row = msg_row;
+ --no_wait_return;
+ if (debug_break_level > 0)
+ msg_silent = save_msg_silent;
+
+ if (pending == CSTP_RETURN)
+ vim_free(s);
+ else if (pending & CSTP_THROW)
+ vim_free(mesg);
+}
+
+/*
+ * If something is made pending in a finally clause, report it if required by
+ * the 'verbose' option or when debugging.
+ */
+void report_make_pending(pending, value)
+int pending;
+void *value;
+{
+ if (p_verbose >= 14 || debug_break_level > 0) {
+ if (debug_break_level <= 0)
+ verbose_enter();
+ report_pending(RP_MAKE, pending, value);
+ if (debug_break_level <= 0)
+ verbose_leave();
+ }
+}
+
+/*
+ * If something pending in a finally clause is resumed at the ":endtry", report
+ * it if required by the 'verbose' option or when debugging.
+ */
+void report_resume_pending(pending, value)
+int pending;
+void *value;
+{
+ if (p_verbose >= 14 || debug_break_level > 0) {
+ if (debug_break_level <= 0)
+ verbose_enter();
+ report_pending(RP_RESUME, pending, value);
+ if (debug_break_level <= 0)
+ verbose_leave();
+ }
+}
+
+/*
+ * If something pending in a finally clause is discarded, report it if required
+ * by the 'verbose' option or when debugging.
+ */
+void report_discard_pending(pending, value)
+int pending;
+void *value;
+{
+ if (p_verbose >= 14 || debug_break_level > 0) {
+ if (debug_break_level <= 0)
+ verbose_enter();
+ report_pending(RP_DISCARD, pending, value);
+ if (debug_break_level <= 0)
+ verbose_leave();
+ }
+}
+
+
+/*
+ * ":if".
+ */
+void ex_if(eap)
+exarg_T *eap;
+{
+ int error;
+ int skip;
+ int result;
+ struct condstack *cstack = eap->cstack;
+
+ if (cstack->cs_idx == CSTACK_LEN - 1)
+ eap->errmsg = (char_u *)N_("E579: :if nesting too deep");
+ else {
+ ++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));
+
+ result = eval_to_bool(eap->arg, &error, &eap->nextcmd, skip);
+
+ if (!skip && !error) {
+ if (result)
+ cstack->cs_flags[cstack->cs_idx] = CSF_ACTIVE | CSF_TRUE;
+ } else
+ /* set TRUE, so this conditional will never get active */
+ cstack->cs_flags[cstack->cs_idx] = CSF_TRUE;
+ }
+}
+
+/*
+ * ":endif".
+ */
+void ex_endif(eap)
+exarg_T *eap;
+{
+ did_endif = TRUE;
+ if (eap->cstack->cs_idx < 0
+ || (eap->cstack->cs_flags[eap->cstack->cs_idx]
+ & (CSF_WHILE | CSF_FOR | CSF_TRY)))
+ eap->errmsg = (char_u *)N_("E580: :endif without :if");
+ else {
+ /*
+ * When debugging or a breakpoint was encountered, display the debug
+ * prompt (if not already done). This shows the user that an ":endif"
+ * is executed when the ":if" or a previous ":elseif" was not TRUE.
+ * Handle a ">quit" debug command as if an interrupt had occurred before
+ * the ":endif". That is, throw an interrupt exception if appropriate.
+ * Doing this here prevents an exception for a parsing error being
+ * discarded by throwing the interrupt exception later on.
+ */
+ if (!(eap->cstack->cs_flags[eap->cstack->cs_idx] & CSF_TRUE)
+ && dbg_check_skipped(eap))
+ (void)do_intthrow(eap->cstack);
+
+ --eap->cstack->cs_idx;
+ }
+}
+
+/*
+ * ":else" and ":elseif".
+ */
+void ex_else(eap)
+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));
+
+ if (cstack->cs_idx < 0
+ || (cstack->cs_flags[cstack->cs_idx]
+ & (CSF_WHILE | CSF_FOR | CSF_TRY))) {
+ if (eap->cmdidx == CMD_else) {
+ eap->errmsg = (char_u *)N_("E581: :else without :if");
+ return;
+ }
+ eap->errmsg = (char_u *)N_("E582: :elseif without :if");
+ skip = TRUE;
+ } else if (cstack->cs_flags[cstack->cs_idx] & CSF_ELSE) {
+ if (eap->cmdidx == CMD_else) {
+ eap->errmsg = (char_u *)N_("E583: multiple :else");
+ return;
+ }
+ eap->errmsg = (char_u *)N_("E584: :elseif after :else");
+ skip = TRUE;
+ }
+
+ /* if skipping or the ":if" was TRUE, reset ACTIVE, otherwise set it */
+ if (skip || cstack->cs_flags[cstack->cs_idx] & CSF_TRUE) {
+ if (eap->errmsg == NULL)
+ cstack->cs_flags[cstack->cs_idx] = CSF_TRUE;
+ skip = TRUE; /* don't evaluate an ":elseif" */
+ } else
+ cstack->cs_flags[cstack->cs_idx] = CSF_ACTIVE;
+
+ /*
+ * When debugging or a breakpoint was encountered, display the debug prompt
+ * (if not already done). This shows the user that an ":else" or ":elseif"
+ * is executed when the ":if" or previous ":elseif" was not TRUE. Handle
+ * a ">quit" debug command as if an interrupt had occurred before the
+ * ":else" or ":elseif". That is, set "skip" and throw an interrupt
+ * exception if appropriate. Doing this here prevents that an exception
+ * for a parsing errors is discarded when throwing the interrupt exception
+ * later on.
+ */
+ if (!skip && dbg_check_skipped(eap) && got_int) {
+ (void)do_intthrow(cstack);
+ skip = TRUE;
+ }
+
+ if (eap->cmdidx == CMD_elseif) {
+ 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
+ * a conditional error was detected above and there is another failure
+ * when parsing the expression. Since the skip flag is set in this
+ * case, the parsing error will be ignored by emsg(). */
+
+ if (!skip && !error) {
+ if (result)
+ cstack->cs_flags[cstack->cs_idx] = CSF_ACTIVE | CSF_TRUE;
+ else
+ cstack->cs_flags[cstack->cs_idx] = 0;
+ } else if (eap->errmsg == NULL)
+ /* set TRUE, so this conditional will never get active */
+ cstack->cs_flags[cstack->cs_idx] = CSF_TRUE;
+ } else
+ cstack->cs_flags[cstack->cs_idx] |= CSF_ELSE;
+}
+
+/*
+ * Handle ":while" and ":for".
+ */
+void ex_while(eap)
+exarg_T *eap;
+{
+ int error;
+ int skip;
+ int result;
+ struct condstack *cstack = eap->cstack;
+
+ if (cstack->cs_idx == CSTACK_LEN - 1)
+ eap->errmsg = (char_u *)N_("E585: :while/:for nesting too deep");
+ else {
+ /*
+ * The loop flag is set when we have jumped back from the matching
+ * ":endwhile" or ":endfor". When not set, need to initialise this
+ * cstack entry.
+ */
+ if ((cstack->cs_lflags & CSL_HAD_LOOP) == 0) {
+ ++cstack->cs_idx;
+ ++cstack->cs_looplevel;
+ cstack->cs_line[cstack->cs_idx] = -1;
+ }
+ 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));
+ if (eap->cmdidx == CMD_while) {
+ /*
+ * ":while bool-expr"
+ */
+ result = eval_to_bool(eap->arg, &error, &eap->nextcmd, skip);
+ } else {
+ void *fi;
+
+ /*
+ * ":for var in list-expr"
+ */
+ if ((cstack->cs_lflags & CSL_HAD_LOOP) != 0) {
+ /* Jumping here from a ":continue" or ":endfor": use the
+ * previously evaluated list. */
+ fi = cstack->cs_forinfo[cstack->cs_idx];
+ error = FALSE;
+ } else {
+ /* Evaluate the argument and get the info in a structure. */
+ fi = eval_for_line(eap->arg, &error, &eap->nextcmd, skip);
+ cstack->cs_forinfo[cstack->cs_idx] = fi;
+ }
+
+ /* use the element at the start of the list and advance */
+ if (!error && fi != NULL && !skip)
+ result = next_for_item(fi, eap->arg);
+ else
+ result = FALSE;
+
+ if (!result) {
+ free_for_info(fi);
+ cstack->cs_forinfo[cstack->cs_idx] = NULL;
+ }
+ }
+
+ /*
+ * If this cstack entry was just initialised and is active, set the
+ * loop flag, so do_cmdline() will set the line number in cs_line[].
+ * If executing the command a second time, clear the loop flag.
+ */
+ if (!skip && !error && result) {
+ cstack->cs_flags[cstack->cs_idx] |= (CSF_ACTIVE | CSF_TRUE);
+ cstack->cs_lflags ^= CSL_HAD_LOOP;
+ } else {
+ cstack->cs_lflags &= ~CSL_HAD_LOOP;
+ /* If the ":while" evaluates to FALSE or ":for" is past the end of
+ * the list, show the debug prompt at the ":endwhile"/":endfor" as
+ * if there was a ":break" in a ":while"/":for" evaluating to
+ * TRUE. */
+ if (!skip && !error)
+ cstack->cs_flags[cstack->cs_idx] |= CSF_TRUE;
+ }
+ }
+}
+
+/*
+ * ":continue"
+ */
+void ex_continue(eap)
+exarg_T *eap;
+{
+ int idx;
+ struct condstack *cstack = eap->cstack;
+
+ if (cstack->cs_looplevel <= 0 || cstack->cs_idx < 0)
+ eap->errmsg = (char_u *)N_("E586: :continue without :while or :for");
+ else {
+ /* Try to find the matching ":while". This might stop at a try
+ * conditional not in its finally clause (which is then to be executed
+ * next). Therefor, inactivate all conditionals except the ":while"
+ * itself (if reached). */
+ idx = cleanup_conditionals(cstack, CSF_WHILE | CSF_FOR, FALSE);
+ if (idx >= 0 && (cstack->cs_flags[idx] & (CSF_WHILE | CSF_FOR))) {
+ rewind_conditionals(cstack, idx, CSF_TRY, &cstack->cs_trylevel);
+
+ /*
+ * Set CSL_HAD_CONT, so do_cmdline() will jump back to the
+ * matching ":while".
+ */
+ cstack->cs_lflags |= CSL_HAD_CONT; /* let do_cmdline() handle it */
+ } else {
+ /* If a try conditional not in its finally clause is reached first,
+ * make the ":continue" pending for execution at the ":endtry". */
+ cstack->cs_pending[idx] = CSTP_CONTINUE;
+ report_make_pending(CSTP_CONTINUE, NULL);
+ }
+ }
+}
+
+/*
+ * ":break"
+ */
+void ex_break(eap)
+exarg_T *eap;
+{
+ int idx;
+ struct condstack *cstack = eap->cstack;
+
+ if (cstack->cs_looplevel <= 0 || cstack->cs_idx < 0)
+ eap->errmsg = (char_u *)N_("E587: :break without :while or :for");
+ else {
+ /* Inactivate conditionals until the matching ":while" or a try
+ * conditional not in its finally clause (which is then to be
+ * executed next) is found. In the latter case, make the ":break"
+ * pending for execution at the ":endtry". */
+ idx = cleanup_conditionals(cstack, CSF_WHILE | CSF_FOR, TRUE);
+ if (idx >= 0 && !(cstack->cs_flags[idx] & (CSF_WHILE | CSF_FOR))) {
+ cstack->cs_pending[idx] = CSTP_BREAK;
+ report_make_pending(CSTP_BREAK, NULL);
+ }
+ }
+}
+
+/*
+ * ":endwhile" and ":endfor"
+ */
+void ex_endwhile(eap)
+exarg_T *eap;
+{
+ struct condstack *cstack = eap->cstack;
+ int idx;
+ char_u *err;
+ int csf;
+ int fl;
+
+ if (eap->cmdidx == CMD_endwhile) {
+ err = e_while;
+ csf = CSF_WHILE;
+ } else {
+ err = e_for;
+ csf = CSF_FOR;
+ }
+
+ if (cstack->cs_looplevel <= 0 || cstack->cs_idx < 0)
+ eap->errmsg = err;
+ else {
+ fl = cstack->cs_flags[cstack->cs_idx];
+ if (!(fl & csf)) {
+ /* If we are in a ":while" or ":for" but used the wrong endloop
+ * command, do not rewind to the next enclosing ":for"/":while". */
+ if (fl & CSF_WHILE)
+ eap->errmsg = (char_u *)_("E732: Using :endfor with :while");
+ else if (fl & CSF_FOR)
+ eap->errmsg = (char_u *)_("E733: Using :endwhile with :for");
+ }
+ if (!(fl & (CSF_WHILE | CSF_FOR))) {
+ if (!(fl & CSF_TRY))
+ eap->errmsg = e_endif;
+ else if (fl & CSF_FINALLY)
+ eap->errmsg = e_endtry;
+ /* Try to find the matching ":while" and report what's missing. */
+ for (idx = cstack->cs_idx; idx > 0; --idx) {
+ fl = cstack->cs_flags[idx];
+ if ((fl & CSF_TRY) && !(fl & CSF_FINALLY)) {
+ /* Give up at a try conditional not in its finally clause.
+ * Ignore the ":endwhile"/":endfor". */
+ eap->errmsg = err;
+ return;
+ }
+ if (fl & csf)
+ break;
+ }
+ /* Cleanup and rewind all contained (and unclosed) conditionals. */
+ (void)cleanup_conditionals(cstack, CSF_WHILE | CSF_FOR, FALSE);
+ rewind_conditionals(cstack, idx, CSF_TRY, &cstack->cs_trylevel);
+ }
+ /*
+ * When debugging or a breakpoint was encountered, display the debug
+ * prompt (if not already done). This shows the user that an
+ * ":endwhile"/":endfor" is executed when the ":while" was not TRUE or
+ * after a ":break". Handle a ">quit" debug command as if an
+ * interrupt had occurred before the ":endwhile"/":endfor". That is,
+ * throw an interrupt exception if appropriate. Doing this here
+ * prevents that an exception for a parsing error is discarded when
+ * throwing the interrupt exception later on.
+ */
+ else if (cstack->cs_flags[cstack->cs_idx] & CSF_TRUE
+ && !(cstack->cs_flags[cstack->cs_idx] & CSF_ACTIVE)
+ && dbg_check_skipped(eap))
+ (void)do_intthrow(cstack);
+
+ /*
+ * Set loop flag, so do_cmdline() will jump back to the matching
+ * ":while" or ":for".
+ */
+ cstack->cs_lflags |= CSL_HAD_ENDLOOP;
+ }
+}
+
+
+/*
+ * ":throw expr"
+ */
+void ex_throw(eap)
+exarg_T *eap;
+{
+ char_u *arg = eap->arg;
+ char_u *value;
+
+ if (*arg != NUL && *arg != '|' && *arg != '\n')
+ value = eval_to_string_skip(arg, &eap->nextcmd, eap->skip);
+ else {
+ EMSG(_(e_argreq));
+ value = NULL;
+ }
+
+ /* 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)
+ vim_free(value);
+ else
+ do_throw(eap->cstack);
+ }
+}
+
+/*
+ * Throw the current exception through the specified cstack. Common routine
+ * for ":throw" (user exception) and error and interrupt exceptions. Also
+ * used for rethrowing an uncaught exception.
+ */
+void do_throw(cstack)
+struct condstack *cstack;
+{
+ int idx;
+ int inactivate_try = FALSE;
+
+ /*
+ * Cleanup and inactivate up to the next surrounding try conditional that
+ * is not in its finally clause. Normally, do not inactivate the try
+ * conditional itself, so that its ACTIVE flag can be tested below. But
+ * if a previous error or interrupt has not been converted to an exception,
+ * inactivate the try conditional, too, as if the conversion had been done,
+ * and reset the did_emsg or got_int flag, so this won't happen again at
+ * the next surrounding try conditional.
+ */
+#ifndef THROW_ON_ERROR_TRUE
+ if (did_emsg && !THROW_ON_ERROR) {
+ inactivate_try = TRUE;
+ did_emsg = FALSE;
+ }
+#endif
+#ifndef THROW_ON_INTERRUPT_TRUE
+ if (got_int && !THROW_ON_INTERRUPT) {
+ inactivate_try = TRUE;
+ got_int = FALSE;
+ }
+#endif
+ idx = cleanup_conditionals(cstack, 0, inactivate_try);
+ if (idx >= 0) {
+ /*
+ * If this try conditional is active and we are before its first
+ * ":catch", set THROWN so that the ":catch" commands will check
+ * whether the exception matches. When the exception came from any of
+ * the catch clauses, it will be made pending at the ":finally" (if
+ * present) and rethrown at the ":endtry". This will also happen if
+ * the try conditional is inactive. This is the case when we are
+ * throwing an exception due to an error or interrupt on the way from
+ * a preceding ":continue", ":break", ":return", ":finish", error or
+ * interrupt (not converted to an exception) to the finally clause or
+ * from a preceding throw of a user or error or interrupt exception to
+ * the matching catch clause or the finally clause.
+ */
+ if (!(cstack->cs_flags[idx] & CSF_CAUGHT)) {
+ if (cstack->cs_flags[idx] & CSF_ACTIVE)
+ cstack->cs_flags[idx] |= CSF_THROWN;
+ else
+ /* THROWN may have already been set for a catchable exception
+ * that has been discarded. Ensure it is reset for the new
+ * exception. */
+ cstack->cs_flags[idx] &= ~CSF_THROWN;
+ }
+ cstack->cs_flags[idx] &= ~CSF_ACTIVE;
+ cstack->cs_exception[idx] = current_exception;
+ }
+
+ did_throw = TRUE;
+}
+
+/*
+ * ":try"
+ */
+void ex_try(eap)
+exarg_T *eap;
+{
+ int skip;
+ struct condstack *cstack = eap->cstack;
+
+ if (cstack->cs_idx == CSTACK_LEN - 1)
+ eap->errmsg = (char_u *)N_("E601: :try nesting too deep");
+ else {
+ ++cstack->cs_idx;
+ ++cstack->cs_trylevel;
+ 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));
+
+ if (!skip) {
+ /* Set ACTIVE and TRUE. TRUE means that the corresponding ":catch"
+ * commands should check for a match if an exception is thrown and
+ * that the finally clause needs to be executed. */
+ cstack->cs_flags[cstack->cs_idx] |= CSF_ACTIVE | CSF_TRUE;
+
+ /*
+ * ":silent!", even when used in a try conditional, disables
+ * displaying of error messages and conversion of errors to
+ * exceptions. When the silent commands again open a try
+ * conditional, save "emsg_silent" and reset it so that errors are
+ * again converted to exceptions. The value is restored when that
+ * try conditional is left. If it is left normally, the commands
+ * following the ":endtry" are again silent. If it is left by
+ * a ":continue", ":break", ":return", or ":finish", the commands
+ * executed next are again silent. If it is left due to an
+ * aborting error, an interrupt, or an exception, restoring
+ * "emsg_silent" does not matter since we are already in the
+ * aborting state and/or the exception has already been thrown.
+ * The effect is then just freeing the memory that was allocated
+ * to save the value.
+ */
+ if (emsg_silent) {
+ eslist_T *elem;
+
+ elem = (eslist_T *)alloc((unsigned)sizeof(struct eslist_elem));
+ if (elem == NULL)
+ EMSG(_(e_outofmem));
+ else {
+ elem->saved_emsg_silent = emsg_silent;
+ elem->next = cstack->cs_emsg_silent_list;
+ cstack->cs_emsg_silent_list = elem;
+ cstack->cs_flags[cstack->cs_idx] |= CSF_SILENT;
+ emsg_silent = 0;
+ }
+ }
+ }
+
+ }
+}
+
+/*
+ * ":catch /{pattern}/" and ":catch"
+ */
+void ex_catch(eap)
+exarg_T *eap;
+{
+ int idx = 0;
+ int give_up = FALSE;
+ int skip = FALSE;
+ int caught = FALSE;
+ char_u *end;
+ int save_char = 0;
+ char_u *save_cpo;
+ regmatch_T regmatch;
+ int prev_got_int;
+ struct condstack *cstack = eap->cstack;
+ char_u *pat;
+
+ if (cstack->cs_trylevel <= 0 || cstack->cs_idx < 0) {
+ eap->errmsg = (char_u *)N_("E603: :catch without :try");
+ give_up = TRUE;
+ } else {
+ if (!(cstack->cs_flags[cstack->cs_idx] & CSF_TRY)) {
+ /* Report what's missing if the matching ":try" is not in its
+ * finally clause. */
+ eap->errmsg = get_end_emsg(cstack);
+ skip = TRUE;
+ }
+ for (idx = cstack->cs_idx; idx > 0; --idx)
+ if (cstack->cs_flags[idx] & CSF_TRY)
+ break;
+ if (cstack->cs_flags[idx] & CSF_FINALLY) {
+ /* Give up for a ":catch" after ":finally" and ignore it.
+ * Just parse. */
+ eap->errmsg = (char_u *)N_("E604: :catch after :finally");
+ give_up = TRUE;
+ } else
+ rewind_conditionals(cstack, idx, CSF_WHILE | CSF_FOR,
+ &cstack->cs_looplevel);
+ }
+
+ if (ends_excmd(*eap->arg)) { /* no argument, catch all errors */
+ pat = (char_u *)".*";
+ end = NULL;
+ eap->nextcmd = find_nextcmd(eap->arg);
+ } else {
+ pat = eap->arg + 1;
+ end = skip_regexp(pat, *eap->arg, TRUE, NULL);
+ }
+
+ if (!give_up) {
+ /*
+ * Don't do something when no exception has been thrown or when the
+ * 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;
+
+ /*
+ * Check for a match only if an exception is thrown but not caught by
+ * a previous ":catch". An exception that has replaced a discarded
+ * exception is not checked (THROWN is not set then).
+ */
+ if (!skip && (cstack->cs_flags[idx] & CSF_THROWN)
+ && !(cstack->cs_flags[idx] & CSF_CAUGHT)) {
+ if (end != NULL && *end != NUL && !ends_excmd(*skipwhite(end + 1))) {
+ EMSG(_(e_trailing));
+ return;
+ }
+
+ /* When debugging or a breakpoint was encountered, display the
+ * debug prompt (if not already done) before checking for a match.
+ * This is a helpful hint for the user when the regular expression
+ * matching fails. Handle a ">quit" debug command as if an
+ * interrupt had occurred before the ":catch". That is, discard
+ * the original exception, replace it by an interrupt exception,
+ * and don't catch it in this try block. */
+ if (!dbg_check_skipped(eap) || !do_intthrow(cstack)) {
+ /* Terminate the pattern and avoid the 'l' flag in 'cpoptions'
+ * while compiling it. */
+ if (end != NULL) {
+ save_char = *end;
+ *end = NUL;
+ }
+ save_cpo = p_cpo;
+ p_cpo = (char_u *)"";
+ regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING);
+ regmatch.rm_ic = FALSE;
+ if (end != NULL)
+ *end = save_char;
+ p_cpo = save_cpo;
+ if (regmatch.regprog == NULL)
+ EMSG2(_(e_invarg2), pat);
+ else {
+ /*
+ * Save the value of got_int and reset it. We don't want
+ * a previous interruption cancel matching, only hitting
+ * CTRL-C while matching should abort it.
+ */
+ prev_got_int = got_int;
+ got_int = FALSE;
+ caught = vim_regexec_nl(&regmatch, current_exception->value,
+ (colnr_T)0);
+ got_int |= prev_got_int;
+ vim_regfree(regmatch.regprog);
+ }
+ }
+ }
+
+ if (caught) {
+ /* Make this ":catch" clause active and reset did_emsg, got_int,
+ * and did_throw. Put the exception on the caught stack. */
+ cstack->cs_flags[idx] |= CSF_ACTIVE | CSF_CAUGHT;
+ did_emsg = got_int = did_throw = 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));
+ } else {
+ /*
+ * If there is a preceding catch clause and it caught the exception,
+ * finish the exception now. This happens also after errors except
+ * when this ":catch" was after the ":finally" or not within
+ * a ":try". Make the try conditional inactive so that the
+ * following catch clauses are skipped. On an error or interrupt
+ * after the preceding try block or catch clause was left by
+ * a ":continue", ":break", ":return", or ":finish", discard the
+ * pending action.
+ */
+ cleanup_conditionals(cstack, CSF_TRY, TRUE);
+ }
+ }
+
+ if (end != NULL)
+ eap->nextcmd = find_nextcmd(end);
+}
+
+/*
+ * ":finally"
+ */
+void ex_finally(eap)
+exarg_T *eap;
+{
+ int idx;
+ int skip = FALSE;
+ int pending = CSTP_NONE;
+ struct condstack *cstack = eap->cstack;
+
+ if (cstack->cs_trylevel <= 0 || cstack->cs_idx < 0)
+ eap->errmsg = (char_u *)N_("E606: :finally without :try");
+ else {
+ if (!(cstack->cs_flags[cstack->cs_idx] & CSF_TRY)) {
+ eap->errmsg = get_end_emsg(cstack);
+ for (idx = cstack->cs_idx - 1; idx > 0; --idx)
+ if (cstack->cs_flags[idx] & CSF_TRY)
+ break;
+ /* Make this error pending, so that the commands in the following
+ * finally clause can be executed. This overrules also a pending
+ * ":continue", ":break", ":return", or ":finish". */
+ pending = CSTP_ERROR;
+ } else
+ idx = cstack->cs_idx;
+
+ if (cstack->cs_flags[idx] & CSF_FINALLY) {
+ /* Give up for a multiple ":finally" and ignore it. */
+ eap->errmsg = (char_u *)N_("E607: multiple :finally");
+ return;
+ }
+ rewind_conditionals(cstack, idx, CSF_WHILE | CSF_FOR,
+ &cstack->cs_looplevel);
+
+ /*
+ * Don't do something when the corresponding try block never got active
+ * (because of an inactive surrounding conditional or after an error or
+ * 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.
+ */
+ skip = !(cstack->cs_flags[cstack->cs_idx] & CSF_TRUE);
+
+ if (!skip) {
+ /* When debugging or a breakpoint was encountered, display the
+ * debug prompt (if not already done). The user then knows that the
+ * finally clause is executed. */
+ if (dbg_check_skipped(eap)) {
+ /* Handle a ">quit" debug command as if an interrupt had
+ * occurred before the ":finally". That is, discard the
+ * original exception and replace it by an interrupt
+ * exception. */
+ (void)do_intthrow(cstack);
+ }
+
+ /*
+ * If there is a preceding catch clause and it caught the exception,
+ * finish the exception now. This happens also after errors except
+ * when this is a multiple ":finally" or one not within a ":try".
+ * After an error or interrupt, this also discards a pending
+ * ":continue", ":break", ":finish", or ":return" from the preceding
+ * try block or catch clause.
+ */
+ 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
+ * 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
+ * already been set, respectively in case that the error is not
+ * converted to an exception, did_throw 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 (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;
+ pending |= did_emsg ? CSTP_ERROR : 0;
+ pending |= got_int ? CSTP_INTERRUPT : 0;
+ cstack->cs_pending[cstack->cs_idx] = pending;
+
+ /* It's mandatory that the current exception is stored in the
+ * cstack so that it can be rethrown at the ":endtry" or be
+ * discarded if the finally clause is left by a ":continue",
+ * ":break", ":return", ":finish", error, interrupt, or another
+ * 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));
+ }
+
+ /*
+ * Set CSL_HAD_FINA, so do_cmdline() will reset did_emsg,
+ * got_int, and did_throw 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.
+ */
+ cstack->cs_lflags |= CSL_HAD_FINA;
+ }
+ }
+}
+
+/*
+ * ":endtry"
+ */
+void ex_endtry(eap)
+exarg_T *eap;
+{
+ int idx;
+ int skip;
+ int rethrow = FALSE;
+ int pending = CSTP_NONE;
+ void *rettv = NULL;
+ struct condstack *cstack = eap->cstack;
+
+ if (cstack->cs_trylevel <= 0 || cstack->cs_idx < 0)
+ eap->errmsg = (char_u *)N_("E602: :endtry without :try");
+ else {
+ /*
+ * Don't do something after an error, interrupt or throw in the try
+ * block, catch clause, or finally clause preceding this ":endtry" or
+ * when an error or interrupt occurred after a ":continue", ":break",
+ * ":return", or ":finish" in a try block or catch clause preceding this
+ * ":endtry" or when the try block never got active (because of an
+ * inactive surrounding conditional or after an error or interrupt or
+ * throw) or when there is a surrounding conditional and it has been
+ * 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 ||
+ !(cstack->cs_flags[cstack->cs_idx] & CSF_TRUE);
+
+ if (!(cstack->cs_flags[cstack->cs_idx] & CSF_TRY)) {
+ eap->errmsg = get_end_emsg(cstack);
+ /* Find the matching ":try" and report what's missing. */
+ idx = cstack->cs_idx;
+ do
+ --idx;
+ while (idx > 0 && !(cstack->cs_flags[idx] & CSF_TRY));
+ rewind_conditionals(cstack, idx, CSF_WHILE | CSF_FOR,
+ &cstack->cs_looplevel);
+ skip = TRUE;
+
+ /*
+ * 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.
+ * This does not affect the script termination due to the error
+ * since "trylevel" is decremented after emsg() has been called.
+ */
+ if (did_throw)
+ discard_current_exception();
+ } else {
+ idx = cstack->cs_idx;
+
+ /*
+ * If we stopped with the exception currently being thrown at this
+ * try conditional since we didn't know that it doesn't have
+ * 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 there was no finally clause, show the user when debugging or
+ * a breakpoint was encountered that the end of the try conditional has
+ * been reached: display the debug prompt (if not already done). Do
+ * this on normal control flow or when an exception was thrown, but not
+ * on an interrupt or error not converted to an exception or when
+ * a ":break", ":continue", ":return", or ":finish" is pending. These
+ * actions are carried out immediately.
+ */
+ if ((rethrow || (!skip
+ && !(cstack->cs_flags[idx] & CSF_FINALLY)
+ && !cstack->cs_pending[idx]))
+ && dbg_check_skipped(eap)) {
+ /* Handle a ">quit" debug command as if an interrupt had occurred
+ * before the ":endtry". That is, throw an interrupt exception and
+ * set "skip" and "rethrow". */
+ 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;
+ }
+ }
+
+ /*
+ * If a ":return" is pending, we need to resume it after closing the
+ * try conditional; remember the return value. If there was a finally
+ * clause making an exception pending, we need to rethrow it. Make it
+ * the exception currently being thrown.
+ */
+ if (!skip) {
+ pending = cstack->cs_pending[idx];
+ cstack->cs_pending[idx] = CSTP_NONE;
+ if (pending == CSTP_RETURN)
+ rettv = cstack->cs_rettv[idx];
+ else if (pending & CSTP_THROW)
+ current_exception = cstack->cs_exception[idx];
+ }
+
+ /*
+ * Discard anything pending on an error, interrupt, or throw in the
+ * finally clause. If there was no ":finally", discard a pending
+ * ":continue", ":break", ":return", or ":finish" if an error or
+ * interrupt occurred afterwards, but before the ":endtry" was reached.
+ * If an exception was caught by the last of the catch clauses and there
+ * was no finally clause, finish the exception now. This happens also
+ * after errors except when this ":endtry" is not within a ":try".
+ * Restore "emsg_silent" if it has been reset by this try conditional.
+ */
+ (void)cleanup_conditionals(cstack, CSF_TRY | CSF_SILENT, TRUE);
+
+ --cstack->cs_idx;
+ --cstack->cs_trylevel;
+
+ if (!skip) {
+ report_resume_pending(pending,
+ (pending == CSTP_RETURN) ? rettv :
+ (pending & CSTP_THROW) ? (void *)current_exception : NULL);
+ switch (pending) {
+ case CSTP_NONE:
+ break;
+
+ /* Reactivate a pending ":continue", ":break", ":return",
+ * ":finish" from the try block or a catch clause of this try
+ * conditional. This is skipped, if there was an error in an
+ * (unskipped) conditional command or an interrupt afterwards
+ * or if the finally clause is present and executed a new error,
+ * interrupt, throw, ":continue", ":break", ":return", or
+ * ":finish". */
+ case CSTP_CONTINUE:
+ ex_continue(eap);
+ break;
+ case CSTP_BREAK:
+ ex_break(eap);
+ break;
+ case CSTP_RETURN:
+ do_return(eap, FALSE, FALSE, rettv);
+ break;
+ case CSTP_FINISH:
+ 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. */
+ default:
+ 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). */
+ do_throw(cstack);
+ }
+}
+
+/*
+ * enter_cleanup() and leave_cleanup()
+ *
+ * Functions to be called before/after invoking a sequence of autocommands for
+ * cleanup for a failed command. (Failure means here that a call to emsg()
+ * has been made, an interrupt occurred, or there is an uncaught exception
+ * from a previous autocommand execution of the same command.)
+ *
+ * Call enter_cleanup() with a pointer to a cleanup_T and pass the same
+ * pointer to leave_cleanup(). The cleanup_T structure stores the pending
+ * error/interrupt/exception state.
+ */
+
+/*
+ * This function works a bit like ex_finally() except that there was not
+ * actually an extra try block around the part that failed and an error or
+ * interrupt has not (yet) been converted to an exception. This function
+ * saves the error/interrupt/ exception state and prepares for the call to
+ * do_cmdline() that is going to be made for the cleanup autocommand
+ * execution.
+ */
+void enter_cleanup(csp)
+cleanup_T *csp;
+{
+ int pending = CSTP_NONE;
+
+ /*
+ * Postpone did_emsg, got_int, did_throw. 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_throw || need_rethrow)
+ csp->exception = current_exception;
+ else {
+ csp->exception = NULL;
+ if (did_emsg) {
+ force_abort |= cause_abort;
+ cause_abort = FALSE;
+ }
+ }
+ did_emsg = got_int = did_throw = need_rethrow = FALSE;
+
+ /* Report if required by the 'verbose' option or when debugging. */
+ report_make_pending(pending, csp->exception);
+ } else {
+ csp->pending = CSTP_NONE;
+ csp->exception = NULL;
+ }
+}
+
+/*
+ * See comment above enter_cleanup() for how this function is used.
+ *
+ * This function is a bit like ex_endtry() except that there was not actually
+ * an extra try block around the part that failed and an error or interrupt
+ * had not (yet) been converted to an exception when the cleanup autocommand
+ * sequence was invoked.
+ *
+ * This function has to be called with the address of the cleanup_T structure
+ * filled by enter_cleanup() as an argument; it restores the error/interrupt/
+ * exception state saved by that function - except there was an aborting
+ * error, an interrupt or an uncaught exception during execution of the
+ * cleanup autocommands. In the latter case, the saved error/interrupt/
+ * exception state is discarded.
+ */
+void leave_cleanup(csp)
+cleanup_T *csp;
+{
+ int pending = csp->pending;
+
+ if (pending == CSTP_NONE) /* nothing to do */
+ return;
+
+ /* If there was an aborting error, an interrupt, or an uncaught exception
+ * after the corresponding call to enter_cleanup(), discard what has been
+ * made pending by it. Report this to the user if required by the
+ * 'verbose' option or when debugging. */
+ if (aborting() || need_rethrow) {
+ if (pending & CSTP_THROW)
+ /* Cancel the pending exception (includes report). */
+ discard_exception((except_T *)csp->exception, FALSE);
+ else
+ report_discard_pending(pending, NULL);
+
+ /* If an error was about to be converted to an exception when
+ * enter_cleanup() was called, free the message list. */
+ if (msg_list != NULL)
+ free_global_msglist();
+ }
+ /*
+ * If there was no new error, interrupt, or throw between the calls
+ * to enter_cleanup() and leave_cleanup(), restore the pending
+ * error/interrupt/exception state.
+ */
+ else {
+ /*
+ * If there was an exception being thrown when enter_cleanup() was
+ * called, we need to rethrow it. Make it the exception currently
+ * being thrown.
+ */
+ if (pending & CSTP_THROW)
+ current_exception = csp->exception;
+
+ /*
+ * If an error was about to be converted to an exception when
+ * enter_cleanup() was called, let "cause_abort" take the part of
+ * "force_abort" (as done by cause_errthrow()).
+ */
+ else if (pending & CSTP_ERROR) {
+ cause_abort = force_abort;
+ 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() */
+
+ /* Report if required by the 'verbose' option or when debugging. */
+ report_resume_pending(pending,
+ (pending & CSTP_THROW) ? (void *)current_exception : NULL);
+ }
+}
+
+
+/*
+ * Make conditionals inactive and discard what's pending in finally clauses
+ * until the conditional type searched for or a try conditional not in its
+ * finally clause is reached. If this is in an active catch clause, finish
+ * the caught exception.
+ * Return the cstack index where the search stopped.
+ * Values used for "searched_cond" are (CSF_WHILE | CSF_FOR) or CSF_TRY or 0,
+ * the latter meaning the innermost try conditional not in its finally clause.
+ * "inclusive" tells whether the conditional searched for should be made
+ * inactive itself (a try conditional not in its finally clause possibly find
+ * before is always made inactive). If "inclusive" is TRUE and
+ * "searched_cond" is CSF_TRY|CSF_SILENT, the saved former value of
+ * "emsg_silent", if reset when the try conditional finally reached was
+ * entered, is restored (used by ex_endtry()). This is normally done only
+ * when such a try conditional is left.
+ */
+int cleanup_conditionals(cstack, searched_cond, inclusive)
+struct condstack *cstack;
+int searched_cond;
+int inclusive;
+{
+ int idx;
+ int stop = FALSE;
+
+ for (idx = cstack->cs_idx; idx >= 0; --idx) {
+ if (cstack->cs_flags[idx] & CSF_TRY) {
+ /*
+ * Discard anything pending in a finally clause and continue the
+ * search. There may also be a pending ":continue", ":break",
+ * ":return", or ":finish" before the finally clause. We must not
+ * discard it, unless an error or interrupt occurred afterwards.
+ */
+ if (did_emsg || got_int || (cstack->cs_flags[idx] & CSF_FINALLY)) {
+ switch (cstack->cs_pending[idx]) {
+ case CSTP_NONE:
+ break;
+
+ case CSTP_CONTINUE:
+ case CSTP_BREAK:
+ case CSTP_FINISH:
+ report_discard_pending(cstack->cs_pending[idx], NULL);
+ cstack->cs_pending[idx] = CSTP_NONE;
+ break;
+
+ case CSTP_RETURN:
+ report_discard_pending(CSTP_RETURN,
+ cstack->cs_rettv[idx]);
+ discard_pending_return(cstack->cs_rettv[idx]);
+ cstack->cs_pending[idx] = CSTP_NONE;
+ break;
+
+ default:
+ if (cstack->cs_flags[idx] & CSF_FINALLY) {
+ if (cstack->cs_pending[idx] & CSTP_THROW) {
+ /* Cancel the pending exception. This is in the
+ * finally clause, so that the stack of the
+ * caught exceptions is not involved. */
+ discard_exception((except_T *)
+ cstack->cs_exception[idx],
+ FALSE);
+ } else
+ report_discard_pending(cstack->cs_pending[idx],
+ NULL);
+ cstack->cs_pending[idx] = CSTP_NONE;
+ }
+ break;
+ }
+ }
+
+ /*
+ * Stop at a try conditional not in its finally clause. If this try
+ * conditional is in an active catch clause, finish the caught
+ * exception.
+ */
+ if (!(cstack->cs_flags[idx] & CSF_FINALLY)) {
+ if ((cstack->cs_flags[idx] & CSF_ACTIVE)
+ && (cstack->cs_flags[idx] & CSF_CAUGHT))
+ finish_exception((except_T *)cstack->cs_exception[idx]);
+ /* Stop at this try conditional - except the try block never
+ * got active (because of an inactive surrounding conditional
+ * or when the ":try" appeared after an error or interrupt or
+ * throw). */
+ if (cstack->cs_flags[idx] & CSF_TRUE) {
+ if (searched_cond == 0 && !inclusive)
+ break;
+ stop = TRUE;
+ }
+ }
+ }
+
+ /* Stop on the searched conditional type (even when the surrounding
+ * conditional is not active or something has been made pending).
+ * If "inclusive" is TRUE and "searched_cond" is CSF_TRY|CSF_SILENT,
+ * check first whether "emsg_silent" needs to be restored. */
+ if (cstack->cs_flags[idx] & searched_cond) {
+ if (!inclusive)
+ break;
+ stop = TRUE;
+ }
+ cstack->cs_flags[idx] &= ~CSF_ACTIVE;
+ if (stop && searched_cond != (CSF_TRY | CSF_SILENT))
+ break;
+
+ /*
+ * When leaving a try conditional that reset "emsg_silent" on its
+ * entry after saving the original value, restore that value here and
+ * free the memory used to store it.
+ */
+ if ((cstack->cs_flags[idx] & CSF_TRY)
+ && (cstack->cs_flags[idx] & CSF_SILENT)) {
+ eslist_T *elem;
+
+ elem = cstack->cs_emsg_silent_list;
+ cstack->cs_emsg_silent_list = elem->next;
+ emsg_silent = elem->saved_emsg_silent;
+ vim_free(elem);
+ cstack->cs_flags[idx] &= ~CSF_SILENT;
+ }
+ if (stop)
+ break;
+ }
+ return idx;
+}
+
+/*
+ * Return an appropriate error message for a missing endwhile/endfor/endif.
+ */
+static char_u * get_end_emsg(cstack)
+struct condstack *cstack;
+{
+ if (cstack->cs_flags[cstack->cs_idx] & CSF_WHILE)
+ return e_endwhile;
+ if (cstack->cs_flags[cstack->cs_idx] & CSF_FOR)
+ return e_endfor;
+ return e_endif;
+}
+
+
+/*
+ * Rewind conditionals until index "idx" is reached. "cond_type" and
+ * "cond_level" specify a conditional type and the address of a level variable
+ * which is to be decremented with each skipped conditional of the specified
+ * type.
+ * Also free "for info" structures where needed.
+ */
+void rewind_conditionals(cstack, idx, cond_type, cond_level)
+struct condstack *cstack;
+int idx;
+int cond_type;
+int *cond_level;
+{
+ while (cstack->cs_idx > idx) {
+ if (cstack->cs_flags[cstack->cs_idx] & cond_type)
+ --*cond_level;
+ if (cstack->cs_flags[cstack->cs_idx] & CSF_FOR)
+ free_for_info(cstack->cs_forinfo[cstack->cs_idx]);
+ --cstack->cs_idx;
+ }
+}
+
+/*
+ * ":endfunction" when not after a ":function"
+ */
+void ex_endfunction(eap)
+exarg_T *eap UNUSED;
+{
+ EMSG(_("E193: :endfunction not inside a function"));
+}
+
+/*
+ * Return TRUE if the string "p" looks like a ":while" or ":for" command.
+ */
+int has_loop_cmd(p)
+char_u *p;
+{
+ int len;
+
+ /* skip modifiers, white space and ':' */
+ for (;; ) {
+ while (*p == ' ' || *p == '\t' || *p == ':')
+ ++p;
+ len = modifier_len(p);
+ if (len == 0)
+ break;
+ p += len;
+ }
+ if ((p[0] == 'w' && p[1] == 'h')
+ || (p[0] == 'f' && p[1] == 'o' && p[2] == 'r'))
+ return TRUE;
+ return FALSE;
+}
+
diff --git a/src/ex_getln.c b/src/ex_getln.c
new file mode 100644
index 0000000000..dbef0a9449
--- /dev/null
+++ b/src/ex_getln.c
@@ -0,0 +1,5486 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * 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.
+ */
+
+/*
+ * ex_getln.c: Functions for entering and editing an Ex command line.
+ */
+
+#include "vim.h"
+
+/*
+ * Variables shared between getcmdline(), redrawcmdline() and others.
+ * These need to be saved when using CTRL-R |, that's why they are in a
+ * 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 */
+};
+
+/* 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().
+ * TODO: make it local to getcmdline() and pass it around. */
+static struct cmdline_info ccline;
+
+static int cmd_showtail; /* Only show path tail in lists ? */
+
+static int new_cmdpos; /* position set by set_cmdline_pos() */
+
+typedef struct hist_entry {
+ int hisnum; /* identifying number */
+ int viminfo; /* when TRUE hisstr comes from viminfo */
+ char_u *hisstr; /* actual entry, separator char after the NUL */
+} histentry_T;
+
+static histentry_T *(history[HIST_COUNT]) = {NULL, NULL, NULL, NULL, NULL};
+static int hisidx[HIST_COUNT] = {-1, -1, -1, -1, -1}; /* lastused entry */
+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 */
+
+static int hist_char2type __ARGS((int c));
+
+static int in_history __ARGS((int, char_u *, int, int, int));
+static int calc_hist_idx __ARGS((int histype, int num));
+
+static int cmd_hkmap = 0; /* Hebrew mapping during command line */
+
+static int cmd_fkmap = 0; /* Farsi mapping during command line */
+
+static int cmdline_charsize __ARGS((int idx));
+static void set_cmdspos __ARGS((void));
+static void set_cmdspos_cursor __ARGS((void));
+static void correct_cmdspos __ARGS((int idx, int cells));
+static void alloc_cmdbuff __ARGS((int len));
+static int realloc_cmdbuff __ARGS((int len));
+static void draw_cmdline __ARGS((int start, int len));
+static void save_cmdline __ARGS((struct cmdline_info *ccp));
+static void restore_cmdline __ARGS((struct cmdline_info *ccp));
+static int cmdline_paste __ARGS((int regname, int literally, int remcr));
+static void cmdline_del __ARGS((int from));
+static void redrawcmdprompt __ARGS((void));
+static void cursorcmd __ARGS((void));
+static int ccheck_abbr __ARGS((int));
+static int nextwild __ARGS((expand_T *xp, int type, int options, int escape));
+static void escape_fname __ARGS((char_u **pp));
+static int showmatches __ARGS((expand_T *xp, int wildmenu));
+static void set_expand_context __ARGS((expand_T *xp));
+static int ExpandFromContext __ARGS((expand_T *xp, char_u *, int *, char_u ***,
+ int));
+static int expand_showtail __ARGS((expand_T *xp));
+static int expand_shellcmd __ARGS((char_u *filepat, int *num_file, char_u *
+ **file,
+ int flagsarg));
+static int ExpandRTDir __ARGS((char_u *pat, int *num_file, char_u ***file,
+ char *dirname[]));
+static char_u *get_history_arg __ARGS((expand_T *xp, int idx));
+static int ExpandUserDefined __ARGS((expand_T *xp, regmatch_T *regmatch,
+ int *num_file,
+ char_u ***file));
+static int ExpandUserList __ARGS((expand_T *xp, int *num_file, char_u ***file));
+static void clear_hist_entry __ARGS((histentry_T *hisptr));
+
+static int ex_window __ARGS((void));
+
+static int
+sort_func_compare __ARGS((const void *s1, const void *s2));
+
+/*
+ * getcmdline() - accept a command line starting with firstc.
+ *
+ * firstc == ':' get ":" command line.
+ * firstc == '/' or '?' get search pattern
+ * firstc == '=' get expression
+ * firstc == '@' get text for input() function
+ * firstc == '>' get text for debug mode
+ * firstc == NUL get text for :insert command
+ * firstc == -1 like NUL, and break on CTRL-C
+ *
+ * The line is collected in ccline.cmdbuff, which is reallocated to fit the
+ * command line.
+ *
+ * Careful: getcmdline() can be called recursively!
+ *
+ * Return pointer to allocated string if there is a commandline, NULL
+ * otherwise.
+ */
+char_u * getcmdline(firstc, count, indent)
+int firstc;
+long count UNUSED; /* only used for incremental search */
+int indent; /* indent for inside conditionals */
+{
+ int c;
+ int i;
+ int j;
+ int gotesc = FALSE; /* TRUE when <ESC> just typed */
+ int do_abbr; /* when TRUE check for abbr. */
+ char_u *lookfor = NULL; /* 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;
+ int did_incsearch = FALSE;
+ int incsearch_postponed = FALSE;
+ int did_wild_list = FALSE; /* did wild_list() recently */
+ int wim_index = 0; /* index in wim_flags[] */
+ int res;
+ int save_msg_scroll = msg_scroll;
+ int save_State = State; /* remember State when called */
+ int some_key_typed = FALSE; /* one of the keys was typed */
+ /* mouse drag and release events are ignored, unless they are
+ * preceded with a mouse down event */
+ int ignore_drag_release = TRUE;
+ int break_ctrl_c = FALSE;
+ expand_T xpc;
+ long *b_im_ptr = NULL;
+ /* 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;
+
+ if (firstc == -1) {
+ firstc = NUL;
+ break_ctrl_c = TRUE;
+ }
+ /* start without Hebrew mapping for a command line */
+ if (firstc == ':' || firstc == '=' || firstc == '>')
+ cmd_hkmap = 0;
+
+ ccline.overstrike = FALSE; /* always start in insert mode */
+ old_cursor = curwin->w_cursor; /* needs to be restored later */
+ old_curswant = curwin->w_curswant;
+ old_leftcol = curwin->w_leftcol;
+ old_topline = curwin->w_topline;
+ old_topfill = curwin->w_topfill;
+ old_botline = curwin->w_botline;
+
+ /*
+ * set some variables for redrawcmd()
+ */
+ ccline.cmdfirstc = (firstc == '@' ? 0 : firstc);
+ ccline.cmdindent = (firstc > 0 ? indent : 0);
+
+ /* alloc initial ccline.cmdbuff */
+ alloc_cmdbuff(exmode_active ? 250 : indent + 1);
+ if (ccline.cmdbuff == NULL)
+ return NULL; /* out of memory */
+ ccline.cmdlen = ccline.cmdpos = 0;
+ ccline.cmdbuff[0] = NUL;
+
+ /* autoindent for :insert and :append */
+ if (firstc <= 0) {
+ copy_spaces(ccline.cmdbuff, indent);
+ ccline.cmdbuff[indent] = NUL;
+ ccline.cmdpos = indent;
+ ccline.cmdspos = indent;
+ ccline.cmdlen = indent;
+ }
+
+ ExpandInit(&xpc);
+ ccline.xpc = &xpc;
+
+ if (curwin->w_p_rl && *curwin->w_p_rlc == 's'
+ && (firstc == '/' || firstc == '?'))
+ cmdmsg_rl = TRUE;
+ else
+ cmdmsg_rl = FALSE;
+
+ redir_off = TRUE; /* don't redirect the typed command */
+ if (!cmd_silent) {
+ i = msg_scrolled;
+ msg_scrolled = 0; /* avoid wait_return message */
+ gotocmdline(TRUE);
+ msg_scrolled += i;
+ redrawcmdprompt(); /* draw prompt or indent */
+ set_cmdspos();
+ }
+ xpc.xp_context = EXPAND_NOTHING;
+ xpc.xp_backslash = XP_BS_NONE;
+#ifndef BACKSLASH_IN_FILENAME
+ xpc.xp_shell = FALSE;
+#endif
+
+ if (ccline.input_fn) {
+ xpc.xp_context = ccline.xp_context;
+ xpc.xp_pattern = ccline.cmdbuff;
+ xpc.xp_arg = ccline.xp_arg;
+ }
+
+ /*
+ * Avoid scrolling when called by a recursive do_cmdline(), e.g. when
+ * doing ":@0" when register 0 doesn't contain a CR.
+ */
+ msg_scroll = FALSE;
+
+ State = CMDLINE;
+
+ if (firstc == '/' || firstc == '?' || firstc == '@') {
+ /* Use ":lmap" mappings for search pattern and input(). */
+ if (curbuf->b_p_imsearch == B_IMODE_USE_INSERT)
+ b_im_ptr = &curbuf->b_p_iminsert;
+ else
+ b_im_ptr = &curbuf->b_p_imsearch;
+ if (*b_im_ptr == B_IMODE_LMAP)
+ State |= LANGMAP;
+#ifdef USE_IM_CONTROL
+ im_set_active(*b_im_ptr == B_IMODE_IM);
+#endif
+ }
+#ifdef USE_IM_CONTROL
+ else if (p_imcmdline)
+ im_set_active(TRUE);
+#endif
+
+ setmouse();
+#ifdef CURSOR_SHAPE
+ ui_cursor_shape(); /* may show different cursor shape */
+#endif
+
+ /* When inside an autocommand for writing "exiting" may be set and
+ * terminal mode set to cooked. Need to set raw mode here then. */
+ settmode(TMODE_RAW);
+
+ init_history();
+ hiscnt = hislen; /* set hiscnt to impossible history value */
+ histype = hist_char2type(firstc);
+
+ do_digraph(-1); /* init digraph typeahead */
+
+ /*
+ * Collect the command string, handling editing keys.
+ */
+ for (;; ) {
+ redir_off = TRUE; /* Don't redirect the typed command.
+ Repeated, because a ":redir" inside
+ completion may switch it on. */
+#ifdef USE_ON_FLY_SCROLL
+ dont_scroll = FALSE; /* allow scrolling here */
+#endif
+ quit_more = FALSE; /* reset after CTRL-D which had a more-prompt */
+
+ cursorcmd(); /* set the cursor on the right spot */
+
+ /* Get a character. Ignore K_IGNORE, it should not do anything, such
+ * as stop completion. */
+ do {
+ c = safe_vgetc();
+ } while (c == K_IGNORE);
+
+ if (KeyTyped) {
+ some_key_typed = TRUE;
+ if (cmd_hkmap)
+ c = hkmap(c);
+ if (cmd_fkmap)
+ c = cmdl_fkmap(c);
+ if (cmdmsg_rl && !KeyStuffed) {
+ /* Invert horizontal movements and operations. Only when
+ * typed by the user directly, not when the result of a
+ * mapping. */
+ switch (c) {
+ case K_RIGHT: c = K_LEFT; break;
+ case K_S_RIGHT: c = K_S_LEFT; break;
+ case K_C_RIGHT: c = K_C_LEFT; break;
+ case K_LEFT: c = K_RIGHT; break;
+ case K_S_LEFT: c = K_S_RIGHT; break;
+ case K_C_LEFT: c = K_C_RIGHT; break;
+ }
+ }
+ }
+
+ /*
+ * Ignore got_int when CTRL-C was typed here.
+ * Don't ignore it in :global, we really need to break then, e.g., for
+ * ":g/pat/normal /pat" (without the <CR>).
+ * Don't ignore it for the input() function.
+ */
+ if ((c == Ctrl_C
+#ifdef UNIX
+ || c == intr_char
+#endif
+ )
+ && firstc != '@'
+ && !break_ctrl_c
+ && !global_busy)
+ got_int = FALSE;
+
+ /* free old command line when finished moving around in the history
+ * list */
+ if (lookfor != NULL
+ && c != K_S_DOWN && c != K_S_UP
+ && c != K_DOWN && c != K_UP
+ && c != K_PAGEDOWN && c != K_PAGEUP
+ && c != K_KPAGEDOWN && c != K_KPAGEUP
+ && c != K_LEFT && c != K_RIGHT
+ && (xpc.xp_numfiles > 0 || (c != Ctrl_P && c != Ctrl_N))) {
+ vim_free(lookfor);
+ lookfor = NULL;
+ }
+
+ /*
+ * When there are matching completions to select <S-Tab> works like
+ * CTRL-P (unless 'wc' is <S-Tab>).
+ */
+ if (c != p_wc && c == K_S_TAB && xpc.xp_numfiles > 0)
+ c = Ctrl_P;
+
+ /* Special translations for 'wildmenu' */
+ if (did_wild_list && p_wmnu) {
+ if (c == K_LEFT)
+ c = Ctrl_P;
+ else if (c == K_RIGHT)
+ c = Ctrl_N;
+ }
+ /* Hitting CR after "emenu Name.": complete submenu */
+ if (xpc.xp_context == EXPAND_MENUNAMES && p_wmnu
+ && ccline.cmdpos > 1
+ && ccline.cmdbuff[ccline.cmdpos - 1] == '.'
+ && ccline.cmdbuff[ccline.cmdpos - 2] != '\\'
+ && (c == '\n' || c == '\r' || c == K_KENTER))
+ c = K_DOWN;
+
+ /* free expanded names when finished walking through matches */
+ if (xpc.xp_numfiles != -1
+ && !(c == p_wc && KeyTyped) && c != p_wcm
+ && c != Ctrl_N && c != Ctrl_P && c != Ctrl_A
+ && c != Ctrl_L) {
+ (void)ExpandOne(&xpc, NULL, NULL, 0, WILD_FREE);
+ did_wild_list = FALSE;
+ if (!p_wmnu || (c != K_UP && c != K_DOWN))
+ xpc.xp_context = EXPAND_NOTHING;
+ wim_index = 0;
+ if (p_wmnu && wild_menu_showing != 0) {
+ int skt = KeyTyped;
+ int old_RedrawingDisabled = RedrawingDisabled;
+
+ if (ccline.input_fn)
+ RedrawingDisabled = 0;
+
+ if (wild_menu_showing == WM_SCROLLED) {
+ /* Entered command line, move it up */
+ cmdline_row--;
+ redrawcmd();
+ } 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(&save_ccline);
+ update_screen(VALID); /* redraw the screen NOW */
+ restore_cmdline(&save_ccline);
+ redrawcmd();
+ save_p_ls = -1;
+ } else {
+ win_redraw_last_status(topframe);
+ redraw_statuslines();
+ }
+ KeyTyped = skt;
+ wild_menu_showing = 0;
+ if (ccline.input_fn)
+ RedrawingDisabled = old_RedrawingDisabled;
+ }
+ }
+
+ /* Special translations for 'wildmenu' */
+ if (xpc.xp_context == EXPAND_MENUNAMES && p_wmnu) {
+ /* Hitting <Down> after "emenu Name.": complete submenu */
+ if (c == K_DOWN && ccline.cmdpos > 0
+ && ccline.cmdbuff[ccline.cmdpos - 1] == '.')
+ c = p_wc;
+ else if (c == K_UP) {
+ /* Hitting <Up>: Remove one submenu name in front of the
+ * cursor */
+ int found = FALSE;
+
+ j = (int)(xpc.xp_pattern - ccline.cmdbuff);
+ i = 0;
+ while (--j > 0) {
+ /* check for start of menu name */
+ if (ccline.cmdbuff[j] == ' '
+ && ccline.cmdbuff[j - 1] != '\\') {
+ i = j + 1;
+ break;
+ }
+ /* check for start of submenu name */
+ if (ccline.cmdbuff[j] == '.'
+ && ccline.cmdbuff[j - 1] != '\\') {
+ if (found) {
+ i = j + 1;
+ break;
+ } else
+ found = TRUE;
+ }
+ }
+ if (i > 0)
+ cmdline_del(i);
+ c = p_wc;
+ xpc.xp_context = EXPAND_NOTHING;
+ }
+ }
+ if ((xpc.xp_context == EXPAND_FILES
+ || xpc.xp_context == EXPAND_DIRECTORIES
+ || xpc.xp_context == EXPAND_SHELLCMD) && p_wmnu) {
+ char_u upseg[5];
+
+ upseg[0] = PATHSEP;
+ upseg[1] = '.';
+ upseg[2] = '.';
+ upseg[3] = PATHSEP;
+ upseg[4] = NUL;
+
+ if (c == K_DOWN
+ && ccline.cmdpos > 0
+ && ccline.cmdbuff[ccline.cmdpos - 1] == PATHSEP
+ && (ccline.cmdpos < 3
+ || ccline.cmdbuff[ccline.cmdpos - 2] != '.'
+ || ccline.cmdbuff[ccline.cmdpos - 3] != '.')) {
+ /* go down a directory */
+ c = p_wc;
+ } else if (STRNCMP(xpc.xp_pattern, upseg + 1, 3) == 0 && c == K_DOWN) {
+ /* If in a direct ancestor, strip off one ../ to go down */
+ int found = FALSE;
+
+ j = ccline.cmdpos;
+ i = (int)(xpc.xp_pattern - ccline.cmdbuff);
+ while (--j > i) {
+ if (has_mbyte)
+ j -= (*mb_head_off)(ccline.cmdbuff, ccline.cmdbuff + j);
+ if (vim_ispathsep(ccline.cmdbuff[j])) {
+ found = TRUE;
+ break;
+ }
+ }
+ if (found
+ && ccline.cmdbuff[j - 1] == '.'
+ && ccline.cmdbuff[j - 2] == '.'
+ && (vim_ispathsep(ccline.cmdbuff[j - 3]) || j == i + 2)) {
+ cmdline_del(j - 2);
+ c = p_wc;
+ }
+ } else if (c == K_UP) {
+ /* go up a directory */
+ int found = FALSE;
+
+ j = ccline.cmdpos - 1;
+ i = (int)(xpc.xp_pattern - ccline.cmdbuff);
+ while (--j > i) {
+ if (has_mbyte)
+ j -= (*mb_head_off)(ccline.cmdbuff, ccline.cmdbuff + j);
+ if (vim_ispathsep(ccline.cmdbuff[j])
+#ifdef BACKSLASH_IN_FILENAME
+ && vim_strchr(" *?[{`$%#", ccline.cmdbuff[j + 1])
+ == NULL
+#endif
+ ) {
+ if (found) {
+ i = j + 1;
+ break;
+ } else
+ found = TRUE;
+ }
+ }
+
+ if (!found)
+ j = i;
+ else if (STRNCMP(ccline.cmdbuff + j, upseg, 4) == 0)
+ j += 4;
+ else if (STRNCMP(ccline.cmdbuff + j, upseg + 1, 3) == 0
+ && j == i)
+ j += 3;
+ else
+ j = 0;
+ if (j > 0) {
+ /* TODO this is only for DOS/UNIX systems - need to put in
+ * machine-specific stuff here and in upseg init */
+ cmdline_del(j);
+ put_on_cmdline(upseg + 1, 3, FALSE);
+ } else if (ccline.cmdpos > i)
+ cmdline_del(i);
+
+ /* Now complete in the new directory. Set KeyTyped in case the
+ * Up key came from a mapping. */
+ c = p_wc;
+ KeyTyped = TRUE;
+ }
+ }
+
+
+ /* 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 (c == Ctrl_BSL) {
+ ++no_mapping;
+ ++allow_keys;
+ c = plain_vgetc();
+ --no_mapping;
+ --allow_keys;
+ /* CTRL-\ e doesn't work when obtaining an expression, unless it
+ * is in a mapping. */
+ if (c != Ctrl_N && c != Ctrl_G && (c != 'e'
+ || (ccline.cmdfirstc == '=' &&
+ KeyTyped))) {
+ vungetc(c);
+ c = Ctrl_BSL;
+ } else if (c == 'e') {
+ char_u *p = NULL;
+ int len;
+
+ /*
+ * Replace the command line with the result of an expression.
+ * Need to save and restore the current command line, to be
+ * able to enter a new one...
+ */
+ if (ccline.cmdpos == ccline.cmdlen)
+ new_cmdpos = 99999; /* keep it at the end */
+ else
+ new_cmdpos = ccline.cmdpos;
+
+ save_cmdline(&save_ccline);
+ c = get_expr_register();
+ restore_cmdline(&save_ccline);
+ if (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(&save_ccline);
+ ++textlock;
+ p = get_expr_line();
+ --textlock;
+ restore_cmdline(&save_ccline);
+
+ if (p != NULL) {
+ len = (int)STRLEN(p);
+ if (realloc_cmdbuff(len + 1) == OK) {
+ ccline.cmdlen = len;
+ STRCPY(ccline.cmdbuff, p);
+ vim_free(p);
+
+ /* Restore the cursor or use the position set with
+ * set_cmdline_pos(). */
+ if (new_cmdpos > ccline.cmdlen)
+ ccline.cmdpos = ccline.cmdlen;
+ else
+ ccline.cmdpos = new_cmdpos;
+
+ KeyTyped = FALSE; /* Don't do p_wc completion. */
+ redrawcmd();
+ goto cmdline_changed;
+ }
+ }
+ }
+ beep_flush();
+ got_int = FALSE; /* don't abandon the command line */
+ did_emsg = FALSE;
+ emsg_on_display = FALSE;
+ redrawcmd();
+ goto cmdline_not_changed;
+ } else {
+ if (c == Ctrl_G && p_im && restart_edit == 0)
+ restart_edit = 'a';
+ gotesc = TRUE; /* will free ccline.cmdbuff after putting it
+ in history */
+ goto returncmd; /* back to Normal mode */
+ }
+ }
+
+ if (c == cedit_key || c == K_CMDWIN) {
+ /*
+ * Open a window to edit the command line (and history).
+ */
+ c = ex_window();
+ some_key_typed = TRUE;
+ } else
+ c = do_digraph(c);
+
+ if (c == '\n' || c == '\r' || c == K_KENTER || (c == ESC
+ && (!KeyTyped ||
+ vim_strchr(p_cpo,
+ CPO_ESC) !=
+ NULL))) {
+ /* In Ex mode a backslash escapes a newline. */
+ if (exmode_active
+ && c != ESC
+ && ccline.cmdpos == ccline.cmdlen
+ && ccline.cmdpos > 0
+ && ccline.cmdbuff[ccline.cmdpos - 1] == '\\') {
+ if (c == K_KENTER)
+ c = '\n';
+ } else {
+ gotesc = FALSE; /* Might have typed ESC previously, don't
+ truncate the cmdline now. */
+ if (ccheck_abbr(c + ABBR_OFF))
+ goto cmdline_changed;
+ if (!cmd_silent) {
+ windgoto(msg_row, 0);
+ out_flush();
+ }
+ break;
+ }
+ }
+
+ /*
+ * Completion for 'wildchar' or 'wildcharm' key.
+ * - hitting <ESC> twice means: abandon command line.
+ * - wildcard expansion is only done when the 'wildchar' key is really
+ * typed, not when it comes from a macro
+ */
+ if ((c == p_wc && !gotesc && KeyTyped) || c == p_wcm) {
+ if (xpc.xp_numfiles > 0) { /* typed p_wc at least twice */
+ /* if 'wildmode' contains "list" may still need to list */
+ if (xpc.xp_numfiles > 1
+ && !did_wild_list
+ && (wim_flags[wim_index] & WIM_LIST)) {
+ (void)showmatches(&xpc, FALSE);
+ redrawcmd();
+ did_wild_list = TRUE;
+ }
+ if (wim_flags[wim_index] & WIM_LONGEST)
+ res = nextwild(&xpc, WILD_LONGEST, WILD_NO_BEEP,
+ firstc != '@');
+ else if (wim_flags[wim_index] & WIM_FULL)
+ res = nextwild(&xpc, WILD_NEXT, WILD_NO_BEEP,
+ firstc != '@');
+ else
+ res = OK; /* don't insert 'wildchar' now */
+ } else { /* typed p_wc first time */
+ wim_index = 0;
+ j = ccline.cmdpos;
+ /* if 'wildmode' first contains "longest", get longest
+ * common part */
+ if (wim_flags[0] & WIM_LONGEST)
+ res = nextwild(&xpc, WILD_LONGEST, WILD_NO_BEEP,
+ firstc != '@');
+ else
+ res = nextwild(&xpc, WILD_EXPAND_KEEP, WILD_NO_BEEP,
+ firstc != '@');
+
+ /* if interrupted while completing, behave like it failed */
+ if (got_int) {
+ (void)vpeekc(); /* remove <C-C> from input stream */
+ got_int = FALSE; /* don't abandon the command line */
+ (void)ExpandOne(&xpc, NULL, NULL, 0, WILD_FREE);
+ xpc.xp_context = EXPAND_NOTHING;
+ goto cmdline_changed;
+ }
+
+ /* when more than one match, and 'wildmode' first contains
+ * "list", or no change and 'wildmode' contains "longest,list",
+ * list all matches */
+ if (res == OK && xpc.xp_numfiles > 1) {
+ /* a "longest" that didn't do anything is skipped (but not
+ * "list:longest") */
+ if (wim_flags[0] == WIM_LONGEST && ccline.cmdpos == j)
+ wim_index = 1;
+ if ((wim_flags[wim_index] & WIM_LIST)
+ || (p_wmnu && (wim_flags[wim_index] & WIM_FULL) != 0)
+ ) {
+ if (!(wim_flags[0] & WIM_LONGEST)) {
+ int p_wmnu_save = p_wmnu;
+ p_wmnu = 0;
+ /* remove match */
+ nextwild(&xpc, WILD_PREV, 0, firstc != '@');
+ p_wmnu = p_wmnu_save;
+ }
+ (void)showmatches(&xpc, p_wmnu
+ && ((wim_flags[wim_index] & WIM_LIST) == 0));
+ redrawcmd();
+ did_wild_list = TRUE;
+ if (wim_flags[wim_index] & WIM_LONGEST)
+ nextwild(&xpc, WILD_LONGEST, WILD_NO_BEEP,
+ firstc != '@');
+ else if (wim_flags[wim_index] & WIM_FULL)
+ nextwild(&xpc, WILD_NEXT, WILD_NO_BEEP,
+ firstc != '@');
+ } else
+ vim_beep();
+ } else if (xpc.xp_numfiles == -1)
+ xpc.xp_context = EXPAND_NOTHING;
+ }
+ if (wim_index < 3)
+ ++wim_index;
+ if (c == ESC)
+ gotesc = TRUE;
+ if (res == OK)
+ goto cmdline_changed;
+ }
+
+ gotesc = FALSE;
+
+ /* <S-Tab> goes to last match, in a clumsy way */
+ if (c == K_S_TAB && KeyTyped) {
+ if (nextwild(&xpc, WILD_EXPAND_KEEP, 0, firstc != '@') == OK
+ && nextwild(&xpc, WILD_PREV, 0, firstc != '@') == OK
+ && nextwild(&xpc, WILD_PREV, 0, firstc != '@') == OK)
+ goto cmdline_changed;
+ }
+
+ if (c == NUL || c == K_ZERO) /* NUL is stored as NL */
+ c = NL;
+
+ do_abbr = TRUE; /* default: check for abbreviation */
+
+ /*
+ * Big switch for a typed command line character.
+ */
+ switch (c) {
+ case K_BS:
+ case Ctrl_H:
+ case K_DEL:
+ case K_KDEL:
+ case Ctrl_W:
+ if (cmd_fkmap && c == K_BS)
+ c = K_DEL;
+ if (c == K_KDEL)
+ c = K_DEL;
+
+ /*
+ * delete current character is the same as backspace on next
+ * character, except at end of line
+ */
+ if (c == K_DEL && ccline.cmdpos != ccline.cmdlen)
+ ++ccline.cmdpos;
+ if (has_mbyte && c == K_DEL)
+ ccline.cmdpos += mb_off_next(ccline.cmdbuff,
+ ccline.cmdbuff + ccline.cmdpos);
+ if (ccline.cmdpos > 0) {
+ char_u *p;
+
+ j = ccline.cmdpos;
+ p = ccline.cmdbuff + j;
+ if (has_mbyte) {
+ p = mb_prevptr(ccline.cmdbuff, p);
+ if (c == Ctrl_W) {
+ while (p > ccline.cmdbuff && vim_isspace(*p))
+ p = mb_prevptr(ccline.cmdbuff, p);
+ i = mb_get_class(p);
+ while (p > ccline.cmdbuff && mb_get_class(p) == i)
+ p = mb_prevptr(ccline.cmdbuff, p);
+ if (mb_get_class(p) != i)
+ p += (*mb_ptr2len)(p);
+ }
+ } else if (c == Ctrl_W) {
+ while (p > ccline.cmdbuff && vim_isspace(p[-1]))
+ --p;
+ i = vim_iswordc(p[-1]);
+ while (p > ccline.cmdbuff && !vim_isspace(p[-1])
+ && vim_iswordc(p[-1]) == i)
+ --p;
+ } else
+ --p;
+ ccline.cmdpos = (int)(p - ccline.cmdbuff);
+ ccline.cmdlen -= j - ccline.cmdpos;
+ i = ccline.cmdpos;
+ while (i < ccline.cmdlen)
+ ccline.cmdbuff[i++] = ccline.cmdbuff[j++];
+
+ /* Truncate at the end, required for multi-byte chars. */
+ ccline.cmdbuff[ccline.cmdlen] = NUL;
+ redrawcmd();
+ } else if (ccline.cmdlen == 0 && c != Ctrl_W
+ && ccline.cmdprompt == NULL && indent == 0) {
+ /* In ex and debug mode it doesn't make sense to return. */
+ if (exmode_active
+ || ccline.cmdfirstc == '>'
+ )
+ goto cmdline_not_changed;
+
+ vim_free(ccline.cmdbuff); /* no commandline to return */
+ ccline.cmdbuff = NULL;
+ if (!cmd_silent) {
+ if (cmdmsg_rl)
+ msg_col = Columns;
+ else
+ msg_col = 0;
+ msg_putchar(' '); /* delete ':' */
+ }
+ redraw_cmdline = TRUE;
+ goto returncmd; /* back to cmd mode */
+ }
+ goto cmdline_changed;
+
+ case K_INS:
+ case K_KINS:
+ /* if Farsi mode set, we are in reverse insert mode -
+ Do not change the mode */
+ if (cmd_fkmap)
+ beep_flush();
+ else
+ ccline.overstrike = !ccline.overstrike;
+#ifdef CURSOR_SHAPE
+ ui_cursor_shape(); /* may show different cursor shape */
+#endif
+ goto cmdline_not_changed;
+
+ case Ctrl_HAT:
+ if (map_to_exists_mode((char_u *)"", LANGMAP, FALSE)) {
+ /* ":lmap" mappings exists, toggle use of mappings. */
+ State ^= LANGMAP;
+#ifdef USE_IM_CONTROL
+ im_set_active(FALSE); /* Disable input method */
+#endif
+ if (b_im_ptr != NULL) {
+ if (State & LANGMAP)
+ *b_im_ptr = B_IMODE_LMAP;
+ else
+ *b_im_ptr = B_IMODE_NONE;
+ }
+ }
+#ifdef USE_IM_CONTROL
+ else {
+ /* There are no ":lmap" mappings, toggle IM. When
+ * 'imdisable' is set don't try getting the status, it's
+ * always off. */
+ if ((p_imdisable && b_im_ptr != NULL)
+ ? *b_im_ptr == B_IMODE_IM : im_get_status()) {
+ im_set_active(FALSE); /* Disable input method */
+ if (b_im_ptr != NULL)
+ *b_im_ptr = B_IMODE_NONE;
+ } else {
+ im_set_active(TRUE); /* Enable input method */
+ if (b_im_ptr != NULL)
+ *b_im_ptr = B_IMODE_IM;
+ }
+ }
+#endif
+ if (b_im_ptr != NULL) {
+ if (b_im_ptr == &curbuf->b_p_iminsert)
+ set_iminsert_global();
+ else
+ set_imsearch_global();
+ }
+#ifdef CURSOR_SHAPE
+ ui_cursor_shape(); /* may show different cursor shape */
+#endif
+ /* Show/unshow value of 'keymap' in status lines later. */
+ status_redraw_curbuf();
+ goto cmdline_not_changed;
+
+ /* case '@': only in very old vi */
+ case Ctrl_U:
+ /* delete all characters left of the cursor */
+ j = ccline.cmdpos;
+ ccline.cmdlen -= j;
+ i = ccline.cmdpos = 0;
+ while (i < ccline.cmdlen)
+ ccline.cmdbuff[i++] = ccline.cmdbuff[j++];
+ /* Truncate at the end, required for multi-byte chars. */
+ ccline.cmdbuff[ccline.cmdlen] = NUL;
+ redrawcmd();
+ goto cmdline_changed;
+
+
+ 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)
+ )
+ goto cmdline_not_changed;
+
+ gotesc = TRUE; /* will free ccline.cmdbuff after
+ putting it in history */
+ goto returncmd; /* back to cmd mode */
+
+ case Ctrl_R: /* insert register */
+#ifdef USE_ON_FLY_SCROLL
+ dont_scroll = TRUE; /* disallow scrolling here */
+#endif
+ putcmdline('"', TRUE);
+ ++no_mapping;
+ i = c = plain_vgetc(); /* CTRL-R <char> */
+ if (i == Ctrl_O)
+ i = Ctrl_R; /* CTRL-R CTRL-O == CTRL-R CTRL-R */
+ if (i == Ctrl_R)
+ c = plain_vgetc(); /* CTRL-R CTRL-R <char> */
+ --no_mapping;
+ /*
+ * Insert the result of an expression.
+ * Need to save the current command line, to be able to enter
+ * a new one...
+ */
+ new_cmdpos = -1;
+ if (c == '=') {
+ if (ccline.cmdfirstc == '=') { /* can't do this recursively */
+ beep_flush();
+ c = ESC;
+ } else {
+ save_cmdline(&save_ccline);
+ c = get_expr_register();
+ restore_cmdline(&save_ccline);
+ }
+ }
+ if (c != ESC) { /* use ESC to cancel inserting register */
+ cmdline_paste(c, i == Ctrl_R, FALSE);
+
+ /* When there was a serious error abort getting the
+ * command line. */
+ if (aborting()) {
+ gotesc = TRUE; /* will free ccline.cmdbuff after
+ putting it in history */
+ goto returncmd; /* back to cmd mode */
+ }
+ KeyTyped = FALSE; /* Don't do p_wc completion. */
+ if (new_cmdpos >= 0) {
+ /* set_cmdline_pos() was used */
+ if (new_cmdpos > ccline.cmdlen)
+ ccline.cmdpos = ccline.cmdlen;
+ else
+ ccline.cmdpos = new_cmdpos;
+ }
+ }
+ redrawcmd();
+ goto cmdline_changed;
+
+ case Ctrl_D:
+ if (showmatches(&xpc, FALSE) == EXPAND_NOTHING)
+ break; /* Use ^D as normal char instead */
+
+ redrawcmd();
+ continue; /* don't do incremental search now */
+
+ case K_RIGHT:
+ case K_S_RIGHT:
+ case K_C_RIGHT:
+ do {
+ if (ccline.cmdpos >= ccline.cmdlen)
+ break;
+ i = cmdline_charsize(ccline.cmdpos);
+ if (KeyTyped && ccline.cmdspos + i >= Columns * Rows)
+ break;
+ ccline.cmdspos += i;
+ if (has_mbyte)
+ ccline.cmdpos += (*mb_ptr2len)(ccline.cmdbuff
+ + ccline.cmdpos);
+ else
+ ++ccline.cmdpos;
+ } while ((c == K_S_RIGHT || c == K_C_RIGHT
+ || (mod_mask & (MOD_MASK_SHIFT|MOD_MASK_CTRL)))
+ && ccline.cmdbuff[ccline.cmdpos] != ' ');
+ if (has_mbyte)
+ set_cmdspos_cursor();
+ goto cmdline_not_changed;
+
+ case K_LEFT:
+ case K_S_LEFT:
+ case K_C_LEFT:
+ if (ccline.cmdpos == 0)
+ goto cmdline_not_changed;
+ do {
+ --ccline.cmdpos;
+ if (has_mbyte) /* move to first byte of char */
+ ccline.cmdpos -= (*mb_head_off)(ccline.cmdbuff,
+ ccline.cmdbuff + ccline.cmdpos);
+ ccline.cmdspos -= cmdline_charsize(ccline.cmdpos);
+ } while (ccline.cmdpos > 0
+ && (c == K_S_LEFT || c == K_C_LEFT
+ || (mod_mask & (MOD_MASK_SHIFT|MOD_MASK_CTRL)))
+ && ccline.cmdbuff[ccline.cmdpos - 1] != ' ');
+ if (has_mbyte)
+ set_cmdspos_cursor();
+ goto cmdline_not_changed;
+
+ case K_IGNORE:
+ /* Ignore mouse event or ex_window() result. */
+ goto cmdline_not_changed;
+
+
+ case K_MIDDLEDRAG:
+ case K_MIDDLERELEASE:
+ goto cmdline_not_changed; /* Ignore mouse */
+
+ case K_MIDDLEMOUSE:
+ if (!mouse_has(MOUSE_COMMAND))
+ goto cmdline_not_changed; /* Ignore mouse */
+ cmdline_paste(0, TRUE, TRUE);
+ redrawcmd();
+ goto cmdline_changed;
+
+
+ case K_LEFTDRAG:
+ case K_LEFTRELEASE:
+ case K_RIGHTDRAG:
+ case K_RIGHTRELEASE:
+ /* Ignore drag and release events when the button-down wasn't
+ * seen before. */
+ if (ignore_drag_release)
+ goto cmdline_not_changed;
+ /* FALLTHROUGH */
+ case K_LEFTMOUSE:
+ case K_RIGHTMOUSE:
+ if (c == K_LEFTRELEASE || c == K_RIGHTRELEASE)
+ ignore_drag_release = TRUE;
+ else
+ ignore_drag_release = FALSE;
+ if (!mouse_has(MOUSE_COMMAND))
+ goto cmdline_not_changed; /* Ignore mouse */
+
+ set_cmdspos();
+ for (ccline.cmdpos = 0; ccline.cmdpos < ccline.cmdlen;
+ ++ccline.cmdpos) {
+ i = cmdline_charsize(ccline.cmdpos);
+ if (mouse_row <= cmdline_row + ccline.cmdspos / Columns
+ && mouse_col < ccline.cmdspos % Columns + i)
+ break;
+ if (has_mbyte) {
+ /* Count ">" for double-wide char that doesn't fit. */
+ correct_cmdspos(ccline.cmdpos, i);
+ ccline.cmdpos += (*mb_ptr2len)(ccline.cmdbuff
+ + ccline.cmdpos) - 1;
+ }
+ ccline.cmdspos += i;
+ }
+ goto cmdline_not_changed;
+
+ /* Mouse scroll wheel: ignored here */
+ case K_MOUSEDOWN:
+ case K_MOUSEUP:
+ case K_MOUSELEFT:
+ case K_MOUSERIGHT:
+ /* Alternate buttons ignored here */
+ case K_X1MOUSE:
+ case K_X1DRAG:
+ case K_X1RELEASE:
+ case K_X2MOUSE:
+ case K_X2DRAG:
+ case K_X2RELEASE:
+ goto cmdline_not_changed;
+
+
+
+ case K_SELECT: /* end of Select mode mapping - ignore */
+ goto cmdline_not_changed;
+
+ case Ctrl_B: /* begin of command line */
+ case K_HOME:
+ case K_KHOME:
+ case K_S_HOME:
+ case K_C_HOME:
+ ccline.cmdpos = 0;
+ set_cmdspos();
+ goto cmdline_not_changed;
+
+ case Ctrl_E: /* end of command line */
+ case K_END:
+ case K_KEND:
+ case K_S_END:
+ case K_C_END:
+ ccline.cmdpos = ccline.cmdlen;
+ set_cmdspos_cursor();
+ goto cmdline_not_changed;
+
+ case Ctrl_A: /* all matches */
+ if (nextwild(&xpc, WILD_ALL, 0, firstc != '@') == FAIL)
+ break;
+ goto cmdline_changed;
+
+ case Ctrl_L:
+ if (p_is && !cmd_silent && (firstc == '/' || firstc == '?')) {
+ /* Add a character from under the cursor for 'incsearch' */
+ if (did_incsearch
+ && !equalpos(curwin->w_cursor, old_cursor)) {
+ 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))
+ c = MB_TOLOWER(c);
+ if (c != NUL) {
+ if (c == firstc || vim_strchr((char_u *)(
+ p_magic ? "\\^$.*[" : "\\^$"), c)
+ != NULL) {
+ /* put a backslash before special characters */
+ stuffcharReadbuff(c);
+ c = '\\';
+ }
+ break;
+ }
+ }
+ goto cmdline_not_changed;
+ }
+
+ /* completion: longest common part */
+ if (nextwild(&xpc, WILD_LONGEST, 0, firstc != '@') == FAIL)
+ break;
+ goto cmdline_changed;
+
+ case Ctrl_N: /* next match */
+ case Ctrl_P: /* previous match */
+ if (xpc.xp_numfiles > 0) {
+ if (nextwild(&xpc, (c == Ctrl_P) ? WILD_PREV : WILD_NEXT,
+ 0, firstc != '@') == FAIL)
+ break;
+ goto cmdline_changed;
+ }
+
+ case K_UP:
+ case K_DOWN:
+ case K_S_UP:
+ case K_S_DOWN:
+ case K_PAGEUP:
+ case K_KPAGEUP:
+ case K_PAGEDOWN:
+ case K_KPAGEDOWN:
+ if (hislen == 0 || firstc == NUL) /* no history */
+ goto cmdline_not_changed;
+
+ i = hiscnt;
+
+ /* save current command string so it can be restored later */
+ if (lookfor == NULL) {
+ if ((lookfor = vim_strsave(ccline.cmdbuff)) == NULL)
+ goto cmdline_not_changed;
+ lookfor[ccline.cmdpos] = NUL;
+ }
+
+ j = (int)STRLEN(lookfor);
+ for (;; ) {
+ /* one step backwards */
+ if (c == K_UP|| c == K_S_UP || c == Ctrl_P
+ || c == K_PAGEUP || c == K_KPAGEUP) {
+ if (hiscnt == hislen) /* first time */
+ hiscnt = hisidx[histype];
+ else if (hiscnt == 0 && hisidx[histype] != hislen - 1)
+ hiscnt = hislen - 1;
+ else if (hiscnt != hisidx[histype] + 1)
+ --hiscnt;
+ else { /* at top of list */
+ hiscnt = i;
+ break;
+ }
+ } else { /* one step forwards */
+ /* on last entry, clear the line */
+ if (hiscnt == hisidx[histype]) {
+ hiscnt = hislen;
+ break;
+ }
+
+ /* not on a history line, nothing to do */
+ if (hiscnt == hislen)
+ break;
+ if (hiscnt == hislen - 1) /* wrap around */
+ hiscnt = 0;
+ else
+ ++hiscnt;
+ }
+ if (hiscnt < 0 || history[histype][hiscnt].hisstr == NULL) {
+ hiscnt = i;
+ break;
+ }
+ if ((c != K_UP && c != K_DOWN)
+ || hiscnt == i
+ || STRNCMP(history[histype][hiscnt].hisstr,
+ lookfor, (size_t)j) == 0)
+ break;
+ }
+
+ if (hiscnt != i) { /* jumped to other entry */
+ char_u *p;
+ int len;
+ int old_firstc;
+
+ vim_free(ccline.cmdbuff);
+ xpc.xp_context = EXPAND_NOTHING;
+ if (hiscnt == hislen)
+ p = lookfor; /* back to the old one */
+ else
+ p = history[histype][hiscnt].hisstr;
+
+ if (histype == HIST_SEARCH
+ && p != lookfor
+ && (old_firstc = p[STRLEN(p) + 1]) != firstc) {
+ /* Correct for the separator character used when
+ * adding the history entry vs the one used now.
+ * First loop: count length.
+ * Second loop: copy the characters. */
+ for (i = 0; i <= 1; ++i) {
+ len = 0;
+ for (j = 0; p[j] != NUL; ++j) {
+ /* Replace old sep with new sep, unless it is
+ * escaped. */
+ if (p[j] == old_firstc
+ && (j == 0 || p[j - 1] != '\\')) {
+ if (i > 0)
+ ccline.cmdbuff[len] = firstc;
+ } else {
+ /* Escape new sep, unless it is already
+ * escaped. */
+ if (p[j] == firstc
+ && (j == 0 || p[j - 1] != '\\')) {
+ if (i > 0)
+ ccline.cmdbuff[len] = '\\';
+ ++len;
+ }
+ if (i > 0)
+ ccline.cmdbuff[len] = p[j];
+ }
+ ++len;
+ }
+ if (i == 0) {
+ alloc_cmdbuff(len);
+ if (ccline.cmdbuff == NULL)
+ goto returncmd;
+ }
+ }
+ ccline.cmdbuff[len] = NUL;
+ } else {
+ alloc_cmdbuff((int)STRLEN(p));
+ if (ccline.cmdbuff == NULL)
+ goto returncmd;
+ STRCPY(ccline.cmdbuff, p);
+ }
+
+ ccline.cmdpos = ccline.cmdlen = (int)STRLEN(ccline.cmdbuff);
+ redrawcmd();
+ goto cmdline_changed;
+ }
+ beep_flush();
+ goto cmdline_not_changed;
+
+ case Ctrl_V:
+ case Ctrl_Q:
+ ignore_drag_release = TRUE;
+ putcmdline('^', TRUE);
+ c = get_literal(); /* get next (two) character(s) */
+ do_abbr = FALSE; /* don't do abbreviation now */
+ /* may need to remove ^ when composing char was typed */
+ if (enc_utf8 && utf_iscomposing(c) && !cmd_silent) {
+ draw_cmdline(ccline.cmdpos, ccline.cmdlen - ccline.cmdpos);
+ msg_putchar(' ');
+ cursorcmd();
+ }
+ break;
+
+ case Ctrl_K:
+ ignore_drag_release = TRUE;
+ putcmdline('?', TRUE);
+#ifdef USE_ON_FLY_SCROLL
+ dont_scroll = TRUE; /* disallow scrolling here */
+#endif
+ c = get_digraph(TRUE);
+ if (c != NUL)
+ break;
+
+ redrawcmd();
+ goto cmdline_not_changed;
+
+ case Ctrl__: /* CTRL-_: switch language mode */
+ if (!p_ari)
+ break;
+ if (p_altkeymap) {
+ cmd_fkmap = !cmd_fkmap;
+ if (cmd_fkmap) /* in Farsi always in Insert mode */
+ ccline.overstrike = FALSE;
+ } else /* Hebrew is default */
+ cmd_hkmap = !cmd_hkmap;
+ goto cmdline_not_changed;
+
+ default:
+#ifdef UNIX
+ if (c == intr_char) {
+ gotesc = TRUE; /* will free ccline.cmdbuff after
+ putting it in history */
+ goto returncmd; /* back to Normal mode */
+ }
+#endif
+ /*
+ * Normal character with no special meaning. Just set mod_mask
+ * to 0x0 so that typing Shift-Space in the GUI doesn't enter
+ * the string <S-Space>. This should only happen after ^V.
+ */
+ if (!IS_SPECIAL(c))
+ mod_mask = 0x0;
+ break;
+ }
+ /*
+ * End of switch on command line character.
+ * We come here if we have a normal character.
+ */
+
+ if (do_abbr && (IS_SPECIAL(c) || !vim_iswordc(c)) && (ccheck_abbr(
+ /* Add ABBR_OFF for characters above 0x100, this is
+ * what check_abbr() expects. */
+ (has_mbyte &&
+ c >=
+ 0x100) ? (c +
+ ABBR_OFF) :
+ c) || c ==
+ Ctrl_RSB))
+ goto cmdline_changed;
+
+ /*
+ * put the character in the command line
+ */
+ if (IS_SPECIAL(c) || mod_mask != 0)
+ put_on_cmdline(get_special_key_name(c, mod_mask), -1, TRUE);
+ else {
+ if (has_mbyte) {
+ j = (*mb_char2bytes)(c, IObuff);
+ IObuff[j] = NUL; /* exclude composing chars */
+ put_on_cmdline(IObuff, j, TRUE);
+ } else {
+ IObuff[0] = c;
+ put_on_cmdline(IObuff, 1, TRUE);
+ }
+ }
+ goto cmdline_changed;
+
+ /*
+ * 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).
+ */
+cmdline_not_changed:
+ if (!incsearch_postponed)
+ continue;
+
+cmdline_changed:
+ /*
+ * 'incsearch' highlighting.
+ */
+ if (p_is && !cmd_silent && (firstc == '/' || firstc == '?')) {
+ pos_T end_pos;
+ proftime_T tm;
+
+ /* if there is a character waiting, search and redraw later */
+ if (char_avail()) {
+ incsearch_postponed = TRUE;
+ continue;
+ }
+ incsearch_postponed = FALSE;
+ curwin->w_cursor = old_cursor; /* start at old position */
+
+ /* If there is no command line, don't do anything */
+ if (ccline.cmdlen == 0)
+ i = 0;
+ else {
+ cursor_off(); /* so the user knows we're busy */
+ out_flush();
+ ++emsg_off; /* So it doesn't beep if bad expr */
+ /* Set the time limit to half a second. */
+ profile_setlimit(500L, &tm);
+ i = do_search(NULL, firstc, ccline.cmdbuff, count,
+ SEARCH_KEEP + SEARCH_OPT + SEARCH_NOOF + SEARCH_PEEK,
+ &tm
+ );
+ --emsg_off;
+ /* if interrupted while searching, behave like it failed */
+ if (got_int) {
+ (void)vpeekc(); /* remove <C-C> from input stream */
+ got_int = FALSE; /* don't abandon the command line */
+ i = 0;
+ } else if (char_avail())
+ /* cancelled searching because a char was typed */
+ incsearch_postponed = TRUE;
+ }
+ if (i != 0)
+ highlight_match = TRUE; /* highlight position */
+ else
+ highlight_match = FALSE; /* remove highlight */
+
+ /* first restore the old curwin values, so the screen is
+ * positioned in the same way as the actual search command */
+ curwin->w_leftcol = old_leftcol;
+ curwin->w_topline = old_topline;
+ curwin->w_topfill = old_topfill;
+ curwin->w_botline = old_botline;
+ changed_cline_bef_curs();
+ update_topline();
+
+ if (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);
+ }
+ validate_cursor();
+ end_pos = curwin->w_cursor;
+ curwin->w_cursor = save_pos;
+ } else
+ end_pos = curwin->w_cursor; /* shutup gcc 4 */
+
+ 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(&save_ccline);
+ update_screen(SOME_VALID);
+ restore_cmdline(&save_ccline);
+
+ /* Leave it at the end to make CTRL-R CTRL-W work. */
+ if (i != 0)
+ curwin->w_cursor = end_pos;
+
+ msg_starthere();
+ redrawcmdline();
+ did_incsearch = TRUE;
+ }
+
+ if (cmdmsg_rl
+ || (p_arshape && !p_tbidi && enc_utf8)
+ )
+ /* Always redraw the whole command line to fix shaping and
+ * 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)
+ redrawcmd();
+ }
+
+returncmd:
+
+ cmdmsg_rl = FALSE;
+
+ cmd_fkmap = 0;
+
+ ExpandCleanup(&xpc);
+ ccline.xpc = NULL;
+
+ if (did_incsearch) {
+ curwin->w_cursor = old_cursor;
+ curwin->w_curswant = old_curswant;
+ curwin->w_leftcol = old_leftcol;
+ curwin->w_topline = old_topline;
+ curwin->w_topfill = old_topfill;
+ curwin->w_botline = old_botline;
+ highlight_match = FALSE;
+ validate_cursor(); /* needed for TAB */
+ redraw_later(SOME_VALID);
+ }
+
+ if (ccline.cmdbuff != NULL) {
+ /*
+ * Put line in history buffer (":" and "=" only when it was typed).
+ */
+ if (ccline.cmdlen && firstc != NUL
+ && (some_key_typed || histype == HIST_SEARCH)) {
+ add_to_history(histype, ccline.cmdbuff, TRUE,
+ histype == HIST_SEARCH ? firstc : NUL);
+ if (firstc == ':') {
+ vim_free(new_last_cmdline);
+ new_last_cmdline = vim_strsave(ccline.cmdbuff);
+ }
+ }
+
+ if (gotesc) { /* abandon command line */
+ vim_free(ccline.cmdbuff);
+ ccline.cmdbuff = NULL;
+ if (msg_scrolled == 0)
+ compute_cmdrow();
+ MSG("");
+ redraw_cmdline = TRUE;
+ }
+ }
+
+ /*
+ * If the screen was shifted up, redraw the whole screen (later).
+ * If the line is too long, clear it, so ruler and shown command do
+ * not get printed in the middle of it.
+ */
+ msg_check();
+ msg_scroll = save_msg_scroll;
+ redir_off = FALSE;
+
+ /* When the command line was typed, no need for a wait-return prompt. */
+ if (some_key_typed)
+ need_wait_return = FALSE;
+
+ State = save_State;
+#ifdef USE_IM_CONTROL
+ if (b_im_ptr != NULL && *b_im_ptr != B_IMODE_LMAP)
+ im_save_status(b_im_ptr);
+ im_set_active(FALSE);
+#endif
+ setmouse();
+#ifdef CURSOR_SHAPE
+ ui_cursor_shape(); /* may show different cursor shape */
+#endif
+
+ {
+ char_u *p = ccline.cmdbuff;
+
+ /* Make ccline empty, getcmdline() may try to use it. */
+ ccline.cmdbuff = NULL;
+ return p;
+ }
+}
+
+/*
+ * 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(firstc, prompt, attr, xp_context, xp_arg)
+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 */
+{
+ char_u *s;
+ struct cmdline_info save_ccline;
+ int msg_col_save = msg_col;
+
+ save_cmdline(&save_ccline);
+ ccline.cmdprompt = prompt;
+ ccline.cmdattr = attr;
+ ccline.xp_context = xp_context;
+ ccline.xp_arg = xp_arg;
+ ccline.input_fn = (firstc == '@');
+ s = getcmdline(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_col = msg_col_save;
+
+ return s;
+}
+
+/*
+ * Return TRUE when the text must not be changed and we can't switch to
+ * another window or buffer. Used when editing the command line, evaluating
+ * 'balloonexpr', etc.
+ */
+int text_locked() {
+ if (cmdwin_type != 0)
+ return TRUE;
+ return textlock != 0;
+}
+
+/*
+ * Give an error message for a command that isn't allowed while the cmdline
+ * window is open or editing the cmdline in another way.
+ */
+void text_locked_msg() {
+ if (cmdwin_type != 0)
+ EMSG(_(e_cmdwin));
+ else
+ EMSG(_(e_secure));
+}
+
+/*
+ * Check if "curbuf_lock" or "allbuf_lock" is set and return TRUE when it is
+ * and give an error message.
+ */
+int curbuf_locked() {
+ if (curbuf_lock > 0) {
+ EMSG(_("E788: Not allowed to edit another buffer now"));
+ return TRUE;
+ }
+ return allbuf_locked();
+}
+
+/*
+ * Check if "allbuf_lock" is set and return TRUE when it is and give an error
+ * message.
+ */
+int allbuf_locked() {
+ if (allbuf_lock > 0) {
+ EMSG(_("E811: Not allowed to change buffer information now"));
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static int cmdline_charsize(idx)
+int idx;
+{
+ if (cmdline_star > 0) /* showing '*', always 1 position */
+ return 1;
+ return ptr2cells(ccline.cmdbuff + idx);
+}
+
+/*
+ * Compute the offset of the cursor on the command line for the prompt and
+ * indent.
+ */
+static void set_cmdspos() {
+ if (ccline.cmdfirstc != NUL)
+ ccline.cmdspos = 1 + ccline.cmdindent;
+ else
+ ccline.cmdspos = 0 + ccline.cmdindent;
+}
+
+/*
+ * Compute the screen position for the cursor on the command line.
+ */
+static void set_cmdspos_cursor() {
+ int i, m, c;
+
+ set_cmdspos();
+ if (KeyTyped) {
+ m = Columns * Rows;
+ if (m < 0) /* overflow, Columns or Rows at weird value */
+ m = MAXCOL;
+ } else
+ m = MAXCOL;
+ for (i = 0; i < ccline.cmdlen && i < ccline.cmdpos; ++i) {
+ c = cmdline_charsize(i);
+ /* Count ">" for double-wide multi-byte char that doesn't fit. */
+ if (has_mbyte)
+ correct_cmdspos(i, c);
+ /* If the cmdline doesn't fit, show cursor on last visible char.
+ * Don't move the cursor itself, so we can still append. */
+ if ((ccline.cmdspos += c) >= m) {
+ ccline.cmdspos -= c;
+ break;
+ }
+ if (has_mbyte)
+ i += (*mb_ptr2len)(ccline.cmdbuff + i) - 1;
+ }
+}
+
+/*
+ * Check if the character at "idx", which is "cells" wide, is a multi-byte
+ * character that doesn't fit, so that a ">" must be displayed.
+ */
+static void correct_cmdspos(idx, cells)
+int idx;
+int cells;
+{
+ if ((*mb_ptr2len)(ccline.cmdbuff + idx) > 1
+ && (*mb_ptr2cells)(ccline.cmdbuff + idx) > 1
+ && ccline.cmdspos % Columns + cells > Columns)
+ ccline.cmdspos++;
+}
+
+/*
+ * Get an Ex command line for the ":" command.
+ */
+char_u * getexline(c, cookie, indent)
+int c; /* normally ':', NUL for ":append" */
+void *cookie UNUSED;
+int indent; /* indent for inside conditionals */
+{
+ /* When executing a register, remove ':' that's in front of each line. */
+ if (exec_from_reg && vpeekc() == ':')
+ (void)vgetc();
+ return getcmdline(c, 1L, indent);
+}
+
+/*
+ * Get an Ex command line for Ex mode.
+ * In Ex mode we only use the OS supplied line editing features and no
+ * mappings or abbreviations.
+ * Returns a string in allocated memory or NULL.
+ */
+char_u * getexmodeline(promptc, cookie, indent)
+int promptc; /* normally ':', NUL for ":append" and '?' for
+ :s prompt */
+void *cookie UNUSED;
+int indent; /* indent for inside conditionals */
+{
+ garray_T line_ga;
+ char_u *pend;
+ int startcol = 0;
+ int c1 = 0;
+ int escaped = FALSE; /* CTRL-V typed */
+ int vcol = 0;
+ char_u *p;
+ int prev_char;
+
+ /* Switch cursor on now. This avoids that it happens after the "\n", which
+ * confuses the system function that computes tabstops. */
+ cursor_on();
+
+ /* always start in column 0; write a newline if necessary */
+ compute_cmdrow();
+ if ((msg_col || msg_didout) && promptc != '?')
+ msg_putchar('\n');
+ if (promptc == ':') {
+ /* indent that is only displayed, not in the line itself */
+ if (p_prompt)
+ msg_putchar(':');
+ while (indent-- > 0)
+ msg_putchar(' ');
+ startcol = msg_col;
+ }
+
+ ga_init2(&line_ga, 1, 30);
+
+ /* autoindent for :insert and :append is in the line itself */
+ if (promptc <= 0) {
+ vcol = indent;
+ while (indent >= 8) {
+ ga_append(&line_ga, TAB);
+ msg_puts((char_u *)" ");
+ indent -= 8;
+ }
+ while (indent-- > 0) {
+ ga_append(&line_ga, ' ');
+ msg_putchar(' ');
+ }
+ }
+ ++no_mapping;
+ ++allow_keys;
+
+ /*
+ * Get the line, one character at a time.
+ */
+ got_int = FALSE;
+ while (!got_int) {
+ if (ga_grow(&line_ga, 40) == FAIL)
+ break;
+
+ /* Get one character at a time. Don't use inchar(), it can't handle
+ * special characters. */
+ prev_char = c1;
+ c1 = vgetc();
+
+ /*
+ * Handle line editing.
+ * Previously this was left to the system, putting the terminal in
+ * cooked mode, but then CTRL-D and CTRL-T can't be used properly.
+ */
+ if (got_int) {
+ msg_putchar('\n');
+ break;
+ }
+
+ if (!escaped) {
+ /* CR typed means "enter", which is NL */
+ if (c1 == '\r')
+ c1 = '\n';
+
+ if (c1 == BS || c1 == K_BS
+ || c1 == DEL || c1 == K_DEL || c1 == K_KDEL) {
+ if (line_ga.ga_len > 0) {
+ --line_ga.ga_len;
+ goto redraw;
+ }
+ continue;
+ }
+
+ if (c1 == Ctrl_U) {
+ msg_col = startcol;
+ msg_clr_eos();
+ line_ga.ga_len = 0;
+ continue;
+ }
+
+ if (c1 == Ctrl_T) {
+ long sw = get_sw_value(curbuf);
+
+ p = (char_u *)line_ga.ga_data;
+ p[line_ga.ga_len] = NUL;
+ indent = get_indent_str(p, 8);
+ indent += sw - indent % sw;
+add_indent:
+ while (get_indent_str(p, 8) < indent) {
+ char_u *s = skipwhite(p);
+
+ ga_grow(&line_ga, 1);
+ mch_memmove(s + 1, s, line_ga.ga_len - (s - p) + 1);
+ *s = ' ';
+ ++line_ga.ga_len;
+ }
+redraw:
+ /* redraw the line */
+ msg_col = startcol;
+ vcol = 0;
+ for (p = (char_u *)line_ga.ga_data;
+ p < (char_u *)line_ga.ga_data + line_ga.ga_len; ++p) {
+ if (*p == TAB) {
+ do {
+ msg_putchar(' ');
+ } while (++vcol % 8);
+ } else {
+ msg_outtrans_len(p, 1);
+ vcol += char2cells(*p);
+ }
+ }
+ msg_clr_eos();
+ windgoto(msg_row, msg_col);
+ continue;
+ }
+
+ if (c1 == Ctrl_D) {
+ /* Delete one shiftwidth. */
+ p = (char_u *)line_ga.ga_data;
+ if (prev_char == '0' || prev_char == '^') {
+ if (prev_char == '^')
+ ex_keep_indent = TRUE;
+ indent = 0;
+ p[--line_ga.ga_len] = NUL;
+ } else {
+ p[line_ga.ga_len] = NUL;
+ indent = get_indent_str(p, 8);
+ --indent;
+ indent -= indent % get_sw_value(curbuf);
+ }
+ while (get_indent_str(p, 8) > indent) {
+ char_u *s = skipwhite(p);
+
+ mch_memmove(s - 1, s, line_ga.ga_len - (s - p) + 1);
+ --line_ga.ga_len;
+ }
+ goto add_indent;
+ }
+
+ if (c1 == Ctrl_V || c1 == Ctrl_Q) {
+ escaped = TRUE;
+ continue;
+ }
+
+ /* Ignore special key codes: mouse movement, K_IGNORE, etc. */
+ if (IS_SPECIAL(c1))
+ continue;
+ }
+
+ if (IS_SPECIAL(c1))
+ c1 = '?';
+ ((char_u *)line_ga.ga_data)[line_ga.ga_len] = c1;
+ if (c1 == '\n')
+ msg_putchar('\n');
+ else if (c1 == TAB) {
+ /* Don't use chartabsize(), 'ts' can be different */
+ do {
+ msg_putchar(' ');
+ } while (++vcol % 8);
+ } else {
+ msg_outtrans_len(
+ ((char_u *)line_ga.ga_data) + line_ga.ga_len, 1);
+ vcol += char2cells(c1);
+ }
+ ++line_ga.ga_len;
+ escaped = FALSE;
+
+ windgoto(msg_row, msg_col);
+ pend = (char_u *)(line_ga.ga_data) + line_ga.ga_len;
+
+ /* We are done when a NL is entered, but not when it comes after an
+ * odd number of backslashes, that results in a NUL. */
+ if (line_ga.ga_len > 0 && pend[-1] == '\n') {
+ int bcount = 0;
+
+ while (line_ga.ga_len - 2 >= bcount && pend[-2 - bcount] == '\\')
+ ++bcount;
+
+ if (bcount > 0) {
+ /* Halve the number of backslashes: "\NL" -> "NUL", "\\NL" ->
+ * "\NL", etc. */
+ line_ga.ga_len -= (bcount + 1) / 2;
+ pend -= (bcount + 1) / 2;
+ pend[-1] = '\n';
+ }
+
+ if ((bcount & 1) == 0) {
+ --line_ga.ga_len;
+ --pend;
+ *pend = NUL;
+ break;
+ }
+ }
+ }
+
+ --no_mapping;
+ --allow_keys;
+
+ /* make following messages go to the next line */
+ msg_didout = FALSE;
+ msg_col = 0;
+ if (msg_row < Rows - 1)
+ ++msg_row;
+ emsg_on_display = FALSE; /* don't want ui_delay() */
+
+ if (got_int)
+ ga_clear(&line_ga);
+
+ return (char_u *)line_ga.ga_data;
+}
+
+# if defined(MCH_CURSOR_SHAPE) || defined(FEAT_GUI) \
+ || defined(FEAT_MOUSESHAPE) || defined(PROTO)
+/*
+ * Return TRUE if ccline.overstrike is on.
+ */
+int cmdline_overstrike() {
+ return ccline.overstrike;
+}
+
+/*
+ * Return TRUE if the cursor is at the end of the cmdline.
+ */
+int cmdline_at_end() {
+ return ccline.cmdpos >= ccline.cmdlen;
+}
+
+#endif
+
+
+
+/*
+ * Allocate a new command line buffer.
+ * Assigns the new buffer to ccline.cmdbuff and ccline.cmdbufflen.
+ * Returns the new value of ccline.cmdbuff and ccline.cmdbufflen.
+ */
+static void alloc_cmdbuff(len)
+int len;
+{
+ /*
+ * give some extra space to avoid having to allocate all the time
+ */
+ if (len < 80)
+ len = 100;
+ else
+ len += 20;
+
+ ccline.cmdbuff = alloc(len); /* caller should check for out-of-memory */
+ ccline.cmdbufflen = len;
+}
+
+/*
+ * Re-allocate the command line to length len + something extra.
+ * return FAIL for failure, OK otherwise
+ */
+static int realloc_cmdbuff(len)
+int len;
+{
+ char_u *p;
+
+ if (len < ccline.cmdbufflen)
+ return OK; /* no need to resize */
+
+ p = ccline.cmdbuff;
+ alloc_cmdbuff(len); /* will get some more */
+ if (ccline.cmdbuff == NULL) { /* out of memory */
+ ccline.cmdbuff = p; /* keep the old one */
+ return FAIL;
+ }
+ /* There isn't always a NUL after the command, but it may need to be
+ * there, thus copy up to the NUL and add a NUL. */
+ mch_memmove(ccline.cmdbuff, p, (size_t)ccline.cmdlen);
+ ccline.cmdbuff[ccline.cmdlen] = NUL;
+ vim_free(p);
+
+ if (ccline.xpc != NULL
+ && ccline.xpc->xp_pattern != NULL
+ && ccline.xpc->xp_context != EXPAND_NOTHING
+ && ccline.xpc->xp_context != EXPAND_UNSUCCESSFUL) {
+ int i = (int)(ccline.xpc->xp_pattern - p);
+
+ /* If xp_pattern points inside the old cmdbuff it needs to be adjusted
+ * to point into the newly allocated memory. */
+ if (i >= 0 && i <= ccline.cmdlen)
+ ccline.xpc->xp_pattern = ccline.cmdbuff + i;
+ }
+
+ return OK;
+}
+
+static char_u *arshape_buf = NULL;
+
+# if defined(EXITFREE) || defined(PROTO)
+void free_cmdline_buf() {
+ vim_free(arshape_buf);
+}
+
+# endif
+
+/*
+ * Draw part of the cmdline at the current cursor position. But draw stars
+ * when cmdline_star is TRUE.
+ */
+static void draw_cmdline(start, len)
+int start;
+int len;
+{
+ int i;
+
+ if (cmdline_star > 0)
+ for (i = 0; i < len; ++i) {
+ msg_putchar('*');
+ 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;
+ int mb_l;
+ int pc, pc1 = 0;
+ int prev_c = 0;
+ int prev_c1 = 0;
+ int u8c;
+ int u8cc[MAX_MCO];
+ int nc = 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. */
+ vim_free(arshape_buf);
+ buflen = len * 2 + 2;
+ arshape_buf = alloc(buflen);
+ if (arshape_buf == NULL)
+ return; /* out of memory */
+ }
+
+ if (utf_iscomposing(utf_ptr2char(ccline.cmdbuff + start))) {
+ /* 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);
+ if (ARABIC_CHAR(u8c)) {
+ /* Do Arabic shaping. */
+ if (cmdmsg_rl) {
+ /* displaying from right to left */
+ pc = prev_c;
+ pc1 = prev_c1;
+ prev_c1 = u8cc[0];
+ if (j + mb_l >= start + len)
+ nc = NUL;
+ else
+ nc = utf_ptr2char(p + mb_l);
+ } else {
+ /* displaying from left to right */
+ if (j + mb_l >= start + len)
+ pc = NUL;
+ else {
+ int pcc[MAX_MCO];
+
+ pc = utfc_ptr2char_len(p + mb_l, pcc,
+ start + len - j - mb_l);
+ pc1 = pcc[0];
+ }
+ nc = prev_c;
+ }
+ prev_c = u8c;
+
+ u8c = arabic_shape(u8c, NULL, &u8cc[0], pc, pc1, nc);
+
+ newlen += (*mb_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);
+ }
+ } else {
+ prev_c = u8c;
+ mch_memmove(arshape_buf + newlen, p, mb_l);
+ newlen += mb_l;
+ }
+ }
+
+ msg_outtrans_len(arshape_buf, newlen);
+ } else
+ msg_outtrans_len(ccline.cmdbuff + start, len);
+}
+
+/*
+ * Put a character on the command line. Shifts the following text to the
+ * right when "shift" is TRUE. Used for CTRL-V, CTRL-K, etc.
+ * "c" must be printable (fit in one display cell)!
+ */
+void putcmdline(c, shift)
+int c;
+int shift;
+{
+ 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;
+ cursorcmd();
+}
+
+/*
+ * Undo a putcmdline(c, FALSE).
+ */
+void unputcmdline() {
+ if (cmd_silent)
+ return;
+ msg_no_more = TRUE;
+ if (ccline.cmdlen == ccline.cmdpos)
+ 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;
+ cursorcmd();
+}
+
+/*
+ * Put the given string, of the given length, onto the command line.
+ * If len is -1, then STRLEN() is used to calculate the length.
+ * If 'redraw' is TRUE then the new part of the command line, and the remaining
+ * part will be redrawn, otherwise it will not. If this function is called
+ * twice in a row, then 'redraw' should be FALSE and redrawcmd() should be
+ * called afterwards.
+ */
+int put_on_cmdline(str, len, redraw)
+char_u *str;
+int len;
+int redraw;
+{
+ int retval;
+ int i;
+ int m;
+ int c;
+
+ if (len < 0)
+ len = (int)STRLEN(str);
+
+ /* Check if ccline.cmdbuff needs to be longer */
+ if (ccline.cmdlen + len + 1 >= ccline.cmdbufflen)
+ retval = realloc_cmdbuff(ccline.cmdlen + len + 1);
+ else
+ retval = OK;
+ if (retval == OK) {
+ if (!ccline.overstrike) {
+ mch_memmove(ccline.cmdbuff + ccline.cmdpos + len,
+ ccline.cmdbuff + ccline.cmdpos,
+ (size_t)(ccline.cmdlen - ccline.cmdpos));
+ ccline.cmdlen += len;
+ } else {
+ if (has_mbyte) {
+ /* Count nr of characters in the new string. */
+ m = 0;
+ for (i = 0; i < len; i += (*mb_ptr2len)(str + i))
+ ++m;
+ /* Count nr of bytes in cmdline that are overwritten by these
+ * characters. */
+ for (i = ccline.cmdpos; i < ccline.cmdlen && m > 0;
+ i += (*mb_ptr2len)(ccline.cmdbuff + i))
+ --m;
+ if (i < ccline.cmdlen) {
+ mch_memmove(ccline.cmdbuff + ccline.cmdpos + len,
+ ccline.cmdbuff + i, (size_t)(ccline.cmdlen - i));
+ ccline.cmdlen += ccline.cmdpos + len - i;
+ } else
+ ccline.cmdlen = ccline.cmdpos + len;
+ } else if (ccline.cmdpos + len > ccline.cmdlen)
+ ccline.cmdlen = ccline.cmdpos + len;
+ }
+ mch_memmove(ccline.cmdbuff + ccline.cmdpos, str, (size_t)len);
+ ccline.cmdbuff[ccline.cmdlen] = NUL;
+
+ if (enc_utf8) {
+ /* When the inserted text starts with a composing character,
+ * backup to the character before it. There could be two of them.
+ */
+ 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;
+ 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)) {
+ ccline.cmdpos -= i;
+ len += i;
+ } else
+ i = 0;
+ }
+ if (i != 0) {
+ /* Also backup the cursor position. */
+ i = ptr2cells(ccline.cmdbuff + ccline.cmdpos);
+ ccline.cmdspos -= i;
+ msg_col -= i;
+ if (msg_col < 0) {
+ msg_col += Columns;
+ --msg_row;
+ }
+ }
+ }
+
+ if (redraw && !cmd_silent) {
+ msg_no_more = TRUE;
+ i = cmdline_row;
+ cursorcmd();
+ draw_cmdline(ccline.cmdpos, ccline.cmdlen - ccline.cmdpos);
+ /* Avoid clearing the rest of the line too often. */
+ if (cmdline_row != i || ccline.overstrike)
+ msg_clr_eos();
+ msg_no_more = FALSE;
+ }
+ /*
+ * If we are in Farsi command mode, the character input must be in
+ * Insert mode. So do not advance the cmdpos.
+ */
+ if (!cmd_fkmap) {
+ if (KeyTyped) {
+ m = Columns * Rows;
+ if (m < 0) /* overflow, Columns or Rows at weird value */
+ m = MAXCOL;
+ } else
+ m = MAXCOL;
+ for (i = 0; i < len; ++i) {
+ c = cmdline_charsize(ccline.cmdpos);
+ /* count ">" for a double-wide char that doesn't fit. */
+ if (has_mbyte)
+ correct_cmdspos(ccline.cmdpos, c);
+ /* Stop cursor at the end of the screen, but do increment the
+ * insert position, so that entering a very long command
+ * works, even though you can't see it. */
+ if (ccline.cmdspos + c < m)
+ ccline.cmdspos += c;
+ if (has_mbyte) {
+ c = (*mb_ptr2len)(ccline.cmdbuff + ccline.cmdpos) - 1;
+ if (c > len - i - 1)
+ c = len - i - 1;
+ ccline.cmdpos += c;
+ i += c;
+ }
+ ++ccline.cmdpos;
+ }
+ }
+ }
+ if (redraw)
+ msg_check();
+ return retval;
+}
+
+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
+ * available globally in prev_ccline.
+ */
+static void save_cmdline(ccp)
+struct cmdline_info *ccp;
+{
+ if (!prev_ccline_used) {
+ vim_memset(&prev_ccline, 0, sizeof(struct cmdline_info));
+ prev_ccline_used = TRUE;
+ }
+ *ccp = prev_ccline;
+ prev_ccline = ccline;
+ ccline.cmdbuff = NULL;
+ ccline.cmdprompt = NULL;
+ ccline.xpc = NULL;
+}
+
+/*
+ * Restore ccline after it has been saved with save_cmdline().
+ */
+static void restore_cmdline(ccp)
+struct cmdline_info *ccp;
+{
+ ccline = prev_ccline;
+ prev_ccline = *ccp;
+}
+
+/*
+ * Save the command line into allocated memory. Returns a pointer to be
+ * passed to restore_cmdline_alloc() later.
+ * Returns NULL when failed.
+ */
+char_u * save_cmdline_alloc() {
+ struct cmdline_info *p;
+
+ p = (struct cmdline_info *)alloc((unsigned)sizeof(struct cmdline_info));
+ if (p != NULL)
+ save_cmdline(p);
+ return (char_u *)p;
+}
+
+/*
+ * Restore the command line from the return value of save_cmdline_alloc().
+ */
+void restore_cmdline_alloc(p)
+char_u *p;
+{
+ if (p != NULL) {
+ restore_cmdline((struct cmdline_info *)p);
+ vim_free(p);
+ }
+}
+
+/*
+ * paste a yank register into the command line.
+ * used by CTRL-R command in command-line mode
+ * insert_reg() can't be used here, because special characters from the
+ * register contents will be interpreted as commands.
+ *
+ * return FAIL for failure, OK otherwise
+ */
+static int cmdline_paste(regname, literally, remcr)
+int regname;
+int literally; /* Insert text literally instead of "as typed" */
+int remcr; /* remove trailing CR */
+{
+ long i;
+ char_u *arg;
+ char_u *p;
+ int 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))
+ return FAIL;
+
+ /* A register containing CTRL-R can cause an endless loop. Allow using
+ * CTRL-C to break the loop. */
+ line_breakcheck();
+ if (got_int)
+ return FAIL;
+
+
+ /* 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;
+ restore_cmdline(&save_ccline);
+
+ if (i) {
+ /* Got the value of a special register in "arg". */
+ if (arg == NULL)
+ return FAIL;
+
+ /* When 'incsearch' is set and CTRL-R CTRL-W used: skip the duplicate
+ * part of the word. */
+ p = arg;
+ if (p_is && regname == Ctrl_W) {
+ char_u *w;
+ int len;
+
+ /* 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 = (int)((ccline.cmdbuff + ccline.cmdpos) - w);
+ if (p_ic ? STRNICMP(w, arg, len) == 0 : STRNCMP(w, arg, len) == 0)
+ p += len;
+ }
+
+ cmdline_paste_str(p, literally);
+ if (allocated)
+ vim_free(arg);
+ return OK;
+ }
+
+ return cmdline_paste_reg(regname, literally, remcr);
+}
+
+/*
+ * Put a string on the command line.
+ * When "literally" is TRUE, insert literally.
+ * When "literally" is FALSE, insert as typed, but don't leave the command
+ * line.
+ */
+void cmdline_paste_str(s, literally)
+char_u *s;
+int literally;
+{
+ int c, cv;
+
+ if (literally)
+ put_on_cmdline(s, -1, TRUE);
+ else
+ while (*s != NUL) {
+ cv = *s;
+ if (cv == Ctrl_V && s[1])
+ ++s;
+ if (has_mbyte)
+ c = mb_cptr2char_adv(&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))
+ stuffcharReadbuff(Ctrl_V);
+ stuffcharReadbuff(c);
+ }
+}
+
+/*
+ * Delete characters on the command line, from "from" to the current
+ * position.
+ */
+static void cmdline_del(from)
+int from;
+{
+ mch_memmove(ccline.cmdbuff + from, ccline.cmdbuff + ccline.cmdpos,
+ (size_t)(ccline.cmdlen - ccline.cmdpos + 1));
+ ccline.cmdlen -= ccline.cmdpos - from;
+ ccline.cmdpos = from;
+}
+
+/*
+ * this function is called when the screen size changes and with incremental
+ * search
+ */
+void redrawcmdline() {
+ if (cmd_silent)
+ return;
+ need_wait_return = FALSE;
+ compute_cmdrow();
+ redrawcmd();
+ cursorcmd();
+}
+
+static void redrawcmdprompt() {
+ int i;
+
+ if (cmd_silent)
+ return;
+ if (ccline.cmdfirstc != NUL)
+ msg_putchar(ccline.cmdfirstc);
+ if (ccline.cmdprompt != NULL) {
+ msg_puts_attr(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)
+ msg_putchar(' ');
+}
+
+/*
+ * Redraw what is currently on the command line.
+ */
+void redrawcmd() {
+ if (cmd_silent)
+ return;
+
+ /* when 'incsearch' is set there may be no command line while redrawing */
+ if (ccline.cmdbuff == NULL) {
+ windgoto(cmdline_row, 0);
+ msg_clr_eos();
+ return;
+ }
+
+ msg_start();
+ redrawcmdprompt();
+
+ /* Don't use more prompt, truncate the cmdline if it doesn't fit. */
+ msg_no_more = TRUE;
+ draw_cmdline(0, ccline.cmdlen);
+ msg_clr_eos();
+ msg_no_more = FALSE;
+
+ set_cmdspos_cursor();
+
+ /*
+ * An emsg() before may have set msg_scroll. This is used in normal mode,
+ * in cmdline mode we can reset them now.
+ */
+ msg_scroll = FALSE; /* next message overwrites cmdline */
+
+ /* Typing ':' at the more prompt may set skip_redraw. We don't want this
+ * in cmdline mode */
+ skip_redraw = FALSE;
+}
+
+void compute_cmdrow() {
+ if (exmode_active || msg_scrolled != 0)
+ cmdline_row = Rows - 1;
+ else
+ cmdline_row = W_WINROW(lastwin) + lastwin->w_height
+ + W_STATUS_HEIGHT(lastwin);
+}
+
+static void cursorcmd() {
+ if (cmd_silent)
+ return;
+
+ if (cmdmsg_rl) {
+ msg_row = cmdline_row + (ccline.cmdspos / (int)(Columns - 1));
+ msg_col = (int)Columns - (ccline.cmdspos % (int)(Columns - 1)) - 1;
+ if (msg_row <= 0)
+ msg_row = Rows - 1;
+ } else {
+ msg_row = cmdline_row + (ccline.cmdspos / (int)Columns);
+ msg_col = ccline.cmdspos % (int)Columns;
+ if (msg_row >= Rows)
+ msg_row = Rows - 1;
+ }
+
+ windgoto(msg_row, msg_col);
+}
+
+void gotocmdline(clr)
+int clr;
+{
+ msg_start();
+ if (cmdmsg_rl)
+ msg_col = Columns - 1;
+ else
+ msg_col = 0; /* always start in column 0 */
+ if (clr) /* clear the bottom line(s) */
+ msg_clr_eos(); /* will reset clear_cmdline */
+ windgoto(cmdline_row, 0);
+}
+
+/*
+ * Check the word in front of the cursor for an abbreviation.
+ * Called when the non-id character "c" has been entered.
+ * When an abbreviation is recognized it is removed from the text with
+ * backspaces and the replacement string is inserted, followed by "c".
+ */
+static int ccheck_abbr(c)
+int c;
+{
+ if (p_paste || no_abbr) /* no abbreviations or in paste mode */
+ return FALSE;
+
+ return check_abbr(c, ccline.cmdbuff, ccline.cmdpos, 0);
+}
+
+static int sort_func_compare(s1, s2)
+const void *s1;
+const void *s2;
+{
+ char_u *p1 = *(char_u **)s1;
+ char_u *p2 = *(char_u **)s2;
+
+ if (*p1 != '<' && *p2 == '<') return -1;
+ if (*p1 == '<' && *p2 != '<') return 1;
+ return STRCMP(p1, p2);
+}
+
+/*
+ * Return FAIL if this is not an appropriate context in which to do
+ * completion of anything, return OK if it is (even if there are no matches).
+ * For the caller, this means that the character is just passed through like a
+ * normal character (instead of being expanded). This allows :s/^I^D etc.
+ */
+static int nextwild(xp, type, options, escape)
+expand_T *xp;
+int type;
+int options; /* extra options for ExpandOne() */
+int escape; /* if TRUE, escape the returned matches */
+{
+ int i, j;
+ char_u *p1;
+ char_u *p2;
+ int difflen;
+ int v;
+
+ if (xp->xp_numfiles == -1) {
+ set_expand_context(xp);
+ cmd_showtail = expand_showtail(xp);
+ }
+
+ if (xp->xp_context == EXPAND_UNSUCCESSFUL) {
+ beep_flush();
+ return OK; /* Something illegal on command line */
+ }
+ if (xp->xp_context == EXPAND_NOTHING) {
+ /* Caller can use the character as a normal char instead */
+ return FAIL;
+ }
+
+ MSG_PUTS("..."); /* show that we are busy */
+ out_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.
+ */
+ 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);
+ vim_free(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) {
+ vim_free(p2);
+ p2 = NULL;
+ }
+ }
+ }
+ }
+
+ if (p2 != NULL && !got_int) {
+ difflen = (int)STRLEN(p2) - xp->xp_pattern_len;
+ if (ccline.cmdlen + difflen + 4 > ccline.cmdbufflen) {
+ v = realloc_cmdbuff(ccline.cmdlen + difflen + 4);
+ xp->xp_pattern = ccline.cmdbuff + i;
+ } else
+ v = OK;
+ if (v == OK) {
+ mch_memmove(&ccline.cmdbuff[ccline.cmdpos + difflen],
+ &ccline.cmdbuff[ccline.cmdpos],
+ (size_t)(ccline.cmdlen - ccline.cmdpos + 1));
+ mch_memmove(&ccline.cmdbuff[i], p2, STRLEN(p2));
+ ccline.cmdlen += difflen;
+ ccline.cmdpos += difflen;
+ }
+ }
+ vim_free(p2);
+
+ redrawcmd();
+ cursorcmd();
+
+ /* When expanding a ":map" command and no matches are found, assume that
+ * the key is supposed to be inserted literally */
+ if (xp->xp_context == EXPAND_MAPPINGS && p2 == NULL)
+ return FAIL;
+
+ if (xp->xp_numfiles <= 0 && p2 == NULL)
+ beep_flush();
+ else if (xp->xp_numfiles == 1)
+ /* free expanded pattern */
+ (void)ExpandOne(xp, NULL, NULL, 0, WILD_FREE);
+
+ return OK;
+}
+
+/*
+ * Do wildcard expansion on the string 'str'.
+ * Chars that should not be expanded must be preceded with a backslash.
+ * Return a pointer to allocated memory containing the new string.
+ * Return NULL for failure.
+ *
+ * "orig" is the originally expanded string, copied to allocated memory. It
+ * should either be kept in orig_save or freed. When "mode" is WILD_NEXT or
+ * WILD_PREV "orig" should be NULL.
+ *
+ * Results are cached in xp->xp_files and xp->xp_numfiles, except when "mode"
+ * is WILD_EXPAND_FREE or WILD_ALL.
+ *
+ * mode = WILD_FREE: just free previously expanded matches
+ * mode = WILD_EXPAND_FREE: normal expansion, do not keep matches
+ * mode = WILD_EXPAND_KEEP: normal expansion, keep matches
+ * mode = WILD_NEXT: use next match in multiple match, wrap to first
+ * mode = WILD_PREV: use previous match in multiple match, wrap to first
+ * mode = WILD_ALL: return all matches concatenated
+ * mode = WILD_LONGEST: return longest matched part
+ * mode = WILD_ALL_KEEP: get all matches, keep matches
+ *
+ * options = WILD_LIST_NOTFOUND: list entries without a match
+ * options = WILD_HOME_REPLACE: do home_replace() for buffer names
+ * options = WILD_USE_NL: Use '\n' for WILD_ALL
+ * options = WILD_NO_BEEP: Don't beep for multiple matches
+ * options = WILD_ADD_SLASH: add a slash after directory names
+ * options = WILD_KEEP_ALL: don't remove 'wildignore' entries
+ * options = WILD_SILENT: don't print warning messages
+ * options = WILD_ESCAPE: put backslash before special chars
+ * options = WILD_ICASE: ignore case for files
+ *
+ * The variables xp->xp_context and xp->xp_backslash must have been set!
+ */
+char_u * ExpandOne(xp, str, orig, options, mode)
+expand_T *xp;
+char_u *str;
+char_u *orig; /* allocated copy of original of expanded string */
+int options;
+int mode;
+{
+ char_u *ss = NULL;
+ static int findex;
+ static char_u *orig_save = NULL; /* kept value of orig */
+ int orig_saved = FALSE;
+ int i;
+ long_u len;
+ int non_suf_match; /* number without matching suffix */
+
+ /*
+ * first handle the case of using an old match
+ */
+ if (mode == WILD_NEXT || mode == WILD_PREV) {
+ if (xp->xp_numfiles > 0) {
+ if (mode == WILD_PREV) {
+ if (findex == -1)
+ findex = xp->xp_numfiles;
+ --findex;
+ } else /* mode == WILD_NEXT */
+ ++findex;
+
+ /*
+ * When wrapping around, return the original string, set findex to
+ * -1.
+ */
+ if (findex < 0) {
+ if (orig_save == NULL)
+ findex = xp->xp_numfiles - 1;
+ else
+ findex = -1;
+ }
+ if (findex >= xp->xp_numfiles) {
+ if (orig_save == NULL)
+ findex = 0;
+ else
+ findex = -1;
+ }
+ if (p_wmnu)
+ 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;
+ }
+
+ /* free old names */
+ if (xp->xp_numfiles != -1 && mode != WILD_ALL && mode != WILD_LONGEST) {
+ FreeWild(xp->xp_numfiles, xp->xp_files);
+ xp->xp_numfiles = -1;
+ vim_free(orig_save);
+ orig_save = NULL;
+ }
+ findex = 0;
+
+ if (mode == WILD_FREE) /* only release file name */
+ return NULL;
+
+ if (xp->xp_numfiles == -1) {
+ vim_free(orig_save);
+ orig_save = orig;
+ orig_saved = TRUE;
+
+ /*
+ * Do the expansion.
+ */
+ if (ExpandFromContext(xp, str, &xp->xp_numfiles, &xp->xp_files,
+ options) == FAIL) {
+#ifdef FNAME_ILLEGAL
+ /* Illegal file name has been silently skipped. But when there
+ * are wildcards, the real problem is that there was no match,
+ * causing the pattern to be added, which has illegal characters.
+ */
+ if (!(options & WILD_SILENT) && (options & WILD_LIST_NOTFOUND))
+ EMSG2(_(e_nomatch2), str);
+#endif
+ } else if (xp->xp_numfiles == 0) {
+ if (!(options & WILD_SILENT))
+ EMSG2(_(e_nomatch2), str);
+ } else {
+ /* Escape the matches for use on the command line. */
+ ExpandEscape(xp, str, xp->xp_numfiles, xp->xp_files, options);
+
+ /*
+ * Check for matching suffixes in file names.
+ */
+ if (mode != WILD_ALL && mode != WILD_ALL_KEEP
+ && mode != WILD_LONGEST) {
+ if (xp->xp_numfiles)
+ non_suf_match = xp->xp_numfiles;
+ else
+ non_suf_match = 1;
+ if ((xp->xp_context == EXPAND_FILES
+ || xp->xp_context == EXPAND_DIRECTORIES)
+ && xp->xp_numfiles > 1) {
+ /*
+ * More than one match; check suffix.
+ * The files will have been sorted on matching suffix in
+ * expand_wildcards, only need to check the first two.
+ */
+ non_suf_match = 0;
+ for (i = 0; i < 2; ++i)
+ if (match_suffix(xp->xp_files[i]))
+ ++non_suf_match;
+ }
+ if (non_suf_match != 1) {
+ /* Can we ever get here unless it's while expanding
+ * interactively? If not, we can get rid of this all
+ * together. Don't really want to wait for this message
+ * (and possibly have to hit return to continue!).
+ */
+ if (!(options & WILD_SILENT))
+ EMSG(_(e_toomany));
+ else if (!(options & WILD_NO_BEEP))
+ beep_flush();
+ }
+ if (!(non_suf_match != 1 && mode == WILD_EXPAND_FREE))
+ ss = vim_strsave(xp->xp_files[0]);
+ }
+ }
+ }
+
+ /* Find longest common part */
+ if (mode == WILD_LONGEST && xp->xp_numfiles > 0) {
+ for (len = 0; xp->xp_files[0][len]; ++len) {
+ for (i = 0; i < xp->xp_numfiles; ++i) {
+ if (p_fic && (xp->xp_context == EXPAND_DIRECTORIES
+ || xp->xp_context == EXPAND_FILES
+ || xp->xp_context == EXPAND_SHELLCMD
+ || xp->xp_context == EXPAND_BUFFERS)) {
+ if (TOLOWER_LOC(xp->xp_files[i][len]) !=
+ TOLOWER_LOC(xp->xp_files[0][len]))
+ break;
+ } else if (xp->xp_files[i][len] != xp->xp_files[0][len])
+ break;
+ }
+ if (i < xp->xp_numfiles) {
+ if (!(options & WILD_NO_BEEP))
+ vim_beep();
+ break;
+ }
+ }
+ ss = alloc((unsigned)len + 1);
+ if (ss)
+ vim_strncpy(ss, xp->xp_files[0], (size_t)len);
+ findex = -1; /* next p_wc gets first one */
+ }
+
+ /* Concatenate all matching names */
+ if (mode == WILD_ALL && xp->xp_numfiles > 0) {
+ len = 0;
+ for (i = 0; i < xp->xp_numfiles; ++i)
+ len += (long_u)STRLEN(xp->xp_files[i]) + 1;
+ ss = lalloc(len, TRUE);
+ if (ss != NULL) {
+ *ss = NUL;
+ for (i = 0; i < xp->xp_numfiles; ++i) {
+ STRCAT(ss, xp->xp_files[i]);
+ if (i != xp->xp_numfiles - 1)
+ STRCAT(ss, (options & WILD_USE_NL) ? "\n" : " ");
+ }
+ }
+ }
+
+ if (mode == WILD_EXPAND_FREE || mode == WILD_ALL)
+ ExpandCleanup(xp);
+
+ /* Free "orig" if it wasn't stored in "orig_save". */
+ if (!orig_saved)
+ vim_free(orig);
+
+ return ss;
+}
+
+/*
+ * Prepare an expand structure for use.
+ */
+void ExpandInit(xp)
+expand_T *xp;
+{
+ xp->xp_pattern = NULL;
+ xp->xp_pattern_len = 0;
+ xp->xp_backslash = XP_BS_NONE;
+#ifndef BACKSLASH_IN_FILENAME
+ xp->xp_shell = FALSE;
+#endif
+ xp->xp_numfiles = -1;
+ xp->xp_files = NULL;
+ xp->xp_arg = NULL;
+ xp->xp_line = NULL;
+}
+
+/*
+ * Cleanup an expand structure after use.
+ */
+void ExpandCleanup(xp)
+expand_T *xp;
+{
+ if (xp->xp_numfiles >= 0) {
+ FreeWild(xp->xp_numfiles, xp->xp_files);
+ xp->xp_numfiles = -1;
+ }
+}
+
+void ExpandEscape(xp, str, numfiles, files, options)
+expand_T *xp;
+char_u *str;
+int numfiles;
+char_u **files;
+int options;
+{
+ int i;
+ char_u *p;
+
+ /*
+ * May change home directory back to "~"
+ */
+ if (options & WILD_HOME_REPLACE)
+ tilde_replace(str, numfiles, files);
+
+ if (options & WILD_ESCAPE) {
+ if (xp->xp_context == EXPAND_FILES
+ || xp->xp_context == EXPAND_FILES_IN_PATH
+ || xp->xp_context == EXPAND_SHELLCMD
+ || xp->xp_context == EXPAND_BUFFERS
+ || xp->xp_context == EXPAND_DIRECTORIES) {
+ /*
+ * Insert a backslash into a file name before a space, \, %, #
+ * and wildmatch characters, except '~'.
+ */
+ for (i = 0; i < numfiles; ++i) {
+ /* for ":set path=" we need to escape spaces twice */
+ if (xp->xp_backslash == XP_BS_THREE) {
+ p = vim_strsave_escaped(files[i], (char_u *)" ");
+ if (p != NULL) {
+ vim_free(files[i]);
+ files[i] = p;
+#if defined(BACKSLASH_IN_FILENAME)
+ p = vim_strsave_escaped(files[i], (char_u *)" ");
+ if (p != NULL) {
+ vim_free(files[i]);
+ files[i] = p;
+ }
+#endif
+ }
+ }
+#ifdef BACKSLASH_IN_FILENAME
+ p = vim_strsave_fnameescape(files[i], FALSE);
+#else
+ p = vim_strsave_fnameescape(files[i], xp->xp_shell);
+#endif
+ if (p != NULL) {
+ vim_free(files[i]);
+ files[i] = p;
+ }
+
+ /* If 'str' starts with "\~", replace "~" at start of
+ * files[i] with "\~". */
+ if (str[0] == '\\' && str[1] == '~' && files[i][0] == '~')
+ escape_fname(&files[i]);
+ }
+ xp->xp_backslash = XP_BS_NONE;
+
+ /* If the first file starts with a '+' escape it. Otherwise it
+ * could be seen as "+cmd". */
+ if (*files[0] == '+')
+ escape_fname(&files[0]);
+ } else if (xp->xp_context == EXPAND_TAGS) {
+ /*
+ * Insert a backslash before characters in a tag name that
+ * would terminate the ":tag" command.
+ */
+ for (i = 0; i < numfiles; ++i) {
+ p = vim_strsave_escaped(files[i], (char_u *)"\\|\"");
+ if (p != NULL) {
+ vim_free(files[i]);
+ files[i] = p;
+ }
+ }
+ }
+ }
+}
+
+/*
+ * 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(fname, shell)
+char_u *fname;
+int shell;
+{
+ char_u *p;
+#ifdef BACKSLASH_IN_FILENAME
+ char_u buf[20];
+ 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;
+ buf[j] = NUL;
+ p = vim_strsave_escaped(fname, buf);
+#else
+ p = vim_strsave_escaped(fname, shell ? SHELL_ESC_CHARS : PATH_ESC_CHARS);
+ if (shell && csh_like_shell() && p != NULL) {
+ char_u *s;
+
+ /* For csh and similar shells need to put two backslashes before '!'.
+ * One is taken by Vim, one by the shell. */
+ s = vim_strsave_escaped(p, (char_u *)"!");
+ vim_free(p);
+ p = s;
+ }
+#endif
+
+ /* '>' and '+' are special at the start of some commands, e.g. ":edit" and
+ * ":write". "cd -" has a special meaning. */
+ if (p != NULL && (*p == '>' || *p == '+' || (*p == '-' && p[1] == NUL)))
+ escape_fname(&p);
+
+ return p;
+}
+
+/*
+ * Put a backslash before the file name in "pp", which is in allocated memory.
+ */
+static void escape_fname(pp)
+char_u **pp;
+{
+ char_u *p;
+
+ p = alloc((unsigned)(STRLEN(*pp) + 2));
+ if (p != NULL) {
+ p[0] = '\\';
+ STRCPY(p + 1, *pp);
+ vim_free(*pp);
+ *pp = p;
+ }
+}
+
+/*
+ * For each file name in files[num_files]:
+ * If 'orig_pat' starts with "~/", replace the home directory with "~".
+ */
+void tilde_replace(orig_pat, num_files, files)
+char_u *orig_pat;
+int num_files;
+char_u **files;
+{
+ int i;
+ char_u *p;
+
+ if (orig_pat[0] == '~' && vim_ispathsep(orig_pat[1])) {
+ for (i = 0; i < num_files; ++i) {
+ p = home_replace_save(NULL, files[i]);
+ if (p != NULL) {
+ vim_free(files[i]);
+ files[i] = p;
+ }
+ }
+ }
+}
+
+/*
+ * Show all matches for completion on the command line.
+ * Returns EXPAND_NOTHING when the character that triggered expansion should
+ * be inserted like a normal character.
+ */
+static int showmatches(xp, wildmenu)
+expand_T *xp;
+int wildmenu UNUSED;
+{
+#define L_SHOWFILE(m) (showtail ? sm_gettail(files_found[m]) : files_found[m])
+ int num_files;
+ char_u **files_found;
+ int i, j, k;
+ int maxlen;
+ int lines;
+ int columns;
+ char_u *p;
+ int lastlen;
+ int attr;
+ int showtail;
+
+ if (xp->xp_numfiles == -1) {
+ set_expand_context(xp);
+ i = expand_cmdline(xp, ccline.cmdbuff, ccline.cmdpos,
+ &num_files, &files_found);
+ showtail = expand_showtail(xp);
+ if (i != EXPAND_OK)
+ return i;
+
+ } else {
+ num_files = xp->xp_numfiles;
+ files_found = xp->xp_files;
+ showtail = cmd_showtail;
+ }
+
+ if (!wildmenu) {
+ msg_didany = FALSE; /* lines_left will be set */
+ msg_start(); /* prepare for paging */
+ msg_putchar('\n');
+ out_flush();
+ cmdline_row = msg_row;
+ msg_didany = FALSE; /* lines_left will be set again */
+ 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 */
+ maxlen = 0;
+ for (i = 0; i < num_files; ++i) {
+ if (!showtail && (xp->xp_context == EXPAND_FILES
+ || xp->xp_context == EXPAND_SHELLCMD
+ || xp->xp_context == EXPAND_BUFFERS)) {
+ home_replace(NULL, files_found[i], NameBuff, MAXPATHL, TRUE);
+ j = vim_strsize(NameBuff);
+ } else
+ j = vim_strsize(L_SHOWFILE(i));
+ if (j > maxlen)
+ maxlen = j;
+ }
+
+ if (xp->xp_context == EXPAND_TAGS_LISTFILES)
+ lines = num_files;
+ else {
+ /* compute the number of columns and lines for the listing */
+ maxlen += 2; /* two spaces between file names */
+ columns = ((int)Columns + 2) / maxlen;
+ if (columns < 1)
+ columns = 1;
+ lines = (num_files + columns - 1) / columns;
+ }
+
+ 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_clr_eos();
+ msg_advance(maxlen - 3);
+ MSG_PUTS_ATTR(_(" kind file\n"), hl_attr(HLF_T));
+ }
+
+ /* list the files line by line */
+ for (i = 0; i < lines; ++i) {
+ 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));
+ p = files_found[k] + STRLEN(files_found[k]) + 1;
+ msg_advance(maxlen + 1);
+ msg_puts(p);
+ msg_advance(maxlen + 3);
+ msg_puts_long_attr(p + 2, hl_attr(HLF_D));
+ break;
+ }
+ for (j = maxlen - lastlen; --j >= 0; )
+ msg_putchar(' ');
+ if (xp->xp_context == EXPAND_FILES
+ || xp->xp_context == EXPAND_SHELLCMD
+ || xp->xp_context == EXPAND_BUFFERS) {
+ /* highlight directories */
+ if (xp->xp_numfiles != -1) {
+ char_u *halved_slash;
+ char_u *exp_path;
+
+ /* Expansion was done before and special characters
+ * were escaped, need to halve backslashes. Also
+ * $HOME has been replaced with ~/. */
+ exp_path = expand_env_save_opt(files_found[k], TRUE);
+ halved_slash = backslash_halve_save(
+ exp_path != NULL ? exp_path : files_found[k]);
+ j = mch_isdir(halved_slash != NULL ? halved_slash
+ : files_found[k]);
+ vim_free(exp_path);
+ vim_free(halved_slash);
+ } else
+ /* Expansion was done here, file names are literal. */
+ j = mch_isdir(files_found[k]);
+ if (showtail)
+ p = L_SHOWFILE(k);
+ else {
+ home_replace(NULL, files_found[k], NameBuff, MAXPATHL,
+ TRUE);
+ p = NameBuff;
+ }
+ } else {
+ j = FALSE;
+ p = L_SHOWFILE(k);
+ }
+ lastlen = msg_outtrans_attr(p, j ? attr : 0);
+ }
+ if (msg_col > 0) { /* when not wrapped around */
+ msg_clr_eos();
+ msg_putchar('\n');
+ }
+ out_flush(); /* show one line at a time */
+ if (got_int) {
+ got_int = FALSE;
+ break;
+ }
+ }
+
+ /*
+ * we redraw the command below the lines that we have just listed
+ * This is a bit tricky, but it saves a lot of screen updating.
+ */
+ cmdline_row = msg_row; /* will put it back later */
+ }
+
+ if (xp->xp_numfiles == -1)
+ FreeWild(num_files, files_found);
+
+ return EXPAND_OK;
+}
+
+/*
+ * Private gettail for showmatches() (and win_redr_status_matches()):
+ * Find tail of file name path, but ignore trailing "/".
+ */
+char_u * sm_gettail(s)
+char_u *s;
+{
+ char_u *p;
+ char_u *t = s;
+ int had_sep = FALSE;
+
+ for (p = s; *p != NUL; ) {
+ if (vim_ispathsep(*p)
+#ifdef BACKSLASH_IN_FILENAME
+ && !rem_backslash(p)
+#endif
+ )
+ had_sep = TRUE;
+ else if (had_sep) {
+ t = p;
+ had_sep = FALSE;
+ }
+ mb_ptr_adv(p);
+ }
+ return t;
+}
+
+/*
+ * Return TRUE if we only need to show the tail of completion matches.
+ * When not completing file names or there is a wildcard in the path FALSE is
+ * returned.
+ */
+static int expand_showtail(xp)
+expand_T *xp;
+{
+ char_u *s;
+ char_u *end;
+
+ /* When not completing file names a "/" may mean something different. */
+ if (xp->xp_context != EXPAND_FILES
+ && xp->xp_context != EXPAND_SHELLCMD
+ && xp->xp_context != EXPAND_DIRECTORIES)
+ return FALSE;
+
+ end = gettail(xp->xp_pattern);
+ if (end == xp->xp_pattern) /* there is no path separator */
+ return FALSE;
+
+ for (s = xp->xp_pattern; s < end; s++) {
+ /* Skip escaped wildcards. Only when the backslash is not a path
+ * separator, on DOS the '*' "path\*\file" must not be skipped. */
+ if (rem_backslash(s))
+ ++s;
+ else if (vim_strchr((char_u *)"*?[", *s) != NULL)
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/*
+ * Prepare a string for expansion.
+ * When expanding file names: The string will be used with expand_wildcards().
+ * Copy "fname[len]" into allocated memory and add a '*' at the end.
+ * When expanding other names: The string will be used with regcomp(). Copy
+ * the name into allocated memory and prepend "^".
+ */
+char_u * addstar(fname, len, context)
+char_u *fname;
+int len;
+int context; /* EXPAND_FILES etc. */
+{
+ char_u *retval;
+ int i, j;
+ int new_len;
+ char_u *tail;
+ int ends_in_star;
+
+ if (context != EXPAND_FILES
+ && context != EXPAND_FILES_IN_PATH
+ && context != EXPAND_SHELLCMD
+ && context != EXPAND_DIRECTORIES) {
+ /*
+ * Matching will be done internally (on something other than files).
+ * So we convert the file-matching-type wildcards into our kind for
+ * 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. */
+ if (context == EXPAND_HELP
+ || context == EXPAND_COLORS
+ || context == EXPAND_COMPILER
+ || context == EXPAND_OWNSYNTAX
+ || context == EXPAND_FILETYPE
+ || (context == EXPAND_TAGS && fname[0] == '/'))
+ retval = vim_strnsave(fname, len);
+ 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 ".*"
+ '~' needs to be replaced by "\~" */
+
+ /* Buffer names are like file names. "." should be literal */
+ if (context == EXPAND_BUFFERS && fname[i] == '.')
+ new_len++; /* "." becomes "\." */
+
+ /* Custom expansion takes care of special things, match
+ * backslashes literally (perhaps also for other types?) */
+ if ((context == EXPAND_USER_DEFINED
+ || context == EXPAND_USER_LIST) && fname[i] == '\\')
+ new_len++; /* '\' becomes "\\" */
+ }
+ retval = alloc(new_len);
+ if (retval != NULL) {
+ retval[0] = '^';
+ j = 1;
+ for (i = 0; i < len; i++, j++) {
+ /* Skip backslash. But why? At least keep it for custom
+ * expansion. */
+ if (context != EXPAND_USER_DEFINED
+ && context != EXPAND_USER_LIST
+ && fname[i] == '\\'
+ && ++i == len)
+ break;
+
+ switch (fname[i]) {
+ case '*': retval[j++] = '.';
+ break;
+ case '~': retval[j++] = '\\';
+ break;
+ case '?': retval[j] = '.';
+ continue;
+ case '.': if (context == EXPAND_BUFFERS)
+ retval[j++] = '\\';
+ break;
+ case '\\': if (context == EXPAND_USER_DEFINED
+ || context == EXPAND_USER_LIST)
+ retval[j++] = '\\';
+ break;
+ }
+ retval[j] = fname[i];
+ }
+ retval[j] = NUL;
+ }
+ }
+ } else {
+ retval = alloc(len + 4);
+ if (retval != NULL) {
+ vim_strncpy(retval, fname, len);
+
+ /*
+ * Don't add a star to *, ~, ~user, $var or `cmd`.
+ * * would become **, which walks the whole tree.
+ * ~ would be at the start of the file name, but not the tail.
+ * $ could be anywhere in the tail.
+ * ` could be anywhere in the file name.
+ * When the name ends in '$' don't add a star, remove the '$'.
+ */
+ tail = gettail(retval);
+ ends_in_star = (len > 0 && retval[len - 1] == '*');
+#ifndef BACKSLASH_IN_FILENAME
+ for (i = len - 2; i >= 0; --i) {
+ if (retval[i] != '\\')
+ break;
+ ends_in_star = !ends_in_star;
+ }
+#endif
+ if ((*retval != '~' || tail != retval)
+ && !ends_in_star
+ && vim_strchr(tail, '$') == NULL
+ && vim_strchr(retval, '`') == NULL)
+ retval[len++] = '*';
+ else if (len > 0 && retval[len - 1] == '$')
+ --len;
+ retval[len] = NUL;
+ }
+ }
+ return retval;
+}
+
+/*
+ * Must parse the command line so far to work out what context we are in.
+ * Completion can then be done based on that context.
+ * This routine sets the variables:
+ * xp->xp_pattern The start of the pattern to be expanded within
+ * the command line (ends at the cursor).
+ * xp->xp_context The type of thing to expand. Will be one of:
+ *
+ * EXPAND_UNSUCCESSFUL Used sometimes when there is something illegal on
+ * the command line, like an unknown command. Caller
+ * should beep.
+ * EXPAND_NOTHING Unrecognised context for completion, use char like
+ * a normal char, rather than for completion. eg
+ * :s/^I/
+ * EXPAND_COMMANDS Cursor is still touching the command, so complete
+ * it.
+ * EXPAND_BUFFERS Complete file names for :buf and :sbuf commands.
+ * EXPAND_FILES After command with XFILE set, or after setting
+ * with P_EXPAND set. eg :e ^I, :w>>^I
+ * EXPAND_DIRECTORIES In some cases this is used instead of the latter
+ * when we know only directories are of interest. eg
+ * :set dir=^I
+ * EXPAND_SHELLCMD After ":!cmd", ":r !cmd" or ":w !cmd".
+ * EXPAND_SETTINGS Complete variable names. eg :set d^I
+ * EXPAND_BOOL_SETTINGS Complete boolean variables only, eg :set no^I
+ * EXPAND_TAGS Complete tags from the files in p_tags. eg :ta a^I
+ * EXPAND_TAGS_LISTFILES As above, but list filenames on ^D, after :tselect
+ * EXPAND_HELP Complete tags from the file 'helpfile'/tags
+ * EXPAND_EVENTS Complete event names
+ * EXPAND_SYNTAX Complete :syntax command arguments
+ * EXPAND_HIGHLIGHT Complete highlight (syntax) group names
+ * EXPAND_AUGROUP Complete autocommand group names
+ * EXPAND_USER_VARS Complete user defined variable names, eg :unlet a^I
+ * EXPAND_MAPPINGS Complete mapping and abbreviation names,
+ * eg :unmap a^I , :cunab x^I
+ * EXPAND_FUNCTIONS Complete internal or user defined function names,
+ * eg :call sub^I
+ * EXPAND_USER_FUNC Complete user defined function names, eg :delf F^I
+ * EXPAND_EXPRESSION Complete internal or user defined function/variable
+ * names in expressions, eg :while s^I
+ * EXPAND_ENV_VARS Complete environment variable names
+ * EXPAND_USER Complete user names
+ */
+static void set_expand_context(xp)
+expand_T *xp;
+{
+ /* only expansion for ':', '>' and '=' command-lines */
+ if (ccline.cmdfirstc != ':'
+ && ccline.cmdfirstc != '>' && ccline.cmdfirstc != '='
+ && !ccline.input_fn
+ ) {
+ xp->xp_context = EXPAND_NOTHING;
+ return;
+ }
+ set_cmd_context(xp, ccline.cmdbuff, ccline.cmdlen, ccline.cmdpos);
+}
+
+void set_cmd_context(xp, str, len, col)
+expand_T *xp;
+char_u *str; /* start of command line */
+int len; /* length of command line (excl. NUL) */
+int col; /* position of cursor */
+{
+ int old_char = NUL;
+ char_u *nextcomm;
+
+ /*
+ * Avoid a UMR warning from Purify, only save the character if it has been
+ * written before.
+ */
+ if (col < len)
+ old_char = str[col];
+ str[col] = NUL;
+ nextcomm = str;
+
+ if (ccline.cmdfirstc == '=') {
+ /* pass CMD_SIZE because there is no real command */
+ set_context_for_expression(xp, str, CMD_SIZE);
+ } else if (ccline.input_fn) {
+ xp->xp_context = ccline.xp_context;
+ xp->xp_pattern = ccline.cmdbuff;
+ xp->xp_arg = ccline.xp_arg;
+ } 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. */
+ xp->xp_line = str;
+ xp->xp_col = col;
+
+ str[col] = old_char;
+}
+
+/*
+ * Expand the command line "str" from context "xp".
+ * "xp" must have been set by set_cmd_context().
+ * xp->xp_pattern points into "str", to where the text that is to be expanded
+ * starts.
+ * Returns EXPAND_UNSUCCESSFUL when there is something illegal before the
+ * cursor.
+ * Returns EXPAND_NOTHING when there is nothing to expand, might insert the
+ * key that triggered expansion literally.
+ * Returns EXPAND_OK otherwise.
+ */
+int expand_cmdline(xp, str, col, matchcount, matches)
+expand_T *xp;
+char_u *str; /* start of command line */
+int col; /* position of cursor */
+int *matchcount; /* return: nr of matches */
+char_u ***matches; /* return: array of pointers to matches */
+{
+ char_u *file_str = NULL;
+ int options = WILD_ADD_SLASH|WILD_SILENT;
+
+ if (xp->xp_context == EXPAND_UNSUCCESSFUL) {
+ beep_flush();
+ return EXPAND_UNSUCCESSFUL; /* Something illegal on command line */
+ }
+ if (xp->xp_context == EXPAND_NOTHING) {
+ /* Caller can use the character as a normal char instead */
+ return EXPAND_NOTHING;
+ }
+
+ /* add star to file name, or convert to regexp if not exp. files. */
+ xp->xp_pattern_len = (int)(str + col - xp->xp_pattern);
+ file_str = addstar(xp->xp_pattern, xp->xp_pattern_len, xp->xp_context);
+ if (file_str == NULL)
+ return EXPAND_UNSUCCESSFUL;
+
+ if (p_wic)
+ options += WILD_ICASE;
+
+ /* find all files that match the description */
+ if (ExpandFromContext(xp, file_str, matchcount, matches, options) == FAIL) {
+ *matchcount = 0;
+ *matches = NULL;
+ }
+ vim_free(file_str);
+
+ return EXPAND_OK;
+}
+
+/*
+ * Cleanup matches for help tags: remove "@en" if "en" is the only language.
+ */
+static void cleanup_help_tags __ARGS((int num_file, char_u **file));
+
+static void cleanup_help_tags(num_file, file)
+int num_file;
+char_u **file;
+{
+ int i, j;
+ int len;
+
+ 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)
+ if (j != i
+ && (int)STRLEN(file[j]) == len + 3
+ && STRNCMP(file[i], file[j], len + 1) == 0)
+ break;
+ if (j == num_file)
+ file[i][len] = NUL;
+ }
+ }
+}
+
+/*
+ * Do the expansion based on xp->xp_context and "pat".
+ */
+static int ExpandFromContext(xp, pat, num_file, file, options)
+expand_T *xp;
+char_u *pat;
+int *num_file;
+char_u ***file;
+int options; /* EW_ flags */
+{
+ regmatch_T regmatch;
+ int ret;
+ int flags;
+
+ flags = EW_DIR; /* include directories */
+ if (options & WILD_LIST_NOTFOUND)
+ flags |= EW_NOTFOUND;
+ if (options & WILD_ADD_SLASH)
+ flags |= EW_ADDSLASH;
+ if (options & WILD_KEEP_ALL)
+ flags |= EW_KEEPALL;
+ if (options & WILD_SILENT)
+ flags |= EW_SILENT;
+
+ if (xp->xp_context == EXPAND_FILES
+ || xp->xp_context == EXPAND_DIRECTORIES
+ || xp->xp_context == EXPAND_FILES_IN_PATH) {
+ /*
+ * Expand file or directory names.
+ */
+ int free_pat = FALSE;
+ int i;
+
+ /* for ":set path=" and ":set tags=" halve backslashes for escaped
+ * space */
+ if (xp->xp_backslash != XP_BS_NONE) {
+ free_pat = TRUE;
+ pat = vim_strsave(pat);
+ for (i = 0; pat[i]; ++i)
+ if (pat[i] == '\\') {
+ if (xp->xp_backslash == XP_BS_THREE
+ && pat[i + 1] == '\\'
+ && pat[i + 2] == '\\'
+ && pat[i + 3] == ' ')
+ STRMOVE(pat + i, pat + i + 3);
+ if (xp->xp_backslash == XP_BS_ONE
+ && pat[i + 1] == ' ')
+ STRMOVE(pat + i, pat + i + 1);
+ }
+ }
+
+ if (xp->xp_context == EXPAND_FILES)
+ flags |= EW_FILE;
+ else if (xp->xp_context == EXPAND_FILES_IN_PATH)
+ flags |= (EW_FILE | EW_PATH);
+ else
+ flags = (flags | EW_DIR) & ~EW_FILE;
+ if (options & WILD_ICASE)
+ flags |= EW_ICASE;
+
+ /* Expand wildcards, supporting %:h and the like. */
+ ret = expand_wildcards_eval(&pat, num_file, file, flags);
+ if (free_pat)
+ vim_free(pat);
+ return ret;
+ }
+
+ *file = (char_u **)"";
+ *num_file = 0;
+ if (xp->xp_context == EXPAND_HELP) {
+ /* With an empty argument we would get all the help tags, which is
+ * very slow. Get matches for "help" instead. */
+ if (find_help_tags(*pat == NUL ? (char_u *)"help" : pat,
+ num_file, file, FALSE) == OK) {
+ cleanup_help_tags(*num_file, *file);
+ return OK;
+ }
+ return FAIL;
+ }
+
+ if (xp->xp_context == EXPAND_SHELLCMD)
+ return expand_shellcmd(pat, num_file, file, flags);
+ if (xp->xp_context == EXPAND_OLD_SETTING)
+ return ExpandOldSetting(num_file, file);
+ if (xp->xp_context == EXPAND_BUFFERS)
+ return ExpandBufnames(pat, num_file, file, options);
+ if (xp->xp_context == EXPAND_TAGS
+ || xp->xp_context == EXPAND_TAGS_LISTFILES)
+ return expand_tags(xp->xp_context == EXPAND_TAGS, pat, num_file, file);
+ if (xp->xp_context == EXPAND_COLORS) {
+ char *directories[] = {"colors", NULL};
+ return ExpandRTDir(pat, num_file, file, directories);
+ }
+ if (xp->xp_context == EXPAND_COMPILER) {
+ char *directories[] = {"compiler", NULL};
+ return ExpandRTDir(pat, num_file, file, directories);
+ }
+ if (xp->xp_context == EXPAND_OWNSYNTAX) {
+ char *directories[] = {"syntax", NULL};
+ return ExpandRTDir(pat, num_file, file, directories);
+ }
+ if (xp->xp_context == EXPAND_FILETYPE) {
+ char *directories[] = {"syntax", "indent", "ftplugin", NULL};
+ return ExpandRTDir(pat, num_file, file, directories);
+ }
+ if (xp->xp_context == EXPAND_USER_LIST)
+ return ExpandUserList(xp, num_file, file);
+
+ regmatch.regprog = vim_regcomp(pat, p_magic ? RE_MAGIC : 0);
+ if (regmatch.regprog == NULL)
+ return FAIL;
+
+ /* set ignore-case according to p_ic, p_scs and pat */
+ regmatch.rm_ic = ignorecase(pat);
+
+ if (xp->xp_context == EXPAND_SETTINGS
+ || xp->xp_context == EXPAND_BOOL_SETTINGS)
+ ret = ExpandSettings(xp, &regmatch, num_file, file);
+ else if (xp->xp_context == EXPAND_MAPPINGS)
+ ret = ExpandMappings(&regmatch, num_file, file);
+ else if (xp->xp_context == EXPAND_USER_DEFINED)
+ ret = ExpandUserDefined(xp, &regmatch, num_file, file);
+ else {
+ static struct expgen {
+ int context;
+ char_u *((*func)__ARGS((expand_T *, int)));
+ 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_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_PROFILE, get_profile_name, TRUE, TRUE},
+#ifdef HAVE_WORKING_LIBINTL
+ {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},
+ };
+ int i;
+
+ /*
+ * Find a context in the table and call the ExpandGeneric() with the
+ * right function to do the expansion.
+ */
+ ret = FAIL;
+ for (i = 0; i < (int)(sizeof(tab) / sizeof(struct expgen)); ++i)
+ if (xp->xp_context == tab[i].context) {
+ if (tab[i].ic)
+ regmatch.rm_ic = TRUE;
+ ret = ExpandGeneric(xp, &regmatch, num_file, file,
+ tab[i].func, tab[i].escaped);
+ break;
+ }
+ }
+
+ vim_regfree(regmatch.regprog);
+
+ return ret;
+}
+
+/*
+ * Expand a list of names.
+ *
+ * Generic function for command line completion. It calls a function to
+ * obtain strings, one by one. The strings are matched against a regexp
+ * program. Matching strings are copied into an array, which is returned.
+ *
+ * Returns OK when no problems encountered, FAIL for error (out of memory).
+ */
+int ExpandGeneric(xp, regmatch, num_file, file, func, escaped)
+expand_T *xp;
+regmatch_T *regmatch;
+int *num_file;
+char_u ***file;
+char_u *((*func)__ARGS((expand_T *, int)));
+/* returns a string from the list */
+int escaped;
+{
+ int i;
+ int count = 0;
+ int round;
+ char_u *str;
+
+ /* do this loop twice:
+ * round == 0: count the number of matching names
+ * round == 1: copy the matching names into allocated memory
+ */
+ for (round = 0; round <= 1; ++round) {
+ for (i = 0;; ++i) {
+ str = (*func)(xp, i);
+ if (str == NULL) /* end of list */
+ break;
+ if (*str == NUL) /* skip empty strings */
+ continue;
+
+ if (vim_regexec(regmatch, str, (colnr_T)0)) {
+ if (round) {
+ if (escaped)
+ str = vim_strsave_escaped(str, (char_u *)" \t\\.");
+ else
+ str = vim_strsave(str);
+ (*file)[count] = str;
+ if (func == get_menu_names && str != NULL) {
+ /* test for separator added by get_menu_names() */
+ str += STRLEN(str) - 1;
+ if (*str == '\001')
+ *str = '.';
+ }
+ }
+ ++count;
+ }
+ }
+ if (round == 0) {
+ if (count == 0)
+ return OK;
+ *num_file = count;
+ *file = (char_u **)alloc((unsigned)(count * sizeof(char_u *)));
+ if (*file == NULL) {
+ *file = (char_u **)"";
+ return FAIL;
+ }
+ count = 0;
+ }
+ }
+
+ /* Sort the results. Keep menu's in the specified order. */
+ if (xp->xp_context != EXPAND_MENUNAMES && xp->xp_context != EXPAND_MENUS) {
+ if (xp->xp_context == EXPAND_EXPRESSION
+ || xp->xp_context == EXPAND_FUNCTIONS
+ || xp->xp_context == EXPAND_USER_FUNC)
+ /* <SNR> functions should be sorted to the end. */
+ qsort((void *)*file, (size_t)*num_file, sizeof(char_u *),
+ sort_func_compare);
+ else
+ sort_strings(*file, *num_file);
+ }
+
+ /* Reset the variables used for special highlight names expansion, so that
+ * they don't show up when getting normal highlight names by ID. */
+ reset_expand_highlight();
+
+ return OK;
+}
+
+/*
+ * Complete a shell command.
+ * Returns FAIL or OK;
+ */
+static int expand_shellcmd(filepat, num_file, file, flagsarg)
+char_u *filepat; /* pattern to match with command names */
+int *num_file; /* return: number of matches */
+char_u ***file; /* return: array with matches */
+int flagsarg; /* EW_ flags */
+{
+ char_u *pat;
+ int i;
+ char_u *path;
+ int mustfree = FALSE;
+ garray_T ga;
+ char_u *buf = alloc(MAXPATHL);
+ size_t l;
+ char_u *s, *e;
+ int flags = flagsarg;
+ int ret;
+
+ if (buf == NULL)
+ return FAIL;
+
+ /* for ":set path=" and ":set tags=" halve backslashes for escaped
+ * space */
+ pat = vim_strsave(filepat);
+ for (i = 0; pat[i]; ++i)
+ if (pat[i] == '\\' && pat[i + 1] == ' ')
+ STRMOVE(pat + i, pat + i + 1);
+
+ flags |= EW_FILE | EW_EXEC;
+
+ /* For an absolute name we don't use $PATH. */
+ if (mch_isFullName(pat))
+ path = (char_u *)" ";
+ else if ((pat[0] == '.' && (vim_ispathsep(pat[1])
+ || (pat[1] == '.' && vim_ispathsep(pat[2])))))
+ path = (char_u *)".";
+ else {
+ path = vim_getenv((char_u *)"PATH", &mustfree);
+ if (path == NULL)
+ path = (char_u *)"";
+ }
+
+ /*
+ * Go over all directories in $PATH. Expand matches in that directory and
+ * collect them in "ga".
+ */
+ ga_init2(&ga, (int)sizeof(char *), 10);
+ for (s = path; *s != NUL; s = e) {
+ if (*s == ' ')
+ ++s; /* Skip space used for absolute path name. */
+
+ e = vim_strchr(s, ':');
+ if (e == NULL)
+ e = s + STRLEN(s);
+
+ l = e - s;
+ if (l > MAXPATHL - 5)
+ break;
+ vim_strncpy(buf, s, l);
+ add_pathsep(buf);
+ l = STRLEN(buf);
+ vim_strncpy(buf + l, pat, MAXPATHL - 1 - l);
+
+ /* Expand matches in one directory of $PATH. */
+ ret = expand_wildcards(1, &buf, num_file, file, flags);
+ if (ret == OK) {
+ if (ga_grow(&ga, *num_file) == FAIL)
+ FreeWild(*num_file, *file);
+ else {
+ for (i = 0; i < *num_file; ++i) {
+ s = (*file)[i];
+ if (STRLEN(s) > l) {
+ /* Remove the path again. */
+ STRMOVE(s, s + l);
+ ((char_u **)ga.ga_data)[ga.ga_len++] = s;
+ } else
+ vim_free(s);
+ }
+ vim_free(*file);
+ }
+ }
+ if (*e != NUL)
+ ++e;
+ }
+ *file = ga.ga_data;
+ *num_file = ga.ga_len;
+
+ vim_free(buf);
+ vim_free(pat);
+ if (mustfree)
+ vim_free(path);
+ return OK;
+}
+
+
+static void * call_user_expand_func __ARGS((void *(*user_expand_func)__ARGS(
+ (char_u *, int, char_u **,
+ int)), expand_T *xp,
+ 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).
+ */
+static void * call_user_expand_func(user_expand_func, xp, num_file, file)
+void *(*user_expand_func)__ARGS((char_u *, int, char_u **, int));
+expand_T *xp;
+int *num_file;
+char_u ***file;
+{
+ int keep = 0;
+ char_u num[50];
+ char_u *args[3];
+ int save_current_SID = current_SID;
+ void *ret;
+ struct cmdline_info save_ccline;
+
+ if (xp->xp_arg == NULL || xp->xp_arg[0] == '\0' || xp->xp_line == NULL)
+ return NULL;
+ *num_file = 0;
+ *file = NULL;
+
+ if (ccline.cmdbuff != NULL) {
+ keep = ccline.cmdbuff[ccline.cmdlen];
+ ccline.cmdbuff[ccline.cmdlen] = 0;
+ }
+
+ args[0] = vim_strnsave(xp->xp_pattern, xp->xp_pattern_len);
+ args[1] = xp->xp_line;
+ sprintf((char *)num, "%d", xp->xp_col);
+ args[2] = num;
+
+ /* Save the cmdline, we don't know what the function may do. */
+ save_ccline = ccline;
+ ccline.cmdbuff = NULL;
+ ccline.cmdprompt = NULL;
+ current_SID = xp->xp_scriptID;
+
+ ret = user_expand_func(xp->xp_arg, 3, args, FALSE);
+
+ ccline = save_ccline;
+ current_SID = save_current_SID;
+ if (ccline.cmdbuff != NULL)
+ ccline.cmdbuff[ccline.cmdlen] = keep;
+
+ vim_free(args[0]);
+ return ret;
+}
+
+/*
+ * Expand names with a function defined by the user.
+ */
+static int ExpandUserDefined(xp, regmatch, num_file, file)
+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;
+
+ retstr = call_user_expand_func(call_func_retstr, xp, num_file, file);
+ if (retstr == NULL)
+ return FAIL;
+
+ ga_init2(&ga, (int)sizeof(char *), 3);
+ for (s = retstr; *s != NUL; s = e) {
+ e = vim_strchr(s, '\n');
+ if (e == NULL)
+ e = s + STRLEN(s);
+ keep = *e;
+ *e = 0;
+
+ if (xp->xp_pattern[0] && vim_regexec(regmatch, s, (colnr_T)0) == 0) {
+ *e = keep;
+ if (*e != NUL)
+ ++e;
+ continue;
+ }
+
+ if (ga_grow(&ga, 1) == FAIL)
+ break;
+
+ ((char_u **)ga.ga_data)[ga.ga_len] = vim_strnsave(s, (int)(e - s));
+ ++ga.ga_len;
+
+ *e = keep;
+ if (*e != NUL)
+ ++e;
+ }
+ vim_free(retstr);
+ *file = ga.ga_data;
+ *num_file = ga.ga_len;
+ return OK;
+}
+
+/*
+ * Expand names with a list returned by a function defined by the user.
+ */
+static int ExpandUserList(xp, num_file, file)
+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)
+ return FAIL;
+
+ ga_init2(&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 */
+
+ if (ga_grow(&ga, 1) == FAIL)
+ break;
+
+ ((char_u **)ga.ga_data)[ga.ga_len] =
+ vim_strsave(li->li_tv.vval.v_string);
+ ++ga.ga_len;
+ }
+ list_unref(retlist);
+
+ *file = ga.ga_data;
+ *num_file = ga.ga_len;
+ return OK;
+}
+
+/*
+ * Expand color scheme, compiler or filetype names:
+ * 'runtimepath'/{dirnames}/{pat}.vim
+ * "dirnames" is an array with one or more directory names.
+ */
+static int ExpandRTDir(pat, num_file, file, dirnames)
+char_u *pat;
+int *num_file;
+char_u ***file;
+char *dirnames[];
+{
+ char_u *matches;
+ char_u *s;
+ char_u *e;
+ garray_T ga;
+ int i;
+ int pat_len;
+
+ *num_file = 0;
+ *file = NULL;
+ pat_len = (int)STRLEN(pat);
+ ga_init2(&ga, (int)sizeof(char *), 10);
+
+ for (i = 0; dirnames[i] != NULL; ++i) {
+ s = alloc((unsigned)(STRLEN(dirnames[i]) + pat_len + 7));
+ if (s == NULL) {
+ ga_clear_strings(&ga);
+ return FAIL;
+ }
+ sprintf((char *)s, "%s/%s*.vim", dirnames[i], pat);
+ matches = globpath(p_rtp, s, 0);
+ vim_free(s);
+ if (matches == NULL)
+ continue;
+
+ for (s = matches; *s != NUL; s = e) {
+ e = vim_strchr(s, '\n');
+ if (e == NULL)
+ e = s + STRLEN(s);
+ if (ga_grow(&ga, 1) == FAIL)
+ break;
+ if (e - 4 > s && STRNICMP(e - 4, ".vim", 4) == 0) {
+ for (s = e - 4; s > matches; mb_ptr_back(matches, s))
+ if (*s == '\n' || vim_ispathsep(*s))
+ break;
+ ++s;
+ ((char_u **)ga.ga_data)[ga.ga_len] =
+ vim_strnsave(s, (int)(e - s - 4));
+ ++ga.ga_len;
+ }
+ if (*e != NUL)
+ ++e;
+ }
+ vim_free(matches);
+ }
+ if (ga.ga_len == 0)
+ return FAIL;
+
+ /* Sort and remove duplicates which can happen when specifying multiple
+ * directories in dirnames. */
+ remove_duplicates(&ga);
+
+ *file = ga.ga_data;
+ *num_file = ga.ga_len;
+ return OK;
+}
+
+
+/*
+ * Expand "file" for all comma-separated directories in "path".
+ * Returns an allocated string with all matches concatenated, separated by
+ * newlines. Returns NULL for an error or no matches.
+ */
+char_u * globpath(path, file, expand_options)
+char_u *path;
+char_u *file;
+int expand_options;
+{
+ expand_T xpc;
+ char_u *buf;
+ garray_T ga;
+ int i;
+ int len;
+ int num_p;
+ char_u **p;
+ char_u *cur = NULL;
+
+ buf = alloc(MAXPATHL);
+ if (buf == NULL)
+ return NULL;
+
+ ExpandInit(&xpc);
+ xpc.xp_context = EXPAND_FILES;
+
+ ga_init2(&ga, 1, 100);
+
+ /* Loop over all entries in {path}. */
+ while (*path != NUL) {
+ /* Copy one item of the path to buf[] and concatenate the file name. */
+ copy_option_part(&path, buf, MAXPATHL, ",");
+ if (STRLEN(buf) + STRLEN(file) + 2 < MAXPATHL) {
+ add_pathsep(buf);
+ STRCAT(buf, file);
+ if (ExpandFromContext(&xpc, buf, &num_p, &p,
+ WILD_SILENT|expand_options) != FAIL && num_p > 0) {
+ ExpandEscape(&xpc, buf, num_p, p, WILD_SILENT|expand_options);
+ for (len = 0, i = 0; i < num_p; ++i)
+ len += (int)STRLEN(p[i]) + 1;
+
+ /* Concatenate new results to previous ones. */
+ if (ga_grow(&ga, len) == OK) {
+ cur = (char_u *)ga.ga_data + ga.ga_len;
+ for (i = 0; i < num_p; ++i) {
+ STRCPY(cur, p[i]);
+ cur += STRLEN(p[i]);
+ *cur++ = '\n';
+ }
+ ga.ga_len += len;
+ }
+ FreeWild(num_p, p);
+ }
+ }
+ }
+ if (cur != NULL)
+ *--cur = 0; /* Replace trailing newline with NUL */
+
+ vim_free(buf);
+ return (char_u *)ga.ga_data;
+}
+
+
+
+/*********************************
+* Command line history stuff *
+*********************************/
+
+/*
+ * Translate a history character to the associated type number.
+ */
+static int hist_char2type(c)
+int c;
+{
+ if (c == ':')
+ return HIST_CMD;
+ if (c == '=')
+ return HIST_EXPR;
+ if (c == '@')
+ return HIST_INPUT;
+ if (c == '>')
+ return HIST_DEBUG;
+ return HIST_SEARCH; /* must be '?' or '/' */
+}
+
+/*
+ * Table of history names.
+ * These names are used in :history and various hist...() functions.
+ * It is sufficient to give the significant prefix of a history name.
+ */
+
+static char *(history_names[]) =
+{
+ "cmd",
+ "search",
+ "expr",
+ "input",
+ "debug",
+ NULL
+};
+
+/*
+ * Function given to ExpandGeneric() to obtain the possible first
+ * arguments of the ":history command.
+ */
+static char_u * get_history_arg(xp, idx)
+expand_T *xp UNUSED;
+int idx;
+{
+ static char_u compl[2] = { NUL, NUL };
+ char *short_names = ":=@>?/";
+ int short_names_count = (int)STRLEN(short_names);
+ int history_name_count = sizeof(history_names) / sizeof(char *) - 1;
+
+ if (idx < short_names_count) {
+ compl[0] = (char_u)short_names[idx];
+ return compl;
+ }
+ if (idx < short_names_count + history_name_count)
+ return (char_u *)history_names[idx - short_names_count];
+ if (idx == short_names_count + history_name_count)
+ return (char_u *)"all";
+ return NULL;
+}
+
+/*
+ * init_history() - Initialize the command line history.
+ * Also used to re-allocate the history when the size changes.
+ */
+void init_history() {
+ int newlen; /* new length of history table */
+ histentry_T *temp;
+ int i;
+ int j;
+ int type;
+
+ /*
+ * If size of history table changed, reallocate it
+ */
+ newlen = (int)p_hi;
+ if (newlen != hislen) { /* history length changed */
+ for (type = 0; type < HIST_COUNT; ++type) { /* adjust the tables */
+ if (newlen) {
+ temp = (histentry_T *)lalloc(
+ (long_u)(newlen * sizeof(histentry_T)), TRUE);
+ if (temp == NULL) { /* out of memory! */
+ if (type == 0) { /* first one: just keep the old length */
+ newlen = hislen;
+ break;
+ }
+ /* Already changed one table, now we can only have zero
+ * length for all tables. */
+ newlen = 0;
+ type = -1;
+ continue;
+ }
+ } else
+ temp = NULL;
+ if (newlen == 0 || temp != NULL) {
+ if (hisidx[type] < 0) { /* there are no entries yet */
+ for (i = 0; i < newlen; ++i)
+ clear_hist_entry(&temp[i]);
+ } else if (newlen > hislen) { /* array becomes bigger */
+ for (i = 0; i <= hisidx[type]; ++i)
+ temp[i] = history[type][i];
+ j = i;
+ for (; i <= newlen - (hislen - hisidx[type]); ++i)
+ clear_hist_entry(&temp[i]);
+ for (; j < hislen; ++i, ++j)
+ temp[i] = history[type][j];
+ } else { /* array becomes smaller or 0 */
+ j = hisidx[type];
+ for (i = newlen - 1;; --i) {
+ if (i >= 0) /* copy newest entries */
+ temp[i] = history[type][j];
+ else /* remove older entries */
+ vim_free(history[type][j].hisstr);
+ if (--j < 0)
+ j = hislen - 1;
+ if (j == hisidx[type])
+ break;
+ }
+ hisidx[type] = newlen - 1;
+ }
+ vim_free(history[type]);
+ history[type] = temp;
+ }
+ }
+ hislen = newlen;
+ }
+}
+
+static void clear_hist_entry(hisptr)
+histentry_T *hisptr;
+{
+ hisptr->hisnum = 0;
+ hisptr->viminfo = FALSE;
+ hisptr->hisstr = NULL;
+}
+
+/*
+ * Check if command line 'str' is already in history.
+ * If 'move_to_front' is TRUE, matching entry is moved to end of history.
+ */
+static int in_history(type, str, move_to_front, sep, writing)
+int type;
+char_u *str;
+int move_to_front; /* Move the entry to the front if it exists */
+int sep;
+int writing; /* ignore entries read from viminfo */
+{
+ int i;
+ int last_i = -1;
+ char_u *p;
+
+ if (hisidx[type] < 0)
+ return FALSE;
+ i = hisidx[type];
+ do {
+ if (history[type][i].hisstr == NULL)
+ return FALSE;
+
+ /* For search history, check that the separator character matches as
+ * well. */
+ p = history[type][i].hisstr;
+ if (STRCMP(str, p) == 0
+ && !(writing && history[type][i].viminfo)
+ && (type != HIST_SEARCH || sep == p[STRLEN(p) + 1])) {
+ if (!move_to_front)
+ return TRUE;
+ last_i = i;
+ break;
+ }
+ if (--i < 0)
+ i = hislen - 1;
+ } while (i != hisidx[type]);
+
+ if (last_i >= 0) {
+ str = history[type][i].hisstr;
+ while (i != hisidx[type]) {
+ if (++i >= hislen)
+ i = 0;
+ history[type][last_i] = history[type][i];
+ last_i = i;
+ }
+ history[type][i].hisnum = ++hisnum[type];
+ history[type][i].viminfo = FALSE;
+ history[type][i].hisstr = str;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*
+ * Convert history name (from table above) to its HIST_ equivalent.
+ * When "name" is empty, return "cmd" history.
+ * Returns -1 for unknown history name.
+ */
+int get_histtype(name)
+char_u *name;
+{
+ int i;
+ int len = (int)STRLEN(name);
+
+ /* No argument: use current history. */
+ if (len == 0)
+ return hist_char2type(ccline.cmdfirstc);
+
+ for (i = 0; history_names[i] != NULL; ++i)
+ if (STRNICMP(name, history_names[i], len) == 0)
+ return i;
+
+ if (vim_strchr((char_u *)":=@>?/", name[0]) != NULL && name[1] == NUL)
+ return hist_char2type(name[0]);
+
+ return -1;
+}
+
+static int last_maptick = -1; /* last seen maptick */
+
+/*
+ * Add the given string to the given history. If the string is already in the
+ * history then it is moved to the front. "histype" may be one of he HIST_
+ * values.
+ */
+void add_to_history(histype, new_entry, in_map, sep)
+int histype;
+char_u *new_entry;
+int in_map; /* consider maptick when inside a mapping */
+int sep; /* separator character used (search hist) */
+{
+ histentry_T *hisptr;
+ int len;
+
+ if (hislen == 0) /* no history */
+ return;
+
+ if (cmdmod.keeppatterns && histype == HIST_SEARCH)
+ return;
+
+ /*
+ * Searches inside the same mapping overwrite each other, so that only
+ * the last line is kept. Be careful not to remove a line that was moved
+ * 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 */
+ hisptr = &history[HIST_SEARCH][hisidx[HIST_SEARCH]];
+ vim_free(hisptr->hisstr);
+ clear_hist_entry(hisptr);
+ --hisnum[histype];
+ if (--hisidx[HIST_SEARCH] < 0)
+ hisidx[HIST_SEARCH] = hislen - 1;
+ }
+ last_maptick = -1;
+ }
+ if (!in_history(histype, new_entry, TRUE, sep, FALSE)) {
+ if (++hisidx[histype] == hislen)
+ hisidx[histype] = 0;
+ hisptr = &history[histype][hisidx[histype]];
+ vim_free(hisptr->hisstr);
+
+ /* Store the separator after the NUL of the string. */
+ len = (int)STRLEN(new_entry);
+ hisptr->hisstr = vim_strnsave(new_entry, len + 2);
+ if (hisptr->hisstr != NULL)
+ hisptr->hisstr[len + 1] = sep;
+
+ hisptr->hisnum = ++hisnum[histype];
+ hisptr->viminfo = FALSE;
+ if (histype == HIST_SEARCH && in_map)
+ last_maptick = maptick;
+ }
+}
+
+
+/*
+ * Get identifier of newest history entry.
+ * "histype" may be one of the HIST_ values.
+ */
+int get_history_idx(histype)
+int histype;
+{
+ if (hislen == 0 || histype < 0 || histype >= HIST_COUNT
+ || hisidx[histype] < 0)
+ return -1;
+
+ return history[histype][hisidx[histype]].hisnum;
+}
+
+static struct cmdline_info *get_ccline_ptr __ARGS((void));
+
+/*
+ * Get pointer to the command line info to use. cmdline_paste() may clear
+ * ccline and put the previous value in prev_ccline.
+ */
+static struct cmdline_info * get_ccline_ptr()
+{
+ if ((State & CMDLINE) == 0)
+ return NULL;
+ if (ccline.cmdbuff != NULL)
+ return &ccline;
+ if (prev_ccline_used && prev_ccline.cmdbuff != NULL)
+ return &prev_ccline;
+ return NULL;
+}
+
+/*
+ * Get the current command line in allocated memory.
+ * Only works when the command line is being edited.
+ * Returns NULL when something is wrong.
+ */
+char_u * get_cmdline_str() {
+ struct cmdline_info *p = get_ccline_ptr();
+
+ if (p == NULL)
+ return NULL;
+ return vim_strnsave(p->cmdbuff, p->cmdlen);
+}
+
+/*
+ * Get the current command line position, counted in bytes.
+ * Zero is the first position.
+ * Only works when the command line is being edited.
+ * Returns -1 when something is wrong.
+ */
+int get_cmdline_pos() {
+ struct cmdline_info *p = get_ccline_ptr();
+
+ if (p == NULL)
+ return -1;
+ return p->cmdpos;
+}
+
+/*
+ * Set the command line byte position to "pos". Zero is the first position.
+ * Only works when the command line is being edited.
+ * Returns 1 when failed, 0 when OK.
+ */
+int set_cmdline_pos(pos)
+int pos;
+{
+ struct cmdline_info *p = get_ccline_ptr();
+
+ if (p == NULL)
+ return 1;
+
+ /* The position is not set directly but after CTRL-\ e or CTRL-R = has
+ * changed the command line. */
+ if (pos < 0)
+ new_cmdpos = 0;
+ else
+ new_cmdpos = pos;
+ return 0;
+}
+
+/*
+ * Get the current command-line type.
+ * Returns ':' or '/' or '?' or '@' or '>' or '-'
+ * Only works when the command line is being edited.
+ * Returns NUL when something is wrong.
+ */
+int get_cmdline_type() {
+ struct cmdline_info *p = get_ccline_ptr();
+
+ if (p == NULL)
+ return NUL;
+ if (p->cmdfirstc == NUL)
+ return (p->input_fn) ? '@' : '-';
+ return p->cmdfirstc;
+}
+
+/*
+ * Calculate history index from a number:
+ * num > 0: seen as identifying number of a history entry
+ * num < 0: relative position in history wrt newest entry
+ * "histype" may be one of the HIST_ values.
+ */
+static int calc_hist_idx(histype, num)
+int histype;
+int num;
+{
+ int i;
+ histentry_T *hist;
+ int wrapped = FALSE;
+
+ if (hislen == 0 || histype < 0 || histype >= HIST_COUNT
+ || (i = hisidx[histype]) < 0 || num == 0)
+ return -1;
+
+ hist = history[histype];
+ if (num > 0) {
+ while (hist[i].hisnum > num)
+ if (--i < 0) {
+ if (wrapped)
+ break;
+ i += hislen;
+ wrapped = TRUE;
+ }
+ if (hist[i].hisnum == num && hist[i].hisstr != NULL)
+ return i;
+ } else if (-num <= hislen) {
+ i += num + 1;
+ if (i < 0)
+ i += hislen;
+ if (hist[i].hisstr != NULL)
+ return i;
+ }
+ return -1;
+}
+
+/*
+ * Get a history entry by its index.
+ * "histype" may be one of the HIST_ values.
+ */
+char_u * get_history_entry(histype, idx)
+int histype;
+int idx;
+{
+ idx = calc_hist_idx(histype, idx);
+ if (idx >= 0)
+ return history[histype][idx].hisstr;
+ else
+ return (char_u *)"";
+}
+
+/*
+ * Clear all entries of a history.
+ * "histype" may be one of the HIST_ values.
+ */
+int clr_history(histype)
+int histype;
+{
+ int i;
+ histentry_T *hisptr;
+
+ if (hislen != 0 && histype >= 0 && histype < HIST_COUNT) {
+ hisptr = history[histype];
+ for (i = hislen; i--; ) {
+ vim_free(hisptr->hisstr);
+ clear_hist_entry(hisptr);
+ }
+ hisidx[histype] = -1; /* mark history as cleared */
+ hisnum[histype] = 0; /* reset identifier counter */
+ return OK;
+ }
+ return FAIL;
+}
+
+/*
+ * Remove all entries matching {str} from a history.
+ * "histype" may be one of the HIST_ values.
+ */
+int del_history_entry(histype, str)
+int histype;
+char_u *str;
+{
+ regmatch_T regmatch;
+ histentry_T *hisptr;
+ int idx;
+ int i;
+ int last;
+ int found = FALSE;
+
+ regmatch.regprog = NULL;
+ regmatch.rm_ic = FALSE; /* always match case */
+ if (hislen != 0
+ && histype >= 0
+ && histype < HIST_COUNT
+ && *str != NUL
+ && (idx = hisidx[histype]) >= 0
+ && (regmatch.regprog = vim_regcomp(str, RE_MAGIC + RE_STRING))
+ != NULL) {
+ i = last = idx;
+ do {
+ hisptr = &history[histype][i];
+ if (hisptr->hisstr == NULL)
+ break;
+ if (vim_regexec(&regmatch, hisptr->hisstr, (colnr_T)0)) {
+ found = TRUE;
+ vim_free(hisptr->hisstr);
+ clear_hist_entry(hisptr);
+ } else {
+ if (i != last) {
+ history[histype][last] = *hisptr;
+ clear_hist_entry(hisptr);
+ }
+ if (--last < 0)
+ last += hislen;
+ }
+ if (--i < 0)
+ i += hislen;
+ } while (i != idx);
+ if (history[histype][idx].hisstr == NULL)
+ hisidx[histype] = -1;
+ }
+ vim_regfree(regmatch.regprog);
+ return found;
+}
+
+/*
+ * Remove an indexed entry from a history.
+ * "histype" may be one of the HIST_ values.
+ */
+int del_history_idx(histype, idx)
+int histype;
+int idx;
+{
+ int i, j;
+
+ i = calc_hist_idx(histype, idx);
+ if (i < 0)
+ return FALSE;
+ idx = hisidx[histype];
+ vim_free(history[histype][i].hisstr);
+
+ /* When deleting the last added search string in a mapping, reset
+ * last_maptick, so that the last added search string isn't deleted again.
+ */
+ if (histype == HIST_SEARCH && maptick == last_maptick && i == idx)
+ last_maptick = -1;
+
+ while (i != idx) {
+ j = (i + 1) % hislen;
+ history[histype][i] = history[histype][j];
+ i = j;
+ }
+ clear_hist_entry(&history[histype][i]);
+ if (--i < 0)
+ i += hislen;
+ hisidx[histype] = i;
+ return TRUE;
+}
+
+
+/*
+ * Very specific function to remove the value in ":set key=val" from the
+ * history.
+ */
+void remove_key_from_history() {
+ char_u *p;
+ int i;
+
+ i = hisidx[HIST_CMD];
+ if (i < 0)
+ return;
+ p = history[HIST_CMD][i].hisstr;
+ if (p != NULL)
+ for (; *p; ++p)
+ if (STRNCMP(p, "key", 3) == 0 && !isalpha(p[3])) {
+ p = vim_strchr(p + 3, '=');
+ if (p == NULL)
+ break;
+ ++p;
+ for (i = 0; p[i] && !vim_iswhite(p[i]); ++i)
+ if (p[i] == '\\' && p[i + 1])
+ ++i;
+ STRMOVE(p, p + i);
+ --p;
+ }
+}
+
+/*
+ * Get indices "num1,num2" that specify a range within a list (not a range of
+ * text lines in a buffer!) from a string. Used for ":history" and ":clist".
+ * Returns OK if parsed successfully, otherwise FAIL.
+ */
+int get_list_range(str, num1, num2)
+char_u **str;
+int *num1;
+int *num2;
+{
+ int len;
+ int first = FALSE;
+ long num;
+
+ *str = skipwhite(*str);
+ if (**str == '-' || vim_isdigit(**str)) { /* parse "from" part of range */
+ vim_str2nr(*str, NULL, &len, FALSE, FALSE, &num, NULL);
+ *str += len;
+ *num1 = (int)num;
+ first = TRUE;
+ }
+ *str = skipwhite(*str);
+ if (**str == ',') { /* parse "to" part of range */
+ *str = skipwhite(*str + 1);
+ vim_str2nr(*str, NULL, &len, FALSE, FALSE, &num, NULL);
+ if (len > 0) {
+ *num2 = (int)num;
+ *str = skipwhite(*str + len);
+ } else if (!first) /* no number given at all */
+ return FAIL;
+ } else if (first) /* only one number given */
+ *num2 = *num1;
+ return OK;
+}
+
+/*
+ * :history command - print a history
+ */
+void ex_history(eap)
+exarg_T *eap;
+{
+ histentry_T *hist;
+ int histype1 = HIST_CMD;
+ int histype2 = HIST_CMD;
+ int hisidx1 = 1;
+ int hisidx2 = -1;
+ int idx;
+ int i, j, k;
+ char_u *end;
+ char_u *arg = eap->arg;
+
+ if (hislen == 0) {
+ MSG(_("'history' option is zero"));
+ return;
+ }
+
+ if (!(VIM_ISDIGIT(*arg) || *arg == '-' || *arg == ',')) {
+ end = arg;
+ while (ASCII_ISALPHA(*end)
+ || vim_strchr((char_u *)":=@>/?", *end) != NULL)
+ end++;
+ i = *end;
+ *end = NUL;
+ histype1 = get_histtype(arg);
+ if (histype1 == -1) {
+ if (STRNICMP(arg, "all", STRLEN(arg)) == 0) {
+ histype1 = 0;
+ histype2 = HIST_COUNT-1;
+ } else {
+ *end = i;
+ EMSG(_(e_trailing));
+ return;
+ }
+ } else
+ histype2 = histype1;
+ *end = i;
+ } else
+ end = arg;
+ if (!get_list_range(&end, &hisidx1, &hisidx2) || *end != NUL) {
+ EMSG(_(e_trailing));
+ return;
+ }
+
+ for (; !got_int && histype1 <= histype2; ++histype1) {
+ STRCPY(IObuff, "\n # ");
+ STRCAT(STRCAT(IObuff, history_names[histype1]), " history");
+ MSG_PUTS_TITLE(IObuff);
+ idx = hisidx[histype1];
+ hist = history[histype1];
+ j = hisidx1;
+ k = hisidx2;
+ if (j < 0)
+ j = (-j > hislen) ? 0 : hist[(hislen+j+idx+1) % hislen].hisnum;
+ if (k < 0)
+ k = (-k > hislen) ? 0 : hist[(hislen+k+idx+1) % hislen].hisnum;
+ if (idx >= 0 && j <= k)
+ for (i = idx + 1; !got_int; ++i) {
+ if (i == hislen)
+ i = 0;
+ if (hist[i].hisstr != NULL
+ && hist[i].hisnum >= j && hist[i].hisnum <= k) {
+ msg_putchar('\n');
+ sprintf((char *)IObuff, "%c%6d ", i == idx ? '>' : ' ',
+ hist[i].hisnum);
+ if (vim_strsize(hist[i].hisstr) > (int)Columns - 10)
+ trunc_string(hist[i].hisstr, IObuff + STRLEN(IObuff),
+ (int)Columns - 10, IOSIZE - (int)STRLEN(IObuff));
+ else
+ STRCAT(IObuff, hist[i].hisstr);
+ msg_outtrans(IObuff);
+ out_flush();
+ }
+ if (i == idx)
+ break;
+ }
+ }
+}
+
+/*
+ * Buffers for history read from a viminfo file. Only valid while reading.
+ */
+static char_u **viminfo_history[HIST_COUNT] = {NULL, NULL, NULL, NULL};
+static int viminfo_hisidx[HIST_COUNT] = {0, 0, 0, 0};
+static int viminfo_hislen[HIST_COUNT] = {0, 0, 0, 0};
+static int viminfo_add_at_front = FALSE;
+
+static int hist_type2char __ARGS((int type, int use_question));
+
+/*
+ * Translate a history type number to the associated character.
+ */
+static int hist_type2char(type, use_question)
+int type;
+int use_question; /* use '?' instead of '/' */
+{
+ if (type == HIST_CMD)
+ return ':';
+ if (type == HIST_SEARCH) {
+ if (use_question)
+ return '?';
+ else
+ return '/';
+ }
+ if (type == HIST_EXPR)
+ return '=';
+ return '@';
+}
+
+/*
+ * Prepare for reading the history from the viminfo file.
+ * This allocates history arrays to store the read history lines.
+ */
+void prepare_viminfo_history(asklen, writing)
+int asklen;
+int writing;
+{
+ int i;
+ int num;
+ int type;
+ int len;
+
+ init_history();
+ viminfo_add_at_front = (asklen != 0 && !writing);
+ if (asklen > hislen)
+ asklen = hislen;
+
+ for (type = 0; type < HIST_COUNT; ++type) {
+ /* Count the number of empty spaces in the history list. Entries read
+ * from viminfo previously are also considered empty. If there are
+ * more spaces available than we request, then fill them up. */
+ for (i = 0, num = 0; i < hislen; i++)
+ if (history[type][i].hisstr == NULL || history[type][i].viminfo)
+ num++;
+ len = asklen;
+ if (num > len)
+ len = num;
+ if (len <= 0)
+ viminfo_history[type] = NULL;
+ else
+ viminfo_history[type] =
+ (char_u **)lalloc((long_u)(len * sizeof(char_u *)), FALSE);
+ if (viminfo_history[type] == NULL)
+ len = 0;
+ viminfo_hislen[type] = len;
+ viminfo_hisidx[type] = 0;
+ }
+}
+
+/*
+ * Accept a line from the viminfo, store it in the history array when it's
+ * new.
+ */
+int read_viminfo_history(virp, writing)
+vir_T *virp;
+int writing;
+{
+ int type;
+ long_u len;
+ char_u *val;
+ char_u *p;
+
+ type = hist_char2type(virp->vir_line[0]);
+ if (viminfo_hisidx[type] < viminfo_hislen[type]) {
+ val = viminfo_readstring(virp, 1, TRUE);
+ if (val != NULL && *val != NUL) {
+ int sep = (*val == ' ' ? NUL : *val);
+
+ if (!in_history(type, val + (type == HIST_SEARCH),
+ viminfo_add_at_front, sep, writing)) {
+ /* Need to re-allocate to append the separator byte. */
+ len = STRLEN(val);
+ p = lalloc(len + 2, TRUE);
+ if (p != NULL) {
+ if (type == HIST_SEARCH) {
+ /* Search entry: Move the separator from the first
+ * column to after the NUL. */
+ mch_memmove(p, val + 1, (size_t)len);
+ p[len] = sep;
+ } else {
+ /* Not a search entry: No separator in the viminfo
+ * file, add a NUL separator. */
+ mch_memmove(p, val, (size_t)len + 1);
+ p[len + 1] = NUL;
+ }
+ viminfo_history[type][viminfo_hisidx[type]++] = p;
+ }
+ }
+ }
+ vim_free(val);
+ }
+ return viminfo_readline(virp);
+}
+
+/*
+ * Finish reading history lines from viminfo. Not used when writing viminfo.
+ */
+void finish_viminfo_history() {
+ int idx;
+ int i;
+ int type;
+
+ for (type = 0; type < HIST_COUNT; ++type) {
+ if (history[type] == NULL)
+ continue;
+ idx = hisidx[type] + viminfo_hisidx[type];
+ if (idx >= hislen)
+ idx -= hislen;
+ else if (idx < 0)
+ idx = hislen - 1;
+ if (viminfo_add_at_front)
+ hisidx[type] = idx;
+ else {
+ if (hisidx[type] == -1)
+ hisidx[type] = hislen - 1;
+ do {
+ if (history[type][idx].hisstr != NULL
+ || history[type][idx].viminfo)
+ break;
+ if (++idx == hislen)
+ idx = 0;
+ } while (idx != hisidx[type]);
+ if (idx != hisidx[type] && --idx < 0)
+ idx = hislen - 1;
+ }
+ for (i = 0; i < viminfo_hisidx[type]; i++) {
+ vim_free(history[type][idx].hisstr);
+ history[type][idx].hisstr = viminfo_history[type][i];
+ history[type][idx].viminfo = TRUE;
+ if (--idx < 0)
+ idx = hislen - 1;
+ }
+ idx += 1;
+ idx %= hislen;
+ for (i = 0; i < viminfo_hisidx[type]; i++) {
+ history[type][idx++].hisnum = ++hisnum[type];
+ idx %= hislen;
+ }
+ vim_free(viminfo_history[type]);
+ viminfo_history[type] = NULL;
+ viminfo_hisidx[type] = 0;
+ }
+}
+
+/*
+ * Write history to viminfo file in "fp".
+ * When "merge" is TRUE merge history lines with a previously read viminfo
+ * file, data is in viminfo_history[].
+ * When "merge" is FALSE just write all history lines. Used for ":wviminfo!".
+ */
+void write_viminfo_history(fp, merge)
+FILE *fp;
+int merge;
+{
+ int i;
+ int type;
+ int num_saved;
+ char_u *p;
+ int c;
+ int round;
+
+ init_history();
+ if (hislen == 0)
+ return;
+ for (type = 0; type < HIST_COUNT; ++type) {
+ num_saved = get_viminfo_parameter(hist_type2char(type, FALSE));
+ if (num_saved == 0)
+ continue;
+ if (num_saved < 0) /* Use default */
+ num_saved = hislen;
+ fprintf(fp, _("\n# %s History (newest to oldest):\n"),
+ type == HIST_CMD ? _("Command Line") :
+ type == HIST_SEARCH ? _("Search String") :
+ type == HIST_EXPR ? _("Expression") :
+ _("Input Line"));
+ if (num_saved > hislen)
+ num_saved = hislen;
+
+ /*
+ * Merge typed and viminfo history:
+ * round 1: history of typed commands.
+ * round 2: history from recently read viminfo.
+ */
+ for (round = 1; round <= 2; ++round) {
+ if (round == 1)
+ /* start at newest entry, somewhere in the list */
+ i = hisidx[type];
+ else if (viminfo_hisidx[type] > 0)
+ /* start at newest entry, first in the list */
+ i = 0;
+ else
+ /* empty list */
+ i = -1;
+ if (i >= 0)
+ while (num_saved > 0
+ && !(round == 2 && i >= viminfo_hisidx[type])) {
+ p = round == 1 ? history[type][i].hisstr
+ : viminfo_history[type] == NULL ? NULL
+ : viminfo_history[type][i];
+ if (p != NULL && (round == 2
+ || !merge
+ || !history[type][i].viminfo)) {
+ --num_saved;
+ fputc(hist_type2char(type, TRUE), fp);
+ /* For the search history: put the separator in the
+ * second column; use a space if there isn't one. */
+ if (type == HIST_SEARCH) {
+ c = p[STRLEN(p) + 1];
+ putc(c == NUL ? ' ' : c, fp);
+ }
+ viminfo_writestring(fp, p);
+ }
+ if (round == 1) {
+ /* Decrement index, loop around and stop when back at
+ * the start. */
+ if (--i < 0)
+ i = hislen - 1;
+ if (i == hisidx[type])
+ break;
+ } else {
+ /* Increment index. Stop at the end in the while. */
+ ++i;
+ }
+ }
+ }
+ for (i = 0; i < viminfo_hisidx[type]; ++i)
+ if (viminfo_history[type] != NULL)
+ vim_free(viminfo_history[type][i]);
+ vim_free(viminfo_history[type]);
+ viminfo_history[type] = NULL;
+ viminfo_hisidx[type] = 0;
+ }
+}
+
+/*
+ * Write a character at the current cursor+offset position.
+ * It is directly written into the command buffer block.
+ */
+void cmd_pchar(c, offset)
+int c, offset;
+{
+ if (ccline.cmdpos + offset >= ccline.cmdlen || ccline.cmdpos + offset < 0) {
+ EMSG(_("E198: cmd_pchar beyond the command length"));
+ return;
+ }
+ ccline.cmdbuff[ccline.cmdpos + offset] = (char_u)c;
+ ccline.cmdbuff[ccline.cmdlen] = NUL;
+}
+
+int cmd_gchar(offset)
+int offset;
+{
+ if (ccline.cmdpos + offset >= ccline.cmdlen || ccline.cmdpos + offset < 0) {
+ /* EMSG(_("cmd_gchar beyond the command length")); */
+ return NUL;
+ }
+ return (int)ccline.cmdbuff[ccline.cmdpos + offset];
+}
+
+/*
+ * Open a window on the current command line and history. Allow editing in
+ * the window. Returns when the window is closed.
+ * Returns:
+ * CR if the command is to be executed
+ * Ctrl_C if it is to be abandoned
+ * K_IGNORE if editing continues
+ */
+static int ex_window() {
+ struct cmdline_info save_ccline;
+ buf_T *old_curbuf = curbuf;
+ win_T *old_curwin = curwin;
+ buf_T *bp;
+ win_T *wp;
+ int i;
+ linenr_T lnum;
+ int histtype;
+ garray_T winsizes;
+ char_u typestr[2];
+ int save_restart_edit = restart_edit;
+ int save_State = State;
+ int save_exmode = exmode_active;
+ int save_cmdmsg_rl = cmdmsg_rl;
+
+ /* Can't do this recursively. Can't do it when typing a password. */
+ if (cmdwin_type != 0
+ || cmdline_star > 0
+ ) {
+ beep_flush();
+ return K_IGNORE;
+ }
+
+ /* Save current window sizes. */
+ win_size_save(&winsizes);
+
+ /* Don't execute autocommands while creating the window. */
+ block_autocmds();
+ /* don't use a new tab page */
+ cmdmod.tab = 0;
+
+ /* Create a window for the command-line buffer. */
+ if (win_split((int)p_cwh, WSP_BOT) == FAIL) {
+ beep_flush();
+ unblock_autocmds();
+ return K_IGNORE;
+ }
+ cmdwin_type = get_cmdline_type();
+
+ /* 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;
+ curwin->w_p_rl = cmdmsg_rl;
+ cmdmsg_rl = FALSE;
+ RESET_BINDING(curwin);
+
+ /* Do execute autocommands for setting the filetype (load syntax). */
+ unblock_autocmds();
+
+ /* Showing the prompt may have set need_wait_return, reset it. */
+ need_wait_return = FALSE;
+
+ histtype = hist_char2type(cmdwin_type);
+ if (histtype == HIST_CMD || histtype == HIST_DEBUG) {
+ if (p_wc == TAB) {
+ add_map((char_u *)"<buffer> <Tab> <C-X><C-V>", INSERT);
+ add_map((char_u *)"<buffer> <Tab> a<C-X><C-V>", NORMAL);
+ }
+ set_option_value((char_u *)"ft", 0L, (char_u *)"vim", OPT_LOCAL);
+ }
+
+ /* Reset 'textwidth' after setting 'filetype' (the Vim filetype plugin
+ * sets 'textwidth' to 78). */
+ curbuf->b_p_tw = 0;
+
+ /* Fill the buffer with the history. */
+ init_history();
+ if (hislen > 0) {
+ i = hisidx[histtype];
+ if (i >= 0) {
+ lnum = 0;
+ do {
+ if (++i == hislen)
+ i = 0;
+ if (history[histtype][i].hisstr != NULL)
+ ml_append(lnum++, history[histtype][i].hisstr,
+ (colnr_T)0, FALSE);
+ } while (i != hisidx[histtype]);
+ }
+ }
+
+ /* 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);
+ curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
+ curwin->w_cursor.col = ccline.cmdpos;
+ changed_line_abv_curs();
+ invalidate_botline();
+ redraw_later(SOME_VALID);
+
+ /* Save the command line info, can be used recursively. */
+ save_ccline = ccline;
+ ccline.cmdbuff = NULL;
+ ccline.cmdprompt = NULL;
+
+ /* No Ex mode here! */
+ exmode_active = 0;
+
+ State = NORMAL;
+ setmouse();
+
+ /* Trigger CmdwinEnter autocommands. */
+ typestr[0] = cmdwin_type;
+ typestr[1] = NUL;
+ apply_autocmds(EVENT_CMDWINENTER, typestr, typestr, FALSE, curbuf);
+ if (restart_edit != 0) /* autocmd with ":startinsert" */
+ stuffcharReadbuff(K_NOP);
+
+ i = RedrawingDisabled;
+ RedrawingDisabled = 0;
+
+ /*
+ * Call the main loop until <CR> or CTRL-C is typed.
+ */
+ cmdwin_result = 0;
+ main_loop(TRUE, FALSE);
+
+ RedrawingDisabled = i;
+
+ /* Trigger CmdwinLeave autocommands. */
+ apply_autocmds(EVENT_CMDWINLEAVE, typestr, typestr, FALSE, curbuf);
+
+ /* Restore the command line info. */
+ ccline = save_ccline;
+ cmdwin_type = 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)) {
+ cmdwin_result = Ctrl_C;
+ EMSG(_("E199: Active window or buffer deleted"));
+ } else {
+ /* autocmds may abort script processing */
+ if (aborting() && cmdwin_result != K_IGNORE)
+ cmdwin_result = Ctrl_C;
+ /* Set the new command line from the cmdline buffer. */
+ vim_free(ccline.cmdbuff);
+ if (cmdwin_result == K_XF1 || cmdwin_result == K_XF2) { /* :qa[!] typed */
+ char *p = (cmdwin_result == K_XF2) ? "qa" : "qa!";
+
+ if (histtype == HIST_CMD) {
+ /* Execute the command directly. */
+ ccline.cmdbuff = vim_strsave((char_u *)p);
+ cmdwin_result = CAR;
+ } else {
+ /* First need to cancel what we were doing. */
+ ccline.cmdbuff = NULL;
+ stuffcharReadbuff(':');
+ stuffReadbuff((char_u *)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(ml_get_curline());
+ if (ccline.cmdbuff == NULL)
+ cmdwin_result = Ctrl_C;
+ else {
+ ccline.cmdlen = (int)STRLEN(ccline.cmdbuff);
+ ccline.cmdbufflen = ccline.cmdlen + 1;
+ ccline.cmdpos = curwin->w_cursor.col;
+ if (ccline.cmdpos > ccline.cmdlen)
+ ccline.cmdpos = ccline.cmdlen;
+ if (cmdwin_result == K_IGNORE) {
+ set_cmdspos_cursor();
+ redrawcmd();
+ }
+ }
+
+ /* Don't execute autocommands while deleting the window. */
+ block_autocmds();
+ wp = curwin;
+ bp = curbuf;
+ win_goto(old_curwin);
+ 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);
+
+ /* Restore window sizes. */
+ win_size_restore(&winsizes);
+
+ unblock_autocmds();
+ }
+
+ ga_clear(&winsizes);
+ restart_edit = save_restart_edit;
+ cmdmsg_rl = save_cmdmsg_rl;
+
+ State = save_State;
+ setmouse();
+
+ 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(eap, cmd)
+exarg_T *eap;
+char_u *cmd;
+{
+ char_u *theline;
+ char *end_pattern = NULL;
+ char dot[] = ".";
+ garray_T ga;
+
+ if (cmd[0] != '<' || cmd[1] != '<' || eap->getline == NULL)
+ return NULL;
+
+ ga_init2(&ga, 1, 0x400);
+
+ if (cmd[2] != NUL)
+ end_pattern = (char *)skipwhite(cmd + 2);
+ else
+ end_pattern = dot;
+
+ for (;; ) {
+ theline = eap->getline(
+ eap->cstack->cs_looplevel > 0 ? -1 :
+ NUL, eap->cookie, 0);
+
+ if (theline == NULL || STRCMP(end_pattern, theline) == 0) {
+ vim_free(theline);
+ break;
+ }
+
+ ga_concat(&ga, theline);
+ ga_append(&ga, '\n');
+ vim_free(theline);
+ }
+ ga_append(&ga, NUL);
+
+ return (char_u *)ga.ga_data;
+}
diff --git a/src/farsi.c b/src/farsi.c
new file mode 100644
index 0000000000..a76f37fd26
--- /dev/null
+++ b/src/farsi.c
@@ -0,0 +1,2183 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * 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.
+ */
+
+/*
+ * farsi.c: functions for Farsi language
+ *
+ * Included by main.c, when FEAT_FKMAP is defined.
+ */
+
+static int toF_Xor_X_ __ARGS((int c));
+static int F_is_TyE __ARGS((int c));
+static int F_is_TyC_TyD __ARGS((int c));
+static int F_is_TyB_TyC_TyD __ARGS((int src, int offset));
+static int toF_TyB __ARGS((int c));
+static void put_curr_and_l_to_X __ARGS((int c));
+static void put_and_redo __ARGS((int c));
+static void chg_c_toX_orX __ARGS((void));
+static void chg_c_to_X_orX_ __ARGS((void));
+static void chg_c_to_X_or_X __ARGS((void));
+static void chg_l_to_X_orX_ __ARGS((void));
+static void chg_l_toXor_X __ARGS((void));
+static void chg_r_to_Xor_X_ __ARGS((void));
+static int toF_leading __ARGS((int c));
+static int toF_Rjoin __ARGS((int c));
+static int canF_Ljoin __ARGS((int c));
+static int canF_Rjoin __ARGS((int c));
+static int F_isterm __ARGS((int c));
+static int toF_ending __ARGS((int c));
+static void lrswapbuf __ARGS((char_u *buf, int len));
+
+/*
+** Convert the given Farsi character into a _X or _X_ type
+*/
+static int toF_Xor_X_(c)
+int c;
+{
+ int tempc;
+
+ switch (c) {
+ case BE:
+ return _BE;
+ case PE:
+ return _PE;
+ case TE:
+ return _TE;
+ case SE:
+ return _SE;
+ case JIM:
+ return _JIM;
+ case CHE:
+ return _CHE;
+ case HE_J:
+ return _HE_J;
+ case XE:
+ return _XE;
+ case SIN:
+ return _SIN;
+ case SHIN:
+ return _SHIN;
+ case SAD:
+ return _SAD;
+ case ZAD:
+ return _ZAD;
+ case AYN:
+ return _AYN;
+ case AYN_:
+ return _AYN_;
+ case GHAYN:
+ return _GHAYN;
+ case GHAYN_:
+ return _GHAYN_;
+ case FE:
+ return _FE;
+ case GHAF:
+ return _GHAF;
+ case KAF:
+ return _KAF;
+ case GAF:
+ return _GAF;
+ case LAM:
+ return _LAM;
+ case MIM:
+ return _MIM;
+ case NOON:
+ return _NOON;
+ case YE:
+ case YE_:
+ return _YE;
+ case YEE:
+ case YEE_:
+ return _YEE;
+ case IE:
+ case IE_:
+ return _IE;
+ case F_HE:
+ tempc = _HE;
+
+ if (p_ri && (curwin->w_cursor.col + 1
+ < (colnr_T)STRLEN(ml_get_curline()))) {
+ inc_cursor();
+
+ if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))
+ tempc = _HE_;
+
+ dec_cursor();
+ }
+ if (!p_ri && STRLEN(ml_get_curline())) {
+ dec_cursor();
+
+ if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))
+ tempc = _HE_;
+
+ inc_cursor();
+ }
+
+ return tempc;
+ }
+ return 0;
+}
+
+/*
+** Convert the given Farsi character into Farsi capital character .
+*/
+int toF_TyA(c)
+int c;
+{
+ switch (c) {
+ case ALEF_:
+ return ALEF;
+ case ALEF_U_H_:
+ return ALEF_U_H;
+ case _BE:
+ return BE;
+ case _PE:
+ return PE;
+ case _TE:
+ return TE;
+ case _SE:
+ return SE;
+ case _JIM:
+ return JIM;
+ case _CHE:
+ return CHE;
+ case _HE_J:
+ return HE_J;
+ case _XE:
+ return XE;
+ case _SIN:
+ return SIN;
+ case _SHIN:
+ return SHIN;
+ case _SAD:
+ return SAD;
+ case _ZAD:
+ return ZAD;
+ case _AYN:
+ case AYN_:
+ case _AYN_:
+ return AYN;
+ case _GHAYN:
+ case GHAYN_:
+ case _GHAYN_:
+ return GHAYN;
+ case _FE:
+ return FE;
+ case _GHAF:
+ return GHAF;
+ /* I am not sure what it is !!! case _KAF_H: */
+ case _KAF:
+ return KAF;
+ case _GAF:
+ return GAF;
+ case _LAM:
+ return LAM;
+ case _MIM:
+ return MIM;
+ case _NOON:
+ return NOON;
+ case _YE:
+ case YE_:
+ return YE;
+ case _YEE:
+ case YEE_:
+ return YEE;
+ case TEE_:
+ return TEE;
+ case _IE:
+ case IE_:
+ return IE;
+ case _HE:
+ case _HE_:
+ return F_HE;
+ }
+ return c;
+}
+
+/*
+** Is the character under the cursor+offset in the given buffer a join type.
+** That is a character that is combined with the others.
+** Note: the offset is used only for command line buffer.
+*/
+static int F_is_TyB_TyC_TyD(src, offset)
+int src, offset;
+{
+ int c;
+
+ if (src == SRC_EDT)
+ c = gchar_cursor();
+ else
+ c = cmd_gchar(AT_CURSOR+offset);
+
+ switch (c) {
+ case _LAM:
+ 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 _TA:
+ case _ZA:
+ case _AYN:
+ case _AYN_:
+ case _GHAYN:
+ case _GHAYN_:
+ case _FE:
+ case _GHAF:
+ case _KAF:
+ case _KAF_H:
+ case _GAF:
+ case _MIM:
+ case _NOON:
+ case _YE:
+ case _YEE:
+ case _IE:
+ case _HE_:
+ case _HE:
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*
+** Is the Farsi character one of the terminating only type.
+*/
+static int F_is_TyE(c)
+int c;
+{
+ switch (c) {
+ case ALEF_A:
+ case ALEF_D_H:
+ case DAL:
+ case ZAL:
+ case RE:
+ case ZE:
+ case JE:
+ case WAW:
+ case WAW_H:
+ case HAMZE:
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*
+** Is the Farsi character one of the none leading type.
+*/
+static int F_is_TyC_TyD(c)
+int c;
+{
+ switch (c) {
+ case ALEF_:
+ case ALEF_U_H_:
+ case _AYN_:
+ case AYN_:
+ case _GHAYN_:
+ case GHAYN_:
+ case _HE_:
+ case YE_:
+ case IE_:
+ case TEE_:
+ case YEE_:
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*
+** Convert a none leading Farsi char into a leading type.
+*/
+static int toF_TyB(c)
+int c;
+{
+ switch (c) {
+ case ALEF_: return ALEF;
+ case ALEF_U_H_: return ALEF_U_H;
+ case _AYN_: return _AYN;
+ case AYN_: return AYN; /* exception - there are many of them */
+ case _GHAYN_: return _GHAYN;
+ case GHAYN_: return GHAYN; /* exception - there are many of them */
+ case _HE_: return _HE;
+ case YE_: return YE;
+ case IE_: return IE;
+ case TEE_: return TEE;
+ case YEE_: return YEE;
+ }
+ return c;
+}
+
+/*
+** Overwrite the current redo and cursor characters + left adjust
+*/
+static void put_curr_and_l_to_X(c)
+int c;
+{
+ int tempc;
+
+ if (curwin->w_p_rl && p_ri)
+ return;
+
+ if ((curwin->w_cursor.col < (colnr_T)STRLEN(ml_get_curline()))) {
+ if ((p_ri && curwin->w_cursor.col) || !p_ri) {
+ if (p_ri)
+ dec_cursor();
+ else
+ inc_cursor();
+
+ if (F_is_TyC_TyD((tempc = gchar_cursor()))) {
+ pchar_cursor(toF_TyB(tempc));
+ AppendCharToRedobuff(K_BS);
+ AppendCharToRedobuff(tempc);
+ }
+
+ if (p_ri)
+ inc_cursor();
+ else
+ dec_cursor();
+ }
+ }
+
+ put_and_redo(c);
+}
+
+static void put_and_redo(c)
+int c;
+{
+ pchar_cursor(c);
+ AppendCharToRedobuff(K_BS);
+ AppendCharToRedobuff(c);
+}
+
+/*
+** Change the char. under the cursor to a X_ or X type
+*/
+static void chg_c_toX_orX() {
+ int tempc, curc;
+
+ switch ((curc = gchar_cursor())) {
+ case _BE:
+ tempc = BE;
+ break;
+ case _PE:
+ tempc = PE;
+ break;
+ case _TE:
+ tempc = TE;
+ break;
+ case _SE:
+ tempc = SE;
+ break;
+ case _JIM:
+ tempc = JIM;
+ break;
+ case _CHE:
+ tempc = CHE;
+ break;
+ case _HE_J:
+ tempc = HE_J;
+ break;
+ case _XE:
+ tempc = XE;
+ break;
+ case _SIN:
+ tempc = SIN;
+ break;
+ case _SHIN:
+ tempc = SHIN;
+ break;
+ case _SAD:
+ tempc = SAD;
+ break;
+ case _ZAD:
+ tempc = ZAD;
+ break;
+ case _FE:
+ tempc = FE;
+ break;
+ case _GHAF:
+ tempc = GHAF;
+ break;
+ case _KAF_H:
+ case _KAF:
+ tempc = KAF;
+ break;
+ case _GAF:
+ tempc = GAF;
+ break;
+ case _AYN:
+ tempc = AYN;
+ break;
+ case _AYN_:
+ tempc = AYN_;
+ break;
+ case _GHAYN:
+ tempc = GHAYN;
+ break;
+ case _GHAYN_:
+ tempc = GHAYN_;
+ break;
+ case _LAM:
+ tempc = LAM;
+ break;
+ case _MIM:
+ tempc = MIM;
+ break;
+ case _NOON:
+ tempc = NOON;
+ break;
+ case _HE:
+ case _HE_:
+ tempc = F_HE;
+ break;
+ case _YE:
+ case _IE:
+ case _YEE:
+ if (p_ri) {
+ inc_cursor();
+ if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))
+ tempc = (curc == _YE ? YE_ :
+ (curc == _IE ? IE_ : YEE_));
+ else
+ tempc = (curc == _YE ? YE :
+ (curc == _IE ? IE : YEE));
+ dec_cursor();
+ } else {
+ if (curwin->w_cursor.col) {
+ dec_cursor();
+ if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))
+ tempc = (curc == _YE ? YE_ :
+ (curc == _IE ? IE_ : YEE_));
+ else
+ tempc = (curc == _YE ? YE :
+ (curc == _IE ? IE : YEE));
+ inc_cursor();
+ } else
+ tempc = (curc == _YE ? YE :
+ (curc == _IE ? IE : YEE));
+ }
+ break;
+ default:
+ tempc = 0;
+ }
+
+ if (tempc)
+ put_and_redo(tempc);
+}
+
+/*
+** Change the char. under the cursor to a _X_ or X_ type
+*/
+
+static void chg_c_to_X_orX_() {
+ int tempc;
+
+ switch (gchar_cursor()) {
+ case ALEF:
+ tempc = ALEF_;
+ break;
+ case ALEF_U_H:
+ tempc = ALEF_U_H_;
+ break;
+ case _AYN:
+ tempc = _AYN_;
+ break;
+ case AYN:
+ tempc = AYN_;
+ break;
+ case _GHAYN:
+ tempc = _GHAYN_;
+ break;
+ case GHAYN:
+ tempc = GHAYN_;
+ break;
+ case _HE:
+ tempc = _HE_;
+ break;
+ case YE:
+ tempc = YE_;
+ break;
+ case IE:
+ tempc = IE_;
+ break;
+ case TEE:
+ tempc = TEE_;
+ break;
+ case YEE:
+ tempc = YEE_;
+ break;
+ default:
+ tempc = 0;
+ }
+
+ if (tempc)
+ put_and_redo(tempc);
+}
+
+/*
+** Change the char. under the cursor to a _X_ or _X type
+*/
+static void chg_c_to_X_or_X () {
+ int tempc;
+
+ tempc = gchar_cursor();
+
+ if (curwin->w_cursor.col + 1 < (colnr_T)STRLEN(ml_get_curline())) {
+ inc_cursor();
+
+ if ((tempc == F_HE) && (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))) {
+ tempc = _HE_;
+
+ dec_cursor();
+
+ put_and_redo(tempc);
+ return;
+ }
+
+ dec_cursor();
+ }
+
+ if ((tempc = toF_Xor_X_(tempc)) != 0)
+ put_and_redo(tempc);
+}
+
+/*
+** Change the character left to the cursor to a _X_ or X_ type
+*/
+static void chg_l_to_X_orX_ () {
+ int tempc;
+
+ if (curwin->w_cursor.col != 0 &&
+ (curwin->w_cursor.col + 1 == (colnr_T)STRLEN(ml_get_curline())))
+ return;
+
+ if (!curwin->w_cursor.col && p_ri)
+ return;
+
+ if (p_ri)
+ dec_cursor();
+ else
+ inc_cursor();
+
+ switch (gchar_cursor()) {
+ case ALEF:
+ tempc = ALEF_;
+ break;
+ case ALEF_U_H:
+ tempc = ALEF_U_H_;
+ break;
+ case _AYN:
+ tempc = _AYN_;
+ break;
+ case AYN:
+ tempc = AYN_;
+ break;
+ case _GHAYN:
+ tempc = _GHAYN_;
+ break;
+ case GHAYN:
+ tempc = GHAYN_;
+ break;
+ case _HE:
+ tempc = _HE_;
+ break;
+ case YE:
+ tempc = YE_;
+ break;
+ case IE:
+ tempc = IE_;
+ break;
+ case TEE:
+ tempc = TEE_;
+ break;
+ case YEE:
+ tempc = YEE_;
+ break;
+ default:
+ tempc = 0;
+ }
+
+ if (tempc)
+ put_and_redo(tempc);
+
+ if (p_ri)
+ inc_cursor();
+ else
+ dec_cursor();
+}
+
+/*
+** Change the character left to the cursor to a X or _X type
+*/
+
+static void chg_l_toXor_X () {
+ int tempc;
+
+ if (curwin->w_cursor.col != 0 &&
+ (curwin->w_cursor.col + 1 == (colnr_T)STRLEN(ml_get_curline())))
+ return;
+
+ if (!curwin->w_cursor.col && p_ri)
+ return;
+
+ if (p_ri)
+ dec_cursor();
+ else
+ inc_cursor();
+
+ switch (gchar_cursor()) {
+ case ALEF_:
+ tempc = ALEF;
+ break;
+ case ALEF_U_H_:
+ tempc = ALEF_U_H;
+ break;
+ case _AYN_:
+ tempc = _AYN;
+ break;
+ case AYN_:
+ tempc = AYN;
+ break;
+ case _GHAYN_:
+ tempc = _GHAYN;
+ break;
+ case GHAYN_:
+ tempc = GHAYN;
+ break;
+ case _HE_:
+ tempc = _HE;
+ break;
+ case YE_:
+ tempc = YE;
+ break;
+ case IE_:
+ tempc = IE;
+ break;
+ case TEE_:
+ tempc = TEE;
+ break;
+ case YEE_:
+ tempc = YEE;
+ break;
+ default:
+ tempc = 0;
+ }
+
+ if (tempc)
+ put_and_redo(tempc);
+
+ if (p_ri)
+ inc_cursor();
+ else
+ dec_cursor();
+}
+
+/*
+** Change the character right to the cursor to a _X or _X_ type
+*/
+
+static void chg_r_to_Xor_X_() {
+ int tempc, c;
+
+ if (curwin->w_cursor.col) {
+ if (!p_ri)
+ dec_cursor();
+
+ tempc = gchar_cursor();
+
+ if ((c = toF_Xor_X_(tempc)) != 0)
+ put_and_redo(c);
+
+ if (!p_ri)
+ inc_cursor();
+
+ }
+}
+
+/*
+** Map Farsi keyboard when in fkmap mode.
+*/
+
+int fkmap(c)
+int c;
+{
+ int tempc;
+ static int revins;
+
+ if (IS_SPECIAL(c))
+ return c;
+
+ if (VIM_ISDIGIT(c) || ((c == '.' || c == '+' || c == '-' ||
+ c == '^' || c == '%' || c == '#' ||
+ c == '=') && revins)) {
+ 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();
+ }
+ }
+
+ arrow_used = TRUE;
+ (void)stop_arrow();
+
+ if (!curwin->w_p_rl && revins)
+ inc_cursor();
+
+ ++revins;
+ p_ri=1;
+ } else {
+ if (revins) {
+ 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)
+ 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 (!revins) {
+ if (curwin->w_p_rl)
+ p_ri=0;
+ if (!curwin->w_p_rl)
+ p_ri=1;
+ }
+
+ if ((c < 0x100) && (isalpha(c) || c == '&' || c == '^' || c == ';' ||
+ c == '\''|| c == ',' || c == '[' ||
+ c == ']' || c == '{' || c == '}' ))
+ chg_r_to_Xor_X_();
+
+ tempc = 0;
+
+ switch (c) {
+ case '`':
+ case ' ':
+ case '.':
+ case '!':
+ case '"':
+ case '$':
+ case '%':
+ case '^':
+ case '&':
+ case '/':
+ case '(':
+ case ')':
+ case '=':
+ case '\\':
+ case '?':
+ case '+':
+ case '-':
+ case '_':
+ case '*':
+ case ':':
+ case '#':
+ case '~':
+ case '@':
+ case '<':
+ case '>':
+ case '{':
+ case '}':
+ case '|':
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ case 'B':
+ case 'E':
+ case 'F':
+ case 'H':
+ case 'I':
+ case 'K':
+ case 'L':
+ case 'M':
+ case 'O':
+ case 'P':
+ case 'Q':
+ case 'R':
+ case 'T':
+ case 'U':
+ case 'W':
+ case 'Y':
+ case NL:
+ case TAB:
+
+ if (p_ri && c == NL && curwin->w_cursor.col) {
+ /*
+ ** If the char before the cursor is _X_ or X_ do not change
+ ** the one under the cursor with X type.
+ */
+
+ dec_cursor();
+
+ if (F_isalpha(gchar_cursor())) {
+ inc_cursor();
+ return NL;
+ }
+
+ inc_cursor();
+ }
+
+ if (!p_ri)
+ if (!curwin->w_cursor.col) {
+ switch (c) {
+ case '0': return FARSI_0;
+ case '1': return FARSI_1;
+ case '2': return FARSI_2;
+ case '3': return FARSI_3;
+ case '4': return FARSI_4;
+ case '5': return FARSI_5;
+ case '6': return FARSI_6;
+ case '7': return FARSI_7;
+ case '8': return FARSI_8;
+ case '9': return FARSI_9;
+ case 'B': return F_PSP;
+ case 'E': return JAZR_N;
+ case 'F': return ALEF_D_H;
+ case 'H': return ALEF_A;
+ case 'I': return TASH;
+ case 'K': return F_LQUOT;
+ case 'L': return F_RQUOT;
+ case 'M': return HAMZE;
+ case 'O': return '[';
+ case 'P': return ']';
+ case 'Q': return OO;
+ case 'R': return MAD_N;
+ case 'T': return OW;
+ case 'U': return MAD;
+ case 'W': return OW_OW;
+ case 'Y': return JAZR;
+ case '`': return F_PCN;
+ case '!': return F_EXCL;
+ case '@': return F_COMMA;
+ case '#': return F_DIVIDE;
+ case '$': return F_CURRENCY;
+ case '%': return F_PERCENT;
+ case '^': return F_MUL;
+ case '&': return F_BCOMMA;
+ case '*': return F_STAR;
+ case '(': return F_LPARENT;
+ case ')': return F_RPARENT;
+ case '-': return F_MINUS;
+ case '_': return F_UNDERLINE;
+ case '=': return F_EQUALS;
+ case '+': return F_PLUS;
+ case '\\': return F_BSLASH;
+ case '|': return F_PIPE;
+ case ':': return F_DCOLON;
+ case '"': return F_SEMICOLON;
+ case '.': return F_PERIOD;
+ case '/': return F_SLASH;
+ case '<': return F_LESS;
+ case '>': return F_GREATER;
+ case '?': return F_QUESTION;
+ case ' ': return F_BLANK;
+ }
+ break;
+ }
+ 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(tempc));
+ 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 (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))
+ tempc = AYN_;
+ else
+ tempc = AYN;
+
+ if (p_ri)
+ dec_cursor();
+ else
+ inc_cursor();
+
+ put_curr_and_l_to_X(tempc);
+
+ break;
+ case _GHAYN:
+ case _GHAYN_:
+
+ 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 (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))
+ tempc = GHAYN_;
+ else
+ tempc = GHAYN;
+
+ if (p_ri)
+ dec_cursor();
+ else
+ inc_cursor();
+
+ put_curr_and_l_to_X(tempc);
+ break;
+ 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)
+ 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 (p_ri)
+ dec_cursor();
+ else
+ inc_cursor();
+
+ put_curr_and_l_to_X(tempc);
+ break;
+ }
+
+ if (!p_ri)
+ inc_cursor();
+
+ tempc = 0;
+
+ switch (c) {
+ case '0': return FARSI_0;
+ case '1': return FARSI_1;
+ case '2': return FARSI_2;
+ case '3': return FARSI_3;
+ case '4': return FARSI_4;
+ case '5': return FARSI_5;
+ case '6': return FARSI_6;
+ case '7': return FARSI_7;
+ case '8': return FARSI_8;
+ case '9': return FARSI_9;
+ case 'B': return F_PSP;
+ case 'E': return JAZR_N;
+ case 'F': return ALEF_D_H;
+ case 'H': return ALEF_A;
+ case 'I': return TASH;
+ case 'K': return F_LQUOT;
+ case 'L': return F_RQUOT;
+ case 'M': return HAMZE;
+ case 'O': return '[';
+ case 'P': return ']';
+ case 'Q': return OO;
+ case 'R': return MAD_N;
+ case 'T': return OW;
+ case 'U': return MAD;
+ case 'W': return OW_OW;
+ case 'Y': return JAZR;
+ case '`': return F_PCN;
+ case '!': return F_EXCL;
+ case '@': return F_COMMA;
+ case '#': return F_DIVIDE;
+ case '$': return F_CURRENCY;
+ case '%': return F_PERCENT;
+ case '^': return F_MUL;
+ case '&': return F_BCOMMA;
+ case '*': return F_STAR;
+ case '(': return F_LPARENT;
+ case ')': return F_RPARENT;
+ case '-': return F_MINUS;
+ case '_': return F_UNDERLINE;
+ case '=': return F_EQUALS;
+ case '+': return F_PLUS;
+ case '\\': return F_BSLASH;
+ case '|': return F_PIPE;
+ case ':': return F_DCOLON;
+ case '"': return F_SEMICOLON;
+ case '.': return F_PERIOD;
+ case '/': return F_SLASH;
+ case '<': return F_LESS;
+ case '>': return F_GREATER;
+ case '?': return F_QUESTION;
+ case ' ': return F_BLANK;
+ }
+ break;
+
+ case 'a':
+ tempc = _SHIN;
+ break;
+ case 'A':
+ tempc = WAW_H;
+ break;
+ case 'b':
+ tempc = ZAL;
+ break;
+ case 'c':
+ tempc = ZE;
+ break;
+ case 'C':
+ tempc = JE;
+ break;
+ case 'd':
+ tempc = _YE;
+ break;
+ case 'D':
+ tempc = _YEE;
+ break;
+ case 'e':
+ tempc = _SE;
+ break;
+ case 'f':
+ tempc = _BE;
+ break;
+ case 'g':
+ tempc = _LAM;
+ break;
+ case 'G':
+ if (!curwin->w_cursor.col && STRLEN(ml_get_curline())) {
+
+ if (gchar_cursor() == _LAM)
+ chg_c_toX_orX ();
+ else if (p_ri)
+ chg_c_to_X_or_X ();
+ }
+
+ if (!p_ri)
+ if (!curwin->w_cursor.col)
+ return ALEF_U_H;
+
+ if (!p_ri)
+ dec_cursor();
+
+ if (gchar_cursor() == _LAM) {
+ chg_c_toX_orX ();
+ chg_l_toXor_X ();
+ tempc = ALEF_U_H;
+ } else if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR)) {
+ tempc = ALEF_U_H_;
+ chg_l_toXor_X ();
+ } else
+ tempc = ALEF_U_H;
+
+ if (!p_ri)
+ inc_cursor();
+
+ return tempc;
+ case 'h':
+ if (!curwin->w_cursor.col && STRLEN(ml_get_curline())) {
+ if (p_ri)
+ chg_c_to_X_or_X ();
+
+ }
+
+ if (!p_ri)
+ if (!curwin->w_cursor.col)
+ return ALEF;
+
+ if (!p_ri)
+ dec_cursor();
+
+ if (gchar_cursor() == _LAM) {
+ chg_l_toXor_X();
+ del_char(FALSE);
+ AppendCharToRedobuff(K_BS);
+
+ if (!p_ri)
+ dec_cursor();
+
+ tempc = LA;
+ } else {
+ if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR)) {
+ tempc = ALEF_;
+ chg_l_toXor_X ();
+ } else
+ tempc = ALEF;
+ }
+
+ if (!p_ri)
+ inc_cursor();
+
+ return tempc;
+ case 'i':
+ if (!curwin->w_cursor.col && STRLEN(ml_get_curline())) {
+ if (!p_ri && !F_is_TyE(tempc))
+ chg_c_to_X_orX_ ();
+ if (p_ri)
+ chg_c_to_X_or_X ();
+
+ }
+
+ if (!p_ri && !curwin->w_cursor.col)
+ return _HE;
+
+ if (!p_ri)
+ dec_cursor();
+
+ if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))
+ tempc = _HE_;
+ else
+ tempc = _HE;
+
+ if (!p_ri)
+ inc_cursor();
+ break;
+ case 'j':
+ tempc = _TE;
+ break;
+ case 'J':
+ if (!curwin->w_cursor.col && STRLEN(ml_get_curline())) {
+ if (p_ri)
+ chg_c_to_X_or_X ();
+
+ }
+
+ if (!p_ri)
+ if (!curwin->w_cursor.col)
+ return TEE;
+
+ if (!p_ri)
+ dec_cursor();
+
+ if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR)) {
+ tempc = TEE_;
+ chg_l_toXor_X ();
+ } else
+ tempc = TEE;
+
+ if (!p_ri)
+ inc_cursor();
+
+ return tempc;
+ case 'k':
+ tempc = _NOON;
+ break;
+ case 'l':
+ tempc = _MIM;
+ break;
+ case 'm':
+ tempc = _PE;
+ break;
+ case 'n':
+ case 'N':
+ tempc = DAL;
+ break;
+ case 'o':
+ tempc = _XE;
+ break;
+ case 'p':
+ tempc = _HE_J;
+ break;
+ case 'q':
+ tempc = _ZAD;
+ break;
+ case 'r':
+ tempc = _GHAF;
+ break;
+ case 's':
+ tempc = _SIN;
+ break;
+ case 'S':
+ tempc = _IE;
+ break;
+ case 't':
+ tempc = _FE;
+ break;
+ case 'u':
+ if (!curwin->w_cursor.col && STRLEN(ml_get_curline())) {
+ if (!p_ri && !F_is_TyE(tempc))
+ chg_c_to_X_orX_ ();
+ if (p_ri)
+ chg_c_to_X_or_X ();
+
+ }
+
+ if (!p_ri && !curwin->w_cursor.col)
+ return _AYN;
+
+ if (!p_ri)
+ dec_cursor();
+
+ if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))
+ tempc = _AYN_;
+ else
+ tempc = _AYN;
+
+ if (!p_ri)
+ inc_cursor();
+ break;
+ case 'v':
+ case 'V':
+ tempc = RE;
+ break;
+ case 'w':
+ tempc = _SAD;
+ break;
+ case 'x':
+ case 'X':
+ tempc = _TA;
+ break;
+ case 'y':
+ if (!curwin->w_cursor.col && STRLEN(ml_get_curline())) {
+ if (!p_ri && !F_is_TyE(tempc))
+ chg_c_to_X_orX_ ();
+ if (p_ri)
+ chg_c_to_X_or_X ();
+
+ }
+
+ if (!p_ri && !curwin->w_cursor.col)
+ return _GHAYN;
+
+ if (!p_ri)
+ dec_cursor();
+
+ if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))
+ tempc = _GHAYN_;
+ else
+ tempc = _GHAYN;
+
+ if (!p_ri)
+ inc_cursor();
+
+ break;
+ case 'z':
+ tempc = _ZA;
+ break;
+ case 'Z':
+ tempc = _KAF_H;
+ break;
+ case ';':
+ tempc = _KAF;
+ break;
+ case '\'':
+ tempc = _GAF;
+ break;
+ case ',':
+ tempc = WAW;
+ break;
+ case '[':
+ tempc = _JIM;
+ break;
+ case ']':
+ tempc = _CHE;
+ break;
+ }
+
+ if ((F_isalpha(tempc) || F_isdigit(tempc))) {
+ if (!curwin->w_cursor.col && STRLEN(ml_get_curline())) {
+ if (!p_ri && !F_is_TyE(tempc))
+ chg_c_to_X_orX_ ();
+ if (p_ri)
+ chg_c_to_X_or_X ();
+ }
+
+ if (curwin->w_cursor.col) {
+ if (!p_ri)
+ dec_cursor();
+
+ if (F_is_TyE(tempc))
+ chg_l_toXor_X ();
+ else
+ chg_l_to_X_orX_ ();
+
+ if (!p_ri)
+ inc_cursor();
+ }
+ }
+ if (tempc)
+ return tempc;
+ return c;
+}
+
+/*
+** Convert a none leading Farsi char into a leading type.
+*/
+static int toF_leading(c)
+int c;
+{
+ switch (c) {
+ case ALEF_: return ALEF;
+ case ALEF_U_H_: return ALEF_U_H;
+ case BE: return _BE;
+ case PE: return _PE;
+ case TE: return _TE;
+ case SE: return _SE;
+ case JIM: return _JIM;
+ case CHE: return _CHE;
+ case HE_J: return _HE_J;
+ case XE: return _XE;
+ case SIN: return _SIN;
+ case SHIN: return _SHIN;
+ case SAD: return _SAD;
+ case ZAD: return _ZAD;
+
+ case AYN:
+ case AYN_:
+ case _AYN_: return _AYN;
+
+ case GHAYN:
+ case GHAYN_:
+ case _GHAYN_: return _GHAYN;
+
+ case FE: return _FE;
+ case GHAF: return _GHAF;
+ case KAF: return _KAF;
+ case GAF: return _GAF;
+ case LAM: return _LAM;
+ case MIM: return _MIM;
+ case NOON: return _NOON;
+
+ case _HE_:
+ case F_HE: return _HE;
+
+ case YE:
+ case YE_: return _YE;
+
+ case IE_:
+ case IE: return _IE;
+
+ case YEE:
+ case YEE_: return _YEE;
+ }
+ return c;
+}
+
+/*
+** Convert a given Farsi char into right joining type.
+*/
+static int toF_Rjoin(c)
+int c;
+{
+ switch (c) {
+ case ALEF: return ALEF_;
+ case ALEF_U_H: return ALEF_U_H_;
+ case BE: return _BE;
+ case PE: return _PE;
+ case TE: return _TE;
+ case SE: return _SE;
+ case JIM: return _JIM;
+ case CHE: return _CHE;
+ case HE_J: return _HE_J;
+ case XE: return _XE;
+ case SIN: return _SIN;
+ case SHIN: return _SHIN;
+ case SAD: return _SAD;
+ case ZAD: return _ZAD;
+
+ case AYN:
+ case AYN_:
+ case _AYN: return _AYN_;
+
+ case GHAYN:
+ case GHAYN_:
+ case _GHAYN_: return _GHAYN_;
+
+ case FE: return _FE;
+ case GHAF: return _GHAF;
+ case KAF: return _KAF;
+ case GAF: return _GAF;
+ case LAM: return _LAM;
+ case MIM: return _MIM;
+ case NOON: return _NOON;
+
+ case _HE:
+ case F_HE: return _HE_;
+
+ case YE:
+ case YE_: return _YE;
+
+ case IE_:
+ case IE: return _IE;
+
+ case TEE: return TEE_;
+
+ case YEE:
+ case YEE_: return _YEE;
+ }
+ return c;
+}
+
+/*
+** Can a given Farsi character join via its left edj.
+*/
+static int canF_Ljoin(c)
+int c;
+{
+ switch (c) {
+ case _BE:
+ case BE:
+ case PE:
+ case _PE:
+ case TE:
+ case _TE:
+ case SE:
+ case _SE:
+ case JIM:
+ case _JIM:
+ case CHE:
+ case _CHE:
+ case HE_J:
+ case _HE_J:
+ case XE:
+ case _XE:
+ case SIN:
+ case _SIN:
+ case SHIN:
+ case _SHIN:
+ case SAD:
+ case _SAD:
+ case ZAD:
+ case _ZAD:
+ case _TA:
+ case _ZA:
+ case AYN:
+ case _AYN:
+ case _AYN_:
+ case AYN_:
+ case GHAYN:
+ case GHAYN_:
+ case _GHAYN_:
+ case _GHAYN:
+ case FE:
+ case _FE:
+ case GHAF:
+ case _GHAF:
+ case _KAF_H:
+ case KAF:
+ case _KAF:
+ case GAF:
+ case _GAF:
+ case LAM:
+ case _LAM:
+ case MIM:
+ case _MIM:
+ case NOON:
+ case _NOON:
+ case IE:
+ case _IE:
+ case IE_:
+ case YE:
+ case _YE:
+ case YE_:
+ case YEE:
+ case _YEE:
+ case YEE_:
+ case F_HE:
+ case _HE:
+ case _HE_:
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*
+** Can a given Farsi character join via its right edj.
+*/
+static int canF_Rjoin(c)
+int c;
+{
+ switch (c) {
+ case ALEF:
+ case ALEF_:
+ case ALEF_U_H:
+ case ALEF_U_H_:
+ case DAL:
+ case ZAL:
+ case RE:
+ case JE:
+ case ZE:
+ case TEE:
+ case TEE_:
+ case WAW:
+ case WAW_H:
+ return TRUE;
+ }
+
+ return canF_Ljoin(c);
+
+}
+
+/*
+** is a given Farsi character a terminating type.
+*/
+static int F_isterm(c)
+int c;
+{
+ switch (c) {
+ case ALEF:
+ case ALEF_:
+ case ALEF_U_H:
+ case ALEF_U_H_:
+ case DAL:
+ case ZAL:
+ case RE:
+ case JE:
+ case ZE:
+ case WAW:
+ case WAW_H:
+ case TEE:
+ case TEE_:
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/*
+** Convert the given Farsi character into a ending type .
+*/
+static int toF_ending(c)
+int c;
+{
+
+ switch (c) {
+ case _BE:
+ return BE;
+ case _PE:
+ return PE;
+ case _TE:
+ return TE;
+ case _SE:
+ return SE;
+ case _JIM:
+ return JIM;
+ case _CHE:
+ return CHE;
+ case _HE_J:
+ return HE_J;
+ case _XE:
+ return XE;
+ case _SIN:
+ return SIN;
+ case _SHIN:
+ return SHIN;
+ case _SAD:
+ return SAD;
+ case _ZAD:
+ return ZAD;
+ case _AYN:
+ return AYN;
+ case _AYN_:
+ return AYN_;
+ case _GHAYN:
+ return GHAYN;
+ case _GHAYN_:
+ return GHAYN_;
+ case _FE:
+ return FE;
+ case _GHAF:
+ return GHAF;
+ case _KAF_H:
+ case _KAF:
+ return KAF;
+ case _GAF:
+ return GAF;
+ case _LAM:
+ return LAM;
+ case _MIM:
+ return MIM;
+ case _NOON:
+ return NOON;
+ case _YE:
+ return YE_;
+ case YE_:
+ return YE;
+ case _YEE:
+ return YEE_;
+ case YEE_:
+ return YEE;
+ case TEE:
+ return TEE_;
+ case _IE:
+ return IE_;
+ case IE_:
+ return IE;
+ case _HE:
+ case _HE_:
+ return F_HE;
+ }
+ return c;
+}
+
+/*
+** Convert the Farsi 3342 standard into Farsi VIM.
+*/
+void conv_to_pvim() {
+ char_u *ptr;
+ int lnum, llen, i;
+
+ 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-1; i++) {
+ if (canF_Ljoin(ptr[i]) && canF_Rjoin(ptr[i+1])) {
+ ptr[i] = toF_leading(ptr[i]);
+ ++i;
+
+ while (canF_Rjoin(ptr[i]) && i < llen) {
+ ptr[i] = toF_Rjoin(ptr[i]);
+ if (F_isterm(ptr[i]) || !F_isalpha(ptr[i]))
+ break;
+ ++i;
+ }
+ if (!F_isalpha(ptr[i]) || !canF_Rjoin(ptr[i]))
+ ptr[i-1] = toF_ending(ptr[i-1]);
+ } else
+ ptr[i] = toF_TyA(ptr[i]);
+ }
+ }
+
+ /*
+ * Following lines contains Farsi encoded character.
+ */
+
+ do_cmdline_cmd((char_u *)"%s/\202\231/\232/g");
+ do_cmdline_cmd((char_u *)"%s/\201\231/\370\334/g");
+
+ /* Assume the screen has been messed up: clear it and redraw. */
+ redraw_later(CLEAR);
+ MSG_ATTR(farsi_text_1, hl_attr(HLF_S));
+}
+
+/*
+ * Convert the Farsi VIM into Farsi 3342 standard.
+ */
+void conv_to_pstd() {
+ char_u *ptr;
+ int lnum, llen, i;
+
+ /*
+ * Following line contains Farsi encoded character.
+ */
+
+ do_cmdline_cmd((char_u *)"%s/\232/\202\231/g");
+
+ 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++) {
+ ptr[i] = toF_TyA(ptr[i]);
+
+ }
+ }
+
+ /* Assume the screen has been messed up: clear it and redraw. */
+ redraw_later(CLEAR);
+ MSG_ATTR(farsi_text_2, hl_attr(HLF_S));
+}
+
+/*
+ * left-right swap the characters in buf[len].
+ */
+static void lrswapbuf(buf, len)
+char_u *buf;
+int len;
+{
+ char_u *s, *e;
+ int c;
+
+ s = buf;
+ e = buf + len - 1;
+
+ while (e > s) {
+ c = *s;
+ *s = *e;
+ *e = c;
+ ++s;
+ --e;
+ }
+}
+
+/*
+ * swap all the characters in reverse direction
+ */
+char_u * lrswap(ibuf)
+char_u *ibuf;
+{
+ if (ibuf != NULL && *ibuf != NUL)
+ lrswapbuf(ibuf, (int)STRLEN(ibuf));
+ return ibuf;
+}
+
+/*
+ * swap all the Farsi characters in reverse direction
+ */
+char_u * lrFswap(cmdbuf, len)
+char_u *cmdbuf;
+int len;
+{
+ int i, cnt;
+
+ if (cmdbuf == NULL)
+ return cmdbuf;
+
+ if (len == 0 && (len = (int)STRLEN(cmdbuf)) == 0)
+ return cmdbuf;
+
+ for (i = 0; i < len; i++) {
+ for (cnt = 0; i + cnt < len
+ && (F_isalpha(cmdbuf[i + cnt])
+ || F_isdigit(cmdbuf[i + cnt])
+ || cmdbuf[i + cnt] == ' '); ++cnt)
+ ;
+
+ lrswapbuf(cmdbuf + i, cnt);
+ i += cnt;
+ }
+ return cmdbuf;
+}
+
+/*
+ * Reverse the characters in the search path and substitute section
+ * accordingly.
+ * TODO: handle different separator characters. Use skip_regexp().
+ */
+char_u * lrF_sub(ibuf)
+char_u *ibuf;
+{
+ char_u *p, *ep;
+ int i, cnt;
+
+ p = ibuf;
+
+ /* Find the boundary of the search path */
+ while (((p = vim_strchr(p + 1, '/')) != NULL) && p[-1] == '\\')
+ ;
+
+ if (p == NULL)
+ return ibuf;
+
+ /* Reverse the Farsi characters in the search path. */
+ lrFswap(ibuf, (int)(p-ibuf));
+
+ /* Now find the boundary of the substitute section */
+ if ((ep = (char_u *)strrchr((char *)++p, '/')) != NULL)
+ cnt = (int)(ep - p);
+ else
+ cnt = (int)STRLEN(p);
+
+ /* Reverse the characters in the substitute section and take care of '\' */
+ for (i = 0; i < cnt-1; i++)
+ if (p[i] == '\\') {
+ p[i] = p[i+1];
+ p[++i] = '\\';
+ }
+
+ lrswapbuf(p, cnt);
+
+ return ibuf;
+}
+
+/*
+ * Map Farsi keyboard when in cmd_fkmap mode.
+ */
+int cmdl_fkmap(c)
+int c;
+{
+ int tempc;
+
+ switch (c) {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ case '`':
+ case ' ':
+ case '.':
+ case '!':
+ case '"':
+ case '$':
+ case '%':
+ case '^':
+ case '&':
+ case '/':
+ case '(':
+ case ')':
+ case '=':
+ case '\\':
+ case '?':
+ case '+':
+ case '-':
+ case '_':
+ case '*':
+ case ':':
+ case '#':
+ case '~':
+ case '@':
+ case '<':
+ case '>':
+ case '{':
+ case '}':
+ case '|':
+ case 'B':
+ case 'E':
+ case 'F':
+ case 'H':
+ case 'I':
+ case 'K':
+ case 'L':
+ case 'M':
+ case 'O':
+ case 'P':
+ case 'Q':
+ case 'R':
+ case 'T':
+ case 'U':
+ case 'W':
+ case 'Y':
+ case NL:
+ case TAB:
+
+ switch ((tempc = cmd_gchar(AT_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 _AYN:
+ case _GHAYN:
+ case _FE:
+ case _GHAF:
+ case _KAF:
+ case _GAF:
+ case _LAM:
+ case _MIM:
+ case _NOON:
+ case _HE:
+ case _HE_:
+ cmd_pchar(toF_TyA(tempc), AT_CURSOR);
+ break;
+ case _AYN_:
+ cmd_pchar(AYN_, AT_CURSOR);
+ break;
+ case _GHAYN_:
+ cmd_pchar(GHAYN_, AT_CURSOR);
+ break;
+ case _IE:
+ if (F_is_TyB_TyC_TyD(SRC_CMD, AT_CURSOR+1))
+ cmd_pchar(IE_, AT_CURSOR);
+ else
+ cmd_pchar(IE, AT_CURSOR);
+ break;
+ case _YEE:
+ if (F_is_TyB_TyC_TyD(SRC_CMD, AT_CURSOR+1))
+ cmd_pchar(YEE_, AT_CURSOR);
+ else
+ cmd_pchar(YEE, AT_CURSOR);
+ break;
+ case _YE:
+ if (F_is_TyB_TyC_TyD(SRC_CMD, AT_CURSOR+1))
+ cmd_pchar(YE_, AT_CURSOR);
+ else
+ cmd_pchar(YE, AT_CURSOR);
+ }
+
+ switch (c) {
+ case '0': return FARSI_0;
+ case '1': return FARSI_1;
+ case '2': return FARSI_2;
+ case '3': return FARSI_3;
+ case '4': return FARSI_4;
+ case '5': return FARSI_5;
+ case '6': return FARSI_6;
+ case '7': return FARSI_7;
+ case '8': return FARSI_8;
+ case '9': return FARSI_9;
+ case 'B': return F_PSP;
+ case 'E': return JAZR_N;
+ case 'F': return ALEF_D_H;
+ case 'H': return ALEF_A;
+ case 'I': return TASH;
+ case 'K': return F_LQUOT;
+ case 'L': return F_RQUOT;
+ case 'M': return HAMZE;
+ case 'O': return '[';
+ case 'P': return ']';
+ case 'Q': return OO;
+ case 'R': return MAD_N;
+ case 'T': return OW;
+ case 'U': return MAD;
+ case 'W': return OW_OW;
+ case 'Y': return JAZR;
+ case '`': return F_PCN;
+ case '!': return F_EXCL;
+ case '@': return F_COMMA;
+ case '#': return F_DIVIDE;
+ case '$': return F_CURRENCY;
+ case '%': return F_PERCENT;
+ case '^': return F_MUL;
+ case '&': return F_BCOMMA;
+ case '*': return F_STAR;
+ case '(': return F_LPARENT;
+ case ')': return F_RPARENT;
+ case '-': return F_MINUS;
+ case '_': return F_UNDERLINE;
+ case '=': return F_EQUALS;
+ case '+': return F_PLUS;
+ case '\\': return F_BSLASH;
+ case '|': return F_PIPE;
+ case ':': return F_DCOLON;
+ case '"': return F_SEMICOLON;
+ case '.': return F_PERIOD;
+ case '/': return F_SLASH;
+ case '<': return F_LESS;
+ case '>': return F_GREATER;
+ case '?': return F_QUESTION;
+ case ' ': return F_BLANK;
+ }
+
+ break;
+
+ case 'a': return _SHIN;
+ case 'A': return WAW_H;
+ case 'b': return ZAL;
+ case 'c': return ZE;
+ case 'C': return JE;
+ case 'd': return _YE;
+ case 'D': return _YEE;
+ case 'e': return _SE;
+ case 'f': return _BE;
+ case 'g': return _LAM;
+ case 'G':
+ if (cmd_gchar(AT_CURSOR) == _LAM ) {
+ cmd_pchar(LAM, AT_CURSOR);
+ return ALEF_U_H;
+ }
+
+ if (F_is_TyB_TyC_TyD(SRC_CMD, AT_CURSOR))
+ return ALEF_U_H_;
+ else
+ return ALEF_U_H;
+ case 'h':
+ if (cmd_gchar(AT_CURSOR) == _LAM ) {
+ cmd_pchar(LA, AT_CURSOR);
+ redrawcmdline();
+ return K_IGNORE;
+ }
+
+ if (F_is_TyB_TyC_TyD(SRC_CMD, AT_CURSOR))
+ return ALEF_;
+ else
+ return ALEF;
+ case 'i':
+ if (F_is_TyB_TyC_TyD(SRC_CMD, AT_CURSOR))
+ return _HE_;
+ else
+ return _HE;
+ case 'j': return _TE;
+ case 'J':
+ if (F_is_TyB_TyC_TyD(SRC_CMD, AT_CURSOR))
+ return TEE_;
+ else
+ return TEE;
+ case 'k': return _NOON;
+ case 'l': return _MIM;
+ case 'm': return _PE;
+ case 'n':
+ case 'N': return DAL;
+ case 'o': return _XE;
+ case 'p': return _HE_J;
+ case 'q': return _ZAD;
+ case 'r': return _GHAF;
+ case 's': return _SIN;
+ case 'S': return _IE;
+ case 't': return _FE;
+ case 'u':
+ if (F_is_TyB_TyC_TyD(SRC_CMD, AT_CURSOR))
+ return _AYN_;
+ else
+ return _AYN;
+ case 'v':
+ case 'V': return RE;
+ case 'w': return _SAD;
+ case 'x':
+ case 'X': return _TA;
+ case 'y':
+ if (F_is_TyB_TyC_TyD(SRC_CMD, AT_CURSOR))
+ return _GHAYN_;
+ else
+ return _GHAYN;
+ case 'z':
+ case 'Z': return _ZA;
+ case ';': return _KAF;
+ case '\'': return _GAF;
+ case ',': return WAW;
+ case '[': return _JIM;
+ case ']': return _CHE;
+ }
+
+ return c;
+}
+
+/*
+ * F_isalpha returns TRUE if 'c' is a Farsi alphabet
+ */
+int F_isalpha(c)
+int c;
+{
+ return ( c >= TEE_ && c <= _YE)
+ || (c >= ALEF_A && c <= YE)
+ || (c >= _IE && c <= YE_);
+}
+
+/*
+ * F_isdigit returns TRUE if 'c' is a Farsi digit
+ */
+int F_isdigit(c)
+int c;
+{
+ return c >= FARSI_0 && c <= FARSI_9;
+}
+
+/*
+ * F_ischar returns TRUE if 'c' is a Farsi character.
+ */
+int F_ischar(c)
+int c;
+{
+ return c >= TEE_ && c <= YE_;
+}
+
+void farsi_fkey(cap)
+cmdarg_T *cap;
+{
+ int c = cap->cmdchar;
+
+ if (c == K_F8) {
+ if (p_altkeymap) {
+ if (curwin->w_farsi & W_R_L) {
+ p_fkmap = 0;
+ do_cmdline_cmd((char_u *)"set norl");
+ MSG("");
+ } else {
+ p_fkmap = 1;
+ do_cmdline_cmd((char_u *)"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();
+ }
+ }
+}
diff --git a/src/farsi.h b/src/farsi.h
new file mode 100644
index 0000000000..a9dd2fb79f
--- /dev/null
+++ b/src/farsi.h
@@ -0,0 +1,226 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * 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.
+ */
+
+/*
+ * Farsi characters are categorized into following types:
+ *
+ * TyA (for capital letter representation)
+ * TyB (for types that look like _X e.g. AYN)
+ * TyC (for types that look like X_ e.g. YE_)
+ * TyD (for types that look like _X_ e.g. _AYN_)
+ * TyE (for types that look like X e.g. RE)
+ */
+
+/*
+ * Farsi character set definition
+ */
+
+/*
+ * Begin of the non-standard part
+ */
+
+#define TEE_ 0x80
+#define ALEF_U_H_ 0x81
+#define ALEF_ 0x82
+#define _BE 0x83
+#define _PE 0x84
+#define _TE 0x85
+#define _SE 0x86
+#define _JIM 0x87
+#define _CHE 0x88
+#define _HE_J 0x89
+#define _XE 0x8a
+#define _SIN 0x8b
+#define _SHIN 0x8c
+#define _SAD 0x8d
+#define _ZAD 0x8e
+#define _AYN 0x8f
+#define _AYN_ 0x90
+#define AYN_ 0x91
+#define _GHAYN 0x92
+#define _GHAYN_ 0x93
+#define GHAYN_ 0x94
+#define _FE 0x95
+#define _GHAF 0x96
+#define _KAF 0x97
+#define _GAF 0x98
+#define _LAM 0x99
+#define LA 0x9a
+#define _MIM 0x9b
+#define _NOON 0x9c
+#define _HE 0x9d
+#define _HE_ 0x9e
+#define _YE 0x9f
+#define _IE 0xec
+#define IE_ 0xed
+#define IE 0xfb
+#define _YEE 0xee
+#define YEE_ 0xef
+#define YE_ 0xff
+
+/*
+ * End of the non-standard part
+ */
+
+/*
+ * Standard part
+ */
+
+#define F_BLANK 0xa0 /* Farsi ' ' (SP) character */
+#define F_PSP 0xa1 /* PSP for capitalizing of a character */
+#define F_PCN 0xa2 /* PCN for redefining of the hamye meaning */
+#define F_EXCL 0xa3 /* Farsi ! character */
+#define F_CURRENCY 0xa4 /* Farsi Rial character */
+#define F_PERCENT 0xa5 /* Farsi % character */
+#define F_PERIOD 0xa6 /* Farsi '.' character */
+#define F_COMMA 0xa7 /* Farsi ',' character */
+#define F_LPARENT 0xa8 /* Farsi '(' character */
+#define F_RPARENT 0xa9 /* Farsi ')' character */
+#define F_MUL 0xaa /* Farsi 'x' character */
+#define F_PLUS 0xab /* Farsi '+' character */
+#define F_BCOMMA 0xac /* Farsi comma character */
+#define F_MINUS 0xad /* Farsi '-' character */
+#define F_DIVIDE 0xae /* Farsi divide (/) character */
+#define F_SLASH 0xaf /* Farsi '/' character */
+
+#define FARSI_0 0xb0
+#define FARSI_1 0xb1
+#define FARSI_2 0xb2
+#define FARSI_3 0xb3
+#define FARSI_4 0xb4
+#define FARSI_5 0xb5
+#define FARSI_6 0xb6
+#define FARSI_7 0xb7
+#define FARSI_8 0xb8
+#define FARSI_9 0xb9
+
+#define F_DCOLON 0xba /* Farsi ':' character */
+#define F_SEMICOLON 0xbb /* Farsi ';' character */
+#define F_GREATER 0xbc /* Farsi '>' character */
+#define F_EQUALS 0xbd /* Farsi '=' character */
+#define F_LESS 0xbe /* Farsi '<' character */
+#define F_QUESTION 0xbf /* Farsi ? character */
+
+#define ALEF_A 0xc0
+#define ALEF 0xc1
+#define HAMZE 0xc2
+#define BE 0xc3
+#define PE 0xc4
+#define TE 0xc5
+#define SE 0xc6
+#define JIM 0xc7
+#define CHE 0xc8
+#define HE_J 0xc9
+#define XE 0xca
+#define DAL 0xcb
+#define ZAL 0xcc
+#define RE 0xcd
+#define ZE 0xce
+#define JE 0xcf
+#define SIN 0xd0
+#define SHIN 0xd1
+#define SAD 0xd2
+#define ZAD 0xd3
+#define _TA 0xd4
+#define _ZA 0xd5
+#define AYN 0xd6
+#define GHAYN 0xd7
+#define FE 0xd8
+#define GHAF 0xd9
+#define KAF 0xda
+#define GAF 0xdb
+#define LAM 0xdc
+#define MIM 0xdd
+#define NOON 0xde
+#define WAW 0xdf
+#define F_HE 0xe0 /* F_ added for name clash with Perl */
+#define YE 0xe1
+#define TEE 0xfc
+#define _KAF_H 0xfd
+#define YEE 0xfe
+
+#define F_LBRACK 0xe2 /* Farsi '[' character */
+#define F_RBRACK 0xe3 /* Farsi ']' character */
+#define F_LBRACE 0xe4 /* Farsi '{' character */
+#define F_RBRACE 0xe5 /* Farsi '}' character */
+#define F_LQUOT 0xe6 /* Farsi left quotation character */
+#define F_RQUOT 0xe7 /* Farsi right quotation character */
+#define F_STAR 0xe8 /* Farsi '*' character */
+#define F_UNDERLINE 0xe9 /* Farsi '_' character */
+#define F_PIPE 0xea /* Farsi '|' character */
+#define F_BSLASH 0xeb /* Farsi '\' character */
+
+#define MAD 0xf0
+#define JAZR 0xf1
+#define OW 0xf2
+#define MAD_N 0xf3
+#define JAZR_N 0xf4
+#define OW_OW 0xf5
+#define TASH 0xf6
+#define OO 0xf7
+#define ALEF_U_H 0xf8
+#define WAW_H 0xf9
+#define ALEF_D_H 0xfa
+
+/*
+ * global definitions
+ * ==================
+ */
+
+#define SRC_EDT 0
+#define SRC_CMD 1
+
+#define AT_CURSOR 0
+
+/*
+ * definitions for the window dependent functions (w_farsi).
+ */
+#define W_CONV 0x1
+#define W_R_L 0x2
+
+
+/* special Farsi text messages */
+
+EXTERN char_u farsi_text_1[]
+#ifdef DO_INIT
+ = { YE_, _SIN, RE, ALEF_, _FE, ' ', 'V', 'I', 'M',
+ ' ', F_HE, _BE, ' ', SHIN, RE, _GAF, DAL,' ', NOON,
+ ALEF_, _YE, ALEF_, _PE, '\0'}
+
+#endif
+;
+
+EXTERN char_u farsi_text_2[]
+#ifdef DO_INIT
+ = { YE_, _SIN, RE, ALEF_, _FE, ' ', FARSI_3, FARSI_3,
+ FARSI_4, FARSI_2, ' ', DAL, RE, ALEF, DAL, _NOON,
+ ALEF_, _TE, _SIN, ALEF, ' ', F_HE, _BE, ' ', SHIN,
+ RE, _GAF, DAL, ' ', NOON, ALEF_, _YE, ALEF_, _PE, '\0'}
+
+#endif
+;
+
+EXTERN char_u farsi_text_3[]
+#ifdef DO_INIT
+ = { DAL, WAW, _SHIN, _YE, _MIM, _NOON, ' ', YE_, _NOON,
+ ALEF_,_BE, _YE, _TE, _SHIN, _PE, ' ', 'R','E','P','L',
+ 'A','C','E', ' ', NOON, ALEF_, _MIM, RE, _FE, ZE, ALEF,
+ ' ', 'R', 'E', 'V', 'E', 'R', 'S', 'E', ' ', 'I', 'N',
+ 'S', 'E', 'R', 'T', ' ', SHIN, WAW, RE, ' ', ALEF_, _BE,
+ ' ', YE_, _SIN, RE, ALEF_, _FE, ' ', RE, DAL, ' ', RE,
+ ALEF_, _KAF,' ', MIM, ALEF_, _GAF, _NOON, _HE, '\0'}
+
+#endif
+;
+
+
+EXTERN char_u farsi_text_5[]
+#ifdef DO_INIT
+ = { ' ', YE_, _SIN, RE, ALEF_, _FE, '\0'}
+#endif
+;
diff --git a/src/fileio.c b/src/fileio.c
new file mode 100644
index 0000000000..d05181e654
--- /dev/null
+++ b/src/fileio.c
@@ -0,0 +1,8496 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * 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.
+ */
+
+/*
+ * fileio.c: read from and write to a file
+ */
+
+#include "vim.h"
+
+
+#if defined(HAVE_UTIME) && defined(HAVE_UTIME_H)
+# include <utime.h> /* for struct utimbuf */
+#endif
+
+#define BUFSIZE 8192 /* size of normal write buffer */
+#define SMBUFSIZE 256 /* size of emergency write buffer */
+
+/* crypt_magic[0] is pkzip crypt, crypt_magic[1] is sha2+blowfish */
+static char *crypt_magic[] = {"VimCrypt~01!", "VimCrypt~02!"};
+static char crypt_magic_head[] = "VimCrypt~";
+# define CRYPT_MAGIC_LEN 12 /* must be multiple of 4! */
+
+/* For blowfish, after the magic header, we store 8 bytes of salt and then 8
+ * bytes of seed (initialisation vector). */
+static int crypt_salt_len[] = {0, 8};
+static int crypt_seed_len[] = {0, 8};
+#define CRYPT_SALT_LEN_MAX 8
+#define CRYPT_SEED_LEN_MAX 8
+
+/* Is there any system that doesn't have access()? */
+#define USE_MCH_ACCESS
+
+static char_u *next_fenc __ARGS((char_u **pp));
+static char_u *readfile_charconvert __ARGS((char_u *fname, char_u *fenc,
+ int *fdp));
+static void check_marks_read __ARGS((void));
+static int crypt_method_from_magic __ARGS((char *ptr, int len));
+static char_u *check_for_cryptkey __ARGS((char_u *cryptkey, char_u *ptr,
+ long *sizep, off_t *filesizep,
+ int newfile, char_u *fname,
+ int *did_ask));
+#ifdef UNIX
+static void set_file_time __ARGS((char_u *fname, time_t atime, time_t mtime));
+#endif
+static int set_rw_fname __ARGS((char_u *fname, char_u *sfname));
+static int msg_add_fileformat __ARGS((int eol_type));
+static void msg_add_eol __ARGS((void));
+static int check_mtime __ARGS((buf_T *buf, struct stat *s));
+static int time_differs __ARGS((long t1, long t2));
+static int apply_autocmds_exarg __ARGS((event_T event, char_u *fname, char_u *
+ fname_io, int force, buf_T *buf,
+ exarg_T *eap));
+static int au_find_group __ARGS((char_u *name));
+
+# define AUGROUP_DEFAULT -1 /* default autocmd group */
+# define AUGROUP_ERROR -2 /* erroneous autocmd group */
+# define AUGROUP_ALL -3 /* all autocmd groups */
+
+# define HAS_BW_FLAGS
+# define FIO_LATIN1 0x01 /* convert Latin1 */
+# define FIO_UTF8 0x02 /* convert UTF-8 */
+# define FIO_UCS2 0x04 /* convert UCS-2 */
+# define FIO_UCS4 0x08 /* convert UCS-4 */
+# define FIO_UTF16 0x10 /* convert UTF-16 */
+# define FIO_ENDIAN_L 0x80 /* little endian */
+# define FIO_ENCRYPTED 0x1000 /* encrypt written bytes */
+# define FIO_NOCONVERT 0x2000 /* skip encoding conversion */
+# define FIO_UCSBOM 0x4000 /* check for BOM at start of file */
+# define FIO_ALL -1 /* allow all formats */
+
+/* When converting, a read() or write() may leave some bytes to be converted
+ * for the next call. The value is guessed... */
+#define CONV_RESTLEN 30
+
+/* We have to guess how much a sequence of bytes may expand when converting
+ * with iconv() to be able to allocate a buffer. */
+#define ICONV_MULT 8
+
+/*
+ * Structure to pass arguments from buf_write() to buf_write_bytes().
+ */
+struct bw_info {
+ int bw_fd; /* file descriptor */
+ char_u *bw_buf; /* buffer with data to be written */
+ int bw_len; /* length of data */
+#ifdef HAS_BW_FLAGS
+ int bw_flags; /* FIO_ flags */
+#endif
+ char_u bw_rest[CONV_RESTLEN]; /* not converted bytes */
+ int bw_restlen; /* nr of bytes in bw_rest[] */
+ int bw_first; /* first write call */
+ char_u *bw_conv_buf; /* buffer for writing converted chars */
+ int bw_conv_buflen; /* size of bw_conv_buf */
+ int bw_conv_error; /* set for conversion error */
+ linenr_T bw_conv_error_lnum; /* first line with error or zero */
+ linenr_T bw_start_lnum; /* line number at start of buffer */
+# ifdef USE_ICONV
+ iconv_t bw_iconv_fd; /* descriptor for iconv() or -1 */
+# endif
+};
+
+static int buf_write_bytes __ARGS((struct bw_info *ip));
+
+static linenr_T readfile_linenr __ARGS((linenr_T linecnt, char_u *p,
+ char_u *endp));
+static int ucs2bytes __ARGS((unsigned c, char_u **pp, int flags));
+static int need_conversion __ARGS((char_u *fenc));
+static int get_fio_flags __ARGS((char_u *ptr));
+static char_u *check_for_bom __ARGS((char_u *p, long size, int *lenp, int flags));
+static int make_bom __ARGS((char_u *buf, char_u *name));
+static int move_lines __ARGS((buf_T *frombuf, buf_T *tobuf));
+#ifdef TEMPDIRNAMES
+static void vim_settempdir __ARGS((char_u *tempdir));
+#endif
+static char *e_auchangedbuf = N_(
+ "E812: Autocommands changed buffer or buffer name");
+
+void filemess(buf, name, s, attr)
+buf_T *buf;
+char_u *name;
+char_u *s;
+int attr;
+{
+ int msg_scroll_save;
+
+ 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().
+ */
+ msg_scroll_save = msg_scroll;
+ if (shortmess(SHM_OVERALL) && !exiting && p_verbose == 0)
+ msg_scroll = FALSE;
+ if (!msg_scroll) /* wait a bit when overwriting an error msg */
+ check_for_delay(FALSE);
+ msg_start();
+ msg_scroll = msg_scroll_save;
+ msg_scrolled_ign = TRUE;
+ /* may truncate the message to avoid a hit-return prompt */
+ msg_outtrans_attr(msg_may_trunc(FALSE, IObuff), attr);
+ msg_clr_eos();
+ out_flush();
+ msg_scrolled_ign = FALSE;
+}
+
+/*
+ * Read lines from file "fname" into the buffer after line "from".
+ *
+ * 1. We allocate blocks with lalloc, as big as possible.
+ * 2. Each block is filled with characters from the file with a single read().
+ * 3. The lines are inserted in the buffer with ml_append().
+ *
+ * (caller must check that fname != NULL, unless READ_STDIN is used)
+ *
+ * "lines_to_skip" is the number of lines that must be skipped
+ * "lines_to_read" is the number of lines that are appended
+ * When not recovering lines_to_skip is 0 and lines_to_read MAXLNUM.
+ *
+ * flags:
+ * READ_NEW starting to edit a new buffer
+ * READ_FILTER reading filter output
+ * READ_STDIN read from stdin instead of a file
+ * READ_BUFFER read from curbuf instead of a file (converting after reading
+ * 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
+ *
+ * return FAIL for failure, OK otherwise
+ */
+int readfile(fname, sfname, from, lines_to_skip, lines_to_read, eap, flags)
+char_u *fname;
+char_u *sfname;
+linenr_T from;
+linenr_T lines_to_skip;
+linenr_T lines_to_read;
+exarg_T *eap; /* can be NULL! */
+int flags;
+{
+ int fd = 0;
+ int newfile = (flags & READ_NEW);
+ int check_readonly;
+ int filtering = (flags & READ_FILTER);
+ int read_stdin = (flags & READ_STDIN);
+ int read_buffer = (flags & READ_BUFFER);
+ int set_options = newfile || read_buffer
+ || (eap != NULL && eap->read_edit);
+ linenr_T read_buf_lnum = 1; /* next line to read from curbuf */
+ colnr_T read_buf_col = 0; /* next char to read from this line */
+ char_u c;
+ linenr_T lnum = from;
+ char_u *ptr = NULL; /* pointer into read buffer */
+ char_u *buffer = NULL; /* read buffer */
+ char_u *new_buffer = NULL; /* init to shut up gcc */
+ char_u *line_start = NULL; /* init to shut up gcc */
+ 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 *cryptkey = NULL;
+ int did_ask_for_key = FALSE;
+ int crypt_method_used;
+ context_sha256_T sha_ctx;
+ int read_undo_file = FALSE;
+ int split = 0; /* number of split lines */
+#define UNKNOWN 0x0fffffff /* file size is unknown */
+ 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;
+ int swap_mode = -1; /* protection bits for swap file */
+#else
+ int perm;
+#endif
+ int fileformat = 0; /* end-of-line format */
+ int keep_fileformat = FALSE;
+ struct stat st;
+ int file_readonly;
+ 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;
+ int can_retry;
+ linenr_T conv_error = 0; /* line nr with conversion error */
+ linenr_T illegal_byte = 0; /* line nr with illegal byte */
+ int keep_dest_enc = FALSE; /* don't retry when char doesn't fit
+ in destination encoding */
+ int bad_char_behavior = BAD_REPLACE;
+ /* BAD_KEEP, BAD_DROP or character to
+ * replace with */
+ char_u *tmpname = NULL; /* name of 'charconvert' output file */
+ int fio_flags = 0;
+ char_u *fenc; /* fileencoding to use */
+ int fenc_alloced; /* fenc_next is in allocated memory */
+ char_u *fenc_next = NULL; /* next item in 'fencs' or NULL */
+ int advance_fenc = FALSE;
+ long real_size = 0;
+# ifdef USE_ICONV
+ iconv_t iconv_fd = (iconv_t)-1; /* descriptor for iconv() or -1 */
+ int did_iconv = FALSE; /* TRUE when iconv() failed and trying
+ 'charconvert' next */
+# endif
+ int converted = FALSE; /* TRUE if conversion done */
+ int notconverted = FALSE; /* TRUE if conversion wanted but it
+ wasn't possible */
+ char_u conv_rest[CONV_RESTLEN];
+ int conv_restlen = 0; /* nr of bytes in conv_rest[] */
+ buf_T *old_curbuf;
+ char_u *old_b_ffname;
+ char_u *old_b_fname;
+ int using_b_ffname;
+ int using_b_fname;
+
+ curbuf->b_no_eol_lnum = 0; /* in case it was set by the previous read */
+
+ /*
+ * If there is no file name yet, use the one for the read file.
+ * BF_NOTEDITED is set to reflect this.
+ * Don't do this for a read from a filter.
+ * Only do this when 'cpoptions' contains the 'f' flag.
+ */
+ if (curbuf->b_ffname == NULL
+ && !filtering
+ && fname != NULL
+ && vim_strchr(p_cpo, CPO_FNAMER) != NULL
+ && !(flags & READ_DUMMY)) {
+ if (set_rw_fname(fname, sfname) == FAIL)
+ return FAIL;
+ }
+
+ /* Remember the initial values of curbuf, curbuf->b_ffname and
+ * curbuf->b_fname to detect whether they are altered as a result of
+ * executing nasty autocommands. Also check if "fname" and "sfname"
+ * point to one of these values. */
+ old_curbuf = curbuf;
+ old_b_ffname = curbuf->b_ffname;
+ old_b_fname = curbuf->b_fname;
+ using_b_ffname = (fname == curbuf->b_ffname)
+ || (sfname == curbuf->b_ffname);
+ using_b_fname = (fname == curbuf->b_fname) || (sfname == curbuf->b_fname);
+
+ /* After reading a file the cursor line changes but we don't want to
+ * display the line. */
+ ex_no_reprint = TRUE;
+
+ /* don't display the file info for another buffer now */
+ need_fileinfo = FALSE;
+
+ /*
+ * For Unix: Use the short file name whenever possible.
+ * Avoids problems with networks and when directory names are changed.
+ * Don't do this for MS-DOS, a "cd" in a sub-shell may have moved us to
+ * another directory, which we don't detect.
+ */
+ if (sfname == NULL)
+ sfname = fname;
+#if defined(UNIX) || defined(__EMX__)
+ fname = sfname;
+#endif
+
+ /*
+ * The BufReadCmd and FileReadCmd events intercept the reading process by
+ * executing the associated commands instead.
+ */
+ if (!filtering && !read_stdin && !read_buffer) {
+ pos_T pos;
+
+ pos = curbuf->b_op_start;
+
+ /* Set '[ mark to the line above where the lines go (line 1 if zero). */
+ curbuf->b_op_start.lnum = ((from == 0) ? 1 : from);
+ curbuf->b_op_start.col = 0;
+
+ if (newfile) {
+ if (apply_autocmds_exarg(EVENT_BUFREADCMD, NULL, sfname,
+ FALSE, curbuf, eap))
+ return aborting() ? FAIL : OK;
+ } else if (apply_autocmds_exarg(EVENT_FILEREADCMD, sfname, sfname,
+ FALSE, NULL, eap))
+ return aborting() ? FAIL : OK;
+
+ curbuf->b_op_start = pos;
+ }
+
+ if ((shortmess(SHM_OVER) || curbuf->b_help) && p_verbose == 0)
+ msg_scroll = FALSE; /* overwrite previous file message */
+ else
+ msg_scroll = TRUE; /* don't overwrite previous file message */
+
+ /*
+ * If the name ends in a path separator, we can't open it. Check here,
+ * because reading the file may actually work, but then creating the swap
+ * file may destroy it! Reported on MS-DOS and Win 95.
+ * If the name is too long we might crash further on, quit here.
+ */
+ if (fname != NULL && *fname != NUL) {
+ p = fname + STRLEN(fname);
+ if (after_pathsep(fname, p) || STRLEN(fname) >= MAXPATHL) {
+ filemess(curbuf, fname, (char_u *)_("Illegal file name"), 0);
+ msg_end();
+ msg_scroll = msg_save;
+ return FAIL;
+ }
+ }
+
+ if (!read_stdin && !read_buffer) {
+#ifdef UNIX
+ /*
+ * On Unix it is possible to read a directory, so we have to
+ * check for it before the mch_open().
+ */
+ perm = mch_getperm(fname);
+ if (perm >= 0 && !S_ISREG(perm) /* not a regular file ... */
+# ifdef S_ISFIFO
+ && !S_ISFIFO(perm) /* ... or fifo */
+# endif
+# ifdef S_ISSOCK
+ && !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> */
+# endif
+ ) {
+ if (S_ISDIR(perm))
+ filemess(curbuf, fname, (char_u *)_("is a directory"), 0);
+ else
+ filemess(curbuf, fname, (char_u *)_("is not a file"), 0);
+ msg_end();
+ msg_scroll = msg_save;
+ return FAIL;
+ }
+#endif
+ }
+
+ /* Set default or forced 'fileformat' and 'binary'. */
+ set_file_options(set_options, eap);
+
+ /*
+ * When opening a new file we take the readonly flag from the file.
+ * Default is r/w, can be set to r/o below.
+ * Don't reset it when in readonly mode
+ * Only set/reset b_p_ro when BF_CHECK_RO is set.
+ */
+ check_readonly = (newfile && (curbuf->b_flags & BF_CHECK_RO));
+ if (check_readonly && !readonlymode)
+ curbuf->b_p_ro = FALSE;
+
+ if (newfile && !read_stdin && !read_buffer) {
+ /* Remember time of file. */
+ if (mch_stat((char *)fname, &st) >= 0) {
+ buf_store_time(curbuf, &st, fname);
+ curbuf->b_mtime_read = curbuf->b_mtime;
+#ifdef UNIX
+ /*
+ * Use the protection bits of the original file for the swap file.
+ * This makes it possible for others to read the name of the
+ * edited file from the swapfile, but only if they can read the
+ * edited file.
+ * Remove the "write" and "execute" bits for group and others
+ * (they must not write the swapfile).
+ * Add the "read" and "write" bits for the user, otherwise we may
+ * not be able to write to the file ourselves.
+ * Setting the bits is done below, after creating the swap file.
+ */
+ swap_mode = (st.st_mode & 0644) | 0600;
+#endif
+ } else {
+ curbuf->b_mtime = 0;
+ curbuf->b_mtime_read = 0;
+ curbuf->b_orig_size = 0;
+ curbuf->b_orig_mode = 0;
+ }
+
+ /* Reset the "new file" flag. It will be set again below when the
+ * file doesn't exist. */
+ curbuf->b_flags &= ~(BF_NEW | BF_NEW_W);
+ }
+
+ /*
+ * for UNIX: check readonly with perm and mch_access()
+ * for MSDOS and Amiga: check readonly by trying to open the file for writing
+ */
+ file_readonly = FALSE;
+ if (read_stdin) {
+ } else if (!read_buffer) {
+#ifdef USE_MCH_ACCESS
+ if (
+# ifdef UNIX
+ !(perm & 0222) ||
+# endif
+ mch_access((char *)fname, W_OK))
+ file_readonly = TRUE;
+ fd = mch_open((char *)fname, O_RDONLY | O_EXTRA, 0);
+#else
+ if (!newfile
+ || readonlymode
+ || (fd = mch_open((char *)fname, O_RDWR | O_EXTRA, 0)) < 0) {
+ file_readonly = TRUE;
+ /* try to open ro */
+ fd = mch_open((char *)fname, O_RDONLY | O_EXTRA, 0);
+ }
+#endif
+ }
+
+ if (fd < 0) { /* cannot open at all */
+#ifndef UNIX
+ int isdir_f;
+#endif
+ msg_scroll = msg_save;
+#ifndef UNIX
+ /*
+ * On MSDOS and Amiga we can't open a directory, check here.
+ */
+ isdir_f = (mch_isdir(fname));
+ perm = mch_getperm(fname); /* check if the file exists */
+ if (isdir_f) {
+ filemess(curbuf, sfname, (char_u *)_("is a directory"), 0);
+ curbuf->b_p_ro = TRUE; /* must use "w!" now */
+ } else
+#endif
+ if (newfile) {
+ if (perm < 0
+#ifdef ENOENT
+ && errno == ENOENT
+#endif
+ ) {
+ /*
+ * 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
+ * that we are editing this file. Don't do this for a
+ * "nofile" or "nowrite" buffer type. */
+ if (!bt_dontwrite(curbuf)) {
+ check_need_swap(newfile);
+ /* SwapExists autocommand may mess things up */
+ if (curbuf != old_curbuf
+ || (using_b_ffname
+ && (old_b_ffname != curbuf->b_ffname))
+ || (using_b_fname
+ && (old_b_fname != curbuf->b_fname))) {
+ EMSG(_(e_auchangedbuf));
+ return FAIL;
+ }
+ }
+ if (dir_of_file_exists(fname))
+ filemess(curbuf, sfname, (char_u *)_("[New File]"), 0);
+ else
+ filemess(curbuf, sfname,
+ (char_u *)_("[New DIRECTORY]"), 0);
+ /* Even though this is a new file, it might have been
+ * edited before and deleted. Get the old marks. */
+ check_marks_read();
+ /* Set forced 'fileencoding'. */
+ if (eap != NULL)
+ set_forced_fenc(eap);
+ apply_autocmds_exarg(EVENT_BUFNEWFILE, sfname, sfname,
+ FALSE, curbuf, eap);
+ /* remember the current fileformat */
+ save_file_ff(curbuf);
+
+ if (aborting()) /* autocmds may abort script processing */
+ return FAIL;
+ return OK; /* a new file is not an error */
+ } else {
+ filemess(curbuf, sfname, (char_u *)(
+# ifdef EFBIG
+ (errno == EFBIG) ? _("[File too big]") :
+# endif
+# ifdef EOVERFLOW
+ (errno == EOVERFLOW) ? _("[File too big]") :
+# endif
+ _("[Permission Denied]")), 0);
+ curbuf->b_p_ro = TRUE; /* must use "w!" now */
+ }
+ }
+
+ return FAIL;
+ }
+
+ /*
+ * Only set the 'ro' flag for readonly files the first time they are
+ * loaded. Help files always get readonly mode
+ */
+ if ((check_readonly && file_readonly) || curbuf->b_help)
+ curbuf->b_p_ro = TRUE;
+
+ if (set_options) {
+ /* Don't change 'eol' if reading from buffer as it will already be
+ * correctly set when reading stdin. */
+ if (!read_buffer) {
+ curbuf->b_p_eol = TRUE;
+ curbuf->b_start_eol = TRUE;
+ }
+ curbuf->b_p_bomb = FALSE;
+ curbuf->b_start_bomb = FALSE;
+ }
+
+ /* Create a swap file now, so that other Vims are warned that we are
+ * editing this file.
+ * Don't do this for a "nofile" or "nowrite" buffer type. */
+ if (!bt_dontwrite(curbuf)) {
+ check_need_swap(newfile);
+ if (!read_stdin && (curbuf != old_curbuf
+ || (using_b_ffname && (old_b_ffname != curbuf->b_ffname))
+ || (using_b_fname &&
+ (old_b_fname != curbuf->b_fname)))) {
+ EMSG(_(e_auchangedbuf));
+ if (!read_buffer)
+ close(fd);
+ return FAIL;
+ }
+#ifdef UNIX
+ /* 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)mch_setperm(curbuf->b_ml.ml_mfp->mf_fname, (long)swap_mode);
+#endif
+ }
+
+#if defined(HAS_SWAP_EXISTS_ACTION)
+ /* If "Quit" selected at ATTENTION dialog, don't load the file */
+ if (swap_exists_action == SEA_QUIT) {
+ if (!read_buffer && !read_stdin)
+ close(fd);
+ return FAIL;
+ }
+#endif
+
+ ++no_wait_return; /* don't wait for return yet */
+
+ /*
+ * Set '[ mark to the line above where the lines go (line 1 if zero).
+ */
+ curbuf->b_op_start.lnum = ((from == 0) ? 1 : from);
+ curbuf->b_op_start.col = 0;
+
+ 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 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)
+ apply_autocmds_exarg(EVENT_STDINREADPRE, NULL, sfname,
+ FALSE, curbuf, eap);
+ else if (newfile)
+ apply_autocmds_exarg(EVENT_BUFREADPRE, NULL, sfname,
+ FALSE, curbuf, eap);
+ else
+ apply_autocmds_exarg(EVENT_FILEREADPRE, sfname, sfname,
+ FALSE, NULL, eap);
+ if (msg_scrolled == n)
+ msg_scroll = m;
+
+ if (aborting()) { /* autocmds may abort script processing */
+ --no_wait_return;
+ msg_scroll = msg_save;
+ curbuf->b_p_ro = TRUE; /* must use "w!" now */
+ return FAIL;
+ }
+ /*
+ * Don't allow the autocommands to change the current buffer.
+ * Try to re-open the file.
+ *
+ * Don't allow the autocommands to change the buffer name either
+ * (cd for example) if it invalidates fname or sfname.
+ */
+ if (!read_stdin && (curbuf != old_curbuf
+ || (using_b_ffname && (old_b_ffname != curbuf->b_ffname))
+ || (using_b_fname && (old_b_fname != curbuf->b_fname))
+ || (fd =
+ mch_open((char *)fname, O_RDONLY | O_EXTRA,
+ 0)) < 0)) {
+ --no_wait_return;
+ msg_scroll = msg_save;
+ if (fd < 0)
+ EMSG(_("E200: *ReadPre autocommands made the file unreadable"));
+ else
+ EMSG(_("E201: *ReadPre autocommands must not change current buffer"));
+ curbuf->b_p_ro = TRUE; /* must use "w!" now */
+ return FAIL;
+ }
+ }
+
+ /* Autocommands may add lines to the file, need to check if it is empty */
+ 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(_("Vim: Reading from stdin...\n"));
+ } else if (!read_buffer)
+ filemess(curbuf, sfname, (char_u *)"", 0);
+ }
+
+ msg_scroll = FALSE; /* overwrite the file message */
+
+ /*
+ * Set linecnt now, before the "retry" caused by a wrong guess for
+ * fileformat, and after the autocommands, which may change them.
+ */
+ linecnt = curbuf->b_ml.ml_line_count;
+
+ /* "++bad=" argument. */
+ if (eap != NULL && eap->bad_char != 0) {
+ bad_char_behavior = eap->bad_char;
+ if (set_options)
+ curbuf->b_bad_char = eap->bad_char;
+ } else
+ curbuf->b_bad_char = 0;
+
+ /*
+ * Decide which 'encoding' to use or use first.
+ */
+ if (eap != NULL && eap->force_enc != 0) {
+ fenc = enc_canonize(eap->cmd + eap->force_enc);
+ fenc_alloced = TRUE;
+ keep_dest_enc = TRUE;
+ } else if (curbuf->b_p_bin) {
+ 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;
+ } else if (*p_fencs == NUL) {
+ fenc = curbuf->b_p_fenc; /* use format from buffer */
+ fenc_alloced = FALSE;
+ } else {
+ fenc_next = p_fencs; /* try items in 'fileencodings' */
+ fenc = next_fenc(&fenc_next);
+ fenc_alloced = TRUE;
+ }
+
+ /*
+ * Jump back here to retry reading the file in different ways.
+ * Reasons to retry:
+ * - encoding conversion failed: try another one from "fenc_next"
+ * - BOM detected and fenc was set, need to setup conversion
+ * - "fileformat" check failed: try another
+ *
+ * Variables set for special retry actions:
+ * "file_rewind" Rewind the file to start reading it again.
+ * "advance_fenc" Advance "fenc" using "fenc_next".
+ * "skip_read" Re-use already read bytes (BOM detected).
+ * "did_iconv" iconv() conversion failed, try 'charconvert'.
+ * "keep_fileformat" Don't reset "fileformat".
+ *
+ * Other status indicators:
+ * "tmpname" When != NULL did conversion with 'charconvert'.
+ * Output file has to be deleted afterwards.
+ * "iconv_fd" When != -1 did conversion with iconv().
+ */
+retry:
+
+ if (file_rewind) {
+ 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;
+ goto failed;
+ }
+ /* Delete the previously read lines. */
+ while (lnum > from)
+ ml_delete(lnum--, FALSE);
+ file_rewind = FALSE;
+ if (set_options) {
+ curbuf->b_p_bomb = FALSE;
+ curbuf->b_start_bomb = FALSE;
+ }
+ conv_error = 0;
+ }
+
+ if (cryptkey != NULL)
+ /* Need to reset the state, but keep the key, don't want to ask for it
+ * again. */
+ crypt_pop_state();
+
+ /*
+ * When retrying with another "fenc" and the first time "fileformat"
+ * will be reset.
+ */
+ if (keep_fileformat)
+ keep_fileformat = FALSE;
+ else {
+ if (eap != NULL && eap->force_ff != 0) {
+ fileformat = get_fileformat_force(curbuf, eap);
+ try_unix = try_dos = try_mac = FALSE;
+ } else if (curbuf->b_p_bin)
+ fileformat = EOL_UNIX; /* binary: use Unix format */
+ else if (*p_ffs == NUL)
+ fileformat = get_fileformat(curbuf); /* use format from buffer */
+ else
+ fileformat = EOL_UNKNOWN; /* detect from file */
+ }
+
+# ifdef USE_ICONV
+ if (iconv_fd != (iconv_t)-1) {
+ /* aborted conversion with iconv(), close the descriptor */
+ iconv_close(iconv_fd);
+ iconv_fd = (iconv_t)-1;
+ }
+# endif
+
+ if (advance_fenc) {
+ /*
+ * Try the next entry in 'fileencodings'.
+ */
+ advance_fenc = FALSE;
+
+ if (eap != NULL && eap->force_enc != 0) {
+ /* Conversion given with "++cc=" wasn't possible, read
+ * without conversion. */
+ notconverted = TRUE;
+ conv_error = 0;
+ if (fenc_alloced)
+ vim_free(fenc);
+ fenc = (char_u *)"";
+ fenc_alloced = FALSE;
+ } else {
+ if (fenc_alloced)
+ vim_free(fenc);
+ if (fenc_next != NULL) {
+ fenc = next_fenc(&fenc_next);
+ fenc_alloced = (fenc_next != NULL);
+ } else {
+ fenc = (char_u *)"";
+ fenc_alloced = FALSE;
+ }
+ }
+ if (tmpname != NULL) {
+ mch_remove(tmpname); /* delete converted file */
+ vim_free(tmpname);
+ tmpname = NULL;
+ }
+ }
+
+ /*
+ * Conversion may be required when the encoding of the file is different
+ * from 'encoding' or 'encoding' is UTF-16, UCS-2 or UCS-4.
+ */
+ fio_flags = 0;
+ converted = need_conversion(fenc);
+ if (converted) {
+
+ /* "ucs-bom" means we need to check the first bytes of the file
+ * for a BOM. */
+ if (STRCMP(fenc, ENC_UCSBOM) == 0)
+ fio_flags = FIO_UCSBOM;
+
+ /*
+ * Check if UCS-2/4 or Latin1 to UTF-8 conversion needs to be
+ * done. This is handled below after read(). Prepare the
+ * fio_flags to avoid having to parse the string each time.
+ * Also check for Unicode to Latin1 conversion, because iconv()
+ * appears not to handle this correctly. This works just like
+ * conversion to UTF-8 except how the resulting character is put in
+ * the buffer.
+ */
+ else if (enc_utf8 || STRCMP(p_enc, "latin1") == 0)
+ fio_flags = get_fio_flags(fenc);
+
+
+
+# ifdef USE_ICONV
+ /*
+ * Try using iconv() if we can't convert internally.
+ */
+ if (fio_flags == 0
+ && !did_iconv
+ )
+ iconv_fd = (iconv_t)my_iconv_open(
+ enc_utf8 ? (char_u *)"utf-8" : p_enc, fenc);
+# endif
+
+ /*
+ * Use the 'charconvert' expression when conversion is required
+ * and we can't do it internally or with iconv().
+ */
+ if (fio_flags == 0 && !read_stdin && !read_buffer && *p_ccv != NUL
+# ifdef USE_ICONV
+ && iconv_fd == (iconv_t)-1
+# endif
+ ) {
+# ifdef USE_ICONV
+ did_iconv = FALSE;
+# endif
+ /* Skip conversion when it's already done (retry for wrong
+ * "fileformat"). */
+ if (tmpname == NULL) {
+ tmpname = readfile_charconvert(fname, fenc, &fd);
+ if (tmpname == NULL) {
+ /* Conversion failed. Try another one. */
+ advance_fenc = TRUE;
+ if (fd < 0) {
+ /* Re-opening the original file failed! */
+ EMSG(_("E202: Conversion made file unreadable!"));
+ error = TRUE;
+ goto failed;
+ }
+ goto retry;
+ }
+ }
+ } else {
+ if (fio_flags == 0
+# ifdef USE_ICONV
+ && iconv_fd == (iconv_t)-1
+# endif
+ ) {
+ /* Conversion wanted but we can't.
+ * Try the next conversion in 'fileencodings' */
+ advance_fenc = TRUE;
+ goto 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);
+
+ if (!skip_read) {
+ linerest = 0;
+ filesize = 0;
+ skip_count = lines_to_skip;
+ read_count = lines_to_read;
+ conv_restlen = 0;
+ read_undo_file = (newfile && (flags & READ_KEEP_UNDO) == 0
+ && curbuf->b_ffname != NULL
+ && curbuf->b_p_udf
+ && !filtering
+ && !read_stdin
+ && !read_buffer);
+ if (read_undo_file)
+ sha256_start(&sha_ctx);
+ }
+
+ while (!error && !got_int) {
+ /*
+ * We allocate as much space for the file as we can get, plus
+ * space for the old line plus room for one terminating NUL.
+ * The amount is limited by the fact that read() only can read
+ * upto max_unsigned characters (and other things).
+ */
+#if SIZEOF_INT <= 2
+ if (linerest >= 0x7ff0) {
+ ++split;
+ *ptr = NL; /* split line by inserting a NL */
+ size = 1;
+ } else
+#endif
+ {
+ if (!skip_read) {
+#if SIZEOF_INT > 2
+# if defined(SSIZE_MAX) && (SSIZE_MAX < 0x10000L)
+ size = SSIZE_MAX; /* use max I/O size, 52K */
+# else
+ size = 0x10000L; /* use buffer >= 64K */
+# endif
+#else
+ size = 0x7ff0L - linerest; /* limit buffer to 32K */
+#endif
+
+ for (; size >= 10; size = (long)((long_u)size >> 1)) {
+ if ((new_buffer = lalloc((long_u)(size + linerest + 1),
+ FALSE)) != NULL)
+ break;
+ }
+ if (new_buffer == NULL) {
+ do_outofmem_msg((long_u)(size * 2 + linerest + 1));
+ error = TRUE;
+ break;
+ }
+ if (linerest) /* copy characters from the previous buffer */
+ mch_memmove(new_buffer, ptr - linerest, (size_t)linerest);
+ vim_free(buffer);
+ buffer = new_buffer;
+ ptr = buffer + linerest;
+ line_start = buffer;
+
+ /* May need room to translate into.
+ * For iconv() we don't really know the required space, use a
+ * factor ICONV_MULT.
+ * latin1 to utf-8: 1 byte becomes up to 2 bytes
+ * utf-16 to utf-8: 2 bytes become up to 3 bytes, 4 bytes
+ * become up to 4 bytes, size must be multiple of 2
+ * ucs-2 to utf-8: 2 bytes become up to 3 bytes, size must be
+ * multiple of 2
+ * ucs-4 to utf-8: 4 bytes become up to 6 bytes, size must be
+ * multiple of 4 */
+ real_size = (int)size;
+# ifdef USE_ICONV
+ if (iconv_fd != (iconv_t)-1)
+ size = size / ICONV_MULT;
+ else
+# endif
+ if (fio_flags & FIO_LATIN1)
+ size = size / 2;
+ else if (fio_flags & (FIO_UCS2 | FIO_UTF16))
+ size = (size * 2 / 3) & ~1;
+ else if (fio_flags & FIO_UCS4)
+ size = (size * 2 / 3) & ~3;
+ else if (fio_flags == FIO_UCSBOM)
+ size = size / ICONV_MULT; /* worst case */
+
+ if (conv_restlen > 0) {
+ /* Insert unconverted bytes from previous line. */
+ mch_memmove(ptr, conv_rest, conv_restlen);
+ ptr += conv_restlen;
+ size -= conv_restlen;
+ }
+
+ if (read_buffer) {
+ /*
+ * Read bytes from curbuf. Used for converting text read
+ * from stdin.
+ */
+ if (read_buf_lnum > from)
+ size = 0;
+ else {
+ int n, ni;
+ long tlen;
+
+ tlen = 0;
+ for (;; ) {
+ p = ml_get(read_buf_lnum) + read_buf_col;
+ n = (int)STRLEN(p);
+ if ((int)tlen + n + 1 > size) {
+ /* Filled up to "size", append partial line.
+ * Change NL to NUL to reverse the effect done
+ * below. */
+ n = (int)(size - tlen);
+ for (ni = 0; ni < n; ++ni) {
+ if (p[ni] == NL)
+ ptr[tlen++] = NUL;
+ else
+ ptr[tlen++] = p[ni];
+ }
+ read_buf_col += n;
+ break;
+ } else {
+ /* Append whole line and new-line. Change NL
+ * to NUL to reverse the effect done below. */
+ for (ni = 0; ni < n; ++ni) {
+ if (p[ni] == NL)
+ ptr[tlen++] = NUL;
+ else
+ ptr[tlen++] = p[ni];
+ }
+ ptr[tlen++] = NL;
+ read_buf_col = 0;
+ if (++read_buf_lnum > from) {
+ /* When the last line didn't have an
+ * end-of-line don't add it now either. */
+ if (!curbuf->b_p_eol)
+ --tlen;
+ size = tlen;
+ break;
+ }
+ }
+ }
+ }
+ } else {
+ /*
+ * Read bytes from the file.
+ */
+ size = read_eintr(fd, ptr, size);
+ }
+
+ if (size <= 0) {
+ if (size < 0) /* read error */
+ error = TRUE;
+ else if (conv_restlen > 0) {
+ /*
+ * Reached end-of-file but some trailing bytes could
+ * not be converted. Truncated file?
+ */
+
+ /* When we did a conversion report an error. */
+ if (fio_flags != 0
+# ifdef USE_ICONV
+ || iconv_fd != (iconv_t)-1
+# endif
+ ) {
+ if (can_retry)
+ goto rewind_retry;
+ if (conv_error == 0)
+ conv_error = curbuf->b_ml.ml_line_count
+ - linecnt + 1;
+ }
+ /* Remember the first linenr with an illegal byte */
+ else if (illegal_byte == 0)
+ illegal_byte = curbuf->b_ml.ml_line_count
+ - linecnt + 1;
+ if (bad_char_behavior == BAD_DROP) {
+ *(ptr - conv_restlen) = NUL;
+ conv_restlen = 0;
+ } else {
+ /* Replace the trailing bytes with the replacement
+ * character if we were converting; if we weren't,
+ * leave the UTF8 checking code to do it, as it
+ * works slightly differently. */
+ if (bad_char_behavior != BAD_KEEP && (fio_flags != 0
+# ifdef USE_ICONV
+ || iconv_fd != (iconv_t)-1
+# endif
+ )) {
+ while (conv_restlen > 0) {
+ *(--ptr) = bad_char_behavior;
+ --conv_restlen;
+ }
+ }
+ fio_flags = 0; /* don't convert this */
+# ifdef USE_ICONV
+ if (iconv_fd != (iconv_t)-1) {
+ iconv_close(iconv_fd);
+ iconv_fd = (iconv_t)-1;
+ }
+# endif
+ }
+ }
+ }
+
+ /*
+ * At start of file: Check for magic number of encryption.
+ */
+ if (filesize == 0)
+ cryptkey = check_for_cryptkey(cryptkey, ptr, &size,
+ &filesize, newfile, sfname,
+ &did_ask_for_key);
+ /*
+ * Decrypt the read bytes.
+ */
+ if (cryptkey != NULL && size > 0)
+ crypt_decode(ptr, size);
+ }
+ skip_read = FALSE;
+
+ /*
+ * At start of file (or after crypt magic number): Check for BOM.
+ * Also check for a BOM for other Unicode encodings, but not after
+ * converting with 'charconvert' or when a BOM has already been
+ * found.
+ */
+ if ((filesize == 0
+ || (filesize == (CRYPT_MAGIC_LEN
+ + crypt_salt_len[use_crypt_method]
+ + crypt_seed_len[use_crypt_method])
+ && cryptkey != NULL)
+ )
+ && (fio_flags == FIO_UCSBOM
+ || (!curbuf->b_p_bomb
+ && tmpname == NULL
+ && (*fenc == 'u' || (*fenc == NUL && enc_utf8))))) {
+ char_u *ccname;
+ int blen;
+
+ /* no BOM detection in a short file or in binary mode */
+ if (size < 2 || curbuf->b_p_bin)
+ ccname = NULL;
+ else
+ ccname = check_for_bom(ptr, size, &blen,
+ fio_flags == FIO_UCSBOM ? FIO_ALL : get_fio_flags(fenc));
+ if (ccname != NULL) {
+ /* Remove BOM from the text */
+ filesize += blen;
+ size -= blen;
+ mch_memmove(ptr, ptr + blen, (size_t)size);
+ if (set_options) {
+ curbuf->b_p_bomb = TRUE;
+ curbuf->b_start_bomb = TRUE;
+ }
+ }
+
+ if (fio_flags == FIO_UCSBOM) {
+ if (ccname == NULL) {
+ /* No BOM detected: retry with next encoding. */
+ advance_fenc = TRUE;
+ } else {
+ /* BOM detected: set "fenc" and jump back */
+ if (fenc_alloced)
+ vim_free(fenc);
+ fenc = ccname;
+ fenc_alloced = FALSE;
+ }
+ /* retry reading without getting new bytes or rewinding */
+ skip_read = TRUE;
+ goto retry;
+ }
+ }
+
+ /* Include not converted bytes. */
+ ptr -= conv_restlen;
+ size += conv_restlen;
+ conv_restlen = 0;
+ /*
+ * Break here for a read error or end-of-file.
+ */
+ if (size <= 0)
+ break;
+
+
+# ifdef USE_ICONV
+ if (iconv_fd != (iconv_t)-1) {
+ /*
+ * Attempt conversion of the read bytes to 'encoding' using
+ * iconv().
+ */
+ const char *fromp;
+ char *top;
+ size_t from_size;
+ size_t to_size;
+
+ fromp = (char *)ptr;
+ from_size = size;
+ ptr += size;
+ top = (char *)ptr;
+ to_size = real_size - size;
+
+ /*
+ * If there is conversion error or not enough room try using
+ * another conversion. Except for when there is no
+ * alternative (help files).
+ */
+ while ((iconv(iconv_fd, (void *)&fromp, &from_size,
+ &top, &to_size)
+ == (size_t)-1 && ICONV_ERRNO != ICONV_EINVAL)
+ || from_size > CONV_RESTLEN) {
+ if (can_retry)
+ goto rewind_retry;
+ if (conv_error == 0)
+ conv_error = readfile_linenr(linecnt,
+ ptr, (char_u *)top);
+
+ /* Deal with a bad byte and continue with the next. */
+ ++fromp;
+ --from_size;
+ if (bad_char_behavior == BAD_KEEP) {
+ *top++ = *(fromp - 1);
+ --to_size;
+ } else if (bad_char_behavior != BAD_DROP) {
+ *top++ = bad_char_behavior;
+ --to_size;
+ }
+ }
+
+ if (from_size > 0) {
+ /* Some remaining characters, keep them for the next
+ * round. */
+ mch_memmove(conv_rest, (char_u *)fromp, from_size);
+ conv_restlen = (int)from_size;
+ }
+
+ /* move the linerest to before the converted characters */
+ line_start = ptr - linerest;
+ mch_memmove(line_start, buffer, (size_t)linerest);
+ size = (long)((char_u *)top - ptr);
+ }
+# endif
+
+# ifdef MACOS_CONVERT
+ if (fio_flags & FIO_MACROMAN) {
+ /*
+ * Conversion from Apple MacRoman char encoding to UTF-8 or
+ * latin1. This is in os_mac_conv.c.
+ */
+ if (macroman2enc(ptr, &size, real_size) == FAIL)
+ goto rewind_retry;
+ } else
+# endif
+ if (fio_flags != 0) {
+ int u8c;
+ char_u *dest;
+ char_u *tail = NULL;
+
+ /*
+ * "enc_utf8" set: Convert Unicode or Latin1 to UTF-8.
+ * "enc_utf8" not set: Convert Unicode to Latin1.
+ * Go from end to start through the buffer, because the number
+ * of bytes may increase.
+ * "dest" points to after where the UTF-8 bytes go, "p" points
+ * to after the next character to convert.
+ */
+ dest = ptr + real_size;
+ if (fio_flags == FIO_LATIN1 || fio_flags == FIO_UTF8) {
+ p = ptr + size;
+ if (fio_flags == FIO_UTF8) {
+ /* Check for a trailing incomplete UTF-8 sequence */
+ tail = ptr + size - 1;
+ while (tail > ptr && (*tail & 0xc0) == 0x80)
+ --tail;
+ if (tail + utf_byte2len(*tail) <= ptr + size)
+ tail = NULL;
+ else
+ p = tail;
+ }
+ } else if (fio_flags & (FIO_UCS2 | FIO_UTF16)) {
+ /* Check for a trailing byte */
+ p = ptr + (size & ~1);
+ if (size & 1)
+ tail = p;
+ if ((fio_flags & FIO_UTF16) && p > ptr) {
+ /* Check for a trailing leading word */
+ if (fio_flags & FIO_ENDIAN_L) {
+ u8c = (*--p << 8);
+ u8c += *--p;
+ } else {
+ u8c = *--p;
+ u8c += (*--p << 8);
+ }
+ if (u8c >= 0xd800 && u8c <= 0xdbff)
+ tail = p;
+ else
+ p += 2;
+ }
+ } else { /* FIO_UCS4 */
+ /* Check for trailing 1, 2 or 3 bytes */
+ p = ptr + (size & ~3);
+ if (size & 3)
+ tail = p;
+ }
+
+ /* If there is a trailing incomplete sequence move it to
+ * conv_rest[]. */
+ if (tail != NULL) {
+ conv_restlen = (int)((ptr + size) - tail);
+ mch_memmove(conv_rest, (char_u *)tail, conv_restlen);
+ size -= conv_restlen;
+ }
+
+
+ while (p > ptr) {
+ if (fio_flags & FIO_LATIN1)
+ u8c = *--p;
+ else if (fio_flags & (FIO_UCS2 | FIO_UTF16)) {
+ if (fio_flags & FIO_ENDIAN_L) {
+ u8c = (*--p << 8);
+ u8c += *--p;
+ } else {
+ u8c = *--p;
+ u8c += (*--p << 8);
+ }
+ if ((fio_flags & FIO_UTF16)
+ && u8c >= 0xdc00 && u8c <= 0xdfff) {
+ int u16c;
+
+ if (p == ptr) {
+ /* Missing leading word. */
+ if (can_retry)
+ goto rewind_retry;
+ if (conv_error == 0)
+ conv_error = readfile_linenr(linecnt,
+ ptr, p);
+ if (bad_char_behavior == BAD_DROP)
+ continue;
+ if (bad_char_behavior != BAD_KEEP)
+ u8c = bad_char_behavior;
+ }
+
+ /* found second word of double-word, get the first
+ * word and compute the resulting character */
+ if (fio_flags & FIO_ENDIAN_L) {
+ u16c = (*--p << 8);
+ u16c += *--p;
+ } else {
+ u16c = *--p;
+ u16c += (*--p << 8);
+ }
+ u8c = 0x10000 + ((u16c & 0x3ff) << 10)
+ + (u8c & 0x3ff);
+
+ /* Check if the word is indeed a leading word. */
+ if (u16c < 0xd800 || u16c > 0xdbff) {
+ if (can_retry)
+ goto rewind_retry;
+ if (conv_error == 0)
+ conv_error = readfile_linenr(linecnt,
+ ptr, p);
+ if (bad_char_behavior == BAD_DROP)
+ continue;
+ if (bad_char_behavior != BAD_KEEP)
+ u8c = bad_char_behavior;
+ }
+ }
+ } else if (fio_flags & FIO_UCS4) {
+ if (fio_flags & FIO_ENDIAN_L) {
+ u8c = (*--p << 24);
+ u8c += (*--p << 16);
+ u8c += (*--p << 8);
+ u8c += *--p;
+ } else { /* big endian */
+ u8c = *--p;
+ u8c += (*--p << 8);
+ u8c += (*--p << 16);
+ u8c += (*--p << 24);
+ }
+ } else { /* UTF-8 */
+ if (*--p < 0x80)
+ u8c = *p;
+ else {
+ len = utf_head_off(ptr, p);
+ p -= len;
+ u8c = utf_ptr2char(p);
+ if (len == 0) {
+ /* Not a valid UTF-8 character, retry with
+ * another fenc when possible, otherwise just
+ * report the error. */
+ if (can_retry)
+ goto rewind_retry;
+ if (conv_error == 0)
+ conv_error = readfile_linenr(linecnt,
+ ptr, p);
+ if (bad_char_behavior == BAD_DROP)
+ continue;
+ if (bad_char_behavior != BAD_KEEP)
+ u8c = bad_char_behavior;
+ }
+ }
+ }
+ if (enc_utf8) { /* produce UTF-8 */
+ dest -= utf_char2len(u8c);
+ (void)utf_char2bytes(u8c, dest);
+ } else { /* produce Latin1 */
+ --dest;
+ if (u8c >= 0x100) {
+ /* character doesn't fit in latin1, retry with
+ * another fenc when possible, otherwise just
+ * report the error. */
+ if (can_retry)
+ goto rewind_retry;
+ if (conv_error == 0)
+ conv_error = readfile_linenr(linecnt, ptr, p);
+ if (bad_char_behavior == BAD_DROP)
+ ++dest;
+ else if (bad_char_behavior == BAD_KEEP)
+ *dest = u8c;
+ else if (eap != NULL && eap->bad_char != 0)
+ *dest = bad_char_behavior;
+ else
+ *dest = 0xBF;
+ } else
+ *dest = u8c;
+ }
+ }
+
+ /* move the linerest to before the converted characters */
+ line_start = dest - linerest;
+ mch_memmove(line_start, buffer, (size_t)linerest);
+ size = (long)((ptr + real_size) - dest);
+ ptr = dest;
+ } else if (enc_utf8 && !curbuf->b_p_bin) {
+ int incomplete_tail = FALSE;
+
+ /* Reading UTF-8: Check if the bytes are valid UTF-8. */
+ for (p = ptr;; ++p) {
+ int todo = (int)((ptr + size) - p);
+ int l;
+
+ if (todo <= 0)
+ break;
+ if (*p >= 0x80) {
+ /* A length of 1 means it's an illegal byte. Accept
+ * an incomplete character at the end though, the next
+ * read() will get the next bytes, we'll check it
+ * then. */
+ l = utf_ptr2len_len(p, todo);
+ if (l > todo && !incomplete_tail) {
+ /* Avoid retrying with a different encoding when
+ * a truncated file is more likely, or attempting
+ * to read the rest of an incomplete sequence when
+ * we have already done so. */
+ if (p > ptr || filesize > 0)
+ incomplete_tail = TRUE;
+ /* Incomplete byte sequence, move it to conv_rest[]
+ * and try to read the rest of it, unless we've
+ * already done so. */
+ if (p > ptr) {
+ conv_restlen = todo;
+ mch_memmove(conv_rest, p, conv_restlen);
+ size -= conv_restlen;
+ break;
+ }
+ }
+ if (l == 1 || l > todo) {
+ /* Illegal byte. If we can try another encoding
+ * do that, unless at EOF where a truncated
+ * file is more likely than a conversion error. */
+ if (can_retry && !incomplete_tail)
+ break;
+# ifdef USE_ICONV
+ /* When we did a conversion report an error. */
+ if (iconv_fd != (iconv_t)-1 && conv_error == 0)
+ conv_error = readfile_linenr(linecnt, ptr, p);
+# endif
+ /* Remember the first linenr with an illegal byte */
+ if (conv_error == 0 && illegal_byte == 0)
+ illegal_byte = readfile_linenr(linecnt, ptr, p);
+
+ /* Drop, keep or replace the bad byte. */
+ if (bad_char_behavior == BAD_DROP) {
+ mch_memmove(p, p + 1, todo - 1);
+ --p;
+ --size;
+ } else if (bad_char_behavior != BAD_KEEP)
+ *p = bad_char_behavior;
+ } else
+ p += l - 1;
+ }
+ }
+ if (p < ptr + size && !incomplete_tail) {
+ /* Detected a UTF-8 error. */
+rewind_retry:
+ /* Retry reading with another conversion. */
+# if defined(FEAT_EVAL) && defined(USE_ICONV)
+ if (*p_ccv != NUL && iconv_fd != (iconv_t)-1)
+ /* iconv() failed, try 'charconvert' */
+ did_iconv = TRUE;
+ else
+# endif
+ /* use next item from 'fileencodings' */
+ advance_fenc = TRUE;
+ file_rewind = TRUE;
+ goto retry;
+ }
+ }
+
+ /* count the number of characters (after conversion!) */
+ filesize += size;
+
+ /*
+ * when reading the first part of a file: guess EOL type
+ */
+ if (fileformat == EOL_UNKNOWN) {
+ /* First try finding a NL, for Dos and Unix */
+ if (try_dos || try_unix) {
+ for (p = ptr; p < ptr + size; ++p) {
+ if (*p == NL) {
+ if (!try_unix
+ || (try_dos && p > ptr && p[-1] == CAR))
+ fileformat = EOL_DOS;
+ else
+ fileformat = EOL_UNIX;
+ break;
+ }
+ }
+
+ /* Don't give in to EOL_UNIX if EOL_MAC is more likely */
+ if (fileformat == EOL_UNIX && try_mac) {
+ /* Need to reset the counters when retrying fenc. */
+ try_mac = 1;
+ try_unix = 1;
+ for (; p >= ptr && *p != CAR; p--)
+ ;
+ if (p >= ptr) {
+ for (p = ptr; p < ptr + size; ++p) {
+ if (*p == NL)
+ try_unix++;
+ else if (*p == CAR)
+ try_mac++;
+ }
+ if (try_mac > try_unix)
+ fileformat = EOL_MAC;
+ }
+ }
+ }
+
+ /* No NL found: may use Mac format */
+ if (fileformat == EOL_UNKNOWN && try_mac)
+ fileformat = EOL_MAC;
+
+ /* Still nothing found? Use first format in 'ffs' */
+ if (fileformat == EOL_UNKNOWN)
+ fileformat = default_fileformat();
+
+ /* if editing a new file: may set p_tx and p_ff */
+ if (set_options)
+ set_fileformat(fileformat, OPT_LOCAL);
+ }
+ }
+
+ /*
+ * This loop is executed once for every character read.
+ * Keep it fast!
+ */
+ if (fileformat == EOL_MAC) {
+ --ptr;
+ while (++ptr, --size >= 0) {
+ /* catch most common case first */
+ if ((c = *ptr) != NUL && c != CAR && c != NL)
+ continue;
+ if (c == NUL)
+ *ptr = NL; /* NULs are replaced by newlines! */
+ else if (c == NL)
+ *ptr = CAR; /* NLs are replaced by CRs! */
+ else {
+ if (skip_count == 0) {
+ *ptr = NUL; /* end of line */
+ len = (colnr_T) (ptr - line_start + 1);
+ if (ml_append(lnum, line_start, len, newfile) == FAIL) {
+ error = TRUE;
+ break;
+ }
+ if (read_undo_file)
+ sha256_update(&sha_ctx, line_start, len);
+ ++lnum;
+ if (--read_count == 0) {
+ error = TRUE; /* break loop */
+ line_start = ptr; /* nothing left to write */
+ break;
+ }
+ } else
+ --skip_count;
+ line_start = ptr + 1;
+ }
+ }
+ } else {
+ --ptr;
+ while (++ptr, --size >= 0) {
+ if ((c = *ptr) != NUL && c != NL) /* catch most common case */
+ continue;
+ if (c == NUL)
+ *ptr = NL; /* NULs are replaced by newlines! */
+ else {
+ if (skip_count == 0) {
+ *ptr = NUL; /* end of line */
+ len = (colnr_T)(ptr - line_start + 1);
+ if (fileformat == EOL_DOS) {
+ if (ptr[-1] == CAR) { /* remove CR */
+ 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)) {
+ fileformat = EOL_UNIX;
+ if (set_options)
+ set_fileformat(EOL_UNIX, OPT_LOCAL);
+ file_rewind = TRUE;
+ keep_fileformat = TRUE;
+ goto retry;
+ }
+ ff_error = EOL_DOS;
+ }
+ }
+ if (ml_append(lnum, line_start, len, newfile) == FAIL) {
+ error = TRUE;
+ break;
+ }
+ if (read_undo_file)
+ sha256_update(&sha_ctx, line_start, len);
+ ++lnum;
+ if (--read_count == 0) {
+ error = TRUE; /* break loop */
+ line_start = ptr; /* nothing left to write */
+ break;
+ }
+ } else
+ --skip_count;
+ line_start = ptr + 1;
+ }
+ }
+ }
+ linerest = (long)(ptr - line_start);
+ ui_breakcheck();
+ }
+
+failed:
+ /* not an error, max. number of lines reached */
+ if (error && read_count == 0)
+ error = FALSE;
+
+ /*
+ * If we get EOF in the middle of a line, note the fact and
+ * complete the line ourselves.
+ * In Dos format ignore a trailing CTRL-Z, unless 'binary' set.
+ */
+ if (!error
+ && !got_int
+ && linerest != 0
+ && !(!curbuf->b_p_bin
+ && fileformat == EOL_DOS
+ && *line_start == Ctrl_Z
+ && ptr == line_start + 1)) {
+ /* remember for when writing */
+ if (set_options)
+ curbuf->b_p_eol = FALSE;
+ *ptr = NUL;
+ len = (colnr_T)(ptr - line_start + 1);
+ if (ml_append(lnum, line_start, len, newfile) == FAIL)
+ error = TRUE;
+ else {
+ if (read_undo_file)
+ sha256_update(&sha_ctx, line_start, len);
+ read_no_eol_lnum = ++lnum;
+ }
+ }
+
+ if (set_options)
+ save_file_ff(curbuf); /* remember the current file format */
+
+ crypt_method_used = use_crypt_method;
+ if (cryptkey != NULL) {
+ crypt_pop_state();
+ if (cryptkey != curbuf->b_p_key)
+ free_crypt_key(cryptkey);
+ /* don't set cryptkey to NULL, it's used below as a flag that
+ * encryption was used */
+ }
+
+ /* If editing a new file: set 'fenc' for the current buffer.
+ * Also for ":read ++edit file". */
+ if (set_options)
+ set_string_option_direct((char_u *)"fenc", -1, fenc,
+ OPT_FREE|OPT_LOCAL, 0);
+ if (fenc_alloced)
+ vim_free(fenc);
+# ifdef USE_ICONV
+ if (iconv_fd != (iconv_t)-1) {
+ iconv_close(iconv_fd);
+ iconv_fd = (iconv_t)-1;
+ }
+# 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)
+ fcntl(fd, F_SETFD, fdflags | FD_CLOEXEC);
+ }
+#endif
+ vim_free(buffer);
+
+#ifdef HAVE_DUP
+ if (read_stdin) {
+ /* Use stderr for stdin, makes shell commands work. */
+ close(0);
+ ignored = dup(2);
+ }
+#endif
+
+ if (tmpname != NULL) {
+ mch_remove(tmpname); /* delete converted file */
+ vim_free(tmpname);
+ }
+ --no_wait_return; /* may wait for return now */
+
+ /*
+ * In recovery mode everything but autocommands is skipped.
+ */
+ if (!recoverymode) {
+ /* need to delete the last line, which comes from the empty buffer */
+ if (newfile && wasempty && !(curbuf->b_ml.ml_flags & ML_EMPTY)) {
+ ml_delete(curbuf->b_ml.ml_line_count, FALSE);
+ --linecnt;
+ }
+ linecnt = curbuf->b_ml.ml_line_count - linecnt;
+ if (filesize == 0)
+ linecnt = 0;
+ if (newfile || read_buffer) {
+ redraw_curbuf_later(NOT_VALID);
+ /* After reading the text into the buffer the diff info needs to
+ * be updated. */
+ diff_invalidate(curbuf);
+ /* All folds in the window are invalid now. Mark them for update
+ * before triggering autocommands. */
+ foldUpdateAll(curwin);
+ } else if (linecnt) /* appended at least one line */
+ appended_lines_mark(from, linecnt);
+
+ /*
+ * If we were reading from the same terminal as where messages go,
+ * the screen will have been messed up.
+ * Switch on raw mode now and clear the screen.
+ */
+ if (read_stdin) {
+ settmode(TMODE_RAW); /* set to raw mode */
+ starttermcap();
+ screenclear();
+ }
+
+ if (got_int) {
+ if (!(flags & READ_DUMMY)) {
+ filemess(curbuf, sfname, (char_u *)_(e_interr), 0);
+ if (newfile)
+ curbuf->b_p_ro = TRUE; /* must use "w!" now */
+ }
+ msg_scroll = msg_save;
+ check_marks_read();
+ return OK; /* an interrupt isn't really an error */
+ }
+
+ if (!filtering && !(flags & READ_DUMMY)) {
+ msg_add_fname(curbuf, sfname); /* fname in IObuff with quotes */
+ c = FALSE;
+
+#ifdef UNIX
+# ifdef S_ISFIFO
+ if (S_ISFIFO(perm)) { /* fifo or socket */
+ STRCAT(IObuff, _("[fifo/socket]"));
+ c = TRUE;
+ }
+# else
+# ifdef S_IFIFO
+ if ((perm & S_IFMT) == S_IFIFO) { /* fifo */
+ STRCAT(IObuff, _("[fifo]"));
+ c = TRUE;
+ }
+# endif
+# ifdef S_IFSOCK
+ if ((perm & S_IFMT) == S_IFSOCK) { /* or socket */
+ STRCAT(IObuff, _("[socket]"));
+ c = TRUE;
+ }
+# endif
+# endif
+# ifdef OPEN_CHR_FILES
+ if (S_ISCHR(perm)) { /* or character special */
+ STRCAT(IObuff, _("[character special]"));
+ c = TRUE;
+ }
+# endif
+#endif
+ if (curbuf->b_p_ro) {
+ STRCAT(IObuff, shortmess(SHM_RO) ? _("[RO]") : _("[readonly]"));
+ c = TRUE;
+ }
+ if (read_no_eol_lnum) {
+ msg_add_eol();
+ c = TRUE;
+ }
+ if (ff_error == EOL_DOS) {
+ STRCAT(IObuff, _("[CR missing]"));
+ c = TRUE;
+ }
+ if (split) {
+ STRCAT(IObuff, _("[long lines split]"));
+ c = TRUE;
+ }
+ if (notconverted) {
+ STRCAT(IObuff, _("[NOT converted]"));
+ c = TRUE;
+ } else if (converted) {
+ STRCAT(IObuff, _("[converted]"));
+ c = TRUE;
+ }
+ if (cryptkey != NULL) {
+ if (crypt_method_used == 1)
+ STRCAT(IObuff, _("[blowfish]"));
+ else
+ STRCAT(IObuff, _("[crypted]"));
+ c = TRUE;
+ }
+ if (conv_error != 0) {
+ sprintf((char *)IObuff + STRLEN(IObuff),
+ _("[CONVERSION ERROR in line %ld]"), (long)conv_error);
+ c = TRUE;
+ } else if (illegal_byte > 0) {
+ sprintf((char *)IObuff + STRLEN(IObuff),
+ _("[ILLEGAL BYTE in line %ld]"), (long)illegal_byte);
+ c = TRUE;
+ } else if (error) {
+ STRCAT(IObuff, _("[READ ERRORS]"));
+ c = TRUE;
+ }
+ if (msg_add_fileformat(fileformat))
+ c = TRUE;
+ if (cryptkey != NULL)
+ msg_add_lines(c, (long)linecnt, filesize
+ - CRYPT_MAGIC_LEN
+ - crypt_salt_len[use_crypt_method]
+ - crypt_seed_len[use_crypt_method]);
+ else
+ msg_add_lines(c, (long)linecnt, filesize);
+
+ vim_free(keep_msg);
+ keep_msg = NULL;
+ msg_scrolled_ign = TRUE;
+ 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. */
+ set_keep_msg(p, 0);
+ msg_scrolled_ign = FALSE;
+ }
+
+ /* with errors writing the file requires ":w!" */
+ if (newfile && (error
+ || conv_error != 0
+ || (illegal_byte > 0 && bad_char_behavior != BAD_KEEP)
+ ))
+ curbuf->b_p_ro = TRUE;
+
+ u_clearline(); /* cannot use "U" command after adding lines */
+
+ /*
+ * In Ex mode: cursor at last new line.
+ * Otherwise: cursor at first new line.
+ */
+ if (exmode_active)
+ curwin->w_cursor.lnum = from + linecnt;
+ else
+ curwin->w_cursor.lnum = from + 1;
+ check_cursor_lnum();
+ beginline(BL_WHITE | BL_FIX); /* on first non-blank */
+
+ /*
+ * Set '[ and '] marks to the newly read lines.
+ */
+ curbuf->b_op_start.lnum = from + 1;
+ curbuf->b_op_start.col = 0;
+ curbuf->b_op_end.lnum = from + linecnt;
+ curbuf->b_op_end.col = 0;
+
+ }
+ msg_scroll = msg_save;
+
+ /*
+ * Get the marks before executing autocommands, so they can be used there.
+ */
+ check_marks_read();
+
+ /*
+ * Trick: We remember if the last line of the read didn't have
+ * an eol even when 'binary' is off, for when writing it again with
+ * 'binary' on. This is required for
+ * ":autocmd FileReadPost *.gz set bin|'[,']!gunzip" to work.
+ */
+ curbuf->b_no_eol_lnum = read_no_eol_lnum;
+
+ /* When reloading a buffer put the cursor at the first line that is
+ * different. */
+ if (flags & READ_KEEP_UNDO)
+ u_find_first_changed();
+
+ /*
+ * When opening a new file locate undo info and read it.
+ */
+ if (read_undo_file) {
+ char_u hash[UNDO_HASH_SIZE];
+
+ sha256_finish(&sha_ctx, hash);
+ u_read_undo(NULL, hash, fname);
+ }
+
+ if (!read_stdin && !read_buffer) {
+ int m = msg_scroll;
+ int n = msg_scrolled;
+
+ /* Save the fileformat now, otherwise the buffer will be considered
+ * modified if the format/encoding was automatically detected. */
+ if (set_options)
+ save_file_ff(curbuf);
+
+ /*
+ * 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_FILTERREADPOST, NULL, sfname,
+ FALSE, curbuf, eap);
+ else if (newfile)
+ apply_autocmds_exarg(EVENT_BUFREADPOST, NULL, sfname,
+ FALSE, curbuf, eap);
+ else
+ apply_autocmds_exarg(EVENT_FILEREADPOST, sfname, sfname,
+ FALSE, NULL, eap);
+ if (msg_scrolled == n)
+ msg_scroll = m;
+ if (aborting()) /* autocmds may abort script processing */
+ return FAIL;
+ }
+
+ if (recoverymode && error)
+ return FAIL;
+ return OK;
+}
+
+#ifdef OPEN_CHR_FILES
+/*
+ * Returns TRUE if the file name argument is of the form "/dev/fd/\d\+",
+ * which is the name of files used for process substitution output by
+ * some shells on some operating systems, e.g., bash on SunOS.
+ * Do not accept "/dev/fd/[012]", opening these may hang Vim.
+ */
+static int is_dev_fd_file(fname)
+char_u *fname;
+{
+ return STRNCMP(fname, "/dev/fd/", 8) == 0
+ && VIM_ISDIGIT(fname[8])
+ && *skipdigits(fname + 9) == NUL
+ && (fname[9] != NUL
+ || (fname[8] != '0' && fname[8] != '1' && fname[8] != '2'));
+}
+#endif
+
+
+/*
+ * From the current line count and characters read after that, estimate the
+ * line number where we are now.
+ * Used for error messages that include a line number.
+ */
+static linenr_T readfile_linenr(linecnt, p, endp)
+linenr_T linecnt; /* line count before reading more bytes */
+char_u *p; /* start of more bytes read */
+char_u *endp; /* end of more bytes read */
+{
+ char_u *s;
+ linenr_T lnum;
+
+ lnum = curbuf->b_ml.ml_line_count - linecnt + 1;
+ for (s = p; s < endp; ++s)
+ if (*s == '\n')
+ ++lnum;
+ return lnum;
+}
+
+/*
+ * Fill "*eap" to force the 'fileencoding', 'fileformat' and 'binary to be
+ * equal to the buffer "buf". Used for calling readfile().
+ * Returns OK or FAIL.
+ */
+int prep_exarg(eap, buf)
+exarg_T *eap;
+buf_T *buf;
+{
+ eap->cmd = alloc((unsigned)(STRLEN(buf->b_p_ff)
+ + STRLEN(buf->b_p_fenc)
+ + 15));
+ if (eap->cmd == NULL)
+ return FAIL;
+
+ sprintf((char *)eap->cmd, "e ++ff=%s ++enc=%s", buf->b_p_ff, buf->b_p_fenc);
+ eap->force_enc = 14 + (int)STRLEN(buf->b_p_ff);
+ eap->bad_char = buf->b_bad_char;
+ eap->force_ff = 7;
+
+ eap->force_bin = buf->b_p_bin ? FORCE_BIN : FORCE_NOBIN;
+ eap->read_edit = FALSE;
+ eap->forceit = FALSE;
+ return OK;
+}
+
+/*
+ * Set default or forced 'fileformat' and 'binary'.
+ */
+void set_file_options(set_options, eap)
+int set_options;
+exarg_T *eap;
+{
+ /* set default 'fileformat' */
+ if (set_options) {
+ if (eap != NULL && eap->force_ff != 0)
+ set_fileformat(get_fileformat_force(curbuf, eap), OPT_LOCAL);
+ else if (*p_ffs != NUL)
+ set_fileformat(default_fileformat(), OPT_LOCAL);
+ }
+
+ /* set or reset 'binary' */
+ if (eap != NULL && eap->force_bin != 0) {
+ int oldval = curbuf->b_p_bin;
+
+ curbuf->b_p_bin = (eap->force_bin == FORCE_BIN);
+ set_options_bin(oldval, curbuf->b_p_bin, OPT_LOCAL);
+ }
+}
+
+/*
+ * Set forced 'fileencoding'.
+ */
+void set_forced_fenc(eap)
+exarg_T *eap;
+{
+ if (eap->force_enc != 0) {
+ char_u *fenc = enc_canonize(eap->cmd + eap->force_enc);
+
+ if (fenc != NULL)
+ set_string_option_direct((char_u *)"fenc", -1,
+ fenc, OPT_FREE|OPT_LOCAL, 0);
+ vim_free(fenc);
+ }
+}
+
+/*
+ * Find next fileencoding to use from 'fileencodings'.
+ * "pp" points to fenc_next. It's advanced to the next item.
+ * When there are no more items, an empty string is returned and *pp is set to
+ * NULL.
+ * When *pp is not set to NULL, the result is in allocated memory.
+ */
+static char_u * next_fenc(pp)
+char_u **pp;
+{
+ char_u *p;
+ char_u *r;
+
+ if (**pp == NUL) {
+ *pp = NULL;
+ return (char_u *)"";
+ }
+ p = vim_strchr(*pp, ',');
+ if (p == NULL) {
+ r = enc_canonize(*pp);
+ *pp += STRLEN(*pp);
+ } else {
+ r = vim_strnsave(*pp, (int)(p - *pp));
+ *pp = p + 1;
+ if (r != NULL) {
+ p = enc_canonize(r);
+ vim_free(r);
+ r = p;
+ }
+ }
+ if (r == NULL) { /* out of memory */
+ r = (char_u *)"";
+ *pp = NULL;
+ }
+ return r;
+}
+
+/*
+ * Convert a file with the 'charconvert' expression.
+ * This closes the file which is to be read, converts it and opens the
+ * resulting file for reading.
+ * Returns name of the resulting converted file (the caller should delete it
+ * after reading it).
+ * Returns NULL if the conversion failed ("*fdp" is not set) .
+ */
+static char_u * readfile_charconvert(fname, fenc, fdp)
+char_u *fname; /* name of input file */
+char_u *fenc; /* converted from */
+int *fdp; /* in/out: file descriptor of file */
+{
+ char_u *tmpname;
+ char_u *errmsg = NULL;
+
+ tmpname = vim_tempname('r');
+ if (tmpname == NULL)
+ errmsg = (char_u *)_("Can't find temp file for conversion");
+ else {
+ close(*fdp); /* close the input file, ignore errors */
+ *fdp = -1;
+ if (eval_charconvert(fenc, enc_utf8 ? (char_u *)"utf-8" : p_enc,
+ fname, tmpname) == FAIL)
+ errmsg = (char_u *)_("Conversion with 'charconvert' failed");
+ if (errmsg == NULL && (*fdp = mch_open((char *)tmpname,
+ O_RDONLY | O_EXTRA, 0)) < 0)
+ errmsg = (char_u *)_("can't read output of 'charconvert'");
+ }
+
+ if (errmsg != NULL) {
+ /* Don't use emsg(), it breaks mappings, the retry with
+ * another type of conversion might still work. */
+ MSG(errmsg);
+ if (tmpname != NULL) {
+ mch_remove(tmpname); /* delete converted file */
+ vim_free(tmpname);
+ tmpname = NULL;
+ }
+ }
+
+ /* If the input file is closed, open it (caller should check for error). */
+ if (*fdp < 0)
+ *fdp = mch_open((char *)fname, O_RDONLY | O_EXTRA, 0);
+
+ return tmpname;
+}
+
+
+/*
+ * Read marks for the current buffer from the viminfo file, when we support
+ * buffer marks and the buffer has a name.
+ */
+static void check_marks_read() {
+ if (!curbuf->b_marks_read && get_viminfo_parameter('\'') > 0
+ && curbuf->b_ffname != NULL)
+ read_viminfo(NULL, VIF_WANT_MARKS);
+
+ /* Always set b_marks_read; needed when 'viminfo' is changed to include
+ * the ' parameter after opening a buffer. */
+ curbuf->b_marks_read = TRUE;
+}
+
+/*
+ * Get the crypt method used for a file from "ptr[len]", the magic text at the
+ * start of the file.
+ * Returns -1 when no encryption used.
+ */
+static int crypt_method_from_magic(ptr, len)
+char *ptr;
+int len;
+{
+ int i;
+
+ for (i = 0; i < (int)(sizeof(crypt_magic) / sizeof(crypt_magic[0])); i++) {
+ if (len < (CRYPT_MAGIC_LEN + crypt_salt_len[i] + crypt_seed_len[i]))
+ continue;
+ if (memcmp(ptr, crypt_magic[i], CRYPT_MAGIC_LEN) == 0)
+ return i;
+ }
+
+ i = (int)STRLEN(crypt_magic_head);
+ if (len >= i && memcmp(ptr, crypt_magic_head, i) == 0)
+ EMSG(_("E821: File is encrypted with unknown method"));
+
+ return -1;
+}
+
+/*
+ * Check for magic number used for encryption. Applies to the current buffer.
+ * If found, the magic number is removed from ptr[*sizep] and *sizep and
+ * *filesizep are updated.
+ * Return the (new) encryption key, NULL for no encryption.
+ */
+static char_u * check_for_cryptkey(cryptkey, ptr, sizep, filesizep, newfile,
+ fname,
+ did_ask)
+char_u *cryptkey; /* previous encryption key or NULL */
+char_u *ptr; /* pointer to read bytes */
+long *sizep; /* length of read bytes */
+off_t *filesizep; /* nr of bytes used from file */
+int newfile; /* editing a new buffer */
+char_u *fname; /* file name to display */
+int *did_ask; /* flag: whether already asked for key */
+{
+ int method = crypt_method_from_magic((char *)ptr, *sizep);
+ int b_p_ro = curbuf->b_p_ro;
+
+ if (method >= 0) {
+ /* Mark the buffer as read-only until the decryption has taken place.
+ * Avoids accidentally overwriting the file with garbage. */
+ curbuf->b_p_ro = TRUE;
+
+ set_crypt_method(curbuf, method);
+ if (method > 0)
+ (void)blowfish_self_test();
+ if (cryptkey == NULL && !*did_ask) {
+ if (*curbuf->b_p_key)
+ cryptkey = curbuf->b_p_key;
+ else {
+ /* When newfile is TRUE, store the typed key in the 'key'
+ * option and don't free it. bf needs hash of the key saved.
+ * Don't ask for the key again when first time Enter was hit.
+ * Happens when retrying to detect encoding. */
+ smsg((char_u *)_(need_key_msg), fname);
+ msg_scroll = TRUE;
+ cryptkey = get_crypt_key(newfile, FALSE);
+ *did_ask = TRUE;
+
+ /* check if empty key entered */
+ if (cryptkey != NULL && *cryptkey == NUL) {
+ if (cryptkey != curbuf->b_p_key)
+ vim_free(cryptkey);
+ cryptkey = NULL;
+ }
+ }
+ }
+
+ if (cryptkey != NULL) {
+ int seed_len = crypt_seed_len[method];
+ int salt_len = crypt_salt_len[method];
+
+ crypt_push_state();
+ use_crypt_method = method;
+ if (method == 0)
+ crypt_init_keys(cryptkey);
+ else {
+ bf_key_init(cryptkey, ptr + CRYPT_MAGIC_LEN, salt_len);
+ bf_ofb_init(ptr + CRYPT_MAGIC_LEN + salt_len, seed_len);
+ }
+
+ /* Remove magic number from the text */
+ *filesizep += CRYPT_MAGIC_LEN + salt_len + seed_len;
+ *sizep -= CRYPT_MAGIC_LEN + salt_len + seed_len;
+ mch_memmove(ptr, ptr + CRYPT_MAGIC_LEN + salt_len + seed_len,
+ (size_t)*sizep);
+ /* Restore the read-only flag. */
+ curbuf->b_p_ro = b_p_ro;
+ }
+ }
+ /* When starting to edit a new file which does not have encryption, clear
+ * the 'key' option, except when starting up (called with -x argument) */
+ else if (newfile && *curbuf->b_p_key != NUL && !starting)
+ set_option_value((char_u *)"key", 0L, (char_u *)"", OPT_LOCAL);
+
+ return cryptkey;
+}
+
+/*
+ * Check for magic number used for encryption. Applies to the current buffer.
+ * If found and decryption is possible returns OK;
+ */
+int prepare_crypt_read(fp)
+FILE *fp;
+{
+ int method;
+ char_u buffer[CRYPT_MAGIC_LEN + CRYPT_SALT_LEN_MAX
+ + CRYPT_SEED_LEN_MAX + 2];
+
+ if (fread(buffer, CRYPT_MAGIC_LEN, 1, fp) != 1)
+ return FAIL;
+ method = crypt_method_from_magic((char *)buffer,
+ CRYPT_MAGIC_LEN +
+ CRYPT_SEED_LEN_MAX +
+ CRYPT_SALT_LEN_MAX);
+ if (method < 0 || method != get_crypt_method(curbuf))
+ return FAIL;
+
+ crypt_push_state();
+ if (method == 0)
+ crypt_init_keys(curbuf->b_p_key);
+ else {
+ int salt_len = crypt_salt_len[method];
+ int seed_len = crypt_seed_len[method];
+
+ if (fread(buffer, salt_len + seed_len, 1, fp) != 1)
+ return FAIL;
+ bf_key_init(curbuf->b_p_key, buffer, salt_len);
+ bf_ofb_init(buffer + salt_len, seed_len);
+ }
+ return OK;
+}
+
+/*
+ * Prepare for writing encrypted bytes for buffer "buf".
+ * Returns a pointer to an allocated header of length "*lenp".
+ * When out of memory returns NULL.
+ * Otherwise calls crypt_push_state(), call crypt_pop_state() later.
+ */
+char_u * prepare_crypt_write(buf, lenp)
+buf_T *buf;
+int *lenp;
+{
+ char_u *header;
+ int seed_len = crypt_seed_len[get_crypt_method(buf)];
+ int salt_len = crypt_salt_len[get_crypt_method(buf)];
+ char_u *salt;
+ char_u *seed;
+
+ header = alloc_clear(CRYPT_MAGIC_LEN + CRYPT_SALT_LEN_MAX
+ + CRYPT_SEED_LEN_MAX + 2);
+ if (header != NULL) {
+ crypt_push_state();
+ use_crypt_method = get_crypt_method(buf); /* select zip or blowfish */
+ vim_strncpy(header, (char_u *)crypt_magic[use_crypt_method],
+ CRYPT_MAGIC_LEN);
+ if (use_crypt_method == 0)
+ crypt_init_keys(buf->b_p_key);
+ else {
+ /* Using blowfish, add salt and seed. */
+ salt = header + CRYPT_MAGIC_LEN;
+ seed = salt + salt_len;
+ sha2_seed(salt, salt_len, seed, seed_len);
+ bf_key_init(buf->b_p_key, salt, salt_len);
+ bf_ofb_init(seed, seed_len);
+ }
+ }
+ *lenp = CRYPT_MAGIC_LEN + salt_len + seed_len;
+ return header;
+}
+
+
+#ifdef UNIX
+static void set_file_time(fname, atime, mtime)
+char_u *fname;
+time_t atime; /* access time */
+time_t mtime; /* modification time */
+{
+# if defined(HAVE_UTIME) && defined(HAVE_UTIME_H)
+ struct utimbuf buf;
+
+ buf.actime = atime;
+ buf.modtime = mtime;
+ (void)utime((char *)fname, &buf);
+# else
+# if defined(HAVE_UTIMES)
+ struct timeval tvp[2];
+
+ tvp[0].tv_sec = atime;
+ tvp[0].tv_usec = 0;
+ tvp[1].tv_sec = mtime;
+ tvp[1].tv_usec = 0;
+ (void)utimes((char *)fname, (const struct timeval *)&tvp);
+# endif
+# endif
+}
+#endif /* UNIX */
+
+
+/*
+ * Return TRUE if a file appears to be read-only from the file permissions.
+ */
+int check_file_readonly(fname, perm)
+char_u *fname; /* full path to file */
+int perm; /* known permissions on file */
+{
+#ifndef USE_MCH_ACCESS
+ int fd = 0;
+#endif
+
+ return
+#ifdef USE_MCH_ACCESS
+# ifdef UNIX
+ (perm & 0222) == 0 ||
+# endif
+ mch_access((char *)fname, W_OK)
+#else
+ (fd = mch_open((char *)fname, O_RDWR | O_EXTRA, 0)) < 0
+ ? TRUE : (close(fd), FALSE)
+#endif
+ ;
+}
+
+
+/*
+ * buf_write() - write to file "fname" lines "start" through "end"
+ *
+ * We do our own buffering here because fwrite() is so slow.
+ *
+ * If "forceit" is true, we don't care for errors when attempting backups.
+ * In case of an error everything possible is done to restore the original
+ * file. But when "forceit" is TRUE, we risk losing it.
+ *
+ * When "reset_changed" is TRUE and "append" == FALSE and "start" == 1 and
+ * "end" == curbuf->b_ml.ml_line_count, reset curbuf->b_changed.
+ *
+ * This function must NOT use NameBuff (because it's called by autowrite()).
+ *
+ * return FAIL for failure, OK otherwise
+ */
+int buf_write(buf, fname, sfname, start, end, eap, append, forceit,
+ reset_changed, filtering)
+buf_T *buf;
+char_u *fname;
+char_u *sfname;
+linenr_T start, end;
+exarg_T *eap; /* for forced 'ff' and 'fenc', can be
+ NULL! */
+int append; /* append to the file */
+int forceit;
+int reset_changed;
+int filtering;
+{
+ int fd;
+ char_u *backup = NULL;
+ int backup_copy = FALSE; /* copy the original file? */
+ int dobackup;
+ char_u *ffname;
+ char_u *wfname = NULL; /* name of file to write to */
+ char_u *s;
+ char_u *ptr;
+ char_u c;
+ int len;
+ linenr_T lnum;
+ long nchars;
+ char_u *errmsg = NULL;
+ int errmsg_allocated = FALSE;
+ char_u *errnum = NULL;
+ char_u *buffer;
+ char_u smallbuf[SMBUFSIZE];
+ char_u *backup_ext;
+ int bufsize;
+ long perm; /* file permissions */
+ int retval = OK;
+ 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 */
+ struct stat st_old;
+ int prev_got_int = got_int;
+ int file_readonly = FALSE; /* overwritten file is read-only */
+ static char *err_readonly =
+ "is read-only (cannot override: \"W\" in 'cpoptions')";
+#if defined(UNIX) || defined(__EMX__XX) /*XXX fix me sometime? */
+ int made_writable = FALSE; /* 'w' bit has been set */
+#endif
+ /* 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() */
+ int converted = FALSE;
+ int notconverted = FALSE;
+ char_u *fenc; /* effective 'fileencoding' */
+ char_u *fenc_tofree = NULL; /* allocated "fenc" */
+#ifdef HAS_BW_FLAGS
+ int wb_flags = 0;
+#endif
+#ifdef HAVE_ACL
+ vim_acl_T acl = NULL; /* ACL copied from original file to
+ backup or new file */
+#endif
+ int write_undo_file = FALSE;
+ context_sha256_T sha_ctx;
+ int crypt_method_used;
+
+ if (fname == NULL || *fname == NUL) /* safety check */
+ return FAIL;
+ if (buf->b_ml.ml_mfp == NULL) {
+ /* This can happen during startup when there is a stray "w" in the
+ * vimrc file. */
+ EMSG(_(e_emptybuf));
+ return FAIL;
+ }
+
+ /*
+ * Disallow writing from .exrc and .vimrc in current directory for
+ * security reasons.
+ */
+ if (check_secure())
+ return FAIL;
+
+ /* Avoid a crash for a long name. */
+ if (STRLEN(fname) >= MAXPATHL) {
+ EMSG(_(e_longname));
+ return FAIL;
+ }
+
+ /* must init bw_conv_buf and bw_iconv_fd before jumping to "fail" */
+ write_info.bw_conv_buf = NULL;
+ write_info.bw_conv_error = FALSE;
+ write_info.bw_conv_error_lnum = 0;
+ write_info.bw_restlen = 0;
+# ifdef USE_ICONV
+ write_info.bw_iconv_fd = (iconv_t)-1;
+# endif
+
+ /* After writing a file changedtick changes but we don't want to display
+ * the line. */
+ ex_no_reprint = TRUE;
+
+ /*
+ * If there is no file name yet, use the one for the written file.
+ * BF_NOTEDITED is set to reflect this (in case the write fails).
+ * Don't do this when the write is for a filter command.
+ * Don't do this when appending.
+ * Only do this when 'cpoptions' contains the 'F' flag.
+ */
+ if (buf->b_ffname == NULL
+ && reset_changed
+ && whole
+ && buf == curbuf
+ && !bt_nofile(buf)
+ && !filtering
+ && (!append || vim_strchr(p_cpo, CPO_FNAMEAPP) != NULL)
+ && vim_strchr(p_cpo, CPO_FNAMEW) != NULL) {
+ if (set_rw_fname(fname, sfname) == FAIL)
+ return FAIL;
+ buf = curbuf; /* just in case autocmds made "buf" invalid */
+ }
+
+ if (sfname == NULL)
+ sfname = fname;
+ /*
+ * For Unix: Use the short file name whenever possible.
+ * Avoids problems with networks and when directory names are changed.
+ * Don't do this for MS-DOS, a "cd" in a sub-shell may have moved us to
+ * another directory, which we don't detect
+ */
+ ffname = fname; /* remember full fname */
+#ifdef UNIX
+ fname = sfname;
+#endif
+
+ if (buf->b_ffname != NULL && fnamecmp(ffname, buf->b_ffname) == 0)
+ overwriting = TRUE;
+ else
+ overwriting = FALSE;
+
+ if (exiting)
+ settmode(TMODE_COOK); /* when exiting allow typeahead now */
+
+ ++no_wait_return; /* don't wait for return yet */
+
+ /*
+ * Set '[ and '] marks to the lines to be written.
+ */
+ buf->b_op_start.lnum = start;
+ buf->b_op_start.col = 0;
+ buf->b_op_end.lnum = end;
+ buf->b_op_end.col = 0;
+
+ {
+ aco_save_T aco;
+ int buf_ffname = FALSE;
+ int buf_sfname = FALSE;
+ int buf_fname_f = FALSE;
+ int buf_fname_s = FALSE;
+ int did_cmd = FALSE;
+ int nofile_err = FALSE;
+ int empty_memline = (buf->b_ml.ml_mfp == NULL);
+
+ /*
+ * Apply PRE autocommands.
+ * Set curbuf to the buffer to be written.
+ * Careful: The autocommands may call buf_write() recursively!
+ */
+ if (ffname == buf->b_ffname)
+ buf_ffname = TRUE;
+ if (sfname == buf->b_sfname)
+ buf_sfname = TRUE;
+ if (fname == buf->b_ffname)
+ buf_fname_f = TRUE;
+ if (fname == buf->b_sfname)
+ buf_fname_s = TRUE;
+
+ /* set curwin/curbuf to buf and save a few things */
+ aucmd_prepbuf(&aco, buf);
+
+ if (append) {
+ if (!(did_cmd = apply_autocmds_exarg(EVENT_FILEAPPENDCMD,
+ sfname, sfname, FALSE, curbuf, eap))) {
+ if (overwriting && bt_nofile(curbuf))
+ nofile_err = TRUE;
+ else
+ apply_autocmds_exarg(EVENT_FILEAPPENDPRE,
+ sfname, sfname, FALSE, curbuf, eap);
+ }
+ } else if (filtering) {
+ apply_autocmds_exarg(EVENT_FILTERWRITEPRE,
+ NULL, sfname, FALSE, curbuf, eap);
+ } else if (reset_changed && whole) {
+ int was_changed = curbufIsChanged();
+
+ did_cmd = apply_autocmds_exarg(EVENT_BUFWRITECMD,
+ sfname, sfname, FALSE, curbuf, eap);
+ if (did_cmd) {
+ if (was_changed && !curbufIsChanged()) {
+ /* Written everything correctly and BufWriteCmd has reset
+ * 'modified': Correct the undo information so that an
+ * undo now sets 'modified'. */
+ u_unchanged(curbuf);
+ u_update_save_nr(curbuf);
+ }
+ } else {
+ if (overwriting && bt_nofile(curbuf))
+ nofile_err = TRUE;
+ else
+ apply_autocmds_exarg(EVENT_BUFWRITEPRE,
+ sfname, sfname, FALSE, curbuf, eap);
+ }
+ } else {
+ if (!(did_cmd = apply_autocmds_exarg(EVENT_FILEWRITECMD,
+ sfname, sfname, FALSE, curbuf, eap))) {
+ if (overwriting && bt_nofile(curbuf))
+ nofile_err = TRUE;
+ else
+ apply_autocmds_exarg(EVENT_FILEWRITEPRE,
+ sfname, sfname, FALSE, curbuf, eap);
+ }
+ }
+
+ /* 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))
+ buf = NULL;
+ if (buf == NULL || (buf->b_ml.ml_mfp == NULL && !empty_memline)
+ || did_cmd || nofile_err
+ || aborting()
+ ) {
+ --no_wait_return;
+ msg_scroll = msg_save;
+ if (nofile_err)
+ EMSG(_("E676: No matching autocommands for acwrite buffer"));
+
+ if (nofile_err
+ || aborting()
+ )
+ /* An aborting error, interrupt or exception in the
+ * autocommands. */
+ return FAIL;
+ if (did_cmd) {
+ if (buf == NULL)
+ /* The buffer was deleted. We assume it was written
+ * (can't retry anyway). */
+ return OK;
+ if (overwriting) {
+ /* Assume the buffer was written, update the timestamp. */
+ ml_timestamp(buf);
+ if (append)
+ buf->b_flags &= ~BF_NEW;
+ else
+ buf->b_flags &= ~BF_WRITE_MASK;
+ }
+ if (reset_changed && buf->b_changed && !append
+ && (overwriting || vim_strchr(p_cpo, CPO_PLUS) != NULL))
+ /* Buffer still changed, the autocommands didn't work
+ * properly. */
+ return FAIL;
+ return OK;
+ }
+ if (!aborting())
+ EMSG(_("E203: Autocommands deleted or unloaded buffer to be written"));
+ return FAIL;
+ }
+
+ /*
+ * The autocommands may have changed the number of lines in the file.
+ * When writing the whole file, adjust the end.
+ * When writing part of the file, assume that the autocommands only
+ * changed the number of lines that are to be written (tricky!).
+ */
+ if (buf->b_ml.ml_line_count != old_line_count) {
+ if (whole) /* write all */
+ end = buf->b_ml.ml_line_count;
+ else if (buf->b_ml.ml_line_count > old_line_count) /* more lines */
+ end += buf->b_ml.ml_line_count - old_line_count;
+ else { /* less lines */
+ end -= old_line_count - buf->b_ml.ml_line_count;
+ if (end < start) {
+ --no_wait_return;
+ msg_scroll = msg_save;
+ EMSG(_("E204: Autocommand changed number of lines in unexpected way"));
+ return FAIL;
+ }
+ }
+ }
+
+ /*
+ * The autocommands may have changed the name of the buffer, which may
+ * be kept in fname, ffname and sfname.
+ */
+ if (buf_ffname)
+ ffname = buf->b_ffname;
+ if (buf_sfname)
+ sfname = buf->b_sfname;
+ if (buf_fname_f)
+ fname = buf->b_ffname;
+ if (buf_fname_s)
+ fname = buf->b_sfname;
+ }
+
+
+ if (shortmess(SHM_OVER) && !exiting)
+ msg_scroll = FALSE; /* overwrite previous file message */
+ else
+ msg_scroll = TRUE; /* don't overwrite previous file message */
+ if (!filtering)
+ filemess(buf,
+#ifndef UNIX
+ sfname,
+#else
+ fname,
+#endif
+ (char_u *)"", 0); /* show that we are busy */
+ msg_scroll = FALSE; /* always overwrite the file message now */
+
+ buffer = alloc(BUFSIZE);
+ if (buffer == NULL) { /* can't allocate big buffer, use small
+ * one (to be able to write when out of
+ * memory) */
+ buffer = smallbuf;
+ bufsize = SMBUFSIZE;
+ } else
+ bufsize = BUFSIZE;
+
+ /*
+ * Get information about original file (if there is one).
+ */
+#if defined(UNIX) && !defined(ARCHIE)
+ st_old.st_dev = 0;
+ st_old.st_ino = 0;
+ perm = -1;
+ if (mch_stat((char *)fname, &st_old) < 0)
+ newfile = TRUE;
+ else {
+ perm = st_old.st_mode;
+ if (!S_ISREG(st_old.st_mode)) { /* not a file */
+ if (S_ISDIR(st_old.st_mode)) {
+ errnum = (char_u *)"E502: ";
+ errmsg = (char_u *)_("is a directory");
+ goto fail;
+ }
+ if (mch_nodetype(fname) != NODE_WRITABLE) {
+ errnum = (char_u *)"E503: ";
+ errmsg = (char_u *)_("is not a file or writable device");
+ goto fail;
+ }
+ /* It's a device of some kind (or a fifo) which we can write to
+ * but for which we can't make a backup. */
+ device = TRUE;
+ newfile = TRUE;
+ perm = -1;
+ }
+ }
+#else /* !UNIX */
+ /*
+ * Check for a writable device name.
+ */
+ c = mch_nodetype(fname);
+ if (c == NODE_OTHER) {
+ errnum = (char_u *)"E503: ";
+ errmsg = (char_u *)_("is not a file or writable device");
+ goto fail;
+ }
+ if (c == NODE_WRITABLE) {
+ device = TRUE;
+ newfile = TRUE;
+ perm = -1;
+ } else {
+ perm = mch_getperm(fname);
+ if (perm < 0)
+ newfile = TRUE;
+ else if (mch_isdir(fname)) {
+ errnum = (char_u *)"E502: ";
+ errmsg = (char_u *)_("is a directory");
+ goto fail;
+ }
+ if (overwriting)
+ (void)mch_stat((char *)fname, &st_old);
+ }
+#endif /* !UNIX */
+
+ if (!device && !newfile) {
+ /*
+ * Check if the file is really writable (when renaming the file to
+ * make a backup we won't discover it later).
+ */
+ file_readonly = check_file_readonly(fname, (int)perm);
+
+ if (!forceit && file_readonly) {
+ if (vim_strchr(p_cpo, CPO_FWRITE) != NULL) {
+ errnum = (char_u *)"E504: ";
+ errmsg = (char_u *)_(err_readonly);
+ } else {
+ errnum = (char_u *)"E505: ";
+ errmsg = (char_u *)_("is read-only (add ! to override)");
+ }
+ goto fail;
+ }
+
+ /*
+ * Check if the timestamp hasn't changed since reading the file.
+ */
+ if (overwriting) {
+ retval = check_mtime(buf, &st_old);
+ if (retval == FAIL)
+ goto fail;
+ }
+ }
+
+#ifdef HAVE_ACL
+ /*
+ * For systems that support ACL: get the ACL from the original file.
+ */
+ if (!newfile)
+ acl = mch_get_acl(fname);
+#endif
+
+ /*
+ * If 'backupskip' is not empty, don't make a backup for some files.
+ */
+ dobackup = (p_wb || p_bk || *p_pm != NUL);
+ if (dobackup && *p_bsk != NUL && match_file_list(p_bsk, sfname, ffname))
+ dobackup = FALSE;
+
+ /*
+ * Save the value of got_int and reset it. We don't want a previous
+ * interruption cancel writing, only hitting CTRL-C while writing should
+ * abort it.
+ */
+ prev_got_int = got_int;
+ got_int = FALSE;
+
+ /* Mark the buffer as 'being saved' to prevent changed buffer warnings */
+ buf->b_saving = TRUE;
+
+ /*
+ * If we are not appending or filtering, the file exists, and the
+ * 'writebackup', 'backup' or 'patchmode' option is set, need a backup.
+ * When 'patchmode' is set also make a backup when appending.
+ *
+ * Do not make any backup, if 'writebackup' and 'backup' are both switched
+ * off. This helps when editing large files on almost-full disks.
+ */
+ if (!(append && *p_pm == NUL) && !filtering && perm >= 0 && dobackup) {
+#if defined(UNIX) || defined(WIN32)
+ struct stat st;
+#endif
+
+ if ((bkc_flags & BKC_YES) || append) /* "yes" */
+ backup_copy = TRUE;
+#if defined(UNIX) || defined(WIN32)
+ else if ((bkc_flags & BKC_AUTO)) { /* "auto" */
+ int i;
+
+# ifdef UNIX
+ /*
+ * Don't rename the file when:
+ * - it's a hard link
+ * - it's a symbolic link
+ * - we don't have write permission in the directory
+ * - we can't set the owner/group of the new file
+ */
+ if (st_old.st_nlink > 1
+ || mch_lstat((char *)fname, &st) < 0
+ || st.st_dev != st_old.st_dev
+ || st.st_ino != st_old.st_ino
+# ifndef HAVE_FCHOWN
+ || st.st_uid != st_old.st_uid
+ || st.st_gid != st_old.st_gid
+# endif
+ )
+ backup_copy = TRUE;
+ else
+# else
+# endif
+ {
+ /*
+ * Check if we can create a file and set the owner/group to
+ * the ones from the original file.
+ * First find a file name that doesn't exist yet (use some
+ * arbitrary numbers).
+ */
+ STRCPY(IObuff, fname);
+ for (i = 4913;; i += 123) {
+ sprintf((char *)gettail(IObuff), "%d", i);
+ if (mch_lstat((char *)IObuff, &st) < 0)
+ break;
+ }
+ fd = mch_open((char *)IObuff,
+ O_CREAT|O_WRONLY|O_EXCL|O_NOFOLLOW, perm);
+ if (fd < 0) /* can't write in directory */
+ backup_copy = TRUE;
+ else {
+# ifdef UNIX
+# ifdef HAVE_FCHOWN
+ ignored = fchown(fd, st_old.st_uid, st_old.st_gid);
+# endif
+ if (mch_stat((char *)IObuff, &st) < 0
+ || st.st_uid != st_old.st_uid
+ || st.st_gid != st_old.st_gid
+ || (long)st.st_mode != perm)
+ backup_copy = TRUE;
+# endif
+ /* Close the file before removing it, on MS-Windows we
+ * can't delete an open file. */
+ close(fd);
+ mch_remove(IObuff);
+ }
+ }
+ }
+
+ /*
+ * Break symlinks and/or hardlinks if we've been asked to.
+ */
+ if ((bkc_flags & BKC_BREAKSYMLINK) || (bkc_flags & BKC_BREAKHARDLINK)) {
+# ifdef UNIX
+ int lstat_res;
+
+ lstat_res = mch_lstat((char *)fname, &st);
+
+ /* Symlinks. */
+ if ((bkc_flags & BKC_BREAKSYMLINK)
+ && lstat_res == 0
+ && st.st_ino != st_old.st_ino)
+ backup_copy = FALSE;
+
+ /* Hardlinks. */
+ if ((bkc_flags & BKC_BREAKHARDLINK)
+ && st_old.st_nlink > 1
+ && (lstat_res != 0 || st.st_ino == st_old.st_ino))
+ backup_copy = FALSE;
+# else
+# endif
+ }
+
+#endif
+
+ /* make sure we have a valid backup extension to use */
+ if (*p_bex == NUL)
+ backup_ext = (char_u *)".bak";
+ else
+ backup_ext = p_bex;
+
+ if (backup_copy
+ && (fd = mch_open((char *)fname, O_RDONLY | O_EXTRA, 0)) >= 0) {
+ int bfd;
+ char_u *copybuf, *wp;
+ int some_error = FALSE;
+ struct stat st_new;
+ char_u *dirp;
+ char_u *rootname;
+#if defined(UNIX) && !defined(SHORT_FNAME)
+ int did_set_shortname;
+#endif
+
+ copybuf = alloc(BUFSIZE + 1);
+ if (copybuf == NULL) {
+ some_error = TRUE; /* out of memory */
+ goto nobackup;
+ }
+
+ /*
+ * Try to make the backup in each directory in the 'bdir' option.
+ *
+ * Unix semantics has it, that we may have a writable file,
+ * that cannot be recreated with a simple open(..., O_CREAT, ) e.g:
+ * - the directory is not writable,
+ * - the file may be a symbolic link,
+ * - the file may belong to another user/group, etc.
+ *
+ * For these reasons, the existing writable file must be truncated
+ * and reused. Creation of a backup COPY will be attempted.
+ */
+ dirp = p_bdir;
+ while (*dirp) {
+#ifdef UNIX
+ st_new.st_ino = 0;
+ st_new.st_dev = 0;
+ st_new.st_gid = 0;
+#endif
+
+ /*
+ * Isolate one directory name, using an entry in 'bdir'.
+ */
+ (void)copy_option_part(&dirp, copybuf, BUFSIZE, ",");
+ rootname = get_file_in_dir(fname, copybuf);
+ if (rootname == NULL) {
+ some_error = TRUE; /* out of memory */
+ goto nobackup;
+ }
+
+#if defined(UNIX) && !defined(SHORT_FNAME)
+ did_set_shortname = FALSE;
+#endif
+
+ /*
+ * May try twice if 'shortname' not set.
+ */
+ for (;; ) {
+ /*
+ * Make backup file name.
+ */
+ backup = buf_modname(
+#ifdef SHORT_FNAME
+ TRUE,
+#else
+ (buf->b_p_sn || buf->b_shortname),
+#endif
+ rootname, backup_ext, FALSE);
+ if (backup == NULL) {
+ vim_free(rootname);
+ some_error = TRUE; /* out of memory */
+ goto nobackup;
+ }
+
+ /*
+ * Check if backup file already exists.
+ */
+ if (mch_stat((char *)backup, &st_new) >= 0) {
+#ifdef UNIX
+ /*
+ * Check if backup file is same as original file.
+ * May happen when modname() gave the same file back.
+ * E.g. silly link, or file name-length reached.
+ * If we don't check here, we either ruin the file
+ * when copying or erase it after writing. jw.
+ */
+ if (st_new.st_dev == st_old.st_dev
+ && st_new.st_ino == st_old.st_ino) {
+ vim_free(backup);
+ backup = NULL; /* no backup file to delete */
+# ifndef SHORT_FNAME
+ /*
+ * may try again with 'shortname' set
+ */
+ if (!(buf->b_shortname || buf->b_p_sn)) {
+ buf->b_shortname = TRUE;
+ did_set_shortname = TRUE;
+ continue;
+ }
+ /* setting shortname didn't help */
+ if (did_set_shortname)
+ buf->b_shortname = FALSE;
+# endif
+ break;
+ }
+#endif
+
+ /*
+ * If we are not going to keep the backup file, don't
+ * delete an existing one, try to use another name.
+ * Change one character, just before the extension.
+ */
+ if (!p_bk) {
+ wp = backup + STRLEN(backup) - 1
+ - STRLEN(backup_ext);
+ if (wp < backup) /* empty file name ??? */
+ wp = backup;
+ *wp = 'z';
+ while (*wp > 'a'
+ && mch_stat((char *)backup, &st_new) >= 0)
+ --*wp;
+ /* They all exist??? Must be something wrong. */
+ if (*wp == 'a') {
+ vim_free(backup);
+ backup = NULL;
+ }
+ }
+ }
+ break;
+ }
+ vim_free(rootname);
+
+ /*
+ * Try to create the backup file
+ */
+ if (backup != NULL) {
+ /* remove old backup, if present */
+ mch_remove(backup);
+ /* Open with O_EXCL to avoid the file being created while
+ * we were sleeping (symlink hacker attack?) */
+ bfd = mch_open((char *)backup,
+ O_WRONLY|O_CREAT|O_EXTRA|O_EXCL|O_NOFOLLOW,
+ perm & 0777);
+ if (bfd < 0) {
+ vim_free(backup);
+ backup = NULL;
+ } else {
+ /* set file protection same as original file, but
+ * strip s-bit */
+ (void)mch_setperm(backup, perm & 0777);
+
+#ifdef UNIX
+ /*
+ * Try to set the group of the backup same as the
+ * original file. If this fails, set the protection
+ * bits for the group same as the protection bits for
+ * others.
+ */
+ if (st_new.st_gid != st_old.st_gid
+# ifdef HAVE_FCHOWN /* sequent-ptx lacks fchown() */
+ && fchown(bfd, (uid_t)-1, st_old.st_gid) != 0
+# endif
+ )
+ mch_setperm(backup,
+ (perm & 0707) | ((perm & 07) << 3));
+# ifdef HAVE_SELINUX
+ mch_copy_sec(fname, backup);
+# endif
+#endif
+
+ /*
+ * copy the file.
+ */
+ write_info.bw_fd = bfd;
+ write_info.bw_buf = copybuf;
+#ifdef HAS_BW_FLAGS
+ write_info.bw_flags = FIO_NOCONVERT;
+#endif
+ 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)");
+ break;
+ }
+ ui_breakcheck();
+ if (got_int) {
+ errmsg = (char_u *)_(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)");
+#ifdef UNIX
+ set_file_time(backup, st_old.st_atime, st_old.st_mtime);
+#endif
+#ifdef HAVE_ACL
+ mch_set_acl(backup, acl);
+#endif
+#ifdef HAVE_SELINUX
+ mch_copy_sec(fname, backup);
+#endif
+ break;
+ }
+ }
+ }
+nobackup:
+ close(fd); /* ignore errors for closing read file */
+ vim_free(copybuf);
+
+ if (backup == NULL && errmsg == NULL)
+ errmsg = (char_u *)_(
+ "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;
+ } else {
+ char_u *dirp;
+ char_u *p;
+ char_u *rootname;
+
+ /*
+ * Make a backup by renaming the original file.
+ */
+ /*
+ * If 'cpoptions' includes the "W" flag, we don't want to
+ * overwrite a read-only file. But rename may be possible
+ * 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);
+ goto fail;
+ }
+
+ /*
+ *
+ * Form the backup file name - change path/fo.o.h to
+ * path/fo.o.h.bak Try all directories in 'backupdir', first one
+ * that works is used.
+ */
+ dirp = p_bdir;
+ while (*dirp) {
+ /*
+ * Isolate one directory name and make the backup file name.
+ */
+ (void)copy_option_part(&dirp, IObuff, IOSIZE, ",");
+ rootname = get_file_in_dir(fname, IObuff);
+ if (rootname == NULL)
+ backup = NULL;
+ else {
+ backup = buf_modname(
+#ifdef SHORT_FNAME
+ TRUE,
+#else
+ (buf->b_p_sn || buf->b_shortname),
+#endif
+ rootname, backup_ext, FALSE);
+ vim_free(rootname);
+ }
+
+ if (backup != NULL) {
+ /*
+ * If we are not going to keep the backup file, don't
+ * delete an existing one, try to use another name.
+ * Change one character, just before the extension.
+ */
+ if (!p_bk && mch_getperm(backup) >= 0) {
+ p = backup + STRLEN(backup) - 1 - STRLEN(backup_ext);
+ if (p < backup) /* empty file name ??? */
+ p = backup;
+ *p = 'z';
+ while (*p > 'a' && mch_getperm(backup) >= 0)
+ --*p;
+ /* They all exist??? Must be something wrong! */
+ if (*p == 'a') {
+ vim_free(backup);
+ backup = NULL;
+ }
+ }
+ }
+ if (backup != NULL) {
+ /*
+ * Delete any existing backup and move the current version
+ * to the backup. For safety, we don't remove the backup
+ * until the write has finished successfully. And if the
+ * 'backup' option is set, leave it around.
+ */
+ /*
+ * If the renaming of the original file to the backup file
+ * works, quit here.
+ */
+ if (vim_rename(fname, backup) == 0)
+ break;
+
+ vim_free(backup); /* don't do the rename below */
+ backup = NULL;
+ }
+ }
+ if (backup == NULL && !forceit) {
+ errmsg = (char_u *)_("E510: Can't make backup file (add ! to override)");
+ goto fail;
+ }
+ }
+ }
+
+#if defined(UNIX) && !defined(ARCHIE)
+ /* When using ":w!" and the file was read-only: make it writable */
+ if (forceit && perm >= 0 && !(perm & 0200) && st_old.st_uid == getuid()
+ && vim_strchr(p_cpo, CPO_FWRITE) == NULL) {
+ perm |= 0200;
+ (void)mch_setperm(fname, perm);
+ made_writable = TRUE;
+ }
+#endif
+
+ /* When using ":w!" and writing to the current file, 'readonly' makes no
+ * sense, reset it, unless 'Z' appears in 'cpoptions'. */
+ if (forceit && overwriting && vim_strchr(p_cpo, CPO_KEEPRO) == NULL) {
+ buf->b_p_ro = FALSE;
+ need_maketitle = TRUE; /* set window title later */
+ status_redraw_all(); /* redraw status lines later */
+ }
+
+ if (end > buf->b_ml.ml_line_count)
+ end = buf->b_ml.ml_line_count;
+ if (buf->b_ml.ml_flags & ML_EMPTY)
+ start = end + 1;
+
+ /*
+ * If the original file is being overwritten, there is a small chance that
+ * we crash in the middle of writing. Therefore the file is preserved now.
+ * This makes all block numbers positive so that recovery does not need
+ * the original file.
+ * Don't do this if there is a backup file and we are exiting.
+ */
+ if (reset_changed && !newfile && overwriting
+ && !(exiting && backup != NULL)) {
+ ml_preserve(buf, FALSE);
+ if (got_int) {
+ errmsg = (char_u *)_(e_interr);
+ goto restore_backup;
+ }
+ }
+
+
+ /* Default: write the file directly. May write to a temp file for
+ * multi-byte conversion. */
+ wfname = fname;
+
+ /* Check for forced 'fileencoding' from "++opt=val" argument. */
+ if (eap != NULL && eap->force_enc != 0) {
+ fenc = eap->cmd + eap->force_enc;
+ fenc = enc_canonize(fenc);
+ fenc_tofree = fenc;
+ } else
+ fenc = buf->b_p_fenc;
+
+ /*
+ * Check if the file needs to be converted.
+ */
+ converted = need_conversion(fenc);
+
+ /*
+ * Check if UTF-8 to UCS-2/4 or Latin1 conversion needs to be done. Or
+ * Latin1 to Unicode conversion. This is handled in buf_write_bytes().
+ * Prepare the flags for it and allocate bw_conv_buf when needed.
+ */
+ if (converted && (enc_utf8 || STRCMP(p_enc, "latin1") == 0)) {
+ wb_flags = get_fio_flags(fenc);
+ if (wb_flags & (FIO_UCS2 | FIO_UCS4 | FIO_UTF16 | FIO_UTF8)) {
+ /* Need to allocate a buffer to translate into. */
+ if (wb_flags & (FIO_UCS2 | FIO_UTF16 | FIO_UTF8))
+ write_info.bw_conv_buflen = bufsize * 2;
+ else /* FIO_UCS4 */
+ write_info.bw_conv_buflen = bufsize * 4;
+ write_info.bw_conv_buf
+ = lalloc((long_u)write_info.bw_conv_buflen, TRUE);
+ if (write_info.bw_conv_buf == NULL)
+ end = 0;
+ }
+ }
+
+
+
+ if (converted && wb_flags == 0) {
+# ifdef USE_ICONV
+ /*
+ * Use iconv() conversion when conversion is needed and it's not done
+ * internally.
+ */
+ write_info.bw_iconv_fd = (iconv_t)my_iconv_open(fenc,
+ enc_utf8 ? (char_u *)"utf-8" : p_enc);
+ if (write_info.bw_iconv_fd != (iconv_t)-1) {
+ /* We're going to use iconv(), allocate a buffer to convert in. */
+ write_info.bw_conv_buflen = bufsize * ICONV_MULT;
+ write_info.bw_conv_buf
+ = lalloc((long_u)write_info.bw_conv_buflen, TRUE);
+ if (write_info.bw_conv_buf == NULL)
+ end = 0;
+ write_info.bw_first = TRUE;
+ } else
+# endif
+
+ /*
+ * When the file needs to be converted with 'charconvert' after
+ * writing, write to a temp file instead and let the conversion
+ * overwrite the original file.
+ */
+ if (*p_ccv != NUL) {
+ wfname = vim_tempname('w');
+ if (wfname == NULL) { /* Can't write without a tempfile! */
+ errmsg = (char_u *)_("E214: Can't find temp file for writing");
+ goto restore_backup;
+ }
+ }
+ }
+ if (converted && wb_flags == 0
+# ifdef USE_ICONV
+ && write_info.bw_iconv_fd == (iconv_t)-1
+# endif
+ && wfname == fname
+ ) {
+ if (!forceit) {
+ errmsg = (char_u *)_(
+ "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 = mch_open((char *)wfname, O_WRONLY | O_EXTRA | (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
+ struct stat st;
+
+ /* Don't delete the file when it's a hard or symbolic link. */
+ if ((!newfile && st_old.st_nlink > 1)
+ || (mch_lstat((char *)fname, &st) == 0
+ && (st.st_dev != st_old.st_dev
+ || st.st_ino != st_old.st_ino)))
+ errmsg = (char_u *)_("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) {
+#ifdef UNIX
+ /* we write to the file, thus it should be marked
+ writable after all */
+ if (!(perm & 0200))
+ made_writable = TRUE;
+ perm |= 0200;
+ if (st_old.st_uid != getuid() || st_old.st_gid != getgid())
+ perm &= 0777;
+#endif
+ if (!append) /* don't remove when appending */
+ mch_remove(wfname);
+ continue;
+ }
+ }
+ }
+
+restore_backup:
+ {
+ struct stat st;
+
+ /*
+ * 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 (mch_stat((char *)fname, &st) < 0)
+ vim_rename(backup, fname);
+ /* if original file does exist throw away the copy */
+ if (mch_stat((char *)fname, &st) >= 0)
+ mch_remove(backup);
+ } else {
+ /* try to put the original file back */
+ vim_rename(backup, fname);
+ }
+ }
+
+ /* if original file no longer exists give an extra warning */
+ if (!newfile && mch_stat((char *)fname, &st) < 0)
+ end = 0;
+ }
+
+ if (wfname != fname)
+ vim_free(wfname);
+ goto fail;
+ }
+ errmsg = NULL;
+
+
+ write_info.bw_fd = fd;
+
+ if (*buf->b_p_key != NUL && !filtering) {
+ char_u *header;
+ int header_len;
+
+ header = prepare_crypt_write(buf, &header_len);
+ if (header == NULL)
+ end = 0;
+ else {
+ /* Write magic number, so that Vim knows that this file is
+ * encrypted when reading it again. This also undergoes utf-8 to
+ * ucs-2/4 conversion when needed. */
+ write_info.bw_buf = header;
+ write_info.bw_len = header_len;
+ write_info.bw_flags = FIO_NOCONVERT;
+ if (buf_write_bytes(&write_info) == FAIL)
+ end = 0;
+ wb_flags |= FIO_ENCRYPTED;
+ vim_free(header);
+ }
+ }
+
+ 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;
+
+ /*
+ * The BOM is written just after the encryption magic number.
+ * Skip it 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, do encryption */
+ 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_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_info.bw_len = bufsize;
+#ifdef HAS_BW_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 */
+ 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
+ && (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;
+ }
+ nchars += bufsize;
+ s = buffer;
+ len = 0;
+ }
+ *s++ = NL;
+ }
+ }
+ if (++len == bufsize && end) {
+ if (buf_write_bytes(&write_info) == FAIL) {
+ end = 0; /* write error: break loop */
+ break;
+ }
+ nchars += bufsize;
+ s = buffer;
+ len = 0;
+
+ ui_breakcheck();
+ if (got_int) {
+ end = 0; /* Interrupted, break loop */
+ 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) && defined(HAVE_FSYNC)
+ /* 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 && fsync(fd) != 0 && !device) {
+ errmsg = (char_u *)_("E667: Fsync failed");
+ end = 0;
+ }
+#endif
+
+#ifdef HAVE_SELINUX
+ /* 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) {
+# ifdef HAVE_FCHOWN
+ struct stat st;
+
+ /* don't change the owner when it's already OK, some systems remove
+ * permission or ACL stuff */
+ if (mch_stat((char *)wfname, &st) < 0
+ || st.st_uid != st_old.st_uid
+ || st.st_gid != st_old.st_gid) {
+ ignored = fchown(fd, st_old.st_uid, st_old.st_gid);
+ if (perm >= 0) /* set permission again, may have changed */
+ (void)mch_setperm(wfname, perm);
+ }
+# endif
+ buf_setino(buf);
+ } else if (!buf->b_dev_valid)
+ /* Set the inode when creating a new file. */
+ buf_setino(buf);
+#endif
+
+ if (close(fd) != 0) {
+ errmsg = (char_u *)_("E512: Close failed");
+ end = 0;
+ }
+
+#ifdef UNIX
+ 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)mch_setperm(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);
+#endif
+ crypt_method_used = use_crypt_method;
+ if (wb_flags & FIO_ENCRYPTED)
+ crypt_pop_state();
+
+
+ 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 ? (char_u *)"utf-8" : p_enc, fenc,
+ wfname, fname) == FAIL) {
+ write_info.bw_conv_error = TRUE;
+ end = 0;
+ }
+ }
+ mch_remove(wfname);
+ vim_free(wfname);
+ }
+
+ if (end == 0) {
+ 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 = alloc(300);
+ vim_snprintf((char *)errmsg, 300,
+ _(
+ "E513: write error, conversion failed in line %ld (make 'fenc' empty to override)"),
+ (long)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?)");
+ }
+
+ /*
+ * 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. */
+ if (got_int) {
+ MSG(_(e_interr));
+ out_flush();
+ }
+ if ((fd = mch_open((char *)backup, O_RDONLY | O_EXTRA, 0)) >= 0) {
+ if ((write_info.bw_fd = mch_open((char *)fname,
+ O_WRONLY | O_CREAT | O_TRUNC | O_EXTRA,
+ 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)
+ break;
+
+ if (close(write_info.bw_fd) >= 0
+ && write_info.bw_len == 0)
+ end = 1; /* success */
+ }
+ close(fd); /* ignore errors for closing read file */
+ }
+ } else {
+ if (vim_rename(backup, fname) == 0)
+ end = 1;
+ }
+ }
+ goto fail;
+ }
+
+ lnum -= start; /* compute number of written lines */
+ --no_wait_return; /* may wait for return now */
+
+#if !(defined(UNIX) || defined(VMS))
+ fname = sfname; /* use shortname now, for the messages */
+#endif
+ if (!filtering) {
+ msg_add_fname(buf, fname); /* put fname in IObuff with quotes */
+ c = FALSE;
+ if (write_info.bw_conv_error) {
+ STRCAT(IObuff, _(" CONVERSION ERROR"));
+ c = TRUE;
+ if (write_info.bw_conv_error_lnum != 0)
+ vim_snprintf_add((char *)IObuff, IOSIZE, _(" in line %ld;"),
+ (long)write_info.bw_conv_error_lnum);
+ } else if (notconverted) {
+ STRCAT(IObuff, _("[NOT converted]"));
+ c = TRUE;
+ } else if (converted) {
+ STRCAT(IObuff, _("[converted]"));
+ c = TRUE;
+ }
+ if (device) {
+ STRCAT(IObuff, _("[Device]"));
+ c = TRUE;
+ } else if (newfile) {
+ STRCAT(IObuff, shortmess(SHM_NEW) ? _("[New]") : _("[New File]"));
+ c = TRUE;
+ }
+ if (no_eol) {
+ msg_add_eol();
+ c = TRUE;
+ }
+ /* may add [unix/dos/mac] */
+ if (msg_add_fileformat(fileformat))
+ c = TRUE;
+ if (wb_flags & FIO_ENCRYPTED) {
+ if (crypt_method_used == 1)
+ STRCAT(IObuff, _("[blowfish]"));
+ else
+ STRCAT(IObuff, _("[crypted]"));
+ c = TRUE;
+ }
+ msg_add_lines(c, (long)lnum, nchars); /* add line/char count */
+ if (!shortmess(SHM_WRITE)) {
+ if (append)
+ STRCAT(IObuff, shortmess(SHM_WRI) ? _(" [a]") : _(" appended"));
+ else
+ STRCAT(IObuff, shortmess(SHM_WRI) ? _(" [w]") : _(" written"));
+ }
+
+ set_keep_msg(msg_trunc_attr(IObuff, FALSE, 0), 0);
+ }
+
+ /* When written everything correctly: reset 'modified'. Unless not
+ * 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);
+ u_unchanged(buf);
+ u_update_save_nr(buf);
+ }
+
+ /*
+ * If written to the current file, update the timestamp of the swap file
+ * and reset the BF_WRITE_MASK flags. Also sets buf->b_mtime.
+ */
+ if (overwriting) {
+ ml_timestamp(buf);
+ if (append)
+ buf->b_flags &= ~BF_NEW;
+ else
+ buf->b_flags &= ~BF_WRITE_MASK;
+ }
+
+ /*
+ * If we kept a backup until now, and we are in patch mode, then we make
+ * the backup file our 'original' file.
+ */
+ if (*p_pm && dobackup) {
+ char *org = (char *)buf_modname(
+#ifdef SHORT_FNAME
+ TRUE,
+#else
+ (buf->b_p_sn || buf->b_shortname),
+#endif
+ fname, p_pm, FALSE);
+
+ if (backup != NULL) {
+ struct stat st;
+
+ /*
+ * If the original file does not exist yet
+ * the current backup file becomes the original file
+ */
+ if (org == NULL)
+ EMSG(_("E205: Patchmode: can't save original file"));
+ else if (mch_stat(org, &st) < 0) {
+ vim_rename(backup, (char_u *)org);
+ vim_free(backup); /* don't delete the file */
+ backup = NULL;
+#ifdef UNIX
+ set_file_time((char_u *)org, st_old.st_atime, st_old.st_mtime);
+#endif
+ }
+ }
+ /*
+ * If there is no backup file, remember that a (new) file was
+ * created.
+ */
+ else {
+ int empty_fd;
+
+ if (org == NULL
+ || (empty_fd = mch_open(org,
+ O_CREAT | O_EXTRA | O_EXCL | O_NOFOLLOW,
+ perm < 0 ? 0666 : (perm & 0777))) < 0)
+ EMSG(_("E206: patchmode: can't touch empty original file"));
+ else
+ close(empty_fd);
+ }
+ if (org != NULL) {
+ mch_setperm((char_u *)org, mch_getperm(fname) & 0777);
+ vim_free(org);
+ }
+ }
+
+ /*
+ * Remove the backup unless 'backup' option is set
+ */
+ if (!p_bk && backup != NULL && mch_remove(backup) != 0)
+ EMSG(_("E207: Can't delete backup file"));
+
+
+ goto nofail;
+
+ /*
+ * Finish up. We get here either after failure or success.
+ */
+fail:
+ --no_wait_return; /* may wait for return now */
+nofail:
+
+ /* Done saving, we accept changed buffer warnings again */
+ buf->b_saving = FALSE;
+
+ vim_free(backup);
+ if (buffer != smallbuf)
+ vim_free(buffer);
+ vim_free(fenc_tofree);
+ vim_free(write_info.bw_conv_buf);
+# ifdef USE_ICONV
+ if (write_info.bw_iconv_fd != (iconv_t)-1) {
+ iconv_close(write_info.bw_iconv_fd);
+ write_info.bw_iconv_fd = (iconv_t)-1;
+ }
+# endif
+#ifdef HAVE_ACL
+ mch_free_acl(acl);
+#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,
+#ifndef UNIX
+ sfname
+#else
+ 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);
+ mch_memmove(IObuff, errnum, (size_t)numlen);
+ }
+ STRCAT(IObuff, errmsg);
+ emsg(IObuff);
+ if (errmsg_allocated)
+ vim_free(errmsg);
+
+ retval = FAIL;
+ if (end == 0) {
+ MSG_PUTS_ATTR(_("\nWARNING: Original file may be lost or damaged\n"),
+ attr | MSG_HIST);
+ MSG_PUTS_ATTR(_(
+ "don't quit the editor until the file is successfully written!"),
+ attr | MSG_HIST);
+
+ /* Update the timestamp to avoid an "overwrite changed file"
+ * prompt when writing again. */
+ if (mch_stat((char *)fname, &st_old) >= 0) {
+ buf_store_time(buf, &st_old, fname);
+ buf->b_mtime_read = buf->b_mtime;
+ }
+ }
+ }
+ msg_scroll = msg_save;
+
+ /*
+ * When writing the whole file and 'undofile' is set, also write the undo
+ * file.
+ */
+ if (retval == OK && write_undo_file) {
+ char_u hash[UNDO_HASH_SIZE];
+
+ sha256_finish(&sha_ctx, hash);
+ u_write_undo(NULL, FALSE, buf, hash);
+ }
+
+ if (!should_abort(retval)) {
+ aco_save_T aco;
+
+ curbuf->b_no_eol_lnum = 0; /* in case it was set by the previous read */
+
+ /*
+ * Apply POST autocommands.
+ * Careful: The autocommands may call buf_write() recursively!
+ */
+ aucmd_prepbuf(&aco, buf);
+
+ if (append)
+ apply_autocmds_exarg(EVENT_FILEAPPENDPOST, fname, fname,
+ FALSE, curbuf, eap);
+ else if (filtering)
+ apply_autocmds_exarg(EVENT_FILTERWRITEPOST, NULL, fname,
+ FALSE, curbuf, eap);
+ else if (reset_changed && whole)
+ apply_autocmds_exarg(EVENT_BUFWRITEPOST, fname, fname,
+ FALSE, curbuf, eap);
+ else
+ apply_autocmds_exarg(EVENT_FILEWRITEPOST, fname, fname,
+ FALSE, curbuf, eap);
+
+ /* restore curwin/curbuf and a few other things */
+ aucmd_restbuf(&aco);
+
+ if (aborting()) /* autocmds may abort script processing */
+ retval = FALSE;
+ }
+
+ got_int |= prev_got_int;
+
+ return retval;
+}
+
+/*
+ * Set the name of the current buffer. Use when the buffer doesn't have a
+ * name and a ":r" or ":w" command with a file name is used.
+ */
+static int set_rw_fname(fname, sfname)
+char_u *fname;
+char_u *sfname;
+{
+ buf_T *buf = curbuf;
+
+ /* It's like the unnamed buffer is deleted.... */
+ if (curbuf->b_p_bl)
+ apply_autocmds(EVENT_BUFDELETE, NULL, NULL, FALSE, curbuf);
+ apply_autocmds(EVENT_BUFWIPEOUT, NULL, NULL, FALSE, curbuf);
+ if (aborting()) /* autocmds may abort script processing */
+ return FAIL;
+ if (curbuf != buf) {
+ /* We are in another buffer now, don't do the renaming. */
+ EMSG(_(e_auchangedbuf));
+ return FAIL;
+ }
+
+ if (setfname(curbuf, fname, sfname, FALSE) == OK)
+ curbuf->b_flags |= BF_NOTEDITED;
+
+ /* ....and a new named one is created */
+ apply_autocmds(EVENT_BUFNEW, NULL, NULL, FALSE, curbuf);
+ if (curbuf->b_p_bl)
+ apply_autocmds(EVENT_BUFADD, NULL, NULL, FALSE, curbuf);
+ if (aborting()) /* autocmds may abort script processing */
+ return FAIL;
+
+ /* 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);
+ do_modelines(0);
+ }
+
+ return OK;
+}
+
+/*
+ * Put file name into IObuff with quotes.
+ */
+void msg_add_fname(buf, fname)
+buf_T *buf;
+char_u *fname;
+{
+ if (fname == NULL)
+ fname = (char_u *)"-stdin-";
+ home_replace(buf, fname, IObuff + 1, IOSIZE - 4, TRUE);
+ IObuff[0] = '"';
+ STRCAT(IObuff, "\" ");
+}
+
+/*
+ * Append message for text mode to IObuff.
+ * Return TRUE if something appended.
+ */
+static int msg_add_fileformat(eol_type)
+int eol_type;
+{
+#ifndef USE_CRNL
+ if (eol_type == EOL_DOS) {
+ STRCAT(IObuff, shortmess(SHM_TEXT) ? _("[dos]") : _("[dos format]"));
+ return TRUE;
+ }
+#endif
+#ifndef USE_CR
+ if (eol_type == EOL_MAC) {
+ STRCAT(IObuff, shortmess(SHM_TEXT) ? _("[mac]") : _("[mac format]"));
+ return TRUE;
+ }
+#endif
+#if defined(USE_CRNL) || defined(USE_CR)
+ if (eol_type == EOL_UNIX) {
+ STRCAT(IObuff, shortmess(SHM_TEXT) ? _("[unix]") : _("[unix format]"));
+ return TRUE;
+ }
+#endif
+ return FALSE;
+}
+
+/*
+ * Append line and character count to IObuff.
+ */
+void msg_add_lines(insert_space, lnum, nchars)
+int insert_space;
+long lnum;
+off_t nchars;
+{
+ char_u *p;
+
+ p = IObuff + STRLEN(IObuff);
+
+ if (insert_space)
+ *p++ = ' ';
+ if (shortmess(SHM_LINES))
+ sprintf((char *)p,
+#ifdef LONG_LONG_OFF_T
+ "%ldL, %lldC", lnum, nchars
+#else
+ /* Explicit typecast avoids warning on Mac OS X 10.6 */
+ "%ldL, %ldC", lnum, (long)nchars
+#endif
+ );
+ else {
+ if (lnum == 1)
+ STRCPY(p, _("1 line, "));
+ else
+ sprintf((char *)p, _("%ld lines, "), lnum);
+ p += STRLEN(p);
+ if (nchars == 1)
+ STRCPY(p, _("1 character"));
+ else
+ sprintf((char *)p,
+#ifdef LONG_LONG_OFF_T
+ _("%lld characters"), nchars
+#else
+ /* Explicit typecast avoids warning on Mac OS X 10.6 */
+ _("%ld characters"), (long)nchars
+#endif
+ );
+ }
+}
+
+/*
+ * Append message for missing line separator to IObuff.
+ */
+static void msg_add_eol() {
+ STRCAT(IObuff,
+ shortmess(SHM_LAST) ? _("[noeol]") : _("[Incomplete last line]"));
+}
+
+/*
+ * Check modification time of file, before writing to it.
+ * The size isn't checked, because using a tool like "gzip" takes care of
+ * using the same timestamp but can't set the size.
+ */
+static int check_mtime(buf, st)
+buf_T *buf;
+struct stat *st;
+{
+ if (buf->b_mtime_read != 0
+ && time_differs((long)st->st_mtime, 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')
+ return FAIL;
+ msg_scroll = FALSE; /* always overwrite the file message now */
+ }
+ return OK;
+}
+
+static int time_differs(t1, t2)
+long t1, t2;
+{
+#if defined(__linux__) || defined(MSDOS) || defined(MSWIN)
+ /* On a FAT filesystem, esp. under Linux, there are only 5 bits to store
+ * the seconds. Since the roundoff is done when flushing the inode, the
+ * time may change unexpectedly by one second!!! */
+ return t1 - t2 > 1 || t2 - t1 > 1;
+#else
+ return t1 != t2;
+#endif
+}
+
+/*
+ * Call write() to write a number of bytes to the file.
+ * Handles encryption and 'encoding' conversion.
+ *
+ * Return FAIL for failure, OK otherwise.
+ */
+static int buf_write_bytes(ip)
+struct bw_info *ip;
+{
+ int wlen;
+ char_u *buf = ip->bw_buf; /* data to write */
+ int len = ip->bw_len; /* length of data */
+#ifdef HAS_BW_FLAGS
+ int flags = ip->bw_flags; /* extra flags */
+#endif
+
+ /*
+ * Skip conversion when writing the crypt magic number or the BOM.
+ */
+ if (!(flags & FIO_NOCONVERT)) {
+ char_u *p;
+ unsigned c;
+ int n;
+
+ if (flags & FIO_UTF8) {
+ /*
+ * Convert latin1 in the buffer to UTF-8 in the file.
+ */
+ p = ip->bw_conv_buf; /* translate to buffer */
+ for (wlen = 0; wlen < len; ++wlen)
+ p += utf_char2bytes(buf[wlen], p);
+ buf = ip->bw_conv_buf;
+ len = (int)(p - ip->bw_conv_buf);
+ } else if (flags & (FIO_UCS4 | FIO_UTF16 | FIO_UCS2 | FIO_LATIN1)) {
+ /*
+ * Convert UTF-8 bytes in the buffer to UCS-2, UCS-4, UTF-16 or
+ * Latin1 chars in the file.
+ */
+ if (flags & FIO_LATIN1)
+ p = buf; /* translate in-place (can only get shorter) */
+ else
+ p = ip->bw_conv_buf; /* translate to buffer */
+ for (wlen = 0; wlen < len; wlen += n) {
+ if (wlen == 0 && ip->bw_restlen != 0) {
+ int l;
+
+ /* Use remainder of previous call. Append the start of
+ * buf[] to get a full sequence. Might still be too
+ * short! */
+ l = CONV_RESTLEN - ip->bw_restlen;
+ if (l > len)
+ l = len;
+ mch_memmove(ip->bw_rest + ip->bw_restlen, buf, (size_t)l);
+ n = utf_ptr2len_len(ip->bw_rest, ip->bw_restlen + l);
+ if (n > ip->bw_restlen + len) {
+ /* We have an incomplete byte sequence at the end to
+ * be written. We can't convert it without the
+ * remaining bytes. Keep them for the next call. */
+ if (ip->bw_restlen + len > CONV_RESTLEN)
+ return FAIL;
+ ip->bw_restlen += len;
+ break;
+ }
+ if (n > 1)
+ c = utf_ptr2char(ip->bw_rest);
+ else
+ c = ip->bw_rest[0];
+ if (n >= ip->bw_restlen) {
+ n -= ip->bw_restlen;
+ ip->bw_restlen = 0;
+ } else {
+ ip->bw_restlen -= n;
+ mch_memmove(ip->bw_rest, ip->bw_rest + n,
+ (size_t)ip->bw_restlen);
+ n = 0;
+ }
+ } else {
+ n = utf_ptr2len_len(buf + wlen, len - wlen);
+ if (n > len - wlen) {
+ /* We have an incomplete byte sequence at the end to
+ * be written. We can't convert it without the
+ * remaining bytes. Keep them for the next call. */
+ if (len - wlen > CONV_RESTLEN)
+ return FAIL;
+ ip->bw_restlen = len - wlen;
+ mch_memmove(ip->bw_rest, buf + wlen,
+ (size_t)ip->bw_restlen);
+ break;
+ }
+ if (n > 1)
+ c = utf_ptr2char(buf + wlen);
+ else
+ c = buf[wlen];
+ }
+
+ if (ucs2bytes(c, &p, flags) && !ip->bw_conv_error) {
+ ip->bw_conv_error = TRUE;
+ ip->bw_conv_error_lnum = ip->bw_start_lnum;
+ }
+ if (c == NL)
+ ++ip->bw_start_lnum;
+ }
+ if (flags & FIO_LATIN1)
+ len = (int)(p - buf);
+ else {
+ buf = ip->bw_conv_buf;
+ len = (int)(p - ip->bw_conv_buf);
+ }
+ }
+
+
+# ifdef MACOS_CONVERT
+ else if (flags & FIO_MACROMAN) {
+ /*
+ * Convert UTF-8 or latin1 to Apple MacRoman.
+ */
+ char_u *from;
+ size_t fromlen;
+
+ if (ip->bw_restlen > 0) {
+ /* Need to concatenate the remainder of the previous call and
+ * the bytes of the current call. Use the end of the
+ * conversion buffer for this. */
+ fromlen = len + ip->bw_restlen;
+ from = ip->bw_conv_buf + ip->bw_conv_buflen - fromlen;
+ mch_memmove(from, ip->bw_rest, (size_t)ip->bw_restlen);
+ mch_memmove(from + ip->bw_restlen, buf, (size_t)len);
+ } else {
+ from = buf;
+ fromlen = len;
+ }
+
+ if (enc2macroman(from, fromlen,
+ ip->bw_conv_buf, &len, ip->bw_conv_buflen,
+ ip->bw_rest, &ip->bw_restlen) == FAIL) {
+ ip->bw_conv_error = TRUE;
+ return FAIL;
+ }
+ buf = ip->bw_conv_buf;
+ }
+# endif
+
+# ifdef USE_ICONV
+ if (ip->bw_iconv_fd != (iconv_t)-1) {
+ const char *from;
+ size_t fromlen;
+ char *to;
+ size_t tolen;
+
+ /* Convert with iconv(). */
+ if (ip->bw_restlen > 0) {
+ char *fp;
+
+ /* Need to concatenate the remainder of the previous call and
+ * the bytes of the current call. Use the end of the
+ * conversion buffer for this. */
+ fromlen = len + ip->bw_restlen;
+ fp = (char *)ip->bw_conv_buf + ip->bw_conv_buflen - fromlen;
+ mch_memmove(fp, ip->bw_rest, (size_t)ip->bw_restlen);
+ mch_memmove(fp + ip->bw_restlen, buf, (size_t)len);
+ from = fp;
+ tolen = ip->bw_conv_buflen - fromlen;
+ } else {
+ from = (const char *)buf;
+ fromlen = len;
+ tolen = ip->bw_conv_buflen;
+ }
+ to = (char *)ip->bw_conv_buf;
+
+ if (ip->bw_first) {
+ size_t save_len = tolen;
+
+ /* output the initial shift state sequence */
+ (void)iconv(ip->bw_iconv_fd, NULL, NULL, &to, &tolen);
+
+ /* There is a bug in iconv() on Linux (which appears to be
+ * wide-spread) which sets "to" to NULL and messes up "tolen".
+ */
+ if (to == NULL) {
+ to = (char *)ip->bw_conv_buf;
+ tolen = save_len;
+ }
+ ip->bw_first = FALSE;
+ }
+
+ /*
+ * If iconv() has an error or there is not enough room, fail.
+ */
+ if ((iconv(ip->bw_iconv_fd, (void *)&from, &fromlen, &to, &tolen)
+ == (size_t)-1 && ICONV_ERRNO != ICONV_EINVAL)
+ || fromlen > CONV_RESTLEN) {
+ ip->bw_conv_error = TRUE;
+ return FAIL;
+ }
+
+ /* copy remainder to ip->bw_rest[] to be used for the next call. */
+ if (fromlen > 0)
+ mch_memmove(ip->bw_rest, (void *)from, fromlen);
+ ip->bw_restlen = (int)fromlen;
+
+ buf = ip->bw_conv_buf;
+ len = (int)((char_u *)to - ip->bw_conv_buf);
+ }
+# endif
+ }
+
+ if (flags & FIO_ENCRYPTED) /* encrypt the data */
+ crypt_encode(buf, len, buf);
+
+ wlen = write_eintr(ip->bw_fd, buf, len);
+ return (wlen < len) ? FAIL : OK;
+}
+
+/*
+ * Convert a Unicode character to bytes.
+ * Return TRUE for an error, FALSE when it's OK.
+ */
+static int ucs2bytes(c, pp, flags)
+unsigned c; /* in: character */
+char_u **pp; /* in/out: pointer to result */
+int flags; /* FIO_ flags */
+{
+ char_u *p = *pp;
+ int error = FALSE;
+ int cc;
+
+
+ if (flags & FIO_UCS4) {
+ if (flags & FIO_ENDIAN_L) {
+ *p++ = c;
+ *p++ = (c >> 8);
+ *p++ = (c >> 16);
+ *p++ = (c >> 24);
+ } else {
+ *p++ = (c >> 24);
+ *p++ = (c >> 16);
+ *p++ = (c >> 8);
+ *p++ = c;
+ }
+ } else if (flags & (FIO_UCS2 | FIO_UTF16)) {
+ if (c >= 0x10000) {
+ if (flags & FIO_UTF16) {
+ /* Make two words, ten bits of the character in each. First
+ * word is 0xd800 - 0xdbff, second one 0xdc00 - 0xdfff */
+ c -= 0x10000;
+ if (c >= 0x100000)
+ error = TRUE;
+ cc = ((c >> 10) & 0x3ff) + 0xd800;
+ if (flags & FIO_ENDIAN_L) {
+ *p++ = cc;
+ *p++ = ((unsigned)cc >> 8);
+ } else {
+ *p++ = ((unsigned)cc >> 8);
+ *p++ = cc;
+ }
+ c = (c & 0x3ff) + 0xdc00;
+ } else
+ error = TRUE;
+ }
+ if (flags & FIO_ENDIAN_L) {
+ *p++ = c;
+ *p++ = (c >> 8);
+ } else {
+ *p++ = (c >> 8);
+ *p++ = c;
+ }
+ } else { /* Latin1 */
+ if (c >= 0x100) {
+ error = TRUE;
+ *p++ = 0xBF;
+ } else
+ *p++ = c;
+ }
+
+ *pp = p;
+ return error;
+}
+
+/*
+ * Return TRUE if file encoding "fenc" requires conversion from or to
+ * 'encoding'.
+ */
+static int need_conversion(fenc)
+char_u *fenc;
+{
+ int same_encoding;
+ int enc_flags;
+ int fenc_flags;
+
+ if (*fenc == NUL || STRCMP(p_enc, fenc) == 0) {
+ same_encoding = TRUE;
+ fenc_flags = 0;
+ } else {
+ /* Ignore difference between "ansi" and "latin1", "ucs-4" and
+ * "ucs-4be", etc. */
+ enc_flags = get_fio_flags(p_enc);
+ fenc_flags = get_fio_flags(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;
+ }
+
+ /* Encodings differ. However, conversion is not needed when 'enc' is any
+ * Unicode encoding and the file is UTF-8. */
+ return !(enc_utf8 && fenc_flags == FIO_UTF8);
+}
+
+/*
+ * Check "ptr" for a unicode encoding and return the FIO_ flags needed for the
+ * internal conversion.
+ * if "ptr" is an empty string, use 'encoding'.
+ */
+static int get_fio_flags(ptr)
+char_u *ptr;
+{
+ int prop;
+
+ if (*ptr == NUL)
+ ptr = p_enc;
+
+ prop = enc_canon_props(ptr);
+ if (prop & ENC_UNICODE) {
+ if (prop & ENC_2BYTE) {
+ if (prop & ENC_ENDIAN_L)
+ return FIO_UCS2 | FIO_ENDIAN_L;
+ return FIO_UCS2;
+ }
+ if (prop & ENC_4BYTE) {
+ if (prop & ENC_ENDIAN_L)
+ return FIO_UCS4 | FIO_ENDIAN_L;
+ return FIO_UCS4;
+ }
+ if (prop & ENC_2WORD) {
+ if (prop & ENC_ENDIAN_L)
+ return FIO_UTF16 | FIO_ENDIAN_L;
+ return FIO_UTF16;
+ }
+ return FIO_UTF8;
+ }
+ if (prop & ENC_LATIN1)
+ return FIO_LATIN1;
+ /* must be ENC_DBCS, requires iconv() */
+ return 0;
+}
+
+
+
+/*
+ * Check for a Unicode BOM (Byte Order Mark) at the start of p[size].
+ * "size" must be at least 2.
+ * Return the name of the encoding and set "*lenp" to the length.
+ * Returns NULL when no BOM found.
+ */
+static char_u * check_for_bom(p, size, lenp, flags)
+char_u *p;
+long size;
+int *lenp;
+int flags;
+{
+ char *name = NULL;
+ int len = 2;
+
+ if (p[0] == 0xef && p[1] == 0xbb && size >= 3 && p[2] == 0xbf
+ && (flags == FIO_ALL || flags == FIO_UTF8 || flags == 0)) {
+ name = "utf-8"; /* EF BB BF */
+ len = 3;
+ } else if (p[0] == 0xff && p[1] == 0xfe) {
+ if (size >= 4 && p[2] == 0 && p[3] == 0
+ && (flags == FIO_ALL || flags == (FIO_UCS4 | FIO_ENDIAN_L))) {
+ name = "ucs-4le"; /* FF FE 00 00 */
+ len = 4;
+ } else if (flags == (FIO_UCS2 | FIO_ENDIAN_L))
+ name = "ucs-2le"; /* FF FE */
+ else if (flags == FIO_ALL || flags == (FIO_UTF16 | FIO_ENDIAN_L))
+ /* utf-16le is preferred, it also works for ucs-2le text */
+ name = "utf-16le"; /* FF FE */
+ } else if (p[0] == 0xfe && p[1] == 0xff
+ && (flags == FIO_ALL || flags == FIO_UCS2 || flags ==
+ FIO_UTF16)) {
+ /* Default to utf-16, it works also for ucs-2 text. */
+ if (flags == FIO_UCS2)
+ name = "ucs-2"; /* FE FF */
+ else
+ name = "utf-16"; /* FE FF */
+ } else if (size >= 4 && p[0] == 0 && p[1] == 0 && p[2] == 0xfe
+ && p[3] == 0xff && (flags == FIO_ALL || flags == FIO_UCS4)) {
+ name = "ucs-4"; /* 00 00 FE FF */
+ len = 4;
+ }
+
+ *lenp = len;
+ return (char_u *)name;
+}
+
+/*
+ * Generate a BOM in "buf[4]" for encoding "name".
+ * Return the length of the BOM (zero when no BOM).
+ */
+static int make_bom(buf, name)
+char_u *buf;
+char_u *name;
+{
+ int flags;
+ char_u *p;
+
+ flags = get_fio_flags(name);
+
+ /* Can't put a BOM in a non-Unicode file. */
+ if (flags == FIO_LATIN1 || flags == 0)
+ return 0;
+
+ if (flags == FIO_UTF8) { /* UTF-8 */
+ buf[0] = 0xef;
+ buf[1] = 0xbb;
+ buf[2] = 0xbf;
+ return 3;
+ }
+ p = buf;
+ (void)ucs2bytes(0xfeff, &p, flags);
+ return (int)(p - buf);
+}
+
+#if defined(FEAT_VIMINFO) || defined(FEAT_BROWSE) || \
+ defined(FEAT_QUICKFIX) || defined(FEAT_AUTOCMD) || defined(PROTO)
+/*
+ * Try to find a shortname by comparing the fullname with the current
+ * directory.
+ * Returns "full_path" or pointer into "full_path" if shortened.
+ */
+char_u * shorten_fname1(full_path)
+char_u *full_path;
+{
+ char_u *dirname;
+ char_u *p = full_path;
+
+ dirname = alloc(MAXPATHL);
+ if (dirname == NULL)
+ return full_path;
+ if (mch_dirname(dirname, MAXPATHL) == OK) {
+ p = shorten_fname(full_path, dirname);
+ if (p == NULL || *p == NUL)
+ p = full_path;
+ }
+ vim_free(dirname);
+ return p;
+}
+#endif
+
+/*
+ * Try to find a shortname by comparing the fullname with the current
+ * directory.
+ * Returns NULL if not shorter name possible, pointer into "full_path"
+ * otherwise.
+ */
+char_u * shorten_fname(full_path, dir_name)
+char_u *full_path;
+char_u *dir_name;
+{
+ int len;
+ char_u *p;
+
+ if (full_path == NULL)
+ return NULL;
+ len = (int)STRLEN(dir_name);
+ if (fnamencmp(dir_name, full_path, len) == 0) {
+ p = full_path + len;
+ {
+ if (vim_ispathsep(*p))
+ ++p;
+ else
+ p = NULL;
+ }
+ } else
+ p = NULL;
+ return p;
+}
+
+/*
+ * 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(force)
+int force;
+{
+ char_u dirname[MAXPATHL];
+ buf_T *buf;
+ char_u *p;
+
+ mch_dirname(dirname, MAXPATHL);
+ for (buf = firstbuf; buf != NULL; buf = buf->b_next) {
+ if (buf->b_fname != NULL
+ && !bt_nofile(buf)
+ && !path_with_url(buf->b_fname)
+ && (force
+ || buf->b_sfname == NULL
+ || mch_isFullName(buf->b_sfname))) {
+ vim_free(buf->b_sfname);
+ buf->b_sfname = NULL;
+ p = 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;
+ }
+
+ /* Always make the swap file name a full path, a "nofile" buffer may
+ * also have a swap file. */
+ mf_fullname(buf->b_ml.ml_mfp);
+ }
+ status_redraw_all();
+ redraw_tabline = TRUE;
+}
+
+#if (defined(FEAT_DND) && defined(FEAT_GUI_GTK)) \
+ || defined(FEAT_GUI_MSWIN) \
+ || defined(FEAT_GUI_MAC) \
+ || defined(PROTO)
+/*
+ * Shorten all filenames in "fnames[count]" by current directory.
+ */
+void shorten_filenames(fnames, count)
+char_u **fnames;
+int count;
+{
+ int i;
+ char_u dirname[MAXPATHL];
+ char_u *p;
+
+ if (fnames == NULL || count < 1)
+ return;
+ mch_dirname(dirname, sizeof(dirname));
+ for (i = 0; i < count; ++i) {
+ if ((p = shorten_fname(fnames[i], dirname)) != NULL) {
+ /* shorten_fname() returns pointer in given "fnames[i]". If free
+ * "fnames[i]" first, "p" becomes invalid. So we need to copy
+ * "p" first then free fnames[i]. */
+ p = vim_strsave(p);
+ vim_free(fnames[i]);
+ fnames[i] = p;
+ }
+ }
+}
+#endif
+
+/*
+ * add extension to file name - change path/fo.o.h to path/fo.o.h.ext or
+ * fo_o_h.ext for MSDOS or when shortname option set.
+ *
+ * Assumed that fname is a valid name found in the filesystem we assure that
+ * the return value is a different name and ends in 'ext'.
+ * "ext" MUST be at most 4 characters long if it starts with a dot, 3
+ * characters otherwise.
+ * Space for the returned name is allocated, must be freed later.
+ * Returns NULL when out of memory.
+ */
+char_u * modname(fname, ext, prepend_dot)
+char_u *fname, *ext;
+int prepend_dot; /* may prepend a '.' to file name */
+{
+ return buf_modname(
+#ifdef SHORT_FNAME
+ TRUE,
+#else
+ (curbuf->b_p_sn || curbuf->b_shortname),
+#endif
+ fname, ext, prepend_dot);
+}
+
+char_u * buf_modname(shortname, fname, ext, prepend_dot)
+int shortname; /* use 8.3 file name */
+char_u *fname, *ext;
+int prepend_dot; /* may prepend a '.' to file name */
+{
+ char_u *retval;
+ char_u *s;
+ char_u *e;
+ char_u *ptr;
+ int fnamelen, extlen;
+
+ extlen = (int)STRLEN(ext);
+
+ /*
+ * If there is no file name we must get the name of the current directory
+ * (we need the full path in case :cd is used).
+ */
+ if (fname == NULL || *fname == NUL) {
+ retval = alloc((unsigned)(MAXPATHL + extlen + 3));
+ if (retval == NULL)
+ return NULL;
+ if (mch_dirname(retval, MAXPATHL) == FAIL ||
+ (fnamelen = (int)STRLEN(retval)) == 0) {
+ vim_free(retval);
+ return NULL;
+ }
+ if (!after_pathsep(retval, retval + fnamelen)) {
+ retval[fnamelen++] = PATHSEP;
+ retval[fnamelen] = NUL;
+ }
+#ifndef SHORT_FNAME
+ prepend_dot = FALSE; /* nothing to prepend a dot to */
+#endif
+ } else {
+ fnamelen = (int)STRLEN(fname);
+ retval = alloc((unsigned)(fnamelen + extlen + 3));
+ if (retval == NULL)
+ return NULL;
+ STRCPY(retval, fname);
+ }
+
+ /*
+ * search backwards until we hit a '/', '\' or ':' replacing all '.'
+ * by '_' for MSDOS or when shortname option set and ext starts with a dot.
+ * Then truncate what is after the '/', '\' or ':' to 8 characters for
+ * MSDOS and 26 characters for AMIGA, a lot more for UNIX.
+ */
+ for (ptr = retval + fnamelen; ptr > retval; mb_ptr_back(retval, ptr)) {
+ if (*ext == '.'
+#ifdef USE_LONG_FNAME
+ && (!USE_LONG_FNAME || shortname)
+#else
+# ifndef SHORT_FNAME
+ && shortname
+# endif
+#endif
+ )
+ if (*ptr == '.') /* replace '.' by '_' */
+ *ptr = '_';
+ if (vim_ispathsep(*ptr)) {
+ ++ptr;
+ break;
+ }
+ }
+
+ /* the file name has at most BASENAMELEN characters. */
+#ifndef SHORT_FNAME
+ if (STRLEN(ptr) > (unsigned)BASENAMELEN)
+ ptr[BASENAMELEN] = '\0';
+#endif
+
+ s = ptr + STRLEN(ptr);
+
+ /*
+ * For 8.3 file names we may have to reduce the length.
+ */
+#ifdef USE_LONG_FNAME
+ if (!USE_LONG_FNAME || shortname)
+#else
+# ifndef SHORT_FNAME
+ if (shortname)
+# endif
+#endif
+ {
+ /*
+ * If there is no file name, or the file name ends in '/', and the
+ * extension starts with '.', put a '_' before the dot, because just
+ * ".ext" is invalid.
+ */
+ if (fname == NULL || *fname == NUL
+ || vim_ispathsep(fname[STRLEN(fname) - 1])) {
+ if (*ext == '.')
+ *s++ = '_';
+ }
+ /*
+ * If the extension starts with '.', truncate the base name at 8
+ * characters
+ */
+ else if (*ext == '.') {
+ if ((size_t)(s - ptr) > (size_t)8) {
+ s = ptr + 8;
+ *s = '\0';
+ }
+ }
+ /*
+ * If the extension doesn't start with '.', and the file name
+ * doesn't have an extension yet, append a '.'
+ */
+ else if ((e = vim_strchr(ptr, '.')) == NULL)
+ *s++ = '.';
+ /*
+ * If the extension doesn't start with '.', and there already is an
+ * extension, it may need to be truncated
+ */
+ else if ((int)STRLEN(e) + extlen > 4)
+ s = e + 4 - extlen;
+ }
+#if defined(OS2) || defined(USE_LONG_FNAME) || defined(WIN3264)
+ /*
+ * If there is no file name, and the extension starts with '.', put a
+ * '_' before the dot, because just ".ext" may be invalid if it's on a
+ * FAT partition, and on HPFS it doesn't matter.
+ */
+ else if ((fname == NULL || *fname == NUL) && *ext == '.')
+ *s++ = '_';
+#endif
+
+ /*
+ * Append the extension.
+ * ext can start with '.' and cannot exceed 3 more characters.
+ */
+ STRCPY(s, ext);
+
+#ifndef SHORT_FNAME
+ /*
+ * Prepend the dot.
+ */
+ if (prepend_dot && !shortname && *(e = gettail(retval)) != '.'
+#ifdef USE_LONG_FNAME
+ && USE_LONG_FNAME
+#endif
+ ) {
+ STRMOVE(e + 1, e);
+ *e = '.';
+ }
+#endif
+
+ /*
+ * Check that, after appending the extension, the file name is really
+ * different.
+ */
+ if (fname != NULL && STRCMP(fname, retval) == 0) {
+ /* we search for a character that can be replaced by '_' */
+ while (--s >= ptr) {
+ if (*s != '_') {
+ *s = '_';
+ break;
+ }
+ }
+ if (s < ptr) /* fname was "________.<ext>", how tricky! */
+ *ptr = 'v';
+ }
+ return retval;
+}
+
+/*
+ * Like fgets(), but if the file line is too long, it is truncated and the
+ * rest of the line is thrown away. Returns TRUE for end-of-file.
+ */
+int vim_fgets(buf, size, fp)
+char_u *buf;
+int size;
+FILE *fp;
+{
+ char *eof;
+#define FGETS_SIZE 200
+ char tbuf[FGETS_SIZE];
+
+ buf[size - 2] = NUL;
+#ifdef USE_CR
+ eof = fgets_cr((char *)buf, size, fp);
+#else
+ eof = fgets((char *)buf, size, fp);
+#endif
+ if (buf[size - 2] != NUL && buf[size - 2] != '\n') {
+ buf[size - 1] = NUL; /* Truncate the line */
+
+ /* Now throw away the rest of the line: */
+ do {
+ tbuf[FGETS_SIZE - 2] = NUL;
+#ifdef USE_CR
+ ignoredp = fgets_cr((char *)tbuf, FGETS_SIZE, fp);
+#else
+ ignoredp = fgets((char *)tbuf, FGETS_SIZE, fp);
+#endif
+ } while (tbuf[FGETS_SIZE - 2] != NUL && tbuf[FGETS_SIZE - 2] != '\n');
+ }
+ return eof == NULL;
+}
+
+#if defined(USE_CR) || defined(PROTO)
+/*
+ * Like vim_fgets(), but accept any line terminator: CR, CR-LF or LF.
+ * Returns TRUE for end-of-file.
+ * Only used for the Mac, because it's much slower than vim_fgets().
+ */
+int tag_fgets(buf, size, fp)
+char_u *buf;
+int size;
+FILE *fp;
+{
+ int i = 0;
+ int c;
+ int eof = FALSE;
+
+ for (;; ) {
+ c = fgetc(fp);
+ if (c == EOF) {
+ eof = TRUE;
+ break;
+ }
+ if (c == '\r') {
+ /* Always store a NL for end-of-line. */
+ if (i < size - 1)
+ buf[i++] = '\n';
+ c = fgetc(fp);
+ if (c != '\n') /* Macintosh format: single CR. */
+ ungetc(c, fp);
+ break;
+ }
+ if (i < size - 1)
+ buf[i++] = c;
+ if (c == '\n')
+ break;
+ }
+ buf[i] = NUL;
+ return eof;
+}
+#endif
+
+/*
+ * 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(from, to)
+char_u *from;
+char_u *to;
+{
+ int fd_in;
+ int fd_out;
+ int n;
+ char *errmsg = NULL;
+ char *buffer;
+ struct stat st;
+ long perm;
+#ifdef HAVE_ACL
+ vim_acl_T acl; /* ACL from original file */
+#endif
+ int use_tmp_file = FALSE;
+
+ /*
+ * When the names are identical, there is nothing to do. When they refer
+ * to the same file (ignoring case and slash/backslash differences) but
+ * the file name differs we need to go through a temp file.
+ */
+ if (fnamecmp(from, to) == 0) {
+ if (p_fic && STRCMP(gettail(from), gettail(to)) != 0)
+ use_tmp_file = TRUE;
+ else
+ return 0;
+ }
+
+ /*
+ * Fail if the "from" file doesn't exist. Avoids that "to" is deleted.
+ */
+ if (mch_stat((char *)from, &st) < 0)
+ return -1;
+
+#ifdef UNIX
+ {
+ struct stat st_to;
+
+ /* It's possible for the source and destination to be the same file.
+ * This happens when "from" and "to" differ in case and are on a FAT32
+ * filesystem. In that case go through a temp file name. */
+ if (mch_stat((char *)to, &st_to) >= 0
+ && st.st_dev == st_to.st_dev
+ && st.st_ino == st_to.st_ino)
+ use_tmp_file = TRUE;
+ }
+#endif
+
+ if (use_tmp_file) {
+ char tempname[MAXPATHL + 1];
+
+ /*
+ * Find a name that doesn't exist and is in the same directory.
+ * Rename "from" to "tempname" and then rename "tempname" to "to".
+ */
+ if (STRLEN(from) >= MAXPATHL - 5)
+ return -1;
+ STRCPY(tempname, from);
+ for (n = 123; n < 99999; ++n) {
+ sprintf((char *)gettail((char_u *)tempname), "%d", n);
+ if (mch_stat(tempname, &st) < 0) {
+ if (mch_rename((char *)from, tempname) == 0) {
+ if (mch_rename(tempname, (char *)to) == 0)
+ return 0;
+ /* Strange, the second step failed. Try moving the
+ * file back and return failure. */
+ mch_rename(tempname, (char *)from);
+ return -1;
+ }
+ /* If it fails for one temp name it will most likely fail
+ * for any temp name, give up. */
+ return -1;
+ }
+ }
+ return -1;
+ }
+
+ /*
+ * Delete the "to" file, this is required on some systems to make the
+ * mch_rename() work, on other systems it makes sure that we don't have
+ * two files when the mch_rename() fails.
+ */
+
+ mch_remove(to);
+
+ /*
+ * First try a normal rename, return if it works.
+ */
+ if (mch_rename((char *)from, (char *)to) == 0)
+ return 0;
+
+ /*
+ * Rename() failed, try copying the file.
+ */
+ perm = mch_getperm(from);
+#ifdef HAVE_ACL
+ /* For systems that support ACL: get the ACL from the original file. */
+ acl = mch_get_acl(from);
+#endif
+ fd_in = mch_open((char *)from, O_RDONLY|O_EXTRA, 0);
+ if (fd_in == -1) {
+#ifdef HAVE_ACL
+ mch_free_acl(acl);
+#endif
+ return -1;
+ }
+
+ /* Create the new file with same permissions as the original. */
+ fd_out = mch_open((char *)to,
+ O_CREAT|O_EXCL|O_WRONLY|O_EXTRA|O_NOFOLLOW, (int)perm);
+ if (fd_out == -1) {
+ close(fd_in);
+#ifdef HAVE_ACL
+ mch_free_acl(acl);
+#endif
+ return -1;
+ }
+
+ buffer = (char *)alloc(BUFSIZE);
+ if (buffer == NULL) {
+ close(fd_out);
+ close(fd_in);
+#ifdef HAVE_ACL
+ mch_free_acl(acl);
+#endif
+ return -1;
+ }
+
+ while ((n = read_eintr(fd_in, buffer, BUFSIZE)) > 0)
+ if (write_eintr(fd_out, buffer, n) != n) {
+ errmsg = _("E208: Error writing to \"%s\"");
+ break;
+ }
+
+ vim_free(buffer);
+ close(fd_in);
+ if (close(fd_out) < 0)
+ errmsg = _("E209: Error closing \"%s\"");
+ if (n < 0) {
+ errmsg = _("E210: Error reading \"%s\"");
+ to = from;
+ }
+#ifndef UNIX /* for Unix mch_open() already set the permission */
+ mch_setperm(to, perm);
+#endif
+#ifdef HAVE_ACL
+ mch_set_acl(to, acl);
+ mch_free_acl(acl);
+#endif
+#ifdef HAVE_SELINUX
+ mch_copy_sec(from, to);
+#endif
+ if (errmsg != NULL) {
+ EMSG2(errmsg, to);
+ return -1;
+ }
+ mch_remove(from);
+ return 0;
+}
+
+static int already_warned = FALSE;
+
+/*
+ * Check if any not hidden buffer has been changed.
+ * Postpone the check if there are characters in the stuff buffer, a global
+ * command is being executed, a mapping is being executed or an autocommand is
+ * busy.
+ * Returns TRUE if some message was written (screen should be redrawn and
+ * cursor positioned).
+ */
+int check_timestamps(focus)
+int focus; /* called for GUI focus event */
+{
+ buf_T *buf;
+ int didit = 0;
+ int n;
+
+ /* Don't check timestamps while system() or another low-level function may
+ * cause us to lose and gain focus. */
+ if (no_check_timestamps > 0)
+ return FALSE;
+
+ /* Avoid doing a check twice. The OK/Reload dialog can cause a focus
+ * event and we would keep on checking if the file is steadily growing.
+ * Do check again after typing something. */
+ if (focus && did_check_timestamps) {
+ need_check_timestamps = TRUE;
+ return FALSE;
+ }
+
+ 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. */
+ if (buf->b_nwindows > 0) {
+ n = buf_check_timestamp(buf, focus);
+ if (didit < n)
+ didit = n;
+ if (n > 0 && !buf_valid(buf)) {
+ /* 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");
+ out_flush();
+ }
+ }
+ return didit;
+}
+
+/*
+ * Move all the lines from buffer "frombuf" to buffer "tobuf".
+ * Return OK or FAIL. When FAIL "tobuf" is incomplete and/or "frombuf" is not
+ * empty.
+ */
+static int move_lines(frombuf, tobuf)
+buf_T *frombuf;
+buf_T *tobuf;
+{
+ buf_T *tbuf = curbuf;
+ int retval = OK;
+ linenr_T lnum;
+ char_u *p;
+
+ /* Copy the lines in "frombuf" to "tobuf". */
+ curbuf = tobuf;
+ for (lnum = 1; lnum <= frombuf->b_ml.ml_line_count; ++lnum) {
+ p = vim_strsave(ml_get_buf(frombuf, lnum, FALSE));
+ if (p == NULL || ml_append(lnum - 1, p, 0, FALSE) == FAIL) {
+ vim_free(p);
+ retval = FAIL;
+ break;
+ }
+ vim_free(p);
+ }
+
+ /* Delete all the lines in "frombuf". */
+ if (retval != FAIL) {
+ curbuf = frombuf;
+ for (lnum = curbuf->b_ml.ml_line_count; lnum > 0; --lnum)
+ if (ml_delete(lnum, FALSE) == FAIL) {
+ /* Oops! We could try putting back the saved lines, but that
+ * might fail again... */
+ retval = FAIL;
+ break;
+ }
+ }
+
+ curbuf = tbuf;
+ return retval;
+}
+
+/*
+ * Check if buffer "buf" has been changed.
+ * Also check if the file for a new buffer unexpectedly appeared.
+ * return 1 if a changed buffer was found.
+ * return 2 if a message has been displayed.
+ * return 0 otherwise.
+ */
+int buf_check_timestamp(buf, focus)
+buf_T *buf;
+int focus UNUSED; /* called for GUI focus event */
+{
+ struct stat st;
+ int stat_res;
+ int retval = 0;
+ char_u *path;
+ char_u *tbuf;
+ char *mesg = NULL;
+ char *mesg2 = "";
+ int helpmesg = FALSE;
+ int reload = FALSE;
+ int can_reload = FALSE;
+ off_t orig_size = buf->b_orig_size;
+ int orig_mode = buf->b_orig_mode;
+ static int busy = FALSE;
+ int n;
+ char_u *s;
+ char *reason;
+
+ /* If 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. */
+ if (buf->b_ffname == NULL
+ || buf->b_ml.ml_mfp == NULL
+ || *buf->b_p_bt != NUL
+ || buf->b_saving
+ || busy
+ )
+ return 0;
+
+ if ( !(buf->b_flags & BF_NOTEDITED)
+ && buf->b_mtime != 0
+ && ((stat_res = mch_stat((char *)buf->b_ffname, &st)) < 0
+ || time_differs((long)st.st_mtime, buf->b_mtime)
+#ifdef HAVE_ST_MODE
+ || (int)st.st_mode != buf->b_orig_mode
+#else
+ || mch_getperm(buf->b_ffname) != buf->b_orig_mode
+#endif
+ )) {
+ retval = 1;
+
+ /* set b_mtime to stop further warnings (e.g., when executing
+ * FileChangedShell autocmd) */
+ if (stat_res < 0) {
+ buf->b_mtime = 0;
+ buf->b_orig_size = 0;
+ buf->b_orig_mode = 0;
+ } else
+ buf_store_time(buf, &st, buf->b_ffname);
+
+ /* Don't do anything for a directory. Might contain the file
+ * explorer. */
+ if (mch_isdir(buf->b_fname))
+ ;
+
+ /*
+ * If 'autoread' is set, the buffer has no changes and the file still
+ * exists, reload the buffer. Use the buffer-local option value if it
+ * was set, the global option value otherwise.
+ */
+ else if ((buf->b_p_ar >= 0 ? buf->b_p_ar : p_ar)
+ && !bufIsChanged(buf) && stat_res >= 0)
+ reload = TRUE;
+ else {
+ if (stat_res < 0)
+ reason = "deleted";
+ else if (bufIsChanged(buf))
+ reason = "conflict";
+ else if (orig_size != buf->b_orig_size || buf_contents_changed(buf))
+ reason = "changed";
+ else if (orig_mode != buf->b_orig_mode)
+ reason = "mode";
+ else
+ reason = "time";
+
+ /*
+ * Only give the warning if there are no FileChangedShell
+ * autocommands.
+ * Avoid being called recursively by setting "busy".
+ */
+ busy = TRUE;
+ set_vim_var_string(VV_FCS_REASON, (char_u *)reason, -1);
+ set_vim_var_string(VV_FCS_CHOICE, (char_u *)"", -1);
+ ++allbuf_lock;
+ n = apply_autocmds(EVENT_FILECHANGEDSHELL,
+ buf->b_fname, buf->b_fname, FALSE, buf);
+ --allbuf_lock;
+ busy = FALSE;
+ if (n) {
+ if (!buf_valid(buf))
+ EMSG(_("E246: FileChangedShell autocommand deleted buffer"));
+ s = get_vim_var_str(VV_FCS_CHOICE);
+ if (STRCMP(s, "reload") == 0 && *reason != 'd')
+ reload = TRUE;
+ else if (STRCMP(s, "ask") == 0)
+ n = FALSE;
+ else
+ return 2;
+ }
+ if (!n) {
+ if (*reason == 'd')
+ mesg = _("E211: File \"%s\" no longer available");
+ else {
+ helpmesg = TRUE;
+ can_reload = TRUE;
+ /*
+ * Check if the file contents really changed to avoid
+ * giving a warning when only the timestamp was set (e.g.,
+ * checked out of CVS). Always warn when the buffer was
+ * changed.
+ */
+ if (reason[2] == 'n') {
+ mesg = _(
+ "W12: Warning: File \"%s\" has changed and the buffer was changed in Vim as well");
+ mesg2 = _("See \":help W12\" for more info.");
+ } else if (reason[1] == 'h') {
+ mesg = _(
+ "W11: Warning: File \"%s\" has changed since editing started");
+ mesg2 = _("See \":help W11\" for more info.");
+ } else if (*reason == 'm') {
+ mesg = _(
+ "W16: Warning: Mode of file \"%s\" has changed since editing started");
+ mesg2 = _("See \":help W16\" for more info.");
+ } else
+ /* Only timestamp changed, store it to avoid a warning
+ * in check_mtime() later. */
+ buf->b_mtime_read = buf->b_mtime;
+ }
+ }
+ }
+
+ } else if ((buf->b_flags & BF_NEW) && !(buf->b_flags & BF_NEW_W)
+ && vim_fexists(buf->b_ffname)) {
+ retval = 1;
+ mesg = _("W13: Warning: File \"%s\" has been created after editing started");
+ buf->b_flags |= BF_NEW_W;
+ can_reload = TRUE;
+ }
+
+ if (mesg != NULL) {
+ path = home_replace_save(buf, buf->b_fname);
+ if (path != NULL) {
+ if (!helpmesg)
+ mesg2 = "";
+ tbuf = alloc((unsigned)(STRLEN(path) + STRLEN(mesg)
+ + STRLEN(mesg2) + 2));
+ sprintf((char *)tbuf, mesg, path);
+ /* Set warningmsg here, before the unimportant and output-specific
+ * mesg2 has been appended. */
+ set_vim_var_string(VV_WARNINGMSG, tbuf, -1);
+ if (can_reload) {
+ if (*mesg2 != NUL) {
+ STRCAT(tbuf, "\n");
+ STRCAT(tbuf, mesg2);
+ }
+ if (do_dialog(VIM_WARNING, (char_u *)_("Warning"), tbuf,
+ (char_u *)_("&OK\n&Load File"), 1, NULL, TRUE) == 2)
+ reload = TRUE;
+ } else if (State > NORMAL_BUSY || (State & CMDLINE) ||
+ already_warned) {
+ if (*mesg2 != NUL) {
+ STRCAT(tbuf, "; ");
+ STRCAT(tbuf, mesg2);
+ }
+ EMSG(tbuf);
+ retval = 2;
+ } else {
+ if (!autocmd_busy) {
+ msg_start();
+ 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_clr_eos();
+ (void)msg_end();
+ if (emsg_silent == 0) {
+ out_flush();
+ /* give the user some time to think about it */
+ ui_delay(1000L, TRUE);
+
+ /* don't redraw and erase the message */
+ redraw_cmdline = FALSE;
+ }
+ }
+ already_warned = TRUE;
+ }
+
+ vim_free(path);
+ vim_free(tbuf);
+ }
+ }
+
+ if (reload) {
+ /* Reload the buffer. */
+ buf_reload(buf, orig_mode);
+ if (buf->b_p_udf && buf->b_ffname != NULL) {
+ char_u hash[UNDO_HASH_SIZE];
+ buf_T *save_curbuf = curbuf;
+
+ /* Any existing undo file is unusable, write it now. */
+ curbuf = buf;
+ u_compute_hash(hash);
+ u_write_undo(NULL, FALSE, buf, hash);
+ curbuf = save_curbuf;
+ }
+ }
+
+ /* 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);
+
+ return retval;
+}
+
+/*
+ * Reload a buffer that is already loaded.
+ * Used when the file was changed outside of Vim.
+ * "orig_mode" is buf->b_orig_mode before the need for reloading was detected.
+ * buf->b_orig_mode may have been reset already.
+ */
+void buf_reload(buf, orig_mode)
+buf_T *buf;
+int orig_mode;
+{
+ exarg_T ea;
+ pos_T old_cursor;
+ linenr_T old_topline;
+ int old_ro = buf->b_p_ro;
+ buf_T *savebuf;
+ int saved = OK;
+ aco_save_T aco;
+ int flags = READ_NEW;
+
+ /* set curwin/curbuf for "buf" and save some things */
+ aucmd_prepbuf(&aco, buf);
+
+ /* We only want to read the text from the file, not reset the syntax
+ * highlighting, clear marks, diff status, etc. Force the fileformat
+ * and encoding to be the same. */
+ if (prep_exarg(&ea, buf) == OK) {
+ old_cursor = curwin->w_cursor;
+ old_topline = curwin->w_topline;
+
+ 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);
+ saved = u_savecommon(0, curbuf->b_ml.ml_line_count + 1, 0, TRUE);
+ 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)
+ savebuf = NULL;
+ else {
+ /* Allocate a buffer without putting it in the buffer list. */
+ savebuf = buflist_new(NULL, NULL, (linenr_T)1, BLN_DUMMY);
+ if (savebuf != NULL && buf == curbuf) {
+ /* Open the memline. */
+ curbuf = savebuf;
+ curwin->w_buffer = savebuf;
+ saved = ml_open(curbuf);
+ curbuf = buf;
+ curwin->w_buffer = buf;
+ }
+ if (savebuf == NULL || saved == FAIL || buf != curbuf
+ || move_lines(buf, savebuf) == FAIL) {
+ EMSG2(_("E462: Could not prepare for reloading \"%s\""),
+ buf->b_fname);
+ saved = FAIL;
+ }
+ }
+
+ 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())
+ 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)
+ break;
+ (void)move_lines(savebuf, buf);
+ }
+ } else if (buf == curbuf) { /* "buf" still valid */
+ /* Mark the buffer as unmodified and free undo info. */
+ unchanged(buf, TRUE);
+ if ((flags & READ_KEEP_UNDO) == 0) {
+ u_blockfree(buf);
+ u_clearall(buf);
+ } else {
+ /* Mark all undo states as changed. */
+ u_unchanged(curbuf);
+ }
+ }
+ }
+ vim_free(ea.cmd);
+
+ if (savebuf != NULL && buf_valid(savebuf))
+ wipe_buffer(savebuf, FALSE);
+
+ /* Invalidate diff info if necessary. */
+ diff_invalidate(curbuf);
+
+ /* Restore the topline and cursor position and check it (lines may
+ * have been removed). */
+ if (old_topline > curbuf->b_ml.ml_line_count)
+ curwin->w_topline = curbuf->b_ml.ml_line_count;
+ else
+ curwin->w_topline = old_topline;
+ curwin->w_cursor = old_cursor;
+ check_cursor();
+ update_topline();
+ keep_filetype = FALSE;
+ {
+ win_T *wp;
+ tabpage_T *tp;
+
+ /* Update folds unless they are defined manually. */
+ FOR_ALL_TAB_WINDOWS(tp, wp)
+ if (wp->w_buffer == curwin->w_buffer
+ && !foldmethodIsManual(wp))
+ foldUpdateAll(wp);
+ }
+ /* If the mode didn't change and 'readonly' was set, keep the old
+ * value; the user probably used the ":view" command. But don't
+ * reset it, might have had a read error. */
+ if (orig_mode == curbuf->b_orig_mode)
+ curbuf->b_p_ro |= old_ro;
+
+ /* Modelines must override settings done by autocommands. */
+ do_modelines(0);
+ }
+
+ /* restore curwin/curbuf and a few other things */
+ aucmd_restbuf(&aco);
+ /* Careful: autocommands may have made "buf" invalid! */
+}
+
+void buf_store_time(buf, st, fname)
+buf_T *buf;
+struct stat *st;
+char_u *fname UNUSED;
+{
+ buf->b_mtime = (long)st->st_mtime;
+ buf->b_orig_size = st->st_size;
+#ifdef HAVE_ST_MODE
+ buf->b_orig_mode = (int)st->st_mode;
+#else
+ buf->b_orig_mode = mch_getperm(fname);
+#endif
+}
+
+/*
+ * Adjust the line with missing eol, used for the next write.
+ * Used for do_filter(), when the input lines for the filter are deleted.
+ */
+void write_lnum_adjust(offset)
+linenr_T offset;
+{
+ if (curbuf->b_no_eol_lnum != 0) /* only if there is a missing eol */
+ curbuf->b_no_eol_lnum += offset;
+}
+
+#if defined(TEMPDIRNAMES) || defined(PROTO)
+static long temp_count = 0; /* Temp filename counter. */
+
+/*
+ * Delete the temp directory and all files it contains.
+ */
+void vim_deltempdir() {
+ char_u **files;
+ int file_count;
+ int i;
+
+ if (vim_tempdir != NULL) {
+ sprintf((char *)NameBuff, "%s*", vim_tempdir);
+ if (gen_expand_wildcards(1, &NameBuff, &file_count, &files,
+ EW_DIR|EW_FILE|EW_SILENT) == OK) {
+ for (i = 0; i < file_count; ++i)
+ mch_remove(files[i]);
+ FreeWild(file_count, files);
+ }
+ gettail(NameBuff)[-1] = NUL;
+ (void)mch_rmdir(NameBuff);
+
+ vim_free(vim_tempdir);
+ vim_tempdir = NULL;
+ }
+}
+
+#endif
+
+#ifdef TEMPDIRNAMES
+/*
+ * Directory "tempdir" was created. Expand this name to a full path and put
+ * it in "vim_tempdir". This avoids that using ":cd" would confuse us.
+ * "tempdir" must be no longer than MAXPATHL.
+ */
+static void vim_settempdir(tempdir)
+char_u *tempdir;
+{
+ char_u *buf;
+
+ buf = alloc((unsigned)MAXPATHL + 2);
+ if (buf != NULL) {
+ if (vim_FullName(tempdir, buf, MAXPATHL, FALSE) == FAIL)
+ STRCPY(buf, tempdir);
+ add_pathsep(buf);
+ vim_tempdir = vim_strsave(buf);
+ vim_free(buf);
+ }
+}
+#endif
+
+/*
+ * vim_tempname(): Return a unique name that can be used for a temp file.
+ *
+ * The temp file is NOT created.
+ *
+ * The returned pointer is to allocated memory.
+ * The returned pointer is NULL if no valid name was found.
+ */
+char_u * vim_tempname(extra_char)
+int extra_char UNUSED; /* char to use in the name instead of '?' */
+{
+#ifdef USE_TMPNAM
+ char_u itmp[L_tmpnam]; /* use tmpnam() */
+#else
+ char_u itmp[TEMPNAMELEN];
+#endif
+
+#ifdef TEMPDIRNAMES
+ static char *(tempdirs[]) = {TEMPDIRNAMES};
+ int i;
+# ifndef EEXIST
+ struct stat st;
+# endif
+
+ /*
+ * This will create a directory for private use by this instance of Vim.
+ * This is done once, and the same directory is used for all temp files.
+ * This method avoids security problems because of symlink attacks et al.
+ * It's also a bit faster, because we only need to check for an existing
+ * file when creating the directory and not for each temp file.
+ */
+ if (vim_tempdir == NULL) {
+ /*
+ * Try the entries in TEMPDIRNAMES to create the temp directory.
+ */
+ for (i = 0; i < (int)(sizeof(tempdirs) / sizeof(char *)); ++i) {
+# ifndef HAVE_MKDTEMP
+ size_t itmplen;
+ long nr;
+ long off;
+# endif
+
+ /* expand $TMP, leave room for "/v1100000/999999999" */
+ expand_env((char_u *)tempdirs[i], itmp, TEMPNAMELEN - 20);
+ if (mch_isdir(itmp)) { /* directory exists */
+ add_pathsep(itmp);
+
+# ifdef HAVE_MKDTEMP
+ /* Leave room for filename */
+ STRCAT(itmp, "vXXXXXX");
+ if (mkdtemp((char *)itmp) != NULL)
+ vim_settempdir(itmp);
+# else
+ /* Get an arbitrary number of up to 6 digits. When it's
+ * unlikely that it already exists it will be faster,
+ * otherwise it doesn't matter. The use of mkdir() avoids any
+ * security problems because of the predictable number. */
+ nr = (mch_get_pid() + (long)time(NULL)) % 1000000L;
+ itmplen = STRLEN(itmp);
+
+ /* Try up to 10000 different values until we find a name that
+ * doesn't exist. */
+ for (off = 0; off < 10000L; ++off) {
+ int r;
+# if defined(UNIX) || defined(VMS)
+ mode_t umask_save;
+# endif
+
+ sprintf((char *)itmp + itmplen, "v%ld", nr + off);
+# ifndef EEXIST
+ /* If mkdir() does not set errno to EEXIST, check for
+ * existing file here. There is a race condition then,
+ * although it's fail-safe. */
+ if (mch_stat((char *)itmp, &st) >= 0)
+ continue;
+# endif
+# if defined(UNIX) || defined(VMS)
+ /* Make sure the umask doesn't remove the executable bit.
+ * "repl" has been reported to use "177". */
+ umask_save = umask(077);
+# endif
+ r = vim_mkdir(itmp, 0700);
+# if defined(UNIX) || defined(VMS)
+ (void)umask(umask_save);
+# endif
+ if (r == 0) {
+ vim_settempdir(itmp);
+ break;
+ }
+# ifdef EEXIST
+ /* If the mkdir() didn't fail because the file/dir exists,
+ * we probably can't create any dir here, try another
+ * place. */
+ if (errno != EEXIST)
+# endif
+ break;
+ }
+# endif /* HAVE_MKDTEMP */
+ if (vim_tempdir != NULL)
+ break;
+ }
+ }
+ }
+
+ if (vim_tempdir != NULL) {
+ /* There is no need to check if the file exists, because we own the
+ * directory and nobody else creates a file in it. */
+ sprintf((char *)itmp, "%s%ld", vim_tempdir, temp_count++);
+ return vim_strsave(itmp);
+ }
+
+ return NULL;
+
+#else /* TEMPDIRNAMES */
+
+
+# ifdef USE_TMPNAM
+ char_u *p;
+
+ /* tmpnam() will make its own name */
+ p = tmpnam((char *)itmp);
+ if (p == NULL || *p == NUL)
+ return NULL;
+# else
+ char_u *p;
+
+# ifdef VMS_TEMPNAM
+ /* mktemp() is not working on VMS. It seems to be
+ * a do-nothing function. Therefore we use tempnam().
+ */
+ sprintf((char *)itmp, "VIM%c", extra_char);
+ p = (char_u *)tempnam("tmp:", (char *)itmp);
+ if (p != NULL) {
+ /* VMS will use '.LOG' if we don't explicitly specify an extension,
+ * and VIM will then be unable to find the file later */
+ STRCPY(itmp, p);
+ STRCAT(itmp, ".txt");
+ free(p);
+ } else
+ return NULL;
+# else
+ STRCPY(itmp, TEMPNAME);
+ if ((p = vim_strchr(itmp, '?')) != NULL)
+ *p = extra_char;
+ if (mktemp((char *)itmp) == NULL)
+ return NULL;
+# endif
+# endif
+
+ return vim_strsave(itmp);
+#endif /* TEMPDIRNAMES */
+}
+
+#if defined(BACKSLASH_IN_FILENAME) || defined(PROTO)
+/*
+ * Convert all backslashes in fname to forward slashes in-place.
+ */
+void forward_slash(fname)
+char_u *fname;
+{
+ char_u *p;
+
+ for (p = fname; *p != NUL; ++p)
+ /* The Big5 encoding can have '\' in the trail byte. */
+ if (enc_dbcs != 0 && (*mb_ptr2len)(p) > 1)
+ ++p;
+ else if (*p == '\\')
+ *p = '/';
+}
+#endif
+
+
+/*
+ * Code for automatic commands.
+ *
+ * Only included when "FEAT_AUTOCMD" has been defined.
+ */
+
+
+/*
+ * 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.
+ */
+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 */
+} 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() */
+} AutoPat;
+
+static struct event_name {
+ char *name; /* event name */
+ event_T event; /* event number */
+} event_names[] =
+{
+ {"BufAdd", EVENT_BUFADD},
+ {"BufCreate", EVENT_BUFADD},
+ {"BufDelete", EVENT_BUFDELETE},
+ {"BufEnter", EVENT_BUFENTER},
+ {"BufFilePost", EVENT_BUFFILEPOST},
+ {"BufFilePre", EVENT_BUFFILEPRE},
+ {"BufHidden", EVENT_BUFHIDDEN},
+ {"BufLeave", EVENT_BUFLEAVE},
+ {"BufNew", EVENT_BUFNEW},
+ {"BufNewFile", EVENT_BUFNEWFILE},
+ {"BufRead", EVENT_BUFREADPOST},
+ {"BufReadCmd", EVENT_BUFREADCMD},
+ {"BufReadPost", EVENT_BUFREADPOST},
+ {"BufReadPre", EVENT_BUFREADPRE},
+ {"BufUnload", EVENT_BUFUNLOAD},
+ {"BufWinEnter", EVENT_BUFWINENTER},
+ {"BufWinLeave", EVENT_BUFWINLEAVE},
+ {"BufWipeout", EVENT_BUFWIPEOUT},
+ {"BufWrite", EVENT_BUFWRITEPRE},
+ {"BufWritePost", EVENT_BUFWRITEPOST},
+ {"BufWritePre", EVENT_BUFWRITEPRE},
+ {"BufWriteCmd", EVENT_BUFWRITECMD},
+ {"CmdwinEnter", EVENT_CMDWINENTER},
+ {"CmdwinLeave", EVENT_CMDWINLEAVE},
+ {"ColorScheme", EVENT_COLORSCHEME},
+ {"CompleteDone", EVENT_COMPLETEDONE},
+ {"CursorHold", EVENT_CURSORHOLD},
+ {"CursorHoldI", EVENT_CURSORHOLDI},
+ {"CursorMoved", EVENT_CURSORMOVED},
+ {"CursorMovedI", EVENT_CURSORMOVEDI},
+ {"EncodingChanged", EVENT_ENCODINGCHANGED},
+ {"FileEncoding", EVENT_ENCODINGCHANGED},
+ {"FileAppendPost", EVENT_FILEAPPENDPOST},
+ {"FileAppendPre", EVENT_FILEAPPENDPRE},
+ {"FileAppendCmd", EVENT_FILEAPPENDCMD},
+ {"FileChangedShell",EVENT_FILECHANGEDSHELL},
+ {"FileChangedShellPost",EVENT_FILECHANGEDSHELLPOST},
+ {"FileChangedRO", EVENT_FILECHANGEDRO},
+ {"FileReadPost", EVENT_FILEREADPOST},
+ {"FileReadPre", EVENT_FILEREADPRE},
+ {"FileReadCmd", EVENT_FILEREADCMD},
+ {"FileType", EVENT_FILETYPE},
+ {"FileWritePost", EVENT_FILEWRITEPOST},
+ {"FileWritePre", EVENT_FILEWRITEPRE},
+ {"FileWriteCmd", EVENT_FILEWRITECMD},
+ {"FilterReadPost", EVENT_FILTERREADPOST},
+ {"FilterReadPre", EVENT_FILTERREADPRE},
+ {"FilterWritePost", EVENT_FILTERWRITEPOST},
+ {"FilterWritePre", EVENT_FILTERWRITEPRE},
+ {"FocusGained", EVENT_FOCUSGAINED},
+ {"FocusLost", EVENT_FOCUSLOST},
+ {"FuncUndefined", EVENT_FUNCUNDEFINED},
+ {"GUIEnter", EVENT_GUIENTER},
+ {"GUIFailed", EVENT_GUIFAILED},
+ {"InsertChange", EVENT_INSERTCHANGE},
+ {"InsertEnter", EVENT_INSERTENTER},
+ {"InsertLeave", EVENT_INSERTLEAVE},
+ {"InsertCharPre", EVENT_INSERTCHARPRE},
+ {"MenuPopup", EVENT_MENUPOPUP},
+ {"QuickFixCmdPost", EVENT_QUICKFIXCMDPOST},
+ {"QuickFixCmdPre", EVENT_QUICKFIXCMDPRE},
+ {"QuitPre", EVENT_QUITPRE},
+ {"RemoteReply", EVENT_REMOTEREPLY},
+ {"SessionLoadPost", EVENT_SESSIONLOADPOST},
+ {"ShellCmdPost", EVENT_SHELLCMDPOST},
+ {"ShellFilterPost", EVENT_SHELLFILTERPOST},
+ {"SourcePre", EVENT_SOURCEPRE},
+ {"SourceCmd", EVENT_SOURCECMD},
+ {"SpellFileMissing",EVENT_SPELLFILEMISSING},
+ {"StdinReadPost", EVENT_STDINREADPOST},
+ {"StdinReadPre", EVENT_STDINREADPRE},
+ {"SwapExists", EVENT_SWAPEXISTS},
+ {"Syntax", EVENT_SYNTAX},
+ {"TabEnter", EVENT_TABENTER},
+ {"TabLeave", EVENT_TABLEAVE},
+ {"TermChanged", EVENT_TERMCHANGED},
+ {"TermResponse", EVENT_TERMRESPONSE},
+ {"TextChanged", EVENT_TEXTCHANGED},
+ {"TextChangedI", EVENT_TEXTCHANGEDI},
+ {"User", EVENT_USER},
+ {"VimEnter", EVENT_VIMENTER},
+ {"VimLeave", EVENT_VIMLEAVE},
+ {"VimLeavePre", EVENT_VIMLEAVEPRE},
+ {"WinEnter", EVENT_WINENTER},
+ {"WinLeave", EVENT_WINLEAVE},
+ {"VimResized", EVENT_VIMRESIZED},
+ {NULL, (event_T)0}
+};
+
+static AutoPat *first_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
+};
+
+/*
+ * struct used to keep status while executing autocommands for an event.
+ */
+typedef struct AutoPatCmd {
+ AutoPat *curpat; /* next AutoPat to examine */
+ AutoCmd *nextcmd; /* next AutoCmd to execute */
+ int group; /* group being used */
+ char_u *fname; /* fname to match with */
+ char_u *sfname; /* sfname to match with */
+ char_u *tail; /* tail of fname */
+ event_T event; /* current event */
+ int arg_bufnr; /* initially equal to <abuf>, set to zero when
+ buf is deleted */
+ struct AutoPatCmd *next; /* chain of active apc-s for auto-invalidation*/
+} AutoPatCmd;
+
+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])
+
+/*
+ * The ID of the current group. Group 0 is the default one.
+ */
+static int current_augroup = AUGROUP_DEFAULT;
+
+static int au_need_clean = FALSE; /* need to delete marked patterns */
+
+static void show_autocmd __ARGS((AutoPat *ap, event_T event));
+static void au_remove_pat __ARGS((AutoPat *ap));
+static void au_remove_cmds __ARGS((AutoPat *ap));
+static void au_cleanup __ARGS((void));
+static int au_new_group __ARGS((char_u *name));
+static void au_del_group __ARGS((char_u *name));
+static event_T event_name2nr __ARGS((char_u *start, char_u **end));
+static char_u *event_nr2name __ARGS((event_T event));
+static char_u *find_end_event __ARGS((char_u *arg, int have_group));
+static int event_ignored __ARGS((event_T event));
+static int au_get_grouparg __ARGS((char_u **argp));
+static int do_autocmd_event __ARGS((event_T event, char_u *pat, int nested,
+ char_u *cmd, int forceit,
+ int group));
+static int apply_autocmds_group __ARGS((event_T event, char_u *fname, char_u *
+ fname_io, int force, int group, buf_T *
+ buf,
+ exarg_T *eap));
+static void auto_next_pat __ARGS((AutoPatCmd *apc, int stop_at_last));
+
+
+static event_T last_event;
+static int last_group;
+static int autocmd_blocked = 0; /* block all autocmds */
+
+/*
+ * Show the autocommands for one AutoPat.
+ */
+static void show_autocmd(ap, event)
+AutoPat *ap;
+event_T event;
+{
+ AutoCmd *ac;
+
+ /* Check for "got_int" (here and at various places below), which is set
+ * when "q" has been hit for the "--more--" prompt */
+ if (got_int)
+ return;
+ if (ap->pat == NULL) /* pattern has been removed */
+ return;
+
+ msg_putchar('\n');
+ if (got_int)
+ 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 *)" ");
+ }
+ msg_puts_attr(event_nr2name(event), hl_attr(HLF_T));
+ last_event = event;
+ last_group = ap->group;
+ msg_putchar('\n');
+ if (got_int)
+ return;
+ }
+ msg_col = 4;
+ msg_outtrans(ap->pat);
+
+ for (ac = ap->cmds; ac != NULL; ac = ac->next) {
+ if (ac->cmd != NULL) { /* skip removed commands */
+ if (msg_col >= 14)
+ msg_putchar('\n');
+ msg_col = 14;
+ if (got_int)
+ return;
+ msg_outtrans(ac->cmd);
+ if (p_verbose > 0)
+ last_set_msg(ac->scriptID);
+ if (got_int)
+ return;
+ if (ac->next != NULL) {
+ msg_putchar('\n');
+ if (got_int)
+ return;
+ }
+ }
+ }
+}
+
+/*
+ * Mark an autocommand pattern for deletion.
+ */
+static void au_remove_pat(ap)
+AutoPat *ap;
+{
+ vim_free(ap->pat);
+ ap->pat = NULL;
+ ap->buflocal_nr = -1;
+ au_need_clean = TRUE;
+}
+
+/*
+ * Mark all commands for a pattern for deletion.
+ */
+static void au_remove_cmds(ap)
+AutoPat *ap;
+{
+ AutoCmd *ac;
+
+ for (ac = ap->cmds; ac != NULL; ac = ac->next) {
+ vim_free(ac->cmd);
+ ac->cmd = NULL;
+ }
+ au_need_clean = TRUE;
+}
+
+/*
+ * Cleanup autocommands and patterns that have been deleted.
+ * This is only done when not executing autocommands.
+ */
+static void au_cleanup() {
+ AutoPat *ap, **prev_ap;
+ AutoCmd *ac, **prev_ac;
+ event_T event;
+
+ if (autocmd_busy || !au_need_clean)
+ return;
+
+ /* loop over all events */
+ for (event = (event_T)0; (int)event < (int)NUM_EVENTS;
+ event = (event_T)((int)event + 1)) {
+ /* loop over all autocommand patterns */
+ prev_ap = &(first_autopat[(int)event]);
+ for (ap = *prev_ap; ap != NULL; ap = *prev_ap) {
+ /* loop over all commands for this pattern */
+ prev_ac = &(ap->cmds);
+ for (ac = *prev_ac; ac != NULL; ac = *prev_ac) {
+ /* remove the command if the pattern is to be deleted or when
+ * the command has been marked for deletion */
+ if (ap->pat == NULL || ac->cmd == NULL) {
+ *prev_ac = ac->next;
+ vim_free(ac->cmd);
+ vim_free(ac);
+ } else
+ prev_ac = &(ac->next);
+ }
+
+ /* remove the pattern if it has been marked for deletion */
+ if (ap->pat == NULL) {
+ *prev_ap = ap->next;
+ vim_regfree(ap->reg_prog);
+ vim_free(ap);
+ } else
+ prev_ap = &(ap->next);
+ }
+ }
+
+ au_need_clean = FALSE;
+}
+
+/*
+ * Called when buffer is freed, to remove/invalidate related buffer-local
+ * autocmds.
+ */
+void aubuflocal_remove(buf)
+buf_T *buf;
+{
+ AutoPat *ap;
+ event_T event;
+ AutoPatCmd *apc;
+
+ /* invalidate currently executing autocommands */
+ for (apc = active_apc_list; apc; apc = apc->next)
+ if (buf->b_fnum == apc->arg_bufnr)
+ apc->arg_bufnr = 0;
+
+ /* invalidate buflocals looping through events */
+ for (event = (event_T)0; (int)event < (int)NUM_EVENTS;
+ event = (event_T)((int)event + 1))
+ /* loop over all autocommand patterns */
+ for (ap = first_autopat[(int)event]; ap != NULL; ap = ap->next)
+ if (ap->buflocal_nr == buf->b_fnum) {
+ au_remove_pat(ap);
+ if (p_verbose >= 6) {
+ verbose_enter();
+ smsg((char_u *)
+ _("auto-removing autocommand: %s <buffer=%d>"),
+ event_nr2name(event), buf->b_fnum);
+ verbose_leave();
+ }
+ }
+ au_cleanup();
+}
+
+/*
+ * Add an autocmd group name.
+ * Return it's ID. Returns AUGROUP_ERROR (< 0) for error.
+ */
+static int au_new_group(name)
+char_u *name;
+{
+ int i;
+
+ i = au_find_group(name);
+ if (i == AUGROUP_ERROR) { /* the group doesn't exist yet, add it */
+ /* First try using a free entry. */
+ for (i = 0; i < augroups.ga_len; ++i)
+ if (AUGROUP_NAME(i) == NULL)
+ break;
+ if (i == augroups.ga_len && ga_grow(&augroups, 1) == FAIL)
+ return AUGROUP_ERROR;
+
+ AUGROUP_NAME(i) = vim_strsave(name);
+ if (AUGROUP_NAME(i) == NULL)
+ return AUGROUP_ERROR;
+ if (i == augroups.ga_len)
+ ++augroups.ga_len;
+ }
+
+ return i;
+}
+
+static void au_del_group(name)
+char_u *name;
+{
+ int i;
+
+ i = au_find_group(name);
+ if (i == AUGROUP_ERROR) /* the group doesn't exist */
+ EMSG2(_("E367: No such group: \"%s\""), name);
+ else {
+ vim_free(AUGROUP_NAME(i));
+ AUGROUP_NAME(i) = NULL;
+ }
+}
+
+/*
+ * Find the ID of an autocmd group name.
+ * Return it's ID. Returns AUGROUP_ERROR (< 0) for error.
+ */
+static int au_find_group(name)
+char_u *name;
+{
+ int i;
+
+ for (i = 0; i < augroups.ga_len; ++i)
+ if (AUGROUP_NAME(i) != NULL && STRCMP(AUGROUP_NAME(i), name) == 0)
+ return i;
+ return AUGROUP_ERROR;
+}
+
+/*
+ * Return TRUE if augroup "name" exists.
+ */
+int au_has_group(name)
+char_u *name;
+{
+ return au_find_group(name) != AUGROUP_ERROR;
+}
+
+/*
+ * ":augroup {name}".
+ */
+void do_augroup(arg, del_group)
+char_u *arg;
+int del_group;
+{
+ int i;
+
+ if (del_group) {
+ if (*arg == NUL)
+ EMSG(_(e_argreq));
+ else
+ au_del_group(arg);
+ } else if (STRICMP(arg, "end") == 0) /* ":aug end": back to group 0 */
+ current_augroup = AUGROUP_DEFAULT;
+ else if (*arg) { /* ":aug xxx": switch to group xxx */
+ i = au_new_group(arg);
+ if (i != AUGROUP_ERROR)
+ current_augroup = i;
+ } else { /* ":aug": list the group names */
+ msg_start();
+ for (i = 0; i < augroups.ga_len; ++i) {
+ if (AUGROUP_NAME(i) != NULL) {
+ msg_puts(AUGROUP_NAME(i));
+ msg_puts((char_u *)" ");
+ }
+ }
+ msg_clr_eos();
+ msg_end();
+ }
+}
+
+#if defined(EXITFREE) || defined(PROTO)
+void free_all_autocmds() {
+ for (current_augroup = -1; current_augroup < augroups.ga_len;
+ ++current_augroup)
+ do_autocmd((char_u *)"", TRUE);
+ ga_clear_strings(&augroups);
+}
+
+#endif
+
+/*
+ * Return the event number for event name "start".
+ * 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(start, end)
+char_u *start;
+char_u **end;
+{
+ char_u *p;
+ int i;
+ int len;
+
+ /* the event name ends with end of line, a blank or a comma */
+ for (p = start; *p && !vim_iswhite(*p) && *p != ','; ++p)
+ ;
+ for (i = 0; event_names[i].name != NULL; ++i) {
+ len = (int)STRLEN(event_names[i].name);
+ if (len == p - start && STRNICMP(event_names[i].name, start, len) == 0)
+ break;
+ }
+ if (*p == ',')
+ ++p;
+ *end = 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)
+event_T event;
+{
+ 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";
+}
+
+/*
+ * Scan over the events. "*" stands for all events.
+ */
+static char_u * find_end_event(arg, have_group)
+char_u *arg;
+int have_group; /* TRUE when group name was found */
+{
+ char_u *pat;
+ char_u *p;
+
+ if (*arg == '*') {
+ if (arg[1] && !vim_iswhite(arg[1])) {
+ EMSG2(_("E215: Illegal character after *: %s"), arg);
+ return NULL;
+ }
+ pat = arg + 1;
+ } else {
+ for (pat = arg; *pat && !vim_iswhite(*pat); pat = p) {
+ if ((int)event_name2nr(pat, &p) >= (int)NUM_EVENTS) {
+ if (have_group)
+ EMSG2(_("E216: No such event: %s"), pat);
+ else
+ EMSG2(_("E216: No such group or event: %s"), pat);
+ return NULL;
+ }
+ }
+ }
+ return pat;
+}
+
+/*
+ * Return TRUE if "event" is included in 'eventignore'.
+ */
+static int event_ignored(event)
+event_T event;
+{
+ char_u *p = p_ei;
+
+ while (*p != NUL) {
+ if (STRNICMP(p, "all", 3) == 0 && (p[3] == NUL || p[3] == ','))
+ return TRUE;
+ if (event_name2nr(p, &p) == event)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/*
+ * Return OK when the contents of p_ei is valid, FAIL otherwise.
+ */
+int check_ei() {
+ char_u *p = p_ei;
+
+ while (*p) {
+ if (STRNICMP(p, "all", 3) == 0 && (p[3] == NUL || p[3] == ',')) {
+ p += 3;
+ if (*p == ',')
+ ++p;
+ } else if (event_name2nr(p, &p) == NUM_EVENTS)
+ return FAIL;
+ }
+
+ return OK;
+}
+
+/*
+ * Add "what" to 'eventignore' to skip loading syntax highlighting for every
+ * buffer loaded into the window. "what" must start with a comma.
+ * Returns the old value of 'eventignore' in allocated memory.
+ */
+char_u * au_event_disable(what)
+char *what;
+{
+ char_u *new_ei;
+ char_u *save_ei;
+
+ save_ei = vim_strsave(p_ei);
+ if (save_ei != NULL) {
+ new_ei = vim_strnsave(p_ei, (int)(STRLEN(p_ei) + STRLEN(what)));
+ if (new_ei != NULL) {
+ if (*what == ',' && *p_ei == NUL)
+ STRCPY(new_ei, what + 1);
+ else
+ STRCAT(new_ei, what);
+ set_string_option_direct((char_u *)"ei", -1, new_ei,
+ OPT_FREE, SID_NONE);
+ vim_free(new_ei);
+ }
+ }
+ return save_ei;
+}
+
+void au_event_restore(old_ei)
+char_u *old_ei;
+{
+ if (old_ei != NULL) {
+ set_string_option_direct((char_u *)"ei", -1, old_ei,
+ OPT_FREE, SID_NONE);
+ vim_free(old_ei);
+ }
+}
+
+/*
+ * do_autocmd() -- implements the :autocmd command. Can be used in the
+ * following ways:
+ *
+ * :autocmd <event> <pat> <cmd> Add <cmd> to the list of commands that
+ * 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
+ * <event> and <pat>.
+ * :autocmd <event> Show the auto-commands associated with
+ * <event>.
+ * :autocmd Show all auto-commands.
+ * :autocmd! <event> <pat> <cmd> Remove all auto-commands associated with
+ * <event> and <pat>, and add the command
+ * <cmd>, for the current group.
+ * :autocmd! <event> <pat> Remove all auto-commands associated with
+ * <event> and <pat> for the current group.
+ * :autocmd! <event> Remove all auto-commands associated with
+ * <event> for the current group.
+ * :autocmd! Remove ALL auto-commands for the current
+ * group.
+ *
+ * Multiple events and patterns may be given separated by commas. Here are
+ * some examples:
+ * :autocmd bufread,bufenter *.c,*.h set tw=0 smartindent noic
+ * :autocmd bufleave * set tw=79 nosmartindent ic infercase
+ *
+ * :autocmd * *.c show all autocommands for *.c files.
+ *
+ * Mostly a {group} argument can optionally appear before <event>.
+ */
+void do_autocmd(arg, forceit)
+char_u *arg;
+int forceit;
+{
+ char_u *pat;
+ char_u *envpat = NULL;
+ char_u *cmd;
+ event_T event;
+ 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 == NULL) /* out of memory */
+ return;
+
+ /*
+ * Scan over the events.
+ * If we find an illegal name, return here, don't do anything.
+ */
+ pat = find_end_event(arg, group != AUGROUP_ALL);
+ if (pat == NULL)
+ return;
+
+ /*
+ * Scan over the pattern. Put a NUL at the end.
+ */
+ pat = skipwhite(pat);
+ cmd = pat;
+ while (*cmd && (!vim_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;
+
+ p_ssl = TRUE;
+#endif
+ envpat = expand_env_save(pat);
+#ifdef BACKSLASH_IN_FILENAME
+ p_ssl = p_ssl_save;
+#endif
+ if (envpat != NULL)
+ pat = envpat;
+ }
+
+ /*
+ * Check for "nested" flag.
+ */
+ cmd = skipwhite(cmd);
+ if (*cmd != NUL && STRNCMP(cmd, "nested", 6) == 0 && vim_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;
+ }
+
+ /*
+ * Print header when showing autocommands.
+ */
+ if (!forceit && *cmd == NUL) {
+ /* Highlight title */
+ MSG_PUTS_TITLE(_("\n--- Auto-Commands ---"));
+ }
+
+ /*
+ * 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)
+ break;
+ } else {
+ while (*arg && !vim_iswhite(*arg))
+ if (do_autocmd_event(event_name2nr(arg, &arg), pat,
+ nested, cmd, forceit, group) == FAIL)
+ break;
+ }
+
+ if (need_free)
+ vim_free(cmd);
+ vim_free(envpat);
+}
+
+/*
+ * Find the group ID in a ":autocmd" or ":doautocmd" argument.
+ * The "argp" argument is advanced to the following argument.
+ *
+ * Returns the group ID, AUGROUP_ERROR for error (out of memory).
+ */
+static int au_get_grouparg(argp)
+char_u **argp;
+{
+ char_u *group_name;
+ char_u *p;
+ char_u *arg = *argp;
+ int group = AUGROUP_ALL;
+
+ p = skiptowhite(arg);
+ if (p > arg) {
+ group_name = vim_strnsave(arg, (int)(p - arg));
+ if (group_name == NULL) /* out of memory */
+ return AUGROUP_ERROR;
+ group = au_find_group(group_name);
+ if (group == AUGROUP_ERROR)
+ group = AUGROUP_ALL; /* no match, use all groups */
+ else
+ *argp = skipwhite(p); /* match, skip over group name */
+ vim_free(group_name);
+ }
+ return group;
+}
+
+/*
+ * do_autocmd() for one event.
+ * If *pat == NUL do for all patterns.
+ * If *cmd == NUL show entries.
+ * If forceit == TRUE delete entries.
+ * If group is not AUGROUP_ALL, only use this group.
+ */
+static int do_autocmd_event(event, pat, nested, cmd, forceit, group)
+event_T event;
+char_u *pat;
+int nested;
+char_u *cmd;
+int forceit;
+int group;
+{
+ AutoPat *ap;
+ AutoPat **prev_ap;
+ AutoCmd *ac;
+ AutoCmd **prev_ac;
+ int brace_level;
+ char_u *endpat;
+ int findgroup;
+ int allgroups;
+ int patlen;
+ int is_buflocal;
+ int buflocal_nr;
+ char_u buflocal_pat[25]; /* for "<buffer=X>" */
+
+ if (group == AUGROUP_ALL)
+ findgroup = current_augroup;
+ else
+ findgroup = group;
+ allgroups = (group == AUGROUP_ALL && !forceit && *cmd == NUL);
+
+ /*
+ * Show or delete all patterns for an event.
+ */
+ if (*pat == NUL) {
+ for (ap = first_autopat[(int)event]; ap != NULL; ap = ap->next) {
+ if (forceit) { /* delete the AutoPat, if it's in the current group */
+ if (ap->group == findgroup)
+ au_remove_pat(ap);
+ } else if (group == AUGROUP_ALL || ap->group == group)
+ show_autocmd(ap, event);
+ }
+ }
+
+ /*
+ * Loop through all the specified patterns.
+ */
+ for (; *pat; pat = (*endpat == ',' ? endpat + 1 : endpat)) {
+ /*
+ * Find end of the pattern.
+ * Watch out for a comma in braces, like "*.\{obj,o\}".
+ */
+ brace_level = 0;
+ for (endpat = pat; *endpat && (*endpat != ',' || brace_level
+ || endpat[-1] == '\\'); ++endpat) {
+ if (*endpat == '{')
+ brace_level++;
+ else if (*endpat == '}')
+ brace_level--;
+ }
+ if (pat == endpat) /* ignore single comma */
+ continue;
+ patlen = (int)(endpat - pat);
+
+ /*
+ * detect special <buflocal[=X]> buffer-local patterns
+ */
+ is_buflocal = FALSE;
+ buflocal_nr = 0;
+
+ if (patlen >= 7 && STRNCMP(pat, "<buffer", 7) == 0
+ && pat[patlen - 1] == '>') {
+ /* Error will be printed only for addition. printing and removing
+ * will proceed silently. */
+ is_buflocal = TRUE;
+ if (patlen == 8)
+ buflocal_nr = curbuf->b_fnum;
+ else if (patlen > 9 && pat[7] == '=') {
+ /* <buffer=abuf> */
+ if (patlen == 13 && STRNICMP(pat, "<buffer=abuf>", 13))
+ buflocal_nr = autocmd_bufnr;
+ /* <buffer=123> */
+ else if (skipdigits(pat + 8) == pat + patlen - 1)
+ buflocal_nr = atoi((char *)pat + 8);
+ }
+ }
+
+ if (is_buflocal) {
+ /* normalize pat into standard "<buffer>#N" form */
+ sprintf((char *)buflocal_pat, "<buffer=%d>", buflocal_nr);
+ pat = buflocal_pat; /* can modify pat and patlen */
+ patlen = (int)STRLEN(buflocal_pat); /* but not endpat */
+ }
+
+ /*
+ * Find AutoPat entries with this pattern.
+ */
+ prev_ap = &first_autopat[(int)event];
+ while ((ap = *prev_ap) != NULL) {
+ if (ap->pat != NULL) {
+ /* Accept a pattern when:
+ * - a group was specified and it's that group, or a group was
+ * not specified and it's the current group, or a group was
+ * not specified and we are listing
+ * - the length of the pattern matches
+ * - the pattern matches.
+ * For <buffer[=X]>, this condition works because we normalize
+ * all buffer-local patterns.
+ */
+ if ((allgroups || ap->group == findgroup)
+ && ap->patlen == patlen
+ && STRNCMP(pat, ap->pat, patlen) == 0) {
+ /*
+ * Remove existing autocommands.
+ * If adding any new autocmd's for this AutoPat, don't
+ * delete the pattern from the autopat list, append to
+ * this list.
+ */
+ if (forceit) {
+ if (*cmd != NUL && ap->next == NULL) {
+ au_remove_cmds(ap);
+ break;
+ }
+ au_remove_pat(ap);
+ }
+ /*
+ * Show autocmd's for this autopat, or buflocals <buffer=X>
+ */
+ else if (*cmd == NUL)
+ show_autocmd(ap, event);
+
+ /*
+ * Add autocmd to this autopat, if it's the last one.
+ */
+ else if (ap->next == NULL)
+ break;
+ }
+ }
+ prev_ap = &ap->next;
+ }
+
+ /*
+ * Add a new command.
+ */
+ if (*cmd != NUL) {
+ /*
+ * If the pattern we want to add a command to does appear at the
+ * end of the list (or not is not in the list at all), add the
+ * pattern at the end of the list.
+ */
+ if (ap == NULL) {
+ /* 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);
+ return FAIL;
+ }
+
+ ap = (AutoPat *)alloc((unsigned)sizeof(AutoPat));
+ if (ap == NULL)
+ return FAIL;
+ ap->pat = vim_strnsave(pat, patlen);
+ ap->patlen = patlen;
+ if (ap->pat == NULL) {
+ vim_free(ap);
+ return FAIL;
+ }
+
+ if (is_buflocal) {
+ ap->buflocal_nr = buflocal_nr;
+ ap->reg_prog = NULL;
+ } else {
+ char_u *reg_pat;
+
+ ap->buflocal_nr = 0;
+ reg_pat = file_pat_to_reg_pat(pat, endpat,
+ &ap->allow_dirs, TRUE);
+ if (reg_pat != NULL)
+ ap->reg_prog = vim_regcomp(reg_pat, RE_MAGIC);
+ vim_free(reg_pat);
+ if (reg_pat == NULL || ap->reg_prog == NULL) {
+ vim_free(ap->pat);
+ vim_free(ap);
+ return FAIL;
+ }
+ }
+ ap->cmds = NULL;
+ *prev_ap = ap;
+ ap->next = NULL;
+ if (group == AUGROUP_ALL)
+ ap->group = current_augroup;
+ else
+ ap->group = group;
+ }
+
+ /*
+ * Add the autocmd at the end of the AutoCmd list.
+ */
+ prev_ac = &(ap->cmds);
+ while ((ac = *prev_ac) != NULL)
+ prev_ac = &ac->next;
+ ac = (AutoCmd *)alloc((unsigned)sizeof(AutoCmd));
+ if (ac == NULL)
+ return FAIL;
+ ac->cmd = vim_strsave(cmd);
+ ac->scriptID = current_SID;
+ if (ac->cmd == NULL) {
+ vim_free(ac);
+ return FAIL;
+ }
+ ac->next = NULL;
+ *prev_ac = ac;
+ ac->nested = nested;
+ }
+ }
+
+ au_cleanup(); /* may really delete removed patterns/commands now */
+ return OK;
+}
+
+/*
+ * Implementation of ":doautocmd [group] event [fname]".
+ * Return OK for success, FAIL for failure;
+ */
+int do_doautocmd(arg, do_msg)
+char_u *arg;
+int do_msg; /* give message for no matching autocmds? */
+{
+ char_u *fname;
+ int nothing_done = TRUE;
+ int group;
+
+ /*
+ * Check for a legal group name. If not, use AUGROUP_ALL.
+ */
+ group = au_get_grouparg(&arg);
+ if (arg == NULL) /* out of memory */
+ return FAIL;
+
+ if (*arg == '*') {
+ EMSG(_("E217: Can't execute autocommands for ALL events"));
+ return FAIL;
+ }
+
+ /*
+ * Scan over the events.
+ * If we find an illegal name, return here, don't do anything.
+ */
+ fname = find_end_event(arg, group != AUGROUP_ALL);
+ if (fname == NULL)
+ return FAIL;
+
+ fname = skipwhite(fname);
+
+ /*
+ * Loop over the events.
+ */
+ while (*arg && !vim_iswhite(*arg))
+ if (apply_autocmds_group(event_name2nr(arg, &arg),
+ fname, NULL, TRUE, group, curbuf, NULL))
+ nothing_done = FALSE;
+
+ if (nothing_done && do_msg)
+ MSG(_("No matching autocommands"));
+
+ return aborting() ? FAIL : OK;
+}
+
+/*
+ * ":doautoall": execute autocommands for each loaded buffer.
+ */
+void ex_doautoall(eap)
+exarg_T *eap;
+{
+ int retval;
+ aco_save_T aco;
+ buf_T *buf;
+ char_u *arg = eap->arg;
+ int call_do_modelines = check_nomodeline(&arg);
+
+ /*
+ * This is a bit tricky: For some commands curwin->w_buffer needs to be
+ * equal to curbuf, but for some buffers there may not be a window.
+ * So we change the buffer for the current window for a moment. This
+ * gives problems when the autocommands make changes to the list of
+ * buffers or windows...
+ */
+ for (buf = firstbuf; buf != NULL; buf = buf->b_next) {
+ if (buf->b_ml.ml_mfp != NULL) {
+ /* find a window for this buffer and save some values */
+ aucmd_prepbuf(&aco, buf);
+
+ /* execute the autocommands for this buffer */
+ retval = do_doautocmd(arg, FALSE);
+
+ 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. */
+ 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))
+ break;
+ }
+ }
+
+ check_cursor(); /* just in case lines got deleted */
+}
+
+/*
+ * Check *argp for <nomodeline>. When it is present return FALSE, otherwise
+ * return TRUE and advance *argp to after it.
+ * Thus return TRUE when do_modelines() should be called.
+ */
+int check_nomodeline(argp)
+char_u **argp;
+{
+ if (STRNCMP(*argp, "<nomodeline>", 12) == 0) {
+ *argp = skipwhite(*argp + 12);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/*
+ * Prepare for executing autocommands for (hidden) buffer "buf".
+ * Search for a visible window containing the current buffer. If there isn't
+ * one then use "aucmd_win".
+ * Set "curbuf" and "curwin" to match "buf".
+ * When FEAT_AUTOCMD is not defined another version is used, see below.
+ */
+void aucmd_prepbuf(aco, buf)
+aco_save_T *aco; /* structure to save values in */
+buf_T *buf; /* new curbuf */
+{
+ win_T *win;
+ int save_ea;
+ int save_acd;
+
+ /* Find a window that is for the new buffer */
+ if (buf == curbuf) /* be quick when buf is curbuf */
+ win = curwin;
+ else
+ for (win = firstwin; win != NULL; win = win->w_next)
+ if (win->w_buffer == buf)
+ break;
+
+ /* Allocate "aucmd_win" when needed. If this fails (out of memory) fall
+ * back to using the current window. */
+ if (win == NULL && aucmd_win == NULL) {
+ win_alloc_aucmd_win();
+ if (aucmd_win == NULL)
+ win = curwin;
+ }
+ if (win == NULL && aucmd_win_used)
+ /* Strange recursive autocommand, fall back to using the current
+ * window. Expect a few side effects... */
+ win = curwin;
+
+ aco->save_curwin = curwin;
+ aco->save_curbuf = curbuf;
+ if (win != NULL) {
+ /* There is a window for "buf" in the current tab page, make it the
+ * curwin. This is preferred, it has the least side effects (esp. if
+ * "buf" is curbuf). */
+ aco->use_aucmd_win = FALSE;
+ curwin = win;
+ } else {
+ /* There is no window for "buf", use "aucmd_win". To minimize the side
+ * effects, insert it in the current tab page.
+ * Anything related to a window (e.g., setting folds) may have
+ * unexpected results. */
+ aco->use_aucmd_win = TRUE;
+ aucmd_win_used = TRUE;
+ aucmd_win->w_buffer = buf;
+ aucmd_win->w_s = &buf->b_s;
+ ++buf->b_nwindows;
+ win_init_empty(aucmd_win); /* set cursor and topline to safe values */
+
+ /* Make sure w_localdir and globaldir are NULL to avoid a chdir() in
+ * win_enter_ext(). */
+ vim_free(aucmd_win->w_localdir);
+ aucmd_win->w_localdir = NULL;
+ aco->globaldir = globaldir;
+ globaldir = NULL;
+
+
+ /* Split the current window, put the aucmd_win in the upper half.
+ * We don't want the BufEnter or WinEnter autocommands. */
+ block_autocmds();
+ make_snapshot(SNAP_AUCMD_IDX);
+ save_ea = p_ea;
+ p_ea = FALSE;
+
+ /* Prevent chdir() call in win_enter_ext(), through do_autochdir(). */
+ save_acd = p_acd;
+ p_acd = FALSE;
+
+ (void)win_split_ins(0, WSP_TOP, aucmd_win, 0);
+ (void)win_comp_pos(); /* recompute window positions */
+ p_ea = save_ea;
+ p_acd = save_acd;
+ unblock_autocmds();
+ curwin = aucmd_win;
+ }
+ curbuf = buf;
+ aco->new_curwin = curwin;
+ aco->new_curbuf = curbuf;
+}
+
+/*
+ * Cleanup after executing autocommands for a (hidden) buffer.
+ * Restore the window as it was (if possible).
+ * When FEAT_AUTOCMD is not defined another version is used, see below.
+ */
+void aucmd_restbuf(aco)
+aco_save_T *aco; /* structure holding saved values */
+{
+ 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. */
+ block_autocmds();
+ if (curwin != aucmd_win) {
+ tabpage_T *tp;
+ win_T *wp;
+
+ FOR_ALL_TAB_WINDOWS(tp, wp)
+ {
+ if (wp == aucmd_win) {
+ if (tp != curtab)
+ goto_tabpage_tp(tp, TRUE, TRUE);
+ win_goto(aucmd_win);
+ goto win_found;
+ }
+ }
+ }
+win_found:
+
+ /* 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 */
+ unblock_autocmds();
+
+ if (win_valid(aco->save_curwin))
+ curwin = aco->save_curwin;
+ 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 */
+ curbuf = curwin->w_buffer;
+
+ vim_free(globaldir);
+ globaldir = aco->globaldir;
+
+ /* 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 */
+ 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. */
+ 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;
+ curwin->w_buffer = curbuf;
+ ++curbuf->b_nwindows;
+ }
+
+ curwin = aco->save_curwin;
+ curbuf = curwin->w_buffer;
+ }
+ }
+}
+
+static int autocmd_nested = FALSE;
+
+/*
+ * Execute autocommands for "event" and file name "fname".
+ * Return TRUE if some commands were executed.
+ */
+int apply_autocmds(event, fname, fname_io, force, buf)
+event_T event;
+char_u *fname; /* NULL or empty means use actual file name */
+char_u *fname_io; /* fname to use for <afile> on cmdline */
+int force; /* when TRUE, ignore autocmd_busy */
+buf_T *buf; /* buffer for <abuf> */
+{
+ return apply_autocmds_group(event, fname, fname_io, force,
+ AUGROUP_ALL, buf, NULL);
+}
+
+/*
+ * Like apply_autocmds(), but with extra "eap" argument. This takes care of
+ * setting v:filearg.
+ */
+static int apply_autocmds_exarg(event, fname, fname_io, force, buf, eap)
+event_T event;
+char_u *fname;
+char_u *fname_io;
+int force;
+buf_T *buf;
+exarg_T *eap;
+{
+ return apply_autocmds_group(event, fname, fname_io, force,
+ AUGROUP_ALL, buf, eap);
+}
+
+/*
+ * Like apply_autocmds(), but handles the caller's retval. If the script
+ * processing is being aborted or if retval is FAIL when inside a try
+ * conditional, no autocommands are executed. If otherwise the autocommands
+ * cause the script to be aborted, retval is set to FAIL.
+ */
+int apply_autocmds_retval(event, fname, fname_io, force, buf, retval)
+event_T event;
+char_u *fname; /* NULL or empty means use actual file name */
+char_u *fname_io; /* fname to use for <afile> on cmdline */
+int force; /* when TRUE, ignore autocmd_busy */
+buf_T *buf; /* buffer for <abuf> */
+int *retval; /* pointer to caller's retval */
+{
+ int did_cmd;
+
+ if (should_abort(*retval))
+ return FALSE;
+
+ did_cmd = apply_autocmds_group(event, fname, fname_io, force,
+ AUGROUP_ALL, buf, NULL);
+ if (did_cmd
+ && aborting()
+ )
+ *retval = FAIL;
+ return did_cmd;
+}
+
+/*
+ * Return TRUE when there is a CursorHold autocommand defined.
+ */
+int has_cursorhold() {
+ return first_autopat[(int)(get_real_state() == NORMAL_BUSY
+ ? EVENT_CURSORHOLD : EVENT_CURSORHOLDI)] != NULL;
+}
+
+/*
+ * Return TRUE if the CursorHold event can be triggered.
+ */
+int trigger_cursorhold() {
+ int state;
+
+ if (!did_cursorhold
+ && has_cursorhold()
+ && !Recording
+ && typebuf.tb_len == 0
+ && !ins_compl_active()
+ ) {
+ state = get_real_state();
+ if (state == NORMAL_BUSY || (state & INSERT) != 0)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*
+ * Return TRUE when there is a CursorMoved autocommand defined.
+ */
+int has_cursormoved() {
+ return first_autopat[(int)EVENT_CURSORMOVED] != NULL;
+}
+
+/*
+ * Return TRUE when there is a CursorMovedI autocommand defined.
+ */
+int has_cursormovedI() {
+ return first_autopat[(int)EVENT_CURSORMOVEDI] != NULL;
+}
+
+/*
+ * Return TRUE when there is a TextChanged autocommand defined.
+ */
+int has_textchanged() {
+ return first_autopat[(int)EVENT_TEXTCHANGED] != NULL;
+}
+
+/*
+ * Return TRUE when there is a TextChangedI autocommand defined.
+ */
+int has_textchangedI() {
+ return first_autopat[(int)EVENT_TEXTCHANGEDI] != NULL;
+}
+
+/*
+ * Return TRUE when there is an InsertCharPre autocommand defined.
+ */
+int has_insertcharpre() {
+ return first_autopat[(int)EVENT_INSERTCHARPRE] != NULL;
+}
+
+static int apply_autocmds_group(event, fname, fname_io, force, group, buf, eap)
+event_T event;
+char_u *fname; /* NULL or empty means use actual file name */
+char_u *fname_io; /* fname to use for <afile> on cmdline, NULL means
+ use fname */
+int force; /* when TRUE, ignore autocmd_busy */
+int group; /* group ID, or AUGROUP_ALL */
+buf_T *buf; /* buffer for <abuf> */
+exarg_T *eap; /* command arguments */
+{
+ char_u *sfname = NULL; /* short file name */
+ char_u *tail;
+ int save_changed;
+ buf_T *old_curbuf;
+ int retval = FALSE;
+ 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;
+ int save_autocmd_nested;
+ static int nesting = 0;
+ AutoPatCmd patcmd;
+ AutoPat *ap;
+ scid_T save_current_SID;
+ void *save_funccalp;
+ char_u *save_cmdarg;
+ long save_cmdbang;
+ static int filechangeshell_busy = FALSE;
+ proftime_T wait_time;
+
+ /*
+ * Quickly return if there are no autocommands for this event or
+ * autocommands are blocked.
+ */
+ if (first_autopat[(int)event] == NULL || autocmd_blocked > 0)
+ goto BYPASS_AU;
+
+ /*
+ * When autocommands are busy, new autocommands are only executed when
+ * explicitly enabled with the "nested" flag.
+ */
+ if (autocmd_busy && !(force || autocmd_nested))
+ goto BYPASS_AU;
+
+ /*
+ * Quickly return when immediately aborting on error, or when an interrupt
+ * occurred or an exception was thrown but not caught.
+ */
+ if (aborting())
+ goto BYPASS_AU;
+
+ /*
+ * FileChangedShell never nests, because it can create an endless loop.
+ */
+ if (filechangeshell_busy && (event == EVENT_FILECHANGEDSHELL
+ || event == EVENT_FILECHANGEDSHELLPOST))
+ goto BYPASS_AU;
+
+ /*
+ * Ignore events in 'eventignore'.
+ */
+ if (event_ignored(event))
+ goto BYPASS_AU;
+
+ /*
+ * Allow nesting of autocommands, but restrict the depth, because it's
+ * possible to create an endless loop.
+ */
+ if (nesting == 10) {
+ EMSG(_("E218: autocommand nesting too deep"));
+ goto BYPASS_AU;
+ }
+
+ /*
+ * Check if these autocommands are disabled. Used when doing ":all" or
+ * ":ball".
+ */
+ if ( (autocmd_no_enter
+ && (event == EVENT_WINENTER || event == EVENT_BUFENTER))
+ || (autocmd_no_leave
+ && (event == EVENT_WINLEAVE || event == EVENT_BUFLEAVE)))
+ goto BYPASS_AU;
+
+ /*
+ * 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;
+ save_autocmd_nested = autocmd_nested;
+ save_changed = curbuf->b_changed;
+ old_curbuf = curbuf;
+
+ /*
+ * Set the file name to be used for <afile>.
+ * Make a copy to avoid that changing a buffer name or directory makes it
+ * invalid.
+ */
+ if (fname_io == NULL) {
+ if (event == EVENT_COLORSCHEME)
+ autocmd_fname = NULL;
+ else if (fname != NULL && *fname != NUL)
+ autocmd_fname = fname;
+ else if (buf != NULL)
+ autocmd_fname = buf->b_ffname;
+ else
+ autocmd_fname = NULL;
+ } else
+ autocmd_fname = fname_io;
+ if (autocmd_fname != NULL)
+ autocmd_fname = vim_strsave(autocmd_fname);
+ autocmd_fname_full = FALSE; /* call FullName_save() later */
+
+ /*
+ * Set the buffer number to be used for <abuf>.
+ */
+ if (buf == NULL)
+ autocmd_bufnr = 0;
+ else
+ autocmd_bufnr = buf->b_fnum;
+
+ /*
+ * When the file name is NULL or empty, use the file name of buffer "buf".
+ * Always use the full path of the file name to match with, in case
+ * "allow_dirs" is set.
+ */
+ if (fname == NULL || *fname == NUL) {
+ if (buf == NULL)
+ fname = NULL;
+ else {
+ if (event == EVENT_SYNTAX)
+ fname = buf->b_p_syn;
+ else if (event == EVENT_FILETYPE)
+ fname = buf->b_p_ft;
+ else {
+ if (buf->b_sfname != NULL)
+ sfname = vim_strsave(buf->b_sfname);
+ fname = buf->b_ffname;
+ }
+ }
+ if (fname == NULL)
+ fname = (char_u *)"";
+ fname = vim_strsave(fname); /* make a copy, so we can change it */
+ } else {
+ sfname = vim_strsave(fname);
+ /* Don't try expanding FileType, Syntax, FuncUndefined, WindowID,
+ * ColorScheme or QuickFixCmd* */
+ if (event == EVENT_FILETYPE
+ || event == EVENT_SYNTAX
+ || event == EVENT_FUNCUNDEFINED
+ || event == EVENT_REMOTEREPLY
+ || event == EVENT_SPELLFILEMISSING
+ || event == EVENT_QUICKFIXCMDPRE
+ || event == EVENT_COLORSCHEME
+ || event == EVENT_QUICKFIXCMDPOST)
+ fname = vim_strsave(fname);
+ else
+ fname = FullName_save(fname, FALSE);
+ }
+ if (fname == NULL) { /* out of memory */
+ vim_free(sfname);
+ retval = FALSE;
+ goto BYPASS_AU;
+ }
+
+#ifdef BACKSLASH_IN_FILENAME
+ /*
+ * Replace all backslashes with forward slashes. This makes the
+ * autocommand patterns portable between Unix and MS-DOS.
+ */
+ if (sfname != NULL)
+ forward_slash(sfname);
+ forward_slash(fname);
+#endif
+
+
+ /*
+ * Set the name to be used for <amatch>.
+ */
+ autocmd_match = fname;
+
+
+ /* Don't redraw while doing auto commands. */
+ ++RedrawingDisabled;
+ save_sourcing_name = sourcing_name;
+ sourcing_name = NULL; /* don't free this one */
+ save_sourcing_lnum = sourcing_lnum;
+ sourcing_lnum = 0; /* no line number here */
+
+ save_current_SID = current_SID;
+
+ if (do_profiling == PROF_YES)
+ prof_child_enter(&wait_time); /* doesn't count for the caller itself */
+
+ /* Don't use local function variables, if called from a function */
+ save_funccalp = save_funccal();
+
+ /*
+ * When starting to execute autocommands, save the search patterns.
+ */
+ if (!autocmd_busy) {
+ save_search_patterns();
+ saveRedobuff();
+ did_filetype = keep_filetype;
+ }
+
+ /*
+ * Note that we are applying autocmds. Some commands need to know.
+ */
+ autocmd_busy = TRUE;
+ filechangeshell_busy = (event == EVENT_FILECHANGEDSHELL);
+ ++nesting; /* see matching decrement below */
+
+ /* Remember that FileType was triggered. Used for did_filetype(). */
+ if (event == EVENT_FILETYPE)
+ did_filetype = TRUE;
+
+ tail = gettail(fname);
+
+ /* Find first autocommand that matches */
+ patcmd.curpat = first_autopat[(int)event];
+ patcmd.nextcmd = NULL;
+ patcmd.group = group;
+ patcmd.fname = fname;
+ patcmd.sfname = sfname;
+ patcmd.tail = tail;
+ patcmd.event = event;
+ patcmd.arg_bufnr = autocmd_bufnr;
+ patcmd.next = NULL;
+ auto_next_pat(&patcmd, FALSE);
+
+ /* found one, start executing the autocommands */
+ if (patcmd.curpat != NULL) {
+ /* add to active_apc_list */
+ 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);
+ if (eap != NULL) {
+ save_cmdarg = set_cmdarg(eap, NULL);
+ set_vim_var_nr(VV_CMDBANG, (long)eap->forceit);
+ } else
+ save_cmdarg = NULL; /* avoid gcc warning */
+ retval = TRUE;
+ /* mark the last pattern, to avoid an endless loop when more patterns
+ * are added when executing autocommands */
+ for (ap = patcmd.curpat; ap->next != NULL; ap = ap->next)
+ ap->last = FALSE;
+ ap->last = TRUE;
+ check_lnums(TRUE); /* make sure cursor and topline are valid */
+ do_cmdline(NULL, getnextac, (void *)&patcmd,
+ DOCMD_NOWAIT|DOCMD_VERBOSE|DOCMD_REPEAT);
+ if (eap != NULL) {
+ (void)set_cmdarg(NULL, save_cmdarg);
+ set_vim_var_nr(VV_CMDBANG, save_cmdbang);
+ }
+ /* delete from active_apc_list */
+ if (active_apc_list == &patcmd) /* just in case */
+ active_apc_list = patcmd.next;
+ }
+
+ --RedrawingDisabled;
+ autocmd_busy = save_autocmd_busy;
+ filechangeshell_busy = FALSE;
+ autocmd_nested = save_autocmd_nested;
+ vim_free(sourcing_name);
+ sourcing_name = save_sourcing_name;
+ sourcing_lnum = save_sourcing_lnum;
+ vim_free(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);
+ vim_free(fname);
+ vim_free(sfname);
+ --nesting; /* see matching increment above */
+
+ /*
+ * When stopping to execute autocommands, restore the search patterns and
+ * the redo buffer.
+ */
+ if (!autocmd_busy) {
+ restore_search_patterns();
+ restoreRedobuff();
+ did_filetype = FALSE;
+ }
+
+ /*
+ * Some events don't set or reset the Changed flag.
+ * Check if still in the same buffer!
+ */
+ if (curbuf == old_curbuf
+ && (event == EVENT_BUFREADPOST
+ || event == EVENT_BUFWRITEPOST
+ || event == EVENT_FILEAPPENDPOST
+ || event == EVENT_VIMLEAVE
+ || event == EVENT_VIMLEAVEPRE)) {
+ if (curbuf->b_changed != save_changed)
+ need_maketitle = TRUE;
+ curbuf->b_changed = save_changed;
+ }
+
+ au_cleanup(); /* may really delete removed patterns/commands now */
+
+BYPASS_AU:
+ /* When wiping out a buffer make sure all its buffer-local autocommands
+ * are deleted. */
+ if (event == EVENT_BUFWIPEOUT && buf != NULL)
+ aubuflocal_remove(buf);
+
+ return retval;
+}
+
+static char_u *old_termresponse = NULL;
+
+/*
+ * Block triggering autocommands until unblock_autocmd() is called.
+ * Can be used recursively, so long as it's symmetric.
+ */
+void block_autocmds() {
+ /* Remember the value of v:termresponse. */
+ if (autocmd_blocked == 0)
+ old_termresponse = get_vim_var_str(VV_TERMRESPONSE);
+ ++autocmd_blocked;
+}
+
+void unblock_autocmds() {
+ --autocmd_blocked;
+
+ /* When v:termresponse was set while autocommands were blocked, trigger
+ * the autocommands now. Esp. useful when executing a shell command
+ * during startup (vimdiff). */
+ if (autocmd_blocked == 0
+ && get_vim_var_str(VV_TERMRESPONSE) != old_termresponse)
+ apply_autocmds(EVENT_TERMRESPONSE, NULL, NULL, FALSE, curbuf);
+}
+
+int is_autocmd_blocked() {
+ return autocmd_blocked != 0;
+}
+
+/*
+ * Find next autocommand pattern that matches.
+ */
+static void auto_next_pat(apc, stop_at_last)
+AutoPatCmd *apc;
+int stop_at_last; /* stop when 'last' flag is set */
+{
+ AutoPat *ap;
+ AutoCmd *cp;
+ char_u *name;
+ char *s;
+
+ vim_free(sourcing_name);
+ sourcing_name = NULL;
+
+ for (ap = apc->curpat; ap != NULL && !got_int; ap = ap->next) {
+ apc->curpat = NULL;
+
+ /* Only use a pattern when it has not been removed, has commands and
+ * the group matches. For buffer-local autocommands only check the
+ * buffer number. */
+ if (ap->pat != NULL && ap->cmds != NULL
+ && (apc->group == AUGROUP_ALL || apc->group == ap->group)) {
+ /* execution-condition */
+ if (ap->buflocal_nr == 0
+ ? (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 = alloc((unsigned)(STRLEN(s)
+ + STRLEN(name) + ap->patlen + 1));
+ if (sourcing_name != NULL) {
+ sprintf((char *)sourcing_name, s,
+ (char *)name, (char *)ap->pat);
+ if (p_verbose >= 8) {
+ verbose_enter();
+ smsg((char_u *)_("Executing %s"), sourcing_name);
+ verbose_leave();
+ }
+ }
+
+ apc->curpat = ap;
+ apc->nextcmd = ap->cmds;
+ /* mark last command */
+ for (cp = ap->cmds; cp->next != NULL; cp = cp->next)
+ cp->last = FALSE;
+ cp->last = TRUE;
+ }
+ line_breakcheck();
+ if (apc->curpat != NULL) /* found a match */
+ break;
+ }
+ if (stop_at_last && ap->last)
+ break;
+ }
+}
+
+/*
+ * Get next autocommand command.
+ * Called by do_cmdline() to get the next line for ":if".
+ * Returns allocated string, or NULL for end of autocommands.
+ */
+char_u * getnextac(c, cookie, indent)
+int c UNUSED;
+void *cookie;
+int indent UNUSED;
+{
+ AutoPatCmd *acp = (AutoPatCmd *)cookie;
+ char_u *retval;
+ AutoCmd *ac;
+
+ /* Can be called again after returning the last line. */
+ if (acp->curpat == NULL)
+ return NULL;
+
+ /* repeat until we find an autocommand to execute */
+ for (;; ) {
+ /* skip removed commands */
+ while (acp->nextcmd != NULL && acp->nextcmd->cmd == NULL)
+ if (acp->nextcmd->last)
+ acp->nextcmd = NULL;
+ else
+ acp->nextcmd = acp->nextcmd->next;
+
+ if (acp->nextcmd != NULL)
+ break;
+
+ /* at end of commands, find next pattern that matches */
+ if (acp->curpat->last)
+ acp->curpat = NULL;
+ else
+ acp->curpat = acp->curpat->next;
+ if (acp->curpat != NULL)
+ auto_next_pat(acp, TRUE);
+ if (acp->curpat == NULL)
+ return NULL;
+ }
+
+ ac = acp->nextcmd;
+
+ if (p_verbose >= 9) {
+ verbose_enter_scroll();
+ smsg((char_u *)_("autocommand %s"), ac->cmd);
+ msg_puts((char_u *)"\n"); /* don't overwrite this either */
+ verbose_leave_scroll();
+ }
+ retval = vim_strsave(ac->cmd);
+ autocmd_nested = ac->nested;
+ current_SID = ac->scriptID;
+ if (ac->last)
+ acp->nextcmd = NULL;
+ else
+ acp->nextcmd = ac->next;
+ return retval;
+}
+
+/*
+ * Return TRUE if there is a matching autocommand for "fname".
+ * To account for buffer-local autocommands, function needs to know
+ * in which buffer the file will be opened.
+ */
+int has_autocmd(event, sfname, buf)
+event_T event;
+char_u *sfname;
+buf_T *buf;
+{
+ AutoPat *ap;
+ char_u *fname;
+ char_u *tail = gettail(sfname);
+ int retval = FALSE;
+
+ fname = FullName_save(sfname, FALSE);
+ if (fname == NULL)
+ return FALSE;
+
+#ifdef BACKSLASH_IN_FILENAME
+ /*
+ * Replace all backslashes with forward slashes. This makes the
+ * autocommand patterns portable between Unix and MS-DOS.
+ */
+ sfname = vim_strsave(sfname);
+ if (sfname != NULL)
+ forward_slash(sfname);
+ forward_slash(fname);
+#endif
+
+ for (ap = first_autopat[(int)event]; ap != NULL; ap = ap->next)
+ if (ap->pat != NULL && ap->cmds != NULL
+ && (ap->buflocal_nr == 0
+ ? match_file_pat(NULL, ap->reg_prog,
+ fname, sfname, tail, ap->allow_dirs)
+ : buf != NULL && ap->buflocal_nr == buf->b_fnum
+ )) {
+ retval = TRUE;
+ break;
+ }
+
+ vim_free(fname);
+#ifdef BACKSLASH_IN_FILENAME
+ vim_free(sfname);
+#endif
+
+ return retval;
+}
+
+/*
+ * Function given to ExpandGeneric() to obtain the list of autocommand group
+ * names.
+ */
+char_u * get_augroup_name(xp, idx)
+expand_T *xp UNUSED;
+int idx;
+{
+ if (idx == augroups.ga_len) /* add "END" add the end */
+ return (char_u *)"END";
+ if (idx >= augroups.ga_len) /* end of list */
+ return NULL;
+ if (AUGROUP_NAME(idx) == NULL) /* skip deleted entries */
+ return (char_u *)"";
+ return AUGROUP_NAME(idx); /* return a name */
+}
+
+static int include_groups = FALSE;
+
+char_u * set_context_in_autocmd(xp, arg, doautocmd)
+expand_T *xp;
+char_u *arg;
+int doautocmd; /* TRUE for :doauto*, FALSE for :autocmd */
+{
+ char_u *p;
+ int group;
+
+ /* check for a group name, skip it if present */
+ include_groups = FALSE;
+ p = arg;
+ group = au_get_grouparg(&arg);
+ if (group == AUGROUP_ERROR)
+ return NULL;
+ /* If there only is a group name that's what we expand. */
+ if (*arg == NUL && group != AUGROUP_ALL && !vim_iswhite(arg[-1])) {
+ arg = p;
+ group = AUGROUP_ALL;
+ }
+
+ /* skip over event name */
+ for (p = arg; *p != NUL && !vim_iswhite(*p); ++p)
+ if (*p == ',')
+ arg = p + 1;
+ if (*p == NUL) {
+ if (group == AUGROUP_ALL)
+ include_groups = TRUE;
+ xp->xp_context = EXPAND_EVENTS; /* expand event name */
+ xp->xp_pattern = arg;
+ return NULL;
+ }
+
+ /* skip over pattern */
+ arg = skipwhite(p);
+ while (*arg && (!vim_iswhite(*arg) || arg[-1] == '\\'))
+ arg++;
+ if (*arg)
+ return arg; /* expand (next) command */
+
+ if (doautocmd)
+ xp->xp_context = EXPAND_FILES; /* expand file names */
+ else
+ xp->xp_context = EXPAND_NOTHING; /* pattern is not expanded */
+ return NULL;
+}
+
+/*
+ * Function given to ExpandGeneric() to obtain the list of event names.
+ */
+char_u * get_event_name(xp, idx)
+expand_T *xp UNUSED;
+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 */
+ }
+ return (char_u *)event_names[idx - augroups.ga_len].name;
+}
+
+
+/*
+ * Return TRUE if autocmd is supported.
+ */
+int autocmd_supported(name)
+char_u *name;
+{
+ char_u *p;
+
+ return event_name2nr(name, &p) != NUM_EVENTS;
+}
+
+/*
+ * Return TRUE if an autocommand is defined for a group, event and
+ * pattern: The group can be omitted to accept any group. "event" and "pattern"
+ * can be NULL to accept any event and pattern. "pattern" can be NULL to accept
+ * any pattern. Buffer-local patterns <buffer> or <buffer=N> are accepted.
+ * Used for:
+ * exists("#Group") or
+ * exists("#Group#Event") or
+ * exists("#Group#Event#pat") or
+ * exists("#Event") or
+ * exists("#Event#pat")
+ */
+int au_exists(arg)
+char_u *arg;
+{
+ 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;
+ int retval = FALSE;
+
+ /* Make a copy so that we can change the '#' chars to a NUL. */
+ arg_save = vim_strsave(arg);
+ if (arg_save == NULL)
+ return FALSE;
+ p = vim_strchr(arg_save, '#');
+ if (p != NULL)
+ *p++ = NUL;
+
+ /* First, look for an autocmd group name */
+ group = au_find_group(arg_save);
+ if (group == AUGROUP_ERROR) {
+ /* Didn't match a group name, assume the first argument is an event. */
+ group = AUGROUP_ALL;
+ event_name = arg_save;
+ } else {
+ if (p == NULL) {
+ /* "Group": group name is present and it's recognized */
+ retval = TRUE;
+ goto theend;
+ }
+
+ /* Must be "Group#Event" or "Group#Event#pat". */
+ event_name = p;
+ p = vim_strchr(event_name, '#');
+ if (p != NULL)
+ *p++ = NUL; /* "Group#Event#pat" */
+ }
+
+ pattern = p; /* "pattern" is NULL when there is no pattern */
+
+ /* find the index (enum) for the event name */
+ event = event_name2nr(event_name, &p);
+
+ /* return FALSE if the event name is not recognized */
+ if (event == NUM_EVENTS)
+ goto theend;
+
+ /* Find the first autocommand for this event.
+ * If there isn't any, return FALSE;
+ * If there is one and no pattern given, return TRUE; */
+ ap = first_autopat[(int)event];
+ if (ap == NULL)
+ goto theend;
+
+ /* if pattern is "<buffer>", special handling is needed which uses curbuf */
+ /* for pattern "<buffer=N>, fnamecmp() will work fine */
+ if (pattern != NULL && STRICMP(pattern, "<buffer>") == 0)
+ buflocal_buf = curbuf;
+
+ /* Check if there is an autocommand with the given pattern. */
+ for (; ap != NULL; ap = ap->next)
+ /* only use a pattern when it has not been removed and has commands. */
+ /* For buffer-local autocommands, fnamecmp() works fine. */
+ if (ap->pat != NULL && ap->cmds != NULL
+ && (group == AUGROUP_ALL || ap->group == group)
+ && (pattern == NULL
+ || (buflocal_buf == NULL
+ ? fnamecmp(ap->pat, pattern) == 0
+ : ap->buflocal_nr == buflocal_buf->b_fnum))) {
+ retval = TRUE;
+ break;
+ }
+
+theend:
+ vim_free(arg_save);
+ return retval;
+}
+
+
+
+/*
+ * Try matching a filename with a "pattern" ("prog" is NULL), or use the
+ * precompiled regprog "prog" ("pattern" is NULL). That avoids calling
+ * vim_regcomp() often.
+ * Used for autocommands and 'wildignore'.
+ * Returns TRUE if there is a match, FALSE otherwise.
+ */
+int match_file_pat(pattern, prog, fname, sfname, tail, allow_dirs)
+char_u *pattern; /* pattern to match with */
+regprog_T *prog; /* pre-compiled regprog or NULL */
+char_u *fname; /* full path of file name */
+char_u *sfname; /* short file name or NULL */
+char_u *tail; /* tail of path */
+int allow_dirs; /* allow matching with dir */
+{
+ regmatch_T regmatch;
+ int result = FALSE;
+#ifdef FEAT_OSFILETYPE
+ int no_pattern = FALSE; /* TRUE if check is filetype only */
+ char_u *type_start;
+ char_u c;
+ int match = FALSE;
+#endif
+
+ regmatch.rm_ic = p_fic; /* ignore case if 'fileignorecase' is set */
+#ifdef FEAT_OSFILETYPE
+ if (*pattern == '<') {
+ /* There is a filetype condition specified with this pattern.
+ * Check the filetype matches first. If not, don't bother with the
+ * pattern (set regprog to NULL).
+ * Always use magic for the regexp.
+ */
+
+ for (type_start = pattern + 1; (c = *pattern); pattern++) {
+ if ((c == ';' || c == '>') && match == FALSE) {
+ *pattern = NUL; /* Terminate the string */
+ /* TODO: match with 'filetype' of buffer that "fname" comes
+ * from. */
+ match = mch_check_filetype(fname, type_start);
+ *pattern = c; /* Restore the terminator */
+ type_start = pattern + 1;
+ }
+ if (c == '>')
+ break;
+ }
+
+ /* (c should never be NUL, but check anyway) */
+ if (match == FALSE || c == NUL)
+ regmatch.regprog = NULL; /* Doesn't match - don't check pat. */
+ else if (*pattern == NUL) {
+ regmatch.regprog = NULL; /* Vim will try to free regprog later */
+ no_pattern = TRUE; /* Always matches - don't check pat. */
+ } else
+ regmatch.regprog = vim_regcomp(pattern + 1, RE_MAGIC);
+ } else
+#endif
+ {
+ if (prog != NULL)
+ regmatch.regprog = prog;
+ else
+ regmatch.regprog = vim_regcomp(pattern, RE_MAGIC);
+ }
+
+ /*
+ * Try for a match with the pattern with:
+ * 1. the full file name, when the pattern has a '/'.
+ * 2. the short file name, when the pattern has a '/'.
+ * 3. the tail of the file name, when the pattern has no '/'.
+ */
+ if (
+#ifdef FEAT_OSFILETYPE
+ /* If the check is for a filetype only and we don't care
+ * about the path then skip all the regexp stuff.
+ */
+ no_pattern ||
+#endif
+ (regmatch.regprog != NULL
+ && ((allow_dirs
+ && (vim_regexec(&regmatch, fname, (colnr_T)0)
+ || (sfname != NULL
+ && vim_regexec(&regmatch, sfname, (colnr_T)0))))
+ || (!allow_dirs && vim_regexec(&regmatch, tail, (colnr_T)0)))))
+ result = TRUE;
+
+ if (prog == NULL)
+ vim_regfree(regmatch.regprog);
+ return result;
+}
+
+/*
+ * Return TRUE if a file matches with a pattern in "list".
+ * "list" is a comma-separated list of patterns, like 'wildignore'.
+ * "sfname" is the short file name or NULL, "ffname" the long file name.
+ */
+int match_file_list(list, sfname, ffname)
+char_u *list;
+char_u *sfname;
+char_u *ffname;
+{
+ char_u buf[100];
+ char_u *tail;
+ char_u *regpat;
+ char allow_dirs;
+ int match;
+ char_u *p;
+
+ tail = gettail(sfname);
+
+ /* try all patterns in 'wildignore' */
+ p = list;
+ while (*p) {
+ copy_option_part(&p, buf, 100, ",");
+ regpat = file_pat_to_reg_pat(buf, NULL, &allow_dirs, FALSE);
+ if (regpat == NULL)
+ break;
+ match = match_file_pat(regpat, NULL, ffname, sfname,
+ tail, (int)allow_dirs);
+ vim_free(regpat);
+ if (match)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*
+ * Convert the given pattern "pat" which has shell style wildcards in it, into
+ * a regular expression, and return the result in allocated memory. If there
+ * is a directory path separator to be matched, then TRUE is put in
+ * allow_dirs, otherwise FALSE is put there -- webb.
+ * Handle backslashes before special characters, like "\*" and "\ ".
+ *
+ * If FEAT_OSFILETYPE defined then pass initial <type> through unchanged. Eg:
+ * '<html>myfile' becomes '<html>^myfile$' -- leonard.
+ *
+ * Returns NULL when out of memory.
+ */
+char_u * file_pat_to_reg_pat(pat, pat_end, allow_dirs, no_bslash)
+char_u *pat;
+char_u *pat_end; /* first char after pattern or NULL */
+char *allow_dirs; /* Result passed back out in here */
+int no_bslash UNUSED; /* Don't use a backward slash as pathsep */
+{
+ int size;
+ char_u *endp;
+ char_u *reg_pat;
+ char_u *p;
+ int i;
+ int nested = 0;
+ int add_dollar = TRUE;
+#ifdef FEAT_OSFILETYPE
+ int check_length = 0;
+#endif
+
+ if (allow_dirs != NULL)
+ *allow_dirs = FALSE;
+ if (pat_end == NULL)
+ pat_end = pat + STRLEN(pat);
+
+#ifdef FEAT_OSFILETYPE
+ /* Find out how much of the string is the filetype check */
+ if (*pat == '<') {
+ /* Count chars until the next '>' */
+ for (p = pat + 1; p < pat_end && *p != '>'; p++)
+ ;
+ if (p < pat_end) {
+ /* Pattern is of the form <.*>.* */
+ check_length = p - pat + 1;
+ if (p + 1 >= pat_end) {
+ /* The 'pattern' is a filetype check ONLY */
+ reg_pat = (char_u *)alloc(check_length + 1);
+ if (reg_pat != NULL) {
+ mch_memmove(reg_pat, pat, (size_t)check_length);
+ reg_pat[check_length] = NUL;
+ }
+ return reg_pat;
+ }
+ }
+ /* else: there was no closing '>' - assume it was a normal pattern */
+
+ }
+ pat += check_length;
+ size = 2 + check_length;
+#else
+ size = 2; /* '^' at start, '$' at end */
+#endif
+
+ for (p = pat; p < pat_end; p++) {
+ switch (*p) {
+ case '*':
+ case '.':
+ case ',':
+ case '{':
+ case '}':
+ case '~':
+ size += 2; /* extra backslash */
+ break;
+#ifdef BACKSLASH_IN_FILENAME
+ case '\\':
+ case '/':
+ size += 4; /* could become "[\/]" */
+ break;
+#endif
+ default:
+ size++;
+ if (enc_dbcs != 0 && (*mb_ptr2len)(p) > 1) {
+ ++p;
+ ++size;
+ }
+ break;
+ }
+ }
+ reg_pat = alloc(size + 1);
+ if (reg_pat == NULL)
+ return NULL;
+
+#ifdef FEAT_OSFILETYPE
+ /* Copy the type check in to the start. */
+ if (check_length)
+ mch_memmove(reg_pat, pat - check_length, (size_t)check_length);
+ i = check_length;
+#else
+ i = 0;
+#endif
+
+ if (pat[0] == '*')
+ while (pat[0] == '*' && pat < pat_end - 1)
+ pat++;
+ else
+ reg_pat[i++] = '^';
+ endp = pat_end - 1;
+ if (*endp == '*') {
+ while (endp - pat > 0 && *endp == '*')
+ endp--;
+ add_dollar = FALSE;
+ }
+ for (p = pat; *p && nested >= 0 && p <= endp; p++) {
+ switch (*p) {
+ case '*':
+ reg_pat[i++] = '.';
+ reg_pat[i++] = '*';
+ while (p[1] == '*') /* "**" matches like "*" */
+ ++p;
+ break;
+ case '.':
+ case '~':
+ reg_pat[i++] = '\\';
+ reg_pat[i++] = *p;
+ break;
+ case '?':
+ reg_pat[i++] = '.';
+ break;
+ case '\\':
+ if (p[1] == NUL)
+ break;
+#ifdef BACKSLASH_IN_FILENAME
+ if (!no_bslash) {
+ /* translate:
+ * "\x" to "\\x" e.g., "dir\file"
+ * "\*" to "\\.*" e.g., "dir\*.c"
+ * "\?" to "\\." e.g., "dir\??.c"
+ * "\+" to "\+" e.g., "fileX\+.c"
+ */
+ if ((vim_isfilec(p[1]) || p[1] == '*' || p[1] == '?')
+ && p[1] != '+') {
+ reg_pat[i++] = '[';
+ reg_pat[i++] = '\\';
+ reg_pat[i++] = '/';
+ reg_pat[i++] = ']';
+ if (allow_dirs != NULL)
+ *allow_dirs = TRUE;
+ break;
+ }
+ }
+#endif
+ /* Undo escaping from ExpandEscape():
+ * foo\?bar -> foo?bar
+ * foo\%bar -> foo%bar
+ * foo\,bar -> foo,bar
+ * foo\ bar -> foo bar
+ * Don't unescape \, * and others that are also special in a
+ * regexp.
+ * An escaped { must be unescaped since we use magic not
+ * verymagic. Use "\\\{n,m\}"" to get "\{n,m}".
+ */
+ if (*++p == '?'
+#ifdef BACKSLASH_IN_FILENAME
+ && no_bslash
+#endif
+ )
+ reg_pat[i++] = '?';
+ else if (*p == ',' || *p == '%' || *p == '#'
+ || *p == ' ' || *p == '{' || *p == '}')
+ reg_pat[i++] = *p;
+ else if (*p == '\\' && p[1] == '\\' && p[2] == '{') {
+ reg_pat[i++] = '\\';
+ reg_pat[i++] = '{';
+ p += 2;
+ } else {
+ if (allow_dirs != NULL && vim_ispathsep(*p)
+#ifdef BACKSLASH_IN_FILENAME
+ && (!no_bslash || *p != '\\')
+#endif
+ )
+ *allow_dirs = TRUE;
+ reg_pat[i++] = '\\';
+ reg_pat[i++] = *p;
+ }
+ break;
+#ifdef BACKSLASH_IN_FILENAME
+ case '/':
+ reg_pat[i++] = '[';
+ reg_pat[i++] = '\\';
+ reg_pat[i++] = '/';
+ reg_pat[i++] = ']';
+ if (allow_dirs != NULL)
+ *allow_dirs = TRUE;
+ break;
+#endif
+ case '{':
+ reg_pat[i++] = '\\';
+ reg_pat[i++] = '(';
+ nested++;
+ break;
+ case '}':
+ reg_pat[i++] = '\\';
+ reg_pat[i++] = ')';
+ --nested;
+ break;
+ case ',':
+ if (nested) {
+ reg_pat[i++] = '\\';
+ reg_pat[i++] = '|';
+ } else
+ reg_pat[i++] = ',';
+ break;
+ default:
+ if (enc_dbcs != 0 && (*mb_ptr2len)(p) > 1)
+ reg_pat[i++] = *p++;
+ else if (allow_dirs != NULL && vim_ispathsep(*p))
+ *allow_dirs = TRUE;
+ reg_pat[i++] = *p;
+ break;
+ }
+ }
+ if (add_dollar)
+ reg_pat[i++] = '$';
+ reg_pat[i] = NUL;
+ if (nested != 0) {
+ if (nested < 0)
+ EMSG(_("E219: Missing {."));
+ else
+ EMSG(_("E220: Missing }."));
+ vim_free(reg_pat);
+ reg_pat = NULL;
+ }
+ return reg_pat;
+}
+
+#if defined(EINTR) || defined(PROTO)
+/*
+ * Version of read() that retries when interrupted by EINTR (possibly
+ * by a SIGWINCH).
+ */
+long read_eintr(fd, buf, bufsize)
+int fd;
+void *buf;
+size_t bufsize;
+{
+ long ret;
+
+ for (;; ) {
+ ret = vim_read(fd, buf, bufsize);
+ if (ret >= 0 || errno != EINTR)
+ break;
+ }
+ return ret;
+}
+
+/*
+ * Version of write() that retries when interrupted by EINTR (possibly
+ * by a SIGWINCH).
+ */
+long write_eintr(fd, buf, bufsize)
+int fd;
+void *buf;
+size_t bufsize;
+{
+ long ret = 0;
+ long wlen;
+
+ /* Repeat the write() so long it didn't fail, other than being interrupted
+ * by a signal. */
+ while (ret < (long)bufsize) {
+ wlen = vim_write(fd, (char *)buf + ret, bufsize - ret);
+ if (wlen < 0) {
+ if (errno != EINTR)
+ break;
+ } else
+ ret += wlen;
+ }
+ return ret;
+}
+#endif
diff --git a/src/fold.c b/src/fold.c
new file mode 100644
index 0000000000..b3a3d84a2b
--- /dev/null
+++ b/src/fold.c
@@ -0,0 +1,3104 @@
+/* vim:set ts=8 sts=4 sw=4:
+ * vim600:fdm=marker fdl=1 fdc=3:
+ *
+ * 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.
+ */
+
+/*
+ * fold.c: code for folding
+ */
+
+#include "vim.h"
+
+
+/* local declarations. {{{1 */
+/* typedef fold_T {{{2 */
+/*
+ * The toplevel folds for each window are stored in the w_folds growarray.
+ * Each toplevel fold can contain an array of second level folds in the
+ * fd_nested growarray.
+ * 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 */
+} fold_T;
+
+#define FD_OPEN 0 /* fold is open (nested ones can be closed) */
+#define FD_CLOSED 1 /* fold is closed */
+#define FD_LEVEL 2 /* depends on 'foldlevel' (nested folds too) */
+
+#define MAX_LEVEL 20 /* maximum fold depth */
+
+/* static functions {{{2 */
+static void newFoldLevelWin __ARGS((win_T *wp));
+static int checkCloseRec __ARGS((garray_T *gap, linenr_T lnum, int level));
+static int foldFind __ARGS((garray_T *gap, linenr_T lnum, fold_T **fpp));
+static int foldLevelWin __ARGS((win_T *wp, linenr_T lnum));
+static void checkupdate __ARGS((win_T *wp));
+static void setFoldRepeat __ARGS((linenr_T lnum, long count, int do_open));
+static linenr_T setManualFold __ARGS((linenr_T lnum, int opening, int recurse,
+ int *donep));
+static linenr_T setManualFoldWin __ARGS((win_T *wp, linenr_T lnum, int opening,
+ int recurse,
+ int *donep));
+static void foldOpenNested __ARGS((fold_T *fpr));
+static void deleteFoldEntry __ARGS((garray_T *gap, int idx, int recursive));
+static void foldMarkAdjustRecurse __ARGS((garray_T *gap, linenr_T line1,
+ linenr_T line2, long amount,
+ long amount_after));
+static int getDeepestNestingRecurse __ARGS((garray_T *gap));
+static int check_closed __ARGS((win_T *win, fold_T *fp, int *use_levelp,
+ int level, int *maybe_smallp,
+ linenr_T lnum_off));
+static void checkSmall __ARGS((win_T *wp, fold_T *fp, linenr_T lnum_off));
+static void setSmallMaybe __ARGS((garray_T *gap));
+static void foldCreateMarkers __ARGS((linenr_T start, linenr_T end));
+static void foldAddMarker __ARGS((linenr_T lnum, char_u *marker, int markerlen));
+static void deleteFoldMarkers __ARGS((fold_T *fp, int recursive,
+ linenr_T lnum_off));
+static void foldDelMarker __ARGS((linenr_T lnum, char_u *marker, int markerlen));
+static void foldUpdateIEMS __ARGS((win_T *wp, linenr_T top, linenr_T bot));
+static void parseMarker __ARGS((win_T *wp));
+
+static char *e_nofold = N_("E490: No fold found");
+
+/*
+ * While updating the folds lines between invalid_top and invalid_bot have an
+ * undefined fold level. Only used for the window currently being updated.
+ */
+static linenr_T invalid_top = (linenr_T)0;
+static linenr_T invalid_bot = (linenr_T)0;
+
+/*
+ * When using 'foldexpr' we sometimes get the level of the next line, which
+ * calls foldlevel() to get the level of the current line, which hasn't been
+ * stored yet. To get around this chicken-egg problem the level of the
+ * previous line is stored here when available. prev_lnum is zero when the
+ * level is not available.
+ */
+static linenr_T prev_lnum = 0;
+static int prev_lnum_lvl = -1;
+
+/* Flags used for "done" argument of setManualFold. */
+#define DONE_NOTHING 0
+#define DONE_ACTION 1 /* did close or open a fold */
+#define DONE_FOLD 2 /* did find a fold */
+
+static int foldstartmarkerlen;
+static char_u *foldendmarker;
+static int foldendmarkerlen;
+
+/* Exported folding functions. {{{1 */
+/* copyFoldingState() {{{2 */
+/*
+ * Copy that folding state from window "wp_from" to window "wp_to".
+ */
+void copyFoldingState(wp_from, wp_to)
+win_T *wp_from;
+win_T *wp_to;
+{
+ wp_to->w_fold_manual = wp_from->w_fold_manual;
+ wp_to->w_foldinvalid = wp_from->w_foldinvalid;
+ cloneFoldGrowArray(&wp_from->w_folds, &wp_to->w_folds);
+}
+
+/* hasAnyFolding() {{{2 */
+/*
+ * Return TRUE if there may be folded lines in the current window.
+ */
+int hasAnyFolding(win)
+win_T *win;
+{
+ /* very simple now, but can become more complex later */
+ return win->w_p_fen
+ && (!foldmethodIsManual(win) || win->w_folds.ga_len > 0);
+}
+
+/* hasFolding() {{{2 */
+/*
+ * Return TRUE if line "lnum" in the current window is part of a closed
+ * fold.
+ * When returning TRUE, *firstp and *lastp are set to the first and last
+ * lnum of the sequence of folded lines (skipped when NULL).
+ */
+int hasFolding(lnum, firstp, lastp)
+linenr_T lnum;
+linenr_T *firstp;
+linenr_T *lastp;
+{
+ return hasFoldingWin(curwin, lnum, firstp, lastp, TRUE, NULL);
+}
+
+/* hasFoldingWin() {{{2 */
+int hasFoldingWin(win, lnum, firstp, lastp, cache, infop)
+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 */
+{
+ int 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;;
+
+ checkupdate(win);
+ /*
+ * Return quickly when there is no folding at all in this window.
+ */
+ if (!hasAnyFolding(win)) {
+ if (infop != NULL)
+ infop->fi_level = 0;
+ return FALSE;
+ }
+
+ if (cache) {
+ /*
+ * 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);
+ if (x >= 0) {
+ first = win->w_lines[x].wl_lnum;
+ last = win->w_lines[x].wl_lastlnum;
+ had_folded = win->w_lines[x].wl_folded;
+ }
+ }
+
+ if (first == 0) {
+ /*
+ * Recursively search for a fold that contains "lnum".
+ */
+ gap = &win->w_folds;
+ for (;; ) {
+ if (!foldFind(gap, lnum_rel, &fp))
+ break;
+
+ /* Remember lowest level of fold that starts in "lnum". */
+ if (lnum_rel == fp->fd_top && low_level == 0)
+ low_level = level + 1;
+
+ first += fp->fd_top;
+ last += fp->fd_top;
+
+ /* is this fold closed? */
+ had_folded = check_closed(win, fp, &use_level, level,
+ &maybe_small, lnum - lnum_rel);
+ if (had_folded) {
+ /* Fold closed: Set last and quit loop. */
+ last += fp->fd_len - 1;
+ break;
+ }
+
+ /* Fold found, but it's open: Check nested folds. Line number is
+ * relative to containing fold. */
+ gap = &fp->fd_nested;
+ lnum_rel -= fp->fd_top;
+ ++level;
+ }
+ }
+
+ if (!had_folded) {
+ if (infop != NULL) {
+ infop->fi_level = level;
+ infop->fi_lnum = lnum - lnum_rel;
+ infop->fi_low_level = low_level == 0 ? level : low_level;
+ }
+ return FALSE;
+ }
+
+ if (lastp != NULL)
+ *lastp = last;
+ if (firstp != NULL)
+ *firstp = first;
+ if (infop != NULL) {
+ infop->fi_level = level + 1;
+ infop->fi_lnum = first;
+ infop->fi_low_level = low_level == 0 ? level + 1 : low_level;
+ }
+ return TRUE;
+}
+
+/* foldLevel() {{{2 */
+/*
+ * Return fold level at line number "lnum" in the current window.
+ */
+int foldLevel(lnum)
+linenr_T lnum;
+{
+ /* While updating the folds lines between invalid_top and invalid_bot have
+ * an undefined fold level. Otherwise update the folds first. */
+ if (invalid_top == (linenr_T)0)
+ checkupdate(curwin);
+ else if (lnum == prev_lnum && prev_lnum_lvl >= 0)
+ return prev_lnum_lvl;
+ else if (lnum >= invalid_top && lnum <= invalid_bot)
+ return -1;
+
+ /* Return quickly when there is no folding at all in this window. */
+ if (!hasAnyFolding(curwin))
+ return 0;
+
+ 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, lnum)
+win_T *win;
+linenr_T lnum;
+{
+ return foldedCount(win, lnum, NULL) != 0;
+}
+
+/* foldedCount() {{{2 */
+/*
+ * Count the number of lines that are folded at line number "lnum".
+ * Normally "lnum" is the first line of a possible fold, and the returned
+ * number is the number of lines in the fold.
+ * Doesn't use caching from the displayed window.
+ * Returns number of folded lines from "lnum", or 0 if line is not folded.
+ * When "infop" is not NULL, fills *infop with the fold level info.
+ */
+long foldedCount(win, lnum, infop)
+win_T *win;
+linenr_T lnum;
+foldinfo_T *infop;
+{
+ linenr_T last;
+
+ if (hasFoldingWin(win, lnum, NULL, &last, FALSE, infop))
+ return (long)(last - lnum + 1);
+ return 0;
+}
+
+/* foldmethodIsManual() {{{2 */
+/*
+ * Return TRUE if 'foldmethod' is "manual"
+ */
+int foldmethodIsManual(wp)
+win_T *wp;
+{
+ return wp->w_p_fdm[3] == 'u';
+}
+
+/* foldmethodIsIndent() {{{2 */
+/*
+ * Return TRUE if 'foldmethod' is "indent"
+ */
+int foldmethodIsIndent(wp)
+win_T *wp;
+{
+ return wp->w_p_fdm[0] == 'i';
+}
+
+/* foldmethodIsExpr() {{{2 */
+/*
+ * Return TRUE if 'foldmethod' is "expr"
+ */
+int foldmethodIsExpr(wp)
+win_T *wp;
+{
+ return wp->w_p_fdm[1] == 'x';
+}
+
+/* foldmethodIsMarker() {{{2 */
+/*
+ * Return TRUE if 'foldmethod' is "marker"
+ */
+int foldmethodIsMarker(wp)
+win_T *wp;
+{
+ return wp->w_p_fdm[2] == 'r';
+}
+
+/* foldmethodIsSyntax() {{{2 */
+/*
+ * Return TRUE if 'foldmethod' is "syntax"
+ */
+int foldmethodIsSyntax(wp)
+win_T *wp;
+{
+ return wp->w_p_fdm[0] == 's';
+}
+
+/* foldmethodIsDiff() {{{2 */
+/*
+ * Return TRUE if 'foldmethod' is "diff"
+ */
+int foldmethodIsDiff(wp)
+win_T *wp;
+{
+ return wp->w_p_fdm[0] == 'd';
+}
+
+/* closeFold() {{{2 */
+/*
+ * Close fold for current window at line "lnum".
+ * Repeat "count" times.
+ */
+void closeFold(lnum, count)
+linenr_T lnum;
+long count;
+{
+ setFoldRepeat(lnum, count, FALSE);
+}
+
+/* closeFoldRecurse() {{{2 */
+/*
+ * Close fold for current window at line "lnum" recursively.
+ */
+void closeFoldRecurse(lnum)
+linenr_T lnum;
+{
+ (void)setManualFold(lnum, FALSE, TRUE, NULL);
+}
+
+/* opFoldRange() {{{2 */
+/*
+ * Open or Close folds for current window in lines "first" to "last".
+ * Used for "zo", "zO", "zc" and "zC" in Visual mode.
+ */
+void opFoldRange(first, last, opening, recurse, had_visual)
+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 done = DONE_NOTHING; /* avoid error messages */
+ linenr_T lnum;
+ linenr_T lnum_next;
+
+ for (lnum = first; lnum <= last; lnum = lnum_next + 1) {
+ lnum_next = lnum;
+ /* Opening one level only: next fold to open is after the one going to
+ * be opened. */
+ if (opening && !recurse)
+ (void)hasFolding(lnum, NULL, &lnum_next);
+ (void)setManualFold(lnum, opening, recurse, &done);
+ /* Closing one level only: next line to close a fold is after just
+ * closed fold. */
+ if (!opening && !recurse)
+ (void)hasFolding(lnum, NULL, &lnum_next);
+ }
+ if (done == DONE_NOTHING)
+ EMSG(_(e_nofold));
+ /* Force a redraw to remove the Visual highlighting. */
+ if (had_visual)
+ redraw_curbuf_later(INVERTED);
+}
+
+/* openFold() {{{2 */
+/*
+ * Open fold for current window at line "lnum".
+ * Repeat "count" times.
+ */
+void openFold(lnum, count)
+linenr_T lnum;
+long count;
+{
+ setFoldRepeat(lnum, count, TRUE);
+}
+
+/* openFoldRecurse() {{{2 */
+/*
+ * Open fold for current window at line "lnum" recursively.
+ */
+void openFoldRecurse(lnum)
+linenr_T lnum;
+{
+ (void)setManualFold(lnum, TRUE, TRUE, NULL);
+}
+
+/* foldOpenCursor() {{{2 */
+/*
+ * Open folds until the cursor line is not in a closed fold.
+ */
+void foldOpenCursor() {
+ int done;
+
+ checkupdate(curwin);
+ if (hasAnyFolding(curwin))
+ for (;; ) {
+ done = DONE_NOTHING;
+ (void)setManualFold(curwin->w_cursor.lnum, TRUE, FALSE, &done);
+ if (!(done & DONE_ACTION))
+ break;
+ }
+}
+
+/* newFoldLevel() {{{2 */
+/*
+ * Set new foldlevel for current window.
+ */
+void newFoldLevel() {
+ newFoldLevelWin(curwin);
+
+ if (foldmethodIsDiff(curwin) && curwin->w_p_scb) {
+ win_T *wp;
+
+ /*
+ * Set the same foldlevel in other windows in diff mode.
+ */
+ FOR_ALL_WINDOWS(wp)
+ {
+ if (wp != curwin && foldmethodIsDiff(wp) && wp->w_p_scb) {
+ wp->w_p_fdl = curwin->w_p_fdl;
+ newFoldLevelWin(wp);
+ }
+ }
+ }
+}
+
+static void newFoldLevelWin(wp)
+win_T *wp;
+{
+ fold_T *fp;
+ int i;
+
+ checkupdate(wp);
+ if (wp->w_fold_manual) {
+ /* Set all flags for the first level of folds to FD_LEVEL. Following
+ * manual open/close will then change the flags to FD_OPEN or
+ * FD_CLOSED for those folds that don't use 'foldlevel'. */
+ fp = (fold_T *)wp->w_folds.ga_data;
+ for (i = 0; i < wp->w_folds.ga_len; ++i)
+ fp[i].fd_flags = FD_LEVEL;
+ wp->w_fold_manual = FALSE;
+ }
+ changed_window_setting_win(wp);
+}
+
+/* foldCheckClose() {{{2 */
+/*
+ * Apply 'foldlevel' to all folds that don't contain the cursor.
+ */
+void foldCheckClose() {
+ if (*p_fcl != NUL) { /* can only be "all" right now */
+ checkupdate(curwin);
+ if (checkCloseRec(&curwin->w_folds, curwin->w_cursor.lnum,
+ (int)curwin->w_p_fdl))
+ changed_window_setting();
+ }
+}
+
+/* checkCloseRec() {{{2 */
+static int checkCloseRec(gap, lnum, level)
+garray_T *gap;
+linenr_T lnum;
+int level;
+{
+ fold_T *fp;
+ int retval = FALSE;
+ int i;
+
+ fp = (fold_T *)gap->ga_data;
+ for (i = 0; i < gap->ga_len; ++i) {
+ /* Only manually opened folds may need to be closed. */
+ if (fp[i].fd_flags == FD_OPEN) {
+ if (level <= 0 && (lnum < fp[i].fd_top
+ || lnum >= fp[i].fd_top + fp[i].fd_len)) {
+ fp[i].fd_flags = FD_LEVEL;
+ retval = TRUE;
+ } else
+ retval |= checkCloseRec(&fp[i].fd_nested, lnum - fp[i].fd_top,
+ level - 1);
+ }
+ }
+ return retval;
+}
+
+/* foldCreateAllowed() {{{2 */
+/*
+ * Return TRUE if it's allowed to manually create or delete a fold.
+ * Give an error message and return FALSE if not.
+ */
+int foldManualAllowed(create)
+int create;
+{
+ if (foldmethodIsManual(curwin) || foldmethodIsMarker(curwin))
+ return TRUE;
+ if (create)
+ EMSG(_("E350: Cannot create fold with current 'foldmethod'"));
+ else
+ EMSG(_("E351: Cannot delete fold with current 'foldmethod'"));
+ return FALSE;
+}
+
+/* foldCreate() {{{2 */
+/*
+ * Create a fold from line "start" to line "end" (inclusive) in the current
+ * window.
+ */
+void foldCreate(start, end)
+linenr_T start;
+linenr_T end;
+{
+ fold_T *fp;
+ garray_T *gap;
+ garray_T fold_ga;
+ int i, j;
+ int cont;
+ int use_level = FALSE;
+ int closed = FALSE;
+ int level = 0;
+ linenr_T start_rel = start;
+ linenr_T end_rel = end;
+
+ if (start > end) {
+ /* reverse the range */
+ end = start_rel;
+ start = end_rel;
+ start_rel = start;
+ end_rel = end;
+ }
+
+ /* When 'foldmethod' is "marker" add markers, which creates the folds. */
+ if (foldmethodIsMarker(curwin)) {
+ foldCreateMarkers(start, end);
+ return;
+ }
+
+ checkupdate(curwin);
+
+ /* Find the place to insert the new fold. */
+ gap = &curwin->w_folds;
+ for (;; ) {
+ if (!foldFind(gap, start_rel, &fp))
+ break;
+ if (fp->fd_top + fp->fd_len > end_rel) {
+ /* New fold is completely inside this fold: Go one level deeper. */
+ gap = &fp->fd_nested;
+ start_rel -= fp->fd_top;
+ end_rel -= fp->fd_top;
+ if (use_level || fp->fd_flags == FD_LEVEL) {
+ use_level = TRUE;
+ if (level >= curwin->w_p_fdl)
+ closed = TRUE;
+ } else if (fp->fd_flags == FD_CLOSED)
+ closed = TRUE;
+ ++level;
+ } else {
+ /* This fold and new fold overlap: Insert here and move some folds
+ * inside the new fold. */
+ break;
+ }
+ }
+
+ i = (int)(fp - (fold_T *)gap->ga_data);
+ if (ga_grow(gap, 1) == OK) {
+ fp = (fold_T *)gap->ga_data + i;
+ ga_init2(&fold_ga, (int)sizeof(fold_T), 10);
+
+ /* Count number of folds that will be contained in the new fold. */
+ for (cont = 0; i + cont < gap->ga_len; ++cont)
+ if (fp[cont].fd_top > end_rel)
+ break;
+ if (cont > 0 && ga_grow(&fold_ga, cont) == OK) {
+ /* If the first fold starts before the new fold, let the new fold
+ * start there. Otherwise the existing fold would change. */
+ if (start_rel > fp->fd_top)
+ start_rel = fp->fd_top;
+
+ /* When last contained fold isn't completely contained, adjust end
+ * of new fold. */
+ if (end_rel < fp[cont - 1].fd_top + fp[cont - 1].fd_len - 1)
+ end_rel = fp[cont - 1].fd_top + fp[cont - 1].fd_len - 1;
+ /* Move contained folds to inside new fold. */
+ mch_memmove(fold_ga.ga_data, fp, sizeof(fold_T) * cont);
+ fold_ga.ga_len += cont;
+ i += cont;
+
+ /* Adjust line numbers in contained folds to be relative to the
+ * new fold. */
+ for (j = 0; j < cont; ++j)
+ ((fold_T *)fold_ga.ga_data)[j].fd_top -= start_rel;
+ }
+ /* Move remaining entries to after the new fold. */
+ if (i < gap->ga_len)
+ mch_memmove(fp + 1, (fold_T *)gap->ga_data + i,
+ sizeof(fold_T) * (gap->ga_len - i));
+ gap->ga_len = gap->ga_len + 1 - cont;
+
+ /* insert new fold */
+ fp->fd_nested = fold_ga;
+ fp->fd_top = start_rel;
+ fp->fd_len = end_rel - start_rel + 1;
+
+ /* We want the new fold to be closed. If it would remain open because
+ * of using 'foldlevel', need to adjust fd_flags of containing folds.
+ */
+ if (use_level && !closed && level < curwin->w_p_fdl)
+ closeFold(start, 1L);
+ if (!use_level)
+ curwin->w_fold_manual = TRUE;
+ fp->fd_flags = FD_CLOSED;
+ fp->fd_small = MAYBE;
+
+ /* redraw */
+ changed_window_setting();
+ }
+}
+
+/* deleteFold() {{{2 */
+/*
+ * Delete a fold at line "start" in the current window.
+ * When "end" is not 0, delete all folds from "start" to "end".
+ * When "recursive" is TRUE delete recursively.
+ */
+void deleteFold(start, end, recursive, had_visual)
+linenr_T start;
+linenr_T end;
+int recursive;
+int 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;
+ int level = 0;
+ linenr_T lnum = start;
+ linenr_T lnum_off;
+ int 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;
+ for (;; ) {
+ if (!foldFind(gap, lnum - lnum_off, &fp))
+ break;
+ /* lnum is inside this fold, remember info */
+ found_ga = gap;
+ found_fp = fp;
+ found_off = lnum_off;
+
+ /* if "lnum" is folded, don't check nesting */
+ if (check_closed(curwin, fp, &use_level, level,
+ &maybe_small, lnum_off))
+ break;
+
+ /* check nested folds */
+ gap = &fp->fd_nested;
+ lnum_off += fp->fd_top;
+ ++level;
+ }
+ if (found_ga == NULL) {
+ ++lnum;
+ } else {
+ lnum = found_fp->fd_top + found_fp->fd_len + found_off;
+
+ if (foldmethodIsManual(curwin))
+ deleteFoldEntry(found_ga,
+ (int)(found_fp - (fold_T *)found_ga->ga_data), recursive);
+ else {
+ if (first_lnum > found_fp->fd_top + found_off)
+ first_lnum = found_fp->fd_top + found_off;
+ if (last_lnum < lnum)
+ last_lnum = lnum;
+ if (!did_one)
+ parseMarker(curwin);
+ deleteFoldMarkers(found_fp, recursive, found_off);
+ }
+ did_one = TRUE;
+
+ /* redraw window */
+ changed_window_setting();
+ }
+ }
+ if (!did_one) {
+ EMSG(_(e_nofold));
+ /* Force a redraw to remove the Visual highlighting. */
+ if (had_visual)
+ redraw_curbuf_later(INVERTED);
+ } else
+ /* Deleting markers may make cursor column invalid. */
+ check_cursor_col();
+
+ if (last_lnum > 0)
+ changed_lines(first_lnum, (colnr_T)0, last_lnum, 0L);
+}
+
+/* clearFolding() {{{2 */
+/*
+ * Remove all folding for window "win".
+ */
+void clearFolding(win)
+win_T *win;
+{
+ deleteFoldRecurse(&win->w_folds);
+ win->w_foldinvalid = FALSE;
+}
+
+/* foldUpdate() {{{2 */
+/*
+ * Update folds for changes in the buffer of a window.
+ * Note that inserted/deleted lines must have already been taken care of by
+ * calling foldMarkAdjust().
+ * The changes in lines from top to bot (inclusive).
+ */
+void foldUpdate(wp, top, bot)
+win_T *wp;
+linenr_T top;
+linenr_T bot;
+{
+ fold_T *fp;
+
+ /* Mark all folds from top to bot as maybe-small. */
+ (void)foldFind(&curwin->w_folds, top, &fp);
+ while (fp < (fold_T *)curwin->w_folds.ga_data + curwin->w_folds.ga_len
+ && fp->fd_top < bot) {
+ fp->fd_small = MAYBE;
+ ++fp;
+ }
+
+ if (foldmethodIsIndent(wp)
+ || foldmethodIsExpr(wp)
+ || foldmethodIsMarker(wp)
+ || foldmethodIsDiff(wp)
+ || foldmethodIsSyntax(wp)) {
+ int save_got_int = got_int;
+
+ /* reset got_int here, otherwise it won't work */
+ got_int = FALSE;
+ foldUpdateIEMS(wp, top, bot);
+ got_int |= save_got_int;
+ }
+}
+
+/* foldUpdateAll() {{{2 */
+/*
+ * Update all lines in a window for folding.
+ * Used when a fold setting changes or after reloading the buffer.
+ * The actual updating is postponed until fold info is used, to avoid doing
+ * every time a setting is changed or a syntax item is added.
+ */
+void foldUpdateAll(win)
+win_T *win;
+{
+ win->w_foldinvalid = TRUE;
+ 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(updown, dir, count)
+int updown;
+int dir; /* FORWARD or BACKWARD */
+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;
+ for (;; ) {
+ if (!foldFind(gap, curwin->w_cursor.lnum - lnum_off, &fp)) {
+ if (!updown)
+ break;
+
+ /* When moving up, consider a fold above the cursor; when
+ * moving down consider a fold below the cursor. */
+ if (dir == FORWARD) {
+ if (fp - (fold_T *)gap->ga_data >= gap->ga_len)
+ break;
+ --fp;
+ } else {
+ if (fp == (fold_T *)gap->ga_data)
+ break;
+ }
+ /* don't look for contained folds, they will always move
+ * the cursor too far. */
+ last = TRUE;
+ }
+
+ if (!last) {
+ /* Check if this fold is closed. */
+ if (check_closed(curwin, fp, &use_level, level,
+ &maybe_small, lnum_off))
+ last = TRUE;
+
+ /* "[z" and "]z" stop at closed fold */
+ if (last && !updown)
+ break;
+ }
+
+ if (updown) {
+ if (dir == FORWARD) {
+ /* to start of next fold if there is one */
+ if (fp + 1 - (fold_T *)gap->ga_data < gap->ga_len) {
+ lnum = fp[1].fd_top + lnum_off;
+ if (lnum > curwin->w_cursor.lnum)
+ lnum_found = lnum;
+ }
+ } else {
+ /* to end of previous fold if there is one */
+ if (fp > (fold_T *)gap->ga_data) {
+ lnum = fp[-1].fd_top + lnum_off + fp[-1].fd_len - 1;
+ if (lnum < curwin->w_cursor.lnum)
+ lnum_found = lnum;
+ }
+ }
+ } else {
+ /* Open fold found, set cursor to its start/end and then check
+ * nested folds. */
+ if (dir == FORWARD) {
+ lnum = fp->fd_top + lnum_off + fp->fd_len - 1;
+ if (lnum > curwin->w_cursor.lnum)
+ lnum_found = lnum;
+ } else {
+ lnum = fp->fd_top + lnum_off;
+ if (lnum < curwin->w_cursor.lnum)
+ lnum_found = lnum;
+ }
+ }
+
+ if (last)
+ break;
+
+ /* Check nested folds (if any). */
+ gap = &fp->fd_nested;
+ lnum_off += fp->fd_top;
+ ++level;
+ }
+ if (lnum_found != curwin->w_cursor.lnum) {
+ if (retval == FAIL)
+ setpcmark();
+ curwin->w_cursor.lnum = lnum_found;
+ curwin->w_cursor.col = 0;
+ retval = OK;
+ } else
+ break;
+ }
+
+ return retval;
+}
+
+/* foldInitWin() {{{2 */
+/*
+ * Init the fold info in a new window.
+ */
+void foldInitWin(new_win)
+win_T *new_win;
+{
+ ga_init2(&new_win->w_folds, (int)sizeof(fold_T), 10);
+}
+
+/* find_wl_entry() {{{2 */
+/*
+ * Find an entry in the win->w_lines[] array for buffer line "lnum".
+ * Only valid entries are considered (for entries where wl_valid is FALSE the
+ * line number can be wrong).
+ * Returns index of entry or -1 if not found.
+ */
+int find_wl_entry(win, lnum)
+win_T *win;
+linenr_T lnum;
+{
+ int i;
+
+ for (i = 0; i < win->w_lines_valid; ++i)
+ if (win->w_lines[i].wl_valid) {
+ if (lnum < win->w_lines[i].wl_lnum)
+ return -1;
+ if (lnum <= win->w_lines[i].wl_lastlnum)
+ return i;
+ }
+ return -1;
+}
+
+/* foldAdjustVisual() {{{2 */
+/*
+ * Adjust the Visual area to include any fold at the start or end completely.
+ */
+void foldAdjustVisual() {
+ pos_T *start, *end;
+ char_u *ptr;
+
+ if (!VIsual_active || !hasAnyFolding(curwin))
+ return;
+
+ if (ltoreq(VIsual, curwin->w_cursor)) {
+ start = &VIsual;
+ end = &curwin->w_cursor;
+ } else {
+ start = &curwin->w_cursor;
+ end = &VIsual;
+ }
+ if (hasFolding(start->lnum, &start->lnum, NULL))
+ start->col = 0;
+ if (hasFolding(end->lnum, NULL, &end->lnum)) {
+ ptr = ml_get(end->lnum);
+ end->col = (colnr_T)STRLEN(ptr);
+ if (end->col > 0 && *p_sel == 'o')
+ --end->col;
+ /* prevent cursor from moving on the trail byte */
+ if (has_mbyte)
+ mb_adjust_cursor();
+ }
+}
+
+/* cursor_foldstart() {{{2 */
+/*
+ * Move the cursor to the first line of a closed fold.
+ */
+void foldAdjustCursor() {
+ (void)hasFolding(curwin->w_cursor.lnum, &curwin->w_cursor.lnum, NULL);
+}
+
+/* Internal functions for "fold_T" {{{1 */
+/* cloneFoldGrowArray() {{{2 */
+/*
+ * Will "clone" (i.e deep copy) a garray_T of folds.
+ *
+ * Return FAIL if the operation cannot be completed, otherwise OK.
+ */
+void cloneFoldGrowArray(from, to)
+garray_T *from;
+garray_T *to;
+{
+ int i;
+ fold_T *from_p;
+ fold_T *to_p;
+
+ ga_init2(to, from->ga_itemsize, from->ga_growsize);
+ if (from->ga_len == 0 || ga_grow(to, from->ga_len) == FAIL)
+ return;
+
+ from_p = (fold_T *)from->ga_data;
+ to_p = (fold_T *)to->ga_data;
+
+ for (i = 0; i < from->ga_len; i++) {
+ to_p->fd_top = from_p->fd_top;
+ to_p->fd_len = from_p->fd_len;
+ to_p->fd_flags = from_p->fd_flags;
+ to_p->fd_small = from_p->fd_small;
+ cloneFoldGrowArray(&from_p->fd_nested, &to_p->fd_nested);
+ ++to->ga_len;
+ ++from_p;
+ ++to_p;
+ }
+}
+
+/* foldFind() {{{2 */
+/*
+ * Search for line "lnum" in folds of growarray "gap".
+ * Set *fpp to the fold struct for the fold that contains "lnum" or
+ * the first fold below it (careful: it can be beyond the end of the array!).
+ * Returns FALSE when there is no fold that contains "lnum".
+ */
+static int foldFind(gap, lnum, fpp)
+garray_T *gap;
+linenr_T lnum;
+fold_T **fpp;
+{
+ linenr_T low, high;
+ fold_T *fp;
+ int i;
+
+ /*
+ * Perform a binary search.
+ * "low" is lowest index of possible match.
+ * "high" is highest index of possible match.
+ */
+ fp = (fold_T *)gap->ga_data;
+ low = 0;
+ high = gap->ga_len - 1;
+ while (low <= high) {
+ i = (low + high) / 2;
+ if (fp[i].fd_top > lnum)
+ /* fold below lnum, adjust high */
+ high = i - 1;
+ else if (fp[i].fd_top + fp[i].fd_len <= lnum)
+ /* fold above lnum, adjust low */
+ low = i + 1;
+ else {
+ /* lnum is inside this fold */
+ *fpp = fp + i;
+ return TRUE;
+ }
+ }
+ *fpp = fp + low;
+ return FALSE;
+}
+
+/* foldLevelWin() {{{2 */
+/*
+ * Return fold level at line number "lnum" in window "wp".
+ */
+static int foldLevelWin(wp, lnum)
+win_T *wp;
+linenr_T lnum;
+{
+ fold_T *fp;
+ linenr_T lnum_rel = lnum;
+ int level = 0;
+ garray_T *gap;
+
+ /* Recursively search for a fold that contains "lnum". */
+ gap = &wp->w_folds;
+ for (;; ) {
+ if (!foldFind(gap, lnum_rel, &fp))
+ break;
+ /* Check nested folds. Line number is relative to containing fold. */
+ gap = &fp->fd_nested;
+ lnum_rel -= fp->fd_top;
+ ++level;
+ }
+
+ return level;
+}
+
+/* checkupdate() {{{2 */
+/*
+ * Check if the folds in window "wp" are invalid and update them if needed.
+ */
+static void checkupdate(wp)
+win_T *wp;
+{
+ if (wp->w_foldinvalid) {
+ foldUpdate(wp, (linenr_T)1, (linenr_T)MAXLNUM); /* will update all */
+ wp->w_foldinvalid = FALSE;
+ }
+}
+
+/* setFoldRepeat() {{{2 */
+/*
+ * Open or close fold for current window at line "lnum".
+ * Repeat "count" times.
+ */
+static void setFoldRepeat(lnum, count, do_open)
+linenr_T lnum;
+long count;
+int do_open;
+{
+ int done;
+ long n;
+
+ for (n = 0; n < count; ++n) {
+ done = DONE_NOTHING;
+ (void)setManualFold(lnum, do_open, FALSE, &done);
+ if (!(done & DONE_ACTION)) {
+ /* Only give an error message when no fold could be opened. */
+ if (n == 0 && !(done & DONE_FOLD))
+ EMSG(_(e_nofold));
+ break;
+ }
+ }
+}
+
+/* setManualFold() {{{2 */
+/*
+ * 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(lnum, opening, recurse, donep)
+linenr_T lnum;
+int opening; /* TRUE when opening, FALSE when closing */
+int recurse; /* TRUE when closing/opening recursive */
+int *donep;
+{
+ if (foldmethodIsDiff(curwin) && curwin->w_p_scb) {
+ win_T *wp;
+ linenr_T dlnum;
+
+ /*
+ * Do the same operation in other windows in diff mode. Calculate the
+ * line number from the diffs.
+ */
+ FOR_ALL_WINDOWS(wp)
+ {
+ if (wp != curwin && foldmethodIsDiff(wp) && wp->w_p_scb) {
+ dlnum = diff_lnum_win(curwin->w_cursor.lnum, wp);
+ if (dlnum != 0)
+ (void)setManualFoldWin(wp, dlnum, opening, recurse, NULL);
+ }
+ }
+ }
+
+ return setManualFoldWin(curwin, lnum, opening, recurse, donep);
+}
+
+/* setManualFoldWin() {{{2 */
+/*
+ * Open or close the fold in window "wp" which contains "lnum".
+ * "donep", when not NULL, points to flag that is set to DONE_FOLD when some
+ * fold was found and to DONE_ACTION when some fold was opened or closed.
+ * When "donep" is NULL give an error message when no fold was found for
+ * "lnum", but only if "wp" is "curwin".
+ * Return the line number of the next line that could be closed.
+ * It's only valid when "opening" is TRUE!
+ */
+static linenr_T setManualFoldWin(wp, lnum, opening, recurse, donep)
+win_T *wp;
+linenr_T lnum;
+int opening; /* TRUE when opening, FALSE when closing */
+int recurse; /* TRUE when closing/opening recursive */
+int *donep;
+{
+ fold_T *fp;
+ fold_T *fp2;
+ fold_T *found = NULL;
+ int j;
+ int level = 0;
+ int use_level = FALSE;
+ int found_fold = FALSE;
+ garray_T *gap;
+ linenr_T next = MAXLNUM;
+ linenr_T off = 0;
+ int done = 0;
+
+ checkupdate(wp);
+
+ /*
+ * Find the fold, open or close it.
+ */
+ gap = &wp->w_folds;
+ for (;; ) {
+ if (!foldFind(gap, lnum, &fp)) {
+ /* If there is a following fold, continue there next time. */
+ if (fp < (fold_T *)gap->ga_data + gap->ga_len)
+ next = fp->fd_top + off;
+ break;
+ }
+
+ /* lnum is inside this fold */
+ found_fold = TRUE;
+
+ /* If there is a following fold, continue there next time. */
+ if (fp + 1 < (fold_T *)gap->ga_data + gap->ga_len)
+ next = fp[1].fd_top + off;
+
+ /* Change from level-dependent folding to manual. */
+ if (use_level || fp->fd_flags == FD_LEVEL) {
+ use_level = TRUE;
+ if (level >= wp->w_p_fdl)
+ fp->fd_flags = FD_CLOSED;
+ else
+ fp->fd_flags = FD_OPEN;
+ fp2 = (fold_T *)fp->fd_nested.ga_data;
+ for (j = 0; j < fp->fd_nested.ga_len; ++j)
+ fp2[j].fd_flags = FD_LEVEL;
+ }
+
+ /* Simple case: Close recursively means closing the fold. */
+ if (!opening && recurse) {
+ if (fp->fd_flags != FD_CLOSED) {
+ done |= DONE_ACTION;
+ fp->fd_flags = FD_CLOSED;
+ }
+ } else if (fp->fd_flags == FD_CLOSED) {
+ /* When opening, open topmost closed fold. */
+ if (opening) {
+ fp->fd_flags = FD_OPEN;
+ done |= DONE_ACTION;
+ if (recurse)
+ foldOpenNested(fp);
+ }
+ break;
+ }
+
+ /* fold is open, check nested folds */
+ found = fp;
+ gap = &fp->fd_nested;
+ lnum -= fp->fd_top;
+ off += fp->fd_top;
+ ++level;
+ }
+ if (found_fold) {
+ /* When closing and not recurse, close deepest open fold. */
+ if (!opening && found != NULL) {
+ found->fd_flags = FD_CLOSED;
+ done |= DONE_ACTION;
+ }
+ wp->w_fold_manual = TRUE;
+ if (done & DONE_ACTION)
+ changed_window_setting_win(wp);
+ done |= DONE_FOLD;
+ } else if (donep == NULL && wp == curwin)
+ EMSG(_(e_nofold));
+
+ if (donep != NULL)
+ *donep |= done;
+
+ return next;
+}
+
+/* foldOpenNested() {{{2 */
+/*
+ * Open all nested folds in fold "fpr" recursively.
+ */
+static void foldOpenNested(fpr)
+fold_T *fpr;
+{
+ int i;
+ fold_T *fp;
+
+ fp = (fold_T *)fpr->fd_nested.ga_data;
+ for (i = 0; i < fpr->fd_nested.ga_len; ++i) {
+ foldOpenNested(&fp[i]);
+ fp[i].fd_flags = FD_OPEN;
+ }
+}
+
+/* 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(gap, idx, recursive)
+garray_T *gap;
+int idx;
+int recursive;
+{
+ fold_T *fp;
+ int i;
+ long moved;
+ fold_T *nfp;
+
+ fp = (fold_T *)gap->ga_data + idx;
+ if (recursive || fp->fd_nested.ga_len == 0) {
+ /* recursively delete the contained folds */
+ deleteFoldRecurse(&fp->fd_nested);
+ --gap->ga_len;
+ if (idx < gap->ga_len)
+ mch_memmove(fp, fp + 1, sizeof(fold_T) * (gap->ga_len - idx));
+ } else {
+ /* Move nested folds one level up, to overwrite the fold that is
+ * deleted. */
+ moved = fp->fd_nested.ga_len;
+ if (ga_grow(gap, (int)(moved - 1)) == OK) {
+ /* 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) {
+ 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;
+ }
+
+ /* move the existing folds down to make room */
+ if (idx + 1 < gap->ga_len)
+ mch_memmove(fp + moved, fp + 1,
+ sizeof(fold_T) * (gap->ga_len - (idx + 1)));
+ /* move the contained folds one level up */
+ mch_memmove(fp, nfp, (size_t)(sizeof(fold_T) * moved));
+ vim_free(nfp);
+ gap->ga_len += moved - 1;
+ }
+ }
+}
+
+/* deleteFoldRecurse() {{{2 */
+/*
+ * Delete nested folds in a fold.
+ */
+void deleteFoldRecurse(gap)
+garray_T *gap;
+{
+ int i;
+
+ for (i = 0; i < gap->ga_len; ++i)
+ deleteFoldRecurse(&(((fold_T *)(gap->ga_data))[i].fd_nested));
+ ga_clear(gap);
+}
+
+/* foldMarkAdjust() {{{2 */
+/*
+ * Update line numbers of folds for inserted/deleted lines.
+ */
+void foldMarkAdjust(wp, line1, line2, amount, amount_after)
+win_T *wp;
+linenr_T line1;
+linenr_T line2;
+long amount;
+long amount_after;
+{
+ /* If deleting marks from line1 to line2, but not deleting all those
+ * lines, set line2 so that only deleted lines have their folds removed. */
+ if (amount == MAXLNUM && line2 >= line1 && line2 - line1 >= -amount_after)
+ line2 = line1 - amount_after - 1;
+ /* If appending a line in Insert mode, it should be included in the fold
+ * just above the line. */
+ if ((State & INSERT) && amount == (linenr_T)1 && line2 == MAXLNUM)
+ --line1;
+ foldMarkAdjustRecurse(&wp->w_folds, line1, line2, amount, amount_after);
+}
+
+/* foldMarkAdjustRecurse() {{{2 */
+static void foldMarkAdjustRecurse(gap, line1, line2, amount, amount_after)
+garray_T *gap;
+linenr_T line1;
+linenr_T line2;
+long amount;
+long amount_after;
+{
+ fold_T *fp;
+ int i;
+ linenr_T last;
+ linenr_T top;
+
+ /* In Insert mode an inserted line at the top of a fold is considered part
+ * of the fold, otherwise it isn't. */
+ if ((State & INSERT) && amount == (linenr_T)1 && line2 == MAXLNUM)
+ top = line1 + 1;
+ else
+ top = line1;
+
+ /* Find the fold containing or just below "line1". */
+ (void)foldFind(gap, line1, &fp);
+
+ /*
+ * Adjust all folds below "line1" that are affected.
+ */
+ for (i = (int)(fp - (fold_T *)gap->ga_data); i < gap->ga_len; ++i, ++fp) {
+ /*
+ * 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
+ */
+
+ last = fp->fd_top + fp->fd_len - 1; /* last line of fold */
+
+ /* 1. fold completely above line1: nothing to do */
+ if (last < line1)
+ continue;
+
+ /* 6. fold below line2: only adjust for amount_after */
+ if (fp->fd_top > line2) {
+ if (amount_after == 0)
+ break;
+ fp->fd_top += amount_after;
+ } else {
+ if (fp->fd_top >= top && last <= line2) {
+ /* 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
+ fp->fd_top += amount;
+ } else {
+ if (fp->fd_top < top) {
+ /* 2 or 3: need to correct nested folds too */
+ foldMarkAdjustRecurse(&fp->fd_nested, line1 - fp->fd_top,
+ line2 - fp->fd_top, amount, amount_after);
+ if (last <= line2) {
+ /* 2. fold contains line1, line2 is below fold */
+ if (amount == MAXLNUM)
+ fp->fd_len = line1 - fp->fd_top;
+ else
+ fp->fd_len += amount;
+ } else {
+ /* 3. fold contains line1 and line2 */
+ fp->fd_len += amount_after;
+ }
+ } 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) {
+ fp->fd_len -= line2 - fp->fd_top + 1;
+ fp->fd_top = line1;
+ } else {
+ fp->fd_len += amount_after - amount;
+ fp->fd_top += amount;
+ }
+ }
+ }
+ }
+ }
+}
+
+/* getDeepestNesting() {{{2 */
+/*
+ * Get the lowest 'foldlevel' value that makes the deepest nested fold in the
+ * current window open.
+ */
+int getDeepestNesting() {
+ checkupdate(curwin);
+ return getDeepestNestingRecurse(&curwin->w_folds);
+}
+
+static int getDeepestNestingRecurse(gap)
+garray_T *gap;
+{
+ int i;
+ int level;
+ int maxlevel = 0;
+ fold_T *fp;
+
+ fp = (fold_T *)gap->ga_data;
+ for (i = 0; i < gap->ga_len; ++i) {
+ level = getDeepestNestingRecurse(&fp[i].fd_nested) + 1;
+ if (level > maxlevel)
+ maxlevel = level;
+ }
+
+ return maxlevel;
+}
+
+/* check_closed() {{{2 */
+/*
+ * Check if a fold is closed and update the info needed to check nested folds.
+ */
+static int check_closed(win, fp, use_levelp, level, maybe_smallp, lnum_off)
+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 */
+{
+ int 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;
+ if (closed) {
+ if (*maybe_smallp)
+ fp->fd_small = MAYBE;
+ checkSmall(win, fp, lnum_off);
+ if (fp->fd_small == TRUE)
+ closed = FALSE;
+ }
+ return closed;
+}
+
+/* checkSmall() {{{2 */
+/*
+ * Update fd_small field of fold "fp".
+ */
+static void checkSmall(wp, fp, lnum_off)
+win_T *wp;
+fold_T *fp;
+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 */
+ 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) {
+ count += plines_win_nofold(wp, fp->fd_top + lnum_off + n);
+ if (count > curwin->w_p_fml) {
+ fp->fd_small = FALSE;
+ return;
+ }
+ }
+ fp->fd_small = TRUE;
+ }
+ }
+}
+
+/* setSmallMaybe() {{{2 */
+/*
+ * Set small flags in "gap" to MAYBE.
+ */
+static void setSmallMaybe(gap)
+garray_T *gap;
+{
+ int i;
+ fold_T *fp;
+
+ fp = (fold_T *)gap->ga_data;
+ for (i = 0; i < gap->ga_len; ++i)
+ fp[i].fd_small = MAYBE;
+}
+
+/* foldCreateMarkers() {{{2 */
+/*
+ * Create a fold from line "start" to line "end" (inclusive) in the current
+ * window by adding markers.
+ */
+static void foldCreateMarkers(start, end)
+linenr_T start;
+linenr_T end;
+{
+ if (!curbuf->b_p_ma) {
+ EMSG(_(e_modifiable));
+ return;
+ }
+ parseMarker(curwin);
+
+ foldAddMarker(start, curwin->w_p_fmr, foldstartmarkerlen);
+ foldAddMarker(end, foldendmarker, foldendmarkerlen);
+
+ /* 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);
+}
+
+/* foldAddMarker() {{{2 */
+/*
+ * Add "marker[markerlen]" in 'commentstring' to line "lnum".
+ */
+static void foldAddMarker(lnum, marker, markerlen)
+linenr_T lnum;
+char_u *marker;
+int markerlen;
+{
+ char_u *cms = curbuf->b_p_cms;
+ char_u *line;
+ int line_len;
+ char_u *newline;
+ char_u *p = (char_u *)strstr((char *)curbuf->b_p_cms, "%s");
+
+ /* Allocate a new line: old-line + 'cms'-start + marker + 'cms'-end */
+ line = ml_get(lnum);
+ line_len = (int)STRLEN(line);
+
+ if (u_save(lnum - 1, lnum + 1) == OK) {
+ newline = alloc((unsigned)(line_len + markerlen + STRLEN(cms) + 1));
+ if (newline == NULL)
+ return;
+ STRCPY(newline, line);
+ if (p == NULL)
+ vim_strncpy(newline + line_len, marker, markerlen);
+ else {
+ STRCPY(newline + line_len, cms);
+ STRNCPY(newline + line_len + (p - cms), marker, markerlen);
+ STRCPY(newline + line_len + (p - cms) + markerlen, p + 2);
+ }
+
+ ml_replace(lnum, newline, FALSE);
+ }
+}
+
+/* deleteFoldMarkers() {{{2 */
+/*
+ * Delete the markers for a fold, causing it to be deleted.
+ */
+static void deleteFoldMarkers(fp, recursive, lnum_off)
+fold_T *fp;
+int recursive;
+linenr_T lnum_off; /* offset for fp->fd_top */
+{
+ int i;
+
+ if (recursive)
+ for (i = 0; i < fp->fd_nested.ga_len; ++i)
+ deleteFoldMarkers((fold_T *)fp->fd_nested.ga_data + i, TRUE,
+ lnum_off + fp->fd_top);
+ foldDelMarker(fp->fd_top + lnum_off, curwin->w_p_fmr, foldstartmarkerlen);
+ foldDelMarker(fp->fd_top + lnum_off + fp->fd_len - 1,
+ foldendmarker, foldendmarkerlen);
+}
+
+/* foldDelMarker() {{{2 */
+/*
+ * Delete marker "marker[markerlen]" at the end of line "lnum".
+ * Delete 'commentstring' if it matches.
+ * If the marker is not found, there is no error message. Could a missing
+ * close-marker.
+ */
+static void foldDelMarker(lnum, marker, markerlen)
+linenr_T lnum;
+char_u *marker;
+int markerlen;
+{
+ char_u *line;
+ char_u *newline;
+ char_u *p;
+ int len;
+ char_u *cms = curbuf->b_p_cms;
+ char_u *cms2;
+
+ line = ml_get(lnum);
+ for (p = line; *p != NUL; ++p)
+ if (STRNCMP(p, marker, markerlen) == 0) {
+ /* Found the marker, include a digit if it's there. */
+ len = markerlen;
+ if (VIM_ISDIGIT(p[len]))
+ ++len;
+ if (*cms != NUL) {
+ /* Also delete 'commentstring' if it matches. */
+ cms2 = (char_u *)strstr((char *)cms, "%s");
+ if (p - line >= cms2 - cms
+ && STRNCMP(p - (cms2 - cms), cms, cms2 - cms) == 0
+ && STRNCMP(p + len, cms2 + 2, STRLEN(cms2 + 2)) == 0) {
+ p -= cms2 - cms;
+ len += (int)STRLEN(cms) - 2;
+ }
+ }
+ if (u_save(lnum - 1, lnum + 1) == OK) {
+ /* Make new line: text-before-marker + text-after-marker */
+ newline = alloc((unsigned)(STRLEN(line) - len + 1));
+ if (newline != NULL) {
+ STRNCPY(newline, line, p - line);
+ STRCPY(newline + (p - line), p + len);
+ 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.
+ */
+char_u * get_foldtext(wp, lnum, lnume, foldinfo, buf)
+win_T *wp;
+linenr_T lnum, lnume;
+foldinfo_T *foldinfo;
+char_u *buf;
+{
+ char_u *text = NULL;
+ /* an error occurred when evaluating 'fdt' setting */
+ static int got_fdt_error = FALSE;
+ int save_did_emsg = did_emsg;
+ static win_T *last_wp = NULL;
+ static linenr_T last_lnum = 0;
+
+ if (last_wp != wp || last_wp == NULL
+ || last_lnum > lnum || last_lnum == 0)
+ /* window changed, try evaluating foldtext setting once again */
+ got_fdt_error = FALSE;
+
+ if (!got_fdt_error)
+ /* a previous error should not abort evaluating 'foldexpr' */
+ did_emsg = FALSE;
+
+ if (*wp->w_p_fdt != NUL) {
+ char_u dashes[MAX_LEVEL + 2];
+ win_T *save_curwin;
+ int level;
+ char_u *p;
+
+ /* Set "v:foldstart" and "v:foldend". */
+ set_vim_var_nr(VV_FOLDSTART, lnum);
+ set_vim_var_nr(VV_FOLDEND, lnume);
+
+ /* Set "v:folddashes" to a string of "level" dashes. */
+ /* Set "v:foldlevel" to "level". */
+ level = foldinfo->fi_level;
+ if (level > (int)sizeof(dashes) - 1)
+ level = (int)sizeof(dashes) - 1;
+ vim_memset(dashes, '-', (size_t)level);
+ dashes[level] = NUL;
+ set_vim_var_string(VV_FOLDDASHES, dashes, -1);
+ set_vim_var_nr(VV_FOLDLEVEL, (long)level);
+
+ /* skip evaluating foldtext on errors */
+ if (!got_fdt_error) {
+ save_curwin = curwin;
+ curwin = wp;
+ curbuf = wp->w_buffer;
+
+ ++emsg_silent; /* handle exceptions, but don't display errors */
+ text = eval_to_string_safe(wp->w_p_fdt, NULL,
+ was_set_insecurely((char_u *)"foldtext", OPT_LOCAL));
+ --emsg_silent;
+
+ if (text == NULL || did_emsg)
+ got_fdt_error = TRUE;
+
+ curwin = save_curwin;
+ curbuf = curwin->w_buffer;
+ }
+ last_lnum = lnum;
+ last_wp = wp;
+ set_vim_var_string(VV_FOLDDASHES, NULL, -1);
+
+ if (!did_emsg && save_did_emsg)
+ did_emsg = save_did_emsg;
+
+ 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;
+
+ if (has_mbyte && (len = (*mb_ptr2len)(p)) > 1) {
+ if (!vim_isprintc((*mb_ptr2char)(p)))
+ break;
+ p += len - 1;
+ } else if (*p == TAB)
+ *p = ' ';
+ else if (ptr2cells(p) > 1)
+ break;
+ }
+ if (*p != NUL) {
+ p = transstr(text);
+ vim_free(text);
+ text = p;
+ }
+ }
+ }
+ if (text == NULL) {
+ sprintf((char *)buf, _("+--%3ld lines folded "),
+ (long)(lnume - lnum + 1));
+ text = buf;
+ }
+ return text;
+}
+
+/* foldtext_cleanup() {{{2 */
+/*
+ * Remove 'foldmarker' and 'commentstring' from "str" (in-place).
+ */
+void foldtext_cleanup(str)
+char_u *str;
+{
+ char_u *cms_start; /* first part or the whole comment */
+ int cms_slen = 0; /* length of cms_start */
+ char_u *cms_end; /* last part of the comment or NULL */
+ int cms_elen = 0; /* length of cms_end */
+ char_u *s;
+ char_u *p;
+ int len;
+ int did1 = FALSE;
+ int did2 = FALSE;
+
+ /* Ignore leading and trailing white space in 'commentstring'. */
+ cms_start = skipwhite(curbuf->b_p_cms);
+ cms_slen = (int)STRLEN(cms_start);
+ while (cms_slen > 0 && vim_iswhite(cms_start[cms_slen - 1]))
+ --cms_slen;
+
+ /* locate "%s" in 'commentstring', use the part before and after it. */
+ cms_end = (char_u *)strstr((char *)cms_start, "%s");
+ if (cms_end != NULL) {
+ cms_elen = cms_slen - (int)(cms_end - cms_start);
+ cms_slen = (int)(cms_end - cms_start);
+
+ /* exclude white space before "%s" */
+ while (cms_slen > 0 && vim_iswhite(cms_start[cms_slen - 1]))
+ --cms_slen;
+
+ /* skip "%s" and white space after it */
+ s = skipwhite(cms_end + 2);
+ cms_elen -= (int)(s - cms_end);
+ cms_end = s;
+ }
+ parseMarker(curwin);
+
+ for (s = str; *s != NUL; ) {
+ len = 0;
+ if (STRNCMP(s, curwin->w_p_fmr, foldstartmarkerlen) == 0)
+ len = foldstartmarkerlen;
+ else if (STRNCMP(s, foldendmarker, foldendmarkerlen) == 0)
+ len = foldendmarkerlen;
+ if (len > 0) {
+ if (VIM_ISDIGIT(s[len]))
+ ++len;
+
+ /* May remove 'commentstring' start. Useful when it's a double
+ * quote and we already removed a double quote. */
+ for (p = s; p > str && vim_iswhite(p[-1]); --p)
+ ;
+ if (p >= str + cms_slen
+ && STRNCMP(p - cms_slen, cms_start, cms_slen) == 0) {
+ len += (int)(s - p) + cms_slen;
+ s = p - cms_slen;
+ }
+ } else if (cms_end != NULL) {
+ if (!did1 && cms_slen > 0 && STRNCMP(s, cms_start, cms_slen) == 0) {
+ len = cms_slen;
+ did1 = TRUE;
+ } else if (!did2 && cms_elen > 0
+ && STRNCMP(s, cms_end, cms_elen) == 0) {
+ len = cms_elen;
+ did2 = TRUE;
+ }
+ }
+ if (len != 0) {
+ while (vim_iswhite(s[len]))
+ ++len;
+ STRMOVE(s, s + len);
+ } else {
+ mb_ptr_adv(s);
+ }
+ }
+}
+
+/* Folding by indent, expr, marker and syntax. {{{1 */
+/* Define "fline_T", passed to get fold level for a line. {{{2 */
+typedef struct {
+ win_T *wp; /* window */
+ linenr_T lnum; /* current line number */
+ linenr_T off; /* offset between lnum and real line number */
+ linenr_T lnum_save; /* line nr used by foldUpdateIEMSRecurse() */
+ int lvl; /* current level (-1 for undefined) */
+ int lvl_next; /* level used for next line */
+ int start; /* number of folds that are forced to start at
+ this line. */
+ int end; /* level of fold that is forced to end below
+ this line */
+ int had_end; /* level of fold that is forced to end above
+ this line (copy of "end" of prev. line) */
+} fline_T;
+
+/* Flag is set when redrawing is needed. */
+static int fold_changed;
+
+/* Function declarations. {{{2 */
+static linenr_T foldUpdateIEMSRecurse __ARGS((garray_T *gap, int level,
+ linenr_T startlnum, fline_T *flp,
+ void (*getlevel)__ARGS(
+ (fline_T *)), linenr_T bot,
+ int topflags));
+static int foldInsert __ARGS((garray_T *gap, int i));
+static void foldSplit __ARGS((garray_T *gap, int i, linenr_T top, linenr_T bot));
+static void foldRemove __ARGS((garray_T *gap, linenr_T top, linenr_T bot));
+static void foldMerge __ARGS((fold_T *fp1, garray_T *gap, fold_T *fp2));
+static void foldlevelIndent __ARGS((fline_T *flp));
+static void foldlevelDiff __ARGS((fline_T *flp));
+static void foldlevelExpr __ARGS((fline_T *flp));
+static void foldlevelMarker __ARGS((fline_T *flp));
+static void foldlevelSyntax __ARGS((fline_T *flp));
+
+/* foldUpdateIEMS() {{{2 */
+/*
+ * Update the folding for window "wp", at least from lines "top" to "bot".
+ * Return TRUE if any folds did change.
+ */
+static void foldUpdateIEMS(wp, top, bot)
+win_T *wp;
+linenr_T top;
+linenr_T bot;
+{
+ linenr_T start;
+ linenr_T end;
+ fline_T fline;
+ void (*getlevel)__ARGS((fline_T *));
+ int level;
+ fold_T *fp;
+
+ /* Avoid problems when being called recursively. */
+ if (invalid_top != (linenr_T)0)
+ return;
+
+ if (wp->w_foldinvalid) {
+ /* Need to update all folds. */
+ top = 1;
+ bot = wp->w_buffer->b_ml.ml_line_count;
+ wp->w_foldinvalid = FALSE;
+
+ /* Mark all folds a maybe-small. */
+ setSmallMaybe(&wp->w_folds);
+ }
+
+ /* add the context for "diff" folding */
+ if (foldmethodIsDiff(wp)) {
+ if (top > diff_context)
+ top -= diff_context;
+ else
+ top = 1;
+ 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)
+ top = wp->w_buffer->b_ml.ml_line_count;
+
+ fold_changed = FALSE;
+ fline.wp = wp;
+ fline.off = 0;
+ fline.lvl = 0;
+ fline.lvl_next = -1;
+ fline.start = 0;
+ fline.end = MAX_LEVEL + 1;
+ fline.had_end = MAX_LEVEL + 1;
+
+ invalid_top = top;
+ invalid_bot = bot;
+
+ if (foldmethodIsMarker(wp)) {
+ getlevel = foldlevelMarker;
+
+ /* Init marker variables to speed up foldlevelMarker(). */
+ parseMarker(wp);
+
+ /* 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);
+
+ /* The fold may end just above the top, check for that. */
+ fline.lnum = top - 1;
+ fline.lvl = level;
+ getlevel(&fline);
+
+ /* If a fold started here, we already had the level, if it stops
+ * here, we need to use lvl_next. Could also start and end a fold
+ * in the same line. */
+ if (fline.lvl > level)
+ fline.lvl = level - (fline.lvl - fline.lvl_next);
+ else
+ fline.lvl = fline.lvl_next;
+ }
+ fline.lnum = top;
+ getlevel(&fline);
+ } else {
+ fline.lnum = top;
+ if (foldmethodIsExpr(wp)) {
+ getlevel = foldlevelExpr;
+ /* start one line back, because a "<1" may indicate the end of a
+ * fold in the topline */
+ if (top > 1)
+ --fline.lnum;
+ } else if (foldmethodIsSyntax(wp))
+ getlevel = foldlevelSyntax;
+ else if (foldmethodIsDiff(wp))
+ getlevel = foldlevelDiff;
+ else
+ getlevel = foldlevelIndent;
+
+ /* Backup to a line for which the fold level is defined. Since it's
+ * always defined for line one, we will stop there. */
+ fline.lvl = -1;
+ for (; !got_int; --fline.lnum) {
+ /* Reset lvl_next each time, because it will be set to a value for
+ * the next line, but we search backwards here. */
+ fline.lvl_next = -1;
+ getlevel(&fline);
+ if (fline.lvl >= 0)
+ break;
+ }
+ }
+
+ /*
+ * If folding is defined by the syntax, it is possible that a change in
+ * one line will cause all sub-folds of the current fold to change (e.g.,
+ * closing a C-style comment can cause folds in the subsequent lines to
+ * appear). To take that into account we should adjust the value of "bot"
+ * to point to the end of the current fold:
+ */
+ if (foldlevelSyntax == getlevel) {
+ garray_T *gap = &wp->w_folds;
+ fold_T *fpn = NULL;
+ int current_fdl = 0;
+ linenr_T fold_start_lnum = 0;
+ linenr_T lnum_rel = fline.lnum;
+
+ while (current_fdl < fline.lvl) {
+ if (!foldFind(gap, lnum_rel, &fpn))
+ break;
+ ++current_fdl;
+
+ fold_start_lnum += fpn->fd_top;
+ gap = &fpn->fd_nested;
+ lnum_rel -= fpn->fd_top;
+ }
+ if (fpn != NULL && current_fdl == fline.lvl) {
+ linenr_T fold_end_lnum = fold_start_lnum + fpn->fd_len;
+
+ if (fold_end_lnum > bot)
+ bot = fold_end_lnum;
+ }
+ }
+
+ start = fline.lnum;
+ 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). */
+ if (fline.lnum > wp->w_buffer->b_ml.ml_line_count)
+ break;
+ if (fline.lnum > end) {
+ /* For "marker", "expr" and "syntax" methods: If a change caused
+ * a fold to be removed, we need to continue at least until where
+ * it ended. */
+ if (getlevel != foldlevelMarker
+ && getlevel != foldlevelSyntax
+ && getlevel != foldlevelExpr)
+ break;
+ if ((start <= end
+ && foldFind(&wp->w_folds, end, &fp)
+ && fp->fd_top + fp->fd_len - 1 > end)
+ || (fline.lvl == 0
+ && foldFind(&wp->w_folds, fline.lnum, &fp)
+ && fp->fd_top < fline.lnum))
+ end = fp->fd_top + fp->fd_len - 1;
+ else if (getlevel == foldlevelSyntax
+ && foldLevelWin(wp, fline.lnum) != fline.lvl)
+ /* For "syntax" method: Compare the foldlevel that the syntax
+ * tells us to the foldlevel from the existing folds. If they
+ * don't match continue updating folds. */
+ end = fline.lnum;
+ else
+ break;
+ }
+
+ /* A level 1 fold starts at a line with foldlevel > 0. */
+ if (fline.lvl > 0) {
+ invalid_top = fline.lnum;
+ invalid_bot = end;
+ end = foldUpdateIEMSRecurse(&wp->w_folds,
+ 1, start, &fline, getlevel, end, FD_LEVEL);
+ start = fline.lnum;
+ } else {
+ if (fline.lnum == wp->w_buffer->b_ml.ml_line_count)
+ break;
+ ++fline.lnum;
+ fline.lvl = fline.lvl_next;
+ getlevel(&fline);
+ }
+ }
+
+ /* There can't be any folds from start until end now. */
+ foldRemove(&wp->w_folds, start, end);
+
+ /* If some fold changed, need to redraw and position cursor. */
+ if (fold_changed && wp->w_p_fen)
+ changed_window_setting_win(wp);
+
+ /* If we updated folds past "bot", need to redraw more lines. Don't do
+ * this in other situations, the changed lines will be redrawn anyway and
+ * this method can cause the whole window to be updated. */
+ if (end != bot) {
+ if (wp->w_redraw_top == 0 || wp->w_redraw_top > top)
+ wp->w_redraw_top = top;
+ if (wp->w_redraw_bot < end)
+ wp->w_redraw_bot = end;
+ }
+
+ invalid_top = (linenr_T)0;
+}
+
+/* foldUpdateIEMSRecurse() {{{2 */
+/*
+ * Update a fold that starts at "flp->lnum". At this line there is always a
+ * valid foldlevel, and its level >= "level".
+ * "flp" is valid for "flp->lnum" when called and it's valid when returning.
+ * "flp->lnum" is set to the lnum just below the fold, if it ends before
+ * "bot", it's "bot" plus one if the fold continues and it's bigger when using
+ * the marker method and a text change made following folds to change.
+ * When returning, "flp->lnum_save" is the line number that was used to get
+ * the level when the level at "flp->lnum" is invalid.
+ * Remove any folds from "startlnum" up to here at this level.
+ * Recursively update nested folds.
+ * Below line "bot" there are no changes in the text.
+ * "flp->lnum", "flp->lnum_save" and "bot" are relative to the start of the
+ * outer fold.
+ * "flp->off" is the offset to the real line number in the buffer.
+ *
+ * All this would be a lot simpler if all folds in the range would be deleted
+ * and then created again. But we would lose all information about the
+ * folds, even when making changes that don't affect the folding (e.g. "vj~").
+ *
+ * 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(gap, level, startlnum, flp, getlevel, bot,
+ topflags)
+garray_T *gap;
+int level;
+linenr_T startlnum;
+fline_T *flp;
+void (*getlevel)__ARGS((fline_T *));
+linenr_T bot;
+int topflags; /* flags used by containing fold */
+{
+ 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 */
+ int i;
+ int finish = FALSE;
+ linenr_T linecount = flp->wp->w_buffer->b_ml.ml_line_count - flp->off;
+ int concat;
+
+ /*
+ * If using the marker method, the start line is not the start of a fold
+ * at the level we're dealing with and the level is non-zero, we must use
+ * the previous fold. But ignore a fold that starts at or below
+ * startlnum, it must be deleted.
+ */
+ if (getlevel == foldlevelMarker && flp->start <= flp->lvl - level
+ && flp->lvl > 0) {
+ foldFind(gap, startlnum - 1, &fp);
+ if (fp >= ((fold_T *)gap->ga_data) + gap->ga_len
+ || fp->fd_top >= startlnum)
+ fp = NULL;
+ }
+
+ /*
+ * Loop over all lines in this fold, or until "bot" is hit.
+ * Handle nested folds inside of this fold.
+ * "flp->lnum" is the current line. When finding the end of the fold, it
+ * is just below the end of the fold.
+ * "*flp" contains the level of the line "flp->lnum" or a following one if
+ * there are lines with an invalid fold level. "flp->lnum_save" is the
+ * line number that was used to get the fold level (below "flp->lnum" when
+ * it has an invalid fold level). When called the fold level is always
+ * valid, thus "flp->lnum_save" is equal to "flp->lnum".
+ */
+ flp->lnum_save = flp->lnum;
+ while (!got_int) {
+ /* Updating folds can be slow, check for CTRL-C. */
+ line_breakcheck();
+
+ /* Set "lvl" to the level of line "flp->lnum". When flp->start is set
+ * and after the first line of the fold, set the level to zero to
+ * force the fold to end. Do the same when had_end is set: Previous
+ * line was marked as end of a fold. */
+ lvl = flp->lvl;
+ if (lvl > MAX_LEVEL)
+ lvl = MAX_LEVEL;
+ if (flp->lnum > firstlnum
+ && (level > lvl - flp->start || level >= flp->had_end))
+ lvl = 0;
+
+ if (flp->lnum > bot && !finish && fp != NULL) {
+ /* For "marker" and "syntax" methods:
+ * - If a change caused a nested fold to be removed, we need to
+ * delete it and continue at least until where it ended.
+ * - If a change caused a nested fold to be created, or this fold
+ * to continue below its original end, need to finish this fold.
+ */
+ if (getlevel != foldlevelMarker
+ && getlevel != foldlevelExpr
+ && getlevel != foldlevelSyntax)
+ break;
+ i = 0;
+ fp2 = fp;
+ if (lvl >= level) {
+ /* Compute how deep the folds currently are, if it's deeper
+ * than "lvl" then some must be deleted, need to update
+ * at least one nested fold. */
+ ll = flp->lnum - fp->fd_top;
+ while (foldFind(&fp2->fd_nested, ll, &fp2)) {
+ ++i;
+ ll -= fp2->fd_top;
+ }
+ }
+ if (lvl < level + i) {
+ foldFind(&fp->fd_nested, flp->lnum - fp->fd_top, &fp2);
+ if (fp2 != NULL)
+ bot = fp2->fd_top + fp2->fd_len - 1 + fp->fd_top;
+ } else if (fp->fd_top + fp->fd_len <= flp->lnum && lvl >= level)
+ finish = TRUE;
+ else
+ break;
+ }
+
+ /* At the start of the first nested fold and at the end of the current
+ * fold: check if existing folds at this level, before the current
+ * one, need to be deleted or truncated. */
+ if (fp == NULL
+ && (lvl != level
+ || flp->lnum_save >= bot
+ || flp->start != 0
+ || flp->had_end <= MAX_LEVEL
+ || flp->lnum == linecount)) {
+ /*
+ * Remove or update folds that have lines between startlnum and
+ * firstlnum.
+ */
+ while (!got_int) {
+ /* set concat to 1 if it's allowed to concatenated this fold
+ * with a previous one that touches it. */
+ if (flp->start != 0 || flp->had_end <= MAX_LEVEL)
+ concat = 0;
+ else
+ concat = 1;
+
+ /* Find an existing fold to re-use. Preferably one that
+ * includes startlnum, otherwise one that ends just before
+ * startlnum or starts after it. */
+ if (foldFind(gap, startlnum, &fp)
+ || (fp < ((fold_T *)gap->ga_data) + gap->ga_len
+ && fp->fd_top <= firstlnum)
+ || foldFind(gap, firstlnum - concat, &fp)
+ || (fp < ((fold_T *)gap->ga_data) + gap->ga_len
+ && ((lvl < level && fp->fd_top < flp->lnum)
+ || (lvl >= level
+ && fp->fd_top <= flp->lnum_save)))) {
+ if (fp->fd_top + fp->fd_len + concat > firstlnum) {
+ /* Use existing fold for the new fold. If it starts
+ * 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 */
+ foldMarkAdjustRecurse(&fp->fd_nested,
+ (linenr_T)0, (linenr_T)MAXLNUM,
+ (long)(fp->fd_top - firstlnum), 0L);
+ else
+ /* like lines are deleted */
+ foldMarkAdjustRecurse(&fp->fd_nested,
+ (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);
+ i = (int)(fp - (fold_T *)gap->ga_data);
+ foldSplit(gap, i, flp->lnum, flp->lnum - 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;
+ }
+ 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);
+ } 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;
+ }
+ } else {
+ /* Insert new fold. Careful: ga_data may be NULL and it
+ * may change! */
+ i = (int)(fp - (fold_T *)gap->ga_data);
+ if (foldInsert(gap, i) != OK)
+ return bot;
+ fp = (fold_T *)gap->ga_data + i;
+ /* The new fold continues until bot, unless we find the
+ * end earlier. */
+ fp->fd_top = firstlnum;
+ fp->fd_len = bot - firstlnum + 1;
+ /* When the containing fold is open, the new fold is open.
+ * The new fold is closed if the fold above it is closed.
+ * The first fold depends on the containing fold. */
+ if (topflags == FD_OPEN) {
+ flp->wp->w_fold_manual = TRUE;
+ fp->fd_flags = FD_OPEN;
+ } else if (i <= 0) {
+ fp->fd_flags = topflags;
+ if (topflags != FD_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. */
+ if (getlevel == foldlevelMarker
+ || getlevel == foldlevelExpr
+ || getlevel == foldlevelSyntax)
+ finish = TRUE;
+ fold_changed = TRUE;
+ break;
+ }
+ }
+ }
+
+ if (lvl < level || flp->lnum > linecount) {
+ /*
+ * Found a line with a lower foldlevel, this fold ends just above
+ * "flp->lnum".
+ */
+ break;
+ }
+
+ /*
+ * The fold includes the line "flp->lnum" and "flp->lnum_save".
+ * 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)
+ bot = flp->lnum;
+
+ /* Line numbers in the nested fold are relative to the start of
+ * this fold. */
+ flp->lnum = flp->lnum_save - fp->fd_top;
+ flp->off += fp->fd_top;
+ i = (int)(fp - (fold_T *)gap->ga_data);
+ bot = foldUpdateIEMSRecurse(&fp->fd_nested, level + 1,
+ startlnum2 - fp->fd_top, flp, getlevel,
+ bot - fp->fd_top, fp->fd_flags);
+ fp = (fold_T *)gap->ga_data + i;
+ flp->lnum += fp->fd_top;
+ flp->lnum_save += fp->fd_top;
+ flp->off -= fp->fd_top;
+ bot += fp->fd_top;
+ startlnum2 = flp->lnum;
+
+ /* This fold may end at the same line, don't incr. flp->lnum. */
+ } else {
+ /*
+ * Get the level of the next line, then continue the loop to check
+ * if it ends there.
+ * Skip over undefined lines, to find the foldlevel after it.
+ * For the last line in the file the foldlevel is always valid.
+ */
+ flp->lnum = flp->lnum_save;
+ ll = flp->lnum + 1;
+ while (!got_int) {
+ /* Make the previous level available to foldlevel(). */
+ prev_lnum = flp->lnum;
+ prev_lnum_lvl = flp->lvl;
+
+ if (++flp->lnum > linecount)
+ break;
+ flp->lvl = flp->lvl_next;
+ getlevel(flp);
+ if (flp->lvl >= 0 || flp->had_end <= MAX_LEVEL)
+ break;
+ }
+ prev_lnum = 0;
+ if (flp->lnum > linecount)
+ break;
+
+ /* leave flp->lnum_save to lnum of the line that was used to get
+ * the level, flp->lnum to the lnum of the next line. */
+ flp->lnum_save = flp->lnum;
+ flp->lnum = ll;
+ }
+ }
+
+ if (fp == NULL) /* only happens when got_int is set */
+ return bot;
+
+ /*
+ * Get here when:
+ * lvl < level: the folds ends just above "flp->lnum"
+ * lvl >= level: fold continues below "bot"
+ */
+
+ /* 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;
+ }
+
+ /* Delete contained folds from the end of the last one found until where
+ * we stopped looking. */
+ foldRemove(&fp->fd_nested, startlnum2 - fp->fd_top,
+ flp->lnum - 1 - fp->fd_top);
+
+ if (lvl < level) {
+ /* 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 (getlevel == foldlevelMarker
+ || getlevel == foldlevelExpr
+ || getlevel == foldlevelSyntax) {
+ /* 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 */
+ i = (int)(fp - (fold_T *)gap->ga_data);
+ foldSplit(gap, i, flp->lnum, bot);
+ fp = (fold_T *)gap->ga_data + i;
+ }
+ } else
+ fp->fd_len = flp->lnum - fp->fd_top;
+ fold_changed = TRUE;
+ }
+ }
+
+ /* delete following folds that end before the current line */
+ for (;; ) {
+ fp2 = fp + 1;
+ if (fp2 >= (fold_T *)gap->ga_data + gap->ga_len
+ || fp2->fd_top > flp->lnum)
+ break;
+ if (fp2->fd_top + fp2->fd_len > flp->lnum) {
+ if (fp2->fd_top < flp->lnum) {
+ /* Make fold that includes lnum start at lnum. */
+ foldMarkAdjustRecurse(&fp2->fd_nested,
+ (linenr_T)0, (long)(flp->lnum - fp2->fd_top - 1),
+ (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;
+ }
+
+ if (lvl >= level) {
+ /* merge new fold with existing fold that follows */
+ foldMerge(fp, gap, fp2);
+ }
+ break;
+ }
+ 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
+ * was asked for. */
+ if (bot < flp->lnum - 1)
+ bot = flp->lnum - 1;
+
+ return bot;
+}
+
+/* foldInsert() {{{2 */
+/*
+ * Insert a new fold in "gap" at position "i".
+ * Returns OK for success, FAIL for failure.
+ */
+static int foldInsert(gap, i)
+garray_T *gap;
+int i;
+{
+ fold_T *fp;
+
+ if (ga_grow(gap, 1) != OK)
+ return FAIL;
+ fp = (fold_T *)gap->ga_data + i;
+ if (i < gap->ga_len)
+ mch_memmove(fp + 1, fp, sizeof(fold_T) * (gap->ga_len - i));
+ ++gap->ga_len;
+ ga_init2(&fp->fd_nested, (int)sizeof(fold_T), 10);
+ return OK;
+}
+
+/* foldSplit() {{{2 */
+/*
+ * Split the "i"th fold in "gap", which starts before "top" and ends below
+ * "bot" in two pieces, one ending above "top" and the other starting below
+ * "bot".
+ * The caller must first have taken care of any nested folds from "top" to
+ * "bot"!
+ */
+static void foldSplit(gap, i, top, bot)
+garray_T *gap;
+int i;
+linenr_T top;
+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. */
+ if (foldInsert(gap, i + 1) == FAIL)
+ return;
+ fp = (fold_T *)gap->ga_data + i;
+ fp[1].fd_top = bot + 1;
+ 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;
+
+ /* 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;
+ (void)(foldFind(gap1, bot + 1 - fp->fd_top, &fp2));
+ len = (int)((fold_T *)gap1->ga_data + gap1->ga_len - fp2);
+ if (len > 0 && ga_grow(gap2, len) == OK) {
+ for (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;
+ }
+ gap2->ga_len = len;
+ gap1->ga_len -= len;
+ }
+ fp->fd_len = top - fp->fd_top;
+ fold_changed = TRUE;
+}
+
+/* foldRemove() {{{2 */
+/*
+ * Remove folds within the range "top" to and including "bot".
+ * Check for these situations:
+ * 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
+ *
+ * 1: not changed
+ * 2: truncate to stop above "top"
+ * 3: split in two parts, one stops above "top", other starts below "bot".
+ * 4: deleted
+ * 5: made to start below "bot".
+ * 6: not changed
+ */
+static void foldRemove(gap, top, bot)
+garray_T *gap;
+linenr_T top;
+linenr_T bot;
+{
+ fold_T *fp = NULL;
+
+ if (bot < top)
+ return; /* nothing to do */
+
+ for (;; ) {
+ /* 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 */
+ 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. */
+ foldSplit(gap, (int)(fp - (fold_T *)gap->ga_data), top, bot);
+ } else {
+ /* 2: truncate fold at "top". */
+ fp->fd_len = top - fp->fd_top;
+ }
+ 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. */
+ break;
+ }
+ if (fp->fd_top >= top) {
+ /* 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. */
+ foldMarkAdjustRecurse(&fp->fd_nested,
+ (linenr_T)0, (long)(bot - fp->fd_top),
+ (linenr_T)MAXLNUM, (long)(fp->fd_top - bot - 1));
+ fp->fd_len -= bot - fp->fd_top + 1;
+ fp->fd_top = bot + 1;
+ break;
+ }
+
+ /* 4: Delete completely contained fold. */
+ deleteFoldEntry(gap, (int)(fp - (fold_T *)gap->ga_data), TRUE);
+ }
+ }
+}
+
+/* foldMerge() {{{2 */
+/*
+ * Merge two adjacent folds (and the nested ones in them).
+ * This only works correctly when the folds are really adjacent! Thus "fp1"
+ * must end just above "fp2".
+ * The resulting fold is "fp1", nested folds are moved from "fp2" to "fp1".
+ * Fold entry "fp2" in "gap" is deleted.
+ */
+static void foldMerge(fp1, gap, fp2)
+fold_T *fp1;
+garray_T *gap;
+fold_T *fp2;
+{
+ fold_T *fp3;
+ fold_T *fp4;
+ int idx;
+ garray_T *gap1 = &fp1->fd_nested;
+ garray_T *gap2 = &fp2->fd_nested;
+
+ /* If the last nested fold in fp1 touches the first nested fold in fp2,
+ * merge them recursively. */
+ if (foldFind(gap1, fp1->fd_len - 1L, &fp3) && foldFind(gap2, 0L, &fp4))
+ foldMerge(fp3, gap2, fp4);
+
+ /* Move nested folds in fp2 to the end of fp1. */
+ if (gap2->ga_len > 0 && ga_grow(gap1, gap2->ga_len) == OK) {
+ for (idx = 0; idx < gap2->ga_len; ++idx) {
+ ((fold_T *)gap1->ga_data)[gap1->ga_len]
+ = ((fold_T *)gap2->ga_data)[idx];
+ ((fold_T *)gap1->ga_data)[gap1->ga_len].fd_top += fp1->fd_len;
+ ++gap1->ga_len;
+ }
+ gap2->ga_len = 0;
+ }
+
+ fp1->fd_len += fp2->fd_len;
+ deleteFoldEntry(gap, (int)(fp2 - (fold_T *)gap->ga_data), TRUE);
+ fold_changed = TRUE;
+}
+
+/* foldlevelIndent() {{{2 */
+/*
+ * Low level function to get the foldlevel for the "indent" method.
+ * Doesn't use any caching.
+ * Returns a level of -1 if the foldlevel depends on surrounding lines.
+ */
+static void foldlevelIndent(flp)
+fline_T *flp;
+{
+ char_u *s;
+ buf_T *buf;
+ linenr_T lnum = flp->lnum + flp->off;
+
+ buf = flp->wp->w_buffer;
+ s = skipwhite(ml_get_buf(buf, lnum, FALSE));
+
+ /* empty line or lines starting with a character in 'foldignore': level
+ * depends on surrounding lines */
+ if (*s == NUL || vim_strchr(flp->wp->w_p_fdi, *s) != NULL) {
+ /* first and last line can't be undefined, use level 0 */
+ if (lnum == 1 || lnum == buf->b_ml.ml_line_count)
+ flp->lvl = 0;
+ else
+ flp->lvl = -1;
+ } else
+ flp->lvl = get_indent_buf(buf, lnum) / get_sw_value(curbuf);
+ if (flp->lvl > flp->wp->w_p_fdn) {
+ flp->lvl = flp->wp->w_p_fdn;
+ if (flp->lvl < 0)
+ flp->lvl = 0;
+ }
+}
+
+/* foldlevelDiff() {{{2 */
+/*
+ * Low level function to get the foldlevel for the "diff" method.
+ * Doesn't use any caching.
+ */
+static void foldlevelDiff(flp)
+fline_T *flp;
+{
+ if (diff_infold(flp->wp, flp->lnum + flp->off))
+ flp->lvl = 1;
+ else
+ flp->lvl = 0;
+}
+
+/* foldlevelExpr() {{{2 */
+/*
+ * Low level function to get the foldlevel for the "expr" method.
+ * Doesn't use any caching.
+ * Returns a level of -1 if the foldlevel depends on surrounding lines.
+ */
+static void foldlevelExpr(flp)
+fline_T *flp;
+{
+ win_T *win;
+ int n;
+ int c;
+ linenr_T lnum = flp->lnum + flp->off;
+ int save_keytyped;
+
+ win = curwin;
+ curwin = flp->wp;
+ curbuf = flp->wp->w_buffer;
+ set_vim_var_nr(VV_LNUM, lnum);
+
+ flp->start = 0;
+ flp->had_end = flp->end;
+ flp->end = MAX_LEVEL + 1;
+ if (lnum <= 1)
+ flp->lvl = 0;
+
+ /* 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);
+ KeyTyped = save_keytyped;
+
+ switch (c) {
+ /* "a1", "a2", .. : add to the fold level */
+ case 'a': if (flp->lvl >= 0) {
+ flp->lvl += n;
+ flp->lvl_next = flp->lvl;
+ }
+ flp->start = n;
+ break;
+
+ /* "s1", "s2", .. : subtract from the fold level */
+ case 's': if (flp->lvl >= 0) {
+ if (n > flp->lvl)
+ flp->lvl_next = 0;
+ else
+ flp->lvl_next = flp->lvl - n;
+ flp->end = flp->lvl_next + 1;
+ }
+ break;
+
+ /* ">1", ">2", .. : start a fold with a certain level */
+ case '>': flp->lvl = n;
+ flp->lvl_next = n;
+ flp->start = 1;
+ break;
+
+ /* "<1", "<2", .. : end a fold with a certain level */
+ case '<': flp->lvl_next = n - 1;
+ flp->end = n;
+ break;
+
+ /* "=": No change in level */
+ case '=': flp->lvl_next = flp->lvl;
+ break;
+
+ /* "-1", "0", "1", ..: set fold level */
+ default: if (n < 0)
+ /* Use the current level for the next line, so that "a1"
+ * will work there. */
+ flp->lvl_next = flp->lvl;
+ else
+ flp->lvl_next = n;
+ flp->lvl = n;
+ break;
+ }
+
+ /* If the level is unknown for the first or the last line in the file, use
+ * level 0. */
+ if (flp->lvl < 0) {
+ if (lnum <= 1) {
+ flp->lvl = 0;
+ flp->lvl_next = 0;
+ }
+ if (lnum == curbuf->b_ml.ml_line_count)
+ flp->lvl_next = 0;
+ }
+
+ curwin = win;
+ curbuf = curwin->w_buffer;
+}
+
+/* parseMarker() {{{2 */
+/*
+ * Parse 'foldmarker' and set "foldendmarker", "foldstartmarkerlen" and
+ * "foldendmarkerlen".
+ * Relies on the option value to have been checked for correctness already.
+ */
+static void parseMarker(wp)
+win_T *wp;
+{
+ foldendmarker = vim_strchr(wp->w_p_fmr, ',');
+ foldstartmarkerlen = (int)(foldendmarker++ - wp->w_p_fmr);
+ foldendmarkerlen = (int)STRLEN(foldendmarker);
+}
+
+/* foldlevelMarker() {{{2 */
+/*
+ * Low level function to get the foldlevel for the "marker" method.
+ * "foldendmarker", "foldstartmarkerlen" and "foldendmarkerlen" must have been
+ * set before calling this.
+ * Requires that flp->lvl is set to the fold level of the previous line!
+ * Careful: This means you can't call this function twice on the same line.
+ * Doesn't use any caching.
+ * Sets flp->start when a start marker was found.
+ */
+static void foldlevelMarker(flp)
+fline_T *flp;
+{
+ char_u *startmarker;
+ int cstart;
+ int cend;
+ int start_lvl = flp->lvl;
+ char_u *s;
+ int n;
+
+ /* cache a few values for speed */
+ startmarker = flp->wp->w_p_fmr;
+ cstart = *startmarker;
+ ++startmarker;
+ cend = *foldendmarker;
+
+ /* Default: no start found, next level is same as current level */
+ flp->start = 0;
+ flp->lvl_next = flp->lvl;
+
+ s = ml_get_buf(flp->wp->w_buffer, flp->lnum + flp->off, FALSE);
+ while (*s) {
+ if (*s == cstart
+ && STRNCMP(s + 1, startmarker, foldstartmarkerlen - 1) == 0) {
+ /* found startmarker: set flp->lvl */
+ s += foldstartmarkerlen;
+ if (VIM_ISDIGIT(*s)) {
+ n = atoi((char *)s);
+ if (n > 0) {
+ flp->lvl = n;
+ flp->lvl_next = n;
+ if (n <= start_lvl)
+ flp->start = 1;
+ else
+ flp->start = n - start_lvl;
+ }
+ } else {
+ ++flp->lvl;
+ ++flp->lvl_next;
+ ++flp->start;
+ }
+ } else if (*s == cend
+ && STRNCMP(s + 1, foldendmarker + 1,
+ foldendmarkerlen - 1) == 0) {
+ /* found endmarker: set flp->lvl_next */
+ s += foldendmarkerlen;
+ if (VIM_ISDIGIT(*s)) {
+ n = atoi((char *)s);
+ if (n > 0) {
+ flp->lvl = n;
+ flp->lvl_next = n - 1;
+ /* never start a fold with an end marker */
+ if (flp->lvl_next > start_lvl)
+ flp->lvl_next = start_lvl;
+ }
+ } else
+ --flp->lvl_next;
+ } else
+ mb_ptr_adv(s);
+ }
+
+ /* The level can't go negative, must be missing a start marker. */
+ if (flp->lvl_next < 0)
+ flp->lvl_next = 0;
+}
+
+/* foldlevelSyntax() {{{2 */
+/*
+ * Low level function to get the foldlevel for the "syntax" method.
+ * Doesn't use any caching.
+ */
+static void foldlevelSyntax(flp)
+fline_T *flp;
+{
+ linenr_T lnum = flp->lnum + flp->off;
+ int n;
+
+ /* Use the maximum fold level at the start of this line and the next. */
+ flp->lvl = syn_get_foldlevel(flp->wp, lnum);
+ flp->start = 0;
+ if (lnum < flp->wp->w_buffer->b_ml.ml_line_count) {
+ n = syn_get_foldlevel(flp->wp, lnum + 1);
+ if (n > flp->lvl) {
+ flp->start = n - flp->lvl; /* fold(s) start here */
+ flp->lvl = n;
+ }
+ }
+}
+
+/* functions for storing the fold state in a View {{{1 */
+/* put_folds() {{{2 */
+static int put_folds_recurse __ARGS((FILE *fd, garray_T *gap, linenr_T off));
+static int put_foldopen_recurse __ARGS((FILE *fd, win_T *wp, garray_T *gap,
+ linenr_T off));
+static int put_fold_open_close __ARGS((FILE *fd, fold_T *fp, linenr_T off));
+
+/*
+ * Write commands to "fd" to restore the manual folds in window "wp".
+ * Return FAIL if writing fails.
+ */
+int put_folds(fd, wp)
+FILE *fd;
+win_T *wp;
+{
+ if (foldmethodIsManual(wp)) {
+ if (put_line(fd, "silent! normal! zE") == FAIL
+ || put_folds_recurse(fd, &wp->w_folds, (linenr_T)0) == FAIL)
+ return FAIL;
+ }
+
+ /* If some folds are manually opened/closed, need to restore that. */
+ if (wp->w_fold_manual)
+ return put_foldopen_recurse(fd, wp, &wp->w_folds, (linenr_T)0);
+
+ return OK;
+}
+
+/* put_folds_recurse() {{{2 */
+/*
+ * Write commands to "fd" to recreate manually created folds.
+ * Returns FAIL when writing failed.
+ */
+static int put_folds_recurse(fd, gap, off)
+FILE *fd;
+garray_T *gap;
+linenr_T off;
+{
+ int i;
+ fold_T *fp;
+
+ fp = (fold_T *)gap->ga_data;
+ for (i = 0; i < gap->ga_len; i++) {
+ /* Do nested folds first, they will be created closed. */
+ if (put_folds_recurse(fd, &fp->fd_nested, off + fp->fd_top) == FAIL)
+ return FAIL;
+ if (fprintf(fd, "%ld,%ldfold", fp->fd_top + off,
+ fp->fd_top + off + fp->fd_len - 1) < 0
+ || put_eol(fd) == FAIL)
+ return FAIL;
+ ++fp;
+ }
+ return OK;
+}
+
+/* put_foldopen_recurse() {{{2 */
+/*
+ * Write commands to "fd" to open and close manually opened/closed folds.
+ * Returns FAIL when writing failed.
+ */
+static int put_foldopen_recurse(fd, wp, gap, off)
+FILE *fd;
+win_T *wp;
+garray_T *gap;
+linenr_T off;
+{
+ int i;
+ int level;
+ fold_T *fp;
+
+ fp = (fold_T *)gap->ga_data;
+ for (i = 0; i < gap->ga_len; i++) {
+ if (fp->fd_flags != FD_LEVEL) {
+ if (fp->fd_nested.ga_len > 0) {
+ /* open nested folds while this fold is open */
+ if (fprintf(fd, "%ld", fp->fd_top + off) < 0
+ || put_eol(fd) == FAIL
+ || put_line(fd, "normal! zo") == FAIL)
+ return FAIL;
+ if (put_foldopen_recurse(fd, wp, &fp->fd_nested,
+ off + fp->fd_top)
+ == FAIL)
+ return FAIL;
+ /* close the parent when needed */
+ if (fp->fd_flags == FD_CLOSED) {
+ if (put_fold_open_close(fd, fp, off) == FAIL)
+ return FAIL;
+ }
+ } else {
+ /* Open or close the leaf according to the window foldlevel.
+ * Do not close a leaf that is already closed, as it will close
+ * the parent. */
+ level = foldLevelWin(wp, off + fp->fd_top);
+ if ((fp->fd_flags == FD_CLOSED && wp->w_p_fdl >= level)
+ || (fp->fd_flags != FD_CLOSED && wp->w_p_fdl < level))
+ if (put_fold_open_close(fd, fp, off) == FAIL)
+ return FAIL;
+ }
+ }
+ ++fp;
+ }
+
+ return OK;
+}
+
+/* put_fold_open_close() {{{2 */
+/*
+ * Write the open or close command to "fd".
+ * Returns FAIL when writing failed.
+ */
+static int put_fold_open_close(fd, fp, off)
+FILE *fd;
+fold_T *fp;
+linenr_T off;
+{
+ if (fprintf(fd, "%ld", fp->fd_top + off) < 0
+ || put_eol(fd) == FAIL
+ || fprintf(fd, "normal! z%c",
+ fp->fd_flags == FD_CLOSED ? 'c' : 'o') < 0
+ || put_eol(fd) == FAIL)
+ return FAIL;
+
+ return OK;
+}
+
+/* }}}1 */
diff --git a/src/getchar.c b/src/getchar.c
new file mode 100644
index 0000000000..92e1ece639
--- /dev/null
+++ b/src/getchar.c
@@ -0,0 +1,4273 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * 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.
+ */
+
+/*
+ * getchar.c
+ *
+ * functions related with getting a character from the user/mapping/redo/...
+ *
+ * manipulations with redo buffer and stuff buffer
+ * mappings and abbreviations
+ */
+
+#include "vim.h"
+
+/*
+ * These buffers are used for storing:
+ * - stuffed characters: A command that is translated into another command.
+ * - redo characters: will redo the last change.
+ * - recorded characters: for the "q" command.
+ *
+ * The bytes are stored like in the typeahead buffer:
+ * - K_SPECIAL introduces a special key (two more bytes follow). A literal
+ * K_SPECIAL is stored as K_SPECIAL KS_SPECIAL KE_FILLER.
+ * - CSI introduces a GUI termcap code (also when gui.in_use is FALSE,
+ * otherwise switching the GUI on would make mappings invalid).
+ * A literal CSI is stored as CSI KS_EXTRA KE_CSI.
+ * These translations are also done on multi-byte characters!
+ *
+ * Escaping CSI bytes is done by the system-specific input functions, called
+ * by ui_inchar().
+ * Escaping K_SPECIAL is done by inchar().
+ * Un-escaping is done by vgetc().
+ */
+
+#define MINIMAL_SIZE 20 /* minimal size for b_str */
+
+static struct buffheader redobuff = {{NULL, {NUL}}, NULL, 0, 0};
+static struct buffheader old_redobuff = {{NULL, {NUL}}, NULL, 0, 0};
+static struct buffheader save_redobuff = {{NULL, {NUL}}, NULL, 0, 0};
+static struct buffheader save_old_redobuff = {{NULL, {NUL}}, NULL, 0, 0};
+static struct buffheader recordbuff = {{NULL, {NUL}}, NULL, 0, 0};
+
+static int typeahead_char = 0; /* typeahead char that's not flushed */
+
+/*
+ * when block_redo is TRUE redo buffer will not be changed
+ * used by edit() to repeat insertions and 'V' command for redoing
+ */
+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.
+ */
+#define MAP_HASH(mode, \
+ c1) (((mode) & \
+ (NORMAL + VISUAL + SELECTMODE + \
+ OP_PENDING)) ? (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;
+
+/*
+ * List used for abbreviations.
+ */
+static mapblock_T *first_abbr = NULL; /* first entry in abbrlist */
+
+static int KeyNoremap = 0; /* remapping flags */
+
+/*
+ * 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.
+ * typebuf.tb_buf[typebuf.tb_off + typebuf.tb_len - 1] is the last valid char.
+ * typebuf.tb_buf[typebuf.tb_off + typebuf.tb_len] must be NUL.
+ * The head of the buffer may contain the result of mappings, abbreviations
+ * and @a commands. The length of this part is typebuf.tb_maplen.
+ * typebuf.tb_silent is the part where <silent> applies.
+ * After the head are characters that come from the terminal.
+ * typebuf.tb_no_abbr_cnt is the number of characters in typebuf.tb_buf that
+ * should not be considered for abbreviations.
+ * Some parts of typebuf.tb_buf may not be mapped. These parts are remembered
+ * in typebuf.tb_noremap[], which is the same length as typebuf.tb_buf and
+ * contains RM_NONE for the characters that are not to be remapped.
+ * typebuf.tb_noremap[typebuf.tb_off] is the first valid flag.
+ * (typebuf has been put in globals.h, because check_termcode() needs it).
+ */
+#define RM_YES 0 /* tb_noremap: remap */
+#define RM_NONE 1 /* tb_noremap: don't remap */
+#define RM_SCRIPT 2 /* tb_noremap: remap local script mappings */
+#define RM_ABBR 4 /* tb_noremap: don't remap, do abbrev. */
+
+/* typebuf.tb_buf has three parts: room in front (for result of mappings), the
+ * middle for typeahead and room for new characters (which needs to be 3 *
+ * MAXMAPLEN) for the Amiga).
+ */
+#define TYPELEN_INIT (5 * (MAXMAPLEN + 3))
+static char_u typebuf_init[TYPELEN_INIT]; /* initial typebuf.tb_buf */
+static char_u noremapbuf_init[TYPELEN_INIT]; /* initial typebuf.tb_noremap */
+
+static int last_recorded_len = 0; /* number of last recorded chars */
+
+static char_u *get_buffcont __ARGS((struct buffheader *, int));
+static void add_buff __ARGS((struct buffheader *, char_u *, long n));
+static void add_num_buff __ARGS((struct buffheader *, long));
+static void add_char_buff __ARGS((struct buffheader *, int));
+static int read_stuff __ARGS((int advance));
+static void start_stuff __ARGS((void));
+static int read_redo __ARGS((int, int));
+static void copy_redo __ARGS((int));
+static void init_typebuf __ARGS((void));
+static void gotchars __ARGS((char_u *, int));
+static void may_sync_undo __ARGS((void));
+static void closescript __ARGS((void));
+static int vgetorpeek __ARGS((int));
+static void map_free __ARGS((mapblock_T **));
+static void validate_maphash __ARGS((void));
+static void showmap __ARGS((mapblock_T *mp, int local));
+static char_u *eval_map_expr __ARGS((char_u *str, int c));
+
+/*
+ * Free and clear a buffer.
+ */
+void free_buff(buf)
+struct buffheader *buf;
+{
+ struct buffblock *p, *np;
+
+ for (p = buf->bh_first.b_next; p != NULL; p = np) {
+ np = p->b_next;
+ vim_free(p);
+ }
+ buf->bh_first.b_next = NULL;
+}
+
+/*
+ * Return the contents of a buffer as a single string.
+ * K_SPECIAL and CSI in the returned string are escaped.
+ */
+static char_u * get_buffcont(buffer, dozero)
+struct buffheader *buffer;
+int dozero; /* count == zero is not an error */
+{
+ long_u count = 0;
+ char_u *p = NULL;
+ char_u *p2;
+ char_u *str;
+ struct buffblock *bp;
+
+ /* compute the total length of the string */
+ for (bp = buffer->bh_first.b_next; bp != NULL; bp = bp->b_next)
+ count += (long_u)STRLEN(bp->b_str);
+
+ if ((count || dozero) && (p = lalloc(count + 1, TRUE)) != NULL) {
+ p2 = p;
+ for (bp = buffer->bh_first.b_next; bp != NULL; bp = bp->b_next)
+ for (str = bp->b_str; *str; )
+ *p2++ = *str++;
+ *p2 = NUL;
+ }
+ return p;
+}
+
+/*
+ * Return the contents of the record buffer as a single string
+ * and clear the record buffer.
+ * K_SPECIAL and CSI in the returned string are escaped.
+ */
+char_u * get_recorded() {
+ char_u *p;
+ size_t len;
+
+ p = get_buffcont(&recordbuff, TRUE);
+ free_buff(&recordbuff);
+
+ /*
+ * Remove the characters that were added the last time, these must be the
+ * (possibly mapped) characters that stopped the recording.
+ */
+ len = STRLEN(p);
+ if ((int)len >= last_recorded_len) {
+ len -= last_recorded_len;
+ p[len] = NUL;
+ }
+
+ /*
+ * When stopping recording from Insert mode with CTRL-O q, also remove the
+ * CTRL-O.
+ */
+ if (len > 0 && restart_edit != 0 && p[len - 1] == Ctrl_O)
+ p[len - 1] = NUL;
+
+ return p;
+}
+
+/*
+ * Return the contents of the redo buffer as a single string.
+ * K_SPECIAL and CSI in the returned string are escaped.
+ */
+char_u * get_inserted() {
+ 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(buf, s, slen)
+struct buffheader *buf;
+char_u *s;
+long slen; /* length of "s" or -1 */
+{
+ struct buffblock *p;
+ long_u len;
+
+ if (slen < 0)
+ slen = (long)STRLEN(s);
+ if (slen == 0) /* don't add empty strings */
+ return;
+
+ 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"));
+ return;
+ } else if (buf->bh_index != 0)
+ mch_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_index = 0;
+
+ if (buf->bh_space >= (int)slen) {
+ len = (long_u)STRLEN(buf->bh_curr->b_str);
+ vim_strncpy(buf->bh_curr->b_str + len, s, (size_t)slen);
+ buf->bh_space -= slen;
+ } else {
+ if (slen < MINIMAL_SIZE)
+ len = MINIMAL_SIZE;
+ else
+ len = slen;
+ p = (struct buffblock *)lalloc((long_u)(sizeof(struct buffblock) + len),
+ TRUE);
+ if (p == NULL)
+ return; /* no space, just forget it */
+ buf->bh_space = (int)(len - slen);
+ vim_strncpy(p->b_str, s, (size_t)slen);
+
+ p->b_next = buf->bh_curr->b_next;
+ buf->bh_curr->b_next = p;
+ buf->bh_curr = p;
+ }
+ return;
+}
+
+/*
+ * Add number "n" to buffer "buf".
+ */
+static void add_num_buff(buf, n)
+struct buffheader *buf;
+long n;
+{
+ char_u number[32];
+
+ sprintf((char *)number, "%ld", n);
+ add_buff(buf, number, -1L);
+}
+
+/*
+ * Add character 'c' to buffer "buf".
+ * Translates special keys, NUL, CSI, K_SPECIAL and multibyte characters.
+ */
+static void add_char_buff(buf, c)
+struct buffheader *buf;
+int c;
+{
+ char_u bytes[MB_MAXBYTES + 1];
+ int len;
+ int i;
+ char_u temp[4];
+
+ if (IS_SPECIAL(c))
+ len = 1;
+ else
+ len = (*mb_char2bytes)(c, bytes);
+ for (i = 0; i < len; ++i) {
+ if (!IS_SPECIAL(c))
+ c = bytes[i];
+
+ if (IS_SPECIAL(c) || c == K_SPECIAL || c == NUL) {
+ /* translate special key code into three byte sequence */
+ temp[0] = K_SPECIAL;
+ temp[1] = K_SECOND(c);
+ temp[2] = K_THIRD(c);
+ temp[3] = NUL;
+ } else {
+ temp[0] = c;
+ temp[1] = NUL;
+ }
+ add_buff(buf, temp, -1L);
+ }
+}
+
+/*
+ * Get one byte from the stuff buffer.
+ * If advance == TRUE go to the next char.
+ * No translation is done K_SPECIAL and CSI are escaped.
+ */
+static int read_stuff(advance)
+int advance;
+{
+ char_u c;
+ struct buffblock *curr;
+
+ if (stuffbuff.bh_first.b_next == NULL) /* buffer is empty */
+ return NUL;
+
+ curr = stuffbuff.bh_first.b_next;
+ c = curr->b_str[stuffbuff.bh_index];
+
+ if (advance) {
+ if (curr->b_str[++stuffbuff.bh_index] == NUL) {
+ stuffbuff.bh_first.b_next = curr->b_next;
+ vim_free(curr);
+ stuffbuff.bh_index = 0;
+ }
+ }
+ return c;
+}
+
+/*
+ * Prepare the stuff buffer for reading (if it contains something).
+ */
+static void start_stuff() {
+ if (stuffbuff.bh_first.b_next != NULL) {
+ stuffbuff.bh_curr = &(stuffbuff.bh_first);
+ stuffbuff.bh_space = 0;
+ }
+}
+
+/*
+ * Return TRUE if the stuff buffer is empty.
+ */
+int stuff_empty() {
+ return stuffbuff.bh_first.b_next == NULL;
+}
+
+/*
+ * Set a typeahead character that won't be flushed.
+ */
+void typeahead_noflush(c)
+int c;
+{
+ typeahead_char = c;
+}
+
+/*
+ * Remove the contents of the stuff buffer and the mapped characters in the
+ * 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(flush_typeahead)
+int flush_typeahead;
+{
+ init_typebuf();
+
+ start_stuff();
+ while (read_stuff(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 */
+ typebuf.tb_off += typebuf.tb_maplen;
+ typebuf.tb_len -= typebuf.tb_maplen;
+ }
+ typebuf.tb_maplen = 0;
+ typebuf.tb_silent = 0;
+ cmd_silent = FALSE;
+ typebuf.tb_no_abbr_cnt = 0;
+}
+
+/*
+ * The previous contents of the redo buffer is kept in old_redobuffer.
+ * This is used for the CTRL-O <.> command in insert mode.
+ */
+void ResetRedobuff() {
+ if (!block_redo) {
+ free_buff(&old_redobuff);
+ old_redobuff = redobuff;
+ redobuff.bh_first.b_next = NULL;
+ }
+}
+
+/*
+ * Discard the contents of the redo buffer and restore the previous redo
+ * buffer.
+ */
+void CancelRedo() {
+ if (!block_redo) {
+ free_buff(&redobuff);
+ redobuff = old_redobuff;
+ old_redobuff.bh_first.b_next = NULL;
+ start_stuff();
+ while (read_stuff(TRUE) != NUL)
+ ;
+ }
+}
+
+/*
+ * 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() {
+ 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);
+ vim_free(s);
+ }
+ }
+}
+
+/*
+ * Restore redobuff and old_redobuff from save_redobuff and save_old_redobuff.
+ * Used after executing autocommands and user functions.
+ */
+void restoreRedobuff() {
+ if (--save_level == 0) {
+ free_buff(&redobuff);
+ redobuff = save_redobuff;
+ free_buff(&old_redobuff);
+ old_redobuff = save_old_redobuff;
+ }
+}
+
+/*
+ * Append "s" to the redo buffer.
+ * K_SPECIAL and CSI should already have been escaped.
+ */
+void AppendToRedobuff(s)
+char_u *s;
+{
+ if (!block_redo)
+ add_buff(&redobuff, s, -1L);
+}
+
+/*
+ * Append to Redo buffer literally, escaping special characters with CTRL-V.
+ * K_SPECIAL and CSI are escaped as well.
+ */
+void AppendToRedobuffLit(str, len)
+char_u *str;
+int len; /* length of "str" or -1 for up to the NUL */
+{
+ char_u *s = str;
+ int c;
+ char_u *start;
+
+ if (block_redo)
+ return;
+
+ 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 /* EBCDIC: all chars above space are normal */
+ && (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)
+ add_buff(&redobuff, start, (long)(s - start));
+
+ if (*s == NUL || (len >= 0 && s - 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 == '^')))
+ add_char_buff(&redobuff, Ctrl_V);
+
+ /* CTRL-V '0' must be inserted as CTRL-V 048 (EBCDIC: xf0) */
+ if (*s == NUL && c == '0')
+ add_buff(&redobuff, (char_u *)"048", 3L);
+ else
+ add_char_buff(&redobuff, c);
+ }
+}
+
+/*
+ * Append a character to the redo buffer.
+ * Translates special keys, NUL, CSI, K_SPECIAL and multibyte characters.
+ */
+void AppendCharToRedobuff(c)
+int c;
+{
+ if (!block_redo)
+ add_char_buff(&redobuff, c);
+}
+
+/*
+ * Append a number to the redo buffer.
+ */
+void AppendNumberToRedobuff(n)
+long n;
+{
+ if (!block_redo)
+ add_num_buff(&redobuff, n);
+}
+
+/*
+ * Append string "s" to the stuff buffer.
+ * CSI and K_SPECIAL must already have been escaped.
+ */
+void stuffReadbuff(s)
+char_u *s;
+{
+ add_buff(&stuffbuff, s, -1L);
+}
+
+void stuffReadbuffLen(s, len)
+char_u *s;
+long len;
+{
+ add_buff(&stuffbuff, s, len);
+}
+
+/*
+ * Stuff "s" into the stuff buffer, leaving special key codes unmodified and
+ * escaping other K_SPECIAL and CSI bytes.
+ * Change CR, LF and ESC into a space.
+ */
+void stuffReadbuffSpec(s)
+char_u *s;
+{
+ int c;
+
+ while (*s != NUL) {
+ if (*s == K_SPECIAL && s[1] != NUL && s[2] != NUL) {
+ /* Insert special key literally. */
+ stuffReadbuffLen(s, 3L);
+ s += 3;
+ } else {
+ c = mb_ptr2char_adv(&s);
+ if (c == CAR || c == NL || c == ESC)
+ c = ' ';
+ stuffcharReadbuff(c);
+ }
+ }
+}
+
+/*
+ * Append a character to the stuff buffer.
+ * Translates special keys, NUL, CSI, K_SPECIAL and multibyte characters.
+ */
+void stuffcharReadbuff(c)
+int c;
+{
+ add_char_buff(&stuffbuff, c);
+}
+
+/*
+ * Append a number to the stuff buffer.
+ */
+void stuffnumReadbuff(n)
+long n;
+{
+ add_num_buff(&stuffbuff, 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(init, old_redo)
+int init;
+int old_redo;
+{
+ static struct buffblock *bp;
+ static char_u *p;
+ int c;
+ int n;
+ char_u buf[MB_MAXBYTES + 1];
+ int i;
+
+ if (init) {
+ if (old_redo)
+ bp = old_redobuff.bh_first.b_next;
+ else
+ bp = redobuff.bh_first.b_next;
+ if (bp == NULL)
+ return FAIL;
+ p = bp->b_str;
+ return OK;
+ }
+ if ((c = *p) != NUL) {
+ /* Reverse the conversion done by add_char_buff() */
+ /* For a multi-byte character get all the bytes and return the
+ * converted character. */
+ if (has_mbyte && (c != K_SPECIAL || p[1] == KS_SPECIAL))
+ n = MB_BYTE2LEN_CHECK(c);
+ else
+ n = 1;
+ for (i = 0;; ++i) {
+ if (c == K_SPECIAL) { /* special key or escaped K_SPECIAL */
+ c = TO_SPECIAL(p[1], p[2]);
+ p += 2;
+ }
+ if (*++p == NUL && bp->b_next != NULL) {
+ bp = bp->b_next;
+ p = bp->b_str;
+ }
+ buf[i] = c;
+ if (i == n - 1) { /* last byte of a character */
+ if (n != 1)
+ c = (*mb_ptr2char)(buf);
+ break;
+ }
+ c = *p;
+ if (c == NUL) /* cannot happen? */
+ break;
+ }
+ }
+
+ 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(old_redo)
+int old_redo;
+{
+ int c;
+
+ while ((c = read_redo(FALSE, old_redo)) != NUL)
+ stuffcharReadbuff(c);
+}
+
+/*
+ * Stuff the redo buffer into the stuffbuff.
+ * 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(count, old_redo)
+long count;
+int old_redo;
+{
+ int c;
+
+ /* init the pointers; return if nothing to redo */
+ if (read_redo(TRUE, old_redo) == FAIL)
+ return FAIL;
+
+ c = read_redo(FALSE, old_redo);
+
+ /* copy the buffer name, if present */
+ if (c == '"') {
+ add_buff(&stuffbuff, (char_u *)"\"", 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(&stuffbuff, c);
+ 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);
+ }
+
+ /* try to enter the count (in place of a previous count) */
+ if (count) {
+ while (VIM_ISDIGIT(c)) /* skip "old" count */
+ c = read_redo(FALSE, old_redo);
+ add_num_buff(&stuffbuff, count);
+ }
+
+ /* copy from the redo buffer into the stuff buffer */
+ add_char_buff(&stuffbuff, c);
+ copy_redo(old_redo);
+ return OK;
+}
+
+/*
+ * Repeat the last insert (R, o, O, a, A, i or I command) by stuffing
+ * the redo buffer into the stuffbuff.
+ * return FAIL for failure, OK otherwise
+ */
+int start_redo_ins() {
+ int c;
+
+ if (read_redo(TRUE, FALSE) == FAIL)
+ return FAIL;
+ start_stuff();
+
+ /* 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')
+ stuffReadbuff(NL_STR);
+ break;
+ }
+ }
+
+ /* copy the typed text from the redo buffer into the stuff buffer */
+ copy_redo(FALSE);
+ block_redo = TRUE;
+ return OK;
+}
+
+void stop_redo_ins() {
+ block_redo = FALSE;
+}
+
+/*
+ * Initialize typebuf.tb_buf to point to typebuf_init.
+ * alloc() cannot be used here: In out-of-memory situations it would
+ * be impossible to type anything.
+ */
+static void init_typebuf() {
+ if (typebuf.tb_buf == NULL) {
+ typebuf.tb_buf = typebuf_init;
+ typebuf.tb_noremap = noremapbuf_init;
+ typebuf.tb_buflen = TYPELEN_INIT;
+ typebuf.tb_len = 0;
+ typebuf.tb_off = 0;
+ typebuf.tb_change_cnt = 1;
+ }
+}
+
+/*
+ * insert a string in position 'offset' in the typeahead buffer (for "@r"
+ * and ":normal" command, vgetorpeek() and check_termcode())
+ *
+ * If noremap is REMAP_YES, new string can be mapped again.
+ * If noremap is REMAP_NONE, new string cannot be mapped again.
+ * If noremap is REMAP_SKIP, fist char of new string cannot be mapped again,
+ * but abbreviations are allowed.
+ * If noremap is REMAP_SCRIPT, new string cannot be mapped again, except for
+ * script-local mappings.
+ * If noremap is > 0, that many characters of the new string cannot be mapped.
+ *
+ * If nottyped is TRUE, the string does not return KeyTyped (don't use when
+ * offset is non-zero!).
+ *
+ * If silent is TRUE, cmd_silent is set when the characters are obtained.
+ *
+ * return FAIL for failure, OK otherwise
+ */
+int ins_typebuf(str, noremap, offset, nottyped, silent)
+char_u *str;
+int noremap;
+int offset;
+int nottyped;
+int silent;
+{
+ char_u *s1, *s2;
+ int newlen;
+ int addlen;
+ int i;
+ int newoff;
+ int val;
+ int nrm;
+
+ init_typebuf();
+ if (++typebuf.tb_change_cnt == 0)
+ typebuf.tb_change_cnt = 1;
+
+ 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) {
+ typebuf.tb_off -= addlen;
+ mch_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 {
+ newoff = MAXMAPLEN + 4;
+ newlen = typebuf.tb_len + addlen + newoff + 4 * (MAXMAPLEN + 4);
+ if (newlen < 0) { /* string is getting too long */
+ EMSG(_(e_toocompl)); /* also calls flush_buffers */
+ setcursor();
+ return FAIL;
+ }
+ s1 = alloc(newlen);
+ if (s1 == NULL) /* out of memory */
+ return FAIL;
+ s2 = alloc(newlen);
+ if (s2 == NULL) { /* out of memory */
+ vim_free(s1);
+ return FAIL;
+ }
+ typebuf.tb_buflen = newlen;
+
+ /* copy the old chars, before the insertion point */
+ mch_memmove(s1 + newoff, typebuf.tb_buf + typebuf.tb_off,
+ (size_t)offset);
+ /* copy the new chars */
+ mch_memmove(s1 + newoff + offset, str, (size_t)addlen);
+ /* copy the old chars, after the insertion point, including the NUL at
+ * the end */
+ mch_memmove(s1 + newoff + offset + addlen,
+ typebuf.tb_buf + typebuf.tb_off + offset,
+ (size_t)(typebuf.tb_len - offset + 1));
+ if (typebuf.tb_buf != typebuf_init)
+ vim_free(typebuf.tb_buf);
+ typebuf.tb_buf = s1;
+
+ mch_memmove(s2 + newoff, typebuf.tb_noremap + typebuf.tb_off,
+ (size_t)offset);
+ mch_memmove(s2 + newoff + offset + addlen,
+ typebuf.tb_noremap + typebuf.tb_off + offset,
+ (size_t)(typebuf.tb_len - offset));
+ if (typebuf.tb_noremap != noremapbuf_init)
+ vim_free(typebuf.tb_noremap);
+ typebuf.tb_noremap = s2;
+
+ typebuf.tb_off = newoff;
+ }
+ typebuf.tb_len += addlen;
+
+ /* If noremap == REMAP_SCRIPT: do remap script-local mappings. */
+ if (noremap == REMAP_SCRIPT)
+ val = RM_SCRIPT;
+ else if (noremap == REMAP_SKIP)
+ val = RM_ABBR;
+ else
+ val = RM_NONE;
+
+ /*
+ * Adjust typebuf.tb_noremap[] for the new characters:
+ * If noremap == REMAP_NONE or REMAP_SCRIPT: new characters are
+ * (sometimes) not remappable
+ * If noremap == REMAP_YES: all the new characters are mappable
+ * If noremap > 0: "noremap" characters are not remappable, the rest
+ * mappable
+ */
+ if (noremap == REMAP_SKIP)
+ nrm = 1;
+ else if (noremap < 0)
+ nrm = addlen;
+ else
+ nrm = noremap;
+ for (i = 0; i < addlen; ++i)
+ typebuf.tb_noremap[typebuf.tb_off + i + offset] =
+ (--nrm >= 0) ? val : RM_YES;
+
+ /* tb_maplen and tb_silent only remember the length of mapped and/or
+ * silent mappings at the start of the buffer, assuming that a mapped
+ * sequence doesn't result in typed characters. */
+ if (nottyped || typebuf.tb_maplen > offset)
+ typebuf.tb_maplen += addlen;
+ if (silent || typebuf.tb_silent > offset) {
+ typebuf.tb_silent += addlen;
+ cmd_silent = TRUE;
+ }
+ if (typebuf.tb_no_abbr_cnt && offset == 0) /* and not used for abbrev.s */
+ typebuf.tb_no_abbr_cnt += addlen;
+
+ return OK;
+}
+
+/*
+ * Put character "c" back into the typeahead buffer.
+ * Can be used for a character obtained by vgetc() that needs to be put back.
+ * Uses cmd_silent, KeyTyped and KeyNoremap to restore the flags belonging to
+ * the char.
+ */
+void ins_char_typebuf(c)
+int c;
+{
+ char_u buf[MB_MAXBYTES + 1];
+ if (IS_SPECIAL(c)) {
+ buf[0] = K_SPECIAL;
+ buf[1] = K_SECOND(c);
+ buf[2] = K_THIRD(c);
+ buf[3] = NUL;
+ } else {
+ buf[(*mb_char2bytes)(c, buf)] = NUL;
+ }
+ (void)ins_typebuf(buf, KeyNoremap, 0, !KeyTyped, cmd_silent);
+}
+
+/*
+ * Return TRUE if the typeahead buffer was changed (while waiting for a
+ * character to arrive). Happens when a message was received from a client or
+ * from feedkeys().
+ * But check in a more generic way to avoid trouble: When "typebuf.tb_buf"
+ * changed it was reallocated and the old pointer can no longer be used.
+ * Or "typebuf.tb_off" may have been changed and we would overwrite characters
+ * that was just added.
+ */
+int typebuf_changed(tb_change_cnt)
+int tb_change_cnt; /* old value of typebuf.tb_change_cnt */
+{
+ return tb_change_cnt != 0 && (typebuf.tb_change_cnt != tb_change_cnt
+ || typebuf_was_filled
+ );
+}
+
+/*
+ * Return TRUE if there are no characters in the typeahead buffer that have
+ * not been typed (result from a mapping or come from ":normal").
+ */
+int typebuf_typed() {
+ return typebuf.tb_maplen == 0;
+}
+
+/*
+ * Return the number of characters that are mapped (or not typed).
+ */
+int typebuf_maplen() {
+ return typebuf.tb_maplen;
+}
+
+/*
+ * remove "len" characters from typebuf.tb_buf[typebuf.tb_off + offset]
+ */
+void del_typebuf(len, offset)
+int len;
+int offset;
+{
+ int i;
+
+ if (len == 0)
+ return; /* nothing to do */
+
+ typebuf.tb_len -= len;
+
+ /*
+ * Easy case: Just increase typebuf.tb_off.
+ */
+ if (offset == 0 && typebuf.tb_buflen - (typebuf.tb_off + len)
+ >= 3 * MAXMAPLEN + 3)
+ typebuf.tb_off += len;
+ /*
+ * Have to move the characters in typebuf.tb_buf[] and typebuf.tb_noremap[]
+ */
+ else {
+ i = typebuf.tb_off + offset;
+ /*
+ * Leave some extra room at the end to avoid reallocation.
+ */
+ if (typebuf.tb_off > MAXMAPLEN) {
+ mch_memmove(typebuf.tb_buf + MAXMAPLEN,
+ typebuf.tb_buf + typebuf.tb_off, (size_t)offset);
+ mch_memmove(typebuf.tb_noremap + MAXMAPLEN,
+ typebuf.tb_noremap + typebuf.tb_off, (size_t)offset);
+ typebuf.tb_off = MAXMAPLEN;
+ }
+ /* adjust typebuf.tb_buf (include the NUL at the end) */
+ mch_memmove(typebuf.tb_buf + typebuf.tb_off + offset,
+ typebuf.tb_buf + i + len,
+ (size_t)(typebuf.tb_len - offset + 1));
+ /* adjust typebuf.tb_noremap[] */
+ mch_memmove(typebuf.tb_noremap + typebuf.tb_off + offset,
+ typebuf.tb_noremap + i + len,
+ (size_t)(typebuf.tb_len - offset));
+ }
+
+ if (typebuf.tb_maplen > offset) { /* adjust tb_maplen */
+ if (typebuf.tb_maplen < offset + len)
+ typebuf.tb_maplen = offset;
+ else
+ typebuf.tb_maplen -= len;
+ }
+ if (typebuf.tb_silent > offset) { /* adjust tb_silent */
+ if (typebuf.tb_silent < offset + len)
+ typebuf.tb_silent = offset;
+ else
+ typebuf.tb_silent -= len;
+ }
+ if (typebuf.tb_no_abbr_cnt > offset) { /* adjust tb_no_abbr_cnt */
+ if (typebuf.tb_no_abbr_cnt < offset + len)
+ typebuf.tb_no_abbr_cnt = offset;
+ else
+ typebuf.tb_no_abbr_cnt -= len;
+ }
+
+ /* 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.tb_change_cnt = 1;
+}
+
+/*
+ * Write typed characters to script file.
+ * If recording is on put the character in the recordbuffer.
+ */
+static void gotchars(chars, len)
+char_u *chars;
+int len;
+{
+ char_u *s = chars;
+ int c;
+ char_u buf[2];
+ int todo = len;
+
+ /* remember how many chars were last recorded */
+ if (Recording)
+ last_recorded_len += len;
+
+ buf[1] = NUL;
+ while (todo--) {
+ /* Handle one byte at a time; no translation to be done. */
+ c = *s++;
+ updatescript(c);
+
+ if (Recording) {
+ buf[0] = c;
+ add_buff(&recordbuff, buf, 1L);
+ }
+ }
+ may_sync_undo();
+
+ /* output "debug mode" message next time in debug mode */
+ debug_did_msg = FALSE;
+
+ /* Since characters have been typed, consider the following to be in
+ * another mapping. Search string will be kept in history. */
+ ++maptick;
+}
+
+/*
+ * Sync undo. Called when typed characters are obtained from the typeahead
+ * buffer, or when a menu is used.
+ * Do not sync:
+ * - In Insert mode, unless cursor key has been used.
+ * - While reading a script file.
+ * - When no_u_sync is non-zero.
+ */
+static void may_sync_undo() {
+ if ((!(State & (INSERT + CMDLINE)) || arrow_used)
+ && scriptin[curscript] == NULL)
+ u_sync(FALSE);
+}
+
+/*
+ * Make "typebuf" empty and allocate new buffers.
+ * Returns FAIL when out of memory.
+ */
+int alloc_typebuf() {
+ typebuf.tb_buf = alloc(TYPELEN_INIT);
+ typebuf.tb_noremap = alloc(TYPELEN_INIT);
+ if (typebuf.tb_buf == NULL || typebuf.tb_noremap == NULL) {
+ free_typebuf();
+ return FAIL;
+ }
+ typebuf.tb_buflen = TYPELEN_INIT;
+ typebuf.tb_off = 0;
+ typebuf.tb_len = 0;
+ typebuf.tb_maplen = 0;
+ typebuf.tb_silent = 0;
+ typebuf.tb_no_abbr_cnt = 0;
+ if (++typebuf.tb_change_cnt == 0)
+ typebuf.tb_change_cnt = 1;
+ return OK;
+}
+
+/*
+ * Free the buffers of "typebuf".
+ */
+void free_typebuf() {
+ if (typebuf.tb_buf == typebuf_init)
+ EMSG2(_(e_intern2), "Free typebuf 1");
+ else
+ vim_free(typebuf.tb_buf);
+ if (typebuf.tb_noremap == noremapbuf_init)
+ EMSG2(_(e_intern2), "Free typebuf 2");
+ else
+ vim_free(typebuf.tb_noremap);
+}
+
+/*
+ * When doing ":so! file", the current typeahead needs to be saved, and
+ * restored when "file" has been read completely.
+ */
+static typebuf_T saved_typebuf[NSCRIPT];
+
+int save_typebuf() {
+ init_typebuf();
+ saved_typebuf[curscript] = typebuf;
+ /* If out of memory: restore typebuf and close file. */
+ if (alloc_typebuf() == FAIL) {
+ closescript();
+ return FAIL;
+ }
+ return OK;
+}
+
+static int old_char = -1; /* character put back by vungetc() */
+static int old_mod_mask; /* mod_mask for ungotten character */
+static int old_mouse_row; /* mouse_row related to old_char */
+static int old_mouse_col; /* mouse_col related to old_char */
+
+
+/*
+ * Save all three kinds of typeahead, so that the user must type at a prompt.
+ */
+void save_typeahead(tp)
+tasave_T *tp;
+{
+ tp->save_typebuf = typebuf;
+ tp->typebuf_valid = (alloc_typebuf() == OK);
+ if (!tp->typebuf_valid)
+ typebuf = tp->save_typebuf;
+
+ tp->old_char = old_char;
+ tp->old_mod_mask = old_mod_mask;
+ old_char = -1;
+
+ tp->save_stuffbuff = stuffbuff;
+ stuffbuff.bh_first.b_next = NULL;
+# ifdef USE_INPUT_BUF
+ tp->save_inputbuf = get_input_buf();
+# endif
+}
+
+/*
+ * Restore the typeahead to what it was before calling save_typeahead().
+ * The allocated memory is freed, can only be called once!
+ */
+void restore_typeahead(tp)
+tasave_T *tp;
+{
+ if (tp->typebuf_valid) {
+ free_typebuf();
+ typebuf = tp->save_typebuf;
+ }
+
+ old_char = tp->old_char;
+ old_mod_mask = tp->old_mod_mask;
+
+ free_buff(&stuffbuff);
+ stuffbuff = tp->save_stuffbuff;
+# ifdef USE_INPUT_BUF
+ set_input_buf(tp->save_inputbuf);
+# endif
+}
+
+/*
+ * Open a new script file for the ":source!" command.
+ */
+void openscript(name, directly)
+char_u *name;
+int directly; /* when TRUE execute directly */
+{
+ if (curscript + 1 == NSCRIPT) {
+ EMSG(_(e_nesting));
+ return;
+ }
+ if (ignore_script)
+ /* Not reading from script, also don't open one. Warning message? */
+ return;
+
+ if (scriptin[curscript] != NULL) /* already reading script */
+ ++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;
+ return;
+ }
+ if (save_typebuf() == FAIL)
+ return;
+
+ /*
+ * Execute the commands from the file right now when using ":source!"
+ * after ":global" or ":argdo" or in a loop. Also when another command
+ * follows. This means the display won't be updated. Don't do this
+ * always, "make test" would fail.
+ */
+ if (directly) {
+ oparg_T oa;
+ int oldcurscript;
+ int save_State = State;
+ int save_restart_edit = restart_edit;
+ int save_insertmode = p_im;
+ int save_finish_op = finish_op;
+ int save_msg_scroll = msg_scroll;
+
+ State = NORMAL;
+ msg_scroll = FALSE; /* no msg scrolling in Normal mode */
+ restart_edit = 0; /* don't go to Insert mode */
+ p_im = FALSE; /* don't use 'insertmode' */
+ clear_oparg(&oa);
+ finish_op = FALSE;
+
+ oldcurscript = curscript;
+ do {
+ update_topline_cursor(); /* update cursor position and topline */
+ normal_cmd(&oa, FALSE); /* execute one command */
+ vpeekc(); /* check for end of file */
+ } while (scriptin[oldcurscript] != NULL);
+
+ State = save_State;
+ msg_scroll = save_msg_scroll;
+ restart_edit = save_restart_edit;
+ p_im = save_insertmode;
+ finish_op = save_finish_op;
+ }
+}
+
+/*
+ * Close the currently active input script.
+ */
+static void closescript() {
+ free_typebuf();
+ typebuf = saved_typebuf[curscript];
+
+ fclose(scriptin[curscript]);
+ scriptin[curscript] = NULL;
+ if (curscript > 0)
+ --curscript;
+}
+
+#if defined(EXITFREE) || defined(PROTO)
+void close_all_scripts() {
+ while (scriptin[0] != NULL)
+ closescript();
+}
+
+#endif
+
+/*
+ * Return TRUE when reading keys from a script file.
+ */
+int using_script() {
+ return scriptin[curscript] != NULL;
+}
+
+/*
+ * This function is called just before doing a blocking wait. Thus after
+ * waiting 'updatetime' for a character to arrive.
+ */
+void before_blocking() {
+ updatescript(0);
+ if (may_garbage_collect)
+ garbage_collect();
+}
+
+/*
+ * 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(c)
+int c;
+{
+ static int count = 0;
+
+ if (c && scriptout)
+ putc(c, scriptout);
+ if (c == 0 || (p_uc > 0 && ++count >= p_uc)) {
+ ml_sync_all(c == 0, TRUE);
+ count = 0;
+ }
+}
+
+/*
+ * Get the next input character.
+ * Can return a special key or a multi-byte character.
+ * Can return NUL when called recursively, use safe_vgetc() if that's not
+ * wanted.
+ * This translates escaped K_SPECIAL and CSI bytes to a K_SPECIAL or CSI byte.
+ * Collects the bytes of a multibyte character into the whole character.
+ * Returns the modifiers in the global "mod_mask".
+ */
+int vgetc() {
+ int c, c2;
+ int n;
+ 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();
+
+ /*
+ * If a character was put back with vungetc, it was already processed.
+ * Return it directly.
+ */
+ if (old_char != -1) {
+ c = old_char;
+ old_char = -1;
+ mod_mask = old_mod_mask;
+ mouse_row = old_mouse_row;
+ mouse_col = old_mouse_col;
+ } else {
+ mod_mask = 0x0;
+ last_recorded_len = 0;
+ for (;; ) { /* this is done twice if there are modifiers */
+ if (mod_mask) { /* no mapping after modifier has been read */
+ ++no_mapping;
+ ++allow_keys;
+ }
+ c = vgetorpeek(TRUE);
+ if (mod_mask) {
+ --no_mapping;
+ --allow_keys;
+ }
+
+ /* 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;
+ if (c2 == KS_MODIFIER) {
+ mod_mask = c;
+ continue;
+ }
+ c = TO_SPECIAL(c2, c);
+
+ }
+
+ /* a keypad or special function key was not mapped, use it like
+ * its ASCII equivalent */
+ switch (c) {
+ case K_KPLUS: c = '+'; break;
+ case K_KMINUS: c = '-'; break;
+ case K_KDIVIDE: c = '/'; break;
+ case K_KMULTIPLY: c = '*'; break;
+ case K_KENTER: c = CAR; break;
+ case K_KPOINT:
+ c = '.'; break;
+ case K_K0: c = '0'; break;
+ case K_K1: c = '1'; break;
+ case K_K2: c = '2'; break;
+ case K_K3: c = '3'; break;
+ case K_K4: c = '4'; break;
+ case K_K5: c = '5'; break;
+ case K_K6: c = '6'; break;
+ case K_K7: c = '7'; break;
+ case K_K8: c = '8'; break;
+ case K_K9: c = '9'; break;
+
+ case K_XHOME:
+ case K_ZHOME: if (mod_mask == MOD_MASK_SHIFT) {
+ c = K_S_HOME;
+ mod_mask = 0;
+ } else if (mod_mask == MOD_MASK_CTRL) {
+ c = K_C_HOME;
+ mod_mask = 0;
+ } else
+ c = K_HOME;
+ break;
+ case K_XEND:
+ case K_ZEND: if (mod_mask == MOD_MASK_SHIFT) {
+ c = K_S_END;
+ mod_mask = 0;
+ } else if (mod_mask == MOD_MASK_CTRL) {
+ c = K_C_END;
+ mod_mask = 0;
+ } else
+ c = K_END;
+ break;
+
+ case K_XUP: c = K_UP; break;
+ case K_XDOWN: c = K_DOWN; break;
+ case K_XLEFT: c = K_LEFT; break;
+ case K_XRIGHT: c = K_RIGHT; break;
+ }
+
+ /* For a multi-byte character get all the bytes and return the
+ * converted character.
+ * Note: This will loop until enough bytes are received!
+ */
+ if (has_mbyte && (n = MB_BYTE2LEN_CHECK(c)) > 1) {
+ ++no_mapping;
+ buf[0] = c;
+ for (i = 1; i < n; ++i) {
+ buf[i] = vgetorpeek(TRUE);
+ if (buf[i] == K_SPECIAL
+ ) {
+ /* Must be a K_SPECIAL - KS_SPECIAL - KE_FILLER sequence,
+ * which represents a K_SPECIAL (0x80),
+ * or a CSI - KS_EXTRA - KE_CSI sequence, which represents
+ * a CSI (0x9B),
+ * of a K_SPECIAL - KS_EXTRA - KE_CSI, which is CSI too. */
+ c = vgetorpeek(TRUE);
+ if (vgetorpeek(TRUE) == (int)KE_CSI && c == KS_EXTRA)
+ buf[i] = CSI;
+ }
+ }
+ --no_mapping;
+ c = (*mb_ptr2char)(buf);
+ }
+
+ break;
+ }
+ }
+
+ /*
+ * In the main loop "may_garbage_collect" can be set to do garbage
+ * collection in the first next vgetc(). It's disabled after that to
+ * avoid internally used Lists and Dicts to be freed.
+ */
+ may_garbage_collect = FALSE;
+
+ return c;
+}
+
+/*
+ * Like vgetc(), but never return a NUL when called recursively, get a key
+ * directly from the user (ignoring typeahead).
+ */
+int safe_vgetc() {
+ int c;
+
+ c = vgetc();
+ if (c == NUL)
+ c = get_keystroke();
+ return c;
+}
+
+/*
+ * Like safe_vgetc(), but loop to handle K_IGNORE.
+ * Also ignore scrollbar events.
+ */
+int plain_vgetc() {
+ int c;
+
+ do {
+ c = safe_vgetc();
+ } while (c == K_IGNORE || c == K_VER_SCROLLBAR || c == K_HOR_SCROLLBAR);
+ return c;
+}
+
+/*
+ * 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!.
+ */
+int vpeekc() {
+ if (old_char != -1)
+ return old_char;
+ return vgetorpeek(FALSE);
+}
+
+/*
+ * Like vpeekc(), but don't allow mapping. Do allow checking for terminal
+ * codes.
+ */
+int vpeekc_nomap() {
+ int c;
+
+ ++no_mapping;
+ ++allow_keys;
+ c = vpeekc();
+ --no_mapping;
+ --allow_keys;
+ return c;
+}
+
+/*
+ * Check if any character is available, also half an escape sequence.
+ * Trick: when no typeahead found, but there is something in the typeahead
+ * buffer, it must be an ESC that is recognized as the start of a key code.
+ */
+int vpeekc_any() {
+ int c;
+
+ c = vpeekc();
+ if (c == NUL && typebuf.tb_len > 0)
+ c = ESC;
+ return c;
+}
+
+/*
+ * Call vpeekc() without causing anything to be mapped.
+ * Return TRUE if a character is available, FALSE otherwise.
+ */
+int char_avail() {
+ int retval;
+
+ ++no_mapping;
+ retval = vpeekc();
+ --no_mapping;
+ return retval != NUL;
+}
+
+void vungetc(c) /* unget one character (can only be done once!) */
+int c;
+{
+ old_char = c;
+ old_mod_mask = mod_mask;
+ old_mouse_row = mouse_row;
+ 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.
+ */
+static int vgetorpeek(advance)
+int advance;
+{
+ int c, c1;
+ int keylen;
+ char_u *s;
+ mapblock_T *mp;
+ mapblock_T *mp2;
+ mapblock_T *mp_match;
+ int mp_match_len = 0;
+ int timedout = FALSE; /* waited for more than 1 second
+ for mapping to complete */
+ int mapdepth = 0; /* check for recursive mapping */
+ int mode_deleted = FALSE; /* set when mode has been deleted */
+ int local_State;
+ int mlen;
+ int max_mlen;
+ int i;
+ int new_wcol, new_wrow;
+ int n;
+ int nolmaplen;
+ int old_wcol, old_wrow;
+ int wait_tb_len;
+
+ /*
+ * This function doesn't work very well when called recursively. This may
+ * happen though, because of:
+ * 1. The call to add_to_showcmd(). char_avail() is then used to check if
+ * there is a character available, which calls this function. In that
+ * case we must return NUL, to indicate no character is available.
+ * 2. A GUI callback function writes to the screen, causing a
+ * wait_return().
+ * Using ":normal" can also do this, but it saves the typeahead buffer,
+ * thus it should be OK. But don't get a key from the user then.
+ */
+ if (vgetc_busy > 0
+ && ex_normal_busy == 0
+ )
+ return NUL;
+
+ local_State = get_real_state();
+
+ ++vgetc_busy;
+
+ if (advance)
+ KeyStuffed = FALSE;
+
+ init_typebuf();
+ start_stuff();
+ if (advance && typebuf.tb_maplen == 0)
+ Exec_reg = FALSE;
+ do {
+ /*
+ * get a character: 1. from the stuffbuffer
+ */
+ if (typeahead_char != 0) {
+ c = typeahead_char;
+ if (advance)
+ typeahead_char = 0;
+ } else
+ c = read_stuff(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;
+ }
+ if (typebuf.tb_no_abbr_cnt == 0)
+ typebuf.tb_no_abbr_cnt = 1; /* no abbreviations now */
+ } else {
+ /*
+ * Loop until we either find a matching mapped key, or we
+ * are sure that it is not a mapped key.
+ * If a mapped key sequence is found we go back to the start to
+ * try re-mapping.
+ */
+ for (;; ) {
+ /*
+ * ui_breakcheck() is slow, don't use it too often when
+ * inside a mapping. But call it each time for typed
+ * characters.
+ */
+ if (typebuf.tb_maplen)
+ line_breakcheck();
+ else
+ ui_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.
+ */
+ if ((c || typebuf.tb_maplen)
+ && (State & (INSERT + CMDLINE)))
+ c = ESC;
+ else
+ c = Ctrl_C;
+ flush_buffers(TRUE); /* flush all typeahead */
+
+ if (advance) {
+ /* Also record this character, it might be needed to
+ * get out of Insert mode. */
+ *typebuf.tb_buf = c;
+ gotchars(typebuf.tb_buf, 1);
+ }
+ cmd_silent = FALSE;
+
+ break;
+ } else if (typebuf.tb_len > 0) {
+ /*
+ * Check for a mappable key sequence.
+ * Walk through one maphash[] list until we find an
+ * entry that matches.
+ *
+ * Don't look for mappings if:
+ * - no_mapping set: mapping disabled (e.g. for CTRL-V)
+ * - maphash_valid not set: no mappings present.
+ * - typebuf.tb_buf[typebuf.tb_off] should not be remapped
+ * - in insert or cmdline mode and 'paste' option set
+ * - waiting for "hit return to continue" and CR or SPACE
+ * typed
+ * - waiting for a char with --more--
+ * - in Ctrl-X mode, and we get a valid char for that mode
+ */
+ mp = NULL;
+ max_mlen = 0;
+ c1 = typebuf.tb_buf[typebuf.tb_off];
+ if (no_mapping == 0 && maphash_valid
+ && (no_zero_mapping == 0 || c1 != '0')
+ && (typebuf.tb_maplen == 0
+ || (p_remap
+ && (typebuf.tb_noremap[typebuf.tb_off]
+ & (RM_NONE|RM_ABBR)) == 0))
+ && !(p_paste && (State & (INSERT + CMDLINE)))
+ && !(State == HITRETURN && (c1 == CAR || c1 == ' '))
+ && State != ASKMORE
+ && State != CONFIRM
+ && !((ctrl_x_mode != 0 && vim_is_ctrl_x_key(c1))
+ || ((compl_cont_status & CONT_LOCAL)
+ && (c1 == Ctrl_N || c1 == Ctrl_P)))
+ ) {
+ if (c1 == K_SPECIAL)
+ nolmaplen = 2;
+ else {
+ LANGMAP_ADJUST(c1, TRUE);
+ nolmaplen = 0;
+ }
+ /* First try buffer-local mappings. */
+ mp = curbuf->b_maphash[MAP_HASH(local_State, c1)];
+ mp2 = maphash[MAP_HASH(local_State, c1)];
+ if (mp == NULL) {
+ /* There are no buffer-local mappings. */
+ mp = mp2;
+ mp2 = NULL;
+ }
+ /*
+ * Loop until a partly matching mapping is found or
+ * all (local) mappings have been checked.
+ * The longest full match is remembered in "mp_match".
+ * A full match is only accepted if there is no partly
+ * match, so "aa" and "aaa" can both be mapped.
+ */
+ mp_match = NULL;
+ mp_match_len = 0;
+ for (; mp != NULL;
+ mp->m_next == NULL ? (mp = mp2, mp2 = NULL) :
+ (mp = mp->m_next)) {
+ /*
+ * Only consider an entry if the first character
+ * matches and it is for the current state.
+ * Skip ":lmap" mappings if keys were mapped.
+ */
+ if (mp->m_keys[0] == c1
+ && (mp->m_mode & local_State)
+ && ((mp->m_mode & LANGMAP) == 0
+ || typebuf.tb_maplen == 0)) {
+ int nomap = nolmaplen;
+ int c2;
+ /* find the match length of this mapping */
+ for (mlen = 1; mlen < typebuf.tb_len; ++mlen) {
+ c2 = typebuf.tb_buf[typebuf.tb_off + mlen];
+ if (nomap > 0)
+ --nomap;
+ else if (c2 == K_SPECIAL)
+ nomap = 2;
+ else
+ LANGMAP_ADJUST(c2, TRUE);
+ if (mp->m_keys[mlen] != c2)
+ break;
+ }
+
+ /* Don't allow mapping the first byte(s) of a
+ * multi-byte char. Happens when mapping
+ * <M-a> and then changing 'encoding'. */
+ if (has_mbyte && MB_BYTE2LEN(c1)
+ > (*mb_ptr2len)(mp->m_keys))
+ mlen = 0;
+ /*
+ * Check an entry whether it matches.
+ * - Full match: mlen == keylen
+ * - Partly match: mlen == typebuf.tb_len
+ */
+ keylen = mp->m_keylen;
+ if (mlen == keylen
+ || (mlen == typebuf.tb_len
+ && typebuf.tb_len < keylen)) {
+ /*
+ * If only script-local mappings are
+ * allowed, check if the mapping starts
+ * with K_SNR.
+ */
+ s = typebuf.tb_noremap + typebuf.tb_off;
+ if (*s == RM_SCRIPT
+ && (mp->m_keys[0] != K_SPECIAL
+ || mp->m_keys[1] != KS_EXTRA
+ || mp->m_keys[2]
+ != (int)KE_SNR))
+ continue;
+ /*
+ * If one of the typed keys cannot be
+ * remapped, skip the entry.
+ */
+ for (n = mlen; --n >= 0; )
+ if (*s++ & (RM_NONE|RM_ABBR))
+ break;
+ if (n >= 0)
+ continue;
+
+ if (keylen > typebuf.tb_len) {
+ if (!timedout && !(mp_match != NULL
+ && mp_match->m_nowait)) {
+ /* break at a partly match */
+ keylen = KEYLEN_PART_MAP;
+ break;
+ }
+ } else if (keylen > mp_match_len) {
+ /* 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;
+ }
+ }
+
+ /* If no partly match found, use the longest full
+ * match. */
+ if (keylen != KEYLEN_PART_MAP) {
+ mp = mp_match;
+ keylen = mp_match_len;
+ }
+ }
+
+ /* Check for match with 'pastetoggle' */
+ if (*p_pt != NUL && mp == NULL && (State & (INSERT|NORMAL))) {
+ for (mlen = 0; mlen < typebuf.tb_len && p_pt[mlen];
+ ++mlen)
+ if (p_pt[mlen] != typebuf.tb_buf[typebuf.tb_off
+ + mlen])
+ break;
+ if (p_pt[mlen] == NUL) { /* match */
+ /* write chars to script file(s) */
+ if (mlen > typebuf.tb_maplen)
+ gotchars(typebuf.tb_buf + typebuf.tb_off
+ + typebuf.tb_maplen,
+ mlen - typebuf.tb_maplen);
+
+ del_typebuf(mlen, 0); /* remove the chars */
+ set_option_value((char_u *)"paste",
+ (long)!p_paste, NULL, 0);
+ if (!(State & INSERT)) {
+ msg_col = 0;
+ msg_row = Rows - 1;
+ msg_clr_eos(); /* clear ruler */
+ }
+ showmode();
+ setcursor();
+ continue;
+ }
+ /* Need more chars for partly match. */
+ if (mlen == typebuf.tb_len)
+ keylen = KEYLEN_PART_KEY;
+ else if (max_mlen < mlen)
+ /* no match, may have to check for termcode at
+ * next character */
+ max_mlen = mlen + 1;
+ }
+
+ if ((mp == NULL || max_mlen >= mp_match_len)
+ && keylen != KEYLEN_PART_MAP) {
+ int save_keylen = keylen;
+
+ /*
+ * 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 = check_termcode(max_mlen + 1,
+ NULL, 0, NULL);
+
+ /* If no termcode matched but 'pastetoggle'
+ * matched partially it's like an incomplete key
+ * sequence. */
+ if (keylen == 0 && save_keylen == KEYLEN_PART_KEY)
+ keylen = KEYLEN_PART_KEY;
+
+ /*
+ * When getting a partial match, but the last
+ * characters were not typed, don't wait for a
+ * typed character to complete the termcode.
+ * This helps a lot when a ":normal" command ends
+ * in an ESC.
+ */
+ if (keylen < 0
+ && typebuf.tb_len == typebuf.tb_maplen)
+ 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);
+ }
+ break; /* got character, break for loop */
+ }
+ }
+ 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
+ keylen = mp_match_len;
+ }
+
+ /* complete match */
+ if (keylen >= 0 && keylen <= typebuf.tb_len) {
+ int save_m_expr;
+ int save_m_noremap;
+ int save_m_silent;
+ char_u *save_m_keys;
+ char_u *save_m_str;
+
+ /* write chars to script file(s) */
+ if (keylen > typebuf.tb_maplen)
+ gotchars(typebuf.tb_buf + typebuf.tb_off
+ + typebuf.tb_maplen,
+ keylen - typebuf.tb_maplen);
+
+ cmd_silent = (typebuf.tb_silent > 0);
+ del_typebuf(keylen, 0); /* remove the mapped keys */
+
+ /*
+ * Put the replacement string in front of mapstr.
+ * The depth check catches ":map x y" and ":map y x".
+ */
+ if (++mapdepth >= p_mmd) {
+ EMSG(_("E223: recursive mapping"));
+ if (State & CMDLINE)
+ redrawcmdline();
+ else
+ setcursor();
+ flush_buffers(FALSE);
+ mapdepth = 0; /* for next one */
+ c = -1;
+ break;
+ }
+
+ /*
+ * In Select mode and a Visual mode mapping is used:
+ * Switch to Visual mode temporarily. Append K_SELECT
+ * to switch back to Select mode.
+ */
+ if (VIsual_active && VIsual_select
+ && (mp->m_mode & VISUAL)) {
+ VIsual_select = FALSE;
+ (void)ins_typebuf(K_SELECT_STRING, REMAP_NONE,
+ 0, TRUE, FALSE);
+ }
+
+ /* Copy the values from *mp that are used, because
+ * evaluating the expression may invoke a function
+ * that redefines the mapping, thereby making *mp
+ * invalid. */
+ save_m_expr = mp->m_expr;
+ save_m_noremap = mp->m_noremap;
+ save_m_silent = mp->m_silent;
+ save_m_keys = NULL; /* only saved when needed */
+ save_m_str = NULL; /* only saved when needed */
+
+ /*
+ * Handle ":map <expr>": evaluate the {rhs} as an
+ * expression. Also save and restore the command line
+ * for "normal :".
+ */
+ if (mp->m_expr) {
+ int save_vgetc_busy = vgetc_busy;
+
+ vgetc_busy = 0;
+ save_m_keys = vim_strsave(mp->m_keys);
+ save_m_str = vim_strsave(mp->m_str);
+ s = eval_map_expr(save_m_str, NUL);
+ vgetc_busy = save_vgetc_busy;
+ } else
+ s = mp->m_str;
+
+ /*
+ * Insert the 'to' part in the typebuf.tb_buf.
+ * If 'from' field is the same as the start of the
+ * 'to' field, don't remap the first character (but do
+ * allow abbreviations).
+ * If m_noremap is set, don't remap the whole 'to'
+ * part.
+ */
+ if (s == NULL)
+ i = FAIL;
+ else {
+ int noremap;
+
+ if (save_m_noremap != REMAP_YES)
+ noremap = save_m_noremap;
+ else if (
+ STRNCMP(s, save_m_keys != NULL
+ ? save_m_keys : mp->m_keys,
+ (size_t)keylen)
+ != 0)
+ noremap = REMAP_YES;
+ else
+ noremap = REMAP_SKIP;
+ i = ins_typebuf(s, noremap,
+ 0, TRUE, cmd_silent || save_m_silent);
+ if (save_m_expr)
+ vim_free(s);
+ }
+ vim_free(save_m_keys);
+ vim_free(save_m_str);
+ if (i == FAIL) {
+ c = -1;
+ break;
+ }
+ continue;
+ }
+ }
+
+ /*
+ * get a character: 3. from the user - handle <Esc> in Insert mode
+ */
+ /*
+ * special case: if we get an <ESC> in insert mode and there
+ * are no more characters at once, we pretend to go out of
+ * insert mode. This prevents the one second delay after
+ * typing an <ESC>. If we get something after all, we may
+ * have to redisplay the mode. That the cursor is in the wrong
+ * place does not matter.
+ */
+ 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) {
+ colnr_T col = 0, vcol;
+ char_u *ptr;
+
+ if (mode_displayed) {
+ unshowmode(TRUE);
+ mode_deleted = TRUE;
+ }
+ validate_cursor();
+ old_wcol = curwin->w_wcol;
+ old_wrow = curwin->w_wrow;
+
+ /* move cursor left, if possible */
+ if (curwin->w_cursor.col != 0) {
+ if (curwin->w_wcol > 0) {
+ if (did_ai) {
+ /*
+ * We are expecting to truncate the trailing
+ * white-space, so find the last non-white
+ * character -- webb
+ */
+ col = vcol = curwin->w_wcol = 0;
+ ptr = ml_get_curline();
+ while (col < curwin->w_cursor.col) {
+ if (!vim_iswhite(ptr[col]))
+ curwin->w_wcol = vcol;
+ vcol += lbr_chartabsize(ptr + col,
+ (colnr_T)vcol);
+ if (has_mbyte)
+ col += (*mb_ptr2len)(ptr + col);
+ else
+ ++col;
+ }
+ curwin->w_wrow = curwin->w_cline_row
+ + curwin->w_wcol / W_WIDTH(curwin);
+ curwin->w_wcol %= W_WIDTH(curwin);
+ curwin->w_wcol += curwin_col_off();
+ col = 0; /* no correction needed */
+ } else {
+ --curwin->w_wcol;
+ col = curwin->w_cursor.col - 1;
+ }
+ } else if (curwin->w_p_wrap && curwin->w_wrow) {
+ --curwin->w_wrow;
+ curwin->w_wcol = W_WIDTH(curwin) - 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. */
+ ptr = ml_get_curline();
+ col -= (*mb_head_off)(ptr, ptr + col);
+ if ((*mb_ptr2cells)(ptr + col) > 1)
+ --curwin->w_wcol;
+ }
+ }
+ setcursor();
+ out_flush();
+ new_wcol = curwin->w_wcol;
+ new_wrow = curwin->w_wrow;
+ curwin->w_wcol = old_wcol;
+ curwin->w_wrow = old_wrow;
+ }
+ if (c < 0)
+ continue; /* end of input script reached */
+ typebuf.tb_len += c;
+
+ /* buffer full, don't map */
+ if (typebuf.tb_len >= typebuf.tb_maplen + MAXMAPLEN) {
+ timedout = TRUE;
+ continue;
+ }
+
+ if (ex_normal_busy > 0) {
+ static int tc = 0;
+
+ /* No typeahead left and inside ":normal". Must return
+ * something to avoid getting stuck. When an incomplete
+ * mapping is present, behave like it timed out. */
+ if (typebuf.tb_len > 0) {
+ timedout = TRUE;
+ continue;
+ }
+ /* When 'insertmode' is set, ESC just beeps in Insert
+ * mode. Use CTRL-L to make edit() return.
+ * For the command line only CTRL-C always breaks it.
+ * For the cmdline window: Alternate between ESC and
+ * CTRL-C: ESC for most situations and CTRL-C to close the
+ * cmdline window. */
+ if (p_im && (State & INSERT))
+ c = Ctrl_L;
+ else if ((State & CMDLINE)
+ || (cmdwin_type > 0 && tc == ESC)
+ )
+ c = Ctrl_C;
+ else
+ c = ESC;
+ tc = c;
+ break;
+ }
+
+ /*
+ * get a character: 3. from the user - update display
+ */
+ /* In insert mode a screen update is skipped when characters
+ * are still available. But when those available characters
+ * are part of a mapping, and we are going to do a blocking
+ * wait here. Need to update the screen to display the
+ * changed text so far. Also for when 'lazyredraw' is set and
+ * redrawing was postponed because there was something in the
+ * input buffer (e.g., termresponse). */
+ if (((State & INSERT) != 0 || p_lz) && (State & CMDLINE) == 0
+ && advance && must_redraw != 0 && !need_wait_return) {
+ update_screen(0);
+ setcursor(); /* put cursor back where it belongs */
+ }
+
+ /*
+ * If we have a partial match (and are going to wait for more
+ * input from the user), show the partially matched characters
+ * to the user with showcmd.
+ */
+ i = 0;
+ c1 = 0;
+ if (typebuf.tb_len > 0 && advance && !exmode_active) {
+ if (((State & (NORMAL | INSERT)) || State == LANGMAP)
+ && State != HITRETURN) {
+ /* this looks nice when typing a dead character map */
+ if (State & INSERT
+ && ptr2cells(typebuf.tb_buf + typebuf.tb_off
+ + typebuf.tb_len - 1) == 1) {
+ edit_putchar(typebuf.tb_buf[typebuf.tb_off
+ + typebuf.tb_len - 1], FALSE);
+ setcursor(); /* put cursor back where it belongs */
+ c1 = 1;
+ }
+ /* need to use the col and row from above here */
+ old_wcol = curwin->w_wcol;
+ old_wrow = curwin->w_wrow;
+ curwin->w_wcol = new_wcol;
+ curwin->w_wrow = new_wrow;
+ push_showcmd();
+ if (typebuf.tb_len > SHOWCMD_COLS)
+ i = typebuf.tb_len - SHOWCMD_COLS;
+ while (i < typebuf.tb_len)
+ (void)add_to_showcmd(typebuf.tb_buf[typebuf.tb_off
+ + i++]);
+ curwin->w_wcol = old_wcol;
+ curwin->w_wrow = old_wrow;
+ }
+
+ /* this looks nice when typing a dead character map */
+ if ((State & CMDLINE)
+ && cmdline_star == 0
+ && ptr2cells(typebuf.tb_buf + typebuf.tb_off
+ + typebuf.tb_len - 1) == 1) {
+ putcmdline(typebuf.tb_buf[typebuf.tb_off
+ + typebuf.tb_len - 1], FALSE);
+ c1 = 1;
+ }
+ }
+
+ /*
+ * get a character: 3. from the user - get it
+ */
+ 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,
+ !advance
+ ? 0
+ : ((typebuf.tb_len == 0
+ || !(p_timeout || (p_ttimeout
+ && keylen == KEYLEN_PART_KEY)))
+ ? -1L
+ : ((keylen == KEYLEN_PART_KEY && p_ttm >= 0)
+ ? p_ttm
+ : p_tm)), typebuf.tb_change_cnt);
+
+ if (i != 0)
+ pop_showcmd();
+ if (c1 == 1) {
+ if (State & INSERT)
+ edit_unputchar();
+ if (State & CMDLINE)
+ unputcmdline();
+ else
+ setcursor(); /* put cursor back where it belongs */
+ }
+
+ if (c < 0)
+ continue; /* end of input script reached */
+ if (c == NUL) { /* no character available */
+ if (!advance)
+ break;
+ if (wait_tb_len > 0) { /* timed out */
+ timedout = TRUE;
+ continue;
+ }
+ } else { /* allow mapping for just typed characters */
+ while (typebuf.tb_buf[typebuf.tb_off
+ + typebuf.tb_len] != NUL)
+ typebuf.tb_noremap[typebuf.tb_off
+ + typebuf.tb_len++] = RM_YES;
+#ifdef USE_IM_CONTROL
+ /* Get IM status right after getting keys, not after the
+ * timeout for a mapping (focus may be lost by then). */
+ vgetc_im_active = im_get_status();
+#endif
+ }
+ } /* for (;;) */
+ } /* if (!character from stuffbuf) */
+
+ /* if advance is FALSE don't loop on NULs */
+ } while (c < 0 || (advance && c == NUL));
+
+ /*
+ * The "INSERT" message is taken care of here:
+ * if we return an ESC to exit insert mode, the message is deleted
+ * if we don't return an ESC but deleted the message before, redisplay it
+ */
+ if (advance && p_smd && msg_silent == 0 && (State & INSERT)) {
+ if (c == ESC && !mode_deleted && !no_mapping && mode_displayed) {
+ if (typebuf.tb_len && !KeyTyped)
+ redraw_cmdline = TRUE; /* delete mode later */
+ else
+ unshowmode(FALSE);
+ } else if (c != ESC && mode_deleted) {
+ if (typebuf.tb_len && !KeyTyped)
+ redraw_cmdline = TRUE; /* show mode later */
+ else
+ showmode();
+ }
+ }
+
+ --vgetc_busy;
+
+ return c;
+}
+
+/*
+ * inchar() - get one character from
+ * 1. a scriptfile
+ * 2. the keyboard
+ *
+ * As much characters as we can get (upto 'maxlen') are put in "buf" and
+ * NUL terminated (buffer length must be 'maxlen' + 1).
+ * Minimum for "maxlen" is 3!!!!
+ *
+ * "tb_change_cnt" is the value of typebuf.tb_change_cnt if "buf" points into
+ * it. When typebuf.tb_change_cnt changes (e.g., when a message is received
+ * from a remote client) "buf" can no longer be used. "tb_change_cnt" is 0
+ * otherwise.
+ *
+ * If we got an interrupt all input is read until none is available.
+ *
+ * If wait_time == 0 there is no waiting for the char.
+ * If wait_time == n we wait for n msec for a character to arrive.
+ * If wait_time == -1 we wait forever for a character to arrive.
+ *
+ * Return the number of obtained characters.
+ * Return -1 when end of input script reached.
+ */
+int inchar(buf, maxlen, wait_time, tb_change_cnt)
+char_u *buf;
+int maxlen;
+long wait_time; /* milli seconds */
+int tb_change_cnt;
+{
+ int len = 0; /* init for GCC */
+ int retesc = FALSE; /* return ESC with gotint */
+ int script_char;
+
+ if (wait_time == -1L || wait_time > 100L) { /* flush output before waiting */
+ cursor_on();
+ out_flush();
+ }
+
+ /*
+ * Don't reset these when at the hit-return prompt, otherwise a endless
+ * recursive loop may result (write error in swapfile, hit-return, timeout
+ * on char wait, flush swapfile, write error....).
+ */
+ if (State != HITRETURN) {
+ did_outofmem_msg = FALSE; /* display out of memory message (again) */
+ did_swapwrite_msg = FALSE; /* display swap file write error again */
+ }
+ 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! */
+ 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
+ return -1;
+ } else {
+ buf[0] = 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 (got_int) {
+#define DUM_LEN MAXMAPLEN * 3 + 3
+ char_u dum[DUM_LEN + 1];
+
+ for (;; ) {
+ len = ui_inchar(dum, DUM_LEN, 0L, 0);
+ if (len == 0 || (len == 1 && dum[0] == 3))
+ break;
+ }
+ return retesc;
+ }
+
+ /*
+ * Always flush the output characters when getting input characters
+ * from the user.
+ */
+ out_flush();
+
+ /*
+ * Fill up to a third of the buffer, because each character may be
+ * tripled below.
+ */
+ len = ui_inchar(buf, maxlen / 3, wait_time, tb_change_cnt);
+ }
+
+ if (typebuf_changed(tb_change_cnt))
+ return 0;
+
+ return fix_input_buffer(buf, len, script_char >= 0);
+}
+
+/*
+ * Fix typed characters for use by vgetc() and check_termcode().
+ * buf[] must have room to triple the number of bytes!
+ * Returns the new length.
+ */
+int fix_input_buffer(buf, len, script)
+char_u *buf;
+int len;
+int script; /* TRUE when reading from a script */
+{
+ int i;
+ char_u *p = buf;
+
+ /*
+ * Two characters are special: NUL and K_SPECIAL.
+ * When compiled With the GUI CSI is also special.
+ * 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
+ /* timeout may generate K_CURSORHOLD */
+ && (i < 2 || p[1] != KS_EXTRA || p[2] !=
+ (int)KE_CURSORHOLD)
+ )) {
+ mch_memmove(p + 3, p + 1, (size_t)i);
+ p[2] = K_THIRD(p[0]);
+ p[1] = K_SECOND(p[0]);
+ p[0] = K_SPECIAL;
+ p += 2;
+ len += 2;
+ }
+ }
+ *p = NUL; /* add trailing NUL */
+ return len;
+}
+
+#if defined(USE_INPUT_BUF) || defined(PROTO)
+/*
+ * Return TRUE when bytes are in the input buffer or in the typeahead buffer.
+ * Normally the input buffer would be sufficient, but the server_to_input_buf()
+ * or feedkeys() may insert characters in the typeahead buffer while we are
+ * waiting for input to arrive.
+ */
+int input_available() {
+ return !vim_is_input_buf_empty()
+ || typebuf_was_filled
+ ;
+}
+
+#endif
+
+/*
+ * map[!] : show all key mappings
+ * map[!] {lhs} : show key mapping for {lhs}
+ * map[!] {lhs} {rhs} : set key mapping for {lhs} to {rhs}
+ * noremap[!] {lhs} {rhs} : same, but no remapping for {rhs}
+ * unmap[!] {lhs} : remove key mapping for {lhs}
+ * abbr : show all abbreviations
+ * abbr {lhs} : show abbreviations for {lhs}
+ * abbr {lhs} {rhs} : set abbreviation for {lhs} to {rhs}
+ * noreabbr {lhs} {rhs} : same, but no remapping for {rhs}
+ * unabbr {lhs} : remove abbreviation for {lhs}
+ *
+ * maptype: 0 for :map, 1 for :unmap, 2 for noremap.
+ *
+ * arg is pointer to any arguments. Note: arg cannot be a read-only string,
+ * it will be modified.
+ *
+ * for :map mode is NORMAL + VISUAL + SELECTMODE + OP_PENDING
+ * for :map! mode is INSERT + CMDLINE
+ * for :cmap mode is CMDLINE
+ * for :imap mode is INSERT
+ * for :lmap mode is LANGMAP
+ * for :nmap mode is NORMAL
+ * for :vmap mode is VISUAL + SELECTMODE
+ * for :xmap mode is VISUAL
+ * for :smap mode is SELECTMODE
+ * for :omap mode is OP_PENDING
+ *
+ * for :abbr mode is INSERT + CMDLINE
+ * for :iabbr mode is INSERT
+ * for :cabbr mode is CMDLINE
+ *
+ * Return 0 for success
+ * 1 for invalid arguments
+ * 2 for no match
+ * 4 for out of mem
+ * 5 for entry not unique
+ */
+int do_map(maptype, arg, mode, abbrev)
+int maptype;
+char_u *arg;
+int mode;
+int abbrev; /* not a mapping but an abbreviation */
+{
+ char_u *keys;
+ mapblock_T *mp, **mpp;
+ char_u *rhs;
+ char_u *p;
+ int n;
+ int len = 0; /* init for GCC */
+ char_u *newstr;
+ int hasarg;
+ int haskey;
+ int did_it = FALSE;
+ int did_local = FALSE;
+ int round;
+ char_u *keys_buf = NULL;
+ char_u *arg_buf = NULL;
+ int retval = 0;
+ int do_backslash;
+ int hash;
+ int new_hash;
+ mapblock_T **abbr_table;
+ mapblock_T **map_table;
+ int unique = FALSE;
+ int nowait = FALSE;
+ int silent = FALSE;
+ int special = FALSE;
+ int expr = FALSE;
+ int noremap;
+ char_u *orig_rhs;
+
+ keys = arg;
+ map_table = maphash;
+ abbr_table = &first_abbr;
+
+ /* For ":noremap" don't remap, otherwise do remap. */
+ if (maptype == 2)
+ noremap = REMAP_NONE;
+ else
+ noremap = REMAP_YES;
+
+ /* Accept <buffer>, <nowait>, <silent>, <expr> <script> and <unique> in
+ * any order. */
+ for (;; ) {
+ /*
+ * Check for "<buffer>": mapping local to buffer.
+ */
+ if (STRNCMP(keys, "<buffer>", 8) == 0) {
+ keys = skipwhite(keys + 8);
+ map_table = curbuf->b_maphash;
+ abbr_table = &curbuf->b_first_abbr;
+ continue;
+ }
+
+ /*
+ * Check for "<nowait>": don't wait for more characters.
+ */
+ if (STRNCMP(keys, "<nowait>", 8) == 0) {
+ keys = skipwhite(keys + 8);
+ nowait = TRUE;
+ continue;
+ }
+
+ /*
+ * Check for "<silent>": don't echo commands.
+ */
+ if (STRNCMP(keys, "<silent>", 8) == 0) {
+ keys = skipwhite(keys + 8);
+ silent = TRUE;
+ continue;
+ }
+
+ /*
+ * Check for "<special>": accept special keys in <>
+ */
+ if (STRNCMP(keys, "<special>", 9) == 0) {
+ keys = skipwhite(keys + 9);
+ special = TRUE;
+ continue;
+ }
+
+ /*
+ * Check for "<script>": remap script-local mappings only
+ */
+ if (STRNCMP(keys, "<script>", 8) == 0) {
+ keys = skipwhite(keys + 8);
+ noremap = REMAP_SCRIPT;
+ continue;
+ }
+
+ /*
+ * Check for "<expr>": {rhs} is an expression.
+ */
+ if (STRNCMP(keys, "<expr>", 6) == 0) {
+ keys = skipwhite(keys + 6);
+ expr = TRUE;
+ continue;
+ }
+ /*
+ * Check for "<unique>": don't overwrite an existing mapping.
+ */
+ if (STRNCMP(keys, "<unique>", 8) == 0) {
+ keys = skipwhite(keys + 8);
+ unique = TRUE;
+ continue;
+ }
+ break;
+ }
+
+ validate_maphash();
+
+ /*
+ * Find end of keys and skip CTRL-Vs (and backslashes) in it.
+ * Accept backslash like CTRL-V when 'cpoptions' does not contain 'B'.
+ * with :unmap white space is included in the keys, no argument possible.
+ */
+ p = keys;
+ do_backslash = (vim_strchr(p_cpo, CPO_BSLASH) == NULL);
+ while (*p && (maptype == 1 || !vim_iswhite(*p))) {
+ if ((p[0] == Ctrl_V || (do_backslash && p[0] == '\\')) &&
+ p[1] != NUL)
+ ++p; /* skip CTRL-V or backslash */
+ ++p;
+ }
+ if (*p != NUL)
+ *p++ = NUL;
+
+ p = skipwhite(p);
+ rhs = p;
+ hasarg = (*rhs != NUL);
+ haskey = (*keys != NUL);
+
+ /* check for :unmap without argument */
+ if (maptype == 1 && !haskey) {
+ retval = 1;
+ goto theend;
+ }
+
+ /*
+ * If mapping has been given as ^V<C_UP> say, then replace the term codes
+ * with the appropriate two bytes. If it is a shifted special key, unshift
+ * it too, giving another two bytes.
+ * replace_termcodes() may move the result to allocated memory, which
+ * 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, &keys_buf, TRUE, TRUE, special);
+ orig_rhs = rhs;
+ if (hasarg) {
+ if (STRICMP(rhs, "<nop>") == 0) /* "<Nop>" means nothing */
+ rhs = (char_u *)"";
+ else
+ rhs = replace_termcodes(rhs, &arg_buf, FALSE, TRUE, special);
+ }
+
+ /*
+ * When in right-to-left mode and alternate keymap option set,
+ * reverse the character flow in the rhs in Farsi.
+ */
+ if (p_altkeymap && curwin->w_p_rl)
+ lrswap(rhs);
+
+ /*
+ * check arguments and translate function keys
+ */
+ if (haskey) {
+ len = (int)STRLEN(keys);
+ if (len > MAXMAPLEN) { /* maximum length of MAXMAPLEN chars */
+ retval = 1;
+ goto theend;
+ }
+
+ if (abbrev && maptype != 1) {
+ /*
+ * If an abbreviation ends in a keyword character, the
+ * rest must be all keyword-char or all non-keyword-char.
+ * Otherwise we won't be able to find the start of it in a
+ * vi-compatible way.
+ */
+ if (has_mbyte) {
+ int first, last;
+ int same = -1;
+
+ first = vim_iswordp(keys);
+ last = first;
+ p = keys + (*mb_ptr2len)(keys);
+ n = 1;
+ while (p < keys + len) {
+ ++n; /* nr of (multi-byte) chars */
+ last = vim_iswordp(p); /* type of last char */
+ if (same == -1 && last != first)
+ same = n - 1; /* count of same char type */
+ p += (*mb_ptr2len)(p);
+ }
+ if (last && n > 2 && same >= 0 && same < n - 1) {
+ retval = 1;
+ goto theend;
+ }
+ } else if (vim_iswordc(keys[len - 1])) /* ends in keyword char */
+ for (n = 0; n < len - 2; ++n)
+ if (vim_iswordc(keys[n]) != vim_iswordc(keys[len - 2])) {
+ retval = 1;
+ goto theend;
+ }
+ /* An abbreviation cannot contain white space. */
+ for (n = 0; n < len; ++n)
+ if (vim_iswhite(keys[n])) {
+ retval = 1;
+ goto theend;
+ }
+ }
+ }
+
+ if (haskey && hasarg && abbrev) /* if we will add an abbreviation */
+ no_abbr = FALSE; /* reset flag that indicates there are
+ no abbreviations */
+
+ if (!haskey || (maptype != 1 && !hasarg))
+ msg_start();
+
+ /*
+ * Check if a new local mapping wasn't already defined globally.
+ */
+ if (map_table == curbuf->b_maphash && haskey && hasarg && maptype != 1) {
+ /* need to loop over all global hash lists */
+ for (hash = 0; hash < 256 && !got_int; ++hash) {
+ if (abbrev) {
+ if (hash != 0) /* there is only one abbreviation list */
+ break;
+ mp = first_abbr;
+ } else
+ mp = maphash[hash];
+ for (; mp != NULL && !got_int; mp = mp->m_next) {
+ /* check entries with the same mode */
+ if ((mp->m_mode & mode) != 0
+ && mp->m_keylen == len
+ && unique
+ && STRNCMP(mp->m_keys, keys, (size_t)len) == 0) {
+ if (abbrev)
+ EMSG2(_("E224: global abbreviation already exists for %s"),
+ mp->m_keys);
+ else
+ EMSG2(_("E225: global mapping already exists for %s"),
+ mp->m_keys);
+ retval = 5;
+ goto theend;
+ }
+ }
+ }
+ }
+
+ /*
+ * When listing global mappings, also list buffer-local ones here.
+ */
+ if (map_table != curbuf->b_maphash && !hasarg && maptype != 1) {
+ /* need to loop over all global hash lists */
+ for (hash = 0; hash < 256 && !got_int; ++hash) {
+ if (abbrev) {
+ if (hash != 0) /* there is only one abbreviation list */
+ break;
+ mp = curbuf->b_first_abbr;
+ } else
+ mp = curbuf->b_maphash[hash];
+ for (; mp != NULL && !got_int; mp = mp->m_next) {
+ /* check entries with the same mode */
+ if ((mp->m_mode & mode) != 0) {
+ if (!haskey) { /* show all entries */
+ showmap(mp, TRUE);
+ did_local = TRUE;
+ } else {
+ n = mp->m_keylen;
+ if (STRNCMP(mp->m_keys, keys,
+ (size_t)(n < len ? n : len)) == 0) {
+ showmap(mp, TRUE);
+ did_local = TRUE;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /*
+ * Find an entry in the maphash[] list that matches.
+ * For :unmap we may loop two times: once to try to unmap an entry with a
+ * matching 'from' part, a second time, if the first fails, to unmap an
+ * entry with a matching 'to' part. This was done to allow ":ab foo bar"
+ * to be unmapped by typing ":unab foo", where "foo" will be replaced by
+ * "bar" because of the abbreviation.
+ */
+ for (round = 0; (round == 0 || maptype == 1) && round <= 1
+ && !did_it && !got_int; ++round) {
+ /* need to loop over all hash lists */
+ for (hash = 0; hash < 256 && !got_int; ++hash) {
+ if (abbrev) {
+ if (hash > 0) /* there is only one abbreviation list */
+ break;
+ mpp = abbr_table;
+ } else
+ mpp = &(map_table[hash]);
+ for (mp = *mpp; mp != NULL && !got_int; mp = *mpp) {
+
+ if (!(mp->m_mode & mode)) { /* skip entries with wrong mode */
+ mpp = &(mp->m_next);
+ continue;
+ }
+ if (!haskey) { /* show all entries */
+ showmap(mp, map_table != maphash);
+ did_it = TRUE;
+ } else { /* do we have a match? */
+ if (round) { /* second round: Try unmap "rhs" string */
+ n = (int)STRLEN(mp->m_str);
+ p = mp->m_str;
+ } else {
+ n = mp->m_keylen;
+ p = mp->m_keys;
+ }
+ if (STRNCMP(p, keys, (size_t)(n < len ? n : len)) == 0) {
+ if (maptype == 1) { /* delete entry */
+ /* Only accept a full match. For abbreviations we
+ * ignore trailing space when matching with the
+ * "lhs", since an abbreviation can't have
+ * trailing space. */
+ if (n != len && (!abbrev || round || n > len
+ || *skipwhite(keys + n) != NUL)) {
+ mpp = &(mp->m_next);
+ continue;
+ }
+ /*
+ * We reset the indicated mode bits. If nothing is
+ * left the entry is deleted below.
+ */
+ mp->m_mode &= ~mode;
+ did_it = TRUE; /* remember we did something */
+ } else if (!hasarg) { /* show matching entry */
+ showmap(mp, map_table != maphash);
+ did_it = TRUE;
+ } else if (n != len) { /* new entry is ambiguous */
+ mpp = &(mp->m_next);
+ continue;
+ } else if (unique) {
+ if (abbrev)
+ EMSG2(_("E226: abbreviation already exists for %s"),
+ p);
+ else
+ EMSG2(_("E227: mapping already exists for %s"), p);
+ retval = 5;
+ goto theend;
+ } else { /* new rhs for existing entry */
+ mp->m_mode &= ~mode; /* remove mode bits */
+ if (mp->m_mode == 0 && !did_it) { /* reuse entry */
+ newstr = vim_strsave(rhs);
+ if (newstr == NULL) {
+ retval = 4; /* no mem */
+ goto theend;
+ }
+ vim_free(mp->m_str);
+ mp->m_str = newstr;
+ vim_free(mp->m_orig_str);
+ mp->m_orig_str = vim_strsave(orig_rhs);
+ mp->m_noremap = noremap;
+ mp->m_nowait = nowait;
+ mp->m_silent = silent;
+ mp->m_mode = mode;
+ mp->m_expr = expr;
+ mp->m_script_ID = current_SID;
+ did_it = TRUE;
+ }
+ }
+ if (mp->m_mode == 0) { /* entry can be deleted */
+ map_free(mpp);
+ continue; /* continue with *mpp */
+ }
+
+ /*
+ * May need to put this entry into another hash list.
+ */
+ new_hash = MAP_HASH(mp->m_mode, mp->m_keys[0]);
+ if (!abbrev && new_hash != hash) {
+ *mpp = mp->m_next;
+ mp->m_next = map_table[new_hash];
+ map_table[new_hash] = mp;
+
+ continue; /* continue with *mpp */
+ }
+ }
+ }
+ mpp = &(mp->m_next);
+ }
+ }
+ }
+
+ if (maptype == 1) { /* delete entry */
+ if (!did_it)
+ retval = 2; /* no match */
+ goto theend;
+ }
+
+ if (!haskey || !hasarg) { /* print entries */
+ if (!did_it
+ && !did_local
+ ) {
+ if (abbrev)
+ MSG(_("No abbreviation found"));
+ else
+ MSG(_("No mapping found"));
+ }
+ goto theend; /* listing finished */
+ }
+
+ if (did_it) /* have added the new entry already */
+ goto theend;
+
+ /*
+ * Get here when adding a new entry to the maphash[] list or abbrlist.
+ */
+ mp = (mapblock_T *)alloc((unsigned)sizeof(mapblock_T));
+ if (mp == NULL) {
+ retval = 4; /* no mem */
+ goto theend;
+ }
+
+ /* If CTRL-C has been mapped, don't always use it for Interrupting */
+ if (*keys == Ctrl_C)
+ mapped_ctrl_c = TRUE;
+
+ mp->m_keys = vim_strsave(keys);
+ mp->m_str = vim_strsave(rhs);
+ mp->m_orig_str = vim_strsave(orig_rhs);
+ if (mp->m_keys == NULL || mp->m_str == NULL) {
+ vim_free(mp->m_keys);
+ vim_free(mp->m_str);
+ vim_free(mp->m_orig_str);
+ vim_free(mp);
+ retval = 4; /* no mem */
+ goto theend;
+ }
+ mp->m_keylen = (int)STRLEN(mp->m_keys);
+ mp->m_noremap = noremap;
+ mp->m_nowait = nowait;
+ mp->m_silent = silent;
+ mp->m_mode = mode;
+ mp->m_expr = expr;
+ mp->m_script_ID = current_SID;
+
+ /* add the new entry in front of the abbrlist or maphash[] list */
+ if (abbrev) {
+ mp->m_next = *abbr_table;
+ *abbr_table = mp;
+ } else {
+ n = MAP_HASH(mp->m_mode, mp->m_keys[0]);
+ mp->m_next = map_table[n];
+ map_table[n] = mp;
+ }
+
+theend:
+ vim_free(keys_buf);
+ vim_free(arg_buf);
+ return retval;
+}
+
+/*
+ * Delete one entry from the abbrlist or maphash[].
+ * "mpp" is a pointer to the m_next field of the PREVIOUS entry!
+ */
+static void map_free(mpp)
+mapblock_T **mpp;
+{
+ mapblock_T *mp;
+
+ mp = *mpp;
+ vim_free(mp->m_keys);
+ vim_free(mp->m_str);
+ vim_free(mp->m_orig_str);
+ *mpp = mp->m_next;
+ vim_free(mp);
+}
+
+/*
+ * Initialize maphash[] for first use.
+ */
+static void validate_maphash() {
+ if (!maphash_valid) {
+ vim_memset(maphash, 0, sizeof(maphash));
+ maphash_valid = TRUE;
+ }
+}
+
+/*
+ * Get the mapping mode from the command name.
+ */
+int get_map_mode(cmdp, forceit)
+char_u **cmdp;
+int forceit;
+{
+ char_u *p;
+ int modec;
+ int mode;
+
+ p = *cmdp;
+ modec = *p++;
+ if (modec == 'i')
+ mode = INSERT; /* :imap */
+ else if (modec == 'l')
+ mode = LANGMAP; /* :lmap */
+ else if (modec == 'c')
+ mode = CMDLINE; /* :cmap */
+ else if (modec == 'n' && *p != 'o') /* avoid :noremap */
+ mode = NORMAL; /* :nmap */
+ else if (modec == 'v')
+ mode = VISUAL + SELECTMODE; /* :vmap */
+ else if (modec == 'x')
+ mode = VISUAL; /* :xmap */
+ else if (modec == 's')
+ mode = SELECTMODE; /* :smap */
+ else if (modec == 'o')
+ mode = OP_PENDING; /* :omap */
+ else {
+ --p;
+ if (forceit)
+ mode = INSERT + CMDLINE; /* :map ! */
+ else
+ mode = VISUAL + SELECTMODE + NORMAL + OP_PENDING; /* :map */
+ }
+
+ *cmdp = p;
+ return mode;
+}
+
+/*
+ * Clear all mappings or abbreviations.
+ * 'abbr' should be FALSE for mappings, TRUE for abbreviations.
+ */
+void map_clear(cmdp, arg, forceit, abbr)
+char_u *cmdp;
+char_u *arg UNUSED;
+int forceit;
+int abbr;
+{
+ int mode;
+ int local;
+
+ local = (STRCMP(arg, "<buffer>") == 0);
+ if (!local && *arg != NUL) {
+ EMSG(_(e_invarg));
+ return;
+ }
+
+ mode = get_map_mode(&cmdp, forceit);
+ map_clear_int(curbuf, mode,
+ local,
+ abbr);
+}
+
+/*
+ * Clear all mappings in "mode".
+ */
+void map_clear_int(buf, mode, local, abbr)
+buf_T *buf UNUSED; /* buffer for local mappings */
+int mode; /* mode in which to delete */
+int local UNUSED; /* TRUE for buffer-local mappings */
+int abbr; /* TRUE for abbreviations */
+{
+ mapblock_T *mp, **mpp;
+ int hash;
+ int new_hash;
+
+ validate_maphash();
+
+ for (hash = 0; hash < 256; ++hash) {
+ if (abbr) {
+ if (hash > 0) /* there is only one abbrlist */
+ break;
+ if (local)
+ mpp = &buf->b_first_abbr;
+ else
+ mpp = &first_abbr;
+ } else {
+ if (local)
+ mpp = &buf->b_maphash[hash];
+ else
+ mpp = &maphash[hash];
+ }
+ while (*mpp != NULL) {
+ mp = *mpp;
+ if (mp->m_mode & mode) {
+ mp->m_mode &= ~mode;
+ if (mp->m_mode == 0) { /* entry can be deleted */
+ map_free(mpp);
+ continue;
+ }
+ /*
+ * May need to put this entry into another hash list.
+ */
+ new_hash = MAP_HASH(mp->m_mode, mp->m_keys[0]);
+ if (!abbr && new_hash != hash) {
+ *mpp = mp->m_next;
+ if (local) {
+ mp->m_next = buf->b_maphash[new_hash];
+ buf->b_maphash[new_hash] = mp;
+ } else {
+ mp->m_next = maphash[new_hash];
+ maphash[new_hash] = mp;
+ }
+ continue; /* continue with *mpp */
+ }
+ }
+ mpp = &(mp->m_next);
+ }
+ }
+}
+
+/*
+ * Return characters to represent the map mode in an allocated string.
+ * Returns NULL when out of memory.
+ */
+char_u * map_mode_to_chars(mode)
+int mode;
+{
+ garray_T mapmode;
+
+ ga_init2(&mapmode, 1, 7);
+
+ if ((mode & (INSERT + CMDLINE)) == INSERT + CMDLINE)
+ ga_append(&mapmode, '!'); /* :map! */
+ else if (mode & INSERT)
+ ga_append(&mapmode, 'i'); /* :imap */
+ else if (mode & LANGMAP)
+ ga_append(&mapmode, 'l'); /* :lmap */
+ else if (mode & CMDLINE)
+ ga_append(&mapmode, 'c'); /* :cmap */
+ else if ((mode & (NORMAL + VISUAL + SELECTMODE + OP_PENDING))
+ == NORMAL + VISUAL + SELECTMODE + OP_PENDING)
+ ga_append(&mapmode, ' '); /* :map */
+ else {
+ if (mode & NORMAL)
+ ga_append(&mapmode, 'n'); /* :nmap */
+ if (mode & OP_PENDING)
+ ga_append(&mapmode, 'o'); /* :omap */
+ if ((mode & (VISUAL + SELECTMODE)) == VISUAL + SELECTMODE)
+ ga_append(&mapmode, 'v'); /* :vmap */
+ else {
+ if (mode & VISUAL)
+ ga_append(&mapmode, 'x'); /* :xmap */
+ if (mode & SELECTMODE)
+ ga_append(&mapmode, 's'); /* :smap */
+ }
+ }
+
+ ga_append(&mapmode, NUL);
+ return (char_u *)mapmode.ga_data;
+}
+
+static void showmap(mp, local)
+mapblock_T *mp;
+int local; /* TRUE for buffer-local map */
+{
+ int len = 1;
+ char_u *mapchars;
+
+ if (msg_didout || msg_silent != 0) {
+ msg_putchar('\n');
+ if (got_int) /* 'q' typed at MORE prompt */
+ return;
+ }
+
+ mapchars = map_mode_to_chars(mp->m_mode);
+ if (mapchars != NULL) {
+ msg_puts(mapchars);
+ len = (int)STRLEN(mapchars);
+ vim_free(mapchars);
+ }
+
+ while (++len <= 3)
+ msg_putchar(' ');
+
+ /* Display the LHS. Get length of what we write. */
+ len = 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
+ msg_putchar(' ');
+
+ if (local)
+ msg_putchar('@');
+ else
+ msg_putchar(' ');
+
+ /* 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. */
+ char_u *s = vim_strsave(mp->m_str);
+ if (s != NULL) {
+ vim_unescape_csi(s);
+ msg_outtrans_special(s, FALSE);
+ vim_free(s);
+ }
+ }
+ if (p_verbose > 0)
+ last_set_msg(mp->m_script_ID);
+ out_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(str, modechars, abbr)
+char_u *str;
+char_u *modechars;
+int abbr;
+{
+ int mode = 0;
+ char_u *rhs;
+ char_u *buf;
+ int retval;
+
+ rhs = replace_termcodes(str, &buf, FALSE, TRUE, FALSE);
+
+ 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);
+ vim_free(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(rhs, mode, abbr)
+char_u *rhs;
+int mode;
+int abbr;
+{
+ mapblock_T *mp;
+ int hash;
+ int expand_buffer = FALSE;
+
+ validate_maphash();
+
+ /* 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 */
+ break;
+ if (expand_buffer)
+ mp = curbuf->b_first_abbr;
+ else
+ mp = first_abbr;
+ } else if (expand_buffer)
+ mp = curbuf->b_maphash[hash];
+ 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;
+ }
+ }
+ if (expand_buffer)
+ break;
+ expand_buffer = TRUE;
+ }
+
+ return FALSE;
+}
+
+/*
+ * Used below when expanding mapping/abbreviation names.
+ */
+static int expand_mapmodes = 0;
+static int expand_isabbrev = 0;
+static int expand_buffer = FALSE;
+
+/*
+ * Work out what to complete when doing command line completion of mapping
+ * or abbreviation names.
+ */
+char_u * set_context_in_map_cmd(xp, cmd, arg, forceit, isabbrev, isunmap,
+ cmdidx)
+expand_T *xp;
+char_u *cmd;
+char_u *arg;
+int forceit; /* TRUE if '!' given */
+int isabbrev; /* TRUE if abbreviation */
+int isunmap; /* TRUE if unmap/unabbrev command */
+cmdidx_T cmdidx;
+{
+ if (forceit && cmdidx != CMD_map && cmdidx != CMD_unmap)
+ xp->xp_context = EXPAND_NOTHING;
+ else {
+ if (isunmap)
+ expand_mapmodes = get_map_mode(&cmd, forceit || isabbrev);
+ else {
+ expand_mapmodes = INSERT + CMDLINE;
+ if (!isabbrev)
+ expand_mapmodes += VISUAL + SELECTMODE + NORMAL + OP_PENDING;
+ }
+ expand_isabbrev = isabbrev;
+ xp->xp_context = EXPAND_MAPPINGS;
+ expand_buffer = FALSE;
+ for (;; ) {
+ if (STRNCMP(arg, "<buffer>", 8) == 0) {
+ expand_buffer = TRUE;
+ arg = skipwhite(arg + 8);
+ continue;
+ }
+ if (STRNCMP(arg, "<unique>", 8) == 0) {
+ arg = skipwhite(arg + 8);
+ continue;
+ }
+ if (STRNCMP(arg, "<nowait>", 8) == 0) {
+ arg = skipwhite(arg + 8);
+ continue;
+ }
+ if (STRNCMP(arg, "<silent>", 8) == 0) {
+ arg = skipwhite(arg + 8);
+ continue;
+ }
+ if (STRNCMP(arg, "<script>", 8) == 0) {
+ arg = skipwhite(arg + 8);
+ continue;
+ }
+ if (STRNCMP(arg, "<expr>", 6) == 0) {
+ arg = skipwhite(arg + 6);
+ continue;
+ }
+ break;
+ }
+ xp->xp_pattern = arg;
+ }
+
+ return NULL;
+}
+
+/*
+ * Find all mapping/abbreviation names that match regexp 'prog'.
+ * For command line expansion of ":[un]map" and ":[un]abbrev" in all modes.
+ * Return OK if matches found, FAIL otherwise.
+ */
+int ExpandMappings(regmatch, num_file, file)
+regmatch_T *regmatch;
+int *num_file;
+char_u ***file;
+{
+ mapblock_T *mp;
+ int hash;
+ int count;
+ int round;
+ char_u *p;
+ int i;
+
+ validate_maphash();
+
+ *num_file = 0; /* return values in case of FAIL */
+ *file = NULL;
+
+ /*
+ * round == 1: Count the matches.
+ * round == 2: Build the array to keep the matches.
+ */
+ for (round = 1; round <= 2; ++round) {
+ count = 0;
+
+ for (i = 0; i < 6; ++i) {
+ if (i == 0)
+ p = (char_u *)"<silent>";
+ else if (i == 1)
+ p = (char_u *)"<unique>";
+ else if (i == 2)
+ p = (char_u *)"<script>";
+ else if (i == 3)
+ p = (char_u *)"<expr>";
+ else if (i == 4 && !expand_buffer)
+ p = (char_u *)"<buffer>";
+ else if (i == 5)
+ p = (char_u *)"<nowait>";
+ else
+ continue;
+
+ if (vim_regexec(regmatch, p, (colnr_T)0)) {
+ if (round == 1)
+ ++count;
+ else
+ (*file)[count++] = vim_strsave(p);
+ }
+ }
+
+ for (hash = 0; hash < 256; ++hash) {
+ if (expand_isabbrev) {
+ if (hash > 0) /* only one abbrev list */
+ break; /* for (hash) */
+ mp = first_abbr;
+ } else if (expand_buffer)
+ mp = curbuf->b_maphash[hash];
+ else
+ mp = maphash[hash];
+ for (; mp; mp = mp->m_next) {
+ if (mp->m_mode & expand_mapmodes) {
+ p = translate_mapping(mp->m_keys, TRUE);
+ if (p != NULL && vim_regexec(regmatch, p, (colnr_T)0)) {
+ if (round == 1)
+ ++count;
+ else {
+ (*file)[count++] = p;
+ p = NULL;
+ }
+ }
+ vim_free(p);
+ }
+ } /* for (mp) */
+ } /* for (hash) */
+
+ if (count == 0) /* no match found */
+ break; /* for (round) */
+
+ if (round == 1) {
+ *file = (char_u **)alloc((unsigned)(count * sizeof(char_u *)));
+ if (*file == NULL)
+ return FAIL;
+ }
+ } /* for (round) */
+
+ if (count > 1) {
+ char_u **ptr1;
+ char_u **ptr2;
+ char_u **ptr3;
+
+ /* Sort the matches */
+ sort_strings(*file, count);
+
+ /* Remove multiple entries */
+ ptr1 = *file;
+ ptr2 = ptr1 + 1;
+ ptr3 = ptr1 + count;
+
+ while (ptr2 < ptr3) {
+ if (STRCMP(*ptr1, *ptr2))
+ *++ptr1 = *ptr2++;
+ else {
+ vim_free(*ptr2++);
+ count--;
+ }
+ }
+ }
+
+ *num_file = count;
+ return count == 0 ? FAIL : OK;
+}
+
+/*
+ * Check for an abbreviation.
+ * Cursor is at ptr[col]. When inserting, mincol is where insert started.
+ * "c" is the character typed before check_abbr was called. It may have
+ * ABBR_OFF added to avoid prepending a CTRL-V to it.
+ *
+ * Historic vi practice: The last character of an abbreviation must be an id
+ * character ([a-zA-Z0-9_]). The characters in front of it must be all id
+ * characters or all non-id characters. This allows for abbr. "#i" to
+ * "#include".
+ *
+ * Vim addition: Allow for abbreviations that end in a non-keyword character.
+ * Then there must be white space before the abbr.
+ *
+ * return TRUE if there is an abbreviation, FALSE if not
+ */
+int check_abbr(c, ptr, col, mincol)
+int c;
+char_u *ptr;
+int col;
+int mincol;
+{
+ int len;
+ int scol; /* starting column of the abbr. */
+ int j;
+ char_u *s;
+ char_u tb[MB_MAXBYTES + 4];
+ mapblock_T *mp;
+ mapblock_T *mp2;
+ int clen = 0; /* length in characters */
+ int is_id = TRUE;
+ int vim_abbr;
+
+ if (typebuf.tb_no_abbr_cnt) /* abbrev. are not recursive */
+ return FALSE;
+
+ /* no remapping implies no abbreviation, except for CTRL-] */
+ if ((KeyNoremap & (RM_NONE|RM_SCRIPT)) != 0 && c != Ctrl_RSB)
+ return FALSE;
+
+ /*
+ * Check for word before the cursor: If it ends in a keyword char all
+ * chars before it must be keyword chars or non-keyword chars, but not
+ * white space. If it ends in a non-keyword char we accept any characters
+ * before it except white space.
+ */
+ if (col == 0) /* cannot be an abbr. */
+ return FALSE;
+
+ if (has_mbyte) {
+ char_u *p;
+
+ p = mb_prevptr(ptr, ptr + col);
+ if (!vim_iswordp(p))
+ vim_abbr = TRUE; /* Vim added abbr. */
+ else {
+ vim_abbr = FALSE; /* vi compatible abbr. */
+ if (p > ptr)
+ is_id = vim_iswordp(mb_prevptr(ptr, p));
+ }
+ clen = 1;
+ while (p > ptr + mincol) {
+ p = mb_prevptr(ptr, p);
+ if (vim_isspace(*p) || (!vim_abbr && is_id != vim_iswordp(p))) {
+ p += (*mb_ptr2len)(p);
+ break;
+ }
+ ++clen;
+ }
+ scol = (int)(p - ptr);
+ } else {
+ if (!vim_iswordc(ptr[col - 1]))
+ vim_abbr = TRUE; /* Vim added abbr. */
+ else {
+ vim_abbr = FALSE; /* vi compatible abbr. */
+ if (col > 1)
+ is_id = vim_iswordc(ptr[col - 2]);
+ }
+ for (scol = col - 1; scol > 0 && !vim_isspace(ptr[scol - 1])
+ && (vim_abbr || is_id == vim_iswordc(ptr[scol - 1])); --scol)
+ ;
+ }
+
+ if (scol < mincol)
+ scol = mincol;
+ if (scol < col) { /* there is a word in front of the cursor */
+ ptr += scol;
+ len = col - scol;
+ mp = curbuf->b_first_abbr;
+ mp2 = first_abbr;
+ if (mp == NULL) {
+ mp = mp2;
+ mp2 = NULL;
+ }
+ for (; mp;
+ mp->m_next == NULL ? (mp = mp2, mp2 = NULL) :
+ (mp = mp->m_next)) {
+ /* find entries with right mode and keys */
+ if ( (mp->m_mode & State)
+ && mp->m_keylen == len
+ && !STRNCMP(mp->m_keys, ptr, (size_t)len))
+ break;
+ }
+ if (mp != NULL) {
+ /*
+ * Found a match:
+ * Insert the rest of the abbreviation in typebuf.tb_buf[].
+ * This goes from end to start.
+ *
+ * Characters 0x000 - 0x100: normal chars, may need CTRL-V,
+ * except K_SPECIAL: Becomes K_SPECIAL KS_SPECIAL KE_FILLER
+ * Characters where IS_SPECIAL() == TRUE: key codes, need
+ * K_SPECIAL. Other characters (with ABBR_OFF): don't use CTRL-V.
+ *
+ * Character CTRL-] is treated specially - it completes the
+ * abbreviation, but is not inserted into the input stream.
+ */
+ j = 0;
+ if (c != Ctrl_RSB) {
+ /* special key code, split up */
+ if (IS_SPECIAL(c) || c == K_SPECIAL) {
+ tb[j++] = K_SPECIAL;
+ tb[j++] = K_SECOND(c);
+ tb[j++] = 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++] = c;
+ }
+ tb[j] = NUL;
+ /* insert the last typed char */
+ (void)ins_typebuf(tb, 1, 0, TRUE, mp->m_silent);
+ }
+ if (mp->m_expr)
+ s = eval_map_expr(mp->m_str, c);
+ else
+ s = mp->m_str;
+ if (s != NULL) {
+ /* insert the to string */
+ (void)ins_typebuf(s, mp->m_noremap, 0, TRUE, mp->m_silent);
+ /* no abbrev. for these chars */
+ typebuf.tb_no_abbr_cnt += (int)STRLEN(s) + j + 1;
+ if (mp->m_expr)
+ vim_free(s);
+ }
+
+ tb[0] = Ctrl_H;
+ tb[1] = NUL;
+ if (has_mbyte)
+ len = clen; /* Delete characters instead of bytes */
+ while (len-- > 0) /* delete the from string */
+ (void)ins_typebuf(tb, 1, 0, TRUE, mp->m_silent);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/*
+ * Evaluate the RHS of a mapping or abbreviations and take care of escaping
+ * special characters.
+ */
+static char_u * eval_map_expr(str, c)
+char_u *str;
+int c; /* NUL or typed character for abbreviation */
+{
+ char_u *res;
+ char_u *p;
+ char_u *expr;
+ char_u *save_cmd;
+ pos_T save_cursor;
+ int save_msg_col;
+ int save_msg_row;
+
+ /* Remove escaping of CSI, because "str" is in a format to be used as
+ * typeahead. */
+ expr = vim_strsave(str);
+ if (expr == NULL)
+ return NULL;
+ vim_unescape_csi(expr);
+
+ save_cmd = save_cmdline_alloc();
+ if (save_cmd == NULL) {
+ vim_free(expr);
+ return NULL;
+ }
+
+ /* Forbid changing text or using ":normal" to avoid most of the bad side
+ * effects. Also restore the cursor position. */
+ ++textlock;
+ ++ex_normal_lock;
+ set_vim_var_char(c); /* set v:char to the typed character */
+ save_cursor = curwin->w_cursor;
+ save_msg_col = msg_col;
+ save_msg_row = msg_row;
+ p = eval_to_string(expr, NULL, FALSE);
+ --textlock;
+ --ex_normal_lock;
+ curwin->w_cursor = save_cursor;
+ msg_col = save_msg_col;
+ msg_row = save_msg_row;
+
+ restore_cmdline_alloc(save_cmd);
+ vim_free(expr);
+
+ if (p == NULL)
+ return NULL;
+ /* Escape CSI in the result to be able to use the string as typeahead. */
+ res = vim_strsave_escape_csi(p);
+ vim_free(p);
+
+ return res;
+}
+
+/*
+ * Copy "p" to allocated memory, escaping K_SPECIAL and CSI so that the result
+ * can be put in the typeahead buffer.
+ * Returns NULL when out of memory.
+ */
+char_u * vim_strsave_escape_csi(p)
+char_u *p;
+{
+ char_u *res;
+ char_u *s, *d;
+
+ /* Need a buffer to hold up to three times as much. */
+ res = alloc((unsigned)(STRLEN(p) * 3) + 1);
+ if (res != NULL) {
+ d = res;
+ for (s = p; *s != NUL; ) {
+ if (s[0] == K_SPECIAL && s[1] != NUL && s[2] != NUL) {
+ /* Copy special key unmodified. */
+ *d++ = *s++;
+ *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. */
+ 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);
+ }
+ }
+ *d = NUL;
+ }
+ return res;
+}
+
+/*
+ * Remove escaping from CSI and K_SPECIAL characters. Reverse of
+ * vim_strsave_escape_csi(). Works in-place.
+ */
+void vim_unescape_csi(p)
+char_u *p;
+{
+ char_u *s = p, *d = p;
+
+ while (*s != NUL) {
+ if (s[0] == K_SPECIAL && s[1] == KS_SPECIAL && s[2] == KE_FILLER) {
+ *d++ = K_SPECIAL;
+ s += 3;
+ } else if ((s[0] == K_SPECIAL || s[0] == CSI)
+ && s[1] == KS_EXTRA && s[2] == (int)KE_CSI) {
+ *d++ = CSI;
+ s += 3;
+ } else
+ *d++ = *s++;
+ }
+ *d = NUL;
+}
+
+/*
+ * Write map commands for the current mappings to an .exrc file.
+ * Return FAIL on error, OK otherwise.
+ */
+int makemap(fd, buf)
+FILE *fd;
+buf_T *buf; /* buffer for local mappings or NULL */
+{
+ mapblock_T *mp;
+ char_u c1, c2, c3;
+ char_u *p;
+ char *cmd;
+ int abbr;
+ int hash;
+ int did_cpo = FALSE;
+ int i;
+
+ validate_maphash();
+
+ /*
+ * Do the loop twice: Once for mappings, once for abbreviations.
+ * Then loop over all map hash lists.
+ */
+ for (abbr = 0; abbr < 2; ++abbr)
+ for (hash = 0; hash < 256; ++hash) {
+ if (abbr) {
+ if (hash > 0) /* there is only one abbr list */
+ break;
+ if (buf != NULL)
+ mp = buf->b_first_abbr;
+ else
+ mp = first_abbr;
+ } else {
+ if (buf != NULL)
+ mp = buf->b_maphash[hash];
+ else
+ mp = maphash[hash];
+ }
+
+ for (; mp; mp = mp->m_next) {
+ /* skip script-local mappings */
+ if (mp->m_noremap == REMAP_SCRIPT)
+ continue;
+
+ /* skip mappings that contain a <SNR> (script-local thing),
+ * they probably don't work when loaded again */
+ for (p = mp->m_str; *p != NUL; ++p)
+ if (p[0] == K_SPECIAL && p[1] == KS_EXTRA
+ && p[2] == (int)KE_SNR)
+ break;
+ if (*p != NUL)
+ continue;
+
+ /* It's possible to create a mapping and then ":unmap" certain
+ * modes. We recreate this here by mapping the individual
+ * modes, which requires up to three of them. */
+ c1 = NUL;
+ c2 = NUL;
+ c3 = NUL;
+ if (abbr)
+ cmd = "abbr";
+ else
+ cmd = "map";
+ switch (mp->m_mode) {
+ case NORMAL + VISUAL + SELECTMODE + OP_PENDING:
+ break;
+ case NORMAL:
+ c1 = 'n';
+ break;
+ case VISUAL:
+ c1 = 'x';
+ break;
+ case SELECTMODE:
+ c1 = 's';
+ break;
+ case OP_PENDING:
+ c1 = 'o';
+ break;
+ case NORMAL + VISUAL:
+ c1 = 'n';
+ c2 = 'x';
+ break;
+ case NORMAL + SELECTMODE:
+ c1 = 'n';
+ c2 = 's';
+ break;
+ case NORMAL + OP_PENDING:
+ c1 = 'n';
+ c2 = 'o';
+ break;
+ case VISUAL + SELECTMODE:
+ c1 = 'v';
+ break;
+ case VISUAL + OP_PENDING:
+ c1 = 'x';
+ c2 = 'o';
+ break;
+ case SELECTMODE + OP_PENDING:
+ c1 = 's';
+ c2 = 'o';
+ break;
+ case NORMAL + VISUAL + SELECTMODE:
+ c1 = 'n';
+ c2 = 'v';
+ break;
+ case NORMAL + VISUAL + OP_PENDING:
+ c1 = 'n';
+ c2 = 'x';
+ c3 = 'o';
+ break;
+ case NORMAL + SELECTMODE + OP_PENDING:
+ c1 = 'n';
+ c2 = 's';
+ c3 = 'o';
+ break;
+ case VISUAL + SELECTMODE + OP_PENDING:
+ c1 = 'v';
+ c2 = 'o';
+ break;
+ case CMDLINE + INSERT:
+ if (!abbr)
+ cmd = "map!";
+ break;
+ case CMDLINE:
+ c1 = 'c';
+ break;
+ case INSERT:
+ c1 = 'i';
+ break;
+ case LANGMAP:
+ c1 = 'l';
+ break;
+ default:
+ EMSG(_("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 (did_cpo) {
+ if (fprintf(fd, "let s:cpo_save=&cpo") < 0
+ || put_eol(fd) < 0
+ || fprintf(fd, "set cpo&vim") < 0
+ || put_eol(fd) < 0)
+ return FAIL;
+ }
+ }
+ if (c1 && putc(c1, fd) < 0)
+ return FAIL;
+ if (mp->m_noremap != REMAP_YES && fprintf(fd, "nore") < 0)
+ return FAIL;
+ if (fputs(cmd, fd) < 0)
+ return FAIL;
+ if (buf != NULL && fputs(" <buffer>", fd) < 0)
+ return FAIL;
+ if (mp->m_nowait && fputs(" <nowait>", fd) < 0)
+ return FAIL;
+ if (mp->m_silent && fputs(" <silent>", fd) < 0)
+ return FAIL;
+ if (mp->m_noremap == REMAP_SCRIPT
+ && fputs("<script>", fd) < 0)
+ return FAIL;
+ if (mp->m_expr && fputs(" <expr>", fd) < 0)
+ return FAIL;
+
+ if ( putc(' ', fd) < 0
+ || put_escstr(fd, mp->m_keys, 0) == FAIL
+ || putc(' ', fd) < 0
+ || put_escstr(fd, mp->m_str, 1) == FAIL
+ || put_eol(fd) < 0)
+ return FAIL;
+ c1 = c2;
+ c2 = c3;
+ c3 = NUL;
+ } while (c1 != NUL);
+ }
+ }
+
+ if (did_cpo)
+ if (fprintf(fd, "let &cpo=s:cpo_save") < 0
+ || put_eol(fd) < 0
+ || fprintf(fd, "unlet s:cpo_save") < 0
+ || put_eol(fd) < 0)
+ return FAIL;
+ return OK;
+}
+
+/*
+ * write escape string to file
+ * "what": 0 for :map lhs, 1 for :map rhs, 2 for :set
+ *
+ * return FAIL for failure, OK otherwise
+ */
+int put_escstr(fd, strstart, what)
+FILE *fd;
+char_u *strstart;
+int what;
+{
+ char_u *str = strstart;
+ int c;
+ int modifiers;
+
+ /* :map xx <Nop> */
+ if (*str == NUL && what == 1) {
+ if (fprintf(fd, "<Nop>") < 0)
+ return FAIL;
+ 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);
+ if (p != NULL) {
+ while (*p != NUL)
+ if (fputc(*p++, fd) < 0)
+ return FAIL;
+ --str;
+ continue;
+ }
+
+ c = *str;
+ /*
+ * Special key codes have to be translated to be able to make sense
+ * when they are read back.
+ */
+ if (c == K_SPECIAL && what != 2) {
+ modifiers = 0x0;
+ if (str[1] == KS_MODIFIER) {
+ modifiers = str[2];
+ str += 3;
+ c = *str;
+ }
+ if (c == K_SPECIAL) {
+ c = TO_SPECIAL(str[1], str[2]);
+ str += 2;
+ }
+ if (IS_SPECIAL(c) || modifiers) { /* special key */
+ if (fputs((char *)get_special_key_name(c, modifiers), fd) < 0)
+ return FAIL;
+ continue;
+ }
+ }
+
+ /*
+ * A '\n' in a map command should be written as <NL>.
+ * A '\n' in a set command should be written as \^V^J.
+ */
+ if (c == NL) {
+ if (what == 2) {
+ if (fprintf(fd, IF_EB("\\\026\n", "\\" CTRL_V_STR "\n")) < 0)
+ return FAIL;
+ } else {
+ if (fprintf(fd, "<NL>") < 0)
+ return FAIL;
+ }
+ continue;
+ }
+
+ /*
+ * Some characters have to be escaped with CTRL-V to
+ * prevent them from misinterpreted in DoOneCmd().
+ * A space, Tab and '"' has to be escaped with a backslash to
+ * prevent it to be misinterpreted in do_set().
+ * A space has to be escaped with a CTRL-V when it's at the start of a
+ * ":map" rhs.
+ * A '<' has to be escaped with a CTRL-V to prevent it being
+ * interpreted as the start of a special key name.
+ * A space in the lhs of a :map needs a CTRL-V.
+ */
+ if (what == 2 && (vim_iswhite(c) || c == '"' || c == '\\')) {
+ if (putc('\\', fd) < 0)
+ return FAIL;
+ } else if (c < ' ' || c > '~' || c == '|'
+ || (what == 0 && c == ' ')
+ || (what == 1 && str == strstart && c == ' ')
+ || (what != 2 && c == '<')) {
+ if (putc(Ctrl_V, fd) < 0)
+ return FAIL;
+ }
+ if (putc(c, fd) < 0)
+ return FAIL;
+ }
+ return OK;
+}
+
+/*
+ * Check all mappings for the presence of special key codes.
+ * Used after ":set term=xxx".
+ */
+void check_map_keycodes() {
+ mapblock_T *mp;
+ char_u *p;
+ int i;
+ char_u buf[3];
+ char_u *save_name;
+ int abbr;
+ int hash;
+ buf_T *bp;
+
+ validate_maphash();
+ save_name = sourcing_name;
+ sourcing_name = (char_u *)"mappings"; /* avoids giving error messages */
+
+ /* This this once for each buffer, and then once for global
+ * mappings/abbreviations with bp == NULL */
+ for (bp = firstbuf;; bp = bp->b_next) {
+ /*
+ * Do the loop twice: Once for mappings, once for abbreviations.
+ * Then loop over all map hash lists.
+ */
+ for (abbr = 0; abbr <= 1; ++abbr)
+ for (hash = 0; hash < 256; ++hash) {
+ if (abbr) {
+ if (hash) /* there is only one abbr list */
+ break;
+ if (bp != NULL)
+ mp = bp->b_first_abbr;
+ else
+ mp = first_abbr;
+ } else {
+ if (bp != NULL)
+ mp = bp->b_maphash[hash];
+ else
+ mp = maphash[hash];
+ }
+ for (; mp != NULL; mp = mp->m_next) {
+ for (i = 0; i <= 1; ++i) { /* do this twice */
+ if (i == 0)
+ p = mp->m_keys; /* once for the "from" part */
+ else
+ p = mp->m_str; /* and once for the "to" part */
+ while (*p) {
+ if (*p == K_SPECIAL) {
+ ++p;
+ if (*p < 128) { /* for "normal" tcap entries */
+ buf[0] = p[0];
+ buf[1] = p[1];
+ buf[2] = NUL;
+ (void)add_termcap_entry(buf, FALSE);
+ }
+ ++p;
+ }
+ ++p;
+ }
+ }
+ }
+ }
+ if (bp == NULL)
+ break;
+ }
+ sourcing_name = save_name;
+}
+
+/*
+ * Check the string "keys" against the lhs of all mappings.
+ * Return pointer to rhs of mapping (mapblock->m_str).
+ * NULL when no mapping found.
+ */
+char_u * check_map(keys, mode, exact, ign_mod, abbr, mp_ptr, local_ptr)
+char_u *keys;
+int mode;
+int exact; /* require exact match */
+int ign_mod; /* ignore preceding modifier */
+int abbr; /* do abbreviations */
+mapblock_T **mp_ptr; /* return: pointer to mapblock or NULL */
+int *local_ptr; /* return: buffer-local mapping or NULL */
+{
+ int hash;
+ int len, minlen;
+ mapblock_T *mp;
+ char_u *s;
+ int local;
+
+ validate_maphash();
+
+ len = (int)STRLEN(keys);
+ for (local = 1; local >= 0; --local)
+ /* loop over all hash lists */
+ for (hash = 0; hash < 256; ++hash) {
+ if (abbr) {
+ if (hash > 0) /* there is only one list. */
+ break;
+ if (local)
+ mp = curbuf->b_first_abbr;
+ else
+ mp = first_abbr;
+ } else if (local)
+ mp = curbuf->b_maphash[hash];
+ else
+ mp = maphash[hash];
+ for (; mp != NULL; mp = mp->m_next) {
+ /* skip entries with wrong mode, wrong length and not matching
+ * ones */
+ if ((mp->m_mode & mode) && (!exact || mp->m_keylen == len)) {
+ if (len > mp->m_keylen)
+ minlen = mp->m_keylen;
+ else
+ minlen = len;
+ s = mp->m_keys;
+ if (ign_mod && s[0] == K_SPECIAL && s[1] == KS_MODIFIER
+ && s[2] != NUL) {
+ s += 3;
+ if (len > mp->m_keylen - 3)
+ minlen = mp->m_keylen - 3;
+ }
+ if (STRNCMP(s, keys, minlen) == 0) {
+ if (mp_ptr != NULL)
+ *mp_ptr = mp;
+ if (local_ptr != NULL)
+ *local_ptr = local;
+ return mp->m_str;
+ }
+ }
+ }
+ }
+
+ return NULL;
+}
+
+
+#if defined(MSDOS) || defined(MSWIN) || defined(OS2) \
+ || defined(FEAT_CMDWIN) || defined(MACOS) || defined(PROTO)
+/*
+ * Add a mapping "map" for mode "mode".
+ * Need to put string in allocated memory, because do_map() will modify it.
+ */
+void add_map(map, mode)
+char_u *map;
+int mode;
+{
+ char_u *s;
+ char_u *cpo_save = p_cpo;
+
+ p_cpo = (char_u *)""; /* Allow <> notation */
+ s = vim_strsave(map);
+ if (s != NULL) {
+ (void)do_map(0, s, mode, FALSE);
+ vim_free(s);
+ }
+ p_cpo = cpo_save;
+}
+#endif
diff --git a/src/globals.h b/src/globals.h
new file mode 100644
index 0000000000..e6db0d866b
--- /dev/null
+++ b/src/globals.h
@@ -0,0 +1,1199 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * 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.
+ */
+
+/*
+ * definition of global variables
+ */
+
+/*
+ * 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).
+ */
+EXTERN long Rows /* nr of rows in the screen */
+#ifdef DO_INIT
+ = 24L
+#endif
+;
+EXTERN long Columns INIT(= 80); /* nr of columns in the screen */
+
+/*
+ * 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);
+
+/*
+ * Indexes for tab page line:
+ * N > 0 for label of tab page N
+ * N == 0 for no label
+ * N < 0 for closing tab page -N
+ * N == -999 for closing current tab page
+ */
+EXTERN short *TabPageIdxs INIT(= NULL);
+
+EXTERN int screen_Rows INIT(= 0); /* actual size of ScreenLines[] */
+EXTERN int screen_Columns INIT(= 0); /* actual size of ScreenLines[] */
+
+/*
+ * When vgetc() is called, it sets mod_mask to the set of modifiers that are
+ * held down based on the MOD_MASK_* symbols that are read first.
+ */
+EXTERN int mod_mask INIT(= 0x0); /* current key modifiers */
+
+/*
+ * Cmdline_row is the row where the command line starts, just below the
+ * last window.
+ * When the cmdline gets longer than the available space the screen gets
+ * scrolled up. After a CTRL-D (show matches), after hitting ':' after
+ * "hit return", and for the :global command, the command line is
+ * temporarily moved. The old position is restored with the next call to
+ * update_screen().
+ */
+EXTERN int cmdline_row;
+
+EXTERN int redraw_cmdline INIT(= FALSE); /* cmdline must be redrawn */
+EXTERN int clear_cmdline INIT(= FALSE); /* cmdline must be cleared */
+EXTERN int mode_displayed INIT(= FALSE); /* mode is being displayed */
+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 */
+
+EXTERN int use_crypt_method INIT(= 0);
+
+/*
+ * When '$' is included in 'cpoptions' option set:
+ * When a change command is given that deletes only part of a line, a dollar
+ * is put at the end of the changed text. dollar_vcol is set to the virtual
+ * column of this '$'. -1 is used to indicate no $ is being displayed.
+ */
+EXTERN colnr_T dollar_vcol INIT(= -1);
+
+/*
+ * Variables for Insert mode completion.
+ */
+
+/* Length in bytes of the text being completed (this is deleted to be replaced
+ * by the match.) */
+EXTERN int compl_length INIT(= 0);
+
+/* Set when character typed while looking for matches and it means we should
+ * stop looking for matches. */
+EXTERN int compl_interrupted INIT(= FALSE);
+
+/* List of flags for method of completion. */
+EXTERN int compl_cont_status INIT(= 0);
+# define CONT_ADDING 1 /* "normal" or "adding" expansion */
+# define CONT_INTRPT (2 + 4) /* a ^X interrupted the current expansion */
+ /* it's set only iff N_ADDS is set */
+# define CONT_N_ADDS 4 /* next ^X<> will add-new or expand-current */
+# define CONT_S_IPOS 8 /* next ^X<> will set initial_pos?
+ * if so, word-wise-expansion will set SOL */
+# define CONT_SOL 16 /* pattern includes start of line, just for
+ * word-wise expansion, not set for ^X^L */
+# 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 */
+EXTERN int msg_col;
+EXTERN int msg_row;
+EXTERN int msg_scrolled; /* Number of screen lines that windows have
+ * scrolled because of printing messages. */
+EXTERN int msg_scrolled_ign INIT(= FALSE);
+/* when TRUE don't set need_wait_return in
+ msg_puts_attr() when msg_scrolled is
+ non-zero */
+
+EXTERN char_u *keep_msg INIT(= NULL); /* msg to be shown after redraw */
+EXTERN int keep_msg_attr INIT(= 0); /* highlight attr for keep_msg */
+EXTERN int keep_msg_more INIT(= FALSE); /* keep_msg was set by msgmore() */
+EXTERN int need_fileinfo INIT(= FALSE); /* do fileinfo() after redraw */
+EXTERN int msg_scroll INIT(= FALSE); /* msg_start() will scroll */
+EXTERN int msg_didout INIT(= FALSE); /* msg_outstr() was used in line */
+EXTERN int msg_didany INIT(= FALSE); /* msg_outstr() was used at all */
+EXTERN int msg_nowait INIT(= FALSE); /* don't wait for this msg */
+EXTERN int emsg_off INIT(= 0); /* don't display errors for now,
+ unless 'debug' is set. */
+EXTERN int info_message INIT(= FALSE); /* printing informative message */
+EXTERN int msg_hist_off INIT(= FALSE); /* don't add messages to history */
+EXTERN int need_clr_eos INIT(= FALSE); /* need to clear text before
+ displaying a message. */
+EXTERN int emsg_skip INIT(= 0); /* don't display errors for
+ expression that is skipped */
+EXTERN int emsg_severe INIT(= FALSE); /* use message of next of several
+ emsg() calls for throw */
+EXTERN int did_endif INIT(= FALSE); /* just had ":endif" */
+EXTERN dict_T vimvardict; /* Dictionary with v: variables */
+EXTERN dict_T globvardict; /* Dictionary with g: variables */
+EXTERN int did_emsg; /* set by emsg() when the message
+ is displayed or thrown */
+EXTERN int did_emsg_syntax; /* did_emsg set because of a
+ syntax error */
+EXTERN int called_emsg; /* always set by emsg() */
+EXTERN int ex_exitval INIT(= 0); /* exit value for ex mode */
+EXTERN int emsg_on_display INIT(= FALSE); /* there is an error message */
+EXTERN int rc_did_emsg INIT(= FALSE); /* vim_regcomp() called emsg() */
+
+EXTERN int no_wait_return INIT(= 0); /* don't wait for return for now */
+EXTERN int need_wait_return INIT(= 0); /* need to wait for return later */
+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(__EMX__) || defined(VMS) || 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 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 */
+
+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 */
+
+EXTERN int ex_nesting_level INIT(= 0); /* nesting level */
+EXTERN int debug_break_level INIT(= -1); /* break below this level */
+EXTERN int debug_did_msg INIT(= FALSE); /* did "debug mode" message */
+EXTERN int debug_tick INIT(= 0); /* breakpoint change count */
+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.
+ */
+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);
+
+/*
+ * 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);
+
+/*
+ * 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.
+ */
+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);
+
+/*
+ * 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);
+
+/* ID of script being sourced or was sourced to define the current function. */
+EXTERN scid_T current_SID 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 scroll_region INIT(= FALSE); /* term supports scroll region */
+EXTERN int t_colors INIT(= 0); /* int value of T_CCO */
+
+/*
+ * When highlight_match is TRUE, highlight a match, starting at the cursor
+ * position. Search_match_lines is the number of lines after the match (0 for
+ * a match within one line), search_match_endcol the column number of the
+ * character just after the match in the last line.
+ */
+EXTERN int highlight_match INIT(= FALSE); /* show search match pos */
+EXTERN linenr_T search_match_lines; /* lines of of matched string */
+EXTERN colnr_T search_match_endcol; /* col nr of match end */
+
+EXTERN int no_smartcase INIT(= FALSE); /* don't use 'smartcase' once */
+
+EXTERN int need_check_timestamps INIT(= FALSE); /* need to check file
+ timestamps asap */
+EXTERN int did_check_timestamps INIT(= FALSE); /* did check timestamps
+ recently */
+EXTERN int no_check_timestamps INIT(= 0); /* Don't check timestamps */
+
+EXTERN int highlight_attr[HLF_COUNT]; /* Highl. attr for each context. */
+# define USER_HIGHLIGHT
+#ifdef USER_HIGHLIGHT
+EXTERN int highlight_user[9]; /* User[1-9] attributes */
+EXTERN int highlight_stlnc[9]; /* On top of user */
+#endif
+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 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 */
+EXTERN int modified_was_set; /* did ":set modified" */
+EXTERN int did_filetype INIT(= FALSE); /* FileType event found */
+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);
+
+/*
+ * Mouse coordinates, set by check_termcode()
+ */
+EXTERN int mouse_row;
+EXTERN int mouse_col;
+EXTERN int mouse_past_bottom INIT(= FALSE); /* mouse below last line */
+EXTERN int mouse_past_eol INIT(= FALSE); /* mouse right of line */
+EXTERN int mouse_dragging INIT(= 0); /* extending Visual area with
+ mouse dragging */
+/*
+ * When the DEC mouse has been pressed but not yet released we enable
+ * automatic querys for the mouse position.
+ */
+EXTERN int WantQueryMouse INIT(= FALSE);
+
+
+
+
+/* Value set from 'diffopt'. */
+EXTERN int diff_context INIT(= 6); /* context for folds */
+EXTERN int diff_foldcolumn INIT(= 2); /* 'foldcolumn' for diff mode */
+EXTERN int diff_need_scrollbind INIT(= FALSE);
+
+/* The root of the menu hierarchy. */
+EXTERN vimmenu_T *root_menu INIT(= NULL);
+/*
+ * While defining the system menu, sys_menu is TRUE. This avoids
+ * overruling of menus that the user already defined.
+ */
+EXTERN int sys_menu INIT(= FALSE);
+
+/* While redrawing the screen this flag is set. It means the screen size
+ * ('lines' and 'rows') must not be changed. */
+EXTERN int updating_screen INIT(= FALSE);
+
+
+
+/*
+ * All windows are linked in a list. firstwin points to the first entry,
+ * lastwin to the last entry (can be the same as firstwin) and curwin to the
+ * currently active window.
+ * Without the FEAT_WINDOWS they are all equal.
+ */
+EXTERN win_T *firstwin; /* first window */
+EXTERN win_T *lastwin; /* last window */
+EXTERN win_T *prevwin INIT(= NULL); /* previous window */
+# define W_NEXT(wp) ((wp)->w_next)
+# define FOR_ALL_WINDOWS(wp) for (wp = firstwin; wp != NULL; wp = wp->w_next)
+/*
+ * When using this macro "break" only breaks out of the inner loop. Use "goto"
+ * to break out of the tabpage loop.
+ */
+# define FOR_ALL_TAB_WINDOWS(tp, wp) \
+ for ((tp) = first_tabpage; (tp) != NULL; (tp) = (tp)->tp_next) \
+ for ((wp) = ((tp) == curtab) \
+ ? firstwin : (tp)->tp_firstwin; (wp); (wp) = (wp)->w_next)
+
+EXTERN win_T *curwin; /* currently active window */
+
+EXTERN win_T *aucmd_win; /* window used in aucmd_prepbuf() */
+EXTERN int aucmd_win_used INIT(= FALSE); /* aucmd_win is being used */
+
+/*
+ * The window layout is kept in a tree of frames. topframe points to the top
+ * of the tree.
+ */
+EXTERN frame_T *topframe; /* top of the window frame tree */
+
+/*
+ * Tab pages are alternative topframes. "first_tabpage" points to the first
+ * one in the list, "curtab" is the current one.
+ */
+EXTERN tabpage_T *first_tabpage;
+EXTERN tabpage_T *curtab;
+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 */
+
+/* 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 */
+
+/*
+ * List of files being edited (global argument list). curwin->w_alist points
+ * to this when the window is using the global argument list.
+ */
+EXTERN alist_T global_alist; /* global argument list */
+EXTERN int 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 */
+
+#ifdef TEMPDIRNAMES
+EXTERN char_u *vim_tempdir INIT(= NULL); /* Name of Vim's own temp dir.
+ Ends in a slash. */
+#endif
+
+/*
+ * 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. */
+EXTERN int really_exiting INIT(= FALSE);
+/* TRUE when we are sure to exit, e.g., after
+ * a deadly signal */
+/* 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 as "rvim" */
+EXTERN int secure INIT(= FALSE);
+/* non-zero when only "safe" commands are
+ * allowed, e.g. when sourcing .exrc or .vimrc
+ * in current directory */
+
+EXTERN int textlock INIT(= 0);
+/* non-zero when changing text and jumping to
+ * another window or buffer is not allowed */
+
+EXTERN int curbuf_lock INIT(= 0);
+/* non-zero when the current buffer can't be
+ * changed. Used for FileChangedRO. */
+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. */
+# define HAVE_SANDBOX
+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 */
+
+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 */
+
+EXTERN int redo_VIsual_busy INIT(= FALSE);
+/* TRUE when redoing Visual */
+
+/*
+ * 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;
+
+/*
+ * This flag is used to make auto-indent work right on lines where only a
+ * <RETURN> or <ESC> is typed. It is set when an auto-indent is done, and
+ * 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);
+
+/*
+ * Column of first char after autoindent. 0 when no autoindent done. Used
+ * when 'backspace' is 0, to avoid backspacing over autoindent.
+ */
+EXTERN colnr_T ai_col INIT(= 0);
+
+/*
+ * This is a character which will end a start-middle-end comment when typed as
+ * the first character on a new line. It is taken from the last character of
+ * the "end" comment leader when the COM_AUTO_END flag is given for that
+ * comment end in 'comments'. It is only valid when did_ai is TRUE.
+ */
+EXTERN int end_comment_pending INIT(= NUL);
+
+/*
+ * This flag is set after a ":syncbind" to let the check_scrollbind() function
+ * know that it should not attempt to perform scrollbinding due to the scroll
+ * that was a result of the ":syncbind." (Otherwise, check_scrollbind() will
+ * undo some of the work done by ":syncbind.") -ralston
+ */
+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);
+
+/*
+ * 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);
+
+/*
+ * 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 pos_T saved_cursor /* w_cursor before formatting text. */
+#ifdef DO_INIT
+ = INIT_POS_T(0, 0, 0)
+#endif
+;
+
+/*
+ * Stuff for insert mode.
+ */
+EXTERN pos_T Insstart; /* This is where the latest
+ * insert/append mode started. */
+/*
+ * Stuff for VREPLACE mode.
+ */
+EXTERN int orig_line_count INIT(= 0); /* Line count when "gR" started */
+EXTERN int vr_lines_changed INIT(= 0); /* #Lines changed by "gR" so far */
+
+
+#if defined(HAVE_SETJMP_H)
+/*
+ * Stuff for setjmp() and longjmp().
+ * Used to protect areas where we could crash.
+ */
+EXTERN JMP_BUF lc_jump_env; /* argument to SETJMP() */
+# ifdef SIGHASARG
+/* volatile because it is used in signal handlers. */
+EXTERN volatile int lc_signal; /* caught signal number, 0 when no was signal
+ caught; used for mch_libcall() */
+# endif
+/* volatile because it is used in signal handler deathtrap(). */
+EXTERN volatile int lc_active INIT(= FALSE); /* TRUE when lc_jump_env is valid. */
+#endif
+
+/*
+ * These flags are set based upon 'fileencoding'.
+ * Note that "enc_utf8" is also set for "unicode", because the characters are
+ * internally stored as UTF-8 (to avoid trouble with NUL bytes).
+ */
+# define DBCS_JPN 932 /* japan */
+# define DBCS_JPNU 9932 /* euc-jp */
+# define DBCS_KOR 949 /* korea */
+# define DBCS_KORU 9949 /* euc-kr */
+# define DBCS_CHS 936 /* chinese */
+# define DBCS_CHSU 9936 /* euc-cn */
+# define DBCS_CHT 950 /* taiwan */
+# define DBCS_CHTU 9950 /* euc-tw */
+# 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 int 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 */
+
+
+/*
+ * 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];
+
+/* Variables that tell what conversion is used for keyboard input and display
+ * output. */
+EXTERN vimconv_T input_conv; /* type of input conversion */
+EXTERN vimconv_T output_conv; /* type of output conversion */
+
+/*
+ * 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)__ARGS((char_u *p)) INIT(= latin_ptr2len);
+/* idem, with limit on string length */
+EXTERN int (*mb_ptr2len_len)__ARGS((char_u *p, int size)) INIT(
+ = latin_ptr2len_len);
+/* byte length of char */
+EXTERN int (*mb_char2len)__ARGS((int c)) INIT(= latin_char2len);
+/* convert char to bytes, return the length */
+EXTERN int (*mb_char2bytes)__ARGS((int c, char_u *buf)) INIT(= latin_char2bytes);
+EXTERN int (*mb_ptr2cells)__ARGS((char_u *p)) INIT(= latin_ptr2cells);
+EXTERN int (*mb_ptr2cells_len)__ARGS((char_u *p, int size)) INIT(
+ = latin_ptr2cells_len);
+EXTERN int (*mb_char2cells)__ARGS((int c)) INIT(= latin_char2cells);
+EXTERN int (*mb_off2cells)__ARGS((unsigned off, unsigned max_off)) INIT(
+ = latin_off2cells);
+EXTERN int (*mb_ptr2char)__ARGS((char_u *p)) INIT(= latin_ptr2char);
+EXTERN int (*mb_head_off)__ARGS((char_u *base, 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,
+ char **outbuf, size_t *outbytesleft);
+EXTERN iconv_t (*iconv_open)(const char *tocode, const char *fromcode);
+EXTERN int (*iconv_close)(iconv_t cd);
+EXTERN int (*iconvctl)(iconv_t cd, int request, void *argument);
+EXTERN int* (*iconv_errno)(void);
+# endif
+
+
+
+EXTERN int composing_hangul INIT(= 0);
+EXTERN char_u composing_hangul_buffer[5];
+
+/*
+ * "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. */
+
+EXTERN int finish_op INIT(= FALSE); /* TRUE while an operator is pending */
+EXTERN int opcount INIT(= 0); /* count 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 */
+
+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 restart_edit INIT(= 0); /* call edit when next cmd finished */
+EXTERN int arrow_used; /* Normally FALSE, set to TRUE after
+ * hitting cursor key in insert mode.
+ * Used by vgetorpeek() to decide when
+ * to call u_sync() */
+EXTERN int ins_at_eol INIT(= FALSE); /* put cursor after eol when
+ restarting edit after CTRL-O */
+EXTERN char_u *edit_submode INIT(= NULL); /* msg for CTRL-X submode */
+EXTERN char_u *edit_submode_pre INIT(= NULL); /* prepended to edit_submode */
+EXTERN char_u *edit_submode_extra INIT(= NULL); /* appended to edit_submode */
+EXTERN hlf_T edit_submode_highl; /* highl. method for extra info */
+EXTERN int ctrl_x_mode INIT(= 0); /* Which Ctrl-X mode are we in? */
+
+EXTERN int no_abbr INIT(= TRUE); /* TRUE when no abbreviations loaded */
+
+#ifdef USE_EXE_NAME
+EXTERN char_u *exe_name; /* the name of the executable */
+#endif
+
+#ifdef USE_ON_FLY_SCROLL
+EXTERN int dont_scroll INIT(= FALSE); /* don't use scrollbars when TRUE */
+#endif
+EXTERN int mapped_ctrl_c INIT(= FALSE); /* CTRL-C is mapped */
+EXTERN int ctrl_c_interrupts INIT(= TRUE); /* CTRL-C sets got_int */
+
+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 */
+
+#define HAS_SWAP_EXISTS_ACTION
+EXTERN int swap_exists_action INIT(= SEA_NONE);
+/* For dialog when swap file already
+ * exists. */
+EXTERN int swap_exists_did_quit INIT(= FALSE);
+/* Selected "quit" at the dialog. */
+
+EXTERN char_u *IObuff; /* sprintf's are done in this buffer,
+ size is IOSIZE */
+EXTERN char_u *NameBuff; /* file names are expanded in this
+ * buffer, size is MAXPATHL */
+EXTERN char_u msg_buf[MSG_BUF_LEN]; /* small buffer for messages */
+
+/* When non-zero, postpone redrawing. */
+EXTERN int RedrawingDisabled INIT(= 0);
+
+EXTERN int readonlymode INIT(= FALSE); /* Set to TRUE for "view" */
+EXTERN int recoverymode INIT(= FALSE); /* Set to TRUE for "-r" option */
+
+EXTERN struct buffheader stuffbuff /* stuff buffer */
+#ifdef DO_INIT
+ = {{NULL, {NUL}}, NULL, 0, 0}
+#endif
+;
+EXTERN typebuf_T typebuf /* typeahead buffer */
+#ifdef DO_INIT
+ = {NULL, NULL, 0, 0, 0, 0, 0, 0, 0}
+#endif
+;
+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 int KeyStuffed; /* TRUE if current char from stuffbuf */
+#ifdef USE_IM_CONTROL
+EXTERN int vgetc_im_active; /* Input Method was active for last
+ character obtained from vgetc() */
+#endif
+EXTERN int maptick INIT(= 0); /* tick for each non-mapped char */
+
+EXTERN char_u 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 */
+
+EXTERN int need_highlight_changed INIT(= TRUE);
+EXTERN char_u *use_viminfo INIT(= NULL); /* name of viminfo 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 int read_cmd_fd INIT(= 0); /* fd to read commands from */
+
+/* volatile because it is used in signal handler catch_sigint(). */
+EXTERN volatile int got_int INIT(= FALSE); /* set to TRUE when interrupt
+ signal occurred */
+#ifdef USE_TERM_CONSOLE
+EXTERN int term_console INIT(= FALSE); /* set to TRUE when console used */
+#endif
+EXTERN int termcap_active INIT(= FALSE); /* set by starttermcap() */
+EXTERN int cur_tmode INIT(= TMODE_COOK); /* input terminal mode */
+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:
+ * REX_SET to allow \z\(...\),
+ * REX_USE to allow \z\1 et al. */
+EXTERN reg_extmatch_T *re_extmatch_in INIT(= NULL); /* Used by vim_regexec():
+ * strings for \z\1...\z\9 */
+EXTERN reg_extmatch_T *re_extmatch_out INIT(= NULL); /* Set by vim_regexec()
+ * to store \z\(...\) matches */
+
+EXTERN int did_outofmem_msg INIT(= FALSE);
+/* set after out of memory msg */
+EXTERN int did_swapwrite_msg INIT(= FALSE);
+/* set after swap write error msg */
+EXTERN int undo_off INIT(= FALSE); /* undo switched off for now */
+EXTERN int global_busy INIT(= 0); /* set when :global is executing */
+EXTERN int listcmd_busy INIT(= FALSE); /* set when :argdo, :windo or
+ :bufdo is executing */
+EXTERN int need_start_insertmode INIT(= FALSE);
+/* start insert mode soon */
+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 */
+EXTERN pos_T last_cursormoved /* for CursorMoved event */
+# ifdef DO_INIT
+ = INIT_POS_T(0, 0, 0)
+# endif
+;
+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 */
+EXTERN int g_do_tagpreview INIT(= 0); /* for tag preview commands:
+ height of preview window */
+EXTERN int replace_offset INIT(= 0); /* offset for replace_push() */
+
+EXTERN char_u *escape_chars INIT(= (char_u *)" \t\\\"|");
+/* need backslash in cmd line */
+
+EXTERN int keep_help_flag INIT(= FALSE); /* doing :ta from help file */
+
+/*
+ * When a string option is NULL (which only happens in out-of-memory
+ * situations), it is set to empty_option, to avoid having to check for NULL
+ * everywhere.
+ */
+EXTERN char_u *empty_option INIT(= (char_u *)"");
+
+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 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 */
+
+
+EXTERN char breakat_flags[256]; /* which characters are in 'breakat' */
+
+/* these are in version.c */
+extern char *Version;
+extern char *longVersion;
+
+/*
+ * Some file names are stored in pathdef.c, which is generated from the
+ * Makefile to make their value depend on the Makefile.
+ */
+#ifdef HAVE_PATHDEF
+extern char_u *default_vim_dir;
+extern char_u *default_vimruntime_dir;
+extern char_u *all_cflags;
+extern char_u *all_lflags;
+extern char_u *compiled_user;
+extern char_u *compiled_sys;
+#endif
+
+/* When a window has a local directory, the absolute path of the global
+ * current directory is stored here (in allocated memory). If the current
+ * directory is not a local directory, globaldir is NULL. */
+EXTERN char_u *globaldir INIT(= NULL);
+
+/* Characters from 'listchars' option */
+EXTERN int lcs_eol INIT(= '$');
+EXTERN int lcs_ext INIT(= NUL);
+EXTERN int lcs_prec INIT(= NUL);
+EXTERN int lcs_nbsp INIT(= NUL);
+EXTERN int lcs_tab1 INIT(= NUL);
+EXTERN int lcs_tab2 INIT(= NUL);
+EXTERN int lcs_trail INIT(= NUL);
+EXTERN int lcs_conceal INIT(= '-');
+
+/* Characters from 'fillchars' option */
+EXTERN int fill_stl INIT(= ' ');
+EXTERN int fill_stlnc INIT(= ' ');
+EXTERN int fill_vert INIT(= ' ');
+EXTERN int fill_fold INIT(= '-');
+EXTERN int fill_diff 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 char_u no_lines_msg[] INIT(= N_("--No lines in buffer--"));
+
+/*
+ * When ":global" is used to number of substitutions and changed lines is
+ * accumulated until it's finished.
+ * Also used for ":spellrepall".
+ */
+EXTERN long sub_nsubs; /* total number of substitutions */
+EXTERN linenr_T sub_nlines; /* total number of lines changed */
+
+/* table to store parsed 'wildmode' */
+EXTERN char_u wim_flags[4];
+
+/* whether titlestring and iconstring contains statusline syntax */
+# define STL_IN_ICON 1
+# define STL_IN_TITLE 2
+EXTERN int stl_syntax INIT(= 0);
+
+/* don't use 'hlsearch' temporarily */
+EXTERN int no_hlsearch INIT(= FALSE);
+
+
+#ifdef CURSOR_SHAPE
+/* the table is in misc2.c, because of initializations */
+extern cursorentry_T shape_table[SHAPE_IDX_COUNT];
+#endif
+
+/*
+ * Printer stuff shared between hardcopy.c and machine-specific printing code.
+ */
+# define OPT_PRINT_TOP 0
+# define OPT_PRINT_BOT 1
+# define OPT_PRINT_LEFT 2
+# define OPT_PRINT_RIGHT 3
+# define OPT_PRINT_HEADERHEIGHT 4
+# define OPT_PRINT_SYNTAX 5
+# define OPT_PRINT_NUMBER 6
+# define OPT_PRINT_WRAP 7
+# define OPT_PRINT_DUPLEX 8
+# define OPT_PRINT_PORTRAIT 9
+# define OPT_PRINT_PAPER 10
+# define OPT_PRINT_COLLATE 11
+# define OPT_PRINT_JOBSPLIT 12
+# define OPT_PRINT_FORMFEED 13
+
+# define OPT_PRINT_NUM_OPTIONS 14
+
+EXTERN option_table_T printer_opts[OPT_PRINT_NUM_OPTIONS]
+# ifdef DO_INIT
+ =
+ {
+ {"top", TRUE, 0, NULL, 0, FALSE},
+ {"bottom", TRUE, 0, NULL, 0, FALSE},
+ {"left", TRUE, 0, NULL, 0, FALSE},
+ {"right", TRUE, 0, NULL, 0, FALSE},
+ {"header", TRUE, 0, NULL, 0, FALSE},
+ {"syntax", FALSE, 0, NULL, 0, FALSE},
+ {"number", FALSE, 0, NULL, 0, FALSE},
+ {"wrap", FALSE, 0, NULL, 0, FALSE},
+ {"duplex", FALSE, 0, NULL, 0, FALSE},
+ {"portrait", FALSE, 0, NULL, 0, FALSE},
+ {"paper", FALSE, 0, NULL, 0, FALSE},
+ {"collate", FALSE, 0, NULL, 0, FALSE},
+ {"jobsplit", FALSE, 0, NULL, 0, FALSE},
+ {"formfeed", FALSE, 0, NULL, 0, FALSE},
+ }
+
+# endif
+;
+
+/* For prt_get_unit(). */
+# define PRT_UNIT_NONE -1
+# define PRT_UNIT_PERC 0
+# define PRT_UNIT_INCH 1
+# define PRT_UNIT_MM 2
+# define PRT_UNIT_POINT 3
+# define PRT_UNIT_NAMES {"pc", "in", "mm", "pt"}
+
+/* Page number used for %N in 'pageheader' and 'guitablabel'. */
+EXTERN linenr_T printer_page_num;
+
+
+EXTERN int typebuf_was_filled INIT(= FALSE); /* received text from client
+ or from feedkeys() */
+
+
+#if defined(UNIX) || defined(VMS)
+EXTERN int term_is_xterm INIT(= FALSE); /* xterm-like 'term' */
+#endif
+
+#ifdef BACKSLASH_IN_FILENAME
+EXTERN char psepc INIT(= '\\'); /* normal path separator character */
+EXTERN char psepcN INIT(= '/'); /* abnormal path separator character */
+EXTERN char pseps[2] /* normal path separator string */
+# ifdef DO_INIT
+ = {'\\', 0}
+# endif
+;
+#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);
+
+/* Display tick, incremented for each call to update_screen() */
+EXTERN disptick_T display_tick INIT(= 0);
+
+/* Line in which spell checking wasn't highlighted because it touched the
+ * 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
+# ifdef DO_INIT
+ = {0, 0, 0, 0, NULL}
+# endif
+;
+#endif
+
+
+/*
+ * The error messages that can be shared are included here.
+ * Excluded are errors that are only used once and debugging messages.
+ */
+EXTERN char_u e_abort[] INIT(= N_("E470: Command aborted"));
+EXTERN char_u e_argreq[] INIT(= N_("E471: Argument required"));
+EXTERN char_u e_backslash[] INIT(= N_("E10: \\ should be followed by /, ? or &"));
+EXTERN char_u e_cmdwin[] INIT(= N_(
+ "E11: Invalid in command-line window; <CR> executes, CTRL-C quits"));
+EXTERN char_u e_curdir[] INIT(= N_(
+ "E12: Command not allowed from exrc/vimrc in current dir or tag search"));
+EXTERN char_u e_endif[] INIT(= N_("E171: Missing :endif"));
+EXTERN char_u e_endtry[] INIT(= N_("E600: Missing :endtry"));
+EXTERN char_u e_endwhile[] INIT(= N_("E170: Missing :endwhile"));
+EXTERN char_u e_endfor[] INIT(= N_("E170: Missing :endfor"));
+EXTERN char_u e_while[] INIT(= N_("E588: :endwhile without :while"));
+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_interr[] INIT(= N_("Interrupted"));
+EXTERN char_u e_invaddr[] INIT(= N_("E14: Invalid address"));
+EXTERN char_u e_invarg[] INIT(= N_("E474: Invalid argument"));
+EXTERN char_u e_invarg2[] INIT(= N_("E475: Invalid argument: %s"));
+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"));
+#ifdef FEAT_LIBCALL
+EXTERN char_u e_libcall[] INIT(= N_("E364: Library call failed for \"%s()\""));
+#endif
+EXTERN char_u e_markinval[] INIT(= N_("E19: Mark has invalid line number"));
+EXTERN char_u e_marknotset[] INIT(= N_("E20: Mark not set"));
+EXTERN char_u e_modifiable[] INIT(= N_(
+ "E21: Cannot make changes, 'modifiable' is off"));
+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: GUI cannot be used: Not enabled at compile time"));
+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"));
+EXTERN char_u e_nomap[] INIT(= N_("E31: No such mapping"));
+EXTERN char_u e_nomatch[] INIT(= N_("E479: No match"));
+EXTERN char_u e_nomatch2[] INIT(= N_("E480: No match: %s"));
+EXTERN char_u e_noname[] INIT(= N_("E32: No file name"));
+EXTERN char_u e_nopresub[] INIT(= N_(
+ "E33: No previous substitute regular expression"));
+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_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)"));
+EXTERN char_u e_nowrtmsg_nobang[] INIT(= N_("E37: No write since last change"));
+EXTERN char_u e_null[] INIT(= N_("E38: Null argument"));
+EXTERN char_u e_number_exp[] INIT(= N_("E39: Number expected"));
+EXTERN char_u e_openerrf[] INIT(= N_("E40: Can't open errorfile %s"));
+EXTERN char_u e_outofmem[] INIT(= N_("E41: Out of memory!"));
+EXTERN char_u e_patnotf[] INIT(= N_("Pattern not found"));
+EXTERN char_u e_patnotf2[] INIT(= N_("E486: Pattern not found: %s"));
+EXTERN char_u e_positive[] INIT(= N_("E487: Argument must be positive"));
+EXTERN char_u e_prev_dir[] INIT(= N_(
+ "E459: Cannot go back to previous directory"));
+
+EXTERN char_u e_quickfix[] INIT(= N_("E42: No Errors"));
+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\""));
+EXTERN char_u e_readerrf[] INIT(= N_("E47: Error while reading errorfile"));
+#ifdef HAVE_SANDBOX
+EXTERN char_u e_sandbox[] INIT(= N_("E48: Not allowed in sandbox"));
+#endif
+EXTERN char_u e_secure[] INIT(= N_("E523: Not allowed here"));
+#if defined(AMIGA) || defined(MACOS) || defined(MSWIN) \
+ || defined(UNIX) || defined(VMS) || defined(OS2)
+EXTERN char_u e_screenmode[] INIT(= N_(
+ "E359: Screen mode setting not supported"));
+#endif
+EXTERN char_u e_scroll[] INIT(= N_("E49: Invalid scroll size"));
+EXTERN char_u e_shellempty[] INIT(= N_("E91: 'shell' option is empty"));
+EXTERN char_u e_swapclose[] INIT(= N_("E72: Close error on swap file"));
+EXTERN char_u e_tagstack[] INIT(= N_("E73: tag stack empty"));
+EXTERN char_u e_toocompl[] INIT(= N_("E74: Command too complex"));
+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_umark[] INIT(= N_("E78: Unknown mark"));
+EXTERN char_u e_wildexpand[] INIT(= N_("E79: Cannot expand wildcards"));
+EXTERN char_u e_winheight[] INIT(= N_(
+ "E591: 'winheight' cannot be smaller than 'winminheight'"));
+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_maxmempat[] INIT(= N_(
+ "E363: pattern uses more memory than 'maxmempattern'"));
+EXTERN char_u e_emptybuf[] INIT(= N_("E749: empty buffer"));
+
+EXTERN char_u e_invalpat[] INIT(= N_(
+ "E682: Invalid search pattern or delimiter"));
+EXTERN char_u e_bufloaded[] INIT(= N_("E139: File is loaded in another buffer"));
+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 top_bot_msg[] INIT(= N_("search hit TOP, continuing at BOTTOM"));
+EXTERN char bot_top_msg[] INIT(= N_("search hit BOTTOM, continuing at TOP"));
+
+EXTERN char need_key_msg[] INIT(= N_("Need encryption key for \"%s\""));
+
+/*
+ * Comms. with the session manager (XSMP)
+ */
+
+/* For undo we need to know the lowest time possible. */
+EXTERN time_t starttime;
+
+#ifdef STARTUPTIME
+EXTERN FILE *time_fd INIT(= NULL); /* where to write startup timing */
+#endif
+
+/*
+ * Some compilers warn for not using a return value, but in some situations we
+ * can't do anything useful with the value. Assign to this variable to avoid
+ * the warning.
+ */
+EXTERN int ignored;
+EXTERN char *ignoredp;
+
+/*
+ * Optional Farsi support. Include it here, so EXTERN and INIT are defined.
+ */
+# include "farsi.h"
+
+/*
+ * Optional Arabic support. Include it here, so EXTERN and INIT are defined.
+ */
+# include "arabic.h"
diff --git a/src/hangulin.c b/src/hangulin.c
new file mode 100644
index 0000000000..7f41509e83
--- /dev/null
+++ b/src/hangulin.c
@@ -0,0 +1,1518 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * 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.
+ */
+
+#include "vim.h"
+
+#ifndef HANGUL_DEFAULT_KEYBOARD
+# define HANGUL_DEFAULT_KEYBOARD 3
+#endif
+
+#define AUTOMATA_NEW 0
+#define AUTOMATA_CORRECT 1
+#define AUTOMATA_SPECIAL 2
+#define AUTOMATA_CORRECT_NEW 3
+#define AUTOMATA_ERROR 4
+#define AUTOMATA_NULL 5
+
+#define F_F 0x1 /* Ãʼº (initial sound) */
+#define F_M 0x2 /* Áß¼º (medial vowel) */
+#define F_L 0x4 /* Á¾¼º (final consonant) */
+#define F_A 0x8 /* ASCII */
+#define F_NULL 1
+#define M_NULL 2
+#define L_NULL 1
+
+static int hangul_input_state = 0;
+static int f=F_NULL, m=M_NULL, l=L_NULL;
+static int sp=0;
+static char_u stack[20] = {0};
+static int last_l = -1, last_ll = -1;
+static int hangul_keyboard_type = HANGUL_DEFAULT_KEYBOARD;
+
+static void convert_ks_to_3 __ARGS((const char_u *src, int *fp, int *mp,
+ int *lp));
+static int convert_3_to_ks __ARGS((int fv, int mv, int lv, char_u *des));
+static int hangul_automata2 __ARGS((char_u *buf, unsigned int *c));
+static int hangul_automata3 __ARGS((char_u *buf, unsigned int *c));
+
+#define push(x) {stack[ sp++ ] = *(x); stack[sp++] = *((x)+1); }
+#define pop(x) {*((x) + 1) = stack[--sp]; *(x) = stack[--sp]; }
+#define query(x) {*((x) + 1) = stack[sp - 1]; *(x) = stack[sp - 2]; }
+
+#define convert_3_to_code convert_3_to_ks
+
+
+/**********************************************************************/
+/****** 3 ¹ú½ÄÀÚÆÇÀ» À§ÇÑ ·çƾ (Routines for 3 bulsik keyboard) ******/
+/**********************************************************************/
+
+/* 3 ¹ú½Ä¿¡¼­ ÀÚÆÇ º¯È¯ (3 bulsik keyboard conversion) */
+
+static char_u value_table_for_3[] =
+{
+ 24, '"', '#', '$', '%', '&', /* ! " # $ % & */
+ 18, '(', ')', '*', '+', ',', /* ' ( ) * + , */
+ '-', '.', 13, 17, 29, 22, /* - . / 0 1 2 */
+ 19, 19, 26, 5, 12, 28, /* 3 4 5 6 7 8 */
+ 20, ':', 9, '2', '=', '3', /* 9 : ; < = > */
+ '?', '@', 8, '!', 11, 10, /* ? @ A B C D */
+ 26, 3, '/', 39, '8', '4', /* E F G H I J */
+ '5', '6', '1', '0', '9', '>', /* K L M N O P */
+ 28, 6, 7, ';', '7', 16, /* Q R S T U V */
+ 27, 20, '<', 25, '[', 92, /* W X Y Z [ \ */
+ ']', '^', '_', '`', 23, 20, /* ] ^ _ ` a b */
+ 10, 29, 11, 3, 27, 4, /* c d e f g h */
+ 8, 13, 2, 14, 20, 11, /* i j k l m n */
+ 16, 19, 21, 4, 5, 7, /* o p q r s t */
+ 5, 13, 9, 2, 7, 17, /* u v w x y z */
+};
+
+static short_u kind_table_for_3[] =
+{
+ F_L, F_A, F_A, F_A, F_A, F_A, /* ! " # $ % & */
+ F_F, F_A, F_A, F_A, F_A, F_A, /* ' ( ) * + , */
+ F_A, F_A, F_M, F_F, F_L, F_L, /* - . / 0 1 2 */
+ F_L, F_M, F_M, F_M, F_M, F_M, /* 3 4 5 6 7 8 */
+ F_M, F_A, F_F, F_A, F_A, F_A, /* 9 : ; < = > */
+ F_A, F_A, F_L, F_A, F_L, F_L, /* ? @ A B C D */
+ F_L, F_L, F_A, F_A, F_A, F_A, /* E F G H I J */
+ F_A, F_A, F_A, F_A, F_A, F_A, /* K L M N O P */
+ F_L, F_M, F_L, F_A, F_A, F_L, /* Q R S T U V */
+ F_L, F_L, F_A, F_L, F_A, F_A, /* W X Y Z [ \ */
+ F_A, F_A, F_A, F_A, F_L, F_M, /* ] ^ _ ` a b */
+ F_M, F_M, F_M, F_M, F_M, F_F, /* c d e f g h */
+ F_F, F_F, F_F, F_F, F_F, F_F, /* i j k l m n */
+ F_F, F_F, F_L, F_M, F_L, F_M, /* o p q r s t */
+ F_F, F_M, F_L, F_L, F_F, F_L, /* u v w x y z */
+};
+
+/* 3 ¹ú½Ä¿¡¼­ (ÇöÀçÃʼº, ÀԷ¿µ¹®) -> º¹ÇÕÃʼº ó¸®
+ * 3 bulsik: (current initial sound, input english) -> compound initial sound.
+ */
+
+static int comfcon3(v, c)
+int v;
+int c;
+{
+ if (v == 2 && c == 2)
+ return 3;
+ if (v == 5 && c == 5)
+ return 6;
+ if (v == 9 && c == 9)
+ return 10;
+ if (v == 11 && c == 11)
+ return 12;
+ if (v == 14 && c == 14)
+ return 15;
+ return 0;
+}
+
+/* 3 ¹ú½Ä¿¡¼­ (ÇöÀç¸ðÀ½, ÀÔ·Â ¿µ¹®) -> º¹ÇÕ ¸ðÀ½ ó¸®
+ * 3 bulsik: (current vowel, input english) -> compound vowel.
+ */
+
+static int comvow3(v, c)
+int v;
+int c;
+{
+ switch (v) {
+ case 13: /* ¤Ç */
+ switch (c) {
+ case 3: /* ¤Ç¤¿ */
+ return 14;
+ case 4: /* ¤Ç¤À */
+ return 15;
+ case 29: /* ¤Ç¤Ó */
+ return 18;
+ }
+ break;
+
+ case 20: /* ¤Ì */
+ switch (c) {
+ case 7: /* ¤Ì¤Ã */
+ return 21;
+ case 10: /* ¤Ì¤Ä */
+ return 22;
+ case 29: /* ¤Ì¤Ó */
+ return 23;
+ }
+ break;
+
+ /* 3 ¹ú½Ä ÀÚÆÇÀº ¤Ñ¤Ó °¡ ÀÖÀ¸¹Ç·Î ... */
+ }
+ return 0;
+}
+
+/* 3 ¹ú½Ä¿¡¼­ (ÇöÀç ¹Þħ, ¿µ¹®ÀÚ ÀÔ·Â) -> ¹Þħ
+ * 3 bulsik: (current prop(?), input english) -> prop(?).
+ * I want to say, the 'prop' is similar to 'final consonant', but not vowel.
+ * (I cannot find the real english from my dictionary. Sorry!)
+ * VIM: V = initial sound, I = medial vowel, M = final consonant.
+ */
+
+static int comcon3(k, c)
+int k;
+int c;
+{
+ switch (k) {
+ case 2: /* ¤¡ */
+ switch (c) {
+ case 2:
+ return 3; /* ¤¡¤¡ */
+ case 21:
+ return 4; /* ¤¡¤µ */
+ }
+ break;
+
+ case 5: /* ¤¤ */
+ switch (c) {
+ case 24: /* ¤¤¤¸ */
+ return 6;
+ case 29:
+ return 7; /* ¤¤¤¾ */
+ }
+ break;
+
+ case 9: /* ¤© */
+ switch (c) {
+ case 2: /* ¤©¤¡ */
+ return 10;
+ case 17: /* ¤©¤± */
+ return 11;
+ case 19: /* ¤©¤² */
+ return 12;
+ case 21: /* ¤©¤µ */
+ return 13;
+ case 27: /* ¤©¤¼ */
+ return 14;
+ case 28: /* ¤©¤½ */
+ return 15;
+ case 29: /* ¤©¤¾ */
+ return 16;
+ }
+ break;
+
+ case 19:
+ switch (c) {
+ case 21: /* ¤²¤µ */
+ return 20;
+ }
+ break;
+ }
+ return 0;
+}
+
+/**********************************************************************/
+/****** 2 ¹ú½ÄÀÚÆÇÀ» À§ÇÑ ·çƾ (Routines for 2 bulsik keyboard) ******/
+/**********************************************************************/
+
+static int kind_table_for_2(c)
+int c;
+{
+ static char_u table[] =
+ {
+ /* a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s */
+ 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0,
+ /* t, u, v, w, x, y, z */
+ 0, 1, 0, 0, 0, 1, 0
+ };
+
+ if (c <= 'Z')
+ c -= 'A';
+ else
+ c -= 'a';
+
+ return table[c];
+}
+
+/* 2 ¹ú½Ä¿¡¼­ ¿µ¹®ÀÚ -> Á¶ÇÕÇü Ãʼº º¯È¯
+ * (2 bulsik: conversion english char. to initial sound of compound type)
+ * °á°ú: ÃʼºÀÌ ¾Æ´Ï¸é 0 (If it is not initial sound, return 0).
+ */
+static int fcon(c)
+int c;
+{
+ static char_u table[] =
+ {
+ /*E */ 6, /*F */ 0, /*G */ 0, /*H */ 0, /*I */ 0, /*J */ 0, /*K */ 0,
+ /*L */ 0, /*M */ 0, /*N */ 0, /*O */ 0, /*P */ 0, /*Q */ 10, /*R */ 3,
+ /*S */ 0, /*T */ 12, /*U */ 0, /*V */ 0, /*W */ 15, /*X */ 0, /*Y */ 0,
+ /*Z */ 0, /*[ */ 0, /*\ */ 0, /*] */ 0, /*^ */ 0, /*_ */ 0, /*` */ 0,
+ /*a */ 8, /*b */ 0, /*c */ 16, /*d */ 13, /*e */ 5, /*f */ 7, /*g */ 20,
+ /*h */ 0, /*i */ 0, /*j */ 0, /*k */ 0, /*l */ 0, /*m */ 0, /*n */ 0,
+ /*o */ 0, /*p */ 0, /*q */ 9, /*r */ 2, /*s */ 4, /*t */ 11, /*u */ 0,
+ /*v */ 19, /*w */ 14, /*x */ 18, /*y */ 0, /*z */ 17
+ };
+
+ if (c < 'E' || c > 'z')
+ return 0;
+ return table[c - 'E'];
+}
+
+/* 2 ¹ú½Ä¿¡¼­ ¿µ¹®ÀÚ -> Áß¼º º¯È¯
+ * (2 bulsik: conversion english char. to medial vowel)
+ * °á°ú: Áß¼ºÀÌ ¾Æ´Ï¸é 0 (If it is not medial vowel, return 0).
+ */
+static int vow(c)
+int c;
+{
+ static char_u table[] =
+ {
+ /*O */ 6, /*P */ 12, /*Q */ 0, /*R */ 0, /*S */ 0, /*T */ 0, /*U */ 0,
+ /*V */ 0, /*W */ 0, /*X */ 0, /*Y */ 0, /*Z */ 0, /*[ */ 0, /*\ */ 0,
+ /*] */ 0, /*^ */ 0, /*_ */ 0, /*` */ 0, /*a */ 0, /*b */ 26, /*c */ 0,
+ /*d */ 0, /*e */ 0, /*f */ 0, /*g */ 0, /*h */ 13, /*i */ 5, /*j */ 7,
+ /*k */ 3, /*l */ 29, /*m */ 27, /*n */ 20, /*o */ 4, /*p */ 10, /*q */ 0,
+ /*r */ 0, /*s */ 0, /*t */ 0, /*u */ 11, /*v */ 0, /*w */ 0, /*x */ 0,
+ /*y */ 19
+ };
+
+ if (c < 'O' || c > 'y')
+ return 0;
+ return table[c - 'O'];
+}
+
+/* 2¹ú½Ä¿¡¼­ ¿µ¹®ÀÚ -> ¹Þħ º¯È¯
+ * (2 bulsik: conversion english char. to prop)
+ * °á°ú: ¹ÞħÀÌ ¾Æ´Ï¸é 0 (If not prop, return 0)
+ */
+static int lcon(c)
+int c;
+{
+ static char_u table[] =
+ {
+ /*R */ 3, /*S */ 0, /*T */ 22, /*U */ 0, /*V */ 0, /*W */ 0, /*X */ 0,
+ /*Y */ 0, /*Z */ 0, /*[ */ 0, /*\ */ 0, /*] */ 0, /*^ */ 0, /*_ */ 0,
+ /*` */ 0, /*a */ 17, /*b */ 0, /*c */ 25, /*d */ 23, /*e */ 8, /*f */ 9,
+ /*g */ 29, /*h */ 0, /*i */ 0, /*j */ 0, /*k */ 0, /*l */ 0, /*m */ 0,
+ /*n */ 0, /*o */ 0, /*p */ 0, /*q */ 19, /*r */ 2, /*s */ 5, /*t */ 21,
+ /*u */ 0, /*v */ 28, /*w */ 24, /*x */ 27, /*y */ 0, /*z */ 26
+ };
+
+ if (c < 'R' || c > 'z')
+ return 0;
+ return table[c - 'R'];
+}
+
+/* 2 ¹ú½Ä¿¡¼­ (ÇöÀç ¹Þħ, ¿µ¹®ÀÚ ÀÔ·Â) -> ¹Þħ º¯È¯
+ * (2 bulsik: conversion (curr. prop, input english) to prop)
+ */
+
+static int comcon2(k, c)
+int k;
+int c;
+{
+ switch (k) {
+ case 2: /* ¤¡ */
+ switch (c) {
+ case 't':
+ return 4; /* ¤¡¤µ */
+ }
+ break;
+
+ case 5: /* ¤¤ */
+ switch (c) {
+ case 'w': /* ¤¤¤¸ */
+ return 6;
+ case 'g': /* ¤¤¤¾ */
+ return 7;
+ }
+ break;
+
+ case 9: /* ¤© */
+ switch (c) {
+ case 'r': /* ¤©¤¡ */
+ return 10;
+ case 'a': /* ¤©¤± */
+ return 11;
+ case 'q': /* ¤©¤² */
+ return 12;
+ case 't': /* ¤©¤µ */
+ return 13;
+ case 'x': /* ¤©¤¼ */
+ return 14;
+ case 'v': /* ¤©¤½ */
+ return 15;
+ case 'g': /* ¤©¤¾ */
+ return 16;
+ }
+ break;
+
+ case 19: /* ¤² */
+ switch (c) {
+ case 't': /* ¤²¤µ */
+ return 20;
+ }
+ break;
+ }
+ return 0;
+}
+
+/* 2¹ú½Ä¿¡¼­ (ÇöÀç Áß¼º, ¿µ¹® ÀÔ·Â) -> Áß¼º º¯È¯
+ * (2 bulsik: conversion (curr. medial vowel, input english) to medial
+ * vowel)
+ */
+
+static int comvow2(v, c)
+int v;
+int c;
+{
+ switch (v) {
+ case 13: /* ¤Ç */
+ switch (c) {
+ case 'k': /* ¤Ç¤¿ */
+ return 14;
+ case 'o': /* ¤Ç¤À */
+ return 15;
+ case 'l': /* ¤Ç¤Ó */
+ return 18;
+ }
+ break;
+
+ case 20: /* ¤Ì */
+ switch (c) {
+ case 'j': /* ¤Ì¤Ã */
+ return 21;
+ case 'p': /* ¤Ì¤Ä */
+ return 22;
+ case 'l': /* ¤Ì¤Ó */
+ return 23;
+ }
+ break;
+
+ case 27: /* ¤Ñ */
+ switch (c) {
+ case 'l': /* ¤Ñ¤Ó */
+ return 28;
+ }
+ break;
+ }
+ return 0;
+}
+
+int hangul_input_state_get() {
+ return hangul_input_state;
+}
+
+void hangul_input_state_set(state)
+int state;
+{
+ hangul_input_state = state;
+ hangul_input_clear();
+}
+
+int im_get_status() {
+ return hangul_input_state_get();
+}
+
+void hangul_input_state_toggle() {
+ if (hangul_input_state_get()) {
+ hangul_input_state_set(0);
+ if (composing_hangul) {
+ push_raw_key(composing_hangul_buffer, 2);
+ composing_hangul = 0;
+ }
+ } else
+ hangul_input_state_set(1);
+
+ if (showmode()) {
+ setcursor();
+ out_flush();
+ }
+
+}
+
+static int hangul_automata2(buf, c)
+char_u *buf;
+int_u *c;
+{
+ int t,t2;
+
+ if (*c == BS) {
+ if (sp == 0)
+ return AUTOMATA_SPECIAL;
+ else if (sp < 4) {
+ hangul_input_clear();
+ return AUTOMATA_NULL;
+ }
+ pop(buf);
+ query(buf);
+ convert_ks_to_3(buf, &f, &m, &l);
+ last_l = last_ll;
+ last_ll = -1;
+ return AUTOMATA_CORRECT;
+ }
+ if ((!(*c >= 'A' && *c <= 'Z')) && (!(*c >= 'a' && *c <= 'z'))) {
+ hangul_input_clear();
+ return AUTOMATA_SPECIAL;
+ }
+ t = *c;
+ switch (kind_table_for_2(t)) {
+ case 0: /* ÀÚÀ½ (consonant) */
+ if (f == F_NULL) {
+ if (m != M_NULL)
+ hangul_input_clear();
+ f = fcon(t);
+ convert_3_to_code(f, M_NULL, L_NULL, buf);
+ push(buf);
+ last_ll = last_l = -1;
+ return AUTOMATA_NEW;
+ }
+ if (m == M_NULL)
+ return AUTOMATA_ERROR;
+ if (l == L_NULL) {
+ t2 = lcon(t);
+ if (!t2) { /* ¹ÞħÀ¸·Î ÀûÇÕÇÏÁö¾Ê´Ù (cannot use it as a prop) */
+ hangul_input_clear();
+ last_ll = last_l = -1;
+ f = fcon(t);
+ convert_3_to_code(f, m, l, buf);
+ push(buf);
+ return AUTOMATA_NEW;
+ }
+ if (2 == convert_3_to_code(f, m, t2, buf)) {
+ last_ll = -1;
+ last_l = t;
+ l = t2;
+ push(buf);
+ return AUTOMATA_CORRECT;
+ } else { /* ¹ÞħÀ¸·Î ¾²·ÁÇÏ¿´À¸³ª code¿¡ ¾ø´Â ±ÛÀÚÀÌ´Ù */
+ /* cannot find such a prop in the code table */
+ last_ll = last_l = -1;
+ hangul_input_clear();
+ f = fcon(t);
+ convert_3_to_code(f, m, l, buf);
+ push(buf);
+ return AUTOMATA_NEW;
+ }
+ }
+ /* ÃÊ Áß Á¾¼ºÀÌ ¸ðµÎ °®Ãß¾îÁ® ÀÖ´Ù
+ * I have all the 'initial sound' and 'medial vowel' and 'final
+ * consonant'.
+ */
+ t2 = comcon2(l, t);
+ if (t2) {
+ if (2 == convert_3_to_code(f, m, t2, buf)) {
+ l = t2;
+ last_ll = last_l;
+ last_l = t;
+ push(buf);
+ return AUTOMATA_CORRECT;
+ }
+ }
+ last_ll = last_l = -1;
+ hangul_input_clear();
+ f = fcon(t);
+ convert_3_to_code(f, m, l, buf);
+ push(buf);
+ return AUTOMATA_NEW;
+
+ case 1:
+ if (f == F_NULL) {
+ hangul_input_clear();
+ m = vow(t);
+ convert_3_to_code (f, m, L_NULL, buf);
+ push (buf);
+ last_ll = last_l = -1;
+ return AUTOMATA_NEW;
+ }
+ if (m == M_NULL) {
+ m = vow(t);
+ if (2 == convert_3_to_code(f, m, L_NULL, buf)) {
+ last_ll = last_l = -1;
+ push(buf);
+ return AUTOMATA_CORRECT;
+ }
+ m = M_NULL;
+ return AUTOMATA_ERROR;
+ }
+ if (l == L_NULL) {
+ t2 = comvow2(m, t);
+ if (t2) {
+ if (2 != convert_3_to_code(f, t2, L_NULL, buf))
+ return AUTOMATA_ERROR;
+
+ m = t2;
+ push(buf);
+ last_ll = last_l = -1;
+ return AUTOMATA_CORRECT;
+ }
+ return AUTOMATA_ERROR;
+ }
+ pop(buf);
+ pop(buf);
+ sp = 0;
+ if (last_l == -1) {
+ /* À½... ÀÌ°Ô ÇÊ¿äÇϳª?? (Hmm... Is it needed?) */
+ convert_ks_to_3(buf, &f, &m, &l);
+ } else {
+ char_u tmp[3];
+ f = fcon(last_l);
+ convert_3_to_code (f, M_NULL, L_NULL, tmp);
+ push (tmp);
+ }
+ m = vow(t);
+ l = L_NULL;
+ convert_3_to_code(f, m, l, buf + 2);
+ push(buf + 2);
+ return AUTOMATA_CORRECT_NEW;
+
+ default:
+ EMSG(_("E256: Hangul automata ERROR"));
+ break;
+ }
+ return AUTOMATA_ERROR; /* RrEeAaLlLlYy EeRrRrOoRr */
+}
+
+static int hangul_automata3(buf, c)
+char_u *buf;
+int_u *c;
+{
+ int t, t2;
+
+ if (*c >= '!' && *c <= 'z') {
+ *c -= '!';
+ t = value_table_for_3[*c];
+ switch (kind_table_for_3[*c]) {
+ case F_F: /* Ãʼº¹®ÀÚ (char. of an initial sound) */
+ if (m != M_NULL || sp == 0) {
+ /* ÃʼºÀÌ ºñ¾ú°Å³ª ´ÙÀ½ ±ÛÀÚ ¸ðÀ¸±â ½ÃÀÛ
+ * Empty 'initial sound', so starting automata.
+ */
+ hangul_input_clear();
+ f = t;
+ convert_3_to_code(f, M_NULL, L_NULL, buf);
+ push(buf);
+ return AUTOMATA_NEW;
+ }
+ if ((t2 = comfcon3(f,t)) != 0) { /* º¹ÀÚÀ½ (double? consonant) */
+ f=t2;
+ convert_3_to_code(f, M_NULL, L_NULL, buf);
+ push(buf);
+ return AUTOMATA_CORRECT;
+ }
+ return AUTOMATA_ERROR;
+
+ case F_M: /* ¸ðÀ½ (vowel) */
+ if (m == M_NULL) {
+ if (2 != convert_3_to_code(f, t, L_NULL,buf))
+ return AUTOMATA_ERROR;
+
+ m = t;
+ push(buf);
+ if (f == F_NULL)
+ return AUTOMATA_NEW;
+ else
+ return AUTOMATA_CORRECT;
+ }
+ if ((t2 = comvow3(m,t))) { /* º¹¸ðÀ½ (a diphthong) */
+ m = t2;
+ convert_3_to_code(f, m, L_NULL, buf);
+ push(buf);
+ return AUTOMATA_CORRECT;
+ }
+ return AUTOMATA_ERROR;
+
+ case F_L: /* ¹Þħ (prop?) */
+ if (m == M_NULL)
+ return AUTOMATA_ERROR; /* Áß¼º¾ø´Â Á¾¼º */
+ if (l == L_NULL) {
+ if (2 != convert_3_to_code(f, m, t, buf)) {
+ l = L_NULL;
+ return AUTOMATA_ERROR;
+ }
+ push(buf);
+ l = t;
+ return AUTOMATA_CORRECT;
+ }
+ if ((t2 = comcon3(l,t)) != 0) { /* º¹ ¹Þħ ?? (double prop?) */
+ if (2 != convert_3_to_code(f, m, t2, buf))
+ return AUTOMATA_ERROR;
+
+ push(buf);
+ l = t2;
+ return AUTOMATA_CORRECT;
+ }
+ return AUTOMATA_ERROR;
+
+ case F_A: /* Ư¼ö¹®ÀÚ³ª ¼ýÀÚ (special char. or number) */
+ hangul_input_clear();
+ *c = t;
+ return AUTOMATA_SPECIAL;
+ }
+ }
+ if (*c == BS) {
+ if (sp >= 4) {
+ pop(buf);
+ pop(buf);
+ convert_ks_to_3(buf, &f, &m, &l);
+ push(buf);
+ return AUTOMATA_CORRECT;
+ } else if (sp == 0) {
+ return AUTOMATA_SPECIAL;
+ } else {
+ hangul_input_clear();
+ return AUTOMATA_NULL;
+ }
+ }
+ hangul_input_clear();
+ return AUTOMATA_SPECIAL;
+}
+
+void hangul_keyboard_set() {
+ int keyboard;
+ char *s;
+
+ hangul_input_clear();
+
+ if ((s = getenv("VIM_KEYBOARD")) == NULL)
+ s = getenv("HANGUL_KEYBOARD_TYPE");
+
+ if (s) {
+ if (*s == '2')
+ keyboard = 2;
+ else
+ keyboard = 3;
+ hangul_keyboard_type = keyboard;
+ }
+}
+
+int hangul_input_process(s, len)
+char_u *s;
+int len;
+{
+ int n;
+ unsigned int c;
+ char_u hanbuf[20];
+
+ if (len == 1)
+ /* normal key press */
+ c = *s;
+ else if (len == 3 && s[0] == CSI && s[1] == 'k' && s[2] == 'b') {
+ /* backspace */
+ if (composing_hangul)
+ c = Ctrl_H;
+ else
+ return len;
+ } else {
+ if (composing_hangul)
+ push_raw_key(composing_hangul_buffer, 2);
+ hangul_input_clear();
+ composing_hangul = 0;
+ return len;
+ }
+
+ if (hangul_keyboard_type == 2)
+ n = hangul_automata2(hanbuf, &c);
+ else
+ n = hangul_automata3(hanbuf, &c);
+
+ if (n == AUTOMATA_CORRECT) {
+ STRNCPY(composing_hangul_buffer, hanbuf, 2);
+ return 0;
+ } else if (n == AUTOMATA_NEW) {
+ if (composing_hangul)
+ push_raw_key(composing_hangul_buffer, 2);
+ STRNCPY(composing_hangul_buffer, hanbuf, 2);
+ composing_hangul = 1;
+ return 0;
+ } else if (n == AUTOMATA_CORRECT_NEW) {
+ if (composing_hangul)
+ push_raw_key(hanbuf, 2);
+ STRNCPY(composing_hangul_buffer, hanbuf+2, 2);
+ composing_hangul = 1;
+ return 0;
+ } else if (n == AUTOMATA_NULL) {
+ composing_hangul = 0;
+
+ return 0;
+ } else if (n == AUTOMATA_SPECIAL) {
+ if (composing_hangul) {
+ push_raw_key(composing_hangul_buffer, 2);
+ composing_hangul = 0;
+ }
+ *s = c;
+ return 1;
+ } else if (n == AUTOMATA_ERROR) {
+ vim_beep();
+ return 0;
+ }
+ return len;
+}
+
+void hangul_input_clear() {
+ sp = 0;
+ f = F_NULL;
+ m = M_NULL;
+ l = L_NULL;
+}
+
+#define han_index(h, l) (((h)-0xb0)*(0xff-0xa1)+((l)-0xa1))
+
+static const char_u ks_table1[][3] =
+{
+ { 2, 3, 1}, { 2, 3, 2}, { 2, 3, 5}, { 2, 3, 8},
+ { 2, 3, 9}, { 2, 3, 10}, { 2, 3, 11}, { 2, 3, 17},
+ { 2, 3, 19}, { 2, 3, 20}, { 2, 3, 21}, { 2, 3, 22},
+ { 2, 3, 23}, { 2, 3, 24}, { 2, 3, 25}, { 2, 3, 27},
+ { 2, 3, 28}, { 2, 3, 29}, { 2, 4, 1}, { 2, 4, 2},
+ { 2, 4, 5}, { 2, 4, 9}, { 2, 4, 17}, { 2, 4, 19},
+ { 2, 4, 21}, { 2, 4, 22}, { 2, 4, 23}, { 2, 5, 1},
+ { 2, 5, 2}, { 2, 5, 5}, { 2, 5, 9}, { 2, 5, 21},
+ { 2, 5, 23}, { 2, 6, 1}, { 2, 6, 5}, { 2, 6, 9},
+ { 2, 7, 1}, { 2, 7, 2}, { 2, 7, 5}, { 2, 7, 8},
+ { 2, 7, 9}, { 2, 7, 11}, { 2, 7, 17}, { 2, 7, 19},
+ { 2, 7, 21}, { 2, 7, 22}, { 2, 7, 23}, { 2, 7, 24},
+ { 2, 7, 27}, { 2, 7, 28}, { 2, 7, 29}, { 2, 10, 1},
+ { 2, 10, 5}, { 2, 10, 9}, { 2, 10, 17}, { 2, 10, 19},
+ { 2, 10, 21}, { 2, 10, 22}, { 2, 10, 23}, { 2, 11, 1},
+ { 2, 11, 2}, { 2, 11, 3}, { 2, 11, 5}, { 2, 11, 8},
+ { 2, 11, 9}, { 2, 11, 17}, { 2, 11, 19}, { 2, 11, 21},
+ { 2, 11, 22}, { 2, 11, 23}, { 2, 11, 27}, { 2, 12, 1},
+ { 2, 12, 5}, { 2, 12, 9}, { 2, 12, 19}, { 2, 12, 21},
+ { 2, 13, 1}, { 2, 13, 2}, { 2, 13, 5}, { 2, 13, 8},
+ { 2, 13, 9}, { 2, 13, 11}, { 2, 13, 13}, { 2, 13, 16},
+ { 2, 13, 17}, { 2, 13, 19}, { 2, 13, 21}, { 2, 13, 23},
+ { 2, 13, 24}, { 2, 14, 1}, { 2, 14, 2}, { 2, 14, 5},
+ { 2, 14, 9}, { 2, 14, 11}, { 2, 14, 17}, { 2, 14, 19},
+ { 2, 14, 21}, { 2, 14, 23}, { 2, 15, 1}, { 2, 15, 5},
+ { 2, 15, 9}, { 2, 15, 19}, { 2, 15, 22}, { 2, 15, 23},
+ { 2, 18, 1}, { 2, 18, 2}, { 2, 18, 5}, { 2, 18, 9},
+ { 2, 18, 17}, { 2, 18, 19}, { 2, 18, 21}, { 2, 18, 23},
+ { 2, 19, 1}, { 2, 19, 5}, { 2, 19, 9}, { 2, 19, 19},
+ { 2, 19, 21}, { 2, 20, 1}, { 2, 20, 2}, { 2, 20, 5},
+ { 2, 20, 8}, { 2, 20, 9}, { 2, 20, 10}, { 2, 20, 11},
+ { 2, 20, 16}, { 2, 20, 17}, { 2, 20, 19}, { 2, 20, 21},
+ { 2, 20, 23}, { 2, 20, 24}, { 2, 21, 1}, { 2, 21, 2},
+ { 2, 21, 5}, { 2, 21, 9}, { 2, 21, 22}, { 2, 21, 23},
+ { 2, 22, 1}, { 2, 22, 21}, { 2, 23, 1}, { 2, 23, 2},
+ { 2, 23, 5}, { 2, 23, 9}, { 2, 23, 17}, { 2, 23, 19},
+ { 2, 23, 21}, { 2, 26, 1}, { 2, 26, 5}, { 2, 26, 9},
+ { 2, 27, 1}, { 2, 27, 2}, { 2, 27, 5}, { 2, 27, 8},
+ { 2, 27, 9}, { 2, 27, 10}, { 2, 27, 17}, { 2, 27, 19},
+ { 2, 27, 21}, { 2, 27, 23}, { 2, 28, 1}, { 2, 29, 1},
+ { 2, 29, 2}, { 2, 29, 5}, { 2, 29, 8}, { 2, 29, 9},
+ { 2, 29, 11}, { 2, 29, 17}, { 2, 29, 19}, { 2, 29, 21},
+ { 2, 29, 23}, { 2, 29, 24}, { 2, 29, 28}, { 3, 3, 1},
+ { 3, 3, 2}, { 3, 3, 3}, { 3, 3, 5}, { 3, 3, 9},
+ { 3, 3, 11}, { 3, 3, 17}, { 3, 3, 19}, { 3, 3, 21},
+ { 3, 3, 22}, { 3, 3, 23}, { 3, 3, 27}, { 3, 4, 1},
+ { 3, 4, 2}, { 3, 4, 5}, { 3, 4, 9}, { 3, 4, 17},
+ { 3, 4, 19}, { 3, 4, 21}, { 3, 4, 22}, { 3, 4, 23},
+ { 3, 5, 1}, { 3, 5, 2}, { 3, 5, 9}, { 3, 7, 1},
+ { 3, 7, 2}, { 3, 7, 3}, { 3, 7, 5}, { 3, 7, 9},
+ { 3, 7, 17}, { 3, 7, 19}, { 3, 7, 21}, { 3, 7, 22},
+ { 3, 7, 23}, { 3, 10, 1}, { 3, 10, 2}, { 3, 10, 5},
+ { 3, 10, 17}, { 3, 10, 21}, { 3, 10, 23}, { 3, 11, 1},
+ { 3, 11, 5}, { 3, 11, 9}, { 3, 11, 21}, { 3, 11, 22},
+ { 3, 11, 27}, { 3, 12, 1}, { 3, 13, 1}, { 3, 13, 2},
+ { 3, 13, 5}, { 3, 13, 7}, { 3, 13, 9}, { 3, 13, 17},
+ { 3, 13, 19}, { 3, 13, 21}, { 3, 13, 23}, { 3, 13, 24},
+ { 3, 13, 25}, { 3, 14, 1}, { 3, 14, 2}, { 3, 14, 9},
+ { 3, 14, 22}, { 3, 14, 23}, { 3, 15, 1}, { 3, 15, 2},
+ { 3, 15, 23}, { 3, 18, 1}, { 3, 18, 5}, { 3, 18, 9},
+ { 3, 18, 17}, { 3, 18, 19}, { 3, 18, 23}, { 3, 19, 1},
+ { 3, 20, 1}, { 3, 20, 2}, { 3, 20, 5}, { 3, 20, 9},
+ { 3, 20, 16}, { 3, 20, 17}, { 3, 20, 19}, { 3, 20, 21},
+ { 3, 20, 23}, { 3, 20, 24}, { 3, 21, 1}, { 3, 21, 9},
+ { 3, 21, 22}, { 3, 21, 23}, { 3, 22, 1}, { 3, 22, 2},
+ { 3, 22, 5}, { 3, 22, 9}, { 3, 22, 17}, { 3, 22, 19},
+ { 3, 22, 22}, { 3, 23, 1}, { 3, 23, 5}, { 3, 23, 9},
+ { 3, 23, 17}, { 3, 23, 19}, { 3, 26, 1}, { 3, 27, 1},
+ { 3, 27, 2}, { 3, 27, 5}, { 3, 27, 7}, { 3, 27, 9},
+ { 3, 27, 11}, { 3, 27, 16}, { 3, 27, 17}, { 3, 27, 19},
+ { 3, 27, 21}, { 3, 27, 23}, { 3, 27, 27}, { 3, 29, 1},
+ { 3, 29, 2}, { 3, 29, 5}, { 3, 29, 9}, { 3, 29, 17},
+ { 3, 29, 19}, { 3, 29, 21}, { 3, 29, 23}, { 4, 3, 1},
+ { 4, 3, 2}, { 4, 3, 3}, { 4, 3, 5}, { 4, 3, 8},
+ { 4, 3, 9}, { 4, 3, 10}, { 4, 3, 11}, { 4, 3, 17},
+ { 4, 3, 19}, { 4, 3, 21}, { 4, 3, 22}, { 4, 3, 23},
+ { 4, 3, 24}, { 4, 3, 25}, { 4, 3, 27}, { 4, 3, 29},
+ { 4, 4, 1}, { 4, 4, 2}, { 4, 4, 5}, { 4, 4, 9},
+ { 4, 4, 17}, { 4, 4, 19}, { 4, 4, 21}, { 4, 4, 22},
+ { 4, 4, 23}, { 4, 5, 1}, { 4, 5, 2}, { 4, 5, 5},
+ { 4, 5, 9}, { 4, 5, 17}, { 4, 5, 23}, { 4, 7, 1},
+ { 4, 7, 2}, { 4, 7, 4}, { 4, 7, 5}, { 4, 7, 9},
+ { 4, 7, 11}, { 4, 7, 12}, { 4, 7, 17}, { 4, 7, 19},
+ { 4, 7, 21}, { 4, 7, 22}, { 4, 7, 23}, { 4, 7, 29},
+ { 4, 10, 1}, { 4, 10, 2}, { 4, 10, 5}, { 4, 10, 9},
+ { 4, 10, 17}, { 4, 10, 19}, { 4, 10, 21}, { 4, 10, 22},
+ { 4, 10, 23}, { 4, 11, 1}, { 4, 11, 2}, { 4, 11, 5},
+ { 4, 11, 9}, { 4, 11, 17}, { 4, 11, 19}, { 4, 11, 22},
+ { 4, 11, 23}, { 4, 11, 26}, { 4, 12, 1}, { 4, 12, 5},
+ { 4, 13, 1}, { 4, 13, 2}, { 4, 13, 5}, { 4, 13, 9},
+ { 4, 13, 11}, { 4, 13, 17}, { 4, 13, 19}, { 4, 13, 21},
+ { 4, 13, 23}, { 4, 13, 28}, { 4, 13, 29}, { 4, 14, 1},
+ { 4, 14, 5}, { 4, 14, 9}, { 4, 14, 22}, { 4, 18, 1},
+ { 4, 18, 5}, { 4, 18, 9}, { 4, 18, 17}, { 4, 18, 19},
+ { 4, 18, 21}, { 4, 19, 1}, { 4, 19, 2}, { 4, 19, 5},
+ { 4, 19, 9}, { 4, 19, 19}, { 4, 19, 21}, { 4, 19, 23},
+ { 4, 20, 1}, { 4, 20, 2}, { 4, 20, 5}, { 4, 20, 8},
+ { 4, 20, 9}, { 4, 20, 17}, { 4, 20, 19}, { 4, 20, 21},
+ { 4, 20, 23}, { 4, 21, 1}, { 4, 21, 22}, { 4, 22, 1},
+ { 4, 23, 1}, { 4, 23, 5}, { 4, 23, 9}, { 4, 23, 17},
+ { 4, 23, 19}, { 4, 26, 1}, { 4, 26, 2}, { 4, 26, 9},
+ { 4, 26, 17}, { 4, 26, 19}, { 4, 26, 23}, { 4, 27, 1},
+ { 4, 27, 2}, { 4, 27, 5}, { 4, 27, 9}, { 4, 27, 10},
+ { 4, 27, 11}, { 4, 27, 17}, { 4, 27, 19}, { 4, 27, 21},
+ { 4, 27, 23}, { 4, 27, 24}, { 4, 27, 28}, { 4, 28, 1},
+ { 4, 28, 5}, { 4, 28, 9}, { 4, 29, 1}, { 4, 29, 2},
+ { 4, 29, 5}, { 4, 29, 9}, { 4, 29, 11}, { 4, 29, 17},
+ { 4, 29, 19}, { 4, 29, 21}, { 4, 29, 23}, { 4, 29, 28},
+ { 5, 3, 1}, { 5, 3, 2}, { 5, 3, 3}, { 5, 3, 5},
+ { 5, 3, 8}, { 5, 3, 9}, { 5, 3, 10}, { 5, 3, 11},
+ { 5, 3, 12}, { 5, 3, 16}, { 5, 3, 17}, { 5, 3, 19},
+ { 5, 3, 21}, { 5, 3, 22}, { 5, 3, 23}, { 5, 3, 24},
+ { 5, 3, 25}, { 5, 3, 29}, { 5, 4, 1}, { 5, 4, 2},
+ { 5, 4, 5}, { 5, 4, 9}, { 5, 4, 17}, { 5, 4, 19},
+ { 5, 4, 21}, { 5, 4, 22}, { 5, 4, 23}, { 5, 5, 1},
+ { 5, 7, 1}, { 5, 7, 2}, { 5, 7, 3}, { 5, 7, 5},
+ { 5, 7, 8}, { 5, 7, 9}, { 5, 7, 11}, { 5, 7, 12},
+ { 5, 7, 17}, { 5, 7, 19}, { 5, 7, 21}, { 5, 7, 23},
+ { 5, 7, 25}, { 5, 7, 28}, { 5, 10, 1}, { 5, 10, 2},
+ { 5, 10, 5}, { 5, 10, 9}, { 5, 10, 17}, { 5, 10, 19},
+ { 5, 10, 21}, { 5, 10, 22}, { 5, 10, 23}, { 5, 11, 1},
+ { 5, 11, 5}, { 5, 11, 9}, { 5, 11, 22}, { 5, 11, 23},
+ { 5, 12, 1}, { 5, 12, 5}, { 5, 13, 1}, { 5, 13, 2},
+ { 5, 13, 5}, { 5, 13, 8}, { 5, 13, 9}, { 5, 13, 11},
+ { 5, 13, 13}, { 5, 13, 17}, { 5, 13, 19}, { 5, 13, 21},
+ { 5, 13, 23}, { 5, 13, 25}, { 5, 13, 27}, { 5, 14, 1},
+ { 5, 14, 5}, { 5, 14, 9}, { 5, 15, 1}, { 5, 15, 22},
+ { 5, 18, 1}, { 5, 18, 5}, { 5, 18, 9}, { 5, 18, 17},
+ { 5, 18, 19}, { 5, 18, 21}, { 5, 19, 1}, { 5, 20, 1},
+ { 5, 20, 2}, { 5, 20, 5}, { 5, 20, 9}, { 5, 20, 17},
+ { 5, 20, 19}, { 5, 20, 21}, { 5, 20, 23}, { 5, 21, 1},
+ { 5, 21, 22}, { 5, 22, 1}, { 5, 22, 23}, { 5, 23, 1},
+ { 5, 23, 5}, { 5, 23, 9}, { 5, 23, 19}, { 5, 23, 21},
+ { 5, 23, 23}, { 5, 26, 1}, { 5, 26, 5}, { 5, 26, 9},
+ { 5, 26, 17}, { 5, 26, 23}, { 5, 27, 1}, { 5, 27, 2},
+ { 5, 27, 5}, { 5, 27, 8}, { 5, 27, 9}, { 5, 27, 11},
+ { 5, 27, 17}, { 5, 27, 19}, { 5, 27, 21}, { 5, 27, 23},
+ { 5, 28, 1}, { 5, 29, 1}, { 5, 29, 2}, { 5, 29, 5},
+ { 5, 29, 8}, { 5, 29, 9}, { 5, 29, 17}, { 5, 29, 19},
+ { 5, 29, 21}, { 5, 29, 22}, { 5, 29, 23}, { 5, 29, 24},
+ { 6, 3, 1}, { 6, 3, 2}, { 6, 3, 5}, { 6, 3, 9},
+ { 6, 3, 17}, { 6, 3, 19}, { 6, 3, 21}, { 6, 3, 22},
+ { 6, 3, 23}, { 6, 3, 29}, { 6, 4, 1}, { 6, 4, 2},
+ { 6, 4, 5}, { 6, 4, 9}, { 6, 4, 17}, { 6, 4, 19},
+ { 6, 4, 21}, { 6, 4, 22}, { 6, 4, 23}, { 6, 7, 1},
+ { 6, 7, 2}, { 6, 7, 5}, { 6, 7, 9}, { 6, 7, 11},
+ { 6, 7, 12}, { 6, 7, 17}, { 6, 7, 19}, { 6, 7, 21},
+ { 6, 7, 22}, { 6, 7, 23}, { 6, 7, 29}, { 6, 10, 1},
+ { 6, 10, 2}, { 6, 10, 5}, { 6, 10, 9}, { 6, 10, 17},
+ { 6, 10, 19}, { 6, 10, 21}, { 6, 10, 22}, { 6, 10, 23},
+ { 6, 11, 1}, { 6, 11, 22}, { 6, 13, 1}, { 6, 13, 2},
+ { 6, 13, 5}, { 6, 13, 9}, { 6, 13, 23}, { 6, 14, 1},
+ { 6, 14, 9}, { 6, 15, 1}, { 6, 18, 1}, { 6, 18, 5},
+ { 6, 20, 1}, { 6, 20, 2}, { 6, 20, 5}, { 6, 20, 9},
+ { 6, 20, 16}, { 6, 20, 17}, { 6, 20, 23}, { 6, 22, 1},
+ { 6, 23, 1}, { 6, 23, 5}, { 6, 23, 9}, { 6, 23, 17},
+ { 6, 23, 19}, { 6, 23, 23}, { 6, 27, 1}, { 6, 27, 2},
+ { 6, 27, 5}, { 6, 27, 8}, { 6, 27, 9}, { 6, 27, 17},
+ { 6, 27, 19}, { 6, 27, 21}, { 6, 28, 1}, { 6, 28, 5},
+ { 6, 28, 9}, { 6, 28, 17}, { 6, 28, 19}, { 6, 29, 1},
+ { 6, 29, 5}, { 6, 29, 9}, { 6, 29, 17}, { 6, 29, 19},
+ { 6, 29, 21}, { 6, 29, 23}, { 7, 3, 1}, { 7, 3, 2},
+ { 7, 3, 5}, { 7, 3, 9}, { 7, 3, 17}, { 7, 3, 19},
+ { 7, 3, 21}, { 7, 3, 22}, { 7, 3, 23}, { 7, 3, 24},
+ { 7, 3, 28}, { 7, 3, 29}, { 7, 4, 1}, { 7, 4, 2},
+ { 7, 4, 5}, { 7, 4, 9}, { 7, 4, 17}, { 7, 4, 19},
+ { 7, 4, 21}, { 7, 4, 22}, { 7, 4, 23}, { 7, 5, 1},
+ { 7, 5, 2}, { 7, 5, 5}, { 7, 5, 21}, { 7, 5, 23},
+ { 7, 7, 1}, { 7, 7, 2}, { 7, 7, 5}, { 7, 7, 9},
+ { 7, 7, 17}, { 7, 7, 19}, { 7, 7, 21}, { 7, 7, 22},
+ { 7, 7, 23}, { 7, 7, 29}, { 7, 10, 1}, { 7, 10, 2},
+ { 7, 10, 5}, { 7, 10, 9}, { 7, 10, 17}, { 7, 10, 19},
+ { 7, 10, 21}, { 7, 10, 23}, { 7, 11, 1}, { 7, 11, 2},
+ { 7, 11, 5}, { 7, 11, 9}, { 7, 11, 17}, { 7, 11, 19},
+ { 7, 11, 21}, { 7, 11, 22}, { 7, 11, 23}, { 7, 12, 1},
+ { 7, 12, 5}, { 7, 12, 19}, { 7, 12, 21}, { 7, 13, 1},
+ { 7, 13, 2}, { 7, 13, 5}, { 7, 13, 9}, { 7, 13, 17},
+ { 7, 13, 19}, { 7, 13, 21}, { 7, 13, 23}, { 7, 14, 1},
+ { 7, 14, 5}, { 7, 14, 23}, { 7, 15, 22}, { 7, 18, 1},
+ { 7, 18, 5}, { 7, 18, 9}, { 7, 18, 17}, { 7, 18, 19},
+ { 7, 18, 21}, { 7, 18, 23}, { 7, 19, 1}, { 7, 19, 5},
+ { 7, 19, 9}, { 7, 19, 19}, { 7, 19, 21}, { 7, 19, 23},
+ { 7, 20, 1}, { 7, 20, 2}, { 7, 20, 5}, { 7, 20, 9},
+ { 7, 20, 17}, { 7, 20, 19}, { 7, 20, 21}, { 7, 20, 23},
+ { 7, 21, 1}, { 7, 21, 22}, { 7, 22, 1}, { 7, 23, 1},
+ { 7, 23, 2}, { 7, 23, 5}, { 7, 23, 9}, { 7, 23, 17},
+ { 7, 23, 21}, { 7, 23, 23}, { 7, 26, 1}, { 7, 26, 2},
+ { 7, 26, 5}, { 7, 26, 9}, { 7, 26, 17}, { 7, 26, 19},
+ { 7, 26, 21}, { 7, 26, 23}, { 7, 27, 1}, { 7, 27, 2},
+ { 7, 27, 5}, { 7, 27, 9}, { 7, 27, 17}, { 7, 27, 19},
+ { 7, 27, 21}, { 7, 27, 23}, { 7, 27, 24}, { 7, 27, 27},
+ { 7, 27, 28}, { 7, 29, 1}, { 7, 29, 2}, { 7, 29, 5},
+ { 7, 29, 9}, { 7, 29, 17}, { 7, 29, 19}, { 7, 29, 21},
+ { 7, 29, 23}, { 8, 3, 1}, { 8, 3, 2}, { 8, 3, 5},
+ { 8, 3, 7}, { 8, 3, 8}, { 8, 3, 9}, { 8, 3, 10},
+ { 8, 3, 11}, { 8, 3, 17}, { 8, 3, 19}, { 8, 3, 21},
+ { 8, 3, 23}, { 8, 3, 24}, { 8, 3, 27}, { 8, 3, 29},
+ { 8, 4, 1}, { 8, 4, 2}, { 8, 4, 5}, { 8, 4, 9},
+ { 8, 4, 17}, { 8, 4, 19}, { 8, 4, 21}, { 8, 4, 22},
+ { 8, 4, 23}, { 8, 4, 24}, { 8, 5, 1}, { 8, 5, 2},
+ { 8, 5, 9}, { 8, 5, 23}, { 8, 7, 1}, { 8, 7, 2},
+ { 8, 7, 5}, { 8, 7, 9}, { 8, 7, 11}, { 8, 7, 17},
+ { 8, 7, 19}, { 8, 7, 21}, { 8, 7, 23}, { 8, 7, 24},
+ { 8, 7, 29}, { 8, 10, 1}, { 8, 10, 2}, { 8, 10, 5},
+ { 8, 10, 9}, { 8, 10, 17}, { 8, 10, 19}, { 8, 10, 21},
+ { 8, 10, 22}, { 8, 10, 23}, { 8, 11, 1}, { 8, 11, 2},
+ { 8, 11, 5}, { 8, 11, 9}, { 8, 11, 21}, { 8, 11, 22},
+ { 8, 11, 23}, { 8, 11, 25}, { 8, 12, 1}, { 8, 13, 1},
+ { 8, 13, 2}, { 8, 13, 4}, { 8, 13, 5}, { 8, 13, 9},
+ { 8, 13, 11}, { 8, 13, 17}, { 8, 13, 19}, { 8, 13, 21},
+ { 8, 13, 23}, { 8, 14, 1}, { 8, 14, 5}, { 8, 14, 22},
+ { 8, 14, 23}, { 8, 18, 1}, { 8, 18, 5}, { 8, 18, 9},
+ { 8, 18, 19}, { 8, 18, 21}, { 8, 18, 23}, { 8, 19, 1},
+ { 8, 19, 5}, { 8, 19, 9}, { 8, 19, 19}, { 8, 19, 21},
+ { 8, 20, 1}, { 8, 20, 2}, { 8, 20, 3}, { 8, 20, 5},
+ { 8, 20, 8}, { 8, 20, 9}, { 8, 20, 10}, { 8, 20, 11},
+ { 8, 20, 17}, { 8, 20, 19}, { 8, 20, 21}, { 8, 20, 23},
+ { 8, 20, 27}, { 8, 20, 29}, { 8, 21, 1}, { 8, 21, 5},
+ { 8, 21, 9}, { 8, 21, 19}, { 8, 21, 21}, { 8, 22, 1},
+ { 8, 23, 1}, { 8, 23, 5}, { 8, 23, 9}, { 8, 26, 1},
+ { 8, 26, 5}, { 8, 26, 9}, { 8, 26, 17}, { 8, 26, 21},
+ { 8, 27, 1}, { 8, 27, 5}, { 8, 27, 9}, { 8, 27, 17},
+ { 8, 27, 21}, { 8, 29, 1}, { 8, 29, 2}, { 8, 29, 5},
+ { 8, 29, 8}, { 8, 29, 9}, { 8, 29, 11}, { 8, 29, 17},
+ { 8, 29, 19}, { 8, 29, 21}, { 8, 29, 22}, { 8, 29, 23},
+ { 8, 29, 25}, { 8, 29, 27}, { 9, 3, 1}, { 9, 3, 2},
+ { 9, 3, 3}, { 9, 3, 4}, { 9, 3, 5}, { 9, 3, 8},
+ { 9, 3, 9}, { 9, 3, 10}, { 9, 3, 11}, { 9, 3, 12},
+ { 9, 3, 17}, { 9, 3, 19}, { 9, 3, 21}, { 9, 3, 23},
+ { 9, 3, 27}, { 9, 4, 1}, { 9, 4, 2}, { 9, 4, 5},
+ { 9, 4, 9}, { 9, 4, 17}, { 9, 4, 19}, { 9, 4, 21},
+ { 9, 4, 22}, { 9, 4, 23}, { 9, 4, 27}, { 9, 5, 1},
+ { 9, 5, 2}, { 9, 5, 5}, { 9, 5, 19}, { 9, 7, 1},
+ { 9, 7, 2}, { 9, 7, 5}, { 9, 7, 8}, { 9, 7, 9},
+ { 9, 7, 11}, { 9, 7, 17}, { 9, 7, 19}, { 9, 7, 21},
+ { 9, 7, 23}, { 9, 7, 24}, { 9, 10, 1}, { 9, 10, 2},
+ { 9, 10, 5}, { 9, 10, 8}, { 9, 10, 9}, { 9, 10, 17},
+ { 9, 10, 19}, { 9, 10, 21}, { 9, 10, 22}, { 9, 10, 23},
+ { 9, 11, 1}, { 9, 11, 2}, { 9, 11, 5}, { 9, 11, 9},
+ { 9, 11, 19}, { 9, 11, 21}, { 9, 11, 22}, { 9, 11, 23},
+ { 9, 11, 27}, { 9, 12, 1}, { 9, 12, 5}, { 9, 13, 1},
+ { 9, 13, 2}, { 9, 13, 3}, { 9, 13, 5}, { 9, 13, 9},
+ { 9, 13, 17}, { 9, 13, 19}, { 9, 13, 21}, { 9, 13, 23},
+ { 9, 14, 1}, { 9, 14, 5}, { 9, 14, 22}, { 9, 15, 1},
+ { 9, 15, 22}, { 9, 18, 1}, { 9, 18, 2}, { 9, 18, 5},
+ { 9, 18, 9}, { 9, 18, 17}, { 9, 18, 19}, { 9, 19, 1},
+ { 9, 19, 5}, { 9, 20, 1}, { 9, 20, 2}, { 9, 20, 5},
+ { 9, 20, 8}, { 9, 20, 9}, { 9, 20, 10}, { 9, 20, 11},
+ { 9, 20, 17}, { 9, 20, 19}, { 9, 20, 21}, { 9, 20, 23},
+ { 9, 20, 27}, { 9, 20, 28}, { 9, 21, 1}, { 9, 21, 9},
+ { 9, 21, 22}, { 9, 22, 1}, { 9, 23, 1}, { 9, 23, 2},
+ { 9, 23, 5}, { 9, 23, 9}, { 9, 23, 23}, { 9, 26, 1},
+ { 9, 26, 5}, { 9, 26, 9}, { 9, 26, 17}, { 9, 26, 21},
+ { 9, 26, 23}, { 9, 27, 1}, { 9, 27, 2}, { 9, 27, 5},
+ { 9, 27, 9}, { 9, 27, 17}, { 9, 27, 19}, { 9, 27, 21},
+ { 9, 29, 1}, { 9, 29, 2}, { 9, 29, 5}, { 9, 29, 9},
+ { 9, 29, 11}, { 9, 29, 17}, { 9, 29, 19}, { 9, 29, 21},
+ { 9, 29, 23}, { 9, 29, 24}, { 9, 29, 25}, { 10, 3, 1},
+ { 10, 3, 2}, { 10, 3, 5}, { 10, 3, 9}, { 10, 3, 11},
+ { 10, 3, 17}, { 10, 3, 19}, { 10, 3, 21}, { 10, 3, 22},
+ { 10, 3, 23}, { 10, 3, 29}, { 10, 4, 1}, { 10, 4, 2},
+ { 10, 4, 5}, { 10, 4, 9}, { 10, 4, 17}, { 10, 4, 19},
+ { 10, 4, 21}, { 10, 4, 22}, { 10, 4, 23}, { 10, 5, 1},
+ { 10, 5, 2}, { 10, 5, 17}, { 10, 7, 1}, { 10, 7, 2},
+ { 10, 7, 5}, { 10, 7, 8}, { 10, 7, 9}, { 10, 7, 17},
+ { 10, 7, 21}, { 10, 7, 22}, { 10, 7, 23}, { 10, 10, 1},
+ { 10, 10, 23}, { 10, 11, 1}, { 10, 11, 2}, { 10, 11, 17},
+ { 10, 11, 19}, { 10, 11, 21}, { 10, 11, 22}, { 10, 11, 23},
+ { 10, 13, 1}, { 10, 13, 2}, { 10, 13, 5}, { 10, 13, 9},
+ { 10, 13, 17}, { 10, 13, 19}, { 10, 13, 23}, { 10, 18, 1},
+ { 10, 19, 1}, { 10, 19, 23}, { 10, 20, 1}, { 10, 20, 2},
+ { 10, 20, 5}, { 10, 20, 9}, { 10, 20, 17}, { 10, 20, 21},
+ { 10, 20, 23}, { 10, 26, 1}, { 10, 26, 23}, { 10, 27, 1},
+ { 10, 27, 5}, { 10, 27, 9}, { 10, 27, 17}, { 10, 27, 19},
+ { 10, 29, 1}, { 10, 29, 2}, { 10, 29, 5}, { 10, 29, 9},
+ { 10, 29, 17}, { 10, 29, 19}, { 10, 29, 21}, { 10, 29, 23},
+ { 11, 3, 1}, { 11, 3, 2}, { 11, 3, 4}, { 11, 3, 5},
+ { 11, 3, 8}, { 11, 3, 9}, { 11, 3, 10}, { 11, 3, 11},
+ { 11, 3, 17}, { 11, 3, 19}, { 11, 3, 21}, { 11, 3, 22},
+ { 11, 3, 23}, { 11, 3, 27}, { 11, 4, 1}, { 11, 4, 2},
+ { 11, 4, 5}, { 11, 4, 9}, { 11, 4, 17}, { 11, 4, 19},
+ { 11, 4, 21}, { 11, 4, 22}, { 11, 4, 23}, { 11, 5, 1},
+ { 11, 5, 2}, { 11, 5, 5}, { 11, 5, 9}, { 11, 5, 17},
+ { 11, 5, 19}, { 11, 5, 21}, { 11, 5, 23}, { 11, 6, 1},
+ { 11, 6, 5}, { 11, 6, 9}, { 11, 6, 17}, { 11, 6, 23},
+ { 11, 7, 1}, { 11, 7, 2}, { 11, 7, 3}, { 11, 7, 4},
+ { 11, 7, 5}, { 11, 7, 8}, { 11, 7, 9}, { 11, 7, 11},
+ { 11, 7, 12}, { 11, 7, 17}, { 11, 7, 19}, { 11, 7, 21},
+ { 11, 7, 22}, { 11, 7, 23}, { 11, 7, 28}, { 11, 10, 1},
+ { 11, 10, 2}, { 11, 10, 5}, { 11, 10, 9}, { 11, 10, 17},
+ { 11, 10, 19}, { 11, 10, 21}, { 11, 10, 22}, { 11, 10, 23},
+ { 11, 11, 1}, { 11, 11, 2}, { 11, 11, 5}, { 11, 11, 9},
+ { 11, 11, 17}, { 11, 11, 19}, { 11, 11, 21}, { 11, 11, 22},
+ { 11, 11, 23}, { 11, 12, 1}, { 11, 12, 5}, { 11, 12, 9},
+ { 11, 12, 23}, { 11, 13, 1}, { 11, 13, 2}, { 11, 13, 3},
+ { 11, 13, 5}, { 11, 13, 9}, { 11, 13, 11}, { 11, 13, 17},
+ { 11, 13, 19}, { 11, 13, 21}, { 11, 13, 23}, { 11, 13, 27},
+ { 11, 14, 1}, { 11, 14, 2}, { 11, 14, 5}, { 11, 14, 9},
+ { 11, 14, 23}, { 11, 15, 1}, { 11, 15, 5}, { 11, 15, 9},
+ { 11, 15, 17}, { 11, 15, 21}, { 11, 15, 22}, { 11, 18, 1},
+ { 11, 18, 5}, { 11, 18, 9}, { 11, 18, 17}, { 11, 18, 19},
+ { 11, 18, 21}, { 11, 19, 1}, { 11, 19, 2}, { 11, 19, 5},
+ { 11, 19, 9}, { 11, 19, 17}, { 11, 19, 19}, { 11, 19, 21},
+ { 11, 19, 23}, { 11, 20, 1}, { 11, 20, 2}, { 11, 20, 5},
+ { 11, 20, 8}, { 11, 20, 9}, { 11, 20, 17}, { 11, 20, 19},
+ { 11, 20, 21}, { 11, 20, 23}, { 11, 20, 25}, { 11, 20, 27},
+ { 11, 20, 28}, { 11, 21, 1}, { 11, 21, 22}, { 11, 22, 1},
+ { 11, 22, 2}, { 11, 22, 5}, { 11, 22, 9}, { 11, 22, 17},
+ { 11, 22, 23}, { 11, 23, 1}, { 11, 23, 2}, { 11, 23, 5},
+ { 11, 23, 9}, { 11, 23, 17}, { 11, 23, 19}, { 11, 23, 21},
+ { 11, 23, 23}, { 11, 26, 1}, { 11, 26, 2}, { 11, 26, 9},
+ { 11, 26, 17}, { 11, 26, 21}, { 11, 26, 23}, { 11, 27, 1},
+ { 11, 27, 2}, { 11, 27, 5}, { 11, 27, 9}, { 11, 27, 10},
+ { 11, 27, 17}, { 11, 27, 19}, { 11, 27, 21}, { 11, 27, 23},
+ { 11, 29, 1}, { 11, 29, 2}, { 11, 29, 5}, { 11, 29, 8},
+ { 11, 29, 9}, { 11, 29, 16}, { 11, 29, 17}, { 11, 29, 19},
+ { 11, 29, 21}, { 11, 29, 23}, { 11, 29, 28}, { 12, 3, 1},
+ { 12, 3, 2}, { 12, 3, 4}, { 12, 3, 5}, { 12, 3, 9},
+ { 12, 3, 17}, { 12, 3, 19}, { 12, 3, 22}, { 12, 3, 23},
+ { 12, 3, 29}, { 12, 4, 1}, { 12, 4, 2}, { 12, 4, 5},
+ { 12, 4, 9}, { 12, 4, 17}, { 12, 4, 19}, { 12, 4, 22},
+ { 12, 4, 23}, { 12, 5, 23}, { 12, 7, 1}, { 12, 7, 2},
+ { 12, 7, 5}, { 12, 7, 9}, { 12, 7, 11}, { 12, 7, 17},
+ { 12, 7, 19}, { 12, 7, 22}, { 12, 7, 23}, { 12, 10, 1},
+ { 12, 10, 5}, { 12, 10, 9}, { 12, 12, 5}, { 12, 13, 1},
+ { 12, 13, 2}, { 12, 13, 5}, { 12, 13, 8}, { 12, 13, 9},
+ { 12, 13, 11}, { 12, 13, 17}, { 12, 13, 19}, { 12, 13, 23},
+ { 12, 14, 1}, { 12, 14, 2}, { 12, 14, 5}, { 12, 14, 22},
+ { 12, 15, 1}, { 12, 15, 22}, { 12, 18, 1}, { 12, 18, 5},
+ { 12, 18, 9}, { 12, 18, 17}, { 12, 18, 19}, { 12, 19, 1},
+ { 12, 20, 1}, { 12, 20, 2}, { 12, 20, 5}, { 12, 20, 9},
+ { 12, 20, 17}, { 12, 20, 19}, { 12, 20, 23}, { 12, 21, 1},
+ { 12, 21, 22}, { 12, 22, 1}, { 12, 23, 1}, { 12, 23, 5},
+ { 12, 26, 23}, { 12, 27, 1}, { 12, 27, 2}, { 12, 27, 5},
+ { 12, 27, 9}, { 12, 27, 11}, { 12, 27, 16}, { 12, 27, 17},
+ { 12, 27, 19}, { 12, 28, 1}, { 12, 28, 5}, { 12, 28, 9},
+ { 12, 28, 17}, { 12, 29, 1}, { 12, 29, 2}, { 12, 29, 5},
+ { 12, 29, 9}, { 12, 29, 17}, { 12, 29, 19}, { 12, 29, 21},
+ { 12, 29, 23}, { 13, 3, 1}, { 13, 3, 2}, { 13, 3, 5},
+ { 13, 3, 6}, { 13, 3, 7}, { 13, 3, 9}, { 13, 3, 10},
+ { 13, 3, 11}, { 13, 3, 16}, { 13, 3, 17}, { 13, 3, 19},
+ { 13, 3, 21}, { 13, 3, 22}, { 13, 3, 23}, { 13, 3, 27},
+ { 13, 3, 28}, { 13, 4, 1}, { 13, 4, 2}, { 13, 4, 5},
+ { 13, 4, 9}, { 13, 4, 17}, { 13, 4, 19}, { 13, 4, 21},
+ { 13, 4, 22}, { 13, 4, 23}, { 13, 5, 1}, { 13, 5, 2},
+ { 13, 5, 5}, { 13, 5, 9}, { 13, 5, 12}, { 13, 5, 17},
+ { 13, 5, 19}, { 13, 5, 21}, { 13, 5, 23}, { 13, 5, 27},
+ { 13, 5, 29}, { 13, 6, 1}, { 13, 6, 5}, { 13, 6, 9},
+ { 13, 6, 19}, { 13, 7, 1}, { 13, 7, 2}, { 13, 7, 5},
+ { 13, 7, 6}, { 13, 7, 8}, { 13, 7, 9}, { 13, 7, 10},
+ { 13, 7, 11}, { 13, 7, 17}, { 13, 7, 19}, { 13, 7, 20},
+ { 13, 7, 21}, { 13, 7, 22}, { 13, 7, 23}, { 13, 7, 24},
+ { 13, 7, 26}, { 13, 7, 28}, { 13, 10, 1}, { 13, 10, 2},
+ { 13, 10, 5}, { 13, 10, 9}, { 13, 10, 17}, { 13, 10, 19},
+ { 13, 10, 21}, { 13, 10, 23}, { 13, 11, 1}, { 13, 11, 2},
+ { 13, 11, 3}, { 13, 11, 5}, { 13, 11, 9}, { 13, 11, 11},
+ { 13, 11, 12}, { 13, 11, 17}, { 13, 11, 19}, { 13, 11, 20},
+ { 13, 11, 21}, { 13, 11, 22}, { 13, 11, 23}, { 13, 11, 27},
+ { 13, 11, 28}, { 13, 11, 29}, { 13, 12, 1}, { 13, 12, 5},
+ { 13, 12, 9}, { 13, 12, 17}, { 13, 12, 19}, { 13, 12, 21},
+ { 13, 12, 22}, { 13, 13, 1}, { 13, 13, 2}, { 13, 13, 5},
+ { 13, 13, 9}, { 13, 13, 10}, { 13, 13, 11}, { 13, 13, 13},
+ { 13, 13, 16}, { 13, 13, 17}, { 13, 13, 19}, { 13, 13, 21},
+ { 13, 13, 23}, { 13, 13, 25}, { 13, 14, 1}, { 13, 14, 2},
+ { 13, 14, 5}, { 13, 14, 9}, { 13, 14, 17}, { 13, 14, 19},
+ { 13, 14, 21}, { 13, 14, 22}, { 13, 14, 23}, { 13, 15, 1},
+ { 13, 15, 2}, { 13, 15, 5}, { 13, 15, 17}, { 13, 15, 21},
+ { 13, 15, 23}, { 13, 18, 1}, { 13, 18, 2}, { 13, 18, 5},
+ { 13, 18, 9}, { 13, 18, 17}, { 13, 18, 19}, { 13, 18, 21},
+ { 13, 18, 23}, { 13, 19, 1}, { 13, 19, 2}, { 13, 19, 5},
+ { 13, 19, 9}, { 13, 19, 17}, { 13, 19, 19}, { 13, 19, 21},
+ { 13, 19, 23}, { 13, 20, 1}, { 13, 20, 2}, { 13, 20, 5},
+ { 13, 20, 9}, { 13, 20, 10}, { 13, 20, 11}, { 13, 20, 17},
+ { 13, 20, 19}, { 13, 20, 21}, { 13, 20, 23}, { 13, 21, 1},
+ { 13, 21, 2}, { 13, 21, 5}, { 13, 21, 9}, { 13, 21, 17},
+ { 13, 21, 19}, { 13, 21, 22}, { 13, 21, 23}, { 13, 22, 1},
+ { 13, 22, 2}, { 13, 22, 5}, { 13, 22, 9}, { 13, 22, 17},
+ { 13, 22, 19}, { 13, 22, 23}, { 13, 23, 1}, { 13, 23, 2},
+ { 13, 23, 5}, { 13, 23, 9}, { 13, 23, 17}, { 13, 23, 19},
+ { 13, 23, 21}, { 13, 23, 23}, { 13, 26, 1}, { 13, 26, 2},
+ { 13, 26, 5}, { 13, 26, 9}, { 13, 26, 17}, { 13, 26, 19},
+ { 13, 26, 21}, { 13, 26, 23}, { 13, 26, 25}, { 13, 27, 1},
+ { 13, 27, 2}, { 13, 27, 5}, { 13, 27, 9}, { 13, 27, 15},
+ { 13, 27, 17}, { 13, 27, 19}, { 13, 27, 21}, { 13, 27, 23},
+ { 13, 27, 24}, { 13, 27, 25}, { 13, 27, 26}, { 13, 27, 27},
+ { 13, 27, 28}, { 13, 27, 29}, { 13, 28, 1}, { 13, 28, 5},
+ { 13, 28, 9}, { 13, 28, 17}, { 13, 28, 21}, { 13, 29, 1},
+ { 13, 29, 2}, { 13, 29, 5}, { 13, 29, 9}, { 13, 29, 10},
+ { 13, 29, 11}, { 13, 29, 16}, { 13, 29, 17}, { 13, 29, 19},
+ { 13, 29, 21}, { 13, 29, 22}, { 13, 29, 23}, { 13, 29, 24},
+ { 13, 29, 28}, { 14, 3, 1}, { 14, 3, 2}, { 14, 3, 5},
+ { 14, 3, 7}, { 14, 3, 8}, { 14, 3, 9}, { 14, 3, 11},
+ { 14, 3, 17}, { 14, 3, 19}, { 14, 3, 21}, { 14, 3, 22},
+ { 14, 3, 23}, { 14, 3, 24}, { 14, 4, 1}, { 14, 4, 2},
+ { 14, 4, 5}, { 14, 4, 9}, { 14, 4, 17}, { 14, 4, 19},
+ { 14, 4, 21}, { 14, 4, 22}, { 14, 4, 23}, { 14, 5, 1},
+ { 14, 5, 2}, { 14, 5, 5}, { 14, 5, 7}, { 14, 5, 9},
+ { 14, 5, 17}, { 14, 5, 23}, { 14, 6, 1}, { 14, 6, 5},
+ { 14, 6, 9}, { 14, 7, 1}, { 14, 7, 2}, { 14, 7, 5},
+ { 14, 7, 9}, { 14, 7, 11}, { 14, 7, 17}, { 14, 7, 19},
+ { 14, 7, 21}, { 14, 7, 23}, { 14, 7, 24}, { 14, 10, 1},
+ { 14, 10, 2}, { 14, 10, 5}, { 14, 10, 9}, { 14, 10, 17},
+ { 14, 10, 19}, { 14, 10, 21}, { 14, 10, 23}, { 14, 11, 1},
+ { 14, 11, 5}, { 14, 11, 9}, { 14, 11, 17}, { 14, 11, 19},
+ { 14, 11, 22}, { 14, 11, 23}, { 14, 12, 1}, { 14, 13, 1},
+ { 14, 13, 2}, { 14, 13, 5}, { 14, 13, 9}, { 14, 13, 11},
+ { 14, 13, 17}, { 14, 13, 19}, { 14, 13, 21}, { 14, 13, 23},
+ { 14, 13, 24}, { 14, 13, 25}, { 14, 13, 29}, { 14, 14, 1},
+ { 14, 14, 2}, { 14, 14, 9}, { 14, 14, 19}, { 14, 14, 21},
+ { 14, 14, 23}, { 14, 15, 1}, { 14, 15, 22}, { 14, 15, 23},
+ { 14, 18, 1}, { 14, 18, 5}, { 14, 18, 9}, { 14, 18, 17},
+ { 14, 18, 19}, { 14, 18, 21}, { 14, 18, 23}, { 14, 19, 1},
+ { 14, 19, 2}, { 14, 19, 5}, { 14, 19, 23}, { 14, 20, 1},
+ { 14, 20, 2}, { 14, 20, 5}, { 14, 20, 9}, { 14, 20, 10},
+ { 14, 20, 11}, { 14, 20, 17}, { 14, 20, 19}, { 14, 20, 21},
+ { 14, 20, 23}, { 14, 21, 1}, { 14, 21, 22}, { 14, 22, 1},
+ { 14, 23, 1}, { 14, 23, 2}, { 14, 23, 5}, { 14, 23, 9},
+ { 14, 23, 17}, { 14, 23, 19}, { 14, 23, 21}, { 14, 26, 1},
+ { 14, 26, 5}, { 14, 26, 9}, { 14, 26, 17}, { 14, 27, 1},
+ { 14, 27, 2}, { 14, 27, 5}, { 14, 27, 9}, { 14, 27, 17},
+ { 14, 27, 19}, { 14, 27, 21}, { 14, 27, 23}, { 14, 29, 1},
+ { 14, 29, 2}, { 14, 29, 5}, { 14, 29, 8}, { 14, 29, 9},
+ { 14, 29, 11}, { 14, 29, 17}, { 14, 29, 19}, { 14, 29, 21},
+ { 14, 29, 23}, { 14, 29, 24}, { 14, 29, 27}, { 14, 29, 28},
+ { 15, 3, 1}, { 15, 3, 2}, { 15, 3, 5}, { 15, 3, 7},
+ { 15, 3, 9}, { 15, 3, 12}, { 15, 3, 17}, { 15, 3, 19},
+ { 15, 3, 21}, { 15, 3, 22}, { 15, 3, 23}, { 15, 4, 1},
+ { 15, 4, 2}, { 15, 4, 5}, { 15, 4, 9}, { 15, 4, 17},
+ { 15, 4, 19}, { 15, 4, 21}, { 15, 4, 22}, { 15, 4, 23},
+ { 15, 5, 1}, { 15, 5, 5}, { 15, 5, 23}, { 15, 7, 1},
+ { 15, 7, 2}, { 15, 7, 5}, { 15, 7, 9}, { 15, 7, 17},
+ { 15, 7, 19}, { 15, 7, 21}, { 15, 7, 22}, { 15, 7, 23},
+ { 15, 10, 1}, { 15, 10, 23}, { 15, 11, 1}, { 15, 11, 22},
+ { 15, 13, 1}, { 15, 13, 2}, { 15, 13, 5}, { 15, 13, 9},
+ { 15, 13, 17}, { 15, 13, 19}, { 15, 13, 21}, { 15, 13, 23},
+ { 15, 13, 25}, { 15, 14, 1}, { 15, 14, 2}, { 15, 14, 9},
+ { 15, 14, 22}, { 15, 15, 1}, { 15, 15, 22}, { 15, 18, 1},
+ { 15, 18, 5}, { 15, 18, 9}, { 15, 18, 17}, { 15, 18, 19},
+ { 15, 19, 23}, { 15, 20, 1}, { 15, 20, 2}, { 15, 20, 5},
+ { 15, 20, 9}, { 15, 20, 17}, { 15, 20, 19}, { 15, 20, 23},
+ { 15, 21, 1}, { 15, 21, 22}, { 15, 21, 23}, { 15, 23, 1},
+ { 15, 26, 1}, { 15, 27, 1}, { 15, 27, 17}, { 15, 27, 21},
+ { 15, 27, 23}, { 15, 29, 1}, { 15, 29, 2}, { 15, 29, 5},
+ { 15, 29, 9}, { 15, 29, 17}, { 15, 29, 19}, { 15, 29, 23},
+ { 15, 29, 24}, { 15, 29, 29}, { 16, 3, 1}, { 16, 3, 2},
+ { 16, 3, 5}, { 16, 3, 7}, { 16, 3, 9}, { 16, 3, 17},
+ { 16, 3, 19}, { 16, 3, 21}, { 16, 3, 22}, { 16, 3, 23},
+ { 16, 3, 24}, { 16, 4, 1}, { 16, 4, 2}, { 16, 4, 5},
+ { 16, 4, 9}, { 16, 4, 17}, { 16, 4, 19}, { 16, 4, 21},
+ { 16, 4, 22}, { 16, 4, 23}, { 16, 5, 1}, { 16, 5, 5},
+ { 16, 5, 7}, { 16, 5, 9}, { 16, 5, 17}, { 16, 5, 23},
+ { 16, 7, 1}, { 16, 7, 2}, { 16, 7, 5}, { 16, 7, 9},
+ { 16, 7, 17}, { 16, 7, 19}, { 16, 7, 21}, { 16, 7, 22},
+ { 16, 7, 23}, { 16, 10, 1}, { 16, 10, 2}, { 16, 10, 5},
+ { 16, 10, 9}, { 16, 10, 17}, { 16, 10, 19}, { 16, 10, 21},
+ { 16, 10, 23}, { 16, 11, 1}, { 16, 11, 5}, { 16, 11, 22},
+ { 16, 12, 1}, { 16, 12, 5}, { 16, 12, 23}, { 16, 13, 1},
+ { 16, 13, 2}, { 16, 13, 5}, { 16, 13, 9}, { 16, 13, 17},
+ { 16, 13, 19}, { 16, 13, 21}, { 16, 13, 23}, { 16, 14, 1},
+ { 16, 14, 5}, { 16, 14, 9}, { 16, 14, 23}, { 16, 18, 1},
+ { 16, 18, 5}, { 16, 18, 9}, { 16, 18, 17}, { 16, 18, 19},
+ { 16, 18, 21}, { 16, 18, 23}, { 16, 19, 1}, { 16, 19, 17},
+ { 16, 20, 1}, { 16, 20, 2}, { 16, 20, 5}, { 16, 20, 9},
+ { 16, 20, 17}, { 16, 20, 19}, { 16, 20, 21}, { 16, 20, 23},
+ { 16, 21, 1}, { 16, 21, 22}, { 16, 22, 1}, { 16, 22, 5},
+ { 16, 23, 1}, { 16, 23, 5}, { 16, 23, 9}, { 16, 23, 17},
+ { 16, 23, 19}, { 16, 23, 21}, { 16, 23, 23}, { 16, 26, 1},
+ { 16, 26, 5}, { 16, 26, 9}, { 16, 26, 17}, { 16, 26, 23},
+ { 16, 27, 1}, { 16, 27, 2}, { 16, 27, 5}, { 16, 27, 9},
+ { 16, 27, 17}, { 16, 27, 19}, { 16, 27, 21}, { 16, 27, 23},
+ { 16, 29, 1}, { 16, 29, 2}, { 16, 29, 5}, { 16, 29, 8},
+ { 16, 29, 9}, { 16, 29, 10}, { 16, 29, 17}, { 16, 29, 19},
+ { 16, 29, 21}, { 16, 29, 23}, { 17, 3, 1}, { 17, 3, 2},
+ { 17, 3, 5}, { 17, 3, 9}, { 17, 3, 17}, { 17, 3, 19},
+ { 17, 3, 21}, { 17, 3, 23}, { 17, 4, 1}, { 17, 4, 2},
+ { 17, 4, 5}, { 17, 4, 9}, { 17, 4, 17}, { 17, 4, 19},
+ { 17, 4, 21}, { 17, 4, 22}, { 17, 4, 23}, { 17, 5, 1},
+ { 17, 5, 2}, { 17, 5, 23}, { 17, 7, 1}, { 17, 7, 2},
+ { 17, 7, 5}, { 17, 7, 8}, { 17, 7, 9}, { 17, 7, 17},
+ { 17, 7, 19}, { 17, 7, 21}, { 17, 7, 22}, { 17, 7, 23},
+ { 17, 10, 1}, { 17, 10, 2}, { 17, 10, 5}, { 17, 10, 9},
+ { 17, 10, 17}, { 17, 10, 19}, { 17, 10, 21}, { 17, 10, 23},
+ { 17, 11, 1}, { 17, 11, 5}, { 17, 11, 9}, { 17, 11, 17},
+ { 17, 11, 19}, { 17, 11, 21}, { 17, 11, 22}, { 17, 11, 23},
+ { 17, 12, 1}, { 17, 13, 1}, { 17, 13, 2}, { 17, 13, 5},
+ { 17, 13, 9}, { 17, 13, 17}, { 17, 13, 19}, { 17, 13, 21},
+ { 17, 13, 23}, { 17, 14, 1}, { 17, 14, 2}, { 17, 14, 5},
+ { 17, 14, 9}, { 17, 14, 17}, { 17, 14, 23}, { 17, 15, 1},
+ { 17, 15, 23}, { 17, 18, 1}, { 17, 18, 9}, { 17, 19, 1},
+ { 17, 20, 1}, { 17, 20, 2}, { 17, 20, 5}, { 17, 20, 9},
+ { 17, 20, 17}, { 17, 20, 19}, { 17, 20, 21}, { 17, 20, 23},
+ { 17, 21, 1}, { 17, 21, 5}, { 17, 21, 9}, { 17, 21, 23},
+ { 17, 22, 1}, { 17, 22, 23}, { 17, 23, 1}, { 17, 23, 2},
+ { 17, 23, 5}, { 17, 23, 9}, { 17, 23, 17}, { 17, 23, 19},
+ { 17, 23, 21}, { 17, 23, 23}, { 17, 26, 1}, { 17, 26, 5},
+ { 17, 26, 9}, { 17, 26, 17}, { 17, 27, 1}, { 17, 27, 2},
+ { 17, 27, 5}, { 17, 27, 9}, { 17, 27, 17}, { 17, 27, 19},
+ { 17, 27, 23}, { 17, 29, 1}, { 17, 29, 2}, { 17, 29, 5},
+ { 17, 29, 9}, { 17, 29, 17}, { 17, 29, 19}, { 17, 29, 21},
+ { 17, 29, 23}, { 18, 3, 1}, { 18, 3, 2}, { 18, 3, 5},
+ { 18, 3, 9}, { 18, 3, 10}, { 18, 3, 17}, { 18, 3, 19},
+ { 18, 3, 21}, { 18, 3, 22}, { 18, 3, 23}, { 18, 4, 1},
+ { 18, 4, 2}, { 18, 4, 5}, { 18, 4, 9}, { 18, 4, 17},
+ { 18, 4, 19}, { 18, 4, 21}, { 18, 4, 22}, { 18, 4, 23},
+ { 18, 5, 1}, { 18, 5, 23}, { 18, 7, 1}, { 18, 7, 2},
+ { 18, 7, 5}, { 18, 7, 9}, { 18, 7, 11}, { 18, 7, 17},
+ { 18, 7, 19}, { 18, 7, 21}, { 18, 7, 22}, { 18, 7, 23},
+ { 18, 10, 1}, { 18, 10, 2}, { 18, 10, 5}, { 18, 10, 9},
+ { 18, 10, 17}, { 18, 10, 19}, { 18, 10, 21}, { 18, 10, 23},
+ { 18, 11, 1}, { 18, 11, 5}, { 18, 11, 22}, { 18, 12, 1},
+ { 18, 12, 5}, { 18, 13, 1}, { 18, 13, 2}, { 18, 13, 5},
+ { 18, 13, 9}, { 18, 13, 17}, { 18, 13, 19}, { 18, 13, 21},
+ { 18, 13, 23}, { 18, 13, 28}, { 18, 14, 1}, { 18, 14, 5},
+ { 18, 15, 1}, { 18, 18, 1}, { 18, 18, 5}, { 18, 18, 21},
+ { 18, 18, 23}, { 18, 19, 1}, { 18, 20, 1}, { 18, 20, 2},
+ { 18, 20, 5}, { 18, 20, 9}, { 18, 20, 17}, { 18, 20, 19},
+ { 18, 20, 21}, { 18, 20, 23}, { 18, 21, 1}, { 18, 21, 22},
+ { 18, 22, 1}, { 18, 23, 1}, { 18, 23, 2}, { 18, 23, 5},
+ { 18, 23, 9}, { 18, 23, 17}, { 18, 23, 19}, { 18, 23, 23},
+ { 18, 26, 1}, { 18, 26, 5}, { 18, 26, 9}, { 18, 26, 17},
+ { 18, 26, 23}, { 18, 27, 1}, { 18, 27, 2}, { 18, 27, 5},
+ { 18, 27, 8}, { 18, 27, 9}, { 18, 27, 11}, { 18, 27, 17},
+ { 18, 27, 19}, { 18, 27, 21}, { 18, 28, 1}, { 18, 28, 5},
+ { 18, 28, 9}, { 18, 28, 17}, { 18, 28, 19}, { 18, 29, 1},
+ { 18, 29, 2}, { 18, 29, 5}, { 18, 29, 9}, { 18, 29, 17},
+ { 18, 29, 19}, { 18, 29, 21}, { 18, 29, 23}, { 19, 3, 1},
+ { 19, 3, 2}, { 19, 3, 3}, { 19, 3, 5}, { 19, 3, 9},
+ { 19, 3, 11}, { 19, 3, 17}, { 19, 3, 19}, { 19, 3, 21},
+ { 19, 3, 22}, { 19, 3, 23}, { 19, 3, 27}, { 19, 4, 1},
+ { 19, 4, 2}, { 19, 4, 5}, { 19, 4, 9}, { 19, 4, 17},
+ { 19, 4, 19}, { 19, 4, 21}, { 19, 4, 22}, { 19, 4, 23},
+ { 19, 5, 1}, { 19, 5, 2}, { 19, 7, 1}, { 19, 7, 2},
+ { 19, 7, 5}, { 19, 7, 9}, { 19, 7, 17}, { 19, 7, 19},
+ { 19, 7, 21}, { 19, 7, 22}, { 19, 7, 23}, { 19, 10, 1},
+ { 19, 10, 2}, { 19, 10, 5}, { 19, 10, 9}, { 19, 10, 17},
+ { 19, 10, 19}, { 19, 10, 21}, { 19, 10, 23}, { 19, 11, 1},
+ { 19, 11, 5}, { 19, 11, 9}, { 19, 11, 17}, { 19, 11, 19},
+ { 19, 11, 22}, { 19, 11, 23}, { 19, 12, 1}, { 19, 12, 9},
+ { 19, 12, 19}, { 19, 12, 21}, { 19, 13, 1}, { 19, 13, 2},
+ { 19, 13, 5}, { 19, 13, 9}, { 19, 13, 17}, { 19, 13, 19},
+ { 19, 13, 21}, { 19, 13, 23}, { 19, 14, 1}, { 19, 14, 23},
+ { 19, 18, 1}, { 19, 18, 5}, { 19, 19, 1}, { 19, 19, 5},
+ { 19, 19, 9}, { 19, 19, 19}, { 19, 19, 21}, { 19, 20, 1},
+ { 19, 20, 2}, { 19, 20, 5}, { 19, 20, 8}, { 19, 20, 9},
+ { 19, 20, 11}, { 19, 20, 17}, { 19, 20, 19}, { 19, 20, 21},
+ { 19, 20, 23}, { 19, 21, 1}, { 19, 21, 23}, { 19, 23, 1},
+ { 19, 23, 5}, { 19, 23, 9}, { 19, 23, 17}, { 19, 23, 21},
+ { 19, 26, 1}, { 19, 26, 5}, { 19, 26, 9}, { 19, 26, 17},
+ { 19, 26, 21}, { 19, 26, 23}, { 19, 27, 1}, { 19, 27, 5},
+ { 19, 27, 9}, { 19, 27, 17}, { 19, 27, 19}, { 19, 27, 21},
+ { 19, 29, 1}, { 19, 29, 2}, { 19, 29, 5}, { 19, 29, 9},
+ { 19, 29, 17}, { 19, 29, 19}, { 19, 29, 21}, { 19, 29, 23},
+ { 20, 3, 1}, { 20, 3, 2}, { 20, 3, 5}, { 20, 3, 9},
+ { 20, 3, 14}, { 20, 3, 17}, { 20, 3, 19}, { 20, 3, 21},
+ { 20, 3, 23}, { 20, 4, 1}, { 20, 4, 2}, { 20, 4, 5},
+ { 20, 4, 9}, { 20, 4, 17}, { 20, 4, 19}, { 20, 4, 21},
+ { 20, 4, 22}, { 20, 4, 23}, { 20, 5, 1}, { 20, 5, 23},
+ { 20, 7, 1}, { 20, 7, 2}, { 20, 7, 5}, { 20, 7, 9},
+ { 20, 7, 11}, { 20, 7, 17}, { 20, 7, 19}, { 20, 7, 21},
+ { 20, 7, 23}, { 20, 10, 1}, { 20, 10, 2}, { 20, 10, 5},
+ { 20, 10, 9}, { 20, 10, 17}, { 20, 10, 19}, { 20, 10, 21},
+ { 20, 10, 23}, { 20, 11, 1}, { 20, 11, 2}, { 20, 11, 5},
+ { 20, 11, 9}, { 20, 11, 17}, { 20, 11, 19}, { 20, 11, 21},
+ { 20, 11, 22}, { 20, 11, 23}, { 20, 12, 1}, { 20, 12, 5},
+ { 20, 12, 9}, { 20, 12, 19}, { 20, 13, 1}, { 20, 13, 2},
+ { 20, 13, 5}, { 20, 13, 9}, { 20, 13, 14}, { 20, 13, 17},
+ { 20, 13, 19}, { 20, 13, 21}, { 20, 13, 23}, { 20, 13, 27},
+ { 20, 14, 1}, { 20, 14, 2}, { 20, 14, 5}, { 20, 14, 9},
+ { 20, 14, 21}, { 20, 14, 23}, { 20, 15, 1}, { 20, 15, 2},
+ { 20, 15, 5}, { 20, 15, 21}, { 20, 15, 23}, { 20, 18, 1},
+ { 20, 18, 2}, { 20, 18, 5}, { 20, 18, 9}, { 20, 18, 19},
+ { 20, 18, 21}, { 20, 18, 23}, { 20, 19, 1}, { 20, 19, 5},
+ { 20, 19, 9}, { 20, 19, 19}, { 20, 19, 21}, { 20, 20, 1},
+ { 20, 20, 2}, { 20, 20, 5}, { 20, 20, 9}, { 20, 20, 14},
+ { 20, 20, 17}, { 20, 20, 21}, { 20, 20, 23}, { 20, 21, 1},
+ { 20, 21, 5}, { 20, 21, 9}, { 20, 21, 17}, { 20, 21, 23},
+ { 20, 22, 1}, { 20, 22, 2}, { 20, 22, 5}, { 20, 22, 9},
+ { 20, 22, 23}, { 20, 23, 1}, { 20, 23, 2}, { 20, 23, 5},
+ { 20, 23, 9}, { 20, 23, 17}, { 20, 23, 19}, { 20, 23, 21},
+ { 20, 23, 23}, { 20, 26, 1}, { 20, 26, 2}, { 20, 26, 5},
+ { 20, 26, 9}, { 20, 26, 17}, { 20, 26, 21}, { 20, 26, 23},
+ { 20, 27, 1}, { 20, 27, 2}, { 20, 27, 5}, { 20, 27, 7},
+ { 20, 27, 8}, { 20, 27, 9}, { 20, 27, 10}, { 20, 27, 17},
+ { 20, 27, 19}, { 20, 27, 21}, { 20, 27, 23}, { 20, 27, 27},
+ { 20, 28, 1}, { 20, 28, 5}, { 20, 28, 9}, { 20, 28, 17},
+ { 20, 28, 19}, { 20, 28, 23}, { 20, 29, 1}, { 20, 29, 2},
+ { 20, 29, 5}, { 20, 29, 9}, { 20, 29, 17}, { 20, 29, 19},
+ { 20, 29, 21}, { 20, 29, 23},
+};
+
+
+static const unsigned short ks_table2[][4] =
+{
+ {0xa4bf, 1, 3, 1}, {0xa4c0, 1, 4, 1},
+ {0xa4c1, 1, 5, 1}, {0xa4c2, 1, 6, 1},
+ {0xa4c3, 1, 7, 1}, {0xa4c4, 1, 10, 1},
+ {0xa4c5, 1, 11, 1}, {0xa4c6, 1, 12, 1},
+ {0xa4c7, 1, 13, 1}, {0xa4c8, 1, 14, 1},
+ {0xa4c9, 1, 15, 1}, {0xa4ca, 1, 18, 1},
+ {0xa4cb, 1, 19, 1}, {0xa4cc, 1, 20, 1},
+ {0xa4cd, 1, 21, 1}, {0xa4ce, 1, 22, 1},
+ {0xa4cf, 1, 23, 1}, {0xa4d0, 1, 26, 1},
+ {0xa4d1, 1, 27, 1}, {0xa4d2, 1, 28, 1},
+ {0xa4d3, 1, 29, 1}, {0xa4a1, 2, 2, 1},
+ {0xa4a2, 3, 2, 1}, {0xa4a4, 4, 2, 1},
+ {0xa4a7, 5, 2, 1}, {0xa4a8, 6, 2, 1},
+ {0xa4a9, 7, 2, 1}, {0xa4b1, 8, 2, 1},
+ {0xa4b2, 9, 2, 1}, {0xa4b3, 10, 2, 1},
+ {0xa4b5, 11, 2, 1}, {0xa4b6, 12, 2, 1},
+ {0xa4b7, 13, 2, 1}, {0xa4b8, 14, 2, 1},
+ {0xa4b9, 15, 2, 1}, {0xa4ba, 16, 2, 1},
+ {0xa4bb, 17, 2, 1}, {0xa4bc, 18, 2, 1},
+ {0xa4bd, 19, 2, 1}, {0xa4be, 20, 2, 1},
+};
+
+/* Á¶ÇÕÇü Ãʼº - ¿Ï¼ºÇü ³¹ÀÚ º¯È¯
+ * conversion: initial sound of compound type - ??? of completion type
+ */
+
+static const char_u johab_fcon_to_wan[] =
+{
+ 0,
+ 0xd4, 0xa1, 0xa2, 0xa4, 0xa7, /* (ä¿ò),¤¡,¤¢,¤¤,¤§ */
+ 0xa8, 0xa9, 0xb1, 0xb2, 0xb3, /* ¤¨,¤©,¤±,¤²,¤³ */
+ 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, /* ¤µ,¤¶,¤·,¤¸,¤¹ */
+ 0xba, 0xbb, 0xbc, 0xbd, 0xbe /* ¤º,¤»,¤¼,¤½,¤¾ */
+};
+
+/* Á¶ÇÕÇü Áß¼º -> ¿Ï¼ºÇü ³¹ÀÚ º¯È¯
+ * conversion: medial vowel of compound type - ??? of completion type
+ */
+
+static const char_u johab_vow_to_wan[] =
+{
+ 0, 0,
+ 0xd4, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, /* (ä¿ò),¤¿,¤À,¤Á,¤Â,¤Ã */
+ 0, 0,
+ 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, /* ¤Ä,¤Å,¤Æ,¤Ç,¤Ç¤¿,¤Ç¤À */
+ 0, 0,
+ 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* ¤Ç¤Ó,¤Ë,¤Ì,¤Ì¤Ã,¤Ì¤Ä,¤Ì¤Ó */
+ 0, 0,
+ 0xd0, 0xd1, 0xd2, 0xd3 /* ¤Ð,¤Ñ,¤Ñ¤Ó,¤Ó */
+};
+
+/* Á¶ÇÕÇü Á¾¼º -> ¿Ï¼ºÇü ³¹ÀÚ º¯È¯
+ * conversion: final consonant of compound type - ??? of completion type
+ */
+
+static const char_u johab_lcon_to_wan[] =
+{
+ 0,
+ 0xd4, 0xa1, 0xa2, 0xa3, 0xa4, /* (ä¿ò), ¤¡, ¤¢, ¤¡¤µ, ¤¤ */
+ 0xa5, 0xa6, 0xa7, 0xa9, 0xaa, /* ¤¤¤¸, ¤¤¤¾, ¤§, ¤©, ¤©¤¡ */
+ 0xab, 0xac, 0xad, 0xae, 0xaf, /* ¤©¤±, ¤©¤², ¤©¤µ, ¤©¤¼, ¤©¤½ */
+ 0xb0, 0xb1, 0, 0xb2, 0xb4, /* ¤©¤¾, ¤±, 0, ¤², ¤²¤µ */
+ 0xb5, 0xb6, 0xb7, 0xb8, 0xba, /* ¤µ, ¤¶, ¤·, ¤¸, ¤º */
+ 0xbb, 0xbc, 0xbd, 0xbe /* ¤», ¤¼, ¤½, ¤¾ */
+};
+
+static void convert_ks_to_3(src, fp, mp, lp)
+const char_u *src;
+int *fp;
+int *mp;
+int *lp;
+{
+ int h = *src;
+ int low = *(src + 1);
+ int c;
+ int i;
+
+ if ((i = han_index(h, low)) >= 0
+ && i < sizeof(ks_table1)/sizeof(ks_table1[0])) {
+ *fp = ks_table1[i][0];
+ *mp = ks_table1[i][1];
+ *lp = ks_table1[i][2];
+ } else {
+ c = (h << 8) | low;
+ for (i = 0; i < 40; i++)
+ if (ks_table2[i][0] == c) {
+ *fp = ks_table2[i][1];
+ *mp = ks_table2[i][2];
+ *lp = ks_table2[i][3];
+ return;
+ }
+ *fp = 0xff; /* ±×·¡ÇÈ ÄÚµå (graphic code) */
+ *mp = h;
+ *lp = low;
+ }
+}
+
+static int convert_3_to_ks(fv, mv, lv, des)
+int fv;
+int mv;
+int lv;
+char_u *des;
+{
+ char_u key[3];
+ register int hi, lo, mi = 0, result, found;
+
+ if (fv == 0xff) {
+ des[0] = mv;
+ des[1] = lv;
+ return 2;
+ }
+ key[0] = fv;
+ key[1] = mv;
+ key[2] = lv;
+ lo = 0;
+ hi = sizeof(ks_table1)/3 - 1;
+ found = 0;
+ while (lo + 1 < hi) {
+ mi = (lo + hi)/2;
+ result = STRNCMP(ks_table1[mi], key, 3);
+ if (result == 0) {
+ found = 1;
+ break;
+ } else if (result > 0)
+ hi = mi;
+ else
+ lo = mi;
+ }
+ if (!found) {
+ if (!STRNCMP(ks_table1[lo], key, 3)) {
+ found = 1;
+ mi = lo;
+ }
+ if (!STRNCMP(ks_table1[hi], key, 3)) {
+ found = 1;
+ mi = hi;
+ }
+ }
+ if (!found) {
+ for (mi = 0; mi < 40; mi++)
+ if (ks_table2[mi][1] == fv && ks_table2[mi][2] == mv &&
+ ks_table2[mi][3] == lv) {
+ des[0] = (unsigned)(ks_table2[mi][0]) >> 8;
+ des[1] = ks_table2[mi][0];
+ return 2; /* found */
+ }
+ } else {
+ des[0] = mi / (0xff-0xa1) + 0xb0;
+ des[1] = mi % (0xff-0xa1) + 0xa1;
+ return 2; /* found */
+ }
+
+ /* ¿Ï¼ºÇü Ç¥¿¡ ¾ø´Ù. ``KS C 5601 - 1992 Á¤º¸ ±³È¯¿ë ºÎÈ£ ÇØ¼³''
+ * 3.3 Àý¿¡ ¼³¸íµÈ ¹æ¹ýÀ¸·Î encoding ÇÑ´Ù.
+ */
+
+ *des++ = 0xa4; /* ä¿ò */
+ *des++ = 0xd4;
+ *des++ = 0xa4; /* ³¹ÀÚ´Â ¸ðµÎ a4 Çà¿¡ ÀÖ´Ù. */
+ *des++ = johab_fcon_to_wan[fv];
+ *des++ = 0xa4;
+ *des++ = johab_vow_to_wan[mv];
+ *des++ = 0xa4;
+ *des++ = johab_lcon_to_wan[lv];
+ return 8;
+}
diff --git a/src/hardcopy.c b/src/hardcopy.c
new file mode 100644
index 0000000000..5869b55a49
--- /dev/null
+++ b/src/hardcopy.c
@@ -0,0 +1,3258 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * 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.
+ */
+
+/*
+ * hardcopy.c: printing to paper
+ */
+
+#include "vim.h"
+#include "version.h"
+
+/*
+ * To implement printing on a platform, the following functions must be
+ * defined:
+ *
+ * int mch_print_init(prt_settings_T *psettings, char_u *jobname, int forceit)
+ * Called once. Code should display printer dialogue (if appropriate) and
+ * determine printer font and margin settings. Reset has_color if the printer
+ * doesn't support colors at all.
+ * Returns FAIL to abort.
+ *
+ * int mch_print_begin(prt_settings_T *settings)
+ * Called to start the print job.
+ * Return FALSE to abort.
+ *
+ * int mch_print_begin_page(char_u *msg)
+ * Called at the start of each page.
+ * "msg" indicates the progress of the print job, can be NULL.
+ * Return FALSE to abort.
+ *
+ * int mch_print_end_page()
+ * Called at the end of each page.
+ * Return FALSE to abort.
+ *
+ * int mch_print_blank_page()
+ * Called to generate a blank page for collated, duplex, multiple copy
+ * document. Return FALSE to abort.
+ *
+ * void mch_print_end(prt_settings_T *psettings)
+ * Called at normal end of print job.
+ *
+ * void mch_print_cleanup()
+ * Called if print job ends normally or is abandoned. Free any memory, close
+ * devices and handles. Also called when mch_print_begin() fails, but not
+ * when mch_print_init() fails.
+ *
+ * void mch_print_set_font(int Bold, int Italic, int Underline);
+ * Called whenever the font style changes.
+ *
+ * void mch_print_set_bg(long_u bgcol);
+ * Called to set the background color for the following text. Parameter is an
+ * RGB value.
+ *
+ * void mch_print_set_fg(long_u fgcol);
+ * Called to set the foreground color for the following text. Parameter is an
+ * RGB value.
+ *
+ * mch_print_start_line(int margin, int page_line)
+ * Sets the current position at the start of line "page_line".
+ * If margin is TRUE start in the left margin (for header and line number).
+ *
+ * int mch_print_text_out(char_u *p, int len);
+ * Output one character of text p[len] at the current position.
+ * Return TRUE if there is no room for another character in the same line.
+ *
+ * Note that the generic code has no idea of margins. The machine code should
+ * simply make the page look smaller! The header and the line numbers are
+ * printed in the margin.
+ */
+
+static const long_u cterm_color_8[8] =
+{
+ (long_u)0x000000L, (long_u)0xff0000L, (long_u)0x00ff00L, (long_u)0xffff00L,
+ (long_u)0x0000ffL, (long_u)0xff00ffL, (long_u)0x00ffffL, (long_u)0xffffffL
+};
+
+static const long_u cterm_color_16[16] =
+{
+ (long_u)0x000000L, (long_u)0x0000c0L, (long_u)0x008000L, (long_u)0x004080L,
+ (long_u)0xc00000L, (long_u)0xc000c0L, (long_u)0x808000L, (long_u)0xc0c0c0L,
+ (long_u)0x808080L, (long_u)0x6060ffL, (long_u)0x00ff00L, (long_u)0x00ffffL,
+ (long_u)0xff8080L, (long_u)0xff40ffL, (long_u)0xffff00L, (long_u)0xffffffL
+};
+
+static int current_syn_id;
+
+#define PRCOLOR_BLACK (long_u)0
+#define PRCOLOR_WHITE (long_u)0xFFFFFFL
+
+static int curr_italic;
+static int curr_bold;
+static int curr_underline;
+static long_u curr_bg;
+static long_u curr_fg;
+static int page_count;
+
+# define OPT_MBFONT_USECOURIER 0
+# define OPT_MBFONT_ASCII 1
+# define OPT_MBFONT_REGULAR 2
+# define OPT_MBFONT_BOLD 3
+# define OPT_MBFONT_OBLIQUE 4
+# define OPT_MBFONT_BOLDOBLIQUE 5
+# define OPT_MBFONT_NUM_OPTIONS 6
+
+static option_table_T mbfont_opts[OPT_MBFONT_NUM_OPTIONS] =
+{
+ {"c", FALSE, 0, NULL, 0, FALSE},
+ {"a", FALSE, 0, NULL, 0, FALSE},
+ {"r", FALSE, 0, NULL, 0, FALSE},
+ {"b", FALSE, 0, NULL, 0, FALSE},
+ {"i", FALSE, 0, NULL, 0, FALSE},
+ {"o", FALSE, 0, NULL, 0, FALSE},
+};
+
+/*
+ * These values determine the print position on a page.
+ */
+typedef struct {
+ int lead_spaces; /* remaining spaces for a TAB */
+ int print_pos; /* virtual column for computing TABs */
+ colnr_T column; /* byte column */
+ linenr_T file_line; /* line nr in the buffer */
+ long_u bytes_printed; /* bytes printed so far */
+ int ff; /* seen form feed character */
+} prt_pos_T;
+
+static char_u *parse_list_options __ARGS((char_u *option_str, option_table_T *
+ table,
+ int table_size));
+
+static long_u darken_rgb __ARGS((long_u rgb));
+static long_u prt_get_term_color __ARGS((int colorindex));
+static void prt_set_fg __ARGS((long_u fg));
+static void prt_set_bg __ARGS((long_u bg));
+static void prt_set_font __ARGS((int bold, int italic, int underline));
+static void prt_line_number __ARGS((prt_settings_T *psettings, int page_line,
+ linenr_T lnum));
+static void prt_header __ARGS((prt_settings_T *psettings, int pagenum,
+ linenr_T lnum));
+static void prt_message __ARGS((char_u *s));
+static colnr_T hardcopy_line __ARGS((prt_settings_T *psettings, int page_line,
+ prt_pos_T *ppos));
+static void prt_get_attr __ARGS((int hl_id, prt_text_attr_T* pattr, int modec));
+
+/*
+ * Parse 'printoptions' and set the flags in "printer_opts".
+ * Returns an error message or NULL;
+ */
+char_u * parse_printoptions() {
+ return parse_list_options(p_popt, printer_opts, OPT_PRINT_NUM_OPTIONS);
+}
+
+/*
+ * Parse 'printoptions' and set the flags in "printer_opts".
+ * Returns an error message or NULL;
+ */
+char_u * parse_printmbfont() {
+ return parse_list_options(p_pmfn, mbfont_opts, OPT_MBFONT_NUM_OPTIONS);
+}
+
+/*
+ * Parse a list of options in the form
+ * option:value,option:value,option:value
+ *
+ * "value" can start with a number which is parsed out, e.g. margin:12mm
+ *
+ * Returns an error message for an illegal option, NULL otherwise.
+ * Only used for the printer at the moment...
+ */
+static char_u * parse_list_options(option_str, table, table_size)
+char_u *option_str;
+option_table_T *table;
+int table_size;
+{
+ char_u *stringp;
+ char_u *colonp;
+ char_u *commap;
+ char_u *p;
+ int idx = 0; /* init for GCC */
+ int len;
+
+ for (idx = 0; idx < table_size; ++idx)
+ table[idx].present = FALSE;
+
+ /*
+ * Repeat for all comma separated parts.
+ */
+ stringp = option_str;
+ while (*stringp) {
+ colonp = vim_strchr(stringp, ':');
+ if (colonp == NULL)
+ return (char_u *)N_("E550: Missing colon");
+ commap = vim_strchr(stringp, ',');
+ if (commap == NULL)
+ commap = option_str + STRLEN(option_str);
+
+ len = (int)(colonp - stringp);
+
+ for (idx = 0; idx < table_size; ++idx)
+ if (STRNICMP(stringp, table[idx].name, len) == 0)
+ break;
+
+ if (idx == table_size)
+ return (char_u *)N_("E551: Illegal component");
+
+ p = colonp + 1;
+ table[idx].present = TRUE;
+
+ if (table[idx].hasnum) {
+ if (!VIM_ISDIGIT(*p))
+ return (char_u *)N_("E552: digit expected");
+
+ table[idx].number = getdigits(&p); /*advances p*/
+ }
+
+ table[idx].string = p;
+ table[idx].strlen = (int)(commap - p);
+
+ stringp = commap;
+ if (*stringp == ',')
+ ++stringp;
+ }
+
+ return NULL;
+}
+
+
+/*
+ * If using a dark background, the colors will probably be too bright to show
+ * up well on white paper, so reduce their brightness.
+ */
+static long_u darken_rgb(rgb)
+long_u rgb;
+{
+ return ((rgb >> 17) << 16)
+ + (((rgb & 0xff00) >> 9) << 8)
+ + ((rgb & 0xff) >> 1);
+}
+
+static long_u prt_get_term_color(colorindex)
+int colorindex;
+{
+ /* TODO: Should check for xterm with 88 or 256 colors. */
+ if (t_colors > 8)
+ return cterm_color_16[colorindex % 16];
+ return cterm_color_8[colorindex % 8];
+}
+
+static void prt_get_attr(hl_id, pattr, modec)
+int hl_id;
+prt_text_attr_T *pattr;
+int modec;
+{
+ int colorindex;
+ long_u fg_color;
+ long_u bg_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);
+ pattr->underline = (highlight_has_attr(hl_id, HL_UNDERLINE, modec) != NULL);
+ pattr->undercurl = (highlight_has_attr(hl_id, HL_UNDERCURL, modec) != NULL);
+
+ {
+ bg_color = PRCOLOR_WHITE;
+
+ color = (char *)highlight_color(hl_id, (char_u *)"fg", modec);
+ if (color == NULL)
+ colorindex = 0;
+ else
+ colorindex = atoi(color);
+
+ if (colorindex >= 0 && colorindex < t_colors)
+ fg_color = prt_get_term_color(colorindex);
+ else
+ fg_color = PRCOLOR_BLACK;
+ }
+
+ if (fg_color == PRCOLOR_WHITE)
+ fg_color = PRCOLOR_BLACK;
+ else if (*p_bg == 'd')
+ fg_color = darken_rgb(fg_color);
+
+ pattr->fg_color = fg_color;
+ pattr->bg_color = bg_color;
+}
+
+static void prt_set_fg(fg)
+long_u fg;
+{
+ if (fg != curr_fg) {
+ curr_fg = fg;
+ mch_print_set_fg(fg);
+ }
+}
+
+static void prt_set_bg(bg)
+long_u bg;
+{
+ if (bg != curr_bg) {
+ curr_bg = bg;
+ mch_print_set_bg(bg);
+ }
+}
+
+static void prt_set_font(bold, italic, underline)
+int bold;
+int italic;
+int underline;
+{
+ if (curr_bold != bold
+ || curr_italic != italic
+ || curr_underline != underline) {
+ curr_underline = underline;
+ curr_italic = italic;
+ curr_bold = bold;
+ mch_print_set_font(bold, italic, underline);
+ }
+}
+
+/*
+ * Print the line number in the left margin.
+ */
+static void prt_line_number(psettings, page_line, lnum)
+prt_settings_T *psettings;
+int page_line;
+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);
+
+ /* 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++)
+ (void)mch_print_text_out(&tbuf[i], 1);
+
+ if (psettings->do_syntax)
+ /* Set colors for next character. */
+ current_syn_id = -1;
+ else {
+ /* Set colors and font back to normal. */
+ prt_set_fg(PRCOLOR_BLACK);
+ prt_set_bg(PRCOLOR_WHITE);
+ prt_set_font(FALSE, FALSE, FALSE);
+ }
+}
+
+/*
+ * Get the currently effective header height.
+ */
+int prt_header_height() {
+ if (printer_opts[OPT_PRINT_HEADERHEIGHT].present)
+ return printer_opts[OPT_PRINT_HEADERHEIGHT].number;
+ return 2;
+}
+
+/*
+ * Return TRUE if using a line number for printing.
+ */
+int prt_use_number() {
+ return printer_opts[OPT_PRINT_NUMBER].present
+ && TOLOWER_ASC(printer_opts[OPT_PRINT_NUMBER].string[0]) == 'y';
+}
+
+/*
+ * Return the unit used in a margin item in 'printoptions'.
+ * Returns PRT_UNIT_NONE if not recognized.
+ */
+int prt_get_unit(idx)
+int idx;
+{
+ int u = PRT_UNIT_NONE;
+ int i;
+ static char *(units[4]) = PRT_UNIT_NAMES;
+
+ if (printer_opts[idx].present)
+ for (i = 0; i < 4; ++i)
+ if (STRNICMP(printer_opts[idx].string, units[i], 2) == 0) {
+ u = i;
+ break;
+ }
+ return u;
+}
+
+/*
+ * Print the page header.
+ */
+static void prt_header(psettings, pagenum, lnum)
+prt_settings_T *psettings;
+int pagenum;
+linenr_T lnum UNUSED;
+{
+ int width = psettings->chars_per_line;
+ int page_line;
+ char_u *tbuf;
+ char_u *p;
+ int l;
+
+ /* Also use the space for the line number. */
+ if (prt_use_number())
+ width += PRINT_NUMBER_WIDTH;
+
+ tbuf = alloc(width + IOSIZE);
+ if (tbuf == NULL)
+ return;
+
+ if (*p_header != NUL) {
+ linenr_T tmp_lnum, tmp_topline, tmp_botline;
+ int use_sandbox = FALSE;
+
+ /*
+ * Need to (temporarily) set current line number and first/last line
+ * number on the 'window'. Since we don't know how long the page is,
+ * set the first and current line number to the top line, and guess
+ * that the page length is 64.
+ */
+ tmp_lnum = curwin->w_cursor.lnum;
+ tmp_topline = curwin->w_topline;
+ tmp_botline = curwin->w_botline;
+ curwin->w_cursor.lnum = lnum;
+ curwin->w_topline = lnum;
+ curwin->w_botline = lnum + 63;
+ printer_page_num = pagenum;
+
+ use_sandbox = was_set_insecurely((char_u *)"printheader", 0);
+ build_stl_str_hl(curwin, tbuf, (size_t)(width + IOSIZE),
+ p_header, use_sandbox,
+ ' ', width, NULL, NULL);
+
+ /* Reset line numbers */
+ curwin->w_cursor.lnum = tmp_lnum;
+ curwin->w_topline = tmp_topline;
+ curwin->w_botline = tmp_botline;
+ } else
+ sprintf((char *)tbuf, _("Page %d"), pagenum);
+
+ prt_set_fg(PRCOLOR_BLACK);
+ prt_set_bg(PRCOLOR_WHITE);
+ prt_set_font(TRUE, FALSE, FALSE);
+
+ /* 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; ) {
+ if (mch_print_text_out(p,
+ (l = (*mb_ptr2len)(p))
+ )) {
+ ++page_line;
+ if (page_line >= 0) /* out of room in header */
+ break;
+ mch_print_start_line(TRUE, page_line);
+ }
+ p += l;
+ }
+
+ vim_free(tbuf);
+
+ if (psettings->do_syntax)
+ /* Set colors for next character. */
+ current_syn_id = -1;
+ else {
+ /* Set colors and font back to normal. */
+ prt_set_fg(PRCOLOR_BLACK);
+ prt_set_bg(PRCOLOR_WHITE);
+ prt_set_font(FALSE, FALSE, FALSE);
+ }
+}
+
+/*
+ * Display a print status message.
+ */
+static void prt_message(s)
+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));
+ out_flush();
+}
+
+void ex_hardcopy(eap)
+exarg_T *eap;
+{
+ linenr_T lnum;
+ int collated_copies, uncollated_copies;
+ prt_settings_T settings;
+ long_u bytes_to_print = 0;
+ int page_line;
+ int jobsplit;
+
+ vim_memset(&settings, 0, sizeof(prt_settings_T));
+ settings.has_color = TRUE;
+
+ if (*eap->arg == '>') {
+ char_u *errormsg = NULL;
+
+ /* Expand things like "%.ps". */
+ if (expand_filename(eap, eap->cmdlinep, &errormsg) == FAIL) {
+ if (errormsg != NULL)
+ EMSG(errormsg);
+ return;
+ }
+ settings.outfile = skipwhite(eap->arg + 1);
+ } else if (*eap->arg != NUL)
+ settings.arguments = eap->arg;
+
+ /*
+ * Initialise for printing. Ask the user for settings, unless forceit is
+ * set.
+ * The mch_print_init() code should set up margins if applicable. (It may
+ * not be a real printer - for example the engine might generate HTML or
+ * PS.)
+ */
+ if (mch_print_init(&settings,
+ curbuf->b_fname == NULL
+ ? (char_u *)buf_spname(curbuf)
+ : curbuf->b_sfname == NULL
+ ? curbuf->b_fname
+ : curbuf->b_sfname,
+ eap->forceit) == FAIL)
+ return;
+
+ if (t_colors > 1)
+ settings.modec = 'c';
+ else
+ settings.modec = 't';
+
+ if (!syntax_present(curwin))
+ settings.do_syntax = FALSE;
+ else if (printer_opts[OPT_PRINT_SYNTAX].present
+ && TOLOWER_ASC(printer_opts[OPT_PRINT_SYNTAX].string[0]) != 'a')
+ settings.do_syntax =
+ (TOLOWER_ASC(printer_opts[OPT_PRINT_SYNTAX].string[0]) == 'y');
+ else
+ settings.do_syntax = settings.has_color;
+
+ /* 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;
+
+ id = syn_name2id((char_u *)"LineNr");
+ if (id > 0)
+ id = syn_get_final_id(id);
+
+ prt_get_attr(id, &settings.number, settings.modec);
+ }
+
+ /*
+ * Estimate the total lines to be printed
+ */
+ for (lnum = eap->line1; lnum <= eap->line2; lnum++)
+ bytes_to_print += (long_u)STRLEN(skipwhite(ml_get(lnum)));
+ if (bytes_to_print == 0) {
+ MSG(_("No text to be printed"));
+ goto print_fail_no_begin;
+ }
+
+ /* Set colors and font to normal. */
+ curr_bg = (long_u)0xffffffffL;
+ curr_fg = (long_u)0xffffffffL;
+ curr_italic = MAYBE;
+ curr_bold = MAYBE;
+ curr_underline = MAYBE;
+
+ prt_set_fg(PRCOLOR_BLACK);
+ prt_set_bg(PRCOLOR_WHITE);
+ prt_set_font(FALSE, FALSE, FALSE);
+ current_syn_id = -1;
+
+ jobsplit = (printer_opts[OPT_PRINT_JOBSPLIT].present
+ && TOLOWER_ASC(printer_opts[OPT_PRINT_JOBSPLIT].string[0]) == 'y');
+
+ if (!mch_print_begin(&settings))
+ goto print_fail_no_begin;
+
+ /*
+ * Loop over collated copies: 1 2 3, 1 2 3, ...
+ */
+ page_count = 0;
+ for (collated_copies = 0;
+ collated_copies < settings.n_collated_copies;
+ collated_copies++) {
+ prt_pos_T prtpos; /* current print position */
+ prt_pos_T page_prtpos; /* print position at page start */
+ int side;
+
+ vim_memset(&page_prtpos, 0, sizeof(prt_pos_T));
+ page_prtpos.file_line = eap->line1;
+ prtpos = page_prtpos;
+
+ if (jobsplit && collated_copies > 0) {
+ /* Splitting jobs: Stop a previous job and start a new one. */
+ mch_print_end(&settings);
+ if (!mch_print_begin(&settings))
+ goto print_fail_no_begin;
+ }
+
+ /*
+ * Loop over all pages in the print job: 1 2 3 ...
+ */
+ for (page_count = 0; prtpos.file_line <= eap->line2; ++page_count) {
+ /*
+ * Loop over uncollated copies: 1 1 1, 2 2 2, 3 3 3, ...
+ * For duplex: 12 12 12 34 34 34, ...
+ */
+ for (uncollated_copies = 0;
+ uncollated_copies < settings.n_uncollated_copies;
+ uncollated_copies++) {
+ /* Set the print position to the start of this page. */
+ prtpos = page_prtpos;
+
+ /*
+ * Do front and rear side of a page.
+ */
+ for (side = 0; side <= settings.duplex; ++side) {
+ /*
+ * Print one page.
+ */
+
+ /* Check for interrupt character every page. */
+ ui_breakcheck();
+ if (got_int || settings.user_abort)
+ goto print_fail;
+
+ sprintf((char *)IObuff, _("Printing page %d (%d%%)"),
+ page_count + 1 + side,
+ prtpos.bytes_printed > 1000000
+ ? (int)(prtpos.bytes_printed /
+ (bytes_to_print / 100))
+ : (int)((prtpos.bytes_printed * 100)
+ / bytes_to_print));
+ if (!mch_print_begin_page(IObuff))
+ goto print_fail;
+
+ if (settings.n_collated_copies > 1)
+ sprintf((char *)IObuff + STRLEN(IObuff),
+ _(" Copy %d of %d"),
+ collated_copies + 1,
+ settings.n_collated_copies);
+ prt_message(IObuff);
+
+ /*
+ * Output header if required
+ */
+ if (prt_header_height() > 0)
+ prt_header(&settings, page_count + 1 + side,
+ prtpos.file_line);
+
+ for (page_line = 0; page_line < settings.lines_per_page;
+ ++page_line) {
+ prtpos.column = hardcopy_line(&settings,
+ page_line, &prtpos);
+ if (prtpos.column == 0) {
+ /* finished a file line */
+ prtpos.bytes_printed +=
+ STRLEN(skipwhite(ml_get(prtpos.file_line)));
+ if (++prtpos.file_line > eap->line2)
+ break; /* reached the end */
+ } else if (prtpos.ff) {
+ /* Line had a formfeed in it - start new page but
+ * stay on the current line */
+ break;
+ }
+ }
+
+ if (!mch_print_end_page())
+ goto print_fail;
+ if (prtpos.file_line > eap->line2)
+ break; /* reached the end */
+ }
+
+ /*
+ * Extra blank page for duplexing with odd number of pages and
+ * more copies to come.
+ */
+ if (prtpos.file_line > eap->line2 && settings.duplex
+ && side == 0
+ && uncollated_copies + 1 < settings.n_uncollated_copies) {
+ if (!mch_print_blank_page())
+ goto print_fail;
+ }
+ }
+ if (settings.duplex && prtpos.file_line <= eap->line2)
+ ++page_count;
+
+ /* Remember the position where the next page starts. */
+ page_prtpos = prtpos;
+ }
+
+ vim_snprintf((char *)IObuff, IOSIZE, _("Printed: %s"),
+ settings.jobname);
+ prt_message(IObuff);
+ }
+
+print_fail:
+ if (got_int || settings.user_abort) {
+ sprintf((char *)IObuff, "%s", _("Printing aborted"));
+ prt_message(IObuff);
+ }
+ mch_print_end(&settings);
+
+print_fail_no_begin:
+ mch_print_cleanup();
+}
+
+/*
+ * Print one page line.
+ * Return the next column to print, or zero if the line is finished.
+ */
+static colnr_T hardcopy_line(psettings, page_line, ppos)
+prt_settings_T *psettings;
+int page_line;
+prt_pos_T *ppos;
+{
+ colnr_T col;
+ char_u *line;
+ int need_break = FALSE;
+ int outputlen;
+ int tab_spaces;
+ long_u print_pos;
+ prt_text_attr_T attr;
+ int id;
+
+ if (ppos->column == 0 || ppos->ff) {
+ print_pos = 0;
+ tab_spaces = 0;
+ if (!ppos->ff && prt_use_number())
+ prt_line_number(psettings, page_line, ppos->file_line);
+ ppos->ff = FALSE;
+ } else {
+ /* left over from wrap halfway a tab */
+ print_pos = ppos->print_pos;
+ tab_spaces = ppos->lead_spaces;
+ }
+
+ mch_print_start_line(0, 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)
+ outputlen = 1;
+ /*
+ * syntax highlighting stuff.
+ */
+ if (psettings->do_syntax) {
+ id = syn_get_id(curwin, ppos->file_line, col, 1, NULL, FALSE);
+ if (id > 0)
+ id = syn_get_final_id(id);
+ else
+ id = 0;
+ /* Get the line again, a multi-line regexp may invalidate it. */
+ line = ml_get(ppos->file_line);
+
+ if (id != current_syn_id) {
+ current_syn_id = id;
+ prt_get_attr(id, &attr, psettings->modec);
+ prt_set_font(attr.bold, attr.italic, attr.underline);
+ prt_set_fg(attr.fg_color);
+ prt_set_bg(attr.bg_color);
+ }
+ }
+
+ /*
+ * Appropriately expand any tabs to spaces.
+ */
+ if (line[col] == TAB || tab_spaces != 0) {
+ if (tab_spaces == 0)
+ tab_spaces = (int)(curbuf->b_p_ts - (print_pos % curbuf->b_p_ts));
+
+ while (tab_spaces > 0) {
+ need_break = mch_print_text_out((char_u *)" ", 1);
+ print_pos++;
+ tab_spaces--;
+ if (need_break)
+ break;
+ }
+ /* Keep the TAB if we didn't finish it. */
+ if (need_break && tab_spaces > 0)
+ break;
+ } else if (line[col] == FF
+ && printer_opts[OPT_PRINT_FORMFEED].present
+ && TOLOWER_ASC(printer_opts[OPT_PRINT_FORMFEED].string[0])
+ == 'y') {
+ ppos->ff = TRUE;
+ need_break = 1;
+ } else {
+ need_break = mch_print_text_out(line + col, outputlen);
+ if (has_mbyte)
+ print_pos += (*mb_ptr2cells)(line + col);
+ else
+ print_pos++;
+ }
+ }
+
+ ppos->lead_spaces = tab_spaces;
+ ppos->print_pos = (int)print_pos;
+
+ /*
+ * Start next line of file if we clip lines, or have reached end of the
+ * line, unless we are doing a formfeed.
+ */
+ if (!ppos->ff
+ && (line[col] == NUL
+ || (printer_opts[OPT_PRINT_WRAP].present
+ && TOLOWER_ASC(printer_opts[OPT_PRINT_WRAP].string[0])
+ == 'n')))
+ return 0;
+ return col;
+}
+
+
+/*
+ * PS printer stuff.
+ *
+ * Sources of information to help maintain the PS printing code:
+ *
+ * 1. PostScript Language Reference, 3rd Edition,
+ * Addison-Wesley, 1999, ISBN 0-201-37922-8
+ * 2. PostScript Language Program Design,
+ * Addison-Wesley, 1988, ISBN 0-201-14396-8
+ * 3. PostScript Tutorial and Cookbook,
+ * Addison Wesley, 1985, ISBN 0-201-10179-3
+ * 4. PostScript Language Document Structuring Conventions Specification,
+ * version 3.0,
+ * Adobe Technote 5001, 25th September 1992
+ * 5. PostScript Printer Description File Format Specification, Version 4.3,
+ * Adobe technote 5003, 9th February 1996
+ * 6. Adobe Font Metrics File Format Specification, Version 4.1,
+ * Adobe Technote 5007, 7th October 1998
+ * 7. Adobe CMap and CIDFont Files Specification, Version 1.0,
+ * Adobe Technote 5014, 8th October 1996
+ * 8. Adobe CJKV Character Collections and CMaps for CID-Keyed Fonts,
+ * Adoboe Technote 5094, 8th September, 2001
+ * 9. CJKV Information Processing, 2nd Edition,
+ * O'Reilly, 2002, ISBN 1-56592-224-7
+ *
+ * Some of these documents can be found in PDF form on Adobe's web site -
+ * http://www.adobe.com
+ */
+
+#define NUM_ELEMENTS(arr) (sizeof(arr)/sizeof((arr)[0]))
+
+#define PRT_PS_DEFAULT_DPI (72) /* Default user space resolution */
+#define PRT_PS_DEFAULT_FONTSIZE (10)
+#define PRT_PS_DEFAULT_BUFFER_SIZE (80)
+
+struct prt_mediasize_S {
+ char *name;
+ float width; /* width and height in points for portrait */
+ float height;
+};
+
+#define PRT_MEDIASIZE_LEN (sizeof(prt_mediasize) / \
+ sizeof(struct prt_mediasize_S))
+
+static struct prt_mediasize_S prt_mediasize[] =
+{
+ {"A4", 595.0, 842.0},
+ {"letter", 612.0, 792.0},
+ {"10x14", 720.0, 1008.0},
+ {"A3", 842.0, 1191.0},
+ {"A5", 420.0, 595.0},
+ {"B4", 729.0, 1032.0},
+ {"B5", 516.0, 729.0},
+ {"executive", 522.0, 756.0},
+ {"folio", 595.0, 935.0},
+ {"ledger", 1224.0, 792.0}, /* Yes, it is wider than taller! */
+ {"legal", 612.0, 1008.0},
+ {"quarto", 610.0, 780.0},
+ {"statement", 396.0, 612.0},
+ {"tabloid", 792.0, 1224.0}
+};
+
+/* PS font names, must be in Roman, Bold, Italic, Bold-Italic order */
+struct prt_ps_font_S {
+ int wx;
+ int uline_offset;
+ int uline_width;
+ int bbox_min_y;
+ int bbox_max_y;
+ char *(ps_fontname[4]);
+};
+
+#define PRT_PS_FONT_ROMAN (0)
+#define PRT_PS_FONT_BOLD (1)
+#define PRT_PS_FONT_OBLIQUE (2)
+#define PRT_PS_FONT_BOLDOBLIQUE (3)
+
+/* Standard font metrics for Courier family */
+static struct prt_ps_font_S prt_ps_courier_font =
+{
+ 600,
+ -100, 50,
+ -250, 805,
+ {"Courier", "Courier-Bold", "Courier-Oblique", "Courier-BoldOblique"}
+};
+
+/* Generic font metrics for multi-byte fonts */
+static struct prt_ps_font_S prt_ps_mb_font =
+{
+ 1000,
+ -100, 50,
+ -250, 805,
+ {NULL, NULL, NULL, NULL}
+};
+
+/* Pointer to current font set being used */
+static struct prt_ps_font_S* prt_ps_font;
+
+/* Structures to map user named encoding and mapping to PS equivalents for
+ * building CID font name */
+struct prt_ps_encoding_S {
+ char *encoding;
+ char *cmap_encoding;
+ int needs_charset;
+};
+
+struct prt_ps_charset_S {
+ char *charset;
+ char *cmap_charset;
+ int has_charset;
+};
+
+
+#define CS_JIS_C_1978 (0x01)
+#define CS_JIS_X_1983 (0x02)
+#define CS_JIS_X_1990 (0x04)
+#define CS_NEC (0x08)
+#define CS_MSWINDOWS (0x10)
+#define CS_CP932 (0x20)
+#define CS_KANJITALK6 (0x40)
+#define CS_KANJITALK7 (0x80)
+
+/* Japanese encodings and charsets */
+static struct prt_ps_encoding_S j_encodings[] =
+{
+ {"iso-2022-jp", NULL, (CS_JIS_C_1978|CS_JIS_X_1983|CS_JIS_X_1990|
+ CS_NEC)},
+ {"euc-jp", "EUC", (CS_JIS_C_1978|CS_JIS_X_1983|CS_JIS_X_1990)},
+ {"sjis", "RKSJ", (CS_JIS_C_1978|CS_JIS_X_1983|CS_MSWINDOWS|
+ CS_KANJITALK6|CS_KANJITALK7)},
+ {"cp932", "RKSJ", CS_JIS_X_1983},
+ {"ucs-2", "UCS2", CS_JIS_X_1990},
+ {"utf-8", "UTF8", CS_JIS_X_1990}
+};
+static struct prt_ps_charset_S j_charsets[] =
+{
+ {"JIS_C_1978", "78", CS_JIS_C_1978},
+ {"JIS_X_1983", NULL, CS_JIS_X_1983},
+ {"JIS_X_1990", "Hojo", CS_JIS_X_1990},
+ {"NEC", "Ext", CS_NEC},
+ {"MSWINDOWS", "90ms", CS_MSWINDOWS},
+ {"CP932", "90ms", CS_JIS_X_1983},
+ {"KANJITALK6", "83pv", CS_KANJITALK6},
+ {"KANJITALK7", "90pv", CS_KANJITALK7}
+};
+
+#define CS_GB_2312_80 (0x01)
+#define CS_GBT_12345_90 (0x02)
+#define CS_GBK2K (0x04)
+#define CS_SC_MAC (0x08)
+#define CS_GBT_90_MAC (0x10)
+#define CS_GBK (0x20)
+#define CS_SC_ISO10646 (0x40)
+
+/* Simplified Chinese encodings and charsets */
+static struct prt_ps_encoding_S sc_encodings[] =
+{
+ {"iso-2022", NULL, (CS_GB_2312_80|CS_GBT_12345_90)},
+ {"gb18030", NULL, CS_GBK2K},
+ {"euc-cn", "EUC", (CS_GB_2312_80|CS_GBT_12345_90|CS_SC_MAC|
+ CS_GBT_90_MAC)},
+ {"gbk", "EUC", CS_GBK},
+ {"ucs-2", "UCS2", CS_SC_ISO10646},
+ {"utf-8", "UTF8", CS_SC_ISO10646}
+};
+static struct prt_ps_charset_S sc_charsets[] =
+{
+ {"GB_2312-80", "GB", CS_GB_2312_80},
+ {"GBT_12345-90","GBT", CS_GBT_12345_90},
+ {"MAC", "GBpc", CS_SC_MAC},
+ {"GBT-90_MAC", "GBTpc", CS_GBT_90_MAC},
+ {"GBK", "GBK", CS_GBK},
+ {"GB18030", "GBK2K", CS_GBK2K},
+ {"ISO10646", "UniGB", CS_SC_ISO10646}
+};
+
+#define CS_CNS_PLANE_1 (0x01)
+#define CS_CNS_PLANE_2 (0x02)
+#define CS_CNS_PLANE_1_2 (0x04)
+#define CS_B5 (0x08)
+#define CS_ETEN (0x10)
+#define CS_HK_GCCS (0x20)
+#define CS_HK_SCS (0x40)
+#define CS_HK_SCS_ETEN (0x80)
+#define CS_MTHKL (0x100)
+#define CS_MTHKS (0x200)
+#define CS_DLHKL (0x400)
+#define CS_DLHKS (0x800)
+#define CS_TC_ISO10646 (0x1000)
+
+/* Traditional Chinese encodings and charsets */
+static struct prt_ps_encoding_S tc_encodings[] =
+{
+ {"iso-2022", NULL, (CS_CNS_PLANE_1|CS_CNS_PLANE_2)},
+ {"euc-tw", "EUC", CS_CNS_PLANE_1_2},
+ {"big5", "B5", (CS_B5|CS_ETEN|CS_HK_GCCS|CS_HK_SCS|
+ CS_HK_SCS_ETEN|CS_MTHKL|CS_MTHKS|CS_DLHKL|
+ CS_DLHKS)},
+ {"cp950", "B5", CS_B5},
+ {"ucs-2", "UCS2", CS_TC_ISO10646},
+ {"utf-8", "UTF8", CS_TC_ISO10646},
+ {"utf-16", "UTF16", CS_TC_ISO10646},
+ {"utf-32", "UTF32", CS_TC_ISO10646}
+};
+static struct prt_ps_charset_S tc_charsets[] =
+{
+ {"CNS_1992_1", "CNS1", CS_CNS_PLANE_1},
+ {"CNS_1992_2", "CNS2", CS_CNS_PLANE_2},
+ {"CNS_1993", "CNS", CS_CNS_PLANE_1_2},
+ {"BIG5", NULL, CS_B5},
+ {"CP950", NULL, CS_B5},
+ {"ETEN", "ETen", CS_ETEN},
+ {"HK_GCCS", "HKgccs", CS_HK_GCCS},
+ {"SCS", "HKscs", CS_HK_SCS},
+ {"SCS_ETEN", "ETHK", CS_HK_SCS_ETEN},
+ {"MTHKL", "HKm471", CS_MTHKL},
+ {"MTHKS", "HKm314", CS_MTHKS},
+ {"DLHKL", "HKdla", CS_DLHKL},
+ {"DLHKS", "HKdlb", CS_DLHKS},
+ {"ISO10646", "UniCNS", CS_TC_ISO10646}
+};
+
+#define CS_KR_X_1992 (0x01)
+#define CS_KR_MAC (0x02)
+#define CS_KR_X_1992_MS (0x04)
+#define CS_KR_ISO10646 (0x08)
+
+/* Korean encodings and charsets */
+static struct prt_ps_encoding_S k_encodings[] =
+{
+ {"iso-2022-kr", NULL, CS_KR_X_1992},
+ {"euc-kr", "EUC", (CS_KR_X_1992|CS_KR_MAC)},
+ {"johab", "Johab", CS_KR_X_1992},
+ {"cp1361", "Johab", CS_KR_X_1992},
+ {"uhc", "UHC", CS_KR_X_1992_MS},
+ {"cp949", "UHC", CS_KR_X_1992_MS},
+ {"ucs-2", "UCS2", CS_KR_ISO10646},
+ {"utf-8", "UTF8", CS_KR_ISO10646}
+};
+static struct prt_ps_charset_S k_charsets[] =
+{
+ {"KS_X_1992", "KSC", CS_KR_X_1992},
+ {"CP1361", "KSC", CS_KR_X_1992},
+ {"MAC", "KSCpc", CS_KR_MAC},
+ {"MSWINDOWS", "KSCms", CS_KR_X_1992_MS},
+ {"CP949", "KSCms", CS_KR_X_1992_MS},
+ {"WANSUNG", "KSCms", CS_KR_X_1992_MS},
+ {"ISO10646", "UniKS", CS_KR_ISO10646}
+};
+
+/* Collections of encodings and charsets for multi-byte printing */
+struct prt_ps_mbfont_S {
+ int num_encodings;
+ struct prt_ps_encoding_S *encodings;
+ int num_charsets;
+ struct prt_ps_charset_S *charsets;
+ char *ascii_enc;
+ char *defcs;
+};
+
+static struct prt_ps_mbfont_S prt_ps_mbfonts[] =
+{
+ {
+ NUM_ELEMENTS(j_encodings),
+ j_encodings,
+ NUM_ELEMENTS(j_charsets),
+ j_charsets,
+ "jis_roman",
+ "JIS_X_1983"
+ },
+ {
+ NUM_ELEMENTS(sc_encodings),
+ sc_encodings,
+ NUM_ELEMENTS(sc_charsets),
+ sc_charsets,
+ "gb_roman",
+ "GB_2312-80"
+ },
+ {
+ NUM_ELEMENTS(tc_encodings),
+ tc_encodings,
+ NUM_ELEMENTS(tc_charsets),
+ tc_charsets,
+ "cns_roman",
+ "BIG5"
+ },
+ {
+ NUM_ELEMENTS(k_encodings),
+ k_encodings,
+ NUM_ELEMENTS(k_charsets),
+ k_charsets,
+ "ks_roman",
+ "KS_X_1992"
+ }
+};
+
+struct prt_ps_resource_S {
+ char_u name[64];
+ char_u filename[MAXPATHL + 1];
+ int type;
+ char_u title[256];
+ char_u version[256];
+};
+
+/* Types of PS resource file currently used */
+#define PRT_RESOURCE_TYPE_PROCSET (0)
+#define PRT_RESOURCE_TYPE_ENCODING (1)
+#define PRT_RESOURCE_TYPE_CMAP (2)
+
+/* The PS prolog file version number has to match - if the prolog file is
+ * updated, increment the number in the file and here. Version checking was
+ * added as of VIM 6.2.
+ * The CID prolog file version number behaves as per PS prolog.
+ * Table of VIM and prolog versions:
+ *
+ * VIM Prolog CIDProlog
+ * 6.2 1.3
+ * 7.0 1.4 1.0
+ */
+#define PRT_PROLOG_VERSION ((char_u *)"1.4")
+#define PRT_CID_PROLOG_VERSION ((char_u *)"1.0")
+
+/* String versions of PS resource types - indexed by constants above so don't
+ * re-order!
+ */
+static char *prt_resource_types[] =
+{
+ "procset",
+ "encoding",
+ "cmap"
+};
+
+/* Strings to look for in a PS resource file */
+#define PRT_RESOURCE_HEADER "%!PS-Adobe-"
+#define PRT_RESOURCE_RESOURCE "Resource-"
+#define PRT_RESOURCE_PROCSET "ProcSet"
+#define PRT_RESOURCE_ENCODING "Encoding"
+#define PRT_RESOURCE_CMAP "CMap"
+
+
+/* Data for table based DSC comment recognition, easy to extend if VIM needs to
+ * read more comments. */
+#define PRT_DSC_MISC_TYPE (-1)
+#define PRT_DSC_TITLE_TYPE (1)
+#define PRT_DSC_VERSION_TYPE (2)
+#define PRT_DSC_ENDCOMMENTS_TYPE (3)
+
+#define PRT_DSC_TITLE "%%Title:"
+#define PRT_DSC_VERSION "%%Version:"
+#define PRT_DSC_ENDCOMMENTS "%%EndComments:"
+
+struct prt_dsc_comment_S {
+ char *string;
+ int len;
+ int type;
+};
+
+struct prt_dsc_line_S {
+ int type;
+ char_u *string;
+ int len;
+};
+
+
+#define SIZEOF_CSTR(s) (sizeof(s) - 1)
+static struct prt_dsc_comment_S prt_dsc_table[] =
+{
+ {PRT_DSC_TITLE, SIZEOF_CSTR(PRT_DSC_TITLE), PRT_DSC_TITLE_TYPE},
+ {PRT_DSC_VERSION, SIZEOF_CSTR(PRT_DSC_VERSION),
+ PRT_DSC_VERSION_TYPE},
+ {PRT_DSC_ENDCOMMENTS, SIZEOF_CSTR(PRT_DSC_ENDCOMMENTS),
+ PRT_DSC_ENDCOMMENTS_TYPE}
+};
+
+static void prt_write_file_raw_len __ARGS((char_u *buffer, int bytes));
+static void prt_write_file __ARGS((char_u *buffer));
+static void prt_write_file_len __ARGS((char_u *buffer, int bytes));
+static void prt_write_string __ARGS((char *s));
+static void prt_write_int __ARGS((int i));
+static void prt_write_boolean __ARGS((int b));
+static void prt_def_font __ARGS((char *new_name, char *encoding, int height,
+ char *font));
+static void prt_real_bits __ARGS((double real, int precision, int *pinteger,
+ int *pfraction));
+static void prt_write_real __ARGS((double val, int prec));
+static void prt_def_var __ARGS((char *name, double value, int prec));
+static void prt_flush_buffer __ARGS((void));
+static void prt_resource_name __ARGS((char_u *filename, void *cookie));
+static int prt_find_resource __ARGS((char *name,
+ struct prt_ps_resource_S *resource));
+static int prt_open_resource __ARGS((struct prt_ps_resource_S *resource));
+static int prt_check_resource __ARGS((struct prt_ps_resource_S *resource,
+ char_u *version));
+static void prt_dsc_start __ARGS((void));
+static void prt_dsc_noarg __ARGS((char *comment));
+static void prt_dsc_textline __ARGS((char *comment, char *text));
+static void prt_dsc_text __ARGS((char *comment, char *text));
+static void prt_dsc_ints __ARGS((char *comment, int count, int *ints));
+static void prt_dsc_requirements __ARGS((int duplex, int tumble, int collate,
+ int color,
+ int num_copies));
+static void prt_dsc_docmedia __ARGS((char *paper_name, double width,
+ double height, double weight, char *colour,
+ char *type));
+static void prt_dsc_resources __ARGS((char *comment, char *type, char *strings));
+static void prt_dsc_font_resource __ARGS((char *resource,
+ struct prt_ps_font_S *ps_font));
+static float to_device_units __ARGS((int idx, double physsize, int def_number));
+static void prt_page_margins __ARGS((double width, double height, double *left,
+ double *right, double *top,
+ double *bottom));
+static void prt_font_metrics __ARGS((int font_scale));
+static int prt_get_cpl __ARGS((void));
+static int prt_get_lpp __ARGS((void));
+static int prt_add_resource __ARGS((struct prt_ps_resource_S *resource));
+static int prt_resfile_next_line __ARGS((void));
+static int prt_resfile_strncmp __ARGS((int offset, char *string, int len));
+static int prt_resfile_skip_nonws __ARGS((int offset));
+static int prt_resfile_skip_ws __ARGS((int offset));
+static int prt_next_dsc __ARGS((struct prt_dsc_line_S *p_dsc_line));
+static int prt_build_cid_fontname __ARGS((int font, char_u *name, int name_len));
+static void prt_def_cidfont __ARGS((char *new_name, int height, char *cidfont));
+static void prt_dup_cidfont __ARGS((char *original_name, char *new_name));
+static int prt_match_encoding __ARGS((char *p_encoding,
+ struct prt_ps_mbfont_S *p_cmap,
+ struct prt_ps_encoding_S **pp_mbenc));
+static int prt_match_charset __ARGS((char *p_charset,
+ struct prt_ps_mbfont_S *p_cmap,
+ struct prt_ps_charset_S **pp_mbchar));
+
+/*
+ * Variables for the output PostScript file.
+ */
+static FILE *prt_ps_fd;
+static int prt_file_error;
+static char_u *prt_ps_file_name = NULL;
+
+/*
+ * Various offsets and dimensions in default PostScript user space (points).
+ * Used for text positioning calculations
+ */
+static float prt_page_width;
+static float prt_page_height;
+static float prt_left_margin;
+static float prt_right_margin;
+static float prt_top_margin;
+static float prt_bottom_margin;
+static float prt_line_height;
+static float prt_first_line_height;
+static float prt_char_width;
+static float prt_number_width;
+static float prt_bgcol_offset;
+static float prt_pos_x_moveto = 0.0;
+static float prt_pos_y_moveto = 0.0;
+
+/*
+ * Various control variables used to decide when and how to change the
+ * PostScript graphics state.
+ */
+static int prt_need_moveto;
+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 int prt_need_fgcol;
+static int prt_fgcol;
+static int prt_need_bgcol;
+static int prt_do_bgcol;
+static int prt_bgcol;
+static int prt_new_bgcol;
+static int prt_attribute_change;
+static float prt_text_run;
+static int prt_page_num;
+static int prt_bufsiz;
+
+/*
+ * Variables controlling physical printing.
+ */
+static int prt_media;
+static int prt_portrait;
+static int prt_num_copies;
+static int prt_duplex;
+static int prt_tumble;
+static int prt_collate;
+
+/*
+ * Buffers used when generating PostScript output
+ */
+static char_u prt_line_buffer[257];
+static garray_T prt_ps_buffer;
+
+static int prt_do_conv;
+static vimconv_T prt_conv;
+
+static int prt_out_mbyte;
+static int prt_custom_cmap;
+static char prt_cmap[80];
+static int prt_use_courier;
+static int prt_in_ascii;
+static int prt_half_width;
+static char *prt_ascii_encoding;
+static char_u prt_hexchar[] = "0123456789abcdef";
+
+static void prt_write_file_raw_len(buffer, bytes)
+char_u *buffer;
+int bytes;
+{
+ if (!prt_file_error
+ && fwrite(buffer, sizeof(char_u), bytes, prt_ps_fd)
+ != (size_t)bytes) {
+ EMSG(_("E455: Error writing to PostScript output file"));
+ prt_file_error = TRUE;
+ }
+}
+
+static void prt_write_file(buffer)
+char_u *buffer;
+{
+ prt_write_file_len(buffer, (int)STRLEN(buffer));
+}
+
+static void prt_write_file_len(buffer, bytes)
+char_u *buffer;
+int bytes;
+{
+ prt_write_file_raw_len(buffer, bytes);
+}
+
+/*
+ * Write a string.
+ */
+static void prt_write_string(s)
+char *s;
+{
+ vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer), "%s", s);
+ prt_write_file(prt_line_buffer);
+}
+
+/*
+ * Write an int and a space.
+ */
+static void prt_write_int(i)
+int i;
+{
+ sprintf((char *)prt_line_buffer, "%d ", i);
+ prt_write_file(prt_line_buffer);
+}
+
+/*
+ * Write a boolean and a space.
+ */
+static void prt_write_boolean(b)
+int b;
+{
+ sprintf((char *)prt_line_buffer, "%s ", (b ? "T" : "F"));
+ prt_write_file(prt_line_buffer);
+}
+
+/*
+ * Write PostScript to re-encode and define the font.
+ */
+static void prt_def_font(new_name, encoding, height, font)
+char *new_name;
+char *encoding;
+int height;
+char *font;
+{
+ vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer),
+ "/_%s /VIM-%s /%s ref\n", new_name, encoding, font);
+ prt_write_file(prt_line_buffer);
+ if (prt_out_mbyte)
+ sprintf((char *)prt_line_buffer, "/%s %d %f /_%s sffs\n",
+ new_name, height, 500./prt_ps_courier_font.wx, new_name);
+ else
+ vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer),
+ "/%s %d /_%s ffs\n", new_name, height, new_name);
+ prt_write_file(prt_line_buffer);
+}
+
+/*
+ * Write a line to define the CID font.
+ */
+static void prt_def_cidfont(new_name, height, cidfont)
+char *new_name;
+int height;
+char *cidfont;
+{
+ vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer),
+ "/_%s /%s[/%s] vim_composefont\n", new_name, prt_cmap, cidfont);
+ prt_write_file(prt_line_buffer);
+ vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer),
+ "/%s %d /_%s ffs\n", new_name, height, new_name);
+ prt_write_file(prt_line_buffer);
+}
+
+/*
+ * Write a line to define a duplicate of a CID font
+ */
+static void prt_dup_cidfont(original_name, new_name)
+char *original_name;
+char *new_name;
+{
+ vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer),
+ "/%s %s d\n", new_name, original_name);
+ prt_write_file(prt_line_buffer);
+}
+
+/*
+ * Convert a real value into an integer and fractional part as integers, with
+ * the fractional part being in the range [0,10^precision). The fractional part
+ * is also rounded based on the precision + 1'th fractional digit.
+ */
+static void prt_real_bits(real, precision, pinteger, pfraction)
+double real;
+int precision;
+int *pinteger;
+int *pfraction;
+{
+ int i;
+ int integer;
+ float fraction;
+
+ integer = (int)real;
+ fraction = (float)(real - integer);
+ if (real < (double)integer)
+ fraction = -fraction;
+ for (i = 0; i < precision; i++)
+ fraction *= 10.0;
+
+ *pinteger = integer;
+ *pfraction = (int)(fraction + 0.5);
+}
+
+/*
+ * Write a real and a space. Save bytes if real value has no fractional part!
+ * We use prt_real_bits() as %f in sprintf uses the locale setting to decide
+ * what decimal point character to use, but PS always requires a '.'.
+ */
+static void prt_write_real(val, prec)
+double val;
+int prec;
+{
+ int integer;
+ int fraction;
+
+ prt_real_bits(val, prec, &integer, &fraction);
+ /* Emit integer part */
+ sprintf((char *)prt_line_buffer, "%d", integer);
+ prt_write_file(prt_line_buffer);
+ /* Only emit fraction if necessary */
+ if (fraction != 0) {
+ /* Remove any trailing zeros */
+ while ((fraction % 10) == 0) {
+ prec--;
+ fraction /= 10;
+ }
+ /* Emit fraction left padded with zeros */
+ sprintf((char *)prt_line_buffer, ".%0*d", prec, fraction);
+ prt_write_file(prt_line_buffer);
+ }
+ sprintf((char *)prt_line_buffer, " ");
+ prt_write_file(prt_line_buffer);
+}
+
+/*
+ * Write a line to define a numeric variable.
+ */
+static void prt_def_var(name, value, prec)
+char *name;
+double value;
+int prec;
+{
+ vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer),
+ "/%s ", name);
+ prt_write_file(prt_line_buffer);
+ prt_write_real(value, prec);
+ sprintf((char *)prt_line_buffer, "d\n");
+ prt_write_file(prt_line_buffer);
+}
+
+/* Convert size from font space to user space at current font scale */
+#define PRT_PS_FONT_TO_USER(scale, size) ((size) * ((scale)/1000.0))
+
+static void prt_flush_buffer() {
+ if (prt_ps_buffer.ga_len > 0) {
+ /* Any background color must be drawn first */
+ if (prt_do_bgcol && (prt_new_bgcol != PRCOLOR_WHITE)) {
+ int r, g, b;
+
+ if (prt_do_moveto) {
+ prt_write_real(prt_pos_x_moveto, 2);
+ prt_write_real(prt_pos_y_moveto, 2);
+ prt_write_string("m\n");
+ prt_do_moveto = FALSE;
+ }
+
+ /* Size of rect of background color on which text is printed */
+ prt_write_real(prt_text_run, 2);
+ prt_write_real(prt_line_height, 2);
+
+ /* Lastly add the color of the background */
+ r = ((unsigned)prt_new_bgcol & 0xff0000) >> 16;
+ g = ((unsigned)prt_new_bgcol & 0xff00) >> 8;
+ b = prt_new_bgcol & 0xff;
+ prt_write_real(r / 255.0, 3);
+ prt_write_real(g / 255.0, 3);
+ prt_write_real(b / 255.0, 3);
+ prt_write_string("bg\n");
+ }
+ /* Draw underlines before the text as it makes it slightly easier to
+ * find the starting point.
+ */
+ if (prt_do_underline) {
+ if (prt_do_moveto) {
+ prt_write_real(prt_pos_x_moveto, 2);
+ prt_write_real(prt_pos_y_moveto, 2);
+ prt_write_string("m\n");
+ prt_do_moveto = FALSE;
+ }
+
+ /* Underline length of text run */
+ prt_write_real(prt_text_run, 2);
+ prt_write_string("ul\n");
+ }
+ /* Draw the text
+ * Note: we write text out raw - EBCDIC conversion is handled in the
+ * PostScript world via the font encoding vector. */
+ if (prt_out_mbyte)
+ prt_write_string("<");
+ else
+ prt_write_string("(");
+ prt_write_file_raw_len(prt_ps_buffer.ga_data, prt_ps_buffer.ga_len);
+ if (prt_out_mbyte)
+ prt_write_string(">");
+ else
+ prt_write_string(")");
+ /* Add a moveto if need be and use the appropriate show procedure */
+ if (prt_do_moveto) {
+ prt_write_real(prt_pos_x_moveto, 2);
+ prt_write_real(prt_pos_y_moveto, 2);
+ /* moveto and a show */
+ prt_write_string("ms\n");
+ prt_do_moveto = FALSE;
+ } else /* Simple show */
+ prt_write_string("s\n");
+
+ ga_clear(&prt_ps_buffer);
+ ga_init2(&prt_ps_buffer, (int)sizeof(char), prt_bufsiz);
+ }
+}
+
+static void prt_resource_name(filename, cookie)
+char_u *filename;
+void *cookie;
+{
+ char_u *resource_filename = cookie;
+
+ if (STRLEN(filename) >= MAXPATHL)
+ *resource_filename = NUL;
+ else
+ STRCPY(resource_filename, filename);
+}
+
+static int prt_find_resource(name, resource)
+char *name;
+struct prt_ps_resource_S *resource;
+{
+ char_u *buffer;
+ int retval;
+
+ buffer = alloc(MAXPATHL + 1);
+ if (buffer == NULL)
+ return FALSE;
+
+ vim_strncpy(resource->name, (char_u *)name, 63);
+ /* Look for named resource file in runtimepath */
+ STRCPY(buffer, "print");
+ add_pathsep(buffer);
+ vim_strcat(buffer, (char_u *)name, MAXPATHL);
+ vim_strcat(buffer, (char_u *)".ps", MAXPATHL);
+ resource->filename[0] = NUL;
+ retval = (do_in_runtimepath(buffer, FALSE, prt_resource_name,
+ resource->filename)
+ && resource->filename[0] != NUL);
+ vim_free(buffer);
+ return retval;
+}
+
+/* PS CR and LF characters have platform independent values */
+#define PSLF (0x0a)
+#define PSCR (0x0d)
+
+/* Static buffer to read initial comments in a resource file, some can have a
+ * couple of KB of comments! */
+#define PRT_FILE_BUFFER_LEN (2048)
+struct prt_resfile_buffer_S {
+ char_u buffer[PRT_FILE_BUFFER_LEN];
+ int len;
+ int line_start;
+ int line_end;
+};
+
+static struct prt_resfile_buffer_S prt_resfile;
+
+static int prt_resfile_next_line() {
+ int idx;
+
+ /* Move to start of next line and then find end of line */
+ idx = prt_resfile.line_end + 1;
+ while (idx < prt_resfile.len) {
+ if (prt_resfile.buffer[idx] != PSLF && prt_resfile.buffer[idx] != PSCR)
+ break;
+ idx++;
+ }
+ prt_resfile.line_start = idx;
+
+ while (idx < prt_resfile.len) {
+ if (prt_resfile.buffer[idx] == PSLF || prt_resfile.buffer[idx] == PSCR)
+ break;
+ idx++;
+ }
+ prt_resfile.line_end = idx;
+
+ return idx < prt_resfile.len;
+}
+
+static int prt_resfile_strncmp(offset, string, len)
+int offset;
+char *string;
+int len;
+{
+ /* Force not equal if string is longer than remainder of line */
+ if (len > (prt_resfile.line_end - (prt_resfile.line_start + offset)))
+ return 1;
+
+ return STRNCMP(&prt_resfile.buffer[prt_resfile.line_start + offset],
+ string, len);
+}
+
+static int prt_resfile_skip_nonws(offset)
+int offset;
+{
+ int idx;
+
+ idx = prt_resfile.line_start + offset;
+ while (idx < prt_resfile.line_end) {
+ if (isspace(prt_resfile.buffer[idx]))
+ return idx - prt_resfile.line_start;
+ idx++;
+ }
+ return -1;
+}
+
+static int prt_resfile_skip_ws(offset)
+int offset;
+{
+ int idx;
+
+ idx = prt_resfile.line_start + offset;
+ while (idx < prt_resfile.line_end) {
+ if (!isspace(prt_resfile.buffer[idx]))
+ return idx - prt_resfile.line_start;
+ idx++;
+ }
+ return -1;
+}
+
+/* prt_next_dsc() - returns detail on next DSC comment line found. Returns true
+ * if a DSC comment is found, else false */
+static int prt_next_dsc(p_dsc_line)
+struct prt_dsc_line_S *p_dsc_line;
+{
+ int comment;
+ int offset;
+
+ /* Move to start of next line */
+ if (!prt_resfile_next_line())
+ return FALSE;
+
+ /* DSC comments always start %% */
+ if (prt_resfile_strncmp(0, "%%", 2) != 0)
+ return FALSE;
+
+ /* Find type of DSC comment */
+ for (comment = 0; comment < (int)NUM_ELEMENTS(prt_dsc_table); comment++)
+ if (prt_resfile_strncmp(0, prt_dsc_table[comment].string,
+ prt_dsc_table[comment].len) == 0)
+ break;
+
+ if (comment != NUM_ELEMENTS(prt_dsc_table)) {
+ /* Return type of comment */
+ p_dsc_line->type = prt_dsc_table[comment].type;
+ offset = prt_dsc_table[comment].len;
+ } else {
+ /* Unrecognised DSC comment, skip to ws after comment leader */
+ p_dsc_line->type = PRT_DSC_MISC_TYPE;
+ offset = prt_resfile_skip_nonws(0);
+ if (offset == -1)
+ return FALSE;
+ }
+
+ /* Skip ws to comment value */
+ offset = prt_resfile_skip_ws(offset);
+ if (offset == -1)
+ return FALSE;
+
+ p_dsc_line->string = &prt_resfile.buffer[prt_resfile.line_start + offset];
+ p_dsc_line->len = prt_resfile.line_end - (prt_resfile.line_start + offset);
+
+ return TRUE;
+}
+
+/* Improved hand crafted parser to get the type, title, and version number of a
+ * PS resource file so the file details can be added to the DSC header comments.
+ */
+static int prt_open_resource(resource)
+struct prt_ps_resource_S *resource;
+{
+ int offset;
+ int seen_all;
+ int seen_title;
+ int seen_version;
+ FILE *fd_resource;
+ struct prt_dsc_line_S dsc_line;
+
+ fd_resource = mch_fopen((char *)resource->filename, READBIN);
+ if (fd_resource == NULL) {
+ EMSG2(_("E624: Can't open file \"%s\""), resource->filename);
+ return FALSE;
+ }
+ vim_memset(prt_resfile.buffer, NUL, PRT_FILE_BUFFER_LEN);
+
+ /* Parse first line to ensure valid resource file */
+ prt_resfile.len = (int)fread((char *)prt_resfile.buffer, sizeof(char_u),
+ PRT_FILE_BUFFER_LEN, fd_resource);
+ if (ferror(fd_resource)) {
+ EMSG2(_("E457: Can't read PostScript resource file \"%s\""),
+ resource->filename);
+ fclose(fd_resource);
+ return FALSE;
+ }
+ fclose(fd_resource);
+
+ prt_resfile.line_end = -1;
+ prt_resfile.line_start = 0;
+ if (!prt_resfile_next_line())
+ return FALSE;
+
+ offset = 0;
+
+ if (prt_resfile_strncmp(offset, PRT_RESOURCE_HEADER,
+ (int)STRLEN(PRT_RESOURCE_HEADER)) != 0) {
+ EMSG2(_("E618: file \"%s\" is not a PostScript resource file"),
+ resource->filename);
+ return FALSE;
+ }
+
+ /* Skip over any version numbers and following ws */
+ offset += (int)STRLEN(PRT_RESOURCE_HEADER);
+ offset = prt_resfile_skip_nonws(offset);
+ if (offset == -1)
+ return FALSE;
+ offset = prt_resfile_skip_ws(offset);
+ if (offset == -1)
+ return FALSE;
+
+ if (prt_resfile_strncmp(offset, PRT_RESOURCE_RESOURCE,
+ (int)STRLEN(PRT_RESOURCE_RESOURCE)) != 0) {
+ EMSG2(_("E619: file \"%s\" is not a supported PostScript resource file"),
+ resource->filename);
+ return FALSE;
+ }
+ offset += (int)STRLEN(PRT_RESOURCE_RESOURCE);
+
+ /* Decide type of resource in the file */
+ if (prt_resfile_strncmp(offset, PRT_RESOURCE_PROCSET,
+ (int)STRLEN(PRT_RESOURCE_PROCSET)) == 0)
+ resource->type = PRT_RESOURCE_TYPE_PROCSET;
+ else if (prt_resfile_strncmp(offset, PRT_RESOURCE_ENCODING,
+ (int)STRLEN(PRT_RESOURCE_ENCODING)) == 0)
+ resource->type = PRT_RESOURCE_TYPE_ENCODING;
+ else if (prt_resfile_strncmp(offset, PRT_RESOURCE_CMAP,
+ (int)STRLEN(PRT_RESOURCE_CMAP)) == 0)
+ resource->type = PRT_RESOURCE_TYPE_CMAP;
+ else {
+ EMSG2(_("E619: file \"%s\" is not a supported PostScript resource file"),
+ resource->filename);
+ return FALSE;
+ }
+
+ /* Look for title and version of resource */
+ resource->title[0] = '\0';
+ resource->version[0] = '\0';
+ seen_title = FALSE;
+ seen_version = FALSE;
+ seen_all = FALSE;
+ while (!seen_all && prt_next_dsc(&dsc_line)) {
+ switch (dsc_line.type) {
+ case PRT_DSC_TITLE_TYPE:
+ vim_strncpy(resource->title, dsc_line.string, dsc_line.len);
+ seen_title = TRUE;
+ if (seen_version)
+ seen_all = TRUE;
+ break;
+
+ case PRT_DSC_VERSION_TYPE:
+ vim_strncpy(resource->version, dsc_line.string, dsc_line.len);
+ seen_version = TRUE;
+ if (seen_title)
+ seen_all = TRUE;
+ break;
+
+ case PRT_DSC_ENDCOMMENTS_TYPE:
+ /* Wont find title or resource after this comment, stop searching */
+ seen_all = TRUE;
+ break;
+
+ case PRT_DSC_MISC_TYPE:
+ /* Not interested in whatever comment this line had */
+ break;
+ }
+ }
+
+ if (!seen_title || !seen_version) {
+ EMSG2(_("E619: file \"%s\" is not a supported PostScript resource file"),
+ resource->filename);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static int prt_check_resource(resource, version)
+struct prt_ps_resource_S *resource;
+char_u *version;
+{
+ /* Version number m.n should match, the revision number does not matter */
+ if (STRNCMP(resource->version, version, STRLEN(version))) {
+ EMSG2(_("E621: \"%s\" resource file has wrong version"),
+ resource->name);
+ return FALSE;
+ }
+
+ /* Other checks to be added as needed */
+ return TRUE;
+}
+
+static void prt_dsc_start() {
+ prt_write_string("%!PS-Adobe-3.0\n");
+}
+
+static void prt_dsc_noarg(comment)
+char *comment;
+{
+ vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer),
+ "%%%%%s\n", comment);
+ prt_write_file(prt_line_buffer);
+}
+
+static void prt_dsc_textline(comment, text)
+char *comment;
+char *text;
+{
+ vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer),
+ "%%%%%s: %s\n", comment, text);
+ prt_write_file(prt_line_buffer);
+}
+
+static void prt_dsc_text(comment, text)
+char *comment;
+char *text;
+{
+ /* TODO - should scan 'text' for any chars needing escaping! */
+ vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer),
+ "%%%%%s: (%s)\n", comment, text);
+ prt_write_file(prt_line_buffer);
+}
+
+#define prt_dsc_atend(c) prt_dsc_text((c), "atend")
+
+static void prt_dsc_ints(comment, count, ints)
+char *comment;
+int count;
+int *ints;
+{
+ int i;
+
+ vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer),
+ "%%%%%s:", comment);
+ prt_write_file(prt_line_buffer);
+
+ for (i = 0; i < count; i++) {
+ sprintf((char *)prt_line_buffer, " %d", ints[i]);
+ prt_write_file(prt_line_buffer);
+ }
+
+ prt_write_string("\n");
+}
+
+static void prt_dsc_resources(comment, type, string)
+char *comment; /* if NULL add to previous */
+char *type;
+char *string;
+{
+ if (comment != NULL)
+ vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer),
+ "%%%%%s: %s", comment, type);
+ else
+ vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer),
+ "%%%%+ %s", type);
+ prt_write_file(prt_line_buffer);
+
+ vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer),
+ " %s\n", string);
+ prt_write_file(prt_line_buffer);
+}
+
+static void prt_dsc_font_resource(resource, ps_font)
+char *resource;
+struct prt_ps_font_S *ps_font;
+{
+ int i;
+
+ prt_dsc_resources(resource, "font",
+ ps_font->ps_fontname[PRT_PS_FONT_ROMAN]);
+ for (i = PRT_PS_FONT_BOLD; i <= PRT_PS_FONT_BOLDOBLIQUE; i++)
+ if (ps_font->ps_fontname[i] != NULL)
+ prt_dsc_resources(NULL, "font", ps_font->ps_fontname[i]);
+}
+
+static void prt_dsc_requirements(duplex, tumble, collate, color, num_copies)
+int duplex;
+int tumble;
+int collate;
+int color;
+int num_copies;
+{
+ /* Only output the comment if we need to.
+ * Note: tumble is ignored if we are not duplexing
+ */
+ if (!(duplex || collate || color || (num_copies > 1)))
+ return;
+
+ sprintf((char *)prt_line_buffer, "%%%%Requirements:");
+ prt_write_file(prt_line_buffer);
+
+ if (duplex) {
+ prt_write_string(" duplex");
+ if (tumble)
+ prt_write_string("(tumble)");
+ }
+ if (collate)
+ prt_write_string(" collate");
+ if (color)
+ prt_write_string(" color");
+ if (num_copies > 1) {
+ prt_write_string(" numcopies(");
+ /* Note: no space wanted so don't use prt_write_int() */
+ sprintf((char *)prt_line_buffer, "%d", num_copies);
+ prt_write_file(prt_line_buffer);
+ prt_write_string(")");
+ }
+ prt_write_string("\n");
+}
+
+static void prt_dsc_docmedia(paper_name, width, height, weight, colour, type)
+char *paper_name;
+double width;
+double height;
+double weight;
+char *colour;
+char *type;
+{
+ vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer),
+ "%%%%DocumentMedia: %s ", paper_name);
+ prt_write_file(prt_line_buffer);
+ prt_write_real(width, 2);
+ prt_write_real(height, 2);
+ prt_write_real(weight, 2);
+ if (colour == NULL)
+ prt_write_string("()");
+ else
+ prt_write_string(colour);
+ prt_write_string(" ");
+ if (type == NULL)
+ prt_write_string("()");
+ else
+ prt_write_string(type);
+ prt_write_string("\n");
+}
+
+void mch_print_cleanup() {
+ if (prt_out_mbyte) {
+ int i;
+
+ /* Free off all CID font names created, but first clear duplicate
+ * pointers to the same string (when the same font is used for more than
+ * one style).
+ */
+ for (i = PRT_PS_FONT_ROMAN; i <= PRT_PS_FONT_BOLDOBLIQUE; i++) {
+ if (prt_ps_mb_font.ps_fontname[i] != NULL)
+ vim_free(prt_ps_mb_font.ps_fontname[i]);
+ prt_ps_mb_font.ps_fontname[i] = NULL;
+ }
+ }
+
+ if (prt_do_conv) {
+ convert_setup(&prt_conv, NULL, NULL);
+ prt_do_conv = FALSE;
+ }
+ if (prt_ps_fd != NULL) {
+ fclose(prt_ps_fd);
+ prt_ps_fd = NULL;
+ prt_file_error = FALSE;
+ }
+ if (prt_ps_file_name != NULL) {
+ vim_free(prt_ps_file_name);
+ prt_ps_file_name = NULL;
+ }
+}
+
+static float to_device_units(idx, physsize, def_number)
+int idx;
+double physsize;
+int def_number;
+{
+ float ret;
+ int u;
+ int nr;
+
+ u = prt_get_unit(idx);
+ if (u == PRT_UNIT_NONE) {
+ u = PRT_UNIT_PERC;
+ nr = def_number;
+ } else
+ nr = printer_opts[idx].number;
+
+ switch (u) {
+ case PRT_UNIT_INCH:
+ ret = (float)(nr * PRT_PS_DEFAULT_DPI);
+ break;
+ case PRT_UNIT_MM:
+ ret = (float)(nr * PRT_PS_DEFAULT_DPI) / (float)25.4;
+ break;
+ case PRT_UNIT_POINT:
+ ret = (float)nr;
+ break;
+ case PRT_UNIT_PERC:
+ default:
+ ret = (float)(physsize * nr) / 100;
+ break;
+ }
+
+ return ret;
+}
+
+/*
+ * Calculate margins for given width and height from printoptions settings.
+ */
+static void prt_page_margins(width, height, left, right, top, bottom)
+double width;
+double height;
+double *left;
+double *right;
+double *top;
+double *bottom;
+{
+ *left = to_device_units(OPT_PRINT_LEFT, width, 10);
+ *right = width - to_device_units(OPT_PRINT_RIGHT, width, 5);
+ *top = height - to_device_units(OPT_PRINT_TOP, height, 5);
+ *bottom = to_device_units(OPT_PRINT_BOT, height, 5);
+}
+
+static void prt_font_metrics(font_scale)
+int font_scale;
+{
+ prt_line_height = (float)font_scale;
+ prt_char_width = (float)PRT_PS_FONT_TO_USER(font_scale, prt_ps_font->wx);
+}
+
+
+static int prt_get_cpl() {
+ if (prt_use_number()) {
+ prt_number_width = PRINT_NUMBER_WIDTH * prt_char_width;
+ /* If we are outputting multi-byte characters then line numbers will be
+ * printed with half width characters
+ */
+ if (prt_out_mbyte)
+ prt_number_width /= 2;
+ prt_left_margin += prt_number_width;
+ } else
+ prt_number_width = 0.0;
+
+ return (int)((prt_right_margin - prt_left_margin) / prt_char_width);
+}
+
+static int prt_build_cid_fontname(font, name, name_len)
+int font;
+char_u *name;
+int name_len;
+{
+ char *fontname;
+
+ fontname = (char *)alloc(name_len + 1);
+ if (fontname == NULL)
+ return FALSE;
+ vim_strncpy((char_u *)fontname, name, name_len);
+ prt_ps_mb_font.ps_fontname[font] = fontname;
+
+ return TRUE;
+}
+
+/*
+ * Get number of lines of text that fit on a page (excluding the header).
+ */
+static int prt_get_lpp() {
+ int lpp;
+
+ /*
+ * Calculate offset to lower left corner of background rect based on actual
+ * font height (based on its bounding box) and the line height, handling the
+ * case where the font height can exceed the line height.
+ */
+ prt_bgcol_offset = (float)PRT_PS_FONT_TO_USER(prt_line_height,
+ prt_ps_font->bbox_min_y);
+ if ((prt_ps_font->bbox_max_y - prt_ps_font->bbox_min_y) < 1000.0) {
+ prt_bgcol_offset -= (float)PRT_PS_FONT_TO_USER(prt_line_height,
+ (1000.0 - (prt_ps_font->bbox_max_y -
+ prt_ps_font->bbox_min_y)) / 2);
+ }
+
+ /* Get height for topmost line based on background rect offset. */
+ prt_first_line_height = prt_line_height + prt_bgcol_offset;
+
+ /* Calculate lpp */
+ lpp = (int)((prt_top_margin - prt_bottom_margin) / prt_line_height);
+
+ /* Adjust top margin if there is a header */
+ prt_top_margin -= prt_line_height * prt_header_height();
+
+ return lpp - prt_header_height();
+}
+
+static int prt_match_encoding(p_encoding, p_cmap, pp_mbenc)
+char *p_encoding;
+struct prt_ps_mbfont_S *p_cmap;
+struct prt_ps_encoding_S **pp_mbenc;
+{
+ int mbenc;
+ int enc_len;
+ struct prt_ps_encoding_S *p_mbenc;
+
+ *pp_mbenc = NULL;
+ /* Look for recognised encoding */
+ enc_len = (int)STRLEN(p_encoding);
+ p_mbenc = p_cmap->encodings;
+ for (mbenc = 0; mbenc < p_cmap->num_encodings; mbenc++) {
+ if (STRNICMP(p_mbenc->encoding, p_encoding, enc_len) == 0) {
+ *pp_mbenc = p_mbenc;
+ return TRUE;
+ }
+ p_mbenc++;
+ }
+ return FALSE;
+}
+
+static int prt_match_charset(p_charset, p_cmap, pp_mbchar)
+char *p_charset;
+struct prt_ps_mbfont_S *p_cmap;
+struct prt_ps_charset_S **pp_mbchar;
+{
+ int mbchar;
+ int char_len;
+ struct prt_ps_charset_S *p_mbchar;
+
+ /* Look for recognised character set, using default if one is not given */
+ if (*p_charset == NUL)
+ p_charset = p_cmap->defcs;
+ char_len = (int)STRLEN(p_charset);
+ p_mbchar = p_cmap->charsets;
+ for (mbchar = 0; mbchar < p_cmap->num_charsets; mbchar++) {
+ if (STRNICMP(p_mbchar->charset, p_charset, char_len) == 0) {
+ *pp_mbchar = p_mbchar;
+ return TRUE;
+ }
+ p_mbchar++;
+ }
+ return FALSE;
+}
+
+int mch_print_init(psettings, jobname, forceit)
+prt_settings_T *psettings;
+char_u *jobname;
+int forceit UNUSED;
+{
+ int i;
+ char *paper_name;
+ int paper_strlen;
+ int fontsize;
+ char_u *p;
+ double left;
+ double right;
+ double top;
+ double bottom;
+ int props;
+ int cmap = 0;
+ char_u *p_encoding;
+ struct prt_ps_encoding_S *p_mbenc;
+ struct prt_ps_encoding_S *p_mbenc_first;
+ struct prt_ps_charset_S *p_mbchar = NULL;
+
+
+ /*
+ * Set up font and encoding.
+ */
+ p_encoding = enc_skip(p_penc);
+ if (*p_encoding == NUL)
+ p_encoding = enc_skip(p_enc);
+
+ /* Look for a multi-byte font that matches the encoding and character set.
+ * Only look if multi-byte character set is defined, or using multi-byte
+ * encoding other than Unicode. This is because a Unicode encoding does not
+ * uniquely identify a CJK character set to use. */
+ p_mbenc = NULL;
+ props = enc_canon_props(p_encoding);
+ if (!(props & ENC_8BIT) && ((*p_pmcs != NUL) || !(props & ENC_UNICODE))) {
+ p_mbenc_first = NULL;
+ for (cmap = 0; cmap < (int)NUM_ELEMENTS(prt_ps_mbfonts); cmap++)
+ if (prt_match_encoding((char *)p_encoding, &prt_ps_mbfonts[cmap],
+ &p_mbenc)) {
+ if (p_mbenc_first == NULL)
+ p_mbenc_first = p_mbenc;
+ if (prt_match_charset((char *)p_pmcs, &prt_ps_mbfonts[cmap],
+ &p_mbchar))
+ break;
+ }
+
+ /* Use first encoding matched if no charset matched */
+ if (p_mbchar == NULL && p_mbenc_first != NULL)
+ p_mbenc = p_mbenc_first;
+ }
+
+ prt_out_mbyte = (p_mbenc != NULL);
+ if (prt_out_mbyte) {
+ /* Build CMap name - will be same for all multi-byte fonts used */
+ prt_cmap[0] = NUL;
+
+ prt_custom_cmap = (p_mbchar == NULL);
+ if (!prt_custom_cmap) {
+ /* Check encoding and character set are compatible */
+ if ((p_mbenc->needs_charset & p_mbchar->has_charset) == 0) {
+ EMSG(_("E673: Incompatible multi-byte encoding and character set."));
+ return FALSE;
+ }
+
+ /* Add charset name if not empty */
+ if (p_mbchar->cmap_charset != NULL) {
+ vim_strncpy((char_u *)prt_cmap,
+ (char_u *)p_mbchar->cmap_charset, sizeof(prt_cmap) - 3);
+ STRCAT(prt_cmap, "-");
+ }
+ } else {
+ /* Add custom CMap character set name */
+ if (*p_pmcs == NUL) {
+ EMSG(_("E674: printmbcharset cannot be empty with multi-byte encoding."));
+ return FALSE;
+ }
+ vim_strncpy((char_u *)prt_cmap, p_pmcs, sizeof(prt_cmap) - 3);
+ STRCAT(prt_cmap, "-");
+ }
+
+ /* CMap name ends with (optional) encoding name and -H for horizontal */
+ if (p_mbenc->cmap_encoding != NULL && STRLEN(prt_cmap)
+ + STRLEN(p_mbenc->cmap_encoding) + 3 < sizeof(prt_cmap)) {
+ STRCAT(prt_cmap, p_mbenc->cmap_encoding);
+ STRCAT(prt_cmap, "-");
+ }
+ STRCAT(prt_cmap, "H");
+
+ if (!mbfont_opts[OPT_MBFONT_REGULAR].present) {
+ EMSG(_("E675: No default font specified for multi-byte printing."));
+ return FALSE;
+ }
+
+ /* Derive CID font names with fallbacks if not defined */
+ if (!prt_build_cid_fontname(PRT_PS_FONT_ROMAN,
+ mbfont_opts[OPT_MBFONT_REGULAR].string,
+ mbfont_opts[OPT_MBFONT_REGULAR].strlen))
+ return FALSE;
+ if (mbfont_opts[OPT_MBFONT_BOLD].present)
+ if (!prt_build_cid_fontname(PRT_PS_FONT_BOLD,
+ mbfont_opts[OPT_MBFONT_BOLD].string,
+ mbfont_opts[OPT_MBFONT_BOLD].strlen))
+ return FALSE;
+ if (mbfont_opts[OPT_MBFONT_OBLIQUE].present)
+ if (!prt_build_cid_fontname(PRT_PS_FONT_OBLIQUE,
+ mbfont_opts[OPT_MBFONT_OBLIQUE].string,
+ mbfont_opts[OPT_MBFONT_OBLIQUE].strlen))
+ return FALSE;
+ if (mbfont_opts[OPT_MBFONT_BOLDOBLIQUE].present)
+ if (!prt_build_cid_fontname(PRT_PS_FONT_BOLDOBLIQUE,
+ mbfont_opts[OPT_MBFONT_BOLDOBLIQUE].string,
+ mbfont_opts[OPT_MBFONT_BOLDOBLIQUE].strlen))
+ return FALSE;
+
+ /* Check if need to use Courier for ASCII code range, and if so pick up
+ * the encoding to use */
+ prt_use_courier = mbfont_opts[OPT_MBFONT_USECOURIER].present &&
+ (TOLOWER_ASC(mbfont_opts[OPT_MBFONT_USECOURIER].string[0])
+ == 'y');
+ if (prt_use_courier) {
+ /* Use national ASCII variant unless ASCII wanted */
+ if (mbfont_opts[OPT_MBFONT_ASCII].present &&
+ (TOLOWER_ASC(mbfont_opts[OPT_MBFONT_ASCII].string[0]) == 'y'))
+ prt_ascii_encoding = "ascii";
+ else
+ prt_ascii_encoding = prt_ps_mbfonts[cmap].ascii_enc;
+ }
+
+ prt_ps_font = &prt_ps_mb_font;
+ } else {
+ prt_use_courier = FALSE;
+ prt_ps_font = &prt_ps_courier_font;
+ }
+
+ /*
+ * Find the size of the paper and set the margins.
+ */
+ prt_portrait = (!printer_opts[OPT_PRINT_PORTRAIT].present
+ || TOLOWER_ASC(printer_opts[OPT_PRINT_PORTRAIT].string[0]) ==
+ 'y');
+ if (printer_opts[OPT_PRINT_PAPER].present) {
+ paper_name = (char *)printer_opts[OPT_PRINT_PAPER].string;
+ paper_strlen = printer_opts[OPT_PRINT_PAPER].strlen;
+ } else {
+ paper_name = "A4";
+ paper_strlen = 2;
+ }
+ for (i = 0; i < (int)PRT_MEDIASIZE_LEN; ++i)
+ if (STRLEN(prt_mediasize[i].name) == (unsigned)paper_strlen
+ && STRNICMP(prt_mediasize[i].name, paper_name,
+ paper_strlen) == 0)
+ break;
+ if (i == PRT_MEDIASIZE_LEN)
+ i = 0;
+ prt_media = i;
+
+ /*
+ * Set PS pagesize based on media dimensions and print orientation.
+ * Note: Media and page sizes have defined meanings in PostScript and should
+ * be kept distinct. Media is the paper (or transparency, or ...) that is
+ * printed on, whereas the page size is the area that the PostScript
+ * interpreter renders into.
+ */
+ if (prt_portrait) {
+ prt_page_width = prt_mediasize[i].width;
+ prt_page_height = prt_mediasize[i].height;
+ } else {
+ prt_page_width = prt_mediasize[i].height;
+ prt_page_height = prt_mediasize[i].width;
+ }
+
+ /*
+ * Set PS page margins based on the PS pagesize, not the mediasize - this
+ * needs to be done before the cpl and lpp are calculated.
+ */
+ prt_page_margins(prt_page_width, prt_page_height, &left, &right, &top,
+ &bottom);
+ prt_left_margin = (float)left;
+ prt_right_margin = (float)right;
+ prt_top_margin = (float)top;
+ prt_bottom_margin = (float)bottom;
+
+ /*
+ * Set up the font size.
+ */
+ fontsize = PRT_PS_DEFAULT_FONTSIZE;
+ for (p = p_pfn; (p = vim_strchr(p, ':')) != NULL; ++p)
+ if (p[1] == 'h' && VIM_ISDIGIT(p[2]))
+ fontsize = atoi((char *)p + 2);
+ prt_font_metrics(fontsize);
+
+ /*
+ * Return the number of characters per line, and lines per page for the
+ * generic print code.
+ */
+ psettings->chars_per_line = prt_get_cpl();
+ psettings->lines_per_page = prt_get_lpp();
+
+ /* Catch margin settings that leave no space for output! */
+ if (psettings->chars_per_line <= 0 || psettings->lines_per_page <= 0)
+ return FAIL;
+
+ /*
+ * Sort out the number of copies to be printed. PS by default will do
+ * uncollated copies for you, so once we know how many uncollated copies are
+ * wanted cache it away and lie to the generic code that we only want one
+ * uncollated copy.
+ */
+ psettings->n_collated_copies = 1;
+ psettings->n_uncollated_copies = 1;
+ prt_num_copies = 1;
+ prt_collate = (!printer_opts[OPT_PRINT_COLLATE].present
+ || TOLOWER_ASC(printer_opts[OPT_PRINT_COLLATE].string[0]) ==
+ 'y');
+ if (prt_collate) {
+ /* TODO: Get number of collated copies wanted. */
+ psettings->n_collated_copies = 1;
+ } else {
+ /* TODO: Get number of uncollated copies wanted and update the cached
+ * count.
+ */
+ prt_num_copies = 1;
+ }
+
+ psettings->jobname = jobname;
+
+ /*
+ * Set up printer duplex and tumble based on Duplex option setting - default
+ * is long sided duplex printing (i.e. no tumble).
+ */
+ prt_duplex = TRUE;
+ prt_tumble = FALSE;
+ psettings->duplex = 1;
+ if (printer_opts[OPT_PRINT_DUPLEX].present) {
+ if (STRNICMP(printer_opts[OPT_PRINT_DUPLEX].string, "off", 3) == 0) {
+ prt_duplex = FALSE;
+ psettings->duplex = 0;
+ } else if (STRNICMP(printer_opts[OPT_PRINT_DUPLEX].string, "short", 5)
+ == 0)
+ prt_tumble = TRUE;
+ }
+
+ /* For now user abort not supported */
+ psettings->user_abort = 0;
+
+ /* If the user didn't specify a file name, use a temp file. */
+ if (psettings->outfile == NULL) {
+ prt_ps_file_name = vim_tempname('p');
+ if (prt_ps_file_name == NULL) {
+ EMSG(_(e_notmp));
+ return FAIL;
+ }
+ prt_ps_fd = mch_fopen((char *)prt_ps_file_name, WRITEBIN);
+ } else {
+ p = expand_env_save(psettings->outfile);
+ if (p != NULL) {
+ prt_ps_fd = mch_fopen((char *)p, WRITEBIN);
+ vim_free(p);
+ }
+ }
+ if (prt_ps_fd == NULL) {
+ EMSG(_("E324: Can't open PostScript output file"));
+ mch_print_cleanup();
+ return FAIL;
+ }
+
+ prt_bufsiz = psettings->chars_per_line;
+ if (prt_out_mbyte)
+ prt_bufsiz *= 2;
+ ga_init2(&prt_ps_buffer, (int)sizeof(char), prt_bufsiz);
+
+ prt_page_num = 0;
+
+ prt_attribute_change = FALSE;
+ prt_need_moveto = FALSE;
+ prt_need_font = FALSE;
+ prt_need_fgcol = FALSE;
+ prt_need_bgcol = FALSE;
+ prt_need_underline = FALSE;
+
+ prt_file_error = FALSE;
+
+ return OK;
+}
+
+static int prt_add_resource(resource)
+struct prt_ps_resource_S *resource;
+{
+ FILE* fd_resource;
+ char_u resource_buffer[512];
+ size_t bytes_read;
+
+ fd_resource = mch_fopen((char *)resource->filename, READBIN);
+ if (fd_resource == NULL) {
+ EMSG2(_("E456: Can't open file \"%s\""), resource->filename);
+ return FALSE;
+ }
+ prt_dsc_resources("BeginResource", prt_resource_types[resource->type],
+ (char *)resource->title);
+
+ prt_dsc_textline("BeginDocument", (char *)resource->filename);
+
+ for (;; ) {
+ bytes_read = fread((char *)resource_buffer, sizeof(char_u),
+ sizeof(resource_buffer), fd_resource);
+ if (ferror(fd_resource)) {
+ EMSG2(_("E457: Can't read PostScript resource file \"%s\""),
+ resource->filename);
+ fclose(fd_resource);
+ return FALSE;
+ }
+ if (bytes_read == 0)
+ break;
+ prt_write_file_raw_len(resource_buffer, (int)bytes_read);
+ if (prt_file_error) {
+ fclose(fd_resource);
+ return FALSE;
+ }
+ }
+ fclose(fd_resource);
+
+ prt_dsc_noarg("EndDocument");
+
+ prt_dsc_noarg("EndResource");
+
+ return TRUE;
+}
+
+int mch_print_begin(psettings)
+prt_settings_T *psettings;
+{
+ time_t now;
+ int bbox[4];
+ char *p_time;
+ double left;
+ double right;
+ double top;
+ double bottom;
+ struct prt_ps_resource_S *res_prolog;
+ struct prt_ps_resource_S *res_encoding;
+ char buffer[256];
+ char_u *p_encoding;
+ char_u *p;
+ struct prt_ps_resource_S *res_cidfont;
+ struct prt_ps_resource_S *res_cmap;
+ int retval = FALSE;
+
+ res_prolog = (struct prt_ps_resource_S *)
+ alloc(sizeof(struct prt_ps_resource_S));
+ res_encoding = (struct prt_ps_resource_S *)
+ alloc(sizeof(struct prt_ps_resource_S));
+ res_cidfont = (struct prt_ps_resource_S *)
+ alloc(sizeof(struct prt_ps_resource_S));
+ res_cmap = (struct prt_ps_resource_S *)
+ alloc(sizeof(struct prt_ps_resource_S));
+ if (res_prolog == NULL || res_encoding == NULL
+ || res_cidfont == NULL || res_cmap == NULL
+ )
+ goto theend;
+
+ /*
+ * PS DSC Header comments - no PS code!
+ */
+ prt_dsc_start();
+ prt_dsc_textline("Title", (char *)psettings->jobname);
+ if (!get_user_name((char_u *)buffer, 256))
+ STRCPY(buffer, "Unknown");
+ prt_dsc_textline("For", buffer);
+ prt_dsc_textline("Creator", VIM_VERSION_LONG);
+ /* Note: to ensure Clean8bit I don't think we can use LC_TIME */
+ now = time(NULL);
+ p_time = ctime(&now);
+ /* Note: ctime() adds a \n so we have to remove it :-( */
+ p = vim_strchr((char_u *)p_time, '\n');
+ if (p != NULL)
+ *p = NUL;
+ prt_dsc_textline("CreationDate", p_time);
+ prt_dsc_textline("DocumentData", "Clean8Bit");
+ prt_dsc_textline("Orientation", "Portrait");
+ prt_dsc_atend("Pages");
+ prt_dsc_textline("PageOrder", "Ascend");
+ /* The bbox does not change with orientation - it is always in the default
+ * user coordinate system! We have to recalculate right and bottom
+ * coordinates based on the font metrics for the bbox to be accurate. */
+ prt_page_margins(prt_mediasize[prt_media].width,
+ prt_mediasize[prt_media].height,
+ &left, &right, &top, &bottom);
+ bbox[0] = (int)left;
+ if (prt_portrait) {
+ /* In portrait printing the fixed point is the top left corner so we
+ * derive the bbox from that point. We have the expected cpl chars
+ * across the media and lpp lines down the media.
+ */
+ bbox[1] = (int)(top - (psettings->lines_per_page + prt_header_height())
+ * prt_line_height);
+ bbox[2] = (int)(left + psettings->chars_per_line * prt_char_width
+ + 0.5);
+ bbox[3] = (int)(top + 0.5);
+ } else {
+ /* In landscape printing the fixed point is the bottom left corner so we
+ * derive the bbox from that point. We have lpp chars across the media
+ * and cpl lines up the media.
+ */
+ bbox[1] = (int)bottom;
+ bbox[2] = (int)(left + ((psettings->lines_per_page
+ + prt_header_height()) * prt_line_height) + 0.5);
+ bbox[3] = (int)(bottom + psettings->chars_per_line * prt_char_width
+ + 0.5);
+ }
+ prt_dsc_ints("BoundingBox", 4, bbox);
+ /* The media width and height does not change with landscape printing! */
+ prt_dsc_docmedia(prt_mediasize[prt_media].name,
+ prt_mediasize[prt_media].width,
+ prt_mediasize[prt_media].height,
+ (double)0, NULL, NULL);
+ /* Define fonts needed */
+ if (!prt_out_mbyte || prt_use_courier)
+ prt_dsc_font_resource("DocumentNeededResources", &prt_ps_courier_font);
+ if (prt_out_mbyte) {
+ prt_dsc_font_resource((prt_use_courier ? NULL
+ : "DocumentNeededResources"), &prt_ps_mb_font);
+ if (!prt_custom_cmap)
+ prt_dsc_resources(NULL, "cmap", prt_cmap);
+ }
+
+ /* Search for external resources VIM supplies */
+ if (!prt_find_resource("prolog", res_prolog)) {
+ EMSG(_("E456: Can't find PostScript resource file \"prolog.ps\""));
+ return FALSE;
+ }
+ if (!prt_open_resource(res_prolog))
+ return FALSE;
+ if (!prt_check_resource(res_prolog, PRT_PROLOG_VERSION))
+ return FALSE;
+ if (prt_out_mbyte) {
+ /* Look for required version of multi-byte printing procset */
+ if (!prt_find_resource("cidfont", res_cidfont)) {
+ EMSG(_("E456: Can't find PostScript resource file \"cidfont.ps\""));
+ return FALSE;
+ }
+ if (!prt_open_resource(res_cidfont))
+ return FALSE;
+ if (!prt_check_resource(res_cidfont, PRT_CID_PROLOG_VERSION))
+ return FALSE;
+ }
+
+ /* Find an encoding to use for printing.
+ * Check 'printencoding'. If not set or not found, then use 'encoding'. If
+ * that cannot be found then default to "latin1".
+ * Note: VIM specific encoding header is always skipped.
+ */
+ if (!prt_out_mbyte) {
+ p_encoding = enc_skip(p_penc);
+ if (*p_encoding == NUL
+ || !prt_find_resource((char *)p_encoding, res_encoding)) {
+ /* 'printencoding' not set or not supported - find alternate */
+ int props;
+
+ p_encoding = enc_skip(p_enc);
+ props = enc_canon_props(p_encoding);
+ if (!(props & ENC_8BIT)
+ || !prt_find_resource((char *)p_encoding, res_encoding)) {
+ /* 8-bit 'encoding' is not supported */
+ /* Use latin1 as default printing encoding */
+ p_encoding = (char_u *)"latin1";
+ if (!prt_find_resource((char *)p_encoding, res_encoding)) {
+ EMSG2(_("E456: Can't find PostScript resource file \"%s.ps\""),
+ p_encoding);
+ return FALSE;
+ }
+ }
+ }
+ if (!prt_open_resource(res_encoding))
+ return FALSE;
+ /* For the moment there are no checks on encoding resource files to
+ * perform */
+ } else {
+ p_encoding = enc_skip(p_penc);
+ if (*p_encoding == NUL)
+ p_encoding = enc_skip(p_enc);
+ if (prt_use_courier) {
+ /* Include ASCII range encoding vector */
+ if (!prt_find_resource(prt_ascii_encoding, res_encoding)) {
+ EMSG2(_("E456: Can't find PostScript resource file \"%s.ps\""),
+ prt_ascii_encoding);
+ return FALSE;
+ }
+ if (!prt_open_resource(res_encoding))
+ return FALSE;
+ /* For the moment there are no checks on encoding resource files to
+ * perform */
+ }
+ }
+
+ 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;
+ }
+ prt_do_conv = TRUE;
+ }
+ prt_do_conv = prt_conv.vc_type != CONV_NONE;
+
+ if (prt_out_mbyte && prt_custom_cmap) {
+ /* Find user supplied CMap */
+ if (!prt_find_resource(prt_cmap, res_cmap)) {
+ EMSG2(_("E456: Can't find PostScript resource file \"%s.ps\""),
+ prt_cmap);
+ return FALSE;
+ }
+ if (!prt_open_resource(res_cmap))
+ return FALSE;
+ }
+
+ /* List resources supplied */
+ STRCPY(buffer, res_prolog->title);
+ STRCAT(buffer, " ");
+ STRCAT(buffer, res_prolog->version);
+ prt_dsc_resources("DocumentSuppliedResources", "procset", buffer);
+ if (prt_out_mbyte) {
+ STRCPY(buffer, res_cidfont->title);
+ STRCAT(buffer, " ");
+ STRCAT(buffer, res_cidfont->version);
+ prt_dsc_resources(NULL, "procset", buffer);
+
+ if (prt_custom_cmap) {
+ STRCPY(buffer, res_cmap->title);
+ STRCAT(buffer, " ");
+ STRCAT(buffer, res_cmap->version);
+ prt_dsc_resources(NULL, "cmap", buffer);
+ }
+ }
+ if (!prt_out_mbyte || prt_use_courier) {
+ STRCPY(buffer, res_encoding->title);
+ STRCAT(buffer, " ");
+ STRCAT(buffer, res_encoding->version);
+ prt_dsc_resources(NULL, "encoding", buffer);
+ }
+ prt_dsc_requirements(prt_duplex, prt_tumble, prt_collate,
+ psettings->do_syntax
+ , prt_num_copies);
+ prt_dsc_noarg("EndComments");
+
+ /*
+ * PS Document page defaults
+ */
+ prt_dsc_noarg("BeginDefaults");
+
+ /* List font resources most likely common to all pages */
+ if (!prt_out_mbyte || prt_use_courier)
+ prt_dsc_font_resource("PageResources", &prt_ps_courier_font);
+ if (prt_out_mbyte) {
+ prt_dsc_font_resource((prt_use_courier ? NULL : "PageResources"),
+ &prt_ps_mb_font);
+ if (!prt_custom_cmap)
+ prt_dsc_resources(NULL, "cmap", prt_cmap);
+ }
+
+ /* Paper will be used for all pages */
+ prt_dsc_textline("PageMedia", prt_mediasize[prt_media].name);
+
+ prt_dsc_noarg("EndDefaults");
+
+ /*
+ * PS Document prolog inclusion - all required procsets.
+ */
+ prt_dsc_noarg("BeginProlog");
+
+ /* Add required procsets - NOTE: order is important! */
+ if (!prt_add_resource(res_prolog))
+ return FALSE;
+ if (prt_out_mbyte) {
+ /* Add CID font procset, and any user supplied CMap */
+ if (!prt_add_resource(res_cidfont))
+ return FALSE;
+ if (prt_custom_cmap && !prt_add_resource(res_cmap))
+ return FALSE;
+ }
+
+ if (!prt_out_mbyte || prt_use_courier)
+ /* There will be only one Roman font encoding to be included in the PS
+ * file. */
+ if (!prt_add_resource(res_encoding))
+ return FALSE;
+
+ prt_dsc_noarg("EndProlog");
+
+ /*
+ * PS Document setup - must appear after the prolog
+ */
+ prt_dsc_noarg("BeginSetup");
+
+ /* Device setup - page size and number of uncollated copies */
+ prt_write_int((int)prt_mediasize[prt_media].width);
+ prt_write_int((int)prt_mediasize[prt_media].height);
+ prt_write_int(0);
+ prt_write_string("sps\n");
+ prt_write_int(prt_num_copies);
+ prt_write_string("nc\n");
+ prt_write_boolean(prt_duplex);
+ prt_write_boolean(prt_tumble);
+ prt_write_string("dt\n");
+ prt_write_boolean(prt_collate);
+ prt_write_string("c\n");
+
+ /* Font resource inclusion and definition */
+ if (!prt_out_mbyte || prt_use_courier) {
+ /* When using Courier for ASCII range when printing multi-byte, need to
+ * pick up ASCII encoding to use with it. */
+ if (prt_use_courier)
+ p_encoding = (char_u *)prt_ascii_encoding;
+ prt_dsc_resources("IncludeResource", "font",
+ prt_ps_courier_font.ps_fontname[PRT_PS_FONT_ROMAN]);
+ prt_def_font("F0", (char *)p_encoding, (int)prt_line_height,
+ prt_ps_courier_font.ps_fontname[PRT_PS_FONT_ROMAN]);
+ prt_dsc_resources("IncludeResource", "font",
+ prt_ps_courier_font.ps_fontname[PRT_PS_FONT_BOLD]);
+ prt_def_font("F1", (char *)p_encoding, (int)prt_line_height,
+ prt_ps_courier_font.ps_fontname[PRT_PS_FONT_BOLD]);
+ prt_dsc_resources("IncludeResource", "font",
+ prt_ps_courier_font.ps_fontname[PRT_PS_FONT_OBLIQUE]);
+ prt_def_font("F2", (char *)p_encoding, (int)prt_line_height,
+ prt_ps_courier_font.ps_fontname[PRT_PS_FONT_OBLIQUE]);
+ prt_dsc_resources("IncludeResource", "font",
+ prt_ps_courier_font.ps_fontname[PRT_PS_FONT_BOLDOBLIQUE]);
+ prt_def_font("F3", (char *)p_encoding, (int)prt_line_height,
+ prt_ps_courier_font.ps_fontname[PRT_PS_FONT_BOLDOBLIQUE]);
+ }
+ if (prt_out_mbyte) {
+ /* Define the CID fonts to be used in the job. Typically CJKV fonts do
+ * not have an italic form being a western style, so where no font is
+ * defined for these faces VIM falls back to an existing face.
+ * Note: if using Courier for the ASCII range then the printout will
+ * have bold/italic/bolditalic regardless of the setting of printmbfont.
+ */
+ prt_dsc_resources("IncludeResource", "font",
+ prt_ps_mb_font.ps_fontname[PRT_PS_FONT_ROMAN]);
+ if (!prt_custom_cmap)
+ prt_dsc_resources("IncludeResource", "cmap", prt_cmap);
+ prt_def_cidfont("CF0", (int)prt_line_height,
+ prt_ps_mb_font.ps_fontname[PRT_PS_FONT_ROMAN]);
+
+ if (prt_ps_mb_font.ps_fontname[PRT_PS_FONT_BOLD] != NULL) {
+ prt_dsc_resources("IncludeResource", "font",
+ prt_ps_mb_font.ps_fontname[PRT_PS_FONT_BOLD]);
+ if (!prt_custom_cmap)
+ prt_dsc_resources("IncludeResource", "cmap", prt_cmap);
+ prt_def_cidfont("CF1", (int)prt_line_height,
+ prt_ps_mb_font.ps_fontname[PRT_PS_FONT_BOLD]);
+ } else
+ /* Use ROMAN for BOLD */
+ prt_dup_cidfont("CF0", "CF1");
+
+ if (prt_ps_mb_font.ps_fontname[PRT_PS_FONT_OBLIQUE] != NULL) {
+ prt_dsc_resources("IncludeResource", "font",
+ prt_ps_mb_font.ps_fontname[PRT_PS_FONT_OBLIQUE]);
+ if (!prt_custom_cmap)
+ prt_dsc_resources("IncludeResource", "cmap", prt_cmap);
+ prt_def_cidfont("CF2", (int)prt_line_height,
+ prt_ps_mb_font.ps_fontname[PRT_PS_FONT_OBLIQUE]);
+ } else
+ /* Use ROMAN for OBLIQUE */
+ prt_dup_cidfont("CF0", "CF2");
+
+ if (prt_ps_mb_font.ps_fontname[PRT_PS_FONT_BOLDOBLIQUE] != NULL) {
+ prt_dsc_resources("IncludeResource", "font",
+ prt_ps_mb_font.ps_fontname[PRT_PS_FONT_BOLDOBLIQUE]);
+ if (!prt_custom_cmap)
+ prt_dsc_resources("IncludeResource", "cmap", prt_cmap);
+ prt_def_cidfont("CF3", (int)prt_line_height,
+ prt_ps_mb_font.ps_fontname[PRT_PS_FONT_BOLDOBLIQUE]);
+ } else
+ /* Use BOLD for BOLDOBLIQUE */
+ prt_dup_cidfont("CF1", "CF3");
+ }
+
+ /* Misc constant vars used for underlining and background rects */
+ prt_def_var("UO", PRT_PS_FONT_TO_USER(prt_line_height,
+ prt_ps_font->uline_offset), 2);
+ prt_def_var("UW", PRT_PS_FONT_TO_USER(prt_line_height,
+ prt_ps_font->uline_width), 2);
+ prt_def_var("BO", prt_bgcol_offset, 2);
+
+ prt_dsc_noarg("EndSetup");
+
+ /* Fail if any problems writing out to the PS file */
+ retval = !prt_file_error;
+
+theend:
+ vim_free(res_prolog);
+ vim_free(res_encoding);
+ vim_free(res_cidfont);
+ vim_free(res_cmap);
+
+ return retval;
+}
+
+void mch_print_end(psettings)
+prt_settings_T *psettings;
+{
+ prt_dsc_noarg("Trailer");
+
+ /*
+ * Output any info we don't know in toto until we finish
+ */
+ prt_dsc_ints("Pages", 1, &prt_page_num);
+
+ prt_dsc_noarg("EOF");
+
+ /* Write CTRL-D to close serial communication link if used.
+ * NOTHING MUST BE WRITTEN AFTER THIS! */
+ prt_write_file((char_u *)IF_EB("\004", "\067"));
+
+ if (!prt_file_error && psettings->outfile == NULL
+ && !got_int && !psettings->user_abort) {
+ /* Close the file first. */
+ if (prt_ps_fd != NULL) {
+ fclose(prt_ps_fd);
+ prt_ps_fd = NULL;
+ }
+ prt_message((char_u *)_("Sending to printer..."));
+
+ /* Not printing to a file: use 'printexpr' to print the file. */
+ if (eval_printexpr(prt_ps_file_name, psettings->arguments) == FAIL)
+ EMSG(_("E365: Failed to print PostScript file"));
+ else
+ prt_message((char_u *)_("Print job sent."));
+ }
+
+ mch_print_cleanup();
+}
+
+int mch_print_end_page() {
+ prt_flush_buffer();
+
+ prt_write_string("re sp\n");
+
+ prt_dsc_noarg("PageTrailer");
+
+ return !prt_file_error;
+}
+
+int mch_print_begin_page(str)
+char_u *str UNUSED;
+{
+ int page_num[2];
+
+ prt_page_num++;
+
+ page_num[0] = page_num[1] = prt_page_num;
+ prt_dsc_ints("Page", 2, page_num);
+
+ prt_dsc_noarg("BeginPageSetup");
+
+ prt_write_string("sv\n0 g\n");
+ prt_in_ascii = !prt_out_mbyte;
+ if (prt_out_mbyte)
+ prt_write_string("CF0 sf\n");
+ else
+ prt_write_string("F0 sf\n");
+ prt_fgcol = PRCOLOR_BLACK;
+ prt_bgcol = PRCOLOR_WHITE;
+ prt_font = PRT_PS_FONT_ROMAN;
+
+ /* Set up page transformation for landscape printing. */
+ if (!prt_portrait) {
+ prt_write_int(-((int)prt_mediasize[prt_media].width));
+ prt_write_string("sl\n");
+ }
+
+ prt_dsc_noarg("EndPageSetup");
+
+ /* We have reset the font attributes, force setting them again. */
+ curr_bg = (long_u)0xffffffff;
+ curr_fg = (long_u)0xffffffff;
+ curr_bold = MAYBE;
+
+ return !prt_file_error;
+}
+
+int mch_print_blank_page() {
+ return mch_print_begin_page(NULL) ? (mch_print_end_page()) : FALSE;
+}
+
+static float prt_pos_x = 0;
+static float prt_pos_y = 0;
+
+void mch_print_start_line(margin, page_line)
+int margin;
+int page_line;
+{
+ prt_pos_x = prt_left_margin;
+ if (margin)
+ prt_pos_x -= prt_number_width;
+
+ prt_pos_y = prt_top_margin - prt_first_line_height -
+ page_line * prt_line_height;
+
+ prt_attribute_change = TRUE;
+ prt_need_moveto = TRUE;
+ prt_half_width = FALSE;
+}
+
+int mch_print_text_out(p, len)
+char_u *p;
+int len UNUSED;
+{
+ int need_break;
+ char_u ch;
+ char_u ch_buff[8];
+ float char_width;
+ float next_pos;
+ int in_ascii;
+ int half_width;
+
+ 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
+ * in the ASCII range, and the original CID font for everything else.
+ * The problem is that GhostScript still (as of 8.13) does not support
+ * rearranged fonts even though they have been documented by Adobe for 7
+ * years! If they ever do, a lot of this code will disappear.
+ */
+ if (prt_use_courier) {
+ in_ascii = (len == 1 && *p < 0x80);
+ if (prt_in_ascii) {
+ if (!in_ascii) {
+ /* No longer in ASCII range - need to switch font */
+ prt_in_ascii = FALSE;
+ prt_need_font = TRUE;
+ prt_attribute_change = TRUE;
+ }
+ } else if (in_ascii) {
+ /* Now in ASCII range - need to switch font */
+ prt_in_ascii = TRUE;
+ prt_need_font = TRUE;
+ prt_attribute_change = TRUE;
+ }
+ }
+ if (prt_out_mbyte) {
+ half_width = ((*mb_ptr2cells)(p) == 1);
+ if (half_width)
+ char_width /= 2;
+ if (prt_half_width) {
+ if (!half_width) {
+ prt_half_width = FALSE;
+ prt_pos_x += prt_char_width/4;
+ prt_need_moveto = TRUE;
+ prt_attribute_change = TRUE;
+ }
+ } else if (half_width) {
+ prt_half_width = TRUE;
+ prt_pos_x += prt_char_width/4;
+ prt_need_moveto = TRUE;
+ prt_attribute_change = TRUE;
+ }
+ }
+
+ /* Output any required changes to the graphics state, after flushing any
+ * text buffered so far.
+ */
+ if (prt_attribute_change) {
+ prt_flush_buffer();
+ /* Reset count of number of chars that will be printed */
+ prt_text_run = 0;
+
+ if (prt_need_moveto) {
+ prt_pos_x_moveto = prt_pos_x;
+ prt_pos_y_moveto = prt_pos_y;
+ prt_do_moveto = TRUE;
+
+ prt_need_moveto = FALSE;
+ }
+ if (prt_need_font) {
+ if (!prt_in_ascii)
+ prt_write_string("CF");
+ else
+ prt_write_string("F");
+ prt_write_int(prt_font);
+ prt_write_string("sf\n");
+ prt_need_font = FALSE;
+ }
+ if (prt_need_fgcol) {
+ int r, g, b;
+ r = ((unsigned)prt_fgcol & 0xff0000) >> 16;
+ g = ((unsigned)prt_fgcol & 0xff00) >> 8;
+ b = prt_fgcol & 0xff;
+
+ prt_write_real(r / 255.0, 3);
+ if (r == g && g == b)
+ prt_write_string("g\n");
+ else {
+ prt_write_real(g / 255.0, 3);
+ prt_write_real(b / 255.0, 3);
+ prt_write_string("r\n");
+ }
+ prt_need_fgcol = FALSE;
+ }
+
+ if (prt_bgcol != PRCOLOR_WHITE) {
+ prt_new_bgcol = prt_bgcol;
+ if (prt_need_bgcol)
+ prt_do_bgcol = TRUE;
+ } else
+ prt_do_bgcol = FALSE;
+ prt_need_bgcol = FALSE;
+
+ if (prt_need_underline)
+ prt_do_underline = prt_underline;
+ prt_need_underline = FALSE;
+
+ prt_attribute_change = FALSE;
+ }
+
+ 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 *)"";
+ }
+
+ if (prt_out_mbyte) {
+ /* Multi-byte character strings are represented more efficiently as hex
+ * strings when outputting clean 8 bit PS.
+ */
+ do {
+ ch = prt_hexchar[(unsigned)(*p) >> 4];
+ ga_append(&prt_ps_buffer, ch);
+ ch = prt_hexchar[(*p) & 0xf];
+ ga_append(&prt_ps_buffer, ch);
+ p++;
+ } while (--len);
+ } else {
+ /* Add next character to buffer of characters to output.
+ * Note: One printed character may require several PS characters to
+ * represent it, but we only count them as one printed character.
+ */
+ ch = *p;
+ if (ch < 32 || ch == '(' || ch == ')' || ch == '\\') {
+ /* Convert non-printing characters to either their escape or octal
+ * sequence, ensures PS sent over a serial line does not interfere
+ * with the comms protocol. Note: For EBCDIC we need to write out
+ * the escape sequences as ASCII codes!
+ * Note 2: Char codes < 32 are identical in EBCDIC and ASCII AFAIK!
+ */
+ ga_append(&prt_ps_buffer, IF_EB('\\', 0134));
+ switch (ch) {
+ case BS: ga_append(&prt_ps_buffer, IF_EB('b', 0142)); break;
+ case TAB: ga_append(&prt_ps_buffer, IF_EB('t', 0164)); break;
+ case NL: ga_append(&prt_ps_buffer, IF_EB('n', 0156)); break;
+ case FF: ga_append(&prt_ps_buffer, IF_EB('f', 0146)); break;
+ case CAR: ga_append(&prt_ps_buffer, IF_EB('r', 0162)); break;
+ case '(': ga_append(&prt_ps_buffer, IF_EB('(', 0050)); break;
+ case ')': ga_append(&prt_ps_buffer, IF_EB(')', 0051)); break;
+ case '\\': ga_append(&prt_ps_buffer, IF_EB('\\', 0134)); break;
+
+ default:
+ sprintf((char *)ch_buff, "%03o", (unsigned int)ch);
+ ga_append(&prt_ps_buffer, ch_buff[0]);
+ ga_append(&prt_ps_buffer, ch_buff[1]);
+ ga_append(&prt_ps_buffer, ch_buff[2]);
+ break;
+ }
+ } else
+ ga_append(&prt_ps_buffer, ch);
+ }
+
+ /* Need to free any translated characters */
+ if (prt_do_conv && (*p != NUL))
+ vim_free(p);
+
+ 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));
+
+ if (need_break)
+ prt_flush_buffer();
+
+ return need_break;
+}
+
+void mch_print_set_font(iBold, iItalic, iUnderline)
+int iBold;
+int iItalic;
+int iUnderline;
+{
+ int font = 0;
+
+ if (iBold)
+ font |= 0x01;
+ if (iItalic)
+ font |= 0x02;
+
+ if (font != prt_font) {
+ prt_font = font;
+ prt_attribute_change = TRUE;
+ prt_need_font = TRUE;
+ }
+ if (prt_underline != iUnderline) {
+ prt_underline = iUnderline;
+ prt_attribute_change = TRUE;
+ prt_need_underline = TRUE;
+ }
+}
+
+void mch_print_set_bg(bgcol)
+long_u bgcol;
+{
+ prt_bgcol = (int)bgcol;
+ prt_attribute_change = TRUE;
+ prt_need_bgcol = TRUE;
+}
+
+void mch_print_set_fg(fgcol)
+long_u fgcol;
+{
+ if (fgcol != (long_u)prt_fgcol) {
+ prt_fgcol = (int)fgcol;
+ prt_attribute_change = TRUE;
+ prt_need_fgcol = TRUE;
+ }
+}
+
diff --git a/src/hashtab.c b/src/hashtab.c
new file mode 100644
index 0000000000..4bab277f78
--- /dev/null
+++ b/src/hashtab.c
@@ -0,0 +1,416 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * 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.
+ */
+
+/*
+ * hashtab.c: Handling of a hashtable with Vim-specific properties.
+ *
+ * Each item in a hashtable has a NUL terminated string key. A key can appear
+ * only once in the table.
+ *
+ * A hash number is computed from the key for quick lookup. When the hashes
+ * of two different keys point to the same entry an algorithm is used to
+ * iterate over other entries in the table until the right one is found.
+ * To make the iteration work removed keys are different from entries where a
+ * key was never present.
+ *
+ * The mechanism has been partly based on how Python Dictionaries are
+ * implemented. The algorithm is from Knuth Vol. 3, Sec. 6.4.
+ *
+ * The hashtable grows to accommodate more entries when needed. At least 1/3
+ * of the entries is empty to keep the lookup efficient (at the cost of extra
+ * memory).
+ */
+
+#include "vim.h"
+
+
+
+/* Magic value for algorithm that walks through the array. */
+#define PERTURB_SHIFT 5
+
+static int hash_may_resize __ARGS((hashtab_T *ht, int minitems));
+
+
+/*
+ * Initialize an empty hash table.
+ */
+void hash_init(ht)
+hashtab_T *ht;
+{
+ /* This zeroes all "ht_" entries and all the "hi_key" in "ht_smallarray". */
+ vim_memset(ht, 0, sizeof(hashtab_T));
+ ht->ht_array = ht->ht_smallarray;
+ ht->ht_mask = HT_INIT_SIZE - 1;
+}
+
+/*
+ * Free the array of a hash table. Does not free the items it contains!
+ * If "ht" is not freed then you should call hash_init() next!
+ */
+void hash_clear(ht)
+hashtab_T *ht;
+{
+ if (ht->ht_array != ht->ht_smallarray)
+ vim_free(ht->ht_array);
+}
+
+/*
+ * Free the array of a hash table and all the keys it contains. The keys must
+ * have been allocated. "off" is the offset from the start of the allocate
+ * memory to the location of the key (it's always positive).
+ */
+void hash_clear_all(ht, off)
+hashtab_T *ht;
+int off;
+{
+ long todo;
+ hashitem_T *hi;
+
+ todo = (long)ht->ht_used;
+ for (hi = ht->ht_array; todo > 0; ++hi) {
+ if (!HASHITEM_EMPTY(hi)) {
+ vim_free(hi->hi_key - off);
+ --todo;
+ }
+ }
+ hash_clear(ht);
+}
+
+/*
+ * Find "key" in hashtable "ht". "key" must not be NULL.
+ * Always returns a pointer to a hashitem. If the item was not found then
+ * HASHITEM_EMPTY() is TRUE. The pointer is then the place where the key
+ * would be added.
+ * WARNING: The returned pointer becomes invalid when the hashtable is changed
+ * (adding, setting or removing an item)!
+ */
+hashitem_T * hash_find(ht, key)
+hashtab_T *ht;
+char_u *key;
+{
+ return hash_lookup(ht, key, hash_hash(key));
+}
+
+/*
+ * Like hash_find(), but caller computes "hash".
+ */
+hashitem_T * hash_lookup(ht, key, hash)
+hashtab_T *ht;
+char_u *key;
+hash_T hash;
+{
+ hash_T perturb;
+ hashitem_T *freeitem;
+ hashitem_T *hi;
+ unsigned idx;
+
+#ifdef HT_DEBUG
+ ++hash_count_lookup;
+#endif
+
+ /*
+ * Quickly handle the most common situations:
+ * - return if there is no item at all
+ * - skip over a removed item
+ * - return if the item matches
+ */
+ idx = (unsigned)(hash & ht->ht_mask);
+ hi = &ht->ht_array[idx];
+
+ if (hi->hi_key == NULL)
+ return hi;
+ if (hi->hi_key == HI_KEY_REMOVED)
+ freeitem = hi;
+ else if (hi->hi_hash == hash && STRCMP(hi->hi_key, key) == 0)
+ return hi;
+ else
+ freeitem = NULL;
+
+ /*
+ * Need to search through the table to find the key. The algorithm
+ * to step through the table starts with large steps, gradually becoming
+ * smaller down to (1/4 table size + 1). This means it goes through all
+ * table entries in the end.
+ * When we run into a NULL key it's clear that the key isn't there.
+ * Return the first available slot found (can be a slot of a removed
+ * item).
+ */
+ for (perturb = hash;; perturb >>= PERTURB_SHIFT) {
+#ifdef HT_DEBUG
+ ++hash_count_perturb; /* count a "miss" for hashtab lookup */
+#endif
+ idx = (unsigned)((idx << 2U) + idx + perturb + 1U);
+ hi = &ht->ht_array[idx & ht->ht_mask];
+ if (hi->hi_key == NULL)
+ return freeitem == NULL ? hi : freeitem;
+ if (hi->hi_hash == hash
+ && hi->hi_key != HI_KEY_REMOVED
+ && STRCMP(hi->hi_key, key) == 0)
+ return hi;
+ if (hi->hi_key == HI_KEY_REMOVED && freeitem == NULL)
+ freeitem = hi;
+ }
+}
+
+/*
+ * Print the efficiency of hashtable lookups.
+ * Useful when trying different hash algorithms.
+ * Called when exiting.
+ */
+void hash_debug_results() {
+#ifdef HT_DEBUG
+ fprintf(stderr, "\r\n\r\n\r\n\r\n");
+ fprintf(stderr, "Number of hashtable lookups: %ld\r\n", hash_count_lookup);
+ fprintf(stderr, "Number of perturb loops: %ld\r\n", hash_count_perturb);
+ fprintf(stderr, "Percentage of perturb loops: %ld%%\r\n",
+ hash_count_perturb * 100 / hash_count_lookup);
+#endif
+}
+
+/*
+ * Add item with key "key" to hashtable "ht".
+ * Returns FAIL when out of memory or the key is already present.
+ */
+int hash_add(ht, key)
+hashtab_T *ht;
+char_u *key;
+{
+ hash_T hash = hash_hash(key);
+ hashitem_T *hi;
+
+ hi = hash_lookup(ht, key, hash);
+ if (!HASHITEM_EMPTY(hi)) {
+ EMSG2(_(e_intern2), "hash_add()");
+ return FAIL;
+ }
+ return hash_add_item(ht, hi, key, hash);
+}
+
+/*
+ * Add item "hi" with "key" to hashtable "ht". "key" must not be NULL and
+ * "hi" must have been obtained with hash_lookup() and point to an empty item.
+ * "hi" is invalid after this!
+ * Returns OK or FAIL (out of memory).
+ */
+int hash_add_item(ht, hi, key, hash)
+hashtab_T *ht;
+hashitem_T *hi;
+char_u *key;
+hash_T hash;
+{
+ /* If resizing failed before and it fails again we can't add an item. */
+ if (ht->ht_error && hash_may_resize(ht, 0) == FAIL)
+ return FAIL;
+
+ ++ht->ht_used;
+ if (hi->hi_key == NULL)
+ ++ht->ht_filled;
+ hi->hi_key = key;
+ hi->hi_hash = hash;
+
+ /* When the space gets low may resize the array. */
+ return hash_may_resize(ht, 0);
+}
+
+
+/*
+ * Remove item "hi" from hashtable "ht". "hi" must have been obtained with
+ * hash_lookup().
+ * The caller must take care of freeing the item itself.
+ */
+void hash_remove(ht, hi)
+hashtab_T *ht;
+hashitem_T *hi;
+{
+ --ht->ht_used;
+ hi->hi_key = HI_KEY_REMOVED;
+ hash_may_resize(ht, 0);
+}
+
+/*
+ * Lock a hashtable: prevent that ht_array changes.
+ * Don't use this when items are to be added!
+ * Must call hash_unlock() later.
+ */
+void hash_lock(ht)
+hashtab_T *ht;
+{
+ ++ht->ht_locked;
+}
+
+
+/*
+ * Unlock a hashtable: allow ht_array changes again.
+ * Table will be resized (shrink) when necessary.
+ * This must balance a call to hash_lock().
+ */
+void hash_unlock(ht)
+hashtab_T *ht;
+{
+ --ht->ht_locked;
+ (void)hash_may_resize(ht, 0);
+}
+
+/*
+ * Shrink a hashtable when there is too much empty space.
+ * Grow a hashtable when there is not enough empty space.
+ * Returns OK or FAIL (out of memory).
+ */
+static int hash_may_resize(ht, minitems)
+hashtab_T *ht;
+int minitems; /* minimal number of items */
+{
+ hashitem_T temparray[HT_INIT_SIZE];
+ hashitem_T *oldarray, *newarray;
+ hashitem_T *olditem, *newitem;
+ unsigned newi;
+ int todo;
+ long_u oldsize, newsize;
+ long_u minsize;
+ long_u newmask;
+ hash_T perturb;
+
+ /* Don't resize a locked table. */
+ if (ht->ht_locked > 0)
+ return OK;
+
+#ifdef HT_DEBUG
+ if (ht->ht_used > ht->ht_filled)
+ EMSG("hash_may_resize(): more used than filled");
+ if (ht->ht_filled >= ht->ht_mask + 1)
+ EMSG("hash_may_resize(): table completely filled");
+#endif
+
+ if (minitems == 0) {
+ /* Return quickly for small tables with at least two NULL items. NULL
+ * items are required for the lookup to decide a key isn't there. */
+ if (ht->ht_filled < HT_INIT_SIZE - 1
+ && ht->ht_array == ht->ht_smallarray)
+ return OK;
+
+ /*
+ * Grow or refill the array when it's more than 2/3 full (including
+ * removed items, so that they get cleaned up).
+ * Shrink the array when it's less than 1/5 full. When growing it is
+ * at least 1/4 full (avoids repeated grow-shrink operations)
+ */
+ oldsize = ht->ht_mask + 1;
+ if (ht->ht_filled * 3 < oldsize * 2 && ht->ht_used > oldsize / 5)
+ return OK;
+
+ if (ht->ht_used > 1000)
+ minsize = ht->ht_used * 2; /* it's big, don't make too much room */
+ else
+ minsize = ht->ht_used * 4; /* make plenty of room */
+ } else {
+ /* Use specified size. */
+ if ((long_u)minitems < ht->ht_used) /* just in case... */
+ minitems = (int)ht->ht_used;
+ minsize = minitems * 3 / 2; /* array is up to 2/3 full */
+ }
+
+ newsize = HT_INIT_SIZE;
+ while (newsize < minsize) {
+ newsize <<= 1; /* make sure it's always a power of 2 */
+ if (newsize == 0)
+ return FAIL; /* overflow */
+ }
+
+ if (newsize == HT_INIT_SIZE) {
+ /* Use the small array inside the hashdict structure. */
+ newarray = ht->ht_smallarray;
+ if (ht->ht_array == newarray) {
+ /* Moving from ht_smallarray to ht_smallarray! Happens when there
+ * are many removed items. Copy the items to be able to clean up
+ * removed items. */
+ mch_memmove(temparray, newarray, sizeof(temparray));
+ oldarray = temparray;
+ } else
+ oldarray = ht->ht_array;
+ } else {
+ /* Allocate an array. */
+ newarray = (hashitem_T *)alloc((unsigned)
+ (sizeof(hashitem_T) * newsize));
+ if (newarray == NULL) {
+ /* Out of memory. When there are NULL items still return OK.
+ * Otherwise set ht_error, because lookup may result in a hang if
+ * we add another item. */
+ if (ht->ht_filled < ht->ht_mask)
+ return OK;
+ ht->ht_error = TRUE;
+ return FAIL;
+ }
+ oldarray = ht->ht_array;
+ }
+ vim_memset(newarray, 0, (size_t)(sizeof(hashitem_T) * newsize));
+
+ /*
+ * Move all the items from the old array to the new one, placing them in
+ * the right spot. The new array won't have any removed items, thus this
+ * is also a cleanup action.
+ */
+ newmask = newsize - 1;
+ todo = (int)ht->ht_used;
+ for (olditem = oldarray; todo > 0; ++olditem)
+ if (!HASHITEM_EMPTY(olditem)) {
+ /*
+ * The algorithm to find the spot to add the item is identical to
+ * the algorithm to find an item in hash_lookup(). But we only
+ * need to search for a NULL key, thus it's simpler.
+ */
+ newi = (unsigned)(olditem->hi_hash & newmask);
+ newitem = &newarray[newi];
+
+ if (newitem->hi_key != NULL)
+ for (perturb = olditem->hi_hash;; perturb >>= PERTURB_SHIFT) {
+ newi = (unsigned)((newi << 2U) + newi + perturb + 1U);
+ newitem = &newarray[newi & newmask];
+ if (newitem->hi_key == NULL)
+ break;
+ }
+ *newitem = *olditem;
+ --todo;
+ }
+
+ if (ht->ht_array != ht->ht_smallarray)
+ vim_free(ht->ht_array);
+ ht->ht_array = newarray;
+ ht->ht_mask = newmask;
+ ht->ht_filled = ht->ht_used;
+ ht->ht_error = FALSE;
+
+ return OK;
+}
+
+/*
+ * 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(key)
+char_u *key;
+{
+ hash_T hash;
+ char_u *p;
+
+ if ((hash = *key) == 0)
+ return (hash_T)0; /* Empty keys are not allowed, but we don't
+ want to crash if we get one. */
+ p = key + 1;
+
+ /* A simplistic algorithm that appears to do very well.
+ * Suggested by George Reilly. */
+ while (*p != NUL)
+ hash = hash * 101 + *p++;
+
+ return hash;
+}
+
diff --git a/src/if_cscope.c b/src/if_cscope.c
new file mode 100644
index 0000000000..2ef1d61cba
--- /dev/null
+++ b/src/if_cscope.c
@@ -0,0 +1,2352 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * CSCOPE support for Vim added by Andy Kahn <kahn@zk3.dec.com>
+ * Ported to Win32 by Sergey Khorev <sergey.khorev@gmail.com>
+ *
+ * The basic idea/structure of cscope for Vim was borrowed from Nvi. There
+ * might be a few lines of code that look similar to what Nvi has.
+ *
+ * See README.txt for an overview of the Vim source code.
+ */
+
+#include "vim.h"
+
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#if defined(UNIX)
+# include <sys/wait.h>
+#endif
+#include "if_cscope.h"
+
+static void cs_usage_msg __ARGS((csid_e x));
+static int cs_add __ARGS((exarg_T *eap));
+static void cs_stat_emsg __ARGS((char *fname));
+static int cs_add_common __ARGS((char *, char *, char *));
+static int cs_check_for_connections __ARGS((void));
+static int cs_check_for_tags __ARGS((void));
+static int cs_cnt_connections __ARGS((void));
+static void cs_reading_emsg __ARGS((int idx));
+static int cs_cnt_matches __ARGS((int idx));
+static char * cs_create_cmd __ARGS((char *csoption, char *pattern));
+static int cs_create_connection __ARGS((int i));
+static void do_cscope_general __ARGS((exarg_T *eap, int make_split));
+static void cs_file_results __ARGS((FILE *, int *));
+static void cs_fill_results __ARGS((char *, int, int *, char ***,
+ char ***, int *));
+static int cs_find __ARGS((exarg_T *eap));
+static int cs_find_common __ARGS((char *opt, char *pat, int, int, int,
+ char_u *cmdline));
+static int cs_help __ARGS((exarg_T *eap));
+static void clear_csinfo __ARGS((int i));
+static int cs_insert_filelist __ARGS((char *, char *, char *,
+ struct stat *));
+static int cs_kill __ARGS((exarg_T *eap));
+static void cs_kill_execute __ARGS((int, char *));
+static cscmd_T * cs_lookup_cmd __ARGS((exarg_T *eap));
+static char * cs_make_vim_style_matches __ARGS((char *, char *,
+ char *, char *));
+static char * cs_manage_matches __ARGS((char **, char **, int, mcmd_e));
+static char * cs_parse_results __ARGS((int cnumber, char *buf,
+ int bufsize, char **context,
+ char **linenumber,
+ char **search));
+static char * cs_pathcomponents __ARGS((char *path));
+static void cs_print_tags_priv __ARGS((char **, char **, int));
+static int cs_read_prompt __ARGS((int));
+static void cs_release_csp __ARGS((int, int freefnpp));
+static int cs_reset __ARGS((exarg_T *eap));
+static char * cs_resolve_file __ARGS((int, char *));
+static int cs_show __ARGS((exarg_T *eap));
+
+
+static csinfo_T * csinfo = NULL;
+static int csinfo_size = 0; /* number of items allocated in
+ csinfo[] */
+
+static int eap_arg_len; /* length of eap->arg, set in
+ cs_lookup_cmd() */
+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 },
+ { "help", cs_help,
+ N_("Show this message"), "help", 0 },
+ { "kill", cs_kill,
+ N_("Kill a connection"), "kill #", 0 },
+ { "reset", cs_reset,
+ N_("Reinit all connections"), "reset", 0 },
+ { "show", cs_show,
+ N_("Show connections"), "show", 0 },
+ { NULL, NULL, NULL, NULL, 0 }
+};
+
+static void cs_usage_msg(x)
+csid_e x;
+{
+ (void)EMSG2(_("E560: Usage: cs[cope] %s"), cs_cmds[(int)x].usage);
+}
+
+
+static enum {
+ EXP_CSCOPE_SUBCMD, /* expand ":cscope" sub-commands */
+ EXP_SCSCOPE_SUBCMD, /* expand ":scscope" sub-commands */
+ EXP_CSCOPE_FIND, /* expand ":cscope find" arguments */
+ EXP_CSCOPE_KILL /* expand ":cscope kill" arguments */
+} expand_what;
+
+/*
+ * Function given to ExpandGeneric() to obtain the cscope command
+ * expansion.
+ */
+char_u * get_cscope_name(xp, idx)
+expand_T *xp UNUSED;
+int idx;
+{
+ int current_idx;
+ int i;
+
+ switch (expand_what) {
+ case EXP_CSCOPE_SUBCMD:
+ /* Complete with sub-commands of ":cscope":
+ * add, find, help, kill, reset, show */
+ return (char_u *)cs_cmds[idx].name;
+ case EXP_SCSCOPE_SUBCMD:
+ /* Complete with sub-commands of ":scscope": same sub-commands as
+ * ":cscope" but skip commands which don't support split windows */
+ for (i = 0, current_idx = 0; cs_cmds[i].name != NULL; i++)
+ if (cs_cmds[i].cansplit)
+ if (current_idx++ == idx)
+ break;
+ return (char_u *)cs_cmds[i].name;
+ case EXP_CSCOPE_FIND:
+ {
+ const char *query_type[] =
+ {
+ "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. */
+ return (char_u *)query_type[idx];
+ }
+ case EXP_CSCOPE_KILL:
+ {
+ static char connection[5];
+
+ /* ":cscope kill" accepts connection numbers or partial names of
+ * the pathname of the cscope database as argument. Only complete
+ * with connection numbers. -1 can also be used to kill all
+ * connections. */
+ for (i = 0, current_idx = 0; i < csinfo_size; i++) {
+ if (csinfo[i].fname == NULL)
+ continue;
+ if (current_idx++ == idx) {
+ vim_snprintf(connection, sizeof(connection), "%d", i);
+ return (char_u *)connection;
+ }
+ }
+ return (current_idx == idx && idx > 0) ? (char_u *)"-1" : NULL;
+ }
+ default:
+ return NULL;
+ }
+}
+
+/*
+ * Handle command line completion for :cscope command.
+ */
+void set_context_in_cscope_cmd(xp, arg, cmdidx)
+expand_T *xp;
+char_u *arg;
+cmdidx_T cmdidx;
+{
+ char_u *p;
+
+ /* Default: expand subcommands */
+ xp->xp_context = EXPAND_CSCOPE;
+ xp->xp_pattern = 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)
+ xp->xp_context = EXPAND_NOTHING;
+ else if (STRNICMP(arg, "add", p - arg) == 0)
+ xp->xp_context = EXPAND_FILES;
+ else if (STRNICMP(arg, "kill", p - arg) == 0)
+ expand_what = EXP_CSCOPE_KILL;
+ else if (STRNICMP(arg, "find", p - arg) == 0)
+ expand_what = EXP_CSCOPE_FIND;
+ 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(eap, make_split)
+exarg_T *eap;
+int make_split; /* whether to split window */
+{
+ cscmd_T *cmdp;
+
+ if ((cmdp = cs_lookup_cmd(eap)) == NULL) {
+ cs_help(eap);
+ return;
+ }
+
+ if (make_split) {
+ if (!cmdp->cansplit) {
+ (void)MSG_PUTS(_(
+ "This cscope command does not support splitting the window.\n"));
+ return;
+ }
+ postponed_split = -1;
+ postponed_split_flags = cmdmod.split;
+ postponed_split_tab = cmdmod.tab;
+ }
+
+ cmdp->func(eap);
+
+ postponed_split_flags = 0;
+ postponed_split_tab = 0;
+}
+
+/*
+ * PUBLIC: do_cscope
+ */
+void do_cscope(eap)
+exarg_T *eap;
+{
+ do_cscope_general(eap, FALSE);
+}
+
+/*
+ * PUBLIC: do_scscope
+ *
+ * same as do_cscope, but splits window, too.
+ */
+void do_scscope(eap)
+exarg_T *eap;
+{
+ do_cscope_general(eap, TRUE);
+}
+
+/*
+ * PUBLIC: do_cstag
+ *
+ */
+void do_cstag(eap)
+exarg_T *eap;
+{
+ int ret = FALSE;
+
+ if (*eap->arg == NUL) {
+ (void)EMSG(_("E562: Usage: cstag <ident>"));
+ return;
+ }
+
+ switch (p_csto) {
+ case 0:
+ if (cs_check_for_connections()) {
+ ret = cs_find_common("g", (char *)(eap->arg), eap->forceit, FALSE,
+ FALSE, *eap->cmdlinep);
+ if (ret == FALSE) {
+ cs_free_tags();
+ if (msg_col)
+ msg_putchar('\n');
+
+ if (cs_check_for_tags())
+ ret = do_tag(eap->arg, DT_JUMP, 0, eap->forceit, FALSE);
+ }
+ } else if (cs_check_for_tags()) {
+ ret = do_tag(eap->arg, DT_JUMP, 0, eap->forceit, FALSE);
+ }
+ break;
+ case 1:
+ if (cs_check_for_tags()) {
+ ret = do_tag(eap->arg, DT_JUMP, 0, eap->forceit, FALSE);
+ if (ret == FALSE) {
+ if (msg_col)
+ msg_putchar('\n');
+
+ if (cs_check_for_connections()) {
+ ret = cs_find_common("g", (char *)(eap->arg), eap->forceit,
+ FALSE, FALSE, *eap->cmdlinep);
+ if (ret == FALSE)
+ cs_free_tags();
+ }
+ }
+ } else if (cs_check_for_connections()) {
+ ret = cs_find_common("g", (char *)(eap->arg), eap->forceit, FALSE,
+ FALSE, *eap->cmdlinep);
+ if (ret == FALSE)
+ cs_free_tags();
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (!ret) {
+ (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
+ */
+int cs_fgets(buf, size)
+char_u *buf;
+int size;
+{
+ char *p;
+
+ if ((p = cs_manage_matches(NULL, NULL, -1, Get)) == NULL)
+ return TRUE;
+ vim_strncpy(buf, (char_u *)p, size - 1);
+
+ return FALSE;
+} /* cs_fgets */
+
+
+/*
+ * PUBLIC: cs_free_tags
+ *
+ * called only from do_tag(), when popping the tag stack
+ */
+void cs_free_tags() {
+ cs_manage_matches(NULL, NULL, -1, Free);
+}
+
+/*
+ * PUBLIC: cs_print_tags
+ *
+ * called from do_tag()
+ */
+void cs_print_tags() {
+ cs_manage_matches(NULL, NULL, -1, Print);
+}
+
+/*
+ * "cscope_connection([{num} , {dbpath} [, {prepend}]])" function
+ *
+ * Checks for the existence of a |cscope| connection. If no
+ * parameters are specified, then the function returns:
+ *
+ * 0, if cscope was not available (not compiled in), or if there
+ * are no cscope connections; or
+ * 1, if there is at least one cscope connection.
+ *
+ * If parameters are specified, then the value of {num}
+ * determines how existence of a cscope connection is checked:
+ *
+ * {num} Description of existence check
+ * ----- ------------------------------
+ * 0 Same as no parameters (e.g., "cscope_connection()").
+ * 1 Ignore {prepend}, and use partial string matches for
+ * {dbpath}.
+ * 2 Ignore {prepend}, and use exact string matches for
+ * {dbpath}.
+ * 3 Use {prepend}, use partial string matches for both
+ * {dbpath} and {prepend}.
+ * 4 Use {prepend}, use exact string matches for both
+ * {dbpath} and {prepend}.
+ *
+ * Note: All string comparisons are case sensitive!
+ */
+int cs_connection(num, dbpath, ppath)
+int num;
+char_u *dbpath;
+char_u *ppath;
+{
+ int i;
+
+ if (num < 0 || num > 4 || (num > 0 && !dbpath))
+ return FALSE;
+
+ for (i = 0; i < csinfo_size; i++) {
+ if (!csinfo[i].fname)
+ continue;
+
+ if (num == 0)
+ return TRUE;
+
+ switch (num) {
+ case 1:
+ if (strstr(csinfo[i].fname, (char *)dbpath))
+ return TRUE;
+ break;
+ case 2:
+ if (strcmp(csinfo[i].fname, (char *)dbpath) == 0)
+ return TRUE;
+ break;
+ case 3:
+ if (strstr(csinfo[i].fname, (char *)dbpath)
+ && ((!ppath && !csinfo[i].ppath)
+ || (ppath
+ && csinfo[i].ppath
+ && strstr(csinfo[i].ppath, (char *)ppath))))
+ return TRUE;
+ break;
+ case 4:
+ if ((strcmp(csinfo[i].fname, (char *)dbpath) == 0)
+ && ((!ppath && !csinfo[i].ppath)
+ || (ppath
+ && csinfo[i].ppath
+ && (strcmp(csinfo[i].ppath, (char *)ppath) == 0))))
+ return TRUE;
+ break;
+ }
+ }
+
+ return FALSE;
+} /* cs_connection */
+
+
+/*
+ * PRIVATE functions
+ ****************************************************************************/
+
+/*
+ * PRIVATE: cs_add
+ *
+ * add cscope database or a directory name (to look for cscope.out)
+ * to the cscope connection list
+ *
+ * MAXPATHL 256
+ */
+static int cs_add(eap)
+exarg_T *eap UNUSED;
+{
+ char *fname, *ppath, *flags = NULL;
+
+ if ((fname = strtok((char *)NULL, (const char *)" ")) == NULL) {
+ cs_usage_msg(Add);
+ return CSCOPE_FAILURE;
+ }
+ if ((ppath = strtok((char *)NULL, (const char *)" ")) != NULL)
+ flags = strtok((char *)NULL, (const char *)" ");
+
+ return cs_add_common(fname, ppath, flags);
+}
+
+static void cs_stat_emsg(fname)
+char *fname;
+{
+ char *stat_emsg = _("E563: stat(%s) error: %d");
+ char *buf = (char *)alloc((unsigned)strlen(stat_emsg) + MAXPATHL + 10);
+
+ if (buf != NULL) {
+ (void)sprintf(buf, stat_emsg, fname, errno);
+ (void)EMSG(buf);
+ vim_free(buf);
+ } else
+ (void)EMSG(_("E563: stat error"));
+}
+
+
+/*
+ * 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(arg1, arg2, flags)
+char *arg1; /* filename - may contain environment variables */
+char *arg2; /* prepend path - may contain environment variables */
+char *flags;
+{
+ struct stat statbuf;
+ int ret;
+ char *fname = NULL;
+ char *fname2 = NULL;
+ char *ppath = NULL;
+ int i;
+ int len;
+ int usedlen = 0;
+ char_u *fbuf = NULL;
+
+ /* get the filename (arg1), expand it, and try to stat it */
+ if ((fname = (char *)alloc(MAXPATHL + 1)) == NULL)
+ goto add_err;
+
+ expand_env((char_u *)arg1, (char_u *)fname, MAXPATHL);
+ len = (int)STRLEN(fname);
+ fbuf = (char_u *)fname;
+ (void)modify_fname((char_u *)":p", &usedlen,
+ (char_u **)&fname, &fbuf, &len);
+ if (fname == NULL)
+ goto add_err;
+ fname = (char *)vim_strnsave((char_u *)fname, len);
+ vim_free(fbuf);
+ ret = stat(fname, &statbuf);
+ if (ret < 0) {
+staterr:
+ if (p_csverbose)
+ cs_stat_emsg(fname);
+ goto add_err;
+ }
+
+ /* get the prepend path (arg2), expand it, and try to stat it */
+ if (arg2 != NULL) {
+ struct stat statbuf2;
+
+ if ((ppath = (char *)alloc(MAXPATHL + 1)) == NULL)
+ goto add_err;
+
+ expand_env((char_u *)arg2, (char_u *)ppath, MAXPATHL);
+ ret = stat(ppath, &statbuf2);
+ if (ret < 0)
+ goto staterr;
+ }
+
+ /* if filename is a directory, append the cscope database name to it */
+ if ((statbuf.st_mode & S_IFMT) == S_IFDIR) {
+ fname2 = (char *)alloc((unsigned)(strlen(CSCOPE_DBFILE) + strlen(fname) + 2));
+ if (fname2 == NULL)
+ goto add_err;
+
+ while (fname[strlen(fname)-1] == '/'
+ ) {
+ fname[strlen(fname)-1] = '\0';
+ if (fname[0] == '\0')
+ break;
+ }
+ if (fname[0] == '\0')
+ (void)sprintf(fname2, "/%s", CSCOPE_DBFILE);
+ else
+ (void)sprintf(fname2, "%s/%s", fname, CSCOPE_DBFILE);
+
+ ret = stat(fname2, &statbuf);
+ if (ret < 0) {
+ if (p_csverbose)
+ cs_stat_emsg(fname2);
+ goto add_err;
+ }
+
+ i = cs_insert_filelist(fname2, ppath, flags, &statbuf);
+ }
+#if defined(UNIX)
+ else if (S_ISREG(statbuf.st_mode) || S_ISLNK(statbuf.st_mode))
+#else
+ /* WIN32 - substitute define S_ISREG from os_unix.h */
+ else if (((statbuf.st_mode) & S_IFMT) == S_IFREG)
+#endif
+ {
+ i = cs_insert_filelist(fname, ppath, flags, &statbuf);
+ } else {
+ if (p_csverbose)
+ (void)EMSG2(
+ _("E564: %s is not a directory or a valid cscope database"),
+ fname);
+ goto add_err;
+ }
+
+ if (i != -1) {
+ if (cs_create_connection(i) == CSCOPE_FAILURE
+ || cs_read_prompt(i) == CSCOPE_FAILURE) {
+ cs_release_csp(i, TRUE);
+ goto add_err;
+ }
+
+ if (p_csverbose) {
+ msg_clr_eos();
+ (void)smsg_attr(hl_attr(HLF_R),
+ (char_u *)_("Added cscope database %s"),
+ csinfo[i].fname);
+ }
+ }
+
+ vim_free(fname);
+ vim_free(fname2);
+ vim_free(ppath);
+ return CSCOPE_SUCCESS;
+
+add_err:
+ vim_free(fname2);
+ vim_free(fname);
+ vim_free(ppath);
+ return CSCOPE_FAILURE;
+} /* cs_add_common */
+
+
+static int cs_check_for_connections() {
+ return cs_cnt_connections() > 0;
+} /* cs_check_for_connections */
+
+static int cs_check_for_tags() {
+ return p_tags[0] != NUL && curbuf->b_p_tags != NULL;
+} /* cs_check_for_tags */
+
+/*
+ * PRIVATE: cs_cnt_connections
+ *
+ * count the number of cscope connections
+ */
+static int cs_cnt_connections() {
+ short i;
+ short cnt = 0;
+
+ for (i = 0; i < csinfo_size; i++) {
+ if (csinfo[i].fname != NULL)
+ cnt++;
+ }
+ return cnt;
+} /* cs_cnt_connections */
+
+static void cs_reading_emsg(idx)
+int idx; /* connection index */
+{
+ EMSGN(_("E262: error reading cscope connection %ld"), idx);
+}
+
+#define CSREAD_BUFSIZE 2048
+/*
+ * PRIVATE: cs_cnt_matches
+ *
+ * count the number of matches for a given cscope connection.
+ */
+static int cs_cnt_matches(idx)
+int idx;
+{
+ char *stok;
+ char *buf;
+ int nlines;
+
+ buf = (char *)alloc(CSREAD_BUFSIZE);
+ if (buf == NULL)
+ return 0;
+ for (;; ) {
+ if (!fgets(buf, CSREAD_BUFSIZE, csinfo[idx].fr_fp)) {
+ if (feof(csinfo[idx].fr_fp))
+ errno = EIO;
+
+ cs_reading_emsg(idx);
+
+ vim_free(buf);
+ return -1;
+ }
+
+ /*
+ * 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)
+ continue;
+ if (strstr((const char *)stok, "cscope:") == NULL)
+ continue;
+
+ if ((stok = strtok(NULL, (const char *)" ")) == NULL)
+ continue;
+ nlines = atoi(stok);
+ if (nlines < 0) {
+ nlines = 0;
+ break;
+ }
+
+ if ((stok = strtok(NULL, (const char *)" ")) == NULL)
+ continue;
+ if (strncmp((const char *)stok, "lines", 5))
+ continue;
+
+ break;
+ }
+
+ vim_free(buf);
+ return nlines;
+} /* cs_cnt_matches */
+
+
+/*
+ * PRIVATE: cs_create_cmd
+ *
+ * Creates the actual cscope command query from what the user entered.
+ */
+static char * cs_create_cmd(csoption, pattern)
+char *csoption;
+char *pattern;
+{
+ char *cmd;
+ short search;
+ char *pat;
+
+ switch (csoption[0]) {
+ case '0': case 's':
+ search = 0;
+ break;
+ case '1': case 'g':
+ search = 1;
+ break;
+ case '2': case 'd':
+ search = 2;
+ break;
+ case '3': case 'c':
+ search = 3;
+ break;
+ case '4': case 't':
+ search = 4;
+ break;
+ case '6': case 'e':
+ search = 6;
+ break;
+ case '7': case 'f':
+ search = 7;
+ break;
+ case '8': case 'i':
+ search = 8;
+ break;
+ default:
+ (void)EMSG(_("E561: unknown cscope search type"));
+ cs_usage_msg(Find);
+ return NULL;
+ }
+
+ /* Skip white space before the patter, except for text and pattern search,
+ * they may want to use the leading white space. */
+ pat = pattern;
+ if (search != 4 && search != 6)
+ while (vim_iswhite(*pat))
+ ++pat;
+
+ if ((cmd = (char *)alloc((unsigned)(strlen(pat) + 2))) == NULL)
+ return NULL;
+
+ (void)sprintf(cmd, "%d%s", search, pat);
+
+ return cmd;
+} /* 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?
+ */
+static int cs_create_connection(i)
+int i;
+{
+#ifdef UNIX
+ int to_cs[2], from_cs[2];
+#endif
+ int len;
+ char *prog, *cmd, *ppath = NULL;
+
+#if defined(UNIX)
+ /*
+ * Cscope reads from to_cs[0] and writes to from_cs[1]; vi reads from
+ * from_cs[0] and writes to to_cs[1].
+ */
+ to_cs[0] = to_cs[1] = from_cs[0] = from_cs[1] = -1;
+ if (pipe(to_cs) < 0 || pipe(from_cs) < 0) {
+ (void)EMSG(_("E566: Could not create cscope pipes"));
+err_closing:
+ if (to_cs[0] != -1)
+ (void)close(to_cs[0]);
+ if (to_cs[1] != -1)
+ (void)close(to_cs[1]);
+ if (from_cs[0] != -1)
+ (void)close(from_cs[0]);
+ if (from_cs[1] != -1)
+ (void)close(from_cs[1]);
+ return CSCOPE_FAILURE;
+ }
+
+ switch (csinfo[i].pid = fork()) {
+ case -1:
+ (void)EMSG(_("E622: Could not fork for cscope"));
+ goto err_closing;
+ case 0: /* child: run cscope. */
+ if (dup2(to_cs[0], STDIN_FILENO) == -1)
+ PERROR("cs_create_connection 1");
+ if (dup2(from_cs[1], STDOUT_FILENO) == -1)
+ PERROR("cs_create_connection 2");
+ if (dup2(from_cs[1], STDERR_FILENO) == -1)
+ PERROR("cs_create_connection 3");
+
+ /* close unused */
+ (void)close(to_cs[1]);
+ (void)close(from_cs[0]);
+#else
+ /* WIN32 */
+ /* Create pipes to communicate with cscope */
+ sa.nLength = sizeof(SECURITY_ATTRIBUTES);
+ sa.bInheritHandle = TRUE;
+ sa.lpSecurityDescriptor = NULL;
+
+ if (!(pipe_stdin = CreatePipe(&stdin_rd, &stdin_wr, &sa, 0))
+ || !(pipe_stdout = CreatePipe(&stdout_rd, &stdout_wr, &sa, 0))) {
+ (void)EMSG(_("E566: Could not create cscope pipes"));
+err_closing:
+ if (pipe_stdin) {
+ CloseHandle(stdin_rd);
+ CloseHandle(stdin_wr);
+ }
+ if (pipe_stdout) {
+ CloseHandle(stdout_rd);
+ CloseHandle(stdout_wr);
+ }
+ return CSCOPE_FAILURE;
+ }
+#endif
+ /* expand the cscope exec for env var's */
+ if ((prog = (char *)alloc(MAXPATHL + 1)) == NULL) {
+#ifdef UNIX
+ return CSCOPE_FAILURE;
+#else
+ /* WIN32 */
+ goto err_closing;
+#endif
+ }
+ expand_env((char_u *)p_csprg, (char_u *)prog, MAXPATHL);
+
+ /* alloc space to hold the cscope command */
+ len = (int)(strlen(prog) + strlen(csinfo[i].fname) + 32);
+ if (csinfo[i].ppath) {
+ /* expand the prepend path for env var's */
+ if ((ppath = (char *)alloc(MAXPATHL + 1)) == NULL) {
+ vim_free(prog);
+#ifdef UNIX
+ return CSCOPE_FAILURE;
+#else
+ /* WIN32 */
+ goto err_closing;
+#endif
+ }
+ expand_env((char_u *)csinfo[i].ppath, (char_u *)ppath, MAXPATHL);
+
+ len += (int)strlen(ppath);
+ }
+
+ if (csinfo[i].flags)
+ len += (int)strlen(csinfo[i].flags);
+
+ if ((cmd = (char *)alloc(len)) == NULL) {
+ vim_free(prog);
+ vim_free(ppath);
+#ifdef UNIX
+ return CSCOPE_FAILURE;
+#else
+ /* WIN32 */
+ goto err_closing;
+#endif
+ }
+
+ /* run the cscope command; is there execl for non-unix systems? */
+#if defined(UNIX)
+ (void)sprintf(cmd, "exec %s -dl -f %s", prog, csinfo[i].fname);
+#else
+ /* WIN32 */
+ (void)sprintf(cmd, "%s -dl -f %s", prog, csinfo[i].fname);
+#endif
+ if (csinfo[i].ppath != NULL) {
+ (void)strcat(cmd, " -P");
+ (void)strcat(cmd, csinfo[i].ppath);
+ }
+ if (csinfo[i].flags != NULL) {
+ (void)strcat(cmd, " ");
+ (void)strcat(cmd, csinfo[i].flags);
+ }
+# ifdef UNIX
+ /* on Win32 we still need prog */
+ vim_free(prog);
+# endif
+ vim_free(ppath);
+
+#if defined(UNIX)
+# if defined(HAVE_SETSID) || defined(HAVE_SETPGID)
+ /* Change our process group to avoid cscope receiving SIGWINCH. */
+# if defined(HAVE_SETSID)
+ (void)setsid();
+# else
+ if (setpgid(0, 0) == -1)
+ PERROR(_("cs_create_connection setpgid failed"));
+# endif
+# endif
+ if (execl("/bin/sh", "sh", "-c", cmd, (char *)NULL) == -1)
+ PERROR(_("cs_create_connection exec failed"));
+
+ exit(127);
+ /* NOTREACHED */
+ default: /* parent. */
+ /*
+ * Save the file descriptors for later duplication, and
+ * reopen as streams.
+ */
+ if ((csinfo[i].to_fp = fdopen(to_cs[1], "w")) == NULL)
+ PERROR(_("cs_create_connection: fdopen for to_fp failed"));
+ if ((csinfo[i].fr_fp = fdopen(from_cs[0], "r")) == NULL)
+ PERROR(_("cs_create_connection: fdopen for fr_fp failed"));
+
+ /* close unused */
+ (void)close(to_cs[0]);
+ (void)close(from_cs[1]);
+
+ break;
+ }
+
+#else
+ /* WIN32 */
+ /* Create a new process to run cscope and use pipes to talk with it */
+ GetStartupInfo(&si);
+ si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
+ si.wShowWindow = SW_HIDE; /* Hide child application window */
+ si.hStdOutput = stdout_wr;
+ si.hStdError = stdout_wr;
+ si.hStdInput = stdin_rd;
+ created = CreateProcess(NULL, cmd, NULL, NULL, TRUE, CREATE_NEW_CONSOLE,
+ NULL, NULL, &si, &pi);
+ vim_free(prog);
+ vim_free(cmd);
+
+ if (!created) {
+ PERROR(_("cs_create_connection exec failed"));
+ (void)EMSG(_("E623: Could not spawn cscope process"));
+ goto err_closing;
+ }
+ /* else */
+ csinfo[i].pid = pi.dwProcessId;
+ csinfo[i].hProc = pi.hProcess;
+ CloseHandle(pi.hThread);
+
+ /* TODO - tidy up after failure to create files on pipe handles. */
+ if (((fd = _open_osfhandle((OPEN_OH_ARGTYPE)stdin_wr,
+ _O_TEXT|_O_APPEND)) < 0)
+ || ((csinfo[i].to_fp = _fdopen(fd, "w")) == NULL))
+ PERROR(_("cs_create_connection: fdopen for to_fp failed"));
+ if (((fd = _open_osfhandle((OPEN_OH_ARGTYPE)stdout_rd,
+ _O_TEXT|_O_RDONLY)) < 0)
+ || ((csinfo[i].fr_fp = _fdopen(fd, "r")) == NULL))
+ PERROR(_("cs_create_connection: fdopen for fr_fp failed"));
+
+ /* Close handles for file descriptors inherited by the cscope process */
+ CloseHandle(stdin_rd);
+ CloseHandle(stdout_wr);
+
+#endif /* !UNIX */
+
+ return CSCOPE_SUCCESS;
+} /* 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.
+ */
+static int cs_find(eap)
+exarg_T *eap;
+{
+ char *opt, *pat;
+ int i;
+
+ if (cs_check_for_connections() == FALSE) {
+ (void)EMSG(_("E567: no cscope connections"));
+ return FALSE;
+ }
+
+ if ((opt = strtok((char *)NULL, (const char *)" ")) == NULL) {
+ cs_usage_msg(Find);
+ return FALSE;
+ }
+
+ pat = opt + strlen(opt) + 1;
+ if (pat >= (char *)eap->arg + eap_arg_len) {
+ cs_usage_msg(Find);
+ return FALSE;
+ }
+
+ /*
+ * Let's replace the NULs written by strtok() with spaces - we need the
+ * spaces to correctly display the quickfix/location list window's title.
+ */
+ for (i = 0; i < eap_arg_len; ++i)
+ if (NUL == eap->arg[i])
+ eap->arg[i] = ' ';
+
+ return cs_find_common(opt, pat, eap->forceit, TRUE,
+ eap->cmdidx == CMD_lcscope, *eap->cmdlinep);
+} /* cs_find */
+
+
+/*
+ * PRIVATE: cs_find_common
+ *
+ * common code for cscope find, shared by cs_find() and do_cstag()
+ */
+static int cs_find_common(opt, pat, forceit, verbose, use_ll, cmdline)
+char *opt;
+char *pat;
+int forceit;
+int verbose;
+int use_ll;
+char_u *cmdline;
+{
+ int i;
+ char *cmd;
+ int *nummatches;
+ int totmatches;
+ char cmdletter;
+ char *qfpos;
+
+ /* get cmd letter */
+ switch (opt[0]) {
+ case '0':
+ cmdletter = 's';
+ break;
+ case '1':
+ cmdletter = 'g';
+ break;
+ case '2':
+ cmdletter = 'd';
+ break;
+ case '3':
+ cmdletter = 'c';
+ break;
+ case '4':
+ cmdletter = 't';
+ break;
+ case '6':
+ cmdletter = 'e';
+ break;
+ case '7':
+ cmdletter = 'f';
+ break;
+ case '8':
+ cmdletter = 'i';
+ break;
+ default:
+ cmdletter = opt[0];
+ }
+
+ qfpos = (char *)vim_strchr(p_csqf, cmdletter);
+ if (qfpos != NULL) {
+ qfpos++;
+ /* next symbol must be + or - */
+ if (strchr(CSQF_FLAGS, *qfpos) == NULL) {
+ char *nf = _("E469: invalid cscopequickfix flag %c for %c");
+ char *buf = (char *)alloc((unsigned)strlen(nf));
+
+ /* strlen will be enough because we use chars */
+ if (buf != NULL) {
+ sprintf(buf, nf, *qfpos, *(qfpos-1));
+ (void)EMSG(buf);
+ vim_free(buf);
+ }
+ return FALSE;
+ }
+
+ if (*qfpos != '0') {
+ apply_autocmds(EVENT_QUICKFIXCMDPRE, (char_u *)"cscope",
+ curbuf->b_fname, TRUE, curbuf);
+ if (did_throw || force_abort)
+ return FALSE;
+ }
+ }
+
+ /* create the actual command to send to cscope */
+ cmd = cs_create_cmd(opt, pat);
+ if (cmd == NULL)
+ return FALSE;
+
+ nummatches = (int *)alloc(sizeof(int)*csinfo_size);
+ if (nummatches == NULL)
+ return FALSE;
+
+ /* Send query to all open connections, then count the total number
+ * of matches so we can alloc all in one swell foop. */
+ for (i = 0; i < csinfo_size; i++)
+ nummatches[i] = 0;
+ totmatches = 0;
+ for (i = 0; i < csinfo_size; i++) {
+ if (csinfo[i].fname == NULL || csinfo[i].to_fp == NULL)
+ continue;
+
+ /* send cmd to cscope */
+ (void)fprintf(csinfo[i].to_fp, "%s\n", cmd);
+ (void)fflush(csinfo[i].to_fp);
+
+ nummatches[i] = cs_cnt_matches(i);
+
+ if (nummatches[i] > -1)
+ totmatches += nummatches[i];
+
+ if (nummatches[i] == 0)
+ (void)cs_read_prompt(i);
+ }
+ vim_free(cmd);
+
+ if (totmatches == 0) {
+ char *nf = _("E259: no matches found for cscope query %s of %s");
+ char *buf;
+
+ if (!verbose) {
+ vim_free(nummatches);
+ return FALSE;
+ }
+
+ buf = (char *)alloc((unsigned)(strlen(opt) + strlen(pat) + strlen(nf)));
+ if (buf == NULL)
+ (void)EMSG(nf);
+ else {
+ sprintf(buf, nf, opt, pat);
+ (void)EMSG(buf);
+ vim_free(buf);
+ }
+ vim_free(nummatches);
+ return FALSE;
+ }
+
+ if (qfpos != NULL && *qfpos != '0' && totmatches > 0) {
+ /* fill error list */
+ FILE *f;
+ char_u *tmp = vim_tempname('c');
+ qf_info_T *qi = NULL;
+ win_T *wp = NULL;
+
+ f = mch_fopen((char *)tmp, "w");
+ if (f == NULL)
+ EMSG2(_(e_notopen), tmp);
+ else {
+ cs_file_results(f, nummatches);
+ fclose(f);
+ if (use_ll) /* Use location list */
+ wp = curwin;
+ /* '-' starts a new error list */
+ if (qf_init(wp, tmp, (char_u *)"%f%*\\t%l%*\\t%m",
+ *qfpos == '-', cmdline) > 0) {
+ if (postponed_split != 0) {
+ win_split(postponed_split > 0 ? postponed_split : 0,
+ postponed_split_flags);
+ RESET_BINDING(curwin);
+ postponed_split = 0;
+ }
+
+ apply_autocmds(EVENT_QUICKFIXCMDPOST, (char_u *)"cscope",
+ curbuf->b_fname, TRUE, curbuf);
+ if (use_ll)
+ /*
+ * In the location list window, use the displayed location
+ * list. Otherwise, use the location list for the window.
+ */
+ qi = (bt_quickfix(wp->w_buffer) && wp->w_llist_ref != NULL)
+ ? wp->w_llist_ref : wp->w_llist;
+ qf_jump(qi, 0, 0, forceit);
+ }
+ }
+ mch_remove(tmp);
+ vim_free(tmp);
+ vim_free(nummatches);
+ return TRUE;
+ } else {
+ char **matches = NULL, **contexts = NULL;
+ int matched = 0;
+
+ /* read output */
+ cs_fill_results((char *)pat, totmatches, nummatches, &matches,
+ &contexts, &matched);
+ vim_free(nummatches);
+ if (matches == NULL)
+ return FALSE;
+
+ (void)cs_manage_matches(matches, contexts, matched, Store);
+
+ return do_tag((char_u *)pat, DT_CSCOPE, 0, forceit, verbose);
+ }
+
+} /* cs_find_common */
+
+/*
+ * PRIVATE: cs_help
+ *
+ * print help
+ */
+static int cs_help(eap)
+exarg_T *eap UNUSED;
+{
+ cscmd_T *cmdp = cs_cmds;
+
+ (void)MSG_PUTS(_("cscope commands:\n"));
+ while (cmdp->name != NULL) {
+ char *help = _(cmdp->help);
+ int space_cnt = 30 - vim_strsize((char_u *)help);
+
+ /* Use %*s rather than %30s to ensure proper alignment in utf-8 */
+ if (space_cnt < 0)
+ space_cnt = 0;
+ (void)smsg((char_u *)_("%-5s: %s%*s (Usage: %s)"),
+ cmdp->name,
+ help, space_cnt, " ",
+ 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"));
+
+ cmdp++;
+ }
+
+ wait_return(TRUE);
+ return 0;
+} /* cs_help */
+
+
+static void clear_csinfo(i)
+int i;
+{
+ csinfo[i].fname = NULL;
+ csinfo[i].ppath = NULL;
+ csinfo[i].flags = NULL;
+#if defined(UNIX)
+ csinfo[i].st_dev = (dev_t)0;
+ csinfo[i].st_ino = (ino_t)0;
+#else
+ csinfo[i].nVolume = 0;
+ csinfo[i].nIndexHigh = 0;
+ csinfo[i].nIndexLow = 0;
+#endif
+ csinfo[i].pid = 0;
+ csinfo[i].fr_fp = NULL;
+ csinfo[i].to_fp = NULL;
+}
+
+#ifndef UNIX
+static char *GetWin32Error __ARGS((void));
+
+static char * GetWin32Error() {
+ char *msg = NULL;
+ FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL, GetLastError(), 0, (LPSTR)&msg, 0, NULL);
+ if (msg != NULL) {
+ /* remove trailing \r\n */
+ char *pcrlf = strstr(msg, "\r\n");
+ if (pcrlf != NULL)
+ *pcrlf = '\0';
+ }
+ return msg;
+}
+
+#endif
+
+/*
+ * PRIVATE: cs_insert_filelist
+ *
+ * insert a new cscope database filename into the filelist
+ */
+static int cs_insert_filelist(fname, ppath, flags, sb)
+char *fname;
+char *ppath;
+char *flags;
+struct stat *sb UNUSED;
+{
+ short i, j;
+#ifndef UNIX
+ BY_HANDLE_FILE_INFORMATION bhfi;
+
+ /* On windows 9x GetFileInformationByHandle doesn't work, so skip it */
+ if (!mch_windows95()) {
+ switch (win32_fileinfo(fname, &bhfi)) {
+ case FILEINFO_ENC_FAIL: /* enc_to_utf16() failed */
+ case FILEINFO_READ_FAIL: /* CreateFile() failed */
+ if (p_csverbose) {
+ char *cant_msg = _("E625: cannot open cscope database: %s");
+ char *winmsg = GetWin32Error();
+
+ if (winmsg != NULL) {
+ (void)EMSG2(cant_msg, winmsg);
+ LocalFree(winmsg);
+ } else
+ /* subst filename if can't get error text */
+ (void)EMSG2(cant_msg, fname);
+ }
+ return -1;
+
+ case FILEINFO_INFO_FAIL: /* GetFileInformationByHandle() failed */
+ if (p_csverbose)
+ (void)EMSG(_("E626: cannot get cscope database information"));
+ return -1;
+ }
+ }
+#endif
+
+ i = -1; /* can be set to the index of an empty item in csinfo */
+ for (j = 0; j < csinfo_size; j++) {
+ if (csinfo[j].fname != NULL
+#if defined(UNIX)
+ && csinfo[j].st_dev == sb->st_dev && csinfo[j].st_ino == sb->st_ino
+#else
+ /* compare pathnames first */
+ && ((fullpathcmp(csinfo[j].fname, fname, FALSE) & FPC_SAME)
+ /* if not Windows 9x, test index file attributes too */
+ || (!mch_windows95()
+ && csinfo[j].nVolume == bhfi.dwVolumeSerialNumber
+ && csinfo[j].nIndexHigh == bhfi.nFileIndexHigh
+ && csinfo[j].nIndexLow == bhfi.nFileIndexLow))
+#endif
+ ) {
+ if (p_csverbose)
+ (void)EMSG(_("E568: duplicate cscope database not added"));
+ return -1;
+ }
+
+ if (csinfo[j].fname == NULL && i == -1)
+ i = j; /* remember first empty entry */
+ }
+
+ if (i == -1) {
+ i = csinfo_size;
+ if (csinfo_size == 0) {
+ /* First time allocation: allocate only 1 connection. It should
+ * be enough for most users. If more is needed, csinfo will be
+ * reallocated. */
+ csinfo_size = 1;
+ csinfo = (csinfo_T *)alloc_clear(sizeof(csinfo_T));
+ } else {
+ /* Reallocate space for more connections. */
+ csinfo_size *= 2;
+ csinfo = vim_realloc(csinfo, sizeof(csinfo_T)*csinfo_size);
+ }
+ if (csinfo == NULL)
+ return -1;
+ for (j = csinfo_size/2; j < csinfo_size; j++)
+ clear_csinfo(j);
+ }
+
+ if ((csinfo[i].fname = (char *)alloc((unsigned)strlen(fname)+1)) == NULL)
+ return -1;
+
+ (void)strcpy(csinfo[i].fname, (const char *)fname);
+
+ if (ppath != NULL) {
+ if ((csinfo[i].ppath = (char *)alloc((unsigned)strlen(ppath) + 1)) ==
+ NULL) {
+ vim_free(csinfo[i].fname);
+ csinfo[i].fname = NULL;
+ return -1;
+ }
+ (void)strcpy(csinfo[i].ppath, (const char *)ppath);
+ } else
+ csinfo[i].ppath = NULL;
+
+ if (flags != NULL) {
+ if ((csinfo[i].flags = (char *)alloc((unsigned)strlen(flags) + 1)) ==
+ NULL) {
+ vim_free(csinfo[i].fname);
+ vim_free(csinfo[i].ppath);
+ csinfo[i].fname = NULL;
+ csinfo[i].ppath = NULL;
+ return -1;
+ }
+ (void)strcpy(csinfo[i].flags, (const char *)flags);
+ } else
+ csinfo[i].flags = NULL;
+
+#if defined(UNIX)
+ csinfo[i].st_dev = sb->st_dev;
+ csinfo[i].st_ino = sb->st_ino;
+
+#else
+ csinfo[i].nVolume = bhfi.dwVolumeSerialNumber;
+ csinfo[i].nIndexLow = bhfi.nFileIndexLow;
+ csinfo[i].nIndexHigh = bhfi.nFileIndexHigh;
+#endif
+ return i;
+} /* cs_insert_filelist */
+
+
+/*
+ * PRIVATE: cs_lookup_cmd
+ *
+ * find cscope command in command table
+ */
+static cscmd_T * cs_lookup_cmd(eap)
+exarg_T *eap;
+{
+ cscmd_T *cmdp;
+ char *stok;
+ size_t len;
+
+ if (eap->arg == NULL)
+ return NULL;
+
+ /* Store length of eap->arg before it gets modified by strtok(). */
+ eap_arg_len = (int)STRLEN(eap->arg);
+
+ if ((stok = strtok((char *)(eap->arg), (const char *)" ")) == NULL)
+ return NULL;
+
+ len = strlen(stok);
+ for (cmdp = cs_cmds; cmdp->name != NULL; ++cmdp) {
+ if (strncmp((const char *)(stok), cmdp->name, len) == 0)
+ return cmdp;
+ }
+ return NULL;
+} /* cs_lookup_cmd */
+
+
+/*
+ * PRIVATE: cs_kill
+ *
+ * nuke em
+ */
+static int cs_kill(eap)
+exarg_T *eap UNUSED;
+{
+ char *stok;
+ short i;
+
+ if ((stok = strtok((char *)NULL, (const char *)" ")) == NULL) {
+ cs_usage_msg(Kill);
+ return CSCOPE_FAILURE;
+ }
+
+ /* only single digit positive and negative integers are allowed */
+ if ((strlen(stok) < 2 && VIM_ISDIGIT((int)(stok[0])))
+ || (strlen(stok) < 3 && stok[0] == '-'
+ && VIM_ISDIGIT((int)(stok[1]))))
+ i = atoi(stok);
+ else {
+ /* It must be part of a name. We will try to find a match
+ * within all the names in the csinfo data structure
+ */
+ for (i = 0; i < csinfo_size; i++) {
+ if (csinfo[i].fname != NULL && strstr(csinfo[i].fname, stok))
+ break;
+ }
+ }
+
+ if ((i != -1) && (i >= csinfo_size || i < -1 || csinfo[i].fname == NULL)) {
+ if (p_csverbose)
+ (void)EMSG2(_("E261: cscope connection %s not found"), stok);
+ } else {
+ if (i == -1) {
+ for (i = 0; i < csinfo_size; i++) {
+ if (csinfo[i].fname)
+ cs_kill_execute(i, csinfo[i].fname);
+ }
+ } else
+ cs_kill_execute(i, stok);
+ }
+
+ return 0;
+} /* cs_kill */
+
+
+/*
+ * PRIVATE: cs_kill_execute
+ *
+ * Actually kills a specific cscope connection.
+ */
+static void cs_kill_execute(i, cname)
+int i; /* cscope table index */
+char *cname; /* cscope database name */
+{
+ if (p_csverbose) {
+ msg_clr_eos();
+ (void)smsg_attr(hl_attr(HLF_R) | MSG_HIST,
+ (char_u *)_("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.
+ */
+static char * cs_make_vim_style_matches(fname, slno, search, tagstr)
+char *fname;
+char *slno;
+char *search;
+char *tagstr;
+{
+ /* vim style is ctags:
+ *
+ * <tagstr>\t<filename>\t<linenum_or_search>"\t<extra>
+ *
+ * but as mentioned above, we'll always use the line number and
+ * put the search pattern (if one exists) as "extra"
+ *
+ * buf is used as part of vim's method of handling tags, and
+ * (i think) vim frees it when you pop your tags and get replaced
+ * by new ones on the tag stack.
+ */
+ char *buf;
+ int amt;
+
+ if (search != NULL) {
+ amt =
+ (int)(strlen(fname) + strlen(slno) + strlen(tagstr) + strlen(search)+6);
+ if ((buf = (char *)alloc(amt)) == NULL)
+ return NULL;
+
+ (void)sprintf(buf, "%s\t%s\t%s;\"\t%s", tagstr, fname, slno, search);
+ } else {
+ amt = (int)(strlen(fname) + strlen(slno) + strlen(tagstr) + 5);
+ if ((buf = (char *)alloc(amt)) == NULL)
+ return NULL;
+
+ (void)sprintf(buf, "%s\t%s\t%s;\"", tagstr, fname, slno);
+ }
+
+ return buf;
+} /* 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
+ */
+static char * cs_manage_matches(matches, contexts, totmatches, cmd)
+char **matches;
+char **contexts;
+int totmatches;
+mcmd_e cmd;
+{
+ static char **mp = NULL;
+ static char **cp = NULL;
+ static int cnt = -1;
+ static int next = -1;
+ char *p = NULL;
+
+ switch (cmd) {
+ case Store:
+ assert(matches != NULL);
+ assert(totmatches > 0);
+ if (mp != NULL || cp != NULL)
+ (void)cs_manage_matches(NULL, NULL, -1, Free);
+ mp = matches;
+ cp = contexts;
+ cnt = totmatches;
+ next = 0;
+ break;
+ case Get:
+ if (next >= cnt)
+ return NULL;
+
+ p = mp[next];
+ next++;
+ break;
+ case Free:
+ if (mp != NULL) {
+ if (cnt > 0)
+ while (cnt--) {
+ vim_free(mp[cnt]);
+ if (cp != NULL)
+ vim_free(cp[cnt]);
+ }
+ vim_free(mp);
+ vim_free(cp);
+ }
+ mp = NULL;
+ cp = NULL;
+ cnt = 0;
+ next = 0;
+ break;
+ case Print:
+ cs_print_tags_priv(mp, cp, cnt);
+ break;
+ default: /* should not reach here */
+ (void)EMSG(_("E570: fatal error in cs_manage_matches"));
+ return NULL;
+ }
+
+ return p;
+} /* cs_manage_matches */
+
+
+/*
+ * PRIVATE: cs_parse_results
+ *
+ * parse cscope output
+ */
+static char * cs_parse_results(cnumber, buf, bufsize, context, linenumber,
+ search)
+int cnumber;
+char *buf;
+int bufsize;
+char **context;
+char **linenumber;
+char **search;
+{
+ int ch;
+ char *p;
+ char *name;
+
+ if (fgets(buf, bufsize, csinfo[cnumber].fr_fp) == NULL) {
+ if (feof(csinfo[cnumber].fr_fp))
+ errno = EIO;
+
+ cs_reading_emsg(cnumber);
+
+ return NULL;
+ }
+
+ /* If the line's too long for the buffer, discard it. */
+ if ((p = strchr(buf, '\n')) == NULL) {
+ while ((ch = getc(csinfo[cnumber].fr_fp)) != EOF && ch != '\n')
+ ;
+ return NULL;
+ }
+ *p = '\0';
+
+ /*
+ * cscope output is in the following format:
+ *
+ * <filename> <context> <line number> <pattern>
+ */
+ if ((name = strtok((char *)buf, (const char *)" ")) == NULL)
+ return NULL;
+ if ((*context = strtok(NULL, (const char *)" ")) == NULL)
+ return NULL;
+ if ((*linenumber = strtok(NULL, (const char *)" ")) == NULL)
+ return NULL;
+ *search = *linenumber + strlen(*linenumber) + 1; /* +1 to skip \0 */
+
+ /* --- nvi ---
+ * If the file is older than the cscope database, that is,
+ * the database was built since the file was last modified,
+ * or there wasn't a search string, use the line number.
+ */
+ if (strcmp(*search, "<unknown>") == 0)
+ *search = NULL;
+
+ name = cs_resolve_file(cnumber, name);
+ return name;
+}
+
+/*
+ * PRIVATE: cs_file_results
+ *
+ * write cscope find results to file
+ */
+static void cs_file_results(f, nummatches_a)
+FILE *f;
+int *nummatches_a;
+{
+ int i, j;
+ char *buf;
+ char *search, *slno;
+ char *fullname;
+ char *cntx;
+ char *context;
+
+ buf = (char *)alloc(CSREAD_BUFSIZE);
+ if (buf == NULL)
+ return;
+
+ for (i = 0; i < csinfo_size; i++) {
+ if (nummatches_a[i] < 1)
+ continue;
+
+ for (j = 0; j < nummatches_a[i]; j++) {
+ if ((fullname = cs_parse_results(i, buf, CSREAD_BUFSIZE, &cntx,
+ &slno, &search)) == NULL)
+ continue;
+
+ context = (char *)alloc((unsigned)strlen(cntx)+5);
+ if (context == NULL)
+ continue;
+
+ if (strcmp(cntx, "<global>")==0)
+ strcpy(context, "<<global>>");
+ else
+ sprintf(context, "<<%s>>", cntx);
+
+ if (search == NULL)
+ fprintf(f, "%s\t%s\t%s\n", fullname, slno, context);
+ else
+ fprintf(f, "%s\t%s\t%s %s\n", fullname, slno, context, search);
+
+ vim_free(context);
+ vim_free(fullname);
+ } /* for all matches */
+
+ (void)cs_read_prompt(i);
+
+ } /* for all cscope connections */
+ vim_free(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.
+ */
+static void cs_fill_results(tagstr, totmatches, nummatches_a, matches_p,
+ cntxts_p,
+ matched)
+char *tagstr;
+int totmatches;
+int *nummatches_a;
+char ***matches_p;
+char ***cntxts_p;
+int *matched;
+{
+ int i, j;
+ char *buf;
+ char *search, *slno;
+ int totsofar = 0;
+ char **matches = NULL;
+ char **cntxts = NULL;
+ char *fullname;
+ char *cntx;
+
+ assert(totmatches > 0);
+
+ buf = (char *)alloc(CSREAD_BUFSIZE);
+ if (buf == NULL)
+ return;
+
+ if ((matches = (char **)alloc(sizeof(char *) * totmatches)) == NULL)
+ goto parse_out;
+ if ((cntxts = (char **)alloc(sizeof(char *) * totmatches)) == NULL)
+ goto parse_out;
+
+ for (i = 0; i < csinfo_size; i++) {
+ if (nummatches_a[i] < 1)
+ continue;
+
+ for (j = 0; j < nummatches_a[i]; j++) {
+ if ((fullname = cs_parse_results(i, buf, CSREAD_BUFSIZE, &cntx,
+ &slno, &search)) == NULL)
+ continue;
+
+ matches[totsofar] = cs_make_vim_style_matches(fullname, slno,
+ search, tagstr);
+
+ vim_free(fullname);
+
+ if (strcmp(cntx, "<global>") == 0)
+ cntxts[totsofar] = NULL;
+ else
+ /* note: if vim_strsave returns NULL, then the context
+ * will be "<global>", which is misleading.
+ */
+ cntxts[totsofar] = (char *)vim_strsave((char_u *)cntx);
+
+ if (matches[totsofar] != NULL)
+ totsofar++;
+
+ } /* for all matches */
+
+ (void)cs_read_prompt(i);
+
+ } /* for all cscope connections */
+
+parse_out:
+ if (totsofar == 0) {
+ /* No matches, free the arrays and return NULL in "*matches_p". */
+ vim_free(matches);
+ matches = NULL;
+ vim_free(cntxts);
+ cntxts = NULL;
+ }
+ *matched = totsofar;
+ *matches_p = matches;
+ *cntxts_p = cntxts;
+
+ vim_free(buf);
+} /* cs_fill_results */
+
+
+/* get the requested path components */
+static char * cs_pathcomponents(path)
+char *path;
+{
+ int i;
+ char *s;
+
+ if (p_cspc == 0)
+ return path;
+
+ s = path + strlen(path) - 1;
+ for (i = 0; i < p_cspc; ++i)
+ while (s > path && *--s != '/'
+ )
+ ;
+ if ((s > path && *s == '/')
+ )
+ ++s;
+ return s;
+}
+
+/*
+ * PRIVATE: cs_print_tags_priv
+ *
+ * called from cs_manage_matches()
+ */
+static void cs_print_tags_priv(matches, cntxts, num_matches)
+char **matches;
+char **cntxts;
+int num_matches;
+{
+ char *buf = NULL;
+ int bufsize = 0; /* Track available bufsize */
+ int newsize = 0;
+ char *ptag;
+ char *fname, *lno, *extra, *tbuf;
+ int i, idx, num;
+ char *globalcntx = "GLOBAL";
+ char *cntxformat = " <<%s>>";
+ char *context;
+ char *cstag_msg = _("Cscope tag: %s");
+ char *csfmt_str = "%4d %6s ";
+
+ assert (num_matches > 0);
+
+ if ((tbuf = (char *)alloc((unsigned)strlen(matches[0]) + 1)) == NULL)
+ return;
+
+ strcpy(tbuf, matches[0]);
+ ptag = strtok(tbuf, "\t");
+
+ newsize = (int)(strlen(cstag_msg) + strlen(ptag));
+ buf = (char *)alloc(newsize);
+ if (buf != NULL) {
+ bufsize = newsize;
+ (void)sprintf(buf, cstag_msg, ptag);
+ MSG_PUTS_ATTR(buf, hl_attr(HLF_T));
+ }
+
+ vim_free(tbuf);
+
+ MSG_PUTS_ATTR(_("\n # line"), hl_attr(HLF_T)); /* strlen is 7 */
+ msg_advance(msg_col + 2);
+ MSG_PUTS_ATTR(_("filename / context / line\n"), hl_attr(HLF_T));
+
+ num = 1;
+ for (i = 0; i < num_matches; i++) {
+ idx = i;
+
+ /* if we really wanted to, we could avoid this malloc and strcpy
+ * by parsing matches[i] on the fly and placing stuff into buf
+ * directly, but that's too much of a hassle
+ */
+ if ((tbuf = (char *)alloc((unsigned)strlen(matches[idx]) + 1)) == NULL)
+ continue;
+ (void)strcpy(tbuf, matches[idx]);
+
+ if (strtok(tbuf, (const char *)"\t") == NULL)
+ continue;
+ if ((fname = strtok(NULL, (const char *)"\t")) == NULL)
+ continue;
+ if ((lno = strtok(NULL, (const char *)"\t")) == NULL)
+ continue;
+ extra = strtok(NULL, (const char *)"\t");
+
+ lno[strlen(lno)-2] = '\0'; /* ignore ;" at the end */
+
+ /* hopefully 'num' (num of matches) will be less than 10^16 */
+ newsize = (int)(strlen(csfmt_str) + 16 + strlen(lno));
+ if (bufsize < newsize) {
+ buf = (char *)vim_realloc(buf, newsize);
+ if (buf == NULL)
+ bufsize = 0;
+ else
+ bufsize = newsize;
+ }
+ if (buf != NULL) {
+ /* csfmt_str = "%4d %6s "; */
+ (void)sprintf(buf, csfmt_str, num, lno);
+ 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 */
+ if (cntxts[idx] != NULL)
+ context = cntxts[idx];
+ else
+ context = globalcntx;
+ newsize = (int)(strlen(context) + strlen(cntxformat));
+
+ if (bufsize < newsize) {
+ buf = (char *)vim_realloc(buf, newsize);
+ if (buf == NULL)
+ bufsize = 0;
+ else
+ bufsize = newsize;
+ }
+ if (buf != NULL) {
+ (void)sprintf(buf, cntxformat, context);
+
+ /* print the context only if it fits on the same line */
+ if (msg_col + (int)strlen(buf) >= (int)Columns)
+ msg_putchar('\n');
+ msg_advance(12);
+ MSG_PUTS_LONG(buf);
+ msg_putchar('\n');
+ }
+ if (extra != NULL) {
+ msg_advance(13);
+ MSG_PUTS_LONG(extra);
+ }
+
+ vim_free(tbuf); /* only after printing extra due to strtok use */
+
+ if (msg_col)
+ msg_putchar('\n');
+
+ ui_breakcheck();
+ if (got_int) {
+ got_int = FALSE; /* don't print any more matches */
+ break;
+ }
+
+ num++;
+ } /* for all matches */
+
+ vim_free(buf);
+} /* cs_print_tags_priv */
+
+
+/*
+ * PRIVATE: cs_read_prompt
+ *
+ * read a cscope prompt (basically, skip over the ">> ")
+ */
+static int cs_read_prompt(i)
+int i;
+{
+ int ch;
+ char *buf = NULL; /* buffer for possible error message from cscope */
+ int bufpos = 0;
+ char *cs_emsg;
+ int maxlen;
+ static char *eprompt = "Press the RETURN key to continue:";
+ int epromptlen = (int)strlen(eprompt);
+ int n;
+
+ cs_emsg = _("E609: Cscope error: %s");
+ /* compute maximum allowed len for Cscope error message */
+ maxlen = (int)(IOSIZE - strlen(cs_emsg));
+
+ for (;; ) {
+ while ((ch = getc(csinfo[i].fr_fp)) != EOF && ch != CSCOPE_PROMPT[0])
+ /* if there is room and char is printable */
+ if (bufpos < maxlen - 1 && vim_isprintc(ch)) {
+ if (buf == NULL) /* lazy buffer allocation */
+ buf = (char *)alloc(maxlen);
+ if (buf != NULL) {
+ /* 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);
+
+ /* send RETURN to cscope */
+ (void)putc('\n', csinfo[i].to_fp);
+ (void)fflush(csinfo[i].to_fp);
+
+ /* clear buf */
+ bufpos = 0;
+ buf[bufpos] = NUL;
+ }
+ }
+ }
+
+ for (n = 0; n < (int)strlen(CSCOPE_PROMPT); ++n) {
+ if (n > 0)
+ ch = getc(csinfo[i].fr_fp);
+ if (ch == EOF) {
+ PERROR("cs_read_prompt EOF");
+ if (buf != NULL && buf[0] != NUL)
+ (void)EMSG2(cs_emsg, buf);
+ else if (p_csverbose)
+ cs_reading_emsg(i); /* don't have additional information */
+ cs_release_csp(i, TRUE);
+ vim_free(buf);
+ return CSCOPE_FAILURE;
+ }
+
+ if (ch != CSCOPE_PROMPT[n]) {
+ ch = EOF;
+ break;
+ }
+ }
+
+ if (ch == EOF)
+ continue; /* didn't find the prompt */
+ break; /* did find the prompt */
+ }
+
+ vim_free(buf);
+ return CSCOPE_SUCCESS;
+}
+
+#if defined(UNIX) && defined(SIGALRM)
+/*
+ * Used to catch and ignore SIGALRM below.
+ */
+static RETSIGTYPE
+sig_handler SIGDEFARG(sigarg) {
+ /* do nothing */
+ SIGRETURN;
+}
+
+#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.
+ */
+static void cs_release_csp(i, freefnpp)
+int i;
+int freefnpp;
+{
+ /*
+ * Trying to exit normally (not sure whether it is fit to UNIX cscope
+ */
+ if (csinfo[i].to_fp != NULL) {
+ (void)fputs("q\n", csinfo[i].to_fp);
+ (void)fflush(csinfo[i].to_fp);
+ }
+#if defined(UNIX)
+ {
+ int waitpid_errno;
+ int pstat;
+ pid_t pid;
+
+# if defined(HAVE_SIGACTION)
+ struct sigaction sa, old;
+
+ /* Use sigaction() to limit the waiting time to two seconds. */
+ sigemptyset(&sa.sa_mask);
+ sa.sa_handler = sig_handler;
+# ifdef SA_NODEFER
+ sa.sa_flags = SA_NODEFER;
+# else
+ sa.sa_flags = 0;
+# endif
+ sigaction(SIGALRM, &sa, &old);
+ alarm(2); /* 2 sec timeout */
+
+ /* Block until cscope exits or until timer expires */
+ pid = waitpid(csinfo[i].pid, &pstat, 0);
+ waitpid_errno = errno;
+
+ /* cancel pending alarm if still there and restore signal */
+ alarm(0);
+ sigaction(SIGALRM, &old, NULL);
+# else
+ int waited;
+
+ /* Can't use sigaction(), loop for two seconds. First yield the CPU
+ * to give cscope a chance to exit quickly. */
+ sleep(0);
+ for (waited = 0; waited < 40; ++waited) {
+ pid = waitpid(csinfo[i].pid, &pstat, WNOHANG);
+ waitpid_errno = errno;
+ if (pid != 0)
+ break; /* break unless the process is still running */
+ mch_delay(50L, FALSE); /* sleep 50 ms */
+ }
+# endif
+ /*
+ * If the cscope process is still running: kill it.
+ * Safety check: If the PID would be zero here, the entire X session
+ * would be killed. -1 and 1 are dangerous as well.
+ */
+ if (pid < 0 && csinfo[i].pid > 1) {
+# ifdef ECHILD
+ int alive = TRUE;
+
+ if (waitpid_errno == ECHILD) {
+ /*
+ * When using 'vim -g', vim is forked and cscope process is
+ * no longer a child process but a sibling. So waitpid()
+ * fails with errno being ECHILD (No child processes).
+ * Don't send SIGKILL to cscope immediately but wait
+ * (polling) for it to exit normally as result of sending
+ * the "q" command, hence giving it a chance to clean up
+ * its temporary files.
+ */
+ int waited;
+
+ sleep(0);
+ for (waited = 0; waited < 40; ++waited) {
+ /* Check whether cscope process is still alive */
+ if (kill(csinfo[i].pid, 0) != 0) {
+ alive = FALSE; /* cscope process no longer exists */
+ break;
+ }
+ mch_delay(50L, FALSE); /* sleep 50ms */
+ }
+ }
+ if (alive)
+# endif
+ {
+ kill(csinfo[i].pid, SIGKILL);
+ (void)waitpid(csinfo[i].pid, &pstat, 0);
+ }
+ }
+ }
+#else /* !UNIX */
+ if (csinfo[i].hProc != NULL) {
+ /* Give cscope a chance to exit normally */
+ if (WaitForSingleObject(csinfo[i].hProc, 1000) == WAIT_TIMEOUT)
+ TerminateProcess(csinfo[i].hProc, 0);
+ CloseHandle(csinfo[i].hProc);
+ }
+#endif
+
+ if (csinfo[i].fr_fp != NULL)
+ (void)fclose(csinfo[i].fr_fp);
+ if (csinfo[i].to_fp != NULL)
+ (void)fclose(csinfo[i].to_fp);
+
+ if (freefnpp) {
+ vim_free(csinfo[i].fname);
+ vim_free(csinfo[i].ppath);
+ vim_free(csinfo[i].flags);
+ }
+
+ clear_csinfo(i);
+} /* cs_release_csp */
+
+
+/*
+ * PRIVATE: cs_reset
+ *
+ * calls cs_kill on all cscope connections then reinits
+ */
+static int cs_reset(eap)
+exarg_T *eap UNUSED;
+{
+ char **dblist = NULL, **pplist = NULL, **fllist = NULL;
+ int i;
+ char buf[20]; /* for sprintf " (#%d)" */
+
+ if (csinfo_size == 0)
+ return CSCOPE_SUCCESS;
+
+ /* malloc our db and ppath list */
+ dblist = (char **)alloc(csinfo_size * sizeof(char *));
+ pplist = (char **)alloc(csinfo_size * sizeof(char *));
+ fllist = (char **)alloc(csinfo_size * sizeof(char *));
+ if (dblist == NULL || pplist == NULL || fllist == NULL) {
+ vim_free(dblist);
+ vim_free(pplist);
+ vim_free(fllist);
+ return CSCOPE_FAILURE;
+ }
+
+ for (i = 0; i < csinfo_size; i++) {
+ dblist[i] = csinfo[i].fname;
+ pplist[i] = csinfo[i].ppath;
+ fllist[i] = csinfo[i].flags;
+ if (csinfo[i].fname != NULL)
+ cs_release_csp(i, FALSE);
+ }
+
+ /* rebuild the cscope connection list */
+ for (i = 0; i < csinfo_size; i++) {
+ if (dblist[i] != NULL) {
+ cs_add_common(dblist[i], pplist[i], fllist[i]);
+ if (p_csverbose) {
+ /* don't use smsg_attr() because we want to display the
+ * connection number in the same line as
+ * "Added cscope database..."
+ */
+ sprintf(buf, " (#%d)", i);
+ MSG_PUTS_ATTR(buf, hl_attr(HLF_R));
+ }
+ }
+ vim_free(dblist[i]);
+ vim_free(pplist[i]);
+ vim_free(fllist[i]);
+ }
+ vim_free(dblist);
+ vim_free(pplist);
+ vim_free(fllist);
+
+ 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.
+ */
+static char * cs_resolve_file(i, name)
+int i;
+char *name;
+{
+ char *fullname;
+ int len;
+ char_u *csdir = NULL;
+
+ /*
+ * Ppath is freed when we destroy the cscope connection.
+ * Fullname is freed after cs_make_vim_style_matches, after it's been
+ * copied into the tag buffer used by Vim.
+ */
+ len = (int)(strlen(name) + 2);
+ if (csinfo[i].ppath != NULL)
+ len += (int)strlen(csinfo[i].ppath);
+ else if (p_csre && csinfo[i].fname != NULL) {
+ /* If 'cscoperelative' is set and ppath is not set, use cscope.out
+ * path in path resolution. */
+ csdir = alloc(MAXPATHL);
+ if (csdir != NULL) {
+ vim_strncpy(csdir, (char_u *)csinfo[i].fname,
+ gettail((char_u *)csinfo[i].fname)
+ - (char_u *)csinfo[i].fname);
+ len += (int)STRLEN(csdir);
+ }
+ }
+
+ /* Note/example: this won't work if the cscope output already starts
+ * "../.." and the prefix path is also "../..". if something like this
+ * happens, you are screwed up and need to fix how you're using cscope. */
+ if (csinfo[i].ppath != NULL
+ && (strncmp(name, csinfo[i].ppath, strlen(csinfo[i].ppath)) != 0)
+ && (name[0] != '/')
+ ) {
+ if ((fullname = (char *)alloc(len)) != NULL)
+ (void)sprintf(fullname, "%s/%s", csinfo[i].ppath, name);
+ } else if (csdir != NULL && csinfo[i].fname != NULL && *csdir != NUL) {
+ /* Check for csdir to be non empty to avoid empty path concatenated to
+ * cscope output. */
+ fullname = (char *)concat_fnames(csdir, (char_u *)name, TRUE);
+ } else {
+ fullname = (char *)vim_strsave((char_u *)name);
+ }
+
+ vim_free(csdir);
+ return fullname;
+}
+
+
+/*
+ * PRIVATE: cs_show
+ *
+ * show all cscope connections
+ */
+static int cs_show(eap)
+exarg_T *eap UNUSED;
+{
+ short i;
+ if (cs_cnt_connections() == 0)
+ MSG_PUTS(_("no cscope connections\n"));
+ else {
+ MSG_PUTS_ATTR(
+ _(" # pid database name prepend path\n"),
+ hl_attr(HLF_T));
+ for (i = 0; i < csinfo_size; i++) {
+ if (csinfo[i].fname == NULL)
+ continue;
+
+ if (csinfo[i].ppath != NULL)
+ (void)smsg((char_u *)"%2d %-5ld %-34s %-32s",
+ i, (long)csinfo[i].pid, csinfo[i].fname, csinfo[i].ppath);
+ else
+ (void)smsg((char_u *)"%2d %-5ld %-34s <none>",
+ i, (long)csinfo[i].pid, csinfo[i].fname);
+ }
+ }
+
+ wait_return(TRUE);
+ return CSCOPE_SUCCESS;
+} /* cs_show */
+
+
+/*
+ * PUBLIC: cs_end
+ *
+ * Only called when VIM exits to quit any cscope sessions.
+ */
+void cs_end() {
+ int i;
+
+ for (i = 0; i < csinfo_size; i++)
+ cs_release_csp(i, TRUE);
+ vim_free(csinfo);
+ csinfo_size = 0;
+}
+
+/* the end */
diff --git a/src/if_cscope.h b/src/if_cscope.h
new file mode 100644
index 0000000000..3ed89715fc
--- /dev/null
+++ b/src/if_cscope.h
@@ -0,0 +1,72 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * CSCOPE support for Vim added by Andy Kahn <kahn@zk3.dec.com>
+ * Ported to Win32 by Sergey Khorev <sergey.khorev@gmail.com>
+ *
+ * The basic idea/structure of cscope for Vim was borrowed from Nvi.
+ * There might be a few lines of code that look similar to what Nvi
+ * has. If this is a problem and requires inclusion of the annoying
+ * BSD license, then sue me; I'm not worth much anyway.
+ */
+
+
+#if defined(UNIX)
+# include <sys/types.h> /* pid_t */
+# include <sys/stat.h> /* dev_t, ino_t */
+#else
+#endif
+
+#define CSCOPE_SUCCESS 0
+#define CSCOPE_FAILURE -1
+
+#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
+ */
+
+typedef struct {
+ char * name;
+ int (*func)__ARGS((exarg_T *eap));
+ char * help;
+ char * usage;
+ int cansplit; /* if supports splitting window */
+} cscmd_T;
+
+typedef struct csi {
+ char * fname; /* cscope db name */
+ char * ppath; /* path to prepend (the -P option) */
+ char * flags; /* additional cscope flags/options (e.g, -p2) */
+#if defined(UNIX)
+ pid_t pid; /* PID of the connected cscope process. */
+ dev_t st_dev; /* ID of dev containing cscope db */
+ ino_t st_ino; /* inode number of cscope db */
+#else
+#endif
+
+ FILE * fr_fp; /* from cscope: FILE. */
+ FILE * to_fp; /* to cscope: FILE. */
+} csinfo_T;
+
+typedef enum { Add, Find, Help, Kill, Reset, Show } csid_e;
+
+typedef enum {
+ Store,
+ Get,
+ Free,
+ Print
+} mcmd_e;
+
+
+
+/* the end */
diff --git a/src/keymap.h b/src/keymap.h
new file mode 100644
index 0000000000..766413c30c
--- /dev/null
+++ b/src/keymap.h
@@ -0,0 +1,499 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * 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.
+ */
+
+/*
+ * Keycode definitions for special keys.
+ *
+ * Any special key code sequences are replaced by these codes.
+ */
+
+/*
+ * For MSDOS some keys produce codes larger than 0xff. They are split into two
+ * chars, the first one is K_NUL (same value used in term.h).
+ */
+#define K_NUL (0xce) /* for MSDOS: special key follows */
+
+/*
+ * K_SPECIAL is the first byte of a special key code and is always followed by
+ * two bytes.
+ * The second byte can have any value. ASCII is used for normal termcap
+ * entries, 0x80 and higher for special keys, see below.
+ * The third byte is guaranteed to be between 0x02 and 0x7f.
+ */
+
+#define K_SPECIAL (0x80)
+
+/*
+ * Positive characters are "normal" characters.
+ * Negative characters are special key codes. Only characters below -0x200
+ * are used to so that the absolute value can't be mistaken for a single-byte
+ * character.
+ */
+#define IS_SPECIAL(c) ((c) < 0)
+
+/*
+ * Characters 0x0100 - 0x01ff have a special meaning for abbreviations.
+ * Multi-byte characters also have ABBR_OFF added, thus are above 0x0200.
+ */
+#define ABBR_OFF 0x100
+
+/*
+ * NUL cannot be in the input string, therefore it is replaced by
+ * K_SPECIAL KS_ZERO KE_FILLER
+ */
+#define KS_ZERO 255
+
+/*
+ * K_SPECIAL cannot be in the input string, therefore it is replaced by
+ * K_SPECIAL KS_SPECIAL KE_FILLER
+ */
+#define KS_SPECIAL 254
+
+/*
+ * KS_EXTRA is used for keys that have no termcap name
+ * K_SPECIAL KS_EXTRA KE_xxx
+ */
+#define KS_EXTRA 253
+
+/*
+ * KS_MODIFIER is used when a modifier is given for a (special) key
+ * K_SPECIAL KS_MODIFIER bitmask
+ */
+#define KS_MODIFIER 252
+
+/*
+ * These are used for the GUI
+ * K_SPECIAL KS_xxx KE_FILLER
+ */
+#define KS_MOUSE 251
+#define KS_MENU 250
+#define KS_VER_SCROLLBAR 249
+#define KS_HOR_SCROLLBAR 248
+
+/*
+ * These are used for DEC mouse
+ */
+#define KS_NETTERM_MOUSE 247
+#define KS_DEC_MOUSE 246
+
+/*
+ * Used for switching Select mode back on after a mapping or menu.
+ */
+#define KS_SELECT 245
+#define K_SELECT_STRING (char_u *)"\200\365X"
+
+/*
+ * Used for tearing off a menu.
+ */
+#define KS_TEAROFF 244
+
+/* Used for JSB term mouse. */
+#define KS_JSBTERM_MOUSE 243
+
+/* Used a termcap entry that produces a normal character. */
+#define KS_KEY 242
+
+/* Used for the qnx pterm mouse. */
+#define KS_PTERM_MOUSE 241
+
+/* Used for click in a tab pages label. */
+#define KS_TABLINE 240
+
+/* Used for menu in a tab pages line. */
+#define KS_TABMENU 239
+
+/* Used for the urxvt mouse. */
+#define KS_URXVT_MOUSE 238
+
+/* Used for the sgr mouse. */
+#define KS_SGR_MOUSE 237
+
+/*
+ * Filler used after KS_SPECIAL and others
+ */
+#define KE_FILLER ('X')
+
+/*
+ * translation of three byte code "K_SPECIAL a b" into int "K_xxx" and back
+ */
+#define TERMCAP2KEY(a, b) (-((a) + ((int)(b) << 8)))
+#define KEY2TERMCAP0(x) ((-(x)) & 0xff)
+#define KEY2TERMCAP1(x) (((unsigned)(-(x)) >> 8) & 0xff)
+
+/*
+ * get second or third byte when translating special key code into three bytes
+ */
+#define K_SECOND(c) ((c) == K_SPECIAL ? KS_SPECIAL : (c) == \
+ NUL ? KS_ZERO : KEY2TERMCAP0(c))
+
+#define K_THIRD(c) (((c) == K_SPECIAL || (c) == \
+ NUL) ? KE_FILLER : KEY2TERMCAP1(c))
+
+/*
+ * get single int code from second byte after K_SPECIAL
+ */
+#define TO_SPECIAL(a, b) ((a) == KS_SPECIAL ? K_SPECIAL : (a) == \
+ KS_ZERO ? K_ZERO : TERMCAP2KEY(a, b))
+
+/*
+ * Codes for keys that do not have a termcap name.
+ *
+ * K_SPECIAL KS_EXTRA KE_xxx
+ */
+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_SNIFF /* SNiFF+ input waiting */
+
+ , 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_CURSORHOLD /* CursorHold event */
+ , KE_NOP /* doesn't do something */
+ , KE_FOCUSGAINED /* focus gained */
+ , KE_FOCUSLOST /* focus lost */
+};
+
+/*
+ * the three byte codes are replaced with the following int when using vgetc()
+ */
+#define K_ZERO TERMCAP2KEY(KS_ZERO, KE_FILLER)
+
+#define K_UP TERMCAP2KEY('k', 'u')
+#define K_DOWN TERMCAP2KEY('k', 'd')
+#define K_LEFT TERMCAP2KEY('k', 'l')
+#define K_RIGHT TERMCAP2KEY('k', 'r')
+#define K_S_UP TERMCAP2KEY(KS_EXTRA, KE_S_UP)
+#define K_S_DOWN TERMCAP2KEY(KS_EXTRA, KE_S_DOWN)
+#define K_S_LEFT TERMCAP2KEY('#', '4')
+#define K_C_LEFT TERMCAP2KEY(KS_EXTRA, KE_C_LEFT)
+#define K_S_RIGHT TERMCAP2KEY('%', 'i')
+#define K_C_RIGHT TERMCAP2KEY(KS_EXTRA, KE_C_RIGHT)
+#define K_S_HOME TERMCAP2KEY('#', '2')
+#define K_C_HOME TERMCAP2KEY(KS_EXTRA, KE_C_HOME)
+#define K_S_END TERMCAP2KEY('*', '7')
+#define K_C_END TERMCAP2KEY(KS_EXTRA, KE_C_END)
+#define K_TAB TERMCAP2KEY(KS_EXTRA, KE_TAB)
+#define K_S_TAB TERMCAP2KEY('k', 'B')
+
+/* extra set of function keys F1-F4, for vt100 compatible xterm */
+#define K_XF1 TERMCAP2KEY(KS_EXTRA, KE_XF1)
+#define K_XF2 TERMCAP2KEY(KS_EXTRA, KE_XF2)
+#define K_XF3 TERMCAP2KEY(KS_EXTRA, KE_XF3)
+#define K_XF4 TERMCAP2KEY(KS_EXTRA, KE_XF4)
+
+/* extra set of cursor keys for vt100 compatible xterm */
+#define K_XUP TERMCAP2KEY(KS_EXTRA, KE_XUP)
+#define K_XDOWN TERMCAP2KEY(KS_EXTRA, KE_XDOWN)
+#define K_XLEFT TERMCAP2KEY(KS_EXTRA, KE_XLEFT)
+#define K_XRIGHT TERMCAP2KEY(KS_EXTRA, KE_XRIGHT)
+
+#define K_F1 TERMCAP2KEY('k', '1') /* function keys */
+#define K_F2 TERMCAP2KEY('k', '2')
+#define K_F3 TERMCAP2KEY('k', '3')
+#define K_F4 TERMCAP2KEY('k', '4')
+#define K_F5 TERMCAP2KEY('k', '5')
+#define K_F6 TERMCAP2KEY('k', '6')
+#define K_F7 TERMCAP2KEY('k', '7')
+#define K_F8 TERMCAP2KEY('k', '8')
+#define K_F9 TERMCAP2KEY('k', '9')
+#define K_F10 TERMCAP2KEY('k', ';')
+
+#define K_F11 TERMCAP2KEY('F', '1')
+#define K_F12 TERMCAP2KEY('F', '2')
+#define K_F13 TERMCAP2KEY('F', '3')
+#define K_F14 TERMCAP2KEY('F', '4')
+#define K_F15 TERMCAP2KEY('F', '5')
+#define K_F16 TERMCAP2KEY('F', '6')
+#define K_F17 TERMCAP2KEY('F', '7')
+#define K_F18 TERMCAP2KEY('F', '8')
+#define K_F19 TERMCAP2KEY('F', '9')
+#define K_F20 TERMCAP2KEY('F', 'A')
+
+#define K_F21 TERMCAP2KEY('F', 'B')
+#define K_F22 TERMCAP2KEY('F', 'C')
+#define K_F23 TERMCAP2KEY('F', 'D')
+#define K_F24 TERMCAP2KEY('F', 'E')
+#define K_F25 TERMCAP2KEY('F', 'F')
+#define K_F26 TERMCAP2KEY('F', 'G')
+#define K_F27 TERMCAP2KEY('F', 'H')
+#define K_F28 TERMCAP2KEY('F', 'I')
+#define K_F29 TERMCAP2KEY('F', 'J')
+#define K_F30 TERMCAP2KEY('F', 'K')
+
+#define K_F31 TERMCAP2KEY('F', 'L')
+#define K_F32 TERMCAP2KEY('F', 'M')
+#define K_F33 TERMCAP2KEY('F', 'N')
+#define K_F34 TERMCAP2KEY('F', 'O')
+#define K_F35 TERMCAP2KEY('F', 'P')
+#define K_F36 TERMCAP2KEY('F', 'Q')
+#define K_F37 TERMCAP2KEY('F', 'R')
+
+/* extra set of shifted function keys F1-F4, for vt100 compatible xterm */
+#define K_S_XF1 TERMCAP2KEY(KS_EXTRA, KE_S_XF1)
+#define K_S_XF2 TERMCAP2KEY(KS_EXTRA, KE_S_XF2)
+#define K_S_XF3 TERMCAP2KEY(KS_EXTRA, KE_S_XF3)
+#define K_S_XF4 TERMCAP2KEY(KS_EXTRA, KE_S_XF4)
+
+#define K_S_F1 TERMCAP2KEY(KS_EXTRA, KE_S_F1) /* shifted func. keys */
+#define K_S_F2 TERMCAP2KEY(KS_EXTRA, KE_S_F2)
+#define K_S_F3 TERMCAP2KEY(KS_EXTRA, KE_S_F3)
+#define K_S_F4 TERMCAP2KEY(KS_EXTRA, KE_S_F4)
+#define K_S_F5 TERMCAP2KEY(KS_EXTRA, KE_S_F5)
+#define K_S_F6 TERMCAP2KEY(KS_EXTRA, KE_S_F6)
+#define K_S_F7 TERMCAP2KEY(KS_EXTRA, KE_S_F7)
+#define K_S_F8 TERMCAP2KEY(KS_EXTRA, KE_S_F8)
+#define K_S_F9 TERMCAP2KEY(KS_EXTRA, KE_S_F9)
+#define K_S_F10 TERMCAP2KEY(KS_EXTRA, KE_S_F10)
+
+#define K_S_F11 TERMCAP2KEY(KS_EXTRA, KE_S_F11)
+#define K_S_F12 TERMCAP2KEY(KS_EXTRA, KE_S_F12)
+/* K_S_F13 to K_S_F37 are currently not used */
+
+#define K_HELP TERMCAP2KEY('%', '1')
+#define K_UNDO TERMCAP2KEY('&', '8')
+
+#define K_BS TERMCAP2KEY('k', 'b')
+
+#define K_INS TERMCAP2KEY('k', 'I')
+#define K_KINS TERMCAP2KEY(KS_EXTRA, KE_KINS)
+#define K_DEL TERMCAP2KEY('k', 'D')
+#define K_KDEL TERMCAP2KEY(KS_EXTRA, KE_KDEL)
+#define K_HOME TERMCAP2KEY('k', 'h')
+#define K_KHOME TERMCAP2KEY('K', '1') /* keypad home (upper left) */
+#define K_XHOME TERMCAP2KEY(KS_EXTRA, KE_XHOME)
+#define K_ZHOME TERMCAP2KEY(KS_EXTRA, KE_ZHOME)
+#define K_END TERMCAP2KEY('@', '7')
+#define K_KEND TERMCAP2KEY('K', '4') /* keypad end (lower left) */
+#define K_XEND TERMCAP2KEY(KS_EXTRA, KE_XEND)
+#define K_ZEND TERMCAP2KEY(KS_EXTRA, KE_ZEND)
+#define K_PAGEUP TERMCAP2KEY('k', 'P')
+#define K_PAGEDOWN TERMCAP2KEY('k', 'N')
+#define K_KPAGEUP TERMCAP2KEY('K', '3') /* keypad pageup (upper R.) */
+#define K_KPAGEDOWN TERMCAP2KEY('K', '5') /* keypad pagedown (lower R.) */
+
+#define K_KPLUS TERMCAP2KEY('K', '6') /* keypad plus */
+#define K_KMINUS TERMCAP2KEY('K', '7') /* keypad minus */
+#define K_KDIVIDE TERMCAP2KEY('K', '8') /* keypad / */
+#define K_KMULTIPLY TERMCAP2KEY('K', '9') /* keypad * */
+#define K_KENTER TERMCAP2KEY('K', 'A') /* keypad Enter */
+#define K_KPOINT TERMCAP2KEY('K', 'B') /* keypad . or ,*/
+
+#define K_K0 TERMCAP2KEY('K', 'C') /* keypad 0 */
+#define K_K1 TERMCAP2KEY('K', 'D') /* keypad 1 */
+#define K_K2 TERMCAP2KEY('K', 'E') /* keypad 2 */
+#define K_K3 TERMCAP2KEY('K', 'F') /* keypad 3 */
+#define K_K4 TERMCAP2KEY('K', 'G') /* keypad 4 */
+#define K_K5 TERMCAP2KEY('K', 'H') /* keypad 5 */
+#define K_K6 TERMCAP2KEY('K', 'I') /* keypad 6 */
+#define K_K7 TERMCAP2KEY('K', 'J') /* keypad 7 */
+#define K_K8 TERMCAP2KEY('K', 'K') /* keypad 8 */
+#define K_K9 TERMCAP2KEY('K', 'L') /* keypad 9 */
+
+#define K_MOUSE TERMCAP2KEY(KS_MOUSE, KE_FILLER)
+#define K_MENU TERMCAP2KEY(KS_MENU, KE_FILLER)
+#define K_VER_SCROLLBAR TERMCAP2KEY(KS_VER_SCROLLBAR, KE_FILLER)
+#define K_HOR_SCROLLBAR TERMCAP2KEY(KS_HOR_SCROLLBAR, KE_FILLER)
+
+#define K_NETTERM_MOUSE TERMCAP2KEY(KS_NETTERM_MOUSE, KE_FILLER)
+#define K_DEC_MOUSE TERMCAP2KEY(KS_DEC_MOUSE, KE_FILLER)
+#define K_JSBTERM_MOUSE TERMCAP2KEY(KS_JSBTERM_MOUSE, KE_FILLER)
+#define K_PTERM_MOUSE TERMCAP2KEY(KS_PTERM_MOUSE, KE_FILLER)
+#define K_URXVT_MOUSE TERMCAP2KEY(KS_URXVT_MOUSE, KE_FILLER)
+#define K_SGR_MOUSE TERMCAP2KEY(KS_SGR_MOUSE, KE_FILLER)
+
+#define K_SELECT TERMCAP2KEY(KS_SELECT, KE_FILLER)
+#define K_TEAROFF TERMCAP2KEY(KS_TEAROFF, KE_FILLER)
+
+#define K_TABLINE TERMCAP2KEY(KS_TABLINE, KE_FILLER)
+#define K_TABMENU TERMCAP2KEY(KS_TABMENU, KE_FILLER)
+
+/*
+ * Symbols for pseudo keys which are translated from the real key symbols
+ * above.
+ */
+#define K_LEFTMOUSE TERMCAP2KEY(KS_EXTRA, KE_LEFTMOUSE)
+#define K_LEFTMOUSE_NM TERMCAP2KEY(KS_EXTRA, KE_LEFTMOUSE_NM)
+#define K_LEFTDRAG TERMCAP2KEY(KS_EXTRA, KE_LEFTDRAG)
+#define K_LEFTRELEASE TERMCAP2KEY(KS_EXTRA, KE_LEFTRELEASE)
+#define K_LEFTRELEASE_NM TERMCAP2KEY(KS_EXTRA, KE_LEFTRELEASE_NM)
+#define K_MIDDLEMOUSE TERMCAP2KEY(KS_EXTRA, KE_MIDDLEMOUSE)
+#define K_MIDDLEDRAG TERMCAP2KEY(KS_EXTRA, KE_MIDDLEDRAG)
+#define K_MIDDLERELEASE TERMCAP2KEY(KS_EXTRA, KE_MIDDLERELEASE)
+#define K_RIGHTMOUSE TERMCAP2KEY(KS_EXTRA, KE_RIGHTMOUSE)
+#define K_RIGHTDRAG TERMCAP2KEY(KS_EXTRA, KE_RIGHTDRAG)
+#define K_RIGHTRELEASE TERMCAP2KEY(KS_EXTRA, KE_RIGHTRELEASE)
+#define K_X1MOUSE TERMCAP2KEY(KS_EXTRA, KE_X1MOUSE)
+#define K_X1MOUSE TERMCAP2KEY(KS_EXTRA, KE_X1MOUSE)
+#define K_X1DRAG TERMCAP2KEY(KS_EXTRA, KE_X1DRAG)
+#define K_X1RELEASE TERMCAP2KEY(KS_EXTRA, KE_X1RELEASE)
+#define K_X2MOUSE TERMCAP2KEY(KS_EXTRA, KE_X2MOUSE)
+#define K_X2DRAG TERMCAP2KEY(KS_EXTRA, KE_X2DRAG)
+#define K_X2RELEASE TERMCAP2KEY(KS_EXTRA, KE_X2RELEASE)
+
+#define K_IGNORE TERMCAP2KEY(KS_EXTRA, KE_IGNORE)
+#define K_NOP TERMCAP2KEY(KS_EXTRA, KE_NOP)
+
+#define K_SNIFF TERMCAP2KEY(KS_EXTRA, KE_SNIFF)
+
+#define K_MOUSEDOWN TERMCAP2KEY(KS_EXTRA, KE_MOUSEDOWN)
+#define K_MOUSEUP TERMCAP2KEY(KS_EXTRA, KE_MOUSEUP)
+#define K_MOUSELEFT TERMCAP2KEY(KS_EXTRA, KE_MOUSELEFT)
+#define K_MOUSERIGHT TERMCAP2KEY(KS_EXTRA, KE_MOUSERIGHT)
+
+#define K_CSI TERMCAP2KEY(KS_EXTRA, KE_CSI)
+#define K_SNR TERMCAP2KEY(KS_EXTRA, KE_SNR)
+#define K_PLUG TERMCAP2KEY(KS_EXTRA, KE_PLUG)
+#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_CURSORHOLD TERMCAP2KEY(KS_EXTRA, KE_CURSORHOLD)
+
+/* Bits for modifier mask */
+/* 0x01 cannot be used, because the modifier must be 0x02 or higher */
+#define MOD_MASK_SHIFT 0x02
+#define MOD_MASK_CTRL 0x04
+#define MOD_MASK_ALT 0x08 /* aka META */
+#define MOD_MASK_META 0x10 /* META when it's different from ALT */
+#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_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 '>').
+ */
+#define MAX_KEY_NAME_LEN 25
+
+/* 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
+ * following string of tokens:
+ *
+ * <K_SPECIAL> <KS_MODIFIER> bitmask <K_SPECIAL> <KS_EXTRA> <KT_LEFTDRAG>.
+ *
+ * This is a total of 6 tokens, and is currently the longest one possible.
+ */
+#define MAX_KEY_CODE_LEN 6
diff --git a/src/macros.h b/src/macros.h
new file mode 100644
index 0000000000..db68b8a11d
--- /dev/null
+++ b/src/macros.h
@@ -0,0 +1,190 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * 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.
+ */
+
+/*
+ * macros.h: macro definitions for often used code
+ */
+
+/*
+ * pchar(lp, c) - put character 'c' at position 'lp'
+ */
+#define pchar(lp, c) (*(ml_get_buf(curbuf, (lp).lnum, TRUE) + (lp).col) = (c))
+
+/*
+ * 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))
+
+/*
+ * 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) == \
+ NUL)
+
+/*
+ * toupper() and tolower() that use the current locale.
+ * On some systems toupper()/tolower() only work on lower/uppercase
+ * characters, first use islower() or isupper() then.
+ * 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 MB_TOLOWER() and MB_TOUPPER(), because many
+ * toupper() and tolower() implementations only work for ASCII.
+ */
+# ifdef BROKEN_TOUPPER
+# define TOUPPER_LOC(c) (islower(c) ? toupper(c) : (c))
+# define TOLOWER_LOC(c) (isupper(c) ? tolower(c) : (c))
+# else
+# define TOUPPER_LOC toupper
+# define TOLOWER_LOC tolower
+# endif
+
+/* toupper() and tolower() for ASCII only and ignore the current locale. */
+# define TOUPPER_ASC(c) (((c) < 'a' || (c) > 'z') ? (c) : (c) - ('a' - 'A'))
+# define TOLOWER_ASC(c) (((c) < 'A' || (c) > 'Z') ? (c) : (c) + ('a' - 'A'))
+
+/*
+ * MB_ISLOWER() and MB_ISUPPER() are to be used on multi-byte characters. But
+ * don't use them for negative values!
+ */
+# define MB_ISLOWER(c) vim_islower(c)
+# define MB_ISUPPER(c) vim_isupper(c)
+# define MB_TOLOWER(c) vim_tolower(c)
+# define MB_TOUPPER(c) vim_toupper(c)
+
+/* Use our own isdigit() replacement, because on MS-Windows isdigit() returns
+ * non-zero for superscript 1. Also avoids that isdigit() crashes for numbers
+ * below 0 and above 255. */
+#define VIM_ISDIGIT(c) ((unsigned)(c) - '0' < 10)
+
+/* Like isalpha() but reject non-ASCII characters. Can't be used with a
+ * special key (negative value). */
+# define ASCII_ISLOWER(c) ((unsigned)(c) - 'a' < 26)
+# define ASCII_ISUPPER(c) ((unsigned)(c) - 'A' < 26)
+# define ASCII_ISALPHA(c) (ASCII_ISUPPER(c) || ASCII_ISLOWER(c))
+# define ASCII_ISALNUM(c) (ASCII_ISALPHA(c) || VIM_ISDIGIT(c))
+
+/* 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.
+ * When set the overhead for characters < 256 is small.
+ * Don't apply 'langmap' if the character comes from the Stuff buffer.
+ * The do-while is just to ignore a ';' after the macro.
+ */
+# define LANGMAP_ADJUST(c, condition) \
+ do { \
+ if (*p_langmap && (condition) && !KeyStuffed && (c) >= 0) \
+ { \
+ if ((c) < 256) \
+ c = langmap_mapchar[c]; \
+ else \
+ c = langmap_adjust_mb(c); \
+ } \
+ } 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)])
+
+/*
+ * On VMS file names are different and require a translation.
+ * On the Mac open() has only two arguments.
+ */
+# define mch_access(n, p) access((n), (p))
+# define mch_fopen(n, p) fopen((n), (p))
+# define mch_fstat(n, p) fstat((n), (p))
+# ifdef STAT_IGNORES_SLASH
+/* On Solaris stat() accepts "file/" as if it was "file". Return -1 if
+ * the name ends in "/" and it's not a directory. */
+# define mch_stat(n, p) (illegal_slash(n) ? -1 : stat((n), (p)))
+# else
+# define mch_stat(n, p) stat((n), (p))
+# endif
+
+#ifdef HAVE_LSTAT
+# define mch_lstat(n, p) lstat((n), (p))
+#else
+# define mch_lstat(n, p) mch_stat((n), (p))
+#endif
+
+# define mch_open(n, m, p) open((n), (m), (p))
+
+/* mch_open_rw(): invoke mch_open() with third argument for user R/W. */
+#if defined(UNIX) || defined(VMS) /* open in rw------- mode */
+# define mch_open_rw(n, f) mch_open((n), (f), (mode_t)0600)
+#else
+# define mch_open_rw(n, f) mch_open((n), (f), 0)
+#endif
+
+#ifdef STARTUPTIME
+# define TIME_MSG(s) { if (time_fd != NULL) time_msg(s, NULL); }
+#else
+# define TIME_MSG(s)
+#endif
+
+# define REPLACE_NORMAL(s) (((s) & REPLACE_FLAG) && !((s) & VREPLACE_FLAG))
+
+# define UTF_COMPOSINGLIKE(p1, p2) utf_composinglike((p1), (p2))
+
+/* 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)(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. */
+# define mb_ptr_back(s, p) p -= has_mbyte ? ((*mb_head_off)(s, 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(&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))
+
+# define DO_AUTOCHDIR if (p_acd) do_autochdir();
+
+# define RESET_BINDING(wp) (wp)->w_p_scb = FALSE; (wp)->w_p_crb = FALSE
diff --git a/src/main.c b/src/main.c
new file mode 100644
index 0000000000..d073fbe9a9
--- /dev/null
+++ b/src/main.c
@@ -0,0 +1,2382 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * 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.
+ */
+
+#define EXTERN
+#include "vim.h"
+
+/* 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 */
+
+/* Struct for various parameters passed between main() and other functions. */
+typedef struct {
+ int argc;
+ char **argv;
+
+ int evim_mode; /* started as "evim" */
+ char_u *use_vimrc; /* vimrc from -u argument */
+
+ int n_commands; /* no. of commands from + or -c */
+ char_u *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 *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 want_full_screen;
+ int stdout_isatty; /* is stdout a terminal? */
+ char_u *term; /* specified terminal name */
+ int ask_for_key; /* -x argument */
+ 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 */
+
+#if (!defined(UNIX) && !defined(__EMX__)) || defined(ARCHIE)
+ int literal; /* don't expand file names */
+#endif
+ int diff_mode; /* start with 'diff' set */
+} mparm_T;
+
+/* Values for edit_type. */
+#define EDIT_NONE 0 /* no edit type yet */
+#define EDIT_FILE 1 /* file name argument[s] given, use argument list */
+#define EDIT_STDIN 2 /* read file from stdin */
+#define EDIT_TAG 3 /* tag name argument given, use tagname */
+#define EDIT_QF 4 /* start in quickfix mode */
+
+#if (defined(UNIX) || defined(VMS)) && !defined(NO_VIM_MAIN)
+static int file_owned __ARGS((char *fname));
+#endif
+static void mainerr __ARGS((int, char_u *));
+#ifndef NO_VIM_MAIN
+static void main_msg __ARGS((char *s));
+static void usage __ARGS((void));
+static int get_number_arg __ARGS((char_u *p, int *idx, int def));
+# if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
+static void init_locale __ARGS((void));
+# endif
+static void parse_command_name __ARGS((mparm_T *parmp));
+static bool parse_char_i __ARGS((char_u **input, char val));
+static bool parse_string __ARGS((char_u **input, char* val, int len));
+static void command_line_scan __ARGS((mparm_T *parmp));
+static void init_params __ARGS((mparm_T *parmp, int argc, char **argv));
+static void init_startuptime __ARGS((mparm_T *parmp));
+static void allocate_generic_buffers __ARGS((void));
+static void check_and_set_isatty __ARGS((mparm_T *parmp));
+static char_u* get_fname __ARGS((mparm_T *parmp));
+static void set_window_layout __ARGS((mparm_T *parmp));
+static void load_plugins __ARGS((void));
+static void handle_quickfix __ARGS((mparm_T *parmp));
+static void handle_tag __ARGS((char_u *tagname));
+static void check_tty __ARGS((mparm_T *parmp));
+static void read_stdin __ARGS((void));
+static void create_windows __ARGS((mparm_T *parmp));
+static void edit_buffers __ARGS((mparm_T *parmp));
+static void exe_pre_commands __ARGS((mparm_T *parmp));
+static void exe_commands __ARGS((mparm_T *parmp));
+static void source_startup_scripts __ARGS((mparm_T *parmp));
+static void main_start_gui __ARGS((void));
+# if defined(HAS_SWAP_EXISTS_ACTION)
+static void check_swap_exists_action __ARGS((void));
+# endif
+#endif /* NO_VIM_MAIN */
+
+
+/*
+ * Different types of error messages.
+ */
+static char *(main_errors[]) =
+{
+ N_("Unknown option argument"),
+#define ME_UNKNOWN_OPTION 0
+ N_("Too many edit arguments"),
+#define ME_TOO_MANY_ARGS 1
+ N_("Argument missing after"),
+#define ME_ARG_MISSING 2
+ N_("Garbage after option argument"),
+#define ME_GARBAGE 3
+ N_("Too many \"+command\", \"-c command\" or \"--cmd command\" arguments"),
+#define ME_EXTRA_CMD 4
+ N_("Invalid argument for"),
+#define ME_INVALID_ARG 5
+};
+
+#ifndef NO_VIM_MAIN /* skip this for unittests */
+ int
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ char_u *fname = NULL; /* file name from command line */
+ mparm_T params; /* various parameters passed between
+ * main() and other functions. */
+ /*
+ * Do any system-specific initialisations. These can NOT use IObuff or
+ * NameBuff. Thus emsg2() cannot be called!
+ */
+ mch_early_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. */
+ init_params(&params, argc, argv);
+
+#ifdef MEM_PROFILE
+ atexit(vim_mem_profile_dump);
+#endif
+
+ init_startuptime(&params);
+
+ (void)mb_init(); /* init mb_bytelen_tab[] to ones */
+ eval_init(); /* init global variables */
+
+#ifdef __QNXNTO__
+ qnx_init(); /* PhAttach() for clipboard, (and gui) */
+#endif
+
+ /* Init the table of Normal mode commands. */
+ init_normal_cmds();
+
+ /*
+ * Allocate space for the generic buffers (needed for set_init_1() and
+ * EMSG2()).
+ */
+ allocate_generic_buffers();
+
+#if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
+ /*
+ * Setup to use the current locale (for ctype() and many other things).
+ * NOTE: Translated messages with encodings other than latin1 will not
+ * work until set_init_1() has been called!
+ */
+ init_locale();
+#endif
+
+ /*
+ * Check if we have an interactive window.
+ * On the Amiga: If there is no window, we open one with a newcli command
+ * (needed for :! to * work). mch_check_win() will also handle the -d or
+ * -dev argument.
+ */
+ check_and_set_isatty(&params);
+
+ /*
+ * Allocate the first window and buffer.
+ * Can't do anything without it, exit when it fails.
+ */
+ if (win_alloc_first() == FAIL)
+ mch_exit(0);
+
+ init_yank(); /* init yank buffers */
+
+ alist_init(&global_alist); /* Init the argument list to empty. */
+
+ /*
+ * Set the default values for the options.
+ * NOTE: Non-latin1 translated messages are working only after this,
+ * because this is where "has_mbyte" will be set, which is used by
+ * msg_outtrans_len_attr().
+ * First find out the home directory, needed to expand "~" in options.
+ */
+ init_homedir(); /* find real value of $HOME */
+ set_init_1();
+ TIME_MSG("inits 1");
+
+ set_lang_var(); /* set v:lang and v:ctype */
+
+
+ /*
+ * Figure out the way to work from the command name argv[0].
+ * "vimdiff" starts diff mode, "rvim" sets "restricted", etc.
+ */
+ parse_command_name(&params);
+
+ /*
+ * Process the command line arguments. File names are put in the global
+ * argument list "global_alist".
+ */
+ command_line_scan(&params);
+
+ /*
+ * On some systems, when we compile with the GUI, we always use it. On Mac
+ * there is no terminal version, and on Windows we can't fork one off with
+ * :gui.
+ */
+
+ if (GARGCOUNT > 0)
+ fname = get_fname(&params);
+
+ TIME_MSG("expanding arguments");
+
+ if (params.diff_mode && params.window_count == -1)
+ params.window_count = 0; /* open up to 3 windows */
+
+ /* 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;
+
+ /*
+ * When certain to start the GUI, don't check capabilities of terminal.
+ * For GTK we can't be sure, but when started from the desktop it doesn't
+ * make sense to try using a terminal.
+ */
+
+
+ /*
+ * mch_init() sets up the terminal (window) for use. This must be
+ * done after resetting full_screen, otherwise it may move the cursor
+ * (MSDOS).
+ * Note that we may use mch_exit() before mch_init()!
+ */
+ mch_init();
+ TIME_MSG("shell init");
+
+
+ /*
+ * Print a warning if stdout is not a terminal.
+ */
+ check_tty(&params);
+
+ /* 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);
+
+ if (params.want_full_screen && !silent_mode) {
+ termcapinit(params.term); /* set terminal name and get terminal
+ capabilities (will set full_screen) */
+ screen_start(); /* don't know where cursor is now */
+ TIME_MSG("Termcap init");
+ }
+
+ /*
+ * Set the default values for the options that use Rows and Columns.
+ */
+ ui_get_shellsize(); /* inits 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);
+
+ cmdline_row = Rows - p_ch;
+ msg_row = cmdline_row;
+ screenalloc(FALSE); /* allocate screen buffers */
+ set_init_2();
+ TIME_MSG("inits 2");
+
+ msg_scroll = TRUE;
+ no_wait_return = TRUE;
+
+ init_highlight(TRUE, FALSE); /* set the default highlight groups */
+ TIME_MSG("init highlight");
+
+ /* Set the break level after the terminal is initialized. */
+ debug_break_level = params.use_debug_break_level;
+
+#endif /* NO_VIM_MAIN */
+
+ /* vim_main2() needs to be produced when FEAT_MZSCHEME is defined even when
+ * NO_VIM_MAIN is defined. */
+
+#ifndef NO_VIM_MAIN
+ /* Execute --cmd arguments. */
+ exe_pre_commands(&params);
+
+ /* Source startup scripts. */
+ source_startup_scripts(&params);
+
+ /*
+ * Read all the plugin files.
+ * Only when compiled with +eval, since most plugins need it.
+ */
+ load_plugins();
+
+ /* Decide about window layout for diff mode after reading vimrc. */
+ set_window_layout(&params);
+
+ /*
+ * Recovery mode without a file name: List swap files.
+ * This uses the 'dir' option, therefore it must be after the
+ * initializations.
+ */
+ if (recoverymode && fname == NULL) {
+ recover_names(NULL, TRUE, 0, NULL);
+ mch_exit(0);
+ }
+
+ /*
+ * Set a few option defaults after reading .vimrc files:
+ * 'title' and 'icon', Unix: 'shellpipe' and '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)
+ p_uc = 0;
+
+ if (curwin->w_p_rl && p_altkeymap) {
+ p_hkmap = FALSE; /* Reset the Hebrew keymap mode */
+ curwin->w_p_arab = FALSE; /* Reset the Arabic keymap mode */
+ p_fkmap = TRUE; /* Set the Farsi keymap mode */
+ }
+
+ /*
+ * Read in registers, history etc, but not marks, from the viminfo file.
+ * This is where v:oldfiles gets filled.
+ */
+ if (*p_viminfo != NUL) {
+ read_viminfo(NULL, VIF_WANT_INFO | VIF_GET_OLDFILES);
+ TIME_MSG("reading viminfo");
+ }
+ /* 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());
+
+ /*
+ * "-q errorfile": Load the error file now.
+ * If the error file can't be read, exit before doing anything else.
+ */
+ handle_quickfix(&params);
+
+ /*
+ * Start putting things on the screen.
+ * Scroll screen down before drawing over it
+ * Clear screen now, so file message will not be cleared.
+ */
+ starting = NO_BUFFERS;
+ 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_stdin();
+
+#if defined(UNIX) || defined(VMS)
+ /* When switching screens and something caused a message from a vimrc
+ * script, need to output an extra newline on exit. */
+ if ((did_emsg || msg_didout) && *T_TI != NUL)
+ newline_on_exit = TRUE;
+#endif
+
+ /*
+ * When done something that is not allowed or error message call
+ * wait_return. This must be done before starttermcap(), because it may
+ * switch to another screen. It must be done after settmode(TMODE_RAW),
+ * because we want to react on a single key stroke.
+ * Call settmode and starttermcap here, so the T_KS and T_TI may be
+ * defined by termcapinit and redefined in .exrc.
+ */
+ settmode(TMODE_RAW);
+ TIME_MSG("setting raw mode");
+
+ if (need_wait_return || msg_didany) {
+ wait_return(TRUE);
+ TIME_MSG("waiting for return");
+ }
+
+ starttermcap(); /* start termcap if not done by wait_return() */
+ TIME_MSG("start termcap");
+ may_req_ambiguous_char_width();
+
+ setmouse(); /* may start using the mouse */
+ if (scroll_region)
+ scroll_region_reset(); /* In case Rows changed */
+ scroll_start(); /* may scroll the screen to the right position */
+
+ /*
+ * Don't clear the screen when starting in Ex mode, unless using the GUI.
+ */
+ if (exmode_active)
+ must_redraw = CLEAR;
+ else {
+ screenclear(); /* clear screen */
+ TIME_MSG("clearing screen");
+ }
+
+ if (params.ask_for_key) {
+ (void)blowfish_self_test();
+ (void)get_crypt_key(TRUE, TRUE);
+ TIME_MSG("getting crypt key");
+ }
+
+ no_wait_return = TRUE;
+
+ /*
+ * Create the requested number of windows and edit buffers in them.
+ * Also does recovery if "recoverymode" set.
+ */
+ create_windows(&params);
+ TIME_MSG("opening buffers");
+
+ /* clear v:swapcommand */
+ set_vim_var_string(VV_SWAPCOMMAND, NULL, -1);
+
+ /* Ex starts at last line of the file */
+ if (exmode_active)
+ curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
+
+ apply_autocmds(EVENT_BUFENTER, NULL, NULL, FALSE, curbuf);
+ TIME_MSG("BufEnter autocommands");
+ setpcmark();
+
+ /*
+ * When started with "-q errorfile" jump to first error now.
+ */
+ if (params.edit_type == EDIT_QF) {
+ qf_jump(NULL, 0, 0, FALSE);
+ TIME_MSG("jump to first error");
+ }
+
+ /*
+ * If opened more than one window, start editing files in the other
+ * windows.
+ */
+ edit_buffers(&params);
+
+ if (params.diff_mode) {
+ win_T *wp;
+
+ /* set options in each window for "vimdiff". */
+ for (wp = firstwin; wp != NULL; wp = wp->w_next)
+ diff_win_options(wp, TRUE);
+ }
+
+ /*
+ * Shorten any of the filenames, but only when absolute.
+ */
+ shorten_fnames(FALSE);
+
+ /*
+ * Need to jump to the tag before executing the '-c command'.
+ * Makes "vim -c '/return' -t main" work.
+ */
+ handle_tag(params.tagname);
+
+ /* Execute any "+", "-c" and "-S" arguments. */
+ if (params.n_commands > 0)
+ exe_commands(&params);
+
+ RedrawingDisabled = 0;
+ redraw_all_later(NOT_VALID);
+ no_wait_return = FALSE;
+ starting = 0;
+
+ /* Requesting the termresponse is postponed until here, so that a "-c q"
+ * argument doesn't make it appear in the shell Vim was started from. */
+ may_req_termresponse();
+
+ /* start in insert mode */
+ if (p_im)
+ need_start_insertmode = TRUE;
+
+ apply_autocmds(EVENT_VIMENTER, NULL, NULL, FALSE, curbuf);
+ TIME_MSG("VimEnter autocommands");
+
+
+ /* 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) {
+ update_topline();
+ check_scrollbind((linenr_T)0, 0L);
+ TIME_MSG("diff scrollbinding");
+ }
+
+
+
+ /* If ":startinsert" command used, stuff a dummy command to be able to
+ * call normal_cmd(), which will then start Insert mode. */
+ if (restart_edit != 0)
+ stuffcharReadbuff(K_NOP);
+
+
+ TIME_MSG("before starting main loop");
+
+ /*
+ * Call the main command loop. This never returns.
+ */
+ main_loop(FALSE, FALSE);
+
+ return 0;
+}
+#endif /* NO_VIM_MAIN */
+
+/*
+ * Main loop: Execute Normal mode commands until exiting Vim.
+ * Also used to handle commands in the command-line window, until the window
+ * is closed.
+ * Also used to handle ":visual" command after ":global": execute Normal mode
+ * commands, return when entering Ex mode. "noexmode" is TRUE then.
+ */
+void main_loop(cmdwin, noexmode)
+ int cmdwin; /* TRUE when working in the command-line window */
+ int noexmode; /* TRUE when return on entering Ex mode */
+{
+ oparg_T oa; /* operator arguments */
+ int previous_got_int = FALSE; /* "got_int" was TRUE */
+ linenr_T conceal_old_cursor_line = 0;
+ linenr_T conceal_new_cursor_line = 0;
+ int conceal_update_lines = FALSE;
+
+
+ clear_oparg(&oa);
+ while (!cmdwin
+ || cmdwin_result == 0
+ ) {
+ if (stuff_empty()) {
+ did_check_timestamps = FALSE;
+ if (need_check_timestamps)
+ check_timestamps(FALSE);
+ if (need_wait_return) /* if wait_return still needed ... */
+ wait_return(FALSE); /* ... call it now */
+ if (need_start_insertmode && goto_im()
+ && !VIsual_active
+ ) {
+ need_start_insertmode = FALSE;
+ stuffReadbuff((char_u *)"i"); /* start insert mode next */
+ /* skip the fileinfo message now, because it would be shown
+ * after insert mode finishes! */
+ need_fileinfo = FALSE;
+ }
+ }
+
+ /* Reset "got_int" now that we got back to the main loop. Except when
+ * inside a ":g/pat/cmd" command, then the "got_int" needs to abort
+ * the ":g" command.
+ * For ":g/pat/vi" we reset "got_int" when used once. When used
+ * a second time we go back to Ex mode and abort the ":g" command. */
+ if (got_int) {
+ if (noexmode && global_busy && !exmode_active && previous_got_int) {
+ /* Typed two CTRL-C in a row: go back to ex mode as if "Q" was
+ * used and keep "got_int" set, so that it aborts ":g". */
+ exmode_active = EXMODE_NORMAL;
+ State = NORMAL;
+ } else if (!global_busy || !exmode_active) {
+ if (!quit_more)
+ (void)vgetc(); /* flush all buffers */
+ got_int = FALSE;
+ }
+ previous_got_int = TRUE;
+ } else
+ previous_got_int = FALSE;
+
+ if (!exmode_active)
+ msg_scroll = FALSE;
+ quit_more = FALSE;
+
+ /*
+ * If skip redraw is set (for ":" in wait_return()), don't redraw now.
+ * If there is nothing in the stuff_buffer or do_redraw is TRUE,
+ * update cursor and redraw.
+ */
+ if (skip_redraw || exmode_active)
+ skip_redraw = FALSE;
+ else if (do_redraw || stuff_empty()) {
+ /* Trigger CursorMoved if the cursor moved. */
+ if (!finish_op && (
+ has_cursormoved()
+ ||
+ curwin->w_p_cole > 0
+ )
+ && !equalpos(last_cursormoved, curwin->w_cursor)) {
+ if (has_cursormoved())
+ apply_autocmds(EVENT_CURSORMOVED, 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;
+ }
+ last_cursormoved = curwin->w_cursor;
+ }
+
+ /* Trigger TextChanged if b_changedtick differs. */
+ if (!finish_op && has_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;
+ }
+
+ /* Scroll-binding for diff mode may have been postponed until
+ * here. Avoids doing it for every change. */
+ if (diff_need_scrollbind) {
+ check_scrollbind((linenr_T)0, 0L);
+ diff_need_scrollbind = FALSE;
+ }
+ /* Include a closed fold completely in the Visual area. */
+ foldAdjustVisual();
+ /*
+ * When 'foldclose' is set, apply 'foldlevel' to folds that don't
+ * contain the cursor.
+ * When 'foldopen' is "all", open the fold(s) under the cursor.
+ * This may mark the window for redrawing.
+ */
+ if (hasAnyFolding(curwin) && !char_avail()) {
+ foldCheckClose();
+ if (fdo_flags & FDO_ALL)
+ foldOpenCursor();
+ }
+
+ /*
+ * Before redrawing, make sure w_topline is correct, and w_leftcol
+ * if lines don't wrap, and w_skipcol if lines wrap.
+ */
+ update_topline();
+ validate_cursor();
+
+ if (VIsual_active)
+ update_curbuf(INVERTED); /* update inverted part */
+ else if (must_redraw)
+ update_screen(0);
+ else if (redraw_cmdline || clear_cmdline)
+ showmode();
+ redraw_statuslines();
+ if (need_maketitle)
+ maketitle();
+ /* display message after redraw */
+ if (keep_msg != NULL) {
+ char_u *p;
+
+ /* msg_attr_keep() will set keep_msg to NULL, must free the
+ * string here. */
+ p = keep_msg;
+ keep_msg = NULL;
+ msg_attr(p, keep_msg_attr);
+ vim_free(p);
+ }
+ if (need_fileinfo) { /* show file info after redraw */
+ fileinfo(FALSE, TRUE, FALSE);
+ need_fileinfo = FALSE;
+ }
+
+ emsg_on_display = FALSE; /* can delete error message now */
+ did_emsg = FALSE;
+ msg_didany = FALSE; /* reset lines_left in msg_start() */
+ may_clear_sb_text(); /* clear scroll-back text on next msg */
+ showruler(FALSE);
+
+ 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
+ && conceal_old_cursor_line
+ <= curbuf->b_ml.ml_line_count)
+ update_single_line(curwin, conceal_old_cursor_line);
+ update_single_line(curwin, conceal_new_cursor_line);
+ curwin->w_valid &= ~VALID_CROW;
+ }
+ setcursor();
+ cursor_on();
+
+ do_redraw = FALSE;
+
+#ifdef STARTUPTIME
+ /* Now that we have drawn the first screen all the startup stuff
+ * has been done, close any file for startup messages. */
+ if (time_fd != NULL) {
+ TIME_MSG("first screen update");
+ TIME_MSG("--- VIM STARTED ---");
+ fclose(time_fd);
+ time_fd = NULL;
+ }
+#endif
+ }
+
+ /*
+ * Update w_curswant if w_set_curswant has been set.
+ * Postponed until here to avoid computing w_virtcol too often.
+ */
+ update_curswant();
+
+ /*
+ * May perform garbage collection when waiting for a character, but
+ * only at the very toplevel. Otherwise we may be using a List or
+ * Dict internally somewhere.
+ * "may_garbage_collect" is reset in vgetc() which is invoked through
+ * do_exmode() and normal_cmd().
+ */
+ may_garbage_collect = (!cmdwin && !noexmode);
+ /*
+ * If we're invoked as ex, do a round of ex commands.
+ * Otherwise, get and execute a normal mode command.
+ */
+ if (exmode_active) {
+ if (noexmode) /* End of ":global/path/visual" commands */
+ return;
+ do_exmode(exmode_active == EXMODE_VIM);
+ } else
+ normal_cmd(&oa, TRUE);
+ }
+}
+
+
+
+
+/* Exit properly */
+void getout(exitval)
+ int exitval;
+{
+ buf_T *buf;
+ win_T *wp;
+ tabpage_T *tp, *next_tp;
+
+ exiting = TRUE;
+
+ /* When running in Ex mode an error causes us to exit with a non-zero exit
+ * code. POSIX requires this, although it's not 100% clear from the
+ * standard. */
+ if (exmode_active)
+ exitval += ex_exitval;
+
+ /* Position the cursor on the last screen line, below all the text */
+ windgoto((int)Rows - 1, 0);
+
+ /* Optionally print hashtable efficiency. */
+ hash_debug_results();
+
+
+ if (get_vim_var_nr(VV_DYING) <= 1) {
+ /* Trigger BufWinLeave for all windows, but only once per buffer. */
+ for (tp = first_tabpage; tp != NULL; tp = next_tp) {
+ next_tp = tp->tp_next;
+ for (wp = (tp == curtab)
+ ? firstwin : tp->tp_firstwin; wp != NULL; wp = wp->w_next) {
+ if (wp->w_buffer == NULL)
+ /* Autocmd must have close the buffer already, skip. */
+ continue;
+ buf = wp->w_buffer;
+ if (buf->b_changedtick != -1) {
+ 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 */
+ next_tp = first_tabpage;
+ break;
+ }
+ }
+ }
+
+ /* Trigger BufUnload for buffers that are loaded */
+ for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+ 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 */
+ break;
+ }
+ apply_autocmds(EVENT_VIMLEAVEPRE, NULL, NULL, FALSE, curbuf);
+ }
+
+ if (*p_viminfo != NUL)
+ /* Write out the registers, history, marks etc, to the viminfo file */
+ write_viminfo(NULL, FALSE);
+
+ if (get_vim_var_nr(VV_DYING) <= 1)
+ apply_autocmds(EVENT_VIMLEAVE, NULL, NULL, FALSE, curbuf);
+
+ profile_dump();
+
+ if (did_emsg
+ ) {
+ /* give the user a chance to read the (error) message */
+ no_wait_return = FALSE;
+ wait_return(FALSE);
+ }
+
+ /* Position the cursor again, the autocommands may have moved it */
+ windgoto((int)Rows - 1, 0);
+
+#if defined(USE_ICONV) && defined(DYNAMIC_ICONV)
+ iconv_end();
+#endif
+ cs_end();
+ if (garbage_collect_at_exit)
+ garbage_collect();
+
+ mch_exit(exitval);
+}
+
+#ifndef NO_VIM_MAIN
+/*
+ * Get a (optional) count for a Vim argument.
+ */
+static int get_number_arg(p, idx, def)
+ char_u *p; /* pointer to argument */
+ int *idx; /* index in argument, is incremented */
+ int def; /* default value */
+{
+ if (vim_isdigit(p[*idx])) {
+ def = atoi((char *)&(p[*idx]));
+ while (vim_isdigit(p[*idx]))
+ *idx = *idx + 1;
+ }
+ return def;
+}
+
+#if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
+/*
+ * Setup to use the current locale (for ctype() and many other things).
+ */
+static void init_locale() {
+ setlocale(LC_ALL, "");
+
+# if defined(FEAT_FLOAT) && defined(LC_NUMERIC)
+ /* Make sure strtod() uses a decimal point, not a comma. */
+ setlocale(LC_NUMERIC, "C");
+# endif
+
+
+ {
+ int mustfree = FALSE;
+ char_u *p;
+
+ /* expand_env() doesn't work yet, because chartab[] is not initialized
+ * yet, call vim_getenv() directly */
+ p = vim_getenv((char_u *)"VIMRUNTIME", &mustfree);
+ if (p != NULL && *p != NUL) {
+ vim_snprintf((char *)NameBuff, MAXPATHL, "%s/lang", p);
+ bindtextdomain(VIMPACKAGE, (char *)NameBuff);
+ }
+ if (mustfree)
+ vim_free(p);
+ textdomain(VIMPACKAGE);
+ }
+ TIME_MSG("locale set");
+}
+
+#endif
+
+/*
+ * Check for: [r][e][g][vi|vim|view][diff][ex[im]]
+ * If the executable name starts with "r" we disable shell commands.
+ * If the next character is "e" we run in Easy mode.
+ * If the next character is "g" we run the GUI version.
+ * If the next characters are "view" we start in readonly mode.
+ * If the next characters are "diff" or "vimdiff" we start in diff mode.
+ * If the next characters are "ex" we start in Ex mode. If it's followed
+ * by "im" use improved Ex mode.
+ */
+static void parse_command_name(parmp)
+ mparm_T *parmp;
+{
+ char_u *initstr;
+
+ initstr = gettail((char_u *)parmp->argv[0]);
+
+
+ set_vim_var_string(VV_PROGNAME, initstr, -1);
+
+ if (STRNICMP(initstr, "editor", 6) == 0)
+ return;
+
+ if (parse_char_i(&initstr, 'r'))
+ restricted = TRUE;
+
+ if (parse_char_i(&initstr, 'e'))
+ parmp->evim_mode = TRUE;
+
+ /* "gvim" starts the GUI. Also accept "Gvim" for MS-Windows. */
+ if (parse_char_i(&initstr, 'g'))
+ main_start_gui();
+
+ if (parse_string(&initstr, "view", 4)) {
+ readonlymode = TRUE;
+ curbuf->b_p_ro = TRUE;
+ p_uc = 10000; /* don't update very often */
+ } else {
+ parse_string(&initstr, "vim", 3); /* consume "vim" if it's there */
+ }
+
+ /* Catch "[r][g]vimdiff" and "[r][g]viewdiff". */
+ if (parse_string(&initstr, "diff", 4))
+ parmp->diff_mode = TRUE;
+
+ if (parse_string(&initstr, "ex", 2)) {
+ if (parse_string(&initstr, "im", 2))
+ exmode_active = EXMODE_VIM;
+ else
+ exmode_active = EXMODE_NORMAL;
+ change_compatible(TRUE); /* set 'compatible' */
+ }
+}
+
+static bool parse_char_i(input, val)
+ char_u **input;
+ char val;
+{
+ if (TOLOWER_ASC(**input) == val) {
+ *input += 1; /* or (*input)++ WITH parens */
+ return true;
+ }
+ return false;
+}
+
+static bool parse_string(input, val, len)
+ char_u **input;
+ char *val;
+ int len;
+{
+ if (STRNICMP(*input, val, len) == 0) {
+ *input += len;
+ return true;
+ }
+ return false;
+}
+
+/*
+ * Scan the command line arguments.
+ */
+static void command_line_scan(parmp)
+ 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 */
+ int c;
+ char_u *p = NULL;
+ long n;
+
+ --argc;
+ ++argv;
+ argv_idx = 1; /* active option letter is argv[0][argv_idx] */
+ while (argc > 0) {
+ /*
+ * "+" or "+{number}" or "+/{pat}" or "+{command}" argument.
+ */
+ if (argv[0][0] == '+' && !had_minmin) {
+ if (parmp->n_commands >= MAX_ARG_CMDS)
+ mainerr(ME_EXTRA_CMD, NULL);
+ argv_idx = -1; /* skip to next argument */
+ if (argv[0][1] == NUL)
+ parmp->commands[parmp->n_commands++] = (char_u *)"$";
+ else
+ parmp->commands[parmp->n_commands++] = (char_u *)&(argv[0][1]);
+ }
+ /*
+ * 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 */
+ /* "ex -" silent mode */
+ if (exmode_active)
+ silent_mode = TRUE;
+ else {
+ if (parmp->edit_type != EDIT_NONE)
+ mainerr(ME_TOO_MANY_ARGS, (char_u *)argv[0]);
+ parmp->edit_type = EDIT_STDIN;
+ read_cmd_fd = 2; /* read from stderr instead of stdin */
+ }
+ 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 */
+ /* "--nofork" don't fork */
+ /* "--noplugin[s]" skip plugins */
+ /* "--cmd <cmd>" execute cmd before vimrc */
+ if (STRICMP(argv[0] + argv_idx, "help") == 0)
+ usage();
+ else if (STRICMP(argv[0] + argv_idx, "version") == 0) {
+ Columns = 80; /* need to init Columns */
+ info_message = TRUE; /* use mch_msg(), not mch_errmsg() */
+ list_version();
+ msg_putchar('\n');
+ msg_didout = FALSE;
+ mch_exit(0);
+ } else if (STRNICMP(argv[0] + argv_idx, "literal", 7) == 0) {
+#if (!defined(UNIX) && !defined(__EMX__)) || defined(ARCHIE)
+ parmp->literal = TRUE;
+#endif
+ } else if (STRNICMP(argv[0] + argv_idx, "nofork", 6) == 0) {
+ } 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;
+ argv_idx += 11;
+ } else {
+ if (argv[0][argv_idx])
+ mainerr(ME_UNKNOWN_OPTION, (char_u *)argv[0]);
+ had_minmin = TRUE;
+ }
+ 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);
+ 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. */
+ set_options_bin(curbuf->b_p_bin, 1, 0);
+ curbuf->b_p_bin = 1; /* binary file I/O */
+ break;
+
+ case 'C': /* "-C" Compatible */
+ change_compatible(TRUE);
+ break;
+
+ case 'e': /* "-e" Ex mode */
+ exmode_active = EXMODE_NORMAL;
+ break;
+
+ case 'E': /* "-E" Improved Ex mode */
+ exmode_active = EXMODE_VIM;
+ break;
+
+ case 'f': /* "-f" GUI: run in foreground. Amiga: open
+ window directly, not with newcli */
+ break;
+
+ case 'g': /* "-g" start GUI */
+ main_start_gui();
+ break;
+
+ case 'F': /* "-F" start in Farsi mode: rl + fkmap set */
+ p_fkmap = TRUE;
+ set_option_value((char_u *)"rl", 1L, NULL, 0);
+ break;
+
+ case 'h': /* "-h" give help message */
+ usage();
+ break;
+
+ case 'H': /* "-H" start in Hebrew mode: rl + hkmap set */
+ p_hkmap = TRUE;
+ set_option_value((char_u *)"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;
+ break;
+
+ case 'M': /* "-M" no changes or writing of files */
+ reset_modifiable();
+ /* FALLTHROUGH */
+
+ case 'm': /* "-m" no writing of files */
+ p_write = FALSE;
+ break;
+
+ case 'y': /* "-y" easy mode */
+ parmp->evim_mode = TRUE;
+ break;
+
+ case 'N': /* "-N" Nocompatible */
+ change_compatible(FALSE);
+ break;
+
+ 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 */
+ parmp->window_count = get_number_arg((char_u *)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 */
+ parmp->window_count = get_number_arg((char_u *)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 */
+ parmp->window_count = get_number_arg((char_u *)argv[0],
+ &argv_idx, 0);
+ parmp->window_layout = WIN_VER;
+ break;
+
+ case 'q': /* "-q" QuickFix mode */
+ if (parmp->edit_type != EDIT_NONE)
+ mainerr(ME_TOO_MANY_ARGS, (char_u *)argv[0]);
+ parmp->edit_type = EDIT_QF;
+ 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;
+ break;
+
+ 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 */
+ 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;
+ break;
+
+ case 't': /* "-t {tag}" or "-t{tag}" jump to tag */
+ if (parmp->edit_type != EDIT_NONE)
+ mainerr(ME_TOO_MANY_ARGS, (char_u *)argv[0]);
+ parmp->edit_type = EDIT_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;
+ break;
+ case 'V': /* "-V{N}" Verbose level */
+ /* default is 10: a little bit verbose */
+ p_verbose = get_number_arg((char_u *)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);
+ argv_idx = (int)STRLEN(argv[0]);
+ }
+ break;
+
+ case 'v': /* "-v" Vi-mode (as if called "vi") */
+ exmode_active = 0;
+ break;
+
+ case 'w': /* "-w{number}" set window height */
+ /* "-w {scriptout}" write to script */
+ if (vim_isdigit(((char_u *)argv[0])[argv_idx])) {
+ n = get_number_arg((char_u *)argv[0], &argv_idx, 10);
+ set_option_value((char_u *)"window", n, NULL, 0);
+ break;
+ }
+ want_argument = TRUE;
+ break;
+
+ case 'x': /* "-x" encrypted reading/writing of files */
+ parmp->ask_for_key = TRUE;
+ break;
+
+ case 'X': /* "-X" don't connect to X server */
+ break;
+
+ case 'Z': /* "-Z" restricted mode */
+ restricted = TRUE;
+ break;
+
+ case 'c': /* "-c{command}" or "-c {command}" execute
+ command */
+ if (argv[0][argv_idx] != NUL) {
+ if (parmp->n_commands >= MAX_ARG_CMDS)
+ mainerr(ME_EXTRA_CMD, NULL);
+ parmp->commands[parmp->n_commands++] = (char_u *)argv[0]
+ + argv_idx;
+ argv_idx = -1;
+ break;
+ }
+ /*FALLTHROUGH*/
+ case 'S': /* "-S {file}" execute Vim script */
+ case 'i': /* "-i {viminfo}" use for viminfo */
+ case 'T': /* "-T {terminal}" terminal name */
+ case 'u': /* "-u {vimrc}" vim inits file */
+ case 'U': /* "-U {gvimrc}" gvim inits file */
+ case 'W': /* "-W {scriptout}" overwrite */
+ want_argument = TRUE;
+ break;
+
+ default:
+ mainerr(ME_UNKNOWN_OPTION, (char_u *)argv[0]);
+ }
+
+ /*
+ * Handle option arguments with argument.
+ */
+ if (want_argument) {
+ /*
+ * Check for garbage immediately after the option letter.
+ */
+ if (argv[0][argv_idx] != NUL)
+ mainerr(ME_GARBAGE, (char_u *)argv[0]);
+
+ --argc;
+ if (argc < 1 && c != 'S') /* -S has an optional argument */
+ mainerr_arg_missing((char_u *)argv[0]);
+ ++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)
+ mainerr(ME_EXTRA_CMD, NULL);
+ if (c == 'S') {
+ char *a;
+
+ 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. */
+ a = SESSION_FILE;
+ ++argc;
+ --argv;
+ } else
+ a = argv[0];
+ p = alloc((unsigned)(STRLEN(a) + 4));
+ if (p == NULL)
+ mch_exit(2);
+ sprintf((char *)p, "so %s", a);
+ parmp->cmds_tofree[parmp->n_commands] = TRUE;
+ parmp->commands[parmp->n_commands++] = p;
+ } else
+ parmp->commands[parmp->n_commands++] =
+ (char_u *)argv[0];
+ break;
+
+ case '-':
+ if (argv[-1][2] == 'c') {
+ /* "--cmd {command}" execute command */
+ if (parmp->n_pre_commands >= MAX_ARG_CMDS)
+ mainerr(ME_EXTRA_CMD, NULL);
+ parmp->pre_commands[parmp->n_pre_commands++] =
+ (char_u *)argv[0];
+ }
+ /* "--startuptime <file>" already handled */
+ break;
+
+ /* case 'd': -d {device} is handled in mch_check_win() for the
+ * Amiga */
+
+ case 'q': /* "-q {errorfile}" QuickFix mode */
+ parmp->use_ef = (char_u *)argv[0];
+ break;
+
+ case 'i': /* "-i {viminfo}" use for viminfo */
+ use_viminfo = (char_u *)argv[0];
+ break;
+
+ 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");
+ 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");
+ mch_exit(2);
+ }
+ if (save_typebuf() == FAIL)
+ mch_exit(2); /* out of memory */
+ break;
+
+ case 't': /* "-t {tag}" */
+ parmp->tagname = (char_u *)argv[0];
+ break;
+
+ case 'T': /* "-T {terminal}" terminal name */
+ /*
+ * The -T term argument is always available and when
+ * HAVE_TERMLIB is supported it overrides the environment
+ * variable TERM.
+ */
+ parmp->term = (char_u *)argv[0];
+ break;
+
+ case 'u': /* "-u {vimrc}" vim inits file */
+ parmp->use_vimrc = (char_u *)argv[0];
+ break;
+
+ case 'U': /* "-U {gvimrc}" gvim inits file */
+ break;
+
+ case 'w': /* "-w {nr}" 'window' value */
+ /* "-w {scriptout}" append to script file */
+ if (vim_isdigit(*((char_u *)argv[0]))) {
+ argv_idx = 0;
+ n = get_number_arg((char_u *)argv[0], &argv_idx, 10);
+ set_option_value((char_u *)"window", n, NULL, 0);
+ argv_idx = -1;
+ break;
+ }
+ /*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: \""));
+ mch_errmsg(argv[0]);
+ mch_errmsg("\"\n");
+ 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)
+ mainerr(ME_TOO_MANY_ARGS, (char_u *)argv[0]);
+ parmp->edit_type = EDIT_FILE;
+
+
+ /* Add the file to the global argument list. */
+ if (ga_grow(&global_alist.al_ga, 1) == FAIL
+ || (p = vim_strsave((char_u *)argv[0])) == NULL)
+ mch_exit(2);
+ if (parmp->diff_mode && mch_isdir(p) && GARGCOUNT > 0
+ && !mch_isdir(alist_name(&GARGLIST[0]))) {
+ char_u *r;
+
+ r = concat_fnames(p, gettail(alist_name(&GARGLIST[0])), TRUE);
+ if (r != NULL) {
+ vim_free(p);
+ p = r;
+ }
+ }
+
+#ifdef USE_FNAME_CASE
+ /* Make the case of the file name match the actual file. */
+ fname_case(p, 0);
+#endif
+
+ alist_add(&global_alist, p,
+#if (!defined(UNIX) && !defined(__EMX__)) || defined(ARCHIE)
+ parmp->literal ? 2 : 0 /* add buffer nr after exp. */
+#else
+ 2 /* add buffer number now and use curbuf */
+#endif
+ );
+
+ }
+
+ /*
+ * 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;
+ argv_idx = 1;
+ }
+ }
+
+ /* If there is a "+123" or "-c" command, set v:swapcommand to the first
+ * one. */
+ if (parmp->n_commands > 0) {
+ p = alloc((unsigned)STRLEN(parmp->commands[0]) + 3);
+ if (p != NULL) {
+ sprintf((char *)p, ":%s\r", parmp->commands[0]);
+ set_vim_var_string(VV_SWAPCOMMAND, p, -1);
+ vim_free(p);
+ }
+ }
+ TIME_MSG("parsing arguments");
+}
+
+/*
+ * 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. */
+static void init_params(paramp, argc, argv)
+ mparm_T *paramp;
+ int argc;
+ char **argv;
+{
+ vim_memset(paramp, 0, sizeof(*paramp));
+ paramp->argc = argc;
+ paramp->argv = argv;
+ paramp->want_full_screen = TRUE;
+ paramp->use_debug_break_level = -1;
+ paramp->window_count = -1;
+}
+
+/*
+ * Initialize global startuptime file if "--startuptime" passed as an argument.
+ */
+static void init_startuptime(paramp)
+ mparm_T *paramp;
+{
+#ifdef STARTUPTIME
+ int i;
+ for (i = 1; i < paramp->argc; ++i) {
+ if (STRICMP(paramp->argv[i], "--startuptime") == 0 && i + 1 < paramp->argc) {
+ time_fd = mch_fopen(paramp->argv[i + 1], "a");
+ TIME_MSG("--- VIM STARTING ---");
+ break;
+ }
+ }
+#endif
+ starttime = time(NULL);
+}
+
+/*
+ * Allocate space for the generic buffers (needed for set_init_1() and
+ * EMSG2()).
+ */
+static void allocate_generic_buffers()
+{
+ if ((IObuff = alloc(IOSIZE)) == NULL
+ || (NameBuff = alloc(MAXPATHL)) == NULL)
+ mch_exit(0);
+ TIME_MSG("Allocated generic buffers");
+}
+
+/*
+ * Check if we have an interactive window.
+ * On the Amiga: If there is no window, we open one with a newcli command
+ * (needed for :! to * work). mch_check_win() will also handle the -d or
+ * -dev argument.
+ */
+static void check_and_set_isatty(paramp)
+ mparm_T *paramp;
+{
+ paramp->stdout_isatty = (mch_check_win(paramp->argc, paramp->argv) != FAIL);
+ TIME_MSG("window checked");
+}
+
+/*
+ * Get filename from command line, given that there is one.
+ */
+static char_u* get_fname(parmp)
+ mparm_T *parmp;
+{
+#if (!defined(UNIX) && !defined(__EMX__)) || defined(ARCHIE)
+ /*
+ * Expand wildcards in file names.
+ */
+ if (!parmp->literal) {
+ /* 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((char_u *)":set isf+=(,)");
+ alist_expand(NULL, 0);
+ do_cmdline_cmd((char_u *)":set isf&");
+ }
+#endif
+ return alist_name(&GARGLIST[0]);
+}
+
+/*
+ * Decide about window layout for diff mode after reading vimrc.
+ */
+static void set_window_layout(paramp)
+ mparm_T *paramp;
+{
+ if (paramp->diff_mode && paramp->window_layout == 0) {
+ if (diffopt_horizontal())
+ paramp->window_layout = WIN_HOR; /* use horizontal split */
+ else
+ paramp->window_layout = WIN_VER; /* use vertical split */
+ }
+}
+
+/*
+ * Read all the plugin files.
+ * Only when compiled with +eval, since most plugins need it.
+ */
+static void load_plugins()
+{
+ if (p_lpl) {
+ source_runtime((char_u *)"plugin/**/*.vim", TRUE);
+ TIME_MSG("loading plugins");
+ }
+}
+
+/*
+ * "-q errorfile": Load the error file now.
+ * If the error file can't be read, exit before doing anything else.
+ */
+static void handle_quickfix(paramp)
+ mparm_T *paramp;
+{
+ if (paramp->edit_type == EDIT_QF) {
+ if (paramp->use_ef != NULL)
+ 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) {
+ out_char('\n');
+ mch_exit(3);
+ }
+ TIME_MSG("reading errorfile");
+ }
+}
+
+/*
+ * Need to jump to the tag before executing the '-c command'.
+ * Makes "vim -c '/return' -t main" work.
+ */
+static void handle_tag(tagname)
+ char_u *tagname;
+{
+ if (tagname != NULL) {
+#if defined(HAS_SWAP_EXISTS_ACTION)
+ swap_exists_did_quit = FALSE;
+#endif
+
+ vim_snprintf((char *)IObuff, IOSIZE, "ta %s", tagname);
+ do_cmdline_cmd(IObuff);
+ TIME_MSG("jumping to tag");
+
+#if defined(HAS_SWAP_EXISTS_ACTION)
+ /* If the user doesn't want to edit the file then we quit here. */
+ if (swap_exists_did_quit)
+ getout(1);
+#endif
+ }
+}
+
+/*
+ * 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(parmp)
+ mparm_T *parmp;
+{
+ int input_isatty; /* is active input a terminal? */
+
+ input_isatty = mch_input_isatty();
+ if (exmode_active) {
+ if (!input_isatty)
+ silent_mode = TRUE;
+ } else if (parmp->want_full_screen && (!parmp->stdout_isatty || !input_isatty)
+ ) {
+ if (!parmp->stdout_isatty)
+ mch_errmsg(_("Vim: Warning: Output is not to a terminal\n"));
+ if (!input_isatty)
+ mch_errmsg(_("Vim: Warning: Input is not from a terminal\n"));
+ out_flush();
+ if (scriptin[0] == NULL)
+ ui_delay(2000L, TRUE);
+ TIME_MSG("Warning delay");
+ }
+}
+
+/*
+ * Read text from stdin.
+ */
+static void read_stdin() {
+ int i;
+
+#if defined(HAS_SWAP_EXISTS_ACTION)
+ /* When getting the ATTENTION prompt here, use a dialog */
+ swap_exists_action = SEA_DIALOG;
+#endif
+ 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;
+ TIME_MSG("reading stdin");
+#if defined(HAS_SWAP_EXISTS_ACTION)
+ check_swap_exists_action();
+#endif
+ /*
+ * Close stdin and dup it from stderr. Required for GPM to work
+ * properly, and for running external commands.
+ * Is there any other system that cannot do this?
+ */
+ close(0);
+ ignored = dup(2);
+}
+
+/*
+ * Create the requested number of windows and edit buffers in them.
+ * Also does recovery if "recoverymode" set.
+ */
+static void create_windows(parmp)
+ mparm_T *parmp UNUSED;
+{
+ int dorewind;
+ int done = 0;
+
+ /*
+ * Create the number of windows that was requested.
+ */
+ if (parmp->window_count == -1) /* was not set */
+ parmp->window_count = 1;
+ if (parmp->window_count == 0)
+ parmp->window_count = GARGCOUNT;
+ if (parmp->window_count > 1) {
+ /* Don't change the windows if there was a command in .vimrc that
+ * already split some windows */
+ if (parmp->window_layout == 0)
+ parmp->window_layout = WIN_HOR;
+ if (parmp->window_layout == WIN_TABS) {
+ parmp->window_count = make_tabpages(parmp->window_count);
+ TIME_MSG("making tab pages");
+ } else if (firstwin->w_next == NULL) {
+ parmp->window_count = make_windows(parmp->window_count,
+ parmp->window_layout == WIN_VER);
+ TIME_MSG("making windows");
+ } else
+ parmp->window_count = win_count();
+ } else
+ parmp->window_count = 1;
+
+ if (recoverymode) { /* do recover */
+ msg_scroll = TRUE; /* scroll message up */
+ ml_recover();
+ if (curbuf->b_ml.ml_mfp == NULL) /* failed */
+ getout(1);
+ do_modelines(0); /* do modelines */
+ } else {
+ /*
+ * Open a buffer for windows that don't have one yet.
+ * Commands in the .vimrc might have loaded a file or split the window.
+ * Watch out for autocommands that delete a window.
+ */
+ /*
+ * Don't execute Win/Buf Enter/Leave autocommands here
+ */
+ ++autocmd_no_enter;
+ ++autocmd_no_leave;
+ dorewind = TRUE;
+ while (done++ < 1000) {
+ if (dorewind) {
+ if (parmp->window_layout == WIN_TABS)
+ goto_tabpage(1);
+ else
+ curwin = firstwin;
+ } else if (parmp->window_layout == WIN_TABS) {
+ if (curtab->tp_next == NULL)
+ break;
+ goto_tabpage(0);
+ } else {
+ if (curwin->w_next == NULL)
+ break;
+ curwin = curwin->w_next;
+ }
+ dorewind = FALSE;
+ curbuf = curwin->w_buffer;
+ if (curbuf->b_ml.ml_mfp == NULL) {
+ /* Set 'foldlevel' to 'foldlevelstart' if it's not negative. */
+ if (p_fdls >= 0)
+ curwin->w_p_fdl = p_fdls;
+#if defined(HAS_SWAP_EXISTS_ACTION)
+ /* When getting the ATTENTION prompt here, use a dialog */
+ swap_exists_action = SEA_DIALOG;
+#endif
+ set_buflisted(TRUE);
+
+ /* create memfile, read file */
+ (void)open_buffer(FALSE, NULL, 0);
+
+#if defined(HAS_SWAP_EXISTS_ACTION)
+ if (swap_exists_action == SEA_QUIT) {
+ if (got_int || only_one_window()) {
+ /* abort selected or quit and only one window */
+ did_emsg = FALSE; /* avoid hit-enter prompt */
+ getout(1);
+ }
+ /* We can't close the window, it would disturb what
+ * happens next. Clear the file name and set the arg
+ * index to -1 to delete it later. */
+ setfname(curbuf, NULL, NULL, FALSE);
+ curwin->w_arg_idx = -1;
+ swap_exists_action = SEA_NONE;
+ } else
+ handle_swap_exists(NULL);
+#endif
+ dorewind = TRUE; /* start again */
+ }
+ ui_breakcheck();
+ if (got_int) {
+ (void)vgetc(); /* only break the file loading, not the rest */
+ break;
+ }
+ }
+ if (parmp->window_layout == WIN_TABS)
+ goto_tabpage(1);
+ else
+ curwin = firstwin;
+ curbuf = curwin->w_buffer;
+ --autocmd_no_enter;
+ --autocmd_no_leave;
+ }
+}
+
+/*
+ * If opened more than one window, start editing files in the other
+ * windows. make_windows() has already opened the windows.
+ */
+static void edit_buffers(parmp)
+ mparm_T *parmp;
+{
+ int arg_idx; /* index in argument list */
+ int i;
+ int advance = TRUE;
+ win_T *win;
+
+ /*
+ * Don't execute Win/Buf Enter/Leave autocommands here
+ */
+ ++autocmd_no_enter;
+ ++autocmd_no_leave;
+
+ /* When w_arg_idx is -1 remove the window (see create_windows()). */
+ if (curwin->w_arg_idx == -1) {
+ win_close(curwin, TRUE);
+ advance = FALSE;
+ }
+
+ arg_idx = 1;
+ for (i = 1; i < parmp->window_count; ++i) {
+ /* 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;
+ continue;
+ }
+
+ if (advance) {
+ if (parmp->window_layout == WIN_TABS) {
+ if (curtab->tp_next == NULL) /* just checking */
+ break;
+ goto_tabpage(0);
+ } else {
+ if (curwin->w_next == NULL) /* just checking */
+ break;
+ win_enter(curwin->w_next, FALSE);
+ }
+ }
+ advance = TRUE;
+
+ /* Only open the file if there is no file in this window yet (that can
+ * happen when .vimrc contains ":sall"). */
+ if (curbuf == firstwin->w_buffer || curbuf->b_ffname == NULL) {
+ curwin->w_arg_idx = arg_idx;
+ /* Edit file from arg list, if there is one. When "Quit" selected
+ * at the ATTENTION prompt close the window. */
+# ifdef HAS_SWAP_EXISTS_ACTION
+ swap_exists_did_quit = FALSE;
+# endif
+ (void)do_ecmd(0, arg_idx < GARGCOUNT
+ ? alist_name(&GARGLIST[arg_idx]) : NULL,
+ NULL, NULL, ECMD_LASTL, ECMD_HIDE, curwin);
+# ifdef HAS_SWAP_EXISTS_ACTION
+ if (swap_exists_did_quit) {
+ /* abort or quit selected */
+ if (got_int || only_one_window()) {
+ /* abort selected and only one window */
+ did_emsg = FALSE; /* avoid hit-enter prompt */
+ getout(1);
+ }
+ win_close(curwin, TRUE);
+ advance = FALSE;
+ }
+# endif
+ if (arg_idx == GARGCOUNT - 1)
+ arg_had_last = TRUE;
+ ++arg_idx;
+ }
+ ui_breakcheck();
+ if (got_int) {
+ (void)vgetc(); /* only break the file loading, not the rest */
+ break;
+ }
+ }
+
+ if (parmp->window_layout == WIN_TABS)
+ goto_tabpage(1);
+ --autocmd_no_enter;
+
+ /* make the first window the current window */
+ win = firstwin;
+ /* Avoid making a preview window the current window. */
+ while (win->w_p_pvw) {
+ win = win->w_next;
+ if (win == NULL) {
+ win = firstwin;
+ break;
+ }
+ }
+ win_enter(win, FALSE);
+
+ --autocmd_no_leave;
+ TIME_MSG("editing files in windows");
+ if (parmp->window_count > 1 && parmp->window_layout != WIN_TABS)
+ win_equal(curwin, FALSE, 'b'); /* adjust heights */
+}
+
+/*
+ * Execute the commands from --cmd arguments "cmds[cnt]".
+ */
+static void exe_pre_commands(parmp)
+ mparm_T *parmp;
+{
+ char_u **cmds = parmp->pre_commands;
+ int cnt = parmp->n_pre_commands;
+ int i;
+
+ if (cnt > 0) {
+ curwin->w_cursor.lnum = 0; /* just in case.. */
+ sourcing_name = (char_u *)_("pre-vimrc command line");
+ current_SID = SID_CMDARG;
+ for (i = 0; i < cnt; ++i)
+ do_cmdline_cmd(cmds[i]);
+ sourcing_name = NULL;
+ current_SID = 0;
+ TIME_MSG("--cmd commands");
+ }
+}
+
+/*
+ * Execute "+", "-c" and "-S" arguments.
+ */
+static void exe_commands(parmp)
+ mparm_T *parmp;
+{
+ int i;
+
+ /*
+ * We start commands on line 0, make "vim +/pat file" match a
+ * pattern on line 1. But don't move the cursor when an autocommand
+ * with g`" was used.
+ */
+ msg_scroll = TRUE;
+ if (parmp->tagname == NULL && curwin->w_cursor.lnum <= 1)
+ curwin->w_cursor.lnum = 0;
+ sourcing_name = (char_u *)"command line";
+ current_SID = SID_CARG;
+ for (i = 0; i < parmp->n_commands; ++i) {
+ do_cmdline_cmd(parmp->commands[i]);
+ if (parmp->cmds_tofree[i])
+ vim_free(parmp->commands[i]);
+ }
+ sourcing_name = NULL;
+ current_SID = 0;
+ if (curwin->w_cursor.lnum == 0)
+ curwin->w_cursor.lnum = 1;
+
+ if (!exmode_active)
+ msg_scroll = FALSE;
+
+ /* When started with "-q errorfile" jump to first error again. */
+ if (parmp->edit_type == EDIT_QF)
+ qf_jump(NULL, 0, 0, FALSE);
+ TIME_MSG("executing command arguments");
+}
+
+/*
+ * Source startup scripts.
+ */
+static void source_startup_scripts(parmp)
+ mparm_T *parmp;
+{
+ int i;
+
+ /*
+ * For "evim" source evim.vim first of all, so that the user can overrule
+ * any things he doesn't like.
+ */
+ if (parmp->evim_mode) {
+ (void)do_source((char_u *)EVIM_FILE, FALSE, DOSO_NONE);
+ TIME_MSG("source evim file");
+ }
+
+ /*
+ * If -u argument 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 */
+ } else {
+ if (do_source(parmp->use_vimrc, FALSE, DOSO_NONE) != OK)
+ EMSG2(_("E282: Cannot read from \"%s\""), parmp->use_vimrc);
+ }
+ } else if (!silent_mode) {
+
+ /*
+ * Get system wide defaults, if the file name is defined.
+ */
+#ifdef SYS_VIMRC_FILE
+ (void)do_source((char_u *)SYS_VIMRC_FILE, FALSE, DOSO_NONE);
+#endif
+
+ /*
+ * Try to read initialization commands from the following places:
+ * - environment variable VIMINIT
+ * - user vimrc file (s:.vimrc for Amiga, ~/.vimrc otherwise)
+ * - second user vimrc file ($VIM/.vimrc for Dos)
+ * - environment variable EXINIT
+ * - user exrc file (s:.exrc for Amiga, ~/.exrc otherwise)
+ * - second user exrc file ($VIM/.exrc for Dos)
+ * The first that exists is used, the rest is ignored.
+ */
+ if (process_env((char_u *)"VIMINIT", TRUE) != OK) {
+ if (do_source((char_u *)USR_VIMRC_FILE, TRUE, DOSO_VIMRC) == FAIL
+#ifdef USR_VIMRC_FILE2
+ && do_source((char_u *)USR_VIMRC_FILE2, TRUE,
+ DOSO_VIMRC) == FAIL
+#endif
+#ifdef USR_VIMRC_FILE3
+ && do_source((char_u *)USR_VIMRC_FILE3, TRUE,
+ DOSO_VIMRC) == FAIL
+#endif
+#ifdef USR_VIMRC_FILE4
+ && do_source((char_u *)USR_VIMRC_FILE4, TRUE,
+ DOSO_VIMRC) == FAIL
+#endif
+ && process_env((char_u *)"EXINIT", FALSE) == FAIL
+ && do_source((char_u *)USR_EXRC_FILE, FALSE, DOSO_NONE) == FAIL) {
+#ifdef USR_EXRC_FILE2
+ (void)do_source((char_u *)USR_EXRC_FILE2, FALSE, DOSO_NONE);
+#endif
+ }
+ }
+
+ /*
+ * Read initialization commands from ".vimrc" or ".exrc" in current
+ * directory. This is only done if the 'exrc' option is set.
+ * Because of security reasons we disallow shell and write commands
+ * now, except for unix if the file is owned by the user or 'secure'
+ * option has been reset in environment of global ".exrc" or ".vimrc".
+ * Only do this if VIMRC_FILE is not the same as USR_VIMRC_FILE or
+ * SYS_VIMRC_FILE.
+ */
+ if (p_exrc) {
+#if defined(UNIX) || defined(VMS)
+ /* If ".vimrc" file is not owned by user, set 'secure' mode. */
+ if (!file_owned(VIMRC_FILE))
+#endif
+ secure = p_secure;
+
+ i = FAIL;
+ if (fullpathcmp((char_u *)USR_VIMRC_FILE,
+ (char_u *)VIMRC_FILE, FALSE) != FPC_SAME
+#ifdef USR_VIMRC_FILE2
+ && fullpathcmp((char_u *)USR_VIMRC_FILE2,
+ (char_u *)VIMRC_FILE, FALSE) != FPC_SAME
+#endif
+#ifdef USR_VIMRC_FILE3
+ && fullpathcmp((char_u *)USR_VIMRC_FILE3,
+ (char_u *)VIMRC_FILE, FALSE) != FPC_SAME
+#endif
+#ifdef SYS_VIMRC_FILE
+ && fullpathcmp((char_u *)SYS_VIMRC_FILE,
+ (char_u *)VIMRC_FILE, FALSE) != FPC_SAME
+#endif
+ )
+ i = do_source((char_u *)VIMRC_FILE, TRUE, DOSO_VIMRC);
+
+ if (i == FAIL) {
+#if defined(UNIX) || defined(VMS)
+ /* if ".exrc" is not owned by user set 'secure' mode */
+ if (!file_owned(EXRC_FILE))
+ secure = p_secure;
+ else
+ secure = 0;
+#endif
+ if ( fullpathcmp((char_u *)USR_EXRC_FILE,
+ (char_u *)EXRC_FILE, FALSE) != FPC_SAME
+#ifdef USR_EXRC_FILE2
+ && fullpathcmp((char_u *)USR_EXRC_FILE2,
+ (char_u *)EXRC_FILE, FALSE) != FPC_SAME
+#endif
+ )
+ (void)do_source((char_u *)EXRC_FILE, FALSE, DOSO_NONE);
+ }
+ }
+ if (secure == 2)
+ need_wait_return = TRUE;
+ secure = 0;
+ }
+ TIME_MSG("sourcing vimrc file(s)");
+}
+
+/*
+ * Setup to start using the GUI. Exit with an error when not available.
+ */
+static void main_start_gui() {
+ mch_errmsg(_(e_nogvim));
+ mch_errmsg("\n");
+ mch_exit(2);
+}
+
+#endif /* NO_VIM_MAIN */
+
+/*
+ * Get an environment variable, and execute it as Ex commands.
+ * Returns FAIL if the environment variable was not executed, OK otherwise.
+ */
+int process_env(env, is_viminit)
+ char_u *env;
+ int is_viminit; /* when TRUE, called for VIMINIT */
+{
+ char_u *initstr;
+ char_u *save_sourcing_name;
+ linenr_T save_sourcing_lnum;
+ scid_T save_sid;
+
+ if ((initstr = mch_getenv(env)) != NULL && *initstr != NUL) {
+ if (is_viminit)
+ vimrc_found(NULL, NULL);
+ save_sourcing_name = sourcing_name;
+ save_sourcing_lnum = sourcing_lnum;
+ sourcing_name = env;
+ sourcing_lnum = 0;
+ save_sid = current_SID;
+ current_SID = SID_ENV;
+ do_cmdline_cmd(initstr);
+ sourcing_name = save_sourcing_name;
+ sourcing_lnum = save_sourcing_lnum;
+ current_SID = save_sid;;
+ return OK;
+ }
+ return FAIL;
+}
+
+#if (defined(UNIX) || defined(VMS)) && !defined(NO_VIM_MAIN)
+/*
+ * Return TRUE if we are certain the user owns the file "fname".
+ * Used for ".vimrc" and ".exrc".
+ * Use both stat() and lstat() for extra security.
+ */
+static int file_owned(fname)
+ char *fname;
+{
+ struct stat s;
+# ifdef UNIX
+ uid_t uid = getuid();
+# else /* VMS */
+ uid_t uid = ((getgid() << 16) | getuid());
+# endif
+
+ return !(mch_stat(fname, &s) != 0 || s.st_uid != uid
+# ifdef HAVE_LSTAT
+ || mch_lstat(fname, &s) != 0 || s.st_uid != uid
+# endif
+ );
+}
+#endif
+
+/*
+ * Give an error message main_errors["n"] and exit.
+ */
+static void mainerr(n, str)
+ int n; /* one of the ME_ defines */
+ char_u *str; /* extra argument or NULL */
+{
+#if defined(UNIX) || defined(__EMX__) || defined(VMS)
+ reset_signals(); /* kill us with CTRL-C here, if you like */
+#endif
+
+ mch_errmsg(longVersion);
+ mch_errmsg("\n");
+ mch_errmsg(_(main_errors[n]));
+ if (str != NULL) {
+ mch_errmsg(": \"");
+ mch_errmsg((char *)str);
+ mch_errmsg("\"");
+ }
+ mch_errmsg(_("\nMore info with: \"vim -h\"\n"));
+
+ mch_exit(1);
+}
+
+void mainerr_arg_missing(str)
+ char_u *str;
+{
+ mainerr(ME_ARG_MISSING, str);
+}
+
+#ifndef NO_VIM_MAIN
+/*
+ * print a message with three spaces prepended and '\n' appended.
+ */
+static void main_msg(s)
+ char *s;
+{
+ mch_msg(" ");
+ mch_msg(s);
+ mch_msg("\n");
+}
+
+/*
+ * Print messages for "vim -h" or "vim --help" and exit.
+ */
+static void usage() {
+ int i;
+ static char *(use[]) =
+ {
+ N_("[file ..] edit specified file(s)"),
+ N_("- read text from stdin"),
+ N_("-t tag edit file where tag is defined"),
+ N_("-q [errorfile] edit file with first error")
+ };
+
+#if defined(UNIX) || defined(__EMX__) || defined(VMS)
+ reset_signals(); /* kill us with CTRL-C here, if you like */
+#endif
+
+ mch_msg(longVersion);
+ mch_msg(_("\n\nusage:"));
+ for (i = 0;; ++i) {
+ mch_msg(_(" vim [arguments] "));
+ mch_msg(_(use[i]));
+ if (i == (sizeof(use) / sizeof(char_u *)) - 1)
+ break;
+ mch_msg(_("\n or:"));
+ }
+
+ mch_msg(_("\n\nArguments:\n"));
+ main_msg(_("--\t\t\tOnly file names after this"));
+#if (!defined(UNIX) && !defined(__EMX__)) || defined(ARCHIE)
+ main_msg(_("--literal\t\tDon't expand wildcards"));
+#endif
+#ifdef FEAT_OLE
+ main_msg(_("-register\t\tRegister this gvim for OLE"));
+ main_msg(_("-unregister\t\tUnregister gvim for OLE"));
+#endif
+ main_msg(_("-v\t\t\tVi mode (like \"vi\")"));
+ main_msg(_("-e\t\t\tEx mode (like \"ex\")"));
+ main_msg(_("-E\t\t\tImproved Ex mode"));
+ main_msg(_("-s\t\t\tSilent (batch) mode (only for \"ex\")"));
+ main_msg(_("-d\t\t\tDiff mode (like \"vimdiff\")"));
+ main_msg(_("-y\t\t\tEasy mode (like \"evim\", modeless)"));
+ main_msg(_("-R\t\t\tReadonly mode (like \"view\")"));
+ main_msg(_("-Z\t\t\tRestricted mode (like \"rvim\")"));
+ main_msg(_("-m\t\t\tModifications (writing files) not allowed"));
+ main_msg(_("-M\t\t\tModifications in text not allowed"));
+ main_msg(_("-b\t\t\tBinary mode"));
+ main_msg(_("-l\t\t\tLisp mode"));
+ main_msg(_("-C\t\t\tCompatible with Vi: 'compatible'"));
+ main_msg(_("-N\t\t\tNot fully Vi compatible: 'nocompatible'"));
+ main_msg(_("-V[N][fname]\t\tBe verbose [level N] [log messages to fname]"));
+ main_msg(_("-D\t\t\tDebugging mode"));
+ main_msg(_("-n\t\t\tNo swap file, use memory only"));
+ main_msg(_("-r\t\t\tList swap files and exit"));
+ main_msg(_("-r (with file name)\tRecover crashed session"));
+ main_msg(_("-L\t\t\tSame as -r"));
+ main_msg(_("-A\t\t\tstart in Arabic mode"));
+ main_msg(_("-H\t\t\tStart in Hebrew mode"));
+ main_msg(_("-F\t\t\tStart in Farsi mode"));
+ main_msg(_("-T <terminal>\tSet terminal type to <terminal>"));
+ main_msg(_("-u <vimrc>\t\tUse <vimrc> instead of any .vimrc"));
+ main_msg(_("--noplugin\t\tDon't load plugin scripts"));
+ main_msg(_("-p[N]\t\tOpen N tab pages (default: one for each file)"));
+ main_msg(_("-o[N]\t\tOpen N windows (default: one for each file)"));
+ main_msg(_("-O[N]\t\tLike -o but split vertically"));
+ main_msg(_("+\t\t\tStart at end of file"));
+ main_msg(_("+<lnum>\t\tStart at line <lnum>"));
+ main_msg(_("--cmd <command>\tExecute <command> before loading any vimrc file"));
+ main_msg(_("-c <command>\t\tExecute <command> after loading the first file"));
+ main_msg(_(
+ "-S <session>\t\tSource file <session> after loading the first file"));
+ main_msg(_("-s <scriptin>\tRead Normal mode commands from file <scriptin>"));
+ main_msg(_("-w <scriptout>\tAppend all typed commands to file <scriptout>"));
+ main_msg(_("-W <scriptout>\tWrite all typed commands to file <scriptout>"));
+ main_msg(_("-x\t\t\tEdit encrypted files"));
+#ifdef STARTUPTIME
+ main_msg(_("--startuptime <file>\tWrite startup timing messages to <file>"));
+#endif
+ main_msg(_("-i <viminfo>\t\tUse <viminfo> instead of .viminfo"));
+ main_msg(_("-h or --help\tPrint Help (this message) and exit"));
+ main_msg(_("--version\t\tPrint version information and exit"));
+
+
+ mch_exit(0);
+}
+
+#if defined(HAS_SWAP_EXISTS_ACTION)
+/*
+ * Check the result of the ATTENTION dialog:
+ * When "Quit" selected, exit Vim.
+ * When "Recover" selected, recover the file.
+ */
+static void check_swap_exists_action() {
+ if (swap_exists_action == SEA_QUIT)
+ getout(1);
+ handle_swap_exists(NULL);
+}
+
+#endif
+
+#endif
+
+#if defined(STARTUPTIME) || defined(PROTO)
+static void time_diff __ARGS((struct timeval *then, struct timeval *now));
+
+static struct timeval prev_timeval;
+
+
+/*
+ * Save the previous time before doing something that could nest.
+ * set "*tv_rel" to the time elapsed so far.
+ */
+void time_push(tv_rel, tv_start)
+ void *tv_rel, *tv_start;
+{
+ *((struct timeval *)tv_rel) = prev_timeval;
+ gettimeofday(&prev_timeval, NULL);
+ ((struct timeval *)tv_rel)->tv_usec = prev_timeval.tv_usec
+ - ((struct timeval *)tv_rel)->tv_usec;
+ ((struct timeval *)tv_rel)->tv_sec = prev_timeval.tv_sec
+ - ((struct timeval *)tv_rel)->tv_sec;
+ if (((struct timeval *)tv_rel)->tv_usec < 0) {
+ ((struct timeval *)tv_rel)->tv_usec += 1000000;
+ --((struct timeval *)tv_rel)->tv_sec;
+ }
+ *(struct timeval *)tv_start = prev_timeval;
+}
+
+/*
+ * Compute the previous time after doing something that could nest.
+ * Subtract "*tp" from prev_timeval;
+ * Note: The arguments are (void *) to avoid trouble with systems that don't
+ * have struct timeval.
+ */
+void time_pop(tp)
+ void *tp; /* actually (struct timeval *) */
+{
+ prev_timeval.tv_usec -= ((struct timeval *)tp)->tv_usec;
+ prev_timeval.tv_sec -= ((struct timeval *)tp)->tv_sec;
+ if (prev_timeval.tv_usec < 0) {
+ prev_timeval.tv_usec += 1000000;
+ --prev_timeval.tv_sec;
+ }
+}
+
+static void time_diff(then, now)
+ struct timeval *then;
+ struct timeval *now;
+{
+ long usec;
+ long msec;
+
+ usec = now->tv_usec - then->tv_usec;
+ msec = (now->tv_sec - then->tv_sec) * 1000L + usec / 1000L,
+ usec = usec % 1000L;
+ fprintf(time_fd, "%03ld.%03ld", msec, usec >= 0 ? usec : usec + 1000L);
+}
+
+void time_msg(mesg, tv_start)
+ char *mesg;
+ void *tv_start; /* only for do_source: start time; actually
+ (struct timeval *) */
+{
+ static struct timeval start;
+ struct timeval now;
+
+ if (time_fd != NULL) {
+ if (strstr(mesg, "STARTING") != NULL) {
+ gettimeofday(&start, NULL);
+ prev_timeval = start;
+ fprintf(time_fd, "\n\ntimes in msec\n");
+ fprintf(time_fd, " clock self+sourced self: sourced script\n");
+ fprintf(time_fd, " clock elapsed: other lines\n\n");
+ }
+ gettimeofday(&now, NULL);
+ time_diff(&start, &now);
+ if (((struct timeval *)tv_start) != NULL) {
+ fprintf(time_fd, " ");
+ time_diff(((struct timeval *)tv_start), &now);
+ }
+ fprintf(time_fd, " ");
+ time_diff(&prev_timeval, &now);
+ prev_timeval = now;
+ fprintf(time_fd, ": %s\n", mesg);
+ }
+}
+
+#endif
+
+
+
+/*
+ * When FEAT_FKMAP is defined, also compile the Farsi source code.
+ */
+# include "farsi.c"
+
+/*
+ * When FEAT_ARABIC is defined, also compile the Arabic source code.
+ */
+# include "arabic.c"
diff --git a/src/mark.c b/src/mark.c
new file mode 100644
index 0000000000..67d962dc9e
--- /dev/null
+++ b/src/mark.c
@@ -0,0 +1,1563 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * 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.
+ */
+
+/*
+ * mark.c: functions for setting marks and jumping to them
+ */
+
+#include "vim.h"
+
+/*
+ * This file contains routines to maintain and manipulate marks.
+ */
+
+/*
+ * If a named file mark's lnum is non-zero, it is valid.
+ * If a named file mark's fnum is non-zero, it is for an existing buffer,
+ * otherwise it is from .viminfo and namedfm[n].fname is the file name.
+ * There are marks 'A - 'Z (set by user) and '0 to '9 (set when writing
+ * viminfo).
+ */
+#define EXTRA_MARKS 10 /* marks 0-9 */
+static xfmark_T namedfm[NMARKS + EXTRA_MARKS]; /* marks with file nr */
+
+static void fname2fnum __ARGS((xfmark_T *fm));
+static void fmarks_check_one __ARGS((xfmark_T *fm, char_u *name, buf_T *buf));
+static char_u *mark_line __ARGS((pos_T *mp, int lead_len));
+static void show_one_mark __ARGS((int, char_u *, pos_T *, char_u *, int current));
+static void cleanup_jumplist __ARGS((void));
+static void write_one_filemark __ARGS((FILE *fp, xfmark_T *fm, int c1, int c2));
+
+/*
+ * Set named mark "c" at current cursor position.
+ * Returns OK on success, FAIL if bad name given.
+ */
+int setmark(c)
+int c;
+{
+ return setmark_pos(c, &curwin->w_cursor, curbuf->b_fnum);
+}
+
+/*
+ * Set named mark "c" to position "pos".
+ * When "c" is upper case use file "fnum".
+ * Returns OK on success, FAIL if bad name given.
+ */
+int setmark_pos(c, pos, fnum)
+int c;
+pos_T *pos;
+int fnum;
+{
+ int i;
+
+ /* Check for a special key (may cause islower() to crash). */
+ if (c < 0)
+ return FAIL;
+
+ if (c == '\'' || c == '`') {
+ if (pos == &curwin->w_cursor) {
+ setpcmark();
+ /* keep it even when the cursor doesn't move */
+ curwin->w_prev_pcmark = curwin->w_pcmark;
+ } else
+ curwin->w_pcmark = *pos;
+ return OK;
+ }
+
+ if (c == '"') {
+ curbuf->b_last_cursor = *pos;
+ return OK;
+ }
+
+ /* Allow setting '[ and '] for an autocommand that simulates reading a
+ * file. */
+ if (c == '[') {
+ curbuf->b_op_start = *pos;
+ return OK;
+ }
+ if (c == ']') {
+ curbuf->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';
+ return OK;
+ }
+
+ if (c > 'z') /* some islower() and isupper() cannot handle
+ characters above 127 */
+ return FAIL;
+ if (islower(c)) {
+ i = c - 'a';
+ curbuf->b_namedm[i] = *pos;
+ return OK;
+ }
+ if (isupper(c)) {
+ i = c - 'A';
+ namedfm[i].fmark.mark = *pos;
+ namedfm[i].fmark.fnum = fnum;
+ vim_free(namedfm[i].fname);
+ namedfm[i].fname = NULL;
+ return OK;
+ }
+ return FAIL;
+}
+
+/*
+ * Set the previous context mark to the current position and add it to the
+ * jump list.
+ */
+void setpcmark() {
+ int i;
+ xfmark_T *fm;
+#ifdef JUMPLIST_ROTATE
+ xfmark_T tempmark;
+#endif
+
+ /* for :global the mark is set only once */
+ if (global_busy || listcmd_busy || cmdmod.keepjumps)
+ return;
+
+ curwin->w_prev_pcmark = curwin->w_pcmark;
+ curwin->w_pcmark = curwin->w_cursor;
+
+# ifdef JUMPLIST_ROTATE
+ /*
+ * If last used entry is not at the top, put it at the top by rotating
+ * the stack until it is (the newer entries will be at the bottom).
+ * Keep one entry (the last used one) at the top.
+ */
+ if (curwin->w_jumplistidx < curwin->w_jumplistlen)
+ ++curwin->w_jumplistidx;
+ while (curwin->w_jumplistidx < curwin->w_jumplistlen) {
+ tempmark = curwin->w_jumplist[curwin->w_jumplistlen - 1];
+ for (i = curwin->w_jumplistlen - 1; i > 0; --i)
+ curwin->w_jumplist[i] = curwin->w_jumplist[i - 1];
+ curwin->w_jumplist[0] = tempmark;
+ ++curwin->w_jumplistidx;
+ }
+# endif
+
+ /* If jumplist is full: remove oldest entry */
+ if (++curwin->w_jumplistlen > JUMPLISTSIZE) {
+ curwin->w_jumplistlen = JUMPLISTSIZE;
+ vim_free(curwin->w_jumplist[0].fname);
+ for (i = 1; i < JUMPLISTSIZE; ++i)
+ curwin->w_jumplist[i - 1] = curwin->w_jumplist[i];
+ }
+ curwin->w_jumplistidx = curwin->w_jumplistlen;
+ fm = &curwin->w_jumplist[curwin->w_jumplistlen - 1];
+
+ fm->fmark.mark = curwin->w_pcmark;
+ fm->fmark.fnum = curbuf->b_fnum;
+ fm->fname = NULL;
+}
+
+/*
+ * To change context, call setpcmark(), then move the current position to
+ * where ever, then call checkpcmark(). This ensures that the previous
+ * context will only be changed if the cursor moved to a different line.
+ * If pcmark was deleted (with "dG") the previous mark is restored.
+ */
+void checkpcmark() {
+ if (curwin->w_prev_pcmark.lnum != 0
+ && (equalpos(curwin->w_pcmark, curwin->w_cursor)
+ || curwin->w_pcmark.lnum == 0)) {
+ curwin->w_pcmark = curwin->w_prev_pcmark;
+ curwin->w_prev_pcmark.lnum = 0; /* Show it has been checked */
+ }
+}
+
+/*
+ * move "count" positions in the jump list (count may be negative)
+ */
+pos_T * movemark(count)
+int count;
+{
+ pos_T *pos;
+ xfmark_T *jmp;
+
+ cleanup_jumplist();
+
+ if (curwin->w_jumplistlen == 0) /* nothing to jump to */
+ return (pos_T *)NULL;
+
+ for (;; ) {
+ if (curwin->w_jumplistidx + count < 0
+ || curwin->w_jumplistidx + count >= curwin->w_jumplistlen)
+ return (pos_T *)NULL;
+
+ /*
+ * if first CTRL-O or CTRL-I command after a jump, add cursor position
+ * to list. Careful: If there are duplicates (CTRL-O immediately after
+ * starting Vim on a file), another entry may have been removed.
+ */
+ if (curwin->w_jumplistidx == curwin->w_jumplistlen) {
+ setpcmark();
+ --curwin->w_jumplistidx; /* skip the new entry */
+ if (curwin->w_jumplistidx + count < 0)
+ return (pos_T *)NULL;
+ }
+
+ curwin->w_jumplistidx += count;
+
+ jmp = curwin->w_jumplist + curwin->w_jumplistidx;
+ if (jmp->fmark.fnum == 0)
+ fname2fnum(jmp);
+ if (jmp->fmark.fnum != curbuf->b_fnum) {
+ /* jump to other file */
+ if (buflist_findnr(jmp->fmark.fnum) == NULL) { /* Skip this one .. */
+ count += count < 0 ? -1 : 1;
+ continue;
+ }
+ if (buflist_getfile(jmp->fmark.fnum, jmp->fmark.mark.lnum,
+ 0, FALSE) == FAIL)
+ return (pos_T *)NULL;
+ /* Set lnum again, autocommands my have changed it */
+ curwin->w_cursor = jmp->fmark.mark;
+ pos = (pos_T *)-1;
+ } else
+ pos = &(jmp->fmark.mark);
+ return pos;
+ }
+}
+
+/*
+ * Move "count" positions in the changelist (count may be negative).
+ */
+pos_T * movechangelist(count)
+int count;
+{
+ int n;
+
+ if (curbuf->b_changelistlen == 0) /* nothing to jump to */
+ return (pos_T *)NULL;
+
+ n = curwin->w_changelistidx;
+ if (n + count < 0) {
+ if (n == 0)
+ return (pos_T *)NULL;
+ n = 0;
+ } else if (n + count >= curbuf->b_changelistlen) {
+ if (n == curbuf->b_changelistlen - 1)
+ return (pos_T *)NULL;
+ n = curbuf->b_changelistlen - 1;
+ } else
+ n += count;
+ curwin->w_changelistidx = n;
+ return curbuf->b_changelist + n;
+}
+
+/*
+ * Find mark "c" in buffer pointed to by "buf".
+ * If "changefile" is TRUE it's allowed to edit another file for '0, 'A, etc.
+ * If "fnum" is not NULL store the fnum there for '0, 'A etc., don't edit
+ * another file.
+ * Returns:
+ * - pointer to pos_T if found. lnum is 0 when mark not set, -1 when mark is
+ * in another file which can't be gotten. (caller needs to check lnum!)
+ * - NULL if there is no mark called 'c'.
+ * - -1 if mark is in other file and jumped there (only if changefile is TRUE)
+ */
+pos_T * getmark_buf(buf, c, changefile)
+buf_T *buf;
+int c;
+int changefile;
+{
+ return getmark_buf_fnum(buf, c, changefile, NULL);
+}
+
+pos_T * getmark(c, changefile)
+int c;
+int changefile;
+{
+ return getmark_buf_fnum(curbuf, c, changefile, NULL);
+}
+
+pos_T * getmark_buf_fnum(buf, c, changefile, fnum)
+buf_T *buf;
+int c;
+int changefile;
+int *fnum;
+{
+ pos_T *posp;
+ pos_T *startp, *endp;
+ static pos_T pos_copy;
+
+ posp = NULL;
+
+ /* Check for special key, can't be a mark name and might cause islower()
+ * to crash. */
+ if (c < 0)
+ return posp;
+ if (c > '~') /* check for islower()/isupper() */
+ ;
+ else if (c == '\'' || c == '`') { /* previous context mark */
+ pos_copy = curwin->w_pcmark; /* need to make a copy because */
+ posp = &pos_copy; /* w_pcmark may be changed soon */
+ } else if (c == '"') /* to pos when leaving buffer */
+ posp = &(buf->b_last_cursor);
+ else if (c == '^') /* to where Insert mode stopped */
+ posp = &(buf->b_last_insert);
+ else if (c == '.') /* to where last change was made */
+ posp = &(buf->b_last_change);
+ else if (c == '[') /* to start of previous operator */
+ posp = &(buf->b_op_start);
+ else if (c == ']') /* to end of previous operator */
+ posp = &(buf->b_op_end);
+ else if (c == '{' || c == '}') { /* to previous/next paragraph */
+ pos_T pos;
+ oparg_T oa;
+ int slcb = listcmd_busy;
+
+ pos = curwin->w_cursor;
+ listcmd_busy = TRUE; /* avoid that '' is changed */
+ if (findpar(&oa.inclusive,
+ c == '}' ? FORWARD : BACKWARD, 1L, NUL, FALSE)) {
+ pos_copy = curwin->w_cursor;
+ posp = &pos_copy;
+ }
+ curwin->w_cursor = pos;
+ listcmd_busy = slcb;
+ } else if (c == '(' || c == ')') { /* to previous/next sentence */
+ pos_T pos;
+ int slcb = listcmd_busy;
+
+ pos = curwin->w_cursor;
+ listcmd_busy = TRUE; /* avoid that '' is changed */
+ if (findsent(c == ')' ? FORWARD : BACKWARD, 1L)) {
+ pos_copy = curwin->w_cursor;
+ posp = &pos_copy;
+ }
+ curwin->w_cursor = pos;
+ listcmd_busy = slcb;
+ } 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))
+ posp = startp;
+ else
+ posp = endp;
+ /*
+ * 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;
+ if (c == '<')
+ pos_copy.col = 0;
+ else
+ pos_copy.col = MAXCOL;
+ pos_copy.coladd = 0;
+ }
+ } else if (ASCII_ISLOWER(c)) { /* normal named mark */
+ posp = &(buf->b_namedm[c - 'a']);
+ } else if (ASCII_ISUPPER(c) || VIM_ISDIGIT(c)) { /* named file mark */
+ if (VIM_ISDIGIT(c))
+ c = c - '0' + NMARKS;
+ else
+ c -= 'A';
+ posp = &(namedfm[c].fmark.mark);
+
+ if (namedfm[c].fmark.fnum == 0)
+ fname2fnum(&namedfm[c]);
+
+ if (fnum != NULL)
+ *fnum = namedfm[c].fmark.fnum;
+ else if (namedfm[c].fmark.fnum != buf->b_fnum) {
+ /* mark is in another file */
+ posp = &pos_copy;
+
+ if (namedfm[c].fmark.mark.lnum != 0
+ && changefile && namedfm[c].fmark.fnum) {
+ if (buflist_getfile(namedfm[c].fmark.fnum,
+ (linenr_T)1, GETF_SETMARK, FALSE) == OK) {
+ /* Set the lnum now, autocommands could have changed it */
+ curwin->w_cursor = namedfm[c].fmark.mark;
+ return (pos_T *)-1;
+ }
+ pos_copy.lnum = -1; /* can't get file */
+ } else
+ pos_copy.lnum = 0; /* mark exists, but is not valid in
+ current buffer */
+ }
+ }
+
+ return posp;
+}
+
+/*
+ * Search for the next named mark in the current file.
+ *
+ * Returns pointer to pos_T of the next mark or NULL if no mark is found.
+ */
+pos_T * getnextmark(startpos, dir, begin_line)
+pos_T *startpos; /* where to start */
+int dir; /* direction for search */
+int begin_line;
+{
+ int i;
+ pos_T *result = NULL;
+ pos_T pos;
+
+ pos = *startpos;
+
+ /* When searching backward and leaving the cursor on the first non-blank,
+ * position must be in a previous line.
+ * When searching forward and leaving the cursor on the first non-blank,
+ * position must be in a next line. */
+ if (dir == BACKWARD && begin_line)
+ pos.col = 0;
+ else if (dir == FORWARD && begin_line)
+ pos.col = MAXCOL;
+
+ for (i = 0; i < NMARKS; i++) {
+ if (curbuf->b_namedm[i].lnum > 0) {
+ if (dir == FORWARD) {
+ if ((result == NULL || lt(curbuf->b_namedm[i], *result))
+ && lt(pos, curbuf->b_namedm[i]))
+ result = &curbuf->b_namedm[i];
+ } else {
+ if ((result == NULL || lt(*result, curbuf->b_namedm[i]))
+ && lt(curbuf->b_namedm[i], pos))
+ result = &curbuf->b_namedm[i];
+ }
+ }
+ }
+
+ return result;
+}
+
+/*
+ * For an xtended filemark: set the fnum from the fname.
+ * This is used for marks obtained from the .viminfo file. It's postponed
+ * until the mark is used to avoid a long startup delay.
+ */
+static void fname2fnum(fm)
+xfmark_T *fm;
+{
+ char_u *p;
+
+ if (fm->fname != NULL) {
+ /*
+ * First expand "~/" in the file name to the home directory.
+ * Don't expand the whole name, it may contain other '~' chars.
+ */
+ if (fm->fname[0] == '~' && (fm->fname[1] == '/'
+#ifdef BACKSLASH_IN_FILENAME
+ || fm->fname[1] == '\\'
+#endif
+ )) {
+ int len;
+
+ expand_env((char_u *)"~/", NameBuff, MAXPATHL);
+ len = (int)STRLEN(NameBuff);
+ vim_strncpy(NameBuff + len, fm->fname + 2, MAXPATHL - len - 1);
+ } else
+ vim_strncpy(NameBuff, fm->fname, MAXPATHL - 1);
+
+ /* Try to shorten the file name. */
+ mch_dirname(IObuff, IOSIZE);
+ p = shorten_fname(NameBuff, IObuff);
+
+ /* buflist_new() will call fmarks_check_names() */
+ (void)buflist_new(NameBuff, p, (linenr_T)1, 0);
+ }
+}
+
+/*
+ * Check all file marks for a name that matches the file name in buf.
+ * May replace the name with an fnum.
+ * Used for marks that come from the .viminfo file.
+ */
+void fmarks_check_names(buf)
+buf_T *buf;
+{
+ char_u *name;
+ int i;
+ win_T *wp;
+
+ if (buf->b_ffname == NULL)
+ return;
+
+ name = home_replace_save(buf, buf->b_ffname);
+ if (name == NULL)
+ return;
+
+ for (i = 0; i < NMARKS + EXTRA_MARKS; ++i)
+ fmarks_check_one(&namedfm[i], name, buf);
+
+ FOR_ALL_WINDOWS(wp)
+ {
+ for (i = 0; i < wp->w_jumplistlen; ++i)
+ fmarks_check_one(&wp->w_jumplist[i], name, buf);
+ }
+
+ vim_free(name);
+}
+
+static void fmarks_check_one(fm, name, buf)
+xfmark_T *fm;
+char_u *name;
+buf_T *buf;
+{
+ if (fm->fmark.fnum == 0
+ && fm->fname != NULL
+ && fnamecmp(name, fm->fname) == 0) {
+ fm->fmark.fnum = buf->b_fnum;
+ vim_free(fm->fname);
+ fm->fname = NULL;
+ }
+}
+
+/*
+ * Check a if a position from a mark is valid.
+ * Give and error message and return FAIL if not.
+ */
+int check_mark(pos)
+pos_T *pos;
+{
+ if (pos == NULL) {
+ EMSG(_(e_umark));
+ return FAIL;
+ }
+ if (pos->lnum <= 0) {
+ /* lnum is negative if mark is in another file can can't get that
+ * file, error message already give then. */
+ if (pos->lnum == 0)
+ EMSG(_(e_marknotset));
+ return FAIL;
+ }
+ if (pos->lnum > curbuf->b_ml.ml_line_count) {
+ EMSG(_(e_markinval));
+ return FAIL;
+ }
+ return OK;
+}
+
+/*
+ * clrallmarks() - clear all marks in the buffer 'buf'
+ *
+ * Used mainly when trashing the entire buffer during ":e" type commands
+ */
+void clrallmarks(buf)
+buf_T *buf;
+{
+ static int i = -1;
+
+ if (i == -1) /* first call ever: initialize */
+ for (i = 0; i < NMARKS + 1; i++) {
+ namedfm[i].fmark.mark.lnum = 0;
+ namedfm[i].fname = NULL;
+ }
+
+ for (i = 0; i < NMARKS; i++)
+ buf->b_namedm[i].lnum = 0;
+ buf->b_op_start.lnum = 0; /* start/end op mark cleared */
+ buf->b_op_end.lnum = 0;
+ buf->b_last_cursor.lnum = 1; /* '" mark cleared */
+ buf->b_last_cursor.col = 0;
+ buf->b_last_cursor.coladd = 0;
+ buf->b_last_insert.lnum = 0; /* '^ mark cleared */
+ buf->b_last_change.lnum = 0; /* '. mark cleared */
+ buf->b_changelistlen = 0;
+}
+
+/*
+ * Get name of file from a filemark.
+ * When it's in the current buffer, return the text at the mark.
+ * Returns an allocated string.
+ */
+char_u * fm_getname(fmark, lead_len)
+fmark_T *fmark;
+int lead_len;
+{
+ if (fmark->fnum == curbuf->b_fnum) /* current buffer */
+ return mark_line(&(fmark->mark), lead_len);
+ return buflist_nr2name(fmark->fnum, FALSE, TRUE);
+}
+
+/*
+ * Return the line at mark "mp". Truncate to fit in window.
+ * The returned string has been allocated.
+ */
+static char_u * mark_line(mp, lead_len)
+pos_T *mp;
+int lead_len;
+{
+ char_u *s, *p;
+ int len;
+
+ if (mp->lnum == 0 || mp->lnum > curbuf->b_ml.ml_line_count)
+ return vim_strsave((char_u *)"-invalid-");
+ s = vim_strnsave(skipwhite(ml_get(mp->lnum)), (int)Columns);
+ if (s == NULL)
+ return NULL;
+ /* Truncate the line to fit it in the window */
+ len = 0;
+ for (p = s; *p != NUL; mb_ptr_adv(p)) {
+ len += ptr2cells(p);
+ if (len >= Columns - lead_len)
+ break;
+ }
+ *p = NUL;
+ return s;
+}
+
+/*
+ * print the marks
+ */
+void do_marks(eap)
+exarg_T *eap;
+{
+ char_u *arg = eap->arg;
+ int i;
+ char_u *name;
+
+ if (arg != NULL && *arg == NUL)
+ arg = NULL;
+
+ show_one_mark('\'', arg, &curwin->w_pcmark, NULL, TRUE);
+ for (i = 0; i < NMARKS; ++i)
+ show_one_mark(i + 'a', arg, &curbuf->b_namedm[i], NULL, TRUE);
+ for (i = 0; i < NMARKS + EXTRA_MARKS; ++i) {
+ if (namedfm[i].fmark.fnum != 0)
+ name = fm_getname(&namedfm[i].fmark, 15);
+ else
+ name = namedfm[i].fname;
+ if (name != NULL) {
+ show_one_mark(i >= NMARKS ? i - NMARKS + '0' : i + 'A',
+ arg, &namedfm[i].fmark.mark, name,
+ namedfm[i].fmark.fnum == curbuf->b_fnum);
+ if (namedfm[i].fmark.fnum != 0)
+ vim_free(name);
+ }
+ }
+ show_one_mark('"', arg, &curbuf->b_last_cursor, NULL, TRUE);
+ show_one_mark('[', arg, &curbuf->b_op_start, NULL, TRUE);
+ show_one_mark(']', arg, &curbuf->b_op_end, NULL, TRUE);
+ show_one_mark('^', arg, &curbuf->b_last_insert, NULL, TRUE);
+ show_one_mark('.', arg, &curbuf->b_last_change, NULL, TRUE);
+ show_one_mark('<', arg, &curbuf->b_visual.vi_start, NULL, TRUE);
+ show_one_mark('>', arg, &curbuf->b_visual.vi_end, NULL, TRUE);
+ show_one_mark(-1, arg, NULL, NULL, FALSE);
+}
+
+static void show_one_mark(c, arg, p, name, current)
+int c;
+char_u *arg;
+pos_T *p;
+char_u *name;
+int current; /* in current file */
+{
+ static int did_title = FALSE;
+ int mustfree = FALSE;
+
+ if (c == -1) { /* finish up */
+ if (did_title)
+ did_title = FALSE;
+ else {
+ if (arg == NULL)
+ MSG(_("No marks set"));
+ else
+ EMSG2(_("E283: No marks matching \"%s\""), arg);
+ }
+ }
+ /* don't output anything if 'q' typed at --more-- prompt */
+ else if (!got_int
+ && (arg == NULL || vim_strchr(arg, c) != NULL)
+ && p->lnum != 0) {
+ if (!did_title) {
+ /* Highlight title */
+ MSG_PUTS_TITLE(_("\nmark line col file/text"));
+ did_title = TRUE;
+ }
+ msg_putchar('\n');
+ if (!got_int) {
+ sprintf((char *)IObuff, " %c %6ld %4d ", c, p->lnum, p->col);
+ msg_outtrans(IObuff);
+ if (name == NULL && current) {
+ name = mark_line(p, 15);
+ mustfree = TRUE;
+ }
+ if (name != NULL) {
+ msg_outtrans_attr(name, current ? hl_attr(HLF_D) : 0);
+ if (mustfree)
+ vim_free(name);
+ }
+ }
+ out_flush(); /* show one line at a time */
+ }
+}
+
+/*
+ * ":delmarks[!] [marks]"
+ */
+void ex_delmarks(eap)
+exarg_T *eap;
+{
+ char_u *p;
+ int from, to;
+ int i;
+ int lower;
+ int digit;
+ int n;
+
+ if (*eap->arg == NUL && eap->forceit)
+ /* clear all marks */
+ clrallmarks(curbuf);
+ else if (eap->forceit)
+ EMSG(_(e_invarg));
+ else if (*eap->arg == NUL)
+ EMSG(_(e_argreq));
+ else {
+ /* clear specified marks only */
+ for (p = eap->arg; *p != NUL; ++p) {
+ lower = ASCII_ISLOWER(*p);
+ digit = VIM_ISDIGIT(*p);
+ if (lower || digit || ASCII_ISUPPER(*p)) {
+ if (p[1] == '-') {
+ /* clear range of marks */
+ from = *p;
+ to = p[2];
+ if (!(lower ? ASCII_ISLOWER(p[2])
+ : (digit ? VIM_ISDIGIT(p[2])
+ : ASCII_ISUPPER(p[2])))
+ || to < from) {
+ EMSG2(_(e_invarg2), p);
+ return;
+ }
+ p += 2;
+ } else
+ /* clear one lower case mark */
+ from = to = *p;
+
+ for (i = from; i <= to; ++i) {
+ if (lower)
+ curbuf->b_namedm[i - 'a'].lnum = 0;
+ else {
+ if (digit)
+ n = i - '0' + NMARKS;
+ else
+ n = i - 'A';
+ namedfm[n].fmark.mark.lnum = 0;
+ vim_free(namedfm[n].fname);
+ namedfm[n].fname = NULL;
+ }
+ }
+ } else
+ switch (*p) {
+ case '"': curbuf->b_last_cursor.lnum = 0; break;
+ case '^': curbuf->b_last_insert.lnum = 0; break;
+ case '.': curbuf->b_last_change.lnum = 0; break;
+ case '[': curbuf->b_op_start.lnum = 0; break;
+ case ']': curbuf->b_op_end.lnum = 0; break;
+ case '<': curbuf->b_visual.vi_start.lnum = 0; break;
+ case '>': curbuf->b_visual.vi_end.lnum = 0; break;
+ case ' ': break;
+ default: EMSG2(_(e_invarg2), p);
+ return;
+ }
+ }
+ }
+}
+
+/*
+ * print the jumplist
+ */
+void ex_jumps(eap)
+exarg_T *eap UNUSED;
+{
+ int i;
+ char_u *name;
+
+ cleanup_jumplist();
+ /* Highlight title */
+ MSG_PUTS_TITLE(_("\n jump line col file/text"));
+ for (i = 0; i < curwin->w_jumplistlen && !got_int; ++i) {
+ if (curwin->w_jumplist[i].fmark.mark.lnum != 0) {
+ if (curwin->w_jumplist[i].fmark.fnum == 0)
+ fname2fnum(&curwin->w_jumplist[i]);
+ name = fm_getname(&curwin->w_jumplist[i].fmark, 16);
+ if (name == NULL) /* file name not available */
+ continue;
+
+ msg_putchar('\n');
+ if (got_int) {
+ vim_free(name);
+ break;
+ }
+ sprintf((char *)IObuff, "%c %2d %5ld %4d ",
+ i == curwin->w_jumplistidx ? '>' : ' ',
+ i > curwin->w_jumplistidx ? i - curwin->w_jumplistidx
+ : curwin->w_jumplistidx - i,
+ curwin->w_jumplist[i].fmark.mark.lnum,
+ 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);
+ vim_free(name);
+ ui_breakcheck();
+ }
+ out_flush();
+ }
+ if (curwin->w_jumplistidx == curwin->w_jumplistlen)
+ MSG_PUTS("\n>");
+}
+
+/*
+ * print the changelist
+ */
+void ex_changes(eap)
+exarg_T *eap UNUSED;
+{
+ int i;
+ char_u *name;
+
+ /* Highlight title */
+ MSG_PUTS_TITLE(_("\nchange line col text"));
+
+ for (i = 0; i < curbuf->b_changelistlen && !got_int; ++i) {
+ if (curbuf->b_changelist[i].lnum != 0) {
+ msg_putchar('\n');
+ if (got_int)
+ break;
+ sprintf((char *)IObuff, "%c %3d %5ld %4d ",
+ i == curwin->w_changelistidx ? '>' : ' ',
+ i > curwin->w_changelistidx ? i - curwin->w_changelistidx
+ : curwin->w_changelistidx - i,
+ (long)curbuf->b_changelist[i].lnum,
+ curbuf->b_changelist[i].col);
+ msg_outtrans(IObuff);
+ name = mark_line(&curbuf->b_changelist[i], 17);
+ if (name == NULL)
+ break;
+ msg_outtrans_attr(name, hl_attr(HLF_D));
+ vim_free(name);
+ ui_breakcheck();
+ }
+ out_flush();
+ }
+ if (curwin->w_changelistidx == curbuf->b_changelistlen)
+ MSG_PUTS("\n>");
+}
+
+#define one_adjust(add) \
+ { \
+ lp = add; \
+ if (*lp >= line1 && *lp <= line2) \
+ { \
+ if (amount == MAXLNUM) \
+ *lp = 0; \
+ else \
+ *lp += amount; \
+ } \
+ else if (amount_after && *lp > line2) \
+ *lp += amount_after; \
+ }
+
+/* don't delete the line, just put at first deleted line */
+#define one_adjust_nodel(add) \
+ { \
+ lp = add; \
+ if (*lp >= line1 && *lp <= line2) \
+ { \
+ if (amount == MAXLNUM) \
+ *lp = line1; \
+ else \
+ *lp += amount; \
+ } \
+ else if (amount_after && *lp > line2) \
+ *lp += amount_after; \
+ }
+
+/*
+ * Adjust marks between line1 and line2 (inclusive) to move 'amount' lines.
+ * Must be called before changed_*(), appended_lines() or deleted_lines().
+ * May be called before or after changing the text.
+ * When deleting lines line1 to line2, use an 'amount' of MAXLNUM: The marks
+ * within this range are made invalid.
+ * If 'amount_after' is non-zero adjust marks after line2.
+ * Example: Delete lines 34 and 35: mark_adjust(34, 35, MAXLNUM, -2);
+ * Example: Insert two lines below 55: mark_adjust(56, MAXLNUM, 2, 0);
+ * or: mark_adjust(56, 55, MAXLNUM, 2);
+ */
+void mark_adjust(line1, line2, amount, amount_after)
+linenr_T line1;
+linenr_T line2;
+long amount;
+long amount_after;
+{
+ int i;
+ int fnum = curbuf->b_fnum;
+ linenr_T *lp;
+ win_T *win;
+ tabpage_T *tab;
+ static pos_T initpos = INIT_POS_T(1, 0, 0);
+
+ if (line2 < line1 && amount_after == 0L) /* nothing to do */
+ return;
+
+ if (!cmdmod.lockmarks) {
+ /* named marks, lower case and upper case */
+ for (i = 0; i < NMARKS; i++) {
+ one_adjust(&(curbuf->b_namedm[i].lnum));
+ if (namedfm[i].fmark.fnum == fnum)
+ one_adjust_nodel(&(namedfm[i].fmark.mark.lnum));
+ }
+ for (i = NMARKS; i < NMARKS + EXTRA_MARKS; i++) {
+ if (namedfm[i].fmark.fnum == fnum)
+ one_adjust_nodel(&(namedfm[i].fmark.mark.lnum));
+ }
+
+ /* last Insert position */
+ one_adjust(&(curbuf->b_last_insert.lnum));
+
+ /* last change position */
+ one_adjust(&(curbuf->b_last_change.lnum));
+
+ /* last cursor position, if it was set */
+ if (!equalpos(curbuf->b_last_cursor, initpos))
+ one_adjust(&(curbuf->b_last_cursor.lnum));
+
+
+ /* list of change positions */
+ for (i = 0; i < curbuf->b_changelistlen; ++i)
+ one_adjust_nodel(&(curbuf->b_changelist[i].lnum));
+
+ /* Visual area */
+ 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 */
+ FOR_ALL_TAB_WINDOWS(tab, win)
+ qf_mark_adjust(win, line1, line2, amount, amount_after);
+
+ }
+
+ /* previous context mark */
+ one_adjust(&(curwin->w_pcmark.lnum));
+
+ /* previous pcmark */
+ one_adjust(&(curwin->w_prev_pcmark.lnum));
+
+ /* saved cursor for formatting */
+ if (saved_cursor.lnum != 0)
+ one_adjust_nodel(&(saved_cursor.lnum));
+
+ /*
+ * Adjust items in all windows related to the current buffer.
+ */
+ FOR_ALL_TAB_WINDOWS(tab, win)
+ {
+ if (!cmdmod.lockmarks)
+ /* Marks in the jumplist. When deleting lines, this may create
+ * duplicate marks in the jumplist, they will be removed later. */
+ for (i = 0; i < win->w_jumplistlen; ++i)
+ if (win->w_jumplist[i].fmark.fnum == fnum)
+ one_adjust_nodel(&(win->w_jumplist[i].fmark.mark.lnum));
+
+ if (win->w_buffer == curbuf) {
+ if (!cmdmod.lockmarks)
+ /* marks in the tag stack */
+ for (i = 0; i < win->w_tagstacklen; i++)
+ if (win->w_tagstack[i].fmark.fnum == fnum)
+ one_adjust_nodel(&(win->w_tagstack[i].fmark.mark.lnum));
+
+ /* the displayed Visual area */
+ if (win->w_old_cursor_lnum != 0) {
+ one_adjust_nodel(&(win->w_old_cursor_lnum));
+ one_adjust_nodel(&(win->w_old_visual_lnum));
+ }
+
+ /* topline and cursor position for windows with the same buffer
+ * other than the current window */
+ if (win != curwin) {
+ if (win->w_topline >= line1 && win->w_topline <= line2) {
+ if (amount == MAXLNUM) { /* topline is deleted */
+ if (line1 <= 1)
+ win->w_topline = 1;
+ else
+ win->w_topline = line1 - 1;
+ } else /* keep topline on the same line */
+ win->w_topline += amount;
+ win->w_topfill = 0;
+ } else if (amount_after && win->w_topline > line2) {
+ win->w_topline += amount_after;
+ win->w_topfill = 0;
+ }
+ if (win->w_cursor.lnum >= line1 && win->w_cursor.lnum <= line2) {
+ if (amount == MAXLNUM) { /* line with cursor is deleted */
+ if (line1 <= 1)
+ win->w_cursor.lnum = 1;
+ else
+ win->w_cursor.lnum = line1 - 1;
+ win->w_cursor.col = 0;
+ } else /* keep cursor on the same line */
+ win->w_cursor.lnum += amount;
+ } else if (amount_after && win->w_cursor.lnum > line2)
+ win->w_cursor.lnum += amount_after;
+ }
+
+ /* adjust folds */
+ foldMarkAdjust(win, line1, line2, amount, amount_after);
+ }
+ }
+
+ /* adjust diffs */
+ diff_mark_adjust(line1, line2, amount, amount_after);
+}
+
+/* This code is used often, needs to be fast. */
+#define col_adjust(pp) \
+ { \
+ posp = pp; \
+ if (posp->lnum == lnum && posp->col >= mincol) \
+ { \
+ posp->lnum += lnum_amount; \
+ if (col_amount < 0 && posp->col <= (colnr_T)-col_amount) \
+ posp->col = 0; \
+ else \
+ posp->col += col_amount; \
+ } \
+ }
+
+/*
+ * Adjust marks in line "lnum" at column "mincol" and further: add
+ * "lnum_amount" to the line number and add "col_amount" to the column
+ * position.
+ */
+void mark_col_adjust(lnum, mincol, lnum_amount, col_amount)
+linenr_T lnum;
+colnr_T mincol;
+long lnum_amount;
+long col_amount;
+{
+ int i;
+ int fnum = curbuf->b_fnum;
+ win_T *win;
+ pos_T *posp;
+
+ if ((col_amount == 0L && lnum_amount == 0L) || cmdmod.lockmarks)
+ return; /* nothing to do */
+
+ /* named marks, lower case and upper case */
+ for (i = 0; i < NMARKS; i++) {
+ col_adjust(&(curbuf->b_namedm[i]));
+ if (namedfm[i].fmark.fnum == fnum)
+ col_adjust(&(namedfm[i].fmark.mark));
+ }
+ for (i = NMARKS; i < NMARKS + EXTRA_MARKS; i++) {
+ if (namedfm[i].fmark.fnum == fnum)
+ col_adjust(&(namedfm[i].fmark.mark));
+ }
+
+ /* last Insert position */
+ col_adjust(&(curbuf->b_last_insert));
+
+ /* last change position */
+ col_adjust(&(curbuf->b_last_change));
+
+ /* list of change positions */
+ for (i = 0; i < curbuf->b_changelistlen; ++i)
+ col_adjust(&(curbuf->b_changelist[i]));
+
+ /* Visual area */
+ col_adjust(&(curbuf->b_visual.vi_start));
+ col_adjust(&(curbuf->b_visual.vi_end));
+
+ /* previous context mark */
+ col_adjust(&(curwin->w_pcmark));
+
+ /* previous pcmark */
+ col_adjust(&(curwin->w_prev_pcmark));
+
+ /* saved cursor for formatting */
+ col_adjust(&saved_cursor);
+
+ /*
+ * Adjust items in all windows related to the current buffer.
+ */
+ FOR_ALL_WINDOWS(win)
+ {
+ /* marks in the jumplist */
+ for (i = 0; i < win->w_jumplistlen; ++i)
+ if (win->w_jumplist[i].fmark.fnum == fnum)
+ col_adjust(&(win->w_jumplist[i].fmark.mark));
+
+ if (win->w_buffer == curbuf) {
+ /* marks in the tag stack */
+ for (i = 0; i < win->w_tagstacklen; i++)
+ if (win->w_tagstack[i].fmark.fnum == fnum)
+ col_adjust(&(win->w_tagstack[i].fmark.mark));
+
+ /* cursor position for other windows with the same buffer */
+ if (win != curwin)
+ col_adjust(&win->w_cursor);
+ }
+ }
+}
+
+/*
+ * When deleting lines, this may create duplicate marks in the
+ * jumplist. They will be removed here for the current window.
+ */
+static void cleanup_jumplist() {
+ int i;
+ int from, to;
+
+ to = 0;
+ for (from = 0; from < curwin->w_jumplistlen; ++from) {
+ if (curwin->w_jumplistidx == from)
+ curwin->w_jumplistidx = to;
+ for (i = from + 1; i < curwin->w_jumplistlen; ++i)
+ if (curwin->w_jumplist[i].fmark.fnum
+ == curwin->w_jumplist[from].fmark.fnum
+ && curwin->w_jumplist[from].fmark.fnum != 0
+ && curwin->w_jumplist[i].fmark.mark.lnum
+ == curwin->w_jumplist[from].fmark.mark.lnum)
+ break;
+ if (i >= curwin->w_jumplistlen) /* no duplicate */
+ curwin->w_jumplist[to++] = curwin->w_jumplist[from];
+ else
+ vim_free(curwin->w_jumplist[from].fname);
+ }
+ if (curwin->w_jumplistidx == curwin->w_jumplistlen)
+ curwin->w_jumplistidx = to;
+ curwin->w_jumplistlen = to;
+}
+
+/*
+ * Copy the jumplist from window "from" to window "to".
+ */
+void copy_jumplist(from, to)
+win_T *from;
+win_T *to;
+{
+ int i;
+
+ for (i = 0; i < from->w_jumplistlen; ++i) {
+ to->w_jumplist[i] = from->w_jumplist[i];
+ if (from->w_jumplist[i].fname != NULL)
+ to->w_jumplist[i].fname = vim_strsave(from->w_jumplist[i].fname);
+ }
+ to->w_jumplistlen = from->w_jumplistlen;
+ to->w_jumplistidx = from->w_jumplistidx;
+}
+
+/*
+ * Free items in the jumplist of window "wp".
+ */
+void free_jumplist(wp)
+win_T *wp;
+{
+ int i;
+
+ for (i = 0; i < wp->w_jumplistlen; ++i)
+ vim_free(wp->w_jumplist[i].fname);
+}
+
+void set_last_cursor(win)
+win_T *win;
+{
+ if (win->w_buffer != NULL)
+ win->w_buffer->b_last_cursor = win->w_cursor;
+}
+
+#if defined(EXITFREE) || defined(PROTO)
+void free_all_marks() {
+ int i;
+
+ for (i = 0; i < NMARKS + EXTRA_MARKS; i++)
+ if (namedfm[i].fmark.mark.lnum != 0)
+ vim_free(namedfm[i].fname);
+}
+
+#endif
+
+int read_viminfo_filemark(virp, force)
+vir_T *virp;
+int force;
+{
+ char_u *str;
+ xfmark_T *fm;
+ int i;
+
+ /* We only get here if line[0] == '\'' or '-'.
+ * Illegal mark names are ignored (for future expansion). */
+ str = virp->vir_line + 1;
+ if (
+ *str <= 127 &&
+ ((*virp->vir_line == '\'' && (VIM_ISDIGIT(*str) || isupper(*str)))
+ || (*virp->vir_line == '-' && *str == '\''))) {
+ if (*str == '\'') {
+ /* If the jumplist isn't full insert fmark as oldest entry */
+ if (curwin->w_jumplistlen == JUMPLISTSIZE)
+ fm = NULL;
+ else {
+ for (i = curwin->w_jumplistlen; i > 0; --i)
+ curwin->w_jumplist[i] = curwin->w_jumplist[i - 1];
+ ++curwin->w_jumplistidx;
+ ++curwin->w_jumplistlen;
+ fm = &curwin->w_jumplist[0];
+ fm->fmark.mark.lnum = 0;
+ fm->fname = NULL;
+ }
+ } else if (VIM_ISDIGIT(*str))
+ fm = &namedfm[*str - '0' + NMARKS];
+ else
+ fm = &namedfm[*str - 'A'];
+ if (fm != NULL && (fm->fmark.mark.lnum == 0 || force)) {
+ str = skipwhite(str + 1);
+ fm->fmark.mark.lnum = getdigits(&str);
+ str = skipwhite(str);
+ fm->fmark.mark.col = getdigits(&str);
+ fm->fmark.mark.coladd = 0;
+ fm->fmark.fnum = 0;
+ str = skipwhite(str);
+ vim_free(fm->fname);
+ fm->fname = viminfo_readstring(virp, (int)(str - virp->vir_line),
+ FALSE);
+ }
+ }
+ return vim_fgets(virp->vir_line, LSIZE, virp->vir_fd);
+}
+
+void write_viminfo_filemarks(fp)
+FILE *fp;
+{
+ int i;
+ char_u *name;
+ buf_T *buf;
+ xfmark_T *fm;
+
+ if (get_viminfo_parameter('f') == 0)
+ return;
+
+ fputs(_("\n# File marks:\n"), fp);
+
+ /*
+ * Find a mark that is the same file and position as the cursor.
+ * That one, or else the last one is deleted.
+ * Move '0 to '1, '1 to '2, etc. until the matching one or '9
+ * Set '0 mark to current cursor position.
+ */
+ if (curbuf->b_ffname != NULL && !removable(curbuf->b_ffname)) {
+ name = buflist_nr2name(curbuf->b_fnum, TRUE, FALSE);
+ for (i = NMARKS; i < NMARKS + EXTRA_MARKS - 1; ++i)
+ if (namedfm[i].fmark.mark.lnum == curwin->w_cursor.lnum
+ && (namedfm[i].fname == NULL
+ ? namedfm[i].fmark.fnum == curbuf->b_fnum
+ : (name != NULL
+ && STRCMP(name, namedfm[i].fname) == 0)))
+ break;
+ vim_free(name);
+
+ vim_free(namedfm[i].fname);
+ for (; i > NMARKS; --i)
+ namedfm[i] = namedfm[i - 1];
+ namedfm[NMARKS].fmark.mark = curwin->w_cursor;
+ namedfm[NMARKS].fmark.fnum = curbuf->b_fnum;
+ namedfm[NMARKS].fname = NULL;
+ }
+
+ /* Write the filemarks '0 - '9 and 'A - 'Z */
+ for (i = 0; i < NMARKS + EXTRA_MARKS; i++)
+ write_one_filemark(fp, &namedfm[i], '\'',
+ i < NMARKS ? i + 'A' : i - NMARKS + '0');
+
+ /* Write the jumplist with -' */
+ fputs(_("\n# Jumplist (newest first):\n"), fp);
+ setpcmark(); /* add current cursor position */
+ cleanup_jumplist();
+ for (fm = &curwin->w_jumplist[curwin->w_jumplistlen - 1];
+ fm >= &curwin->w_jumplist[0]; --fm) {
+ if (fm->fmark.fnum == 0
+ || ((buf = buflist_findnr(fm->fmark.fnum)) != NULL
+ && !removable(buf->b_ffname)))
+ write_one_filemark(fp, fm, '-', '\'');
+ }
+}
+
+static void write_one_filemark(fp, fm, c1, c2)
+FILE *fp;
+xfmark_T *fm;
+int c1;
+int c2;
+{
+ char_u *name;
+
+ if (fm->fmark.mark.lnum == 0) /* not set */
+ return;
+
+ if (fm->fmark.fnum != 0) /* there is a buffer */
+ name = buflist_nr2name(fm->fmark.fnum, TRUE, FALSE);
+ else
+ name = fm->fname; /* use name from .viminfo */
+ if (name != NULL && *name != NUL) {
+ fprintf(fp, "%c%c %ld %ld ", c1, c2, (long)fm->fmark.mark.lnum,
+ (long)fm->fmark.mark.col);
+ viminfo_writestring(fp, name);
+ }
+
+ if (fm->fmark.fnum != 0)
+ vim_free(name);
+}
+
+/*
+ * Return TRUE if "name" is on removable media (depending on 'viminfo').
+ */
+int removable(name)
+char_u *name;
+{
+ char_u *p;
+ char_u part[51];
+ int retval = FALSE;
+ size_t n;
+
+ name = home_replace_save(NULL, name);
+ if (name != NULL) {
+ for (p = p_viminfo; *p; ) {
+ copy_option_part(&p, part, 51, ", ");
+ if (part[0] == 'r') {
+ n = STRLEN(part + 1);
+ if (MB_STRNICMP(part + 1, name, n) == 0) {
+ retval = TRUE;
+ break;
+ }
+ }
+ }
+ vim_free(name);
+ }
+ return retval;
+}
+
+static void write_one_mark __ARGS((FILE *fp_out, int c, pos_T *pos));
+
+/*
+ * Write all the named marks for all buffers.
+ * Return the number of buffers for which marks have been written.
+ */
+int write_viminfo_marks(fp_out)
+FILE *fp_out;
+{
+ int count;
+ buf_T *buf;
+ int is_mark_set;
+ int i;
+ win_T *win;
+ tabpage_T *tp;
+
+ /*
+ * Set b_last_cursor for the all buffers that have a window.
+ */
+ FOR_ALL_TAB_WINDOWS(tp, win)
+ set_last_cursor(win);
+
+ fputs(_("\n# History of marks within files (newest to oldest):\n"), fp_out);
+ count = 0;
+ for (buf = firstbuf; buf != NULL; buf = buf->b_next) {
+ /*
+ * Only write something if buffer has been loaded and at least one
+ * mark is set.
+ */
+ if (buf->b_marks_read) {
+ if (buf->b_last_cursor.lnum != 0)
+ is_mark_set = TRUE;
+ else {
+ is_mark_set = FALSE;
+ for (i = 0; i < NMARKS; i++)
+ if (buf->b_namedm[i].lnum != 0) {
+ is_mark_set = TRUE;
+ break;
+ }
+ }
+ if (is_mark_set && buf->b_ffname != NULL
+ && buf->b_ffname[0] != NUL && !removable(buf->b_ffname)) {
+ home_replace(NULL, buf->b_ffname, IObuff, IOSIZE, TRUE);
+ fprintf(fp_out, "\n> ");
+ viminfo_writestring(fp_out, IObuff);
+ write_one_mark(fp_out, '"', &buf->b_last_cursor);
+ write_one_mark(fp_out, '^', &buf->b_last_insert);
+ write_one_mark(fp_out, '.', &buf->b_last_change);
+ /* changelist positions are stored oldest first */
+ for (i = 0; i < buf->b_changelistlen; ++i)
+ write_one_mark(fp_out, '+', &buf->b_changelist[i]);
+ for (i = 0; i < NMARKS; i++)
+ write_one_mark(fp_out, 'a' + i, &buf->b_namedm[i]);
+ count++;
+ }
+ }
+ }
+
+ return count;
+}
+
+static void write_one_mark(fp_out, c, pos)
+FILE *fp_out;
+int c;
+pos_T *pos;
+{
+ if (pos->lnum != 0)
+ fprintf(fp_out, "\t%c\t%ld\t%d\n", c, (long)pos->lnum, (int)pos->col);
+}
+
+/*
+ * Handle marks in the viminfo file:
+ * fp_out != NULL: copy marks for buffers not in buffer list
+ * fp_out == NULL && (flags & VIF_WANT_MARKS): read marks for curbuf only
+ * fp_out == NULL && (flags & VIF_GET_OLDFILES | VIF_FORCEIT): fill v:oldfiles
+ */
+void copy_viminfo_marks(virp, fp_out, count, eof, flags)
+vir_T *virp;
+FILE *fp_out;
+int count;
+int eof;
+int flags;
+{
+ char_u *line = virp->vir_line;
+ buf_T *buf;
+ int num_marked_files;
+ int load_marks;
+ int copy_marks_out;
+ char_u *str;
+ int i;
+ char_u *p;
+ char_u *name_buf;
+ pos_T pos;
+ list_T *list = NULL;
+
+ if ((name_buf = alloc(LSIZE)) == NULL)
+ return;
+ *name_buf = NUL;
+
+ if (fp_out == NULL && (flags & (VIF_GET_OLDFILES | VIF_FORCEIT))) {
+ list = list_alloc();
+ if (list != NULL)
+ set_vim_var_list(VV_OLDFILES, list);
+ }
+
+ num_marked_files = get_viminfo_parameter('\'');
+ while (!eof && (count < num_marked_files || fp_out == NULL)) {
+ if (line[0] != '>') {
+ if (line[0] != '\n' && line[0] != '\r' && line[0] != '#') {
+ if (viminfo_error("E576: ", _("Missing '>'"), line))
+ break; /* too many errors, return now */
+ }
+ eof = vim_fgets(line, LSIZE, virp->vir_fd);
+ continue; /* Skip this dud line */
+ }
+
+ /*
+ * Handle long line and translate escaped characters.
+ * Find file name, set str to start.
+ * Ignore leading and trailing white space.
+ */
+ str = skipwhite(line + 1);
+ str = viminfo_readstring(virp, (int)(str - virp->vir_line), FALSE);
+ if (str == NULL)
+ continue;
+ p = str + STRLEN(str);
+ while (p != str && (*p == NUL || vim_isspace(*p)))
+ p--;
+ if (*p)
+ p++;
+ *p = NUL;
+
+ if (list != NULL)
+ list_append_string(list, str, -1);
+
+ /*
+ * If fp_out == NULL, load marks for current buffer.
+ * If fp_out != NULL, copy marks for buffers not in buflist.
+ */
+ load_marks = copy_marks_out = FALSE;
+ if (fp_out == NULL) {
+ if ((flags & VIF_WANT_MARKS) && curbuf->b_ffname != NULL) {
+ if (*name_buf == NUL) /* only need to do this once */
+ home_replace(NULL, curbuf->b_ffname, name_buf, LSIZE, TRUE);
+ if (fnamecmp(str, name_buf) == 0)
+ load_marks = TRUE;
+ }
+ } else { /* fp_out != NULL */
+ /* This is slow if there are many buffers!! */
+ for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+ if (buf->b_ffname != NULL) {
+ home_replace(NULL, buf->b_ffname, name_buf, LSIZE, TRUE);
+ if (fnamecmp(str, name_buf) == 0)
+ break;
+ }
+
+ /*
+ * copy marks if the buffer has not been loaded
+ */
+ if (buf == NULL || !buf->b_marks_read) {
+ copy_marks_out = TRUE;
+ fputs("\n> ", fp_out);
+ viminfo_writestring(fp_out, str);
+ count++;
+ }
+ }
+ vim_free(str);
+
+ pos.coladd = 0;
+ while (!(eof = viminfo_readline(virp)) && line[0] == TAB) {
+ if (load_marks) {
+ if (line[1] != NUL) {
+ unsigned u;
+
+ sscanf((char *)line + 2, "%ld %u", &pos.lnum, &u);
+ pos.col = u;
+ switch (line[1]) {
+ case '"': curbuf->b_last_cursor = pos; break;
+ case '^': curbuf->b_last_insert = pos; break;
+ case '.': curbuf->b_last_change = pos; break;
+ case '+':
+ /* changelist positions are stored oldest
+ * first */
+ if (curbuf->b_changelistlen == JUMPLISTSIZE)
+ /* list is full, remove oldest entry */
+ mch_memmove(curbuf->b_changelist,
+ curbuf->b_changelist + 1,
+ sizeof(pos_T) * (JUMPLISTSIZE - 1));
+ else
+ ++curbuf->b_changelistlen;
+ curbuf->b_changelist[
+ curbuf->b_changelistlen - 1] = pos;
+ break;
+ default: if ((i = line[1] - 'a') >= 0 && i < NMARKS)
+ curbuf->b_namedm[i] = pos;
+ }
+ }
+ } else if (copy_marks_out)
+ fputs((char *)line, fp_out);
+ }
+ if (load_marks) {
+ win_T *wp;
+
+ FOR_ALL_WINDOWS(wp)
+ {
+ if (wp->w_buffer == curbuf)
+ wp->w_changelistidx = curbuf->b_changelistlen;
+ }
+ break;
+ }
+ }
+ vim_free(name_buf);
+}
diff --git a/src/mbyte.c b/src/mbyte.c
new file mode 100644
index 0000000000..8b7abe15ee
--- /dev/null
+++ b/src/mbyte.c
@@ -0,0 +1,4217 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved by Bram Moolenaar
+ * Multibyte extensions partly by Sung-Hoon Baek
+ *
+ * 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.
+ */
+/*
+ * mbyte.c: Code specifically for handling multi-byte characters.
+ *
+ * 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. Conversion is to be
+ * done when 'encoding' is different from 'termencoding'.
+ * (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.
+ * Otherwise, conversion is to be done when 'encoding' differs from
+ * 'termencoding'. (Different in the GTK+ 2 port -- 'termencoding'
+ * is always used for both input and output and must always be set to
+ * "utf-8". gui_mch_init() does this automatically.)
+ * (4) The encoding of the file is specified with 'fileencoding'. Conversion
+ * is to be done when it's different from 'encoding'.
+ *
+ * The viminfo 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"
+ */
+
+#include "vim.h"
+
+# define WINBYTE BYTE
+
+
+
+
+#ifdef HAVE_WCHAR_H
+# include <wchar.h>
+#endif
+
+
+
+static int enc_canon_search __ARGS((char_u *name));
+static int dbcs_char2len __ARGS((int c));
+static int dbcs_char2bytes __ARGS((int c, char_u *buf));
+static int dbcs_ptr2len __ARGS((char_u *p));
+static int dbcs_ptr2len_len __ARGS((char_u *p, int size));
+static int utf_ptr2cells_len __ARGS((char_u *p, int size));
+static int dbcs_char2cells __ARGS((int c));
+static int dbcs_ptr2cells_len __ARGS((char_u *p, int size));
+static int dbcs_ptr2char __ARGS((char_u *p));
+static int utf_safe_read_char_adv __ARGS((char_u **s, size_t *n));
+
+/*
+ * 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,
+};
+
+/*
+ * Like utf8len_tab above, but using a zero for illegal lead bytes.
+ */
+static char 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,
+};
+
+/*
+ * XIM often causes trouble. Define XIM_DEBUG to get a log of XIM callbacks
+ * in the "xim.log" file.
+ */
+/* #define XIM_DEBUG */
+#ifdef XIM_DEBUG
+static void xim_log(char *s, ...) {
+ va_list arglist;
+ static FILE *fd = NULL;
+
+ if (fd == (FILE *)-1)
+ return;
+ if (fd == NULL) {
+ fd = mch_fopen("xim.log", "w");
+ if (fd == NULL) {
+ EMSG("Cannot open xim.log");
+ fd = (FILE *)-1;
+ return;
+ }
+ }
+
+ va_start(arglist, s);
+ vfprintf(fd, s, arglist);
+ va_end(arglist);
+}
+
+#endif
+
+
+/*
+ * Canonical encoding names and their properties.
+ * "iso-8859-n" is handled by enc_canonize() directly.
+ */
+static struct
+{ char *name; int prop; int codepage; }
+enc_canon_table[] =
+{
+#define IDX_LATIN_1 0
+ {"latin1", ENC_8BIT + ENC_LATIN1, 1252},
+#define IDX_ISO_2 1
+ {"iso-8859-2", ENC_8BIT, 0},
+#define IDX_ISO_3 2
+ {"iso-8859-3", ENC_8BIT, 0},
+#define IDX_ISO_4 3
+ {"iso-8859-4", ENC_8BIT, 0},
+#define IDX_ISO_5 4
+ {"iso-8859-5", ENC_8BIT, 0},
+#define IDX_ISO_6 5
+ {"iso-8859-6", ENC_8BIT, 0},
+#define IDX_ISO_7 6
+ {"iso-8859-7", ENC_8BIT, 0},
+#define IDX_ISO_8 7
+ {"iso-8859-8", ENC_8BIT, 0},
+#define IDX_ISO_9 8
+ {"iso-8859-9", ENC_8BIT, 0},
+#define IDX_ISO_10 9
+ {"iso-8859-10", ENC_8BIT, 0},
+#define IDX_ISO_11 10
+ {"iso-8859-11", ENC_8BIT, 0},
+#define IDX_ISO_13 11
+ {"iso-8859-13", ENC_8BIT, 0},
+#define IDX_ISO_14 12
+ {"iso-8859-14", ENC_8BIT, 0},
+#define IDX_ISO_15 13
+ {"iso-8859-15", ENC_8BIT + ENC_LATIN9, 0},
+#define IDX_KOI8_R 14
+ {"koi8-r", ENC_8BIT, 0},
+#define IDX_KOI8_U 15
+ {"koi8-u", ENC_8BIT, 0},
+#define IDX_UTF8 16
+ {"utf-8", ENC_UNICODE, 0},
+#define IDX_UCS2 17
+ {"ucs-2", ENC_UNICODE + ENC_ENDIAN_B + ENC_2BYTE, 0},
+#define IDX_UCS2LE 18
+ {"ucs-2le", ENC_UNICODE + ENC_ENDIAN_L + ENC_2BYTE, 0},
+#define IDX_UTF16 19
+ {"utf-16", ENC_UNICODE + ENC_ENDIAN_B + ENC_2WORD, 0},
+#define IDX_UTF16LE 20
+ {"utf-16le", ENC_UNICODE + ENC_ENDIAN_L + ENC_2WORD, 0},
+#define IDX_UCS4 21
+ {"ucs-4", ENC_UNICODE + ENC_ENDIAN_B + ENC_4BYTE, 0},
+#define IDX_UCS4LE 22
+ {"ucs-4le", ENC_UNICODE + ENC_ENDIAN_L + ENC_4BYTE, 0},
+
+ /* For debugging DBCS encoding on Unix. */
+#define IDX_DEBUG 23
+ {"debug", ENC_DBCS, DBCS_DEBUG},
+#define IDX_EUC_JP 24
+ {"euc-jp", ENC_DBCS, DBCS_JPNU},
+#define IDX_SJIS 25
+ {"sjis", ENC_DBCS, DBCS_JPN},
+#define IDX_EUC_KR 26
+ {"euc-kr", ENC_DBCS, DBCS_KORU},
+#define IDX_EUC_CN 27
+ {"euc-cn", ENC_DBCS, DBCS_CHSU},
+#define IDX_EUC_TW 28
+ {"euc-tw", ENC_DBCS, DBCS_CHTU},
+#define IDX_BIG5 29
+ {"big5", ENC_DBCS, DBCS_CHT},
+
+ /* MS-DOS and MS-Windows codepages are included here, so that they can be
+ * used on Unix too. Most of them are similar to ISO-8859 encodings, but
+ * not exactly the same. */
+#define IDX_CP437 30
+ {"cp437", ENC_8BIT, 437}, /* like iso-8859-1 */
+#define IDX_CP737 31
+ {"cp737", ENC_8BIT, 737}, /* like iso-8859-7 */
+#define IDX_CP775 32
+ {"cp775", ENC_8BIT, 775}, /* Baltic */
+#define IDX_CP850 33
+ {"cp850", ENC_8BIT, 850}, /* like iso-8859-4 */
+#define IDX_CP852 34
+ {"cp852", ENC_8BIT, 852}, /* like iso-8859-1 */
+#define IDX_CP855 35
+ {"cp855", ENC_8BIT, 855}, /* like iso-8859-2 */
+#define IDX_CP857 36
+ {"cp857", ENC_8BIT, 857}, /* like iso-8859-5 */
+#define IDX_CP860 37
+ {"cp860", ENC_8BIT, 860}, /* like iso-8859-9 */
+#define IDX_CP861 38
+ {"cp861", ENC_8BIT, 861}, /* like iso-8859-1 */
+#define IDX_CP862 39
+ {"cp862", ENC_8BIT, 862}, /* like iso-8859-1 */
+#define IDX_CP863 40
+ {"cp863", ENC_8BIT, 863}, /* like iso-8859-8 */
+#define IDX_CP865 41
+ {"cp865", ENC_8BIT, 865}, /* like iso-8859-1 */
+#define IDX_CP866 42
+ {"cp866", ENC_8BIT, 866}, /* like iso-8859-5 */
+#define IDX_CP869 43
+ {"cp869", ENC_8BIT, 869}, /* like iso-8859-7 */
+#define IDX_CP874 44
+ {"cp874", ENC_8BIT, 874}, /* Thai */
+#define IDX_CP932 45
+ {"cp932", ENC_DBCS, DBCS_JPN},
+#define IDX_CP936 46
+ {"cp936", ENC_DBCS, DBCS_CHS},
+#define IDX_CP949 47
+ {"cp949", ENC_DBCS, DBCS_KOR},
+#define IDX_CP950 48
+ {"cp950", ENC_DBCS, DBCS_CHT},
+#define IDX_CP1250 49
+ {"cp1250", ENC_8BIT, 1250}, /* Czech, Polish, etc. */
+#define IDX_CP1251 50
+ {"cp1251", ENC_8BIT, 1251}, /* Cyrillic */
+ /* cp1252 is considered to be equal to latin1 */
+#define IDX_CP1253 51
+ {"cp1253", ENC_8BIT, 1253}, /* Greek */
+#define IDX_CP1254 52
+ {"cp1254", ENC_8BIT, 1254}, /* Turkish */
+#define IDX_CP1255 53
+ {"cp1255", ENC_8BIT, 1255}, /* Hebrew */
+#define IDX_CP1256 54
+ {"cp1256", ENC_8BIT, 1256}, /* Arabic */
+#define IDX_CP1257 55
+ {"cp1257", ENC_8BIT, 1257}, /* Baltic */
+#define IDX_CP1258 56
+ {"cp1258", ENC_8BIT, 1258}, /* Vietnamese */
+
+#define IDX_MACROMAN 57
+ {"macroman", ENC_8BIT + ENC_MACROMAN, 0}, /* Mac OS */
+#define IDX_DECMCS 58
+ {"dec-mcs", ENC_8BIT, 0}, /* DEC MCS */
+#define IDX_HPROMAN8 59
+ {"hp-roman8", ENC_8BIT, 0}, /* HP Roman8 */
+#define IDX_COUNT 60
+};
+
+/*
+ * Aliases for encoding names.
+ */
+static struct
+{ char *name; int canon; }
+enc_alias_table[] =
+{
+ {"ansi", IDX_LATIN_1},
+ {"iso-8859-1", IDX_LATIN_1},
+ {"latin2", IDX_ISO_2},
+ {"latin3", IDX_ISO_3},
+ {"latin4", IDX_ISO_4},
+ {"cyrillic", IDX_ISO_5},
+ {"arabic", IDX_ISO_6},
+ {"greek", IDX_ISO_7},
+ {"hebrew", IDX_ISO_8},
+ {"latin5", IDX_ISO_9},
+ {"turkish", IDX_ISO_9}, /* ? */
+ {"latin6", IDX_ISO_10},
+ {"nordic", IDX_ISO_10}, /* ? */
+ {"thai", IDX_ISO_11}, /* ? */
+ {"latin7", IDX_ISO_13},
+ {"latin8", IDX_ISO_14},
+ {"latin9", IDX_ISO_15},
+ {"utf8", IDX_UTF8},
+ {"unicode", IDX_UCS2},
+ {"ucs2", IDX_UCS2},
+ {"ucs2be", IDX_UCS2},
+ {"ucs-2be", IDX_UCS2},
+ {"ucs2le", IDX_UCS2LE},
+ {"utf16", IDX_UTF16},
+ {"utf16be", IDX_UTF16},
+ {"utf-16be", IDX_UTF16},
+ {"utf16le", IDX_UTF16LE},
+ {"ucs4", IDX_UCS4},
+ {"ucs4be", IDX_UCS4},
+ {"ucs-4be", IDX_UCS4},
+ {"ucs4le", IDX_UCS4LE},
+ {"utf32", IDX_UCS4},
+ {"utf-32", IDX_UCS4},
+ {"utf32be", IDX_UCS4},
+ {"utf-32be", IDX_UCS4},
+ {"utf32le", IDX_UCS4LE},
+ {"utf-32le", IDX_UCS4LE},
+ {"932", IDX_CP932},
+ {"949", IDX_CP949},
+ {"936", IDX_CP936},
+ {"gbk", IDX_CP936},
+ {"950", IDX_CP950},
+ {"eucjp", IDX_EUC_JP},
+ {"unix-jis", IDX_EUC_JP},
+ {"ujis", IDX_EUC_JP},
+ {"shift-jis", IDX_SJIS},
+ {"euckr", IDX_EUC_KR},
+ {"5601", IDX_EUC_KR}, /* Sun: KS C 5601 */
+ {"euccn", IDX_EUC_CN},
+ {"gb2312", IDX_EUC_CN},
+ {"euctw", IDX_EUC_TW},
+ {"japan", IDX_EUC_JP},
+ {"korea", IDX_EUC_KR},
+ {"prc", IDX_EUC_CN},
+ {"chinese", IDX_EUC_CN},
+ {"taiwan", IDX_EUC_TW},
+ {"cp950", IDX_BIG5},
+ {"950", IDX_BIG5},
+ {"mac", IDX_MACROMAN},
+ {"mac-roman", IDX_MACROMAN},
+ {NULL, 0}
+};
+
+#ifndef CP_UTF8
+# define CP_UTF8 65001 /* magic number from winnls.h */
+#endif
+
+/*
+ * Find encoding "name" in the list of canonical encoding names.
+ * Returns -1 if not found.
+ */
+static int enc_canon_search(name)
+char_u *name;
+{
+ int i;
+
+ for (i = 0; i < IDX_COUNT; ++i)
+ if (STRCMP(name, enc_canon_table[i].name) == 0)
+ return i;
+ return -1;
+}
+
+
+
+/*
+ * Find canonical encoding "name" in the list and return its properties.
+ * Returns 0 if not found.
+ */
+int enc_canon_props(name)
+char_u *name;
+{
+ int i;
+
+ i = enc_canon_search(name);
+ if (i >= 0)
+ return enc_canon_table[i].prop;
+ if (STRNCMP(name, "2byte-", 6) == 0)
+ return ENC_DBCS;
+ if (STRNCMP(name, "8bit-", 5) == 0 || STRNCMP(name, "iso-8859-", 9) == 0)
+ return ENC_8BIT;
+ return 0;
+}
+
+/*
+ * 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() {
+ 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;
+ input_conv.vc_type = CONV_NONE;
+ input_conv.vc_factor = 1;
+ output_conv.vc_type = CONV_NONE;
+ 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;
+ }
+ vim_free(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 {
+# if defined(MACOS) || defined(__amigaos4__)
+ /*
+ * if mblen() is not available, character which MSB is turned on
+ * are treated as leading byte character. (note : This assumption
+ * is not always true.)
+ */
+ n = (i & 0x80) ? 2 : 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) {
+ vim_free(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;
+ }
+ }
+# endif
+ }
+
+ 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);
+
+ /* When using Unicode, set default for 'fileencodings'. */
+ if (enc_utf8 && !option_was_set((char_u *)"fencs"))
+ set_string_option_direct((char_u *)"fencs", -1,
+ (char_u *)"ucs-bom,utf-8,default,latin1", OPT_FREE, 0);
+
+#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(VIMPACKAGE,
+ 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
+ * 4 - UCS-4 BOM
+ * 3 - UTF-8 BOM
+ */
+int bomb_size() {
+ 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)
+ n = 3;
+ 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)
+ n = 4;
+ }
+ return n;
+}
+
+/*
+ * Remove all BOM from "s" by moving remaining text.
+ */
+void remove_bom(s)
+char_u *s;
+{
+ if (enc_utf8) {
+ char_u *p = s;
+
+ while ((p = vim_strbyte(p, 0xef)) != NULL) {
+ if (p[1] == 0xbb && p[2] == 0xbf)
+ STRMOVE(p, p + 3);
+ else
+ ++p;
+ }
+ }
+}
+
+/*
+ * Get class of pointer:
+ * 0 for blank or NUL
+ * 1 for punctuation
+ * 2 for an (ASCII) word character
+ * >2 for other word characters
+ */
+int mb_get_class(p)
+char_u *p;
+{
+ return mb_get_class_buf(p, curbuf);
+}
+
+int mb_get_class_buf(p, buf)
+char_u *p;
+buf_T *buf;
+{
+ if (MB_BYTE2LEN(p[0]) == 1) {
+ if (p[0] == NUL || vim_iswhite(p[0]))
+ return 0;
+ if (vim_iswordc_buf(p[0], buf))
+ 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(lead, trail)
+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(c)
+int c UNUSED;
+{
+ return 1;
+}
+
+static int dbcs_char2len(c)
+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(c, buf)
+int c;
+char_u *buf;
+{
+ buf[0] = c;
+ return 1;
+}
+
+static int dbcs_char2bytes(c, buf)
+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(p)
+char_u *p;
+{
+ return MB_BYTE2LEN(*p);
+}
+
+static int dbcs_ptr2len(p)
+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(p, size)
+char_u *p;
+int size;
+{
+ if (size < 1 || *p == NUL)
+ return 0;
+ return 1;
+}
+
+static int dbcs_ptr2len_len(p, size)
+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;
+}
+
+struct interval {
+ long first;
+ long last;
+};
+static int intable __ARGS((struct interval *table, size_t size, int c));
+
+/*
+ * Return TRUE if "c" is in "table[size / sizeof(struct interval)]".
+ */
+static int intable(table, size, c)
+struct interval *table;
+size_t size;
+int c;
+{
+ int mid, bot, top;
+
+ /* first quick check for Latin1 etc. characters */
+ if (c < table[0].first)
+ return FALSE;
+
+ /* binary search in table */
+ bot = 0;
+ top = (int)(size / sizeof(struct interval) - 1);
+ while (top >= bot) {
+ mid = (bot + top) / 2;
+ if (table[mid].last < c)
+ bot = mid + 1;
+ else if (table[mid].first > c)
+ top = mid - 1;
+ else
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*
+ * For UTF-8 character "c" return 2 for a double-width character, 1 for others.
+ * Returns 4 or 6 for an unprintable character.
+ * Is only correct for characters >= 0x80.
+ * When p_ambw is "double", return 2 for a character with East Asian Width
+ * class 'A'(mbiguous).
+ */
+int utf_char2cells(c)
+int c;
+{
+ /* Sorted list of non-overlapping intervals of East Asian double width
+ * characters, generated with ../runtime/tools/unicode.vim. */
+ static struct interval doublewidth[] =
+ {
+ {0x1100, 0x115f},
+ {0x11a3, 0x11a7},
+ {0x11fa, 0x11ff},
+ {0x2329, 0x232a},
+ {0x2e80, 0x2e99},
+ {0x2e9b, 0x2ef3},
+ {0x2f00, 0x2fd5},
+ {0x2ff0, 0x2ffb},
+ {0x3000, 0x3029},
+ {0x3030, 0x303e},
+ {0x3041, 0x3096},
+ {0x309b, 0x30ff},
+ {0x3105, 0x312d},
+ {0x3131, 0x318e},
+ {0x3190, 0x31b7},
+ {0x31c0, 0x31e3},
+ {0x31f0, 0x321e},
+ {0x3220, 0x3247},
+ {0x3250, 0x32fe},
+ {0x3300, 0x4dbf},
+ {0x4e00, 0xa48c},
+ {0xa490, 0xa4c6},
+ {0xa960, 0xa97c},
+ {0xac00, 0xd7a3},
+ {0xd7b0, 0xd7c6},
+ {0xd7cb, 0xd7fb},
+ {0xf900, 0xfaff},
+ {0xfe10, 0xfe19},
+ {0xfe30, 0xfe52},
+ {0xfe54, 0xfe66},
+ {0xfe68, 0xfe6b},
+ {0xff01, 0xff60},
+ {0xffe0, 0xffe6},
+ {0x1f200, 0x1f200},
+ {0x1f210, 0x1f231},
+ {0x1f240, 0x1f248},
+ {0x20000, 0x2fffd},
+ {0x30000, 0x3fffd}
+ };
+ /* Sorted list of non-overlapping intervals of East Asian Ambiguous
+ * characters, generated with ../runtime/tools/unicode.vim. */
+ static struct interval ambiguous[] =
+ {
+ {0x00a1, 0x00a1},
+ {0x00a4, 0x00a4},
+ {0x00a7, 0x00a8},
+ {0x00aa, 0x00aa},
+ {0x00ad, 0x00ae},
+ {0x00b0, 0x00b4},
+ {0x00b6, 0x00ba},
+ {0x00bc, 0x00bf},
+ {0x00c6, 0x00c6},
+ {0x00d0, 0x00d0},
+ {0x00d7, 0x00d8},
+ {0x00de, 0x00e1},
+ {0x00e6, 0x00e6},
+ {0x00e8, 0x00ea},
+ {0x00ec, 0x00ed},
+ {0x00f0, 0x00f0},
+ {0x00f2, 0x00f3},
+ {0x00f7, 0x00fa},
+ {0x00fc, 0x00fc},
+ {0x00fe, 0x00fe},
+ {0x0101, 0x0101},
+ {0x0111, 0x0111},
+ {0x0113, 0x0113},
+ {0x011b, 0x011b},
+ {0x0126, 0x0127},
+ {0x012b, 0x012b},
+ {0x0131, 0x0133},
+ {0x0138, 0x0138},
+ {0x013f, 0x0142},
+ {0x0144, 0x0144},
+ {0x0148, 0x014b},
+ {0x014d, 0x014d},
+ {0x0152, 0x0153},
+ {0x0166, 0x0167},
+ {0x016b, 0x016b},
+ {0x01ce, 0x01ce},
+ {0x01d0, 0x01d0},
+ {0x01d2, 0x01d2},
+ {0x01d4, 0x01d4},
+ {0x01d6, 0x01d6},
+ {0x01d8, 0x01d8},
+ {0x01da, 0x01da},
+ {0x01dc, 0x01dc},
+ {0x0251, 0x0251},
+ {0x0261, 0x0261},
+ {0x02c4, 0x02c4},
+ {0x02c7, 0x02c7},
+ {0x02c9, 0x02cb},
+ {0x02cd, 0x02cd},
+ {0x02d0, 0x02d0},
+ {0x02d8, 0x02db},
+ {0x02dd, 0x02dd},
+ {0x02df, 0x02df},
+ {0x0391, 0x03a1},
+ {0x03a3, 0x03a9},
+ {0x03b1, 0x03c1},
+ {0x03c3, 0x03c9},
+ {0x0401, 0x0401},
+ {0x0410, 0x044f},
+ {0x0451, 0x0451},
+ {0x2010, 0x2010},
+ {0x2013, 0x2016},
+ {0x2018, 0x2019},
+ {0x201c, 0x201d},
+ {0x2020, 0x2022},
+ {0x2024, 0x2027},
+ {0x2030, 0x2030},
+ {0x2032, 0x2033},
+ {0x2035, 0x2035},
+ {0x203b, 0x203b},
+ {0x203e, 0x203e},
+ {0x2074, 0x2074},
+ {0x207f, 0x207f},
+ {0x2081, 0x2084},
+ {0x20ac, 0x20ac},
+ {0x2103, 0x2103},
+ {0x2105, 0x2105},
+ {0x2109, 0x2109},
+ {0x2113, 0x2113},
+ {0x2116, 0x2116},
+ {0x2121, 0x2122},
+ {0x2126, 0x2126},
+ {0x212b, 0x212b},
+ {0x2153, 0x2154},
+ {0x215b, 0x215e},
+ {0x2160, 0x216b},
+ {0x2170, 0x2179},
+ {0x2189, 0x2189},
+ {0x2190, 0x2199},
+ {0x21b8, 0x21b9},
+ {0x21d2, 0x21d2},
+ {0x21d4, 0x21d4},
+ {0x21e7, 0x21e7},
+ {0x2200, 0x2200},
+ {0x2202, 0x2203},
+ {0x2207, 0x2208},
+ {0x220b, 0x220b},
+ {0x220f, 0x220f},
+ {0x2211, 0x2211},
+ {0x2215, 0x2215},
+ {0x221a, 0x221a},
+ {0x221d, 0x2220},
+ {0x2223, 0x2223},
+ {0x2225, 0x2225},
+ {0x2227, 0x222c},
+ {0x222e, 0x222e},
+ {0x2234, 0x2237},
+ {0x223c, 0x223d},
+ {0x2248, 0x2248},
+ {0x224c, 0x224c},
+ {0x2252, 0x2252},
+ {0x2260, 0x2261},
+ {0x2264, 0x2267},
+ {0x226a, 0x226b},
+ {0x226e, 0x226f},
+ {0x2282, 0x2283},
+ {0x2286, 0x2287},
+ {0x2295, 0x2295},
+ {0x2299, 0x2299},
+ {0x22a5, 0x22a5},
+ {0x22bf, 0x22bf},
+ {0x2312, 0x2312},
+ {0x2460, 0x24e9},
+ {0x24eb, 0x254b},
+ {0x2550, 0x2573},
+ {0x2580, 0x258f},
+ {0x2592, 0x2595},
+ {0x25a0, 0x25a1},
+ {0x25a3, 0x25a9},
+ {0x25b2, 0x25b3},
+ {0x25b6, 0x25b7},
+ {0x25bc, 0x25bd},
+ {0x25c0, 0x25c1},
+ {0x25c6, 0x25c8},
+ {0x25cb, 0x25cb},
+ {0x25ce, 0x25d1},
+ {0x25e2, 0x25e5},
+ {0x25ef, 0x25ef},
+ {0x2605, 0x2606},
+ {0x2609, 0x2609},
+ {0x260e, 0x260f},
+ {0x2614, 0x2615},
+ {0x261c, 0x261c},
+ {0x261e, 0x261e},
+ {0x2640, 0x2640},
+ {0x2642, 0x2642},
+ {0x2660, 0x2661},
+ {0x2663, 0x2665},
+ {0x2667, 0x266a},
+ {0x266c, 0x266d},
+ {0x266f, 0x266f},
+ {0x269e, 0x269f},
+ {0x26be, 0x26bf},
+ {0x26c4, 0x26cd},
+ {0x26cf, 0x26e1},
+ {0x26e3, 0x26e3},
+ {0x26e8, 0x26ff},
+ {0x273d, 0x273d},
+ {0x2757, 0x2757},
+ {0x2776, 0x277f},
+ {0x2b55, 0x2b59},
+ {0x3248, 0x324f},
+ {0xe000, 0xf8ff},
+ {0xfffd, 0xfffd},
+ {0x1f100, 0x1f10a},
+ {0x1f110, 0x1f12d},
+ {0x1f131, 0x1f131},
+ {0x1f13d, 0x1f13d},
+ {0x1f13f, 0x1f13f},
+ {0x1f142, 0x1f142},
+ {0x1f146, 0x1f146},
+ {0x1f14a, 0x1f14e},
+ {0x1f157, 0x1f157},
+ {0x1f15f, 0x1f15f},
+ {0x1f179, 0x1f179},
+ {0x1f17b, 0x1f17c},
+ {0x1f17f, 0x1f17f},
+ {0x1f18a, 0x1f18d},
+ {0x1f190, 0x1f190},
+ {0xf0000, 0xffffd},
+ {0x100000, 0x10fffd}
+ };
+
+ if (c >= 0x100) {
+#ifdef USE_WCHAR_FUNCTIONS
+ /*
+ * Assume the library function wcwidth() works better than our own
+ * stuff. It should return 1 for ambiguous width chars!
+ */
+ int n = wcwidth(c);
+
+ if (n < 0)
+ return 6; /* unprintable, displays <xxxx> */
+ if (n > 1)
+ return n;
+#else
+ if (!utf_printable(c))
+ return 6; /* unprintable, displays <xxxx> */
+ if (intable(doublewidth, sizeof(doublewidth), c))
+ return 2;
+#endif
+ }
+ /* Characters below 0x100 are influenced by 'isprint' option */
+ else if (c >= 0x80 && !vim_isprintc(c))
+ return 4; /* unprintable, displays <xx> */
+
+ if (c >= 0x80 && *p_ambw == 'd' && intable(ambiguous, sizeof(ambiguous), c))
+ return 2;
+
+ 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(p)
+char_u *p UNUSED;
+{
+ return 1;
+}
+
+int utf_ptr2cells(p)
+char_u *p;
+{
+ int c;
+
+ /* Need to convert to a wide character. */
+ if (*p >= 0x80) {
+ c = utf_ptr2char(p);
+ /* An illegal byte is displayed as <xx>. */
+ if (utf_ptr2len(p) == 1 || c == NUL)
+ return 4;
+ /* If the char is ASCII it must be an overlong sequence. */
+ if (c < 0x80)
+ return char2cells(c);
+ return utf_char2cells(c);
+ }
+ return 1;
+}
+
+int dbcs_ptr2cells(p)
+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(p, size)
+char_u *p UNUSED;
+int size UNUSED;
+{
+ return 1;
+}
+
+static int utf_ptr2cells_len(p, size)
+char_u *p;
+int size;
+{
+ int c;
+
+ /* Need to convert to a wide character. */
+ if (size > 0 && *p >= 0x80) {
+ if (utf_ptr2len_len(p, size) < utf8len_tab[*p])
+ return 1; /* truncated */
+ c = utf_ptr2char(p);
+ /* An illegal byte is displayed as <xx>. */
+ if (utf_ptr2len(p) == 1 || c == NUL)
+ return 4;
+ /* If the char is ASCII it must be an overlong sequence. */
+ if (c < 0x80)
+ return char2cells(c);
+ return utf_char2cells(c);
+ }
+ return 1;
+}
+
+static int dbcs_ptr2cells_len(p, size)
+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(c)
+int c UNUSED;
+{
+ return 1;
+}
+
+static int dbcs_char2cells(c)
+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);
+}
+
+/*
+ * Return the number of cells occupied by string "p".
+ * Stop at a NUL character. When "len" >= 0 stop at character "p[len]".
+ */
+int mb_string2cells(p, len)
+char_u *p;
+int len;
+{
+ int i;
+ int clen = 0;
+
+ for (i = 0; (len < 0 || i < len) && p[i] != NUL; i += (*mb_ptr2len)(p + i))
+ clen += (*mb_ptr2cells)(p + i);
+ 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(off, max_off)
+unsigned off UNUSED;
+unsigned max_off UNUSED;
+{
+ return 1;
+}
+
+int dbcs_off2cells(off, max_off)
+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(off, max_off)
+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(p)
+char_u *p;
+{
+ return *p;
+}
+
+static int dbcs_ptr2char(p)
+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(p)
+char_u *p;
+{
+ int len;
+
+ if (p[0] < 0x80) /* be quick for ASCII */
+ return p[0];
+
+ len = utf8len_tab_zero[p[0]];
+ if (len > 1 && (p[1] & 0xc0) == 0x80) {
+ 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 ((p[3] & 0xc0) == 0x80) {
+ 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);
+ }
+ }
+ }
+ }
+ /* Illegal value, just return the first byte */
+ return p[0];
+}
+
+/*
+ * Convert a UTF-8 byte sequence to a wide character.
+ * String is assumed to be terminated by NUL or after "n" bytes, whichever
+ * comes first.
+ * The function is safe in the sense that it never accesses memory beyond the
+ * first "n" bytes of "s".
+ *
+ * On success, returns decoded codepoint, advances "s" to the beginning of
+ * next character and decreases "n" accordingly.
+ *
+ * If end of string was reached, returns 0 and, if "n" > 0, advances "s" past
+ * NUL byte.
+ *
+ * If byte sequence is illegal or incomplete, returns -1 and does not advance
+ * "s".
+ */
+static int utf_safe_read_char_adv(s, n)
+char_u **s;
+size_t *n;
+{
+ int c, k;
+
+ if (*n == 0) /* end of buffer */
+ return 0;
+
+ k = utf8len_tab_zero[**s];
+
+ if (k == 1) {
+ /* ASCII character or NUL */
+ (*n)--;
+ return *(*s)++;
+ }
+
+ if ((size_t)k <= *n) {
+ /* We have a multibyte sequence and it isn't truncated by buffer
+ * limits so utf_ptr2char() is safe to use. Or the first byte is
+ * illegal (k=0), and it's also safe to use utf_ptr2char(). */
+ c = utf_ptr2char(*s);
+
+ /* On failure, utf_ptr2char() returns the first byte, so here we
+ * check equality with the first byte. The only non-ASCII character
+ * which equals the first byte of its own UTF-8 representation is
+ * U+00C3 (UTF-8: 0xC3 0x83), so need to check that special case too.
+ * It's safe even if n=1, else we would have k=2 > n. */
+ if (c != (int)(**s) || (c == 0xC3 && (*s)[1] == 0x83)) {
+ /* byte sequence was successfully decoded */
+ *s += k;
+ *n -= k;
+ return c;
+ }
+ }
+
+ /* byte sequence is incomplete or illegal */
+ return -1;
+}
+
+/*
+ * Get character at **pp and advance *pp to the next character.
+ * Note: composing characters are skipped!
+ */
+int mb_ptr2char_adv(pp)
+char_u **pp;
+{
+ int c;
+
+ c = (*mb_ptr2char)(*pp);
+ *pp += (*mb_ptr2len)(*pp);
+ return c;
+}
+
+/*
+ * Get character at **pp and advance *pp to the next character.
+ * Note: composing characters are returned as separate characters.
+ */
+int mb_cptr2char_adv(pp)
+char_u **pp;
+{
+ int c;
+
+ c = (*mb_ptr2char)(*pp);
+ if (enc_utf8)
+ *pp += utf_ptr2len(*pp);
+ else
+ *pp += (*mb_ptr2len)(*pp);
+ return c;
+}
+
+/*
+ * Check whether we are dealing with Arabic combining characters.
+ * Note: these are NOT really composing characters!
+ */
+int arabic_combine(one, two)
+int one; /* first character */
+int two; /* character just after "one" */
+{
+ if (one == a_LAM)
+ return arabic_maycombine(two);
+ return FALSE;
+}
+
+/*
+ * Check whether we are dealing with a character that could be regarded as an
+ * Arabic combining character, need to check the character before this.
+ */
+int arabic_maycombine(two)
+int two;
+{
+ if (p_arshape && !p_tbidi)
+ return two == a_ALEF_MADDA
+ || two == a_ALEF_HAMZA_ABOVE
+ || two == a_ALEF_HAMZA_BELOW
+ || two == a_ALEF;
+ return FALSE;
+}
+
+/*
+ * Check if the character pointed to by "p2" is a composing character when it
+ * comes after "p1". For Arabic sometimes "ab" is replaced with "c", which
+ * behaves like a composing character.
+ */
+int utf_composinglike(p1, p2)
+char_u *p1;
+char_u *p2;
+{
+ int c2;
+
+ c2 = utf_ptr2char(p2);
+ if (utf_iscomposing(c2))
+ return TRUE;
+ if (!arabic_maycombine(c2))
+ return FALSE;
+ 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.
+ */
+int utfc_ptr2char(p, pcc)
+char_u *p;
+int *pcc; /* return: composing chars, last one is 0 */
+{
+ int len;
+ int c;
+ int cc;
+ int i = 0;
+
+ c = utf_ptr2char(p);
+ len = utf_ptr2len(p);
+
+ /* Only accept a composing char when the first char isn't illegal. */
+ if ((len > 1 || *p < 0x80)
+ && p[len] >= 0x80
+ && UTF_COMPOSINGLIKE(p, p + len)) {
+ cc = utf_ptr2char(p + len);
+ for (;; ) {
+ pcc[i++] = cc;
+ if (i == MAX_MCO)
+ break;
+ len += utf_ptr2len(p + len);
+ if (p[len] < 0x80 || !utf_iscomposing(cc = utf_ptr2char(p + len)))
+ break;
+ }
+ }
+
+ if (i < MAX_MCO) /* last composing char must be 0 */
+ pcc[i] = 0;
+
+ return c;
+}
+
+/*
+ * Convert a UTF-8 byte string to a wide character. Also get up to MAX_MCO
+ * composing characters. Use no more than p[maxlen].
+ */
+int utfc_ptr2char_len(p, pcc, maxlen)
+char_u *p;
+int *pcc; /* return: composing chars, last one is 0 */
+int maxlen;
+{
+ int len;
+ int c;
+ int cc;
+ int i = 0;
+
+ c = utf_ptr2char(p);
+ len = utf_ptr2len_len(p, maxlen);
+ /* Only accept a composing char when the first char isn't illegal. */
+ if ((len > 1 || *p < 0x80)
+ && len < maxlen
+ && p[len] >= 0x80
+ && UTF_COMPOSINGLIKE(p, p + len)) {
+ cc = utf_ptr2char(p + len);
+ for (;; ) {
+ pcc[i++] = cc;
+ if (i == MAX_MCO)
+ break;
+ len += utf_ptr2len_len(p + len, maxlen - len);
+ if (len >= maxlen
+ || p[len] < 0x80
+ || !utf_iscomposing(cc = utf_ptr2char(p + len)))
+ break;
+ }
+ }
+
+ if (i < MAX_MCO) /* last composing char must be 0 */
+ pcc[i] = 0;
+
+ return c;
+}
+
+/*
+ * 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(off, buf)
+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(p)
+char_u *p;
+{
+ int len;
+ int i;
+
+ if (*p == NUL)
+ return 0;
+ len = utf8len_tab[*p];
+ for (i = 1; i < len; ++i)
+ if ((p[i] & 0xc0) != 0x80)
+ return 1;
+ return len;
+}
+
+/*
+ * Return length of UTF-8 character, obtained from the first byte.
+ * "b" must be between 0 and 255!
+ * Returns 1 for an invalid first byte value.
+ */
+int utf_byte2len(b)
+int b;
+{
+ return utf8len_tab[b];
+}
+
+/*
+ * Get the length of UTF-8 byte sequence "p[size]". Does not include any
+ * following composing characters.
+ * Returns 1 for "".
+ * Returns 1 for an illegal byte sequence (also in incomplete byte seq.).
+ * Returns number > "size" for an incomplete byte sequence.
+ * Never returns zero.
+ */
+int utf_ptr2len_len(p, size)
+char_u *p;
+int size;
+{
+ int len;
+ int i;
+ int m;
+
+ len = utf8len_tab[*p];
+ if (len == 1)
+ return 1; /* NUL, ascii or illegal lead byte */
+ if (len > size)
+ m = size; /* incomplete byte sequence. */
+ else
+ m = len;
+ for (i = 1; i < m; ++i)
+ if ((p[i] & 0xc0) != 0x80)
+ return 1;
+ 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(p)
+char_u *p;
+{
+ int len;
+ int b0 = *p;
+ int prevlen;
+
+ if (b0 == NUL)
+ return 0;
+ 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);
+
+ /* 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))
+ return len;
+
+ /* Skip over composing char */
+ prevlen = len;
+ len += utf_ptr2len(p + len);
+ }
+}
+
+/*
+ * Return the number of bytes the UTF-8 encoding of the character at "p[size]"
+ * takes. This includes following composing characters.
+ * Returns 0 for an empty string.
+ * Returns 1 for an illegal char or an incomplete byte sequence.
+ */
+int utfc_ptr2len_len(p, size)
+char_u *p;
+int size;
+{
+ int len;
+ int prevlen;
+
+ if (size < 1 || *p == NUL)
+ return 0;
+ if (p[0] < 0x80 && (size == 1 || p[1] < 0x80)) /* be quick for ASCII */
+ return 1;
+
+ /* Skip over first UTF-8 char, stopping at a NUL byte. */
+ len = utf_ptr2len_len(p, size);
+
+ /* Check for illegal byte and incomplete byte sequence. */
+ if ((len == 1 && p[0] >= 0x80) || len > size)
+ 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;
+ while (len < size) {
+ int len_next_char;
+
+ if (p[len] < 0x80)
+ break;
+
+ /*
+ * Next character length should not go beyond size to ensure that
+ * UTF_COMPOSINGLIKE(...) does not read beyond size.
+ */
+ len_next_char = utf_ptr2len_len(p + len, size - len);
+ if (len_next_char > size - len)
+ break;
+
+ if (!UTF_COMPOSINGLIKE(p + prevlen, p + len))
+ break;
+
+ /* Skip over composing char */
+ prevlen = len;
+ len += len_next_char;
+ }
+ return len;
+}
+
+/*
+ * Return the number of bytes the UTF-8 encoding of character "c" takes.
+ * This does not include composing characters.
+ */
+int utf_char2len(c)
+int c;
+{
+ if (c < 0x80)
+ return 1;
+ if (c < 0x800)
+ return 2;
+ if (c < 0x10000)
+ return 3;
+ if (c < 0x200000)
+ return 4;
+ if (c < 0x4000000)
+ return 5;
+ 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(c, buf)
+int c;
+char_u *buf;
+{
+ if (c < 0x80) { /* 7 bits */
+ buf[0] = c;
+ return 1;
+ }
+ if (c < 0x800) { /* 11 bits */
+ buf[0] = 0xc0 + ((unsigned)c >> 6);
+ buf[1] = 0x80 + (c & 0x3f);
+ return 2;
+ }
+ 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 */
+ 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 */
+ 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;
+ }
+ /* 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;
+}
+
+/*
+ * Return TRUE if "c" is a composing UTF-8 character. This means it will be
+ * drawn on top of the preceding character.
+ * Based on code from Markus Kuhn.
+ */
+int utf_iscomposing(c)
+int c;
+{
+ /* Sorted list of non-overlapping intervals.
+ * Generated by ../runtime/tools/unicode.vim. */
+ static struct interval combining[] =
+ {
+ {0x0300, 0x036f},
+ {0x0483, 0x0489},
+ {0x0591, 0x05bd},
+ {0x05bf, 0x05bf},
+ {0x05c1, 0x05c2},
+ {0x05c4, 0x05c5},
+ {0x05c7, 0x05c7},
+ {0x0610, 0x061a},
+ {0x064b, 0x065e},
+ {0x0670, 0x0670},
+ {0x06d6, 0x06dc},
+ {0x06de, 0x06e4},
+ {0x06e7, 0x06e8},
+ {0x06ea, 0x06ed},
+ {0x0711, 0x0711},
+ {0x0730, 0x074a},
+ {0x07a6, 0x07b0},
+ {0x07eb, 0x07f3},
+ {0x0816, 0x0819},
+ {0x081b, 0x0823},
+ {0x0825, 0x0827},
+ {0x0829, 0x082d},
+ {0x0900, 0x0903},
+ {0x093c, 0x093c},
+ {0x093e, 0x094e},
+ {0x0951, 0x0955},
+ {0x0962, 0x0963},
+ {0x0981, 0x0983},
+ {0x09bc, 0x09bc},
+ {0x09be, 0x09c4},
+ {0x09c7, 0x09c8},
+ {0x09cb, 0x09cd},
+ {0x09d7, 0x09d7},
+ {0x09e2, 0x09e3},
+ {0x0a01, 0x0a03},
+ {0x0a3c, 0x0a3c},
+ {0x0a3e, 0x0a42},
+ {0x0a47, 0x0a48},
+ {0x0a4b, 0x0a4d},
+ {0x0a51, 0x0a51},
+ {0x0a70, 0x0a71},
+ {0x0a75, 0x0a75},
+ {0x0a81, 0x0a83},
+ {0x0abc, 0x0abc},
+ {0x0abe, 0x0ac5},
+ {0x0ac7, 0x0ac9},
+ {0x0acb, 0x0acd},
+ {0x0ae2, 0x0ae3},
+ {0x0b01, 0x0b03},
+ {0x0b3c, 0x0b3c},
+ {0x0b3e, 0x0b44},
+ {0x0b47, 0x0b48},
+ {0x0b4b, 0x0b4d},
+ {0x0b56, 0x0b57},
+ {0x0b62, 0x0b63},
+ {0x0b82, 0x0b82},
+ {0x0bbe, 0x0bc2},
+ {0x0bc6, 0x0bc8},
+ {0x0bca, 0x0bcd},
+ {0x0bd7, 0x0bd7},
+ {0x0c01, 0x0c03},
+ {0x0c3e, 0x0c44},
+ {0x0c46, 0x0c48},
+ {0x0c4a, 0x0c4d},
+ {0x0c55, 0x0c56},
+ {0x0c62, 0x0c63},
+ {0x0c82, 0x0c83},
+ {0x0cbc, 0x0cbc},
+ {0x0cbe, 0x0cc4},
+ {0x0cc6, 0x0cc8},
+ {0x0cca, 0x0ccd},
+ {0x0cd5, 0x0cd6},
+ {0x0ce2, 0x0ce3},
+ {0x0d02, 0x0d03},
+ {0x0d3e, 0x0d44},
+ {0x0d46, 0x0d48},
+ {0x0d4a, 0x0d4d},
+ {0x0d57, 0x0d57},
+ {0x0d62, 0x0d63},
+ {0x0d82, 0x0d83},
+ {0x0dca, 0x0dca},
+ {0x0dcf, 0x0dd4},
+ {0x0dd6, 0x0dd6},
+ {0x0dd8, 0x0ddf},
+ {0x0df2, 0x0df3},
+ {0x0e31, 0x0e31},
+ {0x0e34, 0x0e3a},
+ {0x0e47, 0x0e4e},
+ {0x0eb1, 0x0eb1},
+ {0x0eb4, 0x0eb9},
+ {0x0ebb, 0x0ebc},
+ {0x0ec8, 0x0ecd},
+ {0x0f18, 0x0f19},
+ {0x0f35, 0x0f35},
+ {0x0f37, 0x0f37},
+ {0x0f39, 0x0f39},
+ {0x0f3e, 0x0f3f},
+ {0x0f71, 0x0f84},
+ {0x0f86, 0x0f87},
+ {0x0f90, 0x0f97},
+ {0x0f99, 0x0fbc},
+ {0x0fc6, 0x0fc6},
+ {0x102b, 0x103e},
+ {0x1056, 0x1059},
+ {0x105e, 0x1060},
+ {0x1062, 0x1064},
+ {0x1067, 0x106d},
+ {0x1071, 0x1074},
+ {0x1082, 0x108d},
+ {0x108f, 0x108f},
+ {0x109a, 0x109d},
+ {0x135f, 0x135f},
+ {0x1712, 0x1714},
+ {0x1732, 0x1734},
+ {0x1752, 0x1753},
+ {0x1772, 0x1773},
+ {0x17b6, 0x17d3},
+ {0x17dd, 0x17dd},
+ {0x180b, 0x180d},
+ {0x18a9, 0x18a9},
+ {0x1920, 0x192b},
+ {0x1930, 0x193b},
+ {0x19b0, 0x19c0},
+ {0x19c8, 0x19c9},
+ {0x1a17, 0x1a1b},
+ {0x1a55, 0x1a5e},
+ {0x1a60, 0x1a7c},
+ {0x1a7f, 0x1a7f},
+ {0x1b00, 0x1b04},
+ {0x1b34, 0x1b44},
+ {0x1b6b, 0x1b73},
+ {0x1b80, 0x1b82},
+ {0x1ba1, 0x1baa},
+ {0x1c24, 0x1c37},
+ {0x1cd0, 0x1cd2},
+ {0x1cd4, 0x1ce8},
+ {0x1ced, 0x1ced},
+ {0x1cf2, 0x1cf2},
+ {0x1dc0, 0x1de6},
+ {0x1dfd, 0x1dff},
+ {0x20d0, 0x20f0},
+ {0x2cef, 0x2cf1},
+ {0x2de0, 0x2dff},
+ {0x302a, 0x302f},
+ {0x3099, 0x309a},
+ {0xa66f, 0xa672},
+ {0xa67c, 0xa67d},
+ {0xa6f0, 0xa6f1},
+ {0xa802, 0xa802},
+ {0xa806, 0xa806},
+ {0xa80b, 0xa80b},
+ {0xa823, 0xa827},
+ {0xa880, 0xa881},
+ {0xa8b4, 0xa8c4},
+ {0xa8e0, 0xa8f1},
+ {0xa926, 0xa92d},
+ {0xa947, 0xa953},
+ {0xa980, 0xa983},
+ {0xa9b3, 0xa9c0},
+ {0xaa29, 0xaa36},
+ {0xaa43, 0xaa43},
+ {0xaa4c, 0xaa4d},
+ {0xaa7b, 0xaa7b},
+ {0xaab0, 0xaab0},
+ {0xaab2, 0xaab4},
+ {0xaab7, 0xaab8},
+ {0xaabe, 0xaabf},
+ {0xaac1, 0xaac1},
+ {0xabe3, 0xabea},
+ {0xabec, 0xabed},
+ {0xfb1e, 0xfb1e},
+ {0xfe00, 0xfe0f},
+ {0xfe20, 0xfe26},
+ {0x101fd, 0x101fd},
+ {0x10a01, 0x10a03},
+ {0x10a05, 0x10a06},
+ {0x10a0c, 0x10a0f},
+ {0x10a38, 0x10a3a},
+ {0x10a3f, 0x10a3f},
+ {0x11080, 0x11082},
+ {0x110b0, 0x110ba},
+ {0x1d165, 0x1d169},
+ {0x1d16d, 0x1d172},
+ {0x1d17b, 0x1d182},
+ {0x1d185, 0x1d18b},
+ {0x1d1aa, 0x1d1ad},
+ {0x1d242, 0x1d244},
+ {0xe0100, 0xe01ef}
+ };
+
+ return intable(combining, sizeof(combining), c);
+}
+
+/*
+ * Return TRUE for characters that can be displayed in a normal way.
+ * Only for characters of 0x100 and above!
+ */
+int utf_printable(c)
+int c;
+{
+#ifdef USE_WCHAR_FUNCTIONS
+ /*
+ * Assume the iswprint() library function works better than our own stuff.
+ */
+ return iswprint(c);
+#else
+ /* Sorted list of non-overlapping intervals.
+ * 0xd800-0xdfff is reserved for UTF-16, actually illegal. */
+ static struct interval nonprint[] =
+ {
+ {0x070f, 0x070f}, {0x180b, 0x180e}, {0x200b, 0x200f}, {0x202a, 0x202e},
+ {0x206a, 0x206f}, {0xd800, 0xdfff}, {0xfeff, 0xfeff}, {0xfff9, 0xfffb},
+ {0xfffe, 0xffff}
+ };
+
+ return !intable(nonprint, sizeof(nonprint), c);
+#endif
+}
+
+/*
+ * Get class of a Unicode character.
+ * 0: white space
+ * 1: punctuation
+ * 2 or bigger: some class of word character.
+ */
+int utf_class(c)
+int c;
+{
+ /* sorted list of non-overlapping intervals */
+ static struct clinterval {
+ unsigned int first;
+ unsigned int last;
+ unsigned int class;
+ } classes[] =
+ {
+ {0x037e, 0x037e, 1}, /* Greek question mark */
+ {0x0387, 0x0387, 1}, /* Greek ano teleia */
+ {0x055a, 0x055f, 1}, /* Armenian punctuation */
+ {0x0589, 0x0589, 1}, /* Armenian full stop */
+ {0x05be, 0x05be, 1},
+ {0x05c0, 0x05c0, 1},
+ {0x05c3, 0x05c3, 1},
+ {0x05f3, 0x05f4, 1},
+ {0x060c, 0x060c, 1},
+ {0x061b, 0x061b, 1},
+ {0x061f, 0x061f, 1},
+ {0x066a, 0x066d, 1},
+ {0x06d4, 0x06d4, 1},
+ {0x0700, 0x070d, 1}, /* Syriac punctuation */
+ {0x0964, 0x0965, 1},
+ {0x0970, 0x0970, 1},
+ {0x0df4, 0x0df4, 1},
+ {0x0e4f, 0x0e4f, 1},
+ {0x0e5a, 0x0e5b, 1},
+ {0x0f04, 0x0f12, 1},
+ {0x0f3a, 0x0f3d, 1},
+ {0x0f85, 0x0f85, 1},
+ {0x104a, 0x104f, 1}, /* Myanmar punctuation */
+ {0x10fb, 0x10fb, 1}, /* Georgian punctuation */
+ {0x1361, 0x1368, 1}, /* Ethiopic punctuation */
+ {0x166d, 0x166e, 1}, /* Canadian Syl. punctuation */
+ {0x1680, 0x1680, 0},
+ {0x169b, 0x169c, 1},
+ {0x16eb, 0x16ed, 1},
+ {0x1735, 0x1736, 1},
+ {0x17d4, 0x17dc, 1}, /* Khmer punctuation */
+ {0x1800, 0x180a, 1}, /* Mongolian punctuation */
+ {0x2000, 0x200b, 0}, /* spaces */
+ {0x200c, 0x2027, 1}, /* punctuation and symbols */
+ {0x2028, 0x2029, 0},
+ {0x202a, 0x202e, 1}, /* punctuation and symbols */
+ {0x202f, 0x202f, 0},
+ {0x2030, 0x205e, 1}, /* punctuation and symbols */
+ {0x205f, 0x205f, 0},
+ {0x2060, 0x27ff, 1}, /* punctuation and symbols */
+ {0x2070, 0x207f, 0x2070}, /* superscript */
+ {0x2080, 0x2094, 0x2080}, /* subscript */
+ {0x20a0, 0x27ff, 1}, /* all kinds of symbols */
+ {0x2800, 0x28ff, 0x2800}, /* braille */
+ {0x2900, 0x2998, 1}, /* arrows, brackets, etc. */
+ {0x29d8, 0x29db, 1},
+ {0x29fc, 0x29fd, 1},
+ {0x3000, 0x3000, 0}, /* ideographic space */
+ {0x3001, 0x3020, 1}, /* ideographic punctuation */
+ {0x3030, 0x3030, 1},
+ {0x303d, 0x303d, 1},
+ {0x3040, 0x309f, 0x3040}, /* Hiragana */
+ {0x30a0, 0x30ff, 0x30a0}, /* Katakana */
+ {0x3300, 0x9fff, 0x4e00}, /* CJK Ideographs */
+ {0xac00, 0xd7a3, 0xac00}, /* Hangul Syllables */
+ {0xf900, 0xfaff, 0x4e00}, /* CJK Ideographs */
+ {0xfd3e, 0xfd3f, 1},
+ {0xfe30, 0xfe6b, 1}, /* punctuation forms */
+ {0xff00, 0xff0f, 1}, /* half/fullwidth ASCII */
+ {0xff1a, 0xff20, 1}, /* half/fullwidth ASCII */
+ {0xff3b, 0xff40, 1}, /* half/fullwidth ASCII */
+ {0xff5b, 0xff65, 1}, /* half/fullwidth ASCII */
+ {0x20000, 0x2a6df, 0x4e00}, /* CJK Ideographs */
+ {0x2a700, 0x2b73f, 0x4e00}, /* CJK Ideographs */
+ {0x2b740, 0x2b81f, 0x4e00}, /* CJK Ideographs */
+ {0x2f800, 0x2fa1f, 0x4e00}, /* CJK Ideographs */
+ };
+ int bot = 0;
+ int top = sizeof(classes) / sizeof(struct clinterval) - 1;
+ int mid;
+
+ /* 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 */
+ }
+
+ /* binary search in table */
+ while (top >= bot) {
+ mid = (bot + top) / 2;
+ if (classes[mid].last < (unsigned int)c)
+ bot = mid + 1;
+ else if (classes[mid].first > (unsigned int)c)
+ top = mid - 1;
+ else
+ return (int)classes[mid].class;
+ }
+
+ /* 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.
+ */
+
+/*
+ * The following tables are built by ../runtime/tools/unicode.vim.
+ * They must be in numeric order, because we use binary search.
+ * An entry such as {0x41,0x5a,1,32} means that Unicode characters in the
+ * range from 0x41 to 0x5a inclusive, stepping by 1, are changed to
+ * folded/upper/lower by adding 32.
+ */
+typedef struct {
+ int rangeStart;
+ int rangeEnd;
+ int step;
+ int offset;
+} convertStruct;
+
+static convertStruct foldCase[] =
+{
+ {0x41,0x5a,1,32},
+ {0xb5,0xb5,-1,775},
+ {0xc0,0xd6,1,32},
+ {0xd8,0xde,1,32},
+ {0x100,0x12e,2,1},
+ {0x132,0x136,2,1},
+ {0x139,0x147,2,1},
+ {0x14a,0x176,2,1},
+ {0x178,0x178,-1,-121},
+ {0x179,0x17d,2,1},
+ {0x17f,0x17f,-1,-268},
+ {0x181,0x181,-1,210},
+ {0x182,0x184,2,1},
+ {0x186,0x186,-1,206},
+ {0x187,0x187,-1,1},
+ {0x189,0x18a,1,205},
+ {0x18b,0x18b,-1,1},
+ {0x18e,0x18e,-1,79},
+ {0x18f,0x18f,-1,202},
+ {0x190,0x190,-1,203},
+ {0x191,0x191,-1,1},
+ {0x193,0x193,-1,205},
+ {0x194,0x194,-1,207},
+ {0x196,0x196,-1,211},
+ {0x197,0x197,-1,209},
+ {0x198,0x198,-1,1},
+ {0x19c,0x19c,-1,211},
+ {0x19d,0x19d,-1,213},
+ {0x19f,0x19f,-1,214},
+ {0x1a0,0x1a4,2,1},
+ {0x1a6,0x1a6,-1,218},
+ {0x1a7,0x1a7,-1,1},
+ {0x1a9,0x1a9,-1,218},
+ {0x1ac,0x1ac,-1,1},
+ {0x1ae,0x1ae,-1,218},
+ {0x1af,0x1af,-1,1},
+ {0x1b1,0x1b2,1,217},
+ {0x1b3,0x1b5,2,1},
+ {0x1b7,0x1b7,-1,219},
+ {0x1b8,0x1bc,4,1},
+ {0x1c4,0x1c4,-1,2},
+ {0x1c5,0x1c5,-1,1},
+ {0x1c7,0x1c7,-1,2},
+ {0x1c8,0x1c8,-1,1},
+ {0x1ca,0x1ca,-1,2},
+ {0x1cb,0x1db,2,1},
+ {0x1de,0x1ee,2,1},
+ {0x1f1,0x1f1,-1,2},
+ {0x1f2,0x1f4,2,1},
+ {0x1f6,0x1f6,-1,-97},
+ {0x1f7,0x1f7,-1,-56},
+ {0x1f8,0x21e,2,1},
+ {0x220,0x220,-1,-130},
+ {0x222,0x232,2,1},
+ {0x23a,0x23a,-1,10795},
+ {0x23b,0x23b,-1,1},
+ {0x23d,0x23d,-1,-163},
+ {0x23e,0x23e,-1,10792},
+ {0x241,0x241,-1,1},
+ {0x243,0x243,-1,-195},
+ {0x244,0x244,-1,69},
+ {0x245,0x245,-1,71},
+ {0x246,0x24e,2,1},
+ {0x345,0x345,-1,116},
+ {0x370,0x372,2,1},
+ {0x376,0x376,-1,1},
+ {0x386,0x386,-1,38},
+ {0x388,0x38a,1,37},
+ {0x38c,0x38c,-1,64},
+ {0x38e,0x38f,1,63},
+ {0x391,0x3a1,1,32},
+ {0x3a3,0x3ab,1,32},
+ {0x3c2,0x3c2,-1,1},
+ {0x3cf,0x3cf,-1,8},
+ {0x3d0,0x3d0,-1,-30},
+ {0x3d1,0x3d1,-1,-25},
+ {0x3d5,0x3d5,-1,-15},
+ {0x3d6,0x3d6,-1,-22},
+ {0x3d8,0x3ee,2,1},
+ {0x3f0,0x3f0,-1,-54},
+ {0x3f1,0x3f1,-1,-48},
+ {0x3f4,0x3f4,-1,-60},
+ {0x3f5,0x3f5,-1,-64},
+ {0x3f7,0x3f7,-1,1},
+ {0x3f9,0x3f9,-1,-7},
+ {0x3fa,0x3fa,-1,1},
+ {0x3fd,0x3ff,1,-130},
+ {0x400,0x40f,1,80},
+ {0x410,0x42f,1,32},
+ {0x460,0x480,2,1},
+ {0x48a,0x4be,2,1},
+ {0x4c0,0x4c0,-1,15},
+ {0x4c1,0x4cd,2,1},
+ {0x4d0,0x524,2,1},
+ {0x531,0x556,1,48},
+ {0x10a0,0x10c5,1,7264},
+ {0x1e00,0x1e94,2,1},
+ {0x1e9b,0x1e9b,-1,-58},
+ {0x1e9e,0x1e9e,-1,-7615},
+ {0x1ea0,0x1efe,2,1},
+ {0x1f08,0x1f0f,1,-8},
+ {0x1f18,0x1f1d,1,-8},
+ {0x1f28,0x1f2f,1,-8},
+ {0x1f38,0x1f3f,1,-8},
+ {0x1f48,0x1f4d,1,-8},
+ {0x1f59,0x1f5f,2,-8},
+ {0x1f68,0x1f6f,1,-8},
+ {0x1f88,0x1f8f,1,-8},
+ {0x1f98,0x1f9f,1,-8},
+ {0x1fa8,0x1faf,1,-8},
+ {0x1fb8,0x1fb9,1,-8},
+ {0x1fba,0x1fbb,1,-74},
+ {0x1fbc,0x1fbc,-1,-9},
+ {0x1fbe,0x1fbe,-1,-7173},
+ {0x1fc8,0x1fcb,1,-86},
+ {0x1fcc,0x1fcc,-1,-9},
+ {0x1fd8,0x1fd9,1,-8},
+ {0x1fda,0x1fdb,1,-100},
+ {0x1fe8,0x1fe9,1,-8},
+ {0x1fea,0x1feb,1,-112},
+ {0x1fec,0x1fec,-1,-7},
+ {0x1ff8,0x1ff9,1,-128},
+ {0x1ffa,0x1ffb,1,-126},
+ {0x1ffc,0x1ffc,-1,-9},
+ {0x2126,0x2126,-1,-7517},
+ {0x212a,0x212a,-1,-8383},
+ {0x212b,0x212b,-1,-8262},
+ {0x2132,0x2132,-1,28},
+ {0x2160,0x216f,1,16},
+ {0x2183,0x2183,-1,1},
+ {0x24b6,0x24cf,1,26},
+ {0x2c00,0x2c2e,1,48},
+ {0x2c60,0x2c60,-1,1},
+ {0x2c62,0x2c62,-1,-10743},
+ {0x2c63,0x2c63,-1,-3814},
+ {0x2c64,0x2c64,-1,-10727},
+ {0x2c67,0x2c6b,2,1},
+ {0x2c6d,0x2c6d,-1,-10780},
+ {0x2c6e,0x2c6e,-1,-10749},
+ {0x2c6f,0x2c6f,-1,-10783},
+ {0x2c70,0x2c70,-1,-10782},
+ {0x2c72,0x2c75,3,1},
+ {0x2c7e,0x2c7f,1,-10815},
+ {0x2c80,0x2ce2,2,1},
+ {0x2ceb,0x2ced,2,1},
+ {0xa640,0xa65e,2,1},
+ {0xa662,0xa66c,2,1},
+ {0xa680,0xa696,2,1},
+ {0xa722,0xa72e,2,1},
+ {0xa732,0xa76e,2,1},
+ {0xa779,0xa77b,2,1},
+ {0xa77d,0xa77d,-1,-35332},
+ {0xa77e,0xa786,2,1},
+ {0xa78b,0xa78b,-1,1},
+ {0xff21,0xff3a,1,32},
+ {0x10400,0x10427,1,40}
+};
+
+static int utf_convert __ARGS((int a, convertStruct table[], int tableSize));
+static int utf_strnicmp __ARGS((char_u *s1, char_u *s2, size_t n1, size_t n2));
+
+/*
+ * Generic conversion function for case operations.
+ * Return the converted equivalent of "a", which is a UCS-4 character. Use
+ * the given conversion "table". Uses binary search on "table".
+ */
+static int utf_convert(a, table, tableSize)
+int a;
+convertStruct table[];
+int tableSize;
+{
+ int start, mid, end; /* indices into table */
+ int entries = tableSize / sizeof(convertStruct);
+
+ start = 0;
+ end = entries;
+ while (start < end) {
+ /* need to search further */
+ mid = (end + start) / 2;
+ if (table[mid].rangeEnd < a)
+ start = mid + 1;
+ else
+ end = mid;
+ }
+ if (start < entries
+ && table[start].rangeStart <= a
+ && a <= table[start].rangeEnd
+ && (a - table[start].rangeStart) % table[start].step == 0)
+ return a + table[start].offset;
+ else
+ return a;
+}
+
+/*
+ * Return the folded-case equivalent of "a", which is a UCS-4 character. Uses
+ * simple case folding.
+ */
+int utf_fold(a)
+int a;
+{
+ return utf_convert(a, foldCase, (int)sizeof(foldCase));
+}
+
+static convertStruct toLower[] =
+{
+ {0x41,0x5a,1,32},
+ {0xc0,0xd6,1,32},
+ {0xd8,0xde,1,32},
+ {0x100,0x12e,2,1},
+ {0x130,0x130,-1,-199},
+ {0x132,0x136,2,1},
+ {0x139,0x147,2,1},
+ {0x14a,0x176,2,1},
+ {0x178,0x178,-1,-121},
+ {0x179,0x17d,2,1},
+ {0x181,0x181,-1,210},
+ {0x182,0x184,2,1},
+ {0x186,0x186,-1,206},
+ {0x187,0x187,-1,1},
+ {0x189,0x18a,1,205},
+ {0x18b,0x18b,-1,1},
+ {0x18e,0x18e,-1,79},
+ {0x18f,0x18f,-1,202},
+ {0x190,0x190,-1,203},
+ {0x191,0x191,-1,1},
+ {0x193,0x193,-1,205},
+ {0x194,0x194,-1,207},
+ {0x196,0x196,-1,211},
+ {0x197,0x197,-1,209},
+ {0x198,0x198,-1,1},
+ {0x19c,0x19c,-1,211},
+ {0x19d,0x19d,-1,213},
+ {0x19f,0x19f,-1,214},
+ {0x1a0,0x1a4,2,1},
+ {0x1a6,0x1a6,-1,218},
+ {0x1a7,0x1a7,-1,1},
+ {0x1a9,0x1a9,-1,218},
+ {0x1ac,0x1ac,-1,1},
+ {0x1ae,0x1ae,-1,218},
+ {0x1af,0x1af,-1,1},
+ {0x1b1,0x1b2,1,217},
+ {0x1b3,0x1b5,2,1},
+ {0x1b7,0x1b7,-1,219},
+ {0x1b8,0x1bc,4,1},
+ {0x1c4,0x1c4,-1,2},
+ {0x1c5,0x1c5,-1,1},
+ {0x1c7,0x1c7,-1,2},
+ {0x1c8,0x1c8,-1,1},
+ {0x1ca,0x1ca,-1,2},
+ {0x1cb,0x1db,2,1},
+ {0x1de,0x1ee,2,1},
+ {0x1f1,0x1f1,-1,2},
+ {0x1f2,0x1f4,2,1},
+ {0x1f6,0x1f6,-1,-97},
+ {0x1f7,0x1f7,-1,-56},
+ {0x1f8,0x21e,2,1},
+ {0x220,0x220,-1,-130},
+ {0x222,0x232,2,1},
+ {0x23a,0x23a,-1,10795},
+ {0x23b,0x23b,-1,1},
+ {0x23d,0x23d,-1,-163},
+ {0x23e,0x23e,-1,10792},
+ {0x241,0x241,-1,1},
+ {0x243,0x243,-1,-195},
+ {0x244,0x244,-1,69},
+ {0x245,0x245,-1,71},
+ {0x246,0x24e,2,1},
+ {0x370,0x372,2,1},
+ {0x376,0x376,-1,1},
+ {0x386,0x386,-1,38},
+ {0x388,0x38a,1,37},
+ {0x38c,0x38c,-1,64},
+ {0x38e,0x38f,1,63},
+ {0x391,0x3a1,1,32},
+ {0x3a3,0x3ab,1,32},
+ {0x3cf,0x3cf,-1,8},
+ {0x3d8,0x3ee,2,1},
+ {0x3f4,0x3f4,-1,-60},
+ {0x3f7,0x3f7,-1,1},
+ {0x3f9,0x3f9,-1,-7},
+ {0x3fa,0x3fa,-1,1},
+ {0x3fd,0x3ff,1,-130},
+ {0x400,0x40f,1,80},
+ {0x410,0x42f,1,32},
+ {0x460,0x480,2,1},
+ {0x48a,0x4be,2,1},
+ {0x4c0,0x4c0,-1,15},
+ {0x4c1,0x4cd,2,1},
+ {0x4d0,0x524,2,1},
+ {0x531,0x556,1,48},
+ {0x10a0,0x10c5,1,7264},
+ {0x1e00,0x1e94,2,1},
+ {0x1e9e,0x1e9e,-1,-7615},
+ {0x1ea0,0x1efe,2,1},
+ {0x1f08,0x1f0f,1,-8},
+ {0x1f18,0x1f1d,1,-8},
+ {0x1f28,0x1f2f,1,-8},
+ {0x1f38,0x1f3f,1,-8},
+ {0x1f48,0x1f4d,1,-8},
+ {0x1f59,0x1f5f,2,-8},
+ {0x1f68,0x1f6f,1,-8},
+ {0x1f88,0x1f8f,1,-8},
+ {0x1f98,0x1f9f,1,-8},
+ {0x1fa8,0x1faf,1,-8},
+ {0x1fb8,0x1fb9,1,-8},
+ {0x1fba,0x1fbb,1,-74},
+ {0x1fbc,0x1fbc,-1,-9},
+ {0x1fc8,0x1fcb,1,-86},
+ {0x1fcc,0x1fcc,-1,-9},
+ {0x1fd8,0x1fd9,1,-8},
+ {0x1fda,0x1fdb,1,-100},
+ {0x1fe8,0x1fe9,1,-8},
+ {0x1fea,0x1feb,1,-112},
+ {0x1fec,0x1fec,-1,-7},
+ {0x1ff8,0x1ff9,1,-128},
+ {0x1ffa,0x1ffb,1,-126},
+ {0x1ffc,0x1ffc,-1,-9},
+ {0x2126,0x2126,-1,-7517},
+ {0x212a,0x212a,-1,-8383},
+ {0x212b,0x212b,-1,-8262},
+ {0x2132,0x2132,-1,28},
+ {0x2160,0x216f,1,16},
+ {0x2183,0x2183,-1,1},
+ {0x24b6,0x24cf,1,26},
+ {0x2c00,0x2c2e,1,48},
+ {0x2c60,0x2c60,-1,1},
+ {0x2c62,0x2c62,-1,-10743},
+ {0x2c63,0x2c63,-1,-3814},
+ {0x2c64,0x2c64,-1,-10727},
+ {0x2c67,0x2c6b,2,1},
+ {0x2c6d,0x2c6d,-1,-10780},
+ {0x2c6e,0x2c6e,-1,-10749},
+ {0x2c6f,0x2c6f,-1,-10783},
+ {0x2c70,0x2c70,-1,-10782},
+ {0x2c72,0x2c75,3,1},
+ {0x2c7e,0x2c7f,1,-10815},
+ {0x2c80,0x2ce2,2,1},
+ {0x2ceb,0x2ced,2,1},
+ {0xa640,0xa65e,2,1},
+ {0xa662,0xa66c,2,1},
+ {0xa680,0xa696,2,1},
+ {0xa722,0xa72e,2,1},
+ {0xa732,0xa76e,2,1},
+ {0xa779,0xa77b,2,1},
+ {0xa77d,0xa77d,-1,-35332},
+ {0xa77e,0xa786,2,1},
+ {0xa78b,0xa78b,-1,1},
+ {0xff21,0xff3a,1,32},
+ {0x10400,0x10427,1,40}
+};
+
+static convertStruct toUpper[] =
+{
+ {0x61,0x7a,1,-32},
+ {0xb5,0xb5,-1,743},
+ {0xe0,0xf6,1,-32}, /* 0xdf (German sharp s) is not upper-cased */
+ {0xf8,0xfe,1,-32},
+ {0xff,0xff,-1,121},
+ {0x101,0x12f,2,-1},
+ {0x131,0x131,-1,-232},
+ {0x133,0x137,2,-1},
+ {0x13a,0x148,2,-1},
+ {0x14b,0x177,2,-1},
+ {0x17a,0x17e,2,-1},
+ {0x17f,0x17f,-1,-300},
+ {0x180,0x180,-1,195},
+ {0x183,0x185,2,-1},
+ {0x188,0x18c,4,-1},
+ {0x192,0x192,-1,-1},
+ {0x195,0x195,-1,97},
+ {0x199,0x199,-1,-1},
+ {0x19a,0x19a,-1,163},
+ {0x19e,0x19e,-1,130},
+ {0x1a1,0x1a5,2,-1},
+ {0x1a8,0x1ad,5,-1},
+ {0x1b0,0x1b4,4,-1},
+ {0x1b6,0x1b9,3,-1},
+ {0x1bd,0x1bd,-1,-1},
+ {0x1bf,0x1bf,-1,56},
+ {0x1c5,0x1c5,-1,-1},
+ {0x1c6,0x1c6,-1,-2},
+ {0x1c8,0x1c8,-1,-1},
+ {0x1c9,0x1c9,-1,-2},
+ {0x1cb,0x1cb,-1,-1},
+ {0x1cc,0x1cc,-1,-2},
+ {0x1ce,0x1dc,2,-1},
+ {0x1dd,0x1dd,-1,-79},
+ {0x1df,0x1ef,2,-1},
+ {0x1f2,0x1f2,-1,-1},
+ {0x1f3,0x1f3,-1,-2},
+ {0x1f5,0x1f9,4,-1},
+ {0x1fb,0x21f,2,-1},
+ {0x223,0x233,2,-1},
+ {0x23c,0x23c,-1,-1},
+ {0x23f,0x240,1,10815},
+ {0x242,0x247,5,-1},
+ {0x249,0x24f,2,-1},
+ {0x250,0x250,-1,10783},
+ {0x251,0x251,-1,10780},
+ {0x252,0x252,-1,10782},
+ {0x253,0x253,-1,-210},
+ {0x254,0x254,-1,-206},
+ {0x256,0x257,1,-205},
+ {0x259,0x259,-1,-202},
+ {0x25b,0x25b,-1,-203},
+ {0x260,0x260,-1,-205},
+ {0x263,0x263,-1,-207},
+ {0x268,0x268,-1,-209},
+ {0x269,0x269,-1,-211},
+ {0x26b,0x26b,-1,10743},
+ {0x26f,0x26f,-1,-211},
+ {0x271,0x271,-1,10749},
+ {0x272,0x272,-1,-213},
+ {0x275,0x275,-1,-214},
+ {0x27d,0x27d,-1,10727},
+ {0x280,0x283,3,-218},
+ {0x288,0x288,-1,-218},
+ {0x289,0x289,-1,-69},
+ {0x28a,0x28b,1,-217},
+ {0x28c,0x28c,-1,-71},
+ {0x292,0x292,-1,-219},
+ {0x345,0x345,-1,84},
+ {0x371,0x373,2,-1},
+ {0x377,0x377,-1,-1},
+ {0x37b,0x37d,1,130},
+ {0x3ac,0x3ac,-1,-38},
+ {0x3ad,0x3af,1,-37},
+ {0x3b1,0x3c1,1,-32},
+ {0x3c2,0x3c2,-1,-31},
+ {0x3c3,0x3cb,1,-32},
+ {0x3cc,0x3cc,-1,-64},
+ {0x3cd,0x3ce,1,-63},
+ {0x3d0,0x3d0,-1,-62},
+ {0x3d1,0x3d1,-1,-57},
+ {0x3d5,0x3d5,-1,-47},
+ {0x3d6,0x3d6,-1,-54},
+ {0x3d7,0x3d7,-1,-8},
+ {0x3d9,0x3ef,2,-1},
+ {0x3f0,0x3f0,-1,-86},
+ {0x3f1,0x3f1,-1,-80},
+ {0x3f2,0x3f2,-1,7},
+ {0x3f5,0x3f5,-1,-96},
+ {0x3f8,0x3fb,3,-1},
+ {0x430,0x44f,1,-32},
+ {0x450,0x45f,1,-80},
+ {0x461,0x481,2,-1},
+ {0x48b,0x4bf,2,-1},
+ {0x4c2,0x4ce,2,-1},
+ {0x4cf,0x4cf,-1,-15},
+ {0x4d1,0x525,2,-1},
+ {0x561,0x586,1,-48},
+ {0x1d79,0x1d79,-1,35332},
+ {0x1d7d,0x1d7d,-1,3814},
+ {0x1e01,0x1e95,2,-1},
+ {0x1e9b,0x1e9b,-1,-59},
+ {0x1ea1,0x1eff,2,-1},
+ {0x1f00,0x1f07,1,8},
+ {0x1f10,0x1f15,1,8},
+ {0x1f20,0x1f27,1,8},
+ {0x1f30,0x1f37,1,8},
+ {0x1f40,0x1f45,1,8},
+ {0x1f51,0x1f57,2,8},
+ {0x1f60,0x1f67,1,8},
+ {0x1f70,0x1f71,1,74},
+ {0x1f72,0x1f75,1,86},
+ {0x1f76,0x1f77,1,100},
+ {0x1f78,0x1f79,1,128},
+ {0x1f7a,0x1f7b,1,112},
+ {0x1f7c,0x1f7d,1,126},
+ {0x1f80,0x1f87,1,8},
+ {0x1f90,0x1f97,1,8},
+ {0x1fa0,0x1fa7,1,8},
+ {0x1fb0,0x1fb1,1,8},
+ {0x1fb3,0x1fb3,-1,9},
+ {0x1fbe,0x1fbe,-1,-7205},
+ {0x1fc3,0x1fc3,-1,9},
+ {0x1fd0,0x1fd1,1,8},
+ {0x1fe0,0x1fe1,1,8},
+ {0x1fe5,0x1fe5,-1,7},
+ {0x1ff3,0x1ff3,-1,9},
+ {0x214e,0x214e,-1,-28},
+ {0x2170,0x217f,1,-16},
+ {0x2184,0x2184,-1,-1},
+ {0x24d0,0x24e9,1,-26},
+ {0x2c30,0x2c5e,1,-48},
+ {0x2c61,0x2c61,-1,-1},
+ {0x2c65,0x2c65,-1,-10795},
+ {0x2c66,0x2c66,-1,-10792},
+ {0x2c68,0x2c6c,2,-1},
+ {0x2c73,0x2c76,3,-1},
+ {0x2c81,0x2ce3,2,-1},
+ {0x2cec,0x2cee,2,-1},
+ {0x2d00,0x2d25,1,-7264},
+ {0xa641,0xa65f,2,-1},
+ {0xa663,0xa66d,2,-1},
+ {0xa681,0xa697,2,-1},
+ {0xa723,0xa72f,2,-1},
+ {0xa733,0xa76f,2,-1},
+ {0xa77a,0xa77c,2,-1},
+ {0xa77f,0xa787,2,-1},
+ {0xa78c,0xa78c,-1,-1},
+ {0xff41,0xff5a,1,-32},
+ {0x10428,0x1044f,1,-40}
+};
+
+/*
+ * Return the upper-case equivalent of "a", which is a UCS-4 character. Use
+ * simple case folding.
+ */
+int utf_toupper(a)
+int a;
+{
+ /* If 'casemap' contains "keepascii" use ASCII style toupper(). */
+ if (a < 128 && (cmp_flags & CMP_KEEPASCII))
+ return TOUPPER_ASC(a);
+
+#if defined(HAVE_TOWUPPER) && defined(__STDC_ISO_10646__)
+ /* If towupper() is available and handles Unicode, use it. */
+ if (!(cmp_flags & CMP_INTERNAL))
+ return towupper(a);
+#endif
+
+ /* For characters below 128 use locale sensitive toupper(). */
+ if (a < 128)
+ return TOUPPER_LOC(a);
+
+ /* For any other characters use the above mapping table. */
+ return utf_convert(a, toUpper, (int)sizeof(toUpper));
+}
+
+int utf_islower(a)
+int a;
+{
+ /* German sharp s is lower case but has no upper case equivalent. */
+ return (utf_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(a)
+int a;
+{
+ /* If 'casemap' contains "keepascii" use ASCII style tolower(). */
+ if (a < 128 && (cmp_flags & CMP_KEEPASCII))
+ return TOLOWER_ASC(a);
+
+#if defined(HAVE_TOWLOWER) && defined(__STDC_ISO_10646__)
+ /* If towlower() is available and handles Unicode, use it. */
+ if (!(cmp_flags & CMP_INTERNAL))
+ return towlower(a);
+#endif
+
+ /* For characters below 128 use locale sensitive tolower(). */
+ if (a < 128)
+ return TOLOWER_LOC(a);
+
+ /* For any other characters use the above mapping table. */
+ return utf_convert(a, toLower, (int)sizeof(toLower));
+}
+
+int utf_isupper(a)
+int a;
+{
+ return utf_tolower(a) != a;
+}
+
+static int utf_strnicmp(s1, s2, n1, n2)
+char_u *s1, *s2;
+size_t n1, n2;
+{
+ int c1, c2, cdiff;
+ char_u buffer[6];
+
+ for (;; ) {
+ c1 = utf_safe_read_char_adv(&s1, &n1);
+ c2 = utf_safe_read_char_adv(&s2, &n2);
+
+ if (c1 <= 0 || c2 <= 0)
+ break;
+
+ if (c1 == c2)
+ continue;
+
+ cdiff = utf_fold(c1) - utf_fold(c2);
+ if (cdiff != 0)
+ return cdiff;
+ }
+
+ /* some string ended or has an incomplete/illegal character sequence */
+
+ if (c1 == 0 || c2 == 0) {
+ /* some string ended. shorter string is smaller */
+ if (c1 == 0 && c2 == 0)
+ return 0;
+ return c1 == 0 ? -1 : 1;
+ }
+
+ /* Continue with bytewise comparison to produce some result that
+ * would make comparison operations involving this function transitive.
+ *
+ * If only one string had an error, comparison should be made with
+ * folded version of the other string. In this case it is enough
+ * to fold just one character to determine the result of comparison. */
+
+ if (c1 != -1 && c2 == -1) {
+ n1 = utf_char2bytes(utf_fold(c1), buffer);
+ s1 = buffer;
+ } else if (c2 != -1 && c1 == -1) {
+ n2 = utf_char2bytes(utf_fold(c2), buffer);
+ s2 = buffer;
+ }
+
+ while (n1 > 0 && n2 > 0 && *s1 != NUL && *s2 != NUL) {
+ cdiff = (int)(*s1) - (int)(*s2);
+ if (cdiff != 0)
+ return cdiff;
+
+ s1++;
+ s2++;
+ n1--;
+ n2--;
+ }
+
+ if (n1 > 0 && *s1 == NUL)
+ n1 = 0;
+ if (n2 > 0 && *s2 == NUL)
+ n2 = 0;
+
+ if (n1 == 0 && n2 == 0)
+ return 0;
+ return n1 == 0 ? -1 : 1;
+}
+
+/*
+ * Version of strnicmp() that handles multi-byte characters.
+ * Needed for Big5, Shift-JIS and UTF-8 encoding. Other DBCS encodings can
+ * probably use strnicmp(), because there are no ASCII characters in the
+ * second byte.
+ * Returns zero if s1 and s2 are equal (ignoring case), the difference between
+ * two characters otherwise.
+ */
+int mb_strnicmp(s1, s2, nn)
+char_u *s1, *s2;
+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 = MB_TOLOWER(s1[i]) - MB_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;
+}
+
+/*
+ * "g8": show bytes of the UTF-8 char under the cursor. Doesn't matter what
+ * 'encoding' has been set to.
+ */
+void show_utf8() {
+ int len;
+ int rlen = 0;
+ char_u *line;
+ int clen;
+ int i;
+
+ /* Get the byte length of the char under the cursor, including composing
+ * characters. */
+ line = ml_get_cursor();
+ len = utfc_ptr2len(line);
+ if (len == 0) {
+ MSG("NUL");
+ return;
+ }
+
+ clen = 0;
+ for (i = 0; i < len; ++i) {
+ if (clen == 0) {
+ /* start of (composing) character, get its length */
+ if (i > 0) {
+ STRCPY(IObuff + rlen, "+ ");
+ rlen += 2;
+ }
+ clen = utf_ptr2len(line + i);
+ }
+ sprintf((char *)IObuff + rlen, "%02x ",
+ (line[i] == NL) ? NUL : line[i]); /* NUL is stored as NL */
+ --clen;
+ rlen += (int)STRLEN(IObuff + rlen);
+ if (rlen > IOSIZE - 20)
+ break;
+ }
+
+ 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(base, p)
+char_u *base UNUSED;
+char_u *p UNUSED;
+{
+ return 0;
+}
+
+int dbcs_head_off(base, p)
+char_u *base;
+char_u *p;
+{
+ char_u *q;
+
+ /* 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. */
+ 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(base, p)
+char_u *base;
+char_u *p;
+{
+ char_u *q;
+
+ /* 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. */
+ q = base;
+ while (q < p) {
+ if (enc_dbcs == DBCS_JPNU && *q == 0x8e)
+ ++q;
+ else
+ q += dbcs_ptr2len(q);
+ }
+ return (q == p) ? 0 : 1;
+}
+
+int utf_head_off(base, p)
+char_u *base;
+char_u *p;
+{
+ char_u *q;
+ char_u *s;
+ int c;
+ int len;
+ char_u *j;
+
+ if (*p < 0x80) /* be quick for ASCII */
+ return 0;
+
+ /* Skip backwards over trailing bytes: 10xx.xxxx
+ * Skip backwards again if on a composing char. */
+ for (q = p;; --q) {
+ /* Move s to the last byte of this char. */
+ for (s = q; (s[1] & 0xc0) == 0x80; ++s)
+ ;
+ /* Move q to the first byte of this char. */
+ while (q > base && (*q & 0xc0) == 0x80)
+ --q;
+ /* Check for illegal sequence. Do allow an illegal byte after where we
+ * started. */
+ len = utf8len_tab[*q];
+ if (len != (int)(s - q + 1) && len != (int)(p - q + 1))
+ return 0;
+
+ if (q <= base)
+ break;
+
+ c = utf_ptr2char(q);
+ if (utf_iscomposing(c))
+ continue;
+
+ if (arabic_maycombine(c)) {
+ /* Advance to get a sneak-peak at the next char */
+ j = q;
+ --j;
+ /* Move j to the first byte of this char. */
+ while (j > base && (*j & 0xc0) == 0x80)
+ --j;
+ if (arabic_combine(utf_ptr2char(j), c))
+ continue;
+ }
+ break;
+ }
+
+ return (int)(p - q);
+}
+
+/*
+ * Copy a character from "*fp" to "*tp" and advance the pointers.
+ */
+void mb_copy_char(fp, tp)
+char_u **fp;
+char_u **tp;
+{
+ int l = (*mb_ptr2len)(*fp);
+
+ mch_memmove(*tp, *fp, (size_t)l);
+ *tp += l;
+ *fp += l;
+}
+
+/*
+ * Return the offset from "p" to the first byte of a character. When "p" is
+ * at the start of a character 0 is returned, otherwise the offset to the next
+ * character. Can start anywhere in a stream of bytes.
+ */
+int mb_off_next(base, p)
+char_u *base;
+char_u *p;
+{
+ int i;
+ int j;
+
+ if (enc_utf8) {
+ 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;
+ }
+ 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 the offset from "p" to the last byte of the character it points
+ * into. Can start anywhere in a stream of bytes.
+ */
+int mb_tail_off(base, p)
+char_u *base;
+char_u *p;
+{
+ int i;
+ int j;
+
+ 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;
+ }
+
+ /* 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)
+ return 0;
+
+ /* Return 1 when on the lead byte, 0 when on the tail byte. */
+ return 1 - dbcs_head_off(base, p);
+}
+
+/*
+ * Find the next illegal byte sequence.
+ */
+void utf_find_illegal() {
+ pos_T pos = curwin->w_cursor;
+ char_u *p;
+ int len;
+ vimconv_T vimconv;
+ 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'. */
+ convert_setup(&vimconv, p_enc, curbuf->b_p_fenc);
+ }
+
+ curwin->w_cursor.coladd = 0;
+ for (;; ) {
+ p = ml_get_cursor();
+ if (vimconv.vc_type != CONV_NONE) {
+ vim_free(tofree);
+ tofree = string_convert(&vimconv, p, NULL);
+ if (tofree == NULL)
+ break;
+ p = tofree;
+ }
+
+ while (*p != NUL) {
+ /* Illegal means that there are not enough trail bytes (checked by
+ * utf_ptr2len()) or too many of them (overlong sequence). */
+ len = utf_ptr2len(p);
+ if (*p >= 0x80 && (len == 1
+ || utf_char2len(utf_ptr2char(p)) != len)) {
+ if (vimconv.vc_type == CONV_NONE)
+ curwin->w_cursor.col += (colnr_T)(p - ml_get_cursor());
+ else {
+ int l;
+
+ len = (int)(p - tofree);
+ for (p = ml_get_cursor(); *p != NUL && len-- > 0; p += l) {
+ l = utf_ptr2len(p);
+ curwin->w_cursor.col += l;
+ }
+ }
+ goto theend;
+ }
+ p += len;
+ }
+ if (curwin->w_cursor.lnum == curbuf->b_ml.ml_line_count)
+ break;
+ ++curwin->w_cursor.lnum;
+ curwin->w_cursor.col = 0;
+ }
+
+ /* didn't find it: don't move and beep */
+ curwin->w_cursor = pos;
+ beep_flush();
+
+theend:
+ vim_free(tofree);
+ convert_setup(&vimconv, NULL, NULL);
+}
+
+/*
+ * If the cursor moves on an trail byte, set the cursor on the lead byte.
+ * Thus it moves left if necessary.
+ * Return TRUE when the cursor was adjusted.
+ */
+void mb_adjust_cursor() {
+ 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, lp)
+buf_T *buf;
+pos_T *lp;
+{
+ char_u *p;
+
+ 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;
+ }
+}
+
+/*
+ * Return a pointer to the character before "*p", if there is one.
+ */
+char_u * mb_prevptr(line, p)
+char_u *line; /* start of the string */
+char_u *p;
+{
+ if (p > line)
+ mb_ptr_back(line, p);
+ return p;
+}
+
+/*
+ * Return the character length of "str". Each multi-byte character (with
+ * following composing characters) counts as one.
+ */
+int mb_charlen(str)
+char_u *str;
+{
+ char_u *p = str;
+ int count;
+
+ if (p == NULL)
+ return 0;
+
+ for (count = 0; *p != NUL; count++)
+ p += (*mb_ptr2len)(p);
+
+ return count;
+}
+
+/*
+ * Like mb_charlen() but for a string with specified length.
+ */
+int mb_charlen_len(str, len)
+char_u *str;
+int len;
+{
+ char_u *p = str;
+ int count;
+
+ for (count = 0; *p != NUL && p < str + len; count++)
+ p += (*mb_ptr2len)(p);
+
+ 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(pp)
+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;
+
+ /* 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 buf;
+ }
+
+ /* Bail out quickly for ASCII. */
+ if (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!
+ */
+int mb_lefthalve(row, col)
+int row;
+int col;
+{
+ if (composing_hangul)
+ return TRUE;
+ 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(col, row)
+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;
+}
+
+static int enc_alias_search __ARGS((char_u *name));
+
+/*
+ * Skip the Vim specific head of a 'encoding' name.
+ */
+char_u * enc_skip(p)
+char_u *p;
+{
+ if (STRNCMP(p, "2byte-", 6) == 0)
+ return p + 6;
+ if (STRNCMP(p, "8bit-", 5) == 0)
+ return p + 5;
+ return p;
+}
+
+/*
+ * Find the canonical name for encoding "enc".
+ * When the name isn't recognized, returns "enc" itself, but with all lower
+ * case characters and '_' replaced with '-'.
+ * Returns an allocated string. NULL for out-of-memory.
+ */
+char_u * enc_canonize(enc)
+char_u *enc;
+{
+ char_u *r;
+ char_u *p, *s;
+ int i;
+
+ if (STRCMP(enc, "default") == 0) {
+ /* Use the default encoding as it's found by set_init_1(). */
+ r = get_encoding_default();
+ if (r == NULL)
+ r = (char_u *)"latin1";
+ return vim_strsave(r);
+ }
+
+ /* copy "enc" to allocated memory, with room for two '-' */
+ r = alloc((unsigned)(STRLEN(enc) + 3));
+ if (r != NULL) {
+ /* Make it all lower case and replace '_' with '-'. */
+ p = r;
+ for (s = enc; *s != NUL; ++s) {
+ if (*s == '_')
+ *p++ = '-';
+ else
+ *p++ = TOLOWER_ASC(*s);
+ }
+ *p = NUL;
+
+ /* Skip "2byte-" and "8bit-". */
+ p = enc_skip(r);
+
+ /* Change "microsoft-cp" to "cp". Used in some spell files. */
+ if (STRNCMP(p, "microsoft-cp", 12) == 0)
+ STRMOVE(p, p + 10);
+
+ /* "iso8859" -> "iso-8859" */
+ if (STRNCMP(p, "iso8859", 7) == 0) {
+ STRMOVE(p + 4, p + 3);
+ p[3] = '-';
+ }
+
+ /* "iso-8859n" -> "iso-8859-n" */
+ if (STRNCMP(p, "iso-8859", 8) == 0 && p[8] != '-') {
+ STRMOVE(p + 9, p + 8);
+ p[8] = '-';
+ }
+
+ /* "latin-N" -> "latinN" */
+ if (STRNCMP(p, "latin-", 6) == 0)
+ STRMOVE(p + 5, p + 6);
+
+ if (enc_canon_search(p) >= 0) {
+ /* canonical name can be used unmodified */
+ if (p != r)
+ STRMOVE(r, p);
+ } else if ((i = enc_alias_search(p)) >= 0) {
+ /* alias recognized, get canonical name */
+ vim_free(r);
+ r = vim_strsave((char_u *)enc_canon_table[i].name);
+ }
+ }
+ return r;
+}
+
+/*
+ * Search for an encoding alias of "name".
+ * Returns -1 when not found.
+ */
+static int enc_alias_search(name)
+char_u *name;
+{
+ int i;
+
+ for (i = 0; enc_alias_table[i].name != NULL; ++i)
+ if (STRCMP(name, enc_alias_table[i].name) == 0)
+ return enc_alias_table[i].canon;
+ return -1;
+}
+
+
+#ifdef HAVE_LANGINFO_H
+# include <langinfo.h>
+#endif
+
+/*
+ * Get the canonicalized encoding of the current locale.
+ * Returns an allocated string when successful, NULL when not.
+ */
+char_u * enc_locale() {
+ char *s;
+ char *p;
+ int i;
+ char buf[50];
+# ifdef HAVE_NL_LANGINFO_CODESET
+ if ((s = nl_langinfo(CODESET)) == NULL || *s == NUL)
+# endif
+# if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
+ if ((s = setlocale(LC_CTYPE, NULL)) == NULL || *s == NUL)
+# endif
+ if ((s = getenv("LC_ALL")) == NULL || *s == NUL)
+ if ((s = getenv("LC_CTYPE")) == NULL || *s == NUL)
+ s = getenv("LANG");
+
+ if (s == NULL || *s == NUL)
+ return FAIL;
+
+ /* 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"
+ */
+ if ((p = (char *)vim_strchr((char_u *)s, '.')) != NULL) {
+ if (p > s + 2 && STRNICMP(p + 1, "EUC", 3) == 0
+ && !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
+ s = p + 1;
+ }
+ 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);
+}
+
+# if defined(USE_ICONV) || defined(PROTO)
+
+static char_u *
+iconv_string __ARGS((vimconv_T *vcp, char_u *str, int slen, int *unconvlenp,
+ int *resultlenp));
+
+/*
+ * Call iconv_open() with a check if iconv() works properly (there are broken
+ * versions).
+ * Returns (void *)-1 if failed.
+ * (should return iconv_t, but that causes problems with prototypes).
+ */
+void * my_iconv_open(to, from)
+char_u *to;
+char_u *from;
+{
+ iconv_t fd;
+#define ICONV_TESTLEN 400
+ char_u tobuf[ICONV_TESTLEN];
+ char *p;
+ size_t tolen;
+ static int iconv_ok = -1;
+
+ if (iconv_ok == FALSE)
+ return (void *)-1; /* detected a broken iconv() previously */
+
+#ifdef DYNAMIC_ICONV
+ /* 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));
+
+ if (fd != (iconv_t)-1 && iconv_ok == -1) {
+ /*
+ * Do a dummy iconv() call to check if it actually works. There is a
+ * version of iconv() on Linux that is broken. We can't ignore it,
+ * because it's wide-spread. The symptoms are that after outputting
+ * the initial shift state the "to" pointer is NULL and conversion
+ * stops for no apparent reason after about 8160 characters.
+ */
+ p = (char *)tobuf;
+ tolen = ICONV_TESTLEN;
+ (void)iconv(fd, NULL, NULL, &p, &tolen);
+ if (p == NULL) {
+ iconv_ok = FALSE;
+ iconv_close(fd);
+ fd = (iconv_t)-1;
+ } else
+ iconv_ok = TRUE;
+ }
+
+ return (void *)fd;
+}
+
+/*
+ * Convert the string "str[slen]" with iconv().
+ * If "unconvlenp" is not NULL handle the string ending in an incomplete
+ * sequence and set "*unconvlenp" to the length of it.
+ * 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(vcp, str, slen, unconvlenp, resultlenp)
+vimconv_T *vcp;
+char_u *str;
+int slen;
+int *unconvlenp;
+int *resultlenp;
+{
+ const char *from;
+ size_t fromlen;
+ char *to;
+ size_t tolen;
+ size_t len = 0;
+ size_t done = 0;
+ char_u *result = NULL;
+ char_u *p;
+ int l;
+
+ from = (char *)str;
+ fromlen = slen;
+ for (;; ) {
+ if (len == 0 || ICONV_ERRNO == ICONV_E2BIG) {
+ /* Allocate enough room for most conversions. When re-allocating
+ * increase the buffer size. */
+ len = len + fromlen * 2 + 40;
+ p = alloc((unsigned)len);
+ if (p != NULL && done > 0)
+ mch_memmove(p, result, done);
+ vim_free(result);
+ result = p;
+ if (result == NULL) /* out of memory */
+ break;
+ }
+
+ to = (char *)result + done;
+ tolen = len - done - 2;
+ /* Avoid a warning for systems with a wrong iconv() prototype by
+ * casting the second argument to void *. */
+ if (iconv(vcp->vc_fd, (void *)&from, &fromlen, &to, &tolen)
+ != (size_t)-1) {
+ /* Finished, append a NUL. */
+ *to = NUL;
+ break;
+ }
+
+ /* Check both ICONV_EINVAL and EINVAL, because the dynamically loaded
+ * iconv library may use one of them. */
+ if (!vcp->vc_fail && unconvlenp != NULL
+ && (ICONV_ERRNO == ICONV_EINVAL || ICONV_ERRNO == EINVAL)) {
+ /* Handle an incomplete sequence at the end. */
+ *to = NUL;
+ *unconvlenp = (int)fromlen;
+ break;
+ }
+ /* Check both ICONV_EILSEQ and EILSEQ, because the dynamically loaded
+ * iconv library may use one of them. */
+ else if (!vcp->vc_fail
+ && (ICONV_ERRNO == ICONV_EILSEQ || ICONV_ERRNO == EILSEQ
+ || ICONV_ERRNO == ICONV_EINVAL || ICONV_ERRNO == EINVAL)) {
+ /* Can't convert: insert a '?' and skip a character. This assumes
+ * 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)
+ *to++ = '?';
+ if (enc_utf8)
+ l = utfc_ptr2len_len((char_u *)from, (int)fromlen);
+ else {
+ l = (*mb_ptr2len)((char_u *)from);
+ if (l > (int)fromlen)
+ l = (int)fromlen;
+ }
+ from += l;
+ fromlen -= l;
+ } else if (ICONV_ERRNO != ICONV_E2BIG) {
+ /* conversion failed */
+ vim_free(result);
+ result = NULL;
+ break;
+ }
+ /* Not enough room or skipping illegal sequence. */
+ done = to - (char *)result;
+ }
+
+ if (resultlenp != NULL && result != NULL)
+ *resultlenp = (int)(to - (char *)result);
+ return result;
+}
+
+# if defined(DYNAMIC_ICONV) || defined(PROTO)
+/*
+ * Dynamically load the "iconv.dll" on Win32.
+ */
+
+#ifndef DYNAMIC_ICONV /* just generating prototypes */
+# define HINSTANCE int
+#endif
+static HINSTANCE hIconvDLL = 0;
+static HINSTANCE hMsvcrtDLL = 0;
+
+# ifndef DYNAMIC_ICONV_DLL
+# define DYNAMIC_ICONV_DLL "iconv.dll"
+# define DYNAMIC_ICONV_DLL_ALT "libiconv.dll"
+# endif
+# ifndef DYNAMIC_MSVCRT_DLL
+# define DYNAMIC_MSVCRT_DLL "msvcrt.dll"
+# endif
+
+/*
+ * Get the address of 'funcname' which is imported by 'hInst' DLL.
+ */
+static void * get_iconv_import_func(HINSTANCE hInst,
+ const char *funcname) {
+ PBYTE pImage = (PBYTE)hInst;
+ PIMAGE_DOS_HEADER pDOS = (PIMAGE_DOS_HEADER)hInst;
+ PIMAGE_NT_HEADERS pPE;
+ PIMAGE_IMPORT_DESCRIPTOR pImpDesc;
+ PIMAGE_THUNK_DATA pIAT; /* Import Address Table */
+ PIMAGE_THUNK_DATA pINT; /* Import Name Table */
+ PIMAGE_IMPORT_BY_NAME pImpName;
+
+ if (pDOS->e_magic != IMAGE_DOS_SIGNATURE)
+ return NULL;
+ pPE = (PIMAGE_NT_HEADERS)(pImage + pDOS->e_lfanew);
+ if (pPE->Signature != IMAGE_NT_SIGNATURE)
+ return NULL;
+ pImpDesc = (PIMAGE_IMPORT_DESCRIPTOR)(pImage
+ + pPE->OptionalHeader.DataDirectory[
+ IMAGE_DIRECTORY_ENTRY_IMPORT]
+ .VirtualAddress);
+ for (; pImpDesc->FirstThunk; ++pImpDesc) {
+ if (!pImpDesc->OriginalFirstThunk)
+ continue;
+ pIAT = (PIMAGE_THUNK_DATA)(pImage + pImpDesc->FirstThunk);
+ pINT = (PIMAGE_THUNK_DATA)(pImage + pImpDesc->OriginalFirstThunk);
+ for (; pIAT->u1.Function; ++pIAT, ++pINT) {
+ if (IMAGE_SNAP_BY_ORDINAL(pINT->u1.Ordinal))
+ continue;
+ pImpName = (PIMAGE_IMPORT_BY_NAME)(pImage
+ + (UINT_PTR)(pINT->u1.AddressOfData));
+ if (strcmp(pImpName->Name, funcname) == 0)
+ return (void *)pIAT->u1.Function;
+ }
+ }
+ return NULL;
+}
+
+/*
+ * Try opening the iconv.dll and return TRUE if iconv() can be used.
+ */
+int iconv_enabled(verbose)
+int verbose;
+{
+ if (hIconvDLL != 0 && hMsvcrtDLL != 0)
+ return TRUE;
+ hIconvDLL = vimLoadLib(DYNAMIC_ICONV_DLL);
+ if (hIconvDLL == 0) /* sometimes it's called libiconv.dll */
+ hIconvDLL = vimLoadLib(DYNAMIC_ICONV_DLL_ALT);
+ if (hIconvDLL != 0)
+ hMsvcrtDLL = vimLoadLib(DYNAMIC_MSVCRT_DLL);
+ if (hIconvDLL == 0 || hMsvcrtDLL == 0) {
+ /* Only give the message when 'verbose' is set, otherwise it might be
+ * done whenever a conversion is attempted. */
+ if (verbose && p_verbose > 0) {
+ verbose_enter();
+ EMSG2(_(e_loadlib),
+ hIconvDLL == 0 ? DYNAMIC_ICONV_DLL : DYNAMIC_MSVCRT_DLL);
+ verbose_leave();
+ }
+ iconv_end();
+ return FALSE;
+ }
+
+ iconv = (void *)GetProcAddress(hIconvDLL, "libiconv");
+ iconv_open = (void *)GetProcAddress(hIconvDLL, "libiconv_open");
+ iconv_close = (void *)GetProcAddress(hIconvDLL, "libiconv_close");
+ iconvctl = (void *)GetProcAddress(hIconvDLL, "libiconvctl");
+ iconv_errno = get_iconv_import_func(hIconvDLL, "_errno");
+ if (iconv_errno == NULL)
+ iconv_errno = (void *)GetProcAddress(hMsvcrtDLL, "_errno");
+ if (iconv == NULL || iconv_open == NULL || iconv_close == NULL
+ || iconvctl == NULL || iconv_errno == NULL) {
+ iconv_end();
+ if (verbose && p_verbose > 0) {
+ verbose_enter();
+ EMSG2(_(e_loadfunc), "for libiconv");
+ verbose_leave();
+ }
+ return FALSE;
+ }
+ return TRUE;
+}
+
+void iconv_end() {
+ /* Don't use iconv() when inputting or outputting characters. */
+ if (input_conv.vc_type == CONV_ICONV)
+ convert_setup(&input_conv, NULL, NULL);
+ if (output_conv.vc_type == CONV_ICONV)
+ convert_setup(&output_conv, NULL, NULL);
+
+ if (hIconvDLL != 0)
+ FreeLibrary(hIconvDLL);
+ if (hMsvcrtDLL != 0)
+ FreeLibrary(hMsvcrtDLL);
+ hIconvDLL = 0;
+ hMsvcrtDLL = 0;
+}
+
+# endif /* DYNAMIC_ICONV */
+# endif /* USE_ICONV */
+
+
+
+
+/*
+ * Setup "vcp" for conversion from "from" to "to".
+ * The names must have been made canonical with enc_canonize().
+ * vcp->vc_type must have been initialized to CONV_NONE.
+ * Note: cannot be used for conversion from/to ucs-2 and ucs-4 (will use utf-8
+ * instead).
+ * Afterwards invoke with "from" and "to" equal to NULL to cleanup.
+ * Return FAIL when conversion is not supported, OK otherwise.
+ */
+int convert_setup(vcp, from, to)
+vimconv_T *vcp;
+char_u *from;
+char_u *to;
+{
+ return convert_setup_ext(vcp, from, TRUE, to, TRUE);
+}
+
+/*
+ * As convert_setup(), but only when from_unicode_is_utf8 is TRUE will all
+ * "from" unicode charsets be considered utf-8. Same for "to".
+ */
+int convert_setup_ext(vcp, from, from_unicode_is_utf8, to, to_unicode_is_utf8)
+vimconv_T *vcp;
+char_u *from;
+int from_unicode_is_utf8;
+char_u *to;
+int to_unicode_is_utf8;
+{
+ int from_prop;
+ int to_prop;
+ int from_is_utf8;
+ int to_is_utf8;
+
+ /* Reset to no conversion. */
+# ifdef USE_ICONV
+ 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;
+
+ /* No conversion when one of the names is empty or they are equal. */
+ if (from == NULL || *from == NUL || to == NULL || *to == NUL
+ || STRCMP(from, to) == 0)
+ return OK;
+
+ from_prop = enc_canon_props(from);
+ to_prop = enc_canon_props(to);
+ if (from_unicode_is_utf8)
+ from_is_utf8 = from_prop & ENC_UNICODE;
+ else
+ from_is_utf8 = from_prop == ENC_UNICODE;
+ if (to_unicode_is_utf8)
+ to_is_utf8 = to_prop & ENC_UNICODE;
+ else
+ to_is_utf8 = to_prop == ENC_UNICODE;
+
+ if ((from_prop & ENC_LATIN1) && to_is_utf8) {
+ /* Internal latin1 -> utf-8 conversion. */
+ vcp->vc_type = CONV_TO_UTF8;
+ vcp->vc_factor = 2; /* up to twice as long */
+ } else if ((from_prop & ENC_LATIN9) && to_is_utf8) {
+ /* Internal latin9 -> utf-8 conversion. */
+ vcp->vc_type = CONV_9_TO_UTF8;
+ vcp->vc_factor = 3; /* up to three as long (euro sign) */
+ } else if (from_is_utf8 && (to_prop & ENC_LATIN1)) {
+ /* Internal utf-8 -> latin1 conversion. */
+ vcp->vc_type = CONV_TO_LATIN1;
+ } else if (from_is_utf8 && (to_prop & ENC_LATIN9)) {
+ /* Internal utf-8 -> latin9 conversion. */
+ vcp->vc_type = CONV_TO_LATIN9;
+ }
+# ifdef USE_ICONV
+ else {
+ /* Use iconv() for conversion. */
+ vcp->vc_fd = (iconv_t)my_iconv_open(
+ to_is_utf8 ? (char_u *)"utf-8" : to,
+ from_is_utf8 ? (char_u *)"utf-8" : from);
+ if (vcp->vc_fd != (iconv_t)-1) {
+ vcp->vc_type = CONV_ICONV;
+ vcp->vc_factor = 4; /* could be longer too... */
+ }
+ }
+# endif
+ if (vcp->vc_type == CONV_NONE)
+ return FAIL;
+
+ return OK;
+}
+
+#if defined(FEAT_GUI) || defined(AMIGA) || defined(WIN3264) \
+ || defined(MSDOS) || defined(PROTO)
+/*
+ * Do conversion on typed input characters in-place.
+ * The input and output are not NUL terminated!
+ * Returns the length after conversion.
+ */
+int convert_input(ptr, len, maxlen)
+char_u *ptr;
+int len;
+int maxlen;
+{
+ return convert_input_safe(ptr, len, maxlen, NULL, NULL);
+}
+#endif
+
+/*
+ * Like convert_input(), but when there is an incomplete byte sequence at the
+ * end return that as an allocated string in "restp" and set "*restlenp" to
+ * the length. If "restp" is NULL it is not used.
+ */
+int convert_input_safe(ptr, len, maxlen, restp, restlenp)
+char_u *ptr;
+int len;
+int maxlen;
+char_u **restp;
+int *restlenp;
+{
+ char_u *d;
+ int dlen = len;
+ int unconvertlen = 0;
+
+ d = string_convert_ext(&input_conv, ptr, &dlen,
+ restp == NULL ? NULL : &unconvertlen);
+ if (d != NULL) {
+ if (dlen <= maxlen) {
+ if (unconvertlen > 0) {
+ /* Move the unconverted characters to allocated memory. */
+ *restp = alloc(unconvertlen);
+ if (*restp != NULL)
+ mch_memmove(*restp, ptr + len - unconvertlen, unconvertlen);
+ *restlenp = unconvertlen;
+ }
+ mch_memmove(ptr, d, dlen);
+ } else
+ /* result is too long, keep the unconverted text (the caller must
+ * have done something wrong!) */
+ dlen = len;
+ vim_free(d);
+ }
+ return dlen;
+}
+
+/*
+ * Convert text "ptr[*lenp]" according to "vcp".
+ * Returns the result in allocated memory and sets "*lenp".
+ * When "lenp" is NULL, use NUL terminated strings.
+ * 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(vcp, ptr, lenp)
+vimconv_T *vcp;
+char_u *ptr;
+int *lenp;
+{
+ return string_convert_ext(vcp, ptr, lenp, NULL);
+}
+
+/*
+ * Like string_convert(), but when "unconvlenp" is not NULL and there are is
+ * 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(vcp, ptr, lenp, unconvlenp)
+vimconv_T *vcp;
+char_u *ptr;
+int *lenp;
+int *unconvlenp;
+{
+ char_u *retval = NULL;
+ char_u *d;
+ int len;
+ int i;
+ int l;
+ int c;
+
+ if (lenp == NULL)
+ len = (int)STRLEN(ptr);
+ else
+ len = *lenp;
+ if (len == 0)
+ return vim_strsave((char_u *)"");
+
+ switch (vcp->vc_type) {
+ case CONV_TO_UTF8: /* latin1 to utf-8 conversion */
+ retval = alloc(len * 2 + 1);
+ if (retval == NULL)
+ break;
+ d = retval;
+ for (i = 0; i < len; ++i) {
+ c = ptr[i];
+ if (c < 0x80)
+ *d++ = c;
+ else {
+ *d++ = 0xc0 + ((unsigned)c >> 6);
+ *d++ = 0x80 + (c & 0x3f);
+ }
+ }
+ *d = NUL;
+ if (lenp != NULL)
+ *lenp = (int)(d - retval);
+ break;
+
+ case CONV_9_TO_UTF8: /* latin9 to utf-8 conversion */
+ retval = alloc(len * 3 + 1);
+ if (retval == NULL)
+ break;
+ d = retval;
+ for (i = 0; i < len; ++i) {
+ c = ptr[i];
+ switch (c) {
+ case 0xa4: c = 0x20ac; break; /* euro */
+ case 0xa6: c = 0x0160; break; /* S hat */
+ case 0xa8: c = 0x0161; break; /* S -hat */
+ case 0xb4: c = 0x017d; break; /* Z hat */
+ case 0xb8: c = 0x017e; break; /* Z -hat */
+ case 0xbc: c = 0x0152; break; /* OE */
+ case 0xbd: c = 0x0153; break; /* oe */
+ case 0xbe: c = 0x0178; break; /* Y */
+ }
+ d += utf_char2bytes(c, d);
+ }
+ *d = NUL;
+ if (lenp != NULL)
+ *lenp = (int)(d - retval);
+ break;
+
+ case CONV_TO_LATIN1: /* utf-8 to latin1 conversion */
+ case CONV_TO_LATIN9: /* utf-8 to latin9 conversion */
+ retval = alloc(len + 1);
+ if (retval == NULL)
+ break;
+ d = retval;
+ for (i = 0; i < len; ++i) {
+ l = utf_ptr2len_len(ptr + i, len - i);
+ if (l == 0)
+ *d++ = NUL;
+ else if (l == 1) {
+ int l_w = utf8len_tab_zero[ptr[i]];
+
+ if (l_w == 0) {
+ /* Illegal utf-8 byte cannot be converted */
+ vim_free(retval);
+ return NULL;
+ }
+ if (unconvlenp != NULL && l_w > len - i) {
+ /* Incomplete sequence at the end. */
+ *unconvlenp = len - i;
+ break;
+ }
+ *d++ = ptr[i];
+ } else {
+ c = utf_ptr2char(ptr + i);
+ if (vcp->vc_type == CONV_TO_LATIN9)
+ switch (c) {
+ case 0x20ac: c = 0xa4; break; /* euro */
+ case 0x0160: c = 0xa6; break; /* S hat */
+ case 0x0161: c = 0xa8; break; /* S -hat */
+ case 0x017d: c = 0xb4; break; /* Z hat */
+ case 0x017e: c = 0xb8; break; /* Z -hat */
+ case 0x0152: c = 0xbc; break; /* OE */
+ case 0x0153: c = 0xbd; break; /* oe */
+ case 0x0178: c = 0xbe; break; /* Y */
+ case 0xa4:
+ case 0xa6:
+ case 0xa8:
+ case 0xb4:
+ case 0xb8:
+ case 0xbc:
+ case 0xbd:
+ case 0xbe: c = 0x100; break; /* not in latin9 */
+ }
+ if (!utf_iscomposing(c)) { /* skip composing chars */
+ if (c < 0x100)
+ *d++ = c;
+ else if (vcp->vc_fail) {
+ vim_free(retval);
+ return NULL;
+ } else {
+ *d++ = 0xbf;
+ if (utf_char2cells(c) > 1)
+ *d++ = '?';
+ }
+ }
+ i += l - 1;
+ }
+ }
+ *d = NUL;
+ if (lenp != NULL)
+ *lenp = (int)(d - retval);
+ break;
+
+# ifdef MACOS_CONVERT
+ case CONV_MAC_LATIN1:
+ retval = mac_string_convert(ptr, len, lenp, vcp->vc_fail,
+ 'm', 'l', unconvlenp);
+ break;
+
+ case CONV_LATIN1_MAC:
+ retval = mac_string_convert(ptr, len, lenp, vcp->vc_fail,
+ 'l', 'm', unconvlenp);
+ break;
+
+ case CONV_MAC_UTF8:
+ retval = mac_string_convert(ptr, len, lenp, vcp->vc_fail,
+ 'm', 'u', unconvlenp);
+ break;
+
+ case CONV_UTF8_MAC:
+ retval = mac_string_convert(ptr, len, lenp, vcp->vc_fail,
+ 'u', 'm', unconvlenp);
+ break;
+# endif
+
+# ifdef USE_ICONV
+ case CONV_ICONV: /* conversion with output_conv.vc_fd */
+ retval = iconv_string(vcp, ptr, len, unconvlenp, lenp);
+ break;
+# endif
+ }
+
+ return retval;
+}
diff --git a/src/memfile.c b/src/memfile.c
new file mode 100644
index 0000000000..2969a19795
--- /dev/null
+++ b/src/memfile.c
@@ -0,0 +1,1366 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * 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.c: Contains the functions for handling blocks of memory which can
+ * be stored in a file. This is the implementation of a sort of virtual memory.
+ *
+ * A memfile consists of a sequence of blocks. The blocks numbered from 0
+ * upwards have been assigned a place in the actual file. The block number
+ * is equal to the page number in the file. The
+ * blocks with negative numbers are currently in memory only. They can be
+ * assigned a place in the file when too much memory is being used. At that
+ * moment they get a new, positive, number. A list is used for translation of
+ * negative to positive numbers.
+ *
+ * The size of a block is a multiple of a page size, normally the page size of
+ * the device the file is on. Most blocks are 1 page long. A Block of multiple
+ * pages is used for a line that does not fit in a single page.
+ *
+ * Each block can be in memory and/or in a file. The block stays in memory
+ * as long as it is locked. If it is no longer locked it can be swapped out to
+ * the file. It is only written to the file if it has been changed.
+ *
+ * Under normal operation the file is created when opening the memory file and
+ * deleted when closing the memory file. Only with recovery an existing memory
+ * file is opened.
+ */
+
+#include "vim.h"
+
+/*
+ * Some systems have the page size in statfs.f_bsize, some in stat.st_blksize
+ */
+#ifdef HAVE_ST_BLKSIZE
+# define STATFS stat
+# define F_BSIZE st_blksize
+# define fstatfs(fd, buf, len, nul) mch_fstat((fd), (buf))
+#else
+# ifdef HAVE_SYS_STATFS_H
+# include <sys/statfs.h>
+# define STATFS statfs
+# define F_BSIZE f_bsize
+# endif
+#endif
+
+/*
+ * for Amiga Dos 2.0x we use Flush
+ */
+
+#define MEMFILE_PAGE_SIZE 4096 /* default page size */
+
+static long_u total_mem_used = 0; /* total memory used for memfiles */
+
+static void mf_ins_hash __ARGS((memfile_T *, bhdr_T *));
+static void mf_rem_hash __ARGS((memfile_T *, bhdr_T *));
+static bhdr_T *mf_find_hash __ARGS((memfile_T *, blocknr_T));
+static void mf_ins_used __ARGS((memfile_T *, bhdr_T *));
+static void mf_rem_used __ARGS((memfile_T *, bhdr_T *));
+static bhdr_T *mf_release __ARGS((memfile_T *, int));
+static bhdr_T *mf_alloc_bhdr __ARGS((memfile_T *, int));
+static void mf_free_bhdr __ARGS((bhdr_T *));
+static void mf_ins_free __ARGS((memfile_T *, bhdr_T *));
+static bhdr_T *mf_rem_free __ARGS((memfile_T *));
+static int mf_read __ARGS((memfile_T *, bhdr_T *));
+static int mf_write __ARGS((memfile_T *, bhdr_T *));
+static int mf_write_block __ARGS((memfile_T *mfp, bhdr_T *hp, off_t offset,
+ unsigned size));
+static int mf_trans_add __ARGS((memfile_T *, bhdr_T *));
+static void mf_do_open __ARGS((memfile_T *, char_u *, int));
+static void mf_hash_init __ARGS((mf_hashtab_T *));
+static void mf_hash_free __ARGS((mf_hashtab_T *));
+static void mf_hash_free_all __ARGS((mf_hashtab_T *));
+static mf_hashitem_T *mf_hash_find __ARGS((mf_hashtab_T *, blocknr_T));
+static void mf_hash_add_item __ARGS((mf_hashtab_T *, mf_hashitem_T *));
+static void mf_hash_rem_item __ARGS((mf_hashtab_T *, mf_hashitem_T *));
+static int mf_hash_grow __ARGS((mf_hashtab_T *));
+
+/*
+ * The functions for using a memfile:
+ *
+ * mf_open() open a new or existing memfile
+ * mf_open_file() open a swap file for an existing memfile
+ * mf_close() close (and delete) a memfile
+ * mf_new() create a new block in a memfile and lock it
+ * mf_get() get an existing block and lock it
+ * mf_put() unlock a block, may be marked for writing
+ * mf_free() remove a block
+ * mf_sync() sync changed parts of memfile to disk
+ * mf_release_all() release as much memory as possible
+ * mf_trans_del() may translate negative to positive block number
+ * mf_fullname() make file name full path (use before first :cd)
+ */
+
+/*
+ * Open an existing or new memory block file.
+ *
+ * fname: name of file to use (NULL means no file at all)
+ * Note: fname must have been allocated, it is not copied!
+ * If opening the file fails, fname is freed.
+ * flags: flags for open() call
+ *
+ * If fname != NULL and file cannot be opened, fail.
+ *
+ * return value: identifier for this memory block file.
+ */
+memfile_T * mf_open(fname, flags)
+char_u *fname;
+int flags;
+{
+ memfile_T *mfp;
+ off_t size;
+#if defined(STATFS) && defined(UNIX) && !defined(__QNX__) && !defined(__minix)
+# define USE_FSTATFS
+ struct STATFS stf;
+#endif
+
+ if ((mfp = (memfile_T *)alloc((unsigned)sizeof(memfile_T))) == NULL)
+ return NULL;
+
+ if (fname == NULL) { /* no file for this memfile, use memory only */
+ mfp->mf_fname = NULL;
+ mfp->mf_ffname = NULL;
+ mfp->mf_fd = -1;
+ } else {
+ mf_do_open(mfp, fname, flags); /* try to open the file */
+
+ /* if the file cannot be opened, return here */
+ if (mfp->mf_fd < 0) {
+ vim_free(mfp);
+ return NULL;
+ }
+ }
+
+ mfp->mf_free_first = NULL; /* free list is empty */
+ 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;
+ mfp->mf_old_key = NULL;
+
+#ifdef USE_FSTATFS
+ /*
+ * Try to set the page size equal to the block size of the device.
+ * Speeds up I/O a lot.
+ * 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
+ && fstatfs(mfp->mf_fd, &stf, sizeof(struct statfs), 0) == 0
+ && stf.F_BSIZE >= MIN_SWAP_PAGE_SIZE
+ && stf.F_BSIZE <= MAX_SWAP_PAGE_SIZE)
+ mfp->mf_page_size = stf.F_BSIZE;
+#endif
+
+ if (mfp->mf_fd < 0 || (flags & (O_TRUNC|O_EXCL))
+ || (size = 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 = (blocknr_T)((size + mfp->mf_page_size - 1)
+ / mfp->mf_page_size);
+ mfp->mf_blocknr_min = -1;
+ mfp->mf_neg_count = 0;
+ mfp->mf_infile_count = mfp->mf_blocknr_max;
+
+ /*
+ * Compute maximum number of pages ('maxmem' is in Kbyte):
+ * '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 = page_size >> 1;
+ --shift;
+ }
+ mfp->mf_used_count_max = (p_mm << shift) / page_size;
+ if (mfp->mf_used_count_max < 10)
+ mfp->mf_used_count_max = 10;
+ }
+
+ return mfp;
+}
+
+/*
+ * Open a file for an existing memfile. Used when updatecount set from 0 to
+ * some value.
+ * If the file already exists, this fails.
+ * "fname" is the name of file to use (NULL means no file at all)
+ * Note: "fname" must have been allocated, it is not copied! If opening the
+ * file fails, "fname" is freed.
+ *
+ * return value: FAIL if file could not be opened, OK otherwise
+ */
+int mf_open_file(mfp, fname)
+memfile_T *mfp;
+char_u *fname;
+{
+ mf_do_open(mfp, fname, O_RDWR|O_CREAT|O_EXCL); /* try to open the file */
+
+ if (mfp->mf_fd < 0)
+ return FAIL;
+
+ mfp->mf_dirty = TRUE;
+ return OK;
+}
+
+/*
+ * Close a memory file and delete the associated file if 'del_file' is TRUE.
+ */
+void mf_close(mfp, del_file)
+memfile_T *mfp;
+int del_file;
+{
+ bhdr_T *hp, *nextp;
+
+ if (mfp == NULL) /* safety check */
+ return;
+ if (mfp->mf_fd >= 0) {
+ if (close(mfp->mf_fd) < 0)
+ EMSG(_(e_swapclose));
+ }
+ if (del_file && mfp->mf_fname != NULL)
+ mch_remove(mfp->mf_fname);
+ /* free entries in used list */
+ for (hp = mfp->mf_used_first; hp != NULL; hp = nextp) {
+ total_mem_used -= hp->bh_page_count * mfp->mf_page_size;
+ nextp = hp->bh_next;
+ mf_free_bhdr(hp);
+ }
+ while (mfp->mf_free_first != NULL) /* free entries in free list */
+ vim_free(mf_rem_free(mfp));
+ mf_hash_free(&mfp->mf_hash);
+ mf_hash_free_all(&mfp->mf_trans); /* free hashtable and its items */
+ vim_free(mfp->mf_fname);
+ vim_free(mfp->mf_ffname);
+ vim_free(mfp);
+}
+
+/*
+ * Close the swap file for a memfile. Used when 'swapfile' is reset.
+ */
+void mf_close_file(buf, getlines)
+buf_T *buf;
+int getlines; /* get all lines into memory? */
+{
+ memfile_T *mfp;
+ linenr_T lnum;
+
+ mfp = buf->b_ml.ml_mfp;
+ if (mfp == NULL || mfp->mf_fd < 0) /* nothing to close */
+ return;
+
+ if (getlines) {
+ /* get all blocks in memory by accessing all lines (clumsy!) */
+ mf_dont_release = TRUE;
+ for (lnum = 1; lnum <= buf->b_ml.ml_line_count; ++lnum)
+ (void)ml_get_buf(buf, lnum, FALSE);
+ mf_dont_release = FALSE;
+ /* TODO: should check if all blocks are really in core */
+ }
+
+ if (close(mfp->mf_fd) < 0) /* close the file */
+ EMSG(_(e_swapclose));
+ mfp->mf_fd = -1;
+
+ if (mfp->mf_fname != NULL) {
+ mch_remove(mfp->mf_fname); /* delete the swap file */
+ vim_free(mfp->mf_fname);
+ vim_free(mfp->mf_ffname);
+ mfp->mf_fname = NULL;
+ mfp->mf_ffname = NULL;
+ }
+}
+
+/*
+ * Set new size for a memfile. Used when block 0 of a swapfile has been read
+ * and the size it indicates differs from what was guessed.
+ */
+void mf_new_page_size(mfp, new_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. */
+ total_mem_used += new_size - mfp->mf_page_size;
+ mfp->mf_page_size = new_size;
+}
+
+/*
+ * get a new block
+ *
+ * negative: TRUE if negative block number desired (data block)
+ */
+bhdr_T * mf_new(mfp, negative, page_count)
+memfile_T *mfp;
+int negative;
+int page_count;
+{
+ bhdr_T *hp; /* new bhdr_T */
+ bhdr_T *freep; /* first block in free list */
+ char_u *p;
+
+ /*
+ * 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.
+ */
+ hp = mf_release(mfp, page_count);
+
+ /*
+ * Decide on the number to use:
+ * If there is a free block, use its number.
+ * Otherwise use mf_block_min for a negative number, mf_block_max for
+ * a positive number.
+ */
+ freep = mfp->mf_free_first;
+ 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)) == NULL)
+ return NULL;
+ 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 */
+ if ((p = (char_u *)alloc(mfp->mf_page_size * page_count)) == NULL)
+ return NULL;
+ 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;
+ vim_free(freep);
+ }
+ } else { /* get a new number */
+ if (hp == NULL && (hp = mf_alloc_bhdr(mfp, page_count)) == NULL)
+ return NULL;
+ if (negative) {
+ hp->bh_bnum = mfp->mf_blocknr_min--;
+ mfp->mf_neg_count++;
+ } else {
+ hp->bh_bnum = mfp->mf_blocknr_max;
+ mfp->mf_blocknr_max += page_count;
+ }
+ }
+ hp->bh_flags = BH_LOCKED | BH_DIRTY; /* new block is always dirty */
+ mfp->mf_dirty = TRUE;
+ hp->bh_page_count = page_count;
+ mf_ins_used(mfp, hp);
+ mf_ins_hash(mfp, hp);
+
+ /*
+ * Init the data to all zero, to avoid reading uninitialized data.
+ * This also avoids that the passwd file ends up in the swap file!
+ */
+ (void)vim_memset((char *)(hp->bh_data), 0,
+ (size_t)mfp->mf_page_size * page_count);
+
+ return hp;
+}
+
+/*
+ * Get existing block "nr" with "page_count" pages.
+ *
+ * Note: The caller should first check a negative nr with mf_trans_del()
+ */
+bhdr_T * mf_get(mfp, nr, page_count)
+memfile_T *mfp;
+blocknr_T nr;
+int page_count;
+{
+ bhdr_T *hp;
+ /* doesn't exist */
+ if (nr >= mfp->mf_blocknr_max || nr <= mfp->mf_blocknr_min)
+ return NULL;
+
+ /*
+ * see if it is in the cache
+ */
+ hp = mf_find_hash(mfp, nr);
+ if (hp == NULL) { /* not in the hash list */
+ if (nr < 0 || nr >= mfp->mf_infile_count) /* can't be in the file */
+ return NULL;
+
+ /* 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)) == NULL)
+ return NULL;
+
+ hp->bh_bnum = nr;
+ hp->bh_flags = 0;
+ hp->bh_page_count = page_count;
+ if (mf_read(mfp, hp) == FAIL) { /* cannot read the block! */
+ mf_free_bhdr(hp);
+ return NULL;
+ }
+ } else {
+ mf_rem_used(mfp, hp); /* remove from list, insert in front below */
+ mf_rem_hash(mfp, hp);
+ }
+
+ hp->bh_flags |= BH_LOCKED;
+ mf_ins_used(mfp, hp); /* put in front of used list */
+ mf_ins_hash(mfp, hp); /* put in front of hash list */
+
+ return hp;
+}
+
+/*
+ * release the block *hp
+ *
+ * dirty: Block must be written to file later
+ * infile: Block should be in file (needed for recovery)
+ *
+ * no return value, function cannot fail
+ */
+void mf_put(mfp, hp, dirty, infile)
+memfile_T *mfp;
+bhdr_T *hp;
+int dirty;
+int infile;
+{
+ int flags;
+
+ flags = hp->bh_flags;
+
+ if ((flags & BH_LOCKED) == 0)
+ EMSG(_("E293: block was not locked"));
+ flags &= ~BH_LOCKED;
+ if (dirty) {
+ flags |= BH_DIRTY;
+ mfp->mf_dirty = TRUE;
+ }
+ hp->bh_flags = flags;
+ if (infile)
+ mf_trans_add(mfp, hp); /* may translate negative in positive nr */
+}
+
+/*
+ * block *hp is no longer in used, may put it in the free list of memfile *mfp
+ */
+void mf_free(mfp, hp)
+memfile_T *mfp;
+bhdr_T *hp;
+{
+ vim_free(hp->bh_data); /* free the memory */
+ mf_rem_hash(mfp, hp); /* get *hp out of the hash list */
+ mf_rem_used(mfp, hp); /* get *hp out of the used list */
+ if (hp->bh_bnum < 0) {
+ vim_free(hp); /* don't want negative numbers in free list */
+ mfp->mf_neg_count--;
+ } else
+ mf_ins_free(mfp, hp); /* put *hp in the free list */
+}
+
+#if defined(__MORPHOS__) && defined(__libnix__)
+/* function is missing in MorphOS libnix version */
+extern unsigned long *__stdfiledes;
+
+static unsigned long fdtofh(int filedescriptor) {
+ return __stdfiledes[filedescriptor];
+}
+
+#endif
+
+/*
+ * Sync the memory file *mfp to disk.
+ * Flags:
+ * MFS_ALL If not given, blocks with negative numbers are not synced,
+ * even when they are dirty!
+ * MFS_STOP Stop syncing when a character becomes available, but sync at
+ * least one block.
+ * MFS_FLUSH Make sure buffers are flushed to disk, so they will survive a
+ * system crash.
+ * MFS_ZERO Only write block 0.
+ *
+ * Return FAIL for failure, OK otherwise
+ */
+int mf_sync(mfp, flags)
+memfile_T *mfp;
+int flags;
+{
+ int status;
+ bhdr_T *hp;
+#if defined(SYNC_DUP_CLOSE) && !defined(MSDOS)
+ int fd;
+#endif
+ int got_int_save = got_int;
+
+ if (mfp->mf_fd < 0) { /* there is no file, nothing to do */
+ mfp->mf_dirty = FALSE;
+ return FAIL;
+ }
+
+ /* Only a CTRL-C while writing will break us here, not one typed
+ * previously. */
+ got_int = FALSE;
+
+ /*
+ * sync from last to first (may reduce the probability of an inconsistent
+ * file) If a write fails, it is very likely caused by a full filesystem.
+ * Then we only try to write blocks within the existing file. If that also
+ * fails then we give up.
+ */
+ status = OK;
+ for (hp = mfp->mf_used_last; hp != NULL; hp = hp->bh_prev)
+ if (((flags & MFS_ALL) || hp->bh_bnum >= 0)
+ && (hp->bh_flags & BH_DIRTY)
+ && (status == OK || (hp->bh_bnum >= 0
+ && hp->bh_bnum < mfp->mf_infile_count))) {
+ if ((flags & MFS_ZERO) && hp->bh_bnum != 0)
+ continue;
+ if (mf_write(mfp, hp) == FAIL) {
+ if (status == FAIL) /* double error: quit syncing */
+ break;
+ status = FAIL;
+ }
+ if (flags & MFS_STOP) {
+ /* Stop when char available now. */
+ if (ui_char_avail())
+ break;
+ } else
+ ui_breakcheck();
+ if (got_int)
+ break;
+ }
+
+ /*
+ * If the whole list is flushed, the memfile is not dirty anymore.
+ * In case of an error this flag is also set, to avoid trying all the time.
+ */
+ if (hp == NULL || status == FAIL)
+ mfp->mf_dirty = FALSE;
+
+ if ((flags & MFS_FLUSH) && *p_sws != NUL) {
+#if defined(UNIX)
+# ifdef HAVE_FSYNC
+ /*
+ * most Unixes have the very useful fsync() function, just what we need.
+ * However, with OS/2 and EMX it is also available, but there are
+ * reports of bad problems with it (a bug in HPFS.IFS).
+ * So we disable use of it here in case someone tries to be smart
+ * and changes os_os2_cfg.h... (even though there is no __EMX__ test
+ * in the #if, as __EMX__ does not have sync(); we hope for a timely
+ * sync from the system itself).
+ */
+ if (STRCMP(p_sws, "fsync") == 0) {
+ if (fsync(mfp->mf_fd))
+ status = FAIL;
+ } else
+# endif
+ /* OpenNT is strictly POSIX (Benzinger) */
+ /* Tandem/Himalaya NSK-OSS doesn't have sync() */
+# if defined(__OPENNT) || defined(__TANDEM)
+ fflush(NULL);
+# else
+ sync();
+# endif
+#endif
+# ifdef SYNC_DUP_CLOSE
+ /*
+ * Win32 is a bit more work: Duplicate the file handle and close it.
+ * This should flush the file to disk.
+ */
+ if ((fd = dup(mfp->mf_fd)) >= 0)
+ close(fd);
+# endif
+ }
+
+ got_int |= got_int_save;
+
+ return status;
+}
+
+/*
+ * For all blocks in memory file *mfp that have a positive block number set
+ * the dirty flag. These are blocks that need to be written to a newly
+ * created swapfile.
+ */
+void mf_set_dirty(mfp)
+memfile_T *mfp;
+{
+ bhdr_T *hp;
+
+ for (hp = mfp->mf_used_last; hp != NULL; hp = hp->bh_prev)
+ if (hp->bh_bnum > 0)
+ hp->bh_flags |= BH_DIRTY;
+ mfp->mf_dirty = TRUE;
+}
+
+/*
+ * insert block *hp in front of hashlist of memfile *mfp
+ */
+static void mf_ins_hash(mfp, hp)
+memfile_T *mfp;
+bhdr_T *hp;
+{
+ mf_hash_add_item(&mfp->mf_hash, (mf_hashitem_T *)hp);
+}
+
+/*
+ * remove block *hp from hashlist of memfile list *mfp
+ */
+static void mf_rem_hash(mfp, hp)
+memfile_T *mfp;
+bhdr_T *hp;
+{
+ mf_hash_rem_item(&mfp->mf_hash, (mf_hashitem_T *)hp);
+}
+
+/*
+ * look in hash lists of memfile *mfp for block header with number 'nr'
+ */
+static bhdr_T * mf_find_hash(mfp, nr)
+memfile_T *mfp;
+blocknr_T nr;
+{
+ return (bhdr_T *)mf_hash_find(&mfp->mf_hash, nr);
+}
+
+/*
+ * insert block *hp in front of used list of memfile *mfp
+ */
+static void mf_ins_used(mfp, hp)
+memfile_T *mfp;
+bhdr_T *hp;
+{
+ hp->bh_next = mfp->mf_used_first;
+ mfp->mf_used_first = hp;
+ hp->bh_prev = NULL;
+ if (hp->bh_next == NULL) /* list was empty, adjust last pointer */
+ mfp->mf_used_last = 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 *hp from used list of memfile *mfp
+ */
+static void mf_rem_used(mfp, hp)
+memfile_T *mfp;
+bhdr_T *hp;
+{
+ if (hp->bh_next == NULL) /* last block in used list */
+ mfp->mf_used_last = hp->bh_prev;
+ else
+ hp->bh_next->bh_prev = hp->bh_prev;
+ if (hp->bh_prev == NULL) /* first block in used list */
+ 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;
+}
+
+/*
+ * Release the least recently used block from the used list if the number
+ * of used memory blocks gets to big.
+ *
+ * Return the block header to the caller, including the memory block, so
+ * it can be re-used. Make sure the page_count is right.
+ */
+static bhdr_T * mf_release(mfp, page_count)
+memfile_T *mfp;
+int page_count;
+{
+ bhdr_T *hp;
+ int need_release;
+ buf_T *buf;
+
+ /* 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 or total memory used is over 'maxmemtot'
+ */
+ need_release = ((mfp->mf_used_count >= mfp->mf_used_count_max)
+ || (total_mem_used >> 10) >= (long_u)p_mmt);
+
+ /*
+ * Try to create a 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 */
+ for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+ if (buf->b_ml.ml_mfp == mfp)
+ 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;
+
+ 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);
+
+ /*
+ * If a bhdr_T is returned, make sure that the page_count of bh_data is
+ * right
+ */
+ if (hp->bh_page_count != page_count) {
+ vim_free(hp->bh_data);
+ if ((hp->bh_data = alloc(mfp->mf_page_size * page_count)) == NULL) {
+ vim_free(hp);
+ return NULL;
+ }
+ hp->bh_page_count = page_count;
+ }
+ return hp;
+}
+
+/*
+ * release as many blocks as possible
+ * Used in case of out of memory
+ *
+ * return TRUE if any memory was released
+ */
+int mf_release_all() {
+ buf_T *buf;
+ memfile_T *mfp;
+ bhdr_T *hp;
+ int retval = FALSE;
+
+ for (buf = firstbuf; buf != NULL; buf = buf->b_next) {
+ mfp = buf->b_ml.ml_mfp;
+ if (mfp != NULL) {
+ /* If no swap file yet, may open one */
+ if (mfp->mf_fd < 0 && buf->b_may_swap)
+ ml_open_file(buf);
+
+ /* only if there is a swapfile */
+ if (mfp->mf_fd >= 0) {
+ for (hp = mfp->mf_used_last; hp != NULL; ) {
+ if (!(hp->bh_flags & BH_LOCKED)
+ && (!(hp->bh_flags & BH_DIRTY)
+ || mf_write(mfp, hp) != FAIL)) {
+ mf_rem_used(mfp, hp);
+ mf_rem_hash(mfp, hp);
+ mf_free_bhdr(hp);
+ hp = mfp->mf_used_last; /* re-start, list was changed */
+ retval = TRUE;
+ } else
+ hp = hp->bh_prev;
+ }
+ }
+ }
+ }
+ return retval;
+}
+
+/*
+ * Allocate a block header and a block of memory for it
+ */
+static bhdr_T * mf_alloc_bhdr(mfp, page_count)
+memfile_T *mfp;
+int page_count;
+{
+ bhdr_T *hp;
+
+ if ((hp = (bhdr_T *)alloc((unsigned)sizeof(bhdr_T))) != NULL) {
+ if ((hp->bh_data = (char_u *)alloc(mfp->mf_page_size * page_count))
+ == NULL) {
+ vim_free(hp); /* not enough memory */
+ return NULL;
+ }
+ hp->bh_page_count = page_count;
+ }
+ return hp;
+}
+
+/*
+ * Free a block header and the block of memory for it
+ */
+static void mf_free_bhdr(hp)
+bhdr_T *hp;
+{
+ vim_free(hp->bh_data);
+ vim_free(hp);
+}
+
+/*
+ * insert entry *hp in the free list
+ */
+static void mf_ins_free(mfp, hp)
+memfile_T *mfp;
+bhdr_T *hp;
+{
+ hp->bh_next = mfp->mf_free_first;
+ mfp->mf_free_first = hp;
+}
+
+/*
+ * remove the first entry from the free list and return a pointer to it
+ * Note: caller must check that mfp->mf_free_first is not NULL!
+ */
+static bhdr_T * mf_rem_free(mfp)
+memfile_T *mfp;
+{
+ bhdr_T *hp;
+
+ hp = mfp->mf_free_first;
+ mfp->mf_free_first = hp->bh_next;
+ return hp;
+}
+
+/*
+ * read a block from disk
+ *
+ * Return FAIL for failure, OK otherwise
+ */
+static int mf_read(mfp, hp)
+memfile_T *mfp;
+bhdr_T *hp;
+{
+ off_t offset;
+ unsigned page_size;
+ unsigned size;
+
+ if (mfp->mf_fd < 0) /* there is no file, can't read */
+ return FAIL;
+
+ page_size = mfp->mf_page_size;
+ offset = (off_t)page_size * hp->bh_bnum;
+ size = page_size * hp->bh_page_count;
+ if (lseek(mfp->mf_fd, offset, SEEK_SET) != offset) {
+ PERROR(_("E294: Seek error in swap file read"));
+ return FAIL;
+ }
+ if ((unsigned)read_eintr(mfp->mf_fd, hp->bh_data, size) != size) {
+ PERROR(_("E295: Read error in swap file"));
+ return FAIL;
+ }
+
+ /* Decrypt if 'key' is set and this is a data block. */
+ if (*mfp->mf_buffer->b_p_key != NUL)
+ ml_decrypt_data(mfp, hp->bh_data, offset, size);
+
+ return OK;
+}
+
+/*
+ * write a block to disk
+ *
+ * Return FAIL for failure, OK otherwise
+ */
+static int mf_write(mfp, hp)
+memfile_T *mfp;
+bhdr_T *hp;
+{
+ 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 */
+ unsigned page_count; /* number of pages written */
+ unsigned size; /* number of bytes written */
+
+ if (mfp->mf_fd < 0) /* there is no file, can't write */
+ return FAIL;
+
+ if (hp->bh_bnum < 0) /* must assign file block number */
+ if (mf_trans_add(mfp, hp) == FAIL)
+ return FAIL;
+
+ page_size = mfp->mf_page_size;
+
+ /*
+ * We don't want gaps in the file. Write the blocks in front of *hp
+ * to extend the file.
+ * If block 'mf_infile_count' is not in the hash list, it has been
+ * freed. Fill the space in the file with data from the current block.
+ */
+ for (;; ) {
+ nr = hp->bh_bnum;
+ if (nr > mfp->mf_infile_count) { /* beyond end of file */
+ nr = mfp->mf_infile_count;
+ hp2 = mf_find_hash(mfp, nr); /* NULL caught below */
+ } else
+ hp2 = hp;
+
+ offset = (off_t)page_size * nr;
+ if (lseek(mfp->mf_fd, offset, SEEK_SET) != offset) {
+ PERROR(_("E296: Seek error in swap file write"));
+ return FAIL;
+ }
+ if (hp2 == NULL) /* freed block, fill with dummy data */
+ page_count = 1;
+ else
+ page_count = hp2->bh_page_count;
+ size = page_size * page_count;
+ if (mf_write_block(mfp, hp2 == NULL ? hp : hp2, offset, size) == FAIL) {
+ /*
+ * Avoid repeating the error message, this mostly happens when the
+ * disk is full. We give the message again only after a successful
+ * write or when hitting a key. We keep on trying, in case some
+ * space becomes available.
+ */
+ if (!did_swapwrite_msg)
+ EMSG(_("E297: Write error in swap file"));
+ did_swapwrite_msg = TRUE;
+ return FAIL;
+ }
+ did_swapwrite_msg = FALSE;
+ if (hp2 != NULL) /* written a non-dummy block */
+ hp2->bh_flags &= ~BH_DIRTY;
+ /* appended to the file */
+ if (nr + (blocknr_T)page_count > mfp->mf_infile_count)
+ mfp->mf_infile_count = nr + page_count;
+ if (nr == hp->bh_bnum) /* written the desired block */
+ break;
+ }
+ return OK;
+}
+
+/*
+ * Write block "hp" with data size "size" to file "mfp->mf_fd".
+ * Takes care of encryption.
+ * Return FAIL or OK.
+ */
+static int mf_write_block(mfp, hp, offset, size)
+memfile_T *mfp;
+bhdr_T *hp;
+off_t offset UNUSED;
+unsigned size;
+{
+ char_u *data = hp->bh_data;
+ int result = OK;
+
+ /* Encrypt if 'key' is set and this is a data block. */
+ if (*mfp->mf_buffer->b_p_key != NUL) {
+ data = ml_encrypt_data(mfp, data, offset, size);
+ if (data == NULL)
+ return FAIL;
+ }
+
+ if ((unsigned)write_eintr(mfp->mf_fd, data, size) != size)
+ result = FAIL;
+
+ if (data != hp->bh_data)
+ vim_free(data);
+
+ return result;
+}
+
+/*
+ * Make block number for *hp positive and add it to the translation list
+ *
+ * Return FAIL for failure, OK otherwise
+ */
+static int mf_trans_add(mfp, hp)
+memfile_T *mfp;
+bhdr_T *hp;
+{
+ bhdr_T *freep;
+ blocknr_T new_bnum;
+ NR_TRANS *np;
+ int page_count;
+
+ if (hp->bh_bnum >= 0) /* it's already positive */
+ return OK;
+
+ if ((np = (NR_TRANS *)alloc((unsigned)sizeof(NR_TRANS))) == NULL)
+ return FAIL;
+
+ /*
+ * Get a new number for the block.
+ * If the first item in the free list has sufficient pages, use its number
+ * Otherwise use mf_blocknr_max.
+ */
+ freep = mfp->mf_free_first;
+ page_count = hp->bh_page_count;
+ if (freep != NULL && freep->bh_page_count >= page_count) {
+ new_bnum = freep->bh_bnum;
+ /*
+ * If the page count of the free block was larger, reduce it.
+ * If the page count matches, remove the block from the free list
+ */
+ if (freep->bh_page_count > page_count) {
+ freep->bh_bnum += page_count;
+ freep->bh_page_count -= page_count;
+ } else {
+ freep = mf_rem_free(mfp);
+ vim_free(freep);
+ }
+ } else {
+ new_bnum = mfp->mf_blocknr_max;
+ mfp->mf_blocknr_max += page_count;
+ }
+
+ np->nt_old_bnum = hp->bh_bnum; /* adjust number */
+ np->nt_new_bnum = new_bnum;
+
+ mf_rem_hash(mfp, hp); /* remove from old hash list */
+ hp->bh_bnum = new_bnum;
+ mf_ins_hash(mfp, hp); /* insert in new hash list */
+
+ /* Insert "np" into "mf_trans" hashtable with key "np->nt_old_bnum" */
+ mf_hash_add_item(&mfp->mf_trans, (mf_hashitem_T *)np);
+
+ return OK;
+}
+
+/*
+ * Lookup a translation from the trans lists and delete the entry
+ *
+ * Return the positive new number when found, the old number when not found
+ */
+blocknr_T mf_trans_del(mfp, old_nr)
+memfile_T *mfp;
+blocknr_T old_nr;
+{
+ NR_TRANS *np;
+ blocknr_T new_bnum;
+
+ np = (NR_TRANS *)mf_hash_find(&mfp->mf_trans, old_nr);
+
+ if (np == NULL) /* not found */
+ return old_nr;
+
+ mfp->mf_neg_count--;
+ new_bnum = np->nt_new_bnum;
+
+ /* remove entry from the trans list */
+ mf_hash_rem_item(&mfp->mf_trans, (mf_hashitem_T *)np);
+
+ vim_free(np);
+
+ return new_bnum;
+}
+
+/*
+ * Set mfp->mf_ffname according to mfp->mf_fname and some other things.
+ * Only called when creating or renaming the swapfile. Either way it's a new
+ * name so we must work out the full path name.
+ */
+void mf_set_ffname(mfp)
+memfile_T *mfp;
+{
+ mfp->mf_ffname = FullName_save(mfp->mf_fname, FALSE);
+}
+
+/*
+ * Make the name of the file used for the memfile a full path.
+ * Used before doing a :cd
+ */
+void mf_fullname(mfp)
+memfile_T *mfp;
+{
+ if (mfp != NULL && mfp->mf_fname != NULL && mfp->mf_ffname != NULL) {
+ vim_free(mfp->mf_fname);
+ mfp->mf_fname = mfp->mf_ffname;
+ mfp->mf_ffname = NULL;
+ }
+}
+
+/*
+ * return TRUE if there are any translations pending for 'mfp'
+ */
+int mf_need_trans(mfp)
+memfile_T *mfp;
+{
+ return mfp->mf_fname != NULL && mfp->mf_neg_count > 0;
+}
+
+/*
+ * Open a swap file for a memfile.
+ * The "fname" must be in allocated memory, and is consumed (also when an
+ * error occurs).
+ */
+static void mf_do_open(mfp, fname, flags)
+memfile_T *mfp;
+char_u *fname;
+int flags; /* flags for open() */
+{
+#ifdef HAVE_LSTAT
+ struct stat sb;
+#endif
+
+ mfp->mf_fname = fname;
+
+ /*
+ * Get the full path name before the open, because this is
+ * not possible after the open on the Amiga.
+ * fname cannot be NameBuff, because it must have been allocated.
+ */
+ mf_set_ffname(mfp);
+
+#ifdef HAVE_LSTAT
+ /*
+ * 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.
+ */
+ if ((flags & O_CREAT) && mch_lstat((char *)mfp->mf_fname, &sb) >= 0) {
+ mfp->mf_fd = -1;
+ EMSG(_("E300: Swap file already exists (symlink attack?)"));
+ } else
+#endif
+ {
+ /*
+ * try to open the file
+ */
+ flags |= O_EXTRA | O_NOFOLLOW;
+ mfp->mf_fd = mch_open_rw((char *)mfp->mf_fname, flags);
+ }
+
+ /*
+ * If the file cannot be opened, use memory only
+ */
+ if (mfp->mf_fd < 0) {
+ vim_free(mfp->mf_fname);
+ vim_free(mfp->mf_ffname);
+ mfp->mf_fname = NULL;
+ mfp->mf_ffname = NULL;
+ } else {
+#ifdef HAVE_FD_CLOEXEC
+ int fdflags = fcntl(mfp->mf_fd, F_GETFD);
+ if (fdflags >= 0 && (fdflags & FD_CLOEXEC) == 0)
+ fcntl(mfp->mf_fd, F_SETFD, fdflags | FD_CLOEXEC);
+#endif
+#ifdef HAVE_SELINUX
+ mch_copy_sec(fname, mfp->mf_fname);
+#endif
+ mch_hide(mfp->mf_fname); /* try setting the 'hidden' flag */
+ }
+}
+
+/*
+ * Implementation of mf_hashtab_T follows.
+ */
+
+/*
+ * The number of buckets in the hashtable is increased by a factor of
+ * MHT_GROWTH_FACTOR when the average number of items per bucket
+ * exceeds 2 ^ MHT_LOG_LOAD_FACTOR.
+ */
+#define MHT_LOG_LOAD_FACTOR 6
+#define MHT_GROWTH_FACTOR 2 /* must be a power of two */
+
+/*
+ * Initialize an empty hash table.
+ */
+static void mf_hash_init(mht)
+mf_hashtab_T *mht;
+{
+ vim_memset(mht, 0, sizeof(mf_hashtab_T));
+ mht->mht_buckets = mht->mht_small_buckets;
+ mht->mht_mask = MHT_INIT_SIZE - 1;
+}
+
+/*
+ * Free the array of a hash table. Does not free the items it contains!
+ * The hash table must not be used again without another mf_hash_init() call.
+ */
+static void mf_hash_free(mht)
+mf_hashtab_T *mht;
+{
+ if (mht->mht_buckets != mht->mht_small_buckets)
+ vim_free(mht->mht_buckets);
+}
+
+/*
+ * Free the array of a hash table and all the items it contains.
+ */
+static void mf_hash_free_all(mht)
+mf_hashtab_T *mht;
+{
+ long_u idx;
+ mf_hashitem_T *mhi;
+ mf_hashitem_T *next;
+
+ for (idx = 0; idx <= mht->mht_mask; idx++)
+ for (mhi = mht->mht_buckets[idx]; mhi != NULL; mhi = next) {
+ next = mhi->mhi_next;
+ vim_free(mhi);
+ }
+
+ mf_hash_free(mht);
+}
+
+/*
+ * Find "key" in hashtable "mht".
+ * Returns a pointer to a mf_hashitem_T or NULL if the item was not found.
+ */
+static mf_hashitem_T * mf_hash_find(mht, key)
+mf_hashtab_T *mht;
+blocknr_T key;
+{
+ mf_hashitem_T *mhi;
+
+ mhi = mht->mht_buckets[key & mht->mht_mask];
+ while (mhi != NULL && mhi->mhi_key != key)
+ mhi = mhi->mhi_next;
+
+ return mhi;
+}
+
+/*
+ * Add item "mhi" to hashtable "mht".
+ * "mhi" must not be NULL.
+ */
+static void mf_hash_add_item(mht, mhi)
+mf_hashtab_T *mht;
+mf_hashitem_T *mhi;
+{
+ long_u idx;
+
+ idx = mhi->mhi_key & mht->mht_mask;
+ mhi->mhi_next = mht->mht_buckets[idx];
+ mhi->mhi_prev = NULL;
+ if (mhi->mhi_next != NULL)
+ mhi->mhi_next->mhi_prev = mhi;
+ mht->mht_buckets[idx] = mhi;
+
+ mht->mht_count++;
+
+ /*
+ * Grow hashtable when we have more thank 2^MHT_LOG_LOAD_FACTOR
+ * items per bucket on average
+ */
+ if (mht->mht_fixed == 0
+ && (mht->mht_count >> MHT_LOG_LOAD_FACTOR) > mht->mht_mask) {
+ if (mf_hash_grow(mht) == FAIL) {
+ /* stop trying to grow after first failure to allocate memory */
+ mht->mht_fixed = 1;
+ }
+ }
+}
+
+/*
+ * Remove item "mhi" from hashtable "mht".
+ * "mhi" must not be NULL and must have been inserted into "mht".
+ */
+static void mf_hash_rem_item(mht, mhi)
+mf_hashtab_T *mht;
+mf_hashitem_T *mhi;
+{
+ if (mhi->mhi_prev == NULL)
+ mht->mht_buckets[mhi->mhi_key & mht->mht_mask] = mhi->mhi_next;
+ else
+ mhi->mhi_prev->mhi_next = mhi->mhi_next;
+
+ if (mhi->mhi_next != NULL)
+ mhi->mhi_next->mhi_prev = mhi->mhi_prev;
+
+ mht->mht_count--;
+
+ /* We could shrink the table here, but it typically takes little memory,
+ * so why bother? */
+}
+
+/*
+ * Increase number of buckets in the hashtable by MHT_GROWTH_FACTOR and
+ * rehash items.
+ * Returns FAIL when out of memory.
+ */
+static int mf_hash_grow(mht)
+mf_hashtab_T *mht;
+{
+ long_u i, j;
+ int shift;
+ mf_hashitem_T *mhi;
+ mf_hashitem_T *tails[MHT_GROWTH_FACTOR];
+ mf_hashitem_T **buckets;
+ size_t size;
+
+ size = (mht->mht_mask + 1) * MHT_GROWTH_FACTOR * sizeof(void *);
+ buckets = (mf_hashitem_T **)lalloc_clear(size, FALSE);
+ if (buckets == NULL)
+ return FAIL;
+
+ shift = 0;
+ while ((mht->mht_mask >> shift) != 0)
+ shift++;
+
+ for (i = 0; i <= mht->mht_mask; i++) {
+ /*
+ * Traverse the items in the i-th original bucket and move them into
+ * MHT_GROWTH_FACTOR new buckets, preserving their relative order
+ * within each new bucket. Preserving the order is important because
+ * mf_get() tries to keep most recently used items at the front of
+ * each bucket.
+ *
+ * Here we strongly rely on the fact the hashes are computed modulo
+ * a power of two.
+ */
+
+ vim_memset(tails, 0, sizeof(tails));
+
+ for (mhi = mht->mht_buckets[i]; mhi != NULL; mhi = mhi->mhi_next) {
+ j = (mhi->mhi_key >> shift) & (MHT_GROWTH_FACTOR - 1);
+ if (tails[j] == NULL) {
+ buckets[i + (j << shift)] = mhi;
+ tails[j] = mhi;
+ mhi->mhi_prev = NULL;
+ } else {
+ tails[j]->mhi_next = mhi;
+ mhi->mhi_prev = tails[j];
+ tails[j] = mhi;
+ }
+ }
+
+ for (j = 0; j < MHT_GROWTH_FACTOR; j++)
+ if (tails[j] != NULL)
+ tails[j]->mhi_next = NULL;
+ }
+
+ if (mht->mht_buckets != mht->mht_small_buckets)
+ vim_free(mht->mht_buckets);
+
+ mht->mht_buckets = buckets;
+ mht->mht_mask = (mht->mht_mask + 1) * MHT_GROWTH_FACTOR - 1;
+
+ return OK;
+}
diff --git a/src/memline.c b/src/memline.c
new file mode 100644
index 0000000000..15d5416829
--- /dev/null
+++ b/src/memline.c
@@ -0,0 +1,4681 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * 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.
+ */
+
+/* for debugging */
+/* #define CHECK(c, s) if (c) EMSG(s) */
+#define CHECK(c, s)
+
+/*
+ * memline.c: Contains the functions for appending, deleting and changing the
+ * text lines. The memfile functions are used to store the information in
+ * blocks of memory, backed up by a file. The structure of the information is
+ * a tree. The root of the tree is a pointer block. The leaves of the tree
+ * are data blocks. In between may be several layers of pointer blocks,
+ * forming branches.
+ *
+ * Three types of blocks are used:
+ * - Block nr 0 contains information for recovery
+ * - Pointer blocks contain list of pointers to other blocks.
+ * - Data blocks contain the actual text.
+ *
+ * Block nr 0 contains the block0 structure (see below).
+ *
+ * Block nr 1 is the first pointer block. It is the root of the tree.
+ * Other pointer blocks are branches.
+ *
+ * If a line is too big to fit in a single page, the block containing that
+ * line is made big enough to hold the line. It may span several pages.
+ * Otherwise all blocks are one page.
+ *
+ * A data block that was filled when starting to edit a file and was not
+ * changed since then, can have a negative block number. This means that it
+ * has not yet been assigned a place in the file. When recovering, the lines
+ * in this data block can be read from the original file. When the block is
+ * changed (lines appended/deleted/changed) or when it is flushed it gets a
+ * positive number. Use mf_trans_del() to get the new number, before calling
+ * mf_get().
+ */
+
+#include "vim.h"
+
+#ifndef UNIX /* it's in os_unix.h for Unix */
+# include <time.h>
+#endif
+
+#if defined(SASC) || defined(__amigaos4__)
+# include <proto/dos.h> /* for Open() and Close() */
+#endif
+
+typedef struct block0 ZERO_BL; /* contents of the first block */
+typedef struct pointer_block PTR_BL; /* contents of a pointer block */
+typedef struct data_block DATA_BL; /* contents of a data block */
+typedef struct pointer_entry PTR_EN; /* block/line-count pair */
+
+#define DATA_ID (('d' << 8) + 'a') /* data block id */
+#define PTR_ID (('p' << 8) + 't') /* pointer block id */
+#define BLOCK0_ID0 'b' /* block 0 id 0 */
+#define BLOCK0_ID1 '0' /* block 0 id 1 */
+#define BLOCK0_ID1_C0 'c' /* block 0 id 1 'cm' 0 */
+#define BLOCK0_ID1_C1 'C' /* block 0 id 1 'cm' 1 */
+
+/*
+ * pointer to a block, used in a pointer block
+ */
+struct pointer_entry {
+ blocknr_T pe_bnum; /* block number */
+ linenr_T pe_line_count; /* number of lines in this branch */
+ linenr_T pe_old_lnum; /* lnum for this block (for recovery) */
+ int pe_page_count; /* number of pages in block pe_bnum */
+};
+
+/*
+ * A pointer block contains a list of branches in the tree.
+ */
+struct pointer_block {
+ short_u pb_id; /* ID for pointer block: PTR_ID */
+ short_u pb_count; /* number of pointers in this block */
+ short_u pb_count_max; /* maximum value for pb_count */
+ PTR_EN pb_pointer[1]; /* list of pointers to blocks (actually longer)
+ * followed by empty space until end of page */
+};
+
+/*
+ * A data block is a leaf in the tree.
+ *
+ * The text of the lines is at the end of the block. The text of the first line
+ * in the block is put at the end, the text of the second line in front of it,
+ * etc. Thus the order of the lines is the opposite of the line number.
+ */
+struct data_block {
+ short_u db_id; /* ID for data block: DATA_ID */
+ unsigned db_free; /* free space available */
+ unsigned db_txt_start; /* byte where text starts */
+ unsigned db_txt_end; /* byte just after data block */
+ linenr_T db_line_count; /* number of lines in this block */
+ unsigned db_index[1]; /* index for start of line (actually bigger)
+ * followed by empty space upto db_txt_start
+ * followed by the text in the lines until
+ * end of page */
+};
+
+/*
+ * The low bits of db_index hold the actual index. The topmost bit is
+ * used for the global command to be able to mark a line.
+ * This method is not clean, but otherwise there would be at least one extra
+ * byte used for each line.
+ * The mark has to be in this place to keep it with the correct line when other
+ * lines are inserted or deleted.
+ */
+#define DB_MARKED ((unsigned)1 << ((sizeof(unsigned) * 8) - 1))
+#define DB_INDEX_MASK (~DB_MARKED)
+
+#define INDEX_SIZE (sizeof(unsigned)) /* size of one db_index entry */
+#define HEADER_SIZE (sizeof(DATA_BL) - INDEX_SIZE) /* size of data block header */
+
+#define B0_FNAME_SIZE_ORG 900 /* what it was in older versions */
+#define B0_FNAME_SIZE_NOCRYPT 898 /* 2 bytes used for other things */
+#define B0_FNAME_SIZE_CRYPT 890 /* 10 bytes used for other things */
+#define B0_UNAME_SIZE 40
+#define B0_HNAME_SIZE 40
+/*
+ * Restrict the numbers to 32 bits, otherwise most compilers will complain.
+ * This won't detect a 64 bit machine that only swaps a byte in the top 32
+ * bits, but that is crazy anyway.
+ */
+#define B0_MAGIC_LONG 0x30313233L
+#define B0_MAGIC_INT 0x20212223L
+#define B0_MAGIC_SHORT 0x10111213L
+#define B0_MAGIC_CHAR 0x55
+
+/*
+ * Block zero holds all info about the swap file.
+ *
+ * NOTE: DEFINITION OF BLOCK 0 SHOULD NOT CHANGE! It would make all existing
+ * swap files unusable!
+ *
+ * If size of block0 changes anyway, adjust MIN_SWAP_PAGE_SIZE in vim.h!!
+ *
+ * This block is built up of single bytes, to make it portable across
+ * different machines. b0_magic_* is used to check the byte order and size of
+ * variables, because the rest of the swap file is not portable.
+ */
+struct block0 {
+ char_u b0_id[2]; /* id for block 0: BLOCK0_ID0 and BLOCK0_ID1,
+ * BLOCK0_ID1_C0, BLOCK0_ID1_C1 */
+ char_u b0_version[10]; /* Vim version string */
+ char_u b0_page_size[4]; /* number of bytes per page */
+ char_u b0_mtime[4]; /* last modification time of file */
+ char_u b0_ino[4]; /* inode of b0_fname */
+ char_u b0_pid[4]; /* process id of creator (or 0) */
+ char_u b0_uname[B0_UNAME_SIZE]; /* name of user (uid if no name) */
+ char_u b0_hname[B0_HNAME_SIZE]; /* host name (if it has a name) */
+ char_u b0_fname[B0_FNAME_SIZE_ORG]; /* name of file being edited */
+ long b0_magic_long; /* check for byte order of long */
+ int b0_magic_int; /* check for byte order of int */
+ short b0_magic_short; /* check for byte order of short */
+ char_u b0_magic_char; /* check for last char */
+};
+
+/*
+ * Note: b0_dirty and b0_flags are put at the end of the file name. For very
+ * long file names in older versions of Vim they are invalid.
+ * The 'fileencoding' comes before b0_flags, with a NUL in front. But only
+ * when there is room, for very long file names it's omitted.
+ */
+#define B0_DIRTY 0x55
+#define b0_dirty b0_fname[B0_FNAME_SIZE_ORG - 1]
+
+/*
+ * The b0_flags field is new in Vim 7.0.
+ */
+#define b0_flags b0_fname[B0_FNAME_SIZE_ORG - 2]
+
+/*
+ * Crypt seed goes here, 8 bytes. New in Vim 7.3.
+ * Without encryption these bytes may be used for 'fenc'.
+ */
+#define b0_seed b0_fname[B0_FNAME_SIZE_ORG - 2 - MF_SEED_LEN]
+
+/* The lowest two bits contain the fileformat. Zero means it's not set
+ * (compatible with Vim 6.x), otherwise it's EOL_UNIX + 1, EOL_DOS + 1 or
+ * EOL_MAC + 1. */
+#define B0_FF_MASK 3
+
+/* Swap file is in directory of edited file. Used to find the file from
+ * different mount points. */
+#define B0_SAME_DIR 4
+
+/* The 'fileencoding' is at the end of b0_fname[], with a NUL in front of it.
+ * When empty there is only the NUL. */
+#define B0_HAS_FENC 8
+
+#define STACK_INCR 5 /* nr of entries added to ml_stack at a time */
+
+/*
+ * The line number where the first mark may be is remembered.
+ * If it is 0 there are no marks at all.
+ * (always used for the current buffer only, no buffer change possible while
+ * executing a global command).
+ */
+static linenr_T lowest_marked = 0;
+
+/*
+ * arguments for ml_find_line()
+ */
+#define ML_DELETE 0x11 /* delete line */
+#define ML_INSERT 0x12 /* insert line */
+#define ML_FIND 0x13 /* just find the line */
+#define ML_FLUSH 0x02 /* flush locked block */
+#define ML_SIMPLE(x) (x & 0x10) /* DEL, INS or FIND */
+
+/* argument for ml_upd_block0() */
+typedef enum {
+ UB_FNAME = 0 /* update timestamp and filename */
+ , UB_SAME_DIR /* update the B0_SAME_DIR flag */
+ , UB_CRYPT /* update crypt key */
+} upd_block0_T;
+
+static void ml_set_b0_crypt __ARGS((buf_T *buf, ZERO_BL *b0p));
+static int ml_check_b0_id __ARGS((ZERO_BL *b0p));
+static void ml_upd_block0 __ARGS((buf_T *buf, upd_block0_T what));
+static void set_b0_fname __ARGS((ZERO_BL *, buf_T *buf));
+static void set_b0_dir_flag __ARGS((ZERO_BL *b0p, buf_T *buf));
+static void add_b0_fenc __ARGS((ZERO_BL *b0p, buf_T *buf));
+static time_t swapfile_info __ARGS((char_u *));
+static int recov_file_names __ARGS((char_u **, char_u *, int prepend_dot));
+static int ml_append_int __ARGS((buf_T *, linenr_T, char_u *, colnr_T, int, int));
+static int ml_delete_int __ARGS((buf_T *, linenr_T, int));
+static char_u *findswapname __ARGS((buf_T *, char_u **, char_u *));
+static void ml_flush_line __ARGS((buf_T *));
+static bhdr_T *ml_new_data __ARGS((memfile_T *, int, int));
+static bhdr_T *ml_new_ptr __ARGS((memfile_T *));
+static bhdr_T *ml_find_line __ARGS((buf_T *, linenr_T, int));
+static int ml_add_stack __ARGS((buf_T *));
+static void ml_lineadd __ARGS((buf_T *, int));
+static int b0_magic_wrong __ARGS((ZERO_BL *));
+#ifdef CHECK_INODE
+static int fnamecmp_ino __ARGS((char_u *, char_u *, long));
+#endif
+static void long_to_char __ARGS((long, char_u *));
+static long char_to_long __ARGS((char_u *));
+#if defined(UNIX) || defined(WIN3264)
+static char_u *make_percent_swname __ARGS((char_u *dir, char_u *name));
+#endif
+static void ml_crypt_prepare __ARGS((memfile_T *mfp, off_t offset, int reading));
+static void ml_updatechunk __ARGS((buf_T *buf, long line, long len, int updtype));
+
+/*
+ * Open a new memline for "buf".
+ *
+ * Return FAIL for failure, OK otherwise.
+ */
+int ml_open(buf)
+buf_T *buf;
+{
+ memfile_T *mfp;
+ bhdr_T *hp = NULL;
+ ZERO_BL *b0p;
+ PTR_BL *pp;
+ DATA_BL *dp;
+
+ /*
+ * init fields in memline struct
+ */
+ buf->b_ml.ml_stack_size = 0; /* no stack yet */
+ buf->b_ml.ml_stack = NULL; /* no stack yet */
+ buf->b_ml.ml_stack_top = 0; /* nothing in the stack */
+ buf->b_ml.ml_locked = NULL; /* no cached block */
+ buf->b_ml.ml_line_lnum = 0; /* no cached line */
+ buf->b_ml.ml_chunksize = NULL;
+
+ /*
+ * When 'updatecount' is non-zero swap file may be opened later.
+ */
+ if (p_uc && buf->b_p_swf)
+ buf->b_may_swap = TRUE;
+ else
+ buf->b_may_swap = FALSE;
+
+ /*
+ * Open the memfile. No swap file is created yet.
+ */
+ mfp = mf_open(NULL, 0);
+ if (mfp == NULL)
+ goto error;
+
+ buf->b_ml.ml_mfp = mfp;
+ mfp->mf_buffer = buf;
+ buf->b_ml.ml_flags = ML_EMPTY;
+ buf->b_ml.ml_line_count = 1;
+ curwin->w_nrwidth_line_count = 0;
+
+
+ /*
+ * fill block0 struct and write page 0
+ */
+ if ((hp = mf_new(mfp, FALSE, 1)) == NULL)
+ goto error;
+ if (hp->bh_bnum != 0) {
+ EMSG(_("E298: Didn't get block nr 0?"));
+ goto error;
+ }
+ b0p = (ZERO_BL *)(hp->bh_data);
+
+ b0p->b0_id[0] = BLOCK0_ID0;
+ b0p->b0_id[1] = BLOCK0_ID1;
+ b0p->b0_magic_long = (long)B0_MAGIC_LONG;
+ b0p->b0_magic_int = (int)B0_MAGIC_INT;
+ b0p->b0_magic_short = (short)B0_MAGIC_SHORT;
+ b0p->b0_magic_char = B0_MAGIC_CHAR;
+ STRNCPY(b0p->b0_version, "VIM ", 4);
+ STRNCPY(b0p->b0_version + 4, Version, 6);
+ long_to_char((long)mfp->mf_page_size, b0p->b0_page_size);
+
+ if (!buf->b_spell) {
+ b0p->b0_dirty = buf->b_changed ? B0_DIRTY : 0;
+ b0p->b0_flags = get_fileformat(buf) + 1;
+ set_b0_fname(b0p, buf);
+ (void)get_user_name(b0p->b0_uname, B0_UNAME_SIZE);
+ b0p->b0_uname[B0_UNAME_SIZE - 1] = NUL;
+ mch_get_host_name(b0p->b0_hname, B0_HNAME_SIZE);
+ b0p->b0_hname[B0_HNAME_SIZE - 1] = NUL;
+ long_to_char(mch_get_pid(), b0p->b0_pid);
+ if (*buf->b_p_key != NUL)
+ ml_set_b0_crypt(buf, b0p);
+ }
+
+ /*
+ * Always sync block number 0 to disk, so we can check the file name in
+ * the swap file in findswapname(). Don't do this for a help files or
+ * a spell buffer though.
+ * Only works when there's a swapfile, otherwise it's done when the file
+ * is created.
+ */
+ mf_put(mfp, hp, TRUE, FALSE);
+ if (!buf->b_help && !B_SPELL(buf))
+ (void)mf_sync(mfp, 0);
+
+ /*
+ * Fill in root pointer block and write page 1.
+ */
+ if ((hp = ml_new_ptr(mfp)) == NULL)
+ goto error;
+ if (hp->bh_bnum != 1) {
+ EMSG(_("E298: Didn't get block nr 1?"));
+ goto error;
+ }
+ pp = (PTR_BL *)(hp->bh_data);
+ pp->pb_count = 1;
+ pp->pb_pointer[0].pe_bnum = 2;
+ pp->pb_pointer[0].pe_page_count = 1;
+ pp->pb_pointer[0].pe_old_lnum = 1;
+ pp->pb_pointer[0].pe_line_count = 1; /* line count after insertion */
+ mf_put(mfp, hp, TRUE, FALSE);
+
+ /*
+ * Allocate first data block and create an empty line 1.
+ */
+ if ((hp = ml_new_data(mfp, FALSE, 1)) == NULL)
+ goto error;
+ if (hp->bh_bnum != 2) {
+ EMSG(_("E298: Didn't get block nr 2?"));
+ goto error;
+ }
+
+ dp = (DATA_BL *)(hp->bh_data);
+ dp->db_index[0] = --dp->db_txt_start; /* at end of block */
+ dp->db_free -= 1 + INDEX_SIZE;
+ dp->db_line_count = 1;
+ *((char_u *)dp + dp->db_txt_start) = NUL; /* empty line */
+
+ return OK;
+
+error:
+ if (mfp != NULL) {
+ if (hp)
+ mf_put(mfp, hp, FALSE, FALSE);
+ mf_close(mfp, TRUE); /* will also free(mfp->mf_fname) */
+ }
+ buf->b_ml.ml_mfp = NULL;
+ return FAIL;
+}
+
+/*
+ * Prepare encryption for "buf" with block 0 "b0p".
+ */
+static void ml_set_b0_crypt(buf, b0p)
+buf_T *buf;
+ZERO_BL *b0p;
+{
+ if (*buf->b_p_key == NUL)
+ b0p->b0_id[1] = BLOCK0_ID1;
+ else {
+ if (get_crypt_method(buf) == 0)
+ b0p->b0_id[1] = BLOCK0_ID1_C0;
+ else {
+ b0p->b0_id[1] = BLOCK0_ID1_C1;
+ /* Generate a seed and store it in block 0 and in the memfile. */
+ sha2_seed(&b0p->b0_seed, MF_SEED_LEN, NULL, 0);
+ mch_memmove(buf->b_ml.ml_mfp->mf_seed, &b0p->b0_seed, MF_SEED_LEN);
+ }
+ }
+}
+
+/*
+ * Called after the crypt key or 'cryptmethod' was changed for "buf".
+ * Will apply this to the swapfile.
+ * "old_key" is the previous key. It is equal to buf->b_p_key when
+ * 'cryptmethod' is changed.
+ * "old_cm" is the previous 'cryptmethod'. It is equal to the current
+ * 'cryptmethod' when 'key' is changed.
+ */
+void ml_set_crypt_key(buf, old_key, old_cm)
+buf_T *buf;
+char_u *old_key;
+int old_cm;
+{
+ memfile_T *mfp = buf->b_ml.ml_mfp;
+ bhdr_T *hp;
+ int page_count;
+ int idx;
+ long error;
+ infoptr_T *ip;
+ PTR_BL *pp;
+ DATA_BL *dp;
+ blocknr_T bnum;
+ int top;
+
+ if (mfp == NULL)
+ return; /* no memfile yet, nothing to do */
+
+ /* Set the key, method and seed to be used for reading, these must be the
+ * old values. */
+ mfp->mf_old_key = old_key;
+ mfp->mf_old_cm = old_cm;
+ if (old_cm > 0)
+ mch_memmove(mfp->mf_old_seed, mfp->mf_seed, MF_SEED_LEN);
+
+ /* Update block 0 with the crypt flag and may set a new seed. */
+ ml_upd_block0(buf, UB_CRYPT);
+
+ if (mfp->mf_infile_count > 2) {
+ /*
+ * Need to read back all data blocks from disk, decrypt them with the
+ * old key/method and mark them to be written. The algorithm is
+ * similar to what happens in ml_recover(), but we skip negative block
+ * numbers.
+ */
+ ml_flush_line(buf); /* flush buffered line */
+ (void)ml_find_line(buf, (linenr_T)0, ML_FLUSH); /* flush locked block */
+
+ hp = NULL;
+ bnum = 1; /* start with block 1 */
+ page_count = 1; /* which is 1 page */
+ idx = 0; /* start with first index in block 1 */
+ error = 0;
+ buf->b_ml.ml_stack_top = 0;
+ vim_free(buf->b_ml.ml_stack);
+ buf->b_ml.ml_stack = NULL;
+ buf->b_ml.ml_stack_size = 0; /* no stack yet */
+
+ for (; !got_int; line_breakcheck()) {
+ if (hp != NULL)
+ mf_put(mfp, hp, FALSE, FALSE); /* release previous block */
+
+ /* get the block (pointer or data) */
+ if ((hp = mf_get(mfp, (blocknr_T)bnum, page_count)) == NULL) {
+ if (bnum == 1)
+ break;
+ ++error;
+ } else {
+ pp = (PTR_BL *)(hp->bh_data);
+ if (pp->pb_id == PTR_ID) { /* it is a pointer block */
+ if (pp->pb_count == 0) {
+ /* empty block? */
+ ++error;
+ } else if (idx < (int)pp->pb_count) { /* go a block deeper */
+ if (pp->pb_pointer[idx].pe_bnum < 0) {
+ /* Skip data block with negative block number. */
+ ++idx; /* get same block again for next index */
+ continue;
+ }
+
+ /* going one block deeper in the tree, new entry in
+ * stack */
+ if ((top = ml_add_stack(buf)) < 0) {
+ ++error;
+ break; /* out of memory */
+ }
+ ip = &(buf->b_ml.ml_stack[top]);
+ ip->ip_bnum = bnum;
+ ip->ip_index = idx;
+
+ bnum = pp->pb_pointer[idx].pe_bnum;
+ page_count = pp->pb_pointer[idx].pe_page_count;
+ continue;
+ }
+ } else { /* not a pointer block */
+ dp = (DATA_BL *)(hp->bh_data);
+ if (dp->db_id != DATA_ID) /* block id wrong */
+ ++error;
+ else {
+ /* It is a data block, need to write it back to disk. */
+ mf_put(mfp, hp, TRUE, FALSE);
+ hp = NULL;
+ }
+ }
+ }
+
+ if (buf->b_ml.ml_stack_top == 0) /* finished */
+ break;
+
+ /* go one block up in the tree */
+ ip = &(buf->b_ml.ml_stack[--(buf->b_ml.ml_stack_top)]);
+ bnum = ip->ip_bnum;
+ idx = ip->ip_index + 1; /* go to next index */
+ page_count = 1;
+ }
+
+ if (error > 0)
+ EMSG(_("E843: Error while updating swap file crypt"));
+ }
+
+ mfp->mf_old_key = NULL;
+}
+
+/*
+ * ml_setname() is called when the file name of "buf" has been changed.
+ * It may rename the swap file.
+ */
+void ml_setname(buf)
+buf_T *buf;
+{
+ int success = FALSE;
+ memfile_T *mfp;
+ char_u *fname;
+ char_u *dirp;
+
+ mfp = buf->b_ml.ml_mfp;
+ if (mfp->mf_fd < 0) { /* there is no swap file yet */
+ /*
+ * When 'updatecount' is 0 and 'noswapfile' there is no swap file.
+ * For help files we will make a swap file now.
+ */
+ if (p_uc != 0)
+ ml_open_file(buf); /* create a swap file */
+ return;
+ }
+
+ /*
+ * Try all directories in the 'directory' option.
+ */
+ dirp = p_dir;
+ for (;; ) {
+ if (*dirp == NUL) /* tried all directories, fail */
+ break;
+ fname = findswapname(buf, &dirp, mfp->mf_fname);
+ /* alloc's fname */
+ if (dirp == NULL) /* out of memory */
+ break;
+ if (fname == NULL) /* no file name found for this dir */
+ continue;
+
+ /* if the file name is the same we don't have to do anything */
+ if (fnamecmp(fname, mfp->mf_fname) == 0) {
+ vim_free(fname);
+ success = TRUE;
+ break;
+ }
+ /* need to close the swap file before renaming */
+ if (mfp->mf_fd >= 0) {
+ close(mfp->mf_fd);
+ mfp->mf_fd = -1;
+ }
+
+ /* try to rename the swap file */
+ if (vim_rename(mfp->mf_fname, fname) == 0) {
+ success = TRUE;
+ vim_free(mfp->mf_fname);
+ mfp->mf_fname = fname;
+ vim_free(mfp->mf_ffname);
+ mf_set_ffname(mfp);
+ ml_upd_block0(buf, UB_SAME_DIR);
+ break;
+ }
+ vim_free(fname); /* this fname didn't work, try another */
+ }
+
+ if (mfp->mf_fd == -1) { /* need to (re)open the swap file */
+ mfp->mf_fd = mch_open((char *)mfp->mf_fname, O_RDWR | O_EXTRA, 0);
+ if (mfp->mf_fd < 0) {
+ /* could not (re)open the swap file, what can we do???? */
+ 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)
+ fcntl(mfp->mf_fd, F_SETFD, fdflags | FD_CLOEXEC);
+ }
+#endif
+ }
+ if (!success)
+ EMSG(_("E302: Could not rename swap file"));
+}
+
+/*
+ * Open a file for the memfile for all buffers that are not readonly or have
+ * been modified.
+ * Used when 'updatecount' changes from zero to non-zero.
+ */
+void ml_open_files() {
+ buf_T *buf;
+
+ for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+ if (!buf->b_p_ro || buf->b_changed)
+ ml_open_file(buf);
+}
+
+/*
+ * Open a swap file for an existing memfile, if there is no swap file yet.
+ * If we are unable to find a file name, mf_fname will be NULL
+ * and the memfile will be in memory only (no recovery possible).
+ */
+void ml_open_file(buf)
+buf_T *buf;
+{
+ memfile_T *mfp;
+ char_u *fname;
+ char_u *dirp;
+
+ mfp = buf->b_ml.ml_mfp;
+ if (mfp == NULL || mfp->mf_fd >= 0 || !buf->b_p_swf)
+ return; /* nothing to do */
+
+ /* For a spell buffer use a temp file name. */
+ if (buf->b_spell) {
+ fname = vim_tempname('s');
+ if (fname != NULL)
+ (void)mf_open_file(mfp, fname); /* consumes fname! */
+ buf->b_may_swap = FALSE;
+ return;
+ }
+
+ /*
+ * Try all directories in 'directory' option.
+ */
+ dirp = p_dir;
+ for (;; ) {
+ if (*dirp == NUL)
+ break;
+ /* There is a small chance that between choosing the swap file name
+ * and creating it, another Vim creates the file. In that case the
+ * creation will fail and we will use another directory. */
+ fname = findswapname(buf, &dirp, NULL); /* allocates fname */
+ if (dirp == NULL)
+ break; /* out of memory */
+ if (fname == NULL)
+ continue;
+ if (mf_open_file(mfp, fname) == OK) { /* consumes fname! */
+ ml_upd_block0(buf, UB_SAME_DIR);
+
+ /* Flush block zero, so others can read it */
+ if (mf_sync(mfp, MFS_ZERO) == OK) {
+ /* Mark all blocks that should be in the swapfile as dirty.
+ * Needed for when the 'swapfile' option was reset, so that
+ * the swap file was deleted, and then on again. */
+ mf_set_dirty(mfp);
+ break;
+ }
+ /* Writing block 0 failed: close the file and try another dir */
+ mf_close_file(buf, FALSE);
+ }
+ }
+
+ if (mfp->mf_fname == NULL) { /* Failed! */
+ need_wait_return = TRUE; /* call wait_return later */
+ ++no_wait_return;
+ (void)EMSG2(_(
+ "E303: Unable to open swap file for \"%s\", recovery impossible"),
+ buf_spname(buf) != NULL ? buf_spname(buf) : buf->b_fname);
+ --no_wait_return;
+ }
+
+ /* don't try to open a swap file again */
+ 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(newfile)
+int newfile; /* reading file into new buffer */
+{
+ if (curbuf->b_may_swap && (!curbuf->b_p_ro || !newfile))
+ ml_open_file(curbuf);
+}
+
+/*
+ * Close memline for buffer 'buf'.
+ * If 'del_file' is TRUE, delete the swap file
+ */
+void ml_close(buf, del_file)
+buf_T *buf;
+int del_file;
+{
+ if (buf->b_ml.ml_mfp == NULL) /* not open */
+ return;
+ mf_close(buf->b_ml.ml_mfp, del_file); /* close the .swp file */
+ if (buf->b_ml.ml_line_lnum != 0 && (buf->b_ml.ml_flags & ML_LINE_DIRTY))
+ vim_free(buf->b_ml.ml_line_ptr);
+ vim_free(buf->b_ml.ml_stack);
+ vim_free(buf->b_ml.ml_chunksize);
+ buf->b_ml.ml_chunksize = NULL;
+ buf->b_ml.ml_mfp = NULL;
+
+ /* Reset the "recovered" flag, give the ATTENTION prompt the next time
+ * this buffer is loaded. */
+ buf->b_flags &= ~BF_RECOVERED;
+}
+
+/*
+ * Close all existing memlines and memfiles.
+ * Only used when exiting.
+ * When 'del_file' is TRUE, delete the memfiles.
+ * But don't delete files that were ":preserve"d when we are POSIX compatible.
+ */
+void ml_close_all(del_file)
+int del_file;
+{
+ buf_T *buf;
+
+ for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+ ml_close(buf, del_file && ((buf->b_flags & BF_PRESERVED) == 0
+ || vim_strchr(p_cpo, CPO_PRESERVE) == NULL));
+ spell_delete_wordlist(); /* delete the internal wordlist */
+#ifdef TEMPDIRNAMES
+ vim_deltempdir(); /* delete created temp directory */
+#endif
+}
+
+/*
+ * Close all memfiles for not modified buffers.
+ * Only use just before exiting!
+ */
+void ml_close_notmod() {
+ buf_T *buf;
+
+ for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+ if (!bufIsChanged(buf))
+ ml_close(buf, TRUE); /* close all not-modified buffers */
+}
+
+/*
+ * Update the timestamp in the .swp file.
+ * Used when the file has been written.
+ */
+void ml_timestamp(buf)
+buf_T *buf;
+{
+ ml_upd_block0(buf, UB_FNAME);
+}
+
+/*
+ * Return FAIL when the ID of "b0p" is wrong.
+ */
+static int ml_check_b0_id(b0p)
+ZERO_BL *b0p;
+{
+ if (b0p->b0_id[0] != BLOCK0_ID0
+ || (b0p->b0_id[1] != BLOCK0_ID1
+ && b0p->b0_id[1] != BLOCK0_ID1_C0
+ && b0p->b0_id[1] != BLOCK0_ID1_C1)
+ )
+ return FAIL;
+ return OK;
+}
+
+/*
+ * Update the timestamp or the B0_SAME_DIR flag of the .swp file.
+ */
+static void ml_upd_block0(buf, what)
+buf_T *buf;
+upd_block0_T what;
+{
+ memfile_T *mfp;
+ bhdr_T *hp;
+ ZERO_BL *b0p;
+
+ mfp = buf->b_ml.ml_mfp;
+ if (mfp == NULL || (hp = mf_get(mfp, (blocknr_T)0, 1)) == NULL)
+ return;
+ b0p = (ZERO_BL *)(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)
+ set_b0_fname(b0p, buf);
+ else if (what == UB_CRYPT)
+ ml_set_b0_crypt(buf, b0p);
+ else /* what == UB_SAME_DIR */
+ set_b0_dir_flag(b0p, buf);
+ }
+ mf_put(mfp, hp, TRUE, FALSE);
+}
+
+/*
+ * Write file name and timestamp into block 0 of a swap file.
+ * Also set buf->b_mtime.
+ * Don't use NameBuff[]!!!
+ */
+static void set_b0_fname(b0p, buf)
+ZERO_BL *b0p;
+buf_T *buf;
+{
+ struct stat st;
+
+ if (buf->b_ffname == NULL)
+ b0p->b0_fname[0] = NUL;
+ else {
+ size_t flen, ulen;
+ char_u uname[B0_UNAME_SIZE];
+
+ /*
+ * For a file under the home directory of the current user, we try to
+ * replace the home directory path with "~user". This helps when
+ * editing the same file on different machines over a network.
+ * First replace home dir path with "~/" with home_replace().
+ * Then insert the user name to get "~user/".
+ */
+ home_replace(NULL, buf->b_ffname, b0p->b0_fname,
+ B0_FNAME_SIZE_CRYPT, TRUE);
+ if (b0p->b0_fname[0] == '~') {
+ flen = STRLEN(b0p->b0_fname);
+ /* If there is no user name or it is too long, don't use "~/" */
+ if (get_user_name(uname, B0_UNAME_SIZE) == FAIL
+ || (ulen = STRLEN(uname)) + flen > B0_FNAME_SIZE_CRYPT - 1)
+ vim_strncpy(b0p->b0_fname, buf->b_ffname,
+ B0_FNAME_SIZE_CRYPT - 1);
+ else {
+ mch_memmove(b0p->b0_fname + ulen + 1, b0p->b0_fname + 1, flen);
+ mch_memmove(b0p->b0_fname + 1, uname, ulen);
+ }
+ }
+ if (mch_stat((char *)buf->b_ffname, &st) >= 0) {
+ long_to_char((long)st.st_mtime, b0p->b0_mtime);
+#ifdef CHECK_INODE
+ long_to_char((long)st.st_ino, b0p->b0_ino);
+#endif
+ buf_store_time(buf, &st, buf->b_ffname);
+ buf->b_mtime_read = buf->b_mtime;
+ } else {
+ long_to_char(0L, b0p->b0_mtime);
+#ifdef CHECK_INODE
+ long_to_char(0L, b0p->b0_ino);
+#endif
+ buf->b_mtime = 0;
+ buf->b_mtime_read = 0;
+ buf->b_orig_size = 0;
+ buf->b_orig_mode = 0;
+ }
+ }
+
+ /* Also add the 'fileencoding' if there is room. */
+ add_b0_fenc(b0p, curbuf);
+}
+
+/*
+ * Update the B0_SAME_DIR flag of the swap file. It's set if the file and the
+ * swapfile for "buf" are in the same directory.
+ * This is fail safe: if we are not sure the directories are equal the flag is
+ * not set.
+ */
+static void set_b0_dir_flag(b0p, buf)
+ZERO_BL *b0p;
+buf_T *buf;
+{
+ if (same_directory(buf->b_ml.ml_mfp->mf_fname, buf->b_ffname))
+ b0p->b0_flags |= B0_SAME_DIR;
+ else
+ b0p->b0_flags &= ~B0_SAME_DIR;
+}
+
+/*
+ * When there is room, add the 'fileencoding' to block zero.
+ */
+static void add_b0_fenc(b0p, buf)
+ZERO_BL *b0p;
+buf_T *buf;
+{
+ int n;
+ int size = B0_FNAME_SIZE_NOCRYPT;
+
+ /* Without encryption use the same offset as in Vim 7.2 to be compatible.
+ * With encryption it's OK to move elsewhere, the swap file is not
+ * compatible anyway. */
+ if (*buf->b_p_key != NUL)
+ size = B0_FNAME_SIZE_CRYPT;
+
+ n = (int)STRLEN(buf->b_p_fenc);
+ if ((int)STRLEN(b0p->b0_fname) + n + 1 > size)
+ b0p->b0_flags &= ~B0_HAS_FENC;
+ else {
+ mch_memmove((char *)b0p->b0_fname + size - n,
+ (char *)buf->b_p_fenc, (size_t)n);
+ *(b0p->b0_fname + size - n - 1) = NUL;
+ b0p->b0_flags |= B0_HAS_FENC;
+ }
+}
+
+
+/*
+ * Try to recover curbuf from the .swp file.
+ */
+void ml_recover() {
+ buf_T *buf = NULL;
+ memfile_T *mfp = NULL;
+ char_u *fname;
+ char_u *fname_used = NULL;
+ bhdr_T *hp = NULL;
+ ZERO_BL *b0p;
+ int b0_ff;
+ char_u *b0_fenc = NULL;
+ int b0_cm = -1;
+ PTR_BL *pp;
+ DATA_BL *dp;
+ infoptr_T *ip;
+ blocknr_T bnum;
+ int page_count;
+ struct stat org_stat, swp_stat;
+ int len;
+ int directly;
+ linenr_T lnum;
+ char_u *p;
+ int i;
+ long error;
+ int cannot_open;
+ linenr_T line_count;
+ int has_error;
+ int idx;
+ int top;
+ int txt_start;
+ off_t size;
+ int called_from_main;
+ int serious_error = TRUE;
+ long mtime;
+ int attr;
+ int orig_file_status = NOTDONE;
+
+ recoverymode = TRUE;
+ called_from_main = (curbuf->b_ml.ml_mfp == NULL);
+ 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).
+ */
+ 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
+ && ASCII_ISALPHA(fname[len - 1])) {
+ directly = TRUE;
+ fname_used = vim_strsave(fname); /* make a copy for mf_open() */
+ } else {
+ directly = FALSE;
+
+ /* count the number of matching swap files */
+ len = recover_names(fname, FALSE, 0, NULL);
+ if (len == 0) { /* no swap files found */
+ EMSG2(_("E305: No swap file found for %s"), fname);
+ goto theend;
+ }
+ if (len == 1) /* one swap file found, use it */
+ i = 1;
+ else { /* several swap files found, choose */
+ /* list the names of the swap files */
+ (void)recover_names(fname, TRUE, 0, NULL);
+ msg_putchar('\n');
+ MSG_PUTS(_("Enter number of swap file to use (0 to quit): "));
+ i = get_number(FALSE, NULL);
+ if (i < 1 || i > len)
+ goto theend;
+ }
+ /* get the swap file name that will be used */
+ (void)recover_names(fname, FALSE, i, &fname_used);
+ }
+ if (fname_used == NULL)
+ goto theend; /* out of memory */
+
+ /* When called from main() still need to initialize storage structure */
+ if (called_from_main && ml_open(curbuf) == FAIL)
+ getout(1);
+
+ /*
+ * Allocate a buffer structure for the swap file that is used for recovery.
+ * Only the memline and crypt information in it are really used.
+ */
+ buf = (buf_T *)alloc((unsigned)sizeof(buf_T));
+ if (buf == NULL)
+ goto theend;
+
+ /*
+ * init fields in memline struct
+ */
+ buf->b_ml.ml_stack_size = 0; /* no stack yet */
+ buf->b_ml.ml_stack = NULL; /* no stack yet */
+ buf->b_ml.ml_stack_top = 0; /* nothing in the stack */
+ buf->b_ml.ml_line_lnum = 0; /* no cached line */
+ buf->b_ml.ml_locked = NULL; /* no locked block */
+ buf->b_ml.ml_flags = 0;
+ buf->b_p_key = empty_option;
+ buf->b_p_cm = empty_option;
+
+ /*
+ * open the memfile from the old swap file
+ */
+ p = vim_strsave(fname_used); /* save "fname_used" for the message:
+ mf_open() will consume "fname_used"! */
+ 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);
+ goto theend;
+ }
+ buf->b_ml.ml_mfp = mfp;
+ mfp->mf_buffer = buf;
+
+ /*
+ * The page size set in mf_open() might be different from the page size
+ * used in the swap file, we must get it from block 0. But to read block
+ * 0 we need a page size. Use the minimal size for block 0 here, it will
+ * be set to the real value below.
+ */
+ mfp->mf_page_size = MIN_SWAP_PAGE_SIZE;
+
+ /*
+ * try to read block 0
+ */
+ if ((hp = mf_get(mfp, (blocknr_T)0, 1)) == NULL) {
+ msg_start();
+ MSG_PUTS_ATTR(_("Unable to read block 0 from "), attr | MSG_HIST);
+ msg_outtrans_attr(mfp->mf_fname, attr | MSG_HIST);
+ MSG_PUTS_ATTR(_(
+ "\nMaybe no changes were made or Vim did not update the swap file."),
+ attr | MSG_HIST);
+ msg_end();
+ goto theend;
+ }
+ b0p = (ZERO_BL *)(hp->bh_data);
+ if (STRNCMP(b0p->b0_version, "VIM 3.0", 7) == 0) {
+ msg_start();
+ msg_outtrans_attr(mfp->mf_fname, MSG_HIST);
+ MSG_PUTS_ATTR(_(" cannot be used with this version of Vim.\n"),
+ MSG_HIST);
+ MSG_PUTS_ATTR(_("Use Vim version 3.0.\n"), MSG_HIST);
+ msg_end();
+ goto theend;
+ }
+ if (ml_check_b0_id(b0p) == FAIL) {
+ EMSG2(_("E307: %s does not look like a Vim swap file"), mfp->mf_fname);
+ goto theend;
+ }
+ if (b0_magic_wrong(b0p)) {
+ msg_start();
+ msg_outtrans_attr(mfp->mf_fname, attr | MSG_HIST);
+ MSG_PUTS_ATTR(_(" cannot be used on this computer.\n"),
+ attr | MSG_HIST);
+ MSG_PUTS_ATTR(_("The file was created on "), attr | MSG_HIST);
+ /* avoid going past the end of a corrupted hostname */
+ b0p->b0_fname[0] = NUL;
+ MSG_PUTS_ATTR(b0p->b0_hname, attr | MSG_HIST);
+ MSG_PUTS_ATTR(_(",\nor the file has been damaged."), attr | MSG_HIST);
+ msg_end();
+ goto theend;
+ }
+
+ if (b0p->b0_id[1] == BLOCK0_ID1_C0)
+ b0_cm = 0;
+ else if (b0p->b0_id[1] == BLOCK0_ID1_C1) {
+ b0_cm = 1;
+ mch_memmove(mfp->mf_seed, &b0p->b0_seed, MF_SEED_LEN);
+ }
+ set_crypt_method(buf, b0_cm);
+
+ /*
+ * If we guessed the wrong page size, we have to recalculate the
+ * highest block number in the file.
+ */
+ if (mfp->mf_page_size != (unsigned)char_to_long(b0p->b0_page_size)) {
+ unsigned previous_page_size = mfp->mf_page_size;
+
+ mf_new_page_size(mfp, (unsigned)char_to_long(b0p->b0_page_size));
+ if (mfp->mf_page_size < previous_page_size) {
+ msg_start();
+ msg_outtrans_attr(mfp->mf_fname, attr | MSG_HIST);
+ MSG_PUTS_ATTR(_(
+ " has been damaged (page size is smaller than minimum value).\n"),
+ attr | MSG_HIST);
+ 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
+ mfp->mf_blocknr_max = (blocknr_T)(size / mfp->mf_page_size);
+ mfp->mf_infile_count = mfp->mf_blocknr_max;
+
+ /* need to reallocate the memory used to store the data */
+ p = alloc(mfp->mf_page_size);
+ if (p == NULL)
+ goto theend;
+ mch_memmove(p, hp->bh_data, previous_page_size);
+ vim_free(hp->bh_data);
+ hp->bh_data = p;
+ b0p = (ZERO_BL *)(hp->bh_data);
+ }
+
+ /*
+ * If .swp file name given directly, use name from swap file for buffer.
+ */
+ if (directly) {
+ expand_env(b0p->b0_fname, NameBuff, MAXPATHL);
+ if (setfname(curbuf, NameBuff, NULL, TRUE) == FAIL)
+ goto theend;
+ }
+
+ home_replace(NULL, mfp->mf_fname, NameBuff, MAXPATHL, TRUE);
+ smsg((char_u *)_("Using swap file \"%s\""), NameBuff);
+
+ if (buf_spname(curbuf) != NULL)
+ vim_strncpy(NameBuff, buf_spname(curbuf), MAXPATHL - 1);
+ else
+ home_replace(NULL, curbuf->b_ffname, NameBuff, MAXPATHL, TRUE);
+ smsg((char_u *)_("Original file \"%s\""), NameBuff);
+ msg_putchar('\n');
+
+ /*
+ * check date of swap file and original file
+ */
+ mtime = char_to_long(b0p->b0_mtime);
+ if (curbuf->b_ffname != NULL
+ && mch_stat((char *)curbuf->b_ffname, &org_stat) != -1
+ && ((mch_stat((char *)mfp->mf_fname, &swp_stat) != -1
+ && org_stat.st_mtime > swp_stat.st_mtime)
+ || org_stat.st_mtime != mtime)) {
+ EMSG(_("E308: Warning: Original file may have been changed"));
+ }
+ out_flush();
+
+ /* Get the 'fileformat' and 'fileencoding' from block zero. */
+ b0_ff = (b0p->b0_flags & B0_FF_MASK);
+ if (b0p->b0_flags & B0_HAS_FENC) {
+ int fnsize = B0_FNAME_SIZE_NOCRYPT;
+
+ /* Use the same size as in add_b0_fenc(). */
+ if (b0p->b0_id[1] != BLOCK0_ID1)
+ fnsize = B0_FNAME_SIZE_CRYPT;
+ for (p = b0p->b0_fname + fnsize; p > b0p->b0_fname && p[-1] != NUL; --p)
+ ;
+ b0_fenc = vim_strnsave(p, (int)(b0p->b0_fname + fnsize - p));
+ }
+
+ mf_put(mfp, hp, FALSE, FALSE); /* release block 0 */
+ hp = NULL;
+
+ /*
+ * Now that we are sure that the file is going to be recovered, clear the
+ * contents of the current buffer.
+ */
+ while (!(curbuf->b_ml.ml_flags & ML_EMPTY))
+ ml_delete((linenr_T)1, FALSE);
+
+ /*
+ * Try reading the original file to obtain the values of 'fileformat',
+ * 'fileencoding', etc. Ignore errors. The text itself is not used.
+ * When the file is encrypted the user is asked to enter the key.
+ */
+ if (curbuf->b_ffname != NULL)
+ orig_file_status = readfile(curbuf->b_ffname, NULL, (linenr_T)0,
+ (linenr_T)0, (linenr_T)MAXLNUM, NULL, READ_NEW);
+
+ if (b0_cm >= 0) {
+ /* Need to ask the user for the crypt key. If this fails we continue
+ * without a key, will probably get garbage text. */
+ if (*curbuf->b_p_key != NUL) {
+ smsg((char_u *)_("Swap file is encrypted: \"%s\""), fname_used);
+ MSG_PUTS(_(
+ "\nIf you entered a new crypt key but did not write the text file,"));
+ MSG_PUTS(_("\nenter the new crypt key."));
+ MSG_PUTS(_(
+ "\nIf you wrote the text file after changing the crypt key press enter"));
+ MSG_PUTS(_("\nto use the same key for text file and swap file"));
+ } else
+ smsg((char_u *)_(need_key_msg), fname_used);
+ buf->b_p_key = get_crypt_key(FALSE, FALSE);
+ if (buf->b_p_key == NULL)
+ buf->b_p_key = curbuf->b_p_key;
+ else if (*buf->b_p_key == NUL) {
+ vim_free(buf->b_p_key);
+ buf->b_p_key = curbuf->b_p_key;
+ }
+ if (buf->b_p_key == NULL)
+ buf->b_p_key = empty_option;
+ }
+
+ /* Use the 'fileformat' and 'fileencoding' as stored in the swap file. */
+ 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);
+ vim_free(b0_fenc);
+ }
+ unchanged(curbuf, TRUE);
+
+ bnum = 1; /* start with block 1 */
+ page_count = 1; /* which is 1 page */
+ lnum = 0; /* append after line 0 in curbuf */
+ line_count = 0;
+ idx = 0; /* start with first index in block 1 */
+ error = 0;
+ buf->b_ml.ml_stack_top = 0;
+ buf->b_ml.ml_stack = NULL;
+ buf->b_ml.ml_stack_size = 0; /* no stack yet */
+
+ if (curbuf->b_ffname == NULL)
+ cannot_open = TRUE;
+ else
+ cannot_open = FALSE;
+
+ serious_error = FALSE;
+ for (; !got_int; line_breakcheck()) {
+ if (hp != NULL)
+ mf_put(mfp, hp, FALSE, FALSE); /* release previous block */
+
+ /*
+ * get block
+ */
+ if ((hp = mf_get(mfp, (blocknr_T)bnum, page_count)) == NULL) {
+ if (bnum == 1) {
+ EMSG2(_("E309: Unable to read block 1 from %s"), mfp->mf_fname);
+ goto theend;
+ }
+ ++error;
+ ml_append(lnum++, (char_u *)_("???MANY LINES MISSING"),
+ (colnr_T)0, TRUE);
+ } else { /* there is a block */
+ pp = (PTR_BL *)(hp->bh_data);
+ if (pp->pb_id == PTR_ID) { /* it is a pointer block */
+ /* check line count when using pointer block first time */
+ if (idx == 0 && line_count != 0) {
+ for (i = 0; i < (int)pp->pb_count; ++i)
+ line_count -= pp->pb_pointer[i].pe_line_count;
+ if (line_count != 0) {
+ ++error;
+ ml_append(lnum++, (char_u *)_("???LINE COUNT WRONG"),
+ (colnr_T)0, TRUE);
+ }
+ }
+
+ if (pp->pb_count == 0) {
+ ml_append(lnum++, (char_u *)_("???EMPTY BLOCK"),
+ (colnr_T)0, TRUE);
+ ++error;
+ } else if (idx < (int)pp->pb_count) { /* go a block deeper */
+ if (pp->pb_pointer[idx].pe_bnum < 0) {
+ /*
+ * Data block with negative block number.
+ * Try to read lines from the original file.
+ * This is slow, but it works.
+ */
+ 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
+ lnum += line_count;
+ }
+ if (cannot_open) {
+ ++error;
+ ml_append(lnum++, (char_u *)_("???LINES MISSING"),
+ (colnr_T)0, TRUE);
+ }
+ ++idx; /* get same block again for next index */
+ continue;
+ }
+
+ /*
+ * going one block deeper in the tree
+ */
+ if ((top = ml_add_stack(buf)) < 0) { /* new entry in stack */
+ ++error;
+ break; /* out of memory */
+ }
+ ip = &(buf->b_ml.ml_stack[top]);
+ ip->ip_bnum = bnum;
+ ip->ip_index = idx;
+
+ bnum = pp->pb_pointer[idx].pe_bnum;
+ line_count = pp->pb_pointer[idx].pe_line_count;
+ page_count = pp->pb_pointer[idx].pe_page_count;
+ idx = 0;
+ continue;
+ }
+ } else { /* not a pointer block */
+ dp = (DATA_BL *)(hp->bh_data);
+ if (dp->db_id != DATA_ID) { /* block id wrong */
+ if (bnum == 1) {
+ EMSG2(_("E310: Block 1 ID wrong (%s not a .swp file?)"),
+ mfp->mf_fname);
+ goto theend;
+ }
+ ++error;
+ ml_append(lnum++, (char_u *)_("???BLOCK MISSING"),
+ (colnr_T)0, TRUE);
+ } else {
+ /*
+ * it is a data block
+ * Append all the lines in this block
+ */
+ has_error = FALSE;
+ /*
+ * check length of block
+ * if wrong, use length in pointer block
+ */
+ if (page_count * mfp->mf_page_size != dp->db_txt_end) {
+ ml_append(lnum++,
+ (char_u *)_("??? from here until ???END lines may be messed up"),
+ (colnr_T)0, TRUE);
+ ++error;
+ has_error = TRUE;
+ dp->db_txt_end = page_count * mfp->mf_page_size;
+ }
+
+ /* make sure there is a NUL at the end of the block */
+ *((char_u *)dp + dp->db_txt_end - 1) = NUL;
+
+ /*
+ * check number of lines in block
+ * if wrong, use count in data block
+ */
+ if (line_count != dp->db_line_count) {
+ ml_append(lnum++,
+ (char_u *)_(
+ "??? from here until ???END lines may have been inserted/deleted"),
+ (colnr_T)0, TRUE);
+ ++error;
+ has_error = TRUE;
+ }
+
+ for (i = 0; i < dp->db_line_count; ++i) {
+ txt_start = (dp->db_index[i] & DB_INDEX_MASK);
+ if (txt_start <= (int)HEADER_SIZE
+ || txt_start >= (int)dp->db_txt_end) {
+ p = (char_u *)"???";
+ ++error;
+ } else
+ p = (char_u *)dp + txt_start;
+ ml_append(lnum++, p, (colnr_T)0, TRUE);
+ }
+ if (has_error)
+ ml_append(lnum++, (char_u *)_("???END"),
+ (colnr_T)0, TRUE);
+ }
+ }
+ }
+
+ if (buf->b_ml.ml_stack_top == 0) /* finished */
+ break;
+
+ /*
+ * go one block up in the tree
+ */
+ ip = &(buf->b_ml.ml_stack[--(buf->b_ml.ml_stack_top)]);
+ bnum = ip->ip_bnum;
+ idx = ip->ip_index + 1; /* go to next index */
+ page_count = 1;
+ }
+
+ /*
+ * Compare the buffer contents with the original file. When they differ
+ * set the 'modified' flag.
+ * Lines 1 - lnum are the new contents.
+ * Lines lnum + 1 to ml_line_count are the original contents.
+ * Line ml_line_count + 1 in the dummy empty line.
+ */
+ if (orig_file_status != OK || curbuf->b_ml.ml_line_count != lnum * 2 + 1) {
+ /* Recovering an empty file results in two lines and the first line is
+ * 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;
+ }
+ } else {
+ for (idx = 1; idx <= lnum; ++idx) {
+ /* Need to copy one line, fetching the other one may flush it. */
+ p = vim_strsave(ml_get(idx));
+ i = STRCMP(p, ml_get(idx + lnum));
+ vim_free(p);
+ if (i != 0) {
+ changed_int();
+ ++curbuf->b_changedtick;
+ break;
+ }
+ }
+ }
+
+ /*
+ * Delete the lines from the original file and the dummy line from the
+ * empty buffer. These will now be after the last line in the buffer.
+ */
+ while (curbuf->b_ml.ml_line_count > lnum
+ && !(curbuf->b_ml.ml_flags & ML_EMPTY))
+ ml_delete(curbuf->b_ml.ml_line_count, FALSE);
+ curbuf->b_flags |= BF_RECOVERED;
+
+ recoverymode = FALSE;
+ if (got_int)
+ EMSG(_("E311: Recovery Interrupted"));
+ else if (error) {
+ ++no_wait_return;
+ MSG(">>>>>>>>>>>>>");
+ EMSG(_(
+ "E312: Errors detected while recovering; look for lines starting with ???"));
+ --no_wait_return;
+ MSG(_("See \":help E312\" for more information."));
+ MSG(">>>>>>>>>>>>>");
+ } else {
+ if (curbuf->b_changed) {
+ MSG(_("Recovery completed. You should check if everything is OK."));
+ MSG_PUTS(_(
+ "\n(You might want to write out this file under another name\n"));
+ MSG_PUTS(_("and run diff with the original file to check for changes)"));
+ } else
+ MSG(_("Recovery completed. Buffer contents equals file contents."));
+ MSG_PUTS(_("\nYou may want to delete the .swp file now.\n\n"));
+ cmdline_row = msg_row;
+ }
+ if (*buf->b_p_key != NUL && STRCMP(curbuf->b_p_key, buf->b_p_key) != 0) {
+ MSG_PUTS(_("Using crypt key from swap file for the text file.\n"));
+ set_option_value((char_u *)"key", 0L, buf->b_p_key, OPT_LOCAL);
+ }
+ redraw_curbuf_later(NOT_VALID);
+
+theend:
+ vim_free(fname_used);
+ recoverymode = FALSE;
+ if (mfp != NULL) {
+ if (hp != NULL)
+ mf_put(mfp, hp, FALSE, FALSE);
+ mf_close(mfp, FALSE); /* will also vim_free(mfp->mf_fname) */
+ }
+ if (buf != NULL) {
+ if (buf->b_p_key != curbuf->b_p_key)
+ free_string_option(buf->b_p_key);
+ free_string_option(buf->b_p_cm);
+ vim_free(buf->b_ml.ml_stack);
+ vim_free(buf);
+ }
+ if (serious_error && called_from_main)
+ ml_close(curbuf, TRUE);
+ else {
+ apply_autocmds(EVENT_BUFREADPOST, NULL, curbuf->b_fname, FALSE, curbuf);
+ apply_autocmds(EVENT_BUFWINENTER, NULL, curbuf->b_fname, FALSE, curbuf);
+ }
+ return;
+}
+
+/*
+ * Find the names of swap files in current directory and the directory given
+ * with the 'directory' option.
+ *
+ * Used to:
+ * - list the swap files for "vim -r"
+ * - count the number of swap files when recovering
+ * - list the swap files when recovering
+ * - find the name of the n'th swap file when recovering
+ */
+int recover_names(fname, list, nr, fname_out)
+char_u *fname; /* base for swap file name */
+int list; /* when TRUE, list the swap file names */
+int nr; /* when non-zero, return nr'th swap file name */
+char_u **fname_out; /* result when "nr" > 0 */
+{
+ int num_names;
+ char_u *(names[6]);
+ char_u *tail;
+ char_u *p;
+ int num_files;
+ int file_count = 0;
+ char_u **files;
+ int i;
+ char_u *dirp;
+ char_u *dir_name;
+ char_u *fname_res = NULL;
+#ifdef HAVE_READLINK
+ char_u fname_buf[MAXPATHL];
+#endif
+
+ if (fname != NULL) {
+#ifdef HAVE_READLINK
+ /* Expand symlink in the file name, because the swap file is created
+ * with the actual file instead of with the symlink. */
+ if (resolve_symlink(fname, fname_buf) == OK)
+ fname_res = fname_buf;
+ else
+#endif
+ fname_res = fname;
+ }
+
+ if (list) {
+ /* use msg() to start the scrolling properly */
+ msg((char_u *)_("Swap files found:"));
+ msg_putchar('\n');
+ }
+
+ /*
+ * Do the loop for every directory in 'directory'.
+ * First allocate some memory to put the directory name in.
+ */
+ dir_name = alloc((unsigned)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.
+ */
+ (void)copy_option_part(&dirp, dir_name, 31000, ",");
+
+ if (dir_name[0] == '.' && dir_name[1] == NUL) { /* check current dir */
+ if (fname == NULL) {
+ names[0] = vim_strsave((char_u *)"*.sw?");
+#if defined(UNIX) || defined(WIN3264)
+ /* For Unix names starting with a dot are special. MS-Windows
+ * supports this too, on some file systems. */
+ names[1] = vim_strsave((char_u *)".*.sw?");
+ names[2] = vim_strsave((char_u *)".sw?");
+ num_names = 3;
+#else
+ num_names = 1;
+#endif
+ } else
+ num_names = recov_file_names(names, fname_res, TRUE);
+ } else { /* check directory dir_name */
+ if (fname == NULL) {
+ names[0] = concat_fnames(dir_name, (char_u *)"*.sw?", TRUE);
+#if defined(UNIX) || defined(WIN3264)
+ /* For Unix names starting with a dot are special. MS-Windows
+ * supports this too, on some file systems. */
+ names[1] = concat_fnames(dir_name, (char_u *)".*.sw?", TRUE);
+ names[2] = concat_fnames(dir_name, (char_u *)".sw?", TRUE);
+ num_names = 3;
+#else
+ num_names = 1;
+#endif
+ } else {
+#if defined(UNIX) || defined(WIN3264)
+ p = dir_name + STRLEN(dir_name);
+ if (after_pathsep(dir_name, p) && p[-1] == p[-2]) {
+ /* Ends with '//', Use Full path for swap name */
+ tail = make_percent_swname(dir_name, fname_res);
+ } else
+#endif
+ {
+ tail = gettail(fname_res);
+ tail = concat_fnames(dir_name, tail, TRUE);
+ }
+ if (tail == NULL)
+ num_names = 0;
+ else {
+ num_names = recov_file_names(names, tail, FALSE);
+ vim_free(tail);
+ }
+ }
+ }
+
+ /* check for out-of-memory */
+ for (i = 0; i < num_names; ++i) {
+ if (names[i] == NULL) {
+ for (i = 0; i < num_names; ++i)
+ vim_free(names[i]);
+ num_names = 0;
+ }
+ }
+ if (num_names == 0)
+ num_files = 0;
+ else if (expand_wildcards(num_names, names, &num_files, &files,
+ EW_KEEPALL|EW_FILE|EW_SILENT) == FAIL)
+ num_files = 0;
+
+ /*
+ * When no swap file found, wildcard expansion might have failed (e.g.
+ * not able to execute the shell).
+ * Try finding a swap file by simply adding ".swp" to the file name.
+ */
+ if (*dirp == NUL && file_count + num_files == 0 && fname != NULL) {
+ struct stat st;
+ char_u *swapname;
+
+ swapname = modname(fname_res,
+ (char_u *)".swp", TRUE
+ );
+ if (swapname != NULL) {
+ if (mch_stat((char *)swapname, &st) != -1) { /* It exists! */
+ files = (char_u **)alloc((unsigned)sizeof(char_u *));
+ if (files != NULL) {
+ files[0] = swapname;
+ swapname = NULL;
+ num_files = 1;
+ }
+ }
+ vim_free(swapname);
+ }
+ }
+
+ /*
+ * remove swapfile name of the current buffer, it must be ignored
+ */
+ if (curbuf->b_ml.ml_mfp != NULL
+ && (p = curbuf->b_ml.ml_mfp->mf_fname) != NULL) {
+ for (i = 0; i < num_files; ++i)
+ if (fullpathcmp(p, files[i], TRUE) & FPC_SAME) {
+ /* 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. */
+ vim_free(files[i]);
+ if (--num_files == 0)
+ vim_free(files);
+ else
+ for (; i < num_files; ++i)
+ files[i] = files[i + 1];
+ }
+ }
+ if (nr > 0) {
+ file_count += num_files;
+ if (nr <= file_count) {
+ *fname_out = vim_strsave(
+ files[nr - 1 + num_files - file_count]);
+ dirp = (char_u *)""; /* stop searching */
+ }
+ } else if (list) {
+ if (dir_name[0] == '.' && dir_name[1] == NUL) {
+ if (fname == NULL)
+ MSG_PUTS(_(" In current directory:\n"));
+ else
+ MSG_PUTS(_(" Using specified name:\n"));
+ } else {
+ MSG_PUTS(_(" In directory "));
+ msg_home_replace(dir_name);
+ MSG_PUTS(":\n");
+ }
+
+ if (num_files) {
+ for (i = 0; i < num_files; ++i) {
+ /* print the swap file name */
+ msg_outnum((long)++file_count);
+ MSG_PUTS(". ");
+ msg_puts(gettail(files[i]));
+ msg_putchar('\n');
+ (void)swapfile_info(files[i]);
+ }
+ } else
+ MSG_PUTS(_(" -- none --\n"));
+ out_flush();
+ } else
+ file_count += num_files;
+
+ for (i = 0; i < num_names; ++i)
+ vim_free(names[i]);
+ if (num_files > 0)
+ FreeWild(num_files, files);
+ }
+ vim_free(dir_name);
+ return file_count;
+}
+
+#if defined(UNIX) || defined(WIN3264) /* Need _very_ long file names */
+/*
+ * Append the full path to name with path separators made into percent
+ * signs, to dir. An unnamed buffer is handled as "" (<currentdir>/"")
+ */
+static char_u * make_percent_swname(dir, name)
+char_u *dir;
+char_u *name;
+{
+ char_u *d, *s, *f;
+
+ f = fix_fname(name != NULL ? name : (char_u *) "");
+ d = NULL;
+ if (f != NULL) {
+ s = alloc((unsigned)(STRLEN(f) + 1));
+ if (s != NULL) {
+ STRCPY(s, f);
+ for (d = s; *d != NUL; mb_ptr_adv(d))
+ if (vim_ispathsep(*d))
+ *d = '%';
+ d = concat_fnames(dir, s, TRUE);
+ vim_free(s);
+ }
+ vim_free(f);
+ }
+ return d;
+}
+#endif
+
+#if (defined(UNIX) || defined(__EMX__) || defined(VMS)) && \
+ (defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG))
+static int process_still_running;
+#endif
+
+/*
+ * Give information about an existing swap file.
+ * Returns timestamp (0 when unknown).
+ */
+static time_t swapfile_info(fname)
+char_u *fname;
+{
+ struct stat st;
+ int fd;
+ struct block0 b0;
+ time_t x = (time_t)0;
+ char *p;
+#ifdef UNIX
+ char_u uname[B0_UNAME_SIZE];
+#endif
+
+ /* print the swap file date */
+ if (mch_stat((char *)fname, &st) != -1) {
+#ifdef UNIX
+ /* print name of owner of the file */
+ if (mch_get_uname(st.st_uid, uname, B0_UNAME_SIZE) == OK) {
+ MSG_PUTS(_(" owned by: "));
+ msg_outtrans(uname);
+ MSG_PUTS(_(" dated: "));
+ } else
+#endif
+ MSG_PUTS(_(" dated: "));
+ x = st.st_mtime; /* Manx C can't do &st.st_mtime */
+ p = ctime(&x); /* includes '\n' */
+ if (p == NULL)
+ MSG_PUTS("(invalid)\n");
+ else
+ MSG_PUTS(p);
+ }
+
+ /*
+ * print the original file name
+ */
+ fd = mch_open((char *)fname, O_RDONLY | O_EXTRA, 0);
+ if (fd >= 0) {
+ if (read_eintr(fd, &b0, sizeof(b0)) == sizeof(b0)) {
+ if (STRNCMP(b0.b0_version, "VIM 3.0", 7) == 0) {
+ MSG_PUTS(_(" [from Vim version 3.0]"));
+ } else if (ml_check_b0_id(&b0) == FAIL) {
+ MSG_PUTS(_(" [does not look like a Vim swap file]"));
+ } else {
+ MSG_PUTS(_(" file name: "));
+ if (b0.b0_fname[0] == NUL)
+ MSG_PUTS(_("[No Name]"));
+ else
+ msg_outtrans(b0.b0_fname);
+
+ MSG_PUTS(_("\n modified: "));
+ MSG_PUTS(b0.b0_dirty ? _("YES") : _("no"));
+
+ if (*(b0.b0_uname) != NUL) {
+ MSG_PUTS(_("\n user name: "));
+ msg_outtrans(b0.b0_uname);
+ }
+
+ if (*(b0.b0_hname) != NUL) {
+ if (*(b0.b0_uname) != NUL)
+ MSG_PUTS(_(" host name: "));
+ else
+ MSG_PUTS(_("\n host name: "));
+ msg_outtrans(b0.b0_hname);
+ }
+
+ if (char_to_long(b0.b0_pid) != 0L) {
+ MSG_PUTS(_("\n process ID: "));
+ msg_outnum(char_to_long(b0.b0_pid));
+#if defined(UNIX) || defined(__EMX__)
+ /* EMX kill() not working correctly, it seems */
+ if (kill((pid_t)char_to_long(b0.b0_pid), 0) == 0) {
+ MSG_PUTS(_(" (still running)"));
+ process_still_running = TRUE;
+ }
+#endif
+ }
+
+ if (b0_magic_wrong(&b0)) {
+ MSG_PUTS(_("\n [not usable on this computer]"));
+ }
+ }
+ } else
+ MSG_PUTS(_(" [cannot be read]"));
+ close(fd);
+ } else
+ MSG_PUTS(_(" [cannot be opened]"));
+ msg_putchar('\n');
+
+ return x;
+}
+
+static int recov_file_names(names, path, prepend_dot)
+char_u **names;
+char_u *path;
+int prepend_dot;
+{
+ int num_names;
+
+#ifdef SHORT_FNAME
+ /*
+ * (MS-DOS) always short names
+ */
+ names[0] = modname(path, (char_u *)".sw?", FALSE);
+ num_names = 1;
+#else /* !SHORT_FNAME */
+ /*
+ * (Win32 and Win64) never short names, but do prepend a dot.
+ * (Not MS-DOS or Win32 or Win64) maybe short name, maybe not: Try both.
+ * Only use the short name if it is different.
+ */
+ char_u *p;
+ int i;
+ int shortname = curbuf->b_shortname;
+
+ curbuf->b_shortname = FALSE;
+
+ num_names = 0;
+
+ /*
+ * May also add the file name with a dot prepended, for swap file in same
+ * dir as original file.
+ */
+ if (prepend_dot) {
+ names[num_names] = modname(path, (char_u *)".sw?", TRUE);
+ if (names[num_names] == NULL)
+ goto end;
+ ++num_names;
+ }
+
+ /*
+ * Form the normal swap file name pattern by appending ".sw?".
+ */
+ names[num_names] = concat_fnames(path, (char_u *)".sw?", FALSE);
+ if (names[num_names] == NULL)
+ goto end;
+ if (num_names >= 1) { /* check if we have the same name twice */
+ p = names[num_names - 1];
+ i = (int)STRLEN(names[num_names - 1]) - (int)STRLEN(names[num_names]);
+ if (i > 0)
+ p += i; /* file name has been expanded to full path */
+
+ if (STRCMP(p, names[num_names]) != 0)
+ ++num_names;
+ else
+ vim_free(names[num_names]);
+ } else
+ ++num_names;
+
+ /*
+ * Also try with 'shortname' set, in case the file is on a DOS filesystem.
+ */
+ curbuf->b_shortname = TRUE;
+ names[num_names] = modname(path, (char_u *)".sw?", FALSE);
+ if (names[num_names] == NULL)
+ goto end;
+
+ /*
+ * Remove the one from 'shortname', if it's the same as with 'noshortname'.
+ */
+ p = names[num_names];
+ i = STRLEN(names[num_names]) - STRLEN(names[num_names - 1]);
+ if (i > 0)
+ p += i; /* file name has been expanded to full path */
+ if (STRCMP(names[num_names - 1], p) == 0)
+ vim_free(names[num_names]);
+ else
+ ++num_names;
+
+end:
+ curbuf->b_shortname = shortname;
+
+#endif /* !SHORT_FNAME */
+
+ return num_names;
+}
+
+/*
+ * sync all memlines
+ *
+ * If 'check_file' is TRUE, check if original file exists and was not changed.
+ * If 'check_char' is TRUE, stop syncing when character becomes available, but
+ * always sync at least one block.
+ */
+void ml_sync_all(check_file, check_char)
+int check_file;
+int check_char;
+{
+ buf_T *buf;
+ struct stat st;
+
+ for (buf = firstbuf; buf != NULL; buf = buf->b_next) {
+ if (buf->b_ml.ml_mfp == NULL || buf->b_ml.ml_mfp->mf_fname == NULL)
+ continue; /* no file */
+
+ ml_flush_line(buf); /* flush buffered line */
+ /* flush locked block */
+ (void)ml_find_line(buf, (linenr_T)0, ML_FLUSH);
+ if (bufIsChanged(buf) && check_file && mf_need_trans(buf->b_ml.ml_mfp)
+ && buf->b_ffname != NULL) {
+ /*
+ * If the original file does not exist anymore or has been changed
+ * call ml_preserve() to get rid of all negative numbered blocks.
+ */
+ if (mch_stat((char *)buf->b_ffname, &st) == -1
+ || st.st_mtime != buf->b_mtime_read
+ || st.st_size != buf->b_orig_size) {
+ ml_preserve(buf, FALSE);
+ 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 && ui_char_avail()) /* character available now */
+ break;
+ }
+ }
+}
+
+/*
+ * sync one buffer, including negative blocks
+ *
+ * after this all the blocks are in the swap file
+ *
+ * Used for the :preserve command and when the original file has been
+ * changed or deleted.
+ *
+ * when message is TRUE the success of preserving is reported
+ */
+void ml_preserve(buf, message)
+buf_T *buf;
+int message;
+{
+ bhdr_T *hp;
+ linenr_T lnum;
+ memfile_T *mfp = buf->b_ml.ml_mfp;
+ int status;
+ int got_int_save = got_int;
+
+ if (mfp == NULL || mfp->mf_fname == NULL) {
+ if (message)
+ EMSG(_("E313: Cannot preserve, there is no swap file"));
+ return;
+ }
+
+ /* We only want to stop when interrupted here, not when interrupted
+ * 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);
+
+ /* stack is invalid after mf_sync(.., MFS_ALL) */
+ buf->b_ml.ml_stack_top = 0;
+
+ /*
+ * Some of the data blocks may have been changed from negative to
+ * positive block number. In that case the pointer blocks need to be
+ * updated.
+ *
+ * We don't know in which pointer block the references are, so we visit
+ * all data blocks until there are no more translations to be done (or
+ * we hit the end of the file, which can only happen in case a write fails,
+ * e.g. when file system if full).
+ * ml_find_line() does the work by translating the negative block numbers
+ * when getting the first line of each data block.
+ */
+ if (mf_need_trans(mfp) && !got_int) {
+ lnum = 1;
+ while (mf_need_trans(mfp) && lnum <= buf->b_ml.ml_line_count) {
+ hp = ml_find_line(buf, lnum, ML_FIND);
+ if (hp == NULL) {
+ status = FAIL;
+ goto theend;
+ }
+ 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)
+ status = FAIL;
+ buf->b_ml.ml_stack_top = 0; /* stack is invalid now */
+ }
+theend:
+ got_int |= got_int_save;
+
+ if (message) {
+ if (status == OK)
+ MSG(_("File preserved"));
+ else
+ EMSG(_("E314: Preserve failed"));
+ }
+}
+
+/*
+ * NOTE: The pointer returned by the ml_get_*() functions only remains valid
+ * until the next call!
+ * line1 = ml_get(1);
+ * line2 = ml_get(2); // line1 is now invalid!
+ * Make a copy of the line if necessary.
+ */
+/*
+ * Return a pointer to a (read-only copy of a) line.
+ *
+ * On failure an error message is given and IObuff is returned (to avoid
+ * having to check for error everywhere).
+ */
+char_u * ml_get(lnum)
+linenr_T lnum;
+{
+ return ml_get_buf(curbuf, lnum, FALSE);
+}
+
+/*
+ * Return pointer to position "pos".
+ */
+char_u * ml_get_pos(pos)
+pos_T *pos;
+{
+ return ml_get_buf(curbuf, pos->lnum, FALSE) + pos->col;
+}
+
+/*
+ * Return pointer to cursor line.
+ */
+char_u * ml_get_curline() {
+ return ml_get_buf(curbuf, curwin->w_cursor.lnum, FALSE);
+}
+
+/*
+ * Return pointer to cursor position.
+ */
+char_u * ml_get_cursor() {
+ return ml_get_buf(curbuf, curwin->w_cursor.lnum, FALSE) +
+ curwin->w_cursor.col;
+}
+
+/*
+ * Return a pointer to a line in a specific buffer
+ *
+ * "will_change": if TRUE mark the buffer dirty (chars in the line will be
+ * changed)
+ */
+char_u * ml_get_buf(buf, lnum, will_change)
+buf_T *buf;
+linenr_T lnum;
+int will_change; /* line will be changed */
+{
+ bhdr_T *hp;
+ DATA_BL *dp;
+ char_u *ptr;
+ static int recursive = 0;
+
+ 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: %ld"), lnum);
+ --recursive;
+ }
+errorret:
+ STRCPY(IObuff, "???");
+ return IObuff;
+ }
+ if (lnum <= 0) /* pretend line 0 is line 1 */
+ lnum = 1;
+
+ if (buf->b_ml.ml_mfp == NULL) /* there are no lines */
+ return (char_u *)"";
+
+ /*
+ * See if it is the same line as requested last time.
+ * Otherwise may need to flush last used line.
+ * 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) {
+ ml_flush_line(buf);
+
+ /*
+ * Find the data block containing the line.
+ * This also fills the stack with the blocks from the root to the data
+ * block and releases any locked block.
+ */
+ 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 %ld"), lnum);
+ --recursive;
+ }
+ goto errorret;
+ }
+
+ dp = (DATA_BL *)(hp->bh_data);
+
+ ptr = (char_u *)dp +
+ ((dp->db_index[lnum - buf->b_ml.ml_locked_low]) & DB_INDEX_MASK);
+ buf->b_ml.ml_line_ptr = ptr;
+ buf->b_ml.ml_line_lnum = lnum;
+ buf->b_ml.ml_flags &= ~ML_LINE_DIRTY;
+ }
+ if (will_change)
+ buf->b_ml.ml_flags |= (ML_LOCKED_DIRTY | ML_LOCKED_POS);
+
+ return buf->b_ml.ml_line_ptr;
+}
+
+/*
+ * Check if a line that was just obtained by a call to ml_get
+ * is in allocated memory.
+ */
+int ml_line_alloced() {
+ return curbuf->b_ml.ml_flags & ML_LINE_DIRTY;
+}
+
+/*
+ * Append a line after lnum (may be 0 to insert a line in front of the file).
+ * "line" does not need to be allocated, but can't be another line in a
+ * buffer, unlocking may make it invalid.
+ *
+ * newfile: TRUE when starting to edit a new file, meaning that pe_old_lnum
+ * will be set for recovery
+ * Check: The caller of this function should probably also call
+ * appended_lines().
+ *
+ * return FAIL for failure, OK otherwise
+ */
+int ml_append(lnum, line, len, newfile)
+linenr_T lnum; /* append after this line (can be 0) */
+char_u *line; /* text of the new line */
+colnr_T len; /* length of new line, including NUL, or 0 */
+int newfile; /* flag, see above */
+{
+ /* When starting up, we might still need to create the memfile */
+ if (curbuf->b_ml.ml_mfp == NULL && open_buffer(FALSE, NULL, 0) == FAIL)
+ return FAIL;
+
+ if (curbuf->b_ml.ml_line_lnum != 0)
+ ml_flush_line(curbuf);
+ return ml_append_int(curbuf, lnum, line, len, newfile, FALSE);
+}
+
+/*
+ * Like ml_append() but for an arbitrary buffer. The buffer must already have
+ * a memline.
+ */
+int ml_append_buf(buf, lnum, line, len, newfile)
+buf_T *buf;
+linenr_T lnum; /* append after this line (can be 0) */
+char_u *line; /* text of the new line */
+colnr_T len; /* length of new line, including NUL, or 0 */
+int newfile; /* flag, see above */
+{
+ if (buf->b_ml.ml_mfp == NULL)
+ return FAIL;
+
+ if (buf->b_ml.ml_line_lnum != 0)
+ ml_flush_line(buf);
+ return ml_append_int(buf, lnum, line, len, newfile, FALSE);
+}
+
+static int ml_append_int(buf, lnum, line, len, newfile, mark)
+buf_T *buf;
+linenr_T lnum; /* append after this line (can be 0) */
+char_u *line; /* text of the new line */
+colnr_T len; /* length of line, including NUL, or 0 */
+int newfile; /* flag, see above */
+int mark; /* mark the new line */
+{
+ int i;
+ int line_count; /* number of indexes in current block */
+ int offset;
+ int from, to;
+ int space_needed; /* space needed for new line */
+ int page_size;
+ int page_count;
+ int db_idx; /* index for lnum in data block */
+ bhdr_T *hp;
+ memfile_T *mfp;
+ DATA_BL *dp;
+ PTR_BL *pp;
+ infoptr_T *ip;
+
+ /* lnum out of range */
+ if (lnum > buf->b_ml.ml_line_count || buf->b_ml.ml_mfp == NULL)
+ return FAIL;
+
+ if (lowest_marked && lowest_marked > lnum)
+ lowest_marked = lnum + 1;
+
+ if (len == 0)
+ len = (colnr_T)STRLEN(line) + 1; /* space needed for the text */
+ space_needed = len + INDEX_SIZE; /* space needed for text + index */
+
+ mfp = buf->b_ml.ml_mfp;
+ page_size = mfp->mf_page_size;
+
+ /*
+ * find the data block containing the previous line
+ * This also fills the stack with the blocks from the root to the data block
+ * This also releases any locked block.
+ */
+ if ((hp = ml_find_line(buf, lnum == 0 ? (linenr_T)1 : lnum,
+ ML_INSERT)) == NULL)
+ return FAIL;
+
+ buf->b_ml.ml_flags &= ~ML_EMPTY;
+
+ if (lnum == 0) /* got line one instead, correct db_idx */
+ db_idx = -1; /* careful, it is negative! */
+ else
+ db_idx = lnum - buf->b_ml.ml_locked_low;
+ /* get line count before the insertion */
+ line_count = buf->b_ml.ml_locked_high - buf->b_ml.ml_locked_low;
+
+ dp = (DATA_BL *)(hp->bh_data);
+
+ /*
+ * If
+ * - there is not enough room in the current block
+ * - appending to the last line in the block
+ * - not appending to the last line in the file
+ * insert in front of the next block.
+ */
+ if ((int)dp->db_free < space_needed && db_idx == line_count - 1
+ && lnum < buf->b_ml.ml_line_count) {
+ /*
+ * Now that the line is not going to be inserted in the block that we
+ * expected, the line count has to be adjusted in the pointer blocks
+ * by using ml_locked_lineadd.
+ */
+ --(buf->b_ml.ml_locked_lineadd);
+ --(buf->b_ml.ml_locked_high);
+ if ((hp = ml_find_line(buf, lnum + 1, ML_INSERT)) == NULL)
+ return FAIL;
+
+ db_idx = -1; /* careful, it is negative! */
+ /* get line count before the insertion */
+ line_count = buf->b_ml.ml_locked_high - buf->b_ml.ml_locked_low;
+ CHECK(buf->b_ml.ml_locked_low != lnum + 1, "locked_low != lnum + 1");
+
+ dp = (DATA_BL *)(hp->bh_data);
+ }
+
+ ++buf->b_ml.ml_line_count;
+
+ if ((int)dp->db_free >= space_needed) { /* enough room in data block */
+ /*
+ * Insert new line in existing data block, or in data block allocated above.
+ */
+ dp->db_txt_start -= len;
+ dp->db_free -= space_needed;
+ ++(dp->db_line_count);
+
+ /*
+ * move the text of the lines that follow to the front
+ * adjust the indexes of the lines that follow
+ */
+ if (line_count > db_idx + 1) { /* if there are following lines */
+ /*
+ * Offset is the start of the previous line.
+ * This will become the character just after the new line.
+ */
+ if (db_idx < 0)
+ offset = dp->db_txt_end;
+ else
+ offset = ((dp->db_index[db_idx]) & DB_INDEX_MASK);
+ mch_memmove((char *)dp + dp->db_txt_start,
+ (char *)dp + dp->db_txt_start + len,
+ (size_t)(offset - (dp->db_txt_start + len)));
+ for (i = line_count - 1; i > db_idx; --i)
+ dp->db_index[i + 1] = dp->db_index[i] - len;
+ dp->db_index[db_idx + 1] = offset - len;
+ } else /* add line at the end */
+ dp->db_index[db_idx + 1] = dp->db_txt_start;
+
+ /*
+ * copy the text into the block
+ */
+ mch_memmove((char *)dp + dp->db_index[db_idx + 1], line, (size_t)len);
+ if (mark)
+ dp->db_index[db_idx + 1] |= DB_MARKED;
+
+ /*
+ * Mark the block dirty.
+ */
+ buf->b_ml.ml_flags |= ML_LOCKED_DIRTY;
+ if (!newfile)
+ buf->b_ml.ml_flags |= ML_LOCKED_POS;
+ } else { /* not enough space in data block */
+ /*
+ * If there is not enough room we have to create a new data block and copy some
+ * lines into it.
+ * Then we have to insert an entry in the pointer block.
+ * If this pointer block also is full, we go up another block, and so on, up
+ * to the root if necessary.
+ * The line counts in the pointer blocks have already been adjusted by
+ * ml_find_line().
+ */
+ long line_count_left, line_count_right;
+ int page_count_left, page_count_right;
+ bhdr_T *hp_left;
+ bhdr_T *hp_right;
+ bhdr_T *hp_new;
+ int lines_moved;
+ int data_moved = 0; /* init to shut up gcc */
+ int total_moved = 0; /* init to shut up gcc */
+ DATA_BL *dp_right, *dp_left;
+ int stack_idx;
+ int in_left;
+ int lineadd;
+ blocknr_T bnum_left, bnum_right;
+ linenr_T lnum_left, lnum_right;
+ int pb_idx;
+ PTR_BL *pp_new;
+
+ /*
+ * We are going to allocate a new data block. Depending on the
+ * situation it will be put to the left or right of the existing
+ * block. If possible we put the new line in the left block and move
+ * the lines after it to the right block. Otherwise the new line is
+ * also put in the right block. This method is more efficient when
+ * inserting a lot of lines at one place.
+ */
+ if (db_idx < 0) { /* left block is new, right block is existing */
+ lines_moved = 0;
+ in_left = TRUE;
+ /* space_needed does not change */
+ } else { /* left block is existing, right block is new */
+ lines_moved = line_count - db_idx - 1;
+ if (lines_moved == 0)
+ in_left = FALSE; /* put new line in right block */
+ /* space_needed does not change */
+ else {
+ data_moved = ((dp->db_index[db_idx]) & DB_INDEX_MASK) -
+ dp->db_txt_start;
+ total_moved = data_moved + lines_moved * INDEX_SIZE;
+ if ((int)dp->db_free + total_moved >= space_needed) {
+ in_left = TRUE; /* put new line in left block */
+ space_needed = total_moved;
+ } else {
+ in_left = FALSE; /* put new line in right block */
+ space_needed += total_moved;
+ }
+ }
+ }
+
+ page_count = ((space_needed + HEADER_SIZE) + page_size - 1) / page_size;
+ if ((hp_new = ml_new_data(mfp, newfile, page_count)) == NULL) {
+ /* correct line counts in pointer blocks */
+ --(buf->b_ml.ml_locked_lineadd);
+ --(buf->b_ml.ml_locked_high);
+ return FAIL;
+ }
+ if (db_idx < 0) { /* left block is new */
+ hp_left = hp_new;
+ hp_right = hp;
+ line_count_left = 0;
+ line_count_right = line_count;
+ } else { /* right block is new */
+ hp_left = hp;
+ hp_right = hp_new;
+ line_count_left = line_count;
+ line_count_right = 0;
+ }
+ dp_right = (DATA_BL *)(hp_right->bh_data);
+ dp_left = (DATA_BL *)(hp_left->bh_data);
+ bnum_left = hp_left->bh_bnum;
+ bnum_right = hp_right->bh_bnum;
+ page_count_left = hp_left->bh_page_count;
+ page_count_right = hp_right->bh_page_count;
+
+ /*
+ * May move the new line into the right/new block.
+ */
+ if (!in_left) {
+ dp_right->db_txt_start -= len;
+ dp_right->db_free -= len + INDEX_SIZE;
+ dp_right->db_index[0] = dp_right->db_txt_start;
+ if (mark)
+ dp_right->db_index[0] |= DB_MARKED;
+
+ mch_memmove((char *)dp_right + dp_right->db_txt_start,
+ line, (size_t)len);
+ ++line_count_right;
+ }
+ /*
+ * may move lines from the left/old block to the right/new one.
+ */
+ if (lines_moved) {
+ /*
+ */
+ dp_right->db_txt_start -= data_moved;
+ dp_right->db_free -= total_moved;
+ mch_memmove((char *)dp_right + dp_right->db_txt_start,
+ (char *)dp_left + dp_left->db_txt_start,
+ (size_t)data_moved);
+ offset = dp_right->db_txt_start - dp_left->db_txt_start;
+ dp_left->db_txt_start += data_moved;
+ dp_left->db_free += total_moved;
+
+ /*
+ * update indexes in the new block
+ */
+ for (to = line_count_right, from = db_idx + 1;
+ from < line_count_left; ++from, ++to)
+ dp_right->db_index[to] = dp->db_index[from] + offset;
+ line_count_right += lines_moved;
+ line_count_left -= lines_moved;
+ }
+
+ /*
+ * May move the new line into the left (old or new) block.
+ */
+ if (in_left) {
+ dp_left->db_txt_start -= len;
+ dp_left->db_free -= len + INDEX_SIZE;
+ dp_left->db_index[line_count_left] = dp_left->db_txt_start;
+ if (mark)
+ dp_left->db_index[line_count_left] |= DB_MARKED;
+ mch_memmove((char *)dp_left + dp_left->db_txt_start,
+ line, (size_t)len);
+ ++line_count_left;
+ }
+
+ if (db_idx < 0) { /* left block is new */
+ lnum_left = lnum + 1;
+ lnum_right = 0;
+ } else { /* right block is new */
+ lnum_left = 0;
+ if (in_left)
+ lnum_right = lnum + 2;
+ else
+ lnum_right = lnum + 1;
+ }
+ dp_left->db_line_count = line_count_left;
+ dp_right->db_line_count = line_count_right;
+
+ /*
+ * release the two data blocks
+ * The new one (hp_new) already has a correct blocknumber.
+ * The old one (hp, in ml_locked) gets a positive blocknumber if
+ * we changed it and we are not editing a new file.
+ */
+ if (lines_moved || in_left)
+ buf->b_ml.ml_flags |= ML_LOCKED_DIRTY;
+ if (!newfile && db_idx >= 0 && in_left)
+ buf->b_ml.ml_flags |= ML_LOCKED_POS;
+ mf_put(mfp, hp_new, TRUE, FALSE);
+
+ /*
+ * flush the old data block
+ * set ml_locked_lineadd to 0, because the updating of the
+ * pointer blocks is done below
+ */
+ lineadd = buf->b_ml.ml_locked_lineadd;
+ buf->b_ml.ml_locked_lineadd = 0;
+ ml_find_line(buf, (linenr_T)0, ML_FLUSH); /* flush data block */
+
+ /*
+ * update pointer blocks for the new data block
+ */
+ for (stack_idx = buf->b_ml.ml_stack_top - 1; stack_idx >= 0;
+ --stack_idx) {
+ ip = &(buf->b_ml.ml_stack[stack_idx]);
+ pb_idx = ip->ip_index;
+ if ((hp = mf_get(mfp, ip->ip_bnum, 1)) == NULL)
+ return FAIL;
+ pp = (PTR_BL *)(hp->bh_data); /* must be pointer block */
+ if (pp->pb_id != PTR_ID) {
+ EMSG(_("E317: pointer block id wrong 3"));
+ mf_put(mfp, hp, FALSE, FALSE);
+ return FAIL;
+ }
+ /*
+ * TODO: If the pointer block is full and we are adding at the end
+ * try to insert in front of the next block
+ */
+ /* block not full, add one entry */
+ if (pp->pb_count < pp->pb_count_max) {
+ if (pb_idx + 1 < (int)pp->pb_count)
+ mch_memmove(&pp->pb_pointer[pb_idx + 2],
+ &pp->pb_pointer[pb_idx + 1],
+ (size_t)(pp->pb_count - pb_idx - 1) * sizeof(PTR_EN));
+ ++pp->pb_count;
+ pp->pb_pointer[pb_idx].pe_line_count = line_count_left;
+ pp->pb_pointer[pb_idx].pe_bnum = bnum_left;
+ pp->pb_pointer[pb_idx].pe_page_count = page_count_left;
+ pp->pb_pointer[pb_idx + 1].pe_line_count = line_count_right;
+ pp->pb_pointer[pb_idx + 1].pe_bnum = bnum_right;
+ pp->pb_pointer[pb_idx + 1].pe_page_count = page_count_right;
+
+ if (lnum_left != 0)
+ pp->pb_pointer[pb_idx].pe_old_lnum = lnum_left;
+ if (lnum_right != 0)
+ pp->pb_pointer[pb_idx + 1].pe_old_lnum = lnum_right;
+
+ mf_put(mfp, hp, TRUE, FALSE);
+ buf->b_ml.ml_stack_top = stack_idx + 1; /* truncate stack */
+
+ if (lineadd) {
+ --(buf->b_ml.ml_stack_top);
+ /* fix line count for rest of blocks in the stack */
+ ml_lineadd(buf, lineadd);
+ /* fix stack itself */
+ buf->b_ml.ml_stack[buf->b_ml.ml_stack_top].ip_high +=
+ lineadd;
+ ++(buf->b_ml.ml_stack_top);
+ }
+
+ /*
+ * We are finished, break the loop here.
+ */
+ break;
+ } else { /* pointer block full */
+ /*
+ * split the pointer block
+ * allocate a new pointer block
+ * move some of the pointer into the new block
+ * prepare for updating the parent block
+ */
+ for (;; ) { /* do this twice when splitting block 1 */
+ hp_new = ml_new_ptr(mfp);
+ if (hp_new == NULL) /* TODO: try to fix tree */
+ return FAIL;
+ pp_new = (PTR_BL *)(hp_new->bh_data);
+
+ if (hp->bh_bnum != 1)
+ break;
+
+ /*
+ * if block 1 becomes full the tree is given an extra level
+ * The pointers from block 1 are moved into the new block.
+ * block 1 is updated to point to the new block
+ * then continue to split the new block
+ */
+ mch_memmove(pp_new, pp, (size_t)page_size);
+ pp->pb_count = 1;
+ pp->pb_pointer[0].pe_bnum = hp_new->bh_bnum;
+ pp->pb_pointer[0].pe_line_count = buf->b_ml.ml_line_count;
+ pp->pb_pointer[0].pe_old_lnum = 1;
+ pp->pb_pointer[0].pe_page_count = 1;
+ mf_put(mfp, hp, TRUE, FALSE); /* release block 1 */
+ hp = hp_new; /* new block is to be split */
+ pp = pp_new;
+ CHECK(stack_idx != 0, _("stack_idx should be 0"));
+ ip->ip_index = 0;
+ ++stack_idx; /* do block 1 again later */
+ }
+ /*
+ * move the pointers after the current one to the new block
+ * If there are none, the new entry will be in the new block.
+ */
+ total_moved = pp->pb_count - pb_idx - 1;
+ if (total_moved) {
+ mch_memmove(&pp_new->pb_pointer[0],
+ &pp->pb_pointer[pb_idx + 1],
+ (size_t)(total_moved) * sizeof(PTR_EN));
+ pp_new->pb_count = total_moved;
+ pp->pb_count -= total_moved - 1;
+ pp->pb_pointer[pb_idx + 1].pe_bnum = bnum_right;
+ pp->pb_pointer[pb_idx + 1].pe_line_count = line_count_right;
+ pp->pb_pointer[pb_idx + 1].pe_page_count = page_count_right;
+ if (lnum_right)
+ pp->pb_pointer[pb_idx + 1].pe_old_lnum = lnum_right;
+ } else {
+ pp_new->pb_count = 1;
+ pp_new->pb_pointer[0].pe_bnum = bnum_right;
+ pp_new->pb_pointer[0].pe_line_count = line_count_right;
+ pp_new->pb_pointer[0].pe_page_count = page_count_right;
+ pp_new->pb_pointer[0].pe_old_lnum = lnum_right;
+ }
+ pp->pb_pointer[pb_idx].pe_bnum = bnum_left;
+ pp->pb_pointer[pb_idx].pe_line_count = line_count_left;
+ pp->pb_pointer[pb_idx].pe_page_count = page_count_left;
+ if (lnum_left)
+ pp->pb_pointer[pb_idx].pe_old_lnum = lnum_left;
+ lnum_left = 0;
+ lnum_right = 0;
+
+ /*
+ * recompute line counts
+ */
+ line_count_right = 0;
+ for (i = 0; i < (int)pp_new->pb_count; ++i)
+ line_count_right += pp_new->pb_pointer[i].pe_line_count;
+ line_count_left = 0;
+ for (i = 0; i < (int)pp->pb_count; ++i)
+ line_count_left += pp->pb_pointer[i].pe_line_count;
+
+ bnum_left = hp->bh_bnum;
+ bnum_right = hp_new->bh_bnum;
+ page_count_left = 1;
+ page_count_right = 1;
+ mf_put(mfp, hp, TRUE, FALSE);
+ mf_put(mfp, hp_new, TRUE, FALSE);
+ }
+ }
+
+ /*
+ * 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 */
+ }
+ }
+
+ /* The line was inserted below 'lnum' */
+ ml_updatechunk(buf, lnum + 1, (long)len, ML_CHNK_ADDLINE);
+ return OK;
+}
+
+/*
+ * Replace line lnum, with buffering, in current buffer.
+ *
+ * If "copy" is TRUE, make a copy of the line, otherwise the line has been
+ * copied to allocated memory already.
+ *
+ * Check: The caller of this function should probably also call
+ * changed_lines(), unless update_screen(NOT_VALID) is used.
+ *
+ * return FAIL for failure, OK otherwise
+ */
+int ml_replace(lnum, line, copy)
+linenr_T lnum;
+char_u *line;
+int copy;
+{
+ if (line == NULL) /* just checking... */
+ return FAIL;
+
+ /* When starting up, we might still need to create the memfile */
+ if (curbuf->b_ml.ml_mfp == NULL && open_buffer(FALSE, NULL, 0) == FAIL)
+ return FAIL;
+
+ if (copy && (line = vim_strsave(line)) == NULL) /* allocate memory */
+ return FAIL;
+ if (curbuf->b_ml.ml_line_lnum != lnum) /* other line buffered */
+ ml_flush_line(curbuf); /* flush it */
+ else if (curbuf->b_ml.ml_flags & ML_LINE_DIRTY) /* same line allocated */
+ vim_free(curbuf->b_ml.ml_line_ptr); /* free it */
+ curbuf->b_ml.ml_line_ptr = line;
+ curbuf->b_ml.ml_line_lnum = lnum;
+ curbuf->b_ml.ml_flags = (curbuf->b_ml.ml_flags | ML_LINE_DIRTY) & ~ML_EMPTY;
+
+ 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
+ */
+int ml_delete(lnum, message)
+linenr_T lnum;
+int message;
+{
+ ml_flush_line(curbuf);
+ return ml_delete_int(curbuf, lnum, message);
+}
+
+static int ml_delete_int(buf, lnum, message)
+buf_T *buf;
+linenr_T lnum;
+int message;
+{
+ bhdr_T *hp;
+ memfile_T *mfp;
+ DATA_BL *dp;
+ PTR_BL *pp;
+ infoptr_T *ip;
+ int count; /* number of entries in block */
+ int idx;
+ int stack_idx;
+ int text_start;
+ int line_start;
+ long line_size;
+ int i;
+
+ if (lnum < 1 || lnum > buf->b_ml.ml_line_count)
+ return FAIL;
+
+ if (lowest_marked && lowest_marked > lnum)
+ lowest_marked--;
+
+ /*
+ * If the file becomes empty the last line is replaced by an empty line.
+ */
+ if (buf->b_ml.ml_line_count == 1) { /* file becomes empty */
+ if (message
+ )
+ set_keep_msg((char_u *)_(no_lines_msg), 0);
+
+ /* FEAT_BYTEOFF already handled in there, don't worry 'bout it below */
+ i = ml_replace((linenr_T)1, (char_u *)"", TRUE);
+ buf->b_ml.ml_flags |= ML_EMPTY;
+
+ return i;
+ }
+
+ /*
+ * find the data block containing the line
+ * This also fills the stack with the blocks from the root to the data block
+ * This also releases any locked block.
+ */
+ mfp = buf->b_ml.ml_mfp;
+ if (mfp == NULL)
+ return FAIL;
+
+ if ((hp = ml_find_line(buf, lnum, ML_DELETE)) == NULL)
+ return FAIL;
+
+ dp = (DATA_BL *)(hp->bh_data);
+ /* compute line count before the delete */
+ count = (long)(buf->b_ml.ml_locked_high)
+ - (long)(buf->b_ml.ml_locked_low) + 2;
+ idx = lnum - buf->b_ml.ml_locked_low;
+
+ --buf->b_ml.ml_line_count;
+
+ line_start = ((dp->db_index[idx]) & DB_INDEX_MASK);
+ if (idx == 0) /* first line in block, text at the end */
+ line_size = dp->db_txt_end - line_start;
+ else
+ line_size = ((dp->db_index[idx - 1]) & DB_INDEX_MASK) - line_start;
+
+
+ /*
+ * special case: If there is only one line in the data block it becomes empty.
+ * Then we have to remove the entry, pointing to this data block, from the
+ * pointer block. If this pointer block also becomes empty, we go up another
+ * block, and so on, up to the root if necessary.
+ * The line counts in the pointer blocks have already been adjusted by
+ * ml_find_line().
+ */
+ if (count == 1) {
+ mf_free(mfp, hp); /* free the data block */
+ buf->b_ml.ml_locked = NULL;
+
+ for (stack_idx = buf->b_ml.ml_stack_top - 1; stack_idx >= 0;
+ --stack_idx) {
+ buf->b_ml.ml_stack_top = 0; /* stack is invalid when failing */
+ ip = &(buf->b_ml.ml_stack[stack_idx]);
+ idx = ip->ip_index;
+ if ((hp = mf_get(mfp, ip->ip_bnum, 1)) == NULL)
+ return FAIL;
+ pp = (PTR_BL *)(hp->bh_data); /* must be pointer block */
+ if (pp->pb_id != PTR_ID) {
+ EMSG(_("E317: pointer block id wrong 4"));
+ mf_put(mfp, hp, FALSE, FALSE);
+ return FAIL;
+ }
+ count = --(pp->pb_count);
+ if (count == 0) /* the pointer block becomes empty! */
+ mf_free(mfp, hp);
+ else {
+ if (count != idx) /* move entries after the deleted one */
+ mch_memmove(&pp->pb_pointer[idx], &pp->pb_pointer[idx + 1],
+ (size_t)(count - idx) * sizeof(PTR_EN));
+ mf_put(mfp, hp, TRUE, FALSE);
+
+ buf->b_ml.ml_stack_top = stack_idx; /* truncate stack */
+ /* fix line count for rest of blocks in the stack */
+ if (buf->b_ml.ml_locked_lineadd != 0) {
+ ml_lineadd(buf, buf->b_ml.ml_locked_lineadd);
+ buf->b_ml.ml_stack[buf->b_ml.ml_stack_top].ip_high +=
+ buf->b_ml.ml_locked_lineadd;
+ }
+ ++(buf->b_ml.ml_stack_top);
+
+ break;
+ }
+ }
+ CHECK(stack_idx < 0, _("deleted block 1?"));
+ } else {
+ /*
+ * delete the text by moving the next lines forwards
+ */
+ text_start = dp->db_txt_start;
+ mch_memmove((char *)dp + text_start + line_size,
+ (char *)dp + text_start, (size_t)(line_start - text_start));
+
+ /*
+ * delete the index by moving the next indexes backwards
+ * Adjust the indexes for the text movement.
+ */
+ for (i = idx; i < count - 1; ++i)
+ dp->db_index[i] = dp->db_index[i + 1] + line_size;
+
+ dp->db_free += line_size + INDEX_SIZE;
+ dp->db_txt_start += line_size;
+ --(dp->db_line_count);
+
+ /*
+ * mark the block dirty and make sure it is in the file (for recovery)
+ */
+ buf->b_ml.ml_flags |= (ML_LOCKED_DIRTY | ML_LOCKED_POS);
+ }
+
+ ml_updatechunk(buf, lnum, line_size, ML_CHNK_DELLINE);
+ return OK;
+}
+
+/*
+ * set the B_MARKED flag for line 'lnum'
+ */
+void ml_setmarked(lnum)
+linenr_T lnum;
+{
+ bhdr_T *hp;
+ DATA_BL *dp;
+ /* invalid line number */
+ if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count
+ || curbuf->b_ml.ml_mfp == NULL)
+ return; /* give error message? */
+
+ if (lowest_marked == 0 || lowest_marked > lnum)
+ lowest_marked = lnum;
+
+ /*
+ * find the data block containing the line
+ * This also fills the stack with the blocks from the root to the data block
+ * This also releases any locked block.
+ */
+ if ((hp = ml_find_line(curbuf, lnum, ML_FIND)) == NULL)
+ return; /* give error message? */
+
+ dp = (DATA_BL *)(hp->bh_data);
+ dp->db_index[lnum - curbuf->b_ml.ml_locked_low] |= DB_MARKED;
+ curbuf->b_ml.ml_flags |= ML_LOCKED_DIRTY;
+}
+
+/*
+ * find the first line with its B_MARKED flag set
+ */
+linenr_T ml_firstmarked() {
+ bhdr_T *hp;
+ DATA_BL *dp;
+ linenr_T lnum;
+ int i;
+
+ if (curbuf->b_ml.ml_mfp == NULL)
+ return (linenr_T) 0;
+
+ /*
+ * The search starts with lowest_marked line. This is the last line where
+ * a mark was found, adjusted by inserting/deleting lines.
+ */
+ for (lnum = lowest_marked; lnum <= curbuf->b_ml.ml_line_count; ) {
+ /*
+ * Find the data block containing the line.
+ * This also fills the stack with the blocks from the root to the data
+ * block This also releases any locked block.
+ */
+ if ((hp = ml_find_line(curbuf, lnum, ML_FIND)) == NULL)
+ return (linenr_T)0; /* give error message? */
+
+ dp = (DATA_BL *)(hp->bh_data);
+
+ for (i = lnum - curbuf->b_ml.ml_locked_low;
+ lnum <= curbuf->b_ml.ml_locked_high; ++i, ++lnum)
+ if ((dp->db_index[i]) & DB_MARKED) {
+ (dp->db_index[i]) &= DB_INDEX_MASK;
+ curbuf->b_ml.ml_flags |= ML_LOCKED_DIRTY;
+ lowest_marked = lnum + 1;
+ return lnum;
+ }
+ }
+
+ return (linenr_T) 0;
+}
+
+/*
+ * clear all DB_MARKED flags
+ */
+void ml_clearmarked() {
+ bhdr_T *hp;
+ DATA_BL *dp;
+ linenr_T lnum;
+ int i;
+
+ if (curbuf->b_ml.ml_mfp == NULL) /* nothing to do */
+ return;
+
+ /*
+ * The search starts with line lowest_marked.
+ */
+ for (lnum = lowest_marked; lnum <= curbuf->b_ml.ml_line_count; ) {
+ /*
+ * Find the data block containing the line.
+ * This also fills the stack with the blocks from the root to the data
+ * block and releases any locked block.
+ */
+ if ((hp = ml_find_line(curbuf, lnum, ML_FIND)) == NULL)
+ return; /* give error message? */
+
+ dp = (DATA_BL *)(hp->bh_data);
+
+ for (i = lnum - curbuf->b_ml.ml_locked_low;
+ lnum <= curbuf->b_ml.ml_locked_high; ++i, ++lnum)
+ if ((dp->db_index[i]) & DB_MARKED) {
+ (dp->db_index[i]) &= DB_INDEX_MASK;
+ curbuf->b_ml.ml_flags |= ML_LOCKED_DIRTY;
+ }
+ }
+
+ lowest_marked = 0;
+ return;
+}
+
+/*
+ * flush ml_line if necessary
+ */
+static void ml_flush_line(buf)
+buf_T *buf;
+{
+ bhdr_T *hp;
+ DATA_BL *dp;
+ linenr_T lnum;
+ char_u *new_line;
+ char_u *old_line;
+ colnr_T new_len;
+ int old_len;
+ int extra;
+ int idx;
+ int start;
+ int count;
+ int i;
+ static int entered = FALSE;
+
+ if (buf->b_ml.ml_line_lnum == 0 || buf->b_ml.ml_mfp == NULL)
+ return; /* nothing to do */
+
+ if (buf->b_ml.ml_flags & ML_LINE_DIRTY) {
+ /* This code doesn't work recursively, but Netbeans may call back here
+ * when obtaining the cursor position. */
+ if (entered)
+ return;
+ entered = TRUE;
+
+ lnum = buf->b_ml.ml_line_lnum;
+ new_line = buf->b_ml.ml_line_ptr;
+
+ hp = ml_find_line(buf, lnum, ML_FIND);
+ if (hp == NULL)
+ EMSGN(_("E320: Cannot find line %ld"), lnum);
+ else {
+ dp = (DATA_BL *)(hp->bh_data);
+ idx = lnum - buf->b_ml.ml_locked_low;
+ start = ((dp->db_index[idx]) & DB_INDEX_MASK);
+ old_line = (char_u *)dp + start;
+ if (idx == 0) /* line is last in block */
+ old_len = dp->db_txt_end - start;
+ else /* text of previous line follows */
+ old_len = (dp->db_index[idx - 1] & DB_INDEX_MASK) - start;
+ new_len = (colnr_T)STRLEN(new_line) + 1;
+ extra = new_len - old_len; /* negative if lines gets smaller */
+
+ /*
+ * if new line fits in data block, replace directly
+ */
+ if ((int)dp->db_free >= extra) {
+ /* if the length changes and there are following lines */
+ count = buf->b_ml.ml_locked_high - buf->b_ml.ml_locked_low + 1;
+ if (extra != 0 && idx < count - 1) {
+ /* move text of following lines */
+ mch_memmove((char *)dp + dp->db_txt_start - extra,
+ (char *)dp + dp->db_txt_start,
+ (size_t)(start - dp->db_txt_start));
+
+ /* adjust pointers of this and following lines */
+ for (i = idx + 1; i < count; ++i)
+ dp->db_index[i] -= extra;
+ }
+ dp->db_index[idx] -= extra;
+
+ /* adjust free space */
+ dp->db_free -= extra;
+ dp->db_txt_start -= extra;
+
+ /* copy new line into the data block */
+ mch_memmove(old_line - extra, new_line, (size_t)new_len);
+ buf->b_ml.ml_flags |= (ML_LOCKED_DIRTY | ML_LOCKED_POS);
+ /* The else case is already covered by the insert and delete */
+ ml_updatechunk(buf, lnum, (long)extra, ML_CHNK_UPDLINE);
+ } else {
+ /*
+ * Cannot do it in one data block: Delete and append.
+ * Append first, because ml_delete_int() cannot delete the
+ * last line in a buffer, which causes trouble for a buffer
+ * that has only one line.
+ * Don't forget to copy the mark!
+ */
+ /* How about handling errors??? */
+ (void)ml_append_int(buf, lnum, new_line, new_len, FALSE,
+ (dp->db_index[idx] & DB_MARKED));
+ (void)ml_delete_int(buf, lnum, FALSE);
+ }
+ }
+ vim_free(new_line);
+
+ entered = FALSE;
+ }
+
+ buf->b_ml.ml_line_lnum = 0;
+}
+
+/*
+ * create a new, empty, data block
+ */
+static bhdr_T * ml_new_data(mfp, negative, page_count)
+memfile_T *mfp;
+int negative;
+int page_count;
+{
+ bhdr_T *hp;
+ DATA_BL *dp;
+
+ if ((hp = mf_new(mfp, negative, page_count)) == NULL)
+ return NULL;
+
+ dp = (DATA_BL *)(hp->bh_data);
+ dp->db_id = DATA_ID;
+ dp->db_txt_start = dp->db_txt_end = page_count * mfp->mf_page_size;
+ dp->db_free = dp->db_txt_start - HEADER_SIZE;
+ dp->db_line_count = 0;
+
+ return hp;
+}
+
+/*
+ * create a new, empty, pointer block
+ */
+static bhdr_T * ml_new_ptr(mfp)
+memfile_T *mfp;
+{
+ bhdr_T *hp;
+ PTR_BL *pp;
+
+ if ((hp = mf_new(mfp, FALSE, 1)) == NULL)
+ return NULL;
+
+ pp = (PTR_BL *)(hp->bh_data);
+ pp->pb_id = PTR_ID;
+ pp->pb_count = 0;
+ pp->pb_count_max = (short_u)((mfp->mf_page_size - sizeof(PTR_BL))
+ / sizeof(PTR_EN) + 1);
+
+ return hp;
+}
+
+/*
+ * lookup line 'lnum' in a memline
+ *
+ * action: if ML_DELETE or ML_INSERT the line count is updated while searching
+ * if ML_FLUSH only flush a locked block
+ * if ML_FIND just find the line
+ *
+ * If the block was found it is locked and put in ml_locked.
+ * The stack is updated to lead to the locked block. The ip_high field in
+ * the stack is updated to reflect the last line in the block AFTER the
+ * insert or delete, also if the pointer block has not been updated yet. But
+ * if ml_locked != NULL ml_locked_lineadd must be added to ip_high.
+ *
+ * return: NULL for failure, pointer to block header otherwise
+ */
+static bhdr_T * ml_find_line(buf, lnum, action)
+buf_T *buf;
+linenr_T lnum;
+int action;
+{
+ DATA_BL *dp;
+ PTR_BL *pp;
+ infoptr_T *ip;
+ bhdr_T *hp;
+ memfile_T *mfp;
+ linenr_T t;
+ blocknr_T bnum, bnum2;
+ int dirty;
+ linenr_T low, high;
+ int top;
+ int page_count;
+ int idx;
+
+ mfp = buf->b_ml.ml_mfp;
+
+ /*
+ * If there is a locked block check if the wanted line is in it.
+ * If not, flush and release the locked block.
+ * Don't do this for ML_INSERT_SAME, because the stack need to be updated.
+ * Don't do this for ML_FLUSH, because we want to flush the locked block.
+ * Don't do this when 'swapfile' is reset, we want to load all the blocks.
+ */
+ 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 */
+ if (action == ML_INSERT) {
+ ++(buf->b_ml.ml_locked_lineadd);
+ ++(buf->b_ml.ml_locked_high);
+ } else if (action == ML_DELETE) {
+ --(buf->b_ml.ml_locked_lineadd);
+ --(buf->b_ml.ml_locked_high);
+ }
+ return buf->b_ml.ml_locked;
+ }
+
+ mf_put(mfp, buf->b_ml.ml_locked, buf->b_ml.ml_flags & ML_LOCKED_DIRTY,
+ buf->b_ml.ml_flags & ML_LOCKED_POS);
+ buf->b_ml.ml_locked = NULL;
+
+ /*
+ * If lines have been added or deleted in the locked block, need to
+ * update the line count in pointer blocks.
+ */
+ if (buf->b_ml.ml_locked_lineadd != 0)
+ ml_lineadd(buf, buf->b_ml.ml_locked_lineadd);
+ }
+
+ if (action == ML_FLUSH) /* nothing else to do */
+ return NULL;
+
+ bnum = 1; /* start at the root of the tree */
+ page_count = 1;
+ low = 1;
+ high = buf->b_ml.ml_line_count;
+
+ if (action == ML_FIND) { /* first try stack entries */
+ for (top = buf->b_ml.ml_stack_top - 1; top >= 0; --top) {
+ ip = &(buf->b_ml.ml_stack[top]);
+ if (ip->ip_low <= lnum && ip->ip_high >= lnum) {
+ bnum = ip->ip_bnum;
+ low = ip->ip_low;
+ high = ip->ip_high;
+ buf->b_ml.ml_stack_top = top; /* truncate stack at prev entry */
+ break;
+ }
+ }
+ if (top < 0)
+ buf->b_ml.ml_stack_top = 0; /* not found, start at the root */
+ } else /* ML_DELETE or ML_INSERT */
+ buf->b_ml.ml_stack_top = 0; /* start at the root */
+
+ /*
+ * search downwards in the tree until a data block is found
+ */
+ for (;; ) {
+ if ((hp = mf_get(mfp, bnum, page_count)) == NULL)
+ goto error_noblock;
+
+ /*
+ * update high for insert/delete
+ */
+ if (action == ML_INSERT)
+ ++high;
+ else if (action == ML_DELETE)
+ --high;
+
+ dp = (DATA_BL *)(hp->bh_data);
+ if (dp->db_id == DATA_ID) { /* data block */
+ buf->b_ml.ml_locked = hp;
+ buf->b_ml.ml_locked_low = low;
+ buf->b_ml.ml_locked_high = high;
+ buf->b_ml.ml_locked_lineadd = 0;
+ buf->b_ml.ml_flags &= ~(ML_LOCKED_DIRTY | ML_LOCKED_POS);
+ return hp;
+ }
+
+ pp = (PTR_BL *)(dp); /* must be pointer block */
+ if (pp->pb_id != PTR_ID) {
+ EMSG(_("E317: pointer block id wrong"));
+ goto error_block;
+ }
+
+ if ((top = ml_add_stack(buf)) < 0) /* add new entry to stack */
+ goto error_block;
+ ip = &(buf->b_ml.ml_stack[top]);
+ ip->ip_bnum = bnum;
+ ip->ip_low = low;
+ ip->ip_high = high;
+ ip->ip_index = -1; /* index not known yet */
+
+ dirty = FALSE;
+ for (idx = 0; idx < (int)pp->pb_count; ++idx) {
+ t = pp->pb_pointer[idx].pe_line_count;
+ CHECK(t == 0, _("pe_line_count is zero"));
+ if ((low += t) > lnum) {
+ ip->ip_index = idx;
+ bnum = pp->pb_pointer[idx].pe_bnum;
+ page_count = pp->pb_pointer[idx].pe_page_count;
+ high = low - 1;
+ low -= t;
+
+ /*
+ * a negative block number may have been changed
+ */
+ if (bnum < 0) {
+ bnum2 = mf_trans_del(mfp, bnum);
+ if (bnum != bnum2) {
+ bnum = bnum2;
+ pp->pb_pointer[idx].pe_bnum = bnum;
+ dirty = TRUE;
+ }
+ }
+
+ 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: %ld past the end"),
+ lnum - buf->b_ml.ml_line_count);
+
+ else
+ EMSGN(_("E323: line count wrong in block %ld"), bnum);
+ goto error_block;
+ }
+ if (action == ML_DELETE) {
+ pp->pb_pointer[idx].pe_line_count--;
+ dirty = TRUE;
+ } else if (action == ML_INSERT) {
+ pp->pb_pointer[idx].pe_line_count++;
+ dirty = TRUE;
+ }
+ mf_put(mfp, hp, dirty, FALSE);
+ }
+
+error_block:
+ mf_put(mfp, hp, FALSE, FALSE);
+error_noblock:
+ /*
+ * If action is ML_DELETE or ML_INSERT we have to correct the tree for
+ * the incremented/decremented line counts, because there won't be a line
+ * inserted/deleted after all.
+ */
+ if (action == ML_DELETE)
+ ml_lineadd(buf, 1);
+ else if (action == ML_INSERT)
+ ml_lineadd(buf, -1);
+ buf->b_ml.ml_stack_top = 0;
+ return NULL;
+}
+
+/*
+ * add an entry to the info pointer stack
+ *
+ * return -1 for failure, number of the new entry otherwise
+ */
+static int ml_add_stack(buf)
+buf_T *buf;
+{
+ int top;
+ infoptr_T *newstack;
+
+ top = buf->b_ml.ml_stack_top;
+
+ /* may have to increase the stack size */
+ if (top == buf->b_ml.ml_stack_size) {
+ CHECK(top > 0, _("Stack size increases")); /* more than 5 levels??? */
+
+ newstack = (infoptr_T *)alloc((unsigned)sizeof(infoptr_T) *
+ (buf->b_ml.ml_stack_size + STACK_INCR));
+ if (newstack == NULL)
+ return -1;
+ mch_memmove(newstack, buf->b_ml.ml_stack,
+ (size_t)top * sizeof(infoptr_T));
+ vim_free(buf->b_ml.ml_stack);
+ buf->b_ml.ml_stack = newstack;
+ buf->b_ml.ml_stack_size += STACK_INCR;
+ }
+
+ buf->b_ml.ml_stack_top++;
+ return top;
+}
+
+/*
+ * Update the pointer blocks on the stack for inserted/deleted lines.
+ * The stack itself is also updated.
+ *
+ * When a insert/delete line action fails, the line is not inserted/deleted,
+ * but the pointer blocks have already been updated. That is fixed here by
+ * walking through the stack.
+ *
+ * Count is the number of lines added, negative if lines have been deleted.
+ */
+static void ml_lineadd(buf, count)
+buf_T *buf;
+int count;
+{
+ int idx;
+ infoptr_T *ip;
+ PTR_BL *pp;
+ memfile_T *mfp = buf->b_ml.ml_mfp;
+ bhdr_T *hp;
+
+ for (idx = buf->b_ml.ml_stack_top - 1; idx >= 0; --idx) {
+ ip = &(buf->b_ml.ml_stack[idx]);
+ if ((hp = mf_get(mfp, ip->ip_bnum, 1)) == NULL)
+ break;
+ pp = (PTR_BL *)(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"));
+ break;
+ }
+ pp->pb_pointer[ip->ip_index].pe_line_count += count;
+ ip->ip_high += count;
+ mf_put(mfp, hp, TRUE, FALSE);
+ }
+}
+
+#if defined(HAVE_READLINK) || defined(PROTO)
+/*
+ * Resolve a symlink in the last component of a file name.
+ * Note that f_resolve() does it for every part of the path, we don't do that
+ * here.
+ * If it worked returns OK and the resolved link in "buf[MAXPATHL]".
+ * Otherwise returns FAIL.
+ */
+int resolve_symlink(fname, buf)
+char_u *fname;
+char_u *buf;
+{
+ char_u tmp[MAXPATHL];
+ int ret;
+ int depth = 0;
+
+ if (fname == NULL)
+ return FAIL;
+
+ /* Put the result so far in tmp[], starting with the original name. */
+ vim_strncpy(tmp, fname, MAXPATHL - 1);
+
+ for (;; ) {
+ /* Limit symlink depth to 100, catch recursive loops. */
+ if (++depth == 100) {
+ EMSG2(_("E773: Symlink loop for \"%s\""), fname);
+ return FAIL;
+ }
+
+ ret = readlink((char *)tmp, (char *)buf, MAXPATHL - 1);
+ if (ret <= 0) {
+ if (errno == EINVAL || errno == ENOENT) {
+ /* Found non-symlink or not existing file, stop here.
+ * When at the first level use the unmodified name, skip the
+ * call to vim_FullName(). */
+ if (depth == 1)
+ return FAIL;
+
+ /* Use the resolved name in tmp[]. */
+ break;
+ }
+
+ /* There must be some error reading links, use original name. */
+ return FAIL;
+ }
+ 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 (mch_isFullName(buf))
+ STRCPY(tmp, buf);
+ else {
+ char_u *tail;
+
+ tail = gettail(tmp);
+ if (STRLEN(tail) + STRLEN(buf) >= MAXPATHL)
+ return FAIL;
+ STRCPY(tail, buf);
+ }
+ }
+
+ /*
+ * Try to resolve the full name of the file so that the swapfile name will
+ * be consistent even when opening a relative symlink from different
+ * working directories.
+ */
+ return vim_FullName(tmp, buf, MAXPATHL, TRUE);
+}
+#endif
+
+/*
+ * Make swap file name out of the file name and a directory name.
+ * Returns pointer to allocated memory or NULL.
+ */
+char_u * makeswapname(fname, ffname, buf, dir_name)
+char_u *fname;
+char_u *ffname UNUSED;
+buf_T *buf;
+char_u *dir_name;
+{
+ char_u *r, *s;
+ char_u *fname_res = fname;
+#ifdef HAVE_READLINK
+ char_u fname_buf[MAXPATHL];
+#endif
+
+#if defined(UNIX) || defined(WIN3264) /* Need _very_ long file names */
+ s = dir_name + STRLEN(dir_name);
+ if (after_pathsep(dir_name, s) && s[-1] == s[-2]) { /* Ends with '//', Use Full path */
+ r = NULL;
+ if ((s = make_percent_swname(dir_name, fname)) != NULL) {
+ r = modname(s, (char_u *)".swp", FALSE);
+ vim_free(s);
+ }
+ return r;
+ }
+#endif
+
+#ifdef HAVE_READLINK
+ /* Expand symlink in the file name, so that we put the swap file with the
+ * actual file instead of with the symlink. */
+ if (resolve_symlink(fname, fname_buf) == OK)
+ fname_res = fname_buf;
+#endif
+
+ r = buf_modname(
+#ifdef SHORT_FNAME
+ TRUE,
+#else
+ (buf->b_p_sn || buf->b_shortname),
+#endif
+ fname_res,
+ (char_u *)
+ ".swp",
+#ifdef SHORT_FNAME /* always 8.3 file name */
+ FALSE
+#else
+ /* Prepend a '.' to the swap file name for the current directory. */
+ dir_name[0] == '.' && dir_name[1] == NUL
+#endif
+ );
+ if (r == NULL) /* out of memory */
+ return NULL;
+
+ s = get_file_in_dir(r, dir_name);
+ vim_free(r);
+ return s;
+}
+
+/*
+ * Get file name to use for swap file or backup file.
+ * Use the name of the edited file "fname" and an entry in the 'dir' or 'bdir'
+ * option "dname".
+ * - If "dname" is ".", return "fname" (swap file in dir of file).
+ * - If "dname" starts with "./", insert "dname" in "fname" (swap file
+ * relative to dir of file).
+ * - Otherwise, prepend "dname" to the tail of "fname" (swap file in specific
+ * dir).
+ *
+ * The return value is an allocated string and can be NULL.
+ */
+char_u * get_file_in_dir(fname, dname)
+char_u *fname;
+char_u *dname; /* don't use "dirname", it is a global for Alpha */
+{
+ char_u *t;
+ char_u *tail;
+ char_u *retval;
+ int save_char;
+
+ tail = gettail(fname);
+
+ if (dname[0] == '.' && dname[1] == NUL)
+ retval = vim_strsave(fname);
+ else if (dname[0] == '.' && vim_ispathsep(dname[1])) {
+ if (tail == fname) /* no path before file name */
+ retval = concat_fnames(dname + 2, tail, TRUE);
+ else {
+ save_char = *tail;
+ *tail = NUL;
+ t = concat_fnames(fname, dname + 2, TRUE);
+ *tail = save_char;
+ if (t == NULL) /* out of memory */
+ retval = NULL;
+ else {
+ retval = concat_fnames(t, tail, TRUE);
+ vim_free(t);
+ }
+ }
+ } else
+ retval = concat_fnames(dname, tail, TRUE);
+
+
+ return retval;
+}
+
+static void attention_message __ARGS((buf_T *buf, char_u *fname));
+
+/*
+ * Print the ATTENTION message: info about an existing swap file.
+ */
+static void attention_message(buf, fname)
+buf_T *buf; /* buffer being edited */
+char_u *fname; /* swap file name */
+{
+ struct stat st;
+ time_t x, sx;
+ char *p;
+
+ ++no_wait_return;
+ (void)EMSG(_("E325: ATTENTION"));
+ MSG_PUTS(_("\nFound a swap file by the name \""));
+ msg_home_replace(fname);
+ MSG_PUTS("\"\n");
+ sx = swapfile_info(fname);
+ MSG_PUTS(_("While opening file \""));
+ msg_outtrans(buf->b_fname);
+ MSG_PUTS("\"\n");
+ if (mch_stat((char *)buf->b_fname, &st) != -1) {
+ MSG_PUTS(_(" dated: "));
+ x = st.st_mtime; /* Manx C can't do &st.st_mtime */
+ p = ctime(&x); /* includes '\n' */
+ if (p == NULL)
+ MSG_PUTS("(invalid)\n");
+ else
+ MSG_PUTS(p);
+ if (sx != 0 && x > sx)
+ MSG_PUTS(_(" NEWER than swap file!\n"));
+ }
+ /* 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(_("(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);
+ MSG_PUTS(_("\"\n to recover the changes (see \":help recovery\").\n"));
+ MSG_PUTS(_(" If you did this already, delete the swap file \""));
+ msg_outtrans(fname);
+ MSG_PUTS(_("\"\n to avoid this message.\n"));
+ cmdline_row = msg_row;
+ --no_wait_return;
+}
+
+static int do_swapexists __ARGS((buf_T *buf, char_u *fname));
+
+/*
+ * Trigger the SwapExists autocommands.
+ * Returns a value for equivalent to do_dialog() (see below):
+ * 0: still need to ask for a choice
+ * 1: open read-only
+ * 2: edit anyway
+ * 3: recover
+ * 4: delete it
+ * 5: quit
+ * 6: abort
+ */
+static int do_swapexists(buf, fname)
+buf_T *buf;
+char_u *fname;
+{
+ set_vim_var_string(VV_SWAPNAME, fname, -1);
+ set_vim_var_string(VV_SWAPCHOICE, NULL, -1);
+
+ /* Trigger SwapExists autocommands with <afile> set to the file being
+ * edited. Disallow changing directory here. */
+ ++allbuf_lock;
+ apply_autocmds(EVENT_SWAPEXISTS, buf->b_fname, NULL, FALSE, NULL);
+ --allbuf_lock;
+
+ set_vim_var_string(VV_SWAPNAME, NULL, -1);
+
+ switch (*get_vim_var_str(VV_SWAPCHOICE)) {
+ case 'o': return 1;
+ case 'e': return 2;
+ case 'r': return 3;
+ case 'd': return 4;
+ case 'q': return 5;
+ case 'a': return 6;
+ }
+
+ return 0;
+}
+
+/*
+ * Find out what name to use for the swap file for buffer 'buf'.
+ *
+ * Several names are tried to find one that does not exist
+ * Returns the name in allocated memory or NULL.
+ * When out of memory "dirp" is set to NULL.
+ *
+ * Note: If BASENAMELEN is not correct, you will get error messages for
+ * not being able to open the swap or undo file
+ * Note: May trigger SwapExists autocmd, pointers may change!
+ */
+static char_u * findswapname(buf, dirp, old_fname)
+buf_T *buf;
+char_u **dirp; /* pointer to list of directories */
+char_u *old_fname; /* don't give warning for this file name */
+{
+ char_u *fname;
+ int n;
+ char_u *dir_name;
+#ifndef SHORT_FNAME
+ int r;
+#endif
+ char_u *buf_fname = buf->b_fname;
+
+#if !defined(SHORT_FNAME) \
+ && ((!defined(UNIX) && !defined(OS2)) || defined(ARCHIE))
+# define CREATE_DUMMY_FILE
+ FILE *dummyfd = NULL;
+
+
+ /*
+ * If we start editing a new file, e.g. "test.doc", which resides on an
+ * MSDOS compatible filesystem, it is possible that the file
+ * "test.doc.swp" which we create will be exactly the same file. To avoid
+ * this problem we temporarily create "test.doc". Don't do this when the
+ * check below for a 8.3 file name is used.
+ */
+ if (!(buf->b_p_sn || buf->b_shortname) && buf_fname != NULL
+ && mch_getperm(buf_fname) < 0)
+ dummyfd = mch_fopen((char *)buf_fname, "w");
+#endif
+
+ /*
+ * Isolate a directory name from *dirp and put it in dir_name.
+ * First allocate some memory to put the directory name in.
+ */
+ dir_name = alloc((unsigned)STRLEN(*dirp) + 1);
+ if (dir_name == NULL)
+ *dirp = NULL;
+ else
+ (void)copy_option_part(dirp, dir_name, 31000, ",");
+
+ /*
+ * we try different names until we find one that does not exist yet
+ */
+ if (dir_name == NULL) /* out of memory */
+ fname = NULL;
+ else
+ fname = makeswapname(buf_fname, buf->b_ffname, buf, dir_name);
+
+ for (;; ) {
+ if (fname == NULL) /* must be out of memory */
+ break;
+ if ((n = (int)STRLEN(fname)) == 0) { /* safety check */
+ vim_free(fname);
+ fname = NULL;
+ break;
+ }
+#if (defined(UNIX) || defined(OS2)) && !defined(ARCHIE) && !defined(SHORT_FNAME)
+ /*
+ * Some systems have a MS-DOS compatible filesystem that use 8.3 character
+ * file names. If this is the first try and the swap file name does not fit in
+ * 8.3, detect if this is the case, set shortname and try again.
+ */
+ if (fname[n - 2] == 'w' && fname[n - 1] == 'p'
+ && !(buf->b_p_sn || buf->b_shortname)) {
+ char_u *tail;
+ char_u *fname2;
+ struct stat s1, s2;
+ int f1, f2;
+ int created1 = FALSE, created2 = FALSE;
+ int same = FALSE;
+
+ /*
+ * Check if swapfile name does not fit in 8.3:
+ * It either contains two dots, is longer than 8 chars, or starts
+ * with a dot.
+ */
+ tail = gettail(buf_fname);
+ if ( vim_strchr(tail, '.') != NULL
+ || STRLEN(tail) > (size_t)8
+ || *gettail(fname) == '.') {
+ fname2 = alloc(n + 2);
+ if (fname2 != NULL) {
+ STRCPY(fname2, fname);
+ /* if fname == "xx.xx.swp", fname2 = "xx.xx.swx"
+ * if fname == ".xx.swp", fname2 = ".xx.swpx"
+ * if fname == "123456789.swp", fname2 = "12345678x.swp"
+ */
+ if (vim_strchr(tail, '.') != NULL)
+ fname2[n - 1] = 'x';
+ else if (*gettail(fname) == '.') {
+ fname2[n] = 'x';
+ fname2[n + 1] = NUL;
+ } else
+ fname2[n - 5] += 1;
+ /*
+ * may need to create the files to be able to use mch_stat()
+ */
+ f1 = mch_open((char *)fname, O_RDONLY | O_EXTRA, 0);
+ if (f1 < 0) {
+ f1 = mch_open_rw((char *)fname,
+ O_RDWR|O_CREAT|O_EXCL|O_EXTRA);
+ created1 = TRUE;
+ }
+ if (f1 >= 0) {
+ f2 = mch_open((char *)fname2, O_RDONLY | O_EXTRA, 0);
+ if (f2 < 0) {
+ f2 = mch_open_rw((char *)fname2,
+ O_RDWR|O_CREAT|O_EXCL|O_EXTRA);
+ created2 = TRUE;
+ }
+ if (f2 >= 0) {
+ /*
+ * Both files exist now. If mch_stat() returns the
+ * same device and inode they are the same file.
+ */
+ if (mch_fstat(f1, &s1) != -1
+ && mch_fstat(f2, &s2) != -1
+ && s1.st_dev == s2.st_dev
+ && s1.st_ino == s2.st_ino)
+ same = TRUE;
+ close(f2);
+ if (created2)
+ mch_remove(fname2);
+ }
+ close(f1);
+ if (created1)
+ mch_remove(fname);
+ }
+ vim_free(fname2);
+ if (same) {
+ buf->b_shortname = TRUE;
+ vim_free(fname);
+ fname = makeswapname(buf_fname, buf->b_ffname,
+ buf, dir_name);
+ continue; /* try again with b_shortname set */
+ }
+ }
+ }
+ }
+#endif
+ /*
+ * check if the swapfile already exists
+ */
+ if (mch_getperm(fname) < 0) { /* it does not exist */
+#ifdef HAVE_LSTAT
+ struct stat sb;
+
+ /*
+ * Extra security check: When a swap file is a symbolic link, this
+ * is most likely a symlink attack.
+ */
+ if (mch_lstat((char *)fname, &sb) < 0)
+#else
+#endif
+ break;
+ }
+
+ /*
+ * A file name equal to old_fname is OK to use.
+ */
+ if (old_fname != NULL && fnamecmp(fname, old_fname) == 0)
+ break;
+
+ /*
+ * get here when file already exists
+ */
+ if (fname[n - 2] == 'w' && fname[n - 1] == 'p') { /* first try */
+#ifndef SHORT_FNAME
+ /*
+ * on MS-DOS compatible filesystems (e.g. messydos) file.doc.swp
+ * and file.doc are the same file. To guess if this problem is
+ * present try if file.doc.swx exists. If it does, we set
+ * buf->b_shortname and try file_doc.swp (dots replaced by
+ * underscores for this file), and try again. If it doesn't we
+ * assume that "file.doc.swp" already exists.
+ */
+ if (!(buf->b_p_sn || buf->b_shortname)) { /* not tried yet */
+ fname[n - 1] = 'x';
+ r = mch_getperm(fname); /* try "file.swx" */
+ fname[n - 1] = 'p';
+ if (r >= 0) { /* "file.swx" seems to exist */
+ buf->b_shortname = TRUE;
+ vim_free(fname);
+ fname = makeswapname(buf_fname, buf->b_ffname,
+ buf, dir_name);
+ continue; /* try again with '.' replaced with '_' */
+ }
+ }
+#endif
+ /*
+ * If we get here the ".swp" file really exists.
+ * Give an error message, unless recovering, no file name, we are
+ * viewing a help file or when the path of the file is different
+ * (happens when all .swp files are in one directory).
+ */
+ if (!recoverymode && buf_fname != NULL
+ && !buf->b_help && !(buf->b_flags & BF_DUMMY)) {
+ int fd;
+ struct block0 b0;
+ int differ = FALSE;
+
+ /*
+ * Try to read block 0 from the swap file to get the original
+ * file name (and inode number).
+ */
+ fd = mch_open((char *)fname, O_RDONLY | O_EXTRA, 0);
+ if (fd >= 0) {
+ if (read_eintr(fd, &b0, sizeof(b0)) == sizeof(b0)) {
+ /*
+ * If the swapfile has the same directory as the
+ * buffer don't compare the directory names, they can
+ * have a different mountpoint.
+ */
+ if (b0.b0_flags & B0_SAME_DIR) {
+ if (fnamecmp(gettail(buf->b_ffname),
+ gettail(b0.b0_fname)) != 0
+ || !same_directory(fname, buf->b_ffname)) {
+#ifdef CHECK_INODE
+ /* Symlinks may point to the same file even
+ * when the name differs, need to check the
+ * inode too. */
+ expand_env(b0.b0_fname, NameBuff, MAXPATHL);
+ if (fnamecmp_ino(buf->b_ffname, NameBuff,
+ char_to_long(b0.b0_ino)))
+#endif
+ differ = TRUE;
+ }
+ } else {
+ /*
+ * The name in the swap file may be
+ * "~user/path/file". Expand it first.
+ */
+ expand_env(b0.b0_fname, NameBuff, MAXPATHL);
+#ifdef CHECK_INODE
+ if (fnamecmp_ino(buf->b_ffname, NameBuff,
+ char_to_long(b0.b0_ino)))
+ differ = TRUE;
+#else
+ if (fnamecmp(NameBuff, buf->b_ffname) != 0)
+ differ = TRUE;
+#endif
+ }
+ }
+ close(fd);
+ }
+
+ /* give the ATTENTION message when there is an old swap file
+ * for the current file, and the buffer was not recovered. */
+ if (differ == FALSE && !(curbuf->b_flags & BF_RECOVERED)
+ && vim_strchr(p_shm, SHM_ATTENTION) == NULL) {
+#if defined(HAS_SWAP_EXISTS_ACTION)
+ int choice = 0;
+#endif
+#ifdef CREATE_DUMMY_FILE
+ int did_use_dummy = FALSE;
+
+ /* Avoid getting a warning for the file being created
+ * outside of Vim, it was created at the start of this
+ * function. Delete the file now, because Vim might exit
+ * here if the window is closed. */
+ if (dummyfd != NULL) {
+ fclose(dummyfd);
+ dummyfd = NULL;
+ mch_remove(buf_fname);
+ did_use_dummy = TRUE;
+ }
+#endif
+
+#if (defined(UNIX) || defined(__EMX__) || defined(VMS)) && \
+ (defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG))
+ process_still_running = FALSE;
+#endif
+ /*
+ * If there is an SwapExists autocommand and we can handle
+ * the response, trigger it. It may return 0 to ask the
+ * user anyway.
+ */
+ if (swap_exists_action != SEA_NONE
+ && has_autocmd(EVENT_SWAPEXISTS, buf_fname, buf))
+ choice = do_swapexists(buf, fname);
+
+ if (choice == 0) {
+ /* Show info about the existing swap file. */
+ attention_message(buf, fname);
+
+ /* We don't want a 'q' typed at the more-prompt
+ * interrupt loading a file. */
+ got_int = FALSE;
+ }
+
+ if (swap_exists_action != SEA_NONE && choice == 0) {
+ char_u *name;
+
+ name = alloc((unsigned)(STRLEN(fname)
+ + STRLEN(_("Swap file \""))
+ + STRLEN(_("\" already exists!")) + 5));
+ if (name != NULL) {
+ STRCPY(name, _("Swap file \""));
+ home_replace(NULL, fname, name + STRLEN(name),
+ 1000, TRUE);
+ STRCAT(name, _("\" already exists!"));
+ }
+ choice = do_dialog(VIM_WARNING,
+ (char_u *)_("VIM - ATTENTION"),
+ name == NULL
+ ? (char_u *)_("Swap file already exists!")
+ : name,
+# if defined(UNIX) || defined(__EMX__) || defined(VMS)
+ 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);
+
+# if defined(UNIX) || defined(__EMX__) || defined(VMS)
+ if (process_still_running && choice >= 4)
+ choice++; /* Skip missing "Delete it" button */
+# endif
+ vim_free(name);
+
+ /* pretend screen didn't scroll, need redraw anyway */
+ msg_scrolled = 0;
+ redraw_all_later(NOT_VALID);
+ }
+
+#if defined(HAS_SWAP_EXISTS_ACTION)
+ if (choice > 0) {
+ switch (choice) {
+ case 1:
+ buf->b_p_ro = TRUE;
+ break;
+ case 2:
+ break;
+ case 3:
+ swap_exists_action = SEA_RECOVER;
+ break;
+ case 4:
+ mch_remove(fname);
+ break;
+ case 5:
+ swap_exists_action = SEA_QUIT;
+ break;
+ case 6:
+ swap_exists_action = SEA_QUIT;
+ got_int = TRUE;
+ break;
+ }
+
+ /* If the file was deleted this fname can be used. */
+ if (mch_getperm(fname) < 0)
+ break;
+ } else
+#endif
+ {
+ MSG_PUTS("\n");
+ if (msg_silent == 0)
+ /* call wait_return() later */
+ need_wait_return = TRUE;
+ }
+
+#ifdef CREATE_DUMMY_FILE
+ /* Going to try another name, need the dummy file again. */
+ if (did_use_dummy)
+ dummyfd = mch_fopen((char *)buf_fname, "w");
+#endif
+ }
+ }
+ }
+
+ /*
+ * 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.
+ */
+ if (fname[n - 1] == 'a') { /* ".s?a" */
+ if (fname[n - 2] == 'a') { /* ".saa": tried enough, give up */
+ EMSG(_("E326: Too many swap files found"));
+ vim_free(fname);
+ fname = NULL;
+ break;
+ }
+ --fname[n - 2]; /* ".svz", ".suz", etc. */
+ fname[n - 1] = 'z' + 1;
+ }
+ --fname[n - 1]; /* ".swo", ".swn", etc. */
+ }
+
+ vim_free(dir_name);
+#ifdef CREATE_DUMMY_FILE
+ if (dummyfd != NULL) { /* file has been created temporarily */
+ fclose(dummyfd);
+ mch_remove(buf_fname);
+ }
+#endif
+ return fname;
+}
+
+static int b0_magic_wrong(b0p)
+ZERO_BL *b0p;
+{
+ return b0p->b0_magic_long != (long)B0_MAGIC_LONG
+ || b0p->b0_magic_int != (int)B0_MAGIC_INT
+ || b0p->b0_magic_short != (short)B0_MAGIC_SHORT
+ || b0p->b0_magic_char != B0_MAGIC_CHAR;
+}
+
+#ifdef CHECK_INODE
+/*
+ * Compare current file name with file name from swap file.
+ * Try to use inode numbers when possible.
+ * Return non-zero when files are different.
+ *
+ * When comparing file names a few things have to be taken into consideration:
+ * - When working over a network the full path of a file depends on the host.
+ * We check the inode number if possible. It is not 100% reliable though,
+ * because the device number cannot be used over a network.
+ * - When a file does not exist yet (editing a new file) there is no inode
+ * number.
+ * - The file name in a swap file may not be valid on the current host. The
+ * "~user" form is used whenever possible to avoid this.
+ *
+ * This is getting complicated, let's make a table:
+ *
+ * ino_c ino_s fname_c fname_s differ =
+ *
+ * both files exist -> compare inode numbers:
+ * != 0 != 0 X X ino_c != ino_s
+ *
+ * inode number(s) unknown, file names available -> compare file names
+ * == 0 X OK OK fname_c != fname_s
+ * X == 0 OK OK fname_c != fname_s
+ *
+ * current file doesn't exist, file for swap file exist, file name(s) not
+ * available -> probably different
+ * == 0 != 0 FAIL X TRUE
+ * == 0 != 0 X FAIL TRUE
+ *
+ * current file exists, inode for swap unknown, file name(s) not
+ * available -> probably different
+ * != 0 == 0 FAIL X TRUE
+ * != 0 == 0 X FAIL TRUE
+ *
+ * current file doesn't exist, inode for swap unknown, one file name not
+ * available -> probably different
+ * == 0 == 0 FAIL OK TRUE
+ * == 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
+ *
+ * Note that when the ino_t is 64 bits, only the last 32 will be used. This
+ * can't be changed without making the block 0 incompatible with 32 bit
+ * versions.
+ */
+
+static int fnamecmp_ino(fname_c, fname_s, ino_block0)
+char_u *fname_c; /* current file name */
+char_u *fname_s; /* file name from swap file */
+long ino_block0;
+{
+ struct stat st;
+ ino_t ino_c = 0; /* ino of current file */
+ ino_t ino_s; /* ino of file from swap file */
+ char_u buf_c[MAXPATHL]; /* full path of fname_c */
+ char_u buf_s[MAXPATHL]; /* full path of fname_s */
+ int retval_c; /* flag: buf_c valid */
+ int retval_s; /* flag: buf_s valid */
+
+ if (mch_stat((char *)fname_c, &st) == 0)
+ ino_c = (ino_t)st.st_ino;
+
+ /*
+ * First we try to get the inode from the file name, because the inode in
+ * the swap file may be outdated. If that fails (e.g. this path is not
+ * valid on this machine), use the inode from block 0.
+ */
+ if (mch_stat((char *)fname_s, &st) == 0)
+ ino_s = (ino_t)st.st_ino;
+ else
+ ino_s = (ino_t)ino_block0;
+
+ if (ino_c && ino_s)
+ return ino_c != ino_s;
+
+ /*
+ * One of the inode numbers is unknown, try a forced vim_FullName() and
+ * compare the file names.
+ */
+ retval_c = vim_FullName(fname_c, buf_c, MAXPATHL, TRUE);
+ retval_s = vim_FullName(fname_s, buf_s, MAXPATHL, TRUE);
+ if (retval_c == OK && retval_s == OK)
+ return STRCMP(buf_c, buf_s) != 0;
+
+ /*
+ * Can't compare inodes or file names, guess that the files are different,
+ * unless both appear not to exist at all.
+ */
+ if (ino_s == 0 && ino_c == 0 && retval_c == FAIL && retval_s == FAIL)
+ return FALSE;
+ return TRUE;
+}
+#endif /* CHECK_INODE */
+
+/*
+ * Move a long integer into a four byte character array.
+ * Used for machine independency in block zero.
+ */
+static void long_to_char(n, s)
+long n;
+char_u *s;
+{
+ s[0] = (char_u)(n & 0xff);
+ n = (unsigned)n >> 8;
+ s[1] = (char_u)(n & 0xff);
+ n = (unsigned)n >> 8;
+ s[2] = (char_u)(n & 0xff);
+ n = (unsigned)n >> 8;
+ s[3] = (char_u)(n & 0xff);
+}
+
+static long char_to_long(s)
+char_u *s;
+{
+ long retval;
+
+ retval = s[3];
+ retval <<= 8;
+ retval |= s[2];
+ retval <<= 8;
+ retval |= s[1];
+ retval <<= 8;
+ retval |= s[0];
+
+ return retval;
+}
+
+/*
+ * Set the flags in the first block of the swap file:
+ * - file is modified or not: buf->b_changed
+ * - 'fileformat'
+ * - 'fileencoding'
+ */
+void ml_setflags(buf)
+buf_T *buf;
+{
+ bhdr_T *hp;
+ ZERO_BL *b0p;
+
+ if (!buf->b_ml.ml_mfp)
+ return;
+ for (hp = buf->b_ml.ml_mfp->mf_used_last; hp != NULL; hp = hp->bh_prev) {
+ if (hp->bh_bnum == 0) {
+ b0p = (ZERO_BL *)(hp->bh_data);
+ b0p->b0_dirty = buf->b_changed ? B0_DIRTY : 0;
+ b0p->b0_flags = (b0p->b0_flags & ~B0_FF_MASK)
+ | (get_fileformat(buf) + 1);
+ add_b0_fenc(b0p, buf);
+ hp->bh_flags |= BH_DIRTY;
+ mf_sync(buf->b_ml.ml_mfp, MFS_ZERO);
+ break;
+ }
+ }
+}
+
+/*
+ * If "data" points to a data block encrypt the text in it and return a copy
+ * in allocated memory. Return NULL when out of memory.
+ * Otherwise return "data".
+ */
+char_u * ml_encrypt_data(mfp, data, offset, size)
+memfile_T *mfp;
+char_u *data;
+off_t offset;
+unsigned size;
+{
+ DATA_BL *dp = (DATA_BL *)data;
+ char_u *head_end;
+ char_u *text_start;
+ char_u *new_data;
+ int text_len;
+
+ if (dp->db_id != DATA_ID)
+ return data;
+
+ new_data = (char_u *)alloc(size);
+ if (new_data == NULL)
+ return NULL;
+ head_end = (char_u *)(&dp->db_index[dp->db_line_count]);
+ text_start = (char_u *)dp + dp->db_txt_start;
+ text_len = size - dp->db_txt_start;
+
+ /* Copy the header and the text. */
+ mch_memmove(new_data, dp, head_end - (char_u *)dp);
+
+ /* Encrypt the text. */
+ crypt_push_state();
+ ml_crypt_prepare(mfp, offset, FALSE);
+ crypt_encode(text_start, text_len, new_data + dp->db_txt_start);
+ crypt_pop_state();
+
+ /* Clear the gap. */
+ if (head_end < text_start)
+ vim_memset(new_data + (head_end - data), 0, text_start - head_end);
+
+ return new_data;
+}
+
+/*
+ * Decrypt the text in "data" if it points to a data block.
+ */
+void ml_decrypt_data(mfp, data, offset, size)
+memfile_T *mfp;
+char_u *data;
+off_t offset;
+unsigned size;
+{
+ DATA_BL *dp = (DATA_BL *)data;
+ char_u *head_end;
+ char_u *text_start;
+ int text_len;
+
+ if (dp->db_id == DATA_ID) {
+ head_end = (char_u *)(&dp->db_index[dp->db_line_count]);
+ text_start = (char_u *)dp + dp->db_txt_start;
+ text_len = dp->db_txt_end - dp->db_txt_start;
+
+ if (head_end > text_start || dp->db_txt_start > size
+ || dp->db_txt_end > size)
+ return; /* data was messed up */
+
+ /* Decrypt the text in place. */
+ crypt_push_state();
+ ml_crypt_prepare(mfp, offset, TRUE);
+ crypt_decode(text_start, text_len);
+ crypt_pop_state();
+ }
+}
+
+/*
+ * Prepare for encryption/decryption, using the key, seed and offset.
+ */
+static void ml_crypt_prepare(mfp, offset, reading)
+memfile_T *mfp;
+off_t offset;
+int reading;
+{
+ buf_T *buf = mfp->mf_buffer;
+ char_u salt[50];
+ int method;
+ char_u *key;
+ char_u *seed;
+
+ if (reading && mfp->mf_old_key != NULL) {
+ /* Reading back blocks with the previous key/method/seed. */
+ method = mfp->mf_old_cm;
+ key = mfp->mf_old_key;
+ seed = mfp->mf_old_seed;
+ } else {
+ method = get_crypt_method(buf);
+ key = buf->b_p_key;
+ seed = mfp->mf_seed;
+ }
+
+ use_crypt_method = method; /* select pkzip or blowfish */
+ if (method == 0) {
+ vim_snprintf((char *)salt, sizeof(salt), "%s%ld", key, (long)offset);
+ crypt_init_keys(salt);
+ } else {
+ /* Using blowfish, add salt and seed. We use the byte offset of the
+ * block for the salt. */
+ vim_snprintf((char *)salt, sizeof(salt), "%ld", (long)offset);
+ bf_key_init(key, salt, (int)STRLEN(salt));
+ bf_ofb_init(seed, MF_SEED_LEN);
+ }
+}
+
+
+
+
+#define MLCS_MAXL 800 /* max no of lines in chunk */
+#define MLCS_MINL 400 /* should be half of MLCS_MAXL */
+
+/*
+ * Keep information for finding byte offset of a line, updtype may be one of:
+ * ML_CHNK_ADDLINE: Add len to parent chunk, possibly splitting it
+ * Careful: ML_CHNK_ADDLINE may cause ml_find_line() to be called.
+ * ML_CHNK_DELLINE: Subtract len from parent chunk, possibly deleting it
+ * ML_CHNK_UPDLINE: Add len to parent chunk, as a signed entity.
+ */
+static void ml_updatechunk(buf, line, len, updtype)
+buf_T *buf;
+linenr_T line;
+long len;
+int updtype;
+{
+ static buf_T *ml_upd_lastbuf = NULL;
+ static linenr_T ml_upd_lastline;
+ static linenr_T ml_upd_lastcurline;
+ static int ml_upd_lastcurix;
+
+ linenr_T curline = ml_upd_lastcurline;
+ int curix = ml_upd_lastcurix;
+ long size;
+ chunksize_T *curchnk;
+ int rest;
+ bhdr_T *hp;
+ DATA_BL *dp;
+
+ if (buf->b_ml.ml_usedchunks == -1 || len == 0)
+ return;
+ if (buf->b_ml.ml_chunksize == NULL) {
+ buf->b_ml.ml_chunksize = (chunksize_T *)
+ alloc((unsigned)sizeof(chunksize_T) * 100);
+ if (buf->b_ml.ml_chunksize == NULL) {
+ buf->b_ml.ml_usedchunks = -1;
+ return;
+ }
+ buf->b_ml.ml_numchunks = 100;
+ buf->b_ml.ml_usedchunks = 1;
+ buf->b_ml.ml_chunksize[0].mlcs_numlines = 1;
+ buf->b_ml.ml_chunksize[0].mlcs_totalsize = 1;
+ }
+
+ if (updtype == ML_CHNK_UPDLINE && buf->b_ml.ml_line_count == 1) {
+ /*
+ * First line in empty buffer from ml_flush_line() -- reset
+ */
+ buf->b_ml.ml_usedchunks = 1;
+ buf->b_ml.ml_chunksize[0].mlcs_numlines = 1;
+ buf->b_ml.ml_chunksize[0].mlcs_totalsize =
+ (long)STRLEN(buf->b_ml.ml_line_ptr) + 1;
+ return;
+ }
+
+ /*
+ * Find chunk that our line belongs to, curline will be at start of the
+ * chunk.
+ */
+ if (buf != ml_upd_lastbuf || line != ml_upd_lastline + 1
+ || updtype != ML_CHNK_ADDLINE) {
+ for (curline = 1, curix = 0;
+ curix < buf->b_ml.ml_usedchunks - 1
+ && line >= curline +
+ buf->b_ml.ml_chunksize[curix].mlcs_numlines;
+ 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 */
+ curline += buf->b_ml.ml_chunksize[curix].mlcs_numlines;
+ curix++;
+ }
+ curchnk = buf->b_ml.ml_chunksize + curix;
+
+ if (updtype == ML_CHNK_DELLINE)
+ len = -len;
+ curchnk->mlcs_totalsize += len;
+ if (updtype == ML_CHNK_ADDLINE) {
+ curchnk->mlcs_numlines++;
+
+ /* May resize here so we don't have to do it in both cases below */
+ if (buf->b_ml.ml_usedchunks + 1 >= buf->b_ml.ml_numchunks) {
+ buf->b_ml.ml_numchunks = buf->b_ml.ml_numchunks * 3 / 2;
+ buf->b_ml.ml_chunksize = (chunksize_T *)
+ vim_realloc(buf->b_ml.ml_chunksize,
+ sizeof(chunksize_T) * buf->b_ml.ml_numchunks);
+ if (buf->b_ml.ml_chunksize == NULL) {
+ /* Hmmmm, Give up on offset for this buffer */
+ buf->b_ml.ml_usedchunks = -1;
+ return;
+ }
+ }
+
+ if (buf->b_ml.ml_chunksize[curix].mlcs_numlines >= MLCS_MAXL) {
+ int count; /* number of entries in block */
+ int idx;
+ int text_end;
+ int linecnt;
+
+ mch_memmove(buf->b_ml.ml_chunksize + curix + 1,
+ buf->b_ml.ml_chunksize + curix,
+ (buf->b_ml.ml_usedchunks - curix) *
+ sizeof(chunksize_T));
+ /* Compute length of first half of lines in the split chunk */
+ size = 0;
+ linecnt = 0;
+ while (curline < buf->b_ml.ml_line_count
+ && linecnt < MLCS_MINL) {
+ if ((hp = ml_find_line(buf, curline, ML_FIND)) == NULL) {
+ buf->b_ml.ml_usedchunks = -1;
+ return;
+ }
+ dp = (DATA_BL *)(hp->bh_data);
+ count = (long)(buf->b_ml.ml_locked_high) -
+ (long)(buf->b_ml.ml_locked_low) + 1;
+ idx = curline - buf->b_ml.ml_locked_low;
+ curline = buf->b_ml.ml_locked_high + 1;
+ if (idx == 0) /* first line in block, text at the end */
+ text_end = dp->db_txt_end;
+ else
+ text_end = ((dp->db_index[idx - 1]) & DB_INDEX_MASK);
+ /* Compute index of last line to use in this MEMLINE */
+ rest = count - idx;
+ if (linecnt + rest > MLCS_MINL) {
+ idx += MLCS_MINL - linecnt - 1;
+ linecnt = MLCS_MINL;
+ } else {
+ idx = count - 1;
+ linecnt += rest;
+ }
+ size += text_end - ((dp->db_index[idx]) & DB_INDEX_MASK);
+ }
+ buf->b_ml.ml_chunksize[curix].mlcs_numlines = linecnt;
+ buf->b_ml.ml_chunksize[curix + 1].mlcs_numlines -= linecnt;
+ buf->b_ml.ml_chunksize[curix].mlcs_totalsize = size;
+ buf->b_ml.ml_chunksize[curix + 1].mlcs_totalsize -= size;
+ buf->b_ml.ml_usedchunks++;
+ ml_upd_lastbuf = NULL; /* Force recalc of curix & curline */
+ return;
+ } else if (buf->b_ml.ml_chunksize[curix].mlcs_numlines >= MLCS_MINL
+ && curix == buf->b_ml.ml_usedchunks - 1
+ && buf->b_ml.ml_line_count - line <= 1) {
+ /*
+ * We are in the last chunk and it is cheap to crate a new one
+ * after this. Do it now to avoid the loop above later on
+ */
+ curchnk = buf->b_ml.ml_chunksize + curix + 1;
+ buf->b_ml.ml_usedchunks++;
+ if (line == buf->b_ml.ml_line_count) {
+ curchnk->mlcs_numlines = 0;
+ curchnk->mlcs_totalsize = 0;
+ } else {
+ /*
+ * Line is just prior to last, move count for last
+ * This is the common case when loading a new file
+ */
+ hp = ml_find_line(buf, buf->b_ml.ml_line_count, ML_FIND);
+ if (hp == NULL) {
+ buf->b_ml.ml_usedchunks = -1;
+ return;
+ }
+ dp = (DATA_BL *)(hp->bh_data);
+ if (dp->db_line_count == 1)
+ rest = dp->db_txt_end - dp->db_txt_start;
+ else
+ rest =
+ ((dp->db_index[dp->db_line_count - 2]) & DB_INDEX_MASK)
+ - dp->db_txt_start;
+ curchnk->mlcs_totalsize = rest;
+ curchnk->mlcs_numlines = 1;
+ curchnk[-1].mlcs_totalsize -= rest;
+ curchnk[-1].mlcs_numlines -= 1;
+ }
+ }
+ } else if (updtype == ML_CHNK_DELLINE) {
+ curchnk->mlcs_numlines--;
+ ml_upd_lastbuf = NULL; /* Force recalc of curix & curline */
+ if (curix < (buf->b_ml.ml_usedchunks - 1)
+ && (curchnk->mlcs_numlines + curchnk[1].mlcs_numlines)
+ <= MLCS_MINL) {
+ curix++;
+ curchnk = buf->b_ml.ml_chunksize + curix;
+ } else if (curix == 0 && curchnk->mlcs_numlines <= 0) {
+ buf->b_ml.ml_usedchunks--;
+ mch_memmove(buf->b_ml.ml_chunksize, buf->b_ml.ml_chunksize + 1,
+ buf->b_ml.ml_usedchunks * sizeof(chunksize_T));
+ return;
+ } else if (curix == 0 || (curchnk->mlcs_numlines > 10
+ && (curchnk->mlcs_numlines +
+ curchnk[-1].mlcs_numlines)
+ > MLCS_MINL)) {
+ return;
+ }
+
+ /* Collapse chunks */
+ curchnk[-1].mlcs_numlines += curchnk->mlcs_numlines;
+ curchnk[-1].mlcs_totalsize += curchnk->mlcs_totalsize;
+ buf->b_ml.ml_usedchunks--;
+ if (curix < buf->b_ml.ml_usedchunks) {
+ mch_memmove(buf->b_ml.ml_chunksize + curix,
+ buf->b_ml.ml_chunksize + curix + 1,
+ (buf->b_ml.ml_usedchunks - curix) *
+ sizeof(chunksize_T));
+ }
+ return;
+ }
+ ml_upd_lastbuf = buf;
+ ml_upd_lastline = line;
+ ml_upd_lastcurline = curline;
+ 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, lnum, offp)
+buf_T *buf;
+linenr_T lnum;
+long *offp;
+{
+ linenr_T curline;
+ int curix;
+ long size;
+ bhdr_T *hp;
+ DATA_BL *dp;
+ int count; /* number of entries in block */
+ int idx;
+ int start_idx;
+ int text_end;
+ long offset;
+ int len;
+ int ffdos = (get_fileformat(buf) == EOL_DOS);
+ int extra = 0;
+
+ /* take care of cached line first */
+ ml_flush_line(curbuf);
+
+ if (buf->b_ml.ml_usedchunks == -1
+ || buf->b_ml.ml_chunksize == NULL
+ || lnum < 0)
+ return -1;
+
+ if (offp == NULL)
+ offset = 0;
+ else
+ offset = *offp;
+ if (lnum == 0 && offset <= 0)
+ return 1; /* Not a "find offset" and offset 0 _must_ be in line 1 */
+ /*
+ * Find the last chunk before the one containing our line. Last chunk is
+ * special because it will never qualify
+ */
+ curline = 1;
+ curix = size = 0;
+ while (curix < buf->b_ml.ml_usedchunks - 1
+ && ((lnum != 0
+ && lnum >= curline + buf->b_ml.ml_chunksize[curix].mlcs_numlines)
+ || (offset != 0
+ && offset > size +
+ buf->b_ml.ml_chunksize[curix].mlcs_totalsize
+ + ffdos * buf->b_ml.ml_chunksize[curix].mlcs_numlines))) {
+ curline += buf->b_ml.ml_chunksize[curix].mlcs_numlines;
+ size += buf->b_ml.ml_chunksize[curix].mlcs_totalsize;
+ if (offset && ffdos)
+ size += buf->b_ml.ml_chunksize[curix].mlcs_numlines;
+ curix++;
+ }
+
+ while ((lnum != 0 && curline < lnum) || (offset != 0 && size < offset)) {
+ if (curline > buf->b_ml.ml_line_count
+ || (hp = ml_find_line(buf, curline, ML_FIND)) == NULL)
+ return -1;
+ dp = (DATA_BL *)(hp->bh_data);
+ count = (long)(buf->b_ml.ml_locked_high) -
+ (long)(buf->b_ml.ml_locked_low) + 1;
+ start_idx = idx = curline - buf->b_ml.ml_locked_low;
+ if (idx == 0) /* first line in block, text at the end */
+ text_end = dp->db_txt_end;
+ else
+ text_end = ((dp->db_index[idx - 1]) & DB_INDEX_MASK);
+ /* Compute index of last line to use in this MEMLINE */
+ if (lnum != 0) {
+ if (curline + (count - idx) >= lnum)
+ idx += lnum - curline - 1;
+ else
+ idx = count - 1;
+ } else {
+ extra = 0;
+ while (offset >= size
+ + text_end - (int)((dp->db_index[idx]) & DB_INDEX_MASK)
+ + ffdos) {
+ if (ffdos)
+ size++;
+ if (idx == count - 1) {
+ extra = 1;
+ break;
+ }
+ idx++;
+ }
+ }
+ len = text_end - ((dp->db_index[idx]) & DB_INDEX_MASK);
+ size += len;
+ if (offset != 0 && size >= offset) {
+ if (size + ffdos == offset)
+ *offp = 0;
+ else if (idx == start_idx)
+ *offp = offset - size + len;
+ else
+ *offp = offset - size + len
+ - (text_end - ((dp->db_index[idx - 1]) & DB_INDEX_MASK));
+ curline += idx - start_idx + extra;
+ if (curline > buf->b_ml.ml_line_count)
+ return -1; /* exactly one byte beyond the end */
+ return curline;
+ }
+ curline = buf->b_ml.ml_locked_high + 1;
+ }
+
+ if (lnum != 0) {
+ /* Count extra CR characters. */
+ if (ffdos)
+ size += lnum - 1;
+
+ /* Don't count the last line break if 'bin' and 'noeol'. */
+ if (buf->b_p_bin && !buf->b_p_eol)
+ size -= ffdos + 1;
+ }
+
+ return size;
+}
+
+/*
+ * Goto byte in buffer with offset 'cnt'.
+ */
+void goto_byte(cnt)
+long cnt;
+{
+ long boff = cnt;
+ linenr_T lnum;
+
+ 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 */
+ curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
+ curwin->w_curswant = MAXCOL;
+ coladvance((colnr_T)MAXCOL);
+ } else {
+ curwin->w_cursor.lnum = lnum;
+ curwin->w_cursor.col = (colnr_T)boff;
+ curwin->w_cursor.coladd = 0;
+ curwin->w_set_curswant = TRUE;
+ }
+ check_cursor();
+
+ /* Make sure the cursor is on the first byte of a multi-byte char. */
+ if (has_mbyte)
+ mb_adjust_cursor();
+}
diff --git a/src/menu.c b/src/menu.c
new file mode 100644
index 0000000000..12e91b0ae6
--- /dev/null
+++ b/src/menu.c
@@ -0,0 +1,1646 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved by Bram Moolenaar
+ * GUI/Motif support by Robert Webb
+ *
+ * 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.
+ */
+
+/*
+ * Code for menus. Used for the GUI and 'wildmenu'.
+ */
+
+#include "vim.h"
+
+
+#define MENUDEPTH 10 /* maximum depth of menus */
+
+static int add_menu_path __ARGS((char_u *, vimmenu_T *, int *, char_u *));
+static int menu_nable_recurse __ARGS((vimmenu_T *menu, char_u *name, int modes,
+ int enable));
+static int remove_menu __ARGS((vimmenu_T **, char_u *, int, int silent));
+static void free_menu __ARGS((vimmenu_T **menup));
+static void free_menu_string __ARGS((vimmenu_T *, int));
+static int show_menus __ARGS((char_u *, int));
+static void show_menus_recursive __ARGS((vimmenu_T *, int, int));
+static int menu_name_equal __ARGS((char_u *name, vimmenu_T *menu));
+static int menu_namecmp __ARGS((char_u *name, char_u *mname));
+static int get_menu_cmd_modes __ARGS((char_u *, int, int *, int *));
+static char_u *popup_mode_name __ARGS((char_u *name, int idx));
+static char_u *menu_text __ARGS((char_u *text, int *mnemonic, char_u **actext));
+
+
+static int menu_is_hidden __ARGS((char_u *name));
+static int menu_is_tearoff __ARGS((char_u *name));
+
+static char_u *menu_skip_part __ARGS((char_u *p));
+static char_u *menutrans_lookup __ARGS((char_u *name, int len));
+static void menu_unescape_name __ARGS((char_u *p));
+
+static char_u *menu_translate_tab_and_shift __ARGS((char_u *arg_start));
+
+/* 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");
+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(eap)
+exarg_T *eap; /* Ex command arguments */
+{
+ char_u *menu_path;
+ int modes;
+ char_u *map_to;
+ int noremap;
+ int silent = FALSE;
+ int special = FALSE;
+ int unmenu;
+ char_u *map_buf;
+ char_u *arg;
+ char_u *p;
+ int i;
+ int pri_tab[MENUDEPTH + 1];
+ int enable = MAYBE; /* TRUE for "menu enable", FALSE for "menu
+ * disable */
+ vimmenu_T menuarg;
+
+ modes = get_menu_cmd_modes(eap->cmd, eap->forceit, &noremap, &unmenu);
+ arg = eap->arg;
+
+ for (;; ) {
+ if (STRNCMP(arg, "<script>", 8) == 0) {
+ noremap = REMAP_SCRIPT;
+ arg = skipwhite(arg + 8);
+ continue;
+ }
+ if (STRNCMP(arg, "<silent>", 8) == 0) {
+ silent = TRUE;
+ arg = skipwhite(arg + 8);
+ continue;
+ }
+ if (STRNCMP(arg, "<special>", 9) == 0) {
+ special = TRUE;
+ arg = skipwhite(arg + 9);
+ continue;
+ }
+ break;
+ }
+
+
+ /* Locate an optional "icon=filename" argument. */
+ if (STRNCMP(arg, "icon=", 5) == 0) {
+ arg += 5;
+ while (*arg != NUL && *arg != ' ') {
+ if (*arg == '\\')
+ STRMOVE(arg, arg + 1);
+ mb_ptr_adv(arg);
+ }
+ if (*arg != NUL) {
+ *arg++ = NUL;
+ arg = skipwhite(arg);
+ }
+ }
+
+ /*
+ * Fill in the priority table.
+ */
+ for (p = arg; *p; ++p)
+ if (!VIM_ISDIGIT(*p) && *p != '.')
+ break;
+ if (vim_iswhite(*p)) {
+ for (i = 0; i < MENUDEPTH && !vim_iswhite(*arg); ++i) {
+ pri_tab[i] = getdigits(&arg);
+ if (pri_tab[i] == 0)
+ pri_tab[i] = 500;
+ if (*arg == '.')
+ ++arg;
+ }
+ arg = skipwhite(arg);
+ } else if (eap->addr_count && eap->line2 != 0) {
+ pri_tab[0] = eap->line2;
+ i = 1;
+ } else
+ i = 0;
+ while (i < MENUDEPTH)
+ pri_tab[i++] = 500;
+ pri_tab[MENUDEPTH] = -1; /* mark end of the table */
+
+ /*
+ * Check for "disable" or "enable" argument.
+ */
+ if (STRNCMP(arg, "enable", 6) == 0 && vim_iswhite(arg[6])) {
+ enable = TRUE;
+ arg = skipwhite(arg + 6);
+ } else if (STRNCMP(arg, "disable", 7) == 0 && vim_iswhite(arg[7])) {
+ enable = FALSE;
+ arg = skipwhite(arg + 7);
+ }
+
+ /*
+ * If there is no argument, display all menus.
+ */
+ if (*arg == NUL) {
+ show_menus(arg, modes);
+ return;
+ }
+
+
+ menu_path = arg;
+ if (*menu_path == '.') {
+ EMSG2(_(e_invarg2), menu_path);
+ goto theend;
+ }
+
+ map_to = menu_translate_tab_and_shift(arg);
+
+ /*
+ * If there is only a menu name, display menus with that name.
+ */
+ if (*map_to == NUL && !unmenu && enable == MAYBE) {
+ show_menus(menu_path, modes);
+ goto theend;
+ } else if (*map_to != NUL && (unmenu || enable != MAYBE)) {
+ 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 */
+ menu_path = (char_u *)"";
+
+ if (menu_is_popup(menu_path)) {
+ for (i = 0; i < MENU_INDEX_TIP; ++i)
+ if (modes & (1 << i)) {
+ p = popup_mode_name(menu_path, i);
+ if (p != NULL) {
+ menu_nable_recurse(root_menu, p, MENU_ALL_MODES,
+ enable);
+ vim_free(p);
+ }
+ }
+ }
+ menu_nable_recurse(root_menu, menu_path, modes, enable);
+ } else if (unmenu) {
+ /*
+ * Delete menu(s).
+ */
+ if (STRCMP(menu_path, "*") == 0) /* meaning: remove all menus */
+ menu_path = (char_u *)"";
+
+ /*
+ * For the PopUp menu, remove a menu for each mode separately.
+ */
+ if (menu_is_popup(menu_path)) {
+ for (i = 0; i < MENU_INDEX_TIP; ++i)
+ if (modes & (1 << i)) {
+ p = popup_mode_name(menu_path, i);
+ if (p != NULL) {
+ remove_menu(&root_menu, p, MENU_ALL_MODES, TRUE);
+ vim_free(p);
+ }
+ }
+ }
+
+ /* Careful: remove_menu() changes menu_path */
+ remove_menu(&root_menu, menu_path, modes, FALSE);
+ } else {
+ /*
+ * Add menu(s).
+ * Replace special key codes.
+ */
+ if (STRICMP(map_to, "<nop>") == 0) { /* "<Nop>" means nothing */
+ map_to = (char_u *)"";
+ map_buf = NULL;
+ } else if (modes & MENU_TIP_MODE)
+ map_buf = NULL; /* Menu tips are plain text. */
+ else
+ map_to = replace_termcodes(map_to, &map_buf, FALSE, TRUE, special);
+ menuarg.modes = modes;
+ menuarg.noremap[0] = noremap;
+ menuarg.silent[0] = silent;
+ add_menu_path(menu_path, &menuarg, pri_tab, map_to
+ );
+
+ /*
+ * For the PopUp menu, add a menu for each mode separately.
+ */
+ if (menu_is_popup(menu_path)) {
+ for (i = 0; i < MENU_INDEX_TIP; ++i)
+ if (modes & (1 << i)) {
+ p = popup_mode_name(menu_path, i);
+ if (p != NULL) {
+ /* Include all modes, to make ":amenu" work */
+ menuarg.modes = modes;
+ add_menu_path(p, &menuarg, pri_tab, map_to
+ );
+ vim_free(p);
+ }
+ }
+ }
+
+ vim_free(map_buf);
+ }
+
+
+theend:
+ ;
+}
+
+/*
+ * Add the menu with the given name to the menu hierarchy
+ */
+static int add_menu_path(menu_path, menuarg, pri_tab, call_data)
+char_u *menu_path;
+vimmenu_T *menuarg; /* passes modes, iconfile, iconidx,
+ icon_builtin, silent[0], noremap[0] */
+int *pri_tab;
+char_u *call_data;
+{
+ char_u *path_name;
+ int modes = menuarg->modes;
+ vimmenu_T **menup;
+ vimmenu_T *menu = NULL;
+ vimmenu_T *parent;
+ vimmenu_T **lower_pri;
+ char_u *p;
+ char_u *name;
+ char_u *dname;
+ char_u *next_name;
+ int i;
+ int c;
+ int d;
+ int pri_idx = 0;
+ int old_modes = 0;
+ int amenu;
+ char_u *en_name;
+ char_u *map_to = NULL;
+
+ /* Make a copy so we can stuff around with it, since it could be const */
+ path_name = vim_strsave(menu_path);
+ if (path_name == NULL)
+ return FAIL;
+ menup = &root_menu;
+ parent = NULL;
+ name = path_name;
+ while (*name) {
+ /* Get name of this element in the menu hierarchy, and the simplified
+ * name (without mnemonic and accelerator text). */
+ next_name = menu_name_skip(name);
+ map_to = menutrans_lookup(name, (int)STRLEN(name));
+ if (map_to != NULL) {
+ en_name = name;
+ name = map_to;
+ } else
+ en_name = NULL;
+ dname = menu_text(name, NULL, NULL);
+ if (dname == NULL)
+ goto erret;
+ if (*dname == NUL) {
+ /* Only a mnemonic or accelerator is not valid. */
+ EMSG(_("E792: Empty menu name"));
+ goto erret;
+ }
+
+ /* See if it's already there */
+ lower_pri = menup;
+ menu = *menup;
+ while (menu != NULL) {
+ if (menu_name_equal(name, menu) || menu_name_equal(dname, menu)) {
+ if (*next_name == NUL && menu->children != NULL) {
+ 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)
+ EMSG(_(e_notsubmenu));
+ goto erret;
+ }
+ break;
+ }
+ menup = &menu->next;
+
+ /* Count menus, to find where this one needs to be inserted.
+ * Ignore menus that are not in the menubar (PopUp and Toolbar) */
+ if (parent != NULL || menu_is_menubar(menu->name)) {
+ if (menu->priority <= pri_tab[pri_idx]) {
+ lower_pri = menup;
+ }
+ }
+ menu = menu->next;
+ }
+
+ if (menu == NULL) {
+ if (*next_name == NUL && parent == NULL) {
+ EMSG(_("E331: Must not add menu items directly to menu bar"));
+ goto erret;
+ }
+
+ if (menu_is_separator(dname) && *next_name != NUL) {
+ EMSG(_("E332: Separator cannot be part of a menu path"));
+ goto erret;
+ }
+
+ /* Not already there, so lets add it */
+ menu = (vimmenu_T *)alloc_clear((unsigned)sizeof(vimmenu_T));
+ if (menu == NULL)
+ goto erret;
+
+ menu->modes = modes;
+ menu->enabled = MENU_ALL_MODES;
+ menu->name = vim_strsave(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);
+ menu->en_dname = menu_text(en_name, NULL, NULL);
+ } else {
+ menu->en_name = NULL;
+ menu->en_dname = NULL;
+ }
+ menu->priority = pri_tab[pri_idx];
+ menu->parent = parent;
+
+ /*
+ * Add after menu that has lower priority.
+ */
+ menu->next = *lower_pri;
+ *lower_pri = menu;
+
+ old_modes = 0;
+
+ } else {
+ old_modes = menu->modes;
+
+ /*
+ * If this menu option was previously only available in other
+ * modes, then make sure it's available for this one now
+ * Also enable a menu when it's created or changed.
+ */
+ {
+ menu->modes |= modes;
+ menu->enabled |= modes;
+ }
+ }
+
+
+ menup = &menu->children;
+ parent = menu;
+ name = next_name;
+ vim_free(dname);
+ dname = NULL;
+ if (pri_tab[pri_idx + 1] != -1)
+ ++pri_idx;
+ }
+ vim_free(path_name);
+
+ /*
+ * Only add system menu items which have not been defined yet.
+ * First check if this was an ":amenu".
+ */
+ amenu = ((modes & (MENU_NORMAL_MODE | MENU_INSERT_MODE)) ==
+ (MENU_NORMAL_MODE | MENU_INSERT_MODE));
+ if (sys_menu)
+ modes &= ~old_modes;
+
+ if (menu != NULL && modes) {
+ p = (call_data == NULL) ? NULL : vim_strsave(call_data);
+
+ /* loop over all modes, may add more than one */
+ for (i = 0; i < MENU_MODES; ++i) {
+ if (modes & (1 << i)) {
+ /* free any old menu */
+ free_menu_string(menu, i);
+
+ /* For "amenu", may insert an extra character.
+ * Don't do this if adding a tearbar (addtearoff == FALSE).
+ * Don't do this for "<Nop>". */
+ c = 0;
+ d = 0;
+ if (amenu && call_data != NULL && *call_data != NUL
+ ) {
+ switch (1 << i) {
+ case MENU_VISUAL_MODE:
+ case MENU_SELECT_MODE:
+ case MENU_OP_PENDING_MODE:
+ case MENU_CMDLINE_MODE:
+ c = Ctrl_C;
+ break;
+ case MENU_INSERT_MODE:
+ c = Ctrl_BSL;
+ d = Ctrl_O;
+ break;
+ }
+ }
+
+ if (c != 0) {
+ menu->strings[i] = alloc((unsigned)(STRLEN(call_data) + 5 ));
+ if (menu->strings[i] != NULL) {
+ menu->strings[i][0] = c;
+ if (d == 0)
+ STRCPY(menu->strings[i] + 1, call_data);
+ else {
+ menu->strings[i][1] = d;
+ STRCPY(menu->strings[i] + 2, call_data);
+ }
+ if (c == Ctrl_C) {
+ int len = (int)STRLEN(menu->strings[i]);
+
+ /* Append CTRL-\ CTRL-G to obey 'insertmode'. */
+ menu->strings[i][len] = Ctrl_BSL;
+ menu->strings[i][len + 1] = Ctrl_G;
+ menu->strings[i][len + 2] = NUL;
+ }
+ }
+ } else
+ menu->strings[i] = p;
+ menu->noremap[i] = menuarg->noremap[0];
+ menu->silent[i] = menuarg->silent[0];
+ }
+ }
+#if defined(FEAT_TOOLBAR) && !defined(FEAT_GUI_W32) \
+ && (defined(FEAT_BEVAL) || defined(FEAT_GUI_GTK))
+ /* Need to update the menu tip. */
+ if (modes & MENU_TIP_MODE)
+ gui_mch_menu_set_tip(menu);
+#endif
+ }
+ return OK;
+
+erret:
+ vim_free(path_name);
+ vim_free(dname);
+
+ /* Delete any empty submenu we added before discovering the error. Repeat
+ * for higher levels. */
+ while (parent != NULL && parent->children == NULL) {
+ if (parent->parent == NULL)
+ menup = &root_menu;
+ else
+ menup = &parent->parent->children;
+ for (; *menup != NULL && *menup != parent; menup = &((*menup)->next))
+ ;
+ if (*menup == NULL) /* safety check */
+ break;
+ parent = parent->parent;
+ free_menu(menup);
+ }
+ return FAIL;
+}
+
+/*
+ * Set the (sub)menu with the given name to enabled or disabled.
+ * Called recursively.
+ */
+static int menu_nable_recurse(menu, name, modes, enable)
+vimmenu_T *menu;
+char_u *name;
+int modes;
+int enable;
+{
+ char_u *p;
+
+ if (menu == NULL)
+ return OK; /* Got to bottom of hierarchy */
+
+ /* Get name of this element in the menu hierarchy */
+ p = menu_name_skip(name);
+
+ /* Find the menu */
+ while (menu != NULL) {
+ if (*name == NUL || *name == '*' || menu_name_equal(name, menu)) {
+ if (*p != NUL) {
+ if (menu->children == NULL) {
+ EMSG(_(e_notsubmenu));
+ return FAIL;
+ }
+ if (menu_nable_recurse(menu->children, p, modes, enable)
+ == FAIL)
+ return FAIL;
+ } else if (enable)
+ menu->enabled |= modes;
+ else
+ menu->enabled &= ~modes;
+
+ /*
+ * When name is empty, we are doing all menu items for the given
+ * modes, so keep looping, otherwise we are just doing the named
+ * menu item (which has been found) so break here.
+ */
+ if (*name != NUL && *name != '*')
+ break;
+ }
+ menu = menu->next;
+ }
+ if (*name != NUL && *name != '*' && menu == NULL) {
+ EMSG2(_(e_nomenu), name);
+ return FAIL;
+ }
+
+
+ return OK;
+}
+
+/*
+ * Remove the (sub)menu with the given name from the menu hierarchy
+ * Called recursively.
+ */
+static int remove_menu(menup, name, modes, silent)
+vimmenu_T **menup;
+char_u *name;
+int modes;
+int silent; /* don't give error messages */
+{
+ vimmenu_T *menu;
+ vimmenu_T *child;
+ char_u *p;
+
+ if (*menup == NULL)
+ return OK; /* Got to bottom of hierarchy */
+
+ /* Get name of this element in the menu hierarchy */
+ p = menu_name_skip(name);
+
+ /* Find the menu */
+ while ((menu = *menup) != NULL) {
+ if (*name == NUL || menu_name_equal(name, menu)) {
+ if (*p != NUL && menu->children == NULL) {
+ if (!silent)
+ EMSG(_(e_notsubmenu));
+ return FAIL;
+ }
+ if ((menu->modes & modes) != 0x0) {
+#if defined(FEAT_GUI_W32) & defined(FEAT_TEAROFF)
+ /*
+ * If we are removing all entries for this menu,MENU_ALL_MODES,
+ * Then kill any tearoff before we start
+ */
+ if (*p == NUL && modes == MENU_ALL_MODES) {
+ if (IsWindow(menu->tearoff_handle))
+ DestroyWindow(menu->tearoff_handle);
+ }
+#endif
+ if (remove_menu(&menu->children, p, modes, silent) == FAIL)
+ return FAIL;
+ } else if (*name != NUL) {
+ if (!silent)
+ EMSG(_(e_othermode));
+ return FAIL;
+ }
+
+ /*
+ * When name is empty, we are removing all menu items for the given
+ * modes, so keep looping, otherwise we are just removing the named
+ * menu item (which has been found) so break here.
+ */
+ if (*name != NUL)
+ break;
+
+ /* Remove the menu item for the given mode[s]. If the menu item
+ * is no longer valid in ANY mode, delete it */
+ menu->modes &= ~modes;
+ if (modes & MENU_TIP_MODE)
+ free_menu_string(menu, MENU_INDEX_TIP);
+ if ((menu->modes & MENU_ALL_MODES) == 0)
+ free_menu(menup);
+ else
+ menup = &menu->next;
+ } else
+ menup = &menu->next;
+ }
+ if (*name != NUL) {
+ if (menu == NULL) {
+ if (!silent)
+ EMSG2(_(e_nomenu), name);
+ return FAIL;
+ }
+
+
+ /* Recalculate modes for menu based on the new updated children */
+ menu->modes &= ~modes;
+#if defined(FEAT_GUI_W32) & defined(FEAT_TEAROFF)
+ if ((s_tearoffs) && (menu->children != NULL)) /* there's a tear bar.. */
+ child = menu->children->next; /* don't count tearoff bar */
+ else
+#endif
+ child = menu->children;
+ for (; child != NULL; child = child->next)
+ menu->modes |= child->modes;
+ if (modes & MENU_TIP_MODE) {
+ free_menu_string(menu, MENU_INDEX_TIP);
+#if defined(FEAT_TOOLBAR) && !defined(FEAT_GUI_W32) \
+ && (defined(FEAT_BEVAL) || defined(FEAT_GUI_GTK))
+ /* Need to update the menu tip. */
+ if (gui.in_use)
+ gui_mch_menu_set_tip(menu);
+#endif
+ }
+ if ((menu->modes & MENU_ALL_MODES) == 0) {
+ /* The menu item is no longer valid in ANY mode, so delete it */
+#if defined(FEAT_GUI_W32) & defined(FEAT_TEAROFF)
+ if (s_tearoffs && menu->children != NULL) /* there's a tear bar.. */
+ free_menu(&menu->children);
+#endif
+ *menup = menu;
+ free_menu(menup);
+ }
+ }
+
+ return OK;
+}
+
+/*
+ * Free the given menu structure and remove it from the linked list.
+ */
+static void free_menu(menup)
+vimmenu_T **menup;
+{
+ int i;
+ vimmenu_T *menu;
+
+ menu = *menup;
+
+
+ /* Don't change *menup until after calling gui_mch_destroy_menu(). The
+ * MacOS code needs the original structure to properly delete the menu. */
+ *menup = menu->next;
+ vim_free(menu->name);
+ vim_free(menu->dname);
+ vim_free(menu->en_name);
+ vim_free(menu->en_dname);
+ vim_free(menu->actext);
+ for (i = 0; i < MENU_MODES; i++)
+ free_menu_string(menu, i);
+ vim_free(menu);
+
+}
+
+/*
+ * Free the menu->string with the given index.
+ */
+static void free_menu_string(menu, idx)
+vimmenu_T *menu;
+int idx;
+{
+ int count = 0;
+ int i;
+
+ for (i = 0; i < MENU_MODES; i++)
+ if (menu->strings[i] == menu->strings[idx])
+ count++;
+ if (count == 1)
+ vim_free(menu->strings[idx]);
+ menu->strings[idx] = NULL;
+}
+
+/*
+ * Show the mapping associated with a menu item or hierarchy in a sub-menu.
+ */
+static int show_menus(path_name, modes)
+char_u *path_name;
+int modes;
+{
+ char_u *p;
+ char_u *name;
+ vimmenu_T *menu;
+ vimmenu_T *parent = NULL;
+
+ menu = root_menu;
+ name = path_name = vim_strsave(path_name);
+ if (path_name == NULL)
+ return FAIL;
+
+ /* First, find the (sub)menu with the given name */
+ while (*name) {
+ p = menu_name_skip(name);
+ while (menu != NULL) {
+ if (menu_name_equal(name, menu)) {
+ /* Found menu */
+ if (*p != NUL && menu->children == NULL) {
+ EMSG(_(e_notsubmenu));
+ vim_free(path_name);
+ return FAIL;
+ } else if ((menu->modes & modes) == 0x0) {
+ EMSG(_(e_othermode));
+ vim_free(path_name);
+ return FAIL;
+ }
+ break;
+ }
+ menu = menu->next;
+ }
+ if (menu == NULL) {
+ EMSG2(_(e_nomenu), name);
+ vim_free(path_name);
+ return FAIL;
+ }
+ name = p;
+ parent = menu;
+ menu = menu->children;
+ }
+ vim_free(path_name);
+
+ /* 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);
+ return OK;
+}
+
+/*
+ * Recursively show the mappings associated with the menus under the given one
+ */
+static void show_menus_recursive(menu, modes, depth)
+vimmenu_T *menu;
+int modes;
+int depth;
+{
+ int i;
+ int bit;
+
+ if (menu != NULL && (menu->modes & modes) == 0x0)
+ return;
+
+ if (menu != NULL) {
+ msg_putchar('\n');
+ if (got_int) /* "q" hit for "--more--" */
+ return;
+ for (i = 0; i < depth; i++)
+ MSG_PUTS(" ");
+ if (menu->priority) {
+ msg_outnum((long)menu->priority);
+ MSG_PUTS(" ");
+ }
+ /* Same highlighting as for directories!? */
+ msg_outtrans_attr(menu->name, hl_attr(HLF_D));
+ }
+
+ if (menu != NULL && menu->children == NULL) {
+ for (bit = 0; bit < MENU_MODES; bit++)
+ if ((menu->modes & modes & (1 << bit)) != 0) {
+ msg_putchar('\n');
+ if (got_int) /* "q" hit for "--more--" */
+ return;
+ for (i = 0; i < depth + 2; i++)
+ MSG_PUTS(" ");
+ msg_putchar(menu_mode_chars[bit]);
+ if (menu->noremap[bit] == REMAP_NONE)
+ msg_putchar('*');
+ else if (menu->noremap[bit] == REMAP_SCRIPT)
+ msg_putchar('&');
+ else
+ msg_putchar(' ');
+ if (menu->silent[bit])
+ msg_putchar('s');
+ else
+ msg_putchar(' ');
+ if ((menu->modes & menu->enabled & (1 << bit)) == 0)
+ msg_putchar('-');
+ 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);
+ }
+ } else {
+ if (menu == NULL) {
+ menu = root_menu;
+ depth--;
+ } else
+ menu = menu->children;
+
+ /* recursively show all children. Skip PopUp[nvoci]. */
+ for (; menu != NULL && !got_int; menu = menu->next)
+ if (!menu_is_hidden(menu->dname))
+ show_menus_recursive(menu, modes, depth + 1);
+ }
+}
+
+
+/*
+ * Used when expanding menu names.
+ */
+static vimmenu_T *expand_menu = NULL;
+static int expand_modes = 0x0;
+static int expand_emenu; /* TRUE for ":emenu" command */
+
+/*
+ * Work out what to complete when doing command line completion of menu names.
+ */
+char_u * set_context_in_menu_cmd(xp, cmd, arg, forceit)
+expand_T *xp;
+char_u *cmd;
+char_u *arg;
+int forceit;
+{
+ char_u *after_dot;
+ char_u *p;
+ char_u *path_name = NULL;
+ char_u *name;
+ int unmenu;
+ vimmenu_T *menu;
+ int expand_menus;
+
+ xp->xp_context = EXPAND_UNSUCCESSFUL;
+
+
+ /* Check for priority numbers, enable and disable */
+ for (p = arg; *p; ++p)
+ if (!VIM_ISDIGIT(*p) && *p != '.')
+ break;
+
+ if (!vim_iswhite(*p)) {
+ if (STRNCMP(arg, "enable", 6) == 0
+ && (arg[6] == NUL || vim_iswhite(arg[6])))
+ p = arg + 6;
+ else if (STRNCMP(arg, "disable", 7) == 0
+ && (arg[7] == NUL || vim_iswhite(arg[7])))
+ p = arg + 7;
+ else
+ p = arg;
+ }
+
+ while (*p != NUL && vim_iswhite(*p))
+ ++p;
+
+ arg = after_dot = p;
+
+ for (; *p && !vim_iswhite(*p); ++p) {
+ if ((*p == '\\' || *p == Ctrl_V) && p[1] != NUL)
+ p++;
+ else if (*p == '.')
+ after_dot = p + 1;
+ }
+
+ /* ":tearoff" and ":popup" only use menus, not entries */
+ expand_menus = !((*cmd == 't' && cmd[1] == 'e') || *cmd == 'p');
+ expand_emenu = (*cmd == 'e');
+ if (expand_menus && vim_iswhite(*p))
+ return NULL; /* TODO: check for next command? */
+ if (*p == NUL) { /* Complete the menu name */
+ /*
+ * With :unmenu, you only want to match menus for the appropriate mode.
+ * With :menu though you might want to add a menu with the same name as
+ * one in another mode, so match menus from other modes too.
+ */
+ expand_modes = get_menu_cmd_modes(cmd, forceit, NULL, &unmenu);
+ if (!unmenu)
+ expand_modes = MENU_ALL_MODES;
+
+ menu = root_menu;
+ if (after_dot != arg) {
+ path_name = alloc((unsigned)(after_dot - arg));
+ if (path_name == NULL)
+ return NULL;
+ vim_strncpy(path_name, arg, after_dot - arg - 1);
+ }
+ name = path_name;
+ while (name != NULL && *name) {
+ p = menu_name_skip(name);
+ while (menu != NULL) {
+ if (menu_name_equal(name, menu)) {
+ /* Found menu */
+ if ((*p != NUL && menu->children == NULL)
+ || ((menu->modes & expand_modes) == 0x0)) {
+ /*
+ * Menu path continues, but we have reached a leaf.
+ * Or menu exists only in another mode.
+ */
+ vim_free(path_name);
+ return NULL;
+ }
+ break;
+ }
+ menu = menu->next;
+ }
+ if (menu == NULL) {
+ /* No menu found with the name we were looking for */
+ vim_free(path_name);
+ return NULL;
+ }
+ name = p;
+ menu = menu->children;
+ }
+ vim_free(path_name);
+
+ xp->xp_context = expand_menus ? EXPAND_MENUNAMES : EXPAND_MENUS;
+ xp->xp_pattern = after_dot;
+ expand_menu = menu;
+ } else /* We're in the mapping part */
+ xp->xp_context = EXPAND_NOTHING;
+ return NULL;
+}
+
+/*
+ * Function given to ExpandGeneric() to obtain the list of (sub)menus (not
+ * entries).
+ */
+char_u * get_menu_name(xp, idx)
+expand_T *xp UNUSED;
+int idx;
+{
+ static vimmenu_T *menu = NULL;
+ char_u *str;
+ static int should_advance = FALSE;
+
+ if (idx == 0) { /* first call: start at first item */
+ menu = expand_menu;
+ should_advance = FALSE;
+ }
+
+ /* Skip PopUp[nvoci]. */
+ while (menu != NULL && (menu_is_hidden(menu->dname)
+ || menu_is_separator(menu->dname)
+ || menu_is_tearoff(menu->dname)
+ || menu->children == NULL))
+ menu = menu->next;
+
+ if (menu == NULL) /* at end of linked list */
+ return NULL;
+
+ if (menu->modes & expand_modes)
+ if (should_advance)
+ str = menu->en_dname;
+ else {
+ str = menu->dname;
+ if (menu->en_dname == NULL)
+ should_advance = TRUE;
+ }
+ else
+ str = (char_u *)"";
+
+ if (should_advance)
+ /* Advance to next menu entry. */
+ menu = menu->next;
+
+ should_advance = !should_advance;
+
+ return str;
+}
+
+/*
+ * Function given to ExpandGeneric() to obtain the list of menus and menu
+ * entries.
+ */
+char_u * get_menu_names(xp, idx)
+expand_T *xp UNUSED;
+int idx;
+{
+ static vimmenu_T *menu = NULL;
+#define TBUFFER_LEN 256
+ static char_u tbuffer[TBUFFER_LEN]; /*hack*/
+ char_u *str;
+ static int should_advance = FALSE;
+
+ if (idx == 0) { /* first call: start at first item */
+ menu = expand_menu;
+ should_advance = FALSE;
+ }
+
+ /* Skip Browse-style entries, popup menus and separators. */
+ while (menu != NULL
+ && ( menu_is_hidden(menu->dname)
+ || (expand_emenu && menu_is_separator(menu->dname))
+ || menu_is_tearoff(menu->dname)
+ || menu->dname[STRLEN(menu->dname) - 1] == '.'
+ ))
+ menu = menu->next;
+
+ if (menu == NULL) /* at end of linked list */
+ return NULL;
+
+ if (menu->modes & expand_modes) {
+ if (menu->children != NULL) {
+ if (should_advance)
+ vim_strncpy(tbuffer, menu->en_dname, TBUFFER_LEN - 2);
+ else {
+ vim_strncpy(tbuffer, menu->dname, TBUFFER_LEN - 2);
+ if (menu->en_dname == NULL)
+ should_advance = TRUE;
+ }
+ /* hack on menu separators: use a 'magic' char for the separator
+ * so that '.' in names gets escaped properly */
+ STRCAT(tbuffer, "\001");
+ str = tbuffer;
+ } else {
+ if (should_advance)
+ str = menu->en_dname;
+ else {
+ str = menu->dname;
+ if (menu->en_dname == NULL)
+ should_advance = TRUE;
+ }
+ }
+ } else
+ str = (char_u *)"";
+
+ if (should_advance)
+ /* Advance to next menu entry. */
+ menu = menu->next;
+
+ should_advance = !should_advance;
+
+ 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(name)
+char_u *name;
+{
+ char_u *p;
+
+ for (p = name; *p && *p != '.'; mb_ptr_adv(p)) {
+ if (*p == '\\' || *p == Ctrl_V) {
+ STRMOVE(p, p + 1);
+ if (*p == NUL)
+ break;
+ }
+ }
+ if (*p)
+ *p++ = NUL;
+ return p;
+}
+
+/*
+ * 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(name, menu)
+char_u *name;
+vimmenu_T *menu;
+{
+ if (menu->en_name != NULL
+ && (menu_namecmp(name, menu->en_name)
+ || menu_namecmp(name, menu->en_dname)))
+ return TRUE;
+ return menu_namecmp(name, menu->name) || menu_namecmp(name, menu->dname);
+}
+
+static int menu_namecmp(name, mname)
+char_u *name;
+char_u *mname;
+{
+ int i;
+
+ for (i = 0; name[i] != NUL && name[i] != TAB; ++i)
+ if (name[i] != mname[i])
+ break;
+ return (name[i] == NUL || name[i] == TAB)
+ && (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(cmd, forceit, noremap, unmenu)
+char_u *cmd;
+int forceit; /* Was there a "!" after the command? */
+int *noremap;
+int *unmenu;
+{
+ int modes;
+
+ switch (*cmd++) {
+ case 'v': /* vmenu, vunmenu, vnoremenu */
+ modes = MENU_VISUAL_MODE | MENU_SELECT_MODE;
+ break;
+ case 'x': /* xmenu, xunmenu, xnoremenu */
+ modes = MENU_VISUAL_MODE;
+ break;
+ case 's': /* smenu, sunmenu, snoremenu */
+ modes = MENU_SELECT_MODE;
+ break;
+ case 'o': /* omenu */
+ modes = MENU_OP_PENDING_MODE;
+ break;
+ case 'i': /* imenu */
+ modes = MENU_INSERT_MODE;
+ break;
+ case 't':
+ modes = MENU_TIP_MODE; /* tmenu */
+ break;
+ case 'c': /* cmenu */
+ modes = MENU_CMDLINE_MODE;
+ break;
+ case 'a': /* amenu */
+ modes = MENU_INSERT_MODE | MENU_CMDLINE_MODE | MENU_NORMAL_MODE
+ | MENU_VISUAL_MODE | MENU_SELECT_MODE
+ | MENU_OP_PENDING_MODE;
+ break;
+ case 'n':
+ if (*cmd != 'o') { /* nmenu, not noremenu */
+ modes = MENU_NORMAL_MODE;
+ break;
+ }
+ /* FALLTHROUGH */
+ default:
+ --cmd;
+ if (forceit) /* menu!! */
+ modes = MENU_INSERT_MODE | MENU_CMDLINE_MODE;
+ else /* menu */
+ modes = MENU_NORMAL_MODE | MENU_VISUAL_MODE | MENU_SELECT_MODE
+ | MENU_OP_PENDING_MODE;
+ }
+
+ if (noremap != NULL)
+ *noremap = (*cmd == 'n' ? REMAP_NONE : REMAP_YES);
+ if (unmenu != NULL)
+ *unmenu = (*cmd == 'u');
+ return modes;
+}
+
+/*
+ * Modify a menu name starting with "PopUp" to include the mode character.
+ * Returns the name in allocated memory (NULL for failure).
+ */
+static char_u * popup_mode_name(name, idx)
+char_u *name;
+int idx;
+{
+ char_u *p;
+ int len = (int)STRLEN(name);
+
+ p = vim_strnsave(name, len + 1);
+ if (p != NULL) {
+ mch_memmove(p + 6, p + 5, (size_t)(len - 4));
+ p[5] = menu_mode_chars[idx];
+ }
+ return p;
+}
+
+
+/*
+ * Duplicate the menu item text and then process to see if a mnemonic key
+ * and/or accelerator text has been identified.
+ * Returns a pointer to allocated memory, or NULL for failure.
+ * If mnemonic != NULL, *mnemonic is set to the character after the first '&'.
+ * If actext != NULL, *actext is set to the text after the first TAB.
+ */
+static char_u * menu_text(str, mnemonic, actext)
+char_u *str;
+int *mnemonic;
+char_u **actext;
+{
+ char_u *p;
+ char_u *text;
+
+ /* Locate accelerator text, after the first TAB */
+ p = vim_strchr(str, TAB);
+ if (p != NULL) {
+ if (actext != NULL)
+ *actext = vim_strsave(p + 1);
+ text = vim_strnsave(str, (int)(p - str));
+ } else
+ text = vim_strsave(str);
+
+ /* Find mnemonic characters "&a" and reduce "&&" to "&". */
+ for (p = text; p != NULL; ) {
+ p = vim_strchr(p, '&');
+ if (p != NULL) {
+ if (p[1] == NUL) /* trailing "&" */
+ break;
+ if (mnemonic != NULL && p[1] != '&')
+#if !defined(__MVS__) || defined(MOTIF390_MNEMONIC_FIXED)
+ *mnemonic = p[1];
+#else
+ {
+ /*
+ * Well there is a bug in the Motif libraries on OS390 Unix.
+ * The mnemonic keys needs to be converted to ASCII values
+ * first.
+ * This behavior has been seen in 2.8 and 2.9.
+ */
+ char c = p[1];
+ __etoa_l(&c, 1);
+ *mnemonic = c;
+ }
+#endif
+ STRMOVE(p, p + 1);
+ p = p + 1;
+ }
+ }
+ return text;
+}
+
+/*
+ * Return TRUE if "name" can be a menu in the MenuBar.
+ */
+int menu_is_menubar(name)
+char_u *name;
+{
+ return !menu_is_popup(name)
+ && !menu_is_toolbar(name)
+ && *name != MNU_HIDDEN_CHAR;
+}
+
+/*
+ * Return TRUE if "name" is a popup menu name.
+ */
+int menu_is_popup(name)
+char_u *name;
+{
+ return STRNCMP(name, "PopUp", 5) == 0;
+}
+
+
+/*
+ * Return TRUE if "name" is a toolbar menu name.
+ */
+int menu_is_toolbar(name)
+char_u *name;
+{
+ return STRNCMP(name, "ToolBar", 7) == 0;
+}
+
+/*
+ * Return TRUE if the name is a menu separator identifier: Starts and ends
+ * with '-'
+ */
+int menu_is_separator(name)
+char_u *name;
+{
+ return name[0] == '-' && name[STRLEN(name) - 1] == '-';
+}
+
+/*
+ * Return TRUE if the menu is hidden: Starts with ']'
+ */
+static int menu_is_hidden(name)
+char_u *name;
+{
+ return (name[0] == ']') || (menu_is_popup(name) && name[5] != NUL);
+}
+
+#if defined(FEAT_CMDL_COMPL) \
+ || (defined(FEAT_GUI_W32) && defined(FEAT_TEAROFF))
+/*
+ * Return TRUE if the menu is the tearoff menu.
+ */
+static int menu_is_tearoff(name)
+char_u *name UNUSED;
+{
+ return FALSE;
+}
+#endif
+
+
+
+/*
+ * Given a menu descriptor, e.g. "File.New", find it in the menu hierarchy and
+ * execute it.
+ */
+void ex_emenu(eap)
+exarg_T *eap;
+{
+ vimmenu_T *menu;
+ char_u *name;
+ char_u *saved_name;
+ char_u *p;
+ int idx;
+ char_u *mode;
+
+ saved_name = vim_strsave(eap->arg);
+ if (saved_name == NULL)
+ return;
+
+ menu = root_menu;
+ name = saved_name;
+ while (*name) {
+ /* Find in the menu hierarchy */
+ p = menu_name_skip(name);
+
+ while (menu != NULL) {
+ if (menu_name_equal(name, menu)) {
+ if (*p == NUL && menu->children != NULL) {
+ EMSG(_("E333: Menu path must lead to a menu item"));
+ menu = NULL;
+ } else if (*p != NUL && menu->children == NULL) {
+ EMSG(_(e_notsubmenu));
+ menu = NULL;
+ }
+ break;
+ }
+ menu = menu->next;
+ }
+ if (menu == NULL || *p == NUL)
+ break;
+ menu = menu->children;
+ name = p;
+ }
+ vim_free(saved_name);
+ if (menu == NULL) {
+ EMSG2(_("E334: Menu not found: %s"), eap->arg);
+ return;
+ }
+
+ /* Found the menu, so execute.
+ * Use the Insert mode entry when returning to Insert mode. */
+ if (restart_edit
+ && !current_SID
+ ) {
+ mode = (char_u *)"Insert";
+ idx = MENU_INDEX_INSERT;
+ } else if (eap->addr_count) {
+ pos_T tpos;
+
+ mode = (char_u *)"Visual";
+ idx = MENU_INDEX_VISUAL;
+
+ /* GEDDES: This is not perfect - but it is a
+ * quick way of detecting whether we are doing this from a
+ * selection - see if the range matches up with the visual
+ * select start and end. */
+ if ((curbuf->b_visual.vi_start.lnum == eap->line1)
+ && (curbuf->b_visual.vi_end.lnum) == eap->line2) {
+ /* Set it up for visual mode - equivalent to gv. */
+ VIsual_mode = curbuf->b_visual.vi_mode;
+ tpos = curbuf->b_visual.vi_end;
+ curwin->w_cursor = curbuf->b_visual.vi_start;
+ curwin->w_curswant = curbuf->b_visual.vi_curswant;
+ } else {
+ /* Set it up for line-wise visual mode */
+ VIsual_mode = 'V';
+ curwin->w_cursor.lnum = eap->line1;
+ curwin->w_cursor.col = 1;
+ tpos.lnum = eap->line2;
+ tpos.col = MAXCOL;
+ tpos.coladd = 0;
+ }
+
+ /* Activate visual mode */
+ VIsual_active = TRUE;
+ VIsual_reselect = TRUE;
+ check_cursor();
+ VIsual = curwin->w_cursor;
+ curwin->w_cursor = tpos;
+
+ check_cursor();
+
+ /* Adjust the cursor to make sure it is in the correct pos
+ * for exclusive mode */
+ if (*p_sel == 'e' && gchar_cursor() != NUL)
+ ++curwin->w_cursor.col;
+ } else {
+ mode = (char_u *)"Normal";
+ 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)
+ 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
+ EMSG2(_("E335: Menu not defined for %s mode"), mode);
+}
+
+#if defined(FEAT_GUI_MSWIN) \
+ || (defined(FEAT_GUI_GTK) && defined(FEAT_MENU)) \
+ || defined(FEAT_BEVAL_TIP) || defined(PROTO)
+/*
+ * Given a menu descriptor, e.g. "File.New", find it in the menu hierarchy.
+ */
+vimmenu_T * gui_find_menu(path_name)
+char_u *path_name;
+{
+ vimmenu_T *menu = NULL;
+ char_u *name;
+ char_u *saved_name;
+ char_u *p;
+
+ menu = root_menu;
+
+ saved_name = vim_strsave(path_name);
+ if (saved_name == NULL)
+ return NULL;
+
+ name = saved_name;
+ while (*name) {
+ /* find the end of one dot-separated name and put a NUL at the dot */
+ p = menu_name_skip(name);
+
+ while (menu != NULL) {
+ if (menu_name_equal(name, menu)) {
+ if (menu->children == NULL) {
+ /* found a menu item instead of a sub-menu */
+ if (*p == NUL)
+ EMSG(_("E336: Menu path must lead to a sub-menu"));
+ else
+ EMSG(_(e_notsubmenu));
+ menu = NULL;
+ goto theend;
+ }
+ if (*p == NUL) /* found a full match */
+ goto theend;
+ break;
+ }
+ menu = menu->next;
+ }
+ if (menu == NULL) /* didn't find it */
+ break;
+
+ /* Found a match, search the sub-menu. */
+ menu = menu->children;
+ name = p;
+ }
+
+ if (menu == NULL)
+ EMSG(_("E337: Menu not found - check menu names"));
+theend:
+ vim_free(saved_name);
+ return menu;
+}
+#endif
+
+/*
+ * Translation of menu names. Just a simple lookup table.
+ */
+
+typedef struct {
+ char_u *from; /* English name */
+ char_u *from_noamp; /* same, without '&' */
+ char_u *to; /* translated name */
+} menutrans_T;
+
+static garray_T menutrans_ga = {0, 0, 0, 0, NULL};
+
+/*
+ * ":menutrans".
+ * This function is also defined without the +multi_lang feature, in which
+ * case the commands are ignored.
+ */
+void ex_menutranslate(eap)
+exarg_T *eap UNUSED;
+{
+ char_u *arg = eap->arg;
+ menutrans_T *tp;
+ int i;
+ char_u *from, *from_noamp, *to;
+
+ if (menutrans_ga.ga_itemsize == 0)
+ ga_init2(&menutrans_ga, (int)sizeof(menutrans_T), 5);
+
+ /*
+ * ":menutrans clear": clear all translations.
+ */
+ if (STRNCMP(arg, "clear", 5) == 0 && ends_excmd(*skipwhite(arg + 5))) {
+ tp = (menutrans_T *)menutrans_ga.ga_data;
+ for (i = 0; i < menutrans_ga.ga_len; ++i) {
+ vim_free(tp[i].from);
+ vim_free(tp[i].from_noamp);
+ vim_free(tp[i].to);
+ }
+ ga_clear(&menutrans_ga);
+ /* Delete all "menutrans_" global variables. */
+ del_menutrans_vars();
+ } else {
+ /* ":menutrans from to": add translation */
+ from = arg;
+ arg = menu_skip_part(arg);
+ to = skipwhite(arg);
+ *arg = NUL;
+ arg = menu_skip_part(to);
+ if (arg == to)
+ EMSG(_(e_invarg));
+ else {
+ if (ga_grow(&menutrans_ga, 1) == OK) {
+ tp = (menutrans_T *)menutrans_ga.ga_data;
+ from = vim_strsave(from);
+ if (from != NULL) {
+ from_noamp = menu_text(from, NULL, NULL);
+ to = vim_strnsave(to, (int)(arg - to));
+ if (from_noamp != NULL && to != NULL) {
+ menu_translate_tab_and_shift(from);
+ menu_translate_tab_and_shift(to);
+ menu_unescape_name(from);
+ menu_unescape_name(to);
+ tp[menutrans_ga.ga_len].from = from;
+ tp[menutrans_ga.ga_len].from_noamp = from_noamp;
+ tp[menutrans_ga.ga_len].to = to;
+ ++menutrans_ga.ga_len;
+ } else {
+ vim_free(from);
+ vim_free(from_noamp);
+ vim_free(to);
+ }
+ }
+ }
+ }
+ }
+}
+
+/*
+ * Find the character just after one part of a menu name.
+ */
+static char_u * menu_skip_part(p)
+char_u *p;
+{
+ while (*p != NUL && *p != '.' && !vim_iswhite(*p)) {
+ if ((*p == '\\' || *p == Ctrl_V) && p[1] != NUL)
+ ++p;
+ ++p;
+ }
+ return p;
+}
+
+/*
+ * Lookup part of a menu name in the translations.
+ * Return a pointer to the translation or NULL if not found.
+ */
+static char_u * menutrans_lookup(name, len)
+char_u *name;
+int len;
+{
+ menutrans_T *tp = (menutrans_T *)menutrans_ga.ga_data;
+ int i;
+ char_u *dname;
+
+ for (i = 0; i < menutrans_ga.ga_len; ++i)
+ if (STRNCMP(name, tp[i].from, len) == 0 && tp[i].from[len] == NUL)
+ return tp[i].to;
+
+ /* Now try again while ignoring '&' characters. */
+ i = name[len];
+ name[len] = NUL;
+ dname = menu_text(name, NULL, NULL);
+ name[len] = i;
+ if (dname != NULL) {
+ for (i = 0; i < menutrans_ga.ga_len; ++i)
+ if (STRCMP(dname, tp[i].from_noamp) == 0) {
+ vim_free(dname);
+ return tp[i].to;
+ }
+ vim_free(dname);
+ }
+
+ return NULL;
+}
+
+/*
+ * Unescape the name in the translate dictionary table.
+ */
+static void menu_unescape_name(name)
+char_u *name;
+{
+ char_u *p;
+
+ for (p = name; *p && *p != '.'; mb_ptr_adv(p))
+ if (*p == '\\')
+ STRMOVE(p, p + 1);
+}
+
+/*
+ * Isolate the menu name.
+ * Skip the menu name, and translate <Tab> into a real TAB.
+ */
+static char_u * menu_translate_tab_and_shift(arg_start)
+char_u *arg_start;
+{
+ char_u *arg = arg_start;
+
+ while (*arg && !vim_iswhite(*arg)) {
+ if ((*arg == '\\' || *arg == Ctrl_V) && arg[1] != NUL)
+ arg++;
+ else if (STRNICMP(arg, "<TAB>", 5) == 0) {
+ *arg = TAB;
+ STRMOVE(arg + 1, arg + 5);
+ }
+ arg++;
+ }
+ if (*arg != NUL)
+ *arg++ = NUL;
+ arg = skipwhite(arg);
+
+ return arg;
+}
+
diff --git a/src/message.c b/src/message.c
new file mode 100644
index 0000000000..9a9fd87f72
--- /dev/null
+++ b/src/message.c
@@ -0,0 +1,4004 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * 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.
+ */
+
+/*
+ * message.c: functions for displaying messages on the command line
+ */
+
+#define MESSAGE_FILE /* don't include prototype for smsg() */
+
+#include "vim.h"
+
+#if defined(FEAT_FLOAT) && defined(HAVE_MATH_H)
+# include <math.h>
+#endif
+
+static int other_sourcing_name __ARGS((void));
+static char_u *get_emsg_source __ARGS((void));
+static char_u *get_emsg_lnum __ARGS((void));
+static void add_msg_hist __ARGS((char_u *s, int len, int attr));
+static void hit_return_msg __ARGS((void));
+static void msg_home_replace_attr __ARGS((char_u *fname, int attr));
+static char_u *screen_puts_mbyte __ARGS((char_u *s, int l, int attr));
+static void msg_puts_attr_len __ARGS((char_u *str, int maxlen, int attr));
+static void msg_puts_display __ARGS((char_u *str, int maxlen, int attr,
+ int recurse));
+static void msg_scroll_up __ARGS((void));
+static void inc_msg_scrolled __ARGS((void));
+static void store_sb_text __ARGS((char_u **sb_str, char_u *s, int attr,
+ int *sb_col,
+ int finish));
+static void t_puts __ARGS((int *t_col, char_u *t_s, char_u *s, int attr));
+static void msg_puts_printf __ARGS((char_u *str, int maxlen));
+static int do_more_prompt __ARGS((int typed_char));
+static void msg_screen_putchar __ARGS((int c, int attr));
+static int msg_check_screen __ARGS((void));
+static void redir_write __ARGS((char_u *s, int maxlen));
+static char_u *msg_show_console_dialog __ARGS((char_u *message, char_u *buttons,
+ int dfltbutton));
+static int confirm_msg_used = FALSE; /* displaying confirm_msg */
+static char_u *confirm_msg = NULL; /* ":confirm" message */
+static char_u *confirm_msg_tail; /* tail of confirm_msg */
+
+struct msg_hist {
+ struct msg_hist *next;
+ char_u *msg;
+ int attr;
+};
+
+static struct msg_hist *first_msg_hist = NULL;
+static struct msg_hist *last_msg_hist = NULL;
+static int msg_hist_len = 0;
+
+static FILE *verbose_fd = NULL;
+static int verbose_did_open = FALSE;
+
+/*
+ * When writing messages to the screen, there are many different situations.
+ * A number of variables is used to remember the current state:
+ * msg_didany TRUE when messages were written since the last time the
+ * user reacted to a prompt.
+ * Reset: After hitting a key for the hit-return prompt,
+ * hitting <CR> for the command line or input().
+ * Set: When any message is written to the screen.
+ * msg_didout TRUE when something was written to the current line.
+ * Reset: When advancing to the next line, when the current
+ * text can be overwritten.
+ * Set: When any message is written to the screen.
+ * msg_nowait No extra delay for the last drawn message.
+ * Used in normal_cmd() before the mode message is drawn.
+ * emsg_on_display There was an error message recently. Indicates that there
+ * should be a delay before redrawing.
+ * msg_scroll The next message should not overwrite the current one.
+ * msg_scrolled How many lines the screen has been scrolled (because of
+ * messages). Used in update_screen() to scroll the screen
+ * back. Incremented each time the screen scrolls a line.
+ * msg_scrolled_ign TRUE when msg_scrolled is non-zero and msg_puts_attr()
+ * writes something without scrolling should not make
+ * need_wait_return to be set. This is a hack to make ":ts"
+ * work without an extra prompt.
+ * lines_left Number of lines available for messages before the
+ * more-prompt is to be given. -1 when not set.
+ * need_wait_return TRUE when the hit-return prompt is needed.
+ * Reset: After giving the hit-return prompt, when the user
+ * has answered some other prompt.
+ * Set: When the ruler or typeahead display is overwritten,
+ * scrolling the screen for some message.
+ * keep_msg Message to be displayed after redrawing the screen, in
+ * main_loop().
+ * This is an allocated string or NULL when not used.
+ */
+
+/*
+ * msg(s) - displays the string 's' on the status line
+ * When terminal not initialized (yet) mch_errmsg(..) is used.
+ * return TRUE if wait_return not called
+ */
+int msg(s)
+char_u *s;
+{
+ return msg_attr_keep(s, 0, FALSE);
+}
+
+#if defined(FEAT_EVAL) || defined(FEAT_X11) || defined(USE_XSMP) \
+ || defined(FEAT_GUI_GTK) || defined(PROTO)
+/*
+ * Like msg() but keep it silent when 'verbosefile' is set.
+ */
+int verb_msg(s)
+char_u *s;
+{
+ int n;
+
+ verbose_enter();
+ n = msg_attr_keep(s, 0, FALSE);
+ verbose_leave();
+
+ return n;
+}
+#endif
+
+int msg_attr(s, attr)
+char_u *s;
+int attr;
+{
+ return msg_attr_keep(s, attr, FALSE);
+}
+
+int msg_attr_keep(s, attr, keep)
+char_u *s;
+int attr;
+int keep; /* TRUE: set keep_msg if it doesn't scroll */
+{
+ static int entered = 0;
+ int retval;
+ char_u *buf = NULL;
+
+ if (attr == 0)
+ set_vim_var_string(VV_STATUSMSG, s, -1);
+
+ /*
+ * It is possible that displaying a messages causes a problem (e.g.,
+ * when redrawing the window), which causes another message, etc.. To
+ * break this loop, limit the recursiveness to 3 levels.
+ */
+ if (entered >= 3)
+ return TRUE;
+ ++entered;
+
+ /* Add message to history (unless it's a repeated kept message or a
+ * truncated message) */
+ if (s != keep_msg
+ || (*s != '<'
+ && last_msg_hist != NULL
+ && last_msg_hist->msg != NULL
+ && STRCMP(s, last_msg_hist->msg)))
+ add_msg_hist(s, -1, attr);
+
+ /* When displaying keep_msg, don't let msg_start() free it, caller must do
+ * that. */
+ if (s == keep_msg)
+ keep_msg = NULL;
+
+ /* Truncate the message if needed. */
+ msg_start();
+ buf = msg_strtrunc(s, FALSE);
+ if (buf != NULL)
+ s = buf;
+
+ msg_outtrans_attr(s, attr);
+ msg_clr_eos();
+ retval = msg_end();
+
+ if (keep && retval && vim_strsize(s) < (int)(Rows - cmdline_row - 1)
+ * Columns + sc_col)
+ set_keep_msg(s, 0);
+
+ vim_free(buf);
+ --entered;
+ return retval;
+}
+
+/*
+ * Truncate a string such that it can be printed without causing a scroll.
+ * Returns an allocated string or NULL when no truncating is done.
+ */
+char_u * msg_strtrunc(s, force)
+char_u *s;
+int force; /* always truncate */
+{
+ char_u *buf = NULL;
+ int len;
+ int room;
+
+ /* May truncate message to avoid a hit-return prompt */
+ if ((!msg_scroll && !need_wait_return && shortmess(SHM_TRUNCALL)
+ && !exmode_active && msg_silent == 0) || force) {
+ len = vim_strsize(s);
+ if (msg_scrolled != 0)
+ /* Use all the columns. */
+ room = (int)(Rows - msg_row) * Columns - 1;
+ else
+ /* Use up to 'showcmd' column. */
+ room = (int)(Rows - msg_row - 1) * Columns + sc_col - 1;
+ if (len > room && room > 0) {
+ if (enc_utf8)
+ /* may have up to 18 bytes per cell (6 per char, up to two
+ * composing chars) */
+ len = (room + 2) * 18;
+ else if (enc_dbcs == DBCS_JPNU)
+ /* may have up to 2 bytes per cell for euc-jp */
+ len = (room + 2) * 2;
+ else
+ len = room + 2;
+ buf = alloc(len);
+ if (buf != NULL)
+ trunc_string(s, buf, room, len);
+ }
+ }
+ return buf;
+}
+
+/*
+ * Truncate a string "s" to "buf" with cell width "room".
+ * "s" and "buf" may be equal.
+ */
+void trunc_string(s, buf, room, buflen)
+char_u *s;
+char_u *buf;
+int room;
+int buflen;
+{
+ int half;
+ int len;
+ int e;
+ int i;
+ int n;
+
+ room -= 3;
+ half = room / 2;
+ len = 0;
+
+ /* First part: Start of the string. */
+ for (e = 0; len < half && e < buflen; ++e) {
+ if (s[e] == NUL) {
+ /* text fits without truncating! */
+ buf[e] = NUL;
+ return;
+ }
+ n = ptr2cells(s + e);
+ if (len + n >= half)
+ break;
+ len += n;
+ buf[e] = s[e];
+ if (has_mbyte)
+ for (n = (*mb_ptr2len)(s + e); --n > 0; ) {
+ if (++e == buflen)
+ break;
+ buf[e] = s[e];
+ }
+ }
+
+ /* 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;
+ }
+ } else {
+ for (i = (int)STRLEN(s); len + (n = ptr2cells(s + i - 1)) <= room; --i)
+ len += n;
+ }
+
+ /* Set the middle and copy the last part. */
+ if (e + 3 < buflen) {
+ mch_memmove(buf + e, "...", (size_t)3);
+ len = (int)STRLEN(s + i) + 1;
+ if (len >= buflen - e - 3)
+ len = buflen - e - 3 - 1;
+ mch_memmove(buf + e + 3, s + i, len);
+ buf[e + 3 + len - 1] = NUL;
+ } else {
+ buf[e - 1] = NUL; /* make sure it is truncated */
+ }
+}
+
+/*
+ * Automatic prototype generation does not understand this function.
+ * Note: Caller of smgs() and smsg_attr() must check the resulting string is
+ * shorter than IOSIZE!!!
+ */
+# ifndef HAVE_STDARG_H
+
+int
+smsg __ARGS((char_u *, long, long, long,
+ long, long, long, long, long, long, long));
+int
+smsg_attr __ARGS((int, char_u *, long, long, long,
+ long, long, long, long, long, long, long));
+
+int vim_snprintf __ARGS((char *, size_t, char *, long, long, long,
+ long, long, long, long, long, long, long));
+
+/*
+ * smsg(str, arg, ...) is like using sprintf(buf, str, arg, ...) and then
+ * calling msg(buf).
+ * The buffer used is IObuff, the message is truncated at IOSIZE.
+ */
+
+/* VARARGS */
+int smsg(s, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10)
+char_u *s;
+long a1, a2, a3, a4, a5, a6, a7, a8, a9, a10;
+{
+ return smsg_attr(0, s, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
+}
+
+/* VARARGS */
+int smsg_attr(attr, s, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10)
+int attr;
+char_u *s;
+long a1, a2, a3, a4, a5, a6, a7, a8, a9, a10;
+{
+ vim_snprintf((char *)IObuff, IOSIZE, (char *)s,
+ a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
+ return msg_attr(IObuff, attr);
+}
+
+# else /* HAVE_STDARG_H */
+
+int vim_snprintf(char *str, size_t str_m, char *fmt, ...);
+
+int smsg(char_u *s, ...) {
+ va_list arglist;
+
+ va_start(arglist, s);
+ vim_vsnprintf((char *)IObuff, IOSIZE, (char *)s, arglist, NULL);
+ va_end(arglist);
+ return msg(IObuff);
+}
+
+int smsg_attr(int attr, char_u *s, ...) {
+ va_list arglist;
+
+ va_start(arglist, s);
+ vim_vsnprintf((char *)IObuff, IOSIZE, (char *)s, arglist, NULL);
+ va_end(arglist);
+ return msg_attr(IObuff, attr);
+}
+
+# endif /* HAVE_STDARG_H */
+
+/*
+ * Remember the last sourcing name/lnum used in an error message, so that it
+ * isn't printed each time when it didn't change.
+ */
+static int last_sourcing_lnum = 0;
+static char_u *last_sourcing_name = NULL;
+
+/*
+ * Reset the last used sourcing name/lnum. Makes sure it is displayed again
+ * for the next error message;
+ */
+void reset_last_sourcing() {
+ vim_free(last_sourcing_name);
+ last_sourcing_name = NULL;
+ last_sourcing_lnum = 0;
+}
+
+/*
+ * Return TRUE if "sourcing_name" differs from "last_sourcing_name".
+ */
+static int other_sourcing_name() {
+ if (sourcing_name != NULL) {
+ if (last_sourcing_name != NULL)
+ return STRCMP(sourcing_name, last_sourcing_name) != 0;
+ return TRUE;
+ }
+ 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() {
+ char_u *Buf, *p;
+
+ if (sourcing_name != NULL && other_sourcing_name()) {
+ p = (char_u *)_("Error detected while processing %s:");
+ Buf = alloc((unsigned)(STRLEN(sourcing_name) + STRLEN(p)));
+ if (Buf != NULL)
+ sprintf((char *)Buf, (char *)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() {
+ char_u *Buf, *p;
+
+ /* 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 = alloc((unsigned)(STRLEN(p) + 20));
+ if (Buf != NULL)
+ sprintf((char *)Buf, (char *)p, (long)sourcing_lnum);
+ return Buf;
+ }
+ return NULL;
+}
+
+/*
+ * Display name and line number for the source of an error.
+ * Remember the file name and line number, so that for the next error the info
+ * is only displayed if it changed.
+ */
+void msg_source(attr)
+int attr;
+{
+ char_u *p;
+
+ ++no_wait_return;
+ p = get_emsg_source();
+ if (p != NULL) {
+ msg_attr(p, attr);
+ vim_free(p);
+ }
+ p = get_emsg_lnum();
+ if (p != NULL) {
+ msg_attr(p, hl_attr(HLF_N));
+ vim_free(p);
+ last_sourcing_lnum = sourcing_lnum; /* only once for each line */
+ }
+
+ /* remember the last sourcing name printed, also when it's empty */
+ if (sourcing_name == NULL || other_sourcing_name()) {
+ vim_free(last_sourcing_name);
+ if (sourcing_name == NULL)
+ last_sourcing_name = NULL;
+ else
+ last_sourcing_name = vim_strsave(sourcing_name);
+ }
+ --no_wait_return;
+}
+
+/*
+ * Return TRUE if not giving error messages right now:
+ * If "emsg_off" is set: no error messages at the moment.
+ * If "msg" is in 'debug': do error message but without side effects.
+ * If "emsg_skip" is set: never do error messages.
+ */
+int emsg_not_now() {
+ if ((emsg_off > 0 && vim_strchr(p_debug, 'm') == NULL
+ && vim_strchr(p_debug, 't') == NULL)
+ || emsg_skip > 0
+ )
+ return TRUE;
+ return FALSE;
+}
+
+/*
+ * emsg() - display an error message
+ *
+ * Rings the bell, if appropriate, and calls message() to do the real work
+ * When terminal not initialized (yet) mch_errmsg(..) is used.
+ *
+ * return TRUE if wait_return not called
+ */
+int emsg(s)
+char_u *s;
+{
+ int attr;
+ char_u *p;
+ int ignore = FALSE;
+ int severe;
+
+ /* Skip this if not giving error messages at the moment. */
+ if (emsg_not_now())
+ return TRUE;
+
+ called_emsg = TRUE;
+ 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.
+ */
+ severe = emsg_severe;
+ emsg_severe = FALSE;
+
+ if (!emsg_off || vim_strchr(p_debug, 't') != NULL) {
+ /*
+ * Cause a throw of an error exception if appropriate. Don't display
+ * the error message in this case. (If no matching catch clause will
+ * be found, the message will be displayed later on.) "ignore" is set
+ * when the message should be ignored completely (used for the
+ * interrupt message).
+ */
+ if (cause_errthrow(s, severe, &ignore) == TRUE) {
+ if (!ignore)
+ did_emsg = TRUE;
+ return TRUE;
+ }
+
+ /* set "v:errmsg", also when using ":silent! cmd" */
+ 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, -1);
+ vim_free(p);
+ }
+ p = get_emsg_lnum();
+ if (p != NULL) {
+ STRCAT(p, "\n");
+ redir_write(p, -1);
+ vim_free(p);
+ }
+ redir_write(s, -1);
+ return TRUE;
+ }
+
+ /* Reset msg_silent, an error causes messages to be switched back on. */
+ msg_silent = 0;
+ cmd_silent = FALSE;
+
+ if (global_busy) /* break :global command */
+ ++global_busy;
+
+ if (p_eb)
+ beep_flush(); /* also includes flush_buffers() */
+ else
+ flush_buffers(FALSE); /* flush internal buffers */
+ did_emsg = TRUE; /* 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 */
+ if (msg_scrolled != 0)
+ need_wait_return = TRUE; /* needed in case emsg() is called after
+ * wait_return has reset need_wait_return
+ * and a redraw is expected because
+ * msg_scrolled is non-zero */
+
+ /*
+ * Display name and line number for the source of the error.
+ */
+ msg_source(attr);
+
+ /*
+ * Display the error message itself.
+ */
+ msg_nowait = FALSE; /* wait for this msg */
+ return msg_attr(s, attr);
+}
+
+/*
+ * Print an error message with one "%s" and one string argument.
+ */
+int emsg2(s, a1)
+char_u *s, *a1;
+{
+ return emsg3(s, a1, NULL);
+}
+
+/* emsg3() and emsgn() are in misc2.c to avoid warnings for the prototypes. */
+
+void emsg_invreg(name)
+int name;
+{
+ EMSG2(_("E354: Invalid register name: '%s'"), transchar(name));
+}
+
+/*
+ * Like msg(), but truncate to a single line if p_shm contains 't', or when
+ * "force" is TRUE. This truncates in another way as for normal messages.
+ * Careful: The string may be changed by msg_may_trunc()!
+ * Returns a pointer to the printed message, if wait_return() not called.
+ */
+char_u * msg_trunc_attr(s, force, attr)
+char_u *s;
+int force;
+int attr;
+{
+ int n;
+
+ /* Add message to history before truncating */
+ add_msg_hist(s, -1, attr);
+
+ s = msg_may_trunc(force, s);
+
+ msg_hist_off = TRUE;
+ n = msg_attr(s, attr);
+ msg_hist_off = FALSE;
+
+ if (n)
+ return s;
+ return NULL;
+}
+
+/*
+ * Check if message "s" should be truncated at the start (for filenames).
+ * Return a pointer to where the truncated message starts.
+ * Note: May change the message by replacing a character with '<'.
+ */
+char_u * msg_may_trunc(force, s)
+int force;
+char_u *s;
+{
+ int n;
+ int room;
+
+ room = (int)(Rows - cmdline_row - 1) * Columns + sc_col - 1;
+ if ((force || (shortmess(SHM_TRUNC) && !exmode_active))
+ && (n = (int)STRLEN(s) - room) > 0) {
+ if (has_mbyte) {
+ int size = vim_strsize(s);
+
+ /* There may be room anyway when there are multibyte chars. */
+ if (size <= room)
+ return s;
+
+ for (n = 0; size >= room; ) {
+ size -= (*mb_ptr2cells)(s + n);
+ n += (*mb_ptr2len)(s + n);
+ }
+ --n;
+ }
+ s += n;
+ *s = '<';
+ }
+ return s;
+}
+
+static void add_msg_hist(s, len, attr)
+char_u *s;
+int len; /* -1 for undetermined length */
+int attr;
+{
+ struct msg_hist *p;
+
+ if (msg_hist_off || msg_silent != 0)
+ return;
+
+ /* Don't let the message history get too big */
+ while (msg_hist_len > MAX_MSG_HIST_LEN)
+ (void)delete_first_msg();
+
+ /* allocate an entry and add the message at the end of the history */
+ p = (struct msg_hist *)alloc((int)sizeof(struct msg_hist));
+ if (p != NULL) {
+ if (len < 0)
+ len = (int)STRLEN(s);
+ /* remove leading and trailing newlines */
+ while (len > 0 && *s == '\n') {
+ ++s;
+ --len;
+ }
+ while (len > 0 && s[len - 1] == '\n')
+ --len;
+ p->msg = vim_strnsave(s, len);
+ p->next = NULL;
+ p->attr = attr;
+ if (last_msg_hist != NULL)
+ last_msg_hist->next = p;
+ last_msg_hist = p;
+ if (first_msg_hist == NULL)
+ first_msg_hist = last_msg_hist;
+ ++msg_hist_len;
+ }
+}
+
+/*
+ * Delete the first (oldest) message from the history.
+ * Returns FAIL if there are no messages.
+ */
+int delete_first_msg() {
+ struct msg_hist *p;
+
+ if (msg_hist_len <= 0)
+ return FAIL;
+ p = first_msg_hist;
+ first_msg_hist = p->next;
+ if (first_msg_hist == NULL)
+ last_msg_hist = NULL; /* history is empty */
+ vim_free(p->msg);
+ vim_free(p);
+ --msg_hist_len;
+ return OK;
+}
+
+/*
+ * ":messages" command.
+ */
+void ex_messages(eap)
+exarg_T *eap UNUSED;
+{
+ struct msg_hist *p;
+ char_u *s;
+
+ msg_hist_off = TRUE;
+
+ s = mch_getenv((char_u *)"LANG");
+ if (s != NULL && *s != NUL)
+ msg_attr((char_u *)
+ _("Messages maintainer: Bram Moolenaar <Bram@vim.org>"),
+ hl_attr(HLF_T));
+
+ for (p = first_msg_hist; p != NULL && !got_int; p = p->next)
+ if (p->msg != NULL)
+ msg_attr(p->msg, p->attr);
+
+ msg_hist_off = FALSE;
+}
+
+/*
+ * Call this after prompting the user. This will avoid a hit-return message
+ * and a delay.
+ */
+void msg_end_prompt() {
+ need_wait_return = FALSE;
+ emsg_on_display = FALSE;
+ cmdline_row = msg_row;
+ msg_col = 0;
+ msg_clr_eos();
+ 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
+ */
+void wait_return(redraw)
+int redraw;
+{
+ int c;
+ int oldState;
+ int tmpState;
+ int had_got_int;
+ int save_Recording;
+ FILE *save_scriptout;
+
+ if (redraw == TRUE)
+ must_redraw = CLEAR;
+
+ /* If using ":silent cmd", don't wait for a return. Also don't set
+ * need_wait_return to do it later. */
+ if (msg_silent != 0)
+ return;
+
+ /*
+ * When inside vgetc(), we can't wait for a typed character at all.
+ * With the global command (and some others) we only need one return at
+ * the end. Adjust cmdline_row to avoid the next message overwriting the
+ * last one.
+ */
+ if (vgetc_busy > 0)
+ return;
+ need_wait_return = TRUE;
+ if (no_wait_return) {
+ if (!exmode_active)
+ cmdline_row = msg_row;
+ return;
+ }
+
+ redir_off = TRUE; /* don't redirect this message */
+ oldState = State;
+ if (quit_more) {
+ c = CAR; /* just pretend CR was hit */
+ quit_more = FALSE;
+ got_int = FALSE;
+ } else if (exmode_active) {
+ MSG_PUTS(" "); /* make sure the cursor is on the right line */
+ c = CAR; /* no need for a return in ex mode */
+ got_int = FALSE;
+ } else {
+ /* Make sure the hit-return prompt is on screen when 'guioptions' was
+ * just changed. */
+ screenalloc(FALSE);
+
+ State = HITRETURN;
+ setmouse();
+#ifdef USE_ON_FLY_SCROLL
+ dont_scroll = TRUE; /* disallow scrolling here */
+#endif
+ /* Avoid the sequence that the user types ":" at the hit-return prompt
+ * to start an Ex command, but the file-changed dialog gets in the
+ * way. */
+ if (need_check_timestamps)
+ check_timestamps(FALSE);
+
+ hit_return_msg();
+
+ do {
+ /* Remember "got_int", if it is set vgetc() probably returns a
+ * 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;
+
+ /* 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;
+ Recording = save_Recording;
+ scriptout = save_scriptout;
+
+
+ /*
+ * Allow scrolling back in the messages.
+ * Also accept scroll-down commands when messages fill the screen,
+ * to avoid that typing one 'j' too many makes the messages
+ * disappear.
+ */
+ if (p_more && !p_cp) {
+ if (c == 'b' || c == 'k' || c == 'u' || c == 'g'
+ || c == K_UP || c == K_PAGEUP) {
+ if (msg_scrolled > Rows)
+ /* scroll back to show older messages */
+ do_more_prompt(c);
+ else {
+ msg_didout = FALSE;
+ c = K_IGNORE;
+ msg_col =
+ cmdmsg_rl ? Columns - 1 :
+ 0;
+ }
+ if (quit_more) {
+ c = CAR; /* just pretend CR was hit */
+ quit_more = FALSE;
+ got_int = FALSE;
+ } else if (c != K_IGNORE) {
+ c = K_IGNORE;
+ hit_return_msg();
+ }
+ } else if (msg_scrolled > Rows - 2
+ && (c == 'j' || c == 'd' || c == 'f'
+ || c == K_DOWN || c == K_PAGEDOWN))
+ c = K_IGNORE;
+ }
+ } while ((had_got_int && c == Ctrl_C)
+ || c == K_IGNORE
+ || c == K_LEFTDRAG || c == K_LEFTRELEASE
+ || c == K_MIDDLEDRAG || c == K_MIDDLERELEASE
+ || c == K_RIGHTDRAG || c == K_RIGHTRELEASE
+ || c == K_MOUSELEFT || c == K_MOUSERIGHT
+ || c == K_MOUSEDOWN || c == K_MOUSEUP
+ || (!mouse_has(MOUSE_RETURN)
+ && mouse_row < msg_row
+ && (c == K_LEFTMOUSE
+ || c == K_MIDDLEMOUSE
+ || c == K_RIGHTMOUSE
+ || c == K_X1MOUSE
+ || c == K_X2MOUSE))
+ );
+ ui_breakcheck();
+ /*
+ * Avoid that the mouse-up event causes visual mode to start.
+ */
+ if (c == K_LEFTMOUSE || c == K_MIDDLEMOUSE || c == K_RIGHTMOUSE
+ || c == K_X1MOUSE || c == K_X2MOUSE)
+ (void)jump_to_mouse(MOUSE_SETPOS, NULL, 0);
+ else if (vim_strchr((char_u *)"\r\n ", c) == NULL && c != Ctrl_C) {
+ /* Put the character back in the typeahead buffer. Don't use the
+ * stuff buffer, because lmaps wouldn't work. */
+ ins_char_typebuf(c);
+ do_redraw = TRUE; /* need a redraw even though there is
+ typeahead */
+ }
+ }
+ redir_off = FALSE;
+
+ /*
+ * If the user hits ':', '?' or '/' we get a command line from the next
+ * line.
+ */
+ if (c == ':' || c == '?' || c == '/') {
+ if (!exmode_active)
+ cmdline_row = msg_row;
+ skip_redraw = TRUE; /* skip redraw once */
+ do_redraw = FALSE;
+ }
+
+ /*
+ * If the window size changed set_shellsize() will redraw the screen.
+ * Otherwise the screen is only redrawn if 'redraw' is set and no ':'
+ * typed.
+ */
+ tmpState = State;
+ State = oldState; /* restore State before set_shellsize */
+ setmouse();
+ msg_check();
+
+#if defined(UNIX) || defined(VMS)
+ /*
+ * When switching screens, we need to output an extra newline on exit.
+ */
+ if (swapping_screen() && !termcap_active)
+ newline_on_exit = TRUE;
+#endif
+
+ need_wait_return = FALSE;
+ did_wait_return = TRUE;
+ emsg_on_display = FALSE; /* can delete error message now */
+ lines_left = -1; /* reset lines_left at next msg_start() */
+ reset_last_sourcing();
+ if (keep_msg != NULL && vim_strsize(keep_msg) >=
+ (Rows - cmdline_row - 1) * Columns + sc_col) {
+ vim_free(keep_msg);
+ keep_msg = NULL; /* don't redisplay message, it's too long */
+ }
+
+ if (tmpState == SETWSIZE) { /* got resize event while in vgetc() */
+ starttermcap(); /* start termcap before redrawing */
+ shell_resized();
+ } else if (!skip_redraw
+ && (redraw == TRUE || (msg_scrolled != 0 && redraw != -1))) {
+ starttermcap(); /* start termcap before redrawing */
+ redraw_later(VALID);
+ }
+}
+
+/*
+ * Write the hit-return prompt.
+ */
+static void hit_return_msg() {
+ int save_p_more = p_more;
+
+ p_more = FALSE; /* don't want see this message when scrolling back */
+ if (msg_didout) /* start on a new line */
+ msg_putchar('\n');
+ 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_clr_eos();
+ p_more = save_p_more;
+}
+
+/*
+ * Set "keep_msg" to "s". Free the old value and check for NULL pointer.
+ */
+void set_keep_msg(s, attr)
+char_u *s;
+int attr;
+{
+ vim_free(keep_msg);
+ if (s != NULL && msg_silent == 0)
+ keep_msg = vim_strsave(s);
+ else
+ keep_msg = NULL;
+ keep_msg_more = FALSE;
+ keep_msg_attr = attr;
+}
+
+/*
+ * If there currently is a message being displayed, set "keep_msg" to it, so
+ * that it will be displayed again after redraw.
+ */
+void set_keep_msg_from_hist() {
+ if (keep_msg == NULL && last_msg_hist != NULL && msg_scrolled == 0
+ && (State & NORMAL))
+ set_keep_msg(last_msg_hist->msg, last_msg_hist->attr);
+}
+
+/*
+ * Prepare for outputting characters in the command line.
+ */
+void msg_start() {
+ int did_return = FALSE;
+
+ if (!msg_silent) {
+ vim_free(keep_msg);
+ keep_msg = NULL; /* don't display old message now */
+ }
+
+ if (need_clr_eos) {
+ /* Halfway an ":echo" command and getting an (error) message: clear
+ * any text from the command. */
+ need_clr_eos = FALSE;
+ msg_clr_eos();
+ }
+
+ if (!msg_scroll && full_screen) { /* overwrite last message */
+ msg_row = cmdline_row;
+ msg_col =
+ cmdmsg_rl ? Columns - 1 :
+ 0;
+ } else if (msg_didout) { /* start message on next line */
+ msg_putchar('\n');
+ did_return = TRUE;
+ if (exmode_active != EXMODE_NORMAL)
+ cmdline_row = msg_row;
+ }
+ if (!msg_didany || lines_left < 0)
+ msg_starthere();
+ if (msg_silent == 0) {
+ msg_didout = FALSE; /* no output on current line yet */
+ cursor_off();
+ }
+
+ /* when redirecting, may need to start a new line. */
+ if (!did_return)
+ redir_write((char_u *)"\n", -1);
+}
+
+/*
+ * Note that the current msg position is where messages start.
+ */
+void msg_starthere() {
+ lines_left = cmdline_row;
+ msg_didany = FALSE;
+}
+
+void msg_putchar(c)
+int c;
+{
+ msg_putchar_attr(c, 0);
+}
+
+void msg_putchar_attr(c, attr)
+int c;
+int attr;
+{
+ char_u buf[MB_MAXBYTES + 1];
+
+ if (IS_SPECIAL(c)) {
+ buf[0] = K_SPECIAL;
+ buf[1] = K_SECOND(c);
+ buf[2] = K_THIRD(c);
+ buf[3] = NUL;
+ } else {
+ buf[(*mb_char2bytes)(c, buf)] = NUL;
+ }
+ msg_puts_attr(buf, attr);
+}
+
+void msg_outnum(n)
+long n;
+{
+ char_u buf[20];
+
+ sprintf((char *)buf, "%ld", n);
+ msg_puts(buf);
+}
+
+void msg_home_replace(fname)
+char_u *fname;
+{
+ msg_home_replace_attr(fname, 0);
+}
+
+void msg_home_replace_hl(fname)
+char_u *fname;
+{
+ msg_home_replace_attr(fname, hl_attr(HLF_D));
+}
+
+static void msg_home_replace_attr(fname, attr)
+char_u *fname;
+int attr;
+{
+ char_u *name;
+
+ name = home_replace_save(NULL, fname);
+ if (name != NULL)
+ msg_outtrans_attr(name, attr);
+ vim_free(name);
+}
+
+/*
+ * Output 'len' characters in 'str' (including NULs) with translation
+ * if 'len' is -1, output upto a NUL character.
+ * Use attributes 'attr'.
+ * Return the number of characters it takes on the screen.
+ */
+int msg_outtrans(str)
+char_u *str;
+{
+ return msg_outtrans_attr(str, 0);
+}
+
+int msg_outtrans_attr(str, attr)
+char_u *str;
+int attr;
+{
+ return msg_outtrans_len_attr(str, (int)STRLEN(str), attr);
+}
+
+int msg_outtrans_len(str, len)
+char_u *str;
+int len;
+{
+ return msg_outtrans_len_attr(str, len, 0);
+}
+
+/*
+ * Output one character at "p". Return pointer to the next character.
+ * Handles multi-byte characters.
+ */
+char_u * msg_outtrans_one(p, attr)
+char_u *p;
+int attr;
+{
+ int l;
+
+ if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1) {
+ msg_outtrans_len_attr(p, l, attr);
+ return p + l;
+ }
+ msg_puts_attr(transchar_byte(*p), attr);
+ return p + 1;
+}
+
+int msg_outtrans_len_attr(msgstr, len, attr)
+char_u *msgstr;
+int len;
+int attr;
+{
+ int retval = 0;
+ char_u *str = msgstr;
+ char_u *plain_start = msgstr;
+ char_u *s;
+ int mb_l;
+ int c;
+
+ /* if MSG_HIST flag set, add message to history */
+ if (attr & MSG_HIST) {
+ add_msg_hist(str, len, 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);
+
+ /*
+ * 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);
+ plain_start = str + mb_l;
+ msg_puts_attr(transchar(c), attr == 0 ? hl_attr(HLF_8) : attr);
+ retval += char2cells(c);
+ }
+ len -= mb_l - 1;
+ str += mb_l;
+ } else {
+ s = transchar_byte(*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);
+ plain_start = str + 1;
+ msg_puts_attr(s, attr == 0 ? hl_attr(HLF_8) : attr);
+ retval += (int)STRLEN(s);
+ } 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);
+
+ return retval;
+}
+
+void msg_make(arg)
+char_u *arg;
+{
+ int i;
+ static char_u *str = (char_u *)"eeffoc", *rs = (char_u *)"Plon#dqg#vxjduB";
+
+ arg = skipwhite(arg);
+ for (i = 5; *arg && i >= 0; --i)
+ if (*arg++ != str[i])
+ break;
+ if (i < 0) {
+ msg_putchar('\n');
+ for (i = 0; rs[i]; ++i)
+ msg_putchar(rs[i] - 3);
+ }
+}
+
+/*
+ * 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(strstart, from)
+char_u *strstart;
+int from; /* TRUE for lhs of a mapping */
+{
+ char_u *str = strstart;
+ int retval = 0;
+ char_u *string;
+ int attr;
+ int len;
+
+ attr = hl_attr(HLF_8);
+ while (*str != NUL) {
+ /* 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);
+ 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(str, is_lhs)
+char_u *str;
+int is_lhs; /* TRUE for lhs, FALSE for rhs */
+{
+ garray_T ga;
+ char_u *p = str;
+
+ ga_init2(&ga, 1, 40);
+ while (*p != NUL)
+ ga_concat(&ga, str2special(&p, is_lhs));
+ ga_append(&ga, NUL);
+ return (char_u *)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(sp, from)
+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;
+ }
+
+ c = *str;
+ if (c == K_SPECIAL && str[1] != NUL && str[2] != NUL) {
+ if (str[1] == KS_MODIFIER) {
+ modifiers = str[2];
+ str += 3;
+ c = *str;
+ }
+ if (c == K_SPECIAL && str[1] != NUL && str[2] != NUL) {
+ c = TO_SPECIAL(str[1], 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 (has_mbyte && !IS_SPECIAL(c)) {
+ int len = (*mb_ptr2len)(str);
+
+ /* For multi-byte characters check for an illegal byte. */
+ if (has_mbyte && MB_BYTE2LEN(*str) > len) {
+ transchar_nonprint(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);
+ *sp = str + len;
+ } 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;
+ buf[1] = NUL;
+ return buf;
+}
+
+/*
+ * Translate a key sequence into special key names.
+ */
+void str2specialbuf(sp, buf, len)
+char_u *sp;
+char_u *buf;
+int len;
+{
+ char_u *s;
+
+ *buf = NUL;
+ while (*sp) {
+ s = str2special(&sp, FALSE);
+ if ((int)(STRLEN(s) + STRLEN(buf)) < len)
+ STRCAT(buf, s);
+ }
+}
+
+/*
+ * print line for :print or :list command
+ */
+void msg_prt_line(s, list)
+char_u *s;
+int list;
+{
+ int c;
+ int col = 0;
+ int n_extra = 0;
+ int c_extra = 0;
+ char_u *p_extra = NULL; /* init to make SASC shut up */
+ int n;
+ int attr = 0;
+ char_u *trail = NULL;
+ int l;
+ char_u buf[MB_MAXBYTES + 1];
+
+ if (curwin->w_p_list)
+ list = TRUE;
+
+ /* find start of trailing whitespace */
+ if (list && lcs_trail) {
+ trail = s + STRLEN(s);
+ while (trail > s && vim_iswhite(trail[-1]))
+ --trail;
+ }
+
+ /* output a space for an empty line, otherwise the line will be
+ * overwritten */
+ if (*s == NUL && !(list && lcs_eol != NUL))
+ msg_putchar(' ');
+
+ while (!got_int) {
+ if (n_extra > 0) {
+ --n_extra;
+ if (c_extra)
+ c = c_extra;
+ else
+ c = *p_extra++;
+ } else if (has_mbyte && (l = (*mb_ptr2len)(s)) > 1) {
+ col += (*mb_ptr2cells)(s);
+ if (lcs_nbsp != NUL && list && mb_ptr2char(s) == 160) {
+ mb_char2bytes(lcs_nbsp, buf);
+ buf[(*mb_ptr2len)(buf)] = NUL;
+ } else {
+ mch_memmove(buf, s, (size_t)l);
+ buf[l] = NUL;
+ }
+ msg_puts(buf);
+ s += l;
+ continue;
+ } else {
+ attr = 0;
+ c = *s++;
+ if (c == TAB && (!list || lcs_tab1)) {
+ /* tab amount depends on current column */
+ n_extra = curbuf->b_p_ts - col % curbuf->b_p_ts - 1;
+ if (!list) {
+ c = ' ';
+ c_extra = ' ';
+ } else {
+ c = lcs_tab1;
+ c_extra = lcs_tab2;
+ attr = hl_attr(HLF_8);
+ }
+ } else if (c == 160 && list && lcs_nbsp != NUL) {
+ c = lcs_nbsp;
+ 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;
+ } else if (c != NUL && (n = byte2cells(c)) > 1) {
+ n_extra = n - 1;
+ p_extra = transchar_byte(c);
+ c_extra = NUL;
+ c = *p_extra++;
+ /* Use special coloring to be able to distinguish <hex> from
+ * the same in plain text. */
+ attr = hl_attr(HLF_8);
+ } else if (c == ' ' && trail != NULL && s > trail) {
+ c = lcs_trail;
+ attr = hl_attr(HLF_8);
+ }
+ }
+
+ if (c == NUL)
+ break;
+
+ msg_putchar_attr(c, attr);
+ col++;
+ }
+ msg_clr_eos();
+}
+
+/*
+ * Use screen_puts() to output one multi-byte character.
+ * Return the pointer "s" advanced to the next character.
+ */
+static char_u * screen_puts_mbyte(s, l, attr)
+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));
+ return s;
+ }
+
+ screen_puts_len(s, l, msg_row, msg_col, attr);
+ if (cmdmsg_rl) {
+ msg_col -= cw;
+ if (msg_col == 0) {
+ msg_col = Columns;
+ ++msg_row;
+ }
+ } else {
+ msg_col += cw;
+ if (msg_col >= Columns) {
+ msg_col = 0;
+ ++msg_row;
+ }
+ }
+ return s + l;
+}
+
+/*
+ * 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(s)
+char_u *s;
+{
+ msg_puts_attr(s, 0);
+}
+
+void msg_puts_title(s)
+char_u *s;
+{
+ msg_puts_attr(s, hl_attr(HLF_T));
+}
+
+/*
+ * Show a message in such a way that it always fits in the line. Cut out a
+ * part in the middle and replace it with "..." when necessary.
+ * Does not handle multi-byte characters!
+ */
+void msg_puts_long_attr(longstr, attr)
+char_u *longstr;
+int attr;
+{
+ msg_puts_long_len_attr(longstr, (int)STRLEN(longstr), attr);
+}
+
+void msg_puts_long_len_attr(longstr, len, attr)
+char_u *longstr;
+int len;
+int attr;
+{
+ int slen = len;
+ int room;
+
+ room = Columns - msg_col;
+ 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_outtrans_len_attr(longstr + len - slen, slen, attr);
+}
+
+/*
+ * Basic function for writing a message with highlight attributes.
+ */
+void msg_puts_attr(s, attr)
+char_u *s;
+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(str, maxlen, attr)
+char_u *str;
+int maxlen;
+int attr;
+{
+ /*
+ * If redirection is on, also write to the redirection file.
+ */
+ redir_write(str, maxlen);
+
+ /*
+ * Don't print anything when using ":silent cmd".
+ */
+ if (msg_silent != 0)
+ return;
+
+ /* if MSG_HIST flag set, add message to history */
+ if ((attr & MSG_HIST) && maxlen < 0) {
+ add_msg_hist(str, -1, attr);
+ attr &= ~MSG_HIST;
+ }
+
+ /*
+ * When writing something to the screen after it has scrolled, requires a
+ * wait-return prompt later. Needed when scrolling, resetting
+ * need_wait_return after some prompt, and then outputting something
+ * without scrolling
+ */
+ if (msg_scrolled != 0 && !msg_scrolled_ign)
+ need_wait_return = TRUE;
+ msg_didany = TRUE; /* remember that something was outputted */
+
+ /*
+ * If there is no valid screen, use fprintf so we can see error messages.
+ * If termcap is not active, we may be writing in an alternate console
+ * window, cursor positioning may not work correctly (window size may be
+ * different, e.g. for Win32 console) or we just don't know where the
+ * cursor is.
+ */
+ if (msg_use_printf())
+ msg_puts_printf(str, maxlen);
+ else
+ msg_puts_display(str, maxlen, attr, FALSE);
+}
+
+/*
+ * The display part of msg_puts_attr_len().
+ * May be called recursively to display scroll-back text.
+ */
+static void msg_puts_display(str, maxlen, attr, recurse)
+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 */
+ int l;
+ int cw;
+ char_u *sb_str = str;
+ int sb_col = msg_col;
+ int wrap;
+ int did_last_char;
+
+ did_wait_return = FALSE;
+ while ((maxlen < 0 || (int)(s - str) < maxlen) && *s != NUL) {
+ /*
+ * We are at the end of the screen line when:
+ * - When outputting a newline.
+ * - When outputting a character in the last column.
+ */
+ if (!recurse && msg_row >= Rows - 1 && (*s == '\n' || (
+ cmdmsg_rl
+ ? (
+ msg_col <= 1
+ || (*s == TAB && msg_col <= 7)
+ || (has_mbyte &&
+ (*mb_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
+ && 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
+ * ourselves).
+ */
+ if (t_col > 0)
+ /* output postponed text */
+ t_puts(&t_col, t_s, s, attr);
+
+ /* When no more prompt and no more room, truncate here */
+ if (msg_no_more && lines_left == 0)
+ break;
+
+ /* Scroll the screen up one line. */
+ msg_scroll_up();
+
+ msg_row = Rows - 2;
+ 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);
+
+ 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;
+
+ /*
+ * If screen is completely filled and 'more' is set then wait
+ * for a character.
+ */
+ if (lines_left > 0)
+ --lines_left;
+ if (p_more && lines_left == 0 && State != HITRETURN
+ && !msg_no_more && !exmode_active) {
+ if (do_more_prompt(NUL))
+ s = confirm_msg_tail;
+ if (quit_more)
+ return;
+ }
+
+ /* When we displayed a char in last column need to check if there
+ * is still more. */
+ if (did_last_char)
+ continue;
+ }
+
+ wrap = *s == '\n'
+ || msg_col + t_col >= Columns
+ || (has_mbyte && (*mb_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 */
+ 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 (*s == '\n') { /* go to next line */
+ msg_didout = FALSE; /* remember that line is empty */
+ if (cmdmsg_rl)
+ msg_col = Columns - 1;
+ else
+ msg_col = 0;
+ if (++msg_row >= Rows) /* safety check */
+ msg_row = Rows - 1;
+ } else if (*s == '\r') { /* go to column 0 */
+ msg_col = 0;
+ } else if (*s == '\b') { /* go to previous char */
+ if (msg_col)
+ --msg_col;
+ } else if (*s == TAB) { /* translate Tab into spaces */
+ do
+ msg_screen_putchar(' ', attr);
+ while (msg_col & 7);
+ } else if (*s == BELL) /* beep (from ":sh") */
+ vim_beep();
+ 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 {
+ cw = 1;
+ l = 1;
+ }
+ /* 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;
+ else
+ msg_screen_putchar(*s, attr);
+ } else {
+ /* postpone this character until later */
+ if (t_col == 0)
+ t_s = s;
+ t_col += cw;
+ s += l - 1;
+ }
+ }
+ ++s;
+ }
+
+ /* 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);
+
+ msg_check();
+}
+
+/*
+ * Scroll the screen up one line for displaying the next message line.
+ */
+static void msg_scroll_up() {
+ /* scrolling up always works */
+ screen_del_lines(0, 0, 1, (int)Rows, TRUE, NULL);
+
+ if (!can_clear((char_u *)" ")) {
+ /* Scrolling up doesn't result in the right background. Set the
+ * background here. It's not efficient, but avoids that we have to do
+ * it all over the code. */
+ screen_fill((int)Rows - 1, (int)Rows, 0, (int)Columns, ' ', ' ', 0);
+
+ /* Also clear the last char of the last but one line if it was not
+ * cleared before to avoid a scroll-up. */
+ if (ScreenAttrs[LineOffset[Rows - 2] + Columns - 1] == (sattr_T)-1)
+ screen_fill((int)Rows - 2, (int)Rows - 1,
+ (int)Columns - 1, (int)Columns, ' ', ' ', 0);
+ }
+}
+
+/*
+ * Increment "msg_scrolled".
+ */
+static void inc_msg_scrolled() {
+ if (*get_vim_var_str(VV_SCROLLSTART) == NUL) {
+ char_u *p = sourcing_name;
+ char_u *tofree = NULL;
+ int len;
+
+ /* v:scrollstart is empty, set it to the script/function name and line
+ * number */
+ if (p == NULL)
+ p = (char_u *)_("Unknown");
+ else {
+ len = (int)STRLEN(p) + 40;
+ tofree = alloc(len);
+ if (tofree != NULL) {
+ vim_snprintf((char *)tofree, len, _("%s line %ld"),
+ p, (long)sourcing_lnum);
+ p = tofree;
+ }
+ }
+ set_vim_var_string(VV_SCROLLSTART, p, -1);
+ vim_free(tofree);
+ }
+ ++msg_scrolled;
+}
+
+/*
+ * To be able to scroll back at the "more" and "hit-enter" prompts we need to
+ * store the displayed text and remember where screen lines start.
+ */
+typedef struct msgchunk_S msgchunk_T;
+struct msgchunk_S {
+ msgchunk_T *sb_next;
+ msgchunk_T *sb_prev;
+ char sb_eol; /* TRUE when line ends after this text */
+ int sb_msg_col; /* column in which text starts */
+ int sb_attr; /* text attributes */
+ char_u sb_text[1]; /* text to be displayed, actually longer */
+};
+
+static msgchunk_T *last_msgchunk = NULL; /* last displayed text */
+
+static msgchunk_T *msg_sb_start __ARGS((msgchunk_T *mps));
+static msgchunk_T *disp_sb_line __ARGS((int row, msgchunk_T *smp));
+
+static int do_clear_sb_text = FALSE; /* clear text on next msg */
+
+/*
+ * Store part of a printed message for displaying when scrolling back.
+ */
+static void store_sb_text(sb_str, s, attr, sb_col, finish)
+char_u **sb_str; /* start of string */
+char_u *s; /* just after string */
+int attr;
+int *sb_col;
+int finish; /* line ends */
+{
+ msgchunk_T *mp;
+
+ if (do_clear_sb_text) {
+ clear_sb_text();
+ do_clear_sb_text = FALSE;
+ }
+
+ if (s > *sb_str) {
+ mp = (msgchunk_T *)alloc((int)(sizeof(msgchunk_T) + (s - *sb_str)));
+ if (mp != NULL) {
+ mp->sb_eol = finish;
+ mp->sb_msg_col = *sb_col;
+ mp->sb_attr = attr;
+ vim_strncpy(mp->sb_text, *sb_str, s - *sb_str);
+
+ if (last_msgchunk == NULL) {
+ last_msgchunk = mp;
+ mp->sb_prev = NULL;
+ } else {
+ mp->sb_prev = last_msgchunk;
+ last_msgchunk->sb_next = mp;
+ last_msgchunk = mp;
+ }
+ mp->sb_next = NULL;
+ }
+ } else if (finish && last_msgchunk != NULL)
+ last_msgchunk->sb_eol = TRUE;
+
+ *sb_str = s;
+ *sb_col = 0;
+}
+
+/*
+ * Finished showing messages, clear the scroll-back text on the next message.
+ */
+void may_clear_sb_text() {
+ do_clear_sb_text = TRUE;
+}
+
+/*
+ * Clear any text remembered for scrolling back.
+ * Called when redrawing the screen.
+ */
+void clear_sb_text() {
+ msgchunk_T *mp;
+
+ while (last_msgchunk != NULL) {
+ mp = last_msgchunk->sb_prev;
+ vim_free(last_msgchunk);
+ last_msgchunk = mp;
+ }
+}
+
+/*
+ * "g<" command.
+ */
+void show_sb_text() {
+ msgchunk_T *mp;
+
+ /* Only show something if there is more than one line, otherwise it looks
+ * weird, typing a command without output results in one line. */
+ mp = msg_sb_start(last_msgchunk);
+ if (mp == NULL || mp->sb_prev == NULL)
+ vim_beep();
+ else {
+ do_more_prompt('G');
+ wait_return(FALSE);
+ }
+}
+
+/*
+ * Move to the start of screen line in already displayed text.
+ */
+static msgchunk_T * msg_sb_start(mps)
+msgchunk_T *mps;
+{
+ msgchunk_T *mp = mps;
+
+ while (mp != NULL && mp->sb_prev != NULL && !mp->sb_prev->sb_eol)
+ mp = mp->sb_prev;
+ return mp;
+}
+
+/*
+ * Mark the last message chunk as finishing the line.
+ */
+void msg_sb_eol() {
+ if (last_msgchunk != NULL)
+ last_msgchunk->sb_eol = TRUE;
+}
+
+/*
+ * Display a screen line from previously displayed text at row "row".
+ * Returns a pointer to the text for the next line (can be NULL).
+ */
+static msgchunk_T * disp_sb_line(row, smp)
+int row;
+msgchunk_T *smp;
+{
+ msgchunk_T *mp = smp;
+ char_u *p;
+
+ for (;; ) {
+ msg_row = row;
+ msg_col = mp->sb_msg_col;
+ p = mp->sb_text;
+ if (*p == '\n') /* don't display the line break */
+ ++p;
+ msg_puts_display(p, -1, mp->sb_attr, TRUE);
+ if (mp->sb_eol || mp->sb_next == NULL)
+ break;
+ mp = mp->sb_next;
+ }
+ return mp->sb_next;
+}
+
+/*
+ * Output any postponed text for msg_puts_attr_len().
+ */
+static void t_puts(t_col, t_s, s, attr)
+int *t_col;
+char_u *t_s;
+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);
+ msg_col += *t_col;
+ *t_col = 0;
+ /* If the string starts with a composing character don't increment the
+ * column position for it. */
+ if (enc_utf8 && utf_iscomposing(utf_ptr2char(t_s)))
+ --msg_col;
+ if (msg_col >= Columns) {
+ msg_col = 0;
+ ++msg_row;
+ }
+}
+
+/*
+ * Returns TRUE when messages should be printed with mch_errmsg().
+ * This is used when there is no valid screen, so we can see error messages.
+ * If termcap is not active, we may be writing in an alternate console
+ * window, cursor positioning may not work correctly (window size may be
+ * different, e.g. for Win32 console) or we just don't know where the
+ * cursor is.
+ */
+int msg_use_printf() {
+ return !msg_check_screen()
+ || (swapping_screen() && !termcap_active)
+ ;
+}
+
+/*
+ * Print a message when there is no valid screen.
+ */
+static void msg_puts_printf(str, maxlen)
+char_u *str;
+int maxlen;
+{
+ char_u *s = str;
+ char_u buf[4];
+ char_u *p;
+
+ while (*s != NUL && (maxlen < 0 || (int)(s - str) < maxlen)) {
+ if (!(silent_mode && p_verbose == 0)) {
+ /* NL --> CR NL translation (for Unix, not for "--version") */
+ /* NL --> CR translation (for Mac) */
+ p = &buf[0];
+ if (*s == '\n' && !info_message)
+ *p++ = '\r';
+#if defined(USE_CR) && !defined(MACOS_X_UNIX)
+ else
+#endif
+ *p++ = *s;
+ *p = '\0';
+ if (info_message) /* informative message, not an error */
+ mch_msg((char *)buf);
+ else
+ mch_errmsg((char *)buf);
+ }
+
+ /* primitive way to compute the current column */
+ if (cmdmsg_rl) {
+ if (*s == '\r' || *s == '\n')
+ msg_col = Columns - 1;
+ else
+ --msg_col;
+ } else {
+ if (*s == '\r' || *s == '\n')
+ msg_col = 0;
+ else
+ ++msg_col;
+ }
+ ++s;
+ }
+ msg_didout = TRUE; /* assume that line is not empty */
+
+}
+
+/*
+ * Show the more-prompt and handle the user response.
+ * This takes care of scrolling back and displaying previously displayed text.
+ * When at hit-enter prompt "typed_char" is the already typed character,
+ * otherwise it's NUL.
+ * Returns TRUE when jumping ahead to "confirm_msg_tail".
+ */
+static int do_more_prompt(typed_char)
+int typed_char;
+{
+ int used_typed_char = typed_char;
+ int oldState = State;
+ int c;
+ int retval = FALSE;
+ int toscroll;
+ msgchunk_T *mp_last = NULL;
+ msgchunk_T *mp;
+ int i;
+
+ if (typed_char == 'G') {
+ /* "g<": Find first line on the last page. */
+ mp_last = msg_sb_start(last_msgchunk);
+ for (i = 0; i < Rows - 2 && mp_last != NULL
+ && mp_last->sb_prev != NULL; ++i)
+ mp_last = msg_sb_start(mp_last->sb_prev);
+ }
+
+ State = ASKMORE;
+ setmouse();
+ if (typed_char == NUL)
+ msg_moremsg(FALSE);
+ for (;; ) {
+ /*
+ * Get a typed character directly from the user.
+ */
+ if (used_typed_char != NUL) {
+ c = used_typed_char; /* was typed at hit-enter prompt */
+ used_typed_char = NUL;
+ } else
+ c = get_keystroke();
+
+
+ toscroll = 0;
+ switch (c) {
+ case BS: /* scroll one line back */
+ case K_BS:
+ case 'k':
+ case K_UP:
+ toscroll = -1;
+ break;
+
+ case CAR: /* one extra line */
+ case NL:
+ case 'j':
+ case K_DOWN:
+ toscroll = 1;
+ break;
+
+ case 'u': /* Up half a page */
+ toscroll = -(Rows / 2);
+ break;
+
+ case 'd': /* Down half a page */
+ toscroll = Rows / 2;
+ break;
+
+ case 'b': /* one page back */
+ case K_PAGEUP:
+ toscroll = -(Rows - 1);
+ break;
+
+ case ' ': /* one extra page */
+ case 'f':
+ case K_PAGEDOWN:
+ case K_LEFTMOUSE:
+ toscroll = Rows - 1;
+ break;
+
+ case 'g': /* all the way back to the start */
+ toscroll = -999999;
+ break;
+
+ case 'G': /* all the way to the end */
+ toscroll = 999999;
+ lines_left = 999999;
+ break;
+
+ case ':': /* start new command line */
+ if (!confirm_msg_used) {
+ /* Since got_int is set all typeahead will be flushed, but we
+ * want to keep this ':', remember that in a special way. */
+ typeahead_noflush(':');
+ cmdline_row = Rows - 1; /* put ':' on this line */
+ skip_redraw = TRUE; /* skip redraw once */
+ need_wait_return = FALSE; /* don't wait in main() */
+ }
+ /*FALLTHROUGH*/
+ case 'q': /* quit */
+ case Ctrl_C:
+ case ESC:
+ if (confirm_msg_used) {
+ /* Jump to the choices of the dialog. */
+ retval = TRUE;
+ } else {
+ got_int = TRUE;
+ quit_more = TRUE;
+ }
+ /* When there is some more output (wrapping line) display that
+ * without another prompt. */
+ lines_left = Rows - 1;
+ break;
+
+ default: /* no valid response */
+ msg_moremsg(TRUE);
+ continue;
+ }
+
+ if (toscroll != 0) {
+ if (toscroll < 0) {
+ /* go to start of last line */
+ if (mp_last == NULL)
+ mp = msg_sb_start(last_msgchunk);
+ else if (mp_last->sb_prev != NULL)
+ mp = msg_sb_start(mp_last->sb_prev);
+ else
+ mp = NULL;
+
+ /* go to start of line at top of the screen */
+ for (i = 0; i < Rows - 2 && mp != NULL && mp->sb_prev != NULL;
+ ++i)
+ mp = msg_sb_start(mp->sb_prev);
+
+ if (mp != NULL && mp->sb_prev != NULL) {
+ /* Find line to be displayed at top. */
+ for (i = 0; i > toscroll; --i) {
+ if (mp == NULL || mp->sb_prev == NULL)
+ break;
+ mp = msg_sb_start(mp->sb_prev);
+ if (mp_last == NULL)
+ mp_last = msg_sb_start(last_msgchunk);
+ else
+ 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 */
+ (void)disp_sb_line(0, mp);
+ } else {
+ /* redisplay all lines */
+ screenclear();
+ for (i = 0; mp != NULL && i < Rows - 1; ++i) {
+ mp = disp_sb_line(i, mp);
+ ++msg_scrolled;
+ }
+ }
+ toscroll = 0;
+ }
+ } else {
+ /* First display any text that we scrolled back. */
+ while (toscroll > 0 && mp_last != NULL) {
+ /* scroll up, display line at bottom */
+ msg_scroll_up();
+ inc_msg_scrolled();
+ screen_fill((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);
+ continue;
+ }
+
+ /* display more text, return to caller */
+ lines_left = toscroll;
+ }
+
+ break;
+ }
+
+ /* clear the --more-- message */
+ screen_fill((int)Rows - 1, (int)Rows, 0, (int)Columns, ' ', ' ', 0);
+ State = oldState;
+ setmouse();
+ if (quit_more) {
+ msg_row = Rows - 1;
+ msg_col = 0;
+ } else if (cmdmsg_rl)
+ msg_col = Columns - 1;
+
+ return retval;
+}
+
+#if defined(USE_MCH_ERRMSG) || defined(PROTO)
+
+#ifdef mch_errmsg
+# undef mch_errmsg
+#endif
+#ifdef mch_msg
+# undef mch_msg
+#endif
+
+/*
+ * Give an error message. To be used when the screen hasn't been initialized
+ * 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(str)
+char *str;
+{
+ int len;
+
+#if (defined(UNIX) || defined(FEAT_GUI)) && !defined(ALWAYS_USE_GUI)
+ /* On Unix use stderr if it's a tty.
+ * When not going to start the GUI also use stderr.
+ * On Mac, when started from Finder, stderr is the console. */
+ if (
+# ifdef UNIX
+ isatty(2)
+# endif
+ ) {
+ fprintf(stderr, "%s", str);
+ return;
+ }
+#endif
+
+ /* avoid a delay for a message that isn't there */
+ emsg_on_display = FALSE;
+
+ len = (int)STRLEN(str) + 1;
+ if (error_ga.ga_growsize == 0) {
+ error_ga.ga_growsize = 80;
+ error_ga.ga_itemsize = 1;
+ }
+ if (ga_grow(&error_ga, len) == OK) {
+ mch_memmove((char_u *)error_ga.ga_data + error_ga.ga_len,
+ (char_u *)str, len);
+#ifdef UNIX
+ /* remove CR characters, they are displayed */
+ {
+ char_u *p;
+
+ p = (char_u *)error_ga.ga_data + error_ga.ga_len;
+ for (;; ) {
+ p = vim_strchr(p, '\r');
+ if (p == NULL)
+ break;
+ *p = ' ';
+ }
+ }
+#endif
+ --len; /* don't count the NUL at the end */
+ error_ga.ga_len += len;
+ }
+}
+
+/*
+ * Give a message. To be used when the screen hasn't been initialized yet.
+ * When there is no tty, collect messages until the GUI has started and they
+ * can be displayed in a message box.
+ */
+void mch_msg(str)
+char *str;
+{
+#if (defined(UNIX) || defined(FEAT_GUI)) && !defined(ALWAYS_USE_GUI)
+ /* On Unix use stdout if we have a tty. This allows "vim -h | more" and
+ * uses mch_errmsg() when started from the desktop.
+ * When not going to start the GUI also use stdout.
+ * On Mac, when started from Finder, stderr is the console. */
+ if (
+# ifdef UNIX
+ isatty(2)
+# endif
+ ) {
+ printf("%s", str);
+ return;
+ }
+# endif
+ mch_errmsg(str);
+}
+#endif /* USE_MCH_ERRMSG */
+
+/*
+ * Put a character on the screen at the current message position and advance
+ * to the next position. Only for printable ASCII!
+ */
+static void msg_screen_putchar(c, attr)
+int c;
+int attr;
+{
+ msg_didout = TRUE; /* remember that line is not empty */
+ screen_putchar(c, msg_row, msg_col, attr);
+ if (cmdmsg_rl) {
+ if (--msg_col == 0) {
+ msg_col = Columns;
+ ++msg_row;
+ }
+ } else {
+ if (++msg_col >= Columns) {
+ msg_col = 0;
+ ++msg_row;
+ }
+ }
+}
+
+void msg_moremsg(full)
+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);
+}
+
+/*
+ * Repeat the message for the current mode: ASKMORE, EXTERNCMD, CONFIRM or
+ * exmode_active.
+ */
+void repeat_message() {
+ if (State == ASKMORE) {
+ msg_moremsg(TRUE); /* display --more-- message again */
+ msg_row = Rows - 1;
+ } else if (State == CONFIRM) {
+ display_confirm_msg(); /* display ":confirm" message again */
+ msg_row = Rows - 1;
+ } else if (State == EXTERNCMD) {
+ windgoto(msg_row, msg_col); /* put cursor back */
+ } else if (State == HITRETURN || State == SETWSIZE) {
+ if (msg_row == Rows - 1) {
+ /* Avoid drawing the "hit-enter" prompt below the previous one,
+ * overwrite it. Esp. useful when regaining focus and a
+ * FocusGained autocmd exists but didn't draw anything. */
+ msg_didout = FALSE;
+ msg_col = 0;
+ msg_clr_eos();
+ }
+ hit_return_msg();
+ msg_row = Rows - 1;
+ }
+}
+
+/*
+ * msg_check_screen - check if the screen is initialized.
+ * Also check msg_row and msg_col, if they are too big it may cause a crash.
+ * While starting the GUI the terminal codes will be set for the GUI, but the
+ * output goes to the terminal. Don't use the terminal codes then.
+ */
+static int msg_check_screen() {
+ if (!full_screen || !screen_valid(FALSE))
+ return FALSE;
+
+ if (msg_row >= Rows)
+ msg_row = Rows - 1;
+ if (msg_col >= Columns)
+ msg_col = Columns - 1;
+ return TRUE;
+}
+
+/*
+ * Clear from current message position to end of screen.
+ * Skip this when ":silent" was used, no need to clear for redirection.
+ */
+void msg_clr_eos() {
+ if (msg_silent == 0)
+ msg_clr_eos_force();
+}
+
+/*
+ * Clear from current message position to end of screen.
+ * Note: msg_col is not updated, so we remember the end of the message
+ * for msg_check().
+ */
+void msg_clr_eos_force() {
+ if (msg_use_printf()) {
+ if (full_screen) { /* only when termcap codes are valid */
+ if (*T_CD)
+ out_str(T_CD); /* clear to end of display */
+ else if (*T_CE)
+ out_str(T_CE); /* clear to end of line */
+ }
+ } else {
+ 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);
+ }
+ }
+}
+
+/*
+ * Clear the command line.
+ */
+void msg_clr_cmdline() {
+ msg_row = cmdline_row;
+ msg_col = 0;
+ msg_clr_eos_force();
+}
+
+/*
+ * end putting a message on the screen
+ * call wait_return if the message does not fit in the available space
+ * return TRUE if wait_return not called.
+ */
+int msg_end() {
+ /*
+ * If the string is larger than the window,
+ * or the ruler option is set and we run into it,
+ * we have to redraw the window.
+ * Do not do this if we are abandoning the file or editing the command line.
+ */
+ if (!exiting && need_wait_return && !(State & CMDLINE)) {
+ wait_return(FALSE);
+ return FALSE;
+ }
+ out_flush();
+ return TRUE;
+}
+
+/*
+ * If the written message runs into the shown command or ruler, we have to
+ * wait for hit-return and redraw the window later.
+ */
+void msg_check() {
+ if (msg_row == Rows - 1 && msg_col >= sc_col) {
+ need_wait_return = TRUE;
+ redraw_cmdline = TRUE;
+ }
+}
+
+/*
+ * 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(str, maxlen)
+char_u *str;
+int maxlen;
+{
+ char_u *s = str;
+ static int cur_col = 0;
+
+ /* Don't do anything for displaying prompts and the like. */
+ if (redir_off)
+ return;
+
+ /* If 'verbosefile' is set prepare for writing in that file. */
+ if (*p_vfile != NUL && verbose_fd == NULL)
+ verbose_open();
+
+ if (redirecting()) {
+ /* 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 (redir_reg)
+ write_reg_contents(redir_reg, (char_u *)" ", -1, TRUE);
+ else if (redir_vname)
+ var_redir_str((char_u *)" ", -1);
+ else if (redir_fd != NULL)
+ fputs(" ", redir_fd);
+ if (verbose_fd != NULL)
+ fputs(" ", verbose_fd);
+ ++cur_col;
+ }
+ }
+
+ if (redir_reg)
+ write_reg_contents(redir_reg, s, maxlen, TRUE);
+ if (redir_vname)
+ var_redir_str(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)
+ putc(*s, redir_fd);
+ if (verbose_fd != NULL)
+ putc(*s, verbose_fd);
+ if (*s == '\r' || *s == '\n')
+ cur_col = 0;
+ else if (*s == '\t')
+ cur_col += (8 - cur_col % 8);
+ else
+ ++cur_col;
+ ++s;
+ }
+
+ if (msg_silent != 0) /* should update msg_col */
+ msg_col = cur_col;
+ }
+}
+
+int redirecting() {
+ return redir_fd != NULL || *p_vfile != NUL
+ || redir_reg || redir_vname
+ ;
+}
+
+/*
+ * Before giving verbose message.
+ * Must always be called paired with verbose_leave()!
+ */
+void verbose_enter() {
+ if (*p_vfile != NUL)
+ ++msg_silent;
+}
+
+/*
+ * After giving verbose message.
+ * Must always be called paired with verbose_enter()!
+ */
+void verbose_leave() {
+ if (*p_vfile != NUL)
+ if (--msg_silent < 0)
+ msg_silent = 0;
+}
+
+/*
+ * Like verbose_enter() and set msg_scroll when displaying the message.
+ */
+void verbose_enter_scroll() {
+ if (*p_vfile != NUL)
+ ++msg_silent;
+ else
+ /* always scroll up, don't overwrite */
+ msg_scroll = TRUE;
+}
+
+/*
+ * Like verbose_leave() and set cmdline_row when displaying the message.
+ */
+void verbose_leave_scroll() {
+ if (*p_vfile != NUL) {
+ if (--msg_silent < 0)
+ msg_silent = 0;
+ } else
+ cmdline_row = msg_row;
+}
+
+/*
+ * Called when 'verbosefile' is set: stop writing to the file.
+ */
+void verbose_stop() {
+ if (verbose_fd != NULL) {
+ fclose(verbose_fd);
+ verbose_fd = NULL;
+ }
+ verbose_did_open = FALSE;
+}
+
+/*
+ * Open the file 'verbosefile'.
+ * Return FAIL or OK.
+ */
+int verbose_open() {
+ if (verbose_fd == NULL && !verbose_did_open) {
+ /* Only give the error message once. */
+ verbose_did_open = TRUE;
+
+ verbose_fd = mch_fopen((char *)p_vfile, "a");
+ if (verbose_fd == NULL) {
+ EMSG2(_(e_notopen), p_vfile);
+ return FAIL;
+ }
+ }
+ return OK;
+}
+
+/*
+ * Give a warning message (for searching).
+ * Use 'w' highlighting and may repeat the message after redrawing
+ */
+void give_warning(message, hl)
+char_u *message;
+int hl;
+{
+ /* Don't do this for ":silent". */
+ if (msg_silent != 0)
+ return;
+
+ /* Don't want a hit-enter prompt here. */
+ ++no_wait_return;
+
+ set_vim_var_string(VV_WARNINGMSG, message, -1);
+ vim_free(keep_msg);
+ keep_msg = NULL;
+ if (hl)
+ keep_msg_attr = hl_attr(HLF_W);
+ else
+ keep_msg_attr = 0;
+ if (msg_attr(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_col = 0;
+
+ --no_wait_return;
+}
+
+/*
+ * Advance msg cursor to column "col".
+ */
+void msg_advance(col)
+int col;
+{
+ if (msg_silent != 0) { /* nothing to advance to */
+ msg_col = col; /* for redirection, may fill it up later */
+ return;
+ }
+ if (col >= Columns) /* not enough room */
+ col = Columns - 1;
+ if (cmdmsg_rl)
+ while (msg_col > Columns - col)
+ msg_putchar(' ');
+ else
+ while (msg_col < col)
+ msg_putchar(' ');
+}
+
+/*
+ * Used for "confirm()" function, and the :confirm command prefix.
+ * Versions which haven't got flexible dialogs yet, and console
+ * versions, get this generic handler which uses the command line.
+ *
+ * type = one of:
+ * VIM_QUESTION, VIM_INFO, VIM_WARNING, VIM_ERROR or VIM_GENERIC
+ * title = title string (can be NULL for default)
+ * (neither used in console dialogs at the moment)
+ *
+ * Format of the "buttons" string:
+ * "Button1Name\nButton2Name\nButton3Name"
+ * The first button should normally be the default/accept
+ * The second button should be the 'Cancel' button
+ * Other buttons- use your imagination!
+ * A '&' in a button name becomes a shortcut, so each '&' should be before a
+ * different letter.
+ */
+int do_dialog(type, title, message, buttons, dfltbutton, textfield, ex_cmd)
+int type UNUSED;
+char_u *title UNUSED;
+char_u *message;
+char_u *buttons;
+int dfltbutton;
+char_u *textfield UNUSED; /* IObuff for inputdialog(), NULL
+ otherwise */
+int ex_cmd; /* when TRUE pressing : accepts default and starts
+ Ex command */
+{
+ int oldState;
+ int retval = 0;
+ char_u *hotkeys;
+ int c;
+ int i;
+
+#ifndef NO_CONSOLE
+ /* Don't output anything in silent mode ("ex -s") */
+ if (silent_mode)
+ return dfltbutton; /* return default option */
+#endif
+
+
+ oldState = State;
+ State = CONFIRM;
+ setmouse();
+
+ /*
+ * Since we wait for a keypress, don't make the
+ * user press RETURN as well afterwards.
+ */
+ ++no_wait_return;
+ hotkeys = msg_show_console_dialog(message, buttons, dfltbutton);
+
+ if (hotkeys != NULL) {
+ for (;; ) {
+ /* Get a typed character directly from the user. */
+ c = get_keystroke();
+ switch (c) {
+ case CAR: /* User accepts default option */
+ case NL:
+ retval = dfltbutton;
+ break;
+ case Ctrl_C: /* User aborts/cancels */
+ case ESC:
+ retval = 0;
+ break;
+ default: /* Could be a hotkey? */
+ if (c < 0) /* special keys are ignored here */
+ continue;
+ if (c == ':' && ex_cmd) {
+ retval = dfltbutton;
+ ins_char_typebuf(':');
+ break;
+ }
+
+ /* 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)
+ break;
+ ++retval;
+ }
+ if (hotkeys[i])
+ break;
+ /* No hotkey match, so keep waiting */
+ continue;
+ }
+ break;
+ }
+
+ vim_free(hotkeys);
+ }
+
+ State = oldState;
+ setmouse();
+ --no_wait_return;
+ msg_end_prompt();
+
+ return retval;
+}
+
+static int copy_char __ARGS((char_u *from, char_u *to, int lowercase));
+
+/*
+ * Copy one character from "*from" to "*to", taking care of multi-byte
+ * characters. Return the length of the character in bytes.
+ */
+static int copy_char(from, to, lowercase)
+char_u *from;
+char_u *to;
+int lowercase; /* make character lower case */
+{
+ int len;
+ int c;
+
+ if (has_mbyte) {
+ if (lowercase) {
+ c = MB_TOLOWER((*mb_ptr2char)(from));
+ return (*mb_char2bytes)(c, to);
+ } else {
+ len = (*mb_ptr2len)(from);
+ mch_memmove(to, from, (size_t)len);
+ return len;
+ }
+ } else {
+ if (lowercase)
+ *to = (char_u)TOLOWER_LOC(*from);
+ else
+ *to = *from;
+ return 1;
+ }
+}
+
+/*
+ * Format the dialog string, and display it at the bottom of
+ * the screen. Return a string of hotkey chars (if defined) for
+ * each 'button'. If a button has no hotkey defined, the first character of
+ * the button is used.
+ * The hotkeys can be multi-byte characters, but without combining chars.
+ *
+ * Returns an allocated string with hotkeys, or NULL for error.
+ */
+static char_u * msg_show_console_dialog(message, buttons, dfltbutton)
+char_u *message;
+char_u *buttons;
+int dfltbutton;
+{
+ int len = 0;
+# define HOTK_LEN (has_mbyte ? MB_MAXBYTES : 1)
+ int lenhotkey = HOTK_LEN; /* count first button */
+ char_u *hotk = NULL;
+ char_u *msgp = NULL;
+ char_u *hotkp = NULL;
+ char_u *r;
+ int copy;
+#define HAS_HOTKEY_LEN 30
+ char_u has_hotkey[HAS_HOTKEY_LEN];
+ int first_hotkey = FALSE; /* first char of button is hotkey */
+ int idx;
+
+ has_hotkey[0] = FALSE;
+
+ /*
+ * First loop: compute the size of memory to allocate.
+ * Second loop: copy to the allocated memory.
+ */
+ for (copy = 0; copy <= 1; ++copy) {
+ r = buttons;
+ idx = 0;
+ while (*r) {
+ if (*r == DLG_BUTTON_SEP) {
+ if (copy) {
+ *msgp++ = ',';
+ *msgp++ = ' '; /* '\n' -> ', ' */
+
+ /* advance to next hotkey and set default hotkey */
+ if (has_mbyte)
+ hotkp += STRLEN(hotkp);
+ else
+ ++hotkp;
+ hotkp[copy_char(r + 1, hotkp, TRUE)] = NUL;
+ if (dfltbutton)
+ --dfltbutton;
+
+ /* If no hotkey is specified first char is used. */
+ if (idx < HAS_HOTKEY_LEN - 1 && !has_hotkey[++idx])
+ first_hotkey = TRUE;
+ } else {
+ len += 3; /* '\n' -> ', '; 'x' -> '(x)' */
+ lenhotkey += HOTK_LEN; /* each button needs a hotkey */
+ if (idx < HAS_HOTKEY_LEN - 1)
+ has_hotkey[++idx] = FALSE;
+ }
+ } else if (*r == DLG_HOTKEY_CHAR || first_hotkey) {
+ if (*r == DLG_HOTKEY_CHAR)
+ ++r;
+ first_hotkey = FALSE;
+ if (copy) {
+ if (*r == DLG_HOTKEY_CHAR) /* '&&a' -> '&a' */
+ *msgp++ = *r;
+ else {
+ /* '&a' -> '[a]' */
+ *msgp++ = (dfltbutton == 1) ? '[' : '(';
+ msgp += copy_char(r, msgp, FALSE);
+ *msgp++ = (dfltbutton == 1) ? ']' : ')';
+
+ /* redefine hotkey */
+ hotkp[copy_char(r, hotkp, TRUE)] = NUL;
+ }
+ } else {
+ ++len; /* '&a' -> '[a]' */
+ if (idx < HAS_HOTKEY_LEN - 1)
+ has_hotkey[idx] = TRUE;
+ }
+ } else {
+ /* everything else copy literally */
+ if (copy)
+ msgp += copy_char(r, msgp, FALSE);
+ }
+
+ /* advance to the next character */
+ mb_ptr_adv(r);
+ }
+
+ if (copy) {
+ *msgp++ = ':';
+ *msgp++ = ' ';
+ *msgp = NUL;
+ } else {
+ len += (int)(STRLEN(message)
+ + 2 /* for the NL's */
+ + STRLEN(buttons)
+ + 3); /* for the ": " and NUL */
+ lenhotkey++; /* for the NUL */
+
+ /* If no hotkey is specified first char is used. */
+ if (!has_hotkey[0]) {
+ first_hotkey = TRUE;
+ len += 2; /* "x" -> "[x]" */
+ }
+
+ /*
+ * Now allocate and load the strings
+ */
+ vim_free(confirm_msg);
+ confirm_msg = alloc(len);
+ if (confirm_msg == NULL)
+ return NULL;
+ *confirm_msg = NUL;
+ hotk = alloc(lenhotkey);
+ if (hotk == NULL)
+ return NULL;
+
+ *confirm_msg = '\n';
+ STRCPY(confirm_msg + 1, message);
+
+ msgp = confirm_msg + 1 + STRLEN(message);
+ hotkp = hotk;
+
+ /* Define first default hotkey. Keep the hotkey string NUL
+ * terminated to avoid reading past the end. */
+ hotkp[copy_char(buttons, hotkp, TRUE)] = NUL;
+
+ /* Remember where the choices start, displaying starts here when
+ * "hotkp" typed at the more prompt. */
+ confirm_msg_tail = msgp;
+ *msgp++ = '\n';
+ }
+ }
+
+ display_confirm_msg();
+ return hotk;
+}
+
+/*
+ * Display the ":confirm" message. Also called when screen resized.
+ */
+void display_confirm_msg() {
+ /* 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;
+}
+
+int vim_dialog_yesno(type, title, message, dflt)
+int type;
+char_u *title;
+char_u *message;
+int dflt;
+{
+ if (do_dialog(type,
+ title == NULL ? (char_u *)_("Question") : title,
+ message,
+ (char_u *)_("&Yes\n&No"), dflt, NULL, FALSE) == 1)
+ return VIM_YES;
+ return VIM_NO;
+}
+
+int vim_dialog_yesnocancel(type, title, message, dflt)
+int type;
+char_u *title;
+char_u *message;
+int dflt;
+{
+ switch (do_dialog(type,
+ title == NULL ? (char_u *)_("Question") : title,
+ message,
+ (char_u *)_("&Yes\n&No\n&Cancel"), dflt, NULL, FALSE)) {
+ case 1: return VIM_YES;
+ case 2: return VIM_NO;
+ }
+ return VIM_CANCEL;
+}
+
+int vim_dialog_yesnoallcancel(type, title, message, dflt)
+int type;
+char_u *title;
+char_u *message;
+int dflt;
+{
+ switch (do_dialog(type,
+ title == NULL ? (char_u *)"Question" : title,
+ message,
+ (char_u *)_("&Yes\n&No\nSave &All\n&Discard All\n&Cancel"),
+ dflt, NULL, FALSE)) {
+ case 1: return VIM_YES;
+ case 2: return VIM_NO;
+ case 3: return VIM_ALL;
+ case 4: return VIM_DISCARDALL;
+ }
+ return VIM_CANCEL;
+}
+
+
+
+#if defined(HAVE_STDARG_H) && defined(FEAT_EVAL)
+static char *e_printf = N_("E766: Insufficient arguments for printf()");
+
+static long tv_nr __ARGS((typval_T *tvs, int *idxp));
+static char *tv_str __ARGS((typval_T *tvs, int *idxp));
+static double tv_float __ARGS((typval_T *tvs, int *idxp));
+
+/*
+ * Get number argument from "idxp" entry in "tvs". First entry is 1.
+ */
+static long tv_nr(tvs, idxp)
+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(tvs, idxp)
+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(tvs, idxp)
+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;
+}
+#endif
+
+/*
+ * 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, 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 null. 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 null-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.
+ */
+
+/* When generating prototypes all of this is skipped, cproto doesn't
+ * understand this. */
+
+# ifdef HAVE_STDARG_H
+/* 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;
+}
+
+# else
+/* Like vim_vsnprintf() but append to the string. */
+int vim_snprintf_add(str, str_m, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10)
+char *str;
+size_t str_m;
+char *fmt;
+long a1, a2, a3, a4, a5, a6, a7, a8, a9, a10;
+{
+ size_t len = STRLEN(str);
+ size_t space;
+
+ if (str_m <= len)
+ space = 0;
+ else
+ space = str_m - len;
+ return vim_vsnprintf(str + len, space, fmt,
+ a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
+}
+# endif
+
+# ifdef HAVE_STDARG_H
+int vim_snprintf(char *str, size_t str_m, 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(str, str_m, fmt, ap, tvs)
+# else
+/* clumsy way to work around missing va_list */
+# define get_a_arg(i) (++i, i == 2 ? a1 : i == 3 ? a2 : i == 4 ? a3 : i == \
+ 5 ? a4 : i == 6 ? a5 : i == 7 ? a6 : i == 8 ? a7 : i == \
+ 9 ? a8 : i == \
+ 10 ? a9 : a10)
+
+/* VARARGS */
+int vim_snprintf(str, str_m, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10)
+# endif
+char *str;
+size_t str_m;
+char *fmt;
+# ifdef HAVE_STDARG_H
+va_list ap;
+typval_T *tvs;
+# else
+long a1, a2, a3, a4, a5, a6, a7, a8, a9, a10;
+# endif
+{
+ size_t str_l = 0;
+ char *p = fmt;
+ int arg_idx = 1;
+
+ if (p == NULL)
+ p = "";
+ while (*p != NUL) {
+ if (*p != '%') {
+ char *q = strchr(p + 1, '%');
+ size_t n = (q == NULL) ? STRLEN(p) : (size_t)(q - p);
+
+ /* Copy up to the next '%' or NUL without any changes. */
+ if (str_l < str_m) {
+ size_t avail = str_m - str_l;
+
+ mch_memmove(str + str_l, p, n > avail ? avail : n);
+ }
+ p += n;
+ 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 the ' ' and '+' flags appear, the ' ' flag should be
+ * ignored. */
+ int space_for_positive = 1;
+
+ /* allowed values: \0, h, l, L */
+ char length_modifier = '\0';
+
+ /* temporary buffer for simple numeric->string conversion */
+# define TMP_LEN 350 /* On my system 1e308 is the biggest number possible.
+ * That sounds reasonable to use as the maximum
+ * printable. */
+ char tmp[TMP_LEN];
+
+ /* string address in case of string argument */
+ 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.
+ * N.B. 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;
+ case '+': force_sign = 1; space_for_positive = 0; break;
+ case ' ': force_sign = 1;
+ /* If both the ' ' and '+' flags appear, the ' '
+ * flag should be ignored */
+ break;
+ case '#': alternate_form = 1; break;
+ case '\'': break;
+ }
+ p++;
+ }
+ /* If the '0' and '-' flags both appear, the '0' flag should be
+ * ignored. */
+
+ /* parse field width */
+ if (*p == '*') {
+ int j;
+
+ p++;
+ j =
+#ifndef HAVE_STDARG_H
+ get_a_arg(arg_idx);
+#else
+ tvs != NULL ? tv_nr(tvs, &arg_idx) :
+ va_arg(ap, int);
+#endif
+ if (j >= 0)
+ min_field_width = j;
+ else {
+ min_field_width = -j;
+ justify_left = 1;
+ }
+ } else if (VIM_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 (VIM_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;
+
+ j =
+#ifndef HAVE_STDARG_H
+ get_a_arg(arg_idx);
+#else
+ tvs != NULL ? tv_nr(tvs, &arg_idx) :
+ va_arg(ap, int);
+#endif
+ p++;
+ if (j >= 0)
+ precision = j;
+ else {
+ precision_specified = 0;
+ precision = 0;
+ }
+ } else if (VIM_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 (VIM_ISDIGIT((int)(*p)))
+ uj = 10 * uj + (unsigned int)(*p++ - '0');
+ precision = uj;
+ }
+ }
+
+ /* parse 'h', 'l' and 'll' length modifiers */
+ if (*p == 'h' || *p == 'l') {
+ length_modifier = *p;
+ p++;
+ if (length_modifier == 'l' && *p == 'l') {
+ /* double l = long long */
+ length_modifier = 'l'; /* treat it as a single 'l' */
+ 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':
+ length_modifier = '\0';
+ str_arg_l = 1;
+ switch (fmt_spec) {
+ case '%':
+ str_arg = p;
+ break;
+
+ case 'c':
+ {
+ int j;
+
+ j =
+#ifndef HAVE_STDARG_H
+ get_a_arg(arg_idx);
+#else
+ tvs != NULL ? tv_nr(tvs, &arg_idx) :
+ va_arg(ap, int);
+#endif
+ /* standard demands unsigned char */
+ uchar_arg = (unsigned char)j;
+ str_arg = (char *)&uchar_arg;
+ break;
+ }
+
+ case 's':
+ case 'S':
+ str_arg =
+#ifndef HAVE_STDARG_H
+ (char *)get_a_arg(arg_idx);
+#else
+ tvs != NULL ? tv_str(tvs, &arg_idx) :
+ va_arg(ap, char *);
+#endif
+ if (str_arg == NULL) {
+ str_arg = "[NULL]";
+ str_arg_l = 6;
+ }
+ /* make sure not to address string beyond the specified
+ * precision !!! */
+ else if (!precision_specified)
+ str_arg_l = strlen(str_arg);
+ /* truncate string if necessary as requested by precision */
+ else if (precision == 0)
+ str_arg_l = 0;
+ else {
+ /* Don't put the #if inside memchr(), it can be a
+ * macro. */
+#if SIZEOF_INT <= 2
+ char *q = memchr(str_arg, '\0', precision);
+#else
+ /* memchr on HP does not like n > 2^31 !!! */
+ char *q = memchr(str_arg, '\0',
+ precision <= (size_t)0x7fffffffL ? precision
+ : (size_t)0x7fffffffL);
+#endif
+ str_arg_l = (q == NULL) ? precision
+ : (size_t)(q - str_arg);
+ }
+ if (fmt_spec == 'S') {
+ if (min_field_width != 0)
+ min_field_width += STRLEN(str_arg)
+ - mb_string2cells((char_u *)str_arg, -1);
+ if (precision) {
+ char_u *p1 = (char_u *)str_arg;
+ size_t i;
+
+ for (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 'o': case 'x': case 'X': case 'p':
+ {
+ /* NOTE: the u, 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 nonzero
+ * for unsigned arguments), -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;
+
+ /* pointer argument value -only defined for p
+ * conversion */
+ void *ptr_arg = NULL;
+
+ if (fmt_spec == 'p') {
+ length_modifier = '\0';
+ ptr_arg =
+#ifndef HAVE_STDARG_H
+ (void *)get_a_arg(arg_idx);
+#else
+ tvs != NULL ? (void *)tv_str(tvs, &arg_idx) :
+ va_arg(ap, void *);
+#endif
+ if (ptr_arg != NULL)
+ 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 =
+#ifndef HAVE_STDARG_H
+ get_a_arg(arg_idx);
+#else
+ tvs != NULL ? tv_nr(tvs, &arg_idx) :
+ va_arg(ap, int);
+#endif
+ if (int_arg > 0)
+ arg_sign = 1;
+ else if (int_arg < 0)
+ arg_sign = -1;
+ break;
+ case 'l':
+ long_arg =
+#ifndef HAVE_STDARG_H
+ get_a_arg(arg_idx);
+#else
+ tvs != NULL ? tv_nr(tvs, &arg_idx) :
+ va_arg(ap, long int);
+#endif
+ if (long_arg > 0)
+ arg_sign = 1;
+ else if (long_arg < 0)
+ arg_sign = -1;
+ break;
+ }
+ } else {
+ /* unsigned */
+ switch (length_modifier) {
+ case '\0':
+ case 'h':
+ uint_arg =
+#ifndef HAVE_STDARG_H
+ get_a_arg(arg_idx);
+#else
+ tvs != NULL ? (unsigned)
+ tv_nr(tvs, &arg_idx) :
+ va_arg(ap, unsigned int);
+#endif
+ if (uint_arg != 0)
+ arg_sign = 1;
+ break;
+ case 'l':
+ ulong_arg =
+#ifndef HAVE_STDARG_H
+ get_a_arg(arg_idx);
+#else
+ tvs != NULL ? (unsigned long)
+ tv_nr(tvs, &arg_idx) :
+ va_arg(ap, unsigned long int);
+#endif
+ if (ulong_arg != 0)
+ arg_sign = 1;
+ break;
+ }
+ }
+
+ str_arg = tmp;
+ str_arg_l = 0;
+
+ /* NOTE:
+ * For d, i, u, o, x, and X conversions, if precision is
+ * specified, the '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') ) {
+ 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, the resulting formatted string is
+ * empty (d, i, u, 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;
+ }
+ } 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;
+ }
+ }
+
+ /* 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'))
+ 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;
+ precision_specified = 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. */
+ double f;
+ double abs_f;
+ char format[40];
+ int l;
+ int remove_trailing_zeroes = FALSE;
+
+ f =
+# ifndef HAVE_STDARG_H
+ get_a_arg(arg_idx);
+# else
+ tvs != NULL ? tv_float(tvs, &arg_idx) :
+ va_arg(ap, double);
+# endif
+ abs_f = f < 0 ? -f : f;
+
+ if (fmt_spec == 'g' || fmt_spec == 'G') {
+ /* Would be nice to use %g directly, but it prints
+ * "1.0" as "1", we don't want that. */
+ 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' &&
+#ifdef VAX
+ abs_f > 1.0e38
+#else
+ abs_f > 1.0e307
+#endif
+ ) {
+ /* 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 != NULL) {
+ /* Remove superfluous '+' and leading
+ * zeroes from the 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 {
+ char *tp;
+
+ /* Be consistent: some printf("%e") use 1.0e+12
+ * and some 1.0e+012. Remove one zero in the last
+ * case. */
+ tp = (char *)vim_strchr((char_u *)tmp,
+ fmt_spec == 'e' ? 'e' : 'E');
+ if (tp != NULL && (tp[1] == '+' || tp[1] == '-')
+ && tp[2] == '0'
+ && vim_isdigit(tp[3])
+ && vim_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 != NUL)
+ str_arg_l++; /* include invalid conversion specifier
+ unchanged if not at end-of-string */
+ break;
+ }
+
+ if (*p != NUL)
+ 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) {
+ /* left padding with blank or zero */
+ int pn = (int)(min_field_width - (str_arg_l + number_of_zeros_to_pad));
+
+ if (pn > 0) {
+ if (str_l < str_m) {
+ size_t avail = str_m - str_l;
+
+ vim_memset(str + str_l, zero_padding ? '0' : ' ',
+ (size_t)pn > avail ? avail
+ : (size_t)pn);
+ }
+ 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 */
+ int zn = (int)zero_padding_insertion_ind;
+
+ if (zn > 0) {
+ if (str_l < str_m) {
+ size_t avail = str_m - str_l;
+
+ mch_memmove(str + str_l, str_arg,
+ (size_t)zn > avail ? avail
+ : (size_t)zn);
+ }
+ str_l += zn;
+ }
+
+ /* insert zero padding as requested by the precision or min
+ * field width */
+ zn = (int)number_of_zeros_to_pad;
+ if (zn > 0) {
+ if (str_l < str_m) {
+ size_t avail = str_m-str_l;
+
+ vim_memset(str + str_l, '0',
+ (size_t)zn > avail ? avail
+ : (size_t)zn);
+ }
+ str_l += zn;
+ }
+ }
+
+ /* insert formatted string
+ * (or as-is conversion specifier for unknown conversions) */
+ {
+ int sn = (int)(str_arg_l - zero_padding_insertion_ind);
+
+ if (sn > 0) {
+ if (str_l < str_m) {
+ size_t avail = str_m - str_l;
+
+ mch_memmove(str + str_l,
+ str_arg + zero_padding_insertion_ind,
+ (size_t)sn > avail ? avail : (size_t)sn);
+ }
+ str_l += sn;
+ }
+ }
+
+ /* insert right padding */
+ if (justify_left) {
+ /* right blank padding to the field width */
+ int pn = (int)(min_field_width
+ - (str_arg_l + number_of_zeros_to_pad));
+
+ if (pn > 0) {
+ if (str_l < str_m) {
+ size_t avail = str_m - str_l;
+
+ vim_memset(str + str_l, ' ',
+ (size_t)pn > avail ? avail
+ : (size_t)pn);
+ }
+ 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';
+ }
+
+#ifdef HAVE_STDARG_H
+ if (tvs != NULL && tvs[arg_idx - 1].v_type != VAR_UNKNOWN)
+ EMSG(_("E767: Too many arguments to printf()"));
+#endif
+
+ /* 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/misc1.c b/src/misc1.c
new file mode 100644
index 0000000000..92fc47189b
--- /dev/null
+++ b/src/misc1.c
@@ -0,0 +1,9097 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * 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.
+ */
+
+/*
+ * misc1.c: functions that didn't seem to fit elsewhere
+ */
+
+#include "vim.h"
+#include "version.h"
+
+static char_u *vim_version_dir __ARGS((char_u *vimdir));
+static char_u *remove_tail __ARGS((char_u *p, char_u *pend, char_u *name));
+static void init_users __ARGS((void));
+static int copy_indent __ARGS((int size, char_u *src));
+
+/* All user names (for ~user completion as done by shell). */
+static garray_T ga_users;
+
+/*
+ * Count the size (in window cells) of the indent in the current line.
+ */
+int get_indent() {
+ return get_indent_str(ml_get_curline(), (int)curbuf->b_p_ts);
+}
+
+/*
+ * Count the size (in window cells) of the indent in line "lnum".
+ */
+int get_indent_lnum(lnum)
+linenr_T lnum;
+{
+ return get_indent_str(ml_get(lnum), (int)curbuf->b_p_ts);
+}
+
+/*
+ * Count the size (in window cells) of the indent in line "lnum" of buffer
+ * "buf".
+ */
+int get_indent_buf(buf, lnum)
+buf_T *buf;
+linenr_T lnum;
+{
+ return get_indent_str(ml_get_buf(buf, lnum, FALSE), (int)buf->b_p_ts);
+}
+
+/*
+ * count the size (in window cells) of the indent in line "ptr", with
+ * 'tabstop' at "ts"
+ */
+int get_indent_str(ptr, ts)
+char_u *ptr;
+int ts;
+{
+ int count = 0;
+
+ for (; *ptr; ++ptr) {
+ if (*ptr == TAB) /* count a tab for what it is worth */
+ count += ts - (count % ts);
+ else if (*ptr == ' ')
+ ++count; /* count a space for one */
+ else
+ break;
+ }
+ return count;
+}
+
+/*
+ * Set the indent of the current line.
+ * Leaves the cursor on the first non-blank in the line.
+ * Caller must take care of undo.
+ * "flags":
+ * SIN_CHANGED: call changed_bytes() if the line was changed.
+ * SIN_INSERT: insert the indent in front of the line.
+ * SIN_UNDO: save line for undo before changing it.
+ * Returns TRUE if the line was changed.
+ */
+int set_indent(size, flags)
+int size; /* measured in spaces */
+int flags;
+{
+ char_u *p;
+ char_u *newline;
+ char_u *oldline;
+ char_u *s;
+ int todo;
+ int ind_len; /* measured in characters */
+ int line_len;
+ int doit = FALSE;
+ int ind_done = 0; /* measured in spaces */
+ int tab_pad;
+ int retval = FALSE;
+ int orig_char_len = -1; /* number of initial whitespace chars when
+ 'et' and 'pi' are both set */
+
+ /*
+ * First check if there is anything to do and compute the number of
+ * characters needed for the indent.
+ */
+ todo = size;
+ ind_len = 0;
+ p = oldline = ml_get_curline();
+
+ /* Calculate the buffer size for the new indent, and check to see if it
+ * isn't already set */
+
+ /* if 'expandtab' isn't set: use TABs; if both 'expandtab' and
+ * 'preserveindent' are set count the number of characters at the
+ * beginning of the line to be copied */
+ if (!curbuf->b_p_et || (!(flags & SIN_INSERT) && curbuf->b_p_pi)) {
+ /* If 'preserveindent' is set then reuse as much as possible of
+ * the existing indent structure for the new indent */
+ if (!(flags & SIN_INSERT) && curbuf->b_p_pi) {
+ ind_done = 0;
+
+ /* count as many characters as we can use */
+ while (todo > 0 && vim_iswhite(*p)) {
+ if (*p == TAB) {
+ tab_pad = (int)curbuf->b_p_ts
+ - (ind_done % (int)curbuf->b_p_ts);
+ /* stop if this tab will overshoot the target */
+ if (todo < tab_pad)
+ break;
+ todo -= tab_pad;
+ ++ind_len;
+ ind_done += tab_pad;
+ } else {
+ --todo;
+ ++ind_len;
+ ++ind_done;
+ }
+ ++p;
+ }
+
+ /* Set initial number of whitespace chars to copy if we are
+ * preserving indent but expandtab is set */
+ if (curbuf->b_p_et)
+ orig_char_len = ind_len;
+
+ /* Fill to next tabstop with a tab, if possible */
+ tab_pad = (int)curbuf->b_p_ts - (ind_done % (int)curbuf->b_p_ts);
+ if (todo >= tab_pad && orig_char_len == -1) {
+ doit = TRUE;
+ todo -= tab_pad;
+ ++ind_len;
+ /* ind_done += tab_pad; */
+ }
+ }
+
+ /* count tabs required for indent */
+ while (todo >= (int)curbuf->b_p_ts) {
+ if (*p != TAB)
+ doit = TRUE;
+ else
+ ++p;
+ todo -= (int)curbuf->b_p_ts;
+ ++ind_len;
+ /* ind_done += (int)curbuf->b_p_ts; */
+ }
+ }
+ /* count spaces required for indent */
+ while (todo > 0) {
+ if (*p != ' ')
+ doit = TRUE;
+ else
+ ++p;
+ --todo;
+ ++ind_len;
+ /* ++ind_done; */
+ }
+
+ /* Return if the indent is OK already. */
+ if (!doit && !vim_iswhite(*p) && !(flags & SIN_INSERT))
+ return FALSE;
+
+ /* Allocate memory for the new line. */
+ if (flags & SIN_INSERT)
+ p = oldline;
+ else
+ p = skipwhite(p);
+ line_len = (int)STRLEN(p) + 1;
+
+ /* If 'preserveindent' and 'expandtab' are both set keep the original
+ * characters and allocate accordingly. We will fill the rest with spaces
+ * after the if (!curbuf->b_p_et) below. */
+ if (orig_char_len != -1) {
+ newline = alloc(orig_char_len + size - ind_done + line_len);
+ if (newline == NULL)
+ return FALSE;
+ todo = size - ind_done;
+ ind_len = orig_char_len + todo; /* Set total length of indent in
+ * characters, which may have been
+ * undercounted until now */
+ p = oldline;
+ s = newline;
+ while (orig_char_len > 0) {
+ *s++ = *p++;
+ orig_char_len--;
+ }
+
+ /* Skip over any additional white space (useful when newindent is less
+ * than old) */
+ while (vim_iswhite(*p))
+ ++p;
+
+ } else {
+ todo = size;
+ newline = alloc(ind_len + line_len);
+ if (newline == NULL)
+ return FALSE;
+ s = newline;
+ }
+
+ /* Put the characters in the new line. */
+ /* if 'expandtab' isn't set: use TABs */
+ if (!curbuf->b_p_et) {
+ /* If 'preserveindent' is set then reuse as much as possible of
+ * the existing indent structure for the new indent */
+ if (!(flags & SIN_INSERT) && curbuf->b_p_pi) {
+ p = oldline;
+ ind_done = 0;
+
+ while (todo > 0 && vim_iswhite(*p)) {
+ if (*p == TAB) {
+ tab_pad = (int)curbuf->b_p_ts
+ - (ind_done % (int)curbuf->b_p_ts);
+ /* stop if this tab will overshoot the target */
+ if (todo < tab_pad)
+ break;
+ todo -= tab_pad;
+ ind_done += tab_pad;
+ } else {
+ --todo;
+ ++ind_done;
+ }
+ *s++ = *p++;
+ }
+
+ /* Fill to next tabstop with a tab, if possible */
+ tab_pad = (int)curbuf->b_p_ts - (ind_done % (int)curbuf->b_p_ts);
+ if (todo >= tab_pad) {
+ *s++ = TAB;
+ todo -= tab_pad;
+ }
+
+ p = skipwhite(p);
+ }
+
+ while (todo >= (int)curbuf->b_p_ts) {
+ *s++ = TAB;
+ todo -= (int)curbuf->b_p_ts;
+ }
+ }
+ while (todo > 0) {
+ *s++ = ' ';
+ --todo;
+ }
+ mch_memmove(s, p, (size_t)line_len);
+
+ /* Replace the line (unless undo fails). */
+ if (!(flags & SIN_UNDO) || u_savesub(curwin->w_cursor.lnum) == OK) {
+ ml_replace(curwin->w_cursor.lnum, newline, FALSE);
+ if (flags & SIN_CHANGED)
+ changed_bytes(curwin->w_cursor.lnum, 0);
+ /* Correct saved cursor position if it is in this line. */
+ if (saved_cursor.lnum == curwin->w_cursor.lnum) {
+ if (saved_cursor.col >= (colnr_T)(p - oldline))
+ /* cursor was after the indent, adjust for the number of
+ * bytes added/removed */
+ saved_cursor.col += ind_len - (colnr_T)(p - oldline);
+ else if (saved_cursor.col >= (colnr_T)(s - newline))
+ /* cursor was in the indent, and is now after it, put it back
+ * at the start of the indent (replacing spaces with TAB) */
+ saved_cursor.col = (colnr_T)(s - newline);
+ }
+ retval = TRUE;
+ } else
+ vim_free(newline);
+
+ curwin->w_cursor.col = ind_len;
+ return retval;
+}
+
+/*
+ * Copy the indent from ptr to the current line (and fill to size)
+ * Leaves the cursor on the first non-blank in the line.
+ * Returns TRUE if the line was changed.
+ */
+static int copy_indent(size, src)
+int size;
+char_u *src;
+{
+ char_u *p = NULL;
+ char_u *line = NULL;
+ char_u *s;
+ int todo;
+ int ind_len;
+ int line_len = 0;
+ int tab_pad;
+ int ind_done;
+ int round;
+
+ /* Round 1: compute the number of characters needed for the indent
+ * Round 2: copy the characters. */
+ for (round = 1; round <= 2; ++round) {
+ todo = size;
+ ind_len = 0;
+ ind_done = 0;
+ s = src;
+
+ /* Count/copy the usable portion of the source line */
+ while (todo > 0 && vim_iswhite(*s)) {
+ if (*s == TAB) {
+ tab_pad = (int)curbuf->b_p_ts
+ - (ind_done % (int)curbuf->b_p_ts);
+ /* Stop if this tab will overshoot the target */
+ if (todo < tab_pad)
+ break;
+ todo -= tab_pad;
+ ind_done += tab_pad;
+ } else {
+ --todo;
+ ++ind_done;
+ }
+ ++ind_len;
+ if (p != NULL)
+ *p++ = *s;
+ ++s;
+ }
+
+ /* Fill to next tabstop with a tab, if possible */
+ tab_pad = (int)curbuf->b_p_ts - (ind_done % (int)curbuf->b_p_ts);
+ if (todo >= tab_pad && !curbuf->b_p_et) {
+ todo -= tab_pad;
+ ++ind_len;
+ if (p != NULL)
+ *p++ = TAB;
+ }
+
+ /* Add tabs required for indent */
+ while (todo >= (int)curbuf->b_p_ts && !curbuf->b_p_et) {
+ todo -= (int)curbuf->b_p_ts;
+ ++ind_len;
+ if (p != NULL)
+ *p++ = TAB;
+ }
+
+ /* Count/add spaces required for indent */
+ while (todo > 0) {
+ --todo;
+ ++ind_len;
+ if (p != NULL)
+ *p++ = ' ';
+ }
+
+ if (p == NULL) {
+ /* Allocate memory for the result: the copied indent, new indent
+ * and the rest of the line. */
+ line_len = (int)STRLEN(ml_get_curline()) + 1;
+ line = alloc(ind_len + line_len);
+ if (line == NULL)
+ return FALSE;
+ p = line;
+ }
+ }
+
+ /* Append the original line */
+ mch_memmove(p, ml_get_curline(), (size_t)line_len);
+
+ /* Replace the line */
+ ml_replace(curwin->w_cursor.lnum, line, FALSE);
+
+ /* Put the cursor after the indent. */
+ curwin->w_cursor.col = ind_len;
+ return TRUE;
+}
+
+/*
+ * Return the indent of the current line after a number. Return -1 if no
+ * number was found. Used for 'n' in 'formatoptions': numbered list.
+ * Since a pattern is used it can actually handle more than numbers.
+ */
+int get_number_indent(lnum)
+linenr_T lnum;
+{
+ colnr_T col;
+ pos_T pos;
+
+ regmatch_T regmatch;
+ int lead_len = 0; /* length of comment leader */
+
+ if (lnum > curbuf->b_ml.ml_line_count)
+ return -1;
+ pos.lnum = 0;
+
+ /* In format_lines() (i.e. not insert mode), fo+=q is needed too... */
+ if ((State & INSERT) || has_format_option(FO_Q_COMS))
+ lead_len = get_leader_len(ml_get(lnum), NULL, FALSE, TRUE);
+ regmatch.regprog = vim_regcomp(curbuf->b_p_flp, RE_MAGIC);
+ if (regmatch.regprog != NULL) {
+ regmatch.rm_ic = FALSE;
+
+ /* vim_regexec() expects a pointer to a line. This lets us
+ * start matching for the flp beyond any comment leader... */
+ if (vim_regexec(&regmatch, ml_get(lnum) + lead_len, (colnr_T)0)) {
+ pos.lnum = lnum;
+ pos.col = (colnr_T)(*regmatch.endp - ml_get(lnum));
+ pos.coladd = 0;
+ }
+ vim_regfree(regmatch.regprog);
+ }
+
+ if (pos.lnum == 0 || *ml_get_pos(&pos) == NUL)
+ return -1;
+ getvcol(curwin, &pos, &col, NULL, NULL);
+ return (int)col;
+}
+
+
+static int cin_is_cinword __ARGS((char_u *line));
+
+/*
+ * Return TRUE if the string "line" starts with a word from 'cinwords'.
+ */
+static int cin_is_cinword(line)
+char_u *line;
+{
+ char_u *cinw;
+ char_u *cinw_buf;
+ int cinw_len;
+ int retval = FALSE;
+ int len;
+
+ cinw_len = (int)STRLEN(curbuf->b_p_cinw) + 1;
+ cinw_buf = alloc((unsigned)cinw_len);
+ if (cinw_buf != NULL) {
+ line = skipwhite(line);
+ for (cinw = curbuf->b_p_cinw; *cinw; ) {
+ len = copy_option_part(&cinw, cinw_buf, cinw_len, ",");
+ if (STRNCMP(line, cinw_buf, len) == 0
+ && (!vim_iswordc(line[len]) || !vim_iswordc(line[len - 1]))) {
+ retval = TRUE;
+ break;
+ }
+ }
+ vim_free(cinw_buf);
+ }
+ return retval;
+}
+
+/*
+ * open_line: Add a new line below or above the current line.
+ *
+ * For VREPLACE mode, we only add a new line when we get to the end of the
+ * file, otherwise we just start replacing the next line.
+ *
+ * Caller must take care of undo. Since VREPLACE may affect any number of
+ * lines however, it may call u_save_cursor() again when starting to change a
+ * new line.
+ * "flags": OPENLINE_DELSPACES delete spaces after cursor
+ * OPENLINE_DO_COM format comments
+ * OPENLINE_KEEPTRAIL keep trailing spaces
+ * OPENLINE_MARKFIX adjust mark positions after the line break
+ * OPENLINE_COM_LIST format comments with list or 2nd line indent
+ *
+ * "second_line_indent": indent for after ^^D in Insert mode or if flag
+ * OPENLINE_COM_LIST
+ *
+ * Return TRUE for success, FALSE for failure
+ */
+int open_line(dir, flags, second_line_indent)
+int dir; /* FORWARD or BACKWARD */
+int flags;
+int second_line_indent;
+{
+ char_u *saved_line; /* copy of the original line */
+ char_u *next_line = NULL; /* copy of the next line */
+ char_u *p_extra = NULL; /* what goes to next line */
+ int less_cols = 0; /* less columns for mark in new line */
+ int less_cols_off = 0; /* columns to skip for mark adjust */
+ pos_T old_cursor; /* old cursor position */
+ int newcol = 0; /* new cursor column */
+ int newindent = 0; /* auto-indent of the new line */
+ int n;
+ int trunc_line = FALSE; /* truncate current line afterwards */
+ int retval = FALSE; /* return value, default is FAIL */
+ 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 */
+ char_u *leader = NULL; /* copy of comment leader */
+ char_u *allocated = NULL; /* allocated memory */
+#if defined(FEAT_SMARTINDENT) || defined(FEAT_VREPLACE) || defined(FEAT_LISP) \
+ || defined(FEAT_CINDENT) || defined(FEAT_COMMENTS)
+ char_u *p;
+#endif
+ int saved_char = NUL; /* init for GCC */
+ pos_T *pos;
+ int do_si = (!p_paste && curbuf->b_p_si
+ && !curbuf->b_p_cin
+ );
+ int no_si = FALSE; /* reset did_si afterwards */
+ int first_char = NUL; /* init for GCC */
+ int vreplace_mode;
+ int did_append; /* appended a new line */
+ int saved_pi = curbuf->b_p_pi; /* copy of preserveindent setting */
+
+ /*
+ * make a copy of the current line so we can mess with it
+ */
+ saved_line = vim_strsave(ml_get_curline());
+ if (saved_line == NULL) /* out of memory! */
+ return FALSE;
+
+ if (State & VREPLACE_FLAG) {
+ /*
+ * With VREPLACE we make a copy of the next line, which we will be
+ * starting to replace. First make the new line empty and let vim play
+ * with the indenting and comment leader to its heart's content. Then
+ * we grab what it ended up putting on the new line, put back the
+ * original line, and call ins_char() to put each new character onto
+ * the line, replacing what was there before and pushing the right
+ * stuff onto the replace stack. -- webb.
+ */
+ if (curwin->w_cursor.lnum < orig_line_count)
+ next_line = vim_strsave(ml_get(curwin->w_cursor.lnum + 1));
+ else
+ next_line = vim_strsave((char_u *)"");
+ if (next_line == NULL) /* out of memory! */
+ goto theend;
+
+ /*
+ * In VREPLACE mode, a NL replaces the rest of the line, and starts
+ * replacing the next line, so push all of the characters left on the
+ * line onto the replace stack. We'll push any other characters that
+ * might be replaced at the start of the next line (due to autoindent
+ * etc) a bit later.
+ */
+ replace_push(NUL); /* Call twice because BS over NL expects it */
+ replace_push(NUL);
+ p = saved_line + curwin->w_cursor.col;
+ while (*p != NUL) {
+ if (has_mbyte)
+ p += replace_push_mb(p);
+ else
+ replace_push(*p++);
+ }
+ saved_line[curwin->w_cursor.col] = NUL;
+ }
+
+ if ((State & INSERT)
+ && !(State & VREPLACE_FLAG)
+ ) {
+ p_extra = saved_line + curwin->w_cursor.col;
+ if (do_si) { /* need first char after new line break */
+ p = skipwhite(p_extra);
+ first_char = *p;
+ }
+ extra_len = (int)STRLEN(p_extra);
+ saved_char = *p_extra;
+ *p_extra = NUL;
+ }
+
+ u_clearline(); /* cannot do "U" command when adding lines */
+ did_si = FALSE;
+ ai_col = 0;
+
+ /*
+ * If we just did an auto-indent, then we didn't type anything on
+ * the prior line, and it should be truncated. Do this even if 'ai' is not
+ * set because automatically inserting a comment leader also sets did_ai.
+ */
+ if (dir == FORWARD && did_ai)
+ trunc_line = TRUE;
+
+ /*
+ * If 'autoindent' and/or 'smartindent' is set, try to figure out what
+ * indent to use for the new line.
+ */
+ if (curbuf->b_p_ai
+ || do_si
+ ) {
+ /*
+ * count white space on current line
+ */
+ newindent = get_indent_str(saved_line, (int)curbuf->b_p_ts);
+ if (newindent == 0 && !(flags & OPENLINE_COM_LIST))
+ newindent = second_line_indent; /* for ^^D command in insert mode */
+
+ /*
+ * Do smart indenting.
+ * In insert/replace mode (only when dir == FORWARD)
+ * we may move some text to the next line. If it starts with '{'
+ * don't add an indent. Fixes inserting a NL before '{' in line
+ * "if (condition) {"
+ */
+ if (!trunc_line && do_si && *saved_line != NUL
+ && (p_extra == NULL || first_char != '{')) {
+ char_u *ptr;
+ char_u last_char;
+
+ old_cursor = curwin->w_cursor;
+ ptr = saved_line;
+ if (flags & OPENLINE_DO_COM)
+ lead_len = get_leader_len(ptr, NULL, FALSE, TRUE);
+ else
+ lead_len = 0;
+ if (dir == FORWARD) {
+ /*
+ * Skip preprocessor directives, unless they are
+ * recognised as comments.
+ */
+ if (
+ lead_len == 0 &&
+ ptr[0] == '#') {
+ while (ptr[0] == '#' && curwin->w_cursor.lnum > 1)
+ ptr = ml_get(--curwin->w_cursor.lnum);
+ newindent = get_indent();
+ }
+ if (flags & OPENLINE_DO_COM)
+ lead_len = get_leader_len(ptr, NULL, FALSE, TRUE);
+ else
+ lead_len = 0;
+ if (lead_len > 0) {
+ /*
+ * This case gets the following right:
+ * \*
+ * * A comment (read '\' as '/').
+ * *\
+ * #define IN_THE_WAY
+ * This should line up here;
+ */
+ p = skipwhite(ptr);
+ if (p[0] == '/' && p[1] == '*')
+ p++;
+ if (p[0] == '*') {
+ for (p++; *p; p++) {
+ if (p[0] == '/' && p[-1] == '*') {
+ /*
+ * End of C comment, indent should line up
+ * with the line containing the start of
+ * the comment
+ */
+ curwin->w_cursor.col = (colnr_T)(p - ptr);
+ if ((pos = findmatch(NULL, NUL)) != NULL) {
+ curwin->w_cursor.lnum = pos->lnum;
+ newindent = get_indent();
+ }
+ }
+ }
+ }
+ } else { /* Not a comment line */
+ /* Find last non-blank in line */
+ p = ptr + STRLEN(ptr) - 1;
+ while (p > ptr && vim_iswhite(*p))
+ --p;
+ last_char = *p;
+
+ /*
+ * find the character just before the '{' or ';'
+ */
+ if (last_char == '{' || last_char == ';') {
+ if (p > ptr)
+ --p;
+ while (p > ptr && vim_iswhite(*p))
+ --p;
+ }
+ /*
+ * Try to catch lines that are split over multiple
+ * lines. eg:
+ * if (condition &&
+ * condition) {
+ * Should line up here!
+ * }
+ */
+ if (*p == ')') {
+ curwin->w_cursor.col = (colnr_T)(p - ptr);
+ if ((pos = findmatch(NULL, '(')) != NULL) {
+ curwin->w_cursor.lnum = pos->lnum;
+ newindent = get_indent();
+ ptr = ml_get_curline();
+ }
+ }
+ /*
+ * If last character is '{' do indent, without
+ * checking for "if" and the like.
+ */
+ if (last_char == '{') {
+ did_si = TRUE; /* do indent */
+ no_si = TRUE; /* don't delete it when '{' typed */
+ }
+ /*
+ * Look for "if" and the like, use 'cinwords'.
+ * Don't do this if the previous line ended in ';' or
+ * '}'.
+ */
+ else if (last_char != ';' && last_char != '}'
+ && cin_is_cinword(ptr))
+ did_si = TRUE;
+ }
+ } else { /* dir == BACKWARD */
+ /*
+ * Skip preprocessor directives, unless they are
+ * recognised as comments.
+ */
+ if (
+ lead_len == 0 &&
+ ptr[0] == '#') {
+ int was_backslashed = FALSE;
+
+ while ((ptr[0] == '#' || was_backslashed) &&
+ curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count) {
+ if (*ptr && ptr[STRLEN(ptr) - 1] == '\\')
+ was_backslashed = TRUE;
+ else
+ was_backslashed = FALSE;
+ ptr = ml_get(++curwin->w_cursor.lnum);
+ }
+ if (was_backslashed)
+ newindent = 0; /* Got to end of file */
+ else
+ newindent = get_indent();
+ }
+ p = skipwhite(ptr);
+ 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;
+
+ did_ai = TRUE;
+ }
+
+ /*
+ * Find out if the current line starts with a comment leader.
+ * This may then be inserted in front of the new line.
+ */
+ end_comment_pending = NUL;
+ if (flags & OPENLINE_DO_COM)
+ lead_len = get_leader_len(saved_line, &lead_flags, dir == BACKWARD, TRUE);
+ else
+ lead_len = 0;
+ if (lead_len > 0) {
+ char_u *lead_repl = NULL; /* replaces comment leader */
+ int lead_repl_len = 0; /* length of *lead_repl */
+ char_u lead_middle[COM_MAX_LEN]; /* middle-comment string */
+ char_u lead_end[COM_MAX_LEN]; /* end-comment string */
+ char_u *comment_end = NULL; /* where lead_end has been found */
+ int extra_space = FALSE; /* append extra space */
+ int current_flag;
+ int require_blank = FALSE; /* requires blank after middle */
+ char_u *p2;
+
+ /*
+ * If the comment leader has the start, middle or end flag, it may not
+ * be used or may be replaced with the middle leader.
+ */
+ for (p = lead_flags; *p && *p != ':'; ++p) {
+ if (*p == COM_BLANK) {
+ require_blank = TRUE;
+ continue;
+ }
+ if (*p == COM_START || *p == COM_MIDDLE) {
+ current_flag = *p;
+ if (*p == COM_START) {
+ /*
+ * Doing "O" on a start of comment does not insert leader.
+ */
+ if (dir == BACKWARD) {
+ lead_len = 0;
+ break;
+ }
+
+ /* find start of middle part */
+ (void)copy_option_part(&p, lead_middle, COM_MAX_LEN, ",");
+ require_blank = FALSE;
+ }
+
+ /*
+ * Isolate the strings of the middle and end leader.
+ */
+ while (*p && p[-1] != ':') { /* find end of middle flags */
+ if (*p == COM_BLANK)
+ require_blank = TRUE;
+ ++p;
+ }
+ (void)copy_option_part(&p, lead_middle, COM_MAX_LEN, ",");
+
+ while (*p && p[-1] != ':') { /* find end of end flags */
+ /* Check whether we allow automatic ending of comments */
+ if (*p == COM_AUTO_END)
+ end_comment_pending = -1; /* means we want to set it */
+ ++p;
+ }
+ n = copy_option_part(&p, lead_end, COM_MAX_LEN, ",");
+
+ if (end_comment_pending == -1) /* we can set it now */
+ end_comment_pending = lead_end[n - 1];
+
+ /*
+ * If the end of the comment is in the same line, don't use
+ * the comment leader.
+ */
+ if (dir == FORWARD) {
+ for (p = saved_line + lead_len; *p; ++p)
+ if (STRNCMP(p, lead_end, n) == 0) {
+ comment_end = p;
+ lead_len = 0;
+ break;
+ }
+ }
+
+ /*
+ * Doing "o" on a start of comment inserts the middle leader.
+ */
+ if (lead_len > 0) {
+ if (current_flag == COM_START) {
+ lead_repl = lead_middle;
+ lead_repl_len = (int)STRLEN(lead_middle);
+ }
+
+ /*
+ * If we have hit RETURN immediately after the start
+ * comment leader, then put a space after the middle
+ * comment leader on the next line.
+ */
+ if (!vim_iswhite(saved_line[lead_len - 1])
+ && ((p_extra != NULL
+ && (int)curwin->w_cursor.col == lead_len)
+ || (p_extra == NULL
+ && saved_line[lead_len] == NUL)
+ || require_blank))
+ extra_space = TRUE;
+ }
+ break;
+ }
+ if (*p == COM_END) {
+ /*
+ * Doing "o" on the end of a comment does not insert leader.
+ * Remember where the end is, might want to use it to find the
+ * start (for C-comments).
+ */
+ if (dir == FORWARD) {
+ comment_end = skipwhite(saved_line);
+ lead_len = 0;
+ break;
+ }
+
+ /*
+ * Doing "O" on the end of a comment inserts the middle leader.
+ * Find the string for the middle leader, searching backwards.
+ */
+ while (p > curbuf->b_p_com && *p != ',')
+ --p;
+ for (lead_repl = p; lead_repl > curbuf->b_p_com
+ && lead_repl[-1] != ':'; --lead_repl)
+ ;
+ lead_repl_len = (int)(p - lead_repl);
+
+ /* We can probably always add an extra space when doing "O" on
+ * the comment-end */
+ extra_space = TRUE;
+
+ /* Check whether we allow automatic ending of comments */
+ for (p2 = p; *p2 && *p2 != ':'; p2++) {
+ if (*p2 == COM_AUTO_END)
+ end_comment_pending = -1; /* means we want to set it */
+ }
+ if (end_comment_pending == -1) {
+ /* Find last character in end-comment string */
+ while (*p2 && *p2 != ',')
+ p2++;
+ end_comment_pending = p2[-1];
+ }
+ break;
+ }
+ if (*p == COM_FIRST) {
+ /*
+ * Comment leader for first line only: Don't repeat leader
+ * when using "O", blank out leader when using "o".
+ */
+ if (dir == BACKWARD)
+ lead_len = 0;
+ else {
+ lead_repl = (char_u *)"";
+ lead_repl_len = 0;
+ }
+ break;
+ }
+ }
+ if (lead_len) {
+ /* allocate buffer (may concatenate p_extra later) */
+ leader = alloc(lead_len + lead_repl_len + extra_space + extra_len
+ + (second_line_indent > 0 ? second_line_indent : 0) + 1);
+ allocated = leader; /* remember to free it later */
+
+ if (leader == NULL)
+ lead_len = 0;
+ else {
+ vim_strncpy(leader, saved_line, lead_len);
+
+ /*
+ * Replace leader with lead_repl, right or left adjusted
+ */
+ if (lead_repl != NULL) {
+ int c = 0;
+ int off = 0;
+
+ for (p = lead_flags; *p != NUL && *p != ':'; ) {
+ if (*p == COM_RIGHT || *p == COM_LEFT)
+ c = *p++;
+ else if (VIM_ISDIGIT(*p) || *p == '-')
+ off = getdigits(&p);
+ else
+ ++p;
+ }
+ if (c == COM_RIGHT) { /* right adjusted leader */
+ /* find last non-white in the leader to line up with */
+ for (p = leader + lead_len - 1; p > leader
+ && vim_iswhite(*p); --p)
+ ;
+ ++p;
+
+ /* Compute the length of the replaced characters in
+ * screen characters, not bytes. */
+ {
+ int repl_size = vim_strnsize(lead_repl,
+ lead_repl_len);
+ int old_size = 0;
+ char_u *endp = p;
+ int l;
+
+ while (old_size < repl_size && p > leader) {
+ mb_ptr_back(leader, p);
+ old_size += ptr2cells(p);
+ }
+ l = lead_repl_len - (int)(endp - p);
+ if (l != 0)
+ mch_memmove(endp + l, endp,
+ (size_t)((leader + lead_len) - endp));
+ lead_len += l;
+ }
+ mch_memmove(p, lead_repl, (size_t)lead_repl_len);
+ if (p + lead_repl_len > leader + lead_len)
+ p[lead_repl_len] = NUL;
+
+ /* blank-out any other chars from the old leader. */
+ while (--p >= leader) {
+ int l = mb_head_off(leader, p);
+
+ if (l > 1) {
+ p -= l;
+ if (ptr2cells(p) > 1) {
+ p[1] = ' ';
+ --l;
+ }
+ mch_memmove(p + 1, p + l + 1,
+ (size_t)((leader + lead_len) - (p + l + 1)));
+ lead_len -= l;
+ *p = ' ';
+ } else if (!vim_iswhite(*p))
+ *p = ' ';
+ }
+ } else { /* left adjusted leader */
+ p = skipwhite(leader);
+ /* Compute the length of the replaced characters in
+ * screen characters, not bytes. Move the part that is
+ * not to be overwritten. */
+ {
+ int repl_size = vim_strnsize(lead_repl,
+ lead_repl_len);
+ int i;
+ int l;
+
+ for (i = 0; p[i] != NUL && i < lead_len; i += l) {
+ l = (*mb_ptr2len)(p + i);
+ if (vim_strnsize(p, i + l) > repl_size)
+ break;
+ }
+ if (i != lead_repl_len) {
+ mch_memmove(p + lead_repl_len, p + i,
+ (size_t)(lead_len - i - (p - leader)));
+ lead_len += lead_repl_len - i;
+ }
+ }
+ mch_memmove(p, lead_repl, (size_t)lead_repl_len);
+
+ /* Replace any remaining non-white chars in the old
+ * leader by spaces. Keep Tabs, the indent must
+ * remain the same. */
+ for (p += lead_repl_len; p < leader + lead_len; ++p)
+ if (!vim_iswhite(*p)) {
+ /* Don't put a space before a TAB. */
+ if (p + 1 < leader + lead_len && p[1] == TAB) {
+ --lead_len;
+ mch_memmove(p, p + 1,
+ (leader + lead_len) - p);
+ } else {
+ int l = (*mb_ptr2len)(p);
+
+ if (l > 1) {
+ if (ptr2cells(p) > 1) {
+ /* Replace a double-wide char with
+ * two spaces */
+ --l;
+ *p++ = ' ';
+ }
+ mch_memmove(p + 1, p + l,
+ (leader + lead_len) - p);
+ lead_len -= l - 1;
+ }
+ *p = ' ';
+ }
+ }
+ *p = NUL;
+ }
+
+ /* Recompute the indent, it may have changed. */
+ if (curbuf->b_p_ai
+ || do_si
+ )
+ newindent = get_indent_str(leader, (int)curbuf->b_p_ts);
+
+ /* Add the indent offset */
+ if (newindent + off < 0) {
+ off = -newindent;
+ newindent = 0;
+ } else
+ newindent += off;
+
+ /* Correct trailing spaces for the shift, so that
+ * alignment remains equal. */
+ while (off > 0 && lead_len > 0
+ && leader[lead_len - 1] == ' ') {
+ /* Don't do it when there is a tab before the space */
+ if (vim_strchr(skipwhite(leader), '\t') != NULL)
+ break;
+ --lead_len;
+ --off;
+ }
+
+ /* If the leader ends in white space, don't add an
+ * extra space */
+ if (lead_len > 0 && vim_iswhite(leader[lead_len - 1]))
+ extra_space = FALSE;
+ leader[lead_len] = NUL;
+ }
+
+ if (extra_space) {
+ leader[lead_len++] = ' ';
+ leader[lead_len] = NUL;
+ }
+
+ newcol = lead_len;
+
+ /*
+ * if a new indent will be set below, remove the indent that
+ * is in the comment leader
+ */
+ if (newindent
+ || did_si
+ ) {
+ while (lead_len && vim_iswhite(*leader)) {
+ --lead_len;
+ --newcol;
+ ++leader;
+ }
+ }
+
+ }
+ 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
+ * indent to align with the line containing the start of the
+ * comment.
+ */
+ if (comment_end[0] == '*' && comment_end[1] == '/' &&
+ (curbuf->b_p_ai
+ || do_si
+ )) {
+ old_cursor = curwin->w_cursor;
+ curwin->w_cursor.col = (colnr_T)(comment_end - saved_line);
+ if ((pos = findmatch(NULL, NUL)) != NULL) {
+ curwin->w_cursor.lnum = pos->lnum;
+ newindent = get_indent();
+ }
+ curwin->w_cursor = old_cursor;
+ }
+ }
+ }
+
+ /* (State == INSERT || State == REPLACE), only when dir == FORWARD */
+ if (p_extra != NULL) {
+ *p_extra = saved_char; /* restore char that NUL replaced */
+
+ /*
+ * When 'ai' set or "flags" has OPENLINE_DELSPACES, skip to the first
+ * non-blank.
+ *
+ * When in REPLACE mode, put the deleted blanks on the replace stack,
+ * preceded by a NUL, so they can be put back when a BS is entered.
+ */
+ if (REPLACE_NORMAL(State))
+ 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))
+ replace_push(*p_extra);
+ ++p_extra;
+ ++less_cols_off;
+ }
+ }
+ 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);
+ }
+
+ if (p_extra == NULL)
+ p_extra = (char_u *)""; /* append empty line */
+
+ /* concatenate leader and p_extra, if there is a leader */
+ if (lead_len) {
+ if (flags & OPENLINE_COM_LIST && second_line_indent > 0) {
+ int i;
+ int padding = second_line_indent
+ - (newindent + (int)STRLEN(leader));
+
+ /* Here whitespace is inserted after the comment char.
+ * Below, set_indent(newindent, SIN_INSERT) will insert the
+ * whitespace needed before the comment char. */
+ for (i = 0; i < padding; i++) {
+ STRCAT(leader, " ");
+ less_cols--;
+ newcol++;
+ }
+ }
+ STRCAT(leader, p_extra);
+ p_extra = leader;
+ did_ai = TRUE; /* So truncating blanks works with comments */
+ less_cols -= lead_len;
+ } else
+ end_comment_pending = NUL; /* turns out there was no leader */
+
+ old_cursor = curwin->w_cursor;
+ if (dir == BACKWARD)
+ --curwin->w_cursor.lnum;
+ if (!(State & VREPLACE_FLAG) || old_cursor.lnum >= orig_line_count) {
+ 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;
+ } else {
+ /*
+ * In VREPLACE mode we are starting to replace the next line.
+ */
+ curwin->w_cursor.lnum++;
+ if (curwin->w_cursor.lnum >= Insstart.lnum + vr_lines_changed) {
+ /* In case we NL to a new line, BS to the previous one, and NL
+ * again, we don't want to save the new line for undo twice.
+ */
+ (void)u_save_cursor(); /* errors are ignored! */
+ vr_lines_changed++;
+ }
+ ml_replace(curwin->w_cursor.lnum, p_extra, TRUE);
+ changed_bytes(curwin->w_cursor.lnum, 0);
+ curwin->w_cursor.lnum--;
+ did_append = FALSE;
+ }
+
+ if (newindent
+ || did_si
+ ) {
+ ++curwin->w_cursor.lnum;
+ if (did_si) {
+ int sw = (int)get_sw_value(curbuf);
+
+ if (p_sr)
+ newindent -= newindent % sw;
+ newindent += sw;
+ }
+ /* Copy the indent */
+ if (curbuf->b_p_ci) {
+ (void)copy_indent(newindent, saved_line);
+
+ /*
+ * Set the 'preserveindent' option so that any further screwing
+ * with the line doesn't entirely destroy our efforts to preserve
+ * it. It gets restored at the function end.
+ */
+ curbuf->b_p_pi = TRUE;
+ } else
+ (void)set_indent(newindent, SIN_INSERT);
+ less_cols -= curwin->w_cursor.col;
+
+ ai_col = curwin->w_cursor.col;
+
+ /*
+ * In REPLACE mode, for each character in the new indent, there must
+ * be a NUL on the replace stack, for when it is deleted with BS
+ */
+ if (REPLACE_NORMAL(State))
+ for (n = 0; n < (int)curwin->w_cursor.col; ++n)
+ replace_push(NUL);
+ newcol += curwin->w_cursor.col;
+ if (no_si)
+ did_si = FALSE;
+ }
+
+ /*
+ * In REPLACE mode, for each character in the extra leader, there must be
+ * a NUL on the replace stack, for when it is deleted with BS.
+ */
+ if (REPLACE_NORMAL(State))
+ while (lead_len-- > 0)
+ replace_push(NUL);
+
+ curwin->w_cursor = old_cursor;
+
+ if (dir == FORWARD) {
+ if (trunc_line || (State & INSERT)) {
+ /* 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))
+ truncate_spaces(saved_line);
+ 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;
+
+ /* Move marks after the line break to the new line. */
+ if (flags & OPENLINE_MARKFIX)
+ mark_col_adjust(curwin->w_cursor.lnum,
+ curwin->w_cursor.col + less_cols_off,
+ 1L, (long)-less_cols);
+ } else
+ changed_bytes(curwin->w_cursor.lnum, curwin->w_cursor.col);
+ }
+
+ /*
+ * Put the cursor on the new line. Careful: the scrollup() above may
+ * have moved w_cursor, we must use old_cursor.
+ */
+ curwin->w_cursor.lnum = old_cursor.lnum + 1;
+ }
+ if (did_append)
+ changed_lines(curwin->w_cursor.lnum, 0, curwin->w_cursor.lnum, 1L);
+
+ curwin->w_cursor.col = newcol;
+ curwin->w_cursor.coladd = 0;
+
+ /*
+ * In VREPLACE mode, we are handling the replace stack ourselves, so stop
+ * fixthisline() from doing it (via change_indent()) by telling it we're in
+ * normal INSERT mode.
+ */
+ if (State & VREPLACE_FLAG) {
+ vreplace_mode = State; /* So we know to put things right later */
+ State = INSERT;
+ } else
+ vreplace_mode = 0;
+ /*
+ * May do lisp indenting.
+ */
+ if (!p_paste
+ && leader == NULL
+ && curbuf->b_p_lisp
+ && curbuf->b_p_ai) {
+ fixthisline(get_lisp_indent);
+ p = ml_get_curline();
+ ai_col = (colnr_T)(skipwhite(p) - p);
+ }
+ /*
+ * May do indenting after opening a new line.
+ */
+ if (!p_paste
+ && (curbuf->b_p_cin
+ || *curbuf->b_p_inde != NUL
+ )
+ && in_cinkeys(dir == FORWARD
+ ? KEY_OPEN_FORW
+ : KEY_OPEN_BACK, ' ', linewhite(curwin->w_cursor.lnum))) {
+ do_c_expr_indent();
+ p = ml_get_curline();
+ ai_col = (colnr_T)(skipwhite(p) - p);
+ }
+ if (vreplace_mode != 0)
+ State = vreplace_mode;
+
+ /*
+ * Finally, VREPLACE gets the stuff on the new line, then puts back the
+ * original line, and inserts the new stuff char by char, pushing old stuff
+ * onto the replace stack (via ins_char()).
+ */
+ if (State & VREPLACE_FLAG) {
+ /* Put new line in p_extra */
+ p_extra = vim_strsave(ml_get_curline());
+ if (p_extra == NULL)
+ goto theend;
+
+ /* Put back original line */
+ ml_replace(curwin->w_cursor.lnum, next_line, FALSE);
+
+ /* Insert new stuff into line again */
+ curwin->w_cursor.col = 0;
+ curwin->w_cursor.coladd = 0;
+ ins_bytes(p_extra); /* will call changed_bytes() */
+ vim_free(p_extra);
+ next_line = NULL;
+ }
+
+ retval = TRUE; /* success! */
+theend:
+ curbuf->b_p_pi = saved_pi;
+ vim_free(saved_line);
+ vim_free(next_line);
+ vim_free(allocated);
+ return retval;
+}
+
+/*
+ * get_leader_len() returns the length in bytes of the prefix of the given
+ * string which introduces a comment. If this string is not a comment then
+ * 0 is returned.
+ * When "flags" is not NULL, it is set to point to the flags of the recognized
+ * comment leader.
+ * "backward" must be true for the "O" command.
+ * If "include_space" is set, include trailing whitespace while calculating the
+ * length.
+ */
+int get_leader_len(line, flags, backward, include_space)
+char_u *line;
+char_u **flags;
+int backward;
+int include_space;
+{
+ int i, j;
+ int result;
+ int got_com = FALSE;
+ int found_one;
+ char_u part_buf[COM_MAX_LEN]; /* buffer for one option part */
+ char_u *string; /* pointer to comment string */
+ char_u *list;
+ int middle_match_len = 0;
+ char_u *prev_list;
+ char_u *saved_flags = NULL;
+
+ result = i = 0;
+ while (vim_iswhite(line[i])) /* leading white space is ignored */
+ ++i;
+
+ /*
+ * Repeat to match several nested comment strings.
+ */
+ while (line[i] != NUL) {
+ /*
+ * scan through the 'comments' option for a match
+ */
+ found_one = FALSE;
+ for (list = curbuf->b_p_com; *list; ) {
+ /* Get one option part into part_buf[]. Advance "list" to next
+ * one. Put "string" at start of string. */
+ if (!got_com && flags != NULL)
+ *flags = list; /* remember where flags started */
+ prev_list = list;
+ (void)copy_option_part(&list, part_buf, COM_MAX_LEN, ",");
+ string = vim_strchr(part_buf, ':');
+ if (string == NULL) /* missing ':', ignore this part */
+ continue;
+ *string++ = NUL; /* isolate flags from string */
+
+ /* If we found a middle match previously, use that match when this
+ * is not a middle or end. */
+ if (middle_match_len != 0
+ && vim_strchr(part_buf, COM_MIDDLE) == NULL
+ && vim_strchr(part_buf, COM_END) == NULL)
+ break;
+
+ /* When we already found a nested comment, only accept further
+ * nested comments. */
+ if (got_com && vim_strchr(part_buf, COM_NEST) == NULL)
+ continue;
+
+ /* When 'O' flag present and using "O" command skip this one. */
+ if (backward && vim_strchr(part_buf, COM_NOBACK) != NULL)
+ continue;
+
+ /* Line contents and string must match.
+ * When string starts with white space, must have some white space
+ * (but the amount does not need to match, there might be a mix of
+ * TABs and spaces). */
+ if (vim_iswhite(string[0])) {
+ if (i == 0 || !vim_iswhite(line[i - 1]))
+ continue; /* missing white space */
+ while (vim_iswhite(string[0]))
+ ++string;
+ }
+ for (j = 0; string[j] != NUL && string[j] == line[i + j]; ++j)
+ ;
+ if (string[j] != NUL)
+ continue; /* string doesn't match */
+
+ /* When 'b' flag used, there must be white space or an
+ * end-of-line after the string in the line. */
+ if (vim_strchr(part_buf, COM_BLANK) != NULL
+ && !vim_iswhite(line[i + j]) && line[i + j] != NUL)
+ continue;
+
+ /* We have found a match, stop searching unless this is a middle
+ * comment. The middle comment can be a substring of the end
+ * comment in which case it's better to return the length of the
+ * end comment and its flags. Thus we keep searching with middle
+ * and end matches and use an end match if it matches better. */
+ if (vim_strchr(part_buf, COM_MIDDLE) != NULL) {
+ if (middle_match_len == 0) {
+ middle_match_len = j;
+ saved_flags = prev_list;
+ }
+ continue;
+ }
+ if (middle_match_len != 0 && j > middle_match_len)
+ /* Use this match instead of the middle match, since it's a
+ * longer thus better match. */
+ middle_match_len = 0;
+
+ if (middle_match_len == 0)
+ i += j;
+ found_one = TRUE;
+ break;
+ }
+
+ if (middle_match_len != 0) {
+ /* Use the previously found middle match after failing to find a
+ * match with an end. */
+ if (!got_com && flags != NULL)
+ *flags = saved_flags;
+ i += middle_match_len;
+ found_one = TRUE;
+ }
+
+ /* No match found, stop scanning. */
+ if (!found_one)
+ break;
+
+ result = i;
+
+ /* Include any trailing white space. */
+ while (vim_iswhite(line[i]))
+ ++i;
+
+ if (include_space)
+ result = i;
+
+ /* If this comment doesn't nest, stop here. */
+ got_com = TRUE;
+ if (vim_strchr(part_buf, COM_NEST) == NULL)
+ break;
+ }
+ return result;
+}
+
+/*
+ * Return the offset at which the last comment in line starts. If there is no
+ * comment in the whole line, -1 is returned.
+ *
+ * When "flags" is not null, it is set to point to the flags describing the
+ * recognized comment leader.
+ */
+int get_last_leader_offset(line, flags)
+char_u *line;
+char_u **flags;
+{
+ int result = -1;
+ int i, j;
+ int lower_check_bound = 0;
+ char_u *string;
+ char_u *com_leader;
+ char_u *com_flags;
+ char_u *list;
+ int found_one;
+ char_u part_buf[COM_MAX_LEN]; /* buffer for one option part */
+
+ /*
+ * Repeat to match several nested comment strings.
+ */
+ i = (int)STRLEN(line);
+ while (--i >= lower_check_bound) {
+ /*
+ * scan through the 'comments' option for a match
+ */
+ found_one = FALSE;
+ for (list = curbuf->b_p_com; *list; ) {
+ char_u *flags_save = list;
+
+ /*
+ * Get one option part into part_buf[]. Advance list to next one.
+ * put string at start of string.
+ */
+ (void)copy_option_part(&list, part_buf, COM_MAX_LEN, ",");
+ string = vim_strchr(part_buf, ':');
+ if (string == NULL) { /* If everything is fine, this cannot actually
+ * happen. */
+ continue;
+ }
+ *string++ = NUL; /* Isolate flags from string. */
+ com_leader = string;
+
+ /*
+ * Line contents and string must match.
+ * When string starts with white space, must have some white space
+ * (but the amount does not need to match, there might be a mix of
+ * TABs and spaces).
+ */
+ if (vim_iswhite(string[0])) {
+ if (i == 0 || !vim_iswhite(line[i - 1]))
+ continue;
+ while (vim_iswhite(string[0]))
+ ++string;
+ }
+ for (j = 0; string[j] != NUL && string[j] == line[i + j]; ++j)
+ /* do nothing */;
+ if (string[j] != NUL)
+ continue;
+
+ /*
+ * When 'b' flag used, there must be white space or an
+ * end-of-line after the string in the line.
+ */
+ if (vim_strchr(part_buf, COM_BLANK) != NULL
+ && !vim_iswhite(line[i + j]) && line[i + j] != NUL) {
+ continue;
+ }
+
+ /*
+ * We have found a match, stop searching.
+ */
+ found_one = TRUE;
+
+ if (flags)
+ *flags = flags_save;
+ com_flags = flags_save;
+
+ break;
+ }
+
+ if (found_one) {
+ char_u part_buf2[COM_MAX_LEN]; /* buffer for one option part */
+ int len1, len2, off;
+
+ result = i;
+ /*
+ * If this comment nests, continue searching.
+ */
+ if (vim_strchr(part_buf, COM_NEST) != NULL)
+ continue;
+
+ lower_check_bound = i;
+
+ /* Let's verify whether the comment leader found is a substring
+ * of other comment leaders. If it is, let's adjust the
+ * lower_check_bound so that we make sure that we have determined
+ * the comment leader correctly.
+ */
+
+ while (vim_iswhite(*com_leader))
+ ++com_leader;
+ len1 = (int)STRLEN(com_leader);
+
+ for (list = curbuf->b_p_com; *list; ) {
+ char_u *flags_save = list;
+
+ (void)copy_option_part(&list, part_buf2, COM_MAX_LEN, ",");
+ if (flags_save == com_flags)
+ continue;
+ string = vim_strchr(part_buf2, ':');
+ ++string;
+ while (vim_iswhite(*string))
+ ++string;
+ len2 = (int)STRLEN(string);
+ if (len2 == 0)
+ continue;
+
+ /* Now we have to verify whether string ends with a substring
+ * beginning the com_leader. */
+ for (off = (len2 > i ? i : len2); off > 0 && off + len1 > len2; ) {
+ --off;
+ if (!STRNCMP(string + off, com_leader, len2 - off)) {
+ if (i - off < lower_check_bound)
+ lower_check_bound = i - off;
+ }
+ }
+ }
+ }
+ }
+ return result;
+}
+
+/*
+ * Return the number of window lines occupied by buffer line "lnum".
+ */
+int plines(lnum)
+linenr_T lnum;
+{
+ return plines_win(curwin, lnum, TRUE);
+}
+
+int plines_win(wp, lnum, winheight)
+win_T *wp;
+linenr_T lnum;
+int winheight; /* when TRUE limit to window height */
+{
+ /* Check for filler lines above this buffer line. When folded the result
+ * is one line anyway. */
+ return plines_win_nofill(wp, lnum, winheight) + diff_check_fill(wp, lnum);
+}
+
+int plines_nofill(lnum)
+linenr_T lnum;
+{
+ return plines_win_nofill(curwin, lnum, TRUE);
+}
+
+int plines_win_nofill(wp, lnum, winheight)
+win_T *wp;
+linenr_T lnum;
+int winheight; /* when TRUE limit to window height */
+{
+ int lines;
+
+ if (!wp->w_p_wrap)
+ return 1;
+
+ if (wp->w_width == 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)
+ return 1;
+
+ lines = plines_win_nofold(wp, lnum);
+ if (winheight > 0 && lines > wp->w_height)
+ return (int)wp->w_height;
+ return lines;
+}
+
+/*
+ * Return number of window lines physical line "lnum" will occupy in window
+ * "wp". Does not care about folding, 'wrap' or 'diff'.
+ */
+int plines_win_nofold(wp, lnum)
+win_T *wp;
+linenr_T lnum;
+{
+ char_u *s;
+ long col;
+ int width;
+
+ s = ml_get_buf(wp->w_buffer, lnum, FALSE);
+ if (*s == NUL) /* empty line */
+ return 1;
+ col = win_linetabsize(wp, s, (colnr_T)MAXCOL);
+
+ /*
+ * If list mode is on, then the '$' at the end of the line may take up one
+ * extra column.
+ */
+ if (wp->w_p_list && lcs_eol != NUL)
+ col += 1;
+
+ /*
+ * Add column offset for 'number', 'relativenumber' and 'foldcolumn'.
+ */
+ width = W_WIDTH(wp) - win_col_off(wp);
+ if (width <= 0)
+ return 32000;
+ if (col <= width)
+ return 1;
+ col -= width;
+ width += win_col_off2(wp);
+ return (col + (width - 1)) / width + 1;
+}
+
+/*
+ * Like plines_win(), but only reports the number of physical screen lines
+ * used from the start of the line to the given column number.
+ */
+int plines_win_col(wp, lnum, column)
+win_T *wp;
+linenr_T lnum;
+long column;
+{
+ long col;
+ char_u *s;
+ int lines = 0;
+ int width;
+
+ /* Check for filler lines above this buffer line. When folded the result
+ * is one line anyway. */
+ lines = diff_check_fill(wp, lnum);
+
+ if (!wp->w_p_wrap)
+ return lines + 1;
+
+ if (wp->w_width == 0)
+ return lines + 1;
+
+ s = ml_get_buf(wp->w_buffer, lnum, FALSE);
+
+ col = 0;
+ while (*s != NUL && --column >= 0) {
+ col += win_lbr_chartabsize(wp, s, (colnr_T)col, NULL);
+ mb_ptr_adv(s);
+ }
+
+ /*
+ * If *s is a TAB, and the TAB is not displayed as ^I, and we're not in
+ * INSERT mode, then col must be adjusted so that it represents the last
+ * screen position of the TAB. This only fixes an error when the TAB wraps
+ * from one screen line to the next (when 'columns' is not a multiple of
+ * 'ts') -- webb.
+ */
+ if (*s == TAB && (State & NORMAL) && (!wp->w_p_list || lcs_tab1))
+ col += win_lbr_chartabsize(wp, s, (colnr_T)col, NULL) - 1;
+
+ /*
+ * Add column offset for 'number', 'relativenumber', 'foldcolumn', etc.
+ */
+ width = W_WIDTH(wp) - win_col_off(wp);
+ if (width <= 0)
+ return 9999;
+
+ lines += 1;
+ if (col > width)
+ lines += (col - width) / (width + win_col_off2(wp)) + 1;
+ return lines;
+}
+
+int plines_m_win(wp, first, last)
+win_T *wp;
+linenr_T first, last;
+{
+ int count = 0;
+
+ while (first <= last) {
+ int x;
+
+ /* Check if there are any really folded lines, but also included lines
+ * that are maybe folded. */
+ x = foldedCount(wp, first, NULL);
+ if (x > 0) {
+ ++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;
+ }
+ }
+ return count;
+}
+
+/*
+ * Insert string "p" at the cursor position. Stops at a NUL byte.
+ * Handles Replace mode and multi-byte characters.
+ */
+void ins_bytes(p)
+char_u *p;
+{
+ ins_bytes_len(p, (int)STRLEN(p));
+}
+
+#if defined(FEAT_VREPLACE) || defined(FEAT_INS_EXPAND) \
+ || defined(FEAT_COMMENTS) || defined(FEAT_MBYTE) || defined(PROTO)
+/*
+ * Insert string "p" with length "len" at the cursor position.
+ * Handles Replace mode and multi-byte characters.
+ */
+void ins_bytes_len(p, len)
+char_u *p;
+int len;
+{
+ int i;
+ int n;
+
+ if (has_mbyte)
+ for (i = 0; i < len; i += n) {
+ if (enc_utf8)
+ /* avoid reading past p[len] */
+ n = utfc_ptr2len_len(p + i, len - i);
+ else
+ n = (*mb_ptr2len)(p + i);
+ ins_char_bytes(p + i, n);
+ }
+ else
+ for (i = 0; i < len; ++i)
+ ins_char(p[i]);
+}
+#endif
+
+/*
+ * Insert or replace a single character at the cursor position.
+ * When in REPLACE or VREPLACE mode, replace any existing character.
+ * Caller must have prepared for undo.
+ * For multi-byte characters we get the whole character, the caller must
+ * convert bytes to a character.
+ */
+void ins_char(c)
+int c;
+{
+ char_u buf[MB_MAXBYTES + 1];
+ int n;
+
+ n = (*mb_char2bytes)(c, buf);
+
+ /* When "c" is 0x100, 0x200, etc. we don't want to insert a NUL byte.
+ * Happens for CTRL-Vu9900. */
+ if (buf[0] == 0)
+ buf[0] = '\n';
+
+ ins_char_bytes(buf, n);
+}
+
+void ins_char_bytes(buf, charlen)
+char_u *buf;
+int charlen;
+{
+ int c = buf[0];
+ int newlen; /* nr of bytes inserted */
+ int oldlen; /* nr of bytes deleted (0 when not replacing) */
+ char_u *p;
+ char_u *newp;
+ char_u *oldp;
+ int linelen; /* length of old line including NUL */
+ colnr_T col;
+ linenr_T lnum = curwin->w_cursor.lnum;
+ int i;
+
+ /* Break tabs if needed. */
+ if (virtual_active() && curwin->w_cursor.coladd > 0)
+ coladvance_force(getviscol());
+
+ col = curwin->w_cursor.col;
+ oldp = ml_get(lnum);
+ linelen = (int)STRLEN(oldp) + 1;
+
+ /* The lengths default to the values for when not replacing. */
+ oldlen = 0;
+ newlen = charlen;
+
+ if (State & REPLACE_FLAG) {
+ if (State & VREPLACE_FLAG) {
+ colnr_T new_vcol = 0; /* init for GCC */
+ colnr_T vcol;
+ int old_list;
+
+ /*
+ * Disable 'list' temporarily, unless 'cpo' contains the 'L' flag.
+ * Returns the old value of list, so when finished,
+ * curwin->w_p_list should be set back to this.
+ */
+ old_list = curwin->w_p_list;
+ if (old_list && vim_strchr(p_cpo, CPO_LISTWM) == NULL)
+ curwin->w_p_list = FALSE;
+
+ /*
+ * In virtual replace mode each character may replace one or more
+ * characters (zero if it's a TAB). Count the number of bytes to
+ * be deleted to make room for the new character, counting screen
+ * cells. May result in adding spaces to fill a gap.
+ */
+ getvcol(curwin, &curwin->w_cursor, NULL, &vcol, NULL);
+ new_vcol = vcol + chartabsize(buf, vcol);
+ while (oldp[col + oldlen] != NUL && vcol < new_vcol) {
+ vcol += chartabsize(oldp + col + oldlen, vcol);
+ /* Don't need to remove a TAB that takes us to the right
+ * position. */
+ if (vcol > new_vcol && oldp[col + oldlen] == TAB)
+ break;
+ oldlen += (*mb_ptr2len)(oldp + col + oldlen);
+ /* Deleted a bit too much, insert spaces. */
+ if (vcol > new_vcol)
+ newlen += vcol - new_vcol;
+ }
+ curwin->w_p_list = old_list;
+ } else if (oldp[col] != NUL) {
+ /* normal replace */
+ oldlen = (*mb_ptr2len)(oldp + col);
+ }
+
+
+ /* Push the replaced bytes onto the replace stack, so that they can be
+ * put back when BS is used. The bytes of a multi-byte character are
+ * done the other way around, so that the first byte is popped off
+ * first (it tells the byte length of the character). */
+ replace_push(NUL);
+ for (i = 0; i < oldlen; ++i) {
+ if (has_mbyte)
+ i += replace_push_mb(oldp + col + i) - 1;
+ else
+ replace_push(oldp[col + i]);
+ }
+ }
+
+ newp = alloc_check((unsigned)(linelen + newlen - oldlen));
+ if (newp == NULL)
+ return;
+
+ /* Copy bytes before the cursor. */
+ if (col > 0)
+ mch_memmove(newp, oldp, (size_t)col);
+
+ /* Copy bytes after the changed character(s). */
+ p = newp + col;
+ mch_memmove(p + newlen, oldp + col + oldlen,
+ (size_t)(linelen - col - oldlen));
+
+ /* Insert or overwrite the new character. */
+ mch_memmove(p, buf, charlen);
+ i = charlen;
+
+ /* Fill with spaces when necessary. */
+ while (i < newlen)
+ p[i++] = ' ';
+
+ /* Replace the line in the buffer. */
+ ml_replace(lnum, newp, FALSE);
+
+ /* mark the buffer as changed and prepare for displaying */
+ changed_bytes(lnum, col);
+
+ /*
+ * If we're in Insert or Replace mode and 'showmatch' is set, then briefly
+ * show the match for right parens and braces.
+ */
+ if (p_sm && (State & INSERT)
+ && msg_silent == 0
+ && !ins_compl_active()
+ ) {
+ if (has_mbyte)
+ showmatch(mb_ptr2char(buf));
+ else
+ showmatch(c);
+ }
+
+ if (!p_ri || (State & REPLACE_FLAG)) {
+ /* Normal insert: move cursor right */
+ curwin->w_cursor.col += charlen;
+ }
+ /*
+ * TODO: should try to update w_row here, to avoid recomputing it later.
+ */
+}
+
+/*
+ * Insert a string at the cursor position.
+ * Note: Does NOT handle Replace mode.
+ * Caller must have prepared for undo.
+ */
+void ins_str(s)
+char_u *s;
+{
+ char_u *oldp, *newp;
+ int newlen = (int)STRLEN(s);
+ int oldlen;
+ colnr_T col;
+ linenr_T lnum = curwin->w_cursor.lnum;
+
+ if (virtual_active() && curwin->w_cursor.coladd > 0)
+ coladvance_force(getviscol());
+
+ col = curwin->w_cursor.col;
+ oldp = ml_get(lnum);
+ oldlen = (int)STRLEN(oldp);
+
+ newp = alloc_check((unsigned)(oldlen + newlen + 1));
+ if (newp == NULL)
+ return;
+ if (col > 0)
+ mch_memmove(newp, oldp, (size_t)col);
+ mch_memmove(newp + col, s, (size_t)newlen);
+ mch_memmove(newp + col + newlen, oldp + col, (size_t)(oldlen - col + 1));
+ 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(fixpos)
+int fixpos;
+{
+ if (has_mbyte) {
+ /* Make sure the cursor is at the start of a character. */
+ mb_adjust_cursor();
+ if (*ml_get_cursor() == NUL)
+ return FAIL;
+ return del_chars(1L, fixpos);
+ }
+ return del_bytes(1L, fixpos, TRUE);
+}
+
+/*
+ * Like del_bytes(), but delete characters instead of bytes.
+ */
+int del_chars(count, fixpos)
+long count;
+int fixpos;
+{
+ long bytes = 0;
+ long i;
+ char_u *p;
+ int l;
+
+ p = ml_get_cursor();
+ for (i = 0; i < count && *p != NUL; ++i) {
+ l = (*mb_ptr2len)(p);
+ bytes += l;
+ p += l;
+ }
+ return del_bytes(bytes, fixpos, TRUE);
+}
+
+/*
+ * Delete "count" bytes 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_bytes(count, fixpos_arg, use_delcombine)
+long count;
+int fixpos_arg;
+int use_delcombine UNUSED; /* 'delcombine' option applies */
+{
+ char_u *oldp, *newp;
+ colnr_T oldlen;
+ linenr_T lnum = curwin->w_cursor.lnum;
+ colnr_T col = curwin->w_cursor.col;
+ int was_alloced;
+ long movelen;
+ int fixpos = fixpos_arg;
+
+ oldp = ml_get(lnum);
+ oldlen = (int)STRLEN(oldp);
+
+ /*
+ * Can't do anything when the cursor is on the NUL after the line.
+ */
+ if (col >= oldlen)
+ return FAIL;
+
+ /* If 'delcombine' is set and deleting (less than) one character, only
+ * delete the last combining character. */
+ if (p_deco && use_delcombine && enc_utf8
+ && utfc_ptr2len(oldp + col) >= count) {
+ int cc[MAX_MCO];
+ int n;
+
+ (void)utfc_ptr2char(oldp + col, cc);
+ if (cc[0] != NUL) {
+ /* Find the last composing char, there can be several. */
+ n = col;
+ do {
+ col = n;
+ count = utf_ptr2len(oldp + n);
+ n += count;
+ } while (UTF_COMPOSINGLIKE(oldp + col, oldp + n));
+ fixpos = 0;
+ }
+ }
+
+ /*
+ * When count is too big, reduce it.
+ */
+ movelen = (long)oldlen - (long)col - count + 1; /* includes trailing NUL */
+ if (movelen <= 1) {
+ /*
+ * If we just took off the last character of a non-blank line, and
+ * fixpos is TRUE, we don't want to end up positioned at the NUL,
+ * unless "restart_edit" is set or 'virtualedit' contains "onemore".
+ */
+ if (col > 0 && fixpos && restart_edit == 0
+ && (ve_flags & VE_ONEMORE) == 0
+ ) {
+ --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);
+ }
+ count = oldlen - col;
+ movelen = 1;
+ }
+
+ /*
+ * If the old line has been allocated the deletion can be done in the
+ * existing line. Otherwise a new line has to be allocated
+ * Can't do this when using Netbeans, because we would need to invoke
+ * netbeans_removed(), which deallocates the line. Let ml_replace() take
+ * care of notifying Netbeans.
+ */
+ was_alloced = ml_line_alloced(); /* check if oldp was allocated */
+ if (was_alloced)
+ newp = oldp; /* use same allocated memory */
+ else { /* need to allocate a new line */
+ newp = alloc((unsigned)(oldlen + 1 - count));
+ if (newp == NULL)
+ return FAIL;
+ mch_memmove(newp, oldp, (size_t)col);
+ }
+ mch_memmove(newp + col, oldp + col + count, (size_t)movelen);
+ if (!was_alloced)
+ ml_replace(lnum, newp, FALSE);
+
+ /* mark the buffer as changed and prepare for displaying */
+ changed_bytes(lnum, curwin->w_cursor.col);
+
+ return OK;
+}
+
+/*
+ * Delete from cursor to end of line.
+ * Caller must have prepared for undo.
+ *
+ * return FAIL for failure, OK otherwise
+ */
+int truncate_line(fixpos)
+int fixpos; /* if TRUE fix the cursor position when done */
+{
+ char_u *newp;
+ linenr_T lnum = curwin->w_cursor.lnum;
+ colnr_T col = curwin->w_cursor.col;
+
+ if (col == 0)
+ newp = vim_strsave((char_u *)"");
+ else
+ newp = vim_strnsave(ml_get(lnum), col);
+
+ if (newp == NULL)
+ return FAIL;
+
+ ml_replace(lnum, newp, FALSE);
+
+ /* mark the buffer as changed and prepare for displaying */
+ changed_bytes(lnum, curwin->w_cursor.col);
+
+ /*
+ * If "fixpos" is TRUE we don't want to end up positioned at the NUL.
+ */
+ if (fixpos && curwin->w_cursor.col > 0)
+ --curwin->w_cursor.col;
+
+ return OK;
+}
+
+/*
+ * Delete "nlines" lines at the cursor.
+ * Saves the lines for undo first if "undo" is TRUE.
+ */
+void del_lines(nlines, undo)
+long nlines; /* number of lines to delete */
+int undo; /* if TRUE, prepare for undo */
+{
+ long n;
+ linenr_T first = curwin->w_cursor.lnum;
+
+ if (nlines <= 0)
+ return;
+
+ /* save the deleted lines for undo */
+ if (undo && u_savedel(first, nlines) == FAIL)
+ return;
+
+ for (n = 0; n < nlines; ) {
+ if (curbuf->b_ml.ml_flags & ML_EMPTY) /* nothing to delete */
+ break;
+
+ ml_delete(first, TRUE);
+ ++n;
+
+ /* If we delete the last line in the file, stop */
+ if (first > curbuf->b_ml.ml_line_count)
+ break;
+ }
+
+ /* Correct the cursor position before calling deleted_lines_mark(), it may
+ * trigger a callback to display the cursor. */
+ curwin->w_cursor.col = 0;
+ check_cursor_lnum();
+
+ /* adjust marks, mark the buffer as changed and prepare for displaying */
+ deleted_lines_mark(first, n);
+}
+
+int gchar_pos(pos)
+pos_T *pos;
+{
+ char_u *ptr = ml_get_pos(pos);
+
+ if (has_mbyte)
+ return (*mb_ptr2char)(ptr);
+ return (int)*ptr;
+}
+
+int gchar_cursor() {
+ if (has_mbyte)
+ return (*mb_ptr2char)(ml_get_cursor());
+ return (int)*ml_get_cursor();
+}
+
+/*
+ * Write a character at the current cursor position.
+ * It is directly written into the block.
+ */
+void pchar_cursor(c)
+int c;
+{
+ *(ml_get_buf(curbuf, curwin->w_cursor.lnum, TRUE)
+ + curwin->w_cursor.col) = c;
+}
+
+/*
+ * When extra == 0: Return TRUE if the cursor is before or on the first
+ * non-blank in the line.
+ * When extra == 1: Return TRUE if the cursor is before the first non-blank in
+ * the line.
+ */
+int inindent(extra)
+int extra;
+{
+ char_u *ptr;
+ colnr_T col;
+
+ for (col = 0, ptr = ml_get_curline(); vim_iswhite(*ptr); ++col)
+ ++ptr;
+ if (col >= curwin->w_cursor.col + extra)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+/*
+ * Skip to next part of an option argument: Skip space and comma.
+ */
+char_u * skip_to_option_part(p)
+char_u *p;
+{
+ if (*p == ',')
+ ++p;
+ while (*p == ' ')
+ ++p;
+ return p;
+}
+
+/*
+ * Call this function when something in the current buffer is changed.
+ *
+ * Most often called through changed_bytes() and changed_lines(), which also
+ * mark the area of the display to be redrawn.
+ *
+ * Careful: may trigger autocommands that reload the buffer.
+ */
+void changed() {
+
+ if (!curbuf->b_changed) {
+ int save_msg_scroll = msg_scroll;
+
+ /* Give a warning about changing a read-only file. This may also
+ * check-out the file, thus change "curbuf"! */
+ change_warning(0);
+
+ /* Create a swap file if that is wanted.
+ * Don't do this for "nofile" and "nowrite" buffer types. */
+ if (curbuf->b_may_swap
+ && !bt_dontwrite(curbuf)
+ ) {
+ ml_open_file(curbuf);
+
+ /* The ml_open_file() can cause an ATTENTION message.
+ * Wait two seconds, to make sure the user reads this unexpected
+ * message. Since we could be anywhere, call wait_return() now,
+ * and don't let the emsg() set msg_scroll. */
+ if (need_wait_return && emsg_silent == 0) {
+ out_flush();
+ ui_delay(2000L, TRUE);
+ wait_return(TRUE);
+ msg_scroll = save_msg_scroll;
+ }
+ }
+ changed_int();
+ }
+ ++curbuf->b_changedtick;
+}
+
+/*
+ * Internal part of changed(), no user interaction.
+ */
+void changed_int() {
+ curbuf->b_changed = TRUE;
+ ml_setflags(curbuf);
+ check_status(curbuf);
+ redraw_tabline = TRUE;
+ need_maketitle = TRUE; /* set window title later */
+}
+
+static void changedOneline __ARGS((buf_T *buf, linenr_T lnum));
+static void changed_lines_buf __ARGS((buf_T *buf, linenr_T lnum, linenr_T lnume,
+ long xtra));
+static void changed_common __ARGS((linenr_T lnum, colnr_T col, linenr_T lnume,
+ long xtra));
+
+/*
+ * Changed bytes within a single line for the current buffer.
+ * - marks the windows on this buffer to be redisplayed
+ * - marks the buffer changed by calling changed()
+ * - invalidates cached values
+ * Careful: may trigger autocommands that reload the buffer.
+ */
+void changed_bytes(lnum, col)
+linenr_T lnum;
+colnr_T col;
+{
+ changedOneline(curbuf, lnum);
+ changed_common(lnum, col, lnum + 1, 0L);
+
+ /* Diff highlighting in other diff windows may need to be updated too. */
+ if (curwin->w_p_diff) {
+ win_T *wp;
+ linenr_T wlnum;
+
+ for (wp = firstwin; wp != NULL; wp = wp->w_next)
+ if (wp->w_p_diff && wp != curwin) {
+ redraw_win_later(wp, VALID);
+ wlnum = diff_lnum_win(lnum, wp);
+ if (wlnum > 0)
+ changedOneline(wp->w_buffer, wlnum);
+ }
+ }
+}
+
+static void changedOneline(buf, lnum)
+buf_T *buf;
+linenr_T lnum;
+{
+ if (buf->b_mod_set) {
+ /* find the maximum area that must be redisplayed */
+ if (lnum < buf->b_mod_top)
+ buf->b_mod_top = lnum;
+ else if (lnum >= buf->b_mod_bot)
+ buf->b_mod_bot = lnum + 1;
+ } else {
+ /* set the area that must be redisplayed to one line */
+ buf->b_mod_set = TRUE;
+ buf->b_mod_top = lnum;
+ buf->b_mod_bot = lnum + 1;
+ buf->b_mod_xlines = 0;
+ }
+}
+
+/*
+ * Appended "count" lines below line "lnum" in the current buffer.
+ * Must be called AFTER the change and after mark_adjust().
+ * Takes care of marking the buffer to be redrawn and sets the changed flag.
+ */
+void appended_lines(lnum, count)
+linenr_T lnum;
+long count;
+{
+ changed_lines(lnum + 1, 0, lnum + 1, count);
+}
+
+/*
+ * Like appended_lines(), but adjust marks first.
+ */
+void appended_lines_mark(lnum, count)
+linenr_T lnum;
+long count;
+{
+ mark_adjust(lnum + 1, (linenr_T)MAXLNUM, count, 0L);
+ changed_lines(lnum + 1, 0, lnum + 1, count);
+}
+
+/*
+ * Deleted "count" lines at line "lnum" in the current buffer.
+ * Must be called AFTER the change and after mark_adjust().
+ * Takes care of marking the buffer to be redrawn and sets the changed flag.
+ */
+void deleted_lines(lnum, count)
+linenr_T lnum;
+long count;
+{
+ changed_lines(lnum, 0, lnum + count, -count);
+}
+
+/*
+ * Like deleted_lines(), but adjust marks first.
+ * Make sure the cursor is on a valid line before calling, a GUI callback may
+ * be triggered to display the cursor.
+ */
+void deleted_lines_mark(lnum, count)
+linenr_T lnum;
+long count;
+{
+ mark_adjust(lnum, (linenr_T)(lnum + count - 1), (long)MAXLNUM, -count);
+ changed_lines(lnum, 0, lnum + count, -count);
+}
+
+/*
+ * Changed lines for the current buffer.
+ * Must be called AFTER the change and after mark_adjust().
+ * - mark the buffer changed by calling changed()
+ * - mark the windows on this buffer to be redisplayed
+ * - invalidate cached values
+ * "lnum" is the first line that needs displaying, "lnume" the first line
+ * below the changed lines (BEFORE the change).
+ * When only inserting lines, "lnum" and "lnume" are equal.
+ * Takes care of calling changed() and updating b_mod_*.
+ * Careful: may trigger autocommands that reload the buffer.
+ */
+void changed_lines(lnum, col, lnume, xtra)
+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) */
+{
+ 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. */
+ win_T *wp;
+ linenr_T wlnum;
+
+ for (wp = firstwin; wp != NULL; wp = wp->w_next)
+ if (wp->w_p_diff && wp != curwin) {
+ redraw_win_later(wp, VALID);
+ wlnum = diff_lnum_win(lnum, wp);
+ if (wlnum > 0)
+ changed_lines_buf(wp->w_buffer, wlnum,
+ lnume - lnum + wlnum, 0L);
+ }
+ }
+
+ changed_common(lnum, col, lnume, xtra);
+}
+
+static void changed_lines_buf(buf, lnum, lnume, xtra)
+buf_T *buf;
+linenr_T lnum; /* first line with change */
+linenr_T lnume; /* line below last changed line */
+long xtra; /* number of extra lines (negative when deleting) */
+{
+ if (buf->b_mod_set) {
+ /* find the maximum area that must be redisplayed */
+ if (lnum < buf->b_mod_top)
+ buf->b_mod_top = lnum;
+ if (lnum < buf->b_mod_bot) {
+ /* adjust old bot position for xtra lines */
+ buf->b_mod_bot += xtra;
+ if (buf->b_mod_bot < lnum)
+ buf->b_mod_bot = lnum;
+ }
+ if (lnume + xtra > buf->b_mod_bot)
+ buf->b_mod_bot = lnume + xtra;
+ buf->b_mod_xlines += xtra;
+ } else {
+ /* set the area that must be redisplayed */
+ buf->b_mod_set = TRUE;
+ buf->b_mod_top = lnum;
+ buf->b_mod_bot = lnume + xtra;
+ buf->b_mod_xlines = xtra;
+ }
+}
+
+/*
+ * Common code for when a change is was made.
+ * See changed_lines() for the arguments.
+ * Careful: may trigger autocommands that reload the buffer.
+ */
+static void changed_common(lnum, col, lnume, xtra)
+linenr_T lnum;
+colnr_T col;
+linenr_T lnume;
+long xtra;
+{
+ win_T *wp;
+ tabpage_T *tp;
+ int i;
+ int cols;
+ pos_T *p;
+ int add;
+
+ /* mark the buffer as modified */
+ changed();
+
+ /* set the '. mark */
+ if (!cmdmod.keepjumps) {
+ curbuf->b_last_change.lnum = lnum;
+ curbuf->b_last_change.col = col;
+
+ /* Create a new entry if a new undo-able change was started or we
+ * don't have an entry yet. */
+ if (curbuf->b_new_change || curbuf->b_changelistlen == 0) {
+ if (curbuf->b_changelistlen == 0)
+ add = TRUE;
+ else {
+ /* Don't create a new entry when the line number is the same
+ * as the last one and the column is not too far away. Avoids
+ * creating many entries for typing "xxxxx". */
+ p = &curbuf->b_changelist[curbuf->b_changelistlen - 1];
+ if (p->lnum != lnum)
+ add = TRUE;
+ else {
+ cols = comp_textwidth(FALSE);
+ if (cols == 0)
+ cols = 79;
+ add = (p->col + cols < col || col + cols < p->col);
+ }
+ }
+ if (add) {
+ /* This is the first of a new sequence of undo-able changes
+ * and it's at some distance of the last change. Use a new
+ * position in the changelist. */
+ curbuf->b_new_change = FALSE;
+
+ if (curbuf->b_changelistlen == JUMPLISTSIZE) {
+ /* changelist is full: remove oldest entry */
+ curbuf->b_changelistlen = JUMPLISTSIZE - 1;
+ mch_memmove(curbuf->b_changelist, curbuf->b_changelist + 1,
+ sizeof(pos_T) * (JUMPLISTSIZE - 1));
+ FOR_ALL_TAB_WINDOWS(tp, wp)
+ {
+ /* Correct position in changelist for other windows on
+ * this buffer. */
+ if (wp->w_buffer == curbuf && wp->w_changelistidx > 0)
+ --wp->w_changelistidx;
+ }
+ }
+ FOR_ALL_TAB_WINDOWS(tp, wp)
+ {
+ /* For other windows, if the position in the changelist is
+ * at the end it stays at the end. */
+ if (wp->w_buffer == curbuf
+ && wp->w_changelistidx == curbuf->b_changelistlen)
+ ++wp->w_changelistidx;
+ }
+ ++curbuf->b_changelistlen;
+ }
+ }
+ curbuf->b_changelist[curbuf->b_changelistlen - 1] =
+ curbuf->b_last_change;
+ /* The current window is always after the last change, so that "g,"
+ * takes you back to it. */
+ curwin->w_changelistidx = curbuf->b_changelistlen;
+ }
+
+ FOR_ALL_TAB_WINDOWS(tp, wp)
+ {
+ if (wp->w_buffer == curbuf) {
+ /* Mark this window to be redrawn later. */
+ if (wp->w_redr_type < VALID)
+ wp->w_redr_type = VALID;
+
+ /* Check if a change in the buffer has invalidated the cached
+ * values for the cursor. */
+ /*
+ * Update the folds for this window. Can't postpone this, because
+ * a following operator might work on the whole fold: ">>dd".
+ */
+ foldUpdate(wp, lnum, lnume + xtra - 1);
+
+ /* The change may cause lines above or below the change to become
+ * included in a fold. Set lnum/lnume to the first/last line that
+ * might be displayed differently.
+ * Set w_cline_folded here as an efficient way to update it when
+ * inserting lines just above a closed fold. */
+ i = hasFoldingWin(wp, lnum, &lnum, NULL, FALSE, NULL);
+ if (wp->w_cursor.lnum == lnum)
+ wp->w_cline_folded = i;
+ i = hasFoldingWin(wp, lnume, NULL, &lnume, FALSE, NULL);
+ if (wp->w_cursor.lnum == lnume)
+ wp->w_cline_folded = i;
+
+ /* If the changed line is in a range of previously folded lines,
+ * compare with the first line in that range. */
+ if (wp->w_cursor.lnum <= lnum) {
+ i = find_wl_entry(wp, lnum);
+ if (i >= 0 && wp->w_cursor.lnum > wp->w_lines[i].wl_lnum)
+ changed_line_abv_curs_win(wp);
+ }
+
+ if (wp->w_cursor.lnum > lnum)
+ changed_line_abv_curs_win(wp);
+ else if (wp->w_cursor.lnum == lnum && wp->w_cursor.col >= col)
+ changed_cline_bef_curs_win(wp);
+ if (wp->w_botline >= lnum) {
+ /* Assume that botline doesn't change (inserted lines make
+ * other lines scroll down below botline). */
+ approximate_botline_win(wp);
+ }
+
+ /* Check if any w_lines[] entries have become invalid.
+ * For entries below the change: Correct the lnums for
+ * inserted/deleted lines. Makes it possible to stop displaying
+ * after the change. */
+ for (i = 0; i < wp->w_lines_valid; ++i)
+ if (wp->w_lines[i].wl_valid) {
+ if (wp->w_lines[i].wl_lnum >= lnum) {
+ if (wp->w_lines[i].wl_lnum < lnume) {
+ /* line included in change */
+ wp->w_lines[i].wl_valid = FALSE;
+ } else if (xtra != 0) {
+ /* line below change */
+ wp->w_lines[i].wl_lnum += xtra;
+ wp->w_lines[i].wl_lastlnum += xtra;
+ }
+ } else if (wp->w_lines[i].wl_lastlnum >= lnum) {
+ /* change somewhere inside this range of folded lines,
+ * may need to be redrawn */
+ wp->w_lines[i].wl_valid = FALSE;
+ }
+ }
+
+ /* Take care of side effects for setting w_topline when folds have
+ * changed. Esp. when the buffer was changed in another window. */
+ if (hasAnyFolding(wp))
+ set_topline(wp, wp->w_topline);
+ }
+ }
+
+ /* Call update_screen() later, which checks out what needs to be redrawn,
+ * since it notices b_mod_set and then uses b_mod_*. */
+ if (must_redraw < VALID)
+ must_redraw = VALID;
+
+ /* when the cursor line is changed always trigger CursorMoved */
+ if (lnum <= curwin->w_cursor.lnum
+ && lnume + (xtra < 0 ? -xtra : xtra) > curwin->w_cursor.lnum)
+ last_cursormoved.lnum = 0;
+}
+
+/*
+ * unchanged() is called when the changed flag must be reset for buffer 'buf'
+ */
+void unchanged(buf, ff)
+buf_T *buf;
+int ff; /* also reset 'fileformat' */
+{
+ if (buf->b_changed || (ff && file_ff_differs(buf, FALSE))) {
+ buf->b_changed = 0;
+ ml_setflags(buf);
+ if (ff)
+ save_file_ff(buf);
+ check_status(buf);
+ redraw_tabline = TRUE;
+ need_maketitle = TRUE; /* set window title later */
+ }
+ ++buf->b_changedtick;
+}
+
+/*
+ * check_status: called when the status bars for the buffer 'buf'
+ * need to be updated
+ */
+void check_status(buf)
+buf_T *buf;
+{
+ win_T *wp;
+
+ for (wp = firstwin; wp != NULL; wp = wp->w_next)
+ if (wp->w_buffer == buf && wp->w_status_height) {
+ wp->w_redr_status = TRUE;
+ if (must_redraw < VALID)
+ must_redraw = VALID;
+ }
+}
+
+/*
+ * If the file is readonly, give a warning message with the first change.
+ * Don't do this for autocommands.
+ * Don't use emsg(), because it flushes the macro buffer.
+ * If we have undone all changes b_changed will be FALSE, but "b_did_warn"
+ * will be TRUE.
+ * Careful: may trigger autocommands that reload the buffer.
+ */
+void change_warning(col)
+int col; /* column for message; non-zero when in insert
+ mode and 'showmode' is on */
+{
+ static char *w_readonly = N_("W10: Warning: Changing a readonly file");
+
+ if (curbuf->b_did_warn == FALSE
+ && curbufIsChanged() == 0
+ && !autocmd_busy
+ && curbuf->b_p_ro) {
+ ++curbuf_lock;
+ apply_autocmds(EVENT_FILECHANGEDRO, NULL, NULL, FALSE, curbuf);
+ --curbuf_lock;
+ if (!curbuf->b_p_ro)
+ return;
+ /*
+ * Do what msg() does, but with a column offset if the warning should
+ * be after the mode message.
+ */
+ 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);
+ set_vim_var_string(VV_WARNINGMSG, (char_u *)_(w_readonly), -1);
+ msg_clr_eos();
+ (void)msg_end();
+ if (msg_silent == 0 && !silent_mode) {
+ out_flush();
+ ui_delay(1000L, TRUE); /* give the user time to think about it */
+ }
+ curbuf->b_did_warn = TRUE;
+ redraw_cmdline = FALSE; /* don't redraw and erase the message */
+ if (msg_row < Rows - 1)
+ showmode();
+ }
+}
+
+/*
+ * 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(str, direct)
+char_u *str;
+int direct;
+{
+ int r = ' ';
+ int save_State = State;
+
+ if (exiting) /* put terminal in raw mode for this question */
+ settmode(TMODE_RAW);
+ ++no_wait_return;
+#ifdef USE_ON_FLY_SCROLL
+ dont_scroll = TRUE; /* disallow scrolling here */
+#endif
+ State = CONFIRM; /* mouse behaves like with :confirm */
+ setmouse(); /* disables mouse for xterm */
+ ++no_mapping;
+ ++allow_keys; /* no mapping here, but recognize keys */
+
+ while (r != 'y' && r != 'n') {
+ /* same highlighting as for wait_return */
+ smsg_attr(hl_attr(HLF_R), (char_u *)"%s (y/n)?", str);
+ if (direct)
+ r = get_keystroke();
+ else
+ r = plain_vgetc();
+ if (r == Ctrl_C || r == ESC)
+ r = 'n';
+ msg_putchar(r); /* show what you typed */
+ out_flush();
+ }
+ --no_wait_return;
+ State = save_State;
+ setmouse();
+ --no_mapping;
+ --allow_keys;
+
+ return r;
+}
+
+/*
+ * Return TRUE if "c" is a mouse key.
+ */
+int is_mouse_key(c)
+int c;
+{
+ return c == K_LEFTMOUSE
+ || c == K_LEFTMOUSE_NM
+ || c == K_LEFTDRAG
+ || c == K_LEFTRELEASE
+ || c == K_LEFTRELEASE_NM
+ || c == K_MIDDLEMOUSE
+ || c == K_MIDDLEDRAG
+ || c == K_MIDDLERELEASE
+ || c == K_RIGHTMOUSE
+ || c == K_RIGHTDRAG
+ || c == K_RIGHTRELEASE
+ || c == K_MOUSEDOWN
+ || c == K_MOUSEUP
+ || c == K_MOUSELEFT
+ || c == K_MOUSERIGHT
+ || c == K_X1MOUSE
+ || c == K_X1DRAG
+ || c == K_X1RELEASE
+ || c == K_X2MOUSE
+ || c == K_X2DRAG
+ || c == K_X2RELEASE;
+}
+
+/*
+ * Get a key stroke directly from the user.
+ * Ignores mouse clicks and scrollbar events, except a click for the left
+ * button (used at the more prompt).
+ * Doesn't use vgetc(), because it syncs undo and eats mapped characters.
+ * Disadvantage: typeahead is ignored.
+ * Translates the interrupt character for unix to ESC.
+ */
+int get_keystroke() {
+ char_u *buf = NULL;
+ int buflen = 150;
+ int maxlen;
+ int len = 0;
+ int n;
+ int save_mapped_ctrl_c = mapped_ctrl_c;
+ int waited = 0;
+
+ mapped_ctrl_c = FALSE; /* mappings are not used here */
+ for (;; ) {
+ cursor_on();
+ out_flush();
+
+ /* Leave some room for check_termcode() to insert a key code into (max
+ * 5 chars plus NUL). And fix_input_buffer() can triple the number of
+ * bytes. */
+ maxlen = (buflen - 6 - len) / 3;
+ if (buf == NULL)
+ buf = alloc(buflen);
+ else if (maxlen < 10) {
+ /* Need some more space. This might happen when receiving a long
+ * escape sequence. */
+ buflen += 100;
+ buf = vim_realloc(buf, buflen);
+ maxlen = (buflen - 6 - len) / 3;
+ }
+ if (buf == NULL) {
+ do_outofmem_msg((long_u)buflen);
+ return ESC; /* panic! */
+ }
+
+ /* First time: blocking wait. Second time: wait up to 100ms for a
+ * terminal code to complete. */
+ n = ui_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);
+ len += n;
+ waited = 0;
+ } else if (len > 0)
+ ++waited; /* keep track of the waiting time */
+
+ /* Incomplete termcode and not timed out yet: get more characters */
+ if ((n = check_termcode(1, buf, buflen, &len)) < 0
+ && (!p_ttimeout || waited * 100L < (p_ttm < 0 ? p_tm : p_ttm)))
+ continue;
+
+ if (n == KEYLEN_REMOVED) { /* key code removed */
+ if (must_redraw != 0 && !need_wait_return && (State & CMDLINE) == 0) {
+ /* Redrawing was postponed, do it now. */
+ update_screen(0);
+ setcursor(); /* put cursor back where it belongs */
+ }
+ continue;
+ }
+ if (n > 0) /* found a termcode: adjust length */
+ len = n;
+ if (len == 0) /* nothing typed yet */
+ continue;
+
+ /* Handle modifier and/or special key code. */
+ n = buf[0];
+ if (n == K_SPECIAL) {
+ n = TO_SPECIAL(buf[1], buf[2]);
+ if (buf[1] == KS_MODIFIER
+ || n == K_IGNORE
+ || (is_mouse_key(n) && n != K_LEFTMOUSE)
+ ) {
+ if (buf[1] == KS_MODIFIER)
+ mod_mask = buf[2];
+ len -= 3;
+ if (len > 0)
+ mch_memmove(buf, buf + 3, (size_t)len);
+ continue;
+ }
+ 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);
+ }
+#ifdef UNIX
+ if (n == intr_char)
+ n = ESC;
+#endif
+ break;
+ }
+ vim_free(buf);
+
+ mapped_ctrl_c = save_mapped_ctrl_c;
+ return n;
+}
+
+/*
+ * Get a number from the user.
+ * When "mouse_used" is not NULL allow using the mouse.
+ */
+int get_number(colon, mouse_used)
+int colon; /* allow colon to abort */
+int *mouse_used;
+{
+ int n = 0;
+ int c;
+ int typed = 0;
+
+ if (mouse_used != NULL)
+ *mouse_used = FALSE;
+
+ /* When not printing messages, the user won't know what to type, return a
+ * zero (as if CR was hit). */
+ if (msg_silent != 0)
+ return 0;
+
+#ifdef USE_ON_FLY_SCROLL
+ dont_scroll = TRUE; /* disallow scrolling here */
+#endif
+ ++no_mapping;
+ ++allow_keys; /* no mapping here, but recognize keys */
+ for (;; ) {
+ windgoto(msg_row, msg_col);
+ c = safe_vgetc();
+ if (VIM_ISDIGIT(c)) {
+ n = n * 10 + c - '0';
+ msg_putchar(c);
+ ++typed;
+ } else if (c == K_DEL || c == K_KDEL || c == K_BS || c == Ctrl_H) {
+ if (typed > 0) {
+ MSG_PUTS("\b \b");
+ --typed;
+ }
+ n /= 10;
+ } else if (mouse_used != NULL && c == K_LEFTMOUSE) {
+ *mouse_used = TRUE;
+ n = mouse_row + 1;
+ break;
+ } else if (n == 0 && c == ':' && colon) {
+ stuffcharReadbuff(':');
+ if (!exmode_active)
+ cmdline_row = msg_row;
+ skip_redraw = TRUE; /* skip redraw once */
+ do_redraw = FALSE;
+ break;
+ } else if (c == CAR || c == NL || c == Ctrl_C || c == ESC)
+ break;
+ }
+ --no_mapping;
+ --allow_keys;
+ return n;
+}
+
+/*
+ * Ask the user to enter a number.
+ * When "mouse_used" is not NULL allow using the mouse and in that case return
+ * the line number.
+ */
+int prompt_for_number(mouse_used)
+int *mouse_used;
+{
+ int i;
+ int save_cmdline_row;
+ int save_State;
+
+ /* When using ":silent" assume that <CR> was entered. */
+ if (mouse_used != NULL)
+ MSG_PUTS(_("Type number and <Enter> or click with mouse (empty cancels): "));
+ else
+ MSG_PUTS(_("Type number and <Enter> (empty cancels): "));
+
+ /* Set the state such that text can be selected/copied/pasted and we still
+ * get mouse events. */
+ save_cmdline_row = cmdline_row;
+ cmdline_row = 0;
+ save_State = State;
+ State = CMDLINE;
+
+ i = get_number(TRUE, mouse_used);
+ if (KeyTyped) {
+ /* don't call wait_return() now */
+ /* msg_putchar('\n'); */
+ cmdline_row = msg_row - 1;
+ need_wait_return = FALSE;
+ msg_didany = FALSE;
+ msg_didout = FALSE;
+ } else
+ cmdline_row = save_cmdline_row;
+ State = save_State;
+
+ return i;
+}
+
+void msgmore(n)
+long n;
+{
+ long pn;
+
+ if (global_busy /* no messages now, wait until global is finished */
+ || !messaging()) /* 'lazyredraw' set, don't do messages now */
+ return;
+
+ /* We don't want to overwrite another important message, but do overwrite
+ * a previous "more lines" or "fewer lines" message, so that "5dd" and
+ * then "put" reports the last action. */
+ if (keep_msg != NULL && !keep_msg_more)
+ return;
+
+ if (n > 0)
+ pn = n;
+ else
+ pn = -n;
+
+ if (pn > p_report) {
+ if (pn == 1) {
+ if (n > 0)
+ vim_strncpy(msg_buf, (char_u *)_("1 more line"),
+ MSG_BUF_LEN - 1);
+ else
+ vim_strncpy(msg_buf, (char_u *)_("1 line less"),
+ MSG_BUF_LEN - 1);
+ } else {
+ if (n > 0)
+ vim_snprintf((char *)msg_buf, MSG_BUF_LEN,
+ _("%ld more lines"), pn);
+ else
+ vim_snprintf((char *)msg_buf, MSG_BUF_LEN,
+ _("%ld fewer lines"), pn);
+ }
+ if (got_int)
+ vim_strcat(msg_buf, (char_u *)_(" (Interrupted)"), MSG_BUF_LEN);
+ if (msg(msg_buf)) {
+ set_keep_msg(msg_buf, 0);
+ keep_msg_more = TRUE;
+ }
+ }
+}
+
+/*
+ * flush map and typeahead buffers and give a warning for an error
+ */
+void beep_flush() {
+ if (emsg_silent == 0) {
+ flush_buffers(FALSE);
+ vim_beep();
+ }
+}
+
+/*
+ * give a warning for an error
+ */
+void vim_beep() {
+ if (emsg_silent == 0) {
+ if (p_vb
+ ) {
+ out_str(T_VB);
+ } else {
+ out_char(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));
+ }
+ }
+}
+
+/*
+ * To get the "real" home directory:
+ * - get value of $HOME
+ * For Unix:
+ * - go to that directory
+ * - do mch_dirname() to get the real name of that directory.
+ * This also works with mounts and links.
+ * Don't do this for MS-DOS, it will change the "current dir" for a drive.
+ */
+static char_u *homedir = NULL;
+
+void init_homedir() {
+ char_u *var;
+
+ /* In case we are called a second time (when 'encoding' changes). */
+ vim_free(homedir);
+ homedir = NULL;
+
+ var = mch_getenv((char_u *)"HOME");
+
+ if (var != NULL && *var == NUL) /* empty is same as not set */
+ var = NULL;
+
+
+ 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 (mch_dirname(NameBuff, MAXPATHL) == OK
+ && mch_chdir((char *)NameBuff) == 0) {
+ if (!mch_chdir((char *)var) && mch_dirname(IObuff, IOSIZE) == OK)
+ var = IObuff;
+ if (mch_chdir((char *)NameBuff) != 0)
+ EMSG(_(e_prev_dir));
+ }
+#endif
+ homedir = vim_strsave(var);
+ }
+}
+
+#if defined(EXITFREE) || defined(PROTO)
+void free_homedir() {
+ vim_free(homedir);
+}
+
+void free_users() {
+ ga_clear_strings(&ga_users);
+}
+
+#endif
+
+/*
+ * Call expand_env() and store the result in an allocated string.
+ * This is not very memory efficient, this expects the result to be freed
+ * again soon.
+ */
+char_u * expand_env_save(src)
+char_u *src;
+{
+ return expand_env_save_opt(src, FALSE);
+}
+
+/*
+ * Idem, but when "one" is TRUE handle the string as one file name, only
+ * expand "~" at the start.
+ */
+char_u * expand_env_save_opt(src, one)
+char_u *src;
+int one;
+{
+ char_u *p;
+
+ p = alloc(MAXPATHL);
+ if (p != NULL)
+ expand_env_esc(src, p, MAXPATHL, FALSE, one, NULL);
+ return p;
+}
+
+/*
+ * Expand environment variable with path name.
+ * "~/" 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.
+ */
+void expand_env(src, dst, dstlen)
+char_u *src; /* input string e.g. "$HOME/vim.hlp" */
+char_u *dst; /* where to put the result */
+int dstlen; /* maximum length of the result */
+{
+ expand_env_esc(src, dst, dstlen, FALSE, FALSE, NULL);
+}
+
+void expand_env_esc(srcp, dst, dstlen, esc, one, startstr)
+char_u *srcp; /* input string e.g. "$HOME/vim.hlp" */
+char_u *dst; /* where to put the result */
+int dstlen; /* maximum length of the result */
+int esc; /* escape spaces in expanded variables */
+int one; /* "srcp" is one file name */
+char_u *startstr; /* start again after this (can be NULL) */
+{
+ char_u *src;
+ char_u *tail;
+ int c;
+ char_u *var;
+ int copy_char;
+ int mustfree; /* var was allocated, need to free it later */
+ int at_start = TRUE; /* at start of a name */
+ int startstr_len = 0;
+
+ if (startstr != NULL)
+ startstr_len = (int)STRLEN(startstr);
+
+ src = skipwhite(srcp);
+ --dstlen; /* leave one char space for "\," */
+ while (*src && dstlen > 0) {
+ copy_char = TRUE;
+ if ((*src == '$'
+ )
+ || (*src == '~' && at_start)) {
+ mustfree = FALSE;
+
+ /*
+ * The variable name is copied into dst temporarily, because it may
+ * be a string in read-only memory and a NUL needs to be appended.
+ */
+ if (*src != '~') { /* environment var */
+ tail = src + 1;
+ var = dst;
+ c = dstlen - 1;
+
+#ifdef UNIX
+ /* Unix has ${var-name} type environment vars */
+ if (*tail == '{' && !vim_isIDc('{')) {
+ tail++; /* ignore '{' */
+ while (c-- > 0 && *tail && *tail != '}')
+ *var++ = *tail++;
+ } else
+#endif
+ {
+ while (c-- > 0 && *tail != NUL && ((vim_isIDc(*tail))
+ )) {
+ *var++ = *tail++;
+ }
+ }
+
+#if defined(MSDOS) || defined(MSWIN) || defined(OS2) || defined(UNIX)
+# ifdef UNIX
+ if (src[1] == '{' && *tail != '}')
+# else
+ if (*src == '%' && *tail != '%')
+# endif
+ var = NULL;
+ else {
+# ifdef UNIX
+ if (src[1] == '{')
+# else
+ if (*src == '%')
+#endif
+ ++tail;
+#endif
+ *var = NUL;
+ var = vim_getenv(dst, &mustfree);
+#if defined(MSDOS) || defined(MSWIN) || defined(OS2) || defined(UNIX)
+ }
+#endif
+ }
+ /* home directory */
+ else if ( src[1] == NUL
+ || vim_ispathsep(src[1])
+ || vim_strchr((char_u *)" ,\t\n", src[1]) != NULL) {
+ var = homedir;
+ tail = src + 1;
+ } else { /* user directory */
+#if defined(UNIX) || (defined(VMS) && defined(USER_HOME))
+ /*
+ * Copy ~user to dst[], so we can put a NUL after it.
+ */
+ tail = src;
+ var = dst;
+ c = dstlen - 1;
+ while ( c-- > 0
+ && *tail
+ && vim_isfilec(*tail)
+ && !vim_ispathsep(*tail))
+ *var++ = *tail++;
+ *var = NUL;
+# ifdef UNIX
+ /*
+ * If the system supports getpwnam(), use it.
+ * Otherwise, or if getpwnam() 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).
+ */
+# if defined(HAVE_GETPWNAM) && defined(HAVE_PWD_H)
+ {
+ struct passwd *pw;
+
+ /* Note: memory allocated by getpwnam() is never freed.
+ * Calling endpwent() apparently doesn't help. */
+ pw = getpwnam((char *)dst + 1);
+ if (pw != NULL)
+ var = (char_u *)pw->pw_dir;
+ else
+ var = NULL;
+ }
+ if (var == NULL)
+# endif
+ {
+ expand_T xpc;
+
+ ExpandInit(&xpc);
+ xpc.xp_context = EXPAND_FILES;
+ var = ExpandOne(&xpc, dst, NULL,
+ WILD_ADD_SLASH|WILD_SILENT, WILD_EXPAND_FREE);
+ mustfree = TRUE;
+ }
+
+# else /* !UNIX, thus VMS */
+ /*
+ * USER_HOME is a comma-separated list of
+ * directories to search for the user account in.
+ */
+ {
+ char_u test[MAXPATHL], paths[MAXPATHL];
+ char_u *path, *next_path, *ptr;
+ struct stat st;
+
+ STRCPY(paths, USER_HOME);
+ next_path = paths;
+ while (*next_path) {
+ for (path = next_path; *next_path && *next_path != ',';
+ next_path++) ;
+ if (*next_path)
+ *next_path++ = NUL;
+ STRCPY(test, path);
+ STRCAT(test, "/");
+ STRCAT(test, dst + 1);
+ if (mch_stat(test, &st) == 0) {
+ var = alloc(STRLEN(test) + 1);
+ STRCPY(var, test);
+ mustfree = TRUE;
+ break;
+ }
+ }
+ }
+# endif /* UNIX */
+#else
+ /* cannot expand user's home directory, so don't try */
+ var = NULL;
+ tail = (char_u *)""; /* for gcc */
+#endif /* UNIX || VMS */
+ }
+
+#ifdef BACKSLASH_IN_FILENAME
+ /* If 'shellslash' is set change backslashes to forward slashes.
+ * Can't use slash_adjust(), p_ssl may be set temporarily. */
+ if (p_ssl && var != NULL && vim_strchr(var, '\\') != NULL) {
+ char_u *p = vim_strsave(var);
+
+ if (p != NULL) {
+ if (mustfree)
+ vim_free(var);
+ var = p;
+ mustfree = TRUE;
+ forward_slash(var);
+ }
+ }
+#endif
+
+ /* If "var" contains white space, escape it with a backslash.
+ * Required for ":e ~/tt" when $HOME includes a space. */
+ if (esc && var != NULL && vim_strpbrk(var, (char_u *)" \t") != NULL) {
+ char_u *p = vim_strsave_escaped(var, (char_u *)" \t");
+
+ if (p != NULL) {
+ if (mustfree)
+ vim_free(var);
+ var = p;
+ mustfree = TRUE;
+ }
+ }
+
+ if (var != NULL && *var != NUL
+ && (STRLEN(var) + STRLEN(tail) + 1 < (unsigned)dstlen)) {
+ STRCPY(dst, var);
+ dstlen -= (int)STRLEN(var);
+ c = (int)STRLEN(var);
+ /* if var[] ends in a path separator and tail[] starts
+ * with it, skip a character */
+ if (*var != NUL && after_pathsep(dst, dst + c)
+#if defined(BACKSLASH_IN_FILENAME) || defined(AMIGA)
+ && dst[-1] != ':'
+#endif
+ && vim_ispathsep(*tail))
+ ++tail;
+ dst += c;
+ src = tail;
+ copy_char = FALSE;
+ }
+ if (mustfree)
+ vim_free(var);
+ }
+
+ if (copy_char) { /* copy at least one char */
+ /*
+ * Recognize the start of a new name, for '~'.
+ * Don't do this when "one" is TRUE, to avoid expanding "~" in
+ * ":edit foo ~ foo".
+ */
+ at_start = FALSE;
+ if (src[0] == '\\' && src[1] != NUL) {
+ *dst++ = *src++;
+ --dstlen;
+ } else if ((src[0] == ' ' || src[0] == ',') && !one)
+ at_start = TRUE;
+ *dst++ = *src++;
+ --dstlen;
+
+ if (startstr != NULL && src - startstr_len >= srcp
+ && STRNCMP(src - startstr_len, startstr, startstr_len) == 0)
+ at_start = TRUE;
+ }
+ }
+ *dst = NUL;
+}
+
+/*
+ * Vim's version of getenv().
+ * Special handling of $HOME, $VIM and $VIMRUNTIME.
+ * Also does ACP to 'enc' conversion for Win32.
+ * "mustfree" is set to TRUE when returned is allocated, it must be
+ * initialized to FALSE by the caller.
+ */
+char_u * vim_getenv(name, mustfree)
+char_u *name;
+int *mustfree;
+{
+ char_u *p;
+ char_u *pend;
+ int vimruntime;
+
+
+ p = mch_getenv(name);
+ if (p != NULL && *p == NUL) /* empty is the same as not set */
+ p = NULL;
+
+ if (p != NULL) {
+ return p;
+ }
+
+ vimruntime = (STRCMP(name, "VIMRUNTIME") == 0);
+ if (!vimruntime && STRCMP(name, "VIM") != 0)
+ return NULL;
+
+ /*
+ * When expanding $VIMRUNTIME fails, try using $VIM/vim<version> or $VIM.
+ * Don't do this when default_vimruntime_dir is non-empty.
+ */
+ if (vimruntime
+#ifdef HAVE_PATHDEF
+ && *default_vimruntime_dir == NUL
+#endif
+ ) {
+ p = mch_getenv((char_u *)"VIM");
+ if (p != NULL && *p == NUL) /* empty is the same as not set */
+ p = NULL;
+ if (p != NULL) {
+ p = vim_version_dir(p);
+ if (p != NULL)
+ *mustfree = TRUE;
+ else
+ p = mch_getenv((char_u *)"VIM");
+
+ }
+ }
+
+ /*
+ * When expanding $VIM or $VIMRUNTIME fails, try using:
+ * - the directory name from 'helpfile' (unless it contains '$')
+ * - the executable name from argv[0]
+ */
+ if (p == NULL) {
+ if (p_hf != NULL && vim_strchr(p_hf, '$') == NULL)
+ p = p_hf;
+#ifdef USE_EXE_NAME
+ /*
+ * Use the name of the executable, obtained from argv[0].
+ */
+ else
+ p = exe_name;
+#endif
+ if (p != NULL) {
+ /* remove the file name */
+ pend = gettail(p);
+
+ /* remove "doc/" from 'helpfile', if present */
+ if (p == p_hf)
+ pend = remove_tail(p, pend, (char_u *)"doc");
+
+#ifdef USE_EXE_NAME
+ /* remove "src/" from exe_name, if present */
+ if (p == exe_name)
+ pend = remove_tail(p, pend, (char_u *)"src");
+#endif
+
+ /* for $VIM, remove "runtime/" or "vim54/", if present */
+ if (!vimruntime) {
+ pend = remove_tail(p, pend, (char_u *)RUNTIME_DIRNAME);
+ pend = remove_tail(p, pend, (char_u *)VIM_VERSION_NODOT);
+ }
+
+ /* remove trailing path separator */
+ /* With MacOS path (with colons) the final colon is required */
+ /* to avoid confusion between absolute and relative path */
+ if (pend > p && after_pathsep(p, pend))
+ --pend;
+
+ /* check that the result is a directory name */
+ p = vim_strnsave(p, (int)(pend - p));
+
+ if (p != NULL && !mch_isdir(p)) {
+ vim_free(p);
+ p = NULL;
+ } else {
+#ifdef USE_EXE_NAME
+ /* may add "/vim54" or "/runtime" if it exists */
+ if (vimruntime && (pend = vim_version_dir(p)) != NULL) {
+ vim_free(p);
+ p = pend;
+ }
+#endif
+ *mustfree = TRUE;
+ }
+ }
+ }
+
+#ifdef HAVE_PATHDEF
+ /* When there is a pathdef.c file we can use default_vim_dir and
+ * default_vimruntime_dir */
+ if (p == NULL) {
+ /* Only use default_vimruntime_dir when it is not empty */
+ if (vimruntime && *default_vimruntime_dir != NUL) {
+ p = default_vimruntime_dir;
+ *mustfree = FALSE;
+ } else if (*default_vim_dir != NUL) {
+ if (vimruntime && (p = vim_version_dir(default_vim_dir)) != NULL)
+ *mustfree = TRUE;
+ else {
+ p = default_vim_dir;
+ *mustfree = FALSE;
+ }
+ }
+ }
+#endif
+
+ /*
+ * Set the environment variable, so that the new value can be found fast
+ * next time, and others can also use it (e.g. Perl).
+ */
+ if (p != NULL) {
+ if (vimruntime) {
+ vim_setenv((char_u *)"VIMRUNTIME", p);
+ didset_vimruntime = TRUE;
+ } else {
+ vim_setenv((char_u *)"VIM", p);
+ didset_vim = TRUE;
+ }
+ }
+ return p;
+}
+
+/*
+ * Check if the directory "vimdir/<version>" or "vimdir/runtime" exists.
+ * Return NULL if not, return its name in allocated memory otherwise.
+ */
+static char_u * vim_version_dir(vimdir)
+char_u *vimdir;
+{
+ char_u *p;
+
+ if (vimdir == NULL || *vimdir == NUL)
+ return NULL;
+ p = concat_fnames(vimdir, (char_u *)VIM_VERSION_NODOT, TRUE);
+ if (p != NULL && mch_isdir(p))
+ return p;
+ vim_free(p);
+ p = concat_fnames(vimdir, (char_u *)RUNTIME_DIRNAME, TRUE);
+ if (p != NULL && mch_isdir(p))
+ return p;
+ vim_free(p);
+ return NULL;
+}
+
+/*
+ * If the string between "p" and "pend" ends in "name/", return "pend" minus
+ * the length of "name/". Otherwise return "pend".
+ */
+static char_u * remove_tail(p, pend, name)
+char_u *p;
+char_u *pend;
+char_u *name;
+{
+ int len = (int)STRLEN(name) + 1;
+ char_u *newend = pend - len;
+
+ if (newend >= p
+ && fnamencmp(newend, name, len - 1) == 0
+ && (newend == p || after_pathsep(p, newend)))
+ return newend;
+ return pend;
+}
+
+/*
+ * Our portable version of setenv.
+ */
+void vim_setenv(name, val)
+char_u *name;
+char_u *val;
+{
+#ifdef HAVE_SETENV
+ mch_setenv((char *)name, (char *)val, 1);
+#else
+ char_u *envbuf;
+
+ /*
+ * Putenv does not copy the string, it has to remain
+ * valid. The allocated memory will never be freed.
+ */
+ envbuf = alloc((unsigned)(STRLEN(name) + STRLEN(val) + 2));
+ if (envbuf != NULL) {
+ sprintf((char *)envbuf, "%s=%s", name, val);
+ putenv((char *)envbuf);
+ }
+#endif
+ /*
+ * When setting $VIMRUNTIME adjust the directory to find message
+ * translations to $VIMRUNTIME/lang.
+ */
+ if (*val != NUL && STRICMP(name, "VIMRUNTIME") == 0) {
+ char_u *buf = concat_str(val, (char_u *)"/lang");
+
+ if (buf != NULL) {
+ bindtextdomain(VIMPACKAGE, (char *)buf);
+ vim_free(buf);
+ }
+ }
+}
+
+/*
+ * Function given to ExpandGeneric() to obtain an environment variable name.
+ */
+char_u * get_env_name(xp, idx)
+expand_T *xp UNUSED;
+int idx;
+{
+# if defined(AMIGA) || defined(__MRC__) || defined(__SC__)
+ /*
+ * No environ[] on the Amiga and on the Mac (using MPW).
+ */
+ return NULL;
+# else
+# ifndef __WIN32__
+ /* Borland C++ 5.2 has this in a header file. */
+ extern char **environ;
+# endif
+# define ENVNAMELEN 100
+ static char_u name[ENVNAMELEN];
+ char_u *str;
+ int n;
+
+ str = (char_u *)environ[idx];
+ if (str == NULL)
+ return NULL;
+
+ for (n = 0; n < ENVNAMELEN - 1; ++n) {
+ if (str[n] == '=' || str[n] == NUL)
+ break;
+ name[n] = str[n];
+ }
+ name[n] = NUL;
+ return name;
+# endif
+}
+
+/*
+ * Find all user names for user completion.
+ * Done only once and then cached.
+ */
+static void init_users() {
+ static int lazy_init_done = FALSE;
+
+ if (lazy_init_done)
+ return;
+
+ lazy_init_done = TRUE;
+ ga_init2(&ga_users, sizeof(char_u *), 20);
+
+# if defined(HAVE_GETPWENT) && defined(HAVE_PWD_H)
+ {
+ char_u* user;
+ struct passwd* pw;
+
+ setpwent();
+ while ((pw = getpwent()) != NULL)
+ /* pw->pw_name shouldn't be NULL but just in case... */
+ if (pw->pw_name != NULL) {
+ if (ga_grow(&ga_users, 1) == FAIL)
+ break;
+ user = vim_strsave((char_u*)pw->pw_name);
+ if (user == NULL)
+ break;
+ ((char_u **)(ga_users.ga_data))[ga_users.ga_len++] = user;
+ }
+ endpwent();
+ }
+# endif
+}
+
+/*
+ * Function given to ExpandGeneric() to obtain an user names.
+ */
+char_u* get_users(xp, idx)
+expand_T *xp UNUSED;
+int idx;
+{
+ init_users();
+ if (idx < ga_users.ga_len)
+ return ((char_u **)ga_users.ga_data)[idx];
+ return NULL;
+}
+
+/*
+ * Check whether name matches a user name. Return:
+ * 0 if name does not match any user name.
+ * 1 if name partially matches the beginning of a user name.
+ * 2 is name fully matches a user name.
+ */
+int match_user(name)
+char_u* name;
+{
+ int i;
+ int n = (int)STRLEN(name);
+ int result = 0;
+
+ init_users();
+ for (i = 0; i < ga_users.ga_len; i++) {
+ if (STRCMP(((char_u **)ga_users.ga_data)[i], name) == 0)
+ return 2; /* full match */
+ if (STRNCMP(((char_u **)ga_users.ga_data)[i], name, n) == 0)
+ result = 1; /* partial match */
+ }
+ return result;
+}
+
+/*
+ * Replace home directory by "~" in each space or comma separated file name in
+ * 'src'.
+ * If anything fails (except when out of space) dst equals src.
+ */
+void home_replace(buf, src, dst, dstlen, one)
+buf_T *buf; /* when not NULL, check for help files */
+char_u *src; /* input file name */
+char_u *dst; /* where to put the result */
+int dstlen; /* maximum length of the result */
+int one; /* if TRUE, only replace one file name, include
+ spaces and commas in the file name. */
+{
+ size_t dirlen = 0, envlen = 0;
+ size_t len;
+ char_u *homedir_env, *homedir_env_orig;
+ char_u *p;
+
+ if (src == NULL) {
+ *dst = NUL;
+ return;
+ }
+
+ /*
+ * If the file is a help file, remove the path completely.
+ */
+ if (buf != NULL && buf->b_help) {
+ STRCPY(dst, gettail(src));
+ return;
+ }
+
+ /*
+ * We check both the value of the $HOME environment variable and the
+ * "real" home directory.
+ */
+ if (homedir != NULL)
+ dirlen = STRLEN(homedir);
+
+ homedir_env_orig = homedir_env = mch_getenv((char_u *)"HOME");
+ /* Empty is the same as not set. */
+ if (homedir_env != NULL && *homedir_env == NUL)
+ homedir_env = NULL;
+
+ if (homedir_env != NULL && vim_strchr(homedir_env, '~') != NULL) {
+ int usedlen = 0;
+ int flen;
+ char_u *fbuf = NULL;
+
+ flen = (int)STRLEN(homedir_env);
+ (void)modify_fname((char_u *)":p", &usedlen,
+ &homedir_env, &fbuf, &flen);
+ flen = (int)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;
+ }
+
+ if (homedir_env != NULL)
+ envlen = STRLEN(homedir_env);
+
+ if (!one)
+ src = skipwhite(src);
+ 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)).
+ */
+ p = homedir;
+ len = dirlen;
+ for (;; ) {
+ if ( len
+ && fnamencmp(src, 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++ = '/';
+ break;
+ }
+ if (p == homedir_env)
+ break;
+ p = homedir_env;
+ 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 (dstlen == 0) out of space, what to do??? */
+
+ *dst = NUL;
+
+ if (homedir_env != homedir_env_orig)
+ vim_free(homedir_env);
+}
+
+/*
+ * Like home_replace, store the replaced string in allocated memory.
+ * When something fails, NULL is returned.
+ */
+char_u * home_replace_save(buf, src)
+buf_T *buf; /* when not NULL, check for help files */
+char_u *src; /* input file name */
+{
+ char_u *dst;
+ unsigned len;
+
+ len = 3; /* space for "~/" and trailing NUL */
+ if (src != NULL) /* just in case */
+ len += (unsigned)STRLEN(src);
+ dst = alloc(len);
+ if (dst != NULL)
+ home_replace(buf, src, dst, len, TRUE);
+ return dst;
+}
+
+/*
+ * Compare two file names and return:
+ * FPC_SAME if they both exist and are the same file.
+ * FPC_SAMEX if they both don't exist and have the same file name.
+ * FPC_DIFF if they both exist and are different files.
+ * FPC_NOTX if they both don't exist.
+ * FPC_DIFFX if one of them doesn't exist.
+ * For the first name environment variables are expanded
+ */
+int fullpathcmp(s1, s2, checkname)
+char_u *s1, *s2;
+int checkname; /* when both don't exist, check file names */
+{
+#ifdef UNIX
+ char_u exp1[MAXPATHL];
+ char_u full1[MAXPATHL];
+ char_u full2[MAXPATHL];
+ struct stat st1, st2;
+ int r1, r2;
+
+ expand_env(s1, exp1, MAXPATHL);
+ r1 = mch_stat((char *)exp1, &st1);
+ r2 = mch_stat((char *)s2, &st2);
+ if (r1 != 0 && r2 != 0) {
+ /* if mch_stat() doesn't work, may compare the names */
+ if (checkname) {
+ if (fnamecmp(exp1, s2) == 0)
+ return FPC_SAMEX;
+ r1 = vim_FullName(exp1, full1, MAXPATHL, FALSE);
+ r2 = vim_FullName(s2, full2, MAXPATHL, FALSE);
+ if (r1 == OK && r2 == OK && fnamecmp(full1, full2) == 0)
+ return FPC_SAMEX;
+ }
+ return FPC_NOTX;
+ }
+ if (r1 != 0 || r2 != 0)
+ return FPC_DIFFX;
+ if (st1.st_dev == st2.st_dev && st1.st_ino == st2.st_ino)
+ return FPC_SAME;
+ return FPC_DIFF;
+#else
+ char_u *exp1; /* expanded s1 */
+ char_u *full1; /* full path of s1 */
+ char_u *full2; /* full path of s2 */
+ int retval = FPC_DIFF;
+ int r1, r2;
+
+ /* allocate one buffer to store three paths (alloc()/free() is slow!) */
+ if ((exp1 = alloc(MAXPATHL * 3)) != NULL) {
+ full1 = exp1 + MAXPATHL;
+ full2 = full1 + MAXPATHL;
+
+ expand_env(s1, exp1, MAXPATHL);
+ r1 = vim_FullName(exp1, full1, MAXPATHL, FALSE);
+ r2 = vim_FullName(s2, full2, MAXPATHL, FALSE);
+
+ /* If vim_FullName() fails, the file probably doesn't exist. */
+ if (r1 != OK && r2 != OK) {
+ if (checkname && fnamecmp(exp1, s2) == 0)
+ retval = FPC_SAMEX;
+ else
+ retval = FPC_NOTX;
+ } else if (r1 != OK || r2 != OK)
+ retval = FPC_DIFFX;
+ else if (fnamecmp(full1, full2))
+ retval = FPC_DIFF;
+ else
+ retval = FPC_SAME;
+ vim_free(exp1);
+ }
+ return retval;
+#endif
+}
+
+/*
+ * Get the tail of a path: the file name.
+ * When the path ends in a path separator the tail is the NUL after it.
+ * Fail safe: never returns NULL.
+ */
+char_u * gettail(fname)
+char_u *fname;
+{
+ char_u *p1, *p2;
+
+ if (fname == NULL)
+ return (char_u *)"";
+ for (p1 = p2 = get_past_head(fname); *p2; ) { /* find last part of path */
+ if (vim_ispathsep_nocolon(*p2))
+ p1 = p2 + 1;
+ mb_ptr_adv(p2);
+ }
+ return p1;
+}
+
+static char_u *gettail_dir __ARGS((char_u *fname));
+
+/*
+ * Return the end of the directory name, on the first path
+ * separator:
+ * "/path/file", "/path/dir/", "/path//dir", "/file"
+ * ^ ^ ^ ^
+ */
+static char_u * gettail_dir(fname)
+char_u *fname;
+{
+ char_u *dir_end = fname;
+ char_u *next_dir_end = fname;
+ int look_for_sep = TRUE;
+ char_u *p;
+
+ for (p = fname; *p != NUL; ) {
+ if (vim_ispathsep(*p)) {
+ if (look_for_sep) {
+ next_dir_end = p;
+ look_for_sep = FALSE;
+ }
+ } else {
+ if (!look_for_sep)
+ dir_end = next_dir_end;
+ look_for_sep = TRUE;
+ }
+ mb_ptr_adv(p);
+ }
+ return dir_end;
+}
+
+/*
+ * Get pointer to tail of "fname", including path separators. Putting a NUL
+ * here leaves the directory name. Takes care of "c:/" and "//".
+ * Always returns a valid pointer.
+ */
+char_u * gettail_sep(fname)
+char_u *fname;
+{
+ char_u *p;
+ char_u *t;
+
+ p = get_past_head(fname); /* don't remove the '/' from "c:/file" */
+ t = gettail(fname);
+ while (t > p && after_pathsep(fname, t))
+ --t;
+ return t;
+}
+
+/*
+ * get the next path component (just after the next path separator).
+ */
+char_u * getnextcomp(fname)
+char_u *fname;
+{
+ while (*fname && !vim_ispathsep(*fname))
+ mb_ptr_adv(fname);
+ if (*fname)
+ ++fname;
+ return fname;
+}
+
+/*
+ * Get a pointer to one character past the head of a path name.
+ * Unix: after "/"; DOS: after "c:\"; Amiga: after "disk:/"; Mac: no head.
+ * If there is no head, path is returned.
+ */
+char_u * get_past_head(path)
+char_u *path;
+{
+ char_u *retval;
+
+ retval = path;
+
+ while (vim_ispathsep(*retval))
+ ++retval;
+
+ return retval;
+}
+
+/*
+ * Return TRUE if 'c' is a path separator.
+ * Note that for MS-Windows this includes the colon.
+ */
+int vim_ispathsep(c)
+int c;
+{
+#ifdef UNIX
+ return c == '/'; /* UNIX has ':' inside file names */
+#else
+# ifdef BACKSLASH_IN_FILENAME
+ return c == ':' || c == '/' || c == '\\';
+# else
+ return c == ':' || c == '/';
+# endif
+#endif
+}
+
+/*
+ * Like vim_ispathsep(c), but exclude the colon for MS-Windows.
+ */
+int vim_ispathsep_nocolon(c)
+int c;
+{
+ return vim_ispathsep(c)
+#ifdef BACKSLASH_IN_FILENAME
+ && c != ':'
+#endif
+ ;
+}
+
+/*
+ * return TRUE if 'c' is a path list separator.
+ */
+int vim_ispathlistsep(c)
+int c;
+{
+#ifdef UNIX
+ return c == ':';
+#else
+ return c == ';'; /* might not be right for every system... */
+#endif
+}
+
+#if defined(FEAT_GUI_TABLINE) || defined(FEAT_WINDOWS) \
+ || defined(FEAT_EVAL) || defined(PROTO)
+/*
+ * Shorten the path of a file from "~/foo/../.bar/fname" to "~/f/../.b/fname"
+ * It's done in-place.
+ */
+void shorten_dir(str)
+char_u *str;
+{
+ char_u *tail, *s, *d;
+ int skip = FALSE;
+
+ tail = gettail(str);
+ d = str;
+ for (s = str;; ++s) {
+ if (s >= tail) { /* copy the whole tail */
+ *d++ = *s;
+ if (*s == NUL)
+ break;
+ } else if (vim_ispathsep(*s)) { /* copy '/' and next char */
+ *d++ = *s;
+ skip = FALSE;
+ } else if (!skip) {
+ *d++ = *s; /* copy next char */
+ if (*s != '~' && *s != '.') /* and leading "~" and "." */
+ skip = TRUE;
+ if (has_mbyte) {
+ int l = mb_ptr2len(s);
+
+ while (--l > 0)
+ *d++ = *++s;
+ }
+ }
+ }
+}
+#endif
+
+/*
+ * Return TRUE if the directory of "fname" exists, FALSE otherwise.
+ * Also returns TRUE if there is no directory name.
+ * "fname" must be writable!.
+ */
+int dir_of_file_exists(fname)
+char_u *fname;
+{
+ char_u *p;
+ int c;
+ int retval;
+
+ p = gettail_sep(fname);
+ if (p == fname)
+ return TRUE;
+ c = *p;
+ *p = NUL;
+ retval = mch_isdir(fname);
+ *p = c;
+ return retval;
+}
+
+/*
+ * Versions of fnamecmp() and fnamencmp() that handle '/' and '\' equally
+ * and deal with 'fileignorecase'.
+ */
+int vim_fnamecmp(x, y)
+char_u *x, *y;
+{
+#ifdef BACKSLASH_IN_FILENAME
+ return vim_fnamencmp(x, y, MAXPATHL);
+#else
+ if (p_fic)
+ return MB_STRICMP(x, y);
+ return STRCMP(x, y);
+#endif
+}
+
+int vim_fnamencmp(x, y, len)
+char_u *x, *y;
+size_t len;
+{
+#ifdef BACKSLASH_IN_FILENAME
+ char_u *px = x;
+ char_u *py = y;
+ int cx = NUL;
+ int cy = NUL;
+
+ while (len > 0) {
+ cx = PTR2CHAR(px);
+ cy = PTR2CHAR(py);
+ if (cx == NUL || cy == NUL
+ || ((p_fic ? MB_TOLOWER(cx) != MB_TOLOWER(cy) : cx != cy)
+ && !(cx == '/' && cy == '\\')
+ && !(cx == '\\' && cy == '/')))
+ break;
+ len -= MB_PTR2LEN(px);
+ px += MB_PTR2LEN(px);
+ py += MB_PTR2LEN(py);
+ }
+ if (len == 0)
+ return 0;
+ return cx - cy;
+#else
+ if (p_fic)
+ return MB_STRNICMP(x, y, len);
+ return STRNCMP(x, y, len);
+#endif
+}
+
+/*
+ * Concatenate file names fname1 and fname2 into allocated memory.
+ * Only add a '/' or '\\' when 'sep' is TRUE and it is necessary.
+ */
+char_u * concat_fnames(fname1, fname2, sep)
+char_u *fname1;
+char_u *fname2;
+int sep;
+{
+ char_u *dest;
+
+ dest = alloc((unsigned)(STRLEN(fname1) + STRLEN(fname2) + 3));
+ if (dest != NULL) {
+ STRCPY(dest, fname1);
+ if (sep)
+ add_pathsep(dest);
+ STRCAT(dest, fname2);
+ }
+ return dest;
+}
+
+/*
+ * Concatenate two strings and return the result in allocated memory.
+ * Returns NULL when out of memory.
+ */
+char_u * concat_str(str1, str2)
+char_u *str1;
+char_u *str2;
+{
+ char_u *dest;
+ size_t l = STRLEN(str1);
+
+ dest = alloc((unsigned)(l + STRLEN(str2) + 1L));
+ if (dest != NULL) {
+ STRCPY(dest, str1);
+ STRCPY(dest + l, str2);
+ }
+ return dest;
+}
+
+/*
+ * Add a path separator to a file name, unless it already ends in a path
+ * separator.
+ */
+void add_pathsep(p)
+char_u *p;
+{
+ if (*p != NUL && !after_pathsep(p, p + STRLEN(p)))
+ STRCAT(p, PATHSEPSTR);
+}
+
+/*
+ * FullName_save - Make an allocated copy of a full file name.
+ * Returns NULL when out of memory.
+ */
+char_u * FullName_save(fname, force)
+char_u *fname;
+int force; /* force expansion, even when it already looks
+ * like a full path name */
+{
+ char_u *buf;
+ char_u *new_fname = NULL;
+
+ if (fname == NULL)
+ return NULL;
+
+ buf = alloc((unsigned)MAXPATHL);
+ if (buf != NULL) {
+ if (vim_FullName(fname, buf, MAXPATHL, force) != FAIL)
+ new_fname = vim_strsave(buf);
+ else
+ new_fname = vim_strsave(fname);
+ vim_free(buf);
+ }
+ return new_fname;
+}
+
+
+static char_u *skip_string __ARGS((char_u *p));
+static pos_T *ind_find_start_comment __ARGS((void));
+
+/*
+ * Find the start of a comment, not knowing if we are in a comment right now.
+ * Search starts at w_cursor.lnum and goes backwards.
+ */
+static pos_T * ind_find_start_comment() { /* XXX */
+ return find_start_comment(curbuf->b_ind_maxcomment);
+}
+
+pos_T * find_start_comment(ind_maxcomment) /* XXX */
+int ind_maxcomment;
+{
+ pos_T *pos;
+ char_u *line;
+ char_u *p;
+ int cur_maxcomment = ind_maxcomment;
+
+ for (;; ) {
+ pos = findmatchlimit(NULL, '*', FM_BACKWARD, cur_maxcomment);
+ if (pos == NULL)
+ break;
+
+ /*
+ * Check if the comment start we found is inside a string.
+ * If it is then restrict the search to below this line and try again.
+ */
+ line = ml_get(pos->lnum);
+ for (p = line; *p && (colnr_T)(p - line) < pos->col; ++p)
+ p = skip_string(p);
+ if ((colnr_T)(p - line) <= pos->col)
+ break;
+ cur_maxcomment = curwin->w_cursor.lnum - pos->lnum - 1;
+ if (cur_maxcomment <= 0) {
+ pos = NULL;
+ break;
+ }
+ }
+ return pos;
+}
+
+/*
+ * Skip to the end of a "string" and a 'c' character.
+ * If there is no string or character, return argument unmodified.
+ */
+static char_u * skip_string(p)
+char_u *p;
+{
+ int i;
+
+ /*
+ * We loop, because strings may be concatenated: "date""time".
+ */
+ for (;; ++p) {
+ if (p[0] == '\'') { /* 'c' or '\n' or '\000' */
+ if (!p[1]) /* ' at end of line */
+ break;
+ i = 2;
+ if (p[1] == '\\') { /* '\n' or '\000' */
+ ++i;
+ while (vim_isdigit(p[i - 1])) /* '\000' */
+ ++i;
+ }
+ if (p[i] == '\'') { /* check for trailing ' */
+ p += i;
+ continue;
+ }
+ } else if (p[0] == '"') { /* start of string */
+ for (++p; p[0]; ++p) {
+ if (p[0] == '\\' && p[1] != NUL)
+ ++p;
+ else if (p[0] == '"') /* end of string */
+ break;
+ }
+ if (p[0] == '"')
+ continue;
+ }
+ break; /* no string found */
+ }
+ if (!*p)
+ --p; /* backup from NUL */
+ return p;
+}
+
+
+/*
+ * Do C or expression indenting on the current line.
+ */
+void do_c_expr_indent() {
+ if (*curbuf->b_p_inde != NUL)
+ fixthisline(get_expr_indent);
+ else
+ fixthisline(get_c_indent);
+}
+
+/*
+ * Functions for C-indenting.
+ * Most of this originally comes from Eric Fischer.
+ */
+/*
+ * Below "XXX" means that this function may unlock the current line.
+ */
+
+static char_u *cin_skipcomment __ARGS((char_u *));
+static int cin_nocode __ARGS((char_u *));
+static pos_T *find_line_comment __ARGS((void));
+static int cin_islabel_skip __ARGS((char_u **));
+static int cin_isdefault __ARGS((char_u *));
+static char_u *after_label __ARGS((char_u *l));
+static int get_indent_nolabel __ARGS((linenr_T lnum));
+static int skip_label __ARGS((linenr_T, char_u **pp));
+static int cin_first_id_amount __ARGS((void));
+static int cin_get_equal_amount __ARGS((linenr_T lnum));
+static int cin_ispreproc __ARGS((char_u *));
+static int cin_ispreproc_cont __ARGS((char_u **pp, linenr_T *lnump));
+static int cin_iscomment __ARGS((char_u *));
+static int cin_islinecomment __ARGS((char_u *));
+static int cin_isterminated __ARGS((char_u *, int, int));
+static int cin_isinit __ARGS((void));
+static int cin_isfuncdecl __ARGS((char_u **, linenr_T, linenr_T));
+static int cin_isif __ARGS((char_u *));
+static int cin_iselse __ARGS((char_u *));
+static int cin_isdo __ARGS((char_u *));
+static int cin_iswhileofdo __ARGS((char_u *, linenr_T));
+static int cin_is_if_for_while_before_offset __ARGS((char_u *line, int *poffset));
+static int cin_iswhileofdo_end __ARGS((int terminated));
+static int cin_isbreak __ARGS((char_u *));
+static int cin_is_cpp_baseclass __ARGS((colnr_T *col));
+static int get_baseclass_amount __ARGS((int col));
+static int cin_ends_in __ARGS((char_u *, char_u *, char_u *));
+static int cin_starts_with __ARGS((char_u *s, char *word));
+static int cin_skip2pos __ARGS((pos_T *trypos));
+static pos_T *find_start_brace __ARGS((void));
+static pos_T *find_match_paren __ARGS((int));
+static int corr_ind_maxparen __ARGS((pos_T *startpos));
+static int find_last_paren __ARGS((char_u *l, int start, int end));
+static int find_match __ARGS((int lookfor, linenr_T ourscope));
+static int cin_is_cpp_namespace __ARGS((char_u *));
+
+/*
+ * Skip over white space and C comments within the line.
+ * Also skip over Perl/shell comments if desired.
+ */
+static char_u * cin_skipcomment(s)
+char_u *s;
+{
+ while (*s) {
+ char_u *prev_s = s;
+
+ s = skipwhite(s);
+
+ /* Perl/shell # comment comment continues until eol. Require a space
+ * before # to avoid recognizing $#array. */
+ if (curbuf->b_ind_hash_comment != 0 && s != prev_s && *s == '#') {
+ s += STRLEN(s);
+ break;
+ }
+ if (*s != '/')
+ break;
+ ++s;
+ if (*s == '/') { /* slash-slash comment continues till eol */
+ s += STRLEN(s);
+ break;
+ }
+ if (*s != '*')
+ break;
+ for (++s; *s; ++s) /* skip slash-star comment */
+ if (s[0] == '*' && s[1] == '/') {
+ s += 2;
+ break;
+ }
+ }
+ return s;
+}
+
+/*
+ * Return TRUE if there is no code at *s. White space and comments are
+ * not considered code.
+ */
+static int cin_nocode(s)
+char_u *s;
+{
+ return *cin_skipcomment(s) == NUL;
+}
+
+/*
+ * Check previous lines for a "//" line comment, skipping over blank lines.
+ */
+static pos_T * find_line_comment() { /* XXX */
+ static pos_T pos;
+ char_u *line;
+ char_u *p;
+
+ pos = curwin->w_cursor;
+ while (--pos.lnum > 0) {
+ line = ml_get(pos.lnum);
+ p = skipwhite(line);
+ if (cin_islinecomment(p)) {
+ pos.col = (int)(p - line);
+ return &pos;
+ }
+ if (*p != NUL)
+ break;
+ }
+ return NULL;
+}
+
+/*
+ * Check if string matches "label:"; move to character after ':' if true.
+ */
+static int cin_islabel_skip(s)
+char_u **s;
+{
+ if (!vim_isIDc(**s)) /* need at least one ID character */
+ return FALSE;
+
+ while (vim_isIDc(**s))
+ (*s)++;
+
+ *s = cin_skipcomment(*s);
+
+ /* "::" is not a label, it's C++ */
+ return **s == ':' && *++*s != ':';
+}
+
+/*
+ * Recognize a label: "label:".
+ * Note: curwin->w_cursor must be where we are looking for the label.
+ */
+int cin_islabel() { /* XXX */
+ char_u *s;
+
+ s = cin_skipcomment(ml_get_curline());
+
+ /*
+ * Exclude "default" from labels, since it should be indented
+ * like a switch label. Same for C++ scope declarations.
+ */
+ if (cin_isdefault(s))
+ return FALSE;
+ if (cin_isscopedecl(s))
+ return FALSE;
+
+ if (cin_islabel_skip(&s)) {
+ /*
+ * Only accept a label if the previous line is terminated or is a case
+ * label.
+ */
+ pos_T cursor_save;
+ pos_T *trypos;
+ char_u *line;
+
+ cursor_save = curwin->w_cursor;
+ while (curwin->w_cursor.lnum > 1) {
+ --curwin->w_cursor.lnum;
+
+ /*
+ * If we're in a comment now, skip to the start of the comment.
+ */
+ curwin->w_cursor.col = 0;
+ if ((trypos = ind_find_start_comment()) != NULL) /* XXX */
+ curwin->w_cursor = *trypos;
+
+ line = ml_get_curline();
+ if (cin_ispreproc(line)) /* ignore #defines, #if, etc. */
+ continue;
+ if (*(line = cin_skipcomment(line)) == NUL)
+ continue;
+
+ curwin->w_cursor = cursor_save;
+ if (cin_isterminated(line, TRUE, FALSE)
+ || cin_isscopedecl(line)
+ || cin_iscase(line, TRUE)
+ || (cin_islabel_skip(&line) && cin_nocode(line)))
+ return TRUE;
+ return FALSE;
+ }
+ curwin->w_cursor = cursor_save;
+ return TRUE; /* label at start of file??? */
+ }
+ return FALSE;
+}
+
+/*
+ * Recognize structure initialization and enumerations:
+ * "[typedef] [static|public|protected|private] enum"
+ * "[typedef] [static|public|protected|private] = {"
+ */
+static int cin_isinit(void) {
+ char_u *s;
+ static char *skip[] = {"static", "public", "protected", "private"};
+
+ s = cin_skipcomment(ml_get_curline());
+
+ if (cin_starts_with(s, "typedef"))
+ s = cin_skipcomment(s + 7);
+
+ for (;; ) {
+ int i, l;
+
+ for (i = 0; i < (int)(sizeof(skip) / sizeof(char *)); ++i) {
+ l = (int)strlen(skip[i]);
+ if (cin_starts_with(s, skip[i])) {
+ s = cin_skipcomment(s + l);
+ l = 0;
+ break;
+ }
+ }
+ if (l != 0)
+ break;
+ }
+
+ if (cin_starts_with(s, "enum"))
+ return TRUE;
+
+ if (cin_ends_in(s, (char_u *)"=", (char_u *)"{"))
+ return TRUE;
+
+ return FALSE;
+}
+
+/*
+ * Recognize a switch label: "case .*:" or "default:".
+ */
+int cin_iscase(s, strict)
+char_u *s;
+int strict; /* Allow relaxed check of case statement for JS */
+{
+ s = cin_skipcomment(s);
+ if (cin_starts_with(s, "case")) {
+ for (s += 4; *s; ++s) {
+ s = cin_skipcomment(s);
+ if (*s == ':') {
+ if (s[1] == ':') /* skip over "::" for C++ */
+ ++s;
+ else
+ return TRUE;
+ }
+ if (*s == '\'' && s[1] && s[2] == '\'')
+ s += 2; /* skip over ':' */
+ else if (*s == '/' && (s[1] == '*' || s[1] == '/'))
+ return FALSE; /* stop at comment */
+ else if (*s == '"') {
+ /* JS etc. */
+ if (strict)
+ return FALSE; /* stop at string */
+ else
+ return TRUE;
+ }
+ }
+ return FALSE;
+ }
+
+ if (cin_isdefault(s))
+ return TRUE;
+ return FALSE;
+}
+
+/*
+ * Recognize a "default" switch label.
+ */
+static int cin_isdefault(s)
+char_u *s;
+{
+ return STRNCMP(s, "default", 7) == 0
+ && *(s = cin_skipcomment(s + 7)) == ':'
+ && s[1] != ':';
+}
+
+/*
+ * Recognize a "public/private/protected" scope declaration label.
+ */
+int cin_isscopedecl(s)
+char_u *s;
+{
+ int i;
+
+ s = cin_skipcomment(s);
+ if (STRNCMP(s, "public", 6) == 0)
+ i = 6;
+ else if (STRNCMP(s, "protected", 9) == 0)
+ i = 9;
+ else if (STRNCMP(s, "private", 7) == 0)
+ i = 7;
+ else
+ return FALSE;
+ return *(s = cin_skipcomment(s + i)) == ':' && s[1] != ':';
+}
+
+/* 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(s)
+char_u *s;
+{
+ char_u *p;
+ int has_name = 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 (vim_iswhite(*p)) {
+ 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;
+ } else {
+ return FALSE;
+ }
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*
+ * Return a pointer to the first non-empty non-comment character after a ':'.
+ * Return NULL if not found.
+ * case 234: a = b;
+ * ^
+ */
+static char_u * after_label(l)
+char_u *l;
+{
+ for (; *l; ++l) {
+ if (*l == ':') {
+ if (l[1] == ':') /* skip over "::" for C++ */
+ ++l;
+ else if (!cin_iscase(l + 1, FALSE))
+ break;
+ } else if (*l == '\'' && l[1] && l[2] == '\'')
+ l += 2; /* skip over 'x' */
+ }
+ if (*l == NUL)
+ return NULL;
+ l = cin_skipcomment(l + 1);
+ if (*l == NUL)
+ return NULL;
+ return l;
+}
+
+/*
+ * Get indent of line "lnum", skipping a label.
+ * Return 0 if there is nothing after the label.
+ */
+static int get_indent_nolabel(lnum) /* XXX */
+linenr_T lnum;
+{
+ char_u *l;
+ pos_T fp;
+ colnr_T col;
+ char_u *p;
+
+ l = ml_get(lnum);
+ p = after_label(l);
+ if (p == NULL)
+ return 0;
+
+ fp.col = (colnr_T)(p - l);
+ fp.lnum = lnum;
+ getvcol(curwin, &fp, &col, NULL, NULL);
+ return (int)col;
+}
+
+/*
+ * Find indent for line "lnum", ignoring any case or jump label.
+ * Also return a pointer to the text (after the label) in "pp".
+ * label: if (asdf && asdfasdf)
+ * ^
+ */
+static int skip_label(lnum, pp)
+linenr_T lnum;
+char_u **pp;
+{
+ char_u *l;
+ int amount;
+ pos_T cursor_save;
+
+ cursor_save = curwin->w_cursor;
+ curwin->w_cursor.lnum = lnum;
+ l = ml_get_curline();
+ /* XXX */
+ if (cin_iscase(l, FALSE) || cin_isscopedecl(l) || cin_islabel()) {
+ amount = get_indent_nolabel(lnum);
+ l = after_label(ml_get_curline());
+ if (l == NULL) /* just in case */
+ l = ml_get_curline();
+ } else {
+ amount = get_indent();
+ l = ml_get_curline();
+ }
+ *pp = l;
+
+ curwin->w_cursor = cursor_save;
+ return amount;
+}
+
+/*
+ * Return the indent of the first variable name after a type in a declaration.
+ * int a, indent of "a"
+ * static struct foo b, indent of "b"
+ * enum bla c, indent of "c"
+ * Returns zero when it doesn't look like a declaration.
+ */
+static int cin_first_id_amount() {
+ char_u *line, *p, *s;
+ int len;
+ pos_T fp;
+ colnr_T col;
+
+ line = ml_get_curline();
+ p = skipwhite(line);
+ len = (int)(skiptowhite(p) - p);
+ if (len == 6 && STRNCMP(p, "static", 6) == 0) {
+ p = skipwhite(p + 6);
+ len = (int)(skiptowhite(p) - p);
+ }
+ if (len == 6 && STRNCMP(p, "struct", 6) == 0)
+ p = skipwhite(p + 6);
+ else if (len == 4 && STRNCMP(p, "enum", 4) == 0)
+ p = skipwhite(p + 4);
+ else if ((len == 8 && STRNCMP(p, "unsigned", 8) == 0)
+ || (len == 6 && STRNCMP(p, "signed", 6) == 0)) {
+ s = skipwhite(p + len);
+ if ((STRNCMP(s, "int", 3) == 0 && vim_iswhite(s[3]))
+ || (STRNCMP(s, "long", 4) == 0 && vim_iswhite(s[4]))
+ || (STRNCMP(s, "short", 5) == 0 && vim_iswhite(s[5]))
+ || (STRNCMP(s, "char", 4) == 0 && vim_iswhite(s[4])))
+ p = s;
+ }
+ for (len = 0; vim_isIDc(p[len]); ++len)
+ ;
+ if (len == 0 || !vim_iswhite(p[len]) || cin_nocode(p))
+ return 0;
+
+ p = skipwhite(p + len);
+ fp.lnum = curwin->w_cursor.lnum;
+ fp.col = (colnr_T)(p - line);
+ getvcol(curwin, &fp, &col, NULL, NULL);
+ return (int)col;
+}
+
+/*
+ * Return the indent of the first non-blank after an equal sign.
+ * char *foo = "here";
+ * Return zero if no (useful) equal sign found.
+ * Return -1 if the line above "lnum" ends in a backslash.
+ * foo = "asdf\
+ * asdf\
+ * here";
+ */
+static int cin_get_equal_amount(lnum)
+linenr_T lnum;
+{
+ char_u *line;
+ char_u *s;
+ colnr_T col;
+ pos_T fp;
+
+ if (lnum > 1) {
+ line = ml_get(lnum - 1);
+ if (*line != NUL && line[STRLEN(line) - 1] == '\\')
+ return -1;
+ }
+
+ line = s = ml_get(lnum);
+ while (*s != NUL && vim_strchr((char_u *)"=;{}\"'", *s) == NULL) {
+ if (cin_iscomment(s)) /* ignore comments */
+ s = cin_skipcomment(s);
+ else
+ ++s;
+ }
+ if (*s != '=')
+ return 0;
+
+ s = skipwhite(s + 1);
+ if (cin_nocode(s))
+ return 0;
+
+ if (*s == '"') /* nice alignment for continued strings */
+ ++s;
+
+ fp.lnum = lnum;
+ fp.col = (colnr_T)(s - line);
+ getvcol(curwin, &fp, &col, NULL, NULL);
+ return (int)col;
+}
+
+/*
+ * Recognize a preprocessor statement: Any line that starts with '#'.
+ */
+static int cin_ispreproc(s)
+char_u *s;
+{
+ if (*skipwhite(s) == '#')
+ return TRUE;
+ 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(pp, lnump)
+char_u **pp;
+linenr_T *lnump;
+{
+ char_u *line = *pp;
+ linenr_T lnum = *lnump;
+ int retval = FALSE;
+
+ for (;; ) {
+ if (cin_ispreproc(line)) {
+ retval = TRUE;
+ *lnump = lnum;
+ break;
+ }
+ if (lnum == 1)
+ break;
+ line = ml_get(--lnum);
+ if (*line == NUL || line[STRLEN(line) - 1] != '\\')
+ break;
+ }
+
+ if (lnum != *lnump)
+ *pp = ml_get(*lnump);
+ return retval;
+}
+
+/*
+ * Recognize the start of a C or C++ comment.
+ */
+static int cin_iscomment(p)
+char_u *p;
+{
+ return p[0] == '/' && (p[1] == '*' || p[1] == '/');
+}
+
+/*
+ * Recognize the start of a "//" comment.
+ */
+static int cin_islinecomment(p)
+char_u *p;
+{
+ return p[0] == '/' && p[1] == '/';
+}
+
+/*
+ * Recognize a line that starts with '{' or '}', or ends with ';', ',', '{' or
+ * '}'.
+ * Don't consider "} else" a terminated line.
+ * If a line begins with an "else", only consider it terminated if no unmatched
+ * opening braces follow (handle "else { foo();" correctly).
+ * Return the character terminating the line (ending char's have precedence if
+ * both apply in order to determine initializations).
+ */
+static int cin_isterminated(s, incl_open, incl_comma)
+char_u *s;
+int incl_open; /* include '{' at the end as terminator */
+int incl_comma; /* recognize a trailing comma */
+{
+ char_u found_start = 0;
+ unsigned n_open = 0;
+ int is_else = FALSE;
+
+ s = cin_skipcomment(s);
+
+ if (*s == '{' || (*s == '}' && !cin_iselse(s)))
+ found_start = *s;
+
+ if (!found_start)
+ is_else = cin_iselse(s);
+
+ while (*s) {
+ /* skip over comments, "" strings and 'c'haracters */
+ s = skip_string(cin_skipcomment(s));
+ if (*s == '}' && n_open > 0)
+ --n_open;
+ if ((!is_else || n_open == 0)
+ && (*s == ';' || *s == '}' || (incl_comma && *s == ','))
+ && cin_nocode(s + 1))
+ return *s;
+ else if (*s == '{') {
+ if (incl_open && cin_nocode(s + 1))
+ return *s;
+ else
+ ++n_open;
+ }
+
+ if (*s)
+ s++;
+ }
+ 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.
+ */
+static int cin_isfuncdecl(sp, first_lnum, min_lnum)
+char_u **sp;
+linenr_T first_lnum;
+linenr_T min_lnum;
+{
+ char_u *s;
+ linenr_T lnum = first_lnum;
+ int retval = FALSE;
+ pos_T *trypos;
+ int just_started = TRUE;
+
+ if (sp == NULL)
+ s = ml_get(lnum);
+ else
+ s = *sp;
+
+ if (find_last_paren(s, '(', ')')
+ && (trypos = find_match_paren(curbuf->b_ind_maxparen)) != NULL) {
+ lnum = trypos->lnum;
+ if (lnum < min_lnum)
+ return FALSE;
+
+ s = ml_get(lnum);
+ }
+
+ /* Ignore line starting with #. */
+ if (cin_ispreproc(s))
+ return FALSE;
+
+ while (*s && *s != '(' && *s != ';' && *s != '\'' && *s != '"') {
+ if (cin_iscomment(s)) /* ignore comments */
+ s = cin_skipcomment(s);
+ else
+ ++s;
+ }
+ if (*s != '(')
+ return FALSE; /* ';', ' or " before any () or no '(' */
+
+ while (*s && *s != ';' && *s != '\'' && *s != '"') {
+ if (*s == ')' && cin_nocode(s + 1)) {
+ /* ')' at the end: may have found a match
+ * Check for he previous line not to end in a backslash:
+ * #if defined(x) && \
+ * defined(y)
+ */
+ lnum = first_lnum - 1;
+ s = ml_get(lnum);
+ if (*s == NUL || s[STRLEN(s) - 1] != '\\')
+ retval = TRUE;
+ goto done;
+ }
+ if ((*s == ',' && cin_nocode(s + 1)) || s[1] == NUL || cin_nocode(s)) {
+ int comma = (*s == ',');
+
+ /* ',' at the end: continue looking in the next line.
+ * At the end: check for ',' in the next line, for this style:
+ * func(arg1
+ * , arg2) */
+ for (;; ) {
+ if (lnum >= curbuf->b_ml.ml_line_count)
+ break;
+ s = ml_get(++lnum);
+ if (!cin_ispreproc(s))
+ break;
+ }
+ if (lnum >= curbuf->b_ml.ml_line_count)
+ break;
+ /* Require a comma at end of the line or a comma or ')' at the
+ * start of next line. */
+ s = skipwhite(s);
+ if (!just_started && (!comma && *s != ',' && *s != ')'))
+ break;
+ just_started = FALSE;
+ } else if (cin_iscomment(s)) /* ignore comments */
+ s = cin_skipcomment(s);
+ else {
+ ++s;
+ just_started = FALSE;
+ }
+ }
+
+done:
+ if (lnum != first_lnum && sp != NULL)
+ *sp = ml_get(first_lnum);
+
+ return retval;
+}
+
+static int cin_isif(p)
+char_u *p;
+{
+ return STRNCMP(p, "if", 2) == 0 && !vim_isIDc(p[2]);
+}
+
+static int cin_iselse(p)
+char_u *p;
+{
+ if (*p == '}') /* accept "} else" */
+ p = cin_skipcomment(p + 1);
+ return STRNCMP(p, "else", 4) == 0 && !vim_isIDc(p[4]);
+}
+
+static int cin_isdo(p)
+char_u *p;
+{
+ return STRNCMP(p, "do", 2) == 0 && !vim_isIDc(p[2]);
+}
+
+/*
+ * Check if this is a "while" that should have a matching "do".
+ * We only accept a "while (condition) ;", with only white space between the
+ * ')' and ';'. The condition may be spread over several lines.
+ */
+static int cin_iswhileofdo(p, lnum) /* XXX */
+char_u *p;
+linenr_T lnum;
+{
+ pos_T cursor_save;
+ pos_T *trypos;
+ int retval = FALSE;
+
+ p = cin_skipcomment(p);
+ if (*p == '}') /* accept "} while (cond);" */
+ p = cin_skipcomment(p + 1);
+ if (cin_starts_with(p, "while")) {
+ cursor_save = curwin->w_cursor;
+ curwin->w_cursor.lnum = lnum;
+ curwin->w_cursor.col = 0;
+ p = ml_get_curline();
+ while (*p && *p != 'w') { /* skip any '}', until the 'w' of the "while" */
+ ++p;
+ ++curwin->w_cursor.col;
+ }
+ if ((trypos = findmatchlimit(NULL, 0, 0,
+ curbuf->b_ind_maxparen)) != NULL
+ && *cin_skipcomment(ml_get_pos(trypos) + 1) == ';')
+ retval = TRUE;
+ curwin->w_cursor = cursor_save;
+ }
+ return retval;
+}
+
+/*
+ * Check whether in "p" there is an "if", "for" or "while" before "*poffset".
+ * Return 0 if there is none.
+ * Otherwise return !0 and update "*poffset" to point to the place where the
+ * string was found.
+ */
+static int cin_is_if_for_while_before_offset(line, poffset)
+char_u *line;
+int *poffset;
+{
+ int offset = *poffset;
+
+ if (offset-- < 2)
+ return 0;
+ while (offset > 2 && vim_iswhite(line[offset]))
+ --offset;
+
+ offset -= 1;
+ if (!STRNCMP(line + offset, "if", 2))
+ goto probablyFound;
+
+ if (offset >= 1) {
+ offset -= 1;
+ if (!STRNCMP(line + offset, "for", 3))
+ goto probablyFound;
+
+ if (offset >= 2) {
+ offset -= 2;
+ if (!STRNCMP(line + offset, "while", 5))
+ goto probablyFound;
+ }
+ }
+ return 0;
+
+probablyFound:
+ if (!offset || !vim_isIDc(line[offset - 1])) {
+ *poffset = offset;
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ * Return TRUE if we are at the end of a do-while.
+ * do
+ * nothing;
+ * while (foo
+ * && bar); <-- here
+ * Adjust the cursor to the line with "while".
+ */
+static int cin_iswhileofdo_end(terminated)
+int terminated;
+{
+ char_u *line;
+ char_u *p;
+ char_u *s;
+ pos_T *trypos;
+ int i;
+
+ if (terminated != ';') /* there must be a ';' at the end */
+ return FALSE;
+
+ p = line = ml_get_curline();
+ while (*p != NUL) {
+ p = cin_skipcomment(p);
+ if (*p == ')') {
+ s = skipwhite(p + 1);
+ if (*s == ';' && cin_nocode(s + 1)) {
+ /* Found ");" at end of the line, now check there is "while"
+ * before the matching '('. XXX */
+ i = (int)(p - line);
+ curwin->w_cursor.col = i;
+ trypos = find_match_paren(curbuf->b_ind_maxparen);
+ if (trypos != NULL) {
+ s = cin_skipcomment(ml_get(trypos->lnum));
+ if (*s == '}') /* accept "} while (cond);" */
+ s = cin_skipcomment(s + 1);
+ if (cin_starts_with(s, "while")) {
+ curwin->w_cursor.lnum = trypos->lnum;
+ return TRUE;
+ }
+ }
+
+ /* Searching may have made "line" invalid, get it again. */
+ line = ml_get_curline();
+ p = line + i;
+ }
+ }
+ if (*p != NUL)
+ ++p;
+ }
+ return FALSE;
+}
+
+static int cin_isbreak(p)
+char_u *p;
+{
+ return STRNCMP(p, "break", 5) == 0 && !vim_isIDc(p[5]);
+}
+
+/*
+ * Find the position of a C++ base-class declaration or
+ * constructor-initialization. eg:
+ *
+ * class MyClass :
+ * baseClass <-- here
+ * class MyClass : public baseClass,
+ * anotherBaseClass <-- here (should probably lineup ??)
+ * MyClass::MyClass(...) :
+ * baseClass(...) <-- here (constructor-initialization)
+ *
+ * This is a lot of guessing. Watch out for "cond ? func() : foo".
+ */
+static int cin_is_cpp_baseclass(col)
+colnr_T *col; /* return: column to align with */
+{
+ char_u *s;
+ int class_or_struct, lookfor_ctor_init, cpp_base_class;
+ linenr_T lnum = curwin->w_cursor.lnum;
+ char_u *line = ml_get_curline();
+
+ *col = 0;
+
+ s = skipwhite(line);
+ if (*s == '#') /* skip #define FOO x ? (x) : x */
+ return FALSE;
+ s = cin_skipcomment(s);
+ if (*s == NUL)
+ return FALSE;
+
+ cpp_base_class = lookfor_ctor_init = class_or_struct = FALSE;
+
+ /* Search for a line starting with '#', empty, ending in ';' or containing
+ * '{' or '}' and start below it. This handles the following situations:
+ * a = cond ?
+ * func() :
+ * asdf;
+ * func::foo()
+ * : something
+ * {}
+ * Foo::Foo (int one, int two)
+ * : something(4),
+ * somethingelse(3)
+ * {}
+ */
+ while (lnum > 1) {
+ line = ml_get(lnum - 1);
+ s = skipwhite(line);
+ if (*s == '#' || *s == NUL)
+ break;
+ while (*s != NUL) {
+ s = cin_skipcomment(s);
+ if (*s == '{' || *s == '}'
+ || (*s == ';' && cin_nocode(s + 1)))
+ break;
+ if (*s != NUL)
+ ++s;
+ }
+ if (*s != NUL)
+ break;
+ --lnum;
+ }
+
+ line = ml_get(lnum);
+ s = cin_skipcomment(line);
+ for (;; ) {
+ if (*s == NUL) {
+ if (lnum == curwin->w_cursor.lnum)
+ break;
+ /* Continue in the cursor line. */
+ line = ml_get(++lnum);
+ s = cin_skipcomment(line);
+ if (*s == NUL)
+ continue;
+ }
+
+ if (s[0] == '"')
+ s = skip_string(s) + 1;
+ else if (s[0] == ':') {
+ if (s[1] == ':') {
+ /* skip double colon. It can't be a constructor
+ * initialization any more */
+ lookfor_ctor_init = FALSE;
+ s = cin_skipcomment(s + 2);
+ } else if (lookfor_ctor_init || class_or_struct) {
+ /* we have something found, that looks like the start of
+ * cpp-base-class-declaration or constructor-initialization */
+ cpp_base_class = TRUE;
+ lookfor_ctor_init = class_or_struct = FALSE;
+ *col = 0;
+ s = cin_skipcomment(s + 1);
+ } else
+ s = cin_skipcomment(s + 1);
+ } else if ((STRNCMP(s, "class", 5) == 0 && !vim_isIDc(s[5]))
+ || (STRNCMP(s, "struct", 6) == 0 && !vim_isIDc(s[6]))) {
+ class_or_struct = TRUE;
+ lookfor_ctor_init = FALSE;
+
+ if (*s == 'c')
+ s = cin_skipcomment(s + 5);
+ else
+ s = cin_skipcomment(s + 6);
+ } else {
+ if (s[0] == '{' || s[0] == '}' || s[0] == ';') {
+ cpp_base_class = lookfor_ctor_init = class_or_struct = FALSE;
+ } else if (s[0] == ')') {
+ /* Constructor-initialization is assumed if we come across
+ * something like "):" */
+ class_or_struct = FALSE;
+ lookfor_ctor_init = TRUE;
+ } else if (s[0] == '?') {
+ /* Avoid seeing '() :' after '?' as constructor init. */
+ return FALSE;
+ } else if (!vim_isIDc(s[0])) {
+ /* if it is not an identifier, we are wrong */
+ class_or_struct = FALSE;
+ lookfor_ctor_init = FALSE;
+ } else if (*col == 0) {
+ /* it can't be a constructor-initialization any more */
+ lookfor_ctor_init = FALSE;
+
+ /* the first statement starts here: lineup with this one... */
+ if (cpp_base_class)
+ *col = (colnr_T)(s - line);
+ }
+
+ /* When the line ends in a comma don't align with it. */
+ if (lnum == curwin->w_cursor.lnum && *s == ',' && cin_nocode(s + 1))
+ *col = 0;
+
+ s = cin_skipcomment(s + 1);
+ }
+ }
+
+ return cpp_base_class;
+}
+
+static int get_baseclass_amount(col)
+int col;
+{
+ int amount;
+ colnr_T vcol;
+ pos_T *trypos;
+
+ if (col == 0) {
+ amount = get_indent();
+ if (find_last_paren(ml_get_curline(), '(', ')')
+ && (trypos = find_match_paren(curbuf->b_ind_maxparen)) != NULL)
+ amount = get_indent_lnum(trypos->lnum); /* XXX */
+ if (!cin_ends_in(ml_get_curline(), (char_u *)",", NULL))
+ amount += curbuf->b_ind_cpp_baseclass;
+ } else {
+ curwin->w_cursor.col = col;
+ getvcol(curwin, &curwin->w_cursor, &vcol, NULL, NULL);
+ amount = (int)vcol;
+ }
+ if (amount < curbuf->b_ind_cpp_baseclass)
+ amount = curbuf->b_ind_cpp_baseclass;
+ return amount;
+}
+
+/*
+ * Return TRUE if string "s" ends with the string "find", possibly followed by
+ * white space and comments. Skip strings and comments.
+ * Ignore "ignore" after "find" if it's not NULL.
+ */
+static int cin_ends_in(s, find, ignore)
+char_u *s;
+char_u *find;
+char_u *ignore;
+{
+ char_u *p = s;
+ char_u *r;
+ int len = (int)STRLEN(find);
+
+ while (*p != NUL) {
+ p = cin_skipcomment(p);
+ if (STRNCMP(p, find, len) == 0) {
+ r = skipwhite(p + len);
+ if (ignore != NULL && STRNCMP(r, ignore, STRLEN(ignore)) == 0)
+ r = skipwhite(r + STRLEN(ignore));
+ if (cin_nocode(r))
+ return TRUE;
+ }
+ if (*p != NUL)
+ ++p;
+ }
+ return FALSE;
+}
+
+/*
+ * Return TRUE when "s" starts with "word" and then a non-ID character.
+ */
+static int cin_starts_with(s, word)
+char_u *s;
+char *word;
+{
+ int l = (int)STRLEN(word);
+
+ return STRNCMP(s, word, l) == 0 && !vim_isIDc(s[l]);
+}
+
+/*
+ * Skip strings, chars and comments until at or past "trypos".
+ * Return the column found.
+ */
+static int cin_skip2pos(trypos)
+pos_T *trypos;
+{
+ char_u *line;
+ char_u *p;
+
+ p = line = ml_get(trypos->lnum);
+ while (*p && (colnr_T)(p - line) < trypos->col) {
+ if (cin_iscomment(p))
+ p = cin_skipcomment(p);
+ else {
+ p = skip_string(p);
+ ++p;
+ }
+ }
+ return (int)(p - line);
+}
+
+/*
+ * Find the '{' at the start of the block we are in.
+ * Return NULL if no match found.
+ * Ignore a '{' that is in a comment, makes indenting the next three lines
+ * work. */
+/* foo() */
+/* { */
+/* } */
+
+static pos_T * find_start_brace() { /* XXX */
+ pos_T cursor_save;
+ pos_T *trypos;
+ pos_T *pos;
+ static pos_T pos_copy;
+
+ cursor_save = curwin->w_cursor;
+ while ((trypos = findmatchlimit(NULL, '{', FM_BLOCKSTOP, 0)) != NULL) {
+ pos_copy = *trypos; /* copy pos_T, next findmatch will change it */
+ trypos = &pos_copy;
+ curwin->w_cursor = *trypos;
+ pos = NULL;
+ /* ignore the { if it's in a // or / * * / comment */
+ if ((colnr_T)cin_skip2pos(trypos) == trypos->col
+ && (pos = ind_find_start_comment()) == NULL) /* XXX */
+ break;
+ if (pos != NULL)
+ curwin->w_cursor.lnum = pos->lnum;
+ }
+ curwin->w_cursor = cursor_save;
+ return trypos;
+}
+
+/*
+ * Find the matching '(', failing if it is in a comment.
+ * Return NULL if no match found.
+ */
+static pos_T * find_match_paren(ind_maxparen) /* XXX */
+int ind_maxparen;
+{
+ pos_T cursor_save;
+ pos_T *trypos;
+ static pos_T pos_copy;
+
+ cursor_save = curwin->w_cursor;
+ if ((trypos = findmatchlimit(NULL, '(', 0, ind_maxparen)) != NULL) {
+ /* check if the ( is in a // comment */
+ if ((colnr_T)cin_skip2pos(trypos) > trypos->col)
+ trypos = NULL;
+ else {
+ pos_copy = *trypos; /* copy trypos, findmatch will change it */
+ trypos = &pos_copy;
+ curwin->w_cursor = *trypos;
+ if (ind_find_start_comment() != NULL) /* XXX */
+ trypos = NULL;
+ }
+ }
+ curwin->w_cursor = cursor_save;
+ return trypos;
+}
+
+/*
+ * Return ind_maxparen corrected for the difference in line number between the
+ * cursor position and "startpos". This makes sure that searching for a
+ * matching paren above the cursor line doesn't find a match because of
+ * looking a few lines further.
+ */
+static int corr_ind_maxparen(startpos)
+pos_T *startpos;
+{
+ long n = (long)startpos->lnum - (long)curwin->w_cursor.lnum;
+
+ if (n > 0 && n < curbuf->b_ind_maxparen / 2)
+ return curbuf->b_ind_maxparen - (int)n;
+ return curbuf->b_ind_maxparen;
+}
+
+/*
+ * Set w_cursor.col to the column number of the last unmatched ')' or '{' in
+ * line "l". "l" must point to the start of the line.
+ */
+static int find_last_paren(l, start, end)
+char_u *l;
+int start, end;
+{
+ int i;
+ int retval = FALSE;
+ int open_count = 0;
+
+ curwin->w_cursor.col = 0; /* default is start of line */
+
+ for (i = 0; l[i] != NUL; i++) {
+ i = (int)(cin_skipcomment(l + i) - l); /* ignore parens in comments */
+ i = (int)(skip_string(l + i) - l); /* ignore parens in quotes */
+ if (l[i] == start)
+ ++open_count;
+ else if (l[i] == end) {
+ if (open_count > 0)
+ --open_count;
+ else {
+ curwin->w_cursor.col = i;
+ retval = TRUE;
+ }
+ }
+ }
+ return retval;
+}
+
+/*
+ * Parse 'cinoptions' and set the values in "curbuf".
+ * Must be called when 'cinoptions', 'shiftwidth' and/or 'tabstop' changes.
+ */
+void parse_cino(buf)
+buf_T *buf;
+{
+ char_u *p;
+ char_u *l;
+ char_u *digits;
+ int n;
+ int divider;
+ int fraction = 0;
+ int sw = (int)get_sw_value(buf);
+
+ /*
+ * Set the default values.
+ */
+ /* Spaces from a block's opening brace the prevailing indent for that
+ * block should be. */
+ buf->b_ind_level = sw;
+
+ /* Spaces from the edge of the line an open brace that's at the end of a
+ * line is imagined to be. */
+ buf->b_ind_open_imag = 0;
+
+ /* Spaces from the prevailing indent for a line that is not preceded by
+ * an opening brace. */
+ buf->b_ind_no_brace = 0;
+
+ /* Column where the first { of a function should be located }. */
+ buf->b_ind_first_open = 0;
+
+ /* Spaces from the prevailing indent a leftmost open brace should be
+ * located. */
+ buf->b_ind_open_extra = 0;
+
+ /* Spaces from the matching open brace (real location for one at the left
+ * edge; imaginary location from one that ends a line) the matching close
+ * brace should be located. */
+ buf->b_ind_close_extra = 0;
+
+ /* Spaces from the edge of the line an open brace sitting in the leftmost
+ * column is imagined to be. */
+ buf->b_ind_open_left_imag = 0;
+
+ /* Spaces jump labels should be shifted to the left if N is non-negative,
+ * otherwise the jump label will be put to column 1. */
+ buf->b_ind_jump_label = -1;
+
+ /* Spaces from the switch() indent a "case xx" label should be located. */
+ buf->b_ind_case = sw;
+
+ /* Spaces from the "case xx:" code after a switch() should be located. */
+ buf->b_ind_case_code = sw;
+
+ /* Lineup break at end of case in switch() with case label. */
+ buf->b_ind_case_break = 0;
+
+ /* Spaces from the class declaration indent a scope declaration label
+ * should be located. */
+ buf->b_ind_scopedecl = sw;
+
+ /* Spaces from the scope declaration label code should be located. */
+ buf->b_ind_scopedecl_code = sw;
+
+ /* Amount K&R-style parameters should be indented. */
+ buf->b_ind_param = sw;
+
+ /* Amount a function type spec should be indented. */
+ buf->b_ind_func_type = sw;
+
+ /* Amount a cpp base class declaration or constructor initialization
+ * should be indented. */
+ buf->b_ind_cpp_baseclass = sw;
+
+ /* additional spaces beyond the prevailing indent a continuation line
+ * should be located. */
+ buf->b_ind_continuation = sw;
+
+ /* Spaces from the indent of the line with an unclosed parentheses. */
+ buf->b_ind_unclosed = sw * 2;
+
+ /* Spaces from the indent of the line with an unclosed parentheses, which
+ * itself is also unclosed. */
+ buf->b_ind_unclosed2 = sw;
+
+ /* Suppress ignoring spaces from the indent of a line starting with an
+ * unclosed parentheses. */
+ buf->b_ind_unclosed_noignore = 0;
+
+ /* If the opening paren is the last nonwhite character on the line, and
+ * b_ind_unclosed_wrapped is nonzero, use this indent relative to the outer
+ * context (for very long lines). */
+ buf->b_ind_unclosed_wrapped = 0;
+
+ /* Suppress ignoring white space when lining up with the character after
+ * an unclosed parentheses. */
+ buf->b_ind_unclosed_whiteok = 0;
+
+ /* Indent a closing parentheses under the line start of the matching
+ * opening parentheses. */
+ buf->b_ind_matching_paren = 0;
+
+ /* Indent a closing parentheses under the previous line. */
+ buf->b_ind_paren_prev = 0;
+
+ /* Extra indent for comments. */
+ buf->b_ind_comment = 0;
+
+ /* Spaces from the comment opener when there is nothing after it. */
+ buf->b_ind_in_comment = 3;
+
+ /* Boolean: if non-zero, use b_ind_in_comment even if there is something
+ * after the comment opener. */
+ buf->b_ind_in_comment2 = 0;
+
+ /* Max lines to search for an open paren. */
+ buf->b_ind_maxparen = 20;
+
+ /* Max lines to search for an open comment. */
+ buf->b_ind_maxcomment = 70;
+
+ /* Handle braces for java code. */
+ buf->b_ind_java = 0;
+
+ /* Not to confuse JS object properties with labels. */
+ buf->b_ind_js = 0;
+
+ /* Handle blocked cases correctly. */
+ buf->b_ind_keep_case_label = 0;
+
+ /* Handle C++ namespace. */
+ buf->b_ind_cpp_namespace = 0;
+
+ /* Handle continuation lines containing conditions of if(), for() and
+ * while(). */
+ buf->b_ind_if_for_while = 0;
+
+ for (p = buf->b_p_cino; *p; ) {
+ l = p++;
+ if (*p == '-')
+ ++p;
+ digits = p; /* remember where the digits start */
+ n = getdigits(&p);
+ divider = 0;
+ if (*p == '.') { /* ".5s" means a fraction */
+ fraction = atol((char *)++p);
+ while (VIM_ISDIGIT(*p)) {
+ ++p;
+ if (divider)
+ divider *= 10;
+ else
+ divider = 10;
+ }
+ }
+ if (*p == 's') { /* "2s" means two times 'shiftwidth' */
+ if (p == digits)
+ n = sw; /* just "s" is one 'shiftwidth' */
+ else {
+ n *= sw;
+ if (divider)
+ n += (sw * fraction + divider / 2) / divider;
+ }
+ ++p;
+ }
+ if (l[1] == '-')
+ n = -n;
+
+ /* When adding an entry here, also update the default 'cinoptions' in
+ * doc/indent.txt, and add explanation for it! */
+ switch (*l) {
+ case '>': buf->b_ind_level = n; break;
+ case 'e': buf->b_ind_open_imag = n; break;
+ case 'n': buf->b_ind_no_brace = n; break;
+ case 'f': buf->b_ind_first_open = n; break;
+ case '{': buf->b_ind_open_extra = n; break;
+ case '}': buf->b_ind_close_extra = n; break;
+ case '^': buf->b_ind_open_left_imag = n; break;
+ case 'L': buf->b_ind_jump_label = n; break;
+ case ':': buf->b_ind_case = n; break;
+ case '=': buf->b_ind_case_code = n; break;
+ case 'b': buf->b_ind_case_break = n; break;
+ case 'p': buf->b_ind_param = n; break;
+ case 't': buf->b_ind_func_type = n; break;
+ case '/': buf->b_ind_comment = n; break;
+ case 'c': buf->b_ind_in_comment = n; break;
+ case 'C': buf->b_ind_in_comment2 = n; break;
+ case 'i': buf->b_ind_cpp_baseclass = n; break;
+ case '+': buf->b_ind_continuation = n; break;
+ case '(': buf->b_ind_unclosed = n; break;
+ case 'u': buf->b_ind_unclosed2 = n; break;
+ case 'U': buf->b_ind_unclosed_noignore = n; break;
+ case 'W': buf->b_ind_unclosed_wrapped = n; break;
+ case 'w': buf->b_ind_unclosed_whiteok = n; break;
+ case 'm': buf->b_ind_matching_paren = n; break;
+ case 'M': buf->b_ind_paren_prev = n; break;
+ case ')': buf->b_ind_maxparen = n; break;
+ case '*': buf->b_ind_maxcomment = n; break;
+ case 'g': buf->b_ind_scopedecl = n; break;
+ case 'h': buf->b_ind_scopedecl_code = n; break;
+ case 'j': buf->b_ind_java = n; break;
+ case 'J': buf->b_ind_js = n; break;
+ case 'l': buf->b_ind_keep_case_label = n; break;
+ 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;
+ }
+ if (*p == ',')
+ ++p;
+ }
+}
+
+int get_c_indent() {
+ pos_T cur_curpos;
+ int amount;
+ int scope_amount;
+ int cur_amount = MAXCOL;
+ colnr_T col;
+ char_u *theline;
+ char_u *linecopy;
+ pos_T *trypos;
+ pos_T *tryposBrace = NULL;
+ pos_T our_paren_pos;
+ char_u *start;
+ int start_brace;
+#define BRACE_IN_COL0 1 /* '{' is in column 0 */
+#define BRACE_AT_START 2 /* '{' is at start of line */
+#define BRACE_AT_END 3 /* '{' is at end of line */
+ linenr_T ourscope;
+ char_u *l;
+ char_u *look;
+ char_u terminated;
+ int lookfor;
+#define LOOKFOR_INITIAL 0
+#define LOOKFOR_IF 1
+#define LOOKFOR_DO 2
+#define LOOKFOR_CASE 3
+#define LOOKFOR_ANY 4
+#define LOOKFOR_TERM 5
+#define LOOKFOR_UNTERM 6
+#define LOOKFOR_SCOPEDECL 7
+#define LOOKFOR_NOBREAK 8
+#define LOOKFOR_CPP_BASECLASS 9
+#define LOOKFOR_ENUM_OR_INIT 10
+
+ int whilelevel;
+ linenr_T lnum;
+ int n;
+ int iscase;
+ int lookfor_break;
+ int lookfor_cpp_namespace = FALSE;
+ int cont_amount = 0; /* amount for continuation line */
+ int original_line_islabel;
+ int added_to_amount = 0;
+
+ /* make a copy, value is changed below */
+ int ind_continuation = curbuf->b_ind_continuation;
+
+ /* remember where the cursor was when we started */
+ cur_curpos = curwin->w_cursor;
+
+ /* if we are at line 1 0 is fine, right? */
+ if (cur_curpos.lnum == 1)
+ return 0;
+
+ /* Get a copy of the current contents of the line.
+ * This is required, because only the most recent line obtained with
+ * ml_get is valid! */
+ linecopy = vim_strsave(ml_get(cur_curpos.lnum));
+ if (linecopy == NULL)
+ return 0;
+
+ /*
+ * In insert mode and the cursor is on a ')' truncate the line at the
+ * cursor position. We don't want to line up with the matching '(' when
+ * inserting new stuff.
+ * For unknown reasons the cursor might be past the end of the line, thus
+ * check for that.
+ */
+ if ((State & INSERT)
+ && curwin->w_cursor.col < (colnr_T)STRLEN(linecopy)
+ && linecopy[curwin->w_cursor.col] == ')')
+ linecopy[curwin->w_cursor.col] = NUL;
+
+ theline = skipwhite(linecopy);
+
+ /* move the cursor to the start of the line */
+
+ curwin->w_cursor.col = 0;
+
+ original_line_islabel = cin_islabel(); /* XXX */
+
+ /*
+ * #defines and so on always go at the left when included in 'cinkeys'.
+ */
+ if (*theline == '#' && (*linecopy == '#' || in_cinkeys('#', ' ', TRUE)))
+ amount = curbuf->b_ind_hash_comment;
+
+ /*
+ * Is it a non-case label? Then that goes at the left margin too unless:
+ * - JS flag is set.
+ * - 'L' item has a positive value.
+ */
+ else if (original_line_islabel && !curbuf->b_ind_js
+ && curbuf->b_ind_jump_label < 0) {
+ amount = 0;
+ }
+ /*
+ * If we're inside a "//" comment and there is a "//" comment in a
+ * previous line, lineup with that one.
+ */
+ else if (cin_islinecomment(theline)
+ && (trypos = find_line_comment()) != NULL) { /* XXX */
+ /* find how indented the line beginning the comment is */
+ getvcol(curwin, trypos, &col, NULL, NULL);
+ amount = col;
+ }
+ /*
+ * If we're inside a comment and not looking at the start of the
+ * comment, try using the 'comments' option.
+ */
+ else if (!cin_iscomment(theline)
+ && (trypos = ind_find_start_comment()) != NULL) {
+ /* XXX */
+ int lead_start_len = 2;
+ int lead_middle_len = 1;
+ char_u lead_start[COM_MAX_LEN]; /* start-comment string */
+ char_u lead_middle[COM_MAX_LEN]; /* middle-comment string */
+ char_u lead_end[COM_MAX_LEN]; /* end-comment string */
+ char_u *p;
+ int start_align = 0;
+ int start_off = 0;
+ int done = FALSE;
+
+ /* find how indented the line beginning the comment is */
+ getvcol(curwin, trypos, &col, NULL, NULL);
+ amount = col;
+ *lead_start = NUL;
+ *lead_middle = NUL;
+
+ p = curbuf->b_p_com;
+ while (*p != NUL) {
+ int align = 0;
+ int off = 0;
+ int what = 0;
+
+ while (*p != NUL && *p != ':') {
+ if (*p == COM_START || *p == COM_END || *p == COM_MIDDLE)
+ what = *p++;
+ else if (*p == COM_LEFT || *p == COM_RIGHT)
+ align = *p++;
+ else if (VIM_ISDIGIT(*p) || *p == '-')
+ off = getdigits(&p);
+ else
+ ++p;
+ }
+
+ if (*p == ':')
+ ++p;
+ (void)copy_option_part(&p, lead_end, COM_MAX_LEN, ",");
+ if (what == COM_START) {
+ STRCPY(lead_start, lead_end);
+ lead_start_len = (int)STRLEN(lead_start);
+ start_off = off;
+ start_align = align;
+ } else if (what == COM_MIDDLE) {
+ STRCPY(lead_middle, lead_end);
+ lead_middle_len = (int)STRLEN(lead_middle);
+ } else if (what == COM_END) {
+ /* If our line starts with the middle comment string, line it
+ * up with the comment opener per the 'comments' option. */
+ if (STRNCMP(theline, lead_middle, lead_middle_len) == 0
+ && STRNCMP(theline, lead_end, STRLEN(lead_end)) != 0) {
+ done = TRUE;
+ if (curwin->w_cursor.lnum > 1) {
+ /* If the start comment string matches in the previous
+ * line, use the indent of that line plus offset. If
+ * the middle comment string matches in the previous
+ * line, use the indent of that line. XXX */
+ look = skipwhite(ml_get(curwin->w_cursor.lnum - 1));
+ if (STRNCMP(look, lead_start, lead_start_len) == 0)
+ amount = get_indent_lnum(curwin->w_cursor.lnum - 1);
+ else if (STRNCMP(look, lead_middle,
+ lead_middle_len) == 0) {
+ amount = get_indent_lnum(curwin->w_cursor.lnum - 1);
+ break;
+ }
+ /* If the start comment string doesn't match with the
+ * start of the comment, skip this entry. XXX */
+ else if (STRNCMP(ml_get(trypos->lnum) + trypos->col,
+ lead_start, lead_start_len) != 0)
+ continue;
+ }
+ if (start_off != 0)
+ amount += start_off;
+ else if (start_align == COM_RIGHT)
+ amount += vim_strsize(lead_start)
+ - vim_strsize(lead_middle);
+ break;
+ }
+
+ /* If our line starts with the end comment string, line it up
+ * with the middle comment */
+ if (STRNCMP(theline, lead_middle, lead_middle_len) != 0
+ && STRNCMP(theline, lead_end, STRLEN(lead_end)) == 0) {
+ amount = get_indent_lnum(curwin->w_cursor.lnum - 1);
+ /* XXX */
+ if (off != 0)
+ amount += off;
+ else if (align == COM_RIGHT)
+ amount += vim_strsize(lead_start)
+ - vim_strsize(lead_middle);
+ done = TRUE;
+ break;
+ }
+ }
+ }
+
+ /* If our line starts with an asterisk, line up with the
+ * asterisk in the comment opener; otherwise, line up
+ * with the first character of the comment text.
+ */
+ if (done)
+ ;
+ else if (theline[0] == '*')
+ amount += 1;
+ else {
+ /*
+ * If we are more than one line away from the comment opener, take
+ * the indent of the previous non-empty line. If 'cino' has "CO"
+ * and we are just below the comment opener and there are any
+ * white characters after it line up with the text after it;
+ * otherwise, add the amount specified by "c" in 'cino'
+ */
+ amount = -1;
+ for (lnum = cur_curpos.lnum - 1; lnum > trypos->lnum; --lnum) {
+ if (linewhite(lnum)) /* skip blank lines */
+ continue;
+ amount = get_indent_lnum(lnum); /* XXX */
+ break;
+ }
+ if (amount == -1) { /* use the comment opener */
+ if (!curbuf->b_ind_in_comment2) {
+ start = ml_get(trypos->lnum);
+ look = start + trypos->col + 2; /* skip / and * */
+ if (*look != NUL) /* if something after it */
+ trypos->col = (colnr_T)(skipwhite(look) - start);
+ }
+ getvcol(curwin, trypos, &col, NULL, NULL);
+ amount = col;
+ if (curbuf->b_ind_in_comment2 || *look == NUL)
+ amount += curbuf->b_ind_in_comment;
+ }
+ }
+ }
+ /*
+ * Are we inside parentheses or braces?
+ */ /* XXX */
+ else if (((trypos = find_match_paren(curbuf->b_ind_maxparen)) != NULL
+ && curbuf->b_ind_java == 0)
+ || (tryposBrace = find_start_brace()) != NULL
+ || trypos != NULL) {
+ if (trypos != NULL && tryposBrace != NULL) {
+ /* Both an unmatched '(' and '{' is found. Use the one which is
+ * closer to the current cursor position, set the other to NULL. */
+ if (trypos->lnum != tryposBrace->lnum
+ ? trypos->lnum < tryposBrace->lnum
+ : trypos->col < tryposBrace->col)
+ trypos = NULL;
+ else
+ tryposBrace = NULL;
+ }
+
+ if (trypos != NULL) {
+ /*
+ * If the matching paren is more than one line away, use the indent of
+ * a previous non-empty line that matches the same paren.
+ */
+ if (theline[0] == ')' && curbuf->b_ind_paren_prev) {
+ /* Line up with the start of the matching paren line. */
+ amount = get_indent_lnum(curwin->w_cursor.lnum - 1); /* XXX */
+ } else {
+ amount = -1;
+ our_paren_pos = *trypos;
+ for (lnum = cur_curpos.lnum - 1; lnum > our_paren_pos.lnum; --lnum) {
+ l = skipwhite(ml_get(lnum));
+ if (cin_nocode(l)) /* skip comment lines */
+ continue;
+ if (cin_ispreproc_cont(&l, &lnum))
+ continue; /* ignore #define, #if, etc. */
+ curwin->w_cursor.lnum = lnum;
+
+ /* Skip a comment. XXX */
+ if ((trypos = ind_find_start_comment()) != NULL) {
+ lnum = trypos->lnum + 1;
+ continue;
+ }
+
+ /* XXX */
+ if ((trypos = find_match_paren(
+ corr_ind_maxparen(&cur_curpos))) != NULL
+ && trypos->lnum == our_paren_pos.lnum
+ && trypos->col == our_paren_pos.col) {
+ amount = get_indent_lnum(lnum); /* XXX */
+
+ if (theline[0] == ')') {
+ if (our_paren_pos.lnum != lnum
+ && cur_amount > amount)
+ cur_amount = amount;
+ amount = -1;
+ }
+ break;
+ }
+ }
+ }
+
+ /*
+ * Line up with line where the matching paren is. XXX
+ * If the line starts with a '(' or the indent for unclosed
+ * parentheses is zero, line up with the unclosed parentheses.
+ */
+ if (amount == -1) {
+ int ignore_paren_col = 0;
+ int is_if_for_while = 0;
+
+ if (curbuf->b_ind_if_for_while) {
+ /* Look for the outermost opening parenthesis on this line
+ * and check whether it belongs to an "if", "for" or "while". */
+
+ pos_T cursor_save = curwin->w_cursor;
+ pos_T outermost;
+ char_u *line;
+
+ trypos = &our_paren_pos;
+ do {
+ outermost = *trypos;
+ curwin->w_cursor.lnum = outermost.lnum;
+ curwin->w_cursor.col = outermost.col;
+
+ trypos = find_match_paren(curbuf->b_ind_maxparen);
+ } while (trypos && trypos->lnum == outermost.lnum);
+
+ curwin->w_cursor = cursor_save;
+
+ line = ml_get(outermost.lnum);
+
+ is_if_for_while =
+ cin_is_if_for_while_before_offset(line, &outermost.col);
+ }
+
+ amount = skip_label(our_paren_pos.lnum, &look);
+ look = skipwhite(look);
+ if (*look == '(') {
+ linenr_T save_lnum = curwin->w_cursor.lnum;
+ char_u *line;
+ int look_col;
+
+ /* Ignore a '(' in front of the line that has a match before
+ * our matching '('. */
+ curwin->w_cursor.lnum = our_paren_pos.lnum;
+ line = ml_get_curline();
+ look_col = (int)(look - line);
+ curwin->w_cursor.col = look_col + 1;
+ if ((trypos = findmatchlimit(NULL, ')', 0,
+ curbuf->b_ind_maxparen))
+ != NULL
+ && trypos->lnum == our_paren_pos.lnum
+ && trypos->col < our_paren_pos.col)
+ ignore_paren_col = trypos->col + 1;
+
+ curwin->w_cursor.lnum = save_lnum;
+ look = ml_get(our_paren_pos.lnum) + look_col;
+ }
+ if (theline[0] == ')' || (curbuf->b_ind_unclosed == 0
+ && is_if_for_while == 0)
+ || (!curbuf->b_ind_unclosed_noignore && *look == '('
+ && ignore_paren_col == 0)) {
+ /*
+ * If we're looking at a close paren, line up right there;
+ * otherwise, line up with the next (non-white) character.
+ * When b_ind_unclosed_wrapped is set and the matching paren is
+ * the last nonwhite character of the line, use either the
+ * indent of the current line or the indentation of the next
+ * outer paren and add b_ind_unclosed_wrapped (for very long
+ * lines).
+ */
+ if (theline[0] != ')') {
+ cur_amount = MAXCOL;
+ l = ml_get(our_paren_pos.lnum);
+ if (curbuf->b_ind_unclosed_wrapped
+ && cin_ends_in(l, (char_u *)"(", NULL)) {
+ /* look for opening unmatched paren, indent one level
+ * for each additional level */
+ n = 1;
+ for (col = 0; col < our_paren_pos.col; ++col) {
+ switch (l[col]) {
+ case '(':
+ case '{': ++n;
+ break;
+
+ case ')':
+ case '}': if (n > 1)
+ --n;
+ break;
+ }
+ }
+
+ our_paren_pos.col = 0;
+ amount += n * curbuf->b_ind_unclosed_wrapped;
+ } else if (curbuf->b_ind_unclosed_whiteok)
+ our_paren_pos.col++;
+ else {
+ col = our_paren_pos.col + 1;
+ while (vim_iswhite(l[col]))
+ col++;
+ if (l[col] != NUL) /* In case of trailing space */
+ our_paren_pos.col = col;
+ else
+ our_paren_pos.col++;
+ }
+ }
+
+ /*
+ * Find how indented the paren is, or the character after it
+ * if we did the above "if".
+ */
+ if (our_paren_pos.col > 0) {
+ getvcol(curwin, &our_paren_pos, &col, NULL, NULL);
+ if (cur_amount > (int)col)
+ cur_amount = col;
+ }
+ }
+
+ if (theline[0] == ')' && curbuf->b_ind_matching_paren) {
+ /* Line up with the start of the matching paren line. */
+ } else if ((curbuf->b_ind_unclosed == 0 && is_if_for_while == 0)
+ || (!curbuf->b_ind_unclosed_noignore
+ && *look == '(' && ignore_paren_col == 0)) {
+ if (cur_amount != MAXCOL)
+ amount = cur_amount;
+ } else {
+ /* Add b_ind_unclosed2 for each '(' before our matching one,
+ * but ignore (void) before the line (ignore_paren_col). */
+ col = our_paren_pos.col;
+ while ((int)our_paren_pos.col > ignore_paren_col) {
+ --our_paren_pos.col;
+ switch (*ml_get_pos(&our_paren_pos)) {
+ case '(': amount += curbuf->b_ind_unclosed2;
+ col = our_paren_pos.col;
+ break;
+ case ')': amount -= curbuf->b_ind_unclosed2;
+ col = MAXCOL;
+ break;
+ }
+ }
+
+ /* Use b_ind_unclosed once, when the first '(' is not inside
+ * braces */
+ if (col == MAXCOL)
+ amount += curbuf->b_ind_unclosed;
+ else {
+ curwin->w_cursor.lnum = our_paren_pos.lnum;
+ curwin->w_cursor.col = col;
+ if (find_match_paren(curbuf->b_ind_maxparen) != NULL)
+ amount += curbuf->b_ind_unclosed2;
+ else {
+ if (is_if_for_while)
+ amount += curbuf->b_ind_if_for_while;
+ else
+ amount += curbuf->b_ind_unclosed;
+ }
+ }
+ /*
+ * For a line starting with ')' use the minimum of the two
+ * positions, to avoid giving it more indent than the previous
+ * lines:
+ * func_long_name( if (x
+ * arg && yy
+ * ) ^ not here ) ^ not here
+ */
+ if (cur_amount < amount)
+ amount = cur_amount;
+ }
+ }
+
+ /* add extra indent for a comment */
+ if (cin_iscomment(theline))
+ amount += curbuf->b_ind_comment;
+ }
+ /*
+ * Are we at least inside braces, then?
+ */
+ else {
+ trypos = tryposBrace;
+
+ ourscope = trypos->lnum;
+ start = ml_get(ourscope);
+
+ /*
+ * Now figure out how indented the line is in general.
+ * If the brace was at the start of the line, we use that;
+ * otherwise, check out the indentation of the line as
+ * a whole and then add the "imaginary indent" to that.
+ */
+ look = skipwhite(start);
+ if (*look == '{') {
+ getvcol(curwin, trypos, &col, NULL, NULL);
+ amount = col;
+ if (*start == '{')
+ start_brace = BRACE_IN_COL0;
+ else
+ start_brace = BRACE_AT_START;
+ } else {
+ /*
+ * that opening brace might have been on a continuation
+ * line. if so, find the start of the line.
+ */
+ curwin->w_cursor.lnum = ourscope;
+
+ /*
+ * position the cursor over the rightmost paren, so that
+ * matching it will take us back to the start of the line.
+ */
+ lnum = ourscope;
+ if (find_last_paren(start, '(', ')')
+ && (trypos = find_match_paren(curbuf->b_ind_maxparen))
+ != NULL)
+ lnum = trypos->lnum;
+
+ /*
+ * It could have been something like
+ * case 1: if (asdf &&
+ * ldfd) {
+ * }
+ */
+ if (curbuf->b_ind_js || (curbuf->b_ind_keep_case_label
+ && cin_iscase(skipwhite(ml_get_curline()),
+ FALSE)))
+ amount = get_indent();
+ else
+ amount = skip_label(lnum, &l);
+
+ start_brace = BRACE_AT_END;
+ }
+
+ /*
+ * if we're looking at a closing brace, that's where
+ * we want to be. otherwise, add the amount of room
+ * that an indent is supposed to be.
+ */
+ if (theline[0] == '}') {
+ /*
+ * they may want closing braces to line up with something
+ * other than the open brace. indulge them, if so.
+ */
+ amount += curbuf->b_ind_close_extra;
+ } else {
+ /*
+ * If we're looking at an "else", try to find an "if"
+ * to match it with.
+ * If we're looking at a "while", try to find a "do"
+ * to match it with.
+ */
+ lookfor = LOOKFOR_INITIAL;
+ if (cin_iselse(theline))
+ lookfor = LOOKFOR_IF;
+ else if (cin_iswhileofdo(theline, cur_curpos.lnum)) /* XXX */
+ lookfor = LOOKFOR_DO;
+ if (lookfor != LOOKFOR_INITIAL) {
+ curwin->w_cursor.lnum = cur_curpos.lnum;
+ if (find_match(lookfor, ourscope) == OK) {
+ amount = get_indent(); /* XXX */
+ goto theend;
+ }
+ }
+
+ /*
+ * We get here if we are not on an "while-of-do" or "else" (or
+ * failed to find a matching "if").
+ * Search backwards for something to line up with.
+ * First set amount for when we don't find anything.
+ */
+
+ /*
+ * if the '{' is _really_ at the left margin, use the imaginary
+ * location of a left-margin brace. Otherwise, correct the
+ * location for b_ind_open_extra.
+ */
+
+ if (start_brace == BRACE_IN_COL0) { /* '{' is in column 0 */
+ amount = curbuf->b_ind_open_left_imag;
+ lookfor_cpp_namespace = TRUE;
+ } else if (start_brace == BRACE_AT_START &&
+ lookfor_cpp_namespace) { /* '{' is at start */
+
+ lookfor_cpp_namespace = TRUE;
+ } else {
+ if (start_brace == BRACE_AT_END) { /* '{' is at end of line */
+ amount += curbuf->b_ind_open_imag;
+
+ l = skipwhite(ml_get_curline());
+ if (cin_is_cpp_namespace(l))
+ amount += curbuf->b_ind_cpp_namespace;
+ } else {
+ /* Compensate for adding b_ind_open_extra later. */
+ amount -= curbuf->b_ind_open_extra;
+ if (amount < 0)
+ amount = 0;
+ }
+ }
+
+ lookfor_break = FALSE;
+
+ if (cin_iscase(theline, FALSE)) { /* it's a switch() label */
+ lookfor = LOOKFOR_CASE; /* find a previous switch() label */
+ amount += curbuf->b_ind_case;
+ } else if (cin_isscopedecl(theline)) { /* private:, ... */
+ lookfor = LOOKFOR_SCOPEDECL; /* class decl is this block */
+ amount += curbuf->b_ind_scopedecl;
+ } else {
+ if (curbuf->b_ind_case_break && cin_isbreak(theline))
+ /* break; ... */
+ lookfor_break = TRUE;
+
+ lookfor = LOOKFOR_INITIAL;
+ /* b_ind_level from start of block */
+ amount += curbuf->b_ind_level;
+ }
+ scope_amount = amount;
+ whilelevel = 0;
+
+ /*
+ * Search backwards. If we find something we recognize, line up
+ * with that.
+ *
+ * if we're looking at an open brace, indent
+ * the usual amount relative to the conditional
+ * that opens the block.
+ */
+ curwin->w_cursor = cur_curpos;
+ for (;; ) {
+ curwin->w_cursor.lnum--;
+ curwin->w_cursor.col = 0;
+
+ /*
+ * If we went all the way back to the start of our scope, line
+ * up with it.
+ */
+ if (curwin->w_cursor.lnum <= ourscope) {
+ /* 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
+ < ourscope - curbuf->b_ind_maxparen) {
+ /* nothing found (abuse curbuf->b_ind_maxparen as
+ * limit) assume terminated line (i.e. a variable
+ * initialization) */
+ if (cont_amount > 0)
+ amount = cont_amount;
+ else if (!curbuf->b_ind_js)
+ amount += ind_continuation;
+ break;
+ }
+
+ l = ml_get_curline();
+
+ /*
+ * If we're in a comment now, skip to the start of the
+ * comment.
+ */
+ trypos = ind_find_start_comment();
+ 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))
+ continue;
+
+ if (cin_nocode(l))
+ continue;
+
+ terminated = cin_isterminated(l, FALSE, TRUE);
+
+ /*
+ * If we are at top level and the line looks like a
+ * function declaration, we are done
+ * (it's a variable declaration).
+ */
+ if (start_brace != BRACE_IN_COL0
+ || !cin_isfuncdecl(&l, curwin->w_cursor.lnum, 0)) {
+ /* if the line is terminated with another ','
+ * it is a continued variable initialization.
+ * don't add extra indent.
+ * TODO: does not work, if a function
+ * declaration is split over multiple lines:
+ * cin_isfuncdecl returns FALSE then.
+ */
+ if (terminated == ',')
+ break;
+
+ /* if it es a enum declaration or an assignment,
+ * we are done.
+ */
+ if (terminated != ';' && cin_isinit())
+ break;
+
+ /* nothing useful found */
+ if (terminated == 0 || terminated == '{')
+ continue;
+ }
+
+ if (terminated != ';') {
+ /* Skip parens and braces. Position the cursor
+ * over the rightmost paren, so that matching it
+ * will take us back to the start of the line.
+ */ /* XXX */
+ trypos = NULL;
+ if (find_last_paren(l, '(', ')'))
+ trypos = find_match_paren(
+ curbuf->b_ind_maxparen);
+
+ if (trypos == NULL && find_last_paren(l, '{', '}'))
+ trypos = find_start_brace();
+
+ if (trypos != NULL) {
+ curwin->w_cursor.lnum = trypos->lnum + 1;
+ curwin->w_cursor.col = 0;
+ continue;
+ }
+ }
+
+ /* it's a variable declaration, add indentation
+ * like in
+ * int a,
+ * b;
+ */
+ if (cont_amount > 0)
+ amount = cont_amount;
+ else
+ amount += ind_continuation;
+ } else if (lookfor == LOOKFOR_UNTERM) {
+ if (cont_amount > 0)
+ amount = cont_amount;
+ else
+ amount += ind_continuation;
+ } else {
+ if (lookfor != LOOKFOR_TERM
+ && lookfor != LOOKFOR_CPP_BASECLASS) {
+ amount = scope_amount;
+ if (theline[0] == '{') {
+ amount += curbuf->b_ind_open_extra;
+ added_to_amount = curbuf->b_ind_open_extra;
+ }
+ }
+
+ if (lookfor_cpp_namespace) {
+ /*
+ * Looking for C++ namespace, need to look further
+ * back.
+ */
+ if (curwin->w_cursor.lnum == ourscope)
+ continue;
+
+ if (curwin->w_cursor.lnum == 0
+ || curwin->w_cursor.lnum
+ < ourscope - FIND_NAMESPACE_LIM)
+ break;
+
+ l = ml_get_curline();
+
+ /* If we're in a comment now, skip to the start of
+ * the comment. */
+ trypos = ind_find_start_comment();
+ 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))
+ continue;
+
+ /* Finally the actual check for "namespace". */
+ if (cin_is_cpp_namespace(l)) {
+ amount += curbuf->b_ind_cpp_namespace
+ - added_to_amount;
+ break;
+ }
+
+ if (cin_nocode(l))
+ continue;
+ }
+ }
+ break;
+ }
+
+ /*
+ * If we're in a comment now, skip to the start of the comment.
+ */ /* XXX */
+ if ((trypos = ind_find_start_comment()) != NULL) {
+ curwin->w_cursor.lnum = trypos->lnum + 1;
+ curwin->w_cursor.col = 0;
+ continue;
+ }
+
+ l = ml_get_curline();
+
+ /*
+ * If this is a switch() label, may line up relative to that.
+ * If this is a C++ scope declaration, do the same.
+ */
+ iscase = cin_iscase(l, FALSE);
+ if (iscase || cin_isscopedecl(l)) {
+ /* we are only looking for cpp base class
+ * declaration/initialization any longer */
+ if (lookfor == LOOKFOR_CPP_BASECLASS)
+ break;
+
+ /* When looking for a "do" we are not interested in
+ * labels. */
+ if (whilelevel > 0)
+ continue;
+
+ /*
+ * case xx:
+ * c = 99 + <- this indent plus continuation
+ **-> here;
+ */
+ if (lookfor == LOOKFOR_UNTERM
+ || lookfor == LOOKFOR_ENUM_OR_INIT) {
+ if (cont_amount > 0)
+ amount = cont_amount;
+ else
+ amount += ind_continuation;
+ break;
+ }
+
+ /*
+ * case xx: <- line up with this case
+ * x = 333;
+ * case yy:
+ */
+ if ( (iscase && lookfor == LOOKFOR_CASE)
+ || (iscase && lookfor_break)
+ || (!iscase && lookfor == LOOKFOR_SCOPEDECL)) {
+ /*
+ * Check that this case label is not for another
+ * switch()
+ */ /* XXX */
+ if ((trypos = find_start_brace()) == NULL
+ || trypos->lnum == ourscope) {
+ amount = get_indent(); /* XXX */
+ break;
+ }
+ continue;
+ }
+
+ n = get_indent_nolabel(curwin->w_cursor.lnum); /* XXX */
+
+ /*
+ * case xx: if (cond) <- line up with this if
+ * y = y + 1;
+ * -> s = 99;
+ *
+ * case xx:
+ * if (cond) <- line up with this line
+ * y = y + 1;
+ * -> s = 99;
+ */
+ if (lookfor == LOOKFOR_TERM) {
+ if (n)
+ amount = n;
+
+ if (!lookfor_break)
+ break;
+ }
+
+ /*
+ * case xx: x = x + 1; <- line up with this x
+ * -> y = y + 1;
+ *
+ * case xx: if (cond) <- line up with this if
+ * -> y = y + 1;
+ */
+ if (n) {
+ amount = n;
+ l = after_label(ml_get_curline());
+ if (l != NULL && cin_is_cinword(l)) {
+ if (theline[0] == '{')
+ amount += curbuf->b_ind_open_extra;
+ else
+ amount += curbuf->b_ind_level
+ + curbuf->b_ind_no_brace;
+ }
+ break;
+ }
+
+ /*
+ * Try to get the indent of a statement before the switch
+ * label. If nothing is found, line up relative to the
+ * switch label.
+ * break; <- may line up with this line
+ * case xx:
+ * -> y = 1;
+ */
+ scope_amount = get_indent() + (iscase /* XXX */
+ ? curbuf->b_ind_case_code
+ : curbuf->b_ind_scopedecl_code);
+ lookfor = curbuf->b_ind_case_break
+ ? LOOKFOR_NOBREAK : LOOKFOR_ANY;
+ continue;
+ }
+
+ /*
+ * Looking for a switch() label or C++ scope declaration,
+ * ignore other lines, skip {}-blocks.
+ */
+ if (lookfor == LOOKFOR_CASE || lookfor == LOOKFOR_SCOPEDECL) {
+ if (find_last_paren(l, '{', '}')
+ && (trypos = find_start_brace()) != NULL) {
+ curwin->w_cursor.lnum = trypos->lnum + 1;
+ curwin->w_cursor.col = 0;
+ }
+ continue;
+ }
+
+ /*
+ * Ignore jump labels with nothing after them.
+ */
+ if (!curbuf->b_ind_js && cin_islabel()) {
+ l = after_label(ml_get_curline());
+ if (l == NULL || cin_nocode(l))
+ continue;
+ }
+
+ /*
+ * Ignore #defines, #if, etc.
+ * Ignore comment and empty lines.
+ * (need to get the line again, cin_islabel() may have
+ * unlocked it)
+ */
+ l = ml_get_curline();
+ if (cin_ispreproc_cont(&l, &curwin->w_cursor.lnum)
+ || cin_nocode(l))
+ continue;
+
+ /*
+ * Are we at the start of a cpp base class declaration or
+ * constructor initialization?
+ */ /* XXX */
+ n = FALSE;
+ if (lookfor != LOOKFOR_TERM && curbuf->b_ind_cpp_baseclass > 0) {
+ n = cin_is_cpp_baseclass(&col);
+ l = ml_get_curline();
+ }
+ if (n) {
+ if (lookfor == LOOKFOR_UNTERM) {
+ if (cont_amount > 0)
+ amount = cont_amount;
+ else
+ amount += ind_continuation;
+ } else if (theline[0] == '{') {
+ /* Need to find start of the declaration. */
+ lookfor = LOOKFOR_UNTERM;
+ ind_continuation = 0;
+ continue;
+ } else
+ /* XXX */
+ amount = get_baseclass_amount(col);
+ break;
+ } else if (lookfor == LOOKFOR_CPP_BASECLASS) {
+ /* only look, whether there is a cpp base class
+ * declaration or initialization before the opening brace.
+ */
+ if (cin_isterminated(l, TRUE, FALSE))
+ break;
+ else
+ continue;
+ }
+
+ /*
+ * What happens next depends on the line being terminated.
+ * If terminated with a ',' only consider it terminating if
+ * there is another unterminated statement behind, eg:
+ * 123,
+ * sizeof
+ * here
+ * Otherwise check whether it is a enumeration or structure
+ * initialisation (not indented) or a variable declaration
+ * (indented).
+ */
+ terminated = cin_isterminated(l, FALSE, TRUE);
+
+ if (terminated == 0 || (lookfor != LOOKFOR_UNTERM
+ && terminated == ',')) {
+ /*
+ * if we're in the middle of a paren thing,
+ * go back to the line that starts it so
+ * we can get the right prevailing indent
+ * if ( foo &&
+ * bar )
+ */
+ /*
+ * position the cursor over the rightmost paren, so that
+ * matching it will take us back to the start of the line.
+ */
+ (void)find_last_paren(l, '(', ')');
+ trypos = find_match_paren(corr_ind_maxparen(&cur_curpos));
+
+ /*
+ * If we are looking for ',', we also look for matching
+ * braces.
+ */
+ if (trypos == NULL && terminated == ','
+ && find_last_paren(l, '{', '}'))
+ trypos = find_start_brace();
+
+ if (trypos != NULL) {
+ /*
+ * Check if we are on a case label now. This is
+ * handled above.
+ * case xx: if ( asdf &&
+ * asdf)
+ */
+ curwin->w_cursor = *trypos;
+ l = ml_get_curline();
+ if (cin_iscase(l, FALSE) || cin_isscopedecl(l)) {
+ ++curwin->w_cursor.lnum;
+ curwin->w_cursor.col = 0;
+ continue;
+ }
+ }
+
+ /*
+ * Skip over continuation lines to find the one to get the
+ * indent from
+ * char *usethis = "bla\
+ * bla",
+ * here;
+ */
+ if (terminated == ',') {
+ while (curwin->w_cursor.lnum > 1) {
+ l = ml_get(curwin->w_cursor.lnum - 1);
+ if (*l == NUL || l[STRLEN(l) - 1] != '\\')
+ break;
+ --curwin->w_cursor.lnum;
+ curwin->w_cursor.col = 0;
+ }
+ }
+
+ /*
+ * Get indent and pointer to text for current line,
+ * ignoring any jump label. XXX
+ */
+ if (!curbuf->b_ind_js)
+ cur_amount = skip_label(curwin->w_cursor.lnum, &l);
+ else
+ cur_amount = get_indent();
+ /*
+ * If this is just above the line we are indenting, and it
+ * starts with a '{', line it up with this line.
+ * while (not)
+ * -> {
+ * }
+ */
+ if (terminated != ',' && lookfor != LOOKFOR_TERM
+ && theline[0] == '{') {
+ amount = cur_amount;
+ /*
+ * Only add b_ind_open_extra when the current line
+ * doesn't start with a '{', which must have a match
+ * in the same line (scope is the same). Probably:
+ * { 1, 2 },
+ * -> { 3, 4 }
+ */
+ if (*skipwhite(l) != '{')
+ amount += curbuf->b_ind_open_extra;
+
+ if (curbuf->b_ind_cpp_baseclass) {
+ /* have to look back, whether it is a cpp base
+ * class declaration or initialization */
+ lookfor = LOOKFOR_CPP_BASECLASS;
+ continue;
+ }
+ break;
+ }
+
+ /*
+ * Check if we are after an "if", "while", etc.
+ * Also allow " } else".
+ */
+ if (cin_is_cinword(l) || cin_iselse(skipwhite(l))) {
+ /*
+ * Found an unterminated line after an if (), line up
+ * with the last one.
+ * if (cond)
+ * 100 +
+ * -> here;
+ */
+ if (lookfor == LOOKFOR_UNTERM
+ || lookfor == LOOKFOR_ENUM_OR_INIT) {
+ if (cont_amount > 0)
+ amount = cont_amount;
+ else
+ amount += ind_continuation;
+ break;
+ }
+
+ /*
+ * If this is just above the line we are indenting, we
+ * are finished.
+ * while (not)
+ * -> here;
+ * Otherwise this indent can be used when the line
+ * before this is terminated.
+ * yyy;
+ * if (stat)
+ * while (not)
+ * xxx;
+ * -> here;
+ */
+ amount = cur_amount;
+ if (theline[0] == '{')
+ amount += curbuf->b_ind_open_extra;
+ if (lookfor != LOOKFOR_TERM) {
+ amount += curbuf->b_ind_level
+ + curbuf->b_ind_no_brace;
+ break;
+ }
+
+ /*
+ * Special trick: when expecting the while () after a
+ * do, line up with the while()
+ * do
+ * x = 1;
+ * -> here
+ */
+ l = skipwhite(ml_get_curline());
+ if (cin_isdo(l)) {
+ if (whilelevel == 0)
+ break;
+ --whilelevel;
+ }
+
+ /*
+ * When searching for a terminated line, don't use the
+ * one between the "if" and the matching "else".
+ * Need to use the scope of this "else". XXX
+ * If whilelevel != 0 continue looking for a "do {".
+ */
+ if (cin_iselse(l) && whilelevel == 0) {
+ /* If we're looking at "} else", let's make sure we
+ * find the opening brace of the enclosing scope,
+ * not the one from "if () {". */
+ if (*l == '}')
+ curwin->w_cursor.col =
+ (colnr_T)(l - ml_get_curline()) + 1;
+
+ if ((trypos = find_start_brace()) == NULL
+ || find_match(LOOKFOR_IF, trypos->lnum)
+ == FAIL)
+ break;
+ }
+ }
+ /*
+ * If we're below an unterminated line that is not an
+ * "if" or something, we may line up with this line or
+ * add something for a continuation line, depending on
+ * the line before this one.
+ */
+ else {
+ /*
+ * Found two unterminated lines on a row, line up with
+ * the last one.
+ * c = 99 +
+ * 100 +
+ * -> here;
+ */
+ if (lookfor == LOOKFOR_UNTERM) {
+ /* When line ends in a comma add extra indent */
+ if (terminated == ',')
+ amount += ind_continuation;
+ break;
+ }
+
+ if (lookfor == LOOKFOR_ENUM_OR_INIT) {
+ /* Found two lines ending in ',', lineup with the
+ * lowest one, but check for cpp base class
+ * declaration/initialization, if it is an
+ * opening brace or we are looking just for
+ * enumerations/initializations. */
+ if (terminated == ',') {
+ if (curbuf->b_ind_cpp_baseclass == 0)
+ break;
+
+ lookfor = LOOKFOR_CPP_BASECLASS;
+ continue;
+ }
+
+ /* Ignore unterminated lines in between, but
+ * reduce indent. */
+ if (amount > cur_amount)
+ amount = cur_amount;
+ } else {
+ /*
+ * Found first unterminated line on a row, may
+ * line up with this line, remember its indent
+ * 100 +
+ * -> here;
+ */
+ amount = cur_amount;
+
+ /*
+ * If previous line ends in ',', check whether we
+ * are in an initialization or enum
+ * struct xxx =
+ * {
+ * sizeof a,
+ * 124 };
+ * or a normal possible continuation line.
+ * but only, of no other statement has been found
+ * yet.
+ */
+ if (lookfor == LOOKFOR_INITIAL && terminated == ',') {
+ lookfor = LOOKFOR_ENUM_OR_INIT;
+ cont_amount = cin_first_id_amount();
+ } else {
+ if (lookfor == LOOKFOR_INITIAL
+ && *l != NUL
+ && l[STRLEN(l) - 1] == '\\')
+ /* XXX */
+ cont_amount = cin_get_equal_amount(
+ curwin->w_cursor.lnum);
+ if (lookfor != LOOKFOR_TERM)
+ lookfor = LOOKFOR_UNTERM;
+ }
+ }
+ }
+ }
+ /*
+ * Check if we are after a while (cond);
+ * If so: Ignore until the matching "do".
+ */
+ /* XXX */
+ else if (cin_iswhileofdo_end(terminated)) {
+ /*
+ * Found an unterminated line after a while ();, line up
+ * with the last one.
+ * while (cond);
+ * 100 + <- line up with this one
+ * -> here;
+ */
+ if (lookfor == LOOKFOR_UNTERM
+ || lookfor == LOOKFOR_ENUM_OR_INIT) {
+ if (cont_amount > 0)
+ amount = cont_amount;
+ else
+ amount += ind_continuation;
+ break;
+ }
+
+ if (whilelevel == 0) {
+ lookfor = LOOKFOR_TERM;
+ amount = get_indent(); /* XXX */
+ if (theline[0] == '{')
+ amount += curbuf->b_ind_open_extra;
+ }
+ ++whilelevel;
+ }
+ /*
+ * We are after a "normal" statement.
+ * If we had another statement we can stop now and use the
+ * indent of that other statement.
+ * Otherwise the indent of the current statement may be used,
+ * search backwards for the next "normal" statement.
+ */
+ else {
+ /*
+ * Skip single break line, if before a switch label. It
+ * may be lined up with the case label.
+ */
+ if (lookfor == LOOKFOR_NOBREAK
+ && cin_isbreak(skipwhite(ml_get_curline()))) {
+ lookfor = LOOKFOR_ANY;
+ continue;
+ }
+
+ /*
+ * Handle "do {" line.
+ */
+ if (whilelevel > 0) {
+ l = cin_skipcomment(ml_get_curline());
+ if (cin_isdo(l)) {
+ amount = get_indent(); /* XXX */
+ --whilelevel;
+ continue;
+ }
+ }
+
+ /*
+ * Found a terminated line above an unterminated line. Add
+ * the amount for a continuation line.
+ * x = 1;
+ * y = foo +
+ * -> here;
+ * or
+ * int x = 1;
+ * int foo,
+ * -> here;
+ */
+ if (lookfor == LOOKFOR_UNTERM
+ || lookfor == LOOKFOR_ENUM_OR_INIT) {
+ if (cont_amount > 0)
+ amount = cont_amount;
+ else
+ amount += ind_continuation;
+ break;
+ }
+
+ /*
+ * Found a terminated line above a terminated line or "if"
+ * etc. line. Use the amount of the line below us.
+ * x = 1; x = 1;
+ * if (asdf) y = 2;
+ * while (asdf) ->here;
+ * here;
+ * ->foo;
+ */
+ if (lookfor == LOOKFOR_TERM) {
+ if (!lookfor_break && whilelevel == 0)
+ break;
+ }
+ /*
+ * First line above the one we're indenting is terminated.
+ * To know what needs to be done look further backward for
+ * a terminated line.
+ */
+ else {
+ /*
+ * position the cursor over the rightmost paren, so
+ * that matching it will take us back to the start of
+ * the line. Helps for:
+ * func(asdr,
+ * asdfasdf);
+ * here;
+ */
+term_again:
+ l = ml_get_curline();
+ if (find_last_paren(l, '(', ')')
+ && (trypos = find_match_paren(
+ curbuf->b_ind_maxparen)) != NULL) {
+ /*
+ * Check if we are on a case label now. This is
+ * handled above.
+ * case xx: if ( asdf &&
+ * asdf)
+ */
+ curwin->w_cursor = *trypos;
+ l = ml_get_curline();
+ if (cin_iscase(l, FALSE) || cin_isscopedecl(l)) {
+ ++curwin->w_cursor.lnum;
+ curwin->w_cursor.col = 0;
+ continue;
+ }
+ }
+
+ /* When aligning with the case statement, don't align
+ * with a statement after it.
+ * case 1: { <-- don't use this { position
+ * stat;
+ * }
+ * case 2:
+ * stat;
+ * }
+ */
+ iscase = (curbuf->b_ind_keep_case_label
+ && cin_iscase(l, FALSE));
+
+ /*
+ * Get indent and pointer to text for current line,
+ * ignoring any jump label.
+ */
+ amount = skip_label(curwin->w_cursor.lnum, &l);
+
+ if (theline[0] == '{')
+ amount += curbuf->b_ind_open_extra;
+ /* See remark above: "Only add b_ind_open_extra.." */
+ l = skipwhite(l);
+ if (*l == '{')
+ amount -= curbuf->b_ind_open_extra;
+ lookfor = iscase ? LOOKFOR_ANY : LOOKFOR_TERM;
+
+ /*
+ * When a terminated line starts with "else" skip to
+ * the matching "if":
+ * else 3;
+ * indent this;
+ * Need to use the scope of this "else". XXX
+ * If whilelevel != 0 continue looking for a "do {".
+ */
+ if (lookfor == LOOKFOR_TERM
+ && *l != '}'
+ && cin_iselse(l)
+ && whilelevel == 0) {
+ if ((trypos = find_start_brace()) == NULL
+ || find_match(LOOKFOR_IF, trypos->lnum)
+ == FAIL)
+ break;
+ continue;
+ }
+
+ /*
+ * If we're at the end of a block, skip to the start of
+ * that block.
+ */
+ l = ml_get_curline();
+ if (find_last_paren(l, '{', '}') /* XXX */
+ && (trypos = find_start_brace()) != NULL) {
+ curwin->w_cursor = *trypos;
+ /* if not "else {" check for terminated again */
+ /* but skip block for "} else {" */
+ l = cin_skipcomment(ml_get_curline());
+ if (*l == '}' || !cin_iselse(l))
+ goto term_again;
+ ++curwin->w_cursor.lnum;
+ curwin->w_cursor.col = 0;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /* add extra indent for a comment */
+ if (cin_iscomment(theline))
+ amount += curbuf->b_ind_comment;
+
+ /* subtract extra left-shift for jump labels */
+ if (curbuf->b_ind_jump_label > 0 && original_line_islabel)
+ amount -= curbuf->b_ind_jump_label;
+ }
+ /*
+ * ok -- we're not inside any sort of structure at all!
+ *
+ * this means we're at the top level, and everything should
+ * basically just match where the previous line is, except
+ * for the lines immediately following a function declaration,
+ * which are K&R-style parameters and need to be indented.
+ */
+ else {
+ /*
+ * if our line starts with an open brace, forget about any
+ * prevailing indent and make sure it looks like the start
+ * of a function
+ */
+
+ if (theline[0] == '{') {
+ amount = curbuf->b_ind_first_open;
+ }
+ /*
+ * If the NEXT line is a function declaration, the current
+ * line needs to be indented as a function type spec.
+ * Don't do this if the current line looks like a comment or if the
+ * current line is terminated, ie. ends in ';', or if the current line
+ * contains { or }: "void f() {\n if (1)"
+ */
+ else if (cur_curpos.lnum < curbuf->b_ml.ml_line_count
+ && !cin_nocode(theline)
+ && vim_strchr(theline, '{') == NULL
+ && vim_strchr(theline, '}') == NULL
+ && !cin_ends_in(theline, (char_u *)":", NULL)
+ && !cin_ends_in(theline, (char_u *)",", NULL)
+ && cin_isfuncdecl(NULL, cur_curpos.lnum + 1,
+ cur_curpos.lnum + 1)
+ && !cin_isterminated(theline, FALSE, TRUE)) {
+ amount = curbuf->b_ind_func_type;
+ } else {
+ amount = 0;
+ curwin->w_cursor = cur_curpos;
+
+ /* search backwards until we find something we recognize */
+
+ while (curwin->w_cursor.lnum > 1) {
+ curwin->w_cursor.lnum--;
+ curwin->w_cursor.col = 0;
+
+ l = ml_get_curline();
+
+ /*
+ * If we're in a comment now, skip to the start of the comment.
+ */ /* XXX */
+ if ((trypos = ind_find_start_comment()) != NULL) {
+ curwin->w_cursor.lnum = trypos->lnum + 1;
+ curwin->w_cursor.col = 0;
+ continue;
+ }
+
+ /*
+ * Are we at the start of a cpp base class declaration or
+ * constructor initialization?
+ */ /* XXX */
+ n = FALSE;
+ if (curbuf->b_ind_cpp_baseclass != 0 && theline[0] != '{') {
+ n = cin_is_cpp_baseclass(&col);
+ l = ml_get_curline();
+ }
+ if (n) {
+ /* XXX */
+ amount = get_baseclass_amount(col);
+ break;
+ }
+
+ /*
+ * Skip preprocessor directives and blank lines.
+ */
+ if (cin_ispreproc_cont(&l, &curwin->w_cursor.lnum))
+ continue;
+
+ if (cin_nocode(l))
+ continue;
+
+ /*
+ * If the previous line ends in ',', use one level of
+ * indentation:
+ * int foo,
+ * bar;
+ * do this before checking for '}' in case of eg.
+ * enum foobar
+ * {
+ * ...
+ * } foo,
+ * bar;
+ */
+ n = 0;
+ if (cin_ends_in(l, (char_u *)",", NULL)
+ || (*l != NUL && (n = l[STRLEN(l) - 1]) == '\\')) {
+ /* take us back to opening paren */
+ if (find_last_paren(l, '(', ')')
+ && (trypos = find_match_paren(
+ curbuf->b_ind_maxparen)) != NULL)
+ curwin->w_cursor = *trypos;
+
+ /* For a line ending in ',' that is a continuation line go
+ * back to the first line with a backslash:
+ * char *foo = "bla\
+ * bla",
+ * here;
+ */
+ while (n == 0 && curwin->w_cursor.lnum > 1) {
+ l = ml_get(curwin->w_cursor.lnum - 1);
+ if (*l == NUL || l[STRLEN(l) - 1] != '\\')
+ break;
+ --curwin->w_cursor.lnum;
+ curwin->w_cursor.col = 0;
+ }
+
+ amount = get_indent(); /* XXX */
+
+ if (amount == 0)
+ amount = cin_first_id_amount();
+ if (amount == 0)
+ amount = ind_continuation;
+ break;
+ }
+
+ /*
+ * If the line looks like a function declaration, and we're
+ * not in a comment, put it the left margin.
+ */
+ if (cin_isfuncdecl(NULL, cur_curpos.lnum, 0)) /* XXX */
+ break;
+ l = ml_get_curline();
+
+ /*
+ * Finding the closing '}' of a previous function. Put
+ * current line at the left margin. For when 'cino' has "fs".
+ */
+ if (*skipwhite(l) == '}')
+ break;
+
+ /* (matching {)
+ * If the previous line ends on '};' (maybe followed by
+ * comments) align at column 0. For example:
+ * char *string_array[] = { "foo",
+ * / * x * / "b};ar" }; / * foobar * /
+ */
+ if (cin_ends_in(l, (char_u *)"};", NULL))
+ break;
+
+ /*
+ * Find a line only has a semicolon that belongs to a previous
+ * line ending in '}', e.g. before an #endif. Don't increase
+ * indent then.
+ */
+ if (*(look = skipwhite(l)) == ';' && cin_nocode(look + 1)) {
+ pos_T curpos_save = curwin->w_cursor;
+
+ 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)))
+ break;
+ }
+ if (curwin->w_cursor.lnum > 0
+ && cin_ends_in(look, (char_u *)"}", NULL))
+ break;
+
+ curwin->w_cursor = curpos_save;
+ }
+
+ /*
+ * If the PREVIOUS line is a function declaration, the current
+ * line (and the ones that follow) needs to be indented as
+ * parameters.
+ */
+ if (cin_isfuncdecl(&l, curwin->w_cursor.lnum, 0)) {
+ amount = curbuf->b_ind_param;
+ break;
+ }
+
+ /*
+ * If the previous line ends in ';' and the line before the
+ * previous line ends in ',' or '\', ident to column zero:
+ * int foo,
+ * bar;
+ * indent_to_0 here;
+ */
+ if (cin_ends_in(l, (char_u *)";", NULL)) {
+ l = ml_get(curwin->w_cursor.lnum - 1);
+ if (cin_ends_in(l, (char_u *)",", NULL)
+ || (*l != NUL && l[STRLEN(l) - 1] == '\\'))
+ break;
+ l = ml_get_curline();
+ }
+
+ /*
+ * Doesn't look like anything interesting -- so just
+ * use the indent of this line.
+ *
+ * Position the cursor over the rightmost paren, so that
+ * matching it will take us back to the start of the line.
+ */
+ find_last_paren(l, '(', ')');
+
+ if ((trypos = find_match_paren(curbuf->b_ind_maxparen)) != NULL)
+ curwin->w_cursor = *trypos;
+ amount = get_indent(); /* XXX */
+ break;
+ }
+
+ /* add extra indent for a comment */
+ if (cin_iscomment(theline))
+ amount += curbuf->b_ind_comment;
+
+ /* add extra indent if the previous line ended in a backslash:
+ * "asdfasdf\
+ * here";
+ * char *foo = "asdf\
+ * here";
+ */
+ if (cur_curpos.lnum > 1) {
+ l = ml_get(cur_curpos.lnum - 1);
+ if (*l != NUL && l[STRLEN(l) - 1] == '\\') {
+ cur_amount = cin_get_equal_amount(cur_curpos.lnum - 1);
+ if (cur_amount > 0)
+ amount = cur_amount;
+ else if (cur_amount == 0)
+ amount += ind_continuation;
+ }
+ }
+ }
+ }
+
+theend:
+ /* put the cursor back where it belongs */
+ curwin->w_cursor = cur_curpos;
+
+ vim_free(linecopy);
+
+ if (amount < 0)
+ return 0;
+ return amount;
+}
+
+static int find_match(lookfor, ourscope)
+int lookfor;
+linenr_T ourscope;
+{
+ char_u *look;
+ pos_T *theirscope;
+ char_u *mightbeif;
+ int elselevel;
+ int whilelevel;
+
+ if (lookfor == LOOKFOR_IF) {
+ elselevel = 1;
+ whilelevel = 0;
+ } else {
+ elselevel = 0;
+ whilelevel = 1;
+ }
+
+ curwin->w_cursor.col = 0;
+
+ while (curwin->w_cursor.lnum > ourscope + 1) {
+ curwin->w_cursor.lnum--;
+ curwin->w_cursor.col = 0;
+
+ look = cin_skipcomment(ml_get_curline());
+ if (cin_iselse(look)
+ || cin_isif(look)
+ || cin_isdo(look) /* XXX */
+ || cin_iswhileofdo(look, curwin->w_cursor.lnum)) {
+ /*
+ * if we've gone outside the braces entirely,
+ * we must be out of scope...
+ */
+ theirscope = find_start_brace(); /* XXX */
+ if (theirscope == NULL)
+ break;
+
+ /*
+ * and if the brace enclosing this is further
+ * back than the one enclosing the else, we're
+ * out of luck too.
+ */
+ if (theirscope->lnum < ourscope)
+ break;
+
+ /*
+ * and if they're enclosed in a *deeper* brace,
+ * then we can ignore it because it's in a
+ * different scope...
+ */
+ if (theirscope->lnum > ourscope)
+ continue;
+
+ /*
+ * if it was an "else" (that's not an "else if")
+ * then we need to go back to another if, so
+ * increment elselevel
+ */
+ look = cin_skipcomment(ml_get_curline());
+ if (cin_iselse(look)) {
+ mightbeif = cin_skipcomment(look + 4);
+ if (!cin_isif(mightbeif))
+ ++elselevel;
+ continue;
+ }
+
+ /*
+ * if it was a "while" then we need to go back to
+ * another "do", so increment whilelevel. XXX
+ */
+ if (cin_iswhileofdo(look, curwin->w_cursor.lnum)) {
+ ++whilelevel;
+ continue;
+ }
+
+ /* If it's an "if" decrement elselevel */
+ look = cin_skipcomment(ml_get_curline());
+ if (cin_isif(look)) {
+ elselevel--;
+ /*
+ * When looking for an "if" ignore "while"s that
+ * get in the way.
+ */
+ if (elselevel == 0 && lookfor == LOOKFOR_IF)
+ whilelevel = 0;
+ }
+
+ /* If it's a "do" decrement whilelevel */
+ if (cin_isdo(look))
+ whilelevel--;
+
+ /*
+ * if we've used up all the elses, then
+ * this must be the if that we want!
+ * match the indent level of that if.
+ */
+ if (elselevel <= 0 && whilelevel <= 0) {
+ return OK;
+ }
+ }
+ }
+ return FAIL;
+}
+
+/*
+ * Get indent level from 'indentexpr'.
+ */
+int get_expr_indent() {
+ int indent;
+ pos_T save_pos;
+ colnr_T save_curswant;
+ int save_set_curswant;
+ int save_State;
+ int use_sandbox = was_set_insecurely((char_u *)"indentexpr",
+ OPT_LOCAL);
+
+ /* Save and restore cursor position and curswant, in case it was changed
+ * via :normal commands */
+ save_pos = curwin->w_cursor;
+ save_curswant = curwin->w_curswant;
+ save_set_curswant = curwin->w_set_curswant;
+ set_vim_var_nr(VV_LNUM, curwin->w_cursor.lnum);
+ if (use_sandbox)
+ ++sandbox;
+ ++textlock;
+ indent = eval_to_number(curbuf->b_p_inde);
+ if (use_sandbox)
+ --sandbox;
+ --textlock;
+
+ /* Restore the cursor position so that 'indentexpr' doesn't need to.
+ * Pretend to be in Insert mode, allow cursor past end of line for "o"
+ * command. */
+ save_State = State;
+ State = INSERT;
+ curwin->w_cursor = save_pos;
+ curwin->w_curswant = save_curswant;
+ curwin->w_set_curswant = save_set_curswant;
+ check_cursor();
+ State = save_State;
+
+ /* If there is an error, just keep the current indent. */
+ if (indent < 0)
+ indent = get_indent();
+
+ return indent;
+}
+
+static int lisp_match __ARGS((char_u *p));
+
+static int lisp_match(p)
+char_u *p;
+{
+ char_u buf[LSIZE];
+ int len;
+ char_u *word = p_lispwords;
+
+ while (*word != NUL) {
+ (void)copy_option_part(&word, buf, LSIZE, ",");
+ len = (int)STRLEN(buf);
+ if (STRNCMP(buf, p, len) == 0 && p[len] == ' ')
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*
+ * When 'p' is present in 'cpoptions, a Vi compatible method is used.
+ * The incompatible newer method is quite a bit better at indenting
+ * code in lisp-like languages than the traditional one; it's still
+ * mostly heuristics however -- Dirk van Deun, dirk@rave.org
+ *
+ * TODO:
+ * Findmatch() should be adapted for lisp, also to make showmatch
+ * work correctly: now (v5.3) it seems all C/C++ oriented:
+ * - it does not recognize the #\( and #\) notations as character literals
+ * - it doesn't know about comments starting with a semicolon
+ * - it incorrectly interprets '(' as a character literal
+ * All this messes up get_lisp_indent in some rare cases.
+ * Update from Sergey Khorev:
+ * I tried to fix the first two issues.
+ */
+int get_lisp_indent() {
+ pos_T *pos, realpos, paren;
+ int amount;
+ char_u *that;
+ colnr_T col;
+ colnr_T firsttry;
+ int parencount, quotecount;
+ int vi_lisp;
+
+ /* Set vi_lisp to use the vi-compatible method */
+ vi_lisp = (vim_strchr(p_cpo, CPO_LISP) != NULL);
+
+ realpos = curwin->w_cursor;
+ curwin->w_cursor.col = 0;
+
+ if ((pos = findmatch(NULL, '(')) == NULL)
+ pos = findmatch(NULL, '[');
+ else {
+ paren = *pos;
+ pos = findmatch(NULL, '[');
+ if (pos == NULL || ltp(pos, &paren))
+ pos = &paren;
+ }
+ if (pos != NULL) {
+ /* Extra trick: Take the indent of the first previous non-white
+ * line that is at the same () level. */
+ amount = -1;
+ parencount = 0;
+
+ while (--curwin->w_cursor.lnum >= pos->lnum) {
+ if (linewhite(curwin->w_cursor.lnum))
+ continue;
+ for (that = ml_get_curline(); *that != NUL; ++that) {
+ if (*that == ';') {
+ while (*(that + 1) != NUL)
+ ++that;
+ continue;
+ }
+ if (*that == '\\') {
+ if (*(that + 1) != NUL)
+ ++that;
+ continue;
+ }
+ if (*that == '"' && *(that + 1) != NUL) {
+ while (*++that && *that != '"') {
+ /* skipping escaped characters in the string */
+ if (*that == '\\') {
+ if (*++that == NUL)
+ break;
+ if (that[1] == NUL) {
+ ++that;
+ break;
+ }
+ }
+ }
+ }
+ if (*that == '(' || *that == '[')
+ ++parencount;
+ else if (*that == ')' || *that == ']')
+ --parencount;
+ }
+ if (parencount == 0) {
+ amount = get_indent();
+ break;
+ }
+ }
+
+ if (amount == -1) {
+ curwin->w_cursor.lnum = pos->lnum;
+ curwin->w_cursor.col = pos->col;
+ col = pos->col;
+
+ that = ml_get_curline();
+
+ if (vi_lisp && get_indent() == 0)
+ amount = 2;
+ else {
+ amount = 0;
+ while (*that && col) {
+ amount += lbr_chartabsize_adv(&that, (colnr_T)amount);
+ col--;
+ }
+
+ /*
+ * Some keywords require "body" indenting rules (the
+ * non-standard-lisp ones are Scheme special forms):
+ *
+ * (let ((a 1)) instead (let ((a 1))
+ * (...)) of (...))
+ */
+
+ if (!vi_lisp && (*that == '(' || *that == '[')
+ && lisp_match(that + 1))
+ amount += 2;
+ else {
+ that++;
+ amount++;
+ firsttry = amount;
+
+ while (vim_iswhite(*that)) {
+ amount += lbr_chartabsize(that, (colnr_T)amount);
+ ++that;
+ }
+
+ if (*that && *that != ';') { /* not a comment line */
+ /* test *that != '(' to accommodate first let/do
+ * argument if it is more than one line */
+ if (!vi_lisp && *that != '(' && *that != '[')
+ firsttry++;
+
+ parencount = 0;
+ quotecount = 0;
+
+ if (vi_lisp
+ || (*that != '"'
+ && *that != '\''
+ && *that != '#'
+ && (*that < '0' || *that > '9'))) {
+ while (*that
+ && (!vim_iswhite(*that)
+ || quotecount
+ || parencount)
+ && (!((*that == '(' || *that == '[')
+ && !quotecount
+ && !parencount
+ && vi_lisp))) {
+ if (*that == '"')
+ quotecount = !quotecount;
+ if ((*that == '(' || *that == '[')
+ && !quotecount)
+ ++parencount;
+ if ((*that == ')' || *that == ']')
+ && !quotecount)
+ --parencount;
+ if (*that == '\\' && *(that+1) != NUL)
+ amount += lbr_chartabsize_adv(&that,
+ (colnr_T)amount);
+ amount += lbr_chartabsize_adv(&that,
+ (colnr_T)amount);
+ }
+ }
+ while (vim_iswhite(*that)) {
+ amount += lbr_chartabsize(that, (colnr_T)amount);
+ that++;
+ }
+ if (!*that || *that == ';')
+ amount = firsttry;
+ }
+ }
+ }
+ }
+ } else
+ amount = 0; /* no matching '(' or '[' found, use zero indent */
+
+ curwin->w_cursor = realpos;
+
+ return amount;
+}
+
+void prepare_to_exit() {
+#if defined(SIGHUP) && defined(SIG_IGN)
+ /* Ignore SIGHUP, because a dropped connection causes a read error, which
+ * makes Vim exit and then handling SIGHUP causes various reentrance
+ * problems. */
+ signal(SIGHUP, SIG_IGN);
+#endif
+
+ {
+ windgoto((int)Rows - 1, 0);
+
+ /*
+ * Switch terminal mode back now, so messages end up on the "normal"
+ * screen (if there are two screens).
+ */
+ settmode(TMODE_COOK);
+ stoptermcap();
+ out_flush();
+ }
+}
+
+/*
+ * 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.
+ */
+void preserve_exit() {
+ buf_T *buf;
+
+ prepare_to_exit();
+
+ /* Setting this will prevent free() calls. That avoids calling free()
+ * recursively when free() was invoked with a bad pointer. */
+ really_exiting = TRUE;
+
+ out_str(IObuff);
+ screen_start(); /* don't know where cursor is now */
+ out_flush();
+
+ ml_close_notmod(); /* close all not-modified buffers */
+
+ for (buf = firstbuf; buf != NULL; buf = buf->b_next) {
+ if (buf->b_ml.ml_mfp != NULL && buf->b_ml.ml_mfp->mf_fname != NULL) {
+ OUT_STR("Vim: preserving files...\n");
+ screen_start(); /* don't know where cursor is now */
+ out_flush();
+ ml_sync_all(FALSE, FALSE); /* preserve all swap files */
+ break;
+ }
+ }
+
+ ml_close_all(FALSE); /* close all memfiles, without deleting */
+
+ OUT_STR("Vim: Finished.\n");
+
+ getout(1);
+}
+
+/*
+ * return TRUE if "fname" exists.
+ */
+int vim_fexists(fname)
+char_u *fname;
+{
+ struct stat st;
+
+ if (mch_stat((char *)fname, &st))
+ return FALSE;
+ return TRUE;
+}
+
+/*
+ * Check for CTRL-C pressed, but only once in a while.
+ * Should be used instead of ui_breakcheck() for functions that check for
+ * each line in the file. Calling ui_breakcheck() each time takes too much
+ * time, because it can be a system call.
+ */
+
+#ifndef BREAKCHECK_SKIP
+# define BREAKCHECK_SKIP 32
+#endif
+
+static int breakcheck_count = 0;
+
+void line_breakcheck() {
+ if (++breakcheck_count >= BREAKCHECK_SKIP) {
+ breakcheck_count = 0;
+ ui_breakcheck();
+ }
+}
+
+/*
+ * Like line_breakcheck() but check 10 times less often.
+ */
+void fast_breakcheck() {
+ if (++breakcheck_count >= BREAKCHECK_SKIP * 10) {
+ breakcheck_count = 0;
+ ui_breakcheck();
+ }
+}
+
+/*
+ * Invoke expand_wildcards() for one pattern.
+ * Expand items like "%:h" before the expansion.
+ * Returns OK or FAIL.
+ */
+int expand_wildcards_eval(pat, num_file, file, flags)
+char_u **pat; /* pointer to input pattern */
+int *num_file; /* resulting number of files */
+char_u ***file; /* array of resulting files */
+int flags; /* EW_DIR, etc. */
+{
+ int ret = FAIL;
+ char_u *eval_pat = NULL;
+ char_u *exp_pat = *pat;
+ char_u *ignored_msg;
+ int usedlen;
+
+ if (*exp_pat == '%' || *exp_pat == '#' || *exp_pat == '<') {
+ ++emsg_off;
+ eval_pat = eval_vars(exp_pat, exp_pat, &usedlen,
+ NULL, &ignored_msg, NULL);
+ --emsg_off;
+ if (eval_pat != NULL)
+ exp_pat = concat_str(eval_pat, exp_pat + usedlen);
+ }
+
+ if (exp_pat != NULL)
+ ret = expand_wildcards(1, &exp_pat, num_file, file, flags);
+
+ if (eval_pat != NULL) {
+ vim_free(exp_pat);
+ vim_free(eval_pat);
+ }
+
+ return ret;
+}
+
+/*
+ * Expand wildcards. Calls gen_expand_wildcards() and removes files matching
+ * 'wildignore'.
+ * Returns OK or FAIL. When FAIL then "num_file" won't be set.
+ */
+int expand_wildcards(num_pat, pat, num_file, file, flags)
+int num_pat; /* number of input patterns */
+char_u **pat; /* array of input patterns */
+int *num_file; /* resulting number of files */
+char_u ***file; /* array of resulting files */
+int flags; /* EW_DIR, etc. */
+{
+ int retval;
+ int i, j;
+ char_u *p;
+ int non_suf_match; /* number without matching suffix */
+
+ retval = gen_expand_wildcards(num_pat, pat, num_file, file, flags);
+
+ /* When keeping all matches, return here */
+ if ((flags & EW_KEEPALL) || retval == FAIL)
+ return retval;
+
+ /*
+ * Remove names that match 'wildignore'.
+ */
+ if (*p_wig) {
+ char_u *ffname;
+
+ /* check all files in (*file)[] */
+ for (i = 0; i < *num_file; ++i) {
+ ffname = FullName_save((*file)[i], FALSE);
+ if (ffname == NULL) /* out of memory */
+ break;
+ if (match_file_list(p_wig, (*file)[i], ffname)) {
+ /* remove this matching file from the list */
+ vim_free((*file)[i]);
+ for (j = i; j + 1 < *num_file; ++j)
+ (*file)[j] = (*file)[j + 1];
+ --*num_file;
+ --i;
+ }
+ vim_free(ffname);
+ }
+ }
+
+ /*
+ * Move the names where 'suffixes' match to the end.
+ */
+ if (*num_file > 1) {
+ non_suf_match = 0;
+ for (i = 0; i < *num_file; ++i) {
+ if (!match_suffix((*file)[i])) {
+ /*
+ * Move the name without matching suffix to the front
+ * of the list.
+ */
+ p = (*file)[i];
+ for (j = i; j > non_suf_match; --j)
+ (*file)[j] = (*file)[j - 1];
+ (*file)[non_suf_match++] = p;
+ }
+ }
+ }
+
+ return retval;
+}
+
+/*
+ * Return TRUE if "fname" matches with an entry in 'suffixes'.
+ */
+int match_suffix(fname)
+char_u *fname;
+{
+ int fnamelen, setsuflen;
+ char_u *setsuf;
+#define MAXSUFLEN 30 /* maximum length of a file suffix */
+ char_u suf_buf[MAXSUFLEN];
+
+ fnamelen = (int)STRLEN(fname);
+ setsuflen = 0;
+ for (setsuf = p_su; *setsuf; ) {
+ setsuflen = copy_option_part(&setsuf, suf_buf, MAXSUFLEN, ".,");
+ if (setsuflen == 0) {
+ char_u *tail = gettail(fname);
+
+ /* empty entry: match name without a '.' */
+ if (vim_strchr(tail, '.') == NULL) {
+ setsuflen = 1;
+ break;
+ }
+ } else {
+ if (fnamelen >= setsuflen
+ && fnamencmp(suf_buf, fname + fnamelen - setsuflen,
+ (size_t)setsuflen) == 0)
+ break;
+ setsuflen = 0;
+ }
+ }
+ return setsuflen != 0;
+}
+
+#if !defined(NO_EXPANDPATH) || defined(PROTO)
+
+static int vim_backtick __ARGS((char_u *p));
+static int expand_backtick __ARGS((garray_T *gap, char_u *pat, int flags));
+
+
+#if (defined(UNIX) && !defined(VMS)) || defined(USE_UNIXFILENAME) \
+ || defined(PROTO)
+/*
+ * Unix style wildcard expansion code.
+ * It's here because it's used both for Unix and Mac.
+ */
+static int pstrcmp __ARGS((const void *, const void *));
+
+static int pstrcmp(a, b)
+const void *a, *b;
+{
+ return pathcmp(*(char **)a, *(char **)b, -1);
+}
+
+/*
+ * Recursively expand one path component into all matching files and/or
+ * directories. Adds matches to "gap". Handles "*", "?", "[a-z]", "**", etc.
+ * "path" has backslashes before chars that are not to be expanded, starting
+ * at "path + wildoff".
+ * Return the number of matches found.
+ * NOTE: much of this is identical to dos_expandpath(), keep in sync!
+ */
+int unix_expandpath(gap, path, wildoff, flags, didstar)
+garray_T *gap;
+char_u *path;
+int wildoff;
+int flags; /* EW_* flags */
+int didstar; /* expanded "**" once already */
+{
+ char_u *buf;
+ char_u *path_end;
+ char_u *p, *s, *e;
+ int start_len = gap->ga_len;
+ char_u *pat;
+ regmatch_T regmatch;
+ int starts_with_dot;
+ int matches;
+ int len;
+ int starstar = FALSE;
+ static int stardepth = 0; /* depth for "**" expansion */
+
+ DIR *dirp;
+ struct dirent *dp;
+
+ /* Expanding "**" may take a long time, check for CTRL-C. */
+ if (stardepth > 0) {
+ ui_breakcheck();
+ if (got_int)
+ return 0;
+ }
+
+ /* make room for file name */
+ buf = alloc((int)STRLEN(path) + BASENAMELEN + 5);
+ if (buf == NULL)
+ return 0;
+
+ /*
+ * Find the first part in the path name that contains a wildcard.
+ * When EW_ICASE is set every letter is considered to be a wildcard.
+ * Copy it into "buf", including the preceding characters.
+ */
+ p = buf;
+ s = buf;
+ e = NULL;
+ path_end = path;
+ while (*path_end != NUL) {
+ /* May ignore a wildcard that has a backslash before it; it will
+ * be removed by rem_backslash() or file_pat_to_reg_pat() below. */
+ if (path_end >= path + wildoff && rem_backslash(path_end))
+ *p++ = *path_end++;
+ else if (*path_end == '/') {
+ if (e != NULL)
+ break;
+ s = p + 1;
+ } else if (path_end >= path + wildoff
+ && (vim_strchr((char_u *)"*?[{~$", *path_end) != NULL
+ || (!p_fic && (flags & EW_ICASE)
+ && isalpha(PTR2CHAR(path_end)))))
+ e = p;
+ if (has_mbyte) {
+ len = (*mb_ptr2len)(path_end);
+ STRNCPY(p, path_end, len);
+ p += len;
+ path_end += len;
+ } else
+ *p++ = *path_end++;
+ }
+ e = p;
+ *e = NUL;
+
+ /* Now we have one wildcard component between "s" and "e". */
+ /* Remove backslashes between "wildoff" and the start of the wildcard
+ * component. */
+ for (p = buf + wildoff; p < s; ++p)
+ if (rem_backslash(p)) {
+ STRMOVE(p, p + 1);
+ --e;
+ --s;
+ }
+
+ /* Check for "**" between "s" and "e". */
+ for (p = s; p < e; ++p)
+ if (p[0] == '*' && p[1] == '*')
+ starstar = TRUE;
+
+ /* convert the file pattern to a regexp pattern */
+ starts_with_dot = (*s == '.');
+ pat = file_pat_to_reg_pat(s, e, NULL, FALSE);
+ if (pat == NULL) {
+ vim_free(buf);
+ return 0;
+ }
+
+ /* compile the regexp into a program */
+ if (flags & EW_ICASE)
+ regmatch.rm_ic = TRUE; /* 'wildignorecase' set */
+ else
+ regmatch.rm_ic = p_fic; /* ignore case when 'fileignorecase' is set */
+ if (flags & (EW_NOERROR | EW_NOTWILD))
+ ++emsg_silent;
+ regmatch.regprog = vim_regcomp(pat, RE_MAGIC);
+ if (flags & (EW_NOERROR | EW_NOTWILD))
+ --emsg_silent;
+ vim_free(pat);
+
+ if (regmatch.regprog == NULL && (flags & EW_NOTWILD) == 0) {
+ vim_free(buf);
+ return 0;
+ }
+
+ /* If "**" is by itself, this is the first time we encounter it and more
+ * is following then find matches without any directory. */
+ if (!didstar && stardepth < 100 && starstar && e - s == 2
+ && *path_end == '/') {
+ STRCPY(s, path_end + 1);
+ ++stardepth;
+ (void)unix_expandpath(gap, buf, (int)(s - buf), flags, TRUE);
+ --stardepth;
+ }
+
+ /* open the directory for scanning */
+ *s = NUL;
+ dirp = opendir(*buf == NUL ? "." : (char *)buf);
+
+ /* Find all matching entries */
+ if (dirp != NULL) {
+ for (;; ) {
+ dp = readdir(dirp);
+ if (dp == NULL)
+ break;
+ if ((dp->d_name[0] != '.' || starts_with_dot)
+ && ((regmatch.regprog != NULL && vim_regexec(&regmatch,
+ (char_u *)dp->d_name, (colnr_T)0))
+ || ((flags & EW_NOTWILD)
+ && fnamencmp(path + (s - buf), dp->d_name, e - s) == 0))) {
+ STRCPY(s, dp->d_name);
+ len = STRLEN(buf);
+
+ if (starstar && stardepth < 100) {
+ /* For "**" in the pattern first go deeper in the tree to
+ * find matches. */
+ STRCPY(buf + len, "/**");
+ STRCPY(buf + len + 3, path_end);
+ ++stardepth;
+ (void)unix_expandpath(gap, buf, len + 1, flags, TRUE);
+ --stardepth;
+ }
+
+ STRCPY(buf + len, path_end);
+ if (mch_has_exp_wildcard(path_end)) { /* handle more wildcards */
+ /* need to expand another component of the path */
+ /* remove backslashes for the remaining components only */
+ (void)unix_expandpath(gap, buf, len + 1, flags, FALSE);
+ } else {
+ /* no more wildcards, check if there is a match */
+ /* remove backslashes for the remaining components only */
+ if (*path_end != NUL)
+ backslash_halve(buf + len + 1);
+ if (mch_getperm(buf) >= 0) { /* add existing file */
+#ifdef MACOS_CONVERT
+ size_t precomp_len = STRLEN(buf)+1;
+ char_u *precomp_buf =
+ mac_precompose_path(buf, precomp_len, &precomp_len);
+
+ if (precomp_buf) {
+ mch_memmove(buf, precomp_buf, precomp_len);
+ vim_free(precomp_buf);
+ }
+#endif
+ addfile(gap, buf, flags);
+ }
+ }
+ }
+ }
+
+ closedir(dirp);
+ }
+
+ vim_free(buf);
+ vim_regfree(regmatch.regprog);
+
+ matches = gap->ga_len - start_len;
+ if (matches > 0)
+ qsort(((char_u **)gap->ga_data) + start_len, matches,
+ sizeof(char_u *), pstrcmp);
+ return matches;
+}
+#endif
+
+static int find_previous_pathsep __ARGS((char_u *path, char_u **psep));
+static int is_unique __ARGS((char_u *maybe_unique, garray_T *gap, int i));
+static void expand_path_option __ARGS((char_u *curdir, garray_T *gap));
+static char_u *get_path_cutoff __ARGS((char_u *fname, garray_T *gap));
+static void uniquefy_paths __ARGS((garray_T *gap, char_u *pattern));
+static int expand_in_path __ARGS((garray_T *gap, char_u *pattern, int flags));
+
+/*
+ * Moves "*psep" back to the previous path separator in "path".
+ * Returns FAIL is "*psep" ends up at the beginning of "path".
+ */
+static int find_previous_pathsep(path, psep)
+char_u *path;
+char_u **psep;
+{
+ /* skip the current separator */
+ if (*psep > path && vim_ispathsep(**psep))
+ --*psep;
+
+ /* find the previous separator */
+ while (*psep > path) {
+ if (vim_ispathsep(**psep))
+ return OK;
+ mb_ptr_back(path, *psep);
+ }
+
+ return FAIL;
+}
+
+/*
+ * Returns TRUE if "maybe_unique" is unique wrt other_paths in "gap".
+ * "maybe_unique" is the end portion of "((char_u **)gap->ga_data)[i]".
+ */
+static int is_unique(maybe_unique, gap, i)
+char_u *maybe_unique;
+garray_T *gap;
+int i;
+{
+ int j;
+ int candidate_len;
+ int other_path_len;
+ char_u **other_paths = (char_u **)gap->ga_data;
+ char_u *rival;
+
+ for (j = 0; j < gap->ga_len; j++) {
+ if (j == i)
+ continue; /* don't compare it with itself */
+
+ candidate_len = (int)STRLEN(maybe_unique);
+ other_path_len = (int)STRLEN(other_paths[j]);
+ if (other_path_len < candidate_len)
+ continue; /* it's different when it's shorter */
+
+ rival = other_paths[j] + other_path_len - candidate_len;
+ if (fnamecmp(maybe_unique, rival) == 0
+ && (rival == other_paths[j] || vim_ispathsep(*(rival - 1))))
+ return FALSE; /* match */
+ }
+
+ return TRUE; /* no match found */
+}
+
+/*
+ * Split the 'path' option into an array of strings in garray_T. Relative
+ * paths are expanded to their equivalent fullpath. This includes the "."
+ * (relative to current buffer directory) and empty path (relative to current
+ * directory) notations.
+ *
+ * TODO: handle upward search (;) and path limiter (**N) notations by
+ * expanding each into their equivalent path(s).
+ */
+static void expand_path_option(curdir, gap)
+char_u *curdir;
+garray_T *gap;
+{
+ char_u *path_option = *curbuf->b_p_path == NUL
+ ? p_path : curbuf->b_p_path;
+ char_u *buf;
+ char_u *p;
+ int len;
+
+ if ((buf = alloc((int)MAXPATHL)) == NULL)
+ return;
+
+ while (*path_option != NUL) {
+ copy_option_part(&path_option, buf, MAXPATHL, " ,");
+
+ if (buf[0] == '.' && (buf[1] == NUL || vim_ispathsep(buf[1]))) {
+ /* Relative to current buffer:
+ * "/path/file" + "." -> "/path/"
+ * "/path/file" + "./subdir" -> "/path/subdir" */
+ if (curbuf->b_ffname == NULL)
+ continue;
+ p = gettail(curbuf->b_ffname);
+ len = (int)(p - curbuf->b_ffname);
+ if (len + (int)STRLEN(buf) >= MAXPATHL)
+ continue;
+ if (buf[1] == NUL)
+ buf[len] = NUL;
+ else
+ STRMOVE(buf + len, buf + 2);
+ mch_memmove(buf, curbuf->b_ffname, len);
+ simplify_filename(buf);
+ } else if (buf[0] == NUL)
+ /* relative to current directory */
+ STRCPY(buf, curdir);
+ else if (path_with_url(buf))
+ /* URL can't be used here */
+ continue;
+ else if (!mch_isFullName(buf)) {
+ /* Expand relative path to their full path equivalent */
+ len = (int)STRLEN(curdir);
+ if (len + (int)STRLEN(buf) + 3 > MAXPATHL)
+ continue;
+ STRMOVE(buf + len + 1, buf);
+ STRCPY(buf, curdir);
+ buf[len] = PATHSEP;
+ simplify_filename(buf);
+ }
+
+ if (ga_grow(gap, 1) == FAIL)
+ break;
+
+
+ p = vim_strsave(buf);
+ if (p == NULL)
+ break;
+ ((char_u **)gap->ga_data)[gap->ga_len++] = p;
+ }
+
+ vim_free(buf);
+}
+
+/*
+ * Returns a pointer to the file or directory name in "fname" that matches the
+ * longest path in "ga"p, or NULL if there is no match. For example:
+ *
+ * path: /foo/bar/baz
+ * fname: /foo/bar/baz/quux.txt
+ * returns: ^this
+ */
+static char_u * get_path_cutoff(fname, gap)
+char_u *fname;
+garray_T *gap;
+{
+ int i;
+ int maxlen = 0;
+ char_u **path_part = (char_u **)gap->ga_data;
+ char_u *cutoff = NULL;
+
+ for (i = 0; i < gap->ga_len; i++) {
+ int j = 0;
+
+ while ((fname[j] == path_part[i][j]
+ ) && fname[j] != NUL && path_part[i][j] != NUL)
+ j++;
+ if (j > maxlen) {
+ maxlen = j;
+ cutoff = &fname[j];
+ }
+ }
+
+ /* skip to the file or directory name */
+ if (cutoff != NULL)
+ while (vim_ispathsep(*cutoff))
+ mb_ptr_adv(cutoff);
+
+ return cutoff;
+}
+
+/*
+ * Sorts, removes duplicates and modifies all the fullpath names in "gap" so
+ * that they are unique with respect to each other while conserving the part
+ * that matches the pattern. Beware, this is at least O(n^2) wrt "gap->ga_len".
+ */
+static void uniquefy_paths(gap, pattern)
+garray_T *gap;
+char_u *pattern;
+{
+ int i;
+ int len;
+ char_u **fnames = (char_u **)gap->ga_data;
+ int sort_again = FALSE;
+ char_u *pat;
+ char_u *file_pattern;
+ char_u *curdir;
+ regmatch_T regmatch;
+ garray_T path_ga;
+ char_u **in_curdir = NULL;
+ char_u *short_name;
+
+ remove_duplicates(gap);
+ ga_init2(&path_ga, (int)sizeof(char_u *), 1);
+
+ /*
+ * We need to prepend a '*' at the beginning of file_pattern so that the
+ * regex matches anywhere in the path. FIXME: is this valid for all
+ * possible patterns?
+ */
+ len = (int)STRLEN(pattern);
+ file_pattern = alloc(len + 2);
+ if (file_pattern == NULL)
+ return;
+ file_pattern[0] = '*';
+ file_pattern[1] = NUL;
+ STRCAT(file_pattern, pattern);
+ pat = file_pat_to_reg_pat(file_pattern, NULL, NULL, TRUE);
+ vim_free(file_pattern);
+ if (pat == NULL)
+ return;
+
+ regmatch.rm_ic = TRUE; /* always ignore case */
+ regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING);
+ vim_free(pat);
+ if (regmatch.regprog == NULL)
+ return;
+
+ if ((curdir = alloc((int)(MAXPATHL))) == NULL)
+ goto theend;
+ mch_dirname(curdir, MAXPATHL);
+ expand_path_option(curdir, &path_ga);
+
+ in_curdir = (char_u **)alloc_clear(gap->ga_len * sizeof(char_u *));
+ if (in_curdir == NULL)
+ goto theend;
+
+ for (i = 0; i < gap->ga_len && !got_int; i++) {
+ char_u *path = fnames[i];
+ int is_in_curdir;
+ char_u *dir_end = gettail_dir(path);
+ char_u *pathsep_p;
+ char_u *path_cutoff;
+
+ len = (int)STRLEN(path);
+ is_in_curdir = fnamencmp(curdir, path, dir_end - path) == 0
+ && curdir[dir_end - path] == NUL;
+ if (is_in_curdir)
+ in_curdir[i] = vim_strsave(path);
+
+ /* 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;
+ mch_memmove(path, pathsep_p + 1, STRLEN(pathsep_p));
+ break;
+ }
+
+ if (mch_isFullName(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 = shorten_fname(path, curdir);
+ if (short_name != NULL && short_name > path + 1
+ ) {
+ STRCPY(path, ".");
+ add_pathsep(path);
+ STRMOVE(path + STRLEN(path), short_name);
+ }
+ }
+ ui_breakcheck();
+ }
+
+ /* Shorten filenames in /in/current/directory/{filename} */
+ for (i = 0; i < gap->ga_len && !got_int; i++) {
+ char_u *rel_path;
+ char_u *path = in_curdir[i];
+
+ if (path == NULL)
+ continue;
+
+ /* If the {filename} is not unique, change it to ./{filename}.
+ * Else reduce it to {filename} */
+ short_name = shorten_fname(path, curdir);
+ if (short_name == NULL)
+ short_name = path;
+ if (is_unique(short_name, gap, i)) {
+ STRCPY(fnames[i], short_name);
+ continue;
+ }
+
+ rel_path = alloc((int)(STRLEN(short_name) + STRLEN(PATHSEPSTR) + 2));
+ if (rel_path == NULL)
+ goto theend;
+ STRCPY(rel_path, ".");
+ add_pathsep(rel_path);
+ STRCAT(rel_path, short_name);
+
+ vim_free(fnames[i]);
+ fnames[i] = rel_path;
+ sort_again = TRUE;
+ ui_breakcheck();
+ }
+
+theend:
+ vim_free(curdir);
+ if (in_curdir != NULL) {
+ for (i = 0; i < gap->ga_len; i++)
+ vim_free(in_curdir[i]);
+ vim_free(in_curdir);
+ }
+ ga_clear_strings(&path_ga);
+ vim_regfree(regmatch.regprog);
+
+ if (sort_again)
+ remove_duplicates(gap);
+}
+
+/*
+ * Calls globpath() with 'path' values for the given pattern and stores the
+ * result in "gap".
+ * Returns the total number of matches.
+ */
+static int expand_in_path(gap, pattern, flags)
+garray_T *gap;
+char_u *pattern;
+int flags; /* EW_* flags */
+{
+ char_u *curdir;
+ garray_T path_ga;
+ char_u *files = NULL;
+ char_u *s; /* start */
+ char_u *e; /* end */
+ char_u *paths = NULL;
+
+ if ((curdir = alloc((unsigned)MAXPATHL)) == NULL)
+ return 0;
+ mch_dirname(curdir, MAXPATHL);
+
+ ga_init2(&path_ga, (int)sizeof(char_u *), 1);
+ expand_path_option(curdir, &path_ga);
+ vim_free(curdir);
+ if (path_ga.ga_len == 0)
+ return 0;
+
+ paths = ga_concat_strings(&path_ga);
+ ga_clear_strings(&path_ga);
+ if (paths == NULL)
+ return 0;
+
+ files = globpath(paths, pattern, (flags & EW_ICASE) ? WILD_ICASE : 0);
+ vim_free(paths);
+ if (files == NULL)
+ return 0;
+
+ /* Copy each path in files into gap */
+ s = e = files;
+ while (*s != NUL) {
+ while (*e != '\n' && *e != NUL)
+ e++;
+ if (*e == NUL) {
+ addfile(gap, s, flags);
+ break;
+ } else {
+ /* *e is '\n' */
+ *e = NUL;
+ addfile(gap, s, flags);
+ e++;
+ s = e;
+ }
+ }
+ vim_free(files);
+
+ return gap->ga_len;
+}
+
+/*
+ * Sort "gap" and remove duplicate entries. "gap" is expected to contain a
+ * list of file names in allocated memory.
+ */
+void remove_duplicates(gap)
+garray_T *gap;
+{
+ int i;
+ int j;
+ char_u **fnames = (char_u **)gap->ga_data;
+
+ sort_strings(fnames, gap->ga_len);
+ for (i = gap->ga_len - 1; i > 0; --i)
+ if (fnamecmp(fnames[i - 1], fnames[i]) == 0) {
+ vim_free(fnames[i]);
+ for (j = i + 1; j < gap->ga_len; ++j)
+ fnames[j - 1] = fnames[j];
+ --gap->ga_len;
+ }
+}
+
+static int has_env_var __ARGS((char_u *p));
+
+/*
+ * Return TRUE if "p" contains what looks like an environment variable.
+ * Allowing for escaping.
+ */
+static int has_env_var(p)
+char_u *p;
+{
+ 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
+static int has_special_wildchar __ARGS((char_u *p));
+
+/*
+ * Return TRUE if "p" contains a special wildcard character.
+ * Allowing for escaping.
+ */
+static int has_special_wildchar(p)
+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)
+ return TRUE;
+ }
+ return FALSE;
+}
+#endif
+
+/*
+ * Generic wildcard expansion code.
+ *
+ * Characters in "pat" that should not be expanded must be preceded with a
+ * backslash. E.g., "/path\ with\ spaces/my\*star*"
+ *
+ * Return FAIL when no single file was found. In this case "num_file" is not
+ * set, and "file" may contain an error message.
+ * Return OK when some files found. "num_file" is set to the number of
+ * matches, "file" to the array of matches. Call FreeWild() later.
+ */
+int gen_expand_wildcards(num_pat, pat, num_file, file, flags)
+int num_pat; /* number of input patterns */
+char_u **pat; /* array of input patterns */
+int *num_file; /* resulting number of files */
+char_u ***file; /* array of resulting files */
+int flags; /* EW_* flags */
+{
+ int i;
+ garray_T ga;
+ char_u *p;
+ static int recursive = FALSE;
+ int add_pat;
+ int did_expand_in_path = FALSE;
+
+ /*
+ * expand_env() is called to expand things like "~user". If this fails,
+ * it calls ExpandOne(), which brings us back here. In this case, always
+ * call the machine specific expansion function, if possible. Otherwise,
+ * return FAIL.
+ */
+ if (recursive)
+#ifdef SPECIAL_WILDCHAR
+ return mch_expand_wildcards(num_pat, pat, num_file, file, flags);
+#else
+ return FAIL;
+#endif
+
+#ifdef SPECIAL_WILDCHAR
+ /*
+ * If there are any special wildcard characters which we cannot handle
+ * here, call machine specific function for all the expansion. This
+ * avoids starting the shell for each argument separately.
+ * For `=expr` do use the internal function.
+ */
+ for (i = 0; i < num_pat; i++) {
+ if (has_special_wildchar(pat[i])
+ && !(vim_backtick(pat[i]) && pat[i][1] == '=')
+ )
+ return mch_expand_wildcards(num_pat, pat, num_file, file, flags);
+ }
+#endif
+
+ recursive = TRUE;
+
+ /*
+ * The matching file names are stored in a growarray. Init it empty.
+ */
+ ga_init2(&ga, (int)sizeof(char_u *), 30);
+
+ for (i = 0; i < num_pat; ++i) {
+ add_pat = -1;
+ p = pat[i];
+
+ if (vim_backtick(p))
+ add_pat = expand_backtick(&ga, p, flags);
+ else {
+ /*
+ * First expand environment variables, "~/" and "~user/".
+ */
+ if (has_env_var(p) || *p == '~') {
+ p = expand_env_save_opt(p, TRUE);
+ if (p == NULL)
+ p = pat[i];
+#ifdef UNIX
+ /*
+ * On Unix, if expand_env() can't expand an environment
+ * variable, use the shell to do that. Discard previously
+ * found file names and start all over again.
+ */
+ else if (has_env_var(p) || *p == '~') {
+ vim_free(p);
+ ga_clear_strings(&ga);
+ i = mch_expand_wildcards(num_pat, pat, num_file, file,
+ flags);
+ recursive = FALSE;
+ return i;
+ }
+#endif
+ }
+
+ /*
+ * If there are wildcards: Expand file names and add each match to
+ * the list. If there is no match, and EW_NOTFOUND is given, add
+ * the pattern.
+ * If there are no wildcards: Add the file name if it exists or
+ * when EW_NOTFOUND is given.
+ */
+ if (mch_has_exp_wildcard(p)) {
+ if ((flags & EW_PATH)
+ && !mch_isFullName(p)
+ && !(p[0] == '.'
+ && (vim_ispathsep(p[1])
+ || (p[1] == '.' && vim_ispathsep(p[2]))))
+ ) {
+ /* :find completion where 'path' is used.
+ * Recursiveness is OK here. */
+ recursive = FALSE;
+ add_pat = expand_in_path(&ga, p, flags);
+ recursive = TRUE;
+ did_expand_in_path = TRUE;
+ } else
+ add_pat = mch_expandpath(&ga, p, flags);
+ }
+ }
+
+ if (add_pat == -1 || (add_pat == 0 && (flags & EW_NOTFOUND))) {
+ char_u *t = backslash_halve_save(p);
+
+ /* When EW_NOTFOUND is used, always add files and dirs. Makes
+ * "vim c:/" work. */
+ if (flags & EW_NOTFOUND)
+ addfile(&ga, t, flags | EW_DIR | EW_FILE);
+ else if (mch_getperm(t) >= 0)
+ addfile(&ga, t, flags);
+ vim_free(t);
+ }
+
+ if (did_expand_in_path && ga.ga_len > 0 && (flags & EW_PATH))
+ uniquefy_paths(&ga, p);
+ if (p != pat[i])
+ vim_free(p);
+ }
+
+ *num_file = ga.ga_len;
+ *file = (ga.ga_data != NULL) ? (char_u **)ga.ga_data : (char_u **)"";
+
+ recursive = FALSE;
+
+ return (ga.ga_data != NULL) ? OK : FAIL;
+}
+
+
+/*
+ * Return TRUE if we can expand this backtick thing here.
+ */
+static int vim_backtick(p)
+char_u *p;
+{
+ return *p == '`' && *(p + 1) != NUL && *(p + STRLEN(p) - 1) == '`';
+}
+
+/*
+ * Expand an item in `backticks` by executing it as a command.
+ * Currently only works when pat[] starts and ends with a `.
+ * Returns number of file names found.
+ */
+static int expand_backtick(gap, pat, flags)
+garray_T *gap;
+char_u *pat;
+int flags; /* EW_* flags */
+{
+ char_u *p;
+ char_u *cmd;
+ char_u *buffer;
+ int cnt = 0;
+ int i;
+
+ /* Create the command: lop off the backticks. */
+ cmd = vim_strnsave(pat + 1, (int)STRLEN(pat) - 2);
+ if (cmd == NULL)
+ return 0;
+
+ if (*cmd == '=') /* `={expr}`: Expand expression */
+ buffer = eval_to_string(cmd + 1, &p, TRUE);
+ else
+ buffer = get_cmd_output(cmd, NULL,
+ (flags & EW_SILENT) ? SHELL_SILENT : 0);
+ vim_free(cmd);
+ if (buffer == NULL)
+ return 0;
+
+ cmd = buffer;
+ while (*cmd != NUL) {
+ cmd = skipwhite(cmd); /* skip over white space */
+ p = cmd;
+ while (*p != NUL && *p != '\r' && *p != '\n') /* skip over entry */
+ ++p;
+ /* add an entry if it is not empty */
+ if (p > cmd) {
+ i = *p;
+ *p = NUL;
+ addfile(gap, cmd, flags);
+ *p = i;
+ ++cnt;
+ }
+ cmd = p;
+ while (*cmd != NUL && (*cmd == '\r' || *cmd == '\n'))
+ ++cmd;
+ }
+
+ vim_free(buffer);
+ return cnt;
+}
+
+/*
+ * Add a file to a file list. Accepted flags:
+ * EW_DIR add directories
+ * EW_FILE add files
+ * EW_EXEC add executable files
+ * EW_NOTFOUND add even when it doesn't exist
+ * EW_ADDSLASH add slash after directory name
+ */
+void addfile(gap, f, flags)
+garray_T *gap;
+char_u *f; /* filename */
+int flags;
+{
+ char_u *p;
+ int isdir;
+
+ /* if the file/dir doesn't exist, may not add it */
+ if (!(flags & EW_NOTFOUND) && mch_getperm(f) < 0)
+ return;
+
+#ifdef FNAME_ILLEGAL
+ /* if the file/dir contains illegal characters, don't add it */
+ if (vim_strpbrk(f, (char_u *)FNAME_ILLEGAL) != NULL)
+ return;
+#endif
+
+ isdir = mch_isdir(f);
+ if ((isdir && !(flags & EW_DIR)) || (!isdir && !(flags & EW_FILE)))
+ return;
+
+ /* If the file isn't executable, may not add it. Do accept directories. */
+ if (!isdir && (flags & EW_EXEC) && !mch_can_exe(f))
+ return;
+
+ /* Make room for another item in the file list. */
+ if (ga_grow(gap, 1) == FAIL)
+ return;
+
+ p = alloc((unsigned)(STRLEN(f) + 1 + isdir));
+ if (p == NULL)
+ return;
+
+ STRCPY(p, f);
+#ifdef BACKSLASH_IN_FILENAME
+ slash_adjust(p);
+#endif
+ /*
+ * Append a slash or backslash after directory names if none is present.
+ */
+#ifndef DONT_ADD_PATHSEP_TO_DIR
+ if (isdir && (flags & EW_ADDSLASH))
+ add_pathsep(p);
+#endif
+ ((char_u **)gap->ga_data)[gap->ga_len++] = p;
+}
+#endif /* !NO_EXPANDPATH */
+
+
+#ifndef SEEK_SET
+# define SEEK_SET 0
+#endif
+#ifndef SEEK_END
+# define SEEK_END 2
+#endif
+
+/*
+ * Get the stdout of an external command.
+ * Returns an allocated string, or NULL for error.
+ */
+char_u * get_cmd_output(cmd, infile, flags)
+char_u *cmd;
+char_u *infile; /* optional input file name */
+int flags; /* can be SHELL_SILENT */
+{
+ char_u *tempname;
+ char_u *command;
+ char_u *buffer = NULL;
+ int len;
+ int i = 0;
+ FILE *fd;
+
+ if (check_restricted() || check_secure())
+ return NULL;
+
+ /* get a name for the temp file */
+ if ((tempname = vim_tempname('o')) == NULL) {
+ EMSG(_(e_notmp));
+ return NULL;
+ }
+
+ /* Add the redirection stuff */
+ command = make_filter_cmd(cmd, infile, tempname);
+ if (command == NULL)
+ goto done;
+
+ /*
+ * Call the shell to execute the command (errors are ignored).
+ * Don't check timestamps here.
+ */
+ ++no_check_timestamps;
+ call_shell(command, SHELL_DOOUT | SHELL_EXPAND | flags);
+ --no_check_timestamps;
+
+ vim_free(command);
+
+ /*
+ * read the names from the file into memory
+ */
+ fd = mch_fopen((char *)tempname, READBIN);
+
+ if (fd == NULL) {
+ EMSG2(_(e_notopen), tempname);
+ goto done;
+ }
+
+ fseek(fd, 0L, SEEK_END);
+ len = ftell(fd); /* get size of temp file */
+ fseek(fd, 0L, SEEK_SET);
+
+ buffer = alloc(len + 1);
+ if (buffer != NULL)
+ i = (int)fread((char *)buffer, (size_t)1, (size_t)len, fd);
+ fclose(fd);
+ mch_remove(tempname);
+ if (buffer == NULL)
+ goto done;
+ if (i != len) {
+ EMSG2(_(e_notread), tempname);
+ vim_free(buffer);
+ buffer = NULL;
+ } else {
+ /* Change NUL into SOH, otherwise the string is truncated. */
+ for (i = 0; i < len; ++i)
+ if (buffer[i] == NUL)
+ buffer[i] = 1;
+
+ buffer[len] = NUL; /* make sure the buffer is terminated */
+ }
+
+done:
+ vim_free(tempname);
+ return buffer;
+}
+
+/*
+ * Free the list of files returned by expand_wildcards() or other expansion
+ * functions.
+ */
+void FreeWild(count, files)
+int count;
+char_u **files;
+{
+ if (count <= 0 || files == NULL)
+ return;
+ while (count--)
+ vim_free(files[count]);
+ vim_free(files);
+}
+
+/*
+ * Return TRUE when need to go to Insert mode because of 'insertmode'.
+ * Don't do this when still processing a command or a mapping.
+ * Don't do this when inside a ":normal" command.
+ */
+int goto_im() {
+ return p_im && stuff_empty() && typebuf_typed();
+}
+
diff --git a/src/misc2.c b/src/misc2.c
new file mode 100644
index 0000000000..e18de18258
--- /dev/null
+++ b/src/misc2.c
@@ -0,0 +1,5505 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * 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.
+ */
+
+/*
+ * misc2.c: Various functions.
+ */
+#include "vim.h"
+
+static char_u *username = NULL; /* cached result of mch_get_user_name() */
+
+static char_u *ff_expand_buffer = NULL; /* used for expanding filenames */
+
+static int coladvance2 __ARGS((pos_T *pos, int addspaces, int finetune,
+ colnr_T wcol));
+
+/*
+ * Return TRUE if in the current mode we need to use virtual.
+ */
+int virtual_active() {
+ /* 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));
+}
+
+/*
+ * Get the screen position of the cursor.
+ */
+int getviscol() {
+ colnr_T x;
+
+ getvvcol(curwin, &curwin->w_cursor, &x, NULL, NULL);
+ return (int)x;
+}
+
+/*
+ * Get the screen position of character col with a coladd in the cursor line.
+ */
+int getviscol2(col, coladd)
+colnr_T col;
+colnr_T coladd;
+{
+ colnr_T x;
+ pos_T pos;
+
+ pos.lnum = curwin->w_cursor.lnum;
+ pos.col = col;
+ pos.coladd = coladd;
+ getvvcol(curwin, &pos, &x, NULL, NULL);
+ return (int)x;
+}
+
+/*
+ * Go to column "wcol", and add/insert white space as necessary to get the
+ * cursor in that column.
+ * The caller must have saved the cursor line for undo!
+ */
+int coladvance_force(wcol)
+colnr_T wcol;
+{
+ int rc = coladvance2(&curwin->w_cursor, TRUE, FALSE, wcol);
+
+ if (wcol == MAXCOL)
+ curwin->w_valid &= ~VALID_VIRTCOL;
+ else {
+ /* Virtcol is valid */
+ curwin->w_valid |= VALID_VIRTCOL;
+ curwin->w_virtcol = wcol;
+ }
+ return rc;
+}
+
+/*
+ * Try to advance the Cursor to the specified screen column.
+ * If virtual editing: fine tune the cursor position.
+ * Note that all virtual positions off the end of a line should share
+ * a curwin->w_cursor.col value (n.b. this is equal to STRLEN(line)),
+ * beginning at coladd 0.
+ *
+ * return OK if desired column is reached, FAIL if not
+ */
+int coladvance(wcol)
+colnr_T wcol;
+{
+ int rc = getvpos(&curwin->w_cursor, wcol);
+
+ if (wcol == MAXCOL || rc == FAIL)
+ curwin->w_valid &= ~VALID_VIRTCOL;
+ else if (*ml_get_cursor() != TAB) {
+ /* Virtcol is valid when not on a TAB */
+ curwin->w_valid |= VALID_VIRTCOL;
+ curwin->w_virtcol = wcol;
+ }
+ return rc;
+}
+
+/*
+ * Return in "pos" the position of the cursor advanced to screen column "wcol".
+ * return OK if desired column is reached, FAIL if not
+ */
+int getvpos(pos, wcol)
+pos_T *pos;
+colnr_T wcol;
+{
+ return coladvance2(pos, FALSE, virtual_active(), wcol);
+}
+
+static int coladvance2(pos, addspaces, finetune, wcol)
+pos_T *pos;
+int addspaces; /* change the text to achieve our goal? */
+int finetune; /* change char offset for the exact column */
+colnr_T wcol; /* column to move to */
+{
+ int idx;
+ char_u *ptr;
+ char_u *line;
+ colnr_T col = 0;
+ int csize = 0;
+ int one_more;
+ int head = 0;
+
+ one_more = (State & INSERT)
+ || restart_edit != NUL
+ || (VIsual_active && *p_sel != 'o')
+ || ((ve_flags & VE_ONEMORE) && wcol < MAXCOL)
+ ;
+ line = ml_get_buf(curbuf, pos->lnum, FALSE);
+
+ if (wcol >= MAXCOL) {
+ idx = (int)STRLEN(line) - 1 + one_more;
+ col = wcol;
+
+ if ((addspaces || finetune) && !VIsual_active) {
+ curwin->w_curswant = linetabsize(line) + one_more;
+ if (curwin->w_curswant > 0)
+ --curwin->w_curswant;
+ }
+ } else {
+ int width = W_WIDTH(curwin) - win_col_off(curwin);
+
+ if (finetune
+ && curwin->w_p_wrap
+ && curwin->w_width != 0
+ && wcol >= (colnr_T)width) {
+ csize = linetabsize(line);
+ if (csize > 0)
+ csize--;
+
+ if (wcol / width > (colnr_T)csize / width
+ && ((State & INSERT) == 0 || (int)wcol > csize + 1)) {
+ /* In case of line wrapping don't move the cursor beyond the
+ * right screen edge. In Insert mode allow going just beyond
+ * the last character (like what happens when typing and
+ * reaching the right window edge). */
+ wcol = (csize / width + 1) * width - 1;
+ }
+ }
+
+ ptr = line;
+ while (col <= wcol && *ptr != NUL) {
+ /* Count a tab for what it's worth (if list mode not on) */
+ csize = win_lbr_chartabsize(curwin, ptr, col, &head);
+ mb_ptr_adv(ptr);
+ col += csize;
+ }
+ idx = (int)(ptr - line);
+ /*
+ * Handle all the special cases. The virtual_active() check
+ * is needed to ensure that a virtual position off the end of
+ * a line has the correct indexing. The one_more comparison
+ * replaces an explicit add of one_more later on.
+ */
+ if (col > wcol || (!virtual_active() && one_more == 0)) {
+ idx -= 1;
+ /* Don't count the chars from 'showbreak'. */
+ csize -= head;
+ col -= csize;
+ }
+
+ if (virtual_active()
+ && addspaces
+ && ((col != wcol && col != wcol + 1) || csize > 1)) {
+ /* 'virtualedit' is set: The difference between wcol and col is
+ * filled with spaces. */
+
+ if (line[idx] == NUL) {
+ /* Append spaces */
+ int correct = wcol - col;
+ char_u *newline = alloc(idx + correct + 1);
+ int t;
+
+ if (newline == NULL)
+ return FAIL;
+
+ for (t = 0; t < idx; ++t)
+ newline[t] = line[t];
+
+ for (t = 0; t < correct; ++t)
+ newline[t + idx] = ' ';
+
+ newline[idx + correct] = NUL;
+
+ ml_replace(pos->lnum, newline, FALSE);
+ changed_bytes(pos->lnum, (colnr_T)idx);
+ idx += correct;
+ col = wcol;
+ } else {
+ /* Break a tab */
+ int linelen = (int)STRLEN(line);
+ int correct = wcol - col - csize + 1; /* negative!! */
+ char_u *newline;
+ int t, s = 0;
+ int v;
+
+ if (-correct > csize)
+ return FAIL;
+
+ newline = alloc(linelen + csize);
+ if (newline == NULL)
+ return FAIL;
+
+ for (t = 0; t < linelen; t++) {
+ if (t != idx)
+ newline[s++] = line[t];
+ else
+ for (v = 0; v < csize; v++)
+ newline[s++] = ' ';
+ }
+
+ newline[linelen + csize - 1] = NUL;
+
+ ml_replace(pos->lnum, newline, FALSE);
+ changed_bytes(pos->lnum, idx);
+ idx += (csize - 1 + correct);
+ col += correct;
+ }
+ }
+ }
+
+ if (idx < 0)
+ pos->col = 0;
+ else
+ pos->col = idx;
+
+ pos->coladd = 0;
+
+ if (finetune) {
+ if (wcol == MAXCOL) {
+ /* The width of the last character is used to set coladd. */
+ if (!one_more) {
+ colnr_T scol, ecol;
+
+ getvcol(curwin, pos, &scol, NULL, &ecol);
+ pos->coladd = ecol - scol;
+ }
+ } else {
+ int b = (int)wcol - (int)col;
+
+ /* The difference between wcol and col is used to set coladd. */
+ if (b > 0 && b < (MAXCOL - 2 * W_WIDTH(curwin)))
+ pos->coladd = b;
+
+ col += b;
+ }
+ }
+
+ /* prevent from moving onto a trail byte */
+ if (has_mbyte)
+ mb_adjustpos(curbuf, pos);
+
+ if (col < wcol)
+ return FAIL;
+ return OK;
+}
+
+/*
+ * Increment the cursor position. See inc() for return values.
+ */
+int inc_cursor() {
+ return inc(&curwin->w_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(lp)
+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(lp)
+pos_T *lp;
+{
+ int r;
+
+ if ((r = inc(lp)) >= 1 && lp->col)
+ r = inc(lp);
+ return r;
+}
+
+/*
+ * dec(p)
+ *
+ * Decrement the line pointer 'p' crossing line boundaries as necessary.
+ * Return 1 when crossing a line, -1 when at start of file, 0 otherwise.
+ */
+int dec_cursor() {
+ return dec(&curwin->w_cursor);
+}
+
+int dec(lp)
+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(lp)
+pos_T *lp;
+{
+ int r;
+
+ if ((r = dec(lp)) == 1 && lp->col)
+ r = dec(lp);
+ return r;
+}
+
+/*
+ * Get the line number relative to the current cursor position, i.e. the
+ * difference between line number and cursor position. Only look for lines that
+ * can be visible, folded lines don't count.
+ */
+linenr_T get_cursor_rel_lnum(wp, lnum)
+win_T *wp;
+linenr_T lnum; /* line number to get the result for */
+{
+ linenr_T cursor = wp->w_cursor.lnum;
+ linenr_T retval = 0;
+
+ if (hasAnyFolding(wp)) {
+ if (lnum > cursor) {
+ while (lnum > cursor) {
+ (void)hasFoldingWin(wp, lnum, &lnum, NULL, TRUE, NULL);
+ /* if lnum and cursor are in the same fold,
+ * now lnum <= cursor */
+ if (lnum > cursor)
+ retval++;
+ lnum--;
+ }
+ } else if (lnum < cursor) {
+ while (lnum < cursor) {
+ (void)hasFoldingWin(wp, lnum, NULL, &lnum, TRUE, NULL);
+ /* if lnum and cursor are in the same fold,
+ * now lnum >= cursor */
+ if (lnum < cursor)
+ retval--;
+ lnum++;
+ }
+ }
+ /* else if (lnum == cursor)
+ * retval = 0;
+ */
+ } else
+ retval = lnum - cursor;
+
+ return retval;
+}
+
+/*
+ * Make sure curwin->w_cursor.lnum is valid.
+ */
+void check_cursor_lnum() {
+ if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count) {
+ /* If there is a closed fold at the end of the file, put the cursor in
+ * its first line. Otherwise in the last line. */
+ if (!hasFolding(curbuf->b_ml.ml_line_count,
+ &curwin->w_cursor.lnum, NULL))
+ curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
+ }
+ if (curwin->w_cursor.lnum <= 0)
+ curwin->w_cursor.lnum = 1;
+}
+
+/*
+ * Make sure curwin->w_cursor.col is valid.
+ */
+void check_cursor_col() {
+ check_cursor_col_win(curwin);
+}
+
+/*
+ * Make sure win->w_cursor.col is valid.
+ */
+void check_cursor_col_win(win)
+win_T *win;
+{
+ colnr_T len;
+ colnr_T oldcol = win->w_cursor.col;
+ colnr_T oldcoladd = win->w_cursor.col + win->w_cursor.coladd;
+
+ len = (colnr_T)STRLEN(ml_get_buf(win->w_buffer, win->w_cursor.lnum, FALSE));
+ if (len == 0)
+ win->w_cursor.col = 0;
+ else if (win->w_cursor.col >= len) {
+ /* Allow cursor past end-of-line when:
+ * - in Insert mode or restarting Insert mode
+ * - in Visual mode and 'selection' isn't "old"
+ * - 'virtualedit' is set */
+ if ((State & INSERT) || restart_edit
+ || (VIsual_active && *p_sel != 'o')
+ || (ve_flags & VE_ONEMORE)
+ || virtual_active())
+ 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);
+ }
+ } 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)
+ win->w_cursor.coladd = 0;
+ 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 */
+ win->w_cursor.coladd = 0;
+ }
+}
+
+/*
+ * make sure curwin->w_cursor in on a valid character
+ */
+void check_cursor() {
+ check_cursor_lnum();
+ check_cursor_col();
+}
+
+/*
+ * Make sure curwin->w_cursor is not on the NUL at the end of the line.
+ * Allow it when in Visual mode and 'selection' is not "old".
+ */
+void adjust_cursor_col() {
+ if (curwin->w_cursor.col > 0
+ && (!VIsual_active || *p_sel == 'o')
+ && gchar_cursor() == NUL)
+ --curwin->w_cursor.col;
+}
+
+/*
+ * When curwin->w_leftcol has changed, adjust the cursor position.
+ * Return TRUE if the cursor was moved.
+ */
+int leftcol_changed() {
+ long lastcol;
+ colnr_T s, e;
+ int retval = FALSE;
+
+ changed_cline_bef_curs();
+ lastcol = curwin->w_leftcol + W_WIDTH(curwin) - curwin_col_off() - 1;
+ validate_virtcol();
+
+ /*
+ * If the cursor is right or left of the screen, move it to last or first
+ * character.
+ */
+ if (curwin->w_virtcol > (colnr_T)(lastcol - p_siso)) {
+ retval = TRUE;
+ coladvance((colnr_T)(lastcol - p_siso));
+ } else if (curwin->w_virtcol < curwin->w_leftcol + p_siso) {
+ retval = TRUE;
+ (void)coladvance((colnr_T)(curwin->w_leftcol + p_siso));
+ }
+
+ /*
+ * If the start of the character under the cursor is not on the screen,
+ * advance the cursor one more char. If this fails (last char of the
+ * line) adjust the scrolling.
+ */
+ getvvcol(curwin, &curwin->w_cursor, &s, NULL, &e);
+ if (e > (colnr_T)lastcol) {
+ retval = TRUE;
+ coladvance(s - 1);
+ } else if (s < curwin->w_leftcol) {
+ retval = TRUE;
+ if (coladvance(e + 1) == FAIL) { /* there isn't another character */
+ curwin->w_leftcol = s; /* adjust w_leftcol instead */
+ changed_cline_bef_curs();
+ }
+ }
+
+ if (retval)
+ curwin->w_set_curswant = TRUE;
+ redraw_later(NOT_VALID);
+ return retval;
+}
+
+/**********************************************************************
+ * Various routines dealing with allocation and deallocation of memory.
+ */
+
+#if defined(MEM_PROFILE) || defined(PROTO)
+
+# define MEM_SIZES 8200
+static long_u mem_allocs[MEM_SIZES];
+static long_u mem_frees[MEM_SIZES];
+static long_u mem_allocated;
+static long_u mem_freed;
+static long_u mem_peak;
+static long_u num_alloc;
+static long_u num_freed;
+
+static void mem_pre_alloc_s __ARGS((size_t *sizep));
+static void mem_pre_alloc_l __ARGS((long_u *sizep));
+static void mem_post_alloc __ARGS((void **pp, size_t size));
+static void mem_pre_free __ARGS((void **pp));
+
+static void mem_pre_alloc_s(sizep)
+size_t *sizep;
+{
+ *sizep += sizeof(size_t);
+}
+
+static void mem_pre_alloc_l(sizep)
+long_u *sizep;
+{
+ *sizep += sizeof(size_t);
+}
+
+static void mem_post_alloc(pp, size)
+void **pp;
+size_t size;
+{
+ if (*pp == NULL)
+ return;
+ size -= sizeof(size_t);
+ *(long_u *)*pp = size;
+ if (size <= MEM_SIZES-1)
+ mem_allocs[size-1]++;
+ else
+ mem_allocs[MEM_SIZES-1]++;
+ mem_allocated += size;
+ if (mem_allocated - mem_freed > mem_peak)
+ mem_peak = mem_allocated - mem_freed;
+ num_alloc++;
+ *pp = (void *)((char *)*pp + sizeof(size_t));
+}
+
+static void mem_pre_free(pp)
+void **pp;
+{
+ long_u size;
+
+ *pp = (void *)((char *)*pp - sizeof(size_t));
+ size = *(size_t *)*pp;
+ if (size <= MEM_SIZES-1)
+ mem_frees[size-1]++;
+ else
+ mem_frees[MEM_SIZES-1]++;
+ mem_freed += size;
+ num_freed++;
+}
+
+/*
+ * called on exit via atexit()
+ */
+void vim_mem_profile_dump() {
+ int i, j;
+
+ printf("\r\n");
+ j = 0;
+ for (i = 0; i < MEM_SIZES - 1; i++) {
+ if (mem_allocs[i] || mem_frees[i]) {
+ if (mem_frees[i] > mem_allocs[i])
+ printf("\r\n%s", _("ERROR: "));
+ printf("[%4d / %4lu-%-4lu] ", i + 1, mem_allocs[i], mem_frees[i]);
+ j++;
+ if (j > 3) {
+ j = 0;
+ printf("\r\n");
+ }
+ }
+ }
+
+ i = MEM_SIZES - 1;
+ if (mem_allocs[i]) {
+ printf("\r\n");
+ if (mem_frees[i] > mem_allocs[i])
+ puts(_("ERROR: "));
+ printf("[>%d / %4lu-%-4lu]", i, mem_allocs[i], mem_frees[i]);
+ }
+
+ printf(_("\n[bytes] total alloc-freed %lu-%lu, in use %lu, peak use %lu\n"),
+ mem_allocated, mem_freed, mem_allocated - mem_freed, mem_peak);
+ printf(_("[calls] total re/malloc()'s %lu, total free()'s %lu\n\n"),
+ num_alloc, num_freed);
+}
+
+#endif /* MEM_PROFILE */
+
+/*
+ * Some memory is reserved for error messages and for being able to
+ * call mf_release_all(), which needs some memory for mf_trans_add().
+ */
+# define KEEP_ROOM (2 * 8192L)
+#define KEEP_ROOM_KB (KEEP_ROOM / 1024L)
+
+/*
+ * Note: if unsigned is 16 bits we can only allocate up to 64K with alloc().
+ * Use lalloc for larger blocks.
+ */
+char_u * alloc(size)
+unsigned size;
+{
+ return lalloc((long_u)size, TRUE);
+}
+
+/*
+ * Allocate memory and set all bytes to zero.
+ */
+char_u * alloc_clear(size)
+unsigned size;
+{
+ char_u *p;
+
+ p = lalloc((long_u)size, TRUE);
+ if (p != NULL)
+ (void)vim_memset(p, 0, (size_t)size);
+ return p;
+}
+
+/*
+ * alloc() with check for maximum line length
+ */
+char_u * alloc_check(size)
+unsigned size;
+{
+#if !defined(UNIX) && !defined(__EMX__)
+ if (sizeof(int) == 2 && size > 0x7fff) {
+ /* Don't hide this message */
+ emsg_silent = 0;
+ EMSG(_("E340: Line is becoming too long"));
+ return NULL;
+ }
+#endif
+ return lalloc((long_u)size, TRUE);
+}
+
+/*
+ * Allocate memory like lalloc() and set all bytes to zero.
+ */
+char_u * lalloc_clear(size, message)
+long_u size;
+int message;
+{
+ char_u *p;
+
+ p = (lalloc(size, message));
+ if (p != NULL)
+ (void)vim_memset(p, 0, (size_t)size);
+ return p;
+}
+
+/*
+ * Low level memory allocation function.
+ * This is used often, KEEP IT FAST!
+ */
+char_u * lalloc(size, message)
+long_u size;
+int message;
+{
+ char_u *p; /* pointer to new storage space */
+ static int releasing = FALSE; /* don't do mf_release_all() recursive */
+ int try_again;
+#if defined(HAVE_AVAIL_MEM) && !defined(SMALL_MEM)
+ static long_u allocated = 0; /* allocated since last avail check */
+#endif
+
+ /* Safety check for allocating zero bytes */
+ if (size == 0) {
+ /* Don't hide this message */
+ emsg_silent = 0;
+ EMSGN(_("E341: Internal error: lalloc(%ld, )"), size);
+ return NULL;
+ }
+
+#ifdef MEM_PROFILE
+ mem_pre_alloc_l(&size);
+#endif
+
+
+ /*
+ * Loop when out of memory: Try to release some memfile blocks and
+ * if some blocks are released call malloc again.
+ */
+ for (;; ) {
+ /*
+ * Handle three kind of systems:
+ * 1. No check for available memory: Just return.
+ * 2. Slow check for available memory: call mch_avail_mem() after
+ * allocating KEEP_ROOM amount of memory.
+ * 3. Strict check for available memory: call mch_avail_mem()
+ */
+ if ((p = (char_u *)malloc((size_t)size)) != NULL) {
+#ifndef HAVE_AVAIL_MEM
+ /* 1. No check for available memory: Just return. */
+ goto theend;
+#else
+# ifndef SMALL_MEM
+ /* 2. Slow check for available memory: call mch_avail_mem() after
+ * allocating (KEEP_ROOM / 2) amount of memory. */
+ allocated += size;
+ if (allocated < KEEP_ROOM / 2)
+ goto theend;
+ allocated = 0;
+# endif
+ /* 3. check for available memory: call mch_avail_mem() */
+ if (mch_avail_mem(TRUE) < KEEP_ROOM_KB && !releasing) {
+ free((char *)p); /* System is low... no go! */
+ p = NULL;
+ } else
+ goto theend;
+#endif
+ }
+ /*
+ * Remember that mf_release_all() is being called to avoid an endless
+ * loop, because mf_release_all() may call alloc() recursively.
+ */
+ if (releasing)
+ break;
+ releasing = TRUE;
+
+ clear_sb_text(); /* free any scrollback text */
+ try_again = mf_release_all(); /* release as many blocks as possible */
+ try_again |= garbage_collect(); /* cleanup recursive lists/dicts */
+
+ releasing = FALSE;
+ if (!try_again)
+ break;
+ }
+
+ if (message && p == NULL)
+ do_outofmem_msg(size);
+
+theend:
+#ifdef MEM_PROFILE
+ mem_post_alloc((void **)&p, (size_t)size);
+#endif
+ return p;
+}
+
+#if defined(MEM_PROFILE) || defined(PROTO)
+/*
+ * realloc() with memory profiling.
+ */
+void * mem_realloc(ptr, size)
+void *ptr;
+size_t size;
+{
+ void *p;
+
+ mem_pre_free(&ptr);
+ mem_pre_alloc_s(&size);
+
+ p = realloc(ptr, size);
+
+ mem_post_alloc(&p, size);
+
+ return p;
+}
+#endif
+
+/*
+ * Avoid repeating the error message many times (they take 1 second each).
+ * Did_outofmem_msg is reset when a character is read.
+ */
+void do_outofmem_msg(size)
+long_u size;
+{
+ if (!did_outofmem_msg) {
+ /* Don't hide this message */
+ emsg_silent = 0;
+
+ /* Must come first to avoid coming back here when printing the error
+ * message fails, e.g. when setting v:errmsg. */
+ did_outofmem_msg = TRUE;
+
+ EMSGN(_("E342: Out of memory! (allocating %lu bytes)"), size);
+ }
+}
+
+#if defined(EXITFREE) || defined(PROTO)
+
+static void free_findfile __ARGS((void));
+
+/*
+ * Free everything that we allocated.
+ * Can be used to detect memory leaks, e.g., with ccmalloc.
+ * NOTE: This is tricky! Things are freed that functions depend on. Don't be
+ * surprised if Vim crashes...
+ * Some things can't be freed, esp. things local to a library function.
+ */
+void free_all_mem() {
+ buf_T *buf, *nextbuf;
+ static int 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)
+ return;
+ entered = TRUE;
+
+ block_autocmds(); /* don't want to trigger autocommands here */
+
+ /* Close all tabs and windows. Reset 'equalalways' to avoid redraws. */
+ p_ea = FALSE;
+ if (first_tabpage->tp_next != NULL)
+ do_cmdline_cmd((char_u *)"tabonly!");
+ if (firstwin != lastwin)
+ do_cmdline_cmd((char_u *)"only!");
+
+ /* Free all spell info. */
+ spell_free_all();
+
+ /* Clear user commands (before deleting buffers). */
+ ex_comclear(NULL);
+
+ /* Clear menus. */
+ do_cmdline_cmd((char_u *)"aunmenu *");
+ do_cmdline_cmd((char_u *)"menutranslate clear");
+
+ /* Clear mappings, abbreviations, breakpoints. */
+ do_cmdline_cmd((char_u *)"lmapclear");
+ do_cmdline_cmd((char_u *)"xmapclear");
+ do_cmdline_cmd((char_u *)"mapclear");
+ do_cmdline_cmd((char_u *)"mapclear!");
+ do_cmdline_cmd((char_u *)"abclear");
+ do_cmdline_cmd((char_u *)"breakdel *");
+ do_cmdline_cmd((char_u *)"profdel *");
+ do_cmdline_cmd((char_u *)"set keymap=");
+
+ free_titles();
+ free_findfile();
+
+ /* Obviously named calls. */
+ free_all_autocmds();
+ clear_termcodes();
+ free_all_options();
+ free_all_marks();
+ alist_clear(&global_alist);
+ free_homedir();
+ free_users();
+ free_search_patterns();
+ free_old_sub();
+ free_last_insert();
+ free_prev_shellcmd();
+ free_regexp_stuff();
+ free_tag_stuff();
+ free_cd_dir();
+ set_expr_line(NULL);
+ diff_clear(curtab);
+ clear_sb_text(); /* free any scrollback text */
+
+ /* Free some global vars. */
+ vim_free(username);
+ vim_free(last_cmdline);
+ vim_free(new_last_cmdline);
+ set_keep_msg(NULL, 0);
+ vim_free(ff_expand_buffer);
+
+ /* Clear cmdline history. */
+ p_hi = 0;
+ init_history();
+
+ {
+ win_T *win;
+ tabpage_T *tab;
+
+ qf_free_all(NULL);
+ /* Free all location lists */
+ FOR_ALL_TAB_WINDOWS(tab, win)
+ qf_free_all(win);
+ }
+
+ /* Close all script inputs. */
+ close_all_scripts();
+
+ /* 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_cmdline_buf();
+
+ /* Clear registers. */
+ clear_registers();
+ ResetRedobuff();
+ ResetRedobuff();
+
+
+ /* highlight info */
+ free_highlight();
+
+ reset_last_sourcing();
+
+ free_tabpage(first_tabpage);
+ first_tabpage = NULL;
+
+# ifdef UNIX
+ /* Machine-specific free. */
+ mch_free_mem();
+# endif
+
+ /* message history */
+ for (;; )
+ if (delete_first_msg() == FAIL)
+ break;
+
+ eval_clear();
+
+ free_termoptions();
+
+ /* screenlines (can't display anything now!) */
+ free_screenlines();
+
+ clear_hl_tables();
+
+ vim_free(IObuff);
+ vim_free(NameBuff);
+}
+
+#endif
+
+/*
+ * Copy "string" into newly allocated memory.
+ */
+char_u * vim_strsave(string)
+char_u *string;
+{
+ char_u *p;
+ unsigned len;
+
+ len = (unsigned)STRLEN(string) + 1;
+ p = alloc(len);
+ if (p != NULL)
+ mch_memmove(p, string, (size_t)len);
+ return p;
+}
+
+/*
+ * 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.
+ */
+char_u * vim_strnsave(string, len)
+char_u *string;
+int len;
+{
+ char_u *p;
+
+ p = alloc((unsigned)(len + 1));
+ if (p != NULL) {
+ STRNCPY(p, string, len);
+ p[len] = NUL;
+ }
+ return p;
+}
+
+/*
+ * Same as vim_strsave(), but any characters found in esc_chars are preceded
+ * by a backslash.
+ */
+char_u * vim_strsave_escaped(string, esc_chars)
+char_u *string;
+char_u *esc_chars;
+{
+ return vim_strsave_escaped_ext(string, esc_chars, '\\', FALSE);
+}
+
+/*
+ * Same as vim_strsave_escaped(), but when "bsl" is TRUE also escape
+ * characters where rem_backslash() would remove the backslash.
+ * Escape the characters with "cc".
+ */
+char_u * vim_strsave_escaped_ext(string, esc_chars, cc, bsl)
+char_u *string;
+char_u *esc_chars;
+int cc;
+int bsl;
+{
+ char_u *p;
+ char_u *p2;
+ char_u *escaped_string;
+ unsigned length;
+ int l;
+
+ /*
+ * First count the number of backslashes required.
+ * Then allocate the memory and insert them.
+ */
+ length = 1; /* count the trailing NUL */
+ for (p = string; *p; p++) {
+ if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1) {
+ length += l; /* count a multibyte char */
+ p += l - 1;
+ continue;
+ }
+ if (vim_strchr(esc_chars, *p) != NULL || (bsl && rem_backslash(p)))
+ ++length; /* count a backslash */
+ ++length; /* count an ordinary char */
+ }
+ escaped_string = alloc(length);
+ if (escaped_string != NULL) {
+ p2 = escaped_string;
+ for (p = string; *p; p++) {
+ if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1) {
+ mch_memmove(p2, p, (size_t)l);
+ p2 += l;
+ p += l - 1; /* skip multibyte char */
+ continue;
+ }
+ if (vim_strchr(esc_chars, *p) != NULL || (bsl && rem_backslash(p)))
+ *p2++ = cc;
+ *p2++ = *p;
+ }
+ *p2 = NUL;
+ }
+ return escaped_string;
+}
+
+/*
+ * Return TRUE when 'shell' has "csh" in the tail.
+ */
+int csh_like_shell() {
+ return strstr((char *)gettail(p_sh), "csh") != NULL;
+}
+
+/*
+ * Escape "string" for use as a shell argument with system().
+ * This uses single quotes, except when we know we need to use double quotes
+ * (MS-DOS and MS-Windows without 'shellslash' set).
+ * Escape a newline, depending on the 'shell' option.
+ * When "do_special" is TRUE also replace "!", "%", "#" and things starting
+ * with "<" like "<cfile>".
+ * Returns the result in allocated memory, NULL if we have run out.
+ */
+char_u * vim_strsave_shellescape(string, do_special)
+char_u *string;
+int do_special;
+{
+ unsigned length;
+ char_u *p;
+ char_u *d;
+ char_u *escaped_string;
+ int l;
+ int csh_like;
+
+ /* Only csh and similar shells expand '!' within single quotes. For sh and
+ * the like we must not put a backslash before it, it will be taken
+ * literally. If do_special is set the '!' will be escaped twice.
+ * Csh also needs to have "\n" escaped twice when do_special is set. */
+ csh_like = csh_like_shell();
+
+ /* First count the number of extra bytes required. */
+ length = (unsigned)STRLEN(string) + 3; /* two quotes and a trailing NUL */
+ for (p = string; *p != NUL; mb_ptr_adv(p)) {
+ if (*p == '\'')
+ length += 3; /* ' => '\'' */
+ if (*p == '\n' || (*p == '!' && (csh_like || do_special))) {
+ ++length; /* insert backslash */
+ if (csh_like && do_special)
+ ++length; /* insert backslash */
+ }
+ if (do_special && find_cmdline_var(p, &l) >= 0) {
+ ++length; /* insert backslash */
+ p += l - 1;
+ }
+ }
+
+ /* Allocate memory for the result and fill it. */
+ escaped_string = alloc(length);
+ if (escaped_string != NULL) {
+ d = escaped_string;
+
+ /* add opening quote */
+ *d++ = '\'';
+
+ for (p = string; *p != NUL; ) {
+ if (*p == '\'') {
+ *d++ = '\'';
+ *d++ = '\\';
+ *d++ = '\'';
+ *d++ = '\'';
+ ++p;
+ continue;
+ }
+ if (*p == '\n' || (*p == '!' && (csh_like || do_special))) {
+ *d++ = '\\';
+ if (csh_like && do_special)
+ *d++ = '\\';
+ *d++ = *p++;
+ continue;
+ }
+ if (do_special && find_cmdline_var(p, &l) >= 0) {
+ *d++ = '\\'; /* insert backslash */
+ while (--l >= 0) /* copy the var */
+ *d++ = *p++;
+ continue;
+ }
+
+ MB_COPY_CHAR(p, d);
+ }
+
+ /* add terminating quote and finish with a NUL */
+ *d++ = '\'';
+ *d = NUL;
+ }
+
+ return escaped_string;
+}
+
+/*
+ * Like vim_strsave(), but make all characters uppercase.
+ * This uses ASCII lower-to-upper case translation, language independent.
+ */
+char_u * vim_strsave_up(string)
+char_u *string;
+{
+ char_u *p1;
+
+ p1 = vim_strsave(string);
+ vim_strup(p1);
+ return p1;
+}
+
+/*
+ * Like vim_strnsave(), but make all characters uppercase.
+ * This uses ASCII lower-to-upper case translation, language independent.
+ */
+char_u * vim_strnsave_up(string, len)
+char_u *string;
+int len;
+{
+ char_u *p1;
+
+ p1 = vim_strnsave(string, len);
+ vim_strup(p1);
+ return p1;
+}
+
+/*
+ * ASCII lower-to-upper case translation, language independent.
+ */
+void vim_strup(p)
+char_u *p;
+{
+ char_u *p2;
+ int c;
+
+ if (p != NULL) {
+ p2 = p;
+ while ((c = *p2) != NUL)
+ *p2++ = (c < 'a' || c > 'z') ? c : (c - 0x20);
+ }
+}
+
+/*
+ * Make string "s" all upper-case and return it in allocated memory.
+ * Handles multi-byte characters as well as possible.
+ * Returns NULL when out of memory.
+ */
+char_u * strup_save(orig)
+char_u *orig;
+{
+ char_u *p;
+ char_u *res;
+
+ res = p = vim_strsave(orig);
+
+ if (res != NULL)
+ while (*p != NUL) {
+ int l;
+
+ if (enc_utf8) {
+ int c, uc;
+ int newl;
+ char_u *s;
+
+ c = utf_ptr2char(p);
+ 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);
+ newl = utf_char2len(uc);
+ if (newl != l) {
+ s = alloc((unsigned)STRLEN(res) + 1 + newl - l);
+ if (s == NULL)
+ break;
+ mch_memmove(s, res, p - res);
+ STRCPY(s + (p - res) + newl, p + l);
+ p = s + (p - res);
+ vim_free(res);
+ res = s;
+ }
+
+ utf_char2bytes(uc, p);
+ p += newl;
+ } else if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1)
+ p += l; /* skip multi-byte character */
+ else {
+ *p = TOUPPER_LOC(*p); /* note that toupper() can be a macro */
+ p++;
+ }
+ }
+
+ return res;
+}
+
+/*
+ * copy a space a number of times
+ */
+void copy_spaces(ptr, count)
+char_u *ptr;
+size_t count;
+{
+ size_t i = count;
+ char_u *p = ptr;
+
+ while (i--)
+ *p++ = ' ';
+}
+
+/*
+ * Copy a character a number of times.
+ * Does not work for multi-byte characters!
+ */
+void copy_chars(ptr, count, c)
+char_u *ptr;
+size_t count;
+int c;
+{
+ size_t i = count;
+ char_u *p = ptr;
+
+ while (i--)
+ *p++ = c;
+}
+
+/*
+ * delete spaces at the end of a string
+ */
+void del_trailing_spaces(ptr)
+char_u *ptr;
+{
+ char_u *q;
+
+ q = ptr + STRLEN(ptr);
+ while (--q > ptr && vim_iswhite(q[0]) && q[-1] != '\\' && q[-1] != Ctrl_V)
+ *q = NUL;
+}
+
+/*
+ * Like strncpy(), but always terminate the result with one NUL.
+ * "to" must be "len + 1" long!
+ */
+void vim_strncpy(to, from, len)
+char_u *to;
+char_u *from;
+size_t len;
+{
+ STRNCPY(to, from, len);
+ to[len] = NUL;
+}
+
+/*
+ * Like strcat(), but make sure the result fits in "tosize" bytes and is
+ * always NUL terminated.
+ */
+void vim_strcat(to, from, tosize)
+char_u *to;
+char_u *from;
+size_t tosize;
+{
+ size_t tolen = STRLEN(to);
+ size_t fromlen = STRLEN(from);
+
+ if (tolen + fromlen + 1 > tosize) {
+ mch_memmove(to + tolen, from, tosize - tolen - 1);
+ to[tosize - 1] = NUL;
+ } else
+ STRCPY(to + tolen, from);
+}
+
+/*
+ * 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.
+ */
+int copy_option_part(option, buf, maxlen, sep_chars)
+char_u **option;
+char_u *buf;
+int maxlen;
+char *sep_chars;
+{
+ int 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;
+}
+
+/*
+ * Replacement for free() that ignores NULL pointers.
+ * Also skip free() when exiting for sure, this helps when we caught a deadly
+ * signal that was caused by a crash in free().
+ */
+void vim_free(x)
+void *x;
+{
+ if (x != NULL && !really_exiting) {
+#ifdef MEM_PROFILE
+ mem_pre_free(&x);
+#endif
+ free(x);
+ }
+}
+
+#ifndef HAVE_MEMSET
+void * vim_memset(ptr, c, size)
+void *ptr;
+int c;
+size_t size;
+{
+ char *p = ptr;
+
+ while (size-- > 0)
+ *p++ = c;
+ return ptr;
+}
+#endif
+
+#ifdef VIM_MEMCMP
+/*
+ * Return zero when "b1" and "b2" are the same for "len" bytes.
+ * Return non-zero otherwise.
+ */
+int vim_memcmp(b1, b2, len)
+void *b1;
+void *b2;
+size_t len;
+{
+ char_u *p1 = (char_u *)b1, *p2 = (char_u *)b2;
+
+ for (; len > 0; --len) {
+ if (*p1 != *p2)
+ return 1;
+ ++p1;
+ ++p2;
+ }
+ return 0;
+}
+#endif
+
+#ifdef VIM_MEMMOVE
+/*
+ * Version of memmove() that handles overlapping source and destination.
+ * For systems that don't have a function that is guaranteed to do that (SYSV).
+ */
+void mch_memmove(dst_arg, src_arg, len)
+void *src_arg, *dst_arg;
+size_t len;
+{
+ /*
+ * A void doesn't have a size, we use char pointers.
+ */
+ char *dst = dst_arg, *src = src_arg;
+
+ /* overlap, copy backwards */
+ if (dst > src && dst < src + len) {
+ src += len;
+ dst += len;
+ while (len-- > 0)
+ *--dst = *--src;
+ } else /* copy forwards */
+ while (len-- > 0)
+ *dst++ = *src++;
+}
+#endif
+
+#if (!defined(HAVE_STRCASECMP) && !defined(HAVE_STRICMP)) || defined(PROTO)
+/*
+ * Compare two strings, ignoring case, using current locale.
+ * Doesn't work for multi-byte characters.
+ * return 0 for match, < 0 for smaller, > 0 for bigger
+ */
+int vim_stricmp(s1, s2)
+char *s1;
+char *s2;
+{
+ int i;
+
+ for (;; ) {
+ i = (int)TOLOWER_LOC(*s1) - (int)TOLOWER_LOC(*s2);
+ if (i != 0)
+ return i; /* this character different */
+ if (*s1 == NUL)
+ break; /* strings match until NUL */
+ ++s1;
+ ++s2;
+ }
+ return 0; /* strings match */
+}
+#endif
+
+#if (!defined(HAVE_STRNCASECMP) && !defined(HAVE_STRNICMP)) || defined(PROTO)
+/*
+ * Compare two strings, for length "len", ignoring case, using current locale.
+ * Doesn't work for multi-byte characters.
+ * return 0 for match, < 0 for smaller, > 0 for bigger
+ */
+int vim_strnicmp(s1, s2, len)
+char *s1;
+char *s2;
+size_t len;
+{
+ int i;
+
+ while (len > 0) {
+ i = (int)TOLOWER_LOC(*s1) - (int)TOLOWER_LOC(*s2);
+ if (i != 0)
+ return i; /* this character different */
+ if (*s1 == NUL)
+ break; /* strings match until NUL */
+ ++s1;
+ ++s2;
+ --len;
+ }
+ return 0; /* strings match */
+}
+#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(string, c)
+char_u *string;
+int c;
+{
+ char_u *p;
+ int b;
+
+ p = string;
+ if (enc_utf8 && c >= 0x80) {
+ while (*p != NUL) {
+ if (utf_ptr2char(p) == c)
+ return p;
+ p += (*mb_ptr2len)(p);
+ }
+ 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 p;
+ p += (*mb_ptr2len)(p);
+ }
+ return NULL;
+ }
+ if (has_mbyte) {
+ while ((b = *p) != NUL) {
+ if (b == c)
+ return p;
+ p += (*mb_ptr2len)(p);
+ }
+ return NULL;
+ }
+ while ((b = *p) != NUL) {
+ if (b == c)
+ return 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(string, c)
+char_u *string;
+int c;
+{
+ char_u *p = string;
+
+ while (*p != NUL) {
+ if (*p == c)
+ return 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(string, c)
+char_u *string;
+int c;
+{
+ char_u *retval = NULL;
+ char_u *p = string;
+
+ while (*p) {
+ if (*p == c)
+ retval = p;
+ mb_ptr_adv(p);
+ }
+ return retval;
+}
+
+/*
+ * Vim's version of strpbrk(), in case it's missing.
+ * Don't generate a prototype for this, causes problems when it's not used.
+ */
+# ifndef HAVE_STRPBRK
+# ifdef vim_strpbrk
+# undef vim_strpbrk
+# endif
+char_u * vim_strpbrk(s, charset)
+char_u *s;
+char_u *charset;
+{
+ while (*s) {
+ if (vim_strchr(charset, *s) != NULL)
+ return s;
+ mb_ptr_adv(s);
+ }
+ return NULL;
+}
+# endif
+
+/*
+ * Vim has its own isspace() function, because on some machines isspace()
+ * can't handle characters above 128.
+ */
+int vim_isspace(x)
+int x;
+{
+ return (x >= 9 && x <= 13) || x == ' ';
+}
+
+/************************************************************************
+ * Functions for handling growing arrays.
+ */
+
+/*
+ * Clear an allocated growing array.
+ */
+void ga_clear(gap)
+garray_T *gap;
+{
+ vim_free(gap->ga_data);
+ ga_init(gap);
+}
+
+/*
+ * Clear a growing array that contains a list of strings.
+ */
+void ga_clear_strings(gap)
+garray_T *gap;
+{
+ int i;
+
+ for (i = 0; i < gap->ga_len; ++i)
+ vim_free(((char_u **)(gap->ga_data))[i]);
+ ga_clear(gap);
+}
+
+/*
+ * Initialize a growing array. Don't forget to set ga_itemsize and
+ * ga_growsize! Or use ga_init2().
+ */
+void ga_init(gap)
+garray_T *gap;
+{
+ gap->ga_data = NULL;
+ gap->ga_maxlen = 0;
+ gap->ga_len = 0;
+}
+
+void ga_init2(gap, itemsize, growsize)
+garray_T *gap;
+int itemsize;
+int growsize;
+{
+ ga_init(gap);
+ gap->ga_itemsize = itemsize;
+ gap->ga_growsize = growsize;
+}
+
+/*
+ * Make room in growing array "gap" for at least "n" items.
+ * Return FAIL for failure, OK otherwise.
+ */
+int ga_grow(gap, n)
+garray_T *gap;
+int n;
+{
+ size_t old_len;
+ size_t new_len;
+ char_u *pp;
+
+ if (gap->ga_maxlen - gap->ga_len < n) {
+ if (n < gap->ga_growsize)
+ n = gap->ga_growsize;
+ new_len = gap->ga_itemsize * (gap->ga_len + n);
+ pp = (gap->ga_data == NULL)
+ ? alloc((unsigned)new_len) : vim_realloc(gap->ga_data, new_len);
+ if (pp == NULL)
+ return FAIL;
+ old_len = gap->ga_itemsize * gap->ga_maxlen;
+ vim_memset(pp + old_len, 0, new_len - old_len);
+ gap->ga_maxlen = gap->ga_len + n;
+ gap->ga_data = pp;
+ }
+ return OK;
+}
+
+/*
+ * For a growing array that contains a list of strings: concatenate all the
+ * strings with a separating comma.
+ * Returns NULL when out of memory.
+ */
+char_u * ga_concat_strings(gap)
+garray_T *gap;
+{
+ int i;
+ int len = 0;
+ char_u *s;
+
+ for (i = 0; i < gap->ga_len; ++i)
+ len += (int)STRLEN(((char_u **)(gap->ga_data))[i]) + 1;
+
+ s = alloc(len + 1);
+ if (s != NULL) {
+ *s = NUL;
+ for (i = 0; i < gap->ga_len; ++i) {
+ if (*s != NUL)
+ STRCAT(s, ",");
+ STRCAT(s, ((char_u **)(gap->ga_data))[i]);
+ }
+ }
+ return s;
+}
+
+/*
+ * Concatenate a string to a growarray which contains characters.
+ * Note: Does NOT copy the NUL at the end!
+ */
+void ga_concat(gap, s)
+garray_T *gap;
+char_u *s;
+{
+ int len = (int)STRLEN(s);
+
+ if (ga_grow(gap, len) == OK) {
+ mch_memmove((char *)gap->ga_data + gap->ga_len, s, (size_t)len);
+ gap->ga_len += len;
+ }
+}
+
+/*
+ * Append one byte to a growarray which contains bytes.
+ */
+void ga_append(gap, c)
+garray_T *gap;
+int c;
+{
+ if (ga_grow(gap, 1) == OK) {
+ *((char *)gap->ga_data + gap->ga_len) = c;
+ ++gap->ga_len;
+ }
+}
+
+#if (defined(UNIX) && !defined(USE_SYSTEM)) || defined(WIN3264)
+/*
+ * Append the text in "gap" below the cursor line and clear "gap".
+ */
+void append_ga_line(gap)
+garray_T *gap;
+{
+ /* Remove trailing CR. */
+ if (gap->ga_len > 0
+ && !curbuf->b_p_bin
+ && ((char_u *)gap->ga_data)[gap->ga_len - 1] == CAR)
+ --gap->ga_len;
+ ga_append(gap, NUL);
+ ml_append(curwin->w_cursor.lnum++, gap->ga_data, 0, FALSE);
+ gap->ga_len = 0;
+}
+#endif
+
+/************************************************************************
+ * functions that use lookup tables for various things, generally to do with
+ * special key codes.
+ */
+
+/*
+ * 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'},
+ /* 'A' must be the last one */
+ {MOD_MASK_ALT, MOD_MASK_ALT, (char_u)'A'},
+ {0, 0, NUL}
+};
+
+/*
+ * Shifted key terminal codes and their unshifted equivalent.
+ * Don't add mouse codes here, they are handled separately!
+ */
+#define MOD_KEYS_ENTRY_SIZE 5
+
+static char_u modifier_keys_table[] =
+{
+ /* mod mask with modifier without modifier */
+ MOD_MASK_SHIFT, '&', '9', '@', '1', /* begin */
+ MOD_MASK_SHIFT, '&', '0', '@', '2', /* cancel */
+ MOD_MASK_SHIFT, '*', '1', '@', '4', /* command */
+ MOD_MASK_SHIFT, '*', '2', '@', '5', /* copy */
+ MOD_MASK_SHIFT, '*', '3', '@', '6', /* create */
+ MOD_MASK_SHIFT, '*', '4', 'k', 'D', /* delete char */
+ MOD_MASK_SHIFT, '*', '5', 'k', 'L', /* delete line */
+ MOD_MASK_SHIFT, '*', '7', '@', '7', /* end */
+ MOD_MASK_CTRL, KS_EXTRA, (int)KE_C_END, '@', '7', /* end */
+ MOD_MASK_SHIFT, '*', '9', '@', '9', /* exit */
+ MOD_MASK_SHIFT, '*', '0', '@', '0', /* find */
+ MOD_MASK_SHIFT, '#', '1', '%', '1', /* help */
+ MOD_MASK_SHIFT, '#', '2', 'k', 'h', /* home */
+ MOD_MASK_CTRL, KS_EXTRA, (int)KE_C_HOME, 'k', 'h', /* home */
+ MOD_MASK_SHIFT, '#', '3', 'k', 'I', /* insert */
+ MOD_MASK_SHIFT, '#', '4', 'k', 'l', /* left arrow */
+ MOD_MASK_CTRL, KS_EXTRA, (int)KE_C_LEFT, 'k', 'l', /* left arrow */
+ MOD_MASK_SHIFT, '%', 'a', '%', '3', /* message */
+ MOD_MASK_SHIFT, '%', 'b', '%', '4', /* move */
+ MOD_MASK_SHIFT, '%', 'c', '%', '5', /* next */
+ MOD_MASK_SHIFT, '%', 'd', '%', '7', /* options */
+ MOD_MASK_SHIFT, '%', 'e', '%', '8', /* previous */
+ MOD_MASK_SHIFT, '%', 'f', '%', '9', /* print */
+ MOD_MASK_SHIFT, '%', 'g', '%', '0', /* redo */
+ MOD_MASK_SHIFT, '%', 'h', '&', '3', /* replace */
+ MOD_MASK_SHIFT, '%', 'i', 'k', 'r', /* right arr. */
+ MOD_MASK_CTRL, KS_EXTRA, (int)KE_C_RIGHT, 'k', 'r', /* right arr. */
+ MOD_MASK_SHIFT, '%', 'j', '&', '5', /* resume */
+ MOD_MASK_SHIFT, '!', '1', '&', '6', /* save */
+ MOD_MASK_SHIFT, '!', '2', '&', '7', /* suspend */
+ MOD_MASK_SHIFT, '!', '3', '&', '8', /* undo */
+ MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_UP, 'k', 'u', /* up arrow */
+ MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_DOWN, 'k', 'd', /* down arrow */
+
+ /* vt100 F1 */
+ MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_XF1, KS_EXTRA, (int)KE_XF1,
+ MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_XF2, KS_EXTRA, (int)KE_XF2,
+ MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_XF3, KS_EXTRA, (int)KE_XF3,
+ MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_XF4, KS_EXTRA, (int)KE_XF4,
+
+ MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F1, 'k', '1', /* F1 */
+ MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F2, 'k', '2',
+ MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F3, 'k', '3',
+ MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F4, 'k', '4',
+ MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F5, 'k', '5',
+ MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F6, 'k', '6',
+ MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F7, 'k', '7',
+ MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F8, 'k', '8',
+ MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F9, 'k', '9',
+ MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F10, 'k', ';', /* F10 */
+
+ MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F11, 'F', '1',
+ MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F12, 'F', '2',
+ MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F13, 'F', '3',
+ MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F14, 'F', '4',
+ MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F15, 'F', '5',
+ MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F16, 'F', '6',
+ MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F17, 'F', '7',
+ MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F18, 'F', '8',
+ MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F19, 'F', '9',
+ MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F20, 'F', 'A',
+
+ MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F21, 'F', 'B',
+ MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F22, 'F', 'C',
+ MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F23, 'F', 'D',
+ MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F24, 'F', 'E',
+ MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F25, 'F', 'F',
+ MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F26, 'F', 'G',
+ MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F27, 'F', 'H',
+ MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F28, 'F', 'I',
+ MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F29, 'F', 'J',
+ MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F30, 'F', 'K',
+
+ MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F31, 'F', 'L',
+ MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F32, 'F', 'M',
+ MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F33, 'F', 'N',
+ MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F34, 'F', 'O',
+ MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F35, 'F', 'P',
+ MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F36, 'F', 'Q',
+ MOD_MASK_SHIFT, KS_EXTRA, (int)KE_S_F37, 'F', 'R',
+
+ /* TAB pseudo code*/
+ MOD_MASK_SHIFT, 'k', 'B', KS_EXTRA, (int)KE_TAB,
+
+ 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_NETTERM_MOUSE, (char_u *)"NetMouse"},
+ {K_DEC_MOUSE, (char_u *)"DecMouse"},
+#ifdef FEAT_MOUSE_JSB
+ {K_JSBTERM_MOUSE, (char_u *)"JsbMouse"},
+#endif
+ {K_URXVT_MOUSE, (char_u *)"UrxvtMouse"},
+ {K_SGR_MOUSE, (char_u *)"SgrMouse"},
+ {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"},
+ {0, NULL}
+};
+
+#define KEY_NAMES_TABLE_LEN (sizeof(key_names_table) / \
+ sizeof(struct key_name_entry))
+
+static struct mousetable {
+ int pseudo_code; /* Code for pseudo mouse event */
+ int button; /* Which mouse button is it? */
+ int is_click; /* Is it a mouse button click event? */
+ int is_drag; /* Is it a mouse drag event? */
+} mouse_table[] =
+{
+ {(int)KE_LEFTMOUSE, MOUSE_LEFT, TRUE, FALSE},
+ {(int)KE_LEFTDRAG, MOUSE_LEFT, FALSE, TRUE},
+ {(int)KE_LEFTRELEASE, MOUSE_LEFT, FALSE, FALSE},
+ {(int)KE_MIDDLEMOUSE, MOUSE_MIDDLE, TRUE, FALSE},
+ {(int)KE_MIDDLEDRAG, MOUSE_MIDDLE, FALSE, TRUE},
+ {(int)KE_MIDDLERELEASE, MOUSE_MIDDLE, FALSE, FALSE},
+ {(int)KE_RIGHTMOUSE, MOUSE_RIGHT, TRUE, FALSE},
+ {(int)KE_RIGHTDRAG, MOUSE_RIGHT, FALSE, TRUE},
+ {(int)KE_RIGHTRELEASE, MOUSE_RIGHT, FALSE, FALSE},
+ {(int)KE_X1MOUSE, MOUSE_X1, TRUE, FALSE},
+ {(int)KE_X1DRAG, MOUSE_X1, FALSE, TRUE},
+ {(int)KE_X1RELEASE, MOUSE_X1, FALSE, FALSE},
+ {(int)KE_X2MOUSE, MOUSE_X2, TRUE, FALSE},
+ {(int)KE_X2DRAG, MOUSE_X2, FALSE, TRUE},
+ {(int)KE_X2RELEASE, MOUSE_X2, FALSE, FALSE},
+ /* DRAG without CLICK */
+ {(int)KE_IGNORE, MOUSE_RELEASE, FALSE, TRUE},
+ /* RELEASE without CLICK */
+ {(int)KE_IGNORE, MOUSE_RELEASE, FALSE, FALSE},
+ {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).
+ */
+int name_to_mod_mask(c)
+int c;
+{
+ int i;
+
+ c = TOUPPER_ASC(c);
+ for (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(key, modifiers)
+int key;
+int *modifiers;
+{
+ int i;
+ int key0;
+ int key1;
+
+ if (*modifiers & (MOD_MASK_SHIFT | MOD_MASK_CTRL | MOD_MASK_ALT)) {
+ /* 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)
+ 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]);
+ }
+ }
+ return key;
+}
+
+/*
+ * Change <xHome> to <Home>, <xUp> to <Up>, etc.
+ */
+int handle_x_keys(key)
+int key;
+{
+ 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;
+ }
+ return key;
+}
+
+/*
+ * Return a string which contains the name of the given key when the given
+ * modifiers are down.
+ */
+char_u * get_special_key_name(c, modifiers)
+int c;
+int modifiers;
+{
+ static char_u string[MAX_KEY_NAME_LEN + 1];
+
+ int i, idx;
+ int table_idx;
+ char_u *s;
+
+ string[0] = '<';
+ idx = 1;
+
+ /* Key that stands for a normal character. */
+ if (IS_SPECIAL(c) && KEY2TERMCAP0(c) == KS_KEY)
+ c = KEY2TERMCAP1(c);
+
+ /*
+ * Translate shifted special keys into unshifted keys and set modifier.
+ * Same for CTRL and ALT modifiers.
+ */
+ if (IS_SPECIAL(c)) {
+ for (i = 0; modifier_keys_table[i] != 0; i += MOD_KEYS_ENTRY_SIZE)
+ if ( KEY2TERMCAP0(c) == (int)modifier_keys_table[i + 1]
+ && (int)KEY2TERMCAP1(c) == (int)modifier_keys_table[i + 2]) {
+ modifiers |= modifier_keys_table[i];
+ c = TERMCAP2KEY(modifier_keys_table[i + 3],
+ modifier_keys_table[i + 4]);
+ break;
+ }
+ }
+
+ /* try to find the key in the special key table */
+ table_idx = find_special_key_in_table(c);
+
+ /*
+ * When not a known special key, and not a printable character, try to
+ * extract modifiers.
+ */
+ if (c > 0
+ && (*mb_char2len)(c) == 1
+ ) {
+ if (table_idx < 0
+ && (!vim_isprintc(c) || (c & 0x7f) == ' ')
+ && (c & 0x80)) {
+ c &= 0x7f;
+ modifiers |= MOD_MASK_ALT;
+ /* try again, to find the un-alted key in the special key table */
+ table_idx = find_special_key_in_table(c);
+ }
+ if (table_idx < 0 && !vim_isprintc(c) && c < ' ') {
+ c += '@';
+ modifiers |= MOD_MASK_CTRL;
+ }
+ }
+
+ /* translate the modifier into a string */
+ for (i = 0; mod_mask_table[i].name != 'A'; i++)
+ if ((modifiers & mod_mask_table[i].mod_mask)
+ == mod_mask_table[i].mod_flag) {
+ string[idx++] = mod_mask_table[i].name;
+ string[idx++] = (char_u)'-';
+ }
+
+ if (table_idx < 0) { /* unknown special key, may output t_xx */
+ if (IS_SPECIAL(c)) {
+ string[idx++] = 't';
+ string[idx++] = '_';
+ string[idx++] = 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))
+ string[idx++] = c;
+ 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);
+ }
+ string[idx++] = '>';
+ string[idx] = NUL;
+ return string;
+}
+
+/*
+ * Try translating a <> name at (*srcp)[] to dst[].
+ * Return the number of characters added to dst[], zero for no match.
+ * If there is a match, srcp is advanced to after the <> name.
+ * dst[] must be big enough to hold the result (up to six characters)!
+ */
+int trans_special(srcp, dst, keycode)
+char_u **srcp;
+char_u *dst;
+int keycode; /* prefer key code, e.g. K_DEL instead of DEL */
+{
+ int modifiers = 0;
+ int key;
+ int dlen = 0;
+
+ key = find_special_key(srcp, &modifiers, keycode, FALSE);
+ if (key == 0)
+ return 0;
+
+ /* Put the appropriate modifier in a string */
+ if (modifiers != 0) {
+ dst[dlen++] = K_SPECIAL;
+ dst[dlen++] = KS_MODIFIER;
+ dst[dlen++] = modifiers;
+ }
+
+ if (IS_SPECIAL(key)) {
+ dst[dlen++] = K_SPECIAL;
+ dst[dlen++] = KEY2TERMCAP0(key);
+ dst[dlen++] = KEY2TERMCAP1(key);
+ } else if (has_mbyte && !keycode)
+ dlen += (*mb_char2bytes)(key, dst + dlen);
+ else if (keycode)
+ dlen = (int)(add_char2buf(key, dst + dlen) - dst);
+ else
+ dst[dlen++] = key;
+
+ return dlen;
+}
+
+/*
+ * Try translating a <> name at (*srcp)[], return the key and modifiers.
+ * srcp is advanced to after the <> name.
+ * returns 0 if there is no match.
+ */
+int find_special_key(srcp, modp, keycode, keep_x_key)
+char_u **srcp;
+int *modp;
+int keycode; /* prefer key code, e.g. K_DEL instead of DEL */
+int keep_x_key; /* don't translate xHome to Home key */
+{
+ char_u *last_dash;
+ char_u *end_of_name;
+ char_u *src;
+ char_u *bp;
+ int modifiers;
+ int bit;
+ int key;
+ unsigned long n;
+ int l;
+
+ src = *srcp;
+ if (src[0] != '<')
+ return 0;
+
+ /* Find end of modifier list */
+ last_dash = src;
+ for (bp = src + 1; *bp == '-' || vim_isIDc(*bp); bp++) {
+ if (*bp == '-') {
+ last_dash = bp;
+ if (bp[1] != NUL) {
+ if (has_mbyte)
+ l = mb_ptr2len(bp + 1);
+ else
+ l = 1;
+ if (bp[l + 1] == '>')
+ bp += l; /* anything accepted, like <C-?> */
+ }
+ }
+ if (bp[0] == 't' && bp[1] == '_' && bp[2] && bp[3])
+ bp += 3; /* skip t_xx, xx may be '-' or '>' */
+ else if (STRNICMP(bp, "char-", 5) == 0) {
+ vim_str2nr(bp + 5, NULL, &l, TRUE, TRUE, NULL, NULL);
+ bp += l + 5;
+ break;
+ }
+ }
+
+ if (*bp == '>') { /* found matching '>' */
+ end_of_name = bp + 1;
+
+ /* Which modifiers are given? */
+ modifiers = 0x0;
+ for (bp = src + 1; bp < last_dash; bp++) {
+ if (*bp != '-') {
+ bit = name_to_mod_mask(*bp);
+ if (bit == 0x0)
+ break; /* Illegal modifier name */
+ modifiers |= bit;
+ }
+ }
+
+ /*
+ * Legal modifier name.
+ */
+ if (bp >= last_dash) {
+ if (STRNICMP(last_dash + 1, "char-", 5) == 0
+ && VIM_ISDIGIT(last_dash[6])) {
+ /* <Char-123> or <Char-033> or <Char-0x33> */
+ vim_str2nr(last_dash + 6, NULL, NULL, TRUE, TRUE, NULL, &n);
+ key = (int)n;
+ } else {
+ /*
+ * Modifier with single letter, or special key name.
+ */
+ if (has_mbyte)
+ l = mb_ptr2len(last_dash + 1);
+ else
+ l = 1;
+ if (modifiers != 0 && last_dash[l + 1] == '>')
+ key = PTR2CHAR(last_dash + 1);
+ else {
+ key = get_special_key_code(last_dash + 1);
+ if (!keep_x_key)
+ key = handle_x_keys(key);
+ }
+ }
+
+ /*
+ * get_special_key_code() may return NUL for invalid
+ * special key name.
+ */
+ if (key != NUL) {
+ /*
+ * Only use a modifier when there is no special key code that
+ * includes the modifier.
+ */
+ key = simplify_key(key, &modifiers);
+
+ if (!keycode) {
+ /* don't want keycode, use single byte code */
+ if (key == K_BS)
+ key = BS;
+ else if (key == K_DEL || key == K_KDEL)
+ key = DEL;
+ }
+
+ /*
+ * Normal Key with modifier: Try to make a single byte code.
+ */
+ if (!IS_SPECIAL(key))
+ key = extract_modifiers(key, &modifiers);
+
+ *modp = modifiers;
+ *srcp = end_of_name;
+ return key;
+ }
+ }
+ }
+ return 0;
+}
+
+/*
+ * Try to include modifiers in the key.
+ * Changes "Shift-a" to 'A', "Alt-A" to 0xc0, etc.
+ */
+int extract_modifiers(key, modp)
+int key;
+int *modp;
+{
+ int modifiers = *modp;
+
+ if ((modifiers & MOD_MASK_SHIFT) && ASCII_ISALPHA(key)) {
+ key = TOUPPER_ASC(key);
+ modifiers &= ~MOD_MASK_SHIFT;
+ }
+ if ((modifiers & MOD_MASK_CTRL)
+ && ((key >= '?' && key <= '_') || ASCII_ISALPHA(key))
+ ) {
+ key = Ctrl_chr(key);
+ modifiers &= ~MOD_MASK_CTRL;
+ /* <C-@> is <Nul> */
+ if (key == 0)
+ key = K_ZERO;
+ }
+ if ((modifiers & MOD_MASK_ALT) && key < 0x80
+ && !enc_dbcs /* avoid creating a lead byte */
+ ) {
+ key |= 0x80;
+ modifiers &= ~MOD_MASK_ALT; /* remove the META modifier */
+ }
+
+ *modp = modifiers;
+ return key;
+}
+
+/*
+ * Try to find key "c" in the special key table.
+ * Return the index when found, -1 when not found.
+ */
+int find_special_key_in_table(c)
+int c;
+{
+ int i;
+
+ 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)
+ 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.
+ */
+int get_special_key_code(name)
+char_u *name;
+{
+ char_u *table_name;
+ char_u string[3];
+ int i, j;
+
+ /*
+ * If it's <t_xx> we get the code for xx from the termcap
+ */
+ if (name[0] == 't' && name[1] == '_' && name[2] != NUL && name[3] != NUL) {
+ string[0] = name[2];
+ string[1] = name[3];
+ string[2] = NUL;
+ if (add_termcap_entry(string, FALSE) == OK)
+ return TERMCAP2KEY(name[2], name[3]);
+ } else
+ 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]))
+ break;
+ if (!vim_isIDc(name[j]) && table_name[j] == NUL)
+ return key_names_table[i].key;
+ }
+ return 0;
+}
+
+char_u * get_key_name(i)
+int i;
+{
+ if (i >= (int)KEY_NAMES_TABLE_LEN)
+ return NULL;
+ return key_names_table[i].name;
+}
+
+/*
+ * Look up the given mouse code to return the relevant information in the other
+ * arguments. Return which button is down or was released.
+ */
+int get_mouse_button(code, is_click, is_drag)
+int code;
+int *is_click;
+int *is_drag;
+{
+ int i;
+
+ for (i = 0; mouse_table[i].pseudo_code; i++)
+ if (code == mouse_table[i].pseudo_code) {
+ *is_click = mouse_table[i].is_click;
+ *is_drag = mouse_table[i].is_drag;
+ return mouse_table[i].button;
+ }
+ return 0; /* Shouldn't get here */
+}
+
+/*
+ * Return the appropriate pseudo mouse event token (KE_LEFTMOUSE etc) based on
+ * the given information about which mouse button is down, and whether the
+ * mouse was clicked, dragged or released.
+ */
+int get_pseudo_mouse_code(button, is_click, is_drag)
+int button; /* eg MOUSE_LEFT */
+int is_click;
+int is_drag;
+{
+ int i;
+
+ for (i = 0; mouse_table[i].pseudo_code; i++)
+ if (button == mouse_table[i].button
+ && is_click == mouse_table[i].is_click
+ && is_drag == mouse_table[i].is_drag) {
+ return mouse_table[i].pseudo_code;
+ }
+ return (int)KE_IGNORE; /* not recognized, ignore it */
+}
+
+/*
+ * Return the current end-of-line type: EOL_DOS, EOL_UNIX or EOL_MAC.
+ */
+int get_fileformat(buf)
+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, eap)
+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_DOS, EOL_UNIX or EOL_MAC.
+ * Sets both 'textmode' and 'fileformat'.
+ * Note: Does _not_ set global value of 'textmode'!
+ */
+void set_fileformat(t, opt_flags)
+int t;
+int opt_flags; /* OPT_LOCAL and/or OPT_GLOBAL */
+{
+ char *p = NULL;
+
+ switch (t) {
+ case EOL_DOS:
+ p = FF_DOS;
+ curbuf->b_p_tx = TRUE;
+ break;
+ case EOL_UNIX:
+ p = FF_UNIX;
+ curbuf->b_p_tx = FALSE;
+ break;
+ case EOL_MAC:
+ p = FF_MAC;
+ curbuf->b_p_tx = FALSE;
+ break;
+ }
+ 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() {
+ switch (*p_ffs) {
+ case 'm': return EOL_MAC;
+ case 'd': return EOL_DOS;
+ }
+ return EOL_UNIX;
+}
+
+/*
+ * Call shell. Calls mch_call_shell, with 'shellxquote' added.
+ */
+int call_shell(cmd, opt)
+char_u *cmd;
+int opt;
+{
+ char_u *ncmd;
+ int retval;
+ proftime_T wait_time;
+
+ if (p_verbose > 3) {
+ verbose_enter();
+ smsg((char_u *)_("Calling shell to execute: \"%s\""),
+ cmd == NULL ? p_sh : cmd);
+ out_char('\n');
+ cursor_on();
+ 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 = mch_call_shell(cmd, opt);
+ else {
+ char_u *ecmd = cmd;
+
+ if (*p_sxe != NUL && STRCMP(p_sxq, "(") == 0) {
+ ecmd = vim_strsave_escaped_ext(cmd, p_sxe, '^', FALSE);
+ if (ecmd == NULL)
+ ecmd = cmd;
+ }
+ ncmd = alloc((unsigned)(STRLEN(ecmd) + STRLEN(p_sxq) * 2 + 1));
+ if (ncmd != NULL) {
+ 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 = mch_call_shell(ncmd, opt);
+ vim_free(ncmd);
+ } else
+ retval = -1;
+ if (ecmd != cmd)
+ vim_free(ecmd);
+ }
+ /*
+ * Check the window size, in case it changed while executing the
+ * external command.
+ */
+ shell_resized_check();
+ }
+
+ set_vim_var_nr(VV_SHELL_ERROR, (long)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() {
+ if (State & NORMAL) {
+ if (VIsual_active) {
+ if (VIsual_select)
+ return SELECTMODE;
+ return VISUAL;
+ } else if (finish_op)
+ return OP_PENDING;
+ }
+ return State;
+}
+
+/*
+ * Return TRUE if "p" points to just after a path separator.
+ * Takes care of multi-byte characters.
+ * "b" must point to the start of the file name
+ */
+int after_pathsep(b, p)
+char_u *b;
+char_u *p;
+{
+ return p > b && vim_ispathsep(p[-1])
+ && (!has_mbyte || (*mb_head_off)(b, p - 1) == 0);
+}
+
+/*
+ * Return TRUE if file names "f1" and "f2" are in the same directory.
+ * "f1" may be a short name, "f2" must be a full path.
+ */
+int same_directory(f1, f2)
+char_u *f1;
+char_u *f2;
+{
+ char_u ffname[MAXPATHL];
+ char_u *t1;
+ char_u *t2;
+
+ /* safety check */
+ if (f1 == NULL || f2 == NULL)
+ return FALSE;
+
+ (void)vim_FullName(f1, ffname, MAXPATHL, FALSE);
+ t1 = gettail_sep(ffname);
+ t2 = gettail_sep(f2);
+ return t1 - ffname == t2 - f2
+ && pathcmp((char *)ffname, (char *)f2, (int)(t1 - ffname)) == 0;
+}
+
+#if defined(FEAT_SESSION) || defined(MSWIN) || defined(FEAT_GUI_MAC) \
+ || ((defined(FEAT_GUI_GTK)) \
+ && ( defined(FEAT_WINDOWS) || defined(FEAT_DND)) ) \
+ || defined(FEAT_SUN_WORKSHOP) || defined(FEAT_NETBEANS_INTG) \
+ || defined(PROTO)
+/*
+ * Change to a file's directory.
+ * Caller must call shorten_fnames()!
+ * Return OK or FAIL.
+ */
+int vim_chdirfile(fname)
+char_u *fname;
+{
+ char_u dir[MAXPATHL];
+
+ vim_strncpy(dir, fname, MAXPATHL - 1);
+ *gettail_sep(dir) = NUL;
+ return mch_chdir((char *)dir) == 0 ? OK : FAIL;
+}
+#endif
+
+#if defined(STAT_IGNORES_SLASH) || defined(PROTO)
+/*
+ * Check if "name" ends in a slash and is not a directory.
+ * Used for systems where stat() ignores a trailing slash on a file name.
+ * The Vim code assumes a trailing slash is only ignored for a directory.
+ */
+int illegal_slash(name)
+char *name;
+{
+ if (name[0] == NUL)
+ return FALSE; /* no file name is not illegal */
+ if (name[strlen(name) - 1] != '/')
+ return FALSE; /* no trailing slash */
+ if (mch_isdir((char_u *)name))
+ return FALSE; /* trailing slash for a directory */
+ return TRUE;
+}
+#endif
+
+#if defined(CURSOR_SHAPE) || defined(PROTO)
+
+/*
+ * 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},
+};
+
+
+/*
+ * Parse the 'guicursor' option ("what" is SHAPE_CURSOR) or 'mouseshape'
+ * ("what" is SHAPE_MOUSE).
+ * Returns error message for an illegal option, NULL otherwise.
+ */
+char_u * parse_shape_opt(what)
+int what;
+{
+ char_u *modep;
+ char_u *colonp;
+ char_u *commap;
+ char_u *slashp;
+ char_u *p, *endp;
+ int idx = 0; /* init for GCC */
+ int all_idx;
+ int len;
+ int i;
+ long n;
+ 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.
+ */
+ modep = p_guicursor;
+ while (*modep != NUL) {
+ colonp = vim_strchr(modep, ':');
+ if (colonp == NULL)
+ return (char_u *)N_("E545: Missing colon");
+ 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.
+ */
+ all_idx = -1;
+ while (modep < colonp || all_idx > = 0) {
+ if (all_idx < 0) {
+ /* Find the mode. */
+ if (modep[1] == '-' || modep[1] == ':')
+ len = 1;
+ else
+ len = 2;
+ if (len == 1 && TOLOWER_ASC(modep[0]) == 'a')
+ all_idx = SHAPE_IDX_COUNT - 1;
+ else {
+ for (idx = 0; idx < SHAPE_IDX_COUNT; ++idx)
+ if (STRNICMP(modep, shape_table[idx].name, len)
+ == 0)
+ break;
+ if (idx == SHAPE_IDX_COUNT
+ || (shape_table[idx].used_for & what) == 0)
+ return (char_u *)N_("E546: Illegal mode");
+ if (len == 2 && modep[0] == 'v' && modep[1] == 'e')
+ found_ve = TRUE;
+ }
+ modep += len + 1;
+ }
+
+ if (all_idx >= 0)
+ idx = all_idx--;
+ else if (round == 2) {
+ {
+ /* 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;
+ }
+ }
+
+ /* Parse the part after the colon */
+ for (p = colonp + 1; *p && *p != ','; ) {
+ {
+ /*
+ * First handle the ones with a number argument.
+ */
+ i = *p;
+ len = 0;
+ if (STRNICMP(p, "ver", 3) == 0)
+ len = 3;
+ else if (STRNICMP(p, "hor", 3) == 0)
+ len = 3;
+ else if (STRNICMP(p, "blinkwait", 9) == 0)
+ len = 9;
+ else if (STRNICMP(p, "blinkon", 7) == 0)
+ len = 7;
+ else if (STRNICMP(p, "blinkoff", 8) == 0)
+ len = 8;
+ if (len != 0) {
+ p += len;
+ if (!VIM_ISDIGIT(*p))
+ return (char_u *)N_("E548: digit expected");
+ n = getdigits(&p);
+ if (len == 3) { /* "ver" or "hor" */
+ if (n == 0)
+ return (char_u *)N_("E549: Illegal percentage");
+ if (round == 2) {
+ if (TOLOWER_ASC(i) == 'v')
+ shape_table[idx].shape = SHAPE_VER;
+ else
+ shape_table[idx].shape = SHAPE_HOR;
+ shape_table[idx].percentage = n;
+ }
+ } else if (round == 2) {
+ if (len == 9)
+ shape_table[idx].blinkwait = n;
+ else if (len == 7)
+ shape_table[idx].blinkon = n;
+ else
+ shape_table[idx].blinkoff = n;
+ }
+ } else if (STRNICMP(p, "block", 5) == 0) {
+ if (round == 2)
+ shape_table[idx].shape = SHAPE_BLOCK;
+ p += 5;
+ } else { /* must be a highlight group name then */
+ endp = vim_strchr(p, '-');
+ if (commap == NULL) { /* last part */
+ if (endp == NULL)
+ endp = p + STRLEN(p); /* find end of part */
+ } else if (endp > commap || endp == NULL)
+ endp = commap;
+ slashp = vim_strchr(p, '/');
+ if (slashp != NULL && slashp < endp) {
+ /* "group/langmap_group" */
+ i = syn_check_group(p, (int)(slashp - p));
+ p = slashp + 1;
+ }
+ if (round == 2) {
+ shape_table[idx].id = syn_check_group(p,
+ (int)(endp - p));
+ shape_table[idx].id_lm = shape_table[idx].id;
+ if (slashp != NULL && slashp < endp)
+ shape_table[idx].id = i;
+ }
+ p = endp;
+ }
+ } /* if (what != SHAPE_MOUSE) */
+
+ if (*p == '-')
+ ++p;
+ }
+ }
+ modep = p;
+ if (*modep == ',')
+ ++modep;
+ }
+ }
+
+ /* If the 's' flag is not given, use the 'v' cursor for 's' */
+ if (!found_ve) {
+ {
+ shape_table[SHAPE_IDX_VE].shape = shape_table[SHAPE_IDX_V].shape;
+ shape_table[SHAPE_IDX_VE].percentage =
+ shape_table[SHAPE_IDX_V].percentage;
+ shape_table[SHAPE_IDX_VE].blinkwait =
+ shape_table[SHAPE_IDX_V].blinkwait;
+ shape_table[SHAPE_IDX_VE].blinkon =
+ shape_table[SHAPE_IDX_V].blinkon;
+ shape_table[SHAPE_IDX_VE].blinkoff =
+ shape_table[SHAPE_IDX_V].blinkoff;
+ shape_table[SHAPE_IDX_VE].id = shape_table[SHAPE_IDX_V].id;
+ shape_table[SHAPE_IDX_VE].id_lm = shape_table[SHAPE_IDX_V].id_lm;
+ }
+ }
+
+ return NULL;
+}
+
+# if defined(MCH_CURSOR_SHAPE) || defined(FEAT_GUI) \
+ || defined(FEAT_MOUSESHAPE) || defined(PROTO)
+/*
+ * Return the index into shape_table[] for the current mode.
+ * When "mouse" is TRUE, consider indexes valid for the mouse pointer.
+ */
+int get_shape_idx(mouse)
+int mouse;
+{
+ if (!mouse && State == SHOWMATCH)
+ return SHAPE_IDX_SM;
+ if (State & VREPLACE_FLAG)
+ return SHAPE_IDX_R;
+ if (State & REPLACE_FLAG)
+ return SHAPE_IDX_R;
+ if (State & INSERT)
+ return SHAPE_IDX_I;
+ if (State & CMDLINE) {
+ if (cmdline_at_end())
+ return SHAPE_IDX_C;
+ if (cmdline_overstrike())
+ return SHAPE_IDX_CR;
+ return SHAPE_IDX_CI;
+ }
+ if (finish_op)
+ return SHAPE_IDX_O;
+ if (VIsual_active) {
+ if (*p_sel == 'e')
+ return SHAPE_IDX_VE;
+ else
+ return SHAPE_IDX_V;
+ }
+ return SHAPE_IDX_N;
+}
+#endif
+
+
+#endif /* CURSOR_SHAPE */
+
+
+/*
+ * Optional encryption support.
+ * Mohsin Ahmed, mosh@sasi.com, 98-09-24
+ * Based on zip/crypt sources.
+ *
+ * NOTE FOR USA: Since 2000 exporting this code from the USA is allowed to
+ * most countries. There are a few exceptions, but that still should not be a
+ * problem since this code was originally created in Europe and India.
+ *
+ * Blowfish addition originally made by Mohsin Ahmed,
+ * http://www.cs.albany.edu/~mosh 2010-03-14
+ * Based on blowfish by Bruce Schneier (http://www.schneier.com/blowfish.html)
+ * and sha256 by Christophe Devine.
+ */
+
+/* from zip.h */
+
+typedef unsigned short ush; /* unsigned 16-bit value */
+typedef unsigned long ulg; /* unsigned 32-bit value */
+
+static void make_crc_tab __ARGS((void));
+
+static ulg crc_32_tab[256];
+
+/*
+ * Fill the CRC table.
+ */
+static void make_crc_tab() {
+ ulg s,t,v;
+ static int done = FALSE;
+
+ if (done)
+ return;
+ for (t = 0; t < 256; t++) {
+ v = t;
+ for (s = 0; s < 8; s++)
+ v = (v >> 1) ^ ((v & 1) * (ulg)0xedb88320L);
+ crc_32_tab[t] = v;
+ }
+ done = TRUE;
+}
+
+#define CRC32(c, b) (crc_32_tab[((int)(c) ^ (b)) & 0xff] ^ ((c) >> 8))
+
+static ulg keys[3]; /* keys defining the pseudo-random sequence */
+
+/*
+ * Return the next byte in the pseudo-random sequence.
+ */
+#define DECRYPT_BYTE_ZIP(t) { \
+ ush temp; \
+ \
+ temp = (ush)keys[2] | 2; \
+ t = (int)(((unsigned)(temp * (temp ^ 1U)) >> 8) & 0xff); \
+}
+
+/*
+ * Update the encryption keys with the next byte of plain text.
+ */
+#define UPDATE_KEYS_ZIP(c) { \
+ keys[0] = CRC32(keys[0], (c)); \
+ keys[1] += keys[0] & 0xff; \
+ keys[1] = keys[1] * 134775813L + 1; \
+ keys[2] = CRC32(keys[2], (int)(keys[1] >> 24)); \
+}
+
+static int crypt_busy = 0;
+static ulg saved_keys[3];
+static int saved_crypt_method;
+
+/*
+ * Return int value for crypt method string:
+ * 0 for "zip", the old method. Also for any non-valid value.
+ * 1 for "blowfish".
+ */
+int crypt_method_from_string(s)
+char_u *s;
+{
+ return *s == 'b' ? 1 : 0;
+}
+
+/*
+ * Get the crypt method for buffer "buf" as a number.
+ */
+int get_crypt_method(buf)
+buf_T *buf;
+{
+ return crypt_method_from_string(*buf->b_p_cm == NUL ? p_cm : buf->b_p_cm);
+}
+
+/*
+ * Set the crypt method for buffer "buf" to "method" using the int value as
+ * returned by crypt_method_from_string().
+ */
+void set_crypt_method(buf, method)
+buf_T *buf;
+int method;
+{
+ free_string_option(buf->b_p_cm);
+ buf->b_p_cm = vim_strsave((char_u *)(method == 0 ? "zip" : "blowfish"));
+}
+
+/*
+ * Prepare for initializing encryption. If already doing encryption then save
+ * the state.
+ * Must always be called symmetrically with crypt_pop_state().
+ */
+void crypt_push_state() {
+ if (crypt_busy == 1) {
+ /* save the state */
+ if (use_crypt_method == 0) {
+ saved_keys[0] = keys[0];
+ saved_keys[1] = keys[1];
+ saved_keys[2] = keys[2];
+ } else
+ bf_crypt_save();
+ saved_crypt_method = use_crypt_method;
+ } else if (crypt_busy > 1)
+ EMSG2(_(e_intern2), "crypt_push_state()");
+ ++crypt_busy;
+}
+
+/*
+ * End encryption. If doing encryption before crypt_push_state() then restore
+ * the saved state.
+ * Must always be called symmetrically with crypt_push_state().
+ */
+void crypt_pop_state() {
+ --crypt_busy;
+ if (crypt_busy == 1) {
+ use_crypt_method = saved_crypt_method;
+ if (use_crypt_method == 0) {
+ keys[0] = saved_keys[0];
+ keys[1] = saved_keys[1];
+ keys[2] = saved_keys[2];
+ } else
+ bf_crypt_restore();
+ }
+}
+
+/*
+ * Encrypt "from[len]" into "to[len]".
+ * "from" and "to" can be equal to encrypt in place.
+ */
+void crypt_encode(from, len, to)
+char_u *from;
+size_t len;
+char_u *to;
+{
+ size_t i;
+ int ztemp, t;
+
+ if (use_crypt_method == 0)
+ for (i = 0; i < len; ++i) {
+ ztemp = from[i];
+ DECRYPT_BYTE_ZIP(t);
+ UPDATE_KEYS_ZIP(ztemp);
+ to[i] = t ^ ztemp;
+ }
+ else
+ bf_crypt_encode(from, len, to);
+}
+
+/*
+ * Decrypt "ptr[len]" in place.
+ */
+void crypt_decode(ptr, len)
+char_u *ptr;
+long len;
+{
+ char_u *p;
+
+ if (use_crypt_method == 0)
+ for (p = ptr; p < ptr + len; ++p) {
+ ush temp;
+
+ temp = (ush)keys[2] | 2;
+ temp = (int)(((unsigned)(temp * (temp ^ 1U)) >> 8) & 0xff);
+ UPDATE_KEYS_ZIP(*p ^= temp);
+ }
+ else
+ bf_crypt_decode(ptr, len);
+}
+
+/*
+ * Initialize the encryption keys and the random header according to
+ * the given password.
+ * If "passwd" is NULL or empty, don't do anything.
+ */
+void crypt_init_keys(passwd)
+char_u *passwd; /* password string with which to modify keys */
+{
+ if (passwd != NULL && *passwd != NUL) {
+ if (use_crypt_method == 0) {
+ char_u *p;
+
+ make_crc_tab();
+ keys[0] = 305419896L;
+ keys[1] = 591751049L;
+ keys[2] = 878082192L;
+ for (p = passwd; *p!= NUL; ++p) {
+ UPDATE_KEYS_ZIP((int)*p);
+ }
+ } else
+ bf_crypt_init_keys(passwd);
+ }
+}
+
+/*
+ * Free an allocated crypt key. Clear the text to make sure it doesn't stay
+ * in memory anywhere.
+ */
+void free_crypt_key(key)
+char_u *key;
+{
+ char_u *p;
+
+ if (key != NULL) {
+ for (p = key; *p != NUL; ++p)
+ *p = 0;
+ vim_free(key);
+ }
+}
+
+/*
+ * Ask the user for a crypt key.
+ * When "store" is TRUE, the new key is stored in the 'key' option, and the
+ * 'key' option value is returned: Don't free it.
+ * When "store" is FALSE, the typed key is returned in allocated memory.
+ * Returns NULL on failure.
+ */
+char_u * get_crypt_key(store, twice)
+int store;
+int twice; /* Ask for the key twice. */
+{
+ char_u *p1, *p2 = NULL;
+ int round;
+
+ for (round = 0;; ++round) {
+ cmdline_star = TRUE;
+ cmdline_row = msg_row;
+ p1 = getcmdline_prompt(NUL, round == 0
+ ? (char_u *)_("Enter encryption key: ")
+ : (char_u *)_("Enter same key again: "), 0, EXPAND_NOTHING,
+ NULL);
+ cmdline_star = FALSE;
+
+ if (p1 == NULL)
+ break;
+
+ if (round == twice) {
+ if (p2 != NULL && STRCMP(p1, p2) != 0) {
+ MSG(_("Keys don't match!"));
+ free_crypt_key(p1);
+ free_crypt_key(p2);
+ p2 = NULL;
+ round = -1; /* do it again */
+ continue;
+ }
+
+ if (store) {
+ set_option_value((char_u *)"key", 0L, p1, OPT_LOCAL);
+ free_crypt_key(p1);
+ p1 = curbuf->b_p_key;
+ }
+ break;
+ }
+ p2 = p1;
+ }
+
+ /* since the user typed this, no need to wait for return */
+ if (msg_didout)
+ msg_putchar('\n');
+ need_wait_return = FALSE;
+ msg_didout = FALSE;
+
+ free_crypt_key(p2);
+ return p1;
+}
+
+
+/* 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.
+ */
+
+/*
+ * type for the directory search stack
+ */
+typedef struct ff_stack {
+ struct ff_stack *ffs_prev;
+
+ /* the fix part (no wildcards) and the part containing the wildcards
+ * of the search path
+ */
+ char_u *ffs_fix_path;
+ char_u *ffs_wc_path;
+
+ /* files/dirs found in the above directory, matched by the first wildcard
+ * of wc_part
+ */
+ char_u **ffs_filearray;
+ int ffs_filearray_size;
+ char_u ffs_filearray_cur; /* needed for partly handled dirs */
+
+ /* to store status of partly handled directories
+ * 0: we work on this directory for the first time
+ * 1: this directory was partly searched in an earlier step
+ */
+ int ffs_stage;
+
+ /* How deep are we in the directory tree?
+ * Counts backward from value of level parameter to vim_findfile_init
+ */
+ int ffs_level;
+
+ /* Did we already expand '**' to an empty string? */
+ int ffs_star_star_empty;
+} ff_stack_T;
+
+/*
+ * type for already visited directories or files.
+ */
+typedef struct ff_visited {
+ struct ff_visited *ffv_next;
+
+ /* Visited directories are different if the wildcard string are
+ * different. So we have to save it.
+ */
+ char_u *ffv_wc_path;
+ /* for unix use inode etc for comparison (needed because of links), else
+ * use filename.
+ */
+#ifdef UNIX
+ int ffv_dev_valid; /* ffv_dev and ffv_ino were set */
+ dev_t ffv_dev; /* device number */
+ ino_t ffv_ino; /* inode number */
+#endif
+ /* The memory for this struct is allocated according to the length of
+ * ffv_fname.
+ */
+ char_u ffv_fname[1]; /* actually longer */
+} ff_visited_T;
+
+/*
+ * We might have to manage several visited lists during a search.
+ * This is especially needed for the tags option. If tags is set to:
+ * "./++/tags,./++/TAGS,++/tags" (replace + with *)
+ * So we have to do 3 searches:
+ * 1) search from the current files directory downward for the file "tags"
+ * 2) search from the current files directory downward for the file "TAGS"
+ * 3) search from Vims current directory downwards for the file "tags"
+ * As you can see, the first and the third search are for the same file, so for
+ * the third search we can use the visited list of the first search. For the
+ * second search we must start from a empty visited list.
+ * The struct ff_visited_list_hdr is used to manage a linked list of already
+ * visited lists.
+ */
+typedef struct ff_visited_list_hdr {
+ struct ff_visited_list_hdr *ffvl_next;
+
+ /* the filename the attached visited list is for */
+ char_u *ffvl_filename;
+
+ ff_visited_T *ffvl_visited_list;
+
+} ff_visited_list_hdr_T;
+
+
+/*
+ * '**' can be expanded to several directory levels.
+ * Set the default maximum depth.
+ */
+#define FF_MAX_STAR_STAR_EXPAND ((char_u)30)
+
+/*
+ * The search context:
+ * ffsc_stack_ptr: the stack for the dirs to search
+ * ffsc_visited_list: the currently active visited list
+ * ffsc_dir_visited_list: the currently active visited list for search dirs
+ * ffsc_visited_lists_list: the list of all visited lists
+ * ffsc_dir_visited_lists_list: the list of all visited lists for search dirs
+ * ffsc_file_to_search: the file to search for
+ * ffsc_start_dir: the starting directory, if search path was relative
+ * ffsc_fix_path: the fix part of the given path (without wildcards)
+ * Needed for upward search.
+ * ffsc_wc_path: the part of the given path containing wildcards
+ * ffsc_level: how many levels of dirs to search downwards
+ * ffsc_stopdirs_v: array of stop directories for upward search
+ * ffsc_find_what: FINDFILE_BOTH, FINDFILE_DIR or FINDFILE_FILE
+ * ffsc_tagfile: searching for tags file, don't use 'suffixesadd'
+ */
+typedef struct ff_search_ctx_T {
+ ff_stack_T *ffsc_stack_ptr;
+ ff_visited_list_hdr_T *ffsc_visited_list;
+ ff_visited_list_hdr_T *ffsc_dir_visited_list;
+ ff_visited_list_hdr_T *ffsc_visited_lists_list;
+ ff_visited_list_hdr_T *ffsc_dir_visited_lists_list;
+ char_u *ffsc_file_to_search;
+ char_u *ffsc_start_dir;
+ char_u *ffsc_fix_path;
+ char_u *ffsc_wc_path;
+ int ffsc_level;
+ char_u **ffsc_stopdirs_v;
+ int ffsc_find_what;
+ int ffsc_tagfile;
+} ff_search_ctx_T;
+
+/* locally needed functions */
+static int ff_check_visited __ARGS((ff_visited_T **, char_u *, char_u *));
+static void vim_findfile_free_visited_list __ARGS(
+ (ff_visited_list_hdr_T **list_headp));
+static void ff_free_visited_list __ARGS((ff_visited_T *vl));
+static ff_visited_list_hdr_T* ff_get_visited_list __ARGS(
+ (char_u *, ff_visited_list_hdr_T **list_headp));
+static int ff_wc_equal __ARGS((char_u *s1, char_u *s2));
+
+static void ff_push __ARGS((ff_search_ctx_T *search_ctx, ff_stack_T *stack_ptr));
+static ff_stack_T *ff_pop __ARGS((ff_search_ctx_T *search_ctx));
+static void ff_clear __ARGS((ff_search_ctx_T *search_ctx));
+static void ff_free_stack_element __ARGS((ff_stack_T *stack_ptr));
+static ff_stack_T *ff_create_stack_element __ARGS((char_u *, char_u *, int, int));
+static int ff_path_in_stoplist __ARGS((char_u *, int, char_u **));
+
+static char_u e_pathtoolong[] = N_("E854: path too long for completion");
+
+
+/*
+ * Initialization routine for vim_findfile().
+ *
+ * Returns the newly allocated search context or NULL if an error occurred.
+ *
+ * Don't forget to clean up by calling vim_findfile_cleanup() if you are done
+ * with the search context.
+ *
+ * Find the file 'filename' in the directory 'path'.
+ * The parameter 'path' may contain wildcards. If so only search 'level'
+ * directories deep. The parameter 'level' is the absolute maximum and is
+ * not related to restricts given to the '**' wildcard. If 'level' is 100
+ * and you use '**200' vim_findfile() will stop after 100 levels.
+ *
+ * 'filename' cannot contain wildcards! It is used as-is, no backslashes to
+ * escape special characters.
+ *
+ * If 'stopdirs' is not NULL and nothing is found downward, the search is
+ * restarted on the next higher directory level. This is repeated until the
+ * start-directory of a search is contained in 'stopdirs'. 'stopdirs' has the
+ * format ";*<dirname>*\(;<dirname>\)*;\=$".
+ *
+ * If the 'path' is relative, the starting dir for the search is either VIM's
+ * current dir or if the path starts with "./" the current files dir.
+ * If the 'path' is absolute, the starting dir is that part of the path before
+ * the first wildcard.
+ *
+ * Upward search is only done on the starting dir.
+ *
+ * If 'free_visited' is TRUE the list of already visited files/directories is
+ * cleared. Set this to FALSE if you just want to search from another
+ * directory, but want to be sure that no directory from a previous search is
+ * searched again. This is useful if you search for a file at different places.
+ * The list of visited files/dirs can also be cleared with the function
+ * vim_findfile_free_visited().
+ *
+ * Set the parameter 'find_what' to FINDFILE_DIR if you want to search for
+ * directories only, FINDFILE_FILE for files only, FINDFILE_BOTH for both.
+ *
+ * A search context returned by a previous call to vim_findfile_init() can be
+ * passed in the parameter "search_ctx_arg". This context is reused and
+ * reinitialized with the new parameters. The list of already visited
+ * directories from this context is only deleted if the parameter
+ * "free_visited" is true. Be aware that the passed "search_ctx_arg" is freed
+ * if the reinitialization fails.
+ *
+ * If you don't have a search context from a previous call "search_ctx_arg"
+ * must be NULL.
+ *
+ * This function silently ignores a few errors, vim_findfile() will have
+ * limited functionality then.
+ */
+void * vim_findfile_init(path, filename, stopdirs, level, free_visited,
+ find_what,
+ search_ctx_arg, tagfile,
+ rel_fname)
+char_u *path;
+char_u *filename;
+char_u *stopdirs UNUSED;
+int level;
+int free_visited;
+int find_what;
+void *search_ctx_arg;
+int tagfile; /* expanding names of tags files */
+char_u *rel_fname; /* file name to use for "." */
+{
+ char_u *wc_part;
+ ff_stack_T *sptr;
+ ff_search_ctx_T *search_ctx;
+
+ /* If a search context is given by the caller, reuse it, else allocate a
+ * new one.
+ */
+ if (search_ctx_arg != NULL)
+ search_ctx = search_ctx_arg;
+ else {
+ search_ctx = (ff_search_ctx_T*)alloc((unsigned)sizeof(ff_search_ctx_T));
+ if (search_ctx == NULL)
+ goto error_return;
+ vim_memset(search_ctx, 0, sizeof(ff_search_ctx_T));
+ }
+ search_ctx->ffsc_find_what = find_what;
+ search_ctx->ffsc_tagfile = tagfile;
+
+ /* clear the search context, but NOT the visited lists */
+ ff_clear(search_ctx);
+
+ /* clear visited list if wanted */
+ if (free_visited == TRUE)
+ vim_findfile_free_visited(search_ctx);
+ else {
+ /* Reuse old visited lists. Get the visited list for the given
+ * filename. If no list for the current filename exists, creates a new
+ * one. */
+ search_ctx->ffsc_visited_list = ff_get_visited_list(filename,
+ &search_ctx->ffsc_visited_lists_list);
+ if (search_ctx->ffsc_visited_list == NULL)
+ goto error_return;
+ search_ctx->ffsc_dir_visited_list = ff_get_visited_list(filename,
+ &search_ctx->ffsc_dir_visited_lists_list);
+ if (search_ctx->ffsc_dir_visited_list == NULL)
+ goto error_return;
+ }
+
+ if (ff_expand_buffer == NULL) {
+ ff_expand_buffer = (char_u*)alloc(MAXPATHL);
+ if (ff_expand_buffer == NULL)
+ goto error_return;
+ }
+
+ /* Store information on starting dir now if path is relative.
+ * If path is absolute, we do that later. */
+ if (path[0] == '.'
+ && (vim_ispathsep(path[1]) || path[1] == NUL)
+ && (!tagfile || vim_strchr(p_cpo, CPO_DOTTAG) == NULL)
+ && rel_fname != NULL) {
+ int len = (int)(gettail(rel_fname) - rel_fname);
+
+ if (!vim_isAbsName(rel_fname) && len + 1 < MAXPATHL) {
+ /* Make the start dir an absolute path name. */
+ vim_strncpy(ff_expand_buffer, rel_fname, len);
+ search_ctx->ffsc_start_dir = FullName_save(ff_expand_buffer, FALSE);
+ } else
+ search_ctx->ffsc_start_dir = vim_strnsave(rel_fname, len);
+ if (search_ctx->ffsc_start_dir == NULL)
+ goto error_return;
+ if (*++path != NUL)
+ ++path;
+ } else if (*path == NUL || !vim_isAbsName(path)) {
+#ifdef BACKSLASH_IN_FILENAME
+ /* "c:dir" needs "c:" to be expanded, otherwise use current dir */
+ if (*path != NUL && path[1] == ':') {
+ char_u drive[3];
+
+ drive[0] = path[0];
+ drive[1] = ':';
+ drive[2] = NUL;
+ if (vim_FullName(drive, ff_expand_buffer, MAXPATHL, TRUE) == FAIL)
+ goto error_return;
+ path += 2;
+ } else
+#endif
+ if (mch_dirname(ff_expand_buffer, MAXPATHL) == FAIL)
+ goto error_return;
+
+ search_ctx->ffsc_start_dir = vim_strsave(ff_expand_buffer);
+ if (search_ctx->ffsc_start_dir == NULL)
+ goto error_return;
+
+#ifdef BACKSLASH_IN_FILENAME
+ /* A path that starts with "/dir" is relative to the drive, not to the
+ * directory (but not for "//machine/dir"). Only use the drive name. */
+ if ((*path == '/' || *path == '\\')
+ && path[1] != path[0]
+ && search_ctx->ffsc_start_dir[1] == ':')
+ search_ctx->ffsc_start_dir[2] = NUL;
+#endif
+ }
+
+ /*
+ * If stopdirs are given, split them into an array of pointers.
+ * If this fails (mem allocation), there is no upward search at all or a
+ * stop directory is not recognized -> continue silently.
+ * If stopdirs just contains a ";" or is empty,
+ * search_ctx->ffsc_stopdirs_v will only contain a NULL pointer. This
+ * is handled as unlimited upward search. See function
+ * ff_path_in_stoplist() for details.
+ */
+ if (stopdirs != NULL) {
+ char_u *walker = stopdirs;
+ int dircount;
+
+ while (*walker == ';')
+ walker++;
+
+ dircount = 1;
+ search_ctx->ffsc_stopdirs_v =
+ (char_u **)alloc((unsigned)sizeof(char_u *));
+
+ if (search_ctx->ffsc_stopdirs_v != NULL) {
+ do {
+ char_u *helper;
+ void *ptr;
+
+ helper = walker;
+ ptr = vim_realloc(search_ctx->ffsc_stopdirs_v,
+ (dircount + 1) * sizeof(char_u *));
+ if (ptr)
+ search_ctx->ffsc_stopdirs_v = ptr;
+ else
+ /* ignore, keep what we have and continue */
+ break;
+ walker = vim_strchr(walker, ';');
+ if (walker) {
+ search_ctx->ffsc_stopdirs_v[dircount-1] =
+ vim_strnsave(helper, (int)(walker - helper));
+ walker++;
+ } else
+ /* this might be "", which means ascent till top
+ * of directory tree.
+ */
+ search_ctx->ffsc_stopdirs_v[dircount-1] =
+ vim_strsave(helper);
+
+ dircount++;
+
+ } while (walker != NULL);
+ search_ctx->ffsc_stopdirs_v[dircount-1] = NULL;
+ }
+ }
+
+ search_ctx->ffsc_level = level;
+
+ /* split into:
+ * -fix path
+ * -wildcard_stuff (might be NULL)
+ */
+ wc_part = vim_strchr(path, '*');
+ if (wc_part != NULL) {
+ int llevel;
+ int len;
+ char *errpt;
+
+ /* save the fix part of the path */
+ search_ctx->ffsc_fix_path = vim_strnsave(path, (int)(wc_part - path));
+
+ /*
+ * copy wc_path and add restricts to the '**' wildcard.
+ * The octet after a '**' is used as a (binary) counter.
+ * So '**3' is transposed to '**^C' ('^C' is ASCII value 3)
+ * or '**76' is transposed to '**N'( 'N' is ASCII value 76).
+ * For EBCDIC you get different character values.
+ * If no restrict is given after '**' the default is used.
+ * Due to this technique the path looks awful if you print it as a
+ * string.
+ */
+ len = 0;
+ while (*wc_part != NUL) {
+ if (len + 5 >= MAXPATHL) {
+ EMSG(_(e_pathtoolong));
+ break;
+ }
+ if (STRNCMP(wc_part, "**", 2) == 0) {
+ ff_expand_buffer[len++] = *wc_part++;
+ ff_expand_buffer[len++] = *wc_part++;
+
+ llevel = strtol((char *)wc_part, &errpt, 10);
+ if ((char_u *)errpt != wc_part && llevel > 0 && llevel < 255)
+ ff_expand_buffer[len++] = llevel;
+ else if ((char_u *)errpt != wc_part && llevel == 0)
+ /* restrict is 0 -> remove already added '**' */
+ len -= 2;
+ else
+ ff_expand_buffer[len++] = FF_MAX_STAR_STAR_EXPAND;
+ wc_part = (char_u *)errpt;
+ if (*wc_part != NUL && !vim_ispathsep(*wc_part)) {
+ EMSG2(_(
+ "E343: Invalid path: '**[number]' must be at the end of the path or be followed by '%s'."),
+ PATHSEPSTR);
+ goto error_return;
+ }
+ } else
+ ff_expand_buffer[len++] = *wc_part++;
+ }
+ ff_expand_buffer[len] = NUL;
+ search_ctx->ffsc_wc_path = vim_strsave(ff_expand_buffer);
+
+ if (search_ctx->ffsc_wc_path == NULL)
+ goto error_return;
+ } else
+ search_ctx->ffsc_fix_path = vim_strsave(path);
+
+ if (search_ctx->ffsc_start_dir == NULL) {
+ /* store the fix part as startdir.
+ * This is needed if the parameter path is fully qualified.
+ */
+ search_ctx->ffsc_start_dir = vim_strsave(search_ctx->ffsc_fix_path);
+ if (search_ctx->ffsc_start_dir == NULL)
+ goto error_return;
+ search_ctx->ffsc_fix_path[0] = NUL;
+ }
+
+ /* create an absolute path */
+ if (STRLEN(search_ctx->ffsc_start_dir)
+ + STRLEN(search_ctx->ffsc_fix_path) + 3 >= MAXPATHL) {
+ EMSG(_(e_pathtoolong));
+ goto error_return;
+ }
+ STRCPY(ff_expand_buffer, search_ctx->ffsc_start_dir);
+ add_pathsep(ff_expand_buffer);
+ {
+ int eb_len = (int)STRLEN(ff_expand_buffer);
+ char_u *buf = alloc(eb_len
+ + (int)STRLEN(search_ctx->ffsc_fix_path) + 1);
+
+ STRCPY(buf, ff_expand_buffer);
+ STRCPY(buf + eb_len, search_ctx->ffsc_fix_path);
+ if (mch_isdir(buf)) {
+ STRCAT(ff_expand_buffer, search_ctx->ffsc_fix_path);
+ add_pathsep(ff_expand_buffer);
+ } else {
+ char_u *p = gettail(search_ctx->ffsc_fix_path);
+ char_u *wc_path = NULL;
+ char_u *temp = NULL;
+ int len = 0;
+
+ if (p > search_ctx->ffsc_fix_path) {
+ len = (int)(p - search_ctx->ffsc_fix_path) - 1;
+ STRNCAT(ff_expand_buffer, search_ctx->ffsc_fix_path, len);
+ add_pathsep(ff_expand_buffer);
+ } else
+ len = (int)STRLEN(search_ctx->ffsc_fix_path);
+
+ if (search_ctx->ffsc_wc_path != NULL) {
+ wc_path = vim_strsave(search_ctx->ffsc_wc_path);
+ temp = alloc((int)(STRLEN(search_ctx->ffsc_wc_path)
+ + STRLEN(search_ctx->ffsc_fix_path + len)
+ + 1));
+ }
+
+ if (temp == NULL || wc_path == NULL) {
+ vim_free(buf);
+ vim_free(temp);
+ vim_free(wc_path);
+ goto error_return;
+ }
+
+ STRCPY(temp, search_ctx->ffsc_fix_path + len);
+ STRCAT(temp, search_ctx->ffsc_wc_path);
+ vim_free(search_ctx->ffsc_wc_path);
+ vim_free(wc_path);
+ search_ctx->ffsc_wc_path = temp;
+ }
+ vim_free(buf);
+ }
+
+ sptr = ff_create_stack_element(ff_expand_buffer,
+ search_ctx->ffsc_wc_path,
+ level, 0);
+
+ if (sptr == NULL)
+ goto error_return;
+
+ ff_push(search_ctx, sptr);
+
+ search_ctx->ffsc_file_to_search = vim_strsave(filename);
+ if (search_ctx->ffsc_file_to_search == NULL)
+ goto error_return;
+
+ return search_ctx;
+
+error_return:
+ /*
+ * We clear the search context now!
+ * Even when the caller gave us a (perhaps valid) context we free it here,
+ * as we might have already destroyed it.
+ */
+ vim_findfile_cleanup(search_ctx);
+ return NULL;
+}
+
+/*
+ * Get the stopdir string. Check that ';' is not escaped.
+ */
+char_u * vim_findfile_stopdir(buf)
+char_u *buf;
+{
+ char_u *r_ptr = buf;
+
+ while (*r_ptr != NUL && *r_ptr != ';') {
+ if (r_ptr[0] == '\\' && r_ptr[1] == ';') {
+ /* Overwrite the escape char,
+ * use STRLEN(r_ptr) to move the trailing '\0'. */
+ STRMOVE(r_ptr, r_ptr + 1);
+ r_ptr++;
+ }
+ r_ptr++;
+ }
+ if (*r_ptr == ';') {
+ *r_ptr = 0;
+ r_ptr++;
+ } else if (*r_ptr == NUL)
+ r_ptr = NULL;
+ return r_ptr;
+}
+
+/*
+ * Clean up the given search context. Can handle a NULL pointer.
+ */
+void vim_findfile_cleanup(ctx)
+void *ctx;
+{
+ if (ctx == NULL)
+ return;
+
+ vim_findfile_free_visited(ctx);
+ ff_clear(ctx);
+ vim_free(ctx);
+}
+
+/*
+ * Find a file in a search context.
+ * The search context was created with vim_findfile_init() above.
+ * Return a pointer to an allocated file name or NULL if nothing found.
+ * To get all matching files call this function until you get NULL.
+ *
+ * If the passed search_context is NULL, NULL is returned.
+ *
+ * The search algorithm is depth first. To change this replace the
+ * stack with a list (don't forget to leave partly searched directories on the
+ * top of the list).
+ */
+char_u * vim_findfile(search_ctx_arg)
+void *search_ctx_arg;
+{
+ char_u *file_path;
+ char_u *rest_of_wildcards;
+ char_u *path_end = NULL;
+ ff_stack_T *stackp;
+ int len;
+ int i;
+ char_u *p;
+ char_u *suf;
+ ff_search_ctx_T *search_ctx;
+
+ if (search_ctx_arg == NULL)
+ return NULL;
+
+ search_ctx = (ff_search_ctx_T *)search_ctx_arg;
+
+ /*
+ * filepath is used as buffer for various actions and as the storage to
+ * return a found filename.
+ */
+ if ((file_path = alloc((int)MAXPATHL)) == NULL)
+ return NULL;
+
+ /* store the end of the start dir -- needed for upward search */
+ if (search_ctx->ffsc_start_dir != NULL)
+ path_end = &search_ctx->ffsc_start_dir[
+ STRLEN(search_ctx->ffsc_start_dir)];
+
+ /* upward search loop */
+ for (;; ) {
+ /* downward search loop */
+ for (;; ) {
+ /* check if user user wants to stop the search*/
+ ui_breakcheck();
+ if (got_int)
+ break;
+
+ /* get directory to work on from stack */
+ stackp = ff_pop(search_ctx);
+ if (stackp == NULL)
+ break;
+
+ /*
+ * TODO: decide if we leave this test in
+ *
+ * GOOD: don't search a directory(-tree) twice.
+ * BAD: - check linked list for every new directory entered.
+ * - check for double files also done below
+ *
+ * Here we check if we already searched this directory.
+ * We already searched a directory if:
+ * 1) The directory is the same.
+ * 2) We would use the same wildcard string.
+ *
+ * Good if you have links on same directory via several ways
+ * or you have selfreferences in directories (e.g. SuSE Linux 6.3:
+ * /etc/rc.d/init.d is linked to /etc/rc.d -> endless loop)
+ *
+ * This check is only needed for directories we work on for the
+ * first time (hence stackp->ff_filearray == NULL)
+ */
+ if (stackp->ffs_filearray == NULL
+ && ff_check_visited(&search_ctx->ffsc_dir_visited_list
+ ->ffvl_visited_list,
+ stackp->ffs_fix_path
+ , stackp->ffs_wc_path
+ ) == FAIL) {
+#ifdef FF_VERBOSE
+ if (p_verbose >= 5) {
+ verbose_enter_scroll();
+ smsg((char_u *)"Already Searched: %s (%s)",
+ stackp->ffs_fix_path, stackp->ffs_wc_path);
+ /* don't overwrite this either */
+ msg_puts((char_u *)"\n");
+ verbose_leave_scroll();
+ }
+#endif
+ ff_free_stack_element(stackp);
+ continue;
+ }
+#ifdef FF_VERBOSE
+ else if (p_verbose >= 5) {
+ verbose_enter_scroll();
+ smsg((char_u *)"Searching: %s (%s)",
+ stackp->ffs_fix_path, stackp->ffs_wc_path);
+ /* don't overwrite this either */
+ msg_puts((char_u *)"\n");
+ verbose_leave_scroll();
+ }
+#endif
+
+ /* check depth */
+ if (stackp->ffs_level <= 0) {
+ ff_free_stack_element(stackp);
+ continue;
+ }
+
+ file_path[0] = NUL;
+
+ /*
+ * If no filearray till now expand wildcards
+ * The function expand_wildcards() can handle an array of paths
+ * and all possible expands are returned in one array. We use this
+ * to handle the expansion of '**' into an empty string.
+ */
+ if (stackp->ffs_filearray == NULL) {
+ char_u *dirptrs[2];
+
+ /* we use filepath to build the path expand_wildcards() should
+ * expand.
+ */
+ dirptrs[0] = file_path;
+ dirptrs[1] = NULL;
+
+ /* if we have a start dir copy it in */
+ if (!vim_isAbsName(stackp->ffs_fix_path)
+ && search_ctx->ffsc_start_dir) {
+ STRCPY(file_path, search_ctx->ffsc_start_dir);
+ add_pathsep(file_path);
+ }
+
+ /* append the fix part of the search path */
+ STRCAT(file_path, stackp->ffs_fix_path);
+ add_pathsep(file_path);
+
+ rest_of_wildcards = stackp->ffs_wc_path;
+ if (*rest_of_wildcards != NUL) {
+ len = (int)STRLEN(file_path);
+ if (STRNCMP(rest_of_wildcards, "**", 2) == 0) {
+ /* pointer to the restrict byte
+ * The restrict byte is not a character!
+ */
+ p = rest_of_wildcards + 2;
+
+ if (*p > 0) {
+ (*p)--;
+ file_path[len++] = '*';
+ }
+
+ if (*p == 0) {
+ /* remove '**<numb> from wildcards */
+ STRMOVE(rest_of_wildcards, rest_of_wildcards + 3);
+ } else
+ rest_of_wildcards += 3;
+
+ if (stackp->ffs_star_star_empty == 0) {
+ /* if not done before, expand '**' to empty */
+ stackp->ffs_star_star_empty = 1;
+ dirptrs[1] = stackp->ffs_fix_path;
+ }
+ }
+
+ /*
+ * Here we copy until the next path separator or the end of
+ * the path. If we stop at a path separator, there is
+ * still something else left. This is handled below by
+ * pushing every directory returned from expand_wildcards()
+ * on the stack again for further search.
+ */
+ while (*rest_of_wildcards
+ && !vim_ispathsep(*rest_of_wildcards))
+ file_path[len++] = *rest_of_wildcards++;
+
+ file_path[len] = NUL;
+ if (vim_ispathsep(*rest_of_wildcards))
+ rest_of_wildcards++;
+ }
+
+ /*
+ * Expand wildcards like "*" and "$VAR".
+ * If the path is a URL don't try this.
+ */
+ if (path_with_url(dirptrs[0])) {
+ stackp->ffs_filearray = (char_u **)
+ alloc((unsigned)sizeof(char *));
+ if (stackp->ffs_filearray != NULL
+ && (stackp->ffs_filearray[0]
+ = vim_strsave(dirptrs[0])) != NULL)
+ stackp->ffs_filearray_size = 1;
+ else
+ stackp->ffs_filearray_size = 0;
+ } else
+ /* Add EW_NOTWILD because the expanded path may contain
+ * wildcard characters that are to be taken literally.
+ * This is a bit of a hack. */
+ expand_wildcards((dirptrs[1] == NULL) ? 1 : 2, dirptrs,
+ &stackp->ffs_filearray_size,
+ &stackp->ffs_filearray,
+ EW_DIR|EW_ADDSLASH|EW_SILENT|EW_NOTWILD);
+
+ stackp->ffs_filearray_cur = 0;
+ stackp->ffs_stage = 0;
+ } else
+ rest_of_wildcards = &stackp->ffs_wc_path[
+ STRLEN(stackp->ffs_wc_path)];
+
+ if (stackp->ffs_stage == 0) {
+ /* this is the first time we work on this directory */
+ if (*rest_of_wildcards == NUL) {
+ /*
+ * We don't have further wildcards to expand, so we have to
+ * check for the final file now.
+ */
+ for (i = stackp->ffs_filearray_cur;
+ i < stackp->ffs_filearray_size; ++i) {
+ if (!path_with_url(stackp->ffs_filearray[i])
+ && !mch_isdir(stackp->ffs_filearray[i]))
+ continue; /* not a directory */
+
+ /* prepare the filename to be checked for existence
+ * below */
+ STRCPY(file_path, stackp->ffs_filearray[i]);
+ add_pathsep(file_path);
+ STRCAT(file_path, search_ctx->ffsc_file_to_search);
+
+ /*
+ * Try without extra suffix and then with suffixes
+ * from 'suffixesadd'.
+ */
+ len = (int)STRLEN(file_path);
+ if (search_ctx->ffsc_tagfile)
+ suf = (char_u *)"";
+ else
+ suf = curbuf->b_p_sua;
+ for (;; ) {
+ /* if file exists and we didn't already find it */
+ if ((path_with_url(file_path)
+ || (mch_getperm(file_path) >= 0
+ && (search_ctx->ffsc_find_what
+ == FINDFILE_BOTH
+ || ((search_ctx->ffsc_find_what
+ == FINDFILE_DIR)
+ == mch_isdir(file_path)))))
+#ifndef FF_VERBOSE
+ && (ff_check_visited(
+ &search_ctx->ffsc_visited_list->ffvl_visited_list,
+ file_path
+ , (char_u *)""
+ ) == OK)
+#endif
+ ) {
+#ifdef FF_VERBOSE
+ if (ff_check_visited(
+ &search_ctx->ffsc_visited_list->ffvl_visited_list,
+ file_path
+ , (char_u *)""
+ ) == FAIL) {
+ if (p_verbose >= 5) {
+ verbose_enter_scroll();
+ smsg((char_u *)"Already: %s",
+ file_path);
+ /* don't overwrite this either */
+ msg_puts((char_u *)"\n");
+ verbose_leave_scroll();
+ }
+ continue;
+ }
+#endif
+
+ /* push dir to examine rest of subdirs later */
+ stackp->ffs_filearray_cur = i + 1;
+ ff_push(search_ctx, stackp);
+
+ if (!path_with_url(file_path))
+ simplify_filename(file_path);
+ if (mch_dirname(ff_expand_buffer, MAXPATHL)
+ == OK) {
+ p = shorten_fname(file_path,
+ ff_expand_buffer);
+ if (p != NULL)
+ STRMOVE(file_path, p);
+ }
+#ifdef FF_VERBOSE
+ if (p_verbose >= 5) {
+ verbose_enter_scroll();
+ smsg((char_u *)"HIT: %s", file_path);
+ /* don't overwrite this either */
+ msg_puts((char_u *)"\n");
+ verbose_leave_scroll();
+ }
+#endif
+ return file_path;
+ }
+
+ /* Not found or found already, try next suffix. */
+ if (*suf == NUL)
+ break;
+ copy_option_part(&suf, file_path + len,
+ MAXPATHL - len, ",");
+ }
+ }
+ } else {
+ /*
+ * still wildcards left, push the directories for further
+ * search
+ */
+ for (i = stackp->ffs_filearray_cur;
+ i < stackp->ffs_filearray_size; ++i) {
+ if (!mch_isdir(stackp->ffs_filearray[i]))
+ continue; /* not a directory */
+
+ ff_push(search_ctx,
+ ff_create_stack_element(
+ stackp->ffs_filearray[i],
+ rest_of_wildcards,
+ stackp->ffs_level - 1, 0));
+ }
+ }
+ stackp->ffs_filearray_cur = 0;
+ stackp->ffs_stage = 1;
+ }
+
+ /*
+ * if wildcards contains '**' we have to descent till we reach the
+ * leaves of the directory tree.
+ */
+ if (STRNCMP(stackp->ffs_wc_path, "**", 2) == 0) {
+ for (i = stackp->ffs_filearray_cur;
+ i < stackp->ffs_filearray_size; ++i) {
+ if (fnamecmp(stackp->ffs_filearray[i],
+ stackp->ffs_fix_path) == 0)
+ continue; /* don't repush same directory */
+ if (!mch_isdir(stackp->ffs_filearray[i]))
+ continue; /* not a directory */
+ ff_push(search_ctx,
+ ff_create_stack_element(stackp->ffs_filearray[i],
+ stackp->ffs_wc_path, stackp->ffs_level - 1, 1));
+ }
+ }
+
+ /* we are done with the current directory */
+ ff_free_stack_element(stackp);
+
+ }
+
+ /* If we reached this, we didn't find anything downwards.
+ * Let's check if we should do an upward search.
+ */
+ if (search_ctx->ffsc_start_dir
+ && search_ctx->ffsc_stopdirs_v != NULL && !got_int) {
+ ff_stack_T *sptr;
+
+ /* is the last starting directory in the stop list? */
+ if (ff_path_in_stoplist(search_ctx->ffsc_start_dir,
+ (int)(path_end - search_ctx->ffsc_start_dir),
+ search_ctx->ffsc_stopdirs_v) == TRUE)
+ break;
+
+ /* cut of last dir */
+ while (path_end > search_ctx->ffsc_start_dir
+ && vim_ispathsep(*path_end))
+ path_end--;
+ while (path_end > search_ctx->ffsc_start_dir
+ && !vim_ispathsep(path_end[-1]))
+ path_end--;
+ *path_end = 0;
+ path_end--;
+
+ if (*search_ctx->ffsc_start_dir == 0)
+ break;
+
+ STRCPY(file_path, search_ctx->ffsc_start_dir);
+ add_pathsep(file_path);
+ STRCAT(file_path, search_ctx->ffsc_fix_path);
+
+ /* create a new stack entry */
+ sptr = ff_create_stack_element(file_path,
+ search_ctx->ffsc_wc_path, search_ctx->ffsc_level, 0);
+ if (sptr == NULL)
+ break;
+ ff_push(search_ctx, sptr);
+ } else
+ break;
+ }
+
+ vim_free(file_path);
+ return NULL;
+}
+
+/*
+ * Free the list of lists of visited files and directories
+ * Can handle it if the passed search_context is NULL;
+ */
+void vim_findfile_free_visited(search_ctx_arg)
+void *search_ctx_arg;
+{
+ ff_search_ctx_T *search_ctx;
+
+ if (search_ctx_arg == NULL)
+ return;
+
+ search_ctx = (ff_search_ctx_T *)search_ctx_arg;
+ vim_findfile_free_visited_list(&search_ctx->ffsc_visited_lists_list);
+ vim_findfile_free_visited_list(&search_ctx->ffsc_dir_visited_lists_list);
+}
+
+static void vim_findfile_free_visited_list(list_headp)
+ff_visited_list_hdr_T **list_headp;
+{
+ ff_visited_list_hdr_T *vp;
+
+ while (*list_headp != NULL) {
+ vp = (*list_headp)->ffvl_next;
+ ff_free_visited_list((*list_headp)->ffvl_visited_list);
+
+ vim_free((*list_headp)->ffvl_filename);
+ vim_free(*list_headp);
+ *list_headp = vp;
+ }
+ *list_headp = NULL;
+}
+
+static void ff_free_visited_list(vl)
+ff_visited_T *vl;
+{
+ ff_visited_T *vp;
+
+ while (vl != NULL) {
+ vp = vl->ffv_next;
+ vim_free(vl->ffv_wc_path);
+ vim_free(vl);
+ vl = vp;
+ }
+ vl = NULL;
+}
+
+/*
+ * Returns the already visited list for the given filename. If none is found it
+ * allocates a new one.
+ */
+static ff_visited_list_hdr_T* ff_get_visited_list(filename, list_headp)
+char_u *filename;
+ff_visited_list_hdr_T **list_headp;
+{
+ ff_visited_list_hdr_T *retptr = NULL;
+
+ /* check if a visited list for the given filename exists */
+ if (*list_headp != NULL) {
+ retptr = *list_headp;
+ while (retptr != NULL) {
+ if (fnamecmp(filename, retptr->ffvl_filename) == 0) {
+#ifdef FF_VERBOSE
+ if (p_verbose >= 5) {
+ verbose_enter_scroll();
+ smsg((char_u *)"ff_get_visited_list: FOUND list for %s",
+ filename);
+ /* don't overwrite this either */
+ msg_puts((char_u *)"\n");
+ verbose_leave_scroll();
+ }
+#endif
+ return retptr;
+ }
+ retptr = retptr->ffvl_next;
+ }
+ }
+
+#ifdef FF_VERBOSE
+ if (p_verbose >= 5) {
+ verbose_enter_scroll();
+ smsg((char_u *)"ff_get_visited_list: new list for %s", filename);
+ /* don't overwrite this either */
+ msg_puts((char_u *)"\n");
+ verbose_leave_scroll();
+ }
+#endif
+
+ /*
+ * if we reach this we didn't find a list and we have to allocate new list
+ */
+ retptr = (ff_visited_list_hdr_T*)alloc((unsigned)sizeof(*retptr));
+ if (retptr == NULL)
+ return NULL;
+
+ retptr->ffvl_visited_list = NULL;
+ retptr->ffvl_filename = vim_strsave(filename);
+ if (retptr->ffvl_filename == NULL) {
+ vim_free(retptr);
+ return NULL;
+ }
+ retptr->ffvl_next = *list_headp;
+ *list_headp = retptr;
+
+ return retptr;
+}
+
+/*
+ * check if two wildcard paths are equal. Returns TRUE or FALSE.
+ * They are equal if:
+ * - both paths are NULL
+ * - they have the same length
+ * - char by char comparison is OK
+ * - the only differences are in the counters behind a '**', so
+ * '**\20' is equal to '**\24'
+ */
+static int ff_wc_equal(s1, s2)
+char_u *s1;
+char_u *s2;
+{
+ int i;
+ int prev1 = NUL;
+ int prev2 = NUL;
+
+ if (s1 == s2)
+ return TRUE;
+
+ if (s1 == NULL || s2 == NULL)
+ return FALSE;
+
+ if (STRLEN(s1) != STRLEN(s2))
+ return FAIL;
+
+ for (i = 0; s1[i] != NUL && s2[i] != NUL; i += MB_PTR2LEN(s1 + i)) {
+ int c1 = PTR2CHAR(s1 + i);
+ int c2 = PTR2CHAR(s2 + i);
+
+ if ((p_fic ? MB_TOLOWER(c1) != MB_TOLOWER(c2) : c1 != c2)
+ && (prev1 != '*' || prev2 != '*'))
+ return FAIL;
+ prev2 = prev1;
+ prev1 = c1;
+ }
+ return TRUE;
+}
+
+/*
+ * maintains the list of already visited files and dirs
+ * returns FAIL if the given file/dir is already in the list
+ * returns OK if it is newly added
+ *
+ * TODO: What to do on memory allocation problems?
+ * -> return TRUE - Better the file is found several times instead of
+ * never.
+ */
+static int ff_check_visited(visited_list, fname
+ , wc_path)
+ff_visited_T **visited_list;
+char_u *fname;
+char_u *wc_path;
+{
+ ff_visited_T *vp;
+#ifdef UNIX
+ struct stat st;
+ int url = FALSE;
+#endif
+
+ /* For an URL we only compare the name, otherwise we compare the
+ * device/inode (unix) or the full path name (not Unix). */
+ if (path_with_url(fname)) {
+ vim_strncpy(ff_expand_buffer, fname, MAXPATHL - 1);
+#ifdef UNIX
+ url = TRUE;
+#endif
+ } else {
+ ff_expand_buffer[0] = NUL;
+#ifdef UNIX
+ if (mch_stat((char *)fname, &st) < 0)
+#else
+ if (vim_FullName(fname, ff_expand_buffer, MAXPATHL, TRUE) == FAIL)
+#endif
+ return FAIL;
+ }
+
+ /* check against list of already visited files */
+ for (vp = *visited_list; vp != NULL; vp = vp->ffv_next) {
+ if (
+#ifdef UNIX
+ !url ? (vp->ffv_dev_valid && vp->ffv_dev == st.st_dev
+ && vp->ffv_ino == st.st_ino)
+ :
+#endif
+ fnamecmp(vp->ffv_fname, ff_expand_buffer) == 0
+ ) {
+ /* are the wildcard parts equal */
+ if (ff_wc_equal(vp->ffv_wc_path, wc_path) == TRUE)
+ /* already visited */
+ return FAIL;
+ }
+ }
+
+ /*
+ * New file/dir. Add it to the list of visited files/dirs.
+ */
+ vp = (ff_visited_T *)alloc((unsigned)(sizeof(ff_visited_T)
+ + STRLEN(ff_expand_buffer)));
+
+ if (vp != NULL) {
+#ifdef UNIX
+ if (!url) {
+ vp->ffv_dev_valid = TRUE;
+ vp->ffv_ino = st.st_ino;
+ vp->ffv_dev = st.st_dev;
+ vp->ffv_fname[0] = NUL;
+ } else {
+ vp->ffv_dev_valid = FALSE;
+#endif
+ STRCPY(vp->ffv_fname, ff_expand_buffer);
+#ifdef UNIX
+ }
+#endif
+ if (wc_path != NULL)
+ vp->ffv_wc_path = vim_strsave(wc_path);
+ else
+ vp->ffv_wc_path = NULL;
+
+ vp->ffv_next = *visited_list;
+ *visited_list = vp;
+ }
+
+ return OK;
+}
+
+/*
+ * create stack element from given path pieces
+ */
+static ff_stack_T * ff_create_stack_element(fix_part,
+ wc_part,
+ level, star_star_empty)
+char_u *fix_part;
+char_u *wc_part;
+int level;
+int star_star_empty;
+{
+ ff_stack_T *new;
+
+ new = (ff_stack_T *)alloc((unsigned)sizeof(ff_stack_T));
+ if (new == NULL)
+ return NULL;
+
+ new->ffs_prev = NULL;
+ new->ffs_filearray = NULL;
+ new->ffs_filearray_size = 0;
+ new->ffs_filearray_cur = 0;
+ new->ffs_stage = 0;
+ new->ffs_level = level;
+ new->ffs_star_star_empty = star_star_empty;;
+
+ /* the following saves NULL pointer checks in vim_findfile */
+ if (fix_part == NULL)
+ fix_part = (char_u *)"";
+ new->ffs_fix_path = vim_strsave(fix_part);
+
+ if (wc_part == NULL)
+ wc_part = (char_u *)"";
+ new->ffs_wc_path = vim_strsave(wc_part);
+
+ if (new->ffs_fix_path == NULL
+ || new->ffs_wc_path == NULL
+ ) {
+ ff_free_stack_element(new);
+ new = NULL;
+ }
+
+ return new;
+}
+
+/*
+ * Push a dir on the directory stack.
+ */
+static void ff_push(search_ctx, stack_ptr)
+ff_search_ctx_T *search_ctx;
+ff_stack_T *stack_ptr;
+{
+ /* check for NULL pointer, not to return an error to the user, but
+ * to prevent a crash */
+ if (stack_ptr != NULL) {
+ stack_ptr->ffs_prev = search_ctx->ffsc_stack_ptr;
+ search_ctx->ffsc_stack_ptr = stack_ptr;
+ }
+}
+
+/*
+ * Pop a dir from the directory stack.
+ * Returns NULL if stack is empty.
+ */
+static ff_stack_T * ff_pop(search_ctx)
+ff_search_ctx_T *search_ctx;
+{
+ ff_stack_T *sptr;
+
+ sptr = search_ctx->ffsc_stack_ptr;
+ if (search_ctx->ffsc_stack_ptr != NULL)
+ search_ctx->ffsc_stack_ptr = search_ctx->ffsc_stack_ptr->ffs_prev;
+
+ return sptr;
+}
+
+/*
+ * free the given stack element
+ */
+static void ff_free_stack_element(stack_ptr)
+ff_stack_T *stack_ptr;
+{
+ /* vim_free handles possible NULL pointers */
+ vim_free(stack_ptr->ffs_fix_path);
+ vim_free(stack_ptr->ffs_wc_path);
+
+ if (stack_ptr->ffs_filearray != NULL)
+ FreeWild(stack_ptr->ffs_filearray_size, stack_ptr->ffs_filearray);
+
+ vim_free(stack_ptr);
+}
+
+/*
+ * Clear the search context, but NOT the visited list.
+ */
+static void ff_clear(search_ctx)
+ff_search_ctx_T *search_ctx;
+{
+ ff_stack_T *sptr;
+
+ /* clear up stack */
+ while ((sptr = ff_pop(search_ctx)) != NULL)
+ ff_free_stack_element(sptr);
+
+ vim_free(search_ctx->ffsc_file_to_search);
+ vim_free(search_ctx->ffsc_start_dir);
+ vim_free(search_ctx->ffsc_fix_path);
+ vim_free(search_ctx->ffsc_wc_path);
+
+ if (search_ctx->ffsc_stopdirs_v != NULL) {
+ int i = 0;
+
+ while (search_ctx->ffsc_stopdirs_v[i] != NULL) {
+ vim_free(search_ctx->ffsc_stopdirs_v[i]);
+ i++;
+ }
+ vim_free(search_ctx->ffsc_stopdirs_v);
+ }
+ search_ctx->ffsc_stopdirs_v = NULL;
+
+ /* reset everything */
+ search_ctx->ffsc_file_to_search = NULL;
+ search_ctx->ffsc_start_dir = NULL;
+ search_ctx->ffsc_fix_path = NULL;
+ search_ctx->ffsc_wc_path = NULL;
+ search_ctx->ffsc_level = 0;
+}
+
+/*
+ * check if the given path is in the stopdirs
+ * returns TRUE if yes else FALSE
+ */
+static int ff_path_in_stoplist(path, path_len, stopdirs_v)
+char_u *path;
+int path_len;
+char_u **stopdirs_v;
+{
+ int i = 0;
+
+ /* eat up trailing path separators, except the first */
+ while (path_len > 1 && vim_ispathsep(path[path_len - 1]))
+ path_len--;
+
+ /* if no path consider it as match */
+ if (path_len == 0)
+ return TRUE;
+
+ for (i = 0; stopdirs_v[i] != NULL; i++) {
+ if ((int)STRLEN(stopdirs_v[i]) > path_len) {
+ /* match for parent directory. So '/home' also matches
+ * '/home/rks'. Check for PATHSEP in stopdirs_v[i], else
+ * '/home/r' would also match '/home/rks'
+ */
+ if (fnamencmp(stopdirs_v[i], path, path_len) == 0
+ && vim_ispathsep(stopdirs_v[i][path_len]))
+ return TRUE;
+ } else {
+ if (fnamecmp(stopdirs_v[i], path) == 0)
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/*
+ * Find the file name "ptr[len]" in the path. Also finds directory names.
+ *
+ * On the first call set the parameter 'first' to TRUE to initialize
+ * the search. For repeating calls to FALSE.
+ *
+ * Repeating calls will return other files called 'ptr[len]' from the path.
+ *
+ * Only on the first call 'ptr' and 'len' are used. For repeating calls they
+ * don't need valid values.
+ *
+ * If nothing found on the first call the option FNAME_MESS will issue the
+ * message:
+ * 'Can't find file "<file>" in path'
+ * On repeating calls:
+ * 'No more file "<file>" found in path'
+ *
+ * options:
+ * FNAME_MESS give error message when not found
+ *
+ * Uses NameBuff[]!
+ *
+ * Returns an allocated string for the file name. NULL for error.
+ *
+ */
+char_u * find_file_in_path(ptr, len, options, first, rel_fname)
+char_u *ptr; /* file name */
+int len; /* length of file name */
+int options;
+int first; /* use count'th matching file name */
+char_u *rel_fname; /* file name searching relative to */
+{
+ return find_file_in_path_option(ptr, len, options, first,
+ *curbuf->b_p_path == NUL ? p_path : curbuf->b_p_path,
+ FINDFILE_BOTH, rel_fname, curbuf->b_p_sua);
+}
+
+static char_u *ff_file_to_find = NULL;
+static void *fdip_search_ctx = NULL;
+
+#if defined(EXITFREE)
+static void free_findfile() {
+ vim_free(ff_file_to_find);
+ vim_findfile_cleanup(fdip_search_ctx);
+}
+
+#endif
+
+/*
+ * Find the directory name "ptr[len]" in the path.
+ *
+ * options:
+ * FNAME_MESS give error message when not found
+ *
+ * Uses NameBuff[]!
+ *
+ * Returns an allocated string for the file name. NULL for error.
+ */
+char_u * find_directory_in_path(ptr, len, options, rel_fname)
+char_u *ptr; /* file name */
+int len; /* length of file name */
+int options;
+char_u *rel_fname; /* file name searching relative to */
+{
+ return find_file_in_path_option(ptr, len, options, TRUE, p_cdpath,
+ FINDFILE_DIR, rel_fname, (char_u *)"");
+}
+
+char_u * find_file_in_path_option(ptr, len, options, first, path_option,
+ find_what, rel_fname,
+ suffixes)
+char_u *ptr; /* file name */
+int len; /* length of file name */
+int options;
+int first; /* use count'th matching file name */
+char_u *path_option; /* p_path or p_cdpath */
+int find_what; /* FINDFILE_FILE, _DIR or _BOTH */
+char_u *rel_fname; /* file name we are looking relative to. */
+char_u *suffixes; /* list of suffixes, 'suffixesadd' option */
+{
+ static char_u *dir;
+ static int did_findfile_init = FALSE;
+ char_u save_char;
+ char_u *file_name = NULL;
+ char_u *buf = NULL;
+ int rel_to_curdir;
+
+ if (first == TRUE) {
+ /* copy file name into NameBuff, expanding environment variables */
+ save_char = ptr[len];
+ ptr[len] = NUL;
+ expand_env(ptr, NameBuff, MAXPATHL);
+ ptr[len] = save_char;
+
+ vim_free(ff_file_to_find);
+ ff_file_to_find = vim_strsave(NameBuff);
+ if (ff_file_to_find == NULL) { /* out of memory */
+ file_name = NULL;
+ goto theend;
+ }
+ }
+
+ rel_to_curdir = (ff_file_to_find[0] == '.'
+ && (ff_file_to_find[1] == NUL
+ || vim_ispathsep(ff_file_to_find[1])
+ || (ff_file_to_find[1] == '.'
+ && (ff_file_to_find[2] == NUL
+ || vim_ispathsep(ff_file_to_find[2])))));
+ if (vim_isAbsName(ff_file_to_find)
+ /* "..", "../path", "." and "./path": don't use the path_option */
+ || rel_to_curdir
+ ) {
+ /*
+ * Absolute path, no need to use "path_option".
+ * If this is not a first call, return NULL. We already returned a
+ * filename on the first call.
+ */
+ if (first == TRUE) {
+ int l;
+ int run;
+
+ if (path_with_url(ff_file_to_find)) {
+ file_name = vim_strsave(ff_file_to_find);
+ goto theend;
+ }
+
+ /* When FNAME_REL flag given first use the directory of the file.
+ * Otherwise or when this fails use the current directory. */
+ for (run = 1; run <= 2; ++run) {
+ l = (int)STRLEN(ff_file_to_find);
+ if (run == 1
+ && rel_to_curdir
+ && (options & FNAME_REL)
+ && rel_fname != NULL
+ && STRLEN(rel_fname) + l < MAXPATHL) {
+ STRCPY(NameBuff, rel_fname);
+ STRCPY(gettail(NameBuff), ff_file_to_find);
+ l = (int)STRLEN(NameBuff);
+ } else {
+ STRCPY(NameBuff, ff_file_to_find);
+ run = 2;
+ }
+
+ /* When the file doesn't exist, try adding parts of
+ * 'suffixesadd'. */
+ buf = suffixes;
+ for (;; ) {
+ if (
+ (mch_getperm(NameBuff) >= 0
+ && (find_what == FINDFILE_BOTH
+ || ((find_what == FINDFILE_DIR)
+ == mch_isdir(NameBuff))))) {
+ file_name = vim_strsave(NameBuff);
+ goto theend;
+ }
+ if (*buf == NUL)
+ break;
+ copy_option_part(&buf, NameBuff + l, MAXPATHL - l, ",");
+ }
+ }
+ }
+ } else {
+ /*
+ * Loop over all paths in the 'path' or 'cdpath' option.
+ * When "first" is set, first setup to the start of the option.
+ * Otherwise continue to find the next match.
+ */
+ if (first == TRUE) {
+ /* vim_findfile_free_visited can handle a possible NULL pointer */
+ vim_findfile_free_visited(fdip_search_ctx);
+ dir = path_option;
+ did_findfile_init = FALSE;
+ }
+
+ for (;; ) {
+ if (did_findfile_init) {
+ file_name = vim_findfile(fdip_search_ctx);
+ if (file_name != NULL)
+ break;
+
+ did_findfile_init = FALSE;
+ } else {
+ char_u *r_ptr;
+
+ if (dir == NULL || *dir == NUL) {
+ /* We searched all paths of the option, now we can
+ * free the search context. */
+ vim_findfile_cleanup(fdip_search_ctx);
+ fdip_search_ctx = NULL;
+ break;
+ }
+
+ if ((buf = alloc((int)(MAXPATHL))) == NULL)
+ break;
+
+ /* copy next path */
+ buf[0] = 0;
+ copy_option_part(&dir, buf, MAXPATHL, " ,");
+
+ /* get the stopdir string */
+ r_ptr = vim_findfile_stopdir(buf);
+ fdip_search_ctx = vim_findfile_init(buf, ff_file_to_find,
+ r_ptr, 100, FALSE, find_what,
+ fdip_search_ctx, FALSE, rel_fname);
+ if (fdip_search_ctx != NULL)
+ did_findfile_init = TRUE;
+ vim_free(buf);
+ }
+ }
+ }
+ if (file_name == NULL && (options & FNAME_MESS)) {
+ if (first == TRUE) {
+ if (find_what == FINDFILE_DIR)
+ EMSG2(_("E344: Can't find directory \"%s\" in cdpath"),
+ ff_file_to_find);
+ else
+ EMSG2(_("E345: Can't find file \"%s\" in path"),
+ ff_file_to_find);
+ } else {
+ if (find_what == FINDFILE_DIR)
+ EMSG2(_("E346: No more directory \"%s\" found in cdpath"),
+ ff_file_to_find);
+ else
+ EMSG2(_("E347: No more file \"%s\" found in path"),
+ ff_file_to_find);
+ }
+ }
+
+theend:
+ return file_name;
+}
+
+
+/*
+ * Change directory to "new_dir". If FEAT_SEARCHPATH is defined, search
+ * 'cdpath' for relative directory names, otherwise just mch_chdir().
+ */
+int vim_chdir(new_dir)
+char_u *new_dir;
+{
+ char_u *dir_name;
+ int r;
+
+ dir_name = find_directory_in_path(new_dir, (int)STRLEN(new_dir),
+ FNAME_MESS, curbuf->b_ffname);
+ if (dir_name == NULL)
+ return -1;
+ r = mch_chdir((char *)dir_name);
+ vim_free(dir_name);
+ return r;
+}
+
+/*
+ * Get user name from machine-specific function.
+ * Returns the user name in "buf[len]".
+ * Some systems are quite slow in obtaining the user name (Windows NT), thus
+ * cache the result.
+ * Returns OK or FAIL.
+ */
+int get_user_name(buf, len)
+char_u *buf;
+int len;
+{
+ if (username == NULL) {
+ if (mch_get_user_name(buf, len) == FAIL)
+ return FAIL;
+ username = vim_strsave(buf);
+ } else
+ vim_strncpy(buf, username, len - 1);
+ return OK;
+}
+
+#ifndef HAVE_QSORT
+/*
+ * Our own qsort(), for systems that don't have it.
+ * It's simple and slow. From the K&R C book.
+ */
+void qsort(base, elm_count, elm_size, cmp)
+void *base;
+size_t elm_count;
+size_t elm_size;
+int (*cmp)__ARGS((const void *, const void *));
+{
+ char_u *buf;
+ char_u *p1;
+ char_u *p2;
+ int i, j;
+ int gap;
+
+ buf = alloc((unsigned)elm_size);
+ if (buf == NULL)
+ return;
+
+ for (gap = elm_count / 2; gap > 0; gap /= 2)
+ for (i = gap; i < elm_count; ++i)
+ for (j = i - gap; j >= 0; j -= gap) {
+ /* Compare the elements. */
+ p1 = (char_u *)base + j * elm_size;
+ p2 = (char_u *)base + (j + gap) * elm_size;
+ if ((*cmp)((void *)p1, (void *)p2) <= 0)
+ break;
+ /* Exchange the elements. */
+ mch_memmove(buf, p1, elm_size);
+ mch_memmove(p1, p2, elm_size);
+ mch_memmove(p2, buf, elm_size);
+ }
+
+ vim_free(buf);
+}
+#endif
+
+/*
+ * Sort an array of strings.
+ */
+static int
+sort_compare __ARGS((const void *s1, const void *s2));
+
+static int sort_compare(s1, s2)
+const void *s1;
+const void *s2;
+{
+ return STRCMP(*(char **)s1, *(char **)s2);
+}
+
+void sort_strings(files, count)
+char_u **files;
+int count;
+{
+ qsort((void *)files, (size_t)count, sizeof(char_u *), sort_compare);
+}
+
+#if !defined(NO_EXPANDPATH) || defined(PROTO)
+/*
+ * Compare path "p[]" to "q[]".
+ * If "maxlen" >= 0 compare "p[maxlen]" to "q[maxlen]"
+ * Return value like strcmp(p, q), but consider path separators.
+ */
+int pathcmp(p, q, maxlen)
+const char *p, *q;
+int maxlen;
+{
+ int i;
+ int c1, c2;
+ const char *s = NULL;
+
+ for (i = 0; maxlen < 0 || i < maxlen; i += MB_PTR2LEN((char_u *)p + i)) {
+ c1 = PTR2CHAR((char_u *)p + i);
+ c2 = PTR2CHAR((char_u *)q + i);
+
+ /* End of "p": check if "q" also ends or just has a slash. */
+ if (c1 == NUL) {
+ if (c2 == NUL) /* full match */
+ return 0;
+ s = q;
+ break;
+ }
+
+ /* End of "q": check if "p" just has a slash. */
+ if (c2 == NUL) {
+ s = p;
+ break;
+ }
+
+ if ((p_fic ? MB_TOUPPER(c1) != MB_TOUPPER(c2) : c1 != c2)
+#ifdef BACKSLASH_IN_FILENAME
+ /* consider '/' and '\\' to be equal */
+ && !((c1 == '/' && c2 == '\\')
+ || (c1 == '\\' && c2 == '/'))
+#endif
+ ) {
+ if (vim_ispathsep(c1))
+ return -1;
+ if (vim_ispathsep(c2))
+ return 1;
+ return p_fic ? MB_TOUPPER(c1) - MB_TOUPPER(c2)
+ : c1 - c2; /* no match */
+ }
+ }
+ if (s == NULL) /* "i" ran into "maxlen" */
+ return 0;
+
+ c1 = PTR2CHAR((char_u *)s + i);
+ c2 = PTR2CHAR((char_u *)s + i + MB_PTR2LEN((char_u *)s + i));
+ /* ignore a trailing slash, but not "//" or ":/" */
+ if (c2 == NUL
+ && i > 0
+ && !after_pathsep((char_u *)s, (char_u *)s + i)
+#ifdef BACKSLASH_IN_FILENAME
+ && (c1 == '/' || c1 == '\\')
+#else
+ && c1 == '/'
+#endif
+ )
+ return 0; /* match with trailing slash */
+ if (s == q)
+ return -1; /* no match */
+ return 1;
+}
+#endif
+
+/*
+ * The putenv() implementation below comes from the "screen" program.
+ * Included with permission from Juergen Weigert.
+ * See pty.c for the copyright notice.
+ */
+
+/*
+ * putenv -- put value into environment
+ *
+ * Usage: i = putenv (string)
+ * int i;
+ * char *string;
+ *
+ * where string is of the form <name>=<value>.
+ * Putenv returns 0 normally, -1 on error (not enough core for malloc).
+ *
+ * Putenv may need to add a new name into the environment, or to
+ * associate a value longer than the current value with a particular
+ * name. So, to make life simpler, putenv() copies your entire
+ * environment into the heap (i.e. malloc()) from the stack
+ * (i.e. where it resides when your process is initiated) the first
+ * time you call it.
+ *
+ * (history removed, not very interesting. See the "screen" sources.)
+ */
+
+#if !defined(HAVE_SETENV) && !defined(HAVE_PUTENV)
+
+#define EXTRASIZE 5 /* increment to add to env. size */
+
+static int envsize = -1; /* current size of environment */
+extern
+char **environ; /* the global which is your env. */
+
+static int findenv __ARGS((char *name)); /* look for a name in the env. */
+static int newenv __ARGS((void)); /* copy env. from stack to heap */
+static int moreenv __ARGS((void)); /* incr. size of env. */
+
+int putenv(string)
+const char *string;
+{
+ int i;
+ char *p;
+
+ if (envsize < 0) { /* first time putenv called */
+ if (newenv() < 0) /* copy env. to heap */
+ return -1;
+ }
+
+ i = findenv((char *)string); /* look for name in environment */
+
+ if (i < 0) { /* name must be added */
+ for (i = 0; environ[i]; i++) ;
+ if (i >= (envsize - 1)) { /* need new slot */
+ if (moreenv() < 0)
+ return -1;
+ }
+ p = (char *)alloc((unsigned)(strlen(string) + 1));
+ if (p == NULL) /* not enough core */
+ return -1;
+ environ[i + 1] = 0; /* new end of env. */
+ } else { /* name already in env. */
+ p = vim_realloc(environ[i], strlen(string) + 1);
+ if (p == NULL)
+ return -1;
+ }
+ sprintf(p, "%s", string); /* copy into env. */
+ environ[i] = p;
+
+ return 0;
+}
+
+static int findenv(name)
+char *name;
+{
+ char *namechar, *envchar;
+ int i, found;
+
+ found = 0;
+ for (i = 0; environ[i] && !found; i++) {
+ envchar = environ[i];
+ namechar = name;
+ while (*namechar && *namechar != '=' && (*namechar == *envchar)) {
+ namechar++;
+ envchar++;
+ }
+ found = ((*namechar == '\0' || *namechar == '=') && *envchar == '=');
+ }
+ return found ? i - 1 : -1;
+}
+
+static int newenv() {
+ char **env, *elem;
+ int i, esize;
+
+ for (i = 0; environ[i]; i++)
+ ;
+ esize = i + EXTRASIZE + 1;
+ env = (char **)alloc((unsigned)(esize * sizeof (elem)));
+ if (env == NULL)
+ return -1;
+
+ for (i = 0; environ[i]; i++) {
+ elem = (char *)alloc((unsigned)(strlen(environ[i]) + 1));
+ if (elem == NULL)
+ return -1;
+ env[i] = elem;
+ strcpy(elem, environ[i]);
+ }
+
+ env[i] = 0;
+ environ = env;
+ envsize = esize;
+ return 0;
+}
+
+static int moreenv() {
+ int esize;
+ char **env;
+
+ esize = envsize + EXTRASIZE;
+ env = (char **)vim_realloc((char *)environ, esize * sizeof (*env));
+ if (env == 0)
+ return -1;
+ environ = env;
+ envsize = esize;
+ return 0;
+}
+
+# ifdef USE_VIMPTY_GETENV
+char_u * vimpty_getenv(string)
+const char_u *string;
+{
+ int i;
+ char_u *p;
+
+ if (envsize < 0)
+ return NULL;
+
+ i = findenv((char *)string);
+
+ if (i < 0)
+ return NULL;
+
+ p = vim_strchr((char_u *)environ[i], '=');
+ return p + 1;
+}
+# endif
+
+#endif /* !defined(HAVE_SETENV) && !defined(HAVE_PUTENV) */
+
+/*
+ * Return 0 for not writable, 1 for writable file, 2 for a dir which we have
+ * rights to write into.
+ */
+int filewritable(fname)
+char_u *fname;
+{
+ int retval = 0;
+#if defined(UNIX) || defined(VMS)
+ int perm = 0;
+#endif
+
+#if defined(UNIX) || defined(VMS)
+ perm = mch_getperm(fname);
+#endif
+ if (
+# if defined(UNIX) || defined(VMS)
+ (perm & 0222) &&
+# endif
+ mch_access((char *)fname, W_OK) == 0
+ ) {
+ ++retval;
+ if (mch_isdir(fname))
+ ++retval;
+ }
+ return retval;
+}
+
+/*
+ * Print an error message with one or two "%s" and one or two string arguments.
+ * This is not in message.c to avoid a warning for prototypes.
+ */
+int emsg3(s, a1, a2)
+char_u *s, *a1, *a2;
+{
+ if (emsg_not_now())
+ return TRUE; /* no error messages at the moment */
+#ifdef HAVE_STDARG_H
+ vim_snprintf((char *)IObuff, IOSIZE, (char *)s, a1, a2);
+#else
+ vim_snprintf((char *)IObuff, IOSIZE, (char *)s, (long_u)a1, (long_u)a2);
+#endif
+ return emsg(IObuff);
+}
+
+/*
+ * Print an error message with one "%ld" and one long int argument.
+ * This is not in message.c to avoid a warning for prototypes.
+ */
+int emsgn(s, n)
+char_u *s;
+long n;
+{
+ if (emsg_not_now())
+ return TRUE; /* no error messages at the moment */
+ vim_snprintf((char *)IObuff, IOSIZE, (char *)s, n);
+ return emsg(IObuff);
+}
+
+/*
+ * Read 2 bytes from "fd" and turn them into an int, MSB first.
+ */
+int get2c(fd)
+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(fd)
+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(fd)
+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(fd)
+FILE *fd;
+{
+ time_t n = 0;
+ int i;
+
+ for (i = 0; i < 8; ++i)
+ n = (n << 8) + getc(fd);
+ return n;
+}
+
+/*
+ * Read a string of length "cnt" from "fd" into allocated memory.
+ * Returns NULL when out of memory or unable to read that many bytes.
+ */
+char_u * read_string(fd, cnt)
+FILE *fd;
+int cnt;
+{
+ char_u *str;
+ int i;
+ int c;
+
+ /* allocate memory */
+ str = alloc((unsigned)cnt + 1);
+ if (str != NULL) {
+ /* Read the string. Quit when running into the EOF. */
+ for (i = 0; i < cnt; ++i) {
+ c = getc(fd);
+ if (c == EOF) {
+ vim_free(str);
+ return NULL;
+ }
+ str[i] = c;
+ }
+ str[i] = NUL;
+ }
+ return str;
+}
+
+/*
+ * Write a number to file "fd", MSB first, in "len" bytes.
+ */
+int put_bytes(fd, nr, len)
+FILE *fd;
+long_u nr;
+int len;
+{
+ int i;
+
+ for (i = len - 1; i >= 0; --i)
+ if (putc((int)(nr >> (i * 8)), fd) == EOF)
+ return FAIL;
+ return OK;
+}
+
+
+/*
+ * Write time_t to file "fd" in 8 bytes.
+ */
+void put_time(fd, the_time)
+FILE *fd;
+time_t the_time;
+{
+ int c;
+ int i;
+ time_t wtime = the_time;
+
+ /* time_t can be up to 8 bytes in size, more than long_u, thus we
+ * can't use put_bytes() here.
+ * Another problem is that ">>" may do an arithmetic shift that keeps the
+ * sign. This happens for large values of wtime. A cast to long_u may
+ * truncate if time_t is 8 bytes. So only use a cast when it is 4 bytes,
+ * it's safe to assume that long_u is 4 bytes or more and when using 8
+ * bytes the top bit won't be set. */
+ for (i = 7; i >= 0; --i) {
+ if (i + 1 > (int)sizeof(time_t))
+ /* ">>" doesn't work well when shifting more bits than avail */
+ putc(0, fd);
+ else {
+#if defined(SIZEOF_TIME_T) && SIZEOF_TIME_T > 4
+ c = (int)(wtime >> (i * 8));
+#else
+ c = (int)((long_u)wtime >> (i * 8));
+#endif
+ putc(c, fd);
+ }
+ }
+}
+
+
+
+#if (defined(FEAT_MBYTE) && defined(FEAT_QUICKFIX)) \
+ || defined(FEAT_SPELL) || defined(PROTO)
+/*
+ * Return TRUE if string "s" contains a non-ASCII character (128 or higher).
+ * When "s" is NULL FALSE is returned.
+ */
+int has_non_ascii(s)
+char_u *s;
+{
+ char_u *p;
+
+ if (s != NULL)
+ for (p = s; *p != NUL; ++p)
+ if (*p >= 128)
+ return TRUE;
+ return FALSE;
+}
+#endif
diff --git a/src/move.c b/src/move.c
new file mode 100644
index 0000000000..ed63dd212b
--- /dev/null
+++ b/src/move.c
@@ -0,0 +1,2215 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * 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.
+ */
+/*
+ * move.c: Functions for moving the cursor and scrolling text.
+ *
+ * There are two ways to move the cursor:
+ * 1. Move the cursor directly, the text is scrolled to keep the cursor in the
+ * window.
+ * 2. Scroll the text, the cursor is moved into the text visible in the
+ * window.
+ * The 'scrolloff' option makes this a bit complicated.
+ */
+
+#include "vim.h"
+
+static void comp_botline __ARGS((win_T *wp));
+static int scrolljump_value __ARGS((void));
+static int check_top_offset __ARGS((void));
+static void curs_rows __ARGS((win_T *wp, int do_botline));
+static void validate_botline_win __ARGS((win_T *wp));
+static void validate_cheight __ARGS((void));
+
+typedef struct {
+ linenr_T lnum; /* line number */
+ int fill; /* filler lines */
+ int height; /* height of added line */
+} lineoff_T;
+
+static void topline_back __ARGS((lineoff_T *lp));
+static void botline_forw __ARGS((lineoff_T *lp));
+static void botline_topline __ARGS((lineoff_T *lp));
+static void topline_botline __ARGS((lineoff_T *lp));
+static void max_topfill __ARGS((void));
+
+/*
+ * Compute wp->w_botline for the current wp->w_topline. Can be called after
+ * wp->w_topline changed.
+ */
+static void comp_botline(wp)
+win_T *wp;
+{
+ int n;
+ linenr_T lnum;
+ int done;
+ linenr_T last;
+ int folded;
+
+ /*
+ * If w_cline_row is valid, start there.
+ * Otherwise have to start at w_topline.
+ */
+ check_cursor_moved(wp);
+ if (wp->w_valid & VALID_CROW) {
+ lnum = wp->w_cursor.lnum;
+ done = wp->w_cline_row;
+ } else {
+ lnum = wp->w_topline;
+ done = 0;
+ }
+
+ for (; lnum <= wp->w_buffer->b_ml.ml_line_count; ++lnum) {
+ last = lnum;
+ folded = FALSE;
+ if (hasFoldingWin(wp, lnum, NULL, &last, TRUE, NULL)) {
+ n = 1;
+ folded = TRUE;
+ } else if (lnum == wp->w_topline)
+ n = plines_win_nofill(wp, lnum, TRUE) + wp->w_topfill;
+ else
+ n = plines_win(wp, lnum, TRUE);
+ if (
+ lnum <= wp->w_cursor.lnum && last >= wp->w_cursor.lnum
+ ) {
+ wp->w_cline_row = done;
+ wp->w_cline_height = n;
+ wp->w_cline_folded = folded;
+ wp->w_valid |= (VALID_CROW|VALID_CHEIGHT);
+ }
+ if (done + n > wp->w_height)
+ break;
+ done += n;
+ lnum = last;
+ }
+
+ /* wp->w_botline is the line that is just below the window */
+ wp->w_botline = lnum;
+ wp->w_valid |= VALID_BOTLINE|VALID_BOTLINE_AP;
+
+ set_empty_rows(wp, done);
+}
+
+/*
+ * Update curwin->w_topline and redraw if necessary.
+ * Used to update the screen before printing a message.
+ */
+void update_topline_redraw() {
+ update_topline();
+ if (must_redraw)
+ update_screen(0);
+}
+
+/*
+ * Update curwin->w_topline to move the cursor onto the screen.
+ */
+void update_topline() {
+ long line_count;
+ int halfheight;
+ int n;
+ linenr_T old_topline;
+ int old_topfill;
+ linenr_T lnum;
+ int check_topline = FALSE;
+ int check_botline = FALSE;
+ int save_so = p_so;
+
+ if (!screen_valid(TRUE))
+ return;
+
+ check_cursor_moved(curwin);
+ if (curwin->w_valid & VALID_TOPLINE)
+ return;
+
+ /* When dragging with the mouse, don't scroll that quickly */
+ if (mouse_dragging > 0)
+ p_so = mouse_dragging - 1;
+
+ 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)
+ redraw_later(NOT_VALID);
+ curwin->w_topline = 1;
+ curwin->w_botline = 2;
+ curwin->w_valid |= VALID_BOTLINE|VALID_BOTLINE_AP;
+ curwin->w_scbind_pos = 1;
+ }
+ /*
+ * If the cursor is above or near the top of the window, scroll the window
+ * to show the line the cursor is in, with 'scrolloff' context.
+ */
+ else {
+ if (curwin->w_topline > 1) {
+ /* If the cursor is above topline, scrolling is always needed.
+ * If the cursor is far below topline and there is no folding,
+ * scrolling down is never needed. */
+ if (curwin->w_cursor.lnum < curwin->w_topline)
+ check_topline = TRUE;
+ else if (check_top_offset())
+ check_topline = TRUE;
+ }
+ /* Check if there are more filler lines than allowed. */
+ if (!check_topline && curwin->w_topfill > diff_check_fill(curwin,
+ curwin->w_topline))
+ check_topline = TRUE;
+
+ if (check_topline) {
+ halfheight = curwin->w_height / 2 - 1;
+ if (halfheight < 2)
+ halfheight = 2;
+
+ if (hasAnyFolding(curwin)) {
+ /* Count the number of logical lines between the cursor and
+ * topline + p_so (approximation of how much will be
+ * scrolled). */
+ n = 0;
+ for (lnum = curwin->w_cursor.lnum;
+ lnum < curwin->w_topline + p_so; ++lnum) {
+ ++n;
+ /* stop at end of file or when we know we are far off */
+ if (lnum >= curbuf->b_ml.ml_line_count || n >= halfheight)
+ break;
+ (void)hasFolding(lnum, NULL, &lnum);
+ }
+ } else
+ n = curwin->w_topline + p_so - curwin->w_cursor.lnum;
+
+ /* If we weren't very close to begin with, we scroll to put the
+ * cursor in the middle of the window. Otherwise put the cursor
+ * near the top of the window. */
+ if (n >= halfheight)
+ scroll_cursor_halfway(FALSE);
+ else {
+ scroll_cursor_top(scrolljump_value(), FALSE);
+ check_botline = TRUE;
+ }
+ } else {
+ /* Make sure topline is the first line of a fold. */
+ (void)hasFolding(curwin->w_topline, &curwin->w_topline, NULL);
+ check_botline = TRUE;
+ }
+ }
+
+ /*
+ * If the cursor is below the bottom of the window, scroll the window
+ * to put the cursor on the window.
+ * When w_botline is invalid, recompute it first, to avoid a redraw later.
+ * If w_botline was approximated, we might need a redraw later in a few
+ * cases, but we don't want to spend (a lot of) time recomputing w_botline
+ * for every small change.
+ */
+ if (check_botline) {
+ if (!(curwin->w_valid & VALID_BOTLINE_AP))
+ validate_botline();
+
+ if (curwin->w_botline <= curbuf->b_ml.ml_line_count) {
+ if (curwin->w_cursor.lnum < curwin->w_botline) {
+ if (((long)curwin->w_cursor.lnum
+ >= (long)curwin->w_botline - p_so
+ || hasAnyFolding(curwin)
+ )) {
+ lineoff_T loff;
+
+ /* Cursor is (a few lines) above botline, check if there are
+ * 'scrolloff' window lines below the cursor. If not, need to
+ * scroll. */
+ n = curwin->w_empty_rows;
+ loff.lnum = curwin->w_cursor.lnum;
+ /* In a fold go to its last line. */
+ (void)hasFolding(loff.lnum, NULL, &loff.lnum);
+ loff.fill = 0;
+ n += curwin->w_filler_rows;
+ loff.height = 0;
+ while (loff.lnum < curwin->w_botline
+ && (loff.lnum + 1 < curwin->w_botline || loff.fill == 0)
+ ) {
+ n += loff.height;
+ if (n >= p_so)
+ break;
+ botline_forw(&loff);
+ }
+ if (n >= p_so)
+ /* sufficient context, no need to scroll */
+ check_botline = FALSE;
+ } else
+ /* sufficient context, no need to scroll */
+ check_botline = FALSE;
+ }
+ if (check_botline) {
+ if (hasAnyFolding(curwin)) {
+ /* Count the number of logical lines between the cursor and
+ * botline - p_so (approximation of how much will be
+ * scrolled). */
+ line_count = 0;
+ for (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)
+ 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)
+ scroll_cursor_bot(scrolljump_value(), FALSE);
+ else
+ scroll_cursor_halfway(FALSE);
+ }
+ }
+ }
+ curwin->w_valid |= VALID_TOPLINE;
+
+ /*
+ * Need to redraw when topline changed.
+ */
+ if (curwin->w_topline != old_topline
+ || curwin->w_topfill != old_topfill
+ ) {
+ dollar_vcol = -1;
+ if (curwin->w_skipcol != 0) {
+ curwin->w_skipcol = 0;
+ redraw_later(NOT_VALID);
+ } else
+ redraw_later(VALID);
+ /* May need to set w_skipcol when cursor in w_topline. */
+ if (curwin->w_cursor.lnum == curwin->w_topline)
+ validate_cursor();
+ }
+
+ p_so = save_so;
+}
+
+/*
+ * Return the scrolljump value to use for the current window.
+ * When 'scrolljump' is positive use it as-is.
+ * When 'scrolljump' is negative use it as a percentage of the window height.
+ */
+static int scrolljump_value() {
+ if (p_sj >= 0)
+ return (int)p_sj;
+ return (curwin->w_height * -p_sj) / 100;
+}
+
+/*
+ * Return TRUE when there are not 'scrolloff' lines above the cursor for the
+ * current window.
+ */
+static int check_top_offset() {
+ lineoff_T loff;
+ int n;
+
+ if (curwin->w_cursor.lnum < curwin->w_topline + p_so
+ || hasAnyFolding(curwin)
+ ) {
+ loff.lnum = curwin->w_cursor.lnum;
+ loff.fill = 0;
+ n = curwin->w_topfill; /* always have this context */
+ /* Count the visible screen lines above the cursor line. */
+ while (n < p_so) {
+ topline_back(&loff);
+ /* Stop when included a line above the window. */
+ if (loff.lnum < curwin->w_topline
+ || (loff.lnum == curwin->w_topline && loff.fill > 0)
+ )
+ break;
+ n += loff.height;
+ }
+ if (n < p_so)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void update_curswant() {
+ if (curwin->w_set_curswant) {
+ validate_virtcol();
+ curwin->w_curswant = curwin->w_virtcol;
+ curwin->w_set_curswant = FALSE;
+ }
+}
+
+/*
+ * Check if the cursor has moved. Set the w_valid flag accordingly.
+ */
+void check_cursor_moved(wp)
+win_T *wp;
+{
+ if (wp->w_cursor.lnum != wp->w_valid_cursor.lnum) {
+ wp->w_valid &= ~(VALID_WROW|VALID_WCOL|VALID_VIRTCOL
+ |VALID_CHEIGHT|VALID_CROW|VALID_TOPLINE);
+ wp->w_valid_cursor = wp->w_cursor;
+ wp->w_valid_leftcol = wp->w_leftcol;
+ } else if (wp->w_cursor.col != wp->w_valid_cursor.col
+ || wp->w_leftcol != wp->w_valid_leftcol
+ || wp->w_cursor.coladd != wp->w_valid_cursor.coladd
+ ) {
+ wp->w_valid &= ~(VALID_WROW|VALID_WCOL|VALID_VIRTCOL);
+ wp->w_valid_cursor.col = wp->w_cursor.col;
+ wp->w_valid_leftcol = wp->w_leftcol;
+ wp->w_valid_cursor.coladd = wp->w_cursor.coladd;
+ }
+}
+
+/*
+ * Call this function when some window settings have changed, which require
+ * the cursor position, botline and topline to be recomputed and the window to
+ * be redrawn. E.g, when changing the 'wrap' option or folding.
+ */
+void changed_window_setting() {
+ changed_window_setting_win(curwin);
+}
+
+void changed_window_setting_win(wp)
+win_T *wp;
+{
+ wp->w_lines_valid = 0;
+ changed_line_abv_curs_win(wp);
+ wp->w_valid &= ~(VALID_BOTLINE|VALID_BOTLINE_AP|VALID_TOPLINE);
+ redraw_win_later(wp, NOT_VALID);
+}
+
+/*
+ * Set wp->w_topline to a certain number.
+ */
+void set_topline(wp, lnum)
+win_T *wp;
+linenr_T lnum;
+{
+ /* go to first of folded lines */
+ (void)hasFoldingWin(wp, lnum, &lnum, NULL, TRUE, NULL);
+ /* Approximate the value of w_botline */
+ wp->w_botline += lnum - wp->w_topline;
+ wp->w_topline = lnum;
+ wp->w_topline_was_set = TRUE;
+ wp->w_topfill = 0;
+ wp->w_valid &= ~(VALID_WROW|VALID_CROW|VALID_BOTLINE|VALID_TOPLINE);
+ /* Don't set VALID_TOPLINE here, 'scrolloff' needs to be checked. */
+ redraw_later(VALID);
+}
+
+/*
+ * Call this function when the length of the cursor line (in screen
+ * characters) has changed, and the change is before the cursor.
+ * Need to take care of w_botline separately!
+ */
+void changed_cline_bef_curs() {
+ curwin->w_valid &= ~(VALID_WROW|VALID_WCOL|VALID_VIRTCOL
+ |VALID_CHEIGHT|VALID_TOPLINE);
+}
+
+void changed_cline_bef_curs_win(wp)
+win_T *wp;
+{
+ wp->w_valid &= ~(VALID_WROW|VALID_WCOL|VALID_VIRTCOL
+ |VALID_CHEIGHT|VALID_TOPLINE);
+}
+
+/*
+ * Call this function when the length of a line (in screen characters) above
+ * the cursor have changed.
+ * Need to take care of w_botline separately!
+ */
+void changed_line_abv_curs() {
+ curwin->w_valid &= ~(VALID_WROW|VALID_WCOL|VALID_VIRTCOL|VALID_CROW
+ |VALID_CHEIGHT|VALID_TOPLINE);
+}
+
+void changed_line_abv_curs_win(wp)
+win_T *wp;
+{
+ wp->w_valid &= ~(VALID_WROW|VALID_WCOL|VALID_VIRTCOL|VALID_CROW
+ |VALID_CHEIGHT|VALID_TOPLINE);
+}
+
+/*
+ * Make sure the value of curwin->w_botline is valid.
+ */
+void validate_botline() {
+ if (!(curwin->w_valid & VALID_BOTLINE))
+ comp_botline(curwin);
+}
+
+/*
+ * Make sure the value of wp->w_botline is valid.
+ */
+static void validate_botline_win(wp)
+win_T *wp;
+{
+ if (!(wp->w_valid & VALID_BOTLINE))
+ comp_botline(wp);
+}
+
+/*
+ * Mark curwin->w_botline as invalid (because of some change in the buffer).
+ */
+void invalidate_botline() {
+ curwin->w_valid &= ~(VALID_BOTLINE|VALID_BOTLINE_AP);
+}
+
+void invalidate_botline_win(wp)
+win_T *wp;
+{
+ wp->w_valid &= ~(VALID_BOTLINE|VALID_BOTLINE_AP);
+}
+
+void approximate_botline_win(wp)
+win_T *wp;
+{
+ wp->w_valid &= ~VALID_BOTLINE;
+}
+
+/*
+ * Return TRUE if curwin->w_wrow and curwin->w_wcol are valid.
+ */
+int cursor_valid() {
+ check_cursor_moved(curwin);
+ return (curwin->w_valid & (VALID_WROW|VALID_WCOL)) ==
+ (VALID_WROW|VALID_WCOL);
+}
+
+/*
+ * Validate cursor position. Makes sure w_wrow and w_wcol are valid.
+ * w_topline must be valid, you may need to call update_topline() first!
+ */
+void validate_cursor() {
+ check_cursor_moved(curwin);
+ if ((curwin->w_valid & (VALID_WCOL|VALID_WROW)) != (VALID_WCOL|VALID_WROW))
+ curs_columns(TRUE);
+}
+
+/*
+ * Compute wp->w_cline_row and wp->w_cline_height, based on the current value
+ * of wp->w_topline.
+ *
+ * Returns OK when cursor is in the window, FAIL when it isn't.
+ */
+static void curs_rows(wp, do_botline)
+win_T *wp;
+int do_botline; /* also compute w_botline */
+{
+ linenr_T lnum;
+ int i;
+ int all_invalid;
+ int valid;
+ long fold_count;
+
+ /* Check if wp->w_lines[].wl_size is invalid */
+ all_invalid = (!redrawing()
+ || wp->w_lines_valid == 0
+ || wp->w_lines[0].wl_lnum > wp->w_topline);
+ i = 0;
+ wp->w_cline_row = 0;
+ for (lnum = wp->w_topline; lnum < wp->w_cursor.lnum; ++i) {
+ valid = FALSE;
+ if (!all_invalid && i < wp->w_lines_valid) {
+ if (wp->w_lines[i].wl_lnum < lnum || !wp->w_lines[i].wl_valid)
+ continue; /* skip changed or deleted lines */
+ if (wp->w_lines[i].wl_lnum == lnum) {
+ /* Check for newly inserted lines below this row, in which
+ * case we need to check for folded lines. */
+ if (!wp->w_buffer->b_mod_set
+ || wp->w_lines[i].wl_lastlnum < wp->w_cursor.lnum
+ || wp->w_buffer->b_mod_top
+ > wp->w_lines[i].wl_lastlnum + 1)
+ valid = TRUE;
+ } else if (wp->w_lines[i].wl_lnum > lnum)
+ --i; /* hold at inserted lines */
+ }
+ if (valid
+ && (lnum != wp->w_topline || !wp->w_p_diff)
+ ) {
+ lnum = wp->w_lines[i].wl_lastlnum + 1;
+ /* Cursor inside folded lines, don't count this row */
+ if (lnum > wp->w_cursor.lnum)
+ break;
+ wp->w_cline_row += wp->w_lines[i].wl_size;
+ } else {
+ fold_count = foldedCount(wp, lnum, NULL);
+ if (fold_count) {
+ lnum += fold_count;
+ if (lnum > wp->w_cursor.lnum)
+ break;
+ ++wp->w_cline_row;
+ } else if (lnum == wp->w_topline)
+ wp->w_cline_row += plines_win_nofill(wp, lnum++, TRUE)
+ + wp->w_topfill;
+ else
+ wp->w_cline_row += plines_win(wp, lnum++, TRUE);
+ }
+ }
+
+ check_cursor_moved(wp);
+ if (!(wp->w_valid & VALID_CHEIGHT)) {
+ if (all_invalid
+ || i == wp->w_lines_valid
+ || (i < wp->w_lines_valid
+ && (!wp->w_lines[i].wl_valid
+ || wp->w_lines[i].wl_lnum != wp->w_cursor.lnum))) {
+ if (wp->w_cursor.lnum == wp->w_topline)
+ wp->w_cline_height = plines_win_nofill(wp, wp->w_cursor.lnum,
+ TRUE) + wp->w_topfill;
+ else
+ wp->w_cline_height = plines_win(wp, wp->w_cursor.lnum, TRUE);
+ wp->w_cline_folded = hasFoldingWin(wp, wp->w_cursor.lnum,
+ NULL, NULL, TRUE, NULL);
+ } else if (i > wp->w_lines_valid) {
+ /* a line that is too long to fit on the last screen line */
+ wp->w_cline_height = 0;
+ wp->w_cline_folded = hasFoldingWin(wp, wp->w_cursor.lnum,
+ NULL, NULL, TRUE, NULL);
+ } else {
+ wp->w_cline_height = wp->w_lines[i].wl_size;
+ wp->w_cline_folded = wp->w_lines[i].wl_folded;
+ }
+ }
+
+ wp->w_valid |= VALID_CROW|VALID_CHEIGHT;
+
+ /* validate botline too, if update_screen doesn't do it */
+ if (do_botline && all_invalid)
+ validate_botline_win(wp);
+}
+
+/*
+ * Validate curwin->w_virtcol only.
+ */
+void validate_virtcol() {
+ validate_virtcol_win(curwin);
+}
+
+/*
+ * Validate wp->w_virtcol only.
+ */
+void validate_virtcol_win(wp)
+win_T *wp;
+{
+ check_cursor_moved(wp);
+ if (!(wp->w_valid & VALID_VIRTCOL)) {
+ getvvcol(wp, &wp->w_cursor, NULL, &(wp->w_virtcol), NULL);
+ wp->w_valid |= VALID_VIRTCOL;
+ if (wp->w_p_cuc
+ && !pum_visible()
+ )
+ redraw_win_later(wp, SOME_VALID);
+ }
+}
+
+/*
+ * Validate curwin->w_cline_height only.
+ */
+static void validate_cheight() {
+ check_cursor_moved(curwin);
+ if (!(curwin->w_valid & VALID_CHEIGHT)) {
+ if (curwin->w_cursor.lnum == curwin->w_topline)
+ curwin->w_cline_height = plines_nofill(curwin->w_cursor.lnum)
+ + curwin->w_topfill;
+ else
+ curwin->w_cline_height = plines(curwin->w_cursor.lnum);
+ curwin->w_cline_folded = hasFolding(curwin->w_cursor.lnum, NULL, NULL);
+ curwin->w_valid |= VALID_CHEIGHT;
+ }
+}
+
+/*
+ * Validate w_wcol and w_virtcol only.
+ */
+void validate_cursor_col() {
+ colnr_T off;
+ colnr_T col;
+ int width;
+
+ validate_virtcol();
+ if (!(curwin->w_valid & VALID_WCOL)) {
+ col = curwin->w_virtcol;
+ off = curwin_col_off();
+ col += off;
+ width = W_WIDTH(curwin) - off + curwin_col_off2();
+
+ /* long line wrapping, adjust curwin->w_wrow */
+ if (curwin->w_p_wrap
+ && col >= (colnr_T)W_WIDTH(curwin)
+ && width > 0)
+ /* use same formula as what is used in curs_columns() */
+ col -= ((col - W_WIDTH(curwin)) / width + 1) * width;
+ if (col > (int)curwin->w_leftcol)
+ col -= curwin->w_leftcol;
+ else
+ col = 0;
+ curwin->w_wcol = col;
+
+ curwin->w_valid |= VALID_WCOL;
+ }
+}
+
+/*
+ * Compute offset of a window, occupied by absolute or relative line number,
+ * fold column and sign column (these don't move when scrolling horizontally).
+ */
+int win_col_off(wp)
+win_T *wp;
+{
+ return ((wp->w_p_nu || wp->w_p_rnu) ? number_width(wp) + 1 : 0)
+ + (cmdwin_type == 0 || wp != curwin ? 0 : 1)
+ + wp->w_p_fdc
+ ;
+}
+
+int curwin_col_off() {
+ return win_col_off(curwin);
+}
+
+/*
+ * Return the difference in column offset for the second screen line of a
+ * wrapped line. It's 8 if 'number' or 'relativenumber' is on and 'n' is in
+ * 'cpoptions'.
+ */
+int win_col_off2(wp)
+win_T *wp;
+{
+ if ((wp->w_p_nu || wp->w_p_rnu) && vim_strchr(p_cpo, CPO_NUMCOL) != NULL)
+ return number_width(wp) + 1;
+ return 0;
+}
+
+int curwin_col_off2() {
+ return win_col_off2(curwin);
+}
+
+/*
+ * compute curwin->w_wcol and curwin->w_virtcol.
+ * Also updates curwin->w_wrow and curwin->w_cline_row.
+ * Also updates curwin->w_leftcol.
+ */
+void curs_columns(may_scroll)
+int may_scroll; /* when TRUE, may scroll horizontally */
+{
+ int diff;
+ int extra; /* offset for first screen line */
+ int off_left, off_right;
+ int n;
+ int p_lines;
+ int width = 0;
+ int textwidth;
+ int new_leftcol;
+ colnr_T startcol;
+ colnr_T endcol;
+ colnr_T prev_skipcol;
+
+ /*
+ * First make sure that w_topline is valid (after moving the cursor).
+ */
+ update_topline();
+
+ /*
+ * Next make sure that w_cline_row is valid.
+ */
+ if (!(curwin->w_valid & VALID_CROW))
+ curs_rows(curwin, FALSE);
+
+ /*
+ * Compute the number of virtual columns.
+ */
+ if (curwin->w_cline_folded)
+ /* In a folded line the cursor is always in the first column */
+ startcol = curwin->w_virtcol = endcol = curwin->w_leftcol;
+ else
+ getvvcol(curwin, &curwin->w_cursor,
+ &startcol, &(curwin->w_virtcol), &endcol);
+
+ /* remove '$' from change command when cursor moves onto it */
+ if (startcol > dollar_vcol)
+ dollar_vcol = -1;
+
+ extra = curwin_col_off();
+ curwin->w_wcol = curwin->w_virtcol + extra;
+ endcol += extra;
+
+ /*
+ * Now compute w_wrow, counting screen lines from w_cline_row.
+ */
+ curwin->w_wrow = curwin->w_cline_row;
+
+ textwidth = W_WIDTH(curwin) - extra;
+ if (textwidth <= 0) {
+ /* No room for text, put cursor in last char of window. */
+ curwin->w_wcol = W_WIDTH(curwin) - 1;
+ curwin->w_wrow = curwin->w_height - 1;
+ } else if (curwin->w_p_wrap
+ && curwin->w_width != 0
+ ) {
+ width = textwidth + curwin_col_off2();
+
+ /* long line wrapping, adjust curwin->w_wrow */
+ if (curwin->w_wcol >= W_WIDTH(curwin)) {
+ /* this same formula is used in validate_cursor_col() */
+ n = (curwin->w_wcol - W_WIDTH(curwin)) / width + 1;
+ curwin->w_wcol -= n * width;
+ curwin->w_wrow += n;
+
+ /* When cursor wraps to first char of next line in Insert
+ * mode, the 'showbreak' string isn't shown, backup to first
+ * column */
+ if (*p_sbr && *ml_get_cursor() == NUL
+ && curwin->w_wcol == (int)vim_strsize(p_sbr))
+ curwin->w_wcol = 0;
+ }
+ }
+ /* No line wrapping: compute curwin->w_leftcol if scrolling is on and line
+ * is not folded.
+ * If scrolling is off, curwin->w_leftcol is assumed to be 0 */
+ else if (may_scroll
+ && !curwin->w_cline_folded
+ ) {
+ /*
+ * If Cursor is left of the screen, scroll rightwards.
+ * If Cursor is right of the screen, scroll leftwards
+ * If we get closer to the edge than 'sidescrolloff', scroll a little
+ * extra
+ */
+ off_left = (int)startcol - (int)curwin->w_leftcol - p_siso;
+ off_right = (int)endcol - (int)(curwin->w_leftcol + W_WIDTH(curwin)
+ - p_siso) + 1;
+ if (off_left < 0 || off_right > 0) {
+ if (off_left < 0)
+ diff = -off_left;
+ else
+ diff = off_right;
+
+ /* When far off or not enough room on either side, put cursor in
+ * middle of window. */
+ if (p_ss == 0 || diff >= textwidth / 2 || off_right >= off_left)
+ new_leftcol = curwin->w_wcol - extra - textwidth / 2;
+ else {
+ if (diff < p_ss)
+ diff = p_ss;
+ if (off_left < 0)
+ new_leftcol = curwin->w_leftcol - diff;
+ else
+ new_leftcol = curwin->w_leftcol + diff;
+ }
+ if (new_leftcol < 0)
+ new_leftcol = 0;
+ if (new_leftcol != (int)curwin->w_leftcol) {
+ curwin->w_leftcol = new_leftcol;
+ /* screen has to be redrawn with new curwin->w_leftcol */
+ redraw_later(NOT_VALID);
+ }
+ }
+ curwin->w_wcol -= curwin->w_leftcol;
+ } else if (curwin->w_wcol > (int)curwin->w_leftcol)
+ curwin->w_wcol -= curwin->w_leftcol;
+ else
+ curwin->w_wcol = 0;
+
+ /* Skip over filler lines. At the top use w_topfill, there
+ * may be some filler lines above the window. */
+ if (curwin->w_cursor.lnum == curwin->w_topline)
+ curwin->w_wrow += curwin->w_topfill;
+ else
+ curwin->w_wrow += diff_check_fill(curwin, curwin->w_cursor.lnum);
+
+ prev_skipcol = curwin->w_skipcol;
+
+ p_lines = 0;
+ if ((curwin->w_wrow >= curwin->w_height
+ || ((prev_skipcol > 0
+ || curwin->w_wrow + p_so >= curwin->w_height)
+ && (p_lines =
+ plines_win_nofill
+ (curwin, curwin->w_cursor.lnum, FALSE))
+ - 1 >= curwin->w_height))
+ && curwin->w_height != 0
+ && curwin->w_cursor.lnum == curwin->w_topline
+ && width > 0
+ && curwin->w_width != 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
+ * cursor. Avoid scrolling all the time. compute value of "extra":
+ * 1: Less than "p_so" lines above
+ * 2: Less than "p_so" lines below
+ * 3: both of them */
+ extra = 0;
+ if (curwin->w_skipcol + p_so * width > curwin->w_virtcol)
+ extra = 1;
+ /* Compute last display line of the buffer line that we want at the
+ * bottom of the window. */
+ if (p_lines == 0)
+ p_lines = plines_win(curwin, curwin->w_cursor.lnum, FALSE);
+ --p_lines;
+ if (p_lines > curwin->w_wrow + p_so)
+ n = curwin->w_wrow + p_so;
+ else
+ n = p_lines;
+ if ((colnr_T)n >= curwin->w_height + curwin->w_skipcol / width)
+ extra += 2;
+
+ if (extra == 3 || p_lines < p_so * 2) {
+ /* 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
+ n = 0;
+ /* don't skip more than necessary */
+ if (n > p_lines - curwin->w_height + 1)
+ n = p_lines - curwin->w_height + 1;
+ curwin->w_skipcol = n * width;
+ } else if (extra == 1) {
+ /* less then 'scrolloff' lines above, decrease skipcol */
+ extra = (curwin->w_skipcol + p_so * width - curwin->w_virtcol
+ + width - 1) / width;
+ if (extra > 0) {
+ if ((colnr_T)(extra * width) > curwin->w_skipcol)
+ extra = curwin->w_skipcol / width;
+ 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)
+ endcol -= width;
+ 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;
+ 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);
+ else if (extra < 0)
+ win_del_lines(curwin, 0, -extra, FALSE, FALSE);
+ } else
+ curwin->w_skipcol = 0;
+ if (prev_skipcol != curwin->w_skipcol)
+ redraw_later(NOT_VALID);
+
+ /* Redraw when w_row changes and 'relativenumber' is set */
+ if (((curwin->w_valid & VALID_WROW) == 0 && (curwin->w_p_rnu
+ /* or when w_row changes and 'cursorline' is set. */
+ || curwin->w_p_cul
+ ))
+ /* or when w_virtcol changes and 'cursorcolumn' is set */
+ || (curwin->w_p_cuc && (curwin->w_valid & VALID_VIRTCOL) == 0)
+ )
+ if (!pum_visible())
+ redraw_later(SOME_VALID);
+
+ curwin->w_valid |= VALID_WCOL|VALID_WROW|VALID_VIRTCOL;
+}
+
+/*
+ * Scroll the current window down by "line_count" logical lines. "CTRL-Y"
+ */
+void scrolldown(line_count, byfold)
+long line_count;
+int byfold UNUSED; /* TRUE: count a closed fold as one line */
+{
+ long done = 0; /* total # of physical lines done */
+ int wrow;
+ int moved = FALSE;
+
+ linenr_T first;
+
+ /* Make sure w_topline is at the first of a sequence of folded lines. */
+ (void)hasFolding(curwin->w_topline, &curwin->w_topline, NULL);
+ 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;
+ } else {
+ if (curwin->w_topline == 1)
+ break;
+ --curwin->w_topline;
+ curwin->w_topfill = 0;
+ /* A sequence of folded lines only counts for one logical line */
+ if (hasFolding(curwin->w_topline, &first, NULL)) {
+ ++done;
+ if (!byfold)
+ line_count -= curwin->w_topline - first - 1;
+ curwin->w_botline -= curwin->w_topline - first;
+ curwin->w_topline = first;
+ } else
+ done += plines_nofill(curwin->w_topline);
+ }
+ --curwin->w_botline; /* approximate w_botline */
+ invalidate_botline();
+ }
+ curwin->w_wrow += done; /* keep w_wrow updated */
+ curwin->w_cline_row += done; /* keep w_cline_row updated */
+
+ if (curwin->w_cursor.lnum == curwin->w_topline)
+ curwin->w_cline_row = 0;
+ check_topfill(curwin, TRUE);
+
+ /*
+ * Compute the row number of the last row of the cursor line
+ * and move the cursor onto the displayed part of the window.
+ */
+ wrow = curwin->w_wrow;
+ if (curwin->w_p_wrap
+ && curwin->w_width != 0
+ ) {
+ validate_virtcol();
+ validate_cheight();
+ wrow += curwin->w_cline_height - 1 -
+ curwin->w_virtcol / W_WIDTH(curwin);
+ }
+ while (wrow >= curwin->w_height && curwin->w_cursor.lnum > 1) {
+ if (hasFolding(curwin->w_cursor.lnum, &first, NULL)) {
+ --wrow;
+ if (first == 1)
+ curwin->w_cursor.lnum = 1;
+ else
+ curwin->w_cursor.lnum = first - 1;
+ } else
+ wrow -= plines(curwin->w_cursor.lnum--);
+ curwin->w_valid &=
+ ~(VALID_WROW|VALID_WCOL|VALID_CHEIGHT|VALID_CROW|VALID_VIRTCOL);
+ moved = TRUE;
+ }
+ if (moved) {
+ /* Move cursor to first line of closed fold. */
+ foldAdjustCursor();
+ coladvance(curwin->w_curswant);
+ }
+}
+
+/*
+ * Scroll the current window up by "line_count" logical lines. "CTRL-E"
+ */
+void scrollup(line_count, byfold)
+long line_count;
+int byfold UNUSED; /* TRUE: count a closed fold as one line */
+{
+ linenr_T lnum;
+
+ if (
+ (byfold && hasAnyFolding(curwin))
+ ||
+ curwin->w_p_diff
+ ) {
+ /* count each sequence of folded lines as one logical line */
+ lnum = curwin->w_topline;
+ while (line_count--) {
+ if (curwin->w_topfill > 0)
+ --curwin->w_topfill;
+ else {
+ if (byfold)
+ (void)hasFolding(lnum, NULL, &lnum);
+ if (lnum >= curbuf->b_ml.ml_line_count)
+ break;
+ ++lnum;
+ curwin->w_topfill = diff_check_fill(curwin, lnum);
+ }
+ }
+ /* approximate w_botline */
+ curwin->w_botline += lnum - curwin->w_topline;
+ curwin->w_topline = lnum;
+ } else {
+ curwin->w_topline += line_count;
+ curwin->w_botline += line_count; /* approximate w_botline */
+ }
+
+ if (curwin->w_topline > curbuf->b_ml.ml_line_count)
+ curwin->w_topline = curbuf->b_ml.ml_line_count;
+ if (curwin->w_botline > curbuf->b_ml.ml_line_count + 1)
+ curwin->w_botline = curbuf->b_ml.ml_line_count + 1;
+
+ check_topfill(curwin, FALSE);
+
+ if (hasAnyFolding(curwin))
+ /* Make sure w_topline is at the first of a sequence of folded lines. */
+ (void)hasFolding(curwin->w_topline, &curwin->w_topline, NULL);
+
+ curwin->w_valid &= ~(VALID_WROW|VALID_CROW|VALID_BOTLINE);
+ if (curwin->w_cursor.lnum < curwin->w_topline) {
+ curwin->w_cursor.lnum = curwin->w_topline;
+ curwin->w_valid &=
+ ~(VALID_WROW|VALID_WCOL|VALID_CHEIGHT|VALID_CROW|VALID_VIRTCOL);
+ coladvance(curwin->w_curswant);
+ }
+}
+
+/*
+ * Don't end up with too many filler lines in the window.
+ */
+void check_topfill(wp, down)
+win_T *wp;
+int down; /* when TRUE scroll down when not enough space */
+{
+ int n;
+
+ if (wp->w_topfill > 0) {
+ n = plines_win_nofill(wp, wp->w_topline, TRUE);
+ if (wp->w_topfill + n > wp->w_height) {
+ 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 = 0;
+ }
+ }
+ }
+}
+
+/*
+ * Use as many filler lines as possible for w_topline. Make sure w_topline
+ * is still visible.
+ */
+static void max_topfill() {
+ int n;
+
+ n = plines_nofill(curwin->w_topline);
+ if (n >= curwin->w_height)
+ curwin->w_topfill = 0;
+ 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;
+ }
+}
+
+/*
+ * Scroll the screen one line down, but don't do it if it would move the
+ * cursor off the screen.
+ */
+void scrolldown_clamp() {
+ int end_row;
+ int can_fill = (curwin->w_topfill
+ < diff_check_fill(curwin, curwin->w_topline));
+
+ if (curwin->w_topline <= 1
+ && !can_fill
+ )
+ return;
+
+ validate_cursor(); /* w_wrow needs to be valid */
+
+ /*
+ * Compute the row number of the last row of the cursor line
+ * and make sure it doesn't go off the screen. Make sure the cursor
+ * doesn't go past 'scrolloff' lines from the screen end.
+ */
+ end_row = curwin->w_wrow;
+ if (can_fill)
+ ++end_row;
+ else
+ end_row += plines_nofill(curwin->w_topline - 1);
+ if (curwin->w_p_wrap
+ && curwin->w_width != 0
+ ) {
+ validate_cheight();
+ validate_virtcol();
+ end_row += curwin->w_cline_height - 1 -
+ curwin->w_virtcol / W_WIDTH(curwin);
+ }
+ if (end_row < curwin->w_height - p_so) {
+ if (can_fill) {
+ ++curwin->w_topfill;
+ check_topfill(curwin, TRUE);
+ } else {
+ --curwin->w_topline;
+ curwin->w_topfill = 0;
+ }
+ hasFolding(curwin->w_topline, &curwin->w_topline, NULL);
+ --curwin->w_botline; /* approximate w_botline */
+ curwin->w_valid &= ~(VALID_WROW|VALID_CROW|VALID_BOTLINE);
+ }
+}
+
+/*
+ * Scroll the screen one line up, but don't do it if it would move the cursor
+ * off the screen.
+ */
+void scrollup_clamp() {
+ int start_row;
+
+ if (curwin->w_topline == curbuf->b_ml.ml_line_count
+ && curwin->w_topfill == 0
+ )
+ return;
+
+ validate_cursor(); /* w_wrow needs to be valid */
+
+ /*
+ * Compute the row number of the first row of the cursor line
+ * and make sure it doesn't go off the screen. Make sure the cursor
+ * doesn't go before 'scrolloff' lines from the screen start.
+ */
+ start_row = curwin->w_wrow - plines_nofill(curwin->w_topline)
+ - curwin->w_topfill;
+ if (curwin->w_p_wrap
+ && curwin->w_width != 0
+ ) {
+ validate_virtcol();
+ start_row -= curwin->w_virtcol / W_WIDTH(curwin);
+ }
+ if (start_row >= p_so) {
+ if (curwin->w_topfill > 0)
+ --curwin->w_topfill;
+ else {
+ (void)hasFolding(curwin->w_topline, NULL, &curwin->w_topline);
+ ++curwin->w_topline;
+ }
+ ++curwin->w_botline; /* approximate w_botline */
+ curwin->w_valid &= ~(VALID_WROW|VALID_CROW|VALID_BOTLINE);
+ }
+}
+
+/*
+ * Add one line above "lp->lnum". This can be a filler line, a closed fold or
+ * a (wrapped) text line. Uses and sets "lp->fill".
+ * Returns the height of the added line in "lp->height".
+ * Lines above the first one are incredibly high: MAXCOL.
+ */
+static void topline_back(lp)
+lineoff_T *lp;
+{
+ if (lp->fill < diff_check_fill(curwin, lp->lnum)) {
+ /* Add a filler line. */
+ ++lp->fill;
+ lp->height = 1;
+ } else {
+ --lp->lnum;
+ lp->fill = 0;
+ if (lp->lnum < 1)
+ lp->height = MAXCOL;
+ else if (hasFolding(lp->lnum, &lp->lnum, NULL))
+ /* Add a closed fold */
+ lp->height = 1;
+ else {
+ lp->height = plines_nofill(lp->lnum);
+ }
+ }
+}
+
+/*
+ * Add one line below "lp->lnum". This can be a filler line, a closed fold or
+ * a (wrapped) text line. Uses and sets "lp->fill".
+ * Returns the height of the added line in "lp->height".
+ * Lines below the last one are incredibly high.
+ */
+static void botline_forw(lp)
+lineoff_T *lp;
+{
+ if (lp->fill < diff_check_fill(curwin, lp->lnum + 1)) {
+ /* Add a filler line. */
+ ++lp->fill;
+ lp->height = 1;
+ } else {
+ ++lp->lnum;
+ lp->fill = 0;
+ if (lp->lnum > curbuf->b_ml.ml_line_count)
+ lp->height = MAXCOL;
+ else if (hasFolding(lp->lnum, NULL, &lp->lnum))
+ /* Add a closed fold */
+ lp->height = 1;
+ else {
+ lp->height = plines_nofill(lp->lnum);
+ }
+ }
+}
+
+/*
+ * Switch from including filler lines below lp->lnum to including filler
+ * lines above loff.lnum + 1. This keeps pointing to the same line.
+ * When there are no filler lines nothing changes.
+ */
+static void botline_topline(lp)
+lineoff_T *lp;
+{
+ if (lp->fill > 0) {
+ ++lp->lnum;
+ lp->fill = diff_check_fill(curwin, lp->lnum) - lp->fill + 1;
+ }
+}
+
+/*
+ * Switch from including filler lines above lp->lnum to including filler
+ * lines below loff.lnum - 1. This keeps pointing to the same line.
+ * When there are no filler lines nothing changes.
+ */
+static void topline_botline(lp)
+lineoff_T *lp;
+{
+ if (lp->fill > 0) {
+ lp->fill = diff_check_fill(curwin, lp->lnum) - lp->fill + 1;
+ --lp->lnum;
+ }
+}
+
+/*
+ * Recompute topline to put the cursor at the top of the window.
+ * Scroll at least "min_scroll" lines.
+ * If "always" is TRUE, always set topline (for "zt").
+ */
+void scroll_cursor_top(min_scroll, always)
+int min_scroll;
+int always;
+{
+ int scrolled = 0;
+ int extra = 0;
+ int used;
+ int i;
+ linenr_T top; /* just above displayed lines */
+ linenr_T bot; /* just below displayed lines */
+ linenr_T old_topline = curwin->w_topline;
+ linenr_T old_topfill = curwin->w_topfill;
+ linenr_T new_topline;
+ int off = p_so;
+
+ if (mouse_dragging > 0)
+ off = mouse_dragging - 1;
+
+ /*
+ * Decrease topline until:
+ * - it has become 1
+ * - (part of) the cursor line is moved off the screen or
+ * - moved at least 'scrolljump' lines and
+ * - at least 'scrolloff' lines above and below the cursor
+ */
+ validate_cheight();
+ used = curwin->w_cline_height;
+ if (curwin->w_cursor.lnum < curwin->w_topline)
+ scrolled = used;
+
+ if (hasFolding(curwin->w_cursor.lnum, &top, &bot)) {
+ --top;
+ ++bot;
+ } else {
+ top = curwin->w_cursor.lnum - 1;
+ bot = curwin->w_cursor.lnum + 1;
+ }
+ new_topline = top + 1;
+
+ /* count filler lines of the cursor window as context */
+ i = diff_check_fill(curwin, curwin->w_cursor.lnum);
+ used += i;
+ extra += i;
+
+ /*
+ * Check if the lines from "top" to "bot" fit in the window. If they do,
+ * set new_topline and advance "top" and "bot" to include more lines.
+ */
+ while (top > 0) {
+ if (hasFolding(top, &top, NULL))
+ /* count one logical line for a sequence of folded lines */
+ i = 1;
+ else
+ i = plines(top);
+ used += i;
+ if (extra + i <= off && bot < curbuf->b_ml.ml_line_count) {
+ if (hasFolding(bot, NULL, &bot))
+ /* count one logical line for a sequence of folded lines */
+ ++used;
+ else
+ used += plines(bot);
+ }
+ if (used > curwin->w_height)
+ break;
+ if (top < curwin->w_topline)
+ scrolled += i;
+
+ /*
+ * If scrolling is needed, scroll at least 'sj' lines.
+ */
+ if ((new_topline >= curwin->w_topline || scrolled > min_scroll)
+ && extra >= off)
+ break;
+
+ extra += i;
+ new_topline = top;
+ --top;
+ ++bot;
+ }
+
+ /*
+ * If we don't have enough space, put cursor in the middle.
+ * This makes sure we get the same position when using "k" and "j"
+ * in a small window.
+ */
+ if (used > curwin->w_height)
+ scroll_cursor_halfway(FALSE);
+ else {
+ /*
+ * If "always" is FALSE, only adjust topline to a lower value, higher
+ * value may happen with wrapping lines
+ */
+ if (new_topline < curwin->w_topline || always)
+ curwin->w_topline = new_topline;
+ if (curwin->w_topline > curwin->w_cursor.lnum)
+ curwin->w_topline = curwin->w_cursor.lnum;
+ curwin->w_topfill = diff_check_fill(curwin, curwin->w_topline);
+ if (curwin->w_topfill > 0 && extra > off) {
+ curwin->w_topfill -= extra - off;
+ if (curwin->w_topfill < 0)
+ curwin->w_topfill = 0;
+ }
+ check_topfill(curwin, FALSE);
+ if (curwin->w_topline != old_topline
+ || curwin->w_topfill != old_topfill
+ )
+ curwin->w_valid &=
+ ~(VALID_WROW|VALID_CROW|VALID_BOTLINE|VALID_BOTLINE_AP);
+ curwin->w_valid |= VALID_TOPLINE;
+ }
+}
+
+/*
+ * Set w_empty_rows and w_filler_rows for window "wp", having used up "used"
+ * screen lines for text lines.
+ */
+void set_empty_rows(wp, used)
+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 (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)
+ wp->w_empty_rows -= wp->w_filler_rows;
+ else {
+ wp->w_filler_rows = wp->w_empty_rows;
+ wp->w_empty_rows = 0;
+ }
+ }
+ }
+}
+
+/*
+ * Recompute topline to put the cursor at the bottom of the window.
+ * Scroll at least "min_scroll" lines.
+ * If "set_topbot" is TRUE, set topline and botline first (for "zb").
+ * This is messy stuff!!!
+ */
+void scroll_cursor_bot(min_scroll, set_topbot)
+int min_scroll;
+int set_topbot;
+{
+ int used;
+ int scrolled = 0;
+ int extra = 0;
+ int i;
+ linenr_T line_count;
+ linenr_T old_topline = curwin->w_topline;
+ lineoff_T loff;
+ lineoff_T boff;
+ int old_topfill = curwin->w_topfill;
+ int fill_below_window;
+ linenr_T old_botline = curwin->w_botline;
+ linenr_T old_valid = curwin->w_valid;
+ int old_empty_rows = curwin->w_empty_rows;
+ linenr_T cln; /* Cursor Line Number */
+
+ cln = curwin->w_cursor.lnum;
+ if (set_topbot) {
+ used = 0;
+ curwin->w_botline = cln + 1;
+ loff.fill = 0;
+ for (curwin->w_topline = curwin->w_botline;
+ curwin->w_topline > 1;
+ curwin->w_topline = loff.lnum) {
+ loff.lnum = curwin->w_topline;
+ topline_back(&loff);
+ if (loff.height == MAXCOL || used + loff.height > curwin->w_height)
+ break;
+ used += loff.height;
+ curwin->w_topfill = loff.fill;
+ }
+ set_empty_rows(curwin, used);
+ curwin->w_valid |= VALID_BOTLINE|VALID_BOTLINE_AP;
+ if (curwin->w_topline != old_topline
+ || curwin->w_topfill != old_topfill
+ )
+ curwin->w_valid &= ~(VALID_WROW|VALID_CROW);
+ } else
+ validate_botline();
+
+ /* The lines of the cursor line itself are always used. */
+ used = plines_nofill(cln);
+
+ /* If the cursor is below botline, we will at least scroll by the height
+ * of the cursor line. Correct for empty lines, which are really part of
+ * botline. */
+ if (cln >= curwin->w_botline) {
+ scrolled = used;
+ if (cln == curwin->w_botline)
+ scrolled -= curwin->w_empty_rows;
+ }
+
+ /*
+ * Stop counting lines to scroll when
+ * - hitting start of the file
+ * - scrolled nothing or at least 'sj' lines
+ * - at least 'so' lines below the cursor
+ * - lines between botline and cursor have been counted
+ */
+ if (!hasFolding(curwin->w_cursor.lnum, &loff.lnum, &boff.lnum)) {
+ loff.lnum = cln;
+ boff.lnum = cln;
+ }
+ loff.fill = 0;
+ boff.fill = 0;
+ fill_below_window = diff_check_fill(curwin, curwin->w_botline)
+ - curwin->w_filler_rows;
+
+ while (loff.lnum > 1) {
+ /* Stop when scrolled nothing or at least "min_scroll", found "extra"
+ * context for 'scrolloff' and counted all lines below the window. */
+ if ((((scrolled <= 0 || scrolled >= min_scroll)
+ && extra >= (
+ mouse_dragging > 0 ? mouse_dragging - 1 :
+ p_so))
+ || boff.lnum + 1 > curbuf->b_ml.ml_line_count)
+ && loff.lnum <= curwin->w_botline
+ && (loff.lnum < curwin->w_botline
+ || loff.fill >= fill_below_window)
+ )
+ break;
+
+ /* Add one line above */
+ topline_back(&loff);
+ if (loff.height == MAXCOL)
+ used = MAXCOL;
+ else
+ used += loff.height;
+ if (used > curwin->w_height)
+ break;
+ if (loff.lnum >= curwin->w_botline
+ && (loff.lnum > curwin->w_botline
+ || loff.fill <= fill_below_window)
+ ) {
+ /* Count screen lines that are below the window. */
+ scrolled += loff.height;
+ if (loff.lnum == curwin->w_botline
+ && boff.fill == 0
+ )
+ scrolled -= curwin->w_empty_rows;
+ }
+
+ if (boff.lnum < curbuf->b_ml.ml_line_count) {
+ /* Add one line below */
+ botline_forw(&boff);
+ used += boff.height;
+ if (used > curwin->w_height)
+ break;
+ if (extra < (
+ mouse_dragging > 0 ? mouse_dragging - 1 :
+ p_so) || scrolled < min_scroll) {
+ extra += boff.height;
+ if (boff.lnum >= curwin->w_botline
+ || (boff.lnum + 1 == curwin->w_botline
+ && boff.fill > curwin->w_filler_rows)
+ ) {
+ /* Count screen lines that are below the window. */
+ scrolled += boff.height;
+ if (boff.lnum == curwin->w_botline
+ && boff.fill == 0
+ )
+ scrolled -= curwin->w_empty_rows;
+ }
+ }
+ }
+ }
+
+ /* 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)
+ line_count = used;
+ /* scroll minimal number of lines */
+ else {
+ line_count = 0;
+ boff.fill = curwin->w_topfill;
+ boff.lnum = curwin->w_topline - 1;
+ for (i = 0; i < scrolled && boff.lnum < curwin->w_botline; ) {
+ botline_forw(&boff);
+ i += boff.height;
+ ++line_count;
+ }
+ if (i < scrolled) /* below curwin->w_botline, don't scroll */
+ line_count = 9999;
+ }
+
+ /*
+ * 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)
+ scroll_cursor_halfway(FALSE);
+ else
+ scrollup(line_count, TRUE);
+
+ /*
+ * If topline didn't change we need to restore w_botline and w_empty_rows
+ * (we changed them).
+ * If topline did change, update_screen() will set botline.
+ */
+ if (curwin->w_topline == old_topline && set_topbot) {
+ curwin->w_botline = old_botline;
+ curwin->w_empty_rows = old_empty_rows;
+ curwin->w_valid = old_valid;
+ }
+ curwin->w_valid |= VALID_TOPLINE;
+}
+
+/*
+ * Recompute topline to put the cursor halfway the window
+ * If "atend" is TRUE, also put it halfway at the end of the file.
+ */
+void scroll_cursor_halfway(atend)
+int atend;
+{
+ int above = 0;
+ linenr_T topline;
+ int topfill = 0;
+ int below = 0;
+ int used;
+ lineoff_T loff;
+ lineoff_T boff;
+
+ loff.lnum = boff.lnum = curwin->w_cursor.lnum;
+ (void)hasFolding(loff.lnum, &loff.lnum, &boff.lnum);
+ used = plines_nofill(loff.lnum);
+ loff.fill = 0;
+ boff.fill = 0;
+ topline = loff.lnum;
+ while (topline > 1) {
+ if (below <= above) { /* add a line below the cursor first */
+ if (boff.lnum < curbuf->b_ml.ml_line_count) {
+ botline_forw(&boff);
+ used += boff.height;
+ if (used > curwin->w_height)
+ break;
+ below += boff.height;
+ } else {
+ ++below; /* count a "~" line */
+ if (atend)
+ ++used;
+ }
+ }
+
+ if (below > above) { /* add a line above the cursor */
+ topline_back(&loff);
+ if (loff.height == MAXCOL)
+ used = MAXCOL;
+ else
+ used += loff.height;
+ if (used > curwin->w_height)
+ break;
+ above += loff.height;
+ topline = loff.lnum;
+ topfill = loff.fill;
+ }
+ }
+ if (!hasFolding(topline, &curwin->w_topline, NULL))
+ curwin->w_topline = topline;
+ curwin->w_topfill = topfill;
+ check_topfill(curwin, FALSE);
+ curwin->w_valid &= ~(VALID_WROW|VALID_CROW|VALID_BOTLINE|VALID_BOTLINE_AP);
+ curwin->w_valid |= VALID_TOPLINE;
+}
+
+/*
+ * Correct the cursor position so that it is in a part of the screen at least
+ * 'so' lines from the top and bottom, if possible.
+ * If not possible, put it at the same position as scroll_cursor_halfway().
+ * When called topline must be valid!
+ */
+void cursor_correct() {
+ int above = 0; /* screen lines above topline */
+ linenr_T topline;
+ int below = 0; /* screen lines below botline */
+ linenr_T botline;
+ int above_wanted, below_wanted;
+ linenr_T cln; /* Cursor Line Number */
+ int max_off;
+
+ /*
+ * How many lines we would like to have above/below the cursor depends on
+ * whether the first/last line of the file is on screen.
+ */
+ above_wanted = p_so;
+ below_wanted = p_so;
+ if (mouse_dragging > 0) {
+ above_wanted = mouse_dragging - 1;
+ below_wanted = mouse_dragging - 1;
+ }
+ if (curwin->w_topline == 1) {
+ above_wanted = 0;
+ max_off = curwin->w_height / 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;
+ max_off = (curwin->w_height - 1) / 2;
+ if (above_wanted > max_off)
+ above_wanted = max_off;
+ }
+
+ /*
+ * If there are sufficient file-lines above and below the cursor, we can
+ * return now.
+ */
+ cln = curwin->w_cursor.lnum;
+ if (cln >= curwin->w_topline + above_wanted
+ && cln < curwin->w_botline - below_wanted
+ && !hasAnyFolding(curwin)
+ )
+ return;
+
+ /*
+ * Narrow down the area where the cursor can be put by taking lines from
+ * the top and the bottom until:
+ * - the desired context lines are found
+ * - the lines from the top is past the lines from the bottom
+ */
+ topline = curwin->w_topline;
+ botline = curwin->w_botline - 1;
+ /* count filler lines as context */
+ above = curwin->w_topfill;
+ below = curwin->w_filler_rows;
+ while ((above < above_wanted || below < below_wanted) && topline < botline) {
+ if (below < below_wanted && (below <= above || above >= above_wanted)) {
+ if (hasFolding(botline, &botline, NULL))
+ ++below;
+ else
+ below += plines(botline);
+ --botline;
+ }
+ if (above < above_wanted && (above < below || below >= below_wanted)) {
+ if (hasFolding(topline, NULL, &topline))
+ ++above;
+ else
+ above += plines_nofill(topline);
+
+ /* Count filler lines below this line as context. */
+ if (topline < botline)
+ above += diff_check_fill(curwin, topline + 1);
+ ++topline;
+ }
+ }
+ if (topline == botline || botline == 0)
+ curwin->w_cursor.lnum = topline;
+ else if (topline > botline)
+ curwin->w_cursor.lnum = botline;
+ else {
+ if (cln < topline && curwin->w_topline > 1) {
+ curwin->w_cursor.lnum = topline;
+ curwin->w_valid &=
+ ~(VALID_WROW|VALID_WCOL|VALID_CHEIGHT|VALID_CROW);
+ }
+ if (cln > botline && curwin->w_botline <= curbuf->b_ml.ml_line_count) {
+ curwin->w_cursor.lnum = botline;
+ curwin->w_valid &=
+ ~(VALID_WROW|VALID_WCOL|VALID_CHEIGHT|VALID_CROW);
+ }
+ }
+ curwin->w_valid |= VALID_TOPLINE;
+}
+
+static void get_scroll_overlap __ARGS((lineoff_T *lp, int dir));
+
+/*
+ * move screen 'count' pages up or down and update screen
+ *
+ * return FAIL for failure, OK otherwise
+ */
+int onepage(dir, count)
+int dir;
+long count;
+{
+ long n;
+ int retval = OK;
+ lineoff_T loff;
+ linenr_T old_topline = curwin->w_topline;
+
+ if (curbuf->b_ml.ml_line_count == 1) { /* nothing to do */
+ beep_flush();
+ return FAIL;
+ }
+
+ for (; count > 0; --count) {
+ validate_botline();
+ /*
+ * It's an error to move a page up when the first line is already on
+ * the screen. It's an error to move a page down when the last line
+ * is on the screen and the topline is 'scrolloff' lines from the
+ * last line.
+ */
+ if (dir == FORWARD
+ ? ((curwin->w_topline >= curbuf->b_ml.ml_line_count - p_so)
+ && curwin->w_botline > curbuf->b_ml.ml_line_count)
+ : (curwin->w_topline == 1
+ && curwin->w_topfill ==
+ diff_check_fill(curwin, curwin->w_topline)
+ )) {
+ beep_flush();
+ retval = FAIL;
+ break;
+ }
+
+ loff.fill = 0;
+ if (dir == FORWARD) {
+ if (firstwin == lastwin && p_window > 0 && p_window < Rows - 1) {
+ /* Vi compatible scrolling */
+ if (p_window <= 2)
+ ++curwin->w_topline;
+ else
+ curwin->w_topline += p_window - 2;
+ if (curwin->w_topline > curbuf->b_ml.ml_line_count)
+ curwin->w_topline = curbuf->b_ml.ml_line_count;
+ curwin->w_cursor.lnum = curwin->w_topline;
+ } else if (curwin->w_botline > curbuf->b_ml.ml_line_count) {
+ /* at end of file */
+ curwin->w_topline = curbuf->b_ml.ml_line_count;
+ curwin->w_topfill = 0;
+ curwin->w_valid &= ~(VALID_WROW|VALID_CROW);
+ } else {
+ /* For the overlap, start with the line just below the window
+ * and go upwards. */
+ loff.lnum = curwin->w_botline;
+ loff.fill = diff_check_fill(curwin, loff.lnum)
+ - curwin->w_filler_rows;
+ get_scroll_overlap(&loff, -1);
+ curwin->w_topline = loff.lnum;
+ curwin->w_topfill = loff.fill;
+ check_topfill(curwin, FALSE);
+ curwin->w_cursor.lnum = curwin->w_topline;
+ curwin->w_valid &= ~(VALID_WCOL|VALID_CHEIGHT|VALID_WROW|
+ VALID_CROW|VALID_BOTLINE|VALID_BOTLINE_AP);
+ }
+ } else { /* dir == BACKWARDS */
+ if (curwin->w_topline == 1) {
+ /* Include max number of filler lines */
+ max_topfill();
+ continue;
+ }
+ if (firstwin == lastwin && p_window > 0 && p_window < Rows - 1) {
+ /* Vi compatible scrolling (sort of) */
+ if (p_window <= 2)
+ --curwin->w_topline;
+ else
+ curwin->w_topline -= p_window - 2;
+ if (curwin->w_topline < 1)
+ curwin->w_topline = 1;
+ curwin->w_cursor.lnum = curwin->w_topline + p_window - 1;
+ if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count)
+ curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
+ continue;
+ }
+
+ /* Find the line at the top of the window that is going to be the
+ * line at the bottom of the window. Make sure this results in
+ * the same line as before doing CTRL-F. */
+ loff.lnum = curwin->w_topline - 1;
+ loff.fill = diff_check_fill(curwin, loff.lnum + 1)
+ - curwin->w_topfill;
+ get_scroll_overlap(&loff, 1);
+
+ if (loff.lnum >= curbuf->b_ml.ml_line_count) {
+ loff.lnum = curbuf->b_ml.ml_line_count;
+ loff.fill = 0;
+ } else {
+ botline_topline(&loff);
+ }
+ curwin->w_cursor.lnum = loff.lnum;
+
+ /* 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) {
+ topline_back(&loff);
+ if (loff.height == MAXCOL)
+ n = MAXCOL;
+ else
+ n += loff.height;
+ }
+ if (loff.lnum < 1) { /* at begin of file */
+ curwin->w_topline = 1;
+ max_topfill();
+ curwin->w_valid &= ~(VALID_WROW|VALID_CROW|VALID_BOTLINE);
+ } else {
+ /* Go two lines forward again. */
+ topline_botline(&loff);
+ botline_forw(&loff);
+ botline_forw(&loff);
+ botline_topline(&loff);
+ /* We're at the wrong end of a fold now. */
+ (void)hasFolding(loff.lnum, &loff.lnum, NULL);
+
+ /* Always scroll at least one line. Avoid getting stuck on
+ * very long lines. */
+ if (loff.lnum >= curwin->w_topline
+ && (loff.lnum > curwin->w_topline
+ || loff.fill >= curwin->w_topfill)
+ ) {
+ /* First try using the maximum number of filler lines. If
+ * that's not enough, backup one line. */
+ loff.fill = curwin->w_topfill;
+ if (curwin->w_topfill < diff_check_fill(curwin,
+ curwin->w_topline))
+ max_topfill();
+ if (curwin->w_topfill == loff.fill) {
+ --curwin->w_topline;
+ curwin->w_topfill = 0;
+ }
+ comp_botline(curwin);
+ curwin->w_cursor.lnum = curwin->w_botline - 1;
+ curwin->w_valid &= ~(VALID_WCOL|VALID_CHEIGHT|
+ VALID_WROW|VALID_CROW);
+ } else {
+ curwin->w_topline = loff.lnum;
+ curwin->w_topfill = loff.fill;
+ check_topfill(curwin, FALSE);
+ curwin->w_valid &= ~(VALID_WROW|VALID_CROW|VALID_BOTLINE);
+ }
+ }
+ }
+ }
+ foldAdjustCursor();
+ cursor_correct();
+ 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;
+ (void)hasFolding(curwin->w_topline, &curwin->w_topline, NULL);
+ }
+ }
+
+ redraw_later(VALID);
+ return retval;
+}
+
+/*
+ * Decide how much overlap to use for page-up or page-down scrolling.
+ * This is symmetric, so that doing both keeps the same lines displayed.
+ * Three lines are examined:
+ *
+ * before CTRL-F after CTRL-F / before CTRL-B
+ * etc. l1
+ * l1 last but one line ------------
+ * l2 last text line l2 top text line
+ * ------------- l3 second text line
+ * l3 etc.
+ */
+static void get_scroll_overlap(lp, dir)
+lineoff_T *lp;
+int dir;
+{
+ int h1, h2, h3, h4;
+ int min_height = curwin->w_height - 2;
+ lineoff_T loff0, loff1, loff2;
+
+ if (lp->fill > 0)
+ lp->height = 1;
+ else
+ lp->height = plines_nofill(lp->lnum);
+ h1 = lp->height;
+ if (h1 > min_height)
+ return; /* no overlap */
+
+ loff0 = *lp;
+ if (dir > 0)
+ botline_forw(lp);
+ else
+ topline_back(lp);
+ h2 = lp->height;
+ if (h2 == MAXCOL || h2 + h1 > min_height) {
+ *lp = loff0; /* no overlap */
+ return;
+ }
+
+ loff1 = *lp;
+ if (dir > 0)
+ botline_forw(lp);
+ else
+ topline_back(lp);
+ h3 = lp->height;
+ if (h3 == MAXCOL || h3 + h2 > min_height) {
+ *lp = loff0; /* no overlap */
+ return;
+ }
+
+ loff2 = *lp;
+ if (dir > 0)
+ botline_forw(lp);
+ else
+ topline_back(lp);
+ h4 = lp->height;
+ if (h4 == MAXCOL || h4 + h3 + h2 > min_height || h3 + h2 + h1 > min_height)
+ *lp = loff1; /* 1 line overlap */
+ else
+ *lp = loff2; /* 2 lines overlap */
+ return;
+}
+
+/* #define KEEP_SCREEN_LINE */
+/*
+ * Scroll 'scroll' lines up or down.
+ */
+void halfpage(flag, Prenum)
+int flag;
+linenr_T Prenum;
+{
+ long scrolled = 0;
+ int i;
+ int n;
+ int room;
+
+ if (Prenum)
+ curwin->w_p_scr = (Prenum > curwin->w_height) ?
+ curwin->w_height : Prenum;
+ n = (curwin->w_p_scr <= curwin->w_height) ?
+ curwin->w_p_scr : curwin->w_height;
+
+ validate_botline();
+ room = curwin->w_empty_rows;
+ room += curwin->w_filler_rows;
+ if (flag) {
+ /*
+ * scroll the text up
+ */
+ 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;
+ } else {
+ i = plines_nofill(curwin->w_topline);
+ n -= i;
+ if (n < 0 && scrolled > 0)
+ break;
+ (void)hasFolding(curwin->w_topline, NULL, &curwin->w_topline);
+ ++curwin->w_topline;
+ curwin->w_topfill = diff_check_fill(curwin, curwin->w_topline);
+
+#ifndef KEEP_SCREEN_LINE
+ if (curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count) {
+ ++curwin->w_cursor.lnum;
+ curwin->w_valid &=
+ ~(VALID_VIRTCOL|VALID_CHEIGHT|VALID_WCOL);
+ }
+#endif
+ }
+ curwin->w_valid &= ~(VALID_CROW|VALID_WROW);
+ scrolled += i;
+
+ /*
+ * Correct w_botline for changed w_topline.
+ * Won't work when there are filler lines.
+ */
+ if (curwin->w_p_diff)
+ curwin->w_valid &= ~(VALID_BOTLINE|VALID_BOTLINE_AP);
+ else {
+ room += i;
+ do {
+ i = plines(curwin->w_botline);
+ if (i > room)
+ break;
+ (void)hasFolding(curwin->w_botline, NULL,
+ &curwin->w_botline);
+ ++curwin->w_botline;
+ room -= i;
+ } while (curwin->w_botline <= curbuf->b_ml.ml_line_count);
+ }
+ }
+
+#ifndef KEEP_SCREEN_LINE
+ /*
+ * When hit bottom of the file: move cursor down.
+ */
+ if (n > 0) {
+ if (hasAnyFolding(curwin)) {
+ while (--n >= 0
+ && curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count) {
+ (void)hasFolding(curwin->w_cursor.lnum, NULL,
+ &curwin->w_cursor.lnum);
+ ++curwin->w_cursor.lnum;
+ }
+ } else
+ curwin->w_cursor.lnum += n;
+ check_cursor_lnum();
+ }
+#else
+ /* try to put the cursor in the same screen line */
+ while ((curwin->w_cursor.lnum < curwin->w_topline || scrolled > 0)
+ && curwin->w_cursor.lnum < curwin->w_botline - 1) {
+ scrolled -= plines(curwin->w_cursor.lnum);
+ if (scrolled < 0 && curwin->w_cursor.lnum >= curwin->w_topline)
+ break;
+ (void)hasFolding(curwin->w_cursor.lnum, NULL,
+ &curwin->w_cursor.lnum);
+ ++curwin->w_cursor.lnum;
+ }
+#endif
+ } else {
+ /*
+ * scroll the text down
+ */
+ 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;
+ } else {
+ i = plines_nofill(curwin->w_topline - 1);
+ n -= i;
+ if (n < 0 && scrolled > 0)
+ break;
+ --curwin->w_topline;
+ (void)hasFolding(curwin->w_topline, &curwin->w_topline, NULL);
+ curwin->w_topfill = 0;
+ }
+ curwin->w_valid &= ~(VALID_CROW|VALID_WROW|
+ VALID_BOTLINE|VALID_BOTLINE_AP);
+ scrolled += i;
+#ifndef KEEP_SCREEN_LINE
+ if (curwin->w_cursor.lnum > 1) {
+ --curwin->w_cursor.lnum;
+ curwin->w_valid &= ~(VALID_VIRTCOL|VALID_CHEIGHT|VALID_WCOL);
+ }
+#endif
+ }
+#ifndef KEEP_SCREEN_LINE
+ /*
+ * When hit top of the file: move cursor up.
+ */
+ if (n > 0) {
+ if (curwin->w_cursor.lnum <= (linenr_T)n)
+ curwin->w_cursor.lnum = 1;
+ else if (hasAnyFolding(curwin)) {
+ while (--n >= 0 && curwin->w_cursor.lnum > 1) {
+ --curwin->w_cursor.lnum;
+ (void)hasFolding(curwin->w_cursor.lnum,
+ &curwin->w_cursor.lnum, NULL);
+ }
+ } else
+ curwin->w_cursor.lnum -= n;
+ }
+#else
+ /* try to put the cursor in the same screen line */
+ scrolled += n; /* move cursor when topline is 1 */
+ while (curwin->w_cursor.lnum > curwin->w_topline
+ && (scrolled > 0 || curwin->w_cursor.lnum >= curwin->w_botline)) {
+ scrolled -= plines(curwin->w_cursor.lnum - 1);
+ if (scrolled < 0 && curwin->w_cursor.lnum < curwin->w_botline)
+ break;
+ --curwin->w_cursor.lnum;
+ foldAdjustCursor();
+ }
+#endif
+ }
+ /* Move cursor to first line of closed fold. */
+ foldAdjustCursor();
+ check_topfill(curwin, !flag);
+ cursor_correct();
+ beginline(BL_SOL | BL_FIX);
+ redraw_later(VALID);
+}
+
+void do_check_cursorbind() {
+ linenr_T line = curwin->w_cursor.lnum;
+ colnr_T col = curwin->w_cursor.col;
+ colnr_T coladd = curwin->w_cursor.coladd;
+ colnr_T curswant = curwin->w_curswant;
+ int set_curswant = curwin->w_set_curswant;
+ win_T *old_curwin = curwin;
+ buf_T *old_curbuf = curbuf;
+ int restart_edit_save;
+ int old_VIsual_select = VIsual_select;
+ int old_VIsual_active = VIsual_active;
+
+ /*
+ * loop through the cursorbound windows
+ */
+ VIsual_select = VIsual_active = 0;
+ for (curwin = firstwin; curwin; curwin = curwin->w_next) {
+ 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
+ curwin->w_cursor.lnum = line;
+ curwin->w_cursor.col = col;
+ curwin->w_cursor.coladd = coladd;
+ curwin->w_curswant = curswant;
+ curwin->w_set_curswant = set_curswant;
+
+ /* Make sure the cursor is in a valid position. Temporarily set
+ * "restart_edit" to allow the cursor to be beyond the EOL. */
+ restart_edit_save = restart_edit;
+ restart_edit = TRUE;
+ check_cursor();
+ restart_edit = restart_edit_save;
+ /* Correct cursor for multi-byte character. */
+ if (has_mbyte)
+ mb_adjust_cursor();
+ redraw_later(VALID);
+
+ /* Only scroll when 'scrollbind' hasn't done this. */
+ if (!curwin->w_p_scb)
+ update_topline();
+ curwin->w_redr_status = TRUE;
+ }
+ }
+
+ /*
+ * reset current-window
+ */
+ VIsual_select = old_VIsual_select;
+ VIsual_active = old_VIsual_active;
+ curwin = old_curwin;
+ curbuf = old_curbuf;
+}
+
diff --git a/src/normal.c b/src/normal.c
new file mode 100644
index 0000000000..c141f468b2
--- /dev/null
+++ b/src/normal.c
@@ -0,0 +1,7585 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * 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.
+ */
+/*
+ * 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 "vim.h"
+
+/*
+ * The Visual area is remembered for reselection.
+ */
+static int resel_VIsual_mode = NUL; /* 'v', 'V', or Ctrl-V */
+static linenr_T resel_VIsual_line_count; /* number of lines */
+static colnr_T resel_VIsual_vcol; /* nr of cols or end col */
+static int VIsual_mode_orig = NUL; /* type of Visual mode, that user entered */
+
+static int restart_VIsual_select = 0;
+
+static void set_vcount_ca __ARGS((cmdarg_T *cap, int *set_prevcount));
+static int
+nv_compare __ARGS((const void *s1, const void *s2));
+static int find_command __ARGS((int cmdchar));
+static void op_colon __ARGS((oparg_T *oap));
+static void op_function __ARGS((oparg_T *oap));
+static void find_start_of_word __ARGS((pos_T *));
+static void find_end_of_word __ARGS((pos_T *));
+static int get_mouse_class __ARGS((char_u *p));
+static void prep_redo_cmd __ARGS((cmdarg_T *cap));
+static void prep_redo __ARGS((int regname, long, int, int, int, int, int));
+static int checkclearop __ARGS((oparg_T *oap));
+static int checkclearopq __ARGS((oparg_T *oap));
+static void clearop __ARGS((oparg_T *oap));
+static void clearopbeep __ARGS((oparg_T *oap));
+static void unshift_special __ARGS((cmdarg_T *cap));
+static void del_from_showcmd __ARGS((int));
+
+/*
+ * 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.
+ */
+static void nv_ignore __ARGS((cmdarg_T *cap));
+static void nv_nop __ARGS((cmdarg_T *cap));
+static void nv_error __ARGS((cmdarg_T *cap));
+static void nv_help __ARGS((cmdarg_T *cap));
+static void nv_addsub __ARGS((cmdarg_T *cap));
+static void nv_page __ARGS((cmdarg_T *cap));
+static void nv_gd __ARGS((oparg_T *oap, int nchar, int thisblock));
+static int nv_screengo __ARGS((oparg_T *oap, int dir, long dist));
+static void nv_mousescroll __ARGS((cmdarg_T *cap));
+static void nv_mouse __ARGS((cmdarg_T *cap));
+static void nv_scroll_line __ARGS((cmdarg_T *cap));
+static void nv_zet __ARGS((cmdarg_T *cap));
+static void nv_exmode __ARGS((cmdarg_T *cap));
+static void nv_colon __ARGS((cmdarg_T *cap));
+static void nv_ctrlg __ARGS((cmdarg_T *cap));
+static void nv_ctrlh __ARGS((cmdarg_T *cap));
+static void nv_clear __ARGS((cmdarg_T *cap));
+static void nv_ctrlo __ARGS((cmdarg_T *cap));
+static void nv_hat __ARGS((cmdarg_T *cap));
+static void nv_Zet __ARGS((cmdarg_T *cap));
+static void nv_ident __ARGS((cmdarg_T *cap));
+static void nv_tagpop __ARGS((cmdarg_T *cap));
+static void nv_scroll __ARGS((cmdarg_T *cap));
+static void nv_right __ARGS((cmdarg_T *cap));
+static void nv_left __ARGS((cmdarg_T *cap));
+static void nv_up __ARGS((cmdarg_T *cap));
+static void nv_down __ARGS((cmdarg_T *cap));
+static void nv_gotofile __ARGS((cmdarg_T *cap));
+static void nv_end __ARGS((cmdarg_T *cap));
+static void nv_dollar __ARGS((cmdarg_T *cap));
+static void nv_search __ARGS((cmdarg_T *cap));
+static void nv_next __ARGS((cmdarg_T *cap));
+static void normal_search __ARGS((cmdarg_T *cap, int dir, char_u *pat, int opt));
+static void nv_csearch __ARGS((cmdarg_T *cap));
+static void nv_brackets __ARGS((cmdarg_T *cap));
+static void nv_percent __ARGS((cmdarg_T *cap));
+static void nv_brace __ARGS((cmdarg_T *cap));
+static void nv_mark __ARGS((cmdarg_T *cap));
+static void nv_findpar __ARGS((cmdarg_T *cap));
+static void nv_undo __ARGS((cmdarg_T *cap));
+static void nv_kundo __ARGS((cmdarg_T *cap));
+static void nv_Replace __ARGS((cmdarg_T *cap));
+static void nv_vreplace __ARGS((cmdarg_T *cap));
+static void v_swap_corners __ARGS((int cmdchar));
+static void nv_replace __ARGS((cmdarg_T *cap));
+static void n_swapchar __ARGS((cmdarg_T *cap));
+static void nv_cursormark __ARGS((cmdarg_T *cap, int flag, pos_T *pos));
+static void v_visop __ARGS((cmdarg_T *cap));
+static void nv_subst __ARGS((cmdarg_T *cap));
+static void nv_abbrev __ARGS((cmdarg_T *cap));
+static void nv_optrans __ARGS((cmdarg_T *cap));
+static void nv_gomark __ARGS((cmdarg_T *cap));
+static void nv_pcmark __ARGS((cmdarg_T *cap));
+static void nv_regname __ARGS((cmdarg_T *cap));
+static void nv_visual __ARGS((cmdarg_T *cap));
+static void n_start_visual_mode __ARGS((int c));
+static void nv_window __ARGS((cmdarg_T *cap));
+static void nv_suspend __ARGS((cmdarg_T *cap));
+static void nv_g_cmd __ARGS((cmdarg_T *cap));
+static void n_opencmd __ARGS((cmdarg_T *cap));
+static void nv_dot __ARGS((cmdarg_T *cap));
+static void nv_redo __ARGS((cmdarg_T *cap));
+static void nv_Undo __ARGS((cmdarg_T *cap));
+static void nv_tilde __ARGS((cmdarg_T *cap));
+static void nv_operator __ARGS((cmdarg_T *cap));
+static void set_op_var __ARGS((int optype));
+static void nv_lineop __ARGS((cmdarg_T *cap));
+static void nv_home __ARGS((cmdarg_T *cap));
+static void nv_pipe __ARGS((cmdarg_T *cap));
+static void nv_bck_word __ARGS((cmdarg_T *cap));
+static void nv_wordcmd __ARGS((cmdarg_T *cap));
+static void nv_beginline __ARGS((cmdarg_T *cap));
+static void adjust_cursor __ARGS((oparg_T *oap));
+static void adjust_for_sel __ARGS((cmdarg_T *cap));
+static int unadjust_for_sel __ARGS((void));
+static void nv_select __ARGS((cmdarg_T *cap));
+static void nv_goto __ARGS((cmdarg_T *cap));
+static void nv_normal __ARGS((cmdarg_T *cap));
+static void nv_esc __ARGS((cmdarg_T *oap));
+static void nv_edit __ARGS((cmdarg_T *cap));
+static void invoke_edit __ARGS((cmdarg_T *cap, int repl, int cmd, int startln));
+static void nv_object __ARGS((cmdarg_T *cap));
+static void nv_record __ARGS((cmdarg_T *cap));
+static void nv_at __ARGS((cmdarg_T *cap));
+static void nv_halfpage __ARGS((cmdarg_T *cap));
+static void nv_join __ARGS((cmdarg_T *cap));
+static void nv_put __ARGS((cmdarg_T *cap));
+static void nv_open __ARGS((cmdarg_T *cap));
+static void nv_cursorhold __ARGS((cmdarg_T *cap));
+
+static char *e_noident = N_("E349: No identifier under cursor");
+
+/*
+ * Function to be called for a Normal or Visual mode command.
+ * The argument is a cmdarg_T.
+ */
+typedef void (*nv_func_T) __ARGS ((cmdarg_T *cap));
+
+/* Values for cmd_flags. */
+#define NV_NCH 0x01 /* may need to get a second char */
+#define NV_NCH_NOP (0x02|NV_NCH) /* get second char when no operator pending */
+#define NV_NCH_ALW (0x04|NV_NCH) /* always get a second char */
+#define NV_LANG 0x08 /* second char needs language adjustment */
+
+#define NV_SS 0x10 /* may start selection */
+#define NV_SSS 0x20 /* may start selection with shift modifier */
+#define NV_STS 0x40 /* may stop selection without shift modif. */
+#define NV_RL 0x80 /* 'rightleft' modifies command */
+#define NV_KEEPREG 0x100 /* don't clear regname */
+#define NV_NCW 0x200 /* not allowed in command-line window */
+
+/*
+ * Generally speaking, every Normal mode command should either clear any
+ * pending operator (with *clearop*()), or set the motion type variable
+ * oap->motion_type.
+ *
+ * When a cursor motion command is made, it is marked as being a character or
+ * line oriented motion. Then, if an operator is in effect, the operation
+ * becomes character or line oriented accordingly.
+ */
+
+/*
+ * This table contains one entry for every Normal or Visual mode command.
+ * The order doesn't matter, init_normal_cmds() will create a sorted index.
+ * It is faster when all keys from zero to '~' are present.
+ */
+static const struct nv_cmd {
+ int cmd_char; /* (first) command character */
+ nv_func_T cmd_func; /* function for this command */
+ short_u cmd_flags; /* NV_ flags */
+ 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_CURSORHOLD, nv_cursorhold, NV_KEEPREG, 0},
+};
+
+/* Number of commands in nv_cmds[]. */
+#define NV_CMDS_SIZE (sizeof(nv_cmds) / sizeof(struct nv_cmd))
+
+/* Sorted index of commands in nv_cmds[]. */
+static short nv_cmd_idx[NV_CMDS_SIZE];
+
+/* The highest index for which
+ * nv_cmds[idx].cmd_char == nv_cmd_idx[nv_cmds[idx].cmd_char] */
+static int nv_max_linear;
+
+/*
+ * Compare functions for qsort() below, that checks the command character
+ * through the index in nv_cmd_idx[].
+ */
+static int nv_compare(s1, s2)
+const void *s1;
+const void *s2;
+{
+ int c1, c2;
+
+ /* The commands are sorted on absolute value. */
+ c1 = nv_cmds[*(const short *)s1].cmd_char;
+ c2 = nv_cmds[*(const short *)s2].cmd_char;
+ if (c1 < 0)
+ c1 = -c1;
+ if (c2 < 0)
+ c2 = -c2;
+ return c1 - c2;
+}
+
+/*
+ * Initialize the nv_cmd_idx[] table.
+ */
+void init_normal_cmds() {
+ int i;
+
+ /* Fill the index table with a one to one relation. */
+ for (i = 0; i < (int)NV_CMDS_SIZE; ++i)
+ nv_cmd_idx[i] = i;
+
+ /* Sort the commands by the command character. */
+ qsort((void *)&nv_cmd_idx, (size_t)NV_CMDS_SIZE, sizeof(short), nv_compare);
+
+ /* Find the first entry that can't be indexed by the command character. */
+ for (i = 0; i < (int)NV_CMDS_SIZE; ++i)
+ if (i != nv_cmds[nv_cmd_idx[i]].cmd_char)
+ break;
+ nv_max_linear = i - 1;
+}
+
+/*
+ * Search for a command in the commands table.
+ * Returns -1 for invalid command.
+ */
+static int find_command(cmdchar)
+int cmdchar;
+{
+ int i;
+ int idx;
+ int top, bot;
+ int c;
+
+ /* A multi-byte character is never a command. */
+ if (cmdchar >= 0x100)
+ return -1;
+
+ /* We use the absolute value of the character. Special keys have a
+ * negative value, but are sorted on their absolute value. */
+ if (cmdchar < 0)
+ cmdchar = -cmdchar;
+
+ /* If the character is in the first part: The character is the index into
+ * nv_cmd_idx[]. */
+ if (cmdchar <= nv_max_linear)
+ return nv_cmd_idx[cmdchar];
+
+ /* Perform a binary search. */
+ bot = nv_max_linear + 1;
+ top = NV_CMDS_SIZE - 1;
+ idx = -1;
+ while (bot <= top) {
+ i = (top + bot) / 2;
+ c = nv_cmds[nv_cmd_idx[i]].cmd_char;
+ if (c < 0)
+ c = -c;
+ if (cmdchar == c) {
+ idx = nv_cmd_idx[i];
+ break;
+ }
+ if (cmdchar > c)
+ bot = i + 1;
+ else
+ top = i - 1;
+ }
+ return idx;
+}
+
+/*
+ * Execute a command in Normal mode.
+ */
+void normal_cmd(oap, toplevel)
+oparg_T *oap;
+int toplevel UNUSED; /* TRUE when called from main() */
+{
+ cmdarg_T ca; /* command arguments */
+ int c;
+ int ctrl_w = FALSE; /* got CTRL-W command */
+ int old_col = curwin->w_curswant;
+ int need_flushbuf; /* need to call out_flush() */
+ pos_T old_pos; /* cursor position before command */
+ int mapped_len;
+ static int old_mapped_len = 0;
+ int idx;
+ int set_prevcount = FALSE;
+
+ vim_memset(&ca, 0, sizeof(ca)); /* also resets ca.retval */
+ ca.oap = oap;
+
+ /* Use a count remembered from before entering an operator. After typing
+ * "3d" we return from normal_cmd() and come back here, the "3" is
+ * remembered in "opcount". */
+ ca.opcount = opcount;
+
+
+ /*
+ * If there is an operator pending, then the command we take this time
+ * will terminate it. Finish_op tells us to finish the operation before
+ * returning this time (unless the operation was cancelled).
+ */
+#ifdef CURSOR_SHAPE
+ c = finish_op;
+#endif
+ finish_op = (oap->op_type != OP_NOP);
+#ifdef CURSOR_SHAPE
+ if (finish_op != c) {
+ ui_cursor_shape(); /* may show different cursor shape */
+ }
+#endif
+
+ /* When not finishing an operator and no register name typed, reset the
+ * count. */
+ if (!finish_op && !oap->regname) {
+ ca.opcount = 0;
+ set_prevcount = TRUE;
+ }
+
+ /* Restore counts from before receiving K_CURSORHOLD. This means after
+ * typing "3", handling K_CURSORHOLD and then typing "2" we get "32", not
+ * "3 * 2". */
+ if (oap->prev_opcount > 0 || oap->prev_count0 > 0) {
+ ca.opcount = oap->prev_opcount;
+ ca.count0 = oap->prev_count0;
+ oap->prev_opcount = 0;
+ oap->prev_count0 = 0;
+ }
+
+ mapped_len = typebuf_maplen();
+
+ State = NORMAL_BUSY;
+#ifdef USE_ON_FLY_SCROLL
+ dont_scroll = FALSE; /* allow scrolling here */
+#endif
+
+ /* Set v:count here, when called from main() and not a stuffed
+ * command, so that v:count can be used in an expression mapping
+ * when there is no count. */
+ if (toplevel && stuff_empty())
+ set_vcount_ca(&ca, &set_prevcount);
+
+ /*
+ * Get the command character from the user.
+ */
+ c = safe_vgetc();
+ LANGMAP_ADJUST(c, TRUE);
+
+ /*
+ * If a mapping was started in Visual or Select mode, remember the length
+ * of the mapping. This is used below to not return to Insert mode for as
+ * long as the mapping is being executed.
+ */
+ if (restart_edit == 0)
+ old_mapped_len = 0;
+ else if (old_mapped_len
+ || (VIsual_active && mapped_len == 0 && typebuf_maplen() > 0))
+ old_mapped_len = typebuf_maplen();
+
+ if (c == NUL)
+ c = K_ZERO;
+
+ /*
+ * In Select mode, typed text replaces the selection.
+ */
+ if (VIsual_active
+ && VIsual_select
+ && (vim_isprintc(c) || c == NL || c == CAR || c == K_KENTER)) {
+ /* Fake a "c"hange command. When "restart_edit" is set (e.g., because
+ * 'insertmode' is set) fake a "d"elete command, Insert mode will
+ * restart automatically.
+ * Insert the typed character in the typeahead buffer, so that it can
+ * be mapped in Insert mode. Required for ":lmap" to work. */
+ ins_char_typebuf(c);
+ if (restart_edit != 0)
+ c = 'd';
+ else
+ c = 'c';
+ msg_nowait = TRUE; /* don't delay going to insert mode */
+ old_mapped_len = 0; /* do go to Insert mode */
+ }
+
+ need_flushbuf = add_to_showcmd(c);
+
+getcount:
+ if (!(VIsual_active && VIsual_select)) {
+ /*
+ * Handle a count before a command and compute ca.count0.
+ * Note that '0' is a command and not the start of a count, but it's
+ * part of a count after other digits.
+ */
+ while ( (c >= '1' && c <= '9')
+ || (ca.count0 != 0 &&
+ (c == K_DEL || c == K_KDEL || c == '0'))) {
+ if (c == K_DEL || c == K_KDEL) {
+ ca.count0 /= 10;
+ del_from_showcmd(4); /* delete the digit and ~@% */
+ } else
+ ca.count0 = ca.count0 * 10 + (c - '0');
+ if (ca.count0 < 0) /* got too large! */
+ ca.count0 = 999999999L;
+ /* Set v:count here, when called from main() and not a stuffed
+ * command, so that v:count can be used in an expression mapping
+ * right after the count. */
+ if (toplevel && stuff_empty())
+ set_vcount_ca(&ca, &set_prevcount);
+ if (ctrl_w) {
+ ++no_mapping;
+ ++allow_keys; /* no mapping for nchar, but keys */
+ }
+ ++no_zero_mapping; /* don't map zero here */
+ c = plain_vgetc();
+ LANGMAP_ADJUST(c, TRUE);
+ --no_zero_mapping;
+ if (ctrl_w) {
+ --no_mapping;
+ --allow_keys;
+ }
+ need_flushbuf |= add_to_showcmd(c);
+ }
+
+ /*
+ * If we got CTRL-W there may be a/another count
+ */
+ if (c == Ctrl_W && !ctrl_w && oap->op_type == OP_NOP) {
+ ctrl_w = TRUE;
+ ca.opcount = ca.count0; /* remember first count */
+ ca.count0 = 0;
+ ++no_mapping;
+ ++allow_keys; /* no mapping for nchar, but keys */
+ c = plain_vgetc(); /* get next character */
+ LANGMAP_ADJUST(c, TRUE);
+ --no_mapping;
+ --allow_keys;
+ need_flushbuf |= add_to_showcmd(c);
+ goto getcount; /* jump back */
+ }
+ }
+
+ if (c == K_CURSORHOLD) {
+ /* Save the count values so that ca.opcount and ca.count0 are exactly
+ * the same when coming back here after handling K_CURSORHOLD. */
+ oap->prev_opcount = ca.opcount;
+ oap->prev_count0 = ca.count0;
+ } else if (ca.opcount != 0) {
+ /*
+ * If we're in the middle of an operator (including after entering a
+ * yank buffer with '"') AND we had a count before the operator, then
+ * that count overrides the current value of ca.count0.
+ * What this means effectively, is that commands like "3dw" get turned
+ * into "d3w" which makes things fall into place pretty neatly.
+ * If you give a count before AND after the operator, they are
+ * multiplied.
+ */
+ if (ca.count0)
+ ca.count0 *= ca.opcount;
+ else
+ ca.count0 = ca.opcount;
+ }
+
+ /*
+ * Always remember the count. It will be set to zero (on the next call,
+ * above) when there is no pending operator.
+ * When called from main(), save the count for use by the "count" built-in
+ * variable.
+ */
+ ca.opcount = ca.count0;
+ ca.count1 = (ca.count0 == 0 ? 1 : ca.count0);
+
+ /*
+ * Only set v:count when called from main() and not a stuffed command.
+ */
+ if (toplevel && stuff_empty())
+ set_vcount(ca.count0, ca.count1, set_prevcount);
+
+ /*
+ * Find the command character in the table of commands.
+ * For CTRL-W we already got nchar when looking for a count.
+ */
+ if (ctrl_w) {
+ ca.nchar = c;
+ ca.cmdchar = Ctrl_W;
+ } else
+ ca.cmdchar = c;
+ idx = find_command(ca.cmdchar);
+ if (idx < 0) {
+ /* Not a known command: beep. */
+ clearopbeep(oap);
+ goto normal_end;
+ }
+
+ if (text_locked() && (nv_cmds[idx].cmd_flags & NV_NCW)) {
+ /* This command is not allowed while editing a ccmdline: beep. */
+ clearopbeep(oap);
+ text_locked_msg();
+ goto normal_end;
+ }
+ if ((nv_cmds[idx].cmd_flags & NV_NCW) && curbuf_locked())
+ goto normal_end;
+
+ /*
+ * In Visual/Select mode, a few keys are handled in a special way.
+ */
+ if (VIsual_active) {
+ /* when 'keymodel' contains "stopsel" may stop Select/Visual mode */
+ if (km_stopsel
+ && (nv_cmds[idx].cmd_flags & NV_STS)
+ && !(mod_mask & MOD_MASK_SHIFT)) {
+ end_visual_mode();
+ redraw_curbuf_later(INVERTED);
+ }
+
+ /* Keys that work different when 'keymodel' contains "startsel" */
+ if (km_startsel) {
+ if (nv_cmds[idx].cmd_flags & NV_SS) {
+ unshift_special(&ca);
+ idx = find_command(ca.cmdchar);
+ if (idx < 0) {
+ /* Just in case */
+ clearopbeep(oap);
+ goto normal_end;
+ }
+ } else if ((nv_cmds[idx].cmd_flags & NV_SSS)
+ && (mod_mask & MOD_MASK_SHIFT)) {
+ mod_mask &= ~MOD_MASK_SHIFT;
+ }
+ }
+ }
+
+ if (curwin->w_p_rl && KeyTyped && !KeyStuffed
+ && (nv_cmds[idx].cmd_flags & NV_RL)) {
+ /* Invert horizontal movements and operations. Only when typed by the
+ * user directly, not when the result of a mapping or "x" translated
+ * to "dl". */
+ switch (ca.cmdchar) {
+ case 'l': ca.cmdchar = 'h'; break;
+ case K_RIGHT: ca.cmdchar = K_LEFT; break;
+ case K_S_RIGHT: ca.cmdchar = K_S_LEFT; break;
+ case K_C_RIGHT: ca.cmdchar = K_C_LEFT; break;
+ case 'h': ca.cmdchar = 'l'; break;
+ case K_LEFT: ca.cmdchar = K_RIGHT; break;
+ case K_S_LEFT: ca.cmdchar = K_S_RIGHT; break;
+ case K_C_LEFT: ca.cmdchar = K_C_RIGHT; break;
+ case '>': ca.cmdchar = '<'; break;
+ case '<': ca.cmdchar = '>'; break;
+ }
+ idx = find_command(ca.cmdchar);
+ }
+
+ /*
+ * Get an additional character if we need one.
+ */
+ if ((nv_cmds[idx].cmd_flags & NV_NCH)
+ && (((nv_cmds[idx].cmd_flags & NV_NCH_NOP) == NV_NCH_NOP
+ && oap->op_type == OP_NOP)
+ || (nv_cmds[idx].cmd_flags & NV_NCH_ALW) == NV_NCH_ALW
+ || (ca.cmdchar == 'q'
+ && oap->op_type == OP_NOP
+ && !Recording
+ && !Exec_reg)
+ || ((ca.cmdchar == 'a' || ca.cmdchar == 'i')
+ && (oap->op_type != OP_NOP
+ || VIsual_active
+ )))) {
+ int *cp;
+ int repl = FALSE; /* get character for replace mode */
+ int lit = FALSE; /* get extra character literally */
+ int langmap_active = FALSE; /* using :lmap mappings */
+ int lang; /* getting a text character */
+#ifdef USE_IM_CONTROL
+ int save_smd; /* saved value of p_smd */
+#endif
+
+ ++no_mapping;
+ ++allow_keys; /* no mapping for nchar, but allow key codes */
+ /* Don't generate a CursorHold event here, most commands can't handle
+ * it, e.g., nv_replace(), nv_csearch(). */
+ did_cursorhold = TRUE;
+ if (ca.cmdchar == 'g') {
+ /*
+ * For 'g' get the next character now, so that we can check for
+ * "gr", "g'" and "g`".
+ */
+ ca.nchar = plain_vgetc();
+ LANGMAP_ADJUST(ca.nchar, TRUE);
+ need_flushbuf |= add_to_showcmd(ca.nchar);
+ if (ca.nchar == 'r' || ca.nchar == '\'' || ca.nchar == '`'
+ || ca.nchar == Ctrl_BSL) {
+ cp = &ca.extra_char; /* need to get a third character */
+ if (ca.nchar != 'r')
+ lit = TRUE; /* get it literally */
+ else
+ repl = TRUE; /* get it in replace mode */
+ } else
+ cp = NULL; /* no third character needed */
+ } else {
+ if (ca.cmdchar == 'r') /* get it in replace mode */
+ repl = TRUE;
+ cp = &ca.nchar;
+ }
+ lang = (repl || (nv_cmds[idx].cmd_flags & NV_LANG));
+
+ /*
+ * Get a second or third character.
+ */
+ if (cp != NULL) {
+#ifdef CURSOR_SHAPE
+ if (repl) {
+ State = REPLACE; /* pretend Replace mode */
+ ui_cursor_shape(); /* show different cursor shape */
+ }
+#endif
+ if (lang && curbuf->b_p_iminsert == B_IMODE_LMAP) {
+ /* Allow mappings defined with ":lmap". */
+ --no_mapping;
+ --allow_keys;
+ if (repl)
+ State = LREPLACE;
+ else
+ State = LANGMAP;
+ langmap_active = TRUE;
+ }
+#ifdef USE_IM_CONTROL
+ save_smd = p_smd;
+ p_smd = FALSE; /* Don't let the IM code show the mode here */
+ if (lang && curbuf->b_p_iminsert == B_IMODE_IM)
+ im_set_active(TRUE);
+#endif
+
+ *cp = plain_vgetc();
+
+ if (langmap_active) {
+ /* Undo the decrement done above */
+ ++no_mapping;
+ ++allow_keys;
+ State = NORMAL_BUSY;
+ }
+#ifdef USE_IM_CONTROL
+ if (lang) {
+ if (curbuf->b_p_iminsert != B_IMODE_LMAP)
+ im_save_status(&curbuf->b_p_iminsert);
+ im_set_active(FALSE);
+ }
+ p_smd = save_smd;
+#endif
+#ifdef CURSOR_SHAPE
+ State = NORMAL_BUSY;
+#endif
+ need_flushbuf |= add_to_showcmd(*cp);
+
+ if (!lit) {
+ /* Typing CTRL-K gets a digraph. */
+ if (*cp == Ctrl_K
+ && ((nv_cmds[idx].cmd_flags & NV_LANG)
+ || cp == &ca.extra_char)
+ && vim_strchr(p_cpo, CPO_DIGRAPH) == NULL) {
+ c = get_digraph(FALSE);
+ if (c > 0) {
+ *cp = c;
+ /* Guessing how to update showcmd here... */
+ del_from_showcmd(3);
+ need_flushbuf |= add_to_showcmd(*cp);
+ }
+ }
+
+ /* adjust chars > 127, except after "tTfFr" commands */
+ LANGMAP_ADJUST(*cp, !lang);
+ /* adjust Hebrew mapped char */
+ if (p_hkmap && lang && KeyTyped)
+ *cp = hkmap(*cp);
+ /* adjust Farsi mapped char */
+ if (p_fkmap && lang && KeyTyped)
+ *cp = fkmap(*cp);
+ }
+
+ /*
+ * When the next character is CTRL-\ a following CTRL-N means the
+ * command is aborted and we go to Normal mode.
+ */
+ if (cp == &ca.extra_char
+ && ca.nchar == Ctrl_BSL
+ && (ca.extra_char == Ctrl_N || ca.extra_char == Ctrl_G)) {
+ ca.cmdchar = Ctrl_BSL;
+ ca.nchar = ca.extra_char;
+ idx = find_command(ca.cmdchar);
+ } else if ((ca.nchar == 'n' || ca.nchar == 'N') && ca.cmdchar == 'g')
+ ca.oap->op_type = get_op_type(*cp, NUL);
+ else if (*cp == Ctrl_BSL) {
+ long towait = (p_ttm >= 0 ? p_ttm : p_tm);
+
+ /* There is a busy wait here when typing "f<C-\>" and then
+ * something different from CTRL-N. Can't be avoided. */
+ while ((c = vpeekc()) <= 0 && towait > 0L) {
+ do_sleep(towait > 50L ? 50L : towait);
+ towait -= 50L;
+ }
+ if (c > 0) {
+ c = plain_vgetc();
+ if (c != Ctrl_N && c != Ctrl_G)
+ vungetc(c);
+ else {
+ ca.cmdchar = Ctrl_BSL;
+ ca.nchar = c;
+ idx = find_command(ca.cmdchar);
+ }
+ }
+ }
+
+ /* When getting a text character and the next character is a
+ * multi-byte character, it could be a composing character.
+ * However, don't wait for it to arrive. */
+ while (enc_utf8 && lang && (c = vpeekc()) > 0
+ && (c >= 0x100 || MB_BYTE2LEN(vpeekc()) > 1)) {
+ c = plain_vgetc();
+ if (!utf_iscomposing(c)) {
+ vungetc(c); /* it wasn't, put it back */
+ break;
+ } else if (ca.ncharC1 == 0)
+ ca.ncharC1 = c;
+ else
+ ca.ncharC2 = c;
+ }
+ }
+ --no_mapping;
+ --allow_keys;
+ }
+
+ /*
+ * Flush the showcmd characters onto the screen so we can see them while
+ * the command is being executed. Only do this when the shown command was
+ * actually displayed, otherwise this will slow down a lot when executing
+ * mappings.
+ */
+ if (need_flushbuf)
+ out_flush();
+ if (ca.cmdchar != K_IGNORE)
+ did_cursorhold = FALSE;
+
+ State = NORMAL;
+
+ if (ca.nchar == ESC) {
+ clearop(oap);
+ if (restart_edit == 0 && goto_im())
+ restart_edit = 'a';
+ goto normal_end;
+ }
+
+ if (ca.cmdchar != K_IGNORE) {
+ msg_didout = FALSE; /* don't scroll screen up for normal command */
+ msg_col = 0;
+ }
+
+ old_pos = curwin->w_cursor; /* remember where cursor was */
+
+ /* When 'keymodel' contains "startsel" some keys start Select/Visual
+ * mode. */
+ if (!VIsual_active && km_startsel) {
+ if (nv_cmds[idx].cmd_flags & NV_SS) {
+ start_selection();
+ unshift_special(&ca);
+ idx = find_command(ca.cmdchar);
+ } else if ((nv_cmds[idx].cmd_flags & NV_SSS)
+ && (mod_mask & MOD_MASK_SHIFT)) {
+ start_selection();
+ mod_mask &= ~MOD_MASK_SHIFT;
+ }
+ }
+
+ /*
+ * Execute the command!
+ * Call the command function found in the commands table.
+ */
+ ca.arg = nv_cmds[idx].cmd_arg;
+ (nv_cmds[idx].cmd_func)(&ca);
+
+ /*
+ * If we didn't start or finish an operator, reset oap->regname, unless we
+ * need it later.
+ */
+ if (!finish_op
+ && !oap->op_type
+ && (idx < 0 || !(nv_cmds[idx].cmd_flags & NV_KEEPREG))) {
+ clearop(oap);
+ {
+ int regname = 0;
+
+ /* Adjust the register according to 'clipboard', so that when
+ * "unnamed" is present it becomes '*' or '+' instead of '"'. */
+ set_reg_var(regname);
+ }
+ }
+
+ /* Get the length of mapped chars again after typing a count, second
+ * character or "z333<cr>". */
+ if (old_mapped_len > 0)
+ old_mapped_len = typebuf_maplen();
+
+ /*
+ * If an operation is pending, handle it...
+ */
+ do_pending_operator(&ca, old_col, FALSE);
+
+ /*
+ * Wait for a moment when a message is displayed that will be overwritten
+ * by the mode message.
+ * In Visual mode and with "^O" in Insert mode, a short message will be
+ * overwritten by the mode message. Wait a bit, until a key is hit.
+ * In Visual mode, it's more important to keep the Visual area updated
+ * than keeping a message (e.g. from a /pat search).
+ * Only do this if the command was typed, not from a mapping.
+ * Don't wait when emsg_silent is non-zero.
+ * Also wait a bit after an error message, e.g. for "^O:".
+ * Don't redraw the screen, it would remove the message.
+ */
+ if ( ((p_smd
+ && msg_silent == 0
+ && (restart_edit != 0
+ || (VIsual_active
+ && old_pos.lnum == curwin->w_cursor.lnum
+ && old_pos.col == curwin->w_cursor.col)
+ )
+ && (clear_cmdline
+ || redraw_cmdline)
+ && (msg_didout || (msg_didany && msg_scroll))
+ && !msg_nowait
+ && KeyTyped)
+ || (restart_edit != 0
+ && !VIsual_active
+ && (msg_scroll
+ || emsg_on_display)))
+ && oap->regname == 0
+ && !(ca.retval & CA_COMMAND_BUSY)
+ && stuff_empty()
+ && typebuf_typed()
+ && emsg_silent == 0
+ && !did_wait_return
+ && oap->op_type == OP_NOP) {
+ int save_State = State;
+
+ /* Draw the cursor with the right shape here */
+ if (restart_edit != 0)
+ State = INSERT;
+
+ /* If need to redraw, and there is a "keep_msg", redraw before the
+ * delay */
+ if (must_redraw && keep_msg != NULL && !emsg_on_display) {
+ char_u *kmsg;
+
+ kmsg = keep_msg;
+ keep_msg = NULL;
+ /* showmode() will clear keep_msg, but we want to use it anyway */
+ update_screen(0);
+ /* now reset it, otherwise it's put in the history again */
+ keep_msg = kmsg;
+ msg_attr(kmsg, keep_msg_attr);
+ vim_free(kmsg);
+ }
+ setcursor();
+ cursor_on();
+ out_flush();
+ if (msg_scroll || emsg_on_display)
+ ui_delay(1000L, TRUE); /* wait at least one second */
+ ui_delay(3000L, FALSE); /* wait up to three seconds */
+ State = save_State;
+
+ msg_scroll = FALSE;
+ emsg_on_display = FALSE;
+ }
+
+ /*
+ * Finish up after executing a Normal mode command.
+ */
+normal_end:
+
+ msg_nowait = FALSE;
+
+ /* Reset finish_op, in case it was set */
+#ifdef CURSOR_SHAPE
+ c = finish_op;
+#endif
+ finish_op = FALSE;
+#ifdef CURSOR_SHAPE
+ /* Redraw the cursor with another shape, if we were in Operator-pending
+ * mode or did a replace command. */
+ if (c || ca.cmdchar == 'r') {
+ ui_cursor_shape(); /* may show different cursor shape */
+ }
+#endif
+
+ if (oap->op_type == OP_NOP && oap->regname == 0
+ && ca.cmdchar != K_CURSORHOLD
+ )
+ clear_showcmd();
+
+ checkpcmark(); /* check if we moved since setting pcmark */
+ vim_free(ca.searchbuf);
+
+ if (has_mbyte)
+ mb_adjust_cursor();
+
+ if (curwin->w_p_scb && toplevel) {
+ validate_cursor(); /* may need to update w_leftcol */
+ do_check_scrollbind(TRUE);
+ }
+
+ if (curwin->w_p_crb && toplevel) {
+ validate_cursor(); /* may need to update w_leftcol */
+ do_check_cursorbind();
+ }
+
+ /*
+ * May restart edit(), if we got here with CTRL-O in Insert mode (but not
+ * if still inside a mapping that started in Visual mode).
+ * May switch from Visual to Select mode after CTRL-O command.
+ */
+ if ( oap->op_type == OP_NOP
+ && ((restart_edit != 0 && !VIsual_active && old_mapped_len == 0)
+ || restart_VIsual_select == 1)
+ && !(ca.retval & CA_COMMAND_BUSY)
+ && stuff_empty()
+ && oap->regname == 0) {
+ if (restart_VIsual_select == 1) {
+ VIsual_select = TRUE;
+ showmode();
+ restart_VIsual_select = 0;
+ }
+ if (restart_edit != 0
+ && !VIsual_active && old_mapped_len == 0
+ )
+ (void)edit(restart_edit, FALSE, 1L);
+ }
+
+ if (restart_VIsual_select == 2)
+ restart_VIsual_select = 1;
+
+ /* Save count before an operator for next time. */
+ opcount = ca.opcount;
+}
+
+/*
+ * Set v:count and v:count1 according to "cap".
+ * Set v:prevcount only when "set_prevcount" is TRUE.
+ */
+static void set_vcount_ca(cap, set_prevcount)
+cmdarg_T *cap;
+int *set_prevcount;
+{
+ long count = cap->count0;
+
+ /* multiply with cap->opcount the same way as above */
+ if (cap->opcount != 0)
+ count = cap->opcount * (count == 0 ? 1 : count);
+ set_vcount(count, count == 0 ? 1 : count, *set_prevcount);
+ *set_prevcount = FALSE; /* only set v:prevcount once */
+}
+
+/*
+ * Handle an operator after visual mode or when the movement is finished
+ */
+void do_pending_operator(cap, old_col, gui_yank)
+cmdarg_T *cap;
+int old_col;
+int gui_yank;
+{
+ oparg_T *oap = cap->oap;
+ pos_T old_cursor;
+ int empty_region_error;
+ int restart_edit_save;
+
+ /* The visual area is remembered for redo */
+ static int redo_VIsual_mode = NUL; /* 'v', 'V', or Ctrl-V */
+ static linenr_T redo_VIsual_line_count; /* number of lines */
+ static colnr_T redo_VIsual_vcol; /* number of cols or end column */
+ static long redo_VIsual_count; /* count for Visual operator */
+ int include_line_break = FALSE;
+
+ old_cursor = curwin->w_cursor;
+
+ /*
+ * If an operation is pending, handle it...
+ */
+ if ((finish_op
+ || VIsual_active
+ ) && oap->op_type != OP_NOP) {
+ oap->is_VIsual = VIsual_active;
+ if (oap->motion_force == 'V')
+ oap->motion_type = MLINE;
+ else if (oap->motion_force == 'v') {
+ /* If the motion was linewise, "inclusive" will not have been set.
+ * Use "exclusive" to be consistent. Makes "dvj" work nice. */
+ if (oap->motion_type == MLINE)
+ oap->inclusive = FALSE;
+ /* If the motion already was characterwise, toggle "inclusive" */
+ else if (oap->motion_type == MCHAR)
+ oap->inclusive = !oap->inclusive;
+ oap->motion_type = MCHAR;
+ } else if (oap->motion_force == Ctrl_V) {
+ /* Change line- or characterwise motion into Visual block mode. */
+ VIsual_active = TRUE;
+ VIsual = oap->start;
+ VIsual_mode = Ctrl_V;
+ VIsual_select = FALSE;
+ VIsual_reselect = FALSE;
+ }
+
+ /* Only redo yank when 'y' flag is in 'cpoptions'. */
+ /* 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))
+ && cap->cmdchar != 'D'
+ && oap->op_type != OP_FOLD
+ && oap->op_type != OP_FOLDOPEN
+ && oap->op_type != OP_FOLDOPENREC
+ && oap->op_type != OP_FOLDCLOSE
+ && oap->op_type != OP_FOLDCLOSEREC
+ && oap->op_type != OP_FOLDDEL
+ && oap->op_type != OP_FOLDDELREC
+ ) {
+ 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);
+ if (cap->cmdchar == '/' || cap->cmdchar == '?') { /* was a search */
+ /*
+ * If 'cpoptions' does not contain 'r', insert the search
+ * pattern to really repeat the same command.
+ */
+ 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)
+ ResetRedobuff();
+ else {
+ AppendToRedobuffLit(repeat_cmdline, -1);
+ AppendToRedobuff(NL_STR);
+ vim_free(repeat_cmdline);
+ repeat_cmdline = NULL;
+ }
+ }
+ }
+
+ if (redo_VIsual_busy) {
+ /* Redo of an operation on a Visual area. Use the same size from
+ * redo_VIsual_line_count and redo_VIsual_vcol. */
+ oap->start = curwin->w_cursor;
+ curwin->w_cursor.lnum += redo_VIsual_line_count - 1;
+ if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count)
+ curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
+ VIsual_mode = redo_VIsual_mode;
+ if (redo_VIsual_vcol == MAXCOL || VIsual_mode == 'v') {
+ if (VIsual_mode == 'v') {
+ if (redo_VIsual_line_count <= 1) {
+ validate_virtcol();
+ curwin->w_curswant =
+ curwin->w_virtcol + redo_VIsual_vcol - 1;
+ } else
+ curwin->w_curswant = redo_VIsual_vcol;
+ } else {
+ curwin->w_curswant = MAXCOL;
+ }
+ coladvance(curwin->w_curswant);
+ }
+ cap->count0 = redo_VIsual_count;
+ if (redo_VIsual_count != 0)
+ cap->count1 = redo_VIsual_count;
+ else
+ cap->count1 = 1;
+ } else if (VIsual_active) {
+ if (!gui_yank) {
+ /* Save the current VIsual area for '< and '> marks, and "gv" */
+ curbuf->b_visual.vi_start = VIsual;
+ curbuf->b_visual.vi_end = curwin->w_cursor;
+ curbuf->b_visual.vi_mode = VIsual_mode;
+ if (VIsual_mode_orig != NUL) {
+ curbuf->b_visual.vi_mode = VIsual_mode_orig;
+ VIsual_mode_orig = NUL;
+ }
+ curbuf->b_visual.vi_curswant = curwin->w_curswant;
+ curbuf->b_visual_mode_eval = VIsual_mode;
+ }
+
+ /* In Select mode, a linewise selection is operated upon like a
+ * characterwise selection. */
+ if (VIsual_select && VIsual_mode == 'V') {
+ if (lt(VIsual, curwin->w_cursor)) {
+ VIsual.col = 0;
+ curwin->w_cursor.col =
+ (colnr_T)STRLEN(ml_get(curwin->w_cursor.lnum));
+ } else {
+ curwin->w_cursor.col = 0;
+ VIsual.col = (colnr_T)STRLEN(ml_get(VIsual.lnum));
+ }
+ VIsual_mode = 'v';
+ }
+ /* If 'selection' is "exclusive", backup one character for
+ * charwise selections. */
+ else if (VIsual_mode == 'v') {
+ include_line_break =
+ unadjust_for_sel();
+ }
+
+ oap->start = VIsual;
+ if (VIsual_mode == 'V')
+ oap->start.col = 0;
+ }
+
+ /*
+ * Set oap->start to the first position of the operated text, oap->end
+ * to the end of the operated text. w_cursor is equal to oap->start.
+ */
+ if (lt(oap->start, curwin->w_cursor)) {
+ /* Include folded lines completely. */
+ if (!VIsual_active) {
+ if (hasFolding(oap->start.lnum, &oap->start.lnum, NULL))
+ oap->start.col = 0;
+ if (hasFolding(curwin->w_cursor.lnum, NULL,
+ &curwin->w_cursor.lnum))
+ curwin->w_cursor.col = (colnr_T)STRLEN(ml_get_curline());
+ }
+ oap->end = curwin->w_cursor;
+ curwin->w_cursor = oap->start;
+
+ /* w_virtcol may have been updated; if the cursor goes back to its
+ * previous position w_virtcol becomes invalid and isn't updated
+ * automatically. */
+ curwin->w_valid &= ~VALID_VIRTCOL;
+ } else {
+ /* Include folded lines completely. */
+ if (!VIsual_active && oap->motion_type == MLINE) {
+ if (hasFolding(curwin->w_cursor.lnum, &curwin->w_cursor.lnum,
+ NULL))
+ curwin->w_cursor.col = 0;
+ if (hasFolding(oap->start.lnum, NULL, &oap->start.lnum))
+ oap->start.col = (colnr_T)STRLEN(ml_get(oap->start.lnum));
+ }
+ oap->end = oap->start;
+ oap->start = curwin->w_cursor;
+ }
+
+ oap->line_count = oap->end.lnum - oap->start.lnum + 1;
+
+ /* Set "virtual_op" before resetting VIsual_active. */
+ virtual_op = virtual_active();
+
+ if (VIsual_active || redo_VIsual_busy) {
+ if (VIsual_mode == Ctrl_V) { /* block mode */
+ colnr_T start, end;
+
+ oap->block_mode = TRUE;
+
+ getvvcol(curwin, &(oap->start),
+ &oap->start_vcol, NULL, &oap->end_vcol);
+ if (!redo_VIsual_busy) {
+ getvvcol(curwin, &(oap->end), &start, NULL, &end);
+
+ if (start < oap->start_vcol)
+ oap->start_vcol = start;
+ if (end > oap->end_vcol) {
+ if (*p_sel == 'e' && start >= 1
+ && start - 1 >= oap->end_vcol)
+ oap->end_vcol = start - 1;
+ else
+ oap->end_vcol = end;
+ }
+ }
+
+ /* if '$' was used, get oap->end_vcol from longest line */
+ if (curwin->w_curswant == MAXCOL) {
+ curwin->w_cursor.col = MAXCOL;
+ oap->end_vcol = 0;
+ for (curwin->w_cursor.lnum = oap->start.lnum;
+ curwin->w_cursor.lnum <= oap->end.lnum;
+ ++curwin->w_cursor.lnum) {
+ getvvcol(curwin, &curwin->w_cursor, NULL, NULL, &end);
+ if (end > oap->end_vcol)
+ oap->end_vcol = end;
+ }
+ } else if (redo_VIsual_busy)
+ oap->end_vcol = oap->start_vcol + redo_VIsual_vcol - 1;
+ /*
+ * Correct oap->end.col and oap->start.col to be the
+ * upper-left and lower-right corner of the block area.
+ *
+ * (Actually, this does convert column positions into character
+ * positions)
+ */
+ curwin->w_cursor.lnum = oap->end.lnum;
+ coladvance(oap->end_vcol);
+ oap->end = curwin->w_cursor;
+
+ curwin->w_cursor = oap->start;
+ coladvance(oap->start_vcol);
+ oap->start = curwin->w_cursor;
+ }
+
+ if (!redo_VIsual_busy && !gui_yank) {
+ /*
+ * Prepare to reselect and redo Visual: this is based on the
+ * size of the Visual text
+ */
+ resel_VIsual_mode = VIsual_mode;
+ if (curwin->w_curswant == MAXCOL)
+ resel_VIsual_vcol = MAXCOL;
+ else {
+ if (VIsual_mode != Ctrl_V)
+ getvvcol(curwin, &(oap->end),
+ NULL, NULL, &oap->end_vcol);
+ if (VIsual_mode == Ctrl_V || oap->line_count <= 1) {
+ if (VIsual_mode != Ctrl_V)
+ getvvcol(curwin, &(oap->start),
+ &oap->start_vcol, NULL, NULL);
+ resel_VIsual_vcol = oap->end_vcol - oap->start_vcol + 1;
+ } else
+ resel_VIsual_vcol = oap->end_vcol;
+ }
+ resel_VIsual_line_count = oap->line_count;
+ }
+
+ /* can't redo yank (unless 'y' is in 'cpoptions') and ":" */
+ if ((vim_strchr(p_cpo, CPO_YANK) != NULL || oap->op_type != OP_YANK)
+ && oap->op_type != OP_COLON
+ && oap->op_type != OP_FOLD
+ && oap->op_type != OP_FOLDOPEN
+ && oap->op_type != OP_FOLDOPENREC
+ && oap->op_type != OP_FOLDCLOSE
+ && oap->op_type != OP_FOLDCLOSEREC
+ && oap->op_type != OP_FOLDDEL
+ && oap->op_type != OP_FOLDDELREC
+ && oap->motion_force == NUL
+ ) {
+ /* 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'))
+ 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);
+ if (!redo_VIsual_busy) {
+ redo_VIsual_mode = resel_VIsual_mode;
+ redo_VIsual_vcol = resel_VIsual_vcol;
+ redo_VIsual_line_count = resel_VIsual_line_count;
+ redo_VIsual_count = cap->count0;
+ }
+ }
+
+ /*
+ * oap->inclusive defaults to TRUE.
+ * If oap->end is on a NUL (empty line) oap->inclusive becomes
+ * FALSE. This makes "d}P" and "v}dP" work the same.
+ */
+ if (oap->motion_force == NUL || oap->motion_type == MLINE)
+ oap->inclusive = TRUE;
+ if (VIsual_mode == 'V')
+ oap->motion_type = MLINE;
+ else {
+ oap->motion_type = MCHAR;
+ if (VIsual_mode != Ctrl_V && *ml_get_pos(&(oap->end)) == NUL
+ && (include_line_break || !virtual_op)
+ ) {
+ oap->inclusive = FALSE;
+ /* Try to include the newline, unless it's an operator
+ * that works on lines only. */
+ if (*p_sel != 'o' && !op_on_lines(oap->op_type)) {
+ if (oap->end.lnum < curbuf->b_ml.ml_line_count) {
+ ++oap->end.lnum;
+ oap->end.col = 0;
+ oap->end.coladd = 0;
+ ++oap->line_count;
+ } else {
+ /* Cannot move below the last line, make the op
+ * inclusive to tell the operation to include the
+ * line break. */
+ oap->inclusive = TRUE;
+ }
+ }
+ }
+ }
+
+ redo_VIsual_busy = FALSE;
+
+ /*
+ * Switch Visual off now, so screen updating does
+ * not show inverted text when the screen is redrawn.
+ * With OP_YANK and sometimes with OP_COLON and OP_FILTER there is
+ * no screen redraw, so it is done here to remove the inverted
+ * part.
+ */
+ if (!gui_yank) {
+ VIsual_active = FALSE;
+ setmouse();
+ mouse_dragging = 0;
+ if (mode_displayed)
+ clear_cmdline = TRUE; /* unshow visual mode later */
+ else
+ clear_showcmd();
+ if ((oap->op_type == OP_YANK
+ || oap->op_type == OP_COLON
+ || oap->op_type == OP_FUNCTION
+ || oap->op_type == OP_FILTER)
+ && oap->motion_force == NUL)
+ redraw_curbuf_later(INVERTED);
+ }
+ }
+
+ /* Include the trailing byte of a multi-byte char. */
+ if (has_mbyte && oap->inclusive) {
+ int l;
+
+ l = (*mb_ptr2len)(ml_get_pos(&oap->end));
+ if (l > 1)
+ oap->end.col += l - 1;
+ }
+ curwin->w_set_curswant = TRUE;
+
+ /*
+ * oap->empty is set when start and end are the same. The inclusive
+ * flag affects this too, unless yanking and the end is on a NUL.
+ */
+ oap->empty = (oap->motion_type == MCHAR
+ && (!oap->inclusive
+ || (oap->op_type == OP_YANK
+ && gchar_pos(&oap->end) == NUL))
+ && equalpos(oap->start, oap->end)
+ && !(virtual_op && oap->start.coladd != oap->end.coladd)
+ );
+ /*
+ * For delete, change and yank, it's an error to operate on an
+ * empty region, when 'E' included in 'cpoptions' (Vi compatible).
+ */
+ empty_region_error = (oap->empty
+ && vim_strchr(p_cpo, CPO_EMPTYREGION) != NULL);
+
+ /* Force a redraw when operating on an empty Visual region, when
+ * 'modifiable is off or creating a fold. */
+ if (oap->is_VIsual && (oap->empty || !curbuf->b_p_ma
+ || oap->op_type == OP_FOLD
+ ))
+ redraw_curbuf_later(INVERTED);
+
+ /*
+ * If the end of an operator is in column one while oap->motion_type
+ * is MCHAR and oap->inclusive is FALSE, we put op_end after the last
+ * character in the previous line. If op_start is on or before the
+ * first non-blank in the line, the operator becomes linewise
+ * (strange, but that's the way vi does it).
+ */
+ if ( oap->motion_type == MCHAR
+ && oap->inclusive == FALSE
+ && !(cap->retval & CA_NO_ADJ_OP_END)
+ && oap->end.col == 0
+ && (!oap->is_VIsual || *p_sel == 'o')
+ && !oap->block_mode
+ && oap->line_count > 1) {
+ oap->end_adjusted = TRUE; /* remember that we did this */
+ --oap->line_count;
+ --oap->end.lnum;
+ if (inindent(0))
+ oap->motion_type = MLINE;
+ else {
+ oap->end.col = (colnr_T)STRLEN(ml_get(oap->end.lnum));
+ if (oap->end.col) {
+ --oap->end.col;
+ oap->inclusive = TRUE;
+ }
+ }
+ } else
+ oap->end_adjusted = FALSE;
+
+ switch (oap->op_type) {
+ case OP_LSHIFT:
+ case OP_RSHIFT:
+ op_shift(oap, TRUE,
+ oap->is_VIsual ? (int)cap->count1 :
+ 1);
+ auto_format(FALSE, TRUE);
+ break;
+
+ case OP_JOIN_NS:
+ case OP_JOIN:
+ if (oap->line_count < 2)
+ oap->line_count = 2;
+ if (curwin->w_cursor.lnum + oap->line_count - 1 >
+ curbuf->b_ml.ml_line_count)
+ beep_flush();
+ else {
+ (void)do_join(oap->line_count, oap->op_type == OP_JOIN, TRUE, TRUE);
+ auto_format(FALSE, TRUE);
+ }
+ break;
+
+ case OP_DELETE:
+ VIsual_reselect = FALSE; /* don't reselect now */
+ if (empty_region_error) {
+ vim_beep();
+ CancelRedo();
+ } else {
+ (void)op_delete(oap);
+ if (oap->motion_type == MLINE && has_format_option(FO_AUTO))
+ u_save_cursor(); /* cursor line wasn't saved yet */
+ auto_format(FALSE, TRUE);
+ }
+ break;
+
+ case OP_YANK:
+ if (empty_region_error) {
+ if (!gui_yank) {
+ vim_beep();
+ CancelRedo();
+ }
+ } else
+ (void)op_yank(oap, FALSE, !gui_yank);
+ check_cursor_col();
+ break;
+
+ case OP_CHANGE:
+ VIsual_reselect = FALSE; /* don't reselect now */
+ if (empty_region_error) {
+ vim_beep();
+ CancelRedo();
+ } else {
+ /* This is a new edit command, not a restart. Need to
+ * remember it to make 'insertmode' work with mappings for
+ * Visual mode. But do this only once and not when typed and
+ * 'insertmode' isn't set. */
+ if (p_im || !KeyTyped)
+ restart_edit_save = restart_edit;
+ else
+ restart_edit_save = 0;
+ restart_edit = 0;
+ /* Reset finish_op now, don't want it set inside edit(). */
+ finish_op = FALSE;
+ if (op_change(oap)) /* will call edit() */
+ cap->retval |= CA_COMMAND_BUSY;
+ if (restart_edit == 0)
+ restart_edit = restart_edit_save;
+ }
+ 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 */
+
+ case OP_INDENT:
+ case OP_COLON:
+
+ /*
+ * If 'equalprg' is empty, do the indenting internally.
+ */
+ if (oap->op_type == OP_INDENT && *get_equalprg() == NUL) {
+ if (curbuf->b_p_lisp) {
+ op_reindent(oap, get_lisp_indent);
+ break;
+ }
+ op_reindent(oap,
+ *curbuf->b_p_inde != NUL ? get_expr_indent :
+ get_c_indent);
+ break;
+ }
+
+ op_colon(oap);
+ break;
+
+ case OP_TILDE:
+ case OP_UPPER:
+ case OP_LOWER:
+ case OP_ROT13:
+ if (empty_region_error) {
+ vim_beep();
+ CancelRedo();
+ } else
+ op_tilde(oap);
+ check_cursor_col();
+ 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 */
+ break;
+
+ case OP_FORMAT2:
+ op_format(oap, TRUE); /* use internal function */
+ break;
+
+ case OP_FUNCTION:
+ op_function(oap); /* call 'operatorfunc' */
+ break;
+
+ case OP_INSERT:
+ case OP_APPEND:
+ VIsual_reselect = FALSE; /* don't reselect now */
+ if (empty_region_error) {
+ vim_beep();
+ CancelRedo();
+ } else {
+ /* This is a new edit command, not a restart. Need to
+ * remember it to make 'insertmode' work with mappings for
+ * Visual mode. But do this only once. */
+ restart_edit_save = restart_edit;
+ restart_edit = 0;
+
+ op_insert(oap, cap->count1);
+
+ /* TODO: when inserting in several lines, should format all
+ * the lines. */
+ auto_format(FALSE, TRUE);
+
+ if (restart_edit == 0)
+ restart_edit = restart_edit_save;
+ }
+ break;
+
+ case OP_REPLACE:
+ VIsual_reselect = FALSE; /* don't reselect now */
+ if (empty_region_error) {
+ vim_beep();
+ CancelRedo();
+ } else
+ op_replace(oap, cap->nchar);
+ break;
+
+ case OP_FOLD:
+ VIsual_reselect = FALSE; /* don't reselect now */
+ foldCreate(oap->start.lnum, oap->end.lnum);
+ break;
+
+ case OP_FOLDOPEN:
+ case OP_FOLDOPENREC:
+ case OP_FOLDCLOSE:
+ case OP_FOLDCLOSEREC:
+ VIsual_reselect = FALSE; /* don't reselect now */
+ opFoldRange(oap->start.lnum, oap->end.lnum,
+ oap->op_type == OP_FOLDOPEN
+ || oap->op_type == OP_FOLDOPENREC,
+ oap->op_type == OP_FOLDOPENREC
+ || oap->op_type == OP_FOLDCLOSEREC,
+ oap->is_VIsual);
+ break;
+
+ case OP_FOLDDEL:
+ case OP_FOLDDELREC:
+ VIsual_reselect = FALSE; /* don't reselect now */
+ deleteFold(oap->start.lnum, oap->end.lnum,
+ oap->op_type == OP_FOLDDELREC, oap->is_VIsual);
+ break;
+ default:
+ clearopbeep(oap);
+ }
+ virtual_op = MAYBE;
+ if (!gui_yank) {
+ /*
+ * if 'sol' not set, go back to old column for some commands
+ */
+ if (!p_sol && oap->motion_type == MLINE && !oap->end_adjusted
+ && (oap->op_type == OP_LSHIFT || oap->op_type == OP_RSHIFT
+ || oap->op_type == OP_DELETE))
+ coladvance(curwin->w_curswant = old_col);
+ } else {
+ curwin->w_cursor = old_cursor;
+ }
+ oap->block_mode = FALSE;
+ clearop(oap);
+ }
+}
+
+/*
+ * Handle indent and format operators and visual mode ":".
+ */
+static void op_colon(oap)
+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)
+ stuffcharReadbuff('.');
+ else
+ stuffnumReadbuff((long)oap->start.lnum);
+ if (oap->end.lnum != oap->start.lnum) {
+ stuffcharReadbuff(',');
+ if (oap->end.lnum == curwin->w_cursor.lnum)
+ stuffcharReadbuff('.');
+ else if (oap->end.lnum == curbuf->b_ml.ml_line_count)
+ stuffcharReadbuff('$');
+ else if (oap->start.lnum == curwin->w_cursor.lnum) {
+ stuffReadbuff((char_u *)".+");
+ stuffnumReadbuff((long)oap->line_count - 1);
+ } else
+ stuffnumReadbuff((long)oap->end.lnum);
+ }
+ }
+ if (oap->op_type != OP_COLON)
+ stuffReadbuff((char_u *)"!");
+ if (oap->op_type == OP_INDENT) {
+ stuffReadbuff(get_equalprg());
+ stuffReadbuff((char_u *)"\n");
+ } else if (oap->op_type == OP_FORMAT) {
+ if (*p_fp == NUL)
+ stuffReadbuff((char_u *)"fmt");
+ else
+ stuffReadbuff(p_fp);
+ stuffReadbuff((char_u *)"\n']");
+ }
+
+ /*
+ * do_cmdline() does the rest
+ */
+}
+
+/*
+ * Handle the "g@" operator: call 'operatorfunc'.
+ */
+static void op_function(oap)
+oparg_T *oap UNUSED;
+{
+ char_u *(argv[1]);
+ int save_virtual_op = virtual_op;
+
+ if (*p_opfunc == NUL)
+ EMSG(_("E774: 'operatorfunc' is empty"));
+ else {
+ /* Set '[ and '] marks to text to be operated on. */
+ curbuf->b_op_start = oap->start;
+ curbuf->b_op_end = oap->end;
+ if (oap->motion_type != MLINE && !oap->inclusive)
+ /* Exclude the end position. */
+ decl(&curbuf->b_op_end);
+
+ if (oap->block_mode)
+ argv[0] = (char_u *)"block";
+ else if (oap->motion_type == MLINE)
+ argv[0] = (char_u *)"line";
+ else
+ argv[0] = (char_u *)"char";
+
+ /* Reset virtual_op so that 'virtualedit' can be changed in the
+ * function. */
+ virtual_op = MAYBE;
+
+ (void)call_func_retnr(p_opfunc, 1, argv, FALSE);
+
+ virtual_op = save_virtual_op;
+ }
+}
+
+/*
+ * Do the appropriate action for the current mouse click in the current mode.
+ * Not used for Command-line mode.
+ *
+ * Normal Mode:
+ * event modi- position visual change action
+ * fier cursor window
+ * left press - yes end yes
+ * left press C yes end yes "^]" (2)
+ * left press S yes end yes "*" (2)
+ * left drag - yes start if moved no
+ * left relse - yes start if moved no
+ * middle press - yes if not active no put register
+ * middle press - yes if active no yank and put
+ * right press - yes start or extend yes
+ * right press S yes no change yes "#" (2)
+ * right drag - yes extend no
+ * right relse - yes extend no
+ *
+ * Insert or Replace Mode:
+ * event modi- position visual change action
+ * fier cursor window
+ * left press - yes (cannot be active) yes
+ * left press C yes (cannot be active) yes "CTRL-O^]" (2)
+ * left press S yes (cannot be active) yes "CTRL-O*" (2)
+ * left drag - yes start or extend (1) no CTRL-O (1)
+ * left relse - yes start or extend (1) no CTRL-O (1)
+ * middle press - no (cannot be active) no put register
+ * right press - yes start or extend yes CTRL-O
+ * right press S yes (cannot be active) yes "CTRL-O#" (2)
+ *
+ * (1) only if mouse pointer moved since press
+ * (2) only if click is in same buffer
+ *
+ * Return TRUE if start_arrow() should be called for edit mode.
+ */
+int do_mouse(oap, c, dir, count, fixindent)
+oparg_T *oap; /* operator argument, can be NULL */
+int c; /* K_LEFTMOUSE, etc */
+int dir; /* Direction to 'put' if necessary */
+long count;
+int fixindent; /* PUT_FIXINDENT if fixing indent necessary */
+{
+ static int do_always = FALSE; /* ignore 'mouse' setting next time */
+ static int got_click = FALSE; /* got a click some time back */
+
+ int which_button; /* MOUSE_LEFT, _MIDDLE or _RIGHT */
+ int is_click; /* If FALSE it's a drag or release event */
+ int is_drag; /* If TRUE it's a drag event */
+ int jump_flags = 0; /* flags for jump_to_mouse() */
+ pos_T start_visual;
+ int moved; /* Has cursor moved? */
+ int in_status_line; /* mouse in status line */
+ static int in_tab_line = FALSE; /* mouse clicked in tab line */
+ int in_sep_line; /* mouse in vertical separator line */
+ int c1, c2;
+ pos_T save_cursor;
+ win_T *old_curwin = curwin;
+ static pos_T orig_cursor;
+ colnr_T leftcol, rightcol;
+ pos_T end_visual;
+ int diff;
+ int old_active = VIsual_active;
+ int old_mode = VIsual_mode;
+ int regname;
+
+ save_cursor = curwin->w_cursor;
+
+ /*
+ * When GUI is active, always recognize mouse events, otherwise:
+ * - Ignore mouse event in normal mode if 'mouse' doesn't include 'n'.
+ * - Ignore mouse event in visual mode if 'mouse' doesn't include 'v'.
+ * - For command line and insert mode 'mouse' is checked before calling
+ * do_mouse().
+ */
+ if (do_always)
+ do_always = FALSE;
+ else {
+ if (VIsual_active) {
+ if (!mouse_has(MOUSE_VISUAL))
+ return FALSE;
+ } else if (State == NORMAL && !mouse_has(MOUSE_NORMAL))
+ return FALSE;
+ }
+
+ for (;; ) {
+ which_button = get_mouse_button(KEY2TERMCAP1(c), &is_click, &is_drag);
+ if (is_drag) {
+ /* If the next character is the same mouse event then use that
+ * one. Speeds up dragging the status line. */
+ if (vpeekc() != NUL) {
+ int nc;
+ int save_mouse_row = mouse_row;
+ int save_mouse_col = mouse_col;
+
+ /* Need to get the character, peeking doesn't get the actual
+ * one. */
+ nc = safe_vgetc();
+ if (c == nc)
+ continue;
+ vungetc(nc);
+ mouse_row = save_mouse_row;
+ mouse_col = save_mouse_col;
+ }
+ }
+ break;
+ }
+
+
+ /*
+ * Ignore drag and release events if we didn't get a click.
+ */
+ if (is_click)
+ got_click = TRUE;
+ else {
+ if (!got_click) /* didn't get click, ignore */
+ return FALSE;
+ if (!is_drag) { /* release, reset got_click */
+ got_click = FALSE;
+ if (in_tab_line) {
+ in_tab_line = FALSE;
+ return FALSE;
+ }
+ }
+ }
+
+
+ /*
+ * CTRL right mouse button does CTRL-T
+ */
+ if (is_click && (mod_mask & MOD_MASK_CTRL) && which_button == MOUSE_RIGHT) {
+ if (State & INSERT)
+ stuffcharReadbuff(Ctrl_O);
+ if (count > 1)
+ stuffnumReadbuff(count);
+ stuffcharReadbuff(Ctrl_T);
+ got_click = FALSE; /* ignore drag&release now */
+ return FALSE;
+ }
+
+ /*
+ * CTRL only works with left mouse button
+ */
+ if ((mod_mask & MOD_MASK_CTRL) && which_button != MOUSE_LEFT)
+ return FALSE;
+
+ /*
+ * When a modifier is down, ignore drag and release events, as well as
+ * multiple clicks and the middle mouse button.
+ * Accept shift-leftmouse drags when 'mousemodel' is "popup.*".
+ */
+ if ((mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL | MOD_MASK_ALT
+ | MOD_MASK_META))
+ && (!is_click
+ || (mod_mask & MOD_MASK_MULTI_CLICK)
+ || which_button == MOUSE_MIDDLE)
+ && !((mod_mask & (MOD_MASK_SHIFT|MOD_MASK_ALT))
+ && mouse_model_popup()
+ && which_button == MOUSE_LEFT)
+ && !((mod_mask & MOD_MASK_ALT)
+ && !mouse_model_popup()
+ && which_button == MOUSE_RIGHT)
+ )
+ return FALSE;
+
+ /*
+ * If the button press was used as the movement command for an operator
+ * (eg "d<MOUSE>"), or it is the middle button that is held down, ignore
+ * drag/release events.
+ */
+ if (!is_click && which_button == MOUSE_MIDDLE)
+ return FALSE;
+
+ if (oap != NULL)
+ regname = oap->regname;
+ else
+ regname = 0;
+
+ /*
+ * Middle mouse button does a 'put' of the selected text
+ */
+ if (which_button == MOUSE_MIDDLE) {
+ if (State == NORMAL) {
+ /*
+ * If an operator was pending, we don't know what the user wanted
+ * to do. Go back to normal mode: Clear the operator and beep().
+ */
+ if (oap != NULL && oap->op_type != OP_NOP) {
+ clearopbeep(oap);
+ return FALSE;
+ }
+
+ /*
+ * If visual was active, yank the highlighted text and put it
+ * before the mouse pointer position.
+ * In Select mode replace the highlighted text with the clipboard.
+ */
+ if (VIsual_active) {
+ if (VIsual_select) {
+ stuffcharReadbuff(Ctrl_G);
+ stuffReadbuff((char_u *)"\"+p");
+ } else {
+ stuffcharReadbuff('y');
+ stuffcharReadbuff(K_MIDDLEMOUSE);
+ }
+ do_always = TRUE; /* ignore 'mouse' setting next time */
+ return FALSE;
+ }
+ /*
+ * The rest is below jump_to_mouse()
+ */
+ } else if ((State & INSERT) == 0)
+ return FALSE;
+
+ /*
+ * Middle click in insert mode doesn't move the mouse, just insert the
+ * contents of a register. '.' register is special, can't insert that
+ * with do_put().
+ * Also paste at the cursor if the current mode isn't in 'mouse' (only
+ * happens for the GUI).
+ */
+ if ((State & INSERT) || !mouse_has(MOUSE_NORMAL)) {
+ if (regname == '.')
+ insert_reg(regname, TRUE);
+ else {
+ if ((State & REPLACE_FLAG) && !yank_register_mline(regname))
+ insert_reg(regname, TRUE);
+ else {
+ do_put(regname, BACKWARD, 1L, fixindent | PUT_CURSEND);
+
+ /* Repeat it with CTRL-R CTRL-O r or CTRL-R CTRL-P r */
+ AppendCharToRedobuff(Ctrl_R);
+ AppendCharToRedobuff(fixindent ? Ctrl_P : Ctrl_O);
+ AppendCharToRedobuff(regname == 0 ? '"' : regname);
+ }
+ }
+ return FALSE;
+ }
+ }
+
+ /* When dragging or button-up stay in the same window. */
+ if (!is_click)
+ jump_flags |= MOUSE_FOCUS | MOUSE_DID_MOVE;
+
+ start_visual.lnum = 0;
+
+ /* Check for clicking in the tab page line. */
+ if (mouse_row == 0 && firstwin->w_winrow > 0) {
+ if (is_drag) {
+ if (in_tab_line) {
+ c1 = TabPageIdxs[mouse_col];
+ tabpage_move(c1 <= 0 ? 9999 : c1 - 1);
+ }
+ return FALSE;
+ }
+
+ /* click in a tab selects that tab page */
+ if (is_click
+ && cmdwin_type == 0
+ && mouse_col < Columns) {
+ in_tab_line = TRUE;
+ c1 = TabPageIdxs[mouse_col];
+ if (c1 >= 0) {
+ if ((mod_mask & MOD_MASK_MULTI_CLICK) == MOD_MASK_2CLICK) {
+ /* double click opens new page */
+ end_visual_mode();
+ tabpage_new();
+ tabpage_move(c1 == 0 ? 9999 : c1 - 1);
+ } else {
+ /* Go to specified tab page, or next one if not clicking
+ * on a label. */
+ goto_tabpage(c1);
+
+ /* It's like clicking on the status line of a window. */
+ if (curwin != old_curwin)
+ end_visual_mode();
+ }
+ } else if (c1 < 0) {
+ tabpage_T *tp;
+
+ /* Close the current or specified tab page. */
+ if (c1 == -999)
+ tp = curtab;
+ else
+ tp = find_tabpage(-c1);
+ if (tp == curtab) {
+ if (first_tabpage->tp_next != NULL)
+ tabpage_close(FALSE);
+ } else if (tp != NULL)
+ tabpage_close_other(tp, FALSE);
+ }
+ }
+ return TRUE;
+ } else if (is_drag && in_tab_line) {
+ c1 = TabPageIdxs[mouse_col];
+ tabpage_move(c1 <= 0 ? 9999 : c1 - 1);
+ return FALSE;
+ }
+
+
+ /*
+ * When 'mousemodel' is "popup" or "popup_setpos", translate mouse events:
+ * right button up -> pop-up menu
+ * shift-left button -> right button
+ * alt-left button -> alt-right button
+ */
+ if (mouse_model_popup()) {
+ if (which_button == MOUSE_RIGHT
+ && !(mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL))) {
+ /*
+ * NOTE: Ignore right button down and drag mouse events.
+ * Windows only shows the popup menu on the button up event.
+ */
+#if defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_GTK) \
+ || defined(FEAT_GUI_PHOTON) || defined(FEAT_GUI_MAC)
+ if (!is_click)
+ return FALSE;
+#endif
+#if defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_GTK) \
+ || defined(FEAT_GUI_ATHENA) || defined(FEAT_GUI_MSWIN) \
+ || defined(FEAT_GUI_MAC) || defined(FEAT_GUI_PHOTON)
+ if (gui.in_use) {
+ jump_flags = 0;
+ if (STRCMP(p_mousem, "popup_setpos") == 0) {
+ /* First set the cursor position before showing the popup
+ * menu. */
+ if (VIsual_active) {
+ pos_T m_pos;
+
+ /*
+ * set MOUSE_MAY_STOP_VIS if we are outside the
+ * selection or the current window (might have false
+ * negative here)
+ */
+ if (mouse_row < W_WINROW(curwin)
+ || mouse_row
+ > (W_WINROW(curwin) + curwin->w_height))
+ jump_flags = MOUSE_MAY_STOP_VIS;
+ else if (get_fpos_of_mouse(&m_pos) != IN_BUFFER)
+ jump_flags = MOUSE_MAY_STOP_VIS;
+ else {
+ if ((lt(curwin->w_cursor, VIsual)
+ && (lt(m_pos, curwin->w_cursor)
+ || lt(VIsual, m_pos)))
+ || (lt(VIsual, curwin->w_cursor)
+ && (lt(m_pos, VIsual)
+ || lt(curwin->w_cursor, m_pos)))) {
+ jump_flags = MOUSE_MAY_STOP_VIS;
+ } else if (VIsual_mode == Ctrl_V) {
+ getvcols(curwin, &curwin->w_cursor, &VIsual,
+ &leftcol, &rightcol);
+ getvcol(curwin, &m_pos, NULL, &m_pos.col, NULL);
+ if (m_pos.col < leftcol || m_pos.col > rightcol)
+ jump_flags = MOUSE_MAY_STOP_VIS;
+ }
+ }
+ } else
+ jump_flags = MOUSE_MAY_STOP_VIS;
+ }
+ if (jump_flags) {
+ jump_flags = jump_to_mouse(jump_flags, NULL, which_button);
+ update_curbuf(
+ VIsual_active ? INVERTED :
+ VALID);
+ setcursor();
+ out_flush(); /* Update before showing popup menu */
+ }
+ gui_show_popupmenu();
+ return (jump_flags & CURSOR_MOVED) != 0;
+ } else
+ return FALSE;
+#else
+ return FALSE;
+#endif
+ }
+ if (which_button == MOUSE_LEFT
+ && (mod_mask & (MOD_MASK_SHIFT|MOD_MASK_ALT))) {
+ which_button = MOUSE_RIGHT;
+ mod_mask &= ~MOD_MASK_SHIFT;
+ }
+ }
+
+ if ((State & (NORMAL | INSERT))
+ && !(mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL))) {
+ if (which_button == MOUSE_LEFT) {
+ if (is_click) {
+ /* stop Visual mode for a left click in a window, but not when
+ * on a status line */
+ if (VIsual_active)
+ jump_flags |= MOUSE_MAY_STOP_VIS;
+ } else if (mouse_has(MOUSE_VISUAL))
+ jump_flags |= MOUSE_MAY_VIS;
+ } else if (which_button == MOUSE_RIGHT) {
+ if (is_click && VIsual_active) {
+ /*
+ * Remember the start and end of visual before moving the
+ * cursor.
+ */
+ if (lt(curwin->w_cursor, VIsual)) {
+ start_visual = curwin->w_cursor;
+ end_visual = VIsual;
+ } else {
+ start_visual = VIsual;
+ end_visual = curwin->w_cursor;
+ }
+ }
+ jump_flags |= MOUSE_FOCUS;
+ if (mouse_has(MOUSE_VISUAL))
+ jump_flags |= MOUSE_MAY_VIS;
+ }
+ }
+
+ /*
+ * If an operator is pending, ignore all drags and releases until the
+ * next mouse click.
+ */
+ if (!is_drag && oap != NULL && oap->op_type != OP_NOP) {
+ got_click = FALSE;
+ oap->motion_type = MCHAR;
+ }
+
+ /* When releasing the button let jump_to_mouse() know. */
+ if (!is_click && !is_drag)
+ jump_flags |= MOUSE_RELEASED;
+
+ /*
+ * JUMP!
+ */
+ jump_flags = jump_to_mouse(jump_flags,
+ oap == NULL ? NULL : &(oap->inclusive), which_button);
+ moved = (jump_flags & CURSOR_MOVED);
+ in_status_line = (jump_flags & IN_STATUS_LINE);
+ in_sep_line = (jump_flags & IN_SEP_LINE);
+
+
+ /* When jumping to another window, clear a pending operator. That's a bit
+ * friendlier than beeping and not jumping to that window. */
+ if (curwin != old_curwin && oap != NULL && oap->op_type != OP_NOP)
+ clearop(oap);
+
+ if (mod_mask == 0
+ && !is_drag
+ && (jump_flags & (MOUSE_FOLD_CLOSE | MOUSE_FOLD_OPEN))
+ && which_button == MOUSE_LEFT) {
+ /* open or close a fold at this line */
+ if (jump_flags & MOUSE_FOLD_OPEN)
+ openFold(curwin->w_cursor.lnum, 1L);
+ else
+ closeFold(curwin->w_cursor.lnum, 1L);
+ /* don't move the cursor if still in the same window */
+ if (curwin == old_curwin)
+ curwin->w_cursor = save_cursor;
+ }
+
+
+ /* Set global flag that we are extending the Visual area with mouse
+ * dragging; temporarily minimize 'scrolloff'. */
+ if (VIsual_active && is_drag && p_so) {
+ /* In the very first line, allow scrolling one line */
+ if (mouse_row == 0)
+ mouse_dragging = 2;
+ else
+ mouse_dragging = 1;
+ }
+
+ /* When dragging the mouse above the window, scroll down. */
+ if (is_drag && mouse_row < 0 && !in_status_line) {
+ scroll_redraw(FALSE, 1L);
+ mouse_row = 0;
+ }
+
+ if (start_visual.lnum) { /* right click in visual mode */
+ /* When ALT is pressed make Visual mode blockwise. */
+ if (mod_mask & MOD_MASK_ALT)
+ VIsual_mode = Ctrl_V;
+
+ /*
+ * In Visual-block mode, divide the area in four, pick up the corner
+ * that is in the quarter that the cursor is in.
+ */
+ if (VIsual_mode == Ctrl_V) {
+ getvcols(curwin, &start_visual, &end_visual, &leftcol, &rightcol);
+ if (curwin->w_curswant > (leftcol + rightcol) / 2)
+ end_visual.col = leftcol;
+ else
+ end_visual.col = rightcol;
+ if (curwin->w_cursor.lnum <
+ (start_visual.lnum + end_visual.lnum) / 2)
+ end_visual.lnum = end_visual.lnum;
+ else
+ end_visual.lnum = start_visual.lnum;
+
+ /* move VIsual to the right column */
+ start_visual = curwin->w_cursor; /* save the cursor pos */
+ curwin->w_cursor = end_visual;
+ coladvance(end_visual.col);
+ VIsual = curwin->w_cursor;
+ curwin->w_cursor = start_visual; /* restore the cursor */
+ } else {
+ /*
+ * If the click is before the start of visual, change the start.
+ * If the click is after the end of visual, change the end. If
+ * the click is inside the visual, change the closest side.
+ */
+ if (lt(curwin->w_cursor, start_visual))
+ VIsual = end_visual;
+ else if (lt(end_visual, curwin->w_cursor))
+ VIsual = start_visual;
+ else {
+ /* In the same line, compare column number */
+ if (end_visual.lnum == start_visual.lnum) {
+ if (curwin->w_cursor.col - start_visual.col >
+ end_visual.col - curwin->w_cursor.col)
+ VIsual = start_visual;
+ else
+ VIsual = end_visual;
+ }
+ /* In different lines, compare line number */
+ else {
+ diff = (curwin->w_cursor.lnum - start_visual.lnum) -
+ (end_visual.lnum - curwin->w_cursor.lnum);
+
+ if (diff > 0) /* closest to end */
+ VIsual = start_visual;
+ else if (diff < 0) /* closest to start */
+ VIsual = end_visual;
+ else { /* in the middle line */
+ if (curwin->w_cursor.col <
+ (start_visual.col + end_visual.col) / 2)
+ VIsual = end_visual;
+ else
+ VIsual = start_visual;
+ }
+ }
+ }
+ }
+ }
+ /*
+ * If Visual mode started in insert mode, execute "CTRL-O"
+ */
+ else if ((State & INSERT) && VIsual_active)
+ stuffcharReadbuff(Ctrl_O);
+
+ /*
+ * Middle mouse click: Put text before cursor.
+ */
+ if (which_button == MOUSE_MIDDLE) {
+ if (yank_register_mline(regname)) {
+ if (mouse_past_bottom)
+ dir = FORWARD;
+ } else if (mouse_past_eol)
+ dir = FORWARD;
+
+ if (fixindent) {
+ c1 = (dir == BACKWARD) ? '[' : ']';
+ c2 = 'p';
+ } else {
+ c1 = (dir == FORWARD) ? 'p' : 'P';
+ c2 = NUL;
+ }
+ prep_redo(regname, count, NUL, c1, NUL, c2, NUL);
+
+ /*
+ * Remember where the paste started, so in edit() Insstart can be set
+ * to this position
+ */
+ if (restart_edit != 0)
+ where_paste_started = curwin->w_cursor;
+ do_put(regname, dir, count, fixindent | PUT_CURSEND);
+ }
+ /*
+ * Ctrl-Mouse click or double click in a quickfix window jumps to the
+ * error under the mouse pointer.
+ */
+ 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 */
+ }
+ /*
+ * Ctrl-Mouse click (or double click in a help window) jumps to the tag
+ * under the mouse pointer.
+ */
+ else if ((mod_mask & MOD_MASK_CTRL) || (curbuf->b_help
+ && (mod_mask &
+ MOD_MASK_MULTI_CLICK) ==
+ MOD_MASK_2CLICK)) {
+ if (State & INSERT)
+ stuffcharReadbuff(Ctrl_O);
+ stuffcharReadbuff(Ctrl_RSB);
+ got_click = FALSE; /* ignore drag&release now */
+ }
+ /*
+ * Shift-Mouse click searches for the next occurrence of the word under
+ * the mouse pointer
+ */
+ else if ((mod_mask & MOD_MASK_SHIFT)) {
+ if (State & INSERT
+ || (VIsual_active && VIsual_select)
+ )
+ stuffcharReadbuff(Ctrl_O);
+ if (which_button == MOUSE_LEFT)
+ stuffcharReadbuff('*');
+ else /* MOUSE_RIGHT */
+ stuffcharReadbuff('#');
+ }
+ /* Handle double clicks, unless on status line */
+ else if (in_status_line) {
+ } else if (in_sep_line) {
+ } else if ((mod_mask & MOD_MASK_MULTI_CLICK) && (State & (NORMAL | INSERT))
+ && mouse_has(MOUSE_VISUAL)) {
+ if (is_click || !VIsual_active) {
+ if (VIsual_active)
+ orig_cursor = VIsual;
+ else {
+ check_visual_highlight();
+ VIsual = curwin->w_cursor;
+ orig_cursor = VIsual;
+ VIsual_active = TRUE;
+ VIsual_reselect = TRUE;
+ /* start Select mode if 'selectmode' contains "mouse" */
+ may_start_select('o');
+ setmouse();
+ }
+ if ((mod_mask & MOD_MASK_MULTI_CLICK) == MOD_MASK_2CLICK) {
+ /* Double click with ALT pressed makes it blockwise. */
+ if (mod_mask & MOD_MASK_ALT)
+ VIsual_mode = Ctrl_V;
+ else
+ VIsual_mode = 'v';
+ } else if ((mod_mask & MOD_MASK_MULTI_CLICK) == MOD_MASK_3CLICK)
+ VIsual_mode = 'V';
+ else if ((mod_mask & MOD_MASK_MULTI_CLICK) == MOD_MASK_4CLICK)
+ VIsual_mode = Ctrl_V;
+ }
+ /*
+ * A double click selects a word or a block.
+ */
+ if ((mod_mask & MOD_MASK_MULTI_CLICK) == MOD_MASK_2CLICK) {
+ pos_T *pos = NULL;
+ int gc;
+
+ if (is_click) {
+ /* If the character under the cursor (skipping white space) is
+ * not a word character, try finding a match and select a (),
+ * {}, [], #if/#endif, etc. block. */
+ end_visual = curwin->w_cursor;
+ while (gc = gchar_pos(&end_visual), vim_iswhite(gc))
+ inc(&end_visual);
+ if (oap != NULL)
+ oap->motion_type = MCHAR;
+ if (oap != NULL
+ && VIsual_mode == 'v'
+ && !vim_iswordc(gchar_pos(&end_visual))
+ && equalpos(curwin->w_cursor, VIsual)
+ && (pos = findmatch(oap, NUL)) != NULL) {
+ curwin->w_cursor = *pos;
+ if (oap->motion_type == MLINE)
+ VIsual_mode = 'V';
+ else if (*p_sel == 'e') {
+ if (lt(curwin->w_cursor, VIsual))
+ ++VIsual.col;
+ else
+ ++curwin->w_cursor.col;
+ }
+ }
+ }
+
+ if (pos == NULL && (is_click || is_drag)) {
+ /* When not found a match or when dragging: extend to include
+ * a word. */
+ if (lt(curwin->w_cursor, orig_cursor)) {
+ find_start_of_word(&curwin->w_cursor);
+ find_end_of_word(&VIsual);
+ } else {
+ find_start_of_word(&VIsual);
+ if (*p_sel == 'e' && *ml_get_cursor() != NUL)
+ curwin->w_cursor.col +=
+ (*mb_ptr2len)(ml_get_cursor());
+ find_end_of_word(&curwin->w_cursor);
+ }
+ }
+ curwin->w_set_curswant = TRUE;
+ }
+ if (is_click)
+ redraw_curbuf_later(INVERTED); /* update the inversion */
+ } else if (VIsual_active && !old_active) {
+ if (mod_mask & MOD_MASK_ALT)
+ VIsual_mode = Ctrl_V;
+ else
+ VIsual_mode = 'v';
+ }
+
+ /* If Visual mode changed show it later. */
+ if ((!VIsual_active && old_active && mode_displayed)
+ || (VIsual_active && p_smd && msg_silent == 0
+ && (!old_active || VIsual_mode != old_mode)))
+ redraw_cmdline = TRUE;
+
+ return moved;
+}
+
+/*
+ * Move "pos" back to the start of the word it's in.
+ */
+static void find_start_of_word(pos)
+pos_T *pos;
+{
+ char_u *line;
+ int cclass;
+ int col;
+
+ line = ml_get(pos->lnum);
+ cclass = get_mouse_class(line + pos->col);
+
+ while (pos->col > 0) {
+ col = pos->col - 1;
+ col -= (*mb_head_off)(line, line + col);
+ if (get_mouse_class(line + col) != cclass)
+ break;
+ pos->col = col;
+ }
+}
+
+/*
+ * Move "pos" forward to the end of the word it's in.
+ * When 'selection' is "exclusive", the position is just after the word.
+ */
+static void find_end_of_word(pos)
+pos_T *pos;
+{
+ char_u *line;
+ int cclass;
+ int col;
+
+ line = ml_get(pos->lnum);
+ if (*p_sel == 'e' && pos->col > 0) {
+ --pos->col;
+ pos->col -= (*mb_head_off)(line, line + pos->col);
+ }
+ cclass = get_mouse_class(line + pos->col);
+ while (line[pos->col] != NUL) {
+ col = pos->col + (*mb_ptr2len)(line + pos->col);
+ if (get_mouse_class(line + col) != cclass) {
+ if (*p_sel == 'e')
+ pos->col = col;
+ break;
+ }
+ pos->col = col;
+ }
+}
+
+/*
+ * Get class of a character for selection: same class means same word.
+ * 0: blank
+ * 1: punctuation groups
+ * 2: normal word character
+ * >2: multi-byte word character.
+ */
+static int get_mouse_class(p)
+char_u *p;
+{
+ int c;
+
+ if (has_mbyte && MB_BYTE2LEN(p[0]) > 1)
+ return mb_get_class(p);
+
+ c = *p;
+ if (c == ' ' || c == '\t')
+ return 0;
+
+ if (vim_iswordc(c))
+ return 2;
+
+ /*
+ * There are a few special cases where we want certain combinations of
+ * characters to be considered as a single word. These are things like
+ * "->", "/ *", "*=", "+=", "&=", "<=", ">=", "!=" etc. Otherwise, each
+ * character is in its own class.
+ */
+ if (c != NUL && vim_strchr((char_u *)"-+*/%<>&|^!=", c) != NULL)
+ return 1;
+ return c;
+}
+
+/*
+ * Check if highlighting for visual mode is possible, give a warning message
+ * if not.
+ */
+void check_visual_highlight() {
+ static int 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().
+ */
+void end_visual_mode() {
+
+ VIsual_active = FALSE;
+ setmouse();
+ mouse_dragging = 0;
+
+ /* Save the current VIsual area for '< and '> marks, and "gv" */
+ curbuf->b_visual.vi_mode = VIsual_mode;
+ curbuf->b_visual.vi_start = VIsual;
+ curbuf->b_visual.vi_end = curwin->w_cursor;
+ curbuf->b_visual.vi_curswant = curwin->w_curswant;
+ curbuf->b_visual_mode_eval = VIsual_mode;
+ if (!virtual_active())
+ curwin->w_cursor.coladd = 0;
+
+ if (mode_displayed)
+ clear_cmdline = TRUE; /* unshow visual mode later */
+ else
+ clear_showcmd();
+
+ adjust_cursor_eol();
+}
+
+/*
+ * Reset VIsual_active and VIsual_reselect.
+ */
+void reset_VIsual_and_resel() {
+ if (VIsual_active) {
+ end_visual_mode();
+ redraw_curbuf_later(INVERTED); /* delete the inversion later */
+ }
+ VIsual_reselect = FALSE;
+}
+
+/*
+ * Reset VIsual_active and VIsual_reselect if it's set.
+ */
+void reset_VIsual() {
+ if (VIsual_active) {
+ end_visual_mode();
+ redraw_curbuf_later(INVERTED); /* delete the inversion later */
+ VIsual_reselect = FALSE;
+ }
+}
+
+/*
+ * Find the identifier under or to the right of the cursor.
+ * "find_type" can have one of three values:
+ * FIND_IDENT: find an identifier (keyword)
+ * FIND_STRING: find any non-white string
+ * FIND_IDENT + FIND_STRING: find any non-white string, identifier preferred.
+ * FIND_EVAL: find text useful for C program debugging
+ *
+ * There are three steps:
+ * 1. Search forward for the start of an identifier/string. Doesn't move if
+ * already on one.
+ * 2. Search backward for the start of this identifier/string.
+ * This doesn't match the real Vi but I like it a little better and it
+ * shouldn't bother anyone.
+ * 3. Search forward to the end of this identifier/string.
+ * When FIND_IDENT isn't defined, we backup until a blank.
+ *
+ * Returns the length of the string, or zero if no string is found.
+ * If a string is found, a pointer to the string is put in "*string". This
+ * string is not always NUL terminated.
+ */
+int find_ident_under_cursor(string, find_type)
+char_u **string;
+int find_type;
+{
+ return find_ident_at_pos(curwin, curwin->w_cursor.lnum,
+ curwin->w_cursor.col, string, find_type);
+}
+
+/*
+ * Like find_ident_under_cursor(), but for any window and any position.
+ * However: Uses 'iskeyword' from the current window!.
+ */
+int find_ident_at_pos(wp, lnum, startcol, string, find_type)
+win_T *wp;
+linenr_T lnum;
+colnr_T startcol;
+char_u **string;
+int find_type;
+{
+ char_u *ptr;
+ int col = 0; /* init to shut up GCC */
+ int i;
+ int this_class = 0;
+ int prev_class;
+ int prevcol;
+
+ /*
+ * if i == 0: try to find an identifier
+ * if i == 1: try to find any non-white string
+ */
+ ptr = ml_get_buf(wp->w_buffer, lnum, FALSE);
+ for (i = (find_type & FIND_IDENT) ? 0 : 1; i < 2; ++i) {
+ /*
+ * 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);
+ }
+ } else
+ while (ptr[col] != NUL
+ && (i == 0 ? !vim_iswordc(ptr[col]) : vim_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 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])
+ : (!vim_iswhite(ptr[col - 1])
+ && (!(find_type & FIND_IDENT)
+ || !vim_iswordc(ptr[col - 1]))))
+ ))
+ --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]))
+ 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)
+ EMSG(_("E348: No string under cursor"));
+ else
+ EMSG(_(e_noident));
+ return 0;
+ }
+ ptr += col;
+ *string = ptr;
+
+ /*
+ * 3. Find the end if the identifier/string.
+ */
+ 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 && !vim_iswhite(ptr[col])))
+ ) {
+ ++col;
+ }
+
+ return col;
+}
+
+/*
+ * Prepare for redo of a normal command.
+ */
+static void prep_redo_cmd(cap)
+cmdarg_T *cap;
+{
+ prep_redo(cap->oap->regname, cap->count0,
+ NUL, cap->cmdchar, NUL, NUL, cap->nchar);
+}
+
+/*
+ * Prepare for redo of any command.
+ * Note that only the last argument can be a multi-byte char.
+ */
+static void prep_redo(regname, num, cmd1, cmd2, cmd3, cmd4, cmd5)
+int regname;
+long num;
+int cmd1;
+int cmd2;
+int cmd3;
+int cmd4;
+int cmd5;
+{
+ ResetRedobuff();
+ if (regname != 0) { /* yank from specified buffer */
+ AppendCharToRedobuff('"');
+ AppendCharToRedobuff(regname);
+ }
+ if (num)
+ AppendNumberToRedobuff(num);
+
+ if (cmd1 != NUL)
+ AppendCharToRedobuff(cmd1);
+ if (cmd2 != NUL)
+ AppendCharToRedobuff(cmd2);
+ if (cmd3 != NUL)
+ AppendCharToRedobuff(cmd3);
+ if (cmd4 != NUL)
+ AppendCharToRedobuff(cmd4);
+ if (cmd5 != NUL)
+ AppendCharToRedobuff(cmd5);
+}
+
+/*
+ * check for operator active and clear it
+ *
+ * return TRUE if operator was active
+ */
+static int checkclearop(oap)
+oparg_T *oap;
+{
+ if (oap->op_type == OP_NOP)
+ return FALSE;
+ clearopbeep(oap);
+ return TRUE;
+}
+
+/*
+ * Check for operator or Visual active. Clear active operator.
+ *
+ * Return TRUE if operator or Visual was active.
+ */
+static int checkclearopq(oap)
+oparg_T *oap;
+{
+ if (oap->op_type == OP_NOP
+ && !VIsual_active
+ )
+ return FALSE;
+ clearopbeep(oap);
+ return TRUE;
+}
+
+static void clearop(oap)
+oparg_T *oap;
+{
+ oap->op_type = OP_NOP;
+ oap->regname = 0;
+ oap->motion_force = NUL;
+ oap->use_reg_one = FALSE;
+}
+
+static void clearopbeep(oap)
+oparg_T *oap;
+{
+ clearop(oap);
+ beep_flush();
+}
+
+/*
+ * Remove the shift modifier from a special key.
+ */
+static void unshift_special(cap)
+cmdarg_T *cap;
+{
+ switch (cap->cmdchar) {
+ case K_S_RIGHT: cap->cmdchar = K_RIGHT; break;
+ case K_S_LEFT: cap->cmdchar = K_LEFT; break;
+ case K_S_UP: cap->cmdchar = K_UP; break;
+ case K_S_DOWN: cap->cmdchar = K_DOWN; break;
+ case K_S_HOME: cap->cmdchar = K_HOME; break;
+ case K_S_END: cap->cmdchar = K_END; break;
+ }
+ cap->cmdchar = simplify_key(cap->cmdchar, &mod_mask);
+}
+
+/*
+ * Routines for displaying a partly typed command
+ */
+
+# define SHOWCMD_BUFLEN SHOWCMD_COLS + 1 + 30
+static char_u showcmd_buf[SHOWCMD_BUFLEN];
+static char_u old_showcmd_buf[SHOWCMD_BUFLEN]; /* For push_showcmd() */
+static int showcmd_is_clear = TRUE;
+static int showcmd_visual = FALSE;
+
+static void display_showcmd __ARGS((void));
+
+void clear_showcmd() {
+ if (!p_sc)
+ return;
+
+ if (VIsual_active && !char_avail()) {
+ int cursor_bot = lt(VIsual, curwin->w_cursor);
+ long lines;
+ colnr_T leftcol, rightcol;
+ linenr_T top, bot;
+
+ /* Show the size of the Visual area. */
+ if (cursor_bot) {
+ top = VIsual.lnum;
+ bot = curwin->w_cursor.lnum;
+ } else {
+ top = curwin->w_cursor.lnum;
+ bot = VIsual.lnum;
+ }
+ /* Include closed folds as a whole. */
+ hasFolding(top, &top, NULL);
+ hasFolding(bot, NULL, &bot);
+ lines = bot - top + 1;
+
+ if (VIsual_mode == Ctrl_V) {
+ char_u *saved_sbr = p_sbr;
+
+ /* Make 'sbr' empty for a moment to get the correct size. */
+ p_sbr = empty_option;
+ getvcols(curwin, &curwin->w_cursor, &VIsual, &leftcol, &rightcol);
+ p_sbr = saved_sbr;
+ sprintf((char *)showcmd_buf, "%ldx%ld", lines,
+ (long)(rightcol - leftcol + 1));
+ } else if (VIsual_mode == 'V' || VIsual.lnum != curwin->w_cursor.lnum)
+ sprintf((char *)showcmd_buf, "%ld", lines);
+ else {
+ char_u *s, *e;
+ int l;
+ int bytes = 0;
+ int chars = 0;
+
+ if (cursor_bot) {
+ s = ml_get_pos(&VIsual);
+ e = ml_get_cursor();
+ } else {
+ s = ml_get_cursor();
+ e = ml_get_pos(&VIsual);
+ }
+ while ((*p_sel != 'e') ? s <= e : s < e) {
+ l = (*mb_ptr2len)(s);
+ if (l == 0) {
+ ++bytes;
+ ++chars;
+ break; /* end of line */
+ }
+ bytes += l;
+ ++chars;
+ s += l;
+ }
+ if (bytes == chars)
+ sprintf((char *)showcmd_buf, "%d", chars);
+ else
+ sprintf((char *)showcmd_buf, "%d-%d", chars, bytes);
+ }
+ showcmd_buf[SHOWCMD_COLS] = NUL; /* truncate */
+ showcmd_visual = TRUE;
+ } else {
+ showcmd_buf[0] = NUL;
+ showcmd_visual = FALSE;
+
+ /* Don't actually display something if there is nothing to clear. */
+ if (showcmd_is_clear)
+ return;
+ }
+
+ display_showcmd();
+}
+
+/*
+ * Add 'c' to string of shown command chars.
+ * Return TRUE if output has been written (and setcursor() has been called).
+ */
+int add_to_showcmd(c)
+int c;
+{
+ char_u *p;
+ int old_len;
+ int extra_len;
+ int overflow;
+ int i;
+ static int ignore[] =
+ {
+ K_IGNORE,
+ K_LEFTMOUSE, K_LEFTDRAG, K_LEFTRELEASE,
+ K_MIDDLEMOUSE, K_MIDDLEDRAG, K_MIDDLERELEASE,
+ K_RIGHTMOUSE, K_RIGHTDRAG, K_RIGHTRELEASE,
+ K_MOUSEDOWN, K_MOUSEUP, K_MOUSELEFT, K_MOUSERIGHT,
+ K_X1MOUSE, K_X1DRAG, K_X1RELEASE, K_X2MOUSE, K_X2DRAG, K_X2RELEASE,
+ K_CURSORHOLD,
+ 0
+ };
+
+ if (!p_sc || msg_silent != 0)
+ return FALSE;
+
+ if (showcmd_visual) {
+ showcmd_buf[0] = NUL;
+ showcmd_visual = FALSE;
+ }
+
+ /* Ignore keys that are scrollbar updates and mouse clicks */
+ if (IS_SPECIAL(c))
+ for (i = 0; ignore[i] != 0; ++i)
+ if (ignore[i] == c)
+ return FALSE;
+
+ p = transchar(c);
+ if (*p == ' ')
+ STRCPY(p, "<20>");
+ old_len = (int)STRLEN(showcmd_buf);
+ extra_len = (int)STRLEN(p);
+ overflow = old_len + extra_len - SHOWCMD_COLS;
+ if (overflow > 0)
+ mch_memmove(showcmd_buf, showcmd_buf + overflow,
+ old_len - overflow + 1);
+ STRCAT(showcmd_buf, p);
+
+ if (char_avail())
+ return FALSE;
+
+ display_showcmd();
+
+ return TRUE;
+}
+
+void add_to_showcmd_c(c)
+int c;
+{
+ if (!add_to_showcmd(c))
+ setcursor();
+}
+
+/*
+ * Delete 'len' characters from the end of the shown command.
+ */
+static void del_from_showcmd(len)
+int len;
+{
+ int old_len;
+
+ if (!p_sc)
+ return;
+
+ old_len = (int)STRLEN(showcmd_buf);
+ if (len > old_len)
+ len = old_len;
+ showcmd_buf[old_len - len] = NUL;
+
+ if (!char_avail())
+ display_showcmd();
+}
+
+/*
+ * push_showcmd() and pop_showcmd() are used when waiting for the user to type
+ * something and there is a partial mapping.
+ */
+void push_showcmd() {
+ if (p_sc)
+ STRCPY(old_showcmd_buf, showcmd_buf);
+}
+
+void pop_showcmd() {
+ if (!p_sc)
+ return;
+
+ STRCPY(showcmd_buf, old_showcmd_buf);
+
+ display_showcmd();
+}
+
+static void display_showcmd() {
+ int len;
+
+ cursor_off();
+
+ len = (int)STRLEN(showcmd_buf);
+ if (len == 0)
+ showcmd_is_clear = TRUE;
+ else {
+ screen_puts(showcmd_buf, (int)Rows - 1, sc_col, 0);
+ showcmd_is_clear = FALSE;
+ }
+
+ /*
+ * 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);
+
+ setcursor(); /* put cursor back where it belongs */
+}
+
+/*
+ * When "check" is FALSE, prepare for commands that scroll the window.
+ * When "check" is TRUE, take care of scroll-binding after the window has
+ * scrolled. Called from normal_cmd() and edit().
+ */
+void do_check_scrollbind(check)
+int check;
+{
+ static win_T *old_curwin = NULL;
+ static linenr_T old_topline = 0;
+ static int old_topfill = 0;
+ static buf_T *old_buf = NULL;
+ static colnr_T old_leftcol = 0;
+
+ if (check && curwin->w_p_scb) {
+ /* If a ":syncbind" command was just used, don't scroll, only reset
+ * the values. */
+ if (did_syncbind)
+ did_syncbind = FALSE;
+ else if (curwin == old_curwin) {
+ /*
+ * Synchronize other windows, as necessary according to
+ * 'scrollbind'. Don't do this after an ":edit" command, except
+ * when 'diff' is set.
+ */
+ if ((curwin->w_buffer == old_buf
+ || curwin->w_p_diff
+ )
+ && (curwin->w_topline != old_topline
+ || curwin->w_topfill != old_topfill
+ || curwin->w_leftcol != old_leftcol)) {
+ check_scrollbind(curwin->w_topline - old_topline,
+ (long)(curwin->w_leftcol - old_leftcol));
+ }
+ } else if (vim_strchr(p_sbo, 'j')) { /* jump flag set in 'scrollopt' */
+ /*
+ * When switching between windows, make sure that the relative
+ * vertical offset is valid for the new window. The relative
+ * offset is invalid whenever another 'scrollbind' window has
+ * scrolled to a point that would force the current window to
+ * scroll past the beginning or end of its buffer. When the
+ * resync is performed, some of the other 'scrollbind' windows may
+ * need to jump so that the current window's relative position is
+ * visible on-screen.
+ */
+ check_scrollbind(curwin->w_topline - curwin->w_scbind_pos, 0L);
+ }
+ curwin->w_scbind_pos = curwin->w_topline;
+ }
+
+ old_curwin = curwin;
+ old_topline = curwin->w_topline;
+ old_topfill = curwin->w_topfill;
+ old_buf = curwin->w_buffer;
+ old_leftcol = curwin->w_leftcol;
+}
+
+/*
+ * Synchronize any windows that have "scrollbind" set, based on the
+ * number of rows by which the current window has changed
+ * (1998-11-02 16:21:01 R. Edward Ralston <eralston@computer.org>)
+ */
+void check_scrollbind(topline_diff, leftcol_diff)
+linenr_T topline_diff;
+long leftcol_diff;
+{
+ int want_ver;
+ int want_hor;
+ win_T *old_curwin = curwin;
+ buf_T *old_curbuf = curbuf;
+ int old_VIsual_select = VIsual_select;
+ int old_VIsual_active = VIsual_active;
+ colnr_T tgt_leftcol = curwin->w_leftcol;
+ long topline;
+ long y;
+
+ /*
+ * check 'scrollopt' string for vertical and horizontal scroll options
+ */
+ want_ver = (vim_strchr(p_sbo, 'v') && topline_diff != 0);
+ want_ver |= old_curwin->w_p_diff;
+ want_hor = (vim_strchr(p_sbo, 'h') && (leftcol_diff || topline_diff != 0));
+
+ /*
+ * loop through the scrollbound windows and scroll accordingly
+ */
+ VIsual_select = VIsual_active = 0;
+ for (curwin = firstwin; curwin; curwin = curwin->w_next) {
+ curbuf = curwin->w_buffer;
+ /* skip original window and windows with 'noscrollbind' */
+ if (curwin != old_curwin && curwin->w_p_scb) {
+ /*
+ * do the vertical scroll
+ */
+ if (want_ver) {
+ if (old_curwin->w_p_diff && curwin->w_p_diff) {
+ diff_set_topline(old_curwin, curwin);
+ } else {
+ curwin->w_scbind_pos += topline_diff;
+ topline = curwin->w_scbind_pos;
+ if (topline > curbuf->b_ml.ml_line_count)
+ topline = curbuf->b_ml.ml_line_count;
+ if (topline < 1)
+ topline = 1;
+
+ y = topline - curwin->w_topline;
+ if (y > 0)
+ scrollup(y, FALSE);
+ else
+ scrolldown(-y, FALSE);
+ }
+
+ redraw_later(VALID);
+ cursor_correct();
+ curwin->w_redr_status = TRUE;
+ }
+
+ /*
+ * do the horizontal scroll
+ */
+ if (want_hor && curwin->w_leftcol != tgt_leftcol) {
+ curwin->w_leftcol = tgt_leftcol;
+ leftcol_changed();
+ }
+ }
+ }
+
+ /*
+ * reset current-window
+ */
+ VIsual_select = old_VIsual_select;
+ VIsual_active = old_VIsual_active;
+ curwin = old_curwin;
+ curbuf = old_curbuf;
+}
+
+/*
+ * Command character that's ignored.
+ * Used for CTRL-Q and CTRL-S to avoid problems with terminals that use
+ * xon/xoff.
+ */
+static void nv_ignore(cap)
+cmdarg_T *cap;
+{
+ cap->retval |= CA_COMMAND_BUSY; /* don't call edit() now */
+}
+
+/*
+ * Command character that doesn't do anything, but unlike nv_ignore() does
+ * start edit(). Used for "startinsert" executed while starting up.
+ */
+static void nv_nop(cap)
+cmdarg_T *cap UNUSED;
+{
+}
+
+/*
+ * Command character doesn't exist.
+ */
+static void nv_error(cap)
+cmdarg_T *cap;
+{
+ clearopbeep(cap->oap);
+}
+
+/*
+ * <Help> and <F1> commands.
+ */
+static void nv_help(cap)
+cmdarg_T *cap;
+{
+ if (!checkclearopq(cap->oap))
+ ex_help(NULL);
+}
+
+/*
+ * CTRL-A and CTRL-X: Add or subtract from letter or number under cursor.
+ */
+static void nv_addsub(cap)
+cmdarg_T *cap;
+{
+ if (!checkclearopq(cap->oap)
+ && do_addsub((int)cap->cmdchar, cap->count1) == OK)
+ prep_redo_cmd(cap);
+}
+
+/*
+ * CTRL-F, CTRL-B, etc: Scroll page up or down.
+ */
+static void nv_page(cap)
+cmdarg_T *cap;
+{
+ if (!checkclearop(cap->oap)) {
+ if (mod_mask & MOD_MASK_CTRL) {
+ /* <C-PageUp>: tab page back; <C-PageDown>: tab page forward */
+ if (cap->arg == BACKWARD)
+ goto_tabpage(-(int)cap->count1);
+ else
+ goto_tabpage((int)cap->count0);
+ } else
+ (void)onepage(cap->arg, cap->count1);
+ }
+}
+
+/*
+ * Implementation of "gd" and "gD" command.
+ */
+static void nv_gd(oap, nchar, thisblock)
+oparg_T *oap;
+int nchar;
+int thisblock; /* 1 for "1gd" and "1gD" */
+{
+ int len;
+ char_u *ptr;
+
+ if ((len = find_ident_under_cursor(&ptr, FIND_IDENT)) == 0
+ || find_decl(ptr, len, nchar == 'd', thisblock, 0) == FAIL)
+ clearopbeep(oap);
+ else if ((fdo_flags & FDO_SEARCH) && KeyTyped && oap->op_type == OP_NOP)
+ foldOpenCursor();
+}
+
+/*
+ * Search for variable declaration of "ptr[len]".
+ * When "locally" is TRUE in the current function ("gd"), otherwise in the
+ * current file ("gD").
+ * When "thisblock" is TRUE check the {} block scope.
+ * Return FAIL when not found.
+ */
+int find_decl(ptr, len, locally, thisblock, searchflags)
+char_u *ptr;
+int len;
+int locally;
+int thisblock;
+int searchflags; /* flags passed to searchit() */
+{
+ char_u *pat;
+ pos_T old_pos;
+ pos_T par_pos;
+ pos_T found_pos;
+ int t;
+ int save_p_ws;
+ int save_p_scs;
+ int retval = OK;
+ int incll;
+
+ if ((pat = alloc(len + 7)) == NULL)
+ return FAIL;
+
+ /* Put "\V" before the pattern to avoid that the special meaning of "."
+ * and "~" causes trouble. */
+ sprintf((char *)pat, vim_iswordp(ptr) ? "\\V\\<%.*s\\>" : "\\V%.*s",
+ len, ptr);
+ old_pos = curwin->w_cursor;
+ save_p_ws = p_ws;
+ save_p_scs = p_scs;
+ p_ws = FALSE; /* don't wrap around end of file now */
+ p_scs = FALSE; /* don't switch ignorecase off now */
+
+ /*
+ * With "gD" go to line 1.
+ * With "gd" Search back for the start of the current function, then go
+ * back until a blank line. If this fails go to line 1.
+ */
+ if (!locally || !findpar(&incll, BACKWARD, 1L, '{', FALSE)) {
+ setpcmark(); /* Set in findpar() otherwise */
+ curwin->w_cursor.lnum = 1;
+ par_pos = curwin->w_cursor;
+ } else {
+ par_pos = curwin->w_cursor;
+ while (curwin->w_cursor.lnum > 1 && *skipwhite(ml_get_curline()) != NUL)
+ --curwin->w_cursor.lnum;
+ }
+ curwin->w_cursor.col = 0;
+
+ /* Search forward for the identifier, ignore comment lines. */
+ clearpos(&found_pos);
+ for (;; ) {
+ 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 = FAIL; /* match after start is failure too */
+
+ if (thisblock && t != FAIL) {
+ 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)
+ continue;
+ }
+
+ if (t == FAIL) {
+ /* If we previously found a valid position, use it. */
+ if (found_pos.lnum != 0) {
+ curwin->w_cursor = found_pos;
+ t = OK;
+ }
+ break;
+ }
+ if (get_leader_len(ml_get_curline(), NULL, FALSE, TRUE) > 0) {
+ /* Ignore this line, continue at start of next line. */
+ ++curwin->w_cursor.lnum;
+ curwin->w_cursor.col = 0;
+ continue;
+ }
+ if (!locally) /* global search: use first match found */
+ break;
+ if (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;
+ }
+
+ if (t == FAIL) {
+ retval = FAIL;
+ curwin->w_cursor = old_pos;
+ } else {
+ curwin->w_set_curswant = TRUE;
+ /* "n" searches forward now */
+ reset_search_dir();
+ }
+
+ vim_free(pat);
+ p_ws = save_p_ws;
+ p_scs = save_p_scs;
+
+ return retval;
+}
+
+/*
+ * Move 'dist' lines in direction 'dir', counting lines by *screen*
+ * lines rather than lines in the file.
+ * 'dist' must be positive.
+ *
+ * Return OK if able to move cursor, FAIL otherwise.
+ */
+static int nv_screengo(oap, dir, dist)
+oparg_T *oap;
+int dir;
+long dist;
+{
+ int linelen = linetabsize(ml_get_curline());
+ int retval = OK;
+ int atend = FALSE;
+ int n;
+ int col_off1; /* margin offset for first screen line */
+ int col_off2; /* margin offset for wrapped screen line */
+ int width1; /* text width for first screen line */
+ int width2; /* test width for wrapped screen line */
+
+ oap->motion_type = MCHAR;
+ oap->inclusive = (curwin->w_curswant == MAXCOL);
+
+ col_off1 = curwin_col_off();
+ col_off2 = col_off1 - curwin_col_off2();
+ width1 = W_WIDTH(curwin) - col_off1;
+ width2 = W_WIDTH(curwin) - col_off2;
+
+ 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_curswant == MAXCOL) {
+ atend = TRUE;
+ validate_virtcol();
+ if (width1 <= 0)
+ curwin->w_curswant = 0;
+ else {
+ curwin->w_curswant = width1 - 1;
+ if (curwin->w_virtcol > curwin->w_curswant)
+ curwin->w_curswant += ((curwin->w_virtcol
+ - curwin->w_curswant -
+ 1) / width2 + 1) * width2;
+ }
+ } else {
+ if (linelen > width1)
+ n = ((linelen - width1 - 1) / width2 + 1) * width2 + width1;
+ else
+ n = width1;
+ if (curwin->w_curswant > (colnr_T)n + 1)
+ curwin->w_curswant -= ((curwin->w_curswant - n) / width2 + 1)
+ * width2;
+ }
+
+ while (dist--) {
+ if (dir == BACKWARD) {
+ if ((long)curwin->w_curswant >= width2)
+ /* move back within line */
+ curwin->w_curswant -= width2;
+ else {
+ /* to previous line */
+ if (curwin->w_cursor.lnum == 1) {
+ retval = FAIL;
+ break;
+ }
+ --curwin->w_cursor.lnum;
+ /* Move to the start of a closed fold. Don't do that when
+ * 'foldopen' contains "all": it will open in a moment. */
+ if (!(fdo_flags & FDO_ALL))
+ (void)hasFolding(curwin->w_cursor.lnum,
+ &curwin->w_cursor.lnum, NULL);
+ linelen = linetabsize(ml_get_curline());
+ if (linelen > width1)
+ curwin->w_curswant += (((linelen - width1 - 1) / width2)
+ + 1) * width2;
+ }
+ } else { /* dir == FORWARD */
+ if (linelen > width1)
+ n = ((linelen - width1 - 1) / width2 + 1) * width2 + width1;
+ else
+ n = width1;
+ if (curwin->w_curswant + width2 < (colnr_T)n)
+ /* move forward within line */
+ curwin->w_curswant += width2;
+ else {
+ /* to next line */
+ /* Move to the end of a closed fold. */
+ (void)hasFolding(curwin->w_cursor.lnum, NULL,
+ &curwin->w_cursor.lnum);
+ if (curwin->w_cursor.lnum == curbuf->b_ml.ml_line_count) {
+ retval = FAIL;
+ break;
+ }
+ curwin->w_cursor.lnum++;
+ curwin->w_curswant %= width2;
+ linelen = linetabsize(ml_get_curline());
+ }
+ }
+ }
+ }
+
+ if (virtual_active() && atend)
+ coladvance(MAXCOL);
+ else
+ coladvance(curwin->w_curswant);
+
+ if (curwin->w_cursor.col > 0 && curwin->w_p_wrap) {
+ /*
+ * Check for landing on a character that got split at the end of the
+ * last line. We want to advance a screenline, not end up in the same
+ * screenline or move two screenlines.
+ */
+ validate_virtcol();
+ if (curwin->w_virtcol > curwin->w_curswant
+ && (curwin->w_curswant < (colnr_T)width1
+ ? (curwin->w_curswant > (colnr_T)width1 / 2)
+ : ((curwin->w_curswant - width1) % width2
+ > (colnr_T)width2 / 2)))
+ --curwin->w_cursor.col;
+ }
+
+ if (atend)
+ curwin->w_curswant = MAXCOL; /* stick in the last column */
+
+ return retval;
+}
+
+/*
+ * Mouse scroll wheel: Default action is to scroll three lines, or one page
+ * when Shift or Ctrl is used.
+ * K_MOUSEUP (cap->arg == 1) or K_MOUSEDOWN (cap->arg == 0) or
+ * K_MOUSELEFT (cap->arg == -1) or K_MOUSERIGHT (cap->arg == -2)
+ */
+static void nv_mousescroll(cap)
+cmdarg_T *cap;
+{
+ win_T *old_curwin = curwin;
+
+ if (mouse_row >= 0 && mouse_col >= 0) {
+ int row, col;
+
+ row = mouse_row;
+ col = mouse_col;
+
+ /* find the window at the pointer coordinates */
+ curwin = mouse_find_win(&row, &col);
+ curbuf = curwin->w_buffer;
+ }
+
+ if (cap->arg == MSCR_UP || cap->arg == MSCR_DOWN) {
+ if (mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL)) {
+ (void)onepage(cap->arg ? FORWARD : BACKWARD, 1L);
+ } else {
+ cap->count1 = 3;
+ cap->count0 = 3;
+ nv_scroll_line(cap);
+ }
+ }
+
+ curwin->w_redr_status = TRUE;
+
+ curwin = old_curwin;
+ curbuf = curwin->w_buffer;
+}
+
+/*
+ * Mouse clicks and drags.
+ */
+static void nv_mouse(cap)
+cmdarg_T *cap;
+{
+ (void)do_mouse(cap->oap, cap->cmdchar, BACKWARD, cap->count1, 0);
+}
+
+/*
+ * Handle CTRL-E and CTRL-Y commands: scroll a line up or down.
+ * cap->arg must be TRUE for CTRL-E.
+ */
+static void nv_scroll_line(cap)
+cmdarg_T *cap;
+{
+ if (!checkclearop(cap->oap))
+ scroll_redraw(cap->arg, cap->count1);
+}
+
+/*
+ * Scroll "count" lines up or down, and redraw.
+ */
+void scroll_redraw(up, count)
+int up;
+long count;
+{
+ linenr_T prev_topline = curwin->w_topline;
+ int prev_topfill = curwin->w_topfill;
+ linenr_T prev_lnum = curwin->w_cursor.lnum;
+
+ if (up)
+ scrollup(count, TRUE);
+ else
+ scrolldown(count, TRUE);
+ if (p_so) {
+ /* Adjust the cursor position for 'scrolloff'. Mark w_topline as
+ * valid, otherwise the screen jumps back at the end of the file. */
+ cursor_correct();
+ check_cursor_moved(curwin);
+ curwin->w_valid |= VALID_TOPLINE;
+
+ /* If moved back to where we were, at least move the cursor, otherwise
+ * we get stuck at one position. Don't move the cursor up if the
+ * first line of the buffer is already on the screen */
+ while (curwin->w_topline == prev_topline
+ && curwin->w_topfill == prev_topfill
+ ) {
+ if (up) {
+ if (curwin->w_cursor.lnum > prev_lnum
+ || cursor_down(1L, FALSE) == FAIL)
+ break;
+ } else {
+ if (curwin->w_cursor.lnum < prev_lnum
+ || prev_topline == 1L
+ || cursor_up(1L, FALSE) == FAIL)
+ break;
+ }
+ /* Mark w_topline as valid, otherwise the screen jumps back at the
+ * end of the file. */
+ check_cursor_moved(curwin);
+ curwin->w_valid |= VALID_TOPLINE;
+ }
+ }
+ if (curwin->w_cursor.lnum != prev_lnum)
+ coladvance(curwin->w_curswant);
+ redraw_later(VALID);
+}
+
+/*
+ * Commands that start with "z".
+ */
+static void nv_zet(cap)
+cmdarg_T *cap;
+{
+ long n;
+ colnr_T col;
+ int nchar = cap->nchar;
+ long old_fdl = curwin->w_p_fdl;
+ int old_fen = curwin->w_p_fen;
+ int undo = FALSE;
+
+ if (VIM_ISDIGIT(nchar)) {
+ /*
+ * "z123{nchar}": edit the count before obtaining {nchar}
+ */
+ if (checkclearop(cap->oap))
+ return;
+ n = nchar - '0';
+ for (;; ) {
+#ifdef USE_ON_FLY_SCROLL
+ dont_scroll = TRUE; /* disallow scrolling here */
+#endif
+ ++no_mapping;
+ ++allow_keys; /* no mapping for nchar, but allow key codes */
+ nchar = plain_vgetc();
+ LANGMAP_ADJUST(nchar, TRUE);
+ --no_mapping;
+ --allow_keys;
+ (void)add_to_showcmd(nchar);
+ if (nchar == K_DEL || nchar == K_KDEL)
+ n /= 10;
+ else if (VIM_ISDIGIT(nchar))
+ n = n * 10 + (nchar - '0');
+ else if (nchar == CAR) {
+ win_setheight((int)n);
+ break;
+ } else if (nchar == 'l'
+ || nchar == 'h'
+ || nchar == K_LEFT
+ || nchar == K_RIGHT) {
+ cap->count1 = n ? n * cap->count1 : cap->count1;
+ goto dozet;
+ } else {
+ clearopbeep(cap->oap);
+ break;
+ }
+ }
+ cap->oap->op_type = OP_NOP;
+ return;
+ }
+
+dozet:
+ if (
+ /* "zf" and "zF" are always an operator, "zd", "zo", "zO", "zc"
+ * and "zC" only in Visual mode. "zj" and "zk" are motion
+ * commands. */
+ cap->nchar != 'f' && cap->nchar != 'F'
+ && !(VIsual_active && vim_strchr((char_u *)"dcCoO", cap->nchar))
+ && cap->nchar != 'j' && cap->nchar != 'k'
+ &&
+ checkclearop(cap->oap))
+ return;
+
+ /*
+ * For "z+", "z<CR>", "zt", "z.", "zz", "z^", "z-", "zb":
+ * If line number given, set cursor.
+ */
+ if ((vim_strchr((char_u *)"+\r\nt.z^-b", nchar) != NULL)
+ && cap->count0
+ && cap->count0 != curwin->w_cursor.lnum) {
+ setpcmark();
+ if (cap->count0 > curbuf->b_ml.ml_line_count)
+ curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
+ else
+ curwin->w_cursor.lnum = cap->count0;
+ check_cursor_col();
+ }
+
+ switch (nchar) {
+ /* "z+", "z<CR>" and "zt": put cursor at top of screen */
+ case '+':
+ if (cap->count0 == 0) {
+ /* No count given: put cursor at the line below screen */
+ validate_botline(); /* make sure w_botline is valid */
+ if (curwin->w_botline > curbuf->b_ml.ml_line_count)
+ curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
+ else
+ curwin->w_cursor.lnum = curwin->w_botline;
+ }
+ /* FALLTHROUGH */
+ case NL:
+ case CAR:
+ case K_KENTER:
+ beginline(BL_WHITE | BL_FIX);
+ /* FALLTHROUGH */
+
+ case 't': scroll_cursor_top(0, TRUE);
+ redraw_later(VALID);
+ break;
+
+ /* "z." and "zz": put cursor in middle of screen */
+ case '.': beginline(BL_WHITE | BL_FIX);
+ /* FALLTHROUGH */
+
+ case 'z': scroll_cursor_halfway(TRUE);
+ redraw_later(VALID);
+ break;
+
+ /* "z^", "z-" and "zb": put cursor at bottom of screen */
+ case '^': /* Strange Vi behavior: <count>z^ finds line at top of window
+ * when <count> is at bottom of window, and puts that one at
+ * bottom of window. */
+ if (cap->count0 != 0) {
+ scroll_cursor_bot(0, TRUE);
+ curwin->w_cursor.lnum = curwin->w_topline;
+ } else if (curwin->w_topline == 1)
+ curwin->w_cursor.lnum = 1;
+ else
+ curwin->w_cursor.lnum = curwin->w_topline - 1;
+ /* FALLTHROUGH */
+ case '-':
+ beginline(BL_WHITE | BL_FIX);
+ /* FALLTHROUGH */
+
+ case 'b': scroll_cursor_bot(0, TRUE);
+ redraw_later(VALID);
+ break;
+
+ /* "zH" - scroll screen right half-page */
+ case 'H':
+ cap->count1 *= W_WIDTH(curwin) / 2;
+ /* FALLTHROUGH */
+
+ /* "zh" - scroll screen to the right */
+ case 'h':
+ case K_LEFT:
+ if (!curwin->w_p_wrap) {
+ if ((colnr_T)cap->count1 > curwin->w_leftcol)
+ curwin->w_leftcol = 0;
+ else
+ curwin->w_leftcol -= (colnr_T)cap->count1;
+ leftcol_changed();
+ }
+ break;
+
+ /* "zL" - scroll screen left half-page */
+ case 'L': cap->count1 *= W_WIDTH(curwin) / 2;
+ /* FALLTHROUGH */
+
+ /* "zl" - scroll screen to the left */
+ case 'l':
+ case K_RIGHT:
+ if (!curwin->w_p_wrap) {
+ /* scroll the window left */
+ curwin->w_leftcol += (colnr_T)cap->count1;
+ leftcol_changed();
+ }
+ break;
+
+ /* "zs" - scroll screen, cursor at the start */
+ case 's': if (!curwin->w_p_wrap) {
+ if (hasFolding(curwin->w_cursor.lnum, NULL, NULL))
+ col = 0; /* like the cursor is in col 0 */
+ else
+ getvcol(curwin, &curwin->w_cursor, &col, NULL, NULL);
+ if ((long)col > p_siso)
+ col -= p_siso;
+ else
+ col = 0;
+ if (curwin->w_leftcol != col) {
+ curwin->w_leftcol = col;
+ redraw_later(NOT_VALID);
+ }
+ }
+ break;
+
+ /* "ze" - scroll screen, cursor at the end */
+ case 'e': if (!curwin->w_p_wrap) {
+ if (hasFolding(curwin->w_cursor.lnum, NULL, NULL))
+ col = 0; /* like the cursor is in col 0 */
+ else
+ getvcol(curwin, &curwin->w_cursor, NULL, NULL, &col);
+ n = W_WIDTH(curwin) - curwin_col_off();
+ if ((long)col + p_siso < n)
+ col = 0;
+ else
+ col = col + p_siso - n + 1;
+ if (curwin->w_leftcol != col) {
+ curwin->w_leftcol = col;
+ redraw_later(NOT_VALID);
+ }
+ }
+ break;
+
+ /* "zF": create fold command */
+ /* "zf": create fold operator */
+ case 'F':
+ case 'f': if (foldManualAllowed(TRUE)) {
+ cap->nchar = 'f';
+ nv_operator(cap);
+ curwin->w_p_fen = TRUE;
+
+ /* "zF" is like "zfzf" */
+ if (nchar == 'F' && cap->oap->op_type == OP_FOLD) {
+ nv_operator(cap);
+ finish_op = TRUE;
+ }
+ } else
+ clearopbeep(cap->oap);
+ break;
+
+ /* "zd": delete fold at cursor */
+ /* "zD": delete fold at cursor recursively */
+ case 'd':
+ case 'D': if (foldManualAllowed(FALSE)) {
+ if (VIsual_active)
+ nv_operator(cap);
+ else
+ deleteFold(curwin->w_cursor.lnum,
+ curwin->w_cursor.lnum, nchar == 'D', FALSE);
+ }
+ break;
+
+ /* "zE": erase all folds */
+ case 'E': if (foldmethodIsManual(curwin)) {
+ clearFolding(curwin);
+ changed_window_setting();
+ } else if (foldmethodIsMarker(curwin))
+ deleteFold((linenr_T)1, curbuf->b_ml.ml_line_count,
+ TRUE, FALSE);
+ else
+ EMSG(_("E352: Cannot erase folds with current 'foldmethod'"));
+ break;
+
+ /* "zn": fold none: reset 'foldenable' */
+ case 'n': curwin->w_p_fen = FALSE;
+ break;
+
+ /* "zN": fold Normal: set 'foldenable' */
+ case 'N': curwin->w_p_fen = TRUE;
+ break;
+
+ /* "zi": invert folding: toggle 'foldenable' */
+ case 'i': curwin->w_p_fen = !curwin->w_p_fen;
+ break;
+
+ /* "za": open closed fold or close open fold at cursor */
+ case 'a': if (hasFolding(curwin->w_cursor.lnum, NULL, NULL))
+ openFold(curwin->w_cursor.lnum, cap->count1);
+ else {
+ closeFold(curwin->w_cursor.lnum, cap->count1);
+ curwin->w_p_fen = TRUE;
+ }
+ break;
+
+ /* "zA": open fold at cursor recursively */
+ case 'A': if (hasFolding(curwin->w_cursor.lnum, NULL, NULL))
+ openFoldRecurse(curwin->w_cursor.lnum);
+ else {
+ closeFoldRecurse(curwin->w_cursor.lnum);
+ curwin->w_p_fen = TRUE;
+ }
+ break;
+
+ /* "zo": open fold at cursor or Visual area */
+ case 'o': if (VIsual_active)
+ nv_operator(cap);
+ else
+ openFold(curwin->w_cursor.lnum, cap->count1);
+ break;
+
+ /* "zO": open fold recursively */
+ case 'O': if (VIsual_active)
+ nv_operator(cap);
+ else
+ openFoldRecurse(curwin->w_cursor.lnum);
+ break;
+
+ /* "zc": close fold at cursor or Visual area */
+ case 'c': if (VIsual_active)
+ nv_operator(cap);
+ else
+ closeFold(curwin->w_cursor.lnum, cap->count1);
+ curwin->w_p_fen = TRUE;
+ break;
+
+ /* "zC": close fold recursively */
+ case 'C': if (VIsual_active)
+ nv_operator(cap);
+ else
+ closeFoldRecurse(curwin->w_cursor.lnum);
+ curwin->w_p_fen = TRUE;
+ break;
+
+ /* "zv": open folds at the cursor */
+ case 'v': foldOpenCursor();
+ break;
+
+ /* "zx": re-apply 'foldlevel' and open folds at the cursor */
+ case 'x': curwin->w_p_fen = TRUE;
+ curwin->w_foldinvalid = TRUE; /* recompute folds */
+ newFoldLevel(); /* update right now */
+ foldOpenCursor();
+ break;
+
+ /* "zX": undo manual opens/closes, re-apply 'foldlevel' */
+ case 'X': curwin->w_p_fen = TRUE;
+ curwin->w_foldinvalid = TRUE; /* recompute folds */
+ old_fdl = -1; /* force an update */
+ break;
+
+ /* "zm": fold more */
+ case 'm': if (curwin->w_p_fdl > 0)
+ --curwin->w_p_fdl;
+ old_fdl = -1; /* force an update */
+ curwin->w_p_fen = TRUE;
+ break;
+
+ /* "zM": close all folds */
+ case 'M': curwin->w_p_fdl = 0;
+ old_fdl = -1; /* force an update */
+ curwin->w_p_fen = TRUE;
+ break;
+
+ /* "zr": reduce folding */
+ case 'r': ++curwin->w_p_fdl;
+ break;
+
+ /* "zR": open all folds */
+ case 'R': curwin->w_p_fdl = getDeepestNesting();
+ old_fdl = -1; /* force an update */
+ break;
+
+ case 'j': /* "zj" move to next fold downwards */
+ case 'k': /* "zk" move to next fold upwards */
+ if (foldMoveTo(TRUE, nchar == 'j' ? FORWARD : BACKWARD,
+ cap->count1) == FAIL)
+ clearopbeep(cap->oap);
+ break;
+
+
+ case 'u': /* "zug" and "zuw": undo "zg" and "zw" */
+ ++no_mapping;
+ ++allow_keys; /* no mapping for nchar, but allow key codes */
+ nchar = plain_vgetc();
+ LANGMAP_ADJUST(nchar, TRUE);
+ --no_mapping;
+ --allow_keys;
+ (void)add_to_showcmd(nchar);
+ if (vim_strchr((char_u *)"gGwW", nchar) == NULL) {
+ clearopbeep(cap->oap);
+ break;
+ }
+ undo = TRUE;
+ /*FALLTHROUGH*/
+
+ case 'g': /* "zg": add good word to word list */
+ case 'w': /* "zw": add wrong word to word list */
+ case 'G': /* "zG": add good word to temp word list */
+ case 'W': /* "zW": add wrong word to temp word list */
+ {
+ char_u *ptr = NULL;
+ int len;
+
+ if (checkclearop(cap->oap))
+ break;
+ if (VIsual_active && get_visual_text(cap, &ptr, &len)
+ == FAIL)
+ return;
+ if (ptr == NULL) {
+ pos_T pos = curwin->w_cursor;
+
+ /* Find bad word under the cursor. When 'spell' is
+ * off this fails and find_ident_under_cursor() is
+ * used below. */
+ emsg_off++;
+ len = spell_move_to(curwin, FORWARD, TRUE, TRUE, NULL);
+ emsg_off--;
+ if (len != 0 && curwin->w_cursor.col <= pos.col)
+ ptr = ml_get_pos(&curwin->w_cursor);
+ curwin->w_cursor = pos;
+ }
+
+ if (ptr == NULL && (len = find_ident_under_cursor(&ptr,
+ FIND_IDENT)) == 0)
+ return;
+ spell_add_word(ptr, len, nchar == 'w' || nchar == 'W',
+ (nchar == 'G' || nchar == 'W')
+ ? 0 : (int)cap->count1,
+ undo);
+ }
+ break;
+
+ case '=': /* "z=": suggestions for a badly spelled word */
+ if (!checkclearop(cap->oap))
+ spell_suggest((int)cap->count0);
+ break;
+
+ default: clearopbeep(cap->oap);
+ }
+
+ /* Redraw when 'foldenable' changed */
+ if (old_fen != curwin->w_p_fen) {
+ win_T *wp;
+
+ if (foldmethodIsDiff(curwin) && curwin->w_p_scb) {
+ /* Adjust 'foldenable' in diff-synced windows. */
+ FOR_ALL_WINDOWS(wp)
+ {
+ if (wp != curwin && foldmethodIsDiff(wp) && wp->w_p_scb) {
+ wp->w_p_fen = curwin->w_p_fen;
+ changed_window_setting_win(wp);
+ }
+ }
+ }
+ changed_window_setting();
+ }
+
+ /* Redraw when 'foldlevel' changed. */
+ if (old_fdl != curwin->w_p_fdl)
+ newFoldLevel();
+}
+
+
+
+/*
+ * "Q" command.
+ */
+static void nv_exmode(cap)
+cmdarg_T *cap;
+{
+ /*
+ * Ignore 'Q' in Visual mode, just give a beep.
+ */
+ if (VIsual_active)
+ vim_beep();
+ else if (!checkclearop(cap->oap))
+ do_exmode(FALSE);
+}
+
+/*
+ * Handle a ":" command.
+ */
+static void nv_colon(cap)
+cmdarg_T *cap;
+{
+ int old_p_im;
+ int cmd_result;
+
+ if (VIsual_active)
+ nv_operator(cap);
+ else {
+ if (cap->oap->op_type != OP_NOP) {
+ /* Using ":" as a movement is characterwise exclusive. */
+ cap->oap->motion_type = MCHAR;
+ cap->oap->inclusive = FALSE;
+ } else if (cap->count0) {
+ /* translate "count:" into ":.,.+(count - 1)" */
+ stuffcharReadbuff('.');
+ if (cap->count0 > 1) {
+ stuffReadbuff((char_u *)",.+");
+ stuffnumReadbuff((long)cap->count0 - 1L);
+ }
+ }
+
+ /* When typing, don't type below an old message */
+ if (KeyTyped)
+ compute_cmdrow();
+
+ 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);
+
+ /* If 'insertmode' changed, enter or exit Insert mode */
+ if (p_im != old_p_im) {
+ if (p_im)
+ restart_edit = 'i';
+ else
+ restart_edit = 0;
+ }
+
+ if (cmd_result == FAIL)
+ /* The Ex command failed, do not execute the operator. */
+ clearop(cap->oap);
+ else if (cap->oap->op_type != OP_NOP
+ && (cap->oap->start.lnum > curbuf->b_ml.ml_line_count
+ || cap->oap->start.col >
+ (colnr_T)STRLEN(ml_get(cap->oap->start.lnum))
+ || did_emsg
+ ))
+ /* The start of the operator has become invalid by the Ex command.
+ */
+ clearopbeep(cap->oap);
+ }
+}
+
+/*
+ * Handle CTRL-G command.
+ */
+static void nv_ctrlg(cap)
+cmdarg_T *cap;
+{
+ if (VIsual_active) { /* toggle Selection/Visual mode */
+ VIsual_select = !VIsual_select;
+ showmode();
+ } else if (!checkclearop(cap->oap))
+ /* print full name if count given or :cd used */
+ fileinfo((int)cap->count0, FALSE, TRUE);
+}
+
+/*
+ * Handle CTRL-H <Backspace> command.
+ */
+static void nv_ctrlh(cap)
+cmdarg_T *cap;
+{
+ if (VIsual_active && VIsual_select) {
+ cap->cmdchar = 'x'; /* BS key behaves like 'x' in Select mode */
+ v_visop(cap);
+ } else
+ nv_left(cap);
+}
+
+/*
+ * CTRL-L: clear screen and redraw.
+ */
+static void nv_clear(cap)
+cmdarg_T *cap;
+{
+ if (!checkclearop(cap->oap)) {
+ /* Clear all syntax states to force resyncing. */
+ syn_stack_free_all(curwin->w_s);
+ redraw_later(CLEAR);
+ }
+}
+
+/*
+ * CTRL-O: In Select mode: switch to Visual mode for one command.
+ * Otherwise: Go to older pcmark.
+ */
+static void nv_ctrlo(cap)
+cmdarg_T *cap;
+{
+ if (VIsual_active && VIsual_select) {
+ VIsual_select = FALSE;
+ showmode();
+ restart_VIsual_select = 2; /* restart Select mode later */
+ } else {
+ cap->count1 = -cap->count1;
+ nv_pcmark(cap);
+ }
+}
+
+/*
+ * CTRL-^ command, short for ":e #"
+ */
+static void nv_hat(cap)
+cmdarg_T *cap;
+{
+ if (!checkclearopq(cap->oap))
+ (void)buflist_getfile((int)cap->count0, (linenr_T)0,
+ GETF_SETMARK|GETF_ALT, FALSE);
+}
+
+/*
+ * "Z" commands.
+ */
+static void nv_Zet(cap)
+cmdarg_T *cap;
+{
+ if (!checkclearopq(cap->oap)) {
+ switch (cap->nchar) {
+ /* "ZZ": equivalent to ":x". */
+ case 'Z': do_cmdline_cmd((char_u *)"x");
+ break;
+
+ /* "ZQ": equivalent to ":q!" (Elvis compatible). */
+ case 'Q': do_cmdline_cmd((char_u *)"q!");
+ break;
+
+ default: clearopbeep(cap->oap);
+ }
+ }
+}
+
+/*
+ * Call nv_ident() as if "c1" was used, with "c2" as next character.
+ */
+void do_nv_ident(c1, c2)
+int c1;
+int c2;
+{
+ oparg_T oa;
+ cmdarg_T ca;
+
+ clear_oparg(&oa);
+ vim_memset(&ca, 0, sizeof(ca));
+ ca.oap = &oa;
+ ca.cmdchar = c1;
+ ca.nchar = c2;
+ nv_ident(&ca);
+}
+
+/*
+ * Handle the commands that use the word under the cursor.
+ * [g] CTRL-] :ta to current identifier
+ * [g] 'K' run program for current identifier
+ * [g] '*' / to current identifier or string
+ * [g] '#' ? to current identifier or string
+ * g ']' :tselect for current identifier
+ */
+static void nv_ident(cap)
+cmdarg_T *cap;
+{
+ char_u *ptr = NULL;
+ char_u *buf;
+ char_u *newbuf;
+ char_u *p;
+ char_u *kp; /* value of 'keywordprg' */
+ int kp_help; /* 'keywordprg' is ":help" */
+ int n = 0; /* init for GCC */
+ int cmdchar;
+ int g_cmd; /* "g" command */
+ int tag_cmd = FALSE;
+ char_u *aux_ptr;
+ int isman;
+ int isman_s;
+
+ if (cap->cmdchar == 'g') { /* "g*", "g#", "g]" and "gCTRL-]" */
+ cmdchar = cap->nchar;
+ g_cmd = TRUE;
+ } else {
+ cmdchar = cap->cmdchar;
+ g_cmd = FALSE;
+ }
+
+ if (cmdchar == POUND) /* the pound sign, '#' for English keyboards */
+ cmdchar = '#';
+
+ /*
+ * The "]", "CTRL-]" and "K" commands accept an argument in Visual mode.
+ */
+ if (cmdchar == ']' || cmdchar == Ctrl_RSB || cmdchar == 'K') {
+ if (VIsual_active && get_visual_text(cap, &ptr, &n) == FAIL)
+ return;
+ if (checkclearopq(cap->oap))
+ return;
+ }
+
+ if (ptr == NULL && (n = find_ident_under_cursor(&ptr,
+ (cmdchar == '*' || cmdchar == '#')
+ ? FIND_IDENT|FIND_STRING : FIND_IDENT)) == 0) {
+ clearop(cap->oap);
+ return;
+ }
+
+ /* Allocate buffer to put the command in. Inserting backslashes can
+ * double the length of the word. p_kp / curbuf->b_p_kp could be added
+ * and some numbers. */
+ kp = (*curbuf->b_p_kp == NUL ? p_kp : curbuf->b_p_kp);
+ kp_help = (*kp == NUL || STRCMP(kp, ":he") == 0
+ || STRCMP(kp, ":help") == 0);
+ buf = alloc((unsigned)(n * 2 + 30 + STRLEN(kp)));
+ if (buf == NULL)
+ return;
+ buf[0] = NUL;
+
+ switch (cmdchar) {
+ case '*':
+ case '#':
+ /*
+ * Put cursor at start of word, makes search skip the word
+ * under the cursor.
+ * Call setpcmark() first, so "*``" puts the cursor back where
+ * it was.
+ */
+ setpcmark();
+ curwin->w_cursor.col = (colnr_T) (ptr - ml_get_curline());
+
+ if (!g_cmd && vim_iswordp(ptr))
+ STRCPY(buf, "\\<");
+ no_smartcase = TRUE; /* don't use 'smartcase' now */
+ break;
+
+ case 'K':
+ if (kp_help)
+ STRCPY(buf, "he! ");
+ else {
+ /* An external command will probably use an argument starting
+ * with "-" as an option. To avoid trouble we skip the "-". */
+ while (*ptr == '-' && n > 0) {
+ ++ptr;
+ --n;
+ }
+ if (n == 0) {
+ EMSG(_(e_noident)); /* found dashes only */
+ vim_free(buf);
+ return;
+ }
+
+ /* When a count is given, turn it into a range. Is this
+ * really what we want? */
+ isman = (STRCMP(kp, "man") == 0);
+ isman_s = (STRCMP(kp, "man -s") == 0);
+ if (cap->count0 != 0 && !(isman || isman_s))
+ sprintf((char *)buf, ".,.+%ld", cap->count0 - 1);
+
+ STRCAT(buf, "! ");
+ if (cap->count0 == 0 && isman_s)
+ STRCAT(buf, "man");
+ else
+ STRCAT(buf, kp);
+ STRCAT(buf, " ");
+ if (cap->count0 != 0 && (isman || isman_s)) {
+ sprintf((char *)buf + STRLEN(buf), "%ld", cap->count0);
+ STRCAT(buf, " ");
+ }
+ }
+ break;
+
+ case ']':
+ tag_cmd = TRUE;
+ if (p_cst)
+ STRCPY(buf, "cstag ");
+ else
+ STRCPY(buf, "ts ");
+ break;
+
+ default:
+ tag_cmd = TRUE;
+ if (curbuf->b_help)
+ STRCPY(buf, "he! ");
+ else {
+ if (g_cmd)
+ STRCPY(buf, "tj ");
+ else
+ sprintf((char *)buf, "%ldta ", cap->count0);
+ }
+ }
+
+ /*
+ * Now grab the chars in the identifier
+ */
+ if (cmdchar == 'K' && !kp_help) {
+ /* Escape the argument properly for a shell command */
+ ptr = vim_strnsave(ptr, n);
+ p = vim_strsave_shellescape(ptr, TRUE);
+ vim_free(ptr);
+ if (p == NULL) {
+ vim_free(buf);
+ return;
+ }
+ newbuf = (char_u *)vim_realloc(buf, STRLEN(buf) + STRLEN(p) + 1);
+ if (newbuf == NULL) {
+ vim_free(buf);
+ vim_free(p);
+ return;
+ }
+ buf = newbuf;
+ STRCAT(buf, p);
+ vim_free(p);
+ } else {
+ if (cmdchar == '*')
+ aux_ptr = (char_u *)(p_magic ? "/.*~[^$\\" : "/^$\\");
+ else if (cmdchar == '#')
+ aux_ptr = (char_u *)(p_magic ? "/?.*~[^$\\" : "/?^$\\");
+ else if (tag_cmd) {
+ if (curbuf->b_help)
+ /* ":help" handles unescaped argument */
+ aux_ptr = (char_u *)"";
+ else
+ aux_ptr = (char_u *)"\\|\"\n[";
+ } else
+ aux_ptr = (char_u *)"\\|\"\n*?[";
+
+ p = buf + STRLEN(buf);
+ while (n-- > 0) {
+ /* put a backslash before \ and some others */
+ if (vim_strchr(aux_ptr, *ptr) != NULL)
+ *p++ = '\\';
+ /* When current byte is a part of multibyte character, copy all
+ * bytes of that character. */
+ if (has_mbyte) {
+ int i;
+ int len = (*mb_ptr2len)(ptr) - 1;
+
+ for (i = 0; i < len && n >= 1; ++i, --n)
+ *p++ = *ptr++;
+ }
+ *p++ = *ptr++;
+ }
+ *p = NUL;
+ }
+
+ /*
+ * Execute the command.
+ */
+ if (cmdchar == '*' || cmdchar == '#') {
+ if (!g_cmd && (
+ has_mbyte ? vim_iswordp(mb_prevptr(ml_get_curline(), ptr)) :
+ vim_iswordc(ptr[-1])))
+ STRCAT(buf, "\\>");
+ /* put pattern in search history */
+ init_history();
+ add_to_history(HIST_SEARCH, buf, TRUE, NUL);
+ normal_search(cap, cmdchar == '*' ? '/' : '?', buf, 0);
+ } else
+ do_cmdline_cmd(buf);
+
+ vim_free(buf);
+}
+
+/*
+ * Get visually selected text, within one line only.
+ * Returns FAIL if more than one line selected.
+ */
+int get_visual_text(cap, pp, lenp)
+cmdarg_T *cap;
+char_u **pp; /* return: start of selected text */
+int *lenp; /* return: length of selected text */
+{
+ if (VIsual_mode != 'V')
+ unadjust_for_sel();
+ if (VIsual.lnum != curwin->w_cursor.lnum) {
+ if (cap != NULL)
+ clearopbeep(cap->oap);
+ return FAIL;
+ }
+ if (VIsual_mode == 'V') {
+ *pp = ml_get_curline();
+ *lenp = (int)STRLEN(*pp);
+ } else {
+ if (lt(curwin->w_cursor, VIsual)) {
+ *pp = ml_get_pos(&curwin->w_cursor);
+ *lenp = VIsual.col - curwin->w_cursor.col + 1;
+ } else {
+ *pp = ml_get_pos(&VIsual);
+ *lenp = curwin->w_cursor.col - VIsual.col + 1;
+ }
+ if (has_mbyte)
+ /* Correct the length to include the whole last character. */
+ *lenp += (*mb_ptr2len)(*pp + (*lenp - 1)) - 1;
+ }
+ reset_VIsual_and_resel();
+ return OK;
+}
+
+/*
+ * CTRL-T: backwards in tag stack
+ */
+static void nv_tagpop(cap)
+cmdarg_T *cap;
+{
+ if (!checkclearopq(cap->oap))
+ do_tag((char_u *)"", DT_POP, (int)cap->count1, FALSE, TRUE);
+}
+
+/*
+ * Handle scrolling command 'H', 'L' and 'M'.
+ */
+static void nv_scroll(cap)
+cmdarg_T *cap;
+{
+ int used = 0;
+ long n;
+ linenr_T lnum;
+ int half;
+
+ cap->oap->motion_type = MLINE;
+ setpcmark();
+
+ if (cap->cmdchar == 'L') {
+ validate_botline(); /* make sure curwin->w_botline is valid */
+ curwin->w_cursor.lnum = curwin->w_botline - 1;
+ if (cap->count1 - 1 >= curwin->w_cursor.lnum)
+ curwin->w_cursor.lnum = 1;
+ else {
+ if (hasAnyFolding(curwin)) {
+ /* Count a fold for one screen line. */
+ for (n = cap->count1 - 1; n > 0
+ && curwin->w_cursor.lnum > curwin->w_topline; --n) {
+ (void)hasFolding(curwin->w_cursor.lnum,
+ &curwin->w_cursor.lnum, NULL);
+ --curwin->w_cursor.lnum;
+ }
+ } else
+ curwin->w_cursor.lnum -= cap->count1 - 1;
+ }
+ } else {
+ if (cap->cmdchar == 'M') {
+ /* 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". */
+ if (n > 0 && used + diff_check_fill(curwin, curwin->w_topline
+ + n) / 2 >= half) {
+ --n;
+ break;
+ }
+ used += plines(curwin->w_topline + n);
+ if (used >= half)
+ break;
+ 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') */
+ n = cap->count1 - 1;
+ if (hasAnyFolding(curwin)) {
+ /* Count a fold for one screen line. */
+ lnum = curwin->w_topline;
+ while (n-- > 0 && lnum < curwin->w_botline - 1) {
+ hasFolding(lnum, NULL, &lnum);
+ ++lnum;
+ }
+ n = lnum - curwin->w_topline;
+ }
+ }
+ curwin->w_cursor.lnum = curwin->w_topline + n;
+ if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count)
+ curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
+ }
+
+ cursor_correct(); /* correct for 'so' */
+ beginline(BL_SOL | BL_FIX);
+}
+
+/*
+ * Cursor right commands.
+ */
+static void nv_right(cap)
+cmdarg_T *cap;
+{
+ long n;
+ int PAST_LINE;
+
+ if (mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL)) {
+ /* <C-Right> and <S-Right> move a word or WORD right */
+ if (mod_mask & MOD_MASK_CTRL)
+ cap->arg = TRUE;
+ nv_wordcmd(cap);
+ return;
+ }
+
+ cap->oap->motion_type = MCHAR;
+ cap->oap->inclusive = FALSE;
+ PAST_LINE = (VIsual_active && *p_sel != 'o');
+
+ /*
+ * In virtual mode, there's no such thing as "PAST_LINE", as lines are
+ * (theoretically) infinitely long.
+ */
+ if (virtual_active())
+ PAST_LINE = 0;
+
+ for (n = cap->count1; n > 0; --n) {
+ if ((!PAST_LINE && oneright() == FAIL)
+ || (PAST_LINE && *ml_get_cursor() == 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))
+ cap->oap->inclusive = TRUE;
+ else {
+ ++curwin->w_cursor.lnum;
+ curwin->w_cursor.col = 0;
+ curwin->w_cursor.coladd = 0;
+ curwin->w_set_curswant = TRUE;
+ cap->oap->inclusive = FALSE;
+ }
+ continue;
+ }
+ if (cap->oap->op_type == OP_NOP) {
+ /* Only beep and flush if not moved at all */
+ if (n == cap->count1)
+ beep_flush();
+ } else {
+ if (!lineempty(curwin->w_cursor.lnum))
+ cap->oap->inclusive = TRUE;
+ }
+ break;
+ } else if (PAST_LINE) {
+ curwin->w_set_curswant = TRUE;
+ if (virtual_active())
+ oneright();
+ else {
+ if (has_mbyte)
+ curwin->w_cursor.col +=
+ (*mb_ptr2len)(ml_get_cursor());
+ else
+ ++curwin->w_cursor.col;
+ }
+ }
+ }
+ if (n != cap->count1 && (fdo_flags & FDO_HOR) && KeyTyped
+ && cap->oap->op_type == OP_NOP)
+ foldOpenCursor();
+}
+
+/*
+ * Cursor left commands.
+ *
+ * Returns TRUE when operator end should not be adjusted.
+ */
+static void nv_left(cap)
+cmdarg_T *cap;
+{
+ long n;
+
+ if (mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL)) {
+ /* <C-Left> and <S-Left> move a word or WORD left */
+ if (mod_mask & MOD_MASK_CTRL)
+ cap->arg = 1;
+ nv_bck_word(cap);
+ return;
+ }
+
+ cap->oap->motion_type = MCHAR;
+ cap->oap->inclusive = FALSE;
+ for (n = cap->count1; n > 0; --n) {
+ if (oneleft() == FAIL) {
+ /* <BS> and <Del> wrap to previous line if 'whichwrap' has 'b'.
+ * 'h' wraps to previous line if 'whichwrap' has 'h'.
+ * CURS_LEFT wraps to previous line if 'whichwrap' has '<'.
+ */
+ if ( (((cap->cmdchar == K_BS
+ || cap->cmdchar == Ctrl_H)
+ && vim_strchr(p_ww, 'b') != NULL)
+ || (cap->cmdchar == 'h'
+ && vim_strchr(p_ww, 'h') != NULL)
+ || (cap->cmdchar == K_LEFT
+ && vim_strchr(p_ww, '<') != NULL))
+ && curwin->w_cursor.lnum > 1) {
+ --(curwin->w_cursor.lnum);
+ 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)) {
+ if (*ml_get_cursor() != NUL)
+ ++curwin->w_cursor.col;
+ cap->retval |= CA_NO_ADJ_OP_END;
+ }
+ continue;
+ }
+ /* Only beep and flush if not moved at all */
+ else if (cap->oap->op_type == OP_NOP && n == cap->count1)
+ beep_flush();
+ break;
+ }
+ }
+ if (n != cap->count1 && (fdo_flags & FDO_HOR) && KeyTyped
+ && cap->oap->op_type == OP_NOP)
+ foldOpenCursor();
+}
+
+/*
+ * Cursor up commands.
+ * cap->arg is TRUE for "-": Move cursor to first non-blank.
+ */
+static void nv_up(cap)
+cmdarg_T *cap;
+{
+ if (mod_mask & MOD_MASK_SHIFT) {
+ /* <S-Up> is page up */
+ cap->arg = BACKWARD;
+ nv_page(cap);
+ } else {
+ cap->oap->motion_type = MLINE;
+ if (cursor_up(cap->count1, cap->oap->op_type == OP_NOP) == FAIL)
+ clearopbeep(cap->oap);
+ else if (cap->arg)
+ beginline(BL_WHITE | BL_FIX);
+ }
+}
+
+/*
+ * Cursor down commands.
+ * cap->arg is TRUE for CR and "+": Move cursor to first non-blank.
+ */
+static void nv_down(cap)
+cmdarg_T *cap;
+{
+ if (mod_mask & MOD_MASK_SHIFT) {
+ /* <S-Down> is page down */
+ cap->arg = FORWARD;
+ nv_page(cap);
+ } else
+ /* In a quickfix window a <CR> jumps to the error under the cursor. */
+ if (bt_quickfix(curbuf) && cap->cmdchar == CAR)
+ if (curwin->w_llist_ref == NULL)
+ do_cmdline_cmd((char_u *)".cc"); /* quickfix window */
+ else
+ do_cmdline_cmd((char_u *)".ll"); /* location list window */
+ else {
+ /* In the cmdline window a <CR> executes the command. */
+ if (cmdwin_type != 0 && cap->cmdchar == CAR)
+ cmdwin_result = CAR;
+ else {
+ cap->oap->motion_type = MLINE;
+ if (cursor_down(cap->count1, cap->oap->op_type == OP_NOP) == FAIL)
+ clearopbeep(cap->oap);
+ else if (cap->arg)
+ beginline(BL_WHITE | BL_FIX);
+ }
+ }
+}
+
+/*
+ * Grab the file name under the cursor and edit it.
+ */
+static void nv_gotofile(cap)
+cmdarg_T *cap;
+{
+ char_u *ptr;
+ linenr_T lnum = -1;
+
+ if (text_locked()) {
+ clearopbeep(cap->oap);
+ text_locked_msg();
+ return;
+ }
+ if (curbuf_locked()) {
+ clearop(cap->oap);
+ return;
+ }
+
+ ptr = grab_file_name(cap->count1, &lnum);
+
+ if (ptr != NULL) {
+ /* do autowrite if necessary */
+ if (curbufIsChanged() && curbuf->b_nwindows <= 1 && !P_HID(curbuf))
+ 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) {
+ curwin->w_cursor.lnum = lnum;
+ check_cursor_lnum();
+ beginline(BL_SOL | BL_FIX);
+ }
+ vim_free(ptr);
+ } else
+ clearop(cap->oap);
+}
+
+/*
+ * <End> command: to end of current line or last line.
+ */
+static void nv_end(cap)
+cmdarg_T *cap;
+{
+ if (cap->arg || (mod_mask & MOD_MASK_CTRL)) { /* CTRL-END = goto last line */
+ cap->arg = TRUE;
+ nv_goto(cap);
+ cap->count1 = 1; /* to end of current line */
+ }
+ nv_dollar(cap);
+}
+
+/*
+ * Handle the "$" command.
+ */
+static void nv_dollar(cap)
+cmdarg_T *cap;
+{
+ cap->oap->motion_type = MCHAR;
+ cap->oap->inclusive = TRUE;
+ /* In virtual mode when off the edge of a line and an operator
+ * is pending (whew!) keep the cursor where it is.
+ * Otherwise, send it to the end of the line. */
+ if (!virtual_active() || gchar_cursor() != NUL
+ || cap->oap->op_type == OP_NOP)
+ curwin->w_curswant = MAXCOL; /* so we stay at the end */
+ if (cursor_down((long)(cap->count1 - 1),
+ cap->oap->op_type == OP_NOP) == FAIL)
+ clearopbeep(cap->oap);
+ else if ((fdo_flags & FDO_HOR) && KeyTyped && cap->oap->op_type == OP_NOP)
+ foldOpenCursor();
+}
+
+/*
+ * Implementation of '?' and '/' commands.
+ * If cap->arg is TRUE don't set PC mark.
+ */
+static void nv_search(cap)
+cmdarg_T *cap;
+{
+ oparg_T *oap = cap->oap;
+
+ if (cap->cmdchar == '?' && cap->oap->op_type == OP_ROT13) {
+ /* Translate "g??" to "g?g?" */
+ cap->cmdchar = 'g';
+ cap->nchar = '?';
+ nv_operator(cap);
+ return;
+ }
+
+ cap->searchbuf = getcmdline(cap->cmdchar, cap->count1, 0);
+
+ if (cap->searchbuf == NULL) {
+ clearop(oap);
+ return;
+ }
+
+ normal_search(cap, cap->cmdchar, cap->searchbuf,
+ (cap->arg ? 0 : SEARCH_MARK));
+}
+
+/*
+ * Handle "N" and "n" commands.
+ * cap->arg is SEARCH_REV for "N", 0 for "n".
+ */
+static void nv_next(cap)
+cmdarg_T *cap;
+{
+ normal_search(cap, 0, NULL, SEARCH_MARK | cap->arg);
+}
+
+/*
+ * Search for "pat" in direction "dir" ('/' or '?', 0 for repeat).
+ * Uses only cap->count1 and cap->oap from "cap".
+ */
+static void normal_search(cap, dir, pat, opt)
+cmdarg_T *cap;
+int dir;
+char_u *pat;
+int opt; /* extra flags for do_search() */
+{
+ int i;
+
+ cap->oap->motion_type = MCHAR;
+ cap->oap->inclusive = FALSE;
+ cap->oap->use_reg_one = TRUE;
+ curwin->w_set_curswant = TRUE;
+
+ i = do_search(cap->oap, dir, pat, cap->count1,
+ opt | SEARCH_OPT | SEARCH_ECHO | SEARCH_MSG, NULL);
+ if (i == 0)
+ clearop(cap->oap);
+ else {
+ if (i == 2)
+ cap->oap->motion_type = MLINE;
+ curwin->w_cursor.coladd = 0;
+ if (cap->oap->op_type == OP_NOP && (fdo_flags & FDO_SEARCH) && KeyTyped)
+ foldOpenCursor();
+ }
+
+ /* "/$" will put the cursor after the end of the line, may need to
+ * correct that here */
+ check_cursor();
+}
+
+/*
+ * Character search commands.
+ * cap->arg is BACKWARD for 'F' and 'T', FORWARD for 'f' and 't', TRUE for
+ * ',' and FALSE for ';'.
+ * cap->nchar is NUL for ',' and ';' (repeat the search)
+ */
+static void nv_csearch(cap)
+cmdarg_T *cap;
+{
+ int t_cmd;
+
+ if (cap->cmdchar == 't' || cap->cmdchar == 'T')
+ t_cmd = TRUE;
+ else
+ t_cmd = FALSE;
+
+ cap->oap->motion_type = MCHAR;
+ if (IS_SPECIAL(cap->nchar) || searchc(cap, t_cmd) == FAIL)
+ clearopbeep(cap->oap);
+ else {
+ curwin->w_set_curswant = TRUE;
+ /* Include a Tab for "tx" and for "dfx". */
+ if (gchar_cursor() == TAB && virtual_active() && cap->arg == FORWARD
+ && (t_cmd || cap->oap->op_type != OP_NOP)) {
+ colnr_T scol, ecol;
+
+ getvcol(curwin, &curwin->w_cursor, &scol, NULL, &ecol);
+ curwin->w_cursor.coladd = ecol - scol;
+ } else
+ curwin->w_cursor.coladd = 0;
+ adjust_for_sel(cap);
+ if ((fdo_flags & FDO_HOR) && KeyTyped && cap->oap->op_type == OP_NOP)
+ foldOpenCursor();
+ }
+}
+
+/*
+ * "[" and "]" commands.
+ * cap->arg is BACKWARD for "[" and FORWARD for "]".
+ */
+static void nv_brackets(cap)
+cmdarg_T *cap;
+{
+ pos_T new_pos = INIT_POS_T(0, 0, 0);
+ pos_T prev_pos;
+ pos_T *pos = NULL; /* init for GCC */
+ pos_T old_pos; /* cursor position before command */
+ int flag;
+ long n;
+ int findc;
+ int c;
+
+ cap->oap->motion_type = MCHAR;
+ cap->oap->inclusive = FALSE;
+ old_pos = curwin->w_cursor;
+ curwin->w_cursor.coladd = 0; /* TODO: don't do this for an error. */
+
+ /*
+ * "[f" or "]f" : Edit file under the cursor (same as "gf")
+ */
+ if (cap->nchar == 'f')
+ nv_gotofile(cap);
+ else
+ /*
+ * Find the occurrence(s) of the identifier or define under cursor
+ * in current and included files or jump to the first occurrence.
+ *
+ * search list jump
+ * fwd bwd fwd bwd fwd bwd
+ * identifier "]i" "[i" "]I" "[I" "]^I" "[^I"
+ * define "]d" "[d" "]D" "[D" "]^D" "[^D"
+ */
+ if (vim_strchr((char_u *)
+ "iI\011dD\004",
+ cap->nchar) != NULL) {
+ char_u *ptr;
+ int len;
+
+ if ((len = find_ident_under_cursor(&ptr, FIND_IDENT)) == 0)
+ clearop(cap->oap);
+ else {
+ find_pattern_in_path(ptr, 0, len, TRUE,
+ cap->count0 == 0 ? !isupper(cap->nchar) : FALSE,
+ ((cap->nchar & 0xf) == ('d' & 0xf)) ? FIND_DEFINE : FIND_ANY,
+ cap->count1,
+ isupper(cap->nchar) ? ACTION_SHOW_ALL :
+ islower(cap->nchar) ? ACTION_SHOW : ACTION_GOTO,
+ cap->cmdchar == ']' ? curwin->w_cursor.lnum + 1 : (linenr_T)1,
+ (linenr_T)MAXLNUM);
+ curwin->w_set_curswant = TRUE;
+ }
+ } else
+ /*
+ * "[{", "[(", "]}" or "])": go to Nth unclosed '{', '(', '}' or ')'
+ * "[#", "]#": go to start/end of Nth innermost #if..#endif construct.
+ * "[/", "[*", "]/", "]*": go to Nth comment start/end.
+ * "[m" or "]m" search for prev/next start of (Java) method.
+ * "[M" or "]M" search for prev/next end of (Java) method.
+ */
+ if ( (cap->cmdchar == '['
+ && vim_strchr((char_u *)"{(*/#mM", cap->nchar) != NULL)
+ || (cap->cmdchar == ']'
+ && vim_strchr((char_u *)"})*/#mM", cap->nchar) != NULL)) {
+ if (cap->nchar == '*')
+ cap->nchar = '/';
+ prev_pos.lnum = 0;
+ if (cap->nchar == 'm' || cap->nchar == 'M') {
+ if (cap->cmdchar == '[')
+ findc = '{';
+ else
+ findc = '}';
+ n = 9999;
+ } else {
+ findc = cap->nchar;
+ n = cap->count1;
+ }
+ for (; n > 0; --n) {
+ if ((pos = findmatchlimit(cap->oap, findc,
+ (cap->cmdchar == '[') ? FM_BACKWARD : FM_FORWARD, 0)) == NULL) {
+ if (new_pos.lnum == 0) { /* nothing found */
+ if (cap->nchar != 'm' && cap->nchar != 'M')
+ clearopbeep(cap->oap);
+ } else
+ pos = &new_pos; /* use last one found */
+ break;
+ }
+ prev_pos = new_pos;
+ curwin->w_cursor = *pos;
+ new_pos = *pos;
+ }
+ curwin->w_cursor = old_pos;
+
+ /*
+ * Handle "[m", "]m", "[M" and "[M". The findmatchlimit() only
+ * brought us to the match for "[m" and "]M" when inside a method.
+ * Try finding the '{' or '}' we want to be at.
+ * Also repeat for the given count.
+ */
+ if (cap->nchar == 'm' || cap->nchar == 'M') {
+ /* norm is TRUE for "]M" and "[m" */
+ int norm = ((findc == '{') == (cap->nchar == 'm'));
+
+ n = cap->count1;
+ /* found a match: we were inside a method */
+ if (prev_pos.lnum != 0) {
+ pos = &prev_pos;
+ curwin->w_cursor = prev_pos;
+ if (norm)
+ --n;
+ } else
+ pos = NULL;
+ while (n > 0) {
+ for (;; ) {
+ if ((findc == '{' ? dec_cursor() : inc_cursor()) < 0) {
+ /* if not found anything, that's an error */
+ if (pos == NULL)
+ clearopbeep(cap->oap);
+ n = 0;
+ break;
+ }
+ c = gchar_cursor();
+ if (c == '{' || c == '}') {
+ /* Must have found end/start of class: use it.
+ * Or found the place to be at. */
+ if ((c == findc && norm) || (n == 1 && !norm)) {
+ new_pos = curwin->w_cursor;
+ pos = &new_pos;
+ n = 0;
+ }
+ /* if no match found at all, we started outside of the
+ * class and we're inside now. Just go on. */
+ else if (new_pos.lnum == 0) {
+ new_pos = curwin->w_cursor;
+ pos = &new_pos;
+ }
+ /* found start/end of other method: go to match */
+ else if ((pos = findmatchlimit(cap->oap, findc,
+ (cap->cmdchar == '[') ? FM_BACKWARD : FM_FORWARD,
+ 0)) == NULL)
+ n = 0;
+ else
+ curwin->w_cursor = *pos;
+ break;
+ }
+ }
+ --n;
+ }
+ curwin->w_cursor = old_pos;
+ if (pos == NULL && new_pos.lnum != 0)
+ clearopbeep(cap->oap);
+ }
+ if (pos != NULL) {
+ setpcmark();
+ curwin->w_cursor = *pos;
+ curwin->w_set_curswant = TRUE;
+ if ((fdo_flags & FDO_BLOCK) && KeyTyped
+ && cap->oap->op_type == OP_NOP)
+ foldOpenCursor();
+ }
+ }
+ /*
+ * "[[", "[]", "]]" and "][": move to start or end of function
+ */
+ else if (cap->nchar == '[' || cap->nchar == ']') {
+ if (cap->nchar == cap->cmdchar) /* "]]" or "[[" */
+ flag = '{';
+ else
+ flag = '}'; /* "][" or "[]" */
+
+ curwin->w_set_curswant = TRUE;
+ /*
+ * Imitate strange Vi behaviour: When using "]]" with an operator
+ * we also stop at '}'.
+ */
+ if (!findpar(&cap->oap->inclusive, cap->arg, cap->count1, flag,
+ (cap->oap->op_type != OP_NOP
+ && cap->arg == FORWARD && flag == '{')))
+ clearopbeep(cap->oap);
+ else {
+ if (cap->oap->op_type == OP_NOP)
+ beginline(BL_WHITE | BL_FIX);
+ if ((fdo_flags & FDO_BLOCK) && KeyTyped && cap->oap->op_type == OP_NOP)
+ foldOpenCursor();
+ }
+ }
+ /*
+ * "[p", "[P", "]P" and "]p": put with indent adjustment
+ */
+ else if (cap->nchar == 'p' || cap->nchar == 'P') {
+ if (!checkclearop(cap->oap)) {
+ prep_redo_cmd(cap);
+ do_put(cap->oap->regname,
+ (cap->cmdchar == ']' && cap->nchar == 'p') ? FORWARD : BACKWARD,
+ cap->count1, PUT_FIXINDENT);
+ }
+ }
+ /*
+ * "['", "[`", "]'" and "]`": jump to next mark
+ */
+ else if (cap->nchar == '\'' || cap->nchar == '`') {
+ pos = &curwin->w_cursor;
+ for (n = cap->count1; n > 0; --n) {
+ prev_pos = *pos;
+ pos = getnextmark(pos, cap->cmdchar == '[' ? BACKWARD : FORWARD,
+ cap->nchar == '\'');
+ if (pos == NULL)
+ break;
+ }
+ if (pos == NULL)
+ pos = &prev_pos;
+ nv_cursormark(cap, cap->nchar == '\'', pos);
+ }
+ /*
+ * [ or ] followed by a middle mouse click: put selected text with
+ * indent adjustment. Any other button just does as usual.
+ */
+ else if (cap->nchar >= K_RIGHTRELEASE && cap->nchar <= K_LEFTMOUSE) {
+ (void)do_mouse(cap->oap, cap->nchar,
+ (cap->cmdchar == ']') ? FORWARD : BACKWARD,
+ cap->count1, PUT_FIXINDENT);
+ }
+ /*
+ * "[z" and "]z": move to start or end of open fold.
+ */
+ else if (cap->nchar == 'z') {
+ if (foldMoveTo(FALSE, cap->cmdchar == ']' ? FORWARD : BACKWARD,
+ cap->count1) == FAIL)
+ clearopbeep(cap->oap);
+ }
+ /*
+ * "[c" and "]c": move to next or previous diff-change.
+ */
+ else if (cap->nchar == 'c') {
+ if (diff_move_to(cap->cmdchar == ']' ? FORWARD : BACKWARD,
+ cap->count1) == FAIL)
+ clearopbeep(cap->oap);
+ }
+ /*
+ * "[s", "[S", "]s" and "]S": move to next spell error.
+ */
+ else if (cap->nchar == 's' || cap->nchar == 'S') {
+ setpcmark();
+ for (n = 0; n < cap->count1; ++n)
+ if (spell_move_to(curwin, cap->cmdchar == ']' ? FORWARD : BACKWARD,
+ cap->nchar == 's' ? TRUE : FALSE, FALSE, NULL) == 0) {
+ clearopbeep(cap->oap);
+ break;
+ }
+ if (cap->oap->op_type == OP_NOP && (fdo_flags & FDO_SEARCH) && KeyTyped)
+ foldOpenCursor();
+ }
+ /* Not a valid cap->nchar. */
+ else
+ clearopbeep(cap->oap);
+}
+
+/*
+ * Handle Normal mode "%" command.
+ */
+static void nv_percent(cap)
+cmdarg_T *cap;
+{
+ pos_T *pos;
+ linenr_T lnum = curwin->w_cursor.lnum;
+
+ cap->oap->inclusive = TRUE;
+ if (cap->count0) { /* {cnt}% : goto {cnt} percentage in file */
+ if (cap->count0 > 100)
+ clearopbeep(cap->oap);
+ else {
+ cap->oap->motion_type = MLINE;
+ setpcmark();
+ /* Round up, so CTRL-G will give same value. Watch out for a
+ * large line count, the line number must not go negative! */
+ if (curbuf->b_ml.ml_line_count > 1000000)
+ curwin->w_cursor.lnum = (curbuf->b_ml.ml_line_count + 99L)
+ / 100L * cap->count0;
+ else
+ curwin->w_cursor.lnum = (curbuf->b_ml.ml_line_count *
+ cap->count0 + 99L) / 100L;
+ if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count)
+ curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
+ beginline(BL_SOL | BL_FIX);
+ }
+ } else { /* "%" : go to matching paren */
+ cap->oap->motion_type = MCHAR;
+ cap->oap->use_reg_one = TRUE;
+ if ((pos = findmatch(cap->oap, NUL)) == NULL)
+ clearopbeep(cap->oap);
+ else {
+ setpcmark();
+ curwin->w_cursor = *pos;
+ curwin->w_set_curswant = TRUE;
+ curwin->w_cursor.coladd = 0;
+ adjust_for_sel(cap);
+ }
+ }
+ if (cap->oap->op_type == OP_NOP
+ && lnum != curwin->w_cursor.lnum
+ && (fdo_flags & FDO_PERCENT)
+ && KeyTyped)
+ foldOpenCursor();
+}
+
+/*
+ * Handle "(" and ")" commands.
+ * cap->arg is BACKWARD for "(" and FORWARD for ")".
+ */
+static void nv_brace(cap)
+cmdarg_T *cap;
+{
+ cap->oap->motion_type = MCHAR;
+ cap->oap->use_reg_one = TRUE;
+ /* The motion used to be inclusive for "(", but that is not what Vi does. */
+ cap->oap->inclusive = FALSE;
+ curwin->w_set_curswant = TRUE;
+
+ if (findsent(cap->arg, cap->count1) == FAIL)
+ clearopbeep(cap->oap);
+ else {
+ /* Don't leave the cursor on the NUL past end of line. */
+ adjust_cursor(cap->oap);
+ curwin->w_cursor.coladd = 0;
+ if ((fdo_flags & FDO_BLOCK) && KeyTyped && cap->oap->op_type == OP_NOP)
+ foldOpenCursor();
+ }
+}
+
+/*
+ * "m" command: Mark a position.
+ */
+static void nv_mark(cap)
+cmdarg_T *cap;
+{
+ if (!checkclearop(cap->oap)) {
+ if (setmark(cap->nchar) == FAIL)
+ clearopbeep(cap->oap);
+ }
+}
+
+/*
+ * "{" and "}" commands.
+ * cmd->arg is BACKWARD for "{" and FORWARD for "}".
+ */
+static void nv_findpar(cap)
+cmdarg_T *cap;
+{
+ cap->oap->motion_type = MCHAR;
+ cap->oap->inclusive = FALSE;
+ cap->oap->use_reg_one = TRUE;
+ curwin->w_set_curswant = TRUE;
+ if (!findpar(&cap->oap->inclusive, cap->arg, cap->count1, NUL, FALSE))
+ clearopbeep(cap->oap);
+ else {
+ curwin->w_cursor.coladd = 0;
+ if ((fdo_flags & FDO_BLOCK) && KeyTyped && cap->oap->op_type == OP_NOP)
+ foldOpenCursor();
+ }
+}
+
+/*
+ * "u" command: Undo or make lower case.
+ */
+static void nv_undo(cap)
+cmdarg_T *cap;
+{
+ if (cap->oap->op_type == OP_LOWER
+ || VIsual_active
+ ) {
+ /* translate "<Visual>u" to "<Visual>gu" and "guu" to "gugu" */
+ cap->cmdchar = 'g';
+ cap->nchar = 'u';
+ nv_operator(cap);
+ } else
+ nv_kundo(cap);
+}
+
+/*
+ * <Undo> command.
+ */
+static void nv_kundo(cap)
+cmdarg_T *cap;
+{
+ if (!checkclearopq(cap->oap)) {
+ u_undo((int)cap->count1);
+ curwin->w_set_curswant = TRUE;
+ }
+}
+
+/*
+ * Handle the "r" command.
+ */
+static void nv_replace(cap)
+cmdarg_T *cap;
+{
+ char_u *ptr;
+ int had_ctrl_v;
+ long n;
+
+ if (checkclearop(cap->oap))
+ return;
+
+ /* get another character */
+ if (cap->nchar == Ctrl_V) {
+ had_ctrl_v = Ctrl_V;
+ cap->nchar = get_literal();
+ /* Don't redo a multibyte character with CTRL-V. */
+ if (cap->nchar > DEL)
+ had_ctrl_v = NUL;
+ } else
+ had_ctrl_v = NUL;
+
+ /* Abort if the character is a special key. */
+ if (IS_SPECIAL(cap->nchar)) {
+ clearopbeep(cap->oap);
+ return;
+ }
+
+ /* Visual mode "r" */
+ if (VIsual_active) {
+ if (got_int)
+ reset_VIsual();
+ if (had_ctrl_v) {
+ if (cap->nchar == '\r')
+ cap->nchar = -1;
+ else if (cap->nchar == '\n')
+ cap->nchar = -2;
+ }
+ nv_operator(cap);
+ return;
+ }
+
+ /* Break tabs, etc. */
+ if (virtual_active()) {
+ if (u_save_cursor() == FAIL)
+ return;
+ if (gchar_cursor() == NUL) {
+ /* Add extra space and put the cursor on the first one. */
+ coladvance_force((colnr_T)(getviscol() + cap->count1));
+ curwin->w_cursor.col -= cap->count1;
+ } else if (gchar_cursor() == TAB)
+ coladvance_force(getviscol());
+ }
+
+ /* Abort if not enough characters to replace. */
+ ptr = ml_get_cursor();
+ if (STRLEN(ptr) < (unsigned)cap->count1
+ || (has_mbyte && mb_charlen(ptr) < cap->count1)
+ ) {
+ clearopbeep(cap->oap);
+ return;
+ }
+
+ /*
+ * Replacing with a TAB is done by edit() when it is complicated because
+ * 'expandtab' or 'smarttab' is set. CTRL-V TAB inserts a literal TAB.
+ * Other characters are done below to avoid problems with things like
+ * CTRL-V 048 (for edit() this would be R CTRL-V 0 ESC).
+ */
+ if (had_ctrl_v != Ctrl_V && cap->nchar == '\t' &&
+ (curbuf->b_p_et || p_sta)) {
+ stuffnumReadbuff(cap->count1);
+ stuffcharReadbuff('R');
+ stuffcharReadbuff('\t');
+ stuffcharReadbuff(ESC);
+ return;
+ }
+
+ /* save line for undo */
+ if (u_save_cursor() == FAIL)
+ return;
+
+ if (had_ctrl_v != Ctrl_V && (cap->nchar == '\r' || cap->nchar == '\n')) {
+ /*
+ * Replace character(s) by a single newline.
+ * Strange vi behaviour: Only one newline is inserted.
+ * Delete the characters here.
+ * Insert the newline with an insert command, takes care of
+ * autoindent. The insert command depends on being on the last
+ * character of a line or not.
+ */
+ (void)del_chars(cap->count1, FALSE); /* delete the characters */
+ stuffcharReadbuff('\r');
+ stuffcharReadbuff(ESC);
+
+ /* Give 'r' to edit(), to get the redo command right. */
+ invoke_edit(cap, TRUE, 'r', FALSE);
+ } else {
+ prep_redo(cap->oap->regname, cap->count1,
+ NUL, 'r', NUL, had_ctrl_v, cap->nchar);
+
+ curbuf->b_op_start = curwin->w_cursor;
+ if (has_mbyte) {
+ int old_State = State;
+
+ if (cap->ncharC1 != 0)
+ AppendCharToRedobuff(cap->ncharC1);
+ if (cap->ncharC2 != 0)
+ AppendCharToRedobuff(cap->ncharC2);
+
+ /* This is slow, but it handles replacing a single-byte with a
+ * multi-byte and the other way around. Also handles adding
+ * composing characters for utf-8. */
+ for (n = cap->count1; n > 0; --n) {
+ State = REPLACE;
+ if (cap->nchar == Ctrl_E || cap->nchar == Ctrl_Y) {
+ int c = ins_copychar(curwin->w_cursor.lnum
+ + (cap->nchar == Ctrl_Y ? -1 : 1));
+ if (c != NUL)
+ ins_char(c);
+ else
+ /* will be decremented further down */
+ ++curwin->w_cursor.col;
+ } else
+ ins_char(cap->nchar);
+ State = old_State;
+ if (cap->ncharC1 != 0)
+ ins_char(cap->ncharC1);
+ if (cap->ncharC2 != 0)
+ ins_char(cap->ncharC2);
+ }
+ } else {
+ /*
+ * Replace the characters within one line.
+ */
+ for (n = cap->count1; n > 0; --n) {
+ /*
+ * Get ptr again, because u_save and/or showmatch() will have
+ * released the line. At the same time we let know that the
+ * line will be changed.
+ */
+ ptr = ml_get_buf(curbuf, curwin->w_cursor.lnum, TRUE);
+ if (cap->nchar == Ctrl_E || cap->nchar == Ctrl_Y) {
+ int c = ins_copychar(curwin->w_cursor.lnum
+ + (cap->nchar == Ctrl_Y ? -1 : 1));
+ if (c != NUL)
+ ptr[curwin->w_cursor.col] = c;
+ } else
+ ptr[curwin->w_cursor.col] = cap->nchar;
+ if (p_sm && msg_silent == 0)
+ showmatch(cap->nchar);
+ ++curwin->w_cursor.col;
+ }
+
+ /* mark the buffer as changed and prepare for displaying */
+ changed_bytes(curwin->w_cursor.lnum,
+ (colnr_T)(curwin->w_cursor.col - cap->count1));
+ }
+ --curwin->w_cursor.col; /* cursor on the last replaced char */
+ /* if the character on the left of the current cursor is a multi-byte
+ * character, move two characters left */
+ if (has_mbyte)
+ mb_adjust_cursor();
+ curbuf->b_op_end = curwin->w_cursor;
+ curwin->w_set_curswant = TRUE;
+ set_last_insert(cap->nchar);
+ }
+}
+
+/*
+ * 'o': Exchange start and end of Visual area.
+ * 'O': same, but in block mode exchange left and right corners.
+ */
+static void v_swap_corners(cmdchar)
+int cmdchar;
+{
+ pos_T old_cursor;
+ colnr_T left, right;
+
+ if (cmdchar == 'O' && VIsual_mode == Ctrl_V) {
+ old_cursor = curwin->w_cursor;
+ getvcols(curwin, &old_cursor, &VIsual, &left, &right);
+ curwin->w_cursor.lnum = VIsual.lnum;
+ coladvance(left);
+ VIsual = curwin->w_cursor;
+
+ curwin->w_cursor.lnum = old_cursor.lnum;
+ curwin->w_curswant = right;
+ /* 'selection "exclusive" and cursor at right-bottom corner: move it
+ * right one column */
+ if (old_cursor.lnum >= VIsual.lnum && *p_sel == 'e')
+ ++curwin->w_curswant;
+ coladvance(curwin->w_curswant);
+ if (curwin->w_cursor.col == old_cursor.col
+ && (!virtual_active()
+ || curwin->w_cursor.coladd == old_cursor.coladd)
+ ) {
+ curwin->w_cursor.lnum = VIsual.lnum;
+ if (old_cursor.lnum <= VIsual.lnum && *p_sel == 'e')
+ ++right;
+ coladvance(right);
+ VIsual = curwin->w_cursor;
+
+ curwin->w_cursor.lnum = old_cursor.lnum;
+ coladvance(left);
+ curwin->w_curswant = left;
+ }
+ } else {
+ old_cursor = curwin->w_cursor;
+ curwin->w_cursor = VIsual;
+ VIsual = old_cursor;
+ curwin->w_set_curswant = TRUE;
+ }
+}
+
+/*
+ * "R" (cap->arg is FALSE) and "gR" (cap->arg is TRUE).
+ */
+static void nv_Replace(cap)
+cmdarg_T *cap;
+{
+ if (VIsual_active) { /* "R" is replace lines */
+ cap->cmdchar = 'c';
+ cap->nchar = NUL;
+ VIsual_mode_orig = VIsual_mode; /* remember original area for gv */
+ VIsual_mode = 'V';
+ nv_operator(cap);
+ } else if (!checkclearopq(cap->oap)) {
+ if (!curbuf->b_p_ma)
+ EMSG(_(e_modifiable));
+ else {
+ if (virtual_active())
+ coladvance(getviscol());
+ invoke_edit(cap, FALSE, cap->arg ? 'V' : 'R', FALSE);
+ }
+ }
+}
+
+/*
+ * "gr".
+ */
+static void nv_vreplace(cap)
+cmdarg_T *cap;
+{
+ if (VIsual_active) {
+ cap->cmdchar = 'r';
+ cap->nchar = cap->extra_char;
+ nv_replace(cap); /* Do same as "r" in Visual mode for now */
+ } else if (!checkclearopq(cap->oap)) {
+ if (!curbuf->b_p_ma)
+ EMSG(_(e_modifiable));
+ else {
+ if (cap->extra_char == Ctrl_V) /* get another character */
+ cap->extra_char = get_literal();
+ stuffcharReadbuff(cap->extra_char);
+ stuffcharReadbuff(ESC);
+ if (virtual_active())
+ coladvance(getviscol());
+ invoke_edit(cap, TRUE, 'v', FALSE);
+ }
+ }
+}
+
+/*
+ * Swap case for "~" command, when it does not work like an operator.
+ */
+static void n_swapchar(cap)
+cmdarg_T *cap;
+{
+ long n;
+ pos_T startpos;
+ int did_change = 0;
+
+ if (checkclearopq(cap->oap))
+ return;
+
+ if (lineempty(curwin->w_cursor.lnum) && vim_strchr(p_ww, '~') == NULL) {
+ clearopbeep(cap->oap);
+ return;
+ }
+
+ prep_redo_cmd(cap);
+
+ if (u_save_cursor() == FAIL)
+ return;
+
+ startpos = curwin->w_cursor;
+ for (n = cap->count1; n > 0; --n) {
+ did_change |= swapchar(cap->oap->op_type, &curwin->w_cursor);
+ inc_cursor();
+ if (gchar_cursor() == NUL) {
+ if (vim_strchr(p_ww, '~') != NULL
+ && curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count) {
+ ++curwin->w_cursor.lnum;
+ curwin->w_cursor.col = 0;
+ if (n > 1) {
+ if (u_savesub(curwin->w_cursor.lnum) == FAIL)
+ break;
+ u_clearline();
+ }
+ } else
+ break;
+ }
+ }
+
+
+ check_cursor();
+ curwin->w_set_curswant = TRUE;
+ if (did_change) {
+ changed_lines(startpos.lnum, startpos.col, curwin->w_cursor.lnum + 1,
+ 0L);
+ curbuf->b_op_start = startpos;
+ curbuf->b_op_end = curwin->w_cursor;
+ if (curbuf->b_op_end.col > 0)
+ --curbuf->b_op_end.col;
+ }
+}
+
+/*
+ * Move cursor to mark.
+ */
+static void nv_cursormark(cap, flag, pos)
+cmdarg_T *cap;
+int flag;
+pos_T *pos;
+{
+ if (check_mark(pos) == FAIL)
+ clearop(cap->oap);
+ else {
+ if (cap->cmdchar == '\''
+ || cap->cmdchar == '`'
+ || cap->cmdchar == '['
+ || cap->cmdchar == ']')
+ setpcmark();
+ curwin->w_cursor = *pos;
+ if (flag)
+ beginline(BL_WHITE | BL_FIX);
+ else
+ check_cursor();
+ }
+ cap->oap->motion_type = flag ? MLINE : MCHAR;
+ if (cap->cmdchar == '`')
+ cap->oap->use_reg_one = TRUE;
+ cap->oap->inclusive = FALSE; /* ignored if not MCHAR */
+ curwin->w_set_curswant = TRUE;
+}
+
+/*
+ * Handle commands that are operators in Visual mode.
+ */
+static void v_visop(cap)
+cmdarg_T *cap;
+{
+ static char_u trans[] = "YyDdCcxdXdAAIIrr";
+
+ /* Uppercase means linewise, except in block mode, then "D" deletes till
+ * the end of the line, and "C" replaces till EOL */
+ if (isupper(cap->cmdchar)) {
+ if (VIsual_mode != Ctrl_V) {
+ VIsual_mode_orig = VIsual_mode;
+ VIsual_mode = 'V';
+ } else if (cap->cmdchar == 'C' || cap->cmdchar == 'D')
+ curwin->w_curswant = MAXCOL;
+ }
+ cap->cmdchar = *(vim_strchr(trans, cap->cmdchar) + 1);
+ nv_operator(cap);
+}
+
+/*
+ * "s" and "S" commands.
+ */
+static void nv_subst(cap)
+cmdarg_T *cap;
+{
+ if (VIsual_active) { /* "vs" and "vS" are the same as "vc" */
+ if (cap->cmdchar == 'S') {
+ VIsual_mode_orig = VIsual_mode;
+ VIsual_mode = 'V';
+ }
+ cap->cmdchar = 'c';
+ nv_operator(cap);
+ } else
+ nv_optrans(cap);
+}
+
+/*
+ * Abbreviated commands.
+ */
+static void nv_abbrev(cap)
+cmdarg_T *cap;
+{
+ if (cap->cmdchar == K_DEL || cap->cmdchar == K_KDEL)
+ cap->cmdchar = 'x'; /* DEL key behaves like 'x' */
+
+ /* in Visual mode these commands are operators */
+ if (VIsual_active)
+ v_visop(cap);
+ else
+ nv_optrans(cap);
+}
+
+/*
+ * Translate a command into another command.
+ */
+static void nv_optrans(cap)
+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&";
+
+ if (!checkclearopq(cap->oap)) {
+ /* In Vi "2D" doesn't delete the next line. Can't translate it
+ * either, because "2." should also not use the count. */
+ if (cap->cmdchar == 'D' && vim_strchr(p_cpo, CPO_HASH) != NULL) {
+ cap->oap->start = curwin->w_cursor;
+ cap->oap->op_type = OP_DELETE;
+ set_op_var(OP_DELETE);
+ cap->count1 = 1;
+ nv_dollar(cap);
+ finish_op = TRUE;
+ ResetRedobuff();
+ AppendCharToRedobuff('D');
+ } else {
+ if (cap->count0)
+ stuffnumReadbuff(cap->count0);
+ stuffReadbuff(ar[(int)(vim_strchr(str, cap->cmdchar) - str)]);
+ }
+ }
+ cap->opcount = 0;
+}
+
+/*
+ * "'" and "`" commands. Also for "g'" and "g`".
+ * cap->arg is TRUE for "'" and "g'".
+ */
+static void nv_gomark(cap)
+cmdarg_T *cap;
+{
+ pos_T *pos;
+ int c;
+ pos_T old_cursor = curwin->w_cursor;
+ int old_KeyTyped = KeyTyped; /* getting file may reset it */
+
+ if (cap->cmdchar == 'g')
+ c = cap->extra_char;
+ else
+ c = cap->nchar;
+ pos = getmark(c, (cap->oap->op_type == OP_NOP));
+ if (pos == (pos_T *)-1) { /* jumped to other file */
+ if (cap->arg) {
+ check_cursor_lnum();
+ beginline(BL_WHITE | BL_FIX);
+ } else
+ check_cursor();
+ } else
+ nv_cursormark(cap, cap->arg, pos);
+
+ /* May need to clear the coladd that a mark includes. */
+ if (!virtual_active())
+ curwin->w_cursor.coladd = 0;
+ if (cap->oap->op_type == OP_NOP
+ && pos != NULL
+ && (pos == (pos_T *)-1 || !equalpos(old_cursor, *pos))
+ && (fdo_flags & FDO_MARK)
+ && old_KeyTyped)
+ foldOpenCursor();
+}
+
+/*
+ * Handle CTRL-O, CTRL-I, "g;" and "g," commands.
+ */
+static void nv_pcmark(cap)
+cmdarg_T *cap;
+{
+ pos_T *pos;
+ linenr_T lnum = curwin->w_cursor.lnum;
+ int old_KeyTyped = KeyTyped; /* getting file may reset it */
+
+ if (!checkclearopq(cap->oap)) {
+ if (cap->cmdchar == 'g')
+ pos = movechangelist((int)cap->count1);
+ else
+ pos = movemark((int)cap->count1);
+ if (pos == (pos_T *)-1) { /* jump to other file */
+ curwin->w_set_curswant = TRUE;
+ check_cursor();
+ } else if (pos != NULL) /* can jump */
+ nv_cursormark(cap, FALSE, pos);
+ else if (cap->cmdchar == 'g') {
+ if (curbuf->b_changelistlen == 0)
+ EMSG(_("E664: changelist is empty"));
+ else if (cap->count1 < 0)
+ EMSG(_("E662: At start of changelist"));
+ else
+ EMSG(_("E663: At end of changelist"));
+ } else
+ clearopbeep(cap->oap);
+ if (cap->oap->op_type == OP_NOP
+ && (pos == (pos_T *)-1 || lnum != curwin->w_cursor.lnum)
+ && (fdo_flags & FDO_MARK)
+ && old_KeyTyped)
+ foldOpenCursor();
+ }
+}
+
+/*
+ * Handle '"' command.
+ */
+static void nv_regname(cap)
+cmdarg_T *cap;
+{
+ if (checkclearop(cap->oap))
+ return;
+ if (cap->nchar == '=')
+ cap->nchar = get_expr_register();
+ if (cap->nchar != NUL && valid_yank_reg(cap->nchar, FALSE)) {
+ cap->oap->regname = cap->nchar;
+ cap->opcount = cap->count0; /* remember count before '"' */
+ set_reg_var(cap->oap->regname);
+ } else
+ clearopbeep(cap->oap);
+}
+
+/*
+ * Handle "v", "V" and "CTRL-V" commands.
+ * Also for "gh", "gH" and "g^H" commands: Always start Select mode, cap->arg
+ * is TRUE.
+ * Handle CTRL-Q just like CTRL-V.
+ */
+static void nv_visual(cap)
+cmdarg_T *cap;
+{
+ if (cap->cmdchar == Ctrl_Q)
+ cap->cmdchar = Ctrl_V;
+
+ /* '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 */
+ return;
+ }
+
+ VIsual_select = cap->arg;
+ if (VIsual_active) { /* change Visual mode */
+ if (VIsual_mode == cap->cmdchar) /* stop visual mode */
+ end_visual_mode();
+ else { /* toggle char/block mode */
+ /* or char/line mode */
+ VIsual_mode = cap->cmdchar;
+ showmode();
+ }
+ redraw_curbuf_later(INVERTED); /* update the inversion */
+ } else { /* start Visual mode */
+ check_visual_highlight();
+ if (cap->count0 > 0 && resel_VIsual_mode != NUL) {
+ /* use previously selected part */
+ VIsual = curwin->w_cursor;
+
+ VIsual_active = TRUE;
+ VIsual_reselect = TRUE;
+ if (!cap->arg)
+ /* start Select mode when 'selectmode' contains "cmd" */
+ may_start_select('c');
+ setmouse();
+ if (p_smd && msg_silent == 0)
+ redraw_cmdline = TRUE; /* show visual mode later */
+ /*
+ * For V and ^V, we multiply the number of lines even if there
+ * was only one -- webb
+ */
+ if (resel_VIsual_mode != 'v' || resel_VIsual_line_count > 1) {
+ curwin->w_cursor.lnum +=
+ resel_VIsual_line_count * cap->count0 - 1;
+ if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count)
+ curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
+ }
+ VIsual_mode = resel_VIsual_mode;
+ if (VIsual_mode == 'v') {
+ if (resel_VIsual_line_count <= 1) {
+ validate_virtcol();
+ curwin->w_curswant = curwin->w_virtcol
+ + resel_VIsual_vcol * cap->count0 - 1;
+ } else
+ curwin->w_curswant = resel_VIsual_vcol;
+ coladvance(curwin->w_curswant);
+ }
+ if (resel_VIsual_vcol == MAXCOL) {
+ curwin->w_curswant = MAXCOL;
+ coladvance((colnr_T)MAXCOL);
+ } else if (VIsual_mode == Ctrl_V) {
+ validate_virtcol();
+ curwin->w_curswant = curwin->w_virtcol
+ + resel_VIsual_vcol * cap->count0 - 1;
+ coladvance(curwin->w_curswant);
+ } else
+ curwin->w_set_curswant = TRUE;
+ redraw_curbuf_later(INVERTED); /* show the inversion */
+ } else {
+ if (!cap->arg)
+ /* start Select mode when 'selectmode' contains "cmd" */
+ may_start_select('c');
+ n_start_visual_mode(cap->cmdchar);
+ if (VIsual_mode != 'V' && *p_sel == 'e')
+ ++cap->count1; /* include one more char */
+ if (cap->count0 > 0 && --cap->count1 > 0) {
+ /* With a count select that many characters or lines. */
+ if (VIsual_mode == 'v' || VIsual_mode == Ctrl_V)
+ nv_right(cap);
+ else if (VIsual_mode == 'V')
+ nv_down(cap);
+ }
+ }
+ }
+}
+
+/*
+ * Start selection for Shift-movement keys.
+ */
+void start_selection() {
+ /* if 'selectmode' contains "key", start Select mode */
+ may_start_select('k');
+ n_start_visual_mode('v');
+}
+
+/*
+ * Start Select mode, if "c" is in 'selectmode' and not in a mapping or menu.
+ */
+void may_start_select(c)
+int c;
+{
+ VIsual_select = (stuff_empty() && typebuf_typed()
+ && (vim_strchr(p_slm, c) != NULL));
+}
+
+/*
+ * Start Visual mode "c".
+ * Should set VIsual_select before calling this.
+ */
+static void n_start_visual_mode(c)
+int c;
+{
+ /* Check for redraw before changing the state. */
+ conceal_check_cursur_line();
+
+ VIsual_mode = c;
+ VIsual_active = TRUE;
+ VIsual_reselect = TRUE;
+ /* Corner case: the 0 position in a tab may change when going into
+ * virtualedit. Recalculate curwin->w_cursor to avoid bad hilighting.
+ */
+ if (c == Ctrl_V && (ve_flags & VE_BLOCK) && gchar_cursor() == TAB) {
+ validate_virtcol();
+ coladvance(curwin->w_virtcol);
+ }
+ VIsual = curwin->w_cursor;
+
+ foldAdjustVisual();
+
+ setmouse();
+ /* Check for redraw after changing the state. */
+ conceal_check_cursur_line();
+
+ if (p_smd && msg_silent == 0)
+ redraw_cmdline = TRUE; /* show visual mode later */
+
+ /* Only need to redraw this line, unless still need to redraw an old
+ * Visual area (when 'lazyredraw' is set). */
+ if (curwin->w_redr_type < INVERTED) {
+ curwin->w_old_cursor_lnum = curwin->w_cursor.lnum;
+ curwin->w_old_visual_lnum = curwin->w_cursor.lnum;
+ }
+}
+
+
+/*
+ * CTRL-W: Window commands
+ */
+static void nv_window(cap)
+cmdarg_T *cap;
+{
+ if (!checkclearop(cap->oap))
+ do_window(cap->nchar, cap->count0, NUL); /* everything is in window.c */
+}
+
+/*
+ * CTRL-Z: Suspend
+ */
+static void nv_suspend(cap)
+cmdarg_T *cap;
+{
+ clearop(cap->oap);
+ if (VIsual_active)
+ end_visual_mode(); /* stop Visual mode */
+ do_cmdline_cmd((char_u *)"st");
+}
+
+/*
+ * Commands starting with "g".
+ */
+static void nv_g_cmd(cap)
+cmdarg_T *cap;
+{
+ oparg_T *oap = cap->oap;
+ pos_T tpos;
+ int i;
+ int flag = FALSE;
+
+ switch (cap->nchar) {
+#ifdef MEM_PROFILE
+ /*
+ * "g^A": dump log of used memory.
+ */
+ case Ctrl_A:
+ vim_mem_profile_dump();
+ break;
+#endif
+
+ /*
+ * "gR": Enter virtual replace mode.
+ */
+ case 'R':
+ cap->arg = TRUE;
+ nv_Replace(cap);
+ break;
+
+ case 'r':
+ nv_vreplace(cap);
+ break;
+
+ case '&':
+ do_cmdline_cmd((char_u *)"%s//~/&");
+ break;
+
+ /*
+ * "gv": Reselect the previous Visual area. If Visual already active,
+ * exchange previous and current Visual area.
+ */
+ case 'v':
+ if (checkclearop(oap))
+ break;
+
+ if ( curbuf->b_visual.vi_start.lnum == 0
+ || curbuf->b_visual.vi_start.lnum > curbuf->b_ml.ml_line_count
+ || curbuf->b_visual.vi_end.lnum == 0)
+ beep_flush();
+ else {
+ /* set w_cursor to the start of the Visual area, tpos to the end */
+ if (VIsual_active) {
+ i = VIsual_mode;
+ VIsual_mode = curbuf->b_visual.vi_mode;
+ curbuf->b_visual.vi_mode = i;
+ curbuf->b_visual_mode_eval = i;
+ i = curwin->w_curswant;
+ curwin->w_curswant = curbuf->b_visual.vi_curswant;
+ curbuf->b_visual.vi_curswant = i;
+
+ tpos = curbuf->b_visual.vi_end;
+ curbuf->b_visual.vi_end = curwin->w_cursor;
+ curwin->w_cursor = curbuf->b_visual.vi_start;
+ curbuf->b_visual.vi_start = VIsual;
+ } else {
+ VIsual_mode = curbuf->b_visual.vi_mode;
+ curwin->w_curswant = curbuf->b_visual.vi_curswant;
+ tpos = curbuf->b_visual.vi_end;
+ curwin->w_cursor = curbuf->b_visual.vi_start;
+ }
+
+ VIsual_active = TRUE;
+ VIsual_reselect = TRUE;
+
+ /* Set Visual to the start and w_cursor to the end of the Visual
+ * area. Make sure they are on an existing character. */
+ check_cursor();
+ VIsual = curwin->w_cursor;
+ curwin->w_cursor = tpos;
+ check_cursor();
+ update_topline();
+ /*
+ * When called from normal "g" command: start Select mode when
+ * 'selectmode' contains "cmd". When called for K_SELECT, always
+ * start Select mode.
+ */
+ if (cap->arg)
+ VIsual_select = TRUE;
+ else
+ may_start_select('c');
+ setmouse();
+ redraw_curbuf_later(INVERTED);
+ showmode();
+ }
+ break;
+ /*
+ * "gV": Don't reselect the previous Visual area after a Select mode
+ * mapping of menu.
+ */
+ case 'V':
+ VIsual_reselect = FALSE;
+ break;
+
+ /*
+ * "gh": start Select mode.
+ * "gH": start Select line mode.
+ * "g^H": start Select block mode.
+ */
+ case K_BS:
+ cap->nchar = Ctrl_H;
+ /* FALLTHROUGH */
+ case 'h':
+ case 'H':
+ case Ctrl_H:
+ cap->cmdchar = cap->nchar + ('v' - 'h');
+ cap->arg = TRUE;
+ nv_visual(cap);
+ break;
+
+ /* "gn", "gN" visually select next/previous search match
+ * "gn" selects next match
+ * "gN" selects previous match
+ */
+ case 'N':
+ case 'n':
+ if (!current_search(cap->count1, cap->nchar == 'n'))
+ clearopbeep(oap);
+ break;
+
+ /*
+ * "gj" and "gk" two new funny movement keys -- up and down
+ * movement based on *screen* line rather than *file* line.
+ */
+ case 'j':
+ case K_DOWN:
+ /* with 'nowrap' it works just like the normal "j" command; also when
+ * in a closed fold */
+ if (!curwin->w_p_wrap
+ || hasFolding(curwin->w_cursor.lnum, NULL, NULL)
+ ) {
+ oap->motion_type = MLINE;
+ i = cursor_down(cap->count1, oap->op_type == OP_NOP);
+ } else
+ i = nv_screengo(oap, FORWARD, cap->count1);
+ if (i == FAIL)
+ clearopbeep(oap);
+ break;
+
+ case 'k':
+ case K_UP:
+ /* with 'nowrap' it works just like the normal "k" command; also when
+ * in a closed fold */
+ if (!curwin->w_p_wrap
+ || hasFolding(curwin->w_cursor.lnum, NULL, NULL)
+ ) {
+ oap->motion_type = MLINE;
+ i = cursor_up(cap->count1, oap->op_type == OP_NOP);
+ } else
+ i = nv_screengo(oap, BACKWARD, cap->count1);
+ if (i == FAIL)
+ clearopbeep(oap);
+ break;
+
+ /*
+ * "gJ": join two lines without inserting a space.
+ */
+ case 'J':
+ nv_join(cap);
+ break;
+
+ /*
+ * "g0", "g^" and "g$": Like "0", "^" and "$" but for screen lines.
+ * "gm": middle of "g0" and "g$".
+ */
+ case '^':
+ flag = TRUE;
+ /* FALLTHROUGH */
+
+ case '0':
+ case 'm':
+ case K_HOME:
+ case K_KHOME:
+ oap->motion_type = MCHAR;
+ oap->inclusive = FALSE;
+ if (curwin->w_p_wrap
+ && curwin->w_width != 0
+ ) {
+ int width1 = W_WIDTH(curwin) - curwin_col_off();
+ int width2 = width1 + curwin_col_off2();
+
+ validate_virtcol();
+ i = 0;
+ if (curwin->w_virtcol >= (colnr_T)width1 && width2 > 0)
+ i = (curwin->w_virtcol - width1) / width2 * width2 + width1;
+ } else
+ i = curwin->w_leftcol;
+ /* 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 += (W_WIDTH(curwin) - curwin_col_off()
+ + ((curwin->w_p_wrap && i > 0)
+ ? curwin_col_off2() : 0)) / 2;
+ coladvance((colnr_T)i);
+ if (flag) {
+ do
+ i = gchar_cursor();
+ while (vim_iswhite(i) && oneright() == OK);
+ }
+ curwin->w_set_curswant = TRUE;
+ break;
+
+ case '_':
+ /* "g_": to the last non-blank character in the line or <count> lines
+ * downward. */
+ cap->oap->motion_type = MCHAR;
+ cap->oap->inclusive = TRUE;
+ curwin->w_curswant = MAXCOL;
+ if (cursor_down((long)(cap->count1 - 1),
+ cap->oap->op_type == OP_NOP) == FAIL)
+ clearopbeep(cap->oap);
+ else {
+ char_u *ptr = ml_get_curline();
+
+ /* In Visual mode we may end up after the line. */
+ if (curwin->w_cursor.col > 0 && ptr[curwin->w_cursor.col] == NUL)
+ --curwin->w_cursor.col;
+
+ /* Decrease the cursor column until it's on a non-blank. */
+ while (curwin->w_cursor.col > 0
+ && vim_iswhite(ptr[curwin->w_cursor.col]))
+ --curwin->w_cursor.col;
+ curwin->w_set_curswant = TRUE;
+ adjust_for_sel(cap);
+ }
+ break;
+
+ case '$':
+ case K_END:
+ case K_KEND:
+ {
+ int col_off = curwin_col_off();
+
+ oap->motion_type = MCHAR;
+ oap->inclusive = TRUE;
+ if (curwin->w_p_wrap
+ && curwin->w_width != 0
+ ) {
+ curwin->w_curswant = MAXCOL; /* so we stay at the end */
+ if (cap->count1 == 1) {
+ int width1 = W_WIDTH(curwin) - col_off;
+ int width2 = width1 + curwin_col_off2();
+
+ validate_virtcol();
+ i = width1 - 1;
+ if (curwin->w_virtcol >= (colnr_T)width1)
+ i += ((curwin->w_virtcol - width1) / width2 + 1)
+ * width2;
+ coladvance((colnr_T)i);
+
+ /* Make sure we stick in this column. */
+ validate_virtcol();
+ curwin->w_curswant = curwin->w_virtcol;
+ curwin->w_set_curswant = FALSE;
+ if (curwin->w_cursor.col > 0 && curwin->w_p_wrap) {
+ /*
+ * Check for landing on a character that got split at
+ * the end of the line. We do not want to advance to
+ * the next screen line.
+ */
+ if (curwin->w_virtcol > (colnr_T)i)
+ --curwin->w_cursor.col;
+ }
+ } else if (nv_screengo(oap, FORWARD, cap->count1 - 1) == FAIL)
+ clearopbeep(oap);
+ } else {
+ i = curwin->w_leftcol + W_WIDTH(curwin) - col_off - 1;
+ coladvance((colnr_T)i);
+
+ /* Make sure we stick in this column. */
+ validate_virtcol();
+ curwin->w_curswant = curwin->w_virtcol;
+ curwin->w_set_curswant = FALSE;
+ }
+ }
+ break;
+
+ /*
+ * "g*" and "g#", like "*" and "#" but without using "\<" and "\>"
+ */
+ case '*':
+ case '#':
+#if POUND != '#'
+ case POUND: /* pound sign (sometimes equal to '#') */
+#endif
+ case Ctrl_RSB: /* :tag or :tselect for current identifier */
+ case ']': /* :tselect for current identifier */
+ nv_ident(cap);
+ break;
+
+ /*
+ * ge and gE: go back to end of word
+ */
+ case 'e':
+ case 'E':
+ oap->motion_type = MCHAR;
+ curwin->w_set_curswant = TRUE;
+ oap->inclusive = TRUE;
+ if (bckend_word(cap->count1, cap->nchar == 'E', FALSE) == FAIL)
+ clearopbeep(oap);
+ break;
+
+ /*
+ * "g CTRL-G": display info about cursor position
+ */
+ case Ctrl_G:
+ cursor_pos_info();
+ break;
+
+ /*
+ * "gi": start Insert at the last position.
+ */
+ case 'i':
+ if (curbuf->b_last_insert.lnum != 0) {
+ curwin->w_cursor = curbuf->b_last_insert;
+ check_cursor_lnum();
+ i = (int)STRLEN(ml_get_curline());
+ if (curwin->w_cursor.col > (colnr_T)i) {
+ if (virtual_active())
+ curwin->w_cursor.coladd += curwin->w_cursor.col - i;
+ curwin->w_cursor.col = i;
+ }
+ }
+ cap->cmdchar = 'i';
+ nv_edit(cap);
+ break;
+
+ /*
+ * "gI": Start insert in column 1.
+ */
+ case 'I':
+ beginline(0);
+ if (!checkclearopq(oap))
+ invoke_edit(cap, FALSE, 'g', FALSE);
+ break;
+
+ /*
+ * "gf": goto file, edit file under cursor
+ * "]f" and "[f": can also be used.
+ */
+ case 'f':
+ case 'F':
+ nv_gotofile(cap);
+ break;
+
+ /* "g'm" and "g`m": jump to mark without setting pcmark */
+ case '\'':
+ cap->arg = TRUE;
+ /*FALLTHROUGH*/
+ case '`':
+ nv_gomark(cap);
+ break;
+
+ /*
+ * "gs": Goto sleep.
+ */
+ case 's':
+ do_sleep(cap->count1 * 1000L);
+ break;
+
+ /*
+ * "ga": Display the ascii value of the character under the
+ * cursor. It is displayed in decimal, hex, and octal. -- webb
+ */
+ case 'a':
+ do_ascii(NULL);
+ break;
+
+ /*
+ * "g8": Display the bytes used for the UTF-8 character under the
+ * cursor. It is displayed in hex.
+ * "8g8" finds illegal byte sequence.
+ */
+ case '8':
+ if (cap->count0 == 8)
+ utf_find_illegal();
+ else
+ show_utf8();
+ break;
+
+ case '<':
+ show_sb_text();
+ break;
+
+ /*
+ * "gg": Goto the first line in file. With a count it goes to
+ * that line number like for "G". -- webb
+ */
+ case 'g':
+ cap->arg = FALSE;
+ nv_goto(cap);
+ break;
+
+ /*
+ * Two-character operators:
+ * "gq" Format text
+ * "gw" Format text and keep cursor position
+ * "g~" Toggle the case of the text.
+ * "gu" Change text to lower case.
+ * "gU" Change text to upper case.
+ * "g?" rot13 encoding
+ * "g@" call 'operatorfunc'
+ */
+ case 'q':
+ case 'w':
+ oap->cursor_start = curwin->w_cursor;
+ /*FALLTHROUGH*/
+ case '~':
+ case 'u':
+ case 'U':
+ case '?':
+ case '@':
+ nv_operator(cap);
+ break;
+
+ /*
+ * "gd": Find first occurrence of pattern under the cursor in the
+ * current function
+ * "gD": idem, but in the current file.
+ */
+ case 'd':
+ case 'D':
+ nv_gd(oap, cap->nchar, (int)cap->count0);
+ break;
+
+ /*
+ * g<*Mouse> : <C-*mouse>
+ */
+ case K_MIDDLEMOUSE:
+ case K_MIDDLEDRAG:
+ case K_MIDDLERELEASE:
+ case K_LEFTMOUSE:
+ case K_LEFTDRAG:
+ case K_LEFTRELEASE:
+ case K_RIGHTMOUSE:
+ case K_RIGHTDRAG:
+ case K_RIGHTRELEASE:
+ case K_X1MOUSE:
+ case K_X1DRAG:
+ case K_X1RELEASE:
+ case K_X2MOUSE:
+ case K_X2DRAG:
+ case K_X2RELEASE:
+ mod_mask = MOD_MASK_CTRL;
+ (void)do_mouse(oap, cap->nchar, BACKWARD, cap->count1, 0);
+ break;
+
+ case K_IGNORE:
+ break;
+
+ /*
+ * "gP" and "gp": same as "P" and "p" but leave cursor just after new text
+ */
+ case 'p':
+ case 'P':
+ nv_put(cap);
+ break;
+
+ /* "go": goto byte count from start of buffer */
+ case 'o':
+ goto_byte(cap->count0);
+ break;
+
+ /* "gQ": improved Ex mode */
+ case 'Q':
+ if (text_locked()) {
+ clearopbeep(cap->oap);
+ text_locked_msg();
+ break;
+ }
+
+ if (!checkclearopq(oap))
+ do_exmode(TRUE);
+ break;
+
+ case ',':
+ nv_pcmark(cap);
+ break;
+
+ case ';':
+ cap->count1 = -cap->count1;
+ nv_pcmark(cap);
+ break;
+
+ case 't':
+ if (!checkclearop(oap))
+ goto_tabpage((int)cap->count0);
+ break;
+ case 'T':
+ if (!checkclearop(oap))
+ goto_tabpage(-(int)cap->count1);
+ break;
+
+ case '+':
+ case '-': /* "g+" and "g-": undo or redo along the timeline */
+ if (!checkclearopq(oap))
+ undo_time(cap->nchar == '-' ? -cap->count1 : cap->count1,
+ FALSE, FALSE, FALSE);
+ break;
+
+ default:
+ clearopbeep(oap);
+ break;
+ }
+}
+
+/*
+ * Handle "o" and "O" commands.
+ */
+static void n_opencmd(cap)
+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 */
+ (void)hasFolding(curwin->w_cursor.lnum,
+ &curwin->w_cursor.lnum, NULL);
+ else
+ /* Open below the last line of a folded sequence of lines */
+ (void)hasFolding(curwin->w_cursor.lnum,
+ NULL, &curwin->w_cursor.lnum);
+ if (u_save((linenr_T)(curwin->w_cursor.lnum -
+ (cap->cmdchar == 'O' ? 1 : 0)),
+ (linenr_T)(curwin->w_cursor.lnum +
+ (cap->cmdchar == 'o' ? 1 : 0))
+ ) == OK
+ && open_line(cap->cmdchar == 'O' ? BACKWARD : FORWARD,
+ 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);
+ /* When '#' is in 'cpoptions' ignore the count. */
+ if (vim_strchr(p_cpo, CPO_HASH) != NULL)
+ cap->count1 = 1;
+ invoke_edit(cap, FALSE, cap->cmdchar, TRUE);
+ }
+ }
+}
+
+/*
+ * "." command: redo last change.
+ */
+static void nv_dot(cap)
+cmdarg_T *cap;
+{
+ if (!checkclearopq(cap->oap)) {
+ /*
+ * If "restart_edit" 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.
+ */
+ if (start_redo(cap->count0, restart_edit != 0 && !arrow_used) == FAIL)
+ clearopbeep(cap->oap);
+ }
+}
+
+/*
+ * CTRL-R: undo undo
+ */
+static void nv_redo(cap)
+cmdarg_T *cap;
+{
+ if (!checkclearopq(cap->oap)) {
+ u_redo((int)cap->count1);
+ curwin->w_set_curswant = TRUE;
+ }
+}
+
+/*
+ * Handle "U" command.
+ */
+static void nv_Undo(cap)
+cmdarg_T *cap;
+{
+ /* In Visual mode and typing "gUU" triggers an operator */
+ if (cap->oap->op_type == OP_UPPER
+ || VIsual_active
+ ) {
+ /* translate "gUU" to "gUgU" */
+ cap->cmdchar = 'g';
+ cap->nchar = 'U';
+ nv_operator(cap);
+ } else if (!checkclearopq(cap->oap)) {
+ u_undoline();
+ curwin->w_set_curswant = TRUE;
+ }
+}
+
+/*
+ * '~' command: If tilde is not an operator and Visual is off: swap case of a
+ * single character.
+ */
+static void nv_tilde(cap)
+cmdarg_T *cap;
+{
+ if (!p_to
+ && !VIsual_active
+ && cap->oap->op_type != OP_TILDE)
+ n_swapchar(cap);
+ else
+ nv_operator(cap);
+}
+
+/*
+ * Handle an operator command.
+ * The actual work is done by do_pending_operator().
+ */
+static void nv_operator(cap)
+cmdarg_T *cap;
+{
+ int op_type;
+
+ op_type = get_op_type(cap->cmdchar, cap->nchar);
+
+ if (op_type == cap->oap->op_type) /* double operator works on lines */
+ nv_lineop(cap);
+ else if (!checkclearop(cap->oap)) {
+ cap->oap->start = curwin->w_cursor;
+ cap->oap->op_type = op_type;
+ set_op_var(op_type);
+ }
+}
+
+/*
+ * Set v:operator to the characters for "optype".
+ */
+static void set_op_var(optype)
+int optype;
+{
+ char_u opchars[3];
+
+ if (optype == OP_NOP)
+ set_vim_var_string(VV_OP, NULL, 0);
+ else {
+ opchars[0] = get_op_char(optype);
+ opchars[1] = get_extra_op_char(optype);
+ opchars[2] = NUL;
+ set_vim_var_string(VV_OP, opchars, -1);
+ }
+}
+
+/*
+ * Handle linewise operator "dd", "yy", etc.
+ *
+ * "_" is is a strange motion command that helps make operators more logical.
+ * It is actually implemented, but not documented in the real Vi. This motion
+ * command actually refers to "the current line". Commands like "dd" and "yy"
+ * are really an alternate form of "d_" and "y_". It does accept a count, so
+ * "d3_" works to delete 3 lines.
+ */
+static void nv_lineop(cap)
+cmdarg_T *cap;
+{
+ cap->oap->motion_type = MLINE;
+ if (cursor_down(cap->count1 - 1L, cap->oap->op_type == OP_NOP) == FAIL)
+ clearopbeep(cap->oap);
+ else if ( (cap->oap->op_type == OP_DELETE /* only with linewise motions */
+ && cap->oap->motion_force != 'v'
+ && cap->oap->motion_force != Ctrl_V)
+ || cap->oap->op_type == OP_LSHIFT
+ || cap->oap->op_type == OP_RSHIFT)
+ beginline(BL_SOL | BL_FIX);
+ else if (cap->oap->op_type != OP_YANK) /* 'Y' does not move cursor */
+ beginline(BL_WHITE | BL_FIX);
+}
+
+/*
+ * <Home> command.
+ */
+static void nv_home(cap)
+cmdarg_T *cap;
+{
+ /* CTRL-HOME is like "gg" */
+ if (mod_mask & MOD_MASK_CTRL)
+ nv_goto(cap);
+ else {
+ cap->count0 = 1;
+ nv_pipe(cap);
+ }
+ ins_at_eol = FALSE; /* Don't move cursor past eol (only necessary in a
+ one-character line). */
+}
+
+/*
+ * "|" command.
+ */
+static void nv_pipe(cap)
+cmdarg_T *cap;
+{
+ cap->oap->motion_type = MCHAR;
+ cap->oap->inclusive = FALSE;
+ beginline(0);
+ if (cap->count0 > 0) {
+ coladvance((colnr_T)(cap->count0 - 1));
+ curwin->w_curswant = (colnr_T)(cap->count0 - 1);
+ } else
+ curwin->w_curswant = 0;
+ /* keep curswant at the column where we wanted to go, not where
+ * we ended; differs if line is too short */
+ curwin->w_set_curswant = FALSE;
+}
+
+/*
+ * Handle back-word command "b" and "B".
+ * cap->arg is 1 for "B"
+ */
+static void nv_bck_word(cap)
+cmdarg_T *cap;
+{
+ cap->oap->motion_type = MCHAR;
+ cap->oap->inclusive = FALSE;
+ curwin->w_set_curswant = TRUE;
+ if (bck_word(cap->count1, cap->arg, FALSE) == FAIL)
+ clearopbeep(cap->oap);
+ else if ((fdo_flags & FDO_HOR) && KeyTyped && cap->oap->op_type == OP_NOP)
+ foldOpenCursor();
+}
+
+/*
+ * Handle word motion commands "e", "E", "w" and "W".
+ * cap->arg is TRUE for "E" and "W".
+ */
+static void nv_wordcmd(cap)
+cmdarg_T *cap;
+{
+ int n;
+ int word_end;
+ int flag = FALSE;
+ pos_T startpos = curwin->w_cursor;
+
+ /*
+ * Set inclusive for the "E" and "e" command.
+ */
+ if (cap->cmdchar == 'e' || cap->cmdchar == 'E')
+ word_end = TRUE;
+ else
+ word_end = FALSE;
+ cap->oap->inclusive = word_end;
+
+ /*
+ * "cw" and "cW" are a special case.
+ */
+ if (!word_end && cap->oap->op_type == OP_CHANGE) {
+ n = gchar_cursor();
+ if (n != NUL) { /* not an empty line */
+ if (vim_iswhite(n)) {
+ /*
+ * Reproduce a funny Vi behaviour: "cw" on a blank only
+ * changes one character, not all blanks until the start of
+ * the next word. Only do this when the 'w' flag is included
+ * in 'cpoptions'.
+ */
+ if (cap->count1 == 1 && vim_strchr(p_cpo, CPO_CW) != NULL) {
+ cap->oap->inclusive = TRUE;
+ cap->oap->motion_type = MCHAR;
+ return;
+ }
+ } else {
+ /*
+ * This is a little strange. To match what the real Vi does,
+ * we effectively map 'cw' to 'ce', and 'cW' to 'cE', provided
+ * that we are not on a space or a TAB. This seems impolite
+ * at first, but it's really more what we mean when we say
+ * 'cw'.
+ * 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;
+ flag = TRUE;
+ }
+ }
+ }
+
+ cap->oap->motion_type = MCHAR;
+ curwin->w_set_curswant = TRUE;
+ if (word_end)
+ n = end_word(cap->count1, cap->arg, flag, FALSE);
+ else
+ n = fwd_word(cap->count1, cap->arg, cap->oap->op_type != OP_NOP);
+
+ /* Don't leave the cursor on the NUL past the end of line. Unless we
+ * didn't move it forward. */
+ if (lt(startpos, curwin->w_cursor))
+ adjust_cursor(cap->oap);
+
+ if (n == FAIL && cap->oap->op_type == OP_NOP)
+ clearopbeep(cap->oap);
+ else {
+ adjust_for_sel(cap);
+ if ((fdo_flags & FDO_HOR) && KeyTyped && cap->oap->op_type == OP_NOP)
+ foldOpenCursor();
+ }
+}
+
+/*
+ * Used after a movement command: If the cursor ends up on the NUL after the
+ * end of the line, may move it back to the last character and make the motion
+ * inclusive.
+ */
+static void adjust_cursor(oap)
+oparg_T *oap;
+{
+ /* The cursor cannot remain on the NUL when:
+ * - the column is > 0
+ * - not in Visual mode or 'selection' is "o"
+ * - 'virtualedit' is not "all" and not "onemore".
+ */
+ if (curwin->w_cursor.col > 0 && gchar_cursor() == NUL
+ && (!VIsual_active || *p_sel == 'o')
+ && !virtual_active() && (ve_flags & VE_ONEMORE) == 0
+ ) {
+ --curwin->w_cursor.col;
+ /* prevent cursor from moving on the trail byte */
+ if (has_mbyte)
+ mb_adjust_cursor();
+ oap->inclusive = TRUE;
+ }
+}
+
+/*
+ * "0" and "^" commands.
+ * cap->arg is the argument for beginline().
+ */
+static void nv_beginline(cap)
+cmdarg_T *cap;
+{
+ cap->oap->motion_type = MCHAR;
+ cap->oap->inclusive = FALSE;
+ beginline(cap->arg);
+ if ((fdo_flags & FDO_HOR) && KeyTyped && cap->oap->op_type == OP_NOP)
+ foldOpenCursor();
+ ins_at_eol = FALSE; /* Don't move cursor past eol (only necessary in a
+ one-character line). */
+}
+
+/*
+ * In exclusive Visual mode, may include the last character.
+ */
+static void adjust_for_sel(cap)
+cmdarg_T *cap;
+{
+ if (VIsual_active && cap->oap->inclusive && *p_sel == 'e'
+ && gchar_cursor() != NUL && lt(VIsual, curwin->w_cursor)) {
+ if (has_mbyte)
+ inc_cursor();
+ else
+ ++curwin->w_cursor.col;
+ cap->oap->inclusive = FALSE;
+ }
+}
+
+/*
+ * Exclude last character at end of Visual area for 'selection' == "exclusive".
+ * Should check VIsual_mode before calling this.
+ * Returns TRUE when backed up to the previous line.
+ */
+static int unadjust_for_sel() {
+ pos_T *pp;
+
+ if (*p_sel == 'e' && !equalpos(VIsual, curwin->w_cursor)) {
+ if (lt(VIsual, curwin->w_cursor))
+ pp = &curwin->w_cursor;
+ else
+ pp = &VIsual;
+ if (pp->coladd > 0)
+ --pp->coladd;
+ else if (pp->col > 0) {
+ --pp->col;
+ mb_adjustpos(curbuf, pp);
+ } else if (pp->lnum > 1) {
+ --pp->lnum;
+ pp->col = (colnr_T)STRLEN(ml_get(pp->lnum));
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/*
+ * SELECT key in Normal or Visual mode: end of Select mode mapping.
+ */
+static void nv_select(cap)
+cmdarg_T *cap;
+{
+ if (VIsual_active)
+ VIsual_select = TRUE;
+ else if (VIsual_reselect) {
+ cap->nchar = 'v'; /* fake "gv" command */
+ cap->arg = TRUE;
+ nv_g_cmd(cap);
+ }
+}
+
+
+/*
+ * "G", "gg", CTRL-END, CTRL-HOME.
+ * cap->arg is TRUE for "G".
+ */
+static void nv_goto(cap)
+cmdarg_T *cap;
+{
+ linenr_T lnum;
+
+ if (cap->arg)
+ lnum = curbuf->b_ml.ml_line_count;
+ else
+ lnum = 1L;
+ cap->oap->motion_type = MLINE;
+ setpcmark();
+
+ /* When a count is given, use it instead of the default lnum */
+ if (cap->count0 != 0)
+ lnum = cap->count0;
+ if (lnum < 1L)
+ lnum = 1L;
+ else if (lnum > curbuf->b_ml.ml_line_count)
+ lnum = curbuf->b_ml.ml_line_count;
+ curwin->w_cursor.lnum = lnum;
+ beginline(BL_SOL | BL_FIX);
+ if ((fdo_flags & FDO_JUMP) && KeyTyped && cap->oap->op_type == OP_NOP)
+ foldOpenCursor();
+}
+
+/*
+ * CTRL-\ in Normal mode.
+ */
+static void nv_normal(cap)
+cmdarg_T *cap;
+{
+ if (cap->nchar == Ctrl_N || cap->nchar == Ctrl_G) {
+ clearop(cap->oap);
+ if (restart_edit != 0 && mode_displayed)
+ clear_cmdline = TRUE; /* unshow mode later */
+ restart_edit = 0;
+ if (cmdwin_type != 0)
+ cmdwin_result = Ctrl_C;
+ if (VIsual_active) {
+ end_visual_mode(); /* stop Visual */
+ redraw_curbuf_later(INVERTED);
+ }
+ /* CTRL-\ CTRL-G restarts Insert mode when 'insertmode' is set. */
+ if (cap->nchar == Ctrl_G && p_im)
+ restart_edit = 'a';
+ } else
+ clearopbeep(cap->oap);
+}
+
+/*
+ * ESC in Normal mode: beep, but don't flush buffers.
+ * Don't even beep if we are canceling a command.
+ */
+static void nv_esc(cap)
+cmdarg_T *cap;
+{
+ int no_reason;
+
+ no_reason = (cap->oap->op_type == OP_NOP
+ && cap->opcount == 0
+ && cap->count0 == 0
+ && cap->oap->regname == 0
+ && !p_im);
+
+ if (cap->arg) { /* TRUE for CTRL-C */
+ if (restart_edit == 0
+ && cmdwin_type == 0
+ && !VIsual_active
+ && no_reason)
+ MSG(_("Type :quit<Enter> to exit Vim"));
+
+ /* Don't reset "restart_edit" when 'insertmode' is set, it won't be
+ * set again below when halfway a mapping. */
+ if (!p_im)
+ restart_edit = 0;
+ if (cmdwin_type != 0) {
+ cmdwin_result = K_IGNORE;
+ got_int = FALSE; /* don't stop executing autocommands et al. */
+ return;
+ }
+ }
+
+ if (VIsual_active) {
+ end_visual_mode(); /* stop Visual */
+ check_cursor_col(); /* make sure cursor is not beyond EOL */
+ curwin->w_set_curswant = TRUE;
+ redraw_curbuf_later(INVERTED);
+ } else if (no_reason)
+ vim_beep();
+ clearop(cap->oap);
+
+ /* A CTRL-C is often used at the start of a menu. When 'insertmode' is
+ * set return to Insert mode afterwards. */
+ if (restart_edit == 0 && goto_im()
+ && ex_normal_busy == 0
+ )
+ restart_edit = 'a';
+}
+
+/*
+ * Handle "A", "a", "I", "i" and <Insert> commands.
+ */
+static void nv_edit(cap)
+cmdarg_T *cap;
+{
+ /* <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'))
+ 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
+ )) {
+ nv_object(cap);
+ } else if (!curbuf->b_p_ma && !p_im) {
+ /* Only give this error when 'insertmode' is off. */
+ EMSG(_(e_modifiable));
+ clearop(cap->oap);
+ } else if (!checkclearopq(cap->oap)) {
+ switch (cap->cmdchar) {
+ case 'A': /* "A"ppend after the line */
+ curwin->w_set_curswant = TRUE;
+ if (ve_flags == VE_ALL) {
+ int save_State = State;
+
+ /* Pretend Insert mode here to allow the cursor on the
+ * character past the end of the line */
+ State = INSERT;
+ coladvance((colnr_T)MAXCOL);
+ State = save_State;
+ } else
+ curwin->w_cursor.col += (colnr_T)STRLEN(ml_get_cursor());
+ break;
+
+ case 'I': /* "I"nsert before the first non-blank */
+ if (vim_strchr(p_cpo, CPO_INSEND) == NULL)
+ beginline(BL_WHITE);
+ else
+ beginline(BL_WHITE|BL_FIX);
+ break;
+
+ case 'a': /* "a"ppend is like "i"nsert on the next character. */
+ /* increment coladd when in virtual space, increment the
+ * column otherwise, also to append after an unprintable char */
+ if (virtual_active()
+ && (curwin->w_cursor.coladd > 0
+ || *ml_get_cursor() == NUL
+ || *ml_get_cursor() == TAB))
+ curwin->w_cursor.coladd++;
+ else if (*ml_get_cursor() != NUL)
+ inc_cursor();
+ break;
+ }
+
+ if (curwin->w_cursor.coladd && cap->cmdchar != 'A') {
+ int save_State = State;
+
+ /* Pretend Insert mode here to allow the cursor on the
+ * character past the end of the line */
+ State = INSERT;
+ coladvance(getviscol());
+ State = save_State;
+ }
+
+ invoke_edit(cap, FALSE, cap->cmdchar, FALSE);
+ }
+}
+
+/*
+ * Invoke edit() and take care of "restart_edit" and the return value.
+ */
+static void invoke_edit(cap, repl, cmd, startln)
+cmdarg_T *cap;
+int repl; /* "r" or "gr" command */
+int cmd;
+int startln;
+{
+ int restart_edit_save = 0;
+
+ /* Complicated: When the user types "a<C-O>a" we don't want to do Insert
+ * mode recursively. But when doing "a<C-O>." or "a<C-O>rx" we do allow
+ * it. */
+ if (repl || !stuff_empty())
+ restart_edit_save = restart_edit;
+ else
+ restart_edit_save = 0;
+
+ /* Always reset "restart_edit", this is not a restarted edit. */
+ restart_edit = 0;
+
+ if (edit(cmd, startln, cap->count1))
+ cap->retval |= CA_COMMAND_BUSY;
+
+ if (restart_edit == 0)
+ restart_edit = restart_edit_save;
+}
+
+/*
+ * "a" or "i" while an operator is pending or in Visual mode: object motion.
+ */
+static void nv_object(cap)
+cmdarg_T *cap;
+{
+ int flag;
+ int include;
+ char_u *mps_save;
+
+ if (cap->cmdchar == 'i')
+ include = FALSE; /* "ix" = inner object: exclude white space */
+ else
+ include = TRUE; /* "ax" = an object: include white space */
+
+ /* Make sure (), [], {} and <> are in 'matchpairs' */
+ mps_save = curbuf->b_p_mps;
+ curbuf->b_p_mps = (char_u *)"(:),{:},[:],<:>";
+
+ switch (cap->nchar) {
+ case 'w': /* "aw" = a word */
+ flag = current_word(cap->oap, cap->count1, include, FALSE);
+ break;
+ case 'W': /* "aW" = a WORD */
+ flag = current_word(cap->oap, cap->count1, include, TRUE);
+ break;
+ case 'b': /* "ab" = a braces block */
+ case '(':
+ case ')':
+ flag = current_block(cap->oap, cap->count1, include, '(', ')');
+ break;
+ case 'B': /* "aB" = a Brackets block */
+ case '{':
+ case '}':
+ flag = current_block(cap->oap, cap->count1, include, '{', '}');
+ break;
+ case '[': /* "a[" = a [] block */
+ case ']':
+ flag = current_block(cap->oap, cap->count1, include, '[', ']');
+ break;
+ case '<': /* "a<" = a <> block */
+ case '>':
+ flag = current_block(cap->oap, cap->count1, include, '<', '>');
+ break;
+ case 't': /* "at" = a tag block (xml and html) */
+ flag = current_tagblock(cap->oap, cap->count1, include);
+ break;
+ case 'p': /* "ap" = a paragraph */
+ flag = current_par(cap->oap, cap->count1, include, 'p');
+ break;
+ case 's': /* "as" = a sentence */
+ flag = current_sent(cap->oap, cap->count1, include);
+ break;
+ case '"': /* "a"" = a double quoted string */
+ case '\'': /* "a'" = a single quoted string */
+ case '`': /* "a`" = a backtick quoted string */
+ flag = current_quote(cap->oap, cap->count1, include,
+ cap->nchar);
+ break;
+ default:
+ flag = FAIL;
+ break;
+ }
+
+ curbuf->b_p_mps = mps_save;
+ if (flag == FAIL)
+ clearopbeep(cap->oap);
+ adjust_cursor_col();
+ curwin->w_set_curswant = TRUE;
+}
+
+/*
+ * "q" command: Start/stop recording.
+ * "q:", "q/", "q?": edit command-line in command-line window.
+ */
+static void nv_record(cap)
+cmdarg_T *cap;
+{
+ if (cap->oap->op_type == OP_FORMAT) {
+ /* "gqq" is the same as "gqgq": format line */
+ cap->cmdchar = 'g';
+ cap->nchar = 'q';
+ nv_operator(cap);
+ } else if (!checkclearop(cap->oap)) {
+ 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) == FAIL)
+ clearopbeep(cap->oap);
+ }
+}
+
+/*
+ * Handle the "@r" command.
+ */
+static void nv_at(cap)
+cmdarg_T *cap;
+{
+ if (checkclearop(cap->oap))
+ return;
+ if (cap->nchar == '=') {
+ if (get_expr_register() == NUL)
+ return;
+ }
+ while (cap->count1-- && !got_int) {
+ if (do_execreg(cap->nchar, FALSE, FALSE, FALSE) == FAIL) {
+ clearopbeep(cap->oap);
+ break;
+ }
+ line_breakcheck();
+ }
+}
+
+/*
+ * Handle the CTRL-U and CTRL-D commands.
+ */
+static void nv_halfpage(cap)
+cmdarg_T *cap;
+{
+ if ((cap->cmdchar == Ctrl_U && curwin->w_cursor.lnum == 1)
+ || (cap->cmdchar == Ctrl_D
+ && curwin->w_cursor.lnum == curbuf->b_ml.ml_line_count))
+ clearopbeep(cap->oap);
+ else if (!checkclearop(cap->oap))
+ halfpage(cap->cmdchar == Ctrl_D, cap->count0);
+}
+
+/*
+ * Handle "J" or "gJ" command.
+ */
+static void nv_join(cap)
+cmdarg_T *cap;
+{
+ if (VIsual_active) /* join the visual lines */
+ nv_operator(cap);
+ else if (!checkclearop(cap->oap)) {
+ if (cap->count0 <= 1)
+ cap->count0 = 2; /* default for join is two lines! */
+ if (curwin->w_cursor.lnum + cap->count0 - 1 >
+ curbuf->b_ml.ml_line_count)
+ clearopbeep(cap->oap); /* beyond last line */
+ else {
+ prep_redo(cap->oap->regname, cap->count0,
+ NUL, cap->cmdchar, NUL, NUL, cap->nchar);
+ (void)do_join(cap->count0, cap->nchar == NUL, TRUE, TRUE);
+ }
+ }
+}
+
+/*
+ * "P", "gP", "p" and "gp" commands.
+ */
+static void nv_put(cap)
+cmdarg_T *cap;
+{
+ int regname = 0;
+ void *reg1 = NULL, *reg2 = NULL;
+ int empty = FALSE;
+ int was_visual = FALSE;
+ int dir;
+ int flags = 0;
+
+ if (cap->oap->op_type != OP_NOP) {
+ /* "dp" is ":diffput" */
+ if (cap->oap->op_type == OP_DELETE && cap->cmdchar == 'p') {
+ clearop(cap->oap);
+ nv_diffgetput(TRUE);
+ } else
+ clearopbeep(cap->oap);
+ } else {
+ dir = (cap->cmdchar == 'P'
+ || (cap->cmdchar == 'g' && cap->nchar == 'P'))
+ ? BACKWARD : FORWARD;
+ prep_redo_cmd(cap);
+ if (cap->cmdchar == 'g')
+ flags |= PUT_CURSEND;
+
+ if (VIsual_active) {
+ /* Putting in Visual mode: The put text replaces the selected
+ * text. First delete the selected text, then put the new text.
+ * Need to save and restore the registers that the delete
+ * overwrites if the old contents is being put.
+ */
+ was_visual = TRUE;
+ regname = cap->oap->regname;
+ if (regname == 0 || regname == '"'
+ || VIM_ISDIGIT(regname) || regname == '-'
+
+ ) {
+ /* The delete is going to overwrite the register we want to
+ * put, save it first. */
+ reg1 = get_register(regname, TRUE);
+ }
+
+ /* 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;
+
+ if (reg1 != NULL) {
+ /* Delete probably changed the register we want to put, save
+ * it first. Then put back what was there before the delete. */
+ reg2 = get_register(regname, FALSE);
+ put_register(regname, reg1);
+ }
+
+ /* When deleted a linewise Visual area, put the register as
+ * lines to avoid it joined with the next line. When deletion was
+ * characterwise, split a line when putting lines. */
+ if (VIsual_mode == 'V')
+ flags |= PUT_LINE;
+ else if (VIsual_mode == 'v')
+ flags |= PUT_LINE_SPLIT;
+ if (VIsual_mode == Ctrl_V && dir == FORWARD)
+ flags |= PUT_LINE_FORWARD;
+ dir = BACKWARD;
+ if ((VIsual_mode != 'V'
+ && curwin->w_cursor.col < curbuf->b_op_start.col)
+ || (VIsual_mode == 'V'
+ && curwin->w_cursor.lnum < curbuf->b_op_start.lnum))
+ /* cursor is at the end of the line or end of file, put
+ * forward. */
+ dir = FORWARD;
+ /* May have been reset in do_put(). */
+ VIsual_active = TRUE;
+ }
+ do_put(cap->oap->regname, dir, cap->count1, flags);
+
+ /* If a register was saved, put it back now. */
+ if (reg2 != NULL)
+ put_register(regname, reg2);
+
+ /* What to reselect with "gv"? Selecting the just put text seems to
+ * be the most useful, since the original text was removed. */
+ if (was_visual) {
+ curbuf->b_visual.vi_start = curbuf->b_op_start;
+ curbuf->b_visual.vi_end = curbuf->b_op_end;
+ }
+
+ /* When all lines were selected and deleted do_put() leaves an empty
+ * line that needs to be deleted now. */
+ if (empty && *ml_get(curbuf->b_ml.ml_line_count) == NUL) {
+ ml_delete(curbuf->b_ml.ml_line_count, TRUE);
+
+ /* If the cursor was in that line, move it to the end of the last
+ * line. */
+ 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);
+ }
+ }
+ auto_format(FALSE, TRUE);
+ }
+}
+
+/*
+ * "o" and "O" commands.
+ */
+static void nv_open(cap)
+cmdarg_T *cap;
+{
+ /* "do" is ":diffget" */
+ if (cap->oap->op_type == OP_DELETE && cap->cmdchar == 'o') {
+ clearop(cap->oap);
+ nv_diffgetput(FALSE);
+ } else if (VIsual_active) /* switch start and end of visual */
+ v_swap_corners(cap->cmdchar);
+ else
+ n_opencmd(cap);
+}
+
+
+
+
+/*
+ * Trigger CursorHold event.
+ * When waiting for a character for 'updatetime' K_CURSORHOLD is put in the
+ * input buffer. "did_cursorhold" is set to avoid retriggering.
+ */
+static void nv_cursorhold(cap)
+cmdarg_T *cap;
+{
+ apply_autocmds(EVENT_CURSORHOLD, NULL, NULL, FALSE, curbuf);
+ did_cursorhold = TRUE;
+ cap->retval |= CA_COMMAND_BUSY; /* don't call edit() now */
+}
diff --git a/src/ops.c b/src/ops.c
new file mode 100644
index 0000000000..3acb297134
--- /dev/null
+++ b/src/ops.c
@@ -0,0 +1,5275 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * 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.
+ */
+
+/*
+ * ops.c: implementation of various operators: op_shift, op_delete, op_tilde,
+ * op_change, op_yank, do_put, do_join
+ */
+
+#include "vim.h"
+
+/*
+ * Number of registers.
+ * 0 = unnamed register, for normal yanks and puts
+ * 1..9 = registers '1' to '9', for deletes
+ * 10..35 = registers 'a' to 'z'
+ * 36 = delete register '-'
+ * 37 = Selection register '*'. Only if FEAT_CLIPBOARD defined
+ * 38 = Clipboard register '+'. Only if FEAT_CLIPBOARD and FEAT_X11 defined
+ */
+/*
+ * Symbolic names for some registers.
+ */
+#define DELETION_REGISTER 36
+
+# define NUM_REGISTERS 37
+
+/*
+ * Each yank register is an array of pointers to lines.
+ */
+static struct yankreg {
+ char_u **y_array; /* pointer to array of line pointers */
+ linenr_T y_size; /* number of lines in y_array */
+ char_u y_type; /* MLINE, MCHAR or MBLOCK */
+ colnr_T y_width; /* only set if y_type == MBLOCK */
+} y_regs[NUM_REGISTERS];
+
+static struct yankreg *y_current; /* ptr to current yankreg */
+static int y_append; /* TRUE when appending */
+static struct yankreg *y_previous = NULL; /* ptr to last written yankreg */
+
+/*
+ * structure used by block_prep, op_delete and op_yank for blockwise operators
+ * also op_change, op_shift, op_insert, op_replace - AKelly
+ */
+struct block_def {
+ int startspaces; /* 'extra' cols before first char */
+ int endspaces; /* 'extra' cols after last char */
+ int textlen; /* chars in block */
+ char_u *textstart; /* pointer to 1st char (partially) in block */
+ colnr_T textcol; /* index of chars (partially) in block */
+ colnr_T start_vcol; /* start col of 1st char wholly inside block */
+ colnr_T end_vcol; /* start col of 1st char wholly after block */
+ int is_short; /* TRUE if line is too short to fit in block */
+ int is_MAX; /* TRUE if curswant==MAXCOL when starting */
+ int is_oneChar; /* TRUE if block within one character */
+ int pre_whitesp; /* screen cols of ws before block */
+ int pre_whitesp_c; /* chars of ws before block */
+ colnr_T end_char_vcols; /* number of vcols of post-block char */
+ colnr_T start_char_vcols; /* number of vcols of pre-block char */
+};
+
+static void shift_block __ARGS((oparg_T *oap, int amount));
+static void block_insert __ARGS((oparg_T *oap, char_u *s, int b_insert,
+ struct block_def*bdp));
+static int stuff_yank __ARGS((int, char_u *));
+static void put_reedit_in_typebuf __ARGS((int silent));
+static int put_in_typebuf __ARGS((char_u *s, int esc, int colon,
+ int silent));
+static void stuffescaped __ARGS((char_u *arg, int literally));
+static void mb_adjust_opend __ARGS((oparg_T *oap));
+static void free_yank __ARGS((long));
+static void free_yank_all __ARGS((void));
+static int yank_copy_line __ARGS((struct block_def *bd, long y_idx));
+static void dis_msg __ARGS((char_u *p, int skip_esc));
+static char_u *skip_comment __ARGS((char_u *line, int process,
+ int include_space,
+ int *is_comment));
+static void block_prep __ARGS((oparg_T *oap, struct block_def *, linenr_T, int));
+static void str_to_reg __ARGS((struct yankreg *y_ptr, int type, char_u *str,
+ long len,
+ long blocklen));
+static int ends_in_white __ARGS((linenr_T lnum));
+static int same_leader __ARGS((linenr_T lnum, int, char_u *, int, char_u *));
+static int fmt_check_par __ARGS((linenr_T, int *, char_u **, int do_comments));
+
+/*
+ * The names of operators.
+ * IMPORTANT: Index must correspond with defines in vim.h!!!
+ * The third field indicates whether the operator always works on lines.
+ */
+static char opchars[][3] =
+{
+ {NUL, NUL, FALSE}, /* OP_NOP */
+ {'d', NUL, FALSE}, /* OP_DELETE */
+ {'y', NUL, FALSE}, /* OP_YANK */
+ {'c', NUL, FALSE}, /* OP_CHANGE */
+ {'<', NUL, TRUE}, /* OP_LSHIFT */
+ {'>', NUL, TRUE}, /* OP_RSHIFT */
+ {'!', NUL, TRUE}, /* OP_FILTER */
+ {'g', '~', FALSE}, /* OP_TILDE */
+ {'=', NUL, TRUE}, /* OP_INDENT */
+ {'g', 'q', TRUE}, /* OP_FORMAT */
+ {':', NUL, TRUE}, /* OP_COLON */
+ {'g', 'U', FALSE}, /* OP_UPPER */
+ {'g', 'u', FALSE}, /* OP_LOWER */
+ {'J', NUL, TRUE}, /* DO_JOIN */
+ {'g', 'J', TRUE}, /* DO_JOIN_NS */
+ {'g', '?', FALSE}, /* OP_ROT13 */
+ {'r', NUL, FALSE}, /* OP_REPLACE */
+ {'I', NUL, FALSE}, /* OP_INSERT */
+ {'A', NUL, FALSE}, /* OP_APPEND */
+ {'z', 'f', TRUE}, /* OP_FOLD */
+ {'z', 'o', TRUE}, /* OP_FOLDOPEN */
+ {'z', 'O', TRUE}, /* OP_FOLDOPENREC */
+ {'z', 'c', TRUE}, /* OP_FOLDCLOSE */
+ {'z', 'C', TRUE}, /* OP_FOLDCLOSEREC */
+ {'z', 'd', TRUE}, /* OP_FOLDDEL */
+ {'z', 'D', TRUE}, /* OP_FOLDDELREC */
+ {'g', 'w', TRUE}, /* OP_FORMAT2 */
+ {'g', '@', FALSE}, /* OP_FUNCTION */
+};
+
+/*
+ * Translate a command name into an operator type.
+ * Must only be called with a valid operator name!
+ */
+int get_op_type(char1, char2)
+int char1;
+int char2;
+{
+ int i;
+
+ if (char1 == 'r') /* ignore second character */
+ return OP_REPLACE;
+ if (char1 == '~') /* when tilde is an operator */
+ return OP_TILDE;
+ for (i = 0;; ++i)
+ if (opchars[i][0] == char1 && opchars[i][1] == char2)
+ break;
+ return i;
+}
+
+/*
+ * Return TRUE if operator "op" always works on whole lines.
+ */
+int op_on_lines(op)
+int op;
+{
+ return opchars[op][2];
+}
+
+/*
+ * Get first operator command character.
+ * Returns 'g' or 'z' if there is another command character.
+ */
+int get_op_char(optype)
+int optype;
+{
+ return opchars[optype][0];
+}
+
+/*
+ * Get second operator command character.
+ */
+int get_extra_op_char(optype)
+int optype;
+{
+ return opchars[optype][1];
+}
+
+/*
+ * op_shift - handle a shift operation
+ */
+void op_shift(oap, curs_top, amount)
+oparg_T *oap;
+int curs_top;
+int amount;
+{
+ long i;
+ int first_char;
+ char_u *s;
+ int block_col = 0;
+
+ if (u_save((linenr_T)(oap->start.lnum - 1),
+ (linenr_T)(oap->end.lnum + 1)) == FAIL)
+ return;
+
+ if (oap->block_mode)
+ block_col = curwin->w_cursor.col;
+
+ for (i = oap->line_count; --i >= 0; ) {
+ first_char = *ml_get_curline();
+ if (first_char == NUL) /* empty line */
+ curwin->w_cursor.col = 0;
+ else if (oap->block_mode)
+ shift_block(oap, amount);
+ else
+ /* Move the line right if it doesn't start with '#', 'smartindent'
+ * isn't set or 'cindent' isn't set or '#' isn't in 'cino'. */
+ if (first_char != '#' || !preprocs_left()) {
+ shift_line(oap->op_type == OP_LSHIFT, p_sr, amount, FALSE);
+ }
+ ++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();
+
+ if (oap->block_mode) {
+ curwin->w_cursor.lnum = oap->start.lnum;
+ curwin->w_cursor.col = block_col;
+ } else if (curs_top) { /* put cursor on first line, for ">>" */
+ curwin->w_cursor.lnum = oap->start.lnum;
+ beginline(BL_SOL | BL_FIX); /* shift_line() may have set cursor.col */
+ } else
+ --curwin->w_cursor.lnum; /* put cursor on last line, for ":>" */
+
+ if (oap->line_count > p_report) {
+ if (oap->op_type == OP_RSHIFT)
+ s = (char_u *)">";
+ else
+ s = (char_u *)"<";
+ if (oap->line_count == 1) {
+ if (amount == 1)
+ sprintf((char *)IObuff, _("1 line %sed 1 time"), s);
+ else
+ sprintf((char *)IObuff, _("1 line %sed %d times"), s, amount);
+ } else {
+ if (amount == 1)
+ sprintf((char *)IObuff, _("%ld lines %sed 1 time"),
+ oap->line_count, s);
+ else
+ sprintf((char *)IObuff, _("%ld lines %sed %d times"),
+ oap->line_count, s, amount);
+ }
+ msg(IObuff);
+ }
+
+ /*
+ * Set "'[" and "']" marks.
+ */
+ curbuf->b_op_start = oap->start;
+ curbuf->b_op_end.lnum = oap->end.lnum;
+ curbuf->b_op_end.col = (colnr_T)STRLEN(ml_get(oap->end.lnum));
+ if (curbuf->b_op_end.col > 0)
+ --curbuf->b_op_end.col;
+}
+
+/*
+ * shift the current line one shiftwidth left (if left != 0) or right
+ * leaves cursor on first blank in the line
+ */
+void shift_line(left, round, amount, call_changed_bytes)
+int left;
+int round;
+int amount;
+int call_changed_bytes; /* call changed_bytes() */
+{
+ int count;
+ int i, j;
+ int p_sw = (int)get_sw_value(curbuf);
+
+ count = get_indent(); /* get current indent */
+
+ if (round) { /* round off indent */
+ i = count / p_sw; /* number of p_sw rounded down */
+ j = count % p_sw; /* extra spaces */
+ if (j && left) /* first remove extra spaces */
+ --amount;
+ if (left) {
+ i -= amount;
+ if (i < 0)
+ i = 0;
+ } else
+ i += amount;
+ count = i * p_sw;
+ } else { /* original vi indent */
+ if (left) {
+ count -= p_sw * amount;
+ if (count < 0)
+ count = 0;
+ } else
+ count += p_sw * amount;
+ }
+
+ /* Set new indent */
+ if (State & VREPLACE_FLAG)
+ change_indent(INDENT_SET, count, FALSE, NUL, call_changed_bytes);
+ else
+ (void)set_indent(count, call_changed_bytes ? SIN_CHANGED : 0);
+}
+
+/*
+ * Shift one line of the current block one shiftwidth right or left.
+ * Leaves cursor on first character in block.
+ */
+static void shift_block(oap, amount)
+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 = (int)get_sw_value(curbuf);
+ 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;
+
+ 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)
+ return;
+
+ /* total is number of screen columns to be inserted/removed */
+ total = amount * p_sw;
+ oldp = ml_get_curline();
+
+ if (!left) {
+ /*
+ * 1. Get start vcol
+ * 2. Total ws vcols
+ * 3. Divvy into TABs & spp
+ * 4. Construct new string
+ */
+ total += bd.pre_whitesp; /* all virtual WS upto & incl a split TAB */
+ ws_vcol = bd.start_vcol - bd.pre_whitesp;
+ if (bd.startspaces) {
+ if (has_mbyte)
+ bd.textstart += (*mb_ptr2len)(bd.textstart);
+ else
+ ++bd.textstart;
+ }
+ for (; vim_iswhite(*bd.textstart); ) {
+ incr = lbr_chartabsize_adv(&bd.textstart, (colnr_T)(bd.start_vcol));
+ total += incr;
+ bd.start_vcol += incr;
+ }
+ /* OK, now total=all the VWS reqd, and textstart points at the 1st
+ * non-ws char in the block. */
+ if (!curbuf->b_p_et)
+ i = ((ws_vcol % p_ts) + total) / p_ts; /* number of tabs */
+ if (i)
+ j = ((ws_vcol % p_ts) + total) % p_ts; /* number of spp */
+ else
+ 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 = alloc_check((unsigned)(bd.textcol + i + j + len));
+ if (newp == NULL)
+ return;
+ vim_memset(newp, NUL, (size_t)(bd.textcol + i + j + len));
+ mch_memmove(newp, oldp, (size_t)bd.textcol);
+ copy_chars(newp + bd.textcol, (size_t)i, TAB);
+ copy_spaces(newp + bd.textcol + i, (size_t)j);
+ /* the end */
+ mch_memmove(newp + bd.textcol + i + j, bd.textstart, (size_t)len);
+ } else { /* left */
+ colnr_T destination_col; /* column to which text in block will
+ be shifted */
+ char_u *verbatim_copy_end; /* end of the part of the line which is
+ copied verbatim */
+ colnr_T verbatim_copy_width; /* the (displayed) width of this part
+ of line */
+ unsigned fill; /* nr of spaces that replace a TAB */
+ unsigned new_line_len; /* the length of the line after the
+ block shift */
+ size_t block_space_width;
+ size_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
+ * displayed after the block's start column and the character's column
+ * number. Also, let's calculate the width of all the whitespace
+ * characters that are displayed in the block and precede the searched
+ * non-whitespace character.
+ */
+
+ /* 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);
+
+ /* The character's column is in "bd.start_vcol". */
+ non_white_col = bd.start_vcol;
+
+ while (vim_iswhite(*non_white)) {
+ incr = lbr_chartabsize_adv(&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 < (size_t)total
+ ? block_space_width : (size_t)total);
+
+ /* The column to which we will shift the text. */
+ destination_col = (colnr_T)(non_white_col - shift_amount);
+
+ /* Now let's find out how much of the beginning of the line we can
+ * reuse without modification. */
+ verbatim_copy_end = bd.textstart;
+ verbatim_copy_width = bd.start_vcol;
+
+ /* If "bd.startspaces" is set, "bd.textstart" points to the character
+ * preceding the block. We have to subtract its width to obtain its
+ * column number. */
+ if (bd.startspaces)
+ verbatim_copy_width -= bd.start_char_vcols;
+ while (verbatim_copy_width < destination_col) {
+ incr = lbr_chartabsize(verbatim_copy_end, verbatim_copy_width);
+ if (verbatim_copy_width + incr > destination_col)
+ break;
+ verbatim_copy_width += incr;
+ mb_ptr_adv(verbatim_copy_end);
+ }
+
+ /* If "destination_col" is different from the width of the initial
+ * part of the line that will be copied, it means we encountered a tab
+ * character, which we will have to partly replace with spaces. */
+ fill = destination_col - verbatim_copy_width;
+
+ /* The replacement line will consist of:
+ * - the beginning of the original line up to "verbatim_copy_end",
+ * - "fill" number of spaces,
+ * - the rest of the line, pointed to by non_white. */
+ new_line_len = (unsigned)(verbatim_copy_end - oldp)
+ + fill
+ + (unsigned)STRLEN(non_white) + 1;
+
+ newp = alloc_check(new_line_len);
+ if (newp == NULL)
+ return;
+ mch_memmove(newp, oldp, (size_t)(verbatim_copy_end - oldp));
+ copy_spaces(newp + (verbatim_copy_end - oldp), (size_t)fill);
+ STRMOVE(newp + (verbatim_copy_end - oldp) + fill, non_white);
+ }
+ /* 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;
+ p_ri = old_p_ri;
+}
+
+/*
+ * Insert string "s" (b_insert ? before : after) block :AKelly
+ * Caller must prepare for undo.
+ */
+static void block_insert(oap, s, b_insert, bdp)
+oparg_T *oap;
+char_u *s;
+int b_insert;
+struct block_def *bdp;
+{
+ int p_ts;
+ int count = 0; /* extra spaces to replace a cut TAB */
+ int spaces = 0; /* non-zero if cutting a TAB */
+ colnr_T offset; /* pointer along new line */
+ unsigned s_len; /* STRLEN(s) */
+ char_u *newp, *oldp; /* new, old lines */
+ linenr_T lnum; /* loop var */
+ int oldstate = State;
+
+ State = INSERT; /* don't want REPLACE for State */
+ s_len = (unsigned)STRLEN(s);
+
+ for (lnum = oap->start.lnum + 1; lnum <= oap->end.lnum; lnum++) {
+ block_prep(oap, bdp, lnum, TRUE);
+ if (bdp->is_short && b_insert)
+ continue; /* OP_INSERT, line ends before block start */
+
+ oldp = ml_get(lnum);
+
+ if (b_insert) {
+ p_ts = bdp->start_char_vcols;
+ spaces = bdp->startspaces;
+ if (spaces != 0)
+ count = p_ts - 1; /* we're cutting a TAB */
+ offset = bdp->textcol;
+ } else { /* append */
+ p_ts = bdp->end_char_vcols;
+ if (!bdp->is_short) { /* spaces = padding after block */
+ spaces = (bdp->endspaces ? p_ts - bdp->endspaces : 0);
+ if (spaces != 0)
+ count = p_ts - 1; /* we're cutting a TAB */
+ offset = bdp->textcol + bdp->textlen - (spaces != 0);
+ } else { /* spaces = padding to block edge */
+ /* if $ used, just append to EOL (ie spaces==0) */
+ if (!bdp->is_MAX)
+ spaces = (oap->end_vcol - bdp->end_vcol) + 1;
+ count = spaces;
+ offset = bdp->textcol + bdp->textlen;
+ }
+ }
+
+ newp = alloc_check((unsigned)(STRLEN(oldp)) + s_len + count + 1);
+ if (newp == NULL)
+ continue;
+
+ /* copy up to shifted part */
+ mch_memmove(newp, oldp, (size_t)(offset));
+ oldp += offset;
+
+ /* insert pre-padding */
+ copy_spaces(newp + offset, (size_t)spaces);
+
+ /* copy the new text */
+ mch_memmove(newp + offset + spaces, s, (size_t)s_len);
+ offset += s_len;
+
+ if (spaces && !bdp->is_short) {
+ /* insert post-padding */
+ copy_spaces(newp + offset + spaces, (size_t)(p_ts - spaces));
+ /* We're splitting a TAB, don't copy it. */
+ oldp++;
+ /* We allowed for that TAB, remember this now */
+ count++;
+ }
+
+ if (spaces > 0)
+ offset += count;
+ STRMOVE(newp + offset, oldp);
+
+ ml_replace(lnum, newp, FALSE);
+
+ if (lnum == oap->end.lnum) {
+ /* Set "']" mark to the end of the block instead of the end of
+ * the insert in the first line. */
+ curbuf->b_op_end.lnum = oap->end.lnum;
+ curbuf->b_op_end.col = offset;
+ }
+ } /* for all lnum */
+
+ changed_lines(oap->start.lnum + 1, 0, oap->end.lnum + 1, 0L);
+
+ State = oldstate;
+}
+
+/*
+ * op_reindent - handle reindenting a block of lines.
+ */
+void op_reindent(oap, how)
+oparg_T *oap;
+int (*how)__ARGS((void));
+{
+ long i;
+ char_u *l;
+ int count;
+ linenr_T first_changed = 0;
+ linenr_T last_changed = 0;
+ linenr_T start_lnum = curwin->w_cursor.lnum;
+
+ /* Don't even try when 'modifiable' is off. */
+ if (!curbuf->b_p_ma) {
+ EMSG(_(e_modifiable));
+ return;
+ }
+
+ for (i = oap->line_count; --i >= 0 && !got_int; ) {
+ /* it's a slow thing to do, so give feedback so there's no worry that
+ * the computer's just hung. */
+
+ if (i > 1
+ && (i % 50 == 0 || i == oap->line_count - 1)
+ && oap->line_count > p_report)
+ smsg((char_u *)_("%ld lines to indent... "), i);
+
+ /*
+ * Be vi-compatible: For lisp indenting the first line is not
+ * indented, unless there is only one line.
+ */
+ if (i != oap->line_count - 1 || oap->line_count == 1
+ || how != get_lisp_indent) {
+ l = skipwhite(ml_get_curline());
+ if (*l == NUL) /* empty or blank line */
+ count = 0;
+ else
+ count = how(); /* get the indent for this line */
+
+ if (set_indent(count, SIN_UNDO)) {
+ /* did change the indent, call changed_lines() later */
+ if (first_changed == 0)
+ first_changed = curwin->w_cursor.lnum;
+ last_changed = curwin->w_cursor.lnum;
+ }
+ }
+ ++curwin->w_cursor.lnum;
+ curwin->w_cursor.col = 0; /* make sure it's valid */
+ }
+
+ /* put cursor on first non-blank of indented line */
+ curwin->w_cursor.lnum = start_lnum;
+ beginline(BL_SOL | BL_FIX);
+
+ /* 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)
+ changed_lines(first_changed, 0,
+ oap->is_VIsual ? start_lnum + oap->line_count :
+ last_changed + 1, 0L);
+ else if (oap->is_VIsual)
+ redraw_curbuf_later(INVERTED);
+
+ if (oap->line_count > p_report) {
+ i = oap->line_count - (i + 1);
+ if (i == 1)
+ MSG(_("1 line indented "));
+ else
+ smsg((char_u *)_("%ld lines indented "), i);
+ }
+ /* set '[ and '] marks */
+ curbuf->b_op_start = oap->start;
+ curbuf->b_op_end = oap->end;
+}
+
+/*
+ * Keep the last expression line here, for repeating.
+ */
+static char_u *expr_line = NULL;
+
+/*
+ * Get an expression for the "\"=expr1" or "CTRL-R =expr1"
+ * Returns '=' when OK, NUL otherwise.
+ */
+int get_expr_register() {
+ char_u *new_line;
+
+ new_line = getcmdline('=', 0L, 0);
+ if (new_line == NULL)
+ return NUL;
+ if (*new_line == NUL) /* use previous line */
+ vim_free(new_line);
+ else
+ set_expr_line(new_line);
+ return '=';
+}
+
+/*
+ * Set the expression for the '=' register.
+ * Argument must be an allocated string.
+ */
+void set_expr_line(new_line)
+char_u *new_line;
+{
+ vim_free(expr_line);
+ expr_line = new_line;
+}
+
+/*
+ * Get the result of the '=' register expression.
+ * Returns a pointer to allocated memory, or NULL for failure.
+ */
+char_u * get_expr_line() {
+ char_u *expr_copy;
+ char_u *rv;
+ static int nested = 0;
+
+ if (expr_line == NULL)
+ return NULL;
+
+ /* Make a copy of the expression, because evaluating it may cause it to be
+ * changed. */
+ expr_copy = vim_strsave(expr_line);
+ if (expr_copy == NULL)
+ return NULL;
+
+ /* When we are invoked recursively limit the evaluation to 10 levels.
+ * Then return the string as-is. */
+ if (nested >= 10)
+ return expr_copy;
+
+ ++nested;
+ rv = eval_to_string(expr_copy, NULL, TRUE);
+ --nested;
+ vim_free(expr_copy);
+ return rv;
+}
+
+/*
+ * Get the '=' register expression itself, without evaluating it.
+ */
+char_u * get_expr_line_src() {
+ if (expr_line == NULL)
+ return NULL;
+ return vim_strsave(expr_line);
+}
+
+/*
+ * Check if 'regname' is a valid name of a yank register.
+ * Note: There is no check for 0 (default register), caller should do this
+ */
+int valid_yank_reg(regname, writing)
+int regname;
+int writing; /* if TRUE check for writable registers */
+{
+ if ( (regname > 0 && ASCII_ISALNUM(regname))
+ || (!writing && vim_strchr((char_u *)
+ "/.%#:="
+ , regname) != NULL)
+ || regname == '"'
+ || regname == '-'
+ || regname == '_'
+ )
+ return TRUE;
+ return FALSE;
+}
+
+/*
+ * Set y_current and y_append, according to the value of "regname".
+ * Cannot handle the '_' register.
+ * Must only be called with a valid register name!
+ *
+ * If regname is 0 and writing, use register 0
+ * If regname is 0 and reading, use previous register
+ */
+void get_yank_register(regname, writing)
+int regname;
+int writing;
+{
+ int i;
+
+ y_append = FALSE;
+ if ((regname == 0 || regname == '"') && !writing && y_previous != NULL) {
+ y_current = y_previous;
+ return;
+ }
+ i = regname;
+ if (VIM_ISDIGIT(i))
+ i -= '0';
+ else if (ASCII_ISLOWER(i))
+ i = CharOrdLow(i) + 10;
+ else if (ASCII_ISUPPER(i)) {
+ i = CharOrdUp(i) + 10;
+ y_append = TRUE;
+ } else if (regname == '-')
+ i = DELETION_REGISTER;
+ else /* not 0-9, a-z, A-Z or '-': use register 0 */
+ i = 0;
+ y_current = &(y_regs[i]);
+ if (writing) /* remember the register we write into for do_put() */
+ y_previous = y_current;
+}
+
+
+/*
+ * Obtain the contents of a "normal" register. The register is made empty.
+ * The returned pointer has allocated memory, use put_register() later.
+ */
+void * get_register(name, copy)
+int name;
+int copy; /* make a copy, if FALSE make register empty. */
+{
+ struct yankreg *reg;
+ int i;
+
+
+ get_yank_register(name, 0);
+ reg = (struct yankreg *)alloc((unsigned)sizeof(struct yankreg));
+ if (reg != NULL) {
+ *reg = *y_current;
+ if (copy) {
+ /* If we run out of memory some or all of the lines are empty. */
+ if (reg->y_size == 0)
+ reg->y_array = NULL;
+ else
+ reg->y_array = (char_u **)alloc((unsigned)(sizeof(char_u *)
+ * reg->y_size));
+ if (reg->y_array != NULL) {
+ for (i = 0; i < reg->y_size; ++i)
+ reg->y_array[i] = vim_strsave(y_current->y_array[i]);
+ }
+ } else
+ y_current->y_array = NULL;
+ }
+ return (void *)reg;
+}
+
+/*
+ * Put "reg" into register "name". Free any previous contents and "reg".
+ */
+void put_register(name, reg)
+int name;
+void *reg;
+{
+ get_yank_register(name, 0);
+ free_yank_all();
+ *y_current = *(struct yankreg *)reg;
+ vim_free(reg);
+
+}
+
+void free_register(reg)
+void *reg;
+{
+ struct yankreg tmp;
+
+ tmp = *y_current;
+ *y_current = *(struct yankreg *)reg;
+ free_yank_all();
+ vim_free(reg);
+ *y_current = tmp;
+}
+
+/*
+ * return TRUE if the current yank register has type MLINE
+ */
+int yank_register_mline(regname)
+int regname;
+{
+ if (regname != 0 && !valid_yank_reg(regname, FALSE))
+ return FALSE;
+ if (regname == '_') /* black hole is always empty */
+ return FALSE;
+ get_yank_register(regname, FALSE);
+ return y_current->y_type == MLINE;
+}
+
+/*
+ * Start or stop recording into a yank register.
+ *
+ * Return FAIL for failure, OK otherwise.
+ */
+int do_record(c)
+int c;
+{
+ char_u *p;
+ static int regname;
+ struct yankreg *old_y_previous, *old_y_current;
+ int retval;
+
+ if (Recording == FALSE) { /* start recording */
+ /* registers 0-9, a-z and " are allowed */
+ if (c < 0 || (!ASCII_ISALNUM(c) && c != '"'))
+ retval = FAIL;
+ else {
+ Recording = TRUE;
+ showmode();
+ regname = c;
+ retval = OK;
+ }
+ } else { /* stop recording */
+ /*
+ * Get the recorded key hits. K_SPECIAL and CSI will be escaped, this
+ * needs to be removed again to put it in a register. exec_reg then
+ * adds the escaping back later.
+ */
+ Recording = FALSE;
+ MSG("");
+ p = get_recorded();
+ if (p == NULL)
+ retval = FAIL;
+ else {
+ /* Remove escaping for CSI and K_SPECIAL in multi-byte chars. */
+ vim_unescape_csi(p);
+
+ /*
+ * We don't want to change the default register here, so save and
+ * restore the current register name.
+ */
+ old_y_previous = y_previous;
+ old_y_current = y_current;
+
+ retval = stuff_yank(regname, p);
+
+ y_previous = old_y_previous;
+ y_current = old_y_current;
+ }
+ }
+ return retval;
+}
+
+/*
+ * Stuff string "p" into yank register "regname" as a single line (append if
+ * uppercase). "p" must have been alloced.
+ *
+ * return FAIL for failure, OK otherwise
+ */
+static int stuff_yank(regname, p)
+int regname;
+char_u *p;
+{
+ char_u *lp;
+ char_u **pp;
+
+ /* check for read-only register */
+ if (regname != 0 && !valid_yank_reg(regname, TRUE)) {
+ vim_free(p);
+ return FAIL;
+ }
+ if (regname == '_') { /* black hole: don't do anything */
+ vim_free(p);
+ return OK;
+ }
+ get_yank_register(regname, TRUE);
+ if (y_append && y_current->y_array != NULL) {
+ pp = &(y_current->y_array[y_current->y_size - 1]);
+ lp = lalloc((long_u)(STRLEN(*pp) + STRLEN(p) + 1), TRUE);
+ if (lp == NULL) {
+ vim_free(p);
+ return FAIL;
+ }
+ STRCPY(lp, *pp);
+ STRCAT(lp, p);
+ vim_free(p);
+ vim_free(*pp);
+ *pp = lp;
+ } else {
+ free_yank_all();
+ if ((y_current->y_array =
+ (char_u **)alloc((unsigned)sizeof(char_u *))) == NULL) {
+ vim_free(p);
+ return FAIL;
+ }
+ y_current->y_array[0] = p;
+ y_current->y_size = 1;
+ y_current->y_type = MCHAR; /* used to be MLINE, why? */
+ }
+ return OK;
+}
+
+static int execreg_lastc = NUL;
+
+/*
+ * execute a yank register: copy it into the stuff buffer
+ *
+ * return FAIL for failure, OK otherwise
+ */
+int do_execreg(regname, colon, addcr, silent)
+int regname;
+int colon; /* insert ':' before each line */
+int addcr; /* always add '\n' to end of line */
+int silent; /* set "silent" flag in typeahead buffer */
+{
+ long i;
+ char_u *p;
+ int retval = OK;
+ int remap;
+
+ if (regname == '@') { /* repeat previous one */
+ if (execreg_lastc == NUL) {
+ EMSG(_("E748: No previously used register"));
+ return FAIL;
+ }
+ regname = execreg_lastc;
+ }
+ /* check for valid regname */
+ if (regname == '%' || regname == '#' || !valid_yank_reg(regname, FALSE)) {
+ emsg_invreg(regname);
+ return FAIL;
+ }
+ execreg_lastc = regname;
+
+
+ if (regname == '_') /* black hole: don't stuff anything */
+ return OK;
+
+ if (regname == ':') { /* use last command line */
+ if (last_cmdline == NULL) {
+ EMSG(_(e_nolastcmd));
+ return FAIL;
+ }
+ vim_free(new_last_cmdline); /* don't keep the cmdline containing @: */
+ new_last_cmdline = NULL;
+ /* Escape all control characters with a CTRL-V */
+ p = vim_strsave_escaped_ext(
+ last_cmdline,
+ (char_u *)
+ "\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037",
+ Ctrl_V, FALSE);
+ if (p != NULL) {
+ /* When in Visual mode "'<,'>" will be prepended to the command.
+ * Remove it when it's already there. */
+ if (VIsual_active && STRNCMP(p, "'<,'>", 5) == 0)
+ retval = put_in_typebuf(p + 5, TRUE, TRUE, silent);
+ else
+ retval = put_in_typebuf(p, TRUE, TRUE, silent);
+ }
+ vim_free(p);
+ } else if (regname == '=') {
+ p = get_expr_line();
+ if (p == NULL)
+ return FAIL;
+ retval = put_in_typebuf(p, TRUE, colon, silent);
+ vim_free(p);
+ } else if (regname == '.') { /* use last inserted text */
+ p = get_last_insert_save();
+ if (p == NULL) {
+ EMSG(_(e_noinstext));
+ return FAIL;
+ }
+ retval = put_in_typebuf(p, FALSE, colon, silent);
+ vim_free(p);
+ } else {
+ get_yank_register(regname, FALSE);
+ if (y_current->y_array == NULL)
+ return FAIL;
+
+ /* Disallow remaping for ":@r". */
+ remap = colon ? REMAP_NONE : REMAP_YES;
+
+ /*
+ * Insert lines into typeahead buffer, from last one to first one.
+ */
+ put_reedit_in_typebuf(silent);
+ for (i = y_current->y_size; --i >= 0; ) {
+ char_u *escaped;
+
+ /* insert NL between lines and after last line if type is MLINE */
+ if (y_current->y_type == MLINE || i < y_current->y_size - 1
+ || addcr) {
+ if (ins_typebuf((char_u *)"\n", remap, 0, TRUE, silent) == FAIL)
+ return FAIL;
+ }
+ escaped = vim_strsave_escape_csi(y_current->y_array[i]);
+ if (escaped == NULL)
+ return FAIL;
+ retval = ins_typebuf(escaped, remap, 0, TRUE, silent);
+ vim_free(escaped);
+ if (retval == FAIL)
+ return FAIL;
+ if (colon && ins_typebuf((char_u *)":", remap, 0, TRUE, silent)
+ == FAIL)
+ return FAIL;
+ }
+ Exec_reg = TRUE; /* disable the 'q' command */
+ }
+ return retval;
+}
+
+/*
+ * If "restart_edit" is not zero, put it in the typeahead buffer, so that it's
+ * used only after other typeahead has been processed.
+ */
+static void put_reedit_in_typebuf(silent)
+int silent;
+{
+ char_u buf[3];
+
+ if (restart_edit != NUL) {
+ if (restart_edit == 'V') {
+ buf[0] = 'g';
+ buf[1] = 'R';
+ buf[2] = NUL;
+ } else {
+ buf[0] = restart_edit == 'I' ? 'i' : restart_edit;
+ buf[1] = NUL;
+ }
+ if (ins_typebuf(buf, REMAP_NONE, 0, TRUE, silent) == OK)
+ restart_edit = NUL;
+ }
+}
+
+/*
+ * Insert register contents "s" into the typeahead buffer, so that it will be
+ * executed again.
+ * When "esc" is TRUE it is to be taken literally: Escape CSI characters and
+ * no remapping.
+ */
+static int put_in_typebuf(s, esc, colon, silent)
+char_u *s;
+int esc;
+int colon; /* add ':' before the line */
+int silent;
+{
+ int retval = OK;
+
+ put_reedit_in_typebuf(silent);
+ if (colon)
+ retval = ins_typebuf((char_u *)"\n", REMAP_NONE, 0, TRUE, silent);
+ if (retval == OK) {
+ char_u *p;
+
+ if (esc)
+ p = vim_strsave_escape_csi(s);
+ else
+ p = s;
+ if (p == NULL)
+ retval = FAIL;
+ else
+ retval = ins_typebuf(p, esc ? REMAP_NONE : REMAP_YES,
+ 0, TRUE, silent);
+ if (esc)
+ vim_free(p);
+ }
+ if (colon && retval == OK)
+ retval = ins_typebuf((char_u *)":", REMAP_NONE, 0, TRUE, silent);
+ return retval;
+}
+
+/*
+ * Insert a yank register: copy it into the Read buffer.
+ * Used by CTRL-R command and middle mouse button in insert mode.
+ *
+ * return FAIL for failure, OK otherwise
+ */
+int insert_reg(regname, literally)
+int regname;
+int literally; /* insert literally, not as if typed */
+{
+ long i;
+ int retval = OK;
+ char_u *arg;
+ int allocated;
+
+ /*
+ * It is possible to get into an endless loop by having CTRL-R a in
+ * register a and then, in insert mode, doing CTRL-R a.
+ * If you hit CTRL-C, the loop will be broken here.
+ */
+ ui_breakcheck();
+ if (got_int)
+ return FAIL;
+
+ /* check for valid regname */
+ 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)
+ return FAIL;
+ stuffescaped(arg, literally);
+ if (allocated)
+ vim_free(arg);
+ } else { /* name or number register */
+ get_yank_register(regname, FALSE);
+ if (y_current->y_array == NULL)
+ retval = FAIL;
+ else {
+ for (i = 0; i < y_current->y_size; ++i) {
+ stuffescaped(y_current->y_array[i], literally);
+ /*
+ * Insert a newline between lines and after last line if
+ * y_type is MLINE.
+ */
+ if (y_current->y_type == MLINE || i < y_current->y_size - 1)
+ stuffcharReadbuff('\n');
+ }
+ }
+ }
+
+ return retval;
+}
+
+/*
+ * 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(arg, literally)
+char_u *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 /* EBCDIC: chars above space are normal */
+ )
+ || (*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))
+ 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(regname, argp, allocated, errmsg)
+int regname;
+char_u **argp;
+int *allocated; /* return: TRUE when value was allocated */
+int errmsg; /* give error message when failing */
+{
+ int cnt;
+
+ *argp = NULL;
+ *allocated = FALSE;
+ switch (regname) {
+ case '%': /* file name */
+ if (errmsg)
+ check_fname(); /* will give emsg if not set */
+ *argp = curbuf->b_fname;
+ 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;
+
+ case ':': /* last command line */
+ if (last_cmdline == NULL && errmsg)
+ EMSG(_(e_nolastcmd));
+ *argp = last_cmdline;
+ return TRUE;
+
+ case '/': /* last search-pattern */
+ if (last_search_pat() == NULL && errmsg)
+ EMSG(_(e_noprevre));
+ *argp = last_search_pat();
+ return TRUE;
+
+ case '.': /* last inserted text */
+ *argp = get_last_insert_save();
+ *allocated = TRUE;
+ if (*argp == NULL && errmsg)
+ EMSG(_(e_noinstext));
+ 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;
+ 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;
+
+ case '_': /* black hole: always empty */
+ *argp = (char_u *)"";
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/*
+ * Paste a yank register into the command line.
+ * Only for non-special registers.
+ * Used by CTRL-R command in command-line mode
+ * insert_reg() can't be used here, because special characters from the
+ * register contents will be interpreted as commands.
+ *
+ * return FAIL for failure, OK otherwise
+ */
+int cmdline_paste_reg(regname, literally, remcr)
+int regname;
+int literally; /* Insert text literally instead of "as typed" */
+int remcr; /* don't add trailing CR */
+{
+ long i;
+
+ get_yank_register(regname, FALSE);
+ if (y_current->y_array == NULL)
+ return FAIL;
+
+ for (i = 0; i < y_current->y_size; ++i) {
+ cmdline_paste_str(y_current->y_array[i], literally);
+
+ /* Insert ^M between lines and after last line if type is MLINE.
+ * Don't do this when "remcr" is TRUE and the next line is empty. */
+ if (y_current->y_type == MLINE
+ || (i < y_current->y_size - 1
+ && !(remcr
+ && i == y_current->y_size - 2
+ && *y_current->y_array[i + 1] == NUL)))
+ cmdline_paste_str((char_u *)"\r", literally);
+
+ /* Check for CTRL-C, in case someone tries to paste a few thousand
+ * lines and gets bored. */
+ ui_breakcheck();
+ if (got_int)
+ return FAIL;
+ }
+ return OK;
+}
+
+
+/*
+ * Handle a delete operation.
+ *
+ * Return FAIL if undo failed, OK otherwise.
+ */
+int op_delete(oap)
+oparg_T *oap;
+{
+ int n;
+ linenr_T lnum;
+ char_u *ptr;
+ char_u *newp, *oldp;
+ struct block_def bd;
+ linenr_T old_lcount = curbuf->b_ml.ml_line_count;
+ int did_yank = FALSE;
+ int orig_regname = oap->regname;
+
+ if (curbuf->b_ml.ml_flags & ML_EMPTY) /* nothing to do */
+ return OK;
+
+ /* Nothing to delete, return here. Do prepare undo, for op_change(). */
+ if (oap->empty)
+ return u_save_cursor();
+
+ if (!curbuf->b_p_ma) {
+ EMSG(_(e_modifiable));
+ return FAIL;
+ }
+
+
+ if (has_mbyte)
+ mb_adjust_opend(oap);
+
+ /*
+ * Imitate the strange Vi behaviour: If the delete spans more than one
+ * line and motion_type == MCHAR and the result is a blank line, make the
+ * delete linewise. Don't do this for the change command or Visual mode.
+ */
+ if ( oap->motion_type == MCHAR
+ && !oap->is_VIsual
+ && !oap->block_mode
+ && oap->line_count > 1
+ && oap->motion_force == NUL
+ && oap->op_type == OP_DELETE) {
+ ptr = ml_get(oap->end.lnum) + oap->end.col;
+ if (*ptr != NUL)
+ ptr += oap->inclusive;
+ ptr = skipwhite(ptr);
+ if (*ptr == NUL && inindent(0))
+ oap->motion_type = MLINE;
+ }
+
+ /*
+ * Check for trying to delete (e.g. "D") in an empty line.
+ * Note: For the change operator it is ok.
+ */
+ if ( oap->motion_type == MCHAR
+ && oap->line_count == 1
+ && oap->op_type == OP_DELETE
+ && *ml_get(oap->start.lnum) == NUL) {
+ /*
+ * It's an error to operate on an empty region, when 'E' included in
+ * 'cpoptions' (Vi compatible).
+ */
+ if (virtual_op)
+ /* Virtual editing: Nothing gets deleted, but we set the '[ and ']
+ * marks as if it happened. */
+ goto setmarks;
+ if (vim_strchr(p_cpo, CPO_EMPTYREGION) != NULL)
+ beep_flush();
+ return OK;
+ }
+
+ /*
+ * Do a yank of whatever we're about to delete.
+ * If a yank register was specified, put the deleted text into that
+ * register. For the black hole register '_' don't yank anything.
+ */
+ if (oap->regname != '_') {
+ if (oap->regname != 0) {
+ /* check for read-only register */
+ if (!valid_yank_reg(oap->regname, TRUE)) {
+ beep_flush();
+ return OK;
+ }
+ get_yank_register(oap->regname, TRUE); /* yank into specif'd reg. */
+ if (op_yank(oap, TRUE, FALSE) == OK) /* yank without message */
+ did_yank = TRUE;
+ }
+
+ /*
+ * Put deleted text into register 1 and shift number registers if the
+ * delete contains a line break, or when a regname has been specified.
+ * Use the register name from before adjust_clip_reg() may have
+ * changed it.
+ */
+ if (orig_regname != 0 || oap->motion_type == MLINE
+ || oap->line_count > 1 || oap->use_reg_one) {
+ y_current = &y_regs[9];
+ free_yank_all(); /* free register nine */
+ for (n = 9; n > 1; --n)
+ y_regs[n] = y_regs[n - 1];
+ y_previous = y_current = &y_regs[1];
+ y_regs[1].y_array = NULL; /* set register one to empty */
+ if (op_yank(oap, TRUE, FALSE) == OK)
+ did_yank = TRUE;
+ }
+
+ /* Yank into small delete register when no named register specified
+ * and the delete is within one line. */
+ if ((
+ oap->regname == 0) && oap->motion_type != MLINE
+ && oap->line_count == 1) {
+ oap->regname = '-';
+ get_yank_register(oap->regname, TRUE);
+ if (op_yank(oap, TRUE, FALSE) == OK)
+ did_yank = TRUE;
+ oap->regname = 0;
+ }
+
+ /*
+ * If there's too much stuff to fit in the yank register, then get a
+ * confirmation before doing the delete. This is crude, but simple.
+ * And it avoids doing a delete of something we can't put back if we
+ * want.
+ */
+ if (!did_yank) {
+ int msg_silent_save = msg_silent;
+
+ msg_silent = 0; /* must display the prompt */
+ n = ask_yesno((char_u *)_("cannot yank; delete anyway"), TRUE);
+ msg_silent = msg_silent_save;
+ if (n != 'y') {
+ EMSG(_(e_abort));
+ return FAIL;
+ }
+ }
+ }
+
+ /*
+ * block mode delete
+ */
+ if (oap->block_mode) {
+ if (u_save((linenr_T)(oap->start.lnum - 1),
+ (linenr_T)(oap->end.lnum + 1)) == FAIL)
+ 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 */
+ continue;
+
+ /* Adjust cursor position for tab replaced by spaces and 'lbr'. */
+ if (lnum == curwin->w_cursor.lnum) {
+ curwin->w_cursor.col = bd.textcol + bd.startspaces;
+ curwin->w_cursor.coladd = 0;
+ }
+
+ /* n == number of chars deleted
+ * If we delete a TAB, it may be replaced by several characters.
+ * Thus the number of characters may increase!
+ */
+ n = bd.textlen - bd.startspaces - bd.endspaces;
+ oldp = ml_get(lnum);
+ newp = alloc_check((unsigned)STRLEN(oldp) + 1 - n);
+ if (newp == NULL)
+ continue;
+ /* copy up to deleted part */
+ mch_memmove(newp, oldp, (size_t)bd.textcol);
+ /* insert spaces */
+ copy_spaces(newp + bd.textcol,
+ (size_t)(bd.startspaces + bd.endspaces));
+ /* copy the part after the deleted part */
+ oldp += bd.textcol + bd.textlen;
+ STRMOVE(newp + bd.textcol + bd.startspaces + bd.endspaces, oldp);
+ /* replace the line */
+ ml_replace(lnum, newp, FALSE);
+ }
+
+ check_cursor_col();
+ changed_lines(curwin->w_cursor.lnum, curwin->w_cursor.col,
+ oap->end.lnum + 1, 0L);
+ oap->line_count = 0; /* no lines deleted */
+ } else if (oap->motion_type == MLINE) {
+ if (oap->op_type == OP_CHANGE) {
+ /* Delete the lines except the first one. Temporarily move the
+ * cursor to the next line. Save the current line number, if the
+ * last line is deleted it may be changed.
+ */
+ if (oap->line_count > 1) {
+ lnum = curwin->w_cursor.lnum;
+ ++curwin->w_cursor.lnum;
+ del_lines((long)(oap->line_count - 1), TRUE);
+ curwin->w_cursor.lnum = lnum;
+ }
+ 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 */
+ ai_col = curwin->w_cursor.col;
+ } else
+ beginline(0); /* cursor in column 0 */
+ truncate_line(FALSE); /* delete the rest of the line */
+ /* leave cursor past last char in line */
+ if (oap->line_count > 1)
+ u_clearline(); /* "U" command not possible after "2cc" */
+ } else {
+ del_lines(oap->line_count, TRUE);
+ beginline(BL_WHITE | BL_FIX);
+ u_clearline(); /* "U" command not possible after "dd" */
+ }
+ } else {
+ if (virtual_op) {
+ int endcol = 0;
+
+ /* For virtualedit: break the tabs that are partly included. */
+ if (gchar_pos(&oap->start) == '\t') {
+ if (u_save_cursor() == FAIL) /* save first line for undo */
+ return FAIL;
+ if (oap->line_count == 1)
+ endcol = getviscol2(oap->end.col, oap->end.coladd);
+ coladvance_force(getviscol2(oap->start.col, oap->start.coladd));
+ oap->start = curwin->w_cursor;
+ if (oap->line_count == 1) {
+ coladvance(endcol);
+ oap->end.col = curwin->w_cursor.col;
+ oap->end.coladd = curwin->w_cursor.coladd;
+ curwin->w_cursor = oap->start;
+ }
+ }
+
+ /* Break a tab only when it's included in the area. */
+ if (gchar_pos(&oap->end) == '\t'
+ && (int)oap->end.coladd < oap->inclusive) {
+ /* save last line for undo */
+ if (u_save((linenr_T)(oap->end.lnum - 1),
+ (linenr_T)(oap->end.lnum + 1)) == FAIL)
+ return FAIL;
+ curwin->w_cursor = oap->end;
+ coladvance_force(getviscol2(oap->end.col, oap->end.coladd));
+ oap->end = curwin->w_cursor;
+ curwin->w_cursor = oap->start;
+ }
+ }
+
+ if (oap->line_count == 1) { /* delete characters within one line */
+ if (u_save_cursor() == FAIL) /* save line for undo */
+ return FAIL;
+
+ /* if 'cpoptions' contains '$', display '$' at end of change */
+ if ( vim_strchr(p_cpo, CPO_DOLLAR) != NULL
+ && oap->op_type == OP_CHANGE
+ && oap->end.lnum == curwin->w_cursor.lnum
+ && !oap->is_VIsual
+ )
+ display_dollar(oap->end.col - !oap->inclusive);
+
+ n = oap->end.col - oap->start.col + 1 - !oap->inclusive;
+
+ if (virtual_op) {
+ /* fix up things for virtualedit-delete:
+ * break the tabs which are going to get in our way
+ */
+ char_u *curline = ml_get_curline();
+ int len = (int)STRLEN(curline);
+
+ if (oap->end.coladd != 0
+ && (int)oap->end.col >= len - 1
+ && !(oap->start.coladd && (int)oap->end.col >= len - 1))
+ n++;
+ /* Delete at least one char (e.g, when on a control char). */
+ if (n == 0 && oap->start.coladd != oap->end.coladd)
+ n = 1;
+
+ /* When deleted a char in the line, reset coladd. */
+ if (gchar_cursor() != NUL)
+ curwin->w_cursor.coladd = 0;
+ }
+ if (oap->op_type == OP_DELETE
+ && oap->inclusive
+ && oap->end.lnum == curbuf->b_ml.ml_line_count
+ && n > (int)STRLEN(ml_get(oap->end.lnum))) {
+ /* Special case: gH<Del> deletes the last line. */
+ del_lines(1L, FALSE);
+ } else {
+ (void)del_bytes((long)n, !virtual_op, oap->op_type == OP_DELETE
+ && !oap->is_VIsual
+ );
+ }
+ } else { /* delete characters between lines */
+ pos_T curpos;
+ int delete_last_line;
+
+ /* save deleted and changed lines for undo */
+ if (u_save((linenr_T)(curwin->w_cursor.lnum - 1),
+ (linenr_T)(curwin->w_cursor.lnum + oap->line_count)) == FAIL)
+ return FAIL;
+
+ delete_last_line = (oap->end.lnum == curbuf->b_ml.ml_line_count);
+ truncate_line(TRUE); /* delete from cursor to end of line */
+
+ curpos = curwin->w_cursor; /* remember curwin->w_cursor */
+ ++curwin->w_cursor.lnum;
+ del_lines((long)(oap->line_count - 2), FALSE);
+
+ if (delete_last_line)
+ oap->end.lnum = curbuf->b_ml.ml_line_count;
+
+ n = (oap->end.col + 1 - !oap->inclusive);
+ if (oap->inclusive && delete_last_line
+ && n > (int)STRLEN(ml_get(oap->end.lnum))) {
+ /* Special case: gH<Del> deletes the last line. */
+ del_lines(1L, FALSE);
+ curwin->w_cursor = curpos; /* restore curwin->w_cursor */
+ if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count)
+ curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
+ } else {
+ /* delete from start of line until op_end */
+ curwin->w_cursor.col = 0;
+ (void)del_bytes((long)n, !virtual_op, oap->op_type == OP_DELETE
+ && !oap->is_VIsual
+ );
+ curwin->w_cursor = curpos; /* restore curwin->w_cursor */
+ }
+ if (curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count)
+ (void)do_join(2, FALSE, FALSE, FALSE);
+ }
+ }
+
+ msgmore(curbuf->b_ml.ml_line_count - old_lcount);
+
+setmarks:
+ if (oap->block_mode) {
+ curbuf->b_op_end.lnum = oap->end.lnum;
+ curbuf->b_op_end.col = oap->start.col;
+ } else
+ curbuf->b_op_end = oap->start;
+ curbuf->b_op_start = oap->start;
+
+ return OK;
+}
+
+/*
+ * Adjust end of operating area for ending on a multi-byte character.
+ * Used for deletion.
+ */
+static void mb_adjust_opend(oap)
+oparg_T *oap;
+{
+ char_u *p;
+
+ if (oap->inclusive) {
+ p = ml_get(oap->end.lnum);
+ oap->end.col += mb_tail_off(p, p + oap->end.col);
+ }
+}
+
+/*
+ * Replace a whole area with one character.
+ */
+int op_replace(oap, c)
+oparg_T *oap;
+int c;
+{
+ int n, numc;
+ int num_chars;
+ char_u *newp, *oldp;
+ size_t oldlen;
+ struct block_def bd;
+ char_u *after_p = NULL;
+ int had_ctrl_v_cr = (c == -1 || c == -2);
+
+ 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 (has_mbyte)
+ mb_adjust_opend(oap);
+
+ if (u_save((linenr_T)(oap->start.lnum - 1),
+ (linenr_T)(oap->end.lnum + 1)) == FAIL)
+ return FAIL;
+
+ /*
+ * block mode replace
+ */
+ if (oap->block_mode) {
+ 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 */
+
+ /* n == number of extra chars required
+ * If we split a TAB, it may be replaced by several characters.
+ * Thus the number of characters may increase!
+ */
+ /* If the range starts in virtual space, count the initial
+ * coladd offset as part of "startspaces" */
+ if (virtual_op && bd.is_short && *bd.textstart == NUL) {
+ pos_T vpos;
+
+ vpos.lnum = curwin->w_cursor.lnum;
+ getvpos(&vpos, oap->start_vcol);
+ bd.startspaces += vpos.coladd;
+ n = bd.startspaces;
+ } else
+ /* allow for pre spaces */
+ n = (bd.startspaces ? bd.start_char_vcols - 1 : 0);
+
+ /* allow for post spp */
+ n += (bd.endspaces
+ && !bd.is_oneChar
+ && bd.end_char_vcols > 0) ? bd.end_char_vcols - 1 : 0;
+ /* Figure out how many characters to replace. */
+ numc = oap->end_vcol - oap->start_vcol + 1;
+ if (bd.is_short && (!virtual_op || bd.is_MAX))
+ numc -= (oap->end_vcol - bd.end_vcol) + 1;
+
+ /* A double-wide character can be replaced only up to half the
+ * times. */
+ if ((*mb_char2cells)(c) > 1) {
+ if ((numc & 1) && !bd.is_short) {
+ ++bd.endspaces;
+ ++n;
+ }
+ numc = numc / 2;
+ }
+
+ /* Compute bytes needed, move character count to num_chars. */
+ num_chars = numc;
+ numc *= (*mb_char2len)(c);
+ /* oldlen includes textlen, so don't double count */
+ n += numc - bd.textlen;
+
+ oldp = ml_get_curline();
+ oldlen = STRLEN(oldp);
+ newp = alloc_check((unsigned)oldlen + 1 + n);
+ if (newp == NULL)
+ continue;
+ vim_memset(newp, NUL, (size_t)(oldlen + 1 + n));
+ /* copy up to deleted part */
+ mch_memmove(newp, oldp, (size_t)bd.textcol);
+ oldp += bd.textcol + bd.textlen;
+ /* insert pre-spaces */
+ copy_spaces(newp + bd.textcol, (size_t)bd.startspaces);
+ /* insert replacement chars CHECK FOR ALLOCATED SPACE */
+ /* -1/-2 is used for entering CR literally. */
+ if (had_ctrl_v_cr || (c != '\r' && c != '\n')) {
+ if (has_mbyte) {
+ n = (int)STRLEN(newp);
+ while (--num_chars >= 0)
+ n += (*mb_char2bytes)(c, newp + n);
+ } else
+ copy_chars(newp + STRLEN(newp), (size_t)numc, c);
+ if (!bd.is_short) {
+ /* insert post-spaces */
+ copy_spaces(newp + STRLEN(newp), (size_t)bd.endspaces);
+ /* copy the part after the changed part */
+ STRMOVE(newp + STRLEN(newp), oldp);
+ }
+ } else {
+ /* Replacing with \r or \n means splitting the line. */
+ after_p = alloc_check(
+ (unsigned)(oldlen + 1 + n - STRLEN(newp)));
+ if (after_p != NULL)
+ STRMOVE(after_p, oldp);
+ }
+ /* replace the line */
+ ml_replace(curwin->w_cursor.lnum, newp, FALSE);
+ if (after_p != NULL) {
+ ml_append(curwin->w_cursor.lnum++, after_p, 0, FALSE);
+ appended_lines_mark(curwin->w_cursor.lnum, 1L);
+ oap->end.lnum++;
+ vim_free(after_p);
+ }
+ }
+ } else {
+ /*
+ * MCHAR and MLINE motion replace.
+ */
+ if (oap->motion_type == MLINE) {
+ oap->start.col = 0;
+ curwin->w_cursor.col = 0;
+ oap->end.col = (colnr_T)STRLEN(ml_get(oap->end.lnum));
+ if (oap->end.col)
+ --oap->end.col;
+ } else if (!oap->inclusive)
+ dec(&(oap->end));
+
+ while (ltoreq(curwin->w_cursor, oap->end)) {
+ n = gchar_cursor();
+ if (n != NUL) {
+ if ((*mb_char2len)(c) > 1 || (*mb_char2len)(n) > 1) {
+ /* This is slow, but it handles replacing a single-byte
+ * with a multi-byte and the other way around. */
+ if (curwin->w_cursor.lnum == oap->end.lnum)
+ oap->end.col += (*mb_char2len)(c) - (*mb_char2len)(n);
+ n = State;
+ State = REPLACE;
+ ins_char(c);
+ State = n;
+ /* Backup to the replaced character. */
+ dec_cursor();
+ } else {
+ if (n == TAB) {
+ int end_vcol = 0;
+
+ if (curwin->w_cursor.lnum == oap->end.lnum) {
+ /* oap->end has to be recalculated when
+ * the tab breaks */
+ end_vcol = getviscol2(oap->end.col,
+ oap->end.coladd);
+ }
+ coladvance_force(getviscol());
+ if (curwin->w_cursor.lnum == oap->end.lnum)
+ getvpos(&oap->end, end_vcol);
+ }
+ pchar(curwin->w_cursor, c);
+ }
+ } else if (virtual_op && curwin->w_cursor.lnum == oap->end.lnum) {
+ int virtcols = oap->end.coladd;
+
+ if (curwin->w_cursor.lnum == oap->start.lnum
+ && oap->start.col == oap->end.col && oap->start.coladd)
+ virtcols -= oap->start.coladd;
+
+ /* oap->end has been trimmed so it's effectively inclusive;
+ * as a result an extra +1 must be counted so we don't
+ * trample the NUL byte. */
+ coladvance_force(getviscol2(oap->end.col, oap->end.coladd) + 1);
+ curwin->w_cursor.col -= (virtcols + 1);
+ for (; virtcols >= 0; virtcols--) {
+ pchar(curwin->w_cursor, c);
+ if (inc(&curwin->w_cursor) == -1)
+ break;
+ }
+ }
+
+ /* Advance to next character, stop at the end of the file. */
+ if (inc_cursor() == -1)
+ break;
+ }
+ }
+
+ curwin->w_cursor = oap->start;
+ check_cursor();
+ changed_lines(oap->start.lnum, oap->start.col, oap->end.lnum + 1, 0L);
+
+ /* Set "'[" and "']" marks. */
+ curbuf->b_op_start = oap->start;
+ curbuf->b_op_end = oap->end;
+
+ return OK;
+}
+
+static int swapchars __ARGS((int op_type, pos_T *pos, int length));
+
+/*
+ * Handle the (non-standard vi) tilde operator. Also for "gu", "gU" and "g?".
+ */
+void op_tilde(oap)
+oparg_T *oap;
+{
+ pos_T pos;
+ struct block_def bd;
+ int did_change = FALSE;
+
+ if (u_save((linenr_T)(oap->start.lnum - 1),
+ (linenr_T)(oap->end.lnum + 1)) == FAIL)
+ return;
+
+ pos = oap->start;
+ if (oap->block_mode) { /* Visual block mode */
+ for (; pos.lnum <= oap->end.lnum; ++pos.lnum) {
+ int one_change;
+
+ 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);
+ } else { /* not block mode */
+ if (oap->motion_type == MLINE) {
+ oap->start.col = 0;
+ pos.col = 0;
+ oap->end.col = (colnr_T)STRLEN(ml_get(oap->end.lnum));
+ if (oap->end.col)
+ --oap->end.col;
+ } else if (!oap->inclusive)
+ dec(&(oap->end));
+
+ if (pos.lnum == oap->end.lnum)
+ did_change = swapchars(oap->op_type, &pos,
+ oap->end.col - pos.col + 1);
+ else
+ for (;; ) {
+ did_change |= swapchars(oap->op_type, &pos,
+ pos.lnum == oap->end.lnum ? oap->end.col + 1 :
+ (int)STRLEN(ml_get_pos(&pos)));
+ if (ltoreq(oap->end, pos) || inc(&pos) == -1)
+ break;
+ }
+ if (did_change) {
+ changed_lines(oap->start.lnum, oap->start.col, oap->end.lnum + 1,
+ 0L);
+ }
+ }
+
+ if (!did_change && oap->is_VIsual)
+ /* No change: need to remove the Visual selection */
+ redraw_curbuf_later(INVERTED);
+
+ /*
+ * Set '[ and '] marks.
+ */
+ curbuf->b_op_start = oap->start;
+ curbuf->b_op_end = oap->end;
+
+ if (oap->line_count > p_report) {
+ if (oap->line_count == 1)
+ MSG(_("1 line changed"));
+ else
+ smsg((char_u *)_("%ld lines changed"), oap->line_count);
+ }
+}
+
+/*
+ * Invoke swapchar() on "length" bytes at position "pos".
+ * "pos" is advanced to just after the changed characters.
+ * "length" is rounded up to include the whole last multi-byte character.
+ * Also works correctly when the number of bytes changes.
+ * Returns TRUE if some character was changed.
+ */
+static int swapchars(op_type, pos, length)
+int op_type;
+pos_T *pos;
+int length;
+{
+ int todo;
+ int did_change = 0;
+
+ for (todo = length; todo > 0; --todo) {
+ if (has_mbyte) {
+ int len = (*mb_ptr2len)(ml_get_pos(pos));
+
+ /* we're counting bytes, not characters */
+ if (len > 0)
+ todo -= len - 1;
+ }
+ did_change |= swapchar(op_type, pos);
+ if (inc(pos) == -1) /* at end of file */
+ break;
+ }
+ return did_change;
+}
+
+/*
+ * If op_type == OP_UPPER: make uppercase,
+ * if op_type == OP_LOWER: make lowercase,
+ * if op_type == OP_ROT13: do rot13 encoding,
+ * else swap case of character at 'pos'
+ * returns TRUE when something actually changed.
+ */
+int swapchar(op_type, pos)
+int op_type;
+pos_T *pos;
+{
+ int c;
+ int nc;
+
+ c = gchar_pos(pos);
+
+ /* Only do rot13 encoding for ASCII characters. */
+ 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)) {
+ pos_T sp = curwin->w_cursor;
+
+ /* Special handling of German sharp s: change to "SS". */
+ curwin->w_cursor = *pos;
+ del_char(FALSE);
+ ins_char('S');
+ ins_char('S');
+ curwin->w_cursor = sp;
+ inc(pos);
+ }
+
+ if (enc_dbcs != 0 && c >= 0x100) /* No lower/uppercase letter */
+ return FALSE;
+ nc = c;
+ if (MB_ISLOWER(c)) {
+ if (op_type == OP_ROT13)
+ nc = ROT13(c, 'a');
+ 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 = MB_TOLOWER(c);
+ }
+ if (nc != c) {
+ if (enc_utf8 && (c >= 0x80 || nc >= 0x80)) {
+ pos_T sp = curwin->w_cursor;
+
+ curwin->w_cursor = *pos;
+ /* don't use del_char(), it also removes composing chars */
+ del_bytes(utf_ptr2len(ml_get_cursor()), FALSE, FALSE);
+ ins_char(nc);
+ curwin->w_cursor = sp;
+ } else
+ pchar(*pos, nc);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*
+ * op_insert - Insert and append operators for Visual mode.
+ */
+void op_insert(oap, count1)
+oparg_T *oap;
+long count1;
+{
+ long ins_len, pre_textlen = 0;
+ char_u *firstline, *ins_text;
+ struct block_def bd;
+ int i;
+
+ /* edit() changes this - record it for OP_APPEND */
+ bd.is_MAX = (curwin->w_curswant == MAXCOL);
+
+ /* vis block is still marked. Get rid of it now. */
+ curwin->w_cursor.lnum = oap->start.lnum;
+ update_screen(INVERTED);
+
+ if (oap->block_mode) {
+ /* When 'virtualedit' is used, need to insert the extra spaces before
+ * doing block_prep(). When only "block" is used, virtual edit is
+ * already disabled, but still need it when calling
+ * coladvance_force(). */
+ if (curwin->w_cursor.coladd > 0) {
+ int old_ve_flags = ve_flags;
+
+ ve_flags = VE_ALL;
+ if (u_save_cursor() == FAIL)
+ return;
+ coladvance_force(oap->op_type == OP_APPEND
+ ? oap->end_vcol + 1 : getviscol());
+ if (oap->op_type == OP_APPEND)
+ --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);
+ firstline = ml_get(oap->start.lnum) + bd.textcol;
+ if (oap->op_type == OP_APPEND)
+ firstline += bd.textlen;
+ pre_textlen = (long)STRLEN(firstline);
+ }
+
+ if (oap->op_type == OP_APPEND) {
+ if (oap->block_mode
+ && curwin->w_cursor.coladd == 0
+ ) {
+ /* Move the cursor to the character right of the block. */
+ curwin->w_set_curswant = TRUE;
+ while (*ml_get_cursor() != NUL
+ && (curwin->w_cursor.col < bd.textcol + bd.textlen))
+ ++curwin->w_cursor.col;
+ if (bd.is_short && !bd.is_MAX) {
+ /* First line was too short, make it longer and adjust the
+ * values in "bd". */
+ if (u_save_cursor() == FAIL)
+ return;
+ for (i = 0; i < bd.endspaces; ++i)
+ ins_char(' ');
+ bd.textlen += bd.endspaces;
+ }
+ } else {
+ 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)
+ inc_cursor();
+ }
+ }
+
+ edit(NUL, FALSE, (linenr_T)count1);
+
+ /* If user has moved off this line, we don't know what to do, so do
+ * nothing.
+ * Also don't repeat the insert when Insert mode ended with CTRL-C. */
+ if (curwin->w_cursor.lnum != oap->start.lnum || got_int)
+ return;
+
+ if (oap->block_mode) {
+ 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.lnum && !bd.is_MAX) {
+ if (oap->op_type == OP_INSERT
+ && oap->start.col != curbuf->b_op_start.col) {
+ oap->start.col = curbuf->b_op_start.col;
+ pre_textlen -= getviscol2(oap->start.col, oap->start.coladd)
+ - oap->start_vcol;
+ oap->start_vcol = getviscol2(oap->start.col, oap->start.coladd);
+ } else if (oap->op_type == OP_APPEND
+ && oap->end.col >= curbuf->b_op_start.col) {
+ oap->start.col = curbuf->b_op_start.col;
+ /* reset pre_textlen to the value of OP_INSERT */
+ pre_textlen += bd.textlen;
+ pre_textlen -= getviscol2(oap->start.col, oap->start.coladd)
+ - oap->start_vcol;
+ oap->start_vcol = getviscol2(oap->start.col, oap->start.coladd);
+ oap->op_type = OP_INSERT;
+ }
+ }
+
+ /*
+ * Spaces and tabs in the indent may have changed to other spaces and
+ * 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);
+ if (!bd.is_MAX || bd2.textlen < bd.textlen) {
+ if (oap->op_type == OP_APPEND) {
+ pre_textlen += bd2.textlen - bd.textlen;
+ if (bd2.endspaces)
+ --bd2.textlen;
+ }
+ bd.textcol = bd2.textcol;
+ bd.textlen = bd2.textlen;
+ }
+
+ /*
+ * 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;
+ if (pre_textlen >= 0
+ && (ins_len = (long)STRLEN(firstline) - pre_textlen) > 0) {
+ ins_text = vim_strnsave(firstline, (int)ins_len);
+ if (ins_text != NULL) {
+ /* block handled here */
+ if (u_save(oap->start.lnum,
+ (linenr_T)(oap->end.lnum + 1)) == OK)
+ block_insert(oap, ins_text, (oap->op_type == OP_INSERT),
+ &bd);
+
+ curwin->w_cursor.col = oap->start.col;
+ check_cursor();
+ vim_free(ins_text);
+ }
+ }
+ }
+}
+
+/*
+ * op_change - handle a change operation
+ *
+ * return TRUE if edit() returns because of a CTRL-O command
+ */
+int op_change(oap)
+oparg_T *oap;
+{
+ colnr_T l;
+ int retval;
+ long offset;
+ linenr_T linenr;
+ long ins_len;
+ long pre_textlen = 0;
+ long pre_indent = 0;
+ char_u *firstline;
+ char_u *ins_text, *newp, *oldp;
+ struct block_def bd;
+
+ l = oap->start.col;
+ if (oap->motion_type == MLINE) {
+ l = 0;
+ if (!p_paste && curbuf->b_p_si
+ && !curbuf->b_p_cin
+ )
+ 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
+ * save for undo */
+ if (curbuf->b_ml.ml_flags & ML_EMPTY) {
+ if (u_save_cursor() == FAIL)
+ return FALSE;
+ } else if (op_delete(oap) == FAIL)
+ return FALSE;
+
+ 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 */
+ if (oap->block_mode) {
+ /* Add spaces before getting the current line length. */
+ if (virtual_op && (curwin->w_cursor.coladd > 0
+ || gchar_cursor() == NUL))
+ coladvance_force(getviscol());
+ firstline = ml_get(oap->start.lnum);
+ pre_textlen = (long)STRLEN(firstline);
+ pre_indent = (long)(skipwhite(firstline) - firstline);
+ bd.textcol = curwin->w_cursor.col;
+ }
+
+ if (oap->motion_type == MLINE)
+ fix_indent();
+
+ retval = edit(NUL, FALSE, (linenr_T)1);
+
+ /*
+ * In Visual block mode, handle copying the new text to all lines of the
+ * block.
+ * Don't repeat the insert when Insert mode ended with CTRL-C.
+ */
+ if (oap->block_mode && oap->start.lnum != oap->end.lnum && !got_int) {
+ /* Auto-indenting may have changed the indent. If the cursor was past
+ * 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);
+
+ pre_textlen += new_indent - pre_indent;
+ bd.textcol += new_indent - pre_indent;
+ }
+
+ ins_len = (long)STRLEN(firstline) - pre_textlen;
+ if (ins_len > 0) {
+ /* Subsequent calls to ml_get() flush the firstline data - take a
+ * copy of the inserted text. */
+ if ((ins_text = alloc_check((unsigned)(ins_len + 1))) != NULL) {
+ vim_strncpy(ins_text, firstline + bd.textcol, (size_t)ins_len);
+ for (linenr = oap->start.lnum + 1; linenr <= oap->end.lnum;
+ linenr++) {
+ block_prep(oap, &bd, linenr, TRUE);
+ if (!bd.is_short || virtual_op) {
+ pos_T vpos;
+
+ /* If the block starts in virtual space, count the
+ * initial coladd offset as part of "startspaces" */
+ if (bd.is_short) {
+ vpos.lnum = linenr;
+ (void)getvpos(&vpos, oap->start_vcol);
+ } else
+ vpos.coladd = 0;
+ oldp = ml_get(linenr);
+ newp = alloc_check((unsigned)(STRLEN(oldp)
+ + vpos.coladd
+ + ins_len + 1));
+ if (newp == NULL)
+ continue;
+ /* copy up to block start */
+ mch_memmove(newp, oldp, (size_t)bd.textcol);
+ offset = bd.textcol;
+ copy_spaces(newp + offset, (size_t)vpos.coladd);
+ offset += vpos.coladd;
+ mch_memmove(newp + offset, ins_text, (size_t)ins_len);
+ offset += ins_len;
+ oldp += bd.textcol;
+ STRMOVE(newp + offset, oldp);
+ ml_replace(linenr, newp, FALSE);
+ }
+ }
+ check_cursor();
+
+ changed_lines(oap->start.lnum + 1, 0, oap->end.lnum + 1, 0L);
+ }
+ vim_free(ins_text);
+ }
+ }
+
+ return retval;
+}
+
+/*
+ * set all the yank registers to empty (called from main())
+ */
+void init_yank() {
+ int i;
+
+ for (i = 0; i < NUM_REGISTERS; ++i)
+ y_regs[i].y_array = NULL;
+}
+
+#if defined(EXITFREE) || defined(PROTO)
+void clear_registers() {
+ int i;
+
+ for (i = 0; i < NUM_REGISTERS; ++i) {
+ y_current = &y_regs[i];
+ if (y_current->y_array != NULL)
+ free_yank_all();
+ }
+}
+
+#endif
+
+/*
+ * Free "n" lines from the current yank register.
+ * Called for normal freeing and in case of error.
+ */
+static void free_yank(n)
+long n;
+{
+ if (y_current->y_array != NULL) {
+ long i;
+
+ for (i = n; --i >= 0; ) {
+ vim_free(y_current->y_array[i]);
+ }
+ vim_free(y_current->y_array);
+ y_current->y_array = NULL;
+ }
+}
+
+static void free_yank_all() {
+ free_yank(y_current->y_size);
+}
+
+/*
+ * Yank the text between "oap->start" and "oap->end" into a yank register.
+ * If we are to append (uppercase register), we first yank into a new yank
+ * register and then concatenate the old and the new one (so we keep the old
+ * one in case of out-of-memory).
+ *
+ * Return FAIL for failure, OK otherwise.
+ */
+int op_yank(oap, deleting, mess)
+oparg_T *oap;
+int deleting;
+int mess;
+{
+ long y_idx; /* index in y_array[] */
+ struct yankreg *curr; /* copy of y_current */
+ struct yankreg newreg; /* new yank register when appending */
+ char_u **new_ptr;
+ linenr_T lnum; /* current line number */
+ long j;
+ int yanktype = oap->motion_type;
+ long yanklines = oap->line_count;
+ linenr_T yankendlnum = oap->end.lnum;
+ char_u *p;
+ char_u *pnew;
+ struct block_def bd;
+
+ /* check for read-only register */
+ if (oap->regname != 0 && !valid_yank_reg(oap->regname, TRUE)) {
+ beep_flush();
+ return FAIL;
+ }
+ if (oap->regname == '_') /* black hole: nothing to do */
+ return OK;
+
+
+ if (!deleting) /* op_delete() already set y_current */
+ get_yank_register(oap->regname, TRUE);
+
+ curr = y_current;
+ /* append to existing contents */
+ if (y_append && y_current->y_array != NULL)
+ y_current = &newreg;
+ else
+ free_yank_all(); /* free previously yanked lines */
+
+ /*
+ * If the cursor was in column 1 before and after the movement, and the
+ * operator is not inclusive, the yank is always linewise.
+ */
+ if ( oap->motion_type == MCHAR
+ && oap->start.col == 0
+ && !oap->inclusive
+ && (!oap->is_VIsual || *p_sel == 'o')
+ && !oap->block_mode
+ && oap->end.col == 0
+ && yanklines > 1) {
+ yanktype = MLINE;
+ --yankendlnum;
+ --yanklines;
+ }
+
+ y_current->y_size = yanklines;
+ y_current->y_type = yanktype; /* set the yank register type */
+ y_current->y_width = 0;
+ y_current->y_array = (char_u **)lalloc_clear((long_u)(sizeof(char_u *) *
+ yanklines), TRUE);
+
+ if (y_current->y_array == NULL) {
+ y_current = curr;
+ return FAIL;
+ }
+
+ y_idx = 0;
+ lnum = oap->start.lnum;
+
+ if (oap->block_mode) {
+ /* Visual block mode */
+ y_current->y_type = MBLOCK; /* set the yank register type */
+ y_current->y_width = oap->end_vcol - oap->start_vcol;
+
+ if (curwin->w_curswant == MAXCOL && y_current->y_width > 0)
+ y_current->y_width--;
+ }
+
+ for (; lnum <= yankendlnum; lnum++, y_idx++) {
+ switch (y_current->y_type) {
+ case MBLOCK:
+ block_prep(oap, &bd, lnum, FALSE);
+ if (yank_copy_line(&bd, y_idx) == FAIL)
+ goto fail;
+ break;
+
+ case MLINE:
+ if ((y_current->y_array[y_idx] =
+ vim_strsave(ml_get(lnum))) == NULL)
+ goto fail;
+ break;
+
+ case MCHAR:
+ {
+ colnr_T startcol = 0, endcol = MAXCOL;
+ int is_oneChar = FALSE;
+ colnr_T cs, ce;
+ p = ml_get(lnum);
+ bd.startspaces = 0;
+ bd.endspaces = 0;
+
+ if (lnum == oap->start.lnum) {
+ startcol = oap->start.col;
+ if (virtual_op) {
+ getvcol(curwin, &oap->start, &cs, NULL, &ce);
+ if (ce != cs && oap->start.coladd > 0) {
+ /* Part of a tab selected -- but don't
+ * double-count it. */
+ bd.startspaces = (ce - cs + 1)
+ - oap->start.coladd;
+ startcol++;
+ }
+ }
+ }
+
+ if (lnum == oap->end.lnum) {
+ endcol = oap->end.col;
+ 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
+ )) {
+ if (oap->start.lnum == oap->end.lnum
+ && oap->start.col == oap->end.col) {
+ /* Special case: inside a single char */
+ is_oneChar = TRUE;
+ bd.startspaces = oap->end.coladd
+ - oap->start.coladd + oap->inclusive;
+ endcol = startcol;
+ } else {
+ bd.endspaces = oap->end.coladd
+ + oap->inclusive;
+ endcol -= oap->inclusive;
+ }
+ }
+ }
+ }
+ if (endcol == MAXCOL)
+ endcol = (colnr_T)STRLEN(p);
+ if (startcol > endcol
+ || is_oneChar
+ )
+ bd.textlen = 0;
+ else {
+ bd.textlen = endcol - startcol + oap->inclusive;
+ }
+ bd.textstart = p + startcol;
+ if (yank_copy_line(&bd, y_idx) == FAIL)
+ goto fail;
+ break;
+ }
+ /* NOTREACHED */
+ }
+ }
+
+ if (curr != y_current) { /* append the new block to the old block */
+ new_ptr = (char_u **)lalloc(
+ (long_u)(sizeof(char_u *) *
+ (curr->y_size + y_current->y_size)),
+ TRUE);
+ if (new_ptr == NULL)
+ goto fail;
+ for (j = 0; j < curr->y_size; ++j)
+ new_ptr[j] = curr->y_array[j];
+ vim_free(curr->y_array);
+ curr->y_array = new_ptr;
+
+ if (yanktype == MLINE) /* MLINE overrides MCHAR and MBLOCK */
+ curr->y_type = MLINE;
+
+ /* Concatenate the last line of the old block with the first line of
+ * the new block, unless being Vi compatible. */
+ if (curr->y_type == MCHAR && vim_strchr(p_cpo, CPO_REGAPPEND) == NULL) {
+ pnew = lalloc((long_u)(STRLEN(curr->y_array[curr->y_size - 1])
+ + STRLEN(y_current->y_array[0]) + 1), TRUE);
+ if (pnew == NULL) {
+ y_idx = y_current->y_size - 1;
+ goto fail;
+ }
+ STRCPY(pnew, curr->y_array[--j]);
+ STRCAT(pnew, y_current->y_array[0]);
+ vim_free(curr->y_array[j]);
+ vim_free(y_current->y_array[0]);
+ curr->y_array[j++] = pnew;
+ y_idx = 1;
+ } else
+ y_idx = 0;
+ while (y_idx < y_current->y_size)
+ curr->y_array[j++] = y_current->y_array[y_idx++];
+ curr->y_size = j;
+ vim_free(y_current->y_array);
+ y_current = curr;
+ }
+ if (mess) { /* Display message about yank? */
+ if (yanktype == MCHAR
+ && !oap->block_mode
+ && yanklines == 1)
+ yanklines = 0;
+ /* Some versions of Vi use ">=" here, some don't... */
+ if (yanklines > p_report) {
+ /* redisplay now, so message is not deleted */
+ update_topline_redraw();
+ if (yanklines == 1) {
+ if (oap->block_mode)
+ MSG(_("block of 1 line yanked"));
+ else
+ MSG(_("1 line yanked"));
+ } else if (oap->block_mode)
+ smsg((char_u *)_("block of %ld lines yanked"), yanklines);
+ else
+ smsg((char_u *)_("%ld lines yanked"), yanklines);
+ }
+ }
+
+ /*
+ * Set "'[" and "']" marks.
+ */
+ curbuf->b_op_start = oap->start;
+ curbuf->b_op_end = oap->end;
+ if (yanktype == MLINE
+ && !oap->block_mode
+ ) {
+ curbuf->b_op_start.col = 0;
+ curbuf->b_op_end.col = MAXCOL;
+ }
+
+
+ return OK;
+
+fail: /* free the allocated lines */
+ free_yank(y_idx + 1);
+ y_current = curr;
+ return FAIL;
+}
+
+static int yank_copy_line(bd, y_idx)
+struct block_def *bd;
+long y_idx;
+{
+ char_u *pnew;
+
+ if ((pnew = alloc(bd->startspaces + bd->endspaces + bd->textlen + 1))
+ == NULL)
+ return FAIL;
+ y_current->y_array[y_idx] = pnew;
+ copy_spaces(pnew, (size_t)bd->startspaces);
+ pnew += bd->startspaces;
+ mch_memmove(pnew, bd->textstart, (size_t)bd->textlen);
+ pnew += bd->textlen;
+ copy_spaces(pnew, (size_t)bd->endspaces);
+ pnew += bd->endspaces;
+ *pnew = NUL;
+ return OK;
+}
+
+
+/*
+ * Put contents of register "regname" into the text.
+ * Caller must check "regname" to be valid!
+ * "flags": PUT_FIXINDENT make indent look nice
+ * PUT_CURSEND leave cursor after end of new text
+ * PUT_LINE force linewise put (":put")
+ */
+void do_put(regname, dir, count, flags)
+int regname;
+int dir; /* BACKWARD for 'P', FORWARD for 'p' */
+long count;
+int flags;
+{
+ char_u *ptr;
+ char_u *newp, *oldp;
+ int yanklen;
+ int totlen = 0; /* init for gcc */
+ linenr_T lnum;
+ colnr_T col;
+ long i; /* index in y_array[] */
+ int y_type;
+ long y_size;
+ int oldlen;
+ long y_width = 0;
+ colnr_T vcol;
+ int delcount;
+ int incr = 0;
+ long j;
+ struct block_def bd;
+ char_u **y_array = NULL;
+ long nr_lines = 0;
+ pos_T new_cursor;
+ int indent;
+ int orig_indent = 0; /* init for gcc */
+ int indent_diff = 0; /* init for gcc */
+ int first_indent = TRUE;
+ int lendiff = 0;
+ pos_T old_pos;
+ char_u *insert_string = NULL;
+ int allocated = FALSE;
+ long cnt;
+
+
+ if (flags & PUT_FIXINDENT)
+ orig_indent = get_indent();
+
+ curbuf->b_op_start = curwin->w_cursor; /* default for '[ mark */
+ curbuf->b_op_end = curwin->w_cursor; /* default for '] mark */
+
+ /*
+ * Using inserted text works differently, because the register includes
+ * 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');
+ return;
+ }
+
+ /*
+ * 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)
+ return;
+ }
+
+ /* Autocommands may be executed when saving lines for undo, which may make
+ * y_array invalid. Start undo now to avoid that. */
+ u_save(curwin->w_cursor.lnum, curwin->w_cursor.lnum + 1);
+
+ if (insert_string != NULL) {
+ y_type = MCHAR;
+ if (regname == '=') {
+ /* For the = register we need to split the string at NL
+ * characters.
+ * Loop twice: count the number of lines and save them. */
+ for (;; ) {
+ y_size = 0;
+ ptr = insert_string;
+ while (ptr != NULL) {
+ if (y_array != NULL)
+ y_array[y_size] = ptr;
+ ++y_size;
+ ptr = vim_strchr(ptr, '\n');
+ if (ptr != NULL) {
+ if (y_array != NULL)
+ *ptr = NUL;
+ ++ptr;
+ /* A trailing '\n' makes the register linewise. */
+ if (*ptr == NUL) {
+ y_type = MLINE;
+ break;
+ }
+ }
+ }
+ if (y_array != NULL)
+ break;
+ y_array = (char_u **)alloc((unsigned)
+ (y_size * sizeof(char_u *)));
+ if (y_array == NULL)
+ goto end;
+ }
+ } else {
+ y_size = 1; /* use fake one-line yank register */
+ y_array = &insert_string;
+ }
+ } else {
+ get_yank_register(regname, FALSE);
+
+ y_type = y_current->y_type;
+ y_width = y_current->y_width;
+ y_size = y_current->y_size;
+ y_array = y_current->y_array;
+ }
+
+ if (y_type == MLINE) {
+ if (flags & PUT_LINE_SPLIT) {
+ /* "p" or "P" in Visual mode: split the lines to put the text in
+ * between. */
+ if (u_save_cursor() == FAIL)
+ goto end;
+ ptr = vim_strsave(ml_get_cursor());
+ if (ptr == NULL)
+ goto end;
+ ml_append(curwin->w_cursor.lnum, ptr, (colnr_T)0, FALSE);
+ vim_free(ptr);
+
+ ptr = vim_strnsave(ml_get_curline(), curwin->w_cursor.col);
+ if (ptr == NULL)
+ goto end;
+ ml_replace(curwin->w_cursor.lnum, ptr, FALSE);
+ ++nr_lines;
+ dir = FORWARD;
+ }
+ if (flags & PUT_LINE_FORWARD) {
+ /* Must be "p" for a Visual block, put lines below the block. */
+ curwin->w_cursor = curbuf->b_visual.vi_end;
+ dir = FORWARD;
+ }
+ curbuf->b_op_start = curwin->w_cursor; /* default for '[ mark */
+ curbuf->b_op_end = curwin->w_cursor; /* default for '] mark */
+ }
+
+ if (flags & PUT_LINE) /* :put command or "p" in Visual line mode. */
+ y_type = MLINE;
+
+ if (y_size == 0 || y_array == NULL) {
+ EMSG2(_("E353: Nothing in register %s"),
+ regname == 0 ? (char_u *)"\"" : transchar(regname));
+ goto end;
+ }
+
+ if (y_type == MBLOCK) {
+ lnum = curwin->w_cursor.lnum + y_size + 1;
+ if (lnum > curbuf->b_ml.ml_line_count)
+ lnum = curbuf->b_ml.ml_line_count + 1;
+ if (u_save(curwin->w_cursor.lnum - 1, lnum) == FAIL)
+ goto end;
+ } else if (y_type == MLINE) {
+ lnum = curwin->w_cursor.lnum;
+ /* 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
+ (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)
+ goto end;
+ if (dir == FORWARD)
+ curwin->w_cursor.lnum = lnum - 1;
+ else
+ curwin->w_cursor.lnum = lnum;
+ curbuf->b_op_start = curwin->w_cursor; /* for mark_adjust() */
+ } else if (u_save_cursor() == FAIL)
+ goto end;
+
+ yanklen = (int)STRLEN(y_array[0]);
+
+ if (ve_flags == VE_ALL && y_type == MCHAR) {
+ if (gchar_cursor() == TAB) {
+ /* Don't need to insert spaces when "p" on the last position of a
+ * tab or "P" on the first position. */
+ if (dir == FORWARD
+ ? (int)curwin->w_cursor.coladd < curbuf->b_p_ts - 1
+ : curwin->w_cursor.coladd > 0)
+ coladvance_force(getviscol());
+ else
+ curwin->w_cursor.coladd = 0;
+ } else if (curwin->w_cursor.coladd > 0 || gchar_cursor() == NUL)
+ coladvance_force(getviscol() + (dir == FORWARD));
+ }
+
+ lnum = curwin->w_cursor.lnum;
+ col = curwin->w_cursor.col;
+
+ /*
+ * Block mode
+ */
+ if (y_type == MBLOCK) {
+ char c = gchar_cursor();
+ colnr_T endcol2 = 0;
+
+ if (dir == FORWARD && c != NUL) {
+ if (ve_flags == VE_ALL)
+ getvcol(curwin, &curwin->w_cursor, &col, NULL, &endcol2);
+ 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)(ml_get_cursor());
+ else if (c != TAB || ve_flags != VE_ALL)
+ ++curwin->w_cursor.col;
+ ++col;
+ } else
+ getvcol(curwin, &curwin->w_cursor, &col, NULL, &endcol2);
+
+ col += curwin->w_cursor.coladd;
+ if (ve_flags == VE_ALL
+ && (curwin->w_cursor.coladd > 0
+ || endcol2 == curwin->w_cursor.col)) {
+ if (dir == FORWARD && c == NUL)
+ ++col;
+ if (dir != FORWARD && c != NUL)
+ ++curwin->w_cursor.col;
+ if (c == TAB) {
+ if (dir == BACKWARD && curwin->w_cursor.col)
+ curwin->w_cursor.col--;
+ if (dir == FORWARD && col - 1 == endcol2)
+ curwin->w_cursor.col++;
+ }
+ }
+ curwin->w_cursor.coladd = 0;
+ bd.textcol = 0;
+ for (i = 0; i < y_size; ++i) {
+ int spaces;
+ char shortline;
+
+ bd.startspaces = 0;
+ bd.endspaces = 0;
+ vcol = 0;
+ delcount = 0;
+
+ /* add a new line */
+ if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count) {
+ if (ml_append(curbuf->b_ml.ml_line_count, (char_u *)"",
+ (colnr_T)1, FALSE) == FAIL)
+ break;
+ ++nr_lines;
+ }
+ /* get the old line and advance to the position to insert at */
+ oldp = ml_get_curline();
+ oldlen = (int)STRLEN(oldp);
+ for (ptr = oldp; vcol < col && *ptr; ) {
+ /* Count a tab for what it's worth (if list mode not on) */
+ incr = lbr_chartabsize_adv(&ptr, (colnr_T)vcol);
+ vcol += incr;
+ }
+ bd.textcol = (colnr_T)(ptr - oldp);
+
+ shortline = (vcol < col) || (vcol == col && !*ptr);
+
+ if (vcol < col) /* line too short, padd with spaces */
+ bd.startspaces = col - vcol;
+ else if (vcol > col) {
+ bd.endspaces = vcol - col;
+ bd.startspaces = incr - bd.endspaces;
+ --bd.textcol;
+ delcount = 1;
+ if (has_mbyte)
+ bd.textcol -= (*mb_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
+ * block, causing misalignment. */
+ delcount = 0;
+ bd.endspaces = 0;
+ }
+ }
+
+ yanklen = (int)STRLEN(y_array[i]);
+
+ /* calculate number of spaces required to fill right side of block*/
+ spaces = y_width + 1;
+ for (j = 0; j < yanklen; j++)
+ spaces -= lbr_chartabsize(&y_array[i][j], 0);
+ if (spaces < 0)
+ spaces = 0;
+
+ /* insert the new text */
+ totlen = count * (yanklen + spaces) + bd.startspaces + bd.endspaces;
+ newp = alloc_check((unsigned)totlen + oldlen + 1);
+ if (newp == NULL)
+ break;
+ /* copy part up to cursor to new line */
+ ptr = newp;
+ mch_memmove(ptr, oldp, (size_t)bd.textcol);
+ ptr += bd.textcol;
+ /* may insert some spaces before the new text */
+ copy_spaces(ptr, (size_t)bd.startspaces);
+ ptr += bd.startspaces;
+ /* insert the new text */
+ for (j = 0; j < count; ++j) {
+ mch_memmove(ptr, y_array[i], (size_t)yanklen);
+ ptr += yanklen;
+
+ /* insert block's trailing spaces only if there's text behind */
+ if ((j < count - 1 || !shortline) && spaces) {
+ copy_spaces(ptr, (size_t)spaces);
+ ptr += spaces;
+ }
+ }
+ /* may insert some spaces after the new text */
+ copy_spaces(ptr, (size_t)bd.endspaces);
+ ptr += bd.endspaces;
+ /* move the text after the cursor to the end of the line. */
+ mch_memmove(ptr, oldp + bd.textcol + delcount,
+ (size_t)(oldlen - bd.textcol - delcount + 1));
+ ml_replace(curwin->w_cursor.lnum, newp, FALSE);
+
+ ++curwin->w_cursor.lnum;
+ if (i == 0)
+ curwin->w_cursor.col += bd.startspaces;
+ }
+
+ changed_lines(lnum, 0, curwin->w_cursor.lnum, nr_lines);
+
+ /* Set '[ mark. */
+ curbuf->b_op_start = curwin->w_cursor;
+ curbuf->b_op_start.lnum = lnum;
+
+ /* adjust '] mark */
+ curbuf->b_op_end.lnum = curwin->w_cursor.lnum - 1;
+ curbuf->b_op_end.col = bd.textcol + totlen - 1;
+ curbuf->b_op_end.coladd = 0;
+ if (flags & PUT_CURSEND) {
+ colnr_T len;
+
+ curwin->w_cursor = curbuf->b_op_end;
+ curwin->w_cursor.col++;
+
+ /* in Insert mode we might be after the NUL, correct for that */
+ len = (colnr_T)STRLEN(ml_get_curline());
+ if (curwin->w_cursor.col > len)
+ curwin->w_cursor.col = len;
+ } else
+ curwin->w_cursor.lnum = lnum;
+ } else {
+ /*
+ * Character or Line mode
+ */
+ if (y_type == MCHAR) {
+ /* if type is MCHAR, FORWARD is the same as BACKWARD on the next
+ * char */
+ if (dir == FORWARD && gchar_cursor() != NUL) {
+ if (has_mbyte) {
+ int bytelen = (*mb_ptr2len)(ml_get_cursor());
+
+ /* 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;
+ }
+ }
+ }
+ curbuf->b_op_start = curwin->w_cursor;
+ }
+ /*
+ * Line mode: BACKWARD is the same as FORWARD on the previous line
+ */
+ else if (dir == BACKWARD)
+ --lnum;
+ new_cursor = curwin->w_cursor;
+
+ /*
+ * simple case: insert into current line
+ */
+ if (y_type == MCHAR && y_size == 1) {
+ do {
+ totlen = count * yanklen;
+ if (totlen > 0) {
+ oldp = ml_get(lnum);
+ newp = alloc_check((unsigned)(STRLEN(oldp) + totlen + 1));
+ if (newp == NULL)
+ goto end; /* alloc() gave an error message */
+ mch_memmove(newp, oldp, (size_t)col);
+ ptr = newp + col;
+ for (i = 0; i < count; ++i) {
+ mch_memmove(ptr, y_array[0], (size_t)yanklen);
+ ptr += yanklen;
+ }
+ STRMOVE(ptr, oldp + col);
+ ml_replace(lnum, newp, FALSE);
+ /* Place cursor on last putted char. */
+ if (lnum == curwin->w_cursor.lnum) {
+ /* make sure curwin->w_virtcol is updated */
+ changed_cline_bef_curs();
+ curwin->w_cursor.col += (colnr_T)(totlen - 1);
+ }
+ }
+ if (VIsual_active)
+ lnum++;
+ } while (
+ VIsual_active && lnum <= curbuf->b_visual.vi_end.lnum
+ );
+
+ curbuf->b_op_end = curwin->w_cursor;
+ /* For "CTRL-O p" in Insert mode, put cursor after last char */
+ if (totlen && (restart_edit != 0 || (flags & PUT_CURSEND)))
+ ++curwin->w_cursor.col;
+ changed_bytes(lnum, col);
+ } else {
+ /*
+ * Insert at least one line. When y_type is MCHAR, break the first
+ * line in two.
+ */
+ for (cnt = 1; cnt <= count; ++cnt) {
+ i = 0;
+ if (y_type == MCHAR) {
+ /*
+ * Split the current line in two at the insert position.
+ * First insert y_array[size - 1] in front of second line.
+ * Then append y_array[0] to first line.
+ */
+ lnum = new_cursor.lnum;
+ ptr = ml_get(lnum) + col;
+ totlen = (int)STRLEN(y_array[y_size - 1]);
+ newp = alloc_check((unsigned)(STRLEN(ptr) + totlen + 1));
+ if (newp == NULL)
+ goto error;
+ STRCPY(newp, y_array[y_size - 1]);
+ STRCAT(newp, ptr);
+ /* insert second line */
+ ml_append(lnum, newp, (colnr_T)0, FALSE);
+ vim_free(newp);
+
+ oldp = ml_get(lnum);
+ newp = alloc_check((unsigned)(col + yanklen + 1));
+ if (newp == NULL)
+ goto error;
+ /* copy first part of line */
+ mch_memmove(newp, oldp, (size_t)col);
+ /* append to first line */
+ mch_memmove(newp + col, y_array[0], (size_t)(yanklen + 1));
+ ml_replace(lnum, newp, FALSE);
+
+ curwin->w_cursor.lnum = lnum;
+ i = 1;
+ }
+
+ for (; i < y_size; ++i) {
+ if ((y_type != MCHAR || i < y_size - 1)
+ && ml_append(lnum, y_array[i], (colnr_T)0, FALSE)
+ == FAIL)
+ goto error;
+ lnum++;
+ ++nr_lines;
+ if (flags & PUT_FIXINDENT) {
+ old_pos = curwin->w_cursor;
+ curwin->w_cursor.lnum = lnum;
+ ptr = ml_get(lnum);
+ if (cnt == count && i == y_size - 1)
+ lendiff = (int)STRLEN(ptr);
+ if (*ptr == '#' && preprocs_left())
+ indent = 0; /* Leave # lines at start */
+ else if (*ptr == NUL)
+ indent = 0; /* Ignore empty lines */
+ else if (first_indent) {
+ indent_diff = orig_indent - get_indent();
+ indent = orig_indent;
+ first_indent = FALSE;
+ } else if ((indent = get_indent() + indent_diff) < 0)
+ indent = 0;
+ (void)set_indent(indent, 0);
+ curwin->w_cursor = old_pos;
+ /* remember how many chars were removed */
+ if (cnt == count && i == y_size - 1)
+ lendiff -= (int)STRLEN(ml_get(lnum));
+ }
+ }
+ }
+
+error:
+ /* Adjust marks. */
+ if (y_type == MLINE) {
+ curbuf->b_op_start.col = 0;
+ if (dir == FORWARD)
+ curbuf->b_op_start.lnum++;
+ }
+ mark_adjust(curbuf->b_op_start.lnum + (y_type == MCHAR),
+ (linenr_T)MAXLNUM, nr_lines, 0L);
+
+ /* note changed text for displaying and folding */
+ if (y_type == MCHAR)
+ changed_lines(curwin->w_cursor.lnum, col,
+ curwin->w_cursor.lnum + 1, nr_lines);
+ else
+ changed_lines(curbuf->b_op_start.lnum, 0,
+ curbuf->b_op_start.lnum, nr_lines);
+
+ /* put '] mark at last inserted character */
+ curbuf->b_op_end.lnum = lnum;
+ /* correct length for change in indent */
+ col = (colnr_T)STRLEN(y_array[y_size - 1]) - lendiff;
+ if (col > 1)
+ curbuf->b_op_end.col = col - 1;
+ else
+ curbuf->b_op_end.col = 0;
+
+ if (flags & PUT_CURSLINE) {
+ /* ":put": put cursor on last inserted line */
+ curwin->w_cursor.lnum = lnum;
+ beginline(BL_WHITE | BL_FIX);
+ } else if (flags & PUT_CURSEND) {
+ /* put cursor after inserted text */
+ if (y_type == MLINE) {
+ if (lnum >= curbuf->b_ml.ml_line_count)
+ curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
+ else
+ curwin->w_cursor.lnum = lnum + 1;
+ curwin->w_cursor.col = 0;
+ } else {
+ curwin->w_cursor.lnum = lnum;
+ curwin->w_cursor.col = col;
+ }
+ } else if (y_type == MLINE) {
+ /* put cursor on first non-blank in first inserted line */
+ curwin->w_cursor.col = 0;
+ if (dir == FORWARD)
+ ++curwin->w_cursor.lnum;
+ beginline(BL_WHITE | BL_FIX);
+ } else /* put cursor on first inserted character */
+ curwin->w_cursor = new_cursor;
+ }
+ }
+
+ msgmore(nr_lines);
+ curwin->w_set_curswant = TRUE;
+
+end:
+ if (allocated)
+ vim_free(insert_string);
+ if (regname == '=')
+ vim_free(y_array);
+
+ VIsual_active = FALSE;
+
+ /* If the cursor is past the end of the line put it at the end. */
+ adjust_cursor_eol();
+}
+
+/*
+ * When the cursor is on the NUL past the end of the line and it should not be
+ * there move it left.
+ */
+void adjust_cursor_eol() {
+ if (curwin->w_cursor.col > 0
+ && gchar_cursor() == NUL
+ && (ve_flags & VE_ONEMORE) == 0
+ && !(restart_edit || (State & INSERT))) {
+ /* Put the cursor on the last character in the line. */
+ dec_cursor();
+
+ if (ve_flags == VE_ALL) {
+ colnr_T scol, ecol;
+
+ /* Coladd is set to the width of the last character. */
+ getvcol(curwin, &curwin->w_cursor, &scol, NULL, &ecol);
+ curwin->w_cursor.coladd = ecol - scol + 1;
+ }
+ }
+}
+
+/*
+ * Return TRUE if lines starting with '#' should be left aligned.
+ */
+int preprocs_left() {
+ return
+ (curbuf->b_p_si && !curbuf->b_p_cin) ||
+ (curbuf->b_p_cin && in_cinkeys('#', ' ', TRUE)
+ && curbuf->b_ind_hash_comment == 0)
+ ;
+}
+
+/* Return the character name of the register with the given number */
+int get_register_name(num)
+int num;
+{
+ if (num == -1)
+ return '"';
+ else if (num < 10)
+ return num + '0';
+ else if (num == DELETION_REGISTER)
+ return '-';
+ else {
+ return num + 'a' - 10;
+ }
+}
+
+/*
+ * ":dis" and ":registers": Display the contents of the yank registers.
+ */
+void ex_display(eap)
+exarg_T *eap;
+{
+ int i, n;
+ long j;
+ char_u *p;
+ struct yankreg *yb;
+ int name;
+ int attr;
+ char_u *arg = eap->arg;
+ int clen;
+
+ if (arg != NULL && *arg == NUL)
+ arg = NULL;
+ attr = hl_attr(HLF_8);
+
+ /* Highlight title */
+ MSG_PUTS_TITLE(_("\n--- Registers ---"));
+ for (i = -1; i < NUM_REGISTERS && !got_int; ++i) {
+ name = get_register_name(i);
+ if (arg != NULL && vim_strchr(arg, name) == NULL
+#ifdef ONE_CLIPBOARD
+ /* Star register and plus register contain the same thing. */
+ && (name != '*' || vim_strchr(arg, '+') == NULL)
+#endif
+ )
+ continue; /* did not ask for this register */
+
+
+ if (i == -1) {
+ if (y_previous != NULL)
+ yb = y_previous;
+ else
+ yb = &(y_regs[0]);
+ } else
+ yb = &(y_regs[i]);
+
+ 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');
+ msg_putchar('"');
+ msg_putchar(name);
+ MSG_PUTS(" ");
+
+ n = (int)Columns - 6;
+ for (j = 0; j < yb->y_size && n > 1; ++j) {
+ if (j) {
+ MSG_PUTS_ATTR("^J", attr);
+ n -= 2;
+ }
+ for (p = yb->y_array[j]; *p && (n -= ptr2cells(p)) >= 0; ++p) {
+ clen = (*mb_ptr2len)(p);
+ msg_outtrans_len(p, clen);
+ p += clen - 1;
+ }
+ }
+ if (n > 1 && yb->y_type == MLINE)
+ MSG_PUTS_ATTR("^J", attr);
+ out_flush(); /* show one line at a time */
+ }
+ ui_breakcheck();
+ }
+
+ /*
+ * display last inserted text
+ */
+ if ((p = get_last_insert()) != NULL
+ && (arg == NULL || vim_strchr(arg, '.') != NULL) && !got_int) {
+ MSG_PUTS("\n\". ");
+ dis_msg(p, TRUE);
+ }
+
+ /*
+ * display last command line
+ */
+ if (last_cmdline != NULL && (arg == NULL || vim_strchr(arg, ':') != NULL)
+ && !got_int) {
+ MSG_PUTS("\n\": ");
+ dis_msg(last_cmdline, FALSE);
+ }
+
+ /*
+ * display current file name
+ */
+ if (curbuf->b_fname != NULL
+ && (arg == NULL || vim_strchr(arg, '%') != NULL) && !got_int) {
+ MSG_PUTS("\n\"% ");
+ dis_msg(curbuf->b_fname, FALSE);
+ }
+
+ /*
+ * display alternate file name
+ */
+ if ((arg == NULL || vim_strchr(arg, '%') != NULL) && !got_int) {
+ char_u *fname;
+ linenr_T dummy;
+
+ if (buflist_name_nr(0, &fname, &dummy) != FAIL) {
+ MSG_PUTS("\n\"# ");
+ dis_msg(fname, FALSE);
+ }
+ }
+
+ /*
+ * display last search pattern
+ */
+ if (last_search_pat() != NULL
+ && (arg == NULL || vim_strchr(arg, '/') != NULL) && !got_int) {
+ MSG_PUTS("\n\"/ ");
+ dis_msg(last_search_pat(), FALSE);
+ }
+
+ /*
+ * display last used expression
+ */
+ if (expr_line != NULL && (arg == NULL || vim_strchr(arg, '=') != NULL)
+ && !got_int) {
+ MSG_PUTS("\n\"= ");
+ dis_msg(expr_line, FALSE);
+ }
+}
+
+/*
+ * display a string for do_dis()
+ * truncate at end of screen line
+ */
+static void dis_msg(p, skip_esc)
+char_u *p;
+int skip_esc; /* if TRUE, ignore trailing ESC */
+{
+ int n;
+ int l;
+
+ n = (int)Columns - 6;
+ while (*p != NUL
+ && !(*p == ESC && skip_esc && *(p + 1) == NUL)
+ && (n -= ptr2cells(p)) >= 0) {
+ if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1) {
+ msg_outtrans_len(p, l);
+ p += l;
+ } else
+ msg_outtrans_len(p++, 1);
+ }
+ ui_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(line, process, include_space, is_comment)
+char_u *line;
+int process;
+int include_space;
+int *is_comment;
+{
+ char_u *comment_flags = NULL;
+ int lead_len;
+ int leader_offset = get_last_leader_offset(line, &comment_flags);
+
+ *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 == ':')
+ break;
+ ++comment_flags;
+ }
+ if (*comment_flags != COM_END)
+ *is_comment = TRUE;
+ }
+
+ if (process == FALSE)
+ return line;
+
+ lead_len = get_leader_len(line, &comment_flags, FALSE, include_space);
+
+ if (lead_len == 0)
+ return line;
+
+ /* Find:
+ * - COM_END,
+ * - colon,
+ * whichever comes first.
+ */
+ while (*comment_flags) {
+ if (*comment_flags == COM_END
+ || *comment_flags == ':') {
+ break;
+ }
+ ++comment_flags;
+ }
+
+ /* If we found a colon, it means that we are not processing a line
+ * 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)
+ line += lead_len;
+
+ return line;
+}
+
+/*
+ * Join 'count' lines (minimal 2) at cursor position.
+ * When "save_undo" is TRUE save lines for undo first.
+ * Set "use_formatoptions" to FALSE when e.g. processing
+ * backspace and comment leaders should not be removed.
+ *
+ * return FAIL for failure, OK otherwise
+ */
+int do_join(count, insert_space, save_undo, use_formatoptions)
+long count;
+int insert_space;
+int save_undo;
+int use_formatoptions UNUSED;
+{
+ char_u *curr = NULL;
+ char_u *curr_start = NULL;
+ char_u *cend;
+ char_u *newp;
+ char_u *spaces; /* number of spaces inserted before a line */
+ int endcurr1 = NUL;
+ int endcurr2 = NUL;
+ int currsize = 0; /* size of the current line */
+ int sumsize = 0; /* size of the long new line */
+ linenr_T t;
+ colnr_T col = 0;
+ int ret = OK;
+ int *comments = NULL;
+ int remove_comments = (use_formatoptions == TRUE)
+ && has_format_option(FO_REMOVE_COMS);
+ int prev_was_comment;
+
+
+ if (save_undo && u_save((linenr_T)(curwin->w_cursor.lnum - 1),
+ (linenr_T)(curwin->w_cursor.lnum + count)) == FAIL)
+ return FAIL;
+
+ /* Allocate an array to store the number of spaces inserted before each
+ * line. We will use it to pre-compute the length of the new line and the
+ * proper placement of each original line in the new one. */
+ spaces = lalloc_clear((long_u)count, TRUE);
+ if (spaces == NULL)
+ return FAIL;
+ if (remove_comments) {
+ comments = (int *)lalloc_clear((long_u)count * sizeof(int), TRUE);
+ if (comments == NULL) {
+ vim_free(spaces);
+ return FAIL;
+ }
+ }
+
+ /*
+ * Don't move anything, just compute the final line length
+ * and setup the array of space strings lengths
+ */
+ for (t = 0; t < count; ++t) {
+ curr = curr_start = ml_get((linenr_T)(curwin->w_cursor.lnum + t));
+ if (remove_comments) {
+ /* 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);
+ comments[t] = (int)(new_curr - curr);
+ curr = new_curr;
+ } 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))
+ && (!has_format_option(FO_MBYTE_JOIN2)
+ || mb_ptr2char(curr) < 0x100 || endcurr1 < 0x100)
+ ) {
+ /* don't add a space if the line is ending in a space */
+ if (endcurr1 == ' ')
+ endcurr1 = endcurr2;
+ else
+ ++spaces[t];
+ /* extra space when 'joinspaces' set and line ends in '.' */
+ if ( p_js
+ && (endcurr1 == '.'
+ || (vim_strchr(p_cpo, CPO_JOINSP) == NULL
+ && (endcurr1 == '?' || endcurr1 == '!'))))
+ ++spaces[t];
+ }
+ }
+ currsize = (int)STRLEN(curr);
+ 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);
+ }
+ }
+ line_breakcheck();
+ if (got_int) {
+ ret = FAIL;
+ goto theend;
+ }
+ }
+
+ /* store the column position before last line */
+ col = sumsize - currsize - spaces[count - 1];
+
+ /* allocate the space for the new line */
+ newp = alloc_check((unsigned)(sumsize + 1));
+ cend = newp + sumsize;
+ *cend = 0;
+
+ /*
+ * Move affected lines to the new long one.
+ *
+ * Move marks from each deleted line to the joined line, adjusting the
+ * column. This is not Vi compatible, but Vi deletes the marks, thus that
+ * should not really be a problem.
+ */
+ for (t = count - 1;; --t) {
+ cend -= currsize;
+ mch_memmove(cend, curr, (size_t)currsize);
+ if (spaces[t] > 0) {
+ cend -= spaces[t];
+ copy_spaces(cend, (size_t)(spaces[t]));
+ }
+ mark_col_adjust(curwin->w_cursor.lnum + t, (colnr_T)0, (linenr_T)-t,
+ (long)(cend - newp + spaces[t] - (curr - curr_start)));
+ if (t == 0)
+ break;
+ curr = curr_start = ml_get((linenr_T)(curwin->w_cursor.lnum + t - 1));
+ if (remove_comments)
+ curr += comments[t - 1];
+ if (insert_space && t > 1)
+ curr = skipwhite(curr);
+ currsize = (int)STRLEN(curr);
+ }
+ ml_replace(curwin->w_cursor.lnum, newp, FALSE);
+
+ /* 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);
+
+ /*
+ * Delete following lines. To do this we move the cursor there
+ * briefly, and then move it back. After del_lines() the cursor may
+ * have moved up (last line deleted), so the current lnum is kept in t.
+ */
+ t = curwin->w_cursor.lnum;
+ ++curwin->w_cursor.lnum;
+ del_lines(count - 1, FALSE);
+ curwin->w_cursor.lnum = t;
+
+ /*
+ * Set the cursor column:
+ * Vi compatible: use the column of the first join
+ * vim: use the column of the last join
+ */
+ curwin->w_cursor.col =
+ (vim_strchr(p_cpo, CPO_JOINCOL) != NULL ? currsize : col);
+ check_cursor_col();
+
+ curwin->w_cursor.coladd = 0;
+ curwin->w_set_curswant = TRUE;
+
+theend:
+ vim_free(spaces);
+ if (remove_comments)
+ vim_free(comments);
+ return ret;
+}
+
+/*
+ * Return TRUE if the two comment leaders given are the same. "lnum" is
+ * the first line. White-space is ignored. Note that the whole of
+ * 'leader1' must match 'leader2_len' characters from 'leader2' -- webb
+ */
+static int same_leader(lnum, leader1_len, leader1_flags, leader2_len,
+ leader2_flags)
+linenr_T lnum;
+int leader1_len;
+char_u *leader1_flags;
+int leader2_len;
+char_u *leader2_flags;
+{
+ int idx1 = 0, idx2 = 0;
+ char_u *p;
+ char_u *line1;
+ char_u *line2;
+
+ if (leader1_len == 0)
+ return leader2_len == 0;
+
+ /*
+ * If first leader has 'f' flag, the lines can be joined only if the
+ * second line does not have a leader.
+ * If first leader has 'e' flag, the lines can never be joined.
+ * If fist leader has 's' flag, the lines can only be joined if there is
+ * some text after it and the second line has the 'm' flag.
+ */
+ if (leader1_flags != NULL) {
+ for (p = leader1_flags; *p && *p != ':'; ++p) {
+ if (*p == COM_FIRST)
+ return leader2_len == 0;
+ if (*p == COM_END)
+ return FALSE;
+ if (*p == COM_START) {
+ if (*(ml_get(lnum) + leader1_len) == NUL)
+ return FALSE;
+ if (leader2_flags == NULL || leader2_len == 0)
+ return FALSE;
+ for (p = leader2_flags; *p && *p != ':'; ++p)
+ if (*p == COM_MIDDLE)
+ return TRUE;
+ return FALSE;
+ }
+ }
+ }
+
+ /*
+ * Get current line and next line, compare the leaders.
+ * The first line has to be saved, only one line can be locked at a time.
+ */
+ line1 = vim_strsave(ml_get(lnum));
+ if (line1 != NULL) {
+ for (idx1 = 0; vim_iswhite(line1[idx1]); ++idx1)
+ ;
+ line2 = ml_get(lnum + 1);
+ for (idx2 = 0; idx2 < leader2_len; ++idx2) {
+ if (!vim_iswhite(line2[idx2])) {
+ if (line1[idx1++] != line2[idx2])
+ break;
+ } else
+ while (vim_iswhite(line1[idx1]))
+ ++idx1;
+ }
+ vim_free(line1);
+ }
+ return idx2 == leader2_len && idx1 == leader1_len;
+}
+
+/*
+ * Implementation of the format operator 'gq'.
+ */
+void op_format(oap, keep_cursor)
+oparg_T *oap;
+int keep_cursor; /* keep cursor on same text char */
+{
+ long old_line_count = curbuf->b_ml.ml_line_count;
+
+ /* Place the cursor where the "gq" or "gw" command was given, so that "u"
+ * can put it back there. */
+ curwin->w_cursor = oap->cursor_start;
+
+ if (u_save((linenr_T)(oap->start.lnum - 1),
+ (linenr_T)(oap->end.lnum + 1)) == FAIL)
+ return;
+ curwin->w_cursor = oap->start;
+
+ if (oap->is_VIsual)
+ /* When there is no change: need to remove the Visual selection */
+ redraw_curbuf_later(INVERTED);
+
+ /* Set '[ mark at the start of the formatted area */
+ curbuf->b_op_start = oap->start;
+
+ /* For "gw" remember the cursor position and put it back below (adjusted
+ * for joined and split lines). */
+ if (keep_cursor)
+ saved_cursor = oap->cursor_start;
+
+ format_lines(oap->line_count, keep_cursor);
+
+ /*
+ * Leave the cursor at the first non-blank of the last formatted line.
+ * If the cursor was moved one line back (e.g. with "Q}") go to the next
+ * line, so "." will do the next lines.
+ */
+ if (oap->end_adjusted && curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count)
+ ++curwin->w_cursor.lnum;
+ beginline(BL_WHITE | BL_FIX);
+ old_line_count = curbuf->b_ml.ml_line_count - old_line_count;
+ msgmore(old_line_count);
+
+ /* put '] mark on the end of the formatted area */
+ curbuf->b_op_end = curwin->w_cursor;
+
+ if (keep_cursor) {
+ curwin->w_cursor = saved_cursor;
+ saved_cursor.lnum = 0;
+ }
+
+ if (oap->is_VIsual) {
+ win_T *wp;
+
+ FOR_ALL_WINDOWS(wp)
+ {
+ if (wp->w_old_cursor_lnum != 0) {
+ /* When lines have been inserted or deleted, adjust the end of
+ * the Visual area to be redrawn. */
+ if (wp->w_old_cursor_lnum > wp->w_old_visual_lnum)
+ wp->w_old_cursor_lnum += old_line_count;
+ else
+ wp->w_old_visual_lnum += old_line_count;
+ }
+ }
+ }
+}
+
+/*
+ * Implementation of the format operator 'gq' for when using 'formatexpr'.
+ */
+void op_formatexpr(oap)
+oparg_T *oap;
+{
+ if (oap->is_VIsual)
+ /* When there is no change: need to remove the Visual selection */
+ redraw_curbuf_later(INVERTED);
+
+ if (fex_format(oap->start.lnum, oap->line_count, NUL) != 0)
+ /* As documented: when 'formatexpr' returns non-zero fall back to
+ * internal formatting. */
+ op_format(oap, FALSE);
+}
+
+int fex_format(lnum, count, c)
+linenr_T lnum;
+long count;
+int c; /* character to be inserted */
+{
+ int use_sandbox = was_set_insecurely((char_u *)"formatexpr",
+ OPT_LOCAL);
+ int r;
+
+ /*
+ * Set v:lnum to the first line number and v:count to the number of lines.
+ * Set v:char to the character to be inserted (can be NUL).
+ */
+ set_vim_var_nr(VV_LNUM, lnum);
+ set_vim_var_nr(VV_COUNT, 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;
+
+ set_vim_var_string(VV_CHAR, NULL, -1);
+
+ return r;
+}
+
+/*
+ * Format "line_count" lines, starting at the cursor position.
+ * When "line_count" is negative, format until the end of the paragraph.
+ * Lines after the cursor line are saved for undo, caller must have saved the
+ * first line.
+ */
+void format_lines(line_count, avoid_fex)
+linenr_T line_count;
+int avoid_fex; /* don't use 'formatexpr' */
+{
+ int max_len;
+ int is_not_par; /* current line not part of parag. */
+ int next_is_not_par; /* next line not part of paragraph */
+ int is_end_par; /* at end of paragraph */
+ int prev_is_end_par = FALSE; /* prev. line not part of parag. */
+ int next_is_start_par = FALSE;
+ int leader_len = 0; /* leader len of current line */
+ int next_leader_len; /* leader len of next line */
+ char_u *leader_flags = NULL; /* flags for leader of current line */
+ char_u *next_leader_flags; /* flags for leader of next line */
+ int do_comments; /* format comments */
+ int do_comments_list = 0; /* format comments with 'n' or '2' */
+ int advance = TRUE;
+ int second_indent = -1; /* indent for second line (comment
+ * aware) */
+ int do_second_indent;
+ int do_number_indent;
+ int do_trail_white;
+ int first_par_line = TRUE;
+ int smd_save;
+ long count;
+ int need_set_indent = TRUE; /* set indent of next paragraph */
+ int force_format = FALSE;
+ int old_State = State;
+
+ /* length of a line to force formatting: 3 * 'tw' */
+ max_len = comp_textwidth(TRUE) * 3;
+
+ /* check for 'q', '2' and '1' in 'formatoptions' */
+ do_comments = has_format_option(FO_Q_COMS);
+ do_second_indent = has_format_option(FO_Q_SECOND);
+ do_number_indent = has_format_option(FO_Q_NUMBER);
+ do_trail_white = has_format_option(FO_WHITE_PAR);
+
+ /*
+ * Get info about the previous and current line.
+ */
+ if (curwin->w_cursor.lnum > 1)
+ is_not_par = fmt_check_par(curwin->w_cursor.lnum - 1
+ , &leader_len, &leader_flags, do_comments
+ );
+ else
+ is_not_par = TRUE;
+ next_is_not_par = fmt_check_par(curwin->w_cursor.lnum
+ , &next_leader_len, &next_leader_flags, do_comments
+ );
+ is_end_par = (is_not_par || next_is_not_par);
+ if (!is_end_par && do_trail_white)
+ is_end_par = !ends_in_white(curwin->w_cursor.lnum - 1);
+
+ curwin->w_cursor.lnum--;
+ for (count = line_count; count != 0 && !got_int; --count) {
+ /*
+ * Advance to next paragraph.
+ */
+ if (advance) {
+ curwin->w_cursor.lnum++;
+ prev_is_end_par = is_end_par;
+ is_not_par = next_is_not_par;
+ leader_len = next_leader_len;
+ leader_flags = next_leader_flags;
+ }
+
+ /*
+ * The last line to be formatted.
+ */
+ if (count == 1 || curwin->w_cursor.lnum == curbuf->b_ml.ml_line_count) {
+ next_is_not_par = TRUE;
+ next_leader_len = 0;
+ next_leader_flags = NULL;
+ } else {
+ next_is_not_par = fmt_check_par(curwin->w_cursor.lnum + 1
+ , &next_leader_len, &next_leader_flags, do_comments
+ );
+ if (do_number_indent)
+ next_is_start_par =
+ (get_number_indent(curwin->w_cursor.lnum + 1) > 0);
+ }
+ advance = TRUE;
+ is_end_par = (is_not_par || next_is_not_par || next_is_start_par);
+ if (!is_end_par && do_trail_white)
+ is_end_par = !ends_in_white(curwin->w_cursor.lnum);
+
+ /*
+ * Skip lines that are not in a paragraph.
+ */
+ if (is_not_par) {
+ if (line_count < 0)
+ break;
+ } else {
+ /*
+ * For the first line of a paragraph, check indent of second line.
+ * Don't do this for comments and empty lines.
+ */
+ if (first_par_line
+ && (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 (leader_len == 0 && next_leader_len == 0) {
+ /* no comment found */
+ second_indent =
+ get_indent_lnum(curwin->w_cursor.lnum + 1);
+ } else {
+ second_indent = next_leader_len;
+ do_comments_list = 1;
+ }
+ } else if (do_number_indent) {
+ if (leader_len == 0 && next_leader_len == 0) {
+ /* no comment found */
+ second_indent =
+ get_number_indent(curwin->w_cursor.lnum);
+ } else {
+ /* get_number_indent() is now "comment aware"... */
+ second_indent =
+ get_number_indent(curwin->w_cursor.lnum);
+ do_comments_list = 1;
+ }
+ }
+ }
+
+ /*
+ * When the comment leader changes, it's the end of the paragraph.
+ */
+ if (curwin->w_cursor.lnum >= curbuf->b_ml.ml_line_count
+ || !same_leader(curwin->w_cursor.lnum,
+ leader_len, leader_flags,
+ next_leader_len, next_leader_flags)
+ )
+ is_end_par = TRUE;
+
+ /*
+ * If we have got to the end of a paragraph, or the line is
+ * getting long, format it.
+ */
+ if (is_end_par || force_format) {
+ if (need_set_indent)
+ /* replace indent in first line with minimal number of
+ * tabs and spaces, according to current options */
+ (void)set_indent(get_indent(), SIN_CHANGED);
+
+ /* put cursor on last non-space */
+ State = NORMAL; /* don't go past end-of-line */
+ coladvance((colnr_T)MAXCOL);
+ while (curwin->w_cursor.col && vim_isspace(gchar_cursor()))
+ dec_cursor();
+
+ /* do the formatting, without 'showmode' */
+ State = INSERT; /* for open_line() */
+ smd_save = p_smd;
+ p_smd = FALSE;
+ insertchar(NUL, INSCHAR_FORMAT
+ + (do_comments ? INSCHAR_DO_COM : 0)
+ + (do_comments && do_comments_list
+ ? INSCHAR_COM_LIST : 0)
+ + (avoid_fex ? INSCHAR_NO_FEX : 0), second_indent);
+ State = old_State;
+ p_smd = smd_save;
+ second_indent = -1;
+ /* at end of par.: need to set indent of next par. */
+ need_set_indent = is_end_par;
+ if (is_end_par) {
+ /* When called with a negative line count, break at the
+ * end of the paragraph. */
+ if (line_count < 0)
+ break;
+ first_par_line = TRUE;
+ }
+ force_format = FALSE;
+ }
+
+ /*
+ * When still in same paragraph, join the lines together. But
+ * first delete the leader from the second line.
+ */
+ if (!is_end_par) {
+ advance = FALSE;
+ curwin->w_cursor.lnum++;
+ curwin->w_cursor.col = 0;
+ if (line_count < 0 && u_save_cursor() == FAIL)
+ break;
+ if (next_leader_len > 0) {
+ (void)del_bytes((long)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 = ml_get_curline();
+ int indent = (int)(skipwhite(p) - p);
+
+ if (indent > 0) {
+ (void)del_bytes(indent, FALSE, FALSE);
+ mark_col_adjust(curwin->w_cursor.lnum,
+ (colnr_T)0, 0L, (long)-indent);
+ }
+ }
+ curwin->w_cursor.lnum--;
+ if (do_join(2, TRUE, FALSE, FALSE) == FAIL) {
+ beep_flush();
+ break;
+ }
+ first_par_line = FALSE;
+ /* If the line is getting long, format it next time */
+ if (STRLEN(ml_get_curline()) > (size_t)max_len)
+ force_format = TRUE;
+ else
+ force_format = FALSE;
+ }
+ }
+ line_breakcheck();
+ }
+}
+
+/*
+ * Return TRUE if line "lnum" ends in a white character.
+ */
+static int ends_in_white(lnum)
+linenr_T lnum;
+{
+ char_u *s = ml_get(lnum);
+ size_t l;
+
+ if (*s == NUL)
+ return FALSE;
+ /* Don't use STRLEN() inside vim_iswhite(), SAS/C complains: "macro
+ * invocation may call function multiple times". */
+ l = STRLEN(s) - 1;
+ return vim_iswhite(s[l]);
+}
+
+/*
+ * Blank lines, and lines containing only the comment leader, are left
+ * untouched by the formatting. The function returns TRUE in this
+ * case. It also returns TRUE when a line starts with the end of a comment
+ * ('e' in comment flags), so that this line is skipped, and not joined to the
+ * previous line. A new paragraph starts after a blank line, or when the
+ * comment leader changes -- webb.
+ */
+static int fmt_check_par(lnum, leader_len, leader_flags, do_comments)
+linenr_T lnum;
+int *leader_len;
+char_u **leader_flags;
+int do_comments;
+{
+ char_u *flags = NULL; /* init for GCC */
+ char_u *ptr;
+
+ ptr = ml_get(lnum);
+ if (do_comments)
+ *leader_len = get_leader_len(ptr, leader_flags, FALSE, TRUE);
+ else
+ *leader_len = 0;
+
+ if (*leader_len > 0) {
+ /*
+ * Search for 'e' flag in comment leader flags.
+ */
+ flags = *leader_flags;
+ while (*flags && *flags != ':' && *flags != COM_END)
+ ++flags;
+ }
+
+ return *skipwhite(ptr + *leader_len) == NUL
+ || (*leader_len > 0 && *flags == COM_END)
+ || startPS(lnum, NUL, FALSE);
+}
+
+/*
+ * Return TRUE when a paragraph starts in line "lnum". Return FALSE when the
+ * previous line is in the same paragraph. Used for auto-formatting.
+ */
+int paragraph_start(lnum)
+linenr_T lnum;
+{
+ char_u *p;
+ int leader_len = 0; /* leader len of current line */
+ char_u *leader_flags = NULL; /* flags for leader of current line */
+ int next_leader_len; /* leader len of next line */
+ char_u *next_leader_flags; /* flags for leader of next line */
+ int do_comments; /* format comments */
+
+ if (lnum <= 1)
+ return TRUE; /* start of the file */
+
+ p = ml_get(lnum - 1);
+ if (*p == NUL)
+ return TRUE; /* after empty line */
+
+ do_comments = has_format_option(FO_Q_COMS);
+ if (fmt_check_par(lnum - 1
+ , &leader_len, &leader_flags, do_comments
+ ))
+ return TRUE; /* after non-paragraph line */
+
+ if (fmt_check_par(lnum
+ , &next_leader_len, &next_leader_flags, do_comments
+ ))
+ return TRUE; /* "lnum" is not a paragraph line */
+
+ if (has_format_option(FO_WHITE_PAR) && !ends_in_white(lnum - 1))
+ return TRUE; /* missing trailing space in previous line. */
+
+ if (has_format_option(FO_Q_NUMBER) && (get_number_indent(lnum) > 0))
+ return TRUE; /* numbered item starts in "lnum". */
+
+ if (!same_leader(lnum - 1, leader_len, leader_flags,
+ next_leader_len, next_leader_flags))
+ return TRUE; /* change of comment leader. */
+
+ return FALSE;
+}
+
+/*
+ * prepare a few things for block mode yank/delete/tilde
+ *
+ * for delete:
+ * - textlen includes the first/last char to be (partly) deleted
+ * - start/endspaces is the number of columns that are taken by the
+ * first/last deleted char minus the number of columns that have to be
+ * deleted.
+ * for yank and tilde:
+ * - textlen includes the first/last char to be wholly yanked
+ * - start/endspaces is the number of columns of the first/last yanked char
+ * that are to be yanked.
+ */
+static void block_prep(oap, bdp, lnum, is_del)
+oparg_T *oap;
+struct block_def *bdp;
+linenr_T lnum;
+int is_del;
+{
+ int incr = 0;
+ char_u *pend;
+ char_u *pstart;
+ char_u *line;
+ char_u *prev_pstart;
+ char_u *prev_pend;
+
+ bdp->startspaces = 0;
+ bdp->endspaces = 0;
+ bdp->textlen = 0;
+ bdp->start_vcol = 0;
+ bdp->end_vcol = 0;
+ bdp->is_short = FALSE;
+ bdp->is_oneChar = FALSE;
+ bdp->pre_whitesp = 0;
+ bdp->pre_whitesp_c = 0;
+ bdp->end_char_vcols = 0;
+ bdp->start_char_vcols = 0;
+
+ line = ml_get(lnum);
+ pstart = line;
+ prev_pstart = line;
+ while (bdp->start_vcol < oap->start_vcol && *pstart) {
+ /* Count a tab for what it's worth (if list mode not on) */
+ incr = lbr_chartabsize(pstart, (colnr_T)bdp->start_vcol);
+ bdp->start_vcol += incr;
+ if (vim_iswhite(*pstart)) {
+ bdp->pre_whitesp += incr;
+ bdp->pre_whitesp_c++;
+ } else {
+ bdp->pre_whitesp = 0;
+ bdp->pre_whitesp_c = 0;
+ }
+ prev_pstart = pstart;
+ mb_ptr_adv(pstart);
+ }
+ bdp->start_char_vcols = incr;
+ if (bdp->start_vcol < oap->start_vcol) { /* line too short */
+ bdp->end_vcol = bdp->start_vcol;
+ bdp->is_short = TRUE;
+ if (!is_del || oap->op_type == OP_APPEND)
+ bdp->endspaces = oap->end_vcol - oap->start_vcol + 1;
+ } else {
+ /* notice: this converts partly selected Multibyte characters to
+ * spaces, too. */
+ bdp->startspaces = bdp->start_vcol - oap->start_vcol;
+ if (is_del && bdp->startspaces)
+ bdp->startspaces = bdp->start_char_vcols - bdp->startspaces;
+ pend = pstart;
+ bdp->end_vcol = bdp->start_vcol;
+ if (bdp->end_vcol > oap->end_vcol) { /* it's all in one character */
+ bdp->is_oneChar = TRUE;
+ if (oap->op_type == OP_INSERT)
+ bdp->endspaces = bdp->start_char_vcols - bdp->startspaces;
+ else if (oap->op_type == OP_APPEND) {
+ bdp->startspaces += oap->end_vcol - oap->start_vcol + 1;
+ bdp->endspaces = bdp->start_char_vcols - bdp->startspaces;
+ } else {
+ bdp->startspaces = oap->end_vcol - oap->start_vcol + 1;
+ if (is_del && oap->op_type != OP_LSHIFT) {
+ /* just putting the sum of those two into
+ * bdp->startspaces doesn't work for Visual replace,
+ * so we have to split the tab in two */
+ bdp->startspaces = bdp->start_char_vcols
+ - (bdp->start_vcol - oap->start_vcol);
+ bdp->endspaces = bdp->end_vcol - oap->end_vcol - 1;
+ }
+ }
+ } else {
+ prev_pend = pend;
+ while (bdp->end_vcol <= oap->end_vcol && *pend != NUL) {
+ /* Count a tab for what it's worth (if list mode not on) */
+ prev_pend = pend;
+ incr = lbr_chartabsize_adv(&pend, (colnr_T)bdp->end_vcol);
+ bdp->end_vcol += incr;
+ }
+ if (bdp->end_vcol <= oap->end_vcol
+ && (!is_del
+ || oap->op_type == OP_APPEND
+ || oap->op_type == OP_REPLACE)) { /* line too short */
+ bdp->is_short = TRUE;
+ /* Alternative: include spaces to fill up the block.
+ * Disadvantage: can lead to trailing spaces when the line is
+ * short where the text is put */
+ /* if (!is_del || oap->op_type == OP_APPEND) */
+ if (oap->op_type == OP_APPEND || virtual_op)
+ bdp->endspaces = oap->end_vcol - bdp->end_vcol
+ + oap->inclusive;
+ else
+ bdp->endspaces = 0; /* replace doesn't add characters */
+ } else if (bdp->end_vcol > oap->end_vcol) {
+ bdp->endspaces = bdp->end_vcol - oap->end_vcol - 1;
+ if (!is_del && bdp->endspaces) {
+ bdp->endspaces = incr - bdp->endspaces;
+ if (pend != pstart)
+ pend = prev_pend;
+ }
+ }
+ }
+ bdp->end_char_vcols = incr;
+ if (is_del && bdp->startspaces)
+ pstart = prev_pstart;
+ bdp->textlen = (int)(pend - pstart);
+ }
+ bdp->textcol = (colnr_T) (pstart - line);
+ bdp->textstart = pstart;
+}
+
+static void reverse_line __ARGS((char_u *s));
+
+static void reverse_line(s)
+char_u *s;
+{
+ int i, j;
+ char_u c;
+
+ if ((i = (int)STRLEN(s) - 1) <= 0)
+ return;
+
+ curwin->w_cursor.col = i - curwin->w_cursor.col;
+ for (j = 0; j < i; j++, i--) {
+ c = s[i]; s[i] = s[j]; s[j] = c;
+ }
+}
+
+# define RLADDSUBFIX(ptr) if (curwin->w_p_rl) reverse_line(ptr);
+
+/*
+ * add or subtract 'Prenum1' from a number in a line
+ * 'command' is CTRL-A for add, CTRL-X for subtract
+ *
+ * return FAIL for failure, OK otherwise
+ */
+int do_addsub(command, Prenum1)
+int command;
+linenr_T Prenum1;
+{
+ int col;
+ char_u *buf1;
+ char_u buf2[NUMBUFLEN];
+ int hex; /* 'X' or 'x': hex; '0': octal */
+ static int hexupper = FALSE; /* 0xABC */
+ unsigned long n;
+ long_u oldn;
+ char_u *ptr;
+ int c;
+ int length = 0; /* character length of the number */
+ int todel;
+ int dohex;
+ int dooct;
+ int doalp;
+ int firstdigit;
+ int negative;
+ int subtract;
+
+ dohex = (vim_strchr(curbuf->b_p_nf, 'x') != NULL); /* "heX" */
+ dooct = (vim_strchr(curbuf->b_p_nf, 'o') != NULL); /* "Octal" */
+ doalp = (vim_strchr(curbuf->b_p_nf, 'p') != NULL); /* "alPha" */
+
+ ptr = ml_get_curline();
+ RLADDSUBFIX(ptr);
+
+ /*
+ * First check if we are on a hexadecimal number, after the "0x".
+ */
+ col = curwin->w_cursor.col;
+ if (dohex)
+ while (col > 0 && vim_isxdigit(ptr[col]))
+ --col;
+ if ( dohex
+ && col > 0
+ && (ptr[col] == 'X'
+ || ptr[col] == 'x')
+ && ptr[col - 1] == '0'
+ && vim_isxdigit(ptr[col + 1])) {
+ /*
+ * Found hexadecimal number, move to its start.
+ */
+ --col;
+ } else {
+ /*
+ * Search forward and then backward to find the start of number.
+ */
+ col = curwin->w_cursor.col;
+
+ while (ptr[col] != NUL
+ && !vim_isdigit(ptr[col])
+ && !(doalp && ASCII_ISALPHA(ptr[col])))
+ ++col;
+
+ while (col > 0
+ && vim_isdigit(ptr[col - 1])
+ && !(doalp && ASCII_ISALPHA(ptr[col])))
+ --col;
+ }
+
+ /*
+ * If a number was found, and saving for undo works, replace the number.
+ */
+ firstdigit = ptr[col];
+ RLADDSUBFIX(ptr);
+ if ((!VIM_ISDIGIT(firstdigit) && !(doalp && ASCII_ISALPHA(firstdigit)))
+ || u_save_cursor() != OK) {
+ beep_flush();
+ return FAIL;
+ }
+
+ /* get ptr again, because u_save() may have changed it */
+ ptr = ml_get_curline();
+ RLADDSUBFIX(ptr);
+
+ if (doalp && ASCII_ISALPHA(firstdigit)) {
+ /* decrement or increment alphabetic character */
+ if (command == Ctrl_X) {
+ if (CharOrd(firstdigit) < Prenum1) {
+ if (isupper(firstdigit))
+ firstdigit = 'A';
+ else
+ firstdigit = 'a';
+ } else
+ firstdigit -= Prenum1;
+ } else {
+ if (26 - CharOrd(firstdigit) - 1 < Prenum1) {
+ if (isupper(firstdigit))
+ firstdigit = 'Z';
+ else
+ firstdigit = 'z';
+ } else
+ firstdigit += Prenum1;
+ }
+ curwin->w_cursor.col = col;
+ (void)del_char(FALSE);
+ ins_char(firstdigit);
+ } else {
+ negative = FALSE;
+ if (col > 0 && ptr[col - 1] == '-') { /* negative number */
+ --col;
+ negative = TRUE;
+ }
+
+ /* get the number value (unsigned) */
+ vim_str2nr(ptr + col, &hex, &length, dooct, dohex, NULL, &n);
+
+ /* ignore leading '-' for hex and octal numbers */
+ if (hex && negative) {
+ ++col;
+ --length;
+ negative = FALSE;
+ }
+
+ /* add or subtract */
+ subtract = FALSE;
+ if (command == Ctrl_X)
+ subtract ^= TRUE;
+ if (negative)
+ subtract ^= TRUE;
+
+ oldn = n;
+ if (subtract)
+ n -= (unsigned long)Prenum1;
+ else
+ n += (unsigned long)Prenum1;
+
+ /* handle wraparound for decimal numbers */
+ if (!hex) {
+ if (subtract) {
+ if (n > oldn) {
+ n = 1 + (n ^ (unsigned long)-1);
+ negative ^= TRUE;
+ }
+ } else { /* add */
+ if (n < oldn) {
+ n = (n ^ (unsigned long)-1);
+ negative ^= TRUE;
+ }
+ }
+ if (n == 0)
+ negative = FALSE;
+ }
+
+ /*
+ * Delete the old number.
+ */
+ curwin->w_cursor.col = col;
+ todel = length;
+ c = gchar_cursor();
+ /*
+ * Don't include the '-' in the length, only the length of the part
+ * after it is kept the same.
+ */
+ if (c == '-')
+ --length;
+ while (todel-- > 0) {
+ if (c < 0x100 && isalpha(c)) {
+ if (isupper(c))
+ hexupper = TRUE;
+ else
+ hexupper = FALSE;
+ }
+ /* del_char() will mark line needing displaying */
+ (void)del_char(FALSE);
+ c = gchar_cursor();
+ }
+
+ /*
+ * Prepare the leading characters in buf1[].
+ * When there are many leading zeros it could be very long. Allocate
+ * a bit too much.
+ */
+ buf1 = alloc((unsigned)length + NUMBUFLEN);
+ if (buf1 == NULL)
+ return FAIL;
+ ptr = buf1;
+ if (negative) {
+ *ptr++ = '-';
+ }
+ if (hex) {
+ *ptr++ = '0';
+ --length;
+ }
+ if (hex == 'x' || hex == 'X') {
+ *ptr++ = hex;
+ --length;
+ }
+
+ /*
+ * Put the number characters in buf2[].
+ */
+ if (hex == 0)
+ sprintf((char *)buf2, "%lu", n);
+ else if (hex == '0')
+ sprintf((char *)buf2, "%lo", n);
+ else if (hex && hexupper)
+ sprintf((char *)buf2, "%lX", n);
+ else
+ sprintf((char *)buf2, "%lx", n);
+ length -= (int)STRLEN(buf2);
+
+ /*
+ * Adjust number of zeros to the new number of digits, so the
+ * total length of the number remains the same.
+ * Don't do this when
+ * the result may look like an octal number.
+ */
+ if (firstdigit == '0' && !(dooct && hex == 0))
+ while (length-- > 0)
+ *ptr++ = '0';
+ *ptr = NUL;
+ STRCAT(buf1, buf2);
+ ins_str(buf1); /* insert the new number */
+ vim_free(buf1);
+ }
+ --curwin->w_cursor.col;
+ curwin->w_set_curswant = TRUE;
+ ptr = ml_get_buf(curbuf, curwin->w_cursor.lnum, TRUE);
+ RLADDSUBFIX(ptr);
+ return OK;
+}
+
+int read_viminfo_register(virp, force)
+vir_T *virp;
+int force;
+{
+ int eof;
+ int do_it = TRUE;
+ int size;
+ int limit;
+ int i;
+ int set_prev = FALSE;
+ char_u *str;
+ char_u **array = NULL;
+
+ /* We only get here (hopefully) if line[0] == '"' */
+ str = virp->vir_line + 1;
+
+ /* If the line starts with "" this is the y_previous register. */
+ if (*str == '"') {
+ set_prev = TRUE;
+ str++;
+ }
+
+ if (!ASCII_ISALNUM(*str) && *str != '-') {
+ if (viminfo_error("E577: ", _("Illegal register name"), virp->vir_line))
+ return TRUE; /* too many errors, pretend end-of-file */
+ do_it = FALSE;
+ }
+ get_yank_register(*str++, FALSE);
+ if (!force && y_current->y_array != NULL)
+ do_it = FALSE;
+
+ if (*str == '@') {
+ /* "x@: register x used for @@ */
+ if (force || execreg_lastc == NUL)
+ execreg_lastc = str[-1];
+ }
+
+ size = 0;
+ limit = 100; /* Optimized for registers containing <= 100 lines */
+ if (do_it) {
+ if (set_prev)
+ y_previous = y_current;
+ vim_free(y_current->y_array);
+ array = y_current->y_array =
+ (char_u **)alloc((unsigned)(limit * sizeof(char_u *)));
+ str = skipwhite(skiptowhite(str));
+ if (STRNCMP(str, "CHAR", 4) == 0)
+ y_current->y_type = MCHAR;
+ else if (STRNCMP(str, "BLOCK", 5) == 0)
+ y_current->y_type = MBLOCK;
+ else
+ y_current->y_type = MLINE;
+ /* get the block width; if it's missing we get a zero, which is OK */
+ str = skipwhite(skiptowhite(str));
+ y_current->y_width = getdigits(&str);
+ }
+
+ while (!(eof = viminfo_readline(virp))
+ && (virp->vir_line[0] == TAB || virp->vir_line[0] == '<')) {
+ if (do_it) {
+ if (size >= limit) {
+ y_current->y_array = (char_u **)
+ alloc((unsigned)(limit * 2 * sizeof(char_u *)));
+ for (i = 0; i < limit; i++)
+ y_current->y_array[i] = array[i];
+ vim_free(array);
+ limit *= 2;
+ array = y_current->y_array;
+ }
+ str = viminfo_readstring(virp, 1, TRUE);
+ if (str != NULL)
+ array[size++] = str;
+ else
+ do_it = FALSE;
+ }
+ }
+ if (do_it) {
+ if (size == 0) {
+ vim_free(array);
+ y_current->y_array = NULL;
+ } else if (size < limit) {
+ y_current->y_array =
+ (char_u **)alloc((unsigned)(size * sizeof(char_u *)));
+ for (i = 0; i < size; i++)
+ y_current->y_array[i] = array[i];
+ vim_free(array);
+ }
+ y_current->y_size = size;
+ }
+ return eof;
+}
+
+void write_viminfo_registers(fp)
+FILE *fp;
+{
+ int i, j;
+ char_u *type;
+ char_u c;
+ int num_lines;
+ int max_num_lines;
+ int max_kbyte;
+ long len;
+
+ fputs(_("\n# Registers:\n"), fp);
+
+ /* Get '<' value, use old '"' value if '<' is not found. */
+ max_num_lines = get_viminfo_parameter('<');
+ if (max_num_lines < 0)
+ max_num_lines = get_viminfo_parameter('"');
+ if (max_num_lines == 0)
+ return;
+ max_kbyte = get_viminfo_parameter('s');
+ if (max_kbyte == 0)
+ return;
+
+ for (i = 0; i < NUM_REGISTERS; i++) {
+ if (y_regs[i].y_array == NULL)
+ continue;
+ /* Skip empty registers. */
+ num_lines = y_regs[i].y_size;
+ if (num_lines == 0
+ || (num_lines == 1 && y_regs[i].y_type == MCHAR
+ && *y_regs[i].y_array[0] == NUL))
+ continue;
+
+ if (max_kbyte > 0) {
+ /* Skip register if there is more text than the maximum size. */
+ len = 0;
+ for (j = 0; j < num_lines; j++)
+ len += (long)STRLEN(y_regs[i].y_array[j]) + 1L;
+ if (len > (long)max_kbyte * 1024L)
+ continue;
+ }
+
+ switch (y_regs[i].y_type) {
+ case MLINE:
+ type = (char_u *)"LINE";
+ break;
+ case MCHAR:
+ type = (char_u *)"CHAR";
+ break;
+ case MBLOCK:
+ type = (char_u *)"BLOCK";
+ break;
+ default:
+ sprintf((char *)IObuff, _("E574: Unknown register type %d"),
+ y_regs[i].y_type);
+ emsg(IObuff);
+ type = (char_u *)"LINE";
+ break;
+ }
+ if (y_previous == &y_regs[i])
+ fprintf(fp, "\"");
+ c = get_register_name(i);
+ fprintf(fp, "\"%c", c);
+ if (c == execreg_lastc)
+ fprintf(fp, "@");
+ fprintf(fp, "\t%s\t%d\n", type,
+ (int)y_regs[i].y_width
+ );
+
+ /* If max_num_lines < 0, then we save ALL the lines in the register */
+ if (max_num_lines > 0 && num_lines > max_num_lines)
+ num_lines = max_num_lines;
+ for (j = 0; j < num_lines; j++) {
+ putc('\t', fp);
+ viminfo_writestring(fp, y_regs[i].y_array[j]);
+ }
+ }
+}
+
+
+
+
+
+/*
+ * Return the type of a register.
+ * Used for getregtype()
+ * Returns MAUTO for error.
+ */
+char_u get_reg_type(regname, reglen)
+int regname;
+long *reglen;
+{
+ switch (regname) {
+ case '%': /* file name */
+ case '#': /* alternate file name */
+ case '=': /* expression */
+ case ':': /* last command line */
+ case '/': /* last search-pattern */
+ case '.': /* last inserted text */
+ case Ctrl_F: /* Filename under cursor */
+ case Ctrl_P: /* Path under cursor, expand via "path" */
+ case Ctrl_W: /* word under cursor */
+ case Ctrl_A: /* WORD (mnemonic All) under cursor */
+ case '_': /* black hole: always empty */
+ return MCHAR;
+ }
+
+
+ if (regname != NUL && !valid_yank_reg(regname, FALSE))
+ return MAUTO;
+
+ get_yank_register(regname, FALSE);
+
+ if (y_current->y_array != NULL) {
+ if (reglen != NULL && y_current->y_type == MBLOCK)
+ *reglen = y_current->y_width;
+ return y_current->y_type;
+ }
+ return MAUTO;
+}
+
+/*
+ * Return the contents of a register as a single allocated string.
+ * Used for "@r" in expressions and for getreg().
+ * Returns NULL for error.
+ */
+char_u * get_reg_contents(regname, allowexpr, expr_src)
+int regname;
+int allowexpr; /* allow "=" register */
+int expr_src; /* get expression for "=" register */
+{
+ long i;
+ char_u *retval;
+ int allocated;
+ long len;
+
+ /* Don't allow using an expression register inside an expression */
+ if (regname == '=') {
+ if (allowexpr) {
+ if (expr_src)
+ return get_expr_line_src();
+ return get_expr_line();
+ }
+ return NULL;
+ }
+
+ if (regname == '@') /* "@@" is used for unnamed register */
+ regname = '"';
+
+ /* check for valid regname */
+ if (regname != NUL && !valid_yank_reg(regname, FALSE))
+ return NULL;
+
+
+ if (get_spec_reg(regname, &retval, &allocated, FALSE)) {
+ if (retval == NULL)
+ return NULL;
+ if (!allocated)
+ retval = vim_strsave(retval);
+ return retval;
+ }
+
+ get_yank_register(regname, FALSE);
+ if (y_current->y_array == NULL)
+ return NULL;
+
+ /*
+ * Compute length of resulting string.
+ */
+ len = 0;
+ for (i = 0; i < y_current->y_size; ++i) {
+ len += (long)STRLEN(y_current->y_array[i]);
+ /*
+ * Insert a newline between lines and after last line if
+ * y_type is MLINE.
+ */
+ if (y_current->y_type == MLINE || i < y_current->y_size - 1)
+ ++len;
+ }
+
+ retval = lalloc(len + 1, TRUE);
+
+ /*
+ * Copy the lines of the yank register into the string.
+ */
+ if (retval != NULL) {
+ len = 0;
+ for (i = 0; i < y_current->y_size; ++i) {
+ STRCPY(retval + len, y_current->y_array[i]);
+ len += (long)STRLEN(retval + len);
+
+ /*
+ * Insert a NL between lines and after the last line if y_type is
+ * MLINE.
+ */
+ if (y_current->y_type == MLINE || i < y_current->y_size - 1)
+ retval[len++] = '\n';
+ }
+ retval[len] = NUL;
+ }
+
+ return retval;
+}
+
+/*
+ * Store string "str" in register "name".
+ * "maxlen" is the maximum number of bytes to use, -1 for all bytes.
+ * If "must_append" is TRUE, always append to the register. Otherwise append
+ * if "name" is an uppercase letter.
+ * Note: "maxlen" and "must_append" don't work for the "/" register.
+ * Careful: 'str' is modified, you may have to use a copy!
+ * If "str" ends in '\n' or '\r', use linewise, otherwise use characterwise.
+ */
+void write_reg_contents(name, str, maxlen, must_append)
+int name;
+char_u *str;
+int maxlen;
+int must_append;
+{
+ write_reg_contents_ex(name, str, maxlen, must_append, MAUTO, 0L);
+}
+
+void write_reg_contents_ex(name, str, maxlen, must_append, yank_type, block_len)
+int name;
+char_u *str;
+int maxlen;
+int must_append;
+int yank_type;
+long block_len;
+{
+ struct yankreg *old_y_previous, *old_y_current;
+ long len;
+
+ if (maxlen >= 0)
+ len = maxlen;
+ else
+ len = (long)STRLEN(str);
+
+ /* Special case: '/' search pattern */
+ if (name == '/') {
+ set_last_search_pat(str, RE_SEARCH, TRUE, TRUE);
+ return;
+ }
+
+ if (name == '=') {
+ char_u *p, *s;
+
+ p = vim_strnsave(str, (int)len);
+ if (p == NULL)
+ return;
+ if (must_append) {
+ s = concat_str(get_expr_line_src(), p);
+ vim_free(p);
+ p = s;
+
+ }
+ set_expr_line(p);
+ return;
+ }
+
+ if (!valid_yank_reg(name, TRUE)) { /* check for valid reg name */
+ emsg_invreg(name);
+ return;
+ }
+
+ if (name == '_') /* black hole: nothing to do */
+ return;
+
+ /* Don't want to change the current (unnamed) register */
+ old_y_previous = y_previous;
+ old_y_current = y_current;
+
+ get_yank_register(name, TRUE);
+ if (!y_append && !must_append)
+ free_yank_all();
+ str_to_reg(y_current, yank_type, str, len, block_len);
+
+
+ /* ':let @" = "val"' should change the meaning of the "" register */
+ if (name != '"')
+ y_previous = old_y_previous;
+ y_current = old_y_current;
+}
+
+/*
+ * Put a string into a register. When the register is not empty, the string
+ * is appended.
+ */
+static void str_to_reg(y_ptr, yank_type, str, len, blocklen)
+struct yankreg *y_ptr; /* pointer to yank register */
+int yank_type; /* MCHAR, MLINE, MBLOCK, MAUTO */
+char_u *str; /* string to put in register */
+long len; /* length of string */
+long blocklen; /* width of Visual block */
+{
+ int type; /* MCHAR, MLINE or MBLOCK */
+ int lnum;
+ long start;
+ long i;
+ int extra;
+ int newlines; /* number of lines added */
+ int extraline = 0; /* extra line at the end */
+ int append = FALSE; /* append to last line in register */
+ char_u *s;
+ char_u **pp;
+ long maxlen;
+
+ if (y_ptr->y_array == NULL) /* NULL means empty register */
+ y_ptr->y_size = 0;
+
+ if (yank_type == MAUTO)
+ type = ((len > 0 && (str[len - 1] == NL || str[len - 1] == CAR))
+ ? MLINE : MCHAR);
+ else
+ type = yank_type;
+
+ /*
+ * Count the number of lines within the string
+ */
+ newlines = 0;
+ for (i = 0; i < len; i++)
+ if (str[i] == '\n')
+ ++newlines;
+ if (type == MCHAR || len == 0 || str[len - 1] != '\n') {
+ extraline = 1;
+ ++newlines; /* count extra newline at the end */
+ }
+ if (y_ptr->y_size > 0 && y_ptr->y_type == MCHAR) {
+ append = TRUE;
+ --newlines; /* uncount newline when appending first line */
+ }
+
+ /*
+ * Allocate an array to hold the pointers to the new register lines.
+ * If the register was not empty, move the existing lines to the new array.
+ */
+ pp = (char_u **)lalloc_clear((y_ptr->y_size + newlines)
+ * sizeof(char_u *), TRUE);
+ if (pp == NULL) /* out of memory */
+ return;
+ for (lnum = 0; lnum < y_ptr->y_size; ++lnum)
+ pp[lnum] = y_ptr->y_array[lnum];
+ vim_free(y_ptr->y_array);
+ y_ptr->y_array = pp;
+ maxlen = 0;
+
+ /*
+ * Find the end of each line and save it into the array.
+ */
+ for (start = 0; start < len + extraline; start += i + 1) {
+ for (i = start; i < len; ++i) /* find the end of the line */
+ if (str[i] == '\n')
+ break;
+ i -= start; /* i is now length of line */
+ if (i > maxlen)
+ maxlen = i;
+ if (append) {
+ --lnum;
+ extra = (int)STRLEN(y_ptr->y_array[lnum]);
+ } else
+ extra = 0;
+ s = alloc((unsigned)(i + extra + 1));
+ if (s == NULL)
+ break;
+ if (extra)
+ mch_memmove(s, y_ptr->y_array[lnum], (size_t)extra);
+ if (append)
+ vim_free(y_ptr->y_array[lnum]);
+ if (i)
+ mch_memmove(s + extra, str + start, (size_t)i);
+ extra += i;
+ s[extra] = NUL;
+ y_ptr->y_array[lnum++] = s;
+ while (--extra >= 0) {
+ if (*s == NUL)
+ *s = '\n'; /* replace NUL with newline */
+ ++s;
+ }
+ append = FALSE; /* only first line is appended */
+ }
+ y_ptr->y_type = type;
+ y_ptr->y_size = lnum;
+ if (type == MBLOCK)
+ y_ptr->y_width = (blocklen < 0 ? maxlen - 1 : blocklen);
+ else
+ y_ptr->y_width = 0;
+}
+
+void clear_oparg(oap)
+oparg_T *oap;
+{
+ vim_memset(oap, 0, sizeof(oparg_T));
+}
+
+static long line_count_info __ARGS((char_u *line, long *wc, long *cc,
+ long limit,
+ int eol_size));
+
+/*
+ * Count the number of bytes, characters and "words" in a line.
+ *
+ * "Words" are counted by looking for boundaries between non-space and
+ * space characters. (it seems to produce results that match 'wc'.)
+ *
+ * Return value is byte count; word count for the line is added to "*wc".
+ * Char count is added to "*cc".
+ *
+ * The function will only examine the first "limit" characters in the
+ * line, stopping if it encounters an end-of-line (NUL byte). In that
+ * case, eol_size will be added to the character count to account for
+ * the size of the EOL character.
+ */
+static long line_count_info(line, wc, cc, limit, eol_size)
+char_u *line;
+long *wc;
+long *cc;
+long limit;
+int eol_size;
+{
+ long i;
+ long words = 0;
+ long chars = 0;
+ int is_word = 0;
+
+ for (i = 0; i < limit && line[i] != NUL; ) {
+ if (is_word) {
+ if (vim_isspace(line[i])) {
+ words++;
+ is_word = 0;
+ }
+ } else if (!vim_isspace(line[i]))
+ is_word = 1;
+ ++chars;
+ i += (*mb_ptr2len)(line + i);
+ }
+
+ if (is_word)
+ words++;
+ *wc += words;
+
+ /* Add eol_size if the end of line was reached before hitting limit. */
+ if (i < limit && line[i] == NUL) {
+ i += eol_size;
+ chars += eol_size;
+ }
+ *cc += chars;
+ return i;
+}
+
+/*
+ * Give some info about the position of the cursor (for "g CTRL-G").
+ * In Visual mode, give some info about the selected region. (In this case,
+ * the *_count_cursor variables store running totals for the selection.)
+ */
+void cursor_pos_info() {
+ char_u *p;
+ char_u buf1[50];
+ char_u buf2[40];
+ linenr_T lnum;
+ long byte_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;
+ int eol_size;
+ long last_check = 100000L;
+ long line_count_selected = 0;
+ pos_T min_pos, max_pos;
+ oparg_T oparg;
+ struct block_def bd;
+
+ /*
+ * Compute the length of the file in characters.
+ */
+ if (curbuf->b_ml.ml_flags & ML_EMPTY) {
+ MSG(_(no_lines_msg));
+ } else {
+ if (get_fileformat(curbuf) == EOL_DOS)
+ eol_size = 2;
+ else
+ eol_size = 1;
+
+ if (VIsual_active) {
+ if (lt(VIsual, curwin->w_cursor)) {
+ min_pos = VIsual;
+ max_pos = curwin->w_cursor;
+ } else {
+ min_pos = curwin->w_cursor;
+ max_pos = VIsual;
+ }
+ if (*p_sel == 'e' && max_pos.col > 0)
+ --max_pos.col;
+
+ if (VIsual_mode == Ctrl_V) {
+ char_u * saved_sbr = p_sbr;
+
+ /* Make 'sbr' empty for a moment to get the correct size. */
+ p_sbr = empty_option;
+ oparg.is_VIsual = 1;
+ oparg.block_mode = TRUE;
+ oparg.op_type = OP_NOP;
+ getvcols(curwin, &min_pos, &max_pos,
+ &oparg.start_vcol, &oparg.end_vcol);
+ p_sbr = saved_sbr;
+ if (curwin->w_curswant == MAXCOL)
+ oparg.end_vcol = MAXCOL;
+ /* Swap the start, end vcol if needed */
+ if (oparg.end_vcol < oparg.start_vcol) {
+ oparg.end_vcol += oparg.start_vcol;
+ oparg.start_vcol = oparg.end_vcol - oparg.start_vcol;
+ oparg.end_vcol -= oparg.start_vcol;
+ }
+ }
+ line_count_selected = max_pos.lnum - min_pos.lnum + 1;
+ }
+
+ for (lnum = 1; lnum <= curbuf->b_ml.ml_line_count; ++lnum) {
+ /* Check for a CTRL-C every 100000 characters. */
+ if (byte_count > last_check) {
+ ui_breakcheck();
+ if (got_int)
+ return;
+ last_check = byte_count + 100000L;
+ }
+
+ /* Do extra processing for VIsual mode. */
+ if (VIsual_active
+ && lnum >= min_pos.lnum && lnum <= max_pos.lnum) {
+ char_u *s = NULL;
+ long len = 0L;
+
+ switch (VIsual_mode) {
+ case Ctrl_V:
+ virtual_op = virtual_active();
+ block_prep(&oparg, &bd, lnum, 0);
+ virtual_op = MAYBE;
+ s = bd.textstart;
+ len = (long)bd.textlen;
+ break;
+ case 'V':
+ s = ml_get(lnum);
+ len = MAXCOL;
+ break;
+ case 'v':
+ {
+ colnr_T start_col = (lnum == min_pos.lnum)
+ ? min_pos.col : 0;
+ colnr_T end_col = (lnum == max_pos.lnum)
+ ? max_pos.col - start_col + 1 : MAXCOL;
+
+ s = ml_get(lnum) + start_col;
+ len = end_col;
+ }
+ break;
+ }
+ if (s != NULL) {
+ byte_count_cursor += line_count_info(s, &word_count_cursor,
+ &char_count_cursor, len, eol_size);
+ if (lnum == curbuf->b_ml.ml_line_count
+ && !curbuf->b_p_eol
+ && curbuf->b_p_bin
+ && (long)STRLEN(s) < len)
+ byte_count_cursor -= eol_size;
+ }
+ } else {
+ /* In non-visual mode, check for the line the cursor is on */
+ 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);
+ }
+ }
+ /* Add to the running totals */
+ byte_count += line_count_info(ml_get(lnum), &word_count,
+ &char_count, (long)MAXCOL, eol_size);
+ }
+
+ /* Correction for when last line doesn't have an EOL. */
+ if (!curbuf->b_p_eol && curbuf->b_p_bin)
+ byte_count -= eol_size;
+
+ if (VIsual_active) {
+ if (VIsual_mode == Ctrl_V && curwin->w_curswant < MAXCOL) {
+ getvcols(curwin, &min_pos, &max_pos, &min_pos.col,
+ &max_pos.col);
+ vim_snprintf((char *)buf1, sizeof(buf1), _("%ld Cols; "),
+ (long)(oparg.end_vcol - oparg.start_vcol + 1));
+ } else
+ buf1[0] = NUL;
+
+ if (char_count_cursor == byte_count_cursor
+ && char_count == byte_count)
+ vim_snprintf((char *)IObuff, IOSIZE,
+ _("Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Bytes"),
+ buf1, line_count_selected,
+ (long)curbuf->b_ml.ml_line_count,
+ word_count_cursor, word_count,
+ byte_count_cursor, byte_count);
+ else
+ vim_snprintf((char *)IObuff, IOSIZE,
+ _(
+ "Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Chars; %ld of %ld Bytes"),
+ buf1, line_count_selected,
+ (long)curbuf->b_ml.ml_line_count,
+ word_count_cursor, word_count,
+ char_count_cursor, char_count,
+ byte_count_cursor, byte_count);
+ } else {
+ p = ml_get_curline();
+ validate_virtcol();
+ col_print(buf1, sizeof(buf1), (int)curwin->w_cursor.col + 1,
+ (int)curwin->w_virtcol + 1);
+ col_print(buf2, sizeof(buf2), (int)STRLEN(p), linetabsize(p));
+
+ if (char_count_cursor == byte_count_cursor
+ && char_count == byte_count)
+ vim_snprintf((char *)IObuff, IOSIZE,
+ _("Col %s of %s; Line %ld of %ld; Word %ld of %ld; Byte %ld of %ld"),
+ (char *)buf1, (char *)buf2,
+ (long)curwin->w_cursor.lnum,
+ (long)curbuf->b_ml.ml_line_count,
+ word_count_cursor, word_count,
+ byte_count_cursor, byte_count);
+ else
+ vim_snprintf((char *)IObuff, IOSIZE,
+ _(
+ "Col %s of %s; Line %ld of %ld; Word %ld of %ld; Char %ld of %ld; Byte %ld of %ld"),
+ (char *)buf1, (char *)buf2,
+ (long)curwin->w_cursor.lnum,
+ (long)curbuf->b_ml.ml_line_count,
+ word_count_cursor, word_count,
+ char_count_cursor, char_count,
+ byte_count_cursor, byte_count);
+ }
+
+ byte_count = bomb_size();
+ if (byte_count > 0)
+ sprintf((char *)IObuff + STRLEN(IObuff), _("(+%ld for BOM)"),
+ byte_count);
+ /* Don't shorten this message, the user asked for it. */
+ p = p_shm;
+ p_shm = (char_u *)"";
+ msg(IObuff);
+ p_shm = p;
+ }
+}
+
diff --git a/src/option.c b/src/option.c
new file mode 100644
index 0000000000..9dc432a1d4
--- /dev/null
+++ b/src/option.c
@@ -0,0 +1,8298 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * 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.
+ */
+
+/*
+ * 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.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 structs.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.
+ * - When an entry has the P_VIM flag, or is lacking the P_VI_DEF flag, add a
+ * comment at the help for the 'compatible' option.
+ */
+
+#define IN_OPTION_C
+#include "vim.h"
+
+/*
+ * The options that are local to a window or buffer have "indir" set to one of
+ * these values. Special values:
+ * PV_NONE: global option.
+ * PV_WIN is added: window-local option
+ * PV_BUF is added: buffer-local option
+ * PV_BOTH is added: global option which also has a local value.
+ */
+#define PV_BOTH 0x1000
+#define PV_WIN 0x2000
+#define PV_BUF 0x4000
+#define PV_MASK 0x0fff
+#define OPT_WIN(x) (idopt_T)(PV_WIN + (int)(x))
+#define OPT_BUF(x) (idopt_T)(PV_BUF + (int)(x))
+#define OPT_BOTH(x) (idopt_T)(PV_BOTH + (int)(x))
+
+/*
+ * Definition of the PV_ values for buffer-local options.
+ * The BV_ values are defined in option.h.
+ */
+#define PV_AI OPT_BUF(BV_AI)
+#define PV_AR OPT_BOTH(OPT_BUF(BV_AR))
+# define PV_BH OPT_BUF(BV_BH)
+# define PV_BT OPT_BUF(BV_BT)
+# define PV_EFM OPT_BOTH(OPT_BUF(BV_EFM))
+# define PV_GP OPT_BOTH(OPT_BUF(BV_GP))
+# define PV_MP OPT_BOTH(OPT_BUF(BV_MP))
+#define PV_BIN OPT_BUF(BV_BIN)
+#define PV_BL OPT_BUF(BV_BL)
+# define PV_BOMB OPT_BUF(BV_BOMB)
+#define PV_CI OPT_BUF(BV_CI)
+# define PV_CIN OPT_BUF(BV_CIN)
+# define PV_CINK OPT_BUF(BV_CINK)
+# define PV_CINO OPT_BUF(BV_CINO)
+# define PV_CINW OPT_BUF(BV_CINW)
+#define PV_CM OPT_BOTH(OPT_BUF(BV_CM))
+# define PV_CMS OPT_BUF(BV_CMS)
+# define PV_COM OPT_BUF(BV_COM)
+# define PV_CPT OPT_BUF(BV_CPT)
+# define PV_DICT OPT_BOTH(OPT_BUF(BV_DICT))
+# define PV_TSR OPT_BOTH(OPT_BUF(BV_TSR))
+# define PV_CFU OPT_BUF(BV_CFU)
+# define PV_DEF OPT_BOTH(OPT_BUF(BV_DEF))
+# define PV_INC OPT_BOTH(OPT_BUF(BV_INC))
+#define PV_EOL OPT_BUF(BV_EOL)
+#define PV_EP OPT_BOTH(OPT_BUF(BV_EP))
+#define PV_ET OPT_BUF(BV_ET)
+# define PV_FENC OPT_BUF(BV_FENC)
+# define PV_FEX OPT_BUF(BV_FEX)
+#define PV_FF OPT_BUF(BV_FF)
+#define PV_FLP OPT_BUF(BV_FLP)
+#define PV_FO OPT_BUF(BV_FO)
+# define PV_FT OPT_BUF(BV_FT)
+#define PV_IMI OPT_BUF(BV_IMI)
+#define PV_IMS OPT_BUF(BV_IMS)
+# define PV_INDE OPT_BUF(BV_INDE)
+# define PV_INDK OPT_BUF(BV_INDK)
+# define PV_INEX OPT_BUF(BV_INEX)
+#define PV_INF OPT_BUF(BV_INF)
+#define PV_ISK OPT_BUF(BV_ISK)
+# define PV_KEY OPT_BUF(BV_KEY)
+# define PV_KMAP OPT_BUF(BV_KMAP)
+#define PV_KP OPT_BOTH(OPT_BUF(BV_KP))
+# define PV_LISP OPT_BUF(BV_LISP)
+#define PV_MA OPT_BUF(BV_MA)
+#define PV_ML OPT_BUF(BV_ML)
+#define PV_MOD OPT_BUF(BV_MOD)
+#define PV_MPS OPT_BUF(BV_MPS)
+#define PV_NF OPT_BUF(BV_NF)
+# define PV_OFU OPT_BUF(BV_OFU)
+#define PV_PATH OPT_BOTH(OPT_BUF(BV_PATH))
+#define PV_PI OPT_BUF(BV_PI)
+# define PV_QE OPT_BUF(BV_QE)
+#define PV_RO OPT_BUF(BV_RO)
+# define PV_SI OPT_BUF(BV_SI)
+#ifndef SHORT_FNAME
+# define PV_SN OPT_BUF(BV_SN)
+#endif
+# define PV_SMC OPT_BUF(BV_SMC)
+# define PV_SYN OPT_BUF(BV_SYN)
+# define PV_SPC OPT_BUF(BV_SPC)
+# define PV_SPF OPT_BUF(BV_SPF)
+# define PV_SPL OPT_BUF(BV_SPL)
+#define PV_STS OPT_BUF(BV_STS)
+# define PV_SUA OPT_BUF(BV_SUA)
+#define PV_SW OPT_BUF(BV_SW)
+#define PV_SWF OPT_BUF(BV_SWF)
+#define PV_TAGS OPT_BOTH(OPT_BUF(BV_TAGS))
+#define PV_TS OPT_BUF(BV_TS)
+#define PV_TW OPT_BUF(BV_TW)
+#define PV_TX OPT_BUF(BV_TX)
+# define PV_UDF OPT_BUF(BV_UDF)
+#define PV_WM OPT_BUF(BV_WM)
+
+/*
+ * Definition of the PV_ values for window-local options.
+ * The WV_ values are defined in option.h.
+ */
+#define PV_LIST OPT_WIN(WV_LIST)
+# define PV_ARAB OPT_WIN(WV_ARAB)
+# define PV_DIFF OPT_WIN(WV_DIFF)
+# define PV_FDC OPT_WIN(WV_FDC)
+# define PV_FEN OPT_WIN(WV_FEN)
+# define PV_FDI OPT_WIN(WV_FDI)
+# define PV_FDL OPT_WIN(WV_FDL)
+# define PV_FDM OPT_WIN(WV_FDM)
+# define PV_FML OPT_WIN(WV_FML)
+# define PV_FDN OPT_WIN(WV_FDN)
+# define PV_FDE OPT_WIN(WV_FDE)
+# define PV_FDT OPT_WIN(WV_FDT)
+# define PV_FMR OPT_WIN(WV_FMR)
+# define PV_LBR OPT_WIN(WV_LBR)
+#define PV_NU OPT_WIN(WV_NU)
+#define PV_RNU OPT_WIN(WV_RNU)
+# define PV_NUW OPT_WIN(WV_NUW)
+# define PV_PVW OPT_WIN(WV_PVW)
+# define PV_RL OPT_WIN(WV_RL)
+# define PV_RLC OPT_WIN(WV_RLC)
+# define PV_SCBIND OPT_WIN(WV_SCBIND)
+#define PV_SCROLL OPT_WIN(WV_SCROLL)
+# define PV_SPELL OPT_WIN(WV_SPELL)
+# define PV_CUC OPT_WIN(WV_CUC)
+# define PV_CUL OPT_WIN(WV_CUL)
+# define PV_CC OPT_WIN(WV_CC)
+# define PV_STL OPT_BOTH(OPT_WIN(WV_STL))
+#define PV_UL OPT_BOTH(OPT_BUF(BV_UL))
+# define PV_WFH OPT_WIN(WV_WFH)
+# define PV_WFW OPT_WIN(WV_WFW)
+#define PV_WRAP OPT_WIN(WV_WRAP)
+# define PV_CRBIND OPT_WIN(WV_CRBIND)
+# define PV_COCU OPT_WIN(WV_COCU)
+# define PV_COLE OPT_WIN(WV_COLE)
+
+/* WV_ and BV_ values get typecasted to this for the "indir" field */
+typedef enum {
+ PV_NONE = 0,
+ PV_MAXVAL = 0xffff /* to avoid warnings for value out of range */
+} idopt_T;
+
+/*
+ * Options local to a window have a value local to a buffer and global to all
+ * buffers. Indicate this by setting "var" to VAR_WIN.
+ */
+#define VAR_WIN ((char_u *)-1)
+
+/*
+ * These are the global values for options which are also local to a buffer.
+ * Only to be used in option.c!
+ */
+static int p_ai;
+static int p_bin;
+static int p_bomb;
+static char_u *p_bh;
+static char_u *p_bt;
+static int p_bl;
+static int p_ci;
+static int p_cin;
+static char_u *p_cink;
+static char_u *p_cino;
+static char_u *p_cinw;
+static char_u *p_com;
+static char_u *p_cms;
+static char_u *p_cpt;
+static char_u *p_cfu;
+static char_u *p_ofu;
+static int p_eol;
+static int p_et;
+static char_u *p_fenc;
+static char_u *p_ff;
+static char_u *p_fo;
+static char_u *p_flp;
+static char_u *p_ft;
+static long p_iminsert;
+static long p_imsearch;
+static char_u *p_inex;
+static char_u *p_inde;
+static char_u *p_indk;
+static char_u *p_fex;
+static int p_inf;
+static char_u *p_isk;
+static char_u *p_key;
+static int p_lisp;
+static int p_ml;
+static int p_ma;
+static int p_mod;
+static char_u *p_mps;
+static char_u *p_nf;
+static int p_pi;
+static char_u *p_qe;
+static int p_ro;
+static int p_si;
+#ifndef SHORT_FNAME
+static int p_sn;
+#endif
+static long p_sts;
+static char_u *p_sua;
+static long p_sw;
+static int p_swf;
+static long p_smc;
+static char_u *p_syn;
+static char_u *p_spc;
+static char_u *p_spf;
+static char_u *p_spl;
+static long p_ts;
+static long p_tw;
+static int p_tx;
+static int p_udf;
+static long p_wm;
+static char_u *p_keymap;
+
+/* Saved values for when 'bin' is set. */
+static int p_et_nobin;
+static int p_ml_nobin;
+static long p_tw_nobin;
+static long p_wm_nobin;
+
+/* Saved values for when 'paste' is set */
+static long p_tw_nopaste;
+static long p_wm_nopaste;
+static long p_sts_nopaste;
+static int p_ai_nopaste;
+
+struct vimoption {
+ char *fullname; /* full option name */
+ char *shortname; /* permissible abbreviation */
+ long_u 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 */
+# define SCRIPTID_INIT , 0
+};
+
+#define VI_DEFAULT 0 /* def_val[VI_DEFAULT] is Vi default value */
+#define VIM_DEFAULT 1 /* def_val[VIM_DEFAULT] is Vim default value */
+
+/*
+ * Flags
+ */
+#define P_BOOL 0x01 /* the option is boolean */
+#define P_NUM 0x02 /* the option is numeric */
+#define P_STRING 0x04 /* the option is a string */
+#define P_ALLOCED 0x08 /* the string option is in allocated memory,
+ must use free_string_option() when
+ assigning new value. Not set if default is
+ the same. */
+#define P_EXPAND 0x10 /* environment expansion. NOTE: P_EXPAND can
+ never be used for local or hidden options! */
+#define P_NODEFAULT 0x40 /* don't set to default value */
+#define P_DEF_ALLOCED 0x80 /* default value is in allocated memory, must
+ use vim_free() when assigning new value */
+#define P_WAS_SET 0x100 /* option has been set/reset */
+#define P_NO_MKRC 0x200 /* don't include in :mkvimrc output */
+#define P_VI_DEF 0x400 /* Use Vi default for Vim */
+#define P_VIM 0x800 /* Vim option, reset when 'cp' set */
+
+/* when option changed, what to display: */
+#define P_RSTAT 0x1000 /* redraw status lines */
+#define P_RWIN 0x2000 /* redraw current window */
+#define P_RBUF 0x4000 /* redraw current buffer */
+#define P_RALL 0x6000 /* redraw all windows */
+#define P_RCLR 0x7000 /* clear and redraw all */
+
+#define P_COMMA 0x8000 /* comma separated list */
+#define P_NODUP 0x10000L /* don't allow duplicate strings */
+#define P_FLAGLIST 0x20000L /* list of single-char flags */
+
+#define P_SECURE 0x40000L /* cannot change in modeline or secure mode */
+#define P_GETTEXT 0x80000L /* expand default value with _() */
+#define P_NOGLOB 0x100000L /* do not use local value for global vimrc */
+#define P_NFNAME 0x200000L /* only normal file name chars allowed */
+#define P_INSECURE 0x400000L /* option was set from a modeline */
+#define P_PRI_MKRC 0x800000L /* priority for :mkvimrc (setting option has
+ side effects) */
+#define P_NO_ML 0x1000000L /* not allowed in modeline */
+#define P_CURSWANT 0x2000000L /* update curswant required; not needed when
+ * there is a redraw flag */
+
+#define ISK_LATIN1 (char_u *)"@,48-57,_,192-255"
+
+/* 'isprint' for latin1 is also used for MS-Windows cp1252, where 0x80 is used
+ * for the currency sign. */
+# define ISP_LATIN1 (char_u *)"@,161-255"
+
+/* The 16 bit MS-DOS version is low on space, make the string as short as
+ * possible when compiling with few features. */
+#if defined(FEAT_DIFF) || defined(FEAT_FOLDING) || defined(FEAT_SPELL) \
+ || defined(FEAT_VERTSPLIT) || defined(FEAT_CLIPBOARD) \
+ || defined(FEAT_INS_EXPAND) || defined(FEAT_SYN_HL) || defined(FEAT_CONCEAL)
+# define HIGHLIGHT_INIT \
+ "8:SpecialKey,@: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,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"
+#else
+# define HIGHLIGHT_INIT \
+ "8:SpecialKey,@:NonText,d:Directory,e:ErrorMsg,i:IncSearch,l:Search,m:MoreMsg,M:ModeMsg,n:LineNr,N:CursorLineNr,r:Question,s:StatusLine,S:StatusLineNC,t:Title,v:Visual,w:WarningMsg,W:WildMenu,>:SignColumn,*:TabLine,#:TabLineSel,_:TabLineFill"
+#endif
+
+/*
+ * options[] is initialized here.
+ * The order of the options MUST be alphabetic for ":set all" and findoption().
+ * All option names MUST start with a lowercase letter (for findoption()).
+ * Exception: "t_" options are at the end.
+ * The options with a NULL variable are 'hidden': a set command for them is
+ * ignored and they are not printed.
+ */
+static struct vimoption
+ options[] =
+{
+ {"aleph", "al", P_NUM|P_VI_DEF|P_CURSWANT,
+ (char_u *)&p_aleph, PV_NONE,
+ {
+ (char_u *)224L,
+ (char_u *)0L
+ } SCRIPTID_INIT},
+ {"antialias", "anti", P_BOOL|P_VI_DEF|P_VIM|P_RCLR,
+ (char_u *)NULL, PV_NONE,
+ {(char_u *)FALSE, (char_u *)FALSE}
+ SCRIPTID_INIT},
+ {"arabic", "arab", P_BOOL|P_VI_DEF|P_VIM|P_CURSWANT,
+ (char_u *)VAR_WIN, PV_ARAB,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"arabicshape", "arshape", P_BOOL|P_VI_DEF|P_VIM|P_RCLR,
+ (char_u *)&p_arshape, PV_NONE,
+ {(char_u *)TRUE, (char_u *)0L} SCRIPTID_INIT},
+ {"allowrevins", "ari", P_BOOL|P_VI_DEF|P_VIM,
+ (char_u *)&p_ari, PV_NONE,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"altkeymap", "akm", P_BOOL|P_VI_DEF,
+ (char_u *)&p_altkeymap, PV_NONE,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"ambiwidth", "ambw", P_STRING|P_VI_DEF|P_RCLR,
+ (char_u *)&p_ambw, PV_NONE,
+ {(char_u *)"single", (char_u *)0L}
+ SCRIPTID_INIT},
+ {"autochdir", "acd", P_BOOL|P_VI_DEF,
+ (char_u *)&p_acd, PV_NONE,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"autoindent", "ai", P_BOOL|P_VI_DEF,
+ (char_u *)&p_ai, PV_AI,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"autoprint", "ap", P_BOOL|P_VI_DEF,
+ (char_u *)NULL, PV_NONE,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"autoread", "ar", P_BOOL|P_VI_DEF,
+ (char_u *)&p_ar, PV_AR,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"autowrite", "aw", P_BOOL|P_VI_DEF,
+ (char_u *)&p_aw, PV_NONE,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"autowriteall","awa", P_BOOL|P_VI_DEF,
+ (char_u *)&p_awa, PV_NONE,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"background", "bg", P_STRING|P_VI_DEF|P_RCLR,
+ (char_u *)&p_bg, PV_NONE,
+ {
+ (char_u *)"light",
+ (char_u *)0L
+ } SCRIPTID_INIT},
+ {"backspace", "bs", P_STRING|P_VI_DEF|P_VIM|P_COMMA|P_NODUP,
+ (char_u *)&p_bs, PV_NONE,
+ {(char_u *)"", (char_u *)0L} SCRIPTID_INIT},
+ {"backup", "bk", P_BOOL|P_VI_DEF|P_VIM,
+ (char_u *)&p_bk, PV_NONE,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"backupcopy", "bkc", P_STRING|P_VIM|P_COMMA|P_NODUP,
+ (char_u *)&p_bkc, PV_NONE,
+#ifdef UNIX
+ {(char_u *)"yes", (char_u *)"auto"}
+#else
+ {(char_u *)"auto", (char_u *)"auto"}
+#endif
+ SCRIPTID_INIT},
+ {"backupdir", "bdir", P_STRING|P_EXPAND|P_VI_DEF|P_COMMA|P_NODUP|P_SECURE,
+ (char_u *)&p_bdir, PV_NONE,
+ {(char_u *)DFLT_BDIR, (char_u *)0L} SCRIPTID_INIT},
+ {"backupext", "bex", P_STRING|P_VI_DEF|P_NFNAME,
+ (char_u *)&p_bex, PV_NONE,
+ {
+ (char_u *)"~",
+ (char_u *)0L
+ } SCRIPTID_INIT},
+ {"backupskip", "bsk", P_STRING|P_VI_DEF|P_COMMA,
+ (char_u *)&p_bsk, PV_NONE,
+ {(char_u *)"", (char_u *)0L}
+ SCRIPTID_INIT},
+ {"beautify", "bf", P_BOOL|P_VI_DEF,
+ (char_u *)NULL, PV_NONE,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"binary", "bin", P_BOOL|P_VI_DEF|P_RSTAT,
+ (char_u *)&p_bin, PV_BIN,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"bioskey", "biosk",P_BOOL|P_VI_DEF,
+ (char_u *)NULL, PV_NONE,
+ {(char_u *)TRUE, (char_u *)0L} SCRIPTID_INIT},
+ {"bomb", NULL, P_BOOL|P_NO_MKRC|P_VI_DEF|P_RSTAT,
+ (char_u *)&p_bomb, PV_BOMB,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"breakat", "brk", P_STRING|P_VI_DEF|P_RALL|P_FLAGLIST,
+ (char_u *)&p_breakat, PV_NONE,
+ {(char_u *)" \t!@*-+;:,./?", (char_u *)0L}
+ SCRIPTID_INIT},
+ {"browsedir", "bsdir",P_STRING|P_VI_DEF,
+ (char_u *)NULL, PV_NONE,
+ {(char_u *)0L, (char_u *)0L}
+ SCRIPTID_INIT},
+ {"bufhidden", "bh", P_STRING|P_ALLOCED|P_VI_DEF|P_NOGLOB,
+ (char_u *)&p_bh, PV_BH,
+ {(char_u *)"", (char_u *)0L}
+ SCRIPTID_INIT},
+ {"buflisted", "bl", P_BOOL|P_VI_DEF|P_NOGLOB,
+ (char_u *)&p_bl, PV_BL,
+ {(char_u *)1L, (char_u *)0L}
+ SCRIPTID_INIT},
+ {"buftype", "bt", P_STRING|P_ALLOCED|P_VI_DEF|P_NOGLOB,
+ (char_u *)&p_bt, PV_BT,
+ {(char_u *)"", (char_u *)0L}
+ SCRIPTID_INIT},
+ {"casemap", "cmp", P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
+ (char_u *)&p_cmp, PV_NONE,
+ {(char_u *)"internal,keepascii", (char_u *)0L}
+ SCRIPTID_INIT},
+ {"cdpath", "cd", P_STRING|P_EXPAND|P_VI_DEF|P_COMMA|P_NODUP,
+ (char_u *)&p_cdpath, PV_NONE,
+ {(char_u *)",,", (char_u *)0L}
+ SCRIPTID_INIT},
+ {"cedit", NULL, P_STRING,
+ (char_u *)&p_cedit, PV_NONE,
+ {(char_u *)"", (char_u *)CTRL_F_STR}
+ SCRIPTID_INIT},
+ {"charconvert", "ccv", P_STRING|P_VI_DEF|P_SECURE,
+ (char_u *)&p_ccv, PV_NONE,
+ {(char_u *)"", (char_u *)0L}
+ SCRIPTID_INIT},
+ {"cindent", "cin", P_BOOL|P_VI_DEF|P_VIM,
+ (char_u *)&p_cin, PV_CIN,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"cinkeys", "cink", P_STRING|P_ALLOCED|P_VI_DEF|P_COMMA|P_NODUP,
+ (char_u *)&p_cink, PV_CINK,
+ {(char_u *)"0{,0},0),:,0#,!^F,o,O,e", (char_u *)0L}
+ SCRIPTID_INIT},
+ {"cinoptions", "cino", P_STRING|P_ALLOCED|P_VI_DEF|P_COMMA|P_NODUP,
+ (char_u *)&p_cino, PV_CINO,
+ {(char_u *)"", (char_u *)0L} SCRIPTID_INIT},
+ {"cinwords", "cinw", P_STRING|P_ALLOCED|P_VI_DEF|P_COMMA|P_NODUP,
+ (char_u *)&p_cinw, PV_CINW,
+ {(char_u *)"if,else,while,do,for,switch",
+ (char_u *)0L}
+ SCRIPTID_INIT},
+ {"clipboard", "cb", P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
+ (char_u *)NULL, PV_NONE,
+ {(char_u *)"", (char_u *)0L}
+ SCRIPTID_INIT},
+ {"cmdheight", "ch", P_NUM|P_VI_DEF|P_RALL,
+ (char_u *)&p_ch, PV_NONE,
+ {(char_u *)1L, (char_u *)0L} SCRIPTID_INIT},
+ {"cmdwinheight", "cwh", P_NUM|P_VI_DEF,
+ (char_u *)&p_cwh, PV_NONE,
+ {(char_u *)7L, (char_u *)0L} SCRIPTID_INIT},
+ {"colorcolumn", "cc", P_STRING|P_VI_DEF|P_COMMA|P_NODUP|P_RWIN,
+ (char_u *)VAR_WIN, PV_CC,
+ {(char_u *)"", (char_u *)0L} SCRIPTID_INIT},
+ {"columns", "co", P_NUM|P_NODEFAULT|P_NO_MKRC|P_VI_DEF|P_RCLR,
+ (char_u *)&Columns, PV_NONE,
+ {(char_u *)80L, (char_u *)0L} SCRIPTID_INIT},
+ {"comments", "com", P_STRING|P_ALLOCED|P_VI_DEF|P_COMMA|P_NODUP|
+ P_CURSWANT,
+ (char_u *)&p_com, PV_COM,
+ {(char_u *)"s1:/*,mb:*,ex:*/,://,b:#,:%,:XCOMM,n:>,fb:-",
+ (char_u *)0L}
+ SCRIPTID_INIT},
+ {"commentstring", "cms", P_STRING|P_ALLOCED|P_VI_DEF|P_CURSWANT,
+ (char_u *)&p_cms, PV_CMS,
+ {(char_u *)"/*%s*/", (char_u *)0L}
+ SCRIPTID_INIT},
+ /* P_PRI_MKRC isn't needed here, optval_default()
+ * always returns TRUE for 'compatible' */
+ {"compatible", "cp", P_BOOL|P_RALL,
+ (char_u *)&p_cp, PV_NONE,
+ {(char_u *)TRUE, (char_u *)FALSE} SCRIPTID_INIT},
+ {"complete", "cpt", P_STRING|P_ALLOCED|P_VI_DEF|P_COMMA|P_NODUP,
+ (char_u *)&p_cpt, PV_CPT,
+ {(char_u *)".,w,b,u,t,i", (char_u *)0L}
+ SCRIPTID_INIT},
+ {"concealcursor","cocu", P_STRING|P_ALLOCED|P_RWIN|P_VI_DEF,
+ (char_u *)VAR_WIN, PV_COCU,
+ {(char_u *)"", (char_u *)NULL}
+ SCRIPTID_INIT},
+ {"conceallevel","cole", P_NUM|P_RWIN|P_VI_DEF,
+ (char_u *)VAR_WIN, PV_COLE,
+ {(char_u *)0L, (char_u *)0L}
+ SCRIPTID_INIT},
+ {"completefunc", "cfu", P_STRING|P_ALLOCED|P_VI_DEF|P_SECURE,
+ (char_u *)&p_cfu, PV_CFU,
+ {(char_u *)"", (char_u *)0L}
+ SCRIPTID_INIT},
+ {"completeopt", "cot", P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
+ (char_u *)&p_cot, PV_NONE,
+ {(char_u *)"menu,preview", (char_u *)0L}
+ SCRIPTID_INIT},
+ {"confirm", "cf", P_BOOL|P_VI_DEF,
+ (char_u *)&p_confirm, PV_NONE,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"conskey", "consk",P_BOOL|P_VI_DEF,
+ (char_u *)NULL, PV_NONE,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"copyindent", "ci", P_BOOL|P_VI_DEF|P_VIM,
+ (char_u *)&p_ci, PV_CI,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"cpoptions", "cpo", P_STRING|P_VIM|P_RALL|P_FLAGLIST,
+ (char_u *)&p_cpo, PV_NONE,
+ {(char_u *)CPO_VI, (char_u *)CPO_VIM}
+ SCRIPTID_INIT},
+ {"cryptmethod", "cm", P_STRING|P_ALLOCED|P_VI_DEF,
+ (char_u *)&p_cm, PV_CM,
+ {(char_u *)"zip", (char_u *)0L}
+ SCRIPTID_INIT},
+ {"cscopepathcomp", "cspc", P_NUM|P_VI_DEF|P_VIM,
+ (char_u *)&p_cspc, PV_NONE,
+ {(char_u *)0L, (char_u *)0L} SCRIPTID_INIT},
+ {"cscopeprg", "csprg", P_STRING|P_EXPAND|P_VI_DEF|P_SECURE,
+ (char_u *)&p_csprg, PV_NONE,
+ {(char_u *)"cscope", (char_u *)0L}
+ SCRIPTID_INIT},
+ {"cscopequickfix", "csqf", P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
+ (char_u *)&p_csqf, PV_NONE,
+ {(char_u *)"", (char_u *)0L}
+ SCRIPTID_INIT},
+ {"cscoperelative", "csre", P_BOOL|P_VI_DEF|P_VIM,
+ (char_u *)&p_csre, PV_NONE,
+ {(char_u *)0L, (char_u *)0L} SCRIPTID_INIT},
+ {"cscopetag", "cst", P_BOOL|P_VI_DEF|P_VIM,
+ (char_u *)&p_cst, PV_NONE,
+ {(char_u *)0L, (char_u *)0L} SCRIPTID_INIT},
+ {"cscopetagorder", "csto", P_NUM|P_VI_DEF|P_VIM,
+ (char_u *)&p_csto, PV_NONE,
+ {(char_u *)0L, (char_u *)0L} SCRIPTID_INIT},
+ {"cscopeverbose", "csverb", P_BOOL|P_VI_DEF|P_VIM,
+ (char_u *)&p_csverbose, PV_NONE,
+ {(char_u *)0L, (char_u *)0L} SCRIPTID_INIT},
+ {"cursorbind", "crb", P_BOOL|P_VI_DEF,
+ (char_u *)VAR_WIN, PV_CRBIND,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"cursorcolumn", "cuc", P_BOOL|P_VI_DEF|P_RWIN,
+ (char_u *)VAR_WIN, PV_CUC,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"cursorline", "cul", P_BOOL|P_VI_DEF|P_RWIN,
+ (char_u *)VAR_WIN, PV_CUL,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"debug", NULL, P_STRING|P_VI_DEF,
+ (char_u *)&p_debug, PV_NONE,
+ {(char_u *)"", (char_u *)0L} SCRIPTID_INIT},
+ {"define", "def", P_STRING|P_ALLOCED|P_VI_DEF|P_CURSWANT,
+ (char_u *)&p_def, PV_DEF,
+ {(char_u *)"^\\s*#\\s*define", (char_u *)0L}
+ SCRIPTID_INIT},
+ {"delcombine", "deco", P_BOOL|P_VI_DEF|P_VIM,
+ (char_u *)&p_deco, PV_NONE,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"dictionary", "dict", P_STRING|P_EXPAND|P_VI_DEF|P_COMMA|P_NODUP,
+ (char_u *)&p_dict, PV_DICT,
+ {(char_u *)"", (char_u *)0L} SCRIPTID_INIT},
+ {"diff", NULL, P_BOOL|P_VI_DEF|P_RWIN|P_NOGLOB,
+ (char_u *)VAR_WIN, PV_DIFF,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"diffexpr", "dex", P_STRING|P_VI_DEF|P_SECURE|P_CURSWANT,
+ (char_u *)&p_dex, PV_NONE,
+ {(char_u *)"", (char_u *)0L}
+ SCRIPTID_INIT},
+ {"diffopt", "dip", P_STRING|P_ALLOCED|P_VI_DEF|P_RWIN|P_COMMA|P_NODUP,
+ (char_u *)&p_dip, PV_NONE,
+ {(char_u *)"filler", (char_u *)NULL}
+ SCRIPTID_INIT},
+ {"digraph", "dg", P_BOOL|P_VI_DEF|P_VIM,
+ (char_u *)&p_dg, PV_NONE,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"directory", "dir", P_STRING|P_EXPAND|P_VI_DEF|P_COMMA|P_NODUP|P_SECURE,
+ (char_u *)&p_dir, PV_NONE,
+ {(char_u *)DFLT_DIR, (char_u *)0L} SCRIPTID_INIT},
+ {"display", "dy", P_STRING|P_VI_DEF|P_COMMA|P_RALL|P_NODUP,
+ (char_u *)&p_dy, PV_NONE,
+ {(char_u *)"", (char_u *)0L} SCRIPTID_INIT},
+ {"eadirection", "ead", P_STRING|P_VI_DEF,
+ (char_u *)&p_ead, PV_NONE,
+ {(char_u *)"both", (char_u *)0L}
+ SCRIPTID_INIT},
+ {"edcompatible","ed", P_BOOL|P_VI_DEF,
+ (char_u *)&p_ed, PV_NONE,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"encoding", "enc", P_STRING|P_VI_DEF|P_RCLR|P_NO_ML,
+ (char_u *)&p_enc, PV_NONE,
+ {(char_u *)ENC_DFLT, (char_u *)0L}
+ SCRIPTID_INIT},
+ {"endofline", "eol", P_BOOL|P_NO_MKRC|P_VI_DEF|P_RSTAT,
+ (char_u *)&p_eol, PV_EOL,
+ {(char_u *)TRUE, (char_u *)0L} SCRIPTID_INIT},
+ {"equalalways", "ea", P_BOOL|P_VI_DEF|P_RALL,
+ (char_u *)&p_ea, PV_NONE,
+ {(char_u *)TRUE, (char_u *)0L} SCRIPTID_INIT},
+ {"equalprg", "ep", P_STRING|P_EXPAND|P_VI_DEF|P_SECURE,
+ (char_u *)&p_ep, PV_EP,
+ {(char_u *)"", (char_u *)0L} SCRIPTID_INIT},
+ {"errorbells", "eb", P_BOOL|P_VI_DEF,
+ (char_u *)&p_eb, PV_NONE,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"errorfile", "ef", P_STRING|P_EXPAND|P_VI_DEF|P_SECURE,
+ (char_u *)&p_ef, PV_NONE,
+ {(char_u *)DFLT_ERRORFILE, (char_u *)0L}
+ SCRIPTID_INIT},
+ {"errorformat", "efm", P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
+ (char_u *)&p_efm, PV_EFM,
+ {(char_u *)DFLT_EFM, (char_u *)0L}
+ SCRIPTID_INIT},
+ {"esckeys", "ek", P_BOOL|P_VIM,
+ (char_u *)&p_ek, PV_NONE,
+ {(char_u *)FALSE, (char_u *)TRUE} SCRIPTID_INIT},
+ {"eventignore", "ei", P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
+ (char_u *)&p_ei, PV_NONE,
+ {(char_u *)"", (char_u *)0L} SCRIPTID_INIT},
+ {"expandtab", "et", P_BOOL|P_VI_DEF|P_VIM,
+ (char_u *)&p_et, PV_ET,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"exrc", "ex", P_BOOL|P_VI_DEF|P_SECURE,
+ (char_u *)&p_exrc, PV_NONE,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"fileencoding","fenc", P_STRING|P_ALLOCED|P_VI_DEF|P_RSTAT|P_RBUF|P_NO_MKRC,
+ (char_u *)&p_fenc, PV_FENC,
+ {(char_u *)"", (char_u *)0L}
+ SCRIPTID_INIT},
+ {"fileencodings","fencs", P_STRING|P_VI_DEF|P_COMMA,
+ (char_u *)&p_fencs, PV_NONE,
+ {(char_u *)"ucs-bom", (char_u *)0L}
+ SCRIPTID_INIT},
+ {"fileformat", "ff", P_STRING|P_ALLOCED|P_VI_DEF|P_RSTAT|P_NO_MKRC|
+ P_CURSWANT,
+ (char_u *)&p_ff, PV_FF,
+ {(char_u *)DFLT_FF, (char_u *)0L} SCRIPTID_INIT},
+ {"fileformats", "ffs", P_STRING|P_VIM|P_COMMA|P_NODUP,
+ (char_u *)&p_ffs, PV_NONE,
+ {(char_u *)DFLT_FFS_VI, (char_u *)DFLT_FFS_VIM}
+ SCRIPTID_INIT},
+ {"fileignorecase", "fic", P_BOOL|P_VI_DEF,
+ (char_u *)&p_fic, PV_NONE,
+ {
+#ifdef CASE_INSENSITIVE_FILENAME
+ (char_u *)TRUE,
+#else
+ (char_u *)FALSE,
+#endif
+ (char_u *)0L
+ } SCRIPTID_INIT},
+ {"filetype", "ft", P_STRING|P_ALLOCED|P_VI_DEF|P_NOGLOB|P_NFNAME,
+ (char_u *)&p_ft, PV_FT,
+ {(char_u *)"", (char_u *)0L}
+ SCRIPTID_INIT},
+ {"fillchars", "fcs", P_STRING|P_VI_DEF|P_RALL|P_COMMA|P_NODUP,
+ (char_u *)&p_fcs, PV_NONE,
+ {(char_u *)"vert:|,fold:-", (char_u *)0L}
+ SCRIPTID_INIT},
+ {"fkmap", "fk", P_BOOL|P_VI_DEF,
+ (char_u *)&p_fkmap, PV_NONE,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"flash", "fl", P_BOOL|P_VI_DEF,
+ (char_u *)NULL, PV_NONE,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"foldclose", "fcl", P_STRING|P_VI_DEF|P_COMMA|P_NODUP|P_RWIN,
+ (char_u *)&p_fcl, PV_NONE,
+ {(char_u *)"", (char_u *)0L} SCRIPTID_INIT},
+ {"foldcolumn", "fdc", P_NUM|P_VI_DEF|P_RWIN,
+ (char_u *)VAR_WIN, PV_FDC,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"foldenable", "fen", P_BOOL|P_VI_DEF|P_RWIN,
+ (char_u *)VAR_WIN, PV_FEN,
+ {(char_u *)TRUE, (char_u *)0L} SCRIPTID_INIT},
+ {"foldexpr", "fde", P_STRING|P_ALLOCED|P_VIM|P_VI_DEF|P_RWIN,
+ (char_u *)VAR_WIN, PV_FDE,
+ {(char_u *)"0", (char_u *)NULL}
+ SCRIPTID_INIT},
+ {"foldignore", "fdi", P_STRING|P_ALLOCED|P_VIM|P_VI_DEF|P_RWIN,
+ (char_u *)VAR_WIN, PV_FDI,
+ {(char_u *)"#", (char_u *)NULL} SCRIPTID_INIT},
+ {"foldlevel", "fdl", P_NUM|P_VI_DEF|P_RWIN,
+ (char_u *)VAR_WIN, PV_FDL,
+ {(char_u *)0L, (char_u *)0L} SCRIPTID_INIT},
+ {"foldlevelstart","fdls", P_NUM|P_VI_DEF|P_CURSWANT,
+ (char_u *)&p_fdls, PV_NONE,
+ {(char_u *)-1L, (char_u *)0L} SCRIPTID_INIT},
+ {"foldmarker", "fmr", P_STRING|P_ALLOCED|P_VIM|P_VI_DEF|
+ P_RWIN|P_COMMA|P_NODUP,
+ (char_u *)VAR_WIN, PV_FMR,
+ {(char_u *)"{{{,}}}", (char_u *)NULL}
+ SCRIPTID_INIT},
+ {"foldmethod", "fdm", P_STRING|P_ALLOCED|P_VIM|P_VI_DEF|P_RWIN,
+ (char_u *)VAR_WIN, PV_FDM,
+ {(char_u *)"manual", (char_u *)NULL} SCRIPTID_INIT},
+ {"foldminlines","fml", P_NUM|P_VI_DEF|P_RWIN,
+ (char_u *)VAR_WIN, PV_FML,
+ {(char_u *)1L, (char_u *)0L} SCRIPTID_INIT},
+ {"foldnestmax", "fdn", P_NUM|P_VI_DEF|P_RWIN,
+ (char_u *)VAR_WIN, PV_FDN,
+ {(char_u *)20L, (char_u *)0L} SCRIPTID_INIT},
+ {"foldopen", "fdo", P_STRING|P_VI_DEF|P_COMMA|P_NODUP|P_CURSWANT,
+ (char_u *)&p_fdo, PV_NONE,
+ {(char_u *)"block,hor,mark,percent,quickfix,search,tag,undo",
+ (char_u *)0L} SCRIPTID_INIT},
+ {"foldtext", "fdt", P_STRING|P_ALLOCED|P_VIM|P_VI_DEF|P_RWIN,
+ (char_u *)VAR_WIN, PV_FDT,
+ {(char_u *)"foldtext()", (char_u *)NULL}
+ SCRIPTID_INIT},
+ {"formatexpr", "fex", P_STRING|P_ALLOCED|P_VI_DEF|P_VIM,
+ (char_u *)&p_fex, PV_FEX,
+ {(char_u *)"", (char_u *)0L}
+ SCRIPTID_INIT},
+ {"formatoptions","fo", P_STRING|P_ALLOCED|P_VIM|P_FLAGLIST,
+ (char_u *)&p_fo, PV_FO,
+ {(char_u *)DFLT_FO_VI, (char_u *)DFLT_FO_VIM}
+ SCRIPTID_INIT},
+ {"formatlistpat","flp", P_STRING|P_ALLOCED|P_VI_DEF,
+ (char_u *)&p_flp, PV_FLP,
+ {(char_u *)"^\\s*\\d\\+[\\]:.)}\\t ]\\s*",
+ (char_u *)0L} SCRIPTID_INIT},
+ {"formatprg", "fp", P_STRING|P_EXPAND|P_VI_DEF|P_SECURE,
+ (char_u *)&p_fp, PV_NONE,
+ {(char_u *)"", (char_u *)0L} SCRIPTID_INIT},
+ {"fsync", "fs", P_BOOL|P_SECURE|P_VI_DEF,
+#ifdef HAVE_FSYNC
+ (char_u *)&p_fs, PV_NONE,
+ {(char_u *)TRUE, (char_u *)0L}
+#else
+ (char_u *)NULL, PV_NONE,
+ {(char_u *)FALSE, (char_u *)0L}
+#endif
+ SCRIPTID_INIT},
+ {"gdefault", "gd", P_BOOL|P_VI_DEF|P_VIM,
+ (char_u *)&p_gd, PV_NONE,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"graphic", "gr", P_BOOL|P_VI_DEF,
+ (char_u *)NULL, PV_NONE,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"grepformat", "gfm", P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
+ (char_u *)&p_gefm, PV_NONE,
+ {(char_u *)DFLT_GREPFORMAT, (char_u *)0L}
+ SCRIPTID_INIT},
+ {"grepprg", "gp", P_STRING|P_EXPAND|P_VI_DEF|P_SECURE,
+ (char_u *)&p_gp, PV_GP,
+ {
+# ifdef UNIX
+ /* Add an extra file name so that grep will always
+ * insert a file name in the match line. */
+ (char_u *)"grep -n $* /dev/null",
+# else
+ (char_u *)"grep -n ",
+# endif
+ (char_u *)0L
+ }
+ SCRIPTID_INIT},
+ {"guicursor", "gcr", P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
+#ifdef CURSOR_SHAPE
+ (char_u *)&p_guicursor, PV_NONE,
+ {
+ (char_u *)"n-v-c:block,o:hor50,i-ci:hor15,r-cr:hor30,sm:block",
+ (char_u *)0L
+ }
+#else
+ (char_u *)NULL, PV_NONE,
+ {(char_u *)NULL, (char_u *)0L}
+#endif
+ SCRIPTID_INIT},
+ {"guifont", "gfn", P_STRING|P_VI_DEF|P_RCLR|P_COMMA|P_NODUP,
+ (char_u *)NULL, PV_NONE,
+ {(char_u *)NULL, (char_u *)0L}
+ SCRIPTID_INIT},
+ {"guifontset", "gfs", P_STRING|P_VI_DEF|P_RCLR|P_COMMA,
+ (char_u *)NULL, PV_NONE,
+ {(char_u *)NULL, (char_u *)0L}
+ SCRIPTID_INIT},
+ {"guifontwide", "gfw", P_STRING|P_VI_DEF|P_RCLR|P_COMMA|P_NODUP,
+ (char_u *)NULL, PV_NONE,
+ {(char_u *)NULL, (char_u *)0L}
+ SCRIPTID_INIT},
+ {"guiheadroom", "ghr", P_NUM|P_VI_DEF,
+ (char_u *)NULL, PV_NONE,
+ {(char_u *)50L, (char_u *)0L} SCRIPTID_INIT},
+ {"guioptions", "go", P_STRING|P_VI_DEF|P_RALL|P_FLAGLIST,
+ (char_u *)NULL, PV_NONE,
+ {(char_u *)NULL, (char_u *)0L}
+ SCRIPTID_INIT},
+ {"guipty", NULL, P_BOOL|P_VI_DEF,
+ (char_u *)NULL, PV_NONE,
+ {(char_u *)TRUE, (char_u *)0L} SCRIPTID_INIT},
+ {"guitablabel", "gtl", P_STRING|P_VI_DEF|P_RWIN,
+ (char_u *)NULL, PV_NONE,
+ {(char_u *)NULL, (char_u *)0L}
+ SCRIPTID_INIT},
+ {"guitabtooltip", "gtt", P_STRING|P_VI_DEF|P_RWIN,
+ (char_u *)NULL, PV_NONE,
+ {(char_u *)NULL, (char_u *)0L}
+ SCRIPTID_INIT},
+ {"hardtabs", "ht", P_NUM|P_VI_DEF,
+ (char_u *)NULL, PV_NONE,
+ {(char_u *)0L, (char_u *)0L} SCRIPTID_INIT},
+ {"helpfile", "hf", P_STRING|P_EXPAND|P_VI_DEF|P_SECURE,
+ (char_u *)&p_hf, PV_NONE,
+ {(char_u *)DFLT_HELPFILE, (char_u *)0L}
+ SCRIPTID_INIT},
+ {"helpheight", "hh", P_NUM|P_VI_DEF,
+ (char_u *)&p_hh, PV_NONE,
+ {(char_u *)20L, (char_u *)0L} SCRIPTID_INIT},
+ {"helplang", "hlg", P_STRING|P_VI_DEF|P_COMMA,
+ (char_u *)&p_hlg, PV_NONE,
+ {(char_u *)"", (char_u *)0L}
+ SCRIPTID_INIT},
+ {"hidden", "hid", P_BOOL|P_VI_DEF,
+ (char_u *)&p_hid, PV_NONE,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"highlight", "hl", P_STRING|P_VI_DEF|P_RCLR|P_COMMA|P_NODUP,
+ (char_u *)&p_hl, PV_NONE,
+ {(char_u *)HIGHLIGHT_INIT, (char_u *)0L}
+ SCRIPTID_INIT},
+ {"history", "hi", P_NUM|P_VIM,
+ (char_u *)&p_hi, PV_NONE,
+ {(char_u *)0L, (char_u *)20L} SCRIPTID_INIT},
+ {"hkmap", "hk", P_BOOL|P_VI_DEF|P_VIM,
+ (char_u *)&p_hkmap, PV_NONE,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"hkmapp", "hkp", P_BOOL|P_VI_DEF|P_VIM,
+ (char_u *)&p_hkmapp, PV_NONE,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"hlsearch", "hls", P_BOOL|P_VI_DEF|P_VIM|P_RALL,
+ (char_u *)&p_hls, PV_NONE,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"icon", NULL, P_BOOL|P_VI_DEF,
+ (char_u *)&p_icon, PV_NONE,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"iconstring", NULL, P_STRING|P_VI_DEF,
+ (char_u *)&p_iconstring, PV_NONE,
+ {(char_u *)"", (char_u *)0L} SCRIPTID_INIT},
+ {"ignorecase", "ic", P_BOOL|P_VI_DEF,
+ (char_u *)&p_ic, PV_NONE,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"imactivatefunc","imaf",P_STRING|P_VI_DEF|P_SECURE,
+ (char_u *)NULL, PV_NONE,
+ {(char_u *)NULL, (char_u *)0L}
+ SCRIPTID_INIT},
+ {"imactivatekey","imak",P_STRING|P_VI_DEF,
+ (char_u *)NULL, PV_NONE,
+ {(char_u *)"", (char_u *)0L} SCRIPTID_INIT},
+ {"imcmdline", "imc", P_BOOL|P_VI_DEF,
+#ifdef USE_IM_CONTROL
+ (char_u *)&p_imcmdline, PV_NONE,
+#else
+ (char_u *)NULL, PV_NONE,
+#endif
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"imdisable", "imd", P_BOOL|P_VI_DEF,
+#ifdef USE_IM_CONTROL
+ (char_u *)&p_imdisable, PV_NONE,
+#else
+ (char_u *)NULL, PV_NONE,
+#endif
+ {(char_u *)FALSE, (char_u *)0L}
+ SCRIPTID_INIT},
+ {"iminsert", "imi", P_NUM|P_VI_DEF,
+ (char_u *)&p_iminsert, PV_IMI,
+#ifdef B_IMODE_IM
+ {(char_u *)B_IMODE_IM, (char_u *)0L}
+#else
+ {(char_u *)B_IMODE_NONE, (char_u *)0L}
+#endif
+ SCRIPTID_INIT},
+ {"imsearch", "ims", P_NUM|P_VI_DEF,
+ (char_u *)&p_imsearch, PV_IMS,
+#ifdef B_IMODE_IM
+ {(char_u *)B_IMODE_IM, (char_u *)0L}
+#else
+ {(char_u *)B_IMODE_NONE, (char_u *)0L}
+#endif
+ SCRIPTID_INIT},
+ {"imstatusfunc","imsf",P_STRING|P_VI_DEF|P_SECURE,
+ (char_u *)NULL, PV_NONE,
+ {(char_u *)NULL, (char_u *)0L}
+ SCRIPTID_INIT},
+ {"include", "inc", P_STRING|P_ALLOCED|P_VI_DEF,
+ (char_u *)&p_inc, PV_INC,
+ {(char_u *)"^\\s*#\\s*include", (char_u *)0L}
+ SCRIPTID_INIT},
+ {"includeexpr", "inex", P_STRING|P_ALLOCED|P_VI_DEF,
+ (char_u *)&p_inex, PV_INEX,
+ {(char_u *)"", (char_u *)0L}
+ SCRIPTID_INIT},
+ {"incsearch", "is", P_BOOL|P_VI_DEF|P_VIM,
+ (char_u *)&p_is, PV_NONE,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"indentexpr", "inde", P_STRING|P_ALLOCED|P_VI_DEF|P_VIM,
+ (char_u *)&p_inde, PV_INDE,
+ {(char_u *)"", (char_u *)0L}
+ SCRIPTID_INIT},
+ {"indentkeys", "indk", P_STRING|P_ALLOCED|P_VI_DEF|P_COMMA|P_NODUP,
+ (char_u *)&p_indk, PV_INDK,
+ {(char_u *)"0{,0},:,0#,!^F,o,O,e", (char_u *)0L}
+ SCRIPTID_INIT},
+ {"infercase", "inf", P_BOOL|P_VI_DEF,
+ (char_u *)&p_inf, PV_INF,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"insertmode", "im", P_BOOL|P_VI_DEF|P_VIM,
+ (char_u *)&p_im, PV_NONE,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"isfname", "isf", P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
+ (char_u *)&p_isf, PV_NONE,
+ {
+#ifdef BACKSLASH_IN_FILENAME
+ /* Excluded are: & and ^ are special in cmd.exe
+ * ( and ) are used in text separating fnames */
+ (char_u *)"@,48-57,/,\\,.,-,_,+,,,#,$,%,{,},[,],:,@-@,!,~,=",
+#else
+ (char_u *)"@,48-57,/,.,-,_,+,,,#,$,%,~,=",
+#endif
+ (char_u *)0L
+ } SCRIPTID_INIT},
+ {"isident", "isi", P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
+ (char_u *)&p_isi, PV_NONE,
+ {
+ (char_u *)"@,48-57,_,192-255",
+ (char_u *)0L
+ } SCRIPTID_INIT},
+ {"iskeyword", "isk", P_STRING|P_ALLOCED|P_VIM|P_COMMA|P_NODUP,
+ (char_u *)&p_isk, PV_ISK,
+ {
+ (char_u *)"@,48-57,_",
+ ISK_LATIN1
+ } SCRIPTID_INIT},
+ {"isprint", "isp", P_STRING|P_VI_DEF|P_RALL|P_COMMA|P_NODUP,
+ (char_u *)&p_isp, PV_NONE,
+ {
+#if defined(MSDOS) || defined(MSWIN) || defined(OS2) \
+ || (defined(MACOS) && !defined(MACOS_X)) \
+ || defined(VMS)
+ (char_u *)"@,~-255",
+#else
+ ISP_LATIN1,
+#endif
+ (char_u *)0L
+ } SCRIPTID_INIT},
+ {"joinspaces", "js", P_BOOL|P_VI_DEF|P_VIM,
+ (char_u *)&p_js, PV_NONE,
+ {(char_u *)TRUE, (char_u *)0L} SCRIPTID_INIT},
+ {"key", NULL, P_STRING|P_ALLOCED|P_VI_DEF|P_NO_MKRC,
+ (char_u *)&p_key, PV_KEY,
+ {(char_u *)"", (char_u *)0L}
+ SCRIPTID_INIT},
+ {"keymap", "kmp", P_STRING|P_ALLOCED|P_VI_DEF|P_RBUF|P_RSTAT|P_NFNAME|
+ P_PRI_MKRC,
+ (char_u *)&p_keymap, PV_KMAP,
+ {(char_u *)"", (char_u *)0L}
+ SCRIPTID_INIT},
+ {"keymodel", "km", P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
+ (char_u *)&p_km, PV_NONE,
+ {(char_u *)"", (char_u *)0L} SCRIPTID_INIT},
+ {"keywordprg", "kp", P_STRING|P_EXPAND|P_VI_DEF|P_SECURE,
+ (char_u *)&p_kp, PV_KP,
+ {
+# ifdef USEMAN_S
+ (char_u *)"man -s",
+# else
+ (char_u *)"man",
+# endif
+ (char_u *)0L
+ } SCRIPTID_INIT},
+ {"langmap", "lmap", P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
+ (char_u *)&p_langmap, PV_NONE,
+ {(char_u *)"", /* unmatched } */
+ (char_u *)0L} SCRIPTID_INIT},
+ {"langmenu", "lm", P_STRING|P_VI_DEF|P_NFNAME,
+ (char_u *)&p_lm, PV_NONE,
+ {(char_u *)"", (char_u *)0L} SCRIPTID_INIT},
+ {"laststatus", "ls", P_NUM|P_VI_DEF|P_RALL,
+ (char_u *)&p_ls, PV_NONE,
+ {(char_u *)1L, (char_u *)0L} SCRIPTID_INIT},
+ {"lazyredraw", "lz", P_BOOL|P_VI_DEF,
+ (char_u *)&p_lz, PV_NONE,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"linebreak", "lbr", P_BOOL|P_VI_DEF|P_RWIN,
+ (char_u *)VAR_WIN, PV_LBR,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"lines", NULL, P_NUM|P_NODEFAULT|P_NO_MKRC|P_VI_DEF|P_RCLR,
+ (char_u *)&Rows, PV_NONE,
+ {
+ (char_u *)24L,
+ (char_u *)0L
+ } SCRIPTID_INIT},
+ {"linespace", "lsp", P_NUM|P_VI_DEF|P_RCLR,
+ (char_u *)NULL, PV_NONE,
+ {(char_u *)0L, (char_u *)0L}
+ SCRIPTID_INIT},
+ {"lisp", NULL, P_BOOL|P_VI_DEF,
+ (char_u *)&p_lisp, PV_LISP,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"lispwords", "lw", P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
+ (char_u *)&p_lispwords, PV_NONE,
+ {(char_u *)LISPWORD_VALUE, (char_u *)0L}
+ SCRIPTID_INIT},
+ {"list", NULL, P_BOOL|P_VI_DEF|P_RWIN,
+ (char_u *)VAR_WIN, PV_LIST,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"listchars", "lcs", P_STRING|P_VI_DEF|P_RALL|P_COMMA|P_NODUP,
+ (char_u *)&p_lcs, PV_NONE,
+ {(char_u *)"eol:$", (char_u *)0L} SCRIPTID_INIT},
+ {"loadplugins", "lpl", P_BOOL|P_VI_DEF,
+ (char_u *)&p_lpl, PV_NONE,
+ {(char_u *)TRUE, (char_u *)0L} SCRIPTID_INIT},
+ {"magic", NULL, P_BOOL|P_VI_DEF,
+ (char_u *)&p_magic, PV_NONE,
+ {(char_u *)TRUE, (char_u *)0L} SCRIPTID_INIT},
+ {"makeef", "mef", P_STRING|P_EXPAND|P_VI_DEF|P_SECURE,
+ (char_u *)&p_mef, PV_NONE,
+ {(char_u *)"", (char_u *)0L}
+ SCRIPTID_INIT},
+ {"makeprg", "mp", P_STRING|P_EXPAND|P_VI_DEF|P_SECURE,
+ (char_u *)&p_mp, PV_MP,
+ {(char_u *)"make", (char_u *)0L}
+ SCRIPTID_INIT},
+ {"matchpairs", "mps", P_STRING|P_ALLOCED|P_VI_DEF|P_COMMA|P_NODUP,
+ (char_u *)&p_mps, PV_MPS,
+ {(char_u *)"(:),{:},[:]", (char_u *)0L}
+ SCRIPTID_INIT},
+ {"matchtime", "mat", P_NUM|P_VI_DEF,
+ (char_u *)&p_mat, PV_NONE,
+ {(char_u *)5L, (char_u *)0L} SCRIPTID_INIT},
+ {"maxcombine", "mco", P_NUM|P_VI_DEF|P_CURSWANT,
+ (char_u *)&p_mco, PV_NONE,
+ {(char_u *)2, (char_u *)0L} SCRIPTID_INIT},
+ {"maxfuncdepth", "mfd", P_NUM|P_VI_DEF,
+ (char_u *)&p_mfd, PV_NONE,
+ {(char_u *)100L, (char_u *)0L} SCRIPTID_INIT},
+ {"maxmapdepth", "mmd", P_NUM|P_VI_DEF,
+ (char_u *)&p_mmd, PV_NONE,
+ {(char_u *)1000L, (char_u *)0L} SCRIPTID_INIT},
+ {"maxmem", "mm", P_NUM|P_VI_DEF,
+ (char_u *)&p_mm, PV_NONE,
+ {(char_u *)DFLT_MAXMEM, (char_u *)0L}
+ SCRIPTID_INIT},
+ {"maxmempattern","mmp", P_NUM|P_VI_DEF,
+ (char_u *)&p_mmp, PV_NONE,
+ {(char_u *)1000L, (char_u *)0L} SCRIPTID_INIT},
+ {"maxmemtot", "mmt", P_NUM|P_VI_DEF,
+ (char_u *)&p_mmt, PV_NONE,
+ {(char_u *)DFLT_MAXMEMTOT, (char_u *)0L}
+ SCRIPTID_INIT},
+ {"menuitems", "mis", P_NUM|P_VI_DEF,
+ (char_u *)&p_mis, PV_NONE,
+ {(char_u *)25L, (char_u *)0L} SCRIPTID_INIT},
+ {"mesg", NULL, P_BOOL|P_VI_DEF,
+ (char_u *)NULL, PV_NONE,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"mkspellmem", "msm", P_STRING|P_VI_DEF|P_EXPAND|P_SECURE,
+ (char_u *)&p_msm, PV_NONE,
+ {(char_u *)"460000,2000,500", (char_u *)0L}
+ SCRIPTID_INIT},
+ {"modeline", "ml", P_BOOL|P_VIM,
+ (char_u *)&p_ml, PV_ML,
+ {(char_u *)FALSE, (char_u *)TRUE} SCRIPTID_INIT},
+ {"modelines", "mls", P_NUM|P_VI_DEF,
+ (char_u *)&p_mls, PV_NONE,
+ {(char_u *)5L, (char_u *)0L} SCRIPTID_INIT},
+ {"modifiable", "ma", P_BOOL|P_VI_DEF|P_NOGLOB,
+ (char_u *)&p_ma, PV_MA,
+ {(char_u *)TRUE, (char_u *)0L} SCRIPTID_INIT},
+ {"modified", "mod", P_BOOL|P_NO_MKRC|P_VI_DEF|P_RSTAT,
+ (char_u *)&p_mod, PV_MOD,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"more", NULL, P_BOOL|P_VIM,
+ (char_u *)&p_more, PV_NONE,
+ {(char_u *)FALSE, (char_u *)TRUE} SCRIPTID_INIT},
+ {"mouse", NULL, P_STRING|P_VI_DEF|P_FLAGLIST,
+ (char_u *)&p_mouse, PV_NONE,
+ {
+ (char_u *)"",
+ (char_u *)0L
+ } SCRIPTID_INIT},
+ {"mousefocus", "mousef", P_BOOL|P_VI_DEF,
+ (char_u *)NULL, PV_NONE,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"mousehide", "mh", P_BOOL|P_VI_DEF,
+ (char_u *)NULL, PV_NONE,
+ {(char_u *)TRUE, (char_u *)0L} SCRIPTID_INIT},
+ {"mousemodel", "mousem", P_STRING|P_VI_DEF,
+ (char_u *)&p_mousem, PV_NONE,
+ {
+ (char_u *)"extend",
+ (char_u *)0L
+ } SCRIPTID_INIT},
+ {"mouseshape", "mouses", P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
+ (char_u *)NULL, PV_NONE,
+ {(char_u *)NULL, (char_u *)0L}
+ SCRIPTID_INIT},
+ {"mousetime", "mouset", P_NUM|P_VI_DEF,
+ (char_u *)&p_mouset, PV_NONE,
+ {(char_u *)500L, (char_u *)0L} SCRIPTID_INIT},
+ {"mzquantum", "mzq", P_NUM,
+ (char_u *)NULL, PV_NONE,
+ {(char_u *)100L, (char_u *)100L} SCRIPTID_INIT},
+ {"novice", NULL, P_BOOL|P_VI_DEF,
+ (char_u *)NULL, PV_NONE,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"nrformats", "nf", P_STRING|P_ALLOCED|P_VI_DEF|P_COMMA|P_NODUP,
+ (char_u *)&p_nf, PV_NF,
+ {(char_u *)"octal,hex", (char_u *)0L}
+ SCRIPTID_INIT},
+ {"number", "nu", P_BOOL|P_VI_DEF|P_RWIN,
+ (char_u *)VAR_WIN, PV_NU,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"numberwidth", "nuw", P_NUM|P_RWIN|P_VIM,
+ (char_u *)VAR_WIN, PV_NUW,
+ {(char_u *)8L, (char_u *)4L} SCRIPTID_INIT},
+ {"omnifunc", "ofu", P_STRING|P_ALLOCED|P_VI_DEF|P_SECURE,
+ (char_u *)&p_ofu, PV_OFU,
+ {(char_u *)"", (char_u *)0L}
+ SCRIPTID_INIT},
+ {"open", NULL, P_BOOL|P_VI_DEF,
+ (char_u *)NULL, PV_NONE,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"opendevice", "odev", P_BOOL|P_VI_DEF,
+ (char_u *)NULL, PV_NONE,
+ {(char_u *)FALSE, (char_u *)FALSE}
+ SCRIPTID_INIT},
+ {"operatorfunc", "opfunc", P_STRING|P_VI_DEF|P_SECURE,
+ (char_u *)&p_opfunc, PV_NONE,
+ {(char_u *)"", (char_u *)0L} SCRIPTID_INIT},
+ {"optimize", "opt", P_BOOL|P_VI_DEF,
+ (char_u *)NULL, PV_NONE,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"osfiletype", "oft", P_STRING|P_ALLOCED|P_VI_DEF,
+ (char_u *)NULL, PV_NONE,
+ {(char_u *)0L, (char_u *)0L} SCRIPTID_INIT},
+ {"paragraphs", "para", P_STRING|P_VI_DEF,
+ (char_u *)&p_para, PV_NONE,
+ {(char_u *)"IPLPPPQPP TPHPLIPpLpItpplpipbp",
+ (char_u *)0L} SCRIPTID_INIT},
+ {"paste", NULL, P_BOOL|P_VI_DEF|P_PRI_MKRC,
+ (char_u *)&p_paste, PV_NONE,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"pastetoggle", "pt", P_STRING|P_VI_DEF,
+ (char_u *)&p_pt, PV_NONE,
+ {(char_u *)"", (char_u *)0L} SCRIPTID_INIT},
+ {"patchexpr", "pex", P_STRING|P_VI_DEF|P_SECURE,
+ (char_u *)&p_pex, PV_NONE,
+ {(char_u *)"", (char_u *)0L}
+ SCRIPTID_INIT},
+ {"patchmode", "pm", P_STRING|P_VI_DEF|P_NFNAME,
+ (char_u *)&p_pm, PV_NONE,
+ {(char_u *)"", (char_u *)0L} SCRIPTID_INIT},
+ {"path", "pa", P_STRING|P_EXPAND|P_VI_DEF|P_COMMA|P_NODUP,
+ (char_u *)&p_path, PV_PATH,
+ {
+ (char_u *)".,/usr/include,,",
+ (char_u *)0L
+ } SCRIPTID_INIT},
+ {"preserveindent", "pi", P_BOOL|P_VI_DEF|P_VIM,
+ (char_u *)&p_pi, PV_PI,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"previewheight", "pvh", P_NUM|P_VI_DEF,
+ (char_u *)&p_pvh, PV_NONE,
+ {(char_u *)12L, (char_u *)0L} SCRIPTID_INIT},
+ {"previewwindow", "pvw", P_BOOL|P_VI_DEF|P_RSTAT|P_NOGLOB,
+ (char_u *)VAR_WIN, PV_PVW,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"printdevice", "pdev", P_STRING|P_VI_DEF|P_SECURE,
+ (char_u *)&p_pdev, PV_NONE,
+ {(char_u *)"", (char_u *)0L}
+ SCRIPTID_INIT},
+ {"printencoding", "penc", P_STRING|P_VI_DEF,
+ (char_u *)&p_penc, PV_NONE,
+ {(char_u *)"", (char_u *)0L}
+ SCRIPTID_INIT},
+ {"printexpr", "pexpr", P_STRING|P_VI_DEF,
+ (char_u *)&p_pexpr, PV_NONE,
+ {(char_u *)"", (char_u *)0L}
+ SCRIPTID_INIT},
+ {"printfont", "pfn", P_STRING|P_VI_DEF,
+ (char_u *)&p_pfn, PV_NONE,
+ {
+ (char_u *)"courier",
+ (char_u *)0L
+ }
+ SCRIPTID_INIT},
+ {"printheader", "pheader", P_STRING|P_VI_DEF|P_GETTEXT,
+ (char_u *)&p_header, PV_NONE,
+ {(char_u *)N_("%<%f%h%m%=Page %N"), (char_u *)0L}
+ SCRIPTID_INIT},
+ {"printmbcharset", "pmbcs", P_STRING|P_VI_DEF,
+ (char_u *)&p_pmcs, PV_NONE,
+ {(char_u *)"", (char_u *)0L}
+ SCRIPTID_INIT},
+ {"printmbfont", "pmbfn", P_STRING|P_VI_DEF,
+ (char_u *)&p_pmfn, PV_NONE,
+ {(char_u *)"", (char_u *)0L}
+ SCRIPTID_INIT},
+ {"printoptions", "popt", P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
+ (char_u *)&p_popt, PV_NONE,
+ {(char_u *)"", (char_u *)0L}
+ SCRIPTID_INIT},
+ {"prompt", NULL, P_BOOL|P_VI_DEF,
+ (char_u *)&p_prompt, PV_NONE,
+ {(char_u *)TRUE, (char_u *)0L} SCRIPTID_INIT},
+ {"pumheight", "ph", P_NUM|P_VI_DEF,
+ (char_u *)&p_ph, PV_NONE,
+ {(char_u *)0L, (char_u *)0L} SCRIPTID_INIT},
+ {"quoteescape", "qe", P_STRING|P_ALLOCED|P_VI_DEF,
+ (char_u *)&p_qe, PV_QE,
+ {(char_u *)"\\", (char_u *)0L}
+ SCRIPTID_INIT},
+ {"readonly", "ro", P_BOOL|P_VI_DEF|P_RSTAT|P_NOGLOB,
+ (char_u *)&p_ro, PV_RO,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"redraw", NULL, P_BOOL|P_VI_DEF,
+ (char_u *)NULL, PV_NONE,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"redrawtime", "rdt", P_NUM|P_VI_DEF,
+ (char_u *)&p_rdt, PV_NONE,
+ {(char_u *)2000L, (char_u *)0L} SCRIPTID_INIT},
+ {"regexpengine", "re", P_NUM|P_VI_DEF,
+ (char_u *)&p_re, PV_NONE,
+ {(char_u *)0L, (char_u *)0L} SCRIPTID_INIT},
+ {"relativenumber", "rnu", P_BOOL|P_VI_DEF|P_RWIN,
+ (char_u *)VAR_WIN, PV_RNU,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"remap", NULL, P_BOOL|P_VI_DEF,
+ (char_u *)&p_remap, PV_NONE,
+ {(char_u *)TRUE, (char_u *)0L} SCRIPTID_INIT},
+ {"report", NULL, P_NUM|P_VI_DEF,
+ (char_u *)&p_report, PV_NONE,
+ {(char_u *)2L, (char_u *)0L} SCRIPTID_INIT},
+ {"restorescreen", "rs", P_BOOL|P_VI_DEF,
+ (char_u *)NULL, PV_NONE,
+ {(char_u *)TRUE, (char_u *)0L} SCRIPTID_INIT},
+ {"revins", "ri", P_BOOL|P_VI_DEF|P_VIM,
+ (char_u *)&p_ri, PV_NONE,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"rightleft", "rl", P_BOOL|P_VI_DEF|P_RWIN,
+ (char_u *)VAR_WIN, PV_RL,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"rightleftcmd", "rlc", P_STRING|P_ALLOCED|P_VI_DEF|P_RWIN,
+ (char_u *)VAR_WIN, PV_RLC,
+ {(char_u *)"search", (char_u *)NULL}
+ SCRIPTID_INIT},
+ {"ruler", "ru", P_BOOL|P_VI_DEF|P_VIM|P_RSTAT,
+ (char_u *)&p_ru, PV_NONE,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"rulerformat", "ruf", P_STRING|P_VI_DEF|P_ALLOCED|P_RSTAT,
+ (char_u *)&p_ruf, PV_NONE,
+ {(char_u *)"", (char_u *)0L} SCRIPTID_INIT},
+ {"runtimepath", "rtp", P_STRING|P_VI_DEF|P_EXPAND|P_COMMA|P_NODUP|P_SECURE,
+ (char_u *)&p_rtp, PV_NONE,
+ {(char_u *)DFLT_RUNTIMEPATH, (char_u *)0L}
+ SCRIPTID_INIT},
+ {"scroll", "scr", P_NUM|P_NO_MKRC|P_VI_DEF,
+ (char_u *)VAR_WIN, PV_SCROLL,
+ {(char_u *)12L, (char_u *)0L} SCRIPTID_INIT},
+ {"scrollbind", "scb", P_BOOL|P_VI_DEF,
+ (char_u *)VAR_WIN, PV_SCBIND,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"scrolljump", "sj", P_NUM|P_VI_DEF|P_VIM,
+ (char_u *)&p_sj, PV_NONE,
+ {(char_u *)1L, (char_u *)0L} SCRIPTID_INIT},
+ {"scrolloff", "so", P_NUM|P_VI_DEF|P_VIM|P_RALL,
+ (char_u *)&p_so, PV_NONE,
+ {(char_u *)0L, (char_u *)0L} SCRIPTID_INIT},
+ {"scrollopt", "sbo", P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
+ (char_u *)&p_sbo, PV_NONE,
+ {(char_u *)"ver,jump", (char_u *)0L}
+ SCRIPTID_INIT},
+ {"sections", "sect", P_STRING|P_VI_DEF,
+ (char_u *)&p_sections, PV_NONE,
+ {(char_u *)"SHNHH HUnhsh", (char_u *)0L}
+ SCRIPTID_INIT},
+ {"secure", NULL, P_BOOL|P_VI_DEF|P_SECURE,
+ (char_u *)&p_secure, PV_NONE,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"selection", "sel", P_STRING|P_VI_DEF,
+ (char_u *)&p_sel, PV_NONE,
+ {(char_u *)"inclusive", (char_u *)0L}
+ SCRIPTID_INIT},
+ {"selectmode", "slm", P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
+ (char_u *)&p_slm, PV_NONE,
+ {(char_u *)"", (char_u *)0L} SCRIPTID_INIT},
+ {"sessionoptions", "ssop", P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
+ (char_u *)&p_ssop, PV_NONE,
+ {(char_u *)"blank,buffers,curdir,folds,help,options,tabpages,winsize",
+ (char_u *)0L}
+ SCRIPTID_INIT},
+ {"shell", "sh", P_STRING|P_EXPAND|P_VI_DEF|P_SECURE,
+ (char_u *)&p_sh, PV_NONE,
+ {
+# if defined(ARCHIE)
+ (char_u *)"gos",
+# else
+ (char_u *)"sh",
+# endif
+ (char_u *)0L
+ } SCRIPTID_INIT},
+ {"shellcmdflag","shcf", P_STRING|P_VI_DEF|P_SECURE,
+ (char_u *)&p_shcf, PV_NONE,
+ {
+ (char_u *)"-c",
+ (char_u *)0L
+ } SCRIPTID_INIT},
+ {"shellpipe", "sp", P_STRING|P_VI_DEF|P_SECURE,
+ (char_u *)&p_sp, PV_NONE,
+ {
+#if defined(UNIX) || defined(OS2)
+# ifdef ARCHIE
+ (char_u *)"2>",
+# else
+ (char_u *)"| tee",
+# endif
+#else
+ (char_u *)">",
+#endif
+ (char_u *)0L
+ }
+ SCRIPTID_INIT},
+ {"shellquote", "shq", P_STRING|P_VI_DEF|P_SECURE,
+ (char_u *)&p_shq, PV_NONE,
+ {(char_u *)"", (char_u *)0L} SCRIPTID_INIT},
+ {"shellredir", "srr", P_STRING|P_VI_DEF|P_SECURE,
+ (char_u *)&p_srr, PV_NONE,
+ {(char_u *)">", (char_u *)0L} SCRIPTID_INIT},
+ {"shellslash", "ssl", P_BOOL|P_VI_DEF,
+#ifdef BACKSLASH_IN_FILENAME
+ (char_u *)&p_ssl, PV_NONE,
+#else
+ (char_u *)NULL, PV_NONE,
+#endif
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"shelltemp", "stmp", P_BOOL,
+ (char_u *)&p_stmp, PV_NONE,
+ {(char_u *)FALSE, (char_u *)TRUE} SCRIPTID_INIT},
+ {"shelltype", "st", P_NUM|P_VI_DEF,
+ (char_u *)NULL, PV_NONE,
+ {(char_u *)0L, (char_u *)0L} SCRIPTID_INIT},
+ {"shellxquote", "sxq", P_STRING|P_VI_DEF|P_SECURE,
+ (char_u *)&p_sxq, PV_NONE,
+ {
+#if defined(UNIX) && defined(USE_SYSTEM) && !defined(__EMX__)
+ (char_u *)"\"",
+#else
+ (char_u *)"",
+#endif
+ (char_u *)0L
+ } SCRIPTID_INIT},
+ {"shellxescape", "sxe", P_STRING|P_VI_DEF|P_SECURE,
+ (char_u *)&p_sxe, PV_NONE,
+ {
+ (char_u *)"",
+ (char_u *)0L
+ } SCRIPTID_INIT},
+ {"shiftround", "sr", P_BOOL|P_VI_DEF|P_VIM,
+ (char_u *)&p_sr, PV_NONE,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"shiftwidth", "sw", P_NUM|P_VI_DEF,
+ (char_u *)&p_sw, PV_SW,
+ {(char_u *)8L, (char_u *)0L} SCRIPTID_INIT},
+ {"shortmess", "shm", P_STRING|P_VIM|P_FLAGLIST,
+ (char_u *)&p_shm, PV_NONE,
+ {(char_u *)"", (char_u *)"filnxtToO"}
+ SCRIPTID_INIT},
+ {"shortname", "sn", P_BOOL|P_VI_DEF,
+#ifdef SHORT_FNAME
+ (char_u *)NULL, PV_NONE,
+#else
+ (char_u *)&p_sn, PV_SN,
+#endif
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"showbreak", "sbr", P_STRING|P_VI_DEF|P_RALL,
+ (char_u *)&p_sbr, PV_NONE,
+ {(char_u *)"", (char_u *)0L} SCRIPTID_INIT},
+ {"showcmd", "sc", P_BOOL|P_VIM,
+ (char_u *)&p_sc, PV_NONE,
+ {(char_u *)FALSE,
+#ifdef UNIX
+ (char_u *)FALSE
+#else
+ (char_u *) TRUE
+#endif
+ } SCRIPTID_INIT},
+ {"showfulltag", "sft", P_BOOL|P_VI_DEF,
+ (char_u *)&p_sft, PV_NONE,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"showmatch", "sm", P_BOOL|P_VI_DEF,
+ (char_u *)&p_sm, PV_NONE,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"showmode", "smd", P_BOOL|P_VIM,
+ (char_u *)&p_smd, PV_NONE,
+ {(char_u *)FALSE, (char_u *)TRUE} SCRIPTID_INIT},
+ {"showtabline", "stal", P_NUM|P_VI_DEF|P_RALL,
+ (char_u *)&p_stal, PV_NONE,
+ {(char_u *)1L, (char_u *)0L} SCRIPTID_INIT},
+ {"sidescroll", "ss", P_NUM|P_VI_DEF,
+ (char_u *)&p_ss, PV_NONE,
+ {(char_u *)0L, (char_u *)0L} SCRIPTID_INIT},
+ {"sidescrolloff", "siso", P_NUM|P_VI_DEF|P_VIM|P_RBUF,
+ (char_u *)&p_siso, PV_NONE,
+ {(char_u *)0L, (char_u *)0L} SCRIPTID_INIT},
+ {"slowopen", "slow", P_BOOL|P_VI_DEF,
+ (char_u *)NULL, PV_NONE,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"smartcase", "scs", P_BOOL|P_VI_DEF|P_VIM,
+ (char_u *)&p_scs, PV_NONE,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"smartindent", "si", P_BOOL|P_VI_DEF|P_VIM,
+ (char_u *)&p_si, PV_SI,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"smarttab", "sta", P_BOOL|P_VI_DEF|P_VIM,
+ (char_u *)&p_sta, PV_NONE,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"softtabstop", "sts", P_NUM|P_VI_DEF|P_VIM,
+ (char_u *)&p_sts, PV_STS,
+ {(char_u *)0L, (char_u *)0L} SCRIPTID_INIT},
+ {"sourceany", NULL, P_BOOL|P_VI_DEF,
+ (char_u *)NULL, PV_NONE,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"spell", NULL, P_BOOL|P_VI_DEF|P_RWIN,
+ (char_u *)VAR_WIN, PV_SPELL,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"spellcapcheck", "spc", P_STRING|P_ALLOCED|P_VI_DEF|P_RBUF,
+ (char_u *)&p_spc, PV_SPC,
+ {(char_u *)"[.?!]\\_[\\])'\" ]\\+", (char_u *)0L}
+ SCRIPTID_INIT},
+ {"spellfile", "spf", P_STRING|P_EXPAND|P_ALLOCED|P_VI_DEF|P_SECURE|P_COMMA,
+ (char_u *)&p_spf, PV_SPF,
+ {(char_u *)"", (char_u *)0L}
+ SCRIPTID_INIT},
+ {"spelllang", "spl", P_STRING|P_ALLOCED|P_VI_DEF|P_COMMA|P_RBUF|P_EXPAND,
+ (char_u *)&p_spl, PV_SPL,
+ {(char_u *)"en", (char_u *)0L}
+ SCRIPTID_INIT},
+ {"spellsuggest", "sps", P_STRING|P_VI_DEF|P_EXPAND|P_SECURE|P_COMMA,
+ (char_u *)&p_sps, PV_NONE,
+ {(char_u *)"best", (char_u *)0L}
+ SCRIPTID_INIT},
+ {"splitbelow", "sb", P_BOOL|P_VI_DEF,
+ (char_u *)&p_sb, PV_NONE,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"splitright", "spr", P_BOOL|P_VI_DEF,
+ (char_u *)&p_spr, PV_NONE,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"startofline", "sol", P_BOOL|P_VI_DEF|P_VIM,
+ (char_u *)&p_sol, PV_NONE,
+ {(char_u *)TRUE, (char_u *)0L} SCRIPTID_INIT},
+ {"statusline","stl", P_STRING|P_VI_DEF|P_ALLOCED|P_RSTAT,
+ (char_u *)&p_stl, PV_STL,
+ {(char_u *)"", (char_u *)0L} SCRIPTID_INIT},
+ {"suffixes", "su", P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
+ (char_u *)&p_su, PV_NONE,
+ {(char_u *)".bak,~,.o,.h,.info,.swp,.obj",
+ (char_u *)0L} SCRIPTID_INIT},
+ {"suffixesadd", "sua", P_STRING|P_VI_DEF|P_ALLOCED|P_COMMA|P_NODUP,
+ (char_u *)&p_sua, PV_SUA,
+ {(char_u *)"", (char_u *)0L}
+ SCRIPTID_INIT},
+ {"swapfile", "swf", P_BOOL|P_VI_DEF|P_RSTAT,
+ (char_u *)&p_swf, PV_SWF,
+ {(char_u *)TRUE, (char_u *)0L} SCRIPTID_INIT},
+ {"swapsync", "sws", P_STRING|P_VI_DEF,
+ (char_u *)&p_sws, PV_NONE,
+ {(char_u *)"fsync", (char_u *)0L} SCRIPTID_INIT},
+ {"switchbuf", "swb", P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
+ (char_u *)&p_swb, PV_NONE,
+ {(char_u *)"", (char_u *)0L} SCRIPTID_INIT},
+ {"synmaxcol", "smc", P_NUM|P_VI_DEF|P_RBUF,
+ (char_u *)&p_smc, PV_SMC,
+ {(char_u *)3000L, (char_u *)0L}
+ SCRIPTID_INIT},
+ {"syntax", "syn", P_STRING|P_ALLOCED|P_VI_DEF|P_NOGLOB|P_NFNAME,
+ (char_u *)&p_syn, PV_SYN,
+ {(char_u *)"", (char_u *)0L}
+ SCRIPTID_INIT},
+ {"tabline", "tal", P_STRING|P_VI_DEF|P_RALL,
+ (char_u *)&p_tal, PV_NONE,
+ {(char_u *)"", (char_u *)0L} SCRIPTID_INIT},
+ {"tabpagemax", "tpm", P_NUM|P_VI_DEF,
+ (char_u *)&p_tpm, PV_NONE,
+ {(char_u *)10L, (char_u *)0L} SCRIPTID_INIT},
+ {"tabstop", "ts", P_NUM|P_VI_DEF|P_RBUF,
+ (char_u *)&p_ts, PV_TS,
+ {(char_u *)8L, (char_u *)0L} SCRIPTID_INIT},
+ {"tagbsearch", "tbs", P_BOOL|P_VI_DEF,
+ (char_u *)&p_tbs, PV_NONE,
+ {(char_u *)TRUE, (char_u *)0L}
+ SCRIPTID_INIT},
+ {"taglength", "tl", P_NUM|P_VI_DEF,
+ (char_u *)&p_tl, PV_NONE,
+ {(char_u *)0L, (char_u *)0L} SCRIPTID_INIT},
+ {"tagrelative", "tr", P_BOOL|P_VIM,
+ (char_u *)&p_tr, PV_NONE,
+ {(char_u *)FALSE, (char_u *)TRUE} SCRIPTID_INIT},
+ {"tags", "tag", P_STRING|P_EXPAND|P_VI_DEF|P_COMMA|P_NODUP,
+ (char_u *)&p_tags, PV_TAGS,
+ {
+ (char_u *)"./tags,tags",
+ (char_u *)0L
+ } SCRIPTID_INIT},
+ {"tagstack", "tgst", P_BOOL|P_VI_DEF,
+ (char_u *)&p_tgst, PV_NONE,
+ {(char_u *)TRUE, (char_u *)0L} SCRIPTID_INIT},
+ {"term", NULL, P_STRING|P_EXPAND|P_NODEFAULT|P_NO_MKRC|P_VI_DEF|
+ P_RALL,
+ (char_u *)&T_NAME, PV_NONE,
+ {(char_u *)"", (char_u *)0L} SCRIPTID_INIT},
+ {"termbidi", "tbidi", P_BOOL|P_VI_DEF,
+ (char_u *)&p_tbidi, PV_NONE,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"termencoding", "tenc", P_STRING|P_VI_DEF|P_RCLR,
+ (char_u *)&p_tenc, PV_NONE,
+ {(char_u *)"", (char_u *)0L}
+ SCRIPTID_INIT},
+ {"terse", NULL, P_BOOL|P_VI_DEF,
+ (char_u *)&p_terse, PV_NONE,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"textauto", "ta", P_BOOL|P_VIM,
+ (char_u *)&p_ta, PV_NONE,
+ {(char_u *)DFLT_TEXTAUTO, (char_u *)TRUE}
+ SCRIPTID_INIT},
+ {"textmode", "tx", P_BOOL|P_VI_DEF|P_NO_MKRC,
+ (char_u *)&p_tx, PV_TX,
+ {
+#ifdef USE_CRNL
+ (char_u *)TRUE,
+#else
+ (char_u *)FALSE,
+#endif
+ (char_u *)0L
+ } SCRIPTID_INIT},
+ {"textwidth", "tw", P_NUM|P_VI_DEF|P_VIM|P_RBUF,
+ (char_u *)&p_tw, PV_TW,
+ {(char_u *)0L, (char_u *)0L} SCRIPTID_INIT},
+ {"thesaurus", "tsr", P_STRING|P_EXPAND|P_VI_DEF|P_COMMA|P_NODUP,
+ (char_u *)&p_tsr, PV_TSR,
+ {(char_u *)"", (char_u *)0L} SCRIPTID_INIT},
+ {"tildeop", "top", P_BOOL|P_VI_DEF|P_VIM,
+ (char_u *)&p_to, PV_NONE,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"timeout", "to", P_BOOL|P_VI_DEF,
+ (char_u *)&p_timeout, PV_NONE,
+ {(char_u *)TRUE, (char_u *)0L} SCRIPTID_INIT},
+ {"timeoutlen", "tm", P_NUM|P_VI_DEF,
+ (char_u *)&p_tm, PV_NONE,
+ {(char_u *)1000L, (char_u *)0L} SCRIPTID_INIT},
+ {"title", NULL, P_BOOL|P_VI_DEF,
+ (char_u *)&p_title, PV_NONE,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"titlelen", NULL, P_NUM|P_VI_DEF,
+ (char_u *)&p_titlelen, PV_NONE,
+ {(char_u *)85L, (char_u *)0L} SCRIPTID_INIT},
+ {"titleold", NULL, P_STRING|P_VI_DEF|P_GETTEXT|P_SECURE|P_NO_MKRC,
+ (char_u *)&p_titleold, PV_NONE,
+ {(char_u *)N_("Thanks for flying Vim"),
+ (char_u *)0L}
+ SCRIPTID_INIT},
+ {"titlestring", NULL, P_STRING|P_VI_DEF,
+ (char_u *)&p_titlestring, PV_NONE,
+ {(char_u *)"", (char_u *)0L} SCRIPTID_INIT},
+ {"ttimeout", NULL, P_BOOL|P_VI_DEF|P_VIM,
+ (char_u *)&p_ttimeout, PV_NONE,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"ttimeoutlen", "ttm", P_NUM|P_VI_DEF,
+ (char_u *)&p_ttm, PV_NONE,
+ {(char_u *)-1L, (char_u *)0L} SCRIPTID_INIT},
+ {"ttybuiltin", "tbi", P_BOOL|P_VI_DEF,
+ (char_u *)&p_tbi, PV_NONE,
+ {(char_u *)TRUE, (char_u *)0L} SCRIPTID_INIT},
+ {"ttyfast", "tf", P_BOOL|P_NO_MKRC|P_VI_DEF,
+ (char_u *)&p_tf, PV_NONE,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"ttymouse", "ttym", P_STRING|P_NODEFAULT|P_NO_MKRC|P_VI_DEF,
+#if defined(FEAT_MOUSE) && (defined(UNIX) || defined(VMS))
+ (char_u *)&p_ttym, PV_NONE,
+#else
+ (char_u *)NULL, PV_NONE,
+#endif
+ {(char_u *)"", (char_u *)0L} SCRIPTID_INIT},
+ {"ttyscroll", "tsl", P_NUM|P_VI_DEF,
+ (char_u *)&p_ttyscroll, PV_NONE,
+ {(char_u *)999L, (char_u *)0L} SCRIPTID_INIT},
+ {"ttytype", "tty", P_STRING|P_EXPAND|P_NODEFAULT|P_NO_MKRC|P_VI_DEF|
+ P_RALL,
+ (char_u *)&T_NAME, PV_NONE,
+ {(char_u *)"", (char_u *)0L} SCRIPTID_INIT},
+ {"undodir", "udir", P_STRING|P_EXPAND|P_COMMA|P_NODUP|P_SECURE|P_VI_DEF,
+ (char_u *)&p_udir, PV_NONE,
+ {(char_u *)".", (char_u *)0L}
+ SCRIPTID_INIT},
+ {"undofile", "udf", P_BOOL|P_VI_DEF|P_VIM,
+ (char_u *)&p_udf, PV_UDF,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"undolevels", "ul", P_NUM|P_VI_DEF,
+ (char_u *)&p_ul, PV_UL,
+ {
+#if defined(UNIX) || defined(WIN3264) || defined(OS2) || defined(VMS)
+ (char_u *)1000L,
+#else
+ (char_u *)100L,
+#endif
+ (char_u *)0L
+ } SCRIPTID_INIT},
+ {"undoreload", "ur", P_NUM|P_VI_DEF,
+ (char_u *)&p_ur, PV_NONE,
+ { (char_u *)10000L, (char_u *)0L} SCRIPTID_INIT},
+ {"updatecount", "uc", P_NUM|P_VI_DEF,
+ (char_u *)&p_uc, PV_NONE,
+ {(char_u *)200L, (char_u *)0L} SCRIPTID_INIT},
+ {"updatetime", "ut", P_NUM|P_VI_DEF,
+ (char_u *)&p_ut, PV_NONE,
+ {(char_u *)4000L, (char_u *)0L} SCRIPTID_INIT},
+ {"verbose", "vbs", P_NUM|P_VI_DEF,
+ (char_u *)&p_verbose, PV_NONE,
+ {(char_u *)0L, (char_u *)0L} SCRIPTID_INIT},
+ {"verbosefile", "vfile", P_STRING|P_EXPAND|P_VI_DEF|P_SECURE,
+ (char_u *)&p_vfile, PV_NONE,
+ {(char_u *)"", (char_u *)0L} SCRIPTID_INIT},
+ {"viewdir", "vdir", P_STRING|P_EXPAND|P_VI_DEF|P_SECURE,
+ (char_u *)&p_vdir, PV_NONE,
+ {(char_u *)DFLT_VDIR, (char_u *)0L}
+ SCRIPTID_INIT},
+ {"viewoptions", "vop", P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
+ (char_u *)&p_vop, PV_NONE,
+ {(char_u *)"folds,options,cursor", (char_u *)0L}
+ SCRIPTID_INIT},
+ {"viminfo", "vi", P_STRING|P_COMMA|P_NODUP|P_SECURE,
+ (char_u *)&p_viminfo, PV_NONE,
+ {(char_u *)"", (char_u *)"'100,<50,s10,h"}
+ SCRIPTID_INIT},
+ {"virtualedit", "ve", P_STRING|P_COMMA|P_NODUP|P_VI_DEF|P_VIM|P_CURSWANT,
+ (char_u *)&p_ve, PV_NONE,
+ {(char_u *)"", (char_u *)""}
+ SCRIPTID_INIT},
+ {"visualbell", "vb", P_BOOL|P_VI_DEF,
+ (char_u *)&p_vb, PV_NONE,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"w300", NULL, P_NUM|P_VI_DEF,
+ (char_u *)NULL, PV_NONE,
+ {(char_u *)0L, (char_u *)0L} SCRIPTID_INIT},
+ {"w1200", NULL, P_NUM|P_VI_DEF,
+ (char_u *)NULL, PV_NONE,
+ {(char_u *)0L, (char_u *)0L} SCRIPTID_INIT},
+ {"w9600", NULL, P_NUM|P_VI_DEF,
+ (char_u *)NULL, PV_NONE,
+ {(char_u *)0L, (char_u *)0L} SCRIPTID_INIT},
+ {"warn", NULL, P_BOOL|P_VI_DEF,
+ (char_u *)&p_warn, PV_NONE,
+ {(char_u *)TRUE, (char_u *)0L} SCRIPTID_INIT},
+ {"weirdinvert", "wiv", P_BOOL|P_VI_DEF|P_RCLR,
+ (char_u *)&p_wiv, PV_NONE,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"whichwrap", "ww", P_STRING|P_VIM|P_COMMA|P_FLAGLIST,
+ (char_u *)&p_ww, PV_NONE,
+ {(char_u *)"", (char_u *)"b,s"} SCRIPTID_INIT},
+ {"wildchar", "wc", P_NUM|P_VIM,
+ (char_u *)&p_wc, PV_NONE,
+ {(char_u *)(long)Ctrl_E, (char_u *)(long)TAB}
+ SCRIPTID_INIT},
+ {"wildcharm", "wcm", P_NUM|P_VI_DEF,
+ (char_u *)&p_wcm, PV_NONE,
+ {(char_u *)0L, (char_u *)0L} SCRIPTID_INIT},
+ {"wildignore", "wig", P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
+ (char_u *)&p_wig, PV_NONE,
+ {(char_u *)"", (char_u *)0L} SCRIPTID_INIT},
+ {"wildignorecase", "wic", P_BOOL|P_VI_DEF,
+ (char_u *)&p_wic, PV_NONE,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"wildmenu", "wmnu", P_BOOL|P_VI_DEF,
+ (char_u *)&p_wmnu, PV_NONE,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"wildmode", "wim", P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
+ (char_u *)&p_wim, PV_NONE,
+ {(char_u *)"full", (char_u *)0L} SCRIPTID_INIT},
+ {"wildoptions", "wop", P_STRING|P_VI_DEF,
+ (char_u *)&p_wop, PV_NONE,
+ {(char_u *)"", (char_u *)0L}
+ SCRIPTID_INIT},
+ {"winaltkeys", "wak", P_STRING|P_VI_DEF,
+ (char_u *)&p_wak, PV_NONE,
+ {(char_u *)"menu", (char_u *)0L}
+ SCRIPTID_INIT},
+ {"window", "wi", P_NUM|P_VI_DEF,
+ (char_u *)&p_window, PV_NONE,
+ {(char_u *)0L, (char_u *)0L} SCRIPTID_INIT},
+ {"winheight", "wh", P_NUM|P_VI_DEF,
+ (char_u *)&p_wh, PV_NONE,
+ {(char_u *)1L, (char_u *)0L} SCRIPTID_INIT},
+ {"winfixheight", "wfh", P_BOOL|P_VI_DEF|P_RSTAT,
+ (char_u *)VAR_WIN, PV_WFH,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"winfixwidth", "wfw", P_BOOL|P_VI_DEF|P_RSTAT,
+ (char_u *)VAR_WIN, PV_WFW,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"winminheight", "wmh", P_NUM|P_VI_DEF,
+ (char_u *)&p_wmh, PV_NONE,
+ {(char_u *)1L, (char_u *)0L} SCRIPTID_INIT},
+ {"winminwidth", "wmw", P_NUM|P_VI_DEF,
+ (char_u *)&p_wmw, PV_NONE,
+ {(char_u *)1L, (char_u *)0L} SCRIPTID_INIT},
+ {"winwidth", "wiw", P_NUM|P_VI_DEF,
+ (char_u *)&p_wiw, PV_NONE,
+ {(char_u *)20L, (char_u *)0L} SCRIPTID_INIT},
+ {"wrap", NULL, P_BOOL|P_VI_DEF|P_RWIN,
+ (char_u *)VAR_WIN, PV_WRAP,
+ {(char_u *)TRUE, (char_u *)0L} SCRIPTID_INIT},
+ {"wrapmargin", "wm", P_NUM|P_VI_DEF,
+ (char_u *)&p_wm, PV_WM,
+ {(char_u *)0L, (char_u *)0L} SCRIPTID_INIT},
+ {"wrapscan", "ws", P_BOOL|P_VI_DEF,
+ (char_u *)&p_ws, PV_NONE,
+ {(char_u *)TRUE, (char_u *)0L} SCRIPTID_INIT},
+ {"write", NULL, P_BOOL|P_VI_DEF,
+ (char_u *)&p_write, PV_NONE,
+ {(char_u *)TRUE, (char_u *)0L} SCRIPTID_INIT},
+ {"writeany", "wa", P_BOOL|P_VI_DEF,
+ (char_u *)&p_wa, PV_NONE,
+ {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+ {"writebackup", "wb", P_BOOL|P_VI_DEF|P_VIM,
+ (char_u *)&p_wb, PV_NONE,
+ {
+ (char_u *)TRUE,
+ (char_u *)0L
+ } SCRIPTID_INIT},
+ {"writedelay", "wd", P_NUM|P_VI_DEF,
+ (char_u *)&p_wd, PV_NONE,
+ {(char_u *)0L, (char_u *)0L} SCRIPTID_INIT},
+
+ /* terminal output codes */
+#define p_term(sss, vvv) {sss, NULL, P_STRING|P_VI_DEF|P_RALL|P_SECURE, \
+ (char_u *)&vvv, PV_NONE, \
+ {(char_u *)"", (char_u *)0L} SCRIPTID_INIT},
+
+ p_term("t_AB", T_CAB)
+ p_term("t_AF", T_CAF)
+ p_term("t_AL", T_CAL)
+ p_term("t_al", T_AL)
+ p_term("t_bc", T_BC)
+ p_term("t_cd", T_CD)
+ p_term("t_ce", T_CE)
+ p_term("t_cl", T_CL)
+ p_term("t_cm", T_CM)
+ p_term("t_Co", T_CCO)
+ p_term("t_CS", T_CCS)
+ p_term("t_cs", T_CS)
+ p_term("t_CV", T_CSV)
+ p_term("t_ut", T_UT)
+ p_term("t_da", T_DA)
+ p_term("t_db", T_DB)
+ p_term("t_DL", T_CDL)
+ p_term("t_dl", T_DL)
+ p_term("t_fs", T_FS)
+ p_term("t_IE", T_CIE)
+ p_term("t_IS", T_CIS)
+ p_term("t_ke", T_KE)
+ p_term("t_ks", T_KS)
+ p_term("t_le", T_LE)
+ p_term("t_mb", T_MB)
+ p_term("t_md", T_MD)
+ p_term("t_me", T_ME)
+ p_term("t_mr", T_MR)
+ p_term("t_ms", T_MS)
+ p_term("t_nd", T_ND)
+ p_term("t_op", T_OP)
+ p_term("t_RI", T_CRI)
+ p_term("t_RV", T_CRV)
+ p_term("t_u7", T_U7)
+ p_term("t_Sb", T_CSB)
+ p_term("t_Sf", T_CSF)
+ p_term("t_se", T_SE)
+ p_term("t_so", T_SO)
+ p_term("t_sr", T_SR)
+ p_term("t_ts", T_TS)
+ p_term("t_te", T_TE)
+ p_term("t_ti", T_TI)
+ p_term("t_ue", T_UE)
+ p_term("t_us", T_US)
+ p_term("t_vb", T_VB)
+ p_term("t_ve", T_VE)
+ p_term("t_vi", T_VI)
+ p_term("t_vs", T_VS)
+ p_term("t_WP", T_CWP)
+ p_term("t_WS", T_CWS)
+ p_term("t_SI", T_CSI)
+ p_term("t_EI", T_CEI)
+ p_term("t_xs", T_XS)
+ p_term("t_ZH", T_CZH)
+ p_term("t_ZR", T_CZR)
+
+ /* terminal key codes are not in here */
+
+ /* end marker */
+ {
+ NULL, NULL, 0, NULL, PV_NONE, {NULL, NULL} SCRIPTID_INIT
+ }
+};
+
+#define PARAM_COUNT (sizeof(options) / sizeof(struct vimoption))
+
+static char *(p_ambw_values[]) = {"single", "double", NULL};
+static char *(p_bg_values[]) = {"light", "dark", NULL};
+static char *(p_nf_values[]) = {"octal", "hex", "alpha", NULL};
+static char *(p_ff_values[]) = {FF_UNIX, FF_DOS, FF_MAC, NULL};
+static char *(p_cm_values[]) = {"zip", "blowfish", NULL};
+static char *(p_wop_values[]) = {"tagfile", NULL};
+static char *(p_wak_values[]) = {"yes", "menu", "no", NULL};
+static char *(p_mousem_values[]) =
+{"extend", "popup", "popup_setpos", "mac", NULL};
+static char *(p_sel_values[]) = {"inclusive", "exclusive", "old", NULL};
+static char *(p_slm_values[]) = {"mouse", "key", "cmd", NULL};
+static char *(p_km_values[]) = {"startsel", "stopsel", NULL};
+static char *(p_scbopt_values[]) = {"ver", "hor", "jump", NULL};
+static char *(p_debug_values[]) = {"msg", "throw", "beep", NULL};
+static char *(p_ead_values[]) = {"both", "ver", "hor", NULL};
+static char *(p_buftype_values[]) =
+{"nofile", "nowrite", "quickfix", "help", "acwrite", NULL};
+static char *(p_bufhidden_values[]) = {"hide", "unload", "delete", "wipe", NULL};
+static char *(p_bs_values[]) = {"indent", "eol", "start", NULL};
+static char *(p_fdm_values[]) = {"manual", "expr", "marker", "indent", "syntax",
+ "diff",
+ NULL};
+static char *(p_fcl_values[]) = {"all", NULL};
+static char *(p_cot_values[]) = {"menu", "menuone", "longest", "preview", NULL};
+
+static void set_option_default __ARGS((int, int opt_flags, int compatible));
+static void set_options_default __ARGS((int opt_flags));
+static char_u *term_bg_default __ARGS((void));
+static void did_set_option __ARGS((int opt_idx, int opt_flags, int new_value));
+static char_u *illegal_char __ARGS((char_u *, int));
+static int string_to_key __ARGS((char_u *arg));
+static char_u *check_cedit __ARGS((void));
+static void did_set_title __ARGS((int icon));
+static char_u *option_expand __ARGS((int opt_idx, char_u *val));
+static void didset_options __ARGS((void));
+static void check_string_option __ARGS((char_u **pp));
+static long_u *insecure_flag __ARGS((int opt_idx, int opt_flags));
+static void set_string_option_global __ARGS((int opt_idx, char_u **varp));
+static char_u *set_string_option __ARGS((int opt_idx, char_u *value,
+ int opt_flags));
+static char_u *did_set_string_option __ARGS((int opt_idx, char_u **varp,
+ int new_value_alloced, char_u *
+ oldval, char_u *errbuf,
+ int opt_flags));
+static char_u *set_chars_option __ARGS((char_u **varp));
+static int int_cmp __ARGS((const void *a, const void *b));
+static char_u *compile_cap_prog __ARGS((synblock_T *synblock));
+static void set_option_scriptID_idx __ARGS((int opt_idx, int opt_flags, int id));
+static char_u *set_bool_option __ARGS((int opt_idx, char_u *varp, int value,
+ int opt_flags));
+static char_u *set_num_option __ARGS((int opt_idx, char_u *varp, long value,
+ char_u *errbuf, size_t errbuflen,
+ int opt_flags));
+static void check_redraw __ARGS((long_u flags));
+static int findoption __ARGS((char_u *));
+static int find_key_option __ARGS((char_u *));
+static void showoptions __ARGS((int all, int opt_flags));
+static int optval_default __ARGS((struct vimoption *, char_u *varp));
+static void showoneopt __ARGS((struct vimoption *, int opt_flags));
+static int put_setstring __ARGS((FILE *fd, char *cmd, char *name, char_u *
+ *valuep,
+ int expand));
+static int put_setnum __ARGS((FILE *fd, char *cmd, char *name, long *valuep));
+static int put_setbool __ARGS((FILE *fd, char *cmd, char *name, int value));
+static int istermoption __ARGS((struct vimoption *));
+static char_u *get_varp_scope __ARGS((struct vimoption *p, int opt_flags));
+static char_u *get_varp __ARGS((struct vimoption *));
+static void option_value2string __ARGS((struct vimoption *, int opt_flags));
+static int wc_use_keyname __ARGS((char_u *varp, long *wcp));
+static void langmap_init __ARGS((void));
+static void langmap_set __ARGS((void));
+static void paste_option_changed __ARGS((void));
+static void compatible_set __ARGS((void));
+static void fill_breakat_flags __ARGS((void));
+static int opt_strings_flags __ARGS((char_u *val, char **values,
+ unsigned *flagp,
+ int list));
+static int check_opt_strings __ARGS((char_u *val, char **values, int));
+static int check_opt_wim __ARGS((void));
+
+/*
+ * Initialize the options, first part.
+ *
+ * Called only once from main(), just after creating the first buffer.
+ */
+void set_init_1() {
+ char_u *p;
+ int opt_idx;
+ long_u n;
+
+ langmap_init();
+
+ /* Be Vi compatible by default */
+ p_cp = TRUE;
+
+ /* Use POSIX compatibility when $VIM_POSIX is set. */
+ if (mch_getenv((char_u *)"VIM_POSIX") != NULL) {
+ set_string_default("cpo", (char_u *)CPO_ALL);
+ set_string_default("shm", (char_u *)"A");
+ }
+
+ /*
+ * Find default value for 'shell' option.
+ * Don't use it if it is empty.
+ */
+ if (((p = mch_getenv((char_u *)"SHELL")) != NULL && *p != NUL)
+ )
+ set_string_default("sh", p);
+
+ /*
+ * Set the default for 'backupskip' to include environment variables for
+ * temp files.
+ */
+ {
+# ifdef UNIX
+ static char *(names[4]) = {"", "TMPDIR", "TEMP", "TMP"};
+# else
+ static char *(names[3]) = {"TMPDIR", "TEMP", "TMP"};
+# endif
+ int len;
+ garray_T ga;
+ int mustfree;
+
+ ga_init2(&ga, 1, 100);
+ for (n = 0; n < (long)(sizeof(names) / sizeof(char *)); ++n) {
+ mustfree = FALSE;
+# ifdef UNIX
+ if (*names[n] == NUL)
+ p = (char_u *)"/tmp";
+ else
+# endif
+ p = vim_getenv((char_u *)names[n], &mustfree);
+ if (p != NULL && *p != NUL) {
+ /* First time count the NUL, otherwise count the ','. */
+ len = (int)STRLEN(p) + 3;
+ if (ga_grow(&ga, len) == OK) {
+ if (ga.ga_len > 0)
+ STRCAT(ga.ga_data, ",");
+ STRCAT(ga.ga_data, p);
+ add_pathsep(ga.ga_data);
+ STRCAT(ga.ga_data, "*");
+ ga.ga_len += len;
+ }
+ }
+ if (mustfree)
+ vim_free(p);
+ }
+ if (ga.ga_data != NULL) {
+ set_string_default("bsk", ga.ga_data);
+ vim_free(ga.ga_data);
+ }
+ }
+
+ /*
+ * 'maxmemtot' and 'maxmem' may have to be adjusted for available memory
+ */
+ opt_idx = findoption((char_u *)"maxmemtot");
+ if (opt_idx >= 0) {
+#if !defined(HAVE_AVAIL_MEM) && !defined(HAVE_TOTAL_MEM)
+ if (options[opt_idx].def_val[VI_DEFAULT] == (char_u *)0L)
+#endif
+ {
+#ifdef HAVE_AVAIL_MEM
+ /* Use amount of memory available at this moment. */
+ n = (mch_avail_mem(FALSE) >> 1);
+#else
+# ifdef HAVE_TOTAL_MEM
+ /* Use amount of memory available to Vim. */
+ n = (mch_total_mem(FALSE) >> 1);
+# else
+ n = (0x7fffffff >> 11);
+# endif
+#endif
+ options[opt_idx].def_val[VI_DEFAULT] = (char_u *)n;
+ opt_idx = findoption((char_u *)"maxmem");
+ if (opt_idx >= 0) {
+#if !defined(HAVE_AVAIL_MEM) && !defined(HAVE_TOTAL_MEM)
+ if ((long)options[opt_idx].def_val[VI_DEFAULT] > (long)n
+ || (long)options[opt_idx].def_val[VI_DEFAULT] == 0L)
+#endif
+ options[opt_idx].def_val[VI_DEFAULT] = (char_u *)n;
+ }
+ }
+ }
+
+
+ {
+ char_u *cdpath;
+ char_u *buf;
+ int i;
+ int j;
+ int mustfree = FALSE;
+
+ /* Initialize the 'cdpath' option's default value. */
+ cdpath = vim_getenv((char_u *)"CDPATH", &mustfree);
+ if (cdpath != NULL) {
+ buf = alloc((unsigned)((STRLEN(cdpath) << 1) + 2));
+ if (buf != NULL) {
+ buf[0] = ','; /* start with ",", current dir first */
+ j = 1;
+ for (i = 0; cdpath[i] != NUL; ++i) {
+ if (vim_ispathlistsep(cdpath[i]))
+ buf[j++] = ',';
+ else {
+ if (cdpath[i] == ' ' || cdpath[i] == ',')
+ buf[j++] = '\\';
+ buf[j++] = cdpath[i];
+ }
+ }
+ buf[j] = NUL;
+ opt_idx = findoption((char_u *)"cdpath");
+ if (opt_idx >= 0) {
+ options[opt_idx].def_val[VI_DEFAULT] = buf;
+ options[opt_idx].flags |= P_DEF_ALLOCED;
+ } else
+ vim_free(buf); /* cannot happen */
+ }
+ if (mustfree)
+ vim_free(cdpath);
+ }
+ }
+
+#if defined(FEAT_POSTSCRIPT) && (defined(MSWIN) || defined(OS2) || \
+ defined(VMS) || defined(EBCDIC) || defined(MAC) || defined(hpux))
+ /* Set print encoding on platforms that don't default to latin1 */
+ set_string_default("penc",
+ (char_u *)"hp-roman8"
+ );
+#endif
+
+ /* 'printexpr' must be allocated to be able to evaluate it. */
+ set_string_default(
+ "pexpr",
+ (char_u *)
+ "system('lpr' . (&printdevice == '' ? '' : ' -P' . &printdevice) . ' ' . v:fname_in) . delete(v:fname_in) + v:shell_error"
+ );
+
+ /*
+ * Set all the options (except the terminal options) to their default
+ * value. Also set the global value for local options.
+ */
+ set_options_default(0);
+
+
+ curbuf->b_p_initialized = TRUE;
+ curbuf->b_p_ar = -1; /* no local 'autoread' value */
+ curbuf->b_p_ul = NO_LOCAL_UNDOLEVEL;
+ check_buf_options(curbuf);
+ check_win_options(curwin);
+ check_options();
+
+ /* Must be before option_expand(), because that one needs vim_isIDc() */
+ didset_options();
+
+ /* Use the current chartab for the generic chartab. */
+ init_spell_chartab();
+
+ /*
+ * initialize the table for 'breakat'.
+ */
+ fill_breakat_flags();
+
+ /*
+ * Expand environment variables and things like "~" for the defaults.
+ * If option_expand() returns non-NULL the variable is expanded. This can
+ * only happen for non-indirect options.
+ * Also set the default to the expanded value, so ":set" does not list
+ * them.
+ * Don't set the P_ALLOCED flag, because we don't want to free the
+ * default.
+ */
+ for (opt_idx = 0; !istermoption(&options[opt_idx]); opt_idx++) {
+ if ((options[opt_idx].flags & P_GETTEXT)
+ && options[opt_idx].var != NULL)
+ p = (char_u *)_(*(char **)options[opt_idx].var);
+ else
+ p = option_expand(opt_idx, NULL);
+ if (p != NULL && (p = vim_strsave(p)) != NULL) {
+ *(char_u **)options[opt_idx].var = p;
+ /* VIMEXP
+ * Defaults for all expanded options are currently the same for Vi
+ * and Vim. When this changes, add some code here! Also need to
+ * split P_DEF_ALLOCED in two.
+ */
+ if (options[opt_idx].flags & P_DEF_ALLOCED)
+ vim_free(options[opt_idx].def_val[VI_DEFAULT]);
+ options[opt_idx].def_val[VI_DEFAULT] = p;
+ options[opt_idx].flags |= P_DEF_ALLOCED;
+ }
+ }
+
+ /* Initialize the highlight_attr[] table. */
+ highlight_changed();
+
+ save_file_ff(curbuf); /* Buffer is unchanged */
+
+ /* Parse default for 'wildmode' */
+ check_opt_wim();
+
+ /* Detect use of mlterm.
+ * Mlterm is a terminal emulator akin to xterm that has some special
+ * abilities (bidi namely).
+ * NOTE: mlterm's author is being asked to 'set' a variable
+ * instead of an environment variable due to inheritance.
+ */
+ if (mch_getenv((char_u *)"MLTERM") != NULL)
+ set_option_value((char_u *)"tbidi", 1L, NULL, 0);
+
+ /* Parse default for 'fillchars'. */
+ (void)set_chars_option(&p_fcs);
+
+
+# ifdef MACOS_CONVERT
+ /* Moved to os_mac_conv.c to avoid dependency problems. */
+ mac_lang_init();
+# endif
+
+ /* enc_locale() will try to find the encoding of the current locale. */
+ p = enc_locale();
+ if (p != NULL) {
+ char_u *save_enc;
+
+ /* Try setting 'encoding' and check if the value is valid.
+ * If not, go back to the default "latin1". */
+ save_enc = p_enc;
+ p_enc = p;
+ if (STRCMP(p_enc, "gb18030") == 0) {
+ /* We don't support "gb18030", but "cp936" is a good substitute
+ * for practical purposes, thus use that. It's not an alias to
+ * still support conversion between gb18030 and utf-8. */
+ p_enc = vim_strsave((char_u *)"cp936");
+ vim_free(p);
+ }
+ if (mb_init() == NULL) {
+ opt_idx = findoption((char_u *)"encoding");
+ if (opt_idx >= 0) {
+ options[opt_idx].def_val[VI_DEFAULT] = p_enc;
+ options[opt_idx].flags |= P_DEF_ALLOCED;
+ }
+
+#if defined(MSDOS) || defined(MSWIN) || defined(OS2) || defined(MACOS) \
+ || defined(VMS)
+ if (STRCMP(p_enc, "latin1") == 0
+ || enc_utf8
+ ) {
+ /* Adjust the default for 'isprint' and 'iskeyword' to match
+ * latin1. Also set the defaults for when 'nocompatible' is
+ * set. */
+ set_string_option_direct((char_u *)"isp", -1,
+ ISP_LATIN1, OPT_FREE, SID_NONE);
+ set_string_option_direct((char_u *)"isk", -1,
+ ISK_LATIN1, OPT_FREE, SID_NONE);
+ opt_idx = findoption((char_u *)"isp");
+ if (opt_idx >= 0)
+ options[opt_idx].def_val[VIM_DEFAULT] = ISP_LATIN1;
+ opt_idx = findoption((char_u *)"isk");
+ if (opt_idx >= 0)
+ options[opt_idx].def_val[VIM_DEFAULT] = ISK_LATIN1;
+ (void)init_chartab();
+ }
+#endif
+
+ } else {
+ vim_free(p_enc);
+ p_enc = save_enc;
+ }
+ }
+
+ /* Set the default for 'helplang'. */
+ set_helplang_default(get_mess_lang());
+}
+
+/*
+ * Set an option to its default value.
+ * This does not take care of side effects!
+ */
+static void set_option_default(opt_idx, opt_flags, compatible)
+int opt_idx;
+int opt_flags; /* OPT_FREE, OPT_LOCAL and/or OPT_GLOBAL */
+int compatible; /* use Vi default value */
+{
+ char_u *varp; /* pointer to variable for current option */
+ int dvi; /* index in def_val[] */
+ long_u flags;
+ long_u *flagsp;
+ int both = (opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0;
+
+ varp = get_varp_scope(&(options[opt_idx]), both ? OPT_LOCAL : opt_flags);
+ flags = options[opt_idx].flags;
+ if (varp != NULL) { /* skip hidden option, nothing to do for it */
+ dvi = ((flags & P_VI_DEF) || compatible) ? VI_DEFAULT : VIM_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)
+ 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))
+ 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)
+ win_comp_scroll(curwin);
+ else {
+ *(long *)varp = (long)(long_i)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 */
+ /* the cast to long is required for Manx C, long_i is needed for
+ * MSVC */
+ *(int *)varp = (int)(long)(long_i)options[opt_idx].def_val[dvi];
+#ifdef UNIX
+ /* 'modeline' defaults to off for root */
+ if (options[opt_idx].indir == PV_ML && getuid() == ROOT_UID)
+ *(int *)varp = FALSE;
+#endif
+ /* May also set global value for local option. */
+ if (both)
+ *(int *)get_varp_scope(&(options[opt_idx]), OPT_GLOBAL) =
+ *(int *)varp;
+ }
+
+ /* The default value is not insecure. */
+ flagsp = insecure_flag(opt_idx, opt_flags);
+ *flagsp = *flagsp & ~P_INSECURE;
+ }
+
+ set_option_scriptID_idx(opt_idx, opt_flags, current_SID);
+}
+
+/*
+ * Set all options (except terminal options) to their default value.
+ */
+static void set_options_default(opt_flags)
+int opt_flags; /* OPT_FREE, OPT_LOCAL and/or OPT_GLOBAL */
+{
+ int i;
+ win_T *wp;
+ tabpage_T *tp;
+
+ for (i = 0; !istermoption(&options[i]); i++)
+ if (!(options[i].flags & P_NODEFAULT))
+ set_option_default(i, opt_flags, p_cp);
+
+ /* The 'scroll' option must be computed for all windows. */
+ FOR_ALL_TAB_WINDOWS(tp, wp)
+ win_comp_scroll(wp);
+}
+
+/*
+ * Set the Vi-default value of a string option.
+ * Used for 'sh', 'backupskip' and 'term'.
+ */
+void set_string_default(name, val)
+char *name;
+char_u *val;
+{
+ char_u *p;
+ int opt_idx;
+
+ p = vim_strsave(val);
+ if (p != NULL) { /* we don't want a NULL */
+ opt_idx = findoption((char_u *)name);
+ if (opt_idx >= 0) {
+ if (options[opt_idx].flags & P_DEF_ALLOCED)
+ vim_free(options[opt_idx].def_val[VI_DEFAULT]);
+ options[opt_idx].def_val[VI_DEFAULT] = p;
+ options[opt_idx].flags |= P_DEF_ALLOCED;
+ }
+ }
+}
+
+/*
+ * Set the Vi-default value of a number option.
+ * Used for 'lines' and 'columns'.
+ */
+void set_number_default(name, val)
+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 *)(long_i)val;
+}
+
+#if defined(EXITFREE) || defined(PROTO)
+/*
+ * Free all options.
+ */
+void free_all_options() {
+ int i;
+
+ for (i = 0; !istermoption(&options[i]); i++) {
+ if (options[i].indir == PV_NONE) {
+ /* 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)
+ 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 */
+ 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() {
+ int idx;
+
+ /*
+ * 'scroll' defaults to half the window height. Note that this default is
+ * wrong when the window height changes.
+ */
+ set_number_default("scroll", (long)((long_u)Rows >> 1));
+ idx = findoption((char_u *)"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"))
+ p_window = Rows - 1;
+ set_number_default("window", Rows - 1);
+
+ /* For DOS console the default is always black. */
+ /*
+ * If 'background' wasn't set by the user, try guessing the value,
+ * depending on the terminal name. Only need to check for terminals
+ * with a dark background, that can handle color.
+ */
+ idx = findoption((char_u *)"bg");
+ if (idx >= 0 && !(options[idx].flags & P_WAS_SET)
+ && *term_bg_default() == 'd') {
+ set_string_option_direct(NULL, idx, (char_u *)"dark", OPT_FREE, 0);
+ /* don't mark it as set, when starting the GUI it may be
+ * changed again */
+ options[idx].flags &= ~P_WAS_SET;
+ }
+
+#ifdef CURSOR_SHAPE
+ parse_shape_opt(SHAPE_CURSOR); /* set cursor shapes from 'guicursor' */
+#endif
+ (void)parse_printoptions(); /* parse 'printoptions' default value */
+}
+
+/*
+ * Return "dark" or "light" depending on the kind of terminal.
+ * This is just guessing! Recognized are:
+ * "linux" Linux console
+ * "screen.linux" Linux console with screen
+ * "cygwin" Cygwin shell
+ * "putty" Putty program
+ * We also check the COLORFGBG environment variable, which is set by
+ * rxvt and derivatives. This variable contains either two or three
+ * values separated by semicolons; we want the last value in either
+ * case. If this value is 0-6 or 8, our background is dark.
+ */
+static char_u * term_bg_default() {
+ char_u *p;
+
+ if (STRCMP(T_NAME, "linux") == 0
+ || STRCMP(T_NAME, "screen.linux") == 0
+ || STRCMP(T_NAME, "cygwin") == 0
+ || STRCMP(T_NAME, "putty") == 0
+ || ((p = mch_getenv((char_u *)"COLORFGBG")) != NULL
+ && (p = vim_strrchr(p, ';')) != NULL
+ && ((p[1] >= '0' && p[1] <= '6') || p[1] == '8')
+ && p[2] == NUL))
+ return (char_u *)"dark";
+ return (char_u *)"light";
+}
+
+/*
+ * Initialize the options, part three: After reading the .vimrc
+ */
+void set_init_3() {
+#if defined(UNIX) || defined(OS2) || defined(WIN3264)
+ /*
+ * Set 'shellpipe' and 'shellredir', depending on the 'shell' option.
+ * This is done after other initializations, where 'shell' might have been
+ * set, but only if they have not been set before.
+ */
+ char_u *p;
+ int idx_srr;
+ int do_srr;
+ int idx_sp;
+ int do_sp;
+
+ idx_srr = findoption((char_u *)"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
+ do_sp = !(options[idx_sp].flags & P_WAS_SET);
+
+ /*
+ * Isolate the name of the shell:
+ * - Skip beyond any path. E.g., "/usr/bin/csh -f" -> "csh -f".
+ * - Remove any argument. E.g., "csh -f" -> "csh".
+ * But don't allow a space in the path, so that this works:
+ * "/usr/bin/csh --rcfile ~/.cshrc"
+ * But don't do that for Windows, it's common to have a space in the path.
+ */
+ p = skiptowhite(p_sh);
+ if (*p == NUL) {
+ /* No white space, use the tail. */
+ p = vim_strsave(gettail(p_sh));
+ } else {
+ char_u *p1, *p2;
+
+ /* Find the last path separator before the space. */
+ p1 = p_sh;
+ for (p2 = p_sh; p2 < p; mb_ptr_adv(p2))
+ if (vim_ispathsep(*p2))
+ p1 = p2 + 1;
+ p = vim_strnsave(p1, (int)(p - p1));
+ }
+ if (p != NULL) {
+ /*
+ * Default for p_sp is "| tee", for p_srr is ">".
+ * For known shells it is changed here to include stderr.
+ */
+ if ( fnamecmp(p, "csh") == 0
+ || fnamecmp(p, "tcsh") == 0
+ ) {
+ if (do_sp) {
+ p_sp = (char_u *)"|& tee";
+ options[idx_sp].def_val[VI_DEFAULT] = p_sp;
+ }
+ if (do_srr) {
+ p_srr = (char_u *)">&";
+ options[idx_srr].def_val[VI_DEFAULT] = p_srr;
+ }
+ } else if ( fnamecmp(p, "sh") == 0
+ || fnamecmp(p, "ksh") == 0
+ || fnamecmp(p, "mksh") == 0
+ || fnamecmp(p, "pdksh") == 0
+ || fnamecmp(p, "zsh") == 0
+ || fnamecmp(p, "zsh-beta") == 0
+ || fnamecmp(p, "bash") == 0
+ ) {
+ if (do_sp) {
+ p_sp = (char_u *)"2>&1| tee";
+ options[idx_sp].def_val[VI_DEFAULT] = p_sp;
+ }
+ if (do_srr) {
+ p_srr = (char_u *)">%s 2>&1";
+ options[idx_srr].def_val[VI_DEFAULT] = p_srr;
+ }
+ }
+ vim_free(p);
+ }
+#endif
+
+
+ set_title_defaults();
+}
+
+/*
+ * When 'helplang' is still at its default value, set it to "lang".
+ * Only the first two characters of "lang" are used.
+ */
+void set_helplang_default(lang)
+char_u *lang;
+{
+ int idx;
+
+ if (lang == NULL || STRLEN(lang) < 2) /* safety check */
+ return;
+ idx = findoption((char_u *)"hlg");
+ if (idx >= 0 && !(options[idx].flags & P_WAS_SET)) {
+ if (options[idx].flags & P_ALLOCED)
+ free_string_option(p_hlg);
+ p_hlg = vim_strsave(lang);
+ if (p_hlg == NULL)
+ p_hlg = empty_option;
+ else {
+ /* zh_CN becomes "cn", zh_TW becomes "tw". */
+ if (STRNICMP(p_hlg, "zh_", 3) == 0 && STRLEN(p_hlg) >= 5) {
+ p_hlg[0] = TOLOWER_ASC(p_hlg[3]);
+ p_hlg[1] = TOLOWER_ASC(p_hlg[4]);
+ }
+ p_hlg[2] = NUL;
+ }
+ options[idx].flags |= P_ALLOCED;
+ }
+}
+
+
+/*
+ * 'title' and 'icon' only default to true if they have not been set or reset
+ * in .vimrc and we can read the old value.
+ * When 'title' and 'icon' have been reset in .vimrc, we won't even check if
+ * they can be reset. This reduces startup time when using X on a remote
+ * machine.
+ */
+void set_title_defaults() {
+ int idx1;
+ long val;
+
+ /*
+ * If GUI is (going to be) used, we can always set the window title and
+ * icon name. Saves a bit of time, because the X11 display server does
+ * not need to be contacted.
+ */
+ idx1 = findoption((char_u *)"title");
+ if (idx1 >= 0 && !(options[idx1].flags & P_WAS_SET)) {
+ val = mch_can_restore_title();
+ options[idx1].def_val[VI_DEFAULT] = (char_u *)(long_i)val;
+ p_title = val;
+ }
+ idx1 = findoption((char_u *)"icon");
+ if (idx1 >= 0 && !(options[idx1].flags & P_WAS_SET)) {
+ val = mch_can_restore_icon();
+ options[idx1].def_val[VI_DEFAULT] = (char_u *)(long_i)val;
+ p_icon = val;
+ }
+}
+
+/*
+ * Parse 'arg' for option settings.
+ *
+ * 'arg' may be IObuff, but only when no errors can be present and option
+ * does not need to be expanded with option_expand().
+ * "opt_flags":
+ * 0 for ":set"
+ * OPT_GLOBAL for ":setglobal"
+ * OPT_LOCAL for ":setlocal" and a modeline
+ * OPT_MODELINE for a modeline
+ * OPT_WINONLY to only set window-local options
+ * OPT_NOWIN to skip setting window-local options
+ *
+ * returns FAIL if an error is detected, OK otherwise
+ */
+int do_set(arg, opt_flags)
+char_u *arg; /* option string (may be written to!) */
+int opt_flags;
+{
+ int opt_idx;
+ char_u *errmsg;
+ char_u errbuf[80];
+ char_u *startarg;
+ int prefix; /* 1: nothing, 0: "no", 2: "inv" in front of name */
+ int nextchar; /* next non-white char after option name */
+ int afterchar; /* character just after option name */
+ int len;
+ int i;
+ long value;
+ int key;
+ long_u flags; /* flags for current option */
+ char_u *varp = NULL; /* pointer to variable for current option */
+ int did_show = FALSE; /* already showed one value */
+ int adding; /* "opt+=arg" */
+ int prepending; /* "opt^=arg" */
+ int removing; /* "opt-=arg" */
+ int cp_val = 0;
+ char_u key_name[2];
+
+ if (*arg == NUL) {
+ showoptions(0, opt_flags);
+ did_show = TRUE;
+ goto theend;
+ }
+
+ while (*arg != NUL) { /* loop to process all options */
+ errmsg = NULL;
+ startarg = arg; /* remember for error message */
+
+ if (STRNCMP(arg, "all", 3) == 0 && !isalpha(arg[3])
+ && !(opt_flags & OPT_MODELINE)) {
+ /*
+ * ":set all" show all options.
+ * ":set all&" set all options to their default value.
+ */
+ arg += 3;
+ if (*arg == '&') {
+ ++arg;
+ /* Only for :set command set global value of local options. */
+ set_options_default(OPT_FREE | opt_flags);
+ } else {
+ showoptions(1, opt_flags);
+ did_show = TRUE;
+ }
+ } else if (STRNCMP(arg, "termcap",
+ 7) == 0 && !(opt_flags & OPT_MODELINE)) {
+ showoptions(2, opt_flags);
+ show_termcodes();
+ did_show = TRUE;
+ arg += 7;
+ } else {
+ prefix = 1;
+ if (STRNCMP(arg, "no", 2) == 0 && STRNCMP(arg, "novice", 6) != 0) {
+ prefix = 0;
+ arg += 2;
+ } else if (STRNCMP(arg, "inv", 3) == 0) {
+ prefix = 2;
+ arg += 3;
+ }
+
+ /* find end of name */
+ key = 0;
+ if (*arg == '<') {
+ nextchar = 0;
+ opt_idx = -1;
+ /* look out for <t_>;> */
+ if (arg[1] == 't' && arg[2] == '_' && arg[3] && arg[4])
+ len = 5;
+ else {
+ len = 1;
+ while (arg[len] != NUL && arg[len] != '>')
+ ++len;
+ }
+ if (arg[len] != '>') {
+ errmsg = e_invarg;
+ goto skip;
+ }
+ arg[len] = NUL; /* put NUL after name */
+ if (arg[1] == 't' && arg[2] == '_') /* could be term code */
+ opt_idx = findoption(arg + 1);
+ arg[len++] = '>'; /* restore '>' */
+ if (opt_idx == -1)
+ key = find_key_option(arg + 1);
+ } else {
+ len = 0;
+ /*
+ * The two characters after "t_" may not be alphanumeric.
+ */
+ if (arg[0] == 't' && arg[1] == '_' && arg[2] && arg[3])
+ len = 4;
+ else
+ while (ASCII_ISALNUM(arg[len]) || arg[len] == '_')
+ ++len;
+ nextchar = arg[len];
+ arg[len] = NUL; /* put NUL after name */
+ opt_idx = findoption(arg);
+ arg[len] = nextchar; /* restore nextchar */
+ if (opt_idx == -1)
+ key = find_key_option(arg);
+ }
+
+ /* remember character after option name */
+ afterchar = arg[len];
+
+ /* skip white space, allow ":set ai ?" */
+ while (vim_iswhite(arg[len]))
+ ++len;
+
+ adding = FALSE;
+ prepending = FALSE;
+ removing = FALSE;
+ if (arg[len] != NUL && arg[len + 1] == '=') {
+ if (arg[len] == '+') {
+ adding = TRUE; /* "+=" */
+ ++len;
+ } else if (arg[len] == '^') {
+ prepending = TRUE; /* "^=" */
+ ++len;
+ } else if (arg[len] == '-') {
+ removing = TRUE; /* "-=" */
+ ++len;
+ }
+ }
+ nextchar = arg[len];
+
+ if (opt_idx == -1 && key == 0) { /* found a mismatch: skip */
+ errmsg = (char_u *)N_("E518: Unknown option");
+ goto skip;
+ }
+
+ if (opt_idx >= 0) {
+ if (options[opt_idx].var == NULL) { /* hidden option: skip */
+ /* Only give an error message when requesting the value of
+ * a hidden option, ignore setting it. */
+ if (vim_strchr((char_u *)"=:!&<", nextchar) == NULL
+ && (!(options[opt_idx].flags & P_BOOL)
+ || nextchar == '?'))
+ errmsg = (char_u *)N_("E519: Option not supported");
+ goto skip;
+ }
+
+ flags = options[opt_idx].flags;
+ varp = get_varp_scope(&(options[opt_idx]), opt_flags);
+ } else {
+ flags = P_STRING;
+ if (key < 0) {
+ key_name[0] = KEY2TERMCAP0(key);
+ key_name[1] = KEY2TERMCAP1(key);
+ } else {
+ key_name[0] = KS_KEY;
+ key_name[1] = (key & 0xff);
+ }
+ }
+
+ /* Skip all options that are not window-local (used when showing
+ * an already loaded buffer in a window). */
+ if ((opt_flags & OPT_WINONLY)
+ && (opt_idx < 0 || options[opt_idx].var != VAR_WIN))
+ goto skip;
+
+ /* Skip all options that are window-local (used for :vimgrep). */
+ if ((opt_flags & OPT_NOWIN) && opt_idx >= 0
+ && options[opt_idx].var == VAR_WIN)
+ goto skip;
+
+ /* Disallow changing some options from modelines. */
+ if (opt_flags & OPT_MODELINE) {
+ if (flags & (P_SECURE | P_NO_ML)) {
+ errmsg = (char_u *)_("E520: Not allowed in a modeline");
+ goto skip;
+ }
+ /* In diff mode some options are overruled. This avoids that
+ * 'foldmethod' becomes "marker" instead of "diff" and that
+ * "wrap" gets set. */
+ if (curwin->w_p_diff
+ && opt_idx >= 0 /* shut up coverity warning */
+ && (options[opt_idx].indir == PV_FDM
+ || options[opt_idx].indir == PV_WRAP))
+ goto skip;
+ }
+
+#ifdef HAVE_SANDBOX
+ /* Disallow changing some options in the sandbox */
+ if (sandbox != 0 && (flags & P_SECURE)) {
+ errmsg = (char_u *)_(e_sandbox);
+ goto skip;
+ }
+#endif
+
+ if (vim_strchr((char_u *)"?=:!&<", nextchar) != NULL) {
+ arg += len;
+ cp_val = p_cp;
+ if (nextchar == '&' && arg[1] == 'v' && arg[2] == 'i') {
+ if (arg[3] == 'm') { /* "opt&vim": set to Vim default */
+ cp_val = FALSE;
+ arg += 3;
+ } else { /* "opt&vi": set to Vi default */
+ cp_val = TRUE;
+ arg += 2;
+ }
+ }
+ if (vim_strchr((char_u *)"?!&<", nextchar) != NULL
+ && arg[1] != NUL && !vim_iswhite(arg[1])) {
+ errmsg = e_trailing;
+ goto skip;
+ }
+ }
+
+ /*
+ * allow '=' and ':' as MSDOS command.com allows only one
+ * '=' character per "set" command line. grrr. (jw)
+ */
+ if (nextchar == '?'
+ || (prefix == 1
+ && vim_strchr((char_u *)"=:&<", nextchar) == NULL
+ && !(flags & P_BOOL))) {
+ /*
+ * print value
+ */
+ if (did_show)
+ msg_putchar('\n'); /* cursor below last one */
+ else {
+ gotocmdline(TRUE); /* cursor at status line */
+ did_show = TRUE; /* remember that we did a line */
+ }
+ 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]);
+ }
+ } else {
+ char_u *p;
+
+ p = find_termcode(key_name);
+ if (p == NULL) {
+ errmsg = (char_u *)N_("E846: Key code not set");
+ goto skip;
+ } else
+ (void)show_one_termcode(key_name, p, TRUE);
+ }
+ if (nextchar != '?'
+ && nextchar != NUL && !vim_iswhite(afterchar))
+ errmsg = e_trailing;
+ } else {
+ if (flags & P_BOOL) { /* boolean */
+ if (nextchar == '=' || nextchar == ':') {
+ errmsg = e_invarg;
+ goto skip;
+ }
+
+ /*
+ * ":set opt!": invert
+ * ":set opt&": reset to default value
+ * ":set opt<": reset to global value
+ */
+ if (nextchar == '!')
+ value = *(int *)(varp) ^ 1;
+ else if (nextchar == '&')
+ value = (int)(long)(long_i)options[opt_idx].def_val[
+ ((flags & P_VI_DEF) || cp_val)
+ ? VI_DEFAULT : VIM_DEFAULT];
+ else if (nextchar == '<') {
+ /* For 'autoread' -1 means to use global value. */
+ if ((int *)varp == &curbuf->b_p_ar
+ && opt_flags == OPT_LOCAL)
+ value = -1;
+ else
+ value = *(int *)get_varp_scope(&(options[opt_idx]),
+ OPT_GLOBAL);
+ } else {
+ /*
+ * ":set invopt": invert
+ * ":set opt" or ":set noopt": set or reset
+ */
+ if (nextchar != NUL && !vim_iswhite(afterchar)) {
+ errmsg = e_trailing;
+ goto skip;
+ }
+ if (prefix == 2) /* inv */
+ value = *(int *)(varp) ^ 1;
+ else
+ value = prefix;
+ }
+
+ errmsg = set_bool_option(opt_idx, varp, (int)value,
+ opt_flags);
+ } else { /* numeric or string */
+ if (vim_strchr((char_u *)"=:&<", nextchar) == NULL
+ || prefix != 1) {
+ errmsg = e_invarg;
+ goto skip;
+ }
+
+ if (flags & P_NUM) { /* numeric */
+ /*
+ * Different ways to set a number option:
+ * & set to default value
+ * < set to global value
+ * <xx> accept special key codes for 'wildchar'
+ * c accept any non-digit for 'wildchar'
+ * [-]0-9 set number
+ * other error
+ */
+ ++arg;
+ if (nextchar == '&')
+ value = (long)(long_i)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
+ value = *(long *)get_varp_scope(
+ &(options[opt_idx]), OPT_GLOBAL);
+ } else if (((long *)varp == &p_wc
+ || (long *)varp == &p_wcm)
+ && (*arg == '<'
+ || *arg == '^'
+ || ((!arg[1] || vim_iswhite(arg[1]))
+ && !VIM_ISDIGIT(*arg)))) {
+ value = string_to_key(arg);
+ if (value == 0 && (long *)varp != &p_wcm) {
+ errmsg = e_invarg;
+ goto skip;
+ }
+ }
+ /* allow negative numbers (for 'undolevels') */
+ else if (*arg == '-' || VIM_ISDIGIT(*arg)) {
+ i = 0;
+ if (*arg == '-')
+ i = 1;
+#ifdef HAVE_STRTOL
+ value = strtol((char *)arg, NULL, 0);
+ if (arg[i] == '0' && TOLOWER_ASC(arg[i + 1]) == 'x')
+ i += 2;
+#else
+ value = atol((char *)arg);
+#endif
+ while (VIM_ISDIGIT(arg[i]))
+ ++i;
+ if (arg[i] != NUL && !vim_iswhite(arg[i])) {
+ errmsg = e_invarg;
+ goto skip;
+ }
+ } else {
+ errmsg = (char_u *)N_("E521: Number required after =");
+ goto skip;
+ }
+
+ if (adding)
+ value = *(long *)varp + value;
+ if (prepending)
+ value = *(long *)varp * value;
+ 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 */
+ char_u *save_arg = NULL;
+ char_u *s = NULL;
+ char_u *oldval; /* previous value if *varp */
+ char_u *newval;
+ char_u *origval;
+ unsigned newlen;
+ int comma;
+ int bs;
+ int new_value_alloced; /* new string option
+ was allocated */
+
+ /* When using ":set opt=val" for a global option
+ * with a local value the local value will be
+ * reset, use the global value here. */
+ if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0
+ && ((int)options[opt_idx].indir & PV_BOTH))
+ varp = options[opt_idx].var;
+
+ /* 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 */
+ newval = options[opt_idx].def_val[
+ ((flags & P_VI_DEF) || cp_val)
+ ? VI_DEFAULT : VIM_DEFAULT];
+ if ((char_u **)varp == &p_bg) {
+ /* guess the value of 'background' */
+ newval = term_bg_default();
+ }
+
+ /* expand environment variables and ~ (since the
+ * default value was already expanded, only
+ * required when an environment variable was set
+ * later */
+ if (newval == NULL)
+ newval = empty_option;
+ else {
+ s = option_expand(opt_idx, newval);
+ if (s == NULL)
+ s = newval;
+ newval = vim_strsave(s);
+ }
+ new_value_alloced = TRUE;
+ } else if (nextchar == '<') { /* set to global val */
+ newval = vim_strsave(*(char_u **)get_varp_scope(
+ &(options[opt_idx]), OPT_GLOBAL));
+ new_value_alloced = TRUE;
+ } else {
+ ++arg; /* jump to after the '=' or ':' */
+
+ /*
+ * Set 'keywordprg' to ":help" if an empty
+ * value was passed to :set by the user.
+ * Misuse errbuf[] for the resulting string.
+ */
+ if (varp == (char_u *)&p_kp
+ && (*arg == NUL || *arg == ' ')) {
+ STRCPY(errbuf, ":help");
+ save_arg = arg;
+ arg = errbuf;
+ }
+ /*
+ * Convert 'backspace' number to string, for
+ * adding, prepending and removing string.
+ */
+ else if (varp == (char_u *)&p_bs
+ && VIM_ISDIGIT(**(char_u **)varp)) {
+ i = getdigits((char_u **)varp);
+ switch (i) {
+ case 0:
+ *(char_u **)varp = empty_option;
+ break;
+ case 1:
+ *(char_u **)varp = vim_strsave(
+ (char_u *)"indent,eol");
+ break;
+ case 2:
+ *(char_u **)varp = vim_strsave(
+ (char_u *)"indent,eol,start");
+ break;
+ }
+ vim_free(oldval);
+ oldval = *(char_u **)varp;
+ }
+ /*
+ * Convert 'whichwrap' number to string, for
+ * backwards compatibility with Vim 3.0.
+ * Misuse errbuf[] for the resulting string.
+ */
+ else if (varp == (char_u *)&p_ww
+ && VIM_ISDIGIT(*arg)) {
+ *errbuf = NUL;
+ i = getdigits(&arg);
+ if (i & 1)
+ STRCAT(errbuf, "b,");
+ if (i & 2)
+ STRCAT(errbuf, "s,");
+ if (i & 4)
+ STRCAT(errbuf, "h,l,");
+ if (i & 8)
+ STRCAT(errbuf, "<,>,");
+ if (i & 16)
+ STRCAT(errbuf, "[,],");
+ if (*errbuf != NUL) /* remove trailing , */
+ errbuf[STRLEN(errbuf) - 1] = NUL;
+ save_arg = arg;
+ arg = errbuf;
+ }
+ /*
+ * Remove '>' before 'dir' and 'bdir', for
+ * backwards compatibility with version 3.0
+ */
+ else if ( *arg == '>'
+ && (varp == (char_u *)&p_dir
+ || varp == (char_u *)&p_bdir)) {
+ ++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
+ * we need to remove the backslashes.
+ */
+ /* get a bit too much */
+ newlen = (unsigned)STRLEN(arg) + 1;
+ if (adding || prepending || removing)
+ newlen += (unsigned)STRLEN(origval) + 1;
+ newval = alloc(newlen);
+ if (newval == NULL) /* out of mem, don't change */
+ break;
+ s = newval;
+
+ /*
+ * Copy the string, skip over escaped chars.
+ * For MS-DOS and WIN32 backslashes before normal
+ * file name characters are not removed, and keep
+ * backslash at start, for "\\machine\path", but
+ * do remove it for "\\\\machine\\path".
+ * The reverse is found in ExpandOldSetting().
+ */
+ while (*arg && !vim_iswhite(*arg)) {
+ if (*arg == '\\' && arg[1] != NUL
+#ifdef BACKSLASH_IN_FILENAME
+ && !((flags & P_EXPAND)
+ && vim_isfilec(arg[1])
+ && (arg[1] != '\\'
+ || (s == newval
+ && arg[2] != '\\')))
+#endif
+ )
+ ++arg; /* remove backslash */
+ if (has_mbyte
+ && (i = (*mb_ptr2len)(arg)) > 1) {
+ /* copy multibyte char */
+ mch_memmove(s, arg, (size_t)i);
+ arg += i;
+ s += i;
+ } else
+ *s++ = *arg++;
+ }
+ *s = NUL;
+
+ /*
+ * Expand environment variables and ~.
+ * Don't do it when adding without inserting a
+ * comma.
+ */
+ if (!(adding || prepending || removing)
+ || (flags & P_COMMA)) {
+ s = option_expand(opt_idx, newval);
+ if (s != NULL) {
+ vim_free(newval);
+ newlen = (unsigned)STRLEN(s) + 1;
+ if (adding || prepending || removing)
+ newlen += (unsigned)STRLEN(origval) + 1;
+ newval = alloc(newlen);
+ if (newval == NULL)
+ break;
+ STRCPY(newval, s);
+ }
+ }
+
+ /* locate newval[] in origval[] when removing it
+ * and when adding to avoid duplicates */
+ i = 0; /* init for GCC */
+ if (removing || (flags & P_NODUP)) {
+ i = (int)STRLEN(newval);
+ bs = 0;
+ for (s = origval; *s; ++s) {
+ if ((!(flags & P_COMMA)
+ || s == origval
+ || (s[-1] == ',' && !(bs & 1)))
+ && STRNCMP(s, newval, i) == 0
+ && (!(flags & P_COMMA)
+ || s[i] == ','
+ || s[i] == NUL))
+ break;
+ /* Count backslashes. Only a comma with an
+ * even number of backslashes before it is
+ * recognized as a separator */
+ if (s > origval && s[-1] == '\\')
+ ++bs;
+ else
+ bs = 0;
+ }
+
+ /* do not add if already there */
+ if ((adding || prepending) && *s) {
+ prepending = FALSE;
+ adding = FALSE;
+ STRCPY(newval, origval);
+ }
+ }
+
+ /* concatenate the two strings; add a ',' if
+ * needed */
+ if (adding || prepending) {
+ comma = ((flags & P_COMMA) && *origval != NUL
+ && *newval != NUL);
+ if (adding) {
+ i = (int)STRLEN(origval);
+ mch_memmove(newval + i + comma, newval,
+ STRLEN(newval) + 1);
+ mch_memmove(newval, origval, (size_t)i);
+ } else {
+ i = (int)STRLEN(newval);
+ STRMOVE(newval + i + comma, origval);
+ }
+ if (comma)
+ newval[i] = ',';
+ }
+
+ /* Remove newval[] from origval[]. (Note: "i" has
+ * been set above and is used here). */
+ if (removing) {
+ STRCPY(newval, origval);
+ if (*s) {
+ /* may need to remove a comma */
+ if (flags & P_COMMA) {
+ if (s == origval) {
+ /* include comma after string */
+ if (s[i] == ',')
+ ++i;
+ } else {
+ /* include comma before string */
+ --s;
+ ++i;
+ }
+ }
+ STRMOVE(newval + (s - origval), s + i);
+ }
+ }
+
+ 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;
+ }
+ }
+
+ if (save_arg != NULL) /* number for 'whichwrap' */
+ arg = save_arg;
+ new_value_alloced = TRUE;
+ }
+
+ /* Set the new value. */
+ *(char_u **)(varp) = newval;
+
+ /* Handle side effects, and set the global value for
+ * ":set" on local options. */
+ errmsg = did_set_string_option(opt_idx, (char_u **)varp,
+ new_value_alloced, oldval, errbuf, opt_flags);
+
+ /* If error detected, print the error message. */
+ if (errmsg != NULL)
+ goto skip;
+ } else { /* key code option */
+ char_u *p;
+
+ if (nextchar == '&') {
+ if (add_termcap_entry(key_name, TRUE) == FAIL)
+ errmsg = (char_u *)N_("E522: Not found in termcap");
+ } else {
+ ++arg; /* jump to after the '=' or ':' */
+ for (p = arg; *p && !vim_iswhite(*p); ++p)
+ if (*p == '\\' && p[1] != NUL)
+ ++p;
+ nextchar = *p;
+ *p = NUL;
+ add_termcode(key_name, arg, FALSE);
+ *p = nextchar;
+ }
+ if (full_screen)
+ ttest(FALSE);
+ redraw_all_later(CLEAR);
+ }
+ }
+
+ if (opt_idx >= 0)
+ did_set_option(opt_idx, opt_flags,
+ !prepending && !adding && !removing);
+ }
+
+skip:
+ /*
+ * Advance to next argument.
+ * - skip until a blank found, taking care of backslashes
+ * - skip blanks
+ * - skip one "=val" argument (for hidden options ":set gfn =xx")
+ */
+ for (i = 0; i < 2; ++i) {
+ while (*arg != NUL && !vim_iswhite(*arg))
+ if (*arg++ == '\\' && *arg != NUL)
+ ++arg;
+ arg = skipwhite(arg);
+ if (*arg != '=')
+ break;
+ }
+ }
+
+ if (errmsg != NULL) {
+ vim_strncpy(IObuff, (char_u *)_(errmsg), IOSIZE - 1);
+ i = (int)STRLEN(IObuff) + 2;
+ if (i + (arg - startarg) < IOSIZE) {
+ /* append the argument with the error */
+ STRCAT(IObuff, ": ");
+ mch_memmove(IObuff + i, startarg, (arg - startarg));
+ IObuff[i + (arg - startarg)] = NUL;
+ }
+ /* make sure all characters are printable */
+ trans_characters(IObuff, IOSIZE);
+
+ ++no_wait_return; /* wait_return done later */
+ emsg(IObuff); /* show error highlighted */
+ --no_wait_return;
+
+ return FAIL;
+ }
+
+ arg = skipwhite(arg);
+ }
+
+theend:
+ if (silent_mode && did_show) {
+ /* After displaying option values in silent mode. */
+ silent_mode = FALSE;
+ info_message = TRUE; /* use mch_msg(), not mch_errmsg() */
+ msg_putchar('\n');
+ cursor_on(); /* msg_start() switches it off */
+ out_flush();
+ silent_mode = TRUE;
+ info_message = FALSE; /* use mch_msg(), not mch_errmsg() */
+ }
+
+ return OK;
+}
+
+/*
+ * Call this when an option has been given a new value through a user command.
+ * Sets the P_WAS_SET flag and takes care of the P_INSECURE flag.
+ */
+static void did_set_option(opt_idx, opt_flags, new_value)
+int opt_idx;
+int opt_flags; /* possibly with OPT_MODELINE */
+int new_value; /* value was replaced completely */
+{
+ long_u *p;
+
+ options[opt_idx].flags |= P_WAS_SET;
+
+ /* When an option is set in the sandbox, from a modeline or in secure mode
+ * set the P_INSECURE flag. Otherwise, if a new value is stored reset the
+ * flag. */
+ p = insecure_flag(opt_idx, opt_flags);
+ if (secure
+#ifdef HAVE_SANDBOX
+ || sandbox != 0
+#endif
+ || (opt_flags & OPT_MODELINE))
+ *p = *p | P_INSECURE;
+ else if (new_value)
+ *p = *p & ~P_INSECURE;
+}
+
+static char_u * illegal_char(errbuf, c)
+char_u *errbuf;
+int c;
+{
+ if (errbuf == NULL)
+ return (char_u *)"";
+ sprintf((char *)errbuf, _("E539: Illegal character <%s>"),
+ (char *)transchar(c));
+ return errbuf;
+}
+
+/*
+ * Convert a key name or string into a key value.
+ * Used for 'wildchar' and 'cedit' options.
+ */
+static int string_to_key(arg)
+char_u *arg;
+{
+ if (*arg == '<')
+ return find_key_option(arg + 1);
+ if (*arg == '^')
+ return Ctrl_chr(arg[1]);
+ return *arg;
+}
+
+/*
+ * Check value of 'cedit' and set cedit_key.
+ * Returns NULL if value is OK, error message otherwise.
+ */
+static char_u * check_cedit() {
+ int n;
+
+ if (*p_cedit == NUL)
+ cedit_key = -1;
+ else {
+ n = string_to_key(p_cedit);
+ if (vim_isprintc(n))
+ return e_invarg;
+ cedit_key = n;
+ }
+ return NULL;
+}
+
+/*
+ * When changing 'title', 'titlestring', 'icon' or 'iconstring', call
+ * maketitle() to create and display it.
+ * When switching the title or icon off, call mch_restore_title() to get
+ * the old value back.
+ */
+static void did_set_title(icon)
+int icon; /* Did set icon instead of title */
+{
+ if (starting != NO_SCREEN
+ ) {
+ maketitle();
+ if (icon) {
+ if (!p_icon)
+ mch_restore_title(2);
+ } else {
+ if (!p_title)
+ mch_restore_title(1);
+ }
+ }
+}
+
+/*
+ * set_options_bin - called when 'bin' changes value.
+ */
+void set_options_bin(oldval, newval, opt_flags)
+int oldval;
+int newval;
+int opt_flags; /* OPT_LOCAL and/or OPT_GLOBAL */
+{
+ /*
+ * The option values that are changed when 'bin' changes are
+ * copied when 'bin is set and restored when 'bin' is reset.
+ */
+ if (newval) {
+ if (!oldval) { /* switched on */
+ if (!(opt_flags & OPT_GLOBAL)) {
+ curbuf->b_p_tw_nobin = curbuf->b_p_tw;
+ curbuf->b_p_wm_nobin = curbuf->b_p_wm;
+ curbuf->b_p_ml_nobin = curbuf->b_p_ml;
+ curbuf->b_p_et_nobin = curbuf->b_p_et;
+ }
+ if (!(opt_flags & OPT_LOCAL)) {
+ p_tw_nobin = p_tw;
+ p_wm_nobin = p_wm;
+ p_ml_nobin = p_ml;
+ p_et_nobin = p_et;
+ }
+ }
+
+ if (!(opt_flags & OPT_GLOBAL)) {
+ curbuf->b_p_tw = 0; /* no automatic line wrap */
+ curbuf->b_p_wm = 0; /* no automatic line wrap */
+ curbuf->b_p_ml = 0; /* no modelines */
+ curbuf->b_p_et = 0; /* no expandtab */
+ }
+ if (!(opt_flags & OPT_LOCAL)) {
+ p_tw = 0;
+ p_wm = 0;
+ p_ml = FALSE;
+ p_et = FALSE;
+ p_bin = TRUE; /* needed when called for the "-b" argument */
+ }
+ } else if (oldval) { /* switched off */
+ if (!(opt_flags & OPT_GLOBAL)) {
+ curbuf->b_p_tw = curbuf->b_p_tw_nobin;
+ curbuf->b_p_wm = curbuf->b_p_wm_nobin;
+ curbuf->b_p_ml = curbuf->b_p_ml_nobin;
+ curbuf->b_p_et = curbuf->b_p_et_nobin;
+ }
+ if (!(opt_flags & OPT_LOCAL)) {
+ p_tw = p_tw_nobin;
+ p_wm = p_wm_nobin;
+ p_ml = p_ml_nobin;
+ p_et = p_et_nobin;
+ }
+ }
+}
+
+/*
+ * Find the parameter represented by the given character (eg ', :, ", or /),
+ * and return its associated value in the 'viminfo' string.
+ * Only works for number parameters, not for 'r' or 'n'.
+ * If the parameter is not specified in the string or there is no following
+ * number, return -1.
+ */
+int get_viminfo_parameter(type)
+int type;
+{
+ char_u *p;
+
+ p = find_viminfo_parameter(type);
+ if (p != NULL && VIM_ISDIGIT(*p))
+ return atoi((char *)p);
+ return -1;
+}
+
+/*
+ * Find the parameter represented by the given character (eg ''', ':', '"', or
+ * '/') in the 'viminfo' option and return a pointer to the string after it.
+ * Return NULL if the parameter is not specified in the string.
+ */
+char_u * find_viminfo_parameter(type)
+int type;
+{
+ char_u *p;
+
+ for (p = p_viminfo; *p; ++p) {
+ if (*p == type)
+ return p + 1;
+ if (*p == 'n') /* 'n' is always the last one */
+ break;
+ p = vim_strchr(p, ','); /* skip until next ',' */
+ if (p == NULL) /* hit the end without finding parameter */
+ break;
+ }
+ return NULL;
+}
+
+/*
+ * Expand environment variables for some string options.
+ * These string options cannot be indirect!
+ * If "val" is NULL expand the current value of the option.
+ * Return pointer to NameBuff, or NULL when not expanded.
+ */
+static char_u * option_expand(opt_idx, val)
+int opt_idx;
+char_u *val;
+{
+ /* if option doesn't need expansion nothing to do */
+ 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)
+ val = *(char_u **)options[opt_idx].var;
+
+ /*
+ * Expanding this with NameBuff, expand_env() must not be passed IObuff.
+ * Escape spaces when expanding 'tags', they are used to separate file
+ * names.
+ * For 'spellsuggest' expand after "file:".
+ */
+ expand_env_esc(val, NameBuff, MAXPATHL,
+ (char_u **)options[opt_idx].var == &p_tags, FALSE,
+ (char_u **)options[opt_idx].var == &p_sps ? (char_u *)"file:" :
+ NULL);
+ if (STRCMP(NameBuff, val) == 0) /* they are the same */
+ return NULL;
+
+ return NameBuff;
+}
+
+/*
+ * After setting various option values: recompute variables that depend on
+ * option values.
+ */
+static void didset_options() {
+ /* initialize the table for 'iskeyword' et.al. */
+ (void)init_chartab();
+
+ (void)opt_strings_flags(p_cmp, p_cmp_values, &cmp_flags, TRUE);
+ (void)opt_strings_flags(p_bkc, p_bkc_values, &bkc_flags, TRUE);
+ (void)opt_strings_flags(p_ssop, p_ssop_values, &ssop_flags, TRUE);
+ (void)opt_strings_flags(p_vop, p_ssop_values, &vop_flags, TRUE);
+ (void)opt_strings_flags(p_fdo, p_fdo_values, &fdo_flags, TRUE);
+ (void)opt_strings_flags(p_dy, p_dy_values, &dy_flags, TRUE);
+ (void)opt_strings_flags(p_ve, p_ve_values, &ve_flags, TRUE);
+#if defined(FEAT_MOUSE) && (defined(UNIX) || defined(VMS))
+ (void)opt_strings_flags(p_ttym, p_ttym_values, &ttym_flags, FALSE);
+#endif
+ (void)spell_check_msm();
+ (void)spell_check_sps();
+ (void)compile_cap_prog(curwin->w_s);
+ /* set cedit_key */
+ (void)check_cedit();
+}
+
+/*
+ * Check for string options that are NULL (normally only termcap options).
+ */
+void check_options() {
+ int opt_idx;
+
+ for (opt_idx = 0; options[opt_idx].fullname != NULL; opt_idx++)
+ if ((options[opt_idx].flags & P_STRING) && options[opt_idx].var != NULL)
+ check_string_option((char_u **)get_varp(&(options[opt_idx])));
+}
+
+/*
+ * Check string options in a buffer for NULL value.
+ */
+void check_buf_options(buf)
+buf_T *buf;
+{
+ check_string_option(&buf->b_p_bh);
+ check_string_option(&buf->b_p_bt);
+ check_string_option(&buf->b_p_fenc);
+ check_string_option(&buf->b_p_ff);
+ check_string_option(&buf->b_p_def);
+ check_string_option(&buf->b_p_inc);
+ 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_cm);
+ check_string_option(&buf->b_p_fex);
+ check_string_option(&buf->b_p_key);
+ check_string_option(&buf->b_p_kp);
+ check_string_option(&buf->b_p_mps);
+ check_string_option(&buf->b_p_fo);
+ check_string_option(&buf->b_p_flp);
+ check_string_option(&buf->b_p_isk);
+ check_string_option(&buf->b_p_com);
+ check_string_option(&buf->b_p_cms);
+ check_string_option(&buf->b_p_nf);
+ check_string_option(&buf->b_p_qe);
+ check_string_option(&buf->b_p_syn);
+ check_string_option(&buf->b_s.b_p_spc);
+ check_string_option(&buf->b_s.b_p_spf);
+ check_string_option(&buf->b_s.b_p_spl);
+ check_string_option(&buf->b_p_sua);
+ check_string_option(&buf->b_p_cink);
+ check_string_option(&buf->b_p_cino);
+ parse_cino(buf);
+ check_string_option(&buf->b_p_ft);
+ check_string_option(&buf->b_p_cinw);
+ check_string_option(&buf->b_p_cpt);
+ check_string_option(&buf->b_p_cfu);
+ check_string_option(&buf->b_p_ofu);
+ check_string_option(&buf->b_p_keymap);
+ check_string_option(&buf->b_p_gp);
+ check_string_option(&buf->b_p_mp);
+ check_string_option(&buf->b_p_efm);
+ check_string_option(&buf->b_p_ep);
+ check_string_option(&buf->b_p_path);
+ check_string_option(&buf->b_p_tags);
+ check_string_option(&buf->b_p_dict);
+ check_string_option(&buf->b_p_tsr);
+}
+
+/*
+ * Free the string allocated for an option.
+ * Checks for the string being empty_option. This may happen if we're out of
+ * memory, vim_strsave() returned NULL, which was replaced by empty_option by
+ * check_options().
+ * Does NOT check for P_ALLOCED flag!
+ */
+void free_string_option(p)
+char_u *p;
+{
+ if (p != empty_option)
+ vim_free(p);
+}
+
+void clear_string_option(pp)
+char_u **pp;
+{
+ if (*pp != empty_option)
+ vim_free(*pp);
+ *pp = empty_option;
+}
+
+static void check_string_option(pp)
+char_u **pp;
+{
+ if (*pp == NULL)
+ *pp = empty_option;
+}
+
+/*
+ * Mark a terminal option as allocated, found by a pointer into term_strings[].
+ */
+void set_term_option_alloced(p)
+char_u **p;
+{
+ int opt_idx;
+
+ for (opt_idx = 1; options[opt_idx].fullname != NULL; opt_idx++)
+ if (options[opt_idx].var == (char_u *)p) {
+ options[opt_idx].flags |= P_ALLOCED;
+ return;
+ }
+ return; /* cannot happen: didn't find it! */
+}
+
+/*
+ * Return TRUE when option "opt" was set from a modeline or in secure mode.
+ * Return FALSE when it wasn't.
+ * Return -1 for an unknown option.
+ */
+int was_set_insecurely(opt, opt_flags)
+char_u *opt;
+int opt_flags;
+{
+ int idx = findoption(opt);
+ long_u *flagp;
+
+ if (idx >= 0) {
+ flagp = insecure_flag(idx, opt_flags);
+ return (*flagp & P_INSECURE) != 0;
+ }
+ EMSG2(_(e_intern2), "was_set_insecurely()");
+ return -1;
+}
+
+/*
+ * Get a pointer to the flags used for the P_INSECURE flag of option
+ * "opt_idx". For some local options a local flags field is used.
+ */
+static long_u * insecure_flag(opt_idx, opt_flags)
+int opt_idx;
+int opt_flags;
+{
+ if (opt_flags & OPT_LOCAL)
+ switch ((int)options[opt_idx].indir) {
+ case PV_STL: return &curwin->w_p_stl_flags;
+ case PV_FDE: return &curwin->w_p_fde_flags;
+ case PV_FDT: return &curwin->w_p_fdt_flags;
+ case PV_INDE: return &curbuf->b_p_inde_flags;
+ case PV_FEX: return &curbuf->b_p_fex_flags;
+ case PV_INEX: return &curbuf->b_p_inex_flags;
+ }
+
+ /* Nothing special, return global flags field. */
+ return &options[opt_idx].flags;
+}
+
+static void redraw_titles __ARGS((void));
+
+/*
+ * Redraw the window title and/or tab page text later.
+ */
+static void redraw_titles() {
+ need_maketitle = TRUE;
+ redraw_tabline = TRUE;
+}
+
+/*
+ * Set a string option to a new value (without checking the effect).
+ * The string is copied into allocated memory.
+ * if ("opt_idx" == -1) "name" is used, otherwise "opt_idx" is used.
+ * When "set_sid" is zero set the scriptID to current_SID. When "set_sid" is
+ * SID_NONE don't set the scriptID. Otherwise set the scriptID to "set_sid".
+ */
+void set_string_option_direct(name, opt_idx, val, opt_flags, set_sid)
+char_u *name;
+int opt_idx;
+char_u *val;
+int opt_flags; /* OPT_FREE, OPT_LOCAL and/or OPT_GLOBAL */
+int set_sid UNUSED;
+{
+ char_u *s;
+ char_u **varp;
+ 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()");
+ return;
+ }
+ }
+
+ if (options[idx].var == NULL) /* can't set hidden option */
+ return;
+
+ s = vim_strsave(val);
+ if (s != NULL) {
+ varp = (char_u **)get_varp_scope(&(options[idx]),
+ both ? OPT_LOCAL : opt_flags);
+ if ((opt_flags & OPT_FREE) && (options[idx].flags & P_ALLOCED))
+ free_string_option(*varp);
+ *varp = s;
+
+ /* For buffer/window local option may also set the global value. */
+ if (both)
+ set_string_option_global(idx, varp);
+
+ options[idx].flags |= P_ALLOCED;
+
+ /* When setting both values of a global option with a local value,
+ * make the local value empty, so that the global value is used. */
+ if (((int)options[idx].indir & PV_BOTH) && both) {
+ free_string_option(*varp);
+ *varp = empty_option;
+ }
+ if (set_sid != SID_NONE)
+ set_option_scriptID_idx(idx, opt_flags,
+ set_sid == 0 ? current_SID : set_sid);
+ }
+}
+
+/*
+ * Set global value for string option when it's a local option.
+ */
+static void set_string_option_global(opt_idx, varp)
+int opt_idx; /* option index */
+char_u **varp; /* pointer to option variable */
+{
+ char_u **p, *s;
+
+ /* the global value is always allocated */
+ if (options[opt_idx].var == VAR_WIN)
+ p = (char_u **)GLOBAL_WO(varp);
+ else
+ p = (char_u **)options[opt_idx].var;
+ if (options[opt_idx].indir != PV_NONE
+ && p != varp
+ && (s = vim_strsave(*varp)) != NULL) {
+ free_string_option(*p);
+ *p = s;
+ }
+}
+
+/*
+ * Set a string option to a new value, and handle the effects.
+ *
+ * Returns NULL on success or error message on error.
+ */
+static char_u * set_string_option(opt_idx, value, opt_flags)
+int opt_idx;
+char_u *value;
+int opt_flags; /* OPT_LOCAL and/or OPT_GLOBAL */
+{
+ char_u *s;
+ char_u **varp;
+ char_u *oldval;
+ char_u *r = NULL;
+
+ if (options[opt_idx].var == NULL) /* don't set hidden option */
+ return NULL;
+
+ s = vim_strsave(value);
+ if (s != NULL) {
+ varp = (char_u **)get_varp_scope(&(options[opt_idx]),
+ (opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0
+ ? (((int)options[opt_idx].indir & PV_BOTH)
+ ? OPT_GLOBAL : OPT_LOCAL)
+ : opt_flags);
+ oldval = *varp;
+ *varp = s;
+ if ((r = did_set_string_option(opt_idx, varp, TRUE, oldval, NULL,
+ opt_flags)) == NULL)
+ did_set_option(opt_idx, opt_flags, TRUE);
+ }
+ return r;
+}
+
+/*
+ * Handle string options that need some action to perform when changed.
+ * Returns NULL for success, or an error message for an error.
+ */
+static char_u * did_set_string_option(opt_idx, varp, new_value_alloced, oldval,
+ errbuf,
+ opt_flags)
+int opt_idx; /* index in options[] table */
+char_u **varp; /* pointer to the option variable */
+int new_value_alloced; /* new value was allocated */
+char_u *oldval; /* previous value of the option */
+char_u *errbuf; /* buffer for errors, or NULL */
+int opt_flags; /* OPT_LOCAL and/or OPT_GLOBAL */
+{
+ char_u *errmsg = NULL;
+ char_u *s, *p;
+ int did_chartab = FALSE;
+ char_u **gvarp;
+ long_u free_oldval = (options[opt_idx].flags & P_ALLOCED);
+
+ /* Get the global option to compare with, otherwise we would have to check
+ * two values for all local options. */
+ gvarp = (char_u **)get_varp_scope(&(options[opt_idx]), OPT_GLOBAL);
+
+ /* Disallow changing some options from secure mode */
+ if ((secure
+#ifdef HAVE_SANDBOX
+ || sandbox != 0
+#endif
+ ) && (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) {
+ errmsg = e_invarg;
+ }
+ /* 'term' */
+ else if (varp == &T_NAME) {
+ if (T_NAME[0] == NUL)
+ errmsg = (char_u *)N_("E529: Cannot set 'term' to empty string");
+ else if (set_termname(T_NAME) == FAIL)
+ errmsg = (char_u *)N_("E522: Not found in termcap");
+ else
+ /* Screen colors may have changed. */
+ redraw_later_clear();
+ }
+ /* 'backupcopy' */
+ else if (varp == &p_bkc) {
+ if (opt_strings_flags(p_bkc, p_bkc_values, &bkc_flags, TRUE) != OK)
+ errmsg = e_invarg;
+ if (((bkc_flags & BKC_AUTO) != 0)
+ + ((bkc_flags & BKC_YES) != 0)
+ + ((bkc_flags & BKC_NO) != 0) != 1) {
+ /* Must have exactly one of "auto", "yes" and "no". */
+ (void)opt_strings_flags(oldval, p_bkc_values, &bkc_flags, TRUE);
+ errmsg = e_invarg;
+ }
+ }
+ /* 'backupext' and 'patchmode' */
+ else if (varp == &p_bex || varp == &p_pm) {
+ if (STRCMP(*p_bex == '.' ? p_bex + 1 : p_bex,
+ *p_pm == '.' ? p_pm + 1 : p_pm) == 0)
+ errmsg = (char_u *)N_("E589: 'backupext' and 'patchmode' are equal");
+ }
+ /*
+ * '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
+ || varp == &(curbuf->b_p_isk)
+ || varp == &p_isp
+ || varp == &p_isf) {
+ if (init_chartab() == FAIL) {
+ did_chartab = TRUE; /* need to restore it below */
+ errmsg = e_invarg; /* error in value */
+ }
+ }
+ /* 'helpfile' */
+ else if (varp == &p_hf) {
+ /* May compute new values for $VIM and $VIMRUNTIME */
+ if (didset_vim) {
+ vim_setenv((char_u *)"VIM", (char_u *)"");
+ didset_vim = FALSE;
+ }
+ if (didset_vimruntime) {
+ vim_setenv((char_u *)"VIMRUNTIME", (char_u *)"");
+ didset_vimruntime = FALSE;
+ }
+ }
+ /* 'colorcolumn' */
+ else if (varp == &curwin->w_p_cc)
+ errmsg = check_colorcolumn(curwin);
+
+ /* 'helplang' */
+ else if (varp == &p_hlg) {
+ /* Check for "", "ab", "ab,cd", etc. */
+ for (s = p_hlg; *s != NUL; s += 3) {
+ if (s[1] == NUL || ((s[2] != ',' || s[3] == NUL) && s[2] != NUL)) {
+ errmsg = e_invarg;
+ break;
+ }
+ if (s[2] == NUL)
+ break;
+ }
+ }
+ /* 'highlight' */
+ else if (varp == &p_hl) {
+ if (highlight_changed() == FAIL)
+ errmsg = e_invarg; /* invalid flags */
+ }
+ /* 'nrformats' */
+ else if (gvarp == &p_nf) {
+ if (check_opt_strings(*varp, p_nf_values, TRUE) != OK)
+ errmsg = e_invarg;
+ }
+ /* 'sessionoptions' */
+ else if (varp == &p_ssop) {
+ if (opt_strings_flags(p_ssop, p_ssop_values, &ssop_flags, TRUE) != OK)
+ errmsg = e_invarg;
+ if ((ssop_flags & SSOP_CURDIR) && (ssop_flags & SSOP_SESDIR)) {
+ /* Don't allow both "sesdir" and "curdir". */
+ (void)opt_strings_flags(oldval, p_ssop_values, &ssop_flags, TRUE);
+ errmsg = e_invarg;
+ }
+ }
+ /* 'viewoptions' */
+ else if (varp == &p_vop) {
+ if (opt_strings_flags(p_vop, p_ssop_values, &vop_flags, TRUE) != OK)
+ errmsg = e_invarg;
+ }
+ /* 'scrollopt' */
+ 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)
+ errmsg = e_invarg;
+ 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)
+ errmsg = (char_u *)_("E835: Conflicts with value of 'fillchars'");
+ }
+ /* 'background' */
+ else if (varp == &p_bg) {
+ if (check_opt_strings(p_bg, p_bg_values, FALSE) == OK) {
+ int dark = (*p_bg == 'd');
+
+ 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);
+ free_string_option(p_bg);
+ p_bg = vim_strsave((char_u *)(dark ? "dark" : "light"));
+ check_string_option(&p_bg);
+ init_highlight(FALSE, FALSE);
+ }
+ } else
+ errmsg = e_invarg;
+ }
+ /* 'wildmode' */
+ else if (varp == &p_wim) {
+ if (check_opt_wim() == FAIL)
+ errmsg = e_invarg;
+ }
+ /* 'wildoptions' */
+ else if (varp == &p_wop) {
+ if (check_opt_strings(p_wop, p_wop_values, TRUE) != OK)
+ errmsg = e_invarg;
+ }
+ /* 'winaltkeys' */
+ else if (varp == &p_wak) {
+ if (*p_wak == NUL
+ || check_opt_strings(p_wak, p_wak_values, FALSE) != OK)
+ errmsg = e_invarg;
+ }
+ /* 'eventignore' */
+ else if (varp == &p_ei) {
+ if (check_ei() == FAIL)
+ errmsg = e_invarg;
+ }
+ /* 'encoding' and 'fileencoding' */
+ else if (varp == &p_enc || gvarp == &p_fenc || varp == &p_tenc) {
+ if (gvarp == &p_fenc) {
+ if (!curbuf->b_p_ma && opt_flags != OPT_GLOBAL)
+ errmsg = e_modifiable;
+ 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. */
+ redraw_titles();
+ /* Add 'fileencoding' to the swap file. */
+ ml_setflags(curbuf);
+ }
+ }
+ if (errmsg == NULL) {
+ /* canonize the value, so that STRCMP() can be used on it */
+ p = enc_canonize(*varp);
+ if (p != NULL) {
+ vim_free(*varp);
+ *varp = p;
+ }
+ if (varp == &p_enc) {
+ errmsg = mb_init();
+ redraw_titles();
+ }
+ }
+
+
+ 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();
+
+ /* When 'termencoding' is not empty and 'encoding' changes or when
+ * 'termencoding' changes, need to setup for keyboard input and
+ * display output conversion. */
+ if (((varp == &p_enc && *p_tenc != NUL) || varp == &p_tenc)) {
+ convert_setup(&input_conv, p_tenc, p_enc);
+ convert_setup(&output_conv, p_enc, p_tenc);
+ }
+
+ }
+ } else if (varp == &p_penc) {
+ /* Canonize printencoding if VIM standard one */
+ p = enc_canonize(p_penc);
+ if (p != NULL) {
+ vim_free(p_penc);
+ p_penc = p;
+ } else {
+ /* Ensure lower case and '-' for '_' */
+ for (s = p_penc; *s != NUL; s++) {
+ if (*s == '_')
+ *s = '-';
+ else
+ *s = TOLOWER_ASC(*s);
+ }
+ }
+ } else if (varp == &curbuf->b_p_keymap) {
+ /* load or unload key mapping tables */
+ errmsg = keymap_init();
+
+ if (errmsg == NULL) {
+ if (*curbuf->b_p_keymap != NUL) {
+ /* Installed a new keymap, switch on using it. */
+ curbuf->b_p_iminsert = B_IMODE_LMAP;
+ if (curbuf->b_p_imsearch != B_IMODE_USE_INSERT)
+ curbuf->b_p_imsearch = B_IMODE_LMAP;
+ } else {
+ /* Cleared the keymap, may reset 'iminsert' and 'imsearch'. */
+ if (curbuf->b_p_iminsert == B_IMODE_LMAP)
+ curbuf->b_p_iminsert = B_IMODE_NONE;
+ if (curbuf->b_p_imsearch == B_IMODE_LMAP)
+ curbuf->b_p_imsearch = B_IMODE_USE_INSERT;
+ }
+ if ((opt_flags & OPT_LOCAL) == 0) {
+ set_iminsert_global();
+ set_imsearch_global();
+ }
+ status_redraw_curbuf();
+ }
+ }
+ /* 'fileformat' */
+ else if (gvarp == &p_ff) {
+ if (!curbuf->b_p_ma && !(opt_flags & OPT_GLOBAL))
+ errmsg = e_modifiable;
+ else if (check_opt_strings(*varp, p_ff_values, FALSE) != OK)
+ errmsg = e_invarg;
+ else {
+ /* may also change 'textmode' */
+ if (get_fileformat(curbuf) == EOL_DOS)
+ curbuf->b_p_tx = TRUE;
+ else
+ curbuf->b_p_tx = FALSE;
+ redraw_titles();
+ /* update flag in swap file */
+ ml_setflags(curbuf);
+ /* Redraw needed when switching to/from "mac": a CR in the text
+ * will be displayed differently. */
+ if (get_fileformat(curbuf) == EOL_MAC || *oldval == 'm')
+ redraw_curbuf_later(NOT_VALID);
+ }
+ }
+ /* 'fileformats' */
+ else if (varp == &p_ffs) {
+ if (check_opt_strings(p_ffs, p_ff_values, TRUE) != OK)
+ errmsg = e_invarg;
+ else {
+ /* also change 'textauto' */
+ if (*p_ffs == NUL)
+ p_ta = FALSE;
+ else
+ p_ta = TRUE;
+ }
+ }
+ /* 'cryptkey' */
+ else if (gvarp == &p_key) {
+ /* Make sure the ":set" command doesn't show the new value in the
+ * history. */
+ remove_key_from_history();
+ if (STRCMP(curbuf->b_p_key, oldval) != 0)
+ /* Need to update the swapfile. */
+ ml_set_crypt_key(curbuf, oldval, get_crypt_method(curbuf));
+ } else if (gvarp == &p_cm) {
+ if (opt_flags & OPT_LOCAL)
+ p = curbuf->b_p_cm;
+ else
+ p = p_cm;
+ if (check_opt_strings(p, p_cm_values, TRUE) != OK)
+ errmsg = e_invarg;
+ else if (get_crypt_method(curbuf) > 0 && blowfish_self_test() == FAIL)
+ errmsg = e_invarg;
+ else {
+ /* When setting the global value to empty, make it "zip". */
+ if (*p_cm == NUL) {
+ if (new_value_alloced)
+ free_string_option(p_cm);
+ p_cm = vim_strsave((char_u *)"zip");
+ new_value_alloced = TRUE;
+ }
+
+ /* Need to update the swapfile when the effective method changed.
+ * Set "s" to the effective old value, "p" to the effective new
+ * method and compare. */
+ if ((opt_flags & OPT_LOCAL) && *oldval == NUL)
+ s = p_cm; /* was previously using the global value */
+ else
+ s = oldval;
+ if (*curbuf->b_p_cm == NUL)
+ p = p_cm; /* is now using the global value */
+ else
+ p = curbuf->b_p_cm;
+ if (STRCMP(s, p) != 0)
+ ml_set_crypt_key(curbuf, curbuf->b_p_key,
+ crypt_method_from_string(s));
+
+ /* If the global value changes need to update the swapfile for all
+ * buffers using that value. */
+ if ((opt_flags & OPT_GLOBAL) && STRCMP(p_cm, oldval) != 0) {
+ buf_T *buf;
+
+ for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+ if (buf != curbuf && *buf->b_p_cm == NUL)
+ ml_set_crypt_key(buf, buf->b_p_key,
+ crypt_method_from_string(oldval));
+ }
+ }
+ }
+ /* 'matchpairs' */
+ else if (gvarp == &p_mps) {
+ if (has_mbyte) {
+ for (p = *varp; *p != NUL; ++p) {
+ int x2 = -1;
+ int x3 = -1;
+
+ if (*p != NUL)
+ p += mb_ptr2len(p);
+ if (*p != NUL)
+ x2 = *p++;
+ if (*p != NUL) {
+ x3 = mb_ptr2char(p);
+ p += mb_ptr2len(p);
+ }
+ if (x2 != ':' || x3 == -1 || (*p != NUL && *p != ',')) {
+ errmsg = e_invarg;
+ break;
+ }
+ if (*p == NUL)
+ break;
+ }
+ } else {
+ /* Check for "x:y,x:y" */
+ for (p = *varp; *p != NUL; p += 4) {
+ if (p[1] != ':' || p[2] == NUL || (p[3] != NUL && p[3] != ',')) {
+ errmsg = e_invarg;
+ break;
+ }
+ if (p[3] == NUL)
+ break;
+ }
+ }
+ }
+ /* 'comments' */
+ else if (gvarp == &p_com) {
+ for (s = *varp; *s; ) {
+ while (*s && *s != ':') {
+ if (vim_strchr((char_u *)COM_ALL, *s) == NULL
+ && !VIM_ISDIGIT(*s) && *s != '-') {
+ errmsg = illegal_char(errbuf, *s);
+ break;
+ }
+ ++s;
+ }
+ if (*s++ == NUL)
+ errmsg = (char_u *)N_("E524: Missing colon");
+ else if (*s == ',' || *s == NUL)
+ errmsg = (char_u *)N_("E525: Zero length string");
+ if (errmsg != NULL)
+ break;
+ while (*s && *s != ',') {
+ if (*s == '\\' && s[1] != NUL)
+ ++s;
+ ++s;
+ }
+ s = skip_to_option_part(s);
+ }
+ }
+ /* 'listchars' */
+ else if (varp == &p_lcs) {
+ errmsg = set_chars_option(varp);
+ }
+ /* 'fillchars' */
+ else if (varp == &p_fcs) {
+ errmsg = set_chars_option(varp);
+ }
+ /* 'cedit' */
+ else if (varp == &p_cedit) {
+ errmsg = check_cedit();
+ }
+ /* 'verbosefile' */
+ else if (varp == &p_vfile) {
+ verbose_stop();
+ if (*p_vfile != NUL && verbose_open() == FAIL)
+ errmsg = e_invarg;
+ }
+ /* 'viminfo' */
+ else if (varp == &p_viminfo) {
+ for (s = p_viminfo; *s; ) {
+ /* Check it's a valid character */
+ if (vim_strchr((char_u *)"!\"%'/:<@cfhnrs", *s) == NULL) {
+ errmsg = illegal_char(errbuf, *s);
+ break;
+ }
+ if (*s == 'n') { /* name is always last one */
+ break;
+ } else if (*s == 'r') { /* skip until next ',' */
+ while (*++s && *s != ',')
+ ;
+ } else if (*s == '%') {
+ /* optional number */
+ while (vim_isdigit(*++s))
+ ;
+ } else if (*s == '!' || *s == 'h' || *s == 'c')
+ ++s; /* no extra chars */
+ else { /* must have a number */
+ while (vim_isdigit(*++s))
+ ;
+
+ if (!VIM_ISDIGIT(*(s - 1))) {
+ if (errbuf != NULL) {
+ sprintf((char *)errbuf,
+ _("E526: Missing number after <%s>"),
+ transchar_byte(*(s - 1)));
+ errmsg = errbuf;
+ } else
+ errmsg = (char_u *)"";
+ break;
+ }
+ }
+ if (*s == ',')
+ ++s;
+ else if (*s) {
+ if (errbuf != NULL)
+ errmsg = (char_u *)N_("E527: Missing comma");
+ else
+ errmsg = (char_u *)"";
+ break;
+ }
+ }
+ if (*p_viminfo && errmsg == NULL && get_viminfo_parameter('\'') < 0)
+ errmsg = (char_u *)N_("E528: Must specify a ' value");
+ }
+ /* terminal options */
+ else if (istermoption(&options[opt_idx]) && full_screen) {
+ /* ":set t_Co=0" and ":set t_Co=1" do ":set t_Co=" */
+ if (varp == &T_CCO) {
+ int colors = atoi((char *)T_CCO);
+
+ /* 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;
+ if (t_colors <= 1) {
+ if (new_value_alloced)
+ vim_free(T_CCO);
+ T_CCO = empty_option;
+ }
+ /* We now have a different color setup, initialize it again. */
+ init_highlight(TRUE, FALSE);
+ }
+ }
+ ttest(FALSE);
+ if (varp == &T_ME) {
+ out_str(T_ME);
+ redraw_later(CLEAR);
+ }
+ }
+ /* 'showbreak' */
+ else if (varp == &p_sbr) {
+ for (s = p_sbr; *s; ) {
+ if (ptr2cells(s) != 1)
+ errmsg = (char_u *)N_("E595: contains unprintable or wide character");
+ mb_ptr_adv(s);
+ }
+ }
+
+
+#ifdef CURSOR_SHAPE
+ /* 'guicursor' */
+ else if (varp == &p_guicursor)
+ errmsg = parse_shape_opt(SHAPE_CURSOR);
+#endif
+
+
+ else if (varp == &p_popt)
+ errmsg = parse_printoptions();
+ else if (varp == &p_pmfn)
+ errmsg = parse_printmbfont();
+
+ /* 'langmap' */
+ else if (varp == &p_langmap)
+ langmap_set();
+
+ /* 'breakat' */
+ else if (varp == &p_breakat)
+ fill_breakat_flags();
+
+ /* 'titlestring' and 'iconstring' */
+ else if (varp == &p_titlestring || varp == &p_iconstring) {
+ int flagval = (varp == &p_titlestring) ? STL_IN_TITLE : STL_IN_ICON;
+
+ /* NULL => statusline syntax */
+ if (vim_strchr(*varp, '%') && check_stl_option(*varp) == NULL)
+ stl_syntax |= flagval;
+ else
+ stl_syntax &= ~flagval;
+ did_set_title(varp == &p_iconstring);
+
+ }
+
+
+
+#if defined(FEAT_MOUSE_TTY) && (defined(UNIX) || defined(VMS))
+ /* 'ttymouse' */
+ else if (varp == &p_ttym) {
+ /* Switch the mouse off before changing the escape sequences used for
+ * that. */
+ mch_setmouse(FALSE);
+ if (opt_strings_flags(p_ttym, p_ttym_values, &ttym_flags, FALSE) != OK)
+ errmsg = e_invarg;
+ else
+ check_mouse_termcode();
+ if (termcap_active)
+ setmouse(); /* may switch it on again */
+ }
+#endif
+
+ /* 'selection' */
+ else if (varp == &p_sel) {
+ if (*p_sel == NUL
+ || check_opt_strings(p_sel, p_sel_values, FALSE) != OK)
+ errmsg = e_invarg;
+ }
+ /* 'selectmode' */
+ else if (varp == &p_slm) {
+ if (check_opt_strings(p_slm, p_slm_values, TRUE) != OK)
+ errmsg = e_invarg;
+ }
+ /* 'keymodel' */
+ else if (varp == &p_km) {
+ if (check_opt_strings(p_km, p_km_values, TRUE) != OK)
+ errmsg = e_invarg;
+ else {
+ km_stopsel = (vim_strchr(p_km, 'o') != NULL);
+ km_startsel = (vim_strchr(p_km, 'a') != NULL);
+ }
+ }
+ /* 'mousemodel' */
+ else if (varp == &p_mousem) {
+ if (check_opt_strings(p_mousem, p_mousem_values, FALSE) != OK)
+ errmsg = e_invarg;
+ }
+ /* 'switchbuf' */
+ else if (varp == &p_swb) {
+ if (opt_strings_flags(p_swb, p_swb_values, &swb_flags, TRUE) != OK)
+ errmsg = e_invarg;
+ }
+ /* 'debug' */
+ else if (varp == &p_debug) {
+ if (check_opt_strings(p_debug, p_debug_values, TRUE) != OK)
+ errmsg = e_invarg;
+ }
+ /* 'display' */
+ else if (varp == &p_dy) {
+ if (opt_strings_flags(p_dy, p_dy_values, &dy_flags, TRUE) != OK)
+ errmsg = e_invarg;
+ else
+ (void)init_chartab();
+
+ }
+ /* 'eadirection' */
+ else if (varp == &p_ead) {
+ if (check_opt_strings(p_ead, p_ead_values, FALSE) != OK)
+ errmsg = e_invarg;
+ }
+ /* When 'spelllang' or 'spellfile' is set and there is a window for this
+ * buffer in which 'spell' is set load the wordlists. */
+ else if (varp == &(curbuf->b_s.b_p_spl) || varp == &(curbuf->b_s.b_p_spf)) {
+ win_T *wp;
+ int l;
+
+ if (varp == &(curbuf->b_s.b_p_spf)) {
+ l = (int)STRLEN(curbuf->b_s.b_p_spf);
+ if (l > 0 && (l < 4 || STRCMP(curbuf->b_s.b_p_spf + l - 4,
+ ".add") != 0))
+ errmsg = e_invarg;
+ }
+
+ if (errmsg == NULL) {
+ FOR_ALL_WINDOWS(wp)
+ if (wp->w_buffer == curbuf && wp->w_p_spell) {
+ errmsg = did_set_spelllang(wp);
+ break;
+ }
+ }
+ }
+ /* When 'spellcapcheck' is set compile the regexp program. */
+ else if (varp == &(curwin->w_s->b_p_spc)) {
+ errmsg = compile_cap_prog(curwin->w_s);
+ }
+ /* 'spellsuggest' */
+ else if (varp == &p_sps) {
+ if (spell_check_sps() != OK)
+ errmsg = e_invarg;
+ }
+ /* 'mkspellmem' */
+ else if (varp == &p_msm) {
+ if (spell_check_msm() != OK)
+ errmsg = e_invarg;
+ }
+ /* When 'bufhidden' is set, check for valid value. */
+ else if (gvarp == &p_bh) {
+ if (check_opt_strings(curbuf->b_p_bh, p_bufhidden_values, FALSE) != OK)
+ errmsg = e_invarg;
+ }
+ /* When 'buftype' is set, check for valid value. */
+ else if (gvarp == &p_bt) {
+ if (check_opt_strings(curbuf->b_p_bt, p_buftype_values, FALSE) != OK)
+ errmsg = e_invarg;
+ else {
+ if (curwin->w_status_height) {
+ curwin->w_redr_status = TRUE;
+ redraw_later(VALID);
+ }
+ curbuf->b_help = (curbuf->b_p_bt[0] == 'h');
+ redraw_titles();
+ }
+ }
+ /* 'statusline' or 'rulerformat' */
+ else if (gvarp == &p_stl || varp == &p_ruf) {
+ int wid;
+
+ if (varp == &p_ruf) /* reset ru_wid first */
+ ru_wid = 0;
+ s = *varp;
+ if (varp == &p_ruf && *s == '%') {
+ /* set ru_wid if 'ruf' starts with "%99(" */
+ if (*++s == '-') /* ignore a '-' */
+ s++;
+ wid = getdigits(&s);
+ if (wid && *s == '(' && (errmsg = check_stl_option(p_ruf)) == NULL)
+ ru_wid = wid;
+ else
+ errmsg = check_stl_option(p_ruf);
+ }
+ /* check 'statusline' only if it doesn't start with "%!" */
+ else if (varp == &p_ruf || s[0] != '%' || s[1] != '!')
+ errmsg = check_stl_option(s);
+ if (varp == &p_ruf && errmsg == NULL)
+ comp_col();
+ }
+ /* check if it is a valid value for 'complete' -- Acevedo */
+ else if (gvarp == &p_cpt) {
+ for (s = *varp; *s; ) {
+ while (*s == ',' || *s == ' ')
+ s++;
+ if (!*s)
+ break;
+ if (vim_strchr((char_u *)".wbuksid]tU", *s) == NULL) {
+ errmsg = illegal_char(errbuf, *s);
+ break;
+ }
+ if (*++s != NUL && *s != ',' && *s != ' ') {
+ if (s[-1] == 'k' || s[-1] == 's') {
+ /* skip optional filename after 'k' and 's' */
+ while (*s && *s != ',' && *s != ' ') {
+ if (*s == '\\')
+ ++s;
+ ++s;
+ }
+ } else {
+ if (errbuf != NULL) {
+ sprintf((char *)errbuf,
+ _("E535: Illegal character after <%c>"),
+ *--s);
+ errmsg = errbuf;
+ } else
+ errmsg = (char_u *)"";
+ break;
+ }
+ }
+ }
+ }
+ /* 'completeopt' */
+ else if (varp == &p_cot) {
+ if (check_opt_strings(p_cot, p_cot_values, TRUE) != 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, &p, TRUE, TRUE, FALSE);
+ if (p != NULL) {
+ if (new_value_alloced)
+ free_string_option(p_pt);
+ p_pt = p;
+ new_value_alloced = TRUE;
+ }
+ }
+ }
+ /* 'backspace' */
+ else if (varp == &p_bs) {
+ if (VIM_ISDIGIT(*p_bs)) {
+ if (*p_bs >'2' || p_bs[1] != NUL)
+ errmsg = e_invarg;
+ } else if (check_opt_strings(p_bs, p_bs_values, TRUE) != OK)
+ errmsg = e_invarg;
+ }
+ /* 'casemap' */
+ else if (varp == &p_cmp) {
+ if (opt_strings_flags(p_cmp, p_cmp_values, &cmp_flags, TRUE) != OK)
+ errmsg = e_invarg;
+ }
+ /* 'diffopt' */
+ else if (varp == &p_dip) {
+ if (diffopt_changed() == FAIL)
+ errmsg = e_invarg;
+ }
+ /* 'foldmethod' */
+ else if (gvarp == &curwin->w_allbuf_opt.wo_fdm) {
+ if (check_opt_strings(*varp, p_fdm_values, FALSE) != OK
+ || *curwin->w_p_fdm == NUL)
+ errmsg = e_invarg;
+ else {
+ foldUpdateAll(curwin);
+ if (foldmethodIsDiff(curwin))
+ newFoldLevel();
+ }
+ }
+ /* 'foldexpr' */
+ else if (varp == &curwin->w_p_fde) {
+ if (foldmethodIsExpr(curwin))
+ foldUpdateAll(curwin);
+ }
+ /* 'foldmarker' */
+ else if (gvarp == &curwin->w_allbuf_opt.wo_fmr) {
+ p = vim_strchr(*varp, ',');
+ if (p == NULL)
+ errmsg = (char_u *)N_("E536: comma required");
+ else if (p == *varp || p[1] == NUL)
+ errmsg = e_invarg;
+ else if (foldmethodIsMarker(curwin))
+ foldUpdateAll(curwin);
+ }
+ /* 'commentstring' */
+ else if (gvarp == &p_cms) {
+ if (**varp != NUL && strstr((char *)*varp, "%s") == NULL)
+ errmsg = (char_u *)N_("E537: 'commentstring' must be empty or contain %s");
+ }
+ /* 'foldopen' */
+ else if (varp == &p_fdo) {
+ if (opt_strings_flags(p_fdo, p_fdo_values, &fdo_flags, TRUE) != OK)
+ errmsg = e_invarg;
+ }
+ /* 'foldclose' */
+ else if (varp == &p_fcl) {
+ if (check_opt_strings(p_fcl, p_fcl_values, TRUE) != OK)
+ errmsg = e_invarg;
+ }
+ /* 'foldignore' */
+ else if (gvarp == &curwin->w_allbuf_opt.wo_fdi) {
+ if (foldmethodIsIndent(curwin))
+ foldUpdateAll(curwin);
+ }
+ /* 'virtualedit' */
+ else if (varp == &p_ve) {
+ if (opt_strings_flags(p_ve, p_ve_values, &ve_flags, TRUE) != OK)
+ errmsg = e_invarg;
+ else if (STRCMP(p_ve, oldval) != 0) {
+ /* Recompute cursor position in case the new 've' setting
+ * changes something. */
+ validate_virtcol();
+ coladvance(curwin->w_virtcol);
+ }
+ } else if (varp == &p_csqf) {
+ if (p_csqf != NULL) {
+ p = p_csqf;
+ while (*p != NUL) {
+ if (vim_strchr((char_u *)CSQF_CMDS, *p) == NULL
+ || p[1] == NUL
+ || vim_strchr((char_u *)CSQF_FLAGS, p[1]) == NULL
+ || (p[2] != NUL && p[2] != ',')) {
+ errmsg = e_invarg;
+ break;
+ } else if (p[2] == NUL)
+ break;
+ else
+ p += 3;
+ }
+ }
+ }
+ /* 'cinoptions' */
+ else if (gvarp == &p_cino) {
+ /* TODO: recognize errors */
+ parse_cino(curbuf);
+ }
+ /* Options that are a list of flags. */
+ else {
+ p = NULL;
+ if (varp == &p_ww)
+ p = (char_u *)WW_ALL;
+ if (varp == &p_shm)
+ p = (char_u *)SHM_ALL;
+ else if (varp == &(p_cpo))
+ p = (char_u *)CPO_ALL;
+ else if (varp == &(curbuf->b_p_fo))
+ p = (char_u *)FO_ALL;
+ else if (varp == &curwin->w_p_cocu)
+ p = (char_u *)COCU_ALL;
+ else if (varp == &p_mouse) {
+ p = (char_u *)MOUSE_ALL;
+ }
+ if (p != NULL) {
+ for (s = *varp; *s; ++s)
+ if (vim_strchr(p, *s) == NULL) {
+ errmsg = illegal_char(errbuf, *s);
+ break;
+ }
+ }
+ }
+
+ /*
+ * If error detected, restore the previous value.
+ */
+ if (errmsg != NULL) {
+ if (new_value_alloced)
+ free_string_option(*varp);
+ *varp = oldval;
+ /*
+ * When resetting some values, need to act on it.
+ */
+ 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);
+ /*
+ * Free string options that are in allocated memory.
+ * Use "free_oldval", because recursiveness may change the flags under
+ * our fingers (esp. init_highlight()).
+ */
+ if (free_oldval)
+ free_string_option(oldval);
+ if (new_value_alloced)
+ options[opt_idx].flags |= P_ALLOCED;
+ else
+ options[opt_idx].flags &= ~P_ALLOCED;
+
+ if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0
+ && ((int)options[opt_idx].indir & PV_BOTH)) {
+ /* global option with local value set to use global value; free
+ * the local value and make it empty */
+ p = get_varp_scope(&(options[opt_idx]), OPT_LOCAL);
+ free_string_option(*(char_u **)p);
+ *(char_u **)p = empty_option;
+ }
+ /* May set global value for local option. */
+ else if (!(opt_flags & OPT_LOCAL) && opt_flags != OPT_GLOBAL)
+ set_string_option_global(opt_idx, varp);
+
+ /*
+ * Trigger the autocommand only after setting the flags.
+ */
+ /* 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);
+ } 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);
+ }
+ if (varp == &(curwin->w_s->b_p_spl)) {
+ char_u fname[200];
+ char_u *q = curwin->w_s->b_p_spl;
+
+ /* Skip the first name if it is "cjk". */
+ if (STRNCMP(q, "cjk,", 4) == 0)
+ q += 4;
+
+ /*
+ * Source the spell/LANG.vim in 'runtimepath'.
+ * They could set 'spellcapcheck' depending on the language.
+ * Use the first name in 'spelllang' up to '_region' or
+ * '.encoding'.
+ */
+ for (p = q; *p != NUL; ++p)
+ if (vim_strchr((char_u *)"_.,", *p) != NULL)
+ break;
+ vim_snprintf((char *)fname, 200, "spell/%.*s.vim", (int)(p - q), q);
+ source_runtime(fname, TRUE);
+ }
+ }
+
+ if (varp == &p_mouse) {
+ if (*p_mouse == NUL)
+ mch_setmouse(FALSE); /* switch mouse off */
+ else
+ setmouse(); /* in case 'mouse' changed */
+ }
+
+ if (curwin->w_curswant != MAXCOL
+ && (options[opt_idx].flags & (P_CURSWANT | P_RCLR)) != 0)
+ curwin->w_set_curswant = TRUE;
+
+ check_redraw(options[opt_idx].flags);
+
+ return errmsg;
+}
+
+/*
+ * Simple int comparison function for use with qsort()
+ */
+static int int_cmp(a, b)
+const void *a;
+const void *b;
+{
+ return *(const int *)a - *(const int *)b;
+}
+
+/*
+ * Handle setting 'colorcolumn' or 'textwidth' in window "wp".
+ * Returns error message, NULL if it's OK.
+ */
+char_u * check_colorcolumn(wp)
+win_T *wp;
+{
+ char_u *s;
+ int col;
+ int count = 0;
+ int color_cols[256];
+ int i;
+ int j = 0;
+
+ if (wp->w_buffer == NULL)
+ return NULL; /* buffer was closed */
+
+ for (s = wp->w_p_cc; *s != NUL && count < 255; ) {
+ if (*s == '-' || *s == '+') {
+ /* -N and +N: add to 'textwidth' */
+ col = (*s == '-') ? -1 : 1;
+ ++s;
+ if (!VIM_ISDIGIT(*s))
+ return e_invarg;
+ col = col * getdigits(&s);
+ if (wp->w_buffer->b_p_tw == 0)
+ goto skip; /* 'textwidth' not set, skip this item */
+ col += wp->w_buffer->b_p_tw;
+ if (col < 0)
+ goto skip;
+ } else if (VIM_ISDIGIT(*s))
+ col = getdigits(&s);
+ else
+ return e_invarg;
+ color_cols[count++] = col - 1; /* 1-based to 0-based */
+skip:
+ if (*s == NUL)
+ break;
+ if (*s != ',')
+ return e_invarg;
+ if (*++s == NUL)
+ return e_invarg; /* illegal trailing comma as in "set cc=80," */
+ }
+
+ vim_free(wp->w_p_cc_cols);
+ if (count == 0)
+ wp->w_p_cc_cols = NULL;
+ else {
+ wp->w_p_cc_cols = (int *)alloc((unsigned)sizeof(int) * (count + 1));
+ if (wp->w_p_cc_cols != NULL) {
+ /* sort the columns for faster usage on screen redraw inside
+ * win_line() */
+ qsort(color_cols, count, sizeof(int), int_cmp);
+
+ for (i = 0; i < count; ++i)
+ /* skip duplicates */
+ if (j == 0 || wp->w_p_cc_cols[j - 1] != color_cols[i])
+ wp->w_p_cc_cols[j++] = color_cols[i];
+ wp->w_p_cc_cols[j] = -1; /* end marker */
+ }
+ }
+
+ return NULL; /* no error */
+}
+
+/*
+ * Handle setting 'listchars' or 'fillchars'.
+ * Returns error message, NULL if it's OK.
+ */
+static char_u * set_chars_option(varp)
+char_u **varp;
+{
+ int round, i, len, entries;
+ char_u *p, *s;
+ int c1, c2 = 0;
+ struct charstab {
+ int *cp;
+ char *name;
+ };
+ static struct charstab filltab[] =
+ {
+ {&fill_stl, "stl"},
+ {&fill_stlnc, "stlnc"},
+ {&fill_vert, "vert"},
+ {&fill_fold, "fold"},
+ {&fill_diff, "diff"},
+ };
+ static struct charstab lcstab[] =
+ {
+ {&lcs_eol, "eol"},
+ {&lcs_ext, "extends"},
+ {&lcs_nbsp, "nbsp"},
+ {&lcs_prec, "precedes"},
+ {&lcs_tab2, "tab"},
+ {&lcs_trail, "trail"},
+ {&lcs_conceal, "conceal"},
+ };
+ struct charstab *tab;
+
+ if (varp == &p_lcs) {
+ tab = lcstab;
+ entries = sizeof(lcstab) / sizeof(struct charstab);
+ } else {
+ tab = filltab;
+ entries = sizeof(filltab) / sizeof(struct charstab);
+ }
+
+ /* 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)
+ lcs_tab1 = NUL;
+ else
+ fill_diff = '-';
+ }
+ p = *varp;
+ while (*p) {
+ for (i = 0; i < entries; ++i) {
+ len = (int)STRLEN(tab[i].name);
+ if (STRNCMP(p, tab[i].name, len) == 0
+ && p[len] == ':'
+ && p[len + 1] != NUL) {
+ s = p + len + 1;
+ c1 = mb_ptr2char_adv(&s);
+ if (mb_char2cells(c1) > 1)
+ continue;
+ if (tab[i].cp == &lcs_tab2) {
+ if (*s == NUL)
+ continue;
+ c2 = mb_ptr2char_adv(&s);
+ if (mb_char2cells(c2) > 1)
+ continue;
+ }
+ if (*s == ',' || *s == NUL) {
+ if (round) {
+ if (tab[i].cp == &lcs_tab2) {
+ lcs_tab1 = c1;
+ lcs_tab2 = c2;
+ } else if (tab[i].cp != NULL)
+ *(tab[i].cp) = c1;
+
+ }
+ p = s;
+ break;
+ }
+ }
+ }
+
+ if (i == entries)
+ return e_invarg;
+ if (*p == ',')
+ ++p;
+ }
+ }
+
+ return NULL; /* no error */
+}
+
+/*
+ * Check validity of options with the 'statusline' format.
+ * Return error message or NULL.
+ */
+char_u * check_stl_option(s)
+char_u *s;
+{
+ int itemcnt = 0;
+ int groupdepth = 0;
+ static char_u errbuf[80];
+
+ while (*s && itemcnt < STL_MAX_ITEM) {
+ /* Check for valid keys after % sequences */
+ while (*s && *s != '%')
+ s++;
+ if (!*s)
+ break;
+ s++;
+ if (*s != '%' && *s != ')')
+ ++itemcnt;
+ if (*s == '%' || *s == STL_TRUNCMARK || *s == STL_MIDDLEMARK) {
+ s++;
+ continue;
+ }
+ if (*s == ')') {
+ s++;
+ if (--groupdepth < 0)
+ break;
+ continue;
+ }
+ if (*s == '-')
+ s++;
+ while (VIM_ISDIGIT(*s))
+ s++;
+ if (*s == STL_USER_HL)
+ continue;
+ if (*s == '.') {
+ s++;
+ while (*s && VIM_ISDIGIT(*s))
+ s++;
+ }
+ if (*s == '(') {
+ groupdepth++;
+ continue;
+ }
+ if (vim_strchr(STL_ALL, *s) == NULL) {
+ return illegal_char(errbuf, *s);
+ }
+ if (*s == '{') {
+ s++;
+ while (*s != '}' && *s)
+ s++;
+ if (*s != '}')
+ return (char_u *)N_("E540: Unclosed expression sequence");
+ }
+ }
+ if (itemcnt >= STL_MAX_ITEM)
+ return (char_u *)N_("E541: too many items");
+ if (groupdepth != 0)
+ return (char_u *)N_("E542: unbalanced groups");
+ return NULL;
+}
+
+
+/*
+ * Set curbuf->b_cap_prog to the regexp program for 'spellcapcheck'.
+ * Return error message when failed, NULL when OK.
+ */
+static char_u * compile_cap_prog(synblock)
+synblock_T *synblock;
+{
+ regprog_T *rp = synblock->b_cap_prog;
+ char_u *re;
+
+ if (*synblock->b_p_spc == NUL)
+ synblock->b_cap_prog = NULL;
+ else {
+ /* Prepend a ^ so that we only match at one column */
+ re = concat_str((char_u *)"^", synblock->b_p_spc);
+ if (re != NULL) {
+ synblock->b_cap_prog = vim_regcomp(re, RE_MAGIC);
+ vim_free(re);
+ if (synblock->b_cap_prog == NULL) {
+ synblock->b_cap_prog = rp; /* restore the previous program */
+ return e_invarg;
+ }
+ }
+ }
+
+ vim_regfree(rp);
+ return NULL;
+}
+
+/*
+ * Set the scriptID for an option, taking care of setting the buffer- or
+ * window-local value.
+ */
+static void set_option_scriptID_idx(opt_idx, opt_flags, id)
+int opt_idx;
+int opt_flags;
+int id;
+{
+ int both = (opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0;
+ int indir = (int)options[opt_idx].indir;
+
+ /* 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;
+ 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;
+ }
+}
+
+/*
+ * 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(opt_idx, varp, value, opt_flags)
+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 */
+{
+ int old_value = *(int *)varp;
+
+ /* Disallow changing some options from secure mode */
+ if ((secure
+#ifdef HAVE_SANDBOX
+ || sandbox != 0
+#endif
+ ) && (options[opt_idx].flags & P_SECURE))
+ return e_secure;
+
+ *(int *)varp = value; /* set the new value */
+ /* Remember where the option was set. */
+ set_option_scriptID_idx(opt_idx, opt_flags, current_SID);
+
+
+ /* May set global value for local option. */
+ if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0)
+ *(int *)get_varp_scope(&(options[opt_idx]), OPT_GLOBAL) = value;
+
+ /*
+ * Handle side effects of changing a bool option.
+ */
+
+ /* 'compatible' */
+ if ((int *)varp == &p_cp) {
+ compatible_set();
+ }
+ /* '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 */
+ if ((curbuf == save_curbuf
+ || (opt_flags & OPT_GLOBAL) || opt_flags == 0)
+ && !curbufIsChanged() && curbuf->b_ml.ml_mfp != NULL) {
+ u_compute_hash(hash);
+ u_read_undo(NULL, hash, curbuf->b_fname);
+ }
+ }
+ curbuf = save_curbuf;
+ }
+ } else if ((int *)varp == &curbuf->b_p_ro) {
+ /* when 'readonly' is reset globally, also reset readonlymode */
+ if (!curbuf->b_p_ro && (opt_flags & OPT_LOCAL) == 0)
+ readonlymode = FALSE;
+
+ /* when 'readonly' is set may give W10 again */
+ if (curbuf->b_p_ro)
+ curbuf->b_did_warn = FALSE;
+
+ redraw_titles();
+ }
+ /* when 'modifiable' is changed, redraw the window title */
+ else if ((int *)varp == &curbuf->b_p_ma) {
+ redraw_titles();
+ }
+ /* when 'endofline' is changed, redraw the window title */
+ else if ((int *)varp == &curbuf->b_p_eol) {
+ redraw_titles();
+ }
+ /* when 'bomb' is changed, redraw the window title and tab page text */
+ else if ((int *)varp == &curbuf->b_p_bomb) {
+ redraw_titles();
+ }
+ /* when 'bin' is set also set some other options */
+ else if ((int *)varp == &curbuf->b_p_bin) {
+ set_options_bin(old_value, curbuf->b_p_bin, opt_flags);
+ redraw_titles();
+ }
+ /* when 'buflisted' changes, trigger autocommands */
+ else if ((int *)varp == &curbuf->b_p_bl && old_value != curbuf->b_p_bl) {
+ apply_autocmds(curbuf->b_p_bl ? EVENT_BUFADD : EVENT_BUFDELETE,
+ NULL, NULL, TRUE, curbuf);
+ }
+ /* when 'swf' is set, create swapfile, when reset remove swapfile */
+ else if ((int *)varp == &curbuf->b_p_swf) {
+ if (curbuf->b_p_swf && p_uc)
+ ml_open_file(curbuf); /* create the swap file */
+ else
+ /* no need to reset curbuf->b_may_swap, ml_open_file() will check
+ * buf->b_p_swf */
+ mf_close_file(curbuf, TRUE); /* remove the swap file */
+ }
+ /* when 'terse' is set change 'shortmess' */
+ else if ((int *)varp == &p_terse) {
+ char_u *p;
+
+ p = vim_strchr(p_shm, SHM_SEARCH);
+
+ /* insert 's' in p_shm */
+ if (p_terse && p == NULL) {
+ STRCPY(IObuff, p_shm);
+ STRCAT(IObuff, "s");
+ set_string_option_direct((char_u *)"shm", -1, IObuff, OPT_FREE, 0);
+ }
+ /* remove 's' from p_shm */
+ else if (!p_terse && p != NULL)
+ STRMOVE(p, p + 1);
+ }
+ /* when 'paste' is set or reset also change other options */
+ else if ((int *)varp == &p_paste) {
+ paste_option_changed();
+ }
+ /* 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)" */
+ restart_edit = 0;
+ }
+ }
+ /* when 'ignorecase' is set or reset and 'hlsearch' is set, redraw */
+ else if ((int *)varp == &p_ic && p_hls) {
+ redraw_all_later(SOME_VALID);
+ }
+ /* when 'hlsearch' is set or reset: reset no_hlsearch */
+ else if ((int *)varp == &p_hls) {
+ SET_NO_HLSEARCH(FALSE);
+ }
+ /* when 'scrollbind' is set: snapshot the current position to avoid a jump
+ * at the end of normal_cmd() */
+ else if ((int *)varp == &curwin->w_p_scb) {
+ if (curwin->w_p_scb) {
+ do_check_scrollbind(FALSE);
+ curwin->w_scbind_pos = curwin->w_topline;
+ }
+ }
+ /* There can be only one window with 'previewwindow' set. */
+ else if ((int *)varp == &curwin->w_p_pvw) {
+ if (curwin->w_p_pvw) {
+ win_T *win;
+
+ for (win = firstwin; win != NULL; win = win->w_next)
+ if (win->w_p_pvw && win != curwin) {
+ curwin->w_p_pvw = FALSE;
+ return (char_u *)N_("E590: A preview window already exists");
+ }
+ }
+ }
+ /* when 'textmode' is set or reset also change 'fileformat' */
+ else if ((int *)varp == &curbuf->b_p_tx) {
+ set_fileformat(curbuf->b_p_tx ? EOL_DOS : EOL_UNIX, opt_flags);
+ }
+ /* when 'textauto' is set or reset also change 'fileformats' */
+ else if ((int *)varp == &p_ta)
+ set_string_option_direct((char_u *)"ffs", -1,
+ p_ta ? (char_u *)DFLT_FFS_VIM : (char_u *)"",
+ OPT_FREE | opt_flags, 0);
+
+ /*
+ * 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 ((int *)varp == &p_icon) {
+ 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;
+ }
+
+#ifdef BACKSLASH_IN_FILENAME
+ else if ((int *)varp == &p_ssl) {
+ if (p_ssl) {
+ psepc = '/';
+ psepcN = '\\';
+ pseps[0] = '/';
+ } else {
+ psepc = '\\';
+ psepcN = '/';
+ pseps[0] = '\\';
+ }
+
+ /* need to adjust the file name arguments and buffer names. */
+ buflist_slash_adjust();
+ alist_slash_adjust();
+ scriptnames_slash_adjust();
+ }
+#endif
+
+ /* If 'wrap' is set, set w_leftcol to zero. */
+ else if ((int *)varp == &curwin->w_p_wrap) {
+ if (curwin->w_p_wrap)
+ curwin->w_leftcol = 0;
+ } else if ((int *)varp == &p_ea) {
+ if (p_ea && !old_value)
+ win_equal(curwin, FALSE, 0);
+ } else if ((int *)varp == &p_wiv) {
+ /*
+ * When 'weirdinvert' changed, set/reset 't_xs'.
+ * Then set 'weirdinvert' according to value of 't_xs'.
+ */
+ if (p_wiv && !old_value)
+ T_XS = (char_u *)"y";
+ else if (!p_wiv && old_value)
+ T_XS = empty_option;
+ p_wiv = (*T_XS != NUL);
+ } else if ((int *)varp == &p_acd) {
+ /* Change directories when the 'acd' option is set now. */
+ DO_AUTOCHDIR
+ }
+ /* 'diff' */
+ else if ((int *)varp == &curwin->w_p_diff) {
+ /* May add or remove the buffer from the list of diff buffers. */
+ diff_buf_adjust(curwin);
+ if (foldmethodIsDiff(curwin))
+ foldUpdateAll(curwin);
+ }
+
+#ifdef USE_IM_CONTROL
+ /* 'imdisable' */
+ else if ((int *)varp == &p_imdisable) {
+ /* Only de-activate it here, it will be enabled when changing mode. */
+ if (p_imdisable)
+ im_set_active(FALSE);
+ else if (State & INSERT)
+ /* When the option is set from an autocommand, it may need to take
+ * effect right away. */
+ im_set_active(curbuf->b_p_iminsert == B_IMODE_IM);
+ }
+#endif
+
+ /* 'spell' */
+ else if ((int *)varp == &curwin->w_p_spell) {
+ if (curwin->w_p_spell) {
+ char_u *errmsg = did_set_spelllang(curwin);
+ if (errmsg != NULL)
+ EMSG(_(errmsg));
+ }
+ } else if ((int *)varp == &p_altkeymap) {
+ if (old_value != p_altkeymap) {
+ if (!p_altkeymap) {
+ p_hkmap = p_fkmap;
+ p_fkmap = 0;
+ } else {
+ p_fkmap = p_hkmap;
+ p_hkmap = 0;
+ }
+ (void)init_chartab();
+ }
+ }
+
+ /*
+ * In case some second language keymapping options have changed, check
+ * and correct the setting in a consistent way.
+ */
+
+ /*
+ * If hkmap or fkmap are set, reset Arabic keymapping.
+ */
+ if ((p_hkmap || p_fkmap) && p_altkeymap) {
+ p_altkeymap = p_fkmap;
+ curwin->w_p_arab = FALSE;
+ (void)init_chartab();
+ }
+
+ /*
+ * If hkmap set, reset Farsi keymapping.
+ */
+ if (p_hkmap && p_altkeymap) {
+ p_altkeymap = 0;
+ p_fkmap = 0;
+ curwin->w_p_arab = FALSE;
+ (void)init_chartab();
+ }
+
+ /*
+ * If fkmap set, reset Hebrew keymapping.
+ */
+ if (p_fkmap && !p_altkeymap) {
+ p_altkeymap = 1;
+ p_hkmap = 0;
+ curwin->w_p_arab = FALSE;
+ (void)init_chartab();
+ }
+
+ if ((int *)varp == &curwin->w_p_arab) {
+ if (curwin->w_p_arab) {
+ /*
+ * 'arabic' is set, handle various sub-settings.
+ */
+ if (!p_tbidi) {
+ /* set rightleft mode */
+ if (!curwin->w_p_rl) {
+ curwin->w_p_rl = TRUE;
+ changed_window_setting();
+ }
+
+ /* Enable Arabic shaping (major part of what Arabic requires) */
+ if (!p_arshape) {
+ p_arshape = TRUE;
+ redraw_later_clear();
+ }
+ }
+
+ /* Arabic requires a utf-8 encoding, inform the user if its not
+ * set. */
+ if (STRCMP(p_enc, "utf-8") != 0) {
+ 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));
+ set_vim_var_string(VV_WARNINGMSG, (char_u *)_(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);
+ p_altkeymap = 0;
+ p_hkmap = 0;
+ p_fkmap = 0;
+ (void)init_chartab();
+ } else {
+ /*
+ * 'arabic' is reset, handle various sub-settings.
+ */
+ if (!p_tbidi) {
+ /* reset rightleft mode */
+ if (curwin->w_p_rl) {
+ curwin->w_p_rl = FALSE;
+ changed_window_setting();
+ }
+
+ /* 'arabicshape' isn't reset, it is a global option and
+ * another window may still need it "on". */
+ }
+
+ /* 'delcombine' isn't reset, it is a global option and another
+ * window may still want it "on". */
+
+ /* Revert to the default keymap */
+ curbuf->b_p_iminsert = B_IMODE_NONE;
+ curbuf->b_p_imsearch = B_IMODE_USE_INSERT;
+ }
+ }
+
+
+ /*
+ * End of handling side effects for bool options.
+ */
+
+ options[opt_idx].flags |= P_WAS_SET;
+
+ comp_col(); /* in case 'ruler' or 'showcmd' changed */
+ if (curwin->w_curswant != MAXCOL
+ && (options[opt_idx].flags & (P_CURSWANT | P_RCLR)) != 0)
+ curwin->w_set_curswant = TRUE;
+ check_redraw(options[opt_idx].flags);
+
+ 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(opt_idx, varp, value, errbuf, errbuflen,
+ opt_flags)
+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 */
+{
+ char_u *errmsg = NULL;
+ long old_value = *(long *)varp;
+ long old_Rows = Rows; /* remember old Rows */
+ long old_Columns = Columns; /* remember old Columns */
+ long *pp = (long *)varp;
+
+ /* Disallow changing some options from secure mode. */
+ if ((secure
+#ifdef HAVE_SANDBOX
+ || sandbox != 0
+#endif
+ ) && (options[opt_idx].flags & P_SECURE))
+ return 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;
+ }
+
+ /*
+ * Number options that need some action when changed
+ */
+ if (pp == &p_wh || pp == &p_hh) {
+ if (p_wh < 1) {
+ errmsg = e_positive;
+ p_wh = 1;
+ }
+ if (p_wmh > p_wh) {
+ errmsg = e_winheight;
+ p_wh = p_wmh;
+ }
+ if (p_hh < 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) {
+ errmsg = e_positive;
+ p_wmh = 0;
+ }
+ if (p_wmh > p_wh) {
+ errmsg = e_winheight;
+ p_wmh = p_wh;
+ }
+ win_setminheight();
+ } else if (pp == &p_wiw) {
+ if (p_wiw < 1) {
+ errmsg = e_positive;
+ p_wiw = 1;
+ }
+ if (p_wmw > p_wiw) {
+ errmsg = e_winwidth;
+ p_wiw = p_wmw;
+ }
+
+ /* Change window width NOW */
+ if (lastwin != firstwin && curwin->w_width < p_wiw)
+ win_setwidth((int)p_wiw);
+ }
+ /* 'winminwidth' */
+ else if (pp == &p_wmw) {
+ if (p_wmw < 0) {
+ errmsg = e_positive;
+ p_wmw = 0;
+ }
+ if (p_wmw > p_wiw) {
+ errmsg = e_winwidth;
+ p_wmw = p_wiw;
+ }
+ win_setminheight();
+ }
+ /* (re)set last window status line */
+ else if (pp == &p_ls) {
+ 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;
+ newFoldLevel();
+ }
+ /* 'foldminlines' */
+ else if (pp == &curwin->w_p_fml) {
+ foldUpdateAll(curwin);
+ }
+ /* 'foldnestmax' */
+ 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 == &curbuf->b_p_ts) {
+ if (foldmethodIsIndent(curwin))
+ foldUpdateAll(curwin);
+ /* When 'shiftwidth' changes, or it's zero and 'tabstop' changes:
+ * parse 'cinoptions'. */
+ 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;
+ if (termcap_active) /* don't do this in the alternate screen */
+ showmode();
+ /* 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
+ )
+ 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)
+ 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) {
+ errmsg = e_invarg;
+ curwin->w_p_nuw = 10;
+ }
+ curwin->w_nrwidth_line_count = 0;
+ } else if (pp == &curbuf->b_p_tw) {
+ if (curbuf->b_p_tw < 0) {
+ errmsg = e_positive;
+ curbuf->b_p_tw = 0;
+ }
+ {
+ win_T *wp;
+ tabpage_T *tp;
+
+ FOR_ALL_TAB_WINDOWS(tp, wp)
+ check_colorcolumn(wp);
+ }
+ }
+
+ /*
+ * Check the bounds for numeric options here
+ */
+ if (Rows < min_rows() && full_screen) {
+ if (errbuf != NULL) {
+ vim_snprintf((char *)errbuf, errbuflen,
+ _("E593: Need at least %d lines"), min_rows());
+ errmsg = errbuf;
+ }
+ Rows = min_rows();
+ }
+ if (Columns < MIN_COLUMNS && full_screen) {
+ if (errbuf != NULL) {
+ vim_snprintf((char *)errbuf, errbuflen,
+ _("E594: Need at least %d columns"), MIN_COLUMNS);
+ errmsg = errbuf;
+ }
+ Columns = MIN_COLUMNS;
+ }
+ limit_screen_size();
+
+
+ /*
+ * 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. */
+ if (updating_screen)
+ *pp = old_value;
+ else if (full_screen
+ )
+ set_shellsize((int)Columns, (int)Rows, TRUE);
+ else {
+ /* Postpone the resizing; check the size and cmdline position for
+ * messages. */
+ check_shellsize();
+ if (cmdline_row > Rows - p_ch && Rows > p_ch)
+ cmdline_row = Rows - p_ch;
+ }
+ if (p_window >= Rows || !option_was_set((char_u *)"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))
+ && full_screen) {
+ if (pp == &(curwin->w_p_scr)) {
+ if (curwin->w_p_scr != 0)
+ errmsg = e_scroll;
+ win_comp_scroll(curwin);
+ }
+ /* If 'scroll' became invalid because of a side effect silently adjust
+ * it. */
+ else if (curwin->w_p_scr <= 0)
+ curwin->w_p_scr = 1;
+ 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;
+ }
+ 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;
+ else {
+ errmsg = e_scroll;
+ 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)
+ *(long *)get_varp_scope(&(options[opt_idx]), OPT_GLOBAL) = *pp;
+
+ options[opt_idx].flags |= P_WAS_SET;
+
+ comp_col(); /* in case 'columns' or 'ls' changed */
+ if (curwin->w_curswant != MAXCOL
+ && (options[opt_idx].flags & (P_CURSWANT | P_RCLR)) != 0)
+ curwin->w_set_curswant = TRUE;
+ check_redraw(options[opt_idx].flags);
+
+ return errmsg;
+}
+
+/*
+ * Called after an option changed: check if something needs to be redrawn.
+ */
+static void check_redraw(flags)
+long_u flags;
+{
+ /* Careful: P_RCLR and P_RALL are a combination of other P_ flags */
+ int doclear = (flags & P_RCLR) == P_RCLR;
+ int all = ((flags & P_RALL) == P_RALL || doclear);
+
+ if ((flags & P_RSTAT) || all) /* mark all status lines dirty */
+ status_redraw_all();
+
+ if ((flags & P_RBUF) || (flags & P_RWIN) || all)
+ changed_window_setting();
+ if (flags & P_RBUF)
+ redraw_curbuf_later(NOT_VALID);
+ if (doclear)
+ redraw_all_later(CLEAR);
+ else if (all)
+ redraw_all_later(NOT_VALID);
+}
+
+/*
+ * Find index for option 'arg'.
+ * Return -1 if not found.
+ */
+static int findoption(arg)
+char_u *arg;
+{
+ int opt_idx;
+ char *s, *p;
+ static short 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.
+ */
+ if (quick_tab[1] == 0) {
+ p = options[0].fullname;
+ for (opt_idx = 1; (s = options[opt_idx].fullname) != NULL; opt_idx++) {
+ if (s[0] != p[0]) {
+ if (s[0] == 't' && s[1] == '_')
+ quick_tab[26] = opt_idx;
+ else
+ quick_tab[CharOrdLow(s[0])] = opt_idx;
+ }
+ p = s;
+ }
+ }
+
+ /*
+ * Check for name starting with an illegal character.
+ */
+ if (arg[0] < 'a' || arg[0] > 'z')
+ return -1;
+
+ is_term_opt = (arg[0] == 't' && arg[1] == '_');
+ if (is_term_opt)
+ opt_idx = quick_tab[26];
+ else
+ opt_idx = quick_tab[CharOrdLow(arg[0])];
+ for (; (s = options[opt_idx].fullname) != NULL; opt_idx++) {
+ if (STRCMP(arg, s) == 0) /* match full name */
+ break;
+ }
+ if (s == NULL && !is_term_opt) {
+ opt_idx = quick_tab[CharOrdLow(arg[0])];
+ for (; options[opt_idx].fullname != NULL; opt_idx++) {
+ s = options[opt_idx].shortname;
+ if (s != NULL && STRCMP(arg, s) == 0) /* match short name */
+ break;
+ s = NULL;
+ }
+ }
+ if (s == NULL)
+ opt_idx = -1;
+ return opt_idx;
+}
+
+/*
+ * 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(name, numval, stringval, opt_flags)
+char_u *name;
+long *numval;
+char_u **stringval; /* NULL when only checking existence */
+int opt_flags;
+{
+ int opt_idx;
+ char_u *varp;
+
+ opt_idx = findoption(name);
+ if (opt_idx < 0) /* unknown option */
+ return -3;
+
+ varp = get_varp_scope(&(options[opt_idx]), opt_flags);
+
+ if (options[opt_idx].flags & P_STRING) {
+ if (varp == NULL) /* hidden option */
+ return -2;
+ if (stringval != NULL) {
+ /* never return the value of the crypt key */
+ if ((char_u **)varp == &curbuf->b_p_key
+ && **(char_u **)(varp) != NUL)
+ *stringval = vim_strsave((char_u *)"*****");
+ else
+ *stringval = vim_strsave(*(char_u **)(varp));
+ }
+ return 0;
+ }
+
+ if (varp == NULL) /* hidden option */
+ return -1;
+ 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 ((int *)varp == &curbuf->b_changed)
+ *numval = curbufIsChanged();
+ else
+ *numval = *(int *)varp;
+ }
+ return 1;
+}
+
+
+/*
+ * 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(name, number, string, opt_flags)
+char_u *name;
+long number;
+char_u *string;
+int opt_flags; /* OPT_LOCAL or 0 (both) */
+{
+ int opt_idx;
+ char_u *varp;
+ long_u flags;
+
+ opt_idx = findoption(name);
+ if (opt_idx < 0)
+ EMSG2(_("E355: Unknown option: %s"), name);
+ else {
+ flags = options[opt_idx].flags;
+#ifdef HAVE_SANDBOX
+ /* Disallow changing some options in the sandbox */
+ if (sandbox > 0 && (flags & P_SECURE)) {
+ EMSG(_(e_sandbox));
+ return NULL;
+ }
+#endif
+ if (flags & P_STRING)
+ return set_string_option(opt_idx, string, opt_flags);
+ else {
+ varp = get_varp_scope(&(options[opt_idx]), opt_flags);
+ if (varp != NULL) { /* hidden option is not changed */
+ if (number == 0 && string != NULL) {
+ int idx;
+
+ /* Either we are given a string or we are setting option
+ * to zero. */
+ for (idx = 0; string[idx] == '0'; ++idx)
+ ;
+ if (string[idx] != NUL || idx == 0) {
+ /* 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. */
+ EMSG3(_("E521: Number required: &%s = '%s'"),
+ name, string);
+ 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);
+ }
+ }
+ }
+ return NULL;
+}
+
+/*
+ * Get the terminal code for a terminal option.
+ * Returns NULL when not found.
+ */
+char_u * get_term_code(tname)
+char_u *tname;
+{
+ int opt_idx;
+ char_u *varp;
+
+ if (tname[0] != 't' || tname[1] != '_' ||
+ tname[2] == NUL || tname[3] == NUL)
+ return NULL;
+ if ((opt_idx = findoption(tname)) >= 0) {
+ varp = get_varp(&(options[opt_idx]));
+ if (varp != NULL)
+ varp = *(char_u **)(varp);
+ return varp;
+ }
+ return find_termcode(tname + 2);
+}
+
+char_u * get_highlight_default() {
+ int i;
+
+ i = findoption((char_u *)"hl");
+ if (i >= 0)
+ return options[i].def_val[VI_DEFAULT];
+ return (char_u *)NULL;
+}
+
+char_u * get_encoding_default() {
+ int i;
+
+ i = findoption((char_u *)"enc");
+ 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.
+ */
+static int find_key_option(arg)
+char_u *arg;
+{
+ int key;
+ int modifiers;
+
+ /*
+ * Don't use get_special_key_code() for t_xx, we don't want it to call
+ * add_termcap_entry().
+ */
+ if (arg[0] == 't' && arg[1] == '_' && arg[2] && arg[3])
+ key = TERMCAP2KEY(arg[2], arg[3]);
+ else {
+ --arg; /* put arg at the '<' */
+ modifiers = 0;
+ key = find_special_key(&arg, &modifiers, TRUE, TRUE);
+ if (modifiers) /* can't handle modifiers here */
+ key = 0;
+ }
+ return key;
+}
+
+/*
+ * if 'all' == 0: show changed options
+ * if 'all' == 1: show all normal options
+ * if 'all' == 2: show all terminal options
+ */
+static void showoptions(all, opt_flags)
+int all;
+int opt_flags; /* OPT_LOCAL and/or OPT_GLOBAL */
+{
+ struct vimoption *p;
+ int col;
+ int isterm;
+ char_u *varp;
+ struct vimoption **items;
+ int item_count;
+ int run;
+ int row, rows;
+ int cols;
+ int i;
+ int len;
+
+#define INC 20
+#define GAP 3
+
+ items = (struct vimoption **)alloc((unsigned)(sizeof(struct vimoption *) *
+ PARAM_COUNT));
+ if (items == NULL)
+ return;
+
+ /* Highlight title */
+ if (all == 2)
+ MSG_PUTS_TITLE(_("\n--- Terminal codes ---"));
+ else if (opt_flags & OPT_GLOBAL)
+ MSG_PUTS_TITLE(_("\n--- Global option values ---"));
+ else if (opt_flags & OPT_LOCAL)
+ MSG_PUTS_TITLE(_("\n--- Local option values ---"));
+ else
+ MSG_PUTS_TITLE(_("\n--- Options ---"));
+
+ /*
+ * do the loop two times:
+ * 1. display the short items
+ * 2. display the long items (only strings and numbers)
+ */
+ for (run = 1; run <= 2 && !got_int; ++run) {
+ /*
+ * collect the items in items[]
+ */
+ item_count = 0;
+ for (p = &options[0]; p->fullname != NULL; p++) {
+ varp = NULL;
+ isterm = istermoption(p);
+ if (opt_flags != 0) {
+ if (p->indir != PV_NONE && !isterm)
+ varp = get_varp_scope(p, opt_flags);
+ } else
+ varp = get_varp(p);
+ if (varp != NULL
+ && ((all == 2 && isterm)
+ || (all == 1 && !isterm)
+ || (all == 0 && !optval_default(p, varp)))) {
+ if (p->flags & P_BOOL)
+ len = 1; /* a toggle option fits always */
+ else {
+ option_value2string(p, opt_flags);
+ len = (int)STRLEN(p->fullname) + vim_strsize(NameBuff) + 1;
+ }
+ if ((len <= INC - GAP && run == 1) ||
+ (len > INC - GAP && run == 2))
+ items[item_count++] = p;
+ }
+ }
+
+ /*
+ * display the items
+ */
+ if (run == 1) {
+ cols = (Columns + GAP - 3) / INC;
+ if (cols == 0)
+ cols = 1;
+ rows = (item_count + cols - 1) / cols;
+ } else /* run == 2 */
+ rows = item_count;
+ for (row = 0; row < rows && !got_int; ++row) {
+ msg_putchar('\n'); /* go to next line */
+ if (got_int) /* 'q' typed in more */
+ break;
+ col = 0;
+ for (i = row; i < item_count; i += rows) {
+ msg_col = col; /* make columns */
+ showoneopt(items[i], opt_flags);
+ col += INC;
+ }
+ out_flush();
+ ui_breakcheck();
+ }
+ }
+ vim_free(items);
+}
+
+/*
+ * Return TRUE if option "p" has its default value.
+ */
+static int optval_default(p, varp)
+struct vimoption *p;
+char_u *varp;
+{
+ int dvi;
+
+ 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)(long_i)p->def_val[dvi];
+ if (p->flags & P_BOOL)
+ /* the cast to long is required for Manx C, long_i is
+ * needed for MSVC */
+ return *(int *)varp == (int)(long)(long_i)p->def_val[dvi];
+ /* P_STRING */
+ return STRCMP(*(char_u **)varp, p->def_val[dvi]) == 0;
+}
+
+/*
+ * showoneopt: show the value of one option
+ * must not be called with a hidden option!
+ */
+static void showoneopt(p, opt_flags)
+struct vimoption *p;
+int opt_flags; /* OPT_LOCAL or OPT_GLOBAL */
+{
+ char_u *varp;
+ int save_silent = silent_mode;
+
+ silent_mode = FALSE;
+ info_message = TRUE; /* use mch_msg(), not mch_errmsg() */
+
+ varp = get_varp_scope(p, opt_flags);
+
+ /* 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)
+ MSG_PUTS("--");
+ else
+ MSG_PUTS(" ");
+ MSG_PUTS(p->fullname);
+ if (!(p->flags & P_BOOL)) {
+ msg_putchar('=');
+ /* put value string in NameBuff */
+ option_value2string(p, opt_flags);
+ msg_outtrans(NameBuff);
+ }
+
+ silent_mode = save_silent;
+ info_message = FALSE;
+}
+
+/*
+ * Write modified options as ":set" commands to a file.
+ *
+ * There are three values for "opt_flags":
+ * OPT_GLOBAL: Write global option values and fresh values of
+ * buffer-local options (used for start of a session
+ * file).
+ * OPT_GLOBAL + OPT_LOCAL: Idem, add fresh values of window-local options for
+ * curwin (used for a vimrc file).
+ * OPT_LOCAL: Write buffer-local option values for curbuf, fresh
+ * and local values for window-local options of
+ * curwin. Local values are also written when at the
+ * default value, because a modeline or autocommand
+ * may have set them when doing ":edit file" and the
+ * user has set them back at the default or fresh
+ * value.
+ * When "local_only" is TRUE, don't write fresh
+ * values, only local values (for ":mkview").
+ * (fresh value = value used for a new buffer or window for a local option).
+ *
+ * Return FAIL on error, OK otherwise.
+ */
+int makeset(fd, opt_flags, local_only)
+FILE *fd;
+int opt_flags;
+int local_only;
+{
+ struct vimoption *p;
+ char_u *varp; /* currently used value */
+ char_u *varp_fresh; /* local value */
+ char_u *varp_local = NULL; /* fresh value */
+ char *cmd;
+ int round;
+ int pri;
+
+ /*
+ * The options that don't have a default (terminal name, columns, lines)
+ * are never written. Terminal options are also not written.
+ * Do the loop over "options[]" twice: once for options with the
+ * P_PRI_MKRC flag and once without.
+ */
+ for (pri = 1; pri >= 0; --pri) {
+ for (p = &options[0]; !istermoption(p); p++)
+ if (!(p->flags & P_NO_MKRC)
+ && !istermoption(p)
+ && ((pri == 1) == ((p->flags & P_PRI_MKRC) != 0))) {
+ /* skip global option when only doing locals */
+ if (p->indir == PV_NONE && !(opt_flags & OPT_GLOBAL))
+ continue;
+
+ /* Do not store options like 'bufhidden' and 'syntax' in a vimrc
+ * file, they are always buffer-specific. */
+ if ((opt_flags & OPT_GLOBAL) && (p->flags & P_NOGLOB))
+ continue;
+
+ /* Global values are only written when not at the default value. */
+ varp = get_varp_scope(p, opt_flags);
+ if ((opt_flags & OPT_GLOBAL) && optval_default(p, varp))
+ continue;
+
+ round = 2;
+ if (p->indir != PV_NONE) {
+ if (p->var == VAR_WIN) {
+ /* skip window-local option when only doing globals */
+ if (!(opt_flags & OPT_LOCAL))
+ continue;
+ /* When fresh value of window-local option is not at the
+ * default, need to write it too. */
+ if (!(opt_flags & OPT_GLOBAL) && !local_only) {
+ varp_fresh = get_varp_scope(p, OPT_GLOBAL);
+ if (!optval_default(p, varp_fresh)) {
+ round = 1;
+ varp_local = varp;
+ varp = varp_fresh;
+ }
+ }
+ }
+ }
+
+ /* Round 1: fresh value for window-local options.
+ * Round 2: other values */
+ for (; round <= 2; varp = varp_local, ++round) {
+ if (round == 1 || (opt_flags & OPT_GLOBAL))
+ cmd = "set";
+ else
+ cmd = "setlocal";
+
+ if (p->flags & P_BOOL) {
+ if (put_setbool(fd, cmd, p->fullname, *(int *)varp) == FAIL)
+ return FAIL;
+ } else if (p->flags & P_NUM) {
+ if (put_setnum(fd, cmd, p->fullname, (long *)varp) == FAIL)
+ return FAIL;
+ } else { /* P_STRING */
+ int do_endif = FALSE;
+
+ /* Don't set 'syntax' and 'filetype' again if the value is
+ * already right, avoids reloading the syntax file. */
+ if (
+ p->indir == PV_SYN
+ ||
+ p->indir == PV_FT
+ ) {
+ if (fprintf(fd, "if &%s != '%s'", p->fullname,
+ *(char_u **)(varp)) < 0
+ || put_eol(fd) < 0)
+ return FAIL;
+ do_endif = TRUE;
+ }
+ if (put_setstring(fd, cmd, p->fullname, (char_u **)varp,
+ (p->flags & P_EXPAND) != 0) == FAIL)
+ return FAIL;
+ if (do_endif) {
+ if (put_line(fd, "endif") == FAIL)
+ return FAIL;
+ }
+ }
+ }
+ }
+ }
+ return OK;
+}
+
+/*
+ * Generate set commands for the local fold options only. Used when
+ * 'sessionoptions' or 'viewoptions' contains "folds" but not "options".
+ */
+int makefoldset(fd)
+FILE *fd;
+{
+ if (put_setstring(fd, "setlocal", "fdm", &curwin->w_p_fdm, FALSE) == FAIL
+ || put_setstring(fd, "setlocal", "fde", &curwin->w_p_fde, FALSE)
+ == FAIL
+ || put_setstring(fd, "setlocal", "fmr", &curwin->w_p_fmr, FALSE)
+ == FAIL
+ || put_setstring(fd, "setlocal", "fdi", &curwin->w_p_fdi, FALSE)
+ == FAIL
+ || put_setnum(fd, "setlocal", "fdl", &curwin->w_p_fdl) == FAIL
+ || put_setnum(fd, "setlocal", "fml", &curwin->w_p_fml) == FAIL
+ || put_setnum(fd, "setlocal", "fdn", &curwin->w_p_fdn) == FAIL
+ || put_setbool(fd, "setlocal", "fen", curwin->w_p_fen) == FAIL
+ )
+ return FAIL;
+
+ return OK;
+}
+
+static int put_setstring(fd, cmd, name, valuep, expand)
+FILE *fd;
+char *cmd;
+char *name;
+char_u **valuep;
+int expand;
+{
+ char_u *s;
+ char_u *buf;
+
+ if (fprintf(fd, "%s %s=", cmd, name) < 0)
+ return FAIL;
+ if (*valuep != NULL) {
+ /* Output 'pastetoggle' as key names. For other
+ * options some characters have to be escaped with
+ * CTRL-V or backslash */
+ if (valuep == &p_pt) {
+ s = *valuep;
+ while (*s != NUL)
+ if (put_escstr(fd, str2special(&s, FALSE), 2) == FAIL)
+ return FAIL;
+ } else if (expand) {
+ buf = alloc(MAXPATHL);
+ if (buf == NULL)
+ return FAIL;
+ home_replace(NULL, *valuep, buf, MAXPATHL, FALSE);
+ if (put_escstr(fd, buf, 2) == FAIL) {
+ vim_free(buf);
+ return FAIL;
+ }
+ vim_free(buf);
+ } else if (put_escstr(fd, *valuep, 2) == FAIL)
+ return FAIL;
+ }
+ if (put_eol(fd) < 0)
+ return FAIL;
+ return OK;
+}
+
+static int put_setnum(fd, cmd, name, valuep)
+FILE *fd;
+char *cmd;
+char *name;
+long *valuep;
+{
+ long wc;
+
+ if (fprintf(fd, "%s %s=", cmd, name) < 0)
+ return FAIL;
+ if (wc_use_keyname((char_u *)valuep, &wc)) {
+ /* print 'wildchar' and 'wildcharm' as a key name */
+ if (fputs((char *)get_special_key_name((int)wc, 0), fd) < 0)
+ return FAIL;
+ } else if (fprintf(fd, "%ld", *valuep) < 0)
+ return FAIL;
+ if (put_eol(fd) < 0)
+ return FAIL;
+ return OK;
+}
+
+static int put_setbool(fd, cmd, name, value)
+FILE *fd;
+char *cmd;
+char *name;
+int value;
+{
+ if (value < 0) /* global/local option using global value */
+ return OK;
+ if (fprintf(fd, "%s %s%s", cmd, value ? "" : "no", name) < 0
+ || put_eol(fd) < 0)
+ return FAIL;
+ return OK;
+}
+
+/*
+ * Clear all the terminal options.
+ * If the option has been allocated, free the memory.
+ * Terminal options are never hidden or indirect.
+ */
+void clear_termoptions() {
+ /*
+ * Reset a few things before clearing the old options. This may cause
+ * outputting a few things that the terminal doesn't understand, but the
+ * screen will be cleared later, so this is OK.
+ */
+ mch_setmouse(FALSE); /* switch mouse off */
+ mch_restore_title(3); /* restore window titles */
+ stoptermcap(); /* stop termcap mode */
+
+ free_termoptions();
+}
+
+void free_termoptions() {
+ struct vimoption *p;
+
+ for (p = &options[0]; p->fullname != NULL; p++)
+ if (istermoption(p)) {
+ if (p->flags & P_ALLOCED)
+ free_string_option(*(char_u **)(p->var));
+ if (p->flags & P_DEF_ALLOCED)
+ free_string_option(p->def_val[VI_DEFAULT]);
+ *(char_u **)(p->var) = empty_option;
+ p->def_val[VI_DEFAULT] = empty_option;
+ p->flags &= ~(P_ALLOCED|P_DEF_ALLOCED);
+ }
+ clear_termcodes();
+}
+
+/*
+ * Free the string for one term option, if it was allocated.
+ * Set the string to empty_option and clear allocated flag.
+ * "var" points to the option value.
+ */
+void free_one_termoption(var)
+char_u *var;
+{
+ struct vimoption *p;
+
+ for (p = &options[0]; p->fullname != NULL; p++)
+ if (p->var == var) {
+ if (p->flags & P_ALLOCED)
+ free_string_option(*(char_u **)(p->var));
+ *(char_u **)(p->var) = empty_option;
+ p->flags &= ~P_ALLOCED;
+ break;
+ }
+}
+
+/*
+ * Set the terminal option defaults to the current value.
+ * Used after setting the terminal name.
+ */
+void set_term_defaults() {
+ struct vimoption *p;
+
+ for (p = &options[0]; p->fullname != NULL; p++) {
+ if (istermoption(p) && p->def_val[VI_DEFAULT] != *(char_u **)(p->var)) {
+ if (p->flags & P_DEF_ALLOCED) {
+ free_string_option(p->def_val[VI_DEFAULT]);
+ p->flags &= ~P_DEF_ALLOCED;
+ }
+ p->def_val[VI_DEFAULT] = *(char_u **)(p->var);
+ if (p->flags & P_ALLOCED) {
+ p->flags |= P_DEF_ALLOCED;
+ p->flags &= ~P_ALLOCED; /* don't free the value now */
+ }
+ }
+ }
+}
+
+/*
+ * return TRUE if 'p' starts with 't_'
+ */
+static int istermoption(p)
+struct vimoption *p;
+{
+ return p->fullname[0] == 't' && p->fullname[1] == '_';
+}
+
+/*
+ * Compute columns for ruler and shown command. 'sc_col' is also used to
+ * decide what the maximum length of a message on the status line can be.
+ * If there is a status line for the last window, 'sc_col' is independent
+ * of 'ru_col'.
+ */
+
+#define COL_RULER 17 /* columns needed by standard ruler */
+
+void comp_col() {
+ int last_has_status = (p_ls == 2 || (p_ls == 1 && firstwin != lastwin));
+
+ sc_col = 0;
+ ru_col = 0;
+ if (p_ru) {
+ ru_col = (ru_wid ? ru_wid : COL_RULER) + 1;
+ /* no last status line, adjust sc_col */
+ if (!last_has_status)
+ sc_col = ru_col;
+ }
+ if (p_sc) {
+ sc_col += SHOWCMD_COLS;
+ if (!p_ru || last_has_status) /* no need for separating space */
+ ++sc_col;
+ }
+ sc_col = Columns - sc_col;
+ ru_col = Columns - ru_col;
+ if (sc_col <= 0) /* screen too narrow, will become a mess */
+ sc_col = 1;
+ if (ru_col <= 0)
+ ru_col = 1;
+}
+
+/*
+ * Unset local option value, similar to ":set opt<".
+ */
+void unset_global_local_option(name, from)
+char_u *name;
+void *from;
+{
+ struct vimoption *p;
+ int opt_idx;
+ buf_T *buf = (buf_T *)from;
+
+ opt_idx = findoption(name);
+ p = &(options[opt_idx]);
+
+ switch ((int)p->indir) {
+ /* global option with local value: use local value if it's been set */
+ case PV_EP:
+ clear_string_option(&buf->b_p_ep);
+ break;
+ case PV_KP:
+ clear_string_option(&buf->b_p_kp);
+ break;
+ case PV_PATH:
+ clear_string_option(&buf->b_p_path);
+ break;
+ case PV_AR:
+ buf->b_p_ar = -1;
+ break;
+ case PV_TAGS:
+ clear_string_option(&buf->b_p_tags);
+ break;
+ case PV_DEF:
+ clear_string_option(&buf->b_p_def);
+ break;
+ case PV_INC:
+ clear_string_option(&buf->b_p_inc);
+ break;
+ case PV_DICT:
+ clear_string_option(&buf->b_p_dict);
+ break;
+ case PV_TSR:
+ clear_string_option(&buf->b_p_tsr);
+ break;
+ case PV_EFM:
+ clear_string_option(&buf->b_p_efm);
+ break;
+ case PV_GP:
+ clear_string_option(&buf->b_p_gp);
+ break;
+ case PV_MP:
+ clear_string_option(&buf->b_p_mp);
+ break;
+ case PV_CM:
+ clear_string_option(&buf->b_p_cm);
+ break;
+ case PV_STL:
+ clear_string_option(&((win_T *)from)->w_p_stl);
+ break;
+ case PV_UL:
+ buf->b_p_ul = NO_LOCAL_UNDOLEVEL;
+ break;
+ }
+}
+
+/*
+ * Get pointer to option variable, depending on local or global scope.
+ */
+static char_u * get_varp_scope(p, opt_flags)
+struct vimoption *p;
+int opt_flags;
+{
+ if ((opt_flags & OPT_GLOBAL) && p->indir != PV_NONE) {
+ if (p->var == VAR_WIN)
+ return (char_u *)GLOBAL_WO(get_varp(p));
+ return p->var;
+ }
+ if ((opt_flags & OPT_LOCAL) && ((int)p->indir & PV_BOTH)) {
+ switch ((int)p->indir) {
+ 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);
+ case PV_EP: return (char_u *)&(curbuf->b_p_ep);
+ case PV_KP: return (char_u *)&(curbuf->b_p_kp);
+ case PV_PATH: return (char_u *)&(curbuf->b_p_path);
+ case PV_AR: return (char_u *)&(curbuf->b_p_ar);
+ case PV_TAGS: return (char_u *)&(curbuf->b_p_tags);
+ case PV_DEF: return (char_u *)&(curbuf->b_p_def);
+ case PV_INC: return (char_u *)&(curbuf->b_p_inc);
+ case PV_DICT: return (char_u *)&(curbuf->b_p_dict);
+ case PV_TSR: return (char_u *)&(curbuf->b_p_tsr);
+ case PV_CM: return (char_u *)&(curbuf->b_p_cm);
+ case PV_STL: return (char_u *)&(curwin->w_p_stl);
+ case PV_UL: return (char_u *)&(curbuf->b_p_ul);
+ }
+ return NULL; /* "cannot happen" */
+ }
+ return get_varp(p);
+}
+
+/*
+ * Get pointer to option variable.
+ */
+static char_u * get_varp(p)
+struct vimoption *p;
+{
+ /* hidden option, always return NULL */
+ if (p->var == NULL)
+ return NULL;
+
+ switch ((int)p->indir) {
+ case PV_NONE: return p->var;
+
+ /* global option with local value: use local value if it's been set */
+ case PV_EP: return *curbuf->b_p_ep != NUL
+ ? (char_u *)&curbuf->b_p_ep : p->var;
+ case PV_KP: return *curbuf->b_p_kp != NUL
+ ? (char_u *)&curbuf->b_p_kp : p->var;
+ case PV_PATH: return *curbuf->b_p_path != NUL
+ ? (char_u *)&(curbuf->b_p_path) : p->var;
+ case PV_AR: return curbuf->b_p_ar >= 0
+ ? (char_u *)&(curbuf->b_p_ar) : p->var;
+ case PV_TAGS: return *curbuf->b_p_tags != NUL
+ ? (char_u *)&(curbuf->b_p_tags) : p->var;
+ case PV_DEF: return *curbuf->b_p_def != NUL
+ ? (char_u *)&(curbuf->b_p_def) : p->var;
+ case PV_INC: return *curbuf->b_p_inc != NUL
+ ? (char_u *)&(curbuf->b_p_inc) : p->var;
+ case PV_DICT: return *curbuf->b_p_dict != NUL
+ ? (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_EFM: return *curbuf->b_p_efm != NUL
+ ? (char_u *)&(curbuf->b_p_efm) : p->var;
+ case PV_GP: return *curbuf->b_p_gp != NUL
+ ? (char_u *)&(curbuf->b_p_gp) : p->var;
+ case PV_MP: return *curbuf->b_p_mp != NUL
+ ? (char_u *)&(curbuf->b_p_mp) : p->var;
+ case PV_CM: return *curbuf->b_p_cm != NUL
+ ? (char_u *)&(curbuf->b_p_cm) : p->var;
+ case PV_STL: return *curwin->w_p_stl != NUL
+ ? (char_u *)&(curwin->w_p_stl) : p->var;
+ case PV_UL: return curbuf->b_p_ul != NO_LOCAL_UNDOLEVEL
+ ? (char_u *)&(curbuf->b_p_ul) : p->var;
+
+ case PV_ARAB: return (char_u *)&(curwin->w_p_arab);
+ case PV_LIST: return (char_u *)&(curwin->w_p_list);
+ case PV_SPELL: return (char_u *)&(curwin->w_p_spell);
+ case PV_CUC: return (char_u *)&(curwin->w_p_cuc);
+ case PV_CUL: return (char_u *)&(curwin->w_p_cul);
+ case PV_CC: return (char_u *)&(curwin->w_p_cc);
+ case PV_DIFF: return (char_u *)&(curwin->w_p_diff);
+ case PV_FDC: return (char_u *)&(curwin->w_p_fdc);
+ case PV_FEN: return (char_u *)&(curwin->w_p_fen);
+ case PV_FDI: return (char_u *)&(curwin->w_p_fdi);
+ case PV_FDL: return (char_u *)&(curwin->w_p_fdl);
+ case PV_FDM: return (char_u *)&(curwin->w_p_fdm);
+ case PV_FML: return (char_u *)&(curwin->w_p_fml);
+ case PV_FDN: return (char_u *)&(curwin->w_p_fdn);
+ case PV_FDE: return (char_u *)&(curwin->w_p_fde);
+ case PV_FDT: return (char_u *)&(curwin->w_p_fdt);
+ case PV_FMR: return (char_u *)&(curwin->w_p_fmr);
+ case PV_NU: return (char_u *)&(curwin->w_p_nu);
+ case PV_RNU: return (char_u *)&(curwin->w_p_rnu);
+ case PV_NUW: return (char_u *)&(curwin->w_p_nuw);
+ case PV_WFH: return (char_u *)&(curwin->w_p_wfh);
+ case PV_WFW: return (char_u *)&(curwin->w_p_wfw);
+ case PV_PVW: return (char_u *)&(curwin->w_p_pvw);
+ case PV_RL: return (char_u *)&(curwin->w_p_rl);
+ case PV_RLC: return (char_u *)&(curwin->w_p_rlc);
+ case PV_SCROLL: return (char_u *)&(curwin->w_p_scr);
+ case PV_WRAP: return (char_u *)&(curwin->w_p_wrap);
+ case PV_LBR: return (char_u *)&(curwin->w_p_lbr);
+ case PV_SCBIND: return (char_u *)&(curwin->w_p_scb);
+ case PV_CRBIND: return (char_u *)&(curwin->w_p_crb);
+ case PV_COCU: return (char_u *)&(curwin->w_p_cocu);
+ case PV_COLE: return (char_u *)&(curwin->w_p_cole);
+
+ case PV_AI: return (char_u *)&(curbuf->b_p_ai);
+ case PV_BIN: return (char_u *)&(curbuf->b_p_bin);
+ case PV_BOMB: return (char_u *)&(curbuf->b_p_bomb);
+ 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_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);
+ case PV_CINO: return (char_u *)&(curbuf->b_p_cino);
+ case PV_CINW: return (char_u *)&(curbuf->b_p_cinw);
+ case PV_COM: return (char_u *)&(curbuf->b_p_com);
+ case PV_CMS: return (char_u *)&(curbuf->b_p_cms);
+ case PV_CPT: return (char_u *)&(curbuf->b_p_cpt);
+ case PV_CFU: return (char_u *)&(curbuf->b_p_cfu);
+ case PV_OFU: return (char_u *)&(curbuf->b_p_ofu);
+ case PV_EOL: return (char_u *)&(curbuf->b_p_eol);
+ case PV_ET: return (char_u *)&(curbuf->b_p_et);
+ case PV_FENC: return (char_u *)&(curbuf->b_p_fenc);
+ case PV_FF: return (char_u *)&(curbuf->b_p_ff);
+ case PV_FT: return (char_u *)&(curbuf->b_p_ft);
+ case PV_FO: return (char_u *)&(curbuf->b_p_fo);
+ case PV_FLP: return (char_u *)&(curbuf->b_p_flp);
+ case PV_IMI: return (char_u *)&(curbuf->b_p_iminsert);
+ case PV_IMS: return (char_u *)&(curbuf->b_p_imsearch);
+ case PV_INF: return (char_u *)&(curbuf->b_p_inf);
+ case PV_ISK: return (char_u *)&(curbuf->b_p_isk);
+ case PV_INEX: return (char_u *)&(curbuf->b_p_inex);
+ case PV_INDE: return (char_u *)&(curbuf->b_p_inde);
+ case PV_INDK: return (char_u *)&(curbuf->b_p_indk);
+ case PV_FEX: return (char_u *)&(curbuf->b_p_fex);
+ case PV_KEY: return (char_u *)&(curbuf->b_p_key);
+ case PV_LISP: return (char_u *)&(curbuf->b_p_lisp);
+ case PV_ML: return (char_u *)&(curbuf->b_p_ml);
+ case PV_MPS: return (char_u *)&(curbuf->b_p_mps);
+ case PV_MA: return (char_u *)&(curbuf->b_p_ma);
+ case PV_MOD: return (char_u *)&(curbuf->b_changed);
+ case PV_NF: return (char_u *)&(curbuf->b_p_nf);
+ 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_SI: return (char_u *)&(curbuf->b_p_si);
+#ifndef SHORT_FNAME
+ case PV_SN: return (char_u *)&(curbuf->b_p_sn);
+#endif
+ case PV_STS: return (char_u *)&(curbuf->b_p_sts);
+ case PV_SUA: return (char_u *)&(curbuf->b_p_sua);
+ case PV_SWF: return (char_u *)&(curbuf->b_p_swf);
+ case PV_SMC: return (char_u *)&(curbuf->b_p_smc);
+ case PV_SYN: return (char_u *)&(curbuf->b_p_syn);
+ case PV_SPC: return (char_u *)&(curwin->w_s->b_p_spc);
+ case PV_SPF: return (char_u *)&(curwin->w_s->b_p_spf);
+ case PV_SPL: return (char_u *)&(curwin->w_s->b_p_spl);
+ case PV_SW: return (char_u *)&(curbuf->b_p_sw);
+ case PV_TS: return (char_u *)&(curbuf->b_p_ts);
+ case PV_TW: return (char_u *)&(curbuf->b_p_tw);
+ case PV_TX: return (char_u *)&(curbuf->b_p_tx);
+ 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"));
+ }
+ /* always return a valid pointer to avoid a crash! */
+ return (char_u *)&(curbuf->b_p_wm);
+}
+
+/*
+ * Get the value of 'equalprg', either the buffer-local one or the global one.
+ */
+char_u * get_equalprg() {
+ if (*curbuf->b_p_ep == NUL)
+ return p_ep;
+ return curbuf->b_p_ep;
+}
+
+/*
+ * Copy options from one window to another.
+ * Used when splitting a window.
+ */
+void win_copy_options(wp_from, wp_to)
+win_T *wp_from;
+win_T *wp_to;
+{
+ copy_winopt(&wp_from->w_onebuf_opt, &wp_to->w_onebuf_opt);
+ copy_winopt(&wp_from->w_allbuf_opt, &wp_to->w_allbuf_opt);
+ /* Is this right? */
+ wp_to->w_farsi = wp_from->w_farsi;
+}
+
+/*
+ * Copy the options from one winopt_T to another.
+ * Doesn't free the old option values in "to", use clear_winopt() for that.
+ * The 'scroll' option is not copied, because it depends on the window height.
+ * The 'previewwindow' option is reset, there can be only one preview window.
+ */
+void copy_winopt(from, to)
+winopt_T *from;
+winopt_T *to;
+{
+ to->wo_arab = from->wo_arab;
+ to->wo_list = from->wo_list;
+ to->wo_nu = from->wo_nu;
+ to->wo_rnu = from->wo_rnu;
+ to->wo_nuw = from->wo_nuw;
+ to->wo_rl = from->wo_rl;
+ to->wo_rlc = vim_strsave(from->wo_rlc);
+ to->wo_stl = vim_strsave(from->wo_stl);
+ to->wo_wrap = from->wo_wrap;
+ to->wo_wrap_save = from->wo_wrap_save;
+ to->wo_lbr = from->wo_lbr;
+ to->wo_scb = from->wo_scb;
+ to->wo_scb_save = from->wo_scb_save;
+ to->wo_crb = from->wo_crb;
+ to->wo_crb_save = from->wo_crb_save;
+ to->wo_spell = from->wo_spell;
+ to->wo_cuc = from->wo_cuc;
+ to->wo_cul = from->wo_cul;
+ to->wo_cc = vim_strsave(from->wo_cc);
+ to->wo_diff = from->wo_diff;
+ to->wo_diff_saved = from->wo_diff_saved;
+ to->wo_cocu = vim_strsave(from->wo_cocu);
+ to->wo_cole = from->wo_cole;
+ to->wo_fdc = from->wo_fdc;
+ to->wo_fdc_save = from->wo_fdc_save;
+ to->wo_fen = from->wo_fen;
+ to->wo_fen_save = from->wo_fen_save;
+ to->wo_fdi = vim_strsave(from->wo_fdi);
+ to->wo_fml = from->wo_fml;
+ to->wo_fdl = from->wo_fdl;
+ to->wo_fdl_save = from->wo_fdl_save;
+ to->wo_fdm = vim_strsave(from->wo_fdm);
+ to->wo_fdm_save = from->wo_diff_saved
+ ? vim_strsave(from->wo_fdm_save) : empty_option;
+ to->wo_fdn = from->wo_fdn;
+ 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 */
+}
+
+/*
+ * Check string options in a window for a NULL value.
+ */
+void check_win_options(win)
+win_T *win;
+{
+ check_winopt(&win->w_onebuf_opt);
+ check_winopt(&win->w_allbuf_opt);
+}
+
+/*
+ * Check for NULL pointers in a winopt_T and replace them with empty_option.
+ */
+void check_winopt(wop)
+winopt_T *wop UNUSED;
+{
+ check_string_option(&wop->wo_fdi);
+ check_string_option(&wop->wo_fdm);
+ check_string_option(&wop->wo_fdm_save);
+ check_string_option(&wop->wo_fde);
+ check_string_option(&wop->wo_fdt);
+ check_string_option(&wop->wo_fmr);
+ check_string_option(&wop->wo_rlc);
+ check_string_option(&wop->wo_stl);
+ check_string_option(&wop->wo_cc);
+ check_string_option(&wop->wo_cocu);
+}
+
+/*
+ * Free the allocated memory inside a winopt_T.
+ */
+void clear_winopt(wop)
+winopt_T *wop UNUSED;
+{
+ clear_string_option(&wop->wo_fdi);
+ clear_string_option(&wop->wo_fdm);
+ clear_string_option(&wop->wo_fdm_save);
+ clear_string_option(&wop->wo_fde);
+ clear_string_option(&wop->wo_fdt);
+ clear_string_option(&wop->wo_fmr);
+ clear_string_option(&wop->wo_rlc);
+ clear_string_option(&wop->wo_stl);
+ clear_string_option(&wop->wo_cc);
+ clear_string_option(&wop->wo_cocu);
+}
+
+/*
+ * Copy global option values to local options for one buffer.
+ * Used when creating a new buffer and sometimes when entering a buffer.
+ * flags:
+ * BCO_ENTER We will enter the buf buffer.
+ * BCO_ALWAYS Always copy the options, but only set b_p_initialized when
+ * appropriate.
+ * BCO_NOHELP Don't copy the values to a help buffer.
+ */
+void buf_copy_options(buf, flags)
+buf_T *buf;
+int flags;
+{
+ int should_copy = TRUE;
+ char_u *save_p_isk = NULL; /* init for GCC */
+ int dont_do_help;
+ 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.
+ */
+ if (p_cpo != NULL) {
+ /*
+ * Always copy when entering and 'cpo' contains 'S'.
+ * Don't copy when already initialized.
+ * Don't copy when 'cpo' contains 's' and not entering.
+ * 'S' BCO_ENTER initialized 's' should_copy
+ * yes yes X X TRUE
+ * yes no yes X FALSE
+ * no X yes X FALSE
+ * X no no yes FALSE
+ * X no no no TRUE
+ * no yes no X TRUE
+ */
+ if ((vim_strchr(p_cpo, CPO_BUFOPTGLOB) == NULL || !(flags & BCO_ENTER))
+ && (buf->b_p_initialized
+ || (!(flags & BCO_ENTER)
+ && vim_strchr(p_cpo, CPO_BUFOPT) != NULL)))
+ should_copy = FALSE;
+
+ if (should_copy || (flags & BCO_ALWAYS)) {
+ /* Don't copy the options specific to a help buffer when
+ * BCO_NOHELP is given or the options were initialized already
+ * (jumping back to a help file with CTRL-T or CTRL-O) */
+ dont_do_help = ((flags & BCO_NOHELP) && buf->b_help)
+ || buf->b_p_initialized;
+ if (dont_do_help) { /* don't free b_p_isk */
+ save_p_isk = buf->b_p_isk;
+ buf->b_p_isk = NULL;
+ }
+ /*
+ * Always free the allocated strings.
+ * If not already initialized, set 'readonly' and copy 'fileformat'.
+ */
+ if (!buf->b_p_initialized) {
+ free_buf_options(buf, TRUE);
+ buf->b_p_ro = FALSE; /* don't copy readonly */
+ buf->b_p_tx = p_tx;
+ buf->b_p_fenc = vim_strsave(p_fenc);
+ buf->b_p_ff = vim_strsave(p_ff);
+ buf->b_p_bh = empty_option;
+ buf->b_p_bt = empty_option;
+ } 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_tw = p_tw;
+ buf->b_p_tw_nopaste = p_tw_nopaste;
+ buf->b_p_tw_nobin = p_tw_nobin;
+ buf->b_p_wm = p_wm;
+ buf->b_p_wm_nopaste = p_wm_nopaste;
+ buf->b_p_wm_nobin = p_wm_nobin;
+ buf->b_p_bin = p_bin;
+ buf->b_p_bomb = p_bomb;
+ buf->b_p_et = p_et;
+ buf->b_p_et_nobin = p_et_nobin;
+ 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_cpt = vim_strsave(p_cpt);
+ buf->b_p_cfu = vim_strsave(p_cfu);
+ buf->b_p_ofu = vim_strsave(p_ofu);
+ buf->b_p_sts = p_sts;
+ buf->b_p_sts_nopaste = p_sts_nopaste;
+#ifndef SHORT_FNAME
+ buf->b_p_sn = p_sn;
+#endif
+ buf->b_p_com = vim_strsave(p_com);
+ buf->b_p_cms = vim_strsave(p_cms);
+ buf->b_p_fo = vim_strsave(p_fo);
+ buf->b_p_flp = vim_strsave(p_flp);
+ 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_ci = p_ci;
+ buf->b_p_cin = p_cin;
+ buf->b_p_cink = vim_strsave(p_cink);
+ buf->b_p_cino = vim_strsave(p_cino);
+ /* Don't copy 'filetype', it must be detected */
+ buf->b_p_ft = empty_option;
+ buf->b_p_pi = p_pi;
+ buf->b_p_cinw = vim_strsave(p_cinw);
+ buf->b_p_lisp = p_lisp;
+ /* Don't copy 'syntax', it must be set */
+ buf->b_p_syn = empty_option;
+ buf->b_p_smc = p_smc;
+ buf->b_s.b_p_spc = vim_strsave(p_spc);
+ (void)compile_cap_prog(&buf->b_s);
+ buf->b_s.b_p_spf = vim_strsave(p_spf);
+ 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_fex = vim_strsave(p_fex);
+ buf->b_p_key = vim_strsave(p_key);
+ buf->b_p_sua = vim_strsave(p_sua);
+ buf->b_p_keymap = vim_strsave(p_keymap);
+ buf->b_kmap_state |= KEYMAP_INIT;
+ /* This isn't really an option, but copying the langmap and IME
+ * state from the current buffer is better than resetting it. */
+ buf->b_p_iminsert = p_iminsert;
+ buf->b_p_imsearch = p_imsearch;
+
+ /* options that are normally global but also have a local value
+ * are not copied, start using the global value */
+ buf->b_p_ar = -1;
+ buf->b_p_ul = NO_LOCAL_UNDOLEVEL;
+ buf->b_p_gp = empty_option;
+ buf->b_p_mp = empty_option;
+ buf->b_p_efm = empty_option;
+ buf->b_p_ep = empty_option;
+ buf->b_p_kp = empty_option;
+ buf->b_p_path = empty_option;
+ buf->b_p_tags = empty_option;
+ buf->b_p_def = empty_option;
+ buf->b_p_inc = empty_option;
+ buf->b_p_inex = vim_strsave(p_inex);
+ buf->b_p_dict = empty_option;
+ buf->b_p_tsr = empty_option;
+ buf->b_p_qe = vim_strsave(p_qe);
+ buf->b_p_cm = empty_option;
+ buf->b_p_udf = p_udf;
+
+ /*
+ * Don't copy the options set by ex_help(), use the saved values,
+ * when going from a help buffer to a non-help buffer.
+ * Don't touch these at all when BCO_NOHELP is used and going from
+ * or to a help buffer.
+ */
+ if (dont_do_help)
+ buf->b_p_isk = save_p_isk;
+ else {
+ buf->b_p_isk = vim_strsave(p_isk);
+ did_isk = TRUE;
+ buf->b_p_ts = p_ts;
+ buf->b_help = FALSE;
+ if (buf->b_p_bt[0] == 'h')
+ clear_string_option(&buf->b_p_bt);
+ buf->b_p_ma = p_ma;
+ }
+ }
+
+ /*
+ * When the options should be copied (ignoring BCO_ALWAYS), set the
+ * flag that indicates that the options have been initialized.
+ */
+ if (should_copy)
+ buf->b_p_initialized = TRUE;
+ }
+
+ check_buf_options(buf); /* make sure we don't have NULLs */
+ if (did_isk)
+ (void)buf_init_chartab(buf, FALSE);
+}
+
+/*
+ * Reset the 'modifiable' option and its default value.
+ */
+void reset_modifiable() {
+ 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;
+}
+
+/*
+ * Set the global value for 'iminsert' to the local value.
+ */
+void set_iminsert_global() {
+ p_iminsert = curbuf->b_p_iminsert;
+}
+
+/*
+ * Set the global value for 'imsearch' to the local value.
+ */
+void set_imsearch_global() {
+ p_imsearch = curbuf->b_p_imsearch;
+}
+
+static int expand_option_idx = -1;
+static char_u expand_option_name[5] = {'t', '_', NUL, NUL, NUL};
+static int expand_option_flags = 0;
+
+void set_context_in_set_cmd(xp, arg, opt_flags)
+expand_T *xp;
+char_u *arg;
+int opt_flags; /* OPT_GLOBAL and/or OPT_LOCAL */
+{
+ int nextchar;
+ long_u flags = 0; /* init for GCC */
+ int opt_idx = 0; /* init for GCC */
+ char_u *p;
+ char_u *s;
+ int is_term_option = FALSE;
+ int key;
+
+ expand_option_flags = opt_flags;
+
+ xp->xp_context = EXPAND_SETTINGS;
+ if (*arg == NUL) {
+ xp->xp_pattern = arg;
+ return;
+ }
+ p = arg + STRLEN(arg) - 1;
+ if (*p == ' ' && *(p - 1) != '\\') {
+ xp->xp_pattern = p + 1;
+ return;
+ }
+ while (p > arg) {
+ s = p;
+ /* count number of backslashes before ' ' or ',' */
+ if (*p == ' ' || *p == ',') {
+ while (s > arg && *(s - 1) == '\\')
+ --s;
+ }
+ /* break at a space with an even number of backslashes */
+ if (*p == ' ' && ((p - s) & 1) == 0) {
+ ++p;
+ break;
+ }
+ --p;
+ }
+ if (STRNCMP(p, "no", 2) == 0 && STRNCMP(p, "novice", 6) != 0) {
+ xp->xp_context = EXPAND_BOOL_SETTINGS;
+ p += 2;
+ }
+ if (STRNCMP(p, "inv", 3) == 0) {
+ xp->xp_context = EXPAND_BOOL_SETTINGS;
+ p += 3;
+ }
+ xp->xp_pattern = arg = p;
+ if (*arg == '<') {
+ while (*p != '>')
+ if (*p++ == NUL) /* expand terminal option name */
+ return;
+ key = get_special_key_code(arg + 1);
+ if (key == 0) { /* unknown name */
+ xp->xp_context = EXPAND_NOTHING;
+ return;
+ }
+ nextchar = *++p;
+ is_term_option = TRUE;
+ expand_option_name[2] = KEY2TERMCAP0(key);
+ expand_option_name[3] = KEY2TERMCAP1(key);
+ } else {
+ if (p[0] == 't' && p[1] == '_') {
+ p += 2;
+ if (*p != NUL)
+ ++p;
+ if (*p == NUL)
+ return; /* expand option name */
+ nextchar = *++p;
+ is_term_option = TRUE;
+ expand_option_name[2] = p[-2];
+ expand_option_name[3] = p[-1];
+ } else {
+ /* Allow * wildcard */
+ while (ASCII_ISALNUM(*p) || *p == '_' || *p == '*')
+ p++;
+ if (*p == NUL)
+ return;
+ nextchar = *p;
+ *p = NUL;
+ opt_idx = findoption(arg);
+ *p = nextchar;
+ if (opt_idx == -1 || options[opt_idx].var == NULL) {
+ xp->xp_context = EXPAND_NOTHING;
+ return;
+ }
+ flags = options[opt_idx].flags;
+ if (flags & P_BOOL) {
+ xp->xp_context = EXPAND_NOTHING;
+ return;
+ }
+ }
+ }
+ /* handle "-=" and "+=" */
+ if ((nextchar == '-' || nextchar == '+' || nextchar == '^') && p[1] == '=') {
+ ++p;
+ nextchar = '=';
+ }
+ if ((nextchar != '=' && nextchar != ':')
+ || xp->xp_context == EXPAND_BOOL_SETTINGS) {
+ xp->xp_context = EXPAND_UNSUCCESSFUL;
+ return;
+ }
+ if (xp->xp_context != EXPAND_BOOL_SETTINGS && p[1] == NUL) {
+ xp->xp_context = EXPAND_OLD_SETTING;
+ if (is_term_option)
+ expand_option_idx = -1;
+ else
+ expand_option_idx = opt_idx;
+ xp->xp_pattern = p + 1;
+ return;
+ }
+ xp->xp_context = EXPAND_NOTHING;
+ if (is_term_option || (flags & P_NUM))
+ return;
+
+ xp->xp_pattern = p + 1;
+
+ if (flags & P_EXPAND) {
+ p = options[opt_idx].var;
+ if (p == (char_u *)&p_bdir
+ || p == (char_u *)&p_dir
+ || p == (char_u *)&p_path
+ || p == (char_u *)&p_rtp
+ || p == (char_u *)&p_cdpath
+ || p == (char_u *)&p_vdir
+ ) {
+ xp->xp_context = EXPAND_DIRECTORIES;
+ if (p == (char_u *)&p_path
+ || p == (char_u *)&p_cdpath
+ )
+ xp->xp_backslash = XP_BS_THREE;
+ else
+ xp->xp_backslash = XP_BS_ONE;
+ } else {
+ xp->xp_context = EXPAND_FILES;
+ /* for 'tags' need three backslashes for a space */
+ if (p == (char_u *)&p_tags)
+ xp->xp_backslash = XP_BS_THREE;
+ else
+ xp->xp_backslash = XP_BS_ONE;
+ }
+ }
+
+ /* For an option that is a list of file names, find the start of the
+ * last file name. */
+ for (p = arg + STRLEN(arg) - 1; p > xp->xp_pattern; --p) {
+ /* count number of backslashes before ' ' or ',' */
+ if (*p == ' ' || *p == ',') {
+ s = p;
+ while (s > xp->xp_pattern && *(s - 1) == '\\')
+ --s;
+ if ((*p == ' ' && (xp->xp_backslash == XP_BS_THREE && (p - s) < 3))
+ || (*p == ',' && (flags & P_COMMA) && ((p - s) & 1) == 0)) {
+ xp->xp_pattern = p + 1;
+ break;
+ }
+ }
+
+ /* for 'spellsuggest' start at "file:" */
+ if (options[opt_idx].var == (char_u *)&p_sps
+ && STRNCMP(p, "file:", 5) == 0) {
+ xp->xp_pattern = p + 5;
+ break;
+ }
+ }
+
+ return;
+}
+
+int ExpandSettings(xp, regmatch, num_file, file)
+expand_T *xp;
+regmatch_T *regmatch;
+int *num_file;
+char_u ***file;
+{
+ int num_normal = 0; /* Nr of matching non-term-code settings */
+ int num_term = 0; /* Nr of matching terminal code settings */
+ int opt_idx;
+ int match;
+ int count = 0;
+ char_u *str;
+ int loop;
+ int is_term_opt;
+ char_u name_buf[MAX_KEY_NAME_LEN];
+ static char *(names[]) = {"all", "termcap"};
+ int ic = regmatch->rm_ic; /* remember the ignore-case flag */
+
+ /* do this loop twice:
+ * loop == 0: count the number of matching options
+ * loop == 1: copy the matching options into allocated memory
+ */
+ for (loop = 0; loop <= 1; ++loop) {
+ regmatch->rm_ic = ic;
+ if (xp->xp_context != EXPAND_BOOL_SETTINGS) {
+ for (match = 0; match < (int)(sizeof(names) / sizeof(char *));
+ ++match)
+ if (vim_regexec(regmatch, (char_u *)names[match], (colnr_T)0)) {
+ if (loop == 0)
+ num_normal++;
+ else
+ (*file)[count++] = vim_strsave((char_u *)names[match]);
+ }
+ }
+ for (opt_idx = 0; (str = (char_u *)options[opt_idx].fullname) != NULL;
+ opt_idx++) {
+ if (options[opt_idx].var == NULL)
+ continue;
+ if (xp->xp_context == EXPAND_BOOL_SETTINGS
+ && !(options[opt_idx].flags & P_BOOL))
+ continue;
+ is_term_opt = istermoption(&options[opt_idx]);
+ if (is_term_opt && num_normal > 0)
+ continue;
+ match = FALSE;
+ if (vim_regexec(regmatch, str, (colnr_T)0)
+ || (options[opt_idx].shortname != NULL
+ && vim_regexec(regmatch,
+ (char_u *)options[opt_idx].shortname, (colnr_T)0)))
+ match = TRUE;
+ else if (is_term_opt) {
+ name_buf[0] = '<';
+ name_buf[1] = 't';
+ name_buf[2] = '_';
+ name_buf[3] = str[2];
+ name_buf[4] = str[3];
+ name_buf[5] = '>';
+ name_buf[6] = NUL;
+ if (vim_regexec(regmatch, name_buf, (colnr_T)0)) {
+ match = TRUE;
+ str = name_buf;
+ }
+ }
+ if (match) {
+ if (loop == 0) {
+ if (is_term_opt)
+ num_term++;
+ else
+ num_normal++;
+ } else
+ (*file)[count++] = vim_strsave(str);
+ }
+ }
+ /*
+ * Check terminal key codes, these are not in the option table
+ */
+ if (xp->xp_context != EXPAND_BOOL_SETTINGS && num_normal == 0) {
+ for (opt_idx = 0; (str = get_termcode(opt_idx)) != NULL; opt_idx++) {
+ if (!isprint(str[0]) || !isprint(str[1]))
+ continue;
+
+ name_buf[0] = 't';
+ name_buf[1] = '_';
+ name_buf[2] = str[0];
+ name_buf[3] = str[1];
+ name_buf[4] = NUL;
+
+ match = FALSE;
+ if (vim_regexec(regmatch, name_buf, (colnr_T)0))
+ match = TRUE;
+ else {
+ name_buf[0] = '<';
+ name_buf[1] = 't';
+ name_buf[2] = '_';
+ name_buf[3] = str[0];
+ name_buf[4] = str[1];
+ name_buf[5] = '>';
+ name_buf[6] = NUL;
+
+ if (vim_regexec(regmatch, name_buf, (colnr_T)0))
+ match = TRUE;
+ }
+ if (match) {
+ if (loop == 0)
+ num_term++;
+ else
+ (*file)[count++] = vim_strsave(name_buf);
+ }
+ }
+
+ /*
+ * Check special key names.
+ */
+ regmatch->rm_ic = TRUE; /* ignore case here */
+ for (opt_idx = 0; (str = get_key_name(opt_idx)) != NULL; opt_idx++) {
+ name_buf[0] = '<';
+ STRCPY(name_buf + 1, str);
+ STRCAT(name_buf, ">");
+
+ if (vim_regexec(regmatch, name_buf, (colnr_T)0)) {
+ if (loop == 0)
+ num_term++;
+ else
+ (*file)[count++] = vim_strsave(name_buf);
+ }
+ }
+ }
+ if (loop == 0) {
+ if (num_normal > 0)
+ *num_file = num_normal;
+ else if (num_term > 0)
+ *num_file = num_term;
+ else
+ return OK;
+ *file = (char_u **)alloc((unsigned)(*num_file * sizeof(char_u *)));
+ if (*file == NULL) {
+ *file = (char_u **)"";
+ return FAIL;
+ }
+ }
+ }
+ return OK;
+}
+
+int ExpandOldSetting(num_file, file)
+int *num_file;
+char_u ***file;
+{
+ char_u *var = NULL; /* init for GCC */
+ char_u *buf;
+
+ *num_file = 0;
+ *file = (char_u **)alloc((unsigned)sizeof(char_u *));
+ if (*file == NULL)
+ return FAIL;
+
+ /*
+ * For a terminal key code expand_option_idx is < 0.
+ */
+ if (expand_option_idx < 0) {
+ var = find_termcode(expand_option_name + 2);
+ if (var == NULL)
+ expand_option_idx = findoption(expand_option_name);
+ }
+
+ if (expand_option_idx >= 0) {
+ /* put string of option value in NameBuff */
+ option_value2string(&options[expand_option_idx], expand_option_flags);
+ var = NameBuff;
+ } else if (var == NULL)
+ var = (char_u *)"";
+
+ /* A backslash is required before some characters. This is the reverse of
+ * what happens in do_set(). */
+ buf = vim_strsave_escaped(var, escape_chars);
+
+ if (buf == NULL) {
+ vim_free(*file);
+ *file = NULL;
+ return FAIL;
+ }
+
+#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))
+ 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] != '\\')))
+ STRMOVE(var, var + 1);
+#endif
+
+ *file[0] = buf;
+ *num_file = 1;
+ return OK;
+}
+
+/*
+ * Get the value for the numeric or string option *opp in a nice format into
+ * NameBuff[]. Must not be called with a hidden option!
+ */
+static void option_value2string(opp, opt_flags)
+struct vimoption *opp;
+int opt_flags; /* OPT_GLOBAL and/or OPT_LOCAL */
+{
+ char_u *varp;
+
+ varp = get_varp_scope(opp, opt_flags);
+
+ if (opp->flags & P_NUM) {
+ long wc = 0;
+
+ if (wc_use_keyname(varp, &wc))
+ STRCPY(NameBuff, get_special_key_name((int)wc, 0));
+ else if (wc != 0)
+ STRCPY(NameBuff, transchar((int)wc));
+ else
+ sprintf((char *)NameBuff, "%ld", *(long *)varp);
+ } else { /* P_STRING */
+ varp = *(char_u **)(varp);
+ if (varp == NULL) /* just in case */
+ NameBuff[0] = NUL;
+ /* don't show the actual value of 'key', only that it's set */
+ else if (opp->var == (char_u *)&p_key && *varp)
+ STRCPY(NameBuff, "*****");
+ 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
+ vim_strncpy(NameBuff, varp, MAXPATHL - 1);
+ }
+}
+
+/*
+ * Return TRUE if "varp" points to 'wildchar' or 'wildcharm' and it can be
+ * printed as a keyname.
+ * "*wcp" is set to the value of the option if it's 'wildchar' or 'wildcharm'.
+ */
+static int wc_use_keyname(varp, wcp)
+char_u *varp;
+long *wcp;
+{
+ if (((long *)varp == &p_wc) || ((long *)varp == &p_wcm)) {
+ *wcp = *(long *)varp;
+ if (IS_SPECIAL(*wcp) || find_special_key_in_table((int)*wcp) >= 0)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*
+ * Any character has an equivalent 'langmap' character. This is used for
+ * keyboards that have a special language mode that sends characters above
+ * 128 (although other characters can be translated too). The "to" field is a
+ * Vim command character. This avoids having to switch the keyboard back to
+ * ASCII mode when leaving Insert mode.
+ *
+ * langmap_mapchar[] maps any of 256 chars to an ASCII char used for Vim
+ * commands.
+ * When FEAT_MBYTE is defined langmap_mapga.ga_data is a sorted table of
+ * langmap_entry_T. This does the same as langmap_mapchar[] for characters >=
+ * 256.
+ */
+/*
+ * With multi-byte support use growarray for 'langmap' chars >= 256
+ */
+typedef struct {
+ int from;
+ int to;
+} langmap_entry_T;
+
+static garray_T langmap_mapga;
+static void langmap_set_entry __ARGS((int from, int to));
+
+/*
+ * Search for an entry in "langmap_mapga" for "from". If found set the "to"
+ * field. If not found insert a new entry at the appropriate location.
+ */
+static void langmap_set_entry(from, to)
+int from;
+int to;
+{
+ langmap_entry_T *entries = (langmap_entry_T *)(langmap_mapga.ga_data);
+ int a = 0;
+ int b = langmap_mapga.ga_len;
+
+ /* Do a binary search for an existing entry. */
+ while (a != b) {
+ int i = (a + b) / 2;
+ int d = entries[i].from - from;
+
+ if (d == 0) {
+ entries[i].to = to;
+ return;
+ }
+ if (d < 0)
+ a = i + 1;
+ else
+ b = i;
+ }
+
+ if (ga_grow(&langmap_mapga, 1) != OK)
+ return; /* out of memory */
+
+ /* insert new entry at position "a" */
+ entries = (langmap_entry_T *)(langmap_mapga.ga_data) + a;
+ mch_memmove(entries + 1, entries,
+ (langmap_mapga.ga_len - a) * sizeof(langmap_entry_T));
+ ++langmap_mapga.ga_len;
+ entries[0].from = from;
+ entries[0].to = to;
+}
+
+/*
+ * Apply 'langmap' to multi-byte character "c" and return the result.
+ */
+int langmap_adjust_mb(c)
+int c;
+{
+ langmap_entry_T *entries = (langmap_entry_T *)(langmap_mapga.ga_data);
+ int a = 0;
+ int b = langmap_mapga.ga_len;
+
+ while (a != b) {
+ int i = (a + b) / 2;
+ int d = entries[i].from - c;
+
+ if (d == 0)
+ return entries[i].to; /* found matching entry */
+ if (d < 0)
+ a = i + 1;
+ else
+ b = i;
+ }
+ return c; /* no entry found, return "c" unmodified */
+}
+
+static void langmap_init() {
+ int i;
+
+ for (i = 0; i < 256; i++)
+ langmap_mapchar[i] = i; /* we init with a one-to-one map */
+ ga_init2(&langmap_mapga, sizeof(langmap_entry_T), 8);
+}
+
+/*
+ * Called when langmap option is set; the language map can be
+ * changed at any time!
+ */
+static void langmap_set() {
+ char_u *p;
+ char_u *p2;
+ int from, to;
+
+ ga_clear(&langmap_mapga); /* clear the previous map first */
+ langmap_init(); /* back to one-to-one map */
+
+ 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;
+ }
+ if (p2[0] == ';')
+ ++p2; /* abcd;ABCD form, p2 points to A */
+ else
+ p2 = NULL; /* aAbBcCdD form, p2 is NULL */
+ while (p[0]) {
+ if (p[0] == ',') {
+ ++p;
+ break;
+ }
+ if (p[0] == '\\' && p[1] != NUL)
+ ++p;
+ from = (*mb_ptr2char)(p);
+ to = NUL;
+ if (p2 == NULL) {
+ mb_ptr_adv(p);
+ if (p[0] != ',') {
+ if (p[0] == '\\')
+ ++p;
+ to = (*mb_ptr2char)(p);
+ }
+ } else {
+ if (p2[0] != ',') {
+ if (p2[0] == '\\')
+ ++p2;
+ to = (*mb_ptr2char)(p2);
+ }
+ }
+ if (to == NUL) {
+ EMSG2(_("E357: 'langmap': Matching character missing for %s"),
+ transchar(from));
+ return;
+ }
+
+ if (from >= 256)
+ langmap_set_entry(from, to);
+ else
+ langmap_mapchar[from & 255] = to;
+
+ /* Advance to next pair */
+ mb_ptr_adv(p);
+ if (p2 != NULL) {
+ mb_ptr_adv(p2);
+ if (*p == ';') {
+ p = p2;
+ if (p[0] != NUL) {
+ if (p[0] != ',') {
+ EMSG2(_(
+ "E358: 'langmap': Extra characters after semicolon: %s"),
+ p);
+ return;
+ }
+ ++p;
+ }
+ break;
+ }
+ }
+ }
+ }
+}
+
+/*
+ * Return TRUE if format option 'x' is in effect.
+ * Take care of no formatting when 'paste' is set.
+ */
+int has_format_option(x)
+int x;
+{
+ if (p_paste)
+ return FALSE;
+ return vim_strchr(curbuf->b_p_fo, x) != NULL;
+}
+
+/*
+ * Return TRUE if "x" is present in 'shortmess' option, or
+ * 'shortmess' contains 'a' and "x" is present in SHM_A.
+ */
+int shortmess(x)
+int x;
+{
+ return p_shm != NULL &&
+ ( vim_strchr(p_shm, x) != NULL
+ || (vim_strchr(p_shm, 'a') != NULL
+ && vim_strchr((char_u *)SHM_A, x) != NULL));
+}
+
+/*
+ * paste_option_changed() - Called after p_paste was set or reset.
+ */
+static void paste_option_changed() {
+ static int old_p_paste = FALSE;
+ static int save_sm = 0;
+ static int save_ru = 0;
+ static int save_ri = 0;
+ static int save_hkmap = 0;
+ buf_T *buf;
+
+ if (p_paste) {
+ /*
+ * Paste switched from off to on.
+ * Save the current values, so they can be restored later.
+ */
+ if (!old_p_paste) {
+ /* save options for each buffer */
+ for (buf = firstbuf; buf != NULL; buf = buf->b_next) {
+ buf->b_p_tw_nopaste = buf->b_p_tw;
+ buf->b_p_wm_nopaste = buf->b_p_wm;
+ buf->b_p_sts_nopaste = buf->b_p_sts;
+ buf->b_p_ai_nopaste = buf->b_p_ai;
+ }
+
+ /* save global options */
+ save_sm = p_sm;
+ save_ru = p_ru;
+ save_ri = p_ri;
+ save_hkmap = p_hkmap;
+ /* save global values for local buffer options */
+ p_tw_nopaste = p_tw;
+ p_wm_nopaste = p_wm;
+ p_sts_nopaste = p_sts;
+ p_ai_nopaste = p_ai;
+ }
+
+ /*
+ * Always set the option values, also when 'paste' is set when it is
+ * already on.
+ */
+ /* set options for each buffer */
+ for (buf = firstbuf; buf != NULL; buf = buf->b_next) {
+ buf->b_p_tw = 0; /* textwidth is 0 */
+ buf->b_p_wm = 0; /* wrapmargin is 0 */
+ buf->b_p_sts = 0; /* softtabstop is 0 */
+ buf->b_p_ai = 0; /* no auto-indent */
+ }
+
+ /* set global options */
+ p_sm = 0; /* no showmatch */
+ if (p_ru)
+ status_redraw_all(); /* redraw to remove the ruler */
+ p_ru = 0; /* no ruler */
+ p_ri = 0; /* no reverse insert */
+ p_hkmap = 0; /* no Hebrew keyboard */
+ /* set global values for local buffer options */
+ p_tw = 0;
+ p_wm = 0;
+ p_sts = 0;
+ p_ai = 0;
+ }
+ /*
+ * Paste switched from on to off: Restore saved values.
+ */
+ else if (old_p_paste) {
+ /* restore options for each buffer */
+ for (buf = firstbuf; buf != NULL; buf = buf->b_next) {
+ buf->b_p_tw = buf->b_p_tw_nopaste;
+ buf->b_p_wm = buf->b_p_wm_nopaste;
+ buf->b_p_sts = buf->b_p_sts_nopaste;
+ buf->b_p_ai = buf->b_p_ai_nopaste;
+ }
+
+ /* restore global options */
+ p_sm = save_sm;
+ if (p_ru != save_ru)
+ status_redraw_all(); /* redraw to draw the ruler */
+ p_ru = save_ru;
+ p_ri = save_ri;
+ p_hkmap = save_hkmap;
+ /* set global values for local buffer options */
+ p_tw = p_tw_nopaste;
+ p_wm = p_wm_nopaste;
+ p_sts = p_sts_nopaste;
+ p_ai = p_ai_nopaste;
+ }
+
+ old_p_paste = p_paste;
+}
+
+/*
+ * vimrc_found() - Called when a ".vimrc" or "VIMINIT" has been found.
+ *
+ * Reset 'compatible' and set the values for options that didn't get set yet
+ * to the Vim defaults.
+ * Don't do this if the 'compatible' option has been set or reset before.
+ * When "fname" is not NULL, use it to set $"envname" when it wasn't set yet.
+ */
+void vimrc_found(fname, envname)
+char_u *fname;
+char_u *envname;
+{
+ int opt_idx;
+ int dofree = FALSE;
+ char_u *p;
+
+ if (!option_was_set((char_u *)"cp")) {
+ p_cp = FALSE;
+ for (opt_idx = 0; !istermoption(&options[opt_idx]); opt_idx++)
+ if (!(options[opt_idx].flags & (P_WAS_SET|P_VI_DEF)))
+ set_option_default(opt_idx, OPT_FREE, FALSE);
+ didset_options();
+ }
+
+ if (fname != NULL) {
+ p = vim_getenv(envname, &dofree);
+ if (p == NULL) {
+ /* Set $MYVIMRC to the first vimrc file found. */
+ p = FullName_save(fname, FALSE);
+ if (p != NULL) {
+ vim_setenv(envname, p);
+ vim_free(p);
+ }
+ } else if (dofree)
+ vim_free(p);
+ }
+}
+
+/*
+ * Set 'compatible' on or off. Called for "-C" and "-N" command line arg.
+ */
+void change_compatible(on)
+int on;
+{
+ int opt_idx;
+
+ if (p_cp != on) {
+ p_cp = on;
+ compatible_set();
+ }
+ opt_idx = findoption((char_u *)"cp");
+ if (opt_idx >= 0)
+ options[opt_idx].flags |= P_WAS_SET;
+}
+
+/*
+ * Return TRUE when option "name" has been set.
+ * Only works correctly for global options.
+ */
+int option_was_set(name)
+char_u *name;
+{
+ int idx;
+
+ idx = findoption(name);
+ if (idx < 0) /* unknown option */
+ return FALSE;
+ if (options[idx].flags & P_WAS_SET)
+ return TRUE;
+ return FALSE;
+}
+
+/*
+ * Reset the flag indicating option "name" was set.
+ */
+void reset_option_was_set(name)
+char_u *name;
+{
+ int idx = findoption(name);
+
+ if (idx >= 0)
+ options[idx].flags &= ~P_WAS_SET;
+}
+
+/*
+ * compatible_set() - Called when 'compatible' has been set or unset.
+ *
+ * When 'compatible' set: Set all relevant options (those that have the P_VIM)
+ * flag) to a Vi compatible value.
+ * When 'compatible' is unset: Set all options that have a different default
+ * for Vim (without the P_VI_DEF flag) to that default.
+ */
+static void compatible_set() {
+ int opt_idx;
+
+ for (opt_idx = 0; !istermoption(&options[opt_idx]); opt_idx++)
+ if ( ((options[opt_idx].flags & P_VIM) && p_cp)
+ || (!(options[opt_idx].flags & P_VI_DEF) && !p_cp))
+ set_option_default(opt_idx, OPT_FREE, p_cp);
+ didset_options();
+}
+
+/*
+ * fill_breakat_flags() -- called when 'breakat' changes value.
+ */
+static void fill_breakat_flags() {
+ char_u *p;
+ int i;
+
+ for (i = 0; i < 256; i++)
+ breakat_flags[i] = FALSE;
+
+ if (p_breakat != NULL)
+ for (p = p_breakat; *p; p++)
+ breakat_flags[*p] = TRUE;
+}
+
+/*
+ * Check an option that can be a range of string values.
+ *
+ * Return OK for correct value, FAIL otherwise.
+ * Empty is always OK.
+ */
+static int check_opt_strings(val, values, list)
+char_u *val;
+char **values;
+int list; /* when TRUE: accept a list of values */
+{
+ return opt_strings_flags(val, values, NULL, list);
+}
+
+/*
+ * Handle an option that can be a range of string values.
+ * Set a flag in "*flagp" for each string present.
+ *
+ * Return OK for correct value, FAIL otherwise.
+ * Empty is always OK.
+ */
+static int opt_strings_flags(val, values, flagp, list)
+char_u *val; /* new value */
+char **values; /* array of valid string values */
+unsigned *flagp;
+int list; /* when TRUE: accept a list of values */
+{
+ int i;
+ int len;
+ unsigned new_flags = 0;
+
+ while (*val) {
+ for (i = 0;; ++i) {
+ if (values[i] == NULL) /* val not found in values[] */
+ return FAIL;
+
+ len = (int)STRLEN(values[i]);
+ if (STRNCMP(values[i], val, len) == 0
+ && ((list && val[len] == ',') || val[len] == NUL)) {
+ val += len + (val[len] == ',');
+ new_flags |= (1 << i);
+ break; /* check next item in val list */
+ }
+ }
+ }
+ if (flagp != NULL)
+ *flagp = new_flags;
+
+ return OK;
+}
+
+/*
+ * Read the 'wildmode' option, fill wim_flags[].
+ */
+static int check_opt_wim() {
+ char_u new_wim_flags[4];
+ char_u *p;
+ int i;
+ int idx = 0;
+
+ for (i = 0; i < 4; ++i)
+ new_wim_flags[i] = 0;
+
+ for (p = p_wim; *p; ++p) {
+ for (i = 0; ASCII_ISALPHA(p[i]); ++i)
+ ;
+ if (p[i] != NUL && p[i] != ',' && p[i] != ':')
+ return FAIL;
+ if (i == 7 && STRNCMP(p, "longest", 7) == 0)
+ new_wim_flags[idx] |= WIM_LONGEST;
+ else if (i == 4 && STRNCMP(p, "full", 4) == 0)
+ new_wim_flags[idx] |= WIM_FULL;
+ else if (i == 4 && STRNCMP(p, "list", 4) == 0)
+ new_wim_flags[idx] |= WIM_LIST;
+ else
+ return FAIL;
+ p += i;
+ if (*p == NUL)
+ break;
+ if (*p == ',') {
+ if (idx == 3)
+ return FAIL;
+ ++idx;
+ }
+ }
+
+ /* fill remaining entries with last flag */
+ while (idx < 3) {
+ new_wim_flags[idx + 1] = new_wim_flags[idx];
+ ++idx;
+ }
+
+ /* only when there are no errors, wim_flags[] is changed */
+ for (i = 0; i < 4; ++i)
+ wim_flags[i] = new_wim_flags[i];
+ return OK;
+}
+
+/*
+ * Check if backspacing over something is allowed.
+ */
+int can_bs(what)
+int what; /* BS_INDENT, BS_EOL or BS_START */
+{
+ switch (*p_bs) {
+ case '2': return TRUE;
+ case '1': return what != BS_START;
+ case '0': return FALSE;
+ }
+ return vim_strchr(p_bs, what) != NULL;
+}
+
+/*
+ * Save the current values of 'fileformat' and 'fileencoding', so that we know
+ * the file must be considered changed when the value is different.
+ */
+void save_file_ff(buf)
+buf_T *buf;
+{
+ buf->b_start_ffc = *buf->b_p_ff;
+ buf->b_start_eol = buf->b_p_eol;
+ buf->b_start_bomb = buf->b_p_bomb;
+
+ /* Only use free/alloc when necessary, they take time. */
+ if (buf->b_start_fenc == NULL
+ || STRCMP(buf->b_start_fenc, buf->b_p_fenc) != 0) {
+ vim_free(buf->b_start_fenc);
+ buf->b_start_fenc = vim_strsave(buf->b_p_fenc);
+ }
+}
+
+/*
+ * Return TRUE if 'fileformat' and/or 'fileencoding' has a different value
+ * from when editing started (save_file_ff() called).
+ * Also when 'endofline' was changed and 'binary' is set, or when 'bomb' was
+ * changed and 'binary' is not set.
+ * When "ignore_empty" is true don't consider a new, empty buffer to be
+ * changed.
+ */
+int file_ff_differs(buf, ignore_empty)
+buf_T *buf;
+int ignore_empty;
+{
+ /* In a buffer that was never loaded the options are not valid. */
+ if (buf->b_flags & BF_NEVERLOADED)
+ return FALSE;
+ if (ignore_empty
+ && (buf->b_flags & BF_NEW)
+ && buf->b_ml.ml_line_count == 1
+ && *ml_get_buf(buf, (linenr_T)1, FALSE) == NUL)
+ return FALSE;
+ if (buf->b_start_ffc != *buf->b_p_ff)
+ return TRUE;
+ if (buf->b_p_bin && buf->b_start_eol != buf->b_p_eol)
+ return TRUE;
+ if (!buf->b_p_bin && buf->b_start_bomb != buf->b_p_bomb)
+ return TRUE;
+ if (buf->b_start_fenc == NULL)
+ return *buf->b_p_fenc != NUL;
+ return STRCMP(buf->b_start_fenc, buf->b_p_fenc) != 0;
+}
+
+/*
+ * return OK if "p" is a valid fileformat name, FAIL otherwise.
+ */
+int check_ff_value(p)
+char_u *p;
+{
+ return check_opt_strings(p, p_ff_values, FALSE);
+}
+
+/*
+ * Return the effective shiftwidth value for current buffer, using the
+ * 'tabstop' value when 'shiftwidth' is zero.
+ */
+long get_sw_value(buf)
+buf_T *buf;
+{
+ return buf->b_p_sw ? buf->b_p_sw : buf->b_p_ts;
+}
+
+/*
+ * Return the effective softtabstop value for the current buffer, using the
+ * 'tabstop' value when 'softtabstop' is negative.
+ */
+long get_sts_value() {
+ return curbuf->b_p_sts < 0 ? get_sw_value(curbuf) : curbuf->b_p_sts;
+}
+
+/*
+ * Check matchpairs option for "*initc".
+ * If there is a match set "*initc" to the matching character and "*findc" to
+ * the opposite character. Set "*backwards" to the direction.
+ * When "switchit" is TRUE swap the direction.
+ */
+void find_mps_values(initc, findc, backwards, switchit)
+int *initc;
+int *findc;
+int *backwards;
+int switchit;
+{
+ char_u *ptr;
+
+ 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;
+ }
+ ptr += 2;
+ if (*ptr == *initc) {
+ if (switchit) {
+ *backwards = FALSE;
+ *findc = *initc;
+ *initc = ptr[-2];
+ } else {
+ *backwards = TRUE;
+ *findc = ptr[-2];
+ }
+ return;
+ }
+ ++ptr;
+ }
+ if (*ptr == ',')
+ ++ptr;
+ }
+}
diff --git a/src/option.h b/src/option.h
new file mode 100644
index 0000000000..6cc0cce362
--- /dev/null
+++ b/src/option.h
@@ -0,0 +1,768 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * 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.
+ */
+
+/*
+ * option.h: definition of global variables for settable options
+ */
+
+/*
+ * Default values for 'errorformat'.
+ * The "%f|%l| %m" one is used for when the contents of the quickfix window is
+ * written to a file.
+ */
+#define DFLT_EFM \
+ "%*[^\"]\"%f\"%*\\D%l: %m,\"%f\"%*\\D%l: %m,%-G%f:%l: (Each undeclared identifier is reported only once,%-G%f:%l: for each function it appears in.),%-GIn file included from %f:%l:%c:,%-GIn file included from %f:%l:%c\\,,%-GIn file included from %f:%l:%c,%-GIn file included from %f:%l,%-G%*[ ]from %f:%l:%c,%-G%*[ ]from %f:%l:,%-G%*[ ]from %f:%l\\,,%-G%*[ ]from %f:%l,%f:%l:%c:%m,%f(%l):%m,%f:%l:%m,\"%f\"\\, line %l%*\\D%c%*[^ ] %m,%D%*\\a[%*\\d]: Entering directory %*[`']%f',%X%*\\a[%*\\d]: Leaving directory %*[`']%f',%D%*\\a: Entering directory %*[`']%f',%X%*\\a: Leaving directory %*[`']%f',%DMaking %*\\a in %f,%f|%l| %m"
+
+#define DFLT_GREPFORMAT "%f:%l:%m,%f:%l%m,%f %l%m"
+
+/* default values for b_p_ff 'fileformat' and p_ffs 'fileformats' */
+#define FF_DOS "dos"
+#define FF_MAC "mac"
+#define FF_UNIX "unix"
+
+#ifdef USE_CRNL
+# define DFLT_FF "dos"
+# define DFLT_FFS_VIM "dos,unix"
+# define DFLT_FFS_VI "dos,unix" /* also autodetect in compatible mode */
+# define DFLT_TEXTAUTO TRUE
+#else
+# ifdef USE_CR
+# define DFLT_FF "mac"
+# define DFLT_FFS_VIM "mac,unix,dos"
+# define DFLT_FFS_VI "mac,unix,dos"
+# define DFLT_TEXTAUTO TRUE
+# else
+# define DFLT_FF "unix"
+# define DFLT_FFS_VIM "unix,dos"
+# define DFLT_FFS_VI ""
+# define DFLT_TEXTAUTO FALSE
+# endif
+#endif
+
+
+/* Possible values for 'encoding' */
+# define ENC_UCSBOM "ucs-bom" /* check for BOM at start of file */
+
+/* default value for 'encoding' */
+# define ENC_DFLT "latin1"
+
+/* end-of-line style */
+#define EOL_UNKNOWN -1 /* not defined yet */
+#define EOL_UNIX 0 /* NL */
+#define EOL_DOS 1 /* CR NL */
+#define EOL_MAC 2 /* CR */
+
+/* Formatting options for p_fo 'formatoptions' */
+#define FO_WRAP 't'
+#define FO_WRAP_COMS 'c'
+#define FO_RET_COMS 'r'
+#define FO_OPEN_COMS 'o'
+#define FO_Q_COMS 'q'
+#define FO_Q_NUMBER 'n'
+#define FO_Q_SECOND '2'
+#define FO_INS_VI 'v'
+#define FO_INS_LONG 'l'
+#define FO_INS_BLANK 'b'
+#define FO_MBYTE_BREAK 'm' /* break before/after multi-byte char */
+#define FO_MBYTE_JOIN 'M' /* no space before/after multi-byte char */
+#define FO_MBYTE_JOIN2 'B' /* no space between multi-byte chars */
+#define FO_ONE_LETTER '1'
+#define FO_WHITE_PAR 'w' /* trailing white space continues paragr. */
+#define FO_AUTO 'a' /* automatic formatting */
+#define FO_REMOVE_COMS 'j' /* remove comment leaders when joining lines */
+
+#define DFLT_FO_VI "vt"
+#define DFLT_FO_VIM "tcq"
+#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 */
+#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_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_GOTO1 'g' /* goto line 1 for ":edit" */
+#define CPO_INSEND 'H' /* "I" inserts before last blank in line */
+#define CPO_INTMOD 'i' /* interrupt a read makes buffer modified */
+#define CPO_INDENT 'I' /* remove auto-indent more often */
+#define CPO_JOINSP 'j' /* only use two spaces for join after '.' */
+#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_SHOWMATCH 'm'
+#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_REDO 'r'
+#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_CW 'w' /* "cw" only changes one blank */
+#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_YANK 'y'
+#define CPO_KEEPRO 'Z' /* don't reset 'readonly' on ":w!" */
+#define CPO_DOLLAR '$'
+#define CPO_FILTER '!'
+#define CPO_MATCH '%'
+#define CPO_STAR '*' /* ":*" means ":@" */
+#define CPO_PLUS '+' /* ":write file" resets 'modified' */
+#define CPO_MINUS '-' /* "9-" fails at and before line 9 */
+#define CPO_SPECI '<' /* don't recognize <> in mappings */
+#define CPO_REGAPPEND '>' /* insert NL when appending to a register */
+/* POSIX flags */
+#define CPO_HASH '#' /* "D", "o" and "O" do not use a count */
+#define CPO_PARA '{' /* "{" is also a paragraph boundary */
+#define CPO_TSIZE '|' /* $LINES and $COLUMNS overrule term size */
+#define CPO_PRESERVE '&' /* keep swap file after :preserve */
+#define CPO_SUBPERCENT '/' /* % in :s string uses previous one */
+#define CPO_BACKSL '\\' /* \ is not special in [] */
+#define CPO_CHDIR '.' /* don't chdir if buffer is modified */
+#define CPO_SCOLON ';' /* using "," and ";" will skip over char if
+ * cursor would not move */
+/* default values for Vim, Vi and POSIX */
+#define CPO_VIM "aABceFs"
+#define CPO_VI "aAbBcCdDeEfFgHiIjJkKlLmMnoOpPqrRsStuvwWxXyZ$!%*-+<>;"
+#define CPO_ALL \
+ "aAbBcCdDeEfFgHiIjJkKlLmMnoOpPqrRsStuvwWxXyZ$!%*-+<>#{|&/\\.;"
+
+/* characters for p_ww option: */
+#define WW_ALL "bshl<>[],~"
+
+/* characters for p_mouse option: */
+#define MOUSE_NORMAL 'n' /* use mouse in Normal mode */
+#define MOUSE_VISUAL 'v' /* use mouse in Visual/Select mode */
+#define MOUSE_INSERT 'i' /* use mouse in Insert mode */
+#define MOUSE_COMMAND 'c' /* use mouse in Command-line mode */
+#define MOUSE_HELP 'h' /* use mouse in help buffers */
+#define MOUSE_RETURN 'r' /* use mouse for hit-return message */
+#define MOUSE_A "nvich" /* used for 'a' flag */
+#define MOUSE_ALL "anvichr" /* all possible characters */
+#define MOUSE_NONE ' ' /* don't use Visual selection */
+#define MOUSE_NONEF 'x' /* forced modeless selection */
+
+#define COCU_ALL "nvic" /* flags for 'concealcursor' */
+
+/* characters for p_shm option: */
+#define SHM_RO 'r' /* readonly */
+#define SHM_MOD 'm' /* modified */
+#define SHM_FILE 'f' /* (file 1 of 2) */
+#define SHM_LAST 'i' /* last line incomplete */
+#define SHM_TEXT 'x' /* tx instead of textmode */
+#define SHM_LINES 'l' /* "L" instead of "lines" */
+#define SHM_NEW 'n' /* "[New]" instead of "[New file]" */
+#define SHM_WRI 'w' /* "[w]" instead of "written" */
+#define SHM_A "rmfixlnw" /* represented by 'a' flag */
+#define SHM_WRITE 'W' /* don't use "written" at all */
+#define SHM_TRUNC 't' /* trunctate file messages */
+#define SHM_TRUNCALL 'T' /* trunctate all messages */
+#define SHM_OVER 'o' /* overwrite file messages */
+#define SHM_OVERALL 'O' /* overwrite more messages */
+#define SHM_SEARCH 's' /* no search hit bottom messages */
+#define SHM_ATTENTION 'A' /* no ATTENTION messages */
+#define SHM_INTRO 'I' /* intro messages */
+#define SHM_ALL "rmfixlnwaWtToOsAI" /* all possible flags for 'shm' */
+
+/* characters for p_go: */
+#define GO_ASEL 'a' /* autoselect */
+#define GO_ASELML 'A' /* autoselect modeless selection */
+#define GO_BOT 'b' /* use bottom scrollbar */
+#define GO_CONDIALOG 'c' /* use console dialog */
+#define GO_TABLINE 'e' /* may show tabline */
+#define GO_FORG 'f' /* start GUI in foreground */
+#define GO_GREY 'g' /* use grey menu items */
+#define GO_HORSCROLL 'h' /* flexible horizontal scrolling */
+#define GO_ICON 'i' /* use Vim icon */
+#define GO_LEFT 'l' /* use left scrollbar */
+#define GO_VLEFT 'L' /* left scrollbar with vert split */
+#define GO_MENUS 'm' /* use menu bar */
+#define GO_NOSYSMENU 'M' /* don't source system menu */
+#define GO_POINTER 'p' /* pointer enter/leave callbacks */
+#define GO_ASELPLUS 'P' /* autoselectPlus */
+#define GO_RIGHT 'r' /* use right scrollbar */
+#define GO_VRIGHT 'R' /* right scrollbar with vert split */
+#define GO_TEAROFF 't' /* add tear-off menu items */
+#define GO_TOOLBAR 'T' /* add toolbar */
+#define GO_FOOTER 'F' /* add footer */
+#define GO_VERTICAL 'v' /* arrange dialog buttons vertically */
+#define GO_ALL "aAbcefFghilmMprtTv" /* all possible flags for 'go' */
+
+/* flags for 'comments' option */
+#define COM_NEST 'n' /* comments strings nest */
+#define COM_BLANK 'b' /* needs blank after string */
+#define COM_START 's' /* start of comment */
+#define COM_MIDDLE 'm' /* middle of comment */
+#define COM_END 'e' /* end of comment */
+#define COM_AUTO_END 'x' /* last char of end closes comment */
+#define COM_FIRST 'f' /* first line comment only */
+#define COM_LEFT 'l' /* left adjusted */
+#define COM_RIGHT 'r' /* right adjusted */
+#define COM_NOBACK 'O' /* don't use for "O" command */
+#define COM_ALL "nbsmexflrO" /* all flags for 'comments' option */
+#define COM_MAX_LEN 50 /* maximum length of a part */
+
+/* flags for 'statusline' option */
+#define STL_FILEPATH 'f' /* path of file in buffer */
+#define STL_FULLPATH 'F' /* full path of file in buffer */
+#define STL_FILENAME 't' /* last part (tail) of file path */
+#define STL_COLUMN 'c' /* column og cursor*/
+#define STL_VIRTCOL 'v' /* virtual column */
+#define STL_VIRTCOL_ALT 'V' /* - with 'if different' display */
+#define STL_LINE 'l' /* line number of cursor */
+#define STL_NUMLINES 'L' /* number of lines in buffer */
+#define STL_BUFNO 'n' /* current buffer number */
+#define STL_KEYMAP 'k' /* 'keymap' when active */
+#define STL_OFFSET 'o' /* offset of character under cursor*/
+#define STL_OFFSET_X 'O' /* - in hexadecimal */
+#define STL_BYTEVAL 'b' /* byte value of character */
+#define STL_BYTEVAL_X 'B' /* - in hexadecimal */
+#define STL_ROFLAG 'r' /* readonly flag */
+#define STL_ROFLAG_ALT 'R' /* - other display */
+#define STL_HELPFLAG 'h' /* window is showing a help file */
+#define STL_HELPFLAG_ALT 'H' /* - other display */
+#define STL_FILETYPE 'y' /* 'filetype' */
+#define STL_FILETYPE_ALT 'Y' /* - other display */
+#define STL_PREVIEWFLAG 'w' /* window is showing the preview buf */
+#define STL_PREVIEWFLAG_ALT 'W' /* - other display */
+#define STL_MODIFIED 'm' /* modified flag */
+#define STL_MODIFIED_ALT 'M' /* - other display */
+#define STL_QUICKFIX 'q' /* quickfix window description */
+#define STL_PERCENTAGE 'p' /* percentage through file */
+#define STL_ALTPERCENT 'P' /* percentage as TOP BOT ALL or NN% */
+#define STL_ARGLISTSTAT 'a' /* argument list status as (x of y) */
+#define STL_PAGENUM 'N' /* page number (when printing)*/
+#define STL_VIM_EXPR '{' /* start of expression to substitute */
+#define STL_MIDDLEMARK '=' /* separation between left and right */
+#define STL_TRUNCMARK '<' /* truncation mark if line is too long*/
+#define STL_USER_HL '*' /* highlight from (User)1..9 or 0 */
+#define STL_HIGHLIGHT '#' /* highlight name */
+#define STL_TABPAGENR 'T' /* tab page label nr */
+#define STL_TABCLOSENR 'X' /* tab page close nr */
+#define STL_ALL ((char_u *) "fFtcvVlLknoObBrRhHmYyWwMqpPaN{#")
+
+/* flags used for parsed 'wildmode' */
+#define WIM_FULL 1
+#define WIM_LONGEST 2
+#define WIM_LIST 4
+
+/* arguments for can_bs() */
+#define BS_INDENT 'i' /* "Indent" */
+#define BS_EOL 'o' /* "eOl" */
+#define BS_START 's' /* "Start" */
+
+#define LISPWORD_VALUE \
+ "defun,define,defmacro,set!,lambda,if,case,let,flet,let*,letrec,do,do*,define-syntax,let-syntax,letrec-syntax,destructuring-bind,defpackage,defparameter,defstruct,deftype,defvar,do-all-symbols,do-external-symbols,do-symbols,dolist,dotimes,ecase,etypecase,eval-when,labels,macrolet,multiple-value-bind,multiple-value-call,multiple-value-prog1,multiple-value-setq,prog1,progv,typecase,unless,unwind-protect,when,with-input-from-string,with-open-file,with-open-stream,with-output-to-string,with-package-iterator,define-condition,handler-bind,handler-case,restart-bind,restart-case,with-simple-restart,store-value,use-value,muffle-warning,abort,continue,with-slots,with-slots*,with-accessors,with-accessors*,defclass,defmethod,print-unreadable-object"
+
+/*
+ * The following are actual variables for the options
+ */
+
+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 bkc_flags;
+#ifdef IN_OPTION_C
+static char *(p_bkc_values[]) =
+{"yes", "auto", "no", "breaksymlink", "breakhardlink", NULL};
+#endif
+# define BKC_YES 0x001
+# define BKC_AUTO 0x002
+# 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_bsk; /* 'backupskip' */
+EXTERN char_u *p_cm; /* 'cryptmethod' */
+EXTERN char_u *p_breakat; /* 'breakat' */
+EXTERN char_u *p_cmp; /* 'casemap' */
+EXTERN unsigned cmp_flags;
+# ifdef IN_OPTION_C
+static char *(p_cmp_values[]) = {"internal", "keepascii", NULL};
+# endif
+# define CMP_INTERNAL 0x001
+# define CMP_KEEPASCII 0x002
+EXTERN char_u *p_enc; /* 'encoding' */
+EXTERN int p_deco; /* 'delcombine' */
+EXTERN char_u *p_ccv; /* 'charconvert' */
+EXTERN char_u *p_cedit; /* 'cedit' */
+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"
+# define CSQF_FLAGS "+-0"
+EXTERN int p_cst; /* 'cscopetag' */
+EXTERN long p_csto; /* 'cscopetagorder' */
+EXTERN long p_cspc; /* 'cscopepathcomp' */
+EXTERN int p_csverbose; /* 'cscopeverbose' */
+EXTERN char_u *p_debug; /* 'debug' */
+EXTERN char_u *p_def; /* 'define' */
+EXTERN char_u *p_inc;
+EXTERN char_u *p_dip; /* 'diffopt' */
+EXTERN char_u *p_dex; /* 'diffexpr' */
+EXTERN char_u *p_dict; /* 'dictionary' */
+EXTERN int p_dg; /* 'digraph' */
+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};
+#endif
+#define DY_LASTLINE 0x001
+#define DY_UHEX 0x002
+EXTERN int p_ed; /* 'edcompatible' */
+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_ek; /* 'esckeys' */
+EXTERN int p_exrc; /* 'exrc' */
+EXTERN char_u *p_fencs; /* 'fileencodings' */
+EXTERN char_u *p_ffs; /* 'fileformats' */
+EXTERN long 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",
+ "quickfix", "search", "tag", "insert",
+ "undo", "jump", NULL};
+# endif
+# define FDO_ALL 0x001
+# define FDO_BLOCK 0x002
+# define FDO_HOR 0x004
+# define FDO_MARK 0x008
+# define FDO_PERCENT 0x010
+# define FDO_QUICKFIX 0x020
+# define FDO_SEARCH 0x040
+# define FDO_TAG 0x080
+# define FDO_INSERT 0x100
+# define FDO_UNDO 0x200
+# define FDO_JUMP 0x400
+EXTERN char_u *p_fp; /* 'formatprg' */
+#ifdef HAVE_FSYNC
+EXTERN int p_fs; /* 'fsync' */
+#endif
+EXTERN int p_gd; /* 'gdefault' */
+EXTERN char_u *p_pdev; /* 'printdevice' */
+EXTERN char_u *p_penc; /* 'printencoding' */
+EXTERN char_u *p_pexpr; /* 'printexpr' */
+EXTERN char_u *p_pmfn; /* 'printmbfont' */
+EXTERN char_u *p_pmcs; /* 'printmbcharset' */
+EXTERN char_u *p_pfn; /* 'printfont' */
+EXTERN char_u *p_popt; /* 'printoptions' */
+EXTERN char_u *p_header; /* 'printheader' */
+EXTERN int p_prompt; /* 'prompt' */
+#ifdef CURSOR_SHAPE
+EXTERN char_u *p_guicursor; /* 'guicursor' */
+#endif
+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' */
+EXTERN int p_hkmap; /* 'hkmap' */
+EXTERN int p_hkmapp; /* 'hkmapp' */
+EXTERN int p_fkmap; /* 'fkmap' */
+EXTERN int p_altkeymap; /* 'altkeymap' */
+EXTERN int p_arshape; /* 'arabicshape' */
+EXTERN int p_icon; /* 'icon' */
+EXTERN char_u *p_iconstring; /* 'iconstring' */
+EXTERN int p_ic; /* 'ignorecase' */
+#ifdef USE_IM_CONTROL
+EXTERN int p_imcmdline; /* 'imcmdline' */
+EXTERN int p_imdisable; /* 'imdisable' */
+#endif
+EXTERN int p_is; /* 'incsearch' */
+EXTERN int p_im; /* 'insertmode' */
+EXTERN char_u *p_isf; /* 'isfname' */
+EXTERN char_u *p_isi; /* 'isident' */
+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 char_u *p_lm; /* 'langmenu' */
+EXTERN char_u *p_lispwords; /* 'lispwords' */
+EXTERN long p_ls; /* 'laststatus' */
+EXTERN long p_stal; /* 'showtabline' */
+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_mef; /* 'makeef' */
+EXTERN char_u *p_mp; /* 'makeprg' */
+EXTERN char_u *p_cc; /* 'colorcolumn' */
+EXTERN int p_cc_cols[256]; /* array for 'colorcolumn' columns */
+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' */
+EXTERN char_u *p_mouse; /* 'mouse' */
+EXTERN char_u *p_mousem; /* 'mousemodel' */
+EXTERN long p_mouset; /* 'mousetime' */
+EXTERN int p_more; /* 'more' */
+EXTERN char_u *p_opfunc; /* 'operatorfunc' */
+EXTERN char_u *p_para; /* 'paragraphs' */
+EXTERN int p_paste; /* 'paste' */
+EXTERN char_u *p_pt; /* 'pastetoggle' */
+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_rdt; /* 'redrawtime' */
+EXTERN int p_remap; /* 'remap' */
+EXTERN long p_re; /* 'regexpengine' */
+EXTERN long p_report; /* 'report' */
+EXTERN long p_pvh; /* 'previewheight' */
+EXTERN int p_ari; /* 'allowrevins' */
+EXTERN int p_ri; /* 'revins' */
+EXTERN int p_ru; /* 'ruler' */
+EXTERN char_u *p_ruf; /* 'rulerformat' */
+EXTERN char_u *p_rtp; /* 'runtimepath' */
+EXTERN long p_sj; /* 'scrolljump' */
+EXTERN long p_so; /* 'scrolloff' */
+EXTERN char_u *p_sbo; /* 'scrollopt' */
+EXTERN char_u *p_sections; /* 'sections' */
+EXTERN int p_secure; /* 'secure' */
+EXTERN char_u *p_sel; /* 'selection' */
+EXTERN char_u *p_slm; /* 'selectmode' */
+EXTERN char_u *p_ssop; /* 'sessionoptions' */
+EXTERN unsigned ssop_flags;
+# ifdef IN_OPTION_C
+/* Also used for 'viewoptions'! */
+static char *(p_ssop_values[]) = {"buffers", "winpos", "resize", "winsize",
+ "localoptions", "options", "help", "blank",
+ "globals", "slash", "unix",
+ "sesdir", "curdir", "folds", "cursor",
+ "tabpages", NULL};
+# endif
+# define SSOP_BUFFERS 0x001
+# define SSOP_WINPOS 0x002
+# define SSOP_RESIZE 0x004
+# define SSOP_WINSIZE 0x008
+# define SSOP_LOCALOPTIONS 0x010
+# define SSOP_OPTIONS 0x020
+# define SSOP_HELP 0x040
+# define SSOP_BLANK 0x080
+# define SSOP_GLOBALS 0x100
+# define SSOP_SLASH 0x200
+# define SSOP_UNIX 0x400
+# define SSOP_SESDIR 0x800
+# define SSOP_CURDIR 0x1000
+# 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' */
+#ifdef BACKSLASH_IN_FILENAME
+EXTERN int p_ssl; /* 'shellslash' */
+#endif
+EXTERN char_u *p_stl; /* 'statusline' */
+EXTERN int p_sr; /* 'shiftround' */
+EXTERN char_u *p_shm; /* 'shortmess' */
+EXTERN char_u *p_sbr; /* 'showbreak' */
+EXTERN int p_sc; /* 'showcmd' */
+EXTERN int p_sft; /* 'showfulltag' */
+EXTERN int p_sm; /* 'showmatch' */
+EXTERN int p_smd; /* 'showmode' */
+EXTERN long p_ss; /* 'sidescroll' */
+EXTERN long p_siso; /* 'sidescrolloff' */
+EXTERN int p_scs; /* 'smartcase' */
+EXTERN int p_sta; /* 'smarttab' */
+EXTERN int p_sb; /* 'splitbelow' */
+EXTERN long p_tpm; /* 'tabpagemax' */
+EXTERN char_u *p_tal; /* 'tabline' */
+EXTERN char_u *p_sps; /* 'spellsuggest' */
+EXTERN int p_spr; /* 'splitright' */
+EXTERN int p_sol; /* 'startofline' */
+EXTERN char_u *p_su; /* 'suffixes' */
+EXTERN char_u *p_sws; /* 'swapsync' */
+EXTERN char_u *p_swb; /* 'switchbuf' */
+EXTERN unsigned swb_flags;
+#ifdef IN_OPTION_C
+static char *(p_swb_values[]) = {"useopen", "usetab", "split", "newtab", NULL};
+#endif
+#define SWB_USEOPEN 0x001
+#define SWB_USETAB 0x002
+#define SWB_SPLIT 0x004
+#define SWB_NEWTAB 0x008
+EXTERN int p_tbs; /* 'tagbsearch' */
+EXTERN long p_tl; /* 'taglength' */
+EXTERN int p_tr; /* 'tagrelative' */
+EXTERN char_u *p_tags; /* 'tags' */
+EXTERN int p_tgst; /* 'tagstack' */
+EXTERN int p_tbidi; /* 'termbidi' */
+EXTERN char_u *p_tenc; /* 'termencoding' */
+EXTERN int p_terse; /* 'terse' */
+EXTERN int p_ta; /* 'textauto' */
+EXTERN int p_to; /* 'tildeop' */
+EXTERN int p_timeout; /* 'timeout' */
+EXTERN long p_tm; /* 'timeoutlen' */
+EXTERN int p_title; /* 'title' */
+EXTERN long p_titlelen; /* 'titlelen' */
+EXTERN char_u *p_titleold; /* 'titleold' */
+EXTERN char_u *p_titlestring; /* 'titlestring' */
+EXTERN char_u *p_tsr; /* 'thesaurus' */
+EXTERN int p_ttimeout; /* 'ttimeout' */
+EXTERN long p_ttm; /* 'ttimeoutlen' */
+EXTERN int p_tbi; /* 'ttybuiltin' */
+EXTERN int p_tf; /* 'ttyfast' */
+EXTERN long p_ttyscroll; /* 'ttyscroll' */
+#if defined(FEAT_MOUSE) && (defined(UNIX) || defined(VMS))
+EXTERN char_u *p_ttym; /* 'ttymouse' */
+EXTERN unsigned ttym_flags;
+# ifdef IN_OPTION_C
+static char *(p_ttym_values[]) =
+{"xterm", "xterm2", "dec", "netterm", "jsbterm", "pterm", "urxvt", "sgr", NULL};
+# endif
+# define TTYM_XTERM 0x01
+# define TTYM_XTERM2 0x02
+# define TTYM_DEC 0x04
+# define TTYM_NETTERM 0x08
+# define TTYM_JSBTERM 0x10
+# define TTYM_PTERM 0x20
+# define TTYM_URXVT 0x40
+# define TTYM_SGR 0x80
+#endif
+EXTERN char_u *p_udir; /* 'undodir' */
+EXTERN long p_ul; /* 'undolevels' */
+EXTERN long p_ur; /* 'undoreload' */
+EXTERN long p_uc; /* 'updatecount' */
+EXTERN long p_ut; /* 'updatetime' */
+EXTERN char_u *p_fcs; /* 'fillchar' */
+EXTERN char_u *p_viminfo; /* 'viminfo' */
+EXTERN char_u *p_vdir; /* 'viewdir' */
+EXTERN char_u *p_vop; /* 'viewoptions' */
+EXTERN unsigned vop_flags; /* uses SSOP_ flags */
+EXTERN int p_vb; /* 'visualbell' */
+EXTERN char_u *p_ve; /* 'virtualedit' */
+EXTERN unsigned ve_flags;
+# ifdef IN_OPTION_C
+static char *(p_ve_values[]) = {"block", "insert", "all", "onemore", NULL};
+# endif
+# define VE_BLOCK 5 /* includes "all" */
+# define VE_INSERT 6 /* includes "all" */
+# define VE_ALL 4
+# define VE_ONEMORE 8
+EXTERN long p_verbose; /* 'verbose' */
+#ifdef IN_OPTION_C
+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' */
+#if defined(FEAT_GUI_MSWIN) || defined(FEAT_GUI_MOTIF) || defined(LINT) \
+ || defined (FEAT_GUI_GTK) || defined(FEAT_GUI_PHOTON)
+#define FEAT_WAK
+EXTERN char_u *p_wak; /* 'winaltkeys' */
+#endif
+EXTERN char_u *p_wak;
+EXTERN char_u *p_wig; /* 'wildignore' */
+EXTERN int p_wiv; /* 'weirdinvert' */
+EXTERN char_u *p_ww; /* 'whichwrap' */
+EXTERN long p_wc; /* 'wildchar' */
+EXTERN long p_wcm; /* 'wildcharm' */
+EXTERN long 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' */
+
+/*
+ * "indir" values for buffer-local opions.
+ * These need to be defined globally, so that the BV_COUNT can be used with
+ * b_p_scriptID[].
+ */
+enum {
+ BV_AI = 0
+ , BV_AR
+ , BV_BH
+ , BV_BT
+ , BV_EFM
+ , BV_GP
+ , BV_MP
+ , BV_BIN
+ , BV_BL
+ , BV_BOMB
+ , BV_CI
+ , BV_CIN
+ , BV_CINK
+ , BV_CINO
+ , BV_CINW
+ , BV_CM
+ , BV_CMS
+ , BV_COM
+ , BV_CPT
+ , BV_DICT
+ , BV_TSR
+ , BV_CFU
+ , BV_DEF
+ , BV_INC
+ , BV_EOL
+ , BV_EP
+ , BV_ET
+ , BV_FENC
+ , BV_BEXPR
+ , BV_FEX
+ , BV_FF
+ , BV_FLP
+ , BV_FO
+ , BV_FT
+ , BV_IMI
+ , BV_IMS
+ , BV_INDE
+ , BV_INDK
+ , BV_INEX
+ , BV_INF
+ , BV_ISK
+ , BV_KEY
+ , BV_KMAP
+ , BV_KP
+ , BV_LISP
+ , BV_MA
+ , BV_ML
+ , BV_MOD
+ , BV_MPS
+ , BV_NF
+ , BV_OFU
+ , BV_PATH
+ , BV_PI
+ , BV_QE
+ , BV_RO
+ , BV_SI
+#ifndef SHORT_FNAME
+ , BV_SN
+#endif
+ , BV_SMC
+ , BV_SYN
+ , BV_SPC
+ , BV_SPF
+ , BV_SPL
+ , BV_STS
+ , BV_SUA
+ , BV_SW
+ , BV_SWF
+ , BV_TAGS
+ , BV_TS
+ , BV_TW
+ , BV_TX
+ , BV_UDF
+ , BV_UL
+ , BV_WM
+ , BV_COUNT /* must be the last one */
+};
+
+/*
+ * "indir" values for window-local options.
+ * These need to be defined globally, so that the WV_COUNT can be used in the
+ * window structure.
+ */
+enum {
+ WV_LIST = 0
+ , WV_ARAB
+ , WV_COCU
+ , WV_COLE
+ , WV_CRBIND
+ , WV_DIFF
+ , WV_FDC
+ , WV_FEN
+ , WV_FDI
+ , WV_FDL
+ , WV_FDM
+ , WV_FML
+ , WV_FDN
+ , WV_FDE
+ , WV_FDT
+ , WV_FMR
+ , WV_LBR
+ , WV_NU
+ , WV_RNU
+ , WV_NUW
+ , WV_PVW
+ , WV_RL
+ , WV_RLC
+ , WV_SCBIND
+ , WV_SCROLL
+ , WV_SPELL
+ , WV_CUC
+ , WV_CUL
+ , WV_CC
+ , WV_STL
+ , WV_WFH
+ , WV_WFW
+ , WV_WRAP
+ , WV_COUNT /* must be the last one */
+};
+
+/* Value for b_p_ul indicating the global value must be used. */
+#define NO_LOCAL_UNDOLEVEL -123456
diff --git a/src/os_unix.c b/src/os_unix.c
new file mode 100644
index 0000000000..344be7b0df
--- /dev/null
+++ b/src/os_unix.c
@@ -0,0 +1,4008 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved by Bram Moolenaar
+ * OS/2 port by Paul Slootman
+ * VMS merge by Zoltan Arpadffy
+ *
+ * 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.
+ */
+
+/*
+ * os_unix.c -- code for all flavors of Unix (BSD, SYSV, SVR4, POSIX, ...)
+ * Also for OS/2, using the excellent EMX package!!!
+ * Also for BeOS and Atari MiNT.
+ *
+ * A lot of this file was originally written by Juergen Weigert and later
+ * changed beyond recognition.
+ */
+
+/*
+ * Some systems have a prototype for select() that has (int *) instead of
+ * (fd_set *), which is wrong. This define removes that prototype. We define
+ * our own prototype below.
+ * Don't use it for the Mac, it causes a warning for precompiled headers.
+ * TODO: use a configure check for precompiled headers?
+ */
+# define select select_declared_wrong
+
+#include "vim.h"
+
+
+#include "os_unixx.h" /* unix includes for os_unix.c only */
+
+
+#ifdef HAVE_SELINUX
+# include <selinux/selinux.h>
+static int selinux_enabled = -1;
+#endif
+
+/*
+ * Use this prototype for select, some include files have a wrong prototype
+ */
+# undef select
+
+
+#if defined(HAVE_SELECT)
+extern int select __ARGS((int, fd_set *, fd_set *, fd_set *, struct timeval *));
+#endif
+
+
+
+/*
+ * end of autoconf section. To be extended...
+ */
+
+/* Are the following #ifdefs still required? And why? Is that for X11? */
+
+#if defined(ESIX) || defined(M_UNIX) && !defined(SCO)
+# ifdef SIGWINCH
+# undef SIGWINCH
+# endif
+# ifdef TIOCGWINSZ
+# undef TIOCGWINSZ
+# endif
+#endif
+
+#if defined(SIGWINDOW) && !defined(SIGWINCH) /* hpux 9.01 has it */
+# define SIGWINCH SIGWINDOW
+#endif
+
+
+static int get_x11_title __ARGS((int));
+static int get_x11_icon __ARGS((int));
+
+static char_u *oldtitle = NULL;
+static int did_set_title = FALSE;
+static char_u *oldicon = NULL;
+static int did_set_icon = FALSE;
+
+static void may_core_dump __ARGS((void));
+
+#ifdef HAVE_UNION_WAIT
+typedef union wait waitstatus;
+#else
+typedef int waitstatus;
+#endif
+static pid_t wait4pid __ARGS((pid_t, waitstatus *));
+
+static int WaitForChar __ARGS((long));
+static int RealWaitForChar __ARGS((int, long, int *));
+
+
+static void handle_resize __ARGS((void));
+
+#if defined(SIGWINCH)
+static RETSIGTYPE sig_winch __ARGS(SIGPROTOARG);
+#endif
+#if defined(SIGINT)
+static RETSIGTYPE catch_sigint __ARGS(SIGPROTOARG);
+#endif
+#if defined(SIGPWR)
+static RETSIGTYPE catch_sigpwr __ARGS(SIGPROTOARG);
+#endif
+static RETSIGTYPE deathtrap __ARGS(SIGPROTOARG);
+
+static void catch_int_signal __ARGS((void));
+static void set_signals __ARGS((void));
+static void catch_signals __ARGS(
+ (RETSIGTYPE (*func_deadly)(), RETSIGTYPE (*func_other)()));
+static int have_wildcard __ARGS((int, char_u **));
+static int have_dollars __ARGS((int, char_u **));
+
+static int save_patterns __ARGS((int num_pat, char_u **pat, int *num_file,
+ char_u ***file));
+
+#ifndef SIG_ERR
+# define SIG_ERR ((RETSIGTYPE (*)())-1)
+#endif
+
+/* volatile because it is used in signal handler sig_winch(). */
+static volatile int do_resize = FALSE;
+static char_u *extra_shell_arg = NULL;
+static int show_shell_mess = TRUE;
+/* volatile because it is used in signal handler deathtrap(). */
+static volatile int deadly_signal = 0; /* The signal we caught */
+/* volatile because it is used in signal handler deathtrap(). */
+static volatile int in_mch_delay = FALSE; /* sleeping in mch_delay() */
+
+static int curr_tmode = TMODE_COOK; /* contains current terminal mode */
+
+
+#ifdef SYS_SIGLIST_DECLARED
+/*
+ * I have seen
+ * extern char *_sys_siglist[NSIG];
+ * on Irix, Linux, NetBSD and Solaris. It contains a nice list of strings
+ * that describe the signals. That is nearly what we want here. But
+ * autoconf does only check for sys_siglist (without the underscore), I
+ * do not want to change everything today.... jw.
+ * This is why AC_DECL_SYS_SIGLIST is commented out in configure.in
+ */
+#endif
+
+static struct signalinfo {
+ int sig; /* Signal number, eg. SIGSEGV etc */
+ char *name; /* Signal name (not char_u!). */
+ char deadly; /* Catch as a deadly signal? */
+} signal_info[] =
+{
+#ifdef SIGHUP
+ {SIGHUP, "HUP", TRUE},
+#endif
+#ifdef SIGQUIT
+ {SIGQUIT, "QUIT", TRUE},
+#endif
+#ifdef SIGILL
+ {SIGILL, "ILL", TRUE},
+#endif
+#ifdef SIGTRAP
+ {SIGTRAP, "TRAP", TRUE},
+#endif
+#ifdef SIGABRT
+ {SIGABRT, "ABRT", TRUE},
+#endif
+#ifdef SIGEMT
+ {SIGEMT, "EMT", TRUE},
+#endif
+#ifdef SIGFPE
+ {SIGFPE, "FPE", TRUE},
+#endif
+#ifdef SIGBUS
+ {SIGBUS, "BUS", TRUE},
+#endif
+#if defined(SIGSEGV)
+ /* MzScheme uses SEGV in its garbage collector */
+ {SIGSEGV, "SEGV", TRUE},
+#endif
+#ifdef SIGSYS
+ {SIGSYS, "SYS", TRUE},
+#endif
+#ifdef SIGALRM
+ {SIGALRM, "ALRM", FALSE}, /* Perl's alarm() can trigger it */
+#endif
+#ifdef SIGTERM
+ {SIGTERM, "TERM", TRUE},
+#endif
+#if defined(SIGVTALRM)
+ {SIGVTALRM, "VTALRM", TRUE},
+#endif
+#if defined(SIGPROF) && !defined(WE_ARE_PROFILING)
+ /* MzScheme uses SIGPROF for its own needs; On Linux with profiling
+ * this makes Vim exit. WE_ARE_PROFILING is defined in Makefile. */
+ {SIGPROF, "PROF", TRUE},
+#endif
+#ifdef SIGXCPU
+ {SIGXCPU, "XCPU", TRUE},
+#endif
+#ifdef SIGXFSZ
+ {SIGXFSZ, "XFSZ", TRUE},
+#endif
+#ifdef SIGUSR1
+ {SIGUSR1, "USR1", TRUE},
+#endif
+#if defined(SIGUSR2) && !defined(FEAT_SYSMOUSE)
+ /* Used for sysmouse handling */
+ {SIGUSR2, "USR2", TRUE},
+#endif
+#ifdef SIGINT
+ {SIGINT, "INT", FALSE},
+#endif
+#ifdef SIGWINCH
+ {SIGWINCH, "WINCH", FALSE},
+#endif
+#ifdef SIGTSTP
+ {SIGTSTP, "TSTP", FALSE},
+#endif
+#ifdef SIGPIPE
+ {SIGPIPE, "PIPE", FALSE},
+#endif
+ {-1, "Unknown!", FALSE}
+};
+
+int mch_chdir(path)
+char *path;
+{
+ if (p_verbose >= 5) {
+ verbose_enter();
+ smsg((char_u *)"chdir(%s)", path);
+ verbose_leave();
+ }
+ return chdir(path);
+}
+
+/*
+ * Write s[len] to the screen.
+ */
+void mch_write(s, len)
+char_u *s;
+int len;
+{
+ ignored = (int)write(1, (char *)s, len);
+ if (p_wd) /* Unix is too fast, slow down a bit more */
+ RealWaitForChar(read_cmd_fd, p_wd, NULL);
+}
+
+/*
+ * mch_inchar(): low level input function.
+ * Get a characters from the keyboard.
+ * Return the number of characters that are available.
+ * If wtime == 0 do not wait for characters.
+ * If wtime == n wait a short time for characters.
+ * If wtime == -1 wait forever for characters.
+ */
+int mch_inchar(buf, maxlen, wtime, tb_change_cnt)
+char_u *buf;
+int maxlen;
+long wtime; /* don't use "time", MIPS cannot handle it */
+int tb_change_cnt;
+{
+ int len;
+
+
+ /* Check if window changed size while we were busy, perhaps the ":set
+ * columns=99" command was used. */
+ while (do_resize)
+ handle_resize();
+
+ if (wtime >= 0) {
+ while (WaitForChar(wtime) == 0) { /* no character available */
+ if (!do_resize) /* return if not interrupted by resize */
+ return 0;
+ handle_resize();
+ }
+ } else { /* wtime == -1 */
+ /*
+ * If there is no character available within 'updatetime' seconds
+ * flush all the swap files to disk.
+ * Also done when interrupted by SIGWINCH.
+ */
+ if (WaitForChar(p_ut) == 0) {
+ if (trigger_cursorhold() && maxlen >= 3
+ && !typebuf_changed(tb_change_cnt)) {
+ buf[0] = K_SPECIAL;
+ buf[1] = KS_EXTRA;
+ buf[2] = (int)KE_CURSORHOLD;
+ return 3;
+ }
+ before_blocking();
+ }
+ }
+
+ for (;; ) { /* repeat until we got a character */
+ while (do_resize) /* window changed size */
+ handle_resize();
+
+ /*
+ * We want to be interrupted by the winch signal
+ * or by an event on the monitored file descriptors.
+ */
+ if (WaitForChar(-1L) == 0) {
+ if (do_resize) /* interrupted by SIGWINCH signal */
+ handle_resize();
+ return 0;
+ }
+
+ /* If input was put directly in typeahead buffer bail out here. */
+ if (typebuf_changed(tb_change_cnt))
+ return 0;
+
+ /*
+ * For some terminals we only get one character at a time.
+ * We want the get all available characters, so we could keep on
+ * trying until none is available
+ * For some other terminals this is quite slow, that's why we don't do
+ * it.
+ */
+ len = read_from_input_buf(buf, (long)maxlen);
+ if (len > 0) {
+ return len;
+ }
+ }
+}
+
+static void handle_resize() {
+ do_resize = FALSE;
+ shell_resized();
+}
+
+/*
+ * return non-zero if a character is available
+ */
+int mch_char_avail() {
+ return WaitForChar(0L);
+}
+
+#if defined(HAVE_TOTAL_MEM) || defined(PROTO)
+# ifdef HAVE_SYS_RESOURCE_H
+# include <sys/resource.h>
+# endif
+# if defined(HAVE_SYS_SYSCTL_H) && defined(HAVE_SYSCTL)
+# include <sys/sysctl.h>
+# endif
+# if defined(HAVE_SYS_SYSINFO_H) && defined(HAVE_SYSINFO)
+# include <sys/sysinfo.h>
+# endif
+
+/*
+ * Return total amount of memory available in Kbyte.
+ * Doesn't change when memory has been allocated.
+ */
+long_u mch_total_mem(special)
+int special UNUSED;
+{
+ long_u mem = 0;
+ long_u shiftright = 10; /* how much to shift "mem" right for Kbyte */
+
+# ifdef HAVE_SYSCTL
+ int mib[2], physmem;
+ size_t len;
+
+ /* BSD way of getting the amount of RAM available. */
+ mib[0] = CTL_HW;
+ mib[1] = HW_USERMEM;
+ len = sizeof(physmem);
+ if (sysctl(mib, 2, &physmem, &len, NULL, 0) == 0)
+ mem = (long_u)physmem;
+# endif
+
+# if defined(HAVE_SYS_SYSINFO_H) && defined(HAVE_SYSINFO)
+ if (mem == 0) {
+ struct sysinfo sinfo;
+
+ /* Linux way of getting amount of RAM available */
+ if (sysinfo(&sinfo) == 0) {
+# ifdef HAVE_SYSINFO_MEM_UNIT
+ /* avoid overflow as much as possible */
+ while (shiftright > 0 && (sinfo.mem_unit & 1) == 0) {
+ sinfo.mem_unit = sinfo.mem_unit >> 1;
+ --shiftright;
+ }
+ mem = sinfo.totalram * sinfo.mem_unit;
+# else
+ mem = sinfo.totalram;
+# endif
+ }
+ }
+# endif
+
+# ifdef HAVE_SYSCONF
+ if (mem == 0) {
+ long pagesize, pagecount;
+
+ /* Solaris way of getting amount of RAM available */
+ pagesize = sysconf(_SC_PAGESIZE);
+ pagecount = sysconf(_SC_PHYS_PAGES);
+ if (pagesize > 0 && pagecount > 0) {
+ /* avoid overflow as much as possible */
+ while (shiftright > 0 && (pagesize & 1) == 0) {
+ pagesize = (long_u)pagesize >> 1;
+ --shiftright;
+ }
+ mem = (long_u)pagesize * pagecount;
+ }
+ }
+# endif
+
+ /* Return the minimum of the physical memory and the user limit, because
+ * using more than the user limit may cause Vim to be terminated. */
+# if defined(HAVE_SYS_RESOURCE_H) && defined(HAVE_GETRLIMIT)
+ {
+ struct rlimit rlp;
+
+ if (getrlimit(RLIMIT_DATA, &rlp) == 0
+ && rlp.rlim_cur < ((rlim_t)1 << (sizeof(long_u) * 8 - 1))
+# ifdef RLIM_INFINITY
+ && rlp.rlim_cur != RLIM_INFINITY
+# endif
+ && ((long_u)rlp.rlim_cur >> 10) < (mem >> shiftright)
+ ) {
+ mem = (long_u)rlp.rlim_cur;
+ shiftright = 10;
+ }
+ }
+# endif
+
+ if (mem > 0)
+ return mem >> shiftright;
+ return (long_u)0x1fffff;
+}
+#endif
+
+void mch_delay(msec, ignoreinput)
+long msec;
+int ignoreinput;
+{
+ int old_tmode;
+
+ if (ignoreinput) {
+ /* Go to cooked mode without echo, to allow SIGINT interrupting us
+ * here. But we don't want QUIT to kill us (CTRL-\ used in a
+ * shell may produce SIGQUIT). */
+ in_mch_delay = TRUE;
+ old_tmode = curr_tmode;
+ if (curr_tmode == TMODE_RAW)
+ settmode(TMODE_SLEEP);
+
+ /*
+ * Everybody sleeps in a different way...
+ * Prefer nanosleep(), some versions of usleep() can only sleep up to
+ * one second.
+ */
+#ifdef HAVE_NANOSLEEP
+ {
+ struct timespec ts;
+
+ ts.tv_sec = msec / 1000;
+ ts.tv_nsec = (msec % 1000) * 1000000;
+ (void)nanosleep(&ts, NULL);
+ }
+#else
+# ifdef HAVE_USLEEP
+ while (msec >= 1000) {
+ usleep((unsigned int)(999 * 1000));
+ msec -= 999;
+ }
+ usleep((unsigned int)(msec * 1000));
+# else
+# ifndef HAVE_SELECT
+ poll(NULL, 0, (int)msec);
+# else
+ {
+ struct timeval tv;
+
+ tv.tv_sec = msec / 1000;
+ tv.tv_usec = (msec % 1000) * 1000;
+ /*
+ * NOTE: Solaris 2.6 has a bug that makes select() hang here. Get
+ * a patch from Sun to fix this. Reported by Gunnar Pedersen.
+ */
+ select(0, NULL, NULL, NULL, &tv);
+ }
+# endif /* HAVE_SELECT */
+# endif /* HAVE_NANOSLEEP */
+#endif /* HAVE_USLEEP */
+
+ settmode(old_tmode);
+ in_mch_delay = FALSE;
+ } else
+ WaitForChar(msec);
+}
+
+#if defined(HAVE_STACK_LIMIT) \
+ || (!defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGSTACK))
+# define HAVE_CHECK_STACK_GROWTH
+/*
+ * Support for checking for an almost-out-of-stack-space situation.
+ */
+
+/*
+ * Return a pointer to an item on the stack. Used to find out if the stack
+ * grows up or down.
+ */
+static void check_stack_growth __ARGS((char *p));
+static int stack_grows_downwards;
+
+/*
+ * Find out if the stack grows upwards or downwards.
+ * "p" points to a variable on the stack of the caller.
+ */
+static void check_stack_growth(p)
+char *p;
+{
+ int i;
+
+ stack_grows_downwards = (p > (char *)&i);
+}
+#endif
+
+#if defined(HAVE_STACK_LIMIT) || defined(PROTO)
+static char *stack_limit = NULL;
+
+#if defined(_THREAD_SAFE) && defined(HAVE_PTHREAD_NP_H)
+# include <pthread.h>
+# include <pthread_np.h>
+#endif
+
+/*
+ * Find out until how var the stack can grow without getting into trouble.
+ * Called when starting up and when switching to the signal stack in
+ * deathtrap().
+ */
+static void get_stack_limit() {
+ struct rlimit rlp;
+ int i;
+ long lim;
+
+ /* Set the stack limit to 15/16 of the allowable size. Skip this when the
+ * limit doesn't fit in a long (rlim_cur might be "long long"). */
+ if (getrlimit(RLIMIT_STACK, &rlp) == 0
+ && rlp.rlim_cur < ((rlim_t)1 << (sizeof(long_u) * 8 - 1))
+# ifdef RLIM_INFINITY
+ && rlp.rlim_cur != RLIM_INFINITY
+# endif
+ ) {
+ lim = (long)rlp.rlim_cur;
+#if defined(_THREAD_SAFE) && defined(HAVE_PTHREAD_NP_H)
+ {
+ pthread_attr_t attr;
+ size_t size;
+
+ /* On FreeBSD the initial thread always has a fixed stack size, no
+ * matter what the limits are set to. Normally it's 1 Mbyte. */
+ pthread_attr_init(&attr);
+ if (pthread_attr_get_np(pthread_self(), &attr) == 0) {
+ pthread_attr_getstacksize(&attr, &size);
+ if (lim > (long)size)
+ lim = (long)size;
+ }
+ pthread_attr_destroy(&attr);
+ }
+#endif
+ if (stack_grows_downwards) {
+ stack_limit = (char *)((long)&i - (lim / 16L * 15L));
+ if (stack_limit >= (char *)&i)
+ /* overflow, set to 1/16 of current stack position */
+ stack_limit = (char *)((long)&i / 16L);
+ } else {
+ stack_limit = (char *)((long)&i + (lim / 16L * 15L));
+ if (stack_limit <= (char *)&i)
+ stack_limit = NULL; /* overflow */
+ }
+ }
+}
+
+/*
+ * Return FAIL when running out of stack space.
+ * "p" must point to any variable local to the caller that's on the stack.
+ */
+int mch_stackcheck(p)
+char *p;
+{
+ if (stack_limit != NULL) {
+ if (stack_grows_downwards) {
+ if (p < stack_limit)
+ return FAIL;
+ } else if (p > stack_limit)
+ return FAIL;
+ }
+ return OK;
+}
+#endif
+
+#if defined(HAVE_SIGALTSTACK) || defined(HAVE_SIGSTACK)
+/*
+ * Support for using the signal stack.
+ * This helps when we run out of stack space, which causes a SIGSEGV. The
+ * signal handler then must run on another stack, since the normal stack is
+ * completely full.
+ */
+
+
+#ifndef SIGSTKSZ
+# define SIGSTKSZ 8000 /* just a guess of how much stack is needed... */
+#endif
+
+# ifdef HAVE_SIGALTSTACK
+static stack_t sigstk; /* for sigaltstack() */
+# else
+static struct sigstack sigstk; /* for sigstack() */
+# endif
+
+static void init_signal_stack __ARGS((void));
+static char *signal_stack;
+
+static void init_signal_stack() {
+ if (signal_stack != NULL) {
+# ifdef HAVE_SIGALTSTACK
+ sigstk.ss_sp = signal_stack;
+ sigstk.ss_size = SIGSTKSZ;
+ sigstk.ss_flags = 0;
+ (void)sigaltstack(&sigstk, NULL);
+# else
+ sigstk.ss_sp = signal_stack;
+ if (stack_grows_downwards)
+ sigstk.ss_sp += SIGSTKSZ - 1;
+ sigstk.ss_onstack = 0;
+ (void)sigstack(&sigstk, NULL);
+# endif
+ }
+}
+
+#endif
+
+/*
+ * We need correct prototypes for a signal function, otherwise mean compilers
+ * will barf when the second argument to signal() is ``wrong''.
+ * Let me try it with a few tricky defines from my own osdef.h (jw).
+ */
+#if defined(SIGWINCH)
+static RETSIGTYPE
+sig_winch SIGDEFARG(sigarg) {
+ /* this is not required on all systems, but it doesn't hurt anybody */
+ signal(SIGWINCH, (RETSIGTYPE (*)())sig_winch);
+ do_resize = TRUE;
+ SIGRETURN;
+}
+
+#endif
+
+#if defined(SIGINT)
+static RETSIGTYPE
+catch_sigint SIGDEFARG(sigarg) {
+ /* this is not required on all systems, but it doesn't hurt anybody */
+ signal(SIGINT, (RETSIGTYPE (*)())catch_sigint);
+ got_int = TRUE;
+ SIGRETURN;
+}
+
+#endif
+
+#if defined(SIGPWR)
+static RETSIGTYPE
+catch_sigpwr SIGDEFARG(sigarg) {
+ /* this is not required on all systems, but it doesn't hurt anybody */
+ signal(SIGPWR, (RETSIGTYPE (*)())catch_sigpwr);
+ /*
+ * I'm not sure we get the SIGPWR signal when the system is really going
+ * down or when the batteries are almost empty. Just preserve the swap
+ * files and don't exit, that can't do any harm.
+ */
+ ml_sync_all(FALSE, FALSE);
+ SIGRETURN;
+}
+
+#endif
+
+#if (defined(HAVE_SETJMP_H) && defined(FEAT_LIBCALL)) || defined(PROTO)
+/*
+ * A simplistic version of setjmp() that only allows one level of using.
+ * Don't call twice before calling mch_endjmp()!.
+ * Usage:
+ * mch_startjmp();
+ * if (SETJMP(lc_jump_env) != 0)
+ * {
+ * mch_didjmp();
+ * EMSG("crash!");
+ * }
+ * else
+ * {
+ * do_the_work;
+ * mch_endjmp();
+ * }
+ * Note: Can't move SETJMP() here, because a function calling setjmp() must
+ * not return before the saved environment is used.
+ * Returns OK for normal return, FAIL when the protected code caused a
+ * problem and LONGJMP() was used.
+ */
+void mch_startjmp() {
+#ifdef SIGHASARG
+ lc_signal = 0;
+#endif
+ lc_active = TRUE;
+}
+
+void mch_endjmp() {
+ lc_active = FALSE;
+}
+
+void mch_didjmp() {
+# if defined(HAVE_SIGALTSTACK) || defined(HAVE_SIGSTACK)
+ /* On FreeBSD the signal stack has to be reset after using siglongjmp(),
+ * otherwise catching the signal only works once. */
+ init_signal_stack();
+# endif
+}
+
+#endif
+
+/*
+ * This function handles deadly signals.
+ * It tries to preserve any swap files and exit properly.
+ * (partly from Elvis).
+ * NOTE: Avoid unsafe functions, such as allocating memory, they can result in
+ * a deadlock.
+ */
+static RETSIGTYPE
+deathtrap SIGDEFARG(sigarg) {
+ static int entered = 0; /* count the number of times we got here.
+ Note: when memory has been corrupted
+ this may get an arbitrary value! */
+#ifdef SIGHASARG
+ int i;
+#endif
+
+#if defined(HAVE_SETJMP_H)
+ /*
+ * Catch a crash in protected code.
+ * Restores the environment saved in lc_jump_env, which looks like
+ * SETJMP() returns 1.
+ */
+ if (lc_active) {
+# if defined(SIGHASARG)
+ lc_signal = sigarg;
+# endif
+ lc_active = FALSE; /* don't jump again */
+ LONGJMP(lc_jump_env, 1);
+ /* NOTREACHED */
+ }
+#endif
+
+#ifdef SIGHASARG
+# ifdef SIGQUIT
+ /* While in mch_delay() we go to cooked mode to allow a CTRL-C to
+ * interrupt us. But in cooked mode we may also get SIGQUIT, e.g., when
+ * pressing CTRL-\, but we don't want Vim to exit then. */
+ if (in_mch_delay && sigarg == SIGQUIT)
+ SIGRETURN;
+# endif
+
+ /* When SIGHUP, SIGQUIT, etc. are blocked: postpone the effect and return
+ * here. This avoids that a non-reentrant function is interrupted, e.g.,
+ * free(). Calling free() again may then cause a crash. */
+ if (entered == 0
+ && (0
+# ifdef SIGHUP
+ || sigarg == SIGHUP
+# endif
+# ifdef SIGQUIT
+ || sigarg == SIGQUIT
+# endif
+# ifdef SIGTERM
+ || sigarg == SIGTERM
+# endif
+# ifdef SIGPWR
+ || sigarg == SIGPWR
+# endif
+# ifdef SIGUSR1
+ || sigarg == SIGUSR1
+# endif
+# ifdef SIGUSR2
+ || sigarg == SIGUSR2
+# endif
+ )
+ && !vim_handle_signal(sigarg))
+ SIGRETURN;
+#endif
+
+ /* Remember how often we have been called. */
+ ++entered;
+
+ /* Set the v:dying variable. */
+ set_vim_var_nr(VV_DYING, (long)entered);
+
+#ifdef HAVE_STACK_LIMIT
+ /* Since we are now using the signal stack, need to reset the stack
+ * limit. Otherwise using a regexp will fail. */
+ get_stack_limit();
+#endif
+
+
+#ifdef SIGHASARG
+ /* try to find the name of this signal */
+ for (i = 0; signal_info[i].sig != -1; i++)
+ if (sigarg == signal_info[i].sig)
+ break;
+ deadly_signal = sigarg;
+#endif
+
+ full_screen = FALSE; /* don't write message to the GUI, it might be
+ * part of the problem... */
+ /*
+ * If something goes wrong after entering here, we may get here again.
+ * When this happens, give a message and try to exit nicely (resetting the
+ * terminal mode, etc.)
+ * When this happens twice, just exit, don't even try to give a message,
+ * stack may be corrupt or something weird.
+ * When this still happens again (or memory was corrupted in such a way
+ * that "entered" was clobbered) use _exit(), don't try freeing resources.
+ */
+ if (entered >= 3) {
+ reset_signals(); /* don't catch any signals anymore */
+ may_core_dump();
+ if (entered >= 4)
+ _exit(8);
+ exit(7);
+ }
+ if (entered == 2) {
+ /* No translation, it may call malloc(). */
+ OUT_STR("Vim: Double signal, exiting\n");
+ out_flush();
+ getout(1);
+ }
+
+ /* No translation, it may call malloc(). */
+#ifdef SIGHASARG
+ sprintf((char *)IObuff, "Vim: Caught deadly signal %s\n",
+ signal_info[i].name);
+#else
+ sprintf((char *)IObuff, "Vim: Caught deadly signal\n");
+#endif
+
+ /* Preserve files and exit. This sets the really_exiting flag to prevent
+ * calling free(). */
+ preserve_exit();
+
+
+ SIGRETURN;
+}
+
+#if defined(_REENTRANT) && defined(SIGCONT)
+/*
+ * On Solaris with multi-threading, suspending might not work immediately.
+ * Catch the SIGCONT signal, which will be used as an indication whether the
+ * suspending has been done or not.
+ *
+ * On Linux, signal is not always handled immediately either.
+ * See https://bugs.launchpad.net/bugs/291373
+ *
+ * volatile because it is used in signal handler sigcont_handler().
+ */
+static volatile int sigcont_received;
+static RETSIGTYPE sigcont_handler __ARGS(SIGPROTOARG);
+
+/*
+ * signal handler for SIGCONT
+ */
+static RETSIGTYPE
+sigcont_handler SIGDEFARG(sigarg) {
+ sigcont_received = TRUE;
+ SIGRETURN;
+}
+
+#endif
+
+
+/*
+ * If the machine has job control, use it to suspend the program,
+ * otherwise fake it by starting a new shell.
+ */
+void mch_suspend() {
+ /* BeOS does have SIGTSTP, but it doesn't work. */
+#if defined(SIGTSTP) && !defined(__BEOS__)
+ out_flush(); /* needed to make cursor visible on some systems */
+ settmode(TMODE_COOK);
+ out_flush(); /* needed to disable mouse on some systems */
+
+
+# if defined(_REENTRANT) && defined(SIGCONT)
+ sigcont_received = FALSE;
+# endif
+ kill(0, SIGTSTP); /* send ourselves a STOP signal */
+# if defined(_REENTRANT) && defined(SIGCONT)
+ /*
+ * Wait for the SIGCONT signal to be handled. It generally happens
+ * immediately, but somehow not all the time. Do not call pause()
+ * because there would be race condition which would hang Vim if
+ * signal happened in between the test of sigcont_received and the
+ * call to pause(). If signal is not yet received, call sleep(0)
+ * to just yield CPU. Signal should then be received. If somehow
+ * it's still not received, sleep 1, 2, 3 ms. Don't bother waiting
+ * further if signal is not received after 1+2+3+4 ms (not expected
+ * to happen).
+ */
+ {
+ long wait_time;
+ for (wait_time = 0; !sigcont_received && wait_time <= 3L; wait_time++)
+ /* Loop is not entered most of the time */
+ mch_delay(wait_time, FALSE);
+ }
+# endif
+
+ /*
+ * Set oldtitle to NULL, so the current title is obtained again.
+ */
+ vim_free(oldtitle);
+ oldtitle = NULL;
+ settmode(TMODE_RAW);
+ need_check_timestamps = TRUE;
+ did_check_timestamps = FALSE;
+#else
+ suspend_shell();
+#endif
+}
+
+void mch_init() {
+ Columns = 80;
+ Rows = 24;
+
+ out_flush();
+ set_signals();
+
+#ifdef MACOS_CONVERT
+ mac_conv_init();
+#endif
+}
+
+static void set_signals() {
+#if defined(SIGWINCH)
+ /*
+ * WINDOW CHANGE signal is handled with sig_winch().
+ */
+ signal(SIGWINCH, (RETSIGTYPE (*)())sig_winch);
+#endif
+
+ /*
+ * We want the STOP signal to work, to make mch_suspend() work.
+ * For "rvim" the STOP signal is ignored.
+ */
+#ifdef SIGTSTP
+ signal(SIGTSTP, restricted ? SIG_IGN : SIG_DFL);
+#endif
+#if defined(_REENTRANT) && defined(SIGCONT)
+ signal(SIGCONT, sigcont_handler);
+#endif
+
+ /*
+ * We want to ignore breaking of PIPEs.
+ */
+#ifdef SIGPIPE
+ signal(SIGPIPE, SIG_IGN);
+#endif
+
+#ifdef SIGINT
+ catch_int_signal();
+#endif
+
+ /*
+ * Ignore alarm signals (Perl's alarm() generates it).
+ */
+#ifdef SIGALRM
+ signal(SIGALRM, SIG_IGN);
+#endif
+
+ /*
+ * Catch SIGPWR (power failure?) to preserve the swap files, so that no
+ * work will be lost.
+ */
+#ifdef SIGPWR
+ signal(SIGPWR, (RETSIGTYPE (*)())catch_sigpwr);
+#endif
+
+ /*
+ * Arrange for other signals to gracefully shutdown Vim.
+ */
+ catch_signals(deathtrap, SIG_ERR);
+
+}
+
+#if defined(SIGINT) || defined(PROTO)
+/*
+ * Catch CTRL-C (only works while in Cooked mode).
+ */
+static void catch_int_signal() {
+ signal(SIGINT, (RETSIGTYPE (*)())catch_sigint);
+}
+
+#endif
+
+void reset_signals() {
+ catch_signals(SIG_DFL, SIG_DFL);
+#if defined(_REENTRANT) && defined(SIGCONT)
+ /* SIGCONT isn't in the list, because its default action is ignore */
+ signal(SIGCONT, SIG_DFL);
+#endif
+}
+
+static void catch_signals(func_deadly, func_other)
+RETSIGTYPE (*func_deadly)();
+RETSIGTYPE (*func_other)();
+{
+ int i;
+
+ for (i = 0; signal_info[i].sig != -1; i++)
+ if (signal_info[i].deadly) {
+#if defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGACTION)
+ struct sigaction sa;
+
+ /* Setup to use the alternate stack for the signal function. */
+ sa.sa_handler = func_deadly;
+ sigemptyset(&sa.sa_mask);
+# if defined(__linux__) && defined(_REENTRANT)
+ /* On Linux, with glibc compiled for kernel 2.2, there is a bug in
+ * thread handling in combination with using the alternate stack:
+ * pthread library functions try to use the stack pointer to
+ * identify the current thread, causing a SEGV signal, which
+ * recursively calls deathtrap() and hangs. */
+ sa.sa_flags = 0;
+# else
+ sa.sa_flags = SA_ONSTACK;
+# endif
+ sigaction(signal_info[i].sig, &sa, NULL);
+#else
+# if defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGVEC)
+ struct sigvec sv;
+
+ /* Setup to use the alternate stack for the signal function. */
+ sv.sv_handler = func_deadly;
+ sv.sv_mask = 0;
+ sv.sv_flags = SV_ONSTACK;
+ sigvec(signal_info[i].sig, &sv, NULL);
+# else
+ signal(signal_info[i].sig, func_deadly);
+# endif
+#endif
+ } else if (func_other != SIG_ERR)
+ signal(signal_info[i].sig, func_other);
+}
+
+/*
+ * Handling of SIGHUP, SIGQUIT and SIGTERM:
+ * "when" == a signal: when busy, postpone and return FALSE, otherwise
+ * return TRUE
+ * "when" == SIGNAL_BLOCK: Going to be busy, block signals
+ * "when" == SIGNAL_UNBLOCK: Going to wait, unblock signals, use postponed
+ * signal
+ * Returns TRUE when Vim should exit.
+ */
+int vim_handle_signal(sig)
+int sig;
+{
+ static int got_signal = 0;
+ static int blocked = TRUE;
+
+ switch (sig) {
+ case SIGNAL_BLOCK: blocked = TRUE;
+ break;
+
+ case SIGNAL_UNBLOCK: blocked = FALSE;
+ if (got_signal != 0) {
+ kill(getpid(), got_signal);
+ got_signal = 0;
+ }
+ break;
+
+ default: if (!blocked)
+ return TRUE; /* exit! */
+ got_signal = sig;
+#ifdef SIGPWR
+ if (sig != SIGPWR)
+#endif
+ got_int = TRUE; /* break any loops */
+ break;
+ }
+ return FALSE;
+}
+
+/*
+ * Check_win checks whether we have an interactive stdout.
+ */
+int mch_check_win(argc, argv)
+int argc UNUSED;
+char **argv UNUSED;
+{
+ if (isatty(1))
+ return OK;
+ return FAIL;
+}
+
+/*
+ * Return TRUE if the input comes from a terminal, FALSE otherwise.
+ */
+int mch_input_isatty() {
+ if (isatty(read_cmd_fd))
+ return TRUE;
+ return FALSE;
+}
+
+static int get_x11_title(test_only)
+int test_only UNUSED;
+{
+ return FALSE;
+}
+
+static int get_x11_icon(test_only)
+int test_only;
+{
+ if (!test_only) {
+ if (STRNCMP(T_NAME, "builtin_", 8) == 0)
+ oldicon = vim_strsave(T_NAME + 8);
+ else
+ oldicon = vim_strsave(T_NAME);
+ }
+ return FALSE;
+}
+
+
+int mch_can_restore_title() {
+ return get_x11_title(TRUE);
+}
+
+int mch_can_restore_icon() {
+ return get_x11_icon(TRUE);
+}
+
+/*
+ * Set the window title and icon.
+ */
+void mch_settitle(title, icon)
+char_u *title;
+char_u *icon;
+{
+ int type = 0;
+ static int recursive = 0;
+
+ if (T_NAME == NULL) /* no terminal name (yet) */
+ return;
+ if (title == NULL && icon == NULL) /* nothing to do */
+ return;
+
+ /* When one of the X11 functions causes a deadly signal, we get here again
+ * recursively. Avoid hanging then (something is probably locked). */
+ if (recursive)
+ return;
+ ++recursive;
+
+ /*
+ * if the window ID and the display is known, we may use X11 calls
+ */
+
+ /*
+ * Note: if "t_ts" is set, title is set with escape sequence rather
+ * than x11 calls, because the x11 calls don't always work
+ */
+ if ((type || *T_TS != NUL) && title != NULL) {
+ if (oldtitle == NULL
+ ) /* first call but not in GUI, save title */
+ (void)get_x11_title(FALSE);
+
+ if (*T_TS != NUL) /* it's OK if t_fs is empty */
+ term_settitle(title);
+ did_set_title = TRUE;
+ }
+
+ if ((type || *T_CIS != NUL) && icon != NULL) {
+ if (oldicon == NULL
+ ) /* first call, save icon */
+ get_x11_icon(FALSE);
+
+ if (*T_CIS != NUL) {
+ out_str(T_CIS); /* set icon start */
+ out_str_nf(icon);
+ out_str(T_CIE); /* set icon end */
+ out_flush();
+ }
+ did_set_icon = TRUE;
+ }
+ --recursive;
+}
+
+/*
+ * Restore the window/icon title.
+ * "which" is one of:
+ * 1 only restore title
+ * 2 only restore icon
+ * 3 restore title and icon
+ */
+void mch_restore_title(which)
+int which;
+{
+ /* only restore the title or icon when it has been set */
+ mch_settitle(((which & 1) && did_set_title) ?
+ (oldtitle ? oldtitle : p_titleold) : NULL,
+ ((which & 2) && did_set_icon) ? oldicon : NULL);
+}
+
+
+/*
+ * Return TRUE if "name" looks like some xterm name.
+ * Seiichi Sato mentioned that "mlterm" works like xterm.
+ */
+int vim_is_xterm(name)
+char_u *name;
+{
+ if (name == NULL)
+ return FALSE;
+ return STRNICMP(name, "xterm", 5) == 0
+ || STRNICMP(name, "nxterm", 6) == 0
+ || STRNICMP(name, "kterm", 5) == 0
+ || STRNICMP(name, "mlterm", 6) == 0
+ || STRNICMP(name, "rxvt", 4) == 0
+ || STRCMP(name, "builtin_xterm") == 0;
+}
+
+/*
+ * Return TRUE if "name" appears to be that of a terminal
+ * known to support the xterm-style mouse protocol.
+ * Relies on term_is_xterm having been set to its correct value.
+ */
+int use_xterm_like_mouse(name)
+char_u *name;
+{
+ return name != NULL
+ && (term_is_xterm || STRNICMP(name, "screen", 6) == 0);
+}
+
+/*
+ * Return non-zero when using an xterm mouse, according to 'ttymouse'.
+ * Return 1 for "xterm".
+ * Return 2 for "xterm2".
+ * Return 3 for "urxvt".
+ * Return 4 for "sgr".
+ */
+int use_xterm_mouse() {
+ if (ttym_flags == TTYM_SGR)
+ return 4;
+ if (ttym_flags == TTYM_URXVT)
+ return 3;
+ if (ttym_flags == TTYM_XTERM2)
+ return 2;
+ if (ttym_flags == TTYM_XTERM)
+ return 1;
+ return 0;
+}
+
+int vim_is_iris(name)
+char_u *name;
+{
+ if (name == NULL)
+ return FALSE;
+ return STRNICMP(name, "iris-ansi", 9) == 0
+ || STRCMP(name, "builtin_iris-ansi") == 0;
+}
+
+int vim_is_vt300(name)
+char_u *name;
+{
+ if (name == NULL)
+ return FALSE; /* actually all ANSI comp. terminals should be here */
+ /* catch VT100 - VT5xx */
+ return (STRNICMP(name, "vt", 2) == 0
+ && vim_strchr((char_u *)"12345", name[2]) != NULL)
+ || STRCMP(name, "builtin_vt320") == 0;
+}
+
+/*
+ * Return TRUE if "name" is a terminal for which 'ttyfast' should be set.
+ * This should include all windowed terminal emulators.
+ */
+int vim_is_fastterm(name)
+char_u *name;
+{
+ if (name == NULL)
+ return FALSE;
+ if (vim_is_xterm(name) || vim_is_vt300(name) || vim_is_iris(name))
+ return TRUE;
+ return STRNICMP(name, "hpterm", 6) == 0
+ || STRNICMP(name, "sun-cmd", 7) == 0
+ || STRNICMP(name, "screen", 6) == 0
+ || STRNICMP(name, "dtterm", 6) == 0;
+}
+
+/*
+ * Insert user name in s[len].
+ * Return OK if a name found.
+ */
+int mch_get_user_name(s, len)
+char_u *s;
+int len;
+{
+ return mch_get_uname(getuid(), s, len);
+}
+
+/*
+ * Insert user name for "uid" in s[len].
+ * Return OK if a name found.
+ */
+int mch_get_uname(uid, s, len)
+uid_t uid;
+char_u *s;
+int len;
+{
+#if defined(HAVE_PWD_H) && defined(HAVE_GETPWUID)
+ struct passwd *pw;
+
+ if ((pw = getpwuid(uid)) != NULL
+ && pw->pw_name != NULL && *(pw->pw_name) != NUL) {
+ vim_strncpy(s, (char_u *)pw->pw_name, len - 1);
+ return OK;
+ }
+#endif
+ sprintf((char *)s, "%d", (int)uid); /* assumes s is long enough */
+ return FAIL; /* a number is not a name */
+}
+
+/*
+ * Insert host name is s[len].
+ */
+
+#ifdef HAVE_SYS_UTSNAME_H
+void mch_get_host_name(s, len)
+char_u *s;
+int len;
+{
+ struct utsname vutsname;
+
+ if (uname(&vutsname) < 0)
+ *s = NUL;
+ else
+ vim_strncpy(s, (char_u *)vutsname.nodename, len - 1);
+}
+#else /* HAVE_SYS_UTSNAME_H */
+
+# ifdef HAVE_SYS_SYSTEMINFO_H
+# define gethostname(nam, len) sysinfo(SI_HOSTNAME, nam, len)
+# endif
+
+void mch_get_host_name(s, len)
+char_u *s;
+int len;
+{
+ gethostname((char *)s, len);
+ s[len - 1] = NUL; /* make sure it's terminated */
+}
+#endif /* HAVE_SYS_UTSNAME_H */
+
+/*
+ * return process ID
+ */
+long mch_get_pid() {
+ return (long)getpid();
+}
+
+#if !defined(HAVE_STRERROR) && defined(USE_GETCWD)
+static char *strerror __ARGS((int));
+
+static char * strerror(err)
+int err;
+{
+ extern int sys_nerr;
+ extern char *sys_errlist[];
+ static char er[20];
+
+ if (err > 0 && err < sys_nerr)
+ return sys_errlist[err];
+ sprintf(er, "Error %d", err);
+ return er;
+}
+#endif
+
+/*
+ * Get name of current directory into buffer 'buf' of length 'len' bytes.
+ * Return OK for success, FAIL for failure.
+ */
+int mch_dirname(buf, len)
+char_u *buf;
+int len;
+{
+#if defined(USE_GETCWD)
+ if (getcwd((char *)buf, len) == NULL) {
+ STRCPY(buf, strerror(errno));
+ return FAIL;
+ }
+ return OK;
+#else
+ return getwd((char *)buf) != NULL ? OK : FAIL;
+#endif
+}
+
+
+/*
+ * Get absolute file name into "buf[len]".
+ *
+ * return FAIL for failure, OK for success
+ */
+int mch_FullName(fname, buf, len, force)
+char_u *fname, *buf;
+int len;
+int force; /* also expand when already absolute path */
+{
+ int l;
+#ifdef HAVE_FCHDIR
+ int fd = -1;
+ static int dont_fchdir = FALSE; /* TRUE when fchdir() doesn't work */
+#endif
+ char_u olddir[MAXPATHL];
+ char_u *p;
+ int retval = OK;
+
+
+
+ /* expand it if forced or not an absolute path */
+ if (force || !mch_isFullName(fname)) {
+ /*
+ * If the file name has a path, change to that directory for a moment,
+ * and then do the getwd() (and get back to where we were).
+ * This will get the correct path name with "../" things.
+ */
+ if ((p = vim_strrchr(fname, '/')) != NULL) {
+#ifdef HAVE_FCHDIR
+ /*
+ * Use fchdir() if possible, it's said to be faster and more
+ * reliable. But on SunOS 4 it might not work. Check this by
+ * doing a fchdir() right now.
+ */
+ if (!dont_fchdir) {
+ fd = open(".", O_RDONLY | O_EXTRA, 0);
+ if (fd >= 0 && fchdir(fd) < 0) {
+ close(fd);
+ fd = -1;
+ dont_fchdir = TRUE; /* don't try again */
+ }
+ }
+#endif
+
+ /* Only change directory when we are sure we can return to where
+ * we are now. After doing "su" chdir(".") might not work. */
+ if (
+#ifdef HAVE_FCHDIR
+ fd < 0 &&
+#endif
+ (mch_dirname(olddir, MAXPATHL) == FAIL
+ || mch_chdir((char *)olddir) != 0)) {
+ p = NULL; /* can't get current dir: don't chdir */
+ retval = FAIL;
+ } else {
+ /* The directory is copied into buf[], to be able to remove
+ * the file name without changing it (could be a string in
+ * read-only memory) */
+ if (p - fname >= len)
+ retval = FAIL;
+ else {
+ vim_strncpy(buf, fname, p - fname);
+ if (mch_chdir((char *)buf))
+ retval = FAIL;
+ else
+ fname = p + 1;
+ *buf = NUL;
+ }
+ }
+ }
+ if (mch_dirname(buf, len) == FAIL) {
+ retval = FAIL;
+ *buf = NUL;
+ }
+ if (p != NULL) {
+#ifdef HAVE_FCHDIR
+ if (fd >= 0) {
+ if (p_verbose >= 5) {
+ verbose_enter();
+ MSG("fchdir() to previous dir");
+ verbose_leave();
+ }
+ l = fchdir(fd);
+ close(fd);
+ } else
+#endif
+ l = mch_chdir((char *)olddir);
+ if (l != 0)
+ EMSG(_(e_prev_dir));
+ }
+
+ l = STRLEN(buf);
+ if (l >= len - 1)
+ retval = FAIL; /* no space for trailing "/" */
+ else if (l > 0 && buf[l - 1] != '/' && *fname != NUL
+ && STRCMP(fname, ".") != 0)
+ STRCAT(buf, "/");
+ }
+
+ /* Catch file names which are too long. */
+ if (retval == FAIL || (int)(STRLEN(buf) + STRLEN(fname)) >= len)
+ return FAIL;
+
+ /* Do not append ".", "/dir/." is equal to "/dir". */
+ if (STRCMP(fname, ".") != 0)
+ STRCAT(buf, fname);
+
+ return OK;
+}
+
+/*
+ * Return TRUE if "fname" does not depend on the current directory.
+ */
+int mch_isFullName(fname)
+char_u *fname;
+{
+ return *fname == '/' || *fname == '~';
+}
+
+#if defined(USE_FNAME_CASE) || defined(PROTO)
+/*
+ * Set the case of the file name, if it already exists. This will cause the
+ * file name to remain exactly the same.
+ * Only required for file systems where case is ignored and preserved.
+ */
+void fname_case(name, len)
+char_u *name;
+int len UNUSED; /* buffer size, only used when name gets longer */
+{
+ struct stat st;
+ char_u *slash, *tail;
+ DIR *dirp;
+ struct dirent *dp;
+
+ if (lstat((char *)name, &st) >= 0) {
+ /* Open the directory where the file is located. */
+ slash = vim_strrchr(name, '/');
+ if (slash == NULL) {
+ dirp = opendir(".");
+ tail = name;
+ } else {
+ *slash = NUL;
+ dirp = opendir((char *)name);
+ *slash = '/';
+ tail = slash + 1;
+ }
+
+ if (dirp != NULL) {
+ while ((dp = readdir(dirp)) != NULL) {
+ /* Only accept names that differ in case and are the same byte
+ * length. TODO: accept different length name. */
+ if (STRICMP(tail, dp->d_name) == 0
+ && STRLEN(tail) == STRLEN(dp->d_name)) {
+ char_u newname[MAXPATHL + 1];
+ struct stat st2;
+
+ /* Verify the inode is equal. */
+ vim_strncpy(newname, name, MAXPATHL);
+ vim_strncpy(newname + (tail - name), (char_u *)dp->d_name,
+ MAXPATHL - (tail - name));
+ if (lstat((char *)newname, &st2) >= 0
+ && st.st_ino == st2.st_ino
+ && st.st_dev == st2.st_dev) {
+ STRCPY(tail, dp->d_name);
+ break;
+ }
+ }
+ }
+
+ closedir(dirp);
+ }
+ }
+}
+#endif
+
+/*
+ * Get file permissions for 'name'.
+ * Returns -1 when it doesn't exist.
+ */
+long mch_getperm(name)
+char_u *name;
+{
+ struct stat statb;
+
+ /* Keep the #ifdef outside of stat(), it may be a macro. */
+ if (stat((char *)name, &statb))
+ return -1;
+#ifdef __INTERIX
+ /* The top bit makes the value negative, which means the file doesn't
+ * exist. Remove the bit, we don't use it. */
+ return statb.st_mode & ~S_ADDACE;
+#else
+ return statb.st_mode;
+#endif
+}
+
+/*
+ * set file permission for 'name' to 'perm'
+ *
+ * return FAIL for failure, OK otherwise
+ */
+int mch_setperm(name, perm)
+char_u *name;
+long perm;
+{
+ return chmod((char *)
+ name,
+ (mode_t)perm) == 0 ? OK : FAIL;
+}
+
+#if defined(HAVE_ACL) || defined(PROTO)
+# ifdef HAVE_SYS_ACL_H
+# include <sys/acl.h>
+# endif
+# ifdef HAVE_SYS_ACCESS_H
+# include <sys/access.h>
+# endif
+
+
+#if defined(HAVE_SELINUX) || defined(PROTO)
+/*
+ * Copy security info from "from_file" to "to_file".
+ */
+void mch_copy_sec(from_file, to_file)
+char_u *from_file;
+char_u *to_file;
+{
+ if (from_file == NULL)
+ return;
+
+ if (selinux_enabled == -1)
+ selinux_enabled = is_selinux_enabled();
+
+ if (selinux_enabled > 0) {
+ security_context_t from_context = NULL;
+ 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)
+ return;
+
+ MSG_PUTS(_("\nCould not get security context for "));
+ msg_outtrans(from_file);
+ msg_putchar('\n');
+ return;
+ }
+ if (getfilecon((char *)to_file, &to_context) < 0) {
+ MSG_PUTS(_("\nCould not get security context for "));
+ msg_outtrans(to_file);
+ msg_putchar('\n');
+ freecon (from_context);
+ return;
+ }
+ if (strcmp(from_context, to_context) != 0) {
+ if (setfilecon((char *)to_file, from_context) < 0) {
+ MSG_PUTS(_("\nCould not set security context for "));
+ msg_outtrans(to_file);
+ msg_putchar('\n');
+ }
+ }
+ freecon(to_context);
+ freecon(from_context);
+ }
+}
+#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(fname)
+char_u *fname UNUSED;
+{
+ vim_acl_T ret = NULL;
+ return ret;
+}
+
+/*
+ * Set the ACL of file "fname" to "acl" (unless it's NULL).
+ */
+void mch_set_acl(fname, aclent)
+char_u *fname UNUSED;
+vim_acl_T aclent;
+{
+ if (aclent == NULL)
+ return;
+}
+
+void mch_free_acl(aclent)
+vim_acl_T aclent;
+{
+ if (aclent == NULL)
+ return;
+}
+#endif
+
+/*
+ * Set hidden flag for "name".
+ */
+void mch_hide(name)
+char_u *name UNUSED;
+{
+ /* can't hide a file */
+}
+
+/*
+ * return TRUE if "name" is a directory
+ * return FALSE if "name" is not a directory
+ * return FALSE for error
+ */
+int mch_isdir(name)
+char_u *name;
+{
+ struct stat statb;
+
+ if (*name == NUL) /* Some stat()s don't flag "" as an error. */
+ return FALSE;
+ if (stat((char *)name, &statb))
+ return FALSE;
+#ifdef _POSIX_SOURCE
+ return S_ISDIR(statb.st_mode) ? TRUE : FALSE;
+#else
+ return (statb.st_mode & S_IFMT) == S_IFDIR ? TRUE : FALSE;
+#endif
+}
+
+static int executable_file __ARGS((char_u *name));
+
+/*
+ * Return 1 if "name" is an executable file, 0 if not or it doesn't exist.
+ */
+static int executable_file(name)
+char_u *name;
+{
+ struct stat st;
+
+ if (stat((char *)name, &st))
+ return 0;
+ return S_ISREG(st.st_mode) && mch_access((char *)name, X_OK) == 0;
+}
+
+/*
+ * Return 1 if "name" can be found in $PATH and executed, 0 if not.
+ * Return -1 if unknown.
+ */
+int mch_can_exe(name)
+char_u *name;
+{
+ char_u *buf;
+ char_u *p, *e;
+ int retval;
+
+ /* If it's an absolute or relative path don't need to use $PATH. */
+ if (mch_isFullName(name) || (name[0] == '.' && (name[1] == '/'
+ || (name[1] == '.' &&
+ name[2] == '/'))))
+ return executable_file(name);
+
+ p = (char_u *)getenv("PATH");
+ if (p == NULL || *p == NUL)
+ return -1;
+ buf = alloc((unsigned)(STRLEN(name) + STRLEN(p) + 2));
+ if (buf == NULL)
+ return -1;
+
+ /*
+ * Walk through all entries in $PATH to check if "name" exists there and
+ * is an executable file.
+ */
+ for (;; ) {
+ e = (char_u *)strchr((char *)p, ':');
+ if (e == NULL)
+ e = p + STRLEN(p);
+ if (e - p <= 1) /* empty entry means current dir */
+ STRCPY(buf, "./");
+ else {
+ vim_strncpy(buf, p, e - p);
+ add_pathsep(buf);
+ }
+ STRCAT(buf, name);
+ retval = executable_file(buf);
+ if (retval == 1)
+ break;
+
+ if (*e != ':')
+ break;
+ p = e + 1;
+ }
+
+ vim_free(buf);
+ return retval;
+}
+
+/*
+ * Check what "name" is:
+ * NODE_NORMAL: file or directory (or doesn't exist)
+ * NODE_WRITABLE: writable device, socket, fifo, etc.
+ * NODE_OTHER: non-writable things
+ */
+int mch_nodetype(name)
+char_u *name;
+{
+ struct stat st;
+
+ if (stat((char *)name, &st))
+ return NODE_NORMAL;
+ if (S_ISREG(st.st_mode) || S_ISDIR(st.st_mode))
+ return NODE_NORMAL;
+ if (S_ISBLK(st.st_mode)) /* block device isn't writable */
+ return NODE_OTHER;
+ /* Everything else is writable? */
+ return NODE_WRITABLE;
+}
+
+void mch_early_init() {
+#ifdef HAVE_CHECK_STACK_GROWTH
+ int i;
+
+ check_stack_growth((char *)&i);
+
+# ifdef HAVE_STACK_LIMIT
+ get_stack_limit();
+# endif
+
+#endif
+
+ /*
+ * Setup an alternative stack for signals. Helps to catch signals when
+ * running out of stack space.
+ * Use of sigaltstack() is preferred, it's more portable.
+ * Ignore any errors.
+ */
+#if defined(HAVE_SIGALTSTACK) || defined(HAVE_SIGSTACK)
+ signal_stack = (char *)alloc(SIGSTKSZ);
+ init_signal_stack();
+#endif
+}
+
+#if defined(EXITFREE) || defined(PROTO)
+void mch_free_mem() {
+# if defined(HAVE_SIGALTSTACK) || defined(HAVE_SIGSTACK)
+ vim_free(signal_stack);
+ signal_stack = NULL;
+# endif
+ vim_free(oldtitle);
+ vim_free(oldicon);
+}
+
+#endif
+
+static void exit_scroll __ARGS((void));
+
+/*
+ * Output a newline when exiting.
+ * Make sure the newline goes to the same stream as the text.
+ */
+static void exit_scroll() {
+ if (silent_mode)
+ return;
+ if (newline_on_exit || msg_didout) {
+ if (msg_use_printf()) {
+ if (info_message)
+ mch_msg("\n");
+ else
+ mch_errmsg("\r\n");
+ } else
+ out_char('\n');
+ } else {
+ restore_cterm_colors(); /* get original colors back */
+ msg_clr_eos_force(); /* clear the rest of the display */
+ windgoto((int)Rows - 1, 0); /* may have moved the cursor */
+ }
+}
+
+void mch_exit(r)
+int r;
+{
+ exiting = TRUE;
+
+
+ {
+ settmode(TMODE_COOK);
+ mch_restore_title(3); /* restore xterm title and icon name */
+ /*
+ * When t_ti is not empty but it doesn't cause swapping terminal
+ * pages, need to output a newline when msg_didout is set. But when
+ * t_ti does swap pages it should not go to the shell page. Do this
+ * before stoptermcap().
+ */
+ if (swapping_screen() && !newline_on_exit)
+ exit_scroll();
+
+ /* Stop termcap: May need to check for T_CRV response, which
+ * requires RAW mode. */
+ stoptermcap();
+
+ /*
+ * A newline is only required after a message in the alternate screen.
+ * This is set to TRUE by wait_return().
+ */
+ if (!swapping_screen() || newline_on_exit)
+ exit_scroll();
+
+ /* Cursor may have been switched off without calling starttermcap()
+ * when doing "vim -u vimrc" and vimrc contains ":q". */
+ if (full_screen)
+ cursor_on();
+ }
+ out_flush();
+ ml_close_all(TRUE); /* remove all memfiles */
+ may_core_dump();
+
+#ifdef MACOS_CONVERT
+ mac_conv_cleanup();
+#endif
+
+
+
+#ifdef EXITFREE
+ free_all_mem();
+#endif
+
+ exit(r);
+}
+
+static void may_core_dump() {
+ if (deadly_signal != 0) {
+ signal(deadly_signal, SIG_DFL);
+ kill(getpid(), deadly_signal); /* Die using the signal we caught */
+ }
+}
+
+void mch_settmode(tmode)
+int tmode;
+{
+ static int first = TRUE;
+
+ /* Why is NeXT excluded here (and not in os_unixx.h)? */
+#if defined(ECHOE) && defined(ICANON) && (defined(HAVE_TERMIO_H) || \
+ defined(HAVE_TERMIOS_H)) && !defined(__NeXT__)
+ /*
+ * for "new" tty systems
+ */
+# ifdef HAVE_TERMIOS_H
+ static struct termios told;
+ struct termios tnew;
+# else
+ static struct termio told;
+ struct termio tnew;
+# endif
+
+ if (first) {
+ first = FALSE;
+# if defined(HAVE_TERMIOS_H)
+ tcgetattr(read_cmd_fd, &told);
+# else
+ ioctl(read_cmd_fd, TCGETA, &told);
+# endif
+ }
+
+ tnew = told;
+ if (tmode == TMODE_RAW) {
+ /*
+ * ~ICRNL enables typing ^V^M
+ */
+ tnew.c_iflag &= ~ICRNL;
+ tnew.c_lflag &= ~(ICANON | ECHO | ISIG | ECHOE
+# if defined(IEXTEN) && !defined(__MINT__)
+ | IEXTEN /* IEXTEN enables typing ^V on SOLARIS */
+ /* but it breaks function keys on MINT */
+# endif
+ );
+# ifdef ONLCR /* don't map NL -> CR NL, we do it ourselves */
+ tnew.c_oflag &= ~ONLCR;
+# endif
+ tnew.c_cc[VMIN] = 1; /* return after 1 char */
+ tnew.c_cc[VTIME] = 0; /* don't wait */
+ } else if (tmode == TMODE_SLEEP)
+ tnew.c_lflag &= ~(ECHO);
+
+# if defined(HAVE_TERMIOS_H)
+ {
+ int n = 10;
+
+ /* A signal may cause tcsetattr() to fail (e.g., SIGCONT). Retry a
+ * few times. */
+ while (tcsetattr(read_cmd_fd, TCSANOW, &tnew) == -1
+ && errno == EINTR && n > 0)
+ --n;
+ }
+# else
+ ioctl(read_cmd_fd, TCSETA, &tnew);
+# endif
+
+#else
+
+ /*
+ * for "old" tty systems
+ */
+# ifndef TIOCSETN
+# define TIOCSETN TIOCSETP /* for hpux 9.0 */
+# endif
+ static struct sgttyb ttybold;
+ struct sgttyb ttybnew;
+
+ if (first) {
+ first = FALSE;
+ ioctl(read_cmd_fd, TIOCGETP, &ttybold);
+ }
+
+ ttybnew = ttybold;
+ if (tmode == TMODE_RAW) {
+ ttybnew.sg_flags &= ~(CRMOD | ECHO);
+ ttybnew.sg_flags |= RAW;
+ } else if (tmode == TMODE_SLEEP)
+ ttybnew.sg_flags &= ~(ECHO);
+ ioctl(read_cmd_fd, TIOCSETN, &ttybnew);
+#endif
+ curr_tmode = tmode;
+}
+
+/*
+ * Try to get the code for "t_kb" from the stty setting
+ *
+ * Even if termcap claims a backspace key, the user's setting *should*
+ * prevail. stty knows more about reality than termcap does, and if
+ * somebody's usual erase key is DEL (which, for most BSD users, it will
+ * be), they're going to get really annoyed if their erase key starts
+ * doing forward deletes for no reason. (Eric Fischer)
+ */
+void get_stty() {
+ char_u buf[2];
+ char_u *p;
+
+ /* Why is NeXT excluded here (and not in os_unixx.h)? */
+#if defined(ECHOE) && defined(ICANON) && (defined(HAVE_TERMIO_H) || \
+ defined(HAVE_TERMIOS_H)) && !defined(__NeXT__)
+ /* for "new" tty systems */
+# ifdef HAVE_TERMIOS_H
+ struct termios keys;
+# else
+ struct termio keys;
+# endif
+
+# if defined(HAVE_TERMIOS_H)
+ if (tcgetattr(read_cmd_fd, &keys) != -1)
+# else
+ if (ioctl(read_cmd_fd, TCGETA, &keys) != -1)
+# endif
+ {
+ buf[0] = keys.c_cc[VERASE];
+ intr_char = keys.c_cc[VINTR];
+#else
+ /* for "old" tty systems */
+ struct sgttyb keys;
+
+ if (ioctl(read_cmd_fd, TIOCGETP, &keys) != -1) {
+ buf[0] = keys.sg_erase;
+ intr_char = keys.sg_kill;
+#endif
+ buf[1] = NUL;
+ add_termcode((char_u *)"kb", buf, FALSE);
+
+ /*
+ * If <BS> and <DEL> are now the same, redefine <DEL>.
+ */
+ p = find_termcode((char_u *)"kD");
+ if (p != NULL && p[0] == buf[0] && p[1] == buf[1])
+ do_fixdel(NULL);
+ }
+}
+
+/*
+ * Set mouse clicks on or off.
+ */
+void mch_setmouse(on)
+int on;
+{
+ static int ison = FALSE;
+ int xterm_mouse_vers;
+
+ if (on == ison) /* return quickly if nothing to do */
+ return;
+
+ xterm_mouse_vers = use_xterm_mouse();
+
+ if (ttym_flags == TTYM_URXVT) {
+ out_str_nf((char_u *)
+ (on
+ ? IF_EB("\033[?1015h", ESC_STR "[?1015h")
+ : IF_EB("\033[?1015l", ESC_STR "[?1015l")));
+ ison = on;
+ }
+
+ if (ttym_flags == TTYM_SGR) {
+ out_str_nf((char_u *)
+ (on
+ ? IF_EB("\033[?1006h", ESC_STR "[?1006h")
+ : IF_EB("\033[?1006l", ESC_STR "[?1006l")));
+ ison = on;
+ }
+
+ if (xterm_mouse_vers > 0) {
+ if (on) /* enable mouse events, use mouse tracking if available */
+ out_str_nf((char_u *)
+ (xterm_mouse_vers > 1
+ ? IF_EB("\033[?1002h", ESC_STR "[?1002h")
+ : IF_EB("\033[?1000h", ESC_STR "[?1000h")));
+ else /* disable mouse events, could probably always send the same */
+ out_str_nf((char_u *)
+ (xterm_mouse_vers > 1
+ ? IF_EB("\033[?1002l", ESC_STR "[?1002l")
+ : IF_EB("\033[?1000l", ESC_STR "[?1000l")));
+ ison = on;
+ } else if (ttym_flags == TTYM_DEC) {
+ if (on) /* enable mouse events */
+ out_str_nf((char_u *)"\033[1;2'z\033[1;3'{");
+ else /* disable mouse events */
+ out_str_nf((char_u *)"\033['z");
+ ison = on;
+ }
+
+}
+
+/*
+ * Set the mouse termcode, depending on the 'term' and 'ttymouse' options.
+ */
+void check_mouse_termcode() {
+ if (use_xterm_mouse()
+ && use_xterm_mouse() != 3
+ ) {
+ set_mouse_termcode(KS_MOUSE, (char_u *)(term_is_8bit(T_NAME)
+ ? IF_EB("\233M", CSI_STR "M")
+ : IF_EB("\033[M", ESC_STR "[M")));
+ if (*p_mouse != NUL) {
+ /* force mouse off and maybe on to send possibly new mouse
+ * activation sequence to the xterm, with(out) drag tracing. */
+ mch_setmouse(FALSE);
+ setmouse();
+ }
+ } else
+ del_mouse_termcode(KS_MOUSE);
+
+
+ /* There is no conflict, but one may type "ESC }" from Insert mode. Don't
+ * define it in the GUI or when using an xterm. */
+ if (!use_xterm_mouse()
+ )
+ set_mouse_termcode(KS_NETTERM_MOUSE,
+ (char_u *)IF_EB("\033}", ESC_STR "}"));
+ else
+ del_mouse_termcode(KS_NETTERM_MOUSE);
+
+ /* conflicts with xterm mouse: "\033[" and "\033[M" */
+ if (!use_xterm_mouse()
+ )
+ set_mouse_termcode(KS_DEC_MOUSE, (char_u *)(term_is_8bit(T_NAME)
+ ? IF_EB("\233",
+ CSI_STR) : IF_EB("\033[",
+ ESC_STR "[")));
+ else
+ del_mouse_termcode(KS_DEC_MOUSE);
+ /* same as the dec mouse */
+ if (use_xterm_mouse() == 3
+ ) {
+ set_mouse_termcode(KS_URXVT_MOUSE, (char_u *)(term_is_8bit(T_NAME)
+ ? IF_EB("\233", CSI_STR)
+ : IF_EB("\033[", ESC_STR "[")));
+
+ if (*p_mouse != NUL) {
+ mch_setmouse(FALSE);
+ setmouse();
+ }
+ } else
+ del_mouse_termcode(KS_URXVT_MOUSE);
+ /* same as the dec mouse */
+ if (use_xterm_mouse() == 4
+ ) {
+ set_mouse_termcode(KS_SGR_MOUSE, (char_u *)(term_is_8bit(T_NAME)
+ ? IF_EB("\233<", CSI_STR "<")
+ : IF_EB("\033[<", ESC_STR "[<")));
+
+ if (*p_mouse != NUL) {
+ mch_setmouse(FALSE);
+ setmouse();
+ }
+ } else
+ del_mouse_termcode(KS_SGR_MOUSE);
+}
+
+/*
+ * set screen mode, always fails.
+ */
+int mch_screenmode(arg)
+char_u *arg UNUSED;
+{
+ EMSG(_(e_screenmode));
+ return FAIL;
+}
+
+
+/*
+ * Try to get the current window size:
+ * 1. with an ioctl(), most accurate method
+ * 2. from the environment variables LINES and COLUMNS
+ * 3. from the termcap
+ * 4. keep using the old values
+ * Return OK when size could be determined, FAIL otherwise.
+ */
+int mch_get_shellsize() {
+ long rows = 0;
+ long columns = 0;
+ char_u *p;
+
+ /*
+ * For OS/2 use _scrsize().
+ */
+
+ /*
+ * 1. try using an ioctl. It is the most accurate method.
+ *
+ * Try using TIOCGWINSZ first, some systems that have it also define
+ * TIOCGSIZE but don't have a struct ttysize.
+ */
+# ifdef TIOCGWINSZ
+ {
+ struct winsize ws;
+ int fd = 1;
+
+ /* When stdout is not a tty, use stdin for the ioctl(). */
+ if (!isatty(fd) && isatty(read_cmd_fd))
+ fd = read_cmd_fd;
+ if (ioctl(fd, TIOCGWINSZ, &ws) == 0) {
+ columns = ws.ws_col;
+ rows = ws.ws_row;
+ }
+ }
+# else /* TIOCGWINSZ */
+# ifdef TIOCGSIZE
+ {
+ struct ttysize ts;
+ int fd = 1;
+
+ /* When stdout is not a tty, use stdin for the ioctl(). */
+ if (!isatty(fd) && isatty(read_cmd_fd))
+ fd = read_cmd_fd;
+ if (ioctl(fd, TIOCGSIZE, &ts) == 0) {
+ columns = ts.ts_cols;
+ rows = ts.ts_lines;
+ }
+ }
+# endif /* TIOCGSIZE */
+# endif /* TIOCGWINSZ */
+
+ /*
+ * 2. get size from environment
+ * When being POSIX compliant ('|' flag in 'cpoptions') this overrules
+ * the ioctl() values!
+ */
+ if (columns == 0 || rows == 0 || vim_strchr(p_cpo, CPO_TSIZE) != NULL) {
+ if ((p = (char_u *)getenv("LINES")))
+ rows = atoi((char *)p);
+ if ((p = (char_u *)getenv("COLUMNS")))
+ columns = atoi((char *)p);
+ }
+
+#ifdef HAVE_TGETENT
+ /*
+ * 3. try reading "co" and "li" entries from termcap
+ */
+ if (columns == 0 || rows == 0)
+ getlinecol(&columns, &rows);
+#endif
+
+ /*
+ * 4. If everything fails, use the old values
+ */
+ if (columns <= 0 || rows <= 0)
+ return FAIL;
+
+ Rows = rows;
+ Columns = columns;
+ limit_screen_size();
+ return OK;
+}
+
+/*
+ * Try to set the window size to Rows and Columns.
+ */
+void mch_set_shellsize() {
+ if (*T_CWS) {
+ /*
+ * NOTE: if you get an error here that term_set_winsize() is
+ * undefined, check the output of configure. It could probably not
+ * find a ncurses, termcap or termlib library.
+ */
+ term_set_winsize((int)Rows, (int)Columns);
+ out_flush();
+ screen_start(); /* don't know where cursor is now */
+ }
+}
+
+/*
+ * Rows and/or Columns has changed.
+ */
+void mch_new_shellsize() {
+ /* Nothing to do. */
+}
+
+/*
+ * Wait for process "child" to end.
+ * Return "child" if it exited properly, <= 0 on error.
+ */
+static pid_t wait4pid(child, status)
+pid_t child;
+waitstatus *status;
+{
+ pid_t wait_pid = 0;
+
+ while (wait_pid != child) {
+ /* When compiled with Python threads are probably used, in which case
+ * wait() sometimes hangs for no obvious reason. Use waitpid()
+ * instead and loop (like the GUI). Also needed for other interfaces,
+ * they might call system(). */
+# ifdef __NeXT__
+ wait_pid = wait4(child, status, WNOHANG, (struct rusage *)0);
+# else
+ wait_pid = waitpid(child, status, WNOHANG);
+# endif
+ if (wait_pid == 0) {
+ /* Wait for 10 msec before trying again. */
+ mch_delay(10L, TRUE);
+ continue;
+ }
+ if (wait_pid <= 0
+# ifdef ECHILD
+ && errno == ECHILD
+# endif
+ )
+ break;
+ }
+ return wait_pid;
+}
+
+int mch_call_shell(cmd, options)
+char_u *cmd;
+int options; /* SHELL_*, see vim.h */
+{
+ int tmode = cur_tmode;
+#ifdef USE_SYSTEM /* use system() to start the shell: simple but slow */
+ int x;
+ char_u *newcmd; /* only needed for unix */
+
+ out_flush();
+
+ if (options & SHELL_COOKED)
+ settmode(TMODE_COOK); /* set to normal mode */
+
+
+ if (cmd == NULL)
+ x = system((char *)p_sh);
+ else {
+ newcmd = lalloc(STRLEN(p_sh)
+ + (extra_shell_arg == NULL ? 0 : STRLEN(extra_shell_arg))
+ + STRLEN(p_shcf) + STRLEN(cmd) + 4, TRUE);
+ if (newcmd == NULL)
+ x = 0;
+ else {
+ sprintf((char *)newcmd, "%s %s %s %s", p_sh,
+ extra_shell_arg == NULL ? "" : (char *)extra_shell_arg,
+ (char *)p_shcf,
+ (char *)cmd);
+ x = system((char *)newcmd);
+ vim_free(newcmd);
+ }
+ }
+ if (emsg_silent)
+ ;
+ else if (x == 127)
+ MSG_PUTS(_("\nCannot execute shell sh\n"));
+ else if (x && !(options & SHELL_SILENT)) {
+ MSG_PUTS(_("\nshell returned "));
+ msg_outnum((long)x);
+ msg_putchar('\n');
+ }
+
+ if (tmode == TMODE_RAW)
+ settmode(TMODE_RAW); /* set to raw mode */
+ resettitle();
+ return x;
+
+#else /* USE_SYSTEM */ /* don't use system(), use fork()/exec() */
+
+# define EXEC_FAILED 122 /* Exit code when shell didn't execute. Don't use
+ 127, some shells use that already */
+
+ char_u *newcmd = NULL;
+ pid_t pid;
+ pid_t wpid = 0;
+ pid_t wait_pid = 0;
+# ifdef HAVE_UNION_WAIT
+ union wait status;
+# else
+ int status = -1;
+# endif
+ int retval = -1;
+ char **argv = NULL;
+ int argc;
+ char_u *p_shcf_copy = NULL;
+ int i;
+ char_u *p;
+ int inquote;
+ int pty_master_fd = -1; /* for pty's */
+ int fd_toshell[2]; /* for pipes */
+ int fd_fromshell[2];
+ int pipe_error = FALSE;
+# ifdef HAVE_SETENV
+ char envbuf[50];
+# else
+ static char envbuf_Rows[20];
+ static char envbuf_Columns[20];
+# endif
+ int did_settmode = FALSE; /* settmode(TMODE_RAW) called */
+
+ newcmd = vim_strsave(p_sh);
+ if (newcmd == NULL) /* out of memory */
+ goto error;
+
+ out_flush();
+ if (options & SHELL_COOKED)
+ settmode(TMODE_COOK); /* set to normal mode */
+
+ /*
+ * Do this loop twice:
+ * 1: find number of arguments
+ * 2: separate them and build argv[]
+ */
+ for (i = 0; i < 2; ++i) {
+ p = newcmd;
+ inquote = FALSE;
+ argc = 0;
+ for (;; ) {
+ if (i == 1)
+ argv[argc] = (char *)p;
+ ++argc;
+ while (*p && (inquote || (*p != ' ' && *p != TAB))) {
+ if (*p == '"')
+ inquote = !inquote;
+ ++p;
+ }
+ if (*p == NUL)
+ break;
+ if (i == 1)
+ *p++ = NUL;
+ p = skipwhite(p);
+ }
+ if (argv == NULL) {
+ /*
+ * Account for possible multiple args in p_shcf.
+ */
+ p = p_shcf;
+ for (;; ) {
+ p = skiptowhite(p);
+ if (*p == NUL)
+ break;
+ ++argc;
+ p = skipwhite(p);
+ }
+
+ argv = (char **)alloc((unsigned)((argc + 4) * sizeof(char *)));
+ if (argv == NULL) /* out of memory */
+ goto error;
+ }
+ }
+ if (cmd != NULL) {
+ char_u *s;
+
+ if (extra_shell_arg != NULL)
+ argv[argc++] = (char *)extra_shell_arg;
+
+ /* Break 'shellcmdflag' into white separated parts. This doesn't
+ * handle quoted strings, they are very unlikely to appear. */
+ p_shcf_copy = alloc((unsigned)STRLEN(p_shcf) + 1);
+ if (p_shcf_copy == NULL) /* out of memory */
+ goto error;
+ s = p_shcf_copy;
+ p = p_shcf;
+ while (*p != NUL) {
+ argv[argc++] = (char *)s;
+ while (*p && *p != ' ' && *p != TAB)
+ *s++ = *p++;
+ *s++ = NUL;
+ p = skipwhite(p);
+ }
+
+ argv[argc++] = (char *)cmd;
+ }
+ argv[argc] = NULL;
+
+ /*
+ * For the GUI, when writing the output into the buffer and when reading
+ * input from the buffer: Try using a pseudo-tty to get the stdin/stdout
+ * of the executed command into the Vim window. Or use a pipe.
+ */
+ if ((options & (SHELL_READ|SHELL_WRITE))
+ ) {
+ {
+ pipe_error = (pipe(fd_toshell) < 0);
+ if (!pipe_error) { /* pipe create OK */
+ pipe_error = (pipe(fd_fromshell) < 0);
+ if (pipe_error) { /* pipe create failed */
+ close(fd_toshell[0]);
+ close(fd_toshell[1]);
+ }
+ }
+ if (pipe_error) {
+ MSG_PUTS(_("\nCannot create pipes\n"));
+ out_flush();
+ }
+ }
+ }
+
+ if (!pipe_error) { /* pty or pipe opened or not used */
+
+ if ((pid = fork()) == -1) { /* maybe we should use vfork() */
+ MSG_PUTS(_("\nCannot fork\n"));
+ if ((options & (SHELL_READ|SHELL_WRITE))
+ ) {
+ {
+ close(fd_toshell[0]);
+ close(fd_toshell[1]);
+ close(fd_fromshell[0]);
+ close(fd_fromshell[1]);
+ }
+ }
+ } else if (pid == 0) { /* child */
+ reset_signals(); /* handle signals normally */
+
+ if (!show_shell_mess || (options & SHELL_EXPAND)) {
+ int fd;
+
+ /*
+ * Don't want to show any message from the shell. Can't just
+ * close stdout and stderr though, because some systems will
+ * break if you try to write to them after that, so we must
+ * use dup() to replace them with something else -- webb
+ * Connect stdin to /dev/null too, so ":n `cat`" doesn't hang,
+ * waiting for input.
+ */
+ fd = open("/dev/null", O_RDWR | O_EXTRA, 0);
+ fclose(stdin);
+ fclose(stdout);
+ fclose(stderr);
+
+ /*
+ * If any of these open()'s and dup()'s fail, we just continue
+ * anyway. It's not fatal, and on most systems it will make
+ * no difference at all. On a few it will cause the execvp()
+ * to exit with a non-zero status even when the completion
+ * could be done, which is nothing too serious. If the open()
+ * or dup() failed we'd just do the same thing ourselves
+ * anyway -- webb
+ */
+ if (fd >= 0) {
+ ignored = dup(fd); /* To replace stdin (fd 0) */
+ ignored = dup(fd); /* To replace stdout (fd 1) */
+ ignored = dup(fd); /* To replace stderr (fd 2) */
+
+ /* Don't need this now that we've duplicated it */
+ close(fd);
+ }
+ } else if ((options & (SHELL_READ|SHELL_WRITE))
+ ) {
+
+# ifdef HAVE_SETSID
+ /* Create our own process group, so that the child and all its
+ * children can be kill()ed. Don't do this when using pipes,
+ * because stdin is not a tty, we would lose /dev/tty. */
+ if (p_stmp) {
+ (void)setsid();
+# if defined(SIGHUP)
+ /* When doing "!xterm&" and 'shell' is bash: the shell
+ * will exit and send SIGHUP to all processes in its
+ * group, killing the just started process. Ignore SIGHUP
+ * to avoid that. (suggested by Simon Schubert)
+ */
+ signal(SIGHUP, SIG_IGN);
+# endif
+ }
+# endif
+ /* Simulate to have a dumb terminal (for now) */
+# ifdef HAVE_SETENV
+ setenv("TERM", "dumb", 1);
+ sprintf((char *)envbuf, "%ld", Rows);
+ setenv("ROWS", (char *)envbuf, 1);
+ sprintf((char *)envbuf, "%ld", Rows);
+ setenv("LINES", (char *)envbuf, 1);
+ sprintf((char *)envbuf, "%ld", Columns);
+ setenv("COLUMNS", (char *)envbuf, 1);
+# else
+ /*
+ * Putenv does not copy the string, it has to remain valid.
+ * Use a static array to avoid losing allocated memory.
+ */
+ putenv("TERM=dumb");
+ sprintf(envbuf_Rows, "ROWS=%ld", Rows);
+ putenv(envbuf_Rows);
+ sprintf(envbuf_Rows, "LINES=%ld", Rows);
+ putenv(envbuf_Rows);
+ sprintf(envbuf_Columns, "COLUMNS=%ld", Columns);
+ putenv(envbuf_Columns);
+# endif
+
+ /*
+ * stderr is only redirected when using the GUI, so that a
+ * program like gpg can still access the terminal to get a
+ * passphrase using stderr.
+ */
+ {
+ /* set up stdin for the child */
+ close(fd_toshell[1]);
+ close(0);
+ ignored = dup(fd_toshell[0]);
+ close(fd_toshell[0]);
+
+ /* set up stdout for the child */
+ close(fd_fromshell[0]);
+ close(1);
+ ignored = dup(fd_fromshell[1]);
+ close(fd_fromshell[1]);
+
+ }
+ }
+
+ /*
+ * There is no type cast for the argv, because the type may be
+ * different on different machines. This may cause a warning
+ * message with strict compilers, don't worry about it.
+ * Call _exit() instead of exit() to avoid closing the connection
+ * to the X server (esp. with GTK, which uses atexit()).
+ */
+ execvp(argv[0], argv);
+ _exit(EXEC_FAILED); /* exec failed, return failure code */
+ } else { /* parent */
+ /*
+ * While child is running, ignore terminating signals.
+ * Do catch CTRL-C, so that "got_int" is set.
+ */
+ catch_signals(SIG_IGN, SIG_ERR);
+ catch_int_signal();
+
+ /*
+ * For the GUI we redirect stdin, stdout and stderr to our window.
+ * This is also used to pipe stdin/stdout to/from the external
+ * command.
+ */
+ if ((options & (SHELL_READ|SHELL_WRITE))
+ ) {
+# define BUFLEN 100 /* length for buffer, pseudo tty limit is 128 */
+ char_u buffer[BUFLEN + 1];
+ int buffer_off = 0; /* valid bytes in buffer[] */
+ char_u ta_buf[BUFLEN + 1]; /* TypeAHead */
+ int ta_len = 0; /* valid bytes in ta_buf[] */
+ int len;
+ int p_more_save;
+ int old_State;
+ int c;
+ int toshell_fd;
+ int fromshell_fd;
+ garray_T ga;
+ int noread_cnt;
+# if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
+ struct timeval start_tv;
+# endif
+
+ {
+ close(fd_toshell[0]);
+ close(fd_fromshell[1]);
+ toshell_fd = fd_toshell[1];
+ fromshell_fd = fd_fromshell[0];
+ }
+
+ /*
+ * Write to the child if there are typed characters.
+ * Read from the child if there are characters available.
+ * Repeat the reading a few times if more characters are
+ * available. Need to check for typed keys now and then, but
+ * not too often (delays when no chars are available).
+ * This loop is quit if no characters can be read from the pty
+ * (WaitForChar detected special condition), or there are no
+ * characters available and the child has exited.
+ * Only check if the child has exited when there is no more
+ * output. The child may exit before all the output has
+ * been printed.
+ *
+ * Currently this busy loops!
+ * This can probably dead-lock when the write blocks!
+ */
+ p_more_save = p_more;
+ p_more = FALSE;
+ old_State = State;
+ State = EXTERNCMD; /* don't redraw at window resize */
+
+ if ((options & SHELL_WRITE) && toshell_fd >= 0) {
+ /* Fork a process that will write the lines to the
+ * external program. */
+ if ((wpid = fork()) == -1) {
+ MSG_PUTS(_("\nCannot fork\n"));
+ } else if (wpid == 0) { /* child */
+ linenr_T lnum = curbuf->b_op_start.lnum;
+ int written = 0;
+ char_u *lp = ml_get(lnum);
+ size_t l;
+
+ close(fromshell_fd);
+ for (;; ) {
+ l = STRLEN(lp + written);
+ if (l == 0)
+ len = 0;
+ else if (lp[written] == NL)
+ /* NL -> NUL translation */
+ len = write(toshell_fd, "", (size_t)1);
+ else {
+ char_u *s = vim_strchr(lp + written, NL);
+
+ len = write(toshell_fd, (char *)lp + written,
+ s == NULL ? l
+ : (size_t)(s - (lp + written)));
+ }
+ if (len == (int)l) {
+ /* Finished a line, add a NL, unless this line
+ * should not have one. */
+ if (lnum != curbuf->b_op_end.lnum
+ || !curbuf->b_p_bin
+ || (lnum != curbuf->b_no_eol_lnum
+ && (lnum !=
+ curbuf->b_ml.ml_line_count
+ || curbuf->b_p_eol)))
+ ignored = write(toshell_fd, "\n",
+ (size_t)1);
+ ++lnum;
+ if (lnum > curbuf->b_op_end.lnum) {
+ /* finished all the lines, close pipe */
+ close(toshell_fd);
+ toshell_fd = -1;
+ break;
+ }
+ lp = ml_get(lnum);
+ written = 0;
+ } else if (len > 0)
+ written += len;
+ }
+ _exit(0);
+ } else { /* parent */
+ close(toshell_fd);
+ toshell_fd = -1;
+ }
+ }
+
+ if (options & SHELL_READ)
+ ga_init2(&ga, 1, BUFLEN);
+
+ noread_cnt = 0;
+# if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
+ gettimeofday(&start_tv, NULL);
+# endif
+ for (;; ) {
+ /*
+ * Check if keys have been typed, write them to the child
+ * if there are any.
+ * Don't do this if we are expanding wild cards (would eat
+ * typeahead).
+ * Don't do this when filtering and terminal is in cooked
+ * mode, the shell command will handle the I/O. Avoids
+ * that a typed password is echoed for ssh or gpg command.
+ * Don't get characters when the child has already
+ * finished (wait_pid == 0).
+ * Don't read characters unless we didn't get output for a
+ * while (noread_cnt > 4), avoids that ":r !ls" eats
+ * typeahead.
+ */
+ len = 0;
+ if (!(options & SHELL_EXPAND)
+ && ((options &
+ (SHELL_READ|SHELL_WRITE|SHELL_COOKED))
+ != (SHELL_READ|SHELL_WRITE|SHELL_COOKED)
+ )
+ && wait_pid == 0
+ && (ta_len > 0 || noread_cnt > 4)) {
+ if (ta_len == 0) {
+ /* Get extra characters when we don't have any.
+ * Reset the counter and timer. */
+ noread_cnt = 0;
+# if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
+ gettimeofday(&start_tv, NULL);
+# endif
+ len = ui_inchar(ta_buf, BUFLEN, 10L, 0);
+ }
+ if (ta_len > 0 || len > 0) {
+ /*
+ * For pipes:
+ * Check for CTRL-C: send interrupt signal to child.
+ * Check for CTRL-D: EOF, close pipe to child.
+ */
+ if (len == 1 && (pty_master_fd < 0 || cmd != NULL)) {
+# ifdef SIGINT
+ /*
+ * Send SIGINT to the child's group or all
+ * processes in our group.
+ */
+ if (ta_buf[ta_len] == Ctrl_C
+ || ta_buf[ta_len] == intr_char) {
+# ifdef HAVE_SETSID
+ kill(-pid, SIGINT);
+# else
+ kill(0, SIGINT);
+# endif
+ if (wpid > 0)
+ kill(wpid, SIGINT);
+ }
+# endif
+ if (pty_master_fd < 0 && toshell_fd >= 0
+ && ta_buf[ta_len] == Ctrl_D) {
+ close(toshell_fd);
+ toshell_fd = -1;
+ }
+ }
+
+ /* replace K_BS by <BS> and K_DEL by <DEL> */
+ for (i = ta_len; i < ta_len + len; ++i) {
+ if (ta_buf[i] == CSI && len - i > 2) {
+ c = TERMCAP2KEY(ta_buf[i + 1], ta_buf[i + 2]);
+ if (c == K_DEL || c == K_KDEL || c == K_BS) {
+ mch_memmove(ta_buf + i + 1, ta_buf + i + 3,
+ (size_t)(len - i - 2));
+ if (c == K_DEL || c == K_KDEL)
+ ta_buf[i] = DEL;
+ else
+ ta_buf[i] = Ctrl_H;
+ len -= 2;
+ }
+ } else if (ta_buf[i] == '\r')
+ ta_buf[i] = '\n';
+ if (has_mbyte)
+ i += (*mb_ptr2len_len)(ta_buf + i,
+ ta_len + len - i) - 1;
+ }
+
+ /*
+ * For pipes: echo the typed characters.
+ * For a pty this does not seem to work.
+ */
+ if (pty_master_fd < 0) {
+ for (i = ta_len; i < ta_len + len; ++i) {
+ if (ta_buf[i] == '\n' || ta_buf[i] == '\b')
+ msg_putchar(ta_buf[i]);
+ else if (has_mbyte) {
+ int l = (*mb_ptr2len)(ta_buf + i);
+
+ msg_outtrans_len(ta_buf + i, l);
+ i += l - 1;
+ } else
+ msg_outtrans_len(ta_buf + i, 1);
+ }
+ windgoto(msg_row, msg_col);
+ out_flush();
+ }
+
+ ta_len += len;
+
+ /*
+ * Write the characters to the child, unless EOF has
+ * been typed for pipes. Write one character at a
+ * time, to avoid losing too much typeahead.
+ * When writing buffer lines, drop the typed
+ * characters (only check for CTRL-C).
+ */
+ if (options & SHELL_WRITE)
+ ta_len = 0;
+ else if (toshell_fd >= 0) {
+ len = write(toshell_fd, (char *)ta_buf, (size_t)1);
+ if (len > 0) {
+ ta_len -= len;
+ mch_memmove(ta_buf, ta_buf + len, ta_len);
+ }
+ }
+ }
+ }
+
+ if (got_int) {
+ /* CTRL-C sends a signal to the child, we ignore it
+ * ourselves */
+# ifdef HAVE_SETSID
+ kill(-pid, SIGINT);
+# else
+ kill(0, SIGINT);
+# endif
+ if (wpid > 0)
+ kill(wpid, SIGINT);
+ got_int = FALSE;
+ }
+
+ /*
+ * Check if the child has any characters to be printed.
+ * Read them and write them to our window. Repeat this as
+ * long as there is something to do, avoid the 10ms wait
+ * for mch_inchar(), or sending typeahead characters to
+ * the external process.
+ * TODO: This should handle escape sequences, compatible
+ * to some terminal (vt52?).
+ */
+ ++noread_cnt;
+ while (RealWaitForChar(fromshell_fd, 10L, NULL)) {
+ len = read_eintr(fromshell_fd, buffer
+ + buffer_off, (size_t)(BUFLEN - buffer_off)
+ );
+ if (len <= 0) /* end of file or error */
+ goto finished;
+
+ noread_cnt = 0;
+ if (options & SHELL_READ) {
+ /* Do NUL -> NL translation, append NL separated
+ * lines to the current buffer. */
+ for (i = 0; i < len; ++i) {
+ if (buffer[i] == NL)
+ append_ga_line(&ga);
+ else if (buffer[i] == NUL)
+ ga_append(&ga, NL);
+ else
+ ga_append(&ga, buffer[i]);
+ }
+ } else if (has_mbyte) {
+ int l;
+
+ len += buffer_off;
+ buffer[len] = NUL;
+
+ /* Check if the last character in buffer[] is
+ * incomplete, keep these bytes for the next
+ * round. */
+ for (p = buffer; p < buffer + len; p += l) {
+ l = mb_cptr2len(p);
+ if (l == 0)
+ l = 1; /* NUL byte? */
+ else if (MB_BYTE2LEN(*p) != l)
+ break;
+ }
+ if (p == buffer) { /* no complete character */
+ /* avoid getting stuck at an illegal byte */
+ if (len >= 12)
+ ++p;
+ else {
+ buffer_off = len;
+ continue;
+ }
+ }
+ c = *p;
+ *p = NUL;
+ msg_puts(buffer);
+ if (p < buffer + len) {
+ *p = c;
+ buffer_off = (buffer + len) - p;
+ mch_memmove(buffer, p, buffer_off);
+ continue;
+ }
+ buffer_off = 0;
+ } else {
+ buffer[len] = NUL;
+ msg_puts(buffer);
+ }
+
+ windgoto(msg_row, msg_col);
+ cursor_on();
+ out_flush();
+ if (got_int)
+ break;
+
+# if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
+ {
+ struct timeval now_tv;
+ long msec;
+
+ /* Avoid that we keep looping here without
+ * checking for a CTRL-C for a long time. Don't
+ * break out too often to avoid losing typeahead. */
+ gettimeofday(&now_tv, NULL);
+ msec = (now_tv.tv_sec - start_tv.tv_sec) * 1000L
+ + (now_tv.tv_usec - start_tv.tv_usec) / 1000L;
+ if (msec > 2000) {
+ noread_cnt = 5;
+ break;
+ }
+ }
+# endif
+ }
+
+ /* If we already detected the child has finished break the
+ * loop now. */
+ if (wait_pid == pid)
+ break;
+
+ /*
+ * Check if the child still exists, before checking for
+ * typed characters (otherwise we would lose typeahead).
+ */
+# ifdef __NeXT__
+ wait_pid = wait4(pid, &status, WNOHANG, (struct rusage *)0);
+# else
+ wait_pid = waitpid(pid, &status, WNOHANG);
+# endif
+ if ((wait_pid == (pid_t)-1 && errno == ECHILD)
+ || (wait_pid == pid && WIFEXITED(status))) {
+ /* Don't break the loop yet, try reading more
+ * characters from "fromshell_fd" first. When using
+ * pipes there might still be something to read and
+ * then we'll break the loop at the "break" above. */
+ wait_pid = pid;
+ } else
+ wait_pid = 0;
+
+ }
+finished:
+ p_more = p_more_save;
+ if (options & SHELL_READ) {
+ if (ga.ga_len > 0) {
+ append_ga_line(&ga);
+ /* remember that the NL was missing */
+ curbuf->b_no_eol_lnum = curwin->w_cursor.lnum;
+ } else
+ curbuf->b_no_eol_lnum = 0;
+ ga_clear(&ga);
+ }
+
+ /*
+ * Give all typeahead that wasn't used back to ui_inchar().
+ */
+ if (ta_len)
+ ui_inchar_undo(ta_buf, ta_len);
+ State = old_State;
+ if (toshell_fd >= 0)
+ close(toshell_fd);
+ close(fromshell_fd);
+ }
+
+ /*
+ * Wait until our child has exited.
+ * Ignore wait() returning pids of other children and returning
+ * because of some signal like SIGWINCH.
+ * Don't wait if wait_pid was already set above, indicating the
+ * child already exited.
+ */
+ if (wait_pid != pid)
+ wait_pid = wait4pid(pid, &status);
+
+
+ /* Make sure the child that writes to the external program is
+ * dead. */
+ if (wpid > 0) {
+ kill(wpid, SIGKILL);
+ wait4pid(wpid, NULL);
+ }
+
+ /*
+ * Set to raw mode right now, otherwise a CTRL-C after
+ * catch_signals() will kill Vim.
+ */
+ if (tmode == TMODE_RAW)
+ settmode(TMODE_RAW);
+ did_settmode = TRUE;
+ set_signals();
+
+ if (WIFEXITED(status)) {
+ /* LINTED avoid "bitwise operation on signed value" */
+ retval = WEXITSTATUS(status);
+ if (retval != 0 && !emsg_silent) {
+ if (retval == EXEC_FAILED) {
+ MSG_PUTS(_("\nCannot execute shell "));
+ msg_outtrans(p_sh);
+ msg_putchar('\n');
+ } else if (!(options & SHELL_SILENT)) {
+ MSG_PUTS(_("\nshell returned "));
+ msg_outnum((long)retval);
+ msg_putchar('\n');
+ }
+ }
+ } else
+ MSG_PUTS(_("\nCommand terminated\n"));
+ }
+ }
+ vim_free(argv);
+ vim_free(p_shcf_copy);
+
+error:
+ if (!did_settmode)
+ if (tmode == TMODE_RAW)
+ settmode(TMODE_RAW); /* set to raw mode */
+ resettitle();
+ vim_free(newcmd);
+
+ return retval;
+
+#endif /* USE_SYSTEM */
+}
+
+/*
+ * Check for CTRL-C typed by reading all available characters.
+ * In cooked mode we should get SIGINT, no need to check.
+ */
+void mch_breakcheck() {
+ if (curr_tmode == TMODE_RAW && RealWaitForChar(read_cmd_fd, 0L, NULL))
+ fill_input_buf(FALSE);
+}
+
+/*
+ * Wait "msec" msec until a character is available from the keyboard or from
+ * inbuf[]. msec == -1 will block forever.
+ * When a GUI is being used, this will never get called -- webb
+ */
+static int WaitForChar(msec)
+long msec;
+{
+ int avail;
+
+ if (input_available()) /* something in inbuf[] */
+ return 1;
+
+ /* May need to query the mouse position. */
+ if (WantQueryMouse) {
+ WantQueryMouse = FALSE;
+ mch_write((char_u *)IF_EB("\033[1'|", ESC_STR "[1'|"), 5);
+ }
+
+ /*
+ * For FEAT_MOUSE_GPM and FEAT_XCLIPBOARD we loop here to process mouse
+ * events. This is a bit complicated, because they might both be defined.
+ */
+ avail = RealWaitForChar(read_cmd_fd, msec, NULL);
+ return avail;
+}
+
+/*
+ * Wait "msec" msec until a character is available from file descriptor "fd".
+ * "msec" == 0 will check for characters once.
+ * "msec" == -1 will block until a character is available.
+ * When a GUI is being used, this will not be used for input -- webb
+ * Returns also, when a request from Sniff is waiting -- toni.
+ * Or when a Linux GPM mouse event is waiting.
+ */
+static int RealWaitForChar(fd, msec, check_for_gpm)
+int fd;
+long msec;
+int *check_for_gpm UNUSED;
+{
+ int ret;
+
+#ifdef MAY_LOOP
+ for (;; )
+#endif
+ {
+#ifdef MAY_LOOP
+ int finished = TRUE; /* default is to 'loop' just once */
+#endif
+#ifndef HAVE_SELECT
+ struct pollfd fds[6];
+ int nfd;
+ int towait = (int)msec;
+
+ fds[0].fd = fd;
+ fds[0].events = POLLIN;
+ nfd = 1;
+
+
+ ret = poll(fds, nfd, towait);
+
+
+
+#else /* HAVE_SELECT */
+
+ struct timeval tv;
+ struct timeval *tvp;
+ fd_set rfds, efds;
+ int maxfd;
+ long towait = msec;
+
+
+ if (towait >= 0) {
+ tv.tv_sec = towait / 1000;
+ tv.tv_usec = (towait % 1000) * (1000000/1000);
+ tvp = &tv;
+ } else
+ tvp = NULL;
+
+ /*
+ * Select on ready for reading and exceptional condition (end of file).
+ */
+select_eintr:
+ FD_ZERO(&rfds);
+ FD_ZERO(&efds);
+ FD_SET(fd, &rfds);
+ /* For QNX select() always returns 1 if this is set. Why? */
+ FD_SET(fd, &efds);
+ maxfd = fd;
+
+
+ ret = select(maxfd + 1, &rfds, NULL, &efds, tvp);
+# ifdef EINTR
+ if (ret == -1 && errno == EINTR) {
+ /* Check whether window has been resized, EINTR may be caused by
+ * SIGWINCH. */
+ if (do_resize)
+ handle_resize();
+
+ /* Interrupted by a signal, need to try again. We ignore msec
+ * here, because we do want to check even after a timeout if
+ * characters are available. Needed for reading output of an
+ * external command after the process has finished. */
+ goto select_eintr;
+ }
+# endif
+
+
+#endif /* HAVE_SELECT */
+
+#ifdef MAY_LOOP
+ if (finished || msec == 0)
+ break;
+
+ /* We're going to loop around again, find out for how long */
+ if (msec > 0) {
+# ifdef USE_START_TV
+ struct timeval mtv;
+
+ /* Compute remaining wait time. */
+ gettimeofday(&mtv, NULL);
+ msec -= (mtv.tv_sec - start_tv.tv_sec) * 1000L
+ + (mtv.tv_usec - start_tv.tv_usec) / 1000L;
+# else
+ /* Guess we got interrupted halfway. */
+ msec = msec / 2;
+# endif
+ if (msec <= 0)
+ break; /* waited long enough */
+ }
+#endif
+ }
+
+ return ret > 0;
+}
+
+#ifndef NO_EXPANDPATH
+/*
+ * Expand a path into all matching files and/or directories. Handles "*",
+ * "?", "[a-z]", "**", etc.
+ * "path" has backslashes before chars that are not to be expanded.
+ * Returns the number of matches found.
+ */
+int mch_expandpath(gap, path, flags)
+garray_T *gap;
+char_u *path;
+int flags; /* EW_* flags */
+{
+ return unix_expandpath(gap, path, 0, flags, FALSE);
+}
+#endif
+
+/*
+ * mch_expand_wildcards() - this code does wild-card pattern matching using
+ * the shell
+ *
+ * return OK for success, FAIL for error (you may lose some memory) and put
+ * an error message in *file.
+ *
+ * num_pat is number of input patterns
+ * pat is array of pointers to input patterns
+ * num_file is pointer to number of matched file names
+ * file is pointer to array of pointers to matched file names
+ */
+
+#ifndef SEEK_SET
+# define SEEK_SET 0
+#endif
+#ifndef SEEK_END
+# define SEEK_END 2
+#endif
+
+#define SHELL_SPECIAL (char_u *)"\t \"&'$;<>()\\|"
+
+int mch_expand_wildcards(num_pat, pat, num_file, file, flags)
+int num_pat;
+char_u **pat;
+int *num_file;
+char_u ***file;
+int flags; /* EW_* flags */
+{
+ int i;
+ size_t len;
+ char_u *p;
+ int dir;
+ /*
+ * This is the non-OS/2 implementation (really Unix).
+ */
+ int j;
+ char_u *tempname;
+ char_u *command;
+ FILE *fd;
+ char_u *buffer;
+#define STYLE_ECHO 0 /* use "echo", the default */
+#define STYLE_GLOB 1 /* use "glob", for csh */
+#define STYLE_VIMGLOB 2 /* use "vimglob", for Posix sh */
+#define STYLE_PRINT 3 /* use "print -N", for zsh */
+#define STYLE_BT 4 /* `cmd` expansion, execute the pattern
+ * directly */
+ int shell_style = STYLE_ECHO;
+ int check_spaces;
+ static int did_find_nul = FALSE;
+ int ampersent = FALSE;
+ /* 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 */
+ *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 (!have_wildcard(num_pat, pat))
+ return save_patterns(num_pat, pat, num_file, file);
+
+# ifdef HAVE_SANDBOX
+ /* Don't allow any shell command in the sandbox. */
+ if (sandbox != 0 && check_secure())
+ return FAIL;
+# endif
+
+ /*
+ * 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()))
+ return FAIL;
+
+ /*
+ * get a name for the temp file
+ */
+ if ((tempname = vim_tempname('o')) == 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".
+ */
+ if (num_pat == 1 && *pat[0] == '`'
+ && (len = STRLEN(pat[0])) > 2
+ && *(pat[0] + len - 1) == '`')
+ shell_style = STYLE_BT;
+ 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)
+ shell_style = STYLE_PRINT;
+ }
+ if (shell_style == STYLE_ECHO && strstr((char *)gettail(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 */
+ 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. */
+#ifdef USE_SYSTEM
+ len += STRLEN(pat[i]) + 3; /* add space and two quotes */
+#else
+ ++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;
+ }
+#endif
+ }
+ command = alloc(len);
+ if (command == NULL) {
+ /* out of memory */
+ vim_free(tempname);
+ return FAIL;
+ }
+
+ /*
+ * 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 */
+ p = command + STRLEN(command) - 1;
+ *p-- = ')'; /* remove last backtick */
+ while (p > command && vim_iswhite(*p))
+ --p;
+ if (*p == '&') { /* remove trailing '&' */
+ ampersent = TRUE;
+ *p = ' ';
+ }
+ STRCAT(command, ">");
+ } else {
+ if (flags & EW_NOTFOUND)
+ STRCPY(command, "set nonomatch; ");
+ else
+ STRCPY(command, "unset nonomatch; ");
+ if (shell_style == STYLE_GLOB)
+ STRCAT(command, "glob >");
+ else if (shell_style == STYLE_PRINT)
+ STRCAT(command, "print -N >");
+ else if (shell_style == STYLE_VIMGLOB)
+ STRCAT(command, sh_vimglob_func);
+ else
+ STRCAT(command, "echo >");
+ }
+
+ STRCAT(command, tempname);
+
+ if (shell_style != STYLE_BT)
+ for (i = 0; i < num_pat; ++i) {
+ /* When using system() always add extra quotes, because the shell
+ * is started twice. Otherwise put a backslash before special
+ * characters, except inside ``. */
+#ifdef USE_SYSTEM
+ STRCAT(command, " \"");
+ STRCAT(command, pat[i]);
+ STRCAT(command, "\"");
+#else
+ int intick = FALSE;
+
+ p = command + STRLEN(command);
+ *p++ = ' ';
+ 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. */
+ if (intick
+ || vim_strchr(SHELL_SPECIAL, pat[i][j + 1]) != NULL
+ || pat[i][j + 1] == '`')
+ *p++ = '\\';
+ ++j;
+ } else if (!intick && vim_strchr(SHELL_SPECIAL,
+ pat[i][j]) != NULL)
+ /* Put a backslash before a special character, but not
+ * when inside ``. */
+ *p++ = '\\';
+
+ /* Copy one character. */
+ *p++ = pat[i][j];
+ }
+ *p = NUL;
+#endif
+ }
+ if (flags & EW_SILENT)
+ show_shell_mess = FALSE;
+ 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, SHELL_EXPAND | SHELL_SILENT);
+
+ /* When running in the background, give it some time to create the temp
+ * file, but don't wait for it to finish. */
+ if (ampersent)
+ mch_delay(10L, TRUE);
+
+ extra_shell_arg = NULL; /* cleanup */
+ show_shell_mess = TRUE;
+ vim_free(command);
+
+ if (i != 0) { /* mch_call_shell() failed */
+ mch_remove(tempname);
+ vim_free(tempname);
+ /*
+ * With interactive completion, the error message is not printed.
+ * However with USE_SYSTEM, I don't know how to turn off error messages
+ * from the shell, so screen may still get messed up -- webb.
+ */
+#ifndef USE_SYSTEM
+ if (!(flags & EW_SILENT))
+#endif
+ {
+ redraw_later_clear(); /* probably messed up screen */
+ msg_putchar('\n'); /* clear bottom line quickly */
+ cmdline_row = Rows - 1; /* continue on last line */
+#ifdef USE_SYSTEM
+ if (!(flags & EW_SILENT))
+#endif
+ {
+ MSG(_(e_wildexpand));
+ 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)
+ return FAIL;
+ goto notfound;
+ }
+
+ /*
+ * 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. */
+ if (!(flags & EW_SILENT)) {
+ MSG(_(e_wildexpand));
+ msg_start(); /* don't overwrite this message */
+ }
+ vim_free(tempname);
+ goto notfound;
+ }
+ fseek(fd, 0L, SEEK_END);
+ len = ftell(fd); /* get size of temp file */
+ fseek(fd, 0L, SEEK_SET);
+ buffer = alloc(len + 1);
+ if (buffer == NULL) {
+ /* out of memory */
+ mch_remove(tempname);
+ vim_free(tempname);
+ fclose(fd);
+ return FAIL;
+ }
+ i = fread((char *)buffer, 1, len, fd);
+ fclose(fd);
+ mch_remove(tempname);
+ if (i != (int)len) {
+ /* unexpected read error */
+ EMSG2(_(e_notread), tempname);
+ vim_free(tempname);
+ vim_free(buffer);
+ return FAIL;
+ }
+ vim_free(tempname);
+
+
+
+ /* file names are separated with Space */
+ if (shell_style == STYLE_ECHO) {
+ 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 */
+ }
+ }
+ /* 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 */
+ }
+ }
+ /* 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 */
+ buffer[len] = NUL;
+ if (len && (int)STRLEN(buffer) < (int)len)
+ did_find_nul = TRUE;
+ else
+ 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
+ buffer[len] = NUL;
+ i = 0;
+ 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 (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.
+ */
+ vim_free(buffer);
+ goto notfound;
+ }
+ *num_file = i;
+ *file = (char_u **)alloc(sizeof(char_u *) * i);
+ if (*file == NULL) {
+ /* out of memory */
+ vim_free(buffer);
+ return FAIL;
+ }
+
+ /*
+ * Isolate the individual file names.
+ */
+ p = buffer;
+ for (i = 0; i < *num_file; ++i) {
+ (*file)[i] = p;
+ /* 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 = NUL;
+ else {
+ *p++ = NUL;
+ p = skipwhite(p); /* skip to next entry */
+ }
+ } else { /* NUL separates */
+ while (*p && p < buffer + len) /* skip entry */
+ ++p;
+ ++p; /* skip NUL */
+ }
+ }
+
+ /*
+ * 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) && mch_getperm((*file)[i]) < 0)
+ continue;
+
+ /* check if this entry should be included */
+ dir = (mch_isdir((*file)[i]));
+ if ((dir && !(flags & EW_DIR)) || (!dir && !(flags & EW_FILE)))
+ continue;
+
+ /* Skip files that are not executable if we check for that. */
+ if (!dir && (flags & EW_EXEC) && !mch_can_exe((*file)[i]))
+ continue;
+
+ p = alloc((unsigned)(STRLEN((*file)[i]) + 1 + dir));
+ if (p) {
+ STRCPY(p, (*file)[i]);
+ if (dir)
+ add_pathsep(p); /* add '/' to a directory name */
+ (*file)[j++] = p;
+ }
+ }
+ vim_free(buffer);
+ *num_file = j;
+
+ if (*num_file == 0) { /* rejected all entries */
+ vim_free(*file);
+ *file = NULL;
+ goto notfound;
+ }
+
+ return OK;
+
+notfound:
+ if (flags & EW_NOTFOUND)
+ return save_patterns(num_pat, pat, num_file, file);
+ return FAIL;
+
+}
+
+
+static int save_patterns(num_pat, pat, num_file, file)
+int num_pat;
+char_u **pat;
+int *num_file;
+char_u ***file;
+{
+ int i;
+ char_u *s;
+
+ *file = (char_u **)alloc(num_pat * sizeof(char_u *));
+ if (*file == NULL)
+ return FAIL;
+ for (i = 0; i < num_pat; i++) {
+ s = vim_strsave(pat[i]);
+ if (s != NULL)
+ /* Be compatible with expand_filename(): halve the number of
+ * backslashes. */
+ backslash_halve(s);
+ (*file)[i] = s;
+ }
+ *num_file = num_pat;
+ return OK;
+}
+
+/*
+ * Return TRUE if the string "p" contains a wildcard that mch_expandpath() can
+ * expand.
+ */
+int mch_has_exp_wildcard(p)
+char_u *p;
+{
+ for (; *p; mb_ptr_adv(p)) {
+ if (*p == '\\' && p[1] != NUL)
+ ++p;
+ else if (vim_strchr((char_u *)
+ "*?[{'"
+ , *p) != NULL)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*
+ * Return TRUE if the string "p" contains a wildcard.
+ * Don't recognize '~' at the end as a wildcard.
+ */
+int mch_has_wildcard(p)
+char_u *p;
+{
+ for (; *p; mb_ptr_adv(p)) {
+ if (*p == '\\' && p[1] != NUL)
+ ++p;
+ else if (vim_strchr((char_u *)
+ "*?[{`'$"
+ , *p) != NULL
+ || (*p == '~' && p[1] != NUL))
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static int have_wildcard(num, file)
+int num;
+char_u **file;
+{
+ int i;
+
+ for (i = 0; i < num; i++)
+ if (mch_has_wildcard(file[i]))
+ return 1;
+ return 0;
+}
+
+static int have_dollars(num, file)
+int num;
+char_u **file;
+{
+ int i;
+
+ for (i = 0; i < num; i++)
+ if (vim_strchr(file[i], '$') != NULL)
+ return TRUE;
+ return FALSE;
+}
+
+#ifndef HAVE_RENAME
+/*
+ * Scaled-down version of rename(), which is missing in Xenix.
+ * This version can only move regular files and will fail if the
+ * destination exists.
+ */
+int mch_rename(src, dest)
+const char *src, *dest;
+{
+ struct stat st;
+
+ if (stat(dest, &st) >= 0) /* fail if destination exists */
+ return -1;
+ if (link(src, dest) != 0) /* link file to new name */
+ return -1;
+ if (mch_remove(src) == 0) /* delete link to old name */
+ return 0;
+ return -1;
+}
+#endif /* !HAVE_RENAME */
+
+
+
+#if defined(FEAT_LIBCALL) || defined(PROTO)
+typedef char_u * (*STRPROCSTR) __ARGS ((char_u *));
+typedef char_u * (*INTPROCSTR) __ARGS ((int));
+typedef int (*STRPROCINT) __ARGS ((char_u *));
+typedef int (*INTPROCINT) __ARGS ((int));
+
+/*
+ * Call a DLL routine which takes either a string or int param
+ * and returns an allocated string.
+ */
+int mch_libcall(libname, funcname, argstring, argint, string_result,
+ number_result)
+char_u *libname;
+char_u *funcname;
+char_u *argstring; /* NULL when using a argint */
+int argint;
+char_u **string_result; /* NULL when using number_result */
+int *number_result;
+{
+# if defined(USE_DLOPEN)
+ void *hinstLib;
+ char *dlerr = NULL;
+# else
+ shl_t hinstLib;
+# endif
+ STRPROCSTR ProcAdd;
+ INTPROCSTR ProcAddI;
+ char_u *retval_str = NULL;
+ int retval_int = 0;
+ int success = FALSE;
+
+ /*
+ * Get a handle to the DLL module.
+ */
+# if defined(USE_DLOPEN)
+ /* First clear any error, it's not cleared by the dlopen() call. */
+ (void)dlerror();
+
+ hinstLib = dlopen((char *)libname, RTLD_LAZY
+# ifdef RTLD_LOCAL
+ | RTLD_LOCAL
+# endif
+ );
+ if (hinstLib == NULL) {
+ /* "dlerr" must be used before dlclose() */
+ dlerr = (char *)dlerror();
+ if (dlerr != NULL)
+ EMSG2(_("dlerror = \"%s\""), dlerr);
+ }
+# else
+ hinstLib = shl_load((const char*)libname, BIND_IMMEDIATE|BIND_VERBOSE, 0L);
+# endif
+
+ /* If the handle is valid, try to get the function address. */
+ if (hinstLib != NULL) {
+# ifdef HAVE_SETJMP_H
+ /*
+ * Catch a crash when calling the library function. For example when
+ * using a number where a string pointer is expected.
+ */
+ mch_startjmp();
+ if (SETJMP(lc_jump_env) != 0) {
+ success = FALSE;
+# if defined(USE_DLOPEN)
+ dlerr = NULL;
+# endif
+ mch_didjmp();
+ } else
+# endif
+ {
+ retval_str = NULL;
+ retval_int = 0;
+
+ if (argstring != NULL) {
+# if defined(USE_DLOPEN)
+ ProcAdd = (STRPROCSTR)dlsym(hinstLib, (const char *)funcname);
+ dlerr = (char *)dlerror();
+# else
+ if (shl_findsym(&hinstLib, (const char *)funcname,
+ TYPE_PROCEDURE, (void *)&ProcAdd) < 0)
+ ProcAdd = NULL;
+# endif
+ if ((success = (ProcAdd != NULL
+# if defined(USE_DLOPEN)
+ && dlerr == NULL
+# endif
+ ))) {
+ if (string_result == NULL)
+ retval_int = ((STRPROCINT)ProcAdd)(argstring);
+ else
+ retval_str = (ProcAdd)(argstring);
+ }
+ } else {
+# if defined(USE_DLOPEN)
+ ProcAddI = (INTPROCSTR)dlsym(hinstLib, (const char *)funcname);
+ dlerr = (char *)dlerror();
+# else
+ if (shl_findsym(&hinstLib, (const char *)funcname,
+ TYPE_PROCEDURE, (void *)&ProcAddI) < 0)
+ ProcAddI = NULL;
+# endif
+ if ((success = (ProcAddI != NULL
+# if defined(USE_DLOPEN)
+ && dlerr == NULL
+# endif
+ ))) {
+ if (string_result == NULL)
+ retval_int = ((INTPROCINT)ProcAddI)(argint);
+ else
+ retval_str = (ProcAddI)(argint);
+ }
+ }
+
+ /* Save the string before we free the library. */
+ /* Assume that a "1" or "-1" result is an illegal pointer. */
+ if (string_result == NULL)
+ *number_result = retval_int;
+ else if (retval_str != NULL
+ && retval_str != (char_u *)1
+ && retval_str != (char_u *)-1)
+ *string_result = vim_strsave(retval_str);
+ }
+
+# ifdef HAVE_SETJMP_H
+ mch_endjmp();
+# ifdef SIGHASARG
+ if (lc_signal != 0) {
+ int i;
+
+ /* try to find the name of this signal */
+ for (i = 0; signal_info[i].sig != -1; i++)
+ if (lc_signal == signal_info[i].sig)
+ break;
+ EMSG2("E368: got SIG%s in libcall()", signal_info[i].name);
+ }
+# endif
+# endif
+
+# if defined(USE_DLOPEN)
+ /* "dlerr" must be used before dlclose() */
+ if (dlerr != NULL)
+ EMSG2(_("dlerror = \"%s\""), dlerr);
+
+ /* Free the DLL module. */
+ (void)dlclose(hinstLib);
+# else
+ (void)shl_unload(hinstLib);
+# endif
+ }
+
+ if (!success) {
+ EMSG2(_(e_libcall), funcname);
+ return FAIL;
+ }
+
+ return OK;
+}
+#endif
+
+
+
+
+
diff --git a/src/os_unix.h b/src/os_unix.h
new file mode 100644
index 0000000000..f0fc3d5f9a
--- /dev/null
+++ b/src/os_unix.h
@@ -0,0 +1,372 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * 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.
+ */
+
+/*
+ * NextStep has a problem with configure, undefine a few things:
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+
+# include <sys/types.h>
+# include <sys/stat.h>
+
+#ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+#endif
+
+
+
+/* On AIX 4.2 there is a conflicting prototype for ioctl() in stropts.h and
+ * unistd.h. This hack should fix that (suggested by Jeff George).
+ * But on AIX 4.3 it's alright (suggested by Jake Hamby). */
+
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#ifdef HAVE_LIBC_H
+# include <libc.h> /* for NeXT */
+#endif
+
+#ifdef HAVE_SYS_PARAM_H
+# include <sys/param.h> /* defines BSD, if it's a BSD system */
+#endif
+
+/*
+ * Sun defines FILE on SunOS 4.x.x, Solaris has a typedef for FILE
+ */
+
+/*
+ * Using getcwd() is preferred, because it checks for a buffer overflow.
+ * Don't use getcwd() on systems do use system("sh -c pwd"). There is an
+ * autoconf check for this.
+ * Use getcwd() anyway if getwd() isn't present.
+ */
+#if defined(HAVE_GETCWD) && !(defined(BAD_GETCWD) && defined(HAVE_GETWD))
+# define USE_GETCWD
+#endif
+
+#ifndef __ARGS
+/* The AIX VisualAge cc compiler defines __EXTENDED__ instead of __STDC__
+ * because it includes pre-ansi features. */
+# if defined(__STDC__) || defined(__GNUC__) || defined(__EXTENDED__)
+# define __ARGS(x) x
+# else
+# define __ARGS(x) ()
+# endif
+#endif
+
+/* always use unlink() to remove files */
+# define vim_mkdir(x, y) mkdir((char *)(x), y)
+# define mch_rmdir(x) rmdir((char *)(x))
+# define mch_remove(x) unlink((char *)(x))
+
+/* The number of arguments to a signal handler is configured here. */
+/* It used to be a long list of almost all systems. Any system that doesn't
+ * have an argument??? */
+#define SIGHASARG
+
+/* List 3 arg systems here. I guess __sgi, please test and correct me. jw. */
+
+#ifdef SIGHASARG
+# ifdef SIGHAS3ARGS
+# define SIGPROTOARG (int, int, struct sigcontext *)
+# define SIGDEFARG(s) (s, sig2, scont) int s, sig2; struct sigcontext *scont;
+# define SIGDUMMYARG 0, 0, (struct sigcontext *)0
+# else
+# define SIGPROTOARG (int)
+# define SIGDEFARG(s) (s) int s UNUSED;
+# define SIGDUMMYARG 0
+# endif
+#else
+# define SIGPROTOARG (void)
+# define SIGDEFARG(s) ()
+# define SIGDUMMYARG
+#endif
+
+#ifdef HAVE_DIRENT_H
+# include <dirent.h>
+# ifndef NAMLEN
+# define NAMLEN(dirent) strlen((dirent)->d_name)
+# endif
+#else
+# define dirent direct
+# define NAMLEN(dirent) (dirent)->d_namlen
+# if HAVE_SYS_NDIR_H
+# include <sys/ndir.h>
+# endif
+# if HAVE_SYS_DIR_H
+# include <sys/dir.h>
+# endif
+# if HAVE_NDIR_H
+# include <ndir.h>
+# endif
+#endif
+
+#if !defined(HAVE_SYS_TIME_H) || defined(TIME_WITH_SYS_TIME)
+# include <time.h> /* on some systems time.h should not be
+ included together with sys/time.h */
+#endif
+#ifdef HAVE_SYS_TIME_H
+# include <sys/time.h>
+#endif
+
+#include <signal.h>
+
+#if defined(DIRSIZ) && !defined(MAXNAMLEN)
+# define MAXNAMLEN DIRSIZ
+#endif
+
+#if defined(UFS_MAXNAMLEN) && !defined(MAXNAMLEN)
+# define MAXNAMLEN UFS_MAXNAMLEN /* for dynix/ptx */
+#endif
+
+#if defined(NAME_MAX) && !defined(MAXNAMLEN)
+# define MAXNAMLEN NAME_MAX /* for Linux before .99p3 */
+#endif
+
+/*
+ * Note: if MAXNAMLEN has the wrong value, you will get error messages
+ * for not being able to open the swap file.
+ */
+#if !defined(MAXNAMLEN)
+# define MAXNAMLEN 512 /* for all other Unix */
+#endif
+
+#define BASENAMELEN (MAXNAMLEN - 5)
+
+#ifdef HAVE_PWD_H
+# include <pwd.h>
+#endif
+
+#ifdef __COHERENT__
+# undef __ARGS
+#endif
+
+#if (defined(HAVE_SYS_RESOURCE_H) && defined(HAVE_GETRLIMIT)) \
+ || (defined(HAVE_SYS_SYSINFO_H) && defined(HAVE_SYSINFO)) \
+ || defined(HAVE_SYSCTL) || defined(HAVE_SYSCONF)
+# define HAVE_TOTAL_MEM
+#endif
+
+
+
+
+
+
+/*
+ * Unix system-dependent file names
+ */
+#ifndef SYS_VIMRC_FILE
+# define SYS_VIMRC_FILE "$VIM/vimrc"
+#endif
+#ifndef SYS_GVIMRC_FILE
+# define SYS_GVIMRC_FILE "$VIM/gvimrc"
+#endif
+#ifndef DFLT_HELPFILE
+# define DFLT_HELPFILE "$VIMRUNTIME/doc/help.txt"
+#endif
+#ifndef FILETYPE_FILE
+# define FILETYPE_FILE "filetype.vim"
+#endif
+#ifndef FTPLUGIN_FILE
+# define FTPLUGIN_FILE "ftplugin.vim"
+#endif
+#ifndef INDENT_FILE
+# define INDENT_FILE "indent.vim"
+#endif
+#ifndef FTOFF_FILE
+# define FTOFF_FILE "ftoff.vim"
+#endif
+#ifndef FTPLUGOF_FILE
+# define FTPLUGOF_FILE "ftplugof.vim"
+#endif
+#ifndef INDOFF_FILE
+# define INDOFF_FILE "indoff.vim"
+#endif
+#ifndef SYS_MENU_FILE
+# define SYS_MENU_FILE "$VIMRUNTIME/menu.vim"
+#endif
+
+#ifndef USR_EXRC_FILE
+# define USR_EXRC_FILE "$HOME/.exrc"
+#endif
+
+
+#ifndef USR_VIMRC_FILE
+# define USR_VIMRC_FILE "$HOME/.vimrc"
+#endif
+
+
+#if !defined(USR_EXRC_FILE2)
+# define USR_VIMRC_FILE2 "~/.vim/vimrc"
+#endif
+
+
+#ifndef USR_GVIMRC_FILE
+# define USR_GVIMRC_FILE "$HOME/.gvimrc"
+#endif
+
+#ifndef USR_GVIMRC_FILE2
+# define USR_GVIMRC_FILE2 "~/.vim/gvimrc"
+#endif
+
+
+#ifndef EVIM_FILE
+# define EVIM_FILE "$VIMRUNTIME/evim.vim"
+#endif
+
+# ifndef VIMINFO_FILE
+# define VIMINFO_FILE "$HOME/.viminfo"
+# endif
+
+#ifndef EXRC_FILE
+# define EXRC_FILE ".exrc"
+#endif
+
+#ifndef VIMRC_FILE
+# define VIMRC_FILE ".vimrc"
+#endif
+
+
+#ifndef SYNTAX_FNAME
+# define SYNTAX_FNAME "$VIMRUNTIME/syntax/%s.vim"
+#endif
+
+#ifndef DFLT_BDIR
+# define DFLT_BDIR ".,~/tmp,~/" /* default for 'backupdir' */
+#endif
+
+#ifndef DFLT_DIR
+# define DFLT_DIR ".,~/tmp,/var/tmp,/tmp" /* default for 'directory' */
+#endif
+
+#ifndef DFLT_VDIR
+# define DFLT_VDIR "$HOME/.vim/view" /* default for 'viewdir' */
+#endif
+
+#define DFLT_ERRORFILE "errors.err"
+
+# ifdef RUNTIME_GLOBAL
+# define DFLT_RUNTIMEPATH "~/.vim," RUNTIME_GLOBAL ",$VIMRUNTIME," \
+ RUNTIME_GLOBAL "/after,~/.vim/after"
+# else
+# define DFLT_RUNTIMEPATH \
+ "~/.vim,$VIM/vimfiles,$VIMRUNTIME,$VIM/vimfiles/after,~/.vim/after"
+# endif
+
+# define TEMPDIRNAMES "$TMPDIR", "/tmp", ".", "$HOME"
+# define TEMPNAMELEN 256
+
+/* Special wildcards that need to be handled by the shell */
+#define SPECIAL_WILDCHAR "`'{"
+
+#ifndef HAVE_OPENDIR
+# define NO_EXPANDPATH
+#endif
+
+/*
+ * Unix has plenty of memory, use large buffers
+ */
+#define CMDBUFFSIZE 1024 /* size of the command processing buffer */
+
+/* Use the system path length if it makes sense. */
+#if defined(PATH_MAX) && (PATH_MAX > 1000)
+# define MAXPATHL PATH_MAX
+#else
+# define MAXPATHL 1024
+#endif
+
+#define CHECK_INODE /* used when checking if a swap file already
+ exists for a file */
+# ifndef DFLT_MAXMEM
+# define DFLT_MAXMEM (5*1024) /* use up to 5 Mbyte for a buffer */
+# endif
+# ifndef DFLT_MAXMEMTOT
+# define DFLT_MAXMEMTOT (10*1024) /* use up to 10 Mbyte for Vim */
+# endif
+
+/* memmove is not present on all systems, use memmove, bcopy, memcpy or our
+ * own version */
+/* Some systems have (void *) arguments, some (char *). If we use (char *) it
+ * works for all */
+#ifdef USEMEMMOVE
+# define mch_memmove(to, from, len) memmove((char *)(to), (char *)(from), len)
+#else
+# ifdef USEBCOPY
+# define mch_memmove(to, from, len) bcopy((char *)(from), (char *)(to), len)
+# else
+# ifdef USEMEMCPY
+# define mch_memmove(to, from, len) memcpy((char *)(to), (char *)(from), len)
+# else
+# define VIM_MEMMOVE /* found in misc2.c */
+# endif
+# endif
+#endif
+
+# ifdef HAVE_RENAME
+# define mch_rename(src, dst) rename(src, dst)
+# else
+int mch_rename __ARGS((const char *src, const char *dest));
+# endif
+# ifdef __MVS__
+/* on OS390 Unix getenv() doesn't return a pointer to persistent
+ * storage -> use __getenv() */
+# define mch_getenv(x) (char_u *)__getenv((char *)(x))
+# else
+# define mch_getenv(x) (char_u *)getenv((char *)(x))
+# endif
+# define mch_setenv(name, val, x) setenv(name, val, x)
+
+#if !defined(S_ISDIR) && defined(S_IFDIR)
+# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
+#endif
+#if !defined(S_ISREG) && defined(S_IFREG)
+# define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
+#endif
+#if !defined(S_ISBLK) && defined(S_IFBLK)
+# define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
+#endif
+#if !defined(S_ISSOCK) && defined(S_IFSOCK)
+# define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
+#endif
+#if !defined(S_ISFIFO) && defined(S_IFIFO)
+# define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
+#endif
+#if !defined(S_ISCHR) && defined(S_IFCHR)
+# define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
+#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. */
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif
+#if defined(HAVE_STRINGS_H) && !defined(NO_STRINGS_WITH_STRING_H)
+# include <strings.h>
+#endif
+
+#if defined(HAVE_SETJMP_H)
+# include <setjmp.h>
+# ifdef HAVE_SIGSETJMP
+# define JMP_BUF sigjmp_buf
+# define SETJMP(x) sigsetjmp((x), 1)
+# define LONGJMP siglongjmp
+# else
+# define JMP_BUF jmp_buf
+# define SETJMP(x) setjmp(x)
+# define LONGJMP longjmp
+# endif
+#endif
+
+#define HAVE_DUP /* have dup() */
+#define HAVE_ST_MODE /* have stat.st_mode */
+
+/* We have three kinds of ACL support. */
+#define HAVE_ACL (HAVE_POSIX_ACL || HAVE_SOLARIS_ACL || HAVE_AIX_ACL)
diff --git a/src/os_unixx.h b/src/os_unixx.h
new file mode 100644
index 0000000000..2a28a6d5f1
--- /dev/null
+++ b/src/os_unixx.h
@@ -0,0 +1,122 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * 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.
+ */
+
+/*
+ * os_unixx.h -- include files that are only used in os_unix.c
+ */
+
+/*
+ * Stuff for signals
+ */
+#if defined(HAVE_SIGSET) && !defined(signal)
+# define signal sigset
+#endif
+
+/* sun's sys/ioctl.h redefines symbols from termio world */
+#if defined(HAVE_SYS_IOCTL_H) && !defined(sun)
+# include <sys/ioctl.h>
+#endif
+
+#ifndef USE_SYSTEM /* use fork/exec to start the shell */
+
+# if defined(HAVE_SYS_WAIT_H) || defined(HAVE_UNION_WAIT)
+# include <sys/wait.h>
+# endif
+
+# ifndef WEXITSTATUS
+# ifdef HAVE_UNION_WAIT
+# define WEXITSTATUS(stat_val) ((stat_val).w_T.w_Retcode)
+# else
+# define WEXITSTATUS(stat_val) (((stat_val) >> 8) & 0377)
+# endif
+# endif
+
+# ifndef WIFEXITED
+# ifdef HAVE_UNION_WAIT
+# define WIFEXITED(stat_val) ((stat_val).w_T.w_Termsig == 0)
+# else
+# define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
+# endif
+# endif
+
+#endif /* !USE_SYSTEM */
+
+#ifdef HAVE_STROPTS_H
+#ifdef sinix
+#define buf_T __system_buf_t__
+#endif
+# include <stropts.h>
+#ifdef sinix
+#undef buf_T
+#endif
+#endif
+
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif
+
+#ifdef HAVE_SYS_STREAM_H
+# include <sys/stream.h>
+#endif
+
+#ifdef HAVE_SYS_UTSNAME_H
+# include <sys/utsname.h>
+#endif
+
+#ifdef HAVE_SYS_SYSTEMINFO_H
+/*
+ * foolish Sinix <sys/systeminfo.h> uses SYS_NMLN but doesn't include
+ * <limits.h>, where it is defined. Perhaps other systems have the same
+ * problem? Include it here. -- Slootman
+ */
+# if defined(HAVE_LIMITS_H) && !defined(_LIMITS_H)
+# include <limits.h> /* for SYS_NMLN (Sinix 5.41 / Unix SysV.4) */
+# endif
+
+/* Define SYS_NMLN ourselves if it still isn't defined (for CrayT3E). */
+# ifndef SYS_NMLN
+# define SYS_NMLN 32
+# endif
+
+# include <sys/systeminfo.h> /* for sysinfo */
+#endif
+
+/*
+ * We use termios.h if both termios.h and termio.h are available.
+ * Termios is supposed to be a superset of termio.h. Don't include them both,
+ * it may give problems on some systems (e.g. hpux).
+ * I don't understand why we don't want termios.h for apollo.
+ */
+#if defined(HAVE_TERMIOS_H) && !defined(apollo)
+# include <termios.h>
+#else
+# ifdef HAVE_TERMIO_H
+# include <termio.h>
+# else
+# ifdef HAVE_SGTTY_H
+# include <sgtty.h>
+# endif
+# endif
+#endif
+
+#ifdef HAVE_SYS_PTEM_H
+# include <sys/ptem.h> /* must be after termios.h for Sinix */
+# ifndef _IO_PTEM_H /* For UnixWare that should check for _IO_PT_PTEM_H */
+# define _IO_PTEM_H
+# endif
+#endif
+
+/* shared library access */
+#if defined(HAVE_DLFCN_H) && defined(USE_DLOPEN)
+# ifdef __MVS__
+/* needed to define RTLD_LAZY (Anthony Giorgio) */
+# define __SUSV3
+# endif
+# include <dlfcn.h>
+#else
+#endif
diff --git a/src/po/Makefile b/src/po/Makefile
new file mode 100644
index 0000000000..8674031d84
--- /dev/null
+++ b/src/po/Makefile
@@ -0,0 +1,292 @@
+# Makefile for the Vim message translations.
+
+# TODO make this configurable
+# Note: ja.sjis, *.cp1250 and zh_CN.cp936 are only for MS-Windows, they are
+# not installed on Unix
+
+LANGUAGES = \
+ af \
+ ca \
+ cs \
+ de \
+ en_GB \
+ eo \
+ es \
+ fi \
+ fr \
+ ga \
+ it \
+ ja \
+ ko \
+ ko.UTF-8 \
+ nb \
+ nl \
+ no \
+ pl \
+ pt_BR \
+ ru \
+ sk \
+ sv \
+ uk \
+ vi \
+ zh_CN \
+ zh_CN.UTF-8 \
+ zh_TW \
+ zh_TW.UTF-8
+
+CONVERTED = \
+ cs.cp1250 \
+ ja.sjis \
+ ja.euc-jp \
+ pl.cp1250 \
+ pl.UTF-8 \
+ ru.cp1251 \
+ sk.cp1250 \
+ uk.cp1251 \
+ zh_CN.cp936
+
+MOFILES = \
+ af.mo \
+ ca.mo \
+ cs.mo \
+ de.mo \
+ en_GB.mo \
+ eo.mo \
+ es.mo \
+ fi.mo \
+ fr.mo \
+ ga.mo \
+ it.mo \
+ ja.mo \
+ ko.mo \
+ ko.UTF-8.mo \
+ nb.mo \
+ nl.mo \
+ no.mo \
+ pl.mo \
+ pt_BR.mo \
+ ru.mo \
+ sk.mo \
+ sv.mo \
+ uk.mo \
+ vi.mo \
+ zh_CN.UTF-8.mo \
+ zh_CN.mo \
+ zh_TW.UTF-8.mo \
+ zh_TW.mo
+
+MOCONVERTED = \
+ cs.cp1250.mo \
+ ja.sjis.mo \
+ ja.euc-jp.mo \
+ pl.cp1250.mo \
+ pl.UTF-8.mo \
+ ru.cp1251.mo \
+ sk.cp1250.mo \
+ uk.cp1251.mo \
+ zh_CN.cp936.mo
+
+CHECKFILES = \
+ af.ck \
+ ca.ck \
+ cs.ck \
+ de.ck \
+ en_GB.ck \
+ eo.ck \
+ es.ck \
+ fi.ck \
+ fr.ck \
+ ga.ck \
+ it.ck \
+ ja.ck \
+ ko.ck \
+ ko.UTF-8.ck \
+ nb.ck \
+ nl.ck \
+ no.ck \
+ pl.ck \
+ pt_BR.ck \
+ ru.ck \
+ sk.ck \
+ sv.ck \
+ uk.ck \
+ vi.ck \
+ zh_CN.UTF-8.ck \
+ zh_CN.ck \
+ zh_TW.UTF-8.ck \
+ zh_TW.ck \
+ cs.cp1250.ck \
+ ja.sjis.ck \
+ ja.euc-jp.ck \
+ pl.cp1250.ck \
+ pl.UTF-8.ck \
+ ru.cp1251.ck \
+ sk.cp1250.ck \
+ uk.cp1251.ck \
+ zh_CN.cp936.ck
+
+PACKAGE = vim
+SHELL = /bin/sh
+VIM = ../../build/src/vim
+
+# The OLD_PO_FILE_INPUT and OLD_PO_FILE_OUTPUT are for the new GNU gettext
+# tools 0.10.37, which use a slightly different .po file format that is not
+# compatible with Solaris (and old gettext implementations) unless these are
+# set. gettext 0.10.36 will not work!
+MSGFMT = OLD_PO_FILE_INPUT=yes msgfmt -v
+XGETTEXT = OLD_PO_FILE_INPUT=yes OLD_PO_FILE_OUTPUT=yes xgettext
+MSGMERGE = OLD_PO_FILE_INPUT=yes OLD_PO_FILE_OUTPUT=yes msgmerge
+
+.SUFFIXES:
+.SUFFIXES: .po .mo .pot .ck
+.PHONY: all install uninstall prefixcheck converted check clean checkclean distclean update-po $(LANGUAGES) $(CONVERTED)
+
+.po.mo:
+ $(MSGFMT) -o $@ $<
+
+.po.ck:
+ $(VIM) -u NONE -e -X -S check.vim -c "if error == 0 | q | endif" -c cq $<
+ touch $@
+
+all: $(MOFILES) $(MOCONVERTED)
+
+check: $(CHECKFILES)
+
+install: $(MOFILES) $(MOCONVERTED)
+ @$(MAKE) prefixcheck
+ for lang in $(LANGUAGES) $(CONVERTED); do \
+ dir=$(LOCALEDIR)/$$lang/; \
+ if test ! -x "$$dir"; then \
+ mkdir $$dir; chmod 755 $$dir; \
+ fi; \
+ dir=$(LOCALEDIR)/$$lang/LC_MESSAGES; \
+ if test ! -x "$$dir"; then \
+ mkdir $$dir; chmod 755 $$dir; \
+ fi; \
+ if test -r $$lang.mo; then \
+ $(INSTALL_DATA) $$lang.mo $$dir/$(PACKAGE).mo; \
+ chmod $(FILEMOD) $$dir/$(PACKAGE).mo; \
+ fi; \
+ done
+
+uninstall:
+ @$(MAKE) prefixcheck
+ for cat in $(MOFILES) $(MOCONVERTED); do \
+ cat=`basename $$cat`; \
+ lang=`echo $$cat | sed 's/\$(CATOBJEXT)$$//'`; \
+ rm -f $(LOCALEDIR)/$$lang/LC_MESSAGES/$(PACKAGE).mo; \
+ done
+
+converted: $(MOCONVERTED)
+
+# nl.po was added later, if it does not exist use a file with just a # in it
+# (an empty file doesn't work with old msgfmt).
+nl.po:
+ @( echo \# > nl.po )
+
+# Norwegian/Bokmal: "nb" is an alias for "no".
+# Copying the file is not efficient, but I don't know of another way to make
+# this work.
+nb.po: no.po
+ cp no.po nb.po
+
+# Convert ja.po to create ja.sjis.po. Requires doubling backslashes in the
+# second byte. Don't depend on sjiscorr, it should only be compiled when
+# ja.sjis.po is outdated.
+ja.sjis.po: ja.po
+ @$(MAKE) sjiscorr
+ rm -f ja.sjis.po
+ iconv -f utf-8 -t cp932 ja.po | ./sjiscorr > ja.sjis.po
+
+sjiscorr: sjiscorr.c
+ $(CC) -o sjiscorr sjiscorr.c
+
+ja.euc-jp.po: ja.po
+ iconv -f utf-8 -t euc-jp ja.po | \
+ sed -e 's/charset=utf-8/charset=euc-jp/' -e 's/# Original translations/# Generated from ja.po, DO NOT EDIT/' > ja.euc-jp.po
+
+# Convert cs.po to create cs.cp1250.po.
+cs.cp1250.po: cs.po
+ rm -f cs.cp1250.po
+ iconv -f iso-8859-2 -t cp1250 cs.po | \
+ sed -e 's/charset=ISO-8859-2/charset=cp1250/' -e 's/# Original translations/# Generated from cs.po, DO NOT EDIT/' > cs.cp1250.po
+
+# Convert pl.po to create pl.cp1250.po.
+pl.cp1250.po: pl.po
+ rm -f pl.cp1250.po
+ iconv -f iso-8859-2 -t cp1250 pl.po | \
+ sed -e 's/charset=ISO-8859-2/charset=cp1250/' -e 's/# Original translations/# Generated from pl.po, DO NOT EDIT/' > pl.cp1250.po
+
+# Convert pl.po to create pl.UTF-8.po.
+pl.UTF-8.po: pl.po
+ rm -f pl.UTF-8.po
+ iconv -f iso-8859-2 -t utf-8 pl.po | \
+ sed -e 's/charset=ISO-8859-2/charset=utf-8/' -e 's/# Original translations/# Generated from pl.po, DO NOT EDIT/' > pl.UTF-8.po
+
+# Convert sk.po to create sk.cp1250.po.
+sk.cp1250.po: sk.po
+ rm -f sk.cp1250.po
+ iconv -f iso-8859-2 -t cp1250 sk.po | \
+ sed -e 's/charset=ISO-8859-2/charset=cp1250/' -e 's/# Original translations/# Generated from sk.po, DO NOT EDIT/' > sk.cp1250.po
+
+# Convert zh_CN.po to create zh_CN.cp936.po.
+# set 'charset' to gbk to avoid that msfmt generates a warning
+zh_CN.cp936.po: zh_CN.po
+ rm -f zh_CN.cp936.po
+ iconv -f gb2312 -t cp936 zh_CN.po | \
+ sed -e 's/charset=gb2312/charset=gbk/' -e 's/# Original translations/# Generated from zh_CN.po, DO NOT EDIT/' > zh_CN.cp936.po
+
+# Convert ko.UTF-8.po to create ko.po.
+ko.po: ko.UTF-8.po
+ rm -f ko.po
+ iconv -f UTF-8 -t euc-kr ko.UTF-8.po | \
+ sed -e 's/charset=UTF-8/charset=euc-kr/' \
+ -e 's/# Korean translation for Vim/# Generated from ko.UTF-8.po, DO NOT EDIT/' \
+ > ko.po
+
+# Convert ru.po to create ru.cp1251.po.
+ru.cp1251.po: ru.po
+ rm -f ru.cp1251.po
+ iconv -f utf-8 -t cp1251 ru.po | \
+ sed -e 's/charset=utf-8/charset=cp1251/' -e 's/# Original translations/# Generated from ru.po, DO NOT EDIT/' > ru.cp1251.po
+
+# Convert uk.po to create uk.cp1251.po.
+uk.cp1251.po: uk.po
+ rm -f uk.cp1251.po
+ iconv -f utf-8 -t cp1251 uk.po | \
+ sed -e 's/charset=utf-8/charset=cp1251/' -e 's/# Original translations/# Generated from uk.po, DO NOT EDIT/' > uk.cp1251.po
+
+prefixcheck:
+ @if test "x" = "x$(prefix)"; then \
+ echo "******************************************"; \
+ echo " please use make from the src directory "; \
+ echo "******************************************"; \
+ exit 1; \
+ fi
+
+clean: checkclean
+ rm -f core core.* *.old.po *.mo *.pot sjiscorr
+
+distclean: clean
+
+checkclean:
+ rm -f *.ck
+
+$(PACKAGE).pot: ../*.c ../if_perl.xs ../GvimExt/gvimext.cpp ../globals.h ../if_py_both.h
+ cd ..; $(XGETTEXT) --default-domain=$(PACKAGE) \
+ --add-comments --keyword=_ --keyword=N_ \
+ *.c if_perl.xs GvimExt/gvimext.cpp globals.h if_py_both.h
+ mv -f ../$(PACKAGE).po $(PACKAGE).pot
+
+update-po: $(LANGUAGES)
+
+# Don't add a dependency here, we only want to update the .po files manually
+$(LANGUAGES):
+ @$(MAKE) $(PACKAGE).pot
+ if test ! -f $@.po.orig; then cp $@.po $@.po.orig; fi
+ mv $@.po $@.po.old
+ if $(MSGMERGE) $@.po.old $(PACKAGE).pot -o $@.po; then \
+ rm -f $@.po.old; \
+ else \
+ echo "msgmerge for $@.po failed!"; mv $@.po.old $@.po; \
+ fi
diff --git a/src/po/af.po b/src/po/af.po
new file mode 100644
index 0000000000..d73660b6ed
--- /dev/null
+++ b/src/po/af.po
@@ -0,0 +1,5393 @@
+# Afrikaans 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.
+# Danie Roux <droux@tuks.co.za>, 2001
+# Edited: Jean Jordaan (njj) <jean@upfrontsystems.co.za>, 10/01/2001
+# Edited by Danie on the 31st of October 2001
+# Edited by Danie on the 30th of July 2005
+#
+# njj: Save == Stoor. Write == Skryf.
+# njj: "deleted" == "geskrap"; "remove" == "verwyder"
+# njj: "source" == "uitvoer", want "sourced" lêers word uitgevoer
+# njj: "abort" == "staak"
+# close == sluit
+# Onseker:
+# X Display - vertoonskerm? (njj: ek dink dis reg.)
+# open vim in another GTK Widget - het vertaal as element (njj: OK, maar
+# 'n element is algemener as 'n widget: mens kry byvoorbeeld HTML
+# en XML elemente. Maar ek kan nie nou aan 'n spesifieker woord dink
+# nie.)
+# Printing aborted - drukkery gestaak? (njj: ek dink dis reg.)
+#
+# exception - uitsondering
+# abandon - weg gegooi
+# socket - WEET NIE
+msgid ""
+msgstr ""
+"Project-Id-Version: Vim 6.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2005-04-17 23:24+0200\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"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=ISO_8859-1\n"
+"Content-Transfer-Encoding: 8-bit\n"
+
+msgid "E82: Cannot allocate any buffer, exiting..."
+msgstr "E82: Kan nie buffer toeken nie, program sluit..."
+
+msgid "E83: Cannot allocate buffer, using other one..."
+msgstr "E83: Kan nie buffer toeken nie, gaan ander een gebruik..."
+
+msgid "E515: No buffers were unloaded"
+msgstr "E515: Geen buffers is uitgelaai nie"
+
+msgid "E516: No buffers were deleted"
+msgstr "E516: Geen buffers is geskrap nie"
+
+msgid "E517: No buffers were wiped out"
+msgstr "E517: Geen buffers is geskrap nie"
+
+msgid "1 buffer unloaded"
+msgstr "1 buffer uitgelaai"
+
+#, c-format
+msgid "%d buffers unloaded"
+msgstr "%d buffers uitgelaai"
+
+msgid "1 buffer deleted"
+msgstr "1 buffer geskrap"
+
+#, c-format
+msgid "%d buffers deleted"
+msgstr "%d buffers geskrap"
+
+msgid "1 buffer wiped out"
+msgstr "1 buffer geskrap"
+
+#, c-format
+msgid "%d buffers wiped out"
+msgstr "%d buffers geskrap"
+
+msgid "E84: No modified buffer found"
+msgstr "E84: Geen veranderde buffer gevind nie"
+
+#. back where we started, didn't find anything.
+msgid "E85: There is no listed buffer"
+msgstr "E85: Daar is geen gelyste buffer nie"
+
+msgid "E86: Buffer %ld does not exist"
+msgstr "E86: Buffer %ld bestaan nie"
+
+msgid "E87: Cannot go beyond last buffer"
+msgstr "E87: Kan nie verby laaste buffer gaan nie"
+
+msgid "E88: Cannot go before first buffer"
+msgstr "E88: Kan nie vóór eerste buffer gaan nie"
+
+msgid "E89: No write since last change for buffer %ld (add ! to override)"
+msgstr "E89: Buffer %ld nog ongestoor sedert vorige wysiging (gebruik ! om te dwing)"
+
+msgid "E90: Cannot unload last buffer"
+msgstr "E90: Kan nie laaste buffer uitlaai nie"
+
+msgid "W14: Warning: List of file names overflow"
+msgstr "W14: Waarskuwing: Lêerlys loop oor"
+
+#, c-format
+msgid "E92: Buffer %ld not found"
+msgstr "E92: buffer %ld kon nie gevind word nie"
+
+#, c-format
+msgid "E93: More than one match for %s"
+msgstr "E93: Meer as een treffer vir %s"
+
+#, c-format
+msgid "E94: No matching buffer for %s"
+msgstr "E94: Geen buffer wat by %s pas nie"
+
+#, c-format
+msgid "line %ld"
+msgstr "reël %ld"
+
+msgid "E95: Buffer with this name already exists"
+msgstr "E95: Buffer met hierdie naam bestaan alreeds"
+
+msgid " [Modified]"
+msgstr " [Gewysig]"
+
+msgid "[Not edited]"
+msgstr "[Ongewysig]"
+
+msgid "[New file]"
+msgstr "[Nuwe lêer]"
+
+msgid "[Read errors]"
+msgstr "[Leesfoute]"
+
+msgid "[readonly]"
+msgstr "[lees alleen]"
+
+#, c-format
+msgid "1 line --%d%%--"
+msgstr "1 reël --%d%%--"
+
+#, c-format
+msgid "%ld lines --%d%%--"
+msgstr "%ld reëls --%d%%--"
+
+#, c-format
+msgid "line %ld of %ld --%d%%-- col "
+msgstr "reël %ld van %ld --%d%%-- kolom "
+
+msgid "[No file]"
+msgstr "[Geen lêer]"
+
+#. must be a help buffer
+msgid "help"
+msgstr "help"
+
+msgid "[help]"
+msgstr "[help]"
+
+msgid "[Preview]"
+msgstr "[Voorskou]"
+
+msgid "All"
+msgstr "Alles"
+
+msgid "Bot"
+msgstr "Ond"
+
+msgid "Top"
+msgstr "Bo"
+
+#, c-format
+msgid ""
+"\n"
+"# Buffer list:\n"
+msgstr ""
+"\n"
+"# Buffer lys:\n"
+
+msgid "[Error List]"
+msgstr "[Foutlys]"
+
+msgid "[No File]"
+msgstr "[Geen lêer]"
+
+msgid ""
+"\n"
+"--- Signs ---"
+msgstr ""
+"\n"
+"--- Tekens ---"
+
+#, c-format
+msgid "Signs for %s:"
+msgstr "Tekens vir %s:"
+
+#, c-format
+msgid " line=%ld id=%d name=%s"
+msgstr " reël=%ld id=%d naam=%s"
+
+#, c-format
+msgid "E96: Can not diff more than %ld buffers"
+msgstr "E96: Kan nie meer as %ld buffers 'diff' nie"
+
+msgid "E97: Cannot create diffs"
+msgstr "E97: Kan nie 'diffs' skep nie "
+
+msgid "Patch file"
+msgstr "Laslap lêer"
+
+msgid "E98: Cannot read diff output"
+msgstr "E98: Kan nie 'diff' afvoer lees nie"
+
+msgid "E99: Current buffer is not in diff mode"
+msgstr "E99: Huidige buffer is nie in 'diff' modus nie"
+
+msgid "E100: No other buffer in diff mode"
+msgstr "E100: Geen ander buffer in 'diff' modus nie"
+
+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"
+
+#, c-format
+msgid "E102: Can't find buffer \"%s\""
+msgstr "E102: Kan buffer %s nie vind nie"
+
+#, c-format
+msgid "E103: Buffer \"%s\" is not in diff mode"
+msgstr "E103: Buffer \"%s\" is nie in 'diff' modus nie"
+
+msgid "E104: Escape not allowed in digraph"
+msgstr "E104: 'Escape' nie toegelaat in digraaf nie"
+
+msgid "E544: Keymap file not found"
+msgstr "E544: Sleutelbindinglêer nie gevind nie"
+
+msgid "E105: Using :loadkeymap not in a sourced file"
+msgstr "E105: :loadkeymap word buite 'n uitvoerlêer gebruik"
+
+msgid " Keyword completion (^N^P)"
+msgstr " Sleutelwoord voltooiing (^N^P)"
+
+#. ctrl_x_mode == 0, ^P/^N compl.
+msgid " ^X mode (^E^Y^L^]^F^I^K^D^V^N^P)"
+msgstr " ^X modus (^E^Y^L^]^F^I^K^D^V^N^P)"
+
+#. Scroll has it's own msgs, in it's place there is the msg for local
+#. * ctrl_x_mode = 0 (eg continue_status & CONT_LOCAL) -- Acevedo
+msgid " Keyword Local completion (^N^P)"
+msgstr " Sleutelwoord Lokale voltooiing (^N^P)"
+
+msgid " Whole line completion (^L^N^P)"
+msgstr " Hele-reël voltooiing (^L^N^P)"
+
+msgid " File name completion (^F^N^P)"
+msgstr " Lêernaam voltooiing (^F^N^P)"
+
+msgid " Tag completion (^]^N^P)"
+msgstr " Etiketvoltooiing (^]^N^P)"
+
+msgid " Path pattern completion (^N^P)"
+msgstr " Gidspatroon voltooiing (^N^P)"
+
+msgid " Definition completion (^D^N^P)"
+msgstr " Definisievoltooiing (^D^N^P)"
+
+msgid " Dictionary completion (^K^N^P)"
+msgstr " Woordeboekvoltooiing (^K^N^P)"
+
+msgid " Thesaurus completion (^T^N^P)"
+msgstr " Tesourusvoltooiing (^T^N^P)"
+
+msgid " Command-line completion (^V^N^P)"
+msgstr " Bevelreëlvoltooiing (^V^N^P)"
+
+msgid "Hit end of paragraph"
+msgstr "Het einde van paragraaf getref"
+
+msgid "'thesaurus' option is empty"
+msgstr "'thesaurus' opsie is leeg"
+
+msgid "'dictionary' option is empty"
+msgstr "'dictionary' opsie is leeg"
+
+#, c-format
+msgid "Scanning dictionary: %s"
+msgstr "Deursoek woordeboek: %s"
+
+msgid " (insert) Scroll (^E/^Y)"
+msgstr " (invoeg) Rol (^E/^Y)"
+
+msgid " (replace) Scroll (^E/^Y)"
+msgstr " (vervang) Rol (^E/^Y)"
+
+#, c-format
+msgid "Scanning: %s"
+msgstr "Soek vir: %s"
+
+#, c-format
+msgid "Scanning tags."
+msgstr "Deursoek etikette."
+
+msgid " Adding"
+msgstr " Word bygevoeg"
+
+#. 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.
+#.
+msgid "-- Searching..."
+msgstr "-- Soekend..."
+
+msgid "Back at original"
+msgstr "Terug by oorspronklike"
+
+msgid "Word from other line"
+msgstr "Woord van ander reël"
+
+msgid "The only match"
+msgstr "Die enigste treffer"
+
+#, c-format
+msgid "match %d of %d"
+msgstr "treffer %d van %d"
+
+#, c-format
+msgid "match %d"
+msgstr "treffer %d"
+
+#. Skip further arguments but do continue to
+#. * search for a trailing command.
+#, c-format
+msgid "E106: Unknown variable: \"%s\""
+msgstr "E106: Onbekende veranderlike: \"%s\""
+
+#, c-format
+msgid "E107: Missing parentheses: %s"
+msgstr "E107: Ontbrekende hakies: %s"
+
+#, c-format
+msgid "E108: No such variable: \"%s\""
+msgstr "E108: Geen veranderlike: \"%s\""
+
+msgid "E109: Missing ':' after '?'"
+msgstr "E109: Ontbrekende ':' na '?'"
+
+msgid "E110: Missing ')'"
+msgstr "E110: Ontbrekende ')'"
+
+msgid "E111: Missing ']'"
+msgstr "E111: Ontbrekende ']'"
+
+#, c-format
+msgid "E112: Option name missing: %s"
+msgstr "E112: Opsienaam ontbreek: %s"
+
+#, c-format
+msgid "E113: Unknown option: %s"
+msgstr "E113: Onbekende opsie: %s"
+
+#, c-format
+msgid "E114: Missing quote: %s"
+msgstr "E114: Ontbrekende aanhalingsteken: %s"
+
+#, c-format
+msgid "E115: Missing quote: %s"
+msgstr "E115: Ontbrekende aanhalingsteken: %s"
+
+#, c-format
+msgid "E116: Invalid arguments for function %s"
+msgstr "E116: Ongeldige parameters vir funksie %s"
+
+#, c-format
+msgid "E117: Unknown function: %s"
+msgstr "E117: Onbekende funksie: %s"
+
+#, c-format
+msgid "E118: Too many arguments for function: %s"
+msgstr "E118: Te veel parameters vir funksie: %s"
+
+#, c-format
+msgid "E119: Not enough arguments for function: %s"
+msgstr "E119: Te min parameters vir funksie: %s"
+
+#, c-format
+msgid "E120: Using <SID> not in a script context: %s"
+msgstr "E120: <SID> word buite skripkonteks gebruik: %s"
+
+#.
+#. * 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"
+
+#, c-format
+msgid "+-%s%3ld lines: "
+msgstr "+-%s%3ld reëls: "
+
+msgid ""
+"&OK\n"
+"&Cancel"
+msgstr ""
+"&OK\n"
+"&Kanselleer"
+
+msgid "called inputrestore() more often than inputsave()"
+msgstr "inputrestore() is meer gereeld as inputsave() geroep"
+
+msgid "E655: Too many symbolic links (cycle?)"
+msgstr "E655: Te veel simboliese skakels (siklus?)"
+
+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"
+
+msgid "E258: Unable to send to client"
+msgstr "E258: Kan nie na kliënt stuur nie"
+
+#, c-format
+msgid "E241: Unable to send to %s"
+msgstr "E241: Kan nie na %s stuur nie"
+
+msgid "(Invalid)"
+msgstr "(Ongeldig)"
+
+#, c-format
+msgid "E121: Undefined variable: %s"
+msgstr "E121: Ongedefinieerde veranderlike: %s"
+
+msgid "E461: Illegal variable name: %s"
+msgstr "E461: Ongeldige veranderlikenaam: %s"
+
+msgid "E122: Function %s already exists, add ! to replace it"
+msgstr "E122: Funksie %s bestaan alreeds, gebruik ! om te vervang"
+
+#, c-format
+msgid "E123: Undefined function: %s"
+msgstr "E123: Ongedefinieerde funksie: %s"
+
+#, c-format
+msgid "E124: Missing '(': %s"
+msgstr "E124: Ontbrekende '(': %s"
+
+#, c-format
+msgid "E125: Illegal argument: %s"
+msgstr "E125: Ongeldige parameter: %s"
+
+msgid "E126: Missing :endfunction"
+msgstr "E126: Ontbrekende ':endfunction'"
+
+#, c-format
+msgid "E127: Cannot redefine function %s: It is in use"
+msgstr "E127: Kan funksie %s nie herdefinieer nie: Dit is in gebruik"
+
+msgid "E129: Function name required"
+msgstr "E129: Funksienaam vereis"
+
+#, c-format
+msgid "E128: Function name must start with a capital: %s"
+msgstr "E128: Funksienaam moet met 'n hoofletter begin: %s"
+
+#, c-format
+msgid "E130: Undefined function: %s"
+msgstr "E130: Ongedefinieerde funksie: %s"
+
+#, c-format
+msgid "E131: Cannot delete function %s: It is in use"
+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'"
+
+#. always scroll up, don't overwrite
+#, c-format
+msgid "calling %s"
+msgstr "roep %s"
+
+msgid "%s aborted"
+msgstr "%s gekanselleer"
+
+#, c-format
+msgid "%s returning #%ld"
+msgstr "%s lewer #%ld op"
+
+#, c-format
+msgid "%s returning \"%s\""
+msgstr "%s lewer \"%s\" op"
+
+#. always scroll up, don't overwrite
+#, c-format
+msgid "continuing in %s"
+msgstr "vervolg in %s"
+
+msgid "E133: :return not inside a function"
+msgstr "E133: ':return' buite funksie"
+
+#, c-format
+msgid ""
+"\n"
+"# global variables:\n"
+msgstr ""
+"\n"
+"# globale veranderlikes:\n"
+
+msgid "Entering Debug mode. Type \"cont\" to continue."
+msgstr "Ontfoutmodus begin nou. Tik \"cont\" om te verlaat."
+
+#, c-format
+msgid "line %ld: %s"
+msgstr "reël %ld: %s"
+
+#, c-format
+msgid "cmd: %s"
+msgstr "cmd: %s"
+
+#, c-format
+msgid "Breakpoint in \"%s%s\" line %ld"
+msgstr "Inspeksiepunt in \"%s%s\" reël %ld"
+
+#, c-format
+msgid "E161: Breakpoint not found: %s"
+msgstr "E161: Inspeksiepunt kon nie gevind word nie: %s"
+
+msgid "No breakpoints defined"
+msgstr "Geen inspeksiepunte gedefinieer nie"
+
+#, c-format
+msgid "%3d %s %s line %ld"
+msgstr "%3d %s %s reël %ld"
+
+msgid "Save As"
+msgstr "Stoor As"
+
+#, c-format
+msgid "Save changes to \"%.*s\"?"
+msgstr "Stoor veranderinge na \"%.*s\"?"
+
+msgid "Untitled"
+msgstr "Ongetiteld"
+
+#, c-format
+msgid "E162: No write since last change for buffer \"%s\""
+msgstr "E162: Buffer \"%s\" is nie geskryf sedert vorige wysiging nie"
+
+msgid "Warning: Entered other buffer unexpectedly (check autocommands)"
+msgstr "Waarskuwing: Ander buffer onverwags betree (kyk na outobevele)"
+
+msgid "E163: There is only one file to edit"
+msgstr "E163: Daar is net een lêer om te bewerk"
+
+msgid "E164: Cannot go before first file"
+msgstr "E164: Kan nie vóór die eerste lêer gaan nie"
+
+msgid "E165: Cannot go beyond last file"
+msgstr "E165: Kan nie verby die laaste lêer gaan nie"
+
+msgid "E666: compiler not supported: %s"
+msgstr "E666: vertaler word nie ondersteun nie: %s"
+
+#, c-format
+msgid "Searching for \"%s\" in \"%s\""
+msgstr "Besig om te soek vir \"%s\" in \"%s\""
+
+#, c-format
+msgid "Searching for \"%s\""
+msgstr "Besig om te soek vir \"%s\""
+
+#, c-format
+msgid "not found in 'runtimepath': \"%s\""
+msgstr "kon nie in 'runtimepath' gevind word nie: \"%s\""
+
+msgid "Source Vim script"
+msgstr "Voer Vim skrip uit"
+
+#, c-format
+msgid "Cannot source a directory: \"%s\""
+msgstr "Kan nie gids uitvoer nie: \"%s\""
+
+#, c-format
+msgid "could not source \"%s\""
+msgstr "kon nie \"%s\" uitvoer nie"
+
+#, c-format
+msgid "line %ld: could not source \"%s\""
+msgstr "reël %ld: kon nie \"%s\" uitvoer nie"
+
+#, c-format
+msgid "sourcing \"%s\""
+msgstr "besig om \"%s\" uit te voer"
+
+#, c-format
+msgid "line %ld: sourcing \"%s\""
+msgstr "reël %ld: voer nou \"%s\" uit"
+
+#, c-format
+msgid "finished sourcing %s"
+msgstr "%s klaar uitgevoer"
+
+msgid "W15: Warning: Wrong line separator, ^M may be missing"
+msgstr "W15: Waarskuwing: Verkeerde reëlskeiding, ^M ontbreek dalk"
+
+msgid "E167: :scriptencoding used outside of a sourced file"
+msgstr "E167: ':scriptencoding' buite 'n uitvoerlêer gebruik"
+
+msgid "E168: :finish used outside of a sourced file"
+msgstr "E168: ':finish' buite 'n uitvoerlêer gebruik"
+
+#, c-format
+msgid "Page %d"
+msgstr "Bladsy %d"
+
+msgid "No text to be printed"
+msgstr "Geen teks om te druk nie"
+
+#, c-format
+msgid "Printing page %d (%d%%)"
+msgstr "Druk nou bladsy %d (%d%%)"
+
+#, c-format
+msgid " Copy %d of %d"
+msgstr " Kopie %d van %d"
+
+#, c-format
+msgid "Printed: %s"
+msgstr "Gedruk: %s"
+
+#, c-format
+msgid "Printing aborted"
+msgstr "Drukkery gestaak"
+
+msgid "E455: Error writing to PostScript output file"
+msgstr "E455: Kan nie na 'PostScript' afvoerlêer skryf nie"
+
+msgid "E624: Can't open file \"%s\""
+msgstr "E624: Kan nie lêer \"%s\" oopmaak nie"
+
+#, c-format
+msgid "E457: Can't read PostScript resource file \"%s\""
+msgstr "E457: Kan nie 'PostScript' hulpbron-lêer \"%s\" lees nie"
+
+msgid "E618: file \"%s\" is not a PostScript resource file"
+msgstr "E618: Lêer \"%s\" is nie 'n 'PostScript' hulpbron-lêer nie"
+
+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"
+
+#, c-format
+msgid "E621: \"%s\" resource file has wrong version"
+msgstr "E621: \"%s\" die hulpbron lêer het die verkeerde weergawe"
+
+msgid "E324: Can't open PostScript output file"
+msgstr "E324: Kan nie 'PostScript' afvoerlêer oopmaak nie"
+
+#, c-format
+msgid "E456: Can't open file \"%s\""
+msgstr "E456: Kan nie lêer %s oopmaak nie"
+
+msgid "E456: Can't find PostScript resource file \"prolog.ps\""
+msgstr "E456: Kan nie 'PostScript' hulpbron-lêer \"prolog.ps\" lees nie"
+
+msgid "E456: Can't find PostScript resource file \"%s.ps\""
+msgstr "E456: Kan nie 'PostScript' hulpbron-lêer \"%s\" vind nie"
+
+#, c-format
+msgid "E620: Unable to convert from multi-byte to \"%s\" encoding"
+msgstr "E620: Kon nie van wye-greep na \"%s\" enkodering verander nie"
+
+msgid "Sending to printer..."
+msgstr "Besig om te stuur na drukker..."
+
+msgid "E365: Failed to print PostScript file"
+msgstr "E365: Kon nie 'PostScript' lêer druk nie"
+
+msgid "Print job sent."
+msgstr "Druktaak gestuur."
+
+#, c-format
+msgid "Current %slanguage: \"%s\""
+msgstr "Huidige %staal: \"%s\""
+
+#, c-format
+msgid "E197: Cannot set language to \"%s\""
+msgstr "E197: Kan nie taal na \"%s\" verander nie"
+
+#, c-format
+msgid "<%s>%s%s %d, Hex %02x, Octal %03o"
+msgstr "<%s>%s%s %d, Hex %02x, Oktaal %03o"
+
+msgid "> %d, Hex %04x, Octal %o"
+msgstr "> %d, Hex %04x, Oktaal %o"
+
+msgid "> %d, Hex %08x, Octal %o"
+msgstr "> %d, Hex %08x, Oktaal %o"
+
+msgid "E134: Move lines into themselves"
+msgstr "E134: Skuif reëls in hulself in"
+
+msgid "1 line moved"
+msgstr "1 reël geskuif"
+
+#, c-format
+msgid "%ld lines moved"
+msgstr "%ld reëls geskuif"
+
+#, c-format
+msgid "%ld lines filtered"
+msgstr "%ld 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"
+
+msgid "%sviminfo: %s in line: "
+msgstr "%sviminfo: %s in reël: "
+
+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 "Reading viminfo 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"
+
+msgid " FAILED"
+msgstr " GEFAAL"
+
+#, c-format
+msgid "E137: Viminfo file is not writable: %s"
+msgstr "E137: Viminfo lêer is nie skryfbaar nie: %s"
+
+#, c-format
+msgid "E138: Can't write viminfo file %s!"
+msgstr "E138: Kan nie viminfo lêer %s stoor nie!"
+
+#, c-format
+msgid "Writing viminfo file \"%s\""
+msgstr "Besig om viminfo lêer \"%s\" te stoor"
+
+#. Write the info:
+#, c-format
+msgid "# This viminfo file was generated by Vim %s.\n"
+msgstr "# Hierdie viminfo lêer is gegenereer deur Vim %s.\n"
+
+#, c-format
+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 "# Value of 'encoding' when this file was written\n"
+msgstr "# Waarde van 'encoding' toe hierdie lêer gestoor is\n"
+
+msgid "Illegal starting char"
+msgstr "Ongeldige beginkarakter"
+
+#. Overwriting a file that is loaded in another buffer is not a
+#. * good idea.
+msgid "E139: File is loaded in another buffer"
+msgstr "E139: Lêer is gelaai in ander buffer"
+
+msgid "Write partial file?"
+msgstr "Skryf gedeeltelike lêer?"
+
+msgid "E140: Use ! to write partial buffer"
+msgstr "E140: Gebruik ! om gedeeltelike buffer te skryf"
+
+#, c-format
+msgid "Overwrite existing file \"%.*s\"?"
+msgstr "Oorskryf bestaande lêer \"%.*s\"?"
+
+#, c-format
+msgid "E141: No file name for buffer %ld"
+msgstr "E141: Geen lêernaam vir buffer %ld nie"
+
+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"
+
+#, c-format
+msgid ""
+"'readonly' option is set for \"%.*s\".\n"
+"Do you wish to write anyway?"
+msgstr ""
+"'readonly' opsie is aan vir \"%.*s\".\n"
+"Wil jy dit forseer?"
+
+msgid "Edit File"
+msgstr "Verander lêer"
+
+#, c-format
+msgid "E143: Autocommands unexpectedly deleted new buffer %s"
+msgstr "E143: Outobevele het nuwe buffer %s onverwags geskrap"
+
+msgid "E144: non-numeric argument to :z"
+msgstr "E144: nie-numeriese parameter vir :z"
+
+msgid "E145: Shell commands not allowed in rvim"
+msgstr "E145: Dop bevele nie toegelaat in rvim"
+
+msgid "E146: Regular expressions can't be delimited by letters"
+msgstr "E146: Patrone kan nie deur letters afgebaken word nie"
+
+#, c-format
+msgid "replace with %s (y/n/a/q/l/^E/^Y)?"
+msgstr "vervang met %s (y/n/a/q/l/^E/^Y)?"
+
+msgid "(Interrupted) "
+msgstr "(Onderbreek) "
+
+msgid "1 substitution"
+msgstr "1 vervanging"
+
+#, c-format
+msgid "%ld substitutions"
+msgstr "%ld vervangings"
+
+msgid " on 1 line"
+msgstr " op 1 reël"
+
+#, c-format
+msgid " on %ld lines"
+msgstr " op %ld reëls"
+
+msgid "E147: Cannot do :global recursive"
+msgstr "E147: Kan nie :global rekursief doen nie "
+
+msgid "E148: Regular expression missing from global"
+msgstr "E148: Patroon ontbreek uit globaal"
+
+#, c-format
+msgid "Pattern found in every line: %s"
+msgstr "Patroon gevind in elke reël: %s"
+
+#, c-format
+msgid ""
+"\n"
+"# Last Substitute String:\n"
+"$"
+msgstr ""
+"\n"
+"# Vorige Vervangstring:\n"
+"$"
+
+msgid "E478: Don't panic!"
+msgstr "E478: Bly kalm!"
+
+msgid "E661: Sorry, no '%s' help for %s"
+msgstr "E661: Jammer, geen '%s' hulp vir %s nie"
+
+#, c-format
+msgid "E149: Sorry, no help for %s"
+msgstr "E149: Jammer, geen hulp vir %s nie"
+
+#, c-format
+msgid "Sorry, help file \"%s\" not found"
+msgstr "Jammer, hulplêer \"%s\" kan nie gevind word nie"
+
+#, c-format
+msgid "E150: Not a directory: %s"
+msgstr "E150: Nie 'n gids nie: %s"
+
+#, c-format
+msgid "E152: Cannot open %s for writing"
+msgstr "E152: Kan nie %s oopmaak om te skryf nie"
+
+#, c-format
+msgid "E153: Unable to open %s for reading"
+msgstr "E153: Kan nie %s oop maak om te lees nie"
+
+#, 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"
+
+msgid "E154: Duplicate tag \"%s\" in file %s/%s"
+msgstr "E154: Duplikaat etiket \"%s\" in lêer %s/%s"
+
+#, c-format
+msgid "E160: Unknown sign command: %s"
+msgstr "E160: Onbekende funksie: %s"
+
+msgid "E156: Missing sign name"
+msgstr "E156: Ontbrekende tekennaam"
+
+msgid "E612: Too many signs defined"
+msgstr "E612: Te veel tekens gedefinieer"
+
+#, c-format
+msgid "E239: Invalid sign text: %s"
+msgstr "E239: Ongeldige tekenteks: %s"
+
+#, c-format
+msgid "E155: Unknown sign: %s"
+msgstr "E155: Onbekende opsie: %s"
+
+msgid "E159: Missing sign number"
+msgstr "E159: Ontbrekende tekennommer"
+
+#, c-format
+msgid "E158: Invalid buffer name: %s"
+msgstr "E158: Ongeldige buffernaam: %s"
+
+#, c-format
+msgid "E157: Invalid sign ID: %ld"
+msgstr "E157: Ongeldige teken ID: %ld"
+
+msgid " (NOT FOUND)"
+msgstr " (NIE GEVIND NIE)"
+
+msgid " (not supported)"
+msgstr " (word nie ondersteun nie)"
+
+msgid "[Deleted]"
+msgstr "[Geskrap]"
+
+msgid "Entering Ex mode. Type \"visual\" to go to Normal mode."
+msgstr "Betree Ex modus. Tik \"visual\" om na Normale modus terug te keer."
+
+#. must be at EOF
+msgid "E501: At end-of-file"
+msgstr "E501: By lêereinde"
+
+msgid "E169: Command too recursive"
+msgstr "E169: Bevel te rekursief"
+
+msgid "E605: Exception not caught: %s"
+msgstr "E605: Uitsondering nie gevang nie: %s"
+
+msgid "End of sourced file"
+msgstr "Einde van uitvoerlêer"
+
+msgid "End of function"
+msgstr "Einde van funksie "
+
+msgid "E464: Ambiguous use of user-defined command"
+msgstr "E464: Dubbelsinnige gebruik van gebruiker-gedefinieerde bevel"
+
+msgid "E492: Not an editor command"
+msgstr "E492: Nie 'n verwerkerbevel nie"
+
+msgid "E493: Backwards range given"
+msgstr "E493: Terugwaardse omvang gegee"
+
+msgid "Backwards range given, OK to swap"
+msgstr "Terugwaardse omvang gegee, OK om te ruil"
+
+msgid "E494: Use w or w>>"
+msgstr "E494: Gebruik w of w>>"
+
+msgid "E319: Sorry, the command is not available in this version"
+msgstr "E319: Jammer, die bevel is nie geïmplementeer nie"
+
+msgid "E172: Only one file name allowed"
+msgstr "E172: Slegs een lêernaam toegelaat"
+
+msgid "1 more file to edit. Quit anyway?"
+msgstr "Nog 1 lêer om te bewerk. Stop in elk geval?"
+
+#, c-format
+msgid "%d more files to edit. Quit anyway?"
+msgstr "Nog %d lêers om te bewerk. Stop in elk geval?"
+
+msgid "E173: 1 more file to edit"
+msgstr "E173: Nog 1 lêer om te bewerk"
+
+#, c-format
+msgid "E173: %ld more files to edit"
+msgstr "E173: Nog %ld lêers om te bewerk"
+
+msgid "E174: Command already exists: add ! to replace it"
+msgstr "E174: Bevel bestaan alreeds: gebruik ! om te herdefinieer"
+
+msgid ""
+"\n"
+" Name Args Range Complete Definition"
+msgstr ""
+"\n"
+" Naam Args Reeks Klaar Definisie"
+
+msgid "No user-defined commands found"
+msgstr "Geen gebruiker-gedefinieerde bevele gevind nie"
+
+msgid "E175: No attribute specified"
+msgstr "E175: Geen eienskappe gespesifiseer nie"
+
+msgid "E176: Invalid number of arguments"
+msgstr "E176: Ongeldige aantal parameters"
+
+msgid "E177: Count cannot be specified twice"
+msgstr "E177: Telling kan nie twee keer gespesifiseer word nie"
+
+msgid "E178: Invalid default value for count"
+msgstr "E178: Ongeldige verstekwaarde vir telling"
+
+msgid "E179: argument required for complete"
+msgstr "E179: parameter nodig vir voltooiing"
+
+#, c-format
+msgid "E180: Invalid complete value: %s"
+msgstr "E180: Ongeldige voltooiingswaarde: %s"
+
+msgid "E468: Completion argument only allowed for custom completion"
+msgstr "E468: Voltooiingsargument words slegs toegelaat vir eie voltooiing"
+
+msgid "E467: Custom completion requires a function argument"
+msgstr "E467: Eie voltooiing benodig 'n funksie parameter"
+
+#, c-format
+msgid "E181: Invalid attribute: %s"
+msgstr "E181: Ongeldige eienskap: %s"
+
+msgid "E182: Invalid command name"
+msgstr "E182: Ongeldige bevelnaam"
+
+msgid "E183: User defined commands must start with an uppercase letter"
+msgstr "E183: Gebruiker-gedefinieerde bevele moet met 'n hoofletter begin"
+
+#, c-format
+msgid "E184: No such user-defined command: %s"
+msgstr "E184: Geen gebruiker-gedefinieerde bevel nie: %s"
+
+#, c-format
+msgid "E185: Cannot find color scheme %s"
+msgstr "E185: Kan nie kleurskema %s vind nie"
+
+msgid "Greetings, Vim user!"
+msgstr "Goeiedag, Vim gebruiker!"
+
+msgid "Edit File in new window"
+msgstr "Bewerk lêer in nuwe venster"
+
+msgid "No swap file"
+msgstr "Geen ruillêer"
+
+msgid "Append File"
+msgstr "Las aan by lêer"
+
+msgid "E186: No previous directory"
+msgstr "E186: Geen vorige gids nie"
+
+msgid "E187: Unknown"
+msgstr "E187: Onbekend"
+
+msgid "E465: :winsize requires two number arguments"
+msgstr "E465: ':winsize' benodig twee nommer parameters"
+
+#, c-format
+msgid "Window position: X %d, Y %d"
+msgstr "Vensterposisie: X %d, Y %d"
+
+msgid "E188: Obtaining window position not implemented for this platform"
+msgstr ""
+"E188: Verkryging van vensterposisie is nie vir hierdie platform "
+"geïmplementeer nie"
+
+msgid "E466: :winpos requires two number arguments"
+msgstr "E466: :winpos benodig twee parameters"
+
+msgid "Save Redirection"
+msgstr "Stoor Herversturing"
+
+msgid "Save View"
+msgstr "Stoor Oorsig"
+
+msgid "Save Session"
+msgstr "Stoor Sessie"
+
+msgid "Save Setup"
+msgstr "Stoor konfigurasie"
+
+msgid "E189: \"%s\" exists (add ! to override)"
+msgstr "E189: \"%s\" bestaan (gebruik ! om te dwing)"
+
+#, c-format
+msgid "E190: Cannot open \"%s\" for writing"
+msgstr "E190: Kan \"%s\" nie oopmaak vir skryf nie"
+
+#. set mark
+msgid "E191: Argument must be a letter or forward/backward quote"
+msgstr ""
+"E191: Parameter moet 'n letter of 'n terug/vorentoe aanhalingsteken wees"
+
+msgid "E192: Recursive use of :normal too deep"
+msgstr "E192: Rekursiewe gebruik van ':normal' te diep"
+
+msgid "E194: No alternate file name to substitute for '#'"
+msgstr "E194: Geen alternatiewe lêernaam vir '#' nie"
+
+msgid "E495: no autocommand file name to substitute for \"<afile>\""
+msgstr "E495: geen outobevel-lêernaam om \"<afile>\" mee te vervang nie"
+
+msgid "E496: no autocommand buffer number to substitute for \"<abuf>\""
+msgstr "E496: geen outobevel buffernommer om \"<abuf>\" mee te vervang nie"
+
+msgid "E497: no autocommand match name to substitute for \"<amatch>\""
+msgstr "E497: geen outobevel treffernaam om \"<amatch>\" mee te vervang nie"
+
+msgid "E498: no :source file name to substitute for \"<sfile>\""
+msgstr "E498: geen ':source' lêernaam om \"<sfile>\" mee te vervang nie"
+
+msgid "E499: Empty file name for '%' or '#', only works with \":p:h\""
+msgstr "E499: Leë lêernaam vir '%' of '#', werk slegs met \":p:h\""
+
+msgid "E500: Evaluates to an empty string"
+msgstr "E500: Evalueer na 'n leë string"
+
+msgid "E195: Cannot open viminfo file for reading"
+msgstr "E195: Kan 'viminfo' lêer nie oopmaak om te lees nie"
+
+msgid "E196: No digraphs in this version"
+msgstr "E196: Geen digrawe in hierdie weergawe nie"
+
+msgid "E608: Cannot :throw exceptions with 'Vim' prefix"
+msgstr "E608: Kan nie uitsonderings ':throw' met 'Vim' voorvoegsel nie"
+
+#. always scroll up, don't overwrite
+#, c-format
+msgid "Exception thrown: %s"
+msgstr "Uitsondering gegooi: %s"
+
+#, c-format
+msgid "Exception finished: %s"
+msgstr "Uitsondering het klaar gemaak: %s"
+
+#, c-format
+msgid "Exception discarded: %s"
+msgstr "Uitsondering weg gegooi: %s"
+
+msgid "%s, line %ld"
+msgstr "%s, reël %ld"
+
+#. always scroll up, don't overwrite
+msgid "Exception caught: %s"
+msgstr "Uitsondering gevang: %s"
+
+#, c-format
+msgid "%s made pending"
+msgstr "%s is afwagtend gemaak"
+
+msgid "%s resumed"
+msgstr "%s teruggekeer"
+
+#, c-format
+msgid "%s discarded"
+msgstr "%s weg gegooi"
+
+msgid "Exception"
+msgstr "Uitsondering"
+
+msgid "Error and interrupt"
+msgstr "Fout en onderbreking"
+
+msgid "Error"
+msgstr "Fout"
+
+#. if (pending & CSTP_INTERRUPT)
+msgid "Interrupt"
+msgstr "Onderbreek"
+
+msgid "E579: :if nesting too deep"
+msgstr "E579: geneste ':if' te diep"
+
+msgid "E580: :endif without :if"
+msgstr "E580: ':endif' sonder ':if'"
+
+msgid "E581: :else without :if"
+msgstr "E581: ':else' sonder ':if'"
+
+msgid "E582: :elseif without :if"
+msgstr "E582: ':elseif' sonder ':if'"
+
+msgid "E583: multiple :else"
+msgstr "E583: meer as een ':else'"
+
+msgid "E584: :elseif after :else"
+msgstr "E584: ':elseif' na ':else'"
+
+msgid "E585: :while nesting too deep"
+msgstr "E585: ':while' te diep genes"
+
+msgid "E586: :continue without :while"
+msgstr "E586: ':continue' sonder ':while'"
+
+msgid "E587: :break without :while"
+msgstr "E587: ':break' sonder ':while'"
+
+msgid "E601: :try nesting too deep"
+msgstr "E601: geneste ':try' te diep"
+
+msgid "E603: :catch without :try"
+msgstr "E603: ':catch' sonder ':try'"
+
+#. Give up for a ":catch" after ":finally" and ignore it.
+#. * Just parse.
+msgid "E604: :catch after :finally"
+msgstr "E604: ':catch' na ':finally'"
+
+msgid "E606: :finally without :try"
+msgstr "E606: ':finally' sonder ':try'"
+
+#. Give up for a multiple ":finally" and ignore it.
+msgid "E607: multiple :finally"
+msgstr "E607: meer as een ':finally'"
+
+msgid "E602: :endtry without :try"
+msgstr "E602: ':endtry' sonder ':try'"
+
+msgid "E193: :endfunction not inside a function"
+msgstr "E193: ':endfunction' nie in 'n funksie nie"
+
+msgid "tagname"
+msgstr "etiketnaam"
+
+msgid " kind file\n"
+msgstr " tipe lêer\n"
+
+msgid "'history' option is zero"
+msgstr "'history' opsie is nul"
+
+#, c-format
+msgid ""
+"\n"
+"# %s History (newest to oldest):\n"
+msgstr ""
+"\n"
+"# %s Geskiedenis (van nuutste na oudste):\n"
+
+msgid "Command Line"
+msgstr "Bevelreël"
+
+msgid "Search String"
+msgstr "Soekstring"
+
+msgid "Expression"
+msgstr "Uitdrukking"
+
+msgid "Input Line"
+msgstr "Invoer Lyn"
+
+msgid "E198: cmd_pchar beyond the command length"
+msgstr "E198: 'cmd_pchar' verby die einde van opdraglengte"
+
+msgid "E199: Active window or buffer deleted"
+msgstr "E199: Aktiewe venster of buffer geskrap"
+
+msgid "Illegal file name"
+msgstr "Ongeldige lêernaam"
+
+msgid "is a directory"
+msgstr "is 'n gids"
+
+msgid "is not a file"
+msgstr "is nie 'n lêer nie"
+
+msgid "[New File]"
+msgstr "[Nuwe lêer]"
+
+msgid "[Permission Denied]"
+msgstr "[Toestemming Geweier]"
+
+msgid "E200: *ReadPre autocommands made the file unreadable"
+msgstr "E200: '*ReadPre' outobevele het die lêer onleesbaar gemaak"
+
+msgid "E201: *ReadPre autocommands must not change current buffer"
+msgstr "E201: '*ReadPre' outobevele mag nie die huidige buffer verander nie"
+
+msgid "Vim: Reading from stdin...\n"
+msgstr "Vim: Lees nou vanaf 'stdin'...\n"
+
+msgid "Reading from stdin..."
+msgstr "Lees nou vanaf stdin... "
+
+#. Re-opening the original file failed!
+msgid "E202: Conversion made file unreadable!"
+msgstr "E202: Omsetting het lêer onleesbaar gemaak!"
+
+msgid "[fifo/socket]"
+msgstr "[fifo/socket]"
+
+msgid "[fifo]"
+msgstr "[fifo]"
+
+msgid "[socket]"
+msgstr "[socket]"
+
+msgid "[RO]"
+msgstr "[RO]"
+
+msgid "[CR missing]"
+msgstr "[CR ontbreek]"
+
+msgid "[NL found]"
+msgstr "[NL gevind]"
+
+msgid "[long lines split]"
+msgstr "[lang reëls verdeel]"
+
+msgid "[NOT converted]"
+msgstr "[NIE omgesit nie]"
+
+msgid "[converted]"
+msgstr "[omgesit]"
+
+msgid "[crypted]"
+msgstr "[gekodeer]"
+
+msgid "[CONVERSION ERROR]"
+msgstr "[OMSETTINGSFOUT]"
+
+#, c-format
+msgid "[ILLEGAL BYTE in line %ld]"
+msgstr "[ONWETTIGE GREEP in reël %ld]"
+
+msgid "[READ ERRORS]"
+msgstr "[LEESFOUTE]"
+
+msgid "Can't find temp file for conversion"
+msgstr "Kan nie tydelike lêer vir omsetting vind nie"
+
+msgid "Conversion with 'charconvert' failed"
+msgstr "Omsetting met 'charconvert' het gefaal"
+
+msgid "can't read output of 'charconvert'"
+msgstr "kan afvoer van 'charconvert' nie lees nie"
+
+msgid "E203: Autocommands deleted or unloaded buffer to be written"
+msgstr "E203: Outobevele het die skryfbuffer geskrap of uitgelaai"
+
+msgid "E204: Autocommand changed number of lines in unexpected way"
+msgstr "E204: Outobevel het etlike reëls op onverwagse wyse verander "
+
+msgid "NetBeans disallows writes of unmodified buffers"
+msgstr "NetBeans laat nie skryf toe van onveranderde buffers nie"
+
+msgid "Partial writes disallowed for NetBeans buffers"
+msgstr "Gedeeltelike skryf word nie toegelaat vir NetBeans buffers nie"
+
+msgid "is not a file or writable device"
+msgstr "is nie 'n lêer of 'n skryfbare toestel nie"
+
+msgid "is read-only (add ! to override)"
+msgstr "is lees-alleen (gebruik ! om te dwing)"
+
+msgid "E506: Can't write to backup file (add ! to override)"
+msgstr "E506: Kan nie na rugsteunlêer skryf nie (gebruik ! om te dwing)"
+
+msgid "E507: Close error for backup file (add ! to override)"
+msgstr "E507: Sluitfout vir rugsteunlêer (gebruik ! om te dwing)"
+
+msgid "E508: Can't read file for backup (add ! to override)"
+msgstr "E508: Kan rugsteunlêer nie lees nie (gebruik ! om te dwing)"
+
+msgid "E509: Cannot create backup file (add ! to override)"
+msgstr "E509: Kan rugsteunlêer nie skep nie (gebruik ! om te dwing)"
+
+msgid "E510: Can't make backup file (add ! to override)"
+msgstr "E510: Kan rugsteunlêer nie skep nie (gebruik ! om te dwing)"
+
+msgid "E460: The resource fork would be lost (add ! to override)"
+msgstr "E460: Die hulpbronvurk sal verlore gaan (gebruik ! om te dwing)"
+
+msgid "E214: Can't find temp file for writing"
+msgstr "E214: Kan nie tydelike lêer vind vir skryf nie"
+
+msgid "E213: Cannot convert (add ! to write without conversion)"
+msgstr "E213: Kan nie omsit nie (gebruik ! om te skryf sonder omsetting)"
+
+msgid "E166: Can't open linked file for writing"
+msgstr "E166: Kan lêer nie oopmaak vir skryf nie"
+
+msgid "E212: Can't open file for writing"
+msgstr "E212: Kan lêer nie oopmaak vir skryf nie"
+
+msgid "E667: Fsync failed"
+msgstr "E667: 'Fsync' het gefaal"
+
+msgid "E512: Close failed"
+msgstr "E512: Sluiting gefaal"
+
+msgid "E513: write error, conversion failed"
+msgstr "E513: skryffout, omsetting gefaal"
+
+msgid "E514: write error (file system full?)"
+msgstr "E514: skryffout (lêerstelsel vol?)"
+
+msgid " CONVERSION ERROR"
+msgstr " OMSETTINGSFOUT"
+
+msgid "[Device]"
+msgstr "[Toestel]"
+
+msgid "[New]"
+msgstr "[Nuut]"
+
+msgid " [a]"
+msgstr " [a]"
+
+msgid " appended"
+msgstr " bygevoeg"
+
+msgid " [w]"
+msgstr " [w]"
+
+msgid " written"
+msgstr " geskryf"
+
+msgid "E205: Patchmode: can't save original file"
+msgstr "E205: patchmode: kan oorspronklike lêer nie stoor nie"
+
+msgid "E206: patchmode: can't touch empty original file"
+msgstr "E206: patchmode: kan leë oorspronglêer nie 'touch' nie"
+
+msgid "E207: Can't delete backup file"
+msgstr "E207: Kan rugsteunlêer nie verwyder nie"
+
+msgid ""
+"\n"
+"WARNING: Original file may be lost or damaged\n"
+msgstr ""
+"\n"
+"WAARSKUWING: Oorspronklike lêer mag verlore of beskadig wees\n"
+
+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!"
+
+msgid "[dos]"
+msgstr "[dos]"
+
+msgid "[dos format]"
+msgstr "[dos formaat]"
+
+msgid "[mac]"
+msgstr "[mac]"
+
+msgid "[mac format]"
+msgstr "[mac formaat]"
+
+msgid "[unix]"
+msgstr "[unix]"
+
+msgid "[unix format]"
+msgstr "[unix formaat]"
+
+msgid "1 line, "
+msgstr "1 reël, "
+
+#, c-format
+msgid "%ld lines, "
+msgstr "%ld reëls, "
+
+msgid "1 character"
+msgstr "1 karakter"
+
+#, c-format
+msgid "%ld characters"
+msgstr "%ld karakters"
+
+msgid "[noeol]"
+msgstr "[noeol]"
+
+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
+msgid "WARNING: The file has been changed since reading it!!!"
+msgstr "WAARSKUWING: Die lêer het verander sedert dit gelees is!!!"
+
+msgid "Do you really want to write to it"
+msgstr "Wil jy regtig soontoe skryf?"
+
+#, c-format
+msgid "E208: Error writing to \"%s\""
+msgstr "E208: Kan nie skryf na \"%s\""
+
+#, c-format
+msgid "E209: Error closing \"%s\""
+msgstr "E209: Kan \"%s\" nie sluit nie"
+
+#, c-format
+msgid "E210: Error reading \"%s\""
+msgstr "E210: Kan \"%s\" nie lees nie"
+
+msgid "E246: FileChangedShell autocommand deleted buffer"
+msgstr "E246: 'FileChangedShell' outobevel het buffer verwyder"
+
+#, c-format
+msgid "E211: Warning: File \"%s\" no longer available"
+msgstr "E211: Waarskuwing: Lêer \"%s\" is nie meer beskikbaar nie"
+
+#, c-format
+msgid ""
+"W12: Warning: File \"%s\" has changed and the buffer was changed in Vim as "
+"well"
+msgstr ""
+"W12: Waarskuwing: Lêer \"%s\" het verander sedert bewerking begin het en die "
+"buffer in Vim het ook verander"
+
+#, c-format
+msgid "W11: Warning: File \"%s\" has changed since editing started"
+msgstr "W11: Waarskuwing: Lêer \"%s\" het verander sedert bewerking begin het"
+
+#, 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"
+
+#, 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"
+
+msgid "See \":help W11\" for more info."
+msgstr "Sien \":help W11\" vir meer inligting."
+
+msgid "Warning"
+msgstr "Waarskuwing"
+
+msgid ""
+"&OK\n"
+"&Load File"
+msgstr ""
+"&OK\n"
+"&Laai Lêer"
+
+msgid "E462: Could not prepare for reloading \"%s\""
+msgstr "E462: Kon nie voorberei vir herlaai nie \"%s\""
+
+#, c-format
+msgid "E321: Could not reload \"%s\""
+msgstr "E321: Kon nie \"%s\" herlaai nie"
+
+msgid "--Deleted--"
+msgstr "--Geskrap--"
+
+#. the group doesn't exist
+#, c-format
+msgid "E367: No such group: \"%s\""
+msgstr "E367: Geen sodanige groep nie: \"%s\""
+
+#, c-format
+msgid "E215: Illegal character after *: %s"
+msgstr "E215: Ongeldige karakter na *: %s"
+
+#, c-format
+msgid "E216: No such event: %s"
+msgstr "E216: Geen sodanige gebeurtenis nie: %s"
+
+msgid "E216: No such group or event: %s"
+msgstr "E216: Geen sodanige groep of gebeurtenis nie: %s"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Auto-Commands ---"
+msgstr ""
+"\n"
+"--- Outobevele ---"
+
+msgid "E217: Can't execute autocommands for ALL events"
+msgstr "E217: Kan nie outobevele uitvoer vir 'ALL' gebeurtenisse nie"
+
+msgid "No matching autocommands"
+msgstr "Geen passende outobevele nie"
+
+msgid "E218: autocommand nesting too deep"
+msgstr "E218: outobevele te diep genes"
+
+#, c-format
+msgid "%s Auto commands for \"%s\""
+msgstr "%s outobevele vir \"%s\""
+
+#, c-format
+msgid "Executing %s"
+msgstr "Voer %s uit"
+
+#. always scroll up, don't overwrite
+#, c-format
+msgid "autocommand %s"
+msgstr "outobevel %s"
+
+msgid "E219: Missing {."
+msgstr "E219: Ontbrekende {."
+
+msgid "E220: Missing }."
+msgstr "E220: Ontbrekende }."
+
+msgid "E490: No fold found"
+msgstr "E490: Geen vou gevind nie"
+
+msgid "E350: Cannot create fold with current 'foldmethod'"
+msgstr "E350: Kan nie vou skep met huidige 'foldmethod' nie"
+
+msgid "E351: Cannot delete fold with current 'foldmethod'"
+msgstr "E351: Kan nie vou skrap met huidige 'foldmethod' nie"
+
+msgid "E222: Add to read buffer"
+msgstr "E222: Voeg by leesbuffer"
+
+msgid "E223: recursive mapping"
+msgstr "E223: rekursiewe binding"
+
+#, c-format
+msgid "E224: global abbreviation already exists for %s"
+msgstr "E224: globale afkorting bestaan alreeds vir %s"
+
+#, c-format
+msgid "E225: global mapping already exists for %s"
+msgstr "E225: globale binding bestaan alreeds vir %s"
+
+#, c-format
+msgid "E226: abbreviation already exists for %s"
+msgstr "E226: afkorting bestaan already vir %s"
+
+#, c-format
+msgid "E227: mapping already exists for %s"
+msgstr "E227: binding bestaan alreeds vir %s"
+
+msgid "No abbreviation found"
+msgstr "Geen afkorting gevind nie"
+
+msgid "No mapping found"
+msgstr "Geen binding gevind nie"
+
+msgid "E228: makemap: Illegal mode"
+msgstr "E228: makemap: Ongeldige modus"
+
+msgid "<cannot open> "
+msgstr "<kan nie oopmaak nie> "
+
+msgid "E616: vim_SelFile: can't get font %s"
+msgstr "E616: 'vim_SelFile': kan font %s nie kry nie"
+
+msgid "E614: vim_SelFile: can't return to current directory"
+msgstr "E614: 'vim_SelFile': Kan nie terugkeer na huidige gids nie"
+
+msgid "Pathname:"
+msgstr "Gidsnaam:"
+
+msgid "E615: vim_SelFile: can't get current directory"
+msgstr "E615: vim_SelFile: Kan nie huidige gids verkry nie"
+
+msgid "OK"
+msgstr "OK"
+
+msgid "Cancel"
+msgstr "Kanselleer"
+
+msgid "Vim dialog"
+msgstr "Vim dialooghokkie"
+
+msgid "Scrollbar Widget: Could not get geometry of thumb pixmap."
+msgstr "Rolstaafelement: Kon nie pikselmatriks-duimnael se geometrie kry nie"
+
+msgid "E232: Cannot create BalloonEval with both message and callback"
+msgstr "E232: Kan nie BalloonEval skep met beide boodskap en terugroep nie"
+
+msgid "E229: Cannot start the GUI"
+msgstr "E229: Kan nie die GUI begin nie"
+
+#, c-format
+msgid "E230: Cannot read from \"%s\""
+msgstr "E230: Kan nie lees uit \"%s\" nie"
+
+msgid "E665: Cannot start GUI, no valid font found"
+msgstr "E665: Kan nie GUI begin nie, geen geldige font gevind nie"
+
+msgid "E231: 'guifontwide' invalid"
+msgstr "E231: 'guifontwide' ongeldig"
+
+msgid "E599: Value of 'imactivatekey' is invalid"
+msgstr "E599: Waarde van 'imactivatekey' is ongeldig"
+
+#, c-format
+msgid "E254: Cannot allocate color %s"
+msgstr "E254: Kan nie kleur %s toeken nie"
+
+msgid "Vim dialog..."
+msgstr "Vim dialooghokkie..."
+
+msgid ""
+"&Yes\n"
+"&No\n"
+"&Cancel"
+msgstr ""
+"&Ja\n"
+"&Nee\n"
+"&Kanselleer"
+
+msgid "Input _Methods"
+msgstr "Invoer _Metodes"
+
+msgid "VIM - Search and Replace..."
+msgstr "VIM - Soek en Vervang..."
+
+msgid "VIM - Search..."
+msgstr "VIM - Soek..."
+
+msgid "Find what:"
+msgstr "Soek na:"
+
+msgid "Replace with:"
+msgstr "Vervang met:"
+
+#. whole word only button
+msgid "Match whole word only"
+msgstr "Tref slegs presiese woord"
+
+#. match case button
+msgid "Match case"
+msgstr "Tref kas"
+
+msgid "Direction"
+msgstr "Rigting"
+
+#. 'Up' and 'Down' buttons
+msgid "Up"
+msgstr "Op"
+
+msgid "Down"
+msgstr "Af"
+
+msgid "Find Next"
+msgstr "Vind volgende"
+
+msgid "Replace"
+msgstr "Vervang"
+
+msgid "Replace All"
+msgstr "Vervang alles"
+
+msgid "Vim: Received \"die\" request from session manager\n"
+msgstr "Vim: Het die \"die\" opdrag ontvang van sessiebestuurder\n"
+
+msgid "Vim: Main window unexpectedly destroyed\n"
+msgstr "Vim: Hoofvenster onverwags verwoes\n"
+
+msgid "Font Selection"
+msgstr "Fontkeuse"
+
+msgid "Used CUT_BUFFER0 instead of empty selection"
+msgstr "'CUT_BUFFER0' is gebruik in plaas van leë seleksie"
+
+msgid "Filter"
+msgstr "Filter"
+
+msgid "Directories"
+msgstr "Gidse"
+
+msgid "Help"
+msgstr "Hulp"
+
+msgid "Files"
+msgstr "Lêers"
+
+msgid "Selection"
+msgstr "Seleksie"
+
+msgid "Undo"
+msgstr "Herroep"
+
+msgid "E671: Cannot find window title \"%s\""
+msgstr "E671: Kan nie venster titel vind nie \"%s\""
+
+#, c-format
+msgid "E243: Argument not supported: \"-%s\"; Use the OLE version."
+msgstr "E243: Parameter nie bekend: \"-%s\"; Gebruik die OLE weergawe."
+
+msgid "E672: Unable to open window inside MDI application"
+msgstr "E672: Kon nie venster oopmaak binne 'n MDI toepassing nie"
+
+msgid "Find string (use '\\\\' to find a '\\')"
+msgstr "Vind string (gebruik '\\\\' om 'n '\\' te vind"
+
+msgid "Find & Replace (use '\\\\' to find a '\\')"
+msgstr "Vind & vervang string (gebruik '\\\\' om 'n '\\' te vind"
+
+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"
+
+#, c-format
+msgid "E250: Fonts for the following charsets are missing in fontset %s:"
+msgstr ""
+"E250: Fonte vir die volgende karakterstelle ontbreek in fontversameling %s:"
+
+#, c-format
+msgid "E252: Fontset name: %s"
+msgstr "E252: Fontstel naam: %s"
+
+#, c-format
+msgid "Font '%s' is not fixed-width"
+msgstr "Font '%s' is nie 'n vaste-wydte font nie"
+
+#, c-format
+msgid "E253: Fontset name: %s\n"
+msgstr "E253: Fonstel naam: %s\n"
+
+#, c-format
+msgid "Font0: %s\n"
+msgstr "Font0: %s\n"
+
+#, c-format
+msgid "Font1: %s\n"
+msgstr "Font1: %s\n"
+
+msgid "Font%ld width is not twice that of font0\n"
+msgstr "Font%ld wydte is nie twee keer díe van font0 nie\n"
+
+#, c-format
+msgid "Font0 width: %ld\n"
+msgstr "Font0 wydte: %ld\n"
+
+#, c-format
+msgid ""
+"Font1 width: %ld\n"
+"\n"
+msgstr ""
+"Font1 wydte: %ld\n"
+"\n"
+
+msgid "E256: Hangul automata ERROR"
+msgstr "E256: Hangul outomatiserings FOUT"
+
+msgid "Add a new database"
+msgstr "Voeg 'n nuwe databasis by"
+
+msgid "Query for a pattern"
+msgstr "Soek vir 'n patroon"
+
+msgid "Show this message"
+msgstr "Wys hierdie boodskap"
+
+msgid "Kill a connection"
+msgstr "Sluit 'n verbinding"
+
+msgid "Reinit all connections"
+msgstr "Herstel alle verbindings"
+
+msgid "Show connections"
+msgstr "Wys verbindings"
+
+msgid "E560: Usage: cs[cope] %s"
+msgstr "E560: Gebruik: cs[cope] %s"
+
+msgid "This cscope command does not support splitting the window.\n"
+msgstr ""
+"Hierdie 'cscope' bevel ondersteun nie die splitsing van die venster nie.\n"
+
+msgid "E562: Usage: cstag <ident>"
+msgstr "E562: Gebruik: 'cstag <ident>'"
+
+msgid "E257: cstag: tag not found"
+msgstr "E257: 'cstag': etiket nie gevind nie"
+
+msgid "E563: stat(%s) error: %d"
+msgstr "E563: 'stat(%s)' fout: %d"
+
+msgid "E563: stat error"
+msgstr "E563: 'stat' fout"
+
+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"
+
+#, c-format
+msgid "Added cscope database %s"
+msgstr "'cscope' databasis %s bygevoeg"
+
+msgid "E262: error reading cscope connection %ld"
+msgstr "E262: 'cscope' verbinding %ld kon nie gelees word nie"
+
+msgid "E561: unknown cscope search type"
+msgstr "E561: onbekende 'cscope' soektipe"
+
+msgid "E566: Could not create cscope pipes"
+msgstr "E566: Kon nie 'cscope' pype skep nie"
+
+msgid "E622: Could not fork for cscope"
+msgstr "E622: Kon nie vurk vir 'cscope' nie"
+
+msgid "cs_create_connection exec failed"
+msgstr "'cs_create_connection' uitvoering het misluk"
+
+msgid "E623: Could not spawn cscope process"
+msgstr "E623: Kon nie 'cscope' proses skep nie"
+
+msgid "cs_create_connection: fdopen for to_fp failed"
+msgstr "'cs_create_connection': 'fdopen' vir 'to_fp' het misluk"
+
+msgid "cs_create_connection: fdopen for fr_fp failed"
+msgstr "'cs_create_connection': 'fdopen' vir 'fr_fp' het misluk"
+
+msgid "E567: no cscope connections"
+msgstr "E567: geen 'cscope' verbindings nie"
+
+#, 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"
+
+#, c-format
+msgid "E469: invalid cscopequickfix flag %c for %c"
+msgstr "E469: ongeldige 'cscopequickfix' vlag %c vir %c"
+
+msgid "cscope commands:\n"
+msgstr "'cscope' bevele:\n"
+
+msgid "%-5s: %-30s (Usage: %s)"
+msgstr "%-5s: %-30s: (Gebruik: %s)"
+
+msgid "E625: cannot open cscope database: %s"
+msgstr "E625: Kon nie 'cscope' databasis oopmaak nie: %s"
+
+msgid "E626: cannot get cscope database information"
+msgstr "E626: kan nie 'cscope' databasisinligting kry nie"
+
+msgid "E568: duplicate cscope database not added"
+msgstr "E568: duplikaat 'cscope' databasis nie bygevoeg nie"
+
+msgid "E569: maximum number of cscope connections reached"
+msgstr "E569: maksimum aantal 'cscope' verbindings bereik"
+
+#, c-format
+msgid "E261: cscope connection %s not found"
+msgstr "E261: 'cscope' verbinding %s nie gevind nie"
+
+msgid "cscope connection %s closed"
+msgstr "'cscope' verbinding %s gesluit"
+
+#. should not reach here
+msgid "E570: fatal error in cs_manage_matches"
+msgstr "E570: fatale fout in 'cs_manage_matches'"
+
+msgid "Cscope tag: %s"
+msgstr "Cscope etiket: %s"
+
+msgid ""
+"\n"
+" # line"
+msgstr ""
+"\n"
+" # reël"
+
+msgid "filename / context / line\n"
+msgstr "lêernaam / konteks / reël\n"
+
+msgid "E609: Cscope error: %s"
+msgstr "E609: Cscope fout: %s"
+
+msgid "All cscope databases reset"
+msgstr "Alle 'cscope' databasisse herstel"
+
+msgid "no cscope connections\n"
+msgstr "geen 'cscope' verbindings nie\n"
+
+msgid " # pid database name prepend path\n"
+msgstr " # pid databasis naam gidsvoorvoegsel\n"
+
+msgid ""
+"E263: Sorry, this command is disabled, the Python library could not be "
+"loaded."
+msgstr ""
+"E263: Jammer, hierdie bevel is afgeskakel, die Python biblioteek lêer kon "
+"nie gelaai word nie."
+
+msgid "E659: Cannot invoke Python recursively"
+msgstr "E659: Kan nie Python rekursief roep nie"
+
+msgid "can't delete OutputObject attributes"
+msgstr "kan nie 'OutputObject' eienskappe skrap nie"
+
+msgid "softspace must be an integer"
+msgstr "'softspace' moet 'n heelgetal wees"
+
+msgid "invalid attribute"
+msgstr "ongeldige eienskap"
+
+msgid "writelines() requires list of strings"
+msgstr "'writelines()' benodig 'n lys van stringe"
+
+msgid "E264: Python: Error initialising I/O objects"
+msgstr "E264: Python: Kon nie I/O objekte inwy nie"
+
+# njj: net 'n voorstel ..
+msgid "invalid expression"
+msgstr "ongeldige uitdrukking"
+
+msgid "expressions disabled at compile time"
+msgstr "uitdrukkings afgeskakel tydens kompilering"
+
+msgid "attempt to refer to deleted buffer"
+msgstr "poging om na 'n geskrapte buffer te verwys"
+
+msgid "line number out of range"
+msgstr "reëlnommer buite omvang"
+
+#, c-format
+msgid "<buffer object (deleted) at %8lX>"
+msgstr "<buffervoorwerp (geskrap) by %8lX>"
+
+msgid "invalid mark name"
+msgstr "onbekende merknaam"
+
+msgid "no such buffer"
+msgstr "buffer bestaan nie"
+
+msgid "attempt to refer to deleted window"
+msgstr "poging om na geskrapte venster te verwys"
+
+msgid "readonly attribute"
+msgstr "leesalleen eienskap"
+
+msgid "cursor position outside buffer"
+msgstr "loperposisie buite buffer"
+
+#, c-format
+msgid "<window object (deleted) at %.8lX>"
+msgstr "<venster voorwerp (geskrap) by %.8lX>"
+
+#, c-format
+msgid "<window object (unknown) at %.8lX>"
+msgstr "<verwyder voorwerp (onbekend) by %.8lX>"
+
+#, c-format
+msgid "<window %d>"
+msgstr "<venster %d>"
+
+msgid "no such window"
+msgstr "geen sodanige venster nie"
+
+msgid "cannot save undo information"
+msgstr "kan nie herwin-inligting stoor nie"
+
+msgid "cannot delete line"
+msgstr "kan reël nie verwyder nie"
+
+msgid "cannot replace line"
+msgstr "kan reël nie vervang nie"
+
+msgid "cannot insert line"
+msgstr "kan reël nie byvoeg nie"
+
+msgid "string cannot contain newlines"
+msgstr "string kan nie 'newlines' bevat nie"
+
+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."
+
+#, c-format
+msgid "E273: unknown longjmp status %d"
+msgstr "E273: Onbekende 'longjmp' status %d"
+
+msgid "Toggle implementation/definition"
+msgstr "Stel en herstel implimentasie/definisie"
+
+msgid "Show base class of"
+msgstr "Wys basisklas van"
+
+msgid "Show overridden member function"
+msgstr "Wys vervangde lidfunksie"
+
+msgid "Retrieve from file"
+msgstr "Gaan haal uit lêer"
+
+msgid "Retrieve from project"
+msgstr "Gaan haal uit projek"
+
+msgid "Retrieve from all projects"
+msgstr "Gaan haal uit alle projekte"
+
+msgid "Retrieve"
+msgstr "Gaan haal"
+
+msgid "Show source of"
+msgstr "Wys kode van"
+
+msgid "Find symbol"
+msgstr "Vind simbool"
+
+msgid "Browse class"
+msgstr "Kyk klas deur"
+
+msgid "Show class in hierarchy"
+msgstr "Wys klas in hiërargie"
+
+msgid "Show class in restricted hierarchy"
+msgstr "Wys klas in beperkte hiërargie"
+
+msgid "Xref refers to"
+msgstr "Xref verwys na"
+
+msgid "Xref referred by"
+msgstr "Xref verwys deur"
+
+msgid "Xref has a"
+msgstr "Xref het 'n"
+
+msgid "Xref used by"
+msgstr "Xref gebruik deur"
+
+msgid "Show docu of"
+msgstr "Wys 'docu' van"
+
+msgid "Generate docu for"
+msgstr "Genereer 'docu' vir"
+
+msgid ""
+"Cannot connect to SNiFF+. Check environment (sniffemacs must be found in "
+"$PATH).\n"
+msgstr ""
+"Kan nie 'n verbinding met 'SNiFF+' maak nie. Kyk of die omgewing reg is "
+"('sniffemacs' moet in '$PATH' gevind word).\n"
+
+msgid "E274: Sniff: Error during read. Disconnected"
+msgstr "E274: Sniff: Fout gedurende lees. Verbinding gebreek"
+
+msgid "SNiFF+ is currently "
+msgstr "SNiFF+ is tans"
+
+msgid "not "
+msgstr "nie "
+
+msgid "connected"
+msgstr "gekonnekteer"
+
+#, c-format
+msgid "E275: Unknown SNiFF+ request: %s"
+msgstr "E275: Onbekende SNiFF+ versoek: %s"
+
+msgid "E276: Error connecting to SNiFF+"
+msgstr "E276: Fout in konnekteer met SNiFF+"
+
+msgid "E278: SNiFF+ not connected"
+msgstr "E278: SNiFF+ is nie gekonnekteer nie"
+
+msgid "E279: Not a SNiFF+ buffer"
+msgstr "E279: Nie 'n SNiFF+ buffer nie"
+
+msgid "Sniff: Error during write. Disconnected"
+msgstr "Sniff: Fout gedurende stoor. Verbinding gebreek"
+
+msgid "invalid buffer number"
+msgstr "ongeldige buffernommer"
+
+msgid "not implemented yet"
+msgstr "nog nie geïmplementeer nie"
+
+msgid "unknown option"
+msgstr "onbekende opsie"
+
+#. ???
+msgid "cannot set line(s)"
+msgstr "kan nie reël(s) stel nie"
+
+msgid "mark not set"
+msgstr "merker nie gestel nie"
+
+#, c-format
+msgid "row %d column %d"
+msgstr "ry %d kolom %d"
+
+msgid "cannot insert/append line"
+msgstr "kan nie reël invoeg/aanlas nie"
+
+msgid "unknown flag: "
+msgstr "onbekende vlag: "
+
+msgid "unknown vimOption"
+msgstr "onbekende 'vimOption'"
+
+msgid "keyboard interrupt"
+msgstr "sleutelbordonderbreking"
+
+msgid "vim error"
+msgstr "vim fout"
+
+msgid "cannot create buffer/window command: object is being deleted"
+msgstr "kan nie buffer/venster bevel skep nie: voorwerp word geskrap"
+
+msgid ""
+"cannot register callback command: buffer/window is already being deleted"
+msgstr ""
+"kan nie terugroepbevel registreer nie: buffer/venster word alreeds geskrap"
+
+#. This should never happen. Famous last word?
+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 "cannot register callback command: buffer/window reference not found"
+msgstr ""
+"kan terugroepbevel nie registreer nie: buffer/vensterverwysing nie gevind nie"
+
+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 ""
+"E281: TCL ERROR: exit code is not int!? Please report this to vim-dev@vim.org"
+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"
+
+msgid "E573: Invalid server id used: %s"
+msgstr "E573: Ongeldige bediener-id gebruik: %s"
+
+msgid "E251: VIM instance registry property is badly formed. Deleted!"
+msgstr "E251: VIM instansie register-kenmerk is swak gevorm. Geskrap!"
+
+msgid "Unknown option"
+msgstr "Onbekende opsie"
+
+msgid "Too many edit arguments"
+msgstr "Te veel redigeer-parameters"
+
+msgid "Argument missing after"
+msgstr "Parameter ontbreek na"
+
+msgid "Garbage after option"
+msgstr "Gemors na opsie"
+
+msgid "Too many \"+command\", \"-c command\" or \"--cmd command\" arguments"
+msgstr "Te veel \"+command\", \"-c command\" of \"--cmd command\" parameters"
+
+msgid "Invalid argument for"
+msgstr "Ongeldige parameter vir"
+
+msgid "This Vim was not compiled with the diff feature."
+msgstr "Hierdie Vim is nie gekompileer met 'diff' funksionaliteit nie."
+
+msgid "Attempt to open script file again: \""
+msgstr "Probeer weer om skriplêer oop te maak: \""
+
+msgid "Cannot open for reading: \""
+msgstr "Kan nie oopmaak om te lees nie: \""
+
+msgid "Cannot open for script output: \""
+msgstr "Kan nie oopmaak vir skrip-afvoer nie: \""
+
+#, c-format
+msgid "%d files to edit\n"
+msgstr "%d lêers om te bewerk\n"
+
+msgid "Vim: Warning: Output is not to a terminal\n"
+msgstr "Vim: Waarskuwing: Afvoer gaan nie na 'n terminaal nie\n"
+
+msgid "Vim: Warning: Input is not from a terminal\n"
+msgstr "Vim: Waarskuwing: Invoer kom nie vanaf 'n terminaal nie\n"
+
+#. just in case..
+msgid "pre-vimrc command line"
+msgstr "vóór-'vimrc' bevelreël"
+
+#, c-format
+msgid "E282: Cannot read from \"%s\""
+msgstr "E282: Kan nie lees uit \"%s\" nie"
+
+msgid ""
+"\n"
+"More info with: \"vim -h\"\n"
+msgstr ""
+"\n"
+"Meer inligting met: \"vim -h\"\n"
+
+msgid "[file ..] edit specified file(s)"
+msgstr "[lêer ..] bewerk lêer(s)"
+
+msgid "- read text from stdin"
+msgstr "- lees teks uit 'stdin'"
+
+msgid "-t tag edit file where tag is defined"
+msgstr "-t tag bewerk lêer waar etiket gedefinieer is"
+
+msgid "-q [errorfile] edit file with first error"
+msgstr "-q [foutlêer] bewerk lêer met eerste fout"
+
+msgid ""
+"\n"
+"\n"
+"usage:"
+msgstr ""
+"\n"
+"\n"
+"gebruik:"
+
+msgid " vim [arguments] "
+msgstr " vim [parameters] "
+
+msgid ""
+"\n"
+" or:"
+msgstr ""
+"\n"
+" of:"
+
+msgid ""
+"\n"
+"\n"
+"Arguments:\n"
+msgstr ""
+"\n"
+"\n"
+"Parameters:\n"
+
+msgid "--\t\t\tOnly file names after this"
+msgstr "--\t\t\tSlegs lêername hierna"
+
+msgid "--literal\t\tDon't expand wildcards"
+msgstr "--literal\t\tMoet nie plekhouers uitbrei nie"
+
+msgid "-register\t\tRegister this gvim for OLE"
+msgstr "-register\t\tRegistreer hierdie gvim vir OLE"
+
+msgid "-unregister\t\tUnregister gvim for OLE"
+msgstr "-unregister\t\tOnregistreer gvim vir OLE"
+
+msgid "-g\t\t\tRun using GUI (like \"gvim\")"
+msgstr "-g\t\t\tVoer uit met die GUI (soos \"gvim\")"
+
+msgid "-f or --nofork\tForeground: Don't fork when starting GUI"
+msgstr "-f of --nofork\tVoorgrond: Moenie vurk wanneer GUI begin nie"
+
+msgid "-v\t\t\tVi mode (like \"vi\")"
+msgstr "-v\t\t\tVi modus (soos \"vi\")"
+
+msgid "-e\t\t\tEx mode (like \"ex\")"
+msgstr "-e\t\t\tEx modus (soos \"ex\")"
+
+msgid "-s\t\t\tSilent (batch) mode (only for \"ex\")"
+msgstr "-s\t\t\tStil (bondel) modus (slegs vir \"ex\")"
+
+msgid "-d\t\t\tDiff mode (like \"vimdiff\")"
+msgstr "-d\t\t\tDiff modus (soos \"vimdiff\")"
+
+msgid "-y\t\t\tEasy mode (like \"evim\", modeless)"
+msgstr "-y\t\t\tEasy modus (soos \"evim\", modusloos)"
+
+msgid "-R\t\t\tReadonly mode (like \"view\")"
+msgstr "-R\t\t\tLeesalleen modus (soos \"view\")"
+
+msgid "-Z\t\t\tRestricted mode (like \"rvim\")"
+msgstr "-Z\t\t\tBeperkte modus (soos \"rvim\")"
+
+msgid "-m\t\t\tModifications (writing files) not allowed"
+msgstr "-m\t\t\tVeranderings (skryf van lêers) nie toegelaat nie"
+
+msgid "-M\t\t\tModifications in text not allowed"
+msgstr "-M\t\t\tVeranderings aan teks nie toegelaat nie"
+
+msgid "-b\t\t\tBinary mode"
+msgstr "-b\t\t\tBinêre modus"
+
+msgid "-l\t\t\tLisp mode"
+msgstr "-l\t\t\tLisp modus"
+
+msgid "-C\t\t\tCompatible with Vi: 'compatible'"
+msgstr "-C\t\t\tVersoenbaar met Vi: 'compatible'"
+
+msgid "-N\t\t\tNot fully Vi compatible: 'nocompatible'"
+msgstr "-N\t\t\tNie ten volle Vi-versoenbaar nie: 'nocompatible'"
+
+msgid "-V[N]\t\tVerbose level"
+msgstr "-V[N]\t\tOmslagtigheidsgraad"
+
+msgid "-D\t\t\tDebugging mode"
+msgstr "-D\t\t\tOntfoutmodus"
+
+msgid "-n\t\t\tNo swap file, use memory only"
+msgstr "-n\t\t\tGeen ruillêer, gebruik slegs geheue"
+
+msgid "-r\t\t\tList swap files and exit"
+msgstr "-r\t\t\tLys ruillêers en verlaat vim"
+
+msgid "-r (with file name)\tRecover crashed session"
+msgstr "-r (met lêer naam)\tHerwin ineengestorte sessie"
+
+msgid "-L\t\t\tSame as -r"
+msgstr "-L\t\t\tSelfde as -r"
+
+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 "-dev <device>\t\tUse <device> for I/O"
+msgstr "-dev <toestel>\t\tGebruik <toestel> vir I/O"
+
+msgid "-A\t\t\tstart in Arabic mode"
+msgstr "-A\t\t\tbegin in Arabiese modus"
+
+msgid "-H\t\t\tStart in Hebrew mode"
+msgstr "-H\t\t\tBegin in Hebreeuse modus"
+
+msgid "-F\t\t\tStart in Farsi mode"
+msgstr "-F\t\t\tBegin in Farsi modus"
+
+msgid "-T <terminal>\tSet terminal type to <terminal>"
+msgstr "-T <terminaal>\tStel terminaaltipe na <terminaal>"
+
+msgid "-u <vimrc>\t\tUse <vimrc> instead of any .vimrc"
+msgstr "-u <vimrc>\t\tGebruik <vimrc> in plaas van enige ander .vimrc"
+
+msgid "-U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc"
+msgstr "-U <gvimrc>\t\tGebruik <gvimrc> in plaas van enige .gvimrc"
+
+msgid "--noplugin\t\tDon't load plugin scripts"
+msgstr "--noplugin\t\tMoet nie inpropskripte laai nie"
+
+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 "-O[N]\t\tLike -o but split vertically"
+msgstr "-O[N]\t\tSoos -o maar verdeel vertikaal"
+
+msgid "+\t\t\tStart at end of file"
+msgstr "+\t\t\tBegin by einde van lêer"
+
+msgid "+<lnum>\t\tStart at line <lnum>"
+msgstr "+<lnum>\t\tBegin by reël <lnum>"
+
+msgid "--cmd <command>\tExecute <command> before loading any vimrc file"
+msgstr "--cmd <bevel>\tVoer <bevel> uit voor enige .vimrc-lêer gelaai word"
+
+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 "-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"
+
+msgid "-s <scriptin>\tRead Normal mode commands from file <scriptin>"
+msgstr "-s <skripin>\t\tLees Normale-modus bevele van lêer <skripin>"
+
+msgid "-w <scriptout>\tAppend all typed commands to file <scriptout>"
+msgstr "-w <skripuit>\tLas alle getikte bevele aan by lêer <skripuit>"
+
+msgid "-W <scriptout>\tWrite all typed commands to file <scriptout>"
+msgstr "-W <skripuit>\tSkryf alle getikte bevele na lêer <skripuit>"
+
+msgid "-x\t\t\tEdit encrypted files"
+msgstr "-x\t\t\tBewerk geënkripteerde lêers"
+
+msgid "-display <display>\tConnect vim to this particular X-server"
+msgstr "-display <display>\tKoppel vim aan hierdie X-bediener"
+
+msgid "-X\t\t\tDo not connect to X server"
+msgstr "-X\t\t\tMoet nie verbinding met X-bediener maak nie"
+
+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 "--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 ""
+"--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 ""
+"--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"
+msgstr ""
+"--remote-send <sleutels>\tStuur <sleutels> na 'n Vim-bediener en verlaat"
+
+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 "--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>"
+
+msgid "-i <viminfo>\t\tUse <viminfo> instead of .viminfo"
+msgstr "-i <viminfo>\t\tGebruik <viminfo> in plaas van .viminfo"
+
+msgid "-h or --help\tPrint Help (this message) and exit"
+msgstr "-h of --help\tSkryf Hulp (hierdie boodskap) en sluit"
+
+msgid "--version\t\tPrint version information and exit"
+msgstr "--version\t\tSkryf weergawe-inligting en sluit"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (Motif version):\n"
+msgstr ""
+"\n"
+"Parameters deur gvim herken (Motif weergawe):\n"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (neXtaw version):\n"
+msgstr ""
+"\n"
+"Parameters deur gvim herken (neXtaw weergawe):\n"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (Athena version):\n"
+msgstr ""
+"\n"
+"Parameters deur gvim herken (Athena weergawe):\n"
+
+msgid "-display <display>\tRun vim on <display>"
+msgstr "-display <display>\tVoer vim op <display> uit"
+
+msgid "-iconic\t\tStart vim iconified"
+msgstr "-iconic\t\tBegin vim as ikoon"
+
+msgid "-name <name>\t\tUse resource as if vim was <name>"
+msgstr "-name <name>\t\tGebruik hulpbron asof vim <name> was"
+
+msgid "\t\t\t (Unimplemented)\n"
+msgstr "\t\t\t (Nog nie geïmplementeer nie)\n"
+
+msgid "-background <color>\tUse <color> for the background (also: -bg)"
+msgstr "-background <kleur>\tGebruik <kleur> vir die agtergrond (ook: -bg)"
+
+msgid "-foreground <color>\tUse <color> for normal text (also: -fg)"
+msgstr "-voorgrond <kleur>\tGebruik <kleur> vir normale teks (ook: -fg)"
+
+msgid "-font <font>\t\tUse <font> for normal text (also: -fn)"
+msgstr "-font <font>\t\tGebruik <font> vir normale teks (ook -fn)"
+
+msgid "-boldfont <font>\tUse <font> for bold text"
+msgstr "­boldfont <font>\t Gebruik <font> vir vetletter teks"
+
+msgid "-italicfont <font>\tUse <font> for italic text"
+msgstr "-italicfont <font>\tGebruik <font> vir kursiewe teks"
+
+msgid "-geometry <geom>\tUse <geom> for initial geometry (also: -geom)"
+msgstr "-geometry <geom>\tGebruik <geom> vir aanvanklike geometrie"
+
+msgid "-borderwidth <width>\tUse a border width of <width> (also: -bw)"
+msgstr "-borderwidth <wydte>\tGebruik 'n grenswydte van <wydte> (ook: -bw)"
+
+msgid "-scrollbarwidth <width> Use a scrollbar width of <width> (also: -sw)"
+msgstr ""
+"-scrollbarwidth <wydte>\tGebruik 'n rolstaafwydte van <wydte> (ook: -sw>"
+
+msgid "-menuheight <height>\tUse a menu bar height of <height> (also: -mh)"
+msgstr ""
+"-menuheight <hoogte>\tGebruik a kieslysstaafhoogte van <hoogte> (ook: -mh)"
+
+msgid "-reverse\t\tUse reverse video (also: -rv)"
+msgstr "-reverse\t\tGebruik tru-video (ook: -rv)"
+
+msgid "+reverse\t\tDon't use reverse video (also: +rv)"
+msgstr "+reverse\t\tMoet nie tru-video gebruik nie (ook: +rv)"
+
+msgid "-xrm <resource>\tSet the specified resource"
+msgstr "-xrm <hulpbron>\tStel die gespesifiseerde hulpbron"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (RISC OS version):\n"
+msgstr ""
+"\n"
+"Parameters wat gvim verstaan (RISC OS weergawe):\n"
+
+msgid "--columns <number>\tInitial width of window in columns"
+msgstr "--columns <aantal>\tAanvanklike wydte van venster in kolomme"
+
+msgid "--rows <number>\tInitial height of window in rows"
+msgstr "--rows <aantal>\tAanvanklike hoogte van venster in rye"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (GTK+ version):\n"
+msgstr ""
+"\n"
+"Parameters wat gvim verstaan (GTK+ weergawe):\n"
+
+msgid "-display <display>\tRun vim on <display> (also: --display)"
+msgstr "-display <skerm>\tVoer vim op <skerm> uit: (ook --display)"
+
+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 "--socketid <xid>\tOpen Vim inside another GTK widget"
+msgstr "--socketid <xid>\tMaak Vim in 'n ander GTK element oop"
+
+msgid "-P <parent title>\tOpen Vim inside parent application"
+msgstr "-P <ouer title>\tMaak Vim oop binne 'n ouer toepassing"
+
+msgid "No display"
+msgstr "Geen vertoonskerm"
+
+#. Failed to send, abort.
+msgid ": Send failed.\n"
+msgstr ": Stuur het gefaal.\n"
+
+#. Let vim start normally.
+msgid ": Send failed. Trying to execute locally\n"
+msgstr ": Stuur het gefaal. Probeer om lokaal uit te voer\n"
+
+#, c-format
+msgid "%d of %d edited"
+msgstr "%d van %d lêers bewerk"
+
+msgid "No display: Send expression failed.\n"
+msgstr "Geen vertoonskerm: Stuur van uitdrukking het gefaal.\n"
+
+msgid ": Send expression failed.\n"
+msgstr ": Stuur van uitdrukking het gefaal.\n"
+
+msgid "No marks set"
+msgstr "Geen merkers gestel nie"
+
+#, c-format
+msgid "E283: No marks matching \"%s\""
+msgstr "E283: Geen merkers pas op \"%s\" nie"
+
+#. Highlight title
+msgid ""
+"\n"
+"mark line col file/text"
+msgstr ""
+"\n"
+"merk reël kol lêer/teks"
+
+#. Highlight title
+msgid ""
+"\n"
+" jump line col file/text"
+msgstr ""
+"\n"
+" spring reël kol lêer/teks"
+
+#. Highlight title
+msgid ""
+"\n"
+"change line col text"
+msgstr ""
+"\n"
+"verander reël kol teks"
+
+#, c-format
+msgid ""
+"\n"
+"# File marks:\n"
+msgstr ""
+"\n"
+"# Lêermerkers:\n"
+
+#. Write the jumplist with -'
+#, c-format
+msgid ""
+"\n"
+"# Jumplist (newest first):\n"
+msgstr ""
+"\n"
+"# Springlys (nuutste eerste):\n"
+
+#, c-format
+msgid ""
+"\n"
+"# History of marks within files (newest to oldest):\n"
+msgstr ""
+"\n"
+"# Geskiedenis van merkers in lêers (nuutste tot oudste):\n"
+
+msgid "Missing '>'"
+msgstr "Ontbrekende '>'"
+
+msgid "E543: Not a valid codepage"
+msgstr "E543: Nie 'n geldige kodeblad nie"
+
+msgid "E284: Cannot set IC values"
+msgstr "E284: Kan nie IC waardes stel nie"
+
+msgid "E285: Failed to create input context"
+msgstr "E285: Gefaal met die skep van invoerkonteks"
+
+msgid "E286: Failed to open input method"
+msgstr "E286: Gefaal om invoermetode oop te maak"
+
+msgid "E287: Warning: Could not set destroy callback to IM"
+msgstr "E287: Waarskuwing: Kon nie uitwis-terugroep na IM stel nie"
+
+msgid "E288: input method doesn't support any style"
+msgstr "E288: invoermetode ondersteun geen styl nie"
+
+msgid "E289: input method doesn't support my preedit type"
+msgstr "E289: invoermetode ondersteun nie my voor-bewerking tipe nie"
+
+msgid "E290: over-the-spot style requires fontset"
+msgstr "E290: oor-die-plek styl vereis fontstel"
+
+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 "E292: Input Method Server is not running"
+msgstr "E292: Invoermetodebediener voer nie uit nie"
+
+msgid "E293: block was not locked"
+msgstr "E293: blok was nie gesluit nie"
+
+msgid "E294: Seek error in swap file read"
+msgstr "E294: Soekfout in lees van ruillêer"
+
+msgid "E295: Read error in swap file"
+msgstr "E295: Leesfout in ruillêer"
+
+msgid "E296: Seek error in swap file write"
+msgstr "E296: Soekfout in skryf van ruillêer"
+
+msgid "E297: Write error in swap file"
+msgstr "E297: Skryffout in ruillêer"
+
+msgid "E300: Swap file already exists (symlink attack?)"
+msgstr "E300: Ruillêer bestaan alreeds! ('symlink' probleem?)"
+
+msgid "E298: Didn't get block nr 0?"
+msgstr "E298: Het nie blok no 0 gekry nie?"
+
+msgid "E298: Didn't get block nr 1?"
+msgstr "E298: Het nie blok no 1 gekry nie?"
+
+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????
+msgid "E301: Oops, lost the swap file!!!"
+msgstr "E301: Hiert, die ruillêer is weg!!!"
+
+msgid "E302: Could not rename swap file"
+msgstr "E302: Kon nie ruillêer vernoem nie"
+
+#, 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"
+
+msgid "E304: ml_timestamp: Didn't get block 0??"
+msgstr "E304: 'ml_timestamp': Het nie blok 0 gekry nie??"
+
+#, c-format
+msgid "E305: No swap file found for %s"
+msgstr "E305: Geen ruillêer gevind vir %s nie"
+
+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)"
+
+#, c-format
+msgid "E306: Cannot open %s"
+msgstr "E306: Kan %s nie oopmaak nie"
+
+msgid "Unable to read block 0 from "
+msgstr "Kan nie blok 0 lees vanaf "
+
+msgid ""
+"\n"
+"Maybe no changes were made or Vim did not update the swap file."
+msgstr ""
+"\n"
+"Vim het die ruillêer nie opgedateer nie. Dalk was niks verander nie."
+
+msgid " cannot be used with this version of Vim.\n"
+msgstr " kan nie gebruik word met hierdie weergawe van Vim nie.\n"
+
+msgid "Use Vim version 3.0.\n"
+msgstr "Gebruik Vim weergawe 3.0.\n"
+
+#, c-format
+msgid "E307: %s does not look like a Vim swap file"
+msgstr "E307: %s lyk nie soos 'n Vim ruillêer nie"
+
+msgid " cannot be used on this computer.\n"
+msgstr " kan nie gebruik word op hierdie rekenaar nie.\n"
+
+msgid "The file was created on "
+msgstr "Die lêer is geskep op "
+
+msgid ""
+",\n"
+"or the file has been damaged."
+msgstr ""
+",\n"
+"of die lêer is beskadig."
+
+#, c-format
+msgid "Using swap file \"%s\""
+msgstr "Gebruik ruillêer \"%s\""
+
+#, c-format
+msgid "Original file \"%s\""
+msgstr "Oorspronklike lêer \"%s\""
+
+msgid "E308: Warning: Original file may have been changed"
+msgstr "E308: Waarskuwing: Oorspronklike lêer is dalk gewysig"
+
+#, c-format
+msgid "E309: Unable to read block 1 from %s"
+msgstr "E309: Kan nie block 1 lees van %s"
+
+msgid "???MANY LINES MISSING"
+msgstr "???BAIE REËLS WEG"
+
+msgid "???LINE COUNT WRONG"
+msgstr "???REËLTELLING FOUTIEF"
+
+msgid "???EMPTY BLOCK"
+msgstr "???LEË BLOK"
+
+msgid "???LINES MISSING"
+msgstr "???REËLS WEG"
+
+#, 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?)"
+
+msgid "???BLOCK MISSING"
+msgstr "???BLOK WEG"
+
+msgid "??? from here until ???END lines may be messed up"
+msgstr "??? van hier tot ???END mag reëls deurmekaar wees"
+
+msgid "??? from here until ???END lines may have been inserted/deleted"
+msgstr "??? van hier tot ???END mag daar reëls ingevoeg/geskrap wees"
+
+msgid "???END"
+msgstr "???END"
+
+msgid "E311: Recovery Interrupted"
+msgstr "E311: Herwinning onderbreek"
+
+msgid ""
+"E312: Errors detected while recovering; look for lines starting with ???"
+msgstr ""
+"E312: Foute raakgesien gedurende herwinning; soek vir reëls wat begin met ???"
+
+msgid "See \":help E312\" for more information."
+msgstr "Sien \":help E312\" vir meer inligting."
+
+msgid "Recovery completed. You should check if everything is OK."
+msgstr "Herwinning is klaar. Kyk of alles reg is."
+
+msgid ""
+"\n"
+"(You might want to write out this file under another name\n"
+msgstr ""
+"\n"
+"(Jy wil dalk die lêer stoor onder 'n ander naam\n"
+
+msgid "and run diff with the original file to check for changes)\n"
+msgstr "en dit \"diff\" teen die oorspronklike lêer om wysigings te soek)\n"
+
+msgid ""
+"Delete the .swp file afterwards.\n"
+"\n"
+msgstr ""
+"Verwyder die .swp-lêer na die tyd.\n"
+"\n"
+
+#. use msg() to start the scrolling properly
+msgid "Swap files found:"
+msgstr "Ruillêers gevind:"
+
+msgid " In current directory:\n"
+msgstr " In huidige gids:\n"
+
+msgid " Using specified name:\n"
+msgstr " Wat gespesifiseerde naam gebruik:\n"
+
+msgid " In directory "
+msgstr " In gids "
+
+msgid " -- none --\n"
+msgstr " -- geen --\n"
+
+msgid " owned by: "
+msgstr " eienaar: "
+
+msgid " dated: "
+msgstr " gedateer: "
+
+msgid " dated: "
+msgstr " gedateer: "
+
+msgid " [from Vim version 3.0]"
+msgstr " [van Vim weergawe 3.0]"
+
+msgid " [does not look like a Vim swap file]"
+msgstr " [lyk nie soos 'n Vim ruillêer nie]"
+
+msgid " file name: "
+msgstr " lêernaam: "
+
+msgid ""
+"\n"
+" modified: "
+msgstr ""
+"\n"
+" gewysig: "
+
+msgid "YES"
+msgstr "JA"
+
+msgid "no"
+msgstr "nee"
+
+msgid ""
+"\n"
+" user name: "
+msgstr ""
+"\n"
+" gebruikersnaam: "
+
+msgid " host name: "
+msgstr " gasheernaam: "
+
+msgid ""
+"\n"
+" host name: "
+msgstr ""
+"\n"
+" gasheernaam: "
+
+msgid ""
+"\n"
+" process ID: "
+msgstr ""
+"\n"
+" proses ID: "
+
+msgid " (still running)"
+msgstr " (nog steeds aan die uitvoer)"
+
+msgid ""
+"\n"
+" [not usable with this version of Vim]"
+msgstr ""
+"\n"
+" [nie bruikbaar met hierdie weergawe van Vim nie]"
+
+msgid ""
+"\n"
+" [not usable on this computer]"
+msgstr ""
+"\n"
+" [nie bruikbaar op hierdie rekenaar nie]"
+
+msgid " [cannot be read]"
+msgstr " [kan nie gelees word nie]"
+
+msgid " [cannot be opened]"
+msgstr " [kan nie oopgemaak word nie]"
+
+msgid "E313: Cannot preserve, there is no swap file"
+msgstr "E313: Kan nie bewaar nie, daar is geen ruillêer nie"
+
+msgid "File preserved"
+msgstr "Lêer bewaar"
+
+msgid "E314: Preserve failed"
+msgstr "E314: Kon nie bewaar nie"
+
+#, c-format
+msgid "E315: ml_get: invalid lnum: %ld"
+msgstr "E315: 'ml_get': ongeldige 'lnum': %ld"
+
+#, c-format
+msgid "E316: ml_get: cannot find line %ld"
+msgstr "E316: 'ml_get': kan reël %ld nie vind nie"
+
+msgid "E317: pointer block id wrong 3"
+msgstr "E317: wyser blok id verkeerd 3"
+
+msgid "stack_idx should be 0"
+msgstr "'stack_idx' moet 0 wees"
+
+msgid "E318: Updated too many blocks?"
+msgstr "E318: Te veel blokke opgedateer?"
+
+msgid "E317: pointer block id wrong 4"
+msgstr "E317: wyser blok id verkeerd 4"
+
+msgid "deleted block 1?"
+msgstr "verwyder blok 1?"
+
+#, c-format
+msgid "E320: Cannot find line %ld"
+msgstr "E320: Kan nie reël %ld vind nie"
+
+msgid "E317: pointer block id wrong"
+msgstr "E317: wyser blok id verkeerd"
+
+msgid "pe_line_count is zero"
+msgstr "'pe_line_count' is nul"
+
+#, c-format
+msgid "E322: line number out of range: %ld past the end"
+msgstr "E322: reëlnommer buite perke: %ld verby die einde"
+
+#, c-format
+msgid "E323: line count wrong in block %ld"
+msgstr "E323: reëltelling mag verkeerd wees in blok %ld"
+
+msgid "Stack size increases"
+msgstr "Stapel grootte verhoog"
+
+msgid "E317: pointer block id wrong 2"
+msgstr "E317: wyser blok id verkeerd 2"
+
+msgid "E325: ATTENTION"
+msgstr "E325: LET OP"
+
+msgid ""
+"\n"
+"Found a swap file by the name \""
+msgstr ""
+"\n"
+"Het 'n ruillêer gevind met die naam \""
+
+msgid "While opening file \""
+msgstr "Tydens oopmaak van lêer \""
+
+msgid " NEWER than swap file!\n"
+msgstr " NUWER as die ruillêer!\n"
+
+#. Some of these messages are long to allow translation to
+#. * other languages.
+msgid ""
+"\n"
+"(1) Another program may be editing the same file.\n"
+" If this is the case, be careful not to end up with two\n"
+" different instances of the same file when making changes.\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"
+
+msgid " Quit, or continue with caution.\n"
+msgstr " Stop, of gaan versigtig voort.\n"
+
+msgid ""
+"\n"
+"(2) An edit session for this file crashed.\n"
+msgstr ""
+"\n"
+"(2) 'n Bewerkingsessie van hierdie lêer het ineengestort.\n"
+
+msgid " If this is the case, use \":recover\" or \"vim -r "
+msgstr " Indien wel, gebruik \":recover\" of \"vim -r"
+
+msgid ""
+"\"\n"
+" to recover the changes (see \":help recovery\").\n"
+msgstr ""
+"\"\n"
+" om die veranderinge te herwin (sien \":help recovery\").\n"
+
+msgid " If you did this already, delete the swap file \""
+msgstr " Indien jy dit alreeds gedoen het, verwyder die ruillêer \""
+
+msgid ""
+"\"\n"
+" to avoid this message.\n"
+msgstr ""
+"\"\n"
+" om hierdie boodskap te vermy.\n"
+
+msgid "Swap file \""
+msgstr "Ruillêer \""
+
+msgid "\" already exists!"
+msgstr "\" bestaan alreeds!"
+
+msgid "VIM - ATTENTION"
+msgstr "VIM - LET OP"
+
+msgid "Swap file already exists!"
+msgstr "Ruillêer bestaan alreeds!"
+
+msgid ""
+"&Open Read-Only\n"
+"&Edit anyway\n"
+"&Recover\n"
+"&Quit\n"
+"&Abort"
+msgstr ""
+"&Maak as lees-alleen oop\n"
+"&Bewerk in elk geval\n"
+"&Herwin\n"
+"&Verlaat\n"
+"&Stop"
+
+msgid ""
+"&Open Read-Only\n"
+"&Edit anyway\n"
+"&Recover\n"
+"&Quit\n"
+"&Abort\n"
+"&Delete it"
+msgstr ""
+"&Maak as lees-alleen oop\n"
+"&Bewerk in elk geval\n"
+"&Herwin\n"
+"&Verlaat\n"
+"&Stop\n"
+"S&krap dit"
+
+msgid "E326: Too many swap files found"
+msgstr "E326: Te veel ruillêers gevind"
+
+msgid "E327: Part of menu-item path is not sub-menu"
+msgstr "E327: Deel van kieslys-item pad is nie 'n sub-kieslys nie"
+
+msgid "E328: Menu only exists in another mode"
+msgstr "E328: Kieslys bestaan slegs in 'n ander modus"
+
+msgid "E329: No menu of that name"
+msgstr "E329: Geen kieslys met daardie naam nie"
+
+msgid "E330: Menu path must not lead to a sub-menu"
+msgstr "E330: Kieslyspad moenie lei na 'n sub-kieslys nie"
+
+msgid "E331: Must not add menu items directly to menu bar"
+msgstr "E331: Moenie kieslysitems direk by kieslysstaaf voeg nie"
+
+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
+msgid ""
+"\n"
+"--- Menus ---"
+msgstr ""
+"\n"
+"--- Kieslyste ---"
+
+msgid "Tear off this menu"
+msgstr "Skeur die kieslys af"
+
+msgid "E333: Menu path must lead to a menu item"
+msgstr "E333: Kieslyspad moet lei na 'n kieslysitem"
+
+#, c-format
+msgid "E334: Menu not found: %s"
+msgstr "E334: Kieslys nie gevind nie: %s"
+
+#, c-format
+msgid "E335: Menu not defined for %s mode"
+msgstr "E335: Kieslys nie gedefinieer vir %s modus nie"
+
+msgid "E336: Menu path must lead to a sub-menu"
+msgstr "E336: Kieslyspad moet lei na 'n sub-kieslys"
+
+msgid "E337: Menu not found - check menu names"
+msgstr "E337: Kieslys nie gevind nie - maak seker oor die kieslys name"
+
+#, c-format
+msgid "Error detected while processing %s:"
+msgstr "Fout ontdek tydens verwerking van %s: "
+
+#, c-format
+msgid "line %4ld:"
+msgstr "reël %4ld:"
+
+msgid "[string too long]"
+msgstr "[string te lank]"
+
+msgid "Messages maintainer: Bram Moolenaar <Bram@vim.org>"
+msgstr "Boodskappe onderhouers: Danie Roux en Jean Jordaan <droux@tuks.co.za>"
+
+msgid "Interrupt: "
+msgstr "Onderbreek: "
+
+msgid "Hit ENTER to continue"
+msgstr "Druk ENTER om voort te gaan"
+
+msgid "Hit ENTER or type command to continue"
+msgstr "Druk ENTER of tik 'n bevel om voort te gaan"
+
+msgid "-- More --"
+msgstr "-- Meer --"
+
+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 " (RET: line, SPACE: page, d: half page, q: quit)"
+msgstr " (RET: reël, SPACE: bladsy, d: halwe bladsy, q: los dit"
+
+msgid "Question"
+msgstr "Vraag"
+
+msgid ""
+"&Yes\n"
+"&No"
+msgstr ""
+"&Ja\n"
+"&Nee"
+
+msgid ""
+"&Yes\n"
+"&No\n"
+"Save &All\n"
+"&Discard All\n"
+"&Cancel"
+msgstr ""
+"&Ja\n"
+"&Nee\n"
+"Stoor &alles\n"
+"&Gooi alles weg\n"
+"&Kanselleer"
+
+msgid "Save File dialog"
+msgstr "Stoor Lêer dialooghokkie"
+
+msgid "Open File dialog"
+msgstr "Maak lêer oop dialooghokkie"
+
+#. TODO: non-GUI file selector here
+msgid "E338: Sorry, no file browser in console mode"
+msgstr "E338: Jammer, lêerblaaier nie beskikbaar in konsole-modus nie"
+
+msgid "W10: Warning: Changing a readonly file"
+msgstr "W10: Waarskuwing: Jy wysig aan 'n leesalleen lêer"
+
+msgid "1 more line"
+msgstr "1 reël meer"
+
+msgid "1 line less"
+msgstr "1 reël minder"
+
+#, c-format
+msgid "%ld more lines"
+msgstr "%ld meer reëls"
+
+#, c-format
+msgid "%ld fewer lines"
+msgstr "%ld minder reëls"
+
+msgid " (Interrupted)"
+msgstr " (Onderbreek)"
+
+msgid "Vim: preserving files...\n"
+msgstr "Vim: bewaar lêers...\n"
+
+#. close all memfiles, without deleting
+msgid "Vim: Finished.\n"
+msgstr "Vim: Klaar.\n"
+
+#, c-format
+msgid "ERROR: "
+msgstr "FOUT: "
+
+#, c-format
+msgid ""
+"\n"
+"[bytes] total alloc-freed %lu-%lu, in use %lu, peak use %lu\n"
+msgstr ""
+"\n"
+"[grepe] totaal 'alloc'-vrygelaat %lu-%lu, in gebruik %lu, piekgebruik %lu\n"
+
+#, c-format
+msgid ""
+"[calls] total re/malloc()'s %lu, total free()'s %lu\n"
+"\n"
+msgstr ""
+"[roepe] totaal re/malloc()'s %lu, totale free()'s %lu\n"
+"\n"
+
+msgid "E340: Line is becoming too long"
+msgstr "E340: Rëel word te lank"
+
+#, c-format
+msgid "E341: Internal error: lalloc(%ld, )"
+msgstr "E341: Interne fout: 'lalloc(%ld, )'"
+
+#, c-format
+msgid "E342: Out of memory! (allocating %lu bytes)"
+msgstr "E342: Geheue is op! (ken %lu grepe toe)"
+
+#, c-format
+msgid "Calling shell to execute: \"%s\""
+msgstr "Roep dop om uit te voer: \"%s\""
+
+msgid "E545: Missing colon"
+msgstr "E545: Ontbrekende dubbelpunt"
+
+msgid "E546: Illegal mode"
+msgstr "E546: Ongeldige modus"
+
+msgid "E547: Illegal mouseshape"
+msgstr "E547: Ongeldige muisvorm"
+
+msgid "E548: digit expected"
+msgstr "E548: syfer verwag"
+
+msgid "E549: Illegal percentage"
+msgstr "E549: Ongeldige persentasie"
+
+msgid "Enter encryption key: "
+msgstr "Voer enkripsie-sleutel in: "
+
+msgid "Enter same key again: "
+msgstr "Voer die sleutel weer in: "
+
+msgid "Keys don't match!"
+msgstr "Sleutels verskil!"
+
+#, c-format
+msgid ""
+"E343: Invalid path: '**[number]' must be at the end of the path or be "
+"followed by '%s'."
+msgstr ""
+"E343: Ongeldige pad: '**[nommer]' moet aan die einde van 'n pad wees of "
+"gevolg wees deur %s'."
+
+#, c-format
+msgid "E344: Can't find directory \"%s\" in cdpath"
+msgstr "E344: Kan nie gids \"%s\" in 'cdpath' vind nie"
+
+#, c-format
+msgid "E345: Can't find file \"%s\" in path"
+msgstr "E345: Kan lêer \"%s\" nie vind in pad nie"
+
+#, c-format
+msgid "E346: No more directory \"%s\" found in cdpath"
+msgstr "E346: Geen gids \"%s\" meer gevind in 'cdpath' nie"
+
+#, c-format
+msgid "E347: No more file \"%s\" found in path"
+msgstr "E347: Geen lêer \"%s\" meer gevind in pad nie"
+
+msgid "E550: Missing colon"
+msgstr "E550: Ontbrekende dubbelpunt"
+
+msgid "E551: Illegal component"
+msgstr "E551: Ongeldige komponent"
+
+msgid "E552: digit expected"
+msgstr "E552: syfer verwag"
+
+#. Get here when the server can't be found.
+msgid "Cannot connect to Netbeans #2"
+msgstr "Kan nie aan Netbeans #2 koppel nie"
+
+msgid "Cannot connect to Netbeans"
+msgstr "Kan nie aan Netbeans koppel nie"
+
+#, c-format
+msgid "E668: Wrong access mode for NetBeans connection info file: \"%s\""
+msgstr "E668: Verkeerde toegangsmodue vir NetBeans konneksie inligtingslêer: \"%s\""
+
+msgid "read from Netbeans socket"
+msgstr "lees vanaf Netbeans 'socket'"
+
+msgid "E658: NetBeans connection lost for buffer %ld"
+msgstr "E658: NetBeans konneksie vir buffer %ld verloor"
+
+msgid "Warning: terminal cannot highlight"
+msgstr "Waarskuwing: terminaal kan nie teks uitlig nie"
+
+msgid "E348: No string under cursor"
+msgstr "E348: Geen string onder loper nie"
+
+msgid "E349: No identifier under cursor"
+msgstr "E349: Geen identifiseerder onder loper nie"
+
+msgid "E352: Cannot erase folds with current 'foldmethod'"
+msgstr "E352: Kan nie voue verwyder met huidige 'foldmethod' nie"
+
+msgid "E664: changelist is empty"
+msgstr "E664: 'changelist' is leeg"
+
+msgid "E662: At start of changelist"
+msgstr "E662: By die begin van die veranderingslys"
+
+msgid "E663: At end of changelist"
+msgstr "E663: By die einde van die veranderingslys"
+
+msgid "Type :quit<Enter> to exit Vim"
+msgstr "Tik :quit<Enter> om Vim te verlaat"
+
+# Het te doen met < en >
+#, c-format
+msgid "1 line %sed 1 time"
+msgstr "1 reël 1 keer ge-%s"
+
+#, c-format
+msgid "1 line %sed %d times"
+msgstr "1 reël ge-%s %d keer"
+
+#, c-format
+msgid "%ld lines %sed 1 time"
+msgstr "%ld reëls 1 keer ge-%s"
+
+#, c-format
+msgid "%ld lines %sed %d times"
+msgstr "%ld reëls ge-%s %d keer"
+
+#, c-format
+msgid "%ld lines to indent... "
+msgstr "%ld reëls om in te keep..."
+
+msgid "1 line indented "
+msgstr "1 reël ingekeep "
+
+#, c-format
+msgid "%ld lines indented "
+msgstr "%ld reëls ingekeep "
+
+#. must display the prompt
+msgid "cannot yank; delete anyway"
+msgstr "kan nie pluk nie: verwyder in elk geval"
+
+msgid "1 line changed"
+msgstr "1 reël verander"
+
+msgid "%ld lines changed"
+msgstr "%ld reëls verander"
+
+#, c-format
+msgid "freeing %ld lines"
+msgstr "laat %ld reëls gaan"
+
+msgid "1 line yanked"
+msgstr "1 reël gepluk"
+
+#, c-format
+msgid "%ld lines yanked"
+msgstr "%ld reëls gepluk"
+
+#, c-format
+msgid "E353: Nothing in register %s"
+msgstr "E353: Niks in register %s nie"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Registers ---"
+msgstr ""
+"\n"
+"--- Registers ---"
+
+msgid "Illegal register name"
+msgstr "Ongeldige registernaam"
+
+#, c-format
+msgid ""
+"\n"
+"# Registers:\n"
+msgstr ""
+"\n"
+"# Registers:\n"
+
+msgid "E574: Unknown register type %d"
+msgstr "E574: Onbekende registertipe %d"
+
+#, c-format
+msgid "E354: Invalid register name: '%s'"
+msgstr "E354: Ongeldige registernaam: '%s'"
+
+#, c-format
+msgid "%ld Cols; "
+msgstr "%ld Kolomme; "
+
+#, c-format
+msgid "Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Bytes"
+msgstr "%s%ld van %ld reëls gekies; %ld van %ld Woorde; %ld van %ld Grepe"
+
+# njj: Karakters kan meerdere grepe wees, sien ':h multibyte'
+#, c-format
+msgid "Col %s of %s; Line %ld of %ld; Word %ld of %ld; Byte %ld of %ld"
+msgstr "Kol %s van %s; Reël %ld van %ld; Woord %ld van %ld; Greep %ld van %ld"
+
+#, c-format
+msgid "(+%ld for BOM)"
+msgstr "(+%ld vir 'BOM')"
+
+msgid "%<%f%h%m%=Page %N"
+msgstr "%<%f%h%m%=Bladsy %N"
+
+msgid "Thanks for flying Vim"
+msgstr "Dankie dat jy vlieg met Vim"
+
+msgid "E518: Unknown option"
+msgstr "E518: Onbekende opsie"
+
+msgid "E519: Option not supported"
+msgstr "E519: Opsie is nie ondersteun nie"
+
+msgid "E520: Not allowed in a modeline"
+msgstr "E520: Nie toegelaat in 'n moduslyn nie"
+
+msgid ""
+"\n"
+"\tLast set from "
+msgstr ""
+"\n"
+"\tLaas gestel vanaf "
+
+msgid "E521: Number required after ="
+msgstr "E521: Nommer vereis na ="
+
+msgid "E522: Not found in termcap"
+msgstr "E522: Nie gevind in 'termcap' nie"
+
+msgid "E539: Illegal character <%s>"
+msgstr "E539: Ongeldige karakter <%s>"
+
+msgid "E529: Cannot set 'term' to empty string"
+msgstr "E529: Kan nie 'term' stel na leë string nie"
+
+msgid "E530: Cannot change term in GUI"
+msgstr "E530: Kan nie 'term' verander in GUI nie"
+
+msgid "E531: Use \":gui\" to start the GUI"
+msgstr "E531: Gebruik \":gui\" om die GUI te begin"
+
+msgid "E589: 'backupext' and 'patchmode' are equal"
+msgstr "E589: 'backupext' en 'patchmode' is dieselfde"
+
+msgid "E617: Cannot be changed in the GTK+ 2 GUI"
+msgstr "E617: Kan nie 'term' verander in die GTK+ 2 GUI nie"
+
+msgid "E524: Missing colon"
+msgstr "E524: Ontbrekende dubbelpunt"
+
+msgid "E525: Zero length string"
+msgstr "E525: Nul-lengte string"
+
+msgid "E526: Missing number after <%s>"
+msgstr "E526: Ontbrekende nommer na <%s>"
+
+msgid "E527: Missing comma"
+msgstr "E527: Ontbrekende komma"
+
+msgid "E528: Must specify a ' value"
+msgstr "E528: Moet 'n ' waarde spesifiseer"
+
+msgid "E595: contains unprintable or wide character"
+msgstr "E595: bevat 'n ondrukbare of wye karakter"
+
+msgid "E596: Invalid font(s)"
+msgstr "E596: Ongeldige font(e)"
+
+msgid "E597: can't select fontset"
+msgstr "E597: kan nie fontstel kies nie"
+
+msgid "E598: Invalid fontset"
+msgstr "E598: Ongeldige fontstel"
+
+msgid "E533: can't select wide font"
+msgstr "E533: kan nie wye font kies nie"
+
+msgid "E534: Invalid wide font"
+msgstr "E534: Ongeldige wye font"
+
+msgid "E535: Illegal character after <%c>"
+msgstr "E535: Ongeldige karakter na <%c>"
+
+msgid "E536: comma required"
+msgstr "E536: komma benodig"
+
+msgid "E537: 'commentstring' must be empty or contain %s"
+msgstr "E537: 'commentstring' moet leeg wees of %s bevat"
+
+msgid "E538: No mouse support"
+msgstr "E538: Geen muisondersteuning nie"
+
+msgid "E540: Unclosed expression sequence"
+msgstr "E540: Onvoltooide uitdrukkingreeks"
+
+msgid "E541: too many items"
+msgstr "E541: te veel items"
+
+msgid "E542: unbalanced groups"
+msgstr "E542: ongebalanseerde groepe"
+
+msgid "E590: A preview window already exists"
+msgstr "E590: Daar bestaan reeds 'n voorskouvenster"
+
+msgid "W17: Arabic requires UTF-8, do ':set encoding=utf-8'"
+msgstr "W17: Arabies benodig UTF-8, doen ':set encoding=utf-8'"
+
+msgid "E593: Need at least %d lines"
+msgstr "E593: Benodig ten minste %d reëls"
+
+msgid "E594: Need at least %d columns"
+msgstr "E594: Benodig ten minste %d kolomme"
+
+#, c-format
+msgid "E355: Unknown option: %s"
+msgstr "E355: Onbekende opsie: %s"
+
+msgid ""
+"\n"
+"--- Terminal codes ---"
+msgstr ""
+"\n"
+"--- Terminaal kodes ---"
+
+msgid ""
+"\n"
+"--- Global option values ---"
+msgstr ""
+"\n"
+"--- Globale opsie waardes ---"
+
+msgid ""
+"\n"
+"--- Local option values ---"
+msgstr ""
+"\n"
+"--- Lokale opsie waardes ---"
+
+msgid ""
+"\n"
+"--- Options ---"
+msgstr ""
+"\n"
+"--- Opsies ---"
+
+msgid "E356: get_varp ERROR"
+msgstr "E356: 'get_varp' FOUT"
+
+#, c-format
+msgid "E357: 'langmap': Matching character missing for %s"
+msgstr "E357: 'langmap': Passende karakter ontbreek vir %s"
+
+#, c-format
+msgid "E358: 'langmap': Extra characters after semicolon: %s"
+msgstr "E358: 'langmap: Ekstra karakters na kommapunt: %s"
+
+msgid "cannot open "
+msgstr "kan nie oopmaak nie "
+
+msgid "VIM: Can't open window!\n"
+msgstr "VIM: Kan nie venster oopmaak nie!\n"
+
+msgid "Need Amigados version 2.04 or later\n"
+msgstr "Benodig Amigados weergawe 2.04 of later\n"
+
+#, c-format
+msgid "Need %s version %ld\n"
+msgstr "Benodig %s weergawe %ld\n"
+
+msgid "Cannot open NIL:\n"
+msgstr "Kan nie NIL: oopmaak nie\n"
+
+msgid "Cannot create "
+msgstr "Kan nie skep nie: "
+
+#, c-format
+msgid "Vim exiting with %d\n"
+msgstr "Vim stop met %d\n"
+
+msgid "cannot change console mode ?!\n"
+msgstr "kan konsole-modus nie verander nie ?!\n"
+
+msgid "mch_get_shellsize: not a console??\n"
+msgstr "'mch_get_shellsize': nie 'n konsole nie??\n"
+
+#. if Vim opened a window: Executing a shell may cause crashes
+msgid "E360: Cannot execute shell with -f option"
+msgstr "E360: Kan nie dop met -f opsie uitvoer nie"
+
+msgid "Cannot execute "
+msgstr "Kan nie uitvoer nie "
+
+msgid "shell "
+msgstr "dop "
+
+msgid " returned\n"
+msgstr " teruggekeer\n"
+
+msgid "ANCHOR_BUF_SIZE too small."
+msgstr "'ANCHOR_BUF_SIZE' is te klein"
+
+msgid "I/O ERROR"
+msgstr "I/O FOUT"
+
+msgid "...(truncated)"
+msgstr "...(afgekap)"
+
+msgid "'columns' is not 80, cannot execute external commands"
+msgstr "'columns' is nie 80 nie, kan nie eksterne bevele uitvoer nie"
+
+msgid "E237: Printer selection failed"
+msgstr "E237: Drukker-seleksie het gefaal"
+
+#, c-format
+msgid "to %s on %s"
+msgstr "na %s op %s"
+
+msgid "E613: Unknown printer font: %s"
+msgstr "E613: Onbekende drukker font: %s"
+
+#, c-format
+msgid "E238: Print error: %s"
+msgstr "E238: Drukfout: %s"
+
+msgid "Unknown"
+msgstr "Onbekend"
+
+#, c-format
+msgid "Printing '%s'"
+msgstr "Druk nou '%s'"
+
+#, c-format
+msgid "E244: Illegal charset name \"%s\" in font name \"%s\""
+msgstr "E244: Ongeldige karakterstelnaam \"%s\" in fontnaam \"%s\""
+
+#, c-format
+msgid "E245: Illegal char '%c' in font name \"%s\""
+msgstr "E245: Ongeldige karakter '%c' in fontnaam \"%s\""
+
+msgid "Vim: Double signal, exiting\n"
+msgstr "Vim: Dubbel sein, staak\n"
+
+#, c-format
+msgid "Vim: Caught deadly signal %s\n"
+msgstr "Vim: Het dodelike sein %s gevang\n"
+
+#, c-format
+msgid "Vim: Caught deadly signal\n"
+msgstr "Vim: Het dodelike sein gevang\n"
+
+#, c-format
+msgid "Opening the X display took %ld msec"
+msgstr "Om die X-vertoonskerm oop te maak het %ld msek gevat"
+
+msgid ""
+"\n"
+"Vim: Got X error\n"
+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"
+
+msgid ""
+"\n"
+"Cannot execute shell "
+msgstr ""
+"\n"
+"Kan nie dop uitvoer nie "
+
+msgid ""
+"\n"
+"Cannot execute shell sh\n"
+msgstr ""
+"\n"
+"Kan nie dop 'sh' uitvoer nie\n"
+
+msgid ""
+"\n"
+"shell returned "
+msgstr ""
+"\n"
+"dop lewer "
+
+msgid ""
+"\n"
+"Cannot create pipes\n"
+msgstr ""
+"\n"
+"Kan nie pype skep nie\n"
+
+msgid ""
+"\n"
+"Cannot fork\n"
+msgstr ""
+"\n"
+"Kan nie vurk nie\n"
+
+msgid ""
+"\n"
+"Command terminated\n"
+msgstr ""
+"\n"
+"Bevel beëindig\n"
+
+msgid "XSMP lost ICE connection"
+msgstr "XSMP het ICE konneksie verloor"
+
+msgid "Opening the X display failed"
+msgstr "Oopmaak van die X vertoonskerm het gefaal"
+
+msgid "XSMP handling save-yourself request"
+msgstr "XSMP hanteer 'save-yourself' versoek"
+
+msgid "XSMP opening connection"
+msgstr "XSMP maak nou konneksie oop"
+
+msgid "XSMP ICE connection watch failed"
+msgstr "XSMP ICE konneksie beloer het gefaal"
+
+#, c-format
+msgid "XSMP SmcOpenConnection failed: %s"
+msgstr "XSMP 'SmcOpenConnection' het gefaal: %s"
+
+msgid "At line"
+msgstr "By reël"
+
+msgid "Could not allocate memory for command line."
+msgstr "Kan nie geheue toeken vir bevelreël nie"
+
+msgid "VIM Error"
+msgstr "VIM Fout"
+
+msgid "Could not load vim32.dll!"
+msgstr "Kon nie 'vim32.dll' laai nie!"
+
+msgid "Could not fix up function pointers to the DLL!"
+msgstr "Kon nie funksiewysers na die DLL opstel nie!"
+
+#, c-format
+msgid "shell returned %d"
+msgstr "dop het %d gelewer"
+
+#, c-format
+msgid "Vim: Caught %s event\n"
+msgstr "Vim: Het %s gebeurtenis gevang\n"
+
+msgid "close"
+msgstr "maak toe"
+
+msgid "logoff"
+msgstr "teken uit"
+
+msgid "shutdown"
+msgstr "sit af"
+
+msgid "E371: Command not found"
+msgstr "E371: Bevel nie gevind nie"
+
+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 gevind in '$PATH' nie.\n"
+"Eksterne opdragte sal nie wag na voltooiing nie\n"
+"Sien ':help win32-vimrun' vir meer inligting."
+
+msgid "Vim Warning"
+msgstr "Vim Waarskuwing"
+
+#, c-format
+msgid "E372: Too many %%%c in format string"
+msgstr "E372: Te veel %%%c in formaatstring"
+
+#, c-format
+msgid "E373: Unexpected %%%c in format string"
+msgstr "E373: Onverwagte %%%c in formaatstring"
+
+msgid "E374: Missing ] in format string"
+msgstr "E374: Ontbrekende ] in formaatstring"
+
+#, c-format
+msgid "E375: Unsupported %%%c in format string"
+msgstr "E375: Ongesteunde %%%c in formaatstring"
+
+#, c-format
+msgid "E376: Invalid %%%c in format string prefix"
+msgstr "E376: Ongeldige %%%c in formaatstringvoorvoegsel"
+
+#, c-format
+msgid "E377: Invalid %%%c in format string"
+msgstr "E377: Ongeldige %%%c in formaatstring"
+
+msgid "E378: 'errorformat' contains no pattern"
+msgstr "E378: 'errorformat' bevat geen patroon nie"
+
+msgid "E379: Missing or empty directory name"
+msgstr "E379: Ontbrekende of leë gidsnaam"
+
+msgid "E553: No more items"
+msgstr "E553: Geen items meer nie"
+
+#, c-format
+msgid "(%d of %d)%s%s: "
+msgstr "(%d van %d)%s%s: "
+
+msgid " (line deleted)"
+msgstr " (reël verwyder)"
+
+msgid "E380: At bottom of quickfix stack"
+msgstr "E380: Onder aan 'quickfix' stapel"
+
+msgid "E381: At top of quickfix stack"
+msgstr "E381: Bo aan 'quickfix' stapel"
+
+#, c-format
+msgid "error list %d of %d; %d errors"
+msgstr "foutelys %d van %d; %d foute"
+
+msgid "E382: Cannot write, 'buftype' option is set"
+msgstr "E382: Kan nie skryf nie, 'buftype' opsie is aan"
+
+msgid "E369: invalid item in %s%%[]"
+msgstr "E369: ongeldige item in %s%%[]"
+
+msgid "E339: Pattern too long"
+msgstr "E339: Patroon te lank"
+
+msgid "E50: Too many \\z("
+msgstr "E50: Te veel \\z("
+
+msgid "E51: Too many %s("
+msgstr "E51: Te veel %s("
+
+msgid "E52: Unmatched \\z("
+msgstr "E52: Onpaar \\z("
+
+msgid "E53: Unmatched %s%%("
+msgstr "E53: Onpaar %s%%("
+
+msgid "E54: Unmatched %s("
+msgstr "E54: Onpaar %s("
+
+msgid "E55: Unmatched %s)"
+msgstr "E55: Onpaar %s)"
+
+msgid "E56: %s* operand could be empty"
+msgstr "E56: %s* operand mag leeg wees"
+
+msgid "E57: %s+ operand could be empty"
+msgstr "E57: %s+ operand mag leeg wees"
+
+msgid "E59: invalid character after %s@"
+msgstr "E59: ongeldige karakter na %s@"
+
+msgid "E58: %s{ operand could be empty"
+msgstr "E58: %s{ operand mag leeg wees"
+
+msgid "E60: Too many complex %s{...}s"
+msgstr "E60: Te veel komplekse %s{...}ies"
+
+#, c-format
+msgid "E61: Nested %s*"
+msgstr "E61: Geneste %s*"
+
+#, c-format
+msgid "E62: Nested %s%c"
+msgstr "E62: Geneste %s%c"
+
+msgid "E63: invalid use of \\_"
+msgstr "E63: ongeldige gebruik van \\_"
+
+#, c-format
+msgid "E64: %s%c follows nothing"
+msgstr "E64: %s%c volg niks"
+
+msgid "E65: Illegal back reference"
+msgstr "E65: Ongeldige tru-verwysing"
+
+msgid "E66: \\z( not allowed here"
+msgstr "E66: \\z( nie hier toegelaat nie"
+
+msgid "E67: \\z1 et al. not allowed here"
+msgstr "E67: \\z1 e.a. nie hier toegelaat nie"
+
+msgid "E68: Invalid character after \\z"
+msgstr "E68: ongeldige karakter na \\z"
+
+msgid "E69: Missing ] after %s%%["
+msgstr "E69: Ontbrekende ] na %s%%["
+
+msgid "E70: Empty %s%%[]"
+msgstr "E70: Leë %s%%[]"
+
+msgid "E71: Invalid character after %s%%"
+msgstr "E71: Ongeldige karakter na %s%%"
+
+msgid "E554: Syntax error in %s{...}"
+msgstr "E554: Sintaksfout in %s{...}"
+
+msgid "E361: Crash intercepted; regexp too complex?"
+msgstr "E361: Ineenstorting onderskep. Patroon te kompleks?"
+
+msgid "E363: pattern caused out-of-stack error"
+msgstr "E363: patroon het lëe-stapel fout veroorsaak"
+
+msgid "External submatches:\n"
+msgstr "Eksterne subtreffers:\n"
+
+#, c-format
+msgid "+--%3ld lines folded "
+msgstr "+--%3ld reëls gevou "
+
+msgid " VREPLACE"
+msgstr " VVERVANG"
+
+msgid " REPLACE"
+msgstr " VERVANG"
+
+msgid " REVERSE"
+msgstr " OMKEER"
+
+msgid " INSERT"
+msgstr " INVOEG"
+
+msgid " (insert)"
+msgstr " (invoeg)"
+
+msgid " (replace)"
+msgstr " (vervang)"
+
+msgid " (vreplace)"
+msgstr " (vvervang)"
+
+msgid " Hebrew"
+msgstr " Hebreeus"
+
+msgid " Arabic"
+msgstr " Arabies"
+
+msgid " (lang)"
+msgstr " (taal)"
+
+msgid " (paste)"
+msgstr " (plak)"
+
+msgid " VISUAL"
+msgstr " VISUELE"
+
+msgid " VISUAL LINE"
+msgstr " VISUELE REËL"
+
+msgid " VISUAL BLOCK"
+msgstr " VISUELE BLOK"
+
+msgid " SELECT"
+msgstr " KIES"
+
+msgid " SELECT LINE"
+msgstr " KIES REËL"
+
+msgid " SELECT BLOCK"
+msgstr " KIES BLOK"
+
+msgid "recording"
+msgstr "besig om op te neem"
+
+msgid "search hit TOP, continuing at BOTTOM"
+msgstr "soektog het BO getref, gaan voort van ONDER af"
+
+msgid "search hit BOTTOM, continuing at TOP"
+msgstr "soektog het ONDER getref, gaan voort van BO af"
+
+#, c-format
+msgid "E383: Invalid search string: %s"
+msgstr "E383: Ongeldige soekstring: %s"
+
+#, c-format
+msgid "E384: search hit TOP without match for: %s"
+msgstr "E384: soektog het BO getref sonder treffer vir: %s"
+
+#, c-format
+msgid "E385: search hit BOTTOM without match for: %s"
+msgstr "E385: soektog het ONDER getref sonder treffer vir: %s"
+
+msgid "E386: Expected '?' or '/' after ';'"
+msgstr "E386: Verwag '?' of '/' na ';'"
+
+msgid " (includes previously listed match)"
+msgstr " (sluit in vorige gelyste treffer)"
+
+#. cursor at status line
+msgid "--- Included files "
+msgstr "--- Ingeslote lêers"
+
+msgid "not found "
+msgstr "nie gevind nie "
+
+msgid "in path ---\n"
+msgstr "in pad ---\n"
+
+msgid " (Already listed)"
+msgstr " (Alreeds gelys)"
+
+msgid " NOT FOUND"
+msgstr " NIE GEVIND NIE"
+
+#, c-format
+msgid "Scanning included file: %s"
+msgstr "Deursoek ingeslote lêer: %s"
+
+msgid "E387: Match is on current line"
+msgstr "E387: Treffer is op huidige reël"
+
+msgid "All included files were found"
+msgstr "Alle ingeslote lêers is gevind"
+
+msgid "No included files"
+msgstr "Geen ingeslote lêers nie"
+
+msgid "E388: Couldn't find definition"
+msgstr "E388: Kon definisie nie vind nie"
+
+msgid "E389: Couldn't find pattern"
+msgstr "E389: Kon patroon nie vind nie"
+
+#, c-format
+msgid "E390: Illegal argument: %s"
+msgstr "E390: Ongeldige parameter: %s"
+
+#, c-format
+msgid "E391: No such syntax cluster: %s"
+msgstr "E391: Geen sodanige sintakskluster nie: %s"
+
+msgid "No Syntax items defined for this buffer"
+msgstr "Geen Sintaks-items gedefinieer vir hierdie buffer nie"
+
+msgid "syncing on C-style comments"
+msgstr "sinchroniseer met C-styl kommentaar"
+
+msgid "no syncing"
+msgstr "geen sinchronisering"
+
+msgid "syncing starts "
+msgstr "sinchronisasie begin "
+
+msgid " lines before top line"
+msgstr " reëls voor boonste lyn"
+
+msgid ""
+"\n"
+"--- Syntax sync items ---"
+msgstr ""
+"\n"
+"--- Sintaks sync items ---"
+
+msgid ""
+"\n"
+"syncing on items"
+msgstr ""
+"\n"
+"sinchronisering met items"
+
+msgid ""
+"\n"
+"--- Syntax items ---"
+msgstr ""
+"\n"
+"--- Sintaks items ---"
+
+#, c-format
+msgid "E392: No such syntax cluster: %s"
+msgstr "E392: Geen sodanige sintakskluster nie: %s"
+
+msgid "minimal "
+msgstr "minimaal "
+
+msgid "maximal "
+msgstr "maksimaal "
+
+msgid "; match "
+msgstr "; treffer "
+
+msgid " line breaks"
+msgstr " reël breuke"
+
+msgid "E393: group[t]here not accepted here"
+msgstr "E393: 'group[t]here' nie hier aanvaar nie"
+
+#, c-format
+msgid "E394: Didn't find region item for %s"
+msgstr "E394: Kon nie omgewingsitem vind vir %s nie"
+
+msgid "E395: contains argument not accepted here"
+msgstr "E395: bevat parameters nie hier aanvaar nie"
+
+msgid "E396: containedin argument not accepted here"
+msgstr "E396: 'containedin' parameter nie hier aanvaar nie"
+
+msgid "E397: Filename required"
+msgstr "E397: Lêernaam benodig"
+
+#, c-format
+msgid "E398: Missing '=': %s"
+msgstr "E398: Ontbrekende '=': %s"
+
+#, c-format
+msgid "E399: Not enough arguments: syntax region %s"
+msgstr "E399: Nie genoeg parameters nie: sintaksomgewing %s"
+
+msgid "E400: No cluster specified"
+msgstr "E400: Geen kluster gespesifiseer nie"
+
+#, c-format
+msgid "E401: Pattern delimiter not found: %s"
+msgstr "E401: Patroonbegrenser nie gevind nie: %s"
+
+#, c-format
+msgid "E402: Garbage after pattern: %s"
+msgstr "E402: Gemors na patroon: %s"
+
+msgid "E403: syntax sync: line continuations pattern specified twice"
+msgstr "E403: sintaks sync: reëlvoortgaanpatroon twee keer gespesifiseer"
+
+#, c-format
+msgid "E404: Illegal arguments: %s"
+msgstr "E404: Ongeldige parameters: %s"
+
+#, c-format
+msgid "E405: Missing equal sign: %s"
+msgstr "E405: Ontbrekende gelykaanteken: %s"
+
+#, c-format
+msgid "E406: Empty argument: %s"
+msgstr "E406: Leë parameter: %s"
+
+#, c-format
+msgid "E407: %s not allowed here"
+msgstr "E407: %s nie toegelaat hier nie"
+
+#, c-format
+msgid "E408: %s must be first in contains list"
+msgstr "E408: %s moet vóór in 'contains' lys wees"
+
+#, c-format
+msgid "E409: Unknown group name: %s"
+msgstr "E409: Onbekende groepnaam: %s"
+
+#, c-format
+msgid "E410: Invalid :syntax subcommand: %s"
+msgstr "E410: Ongeldige :syntax subbevel %s"
+
+msgid "E679: recursive loop loading syncolor.vim"
+msgstr "E679: rekursiewe lus gedurende laai van syncolor.vim"
+
+#, c-format
+msgid "E411: highlight group not found: %s"
+msgstr "E411: uitliggroep nie gevind nie: %s"
+
+#, c-format
+msgid "E412: Not enough arguments: \":highlight link %s\""
+msgstr "E412: Te min parameters: \":highlight link %s\""
+
+#, c-format
+msgid "E413: Too many arguments: \":highlight link %s\""
+msgstr "E413: Te veel parameters: \":highlight link %s\""
+
+msgid "E414: group has settings, highlight link ignored"
+msgstr ""
+"E414: groep het instellings, uitligskakel ('highlight link') geïgnoreer"
+
+#, c-format
+msgid "E415: unexpected equal sign: %s"
+msgstr "E415: onverwagte gelykaanteken: %s"
+
+#, c-format
+msgid "E416: missing equal sign: %s"
+msgstr "E416: ontbrekende gelykaanteken: %s"
+
+#, c-format
+msgid "E417: missing argument: %s"
+msgstr "E417: ontbrekende parameter: %s"
+
+#, c-format
+msgid "E418: Illegal value: %s"
+msgstr "E418: Ongeldige waarde: %s"
+
+msgid "E419: FG color unknown"
+msgstr "E419: FG kleur onbekend"
+
+msgid "E420: BG color unknown"
+msgstr "E420: BG kleur onbekend"
+
+#, c-format
+msgid "E421: Color name or number not recognized: %s"
+msgstr "E421: Kleurnaam of -nommer nie herken nie: %s"
+
+#, c-format
+msgid "E422: terminal code too long: %s"
+msgstr "E422: terminaalkode te lank: %s"
+
+#, c-format
+msgid "E423: Illegal argument: %s"
+msgstr "E423: Ongeldige parameter: %s"
+
+msgid "E424: Too many different highlighting attributes in use"
+msgstr "E424: Te veel verskillende uitlig-eienskappe in gebruik"
+
+msgid "E669: Unprintable character in group name"
+msgstr "E669: Onvertoonbare karakter in groepnaam"
+
+#. This is an error, but since there previously was no check only
+#. * give a warning.
+msgid "W18: Invalid character in group name"
+msgstr "W18: Ongeldige karakter groepnaam"
+
+msgid "E555: at bottom of tag stack"
+msgstr "E555: onderaan etiketstapel"
+
+msgid "E556: at top of tag stack"
+msgstr "E556: bo-aan etiketstapel"
+
+msgid "E425: Cannot go before first matching tag"
+msgstr "E425: Kan nie vóór eerste etiket-treffer gaan nie"
+
+#, c-format
+msgid "E426: tag not found: %s"
+msgstr "E426: etiket nie gevind nie: %s"
+
+msgid " # pri kind tag"
+msgstr " # pri tipe etiket"
+
+msgid "file\n"
+msgstr "lêer\n"
+
+#.
+#. * Ask to select a tag from the list.
+#. * When using ":silent" assume that <CR> was entered.
+#.
+msgid "Enter nr of choice (<CR> to abort): "
+msgstr "Sleutel nommer van keuse in (<CR> om te stop): "
+
+msgid "E427: There is only one matching tag"
+msgstr "E427: Daar is slegs een etiket-treffer"
+
+msgid "E428: Cannot go beyond last matching tag"
+msgstr "E428: Kan nie verby laaste etiket-treffer gaan nie"
+
+#, c-format
+msgid "File \"%s\" does not exist"
+msgstr "Lêer \"%s\" bestaan nie"
+
+#. Give an indication of the number of matching tags
+#, c-format
+msgid "tag %d of %d%s"
+msgstr "etiket %d van %d%s"
+
+msgid " or more"
+msgstr " of meer"
+
+msgid " Using tag with different case!"
+msgstr " Gaan etiket met ander kas gebruik!"
+
+#, c-format
+msgid "E429: File \"%s\" does not exist"
+msgstr "E429: Lêer \"%s\" bestaan nie"
+
+#. Highlight title
+msgid ""
+"\n"
+" # TO tag FROM line in file/text"
+msgstr ""
+"\n"
+" # NA etiket VAN reël in lêer/teks"
+
+#, c-format
+msgid "Searching tags file %s"
+msgstr "Deursoek etiketlêer %s"
+
+#, c-format
+msgid "E430: Tag file path truncated for %s\n"
+msgstr "E430: Etiketlêergids afgekap vir %s\n"
+
+#, c-format
+msgid "E431: Format error in tags file \"%s\""
+msgstr "E431: Formaatfout in etiketlêer \"%s\""
+
+#, c-format
+msgid "Before byte %ld"
+msgstr "Voor greep %ld"
+
+#, c-format
+msgid "E432: Tags file not sorted: %s"
+msgstr "E432: Etiketlêer ongesorteer: %s"
+
+#. never opened any tags file
+msgid "E433: No tags file"
+msgstr "E433: Geen etiketlêer nie"
+
+msgid "E434: Can't find tag pattern"
+msgstr "E434: Kan nie etiketpatroon vind nie"
+
+msgid "E435: Couldn't find tag, just guessing!"
+msgstr "E435: Kon nie etiket vind nie, ek raai maar!"
+
+msgid "' not known. Available builtin terminals are:"
+msgstr "' onbekend. Beskikbare ingeboude terminale is:"
+
+msgid "defaulting to '"
+msgstr "gebruik verstek '"
+
+msgid "E557: Cannot open termcap file"
+msgstr "E557: Kan nie 'termcap'-lêer oopmaak nie"
+
+msgid "E558: Terminal entry not found in terminfo"
+msgstr "E558: Terminaalinskrywing nie in 'terminfo' gevind nie"
+
+msgid "E559: Terminal entry not found in termcap"
+msgstr "E559: Terminaalinskrywing nie in 'termcap' gevind nie"
+
+#, c-format
+msgid "E436: No \"%s\" entry in termcap"
+msgstr "E436: Geen \"%s\" inskrywing in termcap nie"
+
+msgid "E437: terminal capability \"cm\" required"
+msgstr "E437: terminaalvermoë \"cm\" vereis"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Terminal keys ---"
+msgstr ""
+"\n"
+"--- Terminaal sleutels ---"
+
+msgid "new shell started\n"
+msgstr "nuwe dop begin\n"
+
+msgid "Vim: Error reading input, exiting...\n"
+msgstr "Vim: Fout met lees van invoer, verlaat...\n"
+
+#. must display the prompt
+msgid "No undo possible; continue anyway"
+msgstr "Geen herstel moontlik; gaan in elk geval voort"
+
+msgid "E438: u_undo: line numbers wrong"
+msgstr "E438: u_undo: reëlnommers foutief"
+
+msgid "1 change"
+msgstr "1 verandering"
+
+#, c-format
+msgid "%ld changes"
+msgstr "%ld veranderinge"
+
+msgid "E439: undo list corrupt"
+msgstr "E439: herstellys korrup"
+
+msgid "E440: undo line missing"
+msgstr "E440: herstelreël ontbreek"
+
+#. Only MS VC 4.1 and earlier can do Win32s
+msgid ""
+"\n"
+"MS-Windows 16/32-bit GUI version"
+msgstr ""
+"\n"
+"MS-Windows 16/32-bis GUI weergawe"
+
+msgid ""
+"\n"
+"MS-Windows 32-bit GUI version"
+msgstr ""
+"\n"
+"MS-Windows 32-bis GUI version"
+
+msgid " in Win32s mode"
+msgstr " in Win32s modus"
+
+msgid " with OLE support"
+msgstr " met OLE ondersteuning"
+
+msgid ""
+"\n"
+"MS-Windows 32-bit console version"
+msgstr ""
+"\n"
+"MS-Windows 32-bis konsole weergawe"
+
+msgid ""
+"\n"
+"MS-Windows 16-bit version"
+msgstr ""
+"\n"
+"MS-Windows 16-bis weergawe"
+
+msgid ""
+"\n"
+"32-bit MS-DOS version"
+msgstr ""
+"\n"
+"32-bis MS-DOS weergawe"
+
+msgid ""
+"\n"
+"16-bit MS-DOS version"
+msgstr ""
+"\n"
+"16-bis MS-DOS weergawe"
+
+msgid ""
+"\n"
+"MacOS X (unix) version"
+msgstr ""
+"\n"
+"MacOS X (unix) weergawe"
+
+msgid ""
+"\n"
+"MacOS X version"
+msgstr ""
+"\n"
+"MacOS X weergawe"
+
+msgid ""
+"\n"
+"MacOS version"
+msgstr ""
+"\n"
+"MacOS weergawe"
+
+msgid ""
+"\n"
+"RISC OS version"
+msgstr ""
+"\n"
+"RISC OS weergawe"
+
+msgid ""
+"\n"
+"Included patches: "
+msgstr ""
+"\n"
+"Ingeslote laslappies:"
+
+msgid "Modified by "
+msgstr "Gewysig deur "
+
+msgid ""
+"\n"
+"Compiled "
+msgstr ""
+"\n"
+"Gekompileer op "
+
+msgid "by "
+msgstr "deur "
+
+msgid ""
+"\n"
+"Huge version "
+msgstr ""
+"\n"
+"Enorme weergawe "
+
+msgid ""
+"\n"
+"Big version "
+msgstr ""
+"\n"
+"Groot weergawe "
+
+msgid ""
+"\n"
+"Normal version "
+msgstr ""
+"\n"
+"Normale weergawe "
+
+msgid ""
+"\n"
+"Small version "
+msgstr ""
+"\n"
+"Klein weergawe "
+
+msgid ""
+"\n"
+"Tiny version "
+msgstr ""
+"\n"
+"Piepklein weergawe "
+
+msgid "without GUI."
+msgstr "sonder GUI."
+
+msgid "with GTK2-GNOME GUI."
+msgstr "met GTK2-GNOME GUI."
+
+msgid "with GTK-GNOME GUI."
+msgstr "met GTK-GNOME GUI."
+
+msgid "with GTK2 GUI."
+msgstr "met GTK2 GUI"
+
+msgid "with GTK GUI."
+msgstr "met GTK GUI"
+
+msgid "with X11-Motif GUI."
+msgstr "met X11-Motif GUI."
+
+msgid "with X11-neXtaw GUI."
+msgstr "met X11-neXtaw GUI"
+
+msgid "with X11-Athena GUI."
+msgstr "met X11-Athena GUI"
+
+msgid "with BeOS GUI."
+msgstr "met BeOS GUI"
+
+msgid "with Photon GUI."
+msgstr "met Photon GUI."
+
+msgid "with GUI."
+msgstr "met GUI."
+
+msgid "with Carbon GUI."
+msgstr "met Carbon GUI."
+
+msgid "with Cocoa GUI."
+msgstr "met Cocoa GUI."
+
+msgid "with (classic) GUI."
+msgstr "met (klassieke) GUI."
+
+msgid " Features included (+) or not (-):\n"
+msgstr " Kenmerke in- (+) of uitgesluit (-):\n"
+
+msgid " system vimrc file: \""
+msgstr " stelsel vimrc-lêer: \""
+
+msgid " user vimrc file: \""
+msgstr " gebruiker vimrc-lêer: \""
+
+msgid " 2nd user vimrc file: \""
+msgstr " 2de gebruiker vimrc-lêer \""
+
+msgid " 3rd user vimrc file: \""
+msgstr " 3de gebruiker vimrc-lêer \""
+
+msgid " user exrc file: \""
+msgstr " gebruiker exrc-lêer: \""
+
+msgid " 2nd user exrc file: \""
+msgstr " 2de gebruiker exrc-lêer: \""
+
+msgid " system gvimrc file: \""
+msgstr " stelsel gvimrc-lêer: \""
+
+msgid " user gvimrc file: \""
+msgstr " gebruiker gvimrc-lêer: \""
+
+msgid "2nd user gvimrc file: \""
+msgstr "2de gebruiker gvimrc-lêer: \""
+
+msgid "3rd user gvimrc file: \""
+msgstr "3de gebruiker gvimrc-lêer: \""
+
+msgid " system menu file: \""
+msgstr " stelsel kieslys-lêer: \""
+
+msgid " fall-back for $VIM: \""
+msgstr " bystand vir $VIM: \""
+
+msgid " f-b for $VIMRUNTIME: \""
+msgstr " bystand vir $VIMRUNTIME: \""
+
+msgid "Compilation: "
+msgstr "Kompilering: "
+
+msgid "Compiler: "
+msgstr "Kompileerder: "
+
+msgid "Linking: "
+msgstr "Koppeling: "
+
+msgid " DEBUG BUILD"
+msgstr " ONTFOUTINGS-KOMPILERING"
+
+msgid "VIM - Vi IMproved"
+msgstr "VIM - Vi Met skop"
+
+# njj: :))
+msgid "version "
+msgstr "Weergawe "
+
+msgid "by Bram Moolenaar et al."
+msgstr "deur Bram Moolenaar et al."
+
+msgid "Vim is open source and freely distributable"
+msgstr "Vim is vryekode, en vrylik verspreibaar"
+
+msgid "Help poor children in Uganda!"
+msgstr "Help arm kinders in Uganda!"
+
+msgid "type :help iccf<Enter> for information "
+msgstr "tik :help iccf<Enter> vir meer inligting hieroor "
+
+msgid "type :q<Enter> to exit "
+msgstr "tik :q<Enter> om program verlaat "
+
+msgid "type :help<Enter> or <F1> for on-line help"
+msgstr "tik :help<Enter> of <F1> vir aanlyn hulp "
+
+msgid "type :help version7<Enter> for version info"
+msgstr "tik :help version7<Enter> vir weergawe-inligting"
+
+msgid "Running in Vi compatible mode"
+msgstr "Voer tans uit in Vi-versoenbare modus"
+
+msgid "type :set nocp<Enter> for Vim defaults"
+msgstr "tik :set nocp<Enter> vir Vim verstekwaardes "
+
+msgid "type :help cp-default<Enter> for info on this"
+msgstr "tik :help cp-default<Enter> vir meer inligting hieroor"
+
+msgid "menu Help->Orphans for information "
+msgstr "menu Hulp->Weeskinders vir meer inligting hieroor "
+
+msgid "Running modeless, typed text is inserted"
+msgstr "Voer modus-loos uit, getikte teks word ingevoeg"
+
+msgid "menu Edit->Global Settings->Toggle Insert Mode "
+msgstr "menu Redigeer->Globale verstellings->Stel en herstel Invoeg Modus"
+
+msgid " for two modes "
+msgstr " vir twee modusse "
+
+msgid "menu Edit->Global Settings->Toggle Vi Compatible"
+msgstr "menu Redigeer->Global verstellings->Stel en herstel Vi Versoenbaar"
+
+msgid " for Vim defaults "
+msgstr " vir Vim verstekwaardes"
+
+msgid "Sponsor Vim development!"
+msgstr "Borg Vim ontwikkeling!"
+
+msgid "Become a registered Vim user!"
+msgstr "Word 'n geregistreerde Vim gebruiker!"
+
+msgid "type :help sponsor<Enter> for information "
+msgstr "tik :help sponsor<Enter> vir meer inligting hieroor "
+
+msgid "type :help register<Enter> for information "
+msgstr "tik :help register<Enter> vir meer inligting hieroor "
+
+msgid "menu Help->Sponsor/Register for information "
+msgstr "menu Hulp->Borg/Registreer vir meer inligting"
+
+msgid "WARNING: Windows 95/98/ME detected"
+msgstr "WAARSKUWING: Windows 95/98/ME bespeur"
+
+msgid "type :help windows95<Enter> for info on this"
+msgstr "tik :help windows95<Enter> vir meer inligting hieroor"
+
+msgid "E441: There is no preview window"
+msgstr "E441: Daar is nie 'n voorskou-venster nie"
+
+msgid "E442: Can't split topleft and botright at the same time"
+msgstr "E442: Kan nie bo-links en onder-regs terselfdertyd verdeel nie"
+
+msgid "E443: Cannot rotate when another window is split"
+msgstr "E443: Kan nie roteer terwyl 'n ander venster verdeel is nie"
+
+msgid "E444: Cannot close last window"
+msgstr "E444: Kan nie laaste venster toemaak nie"
+
+msgid "Already only one window"
+msgstr "Daar is alreeds slegs een venster"
+
+msgid "E445: Other window contains changes"
+msgstr "E445: Die ander venster bevat veranderinge"
+
+msgid "E446: No file name under cursor"
+msgstr "E446: Geen lêernaam onder loper"
+
+#, c-format
+msgid "E447: Can't find file \"%s\" in path"
+msgstr "E447: Kan lêer \"%s\" nie vind in pad nie"
+
+msgid "E370: Could not load library %s"
+msgstr "E370: Kon nie biblioteek laai nie %s"
+
+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 "E299: Perl evaluation forbidden in sandbox without the Safe module"
+msgstr "E299: Perl evaluasie verbied in die sandput sonder die 'Safe' module"
+
+msgid "Edit with &multiple Vims"
+msgstr "Wysig met &meer as een Vim"
+
+msgid "Edit with single &Vim"
+msgstr "Wysig met 'n enkel &Vim"
+
+msgid "&Diff with Vim"
+msgstr "Wys verskille ('&diff') met Vim"
+
+msgid "Edit with &Vim"
+msgstr "Wysig met &Vim"
+
+#. Now concatenate
+msgid "Edit with existing Vim - &"
+msgstr "Wysig met bestaande Vim - &"
+
+msgid "Edits the selected file(s) with Vim"
+msgstr "Wysig die gekose lêer(s) met Vim"
+
+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 "gvimext.dll error"
+msgstr "'gvimext.dll' fout"
+
+msgid "Path length too long!"
+msgstr "Pad-lengte te lank"
+
+msgid "--No lines in buffer--"
+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.
+#.
+msgid "E470: Command aborted"
+msgstr "E470: Bevel gekanselleer"
+
+msgid "E471: Argument required"
+msgstr "E471: Parameter benodig"
+
+msgid "E10: \\ should be followed by /, ? or &"
+msgstr "E10: \\ moet gevolg word deur /, ? of &"
+
+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"
+
+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"
+
+msgid "E171: Missing :endif"
+msgstr "E171: Ontbrekende ':endif'"
+
+msgid "E600: Missing :endtry"
+msgstr "E600: Ontbrekende ':endtry'"
+
+msgid "E170: Missing :endwhile"
+msgstr "E170: Ontbrekende ':endwhile'"
+
+msgid "E588: :endwhile without :while"
+msgstr "E588: ':endwhile' sonder ':while'"
+
+msgid "E13: File exists (add ! to override)"
+msgstr "E13: Lêer bestaan (gebruik ! om te dwing)"
+
+msgid "E472: Command failed"
+msgstr "E472: Bevel het gefaal"
+
+#, c-format
+msgid "E234: Unknown fontset: %s"
+msgstr "E234: Onbekende fontstel: %s"
+
+#, c-format
+msgid "E235: Unknown font: %s"
+msgstr "E235: Onbekende font: %s"
+
+#, c-format
+msgid "E236: Font \"%s\" is not fixed-width"
+msgstr "E236: Font \"%s\" is nie 'n vaste-wydte font nie"
+
+msgid "E473: Internal error"
+msgstr "E473: Interne fout"
+
+msgid "Interrupted"
+msgstr "Onderbreek"
+
+msgid "E14: Invalid address"
+msgstr "E14: Ongeldige adres"
+
+msgid "E474: Invalid argument"
+msgstr "E474: Ongeldige parameter"
+
+msgid "E475: Invalid argument: %s"
+msgstr "E475: Ongeldige parameter: %s"
+
+#, c-format
+msgid "E15: Invalid expression: %s"
+msgstr "E15: Ongeldige uitdrukking: %s"
+
+msgid "E16: Invalid range"
+msgstr "E16: Ongeldige omvang"
+
+msgid "E476: Invalid command"
+msgstr "E476: Ongeldige bevel"
+
+#, c-format
+msgid "E17: \"%s\" is a directory"
+msgstr "E17: \"%s\" is 'n gids"
+
+msgid "E18: Unexpected characters before '='"
+msgstr "E18: Onverwagte karakters voor '='"
+
+#, c-format
+msgid "E364: Library call failed for \"%s()\""
+msgstr "E364: Biblioteekroep het gefaal vir \"%s\"()"
+
+#, c-format
+msgid "E448: Could not load library function %s"
+msgstr "E448: Kon nie biblioteek funksie laai nie %s"
+
+msgid "E19: Mark has invalid line number"
+msgstr "E19: Merker het ongeldige reëlnommer"
+
+msgid "E20: Mark not set"
+msgstr "E20: Merker nie gestel nie"
+
+msgid "E21: Cannot make changes, 'modifiable' is off"
+msgstr "E21: Kan nie wysig nie, 'modifiable' is af"
+
+msgid "E22: Scripts nested too deep"
+msgstr "E22: Skripte te diep ge-nes"
+
+msgid "E23: No alternate file"
+msgstr "E23: Geen alternatiewe lêer nie"
+
+msgid "E24: No such abbreviation"
+msgstr "E24: Afkorting bestaan nie"
+
+msgid "E477: No ! allowed"
+msgstr "E477: Geen ! toegelaat nie"
+
+msgid "E25: GUI cannot be used: Not enabled at compile time"
+msgstr "E25: GUI kan nie gebruik word nie: Nie tydens kompilering gekies 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 "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 "E800: Arabic cannot be used: Not enabled at compile time\n"
+msgstr ""
+"E800: Arabies kan nie gebruik word nie: Nie tydens kompilering gekies nie\n"
+
+#, c-format
+msgid "E28: No such highlight group name: %s"
+msgstr "E28: Geen sodanige uitliggroepnaam nie: %s"
+
+msgid "E29: No inserted text yet"
+msgstr "E29: Nog geen ingevoegde teks nie"
+
+msgid "E30: No previous command line"
+msgstr "E30: Geen vorige bevelreël nie"
+
+msgid "E31: No such mapping"
+msgstr "E31: Geen so 'n binding nie"
+
+msgid "E479: No match"
+msgstr "E479: Geen treffer nie"
+
+msgid "E480: No match: %s"
+msgstr "E480: Geen treffer: %s"
+
+msgid "E32: No file name"
+msgstr "E32: Geen lêernaam"
+
+msgid "E33: No previous substitute regular expression"
+msgstr "E33: Geen vorige vervangingspatroon nie"
+
+msgid "E34: No previous command"
+msgstr "E34: Geen vorige bevel nie"
+
+msgid "E35: No previous regular expression"
+msgstr "E35: Geen vorige patroon nie"
+
+msgid "E481: No range allowed"
+msgstr "E481: Geen omvang toegelaat nie"
+
+msgid "E36: Not enough room"
+msgstr "E36: Te min plek"
+
+#, c-format
+msgid "E247: no registered server named \"%s\""
+msgstr "E247: geen geregistreerde bediener genaamd \"%s\""
+
+msgid "E482: Can't create file %s"
+msgstr "E482: Kan nie lêer %s skep nie"
+
+msgid "E483: Can't get temp file name"
+msgstr "E483: Kan nie tydelike lêernaam kry nie"
+
+msgid "E484: Can't open file %s"
+msgstr "E484: Kan nie lêer %s oopmaak nie"
+
+msgid "E485: Can't read file %s"
+msgstr "E485: Kan nie lêer %s lees nie"
+
+msgid "E37: No write since last change (add ! to override)"
+msgstr "E37: Ongeskryf sedert vorige verandering (gebruik ! om te dwing)"
+
+msgid "E38: Null argument"
+msgstr "E38: Nul parameter"
+
+msgid "E39: Number expected"
+msgstr "E39: Nommer verwag"
+
+#, c-format
+msgid "E40: Can't open errorfile %s"
+msgstr "E40: Kan nie foutlêer %s oopmaak nie"
+
+msgid "E233: cannot open display"
+msgstr "E233: kan nie vertoonskerm oopmaak nie"
+
+msgid "E41: Out of memory!"
+msgstr "E41: Geheue op!"
+
+msgid "Pattern not found"
+msgstr "Patroon nie gevind nie"
+
+msgid "E486: Pattern not found: %s"
+msgstr "E486: Patroon nie gevind nie: %s"
+
+msgid "E487: Argument must be positive"
+msgstr "E487: Parameter moet positief wees"
+
+msgid "E459: Cannot go back to previous directory"
+msgstr "E459: Kan nie terug gaan na die vorige gids nie"
+
+msgid "E42: No Errors"
+msgstr "E42: Geen Foute"
+
+msgid "E43: Damaged match string"
+msgstr "E43: Beskadige trefferstring"
+
+msgid "E44: Corrupted regexp program"
+msgstr "E44: Korrupte patroonprogram"
+
+msgid "E45: 'readonly' option is set (add ! to override)"
+msgstr "E45: 'readonly' opsie is aan (gebruik ! om te dwing)"
+
+#, c-format
+msgid "E46: Cannot set read-only variable \"%s\""
+msgstr "E46: Kan nie lees-alleen veranderlike stel nie \"%s\""
+
+msgid "E47: Error while reading errorfile"
+msgstr "E47: Fout tydens lees van 'errorfile'"
+
+msgid "E48: Not allowed in sandbox"
+msgstr "E48: Nie toegelaat in sandput nie"
+
+msgid "E523: Not allowed here"
+msgstr "E523: Nie hier toegelaat nie"
+
+msgid "E359: Screen mode setting not supported"
+msgstr "E359: Skermmodus instelling nie ondersteun nie"
+
+msgid "E49: Invalid scroll size"
+msgstr "E49: Ongeldige rolgrootte"
+
+msgid "E91: 'shell' option is empty"
+msgstr "E91: 'shell' (dop) opsie is leeg"
+
+msgid "E255: Couldn't read in sign data!"
+msgstr "E255: Fout -- kon nie tekendata lees nie!"
+
+msgid "E72: Close error on swap file"
+msgstr "E72: Sluitfout met ruillêer"
+
+msgid "E73: tag stack empty"
+msgstr "E73: etiketstapel leeg"
+
+msgid "E74: Command too complex"
+msgstr "E74: Bevel te kompleks"
+
+msgid "E75: Name too long"
+msgstr "E75: Naam te lank"
+
+msgid "E76: Too many ["
+msgstr "E76: Te veel ["
+
+msgid "E77: Too many file names"
+msgstr "E77: Te veel lêername"
+
+msgid "E488: Trailing characters"
+msgstr "E488: Oorbodige karakters"
+
+msgid "E78: Unknown mark"
+msgstr "E78: Onbekende merker"
+
+msgid "E79: Cannot expand wildcards"
+msgstr "E79: Kan nie plekhouers uitbrei nie"
+
+msgid "E591: 'winheight' cannot be smaller than 'winminheight'"
+msgstr "E591: 'winheight' kan nie kleiner as 'winminheight' wees nie"
+
+msgid "E592: 'winwidth' cannot be smaller than 'winminwidth'"
+msgstr "E592: 'winwidth' kan nie kleiner as 'winminwidth' wees nie"
+
+msgid "E80: Error while writing"
+msgstr "E80: Fout tydens skryfoperasie"
+
+msgid "Zero count"
+msgstr "Nul telling"
+
+msgid "E81: Using <SID> not in a script context"
+msgstr "E81: Gebruik van '<SID>' buite skripkonteks"
+
+msgid "E449: Invalid expression received"
+msgstr "E449: Ongeldige uitdrukking ontvang"
+
+msgid "E463: Region is guarded, cannot modify"
+msgstr "E463: Omgewing is onder bewaking, kan nie verander nie"
+
+#~ msgid "function "
+#~ msgstr "funksie "
+
+#~ msgid "Run Macro"
+#~ msgstr "Voer Makro uit"
+
+#~ msgid "E221: 'commentstring' is empty"
+#~ msgstr "E221: 'commentstring' opsie is leeg"
+
+#~ msgid "E242: Color name not recognized: %s"
+#~ msgstr "E242: Kleurnaam is onbekend: %s"
+
+#~ msgid "E242: Missing color: %s"
+#~ msgstr "E242: Ontbrekende kleur: %s"
+
+#~ msgid "error reading cscope connection %d"
+#~ msgstr "'cscope' verbinding %d kon nie gelees word nie"
+
+#~ msgid "E260: cscope connection not found"
+#~ msgstr "E260: 'cscope' verbinding nie gevind nie"
+
+#~ msgid "cscope connection closed"
+#~ msgstr "'cscope' verbinding gesluit"
+
+# njj: dalk 'verbinding' ipv 'verbinding' orals?
+#~ msgid "couldn't malloc\n"
+#~ msgstr "kon nie 'malloc' nie\n"
+
+#~ msgid "%2d %-5ld %-34s <none>\n"
+#~ msgstr "%2d %-5ld %-34s <geen>\n"
+
+#~ msgid "E249: couldn't read VIM instance registry property"
+#~ msgstr "E249: kon nie VIM instansie register-kenmerk lees nie"
+
+#~ msgid "\"\n"
+#~ msgstr "\"\n"
+
+#~ msgid "--help\t\tShow Gnome arguments"
+#~ msgstr "--help\t\tWys Gnome parameters"
+
+#~ msgid "1 line ~ed"
+#~ msgstr "1 reël ge-~"
+
+#~ msgid "%ld lines ~ed"
+#~ msgstr "%ld reëls ge-~"
+
+#~ msgid " BLOCK"
+#~ msgstr " BLOK"
+
+#~ msgid " LINE"
+#~ msgstr " REËL"
+
+#~ msgid "Linear tag search"
+#~ msgstr "Liniêre etiketsoek"
+
+#~ msgid "Binary tag search"
+#~ msgstr "Binêre etiketsoek"
+
+#~ msgid "Can't open file %s"
+#~ msgstr "Kan nie lêer %s oopmaak nie"
+
+#~ msgid "E258: no matches found in cscope connections"
+#~ msgstr "E258: geen treffers gevind in 'cscope' verbindings nie"
+
+#~ msgid "No servers found for this display"
+#~ msgstr "Geen bedieners gevind vir die 'display' nie"
+
+#~ msgid "Missing filename"
+#~ msgstr "Ontbrekende lêernaam"
+
+#~ msgid "Invalid line number: %ld"
+#~ msgstr "Ongeldige reëlnommer: %ld"
+
+#~ msgid "Cannot use :normal from event handler"
+#~ msgstr "Kan ':normal' nie vanuit gebeurtenishanteerder gebruik nie"
+
+#~ msgid "%ldL, %ldC"
+#~ msgstr "%ldR, %ldK"
+
+#~ msgid "VIM - Help on..."
+#~ msgstr "VIM - Hulp met.."
+
+#~ msgid "Topic:"
+#~ msgstr "Onderwerp:"
+
+#~ msgid "Error: During loading fontset %s"
+#~ msgstr "Fout: Gedurende die laai van fontstel %s"
+
+#~ msgid "locale is not set correctly"
+#~ msgstr "lokaal is nie korrek gestel nie"
+
+#~ msgid "Set LANG environment variable to your locale"
+#~ msgstr "Stel die 'LANG' omgewingsveranderlike na jou lokaal toe"
+
+#~ msgid "For korean:"
+#~ msgstr "Vir Afrikaans:"
+
+#~ msgid " csh: setenv LANG ko"
+#~ msgstr " csh: setenv LANG af"
+
+#~ msgid " sh : export LANG=ko"
+#~ msgstr " sh: export LANG=af"
+
+#~ msgid "fontset name: %s"
+#~ msgstr "fontstel naam: %s"
+
+#~ msgid "Your language Font missing"
+#~ msgstr "Jou taal Font ontbreek"
+
+#~ msgid "loaded fontname: %s"
+#~ msgstr "gelaaide fontnaam: %s"
+
+#~ msgid "automata ERROR: internal"
+#~ msgstr "automata FOUT: intern"
+
+#~ msgid "cs_add_common: alloc fail #1"
+#~ msgstr "'cs_add_common': toeken onsuksesvol #1"
+
+#~ msgid "cs_add_common: alloc fail #2"
+#~ msgstr "'cs_add_common': toeken onsuksesvol #2"
+
+#~ msgid "cs_add_common: alloc fail #3"
+#~ msgstr "'cs_add_common': toeken onsuksesvol #3"
+
+#~ msgid "cs_add_common: alloc fail #4"
+#~ msgstr "'cs_add_common': toeken onsuksesvol #4"
+
+#~ msgid "Retrieve next symbol"
+#~ msgstr "Kry volgende simbool"
+
+#~ msgid "-- SNiFF+ commands --"
+#~ msgstr "-- SNiFF+ bevele --"
+
+#~ msgid "Unrecognized sniff request [%s]"
+#~ msgstr "Onbekende sniff versoek [%s]"
+
+#~ msgid "Can't create input context."
+#~ msgstr "Kan nie invoerkonteks skep nie."
+
+#~ 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 "Out of memory"
+#~ msgstr "Geheue op"
+
+#~ msgid "PC (32 bits Vim)"
+#~ msgstr "PC (32 bisse Vim)"
+
+#~ msgid "PC (16 bits Vim)"
+#~ msgstr "PC (16 bisse Vim)"
+
+#~ msgid "Unsupported screen mode"
+#~ msgstr "Ongesteunde skermmodus"
+
+#~ msgid "deadly signal"
+#~ msgstr "dodelike sein"
+
+#~ msgid "some"
+#~ msgstr "sommige"
+
+#~ msgid "Library call failed"
+#~ msgstr "Biblioteekfunksieroep het gefaal"
+
+#~ msgid "Cannot clear all highlight groups"
+#~ msgstr "Kan nie alle uitliggroepe leegmaak nie"
+
+#~ msgid "GUI is not running"
+#~ msgstr "GUI voer nie uit nie"
+
+#~ msgid "Command too long"
+#~ msgstr "Bevel te lank"
+
+#~ msgid "Ambiguous mapping"
+#~ msgstr "Dubbelsinnige binding"
+
+#~ msgid "Ambiguous mapping, conflicts with \"%s\""
+#~ msgstr "Dubbelsinnige binding, bots met \"%s\""
+
+#~ msgid "Too many \\("
+#~ msgstr "Te veel \\("
+
+#~ msgid "Unmatched \\("
+#~ msgstr "Onpaar \\("
+
+#~ msgid "Nested *, \\=, \\+, \\! or \\{"
+#~ msgstr "Geneste *, \\=, \\+, \\! of \\{"
+
+#~ msgid "\\= follows nothing"
+#~ msgstr "\\= volg niks"
+
+#~ msgid "\\+ follows nothing"
+#~ msgstr "\\+ volg niks"
+
+#~ msgid "\\@ follows nothing"
+#~ msgstr "\\@ volg niks"
+
+#~ msgid "\\{ follows nothing"
+#~ msgstr "\\{ volg niks"
+
+#~ msgid "\\* follows nothing"
+#~ msgstr "\\* volg niks"
+
+#~ msgid "Unexpected magic character; check META."
+#~ msgstr "Onverwagte toorkarakter; kyk na META."
+
+#~ msgid "type :help uganda<Enter> if you like Vim "
+#~ msgstr "tik :help uganda<Enter> as jy hou van Vim "
+
+#~ msgid " WARNING: Intel CPU detected. "
+#~ msgstr " WAARSKUWING: Intel SVE bespeur. "
+
+#~ msgid " PPC has a much better architecture. "
+#~ msgstr " PPC het 'n veel beter argitektuur. "
+
+#~ msgid "Security error: new viminfo file is a symbolic link"
+#~ msgstr "Sekuriteitsfout: nuwe viminfo lêer is a simboliese skakel"
+
+#~ msgid "line ~%ld: %s"
+#~ msgstr "reël ~%ld: %s"
+
+#~ msgid "makeef option not set"
+#~ msgstr "'makeef' opsie nie aan nie"
+
+#~ msgid "Security error: filter output is a symbolic link: %s"
+#~ msgstr "Sekuriteitsfout: filter afvoer is 'n simboliese skakel"
+
+#~ msgid "Security error: 'charconvert' output is a symbolic link"
+#~ msgstr "Sekuriteitsfout: 'charconvert' afvoer is 'n simboliese skakel"
+
+#~ msgid "Security error: filter input is a symbolic link: %s"
+#~ msgstr "Sekuriteitsfout: filter invoer is 'n simboliese skakel"
+
+#~ msgid "Fold must be at least two lines"
+#~ msgstr "'n Vou moet ten minste 2 reëls wees"
+
+#~ msgid "No fold at this line"
+#~ msgstr "Geen vou by hierdie reël nie"
+
+#~ msgid "Security error: shell command output is a symbolic link"
+#~ msgstr "Sekuriteitsfout: Dop-bevel afvoer is 'n simboliese skakel"
+
+#~ msgid "Warning: %s option changed from modeline"
+#~ msgstr "Waarskuwing: %s opsie verander vanaf moduslyn"
+
+#~ msgid "Change dir debugging enabled."
+#~ msgstr "Verandergids ontfouting in staat gestel"
+
+#~ msgid "Not a proper file name: '%s'"
+#~ msgstr "Nie 'n geldige lêernaam nie: '%s'"
+
+#~ msgid "File name '%s' is valid"
+#~ msgstr "lêernaam '%s is ongeldig"
+
+#~ msgid "Leave: %s"
+#~ msgstr "Verlaat: %s"
+
+#~ msgid "WARNING: tag command changed a buffer!!!"
+#~ msgstr "WAARSKUWING: etiketbevel het buffer verander!!!"
diff --git a/src/po/ca.po b/src/po/ca.po
new file mode 100644
index 0000000000..b397ae0a84
--- /dev/null
+++ b/src/po/ca.po
@@ -0,0 +1,6201 @@
+# Catalan messages for vim.
+# Copyright (C) 2003-2012 Ernest Adrogué <eadrogue@gmx.net>.
+# This file is distributed under the Vim License.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: vim 7.1\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2008-05-24 14:27+0200\n"
+"PO-Revision-Date: 2008-06-06 14:40+0100\n"
+"Last-Translator: Ernest Adrogué <eadrogue@gmx.net>\n"
+"Language-Team: Catalan <ca@dodds.net>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=iso-8859-1\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+msgid "E82: Cannot allocate any buffer, exiting..."
+msgstr "E82: No s'ha pogut assignar memòria per cap buffer, sortint..."
+
+msgid "E83: Cannot allocate buffer, using other one..."
+msgstr "E83: No s'ha pogut assignar memòria pel buffer, usant-ne un altre..."
+
+# unload: Treu el buffer de la memòria però el deixa a la llista
+# delete: Treu el buffer de la memòria i de la llista de buffers
+# wipe out: Elimina el buffer amb totes les opcions, marques, etc.
+msgid "E515: No buffers were unloaded"
+msgstr "E515: No s'ha alliberat cap buffer"
+
+msgid "E516: No buffers were deleted"
+msgstr "E516: No s'ha eliminat cap buffer"
+
+msgid "E517: No buffers were wiped out"
+msgstr "E517: No s'ha destruït cap buffer"
+
+msgid "1 buffer unloaded"
+msgstr "S'ha alliberat 1 buffer"
+
+#, c-format
+msgid "%d buffers unloaded"
+msgstr "S'han alliberat %d buffers"
+
+msgid "1 buffer deleted"
+msgstr "S'ha eliminat 1 buffer"
+
+#, c-format
+msgid "%d buffers deleted"
+msgstr "S'han eliminat %d buffers"
+
+msgid "1 buffer wiped out"
+msgstr "S'ha destruït 1 buffer"
+
+#, c-format
+msgid "%d buffers wiped out"
+msgstr "S'han destruït %d buffers"
+
+msgid "E84: No modified buffer found"
+msgstr "E84: No s'ha trobat cap buffer modificat"
+
+#. back where we started, didn't find anything.
+msgid "E85: There is no listed buffer"
+msgstr "E85: No hi ha cap buffer a la llista"
+
+#, c-format
+msgid "E86: Buffer %ld does not exist"
+msgstr "E86: El buffer %ld no existeix"
+
+msgid "E87: Cannot go beyond last buffer"
+msgstr "E87: No es pot anar més enllà de l'últim buffer"
+
+msgid "E88: Cannot go before first buffer"
+msgstr "E88: No es pot anar més enllà del primer buffer"
+
+#, c-format
+msgid "E89: No write since last change for buffer %ld (add ! to override)"
+msgstr "E89: No s'ha desat el buffer %ld (afegiu ! per confirmar)"
+
+msgid "E90: Cannot unload last buffer"
+msgstr "E90: No es pot alliberar l'últim buffer"
+
+msgid "W14: Warning: List of file names overflow"
+msgstr "W14: Atenció: S'ha desbordat la llista de noms de fitxers"
+
+#, c-format
+msgid "E92: Buffer %ld not found"
+msgstr "E92: No s'ha trobat el buffer %ld"
+
+#, c-format
+msgid "E93: More than one match for %s"
+msgstr "E93: Hi ha més d'una coincidència per a %s"
+
+#, c-format
+msgid "E94: No matching buffer for %s"
+msgstr "E94: No hi ha cap coincidència per a %s"
+
+#, c-format
+msgid "line %ld"
+msgstr "línia %ld"
+
+msgid "E95: Buffer with this name already exists"
+msgstr "E95: Ja existeix un buffer amb aquest nom"
+
+msgid " [Modified]"
+msgstr " [Modificat]"
+
+msgid "[Not edited]"
+msgstr "[No editat]"
+
+msgid "[New file]"
+msgstr "[Fitxer nou]"
+
+msgid "[Read errors]"
+msgstr "[Errors de lectura]"
+
+msgid "[readonly]"
+msgstr "[només lectura]"
+
+#, c-format
+msgid "1 line --%d%%--"
+msgstr "1 línia --%d%%--"
+
+#, c-format
+msgid "%ld lines --%d%%--"
+msgstr "%ld línies --%d%%--"
+
+#, c-format
+msgid "line %ld of %ld --%d%%-- col "
+msgstr "línia %ld de %ld --%d%%-- col "
+
+msgid "[No Name]"
+msgstr "[Sense nom]"
+
+#. must be a help buffer
+msgid "help"
+msgstr "ajuda"
+
+msgid "[Help]"
+msgstr "[Ajuda]"
+
+msgid "[Preview]"
+msgstr "[Vista prèvia]"
+
+msgid "All"
+msgstr "Tot"
+
+msgid "Bot"
+msgstr "Baix"
+
+msgid "Top"
+msgstr "Dalt"
+
+#, c-format
+msgid ""
+"\n"
+"# Buffer list:\n"
+msgstr ""
+"\n"
+"# Llista de buffers:\n"
+
+msgid "[Location List]"
+msgstr "[Llista de posicions]"
+
+msgid "[Quickfix List]"
+msgstr "[Llista Quickfix]"
+
+msgid ""
+"\n"
+"--- Signs ---"
+msgstr ""
+"\n"
+"--- Senyals ---"
+
+#, c-format
+msgid "Signs for %s:"
+msgstr "Senyals per a %s:"
+
+#, c-format
+msgid " line=%ld id=%d name=%s"
+msgstr " línia=%ld id=%d nom=%s"
+
+#, c-format
+msgid "E96: Can not diff more than %ld buffers"
+msgstr "E96: No es poden mostrar diferències amb més de %ld buffers"
+
+msgid "E97: Cannot create diffs"
+msgstr "E97: No s'han pogut mostrar les diferències"
+
+# És el nom d'un diàleg. Menú "Split patched by..."
+msgid "Patch file"
+msgstr "Fitxer de diferències"
+
+msgid "E98: Cannot read diff output"
+msgstr "E98: No s'ha pogut llegir la sortida de diff"
+
+msgid "E99: Current buffer is not in diff mode"
+msgstr "E99: El buffer actual no es troba en mode diff"
+
+msgid "E793: No other buffer in diff mode is modifiable"
+msgstr "E793: No hi ha cap altre buffer en mode diff que sigui modificable"
+
+msgid "E100: No other buffer in diff mode"
+msgstr "E100: No hi ha cap altre buffer en mode diff"
+
+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"
+
+#, c-format
+msgid "E102: Can't find buffer \"%s\""
+msgstr "E102: No s'ha trobat el buffer \"%s\""
+
+#, c-format
+msgid "E103: Buffer \"%s\" is not in diff mode"
+msgstr "E103: El buffer \"%s\" no es troba en mode diff"
+
+msgid "E787: Buffer changed unexpectedly"
+msgstr "E787: El buffer ha canviat inesperadament"
+
+msgid "E104: Escape not allowed in digraph"
+msgstr "E104: No es permeten caràcters d'escapada en un dígraf"
+
+msgid "E544: Keymap file not found"
+msgstr "E544: No s'ha trobat el fitxer de mapa de tecles"
+
+# traducció de «sourced file». eac
+msgid "E105: Using :loadkeymap not in a sourced file"
+msgstr "E105: L'ordre :loadkeymap només es pot usar en fitxers"
+
+msgid "E791: Empty keymap entry"
+msgstr "E791: Entrada al mapa de tecles no conté res"
+
+# buscar un nom, en lloc del verb «completar». eac
+msgid " Keyword completion (^N^P)"
+msgstr " Compleció de paraules clau (^N^P)"
+
+#. ctrl_x_mode == 0, ^P/^N compl.
+msgid " ^X mode (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)"
+msgstr " Mode ^X (^]^D^E^F^|^K^L^N^O^Ps^U^V^Y)"
+
+# buscar un nom, en lloc del verb «completar». eac
+msgid " Whole line completion (^L^N^P)"
+msgstr " Compleció de línies senceres (^L^N^P)"
+
+# buscar un nom, en lloc del verb «completar». eac
+msgid " File name completion (^F^N^P)"
+msgstr " Compleció de noms de fitxer (^F^N^P)"
+
+# buscar un nom, en lloc del verb «completar». eac
+msgid " Tag completion (^]^N^P)"
+msgstr " Compleció d'etiquetes (^]^N^P)"
+
+# buscar un nom, en lloc del verb «completar». eac
+msgid " Path pattern completion (^N^P)"
+msgstr " Compleció d'ubicacions (^N^P)"
+
+# buscar un nom, en lloc del verb «completar». eac
+msgid " Definition completion (^D^N^P)"
+msgstr " Compleció de definicions (^D^N^P)"
+
+# buscar un nom, en lloc del verb «completar». eac
+msgid " Dictionary completion (^K^N^P)"
+msgstr " Compleció de paraules de diccionari (^K^N^P)"
+
+# buscar un nom, en lloc del verb «completar». eac
+msgid " Thesaurus completion (^T^N^P)"
+msgstr " Compleció de sinònims (^T^N^P)"
+
+# buscar un nom, en lloc del verb «completar». eac
+msgid " Command-line completion (^V^N^P)"
+msgstr " Compleció d'ordres (^V^N^P)"
+
+# buscar un nom, en lloc del verb «completar». eac
+msgid " User defined completion (^U^N^P)"
+msgstr " Compleció definida per l'usuari (^U^N^P)"
+
+# buscar un nom, en lloc del verb «completar». eac
+msgid " Omni completion (^O^N^P)"
+msgstr " Omni-compleció (^O^N^P)"
+
+msgid " Spelling suggestion (s^N^P)"
+msgstr "Suggeriment ortogràfic (s^N^P)"
+
+# buscar un nom, en lloc del verb «completar». eac
+msgid " Keyword Local completion (^N^P)"
+msgstr " Compleció de paraules clau locals (^N^P)"
+
+msgid "Hit end of paragraph"
+msgstr "S'ha arribat al final del paràgraf"
+
+msgid "'dictionary' option is empty"
+msgstr "L'opció 'dictionary' no està definida"
+
+msgid "'thesaurus' option is empty"
+msgstr "L'opció 'thesaurus' no està definida"
+
+#, c-format
+msgid "Scanning dictionary: %s"
+msgstr "S'està examinant el diccionari: %s"
+
+msgid " (insert) Scroll (^E/^Y)"
+msgstr " (inserir) Desplaçar (^E/^Y)"
+
+msgid " (replace) Scroll (^E/^Y)"
+msgstr " (substituir) Desplaçar (^E/^Y)"
+
+#, c-format
+msgid "Scanning: %s"
+msgstr "Examinant: %s"
+
+#, c-format
+msgid "Scanning tags."
+msgstr "Examinant les etiquetes."
+
+msgid " Adding"
+msgstr " Afegint"
+
+#. 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.
+#.
+msgid "-- Searching..."
+msgstr "-- Cercant..."
+
+msgid "Back at original"
+msgstr "Original"
+
+msgid "Word from other line"
+msgstr "Paraula d'una altra línia"
+
+msgid "The only match"
+msgstr "L'única coincidència"
+
+#, c-format
+msgid "match %d of %d"
+msgstr "coincidència %d de %d"
+
+#, c-format
+msgid "match %d"
+msgstr "coincidència %d"
+
+msgid "E18: Unexpected characters in :let"
+msgstr "E18: Caràcters inesperats :let"
+
+#, c-format
+msgid "E684: list index out of range: %ld"
+msgstr "E684: índex de llista fora d'abast: %ld"
+
+#, c-format
+msgid "E121: Undefined variable: %s"
+msgstr "E121: Variable no definida: %s"
+
+msgid "E111: Missing ']'"
+msgstr "E111: Falta un ']'"
+
+#, c-format
+msgid "E686: Argument of %s must be a List"
+msgstr "E686: L'argument de %s ha de ser una llista"
+
+#, c-format
+msgid "E712: Argument of %s must be a List or Dictionary"
+msgstr "E712: L'argument de %s ha de ser una llista o un diccionari"
+
+msgid "E713: Cannot use empty key for Dictionary"
+msgstr "E713: Els diccionaris no admeten claus buides"
+
+msgid "E714: List required"
+msgstr "E714: Es requereix una llista"
+
+msgid "E715: Dictionary required"
+msgstr "E715: Es requereix un diccionari"
+
+#, c-format
+msgid "E118: Too many arguments for function: %s"
+msgstr "E118: Massa arguments per a la funció: %s"
+
+#, c-format
+msgid "E716: Key not present in Dictionary: %s"
+msgstr "E716: La clau no existeix al diccionari: %s"
+
+#, c-format
+msgid "E122: Function %s already exists, add ! to replace it"
+msgstr "E122: La funció %s ja existeix, afegiu ! per substituir-la"
+
+msgid "E717: Dictionary entry already exists"
+msgstr "E717: Ja existeix l'entrada al diccionari"
+
+msgid "E718: Funcref required"
+msgstr "E718: Es requereix una referència de funció"
+
+msgid "E719: Cannot use [:] with a Dictionary"
+msgstr "E719: No es pot usar [:] amb un diccionari"
+
+#, c-format
+msgid "E734: Wrong variable type for %s="
+msgstr "E734: Tipus de variable incorrecte per a %s="
+
+#, c-format
+msgid "E130: Unknown function: %s"
+msgstr "E130: Funció desconeguda: %s"
+
+#, c-format
+msgid "E461: Illegal variable name: %s"
+msgstr "E461: El nom de la variable és il·legal: %s"
+
+msgid "E687: Less targets than List items"
+msgstr "E687: Hi ha menys valors objectiu que elements a la llista"
+
+msgid "E688: More targets than List items"
+msgstr "E688: Hi ha més valors objectiu que elements a la llista"
+
+msgid "Double ; in list of variables"
+msgstr "Doble ; a la llista de variables"
+
+#, c-format
+msgid "E738: Can't list variables for %s"
+msgstr "E738: No es poden llistar les variables per a %s"
+
+msgid "E689: Can only index a List or Dictionary"
+msgstr "E689: Només admeten índexs les llistes i els diccionaris"
+
+msgid "E708: [:] must come last"
+msgstr "E708: [:] ha d'anar al final"
+
+msgid "E709: [:] requires a List value"
+msgstr "E709: [:] requereix un valor tipus llista"
+
+msgid "E710: List value has more items than target"
+msgstr "E710: La llista té més elements que valors objectiu"
+
+msgid "E711: List value has not enough items"
+msgstr "E711: La llista no té prou elements"
+
+msgid "E690: Missing \"in\" after :for"
+msgstr "E690: Falta un \"in\" després de :for"
+
+#, c-format
+msgid "E107: Missing parentheses: %s"
+msgstr "E107: Falten claus '{}': %s"
+
+#, c-format
+msgid "E108: No such variable: \"%s\""
+msgstr "E108: No existeix tal variable: \"%s\""
+
+msgid "E743: variable nested too deep for (un)lock"
+msgstr "E743: variable està massa imbricada per a (des)bloquejar-la"
+
+msgid "E109: Missing ':' after '?'"
+msgstr "E109: Falta un ':' després de '?'"
+
+msgid "E691: Can only compare List with List"
+msgstr "E691: Una llista només es pot comparar amb una llista"
+
+msgid "E692: Invalid operation for Lists"
+msgstr "E692: Operació no vàlida en llistes"
+
+msgid "E735: Can only compare Dictionary with Dictionary"
+msgstr "E735: Un diccionari només es pot comparar amb un diccionari"
+
+msgid "E736: Invalid operation for Dictionary"
+msgstr "E736: Operació no vàlida en diccionaris"
+
+msgid "E693: Can only compare Funcref with Funcref"
+msgstr "E693: Una referència de funció només es pot comparar amb una referència de funció"
+
+msgid "E694: Invalid operation for Funcrefs"
+msgstr "E694: Operació no vàlida per a referències de funcions"
+
+msgid "E110: Missing ')'"
+msgstr "E110: Falta un ')'"
+
+msgid "E695: Cannot index a Funcref"
+msgstr "E695: No es pot indexar una referència de funció"
+
+#, c-format
+msgid "E112: Option name missing: %s"
+msgstr "E112: Falta el nom de l'opció: %s"
+
+#, c-format
+msgid "E113: Unknown option: %s"
+msgstr "E113: Opció desconeguda: %s"
+
+#, c-format
+msgid "E114: Missing quote: %s"
+msgstr "E114: Falten cometes: %s"
+
+#, c-format
+msgid "E115: Missing quote: %s"
+msgstr "E115: Falten cometes: %s"
+
+#, c-format
+msgid "E696: Missing comma in List: %s"
+msgstr "E696: Falta una coma a la llista: %s"
+
+#, c-format
+msgid "E697: Missing end of List ']': %s"
+msgstr "E697: Falta un final de llista ']': %s"
+
+#, c-format
+msgid "E720: Missing colon in Dictionary: %s"
+msgstr "E720: Falta un caràcter de dos punts al diccionari: %s"
+
+#, c-format
+msgid "E721: Duplicate key in Dictionary: \"%s\""
+msgstr "E721: Clau duplicada al diccionari: \"%s\""
+
+#, c-format
+msgid "E722: Missing comma in Dictionary: %s"
+msgstr "E722: Falta una coma al diccionari: %s"
+
+#, c-format
+msgid "E723: Missing end of Dictionary '}': %s"
+msgstr "E723: Falta un final de diccionari '}': %s"
+
+msgid "E724: variable nested too deep for displaying"
+msgstr "E724: variable imbricada massa profundament per a mostrar-la"
+
+#, c-format
+msgid "E117: Unknown function: %s"
+msgstr "E117: Funció desconeguda: %s"
+
+#, c-format
+msgid "E119: Not enough arguments for function: %s"
+msgstr "E119: Falten arguments per a la funció: %s"
+
+#, c-format
+msgid "E120: Using <SID> not in a script context: %s"
+msgstr "E120: Ús de <SID> en un context no vàlid: %s"
+
+#, c-format
+msgid "E725: Calling dict function without Dictionary: %s"
+msgstr "E725: Crida a una funció dict sense diccionari: %s"
+
+msgid "E699: Too many arguments"
+msgstr "E699: Sobren arguments"
+
+msgid "E785: complete() can only be used in Insert mode"
+msgstr "E785: complete() només es pot utilitzar en el mode d'inserció"
+
+#.
+#. * 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 "&D'acord"
+
+#, c-format
+msgid "E737: Key already exists: %s"
+msgstr "E737: La clau ja existeix: %s"
+
+#, c-format
+msgid "+-%s%3ld lines: "
+msgstr "+-%s%3ld línies: "
+
+#, c-format
+msgid "E700: Unknown function: %s"
+msgstr "E700: Funció desconeguda: %s"
+
+msgid ""
+"&OK\n"
+"&Cancel"
+msgstr ""
+"&D'acord\n"
+"&Cancel·la"
+
+msgid "called inputrestore() more often than inputsave()"
+msgstr "s'ha cridat inputrestore() més sovint que inputsave()"
+
+msgid "E786: Range not allowed"
+msgstr "E786: Interval no permès"
+
+msgid "E701: Invalid type for len()"
+msgstr "E701: El tipus per a len() no és vàlid"
+
+msgid "E726: Stride is zero"
+msgstr "E726: L'increment entre passos és zero"
+
+msgid "E727: Start past end"
+msgstr "E727: Inici més enllà del final"
+
+msgid "<empty>"
+msgstr "<buit>"
+
+msgid "E240: No connection to Vim server"
+msgstr "E240: No hi ha connexió amb el servidor Vim"
+
+# «res» ? eac
+#, c-format
+msgid "E241: Unable to send to %s"
+msgstr "E241: No s'ha pogut enviar a %s"
+
+msgid "E277: Unable to read a server reply"
+msgstr "E277: No s'ha pogut llegir la resposta del servidor"
+
+msgid "E655: Too many symbolic links (cycle?)"
+msgstr "E655: Massa enllaços simbòlics (circulars?)"
+
+# «res» ? eac
+msgid "E258: Unable to send to client"
+msgstr "E258: No s'ha pogut enviar al client"
+
+msgid "E702: Sort compare function failed"
+msgstr "E702: La funció ordena-compara ha fallat"
+
+msgid "(Invalid)"
+msgstr "(No vàlid)"
+
+msgid "E677: Error writing temp file"
+msgstr "E677: Error en escriure el fitxer temporal"
+
+msgid "E703: Using a Funcref as a Number"
+msgstr "E703: Ús d'una referència de funció com a número"
+
+msgid "E745: Using a List as a Number"
+msgstr "E745: Ús d'una llista com a número"
+
+msgid "E728: Using a Dictionary as a Number"
+msgstr "E728: Ús d'un diccionari com a número"
+
+msgid "E729: using Funcref as a String"
+msgstr "E729: ús d'una referència de funció com a cadena"
+
+msgid "E730: using List as a String"
+msgstr "E730: ús d'una llista com a cadena"
+
+msgid "E731: using Dictionary as a String"
+msgstr "E731: ús d'un diccionari com a cadena"
+
+#, c-format
+msgid "E704: Funcref variable name must start with a capital: %s"
+msgstr "E704: El nom d'una variable Funcref ha de començar en majúscula: %s"
+
+#, c-format
+msgid "E705: Variable name conflicts with existing function: %s"
+msgstr "E705: El nom de la variable entra en conflicte amb una funció existent: %s"
+
+#, c-format
+msgid "E706: Variable type mismatch for: %s"
+msgstr "E706: Tipus de variables no coincidents: %s"
+
+#, c-format
+msgid "E795: Cannot delete variable %s"
+msgstr "E795: No s'ha pogut eliminar la variable %s"
+
+#, c-format
+msgid "E741: Value is locked: %s"
+msgstr "E741: El valor està bloquejat: %s"
+
+msgid "Unknown"
+msgstr "Desconegut"
+
+#, c-format
+msgid "E742: Cannot change value of %s"
+msgstr "E742: No s'ha pogut canviar el valor de %s"
+
+msgid "E698: variable nested too deep for making a copy"
+msgstr "E698: la variable està massa imbricada per fer-ne una còpia"
+
+#, c-format
+msgid "E124: Missing '(': %s"
+msgstr "E124: Falta un '(': %s"
+
+#, c-format
+msgid "E125: Illegal argument: %s"
+msgstr "E125: Argument il·legal: %s"
+
+msgid "E126: Missing :endfunction"
+msgstr "E126: Falta un :endfunction"
+
+#, c-format
+msgid "E746: Function name does not match script file name: %s"
+msgstr "E746: El nom de la funció no coincideix amb el nom de l'script: %s"
+
+msgid "E129: Function name required"
+msgstr "E129: Es necessita un nom de funció"
+
+#, c-format
+msgid "E128: Function name must start with a capital or contain a colon: %s"
+msgstr "E128: El nom de la funció ha de començar en majúscula o contenir dos punts: %s"
+
+#, c-format
+msgid "E131: Cannot delete function %s: It is in use"
+msgstr "E131: No s'ha pogut eliminar la funció %s: S'està utilitzant"
+
+msgid "E132: Function call depth is higher than 'maxfuncdepth'"
+msgstr "E132: Profunditat de crides a funcions superior a 'maxfuncdeptg'"
+
+#, c-format
+msgid "calling %s"
+msgstr "cridant %s"
+
+#, c-format
+msgid "%s aborted"
+msgstr "s'ha avortat %s"
+
+#, c-format
+msgid "%s returning #%ld"
+msgstr "%s ha retornat #%ld"
+
+#, c-format
+msgid "%s returning %s"
+msgstr "%s ha retornat \"%s\""
+
+#, c-format
+msgid "continuing in %s"
+msgstr "continuant a %s"
+
+msgid "E133: :return not inside a function"
+msgstr "E133: :return fora d'una funció"
+
+#, c-format
+msgid ""
+"\n"
+"# global variables:\n"
+msgstr ""
+"\n"
+"# variables globals:\n"
+
+msgid ""
+"\n"
+"\tLast set from "
+msgstr ""
+"\n"
+"\tDefinit per últim cop a "
+
+msgid "Entering Debug mode. Type \"cont\" to continue."
+msgstr "Entrant en mode de depuració. Escriviu \"cont\" per a continuar."
+
+#, c-format
+msgid "line %ld: %s"
+msgstr "línia %ld: %s"
+
+#, c-format
+msgid "cmd: %s"
+msgstr "ordre: %s"
+
+#, c-format
+msgid "Breakpoint in \"%s%s\" line %ld"
+msgstr "Punt de ruptura a \"%s%s\" línia %ld"
+
+#, c-format
+msgid "E161: Breakpoint not found: %s"
+msgstr "E161: Punt de ruptura no trobat: %s"
+
+msgid "No breakpoints defined"
+msgstr "No s'han definit punts de ruptura"
+
+#, c-format
+msgid "%3d %s %s line %ld"
+msgstr "%3d %s %s línia %ld"
+
+msgid "E750: First use :profile start <fname>"
+msgstr "E750: Primer useu :profile start <nomfitxer>"
+
+# Títol d'un diàleg [:browse w]. eac
+msgid "Save As"
+msgstr "Anomena i desa"
+
+#, c-format
+msgid "Save changes to \"%s\"?"
+msgstr "Voleu desar els canvis a \"%s\"?"
+
+msgid "Untitled"
+msgstr "Sense-nom"
+
+#, c-format
+msgid "E162: No write since last change for buffer \"%s\""
+msgstr "E162: No s'han desat els canvis en el buffer \"%s\""
+
+msgid "Warning: Entered other buffer unexpectedly (check autocommands)"
+msgstr "Atenció: S'ha canviat de buffer inesperadament (reviseu les auto-ordres)"
+
+msgid "E163: There is only one file to edit"
+msgstr "E163: Només hi ha un fitxer per editar"
+
+msgid "E164: Cannot go before first file"
+msgstr "E164: No es pot anar més enllà del primer fitxer"
+
+msgid "E165: Cannot go beyond last file"
+msgstr "E165: No es pot anar més enllà de l'últim fitxer"
+
+#, c-format
+msgid "E666: compiler not supported: %s"
+msgstr "E666: el compilador no està suportat: %s"
+
+#, c-format
+msgid "Searching for \"%s\" in \"%s\""
+msgstr "Cercant \"%s\" a \"%s\""
+
+#, c-format
+msgid "Searching for \"%s\""
+msgstr "Cercant \"%s\""
+
+# «runtimepath». eac
+#, c-format
+msgid "not found in 'runtimepath': \"%s\""
+msgstr "no s'ha trobat en el 'runtimepath': \"%s\""
+
+# Títol d'un diàleg [:browse source]. eac
+msgid "Source Vim script"
+msgstr "Interpreta un script Vim"
+
+#, c-format
+msgid "Cannot source a directory: \"%s\""
+msgstr "No es pot interpretar un directori: \"%s\""
+
+#, c-format
+msgid "could not source \"%s\""
+msgstr "no s'ha pogut interpretar \"%s\""
+
+#, c-format
+msgid "line %ld: could not source \"%s\""
+msgstr "línia %ld: no s'ha pogut interpretar \"%s\""
+
+#, c-format
+msgid "sourcing \"%s\""
+msgstr "interpretant \"%s\""
+
+#, c-format
+msgid "line %ld: sourcing \"%s\""
+msgstr "línia %ld: interpretant \"%s\""
+
+#, c-format
+msgid "finished sourcing %s"
+msgstr "ha finalitzat l'interpretació de %s"
+
+msgid "modeline"
+msgstr "modeline"
+
+msgid "--cmd argument"
+msgstr "--cmd argument"
+
+msgid "-c argument"
+msgstr "-c argument"
+
+msgid "environment variable"
+msgstr "variable d'entorn"
+
+msgid "error handler"
+msgstr "gestor d'errors"
+
+msgid "W15: Warning: Wrong line separator, ^M may be missing"
+msgstr "W15: Atenció: El separador de línia no és vàlid, potser falta un ^M"
+
+# «sourced file». eac
+msgid "E167: :scriptencoding used outside of a sourced file"
+msgstr "E167: L'ordre :scriptencoding només es pot utilitzar en scripts"
+
+# «sourced file». eac
+msgid "E168: :finish used outside of a sourced file"
+msgstr "E168: L'ordre :finish només es pot utilitzar en scripts"
+
+# les cadenes substituïdes no es poden traduïr. eac
+#, c-format
+msgid "Current %slanguage: \"%s\""
+msgstr "Idioma actual ( %s): \"%s\""
+
+#, c-format
+msgid "E197: Cannot set language to \"%s\""
+msgstr "E197: No s'ha pogut canviar l'idioma a \"%s\""
+
+# E.G: :ascii
+#, c-format
+msgid "<%s>%s%s %d, Hex %02x, Octal %03o"
+msgstr "<%s>%s%s %d, Hex %02x, Octal %03o"
+
+# E.G: :ascii
+#, c-format
+msgid "> %d, Hex %04x, Octal %o"
+msgstr "> %d, Hex %04x, Octal %o"
+
+# E.G: :ascii
+#, c-format
+msgid "> %d, Hex %08x, Octal %o"
+msgstr "> %d, Hex %08x, Octal %o"
+
+msgid "E134: Move lines into themselves"
+msgstr "E134: No es poden moure línies cap a elles mateixes"
+
+msgid "1 line moved"
+msgstr "1 línia desplaçada"
+
+#, c-format
+msgid "%ld lines moved"
+msgstr "%ld línies desplaçades"
+
+#, c-format
+msgid "%ld lines filtered"
+msgstr "%ld línies filtrades"
+
+msgid "E135: *Filter* Autocommands must not change current buffer"
+msgstr "E135: Les auto-ordres *Filter* no poden canviar el buffer actual"
+
+msgid "[No write since last change]\n"
+msgstr "[No s'han desat els últims canvis]\n"
+
+#, c-format
+msgid "%sviminfo: %s in line: "
+msgstr "%sviminfo: %s a la línia: "
+
+msgid "E136: viminfo: Too many errors, skipping rest of file"
+msgstr "E136: viminfo: Hi ha massa errors, s'omet la resta del fitxer"
+
+# les tres següents van juntes. eac
+#, c-format
+msgid "Reading viminfo file \"%s\"%s%s%s"
+msgstr "Llegint el fitxer viminfo \"%s\"%s%s%s"
+
+msgid " info"
+msgstr " per info"
+
+msgid " marks"
+msgstr " per marques"
+
+msgid " FAILED"
+msgstr " ERROR"
+
+#. avoid a wait_return for this message, it's annoying
+#, c-format
+msgid "E137: Viminfo file is not writable: %s"
+msgstr "E137: El fitxer viminfo no és modificable: %s"
+
+#, c-format
+msgid "E138: Can't write viminfo file %s!"
+msgstr "E138: No s'ha pogut escriure el fitxer viminfo %s!"
+
+#, c-format
+msgid "Writing viminfo file \"%s\""
+msgstr "Escrivint el fitxer viminfo \"%s\""
+
+#. Write the info:
+#, c-format
+msgid "# This viminfo file was generated by Vim %s.\n"
+msgstr "# Aquest fitxer viminfo ha estat generat pel Vim %s.\n"
+
+#, c-format
+msgid ""
+"# You may edit it if you're careful!\n"
+"\n"
+msgstr ""
+"# El podeu editar si aneu amb compte!\n"
+"\n"
+
+#, c-format
+msgid "# Value of 'encoding' when this file was written\n"
+msgstr "# Valor de 'encoding' en el moment d'escriure aquest fitxer\n"
+
+msgid "Illegal starting char"
+msgstr "Caràcter inicial il·legal"
+
+msgid "Write partial file?"
+msgstr "Voleu escriure un fitxer parcial?"
+
+msgid "E140: Use ! to write partial buffer"
+msgstr "E140: Useu ! per desar una part del buffer"
+
+#, c-format
+msgid "Overwrite existing file \"%s\"?"
+msgstr "Voleu sobrescriure el fitxer existent \"%s\"?"
+
+#, c-format
+msgid "Swap file \"%s\" exists, overwrite anyway?"
+msgstr "El fitxer d'intercanvi \"%s\" existeix, sobreescriure igualment?"
+
+#, c-format
+msgid "E768: Swap file exists: %s (:silent! overrides)"
+msgstr "E768: El fitxer d'intercanvi existeix: %s (:silent! per a confirmar)"
+
+#, c-format
+msgid "E141: No file name for buffer %ld"
+msgstr "E141: No hi ha nom de fitxer per al buffer %ld"
+
+msgid "E142: File not written: Writing is disabled by 'write' option"
+msgstr "E142: No s'ha escrit el fitxer: L'opció 'write' ho impedeix"
+
+#, c-format
+msgid ""
+"'readonly' option is set for \"%s\".\n"
+"Do you wish to write anyway?"
+msgstr ""
+"L'opció 'readonly' està definida per a \"%s\".\n"
+"Voleu escriure de totes maneres?"
+
+# és un títol de diàleg [:browse edit]. eac
+msgid "Edit File"
+msgstr "Edita un fitxer"
+
+#, c-format
+msgid "E143: Autocommands unexpectedly deleted new buffer %s"
+msgstr "E143: Una auto-ordre ha eliminat el buffer nou %s inesperadament"
+
+msgid "E144: non-numeric argument to :z"
+msgstr "E144: Argument no numèric per a :z"
+
+msgid "E145: Shell commands not allowed in rvim"
+msgstr "E145: Les ordres shell no estan permeses en l'rvim"
+
+msgid "E146: Regular expressions can't be delimited by letters"
+msgstr "E146: Les expressions regulars no poden estar delimitades per lletres"
+
+# «amb» o «per» + tecles. eac
+#, c-format
+msgid "replace with %s (y/n/a/q/l/^E/^Y)?"
+msgstr "substituir amb %s (y/n/a/q/l/^E/^Y)?"
+
+msgid "(Interrupted) "
+msgstr "(Interromput) "
+
+msgid "1 match"
+msgstr "1 coincidència "
+
+msgid "1 substitution"
+msgstr "1 substitució"
+
+#, c-format
+msgid "%ld matches"
+msgstr "%ld coincidències"
+
+#, c-format
+msgid "%ld substitutions"
+msgstr "%ld substitucions"
+
+msgid " on 1 line"
+msgstr " en 1 línia"
+
+#, c-format
+msgid " on %ld lines"
+msgstr " en %ld línies"
+
+msgid "E147: Cannot do :global recursive"
+msgstr "E147: No es pot executar una ordre global de forma recursiva"
+
+msgid "E148: Regular expression missing from global"
+msgstr "E148: Les ordres globals requereixen una expressió regular"
+
+#, c-format
+msgid "Pattern found in every line: %s"
+msgstr "S'ha trobat el patró a cada línia: %s"
+
+#, c-format
+msgid ""
+"\n"
+"# Last Substitute String:\n"
+"$"
+msgstr ""
+"\n"
+"# Última cadena substituïda:\n"
+"$"
+
+msgid "E478: Don't panic!"
+msgstr "E478: Calma!"
+
+#, c-format
+msgid "E661: Sorry, no '%s' help for %s"
+msgstr "E661: No hi ha ajuda en '%s' per a %s"
+
+#, c-format
+msgid "E149: Sorry, no help for %s"
+msgstr "E149: No hi ha ajuda per %s"
+
+#, c-format
+msgid "Sorry, help file \"%s\" not found"
+msgstr "El fitxer d'ajuda \"%s\" no s'ha trobat"
+
+#, c-format
+msgid "E150: Not a directory: %s"
+msgstr "E150: No és un directori: %s"
+
+#, c-format
+msgid "E152: Cannot open %s for writing"
+msgstr "E152: No s'ha pogut obrir %s amb permís d'escriptura"
+
+#, c-format
+msgid "E153: Unable to open %s for reading"
+msgstr "E153: No s'ha pogut obrir %s amb permís de lectura"
+
+#, c-format
+msgid "E670: Mix of help file encodings within a language: %s"
+msgstr "E670: Conjunts de caràcters diferents dins del mateix idioma: %s"
+
+#, c-format
+msgid "E154: Duplicate tag \"%s\" in file %s/%s"
+msgstr "E154: L'etiqueta \"%s\" està duplicada en el fitxer %s/%s"
+
+#, c-format
+msgid "E160: Unknown sign command: %s"
+msgstr "E160: Ordre de senyalització desconeguda: %s"
+
+msgid "E156: Missing sign name"
+msgstr "E156: Falta el nom del senyal"
+
+msgid "E612: Too many signs defined"
+msgstr "E612: S'han definit massa senyals"
+
+#, c-format
+msgid "E239: Invalid sign text: %s"
+msgstr "E239: El text del senyal no és vàlid: %s"
+
+#, c-format
+msgid "E155: Unknown sign: %s"
+msgstr "E155: El senyal és desconegut: %s"
+
+msgid "E159: Missing sign number"
+msgstr "E159: Falta el número del senyal"
+
+#, c-format
+msgid "E158: Invalid buffer name: %s"
+msgstr "E158: El nom del buffer no és vàlid: %s"
+
+#, c-format
+msgid "E157: Invalid sign ID: %ld"
+msgstr "E157: L'ID del senyal no és vàlida: %ld"
+
+msgid " (NOT FOUND)"
+msgstr " (NO TROBAT)"
+
+msgid " (not supported)"
+msgstr " (no suportat)"
+
+msgid "[Deleted]"
+msgstr "[Eliminat]"
+
+msgid "Entering Ex mode. Type \"visual\" to go to Normal mode."
+msgstr "Mode Ex. Escriviu \"visual\" per tornar al mode Normal."
+
+msgid "E501: At end-of-file"
+msgstr "E501: Final del fitxer"
+
+msgid "E169: Command too recursive"
+msgstr "E169: L'ordre és massa recursiva"
+
+#, c-format
+msgid "E605: Exception not caught: %s"
+msgstr "E605: No s'ha interceptat l'excepció: %s"
+
+msgid "End of sourced file"
+msgstr "Final del fitxer interpretat"
+
+msgid "End of function"
+msgstr "Final de la funció"
+
+msgid "E464: Ambiguous use of user-defined command"
+msgstr "E464: Ús ambigu d'una ordre definida per l'usuari"
+
+msgid "E492: Not an editor command"
+msgstr "E492: No és una ordre d'edició"
+
+msgid "E493: Backwards range given"
+msgstr "E493: Heu especificat un interval decreixent"
+
+# és una pregunta. eac
+msgid "Backwards range given, OK to swap"
+msgstr "Heu especificat un interval decreixent. El voleu invertir"
+
+msgid "E494: Use w or w>>"
+msgstr "E494: Useu w o bé w>>"
+
+msgid "E319: Sorry, the command is not available in this version"
+msgstr "E319: Aquesta ordre no està disponible en aquesta versió"
+
+msgid "E172: Only one file name allowed"
+msgstr "E172: Només està permès un nom de fitxer"
+
+msgid "1 more file to edit. Quit anyway?"
+msgstr "Queda 1 fitxer per editar. Voleu sortir de totes maneres?"
+
+#, c-format
+msgid "%d more files to edit. Quit anyway?"
+msgstr "Queden %d fitxers per editar. Voleu sortir de totes maneres?"
+
+msgid "E173: 1 more file to edit"
+msgstr "E173: Queda 1 fitxer per editar"
+
+#, c-format
+msgid "E173: %ld more files to edit"
+msgstr "E173: Queden %ld fitxers per editar"
+
+msgid "E174: Command already exists: add ! to replace it"
+msgstr "E174: L'ordre ja existeix: afegiu ! per substituir-la"
+
+msgid ""
+"\n"
+" Name Args Range Complete Definition"
+msgstr ""
+"\n"
+" Nom Args Abast Completar Definició"
+
+msgid "No user-defined commands found"
+msgstr "No s'han trobat ordres definides per l'usuari"
+
+msgid "E175: No attribute specified"
+msgstr "E175: No heu especificat cap atribut"
+
+msgid "E176: Invalid number of arguments"
+msgstr "E176: El nombre d'arguments no és vàlid"
+
+msgid "E177: Count cannot be specified twice"
+msgstr "E177: El comptador no es pot especificar dos cops"
+
+msgid "E178: Invalid default value for count"
+msgstr "E178: El valor per omissió del comptador no és vàlid"
+
+# «completar» eac
+msgid "E179: argument required for -complete"
+msgstr "E179: -complete requereix un argument"
+
+#, c-format
+msgid "E181: Invalid attribute: %s"
+msgstr "E181: L'atribut no és vàlid: %s"
+
+msgid "E182: Invalid command name"
+msgstr "E182: El nom de l'ordre no és vàlid"
+
+msgid "E183: User defined commands must start with an uppercase letter"
+msgstr "E183: Les ordres definides per l'usuari han de començar en majúscula"
+
+#, c-format
+msgid "E184: No such user-defined command: %s"
+msgstr "E184: No existeix tal ordre definida per l'usuari: %s"
+
+# «completar» eac
+#, c-format
+msgid "E180: Invalid complete value: %s"
+msgstr "E180: El valor per la funció completar no és vàlid: %s"
+
+# «completar» eac
+msgid "E468: Completion argument only allowed for custom completion"
+msgstr "E468: L'argument de completar només està permès en esquemes personalitzats"
+
+# «completar» eac
+msgid "E467: Custom completion requires a function argument"
+msgstr "E467: Els esquemes de completar requereixen una funció com a argument"
+
+#, c-format
+msgid "E185: Cannot find color scheme %s"
+msgstr "E185: No s'ha trobat l'esquema de colors %s"
+
+msgid "Greetings, Vim user!"
+msgstr "Salutacions, usuari de Vim!"
+
+msgid "E784: Cannot close last tab page"
+msgstr "E784: No es pot tancar l'última pestanya"
+
+msgid "Already only one tab page"
+msgstr "Només hi ha una pestanya"
+
+# Títol d'un diàleg [:browse split] eac
+msgid "Edit File in new window"
+msgstr "Edita un fitxer en una finestra nova"
+
+#, c-format
+msgid "Tab page %d"
+msgstr "Pestanya %d"
+
+msgid "No swap file"
+msgstr "No hi ha fitxer d'intercanvi"
+
+# És un títol d'un diàleg [:browse read] eac
+msgid "Append File"
+msgstr "Afegeix un fitxer"
+
+msgid "E747: Cannot change directory, buffer is modifed (add ! to override)"
+msgstr "E747: No es pot canviar de directori, el buffer ha estat modificat (afegiu ! per confirmar)"
+
+msgid "E186: No previous directory"
+msgstr "E186: No hi ha cap directori anterior"
+
+msgid "E187: Unknown"
+msgstr "E187: Desconegut"
+
+msgid "E465: :winsize requires two number arguments"
+msgstr "E465: L'ordre :winsize requereix dos arguments numèrics"
+
+#, c-format
+msgid "Window position: X %d, Y %d"
+msgstr "Posició de la finestra: X %d, Y %d"
+
+msgid "E188: Obtaining window position not implemented for this platform"
+msgstr "E188: En aquesta plataforma no es pot obtenir la posició de la finestra"
+
+msgid "E466: :winpos requires two number arguments"
+msgstr "E466: L'ordre :winpos requereix dos arguments numèrics"
+
+# És el títol d'un diàleg. eac
+msgid "Save Redirection"
+msgstr "Desa la redirecció"
+
+# És el títol d'un diàleg. eac
+msgid "Save View"
+msgstr "Desa la vista"
+
+# És el títol d'un diàleg. eac
+msgid "Save Session"
+msgstr "Desa la sessió"
+
+# És el títol d'un diàleg. eac
+msgid "Save Setup"
+msgstr "Desa la configuració"
+
+#, c-format
+msgid "E739: Cannot create directory: %s"
+msgstr "E739: No s'ha pogut crear el directori: %s"
+
+#, c-format
+msgid "E189: \"%s\" exists (add ! to override)"
+msgstr "E189: \"%s\" existeix (afegiu ! per confirmar)"
+
+#, c-format
+msgid "E190: Cannot open \"%s\" for writing"
+msgstr "E190: No s'ha pogut obrir \"%s\" amb permís d'escriptura"
+
+#. set mark
+msgid "E191: Argument must be a letter or forward/backward quote"
+msgstr "E191: L'argument ha de ser una lletra o bé un accent obert o tancat"
+
+msgid "E192: Recursive use of :normal too deep"
+msgstr "E192: Ús recursiu de :normal massa profund"
+
+msgid "E194: No alternate file name to substitute for '#'"
+msgstr "E194: No hi ha cap nom de fitxer alternatiu per substituir '#'"
+
+msgid "E495: no autocommand file name to substitute for \"<afile>\""
+msgstr "E495: No hi ha cap nom de fitxer d'auto-ordres per substituir \"<afile>\""
+
+msgid "E496: no autocommand buffer number to substitute for \"<abuf>\""
+msgstr "E496: No hi ha cap nombre de buffer d'auto-ordres per substituir \"<abuf>\""
+
+msgid "E497: no autocommand match name to substitute for \"<amatch>\""
+msgstr "E497: No hi ha cap nom d'auto-ordre per substituir \"<amatch>\""
+
+msgid "E498: no :source file name to substitute for \"<sfile>\""
+msgstr "E498: No hi ha cap script per substituir \"<sfile>\""
+
+#, no-c-format
+msgid "E499: Empty file name for '%' or '#', only works with \":p:h\""
+msgstr "E499: El nom de fitxer per '%' o '#' està buit, només funciona amb \":p:h\""
+
+msgid "E500: Evaluates to an empty string"
+msgstr "E500: S'evalua com a cadena buida"
+
+msgid "E195: Cannot open viminfo file for reading"
+msgstr "E195: No s'ha pogut obrir el fitxer viminfo amb permís de lectura"
+
+msgid "E196: No digraphs in this version"
+msgstr "E196: Aquesta versió no suporta dígrafs"
+
+msgid "E608: Cannot :throw exceptions with 'Vim' prefix"
+msgstr "E608: No es poden generar exepcions amb el prefix 'Vim'"
+
+#. always scroll up, don't overwrite
+#, c-format
+msgid "Exception thrown: %s"
+msgstr "Excepció generada: %s"
+
+#, c-format
+msgid "Exception finished: %s"
+msgstr "Exepció finalitzada: %s"
+
+#, c-format
+msgid "Exception discarded: %s"
+msgstr "Exepció descartada: %s"
+
+#, c-format
+msgid "%s, line %ld"
+msgstr "%s, línia %ld"
+
+#. always scroll up, don't overwrite
+#, c-format
+msgid "Exception caught: %s"
+msgstr "Excepció interceptada: %s"
+
+#, c-format
+msgid "%s made pending"
+msgstr "%s està pendent"
+
+#, c-format
+msgid "%s resumed"
+msgstr "%s s'ha continuat"
+
+#, c-format
+msgid "%s discarded"
+msgstr "%s s'ha descartat"
+
+msgid "Exception"
+msgstr "Exepció"
+
+msgid "Error and interrupt"
+msgstr "Error i interrupció"
+
+msgid "Error"
+msgstr "Error"
+
+#. if (pending & CSTP_INTERRUPT)
+msgid "Interrupt"
+msgstr "Interrupció"
+
+msgid "E579: :if nesting too deep"
+msgstr "E579: Imbricació de :if massa profunda"
+
+msgid "E580: :endif without :if"
+msgstr "E580: Declaració :endif sense :if"
+
+msgid "E581: :else without :if"
+msgstr "E581: Declaració :else sense :if"
+
+msgid "E582: :elseif without :if"
+msgstr "E582: Declaració :elseif sense :if"
+
+msgid "E583: multiple :else"
+msgstr "E583: Múltiples :else"
+
+msgid "E584: :elseif after :else"
+msgstr "E584: Declaració :elseif després de :else"
+
+msgid "E585: :while/:for nesting too deep"
+msgstr "E585: Imbricació de :while/:for massa profunda"
+
+msgid "E586: :continue without :while or :for"
+msgstr "E586: :continue sense :while o :for"
+
+msgid "E587: :break without :while or :for"
+msgstr "E587: :break sense :while"
+
+msgid "E732: Using :endfor with :while"
+msgstr "E732: Ús incorrecte de :endfor amb :while"
+
+msgid "E733: Using :endwhile with :for"
+msgstr "E733: Ús incorrecte de :endwhile amb :for"
+
+msgid "E601: :try nesting too deep"
+msgstr "E601: Imbricació de :try massa profunda"
+
+msgid "E603: :catch without :try"
+msgstr "E603: Declaració :catch sense :try"
+
+#. Give up for a ":catch" after ":finally" and ignore it.
+#. * Just parse.
+msgid "E604: :catch after :finally"
+msgstr "E604: Declaració :catch després de :finally"
+
+msgid "E606: :finally without :try"
+msgstr "E606: Declaració :finally sense :try"
+
+#. Give up for a multiple ":finally" and ignore it.
+msgid "E607: multiple :finally"
+msgstr "E607: Múltiples :finally"
+
+msgid "E602: :endtry without :try"
+msgstr "E602: Declaració :endtry sense :try"
+
+msgid "E193: :endfunction not inside a function"
+msgstr "E193: Declaració :endfunction fora d'una funció"
+
+msgid "E788: Not allowed to edit another buffer now"
+msgstr "E788: No podeu editar un altre buffer ara"
+
+# context? eac
+msgid "tagname"
+msgstr "nom de l'etiqueta"
+
+# context? eac
+msgid " kind file\n"
+msgstr " tipus de fitxer\n"
+
+msgid "'history' option is zero"
+msgstr "l'opció 'history' és zero"
+
+#, c-format
+msgid ""
+"\n"
+"# %s History (newest to oldest):\n"
+msgstr ""
+"\n"
+"# Historial %s (de més a menys recent):\n"
+
+msgid "Command Line"
+msgstr "d'ordres"
+
+msgid "Search String"
+msgstr "de cadenes cercades"
+
+msgid "Expression"
+msgstr "d'expressions"
+
+msgid "Input Line"
+msgstr "de línies d'entrada"
+
+msgid "E198: cmd_pchar beyond the command length"
+msgstr "E198: cmd_pchar fora de l'àrea de l'ordre"
+
+msgid "E199: Active window or buffer deleted"
+msgstr "E199: S'ha eliminat la finestra o el buffer actiu"
+
+msgid "Illegal file name"
+msgstr "El nom de fitxer és il·legal"
+
+msgid "is a directory"
+msgstr "és un directori"
+
+msgid "is not a file"
+msgstr "no és un fitxer"
+
+msgid "is a device (disabled with 'opendevice' option"
+msgstr "és un dispositiu (deshabilitat amb l'opció 'opendevice'"
+
+msgid "[New File]"
+msgstr "[Fitxer nou]"
+
+msgid "[New DIRECTORY]"
+msgstr "[Nou DIRECTORI]"
+
+msgid "[File too big]"
+msgstr "[Fitxer massa gran]"
+
+msgid "[Permission Denied]"
+msgstr "[Permís denegat]"
+
+msgid "E200: *ReadPre autocommands made the file unreadable"
+msgstr "E200: Auto-ordres *ReadPre han deixat el fitxer illegible"
+
+msgid "E201: *ReadPre autocommands must not change current buffer"
+msgstr "E201: Les auto-ordres *ReadPre no poden canviar el buffer actual"
+
+msgid "Vim: Reading from stdin...\n"
+msgstr "Vim: Llegint l'entrada estàndard...\n"
+
+msgid "Reading from stdin..."
+msgstr "Llegint l'entrada estàndard..."
+
+#. Re-opening the original file failed!
+msgid "E202: Conversion made file unreadable!"
+msgstr "E202: La conversió ha deixat el fitxer illegible!"
+
+msgid "[fifo/socket]"
+msgstr "[fifo/socket]"
+
+msgid "[fifo]"
+msgstr "[fifo]"
+
+msgid "[socket]"
+msgstr "[socket]"
+
+# eac només-lectura (nl)
+msgid "[RO]"
+msgstr "[NL]"
+
+msgid "[CR missing]"
+msgstr "[falten caràcters CR]"
+
+# entra en conflicte amb NL (només lectura)
+msgid "[NL found]"
+msgstr "[s'han trobat caràcters NL]"
+
+msgid "[long lines split]"
+msgstr "[línies llargues partides]"
+
+msgid "[NOT converted]"
+msgstr "[NO convertit]"
+
+msgid "[converted]"
+msgstr "[convertit]"
+
+msgid "[crypted]"
+msgstr "[xifrat]"
+
+#, c-format
+msgid "[CONVERSION ERROR in line %ld]"
+msgstr "[ERROR DE CONVERSIÓ a la línia %ld]"
+
+#, c-format
+msgid "[ILLEGAL BYTE in line %ld]"
+msgstr "[OCTET IL·LEGAL a la línia %ld]"
+
+msgid "[READ ERRORS]"
+msgstr "[ERRORS DE LECTURA]"
+
+msgid "Can't find temp file for conversion"
+msgstr "No s'ha trobat el fitxer temporal per la conversió"
+
+msgid "Conversion with 'charconvert' failed"
+msgstr "La conversió amb 'charconvert' ha fallat"
+
+msgid "can't read output of 'charconvert'"
+msgstr "No s'ha pogut llegir la sortida de 'charconvert'"
+
+msgid "E676: No matching autocommands for acwrite buffer"
+msgstr "E676: No hi ha cap auto-ordre coincident per al buffer acwrite"
+
+msgid "E203: Autocommands deleted or unloaded buffer to be written"
+msgstr "E203: Auto-ordres han eliminat o alliberat el buffer a escriure"
+
+msgid "E204: Autocommand changed number of lines in unexpected way"
+msgstr "E204: Una auto-ordre ha canviat el nombre de línies de forma inesperada"
+
+msgid "NetBeans disallows writes of unmodified buffers"
+msgstr "NetBeans no permet escriure buffers no modificats"
+
+msgid "Partial writes disallowed for NetBeans buffers"
+msgstr "L'escriptura parcial no està permesa en buffers NetBeans"
+
+msgid "is not a file or writable device"
+msgstr "no és un fitxer o dispositiu que es pugui escriure"
+
+msgid "writing to device disabled with 'opendevice' option"
+msgstr "escriptura a un dispositiu deshabilitat amb l'opció 'opendevice'"
+
+msgid "is read-only (add ! to override)"
+msgstr "és un fitxer de només lectura (afegiu ! per confirmar)"
+
+msgid "E506: Can't write to backup file (add ! to override)"
+msgstr "E506: No s'ha pogut escriure la còpia de seguretat (afegiu ! per confirmar)"
+
+msgid "E507: Close error for backup file (add ! to override)"
+msgstr "E507: Error en tancar el fitxer còpia de seguretat (afegiu ! per confirmar)"
+
+msgid "E508: Can't read file for backup (add ! to override)"
+msgstr "E508: Error de lectura en fer la còpia de seguretat (afegiu ! per confirmar)"
+
+msgid "E509: Cannot create backup file (add ! to override)"
+msgstr "E509: No s'ha pogut crear la còpia de seguretat (afegiu ! per confirmar)"
+
+msgid "E510: Can't make backup file (add ! to override)"
+msgstr "E510: No s'ha pogut fer la còpia de seguretat (afegiu ! per confirmar)"
+
+# «resource fork» (MacOS) ?
+msgid "E460: The resource fork would be lost (add ! to override)"
+msgstr "E460: La bifurcació de recursos es perdrà (afegiu ! per confirmar)"
+
+msgid "E214: Can't find temp file for writing"
+msgstr "E214: No s'ha trobat el fitxer temporal per escriure-hi"
+
+msgid "E213: Cannot convert (add ! to write without conversion)"
+msgstr "E213: No s'ha pogut convertir (afegiu ! per desar sense conversió)"
+
+msgid "E166: Can't open linked file for writing"
+msgstr "E166: No s'ha pogut obrir el fitxer enllaçat per escriure-hi"
+
+msgid "E212: Can't open file for writing"
+msgstr "E212: No s'ha pogut obrir el fitxer amb permís d'escriptura"
+
+msgid "E667: Fsync failed"
+msgstr "E667: Fsync ha fallat"
+
+msgid "E512: Close failed"
+msgstr "E512: Error en tancar"
+
+msgid "E513: write error, conversion failed (make 'fenc' empty to override)"
+msgstr "E513: error d'escriptura, conversió fallida (anul·leu 'fenc' per a ometre)"
+
+msgid "E514: write error (file system full?)"
+msgstr "E514: Error d'escriptura (sistema de fitxers ple?)"
+
+msgid " CONVERSION ERROR"
+msgstr " ERROR DE CONVERSIÓ"
+
+msgid "[Device]"
+msgstr "[Dispositiu]"
+
+msgid "[New]"
+msgstr "[Nou]"
+
+msgid " [a]"
+msgstr " [a]"
+
+msgid " appended"
+msgstr " afegits"
+
+msgid " [w]"
+msgstr " [e]"
+
+msgid " written"
+msgstr " escrits"
+
+msgid "E205: Patchmode: can't save original file"
+msgstr "E205: patchmode: no s'ha pogut desar el fitxer original"
+
+msgid "E206: patchmode: can't touch empty original file"
+msgstr "E206: patchmode: no s'ha pogut tocar el fitxer original buit"
+
+msgid "E207: Can't delete backup file"
+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"
+
+msgid "don't quit the editor until the file is successfully written!"
+msgstr "no sortiu de l'editor fins que s'hagi desat el fitxer amb èxit!"
+
+msgid "[dos]"
+msgstr "[dos]"
+
+msgid "[dos format]"
+msgstr "[format dos]"
+
+msgid "[mac]"
+msgstr "[mac]"
+
+msgid "[mac format]"
+msgstr "[format mac]"
+
+msgid "[unix]"
+msgstr "[unix]"
+
+msgid "[unix format]"
+msgstr "[format unix]"
+
+msgid "1 line, "
+msgstr "1 línia, "
+
+#, c-format
+msgid "%ld lines, "
+msgstr "%ld línies, "
+
+msgid "1 character"
+msgstr "1 caràcter"
+
+#, c-format
+msgid "%ld characters"
+msgstr "%ld caràcters"
+
+# «no final de línia» eac
+msgid "[noeol]"
+msgstr "[nofl]"
+
+msgid "[Incomplete last line]"
+msgstr "[Última línia incompleta]"
+
+#. 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 "ATENCIÓ: El fitxer ha canviat des de que s'ha llegit!!!"
+
+# pregunta ask_yesno() eac
+msgid "Do you really want to write to it"
+msgstr "Esteu segurs que voleu escriure'l"
+
+#, c-format
+msgid "E208: Error writing to \"%s\""
+msgstr "E208: Error en escriure \"%s\""
+
+#, c-format
+msgid "E209: Error closing \"%s\""
+msgstr "E209: Error en tancar \"%s\""
+
+#, c-format
+msgid "E210: Error reading \"%s\""
+msgstr "E210: Error en llegir \"%s\""
+
+msgid "E246: FileChangedShell autocommand deleted buffer"
+msgstr "E246: L'auto-ordre FileChangedShell ha eliminat el buffer"
+
+#, c-format
+msgid "E211: File \"%s\" no longer available"
+msgstr "E211: El fitxer \"%s\" ha deixat d'estar disponible"
+
+#, c-format
+msgid "W12: Warning: File \"%s\" has changed and the buffer was changed in Vim as well"
+msgstr "W12: Atenció: Tant el fitxer \"%s\" com el buffer del Vim han canviat"
+
+msgid "See \":help W12\" for more info."
+msgstr "Vegeu \":help W12\" per a més info."
+
+# massa llarg? eac
+#, c-format
+msgid "W11: Warning: File \"%s\" has changed since editing started"
+msgstr "W11: Atenció: El fitxer \"%s\" ha canviat des de que s'ha començat a editar"
+
+msgid "See \":help W11\" for more info."
+msgstr "Vegeu \":help W11\" per a més info."
+
+# massa llarg? eac
+#, c-format
+msgid "W16: Warning: Mode of file \"%s\" has changed since editing started"
+msgstr "W16: Atenció: Els permisos de \"%s\" han canviat des que s'ha començat a editar"
+
+msgid "See \":help W16\" for more info."
+msgstr "Vegeu \":help W16\" per a més info."
+
+# massa llarg? eac
+#, c-format
+msgid "W13: Warning: File \"%s\" has been created after editing started"
+msgstr "W13: Atenció: El fitxer \"%s\" ha estat creat després que s'ha començat a editar"
+
+msgid "Warning"
+msgstr "Atenció"
+
+msgid ""
+"&OK\n"
+"&Load File"
+msgstr ""
+"&D'acord\n"
+"&Carrega el fitxer"
+
+#, c-format
+msgid "E462: Could not prepare for reloading \"%s\""
+msgstr "E462: No s'han pogut fer les preparacions per rellegir \"%s\""
+
+#, c-format
+msgid "E321: Could not reload \"%s\""
+msgstr "E321: No s'ha pogut rellegir \"%s\""
+
+msgid "--Deleted--"
+msgstr "--Eliminat--"
+
+#, c-format
+msgid "auto-removing autocommand: %s <buffer=%d>"
+msgstr "auto-eliminant auto-ordre: %s <buffer=%d>"
+
+#. the group doesn't exist
+#, c-format
+msgid "E367: No such group: \"%s\""
+msgstr "E367: No existeix tal grup: \"%s\""
+
+#, c-format
+msgid "E215: Illegal character after *: %s"
+msgstr "E215: Caràcter il·legal després de *: %s"
+
+#, c-format
+msgid "E216: No such event: %s"
+msgstr "E216: No existeix tal esdeveniment: %s"
+
+#, c-format
+msgid "E216: No such group or event: %s"
+msgstr "E216: No existeix tal grup o esdeveniment: %s"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Auto-Commands ---"
+msgstr ""
+"\n"
+"--- Auto-ordres ---"
+
+#, c-format
+msgid "E680: <buffer=%d>: invalid buffer number "
+msgstr "E680: <buffer=%d>: número de buffer no vàlid"
+
+msgid "E217: Can't execute autocommands for ALL events"
+msgstr "E217: No es poden executar auto-ordres per TOTS els esdeveniments"
+
+msgid "No matching autocommands"
+msgstr "No coincideix cap auto-ordre"
+
+msgid "E218: autocommand nesting too deep"
+msgstr "E218: Imbricació d'auto-ordres massa profunda"
+
+#, c-format
+msgid "%s Auto commands for \"%s\""
+msgstr "auto-ordres %s per \"%s\""
+
+#, c-format
+msgid "Executing %s"
+msgstr "Executant %s"
+
+#, c-format
+msgid "autocommand %s"
+msgstr "auto-ordre %s"
+
+msgid "E219: Missing {."
+msgstr "E219: Falta un {."
+
+msgid "E220: Missing }."
+msgstr "E220: Falta un }."
+
+msgid "E490: No fold found"
+msgstr "E490: No s'ha trobat cap plec"
+
+msgid "E350: Cannot create fold with current 'foldmethod'"
+msgstr "E350: No es pot crear cap plec amb el 'foldmethod' actual"
+
+msgid "E351: Cannot delete fold with current 'foldmethod'"
+msgstr "E351: No pot eliminar el plec amb el 'foldmethod' actual"
+
+#, c-format
+msgid "+--%3ld lines folded "
+msgstr "+--%3ld línies plegades "
+
+msgid "E222: Add to read buffer"
+msgstr "E222: No es pot modificar un buffer de lectura"
+
+msgid "E223: recursive mapping"
+msgstr "E223: assignació recursiva"
+
+#, c-format
+msgid "E224: global abbreviation already exists for %s"
+msgstr "E224: ja existeix una abreviació global per %s"
+
+#, c-format
+msgid "E225: global mapping already exists for %s"
+msgstr "E225: ja existeix una assignació global per %s"
+
+#, c-format
+msgid "E226: abbreviation already exists for %s"
+msgstr "E226: ja existeix una abreviació per %s"
+
+#, c-format
+msgid "E227: mapping already exists for %s"
+msgstr "E227: ja existeix una assignació per %s"
+
+msgid "No abbreviation found"
+msgstr "No s'ha trobat cap abreviació"
+
+msgid "No mapping found"
+msgstr "No s'ha trobat cap assignació"
+
+msgid "E228: makemap: Illegal mode"
+msgstr "E228: makemap: Mode il·legal"
+
+msgid "<cannot open> "
+msgstr "<no es pot obrir> "
+
+#, c-format
+msgid "E616: vim_SelFile: can't get font %s"
+msgstr "E616: vim_SelFile: no s'ha pogut obtenir la fosa %s"
+
+msgid "E614: vim_SelFile: can't return to current directory"
+msgstr "E614: vim_SelFile: no s'ha pogut tornar al directori actual"
+
+msgid "Pathname:"
+msgstr "Ubicació:"
+
+msgid "E615: vim_SelFile: can't get current directory"
+msgstr "E615: vim_SelFile: no s'ha pogut obtenir el directori actual"
+
+msgid "OK"
+msgstr "D'acord"
+
+msgid "Cancel"
+msgstr "Cancel·la"
+
+msgid "Vim dialog"
+msgstr "Diàleg del Vim"
+
+msgid "Scrollbar Widget: Could not get geometry of thumb pixmap."
+msgstr "Barra de desplaçament: No s'ha pogut obtenir la mida del mapa de bits."
+
+msgid "E232: Cannot create BalloonEval with both message and callback"
+msgstr "E232: No es pot crear un BalloonEval amb missatge i callback alhora"
+
+msgid "E229: Cannot start the GUI"
+msgstr "E229: No s'ha pogut iniciar l'interfície gràfica"
+
+#, c-format
+msgid "E230: Cannot read from \"%s\""
+msgstr "E230: No s'ha pogut llegir \"%s\""
+
+msgid "E665: Cannot start GUI, no valid font found"
+msgstr "E665: No es pot iniciar l'IUG, no s'ha trobat cap fosa vàlida"
+
+msgid "E231: 'guifontwide' invalid"
+msgstr "E231: El valor de 'guifontwide' no és vàlid"
+
+msgid "E599: Value of 'imactivatekey' is invalid"
+msgstr "E599: El valor de 'imactivatekey' no és vàlid"
+
+#, c-format
+msgid "E254: Cannot allocate color %s"
+msgstr "E254: No s'ha pogut assignar memòria pel color %s"
+
+msgid "No match at cursor, finding next"
+msgstr "Cap coincidència al cursor, cercant la següent"
+
+msgid "Vim dialog..."
+msgstr "Diàleg del Vim..."
+
+msgid ""
+"&Yes\n"
+"&No\n"
+"&Cancel"
+msgstr ""
+"&Sí\n"
+"&No\n"
+"&Cancel·la"
+
+msgid "Input _Methods"
+msgstr "_Mètodes d'entrada"
+
+msgid "VIM - Search and Replace..."
+msgstr "VIM - Cerca i substitueix..."
+
+msgid "VIM - Search..."
+msgstr "VIM - Cerca..."
+
+msgid "Find what:"
+msgstr "Cerca:"
+
+msgid "Replace with:"
+msgstr "Substituieix amb:"
+
+#. whole word only button
+msgid "Match whole word only"
+msgstr "Només paraules senceres"
+
+#. match case button
+msgid "Match case"
+msgstr "Sensible a les majúscules"
+
+msgid "Direction"
+msgstr "Direcció"
+
+#. 'Up' and 'Down' buttons
+msgid "Up"
+msgstr "Amunt"
+
+msgid "Down"
+msgstr "Avall"
+
+msgid "Find Next"
+msgstr "Cerca el següent"
+
+msgid "Replace"
+msgstr "Substitueix"
+
+msgid "Replace All"
+msgstr "Substitueix-les totes"
+
+msgid "Vim: Received \"die\" request from session manager\n"
+msgstr "Vim: S'ha rebut una petició \"die\" del gestor de sessions\n"
+
+msgid "Close"
+msgstr "Tanca"
+
+msgid "New tab"
+msgstr "Nova pestanya"
+
+msgid "Open Tab..."
+msgstr "Obre una pestanya..."
+
+msgid "Vim: Main window unexpectedly destroyed\n"
+msgstr "Vim: La finestra principal ha estat destruïda inesperadament\n"
+
+msgid "Font Selection"
+msgstr "Selecció de fosa"
+
+msgid "Used CUT_BUFFER0 instead of empty selection"
+msgstr "S'ha usat CUT_BUFFER0 en lloc d'una selecció buida"
+
+msgid "&Filter"
+msgstr "&Filtre"
+
+msgid "&Cancel"
+msgstr "&Cancel·la"
+
+msgid "Directories"
+msgstr "Directoris"
+
+msgid "Filter"
+msgstr "Filtre"
+
+msgid "&Help"
+msgstr "&Ajuda"
+
+msgid "Files"
+msgstr "Fitxers"
+
+msgid "&OK"
+msgstr "&D'acord"
+
+msgid "Selection"
+msgstr "Selecció"
+
+msgid "Find &Next"
+msgstr "Cerca el &següent"
+
+msgid "&Replace"
+msgstr "&Substitueix"
+
+msgid "Replace &All"
+msgstr "Substitueix-les &totes"
+
+msgid "&Undo"
+msgstr "&Desfés"
+
+#, c-format
+msgid "E671: Cannot find window title \"%s\""
+msgstr "E671: No s'ha trobat el títol de finestra \"%s\""
+
+#, c-format
+msgid "E243: Argument not supported: \"-%s\"; Use the OLE version."
+msgstr "E243: Argument no suportat: \"-%s\"; Useu la versió OLE."
+
+msgid "E672: Unable to open window inside MDI application"
+msgstr "E672: No s'ha pogut obrir una finestra dins l'aplicació MDI"
+
+msgid "Close tab"
+msgstr "Tanca la pestanya"
+
+msgid "Open tab..."
+msgstr "Obre una pestanya..."
+
+msgid "Find string (use '\\\\' to find a '\\')"
+msgstr "Cerca una cadena (useu '\\\\' per cercar '\\')"
+
+msgid "Find & Replace (use '\\\\' to find a '\\')"
+msgstr "Cerca i substitueix (useu '\\\\' per cercar '\\')"
+
+#. 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 "No Usat"
+
+msgid "Directory\t*.nothing\n"
+msgstr "Directori\t*.res\n"
+
+msgid "Vim E458: Cannot allocate colormap entry, some colors may be incorrect"
+msgstr "Vim E458: No s'ha pogut assignar memòria per colors, poden ser incorrectes"
+
+#, c-format
+msgid "E250: Fonts for the following charsets are missing in fontset %s:"
+msgstr "E250: En el conjunt %s falten tipus pels següents jocs de caràcters:"
+
+#, c-format
+msgid "E252: Fontset name: %s"
+msgstr "E252: Nom del conjunt de tipus: %s"
+
+#, c-format
+msgid "Font '%s' is not fixed-width"
+msgstr "La fosa '%s' no és d'amplada fixa"
+
+#, c-format
+msgid "E253: Fontset name: %s\n"
+msgstr "E253: Nom del conjunt de tipus: %s\n"
+
+#, c-format
+msgid "Font0: %s\n"
+msgstr "Fosa0: %s\n"
+
+#, c-format
+msgid "Font1: %s\n"
+msgstr "Fosa1: %s\n"
+
+#, c-format
+msgid "Font%ld width is not twice that of font0\n"
+msgstr "L'amplada de la fosa%ld no és el doble que la de la fosa0\n"
+
+#, c-format
+msgid "Font0 width: %ld\n"
+msgstr "Amplada de de la Fosa0: %ld\n"
+
+#, c-format
+msgid ""
+"Font1 width: %ld\n"
+"\n"
+msgstr ""
+"Amplada de la Fosa1: %ld\n"
+"\n"
+
+msgid "Invalid font specification"
+msgstr "Especificació de fosa no vàlida"
+
+msgid "&Dismiss"
+msgstr "&Ignora"
+
+msgid "no specific match"
+msgstr "cap coincidència específica"
+
+msgid "Vim - Font Selector"
+msgstr "Vim - Selector de fosa"
+
+msgid "Name:"
+msgstr "Nom:"
+
+#. create toggle button
+msgid "Show size in Points"
+msgstr "Mostra la mida en punts"
+
+msgid "Encoding:"
+msgstr "Codificació:"
+
+msgid "Font:"
+msgstr "Fosa:"
+
+msgid "Style:"
+msgstr "Estil:"
+
+msgid "Size:"
+msgstr "Mida:"
+
+msgid "E256: Hangul automata ERROR"
+msgstr "E256: ERROR de l'autòmata hangul"
+
+msgid "E550: Missing colon"
+msgstr "E550: Falta un caràcter \":\""
+
+msgid "E551: Illegal component"
+msgstr "E551: Component il·legal"
+
+msgid "E552: digit expected"
+msgstr "E552: S'esperava un dígit"
+
+#, c-format
+msgid "Page %d"
+msgstr "Pàgina %d"
+
+msgid "No text to be printed"
+msgstr "No hi ha text per imprimir"
+
+#, c-format
+msgid "Printing page %d (%d%%)"
+msgstr "S'està imprimint la pàgina %d (%d%%)"
+
+#, c-format
+msgid " Copy %d of %d"
+msgstr " Còpia %d de %d"
+
+#, c-format
+msgid "Printed: %s"
+msgstr "S'ha imprès: %s"
+
+msgid "Printing aborted"
+msgstr "S'ha avortat l'impressió"
+
+msgid "E455: Error writing to PostScript output file"
+msgstr "E455: Error en escriure el fitxer PostScript"
+
+#, c-format
+msgid "E624: Can't open file \"%s\""
+msgstr "E624: No s'ha pogut obrir el fitxer \"%s\""
+
+#, c-format
+msgid "E457: Can't read PostScript resource file \"%s\""
+msgstr "E457: No s'ha pogut llegir el fitxer de recursos PostScript \"%s\""
+
+#, c-format
+msgid "E618: file \"%s\" is not a PostScript resource file"
+msgstr "E618: El fitxer \"%s\" no és un fitxer de recursos PostScript"
+
+#, c-format
+msgid "E619: file \"%s\" is not a supported PostScript resource file"
+msgstr "E619: El fitxer de recursos PostScript \"%s\" no està suportat"
+
+#, c-format
+msgid "E621: \"%s\" resource file has wrong version"
+msgstr "E621: La versió del fitxer de recursos \"%s\" no és vàlida"
+
+msgid "E673: Incompatible multi-byte encoding and character set."
+msgstr "E673: Joc de caràcters i codificació multi-octet no compatibles."
+
+msgid "E674: printmbcharset cannot be empty with multi-byte encoding."
+msgstr "E674: printmbcharset no pot estar buit si la codificació és multi-octet"
+
+msgid "E675: No default font specified for multi-byte printing."
+msgstr "E675: No heu especificat cap fosa per defecte per a la impressió multi-octet."
+
+msgid "E324: Can't open PostScript output file"
+msgstr "E324: No s'ha pogut obrir el fitxer PostScript generat"
+
+#, c-format
+msgid "E456: Can't open file \"%s\""
+msgstr "E456: No s'ha pogut obrir el fitxer \"%s\""
+
+msgid "E456: Can't find PostScript resource file \"prolog.ps\""
+msgstr "E456: No s'ha trobat el fitxer de recursos PostScript \"prolog.ps\""
+
+msgid "E456: Can't find PostScript resource file \"cidfont.ps\""
+msgstr "E456: No s'ha trobat el fitxer de recursos PostScript \"cidfont.ps\""
+
+#, c-format
+msgid "E456: Can't find PostScript resource file \"%s.ps\""
+msgstr "E456: No s'ha trobat el fitxer de recursos PostScript \"%s.ps\""
+
+#, c-format
+msgid "E620: Unable to convert to print encoding \"%s\""
+msgstr "E620: No s'ha pogut convertir a la codificació d'impressió \"%s\""
+
+msgid "Sending to printer..."
+msgstr "S'està enviant a la impressora..."
+
+msgid "E365: Failed to print PostScript file"
+msgstr "E365: Error en imprimir el fitxer PostScript"
+
+msgid "Print job sent."
+msgstr "S'ha enviat la tasca d'impressió."
+
+msgid "Add a new database"
+msgstr "Afegeix una base de dades nova"
+
+msgid "Query for a pattern"
+msgstr "Consulta un patró"
+
+msgid "Show this message"
+msgstr "Mostra aquest missatge"
+
+msgid "Kill a connection"
+msgstr "Talla una connexió"
+
+msgid "Reinit all connections"
+msgstr "Reinicia totes les connexions"
+
+msgid "Show connections"
+msgstr "Mostra les connexions"
+
+#, c-format
+msgid "E560: Usage: cs[cope] %s"
+msgstr "E560: Forma d'ús: cs[cope] %s"
+
+msgid "This cscope command does not support splitting the window.\n"
+msgstr "Aquesta ordre de cscope no suporta divisió de finestres.\n"
+
+msgid "E562: Usage: cstag <ident>"
+msgstr "E562: Forma d'ús: cstag <despl>"
+
+msgid "E257: cstag: tag not found"
+msgstr "E257: cstag: No s'ha trobat l'etiqueta"
+
+#, c-format
+msgid "E563: stat(%s) error: %d"
+msgstr "E563: Error de stat(%s): %d"
+
+msgid "E563: stat error"
+msgstr "E563: Error de stat()"
+
+#, c-format
+msgid "E564: %s is not a directory or a valid cscope database"
+msgstr "E564: %s no és un directori o una base de dades de cscope vàlida"
+
+#, c-format
+msgid "Added cscope database %s"
+msgstr "S'ha afegit la base de dades cscope %s"
+
+#, c-format
+msgid "E262: error reading cscope connection %ld"
+msgstr "E262: Error en llegir la connexió cscope %ld"
+
+msgid "E561: unknown cscope search type"
+msgstr "E561: Tipus de cerca cscope desconeguda"
+
+msgid "E566: Could not create cscope pipes"
+msgstr "E566: No s'han pogut crear canonades cscope"
+
+msgid "E622: Could not fork for cscope"
+msgstr "E622: No s'ha pogut bifurcar el procés cscope"
+
+msgid "cs_create_connection exec failed"
+msgstr "l'execució de cs_create_connection ha fallat"
+
+msgid "E623: Could not spawn cscope process"
+msgstr "E623: No s'ha pogut generar un procés per cscope"
+
+msgid "cs_create_connection: fdopen for to_fp failed"
+msgstr "cs_create_connection: fdopen per to_fp ha fallat"
+
+msgid "cs_create_connection: fdopen for fr_fp failed"
+msgstr "cs_create_connection: fdopen per fr_fp ha fallat"
+
+msgid "E567: no cscope connections"
+msgstr "E567: No hi han connexions cscope"
+
+#, c-format
+msgid "E259: no matches found for cscope query %s of %s"
+msgstr "E259: Cap resultat per la consulta cscope %s de %s"
+
+#, c-format
+msgid "E469: invalid cscopequickfix flag %c for %c"
+msgstr "E469: El senyal cscopequickfix %c no és vàlid per %c"
+
+msgid "cscope commands:\n"
+msgstr "ordres de cscope:\n"
+
+#, c-format
+msgid "%-5s: %-30s (Usage: %s)"
+msgstr "%-5s: %-30s (Forma d'ús: %s)"
+
+#, c-format
+msgid "E625: cannot open cscope database: %s"
+msgstr "E625: No s'ha pogut obrir la base de dades cscope: %s"
+
+msgid "E626: cannot get cscope database information"
+msgstr "E626: No s'ha pogut obtenir l'informació de la base de dades cscope"
+
+msgid "E568: duplicate cscope database not added"
+msgstr "E568: No s'ha afegit una base de dades cscope duplicada"
+
+msgid "E569: maximum number of cscope connections reached"
+msgstr "E569: S'ha assolit el màxim nombre de connexions cscope"
+
+#, c-format
+msgid "E261: cscope connection %s not found"
+msgstr "E261: No s'ha trobat la connexió cscope %s"
+
+#, c-format
+msgid "cscope connection %s closed"
+msgstr "s'ha tancat la connexió cscope %s"
+
+#. should not reach here
+msgid "E570: fatal error in cs_manage_matches"
+msgstr "E570: Error fatal a cs_manage_matches"
+
+#, c-format
+msgid "Cscope tag: %s"
+msgstr "Etiqueta cscope: %s"
+
+msgid ""
+"\n"
+" # line"
+msgstr ""
+"\n"
+" # línia"
+
+msgid "filename / context / line\n"
+msgstr "fitxer / context / línia\n"
+
+#, c-format
+msgid "E609: Cscope error: %s"
+msgstr "E609: Error de cscope: %s"
+
+msgid "All cscope databases reset"
+msgstr "S'han reiniciat totes les bases de dades cscope"
+
+msgid "no cscope connections\n"
+msgstr "no hi ha connexions cscope\n"
+
+msgid " # pid database name prepend path\n"
+msgstr " # pid base de dades prefix d'ubicació\n"
+
+msgid "???: Sorry, this command is disabled, the MzScheme library could not be loaded."
+msgstr "???: Aquesta ordre no està habilitada, la biblioteca MzScheme no s'ha pogut carregar."
+
+msgid "invalid expression"
+msgstr "l'expressió no és vàlida"
+
+msgid "expressions disabled at compile time"
+msgstr "no s'ha compilat suport per expressions"
+
+msgid "hidden option"
+msgstr "opció amagada"
+
+msgid "unknown option"
+msgstr "opció desconeguda"
+
+msgid "window index is out of range"
+msgstr "índex de finestra fora d'abast"
+
+msgid "couldn't open buffer"
+msgstr "no s'ha pogut obrir el buffer"
+
+msgid "cannot save undo information"
+msgstr "no s'ha pogut desar l'informació de desfer"
+
+msgid "cannot delete line"
+msgstr "no s'ha pogut esborrar la línia"
+
+msgid "cannot replace line"
+msgstr "no s'ha pogut substituir la línia"
+
+msgid "cannot insert line"
+msgstr "no s'ha pogut inserir la línia"
+
+msgid "string cannot contain newlines"
+msgstr "la cadena no pot contenir salts de línia"
+
+msgid "Vim error: ~a"
+msgstr "Error del Vim: ~a"
+
+msgid "Vim error"
+msgstr "Error del Vim"
+
+msgid "buffer is invalid"
+msgstr "el buffer no és vàlid"
+
+msgid "window is invalid"
+msgstr "la finestra no és vàlida"
+
+msgid "linenr out of range"
+msgstr "nombre de línia fora d'abast"
+
+msgid "not allowed in the Vim sandbox"
+msgstr "no permès a la gàbia del Vim"
+
+msgid "E263: Sorry, this command is disabled, the Python library could not be loaded."
+msgstr "E263: Aquesta ordre està deshabilitada, no s'ha pogut carregar Python."
+
+msgid "E659: Cannot invoke Python recursively"
+msgstr "E659: No es pot invocar Python de forma recursiva"
+
+msgid "can't delete OutputObject attributes"
+msgstr "no s'han pogut eliminar els atributs de l'OutputObject"
+
+msgid "softspace must be an integer"
+msgstr "'softspace' ha de ser un nombre enter"
+
+msgid "invalid attribute"
+msgstr "l'atribut no és vàlid"
+
+msgid "writelines() requires list of strings"
+msgstr "la funció writelines() requereix una llista de cadenes"
+
+msgid "E264: Python: Error initialising I/O objects"
+msgstr "E264: Python: Error en inicialitzar els objectes d'E/S"
+
+msgid "attempt to refer to deleted buffer"
+msgstr "intent de referència a un buffer eliminat"
+
+msgid "line number out of range"
+msgstr "nombre de línia fora d'abast"
+
+#, c-format
+msgid "<buffer object (deleted) at %8lX>"
+msgstr "<objecte buffer (eliminat) a %8lX>"
+
+msgid "invalid mark name"
+msgstr "nom de marca no vàlid"
+
+msgid "no such buffer"
+msgstr "no existeix tal buffer"
+
+msgid "attempt to refer to deleted window"
+msgstr "intent de referir-se a una finestra eliminada"
+
+msgid "readonly attribute"
+msgstr "atribut de només lectura"
+
+msgid "cursor position outside buffer"
+msgstr "posició del cursor fora del buffer"
+
+#, c-format
+msgid "<window object (deleted) at %.8lX>"
+msgstr "<objecte finestra (eliminat) a %.8lX>"
+
+#, c-format
+msgid "<window object (unknown) at %.8lX>"
+msgstr "<objecte finestra (desconegut) a %.8lX>"
+
+#, c-format
+msgid "<window %d>"
+msgstr "<finestra %d>"
+
+msgid "no such window"
+msgstr "no existeix tal finestra"
+
+msgid "E265: $_ must be an instance of String"
+msgstr "E265: $_ ha de ser una instància d'una cadena"
+
+msgid "E266: Sorry, this command is disabled, the Ruby library could not be loaded."
+msgstr "E266: Ordre deshabilitada, no s'ha pogut carregar la biblioteca Ruby."
+
+msgid "E267: unexpected return"
+msgstr "E267: retorn inesperat"
+
+msgid "E268: unexpected next"
+msgstr "E268: 'next' inesperat"
+
+msgid "E269: unexpected break"
+msgstr "E269: tall inesperat"
+
+msgid "E270: unexpected redo"
+msgstr "E270: 'redo' inesperat"
+
+msgid "E271: retry outside of rescue clause"
+msgstr "E271: 'retry' fora d'una clàusula de rescat"
+
+msgid "E272: unhandled exception"
+msgstr "E272: excepció no manejada"
+
+#, c-format
+msgid "E273: unknown longjmp status %d"
+msgstr "E273: estat de longjmp desconegut %d"
+
+msgid "Toggle implementation/definition"
+msgstr "Commuta implementació/definició"
+
+msgid "Show base class of"
+msgstr "Mostra la classe base de"
+
+msgid "Show overridden member function"
+msgstr "Mostra el membre de la funció invalidat"
+
+msgid "Retrieve from file"
+msgstr "Obtenir d'un fitxer"
+
+msgid "Retrieve from project"
+msgstr "Obtenir d'un projecte"
+
+msgid "Retrieve from all projects"
+msgstr "Obtenir de tots els projectes"
+
+msgid "Retrieve"
+msgstr "Obtenir"
+
+msgid "Show source of"
+msgstr "Mostra el codi font de"
+
+msgid "Find symbol"
+msgstr "Cerca un símbol"
+
+msgid "Browse class"
+msgstr "Explora les classes"
+
+msgid "Show class in hierarchy"
+msgstr "Mostra la jerarquia de classes"
+
+msgid "Show class in restricted hierarchy"
+msgstr "Mostra la jerarquia de classes restringida"
+
+msgid "Xref refers to"
+msgstr "Xref es refereix a"
+
+msgid "Xref referred by"
+msgstr "Xref referenciada per"
+
+msgid "Xref has a"
+msgstr "Xref té un"
+
+msgid "Xref used by"
+msgstr "Xref usada per"
+
+msgid "Show docu of"
+msgstr "Mostra docu de"
+
+msgid "Generate docu for"
+msgstr "Genera docu per"
+
+msgid "Cannot connect to SNiFF+. Check environment (sniffemacs must be found in $PATH).\n"
+msgstr "No s'ha pogut connectar amb SNiFF+. Reviseu l'entorn (sniffemacs ha d'estar en el $PATH).\n"
+
+msgid "E274: Sniff: Error during read. Disconnected"
+msgstr "E274: Sniff: Error de lectura. Desconnectat"
+
+msgid "SNiFF+ is currently "
+msgstr "SNiFF+ "
+
+msgid "not "
+msgstr "no "
+
+msgid "connected"
+msgstr "està connectat"
+
+#, c-format
+msgid "E275: Unknown SNiFF+ request: %s"
+msgstr "E275: Petició SNiFF+ desconeguda: %s"
+
+msgid "E276: Error connecting to SNiFF+"
+msgstr "E276: Error en connectar a SNiFF+"
+
+msgid "E278: SNiFF+ not connected"
+msgstr "E278: SNiFF+ no connectat"
+
+msgid "E279: Not a SNiFF+ buffer"
+msgstr "E279: No és un buffer SNiFF+"
+
+msgid "Sniff: Error during write. Disconnected"
+msgstr "Sniff: Error d'escriptura. Desconnectat"
+
+msgid "invalid buffer number"
+msgstr "nombre de buffer no vàlid"
+
+msgid "not implemented yet"
+msgstr "no implementat (encara)"
+
+#. ???
+msgid "cannot set line(s)"
+msgstr "no s'ha pogut establir el nombre de línies"
+
+msgid "mark not set"
+msgstr "marca no establerta"
+
+#, c-format
+msgid "row %d column %d"
+msgstr "fila %d columna %d"
+
+msgid "cannot insert/append line"
+msgstr "no s'ha pogut inserir/afegir la línia"
+
+msgid "unknown flag: "
+msgstr "senyal desconegut: "
+
+msgid "unknown vimOption"
+msgstr "vimOption desconeguda"
+
+msgid "keyboard interrupt"
+msgstr "interrupció de teclat"
+
+msgid "vim error"
+msgstr "error de vim"
+
+msgid "cannot create buffer/window command: object is being deleted"
+msgstr "no s'ha pogut crear l'ordre de buffer/finestra: l'objecte està siguent eliminat"
+
+msgid "cannot register callback command: buffer/window is already being deleted"
+msgstr "no s'ha pogut registrar l'ordre callback: el búfer/finestra ja està sent eliminat"
+
+#. This should never happen. Famous last word?
+msgid "E280: TCL FATAL ERROR: reflist corrupt!? Please report this to vim-dev@vim.org"
+msgstr "E280: ERROR FATAL DE TCL: llista de referències corrupta!? Comuniqueu-ho a vim-dev@vim.org."
+
+msgid "cannot register callback command: buffer/window reference not found"
+msgstr "no s'ha pogut registrar l'ordre callback: referència del búfer/finestra no trobada"
+
+msgid "E571: Sorry, this command is disabled: the Tcl library could not be loaded."
+msgstr "E571: Aquesta ordre està deshabilitada: No s'ha pogut carregar la llibreria Tcl."
+
+msgid "E281: TCL ERROR: exit code is not int!? Please report this to vim-dev@vim.org"
+msgstr "E281: ERROR DE TCL: el codi de retorn no és un enter!? Comuniqueu-ho a vim-dev@vim.org."
+
+#, c-format
+msgid "E572: exit code %d"
+msgstr "E572: codi de sortida %d"
+
+msgid "cannot get line"
+msgstr "no s'ha pogut obtenir la línia"
+
+msgid "Unable to register a command server name"
+msgstr "No s'ha pogut registrar un nom de servidor d'ordres"
+
+msgid "E248: Failed to send command to the destination program"
+msgstr "E248: No s'ha pogut enviar l'ordre al programa destinatari"
+
+#, c-format
+msgid "E573: Invalid server id used: %s"
+msgstr "E573: S'ha usat una ID de servidor no vàlida: %s"
+
+msgid "E251: VIM instance registry property is badly formed. Deleted!"
+msgstr "E251: El registre de l'instància de VIM està mal format. S'ha esborrat!"
+
+msgid "Unknown option argument"
+msgstr "Argument d'opció desconegut"
+
+msgid "Too many edit arguments"
+msgstr "Massa arguments d'edició"
+
+msgid "Argument missing after"
+msgstr "Falta un argument després de"
+
+msgid "Garbage after option argument"
+msgstr "Porqueria després de l'argument d'opció"
+
+msgid "Too many \"+command\", \"-c command\" or \"--cmd command\" arguments"
+msgstr "Massa arguments \"+ordre\", \"-c ordre\" o \"--cmd ordre\""
+
+msgid "Invalid argument for"
+msgstr "Argument no vàlid per"
+
+#, c-format
+msgid "%d files to edit\n"
+msgstr "%d fitxers per editar\n"
+
+msgid "This Vim was not compiled with the diff feature."
+msgstr "Aquest Vim no ha estat compilat amb suport per diff."
+
+msgid "Attempt to open script file again: \""
+msgstr "Reintent d'obrir l'script: \""
+
+msgid "Cannot open for reading: \""
+msgstr "No s'ha pogut obrir amb permís de lectura: \""
+
+msgid "Cannot open for script output: \""
+msgstr "No s'ha pogut obrir per desar-hi l'exida de l'script: \""
+
+msgid "Vim: Error: Failure to start gvim from NetBeans\n"
+msgstr "Vim: Error: Ha fallat l'arrencada del gvim des de NetBeans\n"
+
+msgid "Vim: Warning: Output is not to a terminal\n"
+msgstr "Vim: Atenció: La sortida no està connectada a un terminal\n"
+
+msgid "Vim: Warning: Input is not from a terminal\n"
+msgstr "Vim: Atenció: L'entrada no està connectada a un terminal\n"
+
+#. just in case..
+msgid "pre-vimrc command line"
+msgstr "línia d'ordres pre-vimrc"
+
+#, c-format
+msgid "E282: Cannot read from \"%s\""
+msgstr "E282: No s'ha pogut llegir \"%s\""
+
+msgid ""
+"\n"
+"More info with: \"vim -h\"\n"
+msgstr ""
+"\n"
+"Més informació amb: \"vim -h\"\n"
+
+msgid "[file ..] edit specified file(s)"
+msgstr "[fitxer ...] edita el(s) fitxer(s) especificat(s)"
+
+msgid "- read text from stdin"
+msgstr "- edita el text de l'entrada estàndard"
+
+msgid "-t tag edit file where tag is defined"
+msgstr "-t etiqueta edita el fitxer on hi ha l'etiqueta"
+
+msgid "-q [errorfile] edit file with first error"
+msgstr "-q [ftxerrors] edita el fitxer on hi ha el primer error"
+
+msgid ""
+"\n"
+"\n"
+"usage:"
+msgstr ""
+"\n"
+"\n"
+" ús:"
+
+msgid " vim [arguments] "
+msgstr " vim [arguments] "
+
+msgid ""
+"\n"
+" or:"
+msgstr ""
+"\n"
+"o bé:"
+
+msgid ""
+"\n"
+"Where case is ignored prepend / to make flag upper case"
+msgstr ""
+"\n"
+"On s'ignora la capitalizació, afegiu el prefix / per a indicar majúscules"
+
+msgid ""
+"\n"
+"\n"
+"Arguments:\n"
+msgstr ""
+"\n"
+"\n"
+"Arguments:\n"
+
+msgid "--\t\t\tOnly file names after this"
+msgstr "--\t\t\tDesprés d'això només noms de fitxers"
+
+msgid "--literal\t\tDon't expand wildcards"
+msgstr "--literal\t\tNo expandeix patrons de noms"
+
+msgid "-register\t\tRegister this gvim for OLE"
+msgstr "-register\t\tRegistra aquest gvim per OLE"
+
+msgid "-unregister\t\tUnregister gvim for OLE"
+msgstr "-unregister\t\tDesregistra aquest gvim per OLE"
+
+msgid "-g\t\t\tRun using GUI (like \"gvim\")"
+msgstr "-g\t\t\tUsa una interfície gràfica (com \"gvim\")"
+
+msgid "-f or --nofork\tForeground: Don't fork when starting GUI"
+msgstr "-f o --nofork\tNo crea un procés nou per la GUI"
+
+msgid "-v\t\t\tVi mode (like \"vi\")"
+msgstr "-v\t\t\tMode Vi (com \"vi\")"
+
+msgid "-e\t\t\tEx mode (like \"ex\")"
+msgstr "-e\t\t\tMode Ex (com \"ex\")"
+
+msgid "-s\t\t\tSilent (batch) mode (only for \"ex\")"
+msgstr "-s\t\t\tMode silenciós (només per \"ex\")"
+
+msgid "-d\t\t\tDiff mode (like \"vimdiff\")"
+msgstr "-d\t\t\tMode diff (com \"vimdiff\")"
+
+msgid "-y\t\t\tEasy mode (like \"evim\", modeless)"
+msgstr "-y\t\t\tMode senzill (com \"evim\", sense modes)"
+
+msgid "-R\t\t\tReadonly mode (like \"view\")"
+msgstr "-R\t\t\tMode només lectura (com \"view\")"
+
+msgid "-Z\t\t\tRestricted mode (like \"rvim\")"
+msgstr "-Z\t\t\tMode restringit (com \"rvim)"
+
+msgid "-m\t\t\tModifications (writing files) not allowed"
+msgstr "-m\t\t\tNo permet modificar (escriure) fitxers"
+
+msgid "-M\t\t\tModifications in text not allowed"
+msgstr "-M\t\t\tNo permet modificar el text"
+
+msgid "-b\t\t\tBinary mode"
+msgstr "-b\t\t\tMode binari"
+
+msgid "-l\t\t\tLisp mode"
+msgstr "-l\t\t\tMode Lisp"
+
+msgid "-C\t\t\tCompatible with Vi: 'compatible'"
+msgstr "-C\t\t\tCompatible amb Vi"
+
+msgid "-N\t\t\tNot fully Vi compatible: 'nocompatible'"
+msgstr "-N\t\t\tNo del tot compatible amb Vi"
+
+msgid "-V[N][fname]\t\tBe verbose [level N] [log messages to fname]"
+msgstr "-V[N][nomf]\t\tLoquacitat [nivell N] [desa els missatges a nomf]"
+
+msgid "-D\t\t\tDebugging mode"
+msgstr "-D\t\t\tMode de depuració"
+
+msgid "-n\t\t\tNo swap file, use memory only"
+msgstr "-n\t\t\tNo usa fitxers d'intercanvi, només memòria"
+
+msgid "-r\t\t\tList swap files and exit"
+msgstr "-r\t\t\tLlista els fitxers d'intercanvi i surt"
+
+msgid "-r (with file name)\tRecover crashed session"
+msgstr "-r (amb nom de fitxer) Recupera una sessió accidentada"
+
+msgid "-L\t\t\tSame as -r"
+msgstr "-L\t\t\tIgual que -r"
+
+msgid "-f\t\t\tDon't use newcli to open window"
+msgstr "-f\t\t\tNo obre una finestra nova amb newcli"
+
+msgid "-dev <device>\t\tUse <device> for I/O"
+msgstr "-dev <dispositiu>\t\tUsa <dispositiu> per l'E/S"
+
+msgid "-A\t\t\tstart in Arabic mode"
+msgstr "-A\t\t\tComença en mode àrab"
+
+msgid "-H\t\t\tStart in Hebrew mode"
+msgstr "-H\t\t\tComença en mode hebreu"
+
+msgid "-F\t\t\tStart in Farsi mode"
+msgstr "-F\t\t\t Comença en mode farsi"
+
+msgid "-T <terminal>\tSet terminal type to <terminal>"
+msgstr "-T <terminal>\tDefineix el tipus de terminal"
+
+msgid "-u <vimrc>\t\tUse <vimrc> instead of any .vimrc"
+msgstr "-u <vimrc>\t\tUsa <vimrc> en lloc de qualsevol altre .vimrc"
+
+msgid "-U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc"
+msgstr "-U <gvimrc>\t\tUsa <gvimrc> en lloc de qualsevol altre .gvimrc"
+
+msgid "--noplugin\t\tDon't load plugin scripts"
+msgstr "--noplugin\t\tNo carrega cap plugin"
+
+msgid "-p[N]\t\tOpen N tab pages (default: one for each file)"
+msgstr "-p[N]\t\tObre N pestanyes (per omissió: una per fitxer)"
+
+msgid "-o[N]\t\tOpen N windows (default: one for each file)"
+msgstr "-o[N]\t\tObre N finestres (per omissió: una per fitxer)"
+
+msgid "-O[N]\t\tLike -o but split vertically"
+msgstr "-O[N]\t\tCom -o però amb divisions verticals"
+
+msgid "+\t\t\tStart at end of file"
+msgstr "+\t\t\tComença al final del fitxer"
+
+msgid "+<lnum>\t\tStart at line <lnum>"
+msgstr "+<lnúm>\t\tComença a la línia <lnúm>"
+
+msgid "--cmd <command>\tExecute <command> before loading any vimrc file"
+msgstr "--cmd <ordre>\tExecuta <ordre> abans de llegir els fitxers vimrc"
+
+msgid "-c <command>\t\tExecute <command> after loading the first file"
+msgstr "-c <ordre>\t\tExecuta <ordre> després de carregar el primer fitxer"
+
+msgid "-S <session>\t\tSource file <session> after loading the first file"
+msgstr "-S <fitxer>\t\tEvalua <fitxer> un cop carregat el primer fitxer"
+
+msgid "-s <scriptin>\tRead Normal mode commands from file <scriptin>"
+msgstr "-s <script>\t\tLlegeix ordres del mode Normal del fitxer <script>"
+
+msgid "-w <scriptout>\tAppend all typed commands to file <scriptout>"
+msgstr "-w <script>\t\tAfegeix totes les ordres executades al fitxer <script>"
+
+msgid "-W <scriptout>\tWrite all typed commands to file <scriptout>"
+msgstr "-W <script>\t\tEscriu totes les ordres executades al fitxer <script>"
+
+msgid "-x\t\t\tEdit encrypted files"
+msgstr "-x\t\t\tEdita fitxers amb xifrat"
+
+msgid "-display <display>\tConnect vim to this particular X-server"
+msgstr "-display <pantalla>\tConnecta el Vim a un servidor X particular"
+
+msgid "-X\t\t\tDo not connect to X server"
+msgstr "-X\t\t\tNo es connecta a cap servidor X"
+
+msgid "--remote <files>\tEdit <files> in a Vim server if possible"
+msgstr "--remote <fitxers>\tEdita <fitxers> en un servidor Vim, si és possible"
+
+msgid "--remote-silent <files> Same, don't complain if there is no server"
+msgstr "--remote-silent <fitxers> Igual, no es queixa si no hi ha servidor"
+
+msgid "--remote-wait <files> As --remote but wait for files to have been edited"
+msgstr "--remote-wait <fitxers> Com --remote, però espera que s'editin els fitxers"
+
+msgid "--remote-wait-silent <files> Same, don't complain if there is no server"
+msgstr "--remote-wait-silent <fitxers> Igual, no es queixa si no hi ha servidor"
+
+msgid "--remote-tab <files> As --remote but open tab page for each file"
+msgstr "--remote-tab <fitxers> Com --remote, però obre una pestanya per fitxer"
+
+msgid "--remote-send <keys>\tSend <keys> to a Vim server and exit"
+msgstr "--remote-send <tecles> Envia <tecles> a un servidor Vim i surt"
+
+msgid "--remote-expr <expr>\tEvaluate <expr> in a Vim server and print result"
+msgstr "--remote-expr <expr>\tEvaula <expr> en un servidor Vim i mostra el resultat"
+
+msgid "--serverlist\t\tList available Vim server names and exit"
+msgstr "--serverlist\t\tLlista els noms dels servidors Vim accessibles"
+
+msgid "--servername <name>\tSend to/become the Vim server <name>"
+msgstr "--servername <nom>\tEnvia a o es converteix en servidor Vim <nom>"
+
+msgid "-i <viminfo>\t\tUse <viminfo> instead of .viminfo"
+msgstr "-i <viminfo>\t\tUsa <viminfo> en lloc de .viminfo"
+
+msgid "-h or --help\tPrint Help (this message) and exit"
+msgstr "-h o --help\tMostra aquesta ajuda i surt"
+
+msgid "--version\t\tPrint version information and exit"
+msgstr "--version\t\tMostra informació sobre la versió i surt"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (Motif version):\n"
+msgstr ""
+"\n"
+"Arguments reconeguts pel gvim (versió Motif):\n"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (neXtaw version):\n"
+msgstr ""
+"\n"
+"Arguments reconeguts pel gvim (versió neXtaw>:\n"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (Athena version):\n"
+msgstr ""
+"\n"
+"Arguments reconeguts pel gvim (versió Athena):\n"
+
+msgid "-display <display>\tRun vim on <display>"
+msgstr "-display <pantalla>\tExecuta vim a <pantalla>"
+
+msgid "-iconic\t\tStart vim iconified"
+msgstr "-iconic\t\tComença iconificat"
+
+msgid "-name <name>\t\tUse resource as if vim was <name>"
+msgstr "-name <nom>\t\tUsa els recursos com si vim fós <nom>"
+
+msgid "\t\t\t (Unimplemented)\n"
+msgstr "\t\t\t (No implementat)\n"
+
+msgid "-background <color>\tUse <color> for the background (also: -bg)"
+msgstr "-background <color>\tUsa <color> pel fons (també: -bg)"
+
+msgid "-foreground <color>\tUse <color> for normal text (also: -fg)"
+msgstr "-foreground <color>\tUsa <color> pel text normal (també: -fg)"
+
+msgid "-font <font>\t\tUse <font> for normal text (also: -fn)"
+msgstr "-font <fosa>\tUsa <fosa> pel text normal (també: -fn)"
+
+msgid "-boldfont <font>\tUse <font> for bold text"
+msgstr "-boldfont <fosa>\tUsa <fosa> pel text en negreta"
+
+msgid "-italicfont <font>\tUse <font> for italic text"
+msgstr "-italicfont <fosa>\tUsa <fosa> pel text en cursiva"
+
+msgid "-geometry <geom>\tUse <geom> for initial geometry (also: -geom)"
+msgstr "-geometry <geom>\tUsa <geom> com a geometria inicial (també: -geom)"
+
+msgid "-borderwidth <width>\tUse a border width of <width> (also: -bw)"
+msgstr "-borderwidth <amplada>\tUsa un marge d'amplada <amplada> (també: -bw)"
+
+msgid "-scrollbarwidth <width> Use a scrollbar width of <width> (also: -sw)"
+msgstr "-scrollbarwidth <amplada> Amplada de la barra de desplaçament (també: -sw)"
+
+msgid "-menuheight <height>\tUse a menu bar height of <height> (also: -mh)"
+msgstr "-menuheight <alçada>\tAlçada de la barra de menú (també: -mh)"
+
+msgid "-reverse\t\tUse reverse video (also: -rv)"
+msgstr "-reverse\t\tUsa el mode de video invers (també: -rv)"
+
+msgid "+reverse\t\tDon't use reverse video (also: +rv)"
+msgstr "+reverse\t\tNo usa el mode de video invers (també: +rv)"
+
+msgid "-xrm <resource>\tSet the specified resource"
+msgstr "-xrm <recurs>\tEstableix el recurs especificat"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (RISC OS version):\n"
+msgstr ""
+"\n"
+"Arguments reconeguts pel gvim (versió RISC OS):\n"
+
+msgid "--columns <number>\tInitial width of window in columns"
+msgstr "--columns <nombre>\tAmplada inicial de la finestra en columnes"
+
+msgid "--rows <number>\tInitial height of window in rows"
+msgstr "--rows <nombre>\tAlçada inicial de la finestra en files"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (GTK+ version):\n"
+msgstr ""
+"\n"
+"Arguments reconeguts pel gvim (versió GTK+):\n"
+
+msgid "-display <display>\tRun vim on <display> (also: --display)"
+msgstr "-display <pantalla>\tExecuta vim a <pantalla> (també: --display)"
+
+msgid "--role <role>\tSet a unique role to identify the main window"
+msgstr "--role <rol>\t\tUsa un únic rol per identificar la finestra principal"
+
+msgid "--socketid <xid>\tOpen Vim inside another GTK widget"
+msgstr "--socketid <xid>\tObre el vim dins d'una altra aplicació GTK"
+
+msgid "-P <parent title>\tOpen Vim inside parent application"
+msgstr "-P <títol pare>\tObre el Vim en una aplicació pare"
+
+msgid "No display"
+msgstr "No hi ha cap pantalla"
+
+#. Failed to send, abort.
+msgid ": Send failed.\n"
+msgstr ": Error en enviar.\n"
+
+#. Let vim start normally.
+msgid ": Send failed. Trying to execute locally\n"
+msgstr ": Error en enviar. Intentant l'execució local\n"
+
+#, c-format
+msgid "%d of %d edited"
+msgstr "editat %d de %d"
+
+msgid "No display: Send expression failed.\n"
+msgstr "No hi ha cap pantalla: Error en enviar l'expressió.\n"
+
+msgid ": Send expression failed.\n"
+msgstr ": Error en enviar l'expressió.\n"
+
+msgid "No marks set"
+msgstr "No hi ha marques definides"
+
+#, c-format
+msgid "E283: No marks matching \"%s\""
+msgstr "E283: Cap marca coincideix amb \"%s\""
+
+#. Highlight title
+msgid ""
+"\n"
+"mark line col file/text"
+msgstr ""
+"\n"
+"marca lín col fitxer/text"
+
+#. Highlight title
+msgid ""
+"\n"
+" jump line col file/text"
+msgstr ""
+"\n"
+" salt lín col fitxer/text"
+
+#. Highlight title
+msgid ""
+"\n"
+"change line col text"
+msgstr ""
+"\n"
+"canvi línia col text"
+
+#, c-format
+msgid ""
+"\n"
+"# File marks:\n"
+msgstr ""
+"\n"
+"# Marques de fitxer:\n"
+
+#. Write the jumplist with -'
+#, c-format
+msgid ""
+"\n"
+"# Jumplist (newest first):\n"
+msgstr ""
+"\n"
+"# Llista de salts (de més a menys recent):\n"
+
+#, c-format
+msgid ""
+"\n"
+"# History of marks within files (newest to oldest):\n"
+msgstr ""
+"\n"
+"# Historial de marques en fitxers (de més a menys recent):\n"
+
+msgid "Missing '>'"
+msgstr "Falta un '>'"
+
+msgid "E543: Not a valid codepage"
+msgstr "E543: No és un codi de pàgina vàlid"
+
+msgid "E284: Cannot set IC values"
+msgstr "E284: No s'han pogut establir els valors del context d'entrada"
+
+msgid "E285: Failed to create input context"
+msgstr "E285: Error en crear el context d'entrada"
+
+msgid "E286: Failed to open input method"
+msgstr "E286: Error en obrir el mètode d'entrada"
+
+msgid "E287: Warning: Could not set destroy callback to IM"
+msgstr "E287: Atenció: No s'ha pogut establir el callback de destrucció a IM"
+
+msgid "E288: input method doesn't support any style"
+msgstr "E288: el mètode d'entrada no suporta cap estil"
+
+msgid "E289: input method doesn't support my preedit type"
+msgstr "E289: el mètode d'entrada no suporta el tipus de preedició"
+
+msgid "E290: over-the-spot style requires fontset"
+msgstr "E290: L'estil over-the-spot requereix un conjunt de tipus"
+
+msgid "E291: Your GTK+ is older than 1.2.3. Status area disabled"
+msgstr "E291: La llibreria GTK+ és anterior a 1.2.3. Es deshabilita l'àrea d'estat"
+
+msgid "E292: Input Method Server is not running"
+msgstr "E292: El servidor de mètodes d'entrada (IMS) no està funcionant"
+
+msgid "E293: block was not locked"
+msgstr "E293: El bloc no estava bloquejat"
+
+msgid "E294: Seek error in swap file read"
+msgstr "E294: Error de posició quan es llegia el fitxer d'intercanvi"
+
+msgid "E295: Read error in swap file"
+msgstr "E295: Error de lectura en el fitxer d'intercanvi"
+
+msgid "E296: Seek error in swap file write"
+msgstr "E296: Error de posició quan s'escrivia el fitxer d'intercanvi"
+
+msgid "E297: Write error in swap file"
+msgstr "E297: Error d'escriptura en el fitxer d'intercanvi"
+
+msgid "E300: Swap file already exists (symlink attack?)"
+msgstr "E300: El fitxer d'intercanvi encara existeix"
+
+msgid "E298: Didn't get block nr 0?"
+msgstr "E298: No s'ha pogut obtenir el bloc 0?"
+
+msgid "E298: Didn't get block nr 1?"
+msgstr "E298: No s'ha pogut obtenir el bloc 1?"
+
+msgid "E298: Didn't get block nr 2?"
+msgstr "E298: No s'ha pogut obtenir el bloc 3?"
+
+#. could not (re)open the swap file, what can we do????
+msgid "E301: Oops, lost the swap file!!!"
+msgstr "E301: Ep! El fitxer d'intercanvi s'ha perdut!!!"
+
+msgid "E302: Could not rename swap file"
+msgstr "E302: No s'ha pogut reanomenar el fitxer d'intercanvi"
+
+#, c-format
+msgid "E303: Unable to open swap file for \"%s\", recovery impossible"
+msgstr "E303: Error en obrir el fitxer d'intercanvi de \"%s\", no es podrà recuperar"
+
+msgid "E304: ml_upd_block0(): Didn't get block 0??"
+msgstr "E304: ml_upd_block0(): No s'ha obtingut el bloc 0??"
+
+#, c-format
+msgid "E305: No swap file found for %s"
+msgstr "E305: No s'ha trobat el fitxer d'intercanvi de %s"
+
+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): "
+
+#, c-format
+msgid "E306: Cannot open %s"
+msgstr "E306: No s'ha pogut obrir %s"
+
+msgid "Unable to read block 0 from "
+msgstr "No s'ha pogut llegir el bloc 0 de "
+
+msgid ""
+"\n"
+"Maybe no changes were made or Vim did not update the swap file."
+msgstr ""
+"\n"
+"O bé no s'han fet canvis, o el Vim no ha actualitzat el fitxer d'intercanvi."
+
+msgid " cannot be used with this version of Vim.\n"
+msgstr " no es pot utilitzar amb aquesta versió de Vim.\n"
+
+msgid "Use Vim version 3.0.\n"
+msgstr "Useu Vim versió 3.0.\n"
+
+#, c-format
+msgid "E307: %s does not look like a Vim swap file"
+msgstr "E307: %s no sembla un fitxer d'intercanvi de Vim"
+
+msgid " cannot be used on this computer.\n"
+msgstr " no es pot utilitzar en aquest ordinador.\n"
+
+msgid "The file was created on "
+msgstr "El fitxer va ser creat el "
+
+msgid ""
+",\n"
+"or the file has been damaged."
+msgstr ""
+",\n"
+"o el fitxer està fet malbé."
+
+msgid " has been damaged (page size is smaller than minimum value).\n"
+msgstr " ha estat danyat (la mida de pàgina és inferior al valor mínim).\n"
+
+#, c-format
+msgid "Using swap file \"%s\""
+msgstr "S'està utilitzant el fitxer d'intercanvi \"%s\""
+
+#, c-format
+msgid "Original file \"%s\""
+msgstr "Fitxer original \"%s\""
+
+msgid "E308: Warning: Original file may have been changed"
+msgstr "E308: Atenció: El fitxer original pot haver canviat"
+
+#, c-format
+msgid "E309: Unable to read block 1 from %s"
+msgstr "E309: No s'ha pogut llegir el bloc 1 de %s"
+
+msgid "???MANY LINES MISSING"
+msgstr "???FALTEN MOLTES LÍNIES"
+
+msgid "???LINE COUNT WRONG"
+msgstr "???RECOMPTE DE LÍNIES INCORRECTE"
+
+msgid "???EMPTY BLOCK"
+msgstr "???BLOC BUIT"
+
+msgid "???LINES MISSING"
+msgstr "???FALTEN LÍNIES"
+
+#, c-format
+msgid "E310: Block 1 ID wrong (%s not a .swp file?)"
+msgstr "E310: L'ID del bloc 1 no és correcta (%s no és un fitxer .swp?)"
+
+msgid "???BLOCK MISSING"
+msgstr "???FALTA UN BLOC"
+
+msgid "??? from here until ???END lines may be messed up"
+msgstr "??? Des d'aquí fins ???FINAL les línies poden estar equivocades"
+
+msgid "??? from here until ???END lines may have been inserted/deleted"
+msgstr "??? Des d'aquí fins ???FINAL hi pot haver línies inserides/eliminades"
+
+msgid "???END"
+msgstr "???FINAL"
+
+msgid "E311: Recovery Interrupted"
+msgstr "E311: S'ha interromput la recuperació"
+
+msgid "E312: Errors detected while recovering; look for lines starting with ???"
+msgstr "E312: S'han detectat errors en la recuperació; busqueu línies amb ???"
+
+msgid "See \":help E312\" for more information."
+msgstr "Vegeu \":help E312\" per a més informació."
+
+msgid "Recovery completed. You should check if everything is OK."
+msgstr "S'ha completat la recuperació. Haurieu de revisar que tot sigui correcte."
+
+msgid ""
+"\n"
+"(You might want to write out this file under another name\n"
+msgstr ""
+"\n"
+"(Potser voleu desar aquest fitxer amb un altre nom\n"
+
+msgid "and run diff with the original file to check for changes)\n"
+msgstr "i fer un diff amb el fitxer original per veure els canvis)\n"
+
+msgid ""
+"Delete the .swp file afterwards.\n"
+"\n"
+msgstr ""
+"Elimina el fitxer .swp tot seguit.\n"
+"\n"
+
+#. use msg() to start the scrolling properly
+msgid "Swap files found:"
+msgstr "Fitxers d'intercanvi trobats:"
+
+msgid " In current directory:\n"
+msgstr " En el directori actual:\n"
+
+msgid " Using specified name:\n"
+msgstr " Usant el nom especificat:\n"
+
+msgid " In directory "
+msgstr " En el directori "
+
+msgid " -- none --\n"
+msgstr " -- cap --\n"
+
+msgid " owned by: "
+msgstr " propietat de: "
+
+msgid " dated: "
+msgstr " amb data: "
+
+msgid " dated: "
+msgstr " amb data: "
+
+msgid " [from Vim version 3.0]"
+msgstr " [del Vim versió 3.0]"
+
+msgid " [does not look like a Vim swap file]"
+msgstr " [no sembla un fitxer d'intercanvi de Vim]"
+
+msgid " file name: "
+msgstr " nom del fitxer: "
+
+msgid ""
+"\n"
+" modified: "
+msgstr ""
+"\n"
+" modificat: "
+
+msgid "YES"
+msgstr "SÍ"
+
+msgid "no"
+msgstr "no"
+
+msgid ""
+"\n"
+" user name: "
+msgstr ""
+"\n"
+" nom de l'usuari: "
+
+msgid " host name: "
+msgstr " màquina: "
+
+msgid ""
+"\n"
+" host name: "
+msgstr ""
+"\n"
+" màquina: "
+
+msgid ""
+"\n"
+" process ID: "
+msgstr ""
+"\n"
+" ID del procés: "
+
+msgid " (still running)"
+msgstr " (encara funcionant)"
+
+msgid ""
+"\n"
+" [not usable with this version of Vim]"
+msgstr ""
+"\n"
+" [no usable amb aquesta versió de Vim]"
+
+msgid ""
+"\n"
+" [not usable on this computer]"
+msgstr ""
+"\n"
+" [no usable en aquesta computadora]"
+
+msgid " [cannot be read]"
+msgstr " [no es pot llegir]"
+
+msgid " [cannot be opened]"
+msgstr " [no es pot obrir]"
+
+msgid "E313: Cannot preserve, there is no swap file"
+msgstr "E313: No s'ha pogut preservar, no hi ha fitxer d'intercanvi"
+
+msgid "File preserved"
+msgstr "S'ha preservat el fitxer"
+
+msgid "E314: Preserve failed"
+msgstr "E314: La preservació ha fallat"
+
+#, c-format
+msgid "E315: ml_get: invalid lnum: %ld"
+msgstr "E315: ml_get: lnum no vàlid: %ld"
+
+#, c-format
+msgid "E316: ml_get: cannot find line %ld"
+msgstr "E316: ml_get: no s'ha trobat la línia %ld"
+
+msgid "E317: pointer block id wrong 3"
+msgstr "E317: Punter a la id d'un bloc incorrecte 3"
+
+msgid "stack_idx should be 0"
+msgstr "stack_idx hauria de ser 0"
+
+msgid "E318: Updated too many blocks?"
+msgstr "E318: S'han actualitzat massa blocs?"
+
+msgid "E317: pointer block id wrong 4"
+msgstr "E317: Punter a la id d'un bloc incorrecte 4"
+
+msgid "deleted block 1?"
+msgstr "s'ha eliminat el bloc 1?"
+
+#, c-format
+msgid "E320: Cannot find line %ld"
+msgstr "E320: No s'ha trobat la línia %ld"
+
+msgid "E317: pointer block id wrong"
+msgstr "E317: Punter a la id d'un bloc incorrecte"
+
+msgid "pe_line_count is zero"
+msgstr "po_line_count és zero"
+
+#, c-format
+msgid "E322: line number out of range: %ld past the end"
+msgstr "E322: Nombre de línia fora d'abast: %ld passat el final"
+
+#, c-format
+msgid "E323: line count wrong in block %ld"
+msgstr "E323: Comptador de línia incorrecte al bloc %ld"
+
+msgid "Stack size increases"
+msgstr "La mida de la pila s'incrementa"
+
+msgid "E317: pointer block id wrong 2"
+msgstr "E317: Punter a la id d'un bloc incorrecte 2"
+
+#, c-format
+msgid "E773: Symlink loop for \"%s\""
+msgstr "E773: Bucle d'enllaços simbòlics per a \"%s\""
+
+msgid "E325: ATTENTION"
+msgstr "E325: ATENCIÓ"
+
+msgid ""
+"\n"
+"Found a swap file by the name \""
+msgstr ""
+"\n"
+"S'ha trobat un fitxer d'intercanvi de nom \""
+
+msgid "While opening file \""
+msgstr "Mentre s'obria el fitxer \""
+
+msgid " NEWER than swap file!\n"
+msgstr " MÉS NOU que el fitxer d'intercanvi!\n"
+
+#. Some of these messages are long to allow translation to
+#. * other languages.
+msgid ""
+"\n"
+"(1) Another program may be editing the same file.\n"
+" If this is the case, be careful not to end up with two\n"
+" different instances of the same file when making changes.\n"
+msgstr ""
+"\n"
+"(1) Un altre programa pot estar editant aquest mateix fitxer.\n"
+" En aquest cas, aneu amb compte de no acabar amb dues\n"
+" instàncies diferents del mateix fitxer quan feu canvis.\n"
+
+msgid " Quit, or continue with caution.\n"
+msgstr " Sortiu, o continueu amb precaució.\n"
+
+msgid ""
+"\n"
+"(2) An edit session for this file crashed.\n"
+msgstr ""
+"\n"
+"(2) El Vim s'ha estrellat mentre s'editava aquest fitxer.\n"
+
+msgid " If this is the case, use \":recover\" or \"vim -r "
+msgstr " En aquest cas, useu \":recover\" o bé \"vim -r "
+
+msgid ""
+"\"\n"
+" to recover the changes (see \":help recovery\").\n"
+msgstr ""
+"\"\n"
+" per recuperar els canvis (vegeu \":help recovery\").\n"
+
+msgid " If you did this already, delete the swap file \""
+msgstr " Si ja ho heu fet, elimineu el fitxer \""
+
+msgid ""
+"\"\n"
+" to avoid this message.\n"
+msgstr ""
+"\"\n"
+" per evitar aquest missatge.\n"
+
+msgid "Swap file \""
+msgstr "El fitxer d'intercanvi \""
+
+msgid "\" already exists!"
+msgstr "\" ja existeix!"
+
+msgid "VIM - ATTENTION"
+msgstr "VIM - ATENCIÓ"
+
+msgid "Swap file already exists!"
+msgstr "El fitxer d'intercanvi ja existeix!"
+
+msgid ""
+"&Open Read-Only\n"
+"&Edit anyway\n"
+"&Recover\n"
+"&Quit\n"
+"&Abort"
+msgstr ""
+"&Obrir només-lectura\n"
+"&Editar igualment\n"
+"&Recuperar\n"
+"&Sortir\n"
+"&Avortar"
+
+msgid ""
+"&Open Read-Only\n"
+"&Edit anyway\n"
+"&Recover\n"
+"&Delete it\n"
+"&Quit\n"
+"&Abort"
+msgstr ""
+"&Obrir només-lectura\n"
+"&Editar igualment\n"
+"&Recuperar\n"
+"E&liminar-lo\n"
+"&Sortir\n"
+"&Avortar"
+
+msgid "E326: Too many swap files found"
+msgstr "E326: S'han trobat massa fitxers d'intercanvi"
+
+msgid "E327: Part of menu-item path is not sub-menu"
+msgstr "E327: Part de l'ubicació del menú no és submenú"
+
+msgid "E328: Menu only exists in another mode"
+msgstr "E328: El menú només existeix en un altre mode"
+
+#, c-format
+msgid "E329: No menu \"%s\""
+msgstr "E329: No hi ha cap menú \"%s\""
+
+#. Only a mnemonic or accelerator is not valid.
+msgid "E792: Empty menu name"
+msgstr "E792: Nom de menú buit"
+
+msgid "E330: Menu path must not lead to a sub-menu"
+msgstr "E330: L'ubicació del menú no pot portar a un submenú"
+
+msgid "E331: Must not add menu items directly to menu bar"
+msgstr "E331: No es poden afegir ítems de menú directament a la barra de menú"
+
+msgid "E332: Separator cannot be part of a menu path"
+msgstr "E332: Un separador no pot formar part de l'ubicació de menú"
+
+#. Now we have found the matching menu, and we list the mappings
+#. Highlight title
+msgid ""
+"\n"
+"--- Menus ---"
+msgstr ""
+"\n"
+"--- Menús ---"
+
+msgid "Tear off this menu"
+msgstr "Estripa aquest menú"
+
+msgid "E333: Menu path must lead to a menu item"
+msgstr "E333: L'ubicació de menú ha de portar a un ítem de menú"
+
+#, c-format
+msgid "E334: Menu not found: %s"
+msgstr "E334: No s'ha trobat el menú: %s"
+
+#, c-format
+msgid "E335: Menu not defined for %s mode"
+msgstr "E335: El menú no està definit pel mode %s"
+
+msgid "E336: Menu path must lead to a sub-menu"
+msgstr "E336: L'ubicació de menú ha de portar a un submenú"
+
+msgid "E337: Menu not found - check menu names"
+msgstr "E337: No s'ha trobat el menú - reviseu els noms dels menús"
+
+#, c-format
+msgid "Error detected while processing %s:"
+msgstr "S'ha detectat un error en processar %s:"
+
+#, c-format
+msgid "line %4ld:"
+msgstr "línia %4ld:"
+
+#, c-format
+msgid "E354: Invalid register name: '%s'"
+msgstr "E354: El nom de registre no és vàlid: '%s'"
+
+msgid "Messages maintainer: Bram Moolenaar <Bram@vim.org>"
+msgstr "Traducció dels missatges: Ernest Adrogué <eadrogue@gmx.net>"
+
+msgid "Interrupt: "
+msgstr "Interrupció: "
+
+msgid "Press ENTER or type command to continue"
+msgstr "Premeu ENTRAR o introduïu una ordre per a continuar"
+
+#, c-format
+msgid "%s line %ld"
+msgstr "%s línia %ld"
+
+msgid "-- More --"
+msgstr "-- Més --"
+
+msgid " SPACE/d/j: screen/page/line down, b/u/k: up, q: quit "
+msgstr " ESPAI/d/j: pantalla/pàgina/línia avall, b/u/k: amunt, q: sortir "
+
+msgid "Question"
+msgstr "Pregunta"
+
+msgid ""
+"&Yes\n"
+"&No"
+msgstr ""
+"&Sí\n"
+"&No"
+
+msgid ""
+"&Yes\n"
+"&No\n"
+"Save &All\n"
+"&Discard All\n"
+"&Cancel"
+msgstr ""
+"&Sí\n"
+"&No\n"
+"Desa-ho &tot\n"
+"&Descarta-ho tot\n"
+"&Cancel·la"
+
+msgid "Select Directory dialog"
+msgstr "Diàleg de selecció de directori"
+
+msgid "Save File dialog"
+msgstr "Diàleg de desar fitxer"
+
+msgid "Open File dialog"
+msgstr "Diàleg d'obrir fitxer"
+
+#. TODO: non-GUI file selector here
+msgid "E338: Sorry, no file browser in console mode"
+msgstr "E338: No hi ha un explorador de fitxers en mode consola"
+
+msgid "E766: Insufficient arguments for printf()"
+msgstr "E766: Falten arguments per a printf()"
+
+msgid "E767: Too many arguments to printf()"
+msgstr "E767: Sobren arguments per a printf()"
+
+msgid "W10: Warning: Changing a readonly file"
+msgstr "W10: Atenció: S'està canviant un fitxer de només lectura"
+
+msgid "Type number or click with mouse (<Enter> cancels): "
+msgstr "Introduïu un número o feu clic amb el ratolí (<Entrar> per a cancel·lar): "
+
+msgid "Choice number (<Enter> cancels): "
+msgstr "Trieu un número (<Entrar> per a cancel·lar): "
+
+msgid "1 more line"
+msgstr "1 línia més"
+
+msgid "1 line less"
+msgstr "1 línia menys"
+
+#, c-format
+msgid "%ld more lines"
+msgstr "%ld línies més"
+
+#, c-format
+msgid "%ld fewer lines"
+msgstr "%ld línies menys"
+
+msgid " (Interrupted)"
+msgstr " (Interromput)"
+
+msgid "Beep!"
+msgstr "Bip!"
+
+msgid "Vim: preserving files...\n"
+msgstr "Vim: preservant els fitxers...\n"
+
+#. close all memfiles, without deleting
+msgid "Vim: Finished.\n"
+msgstr "Vim: Finalitzat.\n"
+
+#, c-format
+msgid "ERROR: "
+msgstr "ERROR: "
+
+#, c-format
+msgid ""
+"\n"
+"[bytes] total alloc-freed %lu-%lu, in use %lu, peak use %lu\n"
+msgstr ""
+"\n"
+"[octets] total assignat-alliberat %lu-%lu, en ús %lu, màxim ús %lu\n"
+
+#, c-format
+msgid ""
+"[calls] total re/malloc()'s %lu, total free()'s %lu\n"
+"\n"
+msgstr ""
+"[crides] total re/malloc() %lu, total free() %lu\n"
+"\n"
+
+msgid "E340: Line is becoming too long"
+msgstr "E340: La línia s'està tornant massa llarga"
+
+#, c-format
+msgid "E341: Internal error: lalloc(%ld, )"
+msgstr "E341: Error intern: lalloc(%ld, )"
+
+#, c-format
+msgid "E342: Out of memory! (allocating %lu bytes)"
+msgstr "E342: Memòria exhaurida! (assignant %lu octets)"
+
+#, c-format
+msgid "Calling shell to execute: \"%s\""
+msgstr "S'està cridant l'intèrpret d'ordres per executar: \"%s\""
+
+msgid "E545: Missing colon"
+msgstr "E545: Falta un caràcter \":\""
+
+msgid "E546: Illegal mode"
+msgstr "E546: Mode il·legal"
+
+msgid "E547: Illegal mouseshape"
+msgstr "E547: La forma del punter del ratolí és il·legal"
+
+msgid "E548: digit expected"
+msgstr "E548: S'esperava un dígit"
+
+msgid "E549: Illegal percentage"
+msgstr "E549: Percentatge il·legal"
+
+msgid "Enter encryption key: "
+msgstr "Introduïu la clau de xifrat: "
+
+msgid "Enter same key again: "
+msgstr "Introduïu la mateixa clau un altre cop: "
+
+msgid "Keys don't match!"
+msgstr "La claus no coincideixen!"
+
+#, c-format
+msgid "E343: Invalid path: '**[number]' must be at the end of the path or be followed by '%s'."
+msgstr "E343: Path no vàlid: '**[núm]' ha d'estar al final del path, o seguit de '%s'"
+
+#, c-format
+msgid "E344: Can't find directory \"%s\" in cdpath"
+msgstr "E344: No s'ha trobat el directori \"%s\" en el cdpath"
+
+#, c-format
+msgid "E345: Can't find file \"%s\" in path"
+msgstr "E345: No s'ha trobat el fitxer \"%s\" en el path"
+
+#, c-format
+msgid "E346: No more directory \"%s\" found in cdpath"
+msgstr "E346: No s'ha trobat cap més directori \"%s\" en el cdpath"
+
+#, c-format
+msgid "E347: No more file \"%s\" found in path"
+msgstr "E347: No s'ha trobat cap més fitxer \"%s\" en el path"
+
+#. Get here when the server can't be found.
+msgid "Cannot connect to Netbeans #2"
+msgstr "No s'ha pogut connectar amb Netbeans #2"
+
+msgid "Cannot connect to Netbeans"
+msgstr "No s'ha pogut connectar amb Netbeans"
+
+#, c-format
+msgid "E668: Wrong access mode for NetBeans connection info file: \"%s\""
+msgstr "E668: Mode d'accés incorrecte per al fitxer d'info de la connexió NetBeans: \"%s\""
+
+msgid "read from Netbeans socket"
+msgstr "lectura d'un socket Netbeans"
+
+#, c-format
+msgid "E658: NetBeans connection lost for buffer %ld"
+msgstr "E658: S'ha perdut la connexió NetBeans per al buffer %ld"
+
+msgid "E505: "
+msgstr "E505:"
+
+msgid "E774: 'operatorfunc' is empty"
+msgstr "E774: 'operatorfunc' no conté res"
+
+msgid "E775: Eval feature not available"
+msgstr "E775: La funció eval no està disponible"
+
+msgid "Warning: terminal cannot highlight"
+msgstr "Atenció: el terminal no suporta ressalt"
+
+msgid "E348: No string under cursor"
+msgstr "E348: No hi ha cap cadena sota el cursor"
+
+msgid "E349: No identifier under cursor"
+msgstr "E349: No hi ha cap identificador sota el cursor"
+
+msgid "E352: Cannot erase folds with current 'foldmethod'"
+msgstr "E352: No es poden eliminar plecs amb el 'foldmethod' actual"
+
+msgid "E664: changelist is empty"
+msgstr "E664: La llista de canvis no conté res"
+
+msgid "E662: At start of changelist"
+msgstr "E662: A l'inici de la llista de canvis"
+
+msgid "E663: At end of changelist"
+msgstr "E663: A l'inici de la llista de canvis"
+
+# amplada 53 caràcters
+msgid "Type :quit<Enter> to exit Vim"
+msgstr "Feu :quit<Entrar> per sortir"
+
+#, c-format
+msgid "1 line %sed 1 time"
+msgstr "1 línia %sada 1 vegada"
+
+#, c-format
+msgid "1 line %sed %d times"
+msgstr "1 línia %sada %d vegades"
+
+#, c-format
+msgid "%ld lines %sed 1 time"
+msgstr "%ld línies %sades 1 vegada"
+
+#, c-format
+msgid "%ld lines %sed %d times"
+msgstr "%ld línies %sades %d vegades"
+
+#, c-format
+msgid "%ld lines to indent... "
+msgstr "%ld línies a sagnar... "
+
+msgid "1 line indented "
+msgstr "1 línia sagnada "
+
+#, c-format
+msgid "%ld lines indented "
+msgstr "%ld línies sagnades "
+
+msgid "E748: No previously used register"
+msgstr "E748: No hi ha cap registre usat amb anterioritat"
+
+#. must display the prompt
+msgid "cannot yank; delete anyway"
+msgstr "no s'ha pogut copiar; voleu elimiar el text de totes maneres"
+
+msgid "1 line changed"
+msgstr "1 línia canviada"
+
+#, c-format
+msgid "%ld lines changed"
+msgstr "%ld línies canviades"
+
+#, c-format
+msgid "freeing %ld lines"
+msgstr "alliberant %ld línies"
+
+msgid "block of 1 line yanked"
+msgstr "bloc d'1 línia copiat"
+
+msgid "1 line yanked"
+msgstr "1 línia copiada"
+
+#, c-format
+msgid "block of %ld lines yanked"
+msgstr "bloc de %ld línies copiat"
+
+#, c-format
+msgid "%ld lines yanked"
+msgstr "%ld línies copiades"
+
+#, c-format
+msgid "E353: Nothing in register %s"
+msgstr "E353: No hi ha res en el registre %s"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Registers ---"
+msgstr ""
+"\n"
+"--- Registres ---"
+
+msgid "Illegal register name"
+msgstr "El nom de registre és il·legal"
+
+#, c-format
+msgid ""
+"\n"
+"# Registers:\n"
+msgstr ""
+"\n"
+"# Registres:\n"
+
+#, c-format
+msgid "E574: Unknown register type %d"
+msgstr "E574: El tipus de registre %d és desconegut"
+
+#, c-format
+msgid "%ld Cols; "
+msgstr "%ld Cols; "
+
+#, c-format
+msgid "Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Bytes"
+msgstr "Selecció %s%ld de %ld Línies; %ld de %ld Paraules; %ld de %ld Octets"
+
+#, c-format
+msgid "Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Chars; %ld of %ld Bytes"
+msgstr "Selecció %s%ld de %ld Línies; %ld de %ld Paraules; %ld de %ld Caràcters; %ld de %ld Octets"
+
+#, c-format
+msgid "Col %s of %s; Line %ld of %ld; Word %ld of %ld; Byte %ld of %ld"
+msgstr "Col %s de %s; Línia %ld de %ld; Paraula %ld de %ld; Octet %ld de %ld"
+
+#, c-format
+msgid "Col %s of %s; Line %ld of %ld; Word %ld of %ld; Char %ld of %ld; Byte %ld of %ld"
+msgstr "Col %s de %s; Línia %ld de %ld; Paraula %ld de %ld; Caràcter %ld de %ld; Octet %ld de %ld"
+
+#, c-format
+msgid "(+%ld for BOM)"
+msgstr "(+%ld per la BOM)"
+
+msgid "%<%f%h%m%=Page %N"
+msgstr "%<%f%h%m%=Pàgina %N"
+
+msgid "Thanks for flying Vim"
+msgstr "Gràcies per utilitzar el Vim"
+
+msgid "E518: Unknown option"
+msgstr "E518: L'opció és desconeguda"
+
+msgid "E519: Option not supported"
+msgstr "E519: L'opció no està suportada"
+
+msgid "E520: Not allowed in a modeline"
+msgstr "E520: No està permès en una línia de mode"
+
+msgid "E521: Number required after ="
+msgstr "E521: Es requereix un número després de ="
+
+msgid "E522: Not found in termcap"
+msgstr "E522: No s'ha trobat a la base de dades termcap"
+
+#, c-format
+msgid "E539: Illegal character <%s>"
+msgstr "E539: Caràcter il·legal <%s>"
+
+msgid "E529: Cannot set 'term' to empty string"
+msgstr "E529: No es pot definir 'term' com a cadena buida"
+
+msgid "E530: Cannot change term in GUI"
+msgstr "E530: No es pot canviar de terminal en mode GUI"
+
+msgid "E531: Use \":gui\" to start the GUI"
+msgstr "E531: Useu \":gui\" per ininciar l'interfície d'usuari gràfica"
+
+msgid "E589: 'backupext' and 'patchmode' are equal"
+msgstr "E589: Les opcions 'backupext' i 'patchmode' coincideixen"
+
+msgid "E617: Cannot be changed in the GTK+ 2 GUI"
+msgstr "E617: L'interfície GTK+ 2 no permet canviar la codificació"
+
+msgid "E524: Missing colon"
+msgstr "E524: Falta un caràcter \":\""
+
+msgid "E525: Zero length string"
+msgstr "E525: La llargada de la cadena és zero"
+
+#, c-format
+msgid "E526: Missing number after <%s>"
+msgstr "E526: Falta un número després de <%s>"
+
+msgid "E527: Missing comma"
+msgstr "E527: Falta una coma"
+
+msgid "E528: Must specify a ' value"
+msgstr "E528: Heu d'especificar un valor '"
+
+msgid "E595: contains unprintable or wide character"
+msgstr "E595: Conté un caràcter no imprimible o ample"
+
+msgid "E596: Invalid font(s)"
+msgstr "E596: Fosa no vàlida"
+
+msgid "E597: can't select fontset"
+msgstr "E597: No s'ha pogut seleccionar el conjunt de tipus"
+
+msgid "E598: Invalid fontset"
+msgstr "E598: El conjunt de tipus de lletra no és vàlid"
+
+msgid "E533: can't select wide font"
+msgstr "E533: No s'ha pogut seleccionar una fosa ampla"
+
+msgid "E534: Invalid wide font"
+msgstr "E534: Fosa ampla no vàlida"
+
+#, c-format
+msgid "E535: Illegal character after <%c>"
+msgstr "E535: Caràcter il·legal després de <%c>"
+
+msgid "E536: comma required"
+msgstr "E536: Es requereix una coma"
+
+#, c-format
+msgid "E537: 'commentstring' must be empty or contain %s"
+msgstr "E537: L'opció 'commentstring' ha d'estar indefinida o contenir %s"
+
+msgid "E538: No mouse support"
+msgstr "E538: No hi ha suport per ratolí"
+
+msgid "E540: Unclosed expression sequence"
+msgstr "E540: La seqüència d'expressions no està acabada"
+
+msgid "E541: too many items"
+msgstr "E541: Hi han massa ítems"
+
+msgid "E542: unbalanced groups"
+msgstr "E542: Grups desequilibrats"
+
+msgid "E590: A preview window already exists"
+msgstr "E590: Ja hi ha una finestra de vista prèvia"
+
+msgid "W17: Arabic requires UTF-8, do ':set encoding=utf-8'"
+msgstr "W17: L'àrab requereix UTF-8, feu ':set encoding=utf-8'"
+
+#, c-format
+msgid "E593: Need at least %d lines"
+msgstr "E593: Es necessiten com a mínim %d línies"
+
+#, c-format
+msgid "E594: Need at least %d columns"
+msgstr "E594: Es necessiten com a mínim %d columnes"
+
+#, c-format
+msgid "E355: Unknown option: %s"
+msgstr "E355: L'opció és desconeguda: %s"
+
+msgid ""
+"\n"
+"--- Terminal codes ---"
+msgstr ""
+"\n"
+"--- Codis de terminal ---"
+
+msgid ""
+"\n"
+"--- Global option values ---"
+msgstr ""
+"\n"
+"--- Valors de les opcions globals ---"
+
+msgid ""
+"\n"
+"--- Local option values ---"
+msgstr ""
+"\n"
+"--- Valors de les opcions locals ---"
+
+msgid ""
+"\n"
+"--- Options ---"
+msgstr ""
+"\n"
+"--- Opcions ---"
+
+msgid "E356: get_varp ERROR"
+msgstr "E356: Error en get_varp()"
+
+#, c-format
+msgid "E357: 'langmap': Matching character missing for %s"
+msgstr "E357: 'langmap': No s'ha trobat el caràcter corresponent a %s"
+
+#, c-format
+msgid "E358: 'langmap': Extra characters after semicolon: %s"
+msgstr "E358: 'langmap': Sobren caràcters després del punt i coma: %s"
+
+msgid "cannot open "
+msgstr "no s'ha pogut obrir "
+
+msgid "VIM: Can't open window!\n"
+msgstr "VIM: No s'ha pogut obrir la finestra!\n"
+
+msgid "Need Amigados version 2.04 or later\n"
+msgstr "Es requereix Amigados versió 2.04 o posterior\n"
+
+#, c-format
+msgid "Need %s version %ld\n"
+msgstr "Es requereix %s versió %ld\n"
+
+msgid "Cannot open NIL:\n"
+msgstr "No s'ha pogut obrir NIL:\n"
+
+msgid "Cannot create "
+msgstr "No s'ha pogut crear "
+
+#, c-format
+msgid "Vim exiting with %d\n"
+msgstr "Vim ha finalitzat amb %d\n"
+
+msgid "cannot change console mode ?!\n"
+msgstr "no s'ha pogut canviar el mode de consola ?!\n"
+
+msgid "mch_get_shellsize: not a console??\n"
+msgstr "mch_get_shellsize: no és una consola??\n"
+
+#. if Vim opened a window: Executing a shell may cause crashes
+msgid "E360: Cannot execute shell with -f option"
+msgstr "E360: No s'ha pogut executar l'intèrpret d'ordres amb l'opció -f"
+
+msgid "Cannot execute "
+msgstr "No s'ha pogut executar "
+
+msgid "shell "
+msgstr "l'intèrpret d'ordres "
+
+msgid " returned\n"
+msgstr " ha retornat\n"
+
+msgid "ANCHOR_BUF_SIZE too small."
+msgstr "un valor ANCHOR_BUF_SIZE massa petit."
+
+msgid "I/O ERROR"
+msgstr "ERROR d'E/S"
+
+msgid "Message"
+msgstr "Missatge"
+
+msgid "'columns' is not 80, cannot execute external commands"
+msgstr "L'opció 'columns' no és 80, no es poden executar ordres externes"
+
+msgid "E237: Printer selection failed"
+msgstr "E237: La selecció d'impressora ha fallat"
+
+# a IMPRESSORA a PORT ?
+#, c-format
+msgid "to %s on %s"
+msgstr "a %s a %s"
+
+#, c-format
+msgid "E613: Unknown printer font: %s"
+msgstr "E613: Fosa d'impressió desconeguda: %s"
+
+#, c-format
+msgid "E238: Print error: %s"
+msgstr "E238: Error d'impressió: %s"
+
+#, c-format
+msgid "Printing '%s'"
+msgstr "S'està imprimint '%s'"
+
+#, c-format
+msgid "E244: Illegal charset name \"%s\" in font name \"%s\""
+msgstr "E244: Conjunt de caràcters \"%s\" il·legal en el tipus \"%s\""
+
+#, c-format
+msgid "E245: Illegal char '%c' in font name \"%s\""
+msgstr "E245: Caràcter '%c' il·legal en el tipus \"%s\""
+
+msgid "Vim: Double signal, exiting\n"
+msgstr "Vim: S'ha rebut un doble senyal, sortint\n"
+
+#, c-format
+msgid "Vim: Caught deadly signal %s\n"
+msgstr "Vim: S'ha rebut un senyal letal %s\n"
+
+#, c-format
+msgid "Vim: Caught deadly signal\n"
+msgstr "Vim: S'ha rebut un senyal letal\n"
+
+# display
+#, c-format
+msgid "Opening the X display took %ld msec"
+msgstr "S'ha trigat %ld mseg en obrir el display X"
+
+msgid ""
+"\n"
+"Vim: Got X error\n"
+msgstr ""
+"\n"
+"Vim: Error de X\n"
+
+# display
+msgid "Testing the X display failed"
+msgstr "Ha fallat la comprovació del display X"
+
+# display
+msgid "Opening the X display timed out"
+msgstr "S'ha esgotat el temps mentre es tractava d'obrir el display X"
+
+msgid ""
+"\n"
+"Cannot execute shell "
+msgstr ""
+"\n"
+"No s'ha pogut executar la shell "
+
+msgid ""
+"\n"
+"Cannot execute shell sh\n"
+msgstr ""
+"\n"
+"No s'ha pogut executar la shell sh\n"
+
+msgid ""
+"\n"
+"shell returned "
+msgstr ""
+"\n"
+"la shell ha retornat "
+
+msgid ""
+"\n"
+"Cannot create pipes\n"
+msgstr ""
+"\n"
+"No s'han pogut crear canonades\n"
+
+msgid ""
+"\n"
+"Cannot fork\n"
+msgstr ""
+"\n"
+"No s'ha pogut bifurcar\n"
+
+msgid ""
+"\n"
+"Command terminated\n"
+msgstr ""
+"\n"
+"L'ordre ha finalitzat\n"
+
+msgid "XSMP lost ICE connection"
+msgstr "XSMP: s'ha perdut la connexió ICE"
+
+#, c-format
+msgid "dlerror = \"%s\""
+msgstr "dlerror = \"%s\""
+
+# display
+msgid "Opening the X display failed"
+msgstr "Ha fallat l'obertura del display X"
+
+msgid "XSMP handling save-yourself request"
+msgstr "XSMP: s'està duent a terme la petició save-yourself"
+
+msgid "XSMP opening connection"
+msgstr "XSMP: obrint la connexió"
+
+msgid "XSMP ICE connection watch failed"
+msgstr "XSMP: Ha fallat l'inspecció de la connexió ICE"
+
+#, c-format
+msgid "XSMP SmcOpenConnection failed: %s"
+msgstr "XSMP: Ha fallat la rutina SmcOpenConnection: %s"
+
+msgid "At line"
+msgstr "A la línia"
+
+msgid "Could not load vim32.dll!"
+msgstr "No s'ha pogut carregar vim32.dll!"
+
+msgid "VIM Error"
+msgstr "Error del VIM"
+
+msgid "Could not fix up function pointers to the DLL!"
+msgstr "No s'han pogut reassignar els punters de funcions a la DLL!"
+
+#, c-format
+msgid "shell returned %d"
+msgstr "la shell ha retornat %d"
+
+#, c-format
+msgid "Vim: Caught %s event\n"
+msgstr "Vim: S'ha rebut un event %s\n"
+
+msgid "close"
+msgstr "de finalització"
+
+msgid "logoff"
+msgstr "de final de sessió"
+
+msgid "shutdown"
+msgstr "d'apagament del sistema"
+
+msgid "E371: Command not found"
+msgstr "E371: No s'ha trobat l'ordre"
+
+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 ""
+"El programa VIMRUN.EXE no es troba en el $PATH.\n"
+"Les ordres externes no faran una pausa un cop finalitzades.\n"
+"Vegeu :help win32-vimrun per a més informació."
+
+msgid "Vim Warning"
+msgstr "Vim Atenció"
+
+#, c-format
+msgid "E372: Too many %%%c in format string"
+msgstr "E372: Sobren %%%c a la cadena de format"
+
+#, c-format
+msgid "E373: Unexpected %%%c in format string"
+msgstr "E373: %%%c inesperat a la cadena de format"
+
+msgid "E374: Missing ] in format string"
+msgstr "E374: Falta un ] a la cadena de format"
+
+#, c-format
+msgid "E375: Unsupported %%%c in format string"
+msgstr "E375: %%%c no suportat a la cadena de format"
+
+#, c-format
+msgid "E376: Invalid %%%c in format string prefix"
+msgstr "E376: %%%c no vàlid en el prefix de la cadena de format"
+
+#, c-format
+msgid "E377: Invalid %%%c in format string"
+msgstr "E377: %%%c no vàlid a la cadena de format"
+
+msgid "E378: 'errorformat' contains no pattern"
+msgstr "E378: L'opció 'errorformat' no conté cap patró"
+
+msgid "E379: Missing or empty directory name"
+msgstr "E379: Falta un nom de directori"
+
+msgid "E553: No more items"
+msgstr "E553: No hi ha més ítems"
+
+#, c-format
+msgid "(%d of %d)%s%s: "
+msgstr "(%d de %d)%s%s: "
+
+msgid " (line deleted)"
+msgstr " (línia eliminada)"
+
+msgid "E380: At bottom of quickfix stack"
+msgstr "E380: Baix de la pila quickfix"
+
+msgid "E381: At top of quickfix stack"
+msgstr "E381: Dalt de la pila quickfix"
+
+#, c-format
+msgid "error list %d of %d; %d errors"
+msgstr "llista d'errors %d de %d; %d errors"
+
+msgid "E382: Cannot write, 'buftype' option is set"
+msgstr "E382: No s'ha pogut escriure, l'opció 'buftype' no està definida"
+
+msgid "E683: File name missing or invalid pattern"
+msgstr "E683: Falta el nom de fitxer o el patró no és vàlid"
+
+#, c-format
+msgid "Cannot open file \"%s\""
+msgstr "No s'ha pogut obrir el fitxer \"%s\""
+
+msgid "E681: Buffer is not loaded"
+msgstr "E681: El buffer no està carregat"
+
+msgid "E777: String or List expected"
+msgstr "E777: S'esperava una cadena o una llista"
+
+#, c-format
+msgid "E369: invalid item in %s%%[]"
+msgstr "E369: Ítem no vàlid a %s%%[]"
+
+msgid "E339: Pattern too long"
+msgstr "E339: El patró és massa llarg"
+
+msgid "E50: Too many \\z("
+msgstr "E50: Sobren \\z("
+
+#, c-format
+msgid "E51: Too many %s("
+msgstr "E51: Sobren %s("
+
+msgid "E52: Unmatched \\z("
+msgstr "E52: \\z( desequilibrat"
+
+#, c-format
+msgid "E53: Unmatched %s%%("
+msgstr "E53: %s%%( desequilibrat"
+
+#, c-format
+msgid "E54: Unmatched %s("
+msgstr "E54: %s( desequilibrat"
+
+#, c-format
+msgid "E55: Unmatched %s)"
+msgstr "E55: %s) desequilibrat"
+
+#, c-format
+msgid "E59: invalid character after %s@"
+msgstr "E59: Hi ha un caràcter no vàlid després de %s@"
+
+#, c-format
+msgid "E60: Too many complex %s{...}s"
+msgstr "E60: La construcció %s{...} és massa complexa"
+
+#, c-format
+msgid "E61: Nested %s*"
+msgstr "E61: %s* imbricats"
+
+#, c-format
+msgid "E62: Nested %s%c"
+msgstr "E62: %s%c imbricats"
+
+msgid "E63: invalid use of \\_"
+msgstr "E63: Ús no vàlid de \\_"
+
+#, c-format
+msgid "E64: %s%c follows nothing"
+msgstr "E64: No ha ha res abans de %s%c"
+
+msgid "E65: Illegal back reference"
+msgstr "E65: Referència il·legal a l'element anterior"
+
+msgid "E66: \\z( not allowed here"
+msgstr "E66: \\z( no està permès aquí"
+
+msgid "E67: \\z1 et al. not allowed here"
+msgstr "E67: \\z1 et al. no estan permesos aquí"
+
+msgid "E68: Invalid character after \\z"
+msgstr "E68: Hi ha un caràcter no vàlid després de \\z"
+
+#, c-format
+msgid "E69: Missing ] after %s%%["
+msgstr "E69: Falta un ] després de %s%%["
+
+#, c-format
+msgid "E70: Empty %s%%[]"
+msgstr "E70: Element %s%%[] buit"
+
+#, c-format
+msgid "E678: Invalid character after %s%%[dxouU]"
+msgstr "E678: Caràcter invàlid després de %s%%[dxouU]"
+
+#, c-format
+msgid "E71: Invalid character after %s%%"
+msgstr "E71: Hi ha un caràcter invàlid després de %s%%"
+
+#, c-format
+msgid "E769: Missing ] after %s["
+msgstr "E769: Falta un ] després de %s["
+
+#, c-format
+msgid "E554: Syntax error in %s{...}"
+msgstr "E554: Error de sintaxi a %s{...}"
+
+msgid "External submatches:\n"
+msgstr "Subcoincidències externes:\n"
+
+msgid " VREPLACE"
+msgstr " SUBSTITUIRV"
+
+msgid " REPLACE"
+msgstr " SUBSTITUIR"
+
+# En el mode d'escriptura de dreta a esquerra
+# surt el missatge «REVERSE INSERT»
+msgid " REVERSE"
+msgstr " INVERS"
+
+msgid " INSERT"
+msgstr " INSERIR"
+
+msgid " (insert)"
+msgstr " (inserir)"
+
+msgid " (replace)"
+msgstr " (substituir)"
+
+msgid " (vreplace)"
+msgstr " (substituirv)"
+
+msgid " Hebrew"
+msgstr " Hebreu"
+
+msgid " Arabic"
+msgstr " Àrab"
+
+msgid " (lang)"
+msgstr " (lang)"
+
+msgid " (paste)"
+msgstr " (enganxar)"
+
+msgid " VISUAL"
+msgstr " VISUAL"
+
+msgid " VISUAL LINE"
+msgstr " VISUAL LÍNIA"
+
+msgid " VISUAL BLOCK"
+msgstr " VISUAL BLOC"
+
+msgid " SELECT"
+msgstr " SELECCIONAR"
+
+msgid " SELECT LINE"
+msgstr " SELECCIÓ LÍNIA"
+
+msgid " SELECT BLOCK"
+msgstr " SELECCIÓ BLOC"
+
+msgid "recording"
+msgstr "enregistrant"
+
+#, c-format
+msgid "E383: Invalid search string: %s"
+msgstr "E383: Cadena de cerca no vàlida: %s"
+
+#, c-format
+msgid "E384: search hit TOP without match for: %s"
+msgstr "E384: la cerca ha arribat a DALT sense resultats per: %s"
+
+#, c-format
+msgid "E385: search hit BOTTOM without match for: %s"
+msgstr "E385: la cerca ha arribat a BAIX sense resultats per: %s"
+
+msgid "E386: Expected '?' or '/' after ';'"
+msgstr "E386: S'esperava '?' o '/' després de ';'"
+
+msgid " (includes previously listed match)"
+msgstr " (inclou resultats llistats anteriorment)"
+
+#. cursor at status line
+msgid "--- Included files "
+msgstr "--- Fitxers inclosos "
+
+msgid "not found "
+msgstr "no s'ha trobat"
+
+msgid "in path ---\n"
+msgstr "en el path ---\n"
+
+msgid " (Already listed)"
+msgstr " (Ja s'havia llistat)"
+
+msgid " NOT FOUND"
+msgstr " NO TROBAT"
+
+#, c-format
+msgid "Scanning included file: %s"
+msgstr "Examinant el fitxer inclòs: %s"
+
+#, c-format
+msgid "Searching included file %s"
+msgstr "Cercant al fitxer inclòs %s"
+
+msgid "E387: Match is on current line"
+msgstr "E387: El resultat es troba a la línia actual"
+
+msgid "All included files were found"
+msgstr "S'han trobat tots els fitxers inclosos"
+
+msgid "No included files"
+msgstr "No hi han fitxers inclosos"
+
+msgid "E388: Couldn't find definition"
+msgstr "E388: No s'ha trobat la definició"
+
+msgid "E389: Couldn't find pattern"
+msgstr "E389: No s'ha trobat el patró"
+
+#, c-format
+msgid ""
+"\n"
+"# Last %sSearch Pattern:\n"
+"~"
+msgstr ""
+"\n"
+"# Últim %sPatró de Cerca:\n"
+"~"
+
+msgid "E759: Format error in spell file"
+msgstr "E759: Error de format en el fitxer d'ortografia"
+
+msgid "E758: Truncated spell file"
+msgstr "E758: Fitxer d'ortografia truncat"
+
+#, c-format
+msgid "Trailing text in %s line %d: %s"
+msgstr "Text sobrant a %s línia %d: %s"
+
+#, c-format
+msgid "Affix name too long in %s line %d: %s"
+msgstr "El nom de l'afix és massa llarg a %s línia %d: %s"
+
+msgid "E761: Format error in affix file FOL, LOW or UPP"
+msgstr "E761: Error de format en el fitxer d'afixos FOL, LOW o UPP"
+
+msgid "E762: Character in FOL, LOW or UPP is out of range"
+msgstr "E762: Caràcter a FOL, LOW o UPP fora d'abast"
+
+msgid "Compressing word tree..."
+msgstr "Comprimint l'arbre de paraules..."
+
+msgid "E756: Spell checking is not enabled"
+msgstr "E756: La correcció ortogràfica no està activada"
+
+#, c-format
+msgid "Warning: Cannot find word list \"%s.%s.spl\" or \"%s.ascii.spl\""
+msgstr "Atenció: No s'ha trobat la llista de paraules \"%s.%s.spl\" o \"%s.ascii.spl\""
+
+#, c-format
+msgid "Reading spell file \"%s\""
+msgstr "Llegint el fitxer d'ortografia \"%s\""
+
+msgid "E757: This does not look like a spell file"
+msgstr "E757: Això no té pinta de ser un fitxer d'ortografia"
+
+msgid "E771: Old spell file, needs to be updated"
+msgstr "E771: Fitxer d'ortografia vell, ha de ser actualitzat"
+
+msgid "E772: Spell file is for newer version of Vim"
+msgstr "E772: El fitxer d'ortografia és per a una versió més recent del Vim"
+
+msgid "E770: Unsupported section in spell file"
+msgstr "E770: Secció en el fitxer d'ortografia no suportada"
+
+#, c-format
+msgid "Warning: region %s not supported"
+msgstr "Atenció: la regió %s no està suportada"
+
+#, c-format
+msgid "Reading affix file %s ..."
+msgstr "Llegint el fitxer d'afixos %s ..."
+
+#, c-format
+msgid "Conversion failure for word in %s line %d: %s"
+msgstr "No s'ha pogut convertir una paraula a %s línia %d: %s"
+
+#, c-format
+msgid "Conversion in %s not supported: from %s to %s"
+msgstr "La conversió a %s no està suportada: de %s a %s"
+
+#, c-format
+msgid "Conversion in %s not supported"
+msgstr "Conversió a %s no suportada"
+
+#, c-format
+msgid "Invalid value for FLAG in %s line %d: %s"
+msgstr "Valor de marca no vàlid a %s línia %d: %s"
+
+#, c-format
+msgid "FLAG after using flags in %s line %d: %s"
+msgstr "FLAG després d'usar marques a %s línia %d: %s"
+
+#, c-format
+msgid "Defining COMPOUNDFORBIDFLAG after PFX item may give wrong results in %s line %d"
+msgstr "Definir COMPOUNDFORBIDFLAG després de l'element PFX pot tenir resultats inesperats a %s línia %d"
+
+#, c-format
+msgid "Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in %s line %d"
+msgstr "Definir COMPOUNDPERMITFLAG després de l'element PFX pot tenir resultats inesperats a %s línia %d"
+
+#, c-format
+msgid "Wrong COMPOUNDWORDMAX value in %s line %d: %s"
+msgstr "Valor de COMPOUNDWORDMAX incorrecte a %s línia %d: %s"
+
+#, c-format
+msgid "Wrong COMPOUNDMIN value in %s line %d: %s"
+msgstr "Valor de COMPOUNDMIN incorrecte a %s línia %d: %s"
+
+#, c-format
+msgid "Wrong COMPOUNDSYLMAX value in %s line %d: %s"
+msgstr "Valor de COMPOUNDSYLMAX incorrecte a %s línia %d: %s"
+
+#, c-format
+msgid "Wrong CHECKCOMPOUNDPATTERN value in %s line %d: %s"
+msgstr "Valor de CHECKCOMPOUNDPATTERN incorrecte a %s línia %d: %s"
+
+#, c-format
+msgid "Different combining flag in continued affix block in %s line %d: %s"
+msgstr "Marca de combinació diferent en bloc continuat d'afixos a %s línia %d: %s"
+
+#, c-format
+msgid "Duplicate affix in %s line %d: %s"
+msgstr "Afix duplicat a %s línia %d: %s"
+
+#, c-format
+msgid "Affix also used for BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST in %s line %d: %s"
+msgstr "Afix també utilitzat per a BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST a %s línia %d: %s"
+
+#, c-format
+msgid "Expected Y or N in %s line %d: %s"
+msgstr "S'esperava Y o N a %s línia %d: %s"
+
+#, c-format
+msgid "Broken condition in %s line %d: %s"
+msgstr "Condició errònia a %s línia %d: %s"
+
+#, c-format
+msgid "Expected REP(SAL) count in %s line %d"
+msgstr "S'esperava recompte REP(SAL) a %s línia %d"
+
+#, c-format
+msgid "Expected MAP count in %s line %d"
+msgstr "S'esperava un recompte MAP a %s línia %d"
+
+#, c-format
+msgid "Duplicate character in MAP in %s line %d"
+msgstr "Caràcter duplicat en un element MAP a %s línia %d"
+
+#, c-format
+msgid "Unrecognized or duplicate item in %s line %d: %s"
+msgstr "Element duplicat o no reconegut a %s línia %d: %s"
+
+#, c-format
+msgid "Missing FOL/LOW/UPP line in %s"
+msgstr "Falta una línia FOL/LOW/UPP a %s"
+
+msgid "COMPOUNDSYLMAX used without SYLLABLE"
+msgstr "Element COMPOUNDSYLMAX sense síl·laba"
+
+msgid "Too many postponed prefixes"
+msgstr "Sobren prefixes posposats"
+
+msgid "Too many compound flags"
+msgstr "Sobren marques de composició"
+
+msgid "Too many postponed prefixes and/or compound flags"
+msgstr "Massa prefixes posposats i/o marques de composició"
+
+#, c-format
+msgid "Missing SOFO%s line in %s"
+msgstr "Falta una línia SOFO%s a %s"
+
+#, c-format
+msgid "Both SAL and SOFO lines in %s"
+msgstr "Línies SAL i SOFO a %s"
+
+#, c-format
+msgid "Flag is not a number in %s line %d: %s"
+msgstr "La marca no és un número a %s línia %d: %s"
+
+#, c-format
+msgid "Illegal flag in %s line %d: %s"
+msgstr "Marca il·legal a %s línia %d: %s"
+
+#, c-format
+msgid "%s value differs from what is used in another .aff file"
+msgstr "el valor %s difereix de l'usat en un altre fitxer .aff"
+
+#, c-format
+msgid "Reading dictionary file %s ..."
+msgstr "Llefint el fitxer de diccionari %s ..."
+
+#, c-format
+msgid "E760: No word count in %s"
+msgstr "E760: No hi ha recompte de paraules a %s"
+
+#, c-format
+msgid "line %6d, word %6d - %s"
+msgstr "línia %6d, paraula %6d - %s"
+
+#, c-format
+msgid "Duplicate word in %s line %d: %s"
+msgstr "Paraula duplicada a %s línia %d: %s"
+
+#, c-format
+msgid "First duplicate word in %s line %d: %s"
+msgstr "Primera paraula duplicada a %s línia %d: %s"
+
+#, c-format
+msgid "%d duplicate word(s) in %s"
+msgstr "%d paraula/es duplada/es a %s"
+
+#, c-format
+msgid "Ignored %d word(s) with non-ASCII characters in %s"
+msgstr "%d paraula/es ignorada/es amb caràcters no-ASCII a %s"
+
+#, c-format
+msgid "Reading word file %s ..."
+msgstr "Llegint el fitxer de paraules %s ..."
+
+#, c-format
+msgid "Duplicate /encoding= line ignored in %s line %d: %s"
+msgstr "S'ignora la línia /encoding= duplicada a %s línia %d: %s"
+
+#, c-format
+msgid "/encoding= line after word ignored in %s line %d: %s"
+msgstr "S'ignora una línia /encoding= després d'una paraula a %s línia %d: %s"
+
+#, c-format
+msgid "Duplicate /regions= line ignored in %s line %d: %s"
+msgstr "S'ignora la línia /regions= duplicada a %s línia %d: %s"
+
+#, c-format
+msgid "Too many regions in %s line %d: %s"
+msgstr "Massa regions a %s línia %d: %s"
+
+#, c-format
+msgid "/ line ignored in %s line %d: %s"
+msgstr "Línia / ignorada a %s línia %d: %s"
+
+#, c-format
+msgid "Invalid region nr in %s line %d: %s"
+msgstr "Número de regió no vàlid a %s línia %d: %s"
+
+#, c-format
+msgid "Unrecognized flags in %s line %d: %s"
+msgstr "Marques no reconegudes a %s línia %d: %s"
+
+#, c-format
+msgid "Ignored %d words with non-ASCII characters"
+msgstr "S'ignoren %d paraules amb caràcters no-ASCII"
+
+#, c-format
+msgid "Compressed %d of %d nodes; %d (%d%%) remaining"
+msgstr "Comprimits %d de %d nodes; %d (%d%%) pendents"
+
+msgid "Reading back spell file..."
+msgstr "Tornant a llegir el fitxer d'ortografia..."
+
+#.
+#. * Go through the trie of good words, soundfold each word and add it to
+#. * the soundfold trie.
+#.
+msgid "Performing soundfolding..."
+msgstr "Efectuant expansió per similitud fonètica..."
+
+#, c-format
+msgid "Number of words after soundfolding: %ld"
+msgstr "Nombre de paraules després de l'expansió per similitud fonètica: %ld"
+
+#, c-format
+msgid "Total number of words: %d"
+msgstr "Nombre total de paraules: %d"
+
+#, c-format
+msgid "Writing suggestion file %s ..."
+msgstr "Escrivint el fitxer de suggeriments %s ..."
+
+#, c-format
+msgid "Estimated runtime memory use: %d bytes"
+msgstr "Ús estimat de memòria en funcionament: %d octets"
+
+msgid "E751: Output file name must not have region name"
+msgstr "E751: El fitxer de sortida no pot tenir un nom de regió"
+
+msgid "E754: Only up to 8 regions supported"
+msgstr "E754: Només es suporten fins a 8 regions"
+
+#, c-format
+msgid "E755: Invalid region in %s"
+msgstr "E755: Regió no vàlida a %s"
+
+msgid "Warning: both compounding and NOBREAK specified"
+msgstr "Atenció: heu especificat composició i NOBREAK alhora"
+
+#, c-format
+msgid "Writing spell file %s ..."
+msgstr "Escrivint el fitxer d'ortografia %s ..."
+
+msgid "Done!"
+msgstr "Fet!"
+
+#, c-format
+msgid "E765: 'spellfile' does not have %ld entries"
+msgstr "E765: 'spellfile' no té %ld entrades"
+
+#, c-format
+msgid "Word removed from %s"
+msgstr "Paraula eliminada de %s"
+
+#, c-format
+msgid "Word added to %s"
+msgstr "Paraula afegida a %s"
+
+msgid "E763: Word characters differ between spell files"
+msgstr "E763: Els caràcters de paraula difereixen entre fitxers d'ortografia"
+
+msgid "Sorry, no suggestions"
+msgstr "Cap suggeriment"
+
+#, c-format
+msgid "Sorry, only %ld suggestions"
+msgstr "Llàstima, només %ld suggeriments"
+
+#. for when 'cmdheight' > 1
+#. avoid more prompt
+#, c-format
+msgid "Change \"%.*s\" to:"
+msgstr "Canviar \"%.*s\" per:"
+
+#, c-format
+msgid " < \"%.*s\""
+msgstr " < \"%.*s\""
+
+msgid "E752: No previous spell replacement"
+msgstr "E752: No hi ha cap correcció ortogràfica anterior"
+
+#, c-format
+msgid "E753: Not found: %s"
+msgstr "E753: No trobat: %s"
+
+#, c-format
+msgid "E778: This does not look like a .sug file: %s"
+msgstr "E778: No sembla pas un fitxer .sug: %s"
+
+#, c-format
+msgid "E779: Old .sug file, needs to be updated: %s"
+msgstr "E779: Fitxer .sug antic, ha de ser actualitzat: %s"
+
+#, c-format
+msgid "E780: .sug file is for newer version of Vim: %s"
+msgstr "E780: El fitxer .sug és per a una versió més nova del Vim: %s"
+
+#, c-format
+msgid "E781: .sug file doesn't match .spl file: %s"
+msgstr "E781: El fitxer .sug no coincideix amb el fitxer .spl: %s"
+
+#, c-format
+msgid "E782: error while reading .sug file: %s"
+msgstr "E782: error en llegir el fitxer .sug: %s"
+
+#. This should have been checked when generating the .spl
+#. * file.
+msgid "E783: duplicate char in MAP entry"
+msgstr "E783: Caràcter duplicat a l'entrada MAP"
+
+#, c-format
+msgid "E390: Illegal argument: %s"
+msgstr "E390: L'argument és il·legal: %s"
+
+#, c-format
+msgid "E391: No such syntax cluster: %s"
+msgstr "E391: No existeix tal grup de sintaxi: %s"
+
+msgid "No Syntax items defined for this buffer"
+msgstr "No hi ha ítems de sintaxi definits en aquest buffer"
+
+msgid "syncing on C-style comments"
+msgstr "s'està sincronitzant a partir de comentaris estil C"
+
+msgid "no syncing"
+msgstr "no es sincronitza"
+
+# va junta amb la següent
+msgid "syncing starts "
+msgstr "comença la sincronització"
+
+# va junta amb l'anterior
+msgid " lines before top line"
+msgstr " línies abans de la línia superior"
+
+msgid ""
+"\n"
+"--- Syntax sync items ---"
+msgstr ""
+"\n"
+"--- Ítems de sincronització de sintaxi ---"
+
+msgid ""
+"\n"
+"syncing on items"
+msgstr ""
+"\n"
+"s'està sincronitzant a partir d'ítems"
+
+msgid ""
+"\n"
+"--- Syntax items ---"
+msgstr ""
+"\n"
+"--- Ítems de sintaxi ---"
+
+#, c-format
+msgid "E392: No such syntax cluster: %s"
+msgstr "E392: No existeix tal grup de sintaxi: %s"
+
+msgid "minimal "
+msgstr "mínim "
+
+msgid "maximal "
+msgstr "màxim "
+
+msgid "; match "
+msgstr "; coincidència "
+
+msgid " line breaks"
+msgstr " salts de línia"
+
+msgid "E395: contains argument not accepted here"
+msgstr "E395: Conté un argument que no s'accepta aquí"
+
+msgid "E396: containedin argument not accepted here"
+msgstr "E396: L'argument 'containedin' no s'accepta aquí"
+
+msgid "E393: group[t]here not accepted here"
+msgstr "E393: L'opció group[t]here no s'accepta aquí"
+
+#, c-format
+msgid "E394: Didn't find region item for %s"
+msgstr "E394: No s'ha trobat cap regió d'ítems per %s"
+
+msgid "E397: Filename required"
+msgstr "E397: Es requereix un nom de fitxer"
+
+#, c-format
+msgid "E789: Missing ']': %s"
+msgstr "E789: Falta un ']': %s"
+
+#, c-format
+msgid "E398: Missing '=': %s"
+msgstr "E398: Falta un '=': %s"
+
+# 'syntax region' és una ordre
+#, c-format
+msgid "E399: Not enough arguments: syntax region %s"
+msgstr "E399: Falten arguments: syntax region %s"
+
+msgid "E400: No cluster specified"
+msgstr "E400: No heu especificat cap grup"
+
+#, c-format
+msgid "E401: Pattern delimiter not found: %s"
+msgstr "E401: No s'ha trobat el patró de delimitació: %s"
+
+#, c-format
+msgid "E402: Garbage after pattern: %s"
+msgstr "E402: Hi ha porqueria després del patró: %s"
+
+msgid "E403: syntax sync: line continuations pattern specified twice"
+msgstr "E403: syntax sync: el patró de continuació de línia està repetit"
+
+#, c-format
+msgid "E404: Illegal arguments: %s"
+msgstr "E404: Arguments il·legals: %s"
+
+#, c-format
+msgid "E405: Missing equal sign: %s"
+msgstr "E405: Falta un signe d'igual: %s"
+
+#, c-format
+msgid "E406: Empty argument: %s"
+msgstr "E406: Argument buit: %s"
+
+#, c-format
+msgid "E407: %s not allowed here"
+msgstr "E407: %s no està permès aquí"
+
+#, c-format
+msgid "E408: %s must be first in contains list"
+msgstr "E408: %s ha d'anar al principi de la llista 'contains'"
+
+#, c-format
+msgid "E409: Unknown group name: %s"
+msgstr "E409: El nom del grup és desconegut: %s"
+
+#, c-format
+msgid "E410: Invalid :syntax subcommand: %s"
+msgstr "E410: Sub-ordre de sintaxi no vàlida: %s"
+
+msgid "E679: recursive loop loading syncolor.vim"
+msgstr "E679: Iteració recursiva en carregar syncolor.vim"
+
+#, c-format
+msgid "E411: highlight group not found: %s"
+msgstr "E411: No s'ha trobat el grup de ressalt: %s"
+
+#, c-format
+msgid "E412: Not enough arguments: \":highlight link %s\""
+msgstr "E412: Falten arguments: \":highlight link %s\""
+
+#, c-format
+msgid "E413: Too many arguments: \":highlight link %s\""
+msgstr "E413: Sobren arguments: \":highlight link %s\""
+
+msgid "E414: group has settings, highlight link ignored"
+msgstr "E414: El grup ja ha estat definit, s'ignora l'enllaç de ressalt"
+
+#, c-format
+msgid "E415: unexpected equal sign: %s"
+msgstr "E415: Signe d'igual inesperat: %s"
+
+#, c-format
+msgid "E416: missing equal sign: %s"
+msgstr "E416: Falta un signe d'igual: %s"
+
+#, c-format
+msgid "E417: missing argument: %s"
+msgstr "E417: Falta un argument: %s"
+
+#, c-format
+msgid "E418: Illegal value: %s"
+msgstr "E418: El valor és il·legal: %s"
+
+msgid "E419: FG color unknown"
+msgstr "E419: Color de primer terme desconegut"
+
+msgid "E420: BG color unknown"
+msgstr "E420: Color de fons desconegut"
+
+#, c-format
+msgid "E421: Color name or number not recognized: %s"
+msgstr "E421: Nom o número de color no identificat: %s"
+
+#, c-format
+msgid "E422: terminal code too long: %s"
+msgstr "E422: El codi de terminal és massa llarg: %s"
+
+#, c-format
+msgid "E423: Illegal argument: %s"
+msgstr "E423: L'argument és il·legal: %s"
+
+msgid "E424: Too many different highlighting attributes in use"
+msgstr "E424: Hi ha massa atributs de ressalt diferents en ús"
+
+msgid "E669: Unprintable character in group name"
+msgstr "E669: Caràcter no imprimible en el nom del grup"
+
+msgid "W18: Invalid character in group name"
+msgstr "W18: Hi ha un caràcter no vàlid en el nom del grup"
+
+msgid "E555: at bottom of tag stack"
+msgstr "E555: Baix de la pila d'etiquetes"
+
+msgid "E556: at top of tag stack"
+msgstr "E556: Dalt de la pila d'etiquetes"
+
+msgid "E425: Cannot go before first matching tag"
+msgstr "E425: No es pot anar abans de la primera etiqueta coincident"
+
+#, c-format
+msgid "E426: tag not found: %s"
+msgstr "E426: No s'ha trobat l'etiqueta: %s"
+
+msgid " # pri kind tag"
+msgstr " # pri tip etiqueta"
+
+msgid "file\n"
+msgstr "fitxer\n"
+
+msgid "E427: There is only one matching tag"
+msgstr "E427: Només hi ha una sola etiqueta que coincideixi"
+
+msgid "E428: Cannot go beyond last matching tag"
+msgstr "E428: No es pot anar més enllà de l'última etiqueta coincident"
+
+#, c-format
+msgid "File \"%s\" does not exist"
+msgstr "El fitxer \"%s\" no existeix"
+
+#. Give an indication of the number of matching tags
+#, c-format
+msgid "tag %d of %d%s"
+msgstr "etiqueta %d de %d%s"
+
+msgid " or more"
+msgstr " o més"
+
+msgid " Using tag with different case!"
+msgstr " No es fa distinció entre majúscules i minúscules!"
+
+#, c-format
+msgid "E429: File \"%s\" does not exist"
+msgstr "E429: El fitxer \"%s\" no existeix"
+
+#. Highlight title
+msgid ""
+"\n"
+" # TO tag FROM line in file/text"
+msgstr ""
+"\n"
+" # A etiq DES DE línia en fitxer/text"
+
+#, c-format
+msgid "Searching tags file %s"
+msgstr "Cercant en el fitxer d'etiquetes %s"
+
+#, c-format
+msgid "E430: Tag file path truncated for %s\n"
+msgstr "E430: S'ha truncat l'ubicació del fitxer d'etiquetes per %s\n"
+
+#, c-format
+msgid "E431: Format error in tags file \"%s\""
+msgstr "E431: Error de format en el fitxer d'etiquetes \"%s\""
+
+#, c-format
+msgid "Before byte %ld"
+msgstr "Abans de l'octet %ld"
+
+#, c-format
+msgid "E432: Tags file not sorted: %s"
+msgstr "E432: El fitxer d'etiquetes no està ordenat: %s"
+
+#. never opened any tags file
+msgid "E433: No tags file"
+msgstr "E433: No hi ha cap fitxer d'etiquetes"
+
+msgid "E434: Can't find tag pattern"
+msgstr "E434: No s'ha trobat l'etiqueta"
+
+msgid "E435: Couldn't find tag, just guessing!"
+msgstr "E435: No s'ha trobat l'etiqueta exacta!"
+
+# «terminal» és masculí
+msgid "' not known. Available builtin terminals are:"
+msgstr "' no identificat. Els terminals disponibles són:"
+
+msgid "defaulting to '"
+msgstr "per omissió '"
+
+msgid "E557: Cannot open termcap file"
+msgstr "E557: No s'ha pogut obrir el fitxer termcap"
+
+msgid "E558: Terminal entry not found in terminfo"
+msgstr "E558: No s'ha trobat l'informació del terminal a terminfo"
+
+msgid "E559: Terminal entry not found in termcap"
+msgstr "E559: No s'ha trobat l'informació del terminal a termcap"
+
+#, c-format
+msgid "E436: No \"%s\" entry in termcap"
+msgstr "E436: No hi ha cap entrada \"%s\" a termcap"
+
+msgid "E437: terminal capability \"cm\" required"
+msgstr "E437: Es requereix la capacitat \"cm\" per part del terminal"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Terminal keys ---"
+msgstr ""
+"\n"
+"--- Tecles del terminal ---"
+
+msgid "new shell started\n"
+msgstr "s'ha iniciat una nova shell\n"
+
+msgid "Vim: Error reading input, exiting...\n"
+msgstr "Vim: Error en llegir l'entrada, sortint...\n"
+
+#. must display the prompt
+msgid "No undo possible; continue anyway"
+msgstr "No es pot desfer res; voleu continuar"
+
+msgid "Already at oldest change"
+msgstr "Ja sou en el canvi més vell"
+
+msgid "Already at newest change"
+msgstr "Ja sou en el canvi més recent"
+
+#, c-format
+msgid "Undo number %ld not found"
+msgstr "Línia de desfer número %ld no trobada"
+
+msgid "E438: u_undo: line numbers wrong"
+msgstr "E438: u_undo: els nombres de línia no són correctes"
+
+msgid "more line"
+msgstr "línia més"
+
+msgid "more lines"
+msgstr "línies més"
+
+msgid "line less"
+msgstr "línia menys"
+
+msgid "fewer lines"
+msgstr "línies menys"
+
+msgid "change"
+msgstr "canvi"
+
+msgid "changes"
+msgstr "canvis"
+
+#, c-format
+msgid "%ld %s; %s #%ld %s"
+msgstr "%ld %s; %s #%ld %s"
+
+msgid "before"
+msgstr "abans"
+
+msgid "after"
+msgstr "després"
+
+msgid "Nothing to undo"
+msgstr "No hi ha res per desfer"
+
+msgid "number changes time"
+msgstr "número canvis hora"
+
+#, c-format
+msgid "%ld seconds ago"
+msgstr "fa %ld segons"
+
+msgid "E790: undojoin is not allowed after undo"
+msgstr "E790: undojoin no està permès després de undo"
+
+msgid "E439: undo list corrupt"
+msgstr "E439: La llista de desfer està corrompuda"
+
+msgid "E440: undo line missing"
+msgstr "E440: Falta una línia de desfer"
+
+#. Only MS VC 4.1 and earlier can do Win32s
+msgid ""
+"\n"
+"MS-Windows 16/32-bit GUI version"
+msgstr ""
+"\n"
+"Versió GUI per MS-Windows 16/32 bits"
+
+msgid ""
+"\n"
+"MS-Windows 64-bit GUI version"
+msgstr ""
+"\n"
+"Versió GUI per a MS-Windows 64 bits"
+
+msgid ""
+"\n"
+"MS-Windows 32-bit GUI version"
+msgstr ""
+"\n"
+"Versió GUI per MS-Windows 32 bits"
+
+msgid " in Win32s mode"
+msgstr " en mode Win32s"
+
+msgid " with OLE support"
+msgstr " amb suport per OLE"
+
+msgid ""
+"\n"
+"MS-Windows 32-bit console version"
+msgstr ""
+"\n"
+"Versió consola per MS-Windows 32 bits"
+
+msgid ""
+"\n"
+"MS-Windows 16-bit version"
+msgstr ""
+"\n"
+"Versió per MS-Windows 16 bits"
+
+msgid ""
+"\n"
+"32-bit MS-DOS version"
+msgstr ""
+"\n"
+"Versió per MS-DOS 32 bits"
+
+msgid ""
+"\n"
+"16-bit MS-DOS version"
+msgstr ""
+"\n"
+"Versió per MS-DOS 16 bits"
+
+msgid ""
+"\n"
+"MacOS X (unix) version"
+msgstr ""
+"\n"
+"Versió per MacOS X (Unix)"
+
+msgid ""
+"\n"
+"MacOS X version"
+msgstr ""
+"\n"
+"Versió per MacOS X"
+
+msgid ""
+"\n"
+"MacOS version"
+msgstr ""
+"\n"
+"Versió per MacOS"
+
+msgid ""
+"\n"
+"RISC OS version"
+msgstr ""
+"\n"
+"Versió per RISC OS"
+
+msgid ""
+"\n"
+"Included patches: "
+msgstr ""
+"\n"
+"Modificacions incloses: "
+
+msgid "Modified by "
+msgstr "Modificat per "
+
+msgid ""
+"\n"
+"Compiled "
+msgstr ""
+"\n"
+"Compilat "
+
+msgid "by "
+msgstr "per "
+
+msgid ""
+"\n"
+"Huge version "
+msgstr ""
+"\n"
+"Versió enorme "
+
+msgid ""
+"\n"
+"Big version "
+msgstr ""
+"\n"
+"Versió gran "
+
+msgid ""
+"\n"
+"Normal version "
+msgstr ""
+"\n"
+"Versió normal "
+
+msgid ""
+"\n"
+"Small version "
+msgstr ""
+"\n"
+"Versió reduïda "
+
+msgid ""
+"\n"
+"Tiny version "
+msgstr ""
+"\n"
+"Versió mínima "
+
+msgid "without GUI."
+msgstr "sense GUI."
+
+msgid "with GTK2-GNOME GUI."
+msgstr "amb GUI GTK2-GNOME."
+
+msgid "with GTK-GNOME GUI."
+msgstr "amb GUI GTK-GNOME."
+
+msgid "with GTK2 GUI."
+msgstr "amb GUI GTK2."
+
+msgid "with GTK GUI."
+msgstr "amb GUI GTK."
+
+msgid "with X11-Motif GUI."
+msgstr "amb GUI X11-Motif."
+
+msgid "with X11-neXtaw GUI."
+msgstr "amb GUI X11-neXtaw."
+
+msgid "with X11-Athena GUI."
+msgstr "amb GUI X11-Athena."
+
+msgid "with Photon GUI."
+msgstr "amb GUI Photon."
+
+msgid "with GUI."
+msgstr "amb GUI."
+
+msgid "with Carbon GUI."
+msgstr "amb GUI Carbon."
+
+msgid "with Cocoa GUI."
+msgstr "amb GUI Cocoa."
+
+msgid "with (classic) GUI."
+msgstr "amb GUI (clàssic)."
+
+msgid " Features included (+) or not (-):\n"
+msgstr " Funcions incloses (+) o excloses (-):\n"
+
+# 29 caràcters fins el ":" (inclòs)
+msgid " system vimrc file: \""
+msgstr " fitxer vimrc del sistema: \""
+
+# 29 caràcters fins el ":" (inclòs)
+msgid " user vimrc file: \""
+msgstr " fitxer vimrc de l'usuari: \""
+
+# 29 caràcters fins el ":" (inclòs)
+msgid " 2nd user vimrc file: \""
+msgstr " 2n fitxer vimrc de l'usuari: \""
+
+# 29 caràcters fins el ":" (inclòs)
+msgid " 3rd user vimrc file: \""
+msgstr " 3r fitxer vimrc de l'usuari: \""
+
+# 29 caràcters fins el ":" (inclòs)
+msgid " user exrc file: \""
+msgstr " fitxer exrc de l'usuari: \""
+
+# 29 caràcters fins el ":" (inclòs)
+msgid " 2nd user exrc file: \""
+msgstr " 2n fitxer exrc de l'usuari: \""
+
+# 29 caràcters fins el ":" (inclòs)
+msgid " system gvimrc file: \""
+msgstr " fitxer gvimrc del sistema: \""
+
+# 29 caràcters fins el ":" (inclòs)
+msgid " user gvimrc file: \""
+msgstr " fitxer gvimrc de l'usuari: \""
+
+# 29 caràcters fins el ":" (inclòs)
+msgid "2nd user gvimrc file: \""
+msgstr "2n fitxer gvimrc de l'usuari: \""
+
+# 29 caràcters fins el ":" (inclòs)
+msgid "3rd user gvimrc file: \""
+msgstr "3r fitxer gvimrc de l'usuari: \""
+
+# 29 caràcters fins el ":" (inclòs)
+msgid " system menu file: \""
+msgstr " fitxer de menú del sistema: \""
+
+# 29 caràcters fins el ":" (inclòs)
+msgid " fall-back for $VIM: \""
+msgstr " alternativa per a $VIM: \""
+
+# 29 caràcters fins el ":" (inclòs)
+msgid " f-b for $VIMRUNTIME: \""
+msgstr " alt per a $VIMRUNTIME: \""
+
+msgid "Compilation: "
+msgstr "Compilat amb: "
+
+msgid "Compiler: "
+msgstr "Compilador: "
+
+msgid "Linking: "
+msgstr "Enllaçat amb: "
+
+msgid " DEBUG BUILD"
+msgstr " VERSIÓ DE DEPURACIÓ"
+
+msgid "VIM - Vi IMproved"
+msgstr "VIM - Vi IMproved"
+
+msgid "version "
+msgstr "versió "
+
+msgid "by Bram Moolenaar et al."
+msgstr "per Bram Moolenaar et al."
+
+msgid "Vim is open source and freely distributable"
+msgstr "Vim és un programa obert i lliure distribució"
+
+msgid "Help poor children in Uganda!"
+msgstr "Ajudeu els nens pobres d'Uganda!"
+
+# amplada 53 caràcters
+msgid "type :help iccf<Enter> for information "
+msgstr "feu :help iccf<Entrar> per a més informació "
+
+# amplada 53 caràcters
+msgid "type :q<Enter> to exit "
+msgstr "feu :q<Entrar> per a sortir "
+
+# amplada 53 caràcters
+msgid "type :help<Enter> or <F1> for on-line help"
+msgstr "feu :help<Entrar> o <F1> per a obtenir ajuda "
+
+# amplada 53 caràcters
+msgid "type :help version7<Enter> for version info"
+msgstr "feu :help version7<Entrar> per a info de la versió "
+
+msgid "Running in Vi compatible mode"
+msgstr "Funcionant en mode compatible amb Vi"
+
+# amplada 53 caràcters
+msgid "type :set nocp<Enter> for Vim defaults"
+msgstr "feu :set nocp<Entrar> per al mode no compatible"
+
+# amplada 53 caràcters
+msgid "type :help cp-default<Enter> for info on this"
+msgstr "feu :help cp-default<Entrar> per a info sobre el tema "
+
+# amplada 53 caràcters
+msgid "menu Help->Orphans for information "
+msgstr "menú Ajuda->Orfes per a informació "
+
+msgid "Running modeless, typed text is inserted"
+msgstr "Funcionant sense modes, el text escrit s'insereix"
+
+# Això ha de lligar amb la traducció del menú
+# amplada 53 caràcters
+msgid "menu Edit->Global Settings->Toggle Insert Mode "
+msgstr "menú Edita->Opcions globals->Mode d'inserció "
+
+# amplada 53 caràcters
+msgid " for two modes "
+msgstr " per a dos modes "
+
+# Això ha de lligar amb la traducció del menú
+# amplada 53 caràcters
+msgid "menu Edit->Global Settings->Toggle Vi Compatible"
+msgstr "menú Edita->Opcions globals->Compatible amb Vi "
+
+# amplada 53 caràcters
+msgid " for Vim defaults "
+msgstr " per al mode compatible"
+
+msgid "Sponsor Vim development!"
+msgstr "Patrocineu el desenvolupament del Vim!"
+
+msgid "Become a registered Vim user!"
+msgstr "Feu-vos usuari de Vim registrat!"
+
+# amplada 53 caràcters
+msgid "type :help sponsor<Enter> for information "
+msgstr "feu :help sponsor<Entrar> per a informació "
+
+# amplada 53 caràcters
+msgid "type :help register<Enter> for information "
+msgstr "feu :help register<Entrar> per a informació "
+
+# amplada 53 caràcters
+msgid "menu Help->Sponsor/Register for information "
+msgstr "menú Ajuda->Patrocini/Registre per a informació "
+
+msgid "WARNING: Windows 95/98/ME detected"
+msgstr "ATENCIÓ: S'ha detectat Windows 95/98/ME"
+
+# amplada 53 caràcters
+msgid "type :help windows95<Enter> for info on this"
+msgstr "feu :help windows95<Entrar> per a info sobre el tema "
+
+msgid "Already only one window"
+msgstr "Només hi ha una finestra"
+
+msgid "E441: There is no preview window"
+msgstr "E441: No hi ha cap finestra de previsualització"
+
+msgid "E442: Can't split topleft and botright at the same time"
+msgstr "E442: No es pot dividir horitzontal i verticalment al mateix temps"
+
+msgid "E443: Cannot rotate when another window is split"
+msgstr "E443: No hi pot haver rotació quan hi ha finestres dividides"
+
+msgid "E444: Cannot close last window"
+msgstr "E444: No es pot tancar l'última finestra"
+
+msgid "E445: Other window contains changes"
+msgstr "E445: Hi han altres finestres que contenen canvis"
+
+msgid "E446: No file name under cursor"
+msgstr "E446: No hi ha cap nom de fitxer sota el cursor"
+
+#, c-format
+msgid "E447: Can't find file \"%s\" in path"
+msgstr "E447: No s'ha trobat el fitxer \"%s\" en el path"
+
+#, c-format
+msgid "E370: Could not load library %s"
+msgstr "E370: No s'ha pogut carregar la biblioteca %s"
+
+msgid "Sorry, this command is disabled: the Perl library could not be loaded."
+msgstr "Aquesta ordre no està habilitada: no s'ha pogut carregar la biblioteca Perl."
+
+msgid "E299: Perl evaluation forbidden in sandbox without the Safe module"
+msgstr "E299: Avaluació Perl en una gàbia no permesa sense el mòdul Safe"
+
+msgid "Edit with &multiple Vims"
+msgstr "Edita en &múltiples Vims"
+
+msgid "Edit with single &Vim"
+msgstr "Edita en un sol &Vim"
+
+msgid "Diff with Vim"
+msgstr "Mostra les diferències amb Vim"
+
+msgid "Edit with &Vim"
+msgstr "Edita amb el &Vim"
+
+#. Now concatenate
+msgid "Edit with existing Vim - "
+msgstr "Edita amb un Vim existent - "
+
+msgid "Edits the selected file(s) with Vim"
+msgstr "Edita el(s) fitxer(s) seleccionat(s) amb el Vim"
+
+msgid "Error creating process: Check if gvim is in your path!"
+msgstr "Error en crear el procés: Comproveu que gvim es trobi en el path!"
+
+msgid "gvimext.dll error"
+msgstr "error de la biblioteca gvimext.dll"
+
+msgid "Path length too long!"
+msgstr "La llargada del path és excessiva"
+
+msgid "--No lines in buffer--"
+msgstr "--Cap línia en el buffer--"
+
+#.
+#. * 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: S'ha avortat l'ordre"
+
+msgid "E471: Argument required"
+msgstr "E471: Es requereix un argument"
+
+msgid "E10: \\ should be followed by /, ? or &"
+msgstr "E10: \\ hauria de continuar amb /, ? o &"
+
+msgid "E11: Invalid in command-line window; <CR> executes, CTRL-C quits"
+msgstr "E11: No és vàlid a la línia d'ordres: <ENTRAR> executa, CTRL-C surt"
+
+msgid "E12: Command not allowed from exrc/vimrc in current dir or tag search"
+msgstr "E12: Ordre en exrc/vimrc no permesa en l'actual cerca d'etiquetes o directoris"
+
+msgid "E171: Missing :endif"
+msgstr "E171: Falta una declaració :endif"
+
+msgid "E600: Missing :endtry"
+msgstr "E600: Falta una declaració :endtry"
+
+msgid "E170: Missing :endwhile"
+msgstr "E170: Falta una declaració :endwhile"
+
+msgid "E170: Missing :endfor"
+msgstr "E170: Falta un :endfor"
+
+msgid "E588: :endwhile without :while"
+msgstr "E588: Declaració :endwhile sense :while"
+
+msgid "E588: :endfor without :for"
+msgstr "E588: :endfor sense :for"
+
+msgid "E13: File exists (add ! to override)"
+msgstr "E13: El fitxer existeix (afegiu ! per confirmar)"
+
+msgid "E472: Command failed"
+msgstr "E472: L'ordre ha fallat"
+
+#, c-format
+msgid "E234: Unknown fontset: %s"
+msgstr "E234: Conjunt de tipus desconegut: %s"
+
+#, c-format
+msgid "E235: Unknown font: %s"
+msgstr "E235: Fosa desconeguda: %s"
+
+#, c-format
+msgid "E236: Font \"%s\" is not fixed-width"
+msgstr "E236: La fosa \"%s\" no és d'amplada fixa"
+
+msgid "E473: Internal error"
+msgstr "E473: Error intern"
+
+msgid "Interrupted"
+msgstr "Interromput"
+
+msgid "E14: Invalid address"
+msgstr "E14: L'adreça no és vàlida"
+
+msgid "E474: Invalid argument"
+msgstr "E474: L'argument no és vàlid"
+
+#, c-format
+msgid "E475: Invalid argument: %s"
+msgstr "E475: L'argument no és vàlid: %s"
+
+#, c-format
+msgid "E15: Invalid expression: %s"
+msgstr "E15: L'expressió no és vàlida: %s"
+
+msgid "E16: Invalid range"
+msgstr "E16: L'interval no és vàlid"
+
+msgid "E476: Invalid command"
+msgstr "E476: L'ordre no és vàlida"
+
+#, c-format
+msgid "E17: \"%s\" is a directory"
+msgstr "E17: \"%s\" és un directori"
+
+#, c-format
+msgid "E364: Library call failed for \"%s()\""
+msgstr "E364: La crida a la biblioteca a fallat per \"%s()\""
+
+#, c-format
+msgid "E448: Could not load library function %s"
+msgstr "E448: No s'ha pogut carregar la funció %s"
+
+msgid "E19: Mark has invalid line number"
+msgstr "E19: Marca amb un número de línia no vàlid"
+
+msgid "E20: Mark not set"
+msgstr "E20: Marca no establerta"
+
+msgid "E21: Cannot make changes, 'modifiable' is off"
+msgstr "E21: No es poden fer canvis, l'opció 'modifiable' està desactivada"
+
+msgid "E22: Scripts nested too deep"
+msgstr "E22: Imbricació d'scripts massa profunda"
+
+msgid "E23: No alternate file"
+msgstr "E23: No hi ha cap fitxer alternatiu"
+
+msgid "E24: No such abbreviation"
+msgstr "E24: No existeix tal abreviació"
+
+msgid "E477: No ! allowed"
+msgstr "E477: ! no permès"
+
+msgid "E25: GUI cannot be used: Not enabled at compile time"
+msgstr "E25: No es pot usar la GUI: No ha estat compilada"
+
+msgid "E26: Hebrew cannot be used: Not enabled at compile time\n"
+msgstr "E26: No es pot usar el mode Hebreu: No ha estat compilat\n"
+
+msgid "E27: Farsi cannot be used: Not enabled at compile time\n"
+msgstr "E27: No es pot usar el mode Farsi: No ha estat compilat\n"
+
+msgid "E800: Arabic cannot be used: Not enabled at compile time\n"
+msgstr "E800: No es pot usar el mode àrab: No ha estat compilat\n"
+
+#, c-format
+msgid "E28: No such highlight group name: %s"
+msgstr "E28: No existeix tal grup de ressalt: %s"
+
+msgid "E29: No inserted text yet"
+msgstr "E29: Encara no s'ha inserit text"
+
+msgid "E30: No previous command line"
+msgstr "E30: No hi ha cap ordre anterior"
+
+msgid "E31: No such mapping"
+msgstr "E31: No existeix tal assignació"
+
+msgid "E479: No match"
+msgstr "E479: Cap coincidència"
+
+#, c-format
+msgid "E480: No match: %s"
+msgstr "E480: Cap coincidència: %s"
+
+msgid "E32: No file name"
+msgstr "E32: Falta un nom de fitxer"
+
+msgid "E33: No previous substitute regular expression"
+msgstr "E33: No hi ha cap expressió de substitució anterior"
+
+msgid "E34: No previous command"
+msgstr "E34: No hi ha cap ordre anterior"
+
+msgid "E35: No previous regular expression"
+msgstr "E35: No hi ha cap expressió regular anterior"
+
+msgid "E481: No range allowed"
+msgstr "E481: No es permet cap interval"
+
+msgid "E36: Not enough room"
+msgstr "E36: No hi ha prou espai"
+
+#, c-format
+msgid "E247: no registered server named \"%s\""
+msgstr "E247: No hi ha cap servidor registrat amb aquest nom \"%s\""
+
+#, c-format
+msgid "E482: Can't create file %s"
+msgstr "E482: No es pot crear el fitxer %s"
+
+msgid "E483: Can't get temp file name"
+msgstr "E483: No s'ha pogut obtenir el nom del fitxer temporal"
+
+#, c-format
+msgid "E484: Can't open file %s"
+msgstr "E484: No es pot obrir el fitxer %s"
+
+#, c-format
+msgid "E485: Can't read file %s"
+msgstr "E485: No es pot llegir el fitxer %s"
+
+msgid "E37: No write since last change (add ! to override)"
+msgstr "E37: No s'han desat els canvis (afegiu ! per confirmar)"
+
+msgid "E38: Null argument"
+msgstr "E38: Argument nul"
+
+msgid "E39: Number expected"
+msgstr "E39: S'esperava un número"
+
+#, c-format
+msgid "E40: Can't open errorfile %s"
+msgstr "E40: No s'ha pogut obrir el fitxer d'errors %s"
+
+msgid "E233: cannot open display"
+msgstr "E233: No s'ha pogut obrir la pantalla"
+
+msgid "E41: Out of memory!"
+msgstr "E41: Memòria exhaurida!"
+
+msgid "Pattern not found"
+msgstr "No s'ha trobat el patró"
+
+#, c-format
+msgid "E486: Pattern not found: %s"
+msgstr "E486: No s'ha trobat el patró: %s"
+
+msgid "E487: Argument must be positive"
+msgstr "E487: L'argument ha de ser un número positiu"
+
+msgid "E459: Cannot go back to previous directory"
+msgstr "E459: No es pot tornar al directori anterior"
+
+msgid "E42: No Errors"
+msgstr "E42: No hi han errors"
+
+msgid "E776: No location list"
+msgstr "E776: No hi ha cap llista de posicions"
+
+msgid "E43: Damaged match string"
+msgstr "E43: S'ha corromput la cadena amb l'expressió regular"
+
+msgid "E44: Corrupted regexp program"
+msgstr "E44: S'ha corromput el programa d'expressió regular"
+
+msgid "E45: 'readonly' option is set (add ! to override)"
+msgstr "E45: L'opció 'readonly' està definida (afegiu ! per confirmar)"
+
+#, c-format
+msgid "E46: Cannot change read-only variable \"%s\""
+msgstr "E46: No s'ha pogut canviar la variable de només lectura \"%s\""
+
+#, c-format
+msgid "E794: Cannot set variable in the sandbox: \"%s\""
+msgstr "E794: No s'ha pogut definir la variable dins la gàbia: \"%s\""
+
+msgid "E47: Error while reading errorfile"
+msgstr "E47: Error en llegir el fitxer d'errors"
+
+msgid "E48: Not allowed in sandbox"
+msgstr "E48: No està permès dins d'una gàbia"
+
+msgid "E523: Not allowed here"
+msgstr "E523: No està permès aquí"
+
+msgid "E359: Screen mode setting not supported"
+msgstr "E359: La funció d'ajustar el mode de pantalla no està suportada"
+
+msgid "E49: Invalid scroll size"
+msgstr "E49: La distància de desplaçament no és vàlida"
+
+msgid "E91: 'shell' option is empty"
+msgstr "E91: L'opció 'shell' no conté res"
+
+msgid "E255: Couldn't read in sign data!"
+msgstr "E255: No s'han pogut llegir les dades del senyal!"
+
+msgid "E72: Close error on swap file"
+msgstr "E72: Error en tancar el fitxer d'intercanvi"
+
+msgid "E73: tag stack empty"
+msgstr "E73: La pila d'etiquetes està buida"
+
+msgid "E74: Command too complex"
+msgstr "E74: L'ordre és massa complexa"
+
+msgid "E75: Name too long"
+msgstr "E75: El nom és massa llarg"
+
+msgid "E76: Too many ["
+msgstr "E76: Sobren caràcters ["
+
+msgid "E77: Too many file names"
+msgstr "E77: Sobren noms de fitxer"
+
+msgid "E488: Trailing characters"
+msgstr "E488: Sobren caràcters"
+
+msgid "E78: Unknown mark"
+msgstr "E78: La marca és desconeguda"
+
+msgid "E79: Cannot expand wildcards"
+msgstr "E79: No s'ha pogut expandir el nom de fitxer"
+
+msgid "E591: 'winheight' cannot be smaller than 'winminheight'"
+msgstr "E591: L'opció 'winheight' no pot ser menor que 'winminheight'"
+
+msgid "E592: 'winwidth' cannot be smaller than 'winminwidth'"
+msgstr "E592: L'opció 'winwidth' no pot ser menor que 'winminwidth'"
+
+msgid "E80: Error while writing"
+msgstr "E80: Error d'escriptura"
+
+msgid "Zero count"
+msgstr "Comptador a zero"
+
+msgid "E81: Using <SID> not in a script context"
+msgstr "E81: Ús de <SID> en un context equivocat"
+
+msgid "E449: Invalid expression received"
+msgstr "E449: S'ha rebut una expressió no vàlida"
+
+msgid "E463: Region is guarded, cannot modify"
+msgstr "E463: La regió està protegida, no es pot modificar"
+
+msgid "E744: NetBeans does not allow changes in read-only files"
+msgstr "E744: NetBeans no permet canvis a fitxers de només-lectura"
+
+#, c-format
+msgid "E685: Internal error: %s"
+msgstr "E685: Error intern: %s"
+
+msgid "E363: pattern uses more memory than 'maxmempattern'"
+msgstr "E363: el patró usa més memòria que 'maxmempattern'"
+
+msgid "E749: empty buffer"
+msgstr "E749: buffer buit"
+
+msgid "E682: Invalid search pattern or delimiter"
+msgstr "E682: Patró de cerca o delimitador no vàlid"
+
+msgid "E139: File is loaded in another buffer"
+msgstr "E139: El fitxer està carregat en un altre buffer"
+
+#, c-format
+msgid "E764: Option '%s' is not set"
+msgstr "E764: L'opció '%s' no està definida"
+
+msgid "search hit TOP, continuing at BOTTOM"
+msgstr "la cerca ha arribat a DALT, es continua a BAIX"
+
+msgid "search hit BOTTOM, continuing at TOP"
+msgstr "la cerca ha arribat a BAIX, es continua a DALT"
+
+#~ msgid "[Error List]"
+#~ msgstr "[Llista d'errors]"
+#~ msgid "[No File]"
+#~ msgstr "[Cap fitxer]"
+#~ msgid "E106: Unknown variable: \"%s\""
+#~ msgstr "E106: La variable és desconeguda: \"%s\""
+#~ msgid "E123: Undefined function: %s"
+#~ msgstr "E123: La funció no està definida: %s"
+#~ msgid "E127: Cannot redefine function %s: It is in use"
+#~ msgstr "E127: No s'ha pogut redefinir la funció %s: s'està utilitzant"
+#~ msgid "E130: Undefined function: %s"
+#~ msgstr "E130: La funció no està definida: %s"
+#~ msgid "\"\n"
+#~ msgstr "\"\n"
+#~ msgid "-V[N]\t\tVerbose level"
+#~ msgstr "-V[N]\t\tNivell de loquacitat"
+#~ msgid "--help\t\tShow Gnome arguments"
+#~ msgstr "--help\t\tMostra els arguments per Gnome"
+#~ msgid "[string too long]"
+#~ msgstr "[cadena massa llarga]"
+#~ msgid "Hit ENTER to continue"
+#~ msgstr "Premeu ENTRAR per continuar"
+#~ msgid " (RET/BS: line, SPACE/b: page, d/u: half page, q: quit)"
+#~ msgstr ""
+#~ " (ENTRAR/RETROCÉS: línia, ESPAI/b; pàgina, d/u; mitja pàgina, q: surt)"
+#~ msgid " (RET: line, SPACE: page, d: half page, q: quit)"
+#~ msgstr " (ENTRAR: línia, ESPAI: pàgina, d: mitja pàgina, q: surt)"
+#~ msgid "...(truncated)"
+#~ msgstr "...(truncat)"
+#~ msgid "Could not allocate memory for command line."
+#~ msgstr "No s'ha pogut assignar memòria per la línia d'ordres."
+#~ msgid "E56: %s* operand could be empty"
+#~ msgstr "E56: L'operand %s* podria estar buit"
+#~ msgid "E57: %s+ operand could be empty"
+#~ msgstr "E57: L'operand %s+ podria estar buit"
+#~ msgid "E58: %s{ operand could be empty"
+#~ msgstr "E58: L'operand %s{ podria estar buit"
+#~ msgid "E361: Crash intercepted; regexp too complex?"
+#~ msgstr "E361: Programa inestable; expressió regular massa complexa?"
+#~ msgid "E363: pattern caused out-of-stack error"
+#~ msgstr "E363: El patró ha provocat un error de desbordament de pila"
+#~ msgid " BLOCK"
+#~ msgstr " BLOC"
+#~ msgid " LINE"
+#~ msgstr " LÍNIA"
+#~ msgid "Enter nr of choice (<CR> to abort): "
+#~ msgstr "Entreu un número (<Entrar> per avortar): "
+#~ msgid "with BeOS GUI."
+#~ msgstr "amb GUI BeOS."
+
diff --git a/src/po/check.vim b/src/po/check.vim
new file mode 100644
index 0000000000..5a3a0e3f46
--- /dev/null
+++ b/src/po/check.vim
@@ -0,0 +1,88 @@
+" Vim script for checking .po files.
+"
+" Go through the file and verify that:
+" - All %...s items in "msgid" are identical to the ones in "msgstr".
+" - An error or warning code in "msgid" matches the one in "msgstr".
+
+if 1 " Only execute this if the eval feature is available.
+
+" Function to get a split line at the cursor.
+" Used for both msgid and msgstr lines.
+" Removes all text except % items and returns the result.
+func! GetMline()
+ let idline = substitute(getline('.'), '"\(.*\)"$', '\1', '')
+ while line('.') < line('$')
+ +
+ let line = getline('.')
+ if line[0] != '"'
+ break
+ endif
+ let idline .= substitute(line, '"\(.*\)"$', '\1', '')
+ endwhile
+
+ " remove '%', not used for formatting.
+ let idline = substitute(idline, "'%'", '', 'g')
+
+ " remove '%' used for plural forms.
+ let idline = substitute(idline, '\\nPlural-Forms: .\+;\\n', '', '')
+
+ " remove everything but % items.
+ return substitute(idline, '[^%]*\(%[-+ #''.0-9*]*l\=[dsuxXpoc%]\)\=', '\1', 'g')
+endfunc
+
+" This only works when 'wrapscan' is set.
+let s:save_wrapscan = &wrapscan
+set wrapscan
+
+" Start at the first "msgid" line.
+1
+/^msgid
+let startline = line('.')
+let error = 0
+
+while 1
+ if getline(line('.') - 1) !~ "no-c-format"
+ let fromline = GetMline()
+ 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
+ endif
+ endif
+
+ " Find next msgid.
+ " Wrap around at the end of the file, quit when back at the first one.
+ /^msgid
+ if line('.') == startline
+ break
+ endif
+endwhile
+
+" Check that error code in msgid matches the one in msgstr.
+"
+" Examples of mismatches found with msgid "E123: ..."
+" - msgstr "E321: ..." error code mismatch
+" - msgstr "W123: ..." warning instead of error
+" - msgstr "E123 ..." missing colon
+" - msgstr "..." missing error code
+"
+1
+if search('msgid "\("\n"\)\?\([EW][0-9]\+:\).*\nmsgstr "\("\n"\)\?[^"]\@=\2\@!') > 0
+ echo 'Mismatching error/warning code in line ' . line('.')
+ let error = 1
+endif
+
+if error == 0
+ echo "OK"
+endif
+
+let &wrapscan = s:save_wrapscan
+unlet s:save_wrapscan
+
+endif
diff --git a/src/po/cleanup.vim b/src/po/cleanup.vim
new file mode 100644
index 0000000000..24ae74ed38
--- /dev/null
+++ b/src/po/cleanup.vim
@@ -0,0 +1,19 @@
+" Vim script to cleanup a .po file:
+" - Remove line numbers (avoids that diffs are messy).
+" - Comment-out fuzzy and empty messages.
+" - Make sure there is a space before the string (required for Solaris).
+" Requires Vim 6.0 or later (because of multi-line search patterns).
+
+" Disable diff mode, because it makes this very slow
+let s:was_diff = &diff
+setl nodiff
+
+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/^/#\~ /
+
+if s:was_diff
+ setl diff
+endif
diff --git a/src/po/cs.cp1250.po b/src/po/cs.cp1250.po
new file mode 100644
index 0000000000..97e0e9457b
--- /dev/null
+++ b/src/po/cs.cp1250.po
@@ -0,0 +1,4664 @@
+# Czech translation of vim
+# Jiøí Pavlovský <jpavlovsky@mbox.vol.cz>, 2000 - 2002.
+# Some completion for vim6.0 added by Jiøí Bøezina <brz@centrum.cz>
+# Some bugfixes by Tomáš Zellerin <zellerin@volny.cz>
+#
+# Generated from cs.po, DO NOT EDIT.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: vim-6.0\n"
+"POT-Creation-Date: 2001-10-08 08:27-0700\n"
+"PO-Revision-Date: 2002-02-06 22:29+0100\n"
+"Last-Translator: Jiøí Pavlovský <jpavlovsky@mbox.vol.cz>\n"
+"Language-Team: Czech <cs@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=cp1250\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+msgid "E82: Cannot allocate any buffer, exiting..."
+msgstr "E82: Nelze alokovat žádný buffer, konèím..."
+
+msgid "E83: Cannot allocate buffer, using other one..."
+msgstr "E83: Nelze alokovat buffer, použiji jiný..."
+
+msgid "No buffers were unloaded"
+msgstr "Žádný buffer nebyl deaktivován"
+
+msgid "No buffers were deleted"
+msgstr "Žádný buffer nebyl smazán"
+
+msgid "No buffers were wiped out"
+msgstr "Žádný buffer nebyl zahozen"
+
+msgid "1 buffer unloaded"
+msgstr "Poèet deaktivovaných bufferù: 1"
+
+#, c-format
+msgid "%d buffers unloaded"
+msgstr "Poèet deaktivovaných bufferù: %d"
+
+msgid "1 buffer deleted"
+msgstr "Poèet smazaných bufferù: 1"
+
+#, c-format
+msgid "%d buffers deleted"
+msgstr "Poèet smazaných bufferù: %d"
+
+msgid "1 buffer wiped out"
+msgstr "Poèet zahozených bufferù: 1"
+
+#, c-format
+msgid "%d buffers wiped out"
+msgstr "Poèet zahozených bufferù: %d"
+
+msgid "E84: No modified buffer found"
+msgstr "E84: Nebyl nalezen žádný zmìnìný buffer"
+
+#. back where we started, didn't find anything.
+msgid "E85: There is no listed buffer"
+msgstr "E85: Seznam bufferù je prázdný"
+
+#, c-format
+msgid "E86: Cannot go to buffer %ld"
+msgstr "E86: Nelze pøeskoèit na buffer %ld"
+
+msgid "E87: Cannot go beyond last buffer"
+msgstr "E87: Za poslední buffer nelze pøeskoèit"
+
+msgid "E88: Cannot go before first buffer"
+msgstr "E88: Pøed první buffer nelze pøeskoèit"
+
+#, c-format
+msgid "E89: No write since last change for buffer %ld (use ! to override)"
+msgstr "E89: Zmìny v bufferu %ld nebyly uloženy (! pro vynucení)"
+
+msgid "E90: Cannot unload last buffer"
+msgstr "E90: Poslední buffer nelze deaktivovat"
+
+msgid "W14: Warning: List of file names overflow"
+msgstr "W14: Varování: pøeteèení seznamu s názvy souborù"
+
+#, c-format
+msgid "E92: Buffer %ld not found"
+msgstr "E92: Buffer %ld nenalezen"
+
+#, c-format
+msgid "E93: More than one match for %s"
+msgstr "E93: Vzoru %s vyhovuje více bufferù"
+
+#, c-format
+msgid "E94: No matching buffer for %s"
+msgstr "E94: Vzoru %s nevyhovuje žádný buffer"
+
+#, c-format
+msgid "line %ld"
+msgstr "øádek %ld"
+
+msgid "E95: Buffer with this name already exists"
+msgstr "E95: Buffer tohoto jména již existuje"
+
+msgid " [Modified]"
+msgstr " [Zmìnìný]"
+
+msgid "[Not edited]"
+msgstr "[Needitovaný]"
+
+msgid "[New file]"
+msgstr "[Nový soubor]"
+
+msgid "[Read errors]"
+msgstr "[Chyby pøi ètení]"
+
+msgid "[readonly]"
+msgstr "[Pouze pro ètení]"
+
+msgid "1 line --%d%%--"
+msgstr "øádkù: --%d%%--"
+
+msgid "%ld lines --%d%%--"
+msgstr "øádkù: %ld --%d%%--"
+
+msgid "line %ld of %ld --%d%%-- col "
+msgstr "øádek %ld/%ld --%d%%-- sloupec"
+
+msgid "[No file]"
+msgstr "[Žádný soubor]"
+
+#. must be a help buffer
+msgid "help"
+msgstr "nápovìda"
+
+msgid "[help]"
+msgstr "[nápovìda]"
+
+msgid "[Preview]"
+msgstr "[náhled]"
+
+msgid "All"
+msgstr "Vše"
+
+msgid "Bot"
+msgstr "Konec"
+
+msgid "Top"
+msgstr "Zaèátek"
+
+msgid ""
+"\n"
+"# Buffer list:\n"
+msgstr ""
+"\n"
+"# Seznam bufferù:\n"
+
+msgid "[Error List]"
+msgstr "[seznam chyb]"
+
+msgid "[No File]"
+msgstr "[žádný soubor]"
+
+msgid ""
+"\n"
+"--- Signs ---"
+msgstr ""
+"\n"
+"--- Znaky ---"
+
+#, c-format
+msgid "Signs for %s:"
+msgstr "Znaky pro %s:"
+
+#, c-format
+msgid " line=%ld id=%d name=%s"
+msgstr " øádek=%ld id=%d jméno=%s"
+
+#, c-format
+msgid "E96: Can not diff more than %ld buffers"
+msgstr "E96: Nelze pøekroèit maximální poèet %ld diff bufferù"
+
+msgid "E97: Cannot create diffs"
+msgstr "E97: Nelze vytvoøit diffy"
+
+msgid "Patch file"
+msgstr "Soubor se záplatou"
+
+msgid "E98: Cannot read diff output"
+msgstr "E98: Nelze èíst výstup programu diff"
+
+msgid "E99: Current buffer is not in diff mode"
+msgstr "E99: Aktuální buffer není v diff režimu"
+
+msgid "E100: No other buffer in diff mode"
+msgstr "E100: To byl poslední buffer v diff režimu"
+
+msgid "E101: More than two buffers in diff mode, don't know which one to use"
+msgstr "E101: V diff režimu jsou více než dva buffery. Nevím, který mám použít."
+
+#, c-format
+msgid "E102: Can't find buffer \"%s\""
+msgstr "E102: Nelze nalézt buffer \"%s\""
+
+#, c-format
+msgid "E103: Buffer \"%s\" is not in diff mode"
+msgstr "E103: Buffer \"%s\" není v diff režimu"
+
+msgid "E104: Escape not allowed in digraph"
+msgstr "E104: digraph nesmí obsahovat Escape"
+
+msgid "Keymap file not found"
+msgstr "Soubor s mapou klávesnice nebyl nalezen"
+
+msgid "E105: Using :loadkeymap not in a sourced file"
+msgstr "E105: :loadkeymap mimo interpretovaný soubor"
+
+msgid " Keyword completion (^N/^P)"
+msgstr " Doplòování klíèových slov (^N/^P)"
+
+#. ctrl_x_mode == 0, ^P/^N compl.
+msgid " ^X mode (^E/^Y/^L/^]/^F/^I/^K/^D/^V/^N/^P)"
+msgstr " ^X režim (^E/^Y/^L/^]/^F/^I/^K/^D/^V/^N/^P)"
+
+#. Scroll has it's own msgs, in it's place there is the msg for local
+#. * ctrl_x_mode = 0 (eg continue_status & CONT_LOCAL) -- Acevedo
+msgid " Keyword Local completion (^N/^P)"
+msgstr " Lokální doplòování klíèových slov (^N/^P)"
+
+msgid " Whole line completion (^L/^N/^P)"
+msgstr " Doplòování celých øádkù (^L/^N/^P)"
+
+msgid " File name completion (^F/^N/^P)"
+msgstr " Doplòování názvù souborù (^F/^N/^P)"
+
+msgid " Tag completion (^]/^N/^P)"
+msgstr " Doplòování tagù (^I/^N/^P)"
+
+msgid " Path pattern completion (^N/^P)"
+msgstr " Doplòování vzoru cest (^N/^P)"
+
+msgid " Definition completion (^D/^N/^P)"
+msgstr " Doplòování definic (^D/^N/^P)"
+
+msgid " Dictionary completion (^K/^N/^P)"
+msgstr " Doplòování podle slovníku (^K/^N/^P)"
+
+msgid " Thesaurus completion (^T/^N/^P)"
+msgstr " Doplòování podle tezauru (^T/^N/^P)"
+
+msgid " Command-line completion (^V/^N/^P)"
+msgstr " Doplòování pøíkazové øádky (^I/^N/^P)"
+
+msgid "Hit end of paragraph"
+msgstr "Konec odstavce"
+
+msgid "'thesaurus' option is empty"
+msgstr "volba 'thesaurus' je prázdná"
+
+msgid "'dictionary' option is empty"
+msgstr "volba 'dictionary' je prázdná"
+
+#, c-format
+msgid "Scanning dictionary: %s"
+msgstr "Prohledávám slovník %s"
+
+msgid " (insert) Scroll (^E/^Y)"
+msgstr " (insert) Rolování (^E/^Y)"
+
+msgid " (replace) Scroll (^E/^Y)"
+msgstr " (replace) Rolování (^E/^Y)"
+
+#, c-format
+msgid "Scanning: %s"
+msgstr "Prohledávám %s"
+
+msgid "Scanning tags."
+msgstr "Prohledávám tagy"
+
+msgid " Adding"
+msgstr "Pøidávám"
+
+#. 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.
+#.
+msgid "-- Searching..."
+msgstr "-- Hledám..."
+
+msgid "Back at original"
+msgstr "Výchozí podoba"
+
+msgid "Word from other line"
+msgstr "Slovo z jiného øádku"
+
+msgid "The only match"
+msgstr "Jediná shoda"
+
+#, c-format
+msgid "match %d of %d"
+msgstr "shoda %d/%d"
+
+#, c-format
+msgid "match %d"
+msgstr "shoda %d"
+
+#, c-format
+msgid "E106: Unknown variable: \"%s\""
+msgstr "E106: Neznámá promìnná: \"%s\""
+
+#, c-format
+msgid "E107: Missing parentheses: %s"
+msgstr "E107: Chybí závorky: %s"
+
+#, c-format
+msgid "E108: No such variable: \"%s\""
+msgstr "E108: Promìnná \"%s\" neexistuje"
+
+msgid "E109: Missing ':' after '?'"
+msgstr "E109: Po '?' chybí ':'"
+
+msgid "E110: Missing ')'"
+msgstr "E110: Chybìjící ')'"
+
+msgid "E111: Missing ']'"
+msgstr "E111: Chybìjící ']'"
+
+#, c-format
+msgid "E112: Option name missing: %s"
+msgstr "E112: Chybí jméno volby: %s"
+
+#, c-format
+msgid "E113: Unknown option: %s"
+msgstr "E113: Neznámá volba: %s"
+
+#, c-format
+msgid "E114: Missing quote: %s"
+msgstr "E114: Chybí uvozovky: %s"
+
+#, c-format
+msgid "E115: Missing quote: %s"
+msgstr "E115: Chybí uvozovky: %s"
+
+#, c-format
+msgid "E116: Invalid arguments for function %s"
+msgstr "E116: Chybné argumenty pro funkci %s"
+
+#, c-format
+msgid "E117: Unknown function: %s"
+msgstr "E117: Neznámá funkce: %s"
+
+#, c-format
+msgid "E118: Too many arguments for function: %s"
+msgstr "E118: Pøíliš mnoho argumentù pro funkci %s"
+
+#, c-format
+msgid "E119: Not enough arguments for function: %s"
+msgstr "E119: Pøíliš málo argumentù pro funkci %s"
+
+#, c-format
+msgid "E120: Using <SID> not in a script context: %s"
+msgstr "E120: Použití <SID> mimo kontext skriptu: %s"
+
+#, c-format
+msgid "+-%s%3ld lines: "
+msgstr "+-%s%3ld øádkù:"
+
+msgid ""
+"&OK\n"
+"&Cancel"
+msgstr ""
+"&OK\n"
+"&Zrušit"
+
+msgid "E240: No connection to Vim server"
+msgstr "E240: Neexistuje pøipojení k Vim serveru"
+
+msgid "E277: Unable to read a server reply"
+msgstr "E277: Nelze èíst odpovìï serveru"
+
+msgid "E258: Unable to send to client"
+msgstr "E258: Nelze pøedat klientovi"
+
+#, c-format
+msgid "E241: Unable to send to %s"
+msgstr "E241: Nelze pøedat do %s"
+
+msgid "(Invalid)"
+msgstr "(Chybný)"
+
+#, c-format
+msgid "E121: Undefined variable: %s"
+msgstr "E121: Nedefinovaná promìnná: %s"
+
+#, c-format
+msgid "E122: Function %s already exists, use ! to replace"
+msgstr "E122: Funkce %s již existuje. Použijte ! pro její nahrazení."
+
+#, c-format
+msgid "E123: Undefined function: %s"
+msgstr "E123: Nedefinovaná funkce: %s"
+
+#, c-format
+msgid "E124: Missing '(': %s"
+msgstr "E124: Chybí '(': %s"
+
+#, c-format
+msgid "E125: Illegal argument: %s"
+msgstr "E125: Nepøípustný argument: %s"
+
+msgid "E126: Missing :endfunction"
+msgstr "E126: Chybí :endfunction"
+
+#, c-format
+msgid "E127: Cannot redefine function %s: It is in use"
+msgstr "E127: Nelze pøedefinovat funkci %s: je používána"
+
+#, c-format
+msgid "E128: Function name must start with a capital: %s"
+msgstr "E128: Název funkce musí zaèínat velkým písmenem: %s"
+
+msgid "E129: Function name required"
+msgstr "E129: Je vyžadováno jméno funkce"
+
+msgid "function "
+msgstr "funkce "
+
+#, c-format
+msgid "E130: Undefined function: %s"
+msgstr "E130: Nedefinovaná funkce: %s"
+
+#, c-format
+msgid "E131: Cannot delete function %s: It is in use"
+msgstr "E131: Nelze smazat funkci %s: je již používána"
+
+msgid "E132: Function call depth is higher than 'maxfuncdepth'"
+msgstr "E132: Zanoøení funkce je hlubší než 'maxfuncdepth'"
+
+#. always scroll up, don't overwrite
+#, c-format
+msgid "calling %s"
+msgstr "volám %s"
+
+#. always scroll up, don't overwrite
+#, c-format
+msgid "continuing in %s"
+msgstr "pokraèuji v %s"
+
+msgid "E133: :return not inside a function"
+msgstr "E133: :return mimo funkci"
+
+#, c-format
+msgid "%s returning #%ld"
+msgstr "dokonèeno provádìní %s. Návratová hodnota #%ld"
+
+#, c-format
+msgid "%s returning \"%s\""
+msgstr "dokonèeno provádìní %s. Návratová hodnota \"%s\""
+
+msgid ""
+"\n"
+"# global variables:\n"
+msgstr ""
+"\n"
+"# globální promìnné:\n"
+
+#, c-format
+msgid "<%s>%s%s %d, Hex %02x, Octal %03o"
+msgstr "<%s>%s%s %d, šestnáctkovì %02x, osmièkovì %03o"
+
+msgid "E134: Move lines into themselves"
+msgstr "E134: Nelze pøesunout øádky na pùvodní místo"
+
+msgid "1 line moved"
+msgstr "poèet pøesunutých øádkù: 1"
+
+#, c-format
+msgid "%ld lines moved"
+msgstr "Poèet pøesunutých øádkù: %ld"
+
+#, c-format
+msgid "%ld lines filtered"
+msgstr "Poèet filtrovaných øádkù: %ld"
+
+msgid "E135: *Filter* Autocommands must not change current buffer"
+msgstr "E135: Automatické pøíkazy *Filter* nesmí mìnit aktuální buffer"
+
+msgid "[No write since last change]\n"
+msgstr "[Neuložené zmìny]\n"
+
+#, c-format
+msgid "viminfo: %s in line: "
+msgstr "viminfo: %s na øádku: "
+
+msgid "E136: viminfo: Too many errors, skipping rest of file"
+msgstr "E136: viminfo: pøíliš mnoho chyb, pøeskakuji zbytek souboru"
+
+#, c-format
+msgid "Reading viminfo file \"%s\"%s%s%s"
+msgstr "Ètu viminfo soubor \"%s\"%s%s%s"
+
+msgid " info"
+msgstr " informace"
+
+msgid " marks"
+msgstr " znaèky"
+
+msgid " FAILED"
+msgstr " se nezdaøilo"
+
+#, c-format
+msgid "E137: Viminfo file is not writable: %s"
+msgstr "E137: do viminfo souboru %s nelze zapisovat"
+
+#, c-format
+msgid "E138: Can't write viminfo file %s!"
+msgstr "E138: Nelze uložit viminfo soubor %s!"
+
+#, c-format
+msgid "Writing viminfo file \"%s\""
+msgstr "Ukládám viminfo souboru \"%s\""
+
+#. Write the info:
+msgid "# This viminfo file was generated by Vim %s.\n"
+msgstr "# Tento viminfo soubor byl vytvoøen editorem Vim %s.\n"
+
+msgid ""
+"# You may edit it if you're careful!\n"
+"\n"
+msgstr ""
+"# Pokud budete opatrný, mùžete jej upravovat.\n"
+"\n"
+
+msgid "# Value of 'encoding' when this file was written\n"
+msgstr "# Hodnota volby 'encoding' v dobì uložení tohoto souboru\n"
+
+msgid "Illegal starting char"
+msgstr "Nepøípustný poèáteèní znak"
+
+msgid "Save As"
+msgstr "Uložit jako"
+
+#. Overwriting a file that is loaded in another buffer is not a
+#. * good idea.
+msgid "E139: File is loaded in another buffer"
+msgstr "E139: Soubor je nahrán v jiném bufferu"
+
+msgid "Write partial file?"
+msgstr "Uložit neúplný soubor?"
+
+msgid "E140: Use ! to write partial buffer"
+msgstr "E140: Použijte ! pro uložení neúplného bufferu"
+
+#, c-format
+msgid "Overwrite existing file \"%.*s\"?"
+msgstr "Pøepsat soubor \"%.*s\"?"
+
+#, c-format
+msgid "E141: No file name for buffer %ld"
+msgstr "E141: Žádný název souboru pro buffer %ld"
+
+msgid "E142: File not written: Writing is disabled by 'write' option"
+msgstr "E142: Soubor nebyl uložen: Ukládání je zakázáno volbou 'write'"
+
+#, c-format
+msgid ""
+"'readonly' option is set for \"%.*s\".\n"
+"Do you wish to write anyway?"
+msgstr ""
+"Pro \"%.*s\" je nastavena volba 'readonly'.\n"
+"Pøejete si ji potlaèit?"
+
+msgid "Edit File"
+msgstr "Editovat soubor"
+
+#, c-format
+msgid "E143: Autocommands unexpectedly deleted new buffer %s"
+msgstr "E143: Automatické pøíkazy neoèekávanì smazaly nový buffer %s"
+
+msgid "E144: non-numeric argument to :z"
+msgstr "E144: neèíselný argument pro :z"
+
+msgid "E145: Shell commands not allowed in rvim"
+msgstr "E145: rvim nepovoluje použití pøíkazù shellu"
+
+msgid "E146: Regular expressions can't be delimited by letters"
+msgstr "E146: Regulární výrazy nesmí být oddìleny písmeny"
+
+#, c-format
+msgid "replace with %s (y/n/a/q/l/^E/^Y)?"
+msgstr "nahradit za %s (y/n/a/q/l/^E/^Y)?"
+
+msgid "(Interrupted) "
+msgstr "(Pøerušeno) "
+
+msgid "1 substitution"
+msgstr "1 nahrazení"
+
+#, c-format
+msgid "%ld substitutions"
+msgstr "%ld nahrazení"
+
+msgid " on 1 line"
+msgstr " na jednom øádku"
+
+#, c-format
+msgid " on %ld lines"
+msgstr " na %ld øádcích"
+
+msgid "E147: Cannot do :global recursive"
+msgstr "E147: :global nelze volat rekurzivnì"
+
+msgid "E148: Regular expression missing from global"
+msgstr "E148: U pøíkazu 'global' chybí regulární výraz"
+
+#, c-format
+msgid "Pattern found in every line: %s"
+msgstr "Vzor nalezen na každém øádku: %s"
+
+msgid ""
+"\n"
+"# Last Substitute String:\n"
+"$"
+msgstr ""
+"\n"
+"# Poslední nahrazující øetìzec:\n"
+"$"
+
+#, c-format
+msgid "E149: Sorry, no help for %s"
+msgstr "E149: Lituji, pro %s není žádná nápovìda"
+
+#, c-format
+msgid "Sorry, help file \"%s\" not found"
+msgstr "Lituji, soubor \"%s\" s nápovìdou nebyl nalezen"
+
+#, c-format
+msgid "E150: Not a directory: %s"
+msgstr "E150: %s není adresáøem"
+
+#, c-format
+msgid "E152: Cannot open %s for writing"
+msgstr "E152: Nelze otevøít %s pro zápis"
+
+#, c-format
+msgid "E153: Unable to open %s for reading"
+msgstr "E153: Nelze otevøít %s pro zápis"
+
+#, c-format
+msgid "E154: Duplicate tag \"%s\" in file %s"
+msgstr "E154: Duplicitní tag \"%s\" v souboru %s"
+
+#, c-format
+msgid "E160: Unknown sign command: %s"
+msgstr "E160: Neznámá volba pøíkazu: %s"
+
+msgid "E156: Missing sign name"
+msgstr "E156: Chybí jméno volby"
+
+msgid "E255: Too many signs defined"
+msgstr "E255: Nastaveno pøíliš mnoho voleb"
+
+#, c-format
+msgid "E239: Invalid sign text: %s"
+msgstr "E239: Neplatný text volby: %s"
+
+#, c-format
+msgid "E155: Unknown sign: %s"
+msgstr "E155: Neznámá volba: %s"
+
+msgid "E159: Missing sign number"
+msgstr "E159: Chybí identifikátor volby"
+
+#, c-format
+msgid "E158: Invalid buffer name: %s"
+msgstr "E158: chybné jméno bufferu: %s"
+
+#, c-format
+msgid "E157: Invalid sign ID: %ld"
+msgstr "E157: Chybné ID volby: %ld"
+
+msgid "[Deleted]"
+msgstr "[Vymazáno]"
+
+msgid "Entering Debug mode. Type \"cont\" to leave."
+msgstr "Spouštím ladící režim. Pro ukonèení napište \"cont\"."
+
+#, c-format
+msgid "line %ld: %s"
+msgstr "øádek %ld: %s"
+
+#, c-format
+msgid "cmd: %s"
+msgstr "pøíkaz: %s"
+
+#, c-format
+msgid "Breakpoint in \"%s%s\" line %ld"
+msgstr "Bod pøerušení v \"%s%s\" na øádku %ld"
+
+#, c-format
+msgid "E161: Breakpoint not found: %s"
+msgstr "E161: Bod pøerušení nenalezen: %s"
+
+msgid "No breakpoints defined"
+msgstr "Nebyly definovánu žádné body pøerušení"
+
+#, c-format
+msgid "%3d %s %s line %ld"
+msgstr "%3d %s %s øádek %ld"
+
+#, c-format
+msgid "Save changes to \"%.*s\"?"
+msgstr "Uložit zmìny do \"%.*s\"?"
+
+msgid "Untitled"
+msgstr "Nepojmenováno"
+
+#, c-format
+msgid "E162: No write since last change for buffer \"%s\""
+msgstr "E162: Buffer \"%s\" obsahuje neuložené zmìny"
+
+msgid "Warning: Entered other buffer unexpectedly (check autocommands)"
+msgstr ""
+"Varování: Neèekaný vstup do jiného bufferu (zkontrolujte automatické pøíkazy)"
+
+msgid "E163: There is only one file to edit"
+msgstr "E163: Pro editaci byl zadán pouze jeden soubor"
+
+msgid "E164: Cannot go before first file"
+msgstr "E164: Pøed první soubor nelze pøeskoèit"
+
+msgid "E165: Cannot go beyond last file"
+msgstr "E165: Za poslední soubor nelze pøeskoèit"
+
+#, c-format
+msgid "Searching for \"%s\" in \"%s\""
+msgstr "Hledám \"%s\" v \"%s\""
+
+#, c-format
+msgid "Searching for \"%s\""
+msgstr "Hledám \"%s\""
+
+#, c-format
+msgid "not found in 'runtimepath': \"%s\""
+msgstr "soubor \"%s\" nebyl nalezen v 'runtimepath'"
+
+msgid "Run Macro"
+msgstr "Spustit makro"
+
+#, c-format
+msgid "Cannot source a directory: \"%s\""
+msgstr "nelze interpretovat adresáø: \"%s\""
+
+#, c-format
+msgid "could not source \"%s\""
+msgstr "nelze interpretovat \"%s\""
+
+#, c-format
+msgid "line %ld: could not source \"%s\""
+msgstr "øádek %ld: nelze interpretovat \"%s\""
+
+#, c-format
+msgid "sourcing \"%s\""
+msgstr "interpretuji \"%s\""
+
+#, c-format
+msgid "line %ld: sourcing \"%s\""
+msgstr "øádek %ld: interpretuji %s"
+
+#, c-format
+msgid "finished sourcing %s"
+msgstr "dokonèena interpretace %s"
+
+msgid "W15: Warning: Wrong line separator, ^M may be missing"
+msgstr "W15: Varování: chybný oddìlovaè øádkù. Možná chybí ^M."
+
+msgid "E167: :scriptencoding used outside of a sourced file"
+msgstr "E167: :scriptencoding použito mimo interpretovaný soubor"
+
+msgid "E168: :finish used outside of a sourced file"
+msgstr "E168: :finish použito mimo interpretovaný soubor"
+
+msgid "No text to be printed"
+msgstr "Žádný text k vytištìní"
+
+msgid "Printing page %d (%d%%)"
+msgstr "Tisknu stranu %d (%d%%)"
+
+#, c-format
+msgid " Copy %d of %d"
+msgstr " Kopie %d z %d"
+
+#, c-format
+msgid "Printed: %s"
+msgstr "Vytištìno: %s"
+
+msgid "Printing aborted"
+msgstr "Tisk zrušen"
+
+msgid "E455: Error writing to PostScript output file"
+msgstr "E455: Nelze zapisovat do výstupního PostScriptového souboru"
+
+msgid "E324: Can't open PostScript output file"
+msgstr "E324: Nelze otevøít výstupní PostScriptový soubor"
+
+msgid "E456: Can't open file \"%s\""
+msgstr "E456: Nelze otevøít soubor \"%s\""
+
+msgid "E457: Can't read PostScript resource file \"%s\""
+msgstr "E457: Nelze èíst zdrojový PostScriptový soubor \"%s\""
+
+msgid "Sending to printer..."
+msgstr "Odesílám na tiskárnu..."
+
+msgid "E365: Failed to print PostScript file"
+msgstr "E365: Selhal tisk PostScriptového souboru"
+
+msgid "Print job sent."
+msgstr "Tisková úloha odeslána."
+
+#, c-format
+msgid "Current %slanguage: \"%s\""
+msgstr "Aktuální %sjazyk: \"%s\""
+
+#, c-format
+msgid "E197: Cannot set language to \"%s\""
+msgstr "E197: Nelze nastavit jazyk na \"%s\""
+
+msgid "Entering Ex mode. Type \"visual\" to go to Normal mode."
+msgstr "Spouštím Ex mód. Napište \"visual\" pro návrat do normálního módu."
+
+#. must be at EOF
+msgid "At end-of-file"
+msgstr "Konec souboru"
+
+msgid "E169: Command too recursive"
+msgstr "E169: Pøíkaz je pøíliš rekurzivní"
+
+msgid "E170: Missing :endwhile"
+msgstr "E170: Chybí :endwhile"
+
+msgid "E171: Missing :endif"
+msgstr "E171: Chybí :endif"
+
+msgid "End of sourced file"
+msgstr "Konec interpretovaného souboru"
+
+msgid "End of function"
+msgstr "Konec funkce"
+
+msgid "Ambiguous use of user-defined command"
+msgstr "Nejednoznaèné použití uživatelsky definovaného pøíkazu"
+
+msgid "Not an editor command"
+msgstr "Není pøíkazem editoru"
+
+msgid "Don't panic!"
+msgstr "Nepanikaøte!"
+
+msgid "Backwards range given"
+msgstr "Zadán zpìtný rozsah"
+
+msgid "Backwards range given, OK to swap"
+msgstr "Zadán zpìtný rozsah. Prohodit hranice"
+
+msgid "Use w or w>>"
+msgstr "Použijte w èi w>>"
+
+msgid "E319: Sorry, the command is not available in this version"
+msgstr "E319: Pøíkaz není této verzi bohužel implementován"
+
+msgid "E172: Only one file name allowed"
+msgstr "E172: Pøípustný je pouze jeden název souboru"
+
+#, c-format
+msgid "%d more files to edit. Quit anyway?"
+msgstr "Ještì zbývají soubory k editaci (%d). Chcete pøesto ukonèit editor?"
+
+#, c-format
+msgid "E173: %ld more files to edit"
+msgstr "E173: Ještì zbývají soubory k editaci (%ld)."
+
+msgid "E174: Command already exists: use ! to redefine"
+msgstr "E174: Pøíkaz již existuje: použijte ! pro pøedefinování"
+
+msgid ""
+"\n"
+" Name Args Range Complete Definition"
+msgstr ""
+"\n"
+" Jméno Args Rozsah Úplnost Definice"
+
+msgid "No user-defined commands found"
+msgstr "Nebyly nalezeny žádné uživatelsky definované pøíkazy"
+
+msgid "E175: No attribute specified"
+msgstr "E175: Nebyly zadány žádné atributy"
+
+msgid "E176: Invalid number of arguments"
+msgstr "E176: Chybný poèet argumentù"
+
+msgid "E177: Count cannot be specified twice"
+msgstr "E177: Opakování nemùže být zadáno dvakrát"
+
+msgid "E178: Invalid default value for count"
+msgstr "E178: Chybná implicitní hodnota pro poèet"
+
+msgid "E179: argument required for complete"
+msgstr "E179: chybná implicitní hodnota pro opakování"
+
+#, c-format
+msgid "E180: Invalid complete value: %s"
+msgstr "E180: Chybná hodnota doplnìní: %s"
+
+#, c-format
+msgid "E181: Invalid attribute: %s"
+msgstr "E181: Chybný atribut: %s"
+
+msgid "E182: Invalid command name"
+msgstr "E182: Chybné jméno pøíkazu"
+
+msgid "E183: User defined commands must start with an uppercase letter"
+msgstr "E183: Uživatelsky definované pøíkazy musí zaèínat velikým písmenem."
+
+#, c-format
+msgid "E184: No such user-defined command: %s"
+msgstr "E184: Uživatelsky definovaný pøíkaz %s neexistuje"
+
+#, c-format
+msgid "E185: Cannot find color scheme %s"
+msgstr "E185: Nelze nalézt barevné schéma %s"
+
+msgid "Greetings, Vim user!"
+msgstr "Blahopøeji, uživateli Vimu!"
+
+msgid "Edit File in new window"
+msgstr "Editovat soubor v novém oknì"
+
+msgid "No swap file"
+msgstr "Žádný odkládací soubor"
+
+msgid "Append File"
+msgstr "Uložit soubor"
+
+msgid "E186: No previous directory"
+msgstr "E186: Žádný pøedchozí adresáø"
+
+msgid "E187: Unknown"
+msgstr "E187: Neznámý"
+
+#, c-format
+msgid "Window position: X %d, Y %d"
+msgstr "Umístìní okna: X %d, Y %d"
+
+msgid "E188: Obtaining window position not implemented for this platform"
+msgstr "E188: Na této platformì nelze umístìní okna zjistit"
+
+msgid "Save Redirection"
+msgstr "Uložit pøesmìrování"
+
+msgid "Save View"
+msgstr "Uložit pohled"
+
+msgid "Save Session"
+msgstr "Uložit sezení"
+
+msgid "Save Setup"
+msgstr "Uložit nastavení"
+
+#, c-format
+msgid "E189: \"%s\" exists (use ! to override)"
+msgstr "E189: \"%s\" existuje (použijte ! pro vynucení)"
+
+#, c-format
+msgid "E190: Cannot open \"%s\" for writing"
+msgstr "E190: Nelze otevøít \"%s\" pro zápis"
+
+#. set mark
+msgid "E191: Argument must be a letter or forward/backward quote"
+msgstr "E191: Argumentem mùže být pouze písmeno nebo pravý èi levý apostrof"
+
+msgid "E192: Recursive use of :normal too deep"
+msgstr "E192: Vnoøení :normal je pøíliš hluboké"
+
+msgid ":if nesting too deep"
+msgstr "vnoøení :if je pøíliš hluboké"
+
+msgid ":endif without :if"
+msgstr ":endif bez odpovídajícího :if"
+
+msgid ":else without :if"
+msgstr ":else bez odpovídajícího :if"
+
+msgid ":elseif without :if"
+msgstr ":elseif bez odpovídajícího :if"
+
+msgid ":while nesting too deep"
+msgstr "vnoøení :while je pøíliš hluboké"
+
+msgid ":continue without :while"
+msgstr ":continue bez odpovídajícího :while"
+
+msgid ":break without :while"
+msgstr ":break bez odpovídajícího :while"
+
+msgid ":endwhile without :while"
+msgstr ":endwhile bez odpovídajícího :while"
+
+msgid "E193: :endfunction not inside a function"
+msgstr "E193: :endfunction mimo funkci"
+
+msgid "E194: No alternate file name to substitute for '#'"
+msgstr ""
+"E194: Žádný alternativní název souboru, kterým by bylo možné nahradit '#'"
+
+msgid "no autocommand file name to substitute for \"<afile>\""
+msgstr "Žádný název souboru, kterým by bylo možné nahradit \"<afile>\""
+
+msgid "no autocommand buffer number to substitute for \"<abuf>\""
+msgstr "Žádné èíslo bufferu, kterým by bylo možné nahradit \"<abuf>\""
+
+msgid "no autocommand match name to substitute for \"<amatch>\""
+msgstr ""
+"Žádná shoda automatických pøíkazù, kterou by bylo možné nahradit \"<amatch>\""
+
+msgid "no :source file name to substitute for \"<sfile>\""
+msgstr "Žádný interpretovaný soubor, kterým by bylo možné nahradit \"<sfile>\""
+
+#, no-c-format
+msgid "Empty file name for '%' or '#', only works with \":p:h\""
+msgstr "Prázdný název souboru pro '%' èi '#' funguje pouze s \":p:h\""
+
+msgid "Evaluates to an empty string"
+msgstr "Výsledkem vyhodnocení je prázdný øetìzec"
+
+msgid "E195: Cannot open viminfo file for reading"
+msgstr "E195: Nelze otevøít pro ètení viminfo soubor"
+
+msgid "E196: No digraphs in this version"
+msgstr "E196: V této verzi nejsou spøežky podporovány"
+
+msgid "tagname"
+msgstr "jméno tagu"
+
+msgid " kind file\n"
+msgstr " typ soubor\n"
+
+msgid "'history' option is zero"
+msgstr "'volba 'history' je nastavena na nulu"
+
+#, c-format
+msgid ""
+"\n"
+"# %s History (newest to oldest):\n"
+msgstr ""
+"\n"
+"# Historie %s (poèínaje nejnovìjší položkou):\n"
+
+msgid "Command Line"
+msgstr "pøíkazové øádky"
+
+msgid "Search String"
+msgstr "vyhledávaných øetìzcù"
+
+msgid "Expression"
+msgstr "výrazù"
+
+msgid "Input Line"
+msgstr "vstupní øádky"
+
+msgid "E198: cmd_pchar beyond the command length"
+msgstr "E198: cmd_pchar pøekraèuje délku pøíkazu"
+
+msgid "E199: Active window or buffer deleted"
+msgstr "E199: Smazáno aktivní okno èi buffer"
+
+msgid "Illegal file name"
+msgstr "nepøípustný název souboru"
+
+msgid "is a directory"
+msgstr "je adresáøem"
+
+msgid "is not a file"
+msgstr "není souborem"
+
+msgid "[New File]"
+msgstr "[nový soubor]"
+
+msgid "[Permission Denied]"
+msgstr "[pøístup odmítnut]"
+
+msgid "E200: *ReadPre autocommands made the file unreadable"
+msgstr "E200: *ReadPre automatické pøíkazy uèinily soubor neèitelným"
+
+msgid "E201: *ReadPre autocommands must not change current buffer"
+msgstr "E201: *ReadPre automatické pøíkazy nesmí mìnit aktuální buffer"
+
+msgid "Vim: Reading from stdin...\n"
+msgstr "Vim: Ètu ze standardního vstupu...\n"
+
+msgid "Reading from stdin..."
+msgstr "Ètu ze standardního vstupu..."
+
+#. Re-opening the original file failed!
+msgid "E202: Conversion made file unreadable!"
+msgstr "E202: Po konverzi je soubor neèitelný!"
+
+msgid "[fifo/socket]"
+msgstr "[pojmenovaná roura/soket]"
+
+msgid "[fifo]"
+msgstr "[pojmenovaná roura]"
+
+msgid "[socket]"
+msgstr "[soket]"
+
+msgid "[RO]"
+msgstr "[RO]"
+
+msgid "[CR missing]"
+msgstr "[chybí CR]"
+
+msgid "[NL found]"
+msgstr "[nalezeno NL]"
+
+msgid "[long lines split]"
+msgstr "[dlouhé øádky zalomeny]"
+
+msgid "[NOT converted]"
+msgstr "[nezkonvertován]"
+
+msgid "[converted]"
+msgstr "[zkonvertován]"
+
+msgid "[crypted]"
+msgstr "[zašifrován]"
+
+msgid "[CONVERSION ERROR]"
+msgstr "[CHYBA PØEVODU]"
+
+msgid "[READ ERRORS]"
+msgstr "[CHYBY ÈTENÍ]"
+
+msgid "Can't find temp file for conversion"
+msgstr "Nelze nalézt doèasný soubor pro konverzi"
+
+msgid "Conversion with 'charconvert' failed"
+msgstr "Konverze s 'charconvert' se nezdaøila"
+
+msgid "can't read output of 'charconvert'"
+msgstr "nelze èíst výstup 'charconvert'"
+
+msgid "E203: Autocommands deleted or unloaded buffer to be written"
+msgstr ""
+"E203: Automatické pøíkazy smazaly èi deaktivovaly buffer, který mìl být "
+"uložen"
+
+msgid "E204: Autocommand changed number of lines in unexpected way"
+msgstr "E204: Automatický pøíkaz neèekaným zpùsobem zmìnil poèet øádkù"
+
+msgid "is not a file or writable device"
+msgstr "není souborem ani zaøízením na nìž lze zapisovat"
+
+msgid "is read-only (use ! to override)"
+msgstr "je pouze pro ètení (použijte ! pro vynucení)"
+
+msgid "Can't write to backup file (use ! to override)"
+msgstr "Nelze zapisovat do záložního souboru (použijte ! pro vynucení)"
+
+msgid "Close error for backup file (use ! to override)"
+msgstr "Chyba pøi uzavírání záložního souboru (použijte ! pro vynucení)"
+
+msgid "Can't read file for backup (use ! to override)"
+msgstr "Nelze naèíst soubor pro zálohu (použijte ! pro vynucení)"
+
+msgid "Cannot create backup file (use ! to override)"
+msgstr "Nelze vytvoøit záložní soubor (použijte ! pro vynucení)"
+
+msgid "Can't make backup file (use ! to override)"
+msgstr "Nelze vytvoøit záložní soubor (použijte ! pro vynucení)"
+
+# resource fork ?!
+msgid "The resource fork will be lost (use ! to override)"
+msgstr "'Resource fork' bude ztracen (použijte ! pro vynucení)"
+
+msgid "E214: Can't find temp file for writing"
+msgstr "E214: Nelze najít doèasný temp soubor pro zápis"
+
+msgid "E213: Cannot convert (use ! to write without conversion)"
+msgstr "E213: Nelze pøevést (použijte ! pro zápis bez pøevodu)"
+
+msgid "E166: Can't open linked file for writing"
+msgstr "E166: Nelze otevøít pøipojený soubor pro zápis"
+
+msgid "E212: Can't open file for writing"
+msgstr "E212: Nelze otevøít soubor pro zápis"
+
+msgid "Close failed"
+msgstr "Volání close selhalo"
+
+msgid "write error, conversion failed"
+msgstr "chyba pøi zápisu, konverze se nezdaøila"
+
+msgid "write error (file system full?)"
+msgstr "chyba pøi ukládání (je volné místo na disku?)"
+
+msgid " CONVERSION ERROR"
+msgstr " CHYBA PØEVODU"
+
+msgid "[Device]"
+msgstr "[zaøízení]"
+
+msgid "[New]"
+msgstr "[Nový]"
+
+msgid " [a]"
+msgstr " [p]"
+
+msgid " appended"
+msgstr " pøipojen"
+
+msgid " [w]"
+msgstr " [u]"
+
+msgid " written"
+msgstr " uložen"
+
+msgid "E205: Patchmode: can't save original file"
+msgstr "E205: patchmode: nelze uložit pùvodní soubor"
+
+msgid "E206: patchmode: can't touch empty original file"
+msgstr "E206: patchmode: nelze zapisovat do prázdného pùvodního souboru"
+
+msgid "E207: Can't delete backup file"
+msgstr "E207: Nelze smazat záložní soubor"
+
+msgid ""
+"\n"
+"WARNING: Original file may be lost or damaged\n"
+msgstr ""
+"\n"
+"VAROVÁNÍ: Obsah pùvodního souboru mùže být ztracen èi poškozen\n"
+
+msgid "don't quit the editor until the file is successfully written!"
+msgstr "neukonèujte editor døíve, než bude soubor úspìšnì uložen!"
+
+msgid "[dos]"
+msgstr "[dos]"
+
+msgid "[dos format]"
+msgstr "[dos formát]"
+
+msgid "[mac]"
+msgstr "[mac]"
+
+msgid "[mac format]"
+msgstr "[mac formát]"
+
+msgid "[unix]"
+msgstr "[unix]"
+
+msgid "[unix format]"
+msgstr "[unix formát]"
+
+msgid "1 line, "
+msgstr "1 øádek, "
+
+#, c-format
+msgid "%ld lines, "
+msgstr "%ld øádkù, "
+
+msgid "1 character"
+msgstr "1 znak"
+
+#, c-format
+msgid "%ld characters"
+msgstr "%ld znakù, "
+
+msgid "[noeol]"
+msgstr "[žádný eol]"
+
+msgid "[Incomplete last line]"
+msgstr "[neúplný poslední øádek]"
+
+#. 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 "VAROVÁNÍ: od jeho naètení byl obsah souboru zmìnìn!!!!"
+
+msgid "Do you really want to write to it"
+msgstr "Chcete jej opravdu uložit"
+
+#, c-format
+msgid "E208: Error writing to \"%s\""
+msgstr "E208: Chyba pøi zápisu do \"%s\""
+
+#, c-format
+msgid "E209: Error closing \"%s\""
+msgstr "E209: Chyb pøi uzavírání \"%s\""
+
+#, c-format
+msgid "E210: Error reading \"%s\""
+msgstr "E210: Chyba pøi ètení \"%s\""
+
+msgid "E246: FileChangedShell autocommand deleted buffer"
+msgstr "E246: FileChangedShell autocommand zrušil buffer"
+
+#, c-format
+msgid "E211: Warning: File \"%s\" no longer available"
+msgstr "E211: wa1: soubor \"%s\" již není dostupný"
+
+#, c-format
+msgid ""
+"W12: Warning: File \"%s\" has changed and the buffer was changed in Vim as "
+"well"
+msgstr ""
+"W12: Varování: soubor \"%s\" byl po poèátku editace zmìnìn a buffer ve Vim "
+"také"
+
+#, c-format
+msgid "W11: Warning: File \"%s\" has changed since editing started"
+msgstr "W11: wc2: soubor \"%s\" byl po poèátku editace zmìnìn"
+
+#, c-format
+msgid "W16: Warning: Mode of file \"%s\" has changed since editing started"
+msgstr "W16: Varování: Mód souboru \"%s\" byl zmìnìn od zapoènutí editace"
+
+#, c-format
+msgid "W13: Warning: File \"%s\" has been created after editing started"
+msgstr "W13: wc4: po poèátku editace vytvoøen soubor \"%s\""
+
+msgid "Warning"
+msgstr "Varování"
+
+msgid ""
+"&OK\n"
+"&Load File"
+msgstr ""
+"&OK\n"
+"&Nahrát soubor"
+
+#, c-format
+msgid "E321: Could not reload \"%s\""
+msgstr "E321: Nelze znovuotevøít \"%s\""
+
+msgid "--Deleted--"
+msgstr "--Vymazáno--"
+
+#. the group doesn't exist
+#, c-format
+msgid "E367: No such group: \"%s\""
+msgstr "E367: Skupina \"%s\" neexistuje"
+
+#, c-format
+msgid "E215: Illegal character after *: %s"
+msgstr "E215: Nepøípustný znak po *: %s"
+
+#, c-format
+msgid "E216: No such event: %s"
+msgstr "E216: Událost %s neexistuje"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Auto-Commands ---"
+msgstr ""
+"\n"
+"--- Automatické pøíkazy ---"
+
+msgid "E217: Can't execute autocommands for ALL events"
+msgstr "E217: Automatické pøíkazy nelze spustit pro VŠECHNY události"
+
+msgid "No matching autocommands"
+msgstr "Žádné vyhovující automatické pøíkazy"
+
+msgid "E218: autocommand nesting too deep"
+msgstr "E218: vnoøení automatického pøíkazu pøíliš hluboká"
+
+#, c-format
+msgid "%s Auto commands for \"%s\""
+msgstr "%s automatické pøíkazy pro \"%s\""
+
+#, c-format
+msgid "Executing %s"
+msgstr "spouštím %s"
+
+#. always scroll up, don't overwrite
+#, c-format
+msgid "autocommand %s"
+msgstr "Automatický pøíkaz %s"
+
+msgid "E219: Missing {."
+msgstr "E219: Chybí {."
+
+msgid "E220: Missing }."
+msgstr "E220: Chybí }."
+
+msgid "No fold found"
+msgstr "Žádný záhyb nebyl nalezen"
+
+msgid "E350: Cannot create fold with current 'foldmethod'"
+msgstr "E350: pomocí aktuální 'foldmethod' nelze vytvoøit záhyb"
+
+msgid "E351: Cannot delete fold with current 'foldmethod'"
+msgstr "E351: pomocí aktuální 'foldmethod' nelze vytvoøit záhyb"
+
+msgid "E221: 'commentstring' is empty"
+msgstr "E221: volba 'commentstring' je prázdná"
+
+msgid "E222: Add to read buffer"
+msgstr "E222: Pøidat do bufferu pro ètení"
+
+msgid "E223: recursive mapping"
+msgstr "E223: rekurzivní mapování"
+
+#, c-format
+msgid "E224: global abbreviation already exists for %s"
+msgstr "E224: pro %s již globální zkratka již existuje"
+
+#, c-format
+msgid "E225: global mapping already exists for %s"
+msgstr "E225: pro %s již globální mapování již existuje"
+
+#, c-format
+msgid "E226: abbreviation already exists for %s"
+msgstr "E226: pro %s již zkratka již existuje"
+
+#, c-format
+msgid "E227: mapping already exists for %s"
+msgstr "E227: pro %s již mapování již existuje"
+
+msgid "No abbreviation found"
+msgstr "Žádná zkratka nebyl nalezena"
+
+msgid "No mapping found"
+msgstr "Žádné mapování nebylo nalezeno"
+
+msgid "E228: makemap: Illegal mode"
+msgstr "E228: makemap: nepøípustný mód"
+
+msgid "E229: Cannot start the GUI"
+msgstr "E229: Nelze spustit GUI"
+
+#, c-format
+msgid "E230: Cannot read from \"%s\""
+msgstr "E230: Nelze èíst z \"%s\""
+
+msgid "E231: 'guifontwide' invalid"
+msgstr "E231: volba 'guifontwide' je chybnì nastavena"
+
+msgid "Error"
+msgstr "Chyba"
+
+msgid "&Ok"
+msgstr "&Ok"
+
+msgid "<cannot open> "
+msgstr "<nelze otevøít> "
+
+#, c-format
+msgid "vim_SelFile: can't get font %s"
+msgstr "vim_SelFile: písmo %s není dostupné"
+
+msgid "vim_SelFile: can't return to current directory"
+msgstr "vim_SelFile: nelze se vrátit do aktuálního adresáøe"
+
+msgid "Pathname:"
+msgstr "Název cesty:"
+
+msgid "vim_SelFile: can't get current directory"
+msgstr "vim_SelFile: nelze zjistit aktuální adresáø"
+
+msgid "OK"
+msgstr "OK"
+
+#. 'Cancel' button
+msgid "Cancel"
+msgstr "Zrušit"
+
+msgid "Scrollbar Widget: Could not get geometry of thumb pixmap."
+msgstr "Pøípravek posunovací lišty: nelze zjistit geometrii obrázku"
+
+msgid "Vim dialog"
+msgstr "Vim dialog"
+
+msgid "E232: Cannot create BalloonEval with both message and callback"
+msgstr "E232: BalloonEval nelze vytvoøit se zprávou a zároveò zpìtným voláním"
+
+msgid "Vim dialog..."
+msgstr "Vim dialog.."
+
+msgid "VIM - Search and Replace..."
+msgstr "VIM - Nalézt a nahradit..."
+
+msgid "VIM - Search..."
+msgstr "VIM - Nalézt..."
+
+msgid "Find what:"
+msgstr "Vyhledat:"
+
+msgid "Replace with:"
+msgstr "Nový text:"
+
+#. exact match only button
+msgid "Match exact word only"
+msgstr "hledat pouze celá slova"
+
+msgid "Direction"
+msgstr "Smìr"
+
+#. 'Up' and 'Down' buttons
+msgid "Up"
+msgstr "Nahoru"
+
+msgid "Down"
+msgstr "Dolù"
+
+#. 'Find Next' button
+msgid "Find Next"
+msgstr "Najít další"
+
+#. 'Replace' button
+msgid "Replace"
+msgstr "Nahradit"
+
+#. 'Replace All' button
+msgid "Replace All"
+msgstr "Nahradit vše"
+
+msgid "E233: cannot open display"
+msgstr "E233: nelze otevøít display"
+
+#, c-format
+msgid "E234: Unknown fontset: %s"
+msgstr "E234: Neznámá sada písem: %s"
+
+msgid "Font Selection"
+msgstr "Výbìr písma"
+
+#, c-format
+msgid "E235: Unknown font: %s"
+msgstr "E235: Neznámé písmo: %s"
+
+#, c-format
+msgid "E236: Font \"%s\" is not fixed-width"
+msgstr "E236: Písmo \"%s\" nemá pevnou šíøku"
+
+#, c-format
+msgid "E242: Color name not recognized: %s"
+msgstr "E242: Neznámé jméno barvy: %s"
+
+msgid "Used CUT_BUFFER0 instead of empty selection"
+msgstr "Místo prádné schránky použito CUT_BUFFER0"
+
+msgid "Filter"
+msgstr "Filtr"
+
+msgid "Directories"
+msgstr "Adresáøe"
+
+msgid "Help"
+msgstr "Nápovìda"
+
+msgid "Files"
+msgstr "Soubory"
+
+msgid "Selection"
+msgstr "Výbìr"
+
+msgid "Undo"
+msgstr "Zpìt"
+
+#, c-format
+msgid "E235: Can't load Zap font '%s'"
+msgstr "E235: Nelze naèíst Zap font '%s'"
+
+#, c-format
+msgid "E235: Can't use font %s"
+msgstr "E235: Nelze použít font %s"
+
+#, c-format
+msgid "E242: Missing color: %s"
+msgstr "E242: Chybí barva: %s"
+
+msgid ""
+"\n"
+"Sending message to terminate child process.\n"
+msgstr ""
+"\n"
+"Posílám signál k ukonèení synovského procesu.\n"
+
+#, c-format
+msgid "E243: Argument not supported: \"-%s\"; Use the OLE version."
+msgstr "E243: Argument nepodporován: \"-%s\"; Použijte OLE verzi."
+
+msgid "Find string (use '\\\\' to find a '\\')"
+msgstr "Najít øetìzec (použijte '\\\\' k nalezení '\\')"
+
+msgid "Find & Replace (use '\\\\' to find a '\\')"
+msgstr "Najít & Nahradit (použijte '\\\\' k nalezení '\\')"
+
+msgid "Vim E458: Cannot allocate colormap entry, some colors may be incorrect"
+msgstr ""
+"Vim E458: nelze alokovat položku barevné mapy. Nìkteré barvy mohou být "
+"nesprávné"
+
+#, c-format
+msgid "E250: Fonts for the following charsets are missing in fontset %s:"
+msgstr "E250: písma pro následující znakové sady chybí v sadì písem %s:"
+
+#, c-format
+msgid "E252: Fontset name: %s"
+msgstr "E252: název sady písem: %s"
+
+#, c-format
+msgid "Font '%s' is not fixed-width"
+msgstr "Písmo '%s' nemá pevnou šíøku"
+
+#, c-format
+msgid "E253: Fontset name: %s\n"
+msgstr "E253: název sady písem: %s\n"
+
+#, c-format
+msgid "Font0: %s\n"
+msgstr "Písmo0: %s\n"
+
+#, c-format
+msgid "Font1: %s\n"
+msgstr "Písmo1: %s\n"
+
+#, c-format
+msgid "Font%d width is not twice that of font0\n"
+msgstr "Šíøka písma%d není dvojnásoblem šíøky písma0\n"
+
+#, c-format
+msgid "Font0 width: %ld\n"
+msgstr "Šíøka písma0: %ld\n"
+
+#, c-format
+msgid ""
+"Font1 width: %ld\n"
+"\n"
+msgstr ""
+"Šíøka písma1: %ld\n"
+"\n"
+
+#, c-format
+msgid "E254: Cannot allocate color %s"
+msgstr "E254: nelze alokovat barvu %s"
+
+msgid "E255: Couldn't read in sign data!"
+msgstr "E255: Chyba -- nelze pøeèíst sign data!"
+
+msgid "E256: Hangul automata ERROR"
+msgstr "E256: CYBA Hangul automatu"
+
+msgid "Add a new database"
+msgstr "Pøidat novou databázi"
+
+msgid "Query for a pattern"
+msgstr "Hledání vzorku"
+
+msgid "Show this message"
+msgstr "Zobrazit tuto zprávu"
+
+msgid "Kill a connection"
+msgstr "Ukonèit spojení"
+
+msgid "Reinit all connections"
+msgstr "Znovu inicializovat všechna spojení"
+
+msgid "Show connections"
+msgstr "Zobrazit spojení"
+
+msgid "This cscope command does not support splitting the window.\n"
+msgstr "Tento cscope pøíkaz nepodporuje rozdìlení okna.\n"
+
+msgid "Usage: cstag <ident>"
+msgstr "Použití: cstag <odsazení>"
+
+msgid "E257: cstag: tag not found"
+msgstr "E257: cstag: tag nenalezen"
+
+#, c-format
+msgid "stat(%s) error: %d"
+msgstr "stat(%s) chyba: %d"
+
+#, c-format
+msgid "Added cscope database %s"
+msgstr "Pøidána cscope databáze %s"
+
+#, c-format
+msgid "%s is not a directory or a valid cscope database"
+msgstr "%s není ani adresáøem ani správnou cscope databází"
+
+#, c-format
+msgid "error reading cscope connection %d"
+msgstr "chyba pøi ètení cscope spojení %d"
+
+msgid "unknown cscope search type"
+msgstr "neznámý typ cscope hledání"
+
+msgid "Could not create cscope pipes"
+msgstr "nelze vytvoøit cscope roury"
+
+msgid "cs_create_connection exec failed"
+msgstr "spuštìní cs_create_connection selhalo"
+
+msgid "cs_create_connection: fdopen for to_fp failed"
+msgstr "cs_create_connection: volání fdopen pro to_fp selhalo"
+
+msgid "cs_create_connection: fdopen for fr_fp failed"
+msgstr "cs_create_connection: volání fdopen pro fr_fp selhalo"
+
+msgid "no cscope connections"
+msgstr "žádná cscope spojení"
+
+#, c-format
+msgid "E259: no matches found for cscope query %s of %s"
+msgstr "E259: cscope hledání %s vzorku %s nenašlo žádnou shodu"
+
+msgid "cscope commands:\n"
+msgstr "pøíkazy cscope:\n"
+
+#, c-format
+msgid "%-5s: %-30s (Usage: %s)\n"
+msgstr "%-5s: %-30s (Použití: %s)\n"
+
+msgid "duplicate cscope database not added"
+msgstr "duplicitní cscope databáze nebyla pøidána"
+
+msgid "maximum number of cscope connections reached"
+msgstr "dosažen maximální poèet cscope spojení"
+
+msgid "E260: cscope connection not found"
+msgstr "E260: connection spojení nenalezeno"
+
+#, c-format
+msgid "E261: cscope connection %s not found"
+msgstr "E261: connection spojení %s nenalezeno"
+
+msgid "cscope connection closed"
+msgstr "closed spojení uzavøeno"
+
+#, c-format
+msgid "cscope connection %s closed\n"
+msgstr "cscope spojení %s uzavøeno\n"
+
+#. should not reach here
+msgid "fatal error in cs_manage_matches"
+msgstr "osudová chyba v cs_manage_matches"
+
+#, c-format
+msgid "E262: error reading cscope connection %d"
+msgstr "E262: pøi ètení cscope spojení %d"
+
+msgid "couldn't malloc\n"
+msgstr "volání malloc selhalo\n"
+
+#, c-format
+msgid "Cscope tag: %s\n"
+msgstr "Cscope tag: %s\n"
+
+msgid " # line"
+msgstr " # øádek"
+
+msgid "filename / context / line\n"
+msgstr "název souboru/ kontext/ øádek\n"
+
+msgid "All cscope databases reset"
+msgstr "Všechny cscope databáze resetovány"
+
+msgid "no cscope connections\n"
+msgstr "žádné cscope spojení\n"
+
+msgid " # pid database name prepend path\n"
+msgstr " # pid název databáze pøedpona cesty\n"
+
+#, c-format
+msgid "%2d %-5ld %-34s <none>\n"
+msgstr "%2d %-5ld %-34s <žádný>\n"
+
+msgid ""
+"E263: Sorry, this command is disabled, the Python library could not be "
+"loaded."
+msgstr ""
+"E263: Lituji, tento pøíkaz je deaktivován; knihovnu jazyka Python nelze "
+"nahrát."
+
+msgid "can't delete OutputObject attributes"
+msgstr "nelze smazat atributy OutputObject"
+
+msgid "softspace must be an integer"
+msgstr "softspace musí být kladné celé èíslo"
+
+msgid "invalid attribute"
+msgstr "chybný atribut"
+
+msgid "writelines() requires list of strings"
+msgstr "writelines() vyžaduje seznam øetìzcù"
+
+msgid "E264: Python: Error initialising I/O objects"
+msgstr "E264: Python: chyba pøi inicializaci I/O objektù"
+
+msgid "invalid expression"
+msgstr "Chybný výraz"
+
+msgid "expressions disabled at compile time"
+msgstr "podpora výrazù byla vypnuta pøi pøekladu programu"
+
+msgid "attempt to refer to deleted buffer"
+msgstr "pokus o odkaz na smazaný buffer"
+
+msgid "line number out of range"
+msgstr "èíslo øádku mimo rozsah"
+
+#, c-format
+msgid "<buffer object (deleted) at %8lX>"
+msgstr "<buffer objekt (smazán) na %8lX>"
+
+msgid "invalid mark name"
+msgstr "chybné jméno znaèky"
+
+msgid "no such buffer"
+msgstr "žádný takový buffer"
+
+msgid "attempt to refer to deleted window"
+msgstr "pokus o odkaz na smazané okno"
+
+msgid "readonly attribute"
+msgstr "atribut pouze_pro_ètení"
+
+msgid "cursor position outside buffer"
+msgstr "umístìní kurzoru mimo buffer"
+
+#, c-format
+msgid "<window object (deleted) at %.8lX>"
+msgstr "<objekt okna (smazán) na %.8lX>"
+
+#, c-format
+msgid "<window object (unknown) at %.8lX>"
+msgstr "<objekt okna (neznámý) na %.8lX>"
+
+#, c-format
+msgid "<window %d>"
+msgstr "<okno %d>"
+
+msgid "no such window"
+msgstr "žádné takové okno"
+
+msgid "cannot save undo information"
+msgstr "nelze uložit informace pro pøíkaz undo"
+
+msgid "cannot delete line"
+msgstr "nelze smazat øádek"
+
+msgid "cannot replace line"
+msgstr "nelze nahradit øádek"
+
+msgid "cannot insert line"
+msgstr "nelze vložit øádek"
+
+msgid "string cannot contain newlines"
+msgstr "øetìzec nesmí obsahovat znaky nového øádku"
+
+msgid ""
+"E266: Sorry, this command is disabled, the Ruby library could not be loaded."
+msgstr ""
+"E266: Lituji, ale tento pøíkaz je deaktivován; knihovnu jazyka Ruby nelze "
+"nahrát."
+
+#, c-format
+msgid "E273: unknown longjmp status %d"
+msgstr "E273: neznámý longjmp stav %d"
+
+msgid "Toggle implementation/definition"
+msgstr "Prohození implementace/definice"
+
+msgid "Show base class of"
+msgstr "Zobrazení base class z"
+
+msgid "Show overridden member function"
+msgstr "Zobrazení overridden member funkce"
+
+msgid "Retrieve from file"
+msgstr "Znovuzískáno ze souboru"
+
+msgid "Retrieve from project"
+msgstr "Znovuzískáno z projektu"
+
+msgid "Retrieve from all projects"
+msgstr "Znovzískáno ze všech projektù"
+
+msgid "Retrieve"
+msgstr "Znovuzískáno"
+
+msgid "Show source of"
+msgstr "Zobrazení zdroje"
+
+msgid "Find symbol"
+msgstr "Najít symbol"
+
+msgid "Browse class"
+msgstr "Prohlížet class"
+
+msgid "Show class in hierarchy"
+msgstr "Zobrazení class v hierarchii"
+
+msgid "Show class in restricted hierarchy"
+msgstr "Zobrazení class v restricted hierarchii"
+
+msgid "Xref refers to"
+msgstr "Xref odkazuje na"
+
+msgid "Xref referred by"
+msgstr "Xref odkazoval na"
+
+msgid "Xref has a"
+msgstr "Xref má"
+
+msgid "Xref used by"
+msgstr "Xref použit"
+
+msgid "Show docu of"
+msgstr "Zobrazení documentace"
+
+msgid "Generate docu for"
+msgstr "Generována dokumentace pro"
+
+msgid ""
+"Cannot connect to SNiFF+. Check environment (sniffemacs must be found in "
+"$PATH).\n"
+msgstr ""
+"Nelze se pøipojit k SNiFF+. Zkontrolujte promìnné (sniffemacs musí "
+"být)uvedena v $PATH.\n"
+
+msgid "E274: Sniff: Error during read. Disconnected"
+msgstr "E274: Sniff: Chyba pøi ètení. Odpojeno"
+
+msgid "SNiFF+ is currently "
+msgstr "SNiFF+ je právì "
+
+msgid "not "
+msgstr "ne "
+
+msgid "connected"
+msgstr "pøipojen"
+
+#, c-format
+msgid "E275: Unknown SNiFF+ request: %s"
+msgstr "E275: Neznámý požadavek SNiFF+: %s"
+
+msgid "E276: Error connecting to SNiFF+"
+msgstr "E276: Chybné pøipojení k SNiFF+"
+
+msgid "E278: SNiFF+ not connected"
+msgstr "E278: SNiFF+ nepøipojen"
+
+msgid "E279: Not a SNiFF+ buffer"
+msgstr "E279: Není SNiFF+ buffer"
+
+msgid "Sniff: Error during write. Disconnected"
+msgstr "Sniff: Chyba pøi zápisu. Odpojeno."
+
+msgid "invalid buffer number"
+msgstr "chybný název bufferu"
+
+msgid "not implemented yet"
+msgstr "není ještì podporováno"
+
+msgid "unknown option"
+msgstr "neznámá volba"
+
+#. ???
+msgid "cannot set line(s)"
+msgstr "nelze nastavit øádky"
+
+msgid "mark not set"
+msgstr "znaèka není nastavena"
+
+#, c-format
+msgid "row %d column %d"
+msgstr "øádek %d sloupec %d"
+
+msgid "cannot insert/append line"
+msgstr "nelze vložit/pøipojit øádek"
+
+msgid "unknown flag: "
+msgstr "neznámý pøíznak: "
+
+msgid "unknown vimOption"
+msgstr "neznámá vimOption"
+
+msgid "keyboard interrupt"
+msgstr "pøerušení z klávesnice"
+
+msgid "vim error"
+msgstr "chyba vim"
+
+msgid "cannot create buffer/window command: object is being deleted"
+msgstr "nelze vytvoøit pøíkaz bufferu/okna: objekt smazán"
+
+msgid ""
+"cannot register callback command: buffer/window is already being deleted"
+msgstr ""
+"nelze zaregistrovat pøíkaz zpìtného volání: buffer/okno již bylo smazáno"
+
+#. This should never happen. Famous last word?
+msgid ""
+"E280: TCL FATAL ERROR: reflist corrupt!? Please report this to "
+"vim-dev@vim.org"
+msgstr ""
+"E280: TCL FATAL ERROR: reflist poškozen!? Oznamte, prosím, tuto chybu na "
+"vim-dev@vim.org"
+
+msgid "cannot register callback command: buffer/window reference not found"
+msgstr ""
+"nelze zaregistrovat pøíkaz zpìtného volání: odkaz na buffer/okno nenalezen"
+
+msgid "Sorry, this command is disabled: the Tcl library could not be loaded."
+msgstr ""
+"Lituji, ale tento pøíkaz je deaktivován; knihovnu jazyka Tcl nelze nahrát."
+
+msgid ""
+"E281: TCL ERROR: exit code is not int!? Please report this to vim-dev@vim.org"
+msgstr ""
+"E281: TCL CHYBA: návratový kód není celé èíslo!? Oznamte, prosím, tuto chybu "
+"na vim-dev@vim.org"
+
+msgid "cannot get line"
+msgstr "nelze pøeèíst øádek"
+
+msgid "Unable to register a command server name"
+msgstr "Není možné zaznamenat jméno command serveru"
+
+#, c-format
+msgid "E247: no registered server named \"%s\""
+msgstr "E247: Neexistuje registrovaný server jménem \"%s\""
+
+msgid "E248: Failed to send command to the destination program"
+msgstr "E248: Selhalo zaslání pøíkazu urèenému programu"
+
+#, c-format
+msgid "Invalid server id used: %s"
+msgstr "Použit chybný id serveru: %s"
+
+msgid "E249: couldn't read VIM instance registry property"
+msgstr "E249: nelze èíst VIM instanci registry property"
+
+msgid "E251: VIM instance registry property is badly formed. Deleted!"
+msgstr ""
+"E251: VIM instance registry property byla špatnì vytvoøenaa byla smazána!"
+
+msgid "Unknown option"
+msgstr "Neznámá volba"
+
+msgid "Too many edit arguments"
+msgstr "Pøíliš mnoho edit argumentù"
+
+msgid "Argument missing after"
+msgstr "Chybí argument po"
+
+msgid "Garbage after option"
+msgstr "Chyby za volbou"
+
+msgid "Too many \"+command\" or \"-c command\" arguments"
+msgstr "Pøíliš mnoho \"+pøíkaz\" èi \"-c pøíkaz\" argumentù"
+
+msgid "Invalid argument for"
+msgstr "Chybný argument pro"
+
+msgid "This Vim was not compiled with the diff feature."
+msgstr "VIM nebyl pøeložen s volbou +diff"
+
+msgid "Attempt to open script file again: \""
+msgstr "Pokus o opìtovné otevøení skriptu: \""
+
+msgid "\"\n"
+msgstr "\"\n"
+
+msgid "Cannot open for reading: \""
+msgstr "Nelze otevøít pro zápis: \""
+
+msgid "Cannot open for script output: \""
+msgstr "Nelze otevøít pro výstup skriptu: \""
+
+#, c-format
+msgid "%d files to edit\n"
+msgstr "poèet souborù pro editaci: %d\n"
+
+msgid "Vim: Warning: Output is not to a terminal\n"
+msgstr "Vim: Varování: výstup nesmìøuje na terminál\n"
+
+msgid "Vim: Warning: Input is not from a terminal\n"
+msgstr "Vim: Varování: vstup nepochází z terminálu\n"
+
+#. just in case..
+msgid "pre-vimrc command line"
+msgstr "pre-vimrc pøíkazový øádek"
+
+#, c-format
+msgid "E282: Cannot read from \"%s\""
+msgstr "E282: Nelze èíst z \"%s\""
+
+msgid ""
+"\n"
+"More info with: \"vim -h\"\n"
+msgstr ""
+"\n"
+"Podrobnìjší informace získáte pomocí \"vim -h\"\n"
+
+msgid "[file ..] edit specified file(s)"
+msgstr "[SOUBOR] .. editovat SOUBOR(y)"
+
+msgid "- read text from stdin"
+msgstr "- èíst text ze standardního vstupu"
+
+msgid "-t tag edit file where tag is defined"
+msgstr "-t TAG editovat soubor na místì definice TAGU"
+
+msgid "-q [errorfile] edit file with first error"
+msgstr "-q [chybový soubor] editovat soubor na místì výskytu první chyby"
+
+msgid ""
+"\n"
+"\n"
+"usage:"
+msgstr ""
+"\n"
+"\n"
+"použití:"
+
+msgid " vim [arguments] "
+msgstr "vim [pøepínaèe] "
+
+msgid ""
+"\n"
+" or:"
+msgstr ""
+"\n"
+" nebo"
+
+msgid ""
+"\n"
+"\n"
+"Arguments:\n"
+msgstr ""
+"\n"
+"\n"
+"Argumenty:\n"
+
+msgid "--\t\t\tOnly file names after this"
+msgstr "--\t\t\tMohou následovat pouze názvy souborù"
+
+msgid "-register\t\tRegister this gvim for OLE"
+msgstr "-register\t\tpøihlásit gvim na OLE"
+
+msgid "-unregister\t\tUnregister gvim for OLE"
+msgstr "-register\t\todhlásit gvim z OLE"
+
+msgid "-g\t\t\tRun using GUI (like \"gvim\")"
+msgstr "-g\t\t\tspustit v GUI režimu (stejné jako \"gvim\")"
+
+msgid "-f\t\t\tForeground: Don't fork when starting GUI"
+msgstr "-f\t\t\tPopøedí: pøi startu GUI se neoddìlí od shellu"
+
+msgid "-v\t\t\tVi mode (like \"vi\")"
+msgstr "-v\t\t\tVi mód (stejné jako \"vi\")"
+
+msgid "-e\t\t\tEx mode (like \"ex\")"
+msgstr "-v\t\t\tEx mód (stejné jako \"ex\")"
+
+msgid "-s\t\t\tSilent (batch) mode (only for \"ex\")"
+msgstr "-s\t\t\tTichý (dávkový) režim (pouze pro \"ex\")"
+
+msgid "-d\t\t\tDiff mode (like \"vimdiff\")"
+msgstr "-d\t\t\tDiff režim (stejné jako \"vimdiff\")"
+
+msgid "-y\t\t\tEasy mode (like \"evim\", modeless)"
+msgstr "-v\t\t\tSnadný režim (stejné jako \"evim\", žádné módy )"
+
+msgid "-R\t\t\tReadonly mode (like \"view\")"
+msgstr "-R\t\t\tRežim pouze_pro_ètení (jako \"view\")"
+
+msgid "-Z\t\t\tRestricted mode (like \"rvim\")"
+msgstr "-Z\t\t\tOmezený režim (stejné jako \"rvim\")"
+
+msgid "-m\t\t\tModifications (writing files) not allowed"
+msgstr "-m\t\t\tZmìny (ukládání souborù) zakázány"
+
+msgid "-M\t\t\tModifications in text not allowed"
+msgstr "-M\t\t\tZmìny (ukládání souborù) zakázány"
+
+msgid "-b\t\t\tBinary mode"
+msgstr "-b\t\t\tBinární režim"
+
+msgid "-l\t\t\tLisp mode"
+msgstr "-l\t\t\tLisp režim"
+
+msgid "-C\t\t\tCompatible with Vi: 'compatible'"
+msgstr "-C\t\t\tKompatabilní s Vi: 'compatible'"
+
+msgid "-N\t\t\tNot fully Vi compatible: 'nocompatible'"
+msgstr "-N\t\t\tKompatibilita s Vi vypnuta: 'nocompatible'"
+
+msgid "-V[N]\t\tVerbose level"
+msgstr "-V[N]\t\tÚroveò výpisu hlášek"
+
+msgid "-D\t\t\tDebugging mode"
+msgstr "-D\t\t\tLadící režim"
+
+msgid "-n\t\t\tNo swap file, use memory only"
+msgstr "-n\t\t\tNebude vytváøet odkládací soubor, bude používat pouze pamì"
+
+msgid "-r\t\t\tList swap files and exit"
+msgstr "-r\t\t\tVypíše seznam odkládacích souborù a skonèí"
+
+msgid "-r (with file name)\tRecover crashed session"
+msgstr "-r název souboru\tObnoví pøerušené sezení"
+
+msgid "-L\t\t\tSame as -r"
+msgstr "-L\t\t\tStejné jako -r"
+
+msgid "-f\t\t\tDon't use newcli to open window"
+msgstr "-f\t\t\tNebude používat newcli pro otevøení okna"
+
+msgid "-dev <device>\t\tUse <device> for I/O"
+msgstr "-dev <zaøízení>\t\tPoužít <zaøízení> pro I/O"
+
+msgid "-H\t\t\tstart in Hebrew mode"
+msgstr "-H\t\t\tnastartuje v hebrejském režimu"
+
+msgid "-F\t\t\tstart in Farsi mode"
+msgstr "-F\t\t\tnastartuje ve Farsi režimu"
+
+msgid "-T <terminal>\tSet terminal type to <terminal>"
+msgstr "-T <terminál>\tNastaví typ terminálu na <terminál>"
+
+msgid "-u <vimrc>\t\tUse <vimrc> instead of any .vimrc"
+msgstr "-u <vimrc>\t\tPoužije <vimrc> místo jakéhokoliv .vimrc"
+
+msgid "-U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc"
+msgstr "-U <gvimrc>\t\tPoužije <gvimrc> místo jakéhokoliv .gvimrc"
+
+msgid "--noplugin\t\tDon't load plugin scripts"
+msgstr "--noplugin\t\tNenahraje 'plugin' skripty"
+
+msgid "-o[N]\t\tOpen N windows (default: one for each file)"
+msgstr "-o[N]\t\tOtevøe N oken (implicitnì jedno pro každý soubor)"
+
+msgid "-O[N]\t\tlike -o but split vertically"
+msgstr "-O[N]\t\tJako -o but split vertically"
+
+msgid "+\t\t\tStart at end of file"
+msgstr "+\t\t\tNastaví kurzor na konec souboru"
+
+msgid "+<lnum>\t\tStart at line <lnum>"
+msgstr "+<øádek>\t\tNastaví kurzor na <øádek>"
+
+msgid "--cmd <command>\tExecute <command> before loading any vimrc file"
+msgstr "--cmd <pøíkaz>\tPo nahrání prvního souboru vykoná <pøíkaz>"
+
+msgid "-c <command>\t\tExecute <command> after loading the first file"
+msgstr "-c <pøíkaz>\t\tPo nahrání prvního souboru vykoná <pøíkaz>"
+
+msgid "-S <session>\t\tSource file <session> after loading the first file"
+msgstr ""
+"-S <sezení>\t\tPo nahrání prvního souboru vykoná pøíkazy v souboru <sezení>"
+
+msgid "-s <scriptin>\tRead Normal mode commands from file <scriptin>"
+msgstr "-s <skript>\t\tNaète pøíkazy normálního módu ze <skriptu>"
+
+msgid "-w <scriptout>\tAppend all typed commands to file <scriptout>"
+msgstr "-w <skript>\t\tPøipojí všechny napsané pøíkazy do souboru <skript>"
+
+msgid "-W <scriptout>\tWrite all typed commands to file <scriptout>"
+msgstr "-W <skript>\t\tUloží všechny napsané pøíkazy do souboru <skript>"
+
+msgid "-x\t\t\tEdit encrypted files"
+msgstr "-x\t\t\tEditace zašifrovaných souborù"
+
+msgid "-display <display>\tConnect vim to this particular X-server"
+msgstr "-display <display>\tSpustí vim na daný X-server"
+
+msgid "-X\t\t\tDo not connect to X server"
+msgstr "-X\t\t\tNepøipojí se k X serveru"
+
+msgid "--socketid <xid>\tOpen Vim inside another GTK widget"
+msgstr "--socketid <xid>\tOtevøe Vim uvnitø jiného GTK widgetu"
+
+msgid "--remote <files>\tEdit <files> in a Vim server and exit"
+msgstr "--remote <soubory>\tEdituje <soubory> na Vim serveru a skonèí"
+
+msgid ""
+"--remote-wait <files> As --remote but wait for files to have been edited"
+msgstr ""
+"--remote-wait <soubory> Jako --remote, ale èeká na soubory k editaci"
+
+msgid "--remote-send <keys>\tSend <keys> to a Vim server and exit"
+msgstr "--remote-send <klávesy>\tPøedá <klávesy> Vim serveru a skonèí"
+
+msgid "--remote-expr <expr>\tEvaluate <expr> in a Vim server and print result"
+msgstr "--remote-expr <výraz>\tProvede <výraz> na serveru a zobrazí výsledek"
+
+msgid "--serverlist\t\tList available Vim server names and exit"
+msgstr "--serverlist\t\tVypíše seznam dostupných Vim serverù a skonèí"
+
+msgid "--servername <name>\tSend to/become the Vim server <name>"
+msgstr ""
+"--servername <jméno>\tZašle serveru <jméno>/stane se Vim serverem <jméno>"
+
+msgid "-i <viminfo>\t\tUse <viminfo> instead of .viminfo"
+msgstr "-i <viminfo>\t\tPoužije <viminfo> místo jakéhokoliv .viminfo"
+
+msgid "-h\t\t\tprint Help (this message) and exit"
+msgstr "-h\t\t\tVypíše tuto nápovìdu a skonèí"
+
+msgid "--version\t\tprint version information and exit"
+msgstr "--version\t\tvypíše informace o verzi a skonèí"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (Motif version):\n"
+msgstr ""
+"\n"
+"Pøepínaèe pro gvim (Motif verzi):\n"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (Athena version):\n"
+msgstr ""
+"\n"
+"Pøepínaèe pro gvim (Athena verzi):\n"
+
+msgid "-display <display>\tRun vim on <display>"
+msgstr "-display <display>\tSpustí vim na <display>"
+
+msgid "-iconic\t\tStart vim iconified"
+msgstr "-iconic\t\tSpustí vim minimalizované"
+
+msgid "-name <name>\t\tUse resource as if vim was <name>"
+msgstr "-name <název>\t\tPoužije resource jako by vim mìl <název>"
+
+msgid "\t\t\t (Unimplemented)\n"
+msgstr "\t\t\t (není implementováno)\n"
+
+msgid "-background <color>\tUse <color> for the background (also: -bg)"
+msgstr "-background <barva>\tNastaví <barvu> pozadí (také -bg)"
+
+msgid "-foreground <color>\tUse <color> for normal text (also: -fg)"
+msgstr "-foreground <barva>\tNastaví <barvu> popøedí (také -fg)"
+
+msgid "-font <font>\t\tUse <font> for normal text (also: -fn)"
+msgstr "-font <písmo>\t\tNastaví <písmo> normálního textu (také -fn)"
+
+msgid "-boldfont <font>\tUse <font> for bold text"
+msgstr "-boldfont <písmo>\tNastaví <písmo> pro zvýraznìný text"
+
+msgid "-italicfont <font>\tUse <font> for italic text"
+msgstr "-italicfont <písmo>\tNastaví <písmo> pro kurzívu"
+
+msgid "-geometry <geom>\tUse <geom> for initial geometry (also: -geom)"
+msgstr "-geometry <geometrie>\tNastaví <geometrii> (také -geom)"
+
+msgid "-borderwidth <width>\tUse a border width of <width> (also: -bw)"
+msgstr "-borderwidth <šíøka>\tNastaví <šíøku> okrajù (také -bw)"
+
+msgid "-scrollbarwidth <width> Use a scrollbar width of <width> (also: -sw)"
+msgstr "-scrollbarwidth <šíøku> Nastaví <šíøku> posunovací lišty (také: -sw)"
+
+msgid "-menuheight <height>\tUse a menu bar height of <height> (also: -mh)"
+msgstr "-menuheight <výška>\tNastaví <výšku> nabídky (také -mh)"
+
+msgid "-reverse\t\tUse reverse video (also: -rv)"
+msgstr "-reverse\t\tPoužije reverzní barvy (také -rv)"
+
+msgid "+reverse\t\tDon't use reverse video (also: +rv)"
+msgstr "+reverse\t\tNepoužije reverzní barvy (také +rv)"
+
+msgid "-xrm <resource>\tSet the specified resource"
+msgstr "-xrm <resource>\tNastaví zadaný <resource>"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (RISC OS version):\n"
+msgstr ""
+"\n"
+"Pøepínaèe pro gvim (RISC OS verzi):\n"
+
+msgid "--columns <number>\tInitial width of window in columns"
+msgstr "--columns <poèet>\t<poèet> sloupcù na okno"
+
+msgid "--rows <number>\tInitial height of window in rows"
+msgstr "--rows <poèet>\t<poèet> øádkù na okno"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (GTK+ version):\n"
+msgstr ""
+"\n"
+"Pøepínaèe pro gvim (GTK+ verzi):\n"
+
+msgid "-display <display>\tRun vim on <display> (also: --display)"
+msgstr "-display <display>\tSpustí vim na <display> (také --display)"
+
+msgid "--help\t\tShow Gnome arguments"
+msgstr "--help\t\tVypíše Gnome pøepínaèe"
+
+#. Failed to send, abort.
+msgid ""
+"\n"
+"Send failed.\n"
+msgstr ""
+"\n"
+"Pøedání výrazu selhalo.\n"
+
+#. Let vim start normally.
+msgid ""
+"\n"
+"Send failed. Trying to execute locally\n"
+msgstr ""
+"\n"
+"Pøedání selhalo. Zkouším provést lokálnì\n"
+
+#, c-format
+msgid "%d of %d edited"
+msgstr "%d z %d editováno"
+
+msgid "Send expression failed.\n"
+msgstr "Pøedání výrazu selhalo.\n"
+
+msgid "No marks set"
+msgstr "Nejsou nastaveny žádné znaèky"
+
+#, c-format
+msgid "E283: No marks matching \"%s\""
+msgstr "E283: \"%s\" nevyhovují žádné znaèky"
+
+#. Highlight title
+msgid ""
+"\n"
+"mark line col file/text"
+msgstr ""
+"\n"
+"znaèka øádek sloupec soubor/text"
+
+#. Highlight title
+msgid ""
+"\n"
+" jump line col file/text"
+msgstr ""
+"\n"
+" skok øádek sloupec soubor/text"
+
+msgid ""
+"\n"
+"# File marks:\n"
+msgstr ""
+"\n"
+"# Souborové znaèky:\n"
+
+#. Write the jumplist with -'
+msgid ""
+"\n"
+"# Jumplist (newest first):\n"
+msgstr ""
+"\n"
+"# Seznam skokù (poèínaje nejnovìjší položkou):\n"
+
+msgid ""
+"\n"
+"# History of marks within files (newest to oldest):\n"
+msgstr ""
+"\n"
+"# Historie znaèek v souborech (poèínaje nejnovìjší položkou):\n"
+
+msgid "Missing '>'"
+msgstr "Chybí '>'"
+
+msgid "Not a valid codepage"
+msgstr "Chybná kódová stránka"
+
+msgid "E284: Cannot set IC values"
+msgstr "E284: Nelze nastavit IC hodnoty"
+
+msgid "E285: Failed to create input context"
+msgstr "E285: Nepodaøilo se vytvoøit vstupní kontext"
+
+msgid "E286: Failed to open input method"
+msgstr "E286: Nepodaøilo se otevøít vstupní metodu"
+
+msgid "E287: Warning: Could not set destroy callback to IM"
+msgstr "E287: Varování: likvidaèní zpìtné volání nelze nastavit na IM"
+
+msgid "E288: input method doesn't support any style"
+msgstr "E288: vstupní metoda nepodporuje žádný styl"
+
+msgid "E289: input method doesn't support my preedit type"
+msgstr "E289: vstupní metoda nepodporuje mùj 'preedit' typ"
+
+msgid "E290: over-the-spot style requires fontset"
+msgstr "E290: Nadbodový styl vyžaduje fontset"
+
+msgid "E291: Your GTK+ is older than 1.2.3. Status area disabled"
+msgstr "E291: Máte GTK+ verze starší než 1.2.3. Stavová plocha vypnuta."
+
+msgid "E292: Input Method Server is not running"
+msgstr "E292: Server vstupních metod nebìží"
+
+msgid "E293: block was not locked"
+msgstr "E293: blok nebyl zamknut"
+
+msgid "E294: Seek error in swap file read"
+msgstr "E294: Chyba posunu ukazovátka pøi ètení odkládacího souboru"
+
+msgid "E295: Read error in swap file"
+msgstr "E295: Chyba pøi ètení odkládacího souboru"
+
+msgid "E296: Seek error in swap file write"
+msgstr "E296: Chyba posunu ukazovátka pøi ukládání do odkládacího souboru"
+
+msgid "E297: Write error in swap file"
+msgstr "E297: Chyba pøi ukládání do odkládacího souboru"
+
+msgid "E300: Swap file already exists (symlink attack?)"
+msgstr ""
+"E300: Odkládací soubor již existuje! (Nìkdo hackujepøes nastražený symlink?)"
+
+msgid "E298: Didn't get block nr 0?"
+msgstr "E298: Nelze získat blok 0?"
+
+msgid "E298: Didn't get block nr 1?"
+msgstr "E298: Nelze získat blok 1?"
+
+msgid "E298: Didn't get block nr 2?"
+msgstr "E298: nelze získat blok 2?"
+
+#. could not (re)open the swap file, what can we do????
+msgid "E301: Oops, lost the swap file!!!"
+msgstr "E301: Jéje, odkládací soubor byl ztracen!!!"
+
+msgid "E302: Could not rename swap file"
+msgstr "E302: Nelze pøejmenovat odkládací soubor"
+
+#, c-format
+msgid "E303: Unable to open swap file for \"%s\", recovery impossible"
+msgstr "E303: Nelze otevøít odkládací soubor pro \"%s\""
+
+msgid "E304: ml_timestamp: Didn't get block 0??"
+msgstr "E304: ml_timestamp: nelze získat blok 0??"
+
+#, c-format
+msgid "E305: No swap file found for %s"
+msgstr "E305: Odkládací soubor pro %s nebyl nalezen"
+
+msgid "Enter number of swap file to use (0 to quit): "
+msgstr ""
+"Zadejte èíslo odkládacího souboru, který se má použít (0 pro ukonèení): "
+
+#, c-format
+msgid "E306: Cannot open %s"
+msgstr "E306: Nelze otevøít %s"
+
+msgid "Unable to read block 0 from "
+msgstr "Nelze èíst blok 0 z "
+
+msgid ""
+"\n"
+"Maybe no changes were made or Vim did not update the swap file."
+msgstr ""
+"\n"
+"Možná nedošlo k žádným zmìnám, nebo Vim neaktualizoval odkládací soubor."
+
+msgid " cannot be used with this version of Vim.\n"
+msgstr " nelze použít s touto verzí Vim.\n"
+
+msgid "Use Vim version 3.0.\n"
+msgstr "Použijte Vim verze 3.0.\n"
+
+#, c-format
+msgid "E307: %s does not look like a Vim swap file"
+msgstr "E307: %s se nezdá být odkládacím souborem Vim"
+
+msgid " cannot be used on this computer.\n"
+msgstr " nelze použít na tomto poèítaèi.\n"
+
+msgid "The file was created on "
+msgstr "Soubor byl vytvoøen "
+
+msgid ""
+",\n"
+"or the file has been damaged."
+msgstr ""
+",\n"
+"nebo byl soubor poškozen."
+
+#, c-format
+msgid "Using swap file \"%s\""
+msgstr "Používám odkládací soubor \"%s\""
+
+#, c-format
+msgid "Original file \"%s\""
+msgstr "Pùvodní soubor \"%s\""
+
+msgid "E308: Warning: Original file may have been changed"
+msgstr "E308: Varování: Pùvodní soubor mohl být zmìnìn"
+
+#, c-format
+msgid "E309: Unable to read block 1 from %s"
+msgstr "E309: Nelze èíst blok 1 z %s"
+
+msgid "???MANY LINES MISSING"
+msgstr "???CHYBÍ MNOHO ØÁDKÙ"
+
+msgid "???LINE COUNT WRONG"
+msgstr "???CHYBNÝ POÈET ØÁDKÙ"
+
+msgid "???EMPTY BLOCK"
+msgstr "???PRÁZDNÝ BLOK"
+
+msgid "???LINES MISSING"
+msgstr "???CHYBÌJÍCÍ ØÁDKY"
+
+#, c-format
+msgid "E310: Block 1 ID wrong (%s not a .swp file?)"
+msgstr "E310: ID bloku 1 je chybné (je %s odkládacím souborem?)"
+
+msgid "???BLOCK MISSING"
+msgstr "???CHYBÍ BLOK"
+
+msgid "??? from here until ???END lines may be messed up"
+msgstr "od ??? po ???END mohou být øádky pomíchané"
+
+msgid "??? from here until ???END lines may have been inserted/deleted"
+msgstr "od ??? po ???END mohou být vložené/smazané øádky"
+
+msgid "???END"
+msgstr "???KONEC"
+
+msgid "E311: Recovery Interrupted"
+msgstr "E311: Obnova pøerušena"
+
+msgid ""
+"E312: Errors detected while recovering; look for lines starting with ???"
+msgstr ""
+"E312: V prùbìhu obnovy došlo k chybám; zkontrolujte øádky zaèínající na ???"
+
+msgid "Recovery completed. You should check if everything is OK."
+msgstr "Obnova dokonèena. Zkontrolujte, zda je vše v poøádku."
+
+msgid ""
+"\n"
+"(You might want to write out this file under another name\n"
+msgstr ""
+"\n"
+"(Zvažte uložení tohoto souboru pod jiným názvem\n"
+
+msgid "and run diff with the original file to check for changes)\n"
+msgstr "a kontrolu zmìn pomocí programu diff.)\n"
+
+msgid ""
+"Delete the .swp file afterwards.\n"
+"\n"
+msgstr "Poté smažte odkládací soubor.\n"
+
+#. use msg() to start the scrolling properly
+msgid "Swap files found:"
+msgstr "Nalezené odkládací soubory:"
+
+msgid " In current directory:\n"
+msgstr " V aktuálním adresáøi:\n"
+
+msgid " Using specified name:\n"
+msgstr " Se zadaným názvem:\n"
+
+msgid " In directory "
+msgstr " V adresáøi "
+
+msgid " -- none --\n"
+msgstr " -- žádné --\n"
+
+msgid " owned by: "
+msgstr " vlastník: "
+
+msgid " dated: "
+msgstr " datum vytvoøení: "
+
+msgid " dated: "
+msgstr " datum vytvoøení: "
+
+msgid " [from Vim version 3.0]"
+msgstr " [od Vim verze 3.0]"
+
+msgid " [does not look like a Vim swap file]"
+msgstr " [nevypadá jako odkládací soubor Vim]"
+
+msgid " file name: "
+msgstr " název souboru: "
+
+msgid ""
+"\n"
+" modified: "
+msgstr ""
+"\n"
+" datum zmìny: "
+
+msgid "YES"
+msgstr "ANO"
+
+msgid "no"
+msgstr "ne"
+
+msgid ""
+"\n"
+" user name: "
+msgstr ""
+"\n"
+" uživatelské jméno: "
+
+msgid " host name: "
+msgstr " název poèítaèe: "
+
+msgid ""
+"\n"
+" host name: "
+msgstr ""
+"\n"
+" název poèítaèe: "
+
+msgid ""
+"\n"
+" process ID: "
+msgstr ""
+"\n"
+" ID procesu : "
+
+msgid " (still running)"
+msgstr " (stále aktivní)"
+
+msgid ""
+"\n"
+" [not usable with this version of Vim]"
+msgstr ""
+"\n"
+" [nepoužitelné s touto verzí Vim]"
+
+msgid ""
+"\n"
+" [not usable on this computer]"
+msgstr ""
+"\n"
+" [nepoužitelné na tomto poèítaèi]"
+
+msgid " [cannot be read]"
+msgstr " [nelze pøeèíst]"
+
+msgid " [cannot be opened]"
+msgstr " [nelze otevøít]"
+
+msgid "E313: Cannot preserve, there is no swap file"
+msgstr "E313: Nelze zachovat - odkládací soubor neexistuje."
+
+msgid "File preserved"
+msgstr "Soubor zachován"
+
+msgid "E314: Preserve failed"
+msgstr "E314: Uchování se nezdaøilo"
+
+#, c-format
+msgid "E315: ml_get: invalid lnum: %ld"
+msgstr "E315: ml_get: chybné èíslo øádku: %ld"
+
+#, c-format
+msgid "E316: ml_get: cannot find line %ld"
+msgstr "E316: ml_get: nelze nalézt øádek %ld"
+
+msgid "E317: pointer block id wrong 3"
+msgstr "E317: chybné id ukazatele na blok 3"
+
+msgid "stack_idx should be 0"
+msgstr "stack_idx by mìlo mít hodnotu 3"
+
+msgid "E318: Updated too many blocks?"
+msgstr "E318: Aktualizováno pøíliš mnoho blokù?"
+
+msgid "E317: pointer block id wrong 4"
+msgstr "E317: chybné id ukazatele na blok 4"
+
+msgid "deleted block 1?"
+msgstr "smazán blok 1?"
+
+#, c-format
+msgid "E320: Cannot find line %ld"
+msgstr "E320: Nelze nalézt øádek %ld"
+
+msgid "E317: pointer block id wrong"
+msgstr "E317: chybné id ukazatele na blok"
+
+msgid "pe_line_count is zero"
+msgstr "pe_line_count má nulovou hodnotu"
+
+#, c-format
+msgid "E322: line number out of range: %ld past the end"
+msgstr "E322: poèet øádkù mimo rozsah: %ld > celkový poèet øádkù"
+
+#, c-format
+msgid "E323: line count wrong in block %ld"
+msgstr "E323: chybný poèet øádkù v bloku %ld"
+
+msgid "Stack size increases"
+msgstr "Nárùst velikosti zásobníku"
+
+msgid "E317: pointer block id wrong 2"
+msgstr "E317: chybné id ukazatele na blok 2"
+
+msgid "E325: ATTENTION"
+msgstr "E325: POZOR"
+
+msgid ""
+"\n"
+"Found a swap file by the name \""
+msgstr ""
+"\n"
+"Nalezen odkládací soubor se jménem \""
+
+msgid "While opening file \""
+msgstr "Pøi otevírání souboru\""
+
+msgid " NEWER than swap file!\n"
+msgstr " NOVÌJŠÍ než odkládací soubor!\n"
+
+#. Some of these messages are long to allow translation to
+#. * other languages.
+msgid ""
+"\n"
+"(1) Another program may be editing the same file.\n"
+" If this is the case, be careful not to end up with two\n"
+" different instances of the same file when making changes.\n"
+msgstr ""
+"\n"
+"(1) Soubor mùže být editován jiným programem.\n"
+" Je-li tomu tak, pak si dejte pozor, aby jste po uložení zmìn\n"
+" nemìli dvì rùzné verze téhož souboru.\n"
+
+msgid " Quit, or continue with caution.\n"
+msgstr " Ukonèete program, nebo opatrnì pokraèujte v editaci.\n"
+
+msgid ""
+"\n"
+"(2) An edit session for this file crashed.\n"
+msgstr ""
+"\n"
+"(2) Editace tohoto souboru byla pøerušena neèekaným ukonèením programu.\n"
+
+msgid " If this is the case, use \":recover\" or \"vim -r "
+msgstr " Je-li tomu tak, pak použijte \":recover\" èi \"vim -r "
+
+msgid ""
+"\"\n"
+" to recover the changes (see \":help recovery\").\n"
+msgstr ""
+"\"\n"
+" pro odstranìní zmìn (viz \":help recovery)\".\n"
+
+msgid " If you did this already, delete the swap file \""
+msgstr " Pokud jste tak již uèinil, tak smažte odkládací soubor \""
+
+msgid ""
+"\"\n"
+" to avoid this message.\n"
+msgstr ""
+"\"\n"
+" a tato zpráva se již nebude objevovat.\n"
+
+msgid "Swap file \""
+msgstr "Odkládací soubor \""
+
+msgid "\" already exists!"
+msgstr "\" již existuje!"
+
+msgid "VIM - ATTENTION"
+msgstr "VIM - POZOR"
+
+msgid "Swap file already exists!"
+msgstr "Odkládací soubor již existuje!"
+
+msgid ""
+"&Open Read-Only\n"
+"&Edit anyway\n"
+"&Recover\n"
+"&Quit"
+msgstr ""
+"&Otevøít pouze pro ètení\n"
+"&Pokraèovat v editaci\n"
+"O&bnovit soubor\n"
+"&Konec"
+
+msgid ""
+"&Open Read-Only\n"
+"&Edit anyway\n"
+"&Recover\n"
+"&Quit\n"
+"&Delete it"
+msgstr ""
+"&Otevøít pouze pro ètení\n"
+"&Pokraèovat v editaci\n"
+"O&bnovit soubor\n"
+"&Konec\n"
+"&Smazat"
+
+msgid "E326: Too many swap files found"
+msgstr "E326: Pøíliš mnoho odkládacích souborù"
+
+msgid "E327: Part of menu-item path is not sub-menu"
+msgstr "E327: Èásti cesty k pøedmìtu nabídky není podnabídkou"
+
+msgid "E328: Menu only exists in another mode"
+msgstr "E328: Nabídka existuje pouze v jiném módu"
+
+msgid "E329: No menu of that name"
+msgstr "E329: Nabídka tohoto jména neexistuje"
+
+msgid "E330: Menu path must not lead to a sub-menu"
+msgstr "E330: Cesta nabídkou nesmí vést do podnabídky"
+
+msgid "E331: Must not add menu items directly to menu bar"
+msgstr "E331: Položky nabídky nelze pøidávat pøímo na lištu"
+
+msgid "E332: Separator cannot be part of a menu path"
+msgstr "E332: Oddìlovaè nesmí být èástí cesty nabídkou"
+
+#. Now we have found the matching menu, and we list the mappings
+#. Highlight title
+msgid ""
+"\n"
+"--- Menus ---"
+msgstr ""
+"\n"
+"--- Nabídky ---"
+
+msgid "Tear off this menu"
+msgstr "Odtrhnout tuto nabídku"
+
+msgid "E333: Menu path must lead to a menu item"
+msgstr "E333: Cesta nabídkou musí vést k položce nabídky"
+
+#, c-format
+msgid "E334: Menu not found: %s"
+msgstr "E334: Vzor nenalezen: %s"
+
+#, c-format
+msgid "E335: Menu not defined for %s mode"
+msgstr "E335: V %s módu není nabídka definována"
+
+msgid "E336: Menu path must lead to a sub-menu"
+msgstr "E336: Cesta nabídkou musí vést do podnabídky"
+
+msgid "E337: Menu not found - check menu names"
+msgstr "E337: Nabídka nenalezena - zkontrolujte názvy nabídek"
+
+#, c-format
+msgid "Error detected while processing %s:"
+msgstr "Chyba pøi zpracování %s:"
+
+#, c-format
+msgid "line %4ld:"
+msgstr "øádek %4ld:"
+
+msgid "[string too long]"
+msgstr "[pøíliš dlouhý øetìzec]"
+
+msgid "Messages maintainer: Bram Moolenaar <Bram@vim.org>"
+msgstr "Správce zpráv: Bram Moolenaar <Bram@vim.org>"
+
+msgid "Interrupt: "
+msgstr "Pøerušení: "
+
+msgid "Hit ENTER to continue"
+msgstr "pokraèování stiskem ENTER"
+
+msgid "Hit ENTER or type command to continue"
+msgstr "Pro pokraèování stisknìte ENTER nebo zadejte pøíkaz"
+
+msgid "-- More --"
+msgstr "-- Pokraèování --"
+
+msgid " (RET/BS: line, SPACE/b: page, d/u: half page, q: quit)"
+msgstr " (RET/BS: øádek, MEZERNÍK/b: stránka, d/u: 0.5 stránky, q: konec)"
+
+msgid " (RET: line, SPACE: page, d: half page, q: quit)"
+msgstr " (RET: øádek, MEZERNÍK: stránka, d: 0.5 stránky, q: konec)"
+
+msgid "Question"
+msgstr "Otázka"
+
+msgid ""
+"&Yes\n"
+"&No"
+msgstr ""
+"&Ano\n"
+"&Ne"
+
+msgid ""
+"&Yes\n"
+"&No\n"
+"&Cancel"
+msgstr ""
+"&Ano\n"
+"&Ne\n"
+"&Zrušit"
+
+msgid ""
+"&Yes\n"
+"&No\n"
+"Save &All\n"
+"&Discard All\n"
+"&Cancel"
+msgstr ""
+"&Ano\n"
+"&Ne\n"
+"&Uložit vše\n"
+"Zahodit &vše\n"
+"&Zrušit"
+
+msgid "Save File dialog"
+msgstr "Dialog pro ukládání souborù"
+
+msgid "Open File dialog"
+msgstr "Dialog pro otevírání souborù"
+
+#. TODO: non-GUI file selector here
+msgid "E338: Sorry, no file browser in console mode"
+msgstr "E338: Lituji, ale konzolová verze nepodporuje prohlížeè souborù"
+
+msgid "W10: Warning: Changing a readonly file"
+msgstr "W10: wc1: mìním soubor pouze_pro_ètení"
+
+msgid "1 more line"
+msgstr "poèet nových øádkù: 1"
+
+msgid "1 line less"
+msgstr "poèet smazaných øádkù: 1"
+
+#, c-format
+msgid "%ld more lines"
+msgstr "poèet nových øádkù: %ld"
+
+#, c-format
+msgid "%ld fewer lines"
+msgstr "poèet smazaných øádkù: %ld"
+
+msgid " (Interrupted)"
+msgstr "(Pøerušeno)"
+
+msgid "Vim: preserving files...\n"
+msgstr "Vim: zachovávám soubory...\n"
+
+#. close all memfiles, without deleting
+msgid "Vim: Finished.\n"
+msgstr "Vim: ukonèen\n"
+
+msgid "ERROR: "
+msgstr "CHYBA: "
+
+#, c-format
+msgid ""
+"\n"
+"[bytes] total alloc-freed %lu-%lu, in use %lu, peak use %lu\n"
+msgstr ""
+"\n"
+"[bajtù] celkem uvolnìno-alokováno %lu-%lu, využito %lu, maximální využití "
+"%lu\n"
+
+#, c-format
+msgid ""
+"[calls] total re/malloc()'s %lu, total free()'s %lu\n"
+"\n"
+msgstr ""
+"[volání] celkem re/malloc(): %lu, celkem free() %lu\n"
+"\n"
+
+msgid "E340: Line is becoming too long"
+msgstr "E340: Øádek se stává pøíliš dlouhým"
+
+#, c-format
+msgid "E341: Internal error: lalloc(%ld, )"
+msgstr "E341: Vnitøní chyba: lalloc(%ld, )"
+
+#, c-format
+msgid "E342: Out of memory! (allocating %lu bytes)"
+msgstr "E342: Nedostatek pamìti! (potøebuji alokovat bajtù: %lu)"
+
+#, c-format
+msgid "Calling shell to execute: \"%s\""
+msgstr "Spouštím pøíkaz \"%s\" pomocí shellu"
+
+msgid "Missing colon"
+msgstr "Chybí dvojteèka"
+
+msgid "Illegal mode"
+msgstr "nepøípustný mód"
+
+msgid "Illegal mouseshape"
+msgstr "Chybný tvar myši"
+
+msgid "digit expected"
+msgstr "oèekávána èíslice"
+
+msgid "Illegal percentage"
+msgstr "nepøípustné procento"
+
+msgid "Enter encryption key: "
+msgstr "Zadejte šifrovací klíè: "
+
+msgid "Enter same key again: "
+msgstr "Zadejte ještì jednou tentýž klíè:"
+
+msgid "Keys don't match!"
+msgstr "Klíèe se neshodují"
+
+#, c-format
+msgid ""
+"E343: Invalid path: '**[number]' must be at the end of the path or be "
+"followed by '%s'."
+msgstr ""
+"E343: Chybná cesta: '**[èíslo] musí být buï na konci cesty, nebo musí být\n"
+"následováno'%s. Viz :help path."
+
+#, c-format
+msgid "E344: Can't find directory \"%s\" in cdpath"
+msgstr "E344: Adresáø \"%s\" nelze v cdpath nalézt"
+
+#, c-format
+msgid "E345: Can't find file \"%s\" in path"
+msgstr "E345: Soubor \"%s\" nelze v path nalézt"
+
+#, c-format
+msgid "E346: No more directory \"%s\" found in cdpath"
+msgstr "E346: Žádný další adresáø \"%s\" nebyl v cdpath nalezen"
+
+#, c-format
+msgid "E347: No more file \"%s\" found in path"
+msgstr "E347: Žádný další soubor \"%s\" nebyl v cestì nalezen"
+
+msgid "Illegal component"
+msgstr "nepøípustná souèást"
+
+msgid "Warning: terminal cannot highlight"
+msgstr "Varování: terminál nepodporuje zvýrazòování"
+
+msgid "E348: No string under cursor"
+msgstr "E348: pod kurzorem není žádný øetìzec"
+
+msgid "E349: No identifier under cursor"
+msgstr "E349: pod kurzorem není žádný identifikátor"
+
+msgid "E352: Cannot erase folds with current 'foldmethod'"
+msgstr "E352: pomocí aktuální 'foldmethod' nelze mazat záhyby"
+
+#, c-format
+msgid "1 line %sed 1 time"
+msgstr "poèet øádkù posunutých jednou pomocí %s : 1"
+
+#, c-format
+msgid "1 line %sed %d times"
+msgstr "Poèet øádkù posunutých pomocí %s %d-krát : 1"
+
+#, c-format
+msgid "%ld lines %sed 1 time"
+msgstr "Poèet øádkù: %ld (posunutých jednou pomocí %s)"
+
+#, c-format
+msgid "%ld lines %sed %d times"
+msgstr "Poèet øádkù: %ld (posunutých pomocí %s %d-krát)"
+
+#, c-format
+msgid "%ld lines to indent... "
+msgstr "poèet øádkù k odsazení: %ld"
+
+msgid "1 line indented "
+msgstr "poèet øádkù k odsazení: 1"
+
+#, c-format
+msgid "%ld lines indented "
+msgstr "poèet odsazených øádkù: %ld"
+
+#. must display the prompt
+msgid "cannot yank; delete anyway"
+msgstr "nelze kopírovat; pøesto smazáno"
+
+msgid "1 line changed"
+msgstr "poèet øádek se zmìnìnou velikostí písmen: 1"
+
+#, c-format
+msgid "%ld lines changed"
+msgstr "poèet øádek se zmìnìnou velikostí písmen: %ld"
+
+#, c-format
+msgid "freeing %ld lines"
+msgstr "poèet uvolòovaných øádkù: %ld"
+
+msgid "1 line yanked"
+msgstr "poèet zkopírovaných øádkù: 1"
+
+#, c-format
+msgid "%ld lines yanked"
+msgstr "poèet zkopírovaných øádkù: %ld"
+
+#, c-format
+msgid "E353: Nothing in register %s"
+msgstr "E353: Registr %s je prázdný"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Registers ---"
+msgstr ""
+"\n"
+"--- Registry ---"
+
+msgid "Illegal register name"
+msgstr "nepøípustný název registru"
+
+msgid ""
+"\n"
+"# Registers:\n"
+msgstr ""
+"\n"
+"# Registry:\n"
+
+#, c-format
+msgid "Unknown register type %d"
+msgstr "%d není známým typem registru"
+
+#, c-format
+msgid "E354: Invalid register name: '%s'"
+msgstr "E354: '%s' není pøípustné jméno registru"
+
+#, c-format
+msgid "%ld Cols; "
+msgstr "øádkù: %ld;"
+
+#, c-format
+msgid "Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Bytes"
+msgstr "Vybráno %s%ld z %ld øádkù; %ld z %ld slov; %ld z %ld Bytù"
+
+#, c-format
+msgid "Col %s of %s; Line %ld of %ld; Word %ld of %ld; Byte %ld of %ld"
+msgstr "Sloupec %s z %s; Øádek %ld z %ld; Slovo %ld z %ld; Byte %ld z %ld"
+
+#, c-format
+msgid "(+%ld for BOM)"
+msgstr "(+%ld pro BOM)"
+
+msgid "Thanks for flying Vim"
+msgstr "Dìkuji za použití Vim"
+
+msgid "Option not supported"
+msgstr "Volba není podporována"
+
+msgid "Not allowed in a modeline"
+msgstr "Není v modeline povoleno"
+
+msgid ""
+"\n"
+"\tLast set from "
+msgstr ""
+"\n"
+"\tNaposledy nastavena z "
+
+msgid "Number required after ="
+msgstr "Po = je vyžadováno èíslo"
+
+msgid "Not found in termcap"
+msgstr "Nenalezen v termcapu"
+
+#, c-format
+msgid "Illegal character <%s>"
+msgstr "Nepøípustný znak <%s>"
+
+msgid "Not allowed here"
+msgstr "Toto zde není povoleno"
+
+msgid "Cannot set 'term' to empty string"
+msgstr "volba 'term' nemùže být prázdná"
+
+msgid "Cannot change term in GUI"
+msgstr "V GUI nelze mìnit term"
+
+msgid "Use \":gui\" to start the GUI"
+msgstr "Použijte \"gui\" pro spuštìní GUI"
+
+msgid "'backupext' and 'patchmode' are equal"
+msgstr "volby 'backupext' a 'patchmode' mají stejnou hodnotu"
+
+msgid "Zero length string"
+msgstr "øetìzec o nulové délce"
+
+#, c-format
+msgid "Missing number after <%s>"
+msgstr "Po <%s> chybí èíslo"
+
+msgid "Missing comma"
+msgstr "Chybí èárka"
+
+msgid "Must specify a ' value"
+msgstr "Je nutné zadat hodnotu '"
+
+msgid "contains unprintable character"
+msgstr "obsahuje netisknutelné znaky"
+
+msgid "Invalid font(s)"
+msgstr "Chybná písma"
+
+msgid "can't select fontset"
+msgstr "nelze vybrat sadu písem"
+
+msgid "Invalid fontset"
+msgstr "chybná sada písem"
+
+msgid "can't select wide font"
+msgstr "nelze vybrat široký font"
+
+msgid "Invalid wide font"
+msgstr "Chybné široké písmo"
+
+#, c-format
+msgid "Illegal character after <%c>"
+msgstr "Nepøípustný znak po <%c>"
+
+msgid "comma required"
+msgstr "je nutná èárka"
+
+#, c-format
+msgid "'commentstring' must be empty or contain %s"
+msgstr "volba `commentstring` musí být buï prázdná nebo nastavená na %s"
+
+msgid "No mouse support"
+msgstr "Bez podpory myši"
+
+msgid "Unclosed expression sequence"
+msgstr "neuzavøená sekvence výrazù"
+
+msgid "too many items"
+msgstr "pøíliš mnoho položek"
+
+msgid "unbalanced groups"
+msgstr "nevyvážené skupiny"
+
+msgid "A preview window already exists"
+msgstr "Okno náhledu již existuje"
+
+msgid "'winheight' cannot be smaller than 'winminheight'"
+msgstr ""
+"hodnota volby 'winheight' nesmí být menší než hodnota volby 'winminheight'"
+
+msgid "'winwidth' cannot be smaller than 'winminwidth'"
+msgstr ""
+"hodnota volby 'winwidth' nesmí být menší než hodnota volby 'winminwidth'"
+
+#, c-format
+msgid "Need at least %d lines"
+msgstr "minimální potøebný poèet øádkù: %d"
+
+#, c-format
+msgid "Need at least %d columns"
+msgstr "minimální potøebný poèet sloupcù: %d"
+
+#, c-format
+msgid "E355: Unknown option: %s"
+msgstr "E355: Neznámá volba: %s"
+
+msgid ""
+"\n"
+"--- Terminal codes ---"
+msgstr ""
+"\n"
+"--- Kódy terminálu ---"
+
+msgid ""
+"\n"
+"--- Global option values ---"
+msgstr ""
+"\n"
+"--- Nastavení globálních voleb ---"
+
+msgid ""
+"\n"
+"--- Local option values ---"
+msgstr ""
+"\n"
+"--- Nastavení lokálních voleb ---"
+
+msgid ""
+"\n"
+"--- Options ---"
+msgstr ""
+"\n"
+"--- Volby ---"
+
+msgid "E356: get_varp ERROR"
+msgstr "E356: get_varp CHYBA"
+
+#, c-format
+msgid "E357: 'langmap': Matching character missing for %s"
+msgstr "E357: 'langmap': pro %s chybí vyhovující znak"
+
+#, c-format
+msgid "E358: 'langmap': Extra characters after semicolon: %s"
+msgstr "E358: 'langmap': nadbyteèné znaky po støedníku: %s"
+
+msgid "cannot open "
+msgstr "nelze otevøít "
+
+msgid "VIM: Can't open window!\n"
+msgstr "VIM: Nelze otevøít nové okno!\n"
+
+msgid "Need Amigados version 2.04 or later\n"
+msgstr "Vyžaduje Amigados verze 2.04 nebo vyšší\n"
+
+#, c-format
+msgid "Need %s version %ld\n"
+msgstr "Vyžaduje %s verze %ld\n"
+
+msgid "Cannot open NIL:\n"
+msgstr "Nelze otevøít NIL:\n"
+
+msgid "Cannot create "
+msgstr " Nelze vytvoøit "
+
+#, c-format
+msgid "Vim exiting with %d\n"
+msgstr "Vim bude ukonèen %d\n"
+
+msgid "cannot change console mode ?!\n"
+msgstr "Nelze zmìnit mód konzole ?!\n"
+
+msgid "E359: Screen mode setting not supported"
+msgstr "E359: Nastavování režimu obrazovky není podporováno"
+
+msgid "mch_get_shellsize: not a console??\n"
+msgstr "mch_get_shellsize: neni konzole??\n"
+
+#. if Vim opened a window: Executing a shell may cause crashes
+msgid "E360: Cannot execute shell with -f option"
+msgstr "E360: Nelze spustit shell s parametrem -f"
+
+msgid "Cannot execute "
+msgstr "Nelze spustit "
+
+msgid "shell "
+msgstr "shell "
+
+msgid " returned\n"
+msgstr " návratová hodnota shellu\n"
+
+msgid "ANCHOR_BUF_SIZE too small."
+msgstr "ANCHOR_BUF_SIZE je pøíliš malá."
+
+msgid "I/O ERROR"
+msgstr "I/O CHYBA"
+
+msgid "...(truncated)"
+msgstr "...(kráceno)"
+
+msgid "'columns' is not 80, cannot execute external commands"
+msgstr "'columns' není 80, nelze spustit externí pøíkaz"
+
+#, c-format
+msgid "E364: Library call failed for \"%s()\""
+msgstr "E364: Volání knihovní funkce \"%s()\" selhalo"
+
+msgid "E237: Printer selection failed"
+msgstr "E237: Nelze zvolit tiskárnu"
+
+#, c-format
+msgid "to %s on %s"
+msgstr "do %s v %s"
+
+#, c-format
+msgid "E238: Print error: %s"
+msgstr "E238: Chyba tisku: %s"
+
+msgid "Unknown"
+msgstr "Neznámý"
+
+#, c-format
+msgid "Printing '%s'"
+msgstr "Vytištìno '%s'"
+
+#, c-format
+msgid "E244: Illegal charset name \"%s\" in font name \"%s\""
+msgstr "E244: Nepøípustná jméno znakové sady \"%s\" ve fontu \"%s\""
+
+#, c-format
+msgid "E245: Illegal char '%c' in font name \"%s\""
+msgstr "E245: Nepøípustný znak '%c' ve fontu \"%s\""
+
+msgid "E366: Invalid 'osfiletype' option - using Text"
+msgstr "E366: Neplatný 'osfiletype' - použit Text"
+
+msgid "Vim: Double signal, exiting\n"
+msgstr "VIm: dvojitý signál, konèím\n"
+
+#, c-format
+msgid "Vim: Caught deadly signal %s\n"
+msgstr "Vim: Zachycen smrtelný signál %s\n"
+
+msgid "Vim: Caught deadly signal\n"
+msgstr "Vim: Zachycen smrtelný signál\n"
+
+#, c-format
+msgid "Opening the X display took %ld msec"
+msgstr "Doba otevírání X displeje (v ms): %ld"
+
+msgid ""
+"\n"
+"Vim: Got X error\n"
+msgstr ""
+"\n"
+"Vim: chyba X11\n"
+
+msgid "Testing the X display failed"
+msgstr "Test X displeje se nezdaøil"
+
+msgid "Opening the X display timed out"
+msgstr "Vypršel èas pøi èekání na otevøení X displeje"
+
+msgid ""
+"\n"
+"Cannot execute shell "
+msgstr ""
+"\n"
+"nelze spustit shell "
+
+msgid ""
+"\n"
+"Cannot execute shell sh\n"
+msgstr ""
+"\n"
+"Nelze spustit sh shell\n"
+
+msgid ""
+"\n"
+"shell returned "
+msgstr ""
+"\n"
+" návratová hodnota shellu "
+
+msgid ""
+"\n"
+"Cannot create pipes\n"
+msgstr ""
+"\n"
+"Nelze vytvoøit roury\n"
+
+msgid ""
+"\n"
+"Cannot fork\n"
+msgstr ""
+"\n"
+"Volání fork selhalo\n"
+
+msgid ""
+"\n"
+"Command terminated\n"
+msgstr ""
+"\n"
+"Pøíkaz ukonèen\n"
+
+msgid "Opening the X display failed"
+msgstr "Otevøení X displeje se nezdaøilo"
+
+msgid "At line"
+msgstr "Na øádku"
+
+msgid "Could not load vim32.dll!"
+msgstr "Nelze naèíst vim32.dll!"
+
+msgid "VIM Error"
+msgstr "Chyba VIMu"
+
+msgid "Could not fix up function pointers to the DLL!"
+msgstr "Nelze nastavit ukazatele funkcí na DLL"
+
+#, c-format
+msgid "shell returned %d"
+msgstr "návratová hodnota shellu %d"
+
+#, c-format
+msgid "Vim: Caught %s event\n"
+msgstr "Vim: Zachycen %s signál\n"
+
+msgid "close"
+msgstr "zavøít"
+
+msgid "logoff"
+msgstr "logoff"
+
+msgid "shutdown"
+msgstr "shutdown"
+
+msgid "E371: Command not found"
+msgstr "E371: Pøíkaz není k dispozici"
+
+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 se nevyskytuje ve Vaší $PATH.\n"
+"Externí pøíkazy nebudou "
+
+msgid "Vim Warning"
+msgstr "Varování"
+
+msgid "E372: Too many %%%c in format string"
+msgstr "E372: Pøíliš mnoho %%%c ve formátovacím øetìzci"
+
+msgid "E373: Unexpected %%%c in format string"
+msgstr "E373: Neoèekávaný výskyt %%%c ve formátovacím øetìzci"
+
+msgid "E374: Missing ] in format string"
+msgstr "E374: Ve formátovacím øetìzci chybí ]"
+
+msgid "E375: Unsupported %%%c in format string"
+msgstr "E375: %%%c Nepodporovaná formátová specifikace ve formátovacím øetìzci"
+
+msgid "E376: Invalid %%%c in format string prefix"
+msgstr "E376: Nepøípustné %%%c v prefixu formátovacího øetìzce"
+
+msgid "E377: Invalid %%%c in format string"
+msgstr "E377: Nepøípustné %%%c ve formátovacím øetìzci"
+
+msgid "E378: 'errorformat' contains no pattern"
+msgstr "E378: 'errorformat' neobsahuje žádný vzorek"
+
+msgid "E379: Missing or empty directory name"
+msgstr "E379: Chybìjící nebo prázdný název adresáøe"
+
+msgid "No more items"
+msgstr "Žádné další položky"
+
+#, c-format
+msgid "(%d of %d)%s%s: "
+msgstr "(%d/%d)%s%s: "
+
+msgid " (line deleted)"
+msgstr " (øádek smazán)"
+
+msgid "E380: At bottom of quickfix stack"
+msgstr "E380: Konec quickfix seznamu"
+
+msgid "E381: At top of quickfix stack"
+msgstr "E381: Zaèátek quickfix seznamu"
+
+#, c-format
+msgid "error list %d of %d; %d errors"
+msgstr "seznam chyb %d z %d; poèet chyb: %d"
+
+msgid "E382: Cannot write, 'buftype' option is set"
+msgstr "E382: Nelze uložit, je nastavena volba 'buftype'"
+
+msgid "E339: Pattern too long"
+msgstr "E339: Vzor je pøíliš dlouhý"
+
+#, c-format
+msgid "E61: Nested %s*"
+msgstr "E61: %s*"
+
+#, c-format
+msgid "E62: Nested %s%c"
+msgstr "E62: %s%c"
+
+#, c-format
+msgid "E64: %s%c follows nothing"
+msgstr "E64: %s%c nic není"
+
+#, c-format
+msgid "Syntax error in %s{...}"
+msgstr "Chyba syntaxe v %s{...}"
+
+msgid "E361: Crash intercepted; regexp too complex?"
+msgstr "E361: Zachyceno pøeteèení zásobníku: pøíliš složitý regulární výraz?"
+
+msgid "E363: pattern caused out-of-stack error"
+msgstr "E363: vzorek zpùsobil pøeteèení zásobníku"
+
+msgid "External submatches:\n"
+msgstr "Vnìjší podøazené shody:\n"
+
+#, c-format
+msgid "+--%3ld lines folded "
+msgstr "poèet øádkù v záhybu: %3ld"
+
+msgid " VREPLACE"
+msgstr " VREPLACE"
+
+msgid " REPLACE"
+msgstr " REPLACE"
+
+msgid " REVERSE"
+msgstr " REVERSE"
+
+msgid " INSERT"
+msgstr " INSERT"
+
+msgid " (insert)"
+msgstr " (insert)"
+
+msgid " (replace)"
+msgstr " (replace)"
+
+msgid " (vreplace)"
+msgstr " (vreplace)"
+
+msgid " Hebrew"
+msgstr " hebrejský"
+
+msgid " (lang)"
+msgstr " (lang)"
+
+msgid " (paste)"
+msgstr " (paste)"
+
+msgid " SELECT"
+msgstr " SHODY"
+
+msgid " VISUAL"
+msgstr " VIZUÁLNÍ"
+
+msgid " BLOCK"
+msgstr " BLOK"
+
+msgid " LINE"
+msgstr " ØÁDEK"
+
+msgid "recording"
+msgstr "nahrávám"
+
+msgid "search hit TOP, continuing at BOTTOM"
+msgstr "hledání dosáhlo zaèátku, pokraèování od konce"
+
+msgid "search hit BOTTOM, continuing at TOP"
+msgstr "hledání dosáhlo konce, pokraèování od zaèátku"
+
+#, c-format
+msgid "E383: Invalid search string: %s"
+msgstr "E383: Nepøípustný hledaný øetìzec: %s"
+
+#, c-format
+msgid "E384: search hit TOP without match for: %s"
+msgstr "E384: hledaný dosáhlo zaèátku bez nalezení %s"
+
+#, c-format
+msgid "E385: search hit BOTTOM without match for: %s"
+msgstr "E385: hledaný dosáhlo konce bez nalezení %s"
+
+msgid "E386: Expected '?' or '/' after ';'"
+msgstr "E386: Po ';' oèekávám '?' nebo '/'"
+
+msgid " (includes previously listed match)"
+msgstr " (vèetnì již vypsaných shod)"
+
+#. cursor at status line
+msgid "--- Included files "
+msgstr "--- Vložené soubory"
+
+msgid "not found "
+msgstr " nenalezeny"
+
+msgid "in path ---\n"
+msgstr "v cestì ---\n"
+
+msgid " (Already listed)"
+msgstr " (Již vypsáno)"
+
+msgid " NOT FOUND"
+msgstr " NENALEZENY"
+
+#, c-format
+msgid "Scanning included file: %s"
+msgstr "Prohledávám vložené soubory: %s"
+
+msgid "E387: Match is on current line"
+msgstr "E387: Shoda je na aktuálním øádku"
+
+msgid "All included files were found"
+msgstr "Všechny vložené soubory byly nalezeny"
+
+msgid "No included files"
+msgstr "Žádné vložené soubory"
+
+msgid "E388: Couldn't find definition"
+msgstr "E388: Nelze nalézt definici"
+
+msgid "E389: Couldn't find pattern"
+msgstr "E389: Nelze nalézt vzorek"
+
+#, c-format
+msgid "E390: Illegal argument: %s"
+msgstr "E390: nepøípustný argument: %s"
+
+#, c-format
+msgid "E391: No such syntax cluster: %s"
+msgstr "E391: Syntaktická sestava %s neexistuje"
+
+msgid "No Syntax items defined for this buffer"
+msgstr "Pro tento buffer nejsou definovány žádné pøedmìty syntaxe"
+
+msgid "syncing on C-style comments"
+msgstr "synchronizuji komentáøe v C stylu"
+
+msgid "no syncing"
+msgstr "žádná synchronizace"
+
+msgid "syncing starts "
+msgstr "synchronizace zaèíná "
+
+msgid " lines before top line"
+msgstr " øádkù pøed zaèátkem"
+
+msgid ""
+"\n"
+"--- Syntax sync items ---"
+msgstr ""
+"\n"
+"--- Položky synchronizace syntaxe ---"
+
+msgid ""
+"\n"
+"syncing on items"
+msgstr ""
+"\n"
+"synchronizuji pøedmìty"
+
+msgid ""
+"\n"
+"--- Syntax items ---"
+msgstr ""
+"\n"
+"--- Pøedmìty syntaxe ---"
+
+#, c-format
+msgid "E392: No such syntax cluster: %s"
+msgstr "E392: Syntaktická sestava %s neexistuje"
+
+msgid "minimal "
+msgstr "minimální "
+
+msgid "maximal "
+msgstr "maximální "
+
+msgid "E393: group[t]here not accepted here"
+msgstr "E393: group[t]here nesmí být na tomto místì"
+
+#, c-format
+msgid "E394: Didn't find region item for %s"
+msgstr "E394: Pro %s chybí položka regionu"
+
+msgid "E395: contains argument not accepted here"
+msgstr "E395: obsahuje argumenty, které zde nejsou povoleny"
+
+msgid "E396: containedin argument not accepted here"
+msgstr "E396: obsahuje argumenty, které zde nejsou povoleny"
+
+msgid "E397: Filename required"
+msgstr "E397: Vyžadován název souboru"
+
+#, c-format
+msgid "E398: Missing '=': %s"
+msgstr "E398: Chybí '=': %s"
+
+#, c-format
+msgid "E399: Not enough arguments: syntax region %s"
+msgstr "E399: Pøíliš málo argumentù: oblast syntaxe %s"
+
+msgid "E400: No cluster specified"
+msgstr "E400: Nebyla zadána žádná sestava"
+
+#, c-format
+msgid "E401: Pattern delimiter not found: %s"
+msgstr "E401: Oddìlovaè vzorku %s nenalezen"
+
+#, c-format
+msgid "E402: Garbage after pattern: %s"
+msgstr "E402: Chyba za vzorkem %s"
+
+msgid "E403: syntax sync: line continuations pattern specified twice"
+msgstr "E403: synchronizace syntaxe: vzorek pokraèování øádkù zadán dvakrát"
+
+#, c-format
+msgid "E404: Illegal arguments: %s"
+msgstr "E404: nepøípustný argument: %s"
+
+#, c-format
+msgid "E405: Missing equal sign: %s"
+msgstr "E405: Chybí rovnítko: %s"
+
+#, c-format
+msgid "E406: Empty argument: %s"
+msgstr "E406: Prázdný argument: %s"
+
+#, c-format
+msgid "E407: %s not allowed here"
+msgstr "E407: %s zde není povoleno"
+
+#, c-format
+msgid "E408: %s must be first in contains list"
+msgstr "E408: %s musí být první v 'contains' seznamu"
+
+#, c-format
+msgid "E409: Unknown group name: %s"
+msgstr "E409: Neznámá název skupiny: %s"
+
+#, c-format
+msgid "E410: Invalid :syntax subcommand: %s"
+msgstr "E410: chybný podøazený pøíkaz :syntax : %s "
+
+#, c-format
+msgid "E411: highlight group not found: %s"
+msgstr "E411: skupina zvýraznìní %s nebyla nalezena"
+
+#, c-format
+msgid "E412: Not enough arguments: \":highlight link %s\""
+msgstr "E412: Pøíliš málo argumentù: \":highlight link %s\""
+
+#, c-format
+msgid "E413: Too many arguments: \":highlight link %s\""
+msgstr "E413: Pøíliš mnoho argumentù: \":highlight link %s\""
+
+msgid "E414: group has settings, highlight link ignored"
+msgstr "E414: skupina je nastavena, odkaz na zvýrazòovací skupinu ignorován"
+
+#, c-format
+msgid "E415: unexpected equal sign: %s"
+msgstr "E415: neèekané rovnítko : %s"
+
+#, c-format
+msgid "E416: missing equal sign: %s"
+msgstr "E416: chybné rovnítko: %s"
+
+#, c-format
+msgid "E417: missing argument: %s"
+msgstr "E417: chybí argument: %s"
+
+#, c-format
+msgid "E418: Illegal value: %s"
+msgstr "E418: nepøípustná hodnota: %s"
+
+msgid "E419: FG color unknown"
+msgstr "E419: barva popøedí není známá"
+
+msgid "E420: BG color unknown"
+msgstr "E420: barva popøedí není známá"
+
+#, c-format
+msgid "E421: Color name or number not recognized: %s"
+msgstr "E421: název èi èíslo barvy %s nebylo rozpoznáno"
+
+#, c-format
+msgid "E422: terminal code too long: %s"
+msgstr "E422: terminálový kód %s je pøíliš dlouhý"
+
+#, c-format
+msgid "E423: Illegal argument: %s"
+msgstr "E423: nepøípustný argument: %s"
+
+msgid "E424: Too many different highlighting attributes in use"
+msgstr ""
+"E424: Je používáno pøíliš velké množství odlišných zvýrazòovacích atributù"
+
+msgid "at bottom of tag stack"
+msgstr "konec seznamu tagù"
+
+msgid "at top of tag stack"
+msgstr "zaèátek seznamu tagù"
+
+msgid "E425: Cannot go before first matching tag"
+msgstr "E425: Pøed první vyhovující tag nelze pøeskoèit"
+
+#, c-format
+msgid "E426: tag not found: %s"
+msgstr "E426: tag %s nenalezen"
+
+msgid " # pri kind tag"
+msgstr " # pri typ tag"
+
+msgid "file\n"
+msgstr "soubor\n"
+
+#.
+#. * Ask to select a tag from the list.
+#. * When using ":silent" assume that <CR> was entered.
+#.
+msgid "Enter nr of choice (<CR> to abort): "
+msgstr "Zadejte èíslo (<CR> pro ukonèení): "
+
+msgid "E427: There is only one matching tag"
+msgstr "E427: Vyhovuje pouze jeden tag"
+
+msgid "E428: Cannot go beyond last matching tag"
+msgstr "E428: Za poslední vyhovující tag nelze pøeskoèit"
+
+#, c-format
+msgid "File \"%s\" does not exist"
+msgstr "Soubor \"%s\" neexistuje"
+
+#. Give an indication of the number of matching tags
+#, c-format
+msgid "tag %d of %d%s"
+msgstr "tag %d z celkového poètu %d%s"
+
+msgid " or more"
+msgstr " nebo více"
+
+msgid " Using tag with different case!"
+msgstr " Používám tag s písmeny jiné velikosti!"
+
+#, c-format
+msgid "E429: File \"%s\" does not exist"
+msgstr "E429: \"%s\" neexistuje"
+
+#. Highlight title
+msgid ""
+"\n"
+" # TO tag FROM line in file/text"
+msgstr ""
+"\n"
+" # CÍL tag START øádek v souboru/textu"
+
+msgid "Linear tag search"
+msgstr "Lineární hledání tagu"
+
+msgid "Binary tag search"
+msgstr "Binární hledání tagu"
+
+#, c-format
+msgid "Searching tags file %s"
+msgstr "Prohledávám soubor tagù %s"
+
+#, c-format
+msgid "E430: Tag file path truncated for %s\n"
+msgstr "E430: Soubor tagù %s byl oøezán\n"
+
+#, c-format
+msgid "E431: Format error in tags file \"%s\""
+msgstr "E431: Chyba formátu v souboru tagù \"%s\""
+
+#, c-format
+msgid "Before byte %ld"
+msgstr "Pøed bajtem %ld"
+
+#, c-format
+msgid "E432: Tags file not sorted: %s"
+msgstr "E432: Obsah soubor tagù %s není seøazen"
+
+#. never opened any tags file
+msgid "E433: No tags file"
+msgstr "E433: Žádný soubor tagù"
+
+msgid "E434: Can't find tag pattern"
+msgstr "E434: Nelze najít vzorek tagù"
+
+msgid "E435: Couldn't find tag, just guessing!"
+msgstr "E435: Tag nelze nalézt, pouze hádám!"
+
+msgid "' not known. Available builtin terminals are:"
+msgstr "' není znám. Dostupné vestavìné terminály:"
+
+msgid "defaulting to '"
+msgstr "implicitní terminál '"
+
+msgid "Cannot open termcap file"
+msgstr "Nelze otevøít termcap"
+
+msgid "Terminal entry not found in terminfo"
+msgstr "Terminfo neobsahuje položku pro tento terminál"
+
+msgid "Terminal entry not found in termcap"
+msgstr "Termcap neobsahuje položku pro tento terminál"
+
+#, c-format
+msgid "E436: No \"%s\" entry in termcap"
+msgstr "E436: Termcap neobsahuje položku pro \"%s\""
+
+msgid "E437: terminal capability \"cm\" required"
+msgstr "E437: Terminál musí mít schopnost \"cm\""
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Terminal keys ---"
+msgstr ""
+"\n"
+"--- Klávesy terminálu ---"
+
+msgid "new shell started\n"
+msgstr "spuštìn nový shell\n"
+
+msgid "Vim: Error reading input, exiting...\n"
+msgstr "Vim: chyba pøi ètení vstupu, konèím...\n"
+
+#. must display the prompt
+msgid "No undo possible; continue anyway"
+msgstr "odstranìní zmìn není možné; chcete pøesto pokraèovat"
+
+msgid "E438: u_undo: line numbers wrong"
+msgstr "E438: u_undo: èísla øádkù jsou chybná"
+
+msgid "1 change"
+msgstr "poèet zmìn: 1"
+
+#, c-format
+msgid "%ld changes"
+msgstr "poèet zmìn: %ld"
+
+msgid "E439: undo list corrupt"
+msgstr "E439: záznam o zmìnách poškozen"
+
+msgid "E440: undo line missing"
+msgstr "E440: chybí undo øádek"
+
+#. Only MS VC 4.1 and earlier can do Win32s
+msgid ""
+"\n"
+"MS-Windows 16/32-bit GUI version"
+msgstr ""
+"\n"
+"16/32 bitová GUI verze pro MS Windows"
+
+msgid ""
+"\n"
+"MS-Windows 32-bit GUI version"
+msgstr ""
+"\n"
+"32 bitová GUI verze pro MS Windows"
+
+msgid " in Win32s mode"
+msgstr " ve Win32s režimu"
+
+msgid " with OLE support"
+msgstr " s OLE podporou"
+
+msgid ""
+"\n"
+"MS-Windows 32-bit console version"
+msgstr ""
+"\n"
+"32 bitová verze pro MS Windows konzolu"
+
+msgid ""
+"\n"
+"MS-Windows 16-bit version"
+msgstr ""
+"\n"
+"16 bitová verze pro MS Windows"
+
+msgid ""
+"\n"
+"32-bit MS-DOS version"
+msgstr ""
+"\n"
+"32 bitová verze pro MS Windows"
+
+msgid ""
+"\n"
+"16-bit MS-DOS version"
+msgstr ""
+"\n"
+"16 bitová MS-DOS verze"
+
+msgid ""
+"\n"
+"MacOS X (unix) version"
+msgstr ""
+"\n"
+"MacOS X (unix) verze"
+
+msgid ""
+"\n"
+"MacOS X version"
+msgstr ""
+"\n"
+"MacOS X verze"
+
+msgid ""
+"\n"
+"MacOS version"
+msgstr ""
+"\n"
+"MacOS verze"
+
+msgid ""
+"\n"
+"RISC OS version"
+msgstr ""
+"\n"
+"RISC OS verze"
+
+msgid ""
+"\n"
+"Included patches: "
+msgstr ""
+"\n"
+"Použité záplaty: "
+
+msgid ""
+"\n"
+"Compiled "
+msgstr ""
+"\n"
+"pøeložil "
+
+msgid "by "
+msgstr " "
+
+msgid ""
+"\n"
+"Huge version "
+msgstr ""
+"\n"
+"maximální verze"
+
+msgid ""
+"\n"
+"Big version "
+msgstr ""
+"\n"
+"velká verze "
+
+msgid ""
+"\n"
+"Normal version "
+msgstr ""
+"\n"
+"normální verze"
+
+msgid ""
+"\n"
+"Small version "
+msgstr ""
+"\n"
+"malá verze "
+
+msgid ""
+"\n"
+"Tiny version "
+msgstr ""
+"\n"
+"minimální verze"
+
+msgid "without GUI."
+msgstr "bez grafického rozhraní"
+
+msgid "with GTK-GNOME GUI."
+msgstr "s rozhraním GTK-GNOME"
+
+msgid "with GTK GUI."
+msgstr "s rozhraním GTK"
+
+msgid "with X11-Motif GUI."
+msgstr "s rozhraním X11-Motif"
+
+msgid "with X11-Athena GUI."
+msgstr "S rozhraním X11-Athena"
+
+msgid "with BeOS GUI."
+msgstr "s rozhraním BeOS"
+
+msgid "with Photon GUI."
+msgstr "s rozhraním Photon"
+
+msgid "with GUI."
+msgstr "s grafickým rozhraním"
+
+msgid "with Carbon GUI."
+msgstr "s grafickým rozhraním Carbon"
+
+msgid "with Cocoa GUI."
+msgstr "s grafickým rozhraním Cocoa"
+
+msgid "with (classic) GUI."
+msgstr "s (clasickým) grafickým rozhraním"
+
+msgid " Features included (+) or not (-):\n"
+msgstr " Vlastnosti zahrnuté (+) a nezahrnuté (-):\n"
+
+msgid " system vimrc file: \""
+msgstr " systémový vimrc soubor: \""
+
+msgid " user vimrc file: \""
+msgstr " uživatelský vimrc soubor: \""
+
+msgid " 2nd user vimrc file: \""
+msgstr " druhý uživatelský vimrc soubor: \""
+
+msgid " 3rd user vimrc file: \""
+msgstr " tøetí uživatelský vimrc soubor: \""
+
+msgid " user exrc file: \""
+msgstr " uživatelský exrc soubor: \""
+
+msgid " 2nd user exrc file: \""
+msgstr " druhý uživatelský exrc soubor: \""
+
+msgid " system gvimrc file: \""
+msgstr " systémový gvimrc soubor: \""
+
+msgid " user gvimrc file: \""
+msgstr " uživatelský gvimrc soubor: \""
+
+msgid "2nd user gvimrc file: \""
+msgstr "druhý uživatelský gvimrc soubor: \""
+
+msgid "3rd user gvimrc file: \""
+msgstr "tøetí uživatelský gvimrc soubor: \""
+
+msgid " system menu file: \""
+msgstr " systémový soubor s menu: \""
+
+msgid " fall-back for $VIM: \""
+msgstr " implicitní hodnota $VIM:\""
+
+msgid " f-b for $VIMRUNTIME: \""
+msgstr " implicitní hodnota $VIMRUNTIME: \""
+
+msgid "Compilation: "
+msgstr "Pøeklad: "
+
+msgid "Compiler: "
+msgstr "Pøekladaè: "
+
+msgid "Linking: "
+msgstr "Linkuji: "
+
+msgid " DEBUG BUILD"
+msgstr " PODPORA LADÌNÍ"
+
+msgid "VIM - Vi IMproved"
+msgstr "VIM - Vi IMproved"
+
+msgid "version "
+msgstr "verze "
+
+msgid "by Bram Moolenaar et al."
+msgstr "Autor: Bram Moolenaar a další"
+
+msgid "Vim is open source and freely distributable"
+msgstr "Vim je volnì šiøitelný program s otevøeným zdrojovým kódem"
+
+msgid "Help poor children in Uganda!"
+msgstr "Pomozte chudým dìtem v Ugandì!"
+
+msgid "type :help iccf<Enter> for information "
+msgstr "podrobnìjší informace získáte pomocí :help iccf<Enter>"
+
+msgid "type :q<Enter> to exit "
+msgstr "zadejte :q<Enter> pro ukonèení programu"
+
+msgid "type :help<Enter> or <F1> for on-line help"
+msgstr "zadejte :help<Enter> èi <F1> pro nápovìdu"
+
+msgid "type :help version7<Enter> for version info"
+msgstr "zadejte :help version7<Enter> pro informace o verzi 6"
+
+msgid "Running in Vi compatible mode"
+msgstr "Bìžím v režimu kompatibility s Vi"
+
+msgid "type :set nocp<Enter> for Vim defaults"
+msgstr "zadejte :set nocp<Enter> pro implicitní nastavení Vim"
+
+msgid "type :help cp-default<Enter> for info on this"
+msgstr "podrobnìjší informace získáte pomocí :help cp-default<Enter>"
+
+msgid "WARNING: Windows 95/98/ME detected"
+msgstr "VAROVÁNÍ: detekovány Windows 95/98/ME"
+
+msgid "type :help windows95<Enter> for info on this"
+msgstr "zadejte :help windows95<Enter> pro podrobnìjší informace"
+
+msgid "E441: There is no preview window"
+msgstr "E441: Není žádné preview okno není"
+
+msgid "E442: Can't split topleft and botright at the same time"
+msgstr "E442: Okno nelze rozdìlit zároveò topleft a botright"
+
+msgid "E443: Cannot rotate when another window is split"
+msgstr "E443: Nelze rotovat, pokud je jiné okno rozdìleno"
+
+msgid "E444: Cannot close last window"
+msgstr "E444: Poslední okno nelze uzavøít"
+
+msgid "Already only one window"
+msgstr "Již existuje pouze jedno okno"
+
+msgid "E445: Other window contains changes"
+msgstr "E445: Jiné okno obsahuje zmìny"
+
+msgid "E446: No file name under cursor"
+msgstr "E446: Pod kurzorem se nenachází název souboru"
+
+#, c-format
+msgid "E447: Can't find file \"%s\" in path"
+msgstr "E447: Soubor \"%s\" nelze v path nalézt"
+
+msgid "Edit with &multiple Vims"
+msgstr "Editace &multiple Vimy"
+
+msgid "Edit with single &Vim"
+msgstr "Editace jedním $Vim -em"
+
+msgid "Edit with &Vim"
+msgstr "Editace &Vim -em"
+
+msgid "Edit with existing Vim - &"
+msgstr "Editace existujícím Vimem - &"
+
+msgid "Edits the selected file(s) with Vim"
+msgstr "Editace vybraných souborù Vimem"
+
+msgid "Error creating process: Check if gvim is in your path!"
+msgstr "Chyba pøi spouštìní procesu: Zkontrolujte zdali je gvim v $PATH!"
+
+msgid "gvimext.dll error"
+msgstr "chyba gvimext.dll"
+
+msgid "Path length too long!"
+msgstr "Název (v path) je pøíliš dlouhý"
+
+msgid "--No lines in buffer--"
+msgstr "--Buffer neobsahuje žádný øádek--"
+
+#.
+#. * The error messages that can be shared are included here.
+#. * Excluded are errors that are only used once and debugging messages.
+#.
+msgid "Command aborted"
+msgstr "Pøíkaz pøerušen"
+
+msgid "Argument required"
+msgstr "Je vyžadován argument"
+
+msgid "E10: \\ should be followed by /, ? or &"
+msgstr "E10: po \\ by mìl následovat /. ? nebo &"
+
+msgid "E11: Invalid in command-line window; <CR> executes, CTRL-C quits"
+msgstr ""
+"E11: Chyba v oknì pøíkazové øádky; <CR> pro spuštšní, CTRL-C pro ukonèení"
+
+msgid "E12: Command not allowed from exrc/vimrc in current dir or tag search"
+msgstr ""
+"E12: Pøíkaz není z exrc/vimrc v aktuálním adresáøi èi pøi hledání tagu "
+"povolen."
+
+msgid "E13: File exists (add ! to override)"
+msgstr "E13: Soubor existuje (použijte ! pro vynucení)"
+
+msgid "Command failed"
+msgstr "Pøíkaz selhal"
+
+msgid "Internal error"
+msgstr "Vnitøní chyba"
+
+msgid "Interrupted"
+msgstr "Pøerušeno"
+
+msgid "E14: Invalid address"
+msgstr "E14: Chybná adresa"
+
+msgid "Invalid argument"
+msgstr "Chybný argument"
+
+#, c-format
+msgid "Invalid argument: %s"
+msgstr "Chybný argument: %s"
+
+#, c-format
+msgid "E15: Invalid expression: %s"
+msgstr "E15: Chybný výraz: %s"
+
+msgid "E16: Invalid range"
+msgstr "E16: Chybný rozsah"
+
+msgid "Invalid command"
+msgstr "Chybný pøíkaz"
+
+#, c-format
+msgid "E17: \"%s\" is a directory"
+msgstr "E17: \"%s\" je adresáøem"
+
+msgid "E18: Unexpected characters before '='"
+msgstr "E18: Neoèekávané znaky pøed '='"
+
+msgid "E19: Mark has invalid line number"
+msgstr "E19: Znaèka má chybné èíslo øádku"
+
+msgid "E20: Mark not set"
+msgstr "E20: není nastavena"
+
+msgid "E21: Cannot make changes, 'modifiable' is off"
+msgstr "E21: Nelze mìnit, je nastavena volba 'modifiable'"
+
+msgid "E22: Scripts nested too deep"
+msgstr "E22: Skript vnoøen pøíliš hluboko"
+
+msgid "E23: No alternate file"
+msgstr "E23: Žádný alternativní soubor"
+
+msgid "E24: No such abbreviation"
+msgstr "E24: Taková zkratka neexistuje"
+
+msgid "No ! allowed"
+msgstr "! není povoleno"
+
+msgid "E25: GUI cannot be used: Not enabled at compile time"
+msgstr "E25: Nelze použít GUI: nebylo zapnuto pøi pøekladu programu"
+
+msgid "E26: Hebrew cannot be used: Not enabled at compile time\n"
+msgstr ""
+"E26: nelze použít hebrejský režim: nebyl zapnut pøi pøekladu programu\n"
+
+msgid "E27: Farsi cannot be used: Not enabled at compile time\n"
+msgstr "E27: Nelze použít farsi režim: nebyl zapnut pøi pøekladu programu\n"
+
+#, c-format
+msgid "E28: No such highlight group name: %s"
+msgstr "E28: Skupina zvýraznìní %s neexistuje"
+
+msgid "E29: No inserted text yet"
+msgstr "E29: Zatím není žádný vložený text"
+
+msgid "E30: No previous command line"
+msgstr "E30: Žádná pøedchozí pøíkazová øádka"
+
+msgid "E31: No such mapping"
+msgstr "E31: Žádné takové mapování"
+
+msgid "No match"
+msgstr "Žádná shoda"
+
+#, c-format
+msgid "No match: %s"
+msgstr "Žádná shoda: %s"
+
+msgid "E32: No file name"
+msgstr "E32: Žádný název souboru"
+
+msgid "E33: No previous substitute regular expression"
+msgstr "E33: žádný pøedchozí regulární výraz"
+
+msgid "E34: No previous command"
+msgstr "E34: Žádný pøedchozí pøíkaz"
+
+msgid "E35: No previous regular expression"
+msgstr "E35: žádný pøedchozí regulární výraz"
+
+msgid "No range allowed"
+msgstr "Rozsah není povolen"
+
+msgid "E36: Not enough room"
+msgstr "E36: Nedostatek místa"
+
+#, c-format
+msgid "Can't create file %s"
+msgstr "Nelze vytvoøit soubor %s"
+
+msgid "Can't get temp file name"
+msgstr "Nelze získat název doèasného souboru"
+
+#, c-format
+msgid "Can't open file %s"
+msgstr "Nelze otevøít soubor %s"
+
+#, c-format
+msgid "Can't read file %s"
+msgstr "Nelze èíst soubor %s"
+
+msgid "E37: No write since last change (use ! to override)"
+msgstr "E37: Neuložené zmìny (použijte ! pro vynucení)"
+
+msgid "E38: Null argument"
+msgstr "E38: Nulový argument"
+
+msgid "E39: Number expected"
+msgstr "E39: Oèekáváno èíslo"
+
+#, c-format
+msgid "E40: Can't open errorfile %s"
+msgstr "E40: Nelze otevøít chybový soubor %s"
+
+msgid "E41: Out of memory!"
+msgstr "E41: Nedostatek pamìti!"
+
+msgid "Pattern not found"
+msgstr "Vzor nenalezen"
+
+#, c-format
+msgid "Pattern not found: %s"
+msgstr "Vzor nenalezen: %s"
+
+msgid "Argument must be positive"
+msgstr "Argument musí být kladný"
+
+msgid "E42: No Errors"
+msgstr "E42: Žádné chyby"
+
+msgid "E43: Damaged match string"
+msgstr "E43: Poškozený øetìzec pro vyhledávání"
+
+msgid "E44: Corrupted regexp program"
+msgstr "E44: poškozený regexp program"
+
+msgid "E45: 'readonly' option is set (use ! to override)"
+msgstr "E45: 'nastavena volba 'readonly' (použijte ! pro vynucení)"
+
+#, c-format
+msgid "E46: Cannot set read-only variable \"%s\""
+msgstr "E46: Nelze nastavit pouze_pro_ètení promìnnou \"%s\""
+
+msgid "E47: Error while reading errorfile"
+msgstr "E47: Chyba pøi ètení chybového souboru"
+
+msgid "E48: Not allowed in sandbox"
+msgstr "E48: Není v bezpeènostní schránce povoleno"
+
+msgid "E49: Invalid scroll size"
+msgstr "E49: Chybná hodnota volby 'scroll'"
+
+msgid "E91: 'shell' option is empty"
+msgstr "E91: volba 'shell' je prázdná"
+
+msgid "E72: Close error on swap file"
+msgstr "E72: Chyba pøi uzavírání odkládacího souboru"
+
+msgid "E73: tag stack empty"
+msgstr "E73: seznam tagù je prázdný"
+
+msgid "E74: Command too complex"
+msgstr "E74: Pøíkaz je pøíliš složitý"
+
+msgid "E75: Name too long"
+msgstr "E75: Název je pøíliš dlouhý"
+
+msgid "E76: Too many ["
+msgstr "E76: pøíliš mnoho ["
+
+msgid "E77: Too many file names"
+msgstr "E77: Pøíliš mnoho názvù souborù"
+
+msgid "Trailing characters"
+msgstr "Nadbyteèné znaky na konci"
+
+msgid "E78: Unknown mark"
+msgstr "E78: Neznámá znaèka"
+
+msgid "E79: Cannot expand wildcards"
+msgstr "E79: Nelze expandovat žolíkové znaky"
+
+msgid "E80: Error while writing"
+msgstr "E80: Chyba pøi ukládání"
+
+msgid "Zero count"
+msgstr "Nulový poèet"
+
+msgid "E81: Using <SID> not in a script context"
+msgstr "E81: Použití <SID> mimo kontext skriptu"
diff --git a/src/po/cs.po b/src/po/cs.po
new file mode 100644
index 0000000000..08a14d9b9a
--- /dev/null
+++ b/src/po/cs.po
@@ -0,0 +1,4664 @@
+# Czech translation of vim
+# Jiøí Pavlovský <jpavlovsky@mbox.vol.cz>, 2000 - 2002.
+# Some completion for vim6.0 added by Jiøí Bøezina <brz@centrum.cz>
+# Some bugfixes by Tomá¹ Zellerin <zellerin@volny.cz>
+#
+# Original translations.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: vim-6.0\n"
+"POT-Creation-Date: 2001-10-08 08:27-0700\n"
+"PO-Revision-Date: 2002-02-06 22:29+0100\n"
+"Last-Translator: Jiøí Pavlovský <jpavlovsky@mbox.vol.cz>\n"
+"Language-Team: Czech <cs@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=ISO-8859-2\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+msgid "E82: Cannot allocate any buffer, exiting..."
+msgstr "E82: Nelze alokovat ¾ádný buffer, konèím..."
+
+msgid "E83: Cannot allocate buffer, using other one..."
+msgstr "E83: Nelze alokovat buffer, pou¾iji jiný..."
+
+msgid "No buffers were unloaded"
+msgstr "®ádný buffer nebyl deaktivován"
+
+msgid "No buffers were deleted"
+msgstr "®ádný buffer nebyl smazán"
+
+msgid "No buffers were wiped out"
+msgstr "®ádný buffer nebyl zahozen"
+
+msgid "1 buffer unloaded"
+msgstr "Poèet deaktivovaných bufferù: 1"
+
+#, c-format
+msgid "%d buffers unloaded"
+msgstr "Poèet deaktivovaných bufferù: %d"
+
+msgid "1 buffer deleted"
+msgstr "Poèet smazaných bufferù: 1"
+
+#, c-format
+msgid "%d buffers deleted"
+msgstr "Poèet smazaných bufferù: %d"
+
+msgid "1 buffer wiped out"
+msgstr "Poèet zahozených bufferù: 1"
+
+#, c-format
+msgid "%d buffers wiped out"
+msgstr "Poèet zahozených bufferù: %d"
+
+msgid "E84: No modified buffer found"
+msgstr "E84: Nebyl nalezen ¾ádný zmìnìný buffer"
+
+#. back where we started, didn't find anything.
+msgid "E85: There is no listed buffer"
+msgstr "E85: Seznam bufferù je prázdný"
+
+#, c-format
+msgid "E86: Cannot go to buffer %ld"
+msgstr "E86: Nelze pøeskoèit na buffer %ld"
+
+msgid "E87: Cannot go beyond last buffer"
+msgstr "E87: Za poslední buffer nelze pøeskoèit"
+
+msgid "E88: Cannot go before first buffer"
+msgstr "E88: Pøed první buffer nelze pøeskoèit"
+
+#, c-format
+msgid "E89: No write since last change for buffer %ld (use ! to override)"
+msgstr "E89: Zmìny v bufferu %ld nebyly ulo¾eny (! pro vynucení)"
+
+msgid "E90: Cannot unload last buffer"
+msgstr "E90: Poslední buffer nelze deaktivovat"
+
+msgid "W14: Warning: List of file names overflow"
+msgstr "W14: Varování: pøeteèení seznamu s názvy souborù"
+
+#, c-format
+msgid "E92: Buffer %ld not found"
+msgstr "E92: Buffer %ld nenalezen"
+
+#, c-format
+msgid "E93: More than one match for %s"
+msgstr "E93: Vzoru %s vyhovuje více bufferù"
+
+#, c-format
+msgid "E94: No matching buffer for %s"
+msgstr "E94: Vzoru %s nevyhovuje ¾ádný buffer"
+
+#, c-format
+msgid "line %ld"
+msgstr "øádek %ld"
+
+msgid "E95: Buffer with this name already exists"
+msgstr "E95: Buffer tohoto jména ji¾ existuje"
+
+msgid " [Modified]"
+msgstr " [Zmìnìný]"
+
+msgid "[Not edited]"
+msgstr "[Needitovaný]"
+
+msgid "[New file]"
+msgstr "[Nový soubor]"
+
+msgid "[Read errors]"
+msgstr "[Chyby pøi ètení]"
+
+msgid "[readonly]"
+msgstr "[Pouze pro ètení]"
+
+msgid "1 line --%d%%--"
+msgstr "øádkù: --%d%%--"
+
+msgid "%ld lines --%d%%--"
+msgstr "øádkù: %ld --%d%%--"
+
+msgid "line %ld of %ld --%d%%-- col "
+msgstr "øádek %ld/%ld --%d%%-- sloupec"
+
+msgid "[No file]"
+msgstr "[®ádný soubor]"
+
+#. must be a help buffer
+msgid "help"
+msgstr "nápovìda"
+
+msgid "[help]"
+msgstr "[nápovìda]"
+
+msgid "[Preview]"
+msgstr "[náhled]"
+
+msgid "All"
+msgstr "V¹e"
+
+msgid "Bot"
+msgstr "Konec"
+
+msgid "Top"
+msgstr "Zaèátek"
+
+msgid ""
+"\n"
+"# Buffer list:\n"
+msgstr ""
+"\n"
+"# Seznam bufferù:\n"
+
+msgid "[Error List]"
+msgstr "[seznam chyb]"
+
+msgid "[No File]"
+msgstr "[¾ádný soubor]"
+
+msgid ""
+"\n"
+"--- Signs ---"
+msgstr ""
+"\n"
+"--- Znaky ---"
+
+#, c-format
+msgid "Signs for %s:"
+msgstr "Znaky pro %s:"
+
+#, c-format
+msgid " line=%ld id=%d name=%s"
+msgstr " øádek=%ld id=%d jméno=%s"
+
+#, c-format
+msgid "E96: Can not diff more than %ld buffers"
+msgstr "E96: Nelze pøekroèit maximální poèet %ld diff bufferù"
+
+msgid "E97: Cannot create diffs"
+msgstr "E97: Nelze vytvoøit diffy"
+
+msgid "Patch file"
+msgstr "Soubor se záplatou"
+
+msgid "E98: Cannot read diff output"
+msgstr "E98: Nelze èíst výstup programu diff"
+
+msgid "E99: Current buffer is not in diff mode"
+msgstr "E99: Aktuální buffer není v diff re¾imu"
+
+msgid "E100: No other buffer in diff mode"
+msgstr "E100: To byl poslední buffer v diff re¾imu"
+
+msgid "E101: More than two buffers in diff mode, don't know which one to use"
+msgstr "E101: V diff re¾imu jsou více ne¾ dva buffery. Nevím, který mám pou¾ít."
+
+#, c-format
+msgid "E102: Can't find buffer \"%s\""
+msgstr "E102: Nelze nalézt buffer \"%s\""
+
+#, c-format
+msgid "E103: Buffer \"%s\" is not in diff mode"
+msgstr "E103: Buffer \"%s\" není v diff re¾imu"
+
+msgid "E104: Escape not allowed in digraph"
+msgstr "E104: digraph nesmí obsahovat Escape"
+
+msgid "Keymap file not found"
+msgstr "Soubor s mapou klávesnice nebyl nalezen"
+
+msgid "E105: Using :loadkeymap not in a sourced file"
+msgstr "E105: :loadkeymap mimo interpretovaný soubor"
+
+msgid " Keyword completion (^N/^P)"
+msgstr " Doplòování klíèových slov (^N/^P)"
+
+#. ctrl_x_mode == 0, ^P/^N compl.
+msgid " ^X mode (^E/^Y/^L/^]/^F/^I/^K/^D/^V/^N/^P)"
+msgstr " ^X re¾im (^E/^Y/^L/^]/^F/^I/^K/^D/^V/^N/^P)"
+
+#. Scroll has it's own msgs, in it's place there is the msg for local
+#. * ctrl_x_mode = 0 (eg continue_status & CONT_LOCAL) -- Acevedo
+msgid " Keyword Local completion (^N/^P)"
+msgstr " Lokální doplòování klíèových slov (^N/^P)"
+
+msgid " Whole line completion (^L/^N/^P)"
+msgstr " Doplòování celých øádkù (^L/^N/^P)"
+
+msgid " File name completion (^F/^N/^P)"
+msgstr " Doplòování názvù souborù (^F/^N/^P)"
+
+msgid " Tag completion (^]/^N/^P)"
+msgstr " Doplòování tagù (^I/^N/^P)"
+
+msgid " Path pattern completion (^N/^P)"
+msgstr " Doplòování vzoru cest (^N/^P)"
+
+msgid " Definition completion (^D/^N/^P)"
+msgstr " Doplòování definic (^D/^N/^P)"
+
+msgid " Dictionary completion (^K/^N/^P)"
+msgstr " Doplòování podle slovníku (^K/^N/^P)"
+
+msgid " Thesaurus completion (^T/^N/^P)"
+msgstr " Doplòování podle tezauru (^T/^N/^P)"
+
+msgid " Command-line completion (^V/^N/^P)"
+msgstr " Doplòování pøíkazové øádky (^I/^N/^P)"
+
+msgid "Hit end of paragraph"
+msgstr "Konec odstavce"
+
+msgid "'thesaurus' option is empty"
+msgstr "volba 'thesaurus' je prázdná"
+
+msgid "'dictionary' option is empty"
+msgstr "volba 'dictionary' je prázdná"
+
+#, c-format
+msgid "Scanning dictionary: %s"
+msgstr "Prohledávám slovník %s"
+
+msgid " (insert) Scroll (^E/^Y)"
+msgstr " (insert) Rolování (^E/^Y)"
+
+msgid " (replace) Scroll (^E/^Y)"
+msgstr " (replace) Rolování (^E/^Y)"
+
+#, c-format
+msgid "Scanning: %s"
+msgstr "Prohledávám %s"
+
+msgid "Scanning tags."
+msgstr "Prohledávám tagy"
+
+msgid " Adding"
+msgstr "Pøidávám"
+
+#. 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.
+#.
+msgid "-- Searching..."
+msgstr "-- Hledám..."
+
+msgid "Back at original"
+msgstr "Výchozí podoba"
+
+msgid "Word from other line"
+msgstr "Slovo z jiného øádku"
+
+msgid "The only match"
+msgstr "Jediná shoda"
+
+#, c-format
+msgid "match %d of %d"
+msgstr "shoda %d/%d"
+
+#, c-format
+msgid "match %d"
+msgstr "shoda %d"
+
+#, c-format
+msgid "E106: Unknown variable: \"%s\""
+msgstr "E106: Neznámá promìnná: \"%s\""
+
+#, c-format
+msgid "E107: Missing parentheses: %s"
+msgstr "E107: Chybí závorky: %s"
+
+#, c-format
+msgid "E108: No such variable: \"%s\""
+msgstr "E108: Promìnná \"%s\" neexistuje"
+
+msgid "E109: Missing ':' after '?'"
+msgstr "E109: Po '?' chybí ':'"
+
+msgid "E110: Missing ')'"
+msgstr "E110: Chybìjící ')'"
+
+msgid "E111: Missing ']'"
+msgstr "E111: Chybìjící ']'"
+
+#, c-format
+msgid "E112: Option name missing: %s"
+msgstr "E112: Chybí jméno volby: %s"
+
+#, c-format
+msgid "E113: Unknown option: %s"
+msgstr "E113: Neznámá volba: %s"
+
+#, c-format
+msgid "E114: Missing quote: %s"
+msgstr "E114: Chybí uvozovky: %s"
+
+#, c-format
+msgid "E115: Missing quote: %s"
+msgstr "E115: Chybí uvozovky: %s"
+
+#, c-format
+msgid "E116: Invalid arguments for function %s"
+msgstr "E116: Chybné argumenty pro funkci %s"
+
+#, c-format
+msgid "E117: Unknown function: %s"
+msgstr "E117: Neznámá funkce: %s"
+
+#, c-format
+msgid "E118: Too many arguments for function: %s"
+msgstr "E118: Pøíli¹ mnoho argumentù pro funkci %s"
+
+#, c-format
+msgid "E119: Not enough arguments for function: %s"
+msgstr "E119: Pøíli¹ málo argumentù pro funkci %s"
+
+#, c-format
+msgid "E120: Using <SID> not in a script context: %s"
+msgstr "E120: Pou¾ití <SID> mimo kontext skriptu: %s"
+
+#, c-format
+msgid "+-%s%3ld lines: "
+msgstr "+-%s%3ld øádkù:"
+
+msgid ""
+"&OK\n"
+"&Cancel"
+msgstr ""
+"&OK\n"
+"&Zru¹it"
+
+msgid "E240: No connection to Vim server"
+msgstr "E240: Neexistuje pøipojení k Vim serveru"
+
+msgid "E277: Unable to read a server reply"
+msgstr "E277: Nelze èíst odpovìï serveru"
+
+msgid "E258: Unable to send to client"
+msgstr "E258: Nelze pøedat klientovi"
+
+#, c-format
+msgid "E241: Unable to send to %s"
+msgstr "E241: Nelze pøedat do %s"
+
+msgid "(Invalid)"
+msgstr "(Chybný)"
+
+#, c-format
+msgid "E121: Undefined variable: %s"
+msgstr "E121: Nedefinovaná promìnná: %s"
+
+#, c-format
+msgid "E122: Function %s already exists, use ! to replace"
+msgstr "E122: Funkce %s ji¾ existuje. Pou¾ijte ! pro její nahrazení."
+
+#, c-format
+msgid "E123: Undefined function: %s"
+msgstr "E123: Nedefinovaná funkce: %s"
+
+#, c-format
+msgid "E124: Missing '(': %s"
+msgstr "E124: Chybí '(': %s"
+
+#, c-format
+msgid "E125: Illegal argument: %s"
+msgstr "E125: Nepøípustný argument: %s"
+
+msgid "E126: Missing :endfunction"
+msgstr "E126: Chybí :endfunction"
+
+#, c-format
+msgid "E127: Cannot redefine function %s: It is in use"
+msgstr "E127: Nelze pøedefinovat funkci %s: je pou¾ívána"
+
+#, c-format
+msgid "E128: Function name must start with a capital: %s"
+msgstr "E128: Název funkce musí zaèínat velkým písmenem: %s"
+
+msgid "E129: Function name required"
+msgstr "E129: Je vy¾adováno jméno funkce"
+
+msgid "function "
+msgstr "funkce "
+
+#, c-format
+msgid "E130: Undefined function: %s"
+msgstr "E130: Nedefinovaná funkce: %s"
+
+#, c-format
+msgid "E131: Cannot delete function %s: It is in use"
+msgstr "E131: Nelze smazat funkci %s: je ji¾ pou¾ívána"
+
+msgid "E132: Function call depth is higher than 'maxfuncdepth'"
+msgstr "E132: Zanoøení funkce je hlub¹í ne¾ 'maxfuncdepth'"
+
+#. always scroll up, don't overwrite
+#, c-format
+msgid "calling %s"
+msgstr "volám %s"
+
+#. always scroll up, don't overwrite
+#, c-format
+msgid "continuing in %s"
+msgstr "pokraèuji v %s"
+
+msgid "E133: :return not inside a function"
+msgstr "E133: :return mimo funkci"
+
+#, c-format
+msgid "%s returning #%ld"
+msgstr "dokonèeno provádìní %s. Návratová hodnota #%ld"
+
+#, c-format
+msgid "%s returning \"%s\""
+msgstr "dokonèeno provádìní %s. Návratová hodnota \"%s\""
+
+msgid ""
+"\n"
+"# global variables:\n"
+msgstr ""
+"\n"
+"# globální promìnné:\n"
+
+#, c-format
+msgid "<%s>%s%s %d, Hex %02x, Octal %03o"
+msgstr "<%s>%s%s %d, ¹estnáctkovì %02x, osmièkovì %03o"
+
+msgid "E134: Move lines into themselves"
+msgstr "E134: Nelze pøesunout øádky na pùvodní místo"
+
+msgid "1 line moved"
+msgstr "poèet pøesunutých øádkù: 1"
+
+#, c-format
+msgid "%ld lines moved"
+msgstr "Poèet pøesunutých øádkù: %ld"
+
+#, c-format
+msgid "%ld lines filtered"
+msgstr "Poèet filtrovaných øádkù: %ld"
+
+msgid "E135: *Filter* Autocommands must not change current buffer"
+msgstr "E135: Automatické pøíkazy *Filter* nesmí mìnit aktuální buffer"
+
+msgid "[No write since last change]\n"
+msgstr "[Neulo¾ené zmìny]\n"
+
+#, c-format
+msgid "viminfo: %s in line: "
+msgstr "viminfo: %s na øádku: "
+
+msgid "E136: viminfo: Too many errors, skipping rest of file"
+msgstr "E136: viminfo: pøíli¹ mnoho chyb, pøeskakuji zbytek souboru"
+
+#, c-format
+msgid "Reading viminfo file \"%s\"%s%s%s"
+msgstr "Ètu viminfo soubor \"%s\"%s%s%s"
+
+msgid " info"
+msgstr " informace"
+
+msgid " marks"
+msgstr " znaèky"
+
+msgid " FAILED"
+msgstr " se nezdaøilo"
+
+#, c-format
+msgid "E137: Viminfo file is not writable: %s"
+msgstr "E137: do viminfo souboru %s nelze zapisovat"
+
+#, c-format
+msgid "E138: Can't write viminfo file %s!"
+msgstr "E138: Nelze ulo¾it viminfo soubor %s!"
+
+#, c-format
+msgid "Writing viminfo file \"%s\""
+msgstr "Ukládám viminfo souboru \"%s\""
+
+#. Write the info:
+msgid "# This viminfo file was generated by Vim %s.\n"
+msgstr "# Tento viminfo soubor byl vytvoøen editorem Vim %s.\n"
+
+msgid ""
+"# You may edit it if you're careful!\n"
+"\n"
+msgstr ""
+"# Pokud budete opatrný, mù¾ete jej upravovat.\n"
+"\n"
+
+msgid "# Value of 'encoding' when this file was written\n"
+msgstr "# Hodnota volby 'encoding' v dobì ulo¾ení tohoto souboru\n"
+
+msgid "Illegal starting char"
+msgstr "Nepøípustný poèáteèní znak"
+
+msgid "Save As"
+msgstr "Ulo¾it jako"
+
+#. Overwriting a file that is loaded in another buffer is not a
+#. * good idea.
+msgid "E139: File is loaded in another buffer"
+msgstr "E139: Soubor je nahrán v jiném bufferu"
+
+msgid "Write partial file?"
+msgstr "Ulo¾it neúplný soubor?"
+
+msgid "E140: Use ! to write partial buffer"
+msgstr "E140: Pou¾ijte ! pro ulo¾ení neúplného bufferu"
+
+#, c-format
+msgid "Overwrite existing file \"%.*s\"?"
+msgstr "Pøepsat soubor \"%.*s\"?"
+
+#, c-format
+msgid "E141: No file name for buffer %ld"
+msgstr "E141: ®ádný název souboru pro buffer %ld"
+
+msgid "E142: File not written: Writing is disabled by 'write' option"
+msgstr "E142: Soubor nebyl ulo¾en: Ukládání je zakázáno volbou 'write'"
+
+#, c-format
+msgid ""
+"'readonly' option is set for \"%.*s\".\n"
+"Do you wish to write anyway?"
+msgstr ""
+"Pro \"%.*s\" je nastavena volba 'readonly'.\n"
+"Pøejete si ji potlaèit?"
+
+msgid "Edit File"
+msgstr "Editovat soubor"
+
+#, c-format
+msgid "E143: Autocommands unexpectedly deleted new buffer %s"
+msgstr "E143: Automatické pøíkazy neoèekávanì smazaly nový buffer %s"
+
+msgid "E144: non-numeric argument to :z"
+msgstr "E144: neèíselný argument pro :z"
+
+msgid "E145: Shell commands not allowed in rvim"
+msgstr "E145: rvim nepovoluje pou¾ití pøíkazù shellu"
+
+msgid "E146: Regular expressions can't be delimited by letters"
+msgstr "E146: Regulární výrazy nesmí být oddìleny písmeny"
+
+#, c-format
+msgid "replace with %s (y/n/a/q/l/^E/^Y)?"
+msgstr "nahradit za %s (y/n/a/q/l/^E/^Y)?"
+
+msgid "(Interrupted) "
+msgstr "(Pøeru¹eno) "
+
+msgid "1 substitution"
+msgstr "1 nahrazení"
+
+#, c-format
+msgid "%ld substitutions"
+msgstr "%ld nahrazení"
+
+msgid " on 1 line"
+msgstr " na jednom øádku"
+
+#, c-format
+msgid " on %ld lines"
+msgstr " na %ld øádcích"
+
+msgid "E147: Cannot do :global recursive"
+msgstr "E147: :global nelze volat rekurzivnì"
+
+msgid "E148: Regular expression missing from global"
+msgstr "E148: U pøíkazu 'global' chybí regulární výraz"
+
+#, c-format
+msgid "Pattern found in every line: %s"
+msgstr "Vzor nalezen na ka¾dém øádku: %s"
+
+msgid ""
+"\n"
+"# Last Substitute String:\n"
+"$"
+msgstr ""
+"\n"
+"# Poslední nahrazující øetìzec:\n"
+"$"
+
+#, c-format
+msgid "E149: Sorry, no help for %s"
+msgstr "E149: Lituji, pro %s není ¾ádná nápovìda"
+
+#, c-format
+msgid "Sorry, help file \"%s\" not found"
+msgstr "Lituji, soubor \"%s\" s nápovìdou nebyl nalezen"
+
+#, c-format
+msgid "E150: Not a directory: %s"
+msgstr "E150: %s není adresáøem"
+
+#, c-format
+msgid "E152: Cannot open %s for writing"
+msgstr "E152: Nelze otevøít %s pro zápis"
+
+#, c-format
+msgid "E153: Unable to open %s for reading"
+msgstr "E153: Nelze otevøít %s pro zápis"
+
+#, c-format
+msgid "E154: Duplicate tag \"%s\" in file %s"
+msgstr "E154: Duplicitní tag \"%s\" v souboru %s"
+
+#, c-format
+msgid "E160: Unknown sign command: %s"
+msgstr "E160: Neznámá volba pøíkazu: %s"
+
+msgid "E156: Missing sign name"
+msgstr "E156: Chybí jméno volby"
+
+msgid "E255: Too many signs defined"
+msgstr "E255: Nastaveno pøíli¹ mnoho voleb"
+
+#, c-format
+msgid "E239: Invalid sign text: %s"
+msgstr "E239: Neplatný text volby: %s"
+
+#, c-format
+msgid "E155: Unknown sign: %s"
+msgstr "E155: Neznámá volba: %s"
+
+msgid "E159: Missing sign number"
+msgstr "E159: Chybí identifikátor volby"
+
+#, c-format
+msgid "E158: Invalid buffer name: %s"
+msgstr "E158: chybné jméno bufferu: %s"
+
+#, c-format
+msgid "E157: Invalid sign ID: %ld"
+msgstr "E157: Chybné ID volby: %ld"
+
+msgid "[Deleted]"
+msgstr "[Vymazáno]"
+
+msgid "Entering Debug mode. Type \"cont\" to leave."
+msgstr "Spou¹tím ladící re¾im. Pro ukonèení napi¹te \"cont\"."
+
+#, c-format
+msgid "line %ld: %s"
+msgstr "øádek %ld: %s"
+
+#, c-format
+msgid "cmd: %s"
+msgstr "pøíkaz: %s"
+
+#, c-format
+msgid "Breakpoint in \"%s%s\" line %ld"
+msgstr "Bod pøeru¹ení v \"%s%s\" na øádku %ld"
+
+#, c-format
+msgid "E161: Breakpoint not found: %s"
+msgstr "E161: Bod pøeru¹ení nenalezen: %s"
+
+msgid "No breakpoints defined"
+msgstr "Nebyly definovánu ¾ádné body pøeru¹ení"
+
+#, c-format
+msgid "%3d %s %s line %ld"
+msgstr "%3d %s %s øádek %ld"
+
+#, c-format
+msgid "Save changes to \"%.*s\"?"
+msgstr "Ulo¾it zmìny do \"%.*s\"?"
+
+msgid "Untitled"
+msgstr "Nepojmenováno"
+
+#, c-format
+msgid "E162: No write since last change for buffer \"%s\""
+msgstr "E162: Buffer \"%s\" obsahuje neulo¾ené zmìny"
+
+msgid "Warning: Entered other buffer unexpectedly (check autocommands)"
+msgstr ""
+"Varování: Neèekaný vstup do jiného bufferu (zkontrolujte automatické pøíkazy)"
+
+msgid "E163: There is only one file to edit"
+msgstr "E163: Pro editaci byl zadán pouze jeden soubor"
+
+msgid "E164: Cannot go before first file"
+msgstr "E164: Pøed první soubor nelze pøeskoèit"
+
+msgid "E165: Cannot go beyond last file"
+msgstr "E165: Za poslední soubor nelze pøeskoèit"
+
+#, c-format
+msgid "Searching for \"%s\" in \"%s\""
+msgstr "Hledám \"%s\" v \"%s\""
+
+#, c-format
+msgid "Searching for \"%s\""
+msgstr "Hledám \"%s\""
+
+#, c-format
+msgid "not found in 'runtimepath': \"%s\""
+msgstr "soubor \"%s\" nebyl nalezen v 'runtimepath'"
+
+msgid "Run Macro"
+msgstr "Spustit makro"
+
+#, c-format
+msgid "Cannot source a directory: \"%s\""
+msgstr "nelze interpretovat adresáø: \"%s\""
+
+#, c-format
+msgid "could not source \"%s\""
+msgstr "nelze interpretovat \"%s\""
+
+#, c-format
+msgid "line %ld: could not source \"%s\""
+msgstr "øádek %ld: nelze interpretovat \"%s\""
+
+#, c-format
+msgid "sourcing \"%s\""
+msgstr "interpretuji \"%s\""
+
+#, c-format
+msgid "line %ld: sourcing \"%s\""
+msgstr "øádek %ld: interpretuji %s"
+
+#, c-format
+msgid "finished sourcing %s"
+msgstr "dokonèena interpretace %s"
+
+msgid "W15: Warning: Wrong line separator, ^M may be missing"
+msgstr "W15: Varování: chybný oddìlovaè øádkù. Mo¾ná chybí ^M."
+
+msgid "E167: :scriptencoding used outside of a sourced file"
+msgstr "E167: :scriptencoding pou¾ito mimo interpretovaný soubor"
+
+msgid "E168: :finish used outside of a sourced file"
+msgstr "E168: :finish pou¾ito mimo interpretovaný soubor"
+
+msgid "No text to be printed"
+msgstr "®ádný text k vyti¹tìní"
+
+msgid "Printing page %d (%d%%)"
+msgstr "Tisknu stranu %d (%d%%)"
+
+#, c-format
+msgid " Copy %d of %d"
+msgstr " Kopie %d z %d"
+
+#, c-format
+msgid "Printed: %s"
+msgstr "Vyti¹tìno: %s"
+
+msgid "Printing aborted"
+msgstr "Tisk zru¹en"
+
+msgid "E455: Error writing to PostScript output file"
+msgstr "E455: Nelze zapisovat do výstupního PostScriptového souboru"
+
+msgid "E324: Can't open PostScript output file"
+msgstr "E324: Nelze otevøít výstupní PostScriptový soubor"
+
+msgid "E456: Can't open file \"%s\""
+msgstr "E456: Nelze otevøít soubor \"%s\""
+
+msgid "E457: Can't read PostScript resource file \"%s\""
+msgstr "E457: Nelze èíst zdrojový PostScriptový soubor \"%s\""
+
+msgid "Sending to printer..."
+msgstr "Odesílám na tiskárnu..."
+
+msgid "E365: Failed to print PostScript file"
+msgstr "E365: Selhal tisk PostScriptového souboru"
+
+msgid "Print job sent."
+msgstr "Tisková úloha odeslána."
+
+#, c-format
+msgid "Current %slanguage: \"%s\""
+msgstr "Aktuální %sjazyk: \"%s\""
+
+#, c-format
+msgid "E197: Cannot set language to \"%s\""
+msgstr "E197: Nelze nastavit jazyk na \"%s\""
+
+msgid "Entering Ex mode. Type \"visual\" to go to Normal mode."
+msgstr "Spou¹tím Ex mód. Napi¹te \"visual\" pro návrat do normálního módu."
+
+#. must be at EOF
+msgid "At end-of-file"
+msgstr "Konec souboru"
+
+msgid "E169: Command too recursive"
+msgstr "E169: Pøíkaz je pøíli¹ rekurzivní"
+
+msgid "E170: Missing :endwhile"
+msgstr "E170: Chybí :endwhile"
+
+msgid "E171: Missing :endif"
+msgstr "E171: Chybí :endif"
+
+msgid "End of sourced file"
+msgstr "Konec interpretovaného souboru"
+
+msgid "End of function"
+msgstr "Konec funkce"
+
+msgid "Ambiguous use of user-defined command"
+msgstr "Nejednoznaèné pou¾ití u¾ivatelsky definovaného pøíkazu"
+
+msgid "Not an editor command"
+msgstr "Není pøíkazem editoru"
+
+msgid "Don't panic!"
+msgstr "Nepanikaøte!"
+
+msgid "Backwards range given"
+msgstr "Zadán zpìtný rozsah"
+
+msgid "Backwards range given, OK to swap"
+msgstr "Zadán zpìtný rozsah. Prohodit hranice"
+
+msgid "Use w or w>>"
+msgstr "Pou¾ijte w èi w>>"
+
+msgid "E319: Sorry, the command is not available in this version"
+msgstr "E319: Pøíkaz není této verzi bohu¾el implementován"
+
+msgid "E172: Only one file name allowed"
+msgstr "E172: Pøípustný je pouze jeden název souboru"
+
+#, c-format
+msgid "%d more files to edit. Quit anyway?"
+msgstr "Je¹tì zbývají soubory k editaci (%d). Chcete pøesto ukonèit editor?"
+
+#, c-format
+msgid "E173: %ld more files to edit"
+msgstr "E173: Je¹tì zbývají soubory k editaci (%ld)."
+
+msgid "E174: Command already exists: use ! to redefine"
+msgstr "E174: Pøíkaz ji¾ existuje: pou¾ijte ! pro pøedefinování"
+
+msgid ""
+"\n"
+" Name Args Range Complete Definition"
+msgstr ""
+"\n"
+" Jméno Args Rozsah Úplnost Definice"
+
+msgid "No user-defined commands found"
+msgstr "Nebyly nalezeny ¾ádné u¾ivatelsky definované pøíkazy"
+
+msgid "E175: No attribute specified"
+msgstr "E175: Nebyly zadány ¾ádné atributy"
+
+msgid "E176: Invalid number of arguments"
+msgstr "E176: Chybný poèet argumentù"
+
+msgid "E177: Count cannot be specified twice"
+msgstr "E177: Opakování nemù¾e být zadáno dvakrát"
+
+msgid "E178: Invalid default value for count"
+msgstr "E178: Chybná implicitní hodnota pro poèet"
+
+msgid "E179: argument required for complete"
+msgstr "E179: chybná implicitní hodnota pro opakování"
+
+#, c-format
+msgid "E180: Invalid complete value: %s"
+msgstr "E180: Chybná hodnota doplnìní: %s"
+
+#, c-format
+msgid "E181: Invalid attribute: %s"
+msgstr "E181: Chybný atribut: %s"
+
+msgid "E182: Invalid command name"
+msgstr "E182: Chybné jméno pøíkazu"
+
+msgid "E183: User defined commands must start with an uppercase letter"
+msgstr "E183: U¾ivatelsky definované pøíkazy musí zaèínat velikým písmenem."
+
+#, c-format
+msgid "E184: No such user-defined command: %s"
+msgstr "E184: U¾ivatelsky definovaný pøíkaz %s neexistuje"
+
+#, c-format
+msgid "E185: Cannot find color scheme %s"
+msgstr "E185: Nelze nalézt barevné schéma %s"
+
+msgid "Greetings, Vim user!"
+msgstr "Blahopøeji, u¾ivateli Vimu!"
+
+msgid "Edit File in new window"
+msgstr "Editovat soubor v novém oknì"
+
+msgid "No swap file"
+msgstr "®ádný odkládací soubor"
+
+msgid "Append File"
+msgstr "Ulo¾it soubor"
+
+msgid "E186: No previous directory"
+msgstr "E186: ®ádný pøedchozí adresáø"
+
+msgid "E187: Unknown"
+msgstr "E187: Neznámý"
+
+#, c-format
+msgid "Window position: X %d, Y %d"
+msgstr "Umístìní okna: X %d, Y %d"
+
+msgid "E188: Obtaining window position not implemented for this platform"
+msgstr "E188: Na této platformì nelze umístìní okna zjistit"
+
+msgid "Save Redirection"
+msgstr "Ulo¾it pøesmìrování"
+
+msgid "Save View"
+msgstr "Ulo¾it pohled"
+
+msgid "Save Session"
+msgstr "Ulo¾it sezení"
+
+msgid "Save Setup"
+msgstr "Ulo¾it nastavení"
+
+#, c-format
+msgid "E189: \"%s\" exists (use ! to override)"
+msgstr "E189: \"%s\" existuje (pou¾ijte ! pro vynucení)"
+
+#, c-format
+msgid "E190: Cannot open \"%s\" for writing"
+msgstr "E190: Nelze otevøít \"%s\" pro zápis"
+
+#. set mark
+msgid "E191: Argument must be a letter or forward/backward quote"
+msgstr "E191: Argumentem mù¾e být pouze písmeno nebo pravý èi levý apostrof"
+
+msgid "E192: Recursive use of :normal too deep"
+msgstr "E192: Vnoøení :normal je pøíli¹ hluboké"
+
+msgid ":if nesting too deep"
+msgstr "vnoøení :if je pøíli¹ hluboké"
+
+msgid ":endif without :if"
+msgstr ":endif bez odpovídajícího :if"
+
+msgid ":else without :if"
+msgstr ":else bez odpovídajícího :if"
+
+msgid ":elseif without :if"
+msgstr ":elseif bez odpovídajícího :if"
+
+msgid ":while nesting too deep"
+msgstr "vnoøení :while je pøíli¹ hluboké"
+
+msgid ":continue without :while"
+msgstr ":continue bez odpovídajícího :while"
+
+msgid ":break without :while"
+msgstr ":break bez odpovídajícího :while"
+
+msgid ":endwhile without :while"
+msgstr ":endwhile bez odpovídajícího :while"
+
+msgid "E193: :endfunction not inside a function"
+msgstr "E193: :endfunction mimo funkci"
+
+msgid "E194: No alternate file name to substitute for '#'"
+msgstr ""
+"E194: ®ádný alternativní název souboru, kterým by bylo mo¾né nahradit '#'"
+
+msgid "no autocommand file name to substitute for \"<afile>\""
+msgstr "®ádný název souboru, kterým by bylo mo¾né nahradit \"<afile>\""
+
+msgid "no autocommand buffer number to substitute for \"<abuf>\""
+msgstr "®ádné èíslo bufferu, kterým by bylo mo¾né nahradit \"<abuf>\""
+
+msgid "no autocommand match name to substitute for \"<amatch>\""
+msgstr ""
+"®ádná shoda automatických pøíkazù, kterou by bylo mo¾né nahradit \"<amatch>\""
+
+msgid "no :source file name to substitute for \"<sfile>\""
+msgstr "®ádný interpretovaný soubor, kterým by bylo mo¾né nahradit \"<sfile>\""
+
+#, no-c-format
+msgid "Empty file name for '%' or '#', only works with \":p:h\""
+msgstr "Prázdný název souboru pro '%' èi '#' funguje pouze s \":p:h\""
+
+msgid "Evaluates to an empty string"
+msgstr "Výsledkem vyhodnocení je prázdný øetìzec"
+
+msgid "E195: Cannot open viminfo file for reading"
+msgstr "E195: Nelze otevøít pro ètení viminfo soubor"
+
+msgid "E196: No digraphs in this version"
+msgstr "E196: V této verzi nejsou spøe¾ky podporovány"
+
+msgid "tagname"
+msgstr "jméno tagu"
+
+msgid " kind file\n"
+msgstr " typ soubor\n"
+
+msgid "'history' option is zero"
+msgstr "'volba 'history' je nastavena na nulu"
+
+#, c-format
+msgid ""
+"\n"
+"# %s History (newest to oldest):\n"
+msgstr ""
+"\n"
+"# Historie %s (poèínaje nejnovìj¹í polo¾kou):\n"
+
+msgid "Command Line"
+msgstr "pøíkazové øádky"
+
+msgid "Search String"
+msgstr "vyhledávaných øetìzcù"
+
+msgid "Expression"
+msgstr "výrazù"
+
+msgid "Input Line"
+msgstr "vstupní øádky"
+
+msgid "E198: cmd_pchar beyond the command length"
+msgstr "E198: cmd_pchar pøekraèuje délku pøíkazu"
+
+msgid "E199: Active window or buffer deleted"
+msgstr "E199: Smazáno aktivní okno èi buffer"
+
+msgid "Illegal file name"
+msgstr "nepøípustný název souboru"
+
+msgid "is a directory"
+msgstr "je adresáøem"
+
+msgid "is not a file"
+msgstr "není souborem"
+
+msgid "[New File]"
+msgstr "[nový soubor]"
+
+msgid "[Permission Denied]"
+msgstr "[pøístup odmítnut]"
+
+msgid "E200: *ReadPre autocommands made the file unreadable"
+msgstr "E200: *ReadPre automatické pøíkazy uèinily soubor neèitelným"
+
+msgid "E201: *ReadPre autocommands must not change current buffer"
+msgstr "E201: *ReadPre automatické pøíkazy nesmí mìnit aktuální buffer"
+
+msgid "Vim: Reading from stdin...\n"
+msgstr "Vim: Ètu ze standardního vstupu...\n"
+
+msgid "Reading from stdin..."
+msgstr "Ètu ze standardního vstupu..."
+
+#. Re-opening the original file failed!
+msgid "E202: Conversion made file unreadable!"
+msgstr "E202: Po konverzi je soubor neèitelný!"
+
+msgid "[fifo/socket]"
+msgstr "[pojmenovaná roura/soket]"
+
+msgid "[fifo]"
+msgstr "[pojmenovaná roura]"
+
+msgid "[socket]"
+msgstr "[soket]"
+
+msgid "[RO]"
+msgstr "[RO]"
+
+msgid "[CR missing]"
+msgstr "[chybí CR]"
+
+msgid "[NL found]"
+msgstr "[nalezeno NL]"
+
+msgid "[long lines split]"
+msgstr "[dlouhé øádky zalomeny]"
+
+msgid "[NOT converted]"
+msgstr "[nezkonvertován]"
+
+msgid "[converted]"
+msgstr "[zkonvertován]"
+
+msgid "[crypted]"
+msgstr "[za¹ifrován]"
+
+msgid "[CONVERSION ERROR]"
+msgstr "[CHYBA PØEVODU]"
+
+msgid "[READ ERRORS]"
+msgstr "[CHYBY ÈTENÍ]"
+
+msgid "Can't find temp file for conversion"
+msgstr "Nelze nalézt doèasný soubor pro konverzi"
+
+msgid "Conversion with 'charconvert' failed"
+msgstr "Konverze s 'charconvert' se nezdaøila"
+
+msgid "can't read output of 'charconvert'"
+msgstr "nelze èíst výstup 'charconvert'"
+
+msgid "E203: Autocommands deleted or unloaded buffer to be written"
+msgstr ""
+"E203: Automatické pøíkazy smazaly èi deaktivovaly buffer, který mìl být "
+"ulo¾en"
+
+msgid "E204: Autocommand changed number of lines in unexpected way"
+msgstr "E204: Automatický pøíkaz neèekaným zpùsobem zmìnil poèet øádkù"
+
+msgid "is not a file or writable device"
+msgstr "není souborem ani zaøízením na nì¾ lze zapisovat"
+
+msgid "is read-only (use ! to override)"
+msgstr "je pouze pro ètení (pou¾ijte ! pro vynucení)"
+
+msgid "Can't write to backup file (use ! to override)"
+msgstr "Nelze zapisovat do zálo¾ního souboru (pou¾ijte ! pro vynucení)"
+
+msgid "Close error for backup file (use ! to override)"
+msgstr "Chyba pøi uzavírání zálo¾ního souboru (pou¾ijte ! pro vynucení)"
+
+msgid "Can't read file for backup (use ! to override)"
+msgstr "Nelze naèíst soubor pro zálohu (pou¾ijte ! pro vynucení)"
+
+msgid "Cannot create backup file (use ! to override)"
+msgstr "Nelze vytvoøit zálo¾ní soubor (pou¾ijte ! pro vynucení)"
+
+msgid "Can't make backup file (use ! to override)"
+msgstr "Nelze vytvoøit zálo¾ní soubor (pou¾ijte ! pro vynucení)"
+
+# resource fork ?!
+msgid "The resource fork will be lost (use ! to override)"
+msgstr "'Resource fork' bude ztracen (pou¾ijte ! pro vynucení)"
+
+msgid "E214: Can't find temp file for writing"
+msgstr "E214: Nelze najít doèasný temp soubor pro zápis"
+
+msgid "E213: Cannot convert (use ! to write without conversion)"
+msgstr "E213: Nelze pøevést (pou¾ijte ! pro zápis bez pøevodu)"
+
+msgid "E166: Can't open linked file for writing"
+msgstr "E166: Nelze otevøít pøipojený soubor pro zápis"
+
+msgid "E212: Can't open file for writing"
+msgstr "E212: Nelze otevøít soubor pro zápis"
+
+msgid "Close failed"
+msgstr "Volání close selhalo"
+
+msgid "write error, conversion failed"
+msgstr "chyba pøi zápisu, konverze se nezdaøila"
+
+msgid "write error (file system full?)"
+msgstr "chyba pøi ukládání (je volné místo na disku?)"
+
+msgid " CONVERSION ERROR"
+msgstr " CHYBA PØEVODU"
+
+msgid "[Device]"
+msgstr "[zaøízení]"
+
+msgid "[New]"
+msgstr "[Nový]"
+
+msgid " [a]"
+msgstr " [p]"
+
+msgid " appended"
+msgstr " pøipojen"
+
+msgid " [w]"
+msgstr " [u]"
+
+msgid " written"
+msgstr " ulo¾en"
+
+msgid "E205: Patchmode: can't save original file"
+msgstr "E205: patchmode: nelze ulo¾it pùvodní soubor"
+
+msgid "E206: patchmode: can't touch empty original file"
+msgstr "E206: patchmode: nelze zapisovat do prázdného pùvodního souboru"
+
+msgid "E207: Can't delete backup file"
+msgstr "E207: Nelze smazat zálo¾ní soubor"
+
+msgid ""
+"\n"
+"WARNING: Original file may be lost or damaged\n"
+msgstr ""
+"\n"
+"VAROVÁNÍ: Obsah pùvodního souboru mù¾e být ztracen èi po¹kozen\n"
+
+msgid "don't quit the editor until the file is successfully written!"
+msgstr "neukonèujte editor døíve, ne¾ bude soubor úspì¹nì ulo¾en!"
+
+msgid "[dos]"
+msgstr "[dos]"
+
+msgid "[dos format]"
+msgstr "[dos formát]"
+
+msgid "[mac]"
+msgstr "[mac]"
+
+msgid "[mac format]"
+msgstr "[mac formát]"
+
+msgid "[unix]"
+msgstr "[unix]"
+
+msgid "[unix format]"
+msgstr "[unix formát]"
+
+msgid "1 line, "
+msgstr "1 øádek, "
+
+#, c-format
+msgid "%ld lines, "
+msgstr "%ld øádkù, "
+
+msgid "1 character"
+msgstr "1 znak"
+
+#, c-format
+msgid "%ld characters"
+msgstr "%ld znakù, "
+
+msgid "[noeol]"
+msgstr "[¾ádný eol]"
+
+msgid "[Incomplete last line]"
+msgstr "[neúplný poslední øádek]"
+
+#. 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 "VAROVÁNÍ: od jeho naètení byl obsah souboru zmìnìn!!!!"
+
+msgid "Do you really want to write to it"
+msgstr "Chcete jej opravdu ulo¾it"
+
+#, c-format
+msgid "E208: Error writing to \"%s\""
+msgstr "E208: Chyba pøi zápisu do \"%s\""
+
+#, c-format
+msgid "E209: Error closing \"%s\""
+msgstr "E209: Chyb pøi uzavírání \"%s\""
+
+#, c-format
+msgid "E210: Error reading \"%s\""
+msgstr "E210: Chyba pøi ètení \"%s\""
+
+msgid "E246: FileChangedShell autocommand deleted buffer"
+msgstr "E246: FileChangedShell autocommand zru¹il buffer"
+
+#, c-format
+msgid "E211: Warning: File \"%s\" no longer available"
+msgstr "E211: wa1: soubor \"%s\" ji¾ není dostupný"
+
+#, c-format
+msgid ""
+"W12: Warning: File \"%s\" has changed and the buffer was changed in Vim as "
+"well"
+msgstr ""
+"W12: Varování: soubor \"%s\" byl po poèátku editace zmìnìn a buffer ve Vim "
+"také"
+
+#, c-format
+msgid "W11: Warning: File \"%s\" has changed since editing started"
+msgstr "W11: wc2: soubor \"%s\" byl po poèátku editace zmìnìn"
+
+#, c-format
+msgid "W16: Warning: Mode of file \"%s\" has changed since editing started"
+msgstr "W16: Varování: Mód souboru \"%s\" byl zmìnìn od zapoènutí editace"
+
+#, c-format
+msgid "W13: Warning: File \"%s\" has been created after editing started"
+msgstr "W13: wc4: po poèátku editace vytvoøen soubor \"%s\""
+
+msgid "Warning"
+msgstr "Varování"
+
+msgid ""
+"&OK\n"
+"&Load File"
+msgstr ""
+"&OK\n"
+"&Nahrát soubor"
+
+#, c-format
+msgid "E321: Could not reload \"%s\""
+msgstr "E321: Nelze znovuotevøít \"%s\""
+
+msgid "--Deleted--"
+msgstr "--Vymazáno--"
+
+#. the group doesn't exist
+#, c-format
+msgid "E367: No such group: \"%s\""
+msgstr "E367: Skupina \"%s\" neexistuje"
+
+#, c-format
+msgid "E215: Illegal character after *: %s"
+msgstr "E215: Nepøípustný znak po *: %s"
+
+#, c-format
+msgid "E216: No such event: %s"
+msgstr "E216: Událost %s neexistuje"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Auto-Commands ---"
+msgstr ""
+"\n"
+"--- Automatické pøíkazy ---"
+
+msgid "E217: Can't execute autocommands for ALL events"
+msgstr "E217: Automatické pøíkazy nelze spustit pro V©ECHNY události"
+
+msgid "No matching autocommands"
+msgstr "®ádné vyhovující automatické pøíkazy"
+
+msgid "E218: autocommand nesting too deep"
+msgstr "E218: vnoøení automatického pøíkazu pøíli¹ hluboká"
+
+#, c-format
+msgid "%s Auto commands for \"%s\""
+msgstr "%s automatické pøíkazy pro \"%s\""
+
+#, c-format
+msgid "Executing %s"
+msgstr "spou¹tím %s"
+
+#. always scroll up, don't overwrite
+#, c-format
+msgid "autocommand %s"
+msgstr "Automatický pøíkaz %s"
+
+msgid "E219: Missing {."
+msgstr "E219: Chybí {."
+
+msgid "E220: Missing }."
+msgstr "E220: Chybí }."
+
+msgid "No fold found"
+msgstr "®ádný záhyb nebyl nalezen"
+
+msgid "E350: Cannot create fold with current 'foldmethod'"
+msgstr "E350: pomocí aktuální 'foldmethod' nelze vytvoøit záhyb"
+
+msgid "E351: Cannot delete fold with current 'foldmethod'"
+msgstr "E351: pomocí aktuální 'foldmethod' nelze vytvoøit záhyb"
+
+msgid "E221: 'commentstring' is empty"
+msgstr "E221: volba 'commentstring' je prázdná"
+
+msgid "E222: Add to read buffer"
+msgstr "E222: Pøidat do bufferu pro ètení"
+
+msgid "E223: recursive mapping"
+msgstr "E223: rekurzivní mapování"
+
+#, c-format
+msgid "E224: global abbreviation already exists for %s"
+msgstr "E224: pro %s ji¾ globální zkratka ji¾ existuje"
+
+#, c-format
+msgid "E225: global mapping already exists for %s"
+msgstr "E225: pro %s ji¾ globální mapování ji¾ existuje"
+
+#, c-format
+msgid "E226: abbreviation already exists for %s"
+msgstr "E226: pro %s ji¾ zkratka ji¾ existuje"
+
+#, c-format
+msgid "E227: mapping already exists for %s"
+msgstr "E227: pro %s ji¾ mapování ji¾ existuje"
+
+msgid "No abbreviation found"
+msgstr "®ádná zkratka nebyl nalezena"
+
+msgid "No mapping found"
+msgstr "®ádné mapování nebylo nalezeno"
+
+msgid "E228: makemap: Illegal mode"
+msgstr "E228: makemap: nepøípustný mód"
+
+msgid "E229: Cannot start the GUI"
+msgstr "E229: Nelze spustit GUI"
+
+#, c-format
+msgid "E230: Cannot read from \"%s\""
+msgstr "E230: Nelze èíst z \"%s\""
+
+msgid "E231: 'guifontwide' invalid"
+msgstr "E231: volba 'guifontwide' je chybnì nastavena"
+
+msgid "Error"
+msgstr "Chyba"
+
+msgid "&Ok"
+msgstr "&Ok"
+
+msgid "<cannot open> "
+msgstr "<nelze otevøít> "
+
+#, c-format
+msgid "vim_SelFile: can't get font %s"
+msgstr "vim_SelFile: písmo %s není dostupné"
+
+msgid "vim_SelFile: can't return to current directory"
+msgstr "vim_SelFile: nelze se vrátit do aktuálního adresáøe"
+
+msgid "Pathname:"
+msgstr "Název cesty:"
+
+msgid "vim_SelFile: can't get current directory"
+msgstr "vim_SelFile: nelze zjistit aktuální adresáø"
+
+msgid "OK"
+msgstr "OK"
+
+#. 'Cancel' button
+msgid "Cancel"
+msgstr "Zru¹it"
+
+msgid "Scrollbar Widget: Could not get geometry of thumb pixmap."
+msgstr "Pøípravek posunovací li¹ty: nelze zjistit geometrii obrázku"
+
+msgid "Vim dialog"
+msgstr "Vim dialog"
+
+msgid "E232: Cannot create BalloonEval with both message and callback"
+msgstr "E232: BalloonEval nelze vytvoøit se zprávou a zároveò zpìtným voláním"
+
+msgid "Vim dialog..."
+msgstr "Vim dialog.."
+
+msgid "VIM - Search and Replace..."
+msgstr "VIM - Nalézt a nahradit..."
+
+msgid "VIM - Search..."
+msgstr "VIM - Nalézt..."
+
+msgid "Find what:"
+msgstr "Vyhledat:"
+
+msgid "Replace with:"
+msgstr "Nový text:"
+
+#. exact match only button
+msgid "Match exact word only"
+msgstr "hledat pouze celá slova"
+
+msgid "Direction"
+msgstr "Smìr"
+
+#. 'Up' and 'Down' buttons
+msgid "Up"
+msgstr "Nahoru"
+
+msgid "Down"
+msgstr "Dolù"
+
+#. 'Find Next' button
+msgid "Find Next"
+msgstr "Najít dal¹í"
+
+#. 'Replace' button
+msgid "Replace"
+msgstr "Nahradit"
+
+#. 'Replace All' button
+msgid "Replace All"
+msgstr "Nahradit v¹e"
+
+msgid "E233: cannot open display"
+msgstr "E233: nelze otevøít display"
+
+#, c-format
+msgid "E234: Unknown fontset: %s"
+msgstr "E234: Neznámá sada písem: %s"
+
+msgid "Font Selection"
+msgstr "Výbìr písma"
+
+#, c-format
+msgid "E235: Unknown font: %s"
+msgstr "E235: Neznámé písmo: %s"
+
+#, c-format
+msgid "E236: Font \"%s\" is not fixed-width"
+msgstr "E236: Písmo \"%s\" nemá pevnou ¹íøku"
+
+#, c-format
+msgid "E242: Color name not recognized: %s"
+msgstr "E242: Neznámé jméno barvy: %s"
+
+msgid "Used CUT_BUFFER0 instead of empty selection"
+msgstr "Místo prádné schránky pou¾ito CUT_BUFFER0"
+
+msgid "Filter"
+msgstr "Filtr"
+
+msgid "Directories"
+msgstr "Adresáøe"
+
+msgid "Help"
+msgstr "Nápovìda"
+
+msgid "Files"
+msgstr "Soubory"
+
+msgid "Selection"
+msgstr "Výbìr"
+
+msgid "Undo"
+msgstr "Zpìt"
+
+#, c-format
+msgid "E235: Can't load Zap font '%s'"
+msgstr "E235: Nelze naèíst Zap font '%s'"
+
+#, c-format
+msgid "E235: Can't use font %s"
+msgstr "E235: Nelze pou¾ít font %s"
+
+#, c-format
+msgid "E242: Missing color: %s"
+msgstr "E242: Chybí barva: %s"
+
+msgid ""
+"\n"
+"Sending message to terminate child process.\n"
+msgstr ""
+"\n"
+"Posílám signál k ukonèení synovského procesu.\n"
+
+#, c-format
+msgid "E243: Argument not supported: \"-%s\"; Use the OLE version."
+msgstr "E243: Argument nepodporován: \"-%s\"; Pou¾ijte OLE verzi."
+
+msgid "Find string (use '\\\\' to find a '\\')"
+msgstr "Najít øetìzec (pou¾ijte '\\\\' k nalezení '\\')"
+
+msgid "Find & Replace (use '\\\\' to find a '\\')"
+msgstr "Najít & Nahradit (pou¾ijte '\\\\' k nalezení '\\')"
+
+msgid "Vim E458: Cannot allocate colormap entry, some colors may be incorrect"
+msgstr ""
+"Vim E458: nelze alokovat polo¾ku barevné mapy. Nìkteré barvy mohou být "
+"nesprávné"
+
+#, c-format
+msgid "E250: Fonts for the following charsets are missing in fontset %s:"
+msgstr "E250: písma pro následující znakové sady chybí v sadì písem %s:"
+
+#, c-format
+msgid "E252: Fontset name: %s"
+msgstr "E252: název sady písem: %s"
+
+#, c-format
+msgid "Font '%s' is not fixed-width"
+msgstr "Písmo '%s' nemá pevnou ¹íøku"
+
+#, c-format
+msgid "E253: Fontset name: %s\n"
+msgstr "E253: název sady písem: %s\n"
+
+#, c-format
+msgid "Font0: %s\n"
+msgstr "Písmo0: %s\n"
+
+#, c-format
+msgid "Font1: %s\n"
+msgstr "Písmo1: %s\n"
+
+#, c-format
+msgid "Font%d width is not twice that of font0\n"
+msgstr "©íøka písma%d není dvojnásoblem ¹íøky písma0\n"
+
+#, c-format
+msgid "Font0 width: %ld\n"
+msgstr "©íøka písma0: %ld\n"
+
+#, c-format
+msgid ""
+"Font1 width: %ld\n"
+"\n"
+msgstr ""
+"©íøka písma1: %ld\n"
+"\n"
+
+#, c-format
+msgid "E254: Cannot allocate color %s"
+msgstr "E254: nelze alokovat barvu %s"
+
+msgid "E255: Couldn't read in sign data!"
+msgstr "E255: Chyba -- nelze pøeèíst sign data!"
+
+msgid "E256: Hangul automata ERROR"
+msgstr "E256: CYBA Hangul automatu"
+
+msgid "Add a new database"
+msgstr "Pøidat novou databázi"
+
+msgid "Query for a pattern"
+msgstr "Hledání vzorku"
+
+msgid "Show this message"
+msgstr "Zobrazit tuto zprávu"
+
+msgid "Kill a connection"
+msgstr "Ukonèit spojení"
+
+msgid "Reinit all connections"
+msgstr "Znovu inicializovat v¹echna spojení"
+
+msgid "Show connections"
+msgstr "Zobrazit spojení"
+
+msgid "This cscope command does not support splitting the window.\n"
+msgstr "Tento cscope pøíkaz nepodporuje rozdìlení okna.\n"
+
+msgid "Usage: cstag <ident>"
+msgstr "Pou¾ití: cstag <odsazení>"
+
+msgid "E257: cstag: tag not found"
+msgstr "E257: cstag: tag nenalezen"
+
+#, c-format
+msgid "stat(%s) error: %d"
+msgstr "stat(%s) chyba: %d"
+
+#, c-format
+msgid "Added cscope database %s"
+msgstr "Pøidána cscope databáze %s"
+
+#, c-format
+msgid "%s is not a directory or a valid cscope database"
+msgstr "%s není ani adresáøem ani správnou cscope databází"
+
+#, c-format
+msgid "error reading cscope connection %d"
+msgstr "chyba pøi ètení cscope spojení %d"
+
+msgid "unknown cscope search type"
+msgstr "neznámý typ cscope hledání"
+
+msgid "Could not create cscope pipes"
+msgstr "nelze vytvoøit cscope roury"
+
+msgid "cs_create_connection exec failed"
+msgstr "spu¹tìní cs_create_connection selhalo"
+
+msgid "cs_create_connection: fdopen for to_fp failed"
+msgstr "cs_create_connection: volání fdopen pro to_fp selhalo"
+
+msgid "cs_create_connection: fdopen for fr_fp failed"
+msgstr "cs_create_connection: volání fdopen pro fr_fp selhalo"
+
+msgid "no cscope connections"
+msgstr "¾ádná cscope spojení"
+
+#, c-format
+msgid "E259: no matches found for cscope query %s of %s"
+msgstr "E259: cscope hledání %s vzorku %s nena¹lo ¾ádnou shodu"
+
+msgid "cscope commands:\n"
+msgstr "pøíkazy cscope:\n"
+
+#, c-format
+msgid "%-5s: %-30s (Usage: %s)\n"
+msgstr "%-5s: %-30s (Pou¾ití: %s)\n"
+
+msgid "duplicate cscope database not added"
+msgstr "duplicitní cscope databáze nebyla pøidána"
+
+msgid "maximum number of cscope connections reached"
+msgstr "dosa¾en maximální poèet cscope spojení"
+
+msgid "E260: cscope connection not found"
+msgstr "E260: connection spojení nenalezeno"
+
+#, c-format
+msgid "E261: cscope connection %s not found"
+msgstr "E261: connection spojení %s nenalezeno"
+
+msgid "cscope connection closed"
+msgstr "closed spojení uzavøeno"
+
+#, c-format
+msgid "cscope connection %s closed\n"
+msgstr "cscope spojení %s uzavøeno\n"
+
+#. should not reach here
+msgid "fatal error in cs_manage_matches"
+msgstr "osudová chyba v cs_manage_matches"
+
+#, c-format
+msgid "E262: error reading cscope connection %d"
+msgstr "E262: pøi ètení cscope spojení %d"
+
+msgid "couldn't malloc\n"
+msgstr "volání malloc selhalo\n"
+
+#, c-format
+msgid "Cscope tag: %s\n"
+msgstr "Cscope tag: %s\n"
+
+msgid " # line"
+msgstr " # øádek"
+
+msgid "filename / context / line\n"
+msgstr "název souboru/ kontext/ øádek\n"
+
+msgid "All cscope databases reset"
+msgstr "V¹echny cscope databáze resetovány"
+
+msgid "no cscope connections\n"
+msgstr "¾ádné cscope spojení\n"
+
+msgid " # pid database name prepend path\n"
+msgstr " # pid název databáze pøedpona cesty\n"
+
+#, c-format
+msgid "%2d %-5ld %-34s <none>\n"
+msgstr "%2d %-5ld %-34s <¾ádný>\n"
+
+msgid ""
+"E263: Sorry, this command is disabled, the Python library could not be "
+"loaded."
+msgstr ""
+"E263: Lituji, tento pøíkaz je deaktivován; knihovnu jazyka Python nelze "
+"nahrát."
+
+msgid "can't delete OutputObject attributes"
+msgstr "nelze smazat atributy OutputObject"
+
+msgid "softspace must be an integer"
+msgstr "softspace musí být kladné celé èíslo"
+
+msgid "invalid attribute"
+msgstr "chybný atribut"
+
+msgid "writelines() requires list of strings"
+msgstr "writelines() vy¾aduje seznam øetìzcù"
+
+msgid "E264: Python: Error initialising I/O objects"
+msgstr "E264: Python: chyba pøi inicializaci I/O objektù"
+
+msgid "invalid expression"
+msgstr "Chybný výraz"
+
+msgid "expressions disabled at compile time"
+msgstr "podpora výrazù byla vypnuta pøi pøekladu programu"
+
+msgid "attempt to refer to deleted buffer"
+msgstr "pokus o odkaz na smazaný buffer"
+
+msgid "line number out of range"
+msgstr "èíslo øádku mimo rozsah"
+
+#, c-format
+msgid "<buffer object (deleted) at %8lX>"
+msgstr "<buffer objekt (smazán) na %8lX>"
+
+msgid "invalid mark name"
+msgstr "chybné jméno znaèky"
+
+msgid "no such buffer"
+msgstr "¾ádný takový buffer"
+
+msgid "attempt to refer to deleted window"
+msgstr "pokus o odkaz na smazané okno"
+
+msgid "readonly attribute"
+msgstr "atribut pouze_pro_ètení"
+
+msgid "cursor position outside buffer"
+msgstr "umístìní kurzoru mimo buffer"
+
+#, c-format
+msgid "<window object (deleted) at %.8lX>"
+msgstr "<objekt okna (smazán) na %.8lX>"
+
+#, c-format
+msgid "<window object (unknown) at %.8lX>"
+msgstr "<objekt okna (neznámý) na %.8lX>"
+
+#, c-format
+msgid "<window %d>"
+msgstr "<okno %d>"
+
+msgid "no such window"
+msgstr "¾ádné takové okno"
+
+msgid "cannot save undo information"
+msgstr "nelze ulo¾it informace pro pøíkaz undo"
+
+msgid "cannot delete line"
+msgstr "nelze smazat øádek"
+
+msgid "cannot replace line"
+msgstr "nelze nahradit øádek"
+
+msgid "cannot insert line"
+msgstr "nelze vlo¾it øádek"
+
+msgid "string cannot contain newlines"
+msgstr "øetìzec nesmí obsahovat znaky nového øádku"
+
+msgid ""
+"E266: Sorry, this command is disabled, the Ruby library could not be loaded."
+msgstr ""
+"E266: Lituji, ale tento pøíkaz je deaktivován; knihovnu jazyka Ruby nelze "
+"nahrát."
+
+#, c-format
+msgid "E273: unknown longjmp status %d"
+msgstr "E273: neznámý longjmp stav %d"
+
+msgid "Toggle implementation/definition"
+msgstr "Prohození implementace/definice"
+
+msgid "Show base class of"
+msgstr "Zobrazení base class z"
+
+msgid "Show overridden member function"
+msgstr "Zobrazení overridden member funkce"
+
+msgid "Retrieve from file"
+msgstr "Znovuzískáno ze souboru"
+
+msgid "Retrieve from project"
+msgstr "Znovuzískáno z projektu"
+
+msgid "Retrieve from all projects"
+msgstr "Znovzískáno ze v¹ech projektù"
+
+msgid "Retrieve"
+msgstr "Znovuzískáno"
+
+msgid "Show source of"
+msgstr "Zobrazení zdroje"
+
+msgid "Find symbol"
+msgstr "Najít symbol"
+
+msgid "Browse class"
+msgstr "Prohlí¾et class"
+
+msgid "Show class in hierarchy"
+msgstr "Zobrazení class v hierarchii"
+
+msgid "Show class in restricted hierarchy"
+msgstr "Zobrazení class v restricted hierarchii"
+
+msgid "Xref refers to"
+msgstr "Xref odkazuje na"
+
+msgid "Xref referred by"
+msgstr "Xref odkazoval na"
+
+msgid "Xref has a"
+msgstr "Xref má"
+
+msgid "Xref used by"
+msgstr "Xref pou¾it"
+
+msgid "Show docu of"
+msgstr "Zobrazení documentace"
+
+msgid "Generate docu for"
+msgstr "Generována dokumentace pro"
+
+msgid ""
+"Cannot connect to SNiFF+. Check environment (sniffemacs must be found in "
+"$PATH).\n"
+msgstr ""
+"Nelze se pøipojit k SNiFF+. Zkontrolujte promìnné (sniffemacs musí "
+"být)uvedena v $PATH.\n"
+
+msgid "E274: Sniff: Error during read. Disconnected"
+msgstr "E274: Sniff: Chyba pøi ètení. Odpojeno"
+
+msgid "SNiFF+ is currently "
+msgstr "SNiFF+ je právì "
+
+msgid "not "
+msgstr "ne "
+
+msgid "connected"
+msgstr "pøipojen"
+
+#, c-format
+msgid "E275: Unknown SNiFF+ request: %s"
+msgstr "E275: Neznámý po¾adavek SNiFF+: %s"
+
+msgid "E276: Error connecting to SNiFF+"
+msgstr "E276: Chybné pøipojení k SNiFF+"
+
+msgid "E278: SNiFF+ not connected"
+msgstr "E278: SNiFF+ nepøipojen"
+
+msgid "E279: Not a SNiFF+ buffer"
+msgstr "E279: Není SNiFF+ buffer"
+
+msgid "Sniff: Error during write. Disconnected"
+msgstr "Sniff: Chyba pøi zápisu. Odpojeno."
+
+msgid "invalid buffer number"
+msgstr "chybný název bufferu"
+
+msgid "not implemented yet"
+msgstr "není je¹tì podporováno"
+
+msgid "unknown option"
+msgstr "neznámá volba"
+
+#. ???
+msgid "cannot set line(s)"
+msgstr "nelze nastavit øádky"
+
+msgid "mark not set"
+msgstr "znaèka není nastavena"
+
+#, c-format
+msgid "row %d column %d"
+msgstr "øádek %d sloupec %d"
+
+msgid "cannot insert/append line"
+msgstr "nelze vlo¾it/pøipojit øádek"
+
+msgid "unknown flag: "
+msgstr "neznámý pøíznak: "
+
+msgid "unknown vimOption"
+msgstr "neznámá vimOption"
+
+msgid "keyboard interrupt"
+msgstr "pøeru¹ení z klávesnice"
+
+msgid "vim error"
+msgstr "chyba vim"
+
+msgid "cannot create buffer/window command: object is being deleted"
+msgstr "nelze vytvoøit pøíkaz bufferu/okna: objekt smazán"
+
+msgid ""
+"cannot register callback command: buffer/window is already being deleted"
+msgstr ""
+"nelze zaregistrovat pøíkaz zpìtného volání: buffer/okno ji¾ bylo smazáno"
+
+#. This should never happen. Famous last word?
+msgid ""
+"E280: TCL FATAL ERROR: reflist corrupt!? Please report this to "
+"vim-dev@vim.org"
+msgstr ""
+"E280: TCL FATAL ERROR: reflist po¹kozen!? Oznamte, prosím, tuto chybu na "
+"vim-dev@vim.org"
+
+msgid "cannot register callback command: buffer/window reference not found"
+msgstr ""
+"nelze zaregistrovat pøíkaz zpìtného volání: odkaz na buffer/okno nenalezen"
+
+msgid "Sorry, this command is disabled: the Tcl library could not be loaded."
+msgstr ""
+"Lituji, ale tento pøíkaz je deaktivován; knihovnu jazyka Tcl nelze nahrát."
+
+msgid ""
+"E281: TCL ERROR: exit code is not int!? Please report this to vim-dev@vim.org"
+msgstr ""
+"E281: TCL CHYBA: návratový kód není celé èíslo!? Oznamte, prosím, tuto chybu "
+"na vim-dev@vim.org"
+
+msgid "cannot get line"
+msgstr "nelze pøeèíst øádek"
+
+msgid "Unable to register a command server name"
+msgstr "Není mo¾né zaznamenat jméno command serveru"
+
+#, c-format
+msgid "E247: no registered server named \"%s\""
+msgstr "E247: Neexistuje registrovaný server jménem \"%s\""
+
+msgid "E248: Failed to send command to the destination program"
+msgstr "E248: Selhalo zaslání pøíkazu urèenému programu"
+
+#, c-format
+msgid "Invalid server id used: %s"
+msgstr "Pou¾it chybný id serveru: %s"
+
+msgid "E249: couldn't read VIM instance registry property"
+msgstr "E249: nelze èíst VIM instanci registry property"
+
+msgid "E251: VIM instance registry property is badly formed. Deleted!"
+msgstr ""
+"E251: VIM instance registry property byla ¹patnì vytvoøenaa byla smazána!"
+
+msgid "Unknown option"
+msgstr "Neznámá volba"
+
+msgid "Too many edit arguments"
+msgstr "Pøíli¹ mnoho edit argumentù"
+
+msgid "Argument missing after"
+msgstr "Chybí argument po"
+
+msgid "Garbage after option"
+msgstr "Chyby za volbou"
+
+msgid "Too many \"+command\" or \"-c command\" arguments"
+msgstr "Pøíli¹ mnoho \"+pøíkaz\" èi \"-c pøíkaz\" argumentù"
+
+msgid "Invalid argument for"
+msgstr "Chybný argument pro"
+
+msgid "This Vim was not compiled with the diff feature."
+msgstr "VIM nebyl pøelo¾en s volbou +diff"
+
+msgid "Attempt to open script file again: \""
+msgstr "Pokus o opìtovné otevøení skriptu: \""
+
+msgid "\"\n"
+msgstr "\"\n"
+
+msgid "Cannot open for reading: \""
+msgstr "Nelze otevøít pro zápis: \""
+
+msgid "Cannot open for script output: \""
+msgstr "Nelze otevøít pro výstup skriptu: \""
+
+#, c-format
+msgid "%d files to edit\n"
+msgstr "poèet souborù pro editaci: %d\n"
+
+msgid "Vim: Warning: Output is not to a terminal\n"
+msgstr "Vim: Varování: výstup nesmìøuje na terminál\n"
+
+msgid "Vim: Warning: Input is not from a terminal\n"
+msgstr "Vim: Varování: vstup nepochází z terminálu\n"
+
+#. just in case..
+msgid "pre-vimrc command line"
+msgstr "pre-vimrc pøíkazový øádek"
+
+#, c-format
+msgid "E282: Cannot read from \"%s\""
+msgstr "E282: Nelze èíst z \"%s\""
+
+msgid ""
+"\n"
+"More info with: \"vim -h\"\n"
+msgstr ""
+"\n"
+"Podrobnìj¹í informace získáte pomocí \"vim -h\"\n"
+
+msgid "[file ..] edit specified file(s)"
+msgstr "[SOUBOR] .. editovat SOUBOR(y)"
+
+msgid "- read text from stdin"
+msgstr "- èíst text ze standardního vstupu"
+
+msgid "-t tag edit file where tag is defined"
+msgstr "-t TAG editovat soubor na místì definice TAGU"
+
+msgid "-q [errorfile] edit file with first error"
+msgstr "-q [chybový soubor] editovat soubor na místì výskytu první chyby"
+
+msgid ""
+"\n"
+"\n"
+"usage:"
+msgstr ""
+"\n"
+"\n"
+"pou¾ití:"
+
+msgid " vim [arguments] "
+msgstr "vim [pøepínaèe] "
+
+msgid ""
+"\n"
+" or:"
+msgstr ""
+"\n"
+" nebo"
+
+msgid ""
+"\n"
+"\n"
+"Arguments:\n"
+msgstr ""
+"\n"
+"\n"
+"Argumenty:\n"
+
+msgid "--\t\t\tOnly file names after this"
+msgstr "--\t\t\tMohou následovat pouze názvy souborù"
+
+msgid "-register\t\tRegister this gvim for OLE"
+msgstr "-register\t\tpøihlásit gvim na OLE"
+
+msgid "-unregister\t\tUnregister gvim for OLE"
+msgstr "-register\t\todhlásit gvim z OLE"
+
+msgid "-g\t\t\tRun using GUI (like \"gvim\")"
+msgstr "-g\t\t\tspustit v GUI re¾imu (stejné jako \"gvim\")"
+
+msgid "-f\t\t\tForeground: Don't fork when starting GUI"
+msgstr "-f\t\t\tPopøedí: pøi startu GUI se neoddìlí od shellu"
+
+msgid "-v\t\t\tVi mode (like \"vi\")"
+msgstr "-v\t\t\tVi mód (stejné jako \"vi\")"
+
+msgid "-e\t\t\tEx mode (like \"ex\")"
+msgstr "-v\t\t\tEx mód (stejné jako \"ex\")"
+
+msgid "-s\t\t\tSilent (batch) mode (only for \"ex\")"
+msgstr "-s\t\t\tTichý (dávkový) re¾im (pouze pro \"ex\")"
+
+msgid "-d\t\t\tDiff mode (like \"vimdiff\")"
+msgstr "-d\t\t\tDiff re¾im (stejné jako \"vimdiff\")"
+
+msgid "-y\t\t\tEasy mode (like \"evim\", modeless)"
+msgstr "-v\t\t\tSnadný re¾im (stejné jako \"evim\", ¾ádné módy )"
+
+msgid "-R\t\t\tReadonly mode (like \"view\")"
+msgstr "-R\t\t\tRe¾im pouze_pro_ètení (jako \"view\")"
+
+msgid "-Z\t\t\tRestricted mode (like \"rvim\")"
+msgstr "-Z\t\t\tOmezený re¾im (stejné jako \"rvim\")"
+
+msgid "-m\t\t\tModifications (writing files) not allowed"
+msgstr "-m\t\t\tZmìny (ukládání souborù) zakázány"
+
+msgid "-M\t\t\tModifications in text not allowed"
+msgstr "-M\t\t\tZmìny (ukládání souborù) zakázány"
+
+msgid "-b\t\t\tBinary mode"
+msgstr "-b\t\t\tBinární re¾im"
+
+msgid "-l\t\t\tLisp mode"
+msgstr "-l\t\t\tLisp re¾im"
+
+msgid "-C\t\t\tCompatible with Vi: 'compatible'"
+msgstr "-C\t\t\tKompatabilní s Vi: 'compatible'"
+
+msgid "-N\t\t\tNot fully Vi compatible: 'nocompatible'"
+msgstr "-N\t\t\tKompatibilita s Vi vypnuta: 'nocompatible'"
+
+msgid "-V[N]\t\tVerbose level"
+msgstr "-V[N]\t\tÚroveò výpisu hlá¹ek"
+
+msgid "-D\t\t\tDebugging mode"
+msgstr "-D\t\t\tLadící re¾im"
+
+msgid "-n\t\t\tNo swap file, use memory only"
+msgstr "-n\t\t\tNebude vytváøet odkládací soubor, bude pou¾ívat pouze pamì»"
+
+msgid "-r\t\t\tList swap files and exit"
+msgstr "-r\t\t\tVypí¹e seznam odkládacích souborù a skonèí"
+
+msgid "-r (with file name)\tRecover crashed session"
+msgstr "-r název souboru\tObnoví pøeru¹ené sezení"
+
+msgid "-L\t\t\tSame as -r"
+msgstr "-L\t\t\tStejné jako -r"
+
+msgid "-f\t\t\tDon't use newcli to open window"
+msgstr "-f\t\t\tNebude pou¾ívat newcli pro otevøení okna"
+
+msgid "-dev <device>\t\tUse <device> for I/O"
+msgstr "-dev <zaøízení>\t\tPou¾ít <zaøízení> pro I/O"
+
+msgid "-H\t\t\tstart in Hebrew mode"
+msgstr "-H\t\t\tnastartuje v hebrejském re¾imu"
+
+msgid "-F\t\t\tstart in Farsi mode"
+msgstr "-F\t\t\tnastartuje ve Farsi re¾imu"
+
+msgid "-T <terminal>\tSet terminal type to <terminal>"
+msgstr "-T <terminál>\tNastaví typ terminálu na <terminál>"
+
+msgid "-u <vimrc>\t\tUse <vimrc> instead of any .vimrc"
+msgstr "-u <vimrc>\t\tPou¾ije <vimrc> místo jakéhokoliv .vimrc"
+
+msgid "-U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc"
+msgstr "-U <gvimrc>\t\tPou¾ije <gvimrc> místo jakéhokoliv .gvimrc"
+
+msgid "--noplugin\t\tDon't load plugin scripts"
+msgstr "--noplugin\t\tNenahraje 'plugin' skripty"
+
+msgid "-o[N]\t\tOpen N windows (default: one for each file)"
+msgstr "-o[N]\t\tOtevøe N oken (implicitnì jedno pro ka¾dý soubor)"
+
+msgid "-O[N]\t\tlike -o but split vertically"
+msgstr "-O[N]\t\tJako -o but split vertically"
+
+msgid "+\t\t\tStart at end of file"
+msgstr "+\t\t\tNastaví kurzor na konec souboru"
+
+msgid "+<lnum>\t\tStart at line <lnum>"
+msgstr "+<øádek>\t\tNastaví kurzor na <øádek>"
+
+msgid "--cmd <command>\tExecute <command> before loading any vimrc file"
+msgstr "--cmd <pøíkaz>\tPo nahrání prvního souboru vykoná <pøíkaz>"
+
+msgid "-c <command>\t\tExecute <command> after loading the first file"
+msgstr "-c <pøíkaz>\t\tPo nahrání prvního souboru vykoná <pøíkaz>"
+
+msgid "-S <session>\t\tSource file <session> after loading the first file"
+msgstr ""
+"-S <sezení>\t\tPo nahrání prvního souboru vykoná pøíkazy v souboru <sezení>"
+
+msgid "-s <scriptin>\tRead Normal mode commands from file <scriptin>"
+msgstr "-s <skript>\t\tNaète pøíkazy normálního módu ze <skriptu>"
+
+msgid "-w <scriptout>\tAppend all typed commands to file <scriptout>"
+msgstr "-w <skript>\t\tPøipojí v¹echny napsané pøíkazy do souboru <skript>"
+
+msgid "-W <scriptout>\tWrite all typed commands to file <scriptout>"
+msgstr "-W <skript>\t\tUlo¾í v¹echny napsané pøíkazy do souboru <skript>"
+
+msgid "-x\t\t\tEdit encrypted files"
+msgstr "-x\t\t\tEditace za¹ifrovaných souborù"
+
+msgid "-display <display>\tConnect vim to this particular X-server"
+msgstr "-display <display>\tSpustí vim na daný X-server"
+
+msgid "-X\t\t\tDo not connect to X server"
+msgstr "-X\t\t\tNepøipojí se k X serveru"
+
+msgid "--socketid <xid>\tOpen Vim inside another GTK widget"
+msgstr "--socketid <xid>\tOtevøe Vim uvnitø jiného GTK widgetu"
+
+msgid "--remote <files>\tEdit <files> in a Vim server and exit"
+msgstr "--remote <soubory>\tEdituje <soubory> na Vim serveru a skonèí"
+
+msgid ""
+"--remote-wait <files> As --remote but wait for files to have been edited"
+msgstr ""
+"--remote-wait <soubory> Jako --remote, ale èeká na soubory k editaci"
+
+msgid "--remote-send <keys>\tSend <keys> to a Vim server and exit"
+msgstr "--remote-send <klávesy>\tPøedá <klávesy> Vim serveru a skonèí"
+
+msgid "--remote-expr <expr>\tEvaluate <expr> in a Vim server and print result"
+msgstr "--remote-expr <výraz>\tProvede <výraz> na serveru a zobrazí výsledek"
+
+msgid "--serverlist\t\tList available Vim server names and exit"
+msgstr "--serverlist\t\tVypí¹e seznam dostupných Vim serverù a skonèí"
+
+msgid "--servername <name>\tSend to/become the Vim server <name>"
+msgstr ""
+"--servername <jméno>\tZa¹le serveru <jméno>/stane se Vim serverem <jméno>"
+
+msgid "-i <viminfo>\t\tUse <viminfo> instead of .viminfo"
+msgstr "-i <viminfo>\t\tPou¾ije <viminfo> místo jakéhokoliv .viminfo"
+
+msgid "-h\t\t\tprint Help (this message) and exit"
+msgstr "-h\t\t\tVypí¹e tuto nápovìdu a skonèí"
+
+msgid "--version\t\tprint version information and exit"
+msgstr "--version\t\tvypí¹e informace o verzi a skonèí"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (Motif version):\n"
+msgstr ""
+"\n"
+"Pøepínaèe pro gvim (Motif verzi):\n"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (Athena version):\n"
+msgstr ""
+"\n"
+"Pøepínaèe pro gvim (Athena verzi):\n"
+
+msgid "-display <display>\tRun vim on <display>"
+msgstr "-display <display>\tSpustí vim na <display>"
+
+msgid "-iconic\t\tStart vim iconified"
+msgstr "-iconic\t\tSpustí vim minimalizované"
+
+msgid "-name <name>\t\tUse resource as if vim was <name>"
+msgstr "-name <název>\t\tPou¾ije resource jako by vim mìl <název>"
+
+msgid "\t\t\t (Unimplemented)\n"
+msgstr "\t\t\t (není implementováno)\n"
+
+msgid "-background <color>\tUse <color> for the background (also: -bg)"
+msgstr "-background <barva>\tNastaví <barvu> pozadí (také -bg)"
+
+msgid "-foreground <color>\tUse <color> for normal text (also: -fg)"
+msgstr "-foreground <barva>\tNastaví <barvu> popøedí (také -fg)"
+
+msgid "-font <font>\t\tUse <font> for normal text (also: -fn)"
+msgstr "-font <písmo>\t\tNastaví <písmo> normálního textu (také -fn)"
+
+msgid "-boldfont <font>\tUse <font> for bold text"
+msgstr "-boldfont <písmo>\tNastaví <písmo> pro zvýraznìný text"
+
+msgid "-italicfont <font>\tUse <font> for italic text"
+msgstr "-italicfont <písmo>\tNastaví <písmo> pro kurzívu"
+
+msgid "-geometry <geom>\tUse <geom> for initial geometry (also: -geom)"
+msgstr "-geometry <geometrie>\tNastaví <geometrii> (také -geom)"
+
+msgid "-borderwidth <width>\tUse a border width of <width> (also: -bw)"
+msgstr "-borderwidth <¹íøka>\tNastaví <¹íøku> okrajù (také -bw)"
+
+msgid "-scrollbarwidth <width> Use a scrollbar width of <width> (also: -sw)"
+msgstr "-scrollbarwidth <¹íøku> Nastaví <¹íøku> posunovací li¹ty (také: -sw)"
+
+msgid "-menuheight <height>\tUse a menu bar height of <height> (also: -mh)"
+msgstr "-menuheight <vý¹ka>\tNastaví <vý¹ku> nabídky (také -mh)"
+
+msgid "-reverse\t\tUse reverse video (also: -rv)"
+msgstr "-reverse\t\tPou¾ije reverzní barvy (také -rv)"
+
+msgid "+reverse\t\tDon't use reverse video (also: +rv)"
+msgstr "+reverse\t\tNepou¾ije reverzní barvy (také +rv)"
+
+msgid "-xrm <resource>\tSet the specified resource"
+msgstr "-xrm <resource>\tNastaví zadaný <resource>"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (RISC OS version):\n"
+msgstr ""
+"\n"
+"Pøepínaèe pro gvim (RISC OS verzi):\n"
+
+msgid "--columns <number>\tInitial width of window in columns"
+msgstr "--columns <poèet>\t<poèet> sloupcù na okno"
+
+msgid "--rows <number>\tInitial height of window in rows"
+msgstr "--rows <poèet>\t<poèet> øádkù na okno"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (GTK+ version):\n"
+msgstr ""
+"\n"
+"Pøepínaèe pro gvim (GTK+ verzi):\n"
+
+msgid "-display <display>\tRun vim on <display> (also: --display)"
+msgstr "-display <display>\tSpustí vim na <display> (také --display)"
+
+msgid "--help\t\tShow Gnome arguments"
+msgstr "--help\t\tVypí¹e Gnome pøepínaèe"
+
+#. Failed to send, abort.
+msgid ""
+"\n"
+"Send failed.\n"
+msgstr ""
+"\n"
+"Pøedání výrazu selhalo.\n"
+
+#. Let vim start normally.
+msgid ""
+"\n"
+"Send failed. Trying to execute locally\n"
+msgstr ""
+"\n"
+"Pøedání selhalo. Zkou¹ím provést lokálnì\n"
+
+#, c-format
+msgid "%d of %d edited"
+msgstr "%d z %d editováno"
+
+msgid "Send expression failed.\n"
+msgstr "Pøedání výrazu selhalo.\n"
+
+msgid "No marks set"
+msgstr "Nejsou nastaveny ¾ádné znaèky"
+
+#, c-format
+msgid "E283: No marks matching \"%s\""
+msgstr "E283: \"%s\" nevyhovují ¾ádné znaèky"
+
+#. Highlight title
+msgid ""
+"\n"
+"mark line col file/text"
+msgstr ""
+"\n"
+"znaèka øádek sloupec soubor/text"
+
+#. Highlight title
+msgid ""
+"\n"
+" jump line col file/text"
+msgstr ""
+"\n"
+" skok øádek sloupec soubor/text"
+
+msgid ""
+"\n"
+"# File marks:\n"
+msgstr ""
+"\n"
+"# Souborové znaèky:\n"
+
+#. Write the jumplist with -'
+msgid ""
+"\n"
+"# Jumplist (newest first):\n"
+msgstr ""
+"\n"
+"# Seznam skokù (poèínaje nejnovìj¹í polo¾kou):\n"
+
+msgid ""
+"\n"
+"# History of marks within files (newest to oldest):\n"
+msgstr ""
+"\n"
+"# Historie znaèek v souborech (poèínaje nejnovìj¹í polo¾kou):\n"
+
+msgid "Missing '>'"
+msgstr "Chybí '>'"
+
+msgid "Not a valid codepage"
+msgstr "Chybná kódová stránka"
+
+msgid "E284: Cannot set IC values"
+msgstr "E284: Nelze nastavit IC hodnoty"
+
+msgid "E285: Failed to create input context"
+msgstr "E285: Nepodaøilo se vytvoøit vstupní kontext"
+
+msgid "E286: Failed to open input method"
+msgstr "E286: Nepodaøilo se otevøít vstupní metodu"
+
+msgid "E287: Warning: Could not set destroy callback to IM"
+msgstr "E287: Varování: likvidaèní zpìtné volání nelze nastavit na IM"
+
+msgid "E288: input method doesn't support any style"
+msgstr "E288: vstupní metoda nepodporuje ¾ádný styl"
+
+msgid "E289: input method doesn't support my preedit type"
+msgstr "E289: vstupní metoda nepodporuje mùj 'preedit' typ"
+
+msgid "E290: over-the-spot style requires fontset"
+msgstr "E290: Nadbodový styl vy¾aduje fontset"
+
+msgid "E291: Your GTK+ is older than 1.2.3. Status area disabled"
+msgstr "E291: Máte GTK+ verze star¹í ne¾ 1.2.3. Stavová plocha vypnuta."
+
+msgid "E292: Input Method Server is not running"
+msgstr "E292: Server vstupních metod nebì¾í"
+
+msgid "E293: block was not locked"
+msgstr "E293: blok nebyl zamknut"
+
+msgid "E294: Seek error in swap file read"
+msgstr "E294: Chyba posunu ukazovátka pøi ètení odkládacího souboru"
+
+msgid "E295: Read error in swap file"
+msgstr "E295: Chyba pøi ètení odkládacího souboru"
+
+msgid "E296: Seek error in swap file write"
+msgstr "E296: Chyba posunu ukazovátka pøi ukládání do odkládacího souboru"
+
+msgid "E297: Write error in swap file"
+msgstr "E297: Chyba pøi ukládání do odkládacího souboru"
+
+msgid "E300: Swap file already exists (symlink attack?)"
+msgstr ""
+"E300: Odkládací soubor ji¾ existuje! (Nìkdo hackujepøes nastra¾ený symlink?)"
+
+msgid "E298: Didn't get block nr 0?"
+msgstr "E298: Nelze získat blok 0?"
+
+msgid "E298: Didn't get block nr 1?"
+msgstr "E298: Nelze získat blok 1?"
+
+msgid "E298: Didn't get block nr 2?"
+msgstr "E298: nelze získat blok 2?"
+
+#. could not (re)open the swap file, what can we do????
+msgid "E301: Oops, lost the swap file!!!"
+msgstr "E301: Jéje, odkládací soubor byl ztracen!!!"
+
+msgid "E302: Could not rename swap file"
+msgstr "E302: Nelze pøejmenovat odkládací soubor"
+
+#, c-format
+msgid "E303: Unable to open swap file for \"%s\", recovery impossible"
+msgstr "E303: Nelze otevøít odkládací soubor pro \"%s\""
+
+msgid "E304: ml_timestamp: Didn't get block 0??"
+msgstr "E304: ml_timestamp: nelze získat blok 0??"
+
+#, c-format
+msgid "E305: No swap file found for %s"
+msgstr "E305: Odkládací soubor pro %s nebyl nalezen"
+
+msgid "Enter number of swap file to use (0 to quit): "
+msgstr ""
+"Zadejte èíslo odkládacího souboru, který se má pou¾ít (0 pro ukonèení): "
+
+#, c-format
+msgid "E306: Cannot open %s"
+msgstr "E306: Nelze otevøít %s"
+
+msgid "Unable to read block 0 from "
+msgstr "Nelze èíst blok 0 z "
+
+msgid ""
+"\n"
+"Maybe no changes were made or Vim did not update the swap file."
+msgstr ""
+"\n"
+"Mo¾ná nedo¹lo k ¾ádným zmìnám, nebo Vim neaktualizoval odkládací soubor."
+
+msgid " cannot be used with this version of Vim.\n"
+msgstr " nelze pou¾ít s touto verzí Vim.\n"
+
+msgid "Use Vim version 3.0.\n"
+msgstr "Pou¾ijte Vim verze 3.0.\n"
+
+#, c-format
+msgid "E307: %s does not look like a Vim swap file"
+msgstr "E307: %s se nezdá být odkládacím souborem Vim"
+
+msgid " cannot be used on this computer.\n"
+msgstr " nelze pou¾ít na tomto poèítaèi.\n"
+
+msgid "The file was created on "
+msgstr "Soubor byl vytvoøen "
+
+msgid ""
+",\n"
+"or the file has been damaged."
+msgstr ""
+",\n"
+"nebo byl soubor po¹kozen."
+
+#, c-format
+msgid "Using swap file \"%s\""
+msgstr "Pou¾ívám odkládací soubor \"%s\""
+
+#, c-format
+msgid "Original file \"%s\""
+msgstr "Pùvodní soubor \"%s\""
+
+msgid "E308: Warning: Original file may have been changed"
+msgstr "E308: Varování: Pùvodní soubor mohl být zmìnìn"
+
+#, c-format
+msgid "E309: Unable to read block 1 from %s"
+msgstr "E309: Nelze èíst blok 1 z %s"
+
+msgid "???MANY LINES MISSING"
+msgstr "???CHYBÍ MNOHO ØÁDKÙ"
+
+msgid "???LINE COUNT WRONG"
+msgstr "???CHYBNÝ POÈET ØÁDKÙ"
+
+msgid "???EMPTY BLOCK"
+msgstr "???PRÁZDNÝ BLOK"
+
+msgid "???LINES MISSING"
+msgstr "???CHYBÌJÍCÍ ØÁDKY"
+
+#, c-format
+msgid "E310: Block 1 ID wrong (%s not a .swp file?)"
+msgstr "E310: ID bloku 1 je chybné (je %s odkládacím souborem?)"
+
+msgid "???BLOCK MISSING"
+msgstr "???CHYBÍ BLOK"
+
+msgid "??? from here until ???END lines may be messed up"
+msgstr "od ??? po ???END mohou být øádky pomíchané"
+
+msgid "??? from here until ???END lines may have been inserted/deleted"
+msgstr "od ??? po ???END mohou být vlo¾ené/smazané øádky"
+
+msgid "???END"
+msgstr "???KONEC"
+
+msgid "E311: Recovery Interrupted"
+msgstr "E311: Obnova pøeru¹ena"
+
+msgid ""
+"E312: Errors detected while recovering; look for lines starting with ???"
+msgstr ""
+"E312: V prùbìhu obnovy do¹lo k chybám; zkontrolujte øádky zaèínající na ???"
+
+msgid "Recovery completed. You should check if everything is OK."
+msgstr "Obnova dokonèena. Zkontrolujte, zda je v¹e v poøádku."
+
+msgid ""
+"\n"
+"(You might want to write out this file under another name\n"
+msgstr ""
+"\n"
+"(Zva¾te ulo¾ení tohoto souboru pod jiným názvem\n"
+
+msgid "and run diff with the original file to check for changes)\n"
+msgstr "a kontrolu zmìn pomocí programu diff.)\n"
+
+msgid ""
+"Delete the .swp file afterwards.\n"
+"\n"
+msgstr "Poté sma¾te odkládací soubor.\n"
+
+#. use msg() to start the scrolling properly
+msgid "Swap files found:"
+msgstr "Nalezené odkládací soubory:"
+
+msgid " In current directory:\n"
+msgstr " V aktuálním adresáøi:\n"
+
+msgid " Using specified name:\n"
+msgstr " Se zadaným názvem:\n"
+
+msgid " In directory "
+msgstr " V adresáøi "
+
+msgid " -- none --\n"
+msgstr " -- ¾ádné --\n"
+
+msgid " owned by: "
+msgstr " vlastník: "
+
+msgid " dated: "
+msgstr " datum vytvoøení: "
+
+msgid " dated: "
+msgstr " datum vytvoøení: "
+
+msgid " [from Vim version 3.0]"
+msgstr " [od Vim verze 3.0]"
+
+msgid " [does not look like a Vim swap file]"
+msgstr " [nevypadá jako odkládací soubor Vim]"
+
+msgid " file name: "
+msgstr " název souboru: "
+
+msgid ""
+"\n"
+" modified: "
+msgstr ""
+"\n"
+" datum zmìny: "
+
+msgid "YES"
+msgstr "ANO"
+
+msgid "no"
+msgstr "ne"
+
+msgid ""
+"\n"
+" user name: "
+msgstr ""
+"\n"
+" u¾ivatelské jméno: "
+
+msgid " host name: "
+msgstr " název poèítaèe: "
+
+msgid ""
+"\n"
+" host name: "
+msgstr ""
+"\n"
+" název poèítaèe: "
+
+msgid ""
+"\n"
+" process ID: "
+msgstr ""
+"\n"
+" ID procesu : "
+
+msgid " (still running)"
+msgstr " (stále aktivní)"
+
+msgid ""
+"\n"
+" [not usable with this version of Vim]"
+msgstr ""
+"\n"
+" [nepou¾itelné s touto verzí Vim]"
+
+msgid ""
+"\n"
+" [not usable on this computer]"
+msgstr ""
+"\n"
+" [nepou¾itelné na tomto poèítaèi]"
+
+msgid " [cannot be read]"
+msgstr " [nelze pøeèíst]"
+
+msgid " [cannot be opened]"
+msgstr " [nelze otevøít]"
+
+msgid "E313: Cannot preserve, there is no swap file"
+msgstr "E313: Nelze zachovat - odkládací soubor neexistuje."
+
+msgid "File preserved"
+msgstr "Soubor zachován"
+
+msgid "E314: Preserve failed"
+msgstr "E314: Uchování se nezdaøilo"
+
+#, c-format
+msgid "E315: ml_get: invalid lnum: %ld"
+msgstr "E315: ml_get: chybné èíslo øádku: %ld"
+
+#, c-format
+msgid "E316: ml_get: cannot find line %ld"
+msgstr "E316: ml_get: nelze nalézt øádek %ld"
+
+msgid "E317: pointer block id wrong 3"
+msgstr "E317: chybné id ukazatele na blok 3"
+
+msgid "stack_idx should be 0"
+msgstr "stack_idx by mìlo mít hodnotu 3"
+
+msgid "E318: Updated too many blocks?"
+msgstr "E318: Aktualizováno pøíli¹ mnoho blokù?"
+
+msgid "E317: pointer block id wrong 4"
+msgstr "E317: chybné id ukazatele na blok 4"
+
+msgid "deleted block 1?"
+msgstr "smazán blok 1?"
+
+#, c-format
+msgid "E320: Cannot find line %ld"
+msgstr "E320: Nelze nalézt øádek %ld"
+
+msgid "E317: pointer block id wrong"
+msgstr "E317: chybné id ukazatele na blok"
+
+msgid "pe_line_count is zero"
+msgstr "pe_line_count má nulovou hodnotu"
+
+#, c-format
+msgid "E322: line number out of range: %ld past the end"
+msgstr "E322: poèet øádkù mimo rozsah: %ld > celkový poèet øádkù"
+
+#, c-format
+msgid "E323: line count wrong in block %ld"
+msgstr "E323: chybný poèet øádkù v bloku %ld"
+
+msgid "Stack size increases"
+msgstr "Nárùst velikosti zásobníku"
+
+msgid "E317: pointer block id wrong 2"
+msgstr "E317: chybné id ukazatele na blok 2"
+
+msgid "E325: ATTENTION"
+msgstr "E325: POZOR"
+
+msgid ""
+"\n"
+"Found a swap file by the name \""
+msgstr ""
+"\n"
+"Nalezen odkládací soubor se jménem \""
+
+msgid "While opening file \""
+msgstr "Pøi otevírání souboru\""
+
+msgid " NEWER than swap file!\n"
+msgstr " NOVÌJ©Í ne¾ odkládací soubor!\n"
+
+#. Some of these messages are long to allow translation to
+#. * other languages.
+msgid ""
+"\n"
+"(1) Another program may be editing the same file.\n"
+" If this is the case, be careful not to end up with two\n"
+" different instances of the same file when making changes.\n"
+msgstr ""
+"\n"
+"(1) Soubor mù¾e být editován jiným programem.\n"
+" Je-li tomu tak, pak si dejte pozor, aby jste po ulo¾ení zmìn\n"
+" nemìli dvì rùzné verze tého¾ souboru.\n"
+
+msgid " Quit, or continue with caution.\n"
+msgstr " Ukonèete program, nebo opatrnì pokraèujte v editaci.\n"
+
+msgid ""
+"\n"
+"(2) An edit session for this file crashed.\n"
+msgstr ""
+"\n"
+"(2) Editace tohoto souboru byla pøeru¹ena neèekaným ukonèením programu.\n"
+
+msgid " If this is the case, use \":recover\" or \"vim -r "
+msgstr " Je-li tomu tak, pak pou¾ijte \":recover\" èi \"vim -r "
+
+msgid ""
+"\"\n"
+" to recover the changes (see \":help recovery\").\n"
+msgstr ""
+"\"\n"
+" pro odstranìní zmìn (viz \":help recovery)\".\n"
+
+msgid " If you did this already, delete the swap file \""
+msgstr " Pokud jste tak ji¾ uèinil, tak sma¾te odkládací soubor \""
+
+msgid ""
+"\"\n"
+" to avoid this message.\n"
+msgstr ""
+"\"\n"
+" a tato zpráva se ji¾ nebude objevovat.\n"
+
+msgid "Swap file \""
+msgstr "Odkládací soubor \""
+
+msgid "\" already exists!"
+msgstr "\" ji¾ existuje!"
+
+msgid "VIM - ATTENTION"
+msgstr "VIM - POZOR"
+
+msgid "Swap file already exists!"
+msgstr "Odkládací soubor ji¾ existuje!"
+
+msgid ""
+"&Open Read-Only\n"
+"&Edit anyway\n"
+"&Recover\n"
+"&Quit"
+msgstr ""
+"&Otevøít pouze pro ètení\n"
+"&Pokraèovat v editaci\n"
+"O&bnovit soubor\n"
+"&Konec"
+
+msgid ""
+"&Open Read-Only\n"
+"&Edit anyway\n"
+"&Recover\n"
+"&Quit\n"
+"&Delete it"
+msgstr ""
+"&Otevøít pouze pro ètení\n"
+"&Pokraèovat v editaci\n"
+"O&bnovit soubor\n"
+"&Konec\n"
+"&Smazat"
+
+msgid "E326: Too many swap files found"
+msgstr "E326: Pøíli¹ mnoho odkládacích souborù"
+
+msgid "E327: Part of menu-item path is not sub-menu"
+msgstr "E327: Èásti cesty k pøedmìtu nabídky není podnabídkou"
+
+msgid "E328: Menu only exists in another mode"
+msgstr "E328: Nabídka existuje pouze v jiném módu"
+
+msgid "E329: No menu of that name"
+msgstr "E329: Nabídka tohoto jména neexistuje"
+
+msgid "E330: Menu path must not lead to a sub-menu"
+msgstr "E330: Cesta nabídkou nesmí vést do podnabídky"
+
+msgid "E331: Must not add menu items directly to menu bar"
+msgstr "E331: Polo¾ky nabídky nelze pøidávat pøímo na li¹tu"
+
+msgid "E332: Separator cannot be part of a menu path"
+msgstr "E332: Oddìlovaè nesmí být èástí cesty nabídkou"
+
+#. Now we have found the matching menu, and we list the mappings
+#. Highlight title
+msgid ""
+"\n"
+"--- Menus ---"
+msgstr ""
+"\n"
+"--- Nabídky ---"
+
+msgid "Tear off this menu"
+msgstr "Odtrhnout tuto nabídku"
+
+msgid "E333: Menu path must lead to a menu item"
+msgstr "E333: Cesta nabídkou musí vést k polo¾ce nabídky"
+
+#, c-format
+msgid "E334: Menu not found: %s"
+msgstr "E334: Vzor nenalezen: %s"
+
+#, c-format
+msgid "E335: Menu not defined for %s mode"
+msgstr "E335: V %s módu není nabídka definována"
+
+msgid "E336: Menu path must lead to a sub-menu"
+msgstr "E336: Cesta nabídkou musí vést do podnabídky"
+
+msgid "E337: Menu not found - check menu names"
+msgstr "E337: Nabídka nenalezena - zkontrolujte názvy nabídek"
+
+#, c-format
+msgid "Error detected while processing %s:"
+msgstr "Chyba pøi zpracování %s:"
+
+#, c-format
+msgid "line %4ld:"
+msgstr "øádek %4ld:"
+
+msgid "[string too long]"
+msgstr "[pøíli¹ dlouhý øetìzec]"
+
+msgid "Messages maintainer: Bram Moolenaar <Bram@vim.org>"
+msgstr "Správce zpráv: Bram Moolenaar <Bram@vim.org>"
+
+msgid "Interrupt: "
+msgstr "Pøeru¹ení: "
+
+msgid "Hit ENTER to continue"
+msgstr "pokraèování stiskem ENTER"
+
+msgid "Hit ENTER or type command to continue"
+msgstr "Pro pokraèování stisknìte ENTER nebo zadejte pøíkaz"
+
+msgid "-- More --"
+msgstr "-- Pokraèování --"
+
+msgid " (RET/BS: line, SPACE/b: page, d/u: half page, q: quit)"
+msgstr " (RET/BS: øádek, MEZERNÍK/b: stránka, d/u: 0.5 stránky, q: konec)"
+
+msgid " (RET: line, SPACE: page, d: half page, q: quit)"
+msgstr " (RET: øádek, MEZERNÍK: stránka, d: 0.5 stránky, q: konec)"
+
+msgid "Question"
+msgstr "Otázka"
+
+msgid ""
+"&Yes\n"
+"&No"
+msgstr ""
+"&Ano\n"
+"&Ne"
+
+msgid ""
+"&Yes\n"
+"&No\n"
+"&Cancel"
+msgstr ""
+"&Ano\n"
+"&Ne\n"
+"&Zru¹it"
+
+msgid ""
+"&Yes\n"
+"&No\n"
+"Save &All\n"
+"&Discard All\n"
+"&Cancel"
+msgstr ""
+"&Ano\n"
+"&Ne\n"
+"&Ulo¾it v¹e\n"
+"Zahodit &v¹e\n"
+"&Zru¹it"
+
+msgid "Save File dialog"
+msgstr "Dialog pro ukládání souborù"
+
+msgid "Open File dialog"
+msgstr "Dialog pro otevírání souborù"
+
+#. TODO: non-GUI file selector here
+msgid "E338: Sorry, no file browser in console mode"
+msgstr "E338: Lituji, ale konzolová verze nepodporuje prohlí¾eè souborù"
+
+msgid "W10: Warning: Changing a readonly file"
+msgstr "W10: wc1: mìním soubor pouze_pro_ètení"
+
+msgid "1 more line"
+msgstr "poèet nových øádkù: 1"
+
+msgid "1 line less"
+msgstr "poèet smazaných øádkù: 1"
+
+#, c-format
+msgid "%ld more lines"
+msgstr "poèet nových øádkù: %ld"
+
+#, c-format
+msgid "%ld fewer lines"
+msgstr "poèet smazaných øádkù: %ld"
+
+msgid " (Interrupted)"
+msgstr "(Pøeru¹eno)"
+
+msgid "Vim: preserving files...\n"
+msgstr "Vim: zachovávám soubory...\n"
+
+#. close all memfiles, without deleting
+msgid "Vim: Finished.\n"
+msgstr "Vim: ukonèen\n"
+
+msgid "ERROR: "
+msgstr "CHYBA: "
+
+#, c-format
+msgid ""
+"\n"
+"[bytes] total alloc-freed %lu-%lu, in use %lu, peak use %lu\n"
+msgstr ""
+"\n"
+"[bajtù] celkem uvolnìno-alokováno %lu-%lu, vyu¾ito %lu, maximální vyu¾ití "
+"%lu\n"
+
+#, c-format
+msgid ""
+"[calls] total re/malloc()'s %lu, total free()'s %lu\n"
+"\n"
+msgstr ""
+"[volání] celkem re/malloc(): %lu, celkem free() %lu\n"
+"\n"
+
+msgid "E340: Line is becoming too long"
+msgstr "E340: Øádek se stává pøíli¹ dlouhým"
+
+#, c-format
+msgid "E341: Internal error: lalloc(%ld, )"
+msgstr "E341: Vnitøní chyba: lalloc(%ld, )"
+
+#, c-format
+msgid "E342: Out of memory! (allocating %lu bytes)"
+msgstr "E342: Nedostatek pamìti! (potøebuji alokovat bajtù: %lu)"
+
+#, c-format
+msgid "Calling shell to execute: \"%s\""
+msgstr "Spou¹tím pøíkaz \"%s\" pomocí shellu"
+
+msgid "Missing colon"
+msgstr "Chybí dvojteèka"
+
+msgid "Illegal mode"
+msgstr "nepøípustný mód"
+
+msgid "Illegal mouseshape"
+msgstr "Chybný tvar my¹i"
+
+msgid "digit expected"
+msgstr "oèekávána èíslice"
+
+msgid "Illegal percentage"
+msgstr "nepøípustné procento"
+
+msgid "Enter encryption key: "
+msgstr "Zadejte ¹ifrovací klíè: "
+
+msgid "Enter same key again: "
+msgstr "Zadejte je¹tì jednou tentý¾ klíè:"
+
+msgid "Keys don't match!"
+msgstr "Klíèe se neshodují"
+
+#, c-format
+msgid ""
+"E343: Invalid path: '**[number]' must be at the end of the path or be "
+"followed by '%s'."
+msgstr ""
+"E343: Chybná cesta: '**[èíslo] musí být buï na konci cesty, nebo musí být\n"
+"následováno'%s. Viz :help path."
+
+#, c-format
+msgid "E344: Can't find directory \"%s\" in cdpath"
+msgstr "E344: Adresáø \"%s\" nelze v cdpath nalézt"
+
+#, c-format
+msgid "E345: Can't find file \"%s\" in path"
+msgstr "E345: Soubor \"%s\" nelze v path nalézt"
+
+#, c-format
+msgid "E346: No more directory \"%s\" found in cdpath"
+msgstr "E346: ®ádný dal¹í adresáø \"%s\" nebyl v cdpath nalezen"
+
+#, c-format
+msgid "E347: No more file \"%s\" found in path"
+msgstr "E347: ®ádný dal¹í soubor \"%s\" nebyl v cestì nalezen"
+
+msgid "Illegal component"
+msgstr "nepøípustná souèást"
+
+msgid "Warning: terminal cannot highlight"
+msgstr "Varování: terminál nepodporuje zvýrazòování"
+
+msgid "E348: No string under cursor"
+msgstr "E348: pod kurzorem není ¾ádný øetìzec"
+
+msgid "E349: No identifier under cursor"
+msgstr "E349: pod kurzorem není ¾ádný identifikátor"
+
+msgid "E352: Cannot erase folds with current 'foldmethod'"
+msgstr "E352: pomocí aktuální 'foldmethod' nelze mazat záhyby"
+
+#, c-format
+msgid "1 line %sed 1 time"
+msgstr "poèet øádkù posunutých jednou pomocí %s : 1"
+
+#, c-format
+msgid "1 line %sed %d times"
+msgstr "Poèet øádkù posunutých pomocí %s %d-krát : 1"
+
+#, c-format
+msgid "%ld lines %sed 1 time"
+msgstr "Poèet øádkù: %ld (posunutých jednou pomocí %s)"
+
+#, c-format
+msgid "%ld lines %sed %d times"
+msgstr "Poèet øádkù: %ld (posunutých pomocí %s %d-krát)"
+
+#, c-format
+msgid "%ld lines to indent... "
+msgstr "poèet øádkù k odsazení: %ld"
+
+msgid "1 line indented "
+msgstr "poèet øádkù k odsazení: 1"
+
+#, c-format
+msgid "%ld lines indented "
+msgstr "poèet odsazených øádkù: %ld"
+
+#. must display the prompt
+msgid "cannot yank; delete anyway"
+msgstr "nelze kopírovat; pøesto smazáno"
+
+msgid "1 line changed"
+msgstr "poèet øádek se zmìnìnou velikostí písmen: 1"
+
+#, c-format
+msgid "%ld lines changed"
+msgstr "poèet øádek se zmìnìnou velikostí písmen: %ld"
+
+#, c-format
+msgid "freeing %ld lines"
+msgstr "poèet uvolòovaných øádkù: %ld"
+
+msgid "1 line yanked"
+msgstr "poèet zkopírovaných øádkù: 1"
+
+#, c-format
+msgid "%ld lines yanked"
+msgstr "poèet zkopírovaných øádkù: %ld"
+
+#, c-format
+msgid "E353: Nothing in register %s"
+msgstr "E353: Registr %s je prázdný"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Registers ---"
+msgstr ""
+"\n"
+"--- Registry ---"
+
+msgid "Illegal register name"
+msgstr "nepøípustný název registru"
+
+msgid ""
+"\n"
+"# Registers:\n"
+msgstr ""
+"\n"
+"# Registry:\n"
+
+#, c-format
+msgid "Unknown register type %d"
+msgstr "%d není známým typem registru"
+
+#, c-format
+msgid "E354: Invalid register name: '%s'"
+msgstr "E354: '%s' není pøípustné jméno registru"
+
+#, c-format
+msgid "%ld Cols; "
+msgstr "øádkù: %ld;"
+
+#, c-format
+msgid "Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Bytes"
+msgstr "Vybráno %s%ld z %ld øádkù; %ld z %ld slov; %ld z %ld Bytù"
+
+#, c-format
+msgid "Col %s of %s; Line %ld of %ld; Word %ld of %ld; Byte %ld of %ld"
+msgstr "Sloupec %s z %s; Øádek %ld z %ld; Slovo %ld z %ld; Byte %ld z %ld"
+
+#, c-format
+msgid "(+%ld for BOM)"
+msgstr "(+%ld pro BOM)"
+
+msgid "Thanks for flying Vim"
+msgstr "Dìkuji za pou¾ití Vim"
+
+msgid "Option not supported"
+msgstr "Volba není podporována"
+
+msgid "Not allowed in a modeline"
+msgstr "Není v modeline povoleno"
+
+msgid ""
+"\n"
+"\tLast set from "
+msgstr ""
+"\n"
+"\tNaposledy nastavena z "
+
+msgid "Number required after ="
+msgstr "Po = je vy¾adováno èíslo"
+
+msgid "Not found in termcap"
+msgstr "Nenalezen v termcapu"
+
+#, c-format
+msgid "Illegal character <%s>"
+msgstr "Nepøípustný znak <%s>"
+
+msgid "Not allowed here"
+msgstr "Toto zde není povoleno"
+
+msgid "Cannot set 'term' to empty string"
+msgstr "volba 'term' nemù¾e být prázdná"
+
+msgid "Cannot change term in GUI"
+msgstr "V GUI nelze mìnit term"
+
+msgid "Use \":gui\" to start the GUI"
+msgstr "Pou¾ijte \"gui\" pro spu¹tìní GUI"
+
+msgid "'backupext' and 'patchmode' are equal"
+msgstr "volby 'backupext' a 'patchmode' mají stejnou hodnotu"
+
+msgid "Zero length string"
+msgstr "øetìzec o nulové délce"
+
+#, c-format
+msgid "Missing number after <%s>"
+msgstr "Po <%s> chybí èíslo"
+
+msgid "Missing comma"
+msgstr "Chybí èárka"
+
+msgid "Must specify a ' value"
+msgstr "Je nutné zadat hodnotu '"
+
+msgid "contains unprintable character"
+msgstr "obsahuje netisknutelné znaky"
+
+msgid "Invalid font(s)"
+msgstr "Chybná písma"
+
+msgid "can't select fontset"
+msgstr "nelze vybrat sadu písem"
+
+msgid "Invalid fontset"
+msgstr "chybná sada písem"
+
+msgid "can't select wide font"
+msgstr "nelze vybrat ¹iroký font"
+
+msgid "Invalid wide font"
+msgstr "Chybné ¹iroké písmo"
+
+#, c-format
+msgid "Illegal character after <%c>"
+msgstr "Nepøípustný znak po <%c>"
+
+msgid "comma required"
+msgstr "je nutná èárka"
+
+#, c-format
+msgid "'commentstring' must be empty or contain %s"
+msgstr "volba `commentstring` musí být buï prázdná nebo nastavená na %s"
+
+msgid "No mouse support"
+msgstr "Bez podpory my¹i"
+
+msgid "Unclosed expression sequence"
+msgstr "neuzavøená sekvence výrazù"
+
+msgid "too many items"
+msgstr "pøíli¹ mnoho polo¾ek"
+
+msgid "unbalanced groups"
+msgstr "nevyvá¾ené skupiny"
+
+msgid "A preview window already exists"
+msgstr "Okno náhledu ji¾ existuje"
+
+msgid "'winheight' cannot be smaller than 'winminheight'"
+msgstr ""
+"hodnota volby 'winheight' nesmí být men¹í ne¾ hodnota volby 'winminheight'"
+
+msgid "'winwidth' cannot be smaller than 'winminwidth'"
+msgstr ""
+"hodnota volby 'winwidth' nesmí být men¹í ne¾ hodnota volby 'winminwidth'"
+
+#, c-format
+msgid "Need at least %d lines"
+msgstr "minimální potøebný poèet øádkù: %d"
+
+#, c-format
+msgid "Need at least %d columns"
+msgstr "minimální potøebný poèet sloupcù: %d"
+
+#, c-format
+msgid "E355: Unknown option: %s"
+msgstr "E355: Neznámá volba: %s"
+
+msgid ""
+"\n"
+"--- Terminal codes ---"
+msgstr ""
+"\n"
+"--- Kódy terminálu ---"
+
+msgid ""
+"\n"
+"--- Global option values ---"
+msgstr ""
+"\n"
+"--- Nastavení globálních voleb ---"
+
+msgid ""
+"\n"
+"--- Local option values ---"
+msgstr ""
+"\n"
+"--- Nastavení lokálních voleb ---"
+
+msgid ""
+"\n"
+"--- Options ---"
+msgstr ""
+"\n"
+"--- Volby ---"
+
+msgid "E356: get_varp ERROR"
+msgstr "E356: get_varp CHYBA"
+
+#, c-format
+msgid "E357: 'langmap': Matching character missing for %s"
+msgstr "E357: 'langmap': pro %s chybí vyhovující znak"
+
+#, c-format
+msgid "E358: 'langmap': Extra characters after semicolon: %s"
+msgstr "E358: 'langmap': nadbyteèné znaky po støedníku: %s"
+
+msgid "cannot open "
+msgstr "nelze otevøít "
+
+msgid "VIM: Can't open window!\n"
+msgstr "VIM: Nelze otevøít nové okno!\n"
+
+msgid "Need Amigados version 2.04 or later\n"
+msgstr "Vy¾aduje Amigados verze 2.04 nebo vy¹¹í\n"
+
+#, c-format
+msgid "Need %s version %ld\n"
+msgstr "Vy¾aduje %s verze %ld\n"
+
+msgid "Cannot open NIL:\n"
+msgstr "Nelze otevøít NIL:\n"
+
+msgid "Cannot create "
+msgstr " Nelze vytvoøit "
+
+#, c-format
+msgid "Vim exiting with %d\n"
+msgstr "Vim bude ukonèen %d\n"
+
+msgid "cannot change console mode ?!\n"
+msgstr "Nelze zmìnit mód konzole ?!\n"
+
+msgid "E359: Screen mode setting not supported"
+msgstr "E359: Nastavování re¾imu obrazovky není podporováno"
+
+msgid "mch_get_shellsize: not a console??\n"
+msgstr "mch_get_shellsize: neni konzole??\n"
+
+#. if Vim opened a window: Executing a shell may cause crashes
+msgid "E360: Cannot execute shell with -f option"
+msgstr "E360: Nelze spustit shell s parametrem -f"
+
+msgid "Cannot execute "
+msgstr "Nelze spustit "
+
+msgid "shell "
+msgstr "shell "
+
+msgid " returned\n"
+msgstr " návratová hodnota shellu\n"
+
+msgid "ANCHOR_BUF_SIZE too small."
+msgstr "ANCHOR_BUF_SIZE je pøíli¹ malá."
+
+msgid "I/O ERROR"
+msgstr "I/O CHYBA"
+
+msgid "...(truncated)"
+msgstr "...(kráceno)"
+
+msgid "'columns' is not 80, cannot execute external commands"
+msgstr "'columns' není 80, nelze spustit externí pøíkaz"
+
+#, c-format
+msgid "E364: Library call failed for \"%s()\""
+msgstr "E364: Volání knihovní funkce \"%s()\" selhalo"
+
+msgid "E237: Printer selection failed"
+msgstr "E237: Nelze zvolit tiskárnu"
+
+#, c-format
+msgid "to %s on %s"
+msgstr "do %s v %s"
+
+#, c-format
+msgid "E238: Print error: %s"
+msgstr "E238: Chyba tisku: %s"
+
+msgid "Unknown"
+msgstr "Neznámý"
+
+#, c-format
+msgid "Printing '%s'"
+msgstr "Vyti¹tìno '%s'"
+
+#, c-format
+msgid "E244: Illegal charset name \"%s\" in font name \"%s\""
+msgstr "E244: Nepøípustná jméno znakové sady \"%s\" ve fontu \"%s\""
+
+#, c-format
+msgid "E245: Illegal char '%c' in font name \"%s\""
+msgstr "E245: Nepøípustný znak '%c' ve fontu \"%s\""
+
+msgid "E366: Invalid 'osfiletype' option - using Text"
+msgstr "E366: Neplatný 'osfiletype' - pou¾it Text"
+
+msgid "Vim: Double signal, exiting\n"
+msgstr "VIm: dvojitý signál, konèím\n"
+
+#, c-format
+msgid "Vim: Caught deadly signal %s\n"
+msgstr "Vim: Zachycen smrtelný signál %s\n"
+
+msgid "Vim: Caught deadly signal\n"
+msgstr "Vim: Zachycen smrtelný signál\n"
+
+#, c-format
+msgid "Opening the X display took %ld msec"
+msgstr "Doba otevírání X displeje (v ms): %ld"
+
+msgid ""
+"\n"
+"Vim: Got X error\n"
+msgstr ""
+"\n"
+"Vim: chyba X11\n"
+
+msgid "Testing the X display failed"
+msgstr "Test X displeje se nezdaøil"
+
+msgid "Opening the X display timed out"
+msgstr "Vypr¹el èas pøi èekání na otevøení X displeje"
+
+msgid ""
+"\n"
+"Cannot execute shell "
+msgstr ""
+"\n"
+"nelze spustit shell "
+
+msgid ""
+"\n"
+"Cannot execute shell sh\n"
+msgstr ""
+"\n"
+"Nelze spustit sh shell\n"
+
+msgid ""
+"\n"
+"shell returned "
+msgstr ""
+"\n"
+" návratová hodnota shellu "
+
+msgid ""
+"\n"
+"Cannot create pipes\n"
+msgstr ""
+"\n"
+"Nelze vytvoøit roury\n"
+
+msgid ""
+"\n"
+"Cannot fork\n"
+msgstr ""
+"\n"
+"Volání fork selhalo\n"
+
+msgid ""
+"\n"
+"Command terminated\n"
+msgstr ""
+"\n"
+"Pøíkaz ukonèen\n"
+
+msgid "Opening the X display failed"
+msgstr "Otevøení X displeje se nezdaøilo"
+
+msgid "At line"
+msgstr "Na øádku"
+
+msgid "Could not load vim32.dll!"
+msgstr "Nelze naèíst vim32.dll!"
+
+msgid "VIM Error"
+msgstr "Chyba VIMu"
+
+msgid "Could not fix up function pointers to the DLL!"
+msgstr "Nelze nastavit ukazatele funkcí na DLL"
+
+#, c-format
+msgid "shell returned %d"
+msgstr "návratová hodnota shellu %d"
+
+#, c-format
+msgid "Vim: Caught %s event\n"
+msgstr "Vim: Zachycen %s signál\n"
+
+msgid "close"
+msgstr "zavøít"
+
+msgid "logoff"
+msgstr "logoff"
+
+msgid "shutdown"
+msgstr "shutdown"
+
+msgid "E371: Command not found"
+msgstr "E371: Pøíkaz není k dispozici"
+
+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 se nevyskytuje ve Va¹í $PATH.\n"
+"Externí pøíkazy nebudou "
+
+msgid "Vim Warning"
+msgstr "Varování"
+
+msgid "E372: Too many %%%c in format string"
+msgstr "E372: Pøíli¹ mnoho %%%c ve formátovacím øetìzci"
+
+msgid "E373: Unexpected %%%c in format string"
+msgstr "E373: Neoèekávaný výskyt %%%c ve formátovacím øetìzci"
+
+msgid "E374: Missing ] in format string"
+msgstr "E374: Ve formátovacím øetìzci chybí ]"
+
+msgid "E375: Unsupported %%%c in format string"
+msgstr "E375: %%%c Nepodporovaná formátová specifikace ve formátovacím øetìzci"
+
+msgid "E376: Invalid %%%c in format string prefix"
+msgstr "E376: Nepøípustné %%%c v prefixu formátovacího øetìzce"
+
+msgid "E377: Invalid %%%c in format string"
+msgstr "E377: Nepøípustné %%%c ve formátovacím øetìzci"
+
+msgid "E378: 'errorformat' contains no pattern"
+msgstr "E378: 'errorformat' neobsahuje ¾ádný vzorek"
+
+msgid "E379: Missing or empty directory name"
+msgstr "E379: Chybìjící nebo prázdný název adresáøe"
+
+msgid "No more items"
+msgstr "®ádné dal¹í polo¾ky"
+
+#, c-format
+msgid "(%d of %d)%s%s: "
+msgstr "(%d/%d)%s%s: "
+
+msgid " (line deleted)"
+msgstr " (øádek smazán)"
+
+msgid "E380: At bottom of quickfix stack"
+msgstr "E380: Konec quickfix seznamu"
+
+msgid "E381: At top of quickfix stack"
+msgstr "E381: Zaèátek quickfix seznamu"
+
+#, c-format
+msgid "error list %d of %d; %d errors"
+msgstr "seznam chyb %d z %d; poèet chyb: %d"
+
+msgid "E382: Cannot write, 'buftype' option is set"
+msgstr "E382: Nelze ulo¾it, je nastavena volba 'buftype'"
+
+msgid "E339: Pattern too long"
+msgstr "E339: Vzor je pøíli¹ dlouhý"
+
+#, c-format
+msgid "E61: Nested %s*"
+msgstr "E61: %s*"
+
+#, c-format
+msgid "E62: Nested %s%c"
+msgstr "E62: %s%c"
+
+#, c-format
+msgid "E64: %s%c follows nothing"
+msgstr "E64: %s%c nic není"
+
+#, c-format
+msgid "Syntax error in %s{...}"
+msgstr "Chyba syntaxe v %s{...}"
+
+msgid "E361: Crash intercepted; regexp too complex?"
+msgstr "E361: Zachyceno pøeteèení zásobníku: pøíli¹ slo¾itý regulární výraz?"
+
+msgid "E363: pattern caused out-of-stack error"
+msgstr "E363: vzorek zpùsobil pøeteèení zásobníku"
+
+msgid "External submatches:\n"
+msgstr "Vnìj¹í podøazené shody:\n"
+
+#, c-format
+msgid "+--%3ld lines folded "
+msgstr "poèet øádkù v záhybu: %3ld"
+
+msgid " VREPLACE"
+msgstr " VREPLACE"
+
+msgid " REPLACE"
+msgstr " REPLACE"
+
+msgid " REVERSE"
+msgstr " REVERSE"
+
+msgid " INSERT"
+msgstr " INSERT"
+
+msgid " (insert)"
+msgstr " (insert)"
+
+msgid " (replace)"
+msgstr " (replace)"
+
+msgid " (vreplace)"
+msgstr " (vreplace)"
+
+msgid " Hebrew"
+msgstr " hebrejský"
+
+msgid " (lang)"
+msgstr " (lang)"
+
+msgid " (paste)"
+msgstr " (paste)"
+
+msgid " SELECT"
+msgstr " SHODY"
+
+msgid " VISUAL"
+msgstr " VIZUÁLNÍ"
+
+msgid " BLOCK"
+msgstr " BLOK"
+
+msgid " LINE"
+msgstr " ØÁDEK"
+
+msgid "recording"
+msgstr "nahrávám"
+
+msgid "search hit TOP, continuing at BOTTOM"
+msgstr "hledání dosáhlo zaèátku, pokraèování od konce"
+
+msgid "search hit BOTTOM, continuing at TOP"
+msgstr "hledání dosáhlo konce, pokraèování od zaèátku"
+
+#, c-format
+msgid "E383: Invalid search string: %s"
+msgstr "E383: Nepøípustný hledaný øetìzec: %s"
+
+#, c-format
+msgid "E384: search hit TOP without match for: %s"
+msgstr "E384: hledaný dosáhlo zaèátku bez nalezení %s"
+
+#, c-format
+msgid "E385: search hit BOTTOM without match for: %s"
+msgstr "E385: hledaný dosáhlo konce bez nalezení %s"
+
+msgid "E386: Expected '?' or '/' after ';'"
+msgstr "E386: Po ';' oèekávám '?' nebo '/'"
+
+msgid " (includes previously listed match)"
+msgstr " (vèetnì ji¾ vypsaných shod)"
+
+#. cursor at status line
+msgid "--- Included files "
+msgstr "--- Vlo¾ené soubory"
+
+msgid "not found "
+msgstr " nenalezeny"
+
+msgid "in path ---\n"
+msgstr "v cestì ---\n"
+
+msgid " (Already listed)"
+msgstr " (Ji¾ vypsáno)"
+
+msgid " NOT FOUND"
+msgstr " NENALEZENY"
+
+#, c-format
+msgid "Scanning included file: %s"
+msgstr "Prohledávám vlo¾ené soubory: %s"
+
+msgid "E387: Match is on current line"
+msgstr "E387: Shoda je na aktuálním øádku"
+
+msgid "All included files were found"
+msgstr "V¹echny vlo¾ené soubory byly nalezeny"
+
+msgid "No included files"
+msgstr "®ádné vlo¾ené soubory"
+
+msgid "E388: Couldn't find definition"
+msgstr "E388: Nelze nalézt definici"
+
+msgid "E389: Couldn't find pattern"
+msgstr "E389: Nelze nalézt vzorek"
+
+#, c-format
+msgid "E390: Illegal argument: %s"
+msgstr "E390: nepøípustný argument: %s"
+
+#, c-format
+msgid "E391: No such syntax cluster: %s"
+msgstr "E391: Syntaktická sestava %s neexistuje"
+
+msgid "No Syntax items defined for this buffer"
+msgstr "Pro tento buffer nejsou definovány ¾ádné pøedmìty syntaxe"
+
+msgid "syncing on C-style comments"
+msgstr "synchronizuji komentáøe v C stylu"
+
+msgid "no syncing"
+msgstr "¾ádná synchronizace"
+
+msgid "syncing starts "
+msgstr "synchronizace zaèíná "
+
+msgid " lines before top line"
+msgstr " øádkù pøed zaèátkem"
+
+msgid ""
+"\n"
+"--- Syntax sync items ---"
+msgstr ""
+"\n"
+"--- Polo¾ky synchronizace syntaxe ---"
+
+msgid ""
+"\n"
+"syncing on items"
+msgstr ""
+"\n"
+"synchronizuji pøedmìty"
+
+msgid ""
+"\n"
+"--- Syntax items ---"
+msgstr ""
+"\n"
+"--- Pøedmìty syntaxe ---"
+
+#, c-format
+msgid "E392: No such syntax cluster: %s"
+msgstr "E392: Syntaktická sestava %s neexistuje"
+
+msgid "minimal "
+msgstr "minimální "
+
+msgid "maximal "
+msgstr "maximální "
+
+msgid "E393: group[t]here not accepted here"
+msgstr "E393: group[t]here nesmí být na tomto místì"
+
+#, c-format
+msgid "E394: Didn't find region item for %s"
+msgstr "E394: Pro %s chybí polo¾ka regionu"
+
+msgid "E395: contains argument not accepted here"
+msgstr "E395: obsahuje argumenty, které zde nejsou povoleny"
+
+msgid "E396: containedin argument not accepted here"
+msgstr "E396: obsahuje argumenty, které zde nejsou povoleny"
+
+msgid "E397: Filename required"
+msgstr "E397: Vy¾adován název souboru"
+
+#, c-format
+msgid "E398: Missing '=': %s"
+msgstr "E398: Chybí '=': %s"
+
+#, c-format
+msgid "E399: Not enough arguments: syntax region %s"
+msgstr "E399: Pøíli¹ málo argumentù: oblast syntaxe %s"
+
+msgid "E400: No cluster specified"
+msgstr "E400: Nebyla zadána ¾ádná sestava"
+
+#, c-format
+msgid "E401: Pattern delimiter not found: %s"
+msgstr "E401: Oddìlovaè vzorku %s nenalezen"
+
+#, c-format
+msgid "E402: Garbage after pattern: %s"
+msgstr "E402: Chyba za vzorkem %s"
+
+msgid "E403: syntax sync: line continuations pattern specified twice"
+msgstr "E403: synchronizace syntaxe: vzorek pokraèování øádkù zadán dvakrát"
+
+#, c-format
+msgid "E404: Illegal arguments: %s"
+msgstr "E404: nepøípustný argument: %s"
+
+#, c-format
+msgid "E405: Missing equal sign: %s"
+msgstr "E405: Chybí rovnítko: %s"
+
+#, c-format
+msgid "E406: Empty argument: %s"
+msgstr "E406: Prázdný argument: %s"
+
+#, c-format
+msgid "E407: %s not allowed here"
+msgstr "E407: %s zde není povoleno"
+
+#, c-format
+msgid "E408: %s must be first in contains list"
+msgstr "E408: %s musí být první v 'contains' seznamu"
+
+#, c-format
+msgid "E409: Unknown group name: %s"
+msgstr "E409: Neznámá název skupiny: %s"
+
+#, c-format
+msgid "E410: Invalid :syntax subcommand: %s"
+msgstr "E410: chybný podøazený pøíkaz :syntax : %s "
+
+#, c-format
+msgid "E411: highlight group not found: %s"
+msgstr "E411: skupina zvýraznìní %s nebyla nalezena"
+
+#, c-format
+msgid "E412: Not enough arguments: \":highlight link %s\""
+msgstr "E412: Pøíli¹ málo argumentù: \":highlight link %s\""
+
+#, c-format
+msgid "E413: Too many arguments: \":highlight link %s\""
+msgstr "E413: Pøíli¹ mnoho argumentù: \":highlight link %s\""
+
+msgid "E414: group has settings, highlight link ignored"
+msgstr "E414: skupina je nastavena, odkaz na zvýrazòovací skupinu ignorován"
+
+#, c-format
+msgid "E415: unexpected equal sign: %s"
+msgstr "E415: neèekané rovnítko : %s"
+
+#, c-format
+msgid "E416: missing equal sign: %s"
+msgstr "E416: chybné rovnítko: %s"
+
+#, c-format
+msgid "E417: missing argument: %s"
+msgstr "E417: chybí argument: %s"
+
+#, c-format
+msgid "E418: Illegal value: %s"
+msgstr "E418: nepøípustná hodnota: %s"
+
+msgid "E419: FG color unknown"
+msgstr "E419: barva popøedí není známá"
+
+msgid "E420: BG color unknown"
+msgstr "E420: barva popøedí není známá"
+
+#, c-format
+msgid "E421: Color name or number not recognized: %s"
+msgstr "E421: název èi èíslo barvy %s nebylo rozpoznáno"
+
+#, c-format
+msgid "E422: terminal code too long: %s"
+msgstr "E422: terminálový kód %s je pøíli¹ dlouhý"
+
+#, c-format
+msgid "E423: Illegal argument: %s"
+msgstr "E423: nepøípustný argument: %s"
+
+msgid "E424: Too many different highlighting attributes in use"
+msgstr ""
+"E424: Je pou¾íváno pøíli¹ velké mno¾ství odli¹ných zvýrazòovacích atributù"
+
+msgid "at bottom of tag stack"
+msgstr "konec seznamu tagù"
+
+msgid "at top of tag stack"
+msgstr "zaèátek seznamu tagù"
+
+msgid "E425: Cannot go before first matching tag"
+msgstr "E425: Pøed první vyhovující tag nelze pøeskoèit"
+
+#, c-format
+msgid "E426: tag not found: %s"
+msgstr "E426: tag %s nenalezen"
+
+msgid " # pri kind tag"
+msgstr " # pri typ tag"
+
+msgid "file\n"
+msgstr "soubor\n"
+
+#.
+#. * Ask to select a tag from the list.
+#. * When using ":silent" assume that <CR> was entered.
+#.
+msgid "Enter nr of choice (<CR> to abort): "
+msgstr "Zadejte èíslo (<CR> pro ukonèení): "
+
+msgid "E427: There is only one matching tag"
+msgstr "E427: Vyhovuje pouze jeden tag"
+
+msgid "E428: Cannot go beyond last matching tag"
+msgstr "E428: Za poslední vyhovující tag nelze pøeskoèit"
+
+#, c-format
+msgid "File \"%s\" does not exist"
+msgstr "Soubor \"%s\" neexistuje"
+
+#. Give an indication of the number of matching tags
+#, c-format
+msgid "tag %d of %d%s"
+msgstr "tag %d z celkového poètu %d%s"
+
+msgid " or more"
+msgstr " nebo více"
+
+msgid " Using tag with different case!"
+msgstr " Pou¾ívám tag s písmeny jiné velikosti!"
+
+#, c-format
+msgid "E429: File \"%s\" does not exist"
+msgstr "E429: \"%s\" neexistuje"
+
+#. Highlight title
+msgid ""
+"\n"
+" # TO tag FROM line in file/text"
+msgstr ""
+"\n"
+" # CÍL tag START øádek v souboru/textu"
+
+msgid "Linear tag search"
+msgstr "Lineární hledání tagu"
+
+msgid "Binary tag search"
+msgstr "Binární hledání tagu"
+
+#, c-format
+msgid "Searching tags file %s"
+msgstr "Prohledávám soubor tagù %s"
+
+#, c-format
+msgid "E430: Tag file path truncated for %s\n"
+msgstr "E430: Soubor tagù %s byl oøezán\n"
+
+#, c-format
+msgid "E431: Format error in tags file \"%s\""
+msgstr "E431: Chyba formátu v souboru tagù \"%s\""
+
+#, c-format
+msgid "Before byte %ld"
+msgstr "Pøed bajtem %ld"
+
+#, c-format
+msgid "E432: Tags file not sorted: %s"
+msgstr "E432: Obsah soubor tagù %s není seøazen"
+
+#. never opened any tags file
+msgid "E433: No tags file"
+msgstr "E433: ®ádný soubor tagù"
+
+msgid "E434: Can't find tag pattern"
+msgstr "E434: Nelze najít vzorek tagù"
+
+msgid "E435: Couldn't find tag, just guessing!"
+msgstr "E435: Tag nelze nalézt, pouze hádám!"
+
+msgid "' not known. Available builtin terminals are:"
+msgstr "' není znám. Dostupné vestavìné terminály:"
+
+msgid "defaulting to '"
+msgstr "implicitní terminál '"
+
+msgid "Cannot open termcap file"
+msgstr "Nelze otevøít termcap"
+
+msgid "Terminal entry not found in terminfo"
+msgstr "Terminfo neobsahuje polo¾ku pro tento terminál"
+
+msgid "Terminal entry not found in termcap"
+msgstr "Termcap neobsahuje polo¾ku pro tento terminál"
+
+#, c-format
+msgid "E436: No \"%s\" entry in termcap"
+msgstr "E436: Termcap neobsahuje polo¾ku pro \"%s\""
+
+msgid "E437: terminal capability \"cm\" required"
+msgstr "E437: Terminál musí mít schopnost \"cm\""
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Terminal keys ---"
+msgstr ""
+"\n"
+"--- Klávesy terminálu ---"
+
+msgid "new shell started\n"
+msgstr "spu¹tìn nový shell\n"
+
+msgid "Vim: Error reading input, exiting...\n"
+msgstr "Vim: chyba pøi ètení vstupu, konèím...\n"
+
+#. must display the prompt
+msgid "No undo possible; continue anyway"
+msgstr "odstranìní zmìn není mo¾né; chcete pøesto pokraèovat"
+
+msgid "E438: u_undo: line numbers wrong"
+msgstr "E438: u_undo: èísla øádkù jsou chybná"
+
+msgid "1 change"
+msgstr "poèet zmìn: 1"
+
+#, c-format
+msgid "%ld changes"
+msgstr "poèet zmìn: %ld"
+
+msgid "E439: undo list corrupt"
+msgstr "E439: záznam o zmìnách po¹kozen"
+
+msgid "E440: undo line missing"
+msgstr "E440: chybí undo øádek"
+
+#. Only MS VC 4.1 and earlier can do Win32s
+msgid ""
+"\n"
+"MS-Windows 16/32-bit GUI version"
+msgstr ""
+"\n"
+"16/32 bitová GUI verze pro MS Windows"
+
+msgid ""
+"\n"
+"MS-Windows 32-bit GUI version"
+msgstr ""
+"\n"
+"32 bitová GUI verze pro MS Windows"
+
+msgid " in Win32s mode"
+msgstr " ve Win32s re¾imu"
+
+msgid " with OLE support"
+msgstr " s OLE podporou"
+
+msgid ""
+"\n"
+"MS-Windows 32-bit console version"
+msgstr ""
+"\n"
+"32 bitová verze pro MS Windows konzolu"
+
+msgid ""
+"\n"
+"MS-Windows 16-bit version"
+msgstr ""
+"\n"
+"16 bitová verze pro MS Windows"
+
+msgid ""
+"\n"
+"32-bit MS-DOS version"
+msgstr ""
+"\n"
+"32 bitová verze pro MS Windows"
+
+msgid ""
+"\n"
+"16-bit MS-DOS version"
+msgstr ""
+"\n"
+"16 bitová MS-DOS verze"
+
+msgid ""
+"\n"
+"MacOS X (unix) version"
+msgstr ""
+"\n"
+"MacOS X (unix) verze"
+
+msgid ""
+"\n"
+"MacOS X version"
+msgstr ""
+"\n"
+"MacOS X verze"
+
+msgid ""
+"\n"
+"MacOS version"
+msgstr ""
+"\n"
+"MacOS verze"
+
+msgid ""
+"\n"
+"RISC OS version"
+msgstr ""
+"\n"
+"RISC OS verze"
+
+msgid ""
+"\n"
+"Included patches: "
+msgstr ""
+"\n"
+"Pou¾ité záplaty: "
+
+msgid ""
+"\n"
+"Compiled "
+msgstr ""
+"\n"
+"pøelo¾il "
+
+msgid "by "
+msgstr " "
+
+msgid ""
+"\n"
+"Huge version "
+msgstr ""
+"\n"
+"maximální verze"
+
+msgid ""
+"\n"
+"Big version "
+msgstr ""
+"\n"
+"velká verze "
+
+msgid ""
+"\n"
+"Normal version "
+msgstr ""
+"\n"
+"normální verze"
+
+msgid ""
+"\n"
+"Small version "
+msgstr ""
+"\n"
+"malá verze "
+
+msgid ""
+"\n"
+"Tiny version "
+msgstr ""
+"\n"
+"minimální verze"
+
+msgid "without GUI."
+msgstr "bez grafického rozhraní"
+
+msgid "with GTK-GNOME GUI."
+msgstr "s rozhraním GTK-GNOME"
+
+msgid "with GTK GUI."
+msgstr "s rozhraním GTK"
+
+msgid "with X11-Motif GUI."
+msgstr "s rozhraním X11-Motif"
+
+msgid "with X11-Athena GUI."
+msgstr "S rozhraním X11-Athena"
+
+msgid "with BeOS GUI."
+msgstr "s rozhraním BeOS"
+
+msgid "with Photon GUI."
+msgstr "s rozhraním Photon"
+
+msgid "with GUI."
+msgstr "s grafickým rozhraním"
+
+msgid "with Carbon GUI."
+msgstr "s grafickým rozhraním Carbon"
+
+msgid "with Cocoa GUI."
+msgstr "s grafickým rozhraním Cocoa"
+
+msgid "with (classic) GUI."
+msgstr "s (clasickým) grafickým rozhraním"
+
+msgid " Features included (+) or not (-):\n"
+msgstr " Vlastnosti zahrnuté (+) a nezahrnuté (-):\n"
+
+msgid " system vimrc file: \""
+msgstr " systémový vimrc soubor: \""
+
+msgid " user vimrc file: \""
+msgstr " u¾ivatelský vimrc soubor: \""
+
+msgid " 2nd user vimrc file: \""
+msgstr " druhý u¾ivatelský vimrc soubor: \""
+
+msgid " 3rd user vimrc file: \""
+msgstr " tøetí u¾ivatelský vimrc soubor: \""
+
+msgid " user exrc file: \""
+msgstr " u¾ivatelský exrc soubor: \""
+
+msgid " 2nd user exrc file: \""
+msgstr " druhý u¾ivatelský exrc soubor: \""
+
+msgid " system gvimrc file: \""
+msgstr " systémový gvimrc soubor: \""
+
+msgid " user gvimrc file: \""
+msgstr " u¾ivatelský gvimrc soubor: \""
+
+msgid "2nd user gvimrc file: \""
+msgstr "druhý u¾ivatelský gvimrc soubor: \""
+
+msgid "3rd user gvimrc file: \""
+msgstr "tøetí u¾ivatelský gvimrc soubor: \""
+
+msgid " system menu file: \""
+msgstr " systémový soubor s menu: \""
+
+msgid " fall-back for $VIM: \""
+msgstr " implicitní hodnota $VIM:\""
+
+msgid " f-b for $VIMRUNTIME: \""
+msgstr " implicitní hodnota $VIMRUNTIME: \""
+
+msgid "Compilation: "
+msgstr "Pøeklad: "
+
+msgid "Compiler: "
+msgstr "Pøekladaè: "
+
+msgid "Linking: "
+msgstr "Linkuji: "
+
+msgid " DEBUG BUILD"
+msgstr " PODPORA LADÌNÍ"
+
+msgid "VIM - Vi IMproved"
+msgstr "VIM - Vi IMproved"
+
+msgid "version "
+msgstr "verze "
+
+msgid "by Bram Moolenaar et al."
+msgstr "Autor: Bram Moolenaar a dal¹í"
+
+msgid "Vim is open source and freely distributable"
+msgstr "Vim je volnì ¹iøitelný program s otevøeným zdrojovým kódem"
+
+msgid "Help poor children in Uganda!"
+msgstr "Pomozte chudým dìtem v Ugandì!"
+
+msgid "type :help iccf<Enter> for information "
+msgstr "podrobnìj¹í informace získáte pomocí :help iccf<Enter>"
+
+msgid "type :q<Enter> to exit "
+msgstr "zadejte :q<Enter> pro ukonèení programu"
+
+msgid "type :help<Enter> or <F1> for on-line help"
+msgstr "zadejte :help<Enter> èi <F1> pro nápovìdu"
+
+msgid "type :help version7<Enter> for version info"
+msgstr "zadejte :help version7<Enter> pro informace o verzi 6"
+
+msgid "Running in Vi compatible mode"
+msgstr "Bì¾ím v re¾imu kompatibility s Vi"
+
+msgid "type :set nocp<Enter> for Vim defaults"
+msgstr "zadejte :set nocp<Enter> pro implicitní nastavení Vim"
+
+msgid "type :help cp-default<Enter> for info on this"
+msgstr "podrobnìj¹í informace získáte pomocí :help cp-default<Enter>"
+
+msgid "WARNING: Windows 95/98/ME detected"
+msgstr "VAROVÁNÍ: detekovány Windows 95/98/ME"
+
+msgid "type :help windows95<Enter> for info on this"
+msgstr "zadejte :help windows95<Enter> pro podrobnìj¹í informace"
+
+msgid "E441: There is no preview window"
+msgstr "E441: Není ¾ádné preview okno není"
+
+msgid "E442: Can't split topleft and botright at the same time"
+msgstr "E442: Okno nelze rozdìlit zároveò topleft a botright"
+
+msgid "E443: Cannot rotate when another window is split"
+msgstr "E443: Nelze rotovat, pokud je jiné okno rozdìleno"
+
+msgid "E444: Cannot close last window"
+msgstr "E444: Poslední okno nelze uzavøít"
+
+msgid "Already only one window"
+msgstr "Ji¾ existuje pouze jedno okno"
+
+msgid "E445: Other window contains changes"
+msgstr "E445: Jiné okno obsahuje zmìny"
+
+msgid "E446: No file name under cursor"
+msgstr "E446: Pod kurzorem se nenachází název souboru"
+
+#, c-format
+msgid "E447: Can't find file \"%s\" in path"
+msgstr "E447: Soubor \"%s\" nelze v path nalézt"
+
+msgid "Edit with &multiple Vims"
+msgstr "Editace &multiple Vimy"
+
+msgid "Edit with single &Vim"
+msgstr "Editace jedním $Vim -em"
+
+msgid "Edit with &Vim"
+msgstr "Editace &Vim -em"
+
+msgid "Edit with existing Vim - &"
+msgstr "Editace existujícím Vimem - &"
+
+msgid "Edits the selected file(s) with Vim"
+msgstr "Editace vybraných souborù Vimem"
+
+msgid "Error creating process: Check if gvim is in your path!"
+msgstr "Chyba pøi spou¹tìní procesu: Zkontrolujte zdali je gvim v $PATH!"
+
+msgid "gvimext.dll error"
+msgstr "chyba gvimext.dll"
+
+msgid "Path length too long!"
+msgstr "Název (v path) je pøíli¹ dlouhý"
+
+msgid "--No lines in buffer--"
+msgstr "--Buffer neobsahuje ¾ádný øádek--"
+
+#.
+#. * The error messages that can be shared are included here.
+#. * Excluded are errors that are only used once and debugging messages.
+#.
+msgid "Command aborted"
+msgstr "Pøíkaz pøeru¹en"
+
+msgid "Argument required"
+msgstr "Je vy¾adován argument"
+
+msgid "E10: \\ should be followed by /, ? or &"
+msgstr "E10: po \\ by mìl následovat /. ? nebo &"
+
+msgid "E11: Invalid in command-line window; <CR> executes, CTRL-C quits"
+msgstr ""
+"E11: Chyba v oknì pøíkazové øádky; <CR> pro spu¹t¹ní, CTRL-C pro ukonèení"
+
+msgid "E12: Command not allowed from exrc/vimrc in current dir or tag search"
+msgstr ""
+"E12: Pøíkaz není z exrc/vimrc v aktuálním adresáøi èi pøi hledání tagu "
+"povolen."
+
+msgid "E13: File exists (add ! to override)"
+msgstr "E13: Soubor existuje (pou¾ijte ! pro vynucení)"
+
+msgid "Command failed"
+msgstr "Pøíkaz selhal"
+
+msgid "Internal error"
+msgstr "Vnitøní chyba"
+
+msgid "Interrupted"
+msgstr "Pøeru¹eno"
+
+msgid "E14: Invalid address"
+msgstr "E14: Chybná adresa"
+
+msgid "Invalid argument"
+msgstr "Chybný argument"
+
+#, c-format
+msgid "Invalid argument: %s"
+msgstr "Chybný argument: %s"
+
+#, c-format
+msgid "E15: Invalid expression: %s"
+msgstr "E15: Chybný výraz: %s"
+
+msgid "E16: Invalid range"
+msgstr "E16: Chybný rozsah"
+
+msgid "Invalid command"
+msgstr "Chybný pøíkaz"
+
+#, c-format
+msgid "E17: \"%s\" is a directory"
+msgstr "E17: \"%s\" je adresáøem"
+
+msgid "E18: Unexpected characters before '='"
+msgstr "E18: Neoèekávané znaky pøed '='"
+
+msgid "E19: Mark has invalid line number"
+msgstr "E19: Znaèka má chybné èíslo øádku"
+
+msgid "E20: Mark not set"
+msgstr "E20: není nastavena"
+
+msgid "E21: Cannot make changes, 'modifiable' is off"
+msgstr "E21: Nelze mìnit, je nastavena volba 'modifiable'"
+
+msgid "E22: Scripts nested too deep"
+msgstr "E22: Skript vnoøen pøíli¹ hluboko"
+
+msgid "E23: No alternate file"
+msgstr "E23: ®ádný alternativní soubor"
+
+msgid "E24: No such abbreviation"
+msgstr "E24: Taková zkratka neexistuje"
+
+msgid "No ! allowed"
+msgstr "! není povoleno"
+
+msgid "E25: GUI cannot be used: Not enabled at compile time"
+msgstr "E25: Nelze pou¾ít GUI: nebylo zapnuto pøi pøekladu programu"
+
+msgid "E26: Hebrew cannot be used: Not enabled at compile time\n"
+msgstr ""
+"E26: nelze pou¾ít hebrejský re¾im: nebyl zapnut pøi pøekladu programu\n"
+
+msgid "E27: Farsi cannot be used: Not enabled at compile time\n"
+msgstr "E27: Nelze pou¾ít farsi re¾im: nebyl zapnut pøi pøekladu programu\n"
+
+#, c-format
+msgid "E28: No such highlight group name: %s"
+msgstr "E28: Skupina zvýraznìní %s neexistuje"
+
+msgid "E29: No inserted text yet"
+msgstr "E29: Zatím není ¾ádný vlo¾ený text"
+
+msgid "E30: No previous command line"
+msgstr "E30: ®ádná pøedchozí pøíkazová øádka"
+
+msgid "E31: No such mapping"
+msgstr "E31: ®ádné takové mapování"
+
+msgid "No match"
+msgstr "®ádná shoda"
+
+#, c-format
+msgid "No match: %s"
+msgstr "®ádná shoda: %s"
+
+msgid "E32: No file name"
+msgstr "E32: ®ádný název souboru"
+
+msgid "E33: No previous substitute regular expression"
+msgstr "E33: ¾ádný pøedchozí regulární výraz"
+
+msgid "E34: No previous command"
+msgstr "E34: ®ádný pøedchozí pøíkaz"
+
+msgid "E35: No previous regular expression"
+msgstr "E35: ¾ádný pøedchozí regulární výraz"
+
+msgid "No range allowed"
+msgstr "Rozsah není povolen"
+
+msgid "E36: Not enough room"
+msgstr "E36: Nedostatek místa"
+
+#, c-format
+msgid "Can't create file %s"
+msgstr "Nelze vytvoøit soubor %s"
+
+msgid "Can't get temp file name"
+msgstr "Nelze získat název doèasného souboru"
+
+#, c-format
+msgid "Can't open file %s"
+msgstr "Nelze otevøít soubor %s"
+
+#, c-format
+msgid "Can't read file %s"
+msgstr "Nelze èíst soubor %s"
+
+msgid "E37: No write since last change (use ! to override)"
+msgstr "E37: Neulo¾ené zmìny (pou¾ijte ! pro vynucení)"
+
+msgid "E38: Null argument"
+msgstr "E38: Nulový argument"
+
+msgid "E39: Number expected"
+msgstr "E39: Oèekáváno èíslo"
+
+#, c-format
+msgid "E40: Can't open errorfile %s"
+msgstr "E40: Nelze otevøít chybový soubor %s"
+
+msgid "E41: Out of memory!"
+msgstr "E41: Nedostatek pamìti!"
+
+msgid "Pattern not found"
+msgstr "Vzor nenalezen"
+
+#, c-format
+msgid "Pattern not found: %s"
+msgstr "Vzor nenalezen: %s"
+
+msgid "Argument must be positive"
+msgstr "Argument musí být kladný"
+
+msgid "E42: No Errors"
+msgstr "E42: ®ádné chyby"
+
+msgid "E43: Damaged match string"
+msgstr "E43: Po¹kozený øetìzec pro vyhledávání"
+
+msgid "E44: Corrupted regexp program"
+msgstr "E44: po¹kozený regexp program"
+
+msgid "E45: 'readonly' option is set (use ! to override)"
+msgstr "E45: 'nastavena volba 'readonly' (pou¾ijte ! pro vynucení)"
+
+#, c-format
+msgid "E46: Cannot set read-only variable \"%s\""
+msgstr "E46: Nelze nastavit pouze_pro_ètení promìnnou \"%s\""
+
+msgid "E47: Error while reading errorfile"
+msgstr "E47: Chyba pøi ètení chybového souboru"
+
+msgid "E48: Not allowed in sandbox"
+msgstr "E48: Není v bezpeènostní schránce povoleno"
+
+msgid "E49: Invalid scroll size"
+msgstr "E49: Chybná hodnota volby 'scroll'"
+
+msgid "E91: 'shell' option is empty"
+msgstr "E91: volba 'shell' je prázdná"
+
+msgid "E72: Close error on swap file"
+msgstr "E72: Chyba pøi uzavírání odkládacího souboru"
+
+msgid "E73: tag stack empty"
+msgstr "E73: seznam tagù je prázdný"
+
+msgid "E74: Command too complex"
+msgstr "E74: Pøíkaz je pøíli¹ slo¾itý"
+
+msgid "E75: Name too long"
+msgstr "E75: Název je pøíli¹ dlouhý"
+
+msgid "E76: Too many ["
+msgstr "E76: pøíli¹ mnoho ["
+
+msgid "E77: Too many file names"
+msgstr "E77: Pøíli¹ mnoho názvù souborù"
+
+msgid "Trailing characters"
+msgstr "Nadbyteèné znaky na konci"
+
+msgid "E78: Unknown mark"
+msgstr "E78: Neznámá znaèka"
+
+msgid "E79: Cannot expand wildcards"
+msgstr "E79: Nelze expandovat ¾olíkové znaky"
+
+msgid "E80: Error while writing"
+msgstr "E80: Chyba pøi ukládání"
+
+msgid "Zero count"
+msgstr "Nulový poèet"
+
+msgid "E81: Using <SID> not in a script context"
+msgstr "E81: Pou¾ití <SID> mimo kontext skriptu"
diff --git a/src/po/de.po b/src/po/de.po
new file mode 100644
index 0000000000..6369af4cbc
--- /dev/null
+++ b/src/po/de.po
@@ -0,0 +1,6117 @@
+# German 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.
+#
+# Previous-Translator(s):
+# Johannes Zellner <johannes@zellner.org>
+# Gerfried Fuchs <alfie@ist.org>
+
+msgid ""
+msgstr ""
+"Project-Id-Version: Vim(deutsch)\n"
+"POT-Creation-Date: 2006-04-02 11:30+0200\n"
+"PO-Revision-Date: 2008-05-24 17:26+0200\n"
+"Last-Translator: Georg Dahn <georg.dahn@gmail.com>\n"
+"Language-Team: German <de@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=ISO_8859-1\n"
+"Content-Transfer-Encoding: 8-bit\n"
+
+msgid "E82: Cannot allocate any buffer, exiting..."
+msgstr "E82: Kann keinen Puffer zuweisen; beenden..."
+
+msgid "E83: Cannot allocate buffer, using other one..."
+msgstr "E83: Kann den Puffer nicht zuweisen; benutze einen anderen..."
+
+msgid "E515: No buffers were unloaded"
+msgstr "E515: Keine Puffer wurden entladen"
+
+msgid "E516: No buffers were deleted"
+msgstr "E516: Keine Puffer wurden vollständig gelöscht"
+
+msgid "E517: No buffers were wiped out"
+msgstr "E517: Keine Puffer wurden vollständig gelöscht"
+
+msgid "1 buffer unloaded"
+msgstr "ein Puffer entladen"
+
+#, c-format
+msgid "%d buffers unloaded"
+msgstr "%d Puffer entladen"
+
+msgid "1 buffer deleted"
+msgstr "ein Puffer gelöscht"
+
+#, c-format
+msgid "%d buffers deleted"
+msgstr "%d Puffer gelöscht"
+
+msgid "1 buffer wiped out"
+msgstr "ein Puffer vollständig gelöscht"
+
+#, c-format
+msgid "%d buffers wiped out"
+msgstr "%d Puffer vollständig gelöscht"
+
+msgid "E84: No modified buffer found"
+msgstr "E84: Kein veränderter Puffer gefunden"
+
+#. back where we started, didn't find anything.
+msgid "E85: There is no listed buffer"
+msgstr "E85: Es gibt keine angezeigten Puffer"
+
+#, c-format
+msgid "E86: Buffer %ld does not exist"
+msgstr "E86: Puffer %ld existiert nicht"
+
+msgid "E87: Cannot go beyond last buffer"
+msgstr "E87: Kann nicht über den letzten Puffer hinaus gehen"
+
+msgid "E88: Cannot go before first buffer"
+msgstr "E88: Kann nicht vor den ersten Puffer gehen"
+
+#, c-format
+msgid "E89: No write since last change for buffer %ld (add ! to override)"
+msgstr "E89: Puffer %ld nicht gesichert seit der letzten Änderung (erzwinge mit !)"
+
+msgid "E90: Cannot unload last buffer"
+msgstr "E90: Kann letzten Puffer nicht ausladen"
+
+msgid "W14: Warning: List of file names overflow"
+msgstr "W14: Achtung: Überlauf der Liste der Dateinamen"
+
+#, c-format
+msgid "E92: Buffer %ld not found"
+msgstr "E92: Kein Puffer %ld gefunden"
+
+#, c-format
+msgid "E93: More than one match for %s"
+msgstr "E93: Mehr als ein Treffer für %s"
+
+#, c-format
+msgid "E94: No matching buffer for %s"
+msgstr "E94: Kein übereinstimmender Puffer für %s"
+
+#, c-format
+msgid "line %ld"
+msgstr "Zeile %ld"
+
+msgid "E95: Buffer with this name already exists"
+msgstr "E95: Ein Puffer mit diesem Namen existiert bereits"
+
+msgid " [Modified]"
+msgstr " [Verändert]"
+
+msgid "[Not edited]"
+msgstr "[Nicht editiert]"
+
+msgid "[New file]"
+msgstr "[Neue Datei]"
+
+msgid "[Read errors]"
+msgstr "[Lesefehler]"
+
+msgid "[readonly]"
+msgstr "[Nur Lesen]"
+
+#, c-format
+msgid "1 line --%d%%--"
+msgstr "1 Zeile --%d%%--"
+
+#, c-format
+msgid "%ld lines --%d%%--"
+msgstr "%ld Zeilen --%d%%--"
+
+#, c-format
+msgid "line %ld of %ld --%d%%-- col "
+msgstr "Zeile %ld von %ld --%d%%-- Spalte "
+
+msgid "[No Name]"
+msgstr "[Unbenannt]"
+
+#. must be a help buffer
+msgid "help"
+msgstr "Hilfe"
+
+msgid "[Help]"
+msgstr "[Hilfe]"
+
+msgid "[Preview]"
+msgstr "[Vorschau]"
+
+msgid "All"
+msgstr "Alles"
+
+msgid "Bot"
+msgstr "Ende"
+
+msgid "Top"
+msgstr "Anfang"
+
+#, c-format
+msgid ""
+"\n"
+"# Buffer list:\n"
+msgstr ""
+"\n"
+"# Liste der Puffer:\n"
+
+msgid "[Location List]"
+msgstr "[Positionsliste]"
+
+msgid "[Quickfix List]"
+msgstr "[QuickFix-Liste]"
+
+msgid ""
+"\n"
+"--- Signs ---"
+msgstr ""
+"\n"
+"--- Zeichen ---"
+
+#, c-format
+msgid "Signs for %s:"
+msgstr "Zeichen für %s:"
+
+#, c-format
+msgid " line=%ld id=%d name=%s"
+msgstr " Zeile=%ld id=%d Name=%s"
+
+#, c-format
+msgid "E96: Can not diff more than %ld buffers"
+msgstr "E96: Keine Differenz für mehr als %ld Puffer"
+
+msgid "E97: Cannot create diffs"
+msgstr "E97: Kann keine Differenz erstellen"
+
+msgid "Patch file"
+msgstr "Patch-Datei"
+
+msgid "E98: Cannot read diff output"
+msgstr "E98: Differenz-Ausgabe kann nicht gelesen werden"
+
+msgid "E99: Current buffer is not in diff mode"
+msgstr "E99: Aktueller Puffer ist nicht im Differenz-Modus"
+
+msgid "E100: No other buffer in diff mode"
+msgstr "E100: Kein weiterer Puffer ist im Differenz-Modus"
+
+msgid "E101: More than two buffers in diff mode, don't know which one to use"
+msgstr "E101: Mehrdeutigkeit: Mehr als zwei Puffer im Differenz-Modus"
+
+#, c-format
+msgid "E102: Can't find buffer \"%s\""
+msgstr "E102: Kann Puffer \"%s\" nicht finden"
+
+#, c-format
+msgid "E103: Buffer \"%s\" is not in diff mode"
+msgstr "E103: Puffer \"%s\" ist nicht im Differenz-Modus"
+
+msgid "E104: Escape not allowed in digraph"
+msgstr "E104: 'Escape' ist in einem Digraphen nicht erlaubt"
+
+msgid "E544: Keymap file not found"
+msgstr "E544: Datei für die Tastaturbelegung nicht gefunden"
+
+msgid "E105: Using :loadkeymap not in a sourced file"
+msgstr "E105: :loadkeymap außerhalb einer eingelesenen Datei"
+
+msgid " Keyword completion (^N^P)"
+msgstr " Stichwort-Ergänzung (^N^P)"
+
+#. ctrl_x_mode == 0, ^P/^N compl.
+msgid " ^X mode (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)"
+msgstr " ^X Modus (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)"
+
+msgid " Whole line completion (^L^N^P)"
+msgstr " Zeilen-Ergänzung (^L^N^P)"
+
+msgid " File name completion (^F^N^P)"
+msgstr " Dateinamen-Ergänzung (^F^N^P)"
+
+msgid " Tag completion (^]^N^P)"
+msgstr " Tag-Ergänzung (^]^N^P)"
+
+msgid " Path pattern completion (^N^P)"
+msgstr " Pfadmuster-Ergänzung (^N^P)"
+
+msgid " Definition completion (^D^N^P)"
+msgstr " Definitions-Ergänzung (^D^N^P)"
+
+msgid " Dictionary completion (^K^N^P)"
+msgstr " Wörterbuch-Ergänzung (^K^N^P) "
+
+msgid " Thesaurus completion (^T^N^P)"
+msgstr " Thesaurus-Ergänzung (^T^N^P)"
+
+msgid " Command-line completion (^V^N^P)"
+msgstr " Kommandozeilen-Ergänzung (^V^N^P)"
+
+msgid " User defined completion (^U^N^P)"
+msgstr " Benutzerdefinierte Ergänzung (^U^N^P)"
+
+msgid " Omni completion (^O^N^P)"
+msgstr " Omni-Ergänzung (^O^N^P)"
+
+msgid " Spelling suggestion (s^N^P)"
+msgstr " Vorschlag der Rechtschreibprüfung (s^N^P)"
+
+msgid " Keyword Local completion (^N^P)"
+msgstr " Lokale Schlüsselwort-Ergänzung(^N^P)"
+
+msgid "Hit end of paragraph"
+msgstr "Absatzende erreicht"
+
+msgid "'dictionary' option is empty"
+msgstr "Die Option 'dictionary' ist leer"
+
+msgid "'thesaurus' option is empty"
+msgstr "Die Option 'thesaurus' ist leer"
+
+#, c-format
+msgid "Scanning dictionary: %s"
+msgstr "Durchsuchen des Wörterbuchs: %s"
+
+msgid " (insert) Scroll (^E/^Y)"
+msgstr " (Einfügen) Scrollen (^E/^Y)"
+
+msgid " (replace) Scroll (^E/^Y)"
+msgstr " (Ersetzen) Scrollen (^E/^Y)"
+
+#, c-format
+msgid "Scanning: %s"
+msgstr "Durchsuche: %s"
+
+#, c-format
+msgid "Scanning tags."
+msgstr "Durchsuchen von Tags."
+
+msgid " Adding"
+msgstr " Füge hinzu"
+
+#. 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.
+#.
+msgid "-- Searching..."
+msgstr "-- Suche..."
+
+msgid "Back at original"
+msgstr "Zurück am Ursprung"
+
+msgid "Word from other line"
+msgstr "Wort aus anderer Zeile"
+
+msgid "The only match"
+msgstr "Einziger Treffer"
+
+#, c-format
+msgid "match %d of %d"
+msgstr "Treffer %d von %d"
+
+#, c-format
+msgid "match %d"
+msgstr "Treffer %d"
+
+msgid "E18: Unexpected characters in :let"
+msgstr "E18: Unerwartete Zeichen in :let"
+
+#, c-format
+msgid "E684: list index out of range: %ld"
+msgstr "E684: Index der Liste außerhalb des zulässigen Bereichs: %ld"
+
+#, c-format
+msgid "E121: Undefined variable: %s"
+msgstr "E121: Undefinierte Variable: %s"
+
+msgid "E111: Missing ']'"
+msgstr "E111: Fehlende ']'"
+
+#, c-format
+msgid "E686: Argument of %s must be a List"
+msgstr "E686: Argument von %s muss eine Liste sein"
+
+#, c-format
+msgid "E712: Argument of %s must be a List or Dictionary"
+msgstr "E712: Argument von %s muss eine Liste oder ein Wörterbuch"
+
+msgid "E713: Cannot use empty key for Dictionary"
+msgstr "E713: Der Schlüssel für das Wörterbuch darf nicht leer sein"
+
+msgid "E714: List required"
+msgstr "E714: Liste benötigt"
+
+msgid "E715: Dictionary required"
+msgstr "E715: Wörterbuch benötigt"
+
+#, c-format
+msgid "E118: Too many arguments for function: %s"
+msgstr "E118: Zu viele Argumente für Funktion: %s"
+
+#, c-format
+msgid "E716: Key not present in Dictionary: %s"
+msgstr "E716: Schlüssel nicht vorhanden im Wörterbuch: %s"
+
+#, c-format
+msgid "E122: Function %s already exists, add ! to replace it"
+msgstr "E122: Funktion %s existiert bereits; zum Ersetzen ! hinzufügen"
+
+msgid "E717: Dictionary entry already exists"
+msgstr "E717: Wörterbuch-Eintrag existiert bereits"
+
+msgid "E718: Funcref required"
+msgstr "E718: Funktionsreferenz benötigt"
+
+msgid "E719: Cannot use [:] with a Dictionary"
+msgstr "E719: Kann [:] nicht mit einem Wörterbuch verwenden"
+
+#, c-format
+msgid "E734: Wrong variable type for %s="
+msgstr "E734: Falscher Typ der Variable für %s="
+
+#, c-format
+msgid "E130: Unknown function: %s"
+msgstr "E130: Unbekannte Funktion: %s"
+
+#, c-format
+msgid "E461: Illegal variable name: %s"
+msgstr "E461: Unzulässiger Name der Variable: %s"
+
+msgid "E687: Less targets than List items"
+msgstr "E687: Weniger Ziele als Einträge der Liste"
+
+msgid "E688: More targets than List items"
+msgstr "E688: Mehr Ziele als Einträge der Liste"
+
+msgid "Double ; in list of variables"
+msgstr "Doppeltes ; in der Liste von Variablen"
+
+#, c-format
+msgid "E738: Can't list variables for %s"
+msgstr "E738: Kann Variablen nicht auflisten: %s"
+
+msgid "E689: Can only index a List or Dictionary"
+msgstr "E689: Kann nur Listen und Wörterbücher indizieren"
+
+msgid "E708: [:] must come last"
+msgstr "E708: [:] muss am Schluss kommen"
+
+msgid "E709: [:] requires a List value"
+msgstr "E709: [:] benötigt eine Liste als Wert"
+
+msgid "E710: List value has more items than target"
+msgstr "E710: Listenwert hat mehr Einträge als das Ziel"
+
+msgid "E711: List value has not enough items"
+msgstr "E711: Listenwert hat nicht genügend Einträge"
+
+msgid "E690: Missing \"in\" after :for"
+msgstr "E690: Fehlendes \"in\" nach :for"
+
+#, c-format
+msgid "E107: Missing parentheses: %s"
+msgstr "E107: Fehlende Klammern: %s"
+
+#, c-format
+msgid "E108: No such variable: \"%s\""
+msgstr "E108: Keine solche Variable: \"%s\""
+
+msgid "E743: variable nested too deep for (un)lock"
+msgstr "E743: Variable ist zu tief verschachtelt für (un)lock"
+
+msgid "E109: Missing ':' after '?'"
+msgstr "E109: Fehlender ':' nach '?'"
+
+msgid "E691: Can only compare List with List"
+msgstr "E691: Kann nur eine Liste mit einer Liste vergleichen"
+
+msgid "E692: Invalid operation for Lists"
+msgstr "E692: Unzulässige Operation für Listen"
+
+msgid "E735: Can only compare Dictionary with Dictionary"
+msgstr "E735: Kann nur ein Wörterbuch mit einem Wörterbuch vergleichen"
+
+msgid "E736: Invalid operation for Dictionary"
+msgstr "E736: Unzulässige Operation für ein Wörterbuch"
+
+msgid "E693: Can only compare Funcref with Funcref"
+msgstr "E693: Kann nur eine Funktionsreferenz mit einer Funktionsreferenz vergleichen"
+
+msgid "E694: Invalid operation for Funcrefs"
+msgstr "E694: Unzulässige Operation für Funktionsreferenzen"
+
+msgid "E110: Missing ')'"
+msgstr "E110: Fehlende ')'"
+
+msgid "E695: Cannot index a Funcref"
+msgstr "E695: Kann keine Funktionsreferenz indizieren"
+
+#, c-format
+msgid "E112: Option name missing: %s"
+msgstr "E112: Bezeichnung der Option fehlt: %s"
+
+#, c-format
+msgid "E113: Unknown option: %s"
+msgstr "E113: Unbekannte Option: %s"
+
+#, c-format
+msgid "E114: Missing quote: %s"
+msgstr "E114: Fehlendes Anführungszeichen: %s"
+
+#, c-format
+msgid "E115: Missing quote: %s"
+msgstr "E115: Fehlendes Anführungszeichen: %s"
+
+#, c-format
+msgid "E696: Missing comma in List: %s"
+msgstr "E696: Fehlendes Komma in der Liste: %s"
+
+#, c-format
+msgid "E697: Missing end of List ']': %s"
+msgstr "E697: Fehlendes Ende der Liste ']': %s"
+
+#, c-format
+msgid "E720: Missing colon in Dictionary: %s"
+msgstr "E720: Fehlender Doppelpunkt im Wörterbuch: %s"
+
+#, c-format
+msgid "E721: Duplicate key in Dictionary: \"%s\""
+msgstr "E721: Doppelter Schlüssel im Wörterbuch: \"%s\""
+
+#, c-format
+msgid "E722: Missing comma in Dictionary: %s"
+msgstr "E722: Fehlendes Komma im Wörterbuch: %s"
+
+#, c-format
+msgid "E723: Missing end of Dictionary '}': %s"
+msgstr "E723: Fehlendes Ende des Wörterbuchs '}': %s"
+
+msgid "E724: variable nested too deep for displaying"
+msgstr "E724: Variable ist zu tief verschachtelt für die Anzeige"
+
+msgid "E699: Too many arguments"
+msgstr "E699: Zu viele Argumente"
+
+msgid "E785: complete() can only be used in Insert mode"
+msgstr "E785: complete() kann nur im Einfüge-Modus verwendet werden"
+
+#.
+#. * 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"
+
+#, c-format
+msgid "E737: Key already exists: %s"
+msgstr "E737: Schlüssel existiert bereits: %s"
+
+#, c-format
+msgid "+-%s%3ld lines: "
+msgstr "+-%s%3ld Zeilen: "
+
+#, c-format
+msgid "E700: Unknown function: %s"
+msgstr "E700: Unbekannte Funktion: %s"
+
+msgid ""
+"&OK\n"
+"&Cancel"
+msgstr ""
+"&OK\n"
+"&Abbrechen"
+
+msgid "called inputrestore() more often than inputsave()"
+msgstr "inputrestore() wurde öfter als inputsave() aufgerufen"
+
+msgid "E745: Range not allowed"
+msgstr "E745: Bereich nicht erlaubt"
+
+msgid "E701: Invalid type for len()"
+msgstr "E701: Unzulässiger Typ für len()"
+
+msgid "E726: Stride is zero"
+msgstr "E726: Stride ist Null"
+
+msgid "E727: Start past end"
+msgstr "E727: Start hinter dem Ende"
+
+msgid "<empty>"
+msgstr "<leer>"
+
+msgid "E240: No connection to Vim server"
+msgstr "E240: Keine Verbindung zum Vim-Server"
+
+#, c-format
+msgid "E241: Unable to send to %s"
+msgstr "E241: Kann nicht zu %s senden"
+
+msgid "E277: Unable to read a server reply"
+msgstr "E277: Server-Antwort kann nicht gelesen werden"
+
+msgid "E655: Too many symbolic links (cycle?)"
+msgstr "E655: Zu viele symbolische Links (zirkulär?)"
+
+msgid "E258: Unable to send to client"
+msgstr "E258: Kann nicht zum Client senden"
+
+msgid "E702: Sort compare function failed"
+msgstr "E702: Die Vergleichsfunktion der Sortierung ist fehlgeschlagen"
+
+msgid "(Invalid)"
+msgstr "(Ungültig)"
+
+msgid "E677: Error writing temp file"
+msgstr "E677: Fehler beim Schreiben einer temporären Datei"
+
+msgid "E703: Using a Funcref as a Number"
+msgstr "E703: Funktionsreferenz als Zahl verwendet"
+
+msgid "E745: Using a List as a Number"
+msgstr "E745: Liste als Zahl verwendet"
+
+msgid "E728: Using a Dictionary as a Number"
+msgstr "E728: Wörterbuch als Zahl verwendet"
+
+msgid "E729: using Funcref as a String"
+msgstr "E729: Funktionsreferenz als String verwendet"
+
+msgid "E730: using List as a String"
+msgstr "E730: Liste als String verwendet"
+
+msgid "E731: using Dictionary as a String"
+msgstr "E731: Wörterbuch als String verwendet"
+
+#, c-format
+msgid "E704: Funcref variable name must start with a capital: %s"
+msgstr "E704: Funktionsreferenz-Variable muss mit einem Großbuchstaben beginnen: %s"
+
+#, c-format
+msgid "E705: Variable name conflicts with existing function: %s"
+msgstr "E705: Konflikt eines Variablennamens mit bestehender Funktion: %s"
+
+#, c-format
+msgid "E706: Variable type mismatch for: %s"
+msgstr "E706: Typ der Variable falsch zugeordnet: %s"
+
+#, c-format
+msgid "E741: Value is locked: %s"
+msgstr "E741: Wert ist gesperrt: %s"
+
+msgid "Unknown"
+msgstr "Unbekannt"
+
+#, c-format
+msgid "E742: Cannot change value of %s"
+msgstr "E742: Kann Wert nicht ändern: %s"
+
+msgid "E698: variable nested too deep for making a copy"
+msgstr "E698: Variable ist zu tief verschachtelt für eine Kopie"
+
+#, c-format
+msgid "E124: Missing '(': %s"
+msgstr "E124: Fehlendes '(': %s"
+
+#, c-format
+msgid "E125: Illegal argument: %s"
+msgstr "E125: Unzulässiges Argument: %s"
+
+msgid "E126: Missing :endfunction"
+msgstr "E126: Fehlendes :endfunction"
+
+#, c-format
+msgid "E746: Function name does not match script file name: %s"
+msgstr "E746: Funktionsname stimmt mit dem Namen der Skript-Datei nicht überein: %s"
+
+msgid "E129: Function name required"
+msgstr "E129: Funktionsname wird verlangt"
+
+#, c-format
+msgid "E128: Function name must start with a capital or contain a colon: %s"
+msgstr "E128: Funktionsname muss mit einem Großbuchstaben beginnen oder einen Doppelpunkt enthalten: %s"
+
+#, c-format
+msgid "E131: Cannot delete function %s: It is in use"
+msgstr "E131: Funktion %s kann nicht gelöscht werden: sie ist in Verwendung"
+
+msgid "E132: Function call depth is higher than 'maxfuncdepth'"
+msgstr "E132: Funktionsaufrufstiefe überschreitet 'maxfuncdepth'"
+
+#, c-format
+msgid "calling %s"
+msgstr "rufe %s auf"
+
+#, c-format
+msgid "%s aborted"
+msgstr "%s abgebrochen"
+
+#, c-format
+msgid "%s returning #%ld"
+msgstr "%s lieferte #%ld zurück"
+
+#, c-format
+msgid "%s returning %s"
+msgstr "%s lieferte \"%s\" zurück"
+
+#, c-format
+msgid "continuing in %s"
+msgstr "weiter in %s"
+
+msgid "E133: :return not inside a function"
+msgstr "E133: :return außerhalb einer Funktion"
+
+#, c-format
+msgid ""
+"\n"
+"# global variables:\n"
+msgstr ""
+"\n"
+"# globale Variablen:\n"
+
+msgid ""
+"\n"
+"\tLast set from "
+msgstr ""
+"\n"
+"\tZuletzt gesetzt von "
+
+#, c-format
+msgid "<%s>%s%s %d, Hex %02x, Octal %03o"
+msgstr "<%s>%s%s %d, Hex %02x, Oktal %03o"
+
+#, c-format
+msgid "> %d, Hex %04x, Octal %o"
+msgstr "> %d, Hex %04x, Oktal %o"
+
+#, c-format
+msgid "> %d, Hex %08x, Octal %o"
+msgstr "> %d, Hex %08x, Oktal %o"
+
+msgid "E134: Move lines into themselves"
+msgstr "E134: Verschiebe Zeilen in sich selbst"
+
+msgid "1 line moved"
+msgstr "1 Zeile verschoben"
+
+#, c-format
+msgid "%ld lines moved"
+msgstr "%ld Zeilen verschoben"
+
+#, c-format
+msgid "%ld lines filtered"
+msgstr "%ld Zeilen gefiltert"
+
+msgid "E135: *Filter* Autocommands must not change current buffer"
+msgstr "E135: *Filter*-Autokommandos dürfen den aktuellen Puffer nicht ändern"
+
+msgid "[No write since last change]\n"
+msgstr "[Kein Schreiben seit der letzten Änderung]\n"
+
+#, c-format
+msgid "%sviminfo: %s in line: "
+msgstr "%sviminfo: %s in Zeile: "
+
+msgid "E136: viminfo: Too many errors, skipping rest of file"
+msgstr "E136: viminfo: Zu viele Fehler; überspringe Rest der Datei"
+
+#, c-format
+msgid "Reading viminfo file \"%s\"%s%s%s"
+msgstr "Lesen der viminfo-Datei \"%s\"%s%s%s"
+
+msgid " info"
+msgstr " Information"
+
+msgid " marks"
+msgstr " Markierungen"
+
+msgid " FAILED"
+msgstr " FEHLGESCHLAGEN"
+
+#, c-format
+msgid "E137: Viminfo file is not writable: %s"
+msgstr "E137: Viminfo-Datei ist nicht schreibbar: %s"
+
+#, c-format
+msgid "E138: Can't write viminfo file %s!"
+msgstr "E138: Schreiben der viminfo-Datei %s ist nicht möglich!"
+
+#, c-format
+msgid "Writing viminfo file \"%s\""
+msgstr "Schreiben der viminfo-Datei \"%s\""
+
+#. Write the info:
+#, c-format
+msgid "# This viminfo file was generated by Vim %s.\n"
+msgstr "# Diese viminfo-Datei wurde von Vim %s generiert.\n"
+
+#, c-format
+msgid ""
+"# You may edit it if you're careful!\n"
+"\n"
+msgstr ""
+"# Sie können sie verändern, wenn Sie vorsichtig vorgehen!\n"
+"\n"
+
+#, c-format
+msgid "# Value of 'encoding' when this file was written\n"
+msgstr "# Wert von 'encoding', als diese Datei geschrieben wurde\n"
+
+msgid "Illegal starting char"
+msgstr "Unzulässiges Zeichen am Anfang"
+
+msgid "Save As"
+msgstr "Speichern als"
+
+msgid "Write partial file?"
+msgstr "Partielle Datei schreiben?"
+
+msgid "E140: Use ! to write partial buffer"
+msgstr "E140: Zum Schreiben von partiellen Puffern ! verwenden"
+
+#, c-format
+msgid "Overwrite existing file \"%s\"?"
+msgstr "Überschreibe existierende Datei \"%s\"?"
+
+#, c-format
+msgid "Swap file \"%s\" exists, overwrite anyway?"
+msgstr "Auslagerungsdatei \"%s\" existiert bereits. Überschreiben?"
+
+#, c-format
+msgid "E768: Swap file exists: %s (:silent! overrides)"
+msgstr "E768: Auslagerungsdatei existiert bereits: %s (mit :silent! erzwingen)"
+
+#, c-format
+msgid "E141: No file name for buffer %ld"
+msgstr "E141: Kein Dateiname für Puffer %ld"
+
+msgid "E142: File not written: Writing is disabled by 'write' option"
+msgstr "E142: Datei wurde nicht geschrieben: Schreiben ist durch die Option 'write' ausgeschaltet"
+
+#, c-format
+msgid ""
+"'readonly' option is set for \"%s\".\n"
+"Do you wish to write anyway?"
+msgstr ""
+"'readonly'-Option ist für \"%s\" gesetzt.\n"
+"Möchten Sie trotzdem schreiben?"
+
+msgid "Edit File"
+msgstr "Öffne Datei"
+
+#, c-format
+msgid "E143: Autocommands unexpectedly deleted new buffer %s"
+msgstr "E143: Autokommandos löschten unerwartet neuen Puffer %s"
+
+msgid "E144: non-numeric argument to :z"
+msgstr "E144: Nicht-numerisches Argument für :z"
+
+msgid "E145: Shell commands not allowed in rvim"
+msgstr "E145: Shell-Befehle sind in rvim nicht erlaubt"
+
+msgid "E146: Regular expressions can't be delimited by letters"
+msgstr "E146: Reguläre Ausdrücke können nicht durch Buchstaben begrenzt werden"
+
+#, c-format
+msgid "replace with %s (y/n/a/q/l/^E/^Y)?"
+msgstr "ersetze durch %s (y/n/a/q/l/^E/^Y)?"
+
+msgid "(Interrupted) "
+msgstr "(Unterbrochen) "
+
+msgid "1 match"
+msgstr "ein Treffer"
+
+msgid "1 substitution"
+msgstr "eine Ersetzung"
+
+#, c-format
+msgid "%ld matches"
+msgstr "%ld Treffer"
+
+#, c-format
+msgid "%ld substitutions"
+msgstr "%ld Ersetzungen"
+
+msgid " on 1 line"
+msgstr " auf einer Zeile"
+
+#, c-format
+msgid " on %ld lines"
+msgstr " auf %ld Zeilen"
+
+msgid "E147: Cannot do :global recursive"
+msgstr "E147: Kann :global nicht rekursiv ausführen"
+
+msgid "E148: Regular expression missing from global"
+msgstr "E148: Regulärer Ausdruck fehlt in global"
+
+#, c-format
+msgid "Pattern found in every line: %s"
+msgstr "Muster in jeder Zeile gefunden: %s"
+
+#, c-format
+msgid ""
+"\n"
+"# Last Substitute String:\n"
+"$"
+msgstr ""
+"\n"
+"# Letzte ersetzte Zeichenkette:\n"
+"$"
+
+msgid "E478: Don't panic!"
+msgstr "E478: Nur keine Panik!"
+
+#, c-format
+msgid "E661: Sorry, no '%s' help for %s"
+msgstr "E661: Schade, keine '%s' Hilfe für %s"
+
+#, c-format
+msgid "E149: Sorry, no help for %s"
+msgstr "E149: Schade, keine Hilfe für %s"
+
+#, c-format
+msgid "Sorry, help file \"%s\" not found"
+msgstr "Hilfe-Datei \"%s\" nicht gefunden"
+
+#, c-format
+msgid "E150: Not a directory: %s"
+msgstr "E150: Kein Verzeichnis: %s"
+
+#, c-format
+msgid "E152: Cannot open %s for writing"
+msgstr "E152: %s kann nicht zum Schreiben geöffnet werden"
+
+#, c-format
+msgid "E153: Unable to open %s for reading"
+msgstr "E153: %s kann nicht zum Lesen geöffnet werden"
+
+#, c-format
+msgid "E670: Mix of help file encodings within a language: %s"
+msgstr "E670: Mischung von Kodierungen einer Hilfedatei innerhalb einer Sprache: %s"
+
+#, c-format
+msgid "E154: Duplicate tag \"%s\" in file %s"
+msgstr "E154: Doppelter Tag \"%s\" in der Datei %s"
+
+#, c-format
+msgid "E160: Unknown sign command: %s"
+msgstr "E160: Unbekannter \"sign\"-Befehl: %s"
+
+msgid "E156: Missing sign name"
+msgstr "E156: Name des Zeichens fehlt"
+
+msgid "E612: Too many signs defined"
+msgstr "E612: Zu viele Zeichen definiert"
+
+#, c-format
+msgid "E239: Invalid sign text: %s"
+msgstr "E239: Ungültiger Text für ein Zeichen: %s"
+
+#, c-format
+msgid "E155: Unknown sign: %s"
+msgstr "E155: Unbekanntes Zeichen: %s"
+
+msgid "E159: Missing sign number"
+msgstr "E159: Fehlende Zeichennummer"
+
+#, c-format
+msgid "E158: Invalid buffer name: %s"
+msgstr "E158: ungültige Puffernummer: %s"
+
+#, c-format
+msgid "E157: Invalid sign ID: %ld"
+msgstr "E157: Ungültige Zeichen-ID: %ld"
+
+msgid " (NOT FOUND)"
+msgstr " (NICHT GEFUNDEN)"
+
+msgid " (not supported)"
+msgstr " (nicht unterstützt)"
+
+msgid "[Deleted]"
+msgstr "[Gelöscht]"
+
+msgid "Entering Debug mode. Type \"cont\" to continue."
+msgstr "Debug-Modus. Geben Sie \"cont\" zum Fortsetzen ein."
+
+#, c-format
+msgid "line %ld: %s"
+msgstr "Zeile %ld: %s"
+
+#, c-format
+msgid "cmd: %s"
+msgstr "Befehl: %s"
+
+#, c-format
+msgid "Breakpoint in \"%s%s\" line %ld"
+msgstr "Haltepunkt in \"%s%s\" Zeile %ld"
+
+#, c-format
+msgid "E161: Breakpoint not found: %s"
+msgstr "E161: Haltepunkt nicht gefunden: %s"
+
+msgid "No breakpoints defined"
+msgstr "Keine Haltepunkte definiert"
+
+#, c-format
+msgid "%3d %s %s line %ld"
+msgstr "%3d %s %s Zeile %ld"
+
+msgid "E750: First use :profile start <fname>"
+msgstr "E750: Erste Verwendung von :profile startet <fname>"
+
+#, c-format
+msgid "Save changes to \"%s\"?"
+msgstr "Änderungen in \"%s\" speichern?"
+
+msgid "Untitled"
+msgstr "Unbenannt"
+
+#, c-format
+msgid "E162: No write since last change for buffer \"%s\""
+msgstr "E162: Puffer \"%s\" wurde seit der letzten Änderung nicht geschrieben"
+
+msgid "Warning: Entered other buffer unexpectedly (check autocommands)"
+msgstr "Achtung: Unerwarteter Eintritt in einen andren Puffer (überprüfen Sie die Autokommandos)"
+
+msgid "E163: There is only one file to edit"
+msgstr "E163: Es gibt nur eine Datei zum Editieren"
+
+msgid "E164: Cannot go before first file"
+msgstr "E164: Kann nicht über die erste Datei hinausgehen"
+
+msgid "E165: Cannot go beyond last file"
+msgstr "E165: Kann nicht über die letzte Datei hinausgehen"
+
+#, c-format
+msgid "E666: compiler not supported: %s"
+msgstr "E666: Compiler nicht unterstützt: %s"
+
+#, c-format
+msgid "Searching for \"%s\" in \"%s\""
+msgstr "Suche nach \"%s\" in \"%s\""
+
+#, c-format
+msgid "Searching for \"%s\""
+msgstr "Suche nach \"%s\""
+
+#, c-format
+msgid "not found in 'runtimepath': \"%s\""
+msgstr "im 'runtimepath' nicht gefunden: \"%s\""
+
+msgid "Source Vim script"
+msgstr "Führe Vim-Skript aus"
+
+#, c-format
+msgid "Cannot source a directory: \"%s\""
+msgstr "Kann kein Verzeichnis einlesen: \"%s\""
+
+#, c-format
+msgid "could not source \"%s\""
+msgstr "\"%s\" konnte nicht gelesen werden"
+
+#, c-format
+msgid "line %ld: could not source \"%s\""
+msgstr "Zeile %ld: \"%s\" konnte nicht gelesen werden"
+
+#, c-format
+msgid "sourcing \"%s\""
+msgstr "lese \"%s\""
+
+#, c-format
+msgid "line %ld: sourcing \"%s\""
+msgstr "Zeile %ld: lese \"%s\""
+
+#, c-format
+msgid "finished sourcing %s"
+msgstr "Lesen von %s beendet"
+
+msgid "modeline"
+msgstr "modeline"
+
+msgid "--cmd argument"
+msgstr "--cmd Argument"
+
+msgid "-c argument"
+msgstr "-c Argument"
+
+msgid "environment variable"
+msgstr "Umgebungsvariable"
+
+msgid "error handler"
+msgstr "Error-Handler"
+
+msgid "W15: Warning: Wrong line separator, ^M may be missing"
+msgstr "W15: Achtung: Falscher Zeilentrenner, vielleicht fehlt ein ^M"
+
+msgid "E167: :scriptencoding used outside of a sourced file"
+msgstr "E167: :scriptencoding außerhalb einer eingelesenen Datei"
+
+msgid "E168: :finish used outside of a sourced file"
+msgstr "E168: :finish außerhalb einer eingelesenen Datei"
+
+#, c-format
+msgid "Current %slanguage: \"%s\""
+msgstr "Momentane %sSprache: \"%s\""
+
+#, c-format
+msgid "E197: Cannot set language to \"%s\""
+msgstr "E197: Sprache kann nicht auf \"%s\" gesetzt werden"
+
+msgid "Entering Ex mode. Type \"visual\" to go to Normal mode."
+msgstr "Ex-Modus. Geben Sie \"visual\" ein, um zum Normal-Modus zurückzukehren."
+
+#. must be at EOF
+msgid "E501: At end-of-file"
+msgstr "E501: Am Dateiende"
+
+msgid "E169: Command too recursive"
+msgstr "E169: Befehl zu rekursiv"
+
+#, c-format
+msgid "E605: Exception not caught: %s"
+msgstr "E605: Ausnahme nicht aufgefangen: %s"
+
+msgid "End of sourced file"
+msgstr "Ende der eingelesenen Datei"
+
+msgid "End of function"
+msgstr "Ende der Funktion"
+
+msgid "E464: Ambiguous use of user-defined command"
+msgstr "E464: Mehrdeutige Verwendung eines benutzerdefinierten Befehls"
+
+msgid "E492: Not an editor command"
+msgstr "E492: Kein Editorbefehl"
+
+msgid "E493: Backwards range given"
+msgstr "E493: Bereichsgrenzen rückwärts"
+
+msgid "Backwards range given, OK to swap"
+msgstr "Bereichsgrenzen rückwärts; vertauschen"
+
+msgid "E494: Use w or w>>"
+msgstr "E494: Verwenden Sie w oder w>>"
+
+msgid "E319: Sorry, the command is not available in this version"
+msgstr "E319: Der Befehl ist in dieser Version nicht implementiert"
+
+msgid "E172: Only one file name allowed"
+msgstr "E172: Nur ein Dateiname erlaubt"
+
+msgid "1 more file to edit. Quit anyway?"
+msgstr "Eine weitere Datei zum Editieren. Trotzdem beenden?"
+
+#, c-format
+msgid "%d more files to edit. Quit anyway?"
+msgstr "%d weitere Dateien zum Editieren. Trotzdem beenden?"
+
+msgid "E173: 1 more file to edit"
+msgstr "E173: Eine weitere Datei zum Editieren"
+
+#, c-format
+msgid "E173: %ld more files to edit"
+msgstr "E173: %ld weitere Dateien zum Editieren"
+
+msgid "E174: Command already exists: add ! to replace it"
+msgstr "E174: Befehl existiert bereits: ! zum Ersetzen hinzufügen"
+
+msgid ""
+"\n"
+" Name Args Range Complete Definition"
+msgstr ""
+"\n"
+" Name Args Bereich Fertig Definition"
+
+msgid "No user-defined commands found"
+msgstr "Keine vom Benutzer definierten Befehle gefunden"
+
+msgid "E175: No attribute specified"
+msgstr "E175: Kein Attribut angegeben"
+
+msgid "E176: Invalid number of arguments"
+msgstr "E176: Falsche Anzahl von Argumenten"
+
+msgid "E177: Count cannot be specified twice"
+msgstr "E177: Zähler kann nicht zweimal angegeben werden"
+
+msgid "E178: Invalid default value for count"
+msgstr "E178: Ungültige Voreinstellung für den Zähler"
+
+msgid "E179: argument required for complete"
+msgstr "E179: Argument wird zur Vervollständigung benötigt"
+
+#, c-format
+msgid "E181: Invalid attribute: %s"
+msgstr "E181: Ungültiges Attribut: %s"
+
+msgid "E182: Invalid command name"
+msgstr "E182: Ungültiger Befehls-Name"
+
+msgid "E183: User defined commands must start with an uppercase letter"
+msgstr "E183: Benutzerdefinierte Befehle müssen mit Großbuchstaben beginnen"
+
+#, c-format
+msgid "E184: No such user-defined command: %s"
+msgstr "E184: Unbekannter benutzerdefinierter Befehl: %s"
+
+#, c-format
+msgid "E180: Invalid complete value: %s"
+msgstr "E180: Ungültiger Wert der Vervollständigung: %s"
+
+msgid "E468: Completion argument only allowed for custom completion"
+msgstr "E468: Argument für Vervollständigung nur für eigene Vervollständigung erlaubt"
+
+msgid "E467: Custom completion requires a function argument"
+msgstr "E467: Eigene Vervollständigung benötigt eine Funktion als Argument"
+
+#, c-format
+msgid "E185: Cannot find color scheme %s"
+msgstr "E185: Kann Farbschema %s nicht finden"
+
+msgid "Greetings, Vim user!"
+msgstr "Herzliche Grüße, Vim Benutzer!"
+
+msgid "E784: Cannot close last tab page"
+msgstr "E784: Kann letztes Tab nicht schließen"
+
+msgid "Already only one tab page"
+msgstr "Es existiert bereits nur ein Tab"
+
+msgid "Edit File in new window"
+msgstr "Öffne Datei in einem neuen Fenster"
+
+msgid "No swap file"
+msgstr "Keine Auslagerungsdatei"
+
+msgid "Append File"
+msgstr "Füge Datei an"
+
+msgid "E747: Cannot change directory, buffer is modifed (add ! to override)"
+msgstr "E747: Kann das Verzeichnis nicht wechseln, da der Puffer verändert wurde (erzwinge mit !)"
+
+msgid "E186: No previous directory"
+msgstr "E186: Kein vorheriges Verzeichnis"
+
+msgid "E187: Unknown"
+msgstr "E187: Unbekannt"
+
+msgid "E465: :winsize requires two number arguments"
+msgstr "E465: :winsize benötigt zwei numerische Argumente"
+
+#, c-format
+msgid "Window position: X %d, Y %d"
+msgstr "Fenster-Position: X %d, Y %d"
+
+msgid "E188: Obtaining window position not implemented for this platform"
+msgstr "E188: Die Fensterposition kann für dieses Terminal nicht bestimmt werden"
+
+msgid "E466: :winpos requires two number arguments"
+msgstr "E466: :winpos benötigt zwei numerische Argumente"
+
+msgid "Save Redirection"
+msgstr "Umleitung Speichern"
+
+msgid "Save View"
+msgstr "Ansichten Speichern"
+
+msgid "Save Session"
+msgstr "Sitzung Speichern"
+
+msgid "Save Setup"
+msgstr "Einstellungen Speichern"
+
+#, c-format
+msgid "E739: Cannot create directory: %s"
+msgstr "E739: Kann Verzeichnis nicht erstellen: %s"
+
+#, c-format
+msgid "E189: \"%s\" exists (add ! to override)"
+msgstr "E189: \"%s\" existiert (erzwinge mit !)"
+
+#, c-format
+msgid "E190: Cannot open \"%s\" for writing"
+msgstr "E190: \"%s\" kann nicht zum Schreiben geöffnet werden"
+
+#. set mark
+msgid "E191: Argument must be a letter or forward/backward quote"
+msgstr "E191: Argument muss ein Buchstabe oder vorwärts/rückwärts-Anführungszeichen sein"
+
+msgid "E192: Recursive use of :normal too deep"
+msgstr "E192: Rekursive Verwendung von :normal zu tief"
+
+msgid "E194: No alternate file name to substitute for '#'"
+msgstr "E194: Kein anderer Dateiname zur Ersetzung mit '#'"
+
+msgid "E495: no autocommand file name to substitute for \"<afile>\""
+msgstr "E495: Kein Autokommando-Dateiname zur Ersetzung mit \"<afile>\""
+
+msgid "E496: no autocommand buffer number to substitute for \"<abuf>\""
+msgstr "E496: Keine Autokommando-Puffernummer zur Ersetzung mit \"<abuf>\""
+
+msgid "E497: no autocommand match name to substitute for \"<amatch>\""
+msgstr "E497: Kein passender Name eines Autokommandos zur Ersetzung mit \"<amatch>\""
+
+msgid "E498: no :source file name to substitute for \"<sfile>\""
+msgstr "E498: kein :source Dateiname zur Ersetzung mit \"<sfile>\""
+
+#, no-c-format
+msgid "E499: Empty file name for '%' or '#', only works with \":p:h\""
+msgstr "E499: Leerer Dateiname für '%' oder '#', funktioniert nur mit \":p:h\""
+
+msgid "E500: Evaluates to an empty string"
+msgstr "E500: Ergibt eine leere Zeichenkette"
+
+msgid "E195: Cannot open viminfo file for reading"
+msgstr "E195: viminfo kann nicht zum Lesen geöffnet werden"
+
+msgid "E196: No digraphs in this version"
+msgstr "E196: Keine Digraphen in dieser Version"
+
+msgid "E608: Cannot :throw exceptions with 'Vim' prefix"
+msgstr "E608: Kann nicht :throw Exceptions mit 'Vim' Präfix"
+
+#. always scroll up, don't overwrite
+#, c-format
+msgid "Exception thrown: %s"
+msgstr "Ausnahme geworfen: %s"
+
+#, c-format
+msgid "Exception finished: %s"
+msgstr "Ausnahme beendet: %s"
+
+#, c-format
+msgid "Exception discarded: %s"
+msgstr "Ausnahme verworfen: %s"
+
+#, c-format
+msgid "%s, line %ld"
+msgstr "%s, Zeile %ld"
+
+#. always scroll up, don't overwrite
+#, c-format
+msgid "Exception caught: %s"
+msgstr "Ausnahme gefangen: %s"
+
+#, c-format
+msgid "%s made pending"
+msgstr "%s schwebend gemacht"
+
+#, c-format
+msgid "%s resumed"
+msgstr "%s wieder aufgenommen"
+
+#, c-format
+msgid "%s discarded"
+msgstr "%s verworfen"
+
+msgid "Exception"
+msgstr "Ausnahme"
+
+msgid "Error and interrupt"
+msgstr "Fehler und Unterbrechung"
+
+msgid "Error"
+msgstr "Fehler"
+
+#. if (pending & CSTP_INTERRUPT)
+msgid "Interrupt"
+msgstr "Unterbrechung"
+
+msgid "E579: :if nesting too deep"
+msgstr "E579: :if Schachtelung zu tief"
+
+msgid "E580: :endif without :if"
+msgstr "E580: :endif ohne :if"
+
+msgid "E581: :else without :if"
+msgstr "E581: :else ohne :if"
+
+msgid "E582: :elseif without :if"
+msgstr "E582: :elseif ohne :if"
+
+msgid "E583: multiple :else"
+msgstr "E583: Mehrere :else"
+
+msgid "E584: :elseif after :else"
+msgstr "E584: :elseif nach :else"
+
+msgid "E585: :while nesting too deep"
+msgstr "E585: :while Schachtelung zu tief"
+
+msgid "E586: :continue without :while"
+msgstr "E586: :continue ohne :while"
+
+msgid "E587: :break without :while"
+msgstr "E587: :break ohne :while"
+
+msgid "E732: Using :endfor with :while"
+msgstr "E732: Benützung von :endfor mit :while"
+
+msgid "E733: Using :endwhile with :for"
+msgstr "E733: Benützung von :endwhile mit :for"
+
+msgid "E601: :try nesting too deep"
+msgstr "E601: :try Schachtelung zu tief"
+
+msgid "E603: :catch without :try"
+msgstr "E603: :catch ohne :try"
+
+#. Give up for a ":catch" after ":finally" and ignore it.
+#. * Just parse.
+msgid "E604: :catch after :finally"
+msgstr "E604: :catch nach :finally"
+
+msgid "E606: :finally without :try"
+msgstr "E606: :finally ohne :try"
+
+#. Give up for a multiple ":finally" and ignore it.
+msgid "E607: multiple :finally"
+msgstr "E607: Mehrere :finally"
+
+msgid "E602: :endtry without :try"
+msgstr "E602: :endtry ohne :try"
+
+msgid "E193: :endfunction not inside a function"
+msgstr "E193: :endfunction außerhalb einer Funktion"
+
+msgid "tagname"
+msgstr "Tag-Name"
+
+msgid " kind file\n"
+msgstr " verwandte Datei\n"
+
+msgid "'history' option is zero"
+msgstr "Option 'history' ist Null"
+
+#, c-format
+msgid ""
+"\n"
+"# %s History (newest to oldest):\n"
+msgstr ""
+"\n"
+"# %s Geschichte (neueste bis älteste):\n"
+
+msgid "Command Line"
+msgstr "Befehlszeile"
+
+msgid "Search String"
+msgstr "Suchausdruck"
+
+msgid "Expression"
+msgstr "Ausdruck"
+
+msgid "Input Line"
+msgstr "Eingabe-Zeile"
+
+msgid "E198: cmd_pchar beyond the command length"
+msgstr "E198: cmd_pchar über die Länge des Befehls hinaus"
+
+msgid "E199: Active window or buffer deleted"
+msgstr "E199: Aktives Fenster oder Puffer gelöscht"
+
+msgid "Illegal file name"
+msgstr "Unzulässiger Dateiname"
+
+msgid "is a directory"
+msgstr "ist ein Verzeichnis"
+
+msgid "is not a file"
+msgstr "ist keine Datei"
+
+msgid "[New File]"
+msgstr "[Neue Datei]"
+
+msgid "[New DIRECTORY]"
+msgstr "[Neues VERZEICHNIS]"
+
+msgid "[File too big]"
+msgstr "[Datei zu groß]"
+
+msgid "[Permission Denied]"
+msgstr "[Keine Erlaubnis]"
+
+msgid "E200: *ReadPre autocommands made the file unreadable"
+msgstr "E200: *ReadPre Autokommandos haben die Datei unlesbar gemacht"
+
+msgid "E201: *ReadPre autocommands must not change current buffer"
+msgstr "E201: *ReadPre Autokommandos dürfen nicht den aktuellen Puffer wechseln"
+
+msgid "Vim: Reading from stdin...\n"
+msgstr "Vim: Lese von stdin...\n"
+
+msgid "Reading from stdin..."
+msgstr "Lese von stdin..."
+
+#. Re-opening the original file failed!
+msgid "E202: Conversion made file unreadable!"
+msgstr "E202: Datei wurde unlesbar durch Umwandlung"
+
+msgid "[fifo/socket]"
+msgstr "[fifo/socket]"
+
+msgid "[fifo]"
+msgstr "[fifo]"
+
+msgid "[socket]"
+msgstr "[socket]"
+
+msgid "[RO]"
+msgstr "[RO]"
+
+msgid "[CR missing]"
+msgstr "[CR fehlt]"
+
+msgid "[NL found]"
+msgstr "[NL gefunden]"
+
+msgid "[long lines split]"
+msgstr "[lange Zeilen geteilt]"
+
+msgid "[NOT converted]"
+msgstr "[NICHT konvertiert]"
+
+msgid "[converted]"
+msgstr "[konvertiert]"
+
+msgid "[crypted]"
+msgstr "[verschlüsselt]"
+
+#, c-format
+msgid "[CONVERSION ERROR in line %ld]"
+msgstr "UMWANDLUNGSFEHLER in Zeile %ld]"
+
+#, c-format
+msgid "[ILLEGAL BYTE in line %ld]"
+msgstr "[UNZULÄSSIGES BYTE in Zeile %ld]"
+
+msgid "[READ ERRORS]"
+msgstr "[LESE-FEHLER]"
+
+msgid "Can't find temp file for conversion"
+msgstr "temporäre Datei kann nicht zum Umwandeln geöffnet werden"
+
+msgid "Conversion with 'charconvert' failed"
+msgstr "Fehler bei der Umwandlung mit 'charconvert'"
+
+msgid "can't read output of 'charconvert'"
+msgstr "Ausgabe von 'charconvert' kann nicht gelesen werden"
+
+msgid "E676: No matching autocommands for acwrite buffer"
+msgstr "E676: Keine übereinstimmenden Autokommandos für acwrite Puffer"
+
+msgid "E203: Autocommands deleted or unloaded buffer to be written"
+msgstr "E203: Autokommandos haben den zu schreibenden Puffer gelöscht oder entladen"
+
+msgid "E204: Autocommand changed number of lines in unexpected way"
+msgstr "E204: Autokommandos haben die Anzahl der Zeilen in unerwarteter Weise verändert"
+
+msgid "NetBeans disallows writes of unmodified buffers"
+msgstr "NetBeans verweigert das Schreiben von unveränderten Puffern"
+
+msgid "Partial writes disallowed for NetBeans buffers"
+msgstr "Partielles Schreiben für NetBeans Puffer verweigert"
+
+msgid "is not a file or writable device"
+msgstr "ist keine Datei oder beschreibbares Device"
+
+msgid "is read-only (add ! to override)"
+msgstr "ist Schreibgeschützt (erzwinge mit !)"
+
+msgid "E506: Can't write to backup file (add ! to override)"
+msgstr "E506: Sicherungsdatei kann nicht geschrieben werden (erzwinge mit !)"
+
+msgid "E507: Close error for backup file (add ! to override)"
+msgstr "E507: Fehler beim Schließen der Sicherungsdatei (erzwinge mit !)"
+
+msgid "E508: Can't read file for backup (add ! to override)"
+msgstr "E508: Sicherungsdatei kann nicht gelesen werden (erzwinge mit !)"
+
+msgid "E509: Cannot create backup file (add ! to override)"
+msgstr "E509: Sicherungsdatei kann nicht angelegt werden (erzwinge mit !)"
+
+msgid "E510: Can't make backup file (add ! to override)"
+msgstr "E510: Sicherungsdatei kann nicht erstellt werden (erzwinge mit !)"
+
+msgid "E460: The resource fork would be lost (add ! to override)"
+msgstr "E460: Der Ressourcefork geht verloren (erzwinge mit !)"
+
+msgid "E214: Can't find temp file for writing"
+msgstr "E214: Temporäre Datei kann nicht zum Schreiben geöffnet werden"
+
+msgid "E213: Cannot convert (add ! to write without conversion)"
+msgstr "E213: Fehler bei der Umwandlung (schreibe ohne Umwandlung mit !)"
+
+msgid "E166: Can't open linked file for writing"
+msgstr "E166: Gelinkte Datei kann nicht zum Schreiben geöffnet werden"
+
+msgid "E212: Can't open file for writing"
+msgstr "E212: Datei kann nicht zum Schreiben geöffnet werden"
+
+msgid "E667: Fsync failed"
+msgstr "E667: Fsync fehlgeschlagen"
+
+msgid "E512: Close failed"
+msgstr "E512: Fehler beim Schließen"
+
+msgid "E513: write error, conversion failed"
+msgstr "E513: Schreibfehler, Umwandlung schlug fehl"
+
+msgid "E514: write error (file system full?)"
+msgstr "E514: Schreibfehler (Dateisystem voll?)"
+
+msgid " CONVERSION ERROR"
+msgstr "KONVERTIERUNGSFEHLER"
+
+msgid "[Device]"
+msgstr "[Ausgabegerät]"
+
+msgid "[New]"
+msgstr "[Neu]"
+
+msgid " [a]"
+msgstr " [a]"
+
+msgid " appended"
+msgstr " angefügt"
+
+msgid " [w]"
+msgstr " [w]"
+
+msgid " written"
+msgstr " geschrieben"
+
+msgid "E205: Patchmode: can't save original file"
+msgstr "E205: patchmode: Original-Datei kann nicht gespeichert werden"
+
+msgid "E206: patchmode: can't touch empty original file"
+msgstr "E206: patchmode: leere Original-Datei kann nicht verändert werden"
+
+msgid "E207: Can't delete backup file"
+msgstr "E207: Backup-Datei kann nicht gelöscht werden"
+
+msgid ""
+"\n"
+"WARNING: Original file may be lost or damaged\n"
+msgstr ""
+"\n"
+"ACHTUNG: Original-Datei kann verloren oder zerstört sein\n"
+
+msgid "don't quit the editor until the file is successfully written!"
+msgstr "beende nicht den Editor bis die Datei erfolgreich geschrieben wurde!"
+
+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 "eine Zeile, "
+
+#, c-format
+msgid "%ld lines, "
+msgstr "%ld Zeilen, "
+
+msgid "1 character"
+msgstr "ein Zeichen"
+
+#, c-format
+msgid "%ld characters"
+msgstr "%ld Zeichen"
+
+msgid "[noeol]"
+msgstr "[noeol]"
+
+msgid "[Incomplete last line]"
+msgstr "[Unvollständige letzte Zeile]"
+
+#. 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 "ACHTUNG: Die Datei wurde seit dem letzten Lesen geändert!!!"
+
+msgid "Do you really want to write to it"
+msgstr "Möchten Sie es wirklich schreiben"
+
+#, c-format
+msgid "E208: Error writing to \"%s\""
+msgstr "E208: Fehler während des Schreibens nach \"%s\""
+
+#, c-format
+msgid "E209: Error closing \"%s\""
+msgstr "E209: Fehler beim Schließen von \"%s\""
+
+#, c-format
+msgid "E210: Error reading \"%s\""
+msgstr "E210: Fehler beim Lesen von \"%s\""
+
+msgid "E246: FileChangedShell autocommand deleted buffer"
+msgstr "E246: FileChangedShell-Autokommando löschte Puffer"
+
+#, c-format
+msgid "E211: Warning: File \"%s\" no longer available"
+msgstr "E211: Achtung: Datei \"%s\" ist nicht länger vorhanden"
+
+#, c-format
+msgid ""
+"W12: Warning: File \"%s\" has changed and the buffer was changed in Vim as "
+"well"
+msgstr ""
+"W12: Achtung: Datei \"%s\" wurde verändert und der Puffer wurde ebenfalls in "
+"Vim verändert"
+
+#, c-format
+msgid "W11: Warning: File \"%s\" has changed since editing started"
+msgstr "W11: Achtung: Datei \"%s\" wurde verändert, seit mit dem Editieren angefangen wurde"
+
+#, c-format
+msgid "W16: Warning: Mode of file \"%s\" has changed since editing started"
+msgstr "W16: Achtung: Mode der Datei \"%s\" wurde verändert seit mit dem Editieren angefangen wurde"
+
+#, c-format
+msgid "W13: Warning: File \"%s\" has been created after editing started"
+msgstr "W13: Achtung: Datei \"%s\" wurde erstellt, nachdem mit dem Editieren begonnen wurde"
+
+msgid "See \":help W16\" for more info."
+msgstr "Siehe \":help W16\" für mehr Information"
+
+msgid "Warning"
+msgstr "Warnung"
+
+msgid ""
+"&OK\n"
+"&Load File"
+msgstr ""
+"&OK\n"
+"&Lies Datei"
+
+#, c-format
+msgid "E462: Could not prepare for reloading \"%s\""
+msgstr "E462: Konnte das Neuladen von \"%s\" nicht vorbereiten"
+
+#, c-format
+msgid "E321: Could not reload \"%s\""
+msgstr "E321: \"%s\" konnte nicht neu geladen werden"
+
+msgid "--Deleted--"
+msgstr "--gelöscht--"
+
+#. the group doesn't exist
+#, c-format
+msgid "E367: No such group: \"%s\""
+msgstr "E367: Keine solche Gruppe: \"%s\""
+
+#, c-format
+msgid "E215: Illegal character after *: %s"
+msgstr "E215: Unzulässiges Zeichen nach *: %s"
+
+#, c-format
+msgid "E216: No such event: %s"
+msgstr "E216: Kein derartiges Ereignis: %s"
+
+#, c-format
+msgid "E216: No such group or event: %s"
+msgstr "E216: Keine solche Gruppe oder Ereignis: %s"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Auto-Commands ---"
+msgstr ""
+"\n"
+"--- Autokommandos ---"
+
+#, c-format
+msgid "E680: <buffer=%d>: invalid buffer number "
+msgstr "E680: <buffer=%d>: Ungültige Puffer Nummer "
+
+msgid "E217: Can't execute autocommands for ALL events"
+msgstr "E217: Autokommandos können nicht für ALL Ereignisse ausgeführt werden"
+
+msgid "No matching autocommands"
+msgstr "Keine passenden Autokommandos"
+
+msgid "E218: autocommand nesting too deep"
+msgstr "E218: Autokommando-Schachtelung zu tief"
+
+#, c-format
+msgid "%s Auto commands for \"%s\""
+msgstr "%s Autokommandos für \"%s\""
+
+#, c-format
+msgid "Executing %s"
+msgstr "Ausführung von %s"
+
+#. always scroll up, don't overwrite
+#, c-format
+msgid "autocommand %s"
+msgstr "Autokommando %s"
+
+msgid "E219: Missing {."
+msgstr "E219: Es fehlt ein {."
+
+msgid "E220: Missing }."
+msgstr "E220: Es fehlt ein }."
+
+msgid "E490: No fold found"
+msgstr "E490: Keine Faltung gefunden"
+
+msgid "E350: Cannot create fold with current 'foldmethod'"
+msgstr "E350: Faltung kann mit der aktuellen Faltungsmethode nicht erzeugt werden"
+
+msgid "E351: Cannot delete fold with current 'foldmethod'"
+msgstr "E351: Faltung kann mit der aktuellen Faltungsmethode nicht gelöscht werden"
+
+#, c-format
+msgid "+--%3ld lines folded "
+msgstr "+--%3ld Zeilen gefaltet "
+
+msgid "E222: Add to read buffer"
+msgstr "E222: Zum Lesepuffer hinzufügen"
+
+msgid "E223: recursive mapping"
+msgstr "E223: rekursive Zuordnung"
+
+#, c-format
+msgid "E224: global abbreviation already exists for %s"
+msgstr "E224: Globale Abkürzung für %s existiert bereits"
+
+#, c-format
+msgid "E225: global mapping already exists for %s"
+msgstr "E225: Globale Zuordnung für %s existiert bereits"
+
+#, c-format
+msgid "E226: abbreviation already exists for %s"
+msgstr "E226: Abkürzung für %s existiert bereits"
+
+#, c-format
+msgid "E227: mapping already exists for %s"
+msgstr "E227: Zuordnung für %s existiert bereits"
+
+msgid "No abbreviation found"
+msgstr "Keine Abkürzung gefunden"
+
+msgid "No mapping found"
+msgstr "Keine Zuordnung gefunden"
+
+msgid "E228: makemap: Illegal mode"
+msgstr "E228: makemap: Unzulässiger Modus"
+
+msgid "E229: Cannot start the GUI"
+msgstr "E229: GUI kann nicht gestartet werden"
+
+#, c-format
+msgid "E230: Cannot read from \"%s\""
+msgstr "E230: Kann nicht von \"%s\" lesen"
+
+msgid "E665: Cannot start GUI, no valid font found"
+msgstr "E665: GUI kann nicht gestartet werden, keine gültige Schrift gefunden"
+
+msgid "E231: 'guifontwide' invalid"
+msgstr "E231: 'guifontwide' ungültig"
+
+msgid "E599: Value of 'imactivatekey' is invalid"
+msgstr "E599: Wert von 'imactivatekey' ist ungültig"
+
+#, c-format
+msgid "E254: Cannot allocate color %s"
+msgstr "E254: Kann die Farbe %s nicht zuweisen"
+
+msgid "<cannot open> "
+msgstr "<kann nicht öffnen> "
+
+#, c-format
+msgid "E616: vim_SelFile: can't get font %s"
+msgstr "E616: vim_SelFile: kann Schriftart %s nicht erhalten"
+
+msgid "E614: vim_SelFile: can't return to current directory"
+msgstr "E614: vim_SelFile: kann nicht zum laufenden Verzeichnis zurückkehren"
+
+msgid "Pathname:"
+msgstr "Pfad:"
+
+msgid "E615: vim_SelFile: can't get current directory"
+msgstr "E615: vim_SelFile: aktuelles Verzeichnis kann nicht ermittelt werden"
+
+msgid "OK"
+msgstr "OK"
+
+msgid "Cancel"
+msgstr "Abbrechen"
+
+msgid "Scrollbar Widget: Could not get geometry of thumb pixmap."
+msgstr "Scrollbar Widget: Geometrie des Bildchens kann nicht ermittelt werden"
+
+msgid "Vim dialog"
+msgstr "Vim-Dialog"
+
+msgid "E232: Cannot create BalloonEval with both message and callback"
+msgstr "E232: BalloonEval kann nicht mit sowohl \"message\" und \"callback\" erzeugt werden"
+
+msgid "Vim dialog..."
+msgstr "Vim-Dialog..."
+
+msgid ""
+"&Yes\n"
+"&No\n"
+"&Cancel"
+msgstr ""
+"&Ja\n"
+"&Nein\n"
+"&Abbrechen"
+
+msgid "Input _Methods"
+msgstr "Eingabe _Methoden"
+
+msgid "VIM - Search and Replace..."
+msgstr "VIM - Suchen und Ersetzen..."
+
+msgid "VIM - Search..."
+msgstr "VIM - Suchen..."
+
+msgid "Find what:"
+msgstr "Wonach suchen:"
+
+msgid "Replace with:"
+msgstr "Ersetzen mit:"
+
+#. whole word only button
+msgid "Match whole word only"
+msgstr "Nur ganzes Wort suchen"
+
+#. match case button
+msgid "Match case"
+msgstr "Groß-/Kleinschreibung"
+
+msgid "Direction"
+msgstr "Richtung"
+
+#. 'Up' and 'Down' buttons
+msgid "Up"
+msgstr "Aufwärts"
+
+msgid "Down"
+msgstr "Abwärts"
+
+msgid "Find Next"
+msgstr "Suche Nächstes"
+
+msgid "Replace"
+msgstr "Ersetzen"
+
+msgid "Replace All"
+msgstr "Alle ersetzen"
+
+msgid "Vim: Received \"die\" request from session manager\n"
+msgstr "Vim: \"die\"-Request von Session-Manager erhalten\n"
+
+msgid "Close"
+msgstr "Schließe"
+
+msgid "New tab"
+msgstr "Neues Tab"
+
+msgid "Open Tab..."
+msgstr "Öffne in Tab..."
+
+msgid "Vim: Main window unexpectedly destroyed\n"
+msgstr "Vim: Hauptfenster unerwartet gelöscht\n"
+
+msgid "Font Selection"
+msgstr "Auswahl der Schriftart"
+
+msgid "Used CUT_BUFFER0 instead of empty selection"
+msgstr "CUT_BUFFER0 anstatt der leeren Auswahl benutzt"
+
+msgid "&Filter"
+msgstr "&Filter"
+
+msgid "&Cancel"
+msgstr "&Abbrechen"
+
+msgid "Directories"
+msgstr "Verzeichnisse"
+
+msgid "Filter"
+msgstr "Filter"
+
+msgid "&Help"
+msgstr "&Hilfe"
+
+msgid "Files"
+msgstr "Dateien"
+
+msgid "&OK"
+msgstr "&Ok"
+
+msgid "Selection"
+msgstr "Auswahl"
+
+msgid "Find &Next"
+msgstr "&Nächste"
+
+msgid "&Replace"
+msgstr "&Ersetze"
+
+msgid "Replace &All"
+msgstr "Ersetze &alles"
+
+msgid "&Undo"
+msgstr "&Rückgängig"
+
+#, c-format
+msgid "E671: Cannot find window title \"%s\""
+msgstr "E671: Kann Fenstertitel \"%s\" nicht finden"
+
+#, c-format
+msgid "E243: Argument not supported: \"-%s\"; Use the OLE version."
+msgstr "E243: Argument wird nicht unterstützt: \"-%s\"; verwende die OLE Version."
+
+msgid "E672: Unable to open window inside MDI application"
+msgstr "E672: Kann Fenster nicht innerhalb einer MDI Anwendung öffnen"
+
+msgid "Close tab"
+msgstr "Tab schließen"
+
+msgid "Open tab..."
+msgstr "Öffne in Tab..."
+
+msgid "Find string (use '\\\\' to find a '\\')"
+msgstr "Suche (benütze '\\\\' um ein '\\' zu finden)"
+
+msgid "Find & Replace (use '\\\\' to find a '\\')"
+msgstr "Suche & Ersetze (benütze '\\\\' um ein '\\' zu finden)"
+
+#. 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 "Nicht verwendet"
+
+msgid "Directory\t*.nothing\n"
+msgstr "Verzeichnis\t*.nichts\n"
+
+msgid "Vim E458: Cannot allocate colormap entry, some colors may be incorrect"
+msgstr "Vim E458: \"Colormap\"-Eintrag kann nicht zugewiesen werden, einige Farben können falsch sein"
+
+#, c-format
+msgid "E250: Fonts for the following charsets are missing in fontset %s:"
+msgstr "E250: Schriftarten für die folgenden Zeichensätze fehlen im Fontset %s:"
+
+#, c-format
+msgid "E252: Fontset name: %s"
+msgstr "E252: Fontset Name: %s"
+
+#, c-format
+msgid "Font '%s' is not fixed-width"
+msgstr "Schriftart '%s' hat keine feste Breite"
+
+#, c-format
+msgid "E253: Fontset name: %s\n"
+msgstr "E253: Fontset Name: %s\n"
+
+#, c-format
+msgid "Font0: %s\n"
+msgstr "Schriftart 0: %s\n"
+
+#, c-format
+msgid "Font1: %s\n"
+msgstr "Schriftart 1: %s\n"
+
+#, c-format
+msgid "Font%ld width is not twice that of font0\n"
+msgstr "Die Breite der Schriftart %ld ist nicht doppelt so groß wie die der Schriftart 0\n"
+
+#, c-format
+msgid "Font0 width: %ld\n"
+msgstr "Schriftart 0 Breite: %ld\n"
+
+#, c-format
+msgid ""
+"Font1 width: %ld\n"
+"\n"
+msgstr ""
+"Schriftart 1 Breite: %ld\n"
+"\n"
+
+msgid "Invalid font specification"
+msgstr "Ungültige Spezifikation der Schriftart"
+
+msgid "&Dismiss"
+msgstr "&Aufheben"
+
+msgid "no specific match"
+msgstr "keine spezifische Übereinstimmung"
+
+msgid "Vim - Font Selector"
+msgstr "Vim - Auswahl der Schriftart"
+
+msgid "Name:"
+msgstr "Name:"
+
+#. create toggle button
+msgid "Show size in Points"
+msgstr "Zeige Größe in Punkten"
+
+msgid "Encoding:"
+msgstr "Zeichensatz:"
+
+msgid "Font:"
+msgstr "Schriftart:"
+
+msgid "Style:"
+msgstr "Stil:"
+
+msgid "Size:"
+msgstr "Größe:"
+
+msgid "E256: Hangul automata ERROR"
+msgstr "E256: Hangul-Automat Fehler"
+
+msgid "E550: Missing colon"
+msgstr "E550: Fehlender Doppelpunkt"
+
+msgid "E551: Illegal component"
+msgstr "E551: Unzulässige Komponente"
+
+msgid "E552: digit expected"
+msgstr "E552: Ziffer erwartet"
+
+#, c-format
+msgid "Page %d"
+msgstr "Seite %d"
+
+msgid "No text to be printed"
+msgstr "Kein Text zum Drucken"
+
+#, c-format
+msgid "Printing page %d (%d%%)"
+msgstr "Drucke Seite %d (%d%%)"
+
+#, c-format
+msgid " Copy %d of %d"
+msgstr " Kopiere %d von %d"
+
+#, c-format
+msgid "Printed: %s"
+msgstr "Gedruckt: %s"
+
+msgid "Printing aborted"
+msgstr "Ausdruck abgebrochen"
+
+msgid "E455: Error writing to PostScript output file"
+msgstr "E455: Fehler beim Schreiben der PostScript-Ausgabedatei"
+
+#, c-format
+msgid "E624: Can't open file \"%s\""
+msgstr "E624: Datei \"%s\" kann nicht geöffnet werden"
+
+#, c-format
+msgid "E457: Can't read PostScript resource file \"%s\""
+msgstr "E457: PostScript Ressource-Datei \"%s\" kann nicht gelesen werden"
+
+#, c-format
+msgid "E618: file \"%s\" is not a PostScript resource file"
+msgstr "E618: Datei \"%s\" ist keine PostScript Ressource-Datei"
+
+#, c-format
+msgid "E619: file \"%s\" is not a supported PostScript resource file"
+msgstr "E619: Datei \"%s\" ist keine unterstützte PostScript Ressource-Datei"
+
+#, c-format
+msgid "E621: \"%s\" resource file has wrong version"
+msgstr "E621: \"%s\" Ressource-Datei hat die falsche Version"
+
+msgid "E673: Incompatible multi-byte encoding and character set."
+msgstr "E673: Unzulässiger Multi-Byte Zeichensatz"
+
+msgid "E674: printmbcharset cannot be empty with multi-byte encoding."
+msgstr "E674: printmbcharset darf nicht leer sein mit Multi-Byte Zeichensatz."
+
+msgid "E675: No default font specified for multi-byte printing."
+msgstr "E675: Keine Standardschriftart angegeben für Multi-Byte Ausdruck."
+
+msgid "E324: Can't open PostScript output file"
+msgstr "E324: PostScript Ausgabe-Datei kann nicht geöffnet werden"
+
+#, c-format
+msgid "E456: Can't open file \"%s\""
+msgstr "E456: Datei \"%s\" kann nicht geöffnet werden"
+
+msgid "E456: Can't find PostScript resource file \"prolog.ps\""
+msgstr "E456: PostScript Ressource-Datei \"prolog.ps\" nicht gefunden"
+
+msgid "E456: Can't find PostScript resource file \"cidfont.ps\""
+msgstr "E456: PostScript Ressource-Datei \"cidfont.ps\" nicht gefunden"
+
+#, c-format
+msgid "E456: Can't find PostScript resource file \"%s.ps\""
+msgstr "E456: PostScript Ressource-Datei \"%s\" nicht gefunden"
+
+#, c-format
+msgid "E620: Unable to convert to print encoding \"%s\""
+msgstr "E620: Umwandlung nach dem Zeichensatz für den Ausdruck \"%s\" fehlgeschlagen"
+
+msgid "Sending to printer..."
+msgstr "Schicke zum Drucker..."
+
+msgid "E365: Failed to print PostScript file"
+msgstr "E365: Druck der PostScript-Datei schlug fehl"
+
+msgid "Print job sent."
+msgstr "Druckauftrag abgeschickt"
+
+msgid "Add a new database"
+msgstr "Eine neue Datenbank hinzufügen"
+
+msgid "Query for a pattern"
+msgstr "Muster suchen"
+
+msgid "Show this message"
+msgstr "diese Nachricht anzeigen"
+
+msgid "Kill a connection"
+msgstr "Verbindung abbrechen"
+
+msgid "Reinit all connections"
+msgstr "Verbindungen reinitialisieren"
+
+msgid "Show connections"
+msgstr "Verbindungen anzeigen"
+
+#, c-format
+msgid "E560: Usage: cs[cope] %s"
+msgstr "E560: Verwendung: cs[cope] %s"
+
+msgid "This cscope command does not support splitting the window.\n"
+msgstr "Dieser cscope-Befehl unterstützt nicht Teilen des Fensters.\n"
+
+msgid "E562: Usage: cstag <ident>"
+msgstr "E562: Verwendung: cstag <ident>"
+
+msgid "E257: cstag: tag not found"
+msgstr "E257: cstag: Tag nicht gefunden"
+
+#, c-format
+msgid "E563: stat(%s) error: %d"
+msgstr "E563: stat(%s) Fehler: %d"
+
+msgid "E563: stat error"
+msgstr "E563: 'stat' Fehler"
+
+#, c-format
+msgid "E564: %s is not a directory or a valid cscope database"
+msgstr "E564: %s ist kein Verzeichnis oder eine gültige cscope Datenbank"
+
+#, c-format
+msgid "Added cscope database %s"
+msgstr "csope Datenbank %s hinzugefügt"
+
+#, c-format
+msgid "E262: error reading cscope connection %ld"
+msgstr "E262: Fehler beim Lesen aus der cscope Verbindung %ld"
+
+msgid "E561: unknown cscope search type"
+msgstr "E561: Unbekannter cscope Suchtyp"
+
+msgid "E566: Could not create cscope pipes"
+msgstr "E566: cscope Pipes konnten nicht angelegt werden"
+
+msgid "E622: Could not fork for cscope"
+msgstr "E622: Konnte nicht für cscope verzweigen"
+
+msgid "cs_create_connection exec failed"
+msgstr "cs_create_connection exec misslang"
+
+msgid "E623: Could not spawn cscope process"
+msgstr "E623: Konnte cscope Prozess nicht hervorbringen"
+
+msgid "cs_create_connection: fdopen for to_fp failed"
+msgstr "cs_create_connection: fdopen von to_fp misslang"
+
+msgid "cs_create_connection: fdopen for fr_fp failed"
+msgstr "cs_create_connection: fdopen von fr_fp misslang"
+
+msgid "E567: no cscope connections"
+msgstr "E567: Keine cscope Verbindungen"
+
+#, c-format
+msgid "E259: no matches found for cscope query %s of %s"
+msgstr "E259: keine Übereinstimmungen gefunden für cscope Abfrage %s aus %s"
+
+#, c-format
+msgid "E469: invalid cscopequickfix flag %c for %c"
+msgstr "E469: Unzulässiges cscopequickfix Flag %c für %c"
+
+msgid "cscope commands:\n"
+msgstr "cscope Befehle:\n"
+
+#, c-format
+msgid "%-5s: %-30s (Usage: %s)"
+msgstr "%-5s: %-30s (Verwendung: %s)"
+
+#, c-format
+msgid "E625: cannot open cscope database: %s"
+msgstr "E625: Kann cscope Datenbank nicht öffnen: %s"
+
+msgid "E626: cannot get cscope database information"
+msgstr "E626: Kann cscope Datenbank-Informationen nicht bekommen"
+
+msgid "E568: duplicate cscope database not added"
+msgstr "E568: cscope Datenbank nicht doppelt hinzugefügt"
+
+msgid "E569: maximum number of cscope connections reached"
+msgstr "E569: Maximale Anzahl von cscope Verbindungen erreicht"
+
+#, c-format
+msgid "E261: cscope connection %s not found"
+msgstr "E261: cscope Verbindung %s nicht gefunden"
+
+#, c-format
+msgid "cscope connection %s closed"
+msgstr "cscope Verbindung %s geschlossen"
+
+#. should not reach here
+msgid "E570: fatal error in cs_manage_matches"
+msgstr "E570: Fataler Fehler in cs_manage_matches"
+
+#, c-format
+msgid "Cscope tag: %s"
+msgstr "Cscope Tag: %s"
+
+msgid ""
+"\n"
+" # line"
+msgstr ""
+"\n"
+" # Zeile"
+
+msgid "filename / context / line\n"
+msgstr "Dateiname / Kontext / Zeile\n"
+
+#, c-format
+msgid "E609: Cscope error: %s"
+msgstr "E609: Cscope Fehler: %s"
+
+msgid "All cscope databases reset"
+msgstr "alle cscope Datenbanken zurückgesetzt"
+
+msgid "no cscope connections\n"
+msgstr "keine cscope-Verbindungen\n"
+
+msgid " # pid database name prepend path\n"
+msgstr " # pid Datenbank Name\t führender Pfad\n"
+
+msgid ""
+"???: Sorry, this command is disabled, the MzScheme library could not be "
+"loaded."
+msgstr ""
+"???: Dieser Befehl ist nicht verfügbar, die MzScheme Bibliothek konnte nicht "
+"geladen werden"
+
+msgid "invalid expression"
+msgstr "ungültiger Ausdruck"
+
+msgid "expressions disabled at compile time"
+msgstr "Ausdrücke wurden zur Zeit des Übersetzens nicht zugelassen"
+
+msgid "hidden option"
+msgstr "versteckte Option"
+
+msgid "unknown option"
+msgstr "unbekannte Option"
+
+msgid "window index is out of range"
+msgstr "Fensterindex außerhalb des zulässigen Bereichs"
+
+msgid "couldn't open buffer"
+msgstr "konnte Puffer nicht öffnen"
+
+msgid "cannot save undo information"
+msgstr "kann Information für die Wiederherstellung nicht speichern"
+
+msgid "cannot delete line"
+msgstr "Zeile kann nicht gelöscht werden"
+
+msgid "cannot replace line"
+msgstr "Zeile kann nicht ersetzt werden"
+
+msgid "cannot insert line"
+msgstr "Zeile kann nicht eingefügt werden"
+
+msgid "string cannot contain newlines"
+msgstr "Zeichenfolge kann keine Zeilenwechsel enthalten"
+
+msgid "Vim error: ~a"
+msgstr "Vim Fehler: ~a"
+
+msgid "Vim error"
+msgstr "Vim Fehler"
+
+msgid "buffer is invalid"
+msgstr "ungültiger Puffer"
+
+msgid "window is invalid"
+msgstr "ungültiges Fenster"
+
+msgid "linenr out of range"
+msgstr "'linenr' außerhalb des zulässigen Bereichs"
+
+msgid "not allowed in the Vim sandbox"
+msgstr "in der Vim-Sandbox nicht erlaubt"
+
+msgid ""
+"E263: Sorry, this command is disabled, the Python library could not be "
+"loaded."
+msgstr ""
+"E263: Dieser Befehl ist nicht verfügbar, die Python-Bibliothek konnte nicht "
+"geladen werden"
+
+msgid "E659: Cannot invoke Python recursively"
+msgstr "E659: Kann Python nicht rekursiv ausführen"
+
+msgid "can't delete OutputObject attributes"
+msgstr "OutputObject-Attribute können nicht gelöscht werden"
+
+msgid "softspace must be an integer"
+msgstr "\"softspace\" muss eine ganze Zahl sein"
+
+msgid "invalid attribute"
+msgstr "unzulässiges Attribut"
+
+msgid "writelines() requires list of strings"
+msgstr "writelines() verlangt eine Liste von Zeichenfolgen"
+
+msgid "E264: Python: Error initialising I/O objects"
+msgstr "E264: Python: Fehler bei der Initialisierung von I/O Objekten"
+
+msgid "attempt to refer to deleted buffer"
+msgstr "Versuch, Bezug auf einen gelöschten Puffer zu nehmen"
+
+msgid "line number out of range"
+msgstr "Zeilennummer außerhalb des zulässigen Bereichs"
+
+#, c-format
+msgid "<buffer object (deleted) at %8lX>"
+msgstr "<Pufferobjekt (gelöscht) bei %8lX>"
+
+msgid "invalid mark name"
+msgstr "ungültiger Name einer Markierung"
+
+msgid "no such buffer"
+msgstr "kein solcher Puffer vorhanden"
+
+msgid "attempt to refer to deleted window"
+msgstr "Versuch, Bezug auf eine gelöschtes Fenster zu nehmen"
+
+msgid "readonly attribute"
+msgstr "nur-Lesen Attribut"
+
+msgid "cursor position outside buffer"
+msgstr "Cursor Position außerhalb des Puffers"
+
+#, c-format
+msgid "<window object (deleted) at %.8lX>"
+msgstr "<Fensterobjekt (gelöscht) bei %.8lX>"
+
+#, c-format
+msgid "<window object (unknown) at %.8lX>"
+msgstr "<Fensterobjekt (unbekannt) bei %.8lX>"
+
+#, c-format
+msgid "<window %d>"
+msgstr "<Fenster %d>"
+
+msgid "no such window"
+msgstr "ungültiges Fenster"
+
+msgid ""
+"E266: Sorry, this command is disabled, the Ruby library could not be loaded."
+msgstr ""
+"E266: Dieser Befehl ist nicht verfügbar, die Ruby Bibliothek konnte nicht geladen werden"
+
+#, c-format
+msgid "E273: unknown longjmp status %d"
+msgstr "E273: Unbekannter longjmp Status %d"
+
+msgid "Toggle implementation/definition"
+msgstr "Umschaltung zwischen Implementierung/Definition"
+
+msgid "Show base class of"
+msgstr "Zeige Basis-Klasse von"
+
+msgid "Show overridden member function"
+msgstr "Zeige überschriebene Methode"
+
+msgid "Retrieve from file"
+msgstr "Beziehe aus Datei"
+
+msgid "Retrieve from project"
+msgstr "Beziehe aus Projekt"
+
+msgid "Retrieve from all projects"
+msgstr "Beziehe aus allen Projekten"
+
+msgid "Retrieve"
+msgstr "Beziehe"
+
+msgid "Show source of"
+msgstr "Zeige die Quelle von"
+
+msgid "Find symbol"
+msgstr "Finde Symbol"
+
+msgid "Browse class"
+msgstr "Durchsehe Klassen"
+
+msgid "Show class in hierarchy"
+msgstr "Zeige Klasse in Hierarchie"
+
+msgid "Show class in restricted hierarchy"
+msgstr "Zeige Klasse in eingeschränkter Hierarchie"
+
+msgid "Xref refers to"
+msgstr "Xref bezieht sich auf"
+
+msgid "Xref referred by"
+msgstr "Xref hat Bezüge zu"
+
+msgid "Xref has a"
+msgstr "Xref hat ein"
+
+msgid "Xref used by"
+msgstr "Xref wird verwendet von"
+
+msgid "Show docu of"
+msgstr "Zeige Docu aus"
+
+msgid "Generate docu for"
+msgstr "Generiere Docu für"
+
+msgid ""
+"Cannot connect to SNiFF+. Check environment (sniffemacs must be found in "
+"$PATH).\n"
+msgstr ""
+"Kann keine verbindung zu SNiFF+ aufnehmen. Prüfe die Umgebung (sniffemacs "
+"muss in $PATH) zu finden sein.\n"
+
+msgid "E274: Sniff: Error during read. Disconnected"
+msgstr "E274: Sniff: Fehler beim Lesen. Verbindung abgebrochen"
+
+msgid "SNiFF+ is currently "
+msgstr "SNiFF+ ist zur Zeit"
+
+msgid "not "
+msgstr "nicht"
+
+msgid "connected"
+msgstr "verbunden"
+
+#, c-format
+msgid "E275: Unknown SNiFF+ request: %s"
+msgstr "E275: Unbekannte SNiFF+ Anfrage: %s"
+
+msgid "E276: Error connecting to SNiFF+"
+msgstr "E276: Fehler beim Herstellen der Verbindung mit SNiFF+"
+
+msgid "E278: SNiFF+ not connected"
+msgstr "E278: SNiFF+ ist nicht verbunden"
+
+msgid "E279: Not a SNiFF+ buffer"
+msgstr "E279: Ist kein SNiFF+ Puffer"
+
+msgid "Sniff: Error during write. Disconnected"
+msgstr "Sniff: Fehler beim Schreiben. Verbindung abgebrochen"
+
+msgid "invalid buffer number"
+msgstr "ungültige Puffernummer"
+
+msgid "not implemented yet"
+msgstr "nicht implementiert"
+
+#. ???
+msgid "cannot set line(s)"
+msgstr "kann keine Zeile/Zeilen setzen"
+
+msgid "mark not set"
+msgstr "Marke nicht gesetzt"
+
+#, c-format
+msgid "row %d column %d"
+msgstr "Zeile %d Spalte %d"
+
+msgid "cannot insert/append line"
+msgstr "kann Zeile nicht ein-/anfügen"
+
+msgid "unknown flag: "
+msgstr "unbekanntes Flag: "
+
+msgid "unknown vimOption"
+msgstr "unbekannte vimOption"
+
+msgid "keyboard interrupt"
+msgstr "Tastatur-Unterbrechung"
+
+msgid "vim error"
+msgstr "vim Fehler"
+
+msgid "cannot create buffer/window command: object is being deleted"
+msgstr "Puffer/Fenster-Befehl kann nicht ausgeführt werden: das Objekt wird gelöscht"
+
+msgid ""
+"cannot register callback command: buffer/window is already being deleted"
+msgstr ""
+"kann keinen Callback-Befehl registrieren: Puffer/Fenster ist bereits gelöscht"
+
+#. This should never happen. Famous last word?
+msgid ""
+"E280: TCL FATAL ERROR: reflist corrupt!? Please report this to vim-dev@vim."
+"org"
+msgstr ""
+"E280: TCL FATALER FEHLER: reflist kaputt!? Bitte vim-dev@vim.org"
+"benachrichtigen."
+
+msgid "cannot register callback command: buffer/window reference not found"
+msgstr "kann keinen Callback-Befehl registrieren: Puffer/Fenster-Referenz nicht gefunden"
+
+msgid ""
+"E571: Sorry, this command is disabled: the Tcl library could not be loaded."
+msgstr ""
+"E571: Dieser Befehl ist nicht verfügbar: die Tcl Bibliothek konnte nicht geladen werden"
+
+msgid ""
+"E281: TCL ERROR: exit code is not int!? Please report this to vim-dev@vim.org"
+msgstr ""
+"E281: TCL FEHLER: Exit-Code ist nicht int!? Bitte vim-dev@vim.org benachrichtigen."
+
+#, c-format
+msgid "E572: exit code %d"
+msgstr "E572: Ekit-Code %d"
+
+msgid "cannot get line"
+msgstr "kann Zeile nicht erhalten"
+
+msgid "Unable to register a command server name"
+msgstr "Befehls-Server Name kann nicht registriert werden"
+
+msgid "E248: Failed to send command to the destination program"
+msgstr "E248: Schicken des Befehls zum Ziel-Programm schlug fehl"
+
+#, c-format
+msgid "E573: Invalid server id used: %s"
+msgstr "E573: Ungültige Server ID verwendet: %s"
+
+msgid "E251: VIM instance registry property is badly formed. Deleted!"
+msgstr "E251: Registry-Eigenschaft der VIM Instanz ist fehlerhaft. Gelöscht!"
+
+msgid "Unknown option argument"
+msgstr "Unbekanntes Optionsargument"
+
+msgid "Too many edit arguments"
+msgstr "Zu viele Editor-Argumente"
+
+msgid "Argument missing after"
+msgstr "Argument fehlt nach"
+
+msgid "Garbage after option argument"
+msgstr "Schrott nach dem Optionsargument"
+
+msgid "Too many \"+command\", \"-c command\" or \"--cmd command\" arguments"
+msgstr "Zu viele \"+command\", \"-c command\" oder \"--cmd command\" Argumente"
+
+msgid "Invalid argument for"
+msgstr "Ungültiges Argument für"
+
+msgid "This Vim was not compiled with the diff feature."
+msgstr "Vim wurde nicht mit der \"diff\"-Eigenschaft übersetzt"
+
+msgid "Attempt to open script file again: \""
+msgstr "Versuche, die Skript-Datei erneut zu öffnen: \""
+
+msgid "Cannot open for reading: \""
+msgstr "kann nicht zum Lesen geöffnet werden: \""
+
+msgid "Cannot open for script output: \""
+msgstr "kann nicht zur Skript-Ausgabe geöffnet werden: \""
+
+msgid "Vim: Error: Failure to start gvim from NetBeans\n"
+msgstr "Vim: Fehler: Konnte gvim nicht von NetBeans aus starten\n"
+
+msgid "Vim: Warning: Output is not to a terminal\n"
+msgstr "Vim: Warnung: Die Ausgabe erfolgt nicht auf einem Terminal\n"
+
+msgid "Vim: Warning: Input is not from a terminal\n"
+msgstr "Vim: Warnung: Die Eingabe kommt nicht von einem Terminal\n"
+
+#. just in case..
+msgid "pre-vimrc command line"
+msgstr "pre-vimrc Befehls-Zeile"
+
+#, c-format
+msgid "E282: Cannot read from \"%s\""
+msgstr "E282: Kann nicht von \"%s\" lesen"
+
+msgid ""
+"\n"
+"More info with: \"vim -h\"\n"
+msgstr ""
+"\n"
+"Weitere Informationen mit: \"vim -h\"\n"
+
+msgid "[file ..] edit specified file(s)"
+msgstr "[Datei ..] editiere die angegebenen Datei(-en)"
+
+msgid "- read text from stdin"
+msgstr "- lese Text von stdin"
+
+msgid "-t tag edit file where tag is defined"
+msgstr "-t tag öffne Datei in der der Tag definiert wurde"
+
+msgid "-q [errorfile] edit file with first error"
+msgstr "-q [Fehler-Datei] öffne Datei mit erstem Fehler"
+
+msgid ""
+"\n"
+"\n"
+"usage:"
+msgstr ""
+"\n"
+"\n"
+"Verwendung:"
+
+msgid " vim [arguments] "
+msgstr " vim [Argumente] "
+
+msgid ""
+"\n"
+" or:"
+msgstr ""
+"\n"
+" oder:"
+
+msgid ""
+"\n"
+"\n"
+"Arguments:\n"
+msgstr ""
+"\n"
+"\n"
+"Argumente:\n"
+
+msgid "--\t\t\tOnly file names after this"
+msgstr "--\t\t\tHiernach nur Dateinamen"
+
+msgid "--literal\t\tDon't expand wildcards"
+msgstr "--literal\t\tPlatzhalter werden nicht ausgewertet"
+
+msgid "-register\t\tRegister this gvim for OLE"
+msgstr "-register\t\tRegistriere diesen gvim in OLE"
+
+msgid "-unregister\t\tUnregister gvim for OLE"
+msgstr "-unregister\t\tDeregistriere gvim aus OLE"
+
+msgid "-g\t\t\tRun using GUI (like \"gvim\")"
+msgstr "-g\t\t\tStart als GUI (wie \"gvim\")"
+
+msgid "-f or --nofork\tForeground: Don't fork when starting GUI"
+msgstr "-f\t\t\tVordergrund: Kein \"fork\" beim Start der GUI"
+
+msgid "-v\t\t\tVi mode (like \"vi\")"
+msgstr "-v\t\t\tVi Modus (wie \"vi\")"
+
+msgid "-e\t\t\tEx mode (like \"ex\")"
+msgstr "-e\t\t\tEx Modus (wie \"ex\")"
+
+msgid "-s\t\t\tSilent (batch) mode (only for \"ex\")"
+msgstr "-s\t\t\tLeiser (batch) Modus (nur für \"ex\")"
+
+msgid "-d\t\t\tDiff mode (like \"vimdiff\")"
+msgstr "-d\t\t\tDiff Modus (wie \"vimdiff\")"
+
+msgid "-y\t\t\tEasy mode (like \"evim\", modeless)"
+msgstr "-y\t\t\tLeichter Modus (wie \"evim\", ohne Modi)"
+
+msgid "-R\t\t\tReadonly mode (like \"view\")"
+msgstr "-R\t\t\tModus ohne Schreibrechte (wie \"view\")"
+
+msgid "-Z\t\t\tRestricted mode (like \"rvim\")"
+msgstr "-Z\t\t\tEingeschränkter Modus (wie \"rvim\")"
+
+msgid "-m\t\t\tModifications (writing files) not allowed"
+msgstr "-m\t\t\tModifikationen (beim Schreiben von Dateien) sind nicht erlaubt"
+
+msgid "-M\t\t\tModifications in text not allowed"
+msgstr "-M\t\t\tModifikationen im Text nicht erlaubt"
+
+msgid "-b\t\t\tBinary mode"
+msgstr "-b\t\t\tBinärmodus"
+
+msgid "-l\t\t\tLisp mode"
+msgstr "-l\t\t\tLisp Modus"
+
+msgid "-C\t\t\tCompatible with Vi: 'compatible'"
+msgstr "-C\t\t\tKompatibel zu Vi: 'compatible'"
+
+msgid "-N\t\t\tNot fully Vi compatible: 'nocompatible'"
+msgstr "-N\t\t\tNicht ganz kompatibel zu Vi: 'nocompatible'"
+
+msgid "-V[N]\t\tVerbose level"
+msgstr "-V[N]\t\tVerbose Stufe"
+
+msgid "-D\t\t\tDebugging mode"
+msgstr "-D\t\t\tDebug-Modus"
+
+msgid "-n\t\t\tNo swap file, use memory only"
+msgstr "-n\t\t\tKeine Auslagerungsdatei, verwende nur Speicher"
+
+msgid "-r\t\t\tList swap files and exit"
+msgstr "-r\t\t\tListe nur Auslagerungsdateien auf"
+
+msgid "-r (with file name)\tRecover crashed session"
+msgstr "-r (mit Dateiname)\tStelle abgestürzte Session wieder her"
+
+msgid "-L\t\t\tSame as -r"
+msgstr "-L\t\t\tGenauso wie z -r"
+
+msgid "-f\t\t\tDon't use newcli to open window"
+msgstr "-f\t\t\tVerwende nicht newcli zum Öffnen eines neuen Fensters"
+
+msgid "-dev <device>\t\tUse <device> for I/O"
+msgstr "-dev <device>\t\tVerwende <device> for I/O"
+
+msgid "-A\t\t\tstart in Arabic mode"
+msgstr "-A\t\t\tStart im Arabischen Modus"
+
+msgid "-H\t\t\tStart in Hebrew mode"
+msgstr "-H\t\t\tStart im Hebräischen Modus"
+
+msgid "-F\t\t\tStart in Farsi mode"
+msgstr "-F\t\t\tStart im Farsi Modus"
+
+msgid "-T <terminal>\tSet terminal type to <terminal>"
+msgstr "-T <terminal>\tSetze Terminaltyp auf <terminal>"
+
+msgid "-u <vimrc>\t\tUse <vimrc> instead of any .vimrc"
+msgstr "-u <vimrc>\t\tBenutze <vimrc> anstatt jeglicher .vimrc"
+
+msgid "-U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc"
+msgstr "-U <gvimrc>\t\tBenutze <gvimrc> anstatt jeglicher .gvimrc"
+
+msgid "--noplugin\t\tDon't load plugin scripts"
+msgstr "--noplugin\t\tlade keine \"plugin\"-Skripte"
+
+msgid "-o[N]\t\tOpen N windows (default: one for each file)"
+msgstr "-o[N]\t\tÖffne N Fenster (Vorgabe: einzeln für jede Datei)"
+
+msgid "-O[N]\t\tLike -o but split vertically"
+msgstr "-O[N]\t\tWie -o, aber teile vertikal"
+
+msgid "+\t\t\tStart at end of file"
+msgstr "+\t\t\tStarte am Ende der Datei"
+
+msgid "+<lnum>\t\tStart at line <lnum>"
+msgstr "+<lnum>\t\tStart in Zeile <lnum>"
+
+msgid "--cmd <command>\tExecute <command> before loading any vimrc file"
+msgstr "--cmd <Befehl>\tFühre <Befehl> vor dem Laden jeglicher vimrc-Datei aus"
+
+msgid "-c <command>\t\tExecute <command> after loading the first file"
+msgstr "-c <Befehl>\t\tFühre <Befehl> nach dem Laden der ersten Datei aus"
+
+msgid "-S <session>\t\tSource file <session> after loading the first file"
+msgstr "-S <session>\t\tLese Datei <session> nach dem Laden der ersten Datei"
+
+msgid "-s <scriptin>\tRead Normal mode commands from file <scriptin>"
+msgstr "-s <scriptin>\tLese Normal-Modus Befehle aus der Skript-Datei <scriptin>"
+
+msgid "-w <scriptout>\tAppend all typed commands to file <scriptout>"
+msgstr "-w <scriptout>\tBefehle am Ende der Skript-Datei <scriptout> anfügen"
+
+msgid "-W <scriptout>\tWrite all typed commands to file <scriptout>"
+msgstr "-W <scriptout>\tSchreibe Befehle in die Skript-Datei <scriptout>"
+
+msgid "-x\t\t\tEdit encrypted files"
+msgstr "-x\t\t\tEditiere kodierte Dateien"
+
+msgid "-display <display>\tConnect vim to this particular X-server"
+msgstr "-display <display>\tStarte vim <display>"
+
+msgid "-X\t\t\tDo not connect to X server"
+msgstr "-X\t\t\tStelle keine Verbindung zum X-server her"
+
+msgid "--remote <files>\tEdit <files> in a Vim server if possible"
+msgstr "--remote <Dateien>\tEditiere <Dateien> in einem Vim-Server falls möglich"
+
+msgid "--remote-silent <files> Same, don't complain if there is no server"
+msgstr "--remote-silent <Dateien> Dasselbe ohne Warnung, wenn kein Server vorhanden ist"
+
+msgid ""
+"--remote-wait <files> As --remote but wait for files to have been edited"
+msgstr ""
+"--remote-wait <Dateien> Wie --remote, aber warte, bis die <Dateien> editiert wurden"
+
+msgid ""
+"--remote-wait-silent <files> Same, don't complain if there is no server"
+msgstr ""
+"--remote-wait-silent <files> Dasselbe ohne Warnung, wenn kein Server vorhanden ist"
+
+msgid "--remote-send <keys>\tSend <keys> to a Vim server and exit"
+msgstr "--remote-send <keys>\tSchicke <keys> zu einem Vim Server und beende"
+
+msgid "--remote-expr <expr>\tEvaluate <expr> in a Vim server and print result"
+msgstr "--remote-expr <Ausdruck>\tFühre <Ausdruck> in einem Vim-Server aus und drucke das Ergebnis"
+
+msgid "--serverlist\t\tList available Vim server names and exit"
+msgstr "--serverlist\t\tDrucke verfügbare Vim-Server-Namen und beende"
+
+msgid "--servername <name>\tSend to/become the Vim server <name>"
+msgstr "--servername <Name>\tBenutze den Vim-Server <Name>"
+
+msgid "-i <viminfo>\t\tUse <viminfo> instead of .viminfo"
+msgstr "-i <viminfo>\t\tBenutze <viminfo> statt .viminfo"
+
+msgid "-h or --help\tPrint Help (this message) and exit"
+msgstr "-h or --help\tAnzeigen der Hilfe (diesen Text) und beenden"
+
+msgid "--version\t\tPrint version information and exit"
+msgstr "--version\t\tVersionsinformation anzeigen und beenden"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (Motif version):\n"
+msgstr ""
+"\n"
+"Argumente für die gvim (Motif Version):\n"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (neXtaw version):\n"
+msgstr ""
+"\n"
+"Argumente für die gvim (neXtaw Version):\n"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (Athena version):\n"
+msgstr ""
+"\n"
+"Argumente für die gvim (Athena Version):\n"
+
+msgid "-display <display>\tRun vim on <display>"
+msgstr "-display <display>\tStarte vim auf <display>"
+
+msgid "-iconic\t\tStart vim iconified"
+msgstr "-iconic\t\tStarte vim als Icon"
+
+msgid "-name <name>\t\tUse resource as if vim was <name>"
+msgstr "-name <name>\t\tBenutze so als ob vim <name> hieße"
+
+msgid "\t\t\t (Unimplemented)\n"
+msgstr "\t\t\t (Nicht implementiert)\n"
+
+msgid "-background <color>\tUse <color> for the background (also: -bg)"
+msgstr "-background <Farbe>\tBenutze <Farbe> für den Hintergrund (auch mit: -bg)"
+
+msgid "-foreground <color>\tUse <color> for normal text (also: -fg)"
+msgstr "-foreground <Farbe>\tBenutze <Farbe> für den Text Vordergrund (auch mit: -fg)"
+
+msgid "-font <font>\t\tUse <font> for normal text (also: -fn)"
+msgstr "-font <Schriftart>\tBenutze <Schriftart> für normalen Text (auch mit: -fn)"
+
+msgid "-boldfont <font>\tUse <font> for bold text"
+msgstr "-boldfont <Schriftart>\tBenutze <Schriftart> für Fettschrift"
+
+msgid "-italicfont <font>\tUse <font> for italic text"
+msgstr "-italicfont <Schriftart>\tBenutze <Schriftart> für geneigten Text"
+
+msgid "-geometry <geom>\tUse <geom> for initial geometry (also: -geom)"
+msgstr "-geometry <geom>\tbenutze <geom> für die Anfangs Abmessungen (auch mit: -geom)"
+
+msgid "-borderwidth <width>\tUse a border width of <width> (also: -bw)"
+msgstr "-borderwidth <Breite>\tBenutze einen Rahmen der Breite <Breite> (auch mit: -bw)"
+
+msgid "-scrollbarwidth <width> Use a scrollbar width of <width> (also: -sw)"
+msgstr "-scrollbarwidth <Breite> Benutze eine Scrollbar der Breite <Breite> (auch mit: -sw)"
+
+msgid "-menuheight <height>\tUse a menu bar height of <height> (also: -mh)"
+msgstr "-menuheight <Höhe>\tBenutze einen Menü-Balken der Höhe <Höhe> (auch mit: -mh)"
+
+msgid "-reverse\t\tUse reverse video (also: -rv)"
+msgstr "-reverse\t\tBenutze invertierte Farben (auch mit: -rv)"
+
+msgid "+reverse\t\tDon't use reverse video (also: +rv)"
+msgstr "+reverse\t\tBenutze keine invertierten Farben (auch mit: +rv)"
+
+msgid "-xrm <resource>\tSet the specified resource"
+msgstr "-xrm <resource>\tSetze die gegebene Ressource"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (RISC OS version):\n"
+msgstr ""
+"\n"
+"Argumente für die gvim RISC-OS Version:\n"
+
+msgid "--columns <number>\tInitial width of window in columns"
+msgstr "--columns <Nummer>\tAnfangsbreite des Fensters in Spalten"
+
+msgid "--rows <number>\tInitial height of window in rows"
+msgstr "--rows <Nummer>\tAnfangshöhe des Fensters in Zeilen"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (GTK+ version):\n"
+msgstr ""
+"\n"
+"Argumente für die gvim GTK+ Version:\n"
+
+msgid "-display <display>\tRun vim on <display> (also: --display)"
+msgstr "-display <display>\tStarte vim auf <display> (auch mit: --display)"
+
+msgid "--role <role>\tSet a unique role to identify the main window"
+msgstr "--role <role>\tSetze eine eindeutige Rolle, um das Hauptfenster zu identifizieren"
+
+msgid "--socketid <xid>\tOpen Vim inside another GTK widget"
+msgstr "--socketid <xid>\tÖffne Vim in einem anderen GTK widget"
+
+msgid "-P <parent title>\tOpen Vim inside parent application"
+msgstr "-P <parent title>\tÖffne Vim innerhalb der Vater-Applikation"
+
+msgid "No display"
+msgstr "Keine Anzeige"
+
+#. Failed to send, abort.
+msgid ": Send failed.\n"
+msgstr ": Versendung fehlgeschlagen.\n"
+
+#. Let vim start normally.
+msgid ": Send failed. Trying to execute locally\n"
+msgstr ": Versendung fehlgeschlagen. Versuche lokale Ausführung\n"
+
+#, c-format
+msgid "%d of %d edited"
+msgstr "%d von %d bearbeitet"
+
+msgid "No display: Send expression failed.\n"
+msgstr "Keine Anzeige: Versenden des Ausdrucks fehlgeschlagen.\n"
+
+msgid ": Send expression failed.\n"
+msgstr ": Versenden des Ausdrucks fehlgeschlagen.\n"
+
+msgid "No marks set"
+msgstr "Keine Markierungen gesetzt"
+
+#, c-format
+msgid "E283: No marks matching \"%s\""
+msgstr "E283: Keine Markierungen passen zu \"%s\""
+
+#. Highlight title
+msgid ""
+"\n"
+"mark line col file/text"
+msgstr ""
+"\n"
+"Mark Zeile Sp Datei/Text"
+
+#. Highlight title
+msgid ""
+"\n"
+" jump line col file/text"
+msgstr ""
+"\n"
+" Sprung Zeile Sp Datei/Text"
+
+#. Highlight title
+msgid ""
+"\n"
+"change line col text"
+msgstr ""
+"\n"
+"Änder. Zeile Sp Text"
+
+msgid ""
+"\n"
+"# File marks:\n"
+msgstr ""
+"\n"
+"# Datei-Marken:\n"
+
+#. Write the jumplist with -'
+msgid ""
+"\n"
+"# Jumplist (newest first):\n"
+msgstr ""
+"\n"
+"# Geschichte (neueste zuerst):\n"
+
+msgid ""
+"\n"
+"# History of marks within files (newest to oldest):\n"
+msgstr ""
+"\n"
+"# Geschichte der Markierungen innerhalb von Dateien (neueste zuerst):\n"
+
+msgid "Missing '>'"
+msgstr "'>' fehlt"
+
+msgid "E543: Not a valid codepage"
+msgstr "E543: Keine zulässige Codepage"
+
+msgid "E284: Cannot set IC values"
+msgstr "E284: Kann die IC Werte nicht setzen"
+
+msgid "E285: Failed to create input context"
+msgstr "E285: Eingabe-Kontext konnte nicht erzeugt werden"
+
+msgid "E286: Failed to open input method"
+msgstr "E286: Eingabemethode konnte geöffnet werden"
+
+msgid "E287: Warning: Could not set destroy callback to IM"
+msgstr "E287: Achtung: Destroy Callabck konnte nicht auf IM gesetzt werden"
+
+msgid "E288: input method doesn't support any style"
+msgstr "E288: Eingabemethode unterstützt keinen einzigen Stil"
+
+msgid "E289: input method doesn't support my preedit type"
+msgstr "E289: Eingabemethode unterstützt nicht meinen Voreditier-Typen"
+
+msgid "E290: over-the-spot style requires fontset"
+msgstr "E290: der Über-dem-Punkt Stil benötigt fontset"
+
+msgid "E291: Your GTK+ is older than 1.2.3. Status area disabled"
+msgstr "E291: Ihr GTK+ ist älter als 1.2.3. Der Status-Bereich wird abgeschaltet"
+
+msgid "E292: Input Method Server is not running"
+msgstr "E292: Server der Eingabemethode läuft nicht"
+
+msgid "E293: block was not locked"
+msgstr "E293: Block war nicht gesperrt"
+
+msgid "E294: Seek error in swap file read"
+msgstr "E294: Positionierungsfehler beim Lesen der Auslagerungsdatei"
+
+msgid "E295: Read error in swap file"
+msgstr "E295: Lesefehler in der Auslagerungsdatei"
+
+msgid "E296: Seek error in swap file write"
+msgstr "E296: Positionierungsfehler beim Schreiben in die Auslagerungsdatei"
+
+msgid "E297: Write error in swap file"
+msgstr "E297: Fehler beim Schreiben in die Auslagerungsdatei"
+
+msgid "E300: Swap file already exists (symlink attack?)"
+msgstr "E300: Auslagerungsdatei ist bereits vorhanden (symlink Attacke?)"
+
+msgid "E298: Didn't get block nr 0?"
+msgstr "E298: Block Nr. 0 nicht erhalten?"
+
+msgid "E298: Didn't get block nr 1?"
+msgstr "E298: Block Nr. 1 nicht erhalten?"
+
+msgid "E298: Didn't get block nr 2?"
+msgstr "E298: Block Nr. 2 nicht erhalten?"
+
+#. could not (re)open the swap file, what can we do????
+msgid "E301: Oops, lost the swap file!!!"
+msgstr "E301: Ups, Verlust der Auslagerungsdatei!!!"
+
+msgid "E302: Could not rename swap file"
+msgstr "E302: Auslagerungsdatei konnte nicht umbenannt werden"
+
+#, c-format
+msgid "E303: Unable to open swap file for \"%s\", recovery impossible"
+msgstr "E303: Auslagerungsdatei für \"%s\" konnte nicht geöffnet werden, Wiederherstellung unmöglich"
+
+msgid "E304: ml_timestamp: Didn't get block 0??"
+msgstr "E304: ml_timestamp: Block Nr. 0 nicht erhalten?"
+
+#, c-format
+msgid "E305: No swap file found for %s"
+msgstr "E305: Keine Auslagerungsdatei für %s gefunden"
+
+msgid "Enter number of swap file to use (0 to quit): "
+msgstr "Geben Sie die Nummer der Auslagerungsdatei ein die verwendet werden soll (0 um abzubrechen): "
+
+#, c-format
+msgid "E306: Cannot open %s"
+msgstr "E306: %s kann nicht geöffnet werden"
+
+msgid "Unable to read block 0 from "
+msgstr "Block 0 kann nicht gelesen werden aus "
+
+msgid ""
+"\n"
+"Maybe no changes were made or Vim did not update the swap file."
+msgstr ""
+"\n"
+"Vielleicht wurden keine Änderungen vorgenommen oder Vim hatte die Auslagerungsdatei nicht aktualisiert."
+
+msgid " cannot be used with this version of Vim.\n"
+msgstr " kann nicht zusammen mit dieser Vim Version verwendet werden.\n"
+
+msgid "Use Vim version 3.0.\n"
+msgstr "Benutze Vim Version 3.0.\n"
+
+#, c-format
+msgid "E307: %s does not look like a Vim swap file"
+msgstr "E307: %s sieht nicht wie eine Vim Auslagerungsdatei aus"
+
+msgid " cannot be used on this computer.\n"
+msgstr " kann auf diesem Rechner nicht verwendet werden.\n"
+
+msgid "The file was created on "
+msgstr "Die Datei wurde erstellt um "
+
+msgid ""
+",\n"
+"or the file has been damaged."
+msgstr ""
+",\n"
+"oder die Datei wurde zerstört."
+
+#, c-format
+msgid "Using swap file \"%s\""
+msgstr "Verwende Auslagerungsdatei \"%s\""
+
+#, c-format
+msgid "Original file \"%s\""
+msgstr "Original-Datei \"%s\""
+
+msgid "E308: Warning: Original file may have been changed"
+msgstr "E308: Warnung: Die Originaldatei könnte verändert worden sein"
+
+#, c-format
+msgid "E309: Unable to read block 1 from %s"
+msgstr "E309: Block 1 kann nicht nicht von %s gelesen werden"
+
+msgid "???MANY LINES MISSING"
+msgstr "???VIELE ZEILEN FEHLEN"
+
+msgid "???LINE COUNT WRONG"
+msgstr "???ZEILEN ZÄHLER FALSCH"
+
+msgid "???EMPTY BLOCK"
+msgstr "???LEERER BLOCK"
+
+msgid "???LINES MISSING"
+msgstr "???ZEILEN FEHLEN"
+
+#, c-format
+msgid "E310: Block 1 ID wrong (%s not a .swp file?)"
+msgstr "E310: Block 1 ID falsch (ist %s keine .swp-Datei?)"
+
+msgid "???BLOCK MISSING"
+msgstr "???BLOCK FEHLT"
+
+msgid "??? from here until ???END lines may be messed up"
+msgstr "??? von hier bis ???ENDE könnten die Zeilen falsch sein"
+
+msgid "??? from here until ???END lines may have been inserted/deleted"
+msgstr "??? von hier bis ???ENDE könnten Zeilen eingefügt oder gelöscht sein"
+
+msgid "???END"
+msgstr "???ENDE"
+
+msgid "E311: Recovery Interrupted"
+msgstr "E311: Wiederherstellung unterbrochen"
+
+msgid ""
+"E312: Errors detected while recovering; look for lines starting with ???"
+msgstr ""
+"E312: Fehler wurden festgestellt während der Wiederherstellung: suche nach Zeilen die mit ??? beginnen"
+
+msgid "See \":help E312\" for more information."
+msgstr "Lesen Sie \":help E312\" für weitere Informationen."
+
+msgid "Recovery completed. You should check if everything is OK."
+msgstr "Wiederherstellung beendet. Prüfen Sie, ob alles alles OK ist."
+
+msgid ""
+"\n"
+"(You might want to write out this file under another name\n"
+msgstr ""
+"\n"
+"(Wollen Sie vielleicht diese Datei unter einem neuen Namen speichern\n"
+
+msgid "and run diff with the original file to check for changes)\n"
+msgstr "und \"diff\" zur Original-Datei machen, um Änderungen zu prüfen)\n"
+
+msgid ""
+"Delete the .swp file afterwards.\n"
+"\n"
+msgstr ""
+"Löschen Sie die .swp-Datei danach.\n"
+"\n"
+
+#. use msg() to start the scrolling properly
+msgid "Swap files found:"
+msgstr "Auslagerungsdateien gefunden:"
+
+msgid " In current directory:\n"
+msgstr " Im laufenden Verzeichnis:\n"
+
+msgid " Using specified name:\n"
+msgstr " Benutze gegebenen Namen:\n"
+
+msgid " In directory "
+msgstr " Im Verzeichnis "
+
+msgid " -- none --\n"
+msgstr " -- Nichts --\n"
+
+msgid " owned by: "
+msgstr " Eigentum von: "
+
+msgid " dated: "
+msgstr " vom: "
+
+msgid " dated: "
+msgstr " vom: "
+
+msgid " [from Vim version 3.0]"
+msgstr " [von Vim Version 3.0]"
+
+msgid " [does not look like a Vim swap file]"
+msgstr " [sieht nicht wie eine Vim Auslagerungsdatei aus]"
+
+msgid " file name: "
+msgstr " Dateiname: "
+
+msgid ""
+"\n"
+" modified: "
+msgstr ""
+"\n"
+" verändert: "
+
+msgid "YES"
+msgstr "JA"
+
+msgid "no"
+msgstr "nein"
+
+msgid ""
+"\n"
+" user name: "
+msgstr ""
+"\n"
+" Benutzer-Name: "
+
+msgid " host name: "
+msgstr " Host-Name: "
+
+msgid ""
+"\n"
+" host name: "
+msgstr ""
+"\n"
+" Host-Name: "
+
+msgid ""
+"\n"
+" process ID: "
+msgstr ""
+"\n"
+" Process-ID: "
+
+msgid " (still running)"
+msgstr " (läuft noch)"
+
+msgid ""
+"\n"
+" [not usable with this version of Vim]"
+msgstr ""
+"\n"
+" [nicht verwendbar zusammen mit dieser Vim-Version]"
+
+msgid ""
+"\n"
+" [not usable on this computer]"
+msgstr ""
+"\n"
+" [nicht verwendbar auf diesem Rechner]"
+
+msgid " [cannot be read]"
+msgstr " [kann nicht gelesen werden]"
+
+msgid " [cannot be opened]"
+msgstr " [kann nicht geöffnet werden]"
+
+msgid "E313: Cannot preserve, there is no swap file"
+msgstr "E313: Kann nicht absichern, es gibt keine Auslagerungsdatei"
+
+msgid "File preserved"
+msgstr "Datei gesichert"
+
+msgid "E314: Preserve failed"
+msgstr "E314: Absicherung fehlgeschlagen"
+
+#, c-format
+msgid "E315: ml_get: invalid lnum: %ld"
+msgstr "E315: ml_get: unzulässige lnum: %ld"
+
+#, c-format
+msgid "E316: ml_get: cannot find line %ld"
+msgstr "E316: ml_get: kann Zeile %ld nicht finden"
+
+msgid "E317: pointer block id wrong 3"
+msgstr "E317: Zeiger Block id falsch 3"
+
+msgid "stack_idx should be 0"
+msgstr "stack_idx sollte 0 sein"
+
+msgid "E318: Updated too many blocks?"
+msgstr "E318: Zu viele Blocks aktualisiert?"
+
+msgid "E317: pointer block id wrong 4"
+msgstr "E317: Zeiger Block id falsch 4"
+
+msgid "deleted block 1?"
+msgstr "Block 1 gelöscht?"
+
+#, c-format
+msgid "E320: Cannot find line %ld"
+msgstr "E320: Kann Zeile %ld nicht finden"
+
+msgid "E317: pointer block id wrong"
+msgstr "E317: Zeiger Block id ist falsch"
+
+msgid "pe_line_count is zero"
+msgstr "pe_line_count ist Null"
+
+#, c-format
+msgid "E322: line number out of range: %ld past the end"
+msgstr "E322: Zeilennummer nicht im zulässigen Bereich: %ld nach dem Ende"
+
+#, c-format
+msgid "E323: line count wrong in block %ld"
+msgstr "E323: Zeilen Zähler falsch in Block %ld"
+
+msgid "Stack size increases"
+msgstr "Stapel Größe wächst"
+
+msgid "E317: pointer block id wrong 2"
+msgstr "E317: Zeiger Block id falsch 2"
+
+msgid "E325: ATTENTION"
+msgstr "E325: ACHTUNG"
+
+msgid ""
+"\n"
+"Found a swap file by the name \""
+msgstr ""
+"\n"
+"Auslagerungsdatei mit folgendem Namen gefunden: \""
+
+msgid "While opening file \""
+msgstr "Beim Öffnen der Datei \""
+
+msgid " NEWER than swap file!\n"
+msgstr " neuer als Auslagerungsdatei!\n"
+
+#. Some of these messages are long to allow translation to
+#. * other languages.
+msgid ""
+"\n"
+"(1) Another program may be editing the same file.\n"
+" If this is the case, be careful not to end up with two\n"
+" different instances of the same file when making changes.\n"
+msgstr ""
+"\n"
+"(1) Ein anderes Programm editiert möglicherweise diese Datei.\n"
+" Wenn dies der Fall ist, sollten Sie vorsichtig sein, damit\n"
+" es nicht zu Überschneidungen kommt.\n"
+
+msgid " Quit, or continue with caution.\n"
+msgstr " Ende, oder Fortsetzung mit Vorsicht.\n"
+
+msgid ""
+"\n"
+"(2) An edit session for this file crashed.\n"
+msgstr ""
+"\n"
+"(2) Eine Editiersitzung für diese Datei ist abgestürzt.\n"
+
+msgid " If this is the case, use \":recover\" or \"vim -r "
+msgstr " Wenn dies der Fall ist, so verwenden Sie \":recover\" oder \"vim -r "
+
+msgid ""
+"\"\n"
+" to recover the changes (see \":help recovery\").\n"
+msgstr ""
+"\"\n"
+" um die Änderungen wiederherzustellen (siehe \":help recovery\").\n"
+
+msgid " If you did this already, delete the swap file \""
+msgstr " Wenn dies bereits geschehen ist, löschen Sie die Auslagerungsdatei \""
+
+msgid ""
+"\"\n"
+" to avoid this message.\n"
+msgstr ""
+"\"\n"
+" um diese Nachricht zu vermeiden.\n"
+
+msgid "Swap file \""
+msgstr "Auslagerungsdatei \""
+
+msgid "\" already exists!"
+msgstr "\" ist bereits vorhanden!"
+
+msgid "VIM - ATTENTION"
+msgstr "VIM - ACHTUNG"
+
+msgid "Swap file already exists!"
+msgstr "Auslagerungsdatei ist bereits vorhanden!"
+
+msgid ""
+"&Open Read-Only\n"
+"&Edit anyway\n"
+"&Recover\n"
+"&Quit\n"
+"&Abort"
+msgstr ""
+"Nur zum &Lesen öffnen\n"
+"Trotzdem &editieren\n"
+"&Wiederherstellen\n"
+"&Beenden\n"
+"&Abbrechen"
+
+msgid ""
+"&Open Read-Only\n"
+"&Edit anyway\n"
+"&Recover\n"
+"&Delete it\n"
+"&Quit\n"
+"&Abort"
+msgstr ""
+"Nur zum &Lesen öffnen\n"
+"Trotzdem &editieren\n"
+"&Wiederherstellen\n"
+"&Datei Löschen\n"
+"&Beenden\n"
+"&Abbrechen"
+
+msgid "E326: Too many swap files found"
+msgstr "E326: Zu viele Auslagerungsdateien gefunden"
+
+msgid "E327: Part of menu-item path is not sub-menu"
+msgstr "E327: Teil des Menüpunkt-Pfades muss zum Untermenü führen"
+
+msgid "E328: Menu only exists in another mode"
+msgstr "E328: Menü existiert nur in anderen Modus"
+
+#, c-format
+msgid "E329: No menu \"%s\""
+msgstr "E329: Kein Menü \"%s\""
+
+msgid "E330: Menu path must not lead to a sub-menu"
+msgstr "E330: Menü-Pfad darf nicht zum Untermenü führen"
+
+msgid "E331: Must not add menu items directly to menu bar"
+msgstr "E331: Menüpunkt können nicht direkt zum Menü-Balken hinzugefügt werden"
+
+msgid "E332: Separator cannot be part of a menu path"
+msgstr "E332: Trenner kann nicht Teil des Menü-Pfades sein"
+
+#. Now we have found the matching menu, and we list the mappings
+#. Highlight title
+msgid ""
+"\n"
+"--- Menus ---"
+msgstr ""
+"\n"
+"--- Menüs ---"
+
+msgid "Tear off this menu"
+msgstr "Reiße dieses Menü ab"
+
+msgid "E333: Menu path must lead to a menu item"
+msgstr "E333: Menü-Pfad muss zu einem Menüpunkt führen"
+
+#, c-format
+msgid "E334: Menu not found: %s"
+msgstr "E334: Menü nicht gefunden: %s"
+
+#, c-format
+msgid "E335: Menu not defined for %s mode"
+msgstr "E335: Menü ist für %s Modus nicht definiert"
+
+msgid "E336: Menu path must lead to a sub-menu"
+msgstr "E336: Menü-Pfad muss zum Untermenü führen"
+
+msgid "E337: Menu not found - check menu names"
+msgstr "E337: Menü nicht gefunden - überprüfe Menü-Namen"
+
+#, c-format
+msgid "Error detected while processing %s:"
+msgstr "Fehler beim Ausführen von \"%s\":"
+
+#, c-format
+msgid "line %4ld:"
+msgstr "Zeile %4ld:"
+
+#, c-format
+msgid "E354: Invalid register name: '%s'"
+msgstr "E354: Ungültiger Register Name: '%s'"
+
+msgid "Messages maintainer: Bram Moolenaar <Bram@vim.org>"
+msgstr "Übersetzt von Georg Dahn <gorgyd@yahoo.co.uk>"
+
+msgid "Interrupt: "
+msgstr "Unterbrechung: "
+
+msgid "Hit ENTER or type command to continue"
+msgstr "Drücken Sie die EINGABETASTE oder geben Sie einen Befehl ein"
+
+#, c-format
+msgid "%s line %ld"
+msgstr "%s Zeile %ld"
+
+msgid "-- More --"
+msgstr "-- Mehr --"
+
+msgid " SPACE/d/j: screen/page/line down, b/u/k: up, q: quit "
+msgstr " LEERZEICHEN/d/j: Seite/halbe Seite/Zeile vorwärts, b/u/k: rückwärts, q: Ende "
+
+msgid "Question"
+msgstr "Frage"
+
+msgid ""
+"&Yes\n"
+"&No"
+msgstr ""
+"&Ja\n"
+"&Nein"
+
+msgid ""
+"&Yes\n"
+"&No\n"
+"Save &All\n"
+"&Discard All\n"
+"&Cancel"
+msgstr ""
+"&Ja\n"
+"&Nein\n"
+"Alle &Speichern\n"
+"Alle &Verwerfen\n"
+"&Abbrechen"
+
+msgid "Save File dialog"
+msgstr "Datei Speichern Dialog"
+
+msgid "Open File dialog"
+msgstr "Datei Öffnen Dialog"
+
+#. TODO: non-GUI file selector here
+msgid "E338: Sorry, no file browser in console mode"
+msgstr "E338: Kein Datei-Dialog im Konsole-Modus"
+
+msgid "E766: Insufficient arguments for printf()"
+msgstr "E766: Zu wenige Argumente für printf()"
+
+msgid "E767: Too many arguments to printf()"
+msgstr "E767: Zu viele Argumente für printf()"
+
+msgid "W10: Warning: Changing a readonly file"
+msgstr "W10: Warnung: Ändern einer schreibgeschützten Datei"
+
+msgid "Type number or click with mouse (<Enter> cancels): "
+msgstr "Bitte Nummer eingeben oder mit der Maus auswählen (abbrechen mit <Enter>)"
+
+msgid "Choice number (<Enter> cancels): "
+msgstr "Gewünschte Nummer (abbrechen mit <Enter>)"
+
+msgid "1 more line"
+msgstr "eine Zeile mehr"
+
+msgid "1 line less"
+msgstr "eine Zeile weniger"
+
+#, c-format
+msgid "%ld more lines"
+msgstr "%ld Zeilen mehr"
+
+#, c-format
+msgid "%ld fewer lines"
+msgstr "%ld Zeilen weniger"
+
+msgid " (Interrupted)"
+msgstr " (Unterbrochen)"
+
+msgid "Beep!"
+msgstr "Beep!"
+
+msgid "Vim: preserving files...\n"
+msgstr "Vim: Sichern der Dateien...\n"
+
+#. close all memfiles, without deleting
+msgid "Vim: Finished.\n"
+msgstr "Vim: Beendet.\n"
+
+msgid "ERROR: "
+msgstr "FEHLER: "
+
+#, c-format
+msgid ""
+"\n"
+"[bytes] total alloc-freed %lu-%lu, in use %lu, peak use %lu\n"
+msgstr ""
+"\n"
+"[Bytes] gesamt alloc-frei %lu-%lu, in Verwendung %lu, maximale Verwendung %lu\n"
+
+#, c-format
+msgid ""
+"[calls] total re/malloc()'s %lu, total free()'s %lu\n"
+"\n"
+msgstr ""
+"[Aufrufe] gesamt re/malloc()s %lu, gesamt free()s %lu\n"
+"\n"
+
+msgid "E340: Line is becoming too long"
+msgstr "E340: Zeile wird zu lang"
+
+#, c-format
+msgid "E341: Internal error: lalloc(%ld, )"
+msgstr "E341: Interner Fehler: lalloc(%ld, )"
+
+#, c-format
+msgid "E342: Out of memory! (allocating %lu bytes)"
+msgstr "E342: Kein Speicherplatz mehr vorhanden (%lu Bytes reserviert)"
+
+#, c-format
+msgid "Calling shell to execute: \"%s\""
+msgstr "Rufe Shell auf, um \"%s\" auszuführen"
+
+msgid "E545: Missing colon"
+msgstr "E545: Fehlender Doppelpunkt"
+
+msgid "E546: Illegal mode"
+msgstr "E546: Unzulässiger Modus"
+
+msgid "E547: Illegal mouseshape"
+msgstr "E547: Unzulässiger Mauszeiger"
+
+msgid "E548: digit expected"
+msgstr "E548: Ziffer erwartet"
+
+msgid "E549: Illegal percentage"
+msgstr "E549: Unzulässige Prozentangabe"
+
+msgid "Enter encryption key: "
+msgstr "Geben Sie bitte den Schlüssel ein: "
+
+msgid "Enter same key again: "
+msgstr "Geben Sie den gleichen Schlüssel nochmals ein:"
+
+msgid "Keys don't match!"
+msgstr "Die Schlüssel stimmen nicht überein!"
+
+#, c-format
+msgid ""
+"E343: Invalid path: '**[number]' must be at the end of the path or be "
+"followed by '%s'."
+msgstr ""
+"E343: Ungültiger Pfad: '**[Nummer]' muss am Ende des Pfads sein, oder von "
+"'%s' gefolgt werden. Siehe \":help path\"."
+
+#, c-format
+msgid "E344: Can't find directory \"%s\" in cdpath"
+msgstr "E344: Kann Verzeichnis \"%s\" nicht im 'cdpath' finden"
+
+#, c-format
+msgid "E345: Can't find file \"%s\" in path"
+msgstr "E345: Kann Datei \"%s\" nicht im Pfad finden"
+
+#, c-format
+msgid "E346: No more directory \"%s\" found in cdpath"
+msgstr "E346: Kein weiteres Verzeichnis \"%s\" im 'cdpath' gefunden"
+
+#, c-format
+msgid "E347: No more file \"%s\" found in path"
+msgstr "E347: Keine weitere Datei \"%s\" im Pfad gefunden"
+
+#. Get here when the server can't be found.
+msgid "Cannot connect to Netbeans #2"
+msgstr "Keine Verbindung zu NetBeans #2"
+
+msgid "Cannot connect to Netbeans"
+msgstr "Keine Verbindung zu NetBeans"
+
+#, c-format
+msgid "E668: Wrong access mode for NetBeans connection info file: \"%s\""
+msgstr "E668: Falscher Zugriffsmodus auf die NetBeans Zugriff-Informationsdatei: \"%s\""
+
+msgid "read from Netbeans socket"
+msgstr "gelesen vom NetBeans Socket"
+
+#, c-format
+msgid "E658: NetBeans connection lost for buffer %ld"
+msgstr "E658: Verbindung zu NetBeans für Puffer %ld verloren"
+
+msgid "E505: "
+msgstr "E505: "
+
+msgid "E774: 'operatorfunc' is empty"
+msgstr "E774: 'operatorfunc' is empty"
+
+msgid "E775: Eval feature not available"
+msgstr "E775: Evaluierungsfunktion nicht verfügbar"
+
+msgid "Warning: terminal cannot highlight"
+msgstr "Achtung: Terminal unterstützt keine Hervorhebung"
+
+msgid "E348: No string under cursor"
+msgstr "E348: Keine Zeichenkette unter dem Cursor"
+
+# Identifizierungszeichen/merkmal, Bezeichner
+msgid "E349: No identifier under cursor"
+msgstr "E349: Kein Merkmal unter dem Cursor"
+
+msgid "E352: Cannot erase folds with current 'foldmethod'"
+msgstr "E352: Faltung kann mit der eingestellten Faltungsmethode nicht gelöscht werden"
+
+msgid "E664: changelist is empty"
+msgstr "E664: Liste der Änderungen ist leer"
+
+msgid "E662: At start of changelist"
+msgstr "E662: Am Anfang der Liste der Änderungen"
+
+msgid "E663: At end of changelist"
+msgstr "E663: Am Ende der Liste der Änderungen"
+
+msgid "Type :quit<Enter> to exit Vim"
+msgstr "Bitte :quit<Enter> eingeben um Vim zu verlassen"
+
+#, c-format
+msgid "1 line %sed 1 time"
+msgstr "eine Zeile ein Mal %s"
+
+#, c-format
+msgid "1 line %sed %d times"
+msgstr "eine Zeile %s %d Mal"
+
+#, c-format
+msgid "%ld lines %sed 1 time"
+msgstr "%ld Zeilen %s ein Mal"
+
+#, c-format
+msgid "%ld lines %sed %d times"
+msgstr "%ld Zeilen %s %d Mal"
+
+#, c-format
+msgid "%ld lines to indent... "
+msgstr "%ld Zeilen zum Einrücken... "
+
+msgid "1 line indented "
+msgstr "eine Zeile eingerückt... "
+
+#, c-format
+msgid "%ld lines indented "
+msgstr "%ld Zeilen eingerückt... "
+
+msgid "E748: No previously used register"
+msgstr "E748: Kein bereits verwendetes Register"
+
+#. must display the prompt
+msgid "cannot yank; delete anyway"
+msgstr "kann nicht kopieren; lösche trotzdem"
+
+msgid "1 line changed"
+msgstr "eine Zeile geändert"
+
+#, c-format
+msgid "%ld lines changed"
+msgstr "%ld Zeilen geändert"
+
+#, c-format
+msgid "freeing %ld lines"
+msgstr "gebe %ld Zeilen frei"
+
+msgid "block of 1 line yanked"
+msgstr "Block von einer Zeile kopiert"
+
+msgid "1 line yanked"
+msgstr "eine Zeile kopiert"
+
+#, c-format
+msgid "block of %ld lines yanked"
+msgstr "Block von %ld Zeilen kopiert"
+
+#, c-format
+msgid "%ld lines yanked"
+msgstr "%ld Zeilen kopiert"
+
+#, c-format
+msgid "E353: Nothing in register %s"
+msgstr "E353: Register %s ist leer"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Registers ---"
+msgstr ""
+"\n"
+"--- Register ---"
+
+msgid "Illegal register name"
+msgstr "Unzulässiger Register Name"
+
+msgid ""
+"\n"
+"# Registers:\n"
+msgstr ""
+"\n"
+"# Register:\n"
+
+#, c-format
+msgid "E574: Unknown register type %d"
+msgstr "E574: Unbekannter Register Typ %d"
+
+#, c-format
+msgid "%ld Cols; "
+msgstr "%ld Spalten; "
+
+#, c-format
+msgid "Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Bytes"
+msgstr "%s%ld von %ld Zeilen; %ld von %ld Wörtern; %ld von %ld Bytes"
+
+#, c-format
+msgid ""
+"Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Chars; %ld of %ld "
+"Bytes"
+msgstr ""
+"%s%ld von %ld Zeilen; %ld von %ld Wörtern; %ld von %ld Zeichen; %ld von %ld "
+"Bytes"
+
+#, c-format
+msgid "Col %s of %s; Line %ld of %ld; Word %ld of %ld; Byte %ld of %ld"
+msgstr "Sp %s von %s; Zeile %ld von %ld; Wort %ld von %ld; Byte %ld von %ld"
+
+#, c-format
+msgid ""
+"Col %s of %s; Line %ld of %ld; Word %ld of %ld; Char %ld of %ld; Byte %ld of "
+"%ld"
+msgstr ""
+"Sp %s von %s; Zeile %ld von %ld; Wort %ld von %ld; Zeichen %ld von %ld; Byte %ld von "
+"%ld"
+
+#, c-format
+msgid "(+%ld for BOM)"
+msgstr "(+%ld für BOM)"
+
+msgid "%<%f%h%m%=Page %N"
+msgstr "%<%f%h%m%=Seite %N"
+
+msgid "Thanks for flying Vim"
+msgstr "Danke für die Benutzung von Vim"
+
+msgid "E518: Unknown option"
+msgstr "E518: Unbekannte Option"
+
+msgid "E519: Option not supported"
+msgstr "E519: Option nicht unterstützt"
+
+msgid "E520: Not allowed in a modeline"
+msgstr "E520: Nicht erlaubt in einer Modeline"
+
+msgid "E521: Number required after ="
+msgstr "E521: Zahl benötigt nach ="
+
+msgid "E522: Not found in termcap"
+msgstr "E522: Nicht gefunden in 'termcap'"
+
+#, c-format
+msgid "E539: Illegal character <%s>"
+msgstr "E539: Unzulässiges Zeichen <%s>"
+
+msgid "E529: Cannot set 'term' to empty string"
+msgstr "E529: 'term' darf keine leere Zeichenkette sein"
+
+msgid "E530: Cannot change term in GUI"
+msgstr "E530: Kann Terminal in der GUI nicht verändern"
+
+msgid "E531: Use \":gui\" to start the GUI"
+msgstr "E531: Verwende \":gui\", um die GUI-Version zu starten"
+
+msgid "E589: 'backupext' and 'patchmode' are equal"
+msgstr "E589: 'backupext' und 'patchmode' sind gleich"
+
+msgid "E617: Cannot be changed in the GTK+ 2 GUI"
+msgstr "E617: Kann in der GTK+ 2 GUI nicht verändert werden"
+
+msgid "E524: Missing colon"
+msgstr "E524: Fehlender Doppelpunkt"
+
+msgid "E525: Zero length string"
+msgstr "E525: Zeichenkette der Länge Null"
+
+#, c-format
+msgid "E526: Missing number after <%s>"
+msgstr "E526: Fehlende Zahl nach <%s>"
+
+msgid "E527: Missing comma"
+msgstr "E527: Fehlendes Komma"
+
+msgid "E528: Must specify a ' value"
+msgstr "E528: Ein ' Wert muss angegeben werden"
+
+msgid "E595: contains unprintable or wide character"
+msgstr "E595: Enthält nicht-druckbare oder Multi-Byte Zeichen"
+
+msgid "E596: Invalid font(s)"
+msgstr "E596: Ungültige Schriftart(en)"
+
+msgid "E597: can't select fontset"
+msgstr "E597: Kann \"Fontset\" nicht auswählen"
+
+msgid "E598: Invalid fontset"
+msgstr "E598: Ungültiges \"Fontset\""
+
+msgid "E533: can't select wide font"
+msgstr "E533: Kann Breitschrift nicht auswählen"
+
+msgid "E534: Invalid wide font"
+msgstr "E534: Ungültige Breitschrift"
+
+#, c-format
+msgid "E535: Illegal character after <%c>"
+msgstr "E535: Ungültiges Zeichen nach <%c>"
+
+msgid "E536: comma required"
+msgstr "E536: Komma benötigt"
+
+#, c-format
+msgid "E537: 'commentstring' must be empty or contain %s"
+msgstr "E537: 'commentstring' muss leer sein oder %s enthalten"
+
+msgid "E538: No mouse support"
+msgstr "E538: Keine Maus-Unterstützung"
+
+msgid "E540: Unclosed expression sequence"
+msgstr "E540: Nicht-geschlossene Ausdrucksfolge"
+
+msgid "E541: too many items"
+msgstr "E541: Zu viele Elemente"
+
+msgid "E542: unbalanced groups"
+msgstr "E542: Unausgewogene Gruppen"
+
+msgid "E590: A preview window already exists"
+msgstr "E590: Ein Voransichtsfenster existiert bereits"
+
+msgid "W17: Arabic requires UTF-8, do ':set encoding=utf-8'"
+msgstr "W17: Arabisch benötigt UTF-8, bitte ':set encoding=utf-8' ausführen"
+
+#, c-format
+msgid "E593: Need at least %d lines"
+msgstr "E593: Mindestens %d Zeilen werden benötigt"
+
+#, c-format
+msgid "E594: Need at least %d columns"
+msgstr "E594: Mindestens %d Spalten werden benötigt"
+
+#, c-format
+msgid "E355: Unknown option: %s"
+msgstr "E355: Unbekannte Option: %s"
+
+msgid ""
+"\n"
+"--- Terminal codes ---"
+msgstr ""
+"\n"
+"--- Terminal Codes ---"
+
+msgid ""
+"\n"
+"--- Global option values ---"
+msgstr ""
+"\n"
+"--- Werte globaler Optionen ---"
+
+msgid ""
+"\n"
+"--- Local option values ---"
+msgstr ""
+"\n"
+"--- Werte lokaler Optionen ---"
+
+msgid ""
+"\n"
+"--- Options ---"
+msgstr ""
+"\n"
+"--- Optionen ---"
+
+msgid "E356: get_varp ERROR"
+msgstr "E356: get_varp FEHLER"
+
+#, c-format
+msgid "E357: 'langmap': Matching character missing for %s"
+msgstr "E357: 'langmap': Passendes Zeichen fehlt für %s"
+
+#, c-format
+msgid "E358: 'langmap': Extra characters after semicolon: %s"
+msgstr "E358: 'langmap': Überschüssige Zeichen nach dem Semikolon: %s"
+
+msgid "cannot open "
+msgstr "kann nicht öffnen"
+
+msgid "VIM: Can't open window!\n"
+msgstr "VIM: Fenster kann nicht geöffnet werden!\n"
+
+msgid "Need Amigados version 2.04 or later\n"
+msgstr "Brauche Amigados Version 2.04 oder neuere\n"
+
+#, c-format
+msgid "Need %s version %ld\n"
+msgstr "Benötige %s Version %ld\n"
+
+msgid "Cannot open NIL:\n"
+msgstr "Kann NIL nicht öffnen:\n"
+
+msgid "Cannot create "
+msgstr "Kann nicht anlegen "
+
+#, c-format
+msgid "Vim exiting with %d\n"
+msgstr "Vim steigt aus mit %d\n"
+
+msgid "cannot change console mode ?!\n"
+msgstr "kann Konsolenmodus nicht wechseln ?!\n"
+
+msgid "mch_get_shellsize: not a console??\n"
+msgstr "mch_get_winsize: keine Konsole??\n"
+
+#. if Vim opened a window: Executing a shell may cause crashes
+msgid "E360: Cannot execute shell with -f option"
+msgstr "E360: Kann Shell nicht mit der -f Option ausführen"
+
+msgid "Cannot execute "
+msgstr "Kann nicht ausführen "
+
+msgid "shell "
+msgstr "Shell "
+
+msgid " returned\n"
+msgstr " zurückgegeben\n"
+
+msgid "ANCHOR_BUF_SIZE too small."
+msgstr "ANCHOR_BUF_SIZE zu klein."
+
+msgid "I/O ERROR"
+msgstr "I/O FEHLER"
+
+msgid "...(truncated)"
+msgstr "...(abgeschnitten)"
+
+msgid "Message"
+msgstr "Nachricht"
+
+msgid "'columns' is not 80, cannot execute external commands"
+msgstr "'columns' beträgt nicht 80, kann externe Befehle nicht ausführen"
+
+msgid "E237: Printer selection failed"
+msgstr "E237: Drucker-Auswahl fehlgeschlagen"
+
+#, c-format
+msgid "to %s on %s"
+msgstr "nach %s auf %s"
+
+#, c-format
+msgid "E613: Unknown printer font: %s"
+msgstr "E613: Unbekannte Druckerschriftart: %s"
+
+#, c-format
+msgid "E238: Print error: %s"
+msgstr "E238: Fehler beim Drucken: %s"
+
+#, c-format
+msgid "Printing '%s'"
+msgstr "Drucke '%s'"
+
+#, c-format
+msgid "E244: Illegal charset name \"%s\" in font name \"%s\""
+msgstr "E244: Unzulässiger Zeichensatz-Name \"%s\" im Schriftart-Namen \"%s\""
+
+#, c-format
+msgid "E245: Illegal char '%c' in font name \"%s\""
+msgstr "E245: Unzulässiges Zeichen '%c' in der Schriftart \"%s\""
+
+msgid "Vim: Double signal, exiting\n"
+msgstr "Vim: Doppel-Signal, beenden\n"
+
+#, c-format
+msgid "Vim: Caught deadly signal %s\n"
+msgstr "Vim: Erhielt tödliches Signal %s\n"
+
+msgid "Vim: Caught deadly signal\n"
+msgstr "Vim: Erhielt tödliches Signal\n"
+
+#, c-format
+msgid "Opening the X display took %ld msec"
+msgstr "Öffnen des X-Displays dauerte %ld msec"
+
+msgid ""
+"\n"
+"Vim: Got X error\n"
+msgstr ""
+"\n"
+"Vim: ein X11 Fehler trat auf\n"
+
+msgid "Testing the X display failed"
+msgstr "Test des X-Displays schlug fehl"
+
+msgid "Opening the X display timed out"
+msgstr "Zeitüberschreitung während des Öffnens des X-Displays"
+
+msgid ""
+"\n"
+"Cannot execute shell "
+msgstr ""
+"\n"
+"Shell kann nicht ausführt werden "
+
+msgid ""
+"\n"
+"Cannot execute shell sh\n"
+msgstr ""
+"\n"
+"Shell sh kann nicht ausführt werden\n"
+
+msgid ""
+"\n"
+"shell returned "
+msgstr ""
+"\n"
+"Shell beendet "
+
+msgid ""
+"\n"
+"Cannot create pipes\n"
+msgstr ""
+"\n"
+"Pipes können nicht angelegt werden\n"
+
+msgid ""
+"\n"
+"Cannot fork\n"
+msgstr ""
+"\n"
+"'fork' schlug fehl\n"
+
+msgid ""
+"\n"
+"Command terminated\n"
+msgstr ""
+"\n"
+"Befehl beendet\n"
+
+msgid "XSMP lost ICE connection"
+msgstr "XSMP verlor ICE Verbindung"
+
+#, c-format
+msgid "dlerror = \"%s\""
+msgstr "dlerror = \"%s\""
+
+msgid "Opening the X display failed"
+msgstr "Öffnen des X-Displays schlug fehl"
+
+msgid "XSMP handling save-yourself request"
+msgstr "XSMP verarbeitet 'save-yourself request'"
+
+msgid "XSMP opening connection"
+msgstr "XSMP öffnet Verbindung"
+
+msgid "XSMP ICE connection watch failed"
+msgstr "XSMP ICE Verbindungsüberwachung fehlgeschlagen"
+
+#, c-format
+msgid "XSMP SmcOpenConnection failed: %s"
+msgstr "XSMP SmcOpenConnection fehlgeschlagen: %s"
+
+msgid "At line"
+msgstr "In Zeile"
+
+msgid "Could not load vim32.dll!"
+msgstr "Konnte vim32.dll nicht laden!"
+
+msgid "VIM Error"
+msgstr "VIM Fehler"
+
+msgid "Could not fix up function pointers to the DLL!"
+msgstr "Konnte Funktions-Zeiger in der DLL nicht korrigieren!"
+
+#, c-format
+msgid "shell returned %d"
+msgstr "Shell gab %d zurück"
+
+#, c-format
+msgid "Vim: Caught %s event\n"
+msgstr "Vim: Fing Ereignis %s ein\n"
+
+msgid "close"
+msgstr "schließe"
+
+msgid "logoff"
+msgstr "ausloggen"
+
+msgid "shutdown"
+msgstr "beenden"
+
+msgid "E371: Command not found"
+msgstr "E371: Befehl nicht gefunden"
+
+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 wurde im Pfad $PATH nicht gefunden.\n"
+"Externe Befehle werden nach Ausführung nicht anhalten.\n"
+"Siehe :help win32-vimrun für weitere Informationen."
+
+msgid "Vim Warning"
+msgstr "Vim Warnung"
+
+#, c-format
+msgid "E372: Too many %%%c in format string"
+msgstr "E372: Zu viele %%%c im Format"
+
+#, c-format
+msgid "E373: Unexpected %%%c in format string"
+msgstr "E373: Unerwartetes %%%c im Format"
+
+msgid "E374: Missing ] in format string"
+msgstr "E374: Fehlende ] im Format"
+
+#, c-format
+msgid "E375: Unsupported %%%c in format string"
+msgstr "E375: %%%c wird im Format nicht unterstützt"
+
+#, c-format
+msgid "E376: Invalid %%%c in format string prefix"
+msgstr "E376: Unzulässiges %%%c im Prefix des Formats"
+
+#, c-format
+msgid "E377: Invalid %%%c in format string"
+msgstr "E377: Unzulässiges %%%c im Format"
+
+msgid "E378: 'errorformat' contains no pattern"
+msgstr "E378: 'errorformat' enthält kein Muster"
+
+msgid "E379: Missing or empty directory name"
+msgstr "E379: Fehlender oder leerer Verzeichnisname"
+
+msgid "E553: No more items"
+msgstr "E553: Keine weiteren Einträge"
+
+#, c-format
+msgid "(%d of %d)%s%s: "
+msgstr "(%d aus %d)%s%s: "
+
+msgid " (line deleted)"
+msgstr " (Zeile gelöscht)"
+
+msgid "E380: At bottom of quickfix stack"
+msgstr "E380: Am Anfang der quickfix Liste"
+
+msgid "E381: At top of quickfix stack"
+msgstr "E381: An Ende der quickfix Liste"
+
+#, c-format
+msgid "error list %d of %d; %d errors"
+msgstr "Fehlerliste %d aus %d; %d Fehler"
+
+msgid "E382: Cannot write, 'buftype' option is set"
+msgstr "E382: Kann nicht schreiben, 'buftype'-Option ist gesetzt"
+
+msgid "E683: File name missing or invalid pattern"
+msgstr "E683: Dateiname fehlt oder ungültiges Muster"
+
+#, c-format
+msgid "Cannot open file \"%s\""
+msgstr "Kann Datei \"%s\" nicht öffnen"
+
+msgid "E681: Buffer is not loaded"
+msgstr "E681: Buffer ist nicht geladen"
+
+msgid "E777: String or List expected"
+msgstr "E777: Zeichenkette oder Liste erwartet"
+
+#, c-format
+msgid "E369: invalid item in %s%%[]"
+msgstr "E369: Ungültiges Element in %s%%[]"
+
+msgid "E339: Pattern too long"
+msgstr "E339: Muster zu lang"
+
+msgid "E50: Too many \\z("
+msgstr "E50: Zu viele \\z("
+
+#, c-format
+msgid "E51: Too many %s("
+msgstr "E51: Zu viele %s("
+
+msgid "E52: Unmatched \\z("
+msgstr "E52: \\z( ohne Gegenstück"
+
+#, c-format
+msgid "E53: Unmatched %s%%("
+msgstr "E53: %s%%( ohne Gegenstück"
+
+#, c-format
+msgid "E54: Unmatched %s("
+msgstr "E54: %s( ohne Gegenstück"
+
+#, c-format
+msgid "E55: Unmatched %s)"
+msgstr "E55: %s) ohne Gegenstück"
+
+#, c-format
+msgid "E59: invalid character after %s@"
+msgstr "E59: Ungültiges Zeichen nach %s@"
+
+#, c-format
+msgid "E60: Too many complex %s{...}s"
+msgstr "E60: Zu viele komplexe %s{...}s"
+
+#, c-format
+msgid "E61: Nested %s*"
+msgstr "E61: Verschachteltes %s*"
+
+#, c-format
+msgid "E62: Nested %s%c"
+msgstr "E62: Verschachteltes %s%c"
+
+msgid "E63: invalid use of \\_"
+msgstr "E63: Ungültige Verwendung von \\_"
+
+#, c-format
+msgid "E64: %s%c follows nothing"
+msgstr "E64: %s%c nach Nichts"
+
+msgid "E65: Illegal back reference"
+msgstr "E65: Ungültige Rückreferenz"
+
+msgid "E66: \\z( not allowed here"
+msgstr "E66: \\z( ist hier nicht erlaubt"
+
+msgid "E67: \\z1 et al. not allowed here"
+msgstr "E67: \\z1 usw. ist hier nicht erlaubt"
+
+msgid "E68: Invalid character after \\z"
+msgstr "E68: Ungültiges Zeichen nach \\z"
+
+#, c-format
+msgid "E69: Missing ] after %s%%["
+msgstr "E69: Fehlende ] nach %s%%["
+
+#, c-format
+msgid "E70: Empty %s%%[]"
+msgstr "E70: %s%%[] ist leer"
+
+#, c-format
+msgid "E678: Invalid character after %s%%[dxouU]"
+msgstr "E678: Ungültiges Zeichen nach %s%%[dxouU]"
+
+#, c-format
+msgid "E71: Invalid character after %s%%"
+msgstr "E71: Ungültiges Zeichen nach %s%%"
+
+#, c-format
+msgid "E769: Missing ] after %s["
+msgstr "E769: Fehlende ] nach %s["
+
+#, c-format
+msgid "E554: Syntax error in %s{...}"
+msgstr "E554: Syntaxfehler in %s{...}"
+
+msgid "External submatches:\n"
+msgstr "Externe 'submatches':\n"
+
+msgid " VREPLACE"
+msgstr " V-ERSETZEN"
+
+msgid " REPLACE"
+msgstr " ERSETZEN"
+
+msgid " REVERSE"
+msgstr " INVERTIERT"
+
+msgid " INSERT"
+msgstr " EINFÜGEN"
+
+msgid " (insert)"
+msgstr " (einfügen)"
+
+msgid " (replace)"
+msgstr " (ersetzen)"
+
+msgid " (vreplace)"
+msgstr " (v-ersetzen)"
+
+msgid " Hebrew"
+msgstr " Hebräisch"
+
+msgid " Arabic"
+msgstr " Arabisch"
+
+msgid " (lang)"
+msgstr " (Sprache)"
+
+msgid " (paste)"
+msgstr " (paste)"
+
+msgid " VISUAL"
+msgstr " VISUELL"
+
+msgid " VISUAL LINE"
+msgstr " VISUELL ZEILE"
+
+msgid " VISUAL BLOCK"
+msgstr " VISUELL BLOCK"
+
+msgid " SELECT"
+msgstr " AUSWAHL"
+
+msgid " SELECT LINE"
+msgstr " AUSWAHL ZEILE"
+
+msgid " SELECT BLOCK"
+msgstr " AUSWAHL BLOCK"
+
+msgid "recording"
+msgstr "aufzeichnen"
+
+#, c-format
+msgid "E383: Invalid search string: %s"
+msgstr "E383: Unzulässiges Suchmuster: %s"
+
+#, c-format
+msgid "E384: search hit TOP without match for: %s"
+msgstr "E384: Suche erreichte den ANFANG ohne Treffer für: %s"
+
+#, c-format
+msgid "E385: search hit BOTTOM without match for: %s"
+msgstr "E385: Suche erreichte das ENDE ohne Treffer für: %s"
+
+msgid "E386: Expected '?' or '/' after ';'"
+msgstr "E386: Erwarte '?' oder '/' nach ';'"
+
+msgid " (includes previously listed match)"
+msgstr " (enthält bereits vorher aufgezählte Treffer)"
+
+#. cursor at status line
+msgid "--- Included files "
+msgstr "--- Eingefügte Dateien "
+
+msgid "not found "
+msgstr "nicht gefunden "
+
+msgid "in path ---\n"
+msgstr "im Pfad ---\n"
+
+msgid " (Already listed)"
+msgstr " (Bereits aufgelistet)"
+
+msgid " NOT FOUND"
+msgstr " NICHT GEFUNDEN"
+
+#, c-format
+msgid "Scanning included file: %s"
+msgstr "Durchsuche inkludierte Datei: %s"
+
+#, c-format
+msgid "Searching included file %s"
+msgstr "Suche inkludierte Datei %s"
+
+msgid "E387: Match is on current line"
+msgstr "E387: Treffer ist auf der momentanen Zeile"
+
+msgid "All included files were found"
+msgstr "Alle inkludierten Dateien wurden gefunden"
+
+msgid "No included files"
+msgstr "Keine inkludierten Dateien"
+
+msgid "E388: Couldn't find definition"
+msgstr "E388: Konnte Definition nicht finden"
+
+msgid "E389: Couldn't find pattern"
+msgstr "E389: Konnte Muster nicht finden"
+
+msgid "E759: Format error in spell file"
+msgstr "E759: Format-Fehler im Rechtschreibwörterbuch"
+
+msgid "E758: Truncated spell file"
+msgstr "E758: Abgeschnittenes Rechtschreibwörterbuch"
+
+#, c-format
+msgid "Trailing text in %s line %d: %s"
+msgstr "Angehängter Text in %s Zeile %d: %s"
+
+#, c-format
+msgid "Affix name too long in %s line %d: %s"
+msgstr "Affix Name zu lang in %s Zeile %d: %s"
+
+msgid "E761: Format error in affix file FOL, LOW or UPP"
+msgstr "E761: Format-Fehler in Affix-Datei FOL, LOW oder UPP"
+
+msgid "E762: Character in FOL, LOW or UPP is out of range"
+msgstr "E762: Zeichen in FOL, LOW oder UPP außerhalb des zulässigen Bereichs"
+
+msgid "Compressing word tree..."
+msgstr "Komprimiere Wörter-Baum..."
+
+msgid "E756: Spell checking is not enabled"
+msgstr "E756: Rechtschreibprüfung ist nicht aktiviert"
+
+#, c-format
+msgid "Warning: Cannot find word list \"%s.%s.spl\" or \"%s.ascii.spl\""
+msgstr "Achtung: Kann Wortliste \"%s.%s.spl\" oder \"%s.ascii.spl\" nicht finden"
+
+#, c-format
+msgid "Reading spell file \"%s\""
+msgstr "Lese Rechtschreibwörterbuch \"%s\" ein"
+
+msgid "E757: This does not look like a spell file"
+msgstr "E757: Das sieht nicht nach einem Rechtschreibwörterbuch aus"
+
+msgid "E771: Old spell file, needs to be updated"
+msgstr "E771: Altes Rechtschreibwörterbuch, benötigt Aktualisierung"
+
+msgid "E772: Spell file is for newer version of Vim"
+msgstr "E772: Rechtschreibwörterbuch ist für eine neuere Version von Vim"
+
+msgid "E770: Unsupported section in spell file"
+msgstr "E770: Nicht unterstützter Abschnitt im Rechtschreibwörterbuch"
+
+#, c-format
+msgid "Warning: region %s not supported"
+msgstr "Achtung: Region %s nicht unterstützt"
+
+#, c-format
+msgid "Reading affix file %s ..."
+msgstr "Lese Affix-Datei %s ..."
+
+#, c-format
+msgid "Conversion failure for word in %s line %d: %s"
+msgstr "Umwandlungsfehler beim Wort in %s Zeile %d: %s"
+
+#, c-format
+msgid "Conversion in %s not supported: from %s to %s"
+msgstr "Umwandlung in %s nicht unterstützt: von %s nach %s"
+
+#, c-format
+msgid "Conversion in %s not supported"
+msgstr "Umwandlung in %s nicht unterstützt"
+
+#, c-format
+msgid "Invalid value for FLAG in %s line %d: %s"
+msgstr "Ungültiger Wert von FLAG in %s Zeile %d: %s"
+
+#, c-format
+msgid "FLAG after using flags in %s line %d: %s"
+msgstr "FLAG nach dem Gebrauch von Flags in %s Zeile %d: %s"
+
+#, c-format
+msgid "Wrong COMPOUNDWORDMAX value in %s line %d: %s"
+msgstr "Falscher COMPOUNDWORDMAX-Wert in %s Zeile %d: %s"
+
+#, c-format
+msgid "Wrong COMPOUNDMIN value in %s line %d: %s"
+msgstr "Falscher COMPOUNDMIN-Wert in %s Zeile %d: %s"
+
+#, c-format
+msgid "Wrong COMPOUNDSYLMAX value in %s line %d: %s"
+msgstr "Falscher COMPOUNDSYLMAX-Wert in %s Zeile %d: %s"
+
+#, c-format
+msgid "Wrong CHECKCOMPOUNDPATTERN value in %s line %d: %s"
+msgstr "Falscher CHECKCOMPOUNDPATTERN-Wert in %s Zeile %d: %s"
+
+#, c-format
+msgid "Different combining flag in continued affix block in %s line %d: %s"
+msgstr "Unterschiedliches verknüpfendes Flag im fortgesetzten Affix-Block in %s Zeile %d: %s"
+
+#, c-format
+msgid "Duplicate affix in %s line %d: %s"
+msgstr "Doppeltes Affix in %s Zeile %d: %s"
+
+#, c-format
+msgid ""
+"Affix also used for BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST in %s "
+"line %d: %s"
+msgstr ""
+"Affix wird auch für BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST verwendet in %s "
+"Zeile %d: %s"
+
+#, c-format
+msgid "Expected Y or N in %s line %d: %s"
+msgstr "Y oder N erwartet in %s Zeile %d: %s"
+
+#, c-format
+msgid "Broken condition in %s line %d: %s"
+msgstr "Bedingung verletzt in %s Zeile %d: %s"
+
+#, c-format
+msgid "Affix flags ignored when PFXPOSTPONE used in %s line %d: %s"
+msgstr "Affix Flags ignoriert, wenn PFXPOSTPONE verwendet wird in %s Zeile %d: %s"
+
+#, c-format
+msgid "Expected REP(SAL) count in %s line %d"
+msgstr "Erwartetes REP(SAL) gezählt in %s Zeile %d"
+
+#, c-format
+msgid "Expected MAP count in %s line %d"
+msgstr "Erwartetes MAP gezählt in %s Zeile %d"
+
+#, c-format
+msgid "Duplicate character in MAP in %s line %d"
+msgstr "Doppeltes Zeichen in MAP in %s Zeile %d"
+
+#, c-format
+msgid "Unrecognized or duplicate item in %s line %d: %s"
+msgstr "Nicht erkanntes oder doppeltes Element in %s Zeile %d: %s"
+
+#, c-format
+msgid "Missing FOL/LOW/UPP line in %s"
+msgstr "Fehlende FOL/LOW/UPP Zeile in %s"
+
+msgid "COMPOUNDSYLMAX used without SYLLABLE"
+msgstr "COMPOUNDSYLMAX ohne SYLLABLE verwendet"
+
+msgid "Too many postponed prefixes"
+msgstr "Zu viele zurück gestellte Präfixe"
+
+msgid "Too many compound flags"
+msgstr "Zu viele zusammengesetzte Flags"
+
+msgid "Too many postponed prefixes and/or compound flags"
+msgstr "Zu viele zurück gestellte Präfixe und/oder zusammengesetzte Flags"
+
+#, c-format
+msgid "Missing SOFO%s line in %s"
+msgstr "Fehlende SOFO%s Zeile in %s"
+
+#, c-format
+msgid "Both SAL and SOFO lines in %s"
+msgstr "Sowohl SAL als auch SOFO Zeilen in %s"
+
+#, c-format
+msgid "Flag is not a number in %s line %d: %s"
+msgstr "Flag ist keine Zahl in %s Zeile %d: %s"
+
+#, c-format
+msgid "Illegal flag in %s line %d: %s"
+msgstr "Unerlaubtes Flag in %s Zeile %d: %s"
+
+#, c-format
+msgid "%s value differs from what is used in another .aff file"
+msgstr "%s Wert unterscheidet sich von dem, was in einer anderen .aff Datei verwendet wird"
+
+#, c-format
+msgid "Reading dictionary file %s ..."
+msgstr "Lese Wörterbuch-Datei %s ..."
+
+#, c-format
+msgid "E760: No word count in %s"
+msgstr "E760: Keine Wörter gezählt in %s"
+
+#, c-format
+msgid "line %6d, word %6d - %s"
+msgstr "Zeile %6d, Wort %6d - %s"
+
+#, c-format
+msgid "Duplicate word in %s line %d: %s"
+msgstr "Doppeltes Wort in %s Zeile %d: %s"
+
+#, c-format
+msgid "First duplicate word in %s line %d: %s"
+msgstr "Erstes doppeltes Wort in %s Zeile %d: %s"
+
+#, c-format
+msgid "%d duplicate word(s) in %s"
+msgstr "%d doppelte(s) Wort(e) in %s"
+
+#, c-format
+msgid "Ignored %d word(s) with non-ASCII characters in %s"
+msgstr "%d Wort(e) mit nicht-ASCII Zeichen ignoriert in %s"
+
+#, c-format
+msgid "Reading word file %s ..."
+msgstr "Lese Wort-Datei %s ..."
+
+#, c-format
+msgid "Duplicate /encoding= line ignored in %s line %d: %s"
+msgstr "Doppelte /encoding= Zeile ignoriert in %s Zeile %d: %s"
+
+#, c-format
+msgid "/encoding= line after word ignored in %s line %d: %s"
+msgstr "/encoding= Zeile nach Wort ignoriert in %s Zeile %d: %s"
+
+#, c-format
+msgid "Duplicate /regions= line ignored in %s line %d: %s"
+msgstr "Doppelte /regions= Zeile ignoriert in %s Zeile %d: %s"
+
+#, c-format
+msgid "Too many regions in %s line %d: %s"
+msgstr "Zu viele Regionen in %s Zeile %d: %s"
+
+#, c-format
+msgid "/ line ignored in %s line %d: %s"
+msgstr "/ Zeile ignoriert in %s Zeile %d: %s"
+
+#, c-format
+msgid "Invalid region nr in %s line %d: %s"
+msgstr "Ungültige Regionsnummer in %s Zeile %d: %s"
+
+#, c-format
+msgid "Unrecognized flags in %s line %d: %s"
+msgstr "Nicht erkanntes Flag in %s Zeile %d: %s"
+
+#, c-format
+msgid "Ignored %d words with non-ASCII characters"
+msgstr "%d Wörter mit nicht-ASCII Zeichen ignoriert"
+
+#, c-format
+msgid "Compressed %d of %d nodes; %d (%d%%) remaining"
+msgstr "%d von %d Knoten komprimiert; %d (%d%%) übrig"
+
+msgid "Reading back spell file..."
+msgstr "Lese Rechtschreibwörterbuch zurück..."
+
+#.
+#. * Go through the trie of good words, soundfold each word and add it to
+#. * the soundfold trie.
+#.
+msgid "Performing soundfolding..."
+msgstr "Führe 'Soundfolding' durch..."
+
+#, c-format
+msgid "Number of words after soundfolding: %ld"
+msgstr "Anzahl der Wörter nach 'Soundfolding': %ld"
+
+#, c-format
+msgid "Total number of words: %d"
+msgstr "Gesamte Anzahl von Wörtern: %d"
+
+#, c-format
+msgid "Writing suggestion file %s ..."
+msgstr "Schreibe Datei %s für Vorschläge ..."
+
+#, c-format
+msgid "Estimated runtime memory use: %d bytes"
+msgstr "Geschätzter Speicher zur Laufzeit: %d Bytes"
+
+msgid "E751: Output file name must not have region name"
+msgstr "E751: Ausgabedatei darf keinen Regionsnamen haben"
+
+msgid "E754: Only up to 8 regions supported"
+msgstr "E754: Maximal 8 Regionen unterstützt"
+
+#, c-format
+msgid "E755: Invalid region in %s"
+msgstr "E755: Ungültige Region in %s"
+
+msgid "Warning: both compounding and NOBREAK specified"
+msgstr "Achtung: Sowohl zusammengesetzte Wörter als auch NOBREAK angegeben"
+
+#, c-format
+msgid "Writing spell file %s ..."
+msgstr "Schreibe Rechtschreibwörterbuch %s ..."
+
+msgid "Done!"
+msgstr "Fertig!"
+
+#, c-format
+msgid "E765: 'spellfile' does not have %ld entries"
+msgstr "E765: 'spellfile' hat nicht %ld Einträge"
+
+#, c-format
+msgid "Word removed from %s"
+msgstr "Wort entfernt von %s"
+
+#, c-format
+msgid "Word added to %s"
+msgstr "Wort zu %s hinzugefügt"
+
+msgid "E763: Word characters differ between spell files"
+msgstr "E763: 'Word Characters' unterscheiden sich zwischen Rechtschreibwörterbüchern"
+
+msgid "Sorry, no suggestions"
+msgstr "Leider keine Vorschläge"
+
+#, c-format
+msgid "Sorry, only %ld suggestions"
+msgstr "Leider nur %ld Vorschläge"
+
+#. avoid more prompt
+#, c-format
+msgid "Change \"%.*s\" to:"
+msgstr "Ändere \"%.*s\" nach:"
+
+#, c-format
+msgid " < \"%.*s\""
+msgstr " < \"%.*s\""
+
+msgid "E752: No previous spell replacement"
+msgstr "E752: Keine vorhergehende Ersetzung"
+
+#, c-format
+msgid "E753: Not found: %s"
+msgstr "E753: Nicht gefunden: %s"
+
+#, c-format
+msgid "E778: This does not look like a .sug file: %s"
+msgstr "E778: Das sieht nicht nach einer .sug Datei aus: %s"
+
+#, c-format
+msgid "E779: Old .sug file, needs to be updated: %s"
+msgstr "E779: Veraltete .sug Datei; Aktualisierung erforderlich: %s"
+
+#, c-format
+msgid "E780: .sug file is for newer version of Vim: %s"
+msgstr "E780: .sug Datei ist für eine neuere Version von Vim: %s"
+
+#, c-format
+msgid "E781: .sug file doesn't match .spl file: %s"
+msgstr "E781: .sug Datei passt nicht zur .spl Datei: %s"
+
+#, c-format
+msgid "E782: error while reading .sug file: %s"
+msgstr "E782: Fehler beim Lesen der .sug Datei: %s"
+
+#. This should have been checked when generating the .spl
+#. * file.
+msgid "E783: duplicate char in MAP entry"
+msgstr "E783: Doppeltes Zeichen im MAP Eintrag"
+
+#, c-format
+msgid "E390: Illegal argument: %s"
+msgstr "E390: Unerlaubtes Argument: %s"
+
+#, c-format
+msgid "E391: No such syntax cluster: %s"
+msgstr "E391: Kein solcher Syntax Cluster: %s"
+
+msgid "No Syntax items defined for this buffer"
+msgstr "Keine Syntax-Elemente für diesen Puffer definiert"
+
+msgid "syncing on C-style comments"
+msgstr "Synchronisation an C-Stil Kommentaren"
+
+msgid "no syncing"
+msgstr "keine Synchronisation"
+
+msgid "syncing starts "
+msgstr "Synchronisation beginnt "
+
+msgid " lines before top line"
+msgstr " Zeilen vor der obersten Zeile"
+
+msgid ""
+"\n"
+"--- Syntax sync items ---"
+msgstr ""
+"\n"
+"--- Syntax Synchronisations-Elemente ---"
+
+msgid ""
+"\n"
+"syncing on items"
+msgstr ""
+"\n"
+"Synchronisation an Elementen"
+
+msgid ""
+"\n"
+"--- Syntax items ---"
+msgstr ""
+"\n"
+"--- Syntax-Elemente ---"
+
+#, c-format
+msgid "E392: No such syntax cluster: %s"
+msgstr "E392: Kein solcher Syntax-Cluster: %s"
+
+msgid "minimal "
+msgstr "minimal "
+
+msgid "maximal "
+msgstr "maximal "
+
+msgid "; match "
+msgstr "; Treffer "
+
+msgid " line breaks"
+msgstr " Zeilenumbrüche"
+
+msgid "E393: group[t]here not accepted here"
+msgstr "E393: \"group[t]here\" ist an dieser Stelle ungültig"
+
+#, c-format
+msgid "E394: Didn't find region item for %s"
+msgstr "E394: Konnte kein \"region\"-Element für \"%s\" finden"
+
+msgid "E395: contains argument not accepted here"
+msgstr "E395: \"contains\"-Argument ist an dieser Stelle ungültig"
+
+msgid "E396: containedin argument not accepted here"
+msgstr "E396: \"containedin\"-Argument ist an dieser Stelle ungültig"
+
+msgid "E397: Filename required"
+msgstr "E397: Dateiname wird benötigt"
+
+#, c-format
+msgid "E789: Missing ']': %s"
+msgstr "E789: Fehlende ']': %s"
+
+#, c-format
+msgid "E398: Missing '=': %s"
+msgstr "E398: Fehlendes '=': %s"
+
+#, c-format
+msgid "E399: Not enough arguments: syntax region %s"
+msgstr "E399: Nicht ausreichend viele Argumente: syntax region %s"
+
+msgid "E400: No cluster specified"
+msgstr "E400: Kein Cluster angegeben"
+
+#, c-format
+msgid "E401: Pattern delimiter not found: %s"
+msgstr "E401: Muster-Abgrenzer nicht gefunden: %s"
+
+#, c-format
+msgid "E402: Garbage after pattern: %s"
+msgstr "E402: Schrott nach Muster: %s"
+
+msgid "E403: syntax sync: line continuations pattern specified twice"
+msgstr "E403: Syntax sync: Zeilen-Fortsetzungsmuster zweifach angegeben"
+
+#, c-format
+msgid "E404: Illegal arguments: %s"
+msgstr "E404: Unzulässige Argumente; %s"
+
+#, c-format
+msgid "E405: Missing equal sign: %s"
+msgstr "E405: Gleichheitszeichen fehlt: %s"
+
+#, c-format
+msgid "E406: Empty argument: %s"
+msgstr "E406: Leeres Argument: %s"
+
+#, c-format
+msgid "E407: %s not allowed here"
+msgstr "E407: %s ist hier nicht erlaubt"
+
+#, c-format
+msgid "E408: %s must be first in contains list"
+msgstr "E408: %s muss als Erstes in der Liste der enthaltenen Elemente auftreten"
+
+#, c-format
+msgid "E409: Unknown group name: %s"
+msgstr "E409: Unbekannter Gruppenname: %s"
+
+#, c-format
+msgid "E410: Invalid :syntax subcommand: %s"
+msgstr "E410: Ungültiger :syntax Befehl: %s"
+
+msgid "E679: recursive loop loading syncolor.vim"
+msgstr "E679: Rekursive Schleife beim Laden von syncolor.vim"
+
+#, c-format
+msgid "E411: highlight group not found: %s"
+msgstr "E411: Hervorhebungsgruppe nicht gefunden: %s"
+
+#, c-format
+msgid "E412: Not enough arguments: \":highlight link %s\""
+msgstr "E412: Nicht ausreichend viele Argumente: \":highlight link %s\""
+
+#, c-format
+msgid "E413: Too many arguments: \":highlight link %s\""
+msgstr "E413: Zu viele Argumente: \":highlight link %s\""
+
+msgid "E414: group has settings, highlight link ignored"
+msgstr "E414: Gruppe hat Einstellungen, highlight link ignorieren"
+
+#, c-format
+msgid "E415: unexpected equal sign: %s"
+msgstr "E415: Unerwartetes Gleichheitszeichen: %s"
+
+#, c-format
+msgid "E416: missing equal sign: %s"
+msgstr "E416: fehlendes Gleichheitszeichen: %s"
+
+#, c-format
+msgid "E417: missing argument: %s"
+msgstr "E417: Fehlendes Argument: %s"
+
+#, c-format
+msgid "E418: Illegal value: %s"
+msgstr "E418: Unzulässiger Wert: %s"
+
+msgid "E419: FG color unknown"
+msgstr "E419: FG Farbe unbekannt"
+
+msgid "E420: BG color unknown"
+msgstr "E420: BG Farbe unbekannt"
+
+#, c-format
+msgid "E421: Color name or number not recognized: %s"
+msgstr "E421: Unbekannte Farbbezeichnung oder -Nummer: %s"
+
+#, c-format
+msgid "E422: terminal code too long: %s"
+msgstr "E422: Terminal-Code zu lang: %s"
+
+#, c-format
+msgid "E423: Illegal argument: %s"
+msgstr "E423: Unzulässiges Argument: %s"
+
+msgid "E424: Too many different highlighting attributes in use"
+msgstr "E424: Zu viele verschieden Hervorhebungsattribute in Gebrauch"
+
+msgid "E669: Unprintable character in group name"
+msgstr "E669: Nicht druckbare Zeichen im Namen der Gruppe"
+
+msgid "W18: Invalid character in group name"
+msgstr "W18: Ungültiges Zeichen im Namen der Gruppe"
+
+msgid "E555: at bottom of tag stack"
+msgstr "E555: Am Ende des Tag-Stacks"
+
+msgid "E556: at top of tag stack"
+msgstr "E556: Am Anfang des Tag-Stacks"
+
+msgid "E425: Cannot go before first matching tag"
+msgstr "E425: Kann nicht vor den ersten passenden Tag hinausgehen"
+
+#, c-format
+msgid "E426: tag not found: %s"
+msgstr "E426: Konnte Tag \"%s\" nicht finden"
+
+msgid " # pri kind tag"
+msgstr " # pri verw. tag"
+
+msgid "file\n"
+msgstr "Datei\n"
+
+msgid "E427: There is only one matching tag"
+msgstr "E427: Es gibt nur einen passenden Tag"
+
+msgid "E428: Cannot go beyond last matching tag"
+msgstr "E428: Kann nicht über den letzten passenden Tag hinausgehen"
+
+#, c-format
+msgid "File \"%s\" does not exist"
+msgstr "Die Datei \"%s\" existiert nicht"
+
+#. Give an indication of the number of matching tags
+#, c-format
+msgid "tag %d of %d%s"
+msgstr "Tag %d aus %d%s"
+
+msgid " or more"
+msgstr " oder mehr"
+
+msgid " Using tag with different case!"
+msgstr " Verwendung eines Tags mit abgewandelter Groß-/Klein-Schreibung"
+
+#, c-format
+msgid "E429: File \"%s\" does not exist"
+msgstr "E429: Die Datei \"%s\" existiert nicht"
+
+#. Highlight title
+msgid ""
+"\n"
+" # TO tag FROM line in file/text"
+msgstr ""
+"\n"
+" # NACH TAG VON Zeile in Datei/Text"
+
+#, c-format
+msgid "Searching tags file %s"
+msgstr "tags file %s wird durchsucht"
+
+#, c-format
+msgid "E430: Tag file path truncated for %s\n"
+msgstr "E430: Tag-Dateipfad wurde abgeschnitten für %s\n"
+
+#, c-format
+msgid "E431: Format error in tags file \"%s\""
+msgstr "E431: Format Fehler in Tag-Datei \"%s\""
+
+#, c-format
+msgid "Before byte %ld"
+msgstr "Vor byte %ld"
+
+#, c-format
+msgid "E432: Tags file not sorted: %s"
+msgstr "E432: Tag-Datei ist nicht sortiert: %s"
+
+#. never opened any tags file
+msgid "E433: No tags file"
+msgstr "E433: Keine Tag-Datei"
+
+msgid "E434: Can't find tag pattern"
+msgstr "E434: Kann Tag-Muster nicht finden"
+
+msgid "E435: Couldn't find tag, just guessing!"
+msgstr "E435: Konnte Tag möglicherweise nicht finden!"
+
+msgid "' not known. Available builtin terminals are:"
+msgstr "' nicht bekannt. Die folgenden eingebauten Terminals stehen zur Verfügung:"
+
+msgid "defaulting to '"
+msgstr "Voreinstellung '"
+
+msgid "E557: Cannot open termcap file"
+msgstr "E557: Termcap-Datei kann nicht geöffnet werden"
+
+msgid "E558: Terminal entry not found in terminfo"
+msgstr "E558: Kein Terminal-Eintrag in der Terminfo-Datenbank gefunden"
+
+msgid "E559: Terminal entry not found in termcap"
+msgstr "E559: Kein Terminal-Eintrag in der Termcap-Datei gefunden"
+
+#, c-format
+msgid "E436: No \"%s\" entry in termcap"
+msgstr "E436: Kein \"%s\" Eintrag in der Termcap-Datei"
+
+msgid "E437: terminal capability \"cm\" required"
+msgstr "E437: Terminalfähigkeit \"cm\" wird benötigt"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Terminal keys ---"
+msgstr ""
+"\n"
+"--- Terminal Tasten ---"
+
+msgid "new shell started\n"
+msgstr "neue Shell gestartet\n"
+
+msgid "Vim: Error reading input, exiting...\n"
+msgstr "Vim: Fehler beim Lesen der Eingabe, Abbruch...\n"
+
+msgid "No undo possible; continue anyway"
+msgstr "Wiederherstellung nicht möglich; setze trotzdem fort"
+
+msgid "Already at oldest change"
+msgstr "Bereits bei der ältesten Änderung"
+
+msgid "Already at newest change"
+msgstr "Bereits bei der jüngsten Änderung"
+
+#, c-format
+msgid "Undo number %ld not found"
+msgstr "Nummer %ld zur Wiederherstellung nicht gefunden"
+
+msgid "E438: u_undo: line numbers wrong"
+msgstr "E438: u_undo: Zeilennummer falsch"
+
+msgid "more line"
+msgstr "Zeile mehr"
+
+msgid "more lines"
+msgstr "Zeilen mehr"
+
+msgid "line less"
+msgstr "Zeile weniger"
+
+msgid "fewer lines"
+msgstr "Zeilen weniger"
+
+msgid "change"
+msgstr "Änderung"
+
+msgid "changes"
+msgstr "Änderungen"
+
+#, c-format
+msgid "%ld %s; %s #%ld %s"
+msgstr "%ld %s; %s #%ld %s"
+
+msgid "before"
+msgstr "vor"
+
+msgid "after"
+msgstr "nach"
+
+msgid "Nothing to undo"
+msgstr "Nichts wiederherzustellen"
+
+msgid "number changes time"
+msgstr "Nummer Änd. Zeit"
+
+msgid "E439: undo list corrupt"
+msgstr "E439: Liste der Wiederherstellungen fehlerhaft"
+
+msgid "E440: undo line missing"
+msgstr "E440: Wiederherstellungszeile fehlt"
+
+#. Only MS VC 4.1 and earlier can do Win32s
+msgid ""
+"\n"
+"MS-Windows 16/32-bit GUI version"
+msgstr ""
+"\n"
+"MS-Windows 16/32 Bit GUI Version"
+
+msgid ""
+"\n"
+"MS-Windows 32-bit GUI version"
+msgstr ""
+"\n"
+"MS-Windows 32 Bit GUI Version"
+
+msgid " in Win32s mode"
+msgstr " in Win32s Modus"
+
+msgid " with OLE support"
+msgstr " mit OLE-Unterstützung"
+
+msgid ""
+"\n"
+"MS-Windows 32-bit console version"
+msgstr ""
+"\n"
+"MS-Windows 32 Bit Konsolen-Version"
+
+msgid ""
+"\n"
+"MS-Windows 16-bit version"
+msgstr ""
+"\n"
+"MS-Windows 16 Bit Version"
+
+msgid ""
+"\n"
+"32-bit MS-DOS version"
+msgstr ""
+"\n"
+"32 Bit MS-DOS Version"
+
+msgid ""
+"\n"
+"16-bit MS-DOS version"
+msgstr ""
+"\n"
+"16 Bit MS-DOS Version"
+
+msgid ""
+"\n"
+"MacOS X (unix) version"
+msgstr ""
+"\n"
+"MacOS X (unix) Version"
+
+msgid ""
+"\n"
+"MacOS X version"
+msgstr ""
+"\n"
+"MacOS X Version"
+
+msgid ""
+"\n"
+"MacOS version"
+msgstr ""
+"\n"
+"MacOS Version"
+
+msgid ""
+"\n"
+"RISC OS version"
+msgstr ""
+"\n"
+"RISC OS Version"
+
+msgid ""
+"\n"
+"Included patches: "
+msgstr ""
+"\n"
+"Inklusive der Korrekturen: "
+
+msgid "Modified by "
+msgstr "Verändert von "
+
+msgid ""
+"\n"
+"Compiled "
+msgstr ""
+"\n"
+"Übersetzt "
+
+msgid "by "
+msgstr "von "
+
+msgid ""
+"\n"
+"Huge version "
+msgstr ""
+"\n"
+"Riesige Version "
+
+msgid ""
+"\n"
+"Big version "
+msgstr ""
+"\n"
+"Große Version "
+
+msgid ""
+"\n"
+"Normal version "
+msgstr ""
+"\n"
+"Normale Version "
+
+msgid ""
+"\n"
+"Small version "
+msgstr ""
+"\n"
+"Kleine Version "
+
+msgid ""
+"\n"
+"Tiny version "
+msgstr ""
+"\n"
+"Winzige Version "
+
+msgid "without GUI."
+msgstr "ohne GUI."
+
+msgid "with GTK2-GNOME GUI."
+msgstr "mit GTK2-GNOME GUI."
+
+msgid "with GTK-GNOME GUI."
+msgstr "mit GTK-GNOME GUI."
+
+msgid "with GTK2 GUI."
+msgstr "mit GTK2 GUI."
+
+msgid "with GTK GUI."
+msgstr "mit GTK GUI."
+
+msgid "with X11-Motif GUI."
+msgstr "mit X11-Motif GUI."
+
+msgid "with X11-neXtaw GUI."
+msgstr "mit X11-neXtaw GUI."
+
+msgid "with X11-Athena GUI."
+msgstr "mit X11-Athena GUI."
+
+msgid "with BeOS GUI."
+msgstr "mit BeOS GUI."
+
+msgid "with Photon GUI."
+msgstr "mit Photon GUI."
+
+msgid "with GUI."
+msgstr "mit GUI."
+
+msgid "with Carbon GUI."
+msgstr "mit Carbon GUI."
+
+msgid "with Cocoa GUI."
+msgstr "mit Cocoa GUI."
+
+msgid "with (classic) GUI."
+msgstr "mit (klassischem) GUI."
+
+msgid " Features included (+) or not (-):\n"
+msgstr " Ein- (+) oder ausschließlich (-) der Eigenschaften:\n"
+
+msgid " system vimrc file: \""
+msgstr " System-vimrc-Datei: \""
+
+msgid " user vimrc file: \""
+msgstr " Benutzer-vimrc-Datei: \""
+
+msgid " 2nd user vimrc file: \""
+msgstr " zweite Benutzer-vimrc-Datei: \""
+
+msgid " 3rd user vimrc file: \""
+msgstr " dritte Benutzer-vimrc-Datei: \""
+
+msgid " user exrc file: \""
+msgstr " Benutzer-exrc-Datei: \""
+
+msgid " 2nd user exrc file: \""
+msgstr " zweite Benutzer-exrc-Datei: \""
+
+msgid " system gvimrc file: \""
+msgstr " System-gvimrc-Datei: \""
+
+msgid " user gvimrc file: \""
+msgstr " Benutzer-gvimrc-Datei: \""
+
+msgid "2nd user gvimrc file: \""
+msgstr "zweite Benutzer-gvimrc-Datei: \""
+
+msgid "3rd user gvimrc file: \""
+msgstr "dritte Benutzer-gvimrc-Datei: \""
+
+msgid " system menu file: \""
+msgstr " System-Menü-Datei: \""
+
+msgid " fall-back for $VIM: \""
+msgstr " Voreinstellung für $VIM: \""
+
+msgid " f-b for $VIMRUNTIME: \""
+msgstr " und für $VIMRUNTIME: \""
+
+msgid "Compilation: "
+msgstr "Übersetzt: "
+
+msgid "Compiler: "
+msgstr "Compiler: "
+
+msgid "Linking: "
+msgstr "Linken: "
+
+msgid " DEBUG BUILD"
+msgstr " DEBUG-VERSION"
+
+msgid "VIM - Vi IMproved"
+msgstr "VIM - verbesserter Vi"
+
+msgid "version "
+msgstr "Version "
+
+msgid "by Bram Moolenaar et al."
+msgstr "von Bram Moolenaar und Anderen"
+
+msgid "Vim is open source and freely distributable"
+msgstr "Vim ist Open Source und kann frei weitergegeben werden"
+
+msgid "Help poor children in Uganda!"
+msgstr "Helfen Sie armen Kindern in Uganda!"
+
+msgid "type :help iccf<Enter> for information "
+msgstr "Tippe :help iccf<Enter> für Informationen darüber "
+
+msgid "type :q<Enter> to exit "
+msgstr "Tippe :q<Enter> zum Beenden "
+
+msgid "type :help<Enter> or <F1> for on-line help"
+msgstr "Tippe :help<Enter> oder <F1> für Online Hilfe "
+
+msgid "type :help version7<Enter> for version info"
+msgstr "Tippe :help version7<Enter> für Versions-Informationen"
+
+msgid "Running in Vi compatible mode"
+msgstr "Vi kompatible Einstellung"
+
+msgid "type :set nocp<Enter> for Vim defaults"
+msgstr "Tippe :set nocp<Enter> für Vim-Voreinstellungen "
+
+msgid "type :help cp-default<Enter> for info on this"
+msgstr "Tippe :help cp-default<Enter> für Informationen darüber "
+
+msgid "menu Help->Orphans for information "
+msgstr "Menü Hilfe->Waisen für Informationen darüber "
+
+msgid "Running modeless, typed text is inserted"
+msgstr "Mode-freier Betrieb, getippter Text wird eingefügt"
+
+msgid "menu Edit->Global Settings->Toggle Insert Mode "
+msgstr "Menü Editieren->Globale Einstellung->Einfüge-Modus ein- und ausschalten "
+
+msgid " for two modes "
+msgstr " für zwei Modi "
+
+msgid "menu Edit->Global Settings->Toggle Vi Compatible"
+msgstr "Menü Editieren->Globale Einstellung->Vi-Kompatibilität ein- und ausschalten"
+
+msgid " for Vim defaults "
+msgstr " für Vim Voreinstellungen "
+
+msgid "Sponsor Vim development!"
+msgstr "Unterstützen Sie die Entwicklung von Vim"
+
+msgid "Become a registered Vim user!"
+msgstr "Werden Sie ein registrierter Benutzer von Vim!"
+
+msgid "type :help sponsor<Enter> for information "
+msgstr "Tippe :help sponsor<Enter> für mehr Informationen "
+
+msgid "type :help register<Enter> for information "
+msgstr "Tippe :help register<Enter> für mehr Informationen "
+
+msgid "menu Help->Sponsor/Register for information "
+msgstr "Menü Hilfe->Sponsor/Register für mehr Informationen "
+
+msgid "WARNING: Windows 95/98/ME detected"
+msgstr "ACHTUNG: Windows 95/98/ME wurde erkannt"
+
+msgid "type :help windows95<Enter> for info on this"
+msgstr "Tippe :help windows95<Enter> für Informationen darüber "
+
+msgid "E441: There is no preview window"
+msgstr "E441: Es gibt kein Fenster zur Voransicht"
+
+# should read: topleft / botright
+msgid "E442: Can't split topleft and botright at the same time"
+msgstr "E442: topleft und botright können nicht gleichzeitig verwendet werden"
+
+msgid "E443: Cannot rotate when another window is split"
+msgstr "E443: Rotieren nicht möglich wenn ein anderes Fenster geteilt ist"
+
+msgid "E444: Cannot close last window"
+msgstr "E444: Letztes Fenster kann nicht geschlossen werden"
+
+msgid "Already only one window"
+msgstr "Bereits nur ein Fenster"
+
+msgid "E445: Other window contains changes"
+msgstr "E445: Anderes Fenster enthält Änderungen"
+
+# Cursor: Schreibmarke Positionsmarke
+msgid "E446: No file name under cursor"
+msgstr "E446: Kein Dateiname unter dem Cursor"
+
+#, c-format
+msgid "E447: Can't find file \"%s\" in path"
+msgstr "E447: Kann Datei \"%s\" nicht im Pfad finden"
+
+#, c-format
+msgid "E370: Could not load library %s"
+msgstr "E370: Konnte Bibliothek %s nicht laden"
+
+msgid "Sorry, this command is disabled: the Perl library could not be loaded."
+msgstr "Dieser Befehl ist nicht verfügbar, da die Perl-Bibliothek nicht geladen werden konnte"
+
+msgid "E299: Perl evaluation forbidden in sandbox without the Safe module"
+msgstr "E299: Perl-Evaluierung in der Sandbox ohne dem 'Safe' Modul"
+
+msgid "--No lines in buffer--"
+msgstr "--Keine Zeilen im Puffer--"
+
+#.
+#. * 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: Befehl abgebrochen"
+
+msgid "E471: Argument required"
+msgstr "E471: Argument benötigt"
+
+msgid "E10: \\ should be followed by /, ? or &"
+msgstr "E10: \\ sollte von /, ? or & gefolgt werden"
+
+msgid "E11: Invalid in command-line window; <CR> executes, CTRL-C quits"
+msgstr "E11: Ungültig im Kommandozeilenfenster; <CR> führt aus, CTRL-C beendet"
+
+msgid "E12: Command not allowed from exrc/vimrc in current dir or tag search"
+msgstr "E12: Befehl nicht zulässig vom exrc/vimrc in der momentanen Verzeichnis- oder Tag-Suche"
+
+msgid "E171: Missing :endif"
+msgstr "E171: Fehlendes :endif"
+
+msgid "E600: Missing :endtry"
+msgstr "E600: Fehlendes :endtry"
+
+msgid "E170: Missing :endwhile"
+msgstr "E170: fehlendes :endwhile"
+
+msgid "E170: Missing :endfor"
+msgstr "E170: Fehlendes :endfor"
+
+msgid "E588: :endwhile without :while"
+msgstr "E588: :endwhile ohne :while"
+
+msgid "E588: :endfor without :for"
+msgstr "E588: :endfor ohne :for"
+
+msgid "E13: File exists (add ! to override)"
+msgstr "E13: Datei existiert bereits (erzwinge mit !)"
+
+
+msgid "E472: Command failed"
+msgstr "E472: Befehl fehlgeschlagen"
+
+#, c-format
+msgid "E234: Unknown fontset: %s"
+msgstr "E234: Unbekannter Fontset: %s"
+
+#, c-format
+msgid "E235: Unknown font: %s"
+msgstr "E235: Unbekannte Schriftart: %s"
+
+#, c-format
+msgid "E236: Font \"%s\" is not fixed-width"
+msgstr "E236: Schriftart \"%s\" hat keine feste Breite"
+
+msgid "E473: Internal error"
+msgstr "E473: Interner Fehler"
+
+msgid "Interrupted"
+msgstr "Unterbrochen"
+
+msgid "E14: Invalid address"
+msgstr "E14: Ungültige Adresse"
+
+msgid "E474: Invalid argument"
+msgstr "E474: Ungültiges Argument"
+
+#, c-format
+msgid "E475: Invalid argument: %s"
+msgstr "E475: Ungültiges Argument: %s"
+
+#, c-format
+msgid "E15: Invalid expression: %s"
+msgstr "E15: ungültiger Ausdruck: %s"
+
+msgid "E16: Invalid range"
+msgstr "E16: Ungültiger Bereich"
+
+msgid "E476: Invalid command"
+msgstr "E476: Ungültiger Befehl"
+
+#, c-format
+msgid "E17: \"%s\" is a directory"
+msgstr "E17: \"%s\" ist ein Verzeichnis"
+
+#, c-format
+msgid "E364: Library call failed for \"%s()\""
+msgstr "E364: Bibliotheksaufruf für \"%s()\" schlug fehl"
+
+#, c-format
+msgid "E448: Could not load library function %s"
+msgstr "E448: Bibliotheksfunktion %s konnte nicht geladen werden"
+
+msgid "E19: Mark has invalid line number"
+msgstr "E19: Marke hat ungültige Zeilennummer"
+
+msgid "E20: Mark not set"
+msgstr "E20: Marke nicht gesetzt"
+
+msgid "E21: Cannot make changes, 'modifiable' is off"
+msgstr "E21: Kann keine Änderungen machen, 'modifiable' ist aus"
+
+msgid "E22: Scripts nested too deep"
+msgstr "E22: Skript ist zu tief verschachtelt"
+
+msgid "E23: No alternate file"
+msgstr "E23: Keine alternative Datei"
+
+msgid "E24: No such abbreviation"
+msgstr "E24: Keine Abkürzung gefunden"
+
+msgid "E477: No ! allowed"
+msgstr "E477: Kein ! erlaubt"
+
+msgid "E25: GUI cannot be used: Not enabled at compile time"
+msgstr "E25: GUI kann nicht benutzt werden: wurde zum Zeitpunkt des Übersetzens nicht eingeschaltet."
+
+msgid "E26: Hebrew cannot be used: Not enabled at compile time\n"
+msgstr "E26: Hebräisch kann nicht benutzt werden: wurde zum Zeitpunkt des Übersetzens nicht eingeschaltet.\n"
+
+msgid "E27: Farsi cannot be used: Not enabled at compile time\n"
+msgstr "E27: Farsi kann nicht benutzt werden: wurde zum Zeitpunkt des Übersetzens nicht eingeschaltet.\n"
+
+msgid "E800: Arabic cannot be used: Not enabled at compile time\n"
+msgstr "E800: Arabisch kann nicht benutzt werden: wurde zum Zeitpunkt des Übersetzens nicht eingeschaltet.\n"
+
+#, c-format
+msgid "E28: No such highlight group name: %s"
+msgstr "E28: Hervorhebungsgruppe existiert nicht: %s"
+
+msgid "E29: No inserted text yet"
+msgstr "E29: Noch kein eingefügter Text"
+
+msgid "E30: No previous command line"
+msgstr "E30: Keine vorherige Befehlszeile"
+
+msgid "E31: No such mapping"
+msgstr "E31: Keine Zuordnung gefunden"
+
+msgid "E479: No match"
+msgstr "E479: Kein Treffer"
+
+#, c-format
+msgid "E480: No match: %s"
+msgstr "E480: Kein Treffer: %s"
+
+msgid "E32: No file name"
+msgstr "E32: Kein Dateiname"
+
+msgid "E33: No previous substitute regular expression"
+msgstr "E33: Kein vorheriger regulärer Ersetzungsausdruck"
+
+msgid "E34: No previous command"
+msgstr "E34: Kein vorheriger Befehl"
+
+msgid "E35: No previous regular expression"
+msgstr "E35: Keine vorheriger regulärer Ausdruck"
+
+msgid "E481: No range allowed"
+msgstr "E481: Kein Bereich erlaubt"
+
+msgid "E36: Not enough room"
+msgstr "E36: Zu wenig Platz"
+
+#, c-format
+msgid "E247: no registered server named \"%s\""
+msgstr "E247: Kein registrierter Servername \"%s\""
+
+#, c-format
+msgid "E482: Can't create file %s"
+msgstr "E482: Kann Datei %s nicht erzeugen"
+
+msgid "E483: Can't get temp file name"
+msgstr "E483: Kann den Namen der temporären Datei nicht ermitteln"
+
+#, c-format
+msgid "E484: Can't open file %s"
+msgstr "E484: Kann die Datei %s nicht öffnen"
+
+#, c-format
+msgid "E485: Can't read file %s"
+msgstr "E485: Kann Datei %s nicht lesen"
+
+msgid "E37: No write since last change (add ! to override)"
+msgstr "E37: Kein Schreibvorgang seit der letzten Änderung (erzwinge mit !)"
+
+msgid "E38: Null argument"
+msgstr "E38: Null-Argument"
+
+msgid "E39: Number expected"
+msgstr "E39: Nummer erwartet"
+
+#, c-format
+msgid "E40: Can't open errorfile %s"
+msgstr "E40: Fehlerdatei %s kann nicht geöffnet werden"
+
+msgid "E233: cannot open display"
+msgstr "E233: Display kann nicht geöffnet werden"
+
+msgid "E41: Out of memory!"
+msgstr "E41: Speicher erschöpft!"
+
+msgid "Pattern not found"
+msgstr "Muster nicht gefunden"
+
+#, c-format
+msgid "E486: Pattern not found: %s"
+msgstr "E486: Muster nicht gefunden: %s"
+
+msgid "E487: Argument must be positive"
+msgstr "E487: Argument muss positiv sein"
+
+msgid "E459: Cannot go back to previous directory"
+msgstr "E459: Kann nicht ins vorhergehende Verzeichnis wechseln"
+
+msgid "E42: No Errors"
+msgstr "E42: Kein Fehler"
+
+msgid "E776: No location list"
+msgstr "E776: Keine Positionsliste"
+
+msgid "E43: Damaged match string"
+msgstr "E43: Beschädigter Suchausdruck"
+
+msgid "E44: Corrupted regexp program"
+msgstr "E44: schadhaftes regexp Programm"
+
+msgid "E45: 'readonly' option is set (add ! to override)"
+msgstr "E45: Die Option 'readonly' ist gesetzt (erzwinge mit !)"
+
+#, c-format
+msgid "E46: Cannot set read-only variable \"%s\""
+msgstr "E46: Variable \"%s\" kann nur gelesen werden"
+
+msgid "E47: Error while reading errorfile"
+msgstr "E47: Fehler während des Lesens der Fehlerdatei"
+
+msgid "E48: Not allowed in sandbox"
+msgstr "E48: In einer Sandbox nicht erlaubt"
+
+msgid "E523: Not allowed here"
+msgstr "E523: Hier nicht erlaubt"
+
+msgid "E359: Screen mode setting not supported"
+msgstr "E359: Bildschirm-Modus wird nicht unterstützt"
+
+msgid "E49: Invalid scroll size"
+msgstr "E49: Ungültige Scroll-Größe"
+
+msgid "E91: 'shell' option is empty"
+msgstr "E91: Die Option 'shell' ist leer"
+
+msgid "E255: Couldn't read in sign data!"
+msgstr "E255: Fehler -- Daten für Debuggersymbol konnten nicht gelesen werden"
+
+msgid "E72: Close error on swap file"
+msgstr "E72: Fehler beim Schließen der Auslagerungsdatei"
+
+msgid "E73: tag stack empty"
+msgstr "E73: tag Stapel leer."
+
+msgid "E74: Command too complex"
+msgstr "E74: Befehl zu kompliziert"
+
+msgid "E75: Name too long"
+msgstr "E75: Name zu lang"
+
+msgid "E76: Too many ["
+msgstr "E76: Zu viele ["
+
+msgid "E77: Too many file names"
+msgstr "E77: Zu viele Dateinamen"
+
+msgid "E488: Trailing characters"
+msgstr "E488: Überschüssige Zeichen"
+
+msgid "E78: Unknown mark"
+msgstr "E78: Unbekannte Mark"
+
+msgid "E79: Cannot expand wildcards"
+msgstr "E79: Kann die Platzhalter nicht erweitern"
+
+msgid "E591: 'winheight' cannot be smaller than 'winminheight'"
+msgstr "E591: 'winheight' darf nicht kleiner sein als 'winminheight'"
+
+msgid "E592: 'winwidth' cannot be smaller than 'winminwidth'"
+msgstr "E592: 'winwidth' darf nicht kleiner sein als 'winminwidth'"
+
+msgid "E80: Error while writing"
+msgstr "E80: Fehler während des Schreibens"
+
+msgid "Zero count"
+msgstr "Null-Zähler"
+
+msgid "E81: Using <SID> not in a script context"
+msgstr "E81: <SID> wurde nicht in einer Skript-Umgebung benutzt"
+
+msgid "E449: Invalid expression received"
+msgstr "E449: Ungültiger Ausdruck"
+
+msgid "E463: Region is guarded, cannot modify"
+msgstr "E463: Region ist geschützt; keine Änderung möglich"
+
+msgid "E744: NetBeans does not allow changes in read-only files"
+msgstr "E744: NetBeans erlaubt keine Änderungen in schreibgeschützten Dateien"
+
+#, c-format
+msgid "E685: Internal error: %s"
+msgstr "E685: Interner Fehler: %s"
+
+msgid "E363: pattern uses more memory than 'maxmempattern'"
+msgstr "E363: Muster benötigt mehr Speicher als 'maxmempattern'"
+
+msgid "E749: empty buffer"
+msgstr "E749: Leerer Puffer"
+
+msgid "E682: Invalid search pattern or delimiter"
+msgstr "E682: Ungültiges Suchmuster oder Trennzeichen"
+
+msgid "E139: File is loaded in another buffer"
+msgstr "E139: Datei ist in einem anderen Puffer geladen"
+
+#, c-format
+msgid "E764: Option '%s' is not set"
+msgstr "E764: Option '%s' ist nicht gesetzt"
+
+msgid "search hit TOP, continuing at BOTTOM"
+msgstr "Suche erreichte den ANFANG und wurde am ENDE fortgesetzt"
+
+msgid "search hit BOTTOM, continuing at TOP"
+msgstr "Suche erreichte das ENDE und wurde am ANFANG fortgesetzt"
+
+msgid "Edit with &multiple Vims"
+msgstr "Editiere mit &mehreren Vims"
+
+msgid "Edit with single &Vim"
+msgstr "Editiere mit einem &Vim"
+
+msgid "Diff with Vim"
+msgstr "Differenz mit Vim"
+
+msgid "Edit with &Vim"
+msgstr "Editiere mit &Vim"
+
+msgid "Edit with existing Vim - "
+msgstr "Editiere mit vorhandenem Vim - "
+
+msgid "Press ENTER or type command to continue"
+msgstr "Betätigen Sie die EINGABETASTE oder geben Sie einen Befehl ein"
+
+msgid "Error creating process: Check if gvim is in your path!"
+msgstr "Fehler beim Erzeugen des Prozesses: Überprüfen Sie, ob gvim in Ihrem Pfad ist!"
+
+msgid "gvimext.dll error"
+msgstr "gvimext.dll Fehler"
+
+msgid "Path length too long!"
+msgstr "Die Länge des Pfads ist zu groß!"
+
+msgid "Edits the selected file(s) with Vim"
+msgstr "Editiert die ausgewählte(n) Datei(en) mit Vim"
+
+msgid "%ld seconds ago"
+msgstr "vor %ld Sekunden"
+
+msgid "E790: undojoin is not allowed after undo"
+msgstr "E790: 'undojoin' ist nicht erlaubt nach 'undo'"
+
+#, c-format
+msgid "E117: Unknown function: %s"
+msgstr "E117: Unbekannte Funktion: %s"
+
+#, c-format
+msgid "E119: Not enough arguments for function: %s"
+msgstr "E119: Zu wenige Argumente für Funktion: %s"
+
+#, c-format
+msgid "E120: Using <SID> not in a script context: %s"
+msgstr "E120: <SID> wurde nicht in einer Skript-Umgebung benutzt: %s"
+
+#, c-format
+msgid "E725: Calling dict function without Dictionary: %s"
+msgstr "E725: Aufruf der 'dict' Funktion ohne Wörterbuch: %s"
+
+msgid "E786: Range not allowed"
+msgstr "E786: Bereich nicht erlaubt"
+
+#, c-format
+msgid "E154: Duplicate tag \"%s\" in file %s/%s"
+msgstr "E154: Doppelter Tag \"%s\" in der Datei %s/%s"
+
+msgid "E179: argument required for -complete"
+msgstr "E179: Argument benötigt für -complete"
+
+#, c-format
+msgid "Tab page %d"
+msgstr "Tab %d"
+
+msgid "E585: :while/:for nesting too deep"
+msgstr "E585: :while/:for Schachtelung zu tief"
+
+msgid "E586: :continue without :while or :for"
+msgstr "E586: :continue ohne :while or :for"
+
+msgid "E587: :break without :while or :for"
+msgstr "E587: :break ohne :while oder :for"
+
+msgid "E788: Not allowed to edit another buffer now"
+msgstr "E788: Einen weiteren Puffer zu editieren ist im Moment nicht erlaubt"
+
+msgid "E513: write error, conversion failed (make 'fenc' empty to override)"
+msgstr "E513: Schreibfehler, Umwandlung schlug fehl (leere 'fenc' um sie zu erzwingen)"
+
+#, c-format
+msgid "E211: File \"%s\" no longer available"
+msgstr "E211: Datei \"%s\" ist nicht länger vorhanden"
+
+msgid "See \":help W12\" for more info."
+msgstr "Siehe \":help W12\" für mehr Information"
+
+msgid "See \":help W11\" for more info."
+msgstr "Siehe \":help W11\" für mehr Information"
+
+#, c-format
+msgid "E46: Cannot change read-only variable \"%s\""
+msgstr "E46: Variable \"%s\" kann nur gelesen werden"
+
+#, c-format
+msgid "E46: Cannot set variable in the sandbox: \"%s\""
+msgstr "E46: Variable \"%s\" kann in der Sandbox nur gelesen werden"
+
+msgid "E267: unexpected return"
+msgstr "E267: Unerwartetes 'return'"
+
+msgid "E268: unexpected next"
+msgstr "E268: Unerwartetes 'next'"
+
+msgid "E269: unexpected break"
+msgstr "E269: Unerwartetes 'break'"
+
+msgid "E270: unexpected redo"
+msgstr "E270: Unerwartetes 'redo'"
+
+msgid "E271: retry outside of rescue clause"
+msgstr "E271: 'retry' außerhalb der 'rescue clause'"
+
+msgid "E272: unhandled exception"
+msgstr "E272: Unbehandelte Ausnahme"
+
+#, c-format
+msgid "%d files to edit\n"
+msgstr "%d Dateien zum Editieren\n"
+
+msgid "-p[N]\t\tOpen N tab pages (default: one for each file)"
+msgstr "-p[N]\t\tÖffne N Tabs (Vorgabe: einzeln für jede Datei)"
+
+msgid "--remote-tab <files> As --remote but open tab page for each file"
+msgstr "--remote-tab <Dateien> Wie --remote, aber öffne ein Tab für jede Datei"
+
+msgid "E304: ml_upd_block0(): Didn't get block 0??"
+msgstr "E304: ml_upd_block0(): Block Nr. 0 nicht erhalten?"
+
+msgid "Select Directory dialog"
+msgstr "Verzeichnis Auswahl Dialog"
+
+msgid "No match at cursor, finding next"
+msgstr "Kein Treffer beim Cursur, finde den nächsten"
+
+msgid "E265: $_ must be an instance of String"
+msgstr "E265: $_ muss eine Instanz einer Zeichenkette sein"
+
+msgid "E773: Symlink loop for \"%s\""
+msgstr "E773: Symlink Schleife für \"%s\""
+
+#, c-format
+msgid ""
+"\n"
+"# Last %sSearch Pattern:\n"
+"~"
+msgstr ""
+"\n"
+"# Letztes %sSuchmuster:\n"
+"~"
+
+#, c-format
+msgid ""
+"Defining COMPOUNDFORBIDFLAG after PFX item may give wrong results in %s line "
+"%d"
+msgstr ""
+"Die Definition von COMPOUNDFORBIDFLAG nach dem PFX Element kann falsches Ergebnis in Zeile %s ergeben "
+"%d"
+
+#, c-format
+msgid ""
+"Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in %s line "
+"%d"
+msgstr ""
+"Die Definition von COMPOUNDPERMITFLAG nach dem PFX Element kann falsches Ergebnis in Zeile %s ergeben "
+"%d"
+
+msgid "E116: Invalid arguments for function %s"
+msgstr "E116: Ungültige Argumente für die Funktion %s"
diff --git a/src/po/en_GB.po b/src/po/en_GB.po
new file mode 100644
index 0000000000..1caad8ae2f
--- /dev/null
+++ b/src/po/en_GB.po
@@ -0,0 +1,290 @@
+# UK English 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 Mike Williams <mrw@eandem.co.uk>, 2003.
+#
+# Style Guide:
+# o English spelling!
+# o -ise, not -ize.
+# o No contractions.
+# o Cannot, not can not.
+# o Backward (no s) when used as an adjective.
+# o TBC ...
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Vim(UK English)\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2008-07-19 18:03+0100\n"
+"PO-Revision-Date: 2003-02-25 11:05+0000\n"
+"Last-Translator: Mike Williams <mrw@eandem.co.uk>\n"
+"Language-Team: Mike Williams <mrw@eandem.co.uk>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=ISO_8859-1\n"
+"Content-Transfer-Encoding: 7bit\n"
+
+#, c-format
+msgid "E96: Can not diff more than %ld buffers"
+msgstr "E96: Cannot diff more than %ld buffers"
+
+msgid "E101: More than two buffers in diff mode, don't know which one to use"
+msgstr "E101: More than two buffers in diff mode, do not know which one to use"
+
+#, c-format
+msgid "E102: Can't find buffer \"%s\""
+msgstr "E102: Cannot find buffer \"%s\""
+
+#, c-format
+msgid "E738: Can't list variables for %s"
+msgstr "E738: Cannot list variables for %s"
+
+#, c-format
+msgid "E138: Can't write viminfo file %s!"
+msgstr "E138: Cannot write viminfo file %s!"
+
+msgid ""
+"# You may edit it if you're careful!\n"
+"\n"
+msgstr ""
+"# You may edit it if you are careful!\n"
+"\n"
+
+msgid "E146: Regular expressions can't be delimited by letters"
+msgstr "E146: Regular expressions cannot be delimited by letters"
+
+msgid "E493: Backwards range given"
+msgstr "E493: Backward range given"
+
+msgid "Backwards range given, OK to swap"
+msgstr "Backward range given, OK to swap"
+
+#, c-format
+msgid "E185: Cannot find color scheme %s"
+msgstr "E185: Cannot find colour scheme %s"
+
+msgid "Can't find temp file for conversion"
+msgstr "Cannot find temp file for conversion"
+
+msgid "can't read output of 'charconvert'"
+msgstr "cannot read output of 'charconvert'"
+
+msgid "E506: Can't write to backup file (add ! to override)"
+msgstr "E506: Cannot write to backup file (add ! to override)"
+
+msgid "E508: Can't read file for backup (add ! to override)"
+msgstr "E508: Cannot read file for backup (add ! to override)"
+
+msgid "E510: Can't make backup file (add ! to override)"
+msgstr "E510: Cannot make backup file (add ! to override)"
+
+msgid "E214: Can't find temp file for writing"
+msgstr "E214: Cannot find temp file for writing"
+
+msgid "E166: Can't open linked file for writing"
+msgstr "E166: Cannot open linked file for writing"
+
+msgid "E212: Can't open file for writing"
+msgstr "E212: Cannot open file for writing"
+
+msgid "E205: Patchmode: can't save original file"
+msgstr "E205: Patchmode: cannot save original file"
+
+msgid "E206: patchmode: can't touch empty original file"
+msgstr "E206: patchmode: cannot touch empty original file"
+
+msgid "E207: Can't delete backup file"
+msgstr "E207: Cannot delete backup file"
+
+msgid "don't quit the editor until the file is successfully written!"
+msgstr "do not quit the editor until the file is successfully written!"
+
+msgid "E217: Can't execute autocommands for ALL events"
+msgstr "E217: Cannot execute autocommands for ALL events"
+
+#, c-format
+msgid "E482: Can't create file %s"
+msgstr "E482: Cannot create file %s"
+
+msgid "E483: Can't get temp file name"
+msgstr "E483: Cannot get temp file name"
+
+#, c-format
+msgid "E484: Can't open file %s"
+msgstr "E484: Cannot open file %s"
+
+#, c-format
+msgid "E485: Can't read file %s"
+msgstr "E485: Cannot read file %s"
+
+#, c-format
+msgid "E40: Can't open errorfile %s"
+msgstr "E40: Cannot open errorfile %s"
+
+msgid "E255: Couldn't read in sign data!"
+msgstr "E255: Could not read in sign data!"
+
+#, c-format
+msgid "E254: Cannot allocate color %s"
+msgstr "E254: Cannot allocate colour %s"
+
+#, c-format
+msgid "E616: vim_SelFile: can't get font %s"
+msgstr "E616: vim_SelFile: cannot get font %s"
+
+msgid "E614: vim_SelFile: can't return to current directory"
+msgstr "E614: vim_SelFile: cannot return to current directory"
+
+msgid "E615: vim_SelFile: can't get current directory"
+msgstr "E615: vim_SelFile: cannot get current directory"
+
+msgid "Vim E458: Cannot allocate colormap entry, some colors may be incorrect"
+msgstr ""
+"Vim E458: Cannot allocate colourmap entry, some colours may be incorrect"
+
+#, c-format
+msgid "E624: Can't open file \"%s\""
+msgstr "E624: Cannot open file \"%s\""
+
+#, c-format
+msgid "E457: Can't read PostScript resource file \"%s\""
+msgstr "E457: Cannot read PostScript resource file \"%s\""
+
+msgid "E324: Can't open PostScript output file"
+msgstr "E324: Cannot open PostScript output file"
+
+#, c-format
+msgid "E456: Can't open file \"%s\""
+msgstr "E456: Cannot open file \"%s\""
+
+msgid "E456: Can't find PostScript resource file \"prolog.ps\""
+msgstr "E456: Cannot find PostScript resource file \"prolog.ps\""
+
+msgid "E456: Can't find PostScript resource file \"cidfont.ps\""
+msgstr "E456: Cannot find PostScript resource file \"cidfont.ps\""
+
+#, c-format
+msgid "E456: Can't find PostScript resource file \"%s.ps\""
+msgstr "E456: Cannot find PostScript resource file \"%s.ps\""
+
+msgid "couldn't open buffer"
+msgstr "could not open buffer"
+
+msgid "can't delete OutputObject attributes"
+msgstr "cannot delete OutputObject attributes"
+
+msgid "--literal\t\tDon't expand wildcards"
+msgstr "--literal\t\tDo not expand wildcards"
+
+msgid "-f or --nofork\tForeground: Don't fork when starting GUI"
+msgstr "-f or --nofork\tForeground: Do not fork when starting GUI"
+
+msgid "-f\t\t\tDon't use newcli to open window"
+msgstr "-f\t\t\tDo not use newcli to open window"
+
+msgid "--noplugin\t\tDon't load plugin scripts"
+msgstr "--noplugin\t\tDo not load plugin scripts"
+
+msgid "--remote-silent <files> Same, don't complain if there is no server"
+msgstr "--remote-silent <files> Same, do not complain if there is no server"
+
+msgid ""
+"--remote-wait-silent <files> Same, don't complain if there is no server"
+msgstr ""
+"--remote-wait-silent <files> Same, do not complain if there is no server"
+
+msgid "-background <color>\tUse <color> for the background (also: -bg)"
+msgstr "-background <colour>\tUse <colour> for the background (also: -bg)"
+
+msgid "-foreground <color>\tUse <color> for normal text (also: -fg)"
+msgstr "-foreground <colour>\tUse <colour> for normal text (also: -fg)"
+
+msgid "+reverse\t\tDon't use reverse video (also: +rv)"
+msgstr "+reverse\t\tDo not use reverse video (also: +rv)"
+
+msgid "E288: input method doesn't support any style"
+msgstr "E288: input method does not support any style"
+
+msgid "E289: input method doesn't support my preedit type"
+msgstr "E289: input method does not support my preedit type"
+
+msgid "E298: Didn't get block nr 0?"
+msgstr "E298: Did not get block nr 0?"
+
+msgid "E298: Didn't get block nr 1?"
+msgstr "E298: Did not get block nr 1?"
+
+msgid "E298: Didn't get block nr 2?"
+msgstr "E298: Did not get block nr 2?"
+
+msgid "E304: ml_upd_block0(): Didn't get block 0??"
+msgstr "E304: ml_upd_block0(): Did not get block 0??"
+
+msgid "Messages maintainer: Bram Moolenaar <Bram@vim.org>"
+msgstr "Messages maintainer: Mike Williams <mrw@eandem.co.uk>"
+
+msgid "Keys don't match!"
+msgstr "Keys do not match!"
+
+#, c-format
+msgid "E344: Can't find directory \"%s\" in cdpath"
+msgstr "E344: Cannot find directory \"%s\" in cdpath"
+
+#, c-format
+msgid "E345: Can't find file \"%s\" in path"
+msgstr "E345: Cannot find file \"%s\" in path"
+
+msgid "E597: can't select fontset"
+msgstr "E597: cannot select fontset"
+
+msgid "E533: can't select wide font"
+msgstr "E533: cannot select wide font"
+
+msgid "VIM: Can't open window!\n"
+msgstr "VIM: Cannot open window!\n"
+
+msgid "E388: Couldn't find definition"
+msgstr "E388: Could not find definition"
+
+msgid "E389: Couldn't find pattern"
+msgstr "E389: Could not find pattern"
+
+#, c-format
+msgid "Unrecognized or duplicate item in %s line %d: %s"
+msgstr "Unrecognised or duplicate item in %s line %d: %s"
+
+#, c-format
+msgid "Unrecognized flags in %s line %d: %s"
+msgstr "Unrecognised flags in %s line %d: %s"
+
+#, c-format
+msgid "E781: .sug file doesn't match .spl file: %s"
+msgstr "E781: .sug file does not match .spl file: %s"
+
+#, c-format
+msgid "E394: Didn't find region item for %s"
+msgstr "E394: Did not find region item for %s"
+
+msgid "E419: FG color unknown"
+msgstr "E419: FG colour unknown"
+
+msgid "E420: BG color unknown"
+msgstr "E420: BG colour unknown"
+
+#, c-format
+msgid "E421: Color name or number not recognized: %s"
+msgstr "E421: Colour name or number not recognised: %s"
+
+msgid "E434: Can't find tag pattern"
+msgstr "E434: Cannot find tag pattern"
+
+msgid "E435: Couldn't find tag, just guessing!"
+msgstr "E435: Could not find tag, just guessing!"
+
+msgid "E442: Can't split topleft and botright at the same time"
+msgstr "E442: Cannot split topleft and botright at the same time"
+
+#, c-format
+msgid "E447: Can't find file \"%s\" in path"
+msgstr "E447: Cannot find file \"%s\" in path"
diff --git a/src/po/eo.po b/src/po/eo.po
new file mode 100644
index 0000000000..24062c0f1a
--- /dev/null
+++ b/src/po/eo.po
@@ -0,0 +1,6825 @@
+# Esperanto 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.
+#
+# UNUA TRADUKISTO Dominique PELLE <dominique.pelle ĉe gmail.com>
+# PROVLEGANTO(J) Felipe CASTRO <fefcas ĉe gmail.com>
+# Antono MECHELYNCK <antoine.mechelynck ĉe skynet.be>
+# Yves NEVELSTEEN
+#
+# Uzitaj vortaroj kaj fakvortaroj:
+# Revo: http://www.reta-vortaro.de/revo/
+# 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: 2013-05-27 04:50+0200\n"
+"PO-Revision-Date: 2013-05-27 04:55+0200\n"
+"Last-Translator: Dominique PELLÉ <dominique.pelle@gmail.com>\n"
+"Language-Team: \n"
+"Language: eo\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+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 "[Location List]"
+msgstr "[Listo de lokoj]"
+
+# DP: Ĉu vere indas traduki Quickfix?
+msgid "[Quickfix List]"
+msgstr "[Listo de rapidriparoj]"
+
+msgid "E855: Autocommands caused command to abort"
+msgstr "E855: AÅ­tokomandoj haltigis komandon"
+
+msgid "E82: Cannot allocate any buffer, exiting..."
+msgstr "E82: Ne eblas disponigi iun ajn bufron, nun eliras..."
+
+msgid "E83: Cannot allocate buffer, using other one..."
+msgstr "E83: Ne eblas disponigi bufron, nun uzas alian..."
+
+msgid "E515: No buffers were unloaded"
+msgstr "E515: Neniu bufro estis malÅargita"
+
+msgid "E516: No buffers were deleted"
+msgstr "E516: Neniu bufro estis forviÅita"
+
+msgid "E517: No buffers were wiped out"
+msgstr "E517: Neniu bufro estis detruita"
+
+msgid "1 buffer unloaded"
+msgstr "1 bufro malÅargita"
+
+#, c-format
+msgid "%d buffers unloaded"
+msgstr "%d bufroj malÅargitaj"
+
+msgid "1 buffer deleted"
+msgstr "1 bufro forviÅita"
+
+#, c-format
+msgid "%d buffers deleted"
+msgstr "%d bufroj forviÅitaj"
+
+msgid "1 buffer wiped out"
+msgstr "1 bufro detruita"
+
+#, c-format
+msgid "%d buffers wiped out"
+msgstr "%d bufroj detruitaj"
+
+msgid "E84: No modified buffer found"
+msgstr "E84: Neniu modifita bufro trovita"
+
+#. back where we started, didn't find anything.
+msgid "E85: There is no listed buffer"
+msgstr "E85: Estas neniu listigita bufro"
+
+#, c-format
+msgid "E86: Buffer %ld does not exist"
+msgstr "E86: La bufro %ld ne ekzistas"
+
+msgid "E87: Cannot go beyond last buffer"
+msgstr "E87: Ne eblas iri preter la lastan bufron"
+
+msgid "E88: Cannot go before first buffer"
+msgstr "E88: Ne eblas iri antaÅ­ la unuan bufron"
+
+#, c-format
+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 %ld (aldonu ! por "
+"transpasi)"
+
+msgid "E90: Cannot unload last buffer"
+msgstr "E90: Ne eblas malÅargi la lastan bufron"
+
+msgid "W14: Warning: List of file names overflow"
+msgstr "W14: Averto: Listo de dosiernomoj troas"
+
+#, c-format
+msgid "E92: Buffer %ld not found"
+msgstr "E92: Bufro %ld ne trovita"
+
+#, c-format
+msgid "E93: More than one match for %s"
+msgstr "E93: Pli ol unu kongruo kun %s"
+
+#, c-format
+msgid "E94: No matching buffer for %s"
+msgstr "E94: Neniu bufro kongruas kun %s"
+
+#, c-format
+msgid "line %ld"
+msgstr "linio %ld"
+
+msgid "E95: Buffer with this name already exists"
+msgstr "E95: Bufro kun tiu nomo jam ekzistas"
+
+msgid " [Modified]"
+msgstr "[Modifita]"
+
+msgid "[Not edited]"
+msgstr "[Ne redaktita]"
+
+msgid "[New file]"
+msgstr "[Nova dosiero]"
+
+msgid "[Read errors]"
+msgstr "[Eraroj de legado]"
+
+msgid "[readonly]"
+msgstr "[nurlegebla]"
+
+#, c-format
+msgid "1 line --%d%%--"
+msgstr "1 linio --%d%%--"
+
+#, c-format
+msgid "%ld lines --%d%%--"
+msgstr "%ld linioj --%d%%--"
+
+#, c-format
+msgid "line %ld of %ld --%d%%-- col "
+msgstr "linio %ld de %ld --%d%%-- kol "
+
+msgid "[No Name]"
+msgstr "[Neniu nomo]"
+
+#. must be a help buffer
+msgid "help"
+msgstr "helpo"
+
+msgid "[Help]"
+msgstr "[Helpo]"
+
+msgid "[Preview]"
+msgstr "[AntaÅ­vido]"
+
+msgid "All"
+msgstr "Ĉio"
+
+msgid "Bot"
+msgstr "Subo"
+
+msgid "Top"
+msgstr "Supro"
+
+msgid ""
+"\n"
+"# Buffer list:\n"
+msgstr ""
+"\n"
+"# Listo de bufroj:\n"
+
+msgid "[Scratch]"
+msgstr "[Malneto]"
+
+# DP: Vidu ":help sign-support" por klarigo pri "Sign"
+msgid ""
+"\n"
+"--- Signs ---"
+msgstr ""
+"\n"
+"--- Emfazaj simbolaĵoj ---"
+
+#, c-format
+msgid "Signs for %s:"
+msgstr "Emfazaj simbolaĵoj de %s:"
+
+#, c-format
+msgid " line=%ld id=%d name=%s"
+msgstr " linio=%ld id=%d nomo=%s"
+
+#, c-format
+msgid "E96: Can not diff more than %ld buffers"
+msgstr "E96: Ne eblas dosierdiferenci pli ol %ld bufrojn"
+
+msgid "E810: Cannot read or write temp files"
+msgstr "E810: Ne eblas legi aÅ­ skribi provizorajn dosierojn"
+
+msgid "E97: Cannot create diffs"
+msgstr "E97: Ne eblas krei dosierdiferencojn"
+
+msgid "Patch file"
+msgstr "Flika dosiero"
+
+msgid "E816: Cannot read patch output"
+msgstr "E816: Ne eblas legi eliron de flikilo \"patch\""
+
+msgid "E98: Cannot read diff output"
+msgstr "E98: Ne eblas legi eliron de dosierdiferencilo \"diff\""
+
+msgid "E99: Current buffer is not in diff mode"
+msgstr "E99: Aktuala bufro ne estas en dosierdiferenca reÄimo"
+
+msgid "E793: No other buffer in diff mode is modifiable"
+msgstr "E793: Neniu alia bufro en dosierdiferenca reÄimo estas modifebla"
+
+msgid "E100: No other buffer in diff mode"
+msgstr "E100: Neniu alia bufro en dosierdiferenca reÄimo"
+
+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"
+
+#, c-format
+msgid "E102: Can't find buffer \"%s\""
+msgstr "E102: Ne eblas trovi bufron \"%s\""
+
+#, c-format
+msgid "E103: Buffer \"%s\" is not in diff mode"
+msgstr "E103: Bufro \"%s\" ne estas en dosierdiferenca reÄimo"
+
+msgid "E787: Buffer changed unexpectedly"
+msgstr "E787: Bufro ÅanÄiÄis neatendite"
+
+msgid "E104: Escape not allowed in digraph"
+msgstr "E104: Eskapsigno nepermesebla en duliteraĵo"
+
+msgid "E544: Keymap file not found"
+msgstr "E544: Dosiero de klavmapo ne troveblas"
+
+msgid "E105: Using :loadkeymap not in a sourced file"
+msgstr "E105: Uzo de \":loadkeymap\" nur eblas en vim-skripto"
+
+msgid "E791: Empty keymap entry"
+msgstr "E791: Malplena rikordo en klavmapo"
+
+msgid " Keyword completion (^N^P)"
+msgstr " Kompletigo de Ålosilvorto (^N^P)"
+
+#. ctrl_x_mode == 0, ^P/^N compl.
+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)"
+
+msgid " Whole line completion (^L^N^P)"
+msgstr " Kompletigo de tuta linio (^L^N^P)"
+
+msgid " File name completion (^F^N^P)"
+msgstr " Kompletigo de dosiernomo (^F^N^P)"
+
+msgid " Tag completion (^]^N^P)"
+msgstr " Kompletigo de etikedo (^]^N^P)"
+
+msgid " Path pattern completion (^N^P)"
+msgstr " Kompletigo de Åablona dosierindiko (^N^P)"
+
+msgid " Definition completion (^D^N^P)"
+msgstr " Kompletigo de difino (^D^N^P)"
+
+msgid " Dictionary completion (^K^N^P)"
+msgstr " Kompletigo de vortaro (^K^N^P)"
+
+msgid " Thesaurus completion (^T^N^P)"
+msgstr " Kompletigo de tezaÅ­ro (^T^N^P)"
+
+msgid " Command-line completion (^V^N^P)"
+msgstr " Kompletigo de komanda linio (^V^N^P)"
+
+msgid " User defined completion (^U^N^P)"
+msgstr " Kompletigo difinita de uzanto (^U^N^P)"
+
+# DP: Ĉu eblas trovi pli bonan tradukon?
+msgid " Omni completion (^O^N^P)"
+msgstr " Kompletigo Omni (^O^N^P)"
+
+msgid " Spelling suggestion (s^N^P)"
+msgstr " Sugesto de literumo (s^N^P)"
+
+msgid " Keyword Local completion (^N^P)"
+msgstr " Kompletigo loka de Ålosilvorto (^N/^P)"
+
+msgid "Hit end of paragraph"
+msgstr "Atingis finon de alineo"
+
+msgid "E839: Completion function changed window"
+msgstr "E839: Kompletiga funkcio ÅanÄis la fenestron"
+
+msgid "E840: Completion function deleted text"
+msgstr "E840: Kompletiga funkcio forviÅis tekston"
+
+msgid "'dictionary' option is empty"
+msgstr "La opcio 'dictionary' estas malplena"
+
+msgid "'thesaurus' option is empty"
+msgstr "La opcio 'thesaurus' estas malplena"
+
+#, c-format
+msgid "Scanning dictionary: %s"
+msgstr "Analizas vortaron: %s"
+
+msgid " (insert) Scroll (^E/^Y)"
+msgstr " (enmeto) Rulumo (^E/^Y)"
+
+msgid " (replace) Scroll (^E/^Y)"
+msgstr " (anstataÅ­igo) Rulumo (^E/^Y)"
+
+#, c-format
+msgid "Scanning: %s"
+msgstr "Analizas: %s"
+
+msgid "Scanning tags."
+msgstr "Analizas etikedojn."
+
+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.
+#.
+msgid "-- Searching..."
+msgstr "-- Serĉanta..."
+
+msgid "Back at original"
+msgstr "Reveninta al originalo"
+
+msgid "Word from other line"
+msgstr "Vorto el alia linio"
+
+msgid "The only match"
+msgstr "La sola kongruo"
+
+#, c-format
+msgid "match %d of %d"
+msgstr "kongruo %d de %d"
+
+#, c-format
+msgid "match %d"
+msgstr "kongruo %d"
+
+msgid "E18: Unexpected characters in :let"
+msgstr "E18: Neatenditaj signoj en \":let\""
+
+#, c-format
+msgid "E684: list index out of range: %ld"
+msgstr "E684: indekso de listo ekster limoj: %ld"
+
+#, c-format
+msgid "E121: Undefined variable: %s"
+msgstr "E121: Nedifinita variablo: %s"
+
+msgid "E111: Missing ']'"
+msgstr "E111: Mankas ']'"
+
+#, c-format
+msgid "E686: Argument of %s must be a List"
+msgstr "E686: Argumento de %s devas esti Listo"
+
+#, c-format
+msgid "E712: Argument of %s must be a List or Dictionary"
+msgstr "E712: Argumento de %s devas esti Listo aÅ­ Vortaro"
+
+msgid "E713: Cannot use empty key for Dictionary"
+msgstr "E713: Ne eblas uzi malplenan Ålosilon de Vortaro"
+
+msgid "E714: List required"
+msgstr "E714: Listo bezonata"
+
+msgid "E715: Dictionary required"
+msgstr "E715: Vortaro bezonata"
+
+#, c-format
+msgid "E118: Too many arguments for function: %s"
+msgstr "E118: Tro da argumentoj por funkcio: %s"
+
+#, c-format
+msgid "E716: Key not present in Dictionary: %s"
+msgstr "E716: Åœlosilo malekzistas en Vortaro: %s"
+
+#, 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"
+
+msgid "E719: Cannot use [:] with a Dictionary"
+msgstr "E719: Uzo de [:] ne eblas kun Vortaro"
+
+#, c-format
+msgid "E734: Wrong variable type for %s="
+msgstr "E734: Nevalida datumtipo de variablo de %s="
+
+#, c-format
+msgid "E130: Unknown function: %s"
+msgstr "E130: Nekonata funkcio: %s"
+
+#, c-format
+msgid "E461: Illegal variable name: %s"
+msgstr "E461: Nevalida nomo de variablo: %s"
+
+msgid "E687: Less targets than List items"
+msgstr "E687: Malpli da celoj ol Listeroj"
+
+msgid "E688: More targets than List items"
+msgstr "E688: Pli da celoj ol Listeroj"
+
+msgid "Double ; in list of variables"
+msgstr "Duobla ; en listo de variabloj"
+
+#, c-format
+msgid "E738: Can't list variables for %s"
+msgstr "E738: Ne eblas listigi variablojn de %s"
+
+msgid "E689: Can only index a List or Dictionary"
+msgstr "E689: Nur eblas indeksi Liston aÅ­ Vortaron"
+
+msgid "E708: [:] must come last"
+msgstr "E708: [:] devas esti laste"
+
+msgid "E709: [:] requires a List value"
+msgstr "E709: [:] bezonas listan valoron"
+
+msgid "E710: List value has more items than target"
+msgstr "E710: Lista valoro havas pli da eroj ol la celo"
+
+msgid "E711: List value has not enough items"
+msgstr "E711: Lista valoro ne havas sufiĉe da eroj"
+
+msgid "E690: Missing \"in\" after :for"
+msgstr "E690: \"in\" mankas post \":for\""
+
+#, c-format
+msgid "E107: Missing parentheses: %s"
+msgstr "E107: Mankas krampoj: %s"
+
+#, c-format
+msgid "E108: No such variable: \"%s\""
+msgstr "E108: Ne estas tia variablo: \"%s\""
+
+msgid "E743: variable nested too deep for (un)lock"
+msgstr "E743: variablo ingita tro profunde por malÅlosi"
+
+msgid "E109: Missing ':' after '?'"
+msgstr "E109: Mankas ':' post '?'"
+
+msgid "E691: Can only compare List with List"
+msgstr "E691: Eblas nur kompari Liston kun Listo"
+
+msgid "E692: Invalid operation for Lists"
+msgstr "E692: Nevalida operacio de Listoj"
+
+msgid "E735: Can only compare Dictionary with Dictionary"
+msgstr "E735: Eblas nur kompari Vortaron kun Vortaro"
+
+msgid "E736: Invalid operation for Dictionary"
+msgstr "E736: Nevalida operacio de Vortaro"
+
+msgid "E693: Can only compare Funcref with Funcref"
+msgstr "E693: Eblas nur kompari Funcref kun Funcref"
+
+msgid "E694: Invalid operation for Funcrefs"
+msgstr "E694: Nevalida operacio de Funcref-oj"
+
+msgid "E804: Cannot use '%' with Float"
+msgstr "E804: Ne eblas uzi '%' kun Glitpunktnombro"
+
+msgid "E110: Missing ')'"
+msgstr "E110: Mankas ')'"
+
+msgid "E695: Cannot index a Funcref"
+msgstr "E695: Ne eblas indeksi Funcref"
+
+#, c-format
+msgid "E112: Option name missing: %s"
+msgstr "E112: Mankas nomo de opcio: %s"
+
+#, c-format
+msgid "E113: Unknown option: %s"
+msgstr "E113: Nekonata opcio: %s"
+
+#, c-format
+msgid "E114: Missing quote: %s"
+msgstr "E114: Mankas citilo: %s"
+
+#, c-format
+msgid "E115: Missing quote: %s"
+msgstr "E115: Mankas citilo: %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"
+
+#, 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 "E724: variable nested too deep for displaying"
+msgstr "E724: variablo ingita tro profunde por vidigi"
+
+#, 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"
+
+#, c-format
+msgid "E117: Unknown function: %s"
+msgstr "E117: Nekonata funkcio: %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 "E808: Number or Float required"
+msgstr "E808: Nombro aÅ­ Glitpunktnombro bezonata"
+
+msgid "add() argument"
+msgstr "argumento de add()"
+
+msgid "E699: Too many arguments"
+msgstr "E699: Tro da argumentoj"
+
+msgid "E785: complete() can only be used in Insert mode"
+msgstr "E785: complete() uzeblas nur en Enmeta reÄimo"
+
+#.
+#. * 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 "&Bone"
+
+msgid "extend() argument"
+msgstr "argumento de extend()"
+
+#, c-format
+msgid "E737: Key already exists: %s"
+msgstr "E737: Åœlosilo jam ekzistas: %s"
+
+msgid "map() argument"
+msgstr "argumento de map()"
+
+msgid "filter() argument"
+msgstr "argumento de filter()"
+
+#, c-format
+msgid "+-%s%3ld lines: "
+msgstr "+-%s%3ld linioj: "
+
+#, c-format
+msgid "E700: Unknown function: %s"
+msgstr "E700: Nekonata funkcio: %s"
+
+msgid ""
+"&OK\n"
+"&Cancel"
+msgstr ""
+"&Bone\n"
+"&Rezigni"
+
+msgid "called inputrestore() more often than inputsave()"
+msgstr "alvokis inputrestore() pli ofte ol inputsave()"
+
+msgid "insert() argument"
+msgstr "argumento de insert()"
+
+msgid "E786: Range not allowed"
+msgstr "E786: Amplekso nepermesebla"
+
+msgid "E701: Invalid type for len()"
+msgstr "E701: Nevalida datumtipo de len()"
+
+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 Vim server"
+msgstr "E240: Neniu konekto al Vim-servilo"
+
+#, c-format
+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 "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"
+
+msgid "sort() argument"
+msgstr "argumento de sort()"
+
+msgid "E702: Sort compare function failed"
+msgstr "E702: Ordiga funkcio fiaskis"
+
+msgid "(Invalid)"
+msgstr "(Nevalida)"
+
+msgid "E677: Error writing temp file"
+msgstr "E677: Eraro dum skribo de provizora dosiero"
+
+msgid "E805: Using a Float as a Number"
+msgstr "E805: Uzo de Glitpunktnombro kiel Nombro"
+
+msgid "E703: Using a Funcref as a Number"
+msgstr "E703: Uzo de Funcref kiel Nombro"
+
+msgid "E745: Using a List as a Number"
+msgstr "E745: Uzo de Listo kiel Nombro"
+
+msgid "E728: Using a Dictionary as a Number"
+msgstr "E728: Uzo de Vortaro kiel Nombro"
+
+msgid "E729: using Funcref as a String"
+msgstr "E729: uzo de Funcref kiel Ĉeno"
+
+msgid "E730: using List as a String"
+msgstr "E730: uzo de Listo kiel Ĉeno"
+
+msgid "E731: using Dictionary as a String"
+msgstr "E731: uzo de Vortaro kiel Ĉeno"
+
+msgid "E806: using Float as a String"
+msgstr "E806: uzo de Glitpunktnombro kiel Ĉeno"
+
+#, c-format
+msgid "E706: Variable type mismatch for: %s"
+msgstr "E706: Nekongrua datumtipo de variablo: %s"
+
+#, c-format
+msgid "E795: Cannot delete variable %s"
+msgstr "E795: Ne eblas forviÅi variablon %s"
+
+#, 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"
+
+#, c-format
+msgid "E705: Variable name conflicts with existing function: %s"
+msgstr "E705: Nomo de variablo konfliktas kun ekzistanta funkcio: %s"
+
+#, c-format
+msgid "E741: Value is locked: %s"
+msgstr "E741: Valoro estas Ålosita: %s"
+
+msgid "Unknown"
+msgstr "Nekonata"
+
+#, c-format
+msgid "E742: Cannot change value of %s"
+msgstr "E742: Ne eblas ÅanÄi valoron de %s"
+
+msgid "E698: variable nested too deep for making a copy"
+msgstr "E698: variablo ingita tro profunde por fari kopion"
+
+#, 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 "E125: Illegal argument: %s"
+msgstr "E125: Nevalida argumento: %s"
+
+#, c-format
+msgid "E853: Duplicate argument name: %s"
+msgstr "E853: Ripetita nomo de argumento: %s"
+
+msgid "E126: Missing :endfunction"
+msgstr "E126: Mankas \":endfunction\""
+
+#, 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"
+
+msgid "E129: Function name required"
+msgstr "E129: Nomo de funkcio bezonata"
+
+#, c-format
+msgid "E128: Function name must start with a capital or contain a colon: %s"
+msgstr "E128: Nomo de funkcio devas eki per majusklo aÅ­ enhavi dupunkton: %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 "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"
+
+#, c-format
+msgid "continuing in %s"
+msgstr "daÅ­rigas en %s"
+
+msgid "E133: :return not inside a function"
+msgstr "E133: \":return\" ekster funkcio"
+
+msgid ""
+"\n"
+"# global variables:\n"
+msgstr ""
+"\n"
+"# mallokaj variabloj:\n"
+
+msgid ""
+"\n"
+"\tLast set from "
+msgstr ""
+"\n"
+"\tLaste Åaltita de "
+
+msgid "No old files"
+msgstr "Neniu malnova dosiero"
+
+#, c-format
+msgid "<%s>%s%s %d, Hex %02x, Octal %03o"
+msgstr "<%s>%s%s %d, Deksesuma %02x, Okuma %03o"
+
+#, c-format
+msgid "> %d, Hex %04x, Octal %o"
+msgstr "> %d, Deksesuma %04x, Okuma %o"
+
+#, c-format
+msgid "> %d, Hex %08x, Octal %o"
+msgstr "> %d, Deksesuma %08x, Okuma %o"
+
+msgid "E134: Move lines into themselves"
+msgstr "E134: Movas liniojn en ilin mem"
+
+msgid "1 line moved"
+msgstr "1 linio movita"
+
+#, c-format
+msgid "%ld lines moved"
+msgstr "%ld linioj movitaj"
+
+#, c-format
+msgid "%ld lines filtered"
+msgstr "%ld linioj filtritaj"
+
+msgid "E135: *Filter* Autocommands must not change current buffer"
+msgstr "E135: *Filtraj* AÅ­tokomandoj ne rajtas ÅanÄi aktualan bufron"
+
+msgid "[No write since last change]\n"
+msgstr "[Neniu skribo de post lasta ÅanÄo]\n"
+
+#, c-format
+msgid "%sviminfo: %s in line: "
+msgstr "%sviminfo: %s en linio: "
+
+msgid "E136: viminfo: Too many errors, skipping rest of file"
+msgstr "E136: viminfo: Tro da eraroj, nun ignoras la reston de la dosiero"
+
+#, c-format
+msgid "Reading viminfo file \"%s\"%s%s%s"
+msgstr "Legado de dosiero viminfo \"%s\"%s%s%s"
+
+msgid " info"
+msgstr " informo"
+
+msgid " marks"
+msgstr " markoj"
+
+msgid " oldfiles"
+msgstr " malnovaj dosieroj"
+
+msgid " FAILED"
+msgstr " FIASKIS"
+
+#. avoid a wait_return for this message, it's annoying
+#, c-format
+msgid "E137: Viminfo file is not writable: %s"
+msgstr "E137: Dosiero viminfo ne skribeblas: %s"
+
+#, c-format
+msgid "E138: Can't write viminfo file %s!"
+msgstr "E138: Ne eblas skribi dosieron viminfo %s!"
+
+#, c-format
+msgid "Writing viminfo file \"%s\""
+msgstr "Skribas dosieron viminfo \"%s\""
+
+#. Write the info:
+#, c-format
+msgid "# This viminfo file was generated by Vim %s.\n"
+msgstr "# Tiu dosiero viminfo estis kreita de Vim %s.\n"
+
+msgid ""
+"# You may edit it if you're careful!\n"
+"\n"
+msgstr ""
+"# Vi povas redakti Äin se vi estas singarda.\n"
+"\n"
+
+msgid "# Value of 'encoding' when this file was written\n"
+msgstr "# Valoro de 'encoding' kiam tiu dosiero estis kreita\n"
+
+msgid "Illegal starting char"
+msgstr "Nevalida eka signo"
+
+msgid "Save As"
+msgstr "Konservi kiel"
+
+msgid "Write partial file?"
+msgstr "Ĉu skribi partan dosieron?"
+
+msgid "E140: Use ! to write partial buffer"
+msgstr "E140: Uzu ! por skribi partan bufron"
+
+#, c-format
+msgid "Overwrite existing file \"%s\"?"
+msgstr "Ĉu anstataŭigi ekzistantan dosieron \"%s\"?"
+
+#, c-format
+msgid "Swap file \"%s\" exists, overwrite anyway?"
+msgstr "Permutodosiero .swp \"%s\" ekzistas, ĉu tamen anstataÅ­igi Äin?"
+
+#, c-format
+msgid "E768: Swap file exists: %s (:silent! overrides)"
+msgstr "E768: Permutodosiero .swp ekzistas: %s (:silent! por transpasi)"
+
+#, c-format
+msgid "E141: No file name for buffer %ld"
+msgstr "E141: Neniu dosiernomo de bufro %ld"
+
+msgid "E142: File not written: Writing is disabled by 'write' option"
+msgstr "E142: Dosiero ne skribita: Skribo malÅaltita per la opcio 'write'"
+
+#, c-format
+msgid ""
+"'readonly' option is set for \"%s\".\n"
+"Do you wish to write anyway?"
+msgstr ""
+"La opcio 'readonly' estas Åaltita por \"%s\".\n"
+"Ĉu vi tamen volas skribi?"
+
+#, 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 ""
+"Permesoj de dosiero \"%s\" estas nur-legeblaj.\n"
+"BonÅance Äi eble skribeblus.\n"
+"Ĉu vi volas provi?"
+
+#, c-format
+msgid "E505: \"%s\" is read-only (add ! to override)"
+msgstr "E505: \"%s\" estas nurlegebla (aldonu ! por transpasi)"
+
+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"
+
+msgid "E144: non-numeric argument to :z"
+msgstr "E144: nenumera argumento de :z"
+
+msgid "E145: Shell commands not allowed in rvim"
+msgstr "E145: Åœelkomandoj nepermeseblaj en rvim"
+
+msgid "E146: Regular expressions can't be delimited by letters"
+msgstr "E146: Ne eblas limigi regulesprimon per literoj"
+
+#, 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)?"
+
+msgid "(Interrupted) "
+msgstr "(Interrompita) "
+
+msgid "1 match"
+msgstr "1 kongruo"
+
+msgid "1 substitution"
+msgstr "1 anstataÅ­igo"
+
+#, c-format
+msgid "%ld matches"
+msgstr "%ld kongruoj"
+
+#, c-format
+msgid "%ld substitutions"
+msgstr "%ld anstataÅ­igoj"
+
+msgid " on 1 line"
+msgstr " en 1 linio"
+
+#, c-format
+msgid " on %ld lines"
+msgstr " en %ld linioj"
+
+msgid "E147: Cannot do :global recursive"
+msgstr "E147: Ne eblas fari \":global\" rekursie"
+
+# DP: global estas por ":global" do mi ne tradukis Äin
+msgid "E148: Regular expression missing from global"
+msgstr "E148: Regulesprimo mankas el global"
+
+#, c-format
+msgid "Pattern found in every line: %s"
+msgstr "Ŝablono trovita en ĉiuj linioj: %s"
+
+#, c-format
+msgid "Pattern not found: %s"
+msgstr "Åœablono ne trovita: %s"
+
+msgid ""
+"\n"
+"# Last Substitute String:\n"
+"$"
+msgstr ""
+"\n"
+"# Lasta anstataŭigita ĉeno:\n"
+"$"
+
+# This message should *so* be E42!
+msgid "E478: Don't panic!"
+msgstr "E478: Ne paniku!"
+
+#, c-format
+msgid "E661: Sorry, no '%s' help for %s"
+msgstr "E661: BedaÅ­rinde estas neniu helpo '%s' por %s"
+
+#, c-format
+msgid "E149: Sorry, no help for %s"
+msgstr "E149: BedaÅ­rinde estas neniu helpo por %s"
+
+#, c-format
+msgid "Sorry, help file \"%s\" not found"
+msgstr "BedaÅ­rinde, la helpdosiero \"%s\" ne troveblas"
+
+#, c-format
+msgid "E150: Not a directory: %s"
+msgstr "E150: Ne estas dosierujo: %s"
+
+#, c-format
+msgid "E152: Cannot open %s for writing"
+msgstr "E152: Ne eblas malfermi %s en skribreÄimo"
+
+#, c-format
+msgid "E153: Unable to open %s for reading"
+msgstr "E153: Ne eblas malfermi %s en legreÄimo"
+
+#, 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"
+
+#, c-format
+msgid "E154: Duplicate tag \"%s\" in file %s/%s"
+msgstr "E154: Ripetita etikedo \"%s\" en dosiero %s/%s"
+
+#, c-format
+msgid "E160: Unknown sign command: %s"
+msgstr "E160: Nekonata simbola komando: %s"
+
+msgid "E156: Missing sign name"
+msgstr "E156: Mankas nomo de simbolo"
+
+msgid "E612: Too many signs defined"
+msgstr "E612: Tro da simboloj estas difinitaj"
+
+#, c-format
+msgid "E239: Invalid sign text: %s"
+msgstr "E239: Nevalida teksto de simbolo: %s"
+
+#, c-format
+msgid "E155: Unknown sign: %s"
+msgstr "E155: Nekonata simbolo: %s"
+
+msgid "E159: Missing sign number"
+msgstr "E159: Mankas numero de simbolo"
+
+#, c-format
+msgid "E158: Invalid buffer name: %s"
+msgstr "E158: Nevalida nomo de bufro: %s"
+
+#, c-format
+msgid "E157: Invalid sign ID: %ld"
+msgstr "E157: Nevalida identigilo de simbolo: %ld"
+
+msgid " (NOT FOUND)"
+msgstr " (NETROVITA)"
+
+msgid " (not supported)"
+msgstr " (nesubtenata)"
+
+msgid "[Deleted]"
+msgstr "[ForviÅita]"
+
+msgid "Entering Debug mode. Type \"cont\" to continue."
+msgstr "Eniras sencimigan reÄimon. Tajpu \"cont\" por daÅ­rigi."
+
+#, c-format
+msgid "line %ld: %s"
+msgstr "linio %ld: %s"
+
+#, c-format
+msgid "cmd: %s"
+msgstr "kmd: %s"
+
+#, c-format
+msgid "Breakpoint in \"%s%s\" line %ld"
+msgstr "Kontrolpunkto en \"%s%s\" linio %ld"
+
+#, c-format
+msgid "E161: Breakpoint not found: %s"
+msgstr "E161: Kontrolpunkto ne trovita: %s"
+
+msgid "No breakpoints defined"
+msgstr "Neniu kontrolpunkto estas difinita"
+
+#, c-format
+msgid "%3d %s %s line %ld"
+msgstr "%3d %s %s linio %ld"
+
+msgid "E750: First use \":profile start {fname}\""
+msgstr "E750: Uzu unue \":profile start {dosiernomo}\""
+
+#, c-format
+msgid "Save changes to \"%s\"?"
+msgstr "Ĉu konservi ÅanÄojn al \"%s\"?"
+
+msgid "Untitled"
+msgstr "Sen titolo"
+
+#, 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\""
+
+msgid "Warning: Entered other buffer unexpectedly (check autocommands)"
+msgstr "Averto: Eniris neatendite alian bufron (kontrolu aÅ­tokomandojn)"
+
+msgid "E163: There is only one file to edit"
+msgstr "E163: Estas nur unu redaktenda dosiero"
+
+msgid "E164: Cannot go before first file"
+msgstr "E164: Ne eblas iri antaÅ­ ol la unuan dosieron"
+
+msgid "E165: Cannot go beyond last file"
+msgstr "E165: Ne eblas iri preter la lastan dosieron"
+
+#, c-format
+msgid "E666: compiler not supported: %s"
+msgstr "E666: kompililo nesubtenata: %s"
+
+#, c-format
+msgid "Searching for \"%s\" in \"%s\""
+msgstr "Serĉado de \"%s\" en \"%s\""
+
+#, c-format
+msgid "Searching for \"%s\""
+msgstr "Serĉado de \"%s\""
+
+#, c-format
+msgid "not found in 'runtimepath': \"%s\""
+msgstr "ne trovita en 'runtimepath': \"%s\""
+
+msgid "Source Vim script"
+msgstr "Ruli Vim-skripton"
+
+#, c-format
+msgid "Cannot source a directory: \"%s\""
+msgstr "Ne eblas ruli dosierujon: \"%s\""
+
+#, c-format
+msgid "could not source \"%s\""
+msgstr "ne eblis ruli \"%s\""
+
+#, c-format
+msgid "line %ld: could not source \"%s\""
+msgstr "linio %ld: ne eblis ruli \"%s\""
+
+#, c-format
+msgid "sourcing \"%s\""
+msgstr "rulas \"%s\""
+
+#, c-format
+msgid "line %ld: sourcing \"%s\""
+msgstr "linio %ld: rulas \"%s\""
+
+#, c-format
+msgid "finished sourcing %s"
+msgstr "finis ruli %s"
+
+msgid "modeline"
+msgstr "reÄimlinio"
+
+msgid "--cmd argument"
+msgstr "--cmd argumento"
+
+msgid "-c argument"
+msgstr "-c argumento"
+
+msgid "environment variable"
+msgstr "medivariablo"
+
+msgid "error handler"
+msgstr "erartraktilo"
+
+msgid "W15: Warning: Wrong line separator, ^M may be missing"
+msgstr "W15: Averto: NeÄusta disigilo de linio, ^M eble mankas"
+
+msgid "E167: :scriptencoding used outside of a sourced file"
+msgstr "E167: \":scriptencoding\" uzita ekster rulita dosiero"
+
+msgid "E168: :finish used outside of a sourced file"
+msgstr "E168: \":finish\" uzita ekster rulita dosiero"
+
+#, c-format
+msgid "Current %slanguage: \"%s\""
+msgstr "Aktuala %slingvo: \"%s\""
+
+#, c-format
+msgid "E197: Cannot set language to \"%s\""
+msgstr "E197: Ne eblas ÅanÄi la lingvon al \"%s\""
+
+msgid "Entering Ex mode. Type \"visual\" to go to Normal mode."
+msgstr "Eniras reÄimon Ex. Tajpu \"visual\" por iri al reÄimo Normala."
+
+msgid "E501: At end-of-file"
+msgstr "E501: Ĉe fino-de-dosiero"
+
+msgid "E169: Command too recursive"
+msgstr "E169: Komando tro rekursia"
+
+#, c-format
+msgid "E605: Exception not caught: %s"
+msgstr "E605: Escepto nekaptita: %s"
+
+msgid "End of sourced file"
+msgstr "Fino de rulita dosiero"
+
+msgid "End of function"
+msgstr "Fino de funkcio"
+
+msgid "E464: Ambiguous use of user-defined command"
+msgstr "E464: Ambigua uzo de komando difinita de uzanto"
+
+msgid "E492: Not an editor command"
+msgstr "E492: Ne estas redaktila komando"
+
+msgid "E493: Backwards range given"
+msgstr "E493: Inversa amplekso donita"
+
+msgid "Backwards range given, OK to swap"
+msgstr "Inversa amplekso donita, permuteblas"
+
+msgid "E494: Use w or w>>"
+msgstr "E494: Uzu w aÅ­ w>>"
+
+msgid "E319: Sorry, the command is not available in this version"
+msgstr "E319: BedaÅ­rinde, tiu komando ne haveblas en tiu versio"
+
+msgid "E172: Only one file name allowed"
+msgstr "E172: Nur unu dosiernomo permesebla"
+
+msgid "1 more file to edit. Quit anyway?"
+msgstr "1 plia redaktenda dosiero. Ĉu tamen eliri?"
+
+#, c-format
+msgid "%d more files to edit. Quit anyway?"
+msgstr "%d pliaj redaktendaj dosieroj. Ĉu tamen eliri?"
+
+msgid "E173: 1 more file to edit"
+msgstr "E173: 1 plia redaktenda dosiero"
+
+#, c-format
+msgid "E173: %ld more files to edit"
+msgstr "E173: %ld pliaj redaktendaj dosieroj"
+
+msgid "E174: Command already exists: add ! to replace it"
+msgstr "E174: La komando jam ekzistas: aldonu ! por anstataÅ­igi Äin"
+
+# DP: malfacilas traduki tion, kaj samtempe honori spacetojn
+msgid ""
+"\n"
+" Name Args Range Complete Definition"
+msgstr ""
+"\n"
+" Nomo Arg Interv Kompleto Difino"
+
+msgid "No user-defined commands found"
+msgstr "Neniu komando difinita de uzanto trovita"
+
+msgid "E175: No attribute specified"
+msgstr "E175: Neniu atributo specifita"
+
+msgid "E176: Invalid number of arguments"
+msgstr "E176: Nevalida nombro de argumentoj"
+
+msgid "E177: Count cannot be specified twice"
+msgstr "E177: Kvantoro ne povas aperi dufoje"
+
+msgid "E178: Invalid default value for count"
+msgstr "E178: Nevalida defaÅ­lta valoro de kvantoro"
+
+msgid "E179: argument required for -complete"
+msgstr "E179: argumento bezonata por -complete"
+
+#, c-format
+msgid "E181: Invalid attribute: %s"
+msgstr "E181: Nevalida atributo: %s"
+
+msgid "E182: Invalid command name"
+msgstr "E182: Nevalida komanda nomo"
+
+msgid "E183: User defined commands must start with an uppercase letter"
+msgstr "E183: Komandoj difinataj de uzanto devas eki per majusklo"
+
+msgid "E841: Reserved name, cannot be used for user defined command"
+msgstr "E841: Rezervita nomo, neuzebla por komando difinita de uzanto"
+
+#, c-format
+msgid "E184: No such user-defined command: %s"
+msgstr "E184: Neniu komando-difinita-de-uzanto kiel: %s"
+
+#, c-format
+msgid "E180: Invalid complete value: %s"
+msgstr "E180: Nevalida valoro de kompletigo: %s"
+
+msgid "E468: Completion argument only allowed for custom completion"
+msgstr ""
+"E468: Argumento de kompletigo nur permesebla por kompletigo difinita de "
+"uzanto"
+
+msgid "E467: Custom completion requires a function argument"
+msgstr "E467: Uzula kompletigo bezonas funkcian argumenton"
+
+msgid "unknown"
+msgstr "nekonata"
+
+#, c-format
+msgid "E185: Cannot find color scheme '%s'"
+msgstr "E185: Ne eblas trovi agordaron de koloroj '%s'"
+
+msgid "Greetings, Vim user!"
+msgstr "Bonvenon, uzanto de Vim!"
+
+msgid "E784: Cannot close last tab page"
+msgstr "E784: Ne eblas fermi lastan langeton"
+
+msgid "Already only one tab page"
+msgstr "Jam nur unu langeto"
+
+msgid "Edit File in new window"
+msgstr "Redakti Dosieron en nova fenestro"
+
+#, c-format
+msgid "Tab page %d"
+msgstr "Langeto %d"
+
+msgid "No swap file"
+msgstr "Neniu permutodosiero .swp"
+
+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)"
+
+msgid "E186: No previous directory"
+msgstr "E186: Neniu antaÅ­a dosierujo"
+
+msgid "E187: Unknown"
+msgstr "E187: Nekonata"
+
+msgid "E465: :winsize requires two number arguments"
+msgstr "E465: \":winsize\" bezonas du numerajn argumentojn"
+
+#, 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"
+
+msgid "E466: :winpos requires two number arguments"
+msgstr "E466: \":winpos\" bezonas du numerajn argumentojn"
+
+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"
+
+#, c-format
+msgid "E189: \"%s\" exists (add ! to override)"
+msgstr "E189: \"%s\" ekzistas (aldonu ! por transpasi)"
+
+#, c-format
+msgid "E190: Cannot open \"%s\" for writing"
+msgstr "E190: Ne eblas malfermi \"%s\" por skribi"
+
+#. set mark
+msgid "E191: Argument must be a letter or forward/backward quote"
+msgstr "E191: Argumento devas esti litero, citilo aÅ­ retrocitilo"
+
+msgid "E192: Recursive use of :normal too deep"
+msgstr "E192: Tro profunda rekursia alvoko de \":normal\""
+
+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 '#'"
+
+msgid "E495: no autocommand file name to substitute for \"<afile>\""
+msgstr "E495: neniu dosiernomo de aÅ­tokomando por anstataÅ­igi al \"<afile>\""
+
+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
+msgid "E497: no autocommand match name to substitute for \"<amatch>\""
+msgstr ""
+"E497: neniu nomo de kongruo de aÅ­tokomando por anstataÅ­igi al \"<amatch>\""
+
+msgid "E498: no :source file name to substitute for \"<sfile>\""
+msgstr "E498: neniu dosiernomo \":source\" por anstataÅ­igi al \"<sfile>\""
+
+msgid "E842: no line number to use for \"<slnum>\""
+msgstr "E842: neniu uzebla numero de linio por \"<slnum>\""
+
+#, 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\""
+
+msgid "E500: Evaluates to an empty string"
+msgstr "E500: Liveras malplenan ĉenon"
+
+msgid "E195: Cannot open viminfo file for reading"
+msgstr "E195: Ne eblas malfermi dosieron viminfo en lega reÄimo"
+
+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
+#, c-format
+msgid "Exception thrown: %s"
+msgstr "Escepto lanĉita: %s"
+
+#, c-format
+msgid "Exception finished: %s"
+msgstr "Escepto finiÄis: %s"
+
+#, c-format
+msgid "Exception discarded: %s"
+msgstr "Escepto ne konservita: %s"
+
+#, c-format
+msgid "%s, line %ld"
+msgstr "%s, linio %ld"
+
+#. always scroll up, don't overwrite
+#, c-format
+msgid "Exception caught: %s"
+msgstr "Kaptis escepton: %s"
+
+#, c-format
+msgid "%s made pending"
+msgstr "%s iÄis atendanta(j)"
+
+#, c-format
+msgid "%s resumed"
+msgstr "%s daÅ­rigita(j)"
+
+#, c-format
+msgid "%s discarded"
+msgstr "%s ne konservita(j)"
+
+msgid "Exception"
+msgstr "Escepto"
+
+msgid "Error and interrupt"
+msgstr "Eraro kaj interrompo"
+
+msgid "Error"
+msgstr "Eraro"
+
+#. if (pending & CSTP_INTERRUPT)
+msgid "Interrupt"
+msgstr "Interrompo"
+
+msgid "E579: :if nesting too deep"
+msgstr "E579: \":if\" tro profunde ingita"
+
+msgid "E580: :endif without :if"
+msgstr "E580: \":endif\" sen \":if\""
+
+msgid "E581: :else without :if"
+msgstr "E581: \":else\" sen \":if\""
+
+msgid "E582: :elseif without :if"
+msgstr "E582: \":elseif\" sen \":if\""
+
+msgid "E583: multiple :else"
+msgstr "E583: pluraj \":else\""
+
+msgid "E584: :elseif after :else"
+msgstr "E584: \":elseif\" post \":else\""
+
+msgid "E585: :while/:for nesting too deep"
+msgstr "E585: \":while/:for\" ingita tro profunde"
+
+msgid "E586: :continue without :while or :for"
+msgstr "E586: \":continue\" sen \":while\" aÅ­ \":for\""
+
+msgid "E587: :break without :while or :for"
+msgstr "E587: \":break\" sen \":while\" aÅ­ \":for\""
+
+msgid "E732: Using :endfor with :while"
+msgstr "E732: Uzo de \":endfor\" kun \":while\""
+
+msgid "E733: Using :endwhile with :for"
+msgstr "E733: Uzo de \":endwhile\" kun \":for\""
+
+msgid "E601: :try nesting too deep"
+msgstr "E601: \":try\" ingita tro profunde"
+
+msgid "E603: :catch without :try"
+msgstr "E603: \":catch\" sen \":try\""
+
+#. Give up for a ":catch" after ":finally" and ignore it.
+#. * Just parse.
+msgid "E604: :catch after :finally"
+msgstr "E604: \":catch\" post \":finally\""
+
+msgid "E606: :finally without :try"
+msgstr "E606: \":finally\" sen \":try\""
+
+#. Give up for a multiple ":finally" and ignore it.
+msgid "E607: multiple :finally"
+msgstr "E607: pluraj \":finally\""
+
+msgid "E602: :endtry without :try"
+msgstr "E602: \":endtry\" sen \":try\""
+
+msgid "E193: :endfunction not inside a function"
+msgstr "E193: \":endfunction\" ekster funkcio"
+
+msgid "E788: Not allowed to edit another buffer now"
+msgstr "E788: Ne eblas redakti alian bufron nun"
+
+msgid "E811: Not allowed to change buffer information now"
+msgstr "E811: Ne eblas ÅanÄi informon de bufro nun"
+
+msgid "tagname"
+msgstr "nomo de etikedo"
+
+msgid " kind file\n"
+msgstr " tipo de dosiero\n"
+
+msgid "'history' option is zero"
+msgstr "opcio 'history' estas nul"
+
+#, c-format
+msgid ""
+"\n"
+"# %s History (newest to oldest):\n"
+msgstr ""
+"\n"
+"# Historio %s (de plej nova al plej malnova):\n"
+
+msgid "Command Line"
+msgstr "Komanda linio"
+
+msgid "Search String"
+msgstr "Serĉa ĉeno"
+
+msgid "Expression"
+msgstr "Esprimo"
+
+msgid "Input Line"
+msgstr "Eniga linio"
+
+msgid "E198: cmd_pchar beyond the command length"
+msgstr "E198: cmd_pchar preter la longo de komando"
+
+msgid "E199: Active window or buffer deleted"
+msgstr "E199: Aktiva fenestro aÅ­ bufro forviÅita"
+
+msgid "E812: Autocommands changed buffer or buffer name"
+msgstr "E812: AÅ­tokomandoj ÅanÄis bufron aÅ­ nomon de bufro"
+
+msgid "Illegal file name"
+msgstr "Nevalida dosiernomo"
+
+msgid "is a directory"
+msgstr "estas dosierujo"
+
+msgid "is not a file"
+msgstr "ne estas dosiero"
+
+msgid "is a device (disabled with 'opendevice' option)"
+msgstr "estas aparatdosiero (malÅaltita per la opcio 'opendevice')"
+
+msgid "[New File]"
+msgstr "[Nova dosiero]"
+
+msgid "[New DIRECTORY]"
+msgstr "[Nova DOSIERUJO]"
+
+msgid "[File too big]"
+msgstr "[Dosiero tro granda]"
+
+msgid "[Permission Denied]"
+msgstr "[Permeso rifuzita]"
+
+msgid "E200: *ReadPre autocommands made the file unreadable"
+msgstr "E200: La aÅ­tokomandoj *ReadPre igis la dosieron nelegebla"
+
+msgid "E201: *ReadPre autocommands must not change current buffer"
+msgstr "E201: La aÅ­tokomandoj *ReadPre ne rajtas ÅanÄi la aktualan bufron"
+
+msgid "Vim: Reading from stdin...\n"
+msgstr "Vim: Legado el stdin...\n"
+
+msgid "Reading from stdin..."
+msgstr "Legado el stdin..."
+
+#. Re-opening the original file failed!
+msgid "E202: Conversion made file unreadable!"
+msgstr "E202: Konverto igis la dosieron nelegebla!"
+
+msgid "[fifo/socket]"
+msgstr "[rektvica memoro/kontaktoskatolo]"
+
+msgid "[fifo]"
+msgstr "[rektvica memoro]"
+
+msgid "[socket]"
+msgstr "[kontaktoskatolo]"
+
+msgid "[character special]"
+msgstr "[speciala signo]"
+
+msgid "[RO]"
+msgstr "[Nurlegebla]"
+
+msgid "[CR missing]"
+msgstr "[CR mankas]"
+
+msgid "[long lines split]"
+msgstr "[divido de longaj linioj]"
+
+msgid "[NOT converted]"
+msgstr "[NE konvertita]"
+
+msgid "[converted]"
+msgstr "[konvertita]"
+
+msgid "[blowfish]"
+msgstr "[blowfish]"
+
+msgid "[crypted]"
+msgstr "[ĉifrita]"
+
+#, c-format
+msgid "[CONVERSION ERROR in line %ld]"
+msgstr "[ERARO DE KONVERTO en linio %ld]"
+
+#, c-format
+msgid "[ILLEGAL BYTE in line %ld]"
+msgstr "[NEVALIDA BAJTO en linio %ld]"
+
+msgid "[READ ERRORS]"
+msgstr "[ERAROJ DE LEGADO]"
+
+msgid "Can't find temp file for conversion"
+msgstr "Ne eblas trovi provizoran dosieron por konverti"
+
+msgid "Conversion with 'charconvert' failed"
+msgstr "Konverto kun 'charconvert' fiaskis"
+
+msgid "can't read output of 'charconvert'"
+msgstr "ne eblas legi la eligon de 'charconvert'"
+
+msgid "E821: File is encrypted with unknown method"
+msgstr "E821: Dosiero estas ĉifrata per nekonata metodo"
+
+msgid "E676: No matching autocommands for acwrite buffer"
+msgstr "E676: Neniu kongrua aÅ­tokomando por la bufro acwrite"
+
+msgid "E203: Autocommands deleted or unloaded buffer to be written"
+msgstr "E203: AÅ­tokomandoj forviÅis aÅ­ malÅargis la skribendan bufron"
+
+msgid "E204: Autocommand changed number of lines in unexpected way"
+msgstr "E204: AÅ­tokomando ÅanÄis la nombron de linioj neatendite"
+
+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"
+
+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)"
+
+msgid "E506: Can't write to backup file (add ! to override)"
+msgstr "E506: Ne eblas skribi restaÅ­rkopion (aldonu ! por transpasi)"
+
+msgid "E507: Close error for backup file (add ! to override)"
+msgstr "E507: Eraro dum fermo de restaÅ­rkopio (aldonu ! transpasi)"
+
+msgid "E508: Can't read file for backup (add ! to override)"
+msgstr "E508: Ne eblas legi restaÅ­rkopion (aldonu ! por transpasi)"
+
+msgid "E509: Cannot create backup file (add ! to override)"
+msgstr "E509: Ne eblas krei restaÅ­rkopion (aldonu ! por transpasi)"
+
+msgid "E510: Can't make backup file (add ! to override)"
+msgstr "E510: Ne eblas krei restaÅ­rkopion (aldonu ! por transpasi)"
+
+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"
+
+msgid "E213: Cannot convert (add ! to write without conversion)"
+msgstr "E213: Ne eblas konverti (aldonu ! por skribi sen konverto)"
+
+msgid "E166: Can't open linked file for writing"
+msgstr "E166: Ne eblas malfermi ligitan dosieron por skribi"
+
+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)
+msgid "E667: Fsync failed"
+msgstr "E667: Fsync fiaskis"
+
+msgid "E512: Close failed"
+msgstr "E512: Fermo fiaskis"
+
+msgid "E513: write error, conversion failed (make 'fenc' empty to override)"
+msgstr "E513: skriberaro, konverto fiaskis (igu 'fenc' malplena por transpasi)"
+
+#, c-format
+msgid ""
+"E513: write error, conversion failed in line %ld (make 'fenc' empty to "
+"override)"
+msgstr ""
+"E513: skriberaro, konverto fiaskis en linio %ld (igu 'fenc' malplena por "
+"transpasi)"
+
+msgid "E514: write error (file system full?)"
+msgstr "E514: skriberaro (ĉu plena dosiersistemo?)"
+
+msgid " CONVERSION ERROR"
+msgstr " ERARO DE KONVERTO"
+
+#, c-format
+msgid " in line %ld;"
+msgstr " en linio %ld;"
+
+msgid "[Device]"
+msgstr "[Aparatdosiero]"
+
+msgid "[New]"
+msgstr "[Nova]"
+
+msgid " [a]"
+msgstr " [a]"
+
+msgid " appended"
+msgstr " postaldonita(j)"
+
+msgid " [w]"
+msgstr " [s]"
+
+msgid " written"
+msgstr " skribita(j)"
+
+msgid "E205: Patchmode: can't save original file"
+msgstr "E205: Patchmode: ne eblas konservi originalan dosieron"
+
+msgid "E206: patchmode: can't touch empty original file"
+msgstr "E206: patchmode: ne eblas tuÅi malplenan originalan dosieron"
+
+msgid "E207: Can't delete backup file"
+msgstr "E207: Ne eblas forviÅi restaÅ­rkopion"
+
+msgid ""
+"\n"
+"WARNING: Original file may be lost or damaged\n"
+msgstr ""
+"\n"
+"AVERTO: Originala dosiero estas eble perdita aÅ­ difekta\n"
+
+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!"
+
+msgid "[dos]"
+msgstr "[dos]"
+
+msgid "[dos format]"
+msgstr "[formato dos]"
+
+msgid "[mac]"
+msgstr "[mac]"
+
+msgid "[mac format]"
+msgstr "[formato mac]"
+
+msgid "[unix]"
+msgstr "[unikso]"
+
+msgid "[unix format]"
+msgstr "[formato unikso]"
+
+msgid "1 line, "
+msgstr "1 linio, "
+
+#, c-format
+msgid "%ld lines, "
+msgstr "%ld linioj, "
+
+msgid "1 character"
+msgstr "1 signo"
+
+#, c-format
+msgid "%lld characters"
+msgstr "%lld signoj"
+
+#. Explicit typecast avoids warning on Mac OS X 10.6
+#, c-format
+msgid "%ld characters"
+msgstr "%ld signoj"
+
+msgid "[noeol]"
+msgstr "[sen EOL]"
+
+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
+msgid "WARNING: The file has been changed since reading it!!!"
+msgstr "AVERTO: La dosiero estas ÅanÄita de post kiam Äi estis legita!!!"
+
+msgid "Do you really want to write to it"
+msgstr "Ĉu vi vere volas skribi al Äi"
+
+#, c-format
+msgid "E208: Error writing to \"%s\""
+msgstr "E208: Eraro dum skribo de \"%s\""
+
+#, c-format
+msgid "E209: Error closing \"%s\""
+msgstr "E209: Eraro dum fermo de \"%s\""
+
+#, c-format
+msgid "E210: Error reading \"%s\""
+msgstr "E210: Eraro dum lego de \"%s\""
+
+msgid "E246: FileChangedShell autocommand deleted buffer"
+msgstr "E246: AÅ­tokomando FileChangedShell forviÅis bufron"
+
+#, c-format
+msgid "E211: File \"%s\" no longer available"
+msgstr "E211: Dosiero \"%s\" ne plu haveblas"
+
+#, c-format
+msgid ""
+"W12: Warning: File \"%s\" has changed and the buffer was changed in Vim as "
+"well"
+msgstr ""
+"W12: Averto: Dosiero \"%s\" ÅanÄiÄis kaj la bufro estis ÅanÄita ankaÅ­ en Vim"
+
+msgid "See \":help W12\" for more info."
+msgstr "Vidu \":help W12\" por pliaj informoj."
+
+#, c-format
+msgid "W11: Warning: File \"%s\" has changed since editing started"
+msgstr "W11: Averto: La dosiero \"%s\" ÅanÄiÄis ekde redakti Äin"
+
+msgid "See \":help W11\" for more info."
+msgstr "Vidu \":help W11\" por pliaj informoj."
+
+#, 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"
+
+msgid "See \":help W16\" for more info."
+msgstr "Vidu \":help W16\" por pliaj informoj."
+
+#, 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"
+
+msgid "Warning"
+msgstr "Averto"
+
+msgid ""
+"&OK\n"
+"&Load File"
+msgstr ""
+"&Bone\n"
+"Ŝ&argi Dosieron"
+
+#, c-format
+msgid "E462: Could not prepare for reloading \"%s\""
+msgstr "E462: Ne eblis prepari por reÅargi \"%s\""
+
+#, c-format
+msgid "E321: Could not reload \"%s\""
+msgstr "E321: Ne eblis reÅargi \"%s\""
+
+msgid "--Deleted--"
+msgstr "--ForviÅita--"
+
+#, c-format
+msgid "auto-removing autocommand: %s <buffer=%d>"
+msgstr "aÅ­to-forviÅas aÅ­tokomandon: %s <bufro=%d>"
+
+#. the group doesn't exist
+#, c-format
+msgid "E367: No such group: \"%s\""
+msgstr "E367: Ne ekzistas tia grupo: \"%s\""
+
+#, c-format
+msgid "E215: Illegal character after *: %s"
+msgstr "E215: Nevalida signo post *: %s"
+
+#, c-format
+msgid "E216: No such event: %s"
+msgstr "E216: Ne estas tia evento: %s"
+
+#, c-format
+msgid "E216: No such group or event: %s"
+msgstr "E216: Ne ekzistas tia grupo aÅ­ evento: %s"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Auto-Commands ---"
+msgstr ""
+"\n"
+"--- AÅ­to-Komandoj ---"
+
+#, c-format
+msgid "E680: <buffer=%d>: invalid buffer number "
+msgstr "E680: <bufro=%d>: nevalida numero de bufro "
+
+msgid "E217: Can't execute autocommands for ALL events"
+msgstr "E217: Ne eblas plenumi aŭtokomandojn por ĈIUJ eventoj"
+
+msgid "No matching autocommands"
+msgstr "Neniu kongrua aÅ­tokomando"
+
+msgid "E218: autocommand nesting too deep"
+msgstr "E218: aÅ­tokomando tro ingita"
+
+#, c-format
+msgid "%s Auto commands for \"%s\""
+msgstr "%s AÅ­tokomandoj por \"%s\""
+
+#, c-format
+msgid "Executing %s"
+msgstr "Plenumado de %s"
+
+#, c-format
+msgid "autocommand %s"
+msgstr "aÅ­tokomando %s"
+
+msgid "E219: Missing {."
+msgstr "E219: Mankas {."
+
+msgid "E220: Missing }."
+msgstr "E220: Mankas }."
+
+msgid "E490: No fold found"
+msgstr "E490: Neniu faldo trovita"
+
+msgid "E350: Cannot create fold with current 'foldmethod'"
+msgstr "E350: Ne eblas krei faldon per la aktuala 'foldmethod'"
+
+msgid "E351: Cannot delete fold with current 'foldmethod'"
+msgstr "E351: Ne eblas forviÅi faldon per la aktuala 'foldmethod'"
+
+#, c-format
+msgid "+--%3ld lines folded "
+msgstr "+--%3ld linioj falditaj "
+
+msgid "E222: Add to read buffer"
+msgstr "E222: Aldoni al lega bufro"
+
+msgid "E223: recursive mapping"
+msgstr "E223: rekursia mapo"
+
+#, c-format
+msgid "E224: global abbreviation already exists for %s"
+msgstr "E224: malloka mallongigo jam ekzistas por %s"
+
+#, c-format
+msgid "E225: global mapping already exists for %s"
+msgstr "E225: malloka mapo jam ekzistas por %s"
+
+#, c-format
+msgid "E226: abbreviation already exists for %s"
+msgstr "E226: mallongigo jam ekzistas por %s"
+
+#, c-format
+msgid "E227: mapping already exists for %s"
+msgstr "E227: mapo jam ekzistas por %s"
+
+msgid "No abbreviation found"
+msgstr "Neniu mallongigo trovita"
+
+msgid "No mapping found"
+msgstr "Neniu mapo trovita"
+
+msgid "E228: makemap: Illegal mode"
+msgstr "E228: makemap: Nevalida reÄimo"
+
+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"
+
+#, c-format
+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"
+
+#, c-format
+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> "
+
+#, c-format
+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"
+
+msgid ""
+"&Yes\n"
+"&No\n"
+"&Cancel"
+msgstr ""
+"&Jes\n"
+"&Ne\n"
+"&Rezigni"
+
+# 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:"
+
+#. whole word only button
+msgid "Match whole word only"
+msgstr "Kongrui kun nur plena vorto"
+
+#. match case button
+msgid "Match case"
+msgstr "Uskleca kongruo"
+
+msgid "Direction"
+msgstr "Direkto"
+
+#. 'Up' and 'Down' buttons
+msgid "Up"
+msgstr "Supren"
+
+msgid "Down"
+msgstr "Suben"
+
+#. 'Find Next' button
+msgid "Find Next"
+msgstr "Trovi sekvantan"
+
+#. 'Replace' button
+msgid "Replace"
+msgstr "AnstataÅ­igi"
+
+#. 'Replace All' button
+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"
+msgstr "Fermi"
+
+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"
+
+#, c-format
+msgid "E671: Cannot find window title \"%s\""
+msgstr "E671: Ne eblas trovi titolon de fenestro \"%s\""
+
+#, c-format
+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 "Close tab"
+msgstr "Fermi langeton"
+
+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 '\\')"
+
+#. 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 "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"
+
+#, 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:"
+
+#, c-format
+msgid "E252: Fontset name: %s"
+msgstr "E252: Nomo de tiparo: %s"
+
+#, c-format
+msgid "Font '%s' is not fixed-width"
+msgstr "Tiparo '%s' ne estas egallarÄa"
+
+#, c-format
+msgid "E253: Fontset name: %s\n"
+msgstr "E253: Nomo de tiparo: %s\n"
+
+#, c-format
+msgid "Font0: %s\n"
+msgstr "Font0: %s\n"
+
+#, c-format
+msgid "Font1: %s\n"
+msgstr "Font1: %s\n"
+
+#, c-format
+msgid "Font%ld width is not twice that of font0\n"
+msgstr "Font%ld ne estas duoble pli larÄa ol font0\n"
+
+#, c-format
+msgid "Font0 width: %ld\n"
+msgstr "LarÄo de font0: %ld\n"
+
+#, c-format
+msgid ""
+"Font1 width: %ld\n"
+"\n"
+msgstr ""
+"LarÄo de Font1: %ld\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:"
+
+#. create toggle button
+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 "E550: Missing colon"
+msgstr "E550: Mankas dupunkto"
+
+msgid "E551: Illegal component"
+msgstr "E551: Nevalida komponento"
+
+msgid "E552: digit expected"
+msgstr "E552: cifero atendita"
+
+#, c-format
+msgid "Page %d"
+msgstr "PaÄo %d"
+
+msgid "No text to be printed"
+msgstr "Neniu presenda teksto"
+
+#, c-format
+msgid "Printing page %d (%d%%)"
+msgstr "Presas paÄon %d (%d%%)"
+
+#, c-format
+msgid " Copy %d of %d"
+msgstr " Kopio %d de %d"
+
+#, c-format
+msgid "Printed: %s"
+msgstr "Presis: %s"
+
+msgid "Printing aborted"
+msgstr "Presado ĉesigita"
+
+msgid "E455: Error writing to PostScript output file"
+msgstr "E455: Eraro dum skribo de PostSkripta eliga dosiero"
+
+#, c-format
+msgid "E624: Can't open file \"%s\""
+msgstr "E624: Ne eblas malfermi dosieron \"%s\""
+
+#, c-format
+msgid "E457: Can't read PostScript resource file \"%s\""
+msgstr "E457: Ne eblas legi dosieron de PostSkripta rimedo \"%s\""
+
+#, c-format
+msgid "E618: file \"%s\" is not a PostScript resource file"
+msgstr "E618: \"%s\" ne estas dosiero de PostSkripta rimedo"
+
+#, c-format
+msgid "E619: file \"%s\" is not a supported PostScript resource file"
+msgstr "E619: \"%s\" ne estas subtenata dosiero de PostSkripta rimedo"
+
+#, c-format
+msgid "E621: \"%s\" resource file has wrong version"
+msgstr "E621: \"%s\" dosiero de rimedo havas neÄustan version"
+
+msgid "E673: Incompatible multi-byte encoding and character set."
+msgstr "E673: Nekongrua plurbajta kodoprezento kaj signaro."
+
+msgid "E674: printmbcharset cannot be empty with multi-byte encoding."
+msgstr ""
+"E674: printmbcharset ne rajtas esti malplena kun plurbajta kodoprezento."
+
+msgid "E675: No default font specified for multi-byte printing."
+msgstr "E675: Neniu defaÅ­lta tiparo specifita por plurbajta presado."
+
+msgid "E324: Can't open PostScript output file"
+msgstr "E324: Ne eblas malfermi eligan PostSkriptan dosieron"
+
+#, c-format
+msgid "E456: Can't open file \"%s\""
+msgstr "E456: Ne eblas malfermi dosieron \"%s\""
+
+msgid "E456: Can't find PostScript resource file \"prolog.ps\""
+msgstr "E456: Dosiero de PostSkripta rimedo \"prolog.ps\" ne troveblas"
+
+msgid "E456: Can't find PostScript resource file \"cidfont.ps\""
+msgstr "E456: Dosiero de PostSkripta rimedo \"cidfont.ps\" ne troveblas"
+
+#, c-format
+msgid "E456: Can't find PostScript resource file \"%s.ps\""
+msgstr "E456: Dosiero de PostSkripta rimedo \"%s.ps\" ne troveblas"
+
+#, c-format
+msgid "E620: Unable to convert to print encoding \"%s\""
+msgstr "E620: Ne eblas konverti al la presa kodoprezento \"%s\""
+
+msgid "Sending to printer..."
+msgstr "Sendas al presilo..."
+
+msgid "E365: Failed to print PostScript file"
+msgstr "E365: Presado de PostSkripta dosiero fiaskis"
+
+msgid "Print job sent."
+msgstr "Laboro de presado sendita."
+
+msgid "Add a new database"
+msgstr "Aldoni novan datumbazon"
+
+msgid "Query for a pattern"
+msgstr "Serĉi Åablonon"
+
+msgid "Show this message"
+msgstr "Montri tiun mesaÄon"
+
+msgid "Kill a connection"
+msgstr "Ĉesigi konekton"
+
+msgid "Reinit all connections"
+msgstr "Repravalorizi ĉiujn konektojn"
+
+msgid "Show connections"
+msgstr "Montri konektojn"
+
+#, c-format
+msgid "E560: Usage: cs[cope] %s"
+msgstr "E560: Uzo: cs[cope] %s"
+
+msgid "This cscope command does not support splitting the window.\n"
+msgstr "Tiu ĉi komando de cscope ne subtenas dividon de fenestro.\n"
+
+msgid "E562: Usage: cstag <ident>"
+msgstr "E562: Uzo: cstag <ident>"
+
+msgid "E257: cstag: tag not found"
+msgstr "E257: cstag: etikedo netrovita"
+
+#, c-format
+msgid "E563: stat(%s) error: %d"
+msgstr "E563: Eraro de stat(%s): %d"
+
+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"
+
+#, c-format
+msgid "Added cscope database %s"
+msgstr "Aldonis datumbazon de cscope %s"
+
+#, c-format
+msgid "E262: error reading cscope connection %ld"
+msgstr "E262: eraro dum legado de konekto de cscope %ld"
+
+msgid "E561: unknown cscope search type"
+msgstr "E561: nekonata tipo de serĉo de cscope"
+
+msgid "E566: Could not create cscope pipes"
+msgstr "E566: Ne eblis krei duktojn de cscope"
+
+msgid "E622: Could not fork for cscope"
+msgstr "E622: Ne eblis forki cscope"
+
+msgid "cs_create_connection exec failed"
+msgstr "plenumo de cs_create_connection fiaskis"
+
+msgid "cs_create_connection: fdopen for to_fp failed"
+msgstr "cs_create_connection: fdopen de to_fp fiaskis"
+
+msgid "cs_create_connection: fdopen for fr_fp failed"
+msgstr "cs_create_connection: fdopen de fr_fp fiaskis"
+
+msgid "E623: Could not spawn cscope process"
+msgstr "E623: Ne eblis naskigi procezon cscope"
+
+msgid "E567: no cscope connections"
+msgstr "E567: neniu konekto al cscope"
+
+#, c-format
+msgid "E469: invalid cscopequickfix flag %c for %c"
+msgstr "E469: nevalida flago cscopequickfix %c de %c"
+
+#, 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"
+
+msgid "cscope commands:\n"
+msgstr "komandoj de cscope:\n"
+
+#, c-format
+msgid "%-5s: %s%*s (Usage: %s)"
+msgstr "%-5s: %s%*s (Uzo: %s)"
+
+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: Trovi funkciojn, kiuj alvokas tiun funkcion\n"
+" d: Trovi funkciojn alvokataj de tiu funkcio\n"
+" e: Trovi tiun egrep-Åablonon\n"
+" f: Trovi tiun dosieron\n"
+" g: Trovi tiun difinon\n"
+" i: Trovi dosierojn, kiuj inkluzivas (#include) tiun dosieron\n"
+" s: Trovi tiun C-simbolon\n"
+" t: Trovi tiun ĉenon\n"
+
+#, 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"
+
+#, c-format
+msgid "E261: cscope connection %s not found"
+msgstr "E261: konekto cscope %s netrovita"
+
+#, c-format
+msgid "cscope connection %s closed"
+msgstr "konekto cscope %s fermita"
+
+#. should not reach here
+msgid "E570: fatal error in cs_manage_matches"
+msgstr "E570: neriparebla eraro en cs_manage_matches"
+
+#, c-format
+msgid "Cscope tag: %s"
+msgstr "Etikedo de cscope: %s"
+
+msgid ""
+"\n"
+" # line"
+msgstr ""
+"\n"
+" nro linio"
+
+msgid "filename / context / line\n"
+msgstr "dosiernomo / kunteksto / linio\n"
+
+#, c-format
+msgid "E609: Cscope error: %s"
+msgstr "E609: Eraro de cscope: %s"
+
+msgid "All cscope databases reset"
+msgstr "ReÅargo de ĉiuj datumbazoj de cscope"
+
+msgid "no cscope connections\n"
+msgstr "neniu konekto de cscope\n"
+
+msgid " # pid database name prepend path\n"
+msgstr " # pid nomo de datumbazo prefiksa vojo\n"
+
+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"
+
+#, c-format
+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"
+
+#, c-format
+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"
+
+#, 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"
+
+#. This should never happen. Famous last word?
+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 fiaskis"
+
+#, 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!"
+
+msgid "Unknown option argument"
+msgstr "Nekonata argumento de opcio"
+
+msgid "Too many edit arguments"
+msgstr "Tro da argumentoj de redakto"
+
+msgid "Argument missing after"
+msgstr "Argumento mankas post"
+
+msgid "Garbage after option argument"
+msgstr "Forĵetindaĵo post argumento de opcio"
+
+msgid "Too many \"+command\", \"-c command\" or \"--cmd command\" arguments"
+msgstr "Tro da argumentoj \"+komando\", \"-c komando\" aÅ­ \"--cmd komando\""
+
+msgid "Invalid argument for"
+msgstr "Nevalida argumento por"
+
+#, c-format
+msgid "%d files to edit\n"
+msgstr "%d redaktendaj dosieroj\n"
+
+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 "Attempt to open script file again: \""
+msgstr "Provas malfermi skriptan dosieron denove: \""
+
+msgid "Cannot open for reading: \""
+msgstr "Ne eblas malfermi en lega reÄimo: \""
+
+msgid "Cannot open for script output: \""
+msgstr "Ne eblas malfermi por eligo de skripto: \""
+
+msgid "Vim: Error: Failure to start gvim from NetBeans\n"
+msgstr "Vim: Eraro: Fiaskis lanĉi gvim el NetBeans\n"
+
+msgid "Vim: Warning: Output is not to a terminal\n"
+msgstr "Vim: Averto: Eligo ne estas al terminalo\n"
+
+msgid "Vim: Warning: Input is not from a terminal\n"
+msgstr "Vim: Averto: Enigo ne estas el terminalo\n"
+
+#. just in case..
+msgid "pre-vimrc command line"
+msgstr "komanda linio pre-vimrc"
+
+#, c-format
+msgid "E282: Cannot read from \"%s\""
+msgstr "E282: Ne eblas legi el \"%s\""
+
+msgid ""
+"\n"
+"More info with: \"vim -h\"\n"
+msgstr ""
+"\n"
+"Pliaj informoj per: \"vim -h\"\n"
+
+# DP: tajpu "vim --help" por testi tiujn mesaÄojn
+msgid "[file ..] edit specified file(s)"
+msgstr "[dosiero...] redakti specifita(j)n dosiero(j)n"
+
+msgid "- read text from stdin"
+msgstr "- legi tekston el stdin"
+
+msgid "-t tag edit file where tag is defined"
+msgstr "-t etikedo redakti dosieron kie etikedo estas difinata"
+
+msgid "-q [errorfile] edit file with first error"
+msgstr "-q [erardosiero] redakti dosieron kun unua eraro"
+
+msgid ""
+"\n"
+"\n"
+"usage:"
+msgstr ""
+"\n"
+"\n"
+" uzo:"
+
+msgid " vim [arguments] "
+msgstr " vim [argumentoj] "
+
+msgid ""
+"\n"
+" or:"
+msgstr ""
+"\n"
+" aÅ­:"
+
+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"
+"Arguments:\n"
+msgstr ""
+"\n"
+"\n"
+"Argumentoj:\n"
+
+msgid "--\t\t\tOnly file names after this"
+msgstr "--\t\t\tNur dosiernomoj post tio"
+
+msgid "--literal\t\tDon't expand wildcards"
+msgstr "--literal\t\tNe malvolvi ĵokerojn"
+
+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\")"
+
+msgid "-e\t\t\tEx mode (like \"ex\")"
+msgstr "-e\t\t\tReÄimo Ex (kiel \"ex\")"
+
+msgid "-E\t\t\tImproved Ex mode"
+msgstr "-E\t\t\tPlibonigita Ex-reÄimo"
+
+msgid "-s\t\t\tSilent (batch) mode (only for \"ex\")"
+msgstr "-s\t\t\tSilenta (stapla) reÄimo (nur por \"ex\")"
+
+msgid "-d\t\t\tDiff mode (like \"vimdiff\")"
+msgstr "-d\t\t\tKompara reÄimo (kiel \"vimdiff\")"
+
+msgid "-y\t\t\tEasy mode (like \"evim\", modeless)"
+msgstr "-y\t\t\tFacila reÄimo (kiel \"evim\", senreÄima)"
+
+msgid "-R\t\t\tReadonly mode (like \"view\")"
+msgstr "-R\t\t\tNurlegebla reÄimo (kiel \"view\")"
+
+msgid "-Z\t\t\tRestricted mode (like \"rvim\")"
+msgstr "-Z\t\t\tLimigita reÄimo (kiel \"rvim\")"
+
+msgid "-m\t\t\tModifications (writing files) not allowed"
+msgstr "-m\t\t\tÅœanÄoj (skribo al dosieroj) nepermeseblaj"
+
+msgid "-M\t\t\tModifications in text not allowed"
+msgstr "-M\t\t\tÅœanÄoj al teksto nepermeseblaj"
+
+msgid "-b\t\t\tBinary mode"
+msgstr "-b\t\t\tDuuma reÄimo"
+
+msgid "-l\t\t\tLisp mode"
+msgstr "-l\t\t\tReÄimo Lisp"
+
+msgid "-C\t\t\tCompatible with Vi: 'compatible'"
+msgstr "-C\t\t\tKongrua kun Vi: 'compatible'"
+
+msgid "-N\t\t\tNot fully Vi compatible: 'nocompatible'"
+msgstr "-N\t\t\tNe tute kongrua kun Vi: 'nocompatible'"
+
+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]"
+
+msgid "-D\t\t\tDebugging mode"
+msgstr "-D\t\t\tSencimiga reÄimo"
+
+msgid "-n\t\t\tNo swap file, use memory only"
+msgstr "-n\t\t\tNeniu permutodosiero .swp, uzas nur memoron"
+
+msgid "-r\t\t\tList swap files and exit"
+msgstr "-r\t\t\tListigi permutodosierojn .swp kaj eliri"
+
+msgid "-r (with file name)\tRecover crashed session"
+msgstr "-r (kun dosiernomo)\tRestaÅ­ri kolapsintan seancon"
+
+msgid "-L\t\t\tSame as -r"
+msgstr "-L\t\t\tKiel -r"
+
+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"
+
+msgid "-H\t\t\tStart in Hebrew mode"
+msgstr "-H\t\t\tKomenci en hebrea reÄimo"
+
+msgid "-F\t\t\tStart in Farsi mode"
+msgstr "-F\t\t\tKomenci en persa reÄimo"
+
+msgid "-T <terminal>\tSet terminal type to <terminal>"
+msgstr "-T <terminalo>\tAgordi terminalon al <terminalo>"
+
+msgid "-u <vimrc>\t\tUse <vimrc> instead of any .vimrc"
+msgstr "-u <vimrc>\t\tUzi <vimrc> anstataÅ­ iun ajn .vimrc"
+
+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"
+
+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)"
+
+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)"
+
+msgid "-O[N]\t\tLike -o but split vertically"
+msgstr "-O[N]\t\tKiel -o sed dividi vertikale"
+
+msgid "+\t\t\tStart at end of file"
+msgstr "+\t\t\tKomenci ĉe la fino de la dosiero"
+
+msgid "+<lnum>\t\tStart at line <lnum>"
+msgstr "+<numL>\t\tKomenci ĉe linio <numL>"
+
+msgid "--cmd <command>\tExecute <command> before loading any vimrc file"
+msgstr ""
+"--cmd <komando>\tPlenumi <komando>-n antaÅ­ ol Åargi iun ajn dosieron vimrc"
+
+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"
+
+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"
+
+msgid "-s <scriptin>\tRead Normal mode commands from file <scriptin>"
+msgstr "-s <skripto>\t\tLegi komandojn en Normala reÄimo el dosiero <skripto>"
+
+msgid "-w <scriptout>\tAppend all typed commands to file <scriptout>"
+msgstr ""
+"-w <eligaskripto>\tPostaldoni ĉiujn tajpitajn komandojn al dosiero "
+"<eligaskripto>"
+
+msgid "-W <scriptout>\tWrite all typed commands to file <scriptout>"
+msgstr ""
+"-W <eligaskripto>\tSkribi ĉiujn tajpitajn komandojn al dosiero <eligaskripto>"
+
+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>"
+
+msgid "-i <viminfo>\t\tUse <viminfo> instead of .viminfo"
+msgstr "-i <viminfo>\t\tUzi <viminfo> anstataÅ­ .viminfo"
+
+msgid "-h or --help\tPrint Help (this message) and exit"
+msgstr "-h aÅ­ --help\tAfiÅi Helpon (tiun mesaÄon) kaj eliri"
+
+msgid "--version\t\tPrint version information and exit"
+msgstr "--version\t\tAfiÅi informon de versio kaj eliri"
+
+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"
+
+#. Failed to send, abort.
+msgid ": Send failed.\n"
+msgstr ": Sendo fiaskis.\n"
+
+#. Let vim start normally.
+msgid ": Send failed. Trying to execute locally\n"
+msgstr ": Sendo fiaskis. 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 fiaskis.\n"
+
+msgid ": Send expression failed.\n"
+msgstr ": Sendado de esprimo fiaskis.\n"
+
+msgid "No marks set"
+msgstr "Neniu marko"
+
+#, c-format
+msgid "E283: No marks matching \"%s\""
+msgstr "E283: Neniu marko kongruas kun \"%s\""
+
+#. Highlight title
+msgid ""
+"\n"
+"mark line col file/text"
+msgstr ""
+"\n"
+"mark linio kol dosiero/teksto"
+
+#. Highlight title
+msgid ""
+"\n"
+" jump line col file/text"
+msgstr ""
+"\n"
+" salt linio kol dosiero/teksto"
+
+#. Highlight title
+msgid ""
+"\n"
+"change line col text"
+msgstr ""
+"\n"
+"ÅanÄo linio kol teksto"
+
+msgid ""
+"\n"
+"# File marks:\n"
+msgstr ""
+"\n"
+"# Markoj de dosiero:\n"
+
+#. Write the jumplist with -'
+msgid ""
+"\n"
+"# Jumplist (newest first):\n"
+msgstr ""
+"\n"
+"# Saltlisto (plej novaj unue):\n"
+
+msgid ""
+"\n"
+"# History of marks within files (newest to oldest):\n"
+msgstr ""
+"\n"
+"# Historio de markoj en dosieroj (de plej nova al plej malnova):\n"
+
+msgid "Missing '>'"
+msgstr "Mankas '>'"
+
+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: Ne eblis krei enigan kuntekston"
+
+msgid "E286: Failed to open input method"
+msgstr "E286: Ne eblis malfermi enigan metodon"
+
+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"
+
+msgid "E294: Seek error in swap file read"
+msgstr "E294: Eraro de enpoziciigo dum lego de permutodosiero .swp"
+
+msgid "E295: Read error in swap file"
+msgstr "E295: Eraro de lego en permutodosiero .swp"
+
+msgid "E296: Seek error in swap file write"
+msgstr "E296: Eraro de enpoziciigo dum skribo de permutodosiero .swp"
+
+msgid "E297: Write error in swap file"
+msgstr "E297: Skriberaro en permutodosiero .swp"
+
+msgid "E300: Swap file already exists (symlink attack?)"
+msgstr "E300: Permutodosiero .swp jam ekzistas (ĉu atako per simbola ligilo?)"
+
+msgid "E298: Didn't get block nr 0?"
+msgstr "E298: Ĉu ne akiris blokon n-ro 0?"
+
+msgid "E298: Didn't get block nr 1?"
+msgstr "E298: Ĉu ne akiris blokon n-ro 1?"
+
+msgid "E298: Didn't get block nr 2?"
+msgstr "E298: Ĉu ne akiris blokon n-ro 2?"
+
+msgid "E843: Error while updating swap file crypt"
+msgstr "E843: Eraro dum Äisdatigo de ĉifrada permutodosiero .swp"
+
+#. could not (re)open the swap file, what can we do????
+msgid "E301: Oops, lost the swap file!!!"
+msgstr "E301: Ve, perdis la permutodosieron .swp!!!"
+
+msgid "E302: Could not rename swap file"
+msgstr "E302: Ne eblis renomi la permutodosieron .swp"
+
+#, 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"
+
+msgid "E304: ml_upd_block0(): Didn't get block 0??"
+msgstr "E304: ml_upd_block0(): Ne akiris blokon 0??"
+
+#, c-format
+msgid "E305: No swap file found for %s"
+msgstr "E305: Neniu permutodosiero .swp trovita por %s"
+
+msgid "Enter number of swap file to use (0 to quit): "
+msgstr "Entajpu la uzendan numeron de permutodosiero .swp (0 por eliri): "
+
+#, c-format
+msgid "E306: Cannot open %s"
+msgstr "E306: Ne eblas malfermi %s"
+
+msgid "Unable to read block 0 from "
+msgstr "Ne eblas legi blokon 0 de "
+
+msgid ""
+"\n"
+"Maybe no changes were made or Vim did not update the swap file."
+msgstr ""
+"\n"
+"Eble neniu ÅanÄo estis farita aÅ­ Vim ne Äisdatigis la permutodosieron .swp."
+
+msgid " cannot be used with this version of Vim.\n"
+msgstr " ne uzeblas per tiu versio de vim.\n"
+
+msgid "Use Vim version 3.0.\n"
+msgstr "Uzu version 3.0 de Vim\n"
+
+#, c-format
+msgid "E307: %s does not look like a Vim swap file"
+msgstr "E307: %s ne aspektas kiel permutodosiero .swp de Vim"
+
+msgid " cannot be used on this computer.\n"
+msgstr " ne uzeblas per tiu komputilo.\n"
+
+msgid "The file was created on "
+msgstr "La dosiero estas kreita je "
+
+msgid ""
+",\n"
+"or the file has been damaged."
+msgstr ""
+",\n"
+"aÅ­ la dosiero estas difekta."
+
+#, c-format
+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 " has been damaged (page size is smaller than minimum value).\n"
+msgstr " difektiÄis (paÄa grando pli malgranda ol minimuma valoro).\n"
+
+#, c-format
+msgid "Using swap file \"%s\""
+msgstr "Uzado de permutodosiero .swp \"%s\""
+
+#, c-format
+msgid "Original file \"%s\""
+msgstr "Originala dosiero \"%s\""
+
+msgid "E308: Warning: Original file may have been changed"
+msgstr "E308: Averto: Originala dosiero eble ÅanÄiÄis"
+
+#, c-format
+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 ""
+"\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 permuto dosiero .swp"
+
+#, c-format
+msgid "E309: Unable to read block 1 from %s"
+msgstr "E309: Ne eblas legi blokon 1 de %s"
+
+msgid "???MANY LINES MISSING"
+msgstr "???MULTAJ LINIOJ MANKAS"
+
+msgid "???LINE COUNT WRONG"
+msgstr "???NOMBRO DE LINIOJ NE ÄœUSTAS"
+
+msgid "???EMPTY BLOCK"
+msgstr "???MALPLENA BLOKO"
+
+msgid "???LINES MISSING"
+msgstr "???LINIOJ MANKANTAJ"
+
+#, 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?)"
+
+msgid "???BLOCK MISSING"
+msgstr "???MANKAS BLOKO"
+
+msgid "??? from here until ???END lines may be messed up"
+msgstr "??? ekde tie Äis ???FINO linioj estas eble difektaj"
+
+msgid "??? from here until ???END lines may have been inserted/deleted"
+msgstr "??? ekde tie Äis ???FINO linioj estas eble enmetitaj/forviÅitaj"
+
+msgid "???END"
+msgstr "???FINO"
+
+msgid "E311: Recovery Interrupted"
+msgstr "E311: RestaÅ­ro interrompita"
+
+msgid ""
+"E312: Errors detected while recovering; look for lines starting with ???"
+msgstr "E312: Eraroj dum restaÅ­ro; rigardu liniojn komencantajn per ???"
+
+msgid "See \":help E312\" for more information."
+msgstr "Vidu \":help E312\" por pliaj informoj."
+
+msgid "Recovery completed. You should check if everything is OK."
+msgstr "RestaÅ­ro finiÄis. Indus kontroli ĉu ĉio estas en ordo."
+
+msgid ""
+"\n"
+"(You might want to write out this file under another name\n"
+msgstr ""
+"\n"
+"(Indas konservi tiun dosieron per alia nomo\n"
+
+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)"
+
+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."
+
+msgid ""
+"\n"
+"You may want to delete the .swp file now.\n"
+"\n"
+msgstr ""
+"\n"
+"La dosiero .swp nun forviÅindas.\n"
+"\n"
+
+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"
+
+#. use msg() to start the scrolling properly
+msgid "Swap files found:"
+msgstr "Permutodosiero .swp trovita:"
+
+msgid " In current directory:\n"
+msgstr " En la aktuala dosierujo:\n"
+
+msgid " Using specified name:\n"
+msgstr " Uzado de specifita nomo:\n"
+
+msgid " In directory "
+msgstr " En dosierujo "
+
+msgid " -- none --\n"
+msgstr " -- nenio --\n"
+
+msgid " owned by: "
+msgstr " posedata de: "
+
+msgid " dated: "
+msgstr " dato: "
+
+msgid " dated: "
+msgstr " dato: "
+
+msgid " [from Vim version 3.0]"
+msgstr " [de Vim versio 3.0]"
+
+msgid " [does not look like a Vim swap file]"
+msgstr " [ne aspektas kiel permutodosiero .swp de Vim]"
+
+msgid " file name: "
+msgstr " dosiernomo: "
+
+msgid ""
+"\n"
+" modified: "
+msgstr ""
+"\n"
+" modifita: "
+
+msgid "YES"
+msgstr "JES"
+
+msgid "no"
+msgstr "ne"
+
+msgid ""
+"\n"
+" user name: "
+msgstr ""
+"\n"
+" uzantonomo: "
+
+msgid " host name: "
+msgstr " komputila nomo: "
+
+msgid ""
+"\n"
+" host name: "
+msgstr ""
+"\n"
+" komputila nomo: "
+
+msgid ""
+"\n"
+" process ID: "
+msgstr ""
+"\n"
+" proceza ID: "
+
+msgid " (still running)"
+msgstr " (ankoraÅ­ ruliÄas)"
+
+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]"
+msgstr ""
+"\n"
+" [neuzebla per tiu komputilo]"
+
+msgid " [cannot be read]"
+msgstr " [nelegebla]"
+
+msgid " [cannot be opened]"
+msgstr " [nemalfermebla]"
+
+msgid "E313: Cannot preserve, there is no swap file"
+msgstr "E313: Ne eblas konservi, ne estas permutodosiero .swp"
+
+msgid "File preserved"
+msgstr "Dosiero konservita"
+
+msgid "E314: Preserve failed"
+msgstr "E314: Konservo fiaskis"
+
+#, c-format
+msgid "E315: ml_get: invalid lnum: %ld"
+msgstr "E315: ml_get: nevalida lnum: %ld"
+
+#, c-format
+msgid "E316: ml_get: cannot find line %ld"
+msgstr "E316: ml_get: ne eblas trovi linion %ld"
+
+msgid "E317: pointer block id wrong 3"
+msgstr "E317: nevalida referenco de bloko id 3"
+
+msgid "stack_idx should be 0"
+msgstr "stack_idx devus esti 0"
+
+msgid "E318: Updated too many blocks?"
+msgstr "E318: Ĉu Äisdatigis tro da blokoj?"
+
+msgid "E317: pointer block id wrong 4"
+msgstr "E317: nevalida referenco de bloko id 4"
+
+msgid "deleted block 1?"
+msgstr "ĉu forviÅita bloko 1?"
+
+#, c-format
+msgid "E320: Cannot find line %ld"
+msgstr "E320: Ne eblas trovi linion %ld"
+
+msgid "E317: pointer block id wrong"
+msgstr "E317: nevalida referenco de bloko id"
+
+msgid "pe_line_count is zero"
+msgstr "pe_line_count estas nul"
+
+#, c-format
+msgid "E322: line number out of range: %ld past the end"
+msgstr "E322: numero de linio ekster limoj: %ld preter la fino"
+
+#, c-format
+msgid "E323: line count wrong in block %ld"
+msgstr "E323: nevalida nombro de linioj en bloko %ld"
+
+msgid "Stack size increases"
+msgstr "Stako pligrandiÄas"
+
+msgid "E317: pointer block id wrong 2"
+msgstr "E317: nevalida referenco de bloko id 2"
+
+#, c-format
+msgid "E773: Symlink loop for \"%s\""
+msgstr "E773: Buklo de simbolaj ligiloj por \"%s\""
+
+msgid "E325: ATTENTION"
+msgstr "E325: ATENTO"
+
+msgid ""
+"\n"
+"Found a swap file by the name \""
+msgstr ""
+"\n"
+"Trovis permutodosieron .swp kun la nomo \""
+
+msgid "While opening file \""
+msgstr "Dum malfermo de dosiero \""
+
+msgid " NEWER than swap file!\n"
+msgstr " PLI NOVA ol permutodosiero .swp!\n"
+
+#. 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."
+msgstr ""
+"\n"
+"(1) Alia programo eble redaktas la saman dosieron.\n"
+" Se jes, estu singarda por ne havi du malsamajn\n"
+" aperojn de la sama dosiero, kiam vi faros ÅanÄojn."
+
+msgid " Quit, or continue with caution.\n"
+msgstr " Eliru, aÅ­ daÅ­rigu singarde.\n"
+
+msgid "(2) An edit session for this file crashed.\n"
+msgstr "(2) Redakta seanco de tiu dosiero kolapsis.\n"
+
+msgid " If this is the case, use \":recover\" or \"vim -r "
+msgstr " Se veras, uzu \":recover\" aÅ­ \"vim -r "
+
+msgid ""
+"\"\n"
+" to recover the changes (see \":help recovery\").\n"
+msgstr ""
+"\"\n"
+" por restaÅ­ri la ÅanÄojn (vidu \":help recovery\").\n"
+
+msgid " If you did this already, delete the swap file \""
+msgstr " Se vi jam faris Äin, forviÅu la permutodosieron .swp \""
+
+msgid ""
+"\"\n"
+" to avoid this message.\n"
+msgstr ""
+"\"\n"
+" por eviti tiun mesaÄon.\n"
+
+msgid "Swap file \""
+msgstr "Permutodosiero .swp \""
+
+msgid "\" already exists!"
+msgstr "\" jam ekzistas!"
+
+msgid "VIM - ATTENTION"
+msgstr "VIM - ATENTO"
+
+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)
+msgid ""
+"&Open Read-Only\n"
+"&Edit anyway\n"
+"&Recover\n"
+"&Quit\n"
+"&Abort"
+msgstr ""
+"&Malfermi nurlegreÄime\n"
+"Tamen &redakti\n"
+"Res&taÅ­ri\n"
+"&Eliri\n"
+"Ĉe&sigi"
+
+msgid ""
+"&Open Read-Only\n"
+"&Edit anyway\n"
+"&Recover\n"
+"&Delete it\n"
+"&Quit\n"
+"&Abort"
+msgstr ""
+"&Malfermi nurlegreÄime\n"
+"Tamen &redakti\n"
+"Res&taÅ­ri\n"
+"&ForviÅi\n"
+"&Eliri\n"
+"Ĉe&sigi"
+
+msgid "E326: Too many swap files found"
+msgstr "E326: Tro da dosieroj trovitaj"
+
+msgid "E327: Part of menu-item path is not sub-menu"
+msgstr "E327: Parto de vojo de menuero ne estas sub-menuo"
+
+msgid "E328: Menu only exists in another mode"
+msgstr "E328: Menuo nur ekzistas en alia reÄimo"
+
+#, c-format
+msgid "E329: No menu \"%s\""
+msgstr "E329: Neniu menuo \"%s\""
+
+#. Only a mnemonic or accelerator is not valid.
+msgid "E792: Empty menu name"
+msgstr "E792: Malplena nomo de menuo"
+
+msgid "E330: Menu path must not lead to a sub-menu"
+msgstr "E330: Vojo de menuo ne rajtas konduki al sub-menuo"
+
+msgid "E331: Must not add menu items directly to menu bar"
+msgstr "E331: Aldono de menueroj direkte al menuzono estas malpermesita"
+
+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
+msgid ""
+"\n"
+"--- Menus ---"
+msgstr ""
+"\n"
+"--- Menuoj ---"
+
+msgid "Tear off this menu"
+msgstr "Disigi tiun menuon"
+
+msgid "E333: Menu path must lead to a menu item"
+msgstr "E333: Vojo de menuo devas konduki al menuero"
+
+#, c-format
+msgid "E334: Menu not found: %s"
+msgstr "E334: Menuo netrovita: %s"
+
+#, c-format
+msgid "E335: Menu not defined for %s mode"
+msgstr "E335: Menuo ne estas difinita por reÄimo %s"
+
+msgid "E336: Menu path must lead to a sub-menu"
+msgstr "E336: Vojo de menuo devas konduki al sub-menuo"
+
+msgid "E337: Menu not found - check menu names"
+msgstr "E337: Menuo ne trovita - kontrolu nomojn de menuoj"
+
+#, c-format
+msgid "Error detected while processing %s:"
+msgstr "Eraro okazis dum traktado de %s:"
+
+#, c-format
+msgid "line %4ld:"
+msgstr "linio %4ld:"
+
+#, c-format
+msgid "E354: Invalid register name: '%s'"
+msgstr "E354: Nevalida nomo de reÄistro: '%s'"
+
+msgid "Messages maintainer: Bram Moolenaar <Bram@vim.org>"
+msgstr "Flegado de mesaÄoj: Dominique PELLÉ <dominique.pelle@gmail.com>"
+
+msgid "Interrupt: "
+msgstr "Interrompo: "
+
+msgid "Press ENTER or type command to continue"
+msgstr "Premu ENEN-KLAVON aÅ­ tajpu komandon por daÅ­rigi"
+
+#, c-format
+msgid "%s line %ld"
+msgstr "%s linio %ld"
+
+msgid "-- More --"
+msgstr "-- Pli --"
+
+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 "
+
+msgid "Question"
+msgstr "Demando"
+
+msgid ""
+"&Yes\n"
+"&No"
+msgstr ""
+"&Jes\n"
+"&Ne"
+
+# AM: ĉu Vim konvertos unuliterajn respondojn?
+# DP: jes, '&' bone funkcias (mi kontrolis)
+msgid ""
+"&Yes\n"
+"&No\n"
+"Save &All\n"
+"&Discard All\n"
+"&Cancel"
+msgstr ""
+"&Jes\n"
+"&Ne\n"
+"&Konservi Ĉion\n"
+"&Forlasi Ĉion\n"
+"&Rezigni"
+
+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"
+
+#. TODO: non-GUI file selector here
+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()"
+
+msgid "E807: Expected Float argument for printf()"
+msgstr "E807: Atendis Glitpunktnombron kiel argumento de printf()"
+
+msgid "E767: Too many arguments to printf()"
+msgstr "E767: Tro da argumentoj al printf()"
+
+msgid "W10: Warning: Changing a readonly file"
+msgstr "W10: Averto: ÅœanÄo de nurlegebla dosiero"
+
+msgid "Type number and <Enter> or click with mouse (empty cancels): "
+msgstr ""
+"Tajpu nombron kaj <Enenklavon> aÅ­ alklaku per la muso (malpleno rezignas): "
+
+msgid "Type number and <Enter> (empty cancels): "
+msgstr "Tajpu nombron kaj <Enenklavon> (malpleno rezignas): "
+
+msgid "1 more line"
+msgstr "1 plia linio"
+
+msgid "1 line less"
+msgstr "1 malplia linio"
+
+#, c-format
+msgid "%ld more lines"
+msgstr "%ld pliaj linioj"
+
+#, c-format
+msgid "%ld fewer lines"
+msgstr "%ld malpliaj linioj"
+
+msgid " (Interrupted)"
+msgstr " (Interrompita)"
+
+msgid "Beep!"
+msgstr "Bip!"
+
+msgid "Vim: preserving files...\n"
+msgstr "Vim: konservo de dosieroj...\n"
+
+#. close all memfiles, without deleting
+msgid "Vim: Finished.\n"
+msgstr "Vim: Finita.\n"
+
+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\""
+
+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 "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 "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"
+
+msgid "Cannot connect to Netbeans #2"
+msgstr "Ne eblas konekti al Netbeans n-ro 2"
+
+msgid "Cannot connect to Netbeans"
+msgstr "Ne eblas konekti al Netbeans"
+
+#, 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\""
+
+msgid "read from Netbeans socket"
+msgstr "lego el kontaktoskatolo de Netbeans"
+
+#, 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"
+
+msgid "E774: 'operatorfunc' is empty"
+msgstr "E774: 'operatorfunc' estas malplena"
+
+# 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"
+
+msgid "E348: No string under cursor"
+msgstr "E348: Neniu ĉeno sub la kursoro"
+
+msgid "E352: Cannot erase folds with current 'foldmethod'"
+msgstr "E352: Ne eblas forviÅi faldon per aktuala 'foldmethod'"
+
+msgid "E664: changelist is empty"
+msgstr "E664: Listo de ÅanÄoj estas malplena"
+
+msgid "E662: At start of changelist"
+msgstr "E662: Ĉe komenco de ÅanÄlisto"
+
+msgid "E663: At end of changelist"
+msgstr "E663: Ĉe fino de ÅanÄlisto"
+
+msgid "Type :quit<Enter> to exit Vim"
+msgstr "Tajpu \":quit<Enenklavo>\" por eliri el Vim"
+
+#, c-format
+msgid "1 line %sed 1 time"
+msgstr "1 linio %sita 1 foje"
+
+#, c-format
+msgid "1 line %sed %d times"
+msgstr "1 linio %sita %d foje"
+
+#, c-format
+msgid "%ld lines %sed 1 time"
+msgstr "%ld linio %sita 1 foje"
+
+#, c-format
+msgid "%ld lines %sed %d times"
+msgstr "%ld linioj %sitaj %d foje"
+
+#, c-format
+msgid "%ld lines to indent... "
+msgstr "%ld krommarÄenendaj linioj... "
+
+msgid "1 line indented "
+msgstr "1 linio krommarÄenita "
+
+#, c-format
+msgid "%ld lines indented "
+msgstr "%ld linioj krommarÄenitaj "
+
+msgid "E748: No previously used register"
+msgstr "E748: Neniu reÄistro antaÅ­e uzata"
+
+#. must display the prompt
+msgid "cannot yank; delete anyway"
+msgstr "ne eblas kopii; forviÅi tamene"
+
+msgid "1 line changed"
+msgstr "1 linio ÅanÄita"
+
+#, c-format
+msgid "%ld lines changed"
+msgstr "%ld linioj ÅanÄitaj"
+
+#, c-format
+msgid "freeing %ld lines"
+msgstr "malokupas %ld liniojn"
+
+msgid "block of 1 line yanked"
+msgstr "bloko de 1 linio kopiita"
+
+msgid "1 line yanked"
+msgstr "1 linio kopiita"
+
+#, c-format
+msgid "block of %ld lines yanked"
+msgstr "bloko de %ld linioj kopiita"
+
+#, c-format
+msgid "%ld lines yanked"
+msgstr "%ld linioj kopiitaj"
+
+#, c-format
+msgid "E353: Nothing in register %s"
+msgstr "E353: Nenio en reÄistro %s"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Registers ---"
+msgstr ""
+"\n"
+"--- ReÄistroj ---"
+
+msgid "Illegal register name"
+msgstr "Nevalida nomo de reÄistro"
+
+msgid ""
+"\n"
+"# Registers:\n"
+msgstr ""
+"\n"
+"# ReÄistroj:\n"
+
+#, c-format
+msgid "E574: Unknown register type %d"
+msgstr "E574: Nekonata tipo de reÄistro %d"
+
+#, c-format
+msgid "%ld Cols; "
+msgstr "%ld Kolumnoj; "
+
+#, c-format
+msgid "Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Bytes"
+msgstr "Apartigis %s%ld de %ld Linioj; %ld de %ld Vortoj; %ld de %ld Bajtoj"
+
+#, c-format
+msgid ""
+"Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Chars; %ld of %ld "
+"Bytes"
+msgstr ""
+"Apartigis %s%ld de %ld Linioj; %ld de %ld Vortoj; %ld de %ld Signoj; %ld de "
+"%ld Bajtoj"
+
+#, c-format
+msgid "Col %s of %s; Line %ld of %ld; Word %ld of %ld; Byte %ld of %ld"
+msgstr "Kol %s de %s; Linio %ld de %ld; Vorto %ld de %ld; Bajto %ld de %ld"
+
+#, c-format
+msgid ""
+"Col %s of %s; Line %ld of %ld; Word %ld of %ld; Char %ld of %ld; Byte %ld of "
+"%ld"
+msgstr ""
+"Kol %s de %s; Linio %ld de %ld; Vorto %ld de %ld; Signo %ld de %ld; Bajto "
+"%ld de %ld"
+
+#, c-format
+msgid "(+%ld for BOM)"
+msgstr "(+%ld por BOM)"
+
+msgid "%<%f%h%m%=Page %N"
+msgstr "%<%f%h%m%=Folio %N"
+
+msgid "Thanks for flying Vim"
+msgstr "Dankon pro flugi per Vim"
+
+msgid "E518: Unknown option"
+msgstr "E518: Nekonata opcio"
+
+msgid "E519: Option not supported"
+msgstr "E519: Opcio ne subtenata"
+
+msgid "E520: Not allowed in a modeline"
+msgstr "E520: Nepermesebla en reÄimlinio"
+
+msgid "E846: Key code not set"
+msgstr "E846: Klavkodo ne agordita"
+
+msgid "E521: Number required after ="
+msgstr "E521: Nombro bezonata post ="
+
+msgid "E522: Not found in termcap"
+msgstr "E522: Netrovita en termcap"
+
+#, c-format
+msgid "E539: Illegal character <%s>"
+msgstr "E539: Nevalida signo <%s>"
+
+msgid "E529: Cannot set 'term' to empty string"
+msgstr "E529: Ne eblas agordi 'term' al malplena ĉeno"
+
+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"
+
+msgid "E834: Conflicts with value of 'listchars'"
+msgstr "E834: Konfliktoj kun la valoro de 'listchars'"
+
+msgid "E835: Conflicts with value of 'fillchars'"
+msgstr "E835: Konfliktoj kun la valoro de 'fillchars'"
+
+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"
+
+msgid "E525: Zero length string"
+msgstr "E525: Ĉeno de nula longo"
+
+#, c-format
+msgid "E526: Missing number after <%s>"
+msgstr "E526: Mankas nombro post <%s>"
+
+msgid "E527: Missing comma"
+msgstr "E527: Mankas komo"
+
+msgid "E528: Must specify a ' value"
+msgstr "E528: Devas specifi ' valoron"
+
+msgid "E595: contains unprintable or wide character"
+msgstr "E595: enhavas nepreseblan aÅ­ plurĉellarÄan signon"
+
+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>"
+
+msgid "E536: comma required"
+msgstr "E536: komo bezonata"
+
+#, c-format
+msgid "E537: 'commentstring' must be empty or contain %s"
+msgstr "E537: 'commentstring' devas esti malplena aÅ­ enhavi %s"
+
+msgid "E538: No mouse support"
+msgstr "E538: Neniu muso subtenata"
+
+msgid "E540: Unclosed expression sequence"
+msgstr "E540: '}' mankas"
+
+msgid "E541: too many items"
+msgstr "E541: tro da elementoj"
+
+msgid "E542: unbalanced groups"
+msgstr "E542: misekvilibritaj grupoj"
+
+msgid "E590: A preview window already exists"
+msgstr "E590: AntaÅ­vida fenestro jam ekzistas"
+
+msgid "W17: Arabic requires UTF-8, do ':set encoding=utf-8'"
+msgstr "W17: La araba bezonas UTF-8, tajpu \":set encoding=utf-8\""
+
+#, c-format
+msgid "E593: Need at least %d lines"
+msgstr "E593: Bezonas almenaÅ­ %d liniojn"
+
+#, c-format
+msgid "E594: Need at least %d columns"
+msgstr "E594: Bezonas almenaÅ­ %d kolumnojn"
+
+#, 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.
+#, c-format
+msgid "E521: Number required: &%s = '%s'"
+msgstr "E521: Nombro bezonata: &%s = '%s'"
+
+msgid ""
+"\n"
+"--- Terminal codes ---"
+msgstr ""
+"\n"
+"--- Kodoj de terminalo ---"
+
+msgid ""
+"\n"
+"--- Global option values ---"
+msgstr ""
+"\n"
+"--- Mallokaj opcioj ---"
+
+msgid ""
+"\n"
+"--- Local option values ---"
+msgstr ""
+"\n"
+"--- Valoroj de lokaj opcioj ---"
+
+msgid ""
+"\n"
+"--- Options ---"
+msgstr ""
+"\n"
+"--- Opcioj ---"
+
+msgid "E356: get_varp ERROR"
+msgstr "E356: ERARO get_varp"
+
+#, c-format
+msgid "E357: 'langmap': Matching character missing for %s"
+msgstr "E357: 'langmap': Kongrua signo mankas por %s"
+
+#, c-format
+msgid "E358: 'langmap': Extra characters after semicolon: %s"
+msgstr "E358: 'langmap': Ekstraj signoj post punktokomo: %s"
+
+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"
+
+#. if Vim opened a window: Executing a shell may cause crashes
+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 "'columns' is not 80, cannot execute external commands"
+msgstr "'columns' ne estas 80, ne eblas plenumi eksternajn komandojn"
+
+msgid "E237: Printer selection failed"
+msgstr "E237: Elekto de presilo fiaskis"
+
+#, 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 "E245: Illegal char '%c' in font name \"%s\""
+msgstr "E245: Nevalida signo '%c' en nomo de tiparo \"%s\""
+
+msgid "Vim: Double signal, exiting\n"
+msgstr "Vim: Duobla signalo, eliranta\n"
+
+#, c-format
+msgid "Vim: Caught deadly signal %s\n"
+msgstr "Vim: Kaptis mortigantan signalon %s\n"
+
+#, c-format
+msgid "Vim: Caught deadly signal\n"
+msgstr "Vim: Kaptis mortigantan signalon\n"
+
+#, c-format
+msgid "Opening the X display took %ld msec"
+msgstr "Malfermo de vidigo X daÅ­ris %ld msek"
+
+msgid ""
+"\n"
+"Vim: Got X error\n"
+msgstr ""
+"\n"
+"Vim: Alvenis X eraro\n"
+
+msgid "Testing the X display failed"
+msgstr "Testo de la vidigo X fiaskis"
+
+msgid "Opening the X display timed out"
+msgstr "Tempolimo okazis dum malfermo de vidigo X"
+
+msgid ""
+"\n"
+"Could not get security context for "
+msgstr ""
+"\n"
+"Ne povis akiri kuntekston de sekureco por "
+
+msgid ""
+"\n"
+"Could not set security context for "
+msgstr ""
+"\n"
+"Ne povis Åalti kuntekston de sekureco por "
+
+msgid ""
+"\n"
+"Cannot execute shell "
+msgstr ""
+"\n"
+"Ne eblas plenumi Åelon "
+
+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"
+"Command terminated\n"
+msgstr ""
+"\n"
+"Komando terminigita\n"
+
+msgid "XSMP lost ICE connection"
+msgstr "XSMP perdis la konekton ICE"
+
+#, c-format
+msgid "dlerror = \"%s\""
+msgstr "dlerror = \"%s\""
+
+msgid "Opening the X display failed"
+msgstr "Malfermo de vidigo X fiaskis"
+
+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 fiaskis"
+
+#, c-format
+msgid "XSMP SmcOpenConnection failed: %s"
+msgstr "XSMP: SmcOpenConnection fiaskis: %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!"
+
+#, c-format
+msgid "shell returned %d"
+msgstr "la Åelo liveris %d"
+
+# 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 "E372: Too many %%%c in format string"
+msgstr "E372: Tro da %%%c en formata ĉeno"
+
+#, c-format
+msgid "E373: Unexpected %%%c in format string"
+msgstr "E373: Neatendita %%%c en formata ĉeno"
+
+msgid "E374: Missing ] in format string"
+msgstr "E374: Mankas ] en formata ĉeno"
+
+#, c-format
+msgid "E375: Unsupported %%%c in format string"
+msgstr "E375: Nesubtenata %%%c en formata ĉeno"
+
+#, c-format
+msgid "E376: Invalid %%%c in format string prefix"
+msgstr "E376: Nevalida %%%c en prefikso de formata ĉeno"
+
+#, c-format
+msgid "E377: Invalid %%%c in format string"
+msgstr "E377: Nevalida %%%c en formata ĉeno"
+
+msgid "E378: 'errorformat' contains no pattern"
+msgstr "E378: 'errorformat' enhavas neniun Åablonon"
+
+msgid "E379: Missing or empty directory name"
+msgstr "E379: Nomo de dosierujo mankas aÅ­ estas malplena"
+
+msgid "E553: No more items"
+msgstr "E553: Ne plu estas eroj"
+
+#, c-format
+msgid "(%d of %d)%s%s: "
+msgstr "(%d de %d)%s%s: "
+
+msgid " (line deleted)"
+msgstr " (forviÅita linio)"
+
+msgid "E380: At bottom of quickfix stack"
+msgstr "E380: Ĉe la subo de stako de rapidriparo"
+
+msgid "E381: At top of quickfix stack"
+msgstr "E381: Ĉe la supro de stako de rapidriparo"
+
+#, c-format
+msgid "error list %d of %d; %d errors"
+msgstr "listo de eraroj %d de %d; %d eraroj"
+
+msgid "E382: Cannot write, 'buftype' option is set"
+msgstr "E382: Ne eblas skribi, opcio 'buftype' estas Åaltita"
+
+msgid "Error file"
+msgstr "Erara Dosiero"
+
+msgid "E683: File name missing or invalid pattern"
+msgstr "E683: Dosiernomo mankas aÅ­ nevalida Åablono"
+
+#, c-format
+msgid "Cannot open file \"%s\""
+msgstr "Ne eblas malfermi dosieron \"%s\""
+
+msgid "E681: Buffer is not loaded"
+msgstr "E681: Bufro ne estas Åargita"
+
+msgid "E777: String or List expected"
+msgstr "E777: Ĉeno aŭ Listo atendita"
+
+#, c-format
+msgid "E369: invalid item in %s%%[]"
+msgstr "E369: nevalida ano en %s%%[]"
+
+#, c-format
+msgid "E769: Missing ] after %s["
+msgstr "E769: Mankas ] post %s["
+
+#, c-format
+msgid "E53: Unmatched %s%%("
+msgstr "E53: Neekvilibra %s%%("
+
+#, c-format
+msgid "E54: Unmatched %s("
+msgstr "E54: Neekvilibra %s("
+
+#, c-format
+msgid "E55: Unmatched %s)"
+msgstr "E55: Neekvilibra %s"
+
+msgid "E339: Pattern too long"
+msgstr "E339: Åœablono tro longa"
+
+msgid "E50: Too many \\z("
+msgstr "E50: Tro da \\z("
+
+#, c-format
+msgid "E51: Too many %s("
+msgstr "E51: Tro da %s("
+
+msgid "E52: Unmatched \\z("
+msgstr "E52: Neekvilibra \\z("
+
+#, c-format
+msgid "E59: invalid character after %s@"
+msgstr "E59: nevalida signo post %s@"
+
+#, c-format
+msgid "E60: Too many complex %s{...}s"
+msgstr "E60: Tro da kompleksaj %s{...}-oj"
+
+#, c-format
+msgid "E61: Nested %s*"
+msgstr "E61: Ingita %s*"
+
+#, c-format
+msgid "E62: Nested %s%c"
+msgstr "E62: Ingita %s%c"
+
+msgid "E63: invalid use of \\_"
+msgstr "E63: nevalida uzo de \\_"
+
+#, c-format
+msgid "E64: %s%c follows nothing"
+msgstr "E64: %s%c sekvas nenion"
+
+msgid "E65: Illegal back reference"
+msgstr "E65: Nevalida retro-referenco"
+
+msgid "E66: \\z( not allowed here"
+msgstr "E66: \\z( estas permesebla tie"
+
+# DP: vidu http://www.thefreedictionary.com/et+al.
+msgid "E67: \\z1 et al. not allowed here"
+msgstr "E67: \\z1 kaj aliaj estas nepermeseblaj tie"
+
+msgid "E68: Invalid character after \\z"
+msgstr "E68: Nevalida signo post \\z"
+
+#, c-format
+msgid "E69: Missing ] after %s%%["
+msgstr "E69: Mankas ] post %s%%["
+
+#, c-format
+msgid "E70: Empty %s%%[]"
+msgstr "E70: Malplena %s%%[]"
+
+#, c-format
+msgid "E678: Invalid character after %s%%[dxouU]"
+msgstr "E678: Nevalida signo post %s%%[dxouU]"
+
+#, c-format
+msgid "E71: Invalid character after %s%%"
+msgstr "E71: Nevalida signo post %s%%"
+
+#, c-format
+msgid "E554: Syntax error in %s{...}"
+msgstr "E554: Sintaksa eraro en %s{...}"
+
+msgid "External submatches:\n"
+msgstr "Eksteraj subkongruoj:\n"
+
+msgid ""
+"E864: \\%#= can only be followed by 0, 1, or 2. The automatic engine will be "
+"used "
+msgstr ""
+"E864: \\%#= povas nur esti sekvita de 0, 1, aÅ­ 2. La aÅ­tomata motoro de "
+"regulesprimo estos uzata "
+
+#, c-format
+msgid "E866: (NFA regexp) Misplaced %c"
+msgstr "E866: (NFA-regulesprimo) Mispoziciigita %c"
+
+msgid "E865: (NFA) Regexp end encountered prematurely"
+msgstr "E865: (NFA) Trovis finon de regulesprimo tro frue"
+
+#, c-format
+msgid "E867: (NFA) Unknown operator '\\z%c'"
+msgstr "E867: (NFA) Nekonata operatoro '\\z%c'"
+
+#. should never happen
+msgid "E868: Error building NFA with equivalence class!"
+msgstr "E868: Eraro dum prekomputado de NFA kun ekvivalentoklaso!"
+
+#, c-format
+msgid "E869: (NFA) Unknown operator '\\@%c'"
+msgstr "E869: (NFA) Nekonata operatoro '\\@%c'"
+
+msgid "E870: (NFA regexp) Error reading repetition limits"
+msgstr "E870: (NFS-regulesprimo) Eraro dum legado de limoj de ripeto"
+
+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!"
+
+msgid "E872: (NFA regexp) Too many '('"
+msgstr "E872: (NFA-regulesprimo) tro da '('"
+
+msgid "E873: (NFA regexp) proper termination error"
+msgstr "E873: (NFA-regulesprimo) propra end-eraro"
+
+msgid "E874: (NFA) Could not pop the stack !"
+msgstr "E874: (NFA) Ne povis elpreni de la staplo!"
+
+msgid ""
+"E875: (NFA regexp) (While converting from postfix to NFA), too many states "
+"left on stack"
+msgstr ""
+"E875: (NFA-regulesprimo) (dum konverto de postmeto al NFA), restas tro da "
+"statoj en la staplo"
+
+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 "
+
+msgid "E999: (NFA regexp internal error) Should not process NOT node !"
+msgstr ""
+"E999: (interna eraro de NFA-regulesprimo) Ne devus procezi nodon 'NOT'!"
+
+#. should not be here :P
+msgid "E877: (NFA regexp) Invalid character class "
+msgstr "E877: (NFA-regulesprimo) Nevalida klaso de signo "
+
+#, c-format
+msgid "(NFA) COULD NOT OPEN %s !"
+msgstr "(NFA) NE POVIS MALFERMI %s!"
+
+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 "E878: (NFA) Could not allocate memory for branch traversal!"
+msgstr "E878: (NFA) Ne povis asigni memoron por traigi branĉojn!"
+
+msgid "Could not open temporary log file for writing "
+msgstr "Ne povis malfermi la provizoran protokolan dosieron por skribi "
+
+msgid " VREPLACE"
+msgstr " V-ANSTATAŬIGO"
+
+msgid " REPLACE"
+msgstr " ANSTATAŬIGO"
+
+msgid " REVERSE"
+msgstr " INVERSI"
+
+msgid " INSERT"
+msgstr " ENMETO"
+
+msgid " (insert)"
+msgstr " (enmeto)"
+
+msgid " (replace)"
+msgstr " (anstataÅ­igo)"
+
+msgid " (vreplace)"
+msgstr " (v-anstataÅ­igo)"
+
+msgid " Hebrew"
+msgstr " hebrea"
+
+msgid " Arabic"
+msgstr " araba"
+
+msgid " (lang)"
+msgstr " (lingvo)"
+
+msgid " (paste)"
+msgstr " (algluo)"
+
+msgid " VISUAL"
+msgstr " VIDUMA"
+
+msgid " VISUAL LINE"
+msgstr " VIDUMA LINIO"
+
+msgid " VISUAL BLOCK"
+msgstr " VIDUMA BLOKO"
+
+msgid " SELECT"
+msgstr " APARTIGO"
+
+msgid " SELECT LINE"
+msgstr " APARTIGITA LINIO"
+
+msgid " SELECT BLOCK"
+msgstr " APARTIGITA BLOKO"
+
+msgid "recording"
+msgstr "registrado"
+
+#, c-format
+msgid "E383: Invalid search string: %s"
+msgstr "E383: Nevalida serĉenda ĉeno: %s"
+
+#, c-format
+msgid "E384: search hit TOP without match for: %s"
+msgstr "E384: serĉo atingis SUPRON sen trovi: %s"
+
+#, c-format
+msgid "E385: search hit BOTTOM without match for: %s"
+msgstr "E385: serĉo atingis SUBON sen trovi: %s"
+
+msgid "E386: Expected '?' or '/' after ';'"
+msgstr "E386: Atendis '?' aÅ­ '/' post ';'"
+
+msgid " (includes previously listed match)"
+msgstr " (enhavas antaÅ­e listigitajn kongruojn)"
+
+#. cursor at status line
+msgid "--- Included files "
+msgstr "--- Inkluzivitaj dosieroj "
+
+msgid "not found "
+msgstr "netrovitaj "
+
+msgid "in path ---\n"
+msgstr "en serĉvojo ---\n"
+
+msgid " (Already listed)"
+msgstr " (Jam listigita)"
+
+msgid " NOT FOUND"
+msgstr " NETROVITA"
+
+#, c-format
+msgid "Scanning included file: %s"
+msgstr "Skanado de inkluzivitaj dosieroj: %s"
+
+#, c-format
+msgid "Searching included file %s"
+msgstr "Serĉado de inkluzivitaj dosieroj %s"
+
+msgid "E387: Match is on current line"
+msgstr "E387: Kongruo estas ĉe aktuala linio"
+
+msgid "All included files were found"
+msgstr "Ĉiuj inkluzivitaj dosieroj estis trovitaj"
+
+msgid "No included files"
+msgstr "Neniu inkluzivita dosiero"
+
+msgid "E388: Couldn't find definition"
+msgstr "E388: Ne eblis trovi difinon"
+
+msgid "E389: Couldn't find pattern"
+msgstr "E389: Ne eblis trovi Åablonon"
+
+msgid "Substitute "
+msgstr "AnstataÅ­igi "
+
+#, c-format
+msgid ""
+"\n"
+"# Last %sSearch Pattern:\n"
+"~"
+msgstr ""
+"\n"
+"# Lasta serĉa Åablono %s:\n"
+"~"
+
+msgid "E759: Format error in spell file"
+msgstr "E759: Eraro de formato en literuma dosiero"
+
+msgid "E758: Truncated spell file"
+msgstr "E758: Trunkita literuma dosiero"
+
+#, c-format
+msgid "Trailing text in %s line %d: %s"
+msgstr "Vosta teksto en %s linio %d: %s"
+
+#, c-format
+msgid "Affix name too long in %s line %d: %s"
+msgstr "Nomo de afikso tro longa en %s linio %d: %s"
+
+msgid "E761: Format error in affix file FOL, LOW or UPP"
+msgstr "E761: Eraro de formato en afiksa dosiero FOL, LOW aÅ­ UPP"
+
+msgid "E762: Character in FOL, LOW or UPP is out of range"
+msgstr "E762: Signo en FOL, LOW aÅ­ UPP estas ekster limoj"
+
+msgid "Compressing word tree..."
+msgstr "Densigas arbon de vortoj..."
+
+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\""
+
+#, c-format
+msgid "Reading spell file \"%s\""
+msgstr "Legado de literuma dosiero \"%s\""
+
+msgid "E757: This does not look like a spell file"
+msgstr "E757: Tio ne Åajnas esti literuma dosiero"
+
+msgid "E771: Old spell file, needs to be updated"
+msgstr "E771: Malnova literuma dosiero, Äisdatigo bezonata"
+
+msgid "E772: Spell file is for newer version of Vim"
+msgstr "E772: Literuma dosiero estas por pli nova versio de Vim"
+
+msgid "E770: Unsupported section in spell file"
+msgstr "E770: Nesubtenata sekcio en literuma dosiero"
+
+#, c-format
+msgid "Warning: region %s not supported"
+msgstr "Averto: regiono %s ne subtenata"
+
+#, c-format
+msgid "Reading affix file %s ..."
+msgstr "Legado de afiksa dosiero %s ..."
+
+#, c-format
+msgid "Conversion failure for word in %s line %d: %s"
+msgstr "Malsukceso dum konverto de vorto en %s linio %d: %s"
+
+#, c-format
+msgid "Conversion in %s not supported: from %s to %s"
+msgstr "Konverto en %s nesubtenata: de %s al %s"
+
+#, 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"
+
+#, c-format
+msgid "FLAG after using flags in %s line %d: %s"
+msgstr "FLAG post flagoj en %s linio %d: %s"
+
+#, c-format
+msgid ""
+"Defining COMPOUNDFORBIDFLAG after PFX item may give wrong results in %s line "
+"%d"
+msgstr ""
+"Difino de COMPOUNDFORBIDFLAG post ano PFX povas doni neÄustajn rezultojn en "
+"%s linio %d"
+
+#, c-format
+msgid ""
+"Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in %s line "
+"%d"
+msgstr ""
+"Difino de COMPOUNDPERMITFLAG post ano PFX povas doni neÄustajn rezultojn en "
+"%s linio %d"
+
+#, c-format
+msgid "Wrong COMPOUNDRULES value in %s line %d: %s"
+msgstr "Nevalida valoro de COMPOUNDRULES en %s linio %d: %s"
+
+#, c-format
+msgid "Wrong COMPOUNDWORDMAX value in %s line %d: %s"
+msgstr "Nevalida valoro de COMPOUNDWORDMAX en %s linio %d: %s"
+
+#, c-format
+msgid "Wrong COMPOUNDMIN value in %s line %d: %s"
+msgstr "Nevalida valoro de COMPOUNDMIN en %s linio %d: %s"
+
+#, c-format
+msgid "Wrong COMPOUNDSYLMAX value in %s line %d: %s"
+msgstr "Nevalida valoro de COMPOUNDSYLMAX en %s linio %d: %s"
+
+#, c-format
+msgid "Wrong CHECKCOMPOUNDPATTERN value in %s line %d: %s"
+msgstr "Nevalida valoro de CHECKCOMPOUNDPATTERN en %s linio %d: %s"
+
+#, 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"
+
+#, c-format
+msgid "Duplicate affix in %s line %d: %s"
+msgstr "Ripetita afikso en %s linio %d: %s"
+
+#, c-format
+msgid ""
+"Affix also used for BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST in %s "
+"line %d: %s"
+msgstr ""
+"Afikso ankaÅ­ uzata por BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST en "
+"%s linio %d: %s"
+
+#, c-format
+msgid "Expected Y or N in %s line %d: %s"
+msgstr "Y aÅ­ N atendita en %s linio %d: %s"
+
+#, c-format
+msgid "Broken condition in %s line %d: %s"
+msgstr "Nevalida kondiĉo en %s linio %d: %s"
+
+#, c-format
+msgid "Expected REP(SAL) count in %s line %d"
+msgstr "Neatendita nombro REP(SAL) en %s linio %d"
+
+#, c-format
+msgid "Expected MAP count in %s line %d"
+msgstr "Neatendita nombro de MAPen %s linio %d"
+
+#, c-format
+msgid "Duplicate character in MAP in %s line %d"
+msgstr "Ripetita signo en MAP en %s linio %d"
+
+#, c-format
+msgid "Unrecognized or duplicate item in %s line %d: %s"
+msgstr "Neagnoskita aÅ­ ripetita ano en %s linio %d: %s"
+
+#, c-format
+msgid "Missing FOL/LOW/UPP line in %s"
+msgstr "Mankas linio FOL/LOW/UPP en %s"
+
+msgid "COMPOUNDSYLMAX used without SYLLABLE"
+msgstr "COMPOUNDSYLMAX uzita sen SYLLABLE"
+
+msgid "Too many postponed prefixes"
+msgstr "Tro da prokrastitaj prefiksoj"
+
+msgid "Too many compound flags"
+msgstr "Tro da kunmetitaj flagoj"
+
+msgid "Too many postponed prefixes and/or compound flags"
+msgstr "Tro da prokrastitaj prefiksoj kaj/aÅ­ kunmetitaj flagoj"
+
+#, c-format
+msgid "Missing SOFO%s line in %s"
+msgstr "Mankas SOFO%s-aj linioj en %s"
+
+#, c-format
+msgid "Both SAL and SOFO lines in %s"
+msgstr "AmbaÅ­ SAL kaj SOFO linioj en %s"
+
+#, c-format
+msgid "Flag is not a number in %s line %d: %s"
+msgstr "Flago ne estas nombro en %s linio %d: %s"
+
+#, c-format
+msgid "Illegal flag in %s line %d: %s"
+msgstr "Nevalida flago en %s linio %d: %s"
+
+#, 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"
+
+#, c-format
+msgid "Reading dictionary file %s ..."
+msgstr "Legado de vortardosiero %s ..."
+
+#, c-format
+msgid "E760: No word count in %s"
+msgstr "E760: Ne estas nombro de vortoj en %s"
+
+#, c-format
+msgid "line %6d, word %6d - %s"
+msgstr "linio %6d, vorto %6d - %s"
+
+#, c-format
+msgid "Duplicate word in %s line %d: %s"
+msgstr "Ripetita vorto en %s linio %d: %s"
+
+#, c-format
+msgid "First duplicate word in %s line %d: %s"
+msgstr "Unua ripetita vorto en %s linio %d: %s"
+
+#, c-format
+msgid "%d duplicate word(s) in %s"
+msgstr "%d ripetita(j) vorto(j) en %s"
+
+#, c-format
+msgid "Ignored %d word(s) with non-ASCII characters in %s"
+msgstr "%d ignorita(j) vorto(j) kun neaskiaj signoj en %s"
+
+#, c-format
+msgid "Reading word file %s ..."
+msgstr "Legado de dosiero de vortoj %s ..."
+
+#, c-format
+msgid "Duplicate /encoding= line ignored in %s line %d: %s"
+msgstr "Ripetita linio /encoding= ignorita en %s linio %d: %s"
+
+#, c-format
+msgid "/encoding= line after word ignored in %s line %d: %s"
+msgstr "Linio /encoding= post vorto ignorita en %s linio %d: %s"
+
+#, c-format
+msgid "Duplicate /regions= line ignored in %s line %d: %s"
+msgstr "Ripetita linio /regions= ignorita en %s linio %d: %s"
+
+#, c-format
+msgid "Too many regions in %s line %d: %s"
+msgstr "Tro da regionoj en %s linio %d: %s"
+
+#, c-format
+msgid "/ line ignored in %s line %d: %s"
+msgstr "Linio / ignorita en %s linio %d: %s"
+
+#, c-format
+msgid "Invalid region nr in %s line %d: %s"
+msgstr "Nevalida regiono nr en %s linio %d: %s"
+
+#, c-format
+msgid "Unrecognized flags in %s line %d: %s"
+msgstr "Nekonata flago en %s linio %d: %s"
+
+#, c-format
+msgid "Ignored %d words with non-ASCII characters"
+msgstr "Ignoris %d vorto(j)n kun neaskiaj signoj"
+
+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"
+
+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.
+#.
+msgid "Performing soundfolding..."
+msgstr "Fonetika analizado..."
+
+#, c-format
+msgid "Number of words after soundfolding: %ld"
+msgstr "Nombro de vortoj post fonetika analizado: %ld"
+
+#, c-format
+msgid "Total number of words: %d"
+msgstr "Totala nombro de vortoj: %d"
+
+#, c-format
+msgid "Writing suggestion file %s ..."
+msgstr "Skribado de dosiero de sugesto %s ..."
+
+#, c-format
+msgid "Estimated runtime memory use: %d bytes"
+msgstr "Evaluo de memoro uzata: %d bajtoj"
+
+msgid "E751: Output file name must not have region name"
+msgstr "E751: Nomo de eliga dosiero ne devas havi nomon de regiono"
+
+msgid "E754: Only up to 8 regions supported"
+msgstr "E754: Nur 8 regionoj subtenataj"
+
+#, c-format
+msgid "E755: Invalid region in %s"
+msgstr "E755: Nevalida regiono en %s"
+
+msgid "Warning: both compounding and NOBREAK specified"
+msgstr "Averto: ambaÅ­ NOBREAK kaj NOBREAK specifitaj"
+
+#, c-format
+msgid "Writing spell file %s ..."
+msgstr "Skribado de literuma dosiero %s ..."
+
+msgid "Done!"
+msgstr "Farita!"
+
+#, c-format
+msgid "E765: 'spellfile' does not have %ld entries"
+msgstr "E765: 'spellfile' ne havas %ld rikordojn"
+
+#, c-format
+msgid "Word removed from %s"
+msgstr "Vorto fortirita el %s"
+
+#, c-format
+msgid "Word added to %s"
+msgstr "Vorto aldonita al %s"
+
+msgid "E763: Word characters differ between spell files"
+msgstr "E763: Signoj de vorto malsamas tra literumaj dosieroj"
+
+msgid "Sorry, no suggestions"
+msgstr "BedaÅ­rinde ne estas sugestoj"
+
+#, c-format
+msgid "Sorry, only %ld suggestions"
+msgstr "BedaÅ­rinde estas nur %ld sugestoj"
+
+#. for when 'cmdheight' > 1
+#. avoid more prompt
+#, 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"
+
+#, c-format
+msgid "E778: This does not look like a .sug file: %s"
+msgstr "E778: Tio ne Åajnas esti dosiero .sug: %s"
+
+#, c-format
+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"
+
+#. This should have been checked when generating the .spl
+#. * file.
+msgid "E783: duplicate char in MAP entry"
+msgstr "E783: ripetita signo en rikordo MAP"
+
+#, c-format
+msgid "E390: Illegal argument: %s"
+msgstr "E390: Nevalida argumento: %s"
+
+#, c-format
+msgid "E391: No such syntax cluster: %s"
+msgstr "E391: Nenia sintaksa fasko: %s"
+
+msgid "No Syntax items defined for this buffer"
+msgstr "Neniu sintaksa elemento difinita por tiu bufro"
+
+msgid "syncing on C-style comments"
+msgstr "sinkronigo per C-stilaj komentoj"
+
+msgid "no syncing"
+msgstr "neniu sinkronigo"
+
+msgid "syncing starts "
+msgstr "sinkronigo ekas "
+
+msgid " lines before top line"
+msgstr " linioj antaÅ­ supra linio"
+
+msgid ""
+"\n"
+"--- Syntax sync items ---"
+msgstr ""
+"\n"
+"--- Eroj de sintaksa sinkronigo ---"
+
+msgid ""
+"\n"
+"syncing on items"
+msgstr ""
+"\n"
+"sinkronigo per eroj"
+
+msgid ""
+"\n"
+"--- Syntax items ---"
+msgstr ""
+"\n"
+"--- Sintakseroj ---"
+
+#, c-format
+msgid "E392: No such syntax cluster: %s"
+msgstr "E392: Nenia sintaksa fasko: %s"
+
+msgid "minimal "
+msgstr "minimuma "
+
+msgid "maximal "
+msgstr "maksimuma "
+
+msgid "; match "
+msgstr "; kongruo "
+
+msgid " line breaks"
+msgstr " liniavancoj"
+
+msgid "E395: contains argument not accepted here"
+msgstr "E395: La argumento \"contains\" ne akcepteblas tie"
+
+msgid "E844: invalid cchar value"
+msgstr "E844: nevalida valoro de cchar"
+
+msgid "E393: group[t]here not accepted here"
+msgstr "E393: La argumento \"group[t]here\" ne akcepteblas tie"
+
+#, c-format
+msgid "E394: Didn't find region item for %s"
+msgstr "E394: Ne trovis regionan elementon por %s"
+
+msgid "E397: Filename required"
+msgstr "E397: Dosiernomo bezonata"
+
+msgid "E847: Too many syntax includes"
+msgstr "E847: Tro da sintaksaj inkluzivoj"
+
+#, c-format
+msgid "E789: Missing ']': %s"
+msgstr "E789: Mankas ']': %s"
+
+#, c-format
+msgid "E398: Missing '=': %s"
+msgstr "E398: Mankas '=': %s"
+
+#, c-format
+msgid "E399: Not enough arguments: syntax region %s"
+msgstr "E399: Ne sufiĉaj argumentoj: sintaksa regiono %s"
+
+msgid "E848: Too many syntax clusters"
+msgstr "E848: Tro da sintaksaj grupoj"
+
+msgid "E400: No cluster specified"
+msgstr "E400: Neniu fasko specifita"
+
+#, c-format
+msgid "E401: Pattern delimiter not found: %s"
+msgstr "E401: Disigilo de Åablono netrovita: %s"
+
+#, c-format
+msgid "E402: Garbage after pattern: %s"
+msgstr "E402: Forĵetindaĵo post Åablono: %s"
+
+msgid "E403: syntax sync: line continuations pattern specified twice"
+msgstr "E403: sintaksa sinkronigo: Åablono de linia daÅ­rigo specifita dufoje"
+
+#, c-format
+msgid "E404: Illegal arguments: %s"
+msgstr "E404: Nevalidaj argumentoj: %s"
+
+#, c-format
+msgid "E405: Missing equal sign: %s"
+msgstr "E405: Mankas egalsigno: %s"
+
+#, c-format
+msgid "E406: Empty argument: %s"
+msgstr "E406: Malplena argumento: %s"
+
+#, c-format
+msgid "E407: %s not allowed here"
+msgstr "E407: %s ne estas permesebla tie"
+
+#, c-format
+msgid "E408: %s must be first in contains list"
+msgstr "E408: %s devas esti la unua ano de la listo \"contains\""
+
+#, c-format
+msgid "E409: Unknown group name: %s"
+msgstr "E409: Nekonata nomo de grupo: %s"
+
+#, c-format
+msgid "E410: Invalid :syntax subcommand: %s"
+msgstr "E410: Nevalida \":syntax\" subkomando: %s"
+
+msgid "E679: recursive loop loading syncolor.vim"
+msgstr "E679: rekursia buklo dum Åargo de syncolor.vim"
+
+#, c-format
+msgid "E411: highlight group not found: %s"
+msgstr "E411: emfaza grupo netrovita: %s"
+
+#, c-format
+msgid "E412: Not enough arguments: \":highlight link %s\""
+msgstr "E412: Ne sufiĉaj argumentoj: \":highlight link %s\""
+
+#, c-format
+msgid "E413: Too many arguments: \":highlight link %s\""
+msgstr "E413: Tro argumentoj: \":highlight link %s\""
+
+msgid "E414: group has settings, highlight link ignored"
+msgstr "E414: grupo havas agordojn, ligilo de emfazo ignorita"
+
+#, c-format
+msgid "E415: unexpected equal sign: %s"
+msgstr "E415: neatendita egalsigno: %s"
+
+#, c-format
+msgid "E416: missing equal sign: %s"
+msgstr "E416: mankas egalsigno: %s"
+
+#, c-format
+msgid "E417: missing argument: %s"
+msgstr "E417: mankas argumento: %s"
+
+#, c-format
+msgid "E418: Illegal value: %s"
+msgstr "E418: Nevalida valoro: %s"
+
+msgid "E419: FG color unknown"
+msgstr "E419: Nekonata malfona koloro"
+
+msgid "E420: BG color unknown"
+msgstr "E420: Nekonata fona koloro"
+
+#, c-format
+msgid "E421: Color name or number not recognized: %s"
+msgstr "E421: Kolora nomo aÅ­ nombro nerekonita: %s"
+
+#, c-format
+msgid "E422: terminal code too long: %s"
+msgstr "E422: kodo de terminalo estas tro longa: %s"
+
+#, c-format
+msgid "E423: Illegal argument: %s"
+msgstr "E423: Nevalida argumento: %s"
+
+msgid "E424: Too many different highlighting attributes in use"
+msgstr "E424: Tro da malsamaj atributoj de emfazo uzataj"
+
+msgid "E669: Unprintable character in group name"
+msgstr "E669: Nepresebla signo en nomo de grupo"
+
+msgid "W18: Invalid character in group name"
+msgstr "W18: Nevalida signo en nomo de grupo"
+
+msgid "E849: Too many highlight and syntax groups"
+msgstr "E849: Tro da emfazaj kaj sintaksaj grupoj"
+
+msgid "E555: at bottom of tag stack"
+msgstr "E555: ĉe subo de stako de etikedoj"
+
+msgid "E556: at top of tag stack"
+msgstr "E556: ĉe supro de stako de etikedoj"
+
+msgid "E425: Cannot go before first matching tag"
+msgstr "E425: Ne eblas iri antaÅ­ la unuan kongruan etikedon"
+
+#, c-format
+msgid "E426: tag not found: %s"
+msgstr "E426: etikedo netrovita: %s"
+
+# DP: "pri" estas "priority"
+msgid " # pri kind tag"
+msgstr "nro pri tipo etikedo"
+
+msgid "file\n"
+msgstr "dosiero\n"
+
+msgid "E427: There is only one matching tag"
+msgstr "E427: Estas nur unu kongrua etikedo"
+
+msgid "E428: Cannot go beyond last matching tag"
+msgstr "E428: Ne eblas iri preter lastan kongruan etikedon"
+
+#, c-format
+msgid "File \"%s\" does not exist"
+msgstr "La dosiero \"%s\" ne ekzistas"
+
+#. Give an indication of the number of matching tags
+#, c-format
+msgid "tag %d of %d%s"
+msgstr "etikedo %d de %d%s"
+
+msgid " or more"
+msgstr " aÅ­ pli"
+
+msgid " Using tag with different case!"
+msgstr " Uzo de etikedo kun malsama uskleco!"
+
+#, c-format
+msgid "E429: File \"%s\" does not exist"
+msgstr "E429: Dosiero \"%s\" ne ekzistas"
+
+#. Highlight title
+msgid ""
+"\n"
+" # TO tag FROM line in file/text"
+msgstr ""
+"\n"
+"nro AL etikedo DE linio en dosiero/teksto"
+
+#, c-format
+msgid "Searching tags file %s"
+msgstr "Serĉado de dosiero de etikedoj %s"
+
+#, 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"
+
+#, c-format
+msgid "E431: Format error in tags file \"%s\""
+msgstr "E431: Eraro de formato en etikeda dosiero \"%s\""
+
+#, c-format
+msgid "Before byte %ld"
+msgstr "AntaÅ­ bajto %ld"
+
+#, c-format
+msgid "E432: Tags file not sorted: %s"
+msgstr "E432: Etikeda dosiero ne estas ordigita: %s"
+
+#. never opened any tags file
+msgid "E433: No tags file"
+msgstr "E433: Neniu etikeda dosiero"
+
+msgid "E434: Can't find tag pattern"
+msgstr "E434: Ne eblas trovi Åablonon de etikedo"
+
+msgid "E435: Couldn't find tag, just guessing!"
+msgstr "E435: Ne eblis trovi etikedon, nur divenas!"
+
+#, c-format
+msgid "Duplicate field name: %s"
+msgstr "Ripetita kamponomo: %s"
+
+msgid "' not known. Available builtin terminals are:"
+msgstr "' nekonata. Haveblaj terminaloj estas:"
+
+msgid "defaulting to '"
+msgstr "defaÅ­lto al '"
+
+msgid "E557: Cannot open termcap file"
+msgstr "E557: Ne eblas malfermi la dosieron termcap"
+
+msgid "E558: Terminal entry not found in terminfo"
+msgstr "E558: Ne trovis rikordon de terminalo terminfo"
+
+msgid "E559: Terminal entry not found in termcap"
+msgstr "E559: Ne trovis rikordon de terminalo en termcap"
+
+#, c-format
+msgid "E436: No \"%s\" entry in termcap"
+msgstr "E436: Neniu rikordo \"%s\" en termcap"
+
+msgid "E437: terminal capability \"cm\" required"
+msgstr "E437: kapablo de terminalo \"cm\" bezonata"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Terminal keys ---"
+msgstr ""
+"\n"
+"--- Klavoj de terminalo ---"
+
+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"
+
+msgid "Used CUT_BUFFER0 instead of empty selection"
+msgstr "Uzis CUT_BUFFER0 anstataÅ­ malplenan apartigon"
+
+#. This happens when the FileChangedRO autocommand changes the
+#. * file in a way it becomes shorter.
+msgid "E834: Line count changed unexpectedly"
+msgstr "E834: Nombro de linioj ÅanÄiÄis neatendite"
+
+#. must display the prompt
+msgid "No undo possible; continue anyway"
+msgstr "Malfaro neebla; daÅ­rigi tamene"
+
+#, c-format
+msgid "E828: Cannot open undo file for writing: %s"
+msgstr "E828: Ne eblas malfermi la malfaran dosieron por skribi: %s"
+
+#, c-format
+msgid "E825: Corrupted undo file (%s): %s"
+msgstr "E825: Difektita malfara dosiero (%s): %s"
+
+msgid "Cannot write undo file in any directory in 'undodir'"
+msgstr "Ne eblis skribi malfaran dosieron en iu dosiero ajn de 'undodir'"
+
+#, c-format
+msgid "Will not overwrite with undo file, cannot read: %s"
+msgstr "Ne superskribos malfaran dosieron, ne eblis legi: %s"
+
+#, c-format
+msgid "Will not overwrite, this is not an undo file: %s"
+msgstr "Ne superskribos, tio ne estas malfara dosiero: %s"
+
+msgid "Skipping undo file write, nothing to undo"
+msgstr "Preterpasas skribon de malfara dosiero, nenio por malfari"
+
+#, c-format
+msgid "Writing undo file: %s"
+msgstr "Skribas malfaran dosieron: %s"
+
+#, c-format
+msgid "E829: write error in undo file: %s"
+msgstr "E829: Skriberaro en malfara dosiero: %s"
+
+#, c-format
+msgid "Not reading undo file, owner differs: %s"
+msgstr "Ne legas malfaran dosieron, posedanto malsamas: %s"
+
+#, c-format
+msgid "Reading undo file: %s"
+msgstr "Legado de malfara dosiero: %s"
+
+#, c-format
+msgid "E822: Cannot open undo file for reading: %s"
+msgstr "E822: Ne eblas malfermi malfaran dosieron por legi: %s"
+
+#, c-format
+msgid "E823: Not an undo file: %s"
+msgstr "E823: Ne estas malfara dosiero: %s"
+
+#, c-format
+msgid "E832: Non-encrypted file has encrypted undo file: %s"
+msgstr "E832: Ne ĉifrata dosiero havas ĉifratan malfaran dosieron: %s"
+
+#, c-format
+msgid "E826: Undo file decryption failed: %s"
+msgstr "E826: Malĉifrado de malfara dosiero fiaskis: %s"
+
+#, c-format
+msgid "E827: Undo file is encrypted: %s"
+msgstr "E827: Malfara dosiero estas ĉifrata: %s"
+
+#, c-format
+msgid "E824: Incompatible undo file: %s"
+msgstr "E824: Malkongrua malfara dosiero: %s"
+
+msgid "File contents changed, cannot use undo info"
+msgstr "Enhavo de dosiero ÅanÄiÄis, ne eblas uzi malfarajn informojn"
+
+#, c-format
+msgid "Finished reading undo file %s"
+msgstr "Finis legi malfaran dosieron %s"
+
+msgid "Already at oldest change"
+msgstr "Jam al la plej malnova ÅanÄo"
+
+msgid "Already at newest change"
+msgstr "Jam al la plej nova ÅanÄo"
+
+#, c-format
+msgid "E830: Undo number %ld not found"
+msgstr "E830: Malfara numero %ld netrovita"
+
+msgid "E438: u_undo: line numbers wrong"
+msgstr "E438: u_undo: nevalidaj numeroj de linioj"
+
+msgid "more line"
+msgstr "plia linio"
+
+msgid "more lines"
+msgstr "pliaj linioj"
+
+msgid "line less"
+msgstr "malpli linio"
+
+msgid "fewer lines"
+msgstr "malpli linioj"
+
+msgid "change"
+msgstr "ÅanÄo"
+
+msgid "changes"
+msgstr "ÅanÄoj"
+
+#, c-format
+msgid "%ld %s; %s #%ld %s"
+msgstr "%ld %s; %s #%ld %s"
+
+msgid "before"
+msgstr "antaÅ­"
+
+msgid "after"
+msgstr "post"
+
+msgid "Nothing to undo"
+msgstr "Nenio por malfari"
+
+msgid "number changes when saved"
+msgstr "numero ÅanÄoj tempo konservita"
+
+#, c-format
+msgid "%ld seconds ago"
+msgstr "antaÅ­ %ld sekundoj"
+
+msgid "E790: undojoin is not allowed after undo"
+msgstr "E790: undojoin estas nepermesebla post malfaro"
+
+msgid "E439: undo list corrupt"
+msgstr "E439: listo de malfaro estas difekta"
+
+msgid "E440: undo line missing"
+msgstr "E440: linio de malfaro mankas"
+
+#. Only MS VC 4.1 and earlier can do Win32s
+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"
+"Included patches: "
+msgstr ""
+"\n"
+"Flikaĵoj inkluzivitaj: "
+
+msgid ""
+"\n"
+"Extra patches: "
+msgstr ""
+"\n"
+"Ekstraj flikaĵoj: "
+
+msgid "Modified by "
+msgstr "Modifita de "
+
+msgid ""
+"\n"
+"Compiled "
+msgstr ""
+"\n"
+"Kompilita "
+
+msgid "by "
+msgstr "de "
+
+msgid ""
+"\n"
+"Huge version "
+msgstr ""
+"\n"
+"Grandega versio "
+
+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."
+
+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"
+
+msgid " system vimrc file: \""
+msgstr " sistema dosiero vimrc: \""
+
+msgid " user vimrc file: \""
+msgstr " dosiero vimrc de uzanto: \""
+
+msgid " 2nd user vimrc file: \""
+msgstr " 2-a dosiero vimrc de uzanto: \""
+
+msgid " 3rd user vimrc file: \""
+msgstr " 3-a dosiero vimrc de uzanto: \""
+
+msgid " user exrc file: \""
+msgstr " dosiero exrc de uzanto: \""
+
+msgid " 2nd user exrc file: \""
+msgstr " 2-a dosiero exrc de uzanto: \""
+
+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 " fall-back for $VIM: \""
+msgstr " defaÅ­lto de $VIM: \""
+
+msgid " f-b for $VIMRUNTIME: \""
+msgstr " defaÅ­lto de VIMRUNTIME: \""
+
+msgid "Compilation: "
+msgstr "Kompilado: "
+
+msgid "Compiler: "
+msgstr "Kompililo: "
+
+msgid "Linking: "
+msgstr "Ligado: "
+
+msgid " DEBUG BUILD"
+msgstr " SENCIMIGA MUNTO"
+
+msgid "VIM - Vi IMproved"
+msgstr "VIM - Vi plibonigita"
+
+msgid "version "
+msgstr "versio "
+
+# DP: vidu http://www.thefreedictionary.com/et+al.
+msgid "by Bram Moolenaar et al."
+msgstr "de Bram Moolenaar kaj aliuloj"
+
+msgid "Vim is open source and freely distributable"
+msgstr "Vim estas libera programo kaj disdoneblas libere"
+
+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
+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
+msgid "type :q<Enter> to exit "
+msgstr "tajpu :q<Enenklavo> por eliri "
+
+# DP: atentu al la spacetoj: ĉiuj ĉenoj devas havi la saman longon
+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
+msgid "type :help version7<Enter> for version info"
+msgstr "tajpu :help version7<Enenklavo> por informo de versio"
+
+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
+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
+msgid "type :help cp-default<Enter> for info on this"
+msgstr "tajpu :help cp-default<Enenklavo> por pliaj informoj "
+
+# 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!"
+
+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
+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
+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
+msgid "menu Help->Sponsor/Register for information "
+msgstr "menuo Helpo->Subteni/Registri por pliaj informoj "
+
+msgid "WARNING: Windows 95/98/ME detected"
+msgstr "AVERTO: Trovis Vindozon 95/98/ME"
+
+# 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 "Already only one window"
+msgstr "Jam nur unu fenestro"
+
+msgid "E441: There is no preview window"
+msgstr "E441: Ne estas antaÅ­vida fenestro"
+
+msgid "E442: Can't split topleft and botright at the same time"
+msgstr "E442: Ne eblas dividi supralivan kaj subdekstran samtempe"
+
+msgid "E443: Cannot rotate when another window is split"
+msgstr "E443: Ne eblas rotacii kiam alia fenestro estas dividita"
+
+msgid "E444: Cannot close last window"
+msgstr "E444: Ne eblas fermi la lastan fenestron"
+
+msgid "E813: Cannot close autocmd window"
+msgstr "E813: Ne eblas fermi la fenestron de aÅ­tokomandoj"
+
+msgid "E814: Cannot close window, only autocmd window would remain"
+msgstr "E814: Ne eblas fermi fenestron, nur la fenestro de aÅ­tokomandoj restus"
+
+msgid "E445: Other window contains changes"
+msgstr "E445: La alia fenestro enhavas ÅanÄojn"
+
+msgid "E446: No file name under cursor"
+msgstr "E446: Neniu dosiernomo sub la kursoro"
+
+#, c-format
+msgid "E447: Can't find file \"%s\" in path"
+msgstr "E447: Ne eblas trovi dosieron \"%s\" en serĉvojo"
+
+#, c-format
+msgid "E370: Could not load library %s"
+msgstr "E370: Ne eblis Åargi bibliotekon %s"
+
+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 "E299: Perl evaluation forbidden in sandbox without the Safe module"
+msgstr ""
+"E299: Plenumo de Perl esprimoj malpermesata en sabloludejo sen la modulo Safe"
+
+msgid "Edit with &multiple Vims"
+msgstr "Redakti per &pluraj Vim-oj"
+
+msgid "Edit with single &Vim"
+msgstr "Redakti per unuopa &Vim"
+
+msgid "Diff with Vim"
+msgstr "Kompari per Vim"
+
+msgid "Edit with &Vim"
+msgstr "Redakti per &Vim"
+
+#. Now concatenate
+msgid "Edit with existing Vim - "
+msgstr "Redakti per ekzistanta Vim - "
+
+msgid "Edits the selected file(s) with Vim"
+msgstr "Redakti la apartigita(j)n dosiero(j)n per Vim"
+
+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 "gvimext.dll error"
+msgstr "Eraro de gvimext.dll"
+
+msgid "Path length too long!"
+msgstr "Serĉvojo estas tro longa!"
+
+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.
+#.
+msgid "E470: Command aborted"
+msgstr "E470: komando ĉesigita"
+
+msgid "E471: Argument required"
+msgstr "E471: Argumento bezonata"
+
+msgid "E10: \\ should be followed by /, ? or &"
+msgstr "E10: \\ devus esti sekvita de /, ? aÅ­ &"
+
+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 "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 "E171: Missing :endif"
+msgstr "E171: Mankas \":endif\""
+
+msgid "E600: Missing :endtry"
+msgstr "E600: Mankas \":endtry\""
+
+msgid "E170: Missing :endwhile"
+msgstr "E170: Mankas \":endwhile\""
+
+msgid "E170: Missing :endfor"
+msgstr "E170: Mankas \":endfor\""
+
+msgid "E588: :endwhile without :while"
+msgstr "E588: \":endwhile\" sen \":while\""
+
+msgid "E588: :endfor without :for"
+msgstr "E588: \":endfor\" sen \":for\""
+
+msgid "E13: File exists (add ! to override)"
+msgstr "E13: Dosiero ekzistas (aldonu ! por transpasi)"
+
+msgid "E472: Command failed"
+msgstr "E472: La komando fiaskis"
+
+#, c-format
+msgid "E234: Unknown fontset: %s"
+msgstr "E234: Nekonata familio de tiparo: %s"
+
+#, c-format
+msgid "E235: Unknown font: %s"
+msgstr "E235: Nekonata tiparo: %s"
+
+#, c-format
+msgid "E236: Font \"%s\" is not fixed-width"
+msgstr "E236: La tiparo \"%s\" ne estas egallarÄa"
+
+msgid "E473: Internal error"
+msgstr "E473: Interna eraro"
+
+msgid "Interrupted"
+msgstr "Interrompita"
+
+msgid "E14: Invalid address"
+msgstr "E14: Nevalida adreso"
+
+msgid "E474: Invalid argument"
+msgstr "E474: Nevalida argumento"
+
+#, c-format
+msgid "E475: Invalid argument: %s"
+msgstr "E475: Nevalida argumento: %s"
+
+#, c-format
+msgid "E15: Invalid expression: %s"
+msgstr "E15: Nevalida esprimo: %s"
+
+msgid "E16: Invalid range"
+msgstr "E16: Nevalida amplekso"
+
+msgid "E476: Invalid command"
+msgstr "E476: Nevalida komando"
+
+#, c-format
+msgid "E17: \"%s\" is a directory"
+msgstr "E17: \"%s\" estas dosierujo"
+
+#, c-format
+msgid "E364: Library call failed for \"%s()\""
+msgstr "E364: Alvoko al biblioteko fiaskis por \"%s()\""
+
+#, c-format
+msgid "E448: Could not load library function %s"
+msgstr "E448: Ne eblis Åargi bibliotekan funkcion %s"
+
+msgid "E19: Mark has invalid line number"
+msgstr "E19: Marko havas nevalidan numeron de linio"
+
+msgid "E20: Mark not set"
+msgstr "E20: Marko ne estas agordita"
+
+msgid "E21: Cannot make changes, 'modifiable' is off"
+msgstr "E21: Ne eblas fari ÅanÄojn, 'modifiable' estas malÅaltita"
+
+msgid "E22: Scripts nested too deep"
+msgstr "E22: Tro profunde ingitaj skriptoj"
+
+msgid "E23: No alternate file"
+msgstr "E23: Neniu alterna dosiero"
+
+msgid "E24: No such abbreviation"
+msgstr "E24: Ne estas tia mallongigo"
+
+msgid "E477: No ! allowed"
+msgstr "E477: Neniu ! permesebla"
+
+msgid "E25: GUI cannot be used: Not enabled at compile time"
+msgstr "E25: Grafika interfaco ne uzeblas: MalÅaltita dum kompilado"
+
+msgid "E26: Hebrew cannot be used: Not enabled at compile time\n"
+msgstr "E26: La hebrea ne uzeblas: MalÅaltita dum kompilado\n"
+
+msgid "E27: Farsi cannot be used: Not enabled at compile time\n"
+msgstr "E27: La persa ne uzeblas: MalÅaltita dum kompilado\n"
+
+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 "E28: No such highlight group name: %s"
+msgstr "E28: Neniu grupo de emfazo kiel: %s"
+
+msgid "E29: No inserted text yet"
+msgstr "E29: AnkoraÅ­ neniu enmetita teksto"
+
+msgid "E30: No previous command line"
+msgstr "E30: Neniu antaÅ­a komanda linio"
+
+msgid "E31: No such mapping"
+msgstr "E31: Neniu tiel mapo"
+
+msgid "E479: No match"
+msgstr "E479: Neniu kongruo"
+
+#, c-format
+msgid "E480: No match: %s"
+msgstr "E480: Neniu kongruo: %s"
+
+msgid "E32: No file name"
+msgstr "E32: Neniu dosiernomo"
+
+msgid "E33: No previous substitute regular expression"
+msgstr "E33: Neniu antaÅ­a regulesprimo de anstataÅ­igo"
+
+msgid "E34: No previous command"
+msgstr "E34: Neniu antaÅ­a komando"
+
+msgid "E35: No previous regular expression"
+msgstr "E35: Neniu antaÅ­a regulesprimo"
+
+msgid "E481: No range allowed"
+msgstr "E481: Amplekso nepermesebla"
+
+msgid "E36: Not enough room"
+msgstr "E36: Ne sufiĉe da spaco"
+
+#, c-format
+msgid "E247: no registered server named \"%s\""
+msgstr "E247: neniu registrita servilo nomita \"%s\""
+
+#, c-format
+msgid "E482: Can't create file %s"
+msgstr "E482: Ne eblas krei dosieron %s"
+
+msgid "E483: Can't get temp file name"
+msgstr "E483: Ne eblas akiri provizoran dosiernomon"
+
+#, c-format
+msgid "E484: Can't open file %s"
+msgstr "E484: Ne eblas malfermi dosieron %s"
+
+#, c-format
+msgid "E485: Can't read file %s"
+msgstr "E485: Ne eblas legi dosieron %s"
+
+msgid "E37: No write since last change (add ! to override)"
+msgstr "E37: Neniu skribo de post lasta ÅanÄo (aldonu ! por transpasi)"
+
+msgid "E38: Null argument"
+msgstr "E38: Nula argumento"
+
+msgid "E39: Number expected"
+msgstr "E39: Nombro atendita"
+
+#, c-format
+msgid "E40: Can't open errorfile %s"
+msgstr "E40: Ne eblas malfermi eraran dosieron %s"
+
+msgid "E233: cannot open display"
+msgstr "E233: ne eblas malfermi vidigon"
+
+msgid "E41: Out of memory!"
+msgstr "E41: Ne plu restas memoro!"
+
+msgid "Pattern not found"
+msgstr "Åœablono ne trovita"
+
+#, c-format
+msgid "E486: Pattern not found: %s"
+msgstr "E486: Åœablono ne trovita: %s"
+
+msgid "E487: Argument must be positive"
+msgstr "E487: La argumento devas esti pozitiva"
+
+msgid "E459: Cannot go back to previous directory"
+msgstr "E459: Ne eblas reiri al antaÅ­a dosierujo"
+
+msgid "E42: No Errors"
+msgstr "E42: Neniu eraro"
+
+msgid "E776: No location list"
+msgstr "E776: Neniu listo de loko"
+
+msgid "E43: Damaged match string"
+msgstr "E43: Difekta kongruenda ĉeno"
+
+msgid "E44: Corrupted regexp program"
+msgstr "E44: Difekta programo de regulesprimo"
+
+msgid "E45: 'readonly' option is set (add ! to override)"
+msgstr "E45: La opcio 'readonly' estas Åaltita '(aldonu ! por transpasi)"
+
+#, c-format
+msgid "E46: Cannot change read-only variable \"%s\""
+msgstr "E46: Ne eblas ÅanÄi nurlegeblan variablon \"%s\""
+
+#, c-format
+msgid "E794: Cannot set variable in the sandbox: \"%s\""
+msgstr "E794: Ne eblas agordi variablon en la sabloludejo: \"%s\""
+
+msgid "E47: Error while reading errorfile"
+msgstr "E47: Eraro dum legado de erardosiero"
+
+msgid "E48: Not allowed in sandbox"
+msgstr "E48: Nepermesebla en sabloludejo"
+
+msgid "E523: Not allowed here"
+msgstr "E523: Nepermesebla tie"
+
+msgid "E359: Screen mode setting not supported"
+msgstr "E359: ReÄimo de ekrano ne subtenata"
+
+msgid "E49: Invalid scroll size"
+msgstr "E49: Nevalida grando de rulumo"
+
+msgid "E91: 'shell' option is empty"
+msgstr "E91: La opcio 'shell' estas malplena"
+
+msgid "E255: Couldn't read in sign data!"
+msgstr "E255: Ne eblis legi datumojn de simboloj!"
+
+msgid "E72: Close error on swap file"
+msgstr "E72: Eraro dum malfermo de permutodosiero .swp"
+
+msgid "E73: tag stack empty"
+msgstr "E73: malplena stako de etikedo"
+
+msgid "E74: Command too complex"
+msgstr "E74: Komando tro kompleksa"
+
+msgid "E75: Name too long"
+msgstr "E75: Nomo tro longa"
+
+msgid "E76: Too many ["
+msgstr "E76: Tro da ["
+
+msgid "E77: Too many file names"
+msgstr "E77: Tro da dosiernomoj"
+
+msgid "E488: Trailing characters"
+msgstr "E488: Vostaj signoj"
+
+msgid "E78: Unknown mark"
+msgstr "E78: Nekonata marko"
+
+msgid "E79: Cannot expand wildcards"
+msgstr "E79: Ne eblas malvolvi ĵokerojn"
+
+msgid "E591: 'winheight' cannot be smaller than 'winminheight'"
+msgstr "E591: 'winheight' ne rajtas esti malpli ol 'winminheight'"
+
+msgid "E592: 'winwidth' cannot be smaller than 'winminwidth'"
+msgstr "E592: 'winwidth' ne rajtas esti malpli ol 'winminwidth'"
+
+msgid "E80: Error while writing"
+msgstr "E80: Eraro dum skribado"
+
+msgid "Zero count"
+msgstr "Nul kvantoro"
+
+msgid "E81: Using <SID> not in a script context"
+msgstr "E81: Uzo de <SID> ekster kunteksto de skripto"
+
+msgid "E449: Invalid expression received"
+msgstr "E449: Nevalida esprimo ricevita"
+
+msgid "E463: Region is guarded, cannot modify"
+msgstr "E463: Regiono estas gardita, ne eblas ÅanÄi"
+
+msgid "E744: NetBeans does not allow changes in read-only files"
+msgstr "E744: NetBeans ne permesas ÅanÄojn en nurlegeblaj dosieroj"
+
+#, c-format
+msgid "E685: Internal error: %s"
+msgstr "E685: Interna eraro: %s"
+
+msgid "E363: pattern uses more memory than 'maxmempattern'"
+msgstr "E363: Åablono uzas pli da memoro ol 'maxmempattern'"
+
+msgid "E749: empty buffer"
+msgstr "E749: malplena bufro"
+
+msgid "E682: Invalid search pattern or delimiter"
+msgstr "E682: Nevalida serĉa Åablono aÅ­ disigilo"
+
+msgid "E139: File is loaded in another buffer"
+msgstr "E139: Dosiero estas Åargita en alia bufro"
+
+#, c-format
+msgid "E764: Option '%s' is not set"
+msgstr "E764: La opcio '%s' ne estas Åaltita"
+
+msgid "E850: Invalid register name"
+msgstr "E850: Nevalida nomo de reÄistro"
+
+msgid "search hit TOP, continuing at BOTTOM"
+msgstr "serĉo atingis SUPRON, daŭrigonte al SUBO"
+
+msgid "search hit BOTTOM, continuing at TOP"
+msgstr "serĉo atingis SUBON, daŭrigonte al SUPRO"
+
+#, c-format
+msgid "Need encryption key for \"%s\""
+msgstr "Ŝlosilo de ĉifrado bezonata por \"%s\""
+
+msgid "can't delete OutputObject attributes"
+msgstr "ne eblas forviÅi atributojn de OutputObject"
+
+msgid "softspace must be an integer"
+msgstr "malmolspaceto (softspace) devas esti entjero"
+
+msgid "invalid attribute"
+msgstr "nevalida atributo"
+
+msgid "writelines() requires list of strings"
+msgstr "writelines() bezonas liston de ĉenoj"
+
+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 "Cannot delete DictionaryObject attributes"
+msgstr "ne eblas forviÅi atributojn de DictionaryObject"
+
+msgid "Cannot modify fixed dictionary"
+msgstr "Ne eblas ÅanÄi fiksan vortaron"
+
+msgid "Cannot set this attribute"
+msgstr "Ne eblas agordi tiun atributon"
+
+msgid "dict is locked"
+msgstr "vortaro estas Ålosita"
+
+msgid "failed to add key to dictionary"
+msgstr "aldono de Ålosilo al vortaro fiaskis"
+
+msgid "list index out of range"
+msgstr "indekso de listo ekster limoj"
+
+msgid "internal error: failed to get vim list item"
+msgstr "interna eraro: obteno de vim-a listero fiaskis"
+
+msgid "list is locked"
+msgstr "listo estas Ålosita"
+
+msgid "Failed to add item to list"
+msgstr "Aldono de listero fiaskis"
+
+msgid "internal error: no vim list item"
+msgstr "interna eraro: neniu vim-a listero"
+
+msgid "can only assign lists to slice"
+msgstr "nur eblas pravalorizi listojn al segmento"
+
+msgid "internal error: failed to add item to list"
+msgstr "interna eraro: aldono de listero fiaskis"
+
+msgid "can only concatenate with lists"
+msgstr "eblas nur kunmeti kun listoj"
+
+msgid "cannot delete vim.dictionary attributes"
+msgstr "ne eblas forviÅi atributojn de 'vim.dictionary'"
+
+msgid "cannot modify fixed list"
+msgstr "ne eblas ÅanÄi fiksan liston"
+
+msgid "cannot set this attribute"
+msgstr "ne eblas agordi tiun atributon"
+
+msgid "'self' argument must be a dictionary"
+msgstr "argumento 'self' devas esti vortaro"
+
+msgid "failed to run function"
+msgstr "fiaskis ruli funkcion"
+
+msgid "unable to get option value"
+msgstr "fiaskis akiri valoron de opcio"
+
+msgid "unable to unset global option"
+msgstr "ne povis malÅalti mallokan opcion"
+
+msgid "unable to unset option without global value"
+msgstr "ne povis malÅalti opcion sen malloka valoro"
+
+msgid "object must be integer"
+msgstr "objekto devas esti entjero."
+
+msgid "object must be string"
+msgstr "objekto devas esti ĉeno"
+
+msgid "attempt to refer to deleted tab page"
+msgstr "provo de referenco al forviÅita langeto"
+
+#, c-format
+msgid "<tabpage object (deleted) at %p>"
+msgstr "<langeta objekto (forviÅita) ĉe %p>"
+
+#, c-format
+msgid "<tabpage object (unknown) at %p>"
+msgstr "<langeta objekto (nekonata) ĉe %p>"
+
+#, c-format
+msgid "<tabpage %d>"
+msgstr "<langeto %d>"
+
+msgid "no such tab page"
+msgstr "ne estas tia langeto"
+
+msgid "attempt to refer to deleted window"
+msgstr "provo de referenco al forviÅita fenestro"
+
+msgid "readonly attribute"
+msgstr "nurlegebla atributo"
+
+msgid "cursor position outside buffer"
+msgstr "kursoro poziciita ekster bufro"
+
+#, c-format
+msgid "<window object (deleted) at %p>"
+msgstr "<fenestra objekto (forviÅita) ĉe %p>"
+
+#, c-format
+msgid "<window object (unknown) at %p>"
+msgstr "<objekta fenestro (nekonata) ĉe %p>"
+
+#, c-format
+msgid "<window %d>"
+msgstr "<fenestro %d>"
+
+msgid "no such window"
+msgstr "ne estas tia fenestro"
+
+msgid "attempt to refer to deleted buffer"
+msgstr "provo de referenco al forviÅita bufro"
+
+#, c-format
+msgid "<buffer object (deleted) at %p>"
+msgstr "<bufra objekto (forviÅita) ĉe %p>"
+
+msgid "key must be integer"
+msgstr "Ålosilo devas esti entjero."
+
+msgid "expected vim.buffer object"
+msgstr "atendis objekton vim.buffer"
+
+msgid "failed to switch to given buffer"
+msgstr "ne povis salti al la specifita bufro"
+
+msgid "expected vim.window object"
+msgstr "atendis objekton vim.window"
+
+msgid "failed to find window in the current tab page"
+msgstr "ne povis trovi vindozon en la nuna langeto"
+
+msgid "did not switch to the specified window"
+msgstr "ne saltis al la specifita vindozo"
+
+msgid "expected vim.tabpage object"
+msgstr "atendis objekton vim.tabpage"
+
+msgid "did not switch to the specified tab page"
+msgstr "ne saltis al la specifita langeto"
+
+msgid "failed to run the code"
+msgstr "fiaskis ruli la kodon"
+
+msgid "E858: Eval did not return a valid python object"
+msgstr "E858: Eval ne revenis kun valida python-objekto"
+
+msgid "E859: Failed to convert returned python object to vim value"
+msgstr "E859: Konverto de revena python-objekto al vim-valoro fiaskis"
+
+msgid "unable to convert to vim structure"
+msgstr "ne povis konverti al vim-strukturo"
+
+msgid "NULL reference passed"
+msgstr "NULL-referenco argumento"
+
+msgid "internal error: invalid value type"
+msgstr "interna eraro: nevalida tipo de valoro"
+
+#~ msgid "E863: return value must be an instance of str"
+#~ msgstr "E863: elira valoro devas esti apero de str"
+
+#~ msgid "E860: Eval did not return a valid python 3 object"
+#~ msgstr "E860: Eval ne revenis kun valida python3-objekto"
+
+#~ msgid "E861: Failed to convert returned python 3 object to vim value"
+#~ msgstr "E861: Konverto de revena python3-objekto al vim-valoro fiaskis"
+
+#~ msgid "Only boolean objects are allowed"
+#~ msgstr "Nur buleaj objektoj estas permeseblaj"
+
+#~ msgid "no such key in dictionary"
+#~ msgstr "tiu Ålosilo ne ekzistas en vortaro"
diff --git a/src/po/es.po b/src/po/es.po
new file mode 100644
index 0000000000..5a916caa27
--- /dev/null
+++ b/src/po/es.po
@@ -0,0 +1,8279 @@
+# Vim7/src/po/vim.pot translation to Spanish.
+#
+# Translation project homepage:
+# vim-doc-es http://www.assembla.com/wiki/show/vim-doc-es
+#
+# Last translators:
+# Pedro A. López-Valencia <vorbote@users.sourceforge.net>, 2003-06,2009
+# Omar Campagne Polaino <ocampagne@gmail.com> 2009
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Vim 7.2.284 (rev 1692)\n"
+"Report-Msgid-Bugs-To: vim@bugs.org\n"
+"POT-Creation-Date: 2009-11-25 02:05+0100\n"
+"PO-Revision-Date: 2009-12-04 18:52+0100\n"
+"Last-Translator: Omar Campagne <ocampagne@gmail.com>\n"
+"Language-Team: vim-doc-es http://www.assembla.com/wiki/show/vim-doc-es\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: octect-stream\n"
+
+#: buffer.c:102
+msgid "E82: Cannot allocate any buffer, exiting..."
+msgstr "E82: No se pudo asignar memoria para ningún búfer, saliendo..."
+
+#: buffer.c:105
+msgid "E83: Cannot allocate buffer, using other one..."
+msgstr "E83: No se pudo asignar memoria para el búfer, usando otro..."
+
+#: buffer.c:879
+msgid "E515: No buffers were unloaded"
+msgstr "E515: No se descargó ningún búfer"
+
+#: buffer.c:881
+msgid "E516: No buffers were deleted"
+msgstr "E516: No se borró ningún búfer"
+
+#: buffer.c:883
+msgid "E517: No buffers were wiped out"
+msgstr "E517: No se eliminó ningún búfer"
+
+#: buffer.c:891
+msgid "1 buffer unloaded"
+msgstr "Se descargó un (1) búfer"
+
+#: buffer.c:893
+#, c-format
+msgid "%d buffers unloaded"
+msgstr "Se descargaron %d búfers"
+
+#: buffer.c:898
+msgid "1 buffer deleted"
+msgstr "Se suprimió un (1) búfer"
+
+#: buffer.c:900
+#, c-format
+msgid "%d buffers deleted"
+msgstr "Se suprimieron %d búfers"
+
+#: buffer.c:905
+msgid "1 buffer wiped out"
+msgstr "Se eliminó un (1) búfer"
+
+#: buffer.c:907
+#, c-format
+msgid "%d buffers wiped out"
+msgstr "Se eliminaron %d búfers"
+
+#: buffer.c:965
+msgid "E84: No modified buffer found"
+msgstr "E84: No se encontró ningún búfer modificado"
+
+# back where we started, didn't find anything.
+#. back where we started, didn't find anything.
+#: buffer.c:1004
+msgid "E85: There is no listed buffer"
+msgstr "E85: No hay búfers en la lista"
+
+#: buffer.c:1016
+#, c-format
+msgid "E86: Buffer %ld does not exist"
+msgstr "E86: El búfer %ld no existe"
+
+#: buffer.c:1019
+msgid "E87: Cannot go beyond last buffer"
+msgstr "E87: No se pudo ir más allá del último búfer"
+
+#: buffer.c:1021
+msgid "E88: Cannot go before first buffer"
+msgstr "E88: No se pudo regresar antes del primer búfer"
+
+#: buffer.c:1063
+#, c-format
+msgid "E89: No write since last change for buffer %ld (add ! to override)"
+msgstr ""
+"E89: No se guardó el archivo desde el último cambio del búfer %ld (añada \"!"
+"\" para forzar)"
+
+#: buffer.c:1080
+msgid "E90: Cannot unload last buffer"
+msgstr "E90: No se pudo descargar el último búfer"
+
+#: buffer.c:1651
+msgid "W14: Warning: List of file names overflow"
+msgstr "W14: Advertencia: La lista de nombres de archivos es muy larga"
+
+#: buffer.c:1850 quickfix.c:3632
+#, c-format
+msgid "E92: Buffer %ld not found"
+msgstr "E92: No se encontró el búfer %ld"
+
+#: buffer.c:2125
+#, c-format
+msgid "E93: More than one match for %s"
+msgstr "E93: Hay más de una coincidencia con %s"
+
+#: buffer.c:2127
+#, c-format
+msgid "E94: No matching buffer for %s"
+msgstr "E94: No hay un búfer que coincida con %s"
+
+#: buffer.c:2579
+#, c-format
+msgid "line %ld"
+msgstr "línea %ld"
+
+#: buffer.c:2666
+msgid "E95: Buffer with this name already exists"
+msgstr "E95: Ya existe un búfer con este nombre"
+
+#: buffer.c:2993
+msgid " [Modified]"
+msgstr " [Modificado]"
+
+#: buffer.c:2998
+msgid "[Not edited]"
+msgstr "[Sin editar]"
+
+#: buffer.c:3003
+msgid "[New file]"
+msgstr "[Archivo nuevo]"
+
+#: buffer.c:3004
+msgid "[Read errors]"
+msgstr "[Errores de lectura]"
+
+#: buffer.c:3006 fileio.c:2391 netbeans.c:3632
+msgid "[readonly]"
+msgstr "[Sólo lectura]"
+
+#: buffer.c:3029
+#, c-format
+msgid "1 line --%d%%--"
+msgstr "1 línea --%d%%--"
+
+#: buffer.c:3032
+#, c-format
+msgid "%ld lines --%d%%--"
+msgstr "%ld líneas --%d%%--"
+
+#: buffer.c:3039
+#, c-format
+msgid "line %ld of %ld --%d%%-- col "
+msgstr "línea %ld de %ld --%d%%-- col "
+
+#: buffer.c:3160 buffer.c:5126 memline.c:1727
+msgid "[No Name]"
+msgstr "[Sin nombre]"
+
+# must be a help buffer
+#. must be a help buffer
+#: buffer.c:3198
+msgid "help"
+msgstr "ayuda"
+
+#: buffer.c:3826 screen.c:5817
+msgid "[Help]"
+msgstr "[Ayuda]"
+
+#: buffer.c:3860 screen.c:5823
+msgid "[Preview]"
+msgstr "[Vista previa]"
+
+#: buffer.c:4182
+msgid "All"
+msgstr "Todo"
+
+#: buffer.c:4182
+msgid "Bot"
+msgstr "Final"
+
+#: buffer.c:4185
+msgid "Top"
+msgstr "Comienzo"
+
+#: buffer.c:5061
+#, c-format
+msgid ""
+"\n"
+"# Buffer list:\n"
+msgstr ""
+"\n"
+"# Lista de búfers:\n"
+
+#: buffer.c:5110
+msgid "[Location List]"
+msgstr "[Lista de ubicaciones]"
+
+#: buffer.c:5112
+msgid "[Quickfix List]"
+msgstr "[Lista de cambios rápidos]"
+
+#: buffer.c:5122
+msgid "[Scratch]"
+msgstr "[De cero]"
+
+#: buffer.c:5439
+msgid ""
+"\n"
+"--- Signs ---"
+msgstr ""
+"\n"
+"--- Signos ---"
+
+#: buffer.c:5449
+#, c-format
+msgid "Signs for %s:"
+msgstr "Signos para %s:"
+
+#: buffer.c:5455
+#, c-format
+msgid " line=%ld id=%d name=%s"
+msgstr " línea=%ld id=%d nombre=%s"
+
+#: diff.c:141
+#, c-format
+msgid "E96: Can not diff more than %ld buffers"
+msgstr "E96: No se puede usar \"diff\" con más de %ld búfers"
+
+#: diff.c:777
+msgid "E810: Cannot read or write temp files"
+msgstr "E810: No se puede leer o escribir en archivos temporales"
+
+#: diff.c:778
+msgid "E97: Cannot create diffs"
+msgstr "E97: No se pudieron crear las \"diffs\" (diferencias)"
+
+#: diff.c:901
+msgid "Patch file"
+msgstr "Archivo de parches"
+
+#: diff.c:1005
+msgid "E816: Cannot read patch output"
+msgstr "E816: No se pudo leer la salida del parche"
+
+#: diff.c:1227
+msgid "E98: Cannot read diff output"
+msgstr "E98: No se pudo leer la salida de \"diff\""
+
+#: diff.c:2086
+msgid "E99: Current buffer is not in diff mode"
+msgstr "E99: El búfer actual no está en modo de diferencias"
+
+#: diff.c:2105
+msgid "E793: No other buffer in diff mode is modifiable"
+msgstr "E793: Ningún otro búfer está en modo de diferencias"
+
+#: diff.c:2107
+msgid "E100: No other buffer in diff mode"
+msgstr "E100: Ningún otro búfer está en modo de diferencias"
+
+#: diff.c:2117
+msgid "E101: More than two buffers in diff mode, don't know which one to use"
+msgstr "E101: Más de dos búfers en modo de diferencias, no se cual usar"
+
+#: diff.c:2140
+#, c-format
+msgid "E102: Can't find buffer \"%s\""
+msgstr "E102: No se pudo encontrar el búfer %s"
+
+#: diff.c:2148
+#, c-format
+msgid "E103: Buffer \"%s\" is not in diff mode"
+msgstr "E103: El búfer \"%s\" no está en modo de diferencias"
+
+#: diff.c:2192
+msgid "E787: Buffer changed unexpectedly"
+msgstr "E787: El búfer cambió inesperadamente"
+
+#: digraph.c:2251
+msgid "E104: Escape not allowed in digraph"
+msgstr "E104: El código de escape no se permite en un dígrafo"
+
+#: digraph.c:2444
+msgid "E544: Keymap file not found"
+msgstr "E544: No se encontró el archivo \"keymap\""
+
+#: digraph.c:2471
+msgid "E105: Using :loadkeymap not in a sourced file"
+msgstr "E105: Usando \":loadkeymap\" en el archivo suministrado"
+
+#: digraph.c:2510
+msgid "E791: Empty keymap entry"
+msgstr "E791: Definición de \"keymap\" vacía"
+
+#: edit.c:42
+msgid " Keyword completion (^N^P)"
+msgstr " Completar palabra clave (^N^P)"
+
+# ctrl_x_mode == 0, ^P/^N compl.
+#. ctrl_x_mode == 0, ^P/^N compl.
+#: edit.c:43
+msgid " ^X mode (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)"
+msgstr " Modo ^X (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)"
+
+#: edit.c:45
+msgid " Whole line completion (^L^N^P)"
+msgstr " Completar toda la línea (^L^N^P)"
+
+#: edit.c:46
+msgid " File name completion (^F^N^P)"
+msgstr " Completar nombre de archivo (^F^N^P)"
+
+#: edit.c:47
+msgid " Tag completion (^]^N^P)"
+msgstr " Completar etiquetas (^]^N^P)"
+
+#: edit.c:48
+msgid " Path pattern completion (^N^P)"
+msgstr " Completar patrón de ruta (^N^P)"
+
+#: edit.c:49
+msgid " Definition completion (^D^N^P)"
+msgstr " Completar definición (^D^N^P)"
+
+#: edit.c:51
+msgid " Dictionary completion (^K^N^P)"
+msgstr " Completar diccionario (^K^N^P)"
+
+#: edit.c:52
+msgid " Thesaurus completion (^T^N^P)"
+msgstr " Completar palabras con tesauro (^T^N^P)"
+
+#: edit.c:53
+msgid " Command-line completion (^V^N^P)"
+msgstr " Compleción de línea de órdenes (^V^N^P)"
+
+#: edit.c:54
+msgid " User defined completion (^U^N^P)"
+msgstr " Completar definido por usuario (^U^N^P)"
+
+#: edit.c:55
+msgid " Omni completion (^O^N^P)"
+msgstr " Completar con método Omni (^O^N^P)"
+
+#: edit.c:56
+msgid " Spelling suggestion (s^N^P)"
+msgstr " Sugerencia de ortografía (s^N^P)"
+
+# Scroll has it's own msgs, in it's place there is the msg for local
+# * ctrl_x_mode = 0 (eg continue_status & CONT_LOCAL) -- Acevedo
+#: edit.c:57
+msgid " Keyword Local completion (^N^P)"
+msgstr " Completar palabra clave local (^N^P)"
+
+#: edit.c:60
+msgid "Hit end of paragraph"
+msgstr "Se llegó al final del párrafo"
+
+#: edit.c:2038
+msgid "'dictionary' option is empty"
+msgstr "La opción 'dictionary' está vacía"
+
+#: edit.c:2039
+msgid "'thesaurus' option is empty"
+msgstr "La opción 'thesaurus' (tesauro) está vacía"
+
+#: edit.c:2999
+#, c-format
+msgid "Scanning dictionary: %s"
+msgstr "Buscando en el diccionario: %s"
+
+#: edit.c:3484
+msgid " (insert) Scroll (^E/^Y)"
+msgstr " (insertar) Desplazamiento (^E/^Y)"
+
+#: edit.c:3486
+msgid " (replace) Scroll (^E/^Y)"
+msgstr " (reemplazar) Desplazamiento (^E/^Y)"
+
+#: edit.c:3963
+#, c-format
+msgid "Scanning: %s"
+msgstr "Buscando: %s"
+
+#: edit.c:3998
+msgid "Scanning tags."
+msgstr "Buscando etiquetas."
+
+#: edit.c:5010
+msgid " Adding"
+msgstr "Añadiendo"
+
+# 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.
+#
+#. 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:5057
+msgid "-- Searching..."
+msgstr "-- Buscando..."
+
+#: edit.c:5116
+msgid "Back at original"
+msgstr "De vuelta al original"
+
+#: edit.c:5121
+msgid "Word from other line"
+msgstr "Palabra proveniente de otra línea"
+
+#: edit.c:5126
+msgid "The only match"
+msgstr "La única coincidencia"
+
+#: edit.c:5191
+#, c-format
+msgid "match %d of %d"
+msgstr "coincidencia %d de %d"
+
+#: edit.c:5195
+#, c-format
+msgid "match %d"
+msgstr "coincidencia %d"
+
+#: eval.c:96
+msgid "E18: Unexpected characters in :let"
+msgstr "E18: Caracteres inesperados en :let"
+
+#: eval.c:97
+#, c-format
+msgid "E684: list index out of range: %ld"
+msgstr "E684: índice de lista fuera de rango: %ld"
+
+#: eval.c:98
+#, c-format
+msgid "E121: Undefined variable: %s"
+msgstr "E121: Variable sin definir: %s"
+
+#: eval.c:99
+msgid "E111: Missing ']'"
+msgstr "E111: Falta un \"]\""
+
+#: eval.c:100
+#, c-format
+msgid "E686: Argument of %s must be a List"
+msgstr "E686: El argumento de %s debe ser una lista"
+
+#: eval.c:101
+#, c-format
+msgid "E712: Argument of %s must be a List or Dictionary"
+msgstr "E712: El argumento de %s debe ser una lista o un diccionario"
+
+#: eval.c:102
+msgid "E713: Cannot use empty key for Dictionary"
+msgstr "E713: No se puede usar una llave vacía para el diccionario"
+
+#: eval.c:103
+msgid "E714: List required"
+msgstr "E714: Se requiere una lista"
+
+#: eval.c:104
+msgid "E715: Dictionary required"
+msgstr "E715: Se requiere de un diccionario"
+
+#: eval.c:105
+#, c-format
+msgid "E118: Too many arguments for function: %s"
+msgstr "E118: Demasiados argumentos para la función: %s"
+
+#: eval.c:106
+#, c-format
+msgid "E716: Key not present in Dictionary: %s"
+msgstr "E716: No se encuentra la llave en el diccionario. %s"
+
+#: eval.c:107
+#, c-format
+msgid "E122: Function %s already exists, add ! to replace it"
+msgstr "E122: La función %s ya existe, añada \"!\" para reemplazarla"
+
+#: eval.c:108
+msgid "E717: Dictionary entry already exists"
+msgstr "E717: Esta entrada ya existe en el diccionario"
+
+#: eval.c:109
+msgid "E718: Funcref required"
+msgstr "E718: Se requiere una referencia de función"
+
+# if Vim opened a window: Executing a shell may cause crashes
+#: eval.c:110
+msgid "E719: Cannot use [:] with a Dictionary"
+msgstr "E719: No puede usar [:] con un diccionario"
+
+#: eval.c:111
+#, c-format
+msgid "E734: Wrong variable type for %s="
+msgstr "E734: Tipo de variable incorrecta para %s="
+
+#: eval.c:112
+#, c-format
+msgid "E130: Unknown function: %s"
+msgstr "E130: Función desconocida: %s"
+
+#: eval.c:113
+#, c-format
+msgid "E461: Illegal variable name: %s"
+msgstr "E461: Nombre ilegal para una variable: %s"
+
+#: eval.c:1898
+msgid "E687: Less targets than List items"
+msgstr "E687: Menos blancos que elementos en la lista"
+
+#: eval.c:1903
+msgid "E688: More targets than List items"
+msgstr "E688: Más blancos que elementos en la lista"
+
+#: eval.c:1989
+msgid "Double ; in list of variables"
+msgstr "Duplicado ; en la lista de variables"
+
+#: eval.c:2208
+#, c-format
+msgid "E738: Can't list variables for %s"
+msgstr "E738: No se pudo enumerar las variables de %s"
+
+#: eval.c:2554
+msgid "E689: Can only index a List or Dictionary"
+msgstr "E689: Solo puedo indexar una lista o un diccionario"
+
+#: eval.c:2560
+msgid "E708: [:] must come last"
+msgstr "E708: [:] debe ir al final"
+
+#: eval.c:2612
+msgid "E709: [:] requires a List value"
+msgstr "E709: [:] requiere un valor de la lista"
+
+#: eval.c:2848
+msgid "E710: List value has more items than target"
+msgstr "E710: La lista de valores tiene más elementos que blancos"
+
+#: eval.c:2852
+msgid "E711: List value has not enough items"
+msgstr "E711: La lista de valores no tiene suficientes elementos"
+
+#: eval.c:3087
+msgid "E690: Missing \"in\" after :for"
+msgstr "E690: Falta \"in\" después de :for"
+
+#: eval.c:3320
+#, c-format
+msgid "E107: Missing parentheses: %s"
+msgstr "E107: Faltan paréntesis: %s"
+
+#: eval.c:3559
+#, c-format
+msgid "E108: No such variable: \"%s\""
+msgstr "E108: No existe la variable: \"%s\""
+
+#: eval.c:3646
+msgid "E743: variable nested too deep for (un)lock"
+msgstr "E743: La variable está anidada muy profundamente para (des)bloquear"
+
+#: eval.c:3994
+msgid "E109: Missing ':' after '?'"
+msgstr "E109: Falta un \":\" después de \"?\""
+
+#: eval.c:4296
+msgid "E691: Can only compare List with List"
+msgstr "E691: Solo se puede comparar una lista con otra lista"
+
+#: eval.c:4298
+msgid "E692: Invalid operation for Lists"
+msgstr "E692: Operación inválida para listas"
+
+#: eval.c:4325
+msgid "E735: Can only compare Dictionary with Dictionary"
+msgstr "E735: Solo se puede comparar un diccionario con otro diccionario"
+
+#: eval.c:4327
+msgid "E736: Invalid operation for Dictionary"
+msgstr "E736: Operación inválida para diccionario"
+
+#: eval.c:4347
+msgid "E693: Can only compare Funcref with Funcref"
+msgstr "E693: Solo se puede comparar un \"Funref\" con otro \"Funcref\""
+
+#: eval.c:4349
+msgid "E694: Invalid operation for Funcrefs"
+msgstr "E694: Operación inválida para \"Funcrefs\""
+
+# if Vim opened a window: Executing a shell may cause crashes
+#: eval.c:4769
+msgid "E804: Cannot use '%' with Float"
+msgstr "E804: No se puede usar '%' con \"Float\""
+
+#: eval.c:4989
+msgid "E110: Missing ')'"
+msgstr "E110: Falta un \")\""
+
+#: eval.c:5141
+msgid "E695: Cannot index a Funcref"
+msgstr "E695: No se puede crear un índice de un \"Funcref\""
+
+#: eval.c:5398
+#, c-format
+msgid "E112: Option name missing: %s"
+msgstr "E112: Falta el nombre de la opción: %s"
+
+#: eval.c:5416
+#, c-format
+msgid "E113: Unknown option: %s"
+msgstr "E113: Opción desconocida: %s"
+
+#: eval.c:5482
+#, c-format
+msgid "E114: Missing quote: %s"
+msgstr "E114: Faltan las comillas: %s"
+
+#: eval.c:5618
+#, c-format
+msgid "E115: Missing quote: %s"
+msgstr "E115: Faltan las comillas: %s"
+
+#: eval.c:5697
+#, c-format
+msgid "E696: Missing comma in List: %s"
+msgstr "E696: Falta una coma en la lista: %s"
+
+#: eval.c:5705
+#, c-format
+msgid "E697: Missing end of List ']': %s"
+msgstr "E697: Falta una marca de final de lista ']': %s"
+
+#: eval.c:7195
+#, c-format
+msgid "E720: Missing colon in Dictionary: %s"
+msgstr "E720: Falta una marca de dos puntos en el diccionario: %s"
+
+#: eval.c:7224
+#, c-format
+msgid "E721: Duplicate key in Dictionary: \"%s\""
+msgstr "E721: Llave duplicada en el diccionario: %s"
+
+#: eval.c:7244
+#, c-format
+msgid "E722: Missing comma in Dictionary: %s"
+msgstr "E722: Falta una coma en el diccionario: %s"
+
+#: eval.c:7252
+#, c-format
+msgid "E723: Missing end of Dictionary '}': %s"
+msgstr "E723: Falta una marca de cierre '}' en el diccionario: %s"
+
+#: eval.c:7290
+msgid "E724: variable nested too deep for displaying"
+msgstr "E724: La variable está anidada demasiado profundamente para mostrarla"
+
+#: eval.c:7974
+#, c-format
+msgid "E740: Too many arguments for function %s"
+msgstr "E740: Demasiados argumentos para la función: %s"
+
+#: eval.c:7976
+#, c-format
+msgid "E116: Invalid arguments for function %s"
+msgstr "E116: Argumentos inválidos para la función: %s"
+
+#: eval.c:8181
+#, c-format
+msgid "E117: Unknown function: %s"
+msgstr "E117: Función desconocida: %s"
+
+#: eval.c:8187
+#, c-format
+msgid "E119: Not enough arguments for function: %s"
+msgstr "E119: No hay suficientes argumentos para la función: %s"
+
+#: eval.c:8191
+#, c-format
+msgid "E120: Using <SID> not in a script context: %s"
+msgstr "E120: Usando <SID> en un contexto que no es de \"script\": %s"
+
+#: eval.c:8195
+#, c-format
+msgid "E725: Calling dict function without Dictionary: %s"
+msgstr "E725: Llamando una función \"dict\" sin un diccionario: %s"
+
+#: eval.c:8423
+msgid "E808: Number or Float required"
+msgstr "E808: Se requiere \"Number\" o \"Float\""
+
+#: eval.c:8808
+msgid "E699: Too many arguments"
+msgstr "E699: Demasiados argumentos"
+
+#: eval.c:8977
+msgid "E785: complete() can only be used in Insert mode"
+msgstr "E785: complete() solo se puede usar en modo \"Insert\""
+
+#.
+#. * 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.
+#.
+#: eval.c:9077 gui.c:4871 gui_gtk.c:2144 os_mswin.c:598
+msgid "&Ok"
+msgstr "&Ok"
+
+#: eval.c:9727
+#, c-format
+msgid "E737: Key already exists: %s"
+msgstr "E737: Ya existe una llave: %s"
+
+#: eval.c:10301
+#, c-format
+msgid "+-%s%3ld lines: "
+msgstr "+-%s%3ld líneas: "
+
+#: eval.c:10389
+#, c-format
+msgid "E700: Unknown function: %s"
+msgstr "E700: Función desconocida: %s"
+
+#: eval.c:12379
+msgid ""
+"&OK\n"
+"&Cancel"
+msgstr ""
+"&Aceptar\n"
+"&Cancelar"
+
+#: eval.c:12461
+msgid "called inputrestore() more often than inputsave()"
+msgstr "Se invocó \"inputrestore()\" más veces que \"inputsave()\""
+
+#: eval.c:12595
+msgid "E786: Range not allowed"
+msgstr "E786: El rango no está permitido"
+
+#: eval.c:12795
+msgid "E701: Invalid type for len()"
+msgstr "E701: No es un tipo válido para len()"
+
+#: eval.c:13788
+msgid "E726: Stride is zero"
+msgstr "E726: El largo es cero"
+
+#: eval.c:13790
+msgid "E727: Start past end"
+msgstr "E727: El inicio está más allá del final"
+
+#: eval.c:13843 eval.c:17576
+msgid "<empty>"
+msgstr "<vacio>"
+
+#: eval.c:14077
+msgid "E240: No connection to Vim server"
+msgstr "E240: No hay conexión al servidor Vim"
+
+#: eval.c:14125
+#, c-format
+msgid "E241: Unable to send to %s"
+msgstr "E241: Incapaz de enviar a %s"
+
+#: eval.c:14272
+msgid "E277: Unable to read a server reply"
+msgstr "E277: Incapaz de leer una respuesta del servidor"
+
+#: eval.c:14522
+msgid "E655: Too many symbolic links (cycle?)"
+msgstr "E655: Demasiados enlaces simbólicos (¿referencia circular?)"
+
+#: eval.c:15243
+msgid "E258: Unable to send to client"
+msgstr "E258: Incapaz de enviar al cliente"
+
+#: eval.c:15950
+msgid "E702: Sort compare function failed"
+msgstr "E702: Fallo al ordenar funciones comparadas"
+
+#: eval.c:16275
+msgid "(Invalid)"
+msgstr "(No es válido)"
+
+#: eval.c:16760
+msgid "E677: Error writing temp file"
+msgstr "E677: Error al escribir el archivo temporal"
+
+#: eval.c:18602
+msgid "E805: Using a Float as a Number"
+msgstr "E805: Usando \"Float\" como un \"Number\""
+
+#: eval.c:18606
+msgid "E703: Using a Funcref as a Number"
+msgstr "E703: Usando una función de referencia como \"Number\""
+
+#: eval.c:18614
+msgid "E745: Using a List as a Number"
+msgstr "E745: Usando una \"Lista\" como \"Number\""
+
+#: eval.c:18617
+msgid "E728: Using a Dictionary as a Number"
+msgstr "E728: Usando un Diccionario como \"Number\""
+
+#: eval.c:18720
+msgid "E729: using Funcref as a String"
+msgstr "E729: Usando una Función de referencia como \"String\""
+
+#: eval.c:18723
+msgid "E730: using List as a String"
+msgstr "E730: Usando una \"List\" como \"String\""
+
+#: eval.c:18726
+msgid "E731: using Dictionary as a String"
+msgstr "E731: Usando un Diccionario como \"String\""
+
+#: eval.c:18730
+msgid "E806: using Float as a String"
+msgstr "E806: Usando \"Float\" como \"String\""
+
+#: eval.c:19090
+#, c-format
+msgid "E704: Funcref variable name must start with a capital: %s"
+msgstr ""
+"E704: El nombre de una variable de Función de referencia debe empezar con "
+"mayúscula: %s"
+
+#: eval.c:19095
+#, c-format
+msgid "E705: Variable name conflicts with existing function: %s"
+msgstr "E705: Nombre de variable en conflicto con una función existente: %s"
+
+#: eval.c:19128
+#, c-format
+msgid "E706: Variable type mismatch for: %s"
+msgstr "E706: Tipo de variable no concuerda con : %s"
+
+#: eval.c:19237
+#, c-format
+msgid "E795: Cannot delete variable %s"
+msgstr "E795: No se pudo borrar la variable %s"
+
+#: eval.c:19254
+#, c-format
+msgid "E741: Value is locked: %s"
+msgstr "E741: El valor está bloqueado: %s"
+
+#: eval.c:19255 eval.c:19261 message.c:2132 os_mswin.c:2258
+msgid "Unknown"
+msgstr "Desconocido"
+
+#: eval.c:19260
+#, c-format
+msgid "E742: Cannot change value of %s"
+msgstr "E742: No se pudo cambiar el valor de %s"
+
+#: eval.c:19345
+msgid "E698: variable nested too deep for making a copy"
+msgstr "E698: La variable está anidada muy profundamente para hacer una copia"
+
+#: eval.c:19818
+#, c-format
+msgid "E123: Undefined function: %s"
+msgstr "E123: Función indefinida: %s"
+
+#: eval.c:19831
+#, c-format
+msgid "E124: Missing '(': %s"
+msgstr "E124: Falta un \"(\": %s"
+
+#: eval.c:19887
+#, c-format
+msgid "E125: Illegal argument: %s"
+msgstr "E125: Argumento ilegal: %s"
+
+#: eval.c:19997
+msgid "E126: Missing :endfunction"
+msgstr "E126: Falta un \":endfunction\""
+
+#: eval.c:20134
+#, c-format
+msgid "E707: Function name conflicts with variable: %s"
+msgstr "E707: El nombre de la función entran en conflicto con la variable: %s"
+
+#: eval.c:20149
+#, c-format
+msgid "E127: Cannot redefine function %s: It is in use"
+msgstr "E127: No se puede redefinir la función %s: Está en uso"
+
+#: eval.c:20214
+#, c-format
+msgid "E746: Function name does not match script file name: %s"
+msgstr "E746: Nombre de función no concuerda con el nombre de archivo: %s"
+
+#: eval.c:20332
+msgid "E129: Function name required"
+msgstr "E129: Se requiere el nombre de la función"
+
+#: eval.c:20452
+#, c-format
+msgid "E128: Function name must start with a capital or contain a colon: %s"
+msgstr ""
+"E128: El nombre de una función debe empezar con mayúscula o contener el "
+"signo de dos puntos: %s"
+
+#: eval.c:20984
+#, c-format
+msgid "E131: Cannot delete function %s: It is in use"
+msgstr "E131: No se pudo eliminar la función %s: Está en uso"
+
+#: eval.c:21104
+msgid "E132: Function call depth is higher than 'maxfuncdepth'"
+msgstr ""
+"E132: La recursión de llamada de la función es mayor que \"maxfuncdepth\""
+
+# always scroll up, don't overwrite
+#: eval.c:21243
+#, c-format
+msgid "calling %s"
+msgstr "Invocando %s"
+
+#: eval.c:21335
+#, c-format
+msgid "%s aborted"
+msgstr "Abortada la ejecución de %s"
+
+#: eval.c:21337
+#, c-format
+msgid "%s returning #%ld"
+msgstr "%s devuelve #%ld"
+
+#: eval.c:21353
+#, c-format
+msgid "%s returning %s"
+msgstr "%s devuelve %s"
+
+# always scroll up, don't overwrite
+#: eval.c:21377 ex_cmds2.c:3145
+#, c-format
+msgid "continuing in %s"
+msgstr "continuando en %s"
+
+#: eval.c:21496
+msgid "E133: :return not inside a function"
+msgstr "E133: \":return\" no está dentro de una función"
+
+#: eval.c:21909
+#, c-format
+msgid ""
+"\n"
+"# global variables:\n"
+msgstr ""
+"\n"
+"# variables globales:\n"
+
+#: eval.c:22026
+msgid ""
+"\n"
+"\tLast set from "
+msgstr ""
+"\n"
+"\tSe definió por última vez en "
+
+#: eval.c:22046
+msgid "No old files"
+msgstr "No hay archivos antiguos"
+
+#: ex_cmds.c:101
+#, c-format
+msgid "<%s>%s%s %d, Hex %02x, Octal %03o"
+msgstr "<%s>%s%s %d, Hex %02x, Octal %03o"
+
+#: ex_cmds.c:128
+#, c-format
+msgid "> %d, Hex %04x, Octal %o"
+msgstr "> %d, Hex %04x, Octal %o"
+
+#: ex_cmds.c:129
+#, c-format
+msgid "> %d, Hex %08x, Octal %o"
+msgstr "> %d, Hex %08x, Octal %o"
+
+#: ex_cmds.c:739
+msgid "E134: Move lines into themselves"
+msgstr "E134: Moviendo líneas sobre sí mismas"
+
+#: ex_cmds.c:808
+msgid "1 line moved"
+msgstr "1 línea movida"
+
+#: ex_cmds.c:810
+#, c-format
+msgid "%ld lines moved"
+msgstr "%ld líneas movidas"
+
+#: ex_cmds.c:1305
+#, c-format
+msgid "%ld lines filtered"
+msgstr "%ld líneas filtradas"
+
+#: ex_cmds.c:1329
+msgid "E135: *Filter* Autocommands must not change current buffer"
+msgstr "E135: *Filtro* Las auto-órdenes no deben cambiar el búfer en uso"
+
+#: ex_cmds.c:1414
+msgid "[No write since last change]\n"
+msgstr "[No se ha escrito nada al disco desde el último cambio]\n"
+
+#: ex_cmds.c:1672
+#, c-format
+msgid "%sviminfo: %s in line: "
+msgstr "%sviminfo: %s en la línea: "
+
+#: ex_cmds.c:1680
+msgid "E136: viminfo: Too many errors, skipping rest of file"
+msgstr "E136: viminfo: Demasiados errores, omitiendo el resto del archivo"
+
+#: ex_cmds.c:1709
+#, c-format
+msgid "Reading viminfo file \"%s\"%s%s%s"
+msgstr "Leyendo el archivo \"viminfo\" \"%s\"%s%s%s"
+
+#: ex_cmds.c:1711
+msgid " info"
+msgstr " info"
+
+#: ex_cmds.c:1712
+msgid " marks"
+msgstr " marcas"
+
+#: ex_cmds.c:1713
+msgid " oldfiles"
+msgstr " archivos antiguos"
+
+#: ex_cmds.c:1714
+msgid " FAILED"
+msgstr " FALLÓ"
+
+#. avoid a wait_return for this message, it's annoying
+#: ex_cmds.c:1810
+#, c-format
+msgid "E137: Viminfo file is not writable: %s"
+msgstr "E137: No hay permisos de escritura para el archivo \"viminfo\": %s"
+
+#: ex_cmds.c:1963
+#, c-format
+msgid "E138: Can't write viminfo file %s!"
+msgstr "E138: ¡No se pudo escribir el archivo \"viminfo\" %s!"
+
+#: ex_cmds.c:1973
+#, c-format
+msgid "Writing viminfo file \"%s\""
+msgstr "Escribiendo archivo \"viminfo\" \"%s\""
+
+# Write the info:
+#. Write the info:
+#: ex_cmds.c:2081
+#, c-format
+msgid "# This viminfo file was generated by Vim %s.\n"
+msgstr "# Vim %s generó este archivo \"viminfo\".\n"
+
+#: ex_cmds.c:2083
+#, c-format
+msgid ""
+"# You may edit it if you're careful!\n"
+"\n"
+msgstr ""
+"# Puede editarlo, ¡sólo si tiene cuidado!\n"
+"\n"
+
+#: ex_cmds.c:2085
+#, c-format
+msgid "# Value of 'encoding' when this file was written\n"
+msgstr "# Valor de 'encoding' cuando se escribió este archivo\n"
+
+#: ex_cmds.c:2185
+msgid "Illegal starting char"
+msgstr "Carácter de comienzo ilegal"
+
+#: ex_cmds.c:2551 ex_cmds2.c:1407
+msgid "Save As"
+msgstr "Guardar como"
+
+#: ex_cmds.c:2628
+msgid "Write partial file?"
+msgstr "¿Escribir un archivo parcial?"
+
+#: ex_cmds.c:2635
+msgid "E140: Use ! to write partial buffer"
+msgstr "E140: Use \"!\" para escribir un búfer parcial"
+
+#: ex_cmds.c:2777
+#, c-format
+msgid "Overwrite existing file \"%s\"?"
+msgstr "¿Escribir sobre el archivo existente \"%s\"?"
+
+#: ex_cmds.c:2820
+#, c-format
+msgid "Swap file \"%s\" exists, overwrite anyway?"
+msgstr "Ya existe un archivo de intercambio \"%s\", desea sobreescribirlo? "
+
+#: ex_cmds.c:2833
+#, c-format
+msgid "E768: Swap file exists: %s (:silent! overrides)"
+msgstr ""
+"E768: El archivo de intercambio ya existe: %s (use ! para sobreescribir)"
+
+#: ex_cmds.c:2901
+#, c-format
+msgid "E141: No file name for buffer %ld"
+msgstr "E141: No existe un nombre de archivo para el búfer %ld"
+
+#: ex_cmds.c:2940
+msgid "E142: File not written: Writing is disabled by 'write' option"
+msgstr ""
+"E142: No se ha escrito el archivo: escritura desactivada por \n"
+"la opción 'write'"
+
+#: ex_cmds.c:2970
+#, c-format
+msgid ""
+"'readonly' option is set for \"%s\".\n"
+"Do you wish to write anyway?"
+msgstr ""
+"Se ha activado la opción de solo lectura ('readonly') para %s.\n"
+"¿Desea escribir de todas formas?"
+
+#: ex_cmds.c:2973
+#, 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 ""
+"Los permisos del archivo \"%s\" son de\n"
+"sólo lectura. Cabe la posibilidad de escribir\n"
+"en él. ¿Desea intentarlo?"
+
+#: ex_cmds.c:2990
+#, c-format
+msgid "E505: \"%s\" is read-only (add ! to override)"
+msgstr "E505: \"%s\" es de solo lectura (añada ! para sobreescribir)"
+
+#: ex_cmds.c:3177
+msgid "Edit File"
+msgstr "Editar archivo"
+
+#: ex_cmds.c:3847
+#, c-format
+msgid "E143: Autocommands unexpectedly deleted new buffer %s"
+msgstr "E143: Las auto-órdenes han eliminado al nuevo búfer %s"
+
+#: ex_cmds.c:4063
+msgid "E144: non-numeric argument to :z"
+msgstr "E144: Argumento no numérico para \":z\""
+
+#: ex_cmds.c:4162
+msgid "E145: Shell commands not allowed in rvim"
+msgstr "E145: No se permiten órdenes de consola en rvim"
+
+#: ex_cmds.c:4261
+msgid "E146: Regular expressions can't be delimited by letters"
+msgstr "E146: Las expresiones regulares no se pueden delimitar con letras"
+
+#: ex_cmds.c:4721
+#, c-format
+msgid "replace with %s (y/n/a/q/l/^E/^Y)?"
+msgstr "¿Reemplazar con %s (y/n/a/q/l/^E/^Y)?"
+
+#: ex_cmds.c:5166
+msgid "(Interrupted) "
+msgstr "(Interrumpido)"
+
+#: ex_cmds.c:5171
+msgid "1 match"
+msgstr "Una (1) coincidencia"
+
+#: ex_cmds.c:5171
+msgid "1 substitution"
+msgstr "Una (1) sustitución"
+
+#: ex_cmds.c:5174
+#, c-format
+msgid "%ld matches"
+msgstr "%ld coincidencias"
+
+#: ex_cmds.c:5174
+#, c-format
+msgid "%ld substitutions"
+msgstr "%ld sustituciones"
+
+#: ex_cmds.c:5179
+msgid " on 1 line"
+msgstr " en una (1) línea"
+
+#: ex_cmds.c:5182
+#, c-format
+msgid " on %ld lines"
+msgstr " en %ld líneas"
+
+#: ex_cmds.c:5229
+msgid "E147: Cannot do :global recursive"
+msgstr "E147: \":global\" no puede ser recursivo"
+
+#: ex_cmds.c:5264
+msgid "E148: Regular expression missing from global"
+msgstr "E148: Falta una expresión regular en \":global\""
+
+#: ex_cmds.c:5313
+#, c-format
+msgid "Pattern found in every line: %s"
+msgstr "Patrón encontrado en cada línea: %s"
+
+#: ex_cmds.c:5398
+#, c-format
+msgid ""
+"\n"
+"# Last Substitute String:\n"
+"$"
+msgstr ""
+"\n"
+"# Última cadena de sustitución:\n"
+"$"
+
+#: ex_cmds.c:5511
+msgid "E478: Don't panic!"
+msgstr "E478: ¡No entre en pánico!"
+
+#: ex_cmds.c:5557
+#, c-format
+msgid "E661: Sorry, no '%s' help for %s"
+msgstr "E661: Lo siento, no hay ayuda '%s' para \"%s\""
+
+#: ex_cmds.c:5560
+#, c-format
+msgid "E149: Sorry, no help for %s"
+msgstr "E149: Lo siento, no hay ayuda para \"%s\""
+
+#: ex_cmds.c:5602
+#, c-format
+msgid "Sorry, help file \"%s\" not found"
+msgstr "Lo siento, no encuentro el archivo de ayuda \"%s\""
+
+#: ex_cmds.c:6180
+#, c-format
+msgid "E150: Not a directory: %s"
+msgstr "E150: No es un directorio: %s"
+
+#: ex_cmds.c:6323
+#, c-format
+msgid "E152: Cannot open %s for writing"
+msgstr "E152: No se pudo abrir %s para escritura"
+
+#: ex_cmds.c:6360
+#, c-format
+msgid "E153: Unable to open %s for reading"
+msgstr "E153: Incapaz de abrir %s para lectura"
+
+#: ex_cmds.c:6396
+#, c-format
+msgid "E670: Mix of help file encodings within a language: %s"
+msgstr ""
+"E670: Mezcla de codificaciones en archivos de ayuda dentro de un lenguaje: %s"
+
+#: ex_cmds.c:6474
+#, c-format
+msgid "E154: Duplicate tag \"%s\" in file %s/%s"
+msgstr "E154: Etiqueta \"%s\" duplicada en el archivo %s/%s"
+
+#: ex_cmds.c:6610
+#, c-format
+msgid "E160: Unknown sign command: %s"
+msgstr "E160: Orden de signo desconocida: %s"
+
+#: ex_cmds.c:6627
+msgid "E156: Missing sign name"
+msgstr "E156: Falta el nombre del signo"
+
+#: ex_cmds.c:6673
+msgid "E612: Too many signs defined"
+msgstr "E612: Demasiados signos definidos"
+
+#: ex_cmds.c:6741
+#, c-format
+msgid "E239: Invalid sign text: %s"
+msgstr "E239: El texto de signo no es válido: %s"
+
+#: ex_cmds.c:6772 ex_cmds.c:6947
+#, c-format
+msgid "E155: Unknown sign: %s"
+msgstr "E155: Signo desconocido: %s"
+
+#: ex_cmds.c:6805
+msgid "E159: Missing sign number"
+msgstr "E159: Falta el número del signo"
+
+#: ex_cmds.c:6887
+#, c-format
+msgid "E158: Invalid buffer name: %s"
+msgstr "E158: El nombre del búfer no es válido: %s"
+
+#: ex_cmds.c:6926
+#, c-format
+msgid "E157: Invalid sign ID: %ld"
+msgstr "E157: La identificación del signo no es válida: %ld"
+
+#: ex_cmds.c:6996
+msgid " (NOT FOUND)"
+msgstr " (NO ENCONTRADO)"
+
+#: ex_cmds.c:6998
+msgid " (not supported)"
+msgstr " (no hay apoyo para la función pedida)"
+
+#: ex_cmds.c:7122
+msgid "[Deleted]"
+msgstr "[Suprimido]"
+
+#: ex_cmds2.c:138
+msgid "Entering Debug mode. Type \"cont\" to continue."
+msgstr "Iniciando modo de depuración. Escriba \"cont\" para continuar."
+
+#: ex_cmds2.c:142 ex_docmd.c:1081
+#, c-format
+msgid "line %ld: %s"
+msgstr "línea %ld: %s"
+
+#: ex_cmds2.c:144
+#, c-format
+msgid "cmd: %s"
+msgstr "cmd: %s"
+
+#: ex_cmds2.c:344
+#, c-format
+msgid "Breakpoint in \"%s%s\" line %ld"
+msgstr "\"Breakpoint\" en \"%s%s\" línea %ld"
+
+#: ex_cmds2.c:656
+#, c-format
+msgid "E161: Breakpoint not found: %s"
+msgstr "E161: No se ha encontrado el \"breakpoint\": %s"
+
+#: ex_cmds2.c:692
+msgid "No breakpoints defined"
+msgstr "No se han definido \"breakpoints\""
+
+#: ex_cmds2.c:697
+#, c-format
+msgid "%3d %s %s line %ld"
+msgstr "%3d %s %s línea %ld"
+
+#: ex_cmds2.c:1095
+msgid "E750: First use :profile start <fname>"
+msgstr "E750: Primero use \":profile start <nombre_de_archivo>\""
+
+#: ex_cmds2.c:1432
+#, c-format
+msgid "Save changes to \"%s\"?"
+msgstr "¿Guardar los cambios en \"%s\"?"
+
+#: ex_cmds2.c:1434 ex_docmd.c:10814
+msgid "Untitled"
+msgstr "Sin título"
+
+#: ex_cmds2.c:1563
+#, c-format
+msgid "E162: No write since last change for buffer \"%s\""
+msgstr "E162: No se ha grabado nada desde el último cambio en el búfer \"%s\""
+
+#: ex_cmds2.c:1634
+msgid "Warning: Entered other buffer unexpectedly (check autocommands)"
+msgstr ""
+"Advertencia: se ha entrado en otro búfer de forma inesperada (verifique las "
+"auto-órdenes)"
+
+#: ex_cmds2.c:2078
+msgid "E163: There is only one file to edit"
+msgstr "E163: Hay sólo un archivo para editar"
+
+#: ex_cmds2.c:2080
+msgid "E164: Cannot go before first file"
+msgstr "E164: No se pudo regresar antes del primer archivo"
+
+#: ex_cmds2.c:2082
+msgid "E165: Cannot go beyond last file"
+msgstr "E165: No se pudo ir más allá del último archivo"
+
+#: ex_cmds2.c:2511
+#, c-format
+msgid "E666: compiler not supported: %s"
+msgstr "E666: El compilador no es compatible en esta versión: %s"
+
+#: ex_cmds2.c:2612
+#, c-format
+msgid "Searching for \"%s\" in \"%s\""
+msgstr "Buscando \"%s\" en \"%s\""
+
+#: ex_cmds2.c:2639
+#, c-format
+msgid "Searching for \"%s\""
+msgstr "Buscando \"%s\""
+
+#: ex_cmds2.c:2665
+#, c-format
+msgid "not found in 'runtimepath': \"%s\""
+msgstr "No se ha encontrado en 'runtimepath': %s"
+
+#: ex_cmds2.c:2700
+msgid "Source Vim script"
+msgstr "Ejecute archivo de órdenes de Vim"
+
+#: ex_cmds2.c:2875
+#, c-format
+msgid "Cannot source a directory: \"%s\""
+msgstr "No se pudo ejecutar un directorio: %s"
+
+#: ex_cmds2.c:2932
+#, c-format
+msgid "could not source \"%s\""
+msgstr "No pude ejecutar %s"
+
+#: ex_cmds2.c:2934
+#, c-format
+msgid "line %ld: could not source \"%s\""
+msgstr "línea %ld: no se pudo ejecutar %s"
+
+#: ex_cmds2.c:2950
+#, c-format
+msgid "sourcing \"%s\""
+msgstr "ejecutando %s"
+
+#: ex_cmds2.c:2952
+#, c-format
+msgid "line %ld: sourcing \"%s\""
+msgstr "línea %ld: ejecutando %s"
+
+#: ex_cmds2.c:3143
+#, c-format
+msgid "finished sourcing %s"
+msgstr "La ejecución de %s ha terminado"
+
+#: ex_cmds2.c:3224
+msgid "modeline"
+msgstr "modeline"
+
+#: ex_cmds2.c:3226
+msgid "--cmd argument"
+msgstr "--cmd [argumentos]"
+
+#: ex_cmds2.c:3228
+msgid "-c argument"
+msgstr "-c [argumentos]"
+
+#: ex_cmds2.c:3230
+msgid "environment variable"
+msgstr "variable de entorno"
+
+#: ex_cmds2.c:3232
+msgid "error handler"
+msgstr "administrador de errores"
+
+#: ex_cmds2.c:3524
+msgid "W15: Warning: Wrong line separator, ^M may be missing"
+msgstr "W15: Advertencia: separador de línea incorrecto, puede que falte ^M"
+
+#: ex_cmds2.c:3657
+msgid "E167: :scriptencoding used outside of a sourced file"
+msgstr ""
+"E167: Ha usado \":scriptencoding\" fuera de un archivo de instrucciones "
+"ejecutables"
+
+#: ex_cmds2.c:3690
+msgid "E168: :finish used outside of a sourced file"
+msgstr ""
+"E168: Ha usado \":finish\" fuera de un archivo de instrucciones ejecutables"
+
+#: ex_cmds2.c:4012
+#, c-format
+msgid "Current %slanguage: \"%s\""
+msgstr "Idioma actual %s: \"%s\""
+
+#: ex_cmds2.c:4029
+#, c-format
+msgid "E197: Cannot set language to \"%s\""
+msgstr "E197: No se pudo establecer la opción del idioma a \"%s\""
+
+#: ex_docmd.c:626
+msgid "Entering Ex mode. Type \"visual\" to go to Normal mode."
+msgstr "Entrando al modo Ex. Escriba \"visual\" para ir al modo Normal"
+
+# must be at EOF
+#: ex_docmd.c:681
+msgid "E501: At end-of-file"
+msgstr "E501: Estoy al final del archivo"
+
+#: ex_docmd.c:780
+msgid "E169: Command too recursive"
+msgstr "E169: Orden demasiado recursiva"
+
+#: ex_docmd.c:1359
+#, c-format
+msgid "E605: Exception not caught: %s"
+msgstr "E605: La excepción %s no se atrapó"
+
+#: ex_docmd.c:1447
+msgid "End of sourced file"
+msgstr "Fin del archivo de instrucciones ejecutables"
+
+#: ex_docmd.c:1448
+msgid "End of function"
+msgstr "Fin de la función"
+
+#: ex_docmd.c:2096
+msgid "E464: Ambiguous use of user-defined command"
+msgstr "E464: Uso ambiguo de una orden definida por el usuario"
+
+#: ex_docmd.c:2110
+msgid "E492: Not an editor command"
+msgstr "E492: No es una orden del editor"
+
+#: ex_docmd.c:2242
+msgid "E493: Backwards range given"
+msgstr "E493: Me ha dado un rango invertido"
+
+#: ex_docmd.c:2246
+msgid "Backwards range given, OK to swap"
+msgstr "Se devolvió un rango invertido, ¿puedo intercambiarlo?"
+
+#: ex_docmd.c:2309
+msgid "E494: Use w or w>>"
+msgstr "E494: Use \"w\" o \"w>>\""
+
+#: ex_docmd.c:4076
+msgid "E319: Sorry, the command is not available in this version"
+msgstr "E319: Lo siento, esa orden no está disponible en esta versión"
+
+#: ex_docmd.c:4425
+msgid "E172: Only one file name allowed"
+msgstr "E172: Solo se permite un nombre de archivo"
+
+#: ex_docmd.c:5036
+msgid "1 more file to edit. Quit anyway?"
+msgstr "Un (1) archivo más para editar. ¿Cerrar de todas formas?"
+
+#: ex_docmd.c:5039
+#, c-format
+msgid "%d more files to edit. Quit anyway?"
+msgstr "Hay %d archivos más en edición. ¿Cerrar de todas formas?"
+
+#: ex_docmd.c:5046
+msgid "E173: 1 more file to edit"
+msgstr "E173: Un (1) archivo más para editar"
+
+#: ex_docmd.c:5048
+#, c-format
+msgid "E173: %ld more files to edit"
+msgstr "E173: Hay %ld archivos en edición"
+
+#: ex_docmd.c:5142
+msgid "E174: Command already exists: add ! to replace it"
+msgstr "E174: Ya existe esa orden. Añada \"!\" para reemplazarla"
+
+#: ex_docmd.c:5264
+msgid ""
+"\n"
+" Name Args Range Complete Definition"
+msgstr ""
+"\n"
+" Nombre Args Rango Completar Definición"
+
+#: ex_docmd.c:5357
+msgid "No user-defined commands found"
+msgstr "No se han encontrado órdenes definidos por el usuario"
+
+#: ex_docmd.c:5389
+msgid "E175: No attribute specified"
+msgstr "E175: No se ha especificado el atributo"
+
+#: ex_docmd.c:5441
+msgid "E176: Invalid number of arguments"
+msgstr "E176: El número de argumentos no es válido"
+
+#: ex_docmd.c:5456
+msgid "E177: Count cannot be specified twice"
+msgstr "E177: El recuento no se puede especificar dos veces"
+
+#: ex_docmd.c:5466
+msgid "E178: Invalid default value for count"
+msgstr "E178: El valor predeterminado para el recuento no es válido"
+
+#: ex_docmd.c:5494
+msgid "E179: argument required for -complete"
+msgstr "E179: se necesita un argumento para \"-complete\""
+
+#: ex_docmd.c:5506
+#, c-format
+msgid "E181: Invalid attribute: %s"
+msgstr "E181: El atributo no es válido: %s"
+
+#: ex_docmd.c:5552
+msgid "E182: Invalid command name"
+msgstr "E182: El nombre de la orden no es válido"
+
+#: ex_docmd.c:5567
+msgid "E183: User defined commands must start with an uppercase letter"
+msgstr ""
+"E183: Las órdenes definidas por el usuario deben comenzar con mayúscula"
+
+#: ex_docmd.c:5635
+#, c-format
+msgid "E184: No such user-defined command: %s"
+msgstr "E184: No existe esa orden definida por el usuario: %s"
+
+#: ex_docmd.c:6187
+#, c-format
+msgid "E180: Invalid complete value: %s"
+msgstr "E180: El valor para completar no es válido: %s"
+
+#: ex_docmd.c:6198
+msgid "E468: Completion argument only allowed for custom completion"
+msgstr ""
+"E468: El argumento de finalización solo se permite en finalizaciones "
+"definidas por el usuario"
+
+#: ex_docmd.c:6206
+msgid "E467: Custom completion requires a function argument"
+msgstr ""
+"E467: Las finalizaciones definidas por el usuario requieren de un argumento "
+"de función"
+
+#: ex_docmd.c:6222
+#, c-format
+msgid "E185: Cannot find color scheme %s"
+msgstr "E185: No se pudo encontrar el esquema de colores %s"
+
+#: ex_docmd.c:6230
+msgid "Greetings, Vim user!"
+msgstr "¡Saludos, usuario de Vim!"
+
+#: ex_docmd.c:6448
+msgid "E784: Cannot close last tab page"
+msgstr "E784: No se pudo cerrar la última ventana"
+
+#: ex_docmd.c:6490
+msgid "Already only one tab page"
+msgstr "Solo hay una ventana"
+
+#: ex_docmd.c:7177
+msgid "Edit File in new window"
+msgstr "Editar archivo en una ventana nueva"
+
+#: ex_docmd.c:7303
+#, c-format
+msgid "Tab page %d"
+msgstr "Página %d"
+
+#: ex_docmd.c:7695
+msgid "No swap file"
+msgstr "No hay archivo de intercambio"
+
+#: ex_docmd.c:7800
+msgid "Append File"
+msgstr "Añadir archivo"
+
+#: ex_docmd.c:7899
+msgid "E747: Cannot change directory, buffer is modified (add ! to override)"
+msgstr ""
+"E747: No se pudo cambiar de directorio, el búfer fue modificado (añada ! "
+"para forzar la orden)"
+
+#: ex_docmd.c:7908
+msgid "E186: No previous directory"
+msgstr "E186: No hay un directorio previo"
+
+#: ex_docmd.c:7989
+msgid "E187: Unknown"
+msgstr "E187: Desconocido"
+
+#: ex_docmd.c:8084
+msgid "E465: :winsize requires two number arguments"
+msgstr "E465: \":winsize\" requiere de dos argumentos numéricos"
+
+#: ex_docmd.c:8146
+#, c-format
+msgid "Window position: X %d, Y %d"
+msgstr "Posición de la ventana: X %d, Y %d"
+
+#: ex_docmd.c:8151
+msgid "E188: Obtaining window position not implemented for this platform"
+msgstr ""
+"E188: Obtener la posición de la ventana no está implementado en esta "
+"plataforma"
+
+#: ex_docmd.c:8161
+msgid "E466: :winpos requires two number arguments"
+msgstr "E466: \":winpos\" requiere de dos argumentos numéricos"
+
+#: ex_docmd.c:8499
+msgid "Save Redirection"
+msgstr "Guardar redirección"
+
+#: ex_docmd.c:8730
+msgid "Save View"
+msgstr "Guardar vista"
+
+#: ex_docmd.c:8731
+msgid "Save Session"
+msgstr "Guardar sesión"
+
+#: ex_docmd.c:8733
+msgid "Save Setup"
+msgstr "Guardar configuración"
+
+#: ex_docmd.c:8889
+#, c-format
+msgid "E739: Cannot create directory: %s"
+msgstr "E739: No se pudo crear directorio: %s"
+
+#: ex_docmd.c:8918
+#, c-format
+msgid "E189: \"%s\" exists (add ! to override)"
+msgstr "E189: \"%s\" ya existe (añada ! para sobreescribir.)"
+
+#: ex_docmd.c:8923
+#, c-format
+msgid "E190: Cannot open \"%s\" for writing"
+msgstr "E190: No se pudo abrir \"%s\" para escrbir"
+
+# set mark
+#. set mark
+#: ex_docmd.c:8947
+msgid "E191: Argument must be a letter or forward/backward quote"
+msgstr ""
+"E191: El argumento debe ser una letra o una comilla simple/comilla simple "
+"invertida"
+
+#: ex_docmd.c:8994
+msgid "E192: Recursive use of :normal too deep"
+msgstr "E192: Excesivo uso recursivo de \":normal\""
+
+#: ex_docmd.c:9593
+msgid "E809: #< is not available without the +eval feature"
+msgstr "E809: #< no está disponible sin la característica \"+eval\""
+
+#: ex_docmd.c:9602
+msgid "E194: No alternate file name to substitute for '#'"
+msgstr "E194: No hay un nombre de archivo alterno que sustituya a '#'"
+
+#: ex_docmd.c:9643
+msgid "E495: no autocommand file name to substitute for \"<afile>\""
+msgstr ""
+"E495: No se ha dado un nombre de archivo de auto-órdenes para sustituir a "
+"\"<afile>\""
+
+#: ex_docmd.c:9652
+msgid "E496: no autocommand buffer number to substitute for \"<abuf>\""
+msgstr "E496: No existe un búfer de auto-órdenes para sustituir por \"<abuf>\""
+
+#: ex_docmd.c:9663
+msgid "E497: no autocommand match name to substitute for \"<amatch>\""
+msgstr ""
+"E497: Ningún nombre de auto-orden concuerda para sustituir \"<amatch>\""
+
+#: ex_docmd.c:9673
+msgid "E498: no :source file name to substitute for \"<sfile>\""
+msgstr ""
+"E498: No hay un nombre de archivo \":source\" que sustituya a \"<sfile>\""
+
+#: ex_docmd.c:9715
+#, no-c-format
+msgid "E499: Empty file name for '%' or '#', only works with \":p:h\""
+msgstr ""
+"E499: Un nombre de archivo vacío para \"%\" o \"#\" solo funciona con \":p:h"
+"\""
+
+#: ex_docmd.c:9717
+msgid "E500: Evaluates to an empty string"
+msgstr "E500: La expresión evalúa a una cadena vacía"
+
+#: ex_docmd.c:10794
+msgid "E195: Cannot open viminfo file for reading"
+msgstr "E195: No se pudo abrir el archivo \"viminfo\" para lectura"
+
+#: ex_docmd.c:10964
+msgid "E196: No digraphs in this version"
+msgstr "E196: No hay dígrafos en esta versión"
+
+#: ex_eval.c:441
+msgid "E608: Cannot :throw exceptions with 'Vim' prefix"
+msgstr ""
+"E608: No se pudo lanzar (':throw') excepciones si tienen el prefijo 'Vim'"
+
+# always scroll up, don't overwrite
+#. always scroll up, don't overwrite
+#: ex_eval.c:534
+#, c-format
+msgid "Exception thrown: %s"
+msgstr "Excepción lanzada: %s"
+
+#: ex_eval.c:588
+#, c-format
+msgid "Exception finished: %s"
+msgstr "Excepción terminada: %s"
+
+#: ex_eval.c:589
+#, c-format
+msgid "Exception discarded: %s"
+msgstr "Excepción descartada: %s"
+
+#: ex_eval.c:635 ex_eval.c:687
+#, c-format
+msgid "%s, line %ld"
+msgstr "%s, en la línea %ld"
+
+# always scroll up, don't overwrite
+#. always scroll up, don't overwrite
+#: ex_eval.c:657
+#, c-format
+msgid "Exception caught: %s"
+msgstr "Excepción atrapada: %s"
+
+#: ex_eval.c:737
+#, c-format
+msgid "%s made pending"
+msgstr "%s ha pasado a la lista de pendientes"
+
+#: ex_eval.c:740
+#, c-format
+msgid "%s resumed"
+msgstr "%s continuado"
+
+#: ex_eval.c:744
+#, c-format
+msgid "%s discarded"
+msgstr "%s descartado"
+
+#: ex_eval.c:771
+msgid "Exception"
+msgstr "Excepción"
+
+#: ex_eval.c:777
+msgid "Error and interrupt"
+msgstr "Error e interrupción"
+
+#: ex_eval.c:779 gui.c:4870 gui_xmdlg.c:689 gui_xmdlg.c:808 os_mswin.c:597
+msgid "Error"
+msgstr "Error"
+
+# if (pending & CSTP_INTERRUPT)
+#. if (pending & CSTP_INTERRUPT)
+#: ex_eval.c:781
+msgid "Interrupt"
+msgstr "Interrupción"
+
+#: ex_eval.c:873
+msgid "E579: :if nesting too deep"
+msgstr "E579: ¡\":if\" anidado en exceso!"
+
+#: ex_eval.c:910
+msgid "E580: :endif without :if"
+msgstr "E580: ¡\":endif\" sin un \":if\"!"
+
+#: ex_eval.c:955
+msgid "E581: :else without :if"
+msgstr "E581: ¡\":else\" sin un \":if\"!"
+
+#: ex_eval.c:958
+msgid "E582: :elseif without :if"
+msgstr "E582: ¡\":elseif\" sin un \":if\"!"
+
+#: ex_eval.c:965
+msgid "E583: multiple :else"
+msgstr "E583: ¡\":else\" múltiple!"
+
+#: ex_eval.c:968
+msgid "E584: :elseif after :else"
+msgstr "E584: ¡\":elseif\" después de \":else\"!"
+
+#: ex_eval.c:1035
+msgid "E585: :while/:for nesting too deep"
+msgstr "E585: ¡\":while\" anidado en exceso!"
+
+#: ex_eval.c:1133
+msgid "E586: :continue without :while or :for"
+msgstr "E586: ¡\":continue\" sin un \":while\" o \":for\"!"
+
+#: ex_eval.c:1172
+msgid "E587: :break without :while or :for"
+msgstr "E587: ¡\":break\" sin \":while\" o \":for\"!"
+
+#: ex_eval.c:1222
+msgid "E732: Using :endfor with :while"
+msgstr "E732: Usando \":endfor\" con \":while\""
+
+#: ex_eval.c:1224
+msgid "E733: Using :endwhile with :for"
+msgstr "E733: Usando \":endwhile\" con \":for\""
+
+#: ex_eval.c:1399
+msgid "E601: :try nesting too deep"
+msgstr "E601: ¡\":try\" anidado en exceso!"
+
+#: ex_eval.c:1479
+msgid "E603: :catch without :try"
+msgstr "E603: ¡\":catch\" sin un \":try\"!"
+
+# Give up for a ":catch" after ":finally" and ignore it.
+# * Just parse.
+#. Give up for a ":catch" after ":finally" and ignore it.
+#. * Just parse.
+#: ex_eval.c:1498
+msgid "E604: :catch after :finally"
+msgstr "E604: ¡\":catch\" después de \":finally\"!"
+
+#: ex_eval.c:1632
+msgid "E606: :finally without :try"
+msgstr "E606: ¡\":finally\" sin un \":try\"!"
+
+# Give up for a multiple ":finally" and ignore it.
+#. Give up for a multiple ":finally" and ignore it.
+#: ex_eval.c:1652
+msgid "E607: multiple :finally"
+msgstr "E607: ¡\":finally\" múltiple!"
+
+#: ex_eval.c:1762
+msgid "E602: :endtry without :try"
+msgstr "E602: ¡\":endtry\" sin un \":try\"!"
+
+#: ex_eval.c:2267
+msgid "E193: :endfunction not inside a function"
+msgstr "E193: ¡\":endfunction\" no está dentro de una función!"
+
+#: ex_getln.c:2010
+msgid "E788: Not allowed to edit another buffer now"
+msgstr "E788: No se permite editar otro búfer en este momento"
+
+#: ex_getln.c:2025
+msgid "E811: Not allowed to change buffer information now"
+msgstr "E811: No se permite cambiar la información del búfer en este momento"
+
+#: ex_getln.c:3924
+msgid "tagname"
+msgstr "Nombre de la etiqueta (\"tagname\")"
+
+#: ex_getln.c:3927
+msgid " kind file\n"
+msgstr " tipo de archivo\n"
+
+#: ex_getln.c:5676
+msgid "'history' option is zero"
+msgstr "La opción 'history' (historia) es cero"
+
+#: ex_getln.c:5947
+#, c-format
+msgid ""
+"\n"
+"# %s History (newest to oldest):\n"
+msgstr ""
+"\n"
+"# Historia de %s (de lo más nuevo a lo más antiguo):\n"
+
+#: ex_getln.c:5948
+msgid "Command Line"
+msgstr "Línea de órdenes"
+
+#: ex_getln.c:5949
+msgid "Search String"
+msgstr "Cadena de búsqueda"
+
+#: ex_getln.c:5950
+msgid "Expression"
+msgstr "Expresión"
+
+#: ex_getln.c:5951
+msgid "Input Line"
+msgstr "Línea de entrada"
+
+#: ex_getln.c:5989
+msgid "E198: cmd_pchar beyond the command length"
+msgstr "E198: \"cmd_pchar\" más allá de la longitud de la orden"
+
+#: ex_getln.c:6190
+msgid "E199: Active window or buffer deleted"
+msgstr "E199: Se borró la ventana o el búfer activo"
+
+#: fileio.c:153
+msgid "E812: Autocommands changed buffer or buffer name"
+msgstr "E812: *Filtro* Las auto-órdenes no deben cambiar el búfer en uso"
+
+#: fileio.c:408
+msgid "Illegal file name"
+msgstr "Nombre de archivo ilegal"
+
+#: fileio.c:437 fileio.c:591 fileio.c:3320 fileio.c:3371
+msgid "is a directory"
+msgstr "es un directorio"
+
+#: fileio.c:439
+msgid "is not a file"
+msgstr "no es un archivo"
+
+#: fileio.c:452
+msgid "is a device (disabled with 'opendevice' option)"
+msgstr "es un dispositivo (desactivado con la opción 'opendevice')"
+
+#: fileio.c:628 fileio.c:4605
+msgid "[New File]"
+msgstr "[Archivo nuevo]"
+
+#: fileio.c:631
+msgid "[New DIRECTORY]"
+msgstr "[Directorio nuevo]"
+
+#: fileio.c:665
+msgid "[File too big]"
+msgstr "[El archivo es demasiado grande]"
+
+#: fileio.c:667
+msgid "[Permission Denied]"
+msgstr "[Permiso denegado]"
+
+#: fileio.c:800
+msgid "E200: *ReadPre autocommands made the file unreadable"
+msgstr "E200: Las auto-órdenes \"*ReadPre\" hicieron ilegible el archivo"
+
+#: fileio.c:802
+msgid "E201: *ReadPre autocommands must not change current buffer"
+msgstr "E201: Las auto-órdenes \"*ReadPre\" no deben cambiar el búfer en uso"
+
+#: fileio.c:823
+msgid "Vim: Reading from stdin...\n"
+msgstr "Vim: Leyendo la entrada estándar...\n"
+
+#: fileio.c:829
+msgid "Reading from stdin..."
+msgstr "Leyendo la entrada estándar..."
+
+# Re-opening the original file failed!
+#. Re-opening the original file failed!
+#: fileio.c:1128
+msgid "E202: Conversion made file unreadable!"
+msgstr "E202: ¡La conversión ha hecho ilegible el archivo!"
+
+#: fileio.c:2362
+msgid "[fifo/socket]"
+msgstr "[fifo/socket]"
+
+#: fileio.c:2369
+msgid "[fifo]"
+msgstr "[fifo]"
+
+#: fileio.c:2376
+msgid "[socket]"
+msgstr "[socket]"
+
+#: fileio.c:2384
+msgid "[character special]"
+msgstr "[carácter especial]"
+
+#: fileio.c:2391 netbeans.c:3632
+msgid "[RO]"
+msgstr "[RO]"
+
+#: fileio.c:2401
+msgid "[CR missing]"
+msgstr "[Falta un CR]"
+
+#: fileio.c:2406
+msgid "[long lines split]"
+msgstr "[se han dividido las líneas largas]"
+
+#: fileio.c:2412 fileio.c:4589
+msgid "[NOT converted]"
+msgstr "[NO se ha convertido]"
+
+#: fileio.c:2417 fileio.c:4594
+msgid "[converted]"
+msgstr "[convertido]"
+
+#: fileio.c:2424 fileio.c:4619
+msgid "[crypted]"
+msgstr "[cifrado]"
+
+#: fileio.c:2432
+#, c-format
+msgid "[CONVERSION ERROR in line %ld]"
+msgstr "[ERROR DE CONVERSIÓN en línea %ld]"
+
+#: fileio.c:2438
+#, c-format
+msgid "[ILLEGAL BYTE in line %ld]"
+msgstr "[BYTE ILEGAL en la línea %ld]"
+
+#: fileio.c:2445
+msgid "[READ ERRORS]"
+msgstr "[ERRORES DE LECTURA]"
+
+#: fileio.c:2723
+msgid "Can't find temp file for conversion"
+msgstr "No se pudo encontrar el archivo temporal para la conversión"
+
+#: fileio.c:2730
+msgid "Conversion with 'charconvert' failed"
+msgstr "Falló la conversión con 'charconvert'"
+
+#: fileio.c:2733
+msgid "can't read output of 'charconvert'"
+msgstr "No se pudo leer el resultado de 'charconvert'"
+
+#: fileio.c:3165
+msgid "E676: No matching autocommands for acwrite buffer"
+msgstr "E676: No coincide ninguna auto-orden para \"acwrite\"en el búfer"
+
+#: fileio.c:3200
+msgid "E203: Autocommands deleted or unloaded buffer to be written"
+msgstr ""
+"E203: Las auto-órdenes fueron suprimidas o el búfer se descargó para ser "
+"grabado en disco"
+
+#: fileio.c:3223
+msgid "E204: Autocommand changed number of lines in unexpected way"
+msgstr ""
+"E204: La auto-orden ha cambiado el número de líneas en forma inesperada"
+
+#: fileio.c:3263
+msgid "NetBeans disallows writes of unmodified buffers"
+msgstr "NetBeans no permite que se escriba sobre búfers sin modificar"
+
+#: fileio.c:3271
+msgid "Partial writes disallowed for NetBeans buffers"
+msgstr "No se permite la escritura parcial de los búfers de NetBeans"
+
+#: fileio.c:3326 fileio.c:3344
+msgid "is not a file or writable device"
+msgstr "no es un archivo o dispositivo en el que se pueda escribir"
+
+#: fileio.c:3355
+msgid "writing to device disabled with 'opendevice' option"
+msgstr ""
+"se ha desactivado la escritura en dispositivo con la opción 'opendevice'"
+
+#: fileio.c:3397 netbeans.c:3694
+msgid "is read-only (add ! to override)"
+msgstr "es de solo lectura (añada ! para sobreescribir)"
+
+#: fileio.c:3761
+msgid "E506: Can't write to backup file (add ! to override)"
+msgstr ""
+"E506: No se pudo escribir en el archivo de recuperación\n"
+"(añada ! para forzar la orden)"
+
+#: fileio.c:3773
+msgid "E507: Close error for backup file (add ! to override)"
+msgstr ""
+"E507: Error al cerrar el archivo de la copia de seguridad (añada ! para "
+"forzar la orden)"
+
+#: fileio.c:3775
+msgid "E508: Can't read file for backup (add ! to override)"
+msgstr ""
+"E508: No se pudo leer el archivo para crear la copia de seguridad (añada ! "
+"para forzar la orden)"
+
+#: fileio.c:3794
+msgid "E509: Cannot create backup file (add ! to override)"
+msgstr ""
+"E509: No se pudo crear el archivo para la copia de seguridad (añada ! para "
+"forzar la orden)"
+
+#: fileio.c:3896
+msgid "E510: Can't make backup file (add ! to override)"
+msgstr ""
+"E510: No se pudo hacer un archivo de copia de seguridad (añada ! para forzar "
+"la orden)"
+
+#: fileio.c:3958
+msgid "E460: The resource fork would be lost (add ! to override)"
+msgstr ""
+"E460: Se perdería el segmento (\"fork\") de recursos (añada ! para forzar la "
+"orden)"
+
+#: fileio.c:4067
+msgid "E214: Can't find temp file for writing"
+msgstr "E214: No se pudo encontrar el archivo temporal para escribir en él"
+
+#: fileio.c:4085
+msgid "E213: Cannot convert (add ! to write without conversion)"
+msgstr ""
+"E213: No se pudo convertir (añada \"!\" para escribir el archivo sin "
+"conversión)"
+
+#: fileio.c:4120
+msgid "E166: Can't open linked file for writing"
+msgstr "E166: No se pudo abrir el archivo enlazado para escribir"
+
+#: fileio.c:4124
+msgid "E212: Can't open file for writing"
+msgstr "E212: No se pudo abrir el archivo para escribir en él"
+
+#: fileio.c:4405
+msgid "E667: Fsync failed"
+msgstr "E667: Falló \"fsync\" (sincronización de archivo)"
+
+#: fileio.c:4444
+msgid "E512: Close failed"
+msgstr "E512: Falló el cierre del archivo"
+
+#: fileio.c:4496
+msgid "E513: write error, conversion failed (make 'fenc' empty to override)"
+msgstr ""
+"E513: Error de escritura, la conversión falló (vacíe 'fenc' para forzar)."
+
+#: fileio.c:4501
+#, c-format
+msgid ""
+"E513: write error, conversion failed in line %ld (make 'fenc' empty to "
+"override)"
+msgstr ""
+"E513: Error de escritura, la conversión falló en la línea %ld(vacíe 'fenc' "
+"para forzar)"
+
+#: fileio.c:4510
+msgid "E514: write error (file system full?)"
+msgstr "E514: Error de escritura (¿Sistema de archivos lleno?)"
+
+#: fileio.c:4578
+msgid " CONVERSION ERROR"
+msgstr " ERROR DE CONVERSIÓN"
+
+#: fileio.c:4583
+#, c-format
+msgid " in line %ld;"
+msgstr "en la línea %ld"
+
+#: fileio.c:4600
+msgid "[Device]"
+msgstr "[Dispositivo]"
+
+#: fileio.c:4605
+msgid "[New]"
+msgstr "[Nuevo]"
+
+#: fileio.c:4627
+msgid " [a]"
+msgstr " [a]"
+
+#: fileio.c:4627
+msgid " appended"
+msgstr " añadido"
+
+#: fileio.c:4629
+msgid " [w]"
+msgstr " [w]"
+
+#: fileio.c:4629
+msgid " written"
+msgstr " escritos"
+
+#: fileio.c:4684
+msgid "E205: Patchmode: can't save original file"
+msgstr "E205: Modo de parcheo: no se puede guardar el archivo original"
+
+#: fileio.c:4707
+msgid "E206: patchmode: can't touch empty original file"
+msgstr "E206: Modo de parcheo: no se puede tocar el archivo original vacío"
+
+#: fileio.c:4722
+msgid "E207: Can't delete backup file"
+msgstr "E207: No se pudo borrar el archivo de respaldo"
+
+#: fileio.c:4788
+msgid ""
+"\n"
+"WARNING: Original file may be lost or damaged\n"
+msgstr ""
+"\n"
+"ADVERTENCIA: el archivo original puede haberse perdido o dañado\n"
+
+#: fileio.c:4790
+msgid "don't quit the editor until the file is successfully written!"
+msgstr "¡no salga del editor hasta que el archivo se haya escrito!"
+
+#: fileio.c:4932
+msgid "[dos]"
+msgstr "[DOS]"
+
+#: fileio.c:4932
+msgid "[dos format]"
+msgstr "[formato DOS]"
+
+#: fileio.c:4939
+msgid "[mac]"
+msgstr "[Mac]"
+
+#: fileio.c:4939
+msgid "[mac format]"
+msgstr "[formato Mac]"
+
+#: fileio.c:4946
+msgid "[unix]"
+msgstr "[UNIX]"
+
+#: fileio.c:4946
+msgid "[unix format]"
+msgstr "[formato UNIX]"
+
+#: fileio.c:4973
+msgid "1 line, "
+msgstr "1 línea, "
+
+#: fileio.c:4975
+#, c-format
+msgid "%ld lines, "
+msgstr "%ld líneas, "
+
+#: fileio.c:4978
+msgid "1 character"
+msgstr "1 carácter"
+
+#: fileio.c:4980
+#, c-format
+msgid "%ld characters"
+msgstr "%ld caracteres"
+
+#: fileio.c:4990 netbeans.c:3637
+msgid "[noeol]"
+msgstr "[no hay fin de línea]"
+
+#: fileio.c:4990 netbeans.c:3637
+msgid "[Incomplete last line]"
+msgstr "[Última línea incompleta]"
+
+# don't overwrite messages here
+# must give this prompt
+# don't use emsg() here, don't want to flush the buffers
+#. don't overwrite messages here
+#. must give this prompt
+#. don't use emsg() here, don't want to flush the buffers
+#: fileio.c:5009
+msgid "WARNING: The file has been changed since reading it!!!"
+msgstr "ADVERTENCIA: ¡¡¡El archivo ha cambiado desde que se leyó!!!"
+
+#: fileio.c:5011
+msgid "Do you really want to write to it"
+msgstr "¿Desea realmente escribir al archivo?"
+
+#: fileio.c:6375
+#, c-format
+msgid "E208: Error writing to \"%s\""
+msgstr "E208: Error al escribir a \"%s\""
+
+#: fileio.c:6382
+#, c-format
+msgid "E209: Error closing \"%s\""
+msgstr "E209: Error al cerrar \"%s\""
+
+#: fileio.c:6385
+#, c-format
+msgid "E210: Error reading \"%s\""
+msgstr "E210: Error al leer \"%s\""
+
+#: fileio.c:6647
+msgid "E246: FileChangedShell autocommand deleted buffer"
+msgstr "E246: La auto-orden \"FileChangedShell\" ha borrado el búfer"
+
+#: fileio.c:6662
+#, c-format
+msgid "E211: File \"%s\" no longer available"
+msgstr "E211: El archivo \"%s\" ya no está disponible"
+
+#: fileio.c:6677
+#, c-format
+msgid ""
+"W12: Warning: File \"%s\" has changed and the buffer was changed in Vim as "
+"well"
+msgstr ""
+"W12: Advertencia: el archivo \"%s\" ha cambiado y el búfer se modificó "
+"también en Vim"
+
+#: fileio.c:6678
+msgid "See \":help W12\" for more info."
+msgstr "Véase \":help W12\" para más información"
+
+#: fileio.c:6682
+#, c-format
+msgid "W11: Warning: File \"%s\" has changed since editing started"
+msgstr ""
+"W11: Advertencia: el archivo \"%s\" ha cambiado desde que comenzó la edición"
+
+#: fileio.c:6683
+msgid "See \":help W11\" for more info."
+msgstr "Véase \":help W11\" para más información."
+
+#: fileio.c:6687
+#, c-format
+msgid "W16: Warning: Mode of file \"%s\" has changed since editing started"
+msgstr ""
+"W16: Advertencia: el modo del archivo \"%s\" ha cambiado desde que comenzó "
+"la edición"
+
+#: fileio.c:6688
+msgid "See \":help W16\" for more info."
+msgstr "Véase \":help W16\" para más información."
+
+#: fileio.c:6703
+#, c-format
+msgid "W13: Warning: File \"%s\" has been created after editing started"
+msgstr ""
+"W13: Advertencia: la creación del archivo \"%s\" es posterior al inicio de "
+"la edición"
+
+#: fileio.c:6733
+msgid "Warning"
+msgstr "Advertencia"
+
+#: fileio.c:6734
+msgid ""
+"&OK\n"
+"&Load File"
+msgstr ""
+"&OK\n"
+"&Cargar archivo"
+
+#: fileio.c:6857
+#, c-format
+msgid "E462: Could not prepare for reloading \"%s\""
+msgstr "E462: No pude prepararme para recargar \"%s\""
+
+#: fileio.c:6876
+#, c-format
+msgid "E321: Could not reload \"%s\""
+msgstr "E321: No pude recargar \"%s\""
+
+#: fileio.c:7490
+msgid "--Deleted--"
+msgstr "--Suprimido--"
+
+#: fileio.c:7643
+#, c-format
+msgid "auto-removing autocommand: %s <buffer=%d>"
+msgstr "Auto-removiendo autocomando: %s <búfer=%d>"
+
+# the group doesn't exist
+#. the group doesn't exist
+#: fileio.c:7689
+#, c-format
+msgid "E367: No such group: \"%s\""
+msgstr "E367: No existe el grupo: %s"
+
+#: fileio.c:7836
+#, c-format
+msgid "E215: Illegal character after *: %s"
+msgstr "E215: Carácter ilegal después de *: %s"
+
+#: fileio.c:7848
+#, c-format
+msgid "E216: No such event: %s"
+msgstr "E216: No existe tal evento: %s"
+
+#: fileio.c:7850
+#, c-format
+msgid "E216: No such group or event: %s"
+msgstr "E216: No existe tal grupo o evento: %s"
+
+# Highlight title
+#. Highlight title
+#: fileio.c:8058
+msgid ""
+"\n"
+"--- Auto-Commands ---"
+msgstr ""
+"\n"
+"--- Auto-órdenes ---"
+
+#: fileio.c:8294
+#, c-format
+msgid "E680: <buffer=%d>: invalid buffer number "
+msgstr "E680: número de <búfer=%d> no válido"
+
+#: fileio.c:8391
+msgid "E217: Can't execute autocommands for ALL events"
+msgstr "E217: No se pueden ejecutar las auto-órdenes para TODOS los eventos"
+
+#: fileio.c:8414
+msgid "No matching autocommands"
+msgstr "No coincide ninguna auto-orden"
+
+#: fileio.c:8862
+msgid "E218: autocommand nesting too deep"
+msgstr "E218: La auto-orden se anida en exceso"
+
+#: fileio.c:9215
+#, c-format
+msgid "%s Auto commands for \"%s\""
+msgstr "%s Auto-órdenes para \"%s\""
+
+#: fileio.c:9225
+#, c-format
+msgid "Executing %s"
+msgstr "Ejecutando %s"
+
+# always scroll up, don't overwrite
+#: fileio.c:9294
+#, c-format
+msgid "autocommand %s"
+msgstr "auto-orden %s"
+
+#: fileio.c:9977
+msgid "E219: Missing {."
+msgstr "E219: Falta un {."
+
+#: fileio.c:9979
+msgid "E220: Missing }."
+msgstr "E220: Falta un }."
+
+#: fold.c:68
+msgid "E490: No fold found"
+msgstr "E490: No se encontró ningún pliegue"
+
+#: fold.c:593
+msgid "E350: Cannot create fold with current 'foldmethod'"
+msgstr "E350: No se puede crear el pliegue con el 'foldmethod' actual activo"
+
+#: fold.c:595
+msgid "E351: Cannot delete fold with current 'foldmethod'"
+msgstr "E351: No se puede borrar el pliegue con el 'foldmethod' activo"
+
+#: fold.c:1999
+#, c-format
+msgid "+--%3ld lines folded "
+msgstr "+--%3ld líneas plegadas"
+
+#: getchar.c:252
+msgid "E222: Add to read buffer"
+msgstr "E222: Añadir al búfer de lectura"
+
+#: getchar.c:2407
+msgid "E223: recursive mapping"
+msgstr "E223: Asociación recursiva"
+
+#: getchar.c:3366
+#, c-format
+msgid "E224: global abbreviation already exists for %s"
+msgstr "E224: Ya existe una abreviatura global para %s"
+
+#: getchar.c:3369
+#, c-format
+msgid "E225: global mapping already exists for %s"
+msgstr "E225: Ya existe una asociación global para %s"
+
+#: getchar.c:3501
+#, c-format
+msgid "E226: abbreviation already exists for %s"
+msgstr "E226: Ya existe una abreviatura para %s"
+
+#: getchar.c:3504
+#, c-format
+msgid "E227: mapping already exists for %s"
+msgstr "E227: Ya existe una asociación para %s"
+
+#: getchar.c:3572
+msgid "No abbreviation found"
+msgstr "No se encontró ninguna abreviatura"
+
+#: getchar.c:3574
+msgid "No mapping found"
+msgstr "No se encontró ninguna asociación de teclado"
+
+#: getchar.c:4687
+msgid "E228: makemap: Illegal mode"
+msgstr "E228: \"makemap\": modo ilegal"
+
+#: gui.c:226
+msgid "E229: Cannot start the GUI"
+msgstr "E229: No se pudo iniciar la interfaz gráfica"
+
+#: gui.c:361
+#, c-format
+msgid "E230: Cannot read from \"%s\""
+msgstr "E230: No se pudo leer desde \"%s\""
+
+#: gui.c:487
+msgid "E665: Cannot start GUI, no valid font found"
+msgstr ""
+"E665: No se pudo iniciar la interfaz gráfica (GUI), no se encontró ninguna "
+"tipografía de impresión válida"
+
+#: gui.c:492
+msgid "E231: 'guifontwide' invalid"
+msgstr "E231: El valor de 'guifontwide' no es válido"
+
+#: gui.c:603
+msgid "E599: Value of 'imactivatekey' is invalid"
+msgstr "E599: El valor de 'imactivatekey' no es válido"
+
+#: gui.c:4526
+#, c-format
+msgid "E254: Cannot allocate color %s"
+msgstr "E254: No se pudo asignar el color %s"
+
+#: gui.c:5107
+msgid "No match at cursor, finding next"
+msgstr ""
+"No hay correspondencia en la posición del cursor, buscando la siguiente"
+
+#: gui_at_fs.c:300
+msgid "<cannot open> "
+msgstr "<no se puede abrir> "
+
+#: gui_at_fs.c:1133
+#, c-format
+msgid "E616: vim_SelFile: can't get font %s"
+msgstr ""
+"E616: \"vim_SelFile\": No se puede hallar la tipografía de impresión %s"
+
+#: gui_at_fs.c:2764
+msgid "E614: vim_SelFile: can't return to current directory"
+msgstr "E614: \"vim_SelFile\": no puedo regresar al directorio actual"
+
+#: gui_at_fs.c:2784
+msgid "Pathname:"
+msgstr "Nombre de la ruta:"
+
+#: gui_at_fs.c:2790
+msgid "E615: vim_SelFile: can't get current directory"
+msgstr ""
+"E615: \"vim_SelFile\": No se pudo obtener la ubicación del directorio actual"
+
+#: gui_at_fs.c:2798 gui_xmdlg.c:931
+msgid "OK"
+msgstr "OK"
+
+#: gui_at_fs.c:2798 gui_gtk.c:2831 gui_xmdlg.c:940
+msgid "Cancel"
+msgstr "Cancelar"
+
+#: gui_at_sb.c:490
+msgid "Scrollbar Widget: Could not get geometry of thumb pixmap."
+msgstr ""
+"Scrollbar Widget: No pude obtener la geometría de la miniatura \"pixmap\""
+
+#: gui_athena.c:2160 gui_motif.c:2588
+msgid "Vim dialog"
+msgstr "Diálogo de Vim"
+
+#: gui_beval.c:200 gui_w32.c:4728
+msgid "E232: Cannot create BalloonEval with both message and callback"
+msgstr ""
+"E232: No se pudo crear un \"BalloonEval\" que contenga tanto el mensaje como "
+"la llamada de retorno"
+
+#: gui_gtk.c:1694
+msgid "Vim dialog..."
+msgstr "Diálogo de Vim..."
+
+#: gui_gtk.c:2145 message.c:3654
+msgid ""
+"&Yes\n"
+"&No\n"
+"&Cancel"
+msgstr ""
+"&Si\n"
+"&No\n"
+"&Cancelar"
+
+#: gui_gtk.c:2356
+msgid "Input _Methods"
+msgstr "Métodos de Entrada (\"Input Methods\")"
+
+#: gui_gtk.c:2634 gui_motif.c:3760
+msgid "VIM - Search and Replace..."
+msgstr "VIM - Buscar y reemplazar..."
+
+#: gui_gtk.c:2642 gui_motif.c:3762
+msgid "VIM - Search..."
+msgstr "VIM - Buscar..."
+
+#: gui_gtk.c:2674 gui_motif.c:3871
+msgid "Find what:"
+msgstr "¿Encontrar qué?:"
+
+#: gui_gtk.c:2692 gui_motif.c:3904
+msgid "Replace with:"
+msgstr "Reemplazar con:"
+
+# whole word only button
+#. whole word only button
+#: gui_gtk.c:2724 gui_motif.c:4025
+msgid "Match whole word only"
+msgstr "Encontrar solo palabras completas"
+
+# match case button
+#. match case button
+#: gui_gtk.c:2735 gui_motif.c:4037
+msgid "Match case"
+msgstr "La única coincidencia"
+
+#: gui_gtk.c:2745 gui_motif.c:3976
+msgid "Direction"
+msgstr "Dirección"
+
+# 'Up' and 'Down' buttons
+#. 'Up' and 'Down' buttons
+#: gui_gtk.c:2757 gui_motif.c:3989
+msgid "Up"
+msgstr "Hacia arriba"
+
+#: gui_gtk.c:2761 gui_motif.c:3998
+msgid "Down"
+msgstr "Hacia abajo"
+
+#: gui_gtk.c:2783 gui_gtk.c:2785
+msgid "Find Next"
+msgstr "Encontrar siguiente"
+
+#: gui_gtk.c:2802 gui_gtk.c:2804
+msgid "Replace"
+msgstr "Reemplazar"
+
+#: gui_gtk.c:2815 gui_gtk.c:2817
+msgid "Replace All"
+msgstr "Reemplazar todos"
+
+#: gui_gtk_x11.c:2417
+msgid "Vim: Received \"die\" request from session manager\n"
+msgstr "Vim: Recibí una solicitud \"die\" del administrador de sesiones.\n"
+
+#: gui_gtk_x11.c:3244
+msgid "Close"
+msgstr "Cerrar"
+
+#: gui_gtk_x11.c:3245 gui_w48.c:2375
+msgid "New tab"
+msgstr "Pestaña nueva"
+
+#: gui_gtk_x11.c:3246
+msgid "Open Tab..."
+msgstr "Abrir pestaña..."
+
+#: gui_gtk_x11.c:4025
+msgid "Vim: Main window unexpectedly destroyed\n"
+msgstr "Vim: La ventana principal fue destruida inesperadamente.\n"
+
+#: gui_gtk_x11.c:4746
+msgid "Font Selection"
+msgstr "Selección de tipos de letra"
+
+#: gui_motif.c:2355
+msgid "&Filter"
+msgstr "&Filtro"
+
+#: gui_motif.c:2356 gui_motif.c:3839
+msgid "&Cancel"
+msgstr "&Cancelar"
+
+#: gui_motif.c:2357
+msgid "Directories"
+msgstr "Directorios"
+
+#: gui_motif.c:2358
+msgid "Filter"
+msgstr "Filtro"
+
+#: gui_motif.c:2359
+msgid "&Help"
+msgstr "&Ayuda"
+
+#: gui_motif.c:2360
+msgid "Files"
+msgstr "Archivos"
+
+#: gui_motif.c:2361
+msgid "&OK"
+msgstr "&OK"
+
+#: gui_motif.c:2362
+msgid "Selection"
+msgstr "Selección"
+
+#: gui_motif.c:3791
+msgid "Find &Next"
+msgstr "Encontrar &Siguiente"
+
+#: gui_motif.c:3806
+msgid "&Replace"
+msgstr "&Reemplazar"
+
+#: gui_motif.c:3817
+msgid "Replace &All"
+msgstr "Reemplazar &Todos"
+
+#: gui_motif.c:3828
+msgid "&Undo"
+msgstr "&Deshacer"
+
+#: gui_w32.c:1177
+#, c-format
+msgid "E671: Cannot find window title \"%s\""
+msgstr "E671: No se pudo encontrar el título de la ventana \"%s\""
+
+#: gui_w32.c:1190
+#, c-format
+msgid "E243: Argument not supported: \"-%s\"; Use the OLE version."
+msgstr "E243: Argumento no admitido: \"-%s\"; use la versión OLE."
+
+#: gui_w32.c:1442
+msgid "E672: Unable to open window inside MDI application"
+msgstr "E672: Incapaz de abrir ventana dentro de la aplicación MDI"
+
+#: gui_w48.c:2374
+msgid "Close tab"
+msgstr "Cerrar Ventana"
+
+#: gui_w48.c:2377
+msgid "Open tab..."
+msgstr "Abrir pestaña..."
+
+#: gui_w48.c:2633
+msgid "Find string (use '\\\\' to find a '\\')"
+msgstr "Buscar cadena (use '\\\\' para encontrar un '\\')"
+
+#: gui_w48.c:2669
+msgid "Find & Replace (use '\\\\' to find a '\\')"
+msgstr "Buscar y reemplazar (use '\\\\' para encontrar un '\\')"
+
+#. We fake this: Use a filter that doesn't select anything and a default
+#. * file name that won't be used.
+#: gui_w48.c:3463
+msgid "Not Used"
+msgstr "Sin usar"
+
+#: gui_w48.c:3464
+msgid "Directory\t*.nothing\n"
+msgstr "Directorio\t*.nada\n"
+
+#: gui_x11.c:1546
+msgid "Vim E458: Cannot allocate colormap entry, some colors may be incorrect"
+msgstr ""
+"Vim E458: no se puede asignar una entrada al mapa de colores; algunos "
+"colores tal vez no sean correctos"
+
+#: gui_x11.c:2138
+#, c-format
+msgid "E250: Fonts for the following charsets are missing in fontset %s:"
+msgstr ""
+"E250: Faltan los tipos de letras para los siguientes conjuntos de caracteres "
+"en el conjunto de fuentes %s:"
+
+#: gui_x11.c:2181
+#, c-format
+msgid "E252: Fontset name: %s"
+msgstr "E252: Nombre del conjunto de tipos de letra: %s"
+
+#: gui_x11.c:2182
+#, c-format
+msgid "Font '%s' is not fixed-width"
+msgstr "La tipografía de impresión '%s' no es de ancho fijo"
+
+#: gui_x11.c:2201
+#, c-format
+msgid "E253: Fontset name: %s\n"
+msgstr "E253: Nombre del conjunto de tipografías de impresión: %s\n"
+
+#: gui_x11.c:2202
+#, c-format
+msgid "Font0: %s\n"
+msgstr "Tipo de letra de impresión 0: %s\n"
+
+#: gui_x11.c:2203
+#, c-format
+msgid "Font1: %s\n"
+msgstr "Tipo de letra de impresión 1: %s\n"
+
+#: gui_x11.c:2204
+#, c-format
+msgid "Font%ld width is not twice that of font0\n"
+msgstr ""
+"La anchura del tipo de letra de impresión %ld no es el doble de la \n"
+"de la tipografía de impresión 0\n"
+
+#: gui_x11.c:2205
+#, c-format
+msgid "Font0 width: %ld\n"
+msgstr "Anchura del tipo de letra de impresión 0: %ld\n"
+
+#: gui_x11.c:2206
+#, c-format
+msgid ""
+"Font1 width: %ld\n"
+"\n"
+msgstr ""
+"Anchura del tipo de letra de impresión 1: %ld\n"
+"\n"
+
+#: gui_xmdlg.c:690 gui_xmdlg.c:809
+msgid "Invalid font specification"
+msgstr "La especificación de tipo de letra no es válida"
+
+#: gui_xmdlg.c:691 gui_xmdlg.c:810
+msgid "&Dismiss"
+msgstr "&Cerrar"
+
+#: gui_xmdlg.c:700
+msgid "no specific match"
+msgstr "no hay una coincidencia especifica"
+
+#: gui_xmdlg.c:909
+msgid "Vim - Font Selector"
+msgstr "Vim - Selector de tipos de letra"
+
+#: gui_xmdlg.c:978
+msgid "Name:"
+msgstr "Nombre:"
+
+#. create toggle button
+#: gui_xmdlg.c:1018
+msgid "Show size in Points"
+msgstr "Mostrar tamaño en puntos"
+
+#: gui_xmdlg.c:1037
+msgid "Encoding:"
+msgstr "Codificando:"
+
+#: gui_xmdlg.c:1083
+msgid "Font:"
+msgstr "Tipo de letra:"
+
+#: gui_xmdlg.c:1116
+msgid "Style:"
+msgstr "Estilo:"
+
+#: gui_xmdlg.c:1148
+msgid "Size:"
+msgstr "Tamaño:"
+
+#: hangulin.c:610
+msgid "E256: Hangul automata ERROR"
+msgstr "E256: ERROR del autómata Hangul"
+
+#: hardcopy.c:210
+msgid "E550: Missing colon"
+msgstr "E550: Falta un símbolo de dos puntos"
+
+#: hardcopy.c:222
+msgid "E551: Illegal component"
+msgstr "E551: Componente ilegal"
+
+#: hardcopy.c:230
+msgid "E552: digit expected"
+msgstr "E552: Se esperaba un dígito"
+
+#: hardcopy.c:501
+#, c-format
+msgid "Page %d"
+msgstr "Página %d"
+
+#: hardcopy.c:658
+msgid "No text to be printed"
+msgstr "No hay texto que imprimir"
+
+#: hardcopy.c:736
+#, c-format
+msgid "Printing page %d (%d%%)"
+msgstr "Imprimiendo la página %d (%d%%)"
+
+#: hardcopy.c:748
+#, c-format
+msgid " Copy %d of %d"
+msgstr "Copia %d de %d"
+
+#: hardcopy.c:806
+#, c-format
+msgid "Printed: %s"
+msgstr "Impreso: %s"
+
+#: hardcopy.c:814
+msgid "Printing aborted"
+msgstr "Impresión interrumpida"
+
+#: hardcopy.c:1469
+msgid "E455: Error writing to PostScript output file"
+msgstr "E455: Error escribiendo al archivo PostScript de salida"
+
+#: hardcopy.c:1931
+#, c-format
+msgid "E624: Can't open file \"%s\""
+msgstr "E624: No se pudo abrir el archivo \"%s\""
+
+#: hardcopy.c:1941 hardcopy.c:2822
+#, c-format
+msgid "E457: Can't read PostScript resource file \"%s\""
+msgstr "E457: No se pudo leer el archivo de recursos de PostScript \"%s\""
+
+#: hardcopy.c:1957
+#, c-format
+msgid "E618: file \"%s\" is not a PostScript resource file"
+msgstr "E618: El archivo \"%s\" no es un archivo de recursos PostScript"
+
+#: hardcopy.c:1975 hardcopy.c:1994 hardcopy.c:2037
+#, c-format
+msgid "E619: file \"%s\" is not a supported PostScript resource file"
+msgstr "E619: El archivo \"%s\" no es un recurso PostScript que pueda usar"
+
+#: hardcopy.c:2056
+#, c-format
+msgid "E621: \"%s\" resource file has wrong version"
+msgstr "E621: La versión del archivo de recursos \"%s\" es incorrecta"
+
+#: hardcopy.c:2543
+msgid "E673: Incompatible multi-byte encoding and character set."
+msgstr "E673: Codificación y set de caracteres multi-byte incompatibles"
+
+#: hardcopy.c:2560
+msgid "E674: printmbcharset cannot be empty with multi-byte encoding."
+msgstr ""
+"E674: \"printmbcharset\" no puede estar vacío en una codificación multi-byte"
+
+#: hardcopy.c:2578
+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"
+"multi-byte"
+
+#: hardcopy.c:2771
+msgid "E324: Can't open PostScript output file"
+msgstr "E324: No se pudo abrir el archivo PostScript de salida"
+
+#: hardcopy.c:2808
+#, c-format
+msgid "E456: Can't open file \"%s\""
+msgstr "E456: No se pudo abrir el archivo %s"
+
+#: hardcopy.c:2942
+msgid "E456: Can't find PostScript resource file \"prolog.ps\""
+msgstr "E456: No se encontró el archivo de recursos PostScript \"prolog.ps\""
+
+#: hardcopy.c:2955
+msgid "E456: Can't find PostScript resource file \"cidfont.ps\""
+msgstr "E456: No se encontró el archivo de recursos PostScript \"cidfont.ps\""
+
+#: hardcopy.c:2993 hardcopy.c:3015 hardcopy.c:3044
+#, c-format
+msgid "E456: Can't find PostScript resource file \"%s.ps\""
+msgstr "E456: No se encontró el archivo de recursos PostScript \"%s.ps\""
+
+#: hardcopy.c:3031
+#, c-format
+msgid "E620: Unable to convert to print encoding \"%s\""
+msgstr "E620: No se pudo convertir a la codificación de impresión \"%s\""
+
+#: hardcopy.c:3285
+msgid "Sending to printer..."
+msgstr "Enviando a la impresora..."
+
+#: hardcopy.c:3289
+msgid "E365: Failed to print PostScript file"
+msgstr "E365: Falló la impresión del archivo PostScript"
+
+#: hardcopy.c:3291
+msgid "Print job sent."
+msgstr "Se ha enviado la tarea de impresión."
+
+#: if_cscope.c:77
+msgid "Add a new database"
+msgstr "Añadir una nueva base de datos"
+
+#: if_cscope.c:79
+msgid "Query for a pattern"
+msgstr "Petición de un patrón"
+
+#: if_cscope.c:81
+msgid "Show this message"
+msgstr "Mostrar este mensaje"
+
+#: if_cscope.c:83
+msgid "Kill a connection"
+msgstr "Matar una conexión"
+
+#: if_cscope.c:85
+msgid "Reinit all connections"
+msgstr "Reiniciar todas las conexiones"
+
+#: if_cscope.c:87
+msgid "Show connections"
+msgstr "Mostrar las conexiones"
+
+#: if_cscope.c:95
+#, c-format
+msgid "E560: Usage: cs[cope] %s"
+msgstr "E560: Forma de uso: cs[cope] %s"
+
+#: if_cscope.c:236
+msgid "This cscope command does not support splitting the window.\n"
+msgstr "Esta orden \"cscope\" no admite la división de la ventana.\n"
+
+#: if_cscope.c:287
+msgid "E562: Usage: cstag <ident>"
+msgstr "E562: Forma de uso: cstag <identificador>"
+
+#: if_cscope.c:345
+msgid "E257: cstag: tag not found"
+msgstr "E257: cstag: no se encontró la etiqueta"
+
+#: if_cscope.c:515
+#, c-format
+msgid "E563: stat(%s) error: %d"
+msgstr "E563: Error en stat(%s): %d"
+
+#: if_cscope.c:525
+msgid "E563: stat error"
+msgstr "E563: error en la función \"stat\""
+
+#: if_cscope.c:622
+#, c-format
+msgid "E564: %s is not a directory or a valid cscope database"
+msgstr "E564: \"%s\" no es un directorio ni una base de datos válida de cscope"
+
+#: if_cscope.c:640
+#, c-format
+msgid "Added cscope database %s"
+msgstr "Se ha añadido la base de datos \"cscope\" %s"
+
+#: if_cscope.c:695
+#, c-format
+msgid "E262: error reading cscope connection %ld"
+msgstr "E262: Error al leer la conexión %ld con \"cscope\""
+
+#: if_cscope.c:802
+msgid "E561: unknown cscope search type"
+msgstr "E561: Tipo de búsqueda desconocido para \"cscope\""
+
+#: if_cscope.c:866 if_cscope.c:905
+msgid "E566: Could not create cscope pipes"
+msgstr "E566: Falló la conexión \"pipe\" para comunicarse con \"cscope\""
+
+#: if_cscope.c:882
+msgid "E622: Could not fork for cscope"
+msgstr ""
+"E622: No se pudo crear un nuevo proceso (\"fork\") para usar \"cscope\""
+
+#: if_cscope.c:992 if_cscope.c:1029
+msgid "cs_create_connection exec failed"
+msgstr "Falló la ejecución de \"cs_create_connection\""
+
+#: if_cscope.c:1002 if_cscope.c:1042
+msgid "cs_create_connection: fdopen for to_fp failed"
+msgstr "\"cs_create_connection\": Falló \"fdopen\" para \"to_fp\""
+
+#: if_cscope.c:1004 if_cscope.c:1046
+msgid "cs_create_connection: fdopen for fr_fp failed"
+msgstr "\"cs_create_connection\": Falló \"fdopen\" para \"fr_fp\""
+
+#: if_cscope.c:1030
+msgid "E623: Could not spawn cscope process"
+msgstr "E623: No se pudo crear un nuevo proceso (\"spawn\") de \"cscope\""
+
+#: if_cscope.c:1074
+msgid "E567: no cscope connections"
+msgstr "E567: No hay conexiones con \"cscope\""
+
+#: if_cscope.c:1154
+#, c-format
+msgid "E259: no matches found for cscope query %s of %s"
+msgstr ""
+"E259: No se encontraron coincidencias para la búsqueda \"cscope\" %s de %s"
+
+#: if_cscope.c:1215
+#, c-format
+msgid "E469: invalid cscopequickfix flag %c for %c"
+msgstr "E469: La marca \"cscopequickfix\" %c para %c no es válida"
+
+#: if_cscope.c:1307
+msgid "cscope commands:\n"
+msgstr "órdenes de \"cscope\":\n"
+
+#: if_cscope.c:1316
+#, c-format
+msgid "%-5s: %s%*s (Usage: %s)"
+msgstr "%-5s: %s%*s (Modo de uso: %s)"
+
+#: if_cscope.c:1321
+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 assignments to\n"
+msgstr ""
+"\n"
+" c: Encontrar funciones que invocan esta función\n"
+" d: Encontrar funciones invocados por esta función\n"
+" e: Encontrar este patrón egrep\n"
+" f: Encontrar este archivo\n"
+" g: Encontrar esta definición\n"
+" i: Encontrar archivos #incluyendo este archivo\n"
+" s: Encontrar este símbolo de C\n"
+" t: Encontrar asignaciones a\n"
+
+#: if_cscope.c:1409
+#, c-format
+msgid "E625: cannot open cscope database: %s"
+msgstr "E625: No se pudo abrir la base de datos \"cscope\": %s"
+
+#: if_cscope.c:1427
+msgid "E626: cannot get cscope database information"
+msgstr ""
+"E626: No se pudo obtener información acerca de la base de datos \"cscope\""
+
+#: if_cscope.c:1452
+msgid "E568: duplicate cscope database not added"
+msgstr "E568: Intentó añadir una base de datos de \"cscope\" duplicada"
+
+#: if_cscope.c:1597
+#, c-format
+msgid "E261: cscope connection %s not found"
+msgstr "E261: No se ha encontrado la conexión \"cscope\" %s"
+
+#: if_cscope.c:1631
+#, c-format
+msgid "cscope connection %s closed"
+msgstr "Conexión \"cscope\" %s cerrada"
+
+# should not reach here
+#. should not reach here
+#: if_cscope.c:1771
+msgid "E570: fatal error in cs_manage_matches"
+msgstr "E570: Error fatal en \"cs_manage_matches\""
+
+#: if_cscope.c:2033
+#, c-format
+msgid "Cscope tag: %s"
+msgstr "Etiqueta de \"cscope\": %s"
+
+#: if_cscope.c:2055
+msgid ""
+"\n"
+" # line"
+msgstr ""
+"\n"
+" # línea"
+
+#: if_cscope.c:2057
+msgid "filename / context / line\n"
+msgstr "nombre del archivo / contexto / línea\n"
+
+#: if_cscope.c:2169
+#, c-format
+msgid "E609: Cscope error: %s"
+msgstr "E609: Error de \"cscope\": %s"
+
+#: if_cscope.c:2438
+msgid "All cscope databases reset"
+msgstr "Se han vaciado todas las bases de datos de \"cscope\""
+
+#: if_cscope.c:2505
+msgid "no cscope connections\n"
+msgstr "no hay conexiones \"cscope\"\n"
+
+#: if_cscope.c:2509
+msgid " # pid database name prepend path\n"
+msgstr " nº pid base de datos prefijo ruta\n"
+
+#: if_mzsch.c:1045
+msgid ""
+"E815: Sorry, this command is disabled, the MzScheme libraries could not be "
+"loaded."
+msgstr ""
+"E815: Lo siento, esta orden está desactivada, no se pudo cargar las "
+"bibliotecas de MzScheme"
+
+#: if_mzsch.c:1469 if_python.c:1271 if_tcl.c:1404
+msgid "invalid expression"
+msgstr "expresión no válida"
+
+#: if_mzsch.c:1477 if_python.c:1290 if_tcl.c:1409
+msgid "expressions disabled at compile time"
+msgstr "expresiones desactivadas al compilar"
+
+#: if_mzsch.c:1566
+msgid "hidden option"
+msgstr "opción oculta"
+
+#: if_mzsch.c:1568 if_tcl.c:501
+msgid "unknown option"
+msgstr "opción desconocida"
+
+#: if_mzsch.c:1727
+msgid "window index is out of range"
+msgstr "indice de ventana fuera del rango"
+
+#: if_mzsch.c:1887
+msgid "couldn't open buffer"
+msgstr "No se pudo abrir el búfer"
+
+#: if_mzsch.c:2167 if_mzsch.c:2197 if_mzsch.c:2294 if_mzsch.c:2358
+#: if_mzsch.c:2479 if_mzsch.c:2536 if_python.c:2508 if_python.c:2542
+#: if_python.c:2601 if_python.c:2668 if_python.c:2790 if_python.c:2842
+#: if_tcl.c:684 if_tcl.c:729 if_tcl.c:803 if_tcl.c:875 if_tcl.c:2017
+msgid "cannot save undo information"
+msgstr "No se pudo guardar la información para deshacer"
+
+#: if_mzsch.c:2172 if_mzsch.c:2302 if_mzsch.c:2372 if_python.c:2510
+#: if_python.c:2608 if_python.c:2679
+msgid "cannot delete line"
+msgstr "no puedo suprimir la línea"
+
+#: if_mzsch.c:2203 if_mzsch.c:2387 if_python.c:2547 if_python.c:2695
+#: if_tcl.c:690 if_tcl.c:2039
+msgid "cannot replace line"
+msgstr "no se pudo reemplazar la línea"
+
+#: if_mzsch.c:2402 if_mzsch.c:2485 if_mzsch.c:2546 if_python.c:2713
+#: if_python.c:2792 if_python.c:2850
+msgid "cannot insert line"
+msgstr "no se pudo insertar la línea"
+
+#: if_mzsch.c:2637 if_python.c:2962
+msgid "string cannot contain newlines"
+msgstr "La cadena no puede contener quiebres de línea"
+
+#: if_mzsch.c:2859
+msgid "Vim error: ~a"
+msgstr "Error de Vim: ~a"
+
+#: if_mzsch.c:2892
+msgid "Vim error"
+msgstr "Error de Vim"
+
+#: if_mzsch.c:2958
+msgid "buffer is invalid"
+msgstr "El búfer no es valido"
+
+#: if_mzsch.c:2967
+msgid "window is invalid"
+msgstr "La ventana no es válida"
+
+#: if_mzsch.c:2987
+msgid "linenr out of range"
+msgstr "El número de la línea está fuera del rango"
+
+#: if_mzsch.c:3138 if_mzsch.c:3180
+msgid "not allowed in the Vim sandbox"
+msgstr "No permitido en la \"sandbox\" de vim"
+
+#: if_python.c:517
+msgid ""
+"E263: Sorry, this command is disabled, the Python library could not be "
+"loaded."
+msgstr ""
+"E263: Lo siento, esta orden está desactivada, no se pudo cargar la \n"
+"biblioteca de Python"
+
+#: if_python.c:583
+msgid "E659: Cannot invoke Python recursively"
+msgstr "E659: No se pudo invocar a Python recursivamente"
+
+#: if_python.c:776
+msgid "can't delete OutputObject attributes"
+msgstr "No se pueden borrar los atributos de \"OutputObject\""
+
+#: if_python.c:783
+msgid "softspace must be an integer"
+msgstr "\"softspace\" debe ser un entero"
+
+#: if_python.c:791
+msgid "invalid attribute"
+msgstr "Atributo no válido"
+
+#: if_python.c:830 if_python.c:844
+msgid "writelines() requires list of strings"
+msgstr "\"writelines()\" requiere una lista de cadenas"
+
+#: if_python.c:970
+msgid "E264: Python: Error initialising I/O objects"
+msgstr "E264: Python: error de iniciación de los objetos de I/O"
+
+#: if_python.c:1303
+msgid "attempt to refer to deleted buffer"
+msgstr "Intento de referirse a un búfer suprimido"
+
+#: if_python.c:1318 if_python.c:1359 if_python.c:1423 if_tcl.c:1216
+msgid "line number out of range"
+msgstr "El número de la línea está fuera del rango"
+
+#: if_python.c:1558
+#, c-format
+msgid "<buffer object (deleted) at %p>"
+msgstr "<objeto de búfer (suprimido) en %p>"
+
+#: if_python.c:1649 if_tcl.c:836
+msgid "invalid mark name"
+msgstr "Nombre de marca no válido"
+
+#: if_python.c:1927
+msgid "no such buffer"
+msgstr "No existe tal búfer"
+
+#: if_python.c:2015
+msgid "attempt to refer to deleted window"
+msgstr "Intento de referirse a una ventana suprimida"
+
+#: if_python.c:2060
+msgid "readonly attribute"
+msgstr "Atributo de solo lectura"
+
+#: if_python.c:2074
+msgid "cursor position outside buffer"
+msgstr "Posición del cursor fuera del búfer"
+
+#: if_python.c:2157
+#, c-format
+msgid "<window object (deleted) at %p>"
+msgstr "<objeto ventana (suprimido) en %p>"
+
+#: if_python.c:2169
+#, c-format
+msgid "<window object (unknown) at %p>"
+msgstr "<objeto ventana (desconocido) en %p>"
+
+#: if_python.c:2172
+#, c-format
+msgid "<window %d>"
+msgstr "<ventana %d>"
+
+#: if_python.c:2246
+msgid "no such window"
+msgstr "No existe tal ventana"
+
+#: if_ruby.c:365
+msgid "E265: $_ must be an instance of String"
+msgstr "E265: $_ debe ser una instancia de \"String\""
+
+#: if_ruby.c:426
+msgid ""
+"E266: Sorry, this command is disabled, the Ruby library could not be loaded."
+msgstr ""
+"E266: Lo siento, esta orden está desactivada, no se pudo cargar\n"
+"la biblioteca de Ruby"
+
+#: if_ruby.c:455
+msgid "E267: unexpected return"
+msgstr "E267: \"return\" inesperado"
+
+#: if_ruby.c:458
+msgid "E268: unexpected next"
+msgstr "E268: \"next\" inesperado"
+
+#: if_ruby.c:461
+msgid "E269: unexpected break"
+msgstr "E269: \"break\" inesperado"
+
+#: if_ruby.c:464
+msgid "E270: unexpected redo"
+msgstr "E270: \"redo\" inesperado"
+
+#: if_ruby.c:467
+msgid "E271: retry outside of rescue clause"
+msgstr "E271: \"retry\" fuera de una cláusula \"rescue\""
+
+#: if_ruby.c:474
+msgid "E272: unhandled exception"
+msgstr "E272: excepción sin manejar"
+
+#: if_ruby.c:489
+#, c-format
+msgid "E273: unknown longjmp status %d"
+msgstr "E273: El estado %d de \"longjmp\" es desconocido"
+
+#: if_sniff.c:64
+msgid "Toggle implementation/definition"
+msgstr "Intercambiar implementación/definición"
+
+#: if_sniff.c:65
+msgid "Show base class of"
+msgstr "Mostrar la clase base de"
+
+#: if_sniff.c:66
+msgid "Show overridden member function"
+msgstr "Mostrar la función miembro que se ha sobrepasado con el código nuevo"
+
+#: if_sniff.c:67
+msgid "Retrieve from file"
+msgstr "Restaurar del archivo"
+
+#: if_sniff.c:68
+msgid "Retrieve from project"
+msgstr "Restaurar del proyecto"
+
+#: if_sniff.c:70
+msgid "Retrieve from all projects"
+msgstr "Restaurar de todos los proyectos"
+
+#: if_sniff.c:71
+msgid "Retrieve"
+msgstr "Restaurar"
+
+#: if_sniff.c:72
+msgid "Show source of"
+msgstr "Mostrar el origen de "
+
+#: if_sniff.c:73
+msgid "Find symbol"
+msgstr "Buscar símbolo"
+
+#: if_sniff.c:74
+msgid "Browse class"
+msgstr "Navegador de Clases"
+
+#: if_sniff.c:75
+msgid "Show class in hierarchy"
+msgstr "Mostrar la clase en su jerarquía"
+
+#: if_sniff.c:76
+msgid "Show class in restricted hierarchy"
+msgstr "Mostrar la clase en jerarquía restringida"
+
+#: if_sniff.c:77
+msgid "Xref refers to"
+msgstr "Xref se refiere a"
+
+#: if_sniff.c:78
+msgid "Xref referred by"
+msgstr "Xref referida por"
+
+#: if_sniff.c:79
+msgid "Xref has a"
+msgstr "Xref tiene un"
+
+#: if_sniff.c:80
+msgid "Xref used by"
+msgstr "Xref usada por"
+
+#: if_sniff.c:81
+msgid "Show docu of"
+msgstr "Mostrar \"docu\" de"
+
+#: if_sniff.c:82
+msgid "Generate docu for"
+msgstr "Generar \"docu\" de"
+
+#: if_sniff.c:94
+msgid ""
+"Cannot connect to SNiFF+. Check environment (sniffemacs must be found in "
+"$PATH).\n"
+msgstr ""
+"No se pudo conectar a SNiFF+. Verifique el entorno (\"sniffemacs\" debe\n"
+"estar en \"$PATH\").\n"
+
+#: if_sniff.c:422
+msgid "E274: Sniff: Error during read. Disconnected"
+msgstr "E274: Sniff: Error al leer. Desconectado"
+
+#: if_sniff.c:550
+msgid "SNiFF+ is currently "
+msgstr "SNiFF+ está actualmente "
+
+#: if_sniff.c:552
+msgid "not "
+msgstr "no "
+
+#: if_sniff.c:553
+msgid "connected"
+msgstr "conectado"
+
+#: if_sniff.c:589
+#, c-format
+msgid "E275: Unknown SNiFF+ request: %s"
+msgstr "E275: Petición de SNiFF+ desconocida: %s"
+
+#: if_sniff.c:602
+msgid "E276: Error connecting to SNiFF+"
+msgstr "E276: Error al conectarme a SNiFF+"
+
+#: if_sniff.c:1013
+msgid "E278: SNiFF+ not connected"
+msgstr "E278: SNiFF+ no está conectado"
+
+#: if_sniff.c:1022
+msgid "E279: Not a SNiFF+ buffer"
+msgstr "E279: No es un búfer de SNiFF+"
+
+#: if_sniff.c:1089
+msgid "Sniff: Error during write. Disconnected"
+msgstr "Sniff: error al escribir. Desconectado"
+
+#: if_tcl.c:419
+msgid "invalid buffer number"
+msgstr "Número de búfer no válido"
+
+#: if_tcl.c:465 if_tcl.c:935 if_tcl.c:1115
+msgid "not implemented yet"
+msgstr "Aún no implementado"
+
+# ???
+#. ???
+#: if_tcl.c:774
+msgid "cannot set line(s)"
+msgstr "No se puede(n) definir la/s línea/s"
+
+#: if_tcl.c:845
+msgid "mark not set"
+msgstr "Marca sin definir"
+
+#: if_tcl.c:852 if_tcl.c:1071
+#, c-format
+msgid "row %d column %d"
+msgstr "fila %d columna %d"
+
+#: if_tcl.c:884
+msgid "cannot insert/append line"
+msgstr "No se puede insertar/añadir línea"
+
+#: if_tcl.c:1270
+msgid "unknown flag: "
+msgstr "Indicador desconocido: "
+
+#: if_tcl.c:1340
+msgid "unknown vimOption"
+msgstr "\"vimOption\" desconocida"
+
+#: if_tcl.c:1425
+msgid "keyboard interrupt"
+msgstr "Interrupción desde el teclado"
+
+#: if_tcl.c:1430
+msgid "vim error"
+msgstr "Error de Vim"
+
+#: if_tcl.c:1474
+msgid "cannot create buffer/window command: object is being deleted"
+msgstr "No se pudo crear la orden de búfer/ventana: el objeto se suprimirá"
+
+#: if_tcl.c:1550
+msgid ""
+"cannot register callback command: buffer/window is already being deleted"
+msgstr ""
+"No se pudo registrar el orden \"callback\": El búfer o la ventana ya se \n"
+"eliminó"
+
+# This should never happen. Famous last word?
+#. This should never happen. Famous last word?
+#: if_tcl.c:1569
+msgid ""
+"E280: TCL FATAL ERROR: reflist corrupt!? Please report this to vim-dev@vim."
+"org"
+msgstr ""
+"E280: ERROR FATAL DE TCL: ¿¡\"reflist\" dañada!? Por favor, informe de \n"
+"esto a vim-dev@vim.org"
+
+#: if_tcl.c:1570
+msgid "cannot register callback command: buffer/window reference not found"
+msgstr ""
+"No se pudo registrar la orden de retorno de llamada: No se pudo encontrar\n"
+"la referencia al búfer o la ventana"
+
+#: if_tcl.c:1742
+msgid ""
+"E571: Sorry, this command is disabled: the Tcl library could not be loaded."
+msgstr ""
+"E571: Lo siento, esta orden está desactivada pues no se pudo\n"
+"cargar la biblioteca de Tcl"
+
+#: if_tcl.c:1904
+msgid ""
+"E281: TCL ERROR: exit code is not int!? Please report this to vim-dev@vim.org"
+msgstr ""
+"E281: ERROR DE TCL: ¿¡el código de salida no es \"int\"!? Por favor\n"
+"informe a vim-dev@vim.org"
+
+#: if_tcl.c:1909
+#, c-format
+msgid "E572: exit code %d"
+msgstr "E572: código de salida %d"
+
+#: if_tcl.c:2025
+msgid "cannot get line"
+msgstr "No puedo obtener la línea"
+
+#: if_xcmdsrv.c:233
+msgid "Unable to register a command server name"
+msgstr "Incapaz de registrar un nombre de servidor de órdenes"
+
+#: if_xcmdsrv.c:492
+msgid "E248: Failed to send command to the destination program"
+msgstr "E248: No pude enviar la orden al programa de destino"
+
+#: if_xcmdsrv.c:765
+#, c-format
+msgid "E573: Invalid server id used: %s"
+msgstr "E573: El ID de usuario no es válido en el servidor: %s"
+
+#: if_xcmdsrv.c:1146
+msgid "E251: VIM instance registry property is badly formed. Deleted!"
+msgstr "E251: La propiedad de registro de VIM es incorrecta. ¡Eliminada!"
+
+#: main.c:138
+msgid "Unknown option argument"
+msgstr "Opción de argumento desconocida"
+
+#: main.c:140
+msgid "Too many edit arguments"
+msgstr "Demasiados argumentos de edición"
+
+#: main.c:142
+msgid "Argument missing after"
+msgstr "Falta el argumento después de"
+
+#: main.c:144
+msgid "Garbage after option argument"
+msgstr "Basura después de la opción"
+
+#: main.c:146
+msgid "Too many \"+command\", \"-c command\" or \"--cmd command\" arguments"
+msgstr ""
+"Demasiados argumentos tales como: \"+orden\", \"-c orden\" \n"
+"o \"--cmd orden\""
+
+#: main.c:148
+msgid "Invalid argument for"
+msgstr "Argumento no válido para"
+
+#: main.c:514
+#, c-format
+msgid "%d files to edit\n"
+msgstr "%d archivos que editar\n"
+
+#: main.c:1510
+msgid "This Vim was not compiled with the diff feature."
+msgstr "Este Vim no se ha compilado con la opción \"diff\""
+
+#: main.c:1612
+msgid "'-nb' cannot be used: not enabled at compile time\n"
+msgstr "'-nb' no se puede usar: no se ha activado al compilar\n"
+
+#: main.c:2135
+msgid "Attempt to open script file again: \""
+msgstr "Intento de abrir de nuevo el archivo de órdenes: \""
+
+#: main.c:2144
+msgid "Cannot open for reading: \""
+msgstr "No se pudo abrir para leer: \""
+
+#: main.c:2198
+msgid "Cannot open for script output: \""
+msgstr "No se pudo abrir para escribir la salida del archivo de órdenes: \""
+
+#: main.c:2364
+msgid "Vim: Error: Failure to start gvim from NetBeans\n"
+msgstr "Vim: Error: Imposible iniciar gvim para NetBeans\n"
+
+#: main.c:2369
+msgid "Vim: Warning: Output is not to a terminal\n"
+msgstr "Vim: Advertencia: la salida no es un terminal\n"
+
+#: main.c:2371
+msgid "Vim: Warning: Input is not from a terminal\n"
+msgstr "Vim: Advertencia: la entrada no es desde un terminal\n"
+
+# just in case..
+#. just in case..
+#: main.c:2688
+msgid "pre-vimrc command line"
+msgstr "Línea de órdenes previa a \"vimrc\""
+
+#: main.c:2785
+#, c-format
+msgid "E282: Cannot read from \"%s\""
+msgstr "E282: No se pudo leer desde \"%s\""
+
+#: main.c:3002
+msgid ""
+"\n"
+"More info with: \"vim -h\"\n"
+msgstr ""
+"\n"
+"Más información con: \"vim -h\"\n"
+
+#: main.c:3035
+msgid "[file ..] edit specified file(s)"
+msgstr "[archivo ..] Editar el/los archivos/s especificado/s"
+
+#: main.c:3036
+msgid "- read text from stdin"
+msgstr "- Leer texto de la entrada estándar"
+
+#: main.c:3037
+msgid "-t tag edit file where tag is defined"
+msgstr "-t etiqueta Editar el archivo donde está definida la etiqueta"
+
+#: main.c:3039
+msgid "-q [errorfile] edit file with first error"
+msgstr "-q [fich. err.] Editar el archivo con el primer error"
+
+#: main.c:3048
+msgid ""
+"\n"
+"\n"
+"usage:"
+msgstr ""
+"\n"
+"\n"
+"Uso:"
+
+#: main.c:3051
+msgid " vim [arguments] "
+msgstr " vim [argumentos]"
+
+#: main.c:3055
+msgid ""
+"\n"
+" or:"
+msgstr ""
+"\n"
+" o:"
+
+#: main.c:3058
+msgid ""
+"\n"
+"Where case is ignored prepend / to make flag upper case"
+msgstr ""
+"\n"
+"Cuando mayúscula y minúscula son ignoradas añada \"/\" para \n"
+"cambiar la marca (\"flag\") a mayúscula"
+
+#: main.c:3061
+msgid ""
+"\n"
+"\n"
+"Arguments:\n"
+msgstr ""
+"\n"
+"\n"
+"Argumentos:\n"
+
+#: main.c:3062
+msgid "--\t\t\tOnly file names after this"
+msgstr "--\t\t\tSolo nombres de archivos a partir de aquí"
+
+#: main.c:3064
+msgid "--literal\t\tDon't expand wildcards"
+msgstr "--literal\t\tNo expandir comodines"
+
+#: main.c:3067
+msgid "-register\t\tRegister this gvim for OLE"
+msgstr "-register\t\tRegistrar este \"gvim\" para \"OLE\""
+
+#: main.c:3068
+msgid "-unregister\t\tUnregister gvim for OLE"
+msgstr "-unregister\t\tSuprimir el registro de \"gvim\" para \"OLE\""
+
+#: main.c:3071
+msgid "-g\t\t\tRun using GUI (like \"gvim\")"
+msgstr "-g\t\t\tEjecutar usando el GUI (como \"gvim\")"
+
+#: main.c:3072
+msgid "-f or --nofork\tForeground: Don't fork when starting GUI"
+msgstr ""
+"-f o --nofork\tPrimer plano: No separarse (\"fork\") cuando se\n"
+" \tinicia la interfaz gráfica (GUI)"
+
+#: main.c:3074
+msgid "-v\t\t\tVi mode (like \"vi\")"
+msgstr "-v\t\t\tModo vi"
+
+#: main.c:3075
+msgid "-e\t\t\tEx mode (like \"ex\")"
+msgstr "-e\t\t\tModo ex"
+
+#: main.c:3076
+msgid "-s\t\t\tSilent (batch) mode (only for \"ex\")"
+msgstr "-s\t\t\tModo silencioso de ejecución por lotes (\"ex\")"
+
+#: main.c:3078
+msgid "-d\t\t\tDiff mode (like \"vimdiff\")"
+msgstr "-d\t\t\tModo de diferencias (como \"vimdiff\")"
+
+#: main.c:3080
+msgid "-y\t\t\tEasy mode (like \"evim\", modeless)"
+msgstr "-y\t\t\tModo fácil (como \"evim\", sin modo)"
+
+#: main.c:3081
+msgid "-R\t\t\tReadonly mode (like \"view\")"
+msgstr "-R\t\t\tModo de solo lectura (como \"view\")"
+
+#: main.c:3082
+msgid "-Z\t\t\tRestricted mode (like \"rvim\")"
+msgstr "-Z\t\t\tModo restringido (como \"rvim\")"
+
+#: main.c:3083
+msgid "-m\t\t\tModifications (writing files) not allowed"
+msgstr "-m\t\t\tModificación de archivos desactivada"
+
+#: main.c:3084
+msgid "-M\t\t\tModifications in text not allowed"
+msgstr "-M\t\t\tModificación de texto desactivada"
+
+#: main.c:3085
+msgid "-b\t\t\tBinary mode"
+msgstr "-b\t\t\tModo binario"
+
+#: main.c:3087
+msgid "-l\t\t\tLisp mode"
+msgstr "-l\t\t\tModo LISP"
+
+#: main.c:3089
+msgid "-C\t\t\tCompatible with Vi: 'compatible'"
+msgstr "-C\t\t\tCompatible con vi: \"compatible\""
+
+#: main.c:3090
+msgid "-N\t\t\tNot fully Vi compatible: 'nocompatible'"
+msgstr "-N\t\t\tParcialmente compatible con vi: \"nocompatible\""
+
+#: main.c:3091
+msgid "-V[N][fname]\t\tBe verbose [level N] [log messages to fname]"
+msgstr ""
+"-V[N][nombre_archivo]\t\tCon verbosidad [nivel N] [guardar mensajes en "
+"nombre_archivo]"
+
+#: main.c:3093
+msgid "-D\t\t\tDebugging mode"
+msgstr "-D\t\t\tModo de depuración"
+
+#: main.c:3095
+msgid "-n\t\t\tNo swap file, use memory only"
+msgstr "-n\t\t\tSin archivo de intercambio, solo usa RAM"
+
+#: main.c:3096
+msgid "-r\t\t\tList swap files and exit"
+msgstr "-r\t\t\tDar una lista de los archivo de intercambio y salir"
+
+#: main.c:3097
+msgid "-r (with file name)\tRecover crashed session"
+msgstr "-r \"archivo\"\tRecuperar sesión fallida"
+
+#: main.c:3098
+msgid "-L\t\t\tSame as -r"
+msgstr "-L\t\t\tIgual que \"-r\""
+
+#: main.c:3100
+msgid "-f\t\t\tDon't use newcli to open window"
+msgstr "-f\t\t\tNo usar \"newcli\" para abrir ventanas"
+
+#: main.c:3101
+msgid "-dev <device>\t\tUse <device> for I/O"
+msgstr "-dev <dispositivo>\t\tUsar <dispositivo> para I/O"
+
+#: main.c:3104
+msgid "-A\t\t\tstart in Arabic mode"
+msgstr "-A\t\t\tIniciar en modo árabe"
+
+#: main.c:3107
+msgid "-H\t\t\tStart in Hebrew mode"
+msgstr "-H\t\t\tIniciar en modo hebreo"
+
+#: main.c:3110
+msgid "-F\t\t\tStart in Farsi mode"
+msgstr "-F\t\t\tIniciar en modo persa (farsi)"
+
+#: main.c:3112
+msgid "-T <terminal>\tSet terminal type to <terminal>"
+msgstr "-T <terminal>\tEstablecer el tipo de salida visual a <terminal>"
+
+#: main.c:3113
+msgid "-u <vimrc>\t\tUse <vimrc> instead of any .vimrc"
+msgstr "-u <vimrc>\t\tUsar <vimrc> en lugar de cualquier \".vimrc\""
+
+#: main.c:3115
+msgid "-U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc"
+msgstr "-U <gvimrc>\t\tUsar <gvimrc> en lugar de otro \".gvimrc\""
+
+#: main.c:3117
+msgid "--noplugin\t\tDon't load plugin scripts"
+msgstr "--noplugin\t\tNo cargar los módulos de expansión"
+
+#: main.c:3119
+msgid "-p[N]\t\tOpen N tab pages (default: one for each file)"
+msgstr "-p[N]\t\tAbrir N ventanas (valor predeterminado: una por archivo)"
+
+#: main.c:3120
+msgid "-o[N]\t\tOpen N windows (default: one for each file)"
+msgstr "-o[N]\t\tAbrir N ventanas (valor predeterminado: una por archivo)"
+
+#: main.c:3121
+msgid "-O[N]\t\tLike -o but split vertically"
+msgstr "-O[N]\t\tComo \"-o\" pero divide las ventanas verticalmente"
+
+#: main.c:3123
+msgid "+\t\t\tStart at end of file"
+msgstr "+\t\t\tComenzar al final del archivo"
+
+#: main.c:3124
+msgid "+<lnum>\t\tStart at line <lnum>"
+msgstr "+<número_de_línea>\tComienza en la línea <número_de_línea>"
+
+#: main.c:3125
+msgid "--cmd <command>\tExecute <command> before loading any vimrc file"
+msgstr "--cmd <orden>\tEjecutar la <orden> antes de cargar algún archivo vimrc"
+
+#: main.c:3126
+msgid "-c <command>\t\tExecute <command> after loading the first file"
+msgstr "-c <orden>\t\tEjecutar <orden> después de cargar el primer archivo"
+
+#: main.c:3127
+msgid "-S <session>\t\tSource file <session> after loading the first file"
+msgstr ""
+"-S <sesión>\t\tEjecutar las órdenes del archivo <sesión> después\n"
+" \t\tde cargar el primer archivo"
+
+#: main.c:3128
+msgid "-s <scriptin>\tRead Normal mode commands from file <scriptin>"
+msgstr ""
+"-s <scriptin>\tLeer las órdenes en modo Normal del archivo\n"
+" \t\"módulo de expansión\" de entrada>"
+
+#: main.c:3129
+msgid "-w <scriptout>\tAppend all typed commands to file <scriptout>"
+msgstr ""
+"-w <scriptout>\tAñadir todas las órdenes escritas al archivo\n"
+" \t\"módulo de expansión\" de salida"
+
+#: main.c:3130
+msgid "-W <scriptout>\tWrite all typed commands to file <scriptout>"
+msgstr ""
+"-W <scriptout>\tGrabar todas las órdenes escritas al archivo\n"
+" \t\"módulo de expansión\" de salida"
+
+#: main.c:3132
+msgid "-x\t\t\tEdit encrypted files"
+msgstr "-x\t\t\tEditar archivos cifrados"
+
+#: main.c:3136
+msgid "-display <display>\tConnect vim to this particular X-server"
+msgstr "-display <pantalla>\tConectar vim a este servidor X en particular"
+
+#: main.c:3138
+msgid "-X\t\t\tDo not connect to X server"
+msgstr "-X\t\t\tEvitar la conexión al servidor X"
+
+#: main.c:3141
+msgid "--remote <files>\tEdit <files> in a Vim server if possible"
+msgstr ""
+"--remote <archivos>\tEditar <archivos> en un servidor Vim si es posible"
+
+#: main.c:3142
+msgid "--remote-silent <files> Same, don't complain if there is no server"
+msgstr ""
+"--remote-silent \"archivos\"\tLo mismo pero no se queja si no existe un\n"
+" \tservidor disponible"
+
+#: main.c:3143
+msgid ""
+"--remote-wait <files> As --remote but wait for files to have been edited"
+msgstr ""
+"--remote-wait \"archivos\"\tComo --remote pero espera a que los archivos\n"
+" \tterminen de editarse"
+
+#: main.c:3144
+msgid ""
+"--remote-wait-silent <files> Same, don't complain if there is no server"
+msgstr ""
+"--remote-wait-silent \"archivos\"\tLo mismo pero no se queja si no hay un\n"
+" \tservidor disponible"
+
+#: main.c:3146
+msgid ""
+"--remote-tab[-wait][-silent] <files> As --remote but use tab page per file"
+msgstr ""
+"--remote-tab[-wait][-silent] <archivos> Como \"--remote\" pero usa una "
+"pestaña por página"
+
+#: main.c:3148
+msgid "--remote-send <keys>\tSend <keys> to a Vim server and exit"
+msgstr "--remote-send <teclas>\tEnvíar <teclas> a un servidor Vim y cerrar"
+
+#: main.c:3149
+msgid "--remote-expr <expr>\tEvaluate <expr> in a Vim server and print result"
+msgstr ""
+"--remote-expr <expr>\tEvaluar <expr> en un servidor Vim e imprimir el "
+"resultado"
+
+#: main.c:3150
+msgid "--serverlist\t\tList available Vim server names and exit"
+msgstr ""
+"--serverlist\t\tEmitir una lista de los servidores Vim disponibles y cerrar"
+
+#: main.c:3151
+msgid "--servername <name>\tSend to/become the Vim server <name>"
+msgstr ""
+"--servername \"nombre\"\tEnvíar a/se convierte en el servidor Vim con <nombre>"
+
+#: main.c:3154
+msgid "--startuptime <file>\tWrite startup timing messages to <file>"
+msgstr "-- startuptime <archivo>\tGuardar los mensajes de tiempo de inicio "
+"a <archivo>."
+
+#: main.c:3157
+msgid "-i <viminfo>\t\tUse <viminfo> instead of .viminfo"
+msgstr "-i <viminfo>\t\tUsar <viminfo> en lugar de \".viminfo\""
+
+#: main.c:3159
+msgid "-h or --help\tPrint Help (this message) and exit"
+msgstr "-h or --help\tImpresión de la ayuda (este mensaje) y cerrar"
+
+#: main.c:3160
+msgid "--version\t\tPrint version information and exit"
+msgstr "--version\t\tImpresión de la información de versión y cerrar"
+
+#: main.c:3164
+msgid ""
+"\n"
+"Arguments recognised by gvim (Motif version):\n"
+msgstr ""
+"\n"
+"Argumentos reconocidos por gvim (versión Motif):\n"
+
+#: main.c:3168
+msgid ""
+"\n"
+"Arguments recognised by gvim (neXtaw version):\n"
+msgstr ""
+"\n"
+"Argumentos reconocidos por gvim (versión neXtaw):\n"
+
+#: main.c:3170
+msgid ""
+"\n"
+"Arguments recognised by gvim (Athena version):\n"
+msgstr ""
+"\n"
+"Argumentos reconocidos por gvim (versión Athena):\n"
+
+#: main.c:3174
+msgid "-display <display>\tRun vim on <display>"
+msgstr "-display <pantalla>\tEjecuta vim en <pantalla>"
+
+#: main.c:3175
+msgid "-iconic\t\tStart vim iconified"
+msgstr "-iconic\t\tArranca vim \"iconizado\""
+
+#: main.c:3177
+msgid "-name <name>\t\tUse resource as if vim was <name>"
+msgstr "-name <nombre>\t\tUsa un recurso como si vim fuese <nombre>"
+
+#: main.c:3178
+msgid "\t\t\t (Unimplemented)\n"
+msgstr "\t\t\t (Sin implementar)\n"
+
+#: main.c:3180
+msgid "-background <color>\tUse <color> for the background (also: -bg)"
+msgstr "-background <color>\tUsa <color> para el fondo (también: -bg)"
+
+#: main.c:3181
+msgid "-foreground <color>\tUse <color> for normal text (also: -fg)"
+msgstr "-foreground <color>\tUsa <color> para el texto normal (también: -fg)"
+
+#: main.c:3182 main.c:3202
+msgid "-font <font>\t\tUse <font> for normal text (also: -fn)"
+msgstr ""
+"-font <tipo>\t\tUse <tipo de letra de impresión> para el texto normal\n"
+"(también: -fn)"
+
+#: main.c:3183
+msgid "-boldfont <font>\tUse <font> for bold text"
+msgstr ""
+"-boldfont <tipo>\tUsa <tipo de letra de impresión> para texto en\n"
+"negrita"
+
+#: main.c:3184
+msgid "-italicfont <font>\tUse <font> for italic text"
+msgstr ""
+"-italicfont <tipo>\tUse <tipo de letra de impresión> para texto\n"
+"en cursiva"
+
+#: main.c:3185 main.c:3203
+msgid "-geometry <geom>\tUse <geom> for initial geometry (also: -geom)"
+msgstr ""
+"-geometry <geom>\tUse <geom> para la geometría inicial (también: -geom)"
+
+#: main.c:3186
+msgid "-borderwidth <width>\tUse a border width of <width> (also: -bw)"
+msgstr "-borderwidth <ancho>\tUsa un ancho de borde de <ancho> (también: -bw)"
+
+#: main.c:3187
+msgid "-scrollbarwidth <width> Use a scrollbar width of <width> (also: -sw)"
+msgstr ""
+"-scrollbarwidth <ancho>\tUsa una barra de desplazamiento de ancho <ancho>\n"
+" \t(también: -sw)"
+
+#: main.c:3189
+msgid "-menuheight <height>\tUse a menu bar height of <height> (also: -mh)"
+msgstr ""
+"-menuheight <alt>\tUsa una barra de menú de altura <alt> (también: -mh)"
+
+#: main.c:3191 main.c:3204
+msgid "-reverse\t\tUse reverse video (also: -rv)"
+msgstr "-reverse\t\tUsar vídeo inverso (también: -rv)"
+
+#: main.c:3192
+msgid "+reverse\t\tDon't use reverse video (also: +rv)"
+msgstr "+reverse\t\tNo usar vídeo inverso (también: +rv)"
+
+#: main.c:3193
+msgid "-xrm <resource>\tSet the specified resource"
+msgstr "-xrm <recurso>\tEstablece el recurso especificado"
+
+#: main.c:3196
+msgid ""
+"\n"
+"Arguments recognised by gvim (RISC OS version):\n"
+msgstr ""
+"\n"
+"Argumentos reconocidos por gvim (versión para RISC OS):\n"
+
+#: main.c:3197
+msgid "--columns <number>\tInitial width of window in columns"
+msgstr "--columns <número>\tAnchura inicial de la ventana, en columnas"
+
+#: main.c:3198
+msgid "--rows <number>\tInitial height of window in rows"
+msgstr "--rows <número>\tAltura inicial de la ventana, en filas"
+
+#: main.c:3201
+msgid ""
+"\n"
+"Arguments recognised by gvim (GTK+ version):\n"
+msgstr ""
+"\n"
+"Argumentos reconocidos por gvim (versión GTK+):\n"
+
+#: main.c:3205
+msgid "-display <display>\tRun vim on <display> (also: --display)"
+msgstr "-display <pantalla>\tEjecuta vim en <pantalla> (también: --display)"
+
+#: main.c:3207
+msgid "--role <role>\tSet a unique role to identify the main window"
+msgstr ""
+"--role <role>\tDefine un rol único para identificar la ventana principal"
+
+#: main.c:3209
+msgid "--socketid <xid>\tOpen Vim inside another GTK widget"
+msgstr "--socketid <xid>\tAbre a Vim dentro de otro \"widget\" GTK"
+
+#: main.c:3212
+msgid "-P <parent title>\tOpen Vim inside parent application"
+msgstr "-P <título ventana padre>\tAbrir a Vim dentro de la aplicación padre"
+
+#: main.c:3213
+msgid "--windowid <HWND>\tOpen Vim inside another win32 widget"
+msgstr "--windowid <HWND>\tAbrir Vim dentro de otro objeto de win32"
+
+#: main.c:3557
+msgid "No display"
+msgstr "No hay una ventana"
+
+# Failed to send, abort.
+#. Failed to send, abort.
+#: main.c:3572
+msgid ": Send failed.\n"
+msgstr ": Falló el envío.\n"
+
+# Let vim start normally.
+#. Let vim start normally.
+#: main.c:3578
+msgid ": Send failed. Trying to execute locally\n"
+msgstr ""
+": Falló el inicio de sesión remota (\"send\"). Intentado una\n"
+"ejecución local\n"
+
+#: main.c:3616 main.c:3637
+#, c-format
+msgid "%d of %d edited"
+msgstr "%d de %d editados"
+
+#: main.c:3659
+msgid "No display: Send expression failed.\n"
+msgstr "No hay una ventana en el destino: El envío de la expresión falló.\n"
+
+#: main.c:3671
+msgid ": Send expression failed.\n"
+msgstr ": Falló el envío de la expresión.\n"
+
+#: mark.c:761
+msgid "No marks set"
+msgstr "No se han fijado marcas"
+
+#: mark.c:763
+#, c-format
+msgid "E283: No marks matching \"%s\""
+msgstr "E283: No hay marcas que coincidan con %s"
+
+# Highlight title
+#. Highlight title
+#: mark.c:774
+msgid ""
+"\n"
+"mark line col file/text"
+msgstr ""
+"\n"
+"marca línea col archivo/texto"
+
+# Highlight title
+#. Highlight title
+#: mark.c:896
+msgid ""
+"\n"
+" jump line col file/text"
+msgstr ""
+"\n"
+" salto línea col archivo/texto"
+
+# Highlight title
+#. Highlight title
+#: mark.c:943
+msgid ""
+"\n"
+"change line col text"
+msgstr ""
+"\n"
+"cambio línea col archivo/texto"
+
+#: mark.c:1437
+#, c-format
+msgid ""
+"\n"
+"# File marks:\n"
+msgstr ""
+"\n"
+"# Marcas en el archivo:\n"
+
+# Write the jumplist with -'
+#. Write the jumplist with -'
+#: mark.c:1472
+#, c-format
+msgid ""
+"\n"
+"# Jumplist (newest first):\n"
+msgstr ""
+"\n"
+"# Lista de saltos (el más reciente va primero):\n"
+
+#: mark.c:1573
+#, c-format
+msgid ""
+"\n"
+"# History of marks within files (newest to oldest):\n"
+msgstr ""
+"\n"
+"# Historia de las marcas en los archivos (de la más reciente a la más "
+"antigua):\n"
+
+#: mark.c:1677
+msgid "Missing '>'"
+msgstr "Falta \">\""
+
+#: mbyte.c:532
+msgid "E543: Not a valid codepage"
+msgstr "E543: No es una página de código válida"
+
+#: mbyte.c:4852
+msgid "E284: Cannot set IC values"
+msgstr "E284: No se pudo fijar los valores IC"
+
+#: mbyte.c:5004
+msgid "E285: Failed to create input context"
+msgstr "E285: Falló la creación del contexto de entrada"
+
+#: mbyte.c:5162
+msgid "E286: Failed to open input method"
+msgstr "E286: Falló la apertura del método de entrada"
+
+#: mbyte.c:5175
+msgid "E287: Warning: Could not set destroy callback to IM"
+msgstr ""
+"E287: Advertencia: No pude crear una llamada de retorno\n"
+"de destrucción al IM"
+
+#: mbyte.c:5181
+msgid "E288: input method doesn't support any style"
+msgstr "E288: el método de entrada no admite ningún estilo"
+
+#: mbyte.c:5240
+msgid "E289: input method doesn't support my preedit type"
+msgstr "E289: El método de entrada no soporta mi tipo de pre-edición"
+
+#: mbyte.c:5316
+msgid "E290: over-the-spot style requires fontset"
+msgstr "E290: El estilo \"sobre el punto\" requiere del uso de un \"fontset\""
+
+#: mbyte.c:5352
+msgid "E291: Your GTK+ is older than 1.2.3. Status area disabled"
+msgstr ""
+"E291: Su versión de GTK+ es anterior a 1.2.3. Ãrea de estado\n"
+"desactivada"
+
+#: mbyte.c:5663
+msgid "E292: Input Method Server is not running"
+msgstr "E292: El servidor de método de entrada (IME) no está funcionando"
+
+#: memfile.c:501
+msgid "E293: block was not locked"
+msgstr "E293: El bloque no estaba asegurado"
+
+#: memfile.c:1044
+msgid "E294: Seek error in swap file read"
+msgstr "E294: Error de búsqueda al leer el archivo de intercambio"
+
+#: memfile.c:1049
+msgid "E295: Read error in swap file"
+msgstr "E295: Error de lectura en el archivo de intercambio"
+
+#: memfile.c:1101
+msgid "E296: Seek error in swap file write"
+msgstr "E296: Error de búsqueda al escribir en el archivo de intercambio"
+
+#: memfile.c:1119
+msgid "E297: Write error in swap file"
+msgstr "E297: Error de escritura en el archivo de intercambio"
+
+#: memfile.c:1316
+msgid "E300: Swap file already exists (symlink attack?)"
+msgstr ""
+"E300: Ya existe un archivo de intercambio (¿ataque de enlace simbólico?)"
+
+#: memline.c:312
+msgid "E298: Didn't get block nr 0?"
+msgstr "E298: ¿No se obtuvo el bloque Nº 0?"
+
+#: memline.c:359
+msgid "E298: Didn't get block nr 1?"
+msgstr "E298: ¿No se obtuvo el bloque Nº 1?"
+
+#: memline.c:377
+msgid "E298: Didn't get block nr 2?"
+msgstr "E298: ¿No se obtuvo el bloque Nº 2?"
+
+# could not (re)open the swap file, what can we do????
+#. could not (re)open the swap file, what can we do????
+#: memline.c:490
+msgid "E301: Oops, lost the swap file!!!"
+msgstr "E301: ¡¡¡Perdí el archivo de intercambio!!!"
+
+#: memline.c:502
+msgid "E302: Could not rename swap file"
+msgstr "E302: No pude cambiar el nombre del archivo de intercambio"
+
+#: memline.c:592
+#, 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"
+"recuperación imposible"
+
+#: memline.c:703
+msgid "E304: ml_upd_block0(): Didn't get block 0??"
+msgstr "E304: \"ml_upd_block0()\": ¿No se obtuvo el bloque 0?"
+
+#: memline.c:904
+#, c-format
+msgid "E305: No swap file found for %s"
+msgstr "E305: No se encontró el archivo de intercambio para %s"
+
+#: memline.c:914
+msgid "Enter number of swap file to use (0 to quit): "
+msgstr ""
+"Introduzca el número del archivo de intercambio a usar (0 para salir): "
+
+#: memline.c:959
+#, c-format
+msgid "E306: Cannot open %s"
+msgstr "E306: No se pudo abrir %s"
+
+#: memline.c:981
+msgid "Unable to read block 0 from "
+msgstr "Incapaz de leer el bloque 0 de "
+
+#: memline.c:984
+msgid ""
+"\n"
+"Maybe no changes were made or Vim did not update the swap file."
+msgstr ""
+"\n"
+"Tal vez no hay cambios o Vim no actualizó el archivo de intercambio."
+
+#: memline.c:994 memline.c:1011
+msgid " cannot be used with this version of Vim.\n"
+msgstr " no puede usarse con esta versión de Vim.\n"
+
+#: memline.c:996
+msgid "Use Vim version 3.0.\n"
+msgstr "Use la versión 3.0 de Vim.\n"
+
+#: memline.c:1002
+#, c-format
+msgid "E307: %s does not look like a Vim swap file"
+msgstr "E307: %s no parece un archivo de intercambio de Vim"
+
+#: memline.c:1015
+msgid " cannot be used on this computer.\n"
+msgstr "no puede usarse en este ordenador.\n"
+
+#: memline.c:1017
+msgid "The file was created on "
+msgstr "El archivo se creó el "
+
+#: memline.c:1021
+msgid ""
+",\n"
+"or the file has been damaged."
+msgstr ""
+",\n"
+"o el archivo se ha dañado"
+
+#: memline.c:1039
+msgid " has been damaged (page size is smaller than minimum value).\n"
+msgstr " se ha dañado (el tamaño de la página es menor al valor minimo).\n"
+
+#: memline.c:1071
+#, c-format
+msgid "Using swap file \"%s\""
+msgstr "Usando el archivo de intercambio \"%s\""
+
+#: memline.c:1077
+#, c-format
+msgid "Original file \"%s\""
+msgstr "Archivo original %s"
+
+#: memline.c:1090
+msgid "E308: Warning: Original file may have been changed"
+msgstr "E308: Advertencia: el archivo original puede haber cambiado"
+
+#: memline.c:1164
+#, c-format
+msgid "E309: Unable to read block 1 from %s"
+msgstr "E309: Incapaz de leer el bloque 1 de %s"
+
+#: memline.c:1168
+msgid "???MANY LINES MISSING"
+msgstr "???FALTAN MUCHAS LÃNEAS"
+
+#: memline.c:1184
+msgid "???LINE COUNT WRONG"
+msgstr "???RECUENTO DE LÃNEAS EQUIVOCADO"
+
+#: memline.c:1191
+msgid "???EMPTY BLOCK"
+msgstr "???BLOQUE VACÃO"
+
+#: memline.c:1217
+msgid "???LINES MISSING"
+msgstr "???FALTAN LÃNEAS"
+
+#: memline.c:1249
+#, c-format
+msgid "E310: Block 1 ID wrong (%s not a .swp file?)"
+msgstr "E310: El ID del bloque 1 es incorrecto (¿No es %s un archivo .swp?)"
+
+#: memline.c:1254
+msgid "???BLOCK MISSING"
+msgstr "???FALTA UN BLOQUE"
+
+#: memline.c:1270
+msgid "??? from here until ???END lines may be messed up"
+msgstr "??? desde aquí hasta ???FIN las líneas pueden estar desordenadas"
+
+#: memline.c:1286
+msgid "??? from here until ???END lines may have been inserted/deleted"
+msgstr ""
+"??? desde aquí hasta ???FIN las líneas pueden haber sido\n"
+"insertadas/borradas"
+
+#: memline.c:1306
+msgid "???END"
+msgstr "???FIN"
+
+#: memline.c:1333
+msgid "E311: Recovery Interrupted"
+msgstr "E311: Recuperación interrumpida"
+
+#: memline.c:1338
+msgid ""
+"E312: Errors detected while recovering; look for lines starting with ???"
+msgstr ""
+"E312: Se han detectado errores al recuperar; busque líneas que\n"
+"empiecen con ???"
+
+#: memline.c:1340
+msgid "See \":help E312\" for more information."
+msgstr "Vea \":help E312\" para más información."
+
+#: memline.c:1345
+msgid "Recovery completed. You should check if everything is OK."
+msgstr "Recuperación completa. Ud. debería comprobar que todo está bien"
+
+#: memline.c:1346
+msgid ""
+"\n"
+"(You might want to write out this file under another name\n"
+msgstr ""
+"\n"
+"(Podría querer guardar este archivo con otro nombre\n"
+
+#: memline.c:1347
+msgid "and run diff with the original file to check for changes)\n"
+msgstr ""
+"y ejecutar \"diff\" con el archivo original para comprobar los cambios)\n"
+
+#: memline.c:1348
+msgid ""
+"Delete the .swp file afterwards.\n"
+"\n"
+msgstr ""
+"Elimine el archivo .swp después de terminar.\n"
+"\n"
+
+# use msg() to start the scrolling properly
+#. use msg() to start the scrolling properly
+#: memline.c:1408
+msgid "Swap files found:"
+msgstr "Se han encontrado los siguientes archivos de intercambio:"
+
+#: memline.c:1593
+msgid " In current directory:\n"
+msgstr " En el directorio actual:\n"
+
+#: memline.c:1595
+msgid " Using specified name:\n"
+msgstr " Usando el nombre especificado:\n"
+
+#: memline.c:1599
+msgid " In directory "
+msgstr " En el directorio "
+
+#: memline.c:1617
+msgid " -- none --\n"
+msgstr " -- ninguno --\n"
+
+#: memline.c:1692
+msgid " owned by: "
+msgstr " propiedad de: "
+
+#: memline.c:1694
+msgid " dated: "
+msgstr " de fecha: "
+
+#: memline.c:1698 memline.c:3736
+msgid " dated: "
+msgstr " de fecha: "
+
+#: memline.c:1717
+msgid " [from Vim version 3.0]"
+msgstr " [desde la versión 3.0 de Vim]"
+
+#: memline.c:1721
+msgid " [does not look like a Vim swap file]"
+msgstr " [no parece un archivo de intercambio de Vim]"
+
+#: memline.c:1725
+msgid " file name: "
+msgstr " nombre del archivo: "
+
+#: memline.c:1731
+msgid ""
+"\n"
+" modified: "
+msgstr ""
+"\n"
+" modificado: "
+
+#: memline.c:1732
+msgid "YES"
+msgstr "SI"
+
+#: memline.c:1732
+msgid "no"
+msgstr "no"
+
+#: memline.c:1736
+msgid ""
+"\n"
+" user name: "
+msgstr ""
+"\n"
+" nombre del usuario: "
+
+#: memline.c:1743
+msgid " host name: "
+msgstr " nombre del servidor: "
+
+#: memline.c:1745
+msgid ""
+"\n"
+" host name: "
+msgstr ""
+"\n"
+" nombre del servidor: "
+
+#: memline.c:1751
+msgid ""
+"\n"
+" process ID: "
+msgstr ""
+"\n"
+" ID del proceso: "
+
+#: memline.c:1757
+msgid " (still running)"
+msgstr " (aún en ejecución)"
+
+#: memline.c:1769
+msgid ""
+"\n"
+" [not usable with this version of Vim]"
+msgstr ""
+"\n"
+" [no se puede usar con esta versión de Vim]"
+
+#: memline.c:1772
+msgid ""
+"\n"
+" [not usable on this computer]"
+msgstr ""
+"\n"
+" [no se puede usar en este ordenador]"
+
+#: memline.c:1777
+msgid " [cannot be read]"
+msgstr " [no se puede leer]"
+
+#: memline.c:1781
+msgid " [cannot be opened]"
+msgstr " [no se puede abrir]"
+
+#: memline.c:1971
+msgid "E313: Cannot preserve, there is no swap file"
+msgstr "E313: No se pudo preservar, no existe un archivo de intercambio"
+
+#: memline.c:2024
+msgid "File preserved"
+msgstr "Archivo preservado"
+
+#: memline.c:2026
+msgid "E314: Preserve failed"
+msgstr "E314: Falló la preservación del archivo"
+
+#: memline.c:2103
+#, c-format
+msgid "E315: ml_get: invalid lnum: %ld"
+msgstr "E315: \"ml_get\": número de línea no válido: %ld"
+
+#: memline.c:2138
+#, c-format
+msgid "E316: ml_get: cannot find line %ld"
+msgstr "E316: \"ml_get\": no se pudo encontrar la línea %ld"
+
+#: memline.c:2552
+msgid "E317: pointer block id wrong 3"
+msgstr "E317: El id del bloque de punteros es incorrecto. 3"
+
+#: memline.c:2632
+msgid "stack_idx should be 0"
+msgstr "\"stack_idx\" debería ser 0"
+
+#: memline.c:2694
+msgid "E318: Updated too many blocks?"
+msgstr "E318: ¿Demasiados bloques actualizados?"
+
+#: memline.c:2874
+msgid "E317: pointer block id wrong 4"
+msgstr "E317: El id del bloque de punteros es incorrecto. 4"
+
+#: memline.c:2901
+msgid "deleted block 1?"
+msgstr "¿bloque 1 suprimido?"
+
+#: memline.c:3101
+#, c-format
+msgid "E320: Cannot find line %ld"
+msgstr "E320: No se pudo encontrar la línea %ld"
+
+#: memline.c:3347
+msgid "E317: pointer block id wrong"
+msgstr "E317: El id del bloque de punteros es incorrecto"
+
+#: memline.c:3363
+msgid "pe_line_count is zero"
+msgstr "\"pe_line_count\" es cero"
+
+#: memline.c:3392
+#, c-format
+msgid "E322: line number out of range: %ld past the end"
+msgstr "E322: número de línea fuera de rango: %ld más allá del final"
+
+#: memline.c:3396
+#, c-format
+msgid "E323: line count wrong in block %ld"
+msgstr "E323: recuento de líneas erróneo en el bloque %ld"
+
+#: memline.c:3445
+msgid "Stack size increases"
+msgstr "El tamaño de la pila aumenta"
+
+#: memline.c:3492
+msgid "E317: pointer block id wrong 2"
+msgstr "E317: El id del bloque de punteros es incorrecto. 2"
+
+#: memline.c:3531
+#, c-format
+msgid "E773: Symlink loop for \"%s\""
+msgstr "E773: Bucle de symlinks para \"%s\""
+
+#: memline.c:3726
+msgid "E325: ATTENTION"
+msgstr "E325: ATENCIÓN"
+
+#: memline.c:3727
+msgid ""
+"\n"
+"Found a swap file by the name \""
+msgstr ""
+"\n"
+"Se ha encontrado un archivo de intercambio con el nombre \""
+
+#: memline.c:3731
+msgid "While opening file \""
+msgstr "al abrir el archivo \""
+
+#: memline.c:3744
+msgid " NEWER than swap file!\n"
+msgstr " MÃS NUEVO que el archivo de intercambio!\n"
+
+# Some of these messages are long to allow translation to
+# * other languages.
+#. Some of these messages are long to allow translation to
+#. * other languages.
+#: memline.c:3748
+msgid ""
+"\n"
+"(1) Another program may be editing the same file.\n"
+" If this is the case, be careful not to end up with two\n"
+" different instances of the same file when making changes.\n"
+msgstr ""
+"\n"
+"(1) Puede que otro programa esté editando el mismo archivo.\n"
+" De ser así, tenga cuidado de no acabar con dos\n"
+" ejemplares diferentes del mismo archivo al hacer cambios.\n"
+
+#: memline.c:3749
+msgid " Quit, or continue with caution.\n"
+msgstr " Salga del programa o continúe con precaución.\n"
+
+#: memline.c:3750
+msgid ""
+"\n"
+"(2) An edit session for this file crashed.\n"
+msgstr ""
+"\n"
+"(2) Falló una sesión de edición de este archivo.\n"
+
+#: memline.c:3751
+msgid " If this is the case, use \":recover\" or \"vim -r "
+msgstr " Si es así, use \":recover\" o \"vim -r "
+
+#: memline.c:3753
+msgid ""
+"\"\n"
+" to recover the changes (see \":help recovery\").\n"
+msgstr ""
+"\"\n"
+" para recuperar los cambios (véa \":help recovery\").\n"
+
+#: memline.c:3754
+msgid " If you did this already, delete the swap file \""
+msgstr " Si Ud. ya ha hecho esto, borre el archivo de intercambio \""
+
+#: memline.c:3756
+msgid ""
+"\"\n"
+" to avoid this message.\n"
+msgstr ""
+"\"\n"
+" para evitar este mensaje.\n"
+
+#: memline.c:4175 memline.c:4179
+msgid "Swap file \""
+msgstr "¡El archivo de intercambio \""
+
+#: memline.c:4176 memline.c:4182
+msgid "\" already exists!"
+msgstr "\" ya existe!"
+
+#: memline.c:4185
+msgid "VIM - ATTENTION"
+msgstr "VIM - ATENCIÓN"
+
+#: memline.c:4187
+msgid "Swap file already exists!"
+msgstr "¡Ya existe un archivo de intercambio!"
+
+#: memline.c:4191
+msgid ""
+"&Open Read-Only\n"
+"&Edit anyway\n"
+"&Recover\n"
+"&Quit\n"
+"&Abort"
+msgstr ""
+"&Abrir para lectura únicamente\n"
+"&Editar de todas formas\n"
+"&Recuperar\n"
+"&Salir\n"
+"A&bortar"
+
+#: memline.c:4193
+msgid ""
+"&Open Read-Only\n"
+"&Edit anyway\n"
+"&Recover\n"
+"&Delete it\n"
+"&Quit\n"
+"&Abort"
+msgstr ""
+"&Abrir para lectura únicamente\n"
+"&Editar de todas formas\n"
+"&Recuperar\n"
+"&Borrar&Salir\n"
+"&Abortar"
+
+#: memline.c:4264
+msgid "E326: Too many swap files found"
+msgstr "E326: Se han encontrado demasiados archivos de intercambio"
+
+#: menu.c:64
+msgid "E327: Part of menu-item path is not sub-menu"
+msgstr "E327: Parte de la ruta del item del menú no es un sub-menú"
+
+#: menu.c:65
+msgid "E328: Menu only exists in another mode"
+msgstr "E328: El menú solo existe en otro modo de operación"
+
+#: menu.c:66
+#, c-format
+msgid "E329: No menu \"%s\""
+msgstr "E329: No existe el menú \"%s\""
+
+#. Only a mnemonic or accelerator is not valid.
+#: menu.c:519
+msgid "E792: Empty menu name"
+msgstr "E792: Nombre de menú vacío"
+
+#: menu.c:537
+msgid "E330: Menu path must not lead to a sub-menu"
+msgstr "E330: La ruta del menú no debe conducir a un sub-menú"
+
+#: menu.c:576
+msgid "E331: Must not add menu items directly to menu bar"
+msgstr ""
+"E331: No se deben añadir elementos del menú directamente a la barra del menú"
+
+#: menu.c:582
+msgid "E332: Separator cannot be part of a menu path"
+msgstr "E332: El separador no puede ser parte de una ruta de menú"
+
+# Now we have found the matching menu, and we list the mappings
+# Highlight title
+#. Now we have found the matching menu, and we list the mappings
+#. Highlight title
+#: menu.c:1127
+msgid ""
+"\n"
+"--- Menus ---"
+msgstr ""
+"\n"
+"--- Menús ---"
+
+#: menu.c:2090
+msgid "Tear off this menu"
+msgstr "Desprender y flotar este menú"
+
+#: menu.c:2155
+msgid "E333: Menu path must lead to a menu item"
+msgstr "E333: La ruta del menú debe conducir a un item del menú"
+
+#: menu.c:2175
+#, c-format
+msgid "E334: Menu not found: %s"
+msgstr "E334: No se ha encontrado el menú: %s"
+
+#: menu.c:2257
+#, c-format
+msgid "E335: Menu not defined for %s mode"
+msgstr "E335: El menú no está definido para el modo %s"
+
+#: menu.c:2295
+msgid "E336: Menu path must lead to a sub-menu"
+msgstr "E336: La ruta del menú debe conducir a un sub-menú"
+
+#: menu.c:2316
+msgid "E337: Menu not found - check menu names"
+msgstr "E337: No se ha encontrado el menú - verifique los nombres de los menús"
+
+#: message.c:462
+#, c-format
+msgid "Error detected while processing %s:"
+msgstr "Se ha detectado un error al procesar %s:"
+
+#: message.c:487
+#, c-format
+msgid "line %4ld:"
+msgstr "línea %4ld"
+
+#: message.c:685
+#, c-format
+msgid "E354: Invalid register name: '%s'"
+msgstr "E354: Nombre de registro no válido: '%s'"
+
+#: message.c:833
+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:1090
+msgid "Interrupt: "
+msgstr "Interrupción: "
+
+#: message.c:1092
+msgid "Press ENTER or type command to continue"
+msgstr "Pulse INTRO o escriba una orden para continuar"
+
+#: message.c:2139
+#, c-format
+msgid "%s line %ld"
+msgstr "%s, en la línea %ld"
+
+#: message.c:2839
+msgid "-- More --"
+msgstr "-- Más --"
+
+#: message.c:2845
+msgid " SPACE/d/j: screen/page/line down, b/u/k: up, q: quit "
+msgstr " ESPACIO/d/j: pantalla/página/línea abajo, b/u/k: arriba, q: salir "
+
+#: message.c:3637 message.c:3652
+msgid "Question"
+msgstr "Pregunta"
+
+#: message.c:3639
+msgid ""
+"&Yes\n"
+"&No"
+msgstr ""
+"&Si\n"
+"&No"
+
+#: message.c:3672
+msgid ""
+"&Yes\n"
+"&No\n"
+"Save &All\n"
+"&Discard All\n"
+"&Cancel"
+msgstr ""
+"&Si\n"
+"&No\n"
+"&Guardar todo\n"
+"&Descartar todo\n"
+"&Cancelar"
+
+#: message.c:3713
+msgid "Select Directory dialog"
+msgstr "Diálogo: Selección de directorio"
+
+#: message.c:3715
+msgid "Save File dialog"
+msgstr "Diálogo: Guardar Archivos"
+
+#: message.c:3717
+msgid "Open File dialog"
+msgstr "Diálogo: Abrir Archivos"
+
+# TODO: non-GUI file selector here
+#. TODO: non-GUI file selector here
+#: message.c:3817
+msgid "E338: Sorry, no file browser in console mode"
+msgstr "E338: Lo siento, no hay navegador de archivos en el modo de consola"
+
+#: message.c:3848
+msgid "E766: Insufficient arguments for printf()"
+msgstr "E766: Argumentos insuficientes para printf()"
+
+#: message.c:3924
+msgid "E807: Expected Float argument for printf()"
+msgstr "E807: Se esperaba un argumento \"Float\" para printf()"
+
+#: message.c:4812
+msgid "E767: Too many arguments to printf()"
+msgstr "E767: Demasiados argumentos para printf()"
+
+#: misc1.c:2975
+msgid "W10: Warning: Changing a readonly file"
+msgstr "W10: Advertencia: cambiando un archivo de sólo lectura"
+
+#: misc1.c:3269
+msgid "Type number and <Enter> or click with mouse (empty cancels): "
+msgstr "Escriba un número e <Intro> o pulse con el ratón (la omisión cancela) "
+
+#: misc1.c:3271
+msgid "Type number and <Enter> (empty cancels): "
+msgstr "Escoja un número e <Intro> (la omisión cancela la acción): "
+
+#: misc1.c:3323
+msgid "1 more line"
+msgstr "1 línea más"
+
+#: misc1.c:3325
+msgid "1 line less"
+msgstr "1 línea menos"
+
+#: misc1.c:3330
+#, c-format
+msgid "%ld more lines"
+msgstr "%ld líneas más"
+
+#: misc1.c:3332
+#, c-format
+msgid "%ld fewer lines"
+msgstr "%ld líneas menos"
+
+#: misc1.c:3335
+msgid " (Interrupted)"
+msgstr " (Interrumpido)"
+
+#: misc1.c:3400
+msgid "Beep!"
+msgstr "¡Bip!"
+
+#: misc1.c:8380
+msgid "Vim: preserving files...\n"
+msgstr "Vim: preservando archivos...\n"
+
+# close all memfiles, without deleting
+#. close all memfiles, without deleting
+#: misc1.c:8390
+msgid "Vim: Finished.\n"
+msgstr "Vim: Finalizado.\n"
+
+#: misc2.c:718 misc2.c:734
+#, c-format
+msgid "ERROR: "
+msgstr "ERROR: "
+
+#: misc2.c:738
+#, c-format
+msgid ""
+"\n"
+"[bytes] total alloc-freed %lu-%lu, in use %lu, peak use %lu\n"
+msgstr ""
+"\n"
+"[bytes] total liberados por alloc: %lu-%lu, en uso: %lu, uso máximo: %lu\n"
+
+#: misc2.c:740
+#, c-format
+msgid ""
+"[calls] total re/malloc()'s %lu, total free()'s %lu\n"
+"\n"
+msgstr ""
+"[llamadas] total re/malloc(): %lu, total free(): %lu\n"
+"\n"
+
+#: misc2.c:795
+msgid "E340: Line is becoming too long"
+msgstr "E340: La línea se está haciendo demasiado larga"
+
+#: misc2.c:839
+#, c-format
+msgid "E341: Internal error: lalloc(%ld, )"
+msgstr "E341: Error interno: lalloc(%ld, )"
+
+#: misc2.c:953
+#, c-format
+msgid "E342: Out of memory! (allocating %lu bytes)"
+msgstr "E342: ¡Memoria agotada! (al asignar %lu bytes)"
+
+#: misc2.c:3033
+#, c-format
+msgid "Calling shell to execute: \"%s\""
+msgstr "Invocando al intérprete de órdenes para ejecutar: %s"
+
+#: misc2.c:3302
+msgid "E545: Missing colon"
+msgstr "E545: Falta un símbolo de dos puntos"
+
+#: misc2.c:3304 misc2.c:3331
+msgid "E546: Illegal mode"
+msgstr "E546: Modo de operación ilegal"
+
+#: misc2.c:3370
+msgid "E547: Illegal mouseshape"
+msgstr "E547: El \"mouseshape\" no es válido"
+
+#: misc2.c:3410
+msgid "E548: digit expected"
+msgstr "E548: Se esperaba un dígito"
+
+#: misc2.c:3415
+msgid "E549: Illegal percentage"
+msgstr "E549: Porcentaje ilegal"
+
+#: misc2.c:3737
+msgid "Enter encryption key: "
+msgstr "Introduzca la clave de cifrado: "
+
+#: misc2.c:3738
+msgid "Enter same key again: "
+msgstr "Introduzca la misma clave de cifrado otra vez: "
+
+#: misc2.c:3749
+msgid "Keys don't match!"
+msgstr "¡Las claves de cifrado no coinciden!"
+
+#: misc2.c:4290
+#, c-format
+msgid ""
+"E343: Invalid path: '**[number]' must be at the end of the path or be "
+"followed by '%s'."
+msgstr ""
+"E343: Ruta no válida: '**[número]' debe estar al final de la ruta\n"
+"o seguido de %s."
+
+#: misc2.c:5585
+#, c-format
+msgid "E344: Can't find directory \"%s\" in cdpath"
+msgstr "E344: No se pudo encontrar el directorio \"%s\" en \"cdpath\""
+
+#: misc2.c:5588
+#, c-format
+msgid "E345: Can't find file \"%s\" in path"
+msgstr "E345: No se pudo encontrar el archivo %s en la ruta"
+
+#: misc2.c:5594
+#, c-format
+msgid "E346: No more directory \"%s\" found in cdpath"
+msgstr "E346: No se han encontrado mas directorios \"%s\" en \"cdpath\""
+
+#: misc2.c:5597
+#, c-format
+msgid "E347: No more file \"%s\" found in path"
+msgstr "E347: No se han encontrado mas archivos \"%s\" en la ruta"
+
+# Get here when the server can't be found.
+#: netbeans.c:406
+msgid "Cannot connect to Netbeans #2"
+msgstr "No se pudo conectar a NetBeans #2"
+
+#: netbeans.c:415
+msgid "Cannot connect to Netbeans"
+msgstr "No se pudo conectar a NetBeans"
+
+# c-format
+#: netbeans.c:461
+#, c-format
+msgid "E668: Wrong access mode for NetBeans connection info file: \"%s\""
+msgstr "E668: El dueño/a del archivo de conexión NetBeans no es válido: %s"
+
+#: netbeans.c:770
+msgid "read from Netbeans socket"
+msgstr "leído del socket NetBeans"
+
+#: netbeans.c:1872
+#, c-format
+msgid "E658: NetBeans connection lost for buffer %ld"
+msgstr "E658: Se perdió la conexión NetBeans para el búfer %ld"
+
+#: netbeans.c:3692
+msgid "E505: "
+msgstr "E505: "
+
+#: normal.c:186
+msgid "E349: No identifier under cursor"
+msgstr "E349: No hay ningún identificador bajo el cursor"
+
+#: normal.c:2198
+msgid "E774: 'operatorfunc' is empty"
+msgstr "E774: 'operatorfunc' está vacío"
+
+#: normal.c:2217
+msgid "E775: Eval feature not available"
+msgstr "E775: La característica \"eval\" no está disponible"
+
+#: normal.c:3221
+msgid "Warning: terminal cannot highlight"
+msgstr "Advertencia: la terminal no puede resaltar el texto"
+
+#: normal.c:3516
+msgid "E348: No string under cursor"
+msgstr "E348: No hay ninguna cadena bajo el cursor"
+
+#: normal.c:4868
+msgid "E352: Cannot erase folds with current 'foldmethod'"
+msgstr "E352: No se pudo borrar pliegues con el 'folmethod' actual"
+
+#: normal.c:7365
+msgid "E664: changelist is empty"
+msgstr "E664: La lista de cambios está vacía"
+
+#: normal.c:7367
+msgid "E662: At start of changelist"
+msgstr "E662: Al comienzo de la lista de cambios"
+
+#: normal.c:7369
+msgid "E663: At end of changelist"
+msgstr "E663: Al final de la lista de cambios"
+
+#: normal.c:8734
+msgid "Type :quit<Enter> to exit Vim"
+msgstr "Escriba \":quit<intro>\" para salir de Vim"
+
+#: ops.c:293
+#, c-format
+msgid "1 line %sed 1 time"
+msgstr "1 línea %sed 1 vez"
+
+#: ops.c:295
+#, c-format
+msgid "1 line %sed %d times"
+msgstr "1 línea %sed %d veces"
+
+#: ops.c:300
+#, c-format
+msgid "%ld lines %sed 1 time"
+msgstr "%ld líneas %sed 1 vez"
+
+#: ops.c:303
+#, c-format
+msgid "%ld lines %sed %d times"
+msgstr "%ld líneas %sed %d veces"
+
+#: ops.c:691
+#, c-format
+msgid "%ld lines to indent... "
+msgstr "%ld líneas por sangrar..."
+
+#: ops.c:742
+msgid "1 line indented "
+msgstr "1 línea sangrada"
+
+#: ops.c:744
+#, c-format
+msgid "%ld lines indented "
+msgstr "%ld líneas sangradas"
+
+#: ops.c:1170
+msgid "E748: No previously used register"
+msgstr "E748: No hay registro previamente en uso"
+
+# must display the prompt
+#. must display the prompt
+#: ops.c:1734
+msgid "cannot yank; delete anyway"
+msgstr "No se pudo copiar \"yank\"; ¿Lo borro de todas formas?"
+
+#: ops.c:2331
+msgid "1 line changed"
+msgstr "1 línea cambiada"
+
+#: ops.c:2333
+#, c-format
+msgid "%ld lines changed"
+msgstr "%ld líneas cambiadas"
+
+#: ops.c:2788
+#, c-format
+msgid "freeing %ld lines"
+msgstr "liberando %ld líneas"
+
+#: ops.c:3073
+msgid "block of 1 line yanked"
+msgstr "bloque de 1 línea copiada"
+
+#: ops.c:3076
+msgid "1 line yanked"
+msgstr "1 línea copiada"
+
+#: ops.c:3080
+#, c-format
+msgid "block of %ld lines yanked"
+msgstr "bloque de %ld líneas copiadas"
+
+#: ops.c:3083
+#, c-format
+msgid "%ld lines yanked"
+msgstr "%ld líneas copiadas"
+
+#: ops.c:3378
+#, c-format
+msgid "E353: Nothing in register %s"
+msgstr "E353: No hay nada en el registro %s"
+
+# Highlight title
+#. Highlight title
+#: ops.c:3970
+msgid ""
+"\n"
+"--- Registers ---"
+msgstr ""
+"\n"
+"--- Registros ---"
+
+#: ops.c:5344
+msgid "Illegal register name"
+msgstr "Nombre de registro ilegal"
+
+#: ops.c:5440
+#, c-format
+msgid ""
+"\n"
+"# Registers:\n"
+msgstr ""
+"\n"
+"# Registros:\n"
+
+#: ops.c:5497
+#, c-format
+msgid "E574: Unknown register type %d"
+msgstr "E574: Registro desconocido de tipo %d"
+
+#: ops.c:6435
+#, c-format
+msgid "%ld Cols; "
+msgstr "%ld Cols; "
+
+#: ops.c:6444
+#, c-format
+msgid "Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Bytes"
+msgstr ""
+"Selección %s%ld de %ld Líneas; %ld de %ld Palabras; %ld de %ld Caracteres"
+
+#: ops.c:6451
+#, c-format
+msgid ""
+"Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Chars; %ld of %ld "
+"Bytes"
+msgstr ""
+"Selección %s%ld de %ld Líneas; %ld de %ld Palabras; %ld de %ld Caracteres; %"
+"ld de %ld Bytes"
+
+#: ops.c:6470
+#, c-format
+msgid "Col %s of %s; Line %ld of %ld; Word %ld of %ld; Byte %ld of %ld"
+msgstr "Col %s de %s; Línea %ld de %ld; Palabra %ld de %ld; Byte %ld de %ld"
+
+#: ops.c:6478
+#, c-format
+msgid ""
+"Col %s of %s; Line %ld of %ld; Word %ld of %ld; Char %ld of %ld; Byte %ld of "
+"%ld"
+msgstr ""
+"Col %s de %s; Línea %ld de %ld; Palabra %ld de %ld; Carácter %ld de %ld Byte "
+"%ld de %ld"
+
+#: ops.c:6490
+#, c-format
+msgid "(+%ld for BOM)"
+msgstr "(+%ld para BOM)"
+
+#: option.c:1953
+msgid "%<%f%h%m%=Page %N"
+msgstr "%<%f%h%m%=Página %N"
+
+#: option.c:2524
+msgid "Thanks for flying Vim"
+msgstr "Gracias por volar con Vim"
+
+#: option.c:4099 option.c:4242
+msgid "E518: Unknown option"
+msgstr "E518: Opción desconocida"
+
+#: option.c:4112
+msgid "E519: Option not supported"
+msgstr "E519: Opción no admitida"
+
+#: option.c:4150
+msgid "E520: Not allowed in a modeline"
+msgstr "E520: No permitido en una \"modeline\""
+
+#: option.c:4368
+msgid "E521: Number required after ="
+msgstr "E521: Debe introducir un número después de \"=\""
+
+#: option.c:4693 option.c:5499
+msgid "E522: Not found in termcap"
+msgstr "E522: No lo encontré en el \"termcap\""
+
+#: option.c:4810
+#, c-format
+msgid "E539: Illegal character <%s>"
+msgstr "E539: Carácter ilegal <%s>"
+
+#: option.c:5491
+msgid "E529: Cannot set 'term' to empty string"
+msgstr "E529: No se pudo definir \"term\" como una cadena de caracteres vacía"
+
+#: option.c:5494
+msgid "E530: Cannot change term in GUI"
+msgstr "E530: No se pudo cambiar \"term\" en la interfaz gráfica"
+
+#: option.c:5496
+msgid "E531: Use \":gui\" to start the GUI"
+msgstr "E531: Use \":gui\" para iniciar la interfaz gráfica"
+
+#: option.c:5525
+msgid "E589: 'backupext' and 'patchmode' are equal"
+msgstr "E589: \"backupext\" y \"patchmode\" son iguales"
+
+#: option.c:5753
+msgid "E617: Cannot be changed in the GTK+ 2 GUI"
+msgstr "E617: No puede cambiarse en la interfaz gráfica de GTK+ 2"
+
+#: option.c:5931
+msgid "E524: Missing colon"
+msgstr "E524: Falta un símbolo de dos puntos"
+
+#: option.c:5933
+msgid "E525: Zero length string"
+msgstr "E525: Cadena de caracteres de largo cero"
+
+#: option.c:6016
+#, c-format
+msgid "E526: Missing number after <%s>"
+msgstr "E526: Falta el número después de <%s>"
+
+#: option.c:6030
+msgid "E527: Missing comma"
+msgstr "E527: Falta una coma"
+
+#: option.c:6037
+msgid "E528: Must specify a ' value"
+msgstr "E528: Debe especificar un valor "
+
+#: option.c:6086
+msgid "E595: contains unprintable or wide character"
+msgstr "E595: Contiene un carácter no imprimible o de más de un byte"
+
+#: option.c:6130
+msgid "E596: Invalid font(s)"
+msgstr "E596: Las fuente/s de impresión no son válidas"
+
+#: option.c:6139
+msgid "E597: can't select fontset"
+msgstr "E597: No se pudo seleccionar ese \"fontset\""
+
+#: option.c:6141
+msgid "E598: Invalid fontset"
+msgstr "E598: El conjunto de tipos de letra de impresión no es válido"
+
+#: option.c:6149
+msgid "E533: can't select wide font"
+msgstr ""
+"E533: No se pudo seleccionar el tipo de letra de impresión \"ancho\" (de "
+"\"byte\" doble)"
+
+#: option.c:6151
+msgid "E534: Invalid wide font"
+msgstr "E534: Tipo de letra de impresión \"ancho\" inválida"
+
+#: option.c:6477
+#, c-format
+msgid "E535: Illegal character after <%c>"
+msgstr "E535: Carácter ilegal después de <%c>"
+
+#: option.c:6597
+msgid "E536: comma required"
+msgstr "E536: necesita una coma"
+
+#: option.c:6607
+#, c-format
+msgid "E537: 'commentstring' must be empty or contain %s"
+msgstr "E537: 'commentstring' debe estar vacío o contener %s"
+
+#: option.c:6688
+msgid "E538: No mouse support"
+msgstr "E538: No hay soporte para el ratón"
+
+#: option.c:7007
+msgid "E540: Unclosed expression sequence"
+msgstr "E540: Secuencia de expresión sin cerrar"
+
+#: option.c:7011
+msgid "E541: too many items"
+msgstr "E541: Demasiados elementos"
+
+#: option.c:7013
+msgid "E542: unbalanced groups"
+msgstr "E542: Grupos sin equilibrar"
+
+#: option.c:7349
+msgid "E590: A preview window already exists"
+msgstr "E590: Ya existe una ventana de visualización previa"
+
+#: option.c:7605
+msgid "W17: Arabic requires UTF-8, do ':set encoding=utf-8'"
+msgstr "W17: La opción árabe necesita de UTF-8, use \":set encoding=utf-8\""
+
+#: option.c:8028
+#, c-format
+msgid "E593: Need at least %d lines"
+msgstr "E593: Necesita al menos %d líneas"
+
+#: option.c:8038
+#, c-format
+msgid "E594: Need at least %d columns"
+msgstr "E594: Necesita al menos %d columnas"
+
+#: option.c:8357
+#, c-format
+msgid "E355: Unknown option: %s"
+msgstr "E355: Opción desconocida: %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:8389
+#, c-format
+msgid "E521: Number required: &%s = '%s'"
+msgstr "E521: Debe introducir un número: &%s = '%s'"
+
+#: option.c:8513
+msgid ""
+"\n"
+"--- Terminal codes ---"
+msgstr ""
+"\n"
+"--- Códigos de terminal ---"
+
+#: option.c:8515
+msgid ""
+"\n"
+"--- Global option values ---"
+msgstr ""
+"\n"
+"--- Valores de las opciones globales ---"
+
+#: option.c:8517
+msgid ""
+"\n"
+"--- Local option values ---"
+msgstr ""
+"\n"
+"--- Valores de las opciones locales ---"
+
+#: option.c:8519
+msgid ""
+"\n"
+"--- Options ---"
+msgstr ""
+"\n"
+"--- Opciones ---"
+
+#: option.c:9332
+msgid "E356: get_varp ERROR"
+msgstr "E356: ERROR en \"get_varp\""
+
+#: option.c:10431
+#, c-format
+msgid "E357: 'langmap': Matching character missing for %s"
+msgstr "E357: \"langmap\": falta carácter coincidente para %s"
+
+#: option.c:10463
+#, c-format
+msgid "E358: 'langmap': Extra characters after semicolon: %s"
+msgstr "E358: \"langmap\": caracteres extra después del punto y coma: %s"
+
+#: os_amiga.c:278
+msgid "cannot open "
+msgstr "No se pudo abrir"
+
+#: os_amiga.c:313
+msgid "VIM: Can't open window!\n"
+msgstr "VIM: ¡No se pudo abrir la ventana!\n"
+
+#: os_amiga.c:340
+msgid "Need Amigados version 2.04 or later\n"
+msgstr "Necesito Amigados 2.04 o una versión posterior\n"
+
+#: os_amiga.c:346
+#, c-format
+msgid "Need %s version %ld\n"
+msgstr "Necesito %s versión %ld\n"
+
+#: os_amiga.c:419
+msgid "Cannot open NIL:\n"
+msgstr "No se pudo abrir NIL:\n"
+
+#: os_amiga.c:437
+msgid "Cannot create "
+msgstr "No se pudo crear "
+
+#: os_amiga.c:943
+#, c-format
+msgid "Vim exiting with %d\n"
+msgstr "Saliendo de Vim con %d\n"
+
+#: os_amiga.c:979
+msgid "cannot change console mode ?!\n"
+msgstr "¡¿No se pudo cambiar el modo de la consola?!\n"
+
+#: os_amiga.c:1057
+msgid "mch_get_shellsize: not a console??\n"
+msgstr "\"mch_get_shellsize\": ¿No es una consola?\n"
+
+# if Vim opened a window: Executing a shell may cause crashes
+#. if Vim opened a window: Executing a shell may cause crashes
+#: os_amiga.c:1212
+msgid "E360: Cannot execute shell with -f option"
+msgstr "E360: No se pudo ejecutar el intérprete de órdenes con la opción -f"
+
+#: os_amiga.c:1253 os_amiga.c:1343
+msgid "Cannot execute "
+msgstr "No se puede ejecutar "
+
+#: os_amiga.c:1256 os_amiga.c:1353
+msgid "shell "
+msgstr "shell "
+
+#: os_amiga.c:1276 os_amiga.c:1378
+msgid " returned\n"
+msgstr " devolvió\n"
+
+#: os_amiga.c:1540
+msgid "ANCHOR_BUF_SIZE too small."
+msgstr "\"ANCHOR_BUF_SIZE\" demasiado pequeño."
+
+#: os_amiga.c:1544
+msgid "I/O ERROR"
+msgstr "ERROR I/O"
+
+#: os_mswin.c:595
+msgid "Message"
+msgstr "Mensaje"
+
+#: os_mswin.c:710
+msgid "'columns' is not 80, cannot execute external commands"
+msgstr "\"columns\" no es 80, no puede ejecutar órdenes externas"
+
+#: os_mswin.c:2143
+msgid "E237: Printer selection failed"
+msgstr "E237: Falló la selección de impresora"
+
+#: os_mswin.c:2183
+#, c-format
+msgid "to %s on %s"
+msgstr "para %s en %s"
+
+#: os_mswin.c:2198
+#, c-format
+msgid "E613: Unknown printer font: %s"
+msgstr "E613: Tipo de letra de impresión desconocida en la impresora: %s"
+
+#: os_mswin.c:2247 os_mswin.c:2257
+#, c-format
+msgid "E238: Print error: %s"
+msgstr "E238: Error de impresión: %s"
+
+#: os_mswin.c:2285
+#, c-format
+msgid "Printing '%s'"
+msgstr "Imprimiendo %s"
+
+#: os_mswin.c:3461
+#, c-format
+msgid "E244: Illegal charset name \"%s\" in font name \"%s\""
+msgstr ""
+"E244: El nombre del conjunto de caracteres \"%s\" no es válido en el\n"
+"nombre del tipo de letra de impresión \"%s\""
+
+#: os_mswin.c:3471
+#, c-format
+msgid "E245: Illegal char '%c' in font name \"%s\""
+msgstr ""
+"E245: Carácter '%c' ilegal en el nombre del tipo de letra de\n"
+"impresión %s"
+
+#: os_unix.c:1065
+msgid "Vim: Double signal, exiting\n"
+msgstr "Vim: Señal doble, saliendo\n"
+
+#: os_unix.c:1071
+#, c-format
+msgid "Vim: Caught deadly signal %s\n"
+msgstr "Vim: Capté una señal mortal %s\n"
+
+#: os_unix.c:1074
+#, c-format
+msgid "Vim: Caught deadly signal\n"
+msgstr "Vim: Capté una señal mortal\n"
+
+#: os_unix.c:1412
+#, c-format
+msgid "Opening the X display took %ld msec"
+msgstr "Abrir la pantalla X tomó %ld mseg"
+
+#: os_unix.c:1439
+msgid ""
+"\n"
+"Vim: Got X error\n"
+msgstr ""
+"\n"
+"Vim: Hay un error de X\n"
+
+#: os_unix.c:1544
+msgid "Testing the X display failed"
+msgstr "Falló la prueba del sistema X"
+
+#: os_unix.c:1684
+msgid "Opening the X display timed out"
+msgstr "El \"display\" de X tardó demasiado en abrirse"
+
+#: os_unix.c:2658 os_unix.c:2665
+msgid ""
+"\n"
+"Could not get security context for "
+msgstr ""
+"\n"
+"No se pudo obtener el contexto de seguridad para "
+
+#: os_unix.c:2675
+msgid ""
+"\n"
+"Could not set security context for "
+msgstr ""
+"\n"
+"No se pudo definir el contexto de seguridad para "
+
+#: os_unix.c:3695 os_unix.c:4620
+msgid ""
+"\n"
+"Cannot execute shell "
+msgstr ""
+"\n"
+"No se pudo ejecutar el intérprete de órdenes "
+
+#: os_unix.c:3743
+msgid ""
+"\n"
+"Cannot execute shell sh\n"
+msgstr ""
+"\n"
+"No se pudo ejecutar el intérprete de órdenes \"sh\"\n"
+
+#: os_unix.c:3747 os_unix.c:4626
+msgid ""
+"\n"
+"shell returned "
+msgstr ""
+"\n"
+"El intérprete de órdenes devolvió "
+
+#: os_unix.c:3891
+msgid ""
+"\n"
+"Cannot create pipes\n"
+msgstr ""
+"\n"
+"No se pudo crear \"pipes\"\n"
+
+#: os_unix.c:3905 os_unix.c:4169
+msgid ""
+"\n"
+"Cannot fork\n"
+msgstr ""
+"\n"
+"No se pudo crear proceso secundario \"fork\"\n"
+
+#: os_unix.c:4633
+msgid ""
+"\n"
+"Command terminated\n"
+msgstr ""
+"\n"
+"La orden fue terminada\n"
+
+#: os_unix.c:4919 os_unix.c:5069 os_unix.c:6792
+msgid "XSMP lost ICE connection"
+msgstr "XSMP perdió la conexión ICE"
+
+#: os_unix.c:6192 os_unix.c:6295
+#, c-format
+msgid "dlerror = \"%s\""
+msgstr "dlerror = \"%s\""
+
+#: os_unix.c:6377
+msgid "Opening the X display failed"
+msgstr "Falló la apertura de la pantalla de X"
+
+#: os_unix.c:6701
+msgid "XSMP handling save-yourself request"
+msgstr "XSMP está manejando una solicitud de \"guardelo usted mismo\""
+
+#: os_unix.c:6815
+msgid "XSMP opening connection"
+msgstr "XSMP está abriendo una conexión"
+
+#: os_unix.c:6834
+msgid "XSMP ICE connection watch failed"
+msgstr "XSMP Falló el supervisión de la conexión ICE"
+
+#: os_unix.c:6858
+#, c-format
+msgid "XSMP SmcOpenConnection failed: %s"
+msgstr "XSMP SmcOpenConnection falló: %s"
+
+#: os_vms_mms.c:60
+msgid "At line"
+msgstr "En la línea"
+
+#: os_w32exe.c:89
+msgid "Could not load vim32.dll!"
+msgstr "¡No se pudo cargar \"vim32.dll\"!"
+
+#: os_w32exe.c:89 os_w32exe.c:100
+msgid "VIM Error"
+msgstr "Error de Vim"
+
+#: os_w32exe.c:99
+msgid "Could not fix up function pointers to the DLL!"
+msgstr "¡No se pudo conectar los punteros de la función a la DLL!"
+
+#: os_win16.c:342 os_win32.c:3399
+#, c-format
+msgid "shell returned %d"
+msgstr "El intérprete de órdenes ha devuelto %d"
+
+#: os_win32.c:2856
+#, c-format
+msgid "Vim: Caught %s event\n"
+msgstr "Vim: Capté el evento %s\n"
+
+#: os_win32.c:2858
+msgid "close"
+msgstr "cerrar"
+
+#: os_win32.c:2860
+msgid "logoff"
+msgstr "cerrar la sesión"
+
+#: os_win32.c:2861
+msgid "shutdown"
+msgstr "apagar"
+
+#: os_win32.c:3351
+msgid "E371: Command not found"
+msgstr "E371: No se encontró la orden"
+
+#: os_win32.c:3364
+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 no se encuentra en su $PATH.\n"
+"Las órdenes externas no harán una pausa al finalizar.\n"
+"Véase \":help win32-vimrun\" para más información"
+
+#: os_win32.c:3367
+msgid "Vim Warning"
+msgstr "Advertencia de Vim"
+
+#: quickfix.c:330
+#, c-format
+msgid "E372: Too many %%%c in format string"
+msgstr "E372: Demasiados %%%c en la cadena de formato"
+
+#: quickfix.c:343
+#, c-format
+msgid "E373: Unexpected %%%c in format string"
+msgstr "E373: %%%c inesperado en la cadena de formato"
+
+#: quickfix.c:405
+msgid "E374: Missing ] in format string"
+msgstr "E374: Falta ] en la cadena de formato"
+
+#: quickfix.c:419
+#, c-format
+msgid "E375: Unsupported %%%c in format string"
+msgstr "E375: %%%c no admitido en cadena de formato"
+
+#: quickfix.c:439
+#, c-format
+msgid "E376: Invalid %%%c in format string prefix"
+msgstr "E376: %%%c no es válido en el prefijo de una cadena de formato"
+
+#: quickfix.c:447
+#, c-format
+msgid "E377: Invalid %%%c in format string"
+msgstr "E377: %%%c no es válido en una cadena de formato"
+
+#: quickfix.c:473
+msgid "E378: 'errorformat' contains no pattern"
+msgstr "E378: 'errorformat' no contiene un patrón"
+
+#: quickfix.c:706
+msgid "E379: Missing or empty directory name"
+msgstr "E379: Hace falta el nombre del directorio"
+
+#: quickfix.c:1408
+msgid "E553: No more items"
+msgstr "E553: No hay más elementos"
+
+#: quickfix.c:1830
+#, c-format
+msgid "(%d of %d)%s%s: "
+msgstr "(%d de %d)%s%s: "
+
+#: quickfix.c:1832
+msgid " (line deleted)"
+msgstr " (línea borrada)"
+
+#: quickfix.c:2061
+msgid "E380: At bottom of quickfix stack"
+msgstr "E380: Al final de la pila de corrección rápida"
+
+#: quickfix.c:2070
+msgid "E381: At top of quickfix stack"
+msgstr "E381: Al principio de la pila de corrección rápida"
+
+#: quickfix.c:2084
+#, c-format
+msgid "error list %d of %d; %d errors"
+msgstr "lista de errores %d de %d: %d errores"
+
+#: quickfix.c:2670
+msgid "E382: Cannot write, 'buftype' option is set"
+msgstr "E382: No se pudo escribir, la opción \"buftype\" está activa"
+
+#: quickfix.c:3074
+msgid "E683: File name missing or invalid pattern"
+msgstr "E683: Falta el nombre del archivo o el patrón no es válido"
+
+#: quickfix.c:3172
+#, c-format
+msgid "Cannot open file \"%s\""
+msgstr "No se pudo abrir el archivo %s"
+
+#: quickfix.c:3705
+msgid "E681: Buffer is not loaded"
+msgstr "E681: El búfer no está cargado"
+
+#: quickfix.c:3766
+msgid "E777: String or List expected"
+msgstr "E777: Se esperaba una lista o una cadena de caracteres"
+
+#: regexp.c:331
+#, c-format
+msgid "E369: invalid item in %s%%[]"
+msgstr "E369: El elemento en %s%%[] no es válido"
+
+#: regexp.c:1017
+msgid "E339: Pattern too long"
+msgstr "E339: Patrón demasiado largo"
+
+#: regexp.c:1189
+msgid "E50: Too many \\z("
+msgstr "E50: Demasiados \\z("
+
+#: regexp.c:1200
+#, c-format
+msgid "E51: Too many %s("
+msgstr "E51: Hay demasiados %s("
+
+#: regexp.c:1257
+msgid "E52: Unmatched \\z("
+msgstr "E52: \\z( sin complemento"
+
+#: regexp.c:1261
+#, c-format
+msgid "E53: Unmatched %s%%("
+msgstr "E53: %s%%( sin complemento"
+
+#: regexp.c:1263
+#, c-format
+msgid "E54: Unmatched %s("
+msgstr "E54: %s( sin complemento"
+
+#: regexp.c:1268
+#, c-format
+msgid "E55: Unmatched %s)"
+msgstr "E55: %s) sin complemento"
+
+#: regexp.c:1484
+#, c-format
+msgid "E59: invalid character after %s@"
+msgstr "E59: Carácter inválido después de %s@"
+
+#: regexp.c:1518
+#, c-format
+msgid "E60: Too many complex %s{...}s"
+msgstr "E60: Hay demasiados %s{...}s complejos"
+
+#: regexp.c:1534
+#, c-format
+msgid "E61: Nested %s*"
+msgstr "E61: Anidado %s*"
+
+#: regexp.c:1537
+#, c-format
+msgid "E62: Nested %s%c"
+msgstr "E62: Anidado %s%c"
+
+#: regexp.c:1657
+msgid "E63: invalid use of \\_"
+msgstr "E63: Uso inválido de \\_"
+
+#: regexp.c:1713
+#, c-format
+msgid "E64: %s%c follows nothing"
+msgstr "E64: %s%c no sigue a nada"
+
+#: regexp.c:1769
+msgid "E65: Illegal back reference"
+msgstr "E65: Referencia inversa ilegal"
+
+#: regexp.c:1782
+msgid "E66: \\z( not allowed here"
+msgstr "E66: No se permite \\z( aquí"
+
+#: regexp.c:1801
+msgid "E67: \\z1 et al. not allowed here"
+msgstr "E67: \\z1 et al. no se permiten aquí"
+
+# Es preferible traducir "invalid" por "no [es] válido" pues "inválido" no es lo suficientemente claro. Además, no es políticamente correcto :-) ALV
+#: regexp.c:1813
+msgid "E68: Invalid character after \\z"
+msgstr "E68: Hay un carácter no válido después de \\z"
+
+#: regexp.c:1865
+#, c-format
+msgid "E69: Missing ] after %s%%["
+msgstr "E69: Falta ] después de %s%%["
+
+#: regexp.c:1881
+#, c-format
+msgid "E70: Empty %s%%[]"
+msgstr "E70: %s%%[] vacío"
+
+#: regexp.c:1926
+#, c-format
+msgid "E678: Invalid character after %s%%[dxouU]"
+msgstr "E678: Carácter no válido después de %s%%[dxouU]"
+
+#: regexp.c:1997
+#, c-format
+msgid "E71: Invalid character after %s%%"
+msgstr "E71: Carácter ilegal después de %s%%"
+
+#: regexp.c:2290
+#, c-format
+msgid "E769: Missing ] after %s["
+msgstr "E769: Falta ] después de %s["
+
+#: regexp.c:2978
+#, c-format
+msgid "E554: Syntax error in %s{...}"
+msgstr "E554: Error de sintaxis en %s{...}"
+
+#: regexp.c:3821
+msgid "External submatches:\n"
+msgstr "Sub-coincidencias externas:\n"
+
+#: screen.c:9072
+msgid " VREPLACE"
+msgstr " REEMPLAZO VIRTUAL"
+
+#: screen.c:9076
+msgid " REPLACE"
+msgstr " REEMPLAZAR"
+
+#: screen.c:9081
+msgid " REVERSE"
+msgstr " INVERTIR"
+
+#: screen.c:9083
+msgid " INSERT"
+msgstr " INSERTAR"
+
+#: screen.c:9086
+msgid " (insert)"
+msgstr " (insertar)"
+
+#: screen.c:9088
+msgid " (replace)"
+msgstr " (reemplazar)"
+
+#: screen.c:9090
+msgid " (vreplace)"
+msgstr " (reemplazo virtual)"
+
+#: screen.c:9093
+msgid " Hebrew"
+msgstr " hebreo"
+
+#: screen.c:9104
+msgid " Arabic"
+msgstr " árabe"
+
+#: screen.c:9107
+msgid " (lang)"
+msgstr " (idioma)"
+
+#: screen.c:9111
+msgid " (paste)"
+msgstr " (pegar)"
+
+#: screen.c:9124
+msgid " VISUAL"
+msgstr " VISUAL"
+
+#: screen.c:9125
+msgid " VISUAL LINE"
+msgstr " LÃNEA VISUAL"
+
+#: screen.c:9126
+msgid " VISUAL BLOCK"
+msgstr " BLOQUE VISUAL"
+
+#: screen.c:9127
+msgid " SELECT"
+msgstr " SELECCIONAR"
+
+#: screen.c:9128
+msgid " SELECT LINE"
+msgstr " SELECCIONAR LÃNEA"
+
+#: screen.c:9129
+msgid " SELECT BLOCK"
+msgstr " SELECCIONAR BLOQUE"
+
+#: screen.c:9145 screen.c:9211
+msgid "recording"
+msgstr "grabando"
+
+#: search.c:562
+#, c-format
+msgid "E383: Invalid search string: %s"
+msgstr "E383: La cadena de búsqueda no es válida: %s"
+
+#: search.c:983
+#, c-format
+msgid "E384: search hit TOP without match for: %s"
+msgstr "E384: La búsqueda ha llegado al PRINCIPIO sin coincidir con: %s"
+
+#: search.c:986
+#, c-format
+msgid "E385: search hit BOTTOM without match for: %s"
+msgstr "E385: La búsqueda ha llegado al FINAL sin coincidir con: %s"
+
+#: search.c:1415
+msgid "E386: Expected '?' or '/' after ';'"
+msgstr "E386: Esperaba \"?\" o \"/\" después de \";\""
+
+#: search.c:4681
+msgid " (includes previously listed match)"
+msgstr " (incluye la coincidencia mostrada previamente)"
+
+# cursor at status line
+#. cursor at status line
+#: search.c:4701
+msgid "--- Included files "
+msgstr "--- Archivos incluidos "
+
+#: search.c:4703
+msgid "not found "
+msgstr "no se encontrṕ"
+
+#: search.c:4704
+msgid "in path ---\n"
+msgstr "en la ruta ---\n"
+
+#: search.c:4761
+msgid " (Already listed)"
+msgstr " (Ya está listado)"
+
+#: search.c:4763
+msgid " NOT FOUND"
+msgstr " NO SE ENCONTRÓ"
+
+#: search.c:4817
+#, c-format
+msgid "Scanning included file: %s"
+msgstr "Explorando el archivo incluido: %s"
+
+#: search.c:4826
+#, c-format
+msgid "Searching included file %s"
+msgstr "Buscando en el archivo incluido: %s"
+
+#: search.c:5049
+msgid "E387: Match is on current line"
+msgstr "E387: La coincidencia está en la línea bajo el cursor"
+
+#: search.c:5193
+msgid "All included files were found"
+msgstr "Se han encontrado todos los archivos incluidos"
+
+#: search.c:5195
+msgid "No included files"
+msgstr "No hay archivos incluidos"
+
+#: search.c:5211
+msgid "E388: Couldn't find definition"
+msgstr "E388: La definición no se encontró"
+
+#: search.c:5213
+msgid "E389: Couldn't find pattern"
+msgstr "E389: El patrón no se encontró"
+
+#: search.c:5391
+msgid "Substitute "
+msgstr "Sustitución"
+
+#: search.c:5404
+#, c-format
+msgid ""
+"\n"
+"# Last %sSearch Pattern:\n"
+"~"
+msgstr ""
+"\n"
+"# Último %sPatrón de búsqueda:\n"
+"~"
+
+#: spell.c:989
+msgid "E759: Format error in spell file"
+msgstr "E759: Error de formato en el archivo de ortografía"
+
+#: spell.c:990
+msgid "E758: Truncated spell file"
+msgstr "E758: Archivo de ortografía truncado"
+
+#: spell.c:991
+#, c-format
+msgid "Trailing text in %s line %d: %s"
+msgstr "Texto sobrante en %s línea %d: %s"
+
+#: spell.c:992
+#, c-format
+msgid "Affix name too long in %s line %d: %s"
+msgstr "Nombre de afijo demasiado largo en %s línea %d: %s"
+
+#: spell.c:993
+msgid "E761: Format error in affix file FOL, LOW or UPP"
+msgstr "E761: Error de formato en el archivo de afijos FOL, LOW o UPP"
+
+#: spell.c:994
+msgid "E762: Character in FOL, LOW or UPP is out of range"
+msgstr "E762: El carácter en FOL, LOW o UPP está fuera de rango"
+
+#: spell.c:995
+msgid "Compressing word tree..."
+msgstr "Comprimiendo el árbol de palabras..."
+
+#: spell.c:2149
+msgid "E756: Spell checking is not enabled"
+msgstr "E756: La corrección ortográfica está desactivada"
+
+#: spell.c:2502
+#, 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"
+"or \"%s.ascii.spl\""
+
+#: spell.c:2776
+#, c-format
+msgid "Reading spell file \"%s\""
+msgstr "Leyendo archivo de ortografía \"%s\""
+
+#: spell.c:2808
+msgid "E757: This does not look like a spell file"
+msgstr "E757: Esto no parece un archivo de ortografía"
+
+#: spell.c:2814
+msgid "E771: Old spell file, needs to be updated"
+msgstr "E771: Archivo de ortografía obsoleto, debe actualizarlo"
+
+#: spell.c:2819
+msgid "E772: Spell file is for newer version of Vim"
+msgstr "E772: El archivo de ortografía es para una versión de Vim más reciente"
+
+#: spell.c:2922
+msgid "E770: Unsupported section in spell file"
+msgstr "E770: Sección no compatible en el archivo de ortografía"
+
+#: spell.c:4417
+#, c-format
+msgid "Warning: region %s not supported"
+msgstr "Advertencia: la región %s no es compatible"
+
+#: spell.c:5307
+#, c-format
+msgid "Reading affix file %s ..."
+msgstr "Leyendo el archivo de afijos \"%s\"..."
+
+#: spell.c:5355 spell.c:6699 spell.c:7278
+#, c-format
+msgid "Conversion failure for word in %s line %d: %s"
+msgstr "La conversión falló para la palabra en %s línea %d: %s"
+
+#: spell.c:5403 spell.c:7313
+#, c-format
+msgid "Conversion in %s not supported: from %s to %s"
+msgstr "La conversión en %s no es posible: de %s a %s"
+
+#: spell.c:5407 spell.c:7318
+#, c-format
+msgid "Conversion in %s not supported"
+msgstr "La conversión a %s no es posible en esta versión"
+
+#: spell.c:5420
+#, c-format
+msgid "Invalid value for FLAG in %s line %d: %s"
+msgstr "El valor para \"FLAG\" no es válido en la %s línea %d: %s"
+
+#: spell.c:5433
+#, c-format
+msgid "FLAG after using flags in %s line %d: %s"
+msgstr "\"FLAG\" después de usar parámetros en %s línea %d: %s"
+
+#: spell.c:5524
+#, c-format
+msgid ""
+"Defining COMPOUNDFORBIDFLAG after PFX item may give wrong results in %s line "
+"%d"
+msgstr ""
+"Definir COMPOUNDFORBIDFLAG después de un elemento PFX puede dar resultados "
+"erróneos\n"
+"en %s línea %d"
+
+#: spell.c:5533
+#, c-format
+msgid ""
+"Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in %s line "
+"%d"
+msgstr ""
+"Definir COMPOUNDPERMITFLAG después de un ítem PFX puede dar resultados "
+"erróneos\n"
+"en %s línea %d"
+
+#: spell.c:5554
+#, c-format
+msgid "Wrong COMPOUNDRULES value in %s line %d: %s"
+msgstr "Valor equivocado de COMPOUNDRULES %s línea %d: %s"
+
+#: spell.c:5581
+#, c-format
+msgid "Wrong COMPOUNDWORDMAX value in %s line %d: %s"
+msgstr "Valor equivocado de COMPOUNDWORDMAX en %s línea %d: %s"
+
+#: spell.c:5589
+#, c-format
+msgid "Wrong COMPOUNDMIN value in %s line %d: %s"
+msgstr "Valor equivocado de COMPOUNDMIN en %s línea %d: %s"
+
+#: spell.c:5597
+#, c-format
+msgid "Wrong COMPOUNDSYLMAX value in %s line %d: %s"
+msgstr "Valor equivocado de COMPOUNDSYLMAX en %s línea %d: %s"
+
+#: spell.c:5619
+#, c-format
+msgid "Wrong CHECKCOMPOUNDPATTERN value in %s line %d: %s"
+msgstr "Valor equivocado de CHECKCOMPOUNDPATTERN en %s línea %d: %s"
+
+#: spell.c:5685
+#, 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"
+"en %s línea %d: %s"
+
+#: spell.c:5688
+#, c-format
+msgid "Duplicate affix in %s line %d: %s"
+msgstr "Afijo duplicado en %s línea %d: %s"
+
+#: spell.c:5710
+#, c-format
+msgid ""
+"Affix also used for BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST in %s "
+"line %d: %s"
+msgstr ""
+"Afijo usado también para BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST "
+"en\n"
+"%s línea %d: %s"
+
+#: spell.c:5734
+#, c-format
+msgid "Expected Y or N in %s line %d: %s"
+msgstr "Esperaba Y o N en %s línea %d: %s"
+
+#: spell.c:5818
+#, c-format
+msgid "Broken condition in %s line %d: %s"
+msgstr "Condición inválida en %s línea %d: %s"
+
+#: spell.c:5966
+#, c-format
+msgid "Expected REP(SAL) count in %s line %d"
+msgstr "Esperaba conteo REP(SAL) en %s línea %d"
+
+#: spell.c:6001
+#, c-format
+msgid "Expected MAP count in %s line %d"
+msgstr "Esperaba conteo MAP en %s línea %d"
+
+#: spell.c:6020
+#, c-format
+msgid "Duplicate character in MAP in %s line %d"
+msgstr "Carácter duplicado en MAP en %s línea %d"
+
+#: spell.c:6077
+#, c-format
+msgid "Unrecognized or duplicate item in %s line %d: %s"
+msgstr "Elemento no reconocido o duplicado en %s línea %d: %s"
+
+#: spell.c:6105
+#, c-format
+msgid "Missing FOL/LOW/UPP line in %s"
+msgstr "Falta una línea FOL/LOW/UPP en %s"
+
+#: spell.c:6131
+msgid "COMPOUNDSYLMAX used without SYLLABLE"
+msgstr "COMPOUNDSYLMAX usado sin SYLLABLE"
+
+#: spell.c:6149
+msgid "Too many postponed prefixes"
+msgstr "Hay demasiados prefijos postpuestos"
+
+#: spell.c:6151
+msgid "Too many compound flags"
+msgstr "Demasiados parámetros compuestos"
+
+#: spell.c:6153
+msgid "Too many postponed prefixes and/or compound flags"
+msgstr "Demasiados prefijos postpuestos y/o \"flags\" compuestos"
+
+#: spell.c:6165
+#, c-format
+msgid "Missing SOFO%s line in %s"
+msgstr "Falta una línea SOFO%s en %s"
+
+#: spell.c:6168
+#, c-format
+msgid "Both SAL and SOFO lines in %s"
+msgstr "Líneas SAL y SOFO en %s"
+
+#: spell.c:6275
+#, c-format
+msgid "Flag is not a number in %s line %d: %s"
+msgstr "La marca no es un número en %s línea %d: %s"
+
+#: spell.c:6278
+#, c-format
+msgid "Illegal flag in %s line %d: %s"
+msgstr "Marca ilegal en %s line %d: %s"
+
+#: spell.c:6495 spell.c:6508
+#, c-format
+msgid "%s value differs from what is used in another .aff file"
+msgstr "El valor %s difiere de los que se usa en otro archivo .aff"
+
+#: spell.c:6660
+#, c-format
+msgid "Reading dictionary file %s ..."
+msgstr "Leyendo el archivo de diccionario %s ..."
+
+#: spell.c:6669
+#, c-format
+msgid "E760: No word count in %s"
+msgstr "E760: No hay cuenta de palabras en %s"
+
+#: spell.c:6740
+#, c-format
+msgid "line %6d, word %6d - %s"
+msgstr "línea %6d, palabra %6d - %s"
+
+#: spell.c:6764
+#, c-format
+msgid "Duplicate word in %s line %d: %s"
+msgstr "Palabra duplicada en %s línea %d: %s"
+
+#: spell.c:6767
+#, c-format
+msgid "First duplicate word in %s line %d: %s"
+msgstr "Primera palabra duplicada en %s line %d: %s"
+
+#: spell.c:6822
+#, c-format
+msgid "%d duplicate word(s) in %s"
+msgstr "%d palabra(s) duplicada(s) en %s"
+
+#: spell.c:6824
+#, c-format
+msgid "Ignored %d word(s) with non-ASCII characters in %s"
+msgstr "Ignorando %d palabra(s) con caracteres no-ASCII en %s"
+
+#: spell.c:7247
+#, c-format
+msgid "Reading word file %s ..."
+msgstr "Leyendo archivo de palabras \"%s\" ..."
+
+#: spell.c:7297
+#, c-format
+msgid "Duplicate /encoding= line ignored in %s line %d: %s"
+msgstr "Ignorando línea /encoding= duplicada en %s line %d: %s"
+
+#: spell.c:7300
+#, c-format
+msgid "/encoding= line after word ignored in %s line %d: %s"
+msgstr "Ignorando línea /encoding= después de palabra en %s línea %d: %s"
+
+#: spell.c:7327
+#, c-format
+msgid "Duplicate /regions= line ignored in %s line %d: %s"
+msgstr "Ignorando línea /regions= en %s línea %d: %s"
+
+#: spell.c:7333
+#, c-format
+msgid "Too many regions in %s line %d: %s"
+msgstr "Demasiadas regiones en %s línea %d: %s"
+
+#: spell.c:7347
+#, c-format
+msgid "/ line ignored in %s line %d: %s"
+msgstr "Ignorando línea / en %s línea %d: %s"
+
+#: spell.c:7377
+#, c-format
+msgid "Invalid region nr in %s line %d: %s"
+msgstr "Región nr no válida en %s línea %d: %s"
+
+#: spell.c:7385
+#, c-format
+msgid "Unrecognized flags in %s line %d: %s"
+msgstr "Parámetros no reconocidos en %s línea %d: %s"
+
+#: spell.c:7415
+#, c-format
+msgid "Ignored %d words with non-ASCII characters"
+msgstr "Ignorando %d palabras con caracteres no-ASCII"
+
+#: spell.c:7876
+#, c-format
+msgid "Compressed %d of %d nodes; %d (%d%%) remaining"
+msgstr "Comprimiendo %d de %d nodos; faltan %d (%d%%)"
+
+#: spell.c:8720
+msgid "Reading back spell file..."
+msgstr "Releyendo el archivo de ortografía ..."
+
+#.
+#. * Go through the trie of good words, soundfold each word and add it to
+#. * the soundfold trie.
+#.
+#: spell.c:8741
+msgid "Performing soundfolding..."
+msgstr "Ejecutando compresión fonética"
+
+#: spell.c:8754
+#, c-format
+msgid "Number of words after soundfolding: %ld"
+msgstr "Número de palabras después de la compresión fonética: %ld"
+
+#: spell.c:8879
+#, c-format
+msgid "Total number of words: %d"
+msgstr "Número total de palabras: %d"
+
+#: spell.c:9096
+#, c-format
+msgid "Writing suggestion file %s ..."
+msgstr "Escribiendo el archivo de sugerencias %s ..."
+
+#: spell.c:9157 spell.c:9418
+#, c-format
+msgid "Estimated runtime memory use: %d bytes"
+msgstr "Uso de memoria estimado al usar: %d bytes"
+
+#: spell.c:9289
+msgid "E751: Output file name must not have region name"
+msgstr ""
+"E751: El nombre del archivo de salida no debe contener un nombre de región"
+
+#: spell.c:9291
+msgid "E754: Only up to 8 regions supported"
+msgstr "E754: Solo se pueden usar hasta 8 regiones"
+
+#: spell.c:9321
+#, c-format
+msgid "E755: Invalid region in %s"
+msgstr "E755: Región no válida en %s"
+
+#: spell.c:9392
+msgid "Warning: both compounding and NOBREAK specified"
+msgstr "Advertencia: Se especificó \"compounding\" y NOBREAK"
+
+#: spell.c:9411
+#, c-format
+msgid "Writing spell file %s ..."
+msgstr "Escribiendo archivo de ortografía \"%s\" ..."
+
+#: spell.c:9416
+msgid "Done!"
+msgstr "¡Listo!"
+
+#: spell.c:9543
+#, c-format
+msgid "E765: 'spellfile' does not have %ld entries"
+msgstr "E765: 'spellfile' no tiene entradas %ld"
+
+#: spell.c:9588
+#, c-format
+msgid "Word removed from %s"
+msgstr "Eliminando palabra de %s"
+
+#: spell.c:9633
+#, c-format
+msgid "Word added to %s"
+msgstr "Añadiendo palabra en \"%s\""
+
+#: spell.c:9946
+msgid "E763: Word characters differ between spell files"
+msgstr ""
+"E763: Los caracteres de la palabra difieren entre archivos de ortografía"
+
+#: spell.c:10321
+msgid "Sorry, no suggestions"
+msgstr "Lo siento, no hay sugerencias"
+
+#: spell.c:10325
+#, c-format
+msgid "Sorry, only %ld suggestions"
+msgstr "Lo siento, solo hay %ld sugerencias"
+
+#. for when 'cmdheight' > 1
+#. avoid more prompt
+#: spell.c:10346
+#, c-format
+msgid "Change \"%.*s\" to:"
+msgstr "\"%.*s\" cambió a:"
+
+#: spell.c:10386
+#, c-format
+msgid " < \"%.*s\""
+msgstr " < \"%.*s\""
+
+#: spell.c:10562
+msgid "E752: No previous spell replacement"
+msgstr "E752: No hay un reemplazo de ortografía previo"
+
+#: spell.c:10612
+#, c-format
+msgid "E753: Not found: %s"
+msgstr "E753: No se encontró: %s"
+
+#: spell.c:11032
+#, c-format
+msgid "E778: This does not look like a .sug file: %s"
+msgstr "E778: Esto no se parece a un archivo .sug: %s"
+
+#: spell.c:11039
+#, c-format
+msgid "E779: Old .sug file, needs to be updated: %s"
+msgstr "E779: Archivo .sug obsoleto, necesita una actualización: %s"
+
+#: spell.c:11045
+#, c-format
+msgid "E780: .sug file is for newer version of Vim: %s"
+msgstr "E780: El archivo .sug es para una versión más reciente de Vim: %s"
+
+#: spell.c:11055
+#, c-format
+msgid "E781: .sug file doesn't match .spl file: %s"
+msgstr "E781: El archivo .sug no corresponde al archivo .spl: %s"
+
+#: spell.c:11068
+#, c-format
+msgid "E782: error while reading .sug file: %s"
+msgstr "E782: Error al leer archivo .sig: %s"
+
+#. This should have been checked when generating the .spl
+#. * file.
+#: spell.c:13765
+msgid "E783: duplicate char in MAP entry"
+msgstr "E783: carácter duplicado en entrada MAP"
+
+#: syntax.c:3245 syntax.c:3271
+#, c-format
+msgid "E390: Illegal argument: %s"
+msgstr "E390: Argumento ilegal: %s"
+
+#: syntax.c:3453
+#, c-format
+msgid "E391: No such syntax cluster: %s"
+msgstr "E391: No existe tal agrupamiento sintáctico: %s"
+
+#: syntax.c:3612
+msgid "No Syntax items defined for this buffer"
+msgstr "No hay elementos sintácticos definidos para este búfer"
+
+#: syntax.c:3620
+msgid "syncing on C-style comments"
+msgstr "Sincronizando con los comentarios de estilo \"C\""
+
+#: syntax.c:3628
+msgid "no syncing"
+msgstr "no hay sincronización"
+
+#: syntax.c:3631
+msgid "syncing starts "
+msgstr "Comenzando sincronización"
+
+#: syntax.c:3633 syntax.c:3708
+msgid " lines before top line"
+msgstr " líneas antes de la línea superior"
+
+#: syntax.c:3638
+msgid ""
+"\n"
+"--- Syntax sync items ---"
+msgstr ""
+"\n"
+"--- Elementos de sincronización de sintaxis ---"
+
+#: syntax.c:3643
+msgid ""
+"\n"
+"syncing on items"
+msgstr ""
+"\n"
+"sincronizando con los elementos"
+
+#: syntax.c:3649
+msgid ""
+"\n"
+"--- Syntax items ---"
+msgstr ""
+"\n"
+"--- Elementos sintácticos ---"
+
+#: syntax.c:3672
+#, c-format
+msgid "E392: No such syntax cluster: %s"
+msgstr "E392: No existe tal agrupamiento sintáctico: %s"
+
+#: syntax.c:3698
+msgid "minimal "
+msgstr "mínimo"
+
+#: syntax.c:3705
+msgid "maximal "
+msgstr "máximo"
+
+#: syntax.c:3717
+msgid "; match "
+msgstr "; coincide"
+
+#: syntax.c:3719
+msgid " line breaks"
+msgstr " líneas de quiebre"
+
+#: syntax.c:4347
+msgid "E395: contains argument not accepted here"
+msgstr "E395: el contenido del argumento no se acepta aquí"
+
+#: syntax.c:4358
+msgid "E396: containedin argument not accepted here"
+msgstr "E396: el argumento \"containedin\" no se acepta aquí"
+
+#: syntax.c:4380
+msgid "E393: group[t]here not accepted here"
+msgstr "E393: \"grouphere\" y \"groupthere\" no son válidos aquí"
+
+#: syntax.c:4404
+#, c-format
+msgid "E394: Didn't find region item for %s"
+msgstr "E394: No se encuentra el elemento de la región para %s"
+
+#: syntax.c:4481
+msgid "E397: Filename required"
+msgstr "E397: Debe proporcionar un nombre de archivo"
+
+#: syntax.c:4603
+#, c-format
+msgid "E789: Missing ']': %s"
+msgstr "E789: Falta un ']': %s"
+
+#: syntax.c:4843
+#, c-format
+msgid "E398: Missing '=': %s"
+msgstr "E398: Falta un '=': %s"
+
+#: syntax.c:5002
+#, c-format
+msgid "E399: Not enough arguments: syntax region %s"
+msgstr "E399: Argumentos insuficientes: región de sintaxis %s"
+
+#: syntax.c:5336
+msgid "E400: No cluster specified"
+msgstr "E400: No se ha especificado una agrupación"
+
+#: syntax.c:5373
+#, c-format
+msgid "E401: Pattern delimiter not found: %s"
+msgstr "E401: No hay un delimitador de patrón: %s"
+
+#: syntax.c:5448
+#, c-format
+msgid "E402: Garbage after pattern: %s"
+msgstr "E402: Basura después del patrón: %s"
+
+#: syntax.c:5537
+msgid "E403: syntax sync: line continuations pattern specified twice"
+msgstr ""
+"E403: Sincronización de sintaxis: Se especificó dos veces un\n"
+"patrón de continuación de línea"
+
+#: syntax.c:5594
+#, c-format
+msgid "E404: Illegal arguments: %s"
+msgstr "E404: Argumentos ilegales: %s"
+
+#: syntax.c:5644
+#, c-format
+msgid "E405: Missing equal sign: %s"
+msgstr "E405: Falta el signo igual: %s"
+
+#: syntax.c:5650
+#, c-format
+msgid "E406: Empty argument: %s"
+msgstr "E406: Argumento vacío: %s"
+
+#: syntax.c:5676
+#, c-format
+msgid "E407: %s not allowed here"
+msgstr "E407: %s no se permite aquí"
+
+#: syntax.c:5683
+#, c-format
+msgid "E408: %s must be first in contains list"
+msgstr "E408: %s debe ser el primero en la lista de contenido"
+
+#: syntax.c:5753
+#, c-format
+msgid "E409: Unknown group name: %s"
+msgstr "E409: Nombre de grupo desconocido: %s"
+
+#: syntax.c:5988
+#, c-format
+msgid "E410: Invalid :syntax subcommand: %s"
+msgstr "E410: Suborden \":syntax\" no válido: %s"
+
+#: syntax.c:6475
+msgid "E679: recursive loop loading syncolor.vim"
+msgstr "E679: bucle recursivo al cargar \"syncolor.vim\""
+
+#: syntax.c:6602
+#, c-format
+msgid "E411: highlight group not found: %s"
+msgstr "E411: grupo de resaltado no encontrado: %s"
+
+#: syntax.c:6626
+#, c-format
+msgid "E412: Not enough arguments: \":highlight link %s\""
+msgstr "E412: Argumentos insuficientes: \":highlight link %s\""
+
+#: syntax.c:6633
+#, c-format
+msgid "E413: Too many arguments: \":highlight link %s\""
+msgstr "E413: Demasiados argumentos: \":highlight link %s\""
+
+#: syntax.c:6653
+msgid "E414: group has settings, highlight link ignored"
+msgstr "E414: Esta grupo está configurado, se ignora el enlace resaltado"
+
+#: syntax.c:6785
+#, c-format
+msgid "E415: unexpected equal sign: %s"
+msgstr "E415: Signo \"=\" inesperado: %s"
+
+#: syntax.c:6821
+#, c-format
+msgid "E416: missing equal sign: %s"
+msgstr "E416: Falta el signo \"=\": %s"
+
+#: syntax.c:6849
+#, c-format
+msgid "E417: missing argument: %s"
+msgstr "E417: Falta el argumento: %s"
+
+#: syntax.c:6886
+#, c-format
+msgid "E418: Illegal value: %s"
+msgstr "E418: Valor ilegal: %s"
+
+#: syntax.c:7005
+msgid "E419: FG color unknown"
+msgstr "E419: Color en primer plano desconocido"
+
+#: syntax.c:7016
+msgid "E420: BG color unknown"
+msgstr "E420: Color de fondo desconocido"
+
+#: syntax.c:7077
+#, c-format
+msgid "E421: Color name or number not recognized: %s"
+msgstr "E421: Nombre o número de color desconocido: %s"
+
+#: syntax.c:7304
+#, c-format
+msgid "E422: terminal code too long: %s"
+msgstr "E422: Código de terminal demasiado largo: %s"
+
+#: syntax.c:7351
+#, c-format
+msgid "E423: Illegal argument: %s"
+msgstr "E423: Argumento ilegal: %s"
+
+#: syntax.c:7912
+msgid "E424: Too many different highlighting attributes in use"
+msgstr "E424: Hay demasiados atributos de resaltado sintáctico en uso"
+
+#: syntax.c:8649
+msgid "E669: Unprintable character in group name"
+msgstr "E669: Carácter no imprimible en el nombre del grupo"
+
+# This is an error, but since there previously was no check only
+# * give a warning.
+#: syntax.c:8657
+msgid "W18: Invalid character in group name"
+msgstr "W18: Hay un carácter no válido en el nombre del grupo"
+
+#: tag.c:85
+msgid "E555: at bottom of tag stack"
+msgstr "E555: En el final de la pila de etiquetas"
+
+#: tag.c:86
+msgid "E556: at top of tag stack"
+msgstr "E556: En el principio de la pila de etiquetas"
+
+#: tag.c:434
+msgid "E425: Cannot go before first matching tag"
+msgstr "E425: No se pudo ir antes de la primer etiqueta coincidente"
+
+#: tag.c:583
+#, c-format
+msgid "E426: tag not found: %s"
+msgstr "E426: No se encontró la etiqueta: %s"
+
+#: tag.c:616
+msgid " # pri kind tag"
+msgstr " # etiqueta tipo \"pri\""
+
+#: tag.c:619
+msgid "file\n"
+msgstr "archivo\n"
+
+#: tag.c:953
+msgid "E427: There is only one matching tag"
+msgstr "E427: Sólo coincide una etiqueta"
+
+#: tag.c:955
+msgid "E428: Cannot go beyond last matching tag"
+msgstr "E428: No se pudo ir más allá de la última etiqueta coincidente"
+
+#: tag.c:979
+#, c-format
+msgid "File \"%s\" does not exist"
+msgstr "No existe el archivo \"%s\""
+
+# Give an indication of the number of matching tags
+#. Give an indication of the number of matching tags
+#: tag.c:991
+#, c-format
+msgid "tag %d of %d%s"
+msgstr "etiqueta %d de %d%s"
+
+#: tag.c:994
+msgid " or more"
+msgstr " o más"
+
+#: tag.c:996
+msgid " Using tag with different case!"
+msgstr ""
+" ¡Está usando una etiqueta con mayúsculas y minúsculas que no coinciden!"
+
+#: tag.c:1051
+#, c-format
+msgid "E429: File \"%s\" does not exist"
+msgstr "E429: El archivo \"%s\" no existe"
+
+# Highlight title
+#. Highlight title
+#: tag.c:1119
+msgid ""
+"\n"
+" # TO tag FROM line in file/text"
+msgstr ""
+"\n"
+" # A etiqueta DESDE la línea en el archivo/texto"
+
+#: tag.c:1546
+#, c-format
+msgid "Searching tags file %s"
+msgstr "Buscando el archivo de etiquetas %s"
+
+#: tag.c:1737
+#, c-format
+msgid "E430: Tag file path truncated for %s\n"
+msgstr "E430: La ruta del archivo de etiquetas %s está truncada\n"
+
+#: tag.c:2388
+#, c-format
+msgid "E431: Format error in tags file \"%s\""
+msgstr "E431: Error de formato en el archivo de etiquetas \"%s\""
+
+#: tag.c:2392
+#, c-format
+msgid "Before byte %ld"
+msgstr "Adelante del byte %ld"
+
+#: tag.c:2425
+#, c-format
+msgid "E432: Tags file not sorted: %s"
+msgstr "E432: Archivo de etiquetas sin ordenar: %s"
+
+# never opened any tags file
+#. never opened any tags file
+#: tag.c:2469
+msgid "E433: No tags file"
+msgstr "E433: No hay archivo de etiquetas"
+
+#: tag.c:2748
+msgid "Ignoring long line in tags file"
+msgstr "Ignorando la línea larga en el archivo de etiquetas"
+
+#: tag.c:3257
+msgid "E434: Can't find tag pattern"
+msgstr "E434: No se pudo encontrar el patrón de la etiqueta"
+
+#: tag.c:3268
+msgid "E435: Couldn't find tag, just guessing!"
+msgstr "E435: No se pudo encontrar la etiqueta. ¡Estoy adivinando!"
+
+#: term.c:1793
+msgid "' not known. Available builtin terminals are:"
+msgstr "' desconocido. Los terminales incorporados disponibles son:"
+
+#: term.c:1817
+msgid "defaulting to '"
+msgstr "Usando ' por defecto"
+
+#: term.c:2172
+msgid "E557: Cannot open termcap file"
+msgstr "E557: No se pudo abrir el archivo \"termcap\""
+
+#: term.c:2176
+msgid "E558: Terminal entry not found in terminfo"
+msgstr "E558: No he encontrado la definición del terminal en \"terminfo\""
+
+#: term.c:2178
+msgid "E559: Terminal entry not found in termcap"
+msgstr "E559: No he encontrado la definición del terminal en \"termcap\""
+
+#: term.c:2337
+#, c-format
+msgid "E436: No \"%s\" entry in termcap"
+msgstr "E436: la entrada %s no existe en el archivo \"termcap\""
+
+#: term.c:2811
+msgid "E437: terminal capability \"cm\" required"
+msgstr "E437: Se necesita la capacidad \"cm\" en el terminal"
+
+# Highlight title
+#. Highlight title
+#: term.c:5280
+msgid ""
+"\n"
+"--- Terminal keys ---"
+msgstr ""
+"\n"
+"--- Teclas de la terminal ---"
+
+#: ui.c:284
+msgid "new shell started\n"
+msgstr "Iniciado nuevo intérprete de órdenes\n"
+
+#: ui.c:1886
+msgid "Vim: Error reading input, exiting...\n"
+msgstr "Vim: error al leer la entrada, saliendo...\n"
+
+#: ui.c:2409
+msgid "Used CUT_BUFFER0 instead of empty selection"
+msgstr "Se ha usado \"CUT_BUFFER0\" en vez de una selección vacía"
+
+# must display the prompt
+#. must display the prompt
+#: undo.c:645
+msgid "No undo possible; continue anyway"
+msgstr "No es posible deshacer; continuando de todos modos"
+
+#: undo.c:727 undo.c:937
+msgid "Already at oldest change"
+msgstr "Este es el cambio más antiguo"
+
+#: undo.c:742 undo.c:939
+msgid "Already at newest change"
+msgstr "Este es el cambio más nuevo"
+
+#: undo.c:930
+#, c-format
+msgid "Undo number %ld not found"
+msgstr "No se encontró el número de \"deshacer\" %ld"
+
+#: undo.c:1100
+msgid "E438: u_undo: line numbers wrong"
+msgstr "E438: \"u_undo\": números de línea erróneos"
+
+#: undo.c:1338
+msgid "more line"
+msgstr "Una línea más"
+
+#: undo.c:1340
+msgid "more lines"
+msgstr "líneas más"
+
+#: undo.c:1342
+msgid "line less"
+msgstr "una línea menos"
+
+#: undo.c:1344
+msgid "fewer lines"
+msgstr "líneas menos"
+
+#: undo.c:1349
+msgid "change"
+msgstr "cambio"
+
+#: undo.c:1351
+msgid "changes"
+msgstr "cambios"
+
+#: undo.c:1375
+#, c-format
+msgid "%ld %s; %s #%ld %s"
+msgstr "%ld %s; %s #%ld %s"
+
+#: undo.c:1378
+msgid "before"
+msgstr "antes"
+
+#: undo.c:1378
+msgid "after"
+msgstr "después"
+
+#: undo.c:1486
+msgid "Nothing to undo"
+msgstr "Nada que hacer"
+
+#: undo.c:1492
+msgid "number changes time"
+msgstr "el número modifica el tiempo"
+
+#: undo.c:1525
+#, c-format
+msgid "%ld seconds ago"
+msgstr "hace %ld segundos"
+
+#: undo.c:1541
+msgid "E790: undojoin is not allowed after undo"
+msgstr "E790: \"undojoin\" no está permitido después de \"undo\""
+
+#: undo.c:1591
+msgid "E439: undo list corrupt"
+msgstr "E439: la lista de deshacer se ha dañado"
+
+#: undo.c:1623
+msgid "E440: undo line missing"
+msgstr "E440: falta la línea deshacer"
+
+# Only MS VC 4.1 and earlier can do Win32s
+#. Only MS VC 4.1 and earlier can do Win32s
+#: version.c:1366
+msgid ""
+"\n"
+"MS-Windows 16/32-bit GUI version"
+msgstr ""
+"\n"
+"Versión de interfaz gráfica de 16/32 bits para MS-Windows"
+
+#: version.c:1369
+msgid ""
+"\n"
+"MS-Windows 64-bit GUI version"
+msgstr ""
+"\n"
+"Versión de interfaz gráfica de 64 bits para MS-Windows"
+
+#: version.c:1371
+msgid ""
+"\n"
+"MS-Windows 32-bit GUI version"
+msgstr ""
+"\n"
+"Versión de interfaz gráfica de 32 bits para MS-Windows"
+
+#: version.c:1375
+msgid " in Win32s mode"
+msgstr " en modo Win32s"
+
+#: version.c:1377
+msgid " with OLE support"
+msgstr " con compatibilidad con OLE"
+
+#: version.c:1381
+msgid ""
+"\n"
+"MS-Windows 64-bit console version"
+msgstr ""
+"\n"
+"Versión de 64 bits para consola de MS-Windows"
+
+#: version.c:1383
+msgid ""
+"\n"
+"MS-Windows 32-bit console version"
+msgstr ""
+"\n"
+"Versión de 32 bits para consola de MS-Windows"
+
+#: version.c:1388
+msgid ""
+"\n"
+"MS-Windows 16-bit version"
+msgstr ""
+"\n"
+"Versión de 16 bits para MS-Windows"
+
+#: version.c:1392
+msgid ""
+"\n"
+"32-bit MS-DOS version"
+msgstr ""
+"\n"
+"Versión de 32 bits para MS-DOS"
+
+#: version.c:1394
+msgid ""
+"\n"
+"16-bit MS-DOS version"
+msgstr ""
+"\n"
+"Versión de 16 bits para MS-DOS"
+
+#: version.c:1400
+msgid ""
+"\n"
+"MacOS X (unix) version"
+msgstr ""
+"\n"
+"Versión para X (Unix) para MacOS"
+
+#: version.c:1402
+msgid ""
+"\n"
+"MacOS X version"
+msgstr ""
+"\n"
+"Versión para MacOS X"
+
+#: version.c:1405
+msgid ""
+"\n"
+"MacOS version"
+msgstr ""
+"\n"
+"Versión para MacOS"
+
+#: version.c:1410
+msgid ""
+"\n"
+"RISC OS version"
+msgstr ""
+"\n"
+"Versión para RISC OS"
+
+#: version.c:1413
+msgid ""
+"\n"
+"OpenVMS version"
+msgstr ""
+"\n"
+"Versión para OpenVMS"
+
+#: version.c:1428
+msgid ""
+"\n"
+"Included patches: "
+msgstr ""
+"\n"
+"Parches incluidos: "
+
+#: version.c:1455
+msgid ""
+"\n"
+"Extra patches: "
+msgstr ""
+"\n"
+"Parches adicionales: "
+
+#: version.c:1467 version.c:1831
+msgid "Modified by "
+msgstr "Modificado por "
+
+#: version.c:1474
+msgid ""
+"\n"
+"Compiled "
+msgstr ""
+"\n"
+"Compilado "
+
+#: version.c:1477
+msgid "by "
+msgstr "por "
+
+#: version.c:1489
+msgid ""
+"\n"
+"Huge version "
+msgstr ""
+"\n"
+"Versión \"enorme\" "
+
+#: version.c:1492
+msgid ""
+"\n"
+"Big version "
+msgstr ""
+"\n"
+"Versión \"grande\" "
+
+#: version.c:1495
+msgid ""
+"\n"
+"Normal version "
+msgstr ""
+"\n"
+"Versión \"normal\" "
+
+#: version.c:1498
+msgid ""
+"\n"
+"Small version "
+msgstr ""
+"\n"
+"Versión \"pequeña\" "
+
+#: version.c:1500
+msgid ""
+"\n"
+"Tiny version "
+msgstr ""
+"\n"
+"Versión \"diminuta\" "
+
+#: version.c:1506
+msgid "without GUI."
+msgstr "sin interfaz gráfica (GUI)."
+
+#: version.c:1511
+msgid "with GTK2-GNOME GUI."
+msgstr "con interfaz gráfica para GTK2-GNOME."
+
+#: version.c:1513
+msgid "with GTK-GNOME GUI."
+msgstr "con interfaz gráfica para GTK-GNOME."
+
+#: version.c:1517
+msgid "with GTK2 GUI."
+msgstr "con interfaz gráfica de GTK2."
+
+#: version.c:1519
+msgid "with GTK GUI."
+msgstr "con interfaz gráfica de GTK."
+
+#: version.c:1524
+msgid "with X11-Motif GUI."
+msgstr "con interfaz gráfica para X11-Motif."
+
+#: version.c:1528
+msgid "with X11-neXtaw GUI."
+msgstr "con interfaz gráfica de X11-neXtaw."
+
+#: version.c:1530
+msgid "with X11-Athena GUI."
+msgstr "con interfaz gráfica de X11-Athena."
+
+#: version.c:1534
+msgid "with Photon GUI."
+msgstr "con interfaz gráfica para Photon."
+
+#: version.c:1537
+msgid "with GUI."
+msgstr "con interfaz gráfica de usuario."
+
+#: version.c:1540
+msgid "with Carbon GUI."
+msgstr "con GUI Carbon."
+
+#: version.c:1543
+msgid "with Cocoa GUI."
+msgstr "con interfaz gráfica para Cocoa."
+
+#: version.c:1546
+msgid "with (classic) GUI."
+msgstr "con interfaz gráfica (clásica)."
+
+#: version.c:1556
+msgid " Features included (+) or not (-):\n"
+msgstr " Aspectos incluidos (+) o no (-):\n"
+
+#: version.c:1568
+msgid " system vimrc file: \""
+msgstr " archivo \"vimrc\" del sistema: \""
+
+#: version.c:1573
+msgid " user vimrc file: \""
+msgstr " archivo \"vimrc\" del usuario: \""
+
+#: version.c:1578
+msgid " 2nd user vimrc file: \""
+msgstr " 2º archivo \"vimrc\" del usuario: \""
+
+#: version.c:1583
+msgid " 3rd user vimrc file: \""
+msgstr " 3er archivo \"vimrc\" del usuario: \""
+
+#: version.c:1588
+msgid " user exrc file: \""
+msgstr " archivo \"exrc\" del usuario: \""
+
+#: version.c:1593
+msgid " 2nd user exrc file: \""
+msgstr " 2º archivo \"exrc\" del usuario: \""
+
+#: version.c:1599
+msgid " system gvimrc file: \""
+msgstr " archivo \"gvimrc\" del sistema: \""
+
+#: version.c:1603
+msgid " user gvimrc file: \""
+msgstr " archivo \"gvimrc\" del usuario: \""
+
+#: version.c:1607
+msgid "2nd user gvimrc file: \""
+msgstr " 2º archivo \"gvimrc\" del usuario: \""
+
+#: version.c:1612
+msgid "3rd user gvimrc file: \""
+msgstr "3er archivo \"gvimrc\" del usuario: \""
+
+#: version.c:1619
+msgid " system menu file: \""
+msgstr " archivo de menú del sistema: \""
+
+#: version.c:1627
+msgid " fall-back for $VIM: \""
+msgstr " predefinido para $VIM: \""
+
+#: version.c:1633
+msgid " f-b for $VIMRUNTIME: \""
+msgstr " predefinido para $VIMRUNTIME: \""
+
+#: version.c:1637
+msgid "Compilation: "
+msgstr "Compilación: "
+
+#: version.c:1643
+msgid "Compiler: "
+msgstr "Compilador: "
+
+#: version.c:1648
+msgid "Linking: "
+msgstr "Enlazado: "
+
+#: version.c:1653
+msgid " DEBUG BUILD"
+msgstr " COMPILACIÓN CON SÃMBOLOS DE DEPURACIÓN"
+
+#: version.c:1692
+msgid "VIM - Vi IMproved"
+msgstr "VIM - VI Mejorado"
+
+#: version.c:1694
+msgid "version "
+msgstr "versión "
+
+#: version.c:1695
+msgid "by Bram Moolenaar et al."
+msgstr "por Bram Moolenaar et al."
+
+#: version.c:1699
+msgid "Vim is open source and freely distributable"
+msgstr "Vim es código abierto y se puede distribuir libremente"
+
+#: version.c:1701
+msgid "Help poor children in Uganda!"
+msgstr "¡Ayude a los niños pobres de Uganda!"
+
+#: version.c:1702
+msgid "type :help iccf<Enter> for information "
+msgstr "escriba «:help iccf<Intro>» para más información "
+
+#: version.c:1704
+msgid "type :q<Enter> to exit "
+msgstr "escriba «:q<Intro>» para salir "
+
+#: version.c:1705
+msgid "type :help<Enter> or <F1> for on-line help"
+msgstr "escriba «:help<Intro>» o <F1> para obtener ayuda "
+
+#: version.c:1706
+msgid "type :help version7<Enter> for version info"
+msgstr "escriba «:help version7<Intro>» para información de la versión"
+
+#: version.c:1709
+msgid "Running in Vi compatible mode"
+msgstr "Ejecutando en modo compatible con Vi"
+
+#: version.c:1710
+msgid "type :set nocp<Enter> for Vim defaults"
+msgstr "escriba «:set nocp<Intro>» para los valores predefinidos de Vim"
+
+#: version.c:1711
+msgid "type :help cp-default<Enter> for info on this"
+msgstr "escriba «:help cp-default<Intro>» para más información"
+
+#: version.c:1726
+msgid "menu Help->Orphans for information "
+msgstr "menú Ayuda->Ayude a los niños huérfanos para más información "
+
+#: version.c:1728
+msgid "Running modeless, typed text is inserted"
+msgstr "Ejecución no modal, el texto escrito se inserta directamente"
+
+#: version.c:1729
+msgid "menu Edit->Global Settings->Toggle Insert Mode "
+msgstr "menú Editar->Opciones globales->Activar/Desactivar modo de inserción"
+
+#: version.c:1730
+msgid " for two modes "
+msgstr " para dos modos "
+
+#: version.c:1734
+msgid "menu Edit->Global Settings->Toggle Vi Compatible"
+msgstr ""
+"menú Editar->Opciones globales->Activar/Desactivar compatibilidad con Vi"
+
+#: version.c:1735
+msgid " for Vim defaults "
+msgstr ""
+" para los valores predeterminados de Vim"
+
+#: version.c:1782
+msgid "Sponsor Vim development!"
+msgstr "¡Patrocine el desarrollo de Vim!"
+
+#: version.c:1783
+msgid "Become a registered Vim user!"
+msgstr "¡Conviértase en un usuario registrado de Vim!"
+
+#: version.c:1786
+msgid "type :help sponsor<Enter> for information "
+msgstr "escriba «:help sponsor<Intro>» para más información "
+
+#: version.c:1787
+msgid "type :help register<Enter> for information "
+msgstr "escriba «:help register<Intro>» para más información "
+
+#: version.c:1789
+msgid "menu Help->Sponsor/Register for information "
+msgstr "menú Ayuda->Benefactor/Regístrese para más información"
+
+#: version.c:1799
+msgid "WARNING: Windows 95/98/ME detected"
+msgstr "ADVERTENCIA: se ha detectado Windows 95/98/ME"
+
+#: version.c:1802
+msgid "type :help windows95<Enter> for info on this"
+msgstr "escriba «:help windows95<Intro>» para más información"
+
+#: window.c:88
+msgid "Already only one window"
+msgstr "Solo hay una ventana"
+
+#: window.c:237
+msgid "E441: There is no preview window"
+msgstr "E441: No hay una ventana de vista previa"
+
+#: window.c:672
+msgid "E442: Can't split topleft and botright at the same time"
+msgstr "E442: No se puede dividir arriba izq. y abajo der. al mismo tiempo"
+
+#: window.c:1484
+msgid "E443: Cannot rotate when another window is split"
+msgstr "E443: No se puede rotar cuando otra ventana está dividida"
+
+#: window.c:2113
+msgid "E444: Cannot close last window"
+msgstr "E444: No se puede cerrar la última ventana"
+
+#: window.c:2120
+msgid "E813: Cannot close autocmd window"
+msgstr "E813: No se puede cerrar la ventana de autocmd"
+
+#: window.c:2125
+msgid "E814: Cannot close window, only autocmd window would remain"
+msgstr ""
+"E814: No se pudo cerrar la última ventana, solo quedará\n"
+"la ventana de autocmd"
+
+#: window.c:3188
+msgid "E445: Other window contains changes"
+msgstr "E445: Otra ventana contiene cambios"
+
+#: window.c:5868
+msgid "E446: No file name under cursor"
+msgstr "E446: No hay un nombre de archivo bajo el cursor"
+
+#: window.c:6005
+#, c-format
+msgid "E447: Can't find file \"%s\" in path"
+msgstr "E447: No se pudo encontrar el archivo \"%s\" en la ruta"
+
+#: if_perl.xs:420 globals.h:1420
+#, c-format
+msgid "E370: Could not load library %s"
+msgstr "E370: No se pudo cargar la biblioteca dinámica %s"
+
+#: if_perl.xs:671
+msgid "Sorry, this command is disabled: the Perl library could not be loaded."
+msgstr "Esta orden está desactivada, no se pudo cargar la biblioteca de Perl"
+
+#: if_perl.xs:726
+msgid "E299: Perl evaluation forbidden in sandbox without the Safe module"
+msgstr ""
+"E299: No se permite la evaluación de código Perl en la caja de\n"
+"arena sin el uso del módulo \"Safe\""
+
+#: GvimExt/gvimext.cpp:587
+msgid "Edit with &multiple Vims"
+msgstr "Editar con &múltiples Vims"
+
+#: GvimExt/gvimext.cpp:593
+msgid "Edit with single &Vim"
+msgstr "Editar con un solo &Vim"
+
+#: GvimExt/gvimext.cpp:602
+msgid "Diff with Vim"
+msgstr "Diff con Vim"
+
+#: GvimExt/gvimext.cpp:615
+msgid "Edit with &Vim"
+msgstr "Editar con &Vim"
+
+# Now concatenate
+#. Now concatenate
+#: GvimExt/gvimext.cpp:637
+msgid "Edit with existing Vim - "
+msgstr "Editar con un Vim en ejecución -"
+
+#: GvimExt/gvimext.cpp:752
+msgid "Edits the selected file(s) with Vim"
+msgstr "Editar el(los) archivos seleccionado/s con Vim"
+
+#: GvimExt/gvimext.cpp:891 GvimExt/gvimext.cpp:972
+msgid "Error creating process: Check if gvim is in your path!"
+msgstr ""
+"Error al crear el proceso: ¡Asegúrese de que gvim esta en su ruta de acceso!"
+
+#: GvimExt/gvimext.cpp:892 GvimExt/gvimext.cpp:906 GvimExt/gvimext.cpp:973
+msgid "gvimext.dll error"
+msgstr "error de \"gvimext.dll\""
+
+#: GvimExt/gvimext.cpp:905
+msgid "Path length too long!"
+msgstr "¡La ruta de acceso es demasiado larga!"
+
+#: globals.h:1174
+msgid "--No lines in buffer--"
+msgstr "--No hay líneas en el búfer--"
+
+#
+# * The error messages that can be shared are included here.
+# * Excluded are errors that are only used once and debugging messages.
+#
+#.
+#. * The error messages that can be shared are included here.
+#. * Excluded are errors that are only used once and debugging messages.
+#.
+#: globals.h:1374
+msgid "E470: Command aborted"
+msgstr "E470: La orden se ha interrumpido"
+
+#: globals.h:1375
+msgid "E471: Argument required"
+msgstr "E471: Es necesario un argumento"
+
+#: globals.h:1376
+msgid "E10: \\ should be followed by /, ? or &"
+msgstr "E10: \\ debería ir seguido de \"/\", \"?\" o \"&\""
+
+#: globals.h:1378
+msgid "E11: Invalid in command-line window; <CR> executes, CTRL-C quits"
+msgstr ""
+"E11: Inválido en la ventana de la línea de órdenes: <CR> ejecuta, CTRL-C "
+"cierra"
+
+#: globals.h:1380
+msgid "E12: Command not allowed from exrc/vimrc in current dir or tag search"
+msgstr ""
+"E12: Orden no permitida desde exrc/vimrc en el directorio \n"
+"en uso o al buscar etiquetas"
+
+#: globals.h:1382
+msgid "E171: Missing :endif"
+msgstr "E171: Falta \":endif\""
+
+#: globals.h:1383
+msgid "E600: Missing :endtry"
+msgstr "E600: Falta \":endtry\""
+
+#: globals.h:1384
+msgid "E170: Missing :endwhile"
+msgstr "E170: Falta \":endwhile\""
+
+#: globals.h:1385
+msgid "E170: Missing :endfor"
+msgstr "E170: Falta \":endfor\""
+
+#: globals.h:1386
+msgid "E588: :endwhile without :while"
+msgstr "E588: \":endwhile\" sin \":while\""
+
+#: globals.h:1387
+msgid "E588: :endfor without :for"
+msgstr "E588: \":endfor\" sin un \":for\""
+
+#: globals.h:1389
+msgid "E13: File exists (add ! to override)"
+msgstr "E13: El archivo ya existe (use \"!\" para sobreescribir)"
+
+#: globals.h:1390
+msgid "E472: Command failed"
+msgstr "E472: La orden falló"
+
+#: globals.h:1392
+#, c-format
+msgid "E234: Unknown fontset: %s"
+msgstr "E234: Conjunto de tipos de letra de impresión desconocido: %s"
+
+#: globals.h:1396
+#, c-format
+msgid "E235: Unknown font: %s"
+msgstr "E235: Tipo de letra de impresión desconocida: %s"
+
+#: globals.h:1399
+#, c-format
+msgid "E236: Font \"%s\" is not fixed-width"
+msgstr "E236: El tipo de letra de impresión \"%s\" no es de ancho fijo"
+
+#: globals.h:1401
+msgid "E473: Internal error"
+msgstr "E473: Error interno"
+
+#: globals.h:1402
+msgid "Interrupted"
+msgstr "Interrumpido"
+
+#: globals.h:1403
+msgid "E14: Invalid address"
+msgstr "E14: La dirección no es válida"
+
+#: globals.h:1404
+msgid "E474: Invalid argument"
+msgstr "E474: El argumento no es válido"
+
+#: globals.h:1405
+#, c-format
+msgid "E475: Invalid argument: %s"
+msgstr "E475: El argumento no es válido: %s"
+
+#: globals.h:1407
+#, c-format
+msgid "E15: Invalid expression: %s"
+msgstr "E15: La expresión no es válida: %s"
+
+#: globals.h:1409
+msgid "E16: Invalid range"
+msgstr "E16: El rango no es válido"
+
+#: globals.h:1410
+msgid "E476: Invalid command"
+msgstr "E476: La orden no es válida"
+
+#: globals.h:1412
+#, c-format
+msgid "E17: \"%s\" is a directory"
+msgstr "E17: \"%s\" es un directorio"
+
+#: globals.h:1415
+#, c-format
+msgid "E364: Library call failed for \"%s()\""
+msgstr "E364: Falló la llamada a la biblioteca para \"%s()\""
+
+#: globals.h:1421
+#, c-format
+msgid "E448: Could not load library function %s"
+msgstr "E448: No pude cargar la biblioteca de funciones %s"
+
+#: globals.h:1423
+msgid "E19: Mark has invalid line number"
+msgstr "E19: El número de línea de la marca no es válido"
+
+#: globals.h:1424
+msgid "E20: Mark not set"
+msgstr "E20: No se ha colocado una marca"
+
+#: globals.h:1425
+msgid "E21: Cannot make changes, 'modifiable' is off"
+msgstr "E21: No se pudo modificar, 'modifiable' está desactivado"
+
+#: globals.h:1426
+msgid "E22: Scripts nested too deep"
+msgstr "E22: Demasiados archivos de órdenes anidados"
+
+#: globals.h:1427
+msgid "E23: No alternate file"
+msgstr "E23: No hay un archivo alterno"
+
+#: globals.h:1428
+msgid "E24: No such abbreviation"
+msgstr "E24: No existe esa abreviatura"
+
+#: globals.h:1429
+msgid "E477: No ! allowed"
+msgstr "E477: \"!\" no está permitido"
+
+#: globals.h:1431
+msgid "E25: GUI cannot be used: Not enabled at compile time"
+msgstr ""
+"E25: No se puede usar la interfaz gráfica de usuario: No se activó al "
+"compilar"
+
+#: globals.h:1434
+msgid "E26: Hebrew cannot be used: Not enabled at compile time\n"
+msgstr "E26: No se pudo usar el hebreo: no se activó al compilar\n"
+
+#: globals.h:1437
+msgid "E27: Farsi cannot be used: Not enabled at compile time\n"
+msgstr "E27: No se pudo usar el persa (farsi): no se activó al compilar\n"
+
+#: globals.h:1440
+msgid "E800: Arabic cannot be used: Not enabled at compile time\n"
+msgstr "E800: No se pudo usar el árabe: no se activó al compilar\n"
+
+#: globals.h:1443
+#, c-format
+msgid "E28: No such highlight group name: %s"
+msgstr "E28: No existe un grupo de resaltado de nombre: %s"
+
+#: globals.h:1445
+msgid "E29: No inserted text yet"
+msgstr "E29: Aún no ha insertado texto"
+
+#: globals.h:1446
+msgid "E30: No previous command line"
+msgstr "E30: No hay una línea de órdenes previa"
+
+#: globals.h:1447
+msgid "E31: No such mapping"
+msgstr "E31: No existe tal asociación"
+
+#: globals.h:1448
+msgid "E479: No match"
+msgstr "E479: No hay coincidencia"
+
+#: globals.h:1449
+#, c-format
+msgid "E480: No match: %s"
+msgstr "E480: No coincide: %s"
+
+#: globals.h:1450
+msgid "E32: No file name"
+msgstr "E32: No hay un nombre de archivo"
+
+#: globals.h:1451
+msgid "E33: No previous substitute regular expression"
+msgstr "E33: No existe una expresión regular de sustitución previa"
+
+#: globals.h:1452
+msgid "E34: No previous command"
+msgstr "E34: No existe una orden previa"
+
+#: globals.h:1453
+msgid "E35: No previous regular expression"
+msgstr "E35: No existe una expresión regular previa"
+
+#: globals.h:1454
+msgid "E481: No range allowed"
+msgstr "E481: El rango no está permitido"
+
+#: globals.h:1456
+msgid "E36: Not enough room"
+msgstr "E36: No hay espacio suficiente"
+
+#: globals.h:1459
+#, c-format
+msgid "E247: no registered server named \"%s\""
+msgstr "E247: El servidor llamado \"%s\" no está registrado"
+
+#: globals.h:1461
+#, c-format
+msgid "E482: Can't create file %s"
+msgstr "E482: No se pudo crear el archivo \"%s\""
+
+#: globals.h:1462
+msgid "E483: Can't get temp file name"
+msgstr "E483: No se pudo obtener el nombre del archivo temporal"
+
+#: globals.h:1463
+#, c-format
+msgid "E484: Can't open file %s"
+msgstr "E484: No se pudo abrir el archivo \"%s\""
+
+#: globals.h:1464
+#, c-format
+msgid "E485: Can't read file %s"
+msgstr "E485: No se pudo leer el archivo \"%s\""
+
+#: globals.h:1465
+msgid "E37: No write since last change (add ! to override)"
+msgstr ""
+"E37: No guardó el archivo desde el último cambio (añada \"!\" para forzar)"
+
+#: globals.h:1466
+msgid "E38: Null argument"
+msgstr "E38: Argumento nulo"
+
+#: globals.h:1468
+msgid "E39: Number expected"
+msgstr "E39: Se esperaba un número"
+
+#: globals.h:1471
+#, c-format
+msgid "E40: Can't open errorfile %s"
+msgstr "E40: No se pudo abrir el archivo de errores \"%s\""
+
+#: globals.h:1474
+msgid "E233: cannot open display"
+msgstr "E233: No se pudo abrir la pantalla"
+
+#: globals.h:1476
+msgid "E41: Out of memory!"
+msgstr "E41: ¡Memoria agotada!"
+
+#: globals.h:1478
+msgid "Pattern not found"
+msgstr "No se encontró el patrón de búsqueda"
+
+#: globals.h:1480
+#, c-format
+msgid "E486: Pattern not found: %s"
+msgstr "E486: No se encontró el patrón de búsqueda: %s"
+
+#: globals.h:1481
+msgid "E487: Argument must be positive"
+msgstr "E487: El argumento debe ser positivo"
+
+#: globals.h:1483
+msgid "E459: Cannot go back to previous directory"
+msgstr "E459: No se pudo regresar al directorio previo"
+
+#: globals.h:1487
+msgid "E42: No Errors"
+msgstr "E42: No hay errores"
+
+#: globals.h:1488
+msgid "E776: No location list"
+msgstr "E776: No hay una lista de posiciones"
+
+#: globals.h:1490
+msgid "E43: Damaged match string"
+msgstr "E43: Cadena de coincidencia dañada"
+
+#: globals.h:1491
+msgid "E44: Corrupted regexp program"
+msgstr "E44: El programa \"regexp\" está corrupto"
+
+#: globals.h:1492
+msgid "E45: 'readonly' option is set (add ! to override)"
+msgstr "E45: La opción 'readonly' está activada (añada \"!\" para forzar)"
+
+#: globals.h:1494
+#, c-format
+msgid "E46: Cannot change read-only variable \"%s\""
+msgstr "E46: No puede cambiar la variable de solo lectura \"%s\""
+
+#: globals.h:1495
+#, c-format
+msgid "E794: Cannot set variable in the sandbox: \"%s\""
+msgstr "E794: No se puede definir la variable en el \"sandbox\": \"%s\""
+
+#: globals.h:1498
+msgid "E47: Error while reading errorfile"
+msgstr "E47: Error al leer el archivo de errores"
+
+#: globals.h:1501
+msgid "E48: Not allowed in sandbox"
+msgstr "E48: No se permite en el ambiente protegido"
+
+#: globals.h:1503
+msgid "E523: Not allowed here"
+msgstr "E523: No se permite aquí"
+
+#: globals.h:1506
+msgid "E359: Screen mode setting not supported"
+msgstr "E359: La configuración de la pantalla no es válida"
+
+#: globals.h:1508
+msgid "E49: Invalid scroll size"
+msgstr "E49: La longitud de desplazamiento no es válida"
+
+#: globals.h:1509
+msgid "E91: 'shell' option is empty"
+msgstr "E91: La opción 'shell' (intérprete de órdenes) está vacía"
+
+#: globals.h:1511
+msgid "E255: Couldn't read in sign data!"
+msgstr "E255: ¡No se pudo cargar los signos!"
+
+#: globals.h:1513
+msgid "E72: Close error on swap file"
+msgstr "E72: Error de cierre en el archivo de intercambio"
+
+#: globals.h:1514
+msgid "E73: tag stack empty"
+msgstr "E73: La pila de etiquetas ('tagstack') está vacía"
+
+#: globals.h:1515
+msgid "E74: Command too complex"
+msgstr "E74: La orden es demasiado compleja"
+
+#: globals.h:1516
+msgid "E75: Name too long"
+msgstr "E75: El nombre es demasiado largo"
+
+#: globals.h:1517
+msgid "E76: Too many ["
+msgstr "E76: Hay demasiados ["
+
+#: globals.h:1518
+msgid "E77: Too many file names"
+msgstr "E77: Hay demasiados nombres de archivos"
+
+#: globals.h:1519
+msgid "E488: Trailing characters"
+msgstr "E488: Caracteres en exceso al final de la línea"
+
+#: globals.h:1520
+msgid "E78: Unknown mark"
+msgstr "E78: Marca desconocida"
+
+#: globals.h:1521
+msgid "E79: Cannot expand wildcards"
+msgstr "E79: No se pudo expandir los comodines"
+
+#: globals.h:1523
+msgid "E591: 'winheight' cannot be smaller than 'winminheight'"
+msgstr "E591: \"winheight\" no puede ser más pequeño que \"winminheight\""
+
+#: globals.h:1525
+msgid "E592: 'winwidth' cannot be smaller than 'winminwidth'"
+msgstr "E592: \"winwidth\" no puede ser más pequeño que \"winminwidth\""
+
+#: globals.h:1528
+msgid "E80: Error while writing"
+msgstr "E80: Error al escribir el archivo"
+
+#: globals.h:1529
+msgid "Zero count"
+msgstr "El recuento es cero"
+
+#: globals.h:1531
+msgid "E81: Using <SID> not in a script context"
+msgstr "E81: Usando <SID> en un contexto que no es de archivo de órdenes"
+
+#: globals.h:1534
+msgid "E449: Invalid expression received"
+msgstr "E449: Se recibió una expresión inválida"
+
+#: globals.h:1537
+msgid "E463: Region is guarded, cannot modify"
+msgstr "E463: La región está protegida, no se puede modificar"
+
+#: globals.h:1538
+msgid "E744: NetBeans does not allow changes in read-only files"
+msgstr "E744: NetBeans no permite cambios a archivos de sólo lectura"
+
+#: globals.h:1540
+#, c-format
+msgid "E685: Internal error: %s"
+msgstr "E685: Error interno: %s"
+
+#: globals.h:1541
+msgid "E363: pattern uses more memory than 'maxmempattern'"
+msgstr "E363: El patrón usa más memoria que 'maxmempattern'"
+
+#: globals.h:1542
+msgid "E749: empty buffer"
+msgstr "E749: Búfer vacío"
+
+#: globals.h:1545
+msgid "E682: Invalid search pattern or delimiter"
+msgstr "E682: Patrón de búsqueda o delimitador no válido"
+
+# Overwriting a file that is loaded in another buffer is not a
+# * good idea.
+#: globals.h:1547
+msgid "E139: File is loaded in another buffer"
+msgstr "E139: El archivo ya se ha cargado en otro búfer"
+
+#: globals.h:1550
+#, c-format
+msgid "E764: Option '%s' is not set"
+msgstr "E764: No se ha definido la opción '%s'"
+
+#: globals.h:1557
+msgid "search hit TOP, continuing at BOTTOM"
+msgstr "La búsqueda ha llegado al PRINCIPIO, continuando desde el FINAL"
+
+#: globals.h:1558
+msgid "search hit BOTTOM, continuing at TOP"
+msgstr "La búsqueda ha llegado al FINAL, continuando desde el PRINCIPIO"
+
+#~ msgid "[NL found]"
+#~ msgstr "[NL encontrado]"
+
+#~ msgid "E569: maximum number of cscope connections reached"
+#~ msgstr "E569: Se ha alcanzado el número máximo de conexiones con \"cscope\""
+
+#~ msgid "-V[N]\t\tVerbose level"
+#~ msgstr "-V[N]\t\tNivel de verbosidad (traza de ejecución)"
diff --git a/src/po/fi.po b/src/po/fi.po
new file mode 100644
index 0000000000..5685d171b0
--- /dev/null
+++ b/src/po/fi.po
@@ -0,0 +1,6526 @@
+# Finnish translation for Vim.
+# Copyright (C) 2003-2006 Free Software Foundation, Inc.
+# 2007-2010, 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ä.
+#
+# Sanastosta:
+# 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 .)
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Vim 7\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2010-08-09 02:00+0300\n"
+"PO-Revision-Date: 2010-08-09 02:35+0300\n"
+"Last-Translator: Flammie Pirinen <flammie@iki.fi>\n"
+"Language-Team: Finnish <laatu@lokalisointi.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=ISO-8859-1\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+msgid "E831: bf_key_init() called with empty password"
+msgstr "E831: bf_key_init() tyhjällä salasanalla"
+
+msgid "E820: sizeof(uint32_t) != 4"
+msgstr "E820: sizeof(uint32_t) != 4"
+
+msgid "E817: Blowfish big/little endian use wrong"
+msgstr "E817: Blowfishin tavujärjestys väärä"
+
+msgid "E818: sha256 test failed"
+msgstr "E818: sha256-testi epäonnistui failed"
+
+msgid "E819: Blowfish test failed"
+msgstr "E819: Blowfish-testi epäonnistui"
+
+msgid "[Location List]"
+msgstr "[Sijaintiluettelo]"
+
+msgid "[Quickfix List]"
+msgstr "[Pikakorjausluettelo]"
+
+msgid "E82: Cannot allocate any buffer, exiting..."
+msgstr "E82: Mitään puskuria ei voitu varata, lopetetaan..."
+
+msgid "E83: Cannot allocate buffer, using other one..."
+msgstr "E83: Puskuria ei voitu varata, käytetään toista..."
+
+msgid "E515: No buffers were unloaded"
+msgstr "E515: Puskureita ei vapautettu"
+
+msgid "E516: No buffers were deleted"
+msgstr "E516: Puskureita ei poistettu"
+
+msgid "E517: No buffers were wiped out"
+msgstr "E517: Puskureita ei pyyhitty"
+
+msgid "1 buffer unloaded"
+msgstr "1 puskuri vapautettiin"
+
+#, c-format
+msgid "%d buffers unloaded"
+msgstr "%d puskuria vapautettiin"
+
+msgid "1 buffer deleted"
+msgstr "1 puskuri poistettu"
+
+#, c-format
+msgid "%d buffers deleted"
+msgstr "%d puskuria poistettu"
+
+msgid "1 buffer wiped out"
+msgstr "1 puskuri pyyhitty"
+
+#, c-format
+msgid "%d buffers wiped out"
+msgstr "%d puskuria pyyhitty"
+
+msgid "E84: No modified buffer found"
+msgstr "E84: Ei muokattuja puskureita"
+
+#. back where we started, didn't find anything.
+msgid "E85: There is no listed buffer"
+msgstr "E85: Luetteloitua puskuria ei ole"
+
+#, c-format
+msgid "E86: Buffer %ld does not exist"
+msgstr "E86: Puskuria %ld ei ole"
+
+msgid "E87: Cannot go beyond last buffer"
+msgstr "E87: Viimeisen puskurin ohi ei voi edetä"
+
+msgid "E88: Cannot go before first buffer"
+msgstr "E88: Ensimmäisen puskurin ohi ei voi edetä"
+
+#, c-format
+msgid "E89: No write since last change for buffer %ld (add ! to override)"
+msgstr ""
+"E89: Puskurin %ld muutoksia ei ole tallennettu (lisää komentoon ! "
+"ohittaaksesi)"
+
+msgid "E90: Cannot unload last buffer"
+msgstr "E90: Ei voi vapauttaa viimeistä puskuria"
+
+msgid "W14: Warning: List of file names overflow"
+msgstr "W14: Varoitus: Tiedostonimiluettelon ylivuoto"
+
+#, c-format
+msgid "E92: Buffer %ld not found"
+msgstr "E92: Puskuria %ld ei löydy"
+
+#, c-format
+msgid "E93: More than one match for %s"
+msgstr "E93: %s täsmää useampaan kuin yhteen puskuriin"
+
+#, c-format
+msgid "E94: No matching buffer for %s"
+msgstr "E94: %s ei täsmää yhteenkään puskuriin"
+
+#, c-format
+msgid "line %ld"
+msgstr "rivi %ld"
+
+msgid "E95: Buffer with this name already exists"
+msgstr "E95: Samanniminen puskuri on jo olemassa"
+
+msgid " [Modified]"
+msgstr " [Muokattu]"
+
+msgid "[Not edited]"
+msgstr "[Muokkaamaton]"
+
+msgid "[New file]"
+msgstr "[Uusi tiedosto]"
+
+msgid "[Read errors]"
+msgstr "[Lukuvirheitä]"
+
+msgid "[readonly]"
+msgstr "[kirjoitussuojattu]"
+
+#, c-format
+msgid "1 line --%d%%--"
+msgstr "1 rivi --%d %%--"
+
+#, c-format
+msgid "%ld lines --%d%%--"
+msgstr "%ld riviä --%d %%--"
+
+#, c-format
+msgid "line %ld of %ld --%d%%-- col "
+msgstr "rivi %ld/%ld --%d %%-- sarake "
+
+msgid "[No Name]"
+msgstr "[Nimetön]"
+
+#. must be a help buffer
+msgid "help"
+msgstr "ohje"
+
+msgid "[Help]"
+msgstr "[Ohje]"
+
+msgid "[Preview]"
+msgstr "[Esikatselu]"
+
+# sijainti tiedostossa -indikaattoreja:
+# 4 merkkiä sais riittää
+msgid "All"
+msgstr "Kaik"
+
+msgid "Bot"
+msgstr "Loppu"
+
+msgid "Top"
+msgstr "Alku"
+
+#, c-format
+msgid ""
+"\n"
+"# Buffer list:\n"
+msgstr ""
+"\n"
+"# Puskuriluettelo:\n"
+
+msgid "[Scratch]"
+msgstr "[Raapust]"
+
+msgid ""
+"\n"
+"--- Signs ---"
+msgstr ""
+"\n"
+"--- Merkit ---"
+
+#, c-format
+msgid "Signs for %s:"
+msgstr "Merkit kohteelle %s:"
+
+#, c-format
+msgid " line=%ld id=%d name=%s"
+msgstr " rivi=%ld id=%d nimi=%s"
+
+#, c-format
+msgid "E96: Can not diff more than %ld buffers"
+msgstr "E96: Ei voi diffata enempää kuin %ld puskuria"
+
+msgid "E810: Cannot read or write temp files"
+msgstr "E810: Ei voi lukea tai kirjoittaa väliaikaistiedostoja"
+
+msgid "E97: Cannot create diffs"
+msgstr "E97: Ei voi luoda diffejä"
+
+msgid "Patch file"
+msgstr "Patch-tiedosto"
+
+msgid "E816: Cannot read patch output"
+msgstr "E816: Ei voi lukea patchin tulostetta"
+
+msgid "E98: Cannot read diff output"
+msgstr "E98: Ei voi lukea diffin tulostetta"
+
+msgid "E99: Current buffer is not in diff mode"
+msgstr "E99: Tämä puskuri ei ole diff-tilassa"
+
+msgid "E793: No other buffer in diff mode is modifiable"
+msgstr "E793: Yksikään muu diff-tilan puskurit ei ole muokattavissa"
+
+msgid "E100: No other buffer in diff mode"
+msgstr "E100: Yksikään muu puskuri ei ole diff-tilassa"
+
+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"
+
+#, c-format
+msgid "E102: Can't find buffer \"%s\""
+msgstr "E102: Puskuria %s ei löydy"
+
+#, c-format
+msgid "E103: Buffer \"%s\" is not in diff mode"
+msgstr "E103: Puskuri %s ei ole diff-tilassa"
+
+msgid "E787: Buffer changed unexpectedly"
+msgstr "E787: Puskuri vaihtui odottamatta"
+
+msgid "E104: Escape not allowed in digraph"
+msgstr "E104: Escapea ei voi käyttää digraafissa"
+
+msgid "E544: Keymap file not found"
+msgstr "E544: Näppäinkarttaa ei löydy"
+
+msgid "E105: Using :loadkeymap not in a sourced file"
+msgstr "E105: Käytetään :loadkeymapia ladatun tiedoston ulkopuolella"
+
+msgid "E791: Empty keymap entry"
+msgstr "E791: Tyhjä keymap-kenttä"
+
+msgid " Keyword completion (^N^P)"
+msgstr " Avainsanatäydennys (^N^P)"
+
+#. ctrl_x_mode == 0, ^P/^N compl.
+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)"
+
+msgid " Whole line completion (^L^N^P)"
+msgstr " Täysrivitäydennys (^L^N^P)"
+
+msgid " File name completion (^F^N^P)"
+msgstr " Tiedostonimitäydennys (^F^N^P)"
+
+msgid " Tag completion (^]^N^P)"
+msgstr " Tägitäydennys (^]^N^P)"
+
+msgid " Path pattern completion (^N^P)"
+msgstr " Polkukuviotäydennys (^N^P)"
+
+msgid " Definition completion (^D^N^P)"
+msgstr " Määritelmätäydennys (^D^N^P)"
+
+msgid " Dictionary completion (^K^N^P)"
+msgstr " Sanakirjatäydennys (^K^N^P)"
+
+msgid " Thesaurus completion (^T^N^P)"
+msgstr " Thesaurus-täydennys (^T^N^P)"
+
+msgid " Command-line completion (^V^N^P)"
+msgstr " Komentorivitäydennys (^V^N^P)"
+
+msgid " User defined completion (^U^N^P)"
+msgstr " Käyttäjän määrittelemä täydennys (^U^N^P)"
+
+msgid " Omni completion (^O^N^P)"
+msgstr " Omnitäydennys (^O^N^P)"
+
+msgid " Spelling suggestion (s^N^P)"
+msgstr " Oikaisulukuehdotus (s^N^P)"
+
+msgid " Keyword Local completion (^N^P)"
+msgstr " Avainsanan paikallinen täydennys (^N^P)"
+
+msgid "Hit end of paragraph"
+msgstr "Kappaleen loppu tuli vastaan"
+
+msgid "'dictionary' option is empty"
+msgstr "dictionary-asetus on tyhjä"
+
+msgid "'thesaurus' option is empty"
+msgstr "thesaurus-asetus on tyhjä"
+
+#, c-format
+msgid "Scanning dictionary: %s"
+msgstr "Luetaan sanakirjaa: %s"
+
+msgid " (insert) Scroll (^E/^Y)"
+msgstr " (syöttö) Vieritys (^E/^Y)"
+
+msgid " (replace) Scroll (^E/^Y)"
+msgstr " (korvaus) Vieritys (^E/^Y)"
+
+#, c-format
+msgid "Scanning: %s"
+msgstr "Luetaan: %s"
+
+msgid "Scanning tags."
+msgstr "Luetaan tägejä."
+
+msgid " Adding"
+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.
+#.
+msgid "-- Searching..."
+msgstr "-- Haetaan..."
+
+msgid "Back at original"
+msgstr "Takaisin lähtöpisteessä"
+
+msgid "Word from other line"
+msgstr "Sana toisella rivillä"
+
+msgid "The only match"
+msgstr "Ainoa täsmäys"
+
+#, c-format
+msgid "match %d of %d"
+msgstr "täsmäys %d/%d"
+
+#, c-format
+msgid "match %d"
+msgstr "täsmäys %d"
+
+msgid "E18: Unexpected characters in :let"
+msgstr "E18: Odottamattomia merkkejä komennossa :let"
+
+#, c-format
+msgid "E684: list index out of range: %ld"
+msgstr "E684: Indeksi %ld luettelon rajojen ulkopuolella"
+
+#, c-format
+msgid "E121: Undefined variable: %s"
+msgstr "E121: Määrittelemätön muuttuja: %s"
+
+msgid "E111: Missing ']'"
+msgstr "E111: ] puuttuu"
+
+#, c-format
+msgid "E686: Argument of %s must be a List"
+msgstr "E686: Argumentin %s pitää olla lista"
+
+# datarakenteita
+#, c-format
+msgid "E712: Argument of %s must be a List or Dictionary"
+msgstr "E712: Argumentin %s pitää olla lista tai sanakirja"
+
+msgid "E713: Cannot use empty key for Dictionary"
+msgstr "E713: Sanakirjassa ei voi olla tyhjiä avaimia"
+
+msgid "E714: List required"
+msgstr "E714: Lista tarvitaan"
+
+msgid "E715: Dictionary required"
+msgstr "E715: Sanakirja tarvitaan"
+
+#, c-format
+msgid "E118: Too many arguments for function: %s"
+msgstr "E118: Liikaa argumentteja funktiolle: %s"
+
+#, c-format
+msgid "E716: Key not present in Dictionary: %s"
+msgstr "E716: Avainta %s ei ole sanakirjassa"
+
+#, c-format
+msgid "E122: Function %s already exists, add ! to replace it"
+msgstr "E122: Funktio %s on jo olemassa, lisää ! korvataksesi"
+
+msgid "E717: Dictionary entry already exists"
+msgstr "E717: Sanakirja-alkio on jo olemassa"
+
+msgid "E718: Funcref required"
+msgstr "E718: Funcref tarvitaan"
+
+msgid "E719: Cannot use [:] with a Dictionary"
+msgstr "E719: Sanakirjassa ei voi käyttää merkintää [:]"
+
+#, c-format
+msgid "E734: Wrong variable type for %s="
+msgstr "E734: Väärä muuttujatyyppi muuttujalle %s="
+
+#, c-format
+msgid "E130: Unknown function: %s"
+msgstr "E130: Tuntematon funktio: %s"
+
+#, c-format
+msgid "E461: Illegal variable name: %s"
+msgstr "E461: Virheellinen muuttujanimi: %s"
+
+msgid "E687: Less targets than List items"
+msgstr "E687: Kohteita on vähemmän kuin listan alkioita"
+
+msgid "E688: More targets than List items"
+msgstr "E688: Kohteita on enemmän kuin listan alkioita"
+
+msgid "Double ; in list of variables"
+msgstr "Kaksi ;:ttä listan muuttujissa"
+
+#, c-format
+msgid "E738: Can't list variables for %s"
+msgstr "E738: Kohteen %s muuttujia ei voi listata"
+
+msgid "E689: Can only index a List or Dictionary"
+msgstr "E689: Vain listalla ja sanakirjalla voi olla indeksejä"
+
+msgid "E708: [:] must come last"
+msgstr "E708: [:]:n pitää olla viimeisenä"
+
+msgid "E709: [:] requires a List value"
+msgstr "E709: [:] toimii vain listalla"
+
+msgid "E710: List value has more items than target"
+msgstr "E710: Listalla on enemmän alkioita kuin kohteella"
+
+msgid "E711: List value has not enough items"
+msgstr "E711: Listalla ei ole tarpeeksi alkioita"
+
+msgid "E690: Missing \"in\" after :for"
+msgstr "E690: :for-kommenolta puuttuu in"
+
+#, c-format
+msgid "E107: Missing parentheses: %s"
+msgstr "E107: Sulkeita puuttuu: %s"
+
+#, c-format
+msgid "E108: No such variable: \"%s\""
+msgstr "E108: Muuttujaa %s ei ole"
+
+msgid "E743: variable nested too deep for (un)lock"
+msgstr "E743: muuttujassa liian monta tasoa lukituksen käsittelyyn"
+
+msgid "E109: Missing ':' after '?'"
+msgstr "E109: ?:n jälkeen puuttuu :"
+
+msgid "E691: Can only compare List with List"
+msgstr "E691: Listaa voi verrata vain listaan"
+
+msgid "E692: Invalid operation for Lists"
+msgstr "E692: Virheellinen toiminto listalle"
+
+msgid "E735: Can only compare Dictionary with Dictionary"
+msgstr "E735: Sanakirjaa voi verrata vain sanakirjaan"
+
+msgid "E736: Invalid operation for Dictionary"
+msgstr "E736: Virheellinen toiminto sanakirjalle"
+
+msgid "E693: Can only compare Funcref with Funcref"
+msgstr "E693: Funcrefiä voi verrata vain funcrefiin"
+
+msgid "E694: Invalid operation for Funcrefs"
+msgstr "E694: Virheellinen toiminto funcrefille"
+
+msgid "E804: Cannot use '%' with Float"
+msgstr "E804: Ei voi käyttää '%':a Floatin kanssa"
+
+msgid "E110: Missing ')'"
+msgstr "E110: ) puuttuu"
+
+msgid "E695: Cannot index a Funcref"
+msgstr "E695: Funcrefiä ei voi indeksoida"
+
+#, c-format
+msgid "E112: Option name missing: %s"
+msgstr "E112: Asetuksen nimi puuttuu: %s"
+
+#, c-format
+msgid "E113: Unknown option: %s"
+msgstr "E113: Tuntematon asetus: %s"
+
+#, c-format
+msgid "E114: Missing quote: %s"
+msgstr "E114: Puuttuva lainausmerkki: %s"
+
+#, c-format
+msgid "E115: Missing quote: %s"
+msgstr "E115: Puuttuva lainausmerkki: %s"
+
+#, c-format
+msgid "E696: Missing comma in List: %s"
+msgstr "E696: Listasta puuttuu pilkku: %s"
+
+#, c-format
+msgid "E697: Missing end of List ']': %s"
+msgstr "E697: Listan lopusta puuttuu ]: %s"
+
+#, c-format
+msgid "E720: Missing colon in Dictionary: %s"
+msgstr "E720: Sanakirjasta puuttuu kaksoispiste: %s"
+
+#, c-format
+msgid "E721: Duplicate key in Dictionary: \"%s\""
+msgstr "E721: Kaksi samaa avainta sanakirjassa: %s"
+
+#, c-format
+msgid "E722: Missing comma in Dictionary: %s"
+msgstr "E722: Sanakirjasta puuttuu pilkku: %s"
+
+#, c-format
+msgid "E723: Missing end of Dictionary '}': %s"
+msgstr "E723: Sanakirjan lopusta puuttuu }: %s"
+
+msgid "E724: variable nested too deep for displaying"
+msgstr "E724: muuttuja on upotettu liian syvälle näytettäväksi"
+
+#, c-format
+msgid "E740: Too many arguments for function %s"
+msgstr "E740: Liikaa argumentteja funktiolle %s"
+
+#, c-format
+msgid "E116: Invalid arguments for function %s"
+msgstr "E116: Vääriä argumentteja funktiolle %s"
+
+#, c-format
+msgid "E117: Unknown function: %s"
+msgstr "E117: Tuntematon funktio: %s"
+
+#, c-format
+msgid "E119: Not enough arguments for function: %s"
+msgstr "E119: Liikaa argumentteja funktiolle %s"
+
+#, c-format
+msgid "E120: Using <SID> not in a script context: %s"
+msgstr "E120: <SID> skriptin ulkopuolella: %s"
+
+#, c-format
+msgid "E725: Calling dict function without Dictionary: %s"
+msgstr "E725: dict-funktio ilman sanakirjaa: %s"
+
+msgid "E808: Number or Float required"
+msgstr "E808: Number tai Float vaaditaan"
+
+msgid "E699: Too many arguments"
+msgstr "E699: Liikaa argumentteja"
+
+msgid "E785: complete() can only be used in Insert mode"
+msgstr "E785: complete() toimii vain syöttötilassa"
+
+#.
+#. * 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"
+
+#, c-format
+msgid "E737: Key already exists: %s"
+msgstr "E737: Avain on jo olemassa: %s"
+
+#, c-format
+msgid "+-%s%3ld lines: "
+msgstr "+-%s%3ld riviä: "
+
+#, c-format
+msgid "E700: Unknown function: %s"
+msgstr "E700: Tuntematon funktio: %s"
+
+msgid ""
+"&OK\n"
+"&Cancel"
+msgstr ""
+"&OK\n"
+"&Peru"
+
+msgid "called inputrestore() more often than inputsave()"
+msgstr "inputrestore() suoritettu useammin kuin inputsave()"
+
+msgid "E786: Range not allowed"
+msgstr "E786: Aluetta ei voi käyttää"
+
+msgid "E701: Invalid type for len()"
+msgstr "E701: Virheellinen tyyppi funktiolle len()"
+
+msgid "E726: Stride is zero"
+msgstr "E726: Stride on nolla"
+
+msgid "E727: Start past end"
+msgstr "E727: Alku on lopun jälkeen"
+
+msgid "<empty>"
+msgstr "<tyhjä>"
+
+msgid "E240: No connection to Vim server"
+msgstr "E240: Ei yhteyttä vim-palvelimeen"
+
+#, c-format
+msgid "E241: Unable to send to %s"
+msgstr "E241: Kohteeseen %s lähettäminen ei onnistunut"
+
+msgid "E277: Unable to read a server reply"
+msgstr "E277: Palvelimen vastauksen lukeminen ei onnistunut"
+
+msgid "E655: Too many symbolic links (cycle?)"
+msgstr "E655: Liikaa symbolisia linkkejä (mahdollinen sykli)"
+
+msgid "E258: Unable to send to client"
+msgstr "E258: Asiakkaalle lähetys ei onnistunut"
+
+msgid "E702: Sort compare function failed"
+msgstr "E702: Lajittelun vertausfunktio ei onnistunut"
+
+msgid "(Invalid)"
+msgstr "(Virheellinen)"
+
+msgid "E677: Error writing temp file"
+msgstr "E677: Väliaikaistiedostoon kirjoittaminen ei onnistunut"
+
+msgid "E805: Using a Float as a Number"
+msgstr "E805: Float ei käy Numberista"
+
+msgid "E703: Using a Funcref as a Number"
+msgstr "E703: Funcref ei käy Numberista"
+
+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 "E729: using Funcref as a String"
+msgstr "E729: Funcref ei käy merkkijonosta"
+
+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 "E806: using Float as a String"
+msgstr "E806: Float ei käy merkkijonosta"
+
+#, c-format
+msgid "E704: Funcref variable name must start with a capital: %s"
+msgstr "E704: Funcrefin muuttujanimen pitää alkaa suuraakkosella: %s"
+
+#, c-format
+msgid "E705: Variable name conflicts with existing function: %s"
+msgstr "E705: Muuttujanimi on sama kuin olemassaolevan funktion: %s"
+
+#, c-format
+msgid "E706: Variable type mismatch for: %s"
+msgstr "E706: Muuttujatyyppi ei täsmää: %s"
+
+#, c-format
+msgid "E795: Cannot delete variable %s"
+msgstr "E795: Muuttujaa %s ei voi poistaa"
+
+#, c-format
+msgid "E741: Value is locked: %s"
+msgstr "E741: Arvo on lukittu: %s"
+
+msgid "Unknown"
+msgstr "Tuntematon"
+
+#, c-format
+msgid "E742: Cannot change value of %s"
+msgstr "E742: Ei voi muuttaa muuttujan %s arvoa"
+
+msgid "E698: variable nested too deep for making a copy"
+msgstr "E698: muuttuja on upotettu liian syvälle kopioitavaksi"
+
+#, c-format
+msgid "E123: Undefined function: %s"
+msgstr "E123: Tuntematon funktio: %s"
+
+#, c-format
+msgid "E124: Missing '(': %s"
+msgstr "E124: ( puuttuu: %s"
+
+#, c-format
+msgid "E125: Illegal argument: %s"
+msgstr "E125: Virheellinen argumentti: %s"
+
+msgid "E126: Missing :endfunction"
+msgstr "E126: :endfunction puuttuu"
+
+#, c-format
+msgid "E707: Function name conflicts with variable: %s"
+msgstr "E707: Funktion nimi on ristiriidassa muuttujan kanssa: %s"
+
+#, 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ä"
+
+#, c-format
+msgid "E746: Function name does not match script file name: %s"
+msgstr "E746: Funktion nimi ei ole sama kuin skriptin tiedostonnimi: %s"
+
+msgid "E129: Function name required"
+msgstr "E129: Funktion nimi puuttuu"
+
+#, c-format
+msgid "E128: Function name must start with a capital or contain a colon: %s"
+msgstr ""
+"E128: Funktion nimen pitää alkaa suuraakkosella tai sisältää kaksoispisteen: "
+"%s"
+
+#, c-format
+msgid "E131: Cannot delete function %s: It is in use"
+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"
+
+#, c-format
+msgid "calling %s"
+msgstr "kutsutaan funktiota %s"
+
+#, c-format
+msgid "%s aborted"
+msgstr "%s keskeytettiin"
+
+#, c-format
+msgid "%s returning #%ld"
+msgstr "%s palaa kohdassa #%ld"
+
+#, c-format
+msgid "%s returning %s"
+msgstr "%s palaa kohdassa %s"
+
+#, c-format
+msgid "continuing in %s"
+msgstr "jatkaa kohdassa %s"
+
+msgid "E133: :return not inside a function"
+msgstr "E133: :return ei ole funktion sisällä"
+
+msgid ""
+"\n"
+"# global variables:\n"
+msgstr ""
+"\n"
+"# globaalit muuttujat:\n"
+
+msgid ""
+"\n"
+"\tLast set from "
+msgstr ""
+"\n"
+"\tViimeksi asetettu kohteesta "
+
+msgid "No old files"
+msgstr "Ei vanhoja tiedostoja"
+
+msgid "Entering Debug mode. Type \"cont\" to continue."
+msgstr "Siirrytään vianetsintätilaan, kirjoita cont jatkaaksesi."
+
+#, c-format
+msgid "line %ld: %s"
+msgstr "rivi %ld: %s"
+
+#, c-format
+msgid "cmd: %s"
+msgstr "kmnt: %s"
+
+#, c-format
+msgid "Breakpoint in \"%s%s\" line %ld"
+msgstr "Katkaisukohta %s%s rivillä %ld"
+
+#, c-format
+msgid "E161: Breakpoint not found: %s"
+msgstr "E161: Katkaisukohta puuttuu: %s"
+
+msgid "No breakpoints defined"
+msgstr "Ei katkaisukohtia"
+
+#, c-format
+msgid "%3d %s %s line %ld"
+msgstr "%3d %s %s rivi %ld"
+
+msgid "E750: First use \":profile start {fname}\""
+msgstr "E750: Aloita käskyllä :profile start {fname}"
+
+msgid "Save As"
+msgstr "Tallenna nimellä"
+
+#, c-format
+msgid "Save changes to \"%s\"?"
+msgstr "Tallennetaanko muutokset tiedostoon %s?"
+
+msgid "Untitled"
+msgstr "Nimetön"
+
+#, c-format
+msgid "E162: No write since last change for buffer \"%s\""
+msgstr "E162: Muutoksia ei ole kirjoitettu puskurin %s viime muutoksen jälkeen"
+
+msgid "Warning: Entered other buffer unexpectedly (check autocommands)"
+msgstr "Varoitus: Puskuri vaihtui odottamatta (tarkista autocommands)"
+
+msgid "E163: There is only one file to edit"
+msgstr "E163: Vain yksi tiedosto muokattavana"
+
+msgid "E164: Cannot go before first file"
+msgstr "E164: Ensimmäisen tiedoston ohi ei voi mennä"
+
+msgid "E165: Cannot go beyond last file"
+msgstr "E165: Viimeisen tiedoston ohi ei voi mennä"
+
+#, c-format
+msgid "E666: compiler not supported: %s"
+msgstr "E666: kääntäjää ei tueta: %s"
+
+#, c-format
+msgid "Searching for \"%s\" in \"%s\""
+msgstr "Etsitään ilmausta %s kohteesta %s"
+
+#, c-format
+msgid "Searching for \"%s\""
+msgstr "Etsitään ilmausta %s"
+
+#, c-format
+msgid "not found in 'runtimepath': \"%s\""
+msgstr "ei löydy runtimepathista: %s"
+
+msgid "Source Vim script"
+msgstr "Lataa vim-skripti"
+
+#, c-format
+msgid "Cannot source a directory: \"%s\""
+msgstr "Hakemistoa ei voi ladata: %s"
+
+#, c-format
+msgid "could not source \"%s\""
+msgstr "ei voitu ladata %s"
+
+#, c-format
+msgid "line %ld: could not source \"%s\""
+msgstr "rivi %ld: ei voitu ladata %s"
+
+#, c-format
+msgid "sourcing \"%s\""
+msgstr "ladataan %s"
+
+#, c-format
+msgid "line %ld: sourcing \"%s\""
+msgstr "rivi %ld: ladataan %s"
+
+#, c-format
+msgid "finished sourcing %s"
+msgstr "ladattu %s"
+
+msgid "modeline"
+msgstr "mode-rivi"
+
+msgid "--cmd argument"
+msgstr "--cmd-argumentti"
+
+msgid "-c argument"
+msgstr "-c-argumentti"
+
+msgid "environment variable"
+msgstr "ympäristömuuttuja"
+
+msgid "error handler"
+msgstr "virhekäsittelin"
+
+msgid "W15: Warning: Wrong line separator, ^M may be missing"
+msgstr "W15: Varoitus: Väärä rivierotin, ^M saattaa puuttua"
+
+msgid "E167: :scriptencoding used outside of a sourced file"
+msgstr "E167: :scriptencoding ladatun tiedoston ulkopuolella"
+
+msgid "E168: :finish used outside of a sourced file"
+msgstr "E168: :finish ladatun tiedoston ulkopuolella"
+
+#, c-format
+msgid "Current %slanguage: \"%s\""
+msgstr "Käytössä oleva %skieli: %s"
+
+#, c-format
+msgid "E197: Cannot set language to \"%s\""
+msgstr "E197: Kieleksi ei voitu asettaa kieltä %s"
+
+# 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"
+
+#, c-format
+msgid "%ld lines moved"
+msgstr "%ld riviä siirretty"
+
+#, c-format
+msgid "%ld 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"
+
+#, c-format
+msgid "%sviminfo: %s in line: "
+msgstr "%sviminfo: %s rivillä: "
+
+msgid "E136: viminfo: Too many errors, skipping rest of file"
+msgstr "E136: viminfo: liikaa virheitä, ohitetaan lopputiedosto"
+
+#, c-format
+msgid "Reading viminfo 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"
+
+#. avoid a wait_return for this message, it's annoying
+#, c-format
+msgid "E137: Viminfo file is not writable: %s"
+msgstr "E137: Viminfo-tiedostoon ei voitu kirjoittaa: %s"
+
+#, c-format
+msgid "E138: Can't write viminfo file %s!"
+msgstr "E138: Viminfo-tiedoston kirjoittaminen ei onnistu %s"
+
+#, c-format
+msgid "Writing viminfo file \"%s\""
+msgstr "Kirjoitetaan viminfo-tiedostoa %s"
+
+#. Write the info:
+#, c-format
+msgid "# This viminfo file was generated by Vim %s.\n"
+msgstr "# Vimin %s generoima viminfo-tiedosto.\n"
+
+#, c-format
+msgid ""
+"# You may edit it if you're careful!\n"
+"\n"
+msgstr ""
+"# Muokkaa varovasti!\n"
+"\n"
+
+#, c-format
+msgid "# Value of 'encoding' when this file was written\n"
+msgstr "# encoding-muuttujan arvo tiedostoa kirjoitettaessa\n"
+
+msgid "Illegal starting char"
+msgstr "Virheellinen aloitusmerkki"
+
+msgid "Write partial file?"
+msgstr "Kirjoita osittainen tiedosto"
+
+msgid "E140: Use ! to write partial buffer"
+msgstr "E140: Käytä !-komentoa osittaisen puskurin kirjoittamiseen"
+
+#, c-format
+msgid "Overwrite existing file \"%s\"?"
+msgstr "Ylikirjoitetaanko olemassaoleva tiedosto %s?"
+
+#, c-format
+msgid "Swap file \"%s\" exists, overwrite anyway?"
+msgstr "Swap-tiedosto %s on olemassa, ylikirjoitetaanko?"
+
+#, c-format
+msgid "E768: Swap file exists: %s (:silent! overrides)"
+msgstr "E768: Swap-tiedosto on jo olemassa: %s (komento :silent! ohittaa)"
+
+#, c-format
+msgid "E141: No file name for buffer %ld"
+msgstr "E141: Ei tiedostonimeä puskurille %ld"
+
+msgid "E142: File not written: Writing is disabled by 'write' option"
+msgstr ""
+"E142: Tiedostoa ei kirjoitettu; write-asetus poistaa kirjoituksen käytöstä"
+
+#, c-format
+msgid ""
+"'readonly' option is set for \"%s\".\n"
+"Do you wish to write anyway?"
+msgstr ""
+"readonly asetettu tiedostolle \"%s\".\n"
+"Kirjoitetaanko?"
+
+#, 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 ""
+"Tiedosto %s on kirjoitussuojattu.\n"
+"Siihen saattaa voida silti kirjoittaa.\n"
+"Yritetäänkö?"
+
+#, c-format
+msgid "E505: \"%s\" is read-only (add ! to override)"
+msgstr "E505: %s on kirjoitussuojattu (lisää komentoon ! ohittaaksesi)"
+
+msgid "Edit File"
+msgstr "Muokkaa tiedostoa"
+
+#, c-format
+msgid "E143: Autocommands unexpectedly deleted new buffer %s"
+msgstr "E143: Autocommand poisti uuden puskurin odotuksen vastaisesti %s"
+
+msgid "E144: non-numeric argument to :z"
+msgstr "E144: :z:n argumentti ei ole numero"
+
+msgid "E145: Shell commands not allowed in rvim"
+msgstr "E145: Kuoren komennot eivät toimi rvimissä"
+
+msgid "E146: Regular expressions can't be delimited by letters"
+msgstr "E146: Säännöllistä ilmausta ei voi rajata kirjaimilla"
+
+#, c-format
+msgid "replace with %s (y/n/a/q/l/^E/^Y)?"
+msgstr "korvaa kohteella %s (y/n/a/q/l/^E/^Y)?"
+
+msgid "(Interrupted) "
+msgstr "(Keskeytetty)"
+
+msgid "1 match"
+msgstr "1 täsmäys"
+
+msgid "1 substitution"
+msgstr "1 korvaus"
+
+#, c-format
+msgid "%ld matches"
+msgstr "%ld täsmäystä"
+
+#, c-format
+msgid "%ld substitutions"
+msgstr "%ld korvausta"
+
+msgid " on 1 line"
+msgstr " 1 rivillä"
+
+#, c-format
+msgid " on %ld lines"
+msgstr " %ld rivillä"
+
+msgid "E147: Cannot do :global recursive"
+msgstr "E147: :globalia ei voi suorittaa rekursiivisesti"
+
+msgid "E148: Regular expression missing from global"
+msgstr "E148: Säännöllinen ilmaus puuttuu globaalista"
+
+#, c-format
+msgid "Pattern found in every line: %s"
+msgstr "Kuvio löytyi joka riviltä: %s"
+
+#, c-format
+msgid ""
+"\n"
+"# Last Substitute String:\n"
+"$"
+msgstr ""
+"\n"
+"# Viimeisin korvausmerkkijono:\n"
+"$"
+
+msgid "E478: Don't panic!"
+msgstr "E478: Älä panikoi."
+
+#, c-format
+msgid "E661: Sorry, no '%s' help for %s"
+msgstr "E661: Sori, ei löydy %s-ohjetta kohteelle %s"
+
+#, c-format
+msgid "E149: Sorry, no help for %s"
+msgstr "E149: Sori, ei löydy ohjetta kohteelle %s"
+
+#, c-format
+msgid "Sorry, help file \"%s\" not found"
+msgstr "Sori, ohjetiedostoa %s ei löydy"
+
+#, c-format
+msgid "E150: Not a directory: %s"
+msgstr "E150: Ei ole hakemisto: %s"
+
+#, c-format
+msgid "E152: Cannot open %s for writing"
+msgstr "E152: Ei voi avata tiedostoa %s kirjoittamista varten"
+
+#, c-format
+msgid "E153: Unable to open %s for reading"
+msgstr "E153: Ei voi avata tiedostoa %s lukemista varten"
+
+#, c-format
+msgid "E670: Mix of help file encodings within a language: %s"
+msgstr "E670: Monia ohjetiedostokoodauksia kielessä: %s"
+
+#, c-format
+msgid "E154: Duplicate tag \"%s\" in file %s/%s"
+msgstr "E154: Kaksoiskappale tägistä %s tiedostossa %s/%s"
+
+#, c-format
+msgid "E160: Unknown sign command: %s"
+msgstr "E160: Tuntematon merkkikomento: %s"
+
+msgid "E156: Missing sign name"
+msgstr "E156: Merkki puuttuu"
+
+msgid "E612: Too many signs defined"
+msgstr "E612: Liikaa merkkejä määritelty"
+
+#, c-format
+msgid "E239: Invalid sign text: %s"
+msgstr "E239: Virheellinen merkkiteksti: %s"
+
+#, c-format
+msgid "E155: Unknown sign: %s"
+msgstr "E155: Tuntematon merkki: %s"
+
+msgid "E159: Missing sign number"
+msgstr "E159: Merkin numero puuttuu"
+
+#, c-format
+msgid "E158: Invalid buffer name: %s"
+msgstr "E158: Virheellinen puskurin nimi: %s"
+
+#, c-format
+msgid "E157: Invalid sign ID: %ld"
+msgstr "E157: Virheellinen merkin tunnus: %ld"
+
+msgid " (NOT FOUND)"
+msgstr " (EI LÖYTYNYT)"
+
+msgid " (not supported)"
+msgstr " (ei tuettu)"
+
+msgid "[Deleted]"
+msgstr "[Poistettu]"
+
+msgid "Entering Ex mode. Type \"visual\" to go to Normal mode."
+msgstr "Siirrytään Ex-tilaan, kirjoita visual palataksesi normaaliin tilaan."
+
+msgid "E501: At end-of-file"
+msgstr "E501: Tiedoston lopussa"
+
+msgid "E169: Command too recursive"
+msgstr "E169: Liian rekursiivinen komento"
+
+#, c-format
+msgid "E605: Exception not caught: %s"
+msgstr "E605: Kiinniottamaton poikkeus: %s"
+
+msgid "End of sourced file"
+msgstr "Ladatun tiedoston loppu"
+
+msgid "End of function"
+msgstr "Funktion loppu"
+
+msgid "E464: Ambiguous use of user-defined command"
+msgstr "E464: Käyttäjän määrittelemän komennon monimerkityksinen käyttö"
+
+msgid "E492: Not an editor command"
+msgstr "E492: Ei ole editorikomento"
+
+msgid "E493: Backwards range given"
+msgstr "E493: Takaperoinen arvoalue annettu"
+
+msgid "Backwards range given, OK to swap"
+msgstr "Takaperoinen arvoalue annettu, OK kääntää"
+
+msgid "E494: Use w or w>>"
+msgstr "E494: Käytä w:tä tai w>>:aa"
+
+msgid "E319: Sorry, the command is not available in this version"
+msgstr "E319: Komento ei ole käytettävissä tässä versiossa"
+
+msgid "E172: Only one file name allowed"
+msgstr "E172: Vain yksi tiedostonimi sallitaan"
+
+msgid "1 more file to edit. Quit anyway?"
+msgstr "vielä 1 tiedosto muokattavana, lopetaanko silti?"
+
+#, c-format
+msgid "%d more files to edit. Quit anyway?"
+msgstr "vielä %d tiedostoa muokattavana, lopetetaanko silti?"
+
+msgid "E173: 1 more file to edit"
+msgstr "E173: vielä 1 tiedosto muokattavana"
+
+#, c-format
+msgid "E173: %ld more files to edit"
+msgstr "E173: vielä %ld tiedostoa muokattavana"
+
+msgid "E174: Command already exists: add ! to replace it"
+msgstr "E174: Komento on jo olemassa, käytä !:ä korvataksesi"
+
+msgid ""
+"\n"
+" Name Args Range Complete Definition"
+msgstr ""
+"\n"
+" Nimi Arg Arvot Valmis Määritelmä"
+
+msgid "No user-defined commands found"
+msgstr "Ei käyttäjän määrittelemiä komentoja"
+
+msgid "E175: No attribute specified"
+msgstr "E175: Ei attribuutteja määriteltynä"
+
+msgid "E176: Invalid number of arguments"
+msgstr "E176: Väärä määrä attribuutteja"
+
+msgid "E177: Count cannot be specified twice"
+msgstr "E177: Lukumäärää ei voi määritellä kahdesti"
+
+msgid "E178: Invalid default value for count"
+msgstr "E178: Lukumäärän oletusarvo on väärä"
+
+msgid "E179: argument required for -complete"
+msgstr "E179: -complete vaatii argumentin"
+
+#, c-format
+msgid "E181: Invalid attribute: %s"
+msgstr "E181: Virheellinen attribuutti: %s"
+
+msgid "E182: Invalid command name"
+msgstr "E182: Virheellinen komennon nimi"
+
+msgid "E183: User defined commands must start with an uppercase letter"
+msgstr "E183: Käyttäjän määrittelemän komennon pitää alkaa suuraakkosella"
+
+#, c-format
+msgid "E184: No such user-defined command: %s"
+msgstr "E184: Käyttäjän komentoa ei ole olemassa: %s"
+
+#, c-format
+msgid "E180: Invalid complete value: %s"
+msgstr "E180: Virheellinen täydennysarvo: %s"
+
+msgid "E468: Completion argument only allowed for custom completion"
+msgstr "E468: Täydennysargumentti sopii vain itse määriteltyyn täydennykseen"
+
+msgid "E467: Custom completion requires a function argument"
+msgstr "E467: Itse määritelty täydennys vaatii funktioargumentin"
+
+msgid "unknown"
+msgstr "tuntematon"
+
+#, c-format
+msgid "E185: Cannot find color scheme %s"
+msgstr "E185: Väriteemaa %s ei löydy"
+
+msgid "Greetings, Vim user!"
+msgstr "Tervehdys, Vimin käyttäjä."
+
+msgid "E784: Cannot close last tab page"
+msgstr "E784: Viimeistä välilehteä ei voi sulkea"
+
+msgid "Already only one tab page"
+msgstr "Vain yksi välilehti jäljellä enää"
+
+msgid "Edit File in new window"
+msgstr "Muokkaa uudessa ikkunassa"
+
+#, c-format
+msgid "Tab page %d"
+msgstr "Tabisivu %d"
+
+msgid "No swap file"
+msgstr "Ei swap-tiedostoa"
+
+msgid "Append File"
+msgstr "Lisää tiedostoon"
+
+msgid "E747: Cannot change directory, buffer is modified (add ! to override)"
+msgstr ""
+"E747: Hakemistoa ei voida muuttaa, puskuria on muokattu (lisää komentoon ! "
+"ohittaaksesi"
+
+msgid "E186: No previous directory"
+msgstr "E186: Ei edellistä hakemistoa"
+
+msgid "E187: Unknown"
+msgstr "E187: Tuntematon"
+
+msgid "E465: :winsize requires two number arguments"
+msgstr "E465: :winsize vaatii kaksi numeroargumenttia"
+
+#, c-format
+msgid "Window position: X %d, Y %d"
+msgstr "Ikkunan sijainti: X %d, Y %d"
+
+msgid "E188: Obtaining window position not implemented for this platform"
+msgstr "E188: Ikkunan sijainnin selvitys ei toimi tällä alustalla"
+
+msgid "E466: :winpos requires two number arguments"
+msgstr "E466: :winpos vaatii kaksi lukuargumenttia"
+
+msgid "Save Redirection"
+msgstr "Tallenna uudelleenosoitus"
+
+msgid "Save View"
+msgstr "Tallenna näkymä"
+
+msgid "Save Session"
+msgstr "Tallenna sessio"
+
+msgid "Save Setup"
+msgstr "Tallenna asetukset"
+
+#, c-format
+msgid "E739: Cannot create directory: %s"
+msgstr "E739: hakemistoa ei voi luoda: %s"
+
+#, c-format
+msgid "E189: \"%s\" exists (add ! to override)"
+msgstr "E189: %s on jo olemassa (lisää komentoon ! ohittaaksesi)"
+
+#, c-format
+msgid "E190: Cannot open \"%s\" for writing"
+msgstr "E190: Tiedostoa %s ei voitu avata kirjoittamista varten"
+
+#. set mark
+msgid "E191: Argument must be a letter or forward/backward quote"
+msgstr "E191: Argumentin eteen- tai taaksepäin lainaukseen pitää olla kirjain"
+
+msgid "E192: Recursive use of :normal too deep"
+msgstr "E192: :normalin liian syvä rekursio"
+
+msgid "E809: #< is not available without the +eval feature"
+msgstr "E809: #< ei ole käytössä jollei +eval ole päällä"
+
+msgid "E194: No alternate file name to substitute for '#'"
+msgstr "E194: Ei vaihtoehtoista tiedostonimeä #:lle"
+
+msgid "E495: no autocommand file name to substitute for \"<afile>\""
+msgstr "E495: ei autocommand-tiedostoa kohteelle <afile>"
+
+msgid "E496: no autocommand buffer number to substitute for \"<abuf>\""
+msgstr "E496: ei autocommand-puskurinumeroa kohteelle <abuf>"
+
+msgid "E497: no autocommand match name to substitute for \"<amatch>\""
+msgstr "E497: ei autocommand-täsmäysnimeä kohteella <amatch>"
+
+msgid "E498: no :source file name to substitute for \"<sfile>\""
+msgstr "E498: ei :source-tiedostonimeä kohteelle <sfile>"
+
+#, no-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 "E500: Evaluates to an empty string"
+msgstr "E500: Loppuarvo on tyhjä merkkijono"
+
+msgid "E195: Cannot open viminfo file for reading"
+msgstr "E195: Viminfoa ei voi avata lukemista varten"
+
+msgid "E196: No digraphs in this version"
+msgstr "E196: Digraafeja ei ole tässä versiossa"
+
+msgid "E608: Cannot :throw exceptions with 'Vim' prefix"
+msgstr "E608: Vim-alkuisia poikkeuksia ei voi heittää :throw-komennolla"
+
+#. always scroll up, don't overwrite
+#, c-format
+msgid "Exception thrown: %s"
+msgstr "Poikkeus heitetty: %s"
+
+#, c-format
+msgid "Exception finished: %s"
+msgstr "Poikkeus lopeteltu: %s"
+
+#, c-format
+msgid "Exception discarded: %s"
+msgstr "Poikkeus poistettu: %s"
+
+#, c-format
+msgid "%s, line %ld"
+msgstr "%s, rivi %ld"
+
+#. always scroll up, don't overwrite
+#, c-format
+msgid "Exception caught: %s"
+msgstr "Poikkeus otettu kiinni: %s"
+
+#, c-format
+msgid "%s made pending"
+msgstr "%s odotutettu"
+
+#, c-format
+msgid "%s resumed"
+msgstr "%s palautettu"
+
+#, c-format
+msgid "%s discarded"
+msgstr "%s poistettu"
+
+msgid "Exception"
+msgstr "Poikkeus"
+
+msgid "Error and interrupt"
+msgstr "Virhe ja keskeytys"
+
+msgid "Error"
+msgstr "Virhe"
+
+#. if (pending & CSTP_INTERRUPT)
+msgid "Interrupt"
+msgstr "Keskeytys"
+
+msgid "E579: :if nesting too deep"
+msgstr "E579: liian monta kerrosta :if-komennossa"
+
+msgid "E580: :endif without :if"
+msgstr "E580: :endif ilman komentoa :if"
+
+msgid "E581: :else without :if"
+msgstr "E581: :else ilman komentoa :if"
+
+msgid "E582: :elseif without :if"
+msgstr "E582: :elseif ilman komentoa :if"
+
+msgid "E583: multiple :else"
+msgstr "E583: :else monta kertaa"
+
+msgid "E584: :elseif after :else"
+msgstr "E584: :elseif komennon :else jälkeen"
+
+msgid "E585: :while/:for nesting too deep"
+msgstr "E585: liian monta tasoa :while- tai :for-komennoissa"
+
+msgid "E586: :continue without :while or :for"
+msgstr "E586: :continue ilman komentoa :while tai :for"
+
+msgid "E587: :break without :while or :for"
+msgstr "E587: :break ilman komentoa :while tai :for"
+
+msgid "E732: Using :endfor with :while"
+msgstr "E732: :endfor ilman komentoa :while"
+
+msgid "E733: Using :endwhile with :for"
+msgstr "E733: :endwhile ilman komentoa :for"
+
+msgid "E601: :try nesting too deep"
+msgstr "E601: liian monta tasoa :try-komennossa"
+
+msgid "E603: :catch without :try"
+msgstr "E603: :catch ilman komentoa :try"
+
+#. Give up for a ":catch" after ":finally" and ignore it.
+#. * Just parse.
+msgid "E604: :catch after :finally"
+msgstr "E604: :catch ilman komentoa :finally"
+
+msgid "E606: :finally without :try"
+msgstr "E606: :finally ilman komentoa :try"
+
+#. Give up for a multiple ":finally" and ignore it.
+msgid "E607: multiple :finally"
+msgstr "E607: :finally monta kertaa"
+
+msgid "E602: :endtry without :try"
+msgstr "E602: :endtry ilman komentoa :try"
+
+msgid "E193: :endfunction not inside a function"
+msgstr "E193: :endfunction funktion ulkopuolella"
+
+msgid "E788: Not allowed to edit another buffer now"
+msgstr "E788: Puskuria ei voi muokata nyt"
+
+msgid "E811: Not allowed to change buffer information now"
+msgstr "E811: Puskuria ei voi vaihtaa nyt"
+
+msgid "tagname"
+msgstr "täginimi"
+
+msgid " kind file\n"
+msgstr " -tiedostotyyppi\n"
+
+msgid "'history' option is zero"
+msgstr "history-asetus on nolla"
+
+#, c-format
+msgid ""
+"\n"
+"# %s History (newest to oldest):\n"
+msgstr ""
+"\n"
+"# %s Historia (uusimmasta alkaen):\n"
+
+msgid "Command Line"
+msgstr "Komentorivi"
+
+msgid "Search String"
+msgstr "Hakujono"
+
+msgid "Expression"
+msgstr "Ilmaus"
+
+msgid "Input Line"
+msgstr "Syöterivi"
+
+msgid "E198: cmd_pchar beyond the command length"
+msgstr "E198: cmd_pchar komennon pituuden ulkopuolella"
+
+msgid "E199: Active window or buffer deleted"
+msgstr "E199: Aktiivinen ikkuna tai puskuri poistettu"
+
+msgid "E812: Autocommands changed buffer or buffer name"
+msgstr "E812: Autocommands muutti puskurin tai sen nimen"
+
+msgid "Illegal file name"
+msgstr "Virheellinen tiedostonimi"
+
+msgid "is a directory"
+msgstr "on hakemisto"
+
+msgid "is not a file"
+msgstr "ei ole tiedosto"
+
+msgid "is a device (disabled with 'opendevice' option)"
+msgstr "on laite (ei käytössä opendevice-asetuksen takia)"
+
+msgid "[New File]"
+msgstr "[Uusi tiedosto]"
+
+msgid "[New DIRECTORY]"
+msgstr "[uusi HAKEMISTO]"
+
+msgid "[File too big]"
+msgstr "[Liian iso tiedosto]"
+
+msgid "[Permission Denied]"
+msgstr "[Lupa kielletty]"
+
+msgid "E200: *ReadPre autocommands made the file unreadable"
+msgstr ""
+"E200: *ReadPre-autocommand-komennot tekivät tiedostosta lukukelvottoman"
+
+msgid "E201: *ReadPre autocommands must not change current buffer"
+msgstr "E201: *ReadPre-autocommand-komennot eivät saa muuttaa puskuria"
+
+msgid "Vim: Reading from stdin...\n"
+msgstr "Vim: Luetaan vakiosyötteestä...\n"
+
+msgid "Reading from stdin..."
+msgstr "Luetaan vakiosyötteestä"
+
+#. Re-opening the original file failed!
+msgid "E202: Conversion made file unreadable!"
+msgstr "E202: Muunnos teki tiedostosta lukukelvottoman."
+
+msgid "[fifo/socket]"
+msgstr "[fifo t. soketti]"
+
+msgid "[fifo]"
+msgstr "[fifo]"
+
+msgid "[socket]"
+msgstr "[soketti]"
+
+msgid "[character special]"
+msgstr "[merkki erikoinen]"
+
+msgid "[RO]"
+msgstr "[Luku]"
+
+# Carriage Return elikkä rivinvaihtomerkin eräs muoto/osa (vrt. LF)
+msgid "[CR missing]"
+msgstr "[CR puuttuu]"
+
+msgid "[long lines split]"
+msgstr "[pitkät rivit hajotettu]"
+
+msgid "[NOT converted]"
+msgstr "[EI muunnettu]"
+
+msgid "[converted]"
+msgstr "[muunnettu]"
+
+msgid "[crypted]"
+msgstr "[salattu]"
+
+#, c-format
+msgid "[CONVERSION ERROR in line %ld]"
+msgstr "[MUUNNOSVIRHE rivillä %ld]"
+
+#, c-format
+msgid "[ILLEGAL BYTE in line %ld]"
+msgstr "[VIRHEELLINEN OKTETTI rivillä %ld]"
+
+msgid "[READ ERRORS]"
+msgstr "[LUKUVIRHEITÄ]"
+
+msgid "Can't find temp file for conversion"
+msgstr "Ei voi löytää väliaikaistiedstoa muuntamiseksi"
+
+msgid "Conversion with 'charconvert' failed"
+msgstr "Muunnos charconvert epäonnistui"
+
+msgid "can't read output of 'charconvert'"
+msgstr "charconvertin tulostetta ei voida lukea"
+
+msgid "E821: File is encrypted with unknown method"
+msgstr "E821: Tiedoston salaus on tuntematon"
+
+msgid "E676: No matching autocommands for acwrite buffer"
+msgstr "E676: Ei autocommand-komentoa acwrite-puskurille"
+
+msgid "E203: Autocommands deleted or unloaded buffer to be written"
+msgstr ""
+"E203: Autocommand-komennot poistivat tai vapauttivat puskurin, johon piti "
+"kirjoittaa"
+
+msgid "E204: Autocommand changed number of lines in unexpected way"
+msgstr "E204: Autocommand-komento muutti rivien määrä odottamatta"
+
+msgid "NetBeans disallows writes of unmodified buffers"
+msgstr "NetBeans ei salli kirjoittaa muokkaamattomiin puskureihin"
+
+msgid "Partial writes disallowed for NetBeans buffers"
+msgstr "Osittaiset kirjoitukset kielletty NetBeans-puskureissa"
+
+msgid "is not a file or writable device"
+msgstr "ei ole tiedosto tai kirjoitettava laite"
+
+msgid "writing to device disabled with 'opendevice' option"
+msgstr "laitteeseen kirjoittaminen pois käytöstä opendevice-asetuksella"
+
+msgid "is read-only (add ! to override)"
+msgstr "on kirjoitussuojattu (lisää komentoon ! ohittaaksesi)"
+
+msgid "E506: Can't write to backup file (add ! to override)"
+msgstr ""
+"E506: Ei voi kirjoittaa varmuuskopiotiedostoon (lisää komentoon ! "
+"ohittaaksesi)"
+
+msgid "E507: Close error for backup file (add ! to override)"
+msgstr ""
+"E507: Varmuuskopiotiedoston sulkeminen ei onnistu (lisää komentoon ! "
+"ohittaaksesi)"
+
+msgid "E508: Can't read file for backup (add ! to override)"
+msgstr ""
+"E508: Varmuuskopiotiedostoa ei voi lukea (lisää komentoon ! ohittaaksesi)"
+
+msgid "E509: Cannot create backup file (add ! to override)"
+msgstr ""
+"E509: Ei voi luoda varmuuskopiotiedostoa (lisää komentoon ! ohittaaksesi)"
+
+msgid "E510: Can't make backup file (add ! to override)"
+msgstr ""
+"E510: Ei voi tehdä varmuuskopiotiedostoa (lisää komentoon ! ohittaaksesi)"
+
+# 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 "E214: Can't find temp file for writing"
+msgstr "E214: Ei voi löytää väliaikaistiedostoa kirjoitettavaksi"
+
+msgid "E213: Cannot convert (add ! to write without conversion)"
+msgstr ""
+"E213: Muunnos ei onnistu (lisää komentoon ! kirjoittaaksesi muuntamatta)"
+
+msgid "E166: Can't open linked file for writing"
+msgstr "E166: Linkitetyn tiedoston avaus kirjoittamista varten ei onnistu"
+
+msgid "E212: Can't open file for writing"
+msgstr "E212: Tiedoston avaus kirjoittamista varten ei onnistu"
+
+msgid "E667: Fsync failed"
+msgstr "E667: Fsync ei onnistunut"
+
+msgid "E512: Close failed"
+msgstr "E512: Sulkeminen ei onnistunut"
+
+msgid "E513: write error, conversion failed (make 'fenc' empty to override)"
+msgstr "E513: kirjoitusvirhe, muunnos epäonnistui (tyhjää fenc ohittaaksesi)"
+
+#, c-format
+msgid ""
+"E513: write error, conversion failed in line %ld (make 'fenc' empty to "
+"override)"
+msgstr "E513: kirjoitusvirhe, muunnos epäonnistui rivillä %ld"
+"(tyhjää fenc ohittaaksesi)"
+
+msgid "E514: write error (file system full?)"
+msgstr "E514: kirjoitusvirhe (tiedostojärjestelmä täysi)"
+
+msgid " CONVERSION ERROR"
+msgstr " MUUNNOSVIRHE"
+
+#, c-format
+msgid " in line %ld;"
+msgstr " rivillä %ld"
+
+msgid "[Device]"
+msgstr "[Laite]"
+
+msgid "[New]"
+msgstr "[Uusi]"
+
+msgid " [a]"
+msgstr " [a]"
+
+msgid " appended"
+msgstr " lisätty"
+
+msgid " [w]"
+msgstr " [w]"
+
+msgid " written"
+msgstr " kirjoitettu"
+
+msgid "E205: Patchmode: can't save original file"
+msgstr "E205: Patch-tilassa ei voi tallentaa alkuperäistiedostoa"
+
+msgid "E206: patchmode: can't touch empty original file"
+msgstr "E206: patch-tilassa ei voi muuttaa tyhjää alkuperäistiedostoa"
+
+msgid "E207: Can't delete backup file"
+msgstr "E207: Ei voi poistaa varmuuskopiota"
+
+msgid ""
+"\n"
+"WARNING: Original file may be lost or damaged\n"
+msgstr ""
+"\n"
+"VAROITUS: Alkuperäistiedosto voi hävitä tai vahingoittua\n"
+
+msgid "don't quit the editor until the file is successfully written!"
+msgstr "älä lopeta editoria kesken tallentamisen."
+
+msgid "[dos]"
+msgstr "[dos]"
+
+msgid "[dos format]"
+msgstr "[dos-muoto]"
+
+msgid "[mac]"
+msgstr "[mac]"
+
+msgid "[mac format]"
+msgstr "[mac-muoto]"
+
+msgid "[unix]"
+msgstr "[unix]"
+
+msgid "[unix format]"
+msgstr "[unix-muoto]"
+
+msgid "1 line, "
+msgstr "1 rivi, "
+
+#, c-format
+msgid "%ld lines, "
+msgstr "%ld riviä, "
+
+msgid "1 character"
+msgstr "1 merkki"
+
+#, c-format
+msgid "%lld characters"
+msgstr "%lld merkkiä"
+
+#. Explicit typecast avoids warning on Mac OS X 10.6
+#, c-format
+msgid "%ld characters"
+msgstr "%ld merkkiä"
+
+# ei rivinvaihtoja
+msgid "[noeol]"
+msgstr "[eiriviv.]"
+
+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
+msgid "WARNING: The file has been changed since reading it!!!"
+msgstr "VAROITUS: tiedosto on muuttunut viime lukukerran jälkeen!"
+
+msgid "Do you really want to write to it"
+msgstr "Kirjoitetaanko"
+
+#, c-format
+msgid "E208: Error writing to \"%s\""
+msgstr "E208: Virhe kirjoitettaessa tiedostoon %s"
+
+#, c-format
+msgid "E209: Error closing \"%s\""
+msgstr "E209: Virhe suljettaessa tiedostoa %s"
+
+#, c-format
+msgid "E210: Error reading \"%s\""
+msgstr "E210: Virhe luettaessa tiedostoa %s"
+
+msgid "E246: FileChangedShell autocommand deleted buffer"
+msgstr "E246: FileChangedShell-autocommand poisti puskurin"
+
+#, c-format
+msgid "E211: File \"%s\" no longer available"
+msgstr "E211: Tiedostoa %s ei ole enää"
+
+#, c-format
+msgid ""
+"W12: Warning: File \"%s\" has changed and the buffer was changed in Vim as "
+"well"
+msgstr ""
+"W12: Varoitus: Tiedostoa %s on muutettu ja Vimin puskurissa on muutoksia "
+"tiedostoon"
+
+msgid "See \":help W12\" for more info."
+msgstr ":help W12 kertoo lisätietoja."
+
+#, c-format
+msgid "W11: Warning: File \"%s\" has changed since editing started"
+msgstr "W11: Varoitus: Tiedostoa %s on muutettu muokkauksen aloituksen jälkeen"
+
+msgid "See \":help W11\" for more info."
+msgstr ":help W11 kertoo lisätietoja."
+
+#, 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"
+
+msgid "See \":help W16\" for more info."
+msgstr ":help W16 kertoo lisätietoja."
+
+#, c-format
+msgid "W13: Warning: File \"%s\" has been created after editing started"
+msgstr "W13: Varoitus: Tiedosto %s on luotu muokkauksen aloituksen jälkeen"
+
+msgid "Warning"
+msgstr "Varoitus"
+
+# yllä olevien varoitusten ratkaisut
+msgid ""
+"&OK\n"
+"&Load File"
+msgstr ""
+"&OK\n"
+"&Avaa tiedosto uudelleen"
+
+#, c-format
+msgid "E462: Could not prepare for reloading \"%s\""
+msgstr "E462: Ei voitu valmistella uudelleen avausta %s"
+
+#, c-format
+msgid "E321: Could not reload \"%s\""
+msgstr "E321: Ei voitu uudelleenavata %s"
+
+msgid "--Deleted--"
+msgstr "--Poistettu--"
+
+#, c-format
+msgid "auto-removing autocommand: %s <buffer=%d>"
+msgstr "poistetaan autocommand automaattisesti: %s <puskuri=%d>"
+
+#. the group doesn't exist
+#, c-format
+msgid "E367: No such group: \"%s\""
+msgstr "E367: Ryhmää ei ole: %s"
+
+#, c-format
+msgid "E215: Illegal character after *: %s"
+msgstr "E215: Virheellinen merkki *:n jälkeen: %s"
+
+#, c-format
+msgid "E216: No such event: %s"
+msgstr "E216: Eventtiä ei ole: %s"
+
+#, c-format
+msgid "E216: No such group or event: %s"
+msgstr "E216: Ryhmää tai eventtiä ei ole: %s"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Auto-Commands ---"
+msgstr ""
+"\n"
+"--- Autocommandit ---"
+
+#, c-format
+msgid "E680: <buffer=%d>: invalid buffer number "
+msgstr "E680: <puskuri=%d>: virheellinen puskurinumero"
+
+msgid "E217: Can't execute autocommands for ALL events"
+msgstr "E217: Ei voi suorittaa autocommandsia kaikille eventeille"
+
+msgid "No matching autocommands"
+msgstr "Ei täsmääviä autocommandsia"
+
+msgid "E218: autocommand nesting too deep"
+msgstr "E218: liian monta tasoa autocommandissa"
+
+#, c-format
+msgid "%s Auto commands for \"%s\""
+msgstr "%s Autocommands kohteelle %s"
+
+#, c-format
+msgid "Executing %s"
+msgstr "Suoritetaan %s"
+
+#, c-format
+msgid "autocommand %s"
+msgstr "autocommand %s"
+
+msgid "E219: Missing {."
+msgstr "E219: { puuttuu."
+
+msgid "E220: Missing }."
+msgstr "E220: } puuttuu."
+
+msgid "E490: No fold found"
+msgstr "E490: taitos puuttuu"
+
+msgid "E350: Cannot create fold with current 'foldmethod'"
+msgstr "E350: Taitoksia ei voi tehdä tällä foldmethodilla"
+
+msgid "E351: Cannot delete fold with current 'foldmethod'"
+msgstr "E351: Taitosta ei voi poistaa tällä foldmethodilla"
+
+#, c-format
+msgid "+--%3ld lines folded "
+msgstr "+--%3ld riviä taitettu pois "
+
+msgid "E222: Add to read buffer"
+msgstr "E222: Lisää lukupuskuriin"
+
+msgid "E223: recursive mapping"
+msgstr "E223: rekursiivinen kuvaus"
+
+#, c-format
+msgid "E224: global abbreviation already exists for %s"
+msgstr "E224: globaali lyhenne merkinnälle %s on jo olemassa"
+
+#, c-format
+msgid "E225: global mapping already exists for %s"
+msgstr "E225: globaali kuvaus merkinnälle %s on jo olemassa"
+
+#, c-format
+msgid "E226: abbreviation already exists for %s"
+msgstr "E226: lyhenne on jo olemassa %s"
+
+#, c-format
+msgid "E227: mapping already exists for %s"
+msgstr "E227: kuvaus on jo olemassa %s"
+
+msgid "No abbreviation found"
+msgstr "Lyhennettä ei löydy"
+
+msgid "No mapping found"
+msgstr "Kuvausta ei löydy"
+
+msgid "E228: makemap: Illegal mode"
+msgstr "E228: makemap: Virheellinen tila"
+
+msgid "<cannot open> "
+msgstr "<ei voi avata> "
+
+#, c-format
+msgid "E616: vim_SelFile: can't get font %s"
+msgstr "E616: vim_SelFile: ei saada fonttia %s"
+
+msgid "E614: vim_SelFile: can't return to current directory"
+msgstr "E614: vim_SelFile: nykyiseen hakemistoon ei voi palata"
+
+msgid "Pathname:"
+msgstr "Polku:"
+
+msgid "E615: vim_SelFile: can't get current directory"
+msgstr "E615: vim_SelFile: nykyistä hakemistoa ei saada selville"
+
+msgid "OK"
+msgstr "OK"
+
+msgid "Cancel"
+msgstr "Peru"
+
+msgid "Vim dialog"
+msgstr "Vim-ikkuna"
+
+msgid "Scrollbar Widget: Could not get geometry of thumb pixmap."
+msgstr "Vierityspalkki: Pixmapin geometria ei selviä"
+
+msgid "E232: Cannot create BalloonEval with both message and callback"
+msgstr "E232: Ei voi luoda BalloonEvalia viestille ja callbackille"
+
+msgid "E229: Cannot start the GUI"
+msgstr "E229: GUIn käynnistys ei onnistu"
+
+#, c-format
+msgid "E230: Cannot read from \"%s\""
+msgstr "E230: Ei voi lukea kohteesta %s"
+
+msgid "E665: Cannot start GUI, no valid font found"
+msgstr "E665: Ei voi avata GUIta, sopivaa fonttia ei löydy"
+
+msgid "E231: 'guifontwide' invalid"
+msgstr "E231: guifontwide virheellinen"
+
+msgid "E599: Value of 'imactivatekey' is invalid"
+msgstr "E599: imactivatekeyn arvo on virheellinen"
+
+#, c-format
+msgid "E254: Cannot allocate color %s"
+msgstr "E254: Väriä %s ei voi määritellä"
+
+msgid "No match at cursor, finding next"
+msgstr "Ei täsmäystä kursorin alla, etsitään seuraava"
+
+msgid ""
+"&Yes\n"
+"&No\n"
+"&Cancel"
+msgstr ""
+"&Kyllä\n"
+"&Ei\n"
+"&Peru"
+
+msgid "Input _Methods"
+msgstr "Syöte_menetelmät"
+
+msgid "VIM - Search and Replace..."
+msgstr "VIM - Etsi ja korvaa..."
+
+msgid "VIM - Search..."
+msgstr "VIM - Etsi..."
+
+msgid "Find what:"
+msgstr "Etsi:"
+
+msgid "Replace with:"
+msgstr "Korvaa:"
+
+#. whole word only button
+msgid "Match whole word only"
+msgstr "Korvaa kokonaisia sanoja"
+
+#. match case button
+msgid "Match case"
+msgstr "Kirjaintaso"
+
+msgid "Direction"
+msgstr "Suunta"
+
+#. 'Up' and 'Down' buttons
+msgid "Up"
+msgstr "Ylös"
+
+msgid "Down"
+msgstr "Alas"
+
+#. 'Find Next' button
+msgid "Find Next"
+msgstr "Etsi seuraava"
+
+#. 'Replace' button
+msgid "Replace"
+msgstr "Korvaa"
+
+#. 'Replace All' button
+msgid "Replace All"
+msgstr "Korvaa kaikki"
+
+msgid "Vim: Received \"die\" request from session manager\n"
+msgstr "Vim: sessiomanageri lähetti die-pyynnön\n"
+
+msgid "Close"
+msgstr "Sulje"
+
+msgid "New tab"
+msgstr "Uusi välilehti"
+
+msgid "Open Tab..."
+msgstr "Avaa välilehti..."
+
+msgid "Vim: Main window unexpectedly destroyed\n"
+msgstr "Vim: Pääikkuna tuhoutui odottamatta\n"
+
+msgid "&Filter"
+msgstr "&Suodata"
+
+msgid "&Cancel"
+msgstr "&Peru"
+
+msgid "Directories"
+msgstr "Hakemistot"
+
+msgid "Filter"
+msgstr "Suodatus"
+
+msgid "&Help"
+msgstr "O&hje"
+
+msgid "Files"
+msgstr "Tiedostot"
+
+msgid "&OK"
+msgstr "&Ok"
+
+msgid "Selection"
+msgstr "Valinta"
+
+msgid "Find &Next"
+msgstr "Hae &seuraava"
+
+msgid "&Replace"
+msgstr "Ko&rvaa"
+
+msgid "Replace &All"
+msgstr "Korvaa k&aikki"
+
+msgid "&Undo"
+msgstr "&Kumoa"
+
+#, c-format
+msgid "E671: Cannot find window title \"%s\""
+msgstr "E671: Ikkunan otsikkoa ei löydy %s"
+
+# OLE on object linking and embedding på windowska
+#, c-format
+msgid "E243: Argument not supported: \"-%s\"; Use the OLE version."
+msgstr "E243: Argumenttia ei tueta: -%s, käytä OLE-versiota"
+
+# MDI eli windowsin moni-ikkunasovellus
+msgid "E672: Unable to open window inside MDI application"
+msgstr "E672: Ikkunaa ei voitu avata MDI-sovellukseen"
+
+msgid "Close tab"
+msgstr "Sulje välilehti"
+
+msgid "Open tab..."
+msgstr "Avaa välilehti..."
+
+msgid "Find string (use '\\\\' to find a '\\')"
+msgstr "Etsi merkkijonoa (\\\\:llä löytää \\:t)"
+
+msgid "Find & Replace (use '\\\\' to find a '\\')"
+msgstr "Etsi ja korvaa (\\\\:llä löytää \\:t)"
+
+#. 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 "Ei käytössä"
+
+msgid "Directory\t*.nothing\n"
+msgstr "Hakemisto\t*.nothing\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"
+
+#, c-format
+msgid "E250: Fonts for the following charsets are missing in fontset %s:"
+msgstr "E250: Seuraavien merkistöjoukkojen fontit puuttuvat fontsetistä %s:"
+
+#, c-format
+msgid "E252: Fontset name: %s"
+msgstr "E252: Fontsetin nimi: %s"
+
+#, c-format
+msgid "Font '%s' is not fixed-width"
+msgstr "Fontti %s ei ole tasavälinen"
+
+#, c-format
+msgid "E253: Fontset name: %s\n"
+msgstr "E253: Fontsetin nimi: %s\n"
+
+#, c-format
+msgid "Font0: %s\n"
+msgstr "Fontti0: %s\n"
+
+#, c-format
+msgid "Font1: %s\n"
+msgstr "Fontti1: %s\n"
+
+#, c-format
+msgid "Font%ld width is not twice that of font0\n"
+msgstr "Fontti%ld:n leveys ei ole kaksi kertaa fontti0:n\n"
+
+#, c-format
+msgid "Font0 width: %ld\n"
+msgstr "Fontti0:n leveys: %ld\n"
+
+#, c-format
+msgid ""
+"Font1 width: %ld\n"
+"\n"
+msgstr ""
+"Fontti1:n leveys: %ld\n"
+"\n"
+
+msgid "Invalid font specification"
+msgstr "Virheellinen fonttimääritys"
+
+msgid "&Dismiss"
+msgstr "&Ohita"
+
+msgid "no specific match"
+msgstr "ei tarkkaa täsmäystä"
+
+msgid "Vim - Font Selector"
+msgstr "Vim - fonttivalitsin"
+
+msgid "Name:"
+msgstr "Nimi:"
+
+#. create toggle button
+msgid "Show size in Points"
+msgstr "Näytä koko pisteinä"
+
+msgid "Encoding:"
+msgstr "Koodaus:"
+
+msgid "Font:"
+msgstr "Fontti:"
+
+msgid "Style:"
+msgstr "Tyyli:"
+
+msgid "Size:"
+msgstr "Koko:"
+
+msgid "E256: Hangul automata ERROR"
+msgstr "E256: Hangu-automaattivirhe"
+
+msgid "E550: Missing colon"
+msgstr "E550: kaksoispiste puuttuu"
+
+msgid "E551: Illegal component"
+msgstr "E551: Virheellinen komponentti"
+
+msgid "E552: digit expected"
+msgstr "E552: pitäisi olla numero"
+
+#, c-format
+msgid "Page %d"
+msgstr "Sivu %d"
+
+msgid "No text to be printed"
+msgstr "Ei tekstiä tulostettavaksi"
+
+#, c-format
+msgid "Printing page %d (%d%%)"
+msgstr "Tulostetaan sivua %d (%d %%)"
+
+#, c-format
+msgid " Copy %d of %d"
+msgstr " Kopio %d/%d"
+
+#, c-format
+msgid "Printed: %s"
+msgstr "Tulostettu: %s"
+
+msgid "Printing aborted"
+msgstr "Tulostus peruttu"
+
+msgid "E455: Error writing to PostScript output file"
+msgstr "E455: Virhe kirjoitettaessa PostScriptiä tiedostoon"
+
+#, c-format
+msgid "E624: Can't open file \"%s\""
+msgstr "E624: Ei voi avata tiedostoa %s"
+
+#, c-format
+msgid "E457: Can't read PostScript resource file \"%s\""
+msgstr "E457: Ei voi lukea PostScript-resurssitiedostoa %s"
+
+#, c-format
+msgid "E618: file \"%s\" is not a PostScript resource file"
+msgstr "E618: tiedosto %s ei ole PostScript-resurssitiedosto"
+
+#, c-format
+msgid "E619: file \"%s\" is not a supported PostScript resource file"
+msgstr "E619: tiedosto %s ei ole tuettu PostScript-resurssitiedosto"
+
+#, c-format
+msgid "E621: \"%s\" resource file has wrong version"
+msgstr "E621: resurssitiedoston %s versio on väärä"
+
+msgid "E673: Incompatible multi-byte encoding and character set."
+msgstr "E673: Tukematon monitvauinen merkistökoodaus ja merkistö."
+
+msgid "E674: printmbcharset cannot be empty with multi-byte encoding."
+msgstr "E674: printmbcharset ei voi olla tyhjä monitavuiselle koodaukselle."
+
+msgid "E675: No default font specified for multi-byte printing."
+msgstr "E675: Ei oletusfonttia monitavuiseen tulostukseen"
+
+msgid "E324: Can't open PostScript output file"
+msgstr "E324: PostScript-tulostetiedoston avaus ei onnistu"
+
+#, c-format
+msgid "E456: Can't open file \"%s\""
+msgstr "E456: Tiedoston %s avaus ei onnistu"
+
+msgid "E456: Can't find PostScript resource file \"prolog.ps\""
+msgstr "E456: PostScript-resurssitiedostoa prolog.ps ei löydy"
+
+msgid "E456: Can't find PostScript resource file \"cidfont.ps\""
+msgstr "E456: PostScript-resurssitiedostoa cidfont.ps ei löydy"
+
+#, c-format
+msgid "E456: Can't find PostScript resource file \"%s.ps\""
+msgstr "E456: Postscript-resurssitiedosta %s.ps ei löydy"
+
+#, c-format
+msgid "E620: Unable to convert to print encoding \"%s\""
+msgstr "E620: Tulostuskoodaukseen %s muunto ei onnistu"
+
+msgid "Sending to printer..."
+msgstr "Lähetetään tulostimelle..."
+
+msgid "E365: Failed to print PostScript file"
+msgstr "E365: PostScript-tiedoston tulostus epäonnistui"
+
+msgid "Print job sent."
+msgstr "Tulostustyö lähetetty."
+
+msgid "Add a new database"
+msgstr "Lisää uusi tietokanta"
+
+msgid "Query for a pattern"
+msgstr "Hae kuviota"
+
+msgid "Show this message"
+msgstr "Näytä tämä viesti"
+
+msgid "Kill a connection"
+msgstr "Tapa yhteys"
+
+msgid "Reinit all connections"
+msgstr "Alusta uudelleen yhteydet"
+
+msgid "Show connections"
+msgstr "Näytä yhteydet"
+
+#, c-format
+msgid "E560: Usage: cs[cope] %s"
+msgstr "E560: Käyttö: cs[cope] %s"
+
+msgid "This cscope command does not support splitting the window.\n"
+msgstr "Tämä cscope-komento ei tue ikkunan jakamista.\n"
+
+msgid "E562: Usage: cstag <ident>"
+msgstr "E562: Käyttö: cstag <ident>"
+
+msgid "E257: cstag: tag not found"
+msgstr "E257: cstag: tägia ei löydy"
+
+#, c-format
+msgid "E563: stat(%s) error: %d"
+msgstr "E563: stat(%s)-virhe: %d"
+
+msgid "E563: stat error"
+msgstr "E563: stat-virhe"
+
+#, c-format
+msgid "E564: %s is not a directory or a valid cscope database"
+msgstr "E564: %s ei ole hakemisto eikä cscope-tietokanta"
+
+#, c-format
+msgid "Added cscope database %s"
+msgstr "Lisätty cscope-tietokanta %s"
+
+#, c-format
+msgid "E262: error reading cscope connection %ld"
+msgstr "E262: Virhe luettaessa cscope-yhteyttä %ld"
+
+msgid "E561: unknown cscope search type"
+msgstr "E561: tuntematon cscope-hakutyyppi"
+
+msgid "E566: Could not create cscope pipes"
+msgstr "E566: Ei voitu luoda cscope-putkia"
+
+msgid "E622: Could not fork for cscope"
+msgstr "E622: Ei voitu haarauttaa cscopea"
+
+msgid "cs_create_connection exec failed"
+msgstr "cs_create_connection epäonnistui"
+
+msgid "cs_create_connection: fdopen for to_fp failed"
+msgstr "cs_create_connection: fdopen to_fp epäonnistui"
+
+msgid "cs_create_connection: fdopen for fr_fp failed"
+msgstr "cs_create_connection: fdopen fr_fp epäonnistui"
+
+msgid "E623: Could not spawn cscope process"
+msgstr "E623: Cscope-prosessin luonti epäonnistui"
+
+msgid "E567: no cscope connections"
+msgstr "E567: ei cscope-yhteyksiä"
+
+#, c-format
+msgid "E469: invalid cscopequickfix flag %c for %c"
+msgstr "E469: virheellinen cscopequickfix-asetus %c kohteelle %c"
+
+#, c-format
+msgid "E259: no matches found for cscope query %s of %s"
+msgstr "E259: ei täsmäyksiä cscope-hakuun %s/%s"
+
+msgid "cscope commands:\n"
+msgstr "cscope-komennot:\n"
+
+#, c-format
+msgid "%-5s: %s%*s (Usage: %s)"
+msgstr "%-5s: %s%*s (Käyttö: %s)"
+
+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 assignments to\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"
+" t: Etsi sijoitukset muuttujaan \n"
+
+#, c-format
+msgid "E625: cannot open cscope database: %s"
+msgstr "E625: ei voi avata cscope-tietokantaa: %s"
+
+msgid "E626: cannot get cscope database information"
+msgstr "E626: ei voi hakea cscope-tietokannan tietoja"
+
+msgid "E568: duplicate cscope database not added"
+msgstr "E568: kaksoiskappaletta cscope-tietokannasta ei lisätty"
+
+#, c-format
+msgid "E261: cscope connection %s not found"
+msgstr "E261: cscope-yhteys %s puuttuu"
+
+#, c-format
+msgid "cscope connection %s closed"
+msgstr "cscope-yhteys %s on katkaistu"
+
+#. should not reach here
+msgid "E570: fatal error in cs_manage_matches"
+msgstr "E570: kriittinen virhe cs_manage_matches-funktiossa"
+
+#, c-format
+msgid "Cscope tag: %s"
+msgstr "Cscope-tägi: %s"
+
+msgid ""
+"\n"
+" # line"
+msgstr ""
+"\n"
+" # rivi"
+
+msgid "filename / context / line\n"
+msgstr "tiedosto / konteksti / rivi\n"
+
+#, c-format
+msgid "E609: Cscope error: %s"
+msgstr "E609: Cscope-virhe: %s"
+
+msgid "All cscope databases reset"
+msgstr "Kaikki cscope-tietokannat nollattu"
+
+msgid "no cscope connections\n"
+msgstr "ei cscope-yhteyksiä\n"
+
+msgid " # pid database name prepend path\n"
+msgstr " # pid tietokanta lisäyspolku\n"
+
+msgid "Lua library cannot be loaded."
+msgstr "Luan kirjastoa ei voitu ladata."
+
+msgid "cannot save undo information"
+msgstr "ei voitu tallentaa kumoustietoja"
+
+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 "invalid expression"
+msgstr "virheellinen ilmaus"
+
+msgid "expressions disabled at compile time"
+msgstr "ilmaukset poistettu käytöstä käännösaikana"
+
+msgid "hidden option"
+msgstr "piilotettu asetus"
+
+msgid "unknown option"
+msgstr "tuntematon asetus"
+
+msgid "window index is out of range"
+msgstr "ikkunan indeksi alueen ulkopuolella"
+
+msgid "couldn't open buffer"
+msgstr "ei voitu avata puskuria"
+
+msgid "cannot delete line"
+msgstr "ei voitu poistaa riviä"
+
+msgid "cannot replace line"
+msgstr "ei voitu korvata riviä"
+
+msgid "cannot insert line"
+msgstr "ei voitu lisätä riviä"
+
+msgid "string cannot contain newlines"
+msgstr "merkkijono ei saa sisältää rivinvaihtoja"
+
+msgid "Vim error: ~a"
+msgstr "Vim-virhe: ~a"
+
+msgid "Vim error"
+msgstr "Vim-virhe"
+
+msgid "buffer is invalid"
+msgstr "puskuri on virheellinen"
+
+msgid "window is invalid"
+msgstr "ikkuna on virheellinen"
+
+msgid "linenr out of range"
+msgstr "rivinumero arvoalueen ulkopuolelta"
+
+msgid "not allowed in the Vim sandbox"
+msgstr "ei sallittu Vimin hiekkalaatikossa"
+
+msgid "E836: This Vim cannot execute :python after using :py3"
+msgstr "E836: Python: Ei voi käyttää komentoja :py ja :py3 samassa istunnossa"
+
+msgid "E837: This Vim cannot execute :py3 after using :python"
+msgstr "E837: Python: Ei voi käyttää komentoja :py ja :py3 samassa istunnossa"
+
+msgid ""
+"E263: Sorry, this command is disabled, the Python library could not be "
+"loaded."
+msgstr ""
+"E263: Sori, komento ei toimi, Python-kirjaston lataaminen ei onnistunut."
+
+msgid "can't delete OutputObject attributes"
+msgstr "ei voi poistaa OutputObject-attribuutteja"
+
+msgid "softspace must be an integer"
+msgstr "softspacen pitää olla kokonaisluku"
+
+msgid "invalid attribute"
+msgstr "virheellinen attribuutti"
+
+#, c-format
+msgid "<buffer object (deleted) at %p>"
+msgstr "<puskuriolio (poistettu) kohdassa %p>"
+
+msgid "E659: Cannot invoke Python recursively"
+msgstr "E659: Pythonia ei voi kutsua rekursiivisesti"
+
+msgid "E265: $_ must be an instance of String"
+msgstr "E265: muuttujan $_ pitää olla Stringin instanssi"
+
+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."
+
+msgid "E267: unexpected return"
+msgstr "E267: odotuksenvastainen return"
+
+msgid "E268: unexpected next"
+msgstr "E268: Odotuksenvastainen next"
+
+msgid "E269: unexpected break"
+msgstr "E269: Odotuksenvastainen break"
+
+msgid "E270: unexpected redo"
+msgstr "E270: odotuksenvastainen redo"
+
+msgid "E271: retry outside of rescue clause"
+msgstr "E271: retry rescuen ulkopuolella"
+
+msgid "E272: unhandled exception"
+msgstr "E272: käsittelemätön poikkeus"
+
+#, c-format
+msgid "E273: unknown longjmp status %d"
+msgstr "E273: tuntematon longjmp-tila %d"
+
+msgid "Toggle implementation/definition"
+msgstr "Vaihda toteutuksen ja määritelmän välillä"
+
+msgid "Show base class of"
+msgstr "Näytä kantaluokka kohteelle"
+
+msgid "Show overridden member function"
+msgstr "Näytä korvattu jäsenfunktio"
+
+msgid "Retrieve from file"
+msgstr "Jäljitä tiedostosta"
+
+msgid "Retrieve from project"
+msgstr "Jäljitä projektista"
+
+msgid "Retrieve from all projects"
+msgstr "Jäljitä kaikista projekteista"
+
+msgid "Retrieve"
+msgstr "Jäljitä"
+
+msgid "Show source of"
+msgstr "Näytä lähdekoodi kohteelle"
+
+msgid "Find symbol"
+msgstr "Etsi symboli"
+
+msgid "Browse class"
+msgstr "Selaa luokkaa"
+
+msgid "Show class in hierarchy"
+msgstr "Näytä luokka hierarkiassa"
+
+msgid "Show class in restricted hierarchy"
+msgstr "Näytä luokka rajoitetussa hierarkiassa"
+
+msgid "Xref refers to"
+msgstr "Xref viittaa kohteeseen"
+
+msgid "Xref referred by"
+msgstr "Xref viitattu kohteesta"
+
+msgid "Xref has a"
+msgstr "Xref sisältää kohteen"
+
+msgid "Xref used by"
+msgstr "Xrefiä käyttää"
+
+msgid "Show docu of"
+msgstr "Näytä dokumentti kohteelle"
+
+msgid "Generate docu for"
+msgstr "Luo dokumentti kohteelle"
+
+msgid ""
+"Cannot connect to SNiFF+. Check environment (sniffemacs must be found in "
+"$PATH).\n"
+msgstr ""
+"Ei voida yhdistää SNiFF+:aan. Tarkista ympäristömuuttujat (sniffemacsin "
+"löytyä polkumuuttujasta $PATH).\n"
+
+msgid "E274: Sniff: Error during read. Disconnected"
+msgstr "E274: Sniff: Virhe luettaessa, yhteys katkaistu"
+
+msgid "SNiFF+ is currently "
+msgstr "SNiFF+ "
+
+msgid "not "
+msgstr "ei ole "
+
+msgid "connected"
+msgstr "yhdistetty"
+
+#, c-format
+msgid "E275: Unknown SNiFF+ request: %s"
+msgstr "E275: Tuntematon SNiFF+-pyyntö: %s"
+
+msgid "E276: Error connecting to SNiFF+"
+msgstr "E276: Virhe yhdistettäessä SNiFF+:aan"
+
+msgid "E278: SNiFF+ not connected"
+msgstr "E278: SNiFF+ ei ole yhdistetty"
+
+msgid "E279: Not a SNiFF+ buffer"
+msgstr "E279: Ei ole SNiFF+-puskuri"
+
+msgid "Sniff: Error during write. Disconnected"
+msgstr "Sniff: Virhe kirjoituksessa, yhteys katkaistu"
+
+msgid "invalid buffer number"
+msgstr "virheellinen puskurinumero"
+
+msgid "not implemented yet"
+msgstr "ei toteutettu"
+
+#. ???
+msgid "cannot set line(s)"
+msgstr "ei voi asettaa rivejä"
+
+msgid "invalid mark name"
+msgstr "virheellinen merkin nimi"
+
+msgid "mark not set"
+msgstr "merkko ei ole asetettu"
+
+#, c-format
+msgid "row %d column %d"
+msgstr "rivi %d sarake %d"
+
+msgid "cannot insert/append line"
+msgstr "rivin lisäys ei onnistu"
+
+msgid "line number out of range"
+msgstr "rivinumero arvoalueen ulkopuolella"
+
+msgid "unknown flag: "
+msgstr "tuntematon asetus: "
+
+msgid "unknown vimOption"
+msgstr "tuntematon vimOption"
+
+msgid "keyboard interrupt"
+msgstr "näppäimistökeskeytys"
+
+msgid "vim error"
+msgstr "vim-virhe"
+
+msgid "cannot create buffer/window command: object is being deleted"
+msgstr "ei voi luoda puskuri- tai ikkunakomentoa, olio on poistumassa"
+
+msgid ""
+"cannot register callback command: buffer/window is already being deleted"
+msgstr "callbackia ei voi rekisteröidä: puskuri tai ikkuna on poistettu"
+
+#. This should never happen. Famous last word?
+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 "cannot register callback command: buffer/window reference not found"
+msgstr "callbackia ei voi rekisteröidä: puskurin tai ikkunan viitettä ei löydy"
+
+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."
+
+msgid ""
+"E281: TCL ERROR: exit code is not int!? Please report this to vim-dev@vim.org"
+msgstr ""
+"E281: TCL-virhe: lopetuskoodi ei ole kokonaisluku? Ilmoita asiasta "
+"postituslistalle vim-dev@vim.org"
+
+#, c-format
+msgid "E572: exit code %d"
+msgstr "E572: palautusarvo %d"
+
+msgid "cannot get line"
+msgstr "ei voida hakea riviä"
+
+msgid "Unable to register a command server name"
+msgstr "Komentopalvelimen nimen rekisteröinti ei onnistu"
+
+msgid "E248: Failed to send command to the destination program"
+msgstr "E248: Komennon lähetys kohdeohjelmalle ei onnistu"
+
+#, c-format
+msgid "E573: Invalid server id used: %s"
+msgstr "E573: Virheellinen palvelimen tunniste: %s"
+
+msgid "E251: VIM instance registry property is badly formed. Deleted!"
+msgstr "E251: VIMin instanssin rekisteriarvo on virheellinen, poistettiin."
+
+msgid "Unknown option argument"
+msgstr "Tuntematon asetusargumentti"
+
+msgid "Too many edit arguments"
+msgstr "Liikaa muokkausargumentteja"
+
+msgid "Argument missing after"
+msgstr "Argumentti puuttuu kohdasta"
+
+msgid "Garbage after option argument"
+msgstr "Roskaa argumentin perässä"
+
+msgid "Too many \"+command\", \"-c command\" or \"--cmd command\" arguments"
+msgstr "Liikaa +komentoja, -c-komentoja tai --cmd-komentoja"
+
+msgid "Invalid argument for"
+msgstr "Väärä argumentti valitsimelle"
+
+#, c-format
+msgid "%d files to edit\n"
+msgstr "%d tiedostoa muokattavana\n"
+
+msgid "netbeans is not supported with this GUI\n"
+msgstr "netbeans ei toimi tässä käyttöliittymässä\n"
+
+msgid "This Vim was not compiled with the diff feature."
+msgstr "Tähän Vimiin ei ole käännetty diff-toimintoja mukaan."
+
+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 "Attempt to open script file again: \""
+msgstr "Yritettiin avata skriptitiedostoa uudestaan:"
+
+msgid "Cannot open for reading: \""
+msgstr "Ei voi avata luettavaksi: "
+
+msgid "Cannot open for script output: \""
+msgstr "Ei voi avata skriptin tulostetta varten: "
+
+msgid "Vim: Error: Failure to start gvim from NetBeans\n"
+msgstr "Vim: Virhe: Gvimin käynnistys NetBeansistä ei onnistu\n"
+
+msgid "Vim: Warning: Output is not to a terminal\n"
+msgstr "Vim: Varoitus: Tuloste ei mene terminaalille\n"
+
+msgid "Vim: Warning: Input is not from a terminal\n"
+msgstr "Vim: Varoitus: Syöte ei tule terminaalilta\n"
+
+#. just in case..
+msgid "pre-vimrc command line"
+msgstr "esi-vimrc-komentorivi"
+
+#, c-format
+msgid "E282: Cannot read from \"%s\""
+msgstr "E282: Ei voida lukea kohteesta %s"
+
+msgid ""
+"\n"
+"More info with: \"vim -h\"\n"
+msgstr ""
+"\n"
+"Lisätietoja: \"vim -h\"\n"
+
+msgid "[file ..] edit specified file(s)"
+msgstr "[tiedosto ..] muokkaa tiedostoja"
+
+msgid "- read text from stdin"
+msgstr "- lue vakiosyötteestä"
+
+msgid "-t tag edit file where tag is defined"
+msgstr "-t tägi muokkaa tiedostoa tägistä"
+
+msgid "-q [errorfile] edit file with first error"
+msgstr "-q [virhetiedosto] muokkaa tiedostoa ensimmäisestä virheestä"
+
+msgid ""
+"\n"
+"\n"
+"usage:"
+msgstr ""
+"\n"
+"\n"
+"käyttö:"
+
+msgid " vim [arguments] "
+msgstr " vim [argumentit] "
+
+msgid ""
+"\n"
+" or:"
+msgstr ""
+"\n"
+" tai:"
+
+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 ""
+"\n"
+"\n"
+"Arguments:\n"
+msgstr ""
+"\n"
+"\n"
+"Argumentit:\n"
+
+msgid "--\t\t\tOnly file names after this"
+msgstr "--\t\t\tvain tiedostonimiä tämän jälkeen"
+
+msgid "--literal\t\tDon't expand wildcards"
+msgstr "--literal\t\tÄlä käsittele jokerimerkkejä "
+
+msgid "-register\t\tRegister this gvim for OLE"
+msgstr "-register\t\trekisteröi gvim OLEa varten"
+
+msgid "-unregister\t\tUnregister gvim for OLE"
+msgstr "-unregister\t\tPoista gvim OLE-rekisteristä"
+
+msgid "-g\t\t\tRun using GUI (like \"gvim\")"
+msgstr "-g\t\t\tAvaa GUI (kuten gvimillä)"
+
+msgid "-f or --nofork\tForeground: Don't fork when starting GUI"
+msgstr "-f tai --nofork\tEdustalle: Älä haarauta GUIn käynnistyksessä"
+
+msgid "-v\t\t\tVi mode (like \"vi\")"
+msgstr "-v\t\t\tVi-tila (kuten villä)"
+
+msgid "-e\t\t\tEx mode (like \"ex\")"
+msgstr "-e\t\t\tEx-tila (kute exillä)"
+
+msgid "-s\t\t\tSilent (batch) mode (only for \"ex\")"
+msgstr "-s\t\t\tHiljainen (eräajo)tila (vain exillä)"
+
+msgid "-d\t\t\tDiff mode (like \"vimdiff\")"
+msgstr "-d\t\t\tDiff-tila (kuten vimdiffillä)"
+
+msgid "-y\t\t\tEasy mode (like \"evim\", modeless)"
+msgstr "-y\t\t\tHelppokäyttötila (kuten evimissä, ilman tiloja)"
+
+msgid "-R\t\t\tReadonly mode (like \"view\")"
+msgstr "-R\t\t\tKirjoitussuojattu tila (kuten view'lla)"
+
+msgid "-Z\t\t\tRestricted mode (like \"rvim\")"
+msgstr "-Z\t\t\tRajoitettu tila (kuten rvimillä)"
+
+msgid "-m\t\t\tModifications (writing files) not allowed"
+msgstr "-m\t\t\tMuokkaukset (kirjoittaminen tiedostoon) pois käytöstä"
+
+msgid "-M\t\t\tModifications in text not allowed"
+msgstr "-M\t\t\tTekstin muokkaus pois käytöstä"
+
+msgid "-b\t\t\tBinary mode"
+msgstr "-b\t\t\tBinääritila"
+
+msgid "-l\t\t\tLisp mode"
+msgstr "-l\t\t\tLisp-tila"
+
+msgid "-C\t\t\tCompatible with Vi: 'compatible'"
+msgstr "-C\t\t\tVi-yhteensopivuustila: compatible"
+
+msgid "-N\t\t\tNot fully Vi compatible: 'nocompatible'"
+msgstr "-N\t\t\tEi Vi-yhteensopivuutta: nocompatible"
+
+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] "
+
+msgid "-D\t\t\tDebugging mode"
+msgstr "-D\t\t\tVianetsintätila"
+
+msgid "-n\t\t\tNo swap file, use memory only"
+msgstr "-n\t\t\tEi swap-tiedostoja, käytä muistia"
+
+msgid "-r\t\t\tList swap files and exit"
+msgstr "-r\t\t\tLuetteloi swap-tiedostot ja poistu"
+
+msgid "-r (with file name)\tRecover crashed session"
+msgstr "-r (tiedostonimi)\tPalauta kaatunut sessio"
+
+msgid "-L\t\t\tSame as -r"
+msgstr "-L\t\t\tkuten -r"
+
+msgid "-f\t\t\tDon't use newcli to open window"
+msgstr "-f\t\t\tÄlä käytä newcli:tä ikkunan avaamiseen"
+
+msgid "-dev <device>\t\tUse <device> for I/O"
+msgstr "-dev <laite>\t\tKäytä <laitetta> IO:hon"
+
+msgid "-A\t\t\tstart in Arabic mode"
+msgstr "-A\t\t\tkäynnistä arabia-tilassa"
+
+msgid "-H\t\t\tStart in Hebrew mode"
+msgstr "-H\t\t\tkäynnistä heprea-tilassa"
+
+msgid "-F\t\t\tStart in Farsi mode"
+msgstr "-F\t\t\tkäynnistä farsi-tilassa"
+
+msgid "-T <terminal>\tSet terminal type to <terminal>"
+msgstr "-T <terminaali>\tAseta terminaalin tyypiksi <terminaali>"
+
+msgid "-u <vimrc>\t\tUse <vimrc> instead of any .vimrc"
+msgstr "-u <vimrc>\t\tKäytä <vimrc>-tiedostoa .vimrc:iden sijasta"
+
+msgid "-U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc"
+msgstr "-U <gvimrc>\t\tKäytä <gvimrc>-tiedostoa .gvimrc:iden sijasta"
+
+msgid "--noplugin\t\tDon't load plugin scripts"
+msgstr "--noplugin\t\tÄlä lataa liitännäisiä"
+
+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)"
+
+msgid "-o[N]\t\tOpen N windows (default: one for each file)"
+msgstr "-o[N]\t\tAvaa N ikkunaa (oletus: yksi per tiedosto)"
+
+msgid "-O[N]\t\tLike -o but split vertically"
+msgstr "-O[N]\t\tKuten -o, mutta jaa pystysuunnassa"
+
+msgid "+\t\t\tStart at end of file"
+msgstr "+\t\t\tAloita tiedoston lopusta"
+
+msgid "+<lnum>\t\tStart at line <lnum>"
+msgstr "+<rivi>\t\t\tAloita riviltä <rivi>"
+
+msgid "--cmd <command>\tExecute <command> before loading any vimrc file"
+msgstr "--cmd <komento>\tSuorita <komento> ennen vimrc:iden latausta"
+
+msgid "-c <command>\t\tExecute <command> after loading the first file"
+msgstr "-c <komento>\t\tSuorita <komento> ensimmäisen tiedoston latauduttua"
+
+msgid "-S <session>\t\tSource file <session> after loading the first file"
+msgstr "-S <sessio>\t\tLataa <sessio> ensimmäisen tiedoston latauduttua"
+
+msgid "-s <scriptin>\tRead Normal mode commands from file <scriptin>"
+msgstr "-s <skripti>\tLue normaalitilan komentoja <skripti>-tiedostosta"
+
+msgid "-w <scriptout>\tAppend all typed commands to file <scriptout>"
+msgstr "-w <skripti>\tLisää kirjoitetut komennot <skripti>-tiedostoon"
+
+msgid "-W <scriptout>\tWrite all typed commands to file <scriptout>"
+msgstr "-W <skripti>\tKirjoita komennot <skripti>-tiedostoon"
+
+msgid "-x\t\t\tEdit encrypted files"
+msgstr "-x\t\t\tMuokkaa salattua tiedostoa"
+
+msgid "-display <display>\tConnect vim to this particular X-server"
+msgstr "-display <näyttö>\tYhdistä vim tiettyyn X-palvelimeen"
+
+msgid "-X\t\t\tDo not connect to X server"
+msgstr "-X\t\t\tÄlä yhdistä X-palvelimeen"
+
+msgid "--remote <files>\tEdit <files> in a Vim server if possible"
+msgstr ""
+"--remote <tiedostoja>\tMuokkaa <tiedostoja> Vim-palvelimessa, jos mahdollista"
+
+msgid "--remote-silent <files> Same, don't complain if there is no server"
+msgstr ""
+"--remote-silent <tiedostoja>\tSama, mutta älä ilmoita puuttuvasta "
+"palvelimesta"
+
+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 ""
+"--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 ""
+"--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 "--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 "--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 "--serverlist\t\tList available Vim server names and exit"
+msgstr "--serverlist\t\tLuettele Vim-palvelinten nimet ja lopeta"
+
+msgid "--servername <name>\tSend to/become the Vim server <name>"
+msgstr "--servername <nimi>\tLähetä Vim-palvelimelle <nimi> tai luo se"
+
+msgid "--startuptime <file>\tWrite startup timing messages to <file>"
+msgstr "--startuptime <file>\tKirjoita käynnistysaikaviestit tiedostoon <file>"
+
+msgid "-i <viminfo>\t\tUse <viminfo> instead of .viminfo"
+msgstr "-i <viminfo>\t\tKäytä <viminfo>-tiedostoa .viminfon sijaan"
+
+msgid "-h or --help\tPrint Help (this message) and exit"
+msgstr "-h tai --help\tTulosta ohje (tämä viesti) ja lopeta"
+
+msgid "--version\t\tPrint version information and exit"
+msgstr "--version\t\t\tTulosta versiotiedot ja lopeta"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (Motif version):\n"
+msgstr ""
+"\n"
+"Gvimin (Motif-version) tuntemat argumentit:\n"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (neXtaw version):\n"
+msgstr ""
+"\n"
+"Gvimin (neXtaw-version) tuntemat argumentit:\n"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (Athena version):\n"
+msgstr ""
+"\n"
+"Gvimin (Athena-version) tuntemat argumentit:\n"
+
+msgid "-display <display>\tRun vim on <display>"
+msgstr "-display <näyttö>\tSuorita vim <näytössä>"
+
+msgid "-iconic\t\tStart vim iconified"
+msgstr "-iconic\t\tKäynnistä pienennettynä"
+
+msgid "-background <color>\tUse <color> for the background (also: -bg)"
+msgstr "-background <väri>\tKäytä <väriä> taustavärinä (myös: -bg)"
+
+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 "-font <font>\t\tUse <font> for normal text (also: -fn)"
+msgstr "-font <fontti>\t\tKäytä <fonttia> tekstissä (myös: -fn)"
+
+msgid "-boldfont <font>\tUse <font> for bold text"
+msgstr "-boldfont <fontti>\tKäytä <fonttia> lihavoidussa tekstissä"
+
+msgid "-italicfont <font>\tUse <font> for italic text"
+msgstr "-italicfont <fontti>\tKäytä <fonttia> kursivoidussa tekstissä"
+
+msgid "-geometry <geom>\tUse <geom> for initial geometry (also: -geom)"
+msgstr ""
+"-geometry <geom>\tKäytä mittoja <geom> ikkunan asetteluun (myös: -geom)"
+
+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 "-menuheight <height>\tUse a menu bar height of <height> (also: -mh)"
+msgstr "-menuheight <korkeus>\tKäytä <korkeutta> valikossa (myös: -mh)"
+
+msgid "-reverse\t\tUse reverse video (also: -rv)"
+msgstr "-reverse\t\tKäytä käänteisvärejä (myös: -rv) "
+
+msgid "+reverse\t\tDon't use reverse video (also: +rv)"
+msgstr "+reverse\t\tÄlä käytä käänteisvärejä (myös: +rv)"
+
+msgid "-xrm <resource>\tSet the specified resource"
+msgstr "-xrm <resurssi>\tAseta resurssi"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (RISC OS version):\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"
+
+msgid "--rows <number>\tInitial height of window in rows"
+msgstr "--rows <luku>\tIkkunan alkukorkeus riveinä"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (GTK+ version):\n"
+msgstr ""
+"\n"
+"Gvimin (GTK+-version) tuntemat argumentit:\n"
+
+msgid "-display <display>\tRun vim on <display> (also: --display)"
+msgstr "-display <näyttö>\tSuorita vim näytöllä <näyttö> (myös: --display)"
+
+# 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 "--socketid <xid>\tOpen Vim inside another GTK widget"
+msgstr "--socketid <xid>\tAvaa Vim annettuun GTK-olioon "
+
+msgid "-P <parent title>\tOpen Vim inside parent application"
+msgstr "-P <otsikko>\tAvaa Vim isäntäohjelman sisään"
+
+msgid "--windowid <HWND>\tOpen Vim inside another win32 widget"
+msgstr "--windowid <HWND>\tAvaa Vim annettuun win32-olioon "
+
+msgid "No display"
+msgstr "Ei näyttöä"
+
+#. Failed to send, abort.
+msgid ": Send failed.\n"
+msgstr ": Lähetys epäonnistui.\n"
+
+#. Let vim start normally.
+msgid ": Send failed. Trying to execute locally\n"
+msgstr ": Lähetys epäonnistui. Yritetään suorittaa paikallisena\n"
+
+#, c-format
+msgid "%d of %d edited"
+msgstr "%d/%d muokattu"
+
+msgid "No display: Send expression failed.\n"
+msgstr "Ei näyttöä: Ilmauksen lähetys epäonnistui.\n"
+
+msgid ": Send expression failed.\n"
+msgstr ": Ilmauksen lähetys epäonnistui.\n"
+
+msgid "No marks set"
+msgstr "Ei asetettuja merkkejä"
+
+#, c-format
+msgid "E283: No marks matching \"%s\""
+msgstr "E283: Mikään merkki ei täsmää ilmaukseen \"%s\""
+
+#. Highlight title
+msgid ""
+"\n"
+"mark line col file/text"
+msgstr ""
+"\n"
+"merkki rivi sarake tiedosto/teksti"
+
+#. Highlight title
+msgid ""
+"\n"
+" jump line col file/text"
+msgstr ""
+"\n"
+"hyppy rivi sarake tiedosto/teksti"
+
+#. Highlight title
+msgid ""
+"\n"
+"change line col text"
+msgstr ""
+"\n"
+"muutos rivi sarake teksti"
+
+#, c-format
+msgid ""
+"\n"
+"# File marks:\n"
+msgstr ""
+"\n"
+"# Tiedoston merkit:\n"
+
+#. Write the jumplist with -'
+#, c-format
+msgid ""
+"\n"
+"# Jumplist (newest first):\n"
+msgstr ""
+"\n"
+"# Hyppylista (uusin ensiksi):\n"
+
+#, c-format
+msgid ""
+"\n"
+"# History of marks within files (newest to oldest):\n"
+msgstr ""
+"\n"
+"# Tiedostojen merkkien historia (uusimmasta vanhimpaan):\n"
+
+msgid "Missing '>'"
+msgstr "> puuttuu"
+
+msgid "E543: Not a valid codepage"
+msgstr "E543: Koodisivu ei ole käypä"
+
+msgid "E284: Cannot set IC values"
+msgstr "E284: Ei voi asettaa IC-arvoja"
+
+msgid "E285: Failed to create input context"
+msgstr "E285: Syötekontekstin luonti ei onnistu"
+
+msgid "E286: Failed to open input method"
+msgstr "E286: Syötemetodin avaus ei onnistu"
+
+msgid "E287: Warning: Could not set destroy callback to IM"
+msgstr ""
+"E287: Varoitus: Ei voitu asettaa destroy-kutsua syötemetodipalvelimelle"
+
+msgid "E288: input method doesn't support any style"
+msgstr "E288: syötemetodi ei tue tyylejä"
+
+msgid "E289: input method doesn't support my preedit type"
+msgstr "E289: syötemetodi ei tue tätä preedit-tyyppiä"
+
+msgid "E293: block was not locked"
+msgstr "E293: lohkoa ei ole lukittu"
+
+msgid "E294: Seek error in swap file read"
+msgstr "E294: Hakuvirhe swap-tiedostoa luettaessa"
+
+msgid "E295: Read error in swap file"
+msgstr "E295: Lukuvirhe swap-tiedostossa"
+
+msgid "E296: Seek error in swap file write"
+msgstr "E296: Hakuvirhe swap-tiedostoa kirjoitettaessa"
+
+msgid "E297: Write error in swap file"
+msgstr "E297: Kirjoitusvirhe swap-tiedostossa"
+
+msgid "E300: Swap file already exists (symlink attack?)"
+msgstr "E300: Swaptiedosto on jo olemassa (symlink-hyökkäys?)"
+
+msgid "E298: Didn't get block nr 0?"
+msgstr "E298: Lohko 0:aa ei saatu?"
+
+msgid "E298: Didn't get block nr 1?"
+msgstr "E298: Lohko 1:tä ei saatu?"
+
+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????
+msgid "E301: Oops, lost the swap file!!!"
+msgstr "E301: Hups, swap-tiedosto hävisi!"
+
+msgid "E302: Could not rename swap file"
+msgstr "E302: Swap-tiedoston uudellennimeys ei onnistu"
+
+#, c-format
+msgid "E303: Unable to open swap file for \"%s\", recovery impossible"
+msgstr "E303: Swap-tiedostoa %s ei voi avata, palautus ei onnistu"
+
+msgid "E304: ml_upd_block0(): Didn't get block 0??"
+msgstr "E304: ml_upd_block0(): Lohko 0:aa ei saatu?"
+
+#, c-format
+msgid "E305: No swap file found for %s"
+msgstr "E305: Ei swap-tiedostoa tiedostolle %s"
+
+msgid "Enter number of swap file to use (0 to quit): "
+msgstr "Anna swap-tiedoston numero tai 0 lopettaaksesi: "
+
+#, c-format
+msgid "E306: Cannot open %s"
+msgstr "E306: Ei voi avata tiedostoa %s"
+
+msgid "Unable to read block 0 from "
+msgstr "Ei voi lukea lohkoa 0 kohteesta "
+
+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."
+
+msgid " cannot be used with this version of Vim.\n"
+msgstr " ei toimi tämän version Vimin kanssa.\n"
+
+msgid "Use Vim version 3.0.\n"
+msgstr "Käytä Vimin versiota 3.0\n"
+
+#, c-format
+msgid "E307: %s does not look like a Vim swap file"
+msgstr "E307: %s ei ole Vimin swap-tiedosto"
+
+msgid " cannot be used on this computer.\n"
+msgstr " ei toimi tällä koneella.\n"
+
+msgid "The file was created on "
+msgstr "Tiedosto luotiin "
+
+msgid ""
+",\n"
+"or the file has been damaged."
+msgstr ""
+",\n"
+"tai tiedosto on vahingoittunut."
+
+#, c-format
+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 " has been damaged (page size is smaller than minimum value).\n"
+msgstr " on vioittunut (sivun koko on vähimmäisarvoa pienempi).\n"
+
+#, c-format
+msgid "Using swap file \"%s\""
+msgstr "Käytetään swap-tiedostoa %s"
+
+#, c-format
+msgid "Original file \"%s\""
+msgstr "Alkuperäinen tiedosto %s"
+
+msgid "E308: Warning: Original file may have been changed"
+msgstr "E308: Varoitus: Alkuperäistä tiedostoa saattaa olla muutettu"
+
+#, c-format
+msgid "Swap file is encrypted: \"%s\""
+msgstr "Swap-tiedosto on salattu: %s"
+
+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 ""
+"\n"
+"enter the new crypt key."
+msgstr "\n"
+"anna uusi salausavain."
+
+msgid ""
+"\n"
+"If you wrote the text file after changing the crypt key press enter"
+msgstr "\n"
+"Jos kirjoitit tekstitiedoston salausavaimen vaihdon jälkeen paina enteriä"
+
+msgid ""
+"\n"
+"to use the same key for text file and swap file"
+msgstr "\n"
+"käyttääksesi samaa avainta teksti- ja swäppitiedostoille"
+
+#, c-format
+msgid "E309: Unable to read block 1 from %s"
+msgstr "E309: Ei voitu lukea lohkoa 1 tiedostosta %s"
+
+msgid "???MANY LINES MISSING"
+msgstr "???PALJON RIVEJÄ PUUTTUU"
+
+msgid "???LINE COUNT WRONG"
+msgstr "???RIVIMÄÄRÄ PIELESSÄ"
+
+msgid "???EMPTY BLOCK"
+msgstr "???TYHJÄ LOHKO"
+
+msgid "???LINES MISSING"
+msgstr "???RIVEJÄ PUUTTUU"
+
+#, 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?)"
+
+msgid "???BLOCK MISSING"
+msgstr "???LOHKO PUUTTUU"
+
+msgid "??? from here until ???END lines may be messed up"
+msgstr "??? tästä kohtaan ???LOPPU rivejä sekaisin"
+
+msgid "??? from here until ???END lines may have been inserted/deleted"
+msgstr "??? tästä kohtaan ???LOPPU rivejä saattaa olla lisätty tai poistettu"
+
+msgid "???END"
+msgstr "???LOPPU"
+
+msgid "E311: Recovery Interrupted"
+msgstr "E311: Palautus keskeytetty"
+
+msgid ""
+"E312: Errors detected while recovering; look for lines starting with ???"
+msgstr "E312: Palautuksessa oli virheitä, etsi rivejä, jotka alkavat ???"
+
+msgid "See \":help E312\" for more information."
+msgstr ":help E312 kertoo lisätietoja"
+
+msgid "Recovery completed. You should check if everything is OK."
+msgstr "Palautus onnistui. Tarkista, että kaikki on kunnossa."
+
+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"
+
+msgid "and run diff with the original file to check for changes)"
+msgstr "ja katso diffillä muutokset alkuperäiseen tiedostoon)"
+
+msgid "Recovery completed. Buffer contents equals file contents."
+msgstr "Palautus onnistui. Puskurin ja tiedoston sisällöt täsmäävät."
+
+msgid ""
+"\n"
+"You may want to delete the .swp file now.\n"
+"\n"
+msgstr "\n"
+"Voit poistaa .swp-tiedosto nyt.\n"
+"\n"
+
+msgid "Using crypt key from swap file for the text file.\n"
+msgstr "Käytetään swäpin salausavainta tekstitiedostolle\n"
+
+#. use msg() to start the scrolling properly
+msgid "Swap files found:"
+msgstr "Swap-tiedostoja löytyi:"
+
+msgid " In current directory:\n"
+msgstr " Tässä hakemistossa:\n"
+
+msgid " Using specified name:\n"
+msgstr " Määritellyllä nimellä:\n"
+
+msgid " In directory "
+msgstr " Hakemistossa "
+
+msgid " -- none --\n"
+msgstr " -- ei mitään --\n"
+
+msgid " owned by: "
+msgstr " omistaja: "
+
+msgid " dated: "
+msgstr " ajalta: "
+
+msgid " dated: "
+msgstr " ajalta:"
+
+msgid " [from Vim version 3.0]"
+msgstr " [Vimin 3.0-versiosta]"
+
+msgid " [does not look like a Vim swap file]"
+msgstr " [ei näytä Vimin swap-tiedostolta]"
+
+msgid " file name: "
+msgstr " tiedostonimi: "
+
+msgid ""
+"\n"
+" modified: "
+msgstr ""
+"\n"
+" muokattu: "
+
+msgid "YES"
+msgstr "KYLLÄ"
+
+msgid "no"
+msgstr "ei"
+
+msgid ""
+"\n"
+" user name: "
+msgstr ""
+"\n"
+" käyttäjänimi: "
+
+msgid " host name: "
+msgstr " laitenimi: "
+
+msgid ""
+"\n"
+" host name: "
+msgstr ""
+"\n"
+" laitenimi: "
+
+msgid ""
+"\n"
+" process ID: "
+msgstr ""
+"\n"
+" prosessin tunniste: "
+
+msgid " (still running)"
+msgstr " (käynnissä)"
+
+msgid ""
+"\n"
+" [not usable with this version of Vim]"
+msgstr ""
+"\n"
+" [ei toimi tämän Vim-version kanssa]"
+
+msgid ""
+"\n"
+" [not usable on this computer]"
+msgstr ""
+"\n"
+" [ei toimi tällä koneella]"
+
+msgid " [cannot be read]"
+msgstr " [ei voi lukea]"
+
+msgid " [cannot be opened]"
+msgstr " [ei voi avata]"
+
+msgid "E313: Cannot preserve, there is no swap file"
+msgstr "E313: Ei voi säilyttää, swap-tiedostoa ei ole"
+
+msgid "File preserved"
+msgstr "Tiedosto säilytetty"
+
+msgid "E314: Preserve failed"
+msgstr "E314: Säilyttäminen epäonnistui"
+
+#, c-format
+msgid "E315: ml_get: invalid lnum: %ld"
+msgstr "E315: ml_get: virheellinen lnum: %ld"
+
+#, c-format
+msgid "E316: ml_get: cannot find line %ld"
+msgstr "E316: ml_get: riviä %ld ei löydy"
+
+msgid "E317: pointer block id wrong 3"
+msgstr "E317: osoitinlohkon tunnus väärä 3"
+
+msgid "stack_idx should be 0"
+msgstr "stack_idx pitää olla 0"
+
+msgid "E318: Updated too many blocks?"
+msgstr "E318: Päivitetty liikaa lohkoja"
+
+msgid "E317: pointer block id wrong 4"
+msgstr "E317: osoitinlohkon tunnus väärä 4"
+
+msgid "deleted block 1?"
+msgstr "poistettu lohko 1?"
+
+#, c-format
+msgid "E320: Cannot find line %ld"
+msgstr "E320: Riviä %ld ei löydy"
+
+msgid "E317: pointer block id wrong"
+msgstr "E317: osoitinlohkon tunnus väärä"
+
+msgid "pe_line_count is zero"
+msgstr "pe_line_count on nolla"
+
+#, c-format
+msgid "E322: line number out of range: %ld past the end"
+msgstr "E322: rivinumero arvoalueen ulkopuoleta: %ld on loppua suurempi"
+
+#, c-format
+msgid "E323: line count wrong in block %ld"
+msgstr "E323: rivimäärä väärin lohkossa %ld"
+
+msgid "Stack size increases"
+msgstr "Pinon koko kasvaa"
+
+msgid "E317: pointer block id wrong 2"
+msgstr "E317: osoitinlohon tunnus väärä 2"
+
+#, c-format
+msgid "E773: Symlink loop for \"%s\""
+msgstr "E773: Symlinkkisilmukka kohteelle %s"
+
+msgid "E325: ATTENTION"
+msgstr "E325: HUOMAA"
+
+msgid ""
+"\n"
+"Found a swap file by the name \""
+msgstr ""
+"\n"
+"Swap-tiedosto löytyi: \""
+
+msgid "While opening file \""
+msgstr "Avattaessa tiedostoa "
+
+msgid " NEWER than swap file!\n"
+msgstr " joka on UUDEMPI kuin swap-tiedosto!\n"
+
+#. Some of these messages are long to allow translation to
+#. * other languages.
+msgid ""
+"\n"
+"(1) Another program may be editing the same file.\n"
+" If this is the case, be careful not to end up with two\n"
+" different instances of the same file when making changes.\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"
+
+msgid " Quit, or continue with caution.\n"
+msgstr " Lopeta, tai jatka.\n"
+
+msgid ""
+"\n"
+"(2) An edit session for this file crashed.\n"
+msgstr ""
+"\n"
+"(2) Ohjelma on kaatunut muokatessa tiedostoa.\n"
+
+msgid " If this is the case, use \":recover\" or \"vim -r "
+msgstr " Jos näin on, käytä komentoa :recover tai vim -r "
+
+msgid ""
+"\"\n"
+" to recover the changes (see \":help recovery\").\n"
+msgstr ""
+"\"\n"
+" palauttaaksesi muutokset (lisätietoja: \":help recovery\").\n"
+
+msgid " If you did this already, delete the swap file \""
+msgstr " Jos teit jo näin, poista swap-tiedosto "
+
+msgid ""
+"\"\n"
+" to avoid this message.\n"
+msgstr ""
+"\"\n"
+" välttääksesi tämän viestin.\n"
+
+msgid "Swap file \""
+msgstr "Swap-tiedosto "
+
+msgid "\" already exists!"
+msgstr " on jo olemassa"
+
+msgid "VIM - ATTENTION"
+msgstr "VIM - HUOMAUTUS"
+
+msgid "Swap file already exists!"
+msgstr "Swap-tiedosto on jo olemassa"
+
+msgid ""
+"&Open Read-Only\n"
+"&Edit anyway\n"
+"&Recover\n"
+"&Quit\n"
+"&Abort"
+msgstr ""
+"&Avaa kirjoitussuojattuna\n"
+"&Muokkaa\n"
+"&Palauta\n"
+"&Lopeta\n"
+"P&eru"
+
+msgid ""
+"&Open Read-Only\n"
+"&Edit anyway\n"
+"&Recover\n"
+"&Delete it\n"
+"&Quit\n"
+"&Abort"
+msgstr ""
+"&Avaa kirjoitussuojattuna\n"
+"&Muokkaa\n"
+"&Palauta\n"
+"P&oista\n"
+"&Lopeta\n"
+"P&eru"
+
+msgid "E326: Too many swap files found"
+msgstr "E326: Liian monta swap-tiedostoa"
+
+msgid "E327: Part of menu-item path is not sub-menu"
+msgstr "E327: Valikkokohtapolun osa ei ole alivalikko"
+
+msgid "E328: Menu only exists in another mode"
+msgstr "E328: Valikko on olemassa vain toisessa tilassa"
+
+#, c-format
+msgid "E329: No menu \"%s\""
+msgstr "E329: Ei valikkoa %s"
+
+#. Only a mnemonic or accelerator is not valid.
+msgid "E792: Empty menu name"
+msgstr "E792: tyhjä valikkonimi"
+
+msgid "E330: Menu path must not lead to a sub-menu"
+msgstr "E330: Valikkopolku ei saa johtaa alivalikkoon"
+
+msgid "E331: Must not add menu items directly to menu bar"
+msgstr "E331: Valikkokohtia ei saa lisätä suoraan valikkopalkkiin"
+
+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
+msgid ""
+"\n"
+"--- Menus ---"
+msgstr ""
+"\n"
+"--- Valikot ---"
+
+msgid "Tear off this menu"
+msgstr "Repäise valikko irti"
+
+msgid "E333: Menu path must lead to a menu item"
+msgstr "E333: Valikkopolun on johdettava valikkokohtaan"
+
+#, c-format
+msgid "E334: Menu not found: %s"
+msgstr "E334: Valikkoa ei löydy: %s"
+
+#, c-format
+msgid "E335: Menu not defined for %s mode"
+msgstr "E335: Valikkoa ei ole määritelty %s-tilassa"
+
+msgid "E336: Menu path must lead to a sub-menu"
+msgstr "E336: Valikkopolun pitää johtaa alivalikkoon"
+
+msgid "E337: Menu not found - check menu names"
+msgstr "E337: Valikkoa ei löytynyt - tarkista valikkojen nimet"
+
+#, c-format
+msgid "Error detected while processing %s:"
+msgstr "Virhe suoritettaessa komentoja %s:"
+
+#, c-format
+msgid "line %4ld:"
+msgstr "rivi %4ld:"
+
+#, c-format
+msgid "E354: Invalid register name: '%s'"
+msgstr "E354: Virheellinen rekisterin nimi: %s"
+
+msgid "Messages maintainer: Bram Moolenaar <Bram@vim.org>"
+msgstr "Käännöksen ylläpitäjä: Flammie Pirinen <flammie@iki.fi>"
+
+msgid "Interrupt: "
+msgstr "Keskeytys: "
+
+msgid "Press ENTER or type command to continue"
+msgstr "Paina enteriä tai kirjoita komento aloittaaksesi "
+
+#, c-format
+msgid "%s line %ld"
+msgstr "%s rivi %ld"
+
+msgid "-- More --"
+msgstr "-- Lisää --"
+
+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 "
+
+msgid "Question"
+msgstr "Kysymys"
+
+msgid ""
+"&Yes\n"
+"&No"
+msgstr ""
+"&Kyllä\n"
+"&Ei"
+
+msgid ""
+"&Yes\n"
+"&No\n"
+"Save &All\n"
+"&Discard All\n"
+"&Cancel"
+msgstr ""
+"&Kyllä\n"
+"&Ei\n"
+"&Tallenna kaikki\n"
+"T&uhoa kaikki\n"
+"&Peru"
+
+msgid "Select Directory dialog"
+msgstr "Hakemiston valintaikkuna"
+
+msgid "Save File dialog"
+msgstr "Tallennusikkuna"
+
+msgid "Open File dialog"
+msgstr "Avausikkuna"
+
+#. TODO: non-GUI file selector here
+msgid "E338: Sorry, no file browser in console mode"
+msgstr "E338: Sori, tiedostonselain puuttuu konsolitilasta"
+
+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"
+
+msgid "W10: Warning: Changing a readonly file"
+msgstr "W10: Varoitus: Muutetaan kirjoitussuojattua tiedostoa"
+
+msgid "Type number and <Enter> or click with mouse (empty cancels): "
+msgstr "Kirjoita numero ja <Enter> tai valitse hiirellä (tyhjä peruu): "
+
+msgid "Type number and <Enter> (empty cancels): "
+msgstr "Valitse numero ja <Enter> (tyhjä peruu): "
+
+msgid "1 more line"
+msgstr "1 rivi lisää"
+
+msgid "1 line less"
+msgstr "1 rivi vähemmän"
+
+#, c-format
+msgid "%ld more lines"
+msgstr "%ld riviä lisää"
+
+#, c-format
+msgid "%ld fewer lines"
+msgstr "%ld riviä vähemmän"
+
+msgid " (Interrupted)"
+msgstr " (Keskeytetty)"
+
+msgid "Beep!"
+msgstr "Piip!"
+
+msgid "Vim: preserving files...\n"
+msgstr "Vim: säästetään tiedostoja...\n"
+
+#. close all memfiles, without deleting
+msgid "Vim: Finished.\n"
+msgstr "Vim: Valmis.\n"
+
+#, c-format
+msgid "ERROR: "
+msgstr "VIRHE: "
+
+#, c-format
+msgid ""
+"\n"
+"[bytes] total alloc-freed %lu-%lu, in use %lu, peak use %lu\n"
+msgstr ""
+"\n"
+"[tavua] yht. alloc-free %lu-%lu, käytössä %lu, käyttöhuippu %lu\n"
+
+#, c-format
+msgid ""
+"[calls] total re/malloc()'s %lu, total free()'s %lu\n"
+"\n"
+msgstr ""
+"[kutsut] yht. re/malloc() %lu, yht. free() %lu\n"
+"\n"
+
+msgid "E340: Line is becoming too long"
+msgstr "E340: Rivistä tulee liian pitkä"
+
+#, c-format
+msgid "E341: Internal error: lalloc(%ld, )"
+msgstr "E341: Sisäinen virhe: lalloc(%ld, )"
+
+#, c-format
+msgid "E342: Out of memory! (allocating %lu bytes)"
+msgstr "E342: Muisti loppui! (varattaessa %lu tavua)"
+
+#, c-format
+msgid "Calling shell to execute: \"%s\""
+msgstr "Kutsutaan kuorta suorittamaan: %s"
+
+msgid "E545: Missing colon"
+msgstr "E545: Kaksoispiste puuttuu"
+
+msgid "E546: Illegal mode"
+msgstr "E546: Virheellinen tila"
+
+msgid "E547: Illegal mouseshape"
+msgstr "E547: Virheellinen hiiren muoto"
+
+msgid "E548: digit expected"
+msgstr "E548: pitää olla numero"
+
+msgid "E549: Illegal percentage"
+msgstr "E549: Virheellinen prosenttiluku"
+
+msgid "Enter encryption key: "
+msgstr "Anna salausavain: "
+
+msgid "Enter same key again: "
+msgstr "Anna sama avain uudestaan: "
+
+msgid "Keys don't match!"
+msgstr "Avaimet eivät täsmää!"
+
+#, c-format
+msgid ""
+"E343: Invalid path: '**[number]' must be at the end of the path or be "
+"followed by '%s'."
+msgstr ""
+"E343: Virheellinen polku: '**[numero]' kuuluu polun loppuun tai ennen kohtaa "
+"%s."
+
+#, c-format
+msgid "E344: Can't find directory \"%s\" in cdpath"
+msgstr "E344: Hakemistoa %s ei löydy cdpathista"
+
+#, c-format
+msgid "E345: Can't find file \"%s\" in path"
+msgstr "E345: Tiedostoa %s ei löydy polulta"
+
+#, c-format
+msgid "E346: No more directory \"%s\" found in cdpath"
+msgstr "E346: Hakemisto %s ei ole enää cdpathissa"
+
+#, c-format
+msgid "E347: No more file \"%s\" found in path"
+msgstr "E347: Tiedosto %s ei ole enää polulla"
+
+msgid "Cannot connect to Netbeans #2"
+msgstr "Ei voi yhdistää Netbeans #2:een"
+
+msgid "Cannot connect to Netbeans"
+msgstr "Ei voi yhdistää Netbeansiin"
+
+#, c-format
+msgid "E668: Wrong access mode for NetBeans connection info file: \"%s\""
+msgstr "E668: Väärä avaustila NetBeans-yhteyden infotiedostolle: %s"
+
+msgid "read from Netbeans socket"
+msgstr "luettu Netbeans-soketista"
+
+#, c-format
+msgid "E658: NetBeans connection lost for buffer %ld"
+msgstr "E658: NetBeans-yhteys katkesi puskurille %ld"
+
+msgid "E511: netbeans already connected"
+msgstr "E511: netbeans on yhdistetty jo"
+
+msgid "E505: "
+msgstr "E505: "
+
+msgid "E349: No identifier under cursor"
+msgstr "E349: Ei tunnistetta osoittimen alla"
+
+msgid "E774: 'operatorfunc' is empty"
+msgstr "E774: operatorfunc on tyhjä"
+
+msgid "E775: Eval feature not available"
+msgstr "E775: Eval ei ole käytettävissä"
+
+msgid "Warning: terminal cannot highlight"
+msgstr "Varoitus: terminaalista puuttuu korostus"
+
+msgid "E348: No string under cursor"
+msgstr "E348: Ei merkkijonoa kursorin alla"
+
+msgid "E352: Cannot erase folds with current 'foldmethod'"
+msgstr "E352: taitoksia ei voi poistaa tällä foldmethodilla"
+
+msgid "E664: changelist is empty"
+msgstr "E664: muutoslista on tyhjä"
+
+msgid "E662: At start of changelist"
+msgstr "E662: Muutoslistan alussa"
+
+msgid "E663: At end of changelist"
+msgstr "E663: Muutoslistan lopussa"
+
+msgid "Type :quit<Enter> to exit Vim"
+msgstr "Komento :quit<Enter> lopettaa Vimin"
+
+#, c-format
+msgid "1 line %sed 1 time"
+msgstr "1 riviä %s kerran"
+
+#, c-format
+msgid "1 line %sed %d times"
+msgstr "1 riviä %s %d kertaa"
+
+#, c-format
+msgid "%ld lines %sed 1 time"
+msgstr "%ld riviä %s kerran"
+
+#, c-format
+msgid "%ld lines %sed %d times"
+msgstr "%ld riviä %s %d kertaa"
+
+#, c-format
+msgid "%ld lines to indent... "
+msgstr "%ld riviä sisennettävänä..."
+
+msgid "1 line indented "
+msgstr "1 rivi sisennetty "
+
+#, c-format
+msgid "%ld lines indented "
+msgstr "%ld riviä sisennetty "
+
+msgid "E748: No previously used register"
+msgstr "E748: Ei aiemmin käytettyjä rekisterejä"
+
+#. must display the prompt
+msgid "cannot yank; delete anyway"
+msgstr "Ei voi kopioida; poista joka tapauksessa"
+
+msgid "1 line changed"
+msgstr "1 rivi muuttui"
+
+#, c-format
+msgid "%ld lines changed"
+msgstr "%ld riviä muuttui"
+
+#, c-format
+msgid "freeing %ld lines"
+msgstr "vapautetaan %ld riviä"
+
+msgid "block of 1 line yanked"
+msgstr "1 rivin lohko kopioitu"
+
+msgid "1 line yanked"
+msgstr "1 rivi kopioitu"
+
+#, c-format
+msgid "block of %ld lines yanked"
+msgstr "lohko %ld riviltä kopioitu"
+
+#, c-format
+msgid "%ld lines yanked"
+msgstr "%ld riviä kopioitu"
+
+#, c-format
+msgid "E353: Nothing in register %s"
+msgstr "E353: Rekisterissä %s ei ole mitään"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Registers ---"
+msgstr ""
+"\n"
+"--- Rekisterit ---"
+
+msgid "Illegal register name"
+msgstr "Virheellinen rekisterin nimi"
+
+msgid ""
+"\n"
+"# Registers:\n"
+msgstr ""
+"\n"
+"# Rekisterit:\n"
+
+#, c-format
+msgid "E574: Unknown register type %d"
+msgstr "E574: Tuntematon rekisterityyppi %d"
+
+#, c-format
+msgid "%ld Cols; "
+msgstr "%ld saraketta, "
+
+#, c-format
+msgid "Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Bytes"
+msgstr "Valittu %s%ld/%ld riviä, %ld/%ld sanaa, %ld/%ld tavua"
+
+#, c-format
+msgid ""
+"Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Chars; %ld of %ld "
+"Bytes"
+msgstr "Valittu %s%ld/%ld riviä, %ld/%ld sanaa, %ld/%ld merkkiä, %ld/%ld tavua"
+
+#, c-format
+msgid "Col %s of %s; Line %ld of %ld; Word %ld of %ld; Byte %ld of %ld"
+msgstr "Sarake %s/%s, Rivi %ld/%ld, sana %ld/%ld, tavu %ld/%ld"
+
+#, c-format
+msgid ""
+"Col %s of %s; Line %ld of %ld; Word %ld of %ld; Char %ld of %ld; Byte %ld of "
+"%ld"
+msgstr "Sarake %s/%s, rivi %ld/%ld, sana %ld/%ld, merkki %ld/%ld, tavu %ld/%ld"
+
+# Unicode Byte Order Mark
+#, c-format
+msgid "(+%ld for BOM)"
+msgstr "(+%ld BOMista)"
+
+msgid "%<%f%h%m%=Page %N"
+msgstr "%<%f%h%m%=Sivu %N"
+
+msgid "Thanks for flying Vim"
+msgstr "Kiitos että ajoit Vimiä"
+
+msgid "E518: Unknown option"
+msgstr "E518: Tuntematon asetus"
+
+msgid "E519: Option not supported"
+msgstr "E519: Asetusta ei tueta"
+
+msgid "E520: Not allowed in a modeline"
+msgstr "E520: Ei sallitu modeline-rivillä"
+
+msgid "E521: Number required after ="
+msgstr "E521: =:n jälkeen tarvitaan luku"
+
+msgid "E522: Not found in termcap"
+msgstr "E522: Puuttuu termcapista"
+
+#, c-format
+msgid "E539: Illegal character <%s>"
+msgstr "E539: Virheellinen merkki <%s>"
+
+msgid "E529: Cannot set 'term' to empty string"
+msgstr "E529: Termiä ei voi asettaa tyhjäksi merkkijonoksi"
+
+msgid "E530: Cannot change term in GUI"
+msgstr "E530: Ei voi vaihtaa termiä GUIssa"
+
+msgid "E531: Use \":gui\" to start the GUI"
+msgstr "E531: Käytä komentoa :gui GUIn käynnistämiseen"
+
+msgid "E589: 'backupext' and 'patchmode' are equal"
+msgstr "E589: backupext ja patchmod ovat samat"
+
+msgid "E834: Conflicts with value of 'listchars'"
+msgstr "E834: listcharsin arvoissa on ristiriitoja"
+
+msgid "E835: Conflicts with value of 'fillchars'"
+msgstr "E835: fillcharsin arvossa on ristiriitoja"
+
+msgid "E617: Cannot be changed in the GTK+ 2 GUI"
+msgstr "E617: Ei voi muuttaa GTK+2-GUIssa"
+
+msgid "E524: Missing colon"
+msgstr "E524: Kaksoispiste puuttuu"
+
+msgid "E525: Zero length string"
+msgstr "E525: Nollan pituinen merkkijono"
+
+#, c-format
+msgid "E526: Missing number after <%s>"
+msgstr "E526: Lukuarvo puuttuu merkkijonon <%s> jälkeen"
+
+msgid "E527: Missing comma"
+msgstr "E527: Pilkku puuttuu"
+
+msgid "E528: Must specify a ' value"
+msgstr "E528: '-arvo pitää antaa"
+
+msgid "E595: contains unprintable or wide character"
+msgstr "E595: Sisältää tulostumattomia tai leveitä merkkejä"
+
+msgid "E596: Invalid font(s)"
+msgstr "E596: Viallisia fontteja"
+
+msgid "E597: can't select fontset"
+msgstr "E597: Fontsetin valinta ei onnistu"
+
+msgid "E598: Invalid fontset"
+msgstr "E598: Viallinen fontset"
+
+msgid "E533: can't select wide font"
+msgstr "E533: Leveän fontin valinta ei onnistu"
+
+msgid "E534: Invalid wide font"
+msgstr "E534: Viallinen leveä fontti"
+
+#, c-format
+msgid "E535: Illegal character after <%c>"
+msgstr "E535: Virheellinen merkki merkin <%c> jälkeen"
+
+msgid "E536: comma required"
+msgstr "E536: pilkku puuttuu"
+
+#, c-format
+msgid "E537: 'commentstring' must be empty or contain %s"
+msgstr "E537: commentstringin pitää olla tyhjä tai sisältää %s"
+
+msgid "E538: No mouse support"
+msgstr "E538: Hiirtä ei tueta"
+
+msgid "E540: Unclosed expression sequence"
+msgstr "E540: Sulkematon lausekesarja"
+
+msgid "E541: too many items"
+msgstr "E541: liikaa kohteita"
+
+msgid "E542: unbalanced groups"
+msgstr "E542: epätasapainoisia ryhmiä"
+
+msgid "E590: A preview window already exists"
+msgstr "E590: Esikatseluikkuna on jo olemassa"
+
+msgid "W17: Arabic requires UTF-8, do ':set encoding=utf-8'"
+msgstr "W17: Arabialle pitää olla UTF-8:aa, aseta :set encoding=utf-8"
+
+#, c-format
+msgid "E593: Need at least %d lines"
+msgstr "E593: Tarvitaan ainakin %d riviä"
+
+#, c-format
+msgid "E594: Need at least %d columns"
+msgstr "E594: Tarvitaan ainakin %d saraketta"
+
+#, 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.
+#, c-format
+msgid "E521: Number required: &%s = '%s'"
+msgstr "E521: tarvitaan luku: &%s = '%s'"
+
+msgid ""
+"\n"
+"--- Terminal codes ---"
+msgstr ""
+"\n"
+"--- Terminaalikoodit ---"
+
+msgid ""
+"\n"
+"--- Global option values ---"
+msgstr ""
+"\n"
+"--- Globaalit asetukset ---"
+
+msgid ""
+"\n"
+"--- Local option values ---"
+msgstr ""
+"\n"
+"--- Paikalliset asetukset ---"
+
+msgid ""
+"\n"
+"--- Options ---"
+msgstr ""
+"\n"
+"--- Asetukset ---"
+
+msgid "E356: get_varp ERROR"
+msgstr "E356: get_varp-virhe"
+
+#, c-format
+msgid "E357: 'langmap': Matching character missing for %s"
+msgstr "E357: langmap: Merkkiin %s täsmäävä merkki puuttuu"
+
+#, c-format
+msgid "E358: 'langmap': Extra characters after semicolon: %s"
+msgstr "E358: langmap: ylimääräisiä merkkejä puolipisteen jälkeen: %s"
+
+msgid "cannot open "
+msgstr "ei voi avata "
+
+msgid "VIM: Can't open window!\n"
+msgstr "VIM: Ei voi avata ikkunaa\n"
+
+msgid "Need Amigados version 2.04 or later\n"
+msgstr "Amigados 2.04 tai uudempi tarvitaan\n"
+
+#, c-format
+msgid "Need %s version %ld\n"
+msgstr "Tarvitaan %s versio %ld\n"
+
+msgid "Cannot open NIL:\n"
+msgstr "Ei voi avata NILiä:\n"
+
+msgid "Cannot create "
+msgstr "Ei voi luoda "
+
+#, c-format
+msgid "Vim exiting with %d\n"
+msgstr "Vim sulkeutuu koodilla %d\n"
+
+msgid "cannot change console mode ?!\n"
+msgstr "ei voi vaihtaa konsolitilaa?\n"
+
+msgid "mch_get_shellsize: not a console??\n"
+msgstr "mch_get_shellsize: ei ole konsoli?\n"
+
+#. if Vim opened a window: Executing a shell may cause crashes
+msgid "E360: Cannot execute shell with -f option"
+msgstr "E360: Kuorta ei voi avata asetuksella -f"
+
+msgid "Cannot execute "
+msgstr "Ei voi suorittaa "
+
+msgid "shell "
+msgstr "kuori "
+
+msgid " returned\n"
+msgstr " palautti\n"
+
+msgid "ANCHOR_BUF_SIZE too small."
+msgstr "ANCHOR_BUF_SIZE liian pieni."
+
+msgid "I/O ERROR"
+msgstr "IO-virhe"
+
+msgid "Message"
+msgstr "Viesti"
+
+msgid "'columns' is not 80, cannot execute external commands"
+msgstr "columns ei ole 80, ei voi suorittaa ulkoista komentoa"
+
+msgid "E237: Printer selection failed"
+msgstr "E237: Tulostimen valinta epäonnistui"
+
+#, c-format
+msgid "to %s on %s"
+msgstr "tulostimelle %s kohteessa %s"
+
+#, c-format
+msgid "E613: Unknown printer font: %s"
+msgstr "E613: Tuntematon tulostimen fontti: %s"
+
+#, c-format
+msgid "E238: Print error: %s"
+msgstr "E238: Tulostinvirhe: %s"
+
+#, c-format
+msgid "Printing '%s'"
+msgstr "Tulostetaan %s"
+
+#, c-format
+msgid "E244: Illegal charset name \"%s\" in font name \"%s\""
+msgstr "E244: Virheellinen merkistön nimi %s fontin nimessä %s"
+
+#, c-format
+msgid "E245: Illegal char '%c' in font name \"%s\""
+msgstr "E245: Virheellinen merkki %c fontin nimessä %s"
+
+msgid "Vim: Double signal, exiting\n"
+msgstr "Vim: Kaksoissignaali, lopetetaan\n"
+
+#, c-format
+msgid "Vim: Caught deadly signal %s\n"
+msgstr "Vim: Tappava signaali %s\n"
+
+#, c-format
+msgid "Vim: Caught deadly signal\n"
+msgstr "Vim: Tappava signaali\n"
+
+#, c-format
+msgid "Opening the X display took %ld msec"
+msgstr "X-näytön avaus vei %ld millisekuntia"
+
+msgid ""
+"\n"
+"Vim: Got X error\n"
+msgstr ""
+"\n"
+"Vim: X-virhe\n"
+
+msgid "Testing the X display failed"
+msgstr "X-näytön testaus epäonnistui"
+
+msgid "Opening the X display timed out"
+msgstr "X-näytön avaus aikakatkaistiin"
+
+# mikä security context?
+msgid ""
+"\n"
+"Could not get security context for "
+msgstr ""
+"\n"
+"Ei saatu turvallisuuskontekstia kohteelle "
+
+msgid ""
+"\n"
+"Could not set security context for "
+msgstr ""
+"\n"
+"Ei voitu asettaa turvallisuuskontekstia kohteelle "
+
+msgid ""
+"\n"
+"Cannot execute shell "
+msgstr ""
+"\n"
+"Kuoren suoritus ei onnistu "
+
+msgid ""
+"\n"
+"Cannot execute shell sh\n"
+msgstr ""
+"\n"
+"Kuoren sh suoritus ei onnistu\n"
+
+msgid ""
+"\n"
+"shell returned "
+msgstr ""
+"\n"
+"kuoren palautusarvo "
+
+msgid ""
+"\n"
+"Cannot create pipes\n"
+msgstr ""
+"\n"
+"Putkia ei voi tehdä\n"
+
+msgid ""
+"\n"
+"Cannot fork\n"
+msgstr ""
+"\n"
+"Ei voi haarauttaa\n"
+
+msgid ""
+"\n"
+"Command terminated\n"
+msgstr ""
+"\n"
+"Komento loppui\n"
+
+msgid "XSMP lost ICE connection"
+msgstr "XSMP kadotti ICE-yhteyden"
+
+#, c-format
+msgid "dlerror = \"%s\""
+msgstr "dlerror = %s"
+
+msgid "Opening the X display failed"
+msgstr "X-näytön avaus epäonnistui"
+
+msgid "XSMP handling save-yourself request"
+msgstr "XSMP käsittelee save-yourself-pyyntöä"
+
+msgid "XSMP opening connection"
+msgstr "XSMP avaa yhteyttä"
+
+msgid "XSMP ICE connection watch failed"
+msgstr "XSMP:n ICE-yhteyden tarkkailu epäonnistui"
+
+#, c-format
+msgid "XSMP SmcOpenConnection failed: %s"
+msgstr "XSMP SmcOpenConnection epäonnistui: %s"
+
+msgid "At line"
+msgstr "Rivillä"
+
+msgid "Could not load vim32.dll!"
+msgstr "Vim32.dll:ää ei voitu ladata"
+
+msgid "VIM Error"
+msgstr "VIM-virhe"
+
+msgid "Could not fix up function pointers to the DLL!"
+msgstr "Ei voitu korjata funktio-osoittimia DLL:ssä"
+
+#, c-format
+msgid "shell returned %d"
+msgstr "kuori palautti arvon %d"
+
+#, c-format
+msgid "Vim: Caught %s event\n"
+msgstr "Vim: Napattiin %s\n"
+
+msgid "close"
+msgstr "sulkeminen"
+
+msgid "logoff"
+msgstr "uloskirjautuminen"
+
+msgid "shutdown"
+msgstr "sammutus"
+
+msgid "E371: Command not found"
+msgstr "E371: Komentoa ei löydy"
+
+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 "Vim Warning"
+msgstr "Vim-varoitus"
+
+#, c-format
+msgid "E372: Too many %%%c in format string"
+msgstr "E372: Liikaa %%%c-juttuja muotoilumerkkijonossa"
+
+#, c-format
+msgid "E373: Unexpected %%%c in format string"
+msgstr "E373: Odottamaton %%%c muotoilumerkkijonossa"
+
+msgid "E374: Missing ] in format string"
+msgstr "E374: ] puuttuu muotoilemerkkijonosta"
+
+#, c-format
+msgid "E375: Unsupported %%%c in format string"
+msgstr "E375: Tukematon %%%c muotoilumerkkijonossa"
+
+#, c-format
+msgid "E376: Invalid %%%c in format string prefix"
+msgstr "E376: Virheellinen %%%c muotoilumerkkijonon alussa"
+
+#, c-format
+msgid "E377: Invalid %%%c in format string"
+msgstr "E377: Virheellinen %%%c muotoilumerkkijonossa"
+
+msgid "E378: 'errorformat' contains no pattern"
+msgstr "E378: errorformatissa ei ole kuvioita"
+
+msgid "E379: Missing or empty directory name"
+msgstr "E379: Puuttuva tai tyhjä hakemiston nimi"
+
+msgid "E553: No more items"
+msgstr "E553: Ei enää kohteita"
+
+#, c-format
+msgid "(%d of %d)%s%s: "
+msgstr "(%d/%d)%s%s: "
+
+msgid " (line deleted)"
+msgstr " (rivi poistettu)"
+
+msgid "E380: At bottom of quickfix stack"
+msgstr "E380: quickfix-pinon pohjalla"
+
+msgid "E381: At top of quickfix stack"
+msgstr "E381: quickfix-pinon huipulla"
+
+#, c-format
+msgid "error list %d of %d; %d errors"
+msgstr "virhelista %d/%d, %d virhettä"
+
+msgid "E382: Cannot write, 'buftype' option is set"
+msgstr "E382: Ei voi kirjoittaa, buftype asetettu"
+
+msgid "Error file"
+msgstr "Virhetiedosto"
+
+msgid "E683: File name missing or invalid pattern"
+msgstr "E683: Tiedostonimi puuttuu tai kuvio on viallinen"
+
+#, c-format
+msgid "Cannot open file \"%s\""
+msgstr "Tiedostoa %s ei voi avata"
+
+msgid "E681: Buffer is not loaded"
+msgstr "E681: Puskuria ei ole ladattu"
+
+msgid "E777: String or List expected"
+msgstr "E777: Pitää olla merkkijono tai lista"
+
+#, c-format
+msgid "E369: invalid item in %s%%[]"
+msgstr "E369: virheellinen olio kohdassa %s%%[]"
+
+msgid "E339: Pattern too long"
+msgstr "E339: Liian pitkä kuvio"
+
+msgid "E50: Too many \\z("
+msgstr "E50: Liikaa merkkejä \\z("
+
+#, c-format
+msgid "E51: Too many %s("
+msgstr "E51: Liikaa merkkejä %s("
+
+msgid "E52: Unmatched \\z("
+msgstr "E52: Pariton \\z("
+
+#, c-format
+msgid "E53: Unmatched %s%%("
+msgstr "E53: Pariton %s%%("
+
+#, c-format
+msgid "E54: Unmatched %s("
+msgstr "E54: Pariton %s("
+
+#, c-format
+msgid "E55: Unmatched %s)"
+msgstr "E55: Pariton %s)"
+
+#, c-format
+msgid "E59: invalid character after %s@"
+msgstr "E59: virheellinen merkki kohdan %s@ jälkeen"
+
+#, c-format
+msgid "E60: Too many complex %s{...}s"
+msgstr "E60: Liikaa monimutkaisia ilmauksia %s{...}s"
+
+#, c-format
+msgid "E61: Nested %s*"
+msgstr "E61: Sisäkkäistetty %s*"
+
+#, c-format
+msgid "E62: Nested %s%c"
+msgstr "E62: Sisäkkäistetty %s%c"
+
+msgid "E63: invalid use of \\_"
+msgstr "E63: väärinkäytetty \\_"
+
+#, c-format
+msgid "E64: %s%c follows nothing"
+msgstr "E64: %s%c jälkeen ei minkään"
+
+msgid "E65: Illegal back reference"
+msgstr "E65: Virheellinen täsmäysviittaus"
+
+msgid "E66: \\z( not allowed here"
+msgstr "E66: \\z( ei ole sallittu tässä"
+
+msgid "E67: \\z1 et al. not allowed here"
+msgstr "E67: \\z1 jne. ei ole sallittu tässä"
+
+msgid "E68: Invalid character after \\z"
+msgstr "E68: Virheellinen merkki ilmauksen \\z jälkeen"
+
+#, c-format
+msgid "E69: Missing ] after %s%%["
+msgstr "E69: ] puuttuu merkinnän %s%%[ jäljestä"
+
+#, c-format
+msgid "E70: Empty %s%%[]"
+msgstr "E70: Tyhjä %s%%[]"
+
+#, c-format
+msgid "E678: Invalid character after %s%%[dxouU]"
+msgstr "E678: Virheellinen merkki merkinnän %s%%[dxouU] jäljessä"
+
+#, c-format
+msgid "E71: Invalid character after %s%%"
+msgstr "E71: Virheellinen merkki merkinnän %s%% jäljessä"
+
+#, c-format
+msgid "E769: Missing ] after %s["
+msgstr "E769: ] puuttuu merkinnän %s[ jäljestä"
+
+#, c-format
+msgid "E554: Syntax error in %s{...}"
+msgstr "E554: Syntaksivirhe ilmauksessa %s{...}"
+
+msgid "External submatches:\n"
+msgstr "Ulkoisia alitäsmäyksiä:\n"
+
+# tiloja
+msgid " VREPLACE"
+msgstr " VKORVAUS"
+
+msgid " REPLACE"
+msgstr " KORVAUS"
+
+msgid " REVERSE"
+msgstr " KÄÄNTEIS"
+
+msgid " INSERT"
+msgstr " SYÖTTÖ"
+
+msgid " (insert)"
+msgstr " (syöttö)"
+
+msgid " (replace)"
+msgstr " (korvaus)"
+
+msgid " (vreplace)"
+msgstr " (vkorvaus)"
+
+msgid " Hebrew"
+msgstr " Heprea"
+
+msgid " Arabic"
+msgstr " Arabia"
+
+msgid " (lang)"
+msgstr " (kieli)"
+
+msgid " (paste)"
+msgstr " (liitos)"
+
+msgid " VISUAL"
+msgstr " VALINTA"
+
+msgid " VISUAL LINE"
+msgstr " VALINTARIVI"
+
+msgid " VISUAL BLOCK"
+msgstr " VALINTALOHKO"
+
+msgid " SELECT"
+msgstr " WALINTA"
+
+msgid " SELECT LINE"
+msgstr " WALINTARIVI"
+
+msgid " SELECT BLOCK"
+msgstr " WALINTALOHKO"
+
+msgid "recording"
+msgstr "tallennetaan"
+
+#, c-format
+msgid "E383: Invalid search string: %s"
+msgstr "E383: Viallinen hakujono: %s"
+
+#, c-format
+msgid "E384: search hit TOP without match for: %s"
+msgstr "E384: Haku pääsi alkuun löytämättä jonoa: %s"
+
+#, c-format
+msgid "E385: search hit BOTTOM without match for: %s"
+msgstr "E385: Haku pääsi loppuun löytämättä jonoa: %s"
+
+msgid "E386: Expected '?' or '/' after ';'"
+msgstr "E386: ;:n jälkeen pitää olla ? tai /"
+
+msgid " (includes previously listed match)"
+msgstr " (sisältää viimeksi luetellun täsmäyksen)"
+
+#. cursor at status line
+msgid "--- Included files "
+msgstr "--- Sisällytetyt tiedostot "
+
+msgid "not found "
+msgstr "ei löytynyt "
+
+msgid "in path ---\n"
+msgstr "polusta ---\n"
+
+msgid " (Already listed)"
+msgstr " (Jo lueteltu)"
+
+msgid " NOT FOUND"
+msgstr " EI LÖYTYNYT"
+
+#, c-format
+msgid "Scanning included file: %s"
+msgstr "Haku sisälsi tiedoston: %s"
+
+#, c-format
+msgid "Searching included file %s"
+msgstr "Haku sisälsi tiedoston %s"
+
+msgid "E387: Match is on current line"
+msgstr "E387: Täsmäys tällä rivillä"
+
+msgid "All included files were found"
+msgstr "Kaikki sisällytetyt rivit löytyivät"
+
+msgid "No included files"
+msgstr "Ei sisällytettyjä tiedostoja"
+
+msgid "E388: Couldn't find definition"
+msgstr "E388: Määritelmä ei löydy"
+
+msgid "E389: Couldn't find pattern"
+msgstr "E389: kuvio ei löydy"
+
+msgid "Substitute "
+msgstr "Korvaa "
+
+#, c-format
+msgid ""
+"\n"
+"# Last %sSearch Pattern:\n"
+"~"
+msgstr ""
+"\n"
+"# Edellinen %sHakulauseke:\n"
+"~"
+
+msgid "E759: Format error in spell file"
+msgstr "E759: Muotoiluvirhe oikolukutiedostossa"
+
+msgid "E758: Truncated spell file"
+msgstr "E758: Oikolukutiedosto katkaistu"
+
+#, c-format
+msgid "Trailing text in %s line %d: %s"
+msgstr "Tekstiä rivin perässä tiedostossa %s rivillä %d: %s"
+
+#, c-format
+msgid "Affix name too long in %s line %d: %s"
+msgstr "Affiksin nimi on liian pitkä tiedostossa %s rivillä %d: %s"
+
+msgid "E761: Format error in affix file FOL, LOW or UPP"
+msgstr "E761: Affiksitiedoston FOL-, LOW- tai UPP-muotovirhe "
+
+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"
+
+msgid "Compressing word tree..."
+msgstr "Tiivistetään sanapuuta..."
+
+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"
+
+#, c-format
+msgid "Reading spell file \"%s\""
+msgstr "Luetaan oikaisulukutiedosta %s"
+
+msgid "E757: This does not look like a spell file"
+msgstr "E757: Ei vaikuta oikaisulukutiedostolta"
+
+msgid "E771: Old spell file, needs to be updated"
+msgstr "E771: Vanha oikaisulukutiedosto vaatii päivittämistä"
+
+msgid "E772: Spell file is for newer version of Vim"
+msgstr "E772: Oikaisulukutiedosto on uudemmalle Vimille"
+
+msgid "E770: Unsupported section in spell file"
+msgstr "E770: Tukematon osio oikaisulukutiedostossa"
+
+#, c-format
+msgid "Warning: region %s not supported"
+msgstr "Varoitus: osaa %s ei tueta"
+
+#, c-format
+msgid "Reading affix file %s ..."
+msgstr "Luetaan affiksitiedostoa %s..."
+
+#, c-format
+msgid "Conversion failure for word in %s line %d: %s"
+msgstr "Muunnosvirhe sanalle %s rivillä %d: %s"
+
+#, c-format
+msgid "Conversion in %s not supported: from %s to %s"
+msgstr "Muunnosta kohteessa %s ei tueta: kohteesta %s kohteeseen %s"
+
+#, c-format
+msgid "Conversion in %s not supported"
+msgstr "Muutosta kohteessa %s ei tueta"
+
+#, c-format
+msgid "Invalid value for FLAG in %s line %d: %s"
+msgstr "Tuntematon FLAG kohteessa %s rivillä %d: %s"
+
+#, c-format
+msgid "FLAG after using flags in %s line %d: %s"
+msgstr "FLAG kohteessa %s lippujen jälkeen rivillä %d: %s"
+
+#, 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"
+
+#, 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"
+
+#, c-format
+msgid "Wrong COMPOUNDRULES value in %s line %d: %s"
+msgstr "Väärä COMPOUNDRULES-arvo kohteessa %s rivillä %d: %s"
+
+#, c-format
+msgid "Wrong COMPOUNDWORDMAX value in %s line %d: %s"
+msgstr "Väärä COMPOUNDWORDMAX-arvo kohteessa %s rivillä %d: %s"
+
+#, c-format
+msgid "Wrong COMPOUNDMIN value in %s line %d: %s"
+msgstr "Väärä COMPOUNDMIN-arvo kohteessa %s rivillä %d: %s"
+
+#, c-format
+msgid "Wrong COMPOUNDSYLMAX value in %s line %d: %s"
+msgstr "Väärä COMPOUNDSYLMAX-arvo kohteessa %s rivillä %d: %s"
+
+#, c-format
+msgid "Wrong CHECKCOMPOUNDPATTERN value in %s line %d: %s"
+msgstr "Väärä CHECKCOMPOUNDPATTERN-arvo kohteessa %s rivillä %d: %s"
+
+#, 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"
+
+#, c-format
+msgid "Duplicate affix in %s line %d: %s"
+msgstr "Kaksoiskappale affiksista kohteessa %s rivillä %d: %s"
+
+#, c-format
+msgid ""
+"Affix also used for BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST in %s "
+"line %d: %s"
+msgstr ""
+"Affiksia käytetty myös BAD-, RARE-, KEEPCASE-, NEEDAFFIX-, NEEDCOMPOUND- tai "
+"NOSUGGEST-arvossa kohteessa %s rivillä %d: %s"
+
+#, c-format
+msgid "Expected Y or N in %s line %d: %s"
+msgstr "Odotettiin Y:tä tai N:ää kohteessa %s rivillä %d: %s"
+
+#, c-format
+msgid "Broken condition in %s line %d: %s"
+msgstr "Viallinen ehto kohteessa %s rivillä %d: %s"
+
+#, c-format
+msgid "Expected REP(SAL) count in %s line %d"
+msgstr "Odotettiin REP(SAL)-arvoa kohteessa %s rivillä %d"
+
+#, c-format
+msgid "Expected MAP count in %s line %d"
+msgstr "Odotettiin MAP-arvoa kohteessa %s rivillä %d"
+
+#, c-format
+msgid "Duplicate character in MAP in %s line %d"
+msgstr "Kaksoiskappale merkistä MAP:ssä kohteessa %s rivillä %d"
+
+#, c-format
+msgid "Unrecognized or duplicate item in %s line %d: %s"
+msgstr "Tunnistamaton tai kaksoiskappale arvosta kohteessa %s rivillä %d: %s"
+
+#, c-format
+msgid "Missing FOL/LOW/UPP line in %s"
+msgstr "Puuttuva FOL, LOW tai UPP rivi kohteessa %s"
+
+msgid "COMPOUNDSYLMAX used without SYLLABLE"
+msgstr "COMPOUNDSYLMAX ilman SYLLABLEa"
+
+msgid "Too many postponed prefixes"
+msgstr "Liikaa jälkikäteistettyjä prefiksejä"
+
+msgid "Too many compound flags"
+msgstr "Liikaa yhdyssanalippuja"
+
+msgid "Too many postponed prefixes and/or compound flags"
+msgstr "Liikaa jälkikäteistettyjä prefiksejä tai yhdyssanalippuja"
+
+#, c-format
+msgid "Missing SOFO%s line in %s"
+msgstr "Puuttuva SOFO%s-rivi kohteessa %s"
+
+#, c-format
+msgid "Both SAL and SOFO lines in %s"
+msgstr "SAL- ja SOFO-rivit kohteessa %s"
+
+#, c-format
+msgid "Flag is not a number in %s line %d: %s"
+msgstr "Lippu ei ole lukuarvo kohteessa %s rivillä %d: %s"
+
+#, c-format
+msgid "Illegal flag in %s line %d: %s"
+msgstr "Tuntematon lippu kohteessa %s rivillä %d: %s"
+
+#, c-format
+msgid "%s value differs from what is used in another .aff file"
+msgstr "%s-arvo eroaa toisessa .aff-tiedostossa olevasta"
+
+#, c-format
+msgid "Reading dictionary file %s ..."
+msgstr "Luetaan sanakirjatiedostoa %s"
+
+#, c-format
+msgid "E760: No word count in %s"
+msgstr "E760: Ei sanalaskuria kohteessa %s"
+
+#, c-format
+msgid "line %6d, word %6d - %s"
+msgstr "rivi %6d, sana %6d - %s"
+
+#, c-format
+msgid "Duplicate word in %s line %d: %s"
+msgstr "Toistettu sana kohteessa %s rivillä %d: %s"
+
+#, c-format
+msgid "First duplicate word in %s line %d: %s"
+msgstr "Ensimmäinen kappale kohteessa %s rivillä %d: %s"
+
+#, c-format
+msgid "%d duplicate word(s) in %s"
+msgstr "toistettuja sanoja %d kohteessa %s"
+
+#, c-format
+msgid "Ignored %d word(s) with non-ASCII characters in %s"
+msgstr "Ei-ASCII-merkkien takia ohitettuja sanoja %d kohteessa %s"
+
+#, c-format
+msgid "Reading word file %s ..."
+msgstr "Luetaan sanatiedostoa %s..."
+
+#, c-format
+msgid "Duplicate /encoding= line ignored in %s line %d: %s"
+msgstr "Toistettu /encoding= ohitettu kohteessa %s rivillä %d: %s"
+
+#, c-format
+msgid "/encoding= line after word ignored in %s line %d: %s"
+msgstr "/encoding= sanojen jälkeen ohitettu kohteessa %s rivillä %d: %s"
+
+#, c-format
+msgid "Duplicate /regions= line ignored in %s line %d: %s"
+msgstr "Toistettu /regions= ohitettu kohteessa %s rivillä %d: %s"
+
+#, c-format
+msgid "Too many regions in %s line %d: %s"
+msgstr "Liikaa regionseja kohteessa %s rivillä %d: %s"
+
+#, c-format
+msgid "/ line ignored in %s line %d: %s"
+msgstr "/ ohitettu kohteessa %s rivillä %d: %s"
+
+#, c-format
+msgid "Invalid region nr in %s line %d: %s"
+msgstr "Virheellinen region-luku kohteessa %s rivillä %d: %s"
+
+#, c-format
+msgid "Unrecognized flags in %s line %d: %s"
+msgstr "Tunnistamaton lippu kohteessa %s rivillä %d: %s"
+
+#, c-format
+msgid "Ignored %d words with non-ASCII characters"
+msgstr "Ei-ASCIIn takia ohitettuja sanoja %d"
+
+#, c-format
+msgid "Compressed %d of %d nodes; %d (%d%%) remaining"
+msgstr "Tiivistetty %d/%d noodia. %d (%d %%) jäljellä"
+
+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.
+#.
+msgid "Performing soundfolding..."
+msgstr "Ääntämyksen mukaan yhdistellään..."
+
+#, c-format
+msgid "Number of words after soundfolding: %ld"
+msgstr "Sanoja ääntämysyhdistelyn jälkeen: %ld"
+
+#, c-format
+msgid "Total number of words: %d"
+msgstr "Sanoja yhteensä: %d"
+
+#, c-format
+msgid "Writing suggestion file %s ..."
+msgstr "Kirjoitetaan ehdotustiedostoa %s..."
+
+#, c-format
+msgid "Estimated runtime memory use: %d bytes"
+msgstr "Arvioitu käyttömuisti: %d tavua"
+
+msgid "E751: Output file name must not have region name"
+msgstr "E751: Tulostetiedostonimessä ei saa olla alueen nimeä"
+
+msgid "E754: Only up to 8 regions supported"
+msgstr "E754: Enintään 8 aluetta tuetaan"
+
+#, c-format
+msgid "E755: Invalid region in %s"
+msgstr "E755: Virheellinen alue kohteelle %s"
+
+msgid "Warning: both compounding and NOBREAK specified"
+msgstr "Varoitus: sekä yhdyssanamuodostus että NOBREAK käytössä"
+
+#, c-format
+msgid "Writing spell file %s ..."
+msgstr "Kirjoitetaan oikaisulukutiedostoa %s..."
+
+msgid "Done!"
+msgstr "Valmista."
+
+#, c-format
+msgid "E765: 'spellfile' does not have %ld entries"
+msgstr "E765: spellfile ei sisällä %ld kohtaa"
+
+#, c-format
+msgid "Word removed from %s"
+msgstr "Sana poistettu kohteesta %s"
+
+#, c-format
+msgid "Word added to %s"
+msgstr "Sana lisätty kohteeseen %s"
+
+msgid "E763: Word characters differ between spell files"
+msgstr "E763: Sanan merkit muuttuvat oikaisulukutiedostojen välillä"
+
+msgid "Sorry, no suggestions"
+msgstr "Sori, ei ehdotuksia"
+
+#, c-format
+msgid "Sorry, only %ld suggestions"
+msgstr "Sori, vain %ld ehdotusta"
+
+#. for when 'cmdheight' > 1
+#. avoid more prompt
+#, 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"
+
+#, c-format
+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"
+
+#, c-format
+msgid "E782: error while reading .sug file: %s"
+msgstr "E782: virhe luettaessa .sug-tiedostoa: %s"
+
+#. This should have been checked when generating the .spl
+#. * file.
+msgid "E783: duplicate char in MAP entry"
+msgstr "E783: kaksoiskappale merkistä MAP-kohdassa"
+
+#, c-format
+msgid "E390: Illegal argument: %s"
+msgstr "E390: Virheellinen argumentti: %s"
+
+#, c-format
+msgid "E391: No such syntax cluster: %s"
+msgstr "E391: Syntaksiklusteri puuttuu: %s"
+
+msgid "No Syntax items defined for this buffer"
+msgstr "Ei syntaksikohteita tälle puskurille"
+
+msgid "syncing on C-style comments"
+msgstr "synkkaa C-tyylin kommentteihin"
+
+msgid "no syncing"
+msgstr "ei synkkausta"
+
+msgid "syncing starts "
+msgstr "synkkaus aloitettu "
+
+msgid " lines before top line"
+msgstr " riviä ennen alkua"
+
+msgid ""
+"\n"
+"--- Syntax sync items ---"
+msgstr ""
+"\n"
+"--- Syntax sync -kohteet ---"
+
+msgid ""
+"\n"
+"syncing on items"
+msgstr ""
+"\n"
+"synkataan kohteisiin"
+
+msgid ""
+"\n"
+"--- Syntax items ---"
+msgstr ""
+"\n"
+"--- Syntax-kohteet ---"
+
+#, c-format
+msgid "E392: No such syntax cluster: %s"
+msgstr "E392: syntaksiklusteria ei ole: %s"
+
+msgid "minimal "
+msgstr "vähintään "
+
+msgid "maximal "
+msgstr "enitntään "
+
+msgid "; match "
+msgstr "; täsmää "
+
+msgid " line breaks"
+msgstr " rivinvaihdot"
+
+msgid "E395: contains argument not accepted here"
+msgstr "E395: contains ei sovi tähän"
+
+msgid "E393: group[t]here not accepted here"
+msgstr "E393: group[t]here ei sovi tähän"
+
+#, c-format
+msgid "E394: Didn't find region item for %s"
+msgstr "E394: Aluetta nimelle %s ei löydy"
+
+msgid "E397: Filename required"
+msgstr "E397: Tiedostonimi puuttuu"
+
+#, c-format
+msgid "E789: Missing ']': %s"
+msgstr "E789: ] puuttuu: %s"
+
+#, c-format
+msgid "E398: Missing '=': %s"
+msgstr "E398: = puuttuu: %s"
+
+#, c-format
+msgid "E399: Not enough arguments: syntax region %s"
+msgstr "E399: Argumentteja puuttuu: syntaksialue %s"
+
+msgid "E400: No cluster specified"
+msgstr "E400: klusteri määrittelemättä"
+
+#, c-format
+msgid "E401: Pattern delimiter not found: %s"
+msgstr "E401: Kuvoin erotin puuttuu: %s"
+
+#, c-format
+msgid "E402: Garbage after pattern: %s"
+msgstr "E402: Roskia kuvion jäljessä: %s"
+
+msgid "E403: syntax sync: line continuations pattern specified twice"
+msgstr "E403: syntax sync: rivinjatkamiskuvio määritelty kahdesti"
+
+#, c-format
+msgid "E404: Illegal arguments: %s"
+msgstr "E404: Virheelliset argumentit: %s"
+
+#, c-format
+msgid "E405: Missing equal sign: %s"
+msgstr "E405: = puuttuu: %s"
+
+#, c-format
+msgid "E406: Empty argument: %s"
+msgstr "E406: Tyhjä argumentti: %s"
+
+#, c-format
+msgid "E407: %s not allowed here"
+msgstr "E407: %s ei sovi tähän"
+
+#, c-format
+msgid "E408: %s must be first in contains list"
+msgstr "E408: %s kuuluu contains-listan alkuun"
+
+#, c-format
+msgid "E409: Unknown group name: %s"
+msgstr "E409: Tuntematon ryhmän nimi: %s"
+
+#, c-format
+msgid "E410: Invalid :syntax subcommand: %s"
+msgstr "E410: Virheelluinen :syntax-osakomento: %s"
+
+msgid "E679: recursive loop loading syncolor.vim"
+msgstr "E679: rekursiivinen silmukka syncolor.vimissä"
+
+#, c-format
+msgid "E411: highlight group not found: %s"
+msgstr "E411: korostusryhmää ei löytynyt: %s"
+
+#, c-format
+msgid "E412: Not enough arguments: \":highlight link %s\""
+msgstr "E412: Argumentteja puuttuu: :highlight link %s"
+
+#, c-format
+msgid "E413: Too many arguments: \":highlight link %s\""
+msgstr "E413: Liikaa argumentteja: :highlight link %s"
+
+msgid "E414: group has settings, highlight link ignored"
+msgstr "E414: ryhmällä on asetuksia, highlight link -komento ohitetaan"
+
+#, c-format
+msgid "E415: unexpected equal sign: %s"
+msgstr "E415: odotuksenvastainen =-merkki: %s"
+
+#, c-format
+msgid "E416: missing equal sign: %s"
+msgstr "E416: puuttuva =-merkki: %s"
+
+#, c-format
+msgid "E417: missing argument: %s"
+msgstr "E417: puuttuva argumentti: %s"
+
+#, c-format
+msgid "E418: Illegal value: %s"
+msgstr "E418: Viallinen arvo: %s"
+
+msgid "E419: FG color unknown"
+msgstr "E419: edustaväri tuntematon"
+
+msgid "E420: BG color unknown"
+msgstr "E420: taustaväri tuntematon"
+
+#, c-format
+msgid "E421: Color name or number not recognized: %s"
+msgstr "E421: Värin nimi tai numero tuntematon: %s"
+
+#, c-format
+msgid "E422: terminal code too long: %s"
+msgstr "E422: terminaalikoodi liian pitkä: %s"
+
+#, c-format
+msgid "E423: Illegal argument: %s"
+msgstr "E423: Virheellinen argumentti: %s"
+
+msgid "E424: Too many different highlighting attributes in use"
+msgstr "E424: Liikaa eri korostusattribuutteja"
+
+msgid "E669: Unprintable character in group name"
+msgstr "E669: Tulostuskelvoton merkki ryhmän nimessä"
+
+msgid "W18: Invalid character in group name"
+msgstr "W18: Virheellinen merkki ryhmän nimessä"
+
+msgid "E555: at bottom of tag stack"
+msgstr "E555: tägipinon pohja"
+
+msgid "E556: at top of tag stack"
+msgstr "E556: tägipinon huippu"
+
+msgid "E425: Cannot go before first matching tag"
+msgstr "E425: Ei voida mennä ensimmäistä täsmäävää tägiä alummaksi"
+
+#, c-format
+msgid "E426: tag not found: %s"
+msgstr "E426: tägi puuttuu: %s"
+
+msgid " # pri kind tag"
+msgstr " # arvo tyyppi tägi"
+
+msgid "file\n"
+msgstr "tiedosto\n"
+
+msgid "E427: There is only one matching tag"
+msgstr "E427: Vain yksi tägi täsmää"
+
+msgid "E428: Cannot go beyond last matching tag"
+msgstr "E428: Ei voida edetä viimeisen täsmäävän tägin ohi"
+
+#, c-format
+msgid "File \"%s\" does not exist"
+msgstr "Tiedostoa %s ei ole"
+
+#. Give an indication of the number of matching tags
+#, c-format
+msgid "tag %d of %d%s"
+msgstr "tägi %d/%d%s"
+
+msgid " or more"
+msgstr " tai useammasta"
+
+msgid " Using tag with different case!"
+msgstr " Tägissä eri kirjaintaso"
+
+#, c-format
+msgid "E429: File \"%s\" does not exist"
+msgstr "E429: Tiedostoa %s ei ole"
+
+#. Highlight title
+msgid ""
+"\n"
+" # TO tag FROM line in file/text"
+msgstr ""
+"\n"
+" # TILL tagg FRÅN LINJE i fil/text"
+
+#, c-format
+msgid "Searching tags file %s"
+msgstr "Etsitään tägitiedostoa %s"
+
+#, c-format
+msgid "E430: Tag file path truncated for %s\n"
+msgstr "E430: Tägitiedoston polku katkaistu kohdassa %s\n"
+
+#, c-format
+msgid "E431: Format error in tags file \"%s\""
+msgstr "E431: Muotovirh tägitiedostossa %s"
+
+#, c-format
+msgid "Before byte %ld"
+msgstr "Ennen tavua %ld"
+
+#, c-format
+msgid "E432: Tags file not sorted: %s"
+msgstr "E432: Tägitiedosto ei ole järjestetty: %s"
+
+#. never opened any tags file
+msgid "E433: No tags file"
+msgstr "E433: Ei tägitiedostoja"
+
+msgid "Ignoring long line in tags file"
+msgstr "Ohitetaan pitkä rivi tägitiedostossa"
+
+msgid "E434: Can't find tag pattern"
+msgstr "E434: Tägikuviota ei löydy"
+
+msgid "E435: Couldn't find tag, just guessing!"
+msgstr "E435: Tägiä ei löydy, arvataan."
+
+#, c-format
+msgid "Duplicate field name: %s"
+msgstr "Kaksoiskappale kentän nimestä: %s"
+
+msgid "' not known. Available builtin terminals are:"
+msgstr " ei tunnettu. Tuetut terminaalit:"
+
+msgid "defaulting to '"
+msgstr "oletusarvona "
+
+msgid "E557: Cannot open termcap file"
+msgstr "E557: Ei voi avata termcap-tiedostoa"
+
+msgid "E558: Terminal entry not found in terminfo"
+msgstr "E558: Terminaalia ei löytynyt terminfosta"
+
+msgid "E559: Terminal entry not found in termcap"
+msgstr "E559: Terminaalia ei löytynyt termcapista"
+
+#, c-format
+msgid "E436: No \"%s\" entry in termcap"
+msgstr "E436: %s ei löytynyt termcapista"
+
+msgid "E437: terminal capability \"cm\" required"
+msgstr "E437: terminaalilla pitää olla cm kyvyissään"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Terminal keys ---"
+msgstr ""
+"\n"
+"--- Terminaalinäppäimet ---"
+
+msgid "new shell started\n"
+msgstr "uusi kuori avattu\n"
+
+msgid "Vim: Error reading input, exiting...\n"
+msgstr "Vim: Virhe luettaessa syötettä, poistutaan...\n"
+
+msgid "Used CUT_BUFFER0 instead of empty selection"
+msgstr "Käytettiin CUT_BUFFER0:aa tyhjän valinnan sijaan"
+
+#. This happens when the FileChangedRO autocommand changes the
+#. * file in a way it becomes shorter.
+msgid "E834: Line count changed unexpectedly"
+msgstr "E834: Rivimäärä vaihtui odottamatta"
+
+#. must display the prompt
+msgid "No undo possible; continue anyway"
+msgstr "Ei voi kumota, jatketaan silti"
+
+#, c-format
+msgid "E828: Cannot open undo file for writing: %s"
+msgstr "E828: Kumoustiedoston avaus kirjoittamista varten ei onnistu: %s"
+
+#, c-format
+msgid "E825: Corrupted undo file (%s): %s"
+msgstr "E825: Pilaanntunut kumoustiedosto (%s): %s"
+
+msgid "Cannot write undo file in any directory in 'undodir'"
+msgstr "Ei voitu lukea kumoustiedostoa mistään undodir-muuttujan hakemistosta"
+
+#, c-format
+msgid "Will not overwrite with undo file, cannot read: %s"
+msgstr "Ei ylikirjoitetat kumoustiedostolla, koska ei voida lukea: %s"
+
+#, c-format
+msgid "Will not overwrite, this is not an undo file: %s"
+msgstr "Ei ylikirjoiteta, koska tämä ei ole kumoustiedosto: %s"
+
+msgid "Skipping undo file write, nothing to undo"
+msgstr "Ohitetaan kumoustiedoston kirjoitus, koska ei ole peruutettavia"
+
+#, c-format
+msgid "Writing undo file: %s"
+msgstr "Kirjoitetaan kumoustiedostoa: %s"
+
+#, c-format
+msgid "E829: write error in undo file: %s"
+msgstr "E829: Kirjoitusvirhe kumoustiedostossa: %s"
+
+#, c-format
+msgid "Not reading undo file, owner differs: %s"
+msgstr "Ei lueta kumoustiedosto jonka omistaja on eri: %s"
+
+#, c-format
+msgid "Reading undo file: %s"
+msgstr "Luetaan kumoustiedostoa: %s"
+
+#, c-format
+msgid "E822: Cannot open undo file for reading: %s"
+msgstr "E822: Kumoustiedostoa ei voi avata lukemista varten: %s"
+
+#, c-format
+msgid "E823: Not an undo file: %s"
+msgstr "E823: Ei ole kumoustiedosto: %s"
+
+#, c-format
+msgid "E832: Non-encrypted file has encrypted undo file: %s"
+msgstr "E832: Salaamattomalla tiedostolla on salattu kumoustiedosto: %s"
+
+#, c-format
+msgid "E826: Undo file decryption failed: %s"
+msgstr "E826: Kumoustiedoston purku epäonnistui: %s"
+
+#, c-format
+msgid "E827: Undo file is encrypted: %s"
+msgstr "E827: Kumoustiedosto on salattu: %s"
+
+#, c-format
+msgid "E824: Incompatible undo file: %s"
+msgstr "E824: Epäyhteensopiva kumoustiedosto: %s"
+
+msgid "File contents changed, cannot use undo info"
+msgstr "Tiedoston sisältö on muuttunut, joen kumoustiedot ovat "
+"käyttökelvottomia"
+
+#, c-format
+msgid "Finished reading undo file %s"
+msgstr "Ladattu kumoustiedoto %s"
+
+msgid "Already at oldest change"
+msgstr "Vanhimmassa muutoksessa"
+
+msgid "Already at newest change"
+msgstr "Nuorimmassa muutoksessa"
+
+#, c-format
+msgid "E830: Undo number %ld not found"
+msgstr "E830: Kumouslukua %ld ei löydy"
+
+msgid "E438: u_undo: line numbers wrong"
+msgstr "E438: u_undo: väärät rivinumerot"
+
+msgid "more line"
+msgstr "rivi lisää"
+
+msgid "more lines"
+msgstr "riviä lisää"
+
+msgid "line less"
+msgstr "rivi vähemmän"
+
+msgid "fewer lines"
+msgstr "riviä vähemmän"
+
+msgid "change"
+msgstr "muutos"
+
+msgid "changes"
+msgstr "muutosta"
+
+# eka %s yläpuolelta, toka %s alapuolelta, kolmas %s aika
+#, c-format
+msgid "%ld %s; %s #%ld %s"
+msgstr "%ld %s, %s #%ld %s"
+
+msgid "before"
+msgstr "ennen muutosta"
+
+msgid "after"
+msgstr "jälkeen muutoksen"
+
+msgid "Nothing to undo"
+msgstr "Ei kumottavaa"
+
+msgid "number changes time saved"
+msgstr "muutoksia aika tallennettu"
+
+#, c-format
+msgid "%ld seconds ago"
+msgstr "%ld sekuntia sitten"
+
+msgid "E790: undojoin is not allowed after undo"
+msgstr "E790: undojoin ei toimi undon jälkeen"
+
+msgid "E439: undo list corrupt"
+msgstr "E439: kumouslista rikki"
+
+msgid "E440: undo line missing"
+msgstr "E440: kumousrivi puuttuu"
+
+#. Only MS VC 4.1 and earlier can do Win32s
+msgid ""
+"\n"
+"MS-Windows 16/32-bit GUI version"
+msgstr ""
+"\n"
+"MS-Windows 16- t. 32-bittinen GUI-versio"
+
+msgid ""
+"\n"
+"MS-Windows 64-bit GUI version"
+msgstr ""
+"\n"
+"MS-Windows 64-bittinen GUI-versio"
+
+msgid ""
+"\n"
+"MS-Windows 32-bit GUI version"
+msgstr ""
+"\n"
+"MS-Windows 32-bittinen GUI-version"
+
+msgid " in Win32s mode"
+msgstr " Win32s-tilassa"
+
+msgid " with OLE support"
+msgstr " OLE-tuella"
+
+msgid ""
+"\n"
+"MS-Windows 64-bit console version"
+msgstr ""
+"\n"
+"MS-Windows 32-bittinen konsoliversio"
+
+msgid ""
+"\n"
+"MS-Windows 32-bit console version"
+msgstr ""
+"\n"
+"MS-Windows 32-bittinen konsoliversio"
+
+msgid ""
+"\n"
+"MS-Windows 16-bit version"
+msgstr ""
+"\n"
+"MS-Windows 16-bittinen versio"
+
+msgid ""
+"\n"
+"32-bit MS-DOS version"
+msgstr ""
+"\n"
+"32-bittinen MS-DOS-versio"
+
+msgid ""
+"\n"
+"16-bit MS-DOS version"
+msgstr ""
+"\n"
+"16-bittinen MS-DOS-versio"
+
+msgid ""
+"\n"
+"MacOS X (unix) version"
+msgstr ""
+"\n"
+"MacOS X-version (unix)"
+
+msgid ""
+"\n"
+"MacOS X version"
+msgstr ""
+"\n"
+"MacOS X-version"
+
+msgid ""
+"\n"
+"MacOS version"
+msgstr ""
+"\n"
+"MacOS-version"
+
+msgid ""
+"\n"
+"RISC OS version"
+msgstr ""
+"\n"
+"RISC OS-version"
+
+msgid ""
+"\n"
+"OpenVMS version"
+msgstr ""
+"\n"
+"OpenVMS-version"
+
+msgid ""
+"\n"
+"Included patches: "
+msgstr ""
+"\n"
+"Pätsit: "
+
+msgid ""
+"\n"
+"Extra patches: "
+msgstr "\n"
+"Muita pätsejä: "
+
+msgid "Modified by "
+msgstr "Muokannut "
+
+msgid ""
+"\n"
+"Compiled "
+msgstr ""
+"\n"
+"Kääntänyt "
+
+msgid "by "
+msgstr ": "
+
+msgid ""
+"\n"
+"Huge version "
+msgstr ""
+"\n"
+"Huge-versio "
+
+msgid ""
+"\n"
+"Big version "
+msgstr ""
+"\n"
+"Big-version "
+
+msgid ""
+"\n"
+"Normal version "
+msgstr ""
+"\n"
+"Normal-versio "
+
+msgid ""
+"\n"
+"Small version "
+msgstr ""
+"\n"
+"Small-versio "
+
+msgid ""
+"\n"
+"Tiny version "
+msgstr ""
+"\n"
+"Tiny-versio "
+
+msgid "without GUI."
+msgstr "ilman GUIta."
+
+msgid "with GTK2-GNOME GUI."
+msgstr "GTK2-Gnome-GUIlla."
+
+msgid "with GTK2 GUI."
+msgstr "GTK2-GUIlla."
+
+msgid "with X11-Motif GUI."
+msgstr "X11-Motif-GUIlla."
+
+msgid "with X11-neXtaw GUI."
+msgstr "X11-neXtaw-GUIlla."
+
+msgid "with X11-Athena GUI."
+msgstr "X11-Athena-GUIlla."
+
+msgid "with Photon GUI."
+msgstr "Photon-GUIlla."
+
+msgid "with GUI."
+msgstr "GUIlla."
+
+msgid "with Carbon GUI."
+msgstr "Carbon-GUIlla."
+
+msgid "with Cocoa GUI."
+msgstr "Cocoa-GUIlla."
+
+msgid "with (classic) GUI."
+msgstr "perinteisellä GUIlla."
+
+msgid " Features included (+) or not (-):\n"
+msgstr " Ominaisuudet mukana (+) ja poissa (-):\n"
+
+msgid " system vimrc file: \""
+msgstr " järjestelmän vimrc: \""
+
+msgid " user vimrc file: \""
+msgstr " käyttäjän vimrc: \""
+
+msgid " 2nd user vimrc file: \""
+msgstr " 2. käyttäjän vimrc: \""
+
+msgid " 3rd user vimrc file: \""
+msgstr " 3. käyttäjän vimrc: \""
+
+msgid " user exrc file: \""
+msgstr " käyttäjän exrc: \""
+
+msgid " 2nd user exrc file: \""
+msgstr " 2. käyttäjän exrc: \""
+
+msgid " system gvimrc file: \""
+msgstr " järjestelmän gvimrc: \""
+
+msgid " user gvimrc file: \""
+msgstr " käyttäjän gvimrc: \""
+
+msgid "2nd user gvimrc file: \""
+msgstr "2. käyttäjän gvimrc: \""
+
+msgid "3rd user gvimrc file: \""
+msgstr "3. käyttäjän gvimrc: \""
+
+msgid " system menu file: \""
+msgstr " järjestelmävalikko: \""
+
+msgid " fall-back for $VIM: \""
+msgstr " $VIMin fallback: \""
+
+msgid " f-b for $VIMRUNTIME: \""
+msgstr " $VIMRUNTIMEn f-b: \""
+
+msgid "Compilation: "
+msgstr "Käännös: "
+
+msgid "Compiler: "
+msgstr "Käännin: "
+
+msgid "Linking: "
+msgstr "Linkitys: "
+
+msgid " DEBUG BUILD"
+msgstr " DEBUG-versio"
+
+msgid "VIM - Vi IMproved"
+msgstr "VIM - Vi IMproved"
+
+msgid "version "
+msgstr "versio "
+
+msgid "by Bram Moolenaar et al."
+msgstr "tekijät Bram Moolenaar et al."
+
+msgid "Vim is open source and freely distributable"
+msgstr "Vim on avointa lähdekoodia ja vapaasti jaossa"
+
+msgid "Help poor children in Uganda!"
+msgstr "Auta Ugandan köyhiä lapsia"
+
+msgid "type :help iccf<Enter> for information "
+msgstr "kirjoita :help iccf<Enter> lisätietoa varten "
+
+msgid "type :q<Enter> to exit "
+msgstr "kirjoita :q<Enter> lopettaaksesi "
+
+msgid "type :help<Enter> or <F1> for on-line help"
+msgstr "kirjoita :help<Enter> tai <F1> ohjetta varten "
+
+msgid "type :help version7<Enter> for version info"
+msgstr "kirjoita :help version7<Enter> versiotietoja varten "
+
+msgid "Running in Vi compatible mode"
+msgstr "Suoritetaan Vi-yhteensopivuustilaa"
+
+msgid "type :set nocp<Enter> for Vim defaults"
+msgstr "kirjoita :set nocp<Enter> Vimin oletuksiin "
+
+msgid "type :help cp-default<Enter> for info on this"
+msgstr "kirjoita :help cp-default<Enter> ohjetta oletuksista varten"
+
+msgid "menu Help->Orphans for information "
+msgstr "valikko Ohje->Orvot lisätietoja varten "
+
+msgid "Running modeless, typed text is inserted"
+msgstr "Suoritetaan tilattomana, kirjoitettu teksti syötetään"
+
+msgid "menu Edit->Global Settings->Toggle Insert Mode "
+msgstr "valikko Muokkaa->Yleiset asetukset->Vaihda syötetilaa"
+
+msgid " for two modes "
+msgstr " kahta tilaa varten "
+
+msgid "menu Edit->Global Settings->Toggle Vi Compatible"
+msgstr "valikko Muokkaa->Yleiset asetukset->Vaihda Vi-yhteensopivuutta"
+
+msgid " for Vim defaults "
+msgstr " Vim-oletuksia varten"
+
+msgid "Sponsor Vim development!"
+msgstr "Tue Vimin kehitystä"
+
+msgid "Become a registered Vim user!"
+msgstr "Rekisteröidy Vim-käyttäjäksi."
+
+msgid "type :help sponsor<Enter> for information "
+msgstr "kirjoita :help sponsor<Enter> lisätietoja varten"
+
+msgid "type :help register<Enter> for information "
+msgstr "kirjoita :help register<Enter> lisätietoja varten"
+
+msgid "menu Help->Sponsor/Register for information "
+msgstr "valikko Ohje->Sponsoroi/Rekisteröi lisätietoja varten"
+
+msgid "WARNING: Windows 95/98/ME detected"
+msgstr "VAROITUS: Window 95/98/ME havaittu"
+
+msgid "type :help windows95<Enter> for info on this"
+msgstr "kirjoita :help windows95<Enter> lisätietoja varten"
+
+msgid "Already only one window"
+msgstr "Enää yksi ikkuna jäljellä"
+
+msgid "E441: There is no preview window"
+msgstr "E441: Ei esikatseluikkunaa"
+
+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"
+
+msgid "E443: Cannot rotate when another window is split"
+msgstr "E443: Ei voi kiertää kun toinen ikkuna on jaettu"
+
+msgid "E444: Cannot close last window"
+msgstr "E444: Ei voi sulkea viimeistä ikkunaa"
+
+msgid "E813: Cannot close autocmd window"
+msgstr "E813: Ei voi sulkea autocmd-ikkunaa"
+
+msgid "E814: Cannot close window, only autocmd window would remain"
+msgstr "E814: Ei voi sulkea viimeistä ikkunaa, joka ei ole autocmd-ikkuna"
+
+msgid "E445: Other window contains changes"
+msgstr "E445: Toinen ikkuna sisältää muutoksia"
+
+msgid "E446: No file name under cursor"
+msgstr "E446: Ei tiedostonimeä kursorin alla"
+
+#, c-format
+msgid "E447: Can't find file \"%s\" in path"
+msgstr "E447: Tiedosto %s ei löydy polulta"
+
+#, c-format
+msgid "E370: Could not load library %s"
+msgstr "E370: Kirjaston %s lataaminen ei onnistu"
+
+msgid "Sorry, this command is disabled: the Perl library could not be loaded."
+msgstr "Sori, komento ei toimi, Perl kirjastoa ei voinut ladata."
+
+msgid "E299: Perl evaluation forbidden in sandbox without the Safe module"
+msgstr "E299: Perl-suoritus kielletty hiekkalaatikossa ilman Safe-moduulia"
+
+msgid "Edit with &multiple Vims"
+msgstr "&Muokkaa usealla Vimillä"
+
+msgid "Edit with single &Vim"
+msgstr "Muokkaa yhdellä &Vimillä"
+
+msgid "Diff with Vim"
+msgstr "Diffi Vimillä"
+
+msgid "Edit with &Vim"
+msgstr "Muokkaa &Vimillä"
+
+#. Now concatenate
+msgid "Edit with existing Vim - "
+msgstr "Muokkaa olemassaolevalla Vimillä - "
+
+msgid "Edits the selected file(s) with Vim"
+msgstr "Muokkaa valittuja tiedostoja Vimillä"
+
+msgid "Error creating process: Check if gvim is in your path!"
+msgstr "Virhe prosessin käynnistämisessä, varmista että gvim on polulla"
+
+msgid "gvimext.dll error"
+msgstr "gvimext.dll-virhe"
+
+msgid "Path length too long!"
+msgstr "Liian pitkä polku"
+
+msgid "--No lines in buffer--"
+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.
+#.
+msgid "E470: Command aborted"
+msgstr "E470: Komento peruttu"
+
+msgid "E471: Argument required"
+msgstr "E471: Argumentti puuttuu"
+
+msgid "E10: \\ should be followed by /, ? or &"
+msgstr "E10: \\:n jälkeen pitää tulla /, ? tai &"
+
+msgid "E11: Invalid in command-line window; <CR> executes, CTRL-C quits"
+msgstr "E11: Virheellinen komentorivi-ikkuna, <CR> suorittaa, Ctrl C lopettaa"
+
+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"
+
+msgid "E171: Missing :endif"
+msgstr "E171: :endif puuttuu"
+
+msgid "E600: Missing :endtry"
+msgstr "E600: :endtry puuttuu"
+
+msgid "E170: Missing :endwhile"
+msgstr "E170: :endwhile puuttuu"
+
+msgid "E170: Missing :endfor"
+msgstr "E170: :endfor puuttuu"
+
+msgid "E588: :endwhile without :while"
+msgstr "E588: :endwhile ilman komentoa :while"
+
+msgid "E588: :endfor without :for"
+msgstr "E588: :endfor ilman komentoa :for"
+
+msgid "E13: File exists (add ! to override)"
+msgstr "E13: Tiedosto on jo olemassa (lisää ! ohittaaksesi)"
+
+msgid "E472: Command failed"
+msgstr "E472: Komento epäonnistui"
+
+#, c-format
+msgid "E234: Unknown fontset: %s"
+msgstr "E234: Tuntematon fontset: %s"
+
+#, c-format
+msgid "E235: Unknown font: %s"
+msgstr "E235: Tuntematon fontti: %s"
+
+#, c-format
+msgid "E236: Font \"%s\" is not fixed-width"
+msgstr "E236: Fontti %s ei ole tasavälinen"
+
+msgid "E473: Internal error"
+msgstr "E473: Sisäinen virhe"
+
+msgid "Interrupted"
+msgstr "Keskeytetty"
+
+msgid "E14: Invalid address"
+msgstr "E14: Virheellinen osoite"
+
+msgid "E474: Invalid argument"
+msgstr "E474: Virheellinen argumentti"
+
+#, c-format
+msgid "E475: Invalid argument: %s"
+msgstr "E475: Virheellinen argumentti: %s"
+
+#, c-format
+msgid "E15: Invalid expression: %s"
+msgstr "E15: Virheellinen ilmaus: %s"
+
+msgid "E16: Invalid range"
+msgstr "E16: Virheellinen arvoalue"
+
+msgid "E476: Invalid command"
+msgstr "E476: Virheellinen komento"
+
+#, c-format
+msgid "E17: \"%s\" is a directory"
+msgstr "E17: %s on hakemisto"
+
+#, c-format
+msgid "E364: Library call failed for \"%s()\""
+msgstr "E364: Kirjastukutsu %s() epäonnistui"
+
+#, c-format
+msgid "E448: Could not load library function %s"
+msgstr "E448: Ei voitu ladta kirjastofunktiota %s"
+
+msgid "E19: Mark has invalid line number"
+msgstr "E19: Merkillä on virheellinen rivinumero"
+
+msgid "E20: Mark not set"
+msgstr "E20: Merkkiä ei asetettu"
+
+msgid "E21: Cannot make changes, 'modifiable' is off"
+msgstr "E21: Ei voi tehdä muutoksia, modifiable on pois päältä"
+
+msgid "E22: Scripts nested too deep"
+msgstr "E22: Liian monta tasoa skripteissä"
+
+msgid "E23: No alternate file"
+msgstr "E23: Eo vaihtoehtoista tiedostoa"
+
+msgid "E24: No such abbreviation"
+msgstr "E24: Lyhennettä ei ole"
+
+msgid "E477: No ! allowed"
+msgstr "E477: ! ei sallittu"
+
+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 "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 "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 "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"
+
+#, c-format
+msgid "E28: No such highlight group name: %s"
+msgstr "E28: Korostusryhmää ei ole nimellä: %s"
+
+msgid "E29: No inserted text yet"
+msgstr "E29: Tekstiä ei ole syötetty vielä"
+
+msgid "E30: No previous command line"
+msgstr "E30: Ei edellistä komentoriviä"
+
+msgid "E31: No such mapping"
+msgstr "E31: Kuvausta ei ole"
+
+msgid "E479: No match"
+msgstr "E479: Ei täsmää"
+
+#, c-format
+msgid "E480: No match: %s"
+msgstr "E480: Ei tsämää: %s"
+
+msgid "E32: No file name"
+msgstr "E32: Ei tiedostonimeä"
+
+msgid "E33: No previous substitute regular expression"
+msgstr "E33: Ei edellistä korvausta säännölliselle ilmaukselle"
+
+msgid "E34: No previous command"
+msgstr "E34: Ei edellistä komentoa"
+
+msgid "E35: No previous regular expression"
+msgstr "E35: Ei edellistä säännöllistä ilmausta"
+
+msgid "E481: No range allowed"
+msgstr "E481: Arvoalue ei sallittu"
+
+msgid "E36: Not enough room"
+msgstr "E36: Tila ei riitä"
+
+#, c-format
+msgid "E247: no registered server named \"%s\""
+msgstr "E247: palvelinta %s ei ole rekisteröitynä"
+
+#, c-format
+msgid "E482: Can't create file %s"
+msgstr "E482: Tiedostoa %s ei voi luoda"
+
+msgid "E483: Can't get temp file name"
+msgstr "E483: väliaikaistiedoston nimeä ei saada selville"
+
+#, c-format
+msgid "E484: Can't open file %s"
+msgstr "E484: Ei voi avata tiedostoa %s"
+
+#, c-format
+msgid "E485: Can't read file %s"
+msgstr "E485: Ei voi lukea tiedostoa %s"
+
+msgid "E37: No write since last change (add ! to override)"
+msgstr ""
+"E37: Viimeisen muutoksen jälkeen ei ole kirjoitettu (lisää ! ohittaaksesi)"
+
+msgid "E38: Null argument"
+msgstr "E38: Null-argumentti"
+
+msgid "E39: Number expected"
+msgstr "E39: Pitää olla numero"
+
+#, c-format
+msgid "E40: Can't open errorfile %s"
+msgstr "E40: virhetiedostoa %s ei voi avata"
+
+msgid "E233: cannot open display"
+msgstr "E233: näyttöä ei voi avata"
+
+msgid "E41: Out of memory!"
+msgstr "E41: Muisti loppui"
+
+msgid "Pattern not found"
+msgstr "Kuviota ei löydy"
+
+#, c-format
+msgid "E486: Pattern not found: %s"
+msgstr "E486: Kuviota ei löydy: %s"
+
+msgid "E487: Argument must be positive"
+msgstr "E487: Argumentin pitää olla positiivinen"
+
+msgid "E459: Cannot go back to previous directory"
+msgstr "E459: Ei voi siirtyä edelliseen hakemistoon"
+
+# ;-)
+msgid "E42: No Errors"
+msgstr "E42: Ei virheitä"
+
+msgid "E776: No location list"
+msgstr "E776: Ei sijaintilistaa"
+
+msgid "E43: Damaged match string"
+msgstr "E43: Viallinen täsmäysmerkkijono"
+
+msgid "E44: Corrupted regexp program"
+msgstr "E44: Viallinen regexp-ohjelma"
+
+msgid "E45: 'readonly' option is set (add ! to override)"
+msgstr "E45: readonly asetettu (lisää ! ohittaaksesi)"
+
+#, c-format
+msgid "E46: Cannot change read-only variable \"%s\""
+msgstr "E46: Kirjoitussuojattua muuttujaa %s ei voi muuttaa"
+
+#, c-format
+msgid "E794: Cannot set variable in the sandbox: \"%s\""
+msgstr "E794: Muuttujaa ei voi asettaa hiekkalaatikossa: %s"
+
+msgid "E47: Error while reading errorfile"
+msgstr "E47: Virhe virhetiedostoa luettaessa"
+
+msgid "E48: Not allowed in sandbox"
+msgstr "E48: Ei sallittu hiekkalaatikossa"
+
+msgid "E523: Not allowed here"
+msgstr "E523: Ei sallittu täällä"
+
+msgid "E359: Screen mode setting not supported"
+msgstr "E359: Näyttötila-asetus ei tuettu"
+
+msgid "E49: Invalid scroll size"
+msgstr "E49: Virheellinen vierityskoko"
+
+msgid "E91: 'shell' option is empty"
+msgstr "E91: shell-asetus on tyhjä"
+
+msgid "E255: Couldn't read in sign data!"
+msgstr "E255: Merkkidatan luku ei onnistu"
+
+msgid "E72: Close error on swap file"
+msgstr "E72: Swap-tiedoston sulkemisvirhe"
+
+msgid "E73: tag stack empty"
+msgstr "E73: tägipino tyhjä"
+
+msgid "E74: Command too complex"
+msgstr "E74: Liian monimutkainen komento"
+
+msgid "E75: Name too long"
+msgstr "E75: Liian pitkä nimi"
+
+msgid "E76: Too many ["
+msgstr "E76: Liian monta [:a"
+
+msgid "E77: Too many file names"
+msgstr "E77: Liikaa tiedostonimiä"
+
+msgid "E488: Trailing characters"
+msgstr "E488: Ylimääräisiä merkkejä perässä"
+
+msgid "E78: Unknown mark"
+msgstr "E78: Tuntematon merkki"
+
+msgid "E79: Cannot expand wildcards"
+msgstr "E79: Jokerimerkkien avaus ei onnistu"
+
+msgid "E591: 'winheight' cannot be smaller than 'winminheight'"
+msgstr "E591: winheight ei voi olla pienempi kuin winminheight"
+
+msgid "E592: 'winwidth' cannot be smaller than 'winminwidth'"
+msgstr "E592: winwidth ei voi olla pienempi kuin winminwidth"
+
+msgid "E80: Error while writing"
+msgstr "E80: Kirjoitusvirhe"
+
+msgid "Zero count"
+msgstr "Nollalaskuri"
+
+msgid "E81: Using <SID> not in a script context"
+msgstr "E81: <SID> skriptin ulkopuolella"
+
+msgid "E449: Invalid expression received"
+msgstr "E449: Virheellinen ilmaus saatu"
+
+msgid "E463: Region is guarded, cannot modify"
+msgstr "E463: Alue on suojattu, muuttaminen ei onnistu"
+
+msgid "E744: NetBeans does not allow changes in read-only files"
+msgstr "E744: NetBeans ei tue muutoksia kirjoitussuojattuihin tiedostoihin"
+
+#, c-format
+msgid "E685: Internal error: %s"
+msgstr "E685: Sisäinen virhe: %s"
+
+msgid "E363: pattern uses more memory than 'maxmempattern'"
+msgstr "E363: kuvio käyttää enemmän muistia kuin maxmempattern on"
+
+msgid "E749: empty buffer"
+msgstr "E749: tyhjä puskuri"
+
+msgid "E682: Invalid search pattern or delimiter"
+msgstr "E682: Virheellinen hakulauseke tai erotin"
+
+msgid "E139: File is loaded in another buffer"
+msgstr "E139: Tiedosto on ladattu toiseen puskuriin"
+
+#, c-format
+msgid "E764: Option '%s' is not set"
+msgstr "E764: Asetus %s on asettamatta"
+
+msgid "search hit TOP, continuing at BOTTOM"
+msgstr "haku pääsi ALKUUN, jatketaan LOPUSTA"
+
+msgid "search hit BOTTOM, continuing at TOP"
+msgstr "haku pääsi LOPPUUN, jatketaan ALUSTA"
+
+#, c-format
+msgid "Need encryption key for \"%s\""
+msgstr "Tarvitaan salausavain kohteelle %s "
+
+msgid "writelines() requires list of strings"
+msgstr "writelines()-komennolle pitää antaa merkkijonolista"
+
+msgid "E264: Python: Error initialising I/O objects"
+msgstr "E264: Python: Virhe IO-olioiden alustuksessa"
+
+msgid "no such buffer"
+msgstr "puskuria ei ole"
+
+msgid "attempt to refer to deleted window"
+msgstr "yritettiin viitata poistettuun ikkunaan"
+
+msgid "readonly attribute"
+msgstr "kirjoitussuojattu attribuutti"
+
+msgid "cursor position outside buffer"
+msgstr "kursorin sijainti puskurin ulkopuolella"
+
+#, c-format
+msgid "<window object (deleted) at %p>"
+msgstr "<ikkunaolio (poistettu) kohdassa %p>"
+
+#, c-format
+msgid "<window object (unknown) at %p>"
+msgstr "<ikkunaolio (tuntematon) kohdassa %p>"
+
+#, c-format
+msgid "<window %d>"
+msgstr "<ikkuna %d>"
+
+msgid "no such window"
+msgstr "ikkunaa ei ole"
+
+msgid "attempt to refer to deleted buffer"
+msgstr "yritettiin viitata poistettuun puskuriin"
+
+# New Line eli uusi rivinvaihtomerkki (ei CR, LF tai CR LF)
+#~ msgid "[NL found]"
+#~ msgstr "[NL puuttuu]"
+
+#~ msgid "Vim dialog..."
+#~ msgstr "Vim-ikkuna..."
+
+#~ msgid "Font Selection"
+#~ msgstr "Fontin valinta"
+
+#~ msgid "E569: maximum number of cscope connections reached"
+#~ msgstr "E569: enimmäismäärä cscope-yhteyksiä otettu"
+
+#~ msgid "-name <name>\t\tUse resource as if vim was <name>"
+#~ msgstr "-name <nimi>\t\tKäytä resurssia vim <nimenä>"
+
+#~ msgid "\t\t\t (Unimplemented)\n"
+#~ msgstr "\t\t\t (toteuttamatta)\n"
+
+#~ msgid "E290: over-the-spot style requires fontset"
+#~ msgstr "E290: over-the-spot-tyylissä pitää olla fontset"
+
+#~ 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 "E292: Input Method Server is not running"
+#~ msgstr "E292: Syötemetodipalvelin ei ole käynnissä"
+
+#~ msgid "E396: containedin argument not accepted here"
+#~ msgstr "E396: containedin ei sovi tähän"
+
+#~ msgid "with GTK-GNOME GUI."
+#~ msgstr "GTK-Gnome-GUIlla."
+
+#~ msgid "with GTK GUI."
+#~ msgstr "GTK-GUIlla."
+
+#~ msgid "-V[N]\t\tVerbose level"
+#~ msgstr "-V[N]\t\tMonisanaisuustaso"
+
+#~ msgid "...(truncated)"
+#~ msgstr "...(katkaistu)"
diff --git a/src/po/fr.po b/src/po/fr.po
new file mode 100644
index 0000000000..171b14a77a
--- /dev/null
+++ b/src/po/fr.po
@@ -0,0 +1,7091 @@
+# 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, 2013.
+#
+# Latest translation available at:
+# http://dominique.pelle.free.fr/vim-fr.php
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Vim(Français)\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2013-05-27 04:55+0200\n"
+"PO-Revision-Date: 2013-05-27 10:22+0200\n"
+"Last-Translator: Dominique Pellé <dominique.pelle@gmail.com>\n"
+"Language-Team: \n"
+"Language: fr\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=ISO_8859-15\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+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é"
+
+# DB - TODO : Trouver une traduction valable et attestée pour "location".
+msgid "[Location List]"
+msgstr "[Liste des emplacements]"
+
+msgid "[Quickfix List]"
+msgstr "[Liste Quickfix]"
+
+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.
+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.
+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"
+
+msgid "E515: No buffers were unloaded"
+msgstr "E515: Aucun tampon n'a été déchargé"
+
+msgid "E516: No buffers were deleted"
+msgstr "E516: Aucun tampon n'a été effacé"
+
+msgid "E517: No buffers were wiped out"
+msgstr "E517: Aucun tampon n'a été détruit"
+
+msgid "1 buffer unloaded"
+msgstr "1 tampon a été déchargé"
+
+#, c-format
+msgid "%d buffers unloaded"
+msgstr "%d tampons ont été déchargés"
+
+msgid "1 buffer deleted"
+msgstr "1 tampon a été effacé"
+
+#, c-format
+msgid "%d buffers deleted"
+msgstr "%d tampons ont été effacés"
+
+msgid "1 buffer wiped out"
+msgstr "1 tampon a été détruit"
+
+#, c-format
+msgid "%d buffers wiped out"
+msgstr "%d tampons ont été détruits"
+
+# AB - La version française est meilleure que la version anglaise.
+msgid "E84: No modified buffer found"
+msgstr "E84: Aucun tampon n'est modifié"
+
+#. back where we started, didn't find anything.
+msgid "E85: There is no listed buffer"
+msgstr "E85: Aucun tampon n'est listé"
+
+#, c-format
+msgid "E86: Buffer %ld does not exist"
+msgstr "E86: Le tampon %ld n'existe pas"
+
+# AB - Je ne suis pas sûr que l'on puisse obtenir ce message.
+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.
+msgid "E88: Cannot go before first buffer"
+msgstr "E88: Impossible d'aller avant le premier tampon"
+
+#, c-format
+msgid "E89: No write since last change for buffer %ld (add ! to override)"
+msgstr ""
+"E89: Le tampon %ld n'a pas été enregistré (ajoutez ! pour passer outre)"
+
+msgid "E90: Cannot unload last buffer"
+msgstr "E90: Impossible de décharger le dernier tampon"
+
+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.
+#, c-format
+msgid "E92: Buffer %ld not found"
+msgstr "E92: Le tampon %ld n'existe pas"
+
+# AB - Il faut respecter l'esprit plus que la lettre.
+#, c-format
+msgid "E93: More than one match for %s"
+msgstr "E93: Plusieurs tampons correspondent à %s"
+
+#, c-format
+msgid "E94: No matching buffer for %s"
+msgstr "E94: Aucun tampon ne correspond à %s"
+
+#, c-format
+msgid "line %ld"
+msgstr "ligne %ld"
+
+msgid "E95: Buffer with this name already exists"
+msgstr "E95: Un tampon porte déjà ce nom"
+
+msgid " [Modified]"
+msgstr "[Modifié]"
+
+# AB - "[Inédité]" est plus correct, mais sonne faux.
+msgid "[Not edited]"
+msgstr "[Non édité]"
+
+msgid "[New file]"
+msgstr "[Nouveau fichier]"
+
+msgid "[Read errors]"
+msgstr "[Erreurs de lecture]"
+
+# AB - La version courte, "[RO]", devrait-elle être traduite par "[LS]" ?
+# Il faudrait faire un sondage auprès des utilisateurs francophones.
+msgid "[readonly]"
+msgstr "[lecture-seule]"
+
+#, c-format
+msgid "1 line --%d%%--"
+msgstr "1 ligne --%d%%--"
+
+#, c-format
+msgid "%ld lines --%d%%--"
+msgstr "%ld lignes --%d%%--"
+
+# AB - Faut-il remplacer "sur" par "de" ?
+# DB - Mon avis : oui.
+#, c-format
+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).
+msgid "[No Name]"
+msgstr "[Aucun nom]"
+
+#. must be a help buffer
+msgid "help"
+msgstr "aide"
+
+msgid "[Help]"
+msgstr "[Aide]"
+
+# AB - "Prévisualisation" prend beaucoup de place. "Prévision" est une
+# 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.
+msgid "[Preview]"
+msgstr "[Prévisu]"
+
+msgid "All"
+msgstr "Tout"
+
+msgid "Bot"
+msgstr "Bas"
+
+# AB - Attention, on passe de trois à quatre lettres.
+msgid "Top"
+msgstr "Haut"
+
+msgid ""
+"\n"
+"# Buffer list:\n"
+msgstr ""
+"\n"
+"# Liste des tampons :\n"
+
+msgid "[Scratch]"
+msgstr "[Brouillon]"
+
+msgid ""
+"\n"
+"--- Signs ---"
+msgstr ""
+"\n"
+"--- Symboles ---"
+
+#, c-format
+msgid "Signs for %s:"
+msgstr "Symboles dans %s :"
+
+#, c-format
+msgid " line=%ld id=%d name=%s"
+msgstr " ligne=%ld id=%d nom=%s"
+
+# 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.
+#, c-format
+msgid "E96: Can not diff more than %ld buffers"
+msgstr "E96: Impossible d'utiliser diff sur plus de %ld tampons"
+
+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.
+msgid "E97: Cannot create diffs"
+msgstr "E97: diff ne fonctionne pas"
+
+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"
+
+msgid "E98: Cannot read diff output"
+msgstr "E98: Le fichier intermédiaire produit par diff n'a pu être lu"
+
+msgid "E99: Current buffer is not in diff mode"
+msgstr "E99: Le tampon courant n'est pas en mode diff"
+
+msgid "E793: No other buffer in diff mode is modifiable"
+msgstr "E793: Aucun autre tampon en mode diff n'est modifiable"
+
+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.
+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"
+
+#, c-format
+msgid "E102: Can't find buffer \"%s\""
+msgstr "E102: Le tampon %s est introuvable"
+
+#, c-format
+msgid "E103: Buffer \"%s\" is not in diff mode"
+msgstr "E103: Le tampon %s n'est pas en mode diff"
+
+msgid "E787: Buffer changed unexpectedly"
+msgstr "E787: Le tampon a été modifié inopinément"
+
+# AB - Je cherche une traduction plus concise pour "escape".
+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.
+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.
+msgid "E105: Using :loadkeymap not in a sourced file"
+msgstr "E105: :loadkeymap ne peut être utilisé que dans un script Vim"
+
+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".
+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.
+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)"
+
+msgid " Whole line completion (^L^N^P)"
+msgstr " Complètement de ligne entière (^L^N^P)"
+
+msgid " File name completion (^F^N^P)"
+msgstr " Complètement de nom de fichier (^F^N^P)"
+
+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
+msgid " Path pattern completion (^N^P)"
+msgstr " Complètement global de mot-clé (^N^P)"
+
+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"
+msgid " Dictionary completion (^K^N^P)"
+msgstr " Complètement avec le dictionnaire (^K^N^P)"
+
+# AB - Trouver une meilleure formulation que "selon le".
+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.
+msgid " Command-line completion (^V^N^P)"
+msgstr " Complètement de ligne de commande (^V^N^P)"
+
+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.
+msgid " Omni completion (^O^N^P)"
+msgstr " Complètement selon le type de fichier (Omni) (^O^N^P)"
+
+msgid " Spelling suggestion (s^N^P)"
+msgstr " Suggestion d'orthographe (s^N^P)"
+
+msgid " Keyword Local completion (^N^P)"
+msgstr " Complètement local de mot-clé (^N/^P)"
+
+# AB - Ce texte s'ajoute à la fin d'un des messages de complétion ci-dessus.
+# 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.
+msgid "Hit end of paragraph"
+msgstr "Fin du paragraphe"
+
+msgid "E839: Completion function changed window"
+msgstr "E839: La fonction de complètement a changé la fenêtre"
+
+msgid "E840: Completion function deleted text"
+msgstr "E840: La fonction de complètement a effacé du texte"
+
+msgid "'dictionary' option is empty"
+msgstr "L'option 'dictionary' est vide"
+
+msgid "'thesaurus' option is empty"
+msgstr "L'option 'thesaurus' est vide"
+
+#, c-format
+msgid "Scanning dictionary: %s"
+msgstr "Examen du dictionnaire : %s"
+
+msgid " (insert) Scroll (^E/^Y)"
+msgstr " (insertion) Défilement (^E/^Y)"
+
+msgid " (replace) Scroll (^E/^Y)"
+msgstr " (remplacement) Défilement (^E/^Y)"
+
+#, c-format
+msgid "Scanning: %s"
+msgstr "Examen : %s"
+
+msgid "Scanning tags."
+msgstr "Examen des marqueurs."
+
+# 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.
+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.
+#.
+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.
+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.
+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.
+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.
+#, 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.
+#, c-format
+msgid "match %d"
+msgstr "Correspondance %d"
+
+msgid "E18: Unexpected characters in :let"
+msgstr "E18: Caractères inattendus avant '='"
+
+#, c-format
+msgid "E684: list index out of range: %ld"
+msgstr "E684: index de Liste hors limites : %ld au-delà de la fin"
+
+#, c-format
+msgid "E121: Undefined variable: %s"
+msgstr "E121: Variable non définie : %s"
+
+msgid "E111: Missing ']'"
+msgstr "E111: ']' manquant"
+
+#, c-format
+msgid "E686: Argument of %s must be a List"
+msgstr "E686: L'argument de %s doit être une Liste"
+
+#, 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"
+
+msgid "E713: Cannot use empty key for Dictionary"
+msgstr "E713: Impossible d'utiliser une clé vide dans un Dictionnaire"
+
+msgid "E714: List required"
+msgstr "E714: Liste requise"
+
+msgid "E715: Dictionary required"
+msgstr "E715: Dictionnaire requis"
+
+# DB : Suggestion
+#, c-format
+msgid "E118: Too many arguments for function: %s"
+msgstr "E118: La fonction %s a reçu trop d'arguments"
+
+#, c-format
+msgid "E716: Key not present in Dictionary: %s"
+msgstr "E716: La clé %s n'existe pas dans le Dictionnaire"
+
+#, 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"
+
+msgid "E719: Cannot use [:] with a Dictionary"
+msgstr "E719: Utilisation de [:] impossible avec un Dictionnaire"
+
+#, c-format
+msgid "E734: Wrong variable type for %s="
+msgstr "E734: Type de variable erroné avec %s="
+
+#, c-format
+msgid "E130: Unknown function: %s"
+msgstr "E130: Fonction inconnue : %s"
+
+#, c-format
+msgid "E461: Illegal variable name: %s"
+msgstr "E461: Nom de variable invalide : %s"
+
+# DB - todo : trouver mieux que "destinations".
+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".
+msgid "E688: More targets than List items"
+msgstr "E688: Plus de destinations que d'éléments dans la Liste"
+
+msgid "Double ; in list of variables"
+msgstr "Double ; dans une liste de variables"
+
+#, c-format
+msgid "E738: Can't list variables for %s"
+msgstr "E738: Impossible de lister les variables de %s"
+
+msgid "E689: Can only index a List or Dictionary"
+msgstr "E689: Seul une Liste ou un Dictionnaire peut être indexé"
+
+msgid "E708: [:] must come last"
+msgstr "E708: [:] ne peut être spécifié qu'en dernier"
+
+msgid "E709: [:] requires a List value"
+msgstr "E709: [:] requiert une Liste"
+
+msgid "E710: List value has more items than target"
+msgstr "E710: La Liste a plus d'éléments que la destination"
+
+msgid "E711: List value has not enough items"
+msgstr "E711: La Liste n'a pas assez d'éléments"
+
+msgid "E690: Missing \"in\" after :for"
+msgstr "E690: \"in\" manquant après :for"
+
+#, c-format
+msgid "E107: Missing parentheses: %s"
+msgstr "E107: Parenthèses manquantes : %s"
+
+#, c-format
+msgid "E108: No such variable: \"%s\""
+msgstr "E108: Variable inexistante : %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.
+msgid "E109: Missing ':' after '?'"
+msgstr "E109: Il manque ':' après '?'"
+
+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 Lists"
+msgstr "E692: Opération invalide avec les Listes"
+
+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"
+
+# DB - todo : Traduction valable (et courte) pour Funcref ?
+msgid "E693: Can only compare Funcref with Funcref"
+msgstr "E693: Une Funcref ne peut être comparée qu'à une Funcref"
+
+msgid "E694: Invalid operation for Funcrefs"
+msgstr "E694: Opération invalide avec les Funcrefs"
+
+msgid "E804: Cannot use '%' with Float"
+msgstr "E804: Impossible d'utiliser '%' avec un Flottant"
+
+msgid "E110: Missing ')'"
+msgstr "E110: ')' manquant"
+
+msgid "E695: Cannot index a Funcref"
+msgstr "E695: Impossible d'indexer une Funcref"
+
+# AB - La version française est meilleure que la version anglaise.
+#, c-format
+msgid "E112: Option name missing: %s"
+msgstr "E112: Il manque un nom d'option après %s"
+
+#, c-format
+msgid "E113: Unknown option: %s"
+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".
+#, 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.
+#, c-format
+msgid "E115: Missing quote: %s"
+msgstr "E115: Il manque ' à la fin de %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"
+
+#, 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é \"%s\" dupliquée dans le Dictionnaire"
+
+#, 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 "E724: variable nested too deep for displaying"
+msgstr "E724: variable trop imbriquée pour être affichée"
+
+#, 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"
+
+#, c-format
+msgid "E117: Unknown function: %s"
+msgstr "E117: Fonction inconnue : %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 "E808: Number or Float required"
+msgstr "E808: Nombre ou Flottant requis"
+
+msgid "add() argument"
+msgstr "argument de add()"
+
+msgid "E699: Too many arguments"
+msgstr "E699: Trop d'arguments"
+
+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().
+#.
+#. * 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"
+
+msgid "extend() argument"
+msgstr "argument de extend()"
+
+#, c-format
+msgid "E737: Key already exists: %s"
+msgstr "E737: un mappage existe déjà pour %s"
+
+msgid "map() argument"
+msgstr "argument de map()"
+
+msgid "filter() argument"
+msgstr "argument de filter()"
+
+#, c-format
+msgid "+-%s%3ld lines: "
+msgstr "+-%s%3ld lignes : "
+
+#, c-format
+msgid "E700: Unknown function: %s"
+msgstr "E700: Fonction inconnue : %s"
+
+# 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.
+msgid "called inputrestore() more often than inputsave()"
+msgstr "inputrestore() a été appelé plus de fois qu'inputsave()"
+
+msgid "insert() argument"
+msgstr "argument de insert()"
+
+msgid "E786: Range not allowed"
+msgstr "E786: Les plages ne sont pas autorisées"
+
+msgid "E701: Invalid type for len()"
+msgstr "E701: Type invalide avec len()"
+
+msgid "E726: Stride is zero"
+msgstr "E726: Le pas est nul"
+
+msgid "E727: Start past end"
+msgstr "E727: Début au-delà de la fin"
+
+msgid "<empty>"
+msgstr "<vide>"
+
+# 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.
+#, c-format
+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"
+
+msgid "remove() argument"
+msgstr "argument de remove()"
+
+msgid "E655: Too many symbolic links (cycle?)"
+msgstr "E655: Trop de liens symboliques (cycle ?)"
+
+msgid "reverse() argument"
+msgstr "argument de reverse()"
+
+# 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"
+
+msgid "sort() argument"
+msgstr "argument de sort()"
+
+msgid "E702: Sort compare function failed"
+msgstr "E702: La fonction de comparaison de sort() a échoué"
+
+msgid "(Invalid)"
+msgstr "(Invalide)"
+
+msgid "E677: Error writing temp file"
+msgstr "E677: Erreur lors de l'écriture du fichier temporaire"
+
+msgid "E805: Using a Float as a Number"
+msgstr "E805: Utilisation d'un Flottant comme un Nombre"
+
+msgid "E703: Using a Funcref as a Number"
+msgstr "E703: Utilisation d'une Funcref comme un Nombre"
+
+msgid "E745: Using a List as a Number"
+msgstr "E745: Utilisation d'une Liste comme un Nombre"
+
+msgid "E728: Using a Dictionary as a Number"
+msgstr "E728: Utilisation d'un Dictionnaire comme un Nombre"
+
+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 "E806: using Float as a String"
+msgstr "E806: Utilisation d'un Flottant comme une Chaîne"
+
+# DB : On doit pouvoir trouver nettement mieux que ça.
+#, c-format
+msgid "E706: Variable type mismatch for: %s"
+msgstr "E706: Type de variable incohérent pour %s"
+
+#, c-format
+msgid "E795: Cannot delete variable %s"
+msgstr "E795: Impossible de supprimer la variable %s"
+
+#, 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"
+
+#, 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"
+
+#, c-format
+msgid "E741: Value is locked: %s"
+msgstr "E741: La valeur de %s est verrouillée"
+
+msgid "Unknown"
+msgstr "Inconnu"
+
+#, c-format
+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"
+
+#, 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 "E125: Illegal argument: %s"
+msgstr "E125: Argument invalide : %s"
+
+#, c-format
+msgid "E853: Duplicate argument name: %s"
+msgstr "E853: Nom d'argument dupliqué : %s"
+
+msgid "E126: Missing :endfunction"
+msgstr "E126: Il manque :endfunction"
+
+#, 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"
+
+msgid "E129: Function name required"
+msgstr "E129: Nom de fonction requis"
+
+#, c-format
+msgid "E128: Function name must start with a capital or 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".
+#, 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".
+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\""
+
+# AB - Ce texte fait partie d'un message de débogage.
+#, c-format
+msgid "continuing in %s"
+msgstr "de retour dans %s"
+
+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.
+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 "No old files"
+msgstr "Aucun vieux fichier"
+
+#, c-format
+msgid "<%s>%s%s %d, Hex %02x, Octal %03o"
+msgstr "<%s>%s%s %d, Hexa %02x, Octal %03o"
+
+#, c-format
+msgid "> %d, Hex %04x, Octal %o"
+msgstr "> %d, Hexa %04x, Octal %o"
+
+#, 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.
+msgid "E134: Move lines into themselves"
+msgstr "E134: La destination est dans la plage d'origine"
+
+msgid "1 line moved"
+msgstr "1 ligne déplacée"
+
+#, c-format
+msgid "%ld lines moved"
+msgstr "%ld lignes déplacées"
+
+#, c-format
+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.
+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.
+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().
+#, c-format
+msgid "%sviminfo: %s in line: "
+msgstr "%sviminfo : %s à la ligne "
+
+# AB - La version française est meilleure que la version anglaise.
+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"
+
+# AB - Ce texte fait partie d'un message de débogage.
+# DB - ... dont les valeurs possibles sont les messages
+# qui suivent.
+#, 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.
+msgid " info"
+msgstr " info"
+
+# AB - Ce texte fait partie d'un message de débogage.
+# DB - Voir ci-dessus.
+msgid " marks"
+msgstr " marques"
+
+msgid " oldfiles"
+msgstr " vieux fichiers"
+
+# AB - Ce texte fait partie d'un message de débogage.
+# DB - Voir ci-dessus.
+msgid " FAILED"
+msgstr " ÉCHEC"
+
+# AB - J'espère que la plupart des utilisateurs aura l'idée d'aller vérifier
+# 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
+#, c-format
+msgid "E137: Viminfo file is not writable: %s"
+msgstr "E137: L'écriture dans le fichier %s est interdite"
+
+# 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
+#, 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.
+#, c-format
+msgid "Writing viminfo file \"%s\""
+msgstr "Écriture du fichier viminfo \"%s\""
+
+#. Write the info:
+#, 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.
+msgid ""
+"# You may edit it if you're careful!\n"
+"\n"
+msgstr ""
+"# Vous pouvez l'éditer, mais soyez prudent.\n"
+"\n"
+
+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.
+msgid "Illegal starting char"
+msgstr "Caractère initial non valide"
+
+# 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.
+msgid "Write partial file?"
+msgstr "Perdre une partie du fichier ?"
+
+# AB - La version française est nettement meilleure que la version anglaise.
+msgid "E140: Use ! to write partial buffer"
+msgstr ""
+"E140: Une partie du fichier serait perdue (ajoutez ! pour passer outre)"
+
+#, c-format
+msgid "Overwrite existing file \"%s\"?"
+msgstr "Écraser le fichier %s existant ?"
+
+#, 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.
+#, c-format
+msgid "E768: Swap file exists: %s (:silent! overrides)"
+msgstr "E768: Le fichier d'échange %s existe déjà (:silent! pour passer outre)"
+
+#, c-format
+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.
+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.
+#, c-format
+msgid ""
+"'readonly' option is set for \"%s\".\n"
+"Do you wish to write anyway?"
+msgstr ""
+"L'option 'readonly' est activée pour \"%s\".\n"
+"Voulez-vous tout de même enregistrer ?"
+
+#, 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 ""
+"Les droits du fichier \"%s\" sont restreints à la lecture seule.\n"
+"Il peut être possible de l'écrire tout de même.\n"
+"Tenter ?"
+
+#, 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" ?
+#, c-format
+msgid "E143: Autocommands unexpectedly deleted new buffer %s"
+msgstr "E143: Une autocommande a effacé le nouveau tampon %s"
+
+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û.
+msgid "E145: Shell commands not allowed in rvim"
+msgstr "E145: Les commandes externes sont indisponibles dans rvim"
+
+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"
+
+#, c-format
+msgid "replace with %s (y/n/a/q/l/^E/^Y)?"
+msgstr "remplacer par %s (y/n/a/q/l/^E/^Y)?"
+
+msgid "(Interrupted) "
+msgstr "(Interrompu) "
+
+msgid "1 match"
+msgstr "1 correspondance"
+
+msgid "1 substitution"
+msgstr "1 substitution"
+
+#, c-format
+msgid "%ld matches"
+msgstr "%ld correspondances"
+
+#, c-format
+msgid "%ld substitutions"
+msgstr "%ld substitutions"
+
+msgid " on 1 line"
+msgstr " sur 1 ligne"
+
+#, c-format
+msgid " on %ld lines"
+msgstr " sur %ld lignes"
+
+# AB - Il faut respecter l'esprit plus que la lettre.
+# AB - Ce message devrait contenir une référence à :vglobal.
+msgid "E147: Cannot do :global recursive"
+msgstr "E147: :global ne peut pas exécuter :global"
+
+# AB - Ce message devrait contenir une référence à :vglobal.
+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é.
+#, c-format
+msgid "Pattern found in every line: %s"
+msgstr "Motif trouvé dans toutes les lignes : %s"
+
+#, c-format
+msgid "Pattern not found: %s"
+msgstr "Motif introuvable: %s"
+
+# AB - Ne pas traduire le dollar.
+# AB - Ce message n'est volontairement pas traduit. En effet, il fait partie
+# d'un groupe de trois messages dans viminfo, dont deux ne sont pas soumis
+# à internationalisation. J'attends que les deux autres messages soient
+# traduisibles pour traduire celui-ci.
+# DB - TODO : Qu'en est-il à présent ?
+msgid ""
+"\n"
+"# Last Substitute String:\n"
+"$"
+msgstr ""
+"\n"
+"# Dernières chaînes de substitution :\n"
+"$"
+
+# This message should *so* be E42!
+msgid "E478: Don't panic!"
+msgstr "E478: Pas de panique !"
+
+#, c-format
+msgid "E661: Sorry, no '%s' help for %s"
+msgstr "E661: Désolé, aucune aide en langue '%s' pour %s"
+
+#, c-format
+msgid "E149: Sorry, no help for %s"
+msgstr "E149: Désolé, aucune aide pour %s"
+
+#, c-format
+msgid "Sorry, help file \"%s\" not found"
+msgstr "Désolé, le fichier d'aide \"%s\" est introuvable"
+
+#, c-format
+msgid "E150: Not a directory: %s"
+msgstr "E150: %s n'est pas un répertoire"
+
+# AB - La version anglaise est plus précise, mais trop technique.
+#, c-format
+msgid "E152: Cannot open %s for writing"
+msgstr "E152: Impossible d'écrire %s"
+
+# AB - La version anglaise est plus précise, mais trop technique.
+#, c-format
+msgid "E153: Unable to open %s for reading"
+msgstr "E153: Impossible de lire %s"
+
+#, 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"
+
+# AB - L'étiquette la plus longue fait 27 caractères. Le nom de fichier le plus
+# long fait 12 caractères. Il faudrait donc idéalement faire une
+# traduction de 40 caractères ou moins. Ce qui est loin d'être le cas
+# présent.
+# DB - Suggestion.
+#, c-format
+msgid "E154: Duplicate tag \"%s\" in file %s/%s"
+msgstr "E154: Marqueur \"%s\" dupliqué dans le fichier %s/%s"
+
+# AB - Il faut respecter l'esprit plus que la lettre.
+#, 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.
+msgid "E156: Missing sign name"
+msgstr "E156: Il manque le nom du symbole"
+
+msgid "E612: Too many signs defined"
+msgstr "E612: Trop de symboles sont définis"
+
+# AB - Cette traduction ne me satisfait pas.
+# DB - Suggestion.
+#, c-format
+msgid "E239: Invalid sign text: %s"
+msgstr "E239: Le texte du symbole est invalide : %s"
+
+#, c-format
+msgid "E155: Unknown sign: %s"
+msgstr "E155: Symbole inconnu : %s"
+
+# AB - La version française est meilleure que la version anglaise.
+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.
+#, c-format
+msgid "E158: Invalid buffer name: %s"
+msgstr "E158: Le tampon %s est introuvable"
+
+# AB - Vu le code source, la version française est meilleure que la
+# version anglaise.
+#, c-format
+msgid "E157: Invalid sign ID: %ld"
+msgstr "E157: Le symbole %ld est introuvable"
+
+msgid " (NOT FOUND)"
+msgstr " (INTROUVABLE)"
+
+msgid " (not supported)"
+msgstr " (non supporté)"
+
+msgid "[Deleted]"
+msgstr "[Effacé]"
+
+# AB - La version française de la première phrase ne me satisfait pas.
+# DB - Suggestion.
+msgid "Entering Debug mode. Type \"cont\" to continue."
+msgstr "Mode débogage activé. Tapez \"cont\" pour continuer."
+
+#, c-format
+msgid "line %ld: %s"
+msgstr "ligne %ld : %s"
+
+#, c-format
+msgid "cmd: %s"
+msgstr "cmde : %s"
+
+#, c-format
+msgid "Breakpoint in \"%s%s\" line %ld"
+msgstr "Point d'arrêt dans %s%s ligne %ld"
+
+#, c-format
+msgid "E161: Breakpoint not found: %s"
+msgstr "E161: Le point d'arrêt %s est introuvable"
+
+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.
+#, c-format
+msgid "%3d %s %s line %ld"
+msgstr "%3d %s %s ligne %ld"
+
+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.
+#, 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.
+msgid "Untitled"
+msgstr "(sans titre)"
+
+# AB - Il faut respecter l'esprit plus que la lettre.
+# AB - Ce message est similaire au message E89.
+#, c-format
+msgid "E162: No write since last change for buffer \"%s\""
+msgstr "E162: Le tampon %s n'a pas été enregistré"
+
+msgid "Warning: Entered other buffer unexpectedly (check autocommands)"
+msgstr "Alerte : Entrée inattendue dans un autre tampon (vérifier autocmdes)"
+
+msgid "E163: There is only one file to edit"
+msgstr "E163: Il n'y a qu'un seul fichier à éditer"
+
+msgid "E164: Cannot go before first file"
+msgstr "E164: Impossible d'aller avant le premier fichier"
+
+msgid "E165: Cannot go beyond last file"
+msgstr "E165: Impossible d'aller au-delà du dernier fichier"
+
+#, c-format
+msgid "E666: compiler not supported: %s"
+msgstr "E666: Compilateur %s non supporté"
+
+#, c-format
+msgid "Searching for \"%s\" in \"%s\""
+msgstr "Recherche de \"%s\" dans \"%s\""
+
+#, c-format
+msgid "Searching for \"%s\""
+msgstr "Recherche de \"%s\""
+
+#, c-format
+msgid "not found in 'runtimepath': \"%s\""
+msgstr "introuvable dans 'runtimepath' : \"%s\""
+
+msgid "Source Vim script"
+msgstr "Sourcer un script - Vim"
+
+#, c-format
+msgid "Cannot source a directory: \"%s\""
+msgstr "Impossible de sourcer un répertoire : \"%s\""
+
+#, c-format
+msgid "could not source \"%s\""
+msgstr "impossible de sourcer \"%s\""
+
+#, c-format
+msgid "line %ld: could not source \"%s\""
+msgstr "ligne %ld : impossible de sourcer \"%s\""
+
+#, c-format
+msgid "sourcing \"%s\""
+msgstr "sourcement \"%s\""
+
+#, c-format
+msgid "line %ld: sourcing \"%s\""
+msgstr "ligne %ld : sourcement de \"%s\""
+
+#, c-format
+msgid "finished sourcing %s"
+msgstr "fin du sourcement de %s"
+
+msgid "modeline"
+msgstr "ligne de mode"
+
+msgid "--cmd argument"
+msgstr "argument --cmd"
+
+msgid "-c argument"
+msgstr "argument -c"
+
+msgid "environment variable"
+msgstr "variable d'environnement"
+
+msgid "error handler"
+msgstr "gestionnaire d'erreur"
+
+msgid "W15: Warning: Wrong line separator, ^M may be missing"
+msgstr "W15: Alerte : Séparateur de ligne erroné, ^M possiblement manquant"
+
+msgid "E167: :scriptencoding used outside of a sourced file"
+msgstr "E167: :scriptencoding utilisé en dehors d'un fichier sourcé"
+
+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.
+#, c-format
+msgid "Current %slanguage: \"%s\""
+msgstr "Langue courante pour %s : \"%s\""
+
+#, c-format
+msgid "E197: Cannot set language to \"%s\""
+msgstr "E197: Impossible de choisir la langue \"%s\""
+
+msgid "Entering Ex mode. Type \"visual\" to go to Normal mode."
+msgstr "Mode Ex activé. Tapez \"visual\" pour passer en mode Normal."
+
+msgid "E501: At end-of-file"
+msgstr "E501: À la fin du fichier"
+
+msgid "E169: Command too recursive"
+msgstr "E169: Commande trop récursive"
+
+#, c-format
+msgid "E605: Exception not caught: %s"
+msgstr "E605: Exception non interceptée : %s"
+
+msgid "End of sourced file"
+msgstr "Fin du fichier sourcé"
+
+msgid "End of function"
+msgstr "Fin de la fonction"
+
+msgid "E464: Ambiguous use of user-defined command"
+msgstr "E464: Utilisation ambiguë d'une commande définie par l'utilisateur"
+
+msgid "E492: Not an editor command"
+msgstr "E492: Commande inconnue"
+
+msgid "E493: Backwards range given"
+msgstr "E493: La plage spécifiée est inversée"
+
+msgid "Backwards range given, OK to swap"
+msgstr "La plage spécifiée est inversée, OK pour l'inverser"
+
+msgid "E494: Use w or w>>"
+msgstr "E494: Utilisez w ou w>>"
+
+msgid "E319: Sorry, the command is not available in this version"
+msgstr "E319: Désolé, cette commande n'est pas disponible dans cette version"
+
+msgid "E172: Only one file name allowed"
+msgstr "E172: Un seul nom de fichier autorisé"
+
+msgid "1 more file to edit. Quit anyway?"
+msgstr "Encore 1 fichier à éditer. Quitter tout de même ?"
+
+#, c-format
+msgid "%d more files to edit. Quit anyway?"
+msgstr "Encore %d fichiers à éditer. Quitter tout de même ?"
+
+msgid "E173: 1 more file to edit"
+msgstr "E173: encore 1 fichier à éditer"
+
+#, c-format
+msgid "E173: %ld more files to edit"
+msgstr "E173: encore %ld fichiers à éditer"
+
+msgid "E174: Command already exists: add ! to replace it"
+msgstr "E174: La commande existe déjà : ajoutez ! pour la redéfinir"
+
+msgid ""
+"\n"
+" Name Args Range Complete Definition"
+msgstr ""
+"\n"
+" Nom Args Plage Complet. Définition"
+
+msgid "No user-defined commands found"
+msgstr "Aucune commande définie par l'utilisateur trouvée"
+
+msgid "E175: No attribute specified"
+msgstr "E175: Pas d'attribut spécifié"
+
+msgid "E176: Invalid number of arguments"
+msgstr "E176: Nombre d'arguments invalide"
+
+msgid "E177: Count cannot be specified twice"
+msgstr "E177: Le quantificateur ne peut être spécifié deux fois"
+
+msgid "E178: Invalid default value for count"
+msgstr "E178: La valeur par défaut du quantificateur est invalide"
+
+msgid "E179: argument required for -complete"
+msgstr "E179: argument requis avec -complete"
+
+#, c-format
+msgid "E181: Invalid attribute: %s"
+msgstr "E181: Attribut invalide : %s"
+
+msgid "E182: Invalid command name"
+msgstr "E182: Nom de commande invalide"
+
+msgid "E183: User defined commands must start with an uppercase letter"
+msgstr "E183: Les commandes utilisateur doivent commencer par une majuscule"
+
+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"
+
+#, c-format
+msgid "E184: No such user-defined command: %s"
+msgstr "E184: Aucune commande %s définie par l'utilisateur"
+
+#, c-format
+msgid "E180: Invalid complete value: %s"
+msgstr "E180: Valeur invalide pour \"-complete=\" : %s"
+
+msgid "E468: Completion argument only allowed for custom completion"
+msgstr "E468: Seul le complètement personnalisé accepte un argument"
+
+msgid "E467: Custom completion requires a function argument"
+msgstr "E467: Le complètement personnalisé requiert une fonction en argument"
+
+msgid "unknown"
+msgstr "inconnu"
+
+#, c-format
+msgid "E185: Cannot find color scheme '%s'"
+msgstr "E185: Impossible de trouver le jeu de couleurs '%s'"
+
+msgid "Greetings, Vim user!"
+msgstr "Bienvenue, utilisateur de Vim !"
+
+msgid "E784: Cannot close last tab page"
+msgstr "E784: Impossible de fermer le dernier onglet"
+
+msgid "Already only one tab page"
+msgstr "Il ne reste déjà plus qu'un seul 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"
+
+msgid "No swap file"
+msgstr "Pas de fichier d'échange"
+
+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)"
+
+msgid "E186: No previous directory"
+msgstr "E186: Pas de répertoire précédent"
+
+msgid "E187: Unknown"
+msgstr "E187: Inconnu"
+
+msgid "E465: :winsize requires two number arguments"
+msgstr "E465: :winsize requiert 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.
+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"
+
+msgid "E466: :winpos requires two number arguments"
+msgstr "E466: :winpos requiert deux arguments numériques"
+
+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"
+
+#, c-format
+msgid "E739: Cannot create directory: %s"
+msgstr "E739: Impossible de créer le répertoire \"%s\""
+
+#, c-format
+msgid "E189: \"%s\" exists (add ! to override)"
+msgstr "E189: \"%s\" existe (ajoutez ! pour passer outre)"
+
+#, c-format
+msgid "E190: Cannot open \"%s\" for writing"
+msgstr "E190: Impossible d'ouvrir \"%s\" pour y écrire"
+
+#. set mark
+msgid "E191: Argument must be a letter or forward/backward quote"
+msgstr "E191: L'argument doit être une lettre ou une (contre-)apostrophe"
+
+msgid "E192: Recursive use of :normal too deep"
+msgstr "E192: Appel récursif de :normal trop important"
+
+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 à '#'"
+
+msgid "E495: no autocommand file name to substitute for \"<afile>\""
+msgstr "E495: Aucun nom de ficher d'autocommande à substituer à \"<afile>\""
+
+msgid "E496: no autocommand buffer number to substitute for \"<abuf>\""
+msgstr "E496: Aucun numéro de tampon d'autocommande à substituer à \"<abuf>\""
+
+msgid "E497: no autocommand match name to substitute for \"<amatch>\""
+msgstr "E497: Aucune correspondance d'autocommande à substituer à \"<amatch>\""
+
+msgid "E498: no :source file name to substitute for \"<sfile>\""
+msgstr "E498: Aucun nom de fichier :source à substituer à \"<sfile>\""
+
+msgid "E842: no line number to use for \"<slnum>\""
+msgstr "E842: aucun numéro de ligne à utiliser pour \"<slnum>\""
+
+#, 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\""
+
+msgid "E500: Evaluates to an empty string"
+msgstr "E500: Évalué en une chaîne vide"
+
+msgid "E195: Cannot open viminfo file for reading"
+msgstr "E195: Impossible d'ouvrir le viminfo en lecture"
+
+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
+#, c-format
+msgid "Exception thrown: %s"
+msgstr "Exception émise : %s"
+
+#, c-format
+msgid "Exception finished: %s"
+msgstr "Exception terminée : %s"
+
+#, c-format
+msgid "Exception discarded: %s"
+msgstr "Exception éliminée : %s"
+
+#, c-format
+msgid "%s, line %ld"
+msgstr "%s, ligne %ld"
+
+#. always scroll up, don't overwrite
+#, 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).
+#, c-format
+msgid "%s made pending"
+msgstr "%s mise(s) en attente"
+
+#, c-format
+msgid "%s resumed"
+msgstr "%s ré-émise(s)"
+
+#, c-format
+msgid "%s discarded"
+msgstr "%s éliminée(s)"
+
+msgid "Exception"
+msgstr "Exception"
+
+msgid "Error and interrupt"
+msgstr "Erreur et interruption"
+
+msgid "Error"
+msgstr "Erreur"
+
+#. if (pending & CSTP_INTERRUPT)
+msgid "Interrupt"
+msgstr "Interruption"
+
+msgid "E579: :if nesting too deep"
+msgstr "E579: Imbrication de :if trop importante"
+
+msgid "E580: :endif without :if"
+msgstr "E580: :endif sans :if"
+
+msgid "E581: :else without :if"
+msgstr "E581: :else sans :if"
+
+msgid "E582: :elseif without :if"
+msgstr "E582: :elseif sans :if"
+
+msgid "E583: multiple :else"
+msgstr "E583: Il ne peut y avoir qu'un seul :else"
+
+msgid "E584: :elseif after :else"
+msgstr "E584: :elseif après :else"
+
+msgid "E585: :while/:for nesting too deep"
+msgstr "E585: Imbrication de :while ou :for trop importante"
+
+msgid "E586: :continue without :while or :for"
+msgstr "E586: :continue sans :while ou :for"
+
+msgid "E587: :break without :while or :for"
+msgstr "E587: :break sans :while ou :for"
+
+msgid "E732: Using :endfor with :while"
+msgstr "E732: Utilisation de :endfor avec :while"
+
+msgid "E733: Using :endwhile with :for"
+msgstr "E733: Utilisation de :endwhile avec :for"
+
+msgid "E601: :try nesting too deep"
+msgstr "E601: Imbrication de :try trop importante"
+
+msgid "E603: :catch without :try"
+msgstr "E603: :catch sans :try"
+
+#. Give up for a ":catch" after ":finally" and ignore it.
+#. * Just parse.
+msgid "E604: :catch after :finally"
+msgstr "E604: :catch après :finally"
+
+msgid "E606: :finally without :try"
+msgstr "E606: :finally sans :try"
+
+#. Give up for a multiple ":finally" and ignore it.
+msgid "E607: multiple :finally"
+msgstr "E607: Il ne peut y avoir qu'un seul :finally"
+
+msgid "E602: :endtry without :try"
+msgstr "E602: :endtry sans :try"
+
+msgid "E193: :endfunction not inside a function"
+msgstr "E193: :endfunction en dehors d'une fonction"
+
+msgid "E788: Not allowed to edit another buffer now"
+msgstr "E788: L'édition d'un autre tampon n'est plus permise"
+
+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.
+msgid "tagname"
+msgstr "nom du marqueur"
+
+# DB - TODO : Idem précédent.
+msgid " kind file\n"
+msgstr " type de fichier\n"
+
+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.
+#, c-format
+msgid ""
+"\n"
+"# %s History (newest to oldest):\n"
+msgstr ""
+"\n"
+"# Historique %s (chronologie décroissante) :\n"
+
+msgid "Command Line"
+msgstr "ligne de commande"
+
+msgid "Search String"
+msgstr "chaîne de recherche"
+
+msgid "Expression"
+msgstr "expression"
+
+msgid "Input Line"
+msgstr "ligne de saisie"
+
+msgid "E198: cmd_pchar beyond the command length"
+msgstr "E198: cmd_pchar au-delà de la longueur de la commande"
+
+msgid "E199: Active window or buffer deleted"
+msgstr "E199: Fenêtre ou tampon actif effacé"
+
+msgid "E812: Autocommands changed buffer or buffer name"
+msgstr "E812: Des autocommandes ont changé le tampon ou le nom du tampon"
+
+msgid "Illegal file name"
+msgstr "Nom de fichier invalide"
+
+msgid "is a directory"
+msgstr "est un répertoire"
+
+msgid "is not a file"
+msgstr "n'est pas un fichier"
+
+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]"
+
+msgid "[New DIRECTORY]"
+msgstr "[Nouveau RÉPERTOIRE]"
+
+msgid "[File too big]"
+msgstr "[Fichier trop volumineux]"
+
+msgid "[Permission Denied]"
+msgstr "[Permission refusée]"
+
+msgid "E200: *ReadPre autocommands made the file unreadable"
+msgstr "E200: Les autocommandes *ReadPre ont rendu le fichier illisible"
+
+msgid "E201: *ReadPre autocommands must not change current buffer"
+msgstr ""
+"E201: Autocommandes *ReadPre ne doivent pas modifier le contenu du tampon "
+"courant"
+
+msgid "Vim: Reading from stdin...\n"
+msgstr "Vim : Lecture de stdin...\n"
+
+msgid "Reading from stdin..."
+msgstr "Lecture de stdin..."
+
+#. Re-opening the original file failed!
+msgid "E202: Conversion made file unreadable!"
+msgstr "E202: La conversion a rendu le fichier illisible !"
+
+msgid "[fifo/socket]"
+msgstr "[fifo/socket]"
+
+msgid "[fifo]"
+msgstr "[fifo]"
+
+msgid "[socket]"
+msgstr "[socket]"
+
+msgid "[character special]"
+msgstr "[caractère spécial]"
+
+msgid "[RO]"
+msgstr "[RO]"
+
+msgid "[CR missing]"
+msgstr "[CR manquant]"
+
+msgid "[long lines split]"
+msgstr "[lignes longues coupées]"
+
+msgid "[NOT converted]"
+msgstr "[NON converti]"
+
+msgid "[converted]"
+msgstr "[converti]"
+
+msgid "[blowfish]"
+msgstr "[blowfish]"
+
+msgid "[crypted]"
+msgstr "[chiffré]"
+
+#, c-format
+msgid "[CONVERSION ERROR in line %ld]"
+msgstr "[ERREUR DE CONVERSION à la ligne %ld]"
+
+#, c-format
+msgid "[ILLEGAL BYTE in line %ld]"
+msgstr "[OCTET INVALIDE à la ligne %ld]"
+
+msgid "[READ ERRORS]"
+msgstr "[ERREURS DE LECTURE]"
+
+msgid "Can't find temp file for conversion"
+msgstr "Impossible de générer un fichier temporaire pour la conversion"
+
+msgid "Conversion with 'charconvert' failed"
+msgstr "La conversion avec 'charconvert' a échoué"
+
+# DB : Pas de majuscule ?
+msgid "can't read output of 'charconvert'"
+msgstr "Impossible de lire la sortie de 'charconvert'"
+
+msgid "E821: File is encrypted with unknown method"
+msgstr "E821: Le fichier est chiffré avec une méthode inconnue"
+
+msgid "E676: No matching autocommands for acwrite buffer"
+msgstr "E676: Pas d'autocommande correspondante pour le tampon acwrite"
+
+msgid "E203: Autocommands deleted or unloaded buffer to be written"
+msgstr "E203: Des autocommandes ont effacé ou déchargé le tampon à écrire"
+
+msgid "E204: Autocommand changed number of lines in unexpected way"
+msgstr ""
+"E204: L'autocommande a modifié le nombre de lignes de manière inattendue"
+
+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"
+
+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)"
+
+msgid "E506: Can't write to backup file (add ! to override)"
+msgstr "E506: Impossible d'écrire la copie de secours (! pour passer outre)"
+
+msgid "E507: Close error for backup file (add ! to override)"
+msgstr "E507: Erreur de fermeture de la copie de secours (! pour passer outre)"
+
+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)"
+
+msgid "E509: Cannot create backup file (add ! to override)"
+msgstr ""
+"E509: Impossible de créer la copie de secours (ajoutez ! pour passer outre)"
+
+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)"
+
+msgid "E460: The resource fork would be lost (add ! to override)"
+msgstr ""
+"E460: Les ressources partagées seraient perdues (ajoutez ! pour passer outre)"
+
+msgid "E214: Can't find temp file for writing"
+msgstr "E214: Impossible de générer un fichier temporaire pour y écrire"
+
+msgid "E213: Cannot convert (add ! to write without conversion)"
+msgstr "E213: Impossible de convertir (ajoutez ! pour écrire sans convertir)"
+
+msgid "E166: Can't open linked file for writing"
+msgstr "E166: Impossible d'ouvrir le lien pour y écrire"
+
+msgid "E212: Can't open file for writing"
+msgstr "E212: Impossible d'ouvrir le fichier pour y écrire"
+
+msgid "E667: Fsync failed"
+msgstr "E667: Fsynch a échoué"
+
+msgid "E512: Close failed"
+msgstr "E512: Erreur de fermeture de fichier"
+
+msgid "E513: write error, conversion failed (make 'fenc' empty to override)"
+msgstr ""
+"E513: Erreur d'écriture, échec de conversion (videz 'fenc' pour passer outre)"
+
+#, c-format
+msgid ""
+"E513: write error, conversion failed in line %ld (make 'fenc' empty to "
+"override)"
+msgstr ""
+"E513: Erreur d'écriture, échec de conversion à la ligne %ld (videz 'fenc' "
+"pour passer outre)"
+
+msgid "E514: write error (file system full?)"
+msgstr "E514: erreur d'écriture (système de fichiers plein ?)"
+
+msgid " CONVERSION ERROR"
+msgstr " ERREUR DE CONVERSION"
+
+#, c-format
+msgid " in line %ld;"
+msgstr " à la ligne %ld"
+
+msgid "[Device]"
+msgstr "[Périph.]"
+
+msgid "[New]"
+msgstr "[Nouveau]"
+
+msgid " [a]"
+msgstr " [a]"
+
+msgid " appended"
+msgstr " ajouté(s)"
+
+msgid " [w]"
+msgstr " [e]"
+
+msgid " written"
+msgstr " écrit(s)"
+
+msgid "E205: Patchmode: can't save original file"
+msgstr "E205: Patchmode : impossible d'enregistrer le fichier original"
+
+msgid "E206: patchmode: can't touch empty original file"
+msgstr "E206: patchmode : impossible de créer le fichier original vide"
+
+msgid "E207: Can't delete backup file"
+msgstr "E207: Impossible d'effacer la copie de secours"
+
+msgid ""
+"\n"
+"WARNING: Original file may be lost or damaged\n"
+msgstr ""
+"\n"
+"ALERTE: Le fichier original est peut-être perdu ou endommagé\n"
+
+# DB - todo : un peu long...
+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é !"
+
+msgid "[dos]"
+msgstr "[dos]"
+
+msgid "[dos format]"
+msgstr "[format dos]"
+
+msgid "[mac]"
+msgstr "[mac]"
+
+msgid "[mac format]"
+msgstr "[format mac]"
+
+msgid "[unix]"
+msgstr "[unix]"
+
+msgid "[unix format]"
+msgstr "[format unix]"
+
+msgid "1 line, "
+msgstr "1 ligne, "
+
+#, c-format
+msgid "%ld lines, "
+msgstr "%ld lignes, "
+
+msgid "1 character"
+msgstr "1 caractère"
+
+#, c-format
+msgid "%lld characters"
+msgstr "%lld caractères"
+
+#. Explicit typecast avoids warning on Mac OS X 10.6
+#, c-format
+msgid "%ld characters"
+msgstr "%ld caractères"
+
+msgid "[noeol]"
+msgstr "[noeol]"
+
+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
+msgid "WARNING: The file has been changed since reading it!!!"
+msgstr "ALERTE : Le fichier a été modifié depuis que Vim l'a lu !"
+
+msgid "Do you really want to write to it"
+msgstr "Voulez-vous vraiment écrire dedans"
+
+#, c-format
+msgid "E208: Error writing to \"%s\""
+msgstr "E208: Erreur lors de l'écriture dans \"%s\""
+
+#, c-format
+msgid "E209: Error closing \"%s\""
+msgstr "E209: Erreur lors de la fermeture de \"%s\""
+
+#, c-format
+msgid "E210: Error reading \"%s\""
+msgstr "E210: Erreur lors de la lecture de \"%s\""
+
+msgid "E246: FileChangedShell autocommand deleted buffer"
+msgstr "E246: L'autocommande FileChangedShell a effacé le tampon"
+
+#, 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.
+#, c-format
+msgid ""
+"W12: Warning: File \"%s\" has changed and the buffer was changed in Vim as "
+"well"
+msgstr ""
+"W12: Alerte : Le fichier \"%s\" a été modifié, ainsi que le tampon dans Vim"
+
+msgid "See \":help W12\" for more info."
+msgstr "Consultez \":help W12\" pour plus d'information."
+
+#, 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"
+
+msgid "See \":help W11\" for more info."
+msgstr "Consultez \":help W11\" pour plus d'information."
+
+#, 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"
+
+msgid "See \":help W16\" for more info."
+msgstr "Consultez \":help W16\" pour plus d'information."
+
+#, 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"
+
+msgid "Warning"
+msgstr "Alerte"
+
+msgid ""
+"&OK\n"
+"&Load File"
+msgstr ""
+"&Ok\n"
+"&Charger le fichier"
+
+#, c-format
+msgid "E462: Could not prepare for reloading \"%s\""
+msgstr "E462: Impossible de préparer le rechargement de \"%s\""
+
+#, c-format
+msgid "E321: Could not reload \"%s\""
+msgstr "E321: Impossible de recharger \"%s\""
+
+msgid "--Deleted--"
+msgstr "--Effacé--"
+
+#, c-format
+msgid "auto-removing autocommand: %s <buffer=%d>"
+msgstr "Autocommandes marquées pour auto-suppression : %s <tampon=%d>"
+
+#. the group doesn't exist
+#, c-format
+msgid "E367: No such group: \"%s\""
+msgstr "E367: Aucun groupe \"%s\""
+
+#, c-format
+msgid "E215: Illegal character after *: %s"
+msgstr "E215: Caractère non valide après * : %s"
+
+#, c-format
+msgid "E216: No such event: %s"
+msgstr "E216: Aucun événement %s"
+
+#, c-format
+msgid "E216: No such group or event: %s"
+msgstr "E216: Aucun événement ou groupe %s"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Auto-Commands ---"
+msgstr ""
+"\n"
+"--- Auto-commandes ---"
+
+#, c-format
+msgid "E680: <buffer=%d>: invalid buffer number "
+msgstr "E680: <buffer=%d> : numéro de tampon invalide"
+
+msgid "E217: Can't execute autocommands for ALL events"
+msgstr ""
+"E217: Impossible d'exécuter les autocommandes pour TOUS les événements (ALL)"
+
+msgid "No matching autocommands"
+msgstr "Aucune autocommande correspondante"
+
+msgid "E218: autocommand nesting too deep"
+msgstr "E218: autocommandes trop imbriquées"
+
+#, c-format
+msgid "%s Auto commands for \"%s\""
+msgstr "Autocommandes %s pour \"%s\""
+
+#, c-format
+msgid "Executing %s"
+msgstr "Exécution de %s"
+
+#, c-format
+msgid "autocommand %s"
+msgstr "autocommande %s"
+
+msgid "E219: Missing {."
+msgstr "E219: { manquant."
+
+msgid "E220: Missing }."
+msgstr "E220: } manquant."
+
+msgid "E490: No fold found"
+msgstr "E490: Aucun repli trouvé"
+
+msgid "E350: Cannot create fold with current 'foldmethod'"
+msgstr "E350: Impossible de créer un repli avec la 'foldmethod'e actuelle"
+
+msgid "E351: Cannot delete fold with current 'foldmethod'"
+msgstr "E351: Impossible de supprimer un repli avec la 'foldmethod'e actuelle"
+
+#, c-format
+msgid "+--%3ld lines folded "
+msgstr "+--%3ld lignes repliées "
+
+msgid "E222: Add to read buffer"
+msgstr "E222: Ajout au tampon de lecture"
+
+msgid "E223: recursive mapping"
+msgstr "E223: mappage récursif"
+
+#, c-format
+msgid "E224: global abbreviation already exists for %s"
+msgstr "E224: une abréviation globale existe déjà pour %s"
+
+#, c-format
+msgid "E225: global mapping already exists for %s"
+msgstr "E225: un mappage global existe déjà pour %s"
+
+#, c-format
+msgid "E226: abbreviation already exists for %s"
+msgstr "E226: une abréviation existe déjà pour %s"
+
+#, c-format
+msgid "E227: mapping already exists for %s"
+msgstr "E227: un mappage existe déjà pour %s"
+
+msgid "No abbreviation found"
+msgstr "Aucune abréviation trouvée"
+
+msgid "No mapping found"
+msgstr "Aucun mappage trouvé"
+
+msgid "E228: makemap: Illegal mode"
+msgstr "E228: makemap : mode invalide"
+
+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"
+
+#, c-format
+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"
+
+#, c-format
+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> "
+
+#, c-format
+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"
+
+msgid ""
+"&Yes\n"
+"&No\n"
+"&Cancel"
+msgstr ""
+"&Oui\n"
+"&Non\n"
+"&Annuler"
+
+# 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 :"
+
+#. whole word only button
+msgid "Match whole word only"
+msgstr "Mots entiers seulement"
+
+#. match case button
+msgid "Match case"
+msgstr "Respecter la casse"
+
+msgid "Direction"
+msgstr "Direction"
+
+#. 'Up' and 'Down' buttons
+msgid "Up"
+msgstr "Haut"
+
+msgid "Down"
+msgstr "Bas"
+
+#. 'Find Next' button
+msgid "Find Next"
+msgstr "Suivant"
+
+#. 'Replace' button
+msgid "Replace"
+msgstr "Remplacer"
+
+#. 'Replace All' button
+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"
+msgstr "Fermer"
+
+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"
+
+#, c-format
+msgid "E671: Cannot find window title \"%s\""
+msgstr "E671: Titre de fenêtre \"%s\" introuvable"
+
+#, c-format
+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"
+
+# DB - Les quelques messages qui suivent se retrouvent aussi ici :
+# gui_gtk_x11.c:3170 et suivants.
+# Les libellés changent un peu (majuscule par exemple).
+# La VF tâche de les unifier.
+msgid "Close tab"
+msgstr "Fermer l'onglet"
+
+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.
+#. 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 "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 ?
+#, 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 :"
+
+#, c-format
+msgid "E252: Fontset name: %s"
+msgstr "E252: Nom du jeu de polices : %s"
+
+#, c-format
+msgid "Font '%s' is not fixed-width"
+msgstr "La police '%s' n'a pas une largeur fixe"
+
+#, c-format
+msgid "E253: Fontset name: %s\n"
+msgstr "E253: Nom du jeu de polices : %s\n"
+
+#, c-format
+msgid "Font0: %s\n"
+msgstr "Font0: %s\n"
+
+#, c-format
+msgid "Font1: %s\n"
+msgstr "Font1: %s\n"
+
+#, c-format
+msgid "Font%ld width is not twice that of font0\n"
+msgstr "La largeur de Font%ld n'est pas le double de celle de Font0\n"
+
+#, c-format
+msgid "Font0 width: %ld\n"
+msgstr "Largeur de Font0 : %ld\n"
+
+#, c-format
+msgid ""
+"Font1 width: %ld\n"
+"\n"
+msgstr ""
+"Largeur de Font1 : %ld\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 :"
+
+#. create toggle button
+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 "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.
+msgid "E551: Illegal component"
+msgstr "E551: élément invalide"
+
+msgid "E552: digit expected"
+msgstr "E552: chiffre attendu"
+
+#, c-format
+msgid "Page %d"
+msgstr "Page %d"
+
+msgid "No text to be printed"
+msgstr "Aucun texte à imprimer"
+
+#, c-format
+msgid "Printing page %d (%d%%)"
+msgstr "Impression de la page %d (%d%%)"
+
+#, c-format
+msgid " Copy %d of %d"
+msgstr " Copie %d sur %d"
+
+#, c-format
+msgid "Printed: %s"
+msgstr "Imprimé : %s"
+
+msgid "Printing aborted"
+msgstr "Impression interrompue"
+
+msgid "E455: Error writing to PostScript output file"
+msgstr "E455: Erreur lors de l'écriture du fichier PostScript"
+
+#, c-format
+msgid "E624: Can't open file \"%s\""
+msgstr "E624: Impossible d'ouvrir le fichier \"%s\""
+
+#, c-format
+msgid "E457: Can't read PostScript resource file \"%s\""
+msgstr "E457: Impossible de lire le fichier de ressource PostScript \"%s\""
+
+#, c-format
+msgid "E618: file \"%s\" is not a PostScript resource file"
+msgstr "E618: \"%s\" n'est pas un fichier de ressource PostScript"
+
+#, 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é"
+
+#, c-format
+msgid "E621: \"%s\" resource file has wrong version"
+msgstr "E621: La version du fichier de ressource \"%s\" est erronée"
+
+msgid "E673: Incompatible multi-byte encoding and character set."
+msgstr "E673: Jeu de caractères et encodage multi-octets incompatibles"
+
+msgid "E674: printmbcharset cannot be empty with multi-byte encoding."
+msgstr ""
+"E674: 'printmbcharset' ne peut pas être vide avec un encodage multi-octets"
+
+msgid "E675: No default font specified for multi-byte printing."
+msgstr "E675: Aucune police par défaut pour l'impression multi-octets"
+
+msgid "E324: Can't open PostScript output file"
+msgstr "E324: Impossible d'ouvrir le fichier PostScript de sortie"
+
+#, c-format
+msgid "E456: Can't open file \"%s\""
+msgstr "E456: Impossible d'ouvrir le fichier \"%s\""
+
+msgid "E456: Can't find PostScript resource file \"prolog.ps\""
+msgstr "E456: Le fichier de ressource PostScript \"prolog.ps\" est introuvable"
+
+msgid "E456: Can't find PostScript resource file \"cidfont.ps\""
+msgstr ""
+"E456: Le fichier de ressource PostScript \"cidfont.ps\" est introuvable"
+
+#, c-format
+msgid "E456: Can't find PostScript resource file \"%s.ps\""
+msgstr "E456: Le fichier de ressource PostScript \"%s.ps\" est introuvable"
+
+#, c-format
+msgid "E620: Unable to convert to print encoding \"%s\""
+msgstr "E620: La conversion pour imprimer dans l'encodage \"%s\" a échoué"
+
+msgid "Sending to printer..."
+msgstr "Envoi à l'imprimante..."
+
+msgid "E365: Failed to print PostScript file"
+msgstr "E365: L'impression du fichier PostScript a échoué"
+
+msgid "Print job sent."
+msgstr "Tâche d'impression envoyée."
+
+msgid "Add a new database"
+msgstr "Ajouter une base de données"
+
+msgid "Query for a pattern"
+msgstr "Rechercher un motif"
+
+msgid "Show this message"
+msgstr "Afficher ce message"
+
+msgid "Kill a connection"
+msgstr "Fermer une connexion"
+
+msgid "Reinit all connections"
+msgstr "Réinitialiser toutes les connexions"
+
+msgid "Show connections"
+msgstr "Afficher les connexions"
+
+#, c-format
+msgid "E560: Usage: cs[cope] %s"
+msgstr "E560: Utilisation : cs[cope] %s"
+
+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"
+
+msgid "E562: Usage: cstag <ident>"
+msgstr "E562: Utilisation : cstag <ident>"
+
+msgid "E257: cstag: tag not found"
+msgstr "E257: cstag : marqueur introuvable"
+
+#, c-format
+msgid "E563: stat(%s) error: %d"
+msgstr "E563: Erreur stat(%s) : %d"
+
+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"
+
+#, c-format
+msgid "Added cscope database %s"
+msgstr "Base de données cscope %s ajoutée"
+
+#, c-format
+msgid "E262: error reading cscope connection %ld"
+msgstr "E262: erreur lors de la lecture de la connexion cscope %ld"
+
+msgid "E561: unknown cscope search type"
+msgstr "E561: type de recherche cscope inconnu"
+
+msgid "E566: Could not create cscope pipes"
+msgstr "E566: Impossible de créer les tuyaux (pipes) cscope"
+
+msgid "E622: Could not fork for cscope"
+msgstr "E622: Impossible de forker pour cscope"
+
+msgid "cs_create_connection exec failed"
+msgstr "exec de cs_create_connection a échoué"
+
+msgid "cs_create_connection: fdopen for to_fp failed"
+msgstr "cs_create_connection : fdopen pour to_fp a échoué"
+
+msgid "cs_create_connection: fdopen for fr_fp failed"
+msgstr "cs_create_connection : fdopen pour fr_fp a échoué"
+
+msgid "E623: Could not spawn cscope process"
+msgstr "E623: Impossible d'engendrer le processus cscope"
+
+msgid "E567: no cscope connections"
+msgstr "E567: Aucune connexion cscope"
+
+#, c-format
+msgid "E469: invalid cscopequickfix flag %c for %c"
+msgstr "E469: Drapeau cscopequickfix %c invalide pour %c"
+
+# DB - todo
+#, 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"
+
+msgid "cscope commands:\n"
+msgstr "commandes cscope :\n"
+
+#, c-format
+msgid "%-5s: %s%*s (Usage: %s)"
+msgstr "%-5s: %s%*s (Utilisation : %s)"
+
+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: Trouver les fonctions appelant cette fonction\n"
+" d: Trouver les fonctions appelées par cette fonction\n"
+" e: Trouver ce motif egrep\n"
+" f: Trouver ce fichier\n"
+" g: Trouver cette définition\n"
+" i: Trouver les fichiers qui #incluent ce fichier\n"
+" s: Trouver ce symbole C\n"
+" t: Trouver cette chaîne\n"
+
+#, 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"
+
+#, c-format
+msgid "E261: cscope connection %s not found"
+msgstr "E261: Connexion cscope %s introuvable"
+
+#, c-format
+msgid "cscope connection %s closed"
+msgstr "connexion cscope %s fermée"
+
+#. should not reach here
+msgid "E570: fatal error in cs_manage_matches"
+msgstr "E570: erreur fatale dans cs_manage_matches"
+
+#, c-format
+msgid "Cscope tag: %s"
+msgstr "Marqueur cscope : %s"
+
+msgid ""
+"\n"
+" # line"
+msgstr ""
+"\n"
+" # ligne"
+
+# DB - todo : Faut-il respecter l'alignement ici ?
+msgid "filename / context / line\n"
+msgstr "nom / contexte/ ligne\n"
+
+#, c-format
+msgid "E609: Cscope error: %s"
+msgstr "E609: Erreur cscope : %s"
+
+msgid "All cscope databases reset"
+msgstr "Toutes les bases de données cscope ont été réinitialisées"
+
+msgid "no cscope connections\n"
+msgstr "aucune connexion cscope\n"
+
+msgid " # pid database name prepend path\n"
+msgstr " # pid nom de la base de données chemin\n"
+
+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 "only string keys are allowed"
+msgstr "seule une chaine est autorisée comme clé"
+
+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
+#, c-format
+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é"
+
+#, c-format
+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é"
+
+# 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"
+
+#. This should never happen. Famous last word?
+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 !"
+
+msgid "Unknown option argument"
+msgstr "Option inconnue"
+
+msgid "Too many edit arguments"
+msgstr "Trop d'arguments d'édition"
+
+msgid "Argument missing after"
+msgstr "Argument manquant après"
+
+msgid "Garbage after option argument"
+msgstr "arguments en trop après l'option"
+
+msgid "Too many \"+command\", \"-c command\" or \"--cmd command\" arguments"
+msgstr "Trop d'arguments \"+command\", \"-c command\" ou \"--cmd command\""
+
+msgid "Invalid argument for"
+msgstr "Argument invalide pour"
+
+#, c-format
+msgid "%d files to edit\n"
+msgstr "%d fichiers à éditer\n"
+
+msgid "netbeans is not supported with this GUI\n"
+msgstr "netbeans n'est pas supporté avec cette interface graphique\n"
+
+msgid "This Vim was not compiled with the diff feature."
+msgstr "Ce Vim n'a pas été compilé avec la fonctionnalité diff"
+
+msgid "'-nb' cannot be used: not enabled at compile time\n"
+msgstr "'-nb' ne peut pas être utilisé : désactivé à la compilation\n"
+
+msgid "Attempt to open script file again: \""
+msgstr "Nouvelle tentative pour ouvrir le script : \""
+
+msgid "Cannot open for reading: \""
+msgstr "Impossible d'ouvrir en lecture : \""
+
+msgid "Cannot open for script output: \""
+msgstr "Impossible d'ouvrir pour la sortie script : \""
+
+msgid "Vim: Error: Failure to start gvim from NetBeans\n"
+msgstr "Vim : Erreur : Impossible de démarrer gvim depuis NetBeans\n"
+
+msgid "Vim: Warning: Output is not to a terminal\n"
+msgstr "Vim : Alerte : La sortie ne s'effectue pas sur un terminal\n"
+
+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..
+msgid "pre-vimrc command line"
+msgstr "ligne de commande pre-vimrc"
+
+#, c-format
+msgid "E282: Cannot read from \"%s\""
+msgstr "E282: Impossible de lire \"%s\""
+
+msgid ""
+"\n"
+"More info with: \"vim -h\"\n"
+msgstr ""
+"\n"
+"Plus d'info avec : \"vim -h\"\n"
+
+msgid "[file ..] edit specified file(s)"
+msgstr "[fichier ...] ouvrir le ou les fichiers spécifiés"
+
+msgid "- read text from stdin"
+msgstr "- lire le texte à partir de stdin"
+
+msgid "-t tag edit file where tag is defined"
+msgstr "-t marqueur ouvrir le fichier qui contient le marqueur"
+
+msgid "-q [errorfile] edit file with first error"
+msgstr "-q [fichErr] ouvrir à l'endroit de la première erreur"
+
+msgid ""
+"\n"
+"\n"
+"usage:"
+msgstr ""
+"\n"
+"\n"
+"utilisation :"
+
+msgid " vim [arguments] "
+msgstr " vim [args] "
+
+msgid ""
+"\n"
+" or:"
+msgstr ""
+"\n"
+" ou :"
+
+# 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"
+"Arguments:\n"
+msgstr ""
+"\n"
+"\n"
+"Arguments :\n"
+
+msgid "--\t\t\tOnly file names after this"
+msgstr "--\t\tSeuls des noms de fichier sont spécifiés après ceci"
+
+msgid "--literal\t\tDon't expand wildcards"
+msgstr "--literal\tNe pas développer les métacaractères"
+
+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\")"
+
+msgid "-e\t\t\tEx mode (like \"ex\")"
+msgstr "-e\t\tMode Ex (comme \"ex\")"
+
+msgid "-E\t\t\tImproved Ex mode"
+msgstr "-E\t\t\tMode Ex amélioré"
+
+msgid "-s\t\t\tSilent (batch) mode (only for \"ex\")"
+msgstr "-s\t\tMode silencieux (batch) (seulement pour \"ex\")"
+
+msgid "-d\t\t\tDiff mode (like \"vimdiff\")"
+msgstr "-d\t\tMode diff (comme \"vimdiff\")"
+
+msgid "-y\t\t\tEasy mode (like \"evim\", modeless)"
+msgstr "-y\t\tMode facile (comme \"evim\", vim sans modes)"
+
+msgid "-R\t\t\tReadonly mode (like \"view\")"
+msgstr "-R\t\tMode lecture seule (comme \"view\")"
+
+msgid "-Z\t\t\tRestricted mode (like \"rvim\")"
+msgstr "-Z\t\tMode restreint (comme \"rvim\")"
+
+msgid "-m\t\t\tModifications (writing files) not allowed"
+msgstr "-m\t\tInterdire l'enregistrement des fichiers"
+
+msgid "-M\t\t\tModifications in text not allowed"
+msgstr "-M\t\tInterdire toute modification de texte"
+
+msgid "-b\t\t\tBinary mode"
+msgstr "-b\t\tMode binaire"
+
+msgid "-l\t\t\tLisp mode"
+msgstr "-l\t\tMode lisp"
+
+msgid "-C\t\t\tCompatible with Vi: 'compatible'"
+msgstr "-C\t\tCompatible avec Vi : 'compatible'"
+
+msgid "-N\t\t\tNot fully Vi compatible: 'nocompatible'"
+msgstr "-N\t\tPas totalement compatible avec Vi : 'nocompatible'"
+
+msgid "-V[N][fname]\t\tBe verbose [level N] [log messages to fname]"
+msgstr "-V[N][<fichier>]\tMode verbeux [niveau N] [dans <fichier>]"
+
+msgid "-D\t\t\tDebugging mode"
+msgstr "-D\t\tMode débogage"
+
+msgid "-n\t\t\tNo swap file, use memory only"
+msgstr "-n\t\tNe pas utiliser de fichier d'échange, seulement la mémoire"
+
+msgid "-r\t\t\tList swap files and exit"
+msgstr "-r\t\tLister les fichiers d'échange et quitter"
+
+msgid "-r (with file name)\tRecover crashed session"
+msgstr "-r <fichier>\tRécupérer une session plantée"
+
+msgid "-L\t\t\tSame as -r"
+msgstr "-L\t\tComme -r"
+
+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"
+
+msgid "-H\t\t\tStart in Hebrew mode"
+msgstr "-H\t\tDémarrer en mode hébreu"
+
+msgid "-F\t\t\tStart in Farsi mode"
+msgstr "-F\t\tDémarrer en mode farsi"
+
+msgid "-T <terminal>\tSet terminal type to <terminal>"
+msgstr "-T <term>\tRégler le type du terminal sur <terminal>"
+
+msgid "-u <vimrc>\t\tUse <vimrc> instead of any .vimrc"
+msgstr "-u <vimrc>\tUtiliser <vimrc> au lieu du vimrc habituel"
+
+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"
+
+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)"
+
+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)"
+
+msgid "-O[N]\t\tLike -o but split vertically"
+msgstr "-O[N]\tComme -o, mais partager verticalement"
+
+msgid "+\t\t\tStart at end of file"
+msgstr "+\t\tOuvrir à la fin du fichier"
+
+msgid "+<lnum>\t\tStart at line <lnum>"
+msgstr "+<numL>\tOuvrir le fichier à la ligne <numL>"
+
+msgid "--cmd <command>\tExecute <command> before loading any vimrc file"
+msgstr "--cmd <cmde>\tExécuter <commande> avant de charger les fichiers vimrc"
+
+msgid "-c <command>\t\tExecute <command> after loading the first file"
+msgstr "-c <cmde>\tExécuter <commande> une fois le 1er fichier chargé"
+
+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é"
+
+msgid "-s <scriptin>\tRead Normal mode commands from file <scriptin>"
+msgstr "-s <src>\tLire les commandes du mode Normal à partir du fichier <src>"
+
+msgid "-w <scriptout>\tAppend all typed commands to file <scriptout>"
+msgstr "-w <dest>\tAjouter toutes les commandes tapées dans le fichier <dest>"
+
+msgid "-W <scriptout>\tWrite all typed commands to file <scriptout>"
+msgstr "-W <dest>\tÉcrire toutes les commandes tapées dans le fichier <dest>"
+
+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>"
+
+msgid "-i <viminfo>\t\tUse <viminfo> instead of .viminfo"
+msgstr "-i <viminfo>\t\tUtiliser <viminfo> au lieu du viminfo habituel"
+
+msgid "-h or --help\tPrint Help (this message) and exit"
+msgstr "-h ou --help\t\tAfficher l'aide (ce message) puis quitter"
+
+msgid "--version\t\tPrint version information and exit"
+msgstr "--version\t\tAfficher les informations de version et quitter"
+
+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"
+
+#. Failed to send, abort.
+msgid ": Send failed.\n"
+msgstr " : L'envoi a échoué.\n"
+
+#. Let vim start normally.
+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"
+
+#, c-format
+msgid "E283: No marks matching \"%s\""
+msgstr "E283: Aucune marque ne correspond à \"%s\""
+
+#. Highlight title
+msgid ""
+"\n"
+"mark line col file/text"
+msgstr ""
+"\n"
+"marq ligne col fichier/texte"
+
+#. Highlight title
+msgid ""
+"\n"
+" jump line col file/text"
+msgstr ""
+"\n"
+" saut ligne col fichier/texte"
+
+#. Highlight title
+msgid ""
+"\n"
+"change line col text"
+msgstr ""
+"\n"
+"modif ligne col fichier/texte"
+
+msgid ""
+"\n"
+"# File marks:\n"
+msgstr ""
+"\n"
+"# Marques dans le fichier :\n"
+
+#. Write the jumplist with -'
+msgid ""
+"\n"
+"# Jumplist (newest first):\n"
+msgstr ""
+"\n"
+"# Liste de sauts (le plus récent en premier) :\n"
+
+msgid ""
+"\n"
+"# History of marks within files (newest to oldest):\n"
+msgstr ""
+"\n"
+"# Historique des marques dans les fichiers (les plus récentes en premier) :\n"
+
+msgid "Missing '>'"
+msgstr "'>' manquant"
+
+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 la 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é"
+
+msgid "E294: Seek error in swap file read"
+msgstr "E294: Erreur de positionnement lors de la lecture du fichier d'échange"
+
+msgid "E295: Read error in swap file"
+msgstr "E295: Erreur de lecture dans le fichier d'échange"
+
+msgid "E296: Seek error in swap file write"
+msgstr "E296: Erreur de positionnement lors de l'écriture du fichier d'échange"
+
+msgid "E297: Write error in swap file"
+msgstr "E297: Erreur d'écriture dans le fichier d'échange"
+
+msgid "E300: Swap file already exists (symlink attack?)"
+msgstr "E300: Le fichier d'échange existe déjà (attaque par symlink ?)"
+
+msgid "E298: Didn't get block nr 0?"
+msgstr "E298: Bloc n°0 non récupéré ?"
+
+msgid "E298: Didn't get block nr 1?"
+msgstr "E298: Bloc n°1 non récupéré ?"
+
+msgid "E298: Didn't get block nr 2?"
+msgstr "E298: Bloc n°2 non récupéré ?"
+
+msgid "E843: Error while updating swap file crypt"
+msgstr "E843: Erreur lors de la mise à jour du fichier d'échange crypté"
+
+#. could not (re)open the swap file, what can we do????
+msgid "E301: Oops, lost the swap file!!!"
+msgstr "E301: Oups, le fichier d'échange a disparu !"
+
+msgid "E302: Could not rename swap file"
+msgstr "E302: Impossible de renommer le fichier d'échange"
+
+#, 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"
+
+msgid "E304: ml_upd_block0(): Didn't get block 0??"
+msgstr "E304: ml_upd_block0() : bloc 0 non récupéré ?!"
+
+#, c-format
+msgid "E305: No swap file found for %s"
+msgstr "E305: Aucun fichier d'échange trouvé pour %s"
+
+msgid "Enter number of swap file to use (0 to quit): "
+msgstr "Entrez le numéro du fichier d'échange à utiliser (0 pour quitter) : "
+
+#, c-format
+msgid "E306: Cannot open %s"
+msgstr "E306: Impossible d'ouvrir %s"
+
+msgid "Unable to read block 0 from "
+msgstr "Impossible de lire le bloc 0 de "
+
+msgid ""
+"\n"
+"Maybe no changes were made or Vim did not update the swap file."
+msgstr ""
+"\n"
+"Il est possible qu'aucune modification n'a été faite ou que Vim n'a pas mis "
+"à jour le fichier d'échange."
+
+msgid " cannot be used with this version of Vim.\n"
+msgstr " ne peut pas être utilisé avec cette version de Vim.\n"
+
+msgid "Use Vim version 3.0.\n"
+msgstr "Utilisez Vim version 3.0.\n"
+
+#, 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"
+
+msgid " cannot be used on this computer.\n"
+msgstr " ne peut pas être utilisé sur cet ordinateur.\n"
+
+msgid "The file was created on "
+msgstr "Le fichier a été créé le "
+
+msgid ""
+",\n"
+"or the file has been damaged."
+msgstr ""
+",\n"
+"ou le fichier a été endommagé."
+
+#, 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"
+
+#, c-format
+msgid "Using swap file \"%s\""
+msgstr "Utilisation du fichier d'échange \"%s\""
+
+#, c-format
+msgid "Original file \"%s\""
+msgstr "Fichier original \"%s\""
+
+msgid "E308: Warning: Original file may have been changed"
+msgstr "E308: Alerte : Le fichier original a pu être modifié"
+
+#, 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"
+
+msgid "???MANY LINES MISSING"
+msgstr "???DE NOMBREUSES LIGNES MANQUENT"
+
+msgid "???LINE COUNT WRONG"
+msgstr "???NOMBRE DE LIGNES ERRONÉ"
+
+msgid "???EMPTY BLOCK"
+msgstr "???BLOC VIDE"
+
+msgid "???LINES MISSING"
+msgstr "???LIGNES MANQUANTES"
+
+#, 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 ?)"
+
+msgid "???BLOCK MISSING"
+msgstr "???BLOC MANQUANT"
+
+msgid "??? from here until ???END lines may be messed up"
+msgstr "??? d'ici jusqu'à ???FIN des lignes peuvent être corrompues"
+
+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"
+
+msgid "???END"
+msgstr "???FIN"
+
+msgid "E311: Recovery Interrupted"
+msgstr "E311: Récupération interrompue"
+
+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 ???"
+
+msgid "See \":help E312\" for more information."
+msgstr "Consultez \":help E312\" pour plus d'information."
+
+msgid "Recovery completed. You should check if everything is OK."
+msgstr "Récupération achevée. Vérifiez que tout est correct."
+
+msgid ""
+"\n"
+"(You might want to write out this file under another name\n"
+msgstr ""
+"\n"
+"(Vous voudrez peut-être enregistrer ce fichier sous un autre nom\n"
+
+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)"
+
+msgid "Recovery completed. Buffer contents equals file contents."
+msgstr ""
+"Récupération achevée. Le contenu du tampon est identique au contenu du "
+"fichier."
+
+msgid ""
+"\n"
+"You may want to delete the .swp file now.\n"
+"\n"
+msgstr ""
+"\n"
+"Il est conseillé d'effacer maintenant le fichier .swp.\n"
+"\n"
+
+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"
+
+#. use msg() to start the scrolling properly
+msgid "Swap files found:"
+msgstr "Fichiers d'échange trouvés :"
+
+msgid " In current directory:\n"
+msgstr " Dans le répertoire courant :\n"
+
+msgid " Using specified name:\n"
+msgstr "Utilisant le nom indiqué :\n"
+
+msgid " In directory "
+msgstr " Dans le répertoire "
+
+msgid " -- none --\n"
+msgstr " -- aucun --\n"
+
+msgid " owned by: "
+msgstr " propriété de : "
+
+msgid " dated: "
+msgstr " daté : "
+
+msgid " dated: "
+msgstr " daté : "
+
+msgid " [from Vim version 3.0]"
+msgstr " [de Vim version 3.0]"
+
+msgid " [does not look like a Vim swap file]"
+msgstr " [ne semble pas être un fichier d'échange Vim]"
+
+msgid " file name: "
+msgstr " nom de fichier : "
+
+msgid ""
+"\n"
+" modified: "
+msgstr ""
+"\n"
+" modifié : "
+
+msgid "YES"
+msgstr "OUI"
+
+msgid "no"
+msgstr "non"
+
+msgid ""
+"\n"
+" user name: "
+msgstr ""
+"\n"
+" nom d'utilisateur : "
+
+msgid " host name: "
+msgstr " nom d'hôte : "
+
+msgid ""
+"\n"
+" host name: "
+msgstr ""
+"\n"
+" nom d'hôte : "
+
+msgid ""
+"\n"
+" process ID: "
+msgstr ""
+"\n"
+" processus n° : "
+
+msgid " (still running)"
+msgstr " (en cours d'exécution)"
+
+msgid ""
+"\n"
+" [not usable with this version of Vim]"
+msgstr ""
+"\n"
+" [inutilisable avec cette version de Vim]"
+
+msgid ""
+"\n"
+" [not usable on this computer]"
+msgstr ""
+"\n"
+" [inutilisable sur cet ordinateur]"
+
+msgid " [cannot be read]"
+msgstr " [ne peut être lu]"
+
+msgid " [cannot be opened]"
+msgstr " [ne peut être ouvert]"
+
+msgid "E313: Cannot preserve, there is no swap file"
+msgstr "E313: Préservation impossible, il n'y a pas de fichier d'échange"
+
+msgid "File preserved"
+msgstr "Fichier préservé"
+
+msgid "E314: Preserve failed"
+msgstr "E314: Échec de la préservation"
+
+#, c-format
+msgid "E315: ml_get: invalid lnum: %ld"
+msgstr "E315: ml_get : numéro de ligne invalide : %ld"
+
+#, c-format
+msgid "E316: ml_get: cannot find line %ld"
+msgstr "E316: ml_get : ligne %ld introuvable"
+
+msgid "E317: pointer block id wrong 3"
+msgstr "E317: mauvais id de pointeur de bloc 3"
+
+msgid "stack_idx should be 0"
+msgstr "stack_idx devrait être 0"
+
+msgid "E318: Updated too many blocks?"
+msgstr "E318: Trop de blocs mis à jour ?"
+
+msgid "E317: pointer block id wrong 4"
+msgstr "E317: mauvais id de pointeur de bloc 4"
+
+msgid "deleted block 1?"
+msgstr "bloc 1 effacé ?"
+
+#, c-format
+msgid "E320: Cannot find line %ld"
+msgstr "E320: Ligne %ld introuvable"
+
+msgid "E317: pointer block id wrong"
+msgstr "E317: mauvais id de pointeur de bloc"
+
+msgid "pe_line_count is zero"
+msgstr "pe_line_count vaut zéro"
+
+#, c-format
+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"
+
+#, c-format
+msgid "E323: line count wrong in block %ld"
+msgstr "E323: nombre de lignes erroné dans le bloc %ld"
+
+msgid "Stack size increases"
+msgstr "La taille de la pile s'accroît"
+
+msgid "E317: pointer block id wrong 2"
+msgstr "E317: mauvais id de pointeur de block 2"
+
+#, c-format
+msgid "E773: Symlink loop for \"%s\""
+msgstr "E773: cycle de liens symboliques avec \"%s\""
+
+msgid "E325: ATTENTION"
+msgstr "E325: ATTENTION"
+
+msgid ""
+"\n"
+"Found a swap file by the name \""
+msgstr ""
+"\n"
+"Trouvé un fichier d'échange nommé \""
+
+msgid "While opening file \""
+msgstr "Lors de l'ouverture du fichier \""
+
+msgid " NEWER than swap file!\n"
+msgstr " PLUS RÉCENT que le fichier d'échange !\n"
+
+#. 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."
+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."
+
+msgid " Quit, or continue with caution.\n"
+msgstr " Quittez, ou continuez prudemment.\n"
+
+msgid "(2) An edit session for this file crashed.\n"
+msgstr "(2) Une session d'édition de ce fichier a planté.\n"
+
+msgid " If this is the case, use \":recover\" or \"vim -r "
+msgstr " Si c'est le cas, utilisez \":recover\" ou \"vim -r "
+
+msgid ""
+"\"\n"
+" to recover the changes (see \":help recovery\").\n"
+msgstr ""
+"\"\n"
+" pour récupérer le fichier (voir \":help recovery\").\n"
+
+msgid " If you did this already, delete the swap file \""
+msgstr " Si vous l'avez déjà fait, effacez le fichier d'échange \""
+
+msgid ""
+"\"\n"
+" to avoid this message.\n"
+msgstr ""
+"\"\n"
+" pour éviter ce message.\n"
+
+msgid "Swap file \""
+msgstr "Le fichier d'échange \""
+
+msgid "\" already exists!"
+msgstr "\" existe déjà !"
+
+msgid "VIM - ATTENTION"
+msgstr "VIM - ATTENTION"
+
+msgid "Swap file already exists!"
+msgstr "Un fichier d'échange existe déjà !"
+
+msgid ""
+"&Open Read-Only\n"
+"&Edit anyway\n"
+"&Recover\n"
+"&Quit\n"
+"&Abort"
+msgstr ""
+"&Ouvrir en lecture seule\n"
+"&Editer quand même\n"
+"&Récupérer\n"
+"&Quitter\n"
+"&Abandonner"
+
+msgid ""
+"&Open Read-Only\n"
+"&Edit anyway\n"
+"&Recover\n"
+"&Delete it\n"
+"&Quit\n"
+"&Abort"
+msgstr ""
+"&Ouvrir en lecture seule\n"
+"&Editer quand même\n"
+"&Récupérer\n"
+"Le &supprimer\n"
+"&Quitter\n"
+"&Abandonner"
+
+msgid "E326: Too many swap files found"
+msgstr "E326: Trop de fichiers d'échange trouvés"
+
+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"
+msgid "E328: Menu only exists in another mode"
+msgstr "E328: Le menu n'existe que dans un autre mode"
+
+#, c-format
+msgid "E329: No menu \"%s\""
+msgstr "E329: Aucun menu \"%s\""
+
+#. Only a mnemonic or accelerator is not valid.
+msgid "E792: Empty menu name"
+msgstr "E792: Nom de menu vide"
+
+msgid "E330: Menu path must not lead to a sub-menu"
+msgstr "E330: Le chemin de menu ne doit pas conduire à un sous-menu"
+
+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"
+
+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
+msgid ""
+"\n"
+"--- Menus ---"
+msgstr ""
+"\n"
+"--- Menus ---"
+
+msgid "Tear off this menu"
+msgstr "Détacher ce menu"
+
+msgid "E333: Menu path must lead to a menu item"
+msgstr "E333: Le chemin du menu doit conduire à un élément de menu"
+
+#, c-format
+msgid "E334: Menu not found: %s"
+msgstr "E334: Menu introuvable : %s"
+
+#, c-format
+msgid "E335: Menu not defined for %s mode"
+msgstr "E335: Le menu n'est pas défini pour le mode %s"
+
+msgid "E336: Menu path must lead to a sub-menu"
+msgstr "E336: Le chemin du menu doit conduire à un sous-menu"
+
+msgid "E337: Menu not found - check menu names"
+msgstr "E337: Menu introuvable - vérifiez les noms des menus"
+
+#, c-format
+msgid "Error detected while processing %s:"
+msgstr "Erreur détectée en traitant %s :"
+
+#, c-format
+msgid "line %4ld:"
+msgstr "ligne %4ld :"
+
+#, c-format
+msgid "E354: Invalid register name: '%s'"
+msgstr "E354: Nom de registre invalide : '%s'"
+
+# DB - todo : mettre à jour ?
+msgid "Messages maintainer: Bram Moolenaar <Bram@vim.org>"
+msgstr "Maintenance des messages : Dominique Pellé <dominique.pelle@gmail.com>"
+
+msgid "Interrupt: "
+msgstr "Interruption : "
+
+msgid "Press ENTER or type command to continue"
+msgstr "Appuyez sur ENTRÉE ou tapez une commande pour continuer"
+
+#, c-format
+msgid "%s line %ld"
+msgstr "%s, ligne %ld"
+
+msgid "-- More --"
+msgstr "-- Plus --"
+
+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"
+
+msgid "Question"
+msgstr "Question"
+
+msgid ""
+"&Yes\n"
+"&No"
+msgstr ""
+"&Oui\n"
+"&Non"
+
+msgid ""
+"&Yes\n"
+"&No\n"
+"Save &All\n"
+"&Discard All\n"
+"&Cancel"
+msgstr ""
+"&Oui\n"
+"&Non\n"
+"Tout &enregistrer\n"
+"Tout aban&donner\n"
+"&Annuler"
+
+# 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"
+
+#. TODO: non-GUI file selector here
+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()"
+
+msgid "E807: Expected Float argument for printf()"
+msgstr "E807: printf() attend un argument de type Flottant"
+
+msgid "E767: Too many arguments to printf()"
+msgstr "E767: Trop d'arguments pour printf()"
+
+msgid "W10: Warning: Changing a readonly file"
+msgstr "W10: Alerte : Modification d'un fichier en lecture seule"
+
+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) :"
+
+msgid "Type number and <Enter> (empty cancels): "
+msgstr "Tapez un nombre et <Entrée> (rien annule) :"
+
+msgid "1 more line"
+msgstr "1 ligne en plus"
+
+msgid "1 line less"
+msgstr "1 ligne en moins"
+
+#, c-format
+msgid "%ld more lines"
+msgstr "%ld lignes en plus"
+
+#, c-format
+msgid "%ld fewer lines"
+msgstr "%ld lignes en moins"
+
+msgid " (Interrupted)"
+msgstr " (Interrompu)"
+
+msgid "Beep!"
+msgstr "Bip !"
+
+msgid "Vim: preserving files...\n"
+msgstr "Vim : préservation des fichiers...\n"
+
+#. close all memfiles, without deleting
+msgid "Vim: Finished.\n"
+msgstr "Vim : Fini.\n"
+
+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\""
+
+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 "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 "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'"
+
+msgid "Cannot connect to Netbeans #2"
+msgstr "Impossible de se connecter à Netbeans n°2"
+
+msgid "Cannot connect to Netbeans"
+msgstr "Impossible de se connecter à Netbeans"
+
+#, 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"
+"\""
+
+# DB : message d'un appel à perror().
+msgid "read from Netbeans socket"
+msgstr "read sur la socket Netbeans"
+
+#, 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"
+
+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.
+msgid "Warning: terminal cannot highlight"
+msgstr "Alerte : le terminal ne peut pas surligner"
+
+msgid "E348: No string under cursor"
+msgstr "E348: Aucune chaîne sous le curseur"
+
+msgid "E352: Cannot erase folds with current 'foldmethod'"
+msgstr "E352: Impossible d'effacer des replis avec la 'foldmethod'e actuelle"
+
+msgid "E664: changelist is empty"
+msgstr "E664: La liste des modifications (changelist) est vide"
+
+msgid "E662: At start of changelist"
+msgstr "E662: Au début de la liste des modifications"
+
+msgid "E663: At end of changelist"
+msgstr "E663: À la fin de la liste des modifications"
+
+msgid "Type :quit<Enter> to exit Vim"
+msgstr "tapez :q<Entrée> pour quitter Vim"
+
+#, c-format
+msgid "1 line %sed 1 time"
+msgstr "1 ligne %sée 1 fois"
+
+#, c-format
+msgid "1 line %sed %d times"
+msgstr "1 ligne %sée %d fois"
+
+#, c-format
+msgid "%ld lines %sed 1 time"
+msgstr "%ld lignes %sées 1 fois"
+
+#, c-format
+msgid "%ld lines %sed %d times"
+msgstr "%ld lignes %sées %d fois"
+
+#, c-format
+msgid "%ld lines to indent... "
+msgstr "%ld lignes à indenter... "
+
+msgid "1 line indented "
+msgstr "1 ligne indentée "
+
+#, c-format
+msgid "%ld lines indented "
+msgstr "%ld lignes indentées "
+
+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
+msgid "cannot yank; delete anyway"
+msgstr "impossible de réaliser une copie ; effacer tout de même"
+
+msgid "1 line changed"
+msgstr "1 ligne modifiée"
+
+#, c-format
+msgid "%ld lines changed"
+msgstr "%ld lignes modifiées"
+
+#, c-format
+msgid "freeing %ld lines"
+msgstr "libération de %ld lignes"
+
+msgid "block of 1 line yanked"
+msgstr "bloc de 1 ligne copié"
+
+msgid "1 line yanked"
+msgstr "1 ligne copiée"
+
+#, c-format
+msgid "block of %ld lines yanked"
+msgstr "bloc de %ld lignes copié"
+
+#, c-format
+msgid "%ld lines yanked"
+msgstr "%ld lignes copiées"
+
+#, c-format
+msgid "E353: Nothing in register %s"
+msgstr "E353: Le registre %s est vide"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Registers ---"
+msgstr ""
+"\n"
+"--- Registres ---"
+
+msgid "Illegal register name"
+msgstr "Nom de registre invalide"
+
+msgid ""
+"\n"
+"# Registers:\n"
+msgstr ""
+"\n"
+"# Registres :\n"
+
+#, c-format
+msgid "E574: Unknown register type %d"
+msgstr "E574: Type de registre %d inconnu"
+
+#, c-format
+msgid "%ld Cols; "
+msgstr "%ld Colonnes ; "
+
+#, c-format
+msgid "Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Bytes"
+msgstr ""
+"%s%ld sur %ld Lignes ; %ld sur %ld Mots ; %ld sur %ld Octets sélectionnés"
+
+#, c-format
+msgid ""
+"Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Chars; %ld of %ld "
+"Bytes"
+msgstr ""
+"%s%ld sur %ld Lignes ; %ld sur %ld Mots ; %ld sur %ld Caractères ; %ld sur "
+"%ld octets sélectionnés"
+
+#, c-format
+msgid "Col %s of %s; Line %ld of %ld; Word %ld of %ld; Byte %ld of %ld"
+msgstr ""
+"Colonne %s sur %s ; Ligne %ld sur %ld ; Mot %ld sur %ld ; Octet %ld sur %ld"
+
+#, c-format
+msgid ""
+"Col %s of %s; Line %ld of %ld; Word %ld of %ld; Char %ld of %ld; Byte %ld of "
+"%ld"
+msgstr ""
+"Colonne %s sur %s ; Ligne %ld sur %ld ; Mot %ld sur %ld ; Caractère %ld sur "
+"%ld ; Octet %ld sur %ld"
+
+#, c-format
+msgid "(+%ld for BOM)"
+msgstr "(+%ld pour le BOM)"
+
+msgid "%<%f%h%m%=Page %N"
+msgstr "%<%f%h%m%=Page %N"
+
+msgid "Thanks for flying Vim"
+msgstr "Merci d'avoir choisi Vim"
+
+msgid "E518: Unknown option"
+msgstr "E518: Option inconnue"
+
+msgid "E519: Option not supported"
+msgstr "E519: Option non supportée"
+
+msgid "E520: Not allowed in a modeline"
+msgstr "E520: Non autorisé dans une ligne de mode"
+
+msgid "E846: Key code not set"
+msgstr "E846: Le code de touche n'est pas configuré"
+
+msgid "E521: Number required after ="
+msgstr "E521: Nombre requis après ="
+
+msgid "E522: Not found in termcap"
+msgstr "E522: Introuvable dans termcap"
+
+#, c-format
+msgid "E539: Illegal character <%s>"
+msgstr "E539: Caractère <%s> invalide"
+
+msgid "E529: Cannot set 'term' to empty string"
+msgstr "E529: 'term' ne doit pas être une chaîne vide"
+
+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"
+
+msgid "E834: Conflicts with value of 'listchars'"
+msgstr "E834: Conflits avec la valeur de 'listchars'"
+
+msgid "E835: Conflicts with value of 'fillchars'"
+msgstr "E835: Conflits avec la valeur de 'fillchars'"
+
+msgid "E617: Cannot be changed in the GTK+ 2 GUI"
+msgstr "E617: Non modifiable dans l'interface graphique GTK+ 2"
+
+msgid "E524: Missing colon"
+msgstr "E524: ':' manquant"
+
+msgid "E525: Zero length string"
+msgstr "E525: Chaîne de longueur nulle"
+
+#, c-format
+msgid "E526: Missing number after <%s>"
+msgstr "E526: Nombre manquant après <%s>"
+
+msgid "E527: Missing comma"
+msgstr "E527: Virgule manquante"
+
+msgid "E528: Must specify a ' value"
+msgstr "E528: Une valeur ' doit être spécifiée"
+
+msgid "E595: contains unprintable or wide character"
+msgstr "E595: contient des caractères à largeur double non-imprimables"
+
+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>"
+
+msgid "E536: comma required"
+msgstr "E536: virgule requise"
+
+#, 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.
+msgid "E540: Unclosed expression sequence"
+msgstr "E540: '}' manquant"
+
+msgid "E541: too many items"
+msgstr "E541: trop d'éléments"
+
+msgid "E542: unbalanced groups"
+msgstr "E542: parenthèses non équilibrées"
+
+msgid "E590: A preview window already exists"
+msgstr "E590: Il existe déjà une fenêtre de prévisualisation"
+
+msgid "W17: Arabic requires UTF-8, do ':set encoding=utf-8'"
+msgstr "W17: L'arabe requiert l'UTF-8, tapez ':set encoding=utf-8'"
+
+#, c-format
+msgid "E593: Need at least %d lines"
+msgstr "E593: Au moins %d lignes sont nécessaires"
+
+#, c-format
+msgid "E594: Need at least %d columns"
+msgstr "E594: Au moins %d colonnes sont nécessaires"
+
+#, 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.
+#, c-format
+msgid "E521: Number required: &%s = '%s'"
+msgstr "E521: Nombre requis : &%s = '%s'"
+
+msgid ""
+"\n"
+"--- Terminal codes ---"
+msgstr ""
+"\n"
+"--- Codes de terminal ---"
+
+msgid ""
+"\n"
+"--- Global option values ---"
+msgstr ""
+"\n"
+"--- Valeur des options globales ---"
+
+msgid ""
+"\n"
+"--- Local option values ---"
+msgstr ""
+"\n"
+"--- Valeur des options locales ---"
+
+msgid ""
+"\n"
+"--- Options ---"
+msgstr ""
+"\n"
+"--- Options ---"
+
+msgid "E356: get_varp ERROR"
+msgstr "E356: ERREUR get_varp"
+
+#, c-format
+msgid "E357: 'langmap': Matching character missing for %s"
+msgstr "E357: 'langmap' : Aucun caractère correspondant pour %s"
+
+#, c-format
+msgid "E358: 'langmap': Extra characters after semicolon: %s"
+msgstr "E358: 'langmap' : Caractères surnuméraires après point-virgule : %s"
+
+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"
+
+#. if Vim opened a window: Executing a shell may cause crashes
+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 "'columns' is not 80, cannot execute external commands"
+msgstr "'columns' ne vaut pas 80, impossible d'exécuter des commandes externes"
+
+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 "E245: Illegal char '%c' in font name \"%s\""
+msgstr "E245: Caractère '%c' invalide dans le nom de fonte \"%s\""
+
+msgid "Vim: Double signal, exiting\n"
+msgstr "Vim : Double signal, sortie\n"
+
+#, c-format
+msgid "Vim: Caught deadly signal %s\n"
+msgstr "Vim : Signal mortel %s intercepté\n"
+
+#, c-format
+msgid "Vim: Caught deadly signal\n"
+msgstr "Vim : Signal mortel intercepté\n"
+
+#, c-format
+msgid "Opening the X display took %ld msec"
+msgstr "L'ouverture du display X a pris %ld ms"
+
+msgid ""
+"\n"
+"Vim: Got X error\n"
+msgstr ""
+"\n"
+"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 "
+
+msgid ""
+"\n"
+"Cannot execute shell "
+msgstr ""
+"\n"
+"Impossible d'exécuter le shell "
+
+msgid ""
+"\n"
+"Cannot execute shell sh\n"
+msgstr ""
+"\n"
+"Impossible d'exécuter le shell sh\n"
+
+msgid ""
+"\n"
+"shell returned "
+msgstr ""
+"\n"
+"le shell a retourné "
+
+msgid ""
+"\n"
+"Cannot create pipes\n"
+msgstr ""
+"\n"
+"Impossible de créer des tuyaux (pipes)\n"
+
+msgid ""
+"\n"
+"Cannot fork\n"
+msgstr ""
+"\n"
+"Impossible de forker\n"
+
+msgid ""
+"\n"
+"Command terminated\n"
+msgstr ""
+"\n"
+"Commande interrompue\n"
+
+msgid "XSMP lost ICE connection"
+msgstr "XSMP a perdu la connexion ICE"
+
+#, c-format
+msgid "dlerror = \"%s\""
+msgstr "dlerror = \"%s\""
+
+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 "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 !"
+
+#, c-format
+msgid "shell returned %d"
+msgstr "le shell a retourné %d"
+
+# 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"
+"Voir :help win32-vimrun pour plus d'informations."
+
+msgid "Vim Warning"
+msgstr "Alerte Vim"
+
+#, c-format
+msgid "E372: Too many %%%c in format string"
+msgstr "E372: Trop de %%%c dans la chaîne de format"
+
+#, c-format
+msgid "E373: Unexpected %%%c in format string"
+msgstr "E373: %%%c inattendu dans la chaîne de format"
+
+msgid "E374: Missing ] in format string"
+msgstr "E374: ] manquant dans la chaîne de format"
+
+#, c-format
+msgid "E375: Unsupported %%%c in format string"
+msgstr "E375: %%%c non supporté dans la chaîne de format"
+
+#, c-format
+msgid "E376: Invalid %%%c in format string prefix"
+msgstr "E376: %%%c invalide dans le préfixe de la chaîne de format"
+
+#, c-format
+msgid "E377: Invalid %%%c in format string"
+msgstr "E377: %%%c invalide dans la chaîne de format"
+
+msgid "E378: 'errorformat' contains no pattern"
+msgstr "E378: 'errorformat' ne contient aucun motif"
+
+msgid "E379: Missing or empty directory name"
+msgstr "E379: Nom de répertoire vide ou absent"
+
+msgid "E553: No more items"
+msgstr "E553: Plus d'éléments"
+
+#, c-format
+msgid "(%d of %d)%s%s: "
+msgstr "(%d sur %d)%s%s : "
+
+msgid " (line deleted)"
+msgstr " (ligne effacée)"
+
+msgid "E380: At bottom of quickfix stack"
+msgstr "E380: En bas de la pile quickfix"
+
+msgid "E381: At top of quickfix stack"
+msgstr "E381: Au sommet de la pile quickfix"
+
+#, c-format
+msgid "error list %d of %d; %d errors"
+msgstr "liste d'erreurs %d sur %d ; %d erreurs"
+
+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"
+
+msgid "E683: File name missing or invalid pattern"
+msgstr "E683: Nom de fichier manquant ou motif invalide"
+
+#, c-format
+msgid "Cannot open file \"%s\""
+msgstr "Impossible d'ouvrir le fichier \"%s\""
+
+msgid "E681: Buffer is not loaded"
+msgstr "E681: le tampon n'est pas chargé"
+
+msgid "E777: String or List expected"
+msgstr "E777: Chaîne ou Liste attendue"
+
+#, c-format
+msgid "E369: invalid item in %s%%[]"
+msgstr "E369: élément invalide dans %s%%[]"
+
+#, c-format
+msgid "E769: Missing ] after %s["
+msgstr "E769: ']' manquant après %s["
+
+#, c-format
+msgid "E53: Unmatched %s%%("
+msgstr "E53: Pas de correspondance pour %s%%("
+
+#, c-format
+msgid "E54: Unmatched %s("
+msgstr "E54: %s( ouvrante non fermée"
+
+#, c-format
+msgid "E55: Unmatched %s)"
+msgstr "E55: %s) fermante non ouverte"
+
+msgid "E339: Pattern too long"
+msgstr "E339: Motif trop long"
+
+msgid "E50: Too many \\z("
+msgstr "E50: Trop de \\z("
+
+#, c-format
+msgid "E51: Too many %s("
+msgstr "E51: Trop de %s("
+
+msgid "E52: Unmatched \\z("
+msgstr "E52: Pas de correspondance pour \\z("
+
+#, c-format
+msgid "E59: invalid character after %s@"
+msgstr "E59: caractère invalide après %s@"
+
+#, c-format
+msgid "E60: Too many complex %s{...}s"
+msgstr "E60: Trop de %s{...}s complexes"
+
+#, c-format
+msgid "E61: Nested %s*"
+msgstr "E61: %s* imbriqués"
+
+#, c-format
+msgid "E62: Nested %s%c"
+msgstr "E62: %s%c imbriqués"
+
+msgid "E63: invalid use of \\_"
+msgstr "E63: utilisation invalide de \\_"
+
+#, c-format
+msgid "E64: %s%c follows nothing"
+msgstr "E64: %s%c ne suit aucun atome"
+
+msgid "E65: Illegal back reference"
+msgstr "E65: post-référence invalide"
+
+msgid "E66: \\z( not allowed here"
+msgstr "E66: \\z( n'est pas autorisé ici"
+
+msgid "E67: \\z1 et al. not allowed here"
+msgstr "E67: \\z1 et co. ne sont pas autorisés ici"
+
+msgid "E68: Invalid character after \\z"
+msgstr "E68: Caractère invalide après \\z"
+
+#, c-format
+msgid "E69: Missing ] after %s%%["
+msgstr "E69: ']' manquant après %s%%["
+
+#, c-format
+msgid "E70: Empty %s%%[]"
+msgstr "E70: %s%%[] vide"
+
+#, c-format
+msgid "E678: Invalid character after %s%%[dxouU]"
+msgstr "E678: Caractère invalide après %s%%[dxouU]"
+
+#, c-format
+msgid "E71: Invalid character after %s%%"
+msgstr "E71: Caractère invalide après %s%%"
+
+#, c-format
+msgid "E554: Syntax error in %s{...}"
+msgstr "E554: Erreur de syntaxe dans %s{...}"
+
+msgid "External submatches:\n"
+msgstr "Sous-correspondances externes :\n"
+
+msgid ""
+"E864: \\%#= can only be followed by 0, 1, or 2. The automatic engine will be "
+"used "
+msgstr ""
+"E864: \\%#= peut être suivi uniquement de 0, 1 ou 2. Le moteur automatique "
+"sera utilisé "
+
+#, c-format
+msgid "E866: (NFA regexp) Misplaced %c"
+msgstr "E866: (regexp NFA) %c au mauvais endroit"
+
+msgid "E865: (NFA) Regexp end encountered prematurely"
+msgstr "E865: (NFA) Fin de regexp rencontrée prématurément"
+
+#, c-format
+msgid "E867: (NFA) Unknown operator '\\z%c'"
+msgstr "E867: (NFA) Opérateur inconnu '\\z%c'"
+
+#. should never happen
+msgid "E868: Error building NFA with equivalence class!"
+msgstr "E868: Erreur lors de la construction du NFA avec classe d'équivalence"
+
+#, c-format
+msgid "E869: (NFA) Unknown operator '\\@%c'"
+msgstr "E869: (NFA) Opérateur inconnu '\\@%c'"
+
+msgid "E870: (NFA regexp) Error reading repetition limits"
+msgstr "E870: (regexp NFA) Erreur à la lecture des limites de répétition"
+
+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 "E872: (NFA regexp) Too many '('"
+msgstr "E872: (regexp NFA) Trop de '('"
+
+msgid "E873: (NFA regexp) proper termination error"
+msgstr "E873: (NFA regexp) erreur de terminaison"
+
+msgid "E874: (NFA) Could not pop the stack !"
+msgstr "E874: (NFA) Impossible de dépiler !"
+
+msgid ""
+"E875: (NFA regexp) (While converting from postfix to NFA), too many states "
+"left on stack"
+msgstr ""
+"E875: (regexp NFA) (lors de la conversion de postfix à NFA), il reste trop "
+"d'états sur la pile"
+
+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"
+
+msgid "E999: (NFA regexp internal error) Should not process NOT node !"
+msgstr ""
+"E999: (erreur interne du regexp NFA) Un noeud 'NOT' ne devrait pas être "
+"traité !"
+
+#. should not be here :P
+msgid "E877: (NFA regexp) Invalid character class "
+msgstr "E877: (regexp NFA) Classe de caractère invalide "
+
+#, c-format
+msgid "(NFA) COULD NOT OPEN %s !"
+msgstr "(NFA) IMPOSSIBLE D'OUVRIR %s !"
+
+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 "E878: (NFA) Could not allocate memory for branch traversal!"
+msgstr ""
+"E878: (NFA) Impossible d'allouer la mémoire pour parcourir les branches!"
+
+msgid "Could not open temporary log file for writing "
+msgstr "Impossible d'ouvrir le fichier de log en écriture"
+
+msgid " VREPLACE"
+msgstr " VREMPLACEMENT"
+
+msgid " REPLACE"
+msgstr " REMPLACEMENT"
+
+# DB - todo
+msgid " REVERSE"
+msgstr " REVERSE"
+
+msgid " INSERT"
+msgstr " INSERTION"
+
+msgid " (insert)"
+msgstr " (insertion)"
+
+msgid " (replace)"
+msgstr " (remplacement)"
+
+msgid " (vreplace)"
+msgstr " (vremplacement)"
+
+msgid " Hebrew"
+msgstr " hébreu"
+
+msgid " Arabic"
+msgstr " arabe"
+
+msgid " (lang)"
+msgstr " (langue)"
+
+msgid " (paste)"
+msgstr " (collage)"
+
+msgid " VISUAL"
+msgstr " VISUEL"
+
+msgid " VISUAL LINE"
+msgstr " VISUEL LIGNE"
+
+msgid " VISUAL BLOCK"
+msgstr " VISUEL BLOC"
+
+msgid " SELECT"
+msgstr " SÉLECTION"
+
+msgid " SELECT LINE"
+msgstr " SÉLECTION LIGNE"
+
+msgid " SELECT BLOCK"
+msgstr " SÉLECTION BLOC"
+
+msgid "recording"
+msgstr "Enregistrement"
+
+#, c-format
+msgid "E383: Invalid search string: %s"
+msgstr "E383: Chaîne de recherche invalide : %s"
+
+#, c-format
+msgid "E384: search hit TOP without match for: %s"
+msgstr "E384: la recherche a atteint le HAUT sans trouver : %s"
+
+#, c-format
+msgid "E385: search hit BOTTOM without match for: %s"
+msgstr "E385: la recherche a atteint le BAS sans trouver : %s"
+
+msgid "E386: Expected '?' or '/' after ';'"
+msgstr "E386: '?' ou '/' attendu après ';'"
+
+msgid " (includes previously listed match)"
+msgstr " (inclut des correspondances listées précédemment)"
+
+#. cursor at status line
+msgid "--- Included files "
+msgstr "--- Fichiers inclus "
+
+msgid "not found "
+msgstr "introuvables "
+
+msgid "in path ---\n"
+msgstr "dans le chemin ---\n"
+
+msgid " (Already listed)"
+msgstr " (Déjà listé)"
+
+msgid " NOT FOUND"
+msgstr " INTROUVABLE"
+
+#, c-format
+msgid "Scanning included file: %s"
+msgstr "Examen des fichiers inclus : %s"
+
+#, c-format
+msgid "Searching included file %s"
+msgstr "Recherche du fichier inclus %s"
+
+msgid "E387: Match is on current line"
+msgstr "E387: La correspondance est sur la ligne courante"
+
+msgid "All included files were found"
+msgstr "Tous les fichiers inclus ont été trouvés"
+
+msgid "No included files"
+msgstr "Aucun fichier inclus"
+
+msgid "E388: Couldn't find definition"
+msgstr "E388: Impossible de trouver la définition"
+
+msgid "E389: Couldn't find pattern"
+msgstr "E389: Impossible de trouver le motif"
+
+msgid "Substitute "
+msgstr "Substitue "
+
+#, c-format
+msgid ""
+"\n"
+"# Last %sSearch Pattern:\n"
+"~"
+msgstr ""
+"\n"
+"# Dernier motif de recherche %s :\n"
+"~"
+
+msgid "E759: Format error in spell file"
+msgstr "E759: Erreur de format du fichier orthographique"
+
+msgid "E758: Truncated spell file"
+msgstr "E758: Fichier orthographique tronqué"
+
+#, c-format
+msgid "Trailing text in %s line %d: %s"
+msgstr "Texte en trop dans %s ligne %d : %s"
+
+#, c-format
+msgid "Affix name too long in %s line %d: %s"
+msgstr "Nom d'affixe trop long dans %s ligne %d : %s"
+
+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"
+
+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"
+
+msgid "Compressing word tree..."
+msgstr "Compression de l'arbre des mots"
+
+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"
+
+#, c-format
+msgid "Reading spell file \"%s\""
+msgstr "Lecture du fichier orthographique \"%s\""
+
+msgid "E757: This does not look like a spell file"
+msgstr "E757: Le fichier ne ressemble pas à un fichier orthographique"
+
+msgid "E771: Old spell file, needs to be updated"
+msgstr "E771: Fichier orthographique obsolète, sa mise à jour est nécessaire"
+
+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"
+
+msgid "E770: Unsupported section in spell file"
+msgstr "E770: Section non supportée dans le fichier orthographique"
+
+#, c-format
+msgid "Warning: region %s not supported"
+msgstr "Alerte : région %s non supportée"
+
+#, c-format
+msgid "Reading affix file %s ..."
+msgstr "Lecture du fichier d'affixes %s..."
+
+#, c-format
+msgid "Conversion failure for word in %s line %d: %s"
+msgstr "Échec de conversion du mot dans %s ligne %d : %s"
+
+#, c-format
+msgid "Conversion in %s not supported: from %s to %s"
+msgstr "La conversion dans %s non supportée : de %s vers %s"
+
+#, 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"
+
+#, c-format
+msgid "FLAG after using flags in %s line %d: %s"
+msgstr "FLAG trouvé après des drapeaux dans %s ligne %d : %s"
+
+#, c-format
+msgid ""
+"Defining COMPOUNDFORBIDFLAG after PFX item may give wrong results in %s line "
+"%d"
+msgstr ""
+"Définir COMPOUNDFORBIDFLAG après des PFX peut donner des résultats erronés "
+"dans %s ligne %d"
+
+#, c-format
+msgid ""
+"Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in %s line "
+"%d"
+msgstr ""
+"Définir COMPOUNDPERMITFLAG après des PFX peut donner des résultats erronés "
+"dans %s ligne %d"
+
+#, c-format
+msgid "Wrong COMPOUNDRULES value in %s line %d: %s"
+msgstr "Valeur de COMPOUNDRULES erronée dans %s ligne %d : %s"
+
+#, c-format
+msgid "Wrong COMPOUNDWORDMAX value in %s line %d: %s"
+msgstr "Valeur de COMPOUNDWORDMAX erronée dans %s ligne %d : %s"
+
+#, c-format
+msgid "Wrong COMPOUNDMIN value in %s line %d: %s"
+msgstr "Valeur de COMPOUNDMIN erronée dans %s ligne %d : %s"
+
+#, c-format
+msgid "Wrong COMPOUNDSYLMAX value in %s line %d: %s"
+msgstr "Valeur de COMPOUNDSYLMAX erronée dans %s ligne %d : %s"
+
+#, c-format
+msgid "Wrong CHECKCOMPOUNDPATTERN value in %s line %d: %s"
+msgstr "Valeur de CHECKCOMPOUNDPATTERN erronée dans %s ligne %d : %s"
+
+# DB - TODO
+#, 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"
+
+#, c-format
+msgid "Duplicate affix in %s line %d: %s"
+msgstr "Affixe dupliqué dans %s ligne %d : %s"
+
+#, c-format
+msgid ""
+"Affix also used for BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST in %s "
+"line %d: %s"
+msgstr ""
+"Affixe aussi utilisée pour BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/"
+"NOSUGGEST dans %s ligne %d : %s"
+
+#, 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...)
+#, c-format
+msgid "Broken condition in %s line %d: %s"
+msgstr "Condition non valide dans %s ligne %d : %s"
+
+#, c-format
+msgid "Expected REP(SAL) count in %s line %d"
+msgstr "Nombre de REP(SAL) attendu dans %s ligne %d"
+
+#, c-format
+msgid "Expected MAP count in %s line %d"
+msgstr "Nombre de MAP attendu dans %s ligne %d"
+
+#, c-format
+msgid "Duplicate character in MAP in %s line %d"
+msgstr "Caractère dupliqué dans MAP dans %s ligne %d"
+
+#, c-format
+msgid "Unrecognized or duplicate item in %s line %d: %s"
+msgstr "Élément non reconnu ou dupliqué dans %s ligne %d : %s"
+
+#, c-format
+msgid "Missing FOL/LOW/UPP line in %s"
+msgstr "Ligne FOL/LOW/UPP manquante dans %s"
+
+msgid "COMPOUNDSYLMAX used without SYLLABLE"
+msgstr "Utilisation de COMPOUNDSYLMAX sans SYLLABLE"
+
+msgid "Too many postponed prefixes"
+msgstr "Trop de préfixes reportés (PFXPOSTPONE)"
+
+msgid "Too many compound flags"
+msgstr "Trop de drapeaux de composition"
+
+msgid "Too many postponed prefixes and/or compound flags"
+msgstr "Trop de préfixes reportés et/ou de drapeaux de composition"
+
+#, c-format
+msgid "Missing SOFO%s line in %s"
+msgstr "Ligne SOFO%s manquante dans %s"
+
+#, c-format
+msgid "Both SAL and SOFO lines in %s"
+msgstr "Lignes SAL et lignes SOFO présentes dans %s"
+
+#, 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"
+
+#, c-format
+msgid "Illegal flag in %s line %d: %s"
+msgstr "Drapeau non autorisé dans %s ligne %d : %s"
+
+#, 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"
+
+#, c-format
+msgid "Reading dictionary file %s ..."
+msgstr "Lecture du fichier orthographique %s..."
+
+#, c-format
+msgid "E760: No word count in %s"
+msgstr "E760: Nombre de mots non indiqué dans %s"
+
+#, c-format
+msgid "line %6d, word %6d - %s"
+msgstr "ligne %6d, mot %6d - %s"
+
+#, c-format
+msgid "Duplicate word in %s line %d: %s"
+msgstr "Mot dupliqué dans %s ligne %d : %s"
+
+#, c-format
+msgid "First duplicate word in %s line %d: %s"
+msgstr "Premier mot dupliqué dans %s ligne %d : %s"
+
+#, c-format
+msgid "%d duplicate word(s) in %s"
+msgstr "%d mot(s) dupliqué(s) dans %s"
+
+#, 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"
+
+#, c-format
+msgid "Reading word file %s ..."
+msgstr "Lecture de la liste de mots %s..."
+
+#, c-format
+msgid "Duplicate /encoding= line ignored in %s line %d: %s"
+msgstr "Ligne /encoding= en double ignorée dans %s ligne %d : %s"
+
+#, 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"
+
+#, c-format
+msgid "Duplicate /regions= line ignored in %s line %d: %s"
+msgstr "Ligne /regions= en double ignorée dans %s ligne %d : %s"
+
+#, c-format
+msgid "Too many regions in %s line %d: %s"
+msgstr "Trop de régions dans %s ligne %d : %s"
+
+#, c-format
+msgid "/ line ignored in %s line %d: %s"
+msgstr "Ligne / ignorée dans %s ligne %d : %s"
+
+#, c-format
+msgid "Invalid region nr in %s line %d: %s"
+msgstr "Numéro de région invalide dans %s ligne %d : %s"
+
+#, c-format
+msgid "Unrecognized flags in %s line %d: %s"
+msgstr "Drapeaux non reconnus dans %s ligne %d : %s"
+
+#, c-format
+msgid "Ignored %d words with non-ASCII characters"
+msgstr "%d mot(s) ignoré(s) avec des caractères non-ASCII"
+
+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 "
+
+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.
+#.
+msgid "Performing soundfolding..."
+msgstr "Analyse phonétique en cours..."
+
+#, c-format
+msgid "Number of words after soundfolding: %ld"
+msgstr "Nombre de mots après l'analyse phonétique : %ld"
+
+#, c-format
+msgid "Total number of words: %d"
+msgstr "Nombre total de mots : %d"
+
+#, c-format
+msgid "Writing suggestion file %s ..."
+msgstr "Écriture du fichier de suggestions %s..."
+
+#, c-format
+msgid "Estimated runtime memory use: %d bytes"
+msgstr "Estimation de mémoire consommée : %d octets"
+
+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"
+
+msgid "E754: Only up to 8 regions supported"
+msgstr "E754: 8 régions au maximum sont supportées"
+
+#, c-format
+msgid "E755: Invalid region in %s"
+msgstr "E755: Région invalide dans %s"
+
+msgid "Warning: both compounding and NOBREAK specified"
+msgstr "Alerte : la composition et NOBREAK sont tous les deux spécifiés"
+
+#, c-format
+msgid "Writing spell file %s ..."
+msgstr "Écriture du fichier orthographique %s..."
+
+msgid "Done!"
+msgstr "Terminé !"
+
+# DB - todo : perfectible.
+#, c-format
+msgid "E765: 'spellfile' does not have %ld entries"
+msgstr "E765: 'spellfile' n'a pas %ld entrées"
+
+#, c-format
+msgid "Word removed from %s"
+msgstr "Mot retiré de %s"
+
+#, c-format
+msgid "Word added to %s"
+msgstr "Mot ajouté dans %s"
+
+msgid "E763: Word characters differ between spell files"
+msgstr ""
+"E763: Les caractères de mots diffèrent entre les fichiers orthographiques"
+
+msgid "Sorry, no suggestions"
+msgstr "Désolé, aucune suggestion"
+
+#, c-format
+msgid "Sorry, only %ld suggestions"
+msgstr "Désolé, seulement %ld suggestions"
+
+#. for when 'cmdheight' > 1
+#. avoid more prompt
+#, 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"
+
+#, c-format
+msgid "E778: This does not look like a .sug file: %s"
+msgstr "E778: %s ne semble pas être un fichier .sug"
+
+#, c-format
+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"
+
+#. This should have been checked when generating the .spl
+#. * file.
+msgid "E783: duplicate char in MAP entry"
+msgstr "E783: caractères dupliqué dans l'entrée MAP"
+
+#, c-format
+msgid "E390: Illegal argument: %s"
+msgstr "E390: Argument invalide : %s"
+
+#, c-format
+msgid "E391: No such syntax cluster: %s"
+msgstr "E391: Aucune grappe de syntaxe %s"
+
+msgid "No Syntax items defined for this buffer"
+msgstr "Aucun élément de syntaxe défini pour ce tampon"
+
+msgid "syncing on C-style comments"
+msgstr "synchronisation sur les commentaires de type C"
+
+msgid "no syncing"
+msgstr "Aucune synchronisation"
+
+# DB - Les deux messages qui suivent vont ensemble.
+msgid "syncing starts "
+msgstr "La synchronisation débute "
+
+msgid " lines before top line"
+msgstr " lignes avant la ligne du haut"
+
+msgid ""
+"\n"
+"--- Syntax sync items ---"
+msgstr ""
+"\n"
+"--- Éléments de synchronisation syntaxique ---"
+
+msgid ""
+"\n"
+"syncing on items"
+msgstr ""
+"\n"
+"synchronisation sur éléments"
+
+msgid ""
+"\n"
+"--- Syntax items ---"
+msgstr ""
+"\n"
+"--- Éléments de syntaxe ---"
+
+#, c-format
+msgid "E392: No such syntax cluster: %s"
+msgstr "E392: Aucune grappe de syntaxe %s"
+
+msgid "minimal "
+msgstr "minimum "
+
+msgid "maximal "
+msgstr "maximum "
+
+# DB - todo
+msgid "; match "
+msgstr "; correspond avec "
+
+# DB - todo
+msgid " line breaks"
+msgstr " coupures de ligne"
+
+msgid "E395: contains argument not accepted here"
+msgstr "E395: L'argument « contains » n'est pas accepté ici"
+
+msgid "E844: invalid cchar value"
+msgstr "E844: valeur de cchar invalide"
+
+msgid "E393: group[t]here not accepted here"
+msgstr "E393: L'argument « group[t]here » n'est pas accepté ici"
+
+#, c-format
+msgid "E394: Didn't find region item for %s"
+msgstr "E394: Aucun élément de type région trouvé pour %s"
+
+msgid "E397: Filename required"
+msgstr "E397: Nom de fichier requis"
+
+msgid "E847: Too many syntax includes"
+msgstr "E847: Trop d'inclusions de syntaxe"
+
+#, c-format
+msgid "E789: Missing ']': %s"
+msgstr "E789: ']' manquant : %s"
+
+#, c-format
+msgid "E398: Missing '=': %s"
+msgstr "E398: '=' manquant : %s"
+
+#, c-format
+msgid "E399: Not enough arguments: syntax region %s"
+msgstr "E399: Pas assez d'arguments : syntax region %s"
+
+msgid "E848: Too many syntax clusters"
+msgstr "E848: Trop de grappes de syntaxe"
+
+msgid "E400: No cluster specified"
+msgstr "E400: Aucune grappe spécifiée"
+
+#, c-format
+msgid "E401: Pattern delimiter not found: %s"
+msgstr "E401: Délimiteur de motif introuvable : %s"
+
+#, c-format
+msgid "E402: Garbage after pattern: %s"
+msgstr "E402: caractères en trop après le motif : %s"
+
+msgid "E403: syntax sync: line continuations pattern specified twice"
+msgstr ""
+"E403: synchro syntax : motif de continuation de ligne présent deux fois"
+
+#, c-format
+msgid "E404: Illegal arguments: %s"
+msgstr "E404: Arguments invalides : %s"
+
+#, c-format
+msgid "E405: Missing equal sign: %s"
+msgstr "E405: '=' manquant : %s"
+
+#, c-format
+msgid "E406: Empty argument: %s"
+msgstr "E406: Argument vide : %s"
+
+#, c-format
+msgid "E407: %s not allowed here"
+msgstr "E407: %s n'est pas autorisé ici"
+
+#, c-format
+msgid "E408: %s must be first in contains list"
+msgstr "E408: %s doit être le premier élément d'une liste « contains »"
+
+#, c-format
+msgid "E409: Unknown group name: %s"
+msgstr "E409: Nom de groupe inconnu : %s"
+
+#, c-format
+msgid "E410: Invalid :syntax subcommand: %s"
+msgstr "E410: Sous-commande de :syntax invalide : %s"
+
+msgid "E679: recursive loop loading syncolor.vim"
+msgstr "E679: boucle récursive lors du chargement de syncolor.vim"
+
+#, c-format
+msgid "E411: highlight group not found: %s"
+msgstr "E411: groupe de surbrillance introuvable : %s"
+
+#, c-format
+msgid "E412: Not enough arguments: \":highlight link %s\""
+msgstr "E412: Trop peu d'arguments : \":highlight link %s\""
+
+#, c-format
+msgid "E413: Too many arguments: \":highlight link %s\""
+msgstr "E413: Trop d'arguments : \":highlight link %s\""
+
+msgid "E414: group has settings, highlight link ignored"
+msgstr "E414: le groupe a déjà des attributs, lien de surbrillance ignoré"
+
+#, c-format
+msgid "E415: unexpected equal sign: %s"
+msgstr "E415: signe égal inattendu : %s"
+
+#, c-format
+msgid "E416: missing equal sign: %s"
+msgstr "E416: '=' manquant : %s"
+
+#, c-format
+msgid "E417: missing argument: %s"
+msgstr "E417: argument manquant : %s"
+
+#, c-format
+msgid "E418: Illegal value: %s"
+msgstr "E418: Valeur invalide : %s"
+
+msgid "E419: FG color unknown"
+msgstr "E419: Couleur de premier plan inconnue"
+
+msgid "E420: BG color unknown"
+msgstr "E420: Couleur d'arrière-plan inconnue"
+
+#, c-format
+msgid "E421: Color name or number not recognized: %s"
+msgstr "E421: Nom ou numéro de couleur non reconnu : %s"
+
+#, c-format
+msgid "E422: terminal code too long: %s"
+msgstr "E422: le code de terminal est trop long : %s"
+
+#, c-format
+msgid "E423: Illegal argument: %s"
+msgstr "E423: Argument invalide : %s"
+
+msgid "E424: Too many different highlighting attributes in use"
+msgstr ""
+"E424: Trop d'attributs de surbrillance différents en cours d'utilisation"
+
+msgid "E669: Unprintable character in group name"
+msgstr "E669: Caractère non-imprimable dans un nom de groupe"
+
+msgid "W18: Invalid character in group name"
+msgstr "W18: Caractère invalide dans un nom de groupe"
+
+msgid "E849: Too many highlight and syntax groups"
+msgstr "E849: Trop de groupes de surbrillance et de syntaxe"
+
+msgid "E555: at bottom of tag stack"
+msgstr "E555: En bas de la pile de marqueurs"
+
+msgid "E556: at top of tag stack"
+msgstr "E556: Au sommet de la pile de marqueurs"
+
+msgid "E425: Cannot go before first matching tag"
+msgstr "E425: Impossible d'aller avant le premier marqueur correspondant"
+
+#, c-format
+msgid "E426: tag not found: %s"
+msgstr "E426: Marqueur introuvable : %s"
+
+msgid " # pri kind tag"
+msgstr " # pri type marqueur"
+
+msgid "file\n"
+msgstr "fichier\n"
+
+msgid "E427: There is only one matching tag"
+msgstr "E427: Il n'y a qu'un marqueur correspondant"
+
+msgid "E428: Cannot go beyond last matching tag"
+msgstr "E428: Impossible d'aller au-delà du dernier marqueur correspondant"
+
+#, c-format
+msgid "File \"%s\" does not exist"
+msgstr "Le fichier \"%s\" n'existe pas"
+
+#. Give an indication of the number of matching tags
+#, c-format
+msgid "tag %d of %d%s"
+msgstr "marqueur %d sur %d%s"
+
+msgid " or more"
+msgstr " ou plus"
+
+msgid " Using tag with different case!"
+msgstr " Utilisation d'un marqueur avec une casse différente !"
+
+#, c-format
+msgid "E429: File \"%s\" does not exist"
+msgstr "E429: Le fichier \"%s\" n'existe pas"
+
+#. Highlight title
+msgid ""
+"\n"
+" # TO tag FROM line in file/text"
+msgstr ""
+"\n"
+" # VERS marqueur DE ligne dans le fichier/texte"
+
+#, c-format
+msgid "Searching tags file %s"
+msgstr "Examen du fichier de marqueurs %s"
+
+#, 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"
+
+#, c-format
+msgid "E431: Format error in tags file \"%s\""
+msgstr "E431: Erreur de format dans le fichier de marqueurs \"%s\""
+
+#, c-format
+msgid "Before byte %ld"
+msgstr "Avant l'octet %ld"
+
+#, 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
+msgid "E433: No tags file"
+msgstr "E433: Aucun fichier de marqueurs"
+
+msgid "E434: Can't find tag pattern"
+msgstr "E434: Le motif de marqueur est introuvable"
+
+msgid "E435: Couldn't find tag, just guessing!"
+msgstr "E435: Marqueur introuvable, tentative pour deviner !"
+
+#, c-format
+msgid "Duplicate field name: %s"
+msgstr "Nom de champ dupliqué : %s"
+
+msgid "' not known. Available builtin terminals are:"
+msgstr "' inconnu. Les terminaux intégrés sont :"
+
+msgid "defaulting to '"
+msgstr "utilisation par défaut de '"
+
+msgid "E557: Cannot open termcap file"
+msgstr "E557: Impossible d'ouvrir le fichier termcap"
+
+msgid "E558: Terminal entry not found in terminfo"
+msgstr "E558: La description du terminal est introuvable dans terminfo"
+
+msgid "E559: Terminal entry not found in termcap"
+msgstr "E559: La description du terminal est introuvable dans termcap"
+
+#, c-format
+msgid "E436: No \"%s\" entry in termcap"
+msgstr "E436: Aucune entrée \"%s\" dans termcap"
+
+# DB - todo : Comment améliorer ?
+msgid "E437: terminal capability \"cm\" required"
+msgstr "E437: capacité de terminal \"cm\" requise"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Terminal keys ---"
+msgstr ""
+"\n"
+"--- Touches du 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"
+
+# DB - Message de débogage.
+msgid "Used CUT_BUFFER0 instead of empty selection"
+msgstr "CUT_BUFFER0 utilisé plutôt qu'une sélection vide"
+
+#. This happens when the FileChangedRO autocommand changes the
+#. * file in a way it becomes shorter.
+msgid "E834: Line count changed unexpectedly"
+msgstr "E834: Le nombre de lignes a été changé inopinément"
+
+# DB - Question O/N.
+#. must display the prompt
+msgid "No undo possible; continue anyway"
+msgstr "Annulation impossible ; continuer"
+
+#, c-format
+msgid "E828: Cannot open undo file for writing: %s"
+msgstr "E828: Impossible d'ouvrir le fichier d'annulations en écriture : %s"
+
+#, c-format
+msgid "E825: Corrupted undo file (%s): %s"
+msgstr "E825: Fichier d'annulations corrompu (%s) : %s"
+
+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'"
+
+#, 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"
+
+#, 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"
+
+msgid "Skipping undo file write, nothing to undo"
+msgstr "Le fichier d'annulations n'est pas écrit, rien à annuler"
+
+#, c-format
+msgid "Writing undo file: %s"
+msgstr "Écriture du fichier d'annulations : %s"
+
+#, c-format
+msgid "E829: write error in undo file: %s"
+msgstr "E829: Erreur d'écriture dans le fichier d'annulations : %s"
+
+#, c-format
+msgid "Not reading undo file, owner differs: %s"
+msgstr "Le fichier d'annulations n'est pas lu, propriétaire différent : %s"
+
+#, c-format
+msgid "Reading undo file: %s"
+msgstr "Lecture du fichier d'annulations : %s..."
+
+#, c-format
+msgid "E822: Cannot open undo file for reading: %s"
+msgstr "E822: Impossible d'ouvrir le fichier d'annulations en lecture : %s"
+
+#, c-format
+msgid "E823: Not an undo file: %s"
+msgstr "E823: Ce n'est pas un fichier d'annulations : %s"
+
+#, 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"
+
+msgid "File contents changed, cannot use undo info"
+msgstr ""
+"Le contenu du fichier a changé, impossible d'utiliser les informations "
+"d'annulation"
+
+#, c-format
+msgid "Finished reading undo file %s"
+msgstr "Fin de lecture du fichier d'annulations %s"
+
+msgid "Already at oldest change"
+msgstr "Déjà à la modification la plus ancienne"
+
+msgid "Already at newest change"
+msgstr "Déjà à la modification la plus récente"
+
+#, c-format
+msgid "E830: Undo number %ld not found"
+msgstr "E830: Annulation n° %ld introuvable"
+
+msgid "E438: u_undo: line numbers wrong"
+msgstr "E438: u_undo : numéros de ligne erronés"
+
+msgid "more line"
+msgstr "ligne en plus"
+
+msgid "more lines"
+msgstr "lignes en plus"
+
+msgid "line less"
+msgstr "ligne en moins"
+
+msgid "fewer lines"
+msgstr "lignes en moins"
+
+msgid "change"
+msgstr "modification"
+
+msgid "changes"
+msgstr "modifications"
+
+#, c-format
+msgid "%ld %s; %s #%ld %s"
+msgstr "%ld %s ; %s #%ld ; %s"
+
+msgid "before"
+msgstr "avant"
+
+msgid "after"
+msgstr "après"
+
+msgid "Nothing to undo"
+msgstr "Rien à annuler"
+
+# DB - Les deux premières colonnes sont alignées à droite.
+msgid "number changes when saved"
+msgstr "numéro modif. instant enregistré"
+
+#, c-format
+msgid "%ld seconds ago"
+msgstr "il y a %ld secondes"
+
+msgid "E790: undojoin is not allowed after undo"
+msgstr "E790: undojoin n'est pas autorisé après une annulation"
+
+msgid "E439: undo list corrupt"
+msgstr "E439: la liste d'annulation est corrompue"
+
+msgid "E440: undo line missing"
+msgstr "E440: ligne d'annulation manquante"
+
+#. Only MS VC 4.1 and earlier can do Win32s
+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"
+"Included patches: "
+msgstr ""
+"\n"
+"Rustines incluses : "
+
+msgid ""
+"\n"
+"Extra patches: "
+msgstr ""
+"\n"
+"Rustines extra : "
+
+msgid "Modified by "
+msgstr "Modifié par "
+
+msgid ""
+"\n"
+"Compiled "
+msgstr ""
+"\n"
+"Compilé "
+
+msgid "by "
+msgstr "par "
+
+msgid ""
+"\n"
+"Huge version "
+msgstr ""
+"\n"
+"Énorme version "
+
+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."
+
+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 " Features included (+) or not (-):\n"
+msgstr " Fonctionnalités incluses (+) ou non (-) :\n"
+
+msgid " system vimrc file: \""
+msgstr " fichier vimrc système : \""
+
+msgid " user vimrc file: \""
+msgstr " fichier vimrc utilisateur : \""
+
+msgid " 2nd user vimrc file: \""
+msgstr " 2me fichier vimrc utilisateur : \""
+
+msgid " 3rd user vimrc file: \""
+msgstr " 3me fichier vimrc utilisateur : \""
+
+msgid " user exrc file: \""
+msgstr " fichier exrc utilisateur : \""
+
+msgid " 2nd user exrc file: \""
+msgstr " 2me fichier exrc utilisateur : \""
+
+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 " fall-back for $VIM: \""
+msgstr " $VIM par défaut : \""
+
+msgid " f-b for $VIMRUNTIME: \""
+msgstr " $VIMRUNTIME par défaut : \""
+
+msgid "Compilation: "
+msgstr "Compilation : "
+
+msgid "Compiler: "
+msgstr "Compilateur : "
+
+msgid "Linking: "
+msgstr "Édition de liens : "
+
+msgid " DEBUG BUILD"
+msgstr " VERSION DE DÉBOGAGE"
+
+msgid "VIM - Vi IMproved"
+msgstr "VIM - Vi Amélioré"
+
+msgid "version "
+msgstr "version "
+
+msgid "by Bram Moolenaar et al."
+msgstr "par Bram Moolenaar et al."
+
+msgid "Vim is open source and freely distributable"
+msgstr "Vim est un logiciel libre"
+
+msgid "Help poor children in Uganda!"
+msgstr "Aidez les enfants pauvres d'Ouganda !"
+
+msgid "type :help iccf<Enter> for information "
+msgstr "tapez :help iccf<Entrée> pour plus d'informations "
+
+msgid "type :q<Enter> to exit "
+msgstr "tapez :q<Entrée> pour sortir du programme "
+
+msgid "type :help<Enter> or <F1> for on-line help"
+msgstr "tapez :help<Entrée> ou <F1> pour accéder à l'aide en ligne "
+
+msgid "type :help version7<Enter> for version info"
+msgstr "tapez :help version7<Entrée> pour lire les notes de mise à jour"
+
+# DB - Pour les trois messages qui suivent :
+# :set cp
+# :intro
+msgid "Running in Vi compatible mode"
+msgstr "Compatibilité avec Vi activée"
+
+msgid "type :set nocp<Enter> for Vim defaults"
+msgstr "tapez :set nocp<Entrée> pour la désactiver"
+
+msgid "type :help cp-default<Enter> for info on this"
+msgstr "tapez :help cp-default<Entrée> pour plus d'info"
+
+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 !"
+
+msgid "Become a registered Vim user!"
+msgstr "Devenez un utilisateur de Vim enregistré !"
+
+msgid "type :help sponsor<Enter> for information "
+msgstr "tapez :help sponsor<Entrée> pour plus d'informations "
+
+msgid "type :help register<Enter> for information "
+msgstr "tapez :help register<Entrée> pour plus d'informations "
+
+msgid "menu Help->Sponsor/Register for information "
+msgstr "menu Aide->Sponsor/Enregistrement pour plus d'info"
+
+msgid "WARNING: Windows 95/98/ME detected"
+msgstr "ALERTE: Windows 95/98/ME détecté"
+
+msgid "type :help windows95<Enter> for info on this"
+msgstr "tapez :help windows95<Entrée> pour plus d'information"
+
+msgid "Already only one window"
+msgstr "Il n'y a déjà plus qu'une fenêtre"
+
+msgid "E441: There is no preview window"
+msgstr "E441: Il n'y a pas de fenêtre de prévisualisation"
+
+msgid "E442: Can't split topleft and botright at the same time"
+msgstr "E442: Impossible de partager topleft et botright en même temps"
+
+msgid "E443: Cannot rotate when another window is split"
+msgstr "E443: Rotation impossible quand une autre fenêtre est partagée"
+
+msgid "E444: Cannot close last window"
+msgstr "E444: Impossible de fermer la dernière fenêtre"
+
+msgid "E813: Cannot close autocmd window"
+msgstr "E813: Impossible de fermer la fenêtre des autocommandes"
+
+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"
+
+msgid "E445: Other window contains changes"
+msgstr "E445: Les modifications de l'autre fenêtre n'ont pas été enregistrées"
+
+msgid "E446: No file name under cursor"
+msgstr "E446: Aucun nom de fichier sous le curseur"
+
+#, c-format
+msgid "E447: Can't find file \"%s\" in path"
+msgstr "E447: Le fichier \"%s\" est introuvable dans 'path'"
+
+#, c-format
+msgid "E370: Could not load library %s"
+msgstr "E370: Impossible de charger la bibliothèque %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 "E299: Perl evaluation forbidden in sandbox without the Safe module"
+msgstr "E299: Évaluation Perl interdite dans bac à sable sans le module Safe"
+
+msgid "Edit with &multiple Vims"
+msgstr "Éditer dans &plusieurs Vims"
+
+msgid "Edit with single &Vim"
+msgstr "Éditer dans un seul &Vim"
+
+msgid "Diff with Vim"
+msgstr "&Comparer avec Vim"
+
+msgid "Edit with &Vim"
+msgstr "Éditer dans &Vim"
+
+#. Now concatenate
+msgid "Edit with existing Vim - "
+msgstr "Éditer dans le Vim existant - "
+
+msgid "Edits the selected file(s) with Vim"
+msgstr "Édites le(s) fichier(s) sélectionné(s) avec Vim"
+
+# 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 "gvimext.dll error"
+msgstr "Erreur de gvimext.dll"
+
+msgid "Path length too long!"
+msgstr "Le chemin est trop long !"
+
+# 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--"
+
+#.
+#. * 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: Commande annulée"
+
+msgid "E471: Argument required"
+msgstr "E471: Argument requis"
+
+msgid "E10: \\ should be followed by /, ? or &"
+msgstr "E10: \\ devrait être suivi de /, ? ou &"
+
+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 "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 "E171: Missing :endif"
+msgstr "E171: :endif manquant"
+
+msgid "E600: Missing :endtry"
+msgstr "E600: :endtry manquant"
+
+msgid "E170: Missing :endwhile"
+msgstr "E170: :endwhile manquant"
+
+msgid "E170: Missing :endfor"
+msgstr "E170: :endfor manquant"
+
+msgid "E588: :endwhile without :while"
+msgstr "E588: :endwhile sans :while"
+
+msgid "E588: :endfor without :for"
+msgstr "E588: :endfor sans :for"
+
+msgid "E13: File exists (add ! to override)"
+msgstr "E13: Le fichier existe déjà (ajoutez ! pour passer outre)"
+
+msgid "E472: Command failed"
+msgstr "E472: La commande a échoué"
+
+#, c-format
+msgid "E234: Unknown fontset: %s"
+msgstr "E234: Jeu de police inconnu : %s"
+
+#, c-format
+msgid "E235: Unknown font: %s"
+msgstr "E235: Police inconnue : %s"
+
+#, c-format
+msgid "E236: Font \"%s\" is not fixed-width"
+msgstr "E236: La police \"%s\" n'a pas une chasse (largeur) fixe"
+
+msgid "E473: Internal error"
+msgstr "E473: Erreur interne"
+
+msgid "Interrupted"
+msgstr "Interrompu"
+
+msgid "E14: Invalid address"
+msgstr "E14: Adresse invalide"
+
+msgid "E474: Invalid argument"
+msgstr "E474: Argument invalide"
+
+#, c-format
+msgid "E475: Invalid argument: %s"
+msgstr "E475: Argument invalide : %s"
+
+#, c-format
+msgid "E15: Invalid expression: %s"
+msgstr "E15: Expression invalide : %s"
+
+msgid "E16: Invalid range"
+msgstr "E16: Plage invalide"
+
+msgid "E476: Invalid command"
+msgstr "E476: Commande invalide"
+
+#, c-format
+msgid "E17: \"%s\" is a directory"
+msgstr "E17: \"%s\" est un répertoire"
+
+#, c-format
+msgid "E364: Library call failed for \"%s()\""
+msgstr "E364: L'appel à la bibliothèque a échoué pour \"%s()\""
+
+#, c-format
+msgid "E448: Could not load library function %s"
+msgstr "E448: Impossible de charger la fonction %s de la bibliothèque"
+
+msgid "E19: Mark has invalid line number"
+msgstr "E19: La marque a un numéro de ligne invalide"
+
+msgid "E20: Mark not set"
+msgstr "E20: Marque non positionnée"
+
+msgid "E21: Cannot make changes, 'modifiable' is off"
+msgstr "E21: Impossible de modifier, 'modifiable' est désactivé"
+
+msgid "E22: Scripts nested too deep"
+msgstr "E22: Trop de récursion dans les scripts"
+
+msgid "E23: No alternate file"
+msgstr "E23: Pas de fichier alternatif"
+
+msgid "E24: No such abbreviation"
+msgstr "E24: Cette abréviation n'existe pas"
+
+msgid "E477: No ! allowed"
+msgstr "E477: Le ! n'est pas autorisé"
+
+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 "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 "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 "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"
+
+#, c-format
+msgid "E28: No such highlight group name: %s"
+msgstr "E28: Aucun nom de groupe de surbrillance %s"
+
+msgid "E29: No inserted text yet"
+msgstr "E29: Pas encore de texte inséré"
+
+msgid "E30: No previous command line"
+msgstr "E30: Aucune ligne de commande précédente"
+
+msgid "E31: No such mapping"
+msgstr "E31: Mappage inexistant"
+
+msgid "E479: No match"
+msgstr "E479: Aucune correspondance"
+
+#, c-format
+msgid "E480: No match: %s"
+msgstr "E480: Aucune correspondance : %s"
+
+msgid "E32: No file name"
+msgstr "E32: Aucun nom de fichier"
+
+msgid "E33: No previous substitute regular expression"
+msgstr "E33: Aucune expression régulière de substitution précédente"
+
+msgid "E34: No previous command"
+msgstr "E34: Aucune commande précédente"
+
+msgid "E35: No previous regular expression"
+msgstr "E35: Aucune expression régulière précédente"
+
+msgid "E481: No range allowed"
+msgstr "E481: Les plages ne sont pas autorisées"
+
+msgid "E36: Not enough room"
+msgstr "E36: Pas assez de place"
+
+#, c-format
+msgid "E247: no registered server named \"%s\""
+msgstr "E247: aucun serveur nommé \"%s\" n'est enregistré"
+
+#, c-format
+msgid "E482: Can't create file %s"
+msgstr "E482: Impossible de créer le fichier %s"
+
+msgid "E483: Can't get temp file name"
+msgstr "E483: Impossible d'obtenir un nom de fichier temporaire"
+
+#, c-format
+msgid "E484: Can't open file %s"
+msgstr "E484: Impossible d'ouvrir le fichier \"%s\""
+
+#, c-format
+msgid "E485: Can't read file %s"
+msgstr "E485: Impossible de lire le fichier %s"
+
+msgid "E37: No write since last change (add ! to override)"
+msgstr "E37: Modifications non enregistrées (ajoutez ! pour passer outre)"
+
+msgid "E38: Null argument"
+msgstr "E38: Argument null"
+
+msgid "E39: Number expected"
+msgstr "E39: Nombre attendu"
+
+#, c-format
+msgid "E40: Can't open errorfile %s"
+msgstr "E40: Impossible d'ouvrir le fichier d'erreurs %s"
+
+msgid "E233: cannot open display"
+msgstr "E233: ouverture du display impossible"
+
+msgid "E41: Out of memory!"
+msgstr "E41: Mémoire épuisée"
+
+msgid "Pattern not found"
+msgstr "Motif introuvable"
+
+#, c-format
+msgid "E486: Pattern not found: %s"
+msgstr "E486: Motif introuvable : %s"
+
+msgid "E487: Argument must be positive"
+msgstr "E487: L'argument doit être positif"
+
+msgid "E459: Cannot go back to previous directory"
+msgstr "E459: Impossible de retourner au répertoire précédent"
+
+msgid "E42: No Errors"
+msgstr "E42: Aucune erreur"
+
+# DB - TODO : trouver une traduction valable et attestée pour "location".
+msgid "E776: No location list"
+msgstr "E776: Aucune liste d'emplacements"
+
+msgid "E43: Damaged match string"
+msgstr "E43: La chaîne de recherche est endommagée"
+
+msgid "E44: Corrupted regexp program"
+msgstr "E44: L'automate de regexp est corrompu"
+
+msgid "E45: 'readonly' option is set (add ! to override)"
+msgstr "E45: L'option 'readonly' est activée (ajoutez ! pour passer outre)"
+
+#, c-format
+msgid "E46: Cannot change read-only variable \"%s\""
+msgstr "E46: La variable \"%s\" est en lecture seule"
+
+#, c-format
+msgid "E794: Cannot set variable in the sandbox: \"%s\""
+msgstr ""
+"E794: Impossible de modifier une variable depuis le bac à sable : \"%s\""
+
+msgid "E47: Error while reading errorfile"
+msgstr "E47: Erreur lors de la lecture du fichier d'erreurs"
+
+msgid "E48: Not allowed in sandbox"
+msgstr "E48: Opération interdite dans le bac à sable"
+
+msgid "E523: Not allowed here"
+msgstr "E523: Interdit à cet endroit"
+
+msgid "E359: Screen mode setting not supported"
+msgstr "E359: Choix du mode d'écran non supporté"
+
+msgid "E49: Invalid scroll size"
+msgstr "E49: Valeur de défilement invalide"
+
+msgid "E91: 'shell' option is empty"
+msgstr "E91: L'option 'shell' est vide"
+
+msgid "E255: Couldn't read in sign data!"
+msgstr "E255: Impossible de lire les données du symbole !"
+
+msgid "E72: Close error on swap file"
+msgstr "E72: Erreur lors de la fermeture du fichier d'échange"
+
+msgid "E73: tag stack empty"
+msgstr "E73: La pile des marqueurs est vide"
+
+msgid "E74: Command too complex"
+msgstr "E74: Commande trop complexe"
+
+msgid "E75: Name too long"
+msgstr "E75: Nom trop long"
+
+msgid "E76: Too many ["
+msgstr "E76: Trop de ["
+
+msgid "E77: Too many file names"
+msgstr "E77: Trop de noms de fichiers"
+
+msgid "E488: Trailing characters"
+msgstr "E488: Caractères surnuméraires"
+
+msgid "E78: Unknown mark"
+msgstr "E78: Marque inconnue"
+
+msgid "E79: Cannot expand wildcards"
+msgstr "E79: Impossible de développer les métacaractères"
+
+msgid "E591: 'winheight' cannot be smaller than 'winminheight'"
+msgstr "E591: 'winheight' ne peut pas être plus petit que 'winminheight'"
+
+msgid "E592: 'winwidth' cannot be smaller than 'winminwidth'"
+msgstr "E592: 'winwidth' ne peut pas être plus petit que 'winminwidth'"
+
+msgid "E80: Error while writing"
+msgstr "E80: Erreur lors de l'écriture"
+
+msgid "Zero count"
+msgstr "Le quantificateur est nul"
+
+msgid "E81: Using <SID> not in a script context"
+msgstr "E81: <SID> utilisé en dehors d'un script"
+
+msgid "E449: Invalid expression received"
+msgstr "E449: Expression invalide reçue"
+
+msgid "E463: Region is guarded, cannot modify"
+msgstr "E463: Cette zone est verrouillée et ne peut pas être modifiée"
+
+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 "E685: Internal error: %s"
+msgstr "E685: Erreur interne : %s"
+
+msgid "E363: pattern uses more memory than 'maxmempattern'"
+msgstr "E363: le motif utilise plus de mémoire que 'maxmempattern'"
+
+msgid "E749: empty buffer"
+msgstr "E749: tampon vide"
+
+msgid "E682: Invalid search pattern or delimiter"
+msgstr "E682: Délimiteur ou motif de recherche invalide"
+
+msgid "E139: File is loaded in another buffer"
+msgstr "E139: Le fichier est chargé dans un autre tampon"
+
+#, c-format
+msgid "E764: Option '%s' is not set"
+msgstr "E764: L'option '%s' n'est pas activée"
+
+msgid "E850: Invalid register name"
+msgstr "E850: Nom de registre invalide"
+
+msgid "search hit TOP, continuing at BOTTOM"
+msgstr "La recherche a atteint le HAUT, et continue en BAS"
+
+msgid "search hit BOTTOM, continuing at TOP"
+msgstr "La recherche a atteint le BAS, et continue en HAUT"
+
+#, c-format
+msgid "Need encryption key for \"%s\""
+msgstr "Besoin de la clé de chiffrement pour \"%s\""
+
+msgid "can't delete OutputObject attributes"
+msgstr "impossible d'effacer les attributs d'OutputObject"
+
+msgid "softspace must be an integer"
+msgstr "softspace doit être un nombre entier"
+
+msgid "invalid attribute"
+msgstr "attribut invalide"
+
+msgid "writelines() requires list of strings"
+msgstr "writelines() requiert une liste de chaînes"
+
+msgid "E264: Python: Error initialising I/O objects"
+msgstr "E264: Python : Erreur d'initialisation des objets d'E/S"
+
+msgid "empty keys are not allowed"
+msgstr "les clés vides ne sont pas autorisées"
+
+msgid "Cannot delete DictionaryObject attributes"
+msgstr "Impossible d'effacer les attributs de DictionaryObject"
+
+msgid "Cannot modify fixed dictionary"
+msgstr "Impossible de modifier un dictionnaire fixe"
+
+msgid "Cannot set this attribute"
+msgstr "Impossible d'initialiser cet attribut"
+
+msgid "dict is locked"
+msgstr "dictionnaire est verrouillé"
+
+msgid "failed to add key to dictionary"
+msgstr "l'ajout de clé au dictionnaire a échoué"
+
+msgid "list index out of range"
+msgstr "index de liste hors limites"
+
+msgid "internal error: failed to get vim list item"
+msgstr "erreur interne : accès à un élément de liste a échoué"
+
+msgid "list is locked"
+msgstr "liste verrouillée"
+
+msgid "Failed to add item to list"
+msgstr "Ajout à la liste a échoué"
+
+msgid "internal error: no vim list item"
+msgstr "erreur interne : pas d'élément de liste vim"
+
+msgid "can only assign lists to slice"
+msgstr "seules des tranches peuvent être assignées aux listes"
+
+msgid "internal error: failed to add item to list"
+msgstr "erreur interne : ajout d'élément à la liste a échoué"
+
+msgid "can only concatenate with lists"
+msgstr "on ne peut que concaténer avec des listes"
+
+msgid "cannot delete vim.dictionary attributes"
+msgstr "impossible d'effacer les attributs de vim.dictionary"
+
+msgid "cannot modify fixed list"
+msgstr "impossible de modifier une liste fixe"
+
+msgid "cannot set this attribute"
+msgstr "impossible d'initialiser cet attribut"
+
+msgid "'self' argument must be a dictionary"
+msgstr "l'argument 'self' doit être un dictionnaire"
+
+msgid "failed to run function"
+msgstr "exécution de la fonction a échoué"
+
+msgid "unable to get option value"
+msgstr "impossible d'obtenir la valeur d'une option"
+
+msgid "unable to unset global option"
+msgstr "impossible de désactiver une option globale"
+
+msgid "unable to unset option without global value"
+msgstr "impossible de désactiver une option sans une valeur globale"
+
+msgid "object must be integer"
+msgstr "objet doit être un nombre entier"
+
+msgid "object must be string"
+msgstr "objet doit être de type string"
+
+msgid "attempt to refer to deleted tab page"
+msgstr "tentative de référencer un onglet effacé"
+
+#, c-format
+msgid "<tabpage object (deleted) at %p>"
+msgstr "<objet onglet (effacé) à %p>"
+
+#, c-format
+msgid "<tabpage object (unknown) at %p>"
+msgstr "<objet onglet (inconnu) à %p>"
+
+#, c-format
+msgid "<tabpage %d>"
+msgstr "<onglet %d>"
+
+msgid "no such tab page"
+msgstr "cet onglet n'existe pas"
+
+msgid "attempt to refer to deleted window"
+msgstr "tentative de référencer une fenêtre effacée"
+
+msgid "readonly attribute"
+msgstr "attribut en lecture seule"
+
+msgid "cursor position outside buffer"
+msgstr "curseur positionné en dehors du tampon"
+
+#, c-format
+msgid "<window object (deleted) at %p>"
+msgstr "<objet fenêtre (effacé) à %p>"
+
+#, c-format
+msgid "<window object (unknown) at %p>"
+msgstr "<objet fenêtre (inconnu) à %p>"
+
+#, c-format
+msgid "<window %d>"
+msgstr "<fenêtre %d>"
+
+msgid "no such window"
+msgstr "Cette fenêtre n'existe pas"
+
+msgid "attempt to refer to deleted buffer"
+msgstr "tentative de référencer un tampon effacé"
+
+#, c-format
+msgid "<buffer object (deleted) at %p>"
+msgstr "<objet tampon (effacé) à %p>"
+
+msgid "key must be integer"
+msgstr "la clé doit être un nombre entier"
+
+msgid "expected vim.buffer object"
+msgstr "objet vim.buffer attendu"
+
+msgid "failed to switch to given buffer"
+msgstr "impossible de se déplacer au tampon donné"
+
+msgid "expected vim.window object"
+msgstr "objet vim.window attendu"
+
+msgid "failed to find window in the current tab page"
+msgstr "impossible de trouver une fenêtre dans l'onglet courant"
+
+msgid "did not switch to the specified window"
+msgstr "ne s'est pas déplacé à la fenêtre spécifiée"
+
+msgid "expected vim.tabpage object"
+msgstr "objet vim.tabpage attendu"
+
+msgid "did not switch to the specified tab page"
+msgstr "impossible de se déplacer à l'onglet spécifié"
+
+msgid "failed to run the code"
+msgstr "exécution du code a échoué"
+
+msgid "E858: Eval did not return a valid python object"
+msgstr "E858: Eval n'a pas retourné un objet python valide"
+
+msgid "E859: Failed to convert returned python object to vim value"
+msgstr "E859: Conversion d'objet python à une valeur de vim a échoué"
+
+msgid "unable to convert to vim structure"
+msgstr "conversion à une structure vim impossible"
+
+msgid "NULL reference passed"
+msgstr "référence NULL passée"
+
+msgid "internal error: invalid value type"
+msgstr "erreur interne : type de valeur invalide"
+
+#~ msgid "E860: Eval did not return a valid python 3 object"
+#~ msgstr "E860: Eval n'a pas retourné un object python 3 valid"
+
+#~ msgid "E861: Failed to convert returned python 3 object to vim value"
+#~ msgstr "E861: Conversion d'objet python 3 à une valeur de vim a échoué"
+
+#~ msgid "E863: return value must be an instance of str"
+#~ msgstr "E863: valeur de retour doit être une instance de Str"
+
+#~ msgid "Only boolean objects are allowed"
+#~ msgstr "Seuls les objets booléens sont autorisés"
+
+#~ msgid "no such key in dictionary"
+#~ msgstr "cette clé est inexistante dans le dictionnaire"
diff --git a/src/po/ga.po b/src/po/ga.po
new file mode 100644
index 0000000000..d0c5821b5d
--- /dev/null
+++ b/src/po/ga.po
@@ -0,0 +1,6503 @@
+# Irish translations for vim.
+# This file is distributed under the same license as the vim package.
+# Kevin Patrick Scannell <kscanne@gmail.com>, 2005, 2006, 2008, 2010.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: vim 7.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2010-04-14 09:44-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"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=ISO-8859-1\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+msgid "E82: Cannot allocate any buffer, exiting..."
+msgstr "E82: Ní féidir maolán a dháileadh, ag scor..."
+
+msgid "E83: Cannot allocate buffer, using other one..."
+msgstr "E83: Ní féidir maolán a dháileadh, ag úsáid cinn eile..."
+
+msgid "E515: No buffers were unloaded"
+msgstr "E515: Ní raibh aon mhaolán díluchtaithe"
+
+msgid "E516: No buffers were deleted"
+msgstr "E516: Ní raibh aon mhaolán scriosta"
+
+msgid "E517: No buffers were wiped out"
+msgstr "E517: Ní raibh aon mhaolán bánaithe"
+
+msgid "1 buffer unloaded"
+msgstr "Bhí maolán amháin díluchtaithe"
+
+#, c-format
+msgid "%d buffers unloaded"
+msgstr "%d maolán folmhaithe"
+
+msgid "1 buffer deleted"
+msgstr "Bhí maolán amháin scriosta"
+
+#, c-format
+msgid "%d buffers deleted"
+msgstr "%d maolán scriosta"
+
+msgid "1 buffer wiped out"
+msgstr "Bhí maolán amháin bánaithe"
+
+#, c-format
+msgid "%d buffers wiped out"
+msgstr "%d maolán bánaithe"
+
+msgid "E84: No modified buffer found"
+msgstr "E84: Níor aimsíodh maolán mionathraithe"
+
+#. back where we started, didn't find anything.
+msgid "E85: There is no listed buffer"
+msgstr "E85: Níl aon mhaolán liostaithe ann"
+
+#, c-format
+msgid "E86: Buffer %ld does not exist"
+msgstr "E86: Níl a leithéid de mhaolán %ld"
+
+msgid "E87: Cannot go beyond last buffer"
+msgstr "E87: Ní féidir a dhul thar an maolán deireanach"
+
+msgid "E88: Cannot go before first buffer"
+msgstr "E88: Ní féidir a dhul roimh an chéad mhaolán"
+
+#, c-format
+msgid "E89: No write since last change for buffer %ld (add ! to override)"
+msgstr ""
+"E89: Athraíodh maolán %ld ach nach bhfuil sé sábháilte ó shin (cuir ! leis "
+"an ordú chun sárú)"
+
+msgid "E90: Cannot unload last buffer"
+msgstr "E90: Ní féidir an maolán deireanach a dhíluchtú"
+
+msgid "W14: Warning: List of file names overflow"
+msgstr "W14: Rabhadh: Liosta ainmneacha comhaid thar maoil"
+
+#, c-format
+msgid "E92: Buffer %ld not found"
+msgstr "E92: Maolán %ld gan aimsiú"
+
+#, c-format
+msgid "E93: More than one match for %s"
+msgstr "E93: Níos mó ná teaghrán amháin comhoiriúnaithe le %s"
+
+#, c-format
+msgid "E94: No matching buffer for %s"
+msgstr "E94: Níl aon mhaolán comhoiriúnaithe le %s"
+
+#, c-format
+msgid "line %ld"
+msgstr "líne %ld:"
+
+msgid "E95: Buffer with this name already exists"
+msgstr "E95: Tá maolán ann leis an ainm seo cheana"
+
+msgid " [Modified]"
+msgstr " [Mionathraithe]"
+
+msgid "[Not edited]"
+msgstr "[Gan eagrú]"
+
+msgid "[New file]"
+msgstr "[Comhad nua]"
+
+msgid "[Read errors]"
+msgstr "[Earráidí léimh]"
+
+msgid "[readonly]"
+msgstr "[inléite amháin]"
+
+#, c-format
+msgid "1 line --%d%%--"
+msgstr "1 líne --%d%%--"
+
+#, c-format
+msgid "%ld lines --%d%%--"
+msgstr "%ld líne --%d%%--"
+
+#, c-format
+msgid "line %ld of %ld --%d%%-- col "
+msgstr "líne %ld de %ld --%d%%-- col "
+
+msgid "[No Name]"
+msgstr "[Gan Ainm]"
+
+#. must be a help buffer
+msgid "help"
+msgstr "cabhair"
+
+msgid "[Help]"
+msgstr "[Cabhair]"
+
+msgid "[Preview]"
+msgstr "[Réamhamharc]"
+
+msgid "All"
+msgstr "Uile"
+
+msgid "Bot"
+msgstr "Bun"
+
+msgid "Top"
+msgstr "Barr"
+
+#, c-format
+msgid ""
+"\n"
+"# Buffer list:\n"
+msgstr ""
+"\n"
+"# Liosta maoláin:\n"
+
+msgid "[Location List]"
+msgstr "[Liosta Suíomh]"
+
+msgid "[Quickfix List]"
+msgstr "[Liosta Ceartúchán Tapa]"
+
+msgid "[Scratch]"
+msgstr "[Sealadach]"
+
+msgid ""
+"\n"
+"--- Signs ---"
+msgstr ""
+"\n"
+"--- Comharthaí ---"
+
+#, c-format
+msgid "Signs for %s:"
+msgstr "Comharthaí do %s:"
+
+#, c-format
+msgid " line=%ld id=%d name=%s"
+msgstr " líne=%ld id=%d ainm=%s"
+
+#, c-format
+msgid "E96: Can not diff more than %ld buffers"
+msgstr "E96: Ní féidir diff a dhéanamh ar níos mó ná %ld maolán"
+
+msgid "E810: Cannot read or write temp files"
+msgstr "E810: Ní féidir comhaid shealadacha a léamh nó a scríobh"
+
+msgid "E97: Cannot create diffs"
+msgstr "E97: Ní féidir diffeanna a chruthú"
+
+msgid "Patch file"
+msgstr "Comhad paiste"
+
+msgid "E816: Cannot read patch output"
+msgstr "E816: Ní féidir aschur ó 'patch' a léamh"
+
+msgid "E98: Cannot read diff output"
+msgstr "E98: Ní féidir aschur ó 'diff' a léamh"
+
+msgid "E99: Current buffer is not in diff mode"
+msgstr "E99: Níl an maolán reatha sa mhód diff"
+
+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"
+
+msgid "E100: No other buffer in diff mode"
+msgstr "E100: Níl aon mhaolán eile sa mhód diff"
+
+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"
+
+#, c-format
+msgid "E102: Can't find buffer \"%s\""
+msgstr "E102: Tá maolán \"%s\" gan aimsiú"
+
+#, c-format
+msgid "E103: Buffer \"%s\" is not in diff mode"
+msgstr "E103: Níl maolán \"%s\" i mód diff"
+
+msgid "E787: Buffer changed unexpectedly"
+msgstr "E787: Athraíodh an maolán gan choinne"
+
+msgid "E104: Escape not allowed in digraph"
+msgstr "E104: Ní cheadaítear carachtair éalúcháin i ndéghraf"
+
+msgid "E544: Keymap file not found"
+msgstr "E544: Comhad eochairmhapála gan aimsiú"
+
+msgid "E105: Using :loadkeymap not in a sourced file"
+msgstr "E105: Ag úsáid :loadkeymap ach ní comhad foinsithe é seo"
+
+msgid "E791: Empty keymap entry"
+msgstr "E791: Iontráil fholamh eochairmhapála"
+
+msgid " Keyword completion (^N^P)"
+msgstr " Comhlánú lorgfhocal (^N^P)"
+
+#. ctrl_x_mode == 0, ^P/^N compl.
+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)"
+
+msgid " Whole line completion (^L^N^P)"
+msgstr " Comhlánú Línte Ina Iomlán (^L^N^P)"
+
+msgid " File name completion (^F^N^P)"
+msgstr " Comhlánú de na hainmneacha comhaid (^F^N^P)"
+
+msgid " Tag completion (^]^N^P)"
+msgstr " Comhlánú clibeanna (^]/^N/^P)"
+
+msgid " Path pattern completion (^N^P)"
+msgstr " Comhlánú Conaire (^N^P)"
+
+msgid " Definition completion (^D^N^P)"
+msgstr " Comhlánú de na sainmhínithe (^D^N^P)"
+
+msgid " Dictionary completion (^K^N^P)"
+msgstr " Comhlánú foclóra (^K^N^P)"
+
+msgid " Thesaurus completion (^T^N^P)"
+msgstr " Comhlánú teasárais (^T^N^P)"
+
+msgid " Command-line completion (^V^N^P)"
+msgstr " Comhlánú den líne ordaithe (^V^N^P)"
+
+msgid " User defined completion (^U^N^P)"
+msgstr " Comhlánú saincheaptha (^U^N^P)"
+
+msgid " Omni completion (^O^N^P)"
+msgstr " Comhlánú Omni (^O^N^P)"
+
+msgid " Spelling suggestion (s^N^P)"
+msgstr " Moladh litrithe (s^N^P)"
+
+msgid " Keyword Local completion (^N^P)"
+msgstr " Comhlánú logánta lorgfhocal (^N^P)"
+
+msgid "Hit end of paragraph"
+msgstr "Sroicheadh críoch an pharagraif"
+
+msgid "'dictionary' option is empty"
+msgstr "tá an rogha 'dictionary' folamh"
+
+msgid "'thesaurus' option is empty"
+msgstr "tá an rogha 'thesaurus' folamh"
+
+#, c-format
+msgid "Scanning dictionary: %s"
+msgstr "Foclóir á scanadh: %s"
+
+msgid " (insert) Scroll (^E/^Y)"
+msgstr " (ionsáigh) Scrollaigh (^E/^Y)"
+
+msgid " (replace) Scroll (^E/^Y)"
+msgstr " (ionadaigh) Scrollaigh (^E/^Y)"
+
+#, c-format
+msgid "Scanning: %s"
+msgstr "%s á scanadh"
+
+msgid "Scanning tags."
+msgstr "Clibeanna á scanadh."
+
+msgid " Adding"
+msgstr " Méadú"
+
+#. 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.
+#.
+msgid "-- Searching..."
+msgstr "-- Ag Cuardach..."
+
+msgid "Back at original"
+msgstr "Ar ais ag an mbunáit"
+
+msgid "Word from other line"
+msgstr "Focal as líne eile"
+
+msgid "The only match"
+msgstr "An t-aon teaghrán amháin comhoiriúnaithe"
+
+#, c-format
+msgid "match %d of %d"
+msgstr "comhoiriúnú %d as %d"
+
+#, c-format
+msgid "match %d"
+msgstr "comhoiriúnú %d"
+
+msgid "E18: Unexpected characters in :let"
+msgstr "E18: Carachtair gan choinne i :let"
+
+#, c-format
+msgid "E684: list index out of range: %ld"
+msgstr "E684: innéacs liosta as raon: %ld"
+
+#, c-format
+msgid "E121: Undefined variable: %s"
+msgstr "E121: Athróg gan sainmhíniú: %s"
+
+msgid "E111: Missing ']'"
+msgstr "E111: `]' ar iarraidh"
+
+#, c-format
+msgid "E686: Argument of %s must be a List"
+msgstr "E686: Caithfidh argóint de %s a bheith ina Liosta"
+
+#, 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 "E713: Cannot use empty key for Dictionary"
+msgstr "E713: Ní féidir eochair fholamh a úsáid le Foclóir"
+
+msgid "E714: List required"
+msgstr "E714: Tá gá le liosta"
+
+msgid "E715: Dictionary required"
+msgstr "E715: Tá gá le foclóir"
+
+#, c-format
+msgid "E118: Too many arguments for function: %s"
+msgstr "E118: An iomarca argóintí d'fheidhm: %s"
+
+#, c-format
+msgid "E716: Key not present in Dictionary: %s"
+msgstr "E716: Níl an eochair seo san Fhoclóir: %s"
+
+#, 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"
+
+msgid "E719: Cannot use [:] with a Dictionary"
+msgstr "E719: Ní féidir [:] a úsáid le foclóir"
+
+#, c-format
+msgid "E734: Wrong variable type for %s="
+msgstr "E734: Cineál mícheart athróige le haghaidh %s="
+
+#, c-format
+msgid "E130: Unknown function: %s"
+msgstr "E130: Feidhm anaithnid: %s"
+
+#, c-format
+msgid "E461: Illegal variable name: %s"
+msgstr "E461: Ainm athróige neamhcheadaithe: %s"
+
+msgid "E687: Less targets than List items"
+msgstr "E687: Níos lú spriocanna ná míreanna Liosta"
+
+msgid "E688: More targets than List items"
+msgstr "E688: Níos mó spriocanna ná míreanna Liosta"
+
+msgid "Double ; in list of variables"
+msgstr "; dúblach i liosta na n-athróg"
+
+#, c-format
+msgid "E738: Can't list variables for %s"
+msgstr "E738: Ní féidir athróga do %s a thaispeáint"
+
+msgid "E689: Can only index a List or Dictionary"
+msgstr "E689: Is féidir Liosta nó Foclóir amháin a innéacsú"
+
+msgid "E708: [:] must come last"
+msgstr "E708: caithfidh [:] a bheith ar deireadh"
+
+msgid "E709: [:] requires a List value"
+msgstr "E709: ní foláir Liosta a thabhairt le [:]"
+
+msgid "E710: List value has more items than target"
+msgstr "E710: Tá níos mó míreanna ag an Liosta ná an sprioc"
+
+msgid "E711: List value has not enough items"
+msgstr "E711: Níl go leor míreanna ag an Liosta"
+
+msgid "E690: Missing \"in\" after :for"
+msgstr "E690: \"in\" ar iarraidh i ndiaidh :for"
+
+#, c-format
+msgid "E107: Missing parentheses: %s"
+msgstr "E107: Lúibíní ar iarraidh: %s"
+
+#, c-format
+msgid "E108: No such variable: \"%s\""
+msgstr "E108: Níl a leithéid d'athróg: \"%s\""
+
+msgid "E743: variable nested too deep for (un)lock"
+msgstr "E743: athróg neadaithe ródhomhain chun í a (dí)ghlasáil"
+
+msgid "E109: Missing ':' after '?'"
+msgstr "E109: ':' ar iarraidh i ndiaidh '?'"
+
+msgid "E691: Can only compare List with List"
+msgstr "E691: Is féidir Liosta a chur i gcomparáid le Liosta eile amháin"
+
+msgid "E692: Invalid operation for Lists"
+msgstr "E692: Oibríocht neamhbhailí ar Liostaí"
+
+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"
+
+msgid "E736: Invalid operation for Dictionary"
+msgstr "E736: Oibríocht neamhbhailí ar Fhoclóir"
+
+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 "E694: Invalid operation for Funcrefs"
+msgstr "E694: Oibríocht neamhbhailí ar Funcref"
+
+msgid "E804: Cannot use '%' with Float"
+msgstr "E804: Ní féidir '%' a úsáid le Snámhphointe"
+
+msgid "E110: Missing ')'"
+msgstr "E110: ')' ar iarraidh"
+
+msgid "E695: Cannot index a Funcref"
+msgstr "E695: Ní féidir Funcref a innéacsú"
+
+#, c-format
+msgid "E112: Option name missing: %s"
+msgstr "E112: Ainm rogha ar iarraidh: %s"
+
+#, c-format
+msgid "E113: Unknown option: %s"
+msgstr "E113: Rogha anaithnid: %s"
+
+#, c-format
+msgid "E114: Missing quote: %s"
+msgstr "E114: Comhartha athfhriotail ar iarraidh: %s"
+
+#, c-format
+msgid "E115: Missing quote: %s"
+msgstr "E115: Comhartha athfhriotail ar iarraidh: %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"
+
+#, 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 "E724: variable nested too deep for displaying"
+msgstr "E724: athróg neadaithe ródhomhain chun í a thaispeáint"
+
+#, 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"
+
+#, c-format
+msgid "E117: Unknown function: %s"
+msgstr "E117: Feidhm anaithnid: %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 "E808: Number or Float required"
+msgstr "E808: Uimhir nó Snámhphointe de dhíth"
+
+msgid "E699: Too many arguments"
+msgstr "E699: An iomarca argóintí"
+
+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"
+
+#, c-format
+msgid "E737: Key already exists: %s"
+msgstr "E737: Tá eochair ann cheana: %s"
+
+#, c-format
+msgid "+-%s%3ld lines: "
+msgstr "+-%s%3ld líne: "
+
+#, c-format
+msgid "E700: Unknown function: %s"
+msgstr "E700: Feidhm anaithnid: %s"
+
+msgid ""
+"&OK\n"
+"&Cancel"
+msgstr ""
+"&OK\n"
+"&Cealaigh"
+
+msgid "called inputrestore() more often than inputsave()"
+msgstr "Glaodh inputrestore() níos minice ná inputsave()"
+
+msgid "E786: Range not allowed"
+msgstr "E786: Ní cheadaítear an raon"
+
+msgid "E701: Invalid type for len()"
+msgstr "E701: Cineál neamhbhailí le haghaidh len()"
+
+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 Vim server"
+msgstr "E240: Níl aon nasc le freastalaí Vim"
+
+#, c-format
+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 "E655: Too many symbolic links (cycle?)"
+msgstr "E655: An iomarca naisc shiombalacha (ciogal?)"
+
+msgid "E258: Unable to send to client"
+msgstr "E258: Ní féidir aon rud a sheoladh chuig an chliant"
+
+msgid "E702: Sort compare function failed"
+msgstr "E702: Theip ar fheidhm chomparáide le linn sórtála"
+
+msgid "(Invalid)"
+msgstr "(Neamhbhailí)"
+
+msgid "E677: Error writing temp file"
+msgstr "E677: Earráid agus comhad sealadach á scríobh"
+
+msgid "E805: Using a Float as a Number"
+msgstr "E805: Snámhphointe á úsáid mar Uimhir"
+
+msgid "E703: Using a Funcref as a Number"
+msgstr "E703: Funcref á úsáid mar Uimhir"
+
+msgid "E745: Using a List as a Number"
+msgstr "E745: Liosta á úsáid mar Uimhir"
+
+msgid "E728: Using a Dictionary as a Number"
+msgstr "E728: Foclóir á úsáid mar Uimhir"
+
+msgid "E729: using Funcref as a String"
+msgstr "E729: Funcref á úsáid mar Theaghrán"
+
+msgid "E730: using List as a String"
+msgstr "E730: Liosta á úsáid mar Theaghrán"
+
+msgid "E731: using Dictionary as a String"
+msgstr "E731: Foclóir á úsáid mar Theaghrán"
+
+msgid "E806: using Float as a String"
+msgstr "E806: Snámhphointe á úsáid mar Theaghrán"
+
+#, 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"
+
+#, c-format
+msgid "E705: Variable name conflicts with existing function: %s"
+msgstr "E705: Tagann ainm athróige salach ar fheidhm atá ann cheana: %s"
+
+#, c-format
+msgid "E706: Variable type mismatch for: %s"
+msgstr "E706: Mímheaitseáil idir cineálacha athróige: %s"
+
+#, c-format
+msgid "E795: Cannot delete variable %s"
+msgstr "E795: Ní féidir athróg %s a scriosadh"
+
+#, c-format
+msgid "E741: Value is locked: %s"
+msgstr "E741: Tá an luach faoi ghlas: %s"
+
+msgid "Unknown"
+msgstr "Anaithnid"
+
+#, c-format
+msgid "E742: Cannot change value of %s"
+msgstr "E742: Ní féidir an luach de %s a athrú"
+
+msgid "E698: variable nested too deep for making a copy"
+msgstr "E698: athróg neadaithe ródhomhain chun í a chóipeáil"
+
+#, 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"
+
+#, c-format
+msgid "E125: Illegal argument: %s"
+msgstr "E125: Argóint neamhcheadaithe: %s"
+
+msgid "E126: Missing :endfunction"
+msgstr "E126: :endfunction ar iarraidh"
+
+#, 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"
+
+msgid "E129: Function name required"
+msgstr "E129: Tá gá le hainm feidhme"
+
+#, c-format
+msgid "E128: Function name must start with a capital or contain a colon: %s"
+msgstr ""
+"E128: Caithfidh ceannlitir a bheith ar dtús ainm feidhme, nó idirstad a "
+"bheith ann: %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 "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"
+
+#, c-format
+msgid "continuing in %s"
+msgstr "ag leanúint i %s"
+
+msgid "E133: :return not inside a function"
+msgstr "E133: Caithfidh :return a bheith isteach i bhfeidhm"
+
+#, c-format
+msgid ""
+"\n"
+"# global variables:\n"
+msgstr ""
+"\n"
+"# athróga comhchoiteanna:\n"
+
+msgid ""
+"\n"
+"\tLast set from "
+msgstr ""
+"\n"
+"\tSocraithe is déanaí ó "
+
+msgid "No old files"
+msgstr "Gan seanchomhaid"
+
+#, c-format
+msgid "<%s>%s%s %d, Hex %02x, Octal %03o"
+msgstr "<%s>%s%s %d, Heics %02x, Ocht %03o"
+
+#, c-format
+msgid "> %d, Hex %04x, Octal %o"
+msgstr "> %d, Heics %04x, Ocht %o"
+
+#, c-format
+msgid "> %d, Hex %08x, Octal %o"
+msgstr "> %d, Heics %08x, Ocht %o"
+
+msgid "E134: Move lines into themselves"
+msgstr "E134: Bog línte isteach iontu féin"
+
+msgid "1 line moved"
+msgstr "Bogadh líne amháin"
+
+#, c-format
+msgid "%ld lines moved"
+msgstr "Bogadh %ld líne"
+
+#, c-format
+msgid "%ld lines filtered"
+msgstr "Scagadh %ld líne"
+
+msgid "E135: *Filter* Autocommands must not change current buffer"
+msgstr ""
+"E135: Ní cheadaítear d'uathorduithe *scagaire* an maolán reatha a athrú"
+
+msgid "[No write since last change]\n"
+msgstr "[Athraithe agus nach sábháilte ó shin]\n"
+
+#, c-format
+msgid "%sviminfo: %s in line: "
+msgstr "%sviminfo: %s i líne: "
+
+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"
+
+#, c-format
+msgid "Reading viminfo file \"%s\"%s%s%s"
+msgstr "Comhad viminfo \"%s\"%s%s%s á léamh"
+
+msgid " info"
+msgstr " eolas"
+
+msgid " marks"
+msgstr " marcanna"
+
+msgid " oldfiles"
+msgstr " seanchomhad"
+
+msgid " FAILED"
+msgstr " TEIPTHE"
+
+#. avoid a wait_return for this message, it's annoying
+#, c-format
+msgid "E137: Viminfo file is not writable: %s"
+msgstr "E137: Níl an comhad Viminfo inscríofa: %s"
+
+#, c-format
+msgid "E138: Can't write viminfo file %s!"
+msgstr "E138: Ní féidir comhad viminfo %s a scríobh!"
+
+#, c-format
+msgid "Writing viminfo file \"%s\""
+msgstr "Comhad viminfo \"%s\" á scríobh"
+
+#. Write the info:
+#, c-format
+msgid "# This viminfo file was generated by Vim %s.\n"
+msgstr "# Chruthaigh Vim an comhad viminfo seo %s.\n"
+
+#, c-format
+msgid ""
+"# You may edit it if you're careful!\n"
+"\n"
+msgstr ""
+"# Is féidir leat an comhad seo a chur in eagar ach bí cúramach!\n"
+"\n"
+
+#, c-format
+msgid "# Value of 'encoding' when this file was written\n"
+msgstr "# Luach 'encoding' agus an comhad seo á scríobh\n"
+
+msgid "Illegal starting char"
+msgstr "Carachtar neamhcheadaithe tosaigh"
+
+msgid "Save As"
+msgstr "Sábháil Mar"
+
+msgid "Write partial file?"
+msgstr "Scríobh comhad neamhiomlán?"
+
+msgid "E140: Use ! to write partial buffer"
+msgstr "E140: Bain úsáid as ! chun maolán neamhiomlán a scríobh"
+
+#, c-format
+msgid "Overwrite existing file \"%s\"?"
+msgstr "Forscríobh comhad \"%s\" atá ann cheana?"
+
+#, c-format
+msgid "Swap file \"%s\" exists, overwrite anyway?"
+msgstr "Tá comhad babhtála \"%s\" ann cheana; forscríobh mar sin féin?"
+
+#, 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ú)"
+
+#, c-format
+msgid "E141: No file name for buffer %ld"
+msgstr "E141: Níl aon ainm ar mhaolán %ld"
+
+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'"
+
+#, c-format
+msgid ""
+"'readonly' option is set for \"%s\".\n"
+"Do you wish to write anyway?"
+msgstr ""
+"tá an rogha 'readonly' socraithe do \"%s\".\n"
+"Ar mhaith leat é a scríobh mar sin féin?"
+
+#, 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á comhad \"%s\" inléite amháin.\n"
+"Seans gurbh fhéidir scríobh ann mar sin féin.\n"
+"An bhfuil fonn ort triail a bhaint as?"
+
+#, 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ú)"
+
+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"
+
+msgid "E144: non-numeric argument to :z"
+msgstr "E144: argóint neamhuimhriúil chun :z"
+
+msgid "E145: Shell commands not allowed in rvim"
+msgstr "E145: Ní cheadaítear orduithe blaoisce i rvim"
+
+msgid "E146: Regular expressions can't be delimited by letters"
+msgstr ""
+"E146: Ní cheadaítear litreacha mar theormharcóirí ar shloinn ionadaíochta"
+
+#, 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)?"
+
+msgid "(Interrupted) "
+msgstr "(Idirbhriste) "
+
+msgid "1 match"
+msgstr "1 rud comhoiriúnach"
+
+msgid "1 substitution"
+msgstr "1 ionadaíocht"
+
+#, c-format
+msgid "%ld matches"
+msgstr "%ld rud comhoiriúnach"
+
+#, c-format
+msgid "%ld substitutions"
+msgstr "%ld ionadaíocht"
+
+msgid " on 1 line"
+msgstr " ar líne amháin"
+
+#, c-format
+msgid " on %ld lines"
+msgstr " ar %ld líne"
+
+msgid "E147: Cannot do :global recursive"
+msgstr "E147: Ní cheadaítear :global go hathchúrsach"
+
+# should have ":"
+msgid "E148: Regular expression missing from global"
+msgstr "E148: Slonn ionadaíochta ar iarraidh ó :global"
+
+#, c-format
+msgid "Pattern found in every line: %s"
+msgstr "Aimsíodh an patrún i ngach líne: %s"
+
+#, c-format
+msgid ""
+"\n"
+"# Last Substitute String:\n"
+"$"
+msgstr ""
+"\n"
+"# Teaghrán Ionadach Is Déanaí:\n"
+"$"
+
+msgid "E478: Don't panic!"
+msgstr "E478: Ná téigh i scaoll!"
+
+#, c-format
+msgid "E661: Sorry, no '%s' help for %s"
+msgstr "E661: Tá brón orm, ní aon chabhair '%s' do %s"
+
+#, c-format
+msgid "E149: Sorry, no help for %s"
+msgstr "E149: Tá brón orm, níl aon chabhair do %s"
+
+#, c-format
+msgid "Sorry, help file \"%s\" not found"
+msgstr "Tá brón orm, comhad cabhrach \"%s\" gan aimsiú"
+
+#, c-format
+msgid "E150: Not a directory: %s"
+msgstr "E150: Ní comhadlann é: %s"
+
+#, c-format
+msgid "E152: Cannot open %s for writing"
+msgstr "E152: Ní féidir %s a oscailt chun scríobh ann"
+
+#, c-format
+msgid "E153: Unable to open %s for reading"
+msgstr "E153: Ní féidir %s a oscailt chun é a léamh"
+
+#, 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"
+
+#, c-format
+msgid "E154: Duplicate tag \"%s\" in file %s/%s"
+msgstr "E154: Clib dhúblach \"%s\" i gcomhad %s/%s"
+
+#, c-format
+msgid "E160: Unknown sign command: %s"
+msgstr "E160: Ordú anaithnid comhartha: %s"
+
+msgid "E156: Missing sign name"
+msgstr "E156: Ainm comhartha ar iarraidh"
+
+msgid "E612: Too many signs defined"
+msgstr "E612: An iomarca comharthaí sainmhínithe"
+
+#, c-format
+msgid "E239: Invalid sign text: %s"
+msgstr "E239: Téacs neamhbhailí comhartha: %s"
+
+#, c-format
+msgid "E155: Unknown sign: %s"
+msgstr "E155: Comhartha anaithnid: %s"
+
+msgid "E159: Missing sign number"
+msgstr "E159: Uimhir chomhartha ar iarraidh"
+
+#, c-format
+msgid "E158: Invalid buffer name: %s"
+msgstr "E158: Ainm maoláin neamhbhailí: %s"
+
+#, c-format
+msgid "E157: Invalid sign ID: %ld"
+msgstr "E157: ID neamhbhailí comhartha: %ld"
+
+msgid " (NOT FOUND)"
+msgstr " (AR IARRAIDH)"
+
+msgid " (not supported)"
+msgstr " (níl an rogha seo ar fáil)"
+
+msgid "[Deleted]"
+msgstr "[Scriosta]"
+
+msgid "Entering Debug mode. Type \"cont\" to continue."
+msgstr "Mód dífhabhtaithe á thosú. Clóscríobh \"cont\" chun leanúint."
+
+#, c-format
+msgid "line %ld: %s"
+msgstr "líne %ld: %s"
+
+#, c-format
+msgid "cmd: %s"
+msgstr "ordú: %s"
+
+#, c-format
+msgid "Breakpoint in \"%s%s\" line %ld"
+msgstr "Brisphointe i \"%s%s\" líne %ld"
+
+#, c-format
+msgid "E161: Breakpoint not found: %s"
+msgstr "E161: Brisphointe gan aimsiú: %s"
+
+msgid "No breakpoints defined"
+msgstr "Níl aon bhrisphointe socraithe"
+
+#, c-format
+msgid "%3d %s %s line %ld"
+msgstr "%3d %s %s líne %ld"
+
+msgid "E750: First use \":profile start {fname}\""
+msgstr "E750: Úsáid \":profile start {ainm}\" ar dtús"
+
+#, c-format
+msgid "Save changes to \"%s\"?"
+msgstr "Sábháil athruithe ar \"%s\"?"
+
+msgid "Untitled"
+msgstr "Gan Teideal"
+
+#, 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"
+
+msgid "Warning: Entered other buffer unexpectedly (check autocommands)"
+msgstr "Rabhadh: Chuathas i maolán eile go tobann (seiceáil na huathorduithe)"
+
+msgid "E163: There is only one file to edit"
+msgstr "E163: Níl ach aon chomhad amháin le cur in eagar"
+
+msgid "E164: Cannot go before first file"
+msgstr "E164: Ní féidir a dhul roimh an chéad chomhad"
+
+msgid "E165: Cannot go beyond last file"
+msgstr "E165: Ní féidir a dhul thar an gcomhad deireanach"
+
+#, c-format
+msgid "E666: compiler not supported: %s"
+msgstr "E666: ní ghlactar leis an tiomsaitheoir: %s"
+
+#, c-format
+msgid "Searching for \"%s\" in \"%s\""
+msgstr "Ag déanamh cuardach ar \"%s\" i \"%s\""
+
+#, c-format
+msgid "Searching for \"%s\""
+msgstr "Ag déanamh cuardach ar \"%s\""
+
+#, c-format
+msgid "not found in 'runtimepath': \"%s\""
+msgstr "gan aimsiú i 'runtimepath': \"%s\""
+
+msgid "Source Vim script"
+msgstr "Foinsigh script Vim"
+
+#, c-format
+msgid "Cannot source a directory: \"%s\""
+msgstr "Ní féidir comhadlann a léamh: \"%s\""
+
+#, c-format
+msgid "could not source \"%s\""
+msgstr "níorbh fhéidir \"%s\" a léamh"
+
+#, c-format
+msgid "line %ld: could not source \"%s\""
+msgstr "líne %ld: níorbh fhéidir \"%s\" a fhoinsiú"
+
+#, c-format
+msgid "sourcing \"%s\""
+msgstr "\"%s\" á fhoinsiú"
+
+#, c-format
+msgid "line %ld: sourcing \"%s\""
+msgstr "líne %ld: \"%s\" á fhoinsiú"
+
+#, c-format
+msgid "finished sourcing %s"
+msgstr "deireadh ag foinsiú %s"
+
+msgid "modeline"
+msgstr "módlíne"
+
+msgid "--cmd argument"
+msgstr "argóint --cmd"
+
+msgid "-c argument"
+msgstr "argóint -c"
+
+msgid "environment variable"
+msgstr "athróg thimpeallachta"
+
+msgid "error handler"
+msgstr "láimhseálaí earráidí"
+
+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"
+
+msgid "E167: :scriptencoding used outside of a sourced file"
+msgstr "E167: ní úsáidtear :scriptencoding ach i gcomhad foinsithe"
+
+msgid "E168: :finish used outside of a sourced file"
+msgstr "E168: ní úsáidtear :finish ach i gcomhaid foinsithe"
+
+#, c-format
+msgid "Current %slanguage: \"%s\""
+msgstr "%sTeanga faoi láthair: \"%s\""
+
+#, c-format
+msgid "E197: Cannot set language to \"%s\""
+msgstr "E197: Ní féidir an teanga a shocrú mar \"%s\""
+
+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
+msgid "E501: At end-of-file"
+msgstr "E501: Ag an chomhadchríoch"
+
+msgid "E169: Command too recursive"
+msgstr "E169: Ordú ró-athchúrsach"
+
+#, c-format
+msgid "E605: Exception not caught: %s"
+msgstr "E605: Eisceacht gan láimhseáil: %s"
+
+msgid "End of sourced file"
+msgstr "Críoch chomhaid foinsithe"
+
+msgid "End of function"
+msgstr "Críoch fheidhme"
+
+msgid "E464: Ambiguous use of user-defined command"
+msgstr "E464: Úsáid athbhríoch d'ordú saincheaptha"
+
+msgid "E492: Not an editor command"
+msgstr "E492: Níl ina ordú eagarthóra"
+
+msgid "E493: Backwards range given"
+msgstr "E493: Raon droim ar ais"
+
+msgid "Backwards range given, OK to swap"
+msgstr "Raon droim ar ais, babhtáil"
+
+msgid "E494: Use w or w>>"
+msgstr "E494: Bain úsáid as w nó w>>"
+
+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"
+
+msgid "E172: Only one file name allowed"
+msgstr "E172: Ní cheadaítear ach aon ainm comhaid amháin"
+
+msgid "1 more file to edit. Quit anyway?"
+msgstr "1 comhad le cur in eagar fós. Scoir mar sin féin?"
+
+#, c-format
+msgid "%d more files to edit. Quit anyway?"
+msgstr "%d comhad le cur in eagar fós. Scoir mar sin féin?"
+
+msgid "E173: 1 more file to edit"
+msgstr "E173: 1 chomhad le heagrú fós"
+
+#, c-format
+msgid "E173: %ld more files to edit"
+msgstr "E173: %ld comhad le cur in eagar"
+
+msgid "E174: Command already exists: add ! to replace it"
+msgstr "E174: Tá an t-ordú ann cheana: cuir ! leis chun sárú"
+
+msgid ""
+"\n"
+" Name Args Range Complete Definition"
+msgstr ""
+"\n"
+" Ainm Arg Raon Iomlán Sainmhíniú"
+
+msgid "No user-defined commands found"
+msgstr "Níl aon ordú aimsithe atá sainithe ag an úsáideoir"
+
+msgid "E175: No attribute specified"
+msgstr "E175: Níl aon aitreabúid sainithe"
+
+msgid "E176: Invalid number of arguments"
+msgstr "E176: Tá líon na n-argóintí mícheart"
+
+msgid "E177: Count cannot be specified twice"
+msgstr "E177: Ní cheadaítear an t-áireamh a bheith tugtha faoi dhó"
+
+msgid "E178: Invalid default value for count"
+msgstr "E178: Luach réamhshocraithe neamhbhailí ar áireamh"
+
+msgid "E179: argument required for -complete"
+msgstr "E179: tá gá le hargóint i ndiaidh -complete"
+
+#, c-format
+msgid "E181: Invalid attribute: %s"
+msgstr "E181: Aitreabúid neamhbhailí: %s"
+
+msgid "E182: Invalid command name"
+msgstr "E182: Ainm neamhbhailí ordaithe"
+
+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"
+
+#, c-format
+msgid "E184: No such user-defined command: %s"
+msgstr "E184: Níl a leithéid d'ordú saincheaptha: %s"
+
+#, c-format
+msgid "E180: Invalid complete value: %s"
+msgstr "E180: Luach iomlán neamhbhailí: %s"
+
+msgid "E468: Completion argument only allowed for custom completion"
+msgstr ""
+"E468: Ní cheadaítear argóint chomhlánaithe ach le comhlánú saincheaptha"
+
+msgid "E467: Custom completion requires a function argument"
+msgstr "E467: Tá gá le hargóint fheidhme le comhlánú saincheaptha"
+
+#, c-format
+msgid "E185: Cannot find color scheme %s"
+msgstr "E185: Scéim dathanna %s gan aimsiú"
+
+msgid "Greetings, Vim user!"
+msgstr "Dia duit, a úsáideoir Vim!"
+
+msgid "E784: Cannot close last tab page"
+msgstr "E784: Ní féidir an leathanach cluaisín deiridh a dhúnadh"
+
+msgid "Already only one tab page"
+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"
+
+#, c-format
+msgid "Tab page %d"
+msgstr "Leathanach cluaisín %d"
+
+msgid "No swap file"
+msgstr "Níl aon chomhad babhtála ann"
+
+msgid "Append File"
+msgstr "Cuir Comhad i nDeireadh"
+
+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ú)"
+
+msgid "E186: No previous directory"
+msgstr "E186: Níl aon chomhadlann roimhe seo"
+
+msgid "E187: Unknown"
+msgstr "E187: Anaithnid"
+
+msgid "E465: :winsize requires two number arguments"
+msgstr "E465: ní foláir dhá argóint uimhriúla le :winsize"
+
+#, 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"
+
+msgid "E466: :winpos requires two number arguments"
+msgstr "E466: ní foláir dhá argóint uimhriúla le :winpos"
+
+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ú"
+
+#, c-format
+msgid "E739: Cannot create directory: %s"
+msgstr "E739: Ní féidir comhadlann a chruthú: %s"
+
+#, c-format
+msgid "E189: \"%s\" exists (add ! to override)"
+msgstr "E189: Tá \"%s\" ann cheana (cuir ! leis an ordú chun sárú)"
+
+#, c-format
+msgid "E190: Cannot open \"%s\" for writing"
+msgstr "E190: Ní féidir \"%s\" a oscailt chun léamh"
+
+#. set mark
+msgid "E191: Argument must be a letter or forward/backward quote"
+msgstr "E191: Caithfidh an argóint a bheith litir nó comhartha athfhriotal"
+
+msgid "E192: Recursive use of :normal too deep"
+msgstr "E192: athchúrsáil :normal ródhomhain"
+
+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 '#'"
+
+msgid "E495: no autocommand file name to substitute for \"<afile>\""
+msgstr "E495: níl aon ainm comhaid uathordaithe le cur in ionad \"<afile>\""
+
+msgid "E496: no autocommand buffer number to substitute for \"<abuf>\""
+msgstr "E496: níl aon uimhir mhaolán uathordaithe le cur in ionad \"<abuf>\""
+
+msgid "E497: no autocommand match name to substitute for \"<amatch>\""
+msgstr ""
+"E497: níl aon ainm meaitseála uathordaithe le cur in ionad \"<amatch>\""
+
+msgid "E498: no :source file name to substitute for \"<sfile>\""
+msgstr "E498: níl aon ainm comhaid :source le cur in ionad \"<sfile>\""
+
+#, 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"
+
+msgid "E500: Evaluates to an empty string"
+msgstr "E500: Luacháiltear é seo mar theaghrán folamh"
+
+msgid "E195: Cannot open viminfo file for reading"
+msgstr "E195: Ní féidir an comhad viminfo a oscailt chun léamh"
+
+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
+#, c-format
+msgid "Exception thrown: %s"
+msgstr "Gineadh eisceacht: %s"
+
+#, c-format
+msgid "Exception finished: %s"
+msgstr "Eisceacht curtha i gcrích: %s"
+
+#, c-format
+msgid "Exception discarded: %s"
+msgstr "Eisceacht curtha i leataobh: %s"
+
+#, c-format
+msgid "%s, line %ld"
+msgstr "%s, líne %ld"
+
+#. always scroll up, don't overwrite
+#, c-format
+msgid "Exception caught: %s"
+msgstr "Láimhseáladh eisceacht: %s"
+
+#, c-format
+msgid "%s made pending"
+msgstr "%s ar feitheamh anois"
+
+#, c-format
+msgid "%s resumed"
+msgstr "atosaíodh %s"
+
+#, c-format
+msgid "%s discarded"
+msgstr "%s curtha i leataobh"
+
+msgid "Exception"
+msgstr "Eisceacht"
+
+msgid "Error and interrupt"
+msgstr "Earráid agus idirbhriseadh"
+
+msgid "Error"
+msgstr "Earráid"
+
+#. if (pending & CSTP_INTERRUPT)
+msgid "Interrupt"
+msgstr "Idirbhriseadh"
+
+msgid "E579: :if nesting too deep"
+msgstr "E579: :if neadaithe ródhomhain"
+
+msgid "E580: :endif without :if"
+msgstr "E580: :endif gan :if"
+
+msgid "E581: :else without :if"
+msgstr "E581: :else gan :if"
+
+msgid "E582: :elseif without :if"
+msgstr "E582: :elseif gan :if"
+
+msgid "E583: multiple :else"
+msgstr "E583: :else iomadúla"
+
+msgid "E584: :elseif after :else"
+msgstr "E584: :elseif i ndiaidh :else"
+
+msgid "E585: :while/:for nesting too deep"
+msgstr "E585: :while/:for neadaithe ródhomhain"
+
+msgid "E586: :continue without :while or :for"
+msgstr "E586: :continue gan :while ná :for"
+
+msgid "E587: :break without :while or :for"
+msgstr "E587: :break gan :while ná :for"
+
+msgid "E732: Using :endfor with :while"
+msgstr "E732: :endfor á úsáid le :while"
+
+msgid "E733: Using :endwhile with :for"
+msgstr "E733: :endwhile á úsáid le :for"
+
+msgid "E601: :try nesting too deep"
+msgstr "E601: :try neadaithe ródhomhain"
+
+msgid "E603: :catch without :try"
+msgstr "E603: :catch gan :try"
+
+#. Give up for a ":catch" after ":finally" and ignore it.
+#. * Just parse.
+msgid "E604: :catch after :finally"
+msgstr "E604: :catch i ndiaidh :finally"
+
+msgid "E606: :finally without :try"
+msgstr "E606: :finally gan :try"
+
+#. Give up for a multiple ":finally" and ignore it.
+msgid "E607: multiple :finally"
+msgstr "E607: :finally iomadúla"
+
+msgid "E602: :endtry without :try"
+msgstr "E602: :endtry gan :try"
+
+msgid "E193: :endfunction not inside a function"
+msgstr "E193: Caithfidh :endfunction a bheith isteach i bhfeidhm"
+
+msgid "E788: Not allowed to edit another buffer now"
+msgstr "E788: Níl cead agat maolán eile a chur in eagar anois"
+
+msgid "E811: Not allowed to change buffer information now"
+msgstr "E811: Níl cead agat faisnéis an mhaoláin a athrú anois"
+
+msgid "tagname"
+msgstr "clibainm"
+
+msgid " kind file\n"
+msgstr " cineál comhaid\n"
+
+msgid "'history' option is zero"
+msgstr "tá an rogha 'history' nialas"
+
+#, c-format
+msgid ""
+"\n"
+"# %s History (newest to oldest):\n"
+msgstr ""
+"\n"
+"# %s Stair (is nuaí go dtí is sine):\n"
+
+# this gets plugged into the %s in the previous string,
+# hence the colon
+msgid "Command Line"
+msgstr "Líne na nOrduithe:"
+
+msgid "Search String"
+msgstr "Teaghrán Cuardaigh"
+
+msgid "Expression"
+msgstr "Sloinn:"
+
+msgid "Input Line"
+msgstr "Líne an Ionchuir:"
+
+msgid "E198: cmd_pchar beyond the command length"
+msgstr "E198: cmd_pchar os cionn fad an ordaithe"
+
+msgid "E199: Active window or buffer deleted"
+msgstr "E199: Scriosadh an fhuinneog reatha nó an maolán reatha"
+
+msgid "E812: Autocommands changed buffer or buffer name"
+msgstr ""
+"E812: Bhí maolán nó ainm maoláin athraithe ag orduithe uathoibríocha"
+
+msgid "Illegal file name"
+msgstr "Ainm comhaid neamhcheadaithe"
+
+msgid "is a directory"
+msgstr "is comhadlann é"
+
+msgid "is not a file"
+msgstr "ní comhad é"
+
+msgid "is a device (disabled with 'opendevice' option)"
+msgstr "is gléas é seo (díchumasaithe le rogha 'opendevice')"
+
+msgid "[New File]"
+msgstr "[Comhad Nua]"
+
+msgid "[New DIRECTORY]"
+msgstr "[COMHADLANN nua]"
+
+msgid "[File too big]"
+msgstr "[Comhad rómhór]"
+
+msgid "[Permission Denied]"
+msgstr "[Cead Diúltaithe]"
+
+msgid "E200: *ReadPre autocommands made the file unreadable"
+msgstr "E200: Rinne uathorduithe *ReadPre praiseach as an chomhad"
+
+msgid "E201: *ReadPre autocommands must not change current buffer"
+msgstr "E201: Ní cheadaítear d'uathorduithe *ReadPre an maolán reatha a athrú"
+
+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!
+msgid "E202: Conversion made file unreadable!"
+msgstr "E202: Comhad doléite i ndiaidh an tiontaithe!"
+
+msgid "[fifo/socket]"
+msgstr "[fifo/soicéad]"
+
+# `TITA' ?! -KPS
+msgid "[fifo]"
+msgstr "[fifo]"
+
+msgid "[socket]"
+msgstr "[soicéad]"
+
+msgid "[character special]"
+msgstr "[comhad speisialta den chineál carachtar]"
+
+msgid "[RO]"
+msgstr "[L-A]"
+
+msgid "[CR missing]"
+msgstr "[CR ar iarraidh]"
+
+msgid "[long lines split]"
+msgstr "[línte fada deighilte]"
+
+msgid "[NOT converted]"
+msgstr "[NÍ tiontaithe]"
+
+msgid "[converted]"
+msgstr "[tiontaithe]"
+
+msgid "[crypted]"
+msgstr "[criptithe]"
+
+#, c-format
+msgid "[CONVERSION ERROR in line %ld]"
+msgstr "[EARRÁID TIONTAITHE i líne %ld]"
+
+#, c-format
+msgid "[ILLEGAL BYTE in line %ld]"
+msgstr "[BEART NEAMHCHEADAITHE i líne %ld]"
+
+msgid "[READ ERRORS]"
+msgstr "[EARRÁIDÍ LÉIMH]"
+
+msgid "Can't find temp file for conversion"
+msgstr "Ní féidir comhad sealadach a aimsiú le haghaidh tiontaithe"
+
+msgid "Conversion with 'charconvert' failed"
+msgstr "Theip ar thiontú le 'charconvert'"
+
+msgid "can't read output of 'charconvert'"
+msgstr "ní féidir an t-aschur ó 'charconvert' a léamh"
+
+msgid "E676: No matching autocommands for acwrite buffer"
+msgstr "E676: Níl aon uathordú comhoiriúnaithe le haghaidh maoláin acwrite"
+
+msgid "E203: Autocommands deleted or unloaded buffer to be written"
+msgstr "E203: Scrios nó dhíluchtaigh uathorduithe an maolán le scríobh"
+
+msgid "E204: Autocommand changed number of lines in unexpected way"
+msgstr "E204: D'athraigh uathordú líon na línte gan choinne"
+
+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 á"
+
+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ú)"
+
+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ú)"
+
+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ú)"
+
+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ú)"
+
+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ú)"
+
+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ú)"
+
+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"
+
+msgid "E213: Cannot convert (add ! to write without conversion)"
+msgstr "E213: Ní féidir tiontú (cuir ! leis an ordú chun scríobh gan tiontú)"
+
+msgid "E166: Can't open linked file for writing"
+msgstr "E166: Ní féidir comhad nasctha a oscailt chun scríobh ann"
+
+msgid "E212: Can't open file for writing"
+msgstr "E212: Ní féidir comhad a oscailt chun scríobh ann"
+
+msgid "E667: Fsync failed"
+msgstr "E667: Theip ar fsync"
+
+msgid "E512: Close failed"
+msgstr "E512: Theip ar dúnadh"
+
+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ú)"
+
+#, c-format
+msgid ""
+"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 %ld (úsáid 'fenc' folamh le "
+"sárú)"
+
+msgid "E514: write error (file system full?)"
+msgstr "E514: earráid le linn scríofa (an bhfuil an córas comhaid lán?)"
+
+msgid " CONVERSION ERROR"
+msgstr " EARRÁID TIONTAITHE"
+
+#, c-format
+msgid " in line %ld;"
+msgstr " ar líne %ld;"
+
+msgid "[Device]"
+msgstr "[Gléas]"
+
+msgid "[New]"
+msgstr "[Nua]"
+
+msgid " [a]"
+msgstr " [a]"
+
+msgid " appended"
+msgstr " iarcheangailte"
+
+msgid " [w]"
+msgstr " [w]"
+
+msgid " written"
+msgstr " scríofa"
+
+msgid "E205: Patchmode: can't save original file"
+msgstr "E205: Patchmode: ní féidir an comhad bunúsach a shábháil"
+
+msgid "E206: patchmode: can't touch empty original file"
+msgstr "E206: patchmode: ní féidir an comhad bunúsach folamh a theagmháil"
+
+msgid "E207: Can't delete backup file"
+msgstr "E207: Ní féidir an comhad cúltaca a scriosadh"
+
+msgid ""
+"\n"
+"WARNING: Original file may be lost or damaged\n"
+msgstr ""
+"\n"
+"RABHADH: Is féidir gur caillte nó loite an comhad bunúsach\n"
+
+msgid "don't quit the editor until the file is successfully written!"
+msgstr "ná scoir go dtí go scríobhfaí an comhad!"
+
+msgid "[dos]"
+msgstr "[dos]"
+
+msgid "[dos format]"
+msgstr "[formáid dos]"
+
+msgid "[mac]"
+msgstr "[mac]"
+
+msgid "[mac format]"
+msgstr "[formáid mac]"
+
+msgid "[unix]"
+msgstr "[unix]"
+
+msgid "[unix format]"
+msgstr "[formáid unix]"
+
+msgid "1 line, "
+msgstr "1 líne, "
+
+#, c-format
+msgid "%ld lines, "
+msgstr "%ld líne, "
+
+msgid "1 character"
+msgstr "1 carachtar"
+
+#, c-format
+msgid "%ld characters"
+msgstr "%ld carachtar"
+
+msgid "[noeol]"
+msgstr "[ganEOL]"
+
+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
+msgid "WARNING: The file has been changed since reading it!!!"
+msgstr "RABHADH: Athraíodh an comhad ó léadh é!!!"
+
+msgid "Do you really want to write to it"
+msgstr "An bhfuil tú cinnte gur mhaith leat é a scríobh"
+
+#, c-format
+msgid "E208: Error writing to \"%s\""
+msgstr "E208: Earráid agus \"%s\" á scríobh"
+
+#, c-format
+msgid "E209: Error closing \"%s\""
+msgstr "E209: Earráid agus \"%s\" á dhúnadh"
+
+#, c-format
+msgid "E210: Error reading \"%s\""
+msgstr "E210: Earráid agus \"%s\" á léamh"
+
+msgid "E246: FileChangedShell autocommand deleted buffer"
+msgstr "E246: Scrios uathordú FileChangedShell an maolán"
+
+#, c-format
+msgid "E211: File \"%s\" no longer available"
+msgstr "E211: Níl comhad \"%s\" ar fáil feasta"
+
+#, c-format
+msgid ""
+"W12: Warning: File \"%s\" has changed and the buffer was changed in Vim as "
+"well"
+msgstr ""
+"W12: Rabhadh: Athraíodh comhad \"%s\" agus athraíodh an maolán i Vim fosta"
+
+msgid "See \":help W12\" for more info."
+msgstr "Bain triail as \":help W12\" chun tuilleadh eolais a fháil."
+
+#, 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"
+
+msgid "See \":help W11\" for more info."
+msgstr "Bain triail as \":help W11\" chun tuilleadh eolais a fháil."
+
+#, 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"
+
+msgid "See \":help W16\" for more info."
+msgstr "Bain triail as \":help W16\" chun tuilleadh eolais a fháil."
+
+#, 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"
+
+msgid "Warning"
+msgstr "Rabhadh"
+
+msgid ""
+"&OK\n"
+"&Load File"
+msgstr ""
+"&OK\n"
+"&Luchtaigh Comhad"
+
+#, c-format
+msgid "E462: Could not prepare for reloading \"%s\""
+msgstr "E462: Ní féidir \"%s\" a ullmhú le haghaidh athluchtaithe"
+
+#, c-format
+msgid "E321: Could not reload \"%s\""
+msgstr "E321: Ní féidir \"%s\" a athluchtú"
+
+msgid "--Deleted--"
+msgstr "--Scriosta--"
+
+#, c-format
+msgid "auto-removing autocommand: %s <buffer=%d>"
+msgstr "uathordú á bhaint go huathoibríoch: %s <maolán=%d>"
+
+#. the group doesn't exist
+#, c-format
+msgid "E367: No such group: \"%s\""
+msgstr "E367: Níl a leithéid de ghrúpa: \"%s\""
+
+#, c-format
+msgid "E215: Illegal character after *: %s"
+msgstr "E215: Carachtar neamhcheadaithe i ndiaidh *: %s"
+
+#, c-format
+msgid "E216: No such event: %s"
+msgstr "E216: Níl a leithéid de theagmhas: %s"
+
+#, 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
+msgid ""
+"\n"
+"--- Auto-Commands ---"
+msgstr ""
+"\n"
+"--- Uathorduithe ---"
+
+#, c-format
+msgid "E680: <buffer=%d>: invalid buffer number "
+msgstr "E680: <maolán=%d>: uimhir neamhbhailí mhaoláin "
+
+msgid "E217: Can't execute autocommands for ALL events"
+msgstr "E217: Ní féidir uathorduithe a rith i gcomhair teagmhas UILE"
+
+msgid "No matching autocommands"
+msgstr "Níl aon uathordú comhoiriúnaithe"
+
+msgid "E218: autocommand nesting too deep"
+msgstr "E218: uathordú neadaithe ródhomhain"
+
+#, c-format
+msgid "%s Auto commands for \"%s\""
+msgstr "%s Uathorduithe do \"%s\""
+
+#, c-format
+msgid "Executing %s"
+msgstr "%s á rith"
+
+#, c-format
+msgid "autocommand %s"
+msgstr "uathordú %s"
+
+msgid "E219: Missing {."
+msgstr "E219: { ar iarraidh."
+
+msgid "E220: Missing }."
+msgstr "E220: } ar iarraidh."
+
+msgid "E490: No fold found"
+msgstr "E490: Níor aimsíodh aon fhilleadh"
+
+msgid "E350: Cannot create fold with current 'foldmethod'"
+msgstr "E350: Ní féidir filleadh a chruthú leis an 'foldmethod' reatha"
+
+msgid "E351: Cannot delete fold with current 'foldmethod'"
+msgstr "E351: Ní féidir filleadh a scriosadh leis an 'foldmethod' reatha"
+
+#, c-format
+msgid "+--%3ld lines folded "
+msgstr "+--%3ld líne fillte "
+
+msgid "E222: Add to read buffer"
+msgstr "E222: Cuir leis an maolán léite"
+
+msgid "E223: recursive mapping"
+msgstr "E223: mapáil athchúrsach"
+
+#, c-format
+msgid "E224: global abbreviation already exists for %s"
+msgstr "E224: tá giorrúchán comhchoiteann ann cheana le haghaidh %s"
+
+#, c-format
+msgid "E225: global mapping already exists for %s"
+msgstr "E225: tá mapáil chomhchoiteann ann cheana le haghaidh %s"
+
+#, c-format
+msgid "E226: abbreviation already exists for %s"
+msgstr "E226: tá giorrúchán ann cheana le haghaidh %s"
+
+#, c-format
+msgid "E227: mapping already exists for %s"
+msgstr "E227: tá mapáil ann cheana le haghaidh %s"
+
+msgid "No abbreviation found"
+msgstr "Níor aimsíodh aon ghiorrúchán"
+
+msgid "No mapping found"
+msgstr "Níor aimsíodh aon mhapáil"
+
+msgid "E228: makemap: Illegal mode"
+msgstr "E228: makemap: Mód neamhcheadaithe"
+
+msgid "E229: Cannot start the GUI"
+msgstr "E229: Ní féidir an GUI a chur ag obair"
+
+#, c-format
+msgid "E230: Cannot read from \"%s\""
+msgstr "E230: Ní féidir léamh ó \"%s\""
+
+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 "E231: 'guifontwide' invalid"
+msgstr "E231: 'guifontwide' neamhbhailí"
+
+msgid "E599: Value of 'imactivatekey' is invalid"
+msgstr "E599: Luach neamhbhailí ar 'imactivatekey'"
+
+#, c-format
+msgid "E254: Cannot allocate color %s"
+msgstr "E254: Ní féidir dath %s a dháileadh"
+
+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"
+
+msgid "<cannot open> "
+msgstr "<ní féidir a oscailt> "
+
+#, c-format
+msgid "E616: vim_SelFile: can't get font %s"
+msgstr "E616: vim_SelFile: níl aon fháil ar an chlófhoireann %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 "Pathname:"
+msgstr "Conair:"
+
+msgid "E615: vim_SelFile: can't get current directory"
+msgstr "E615: vim_SelFile: níl an chomhadlann reatha ar fáil"
+
+msgid "OK"
+msgstr "OK"
+
+msgid "Cancel"
+msgstr "Cealaigh"
+
+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."
+
+msgid "Vim dialog"
+msgstr "Dialóg Vim"
+
+msgid "E232: Cannot create BalloonEval with both message and callback"
+msgstr ""
+"E232: Ní féidir BalloonEval a chruthú le teachtaireacht agus aisghlaoch araon"
+
+msgid "Vim dialog..."
+msgstr "Dialóg Vim..."
+
+msgid ""
+"&Yes\n"
+"&No\n"
+"&Cancel"
+msgstr ""
+"&Tá\n"
+"&Níl\n"
+"&Cealaigh"
+
+msgid "Input _Methods"
+msgstr "_Modhanna ionchuir"
+
+# in OLT --KPS
+msgid "VIM - Search and Replace..."
+msgstr "VIM - Cuardaigh agus Athchuir..."
+
+msgid "VIM - Search..."
+msgstr "VIM - Cuardaigh..."
+
+msgid "Find what:"
+msgstr "Aimsigh:"
+
+msgid "Replace with:"
+msgstr "Le cur in ionad:"
+
+#. whole word only button
+msgid "Match whole word only"
+msgstr "Focal iomlán amháin"
+
+#. match case button
+msgid "Match case"
+msgstr "Meaitseáil an cás"
+
+msgid "Direction"
+msgstr "Treo"
+
+#. 'Up' and 'Down' buttons
+msgid "Up"
+msgstr "Suas"
+
+msgid "Down"
+msgstr "Síos"
+
+msgid "Find Next"
+msgstr "An Chéad Cheann Eile"
+
+msgid "Replace"
+msgstr "Ionadaigh"
+
+msgid "Replace All"
+msgstr "Ionadaigh Uile"
+
+msgid "Vim: Received \"die\" request from session manager\n"
+msgstr "Vim: Fuarthas iarratas \"die\" ó bhainisteoir an tseisiúin\n"
+
+msgid "Close"
+msgstr "Dún"
+
+msgid "New tab"
+msgstr "Cluaisín nua"
+
+msgid "Open Tab..."
+msgstr "Oscail Cluaisín..."
+
+msgid "Vim: Main window unexpectedly destroyed\n"
+msgstr "Vim: Milleadh an príomhfhuinneog gan choinne\n"
+
+msgid "Font Selection"
+msgstr "Roghnú Cló"
+
+msgid "&Filter"
+msgstr "&Scagaire"
+
+msgid "&Cancel"
+msgstr "&Cealaigh"
+
+msgid "Directories"
+msgstr "Comhadlanna"
+
+msgid "Filter"
+msgstr "Scagaire"
+
+msgid "&Help"
+msgstr "&Cabhair"
+
+msgid "Files"
+msgstr "Comhaid"
+
+msgid "&OK"
+msgstr "&OK"
+
+msgid "Selection"
+msgstr "Roghnú"
+
+msgid "Find &Next"
+msgstr "An Chéad Chea&nn Eile"
+
+msgid "&Replace"
+msgstr "&Ionadaigh"
+
+msgid "Replace &All"
+msgstr "Ionadaigh &Uile"
+
+msgid "&Undo"
+msgstr "&Cealaigh"
+
+#, c-format
+msgid "E671: Cannot find window title \"%s\""
+msgstr "E671: Ní féidir teideal na fuinneoige \"%s\" a aimsiú"
+
+#, 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."
+
+msgid "E672: Unable to open window inside MDI application"
+msgstr "E672: Ní féidir fuinneog a oscailt isteach i bhfeidhmchlár MDI"
+
+msgid "Close tab"
+msgstr "Dún cluaisín"
+
+msgid "Open tab..."
+msgstr "Oscail cluaisín..."
+
+msgid "Find string (use '\\\\' to find a '\\')"
+msgstr "Aimsigh teaghrán (bain úsáid as '\\\\' chun '\\' a aimsiú)"
+
+msgid "Find & Replace (use '\\\\' to find a '\\')"
+msgstr "Aimsigh & Athchuir (úsáid '\\\\' chun '\\' a aimsiú)"
+
+#. 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"
+
+msgid "Directory\t*.nothing\n"
+msgstr "Comhadlann\t*.neamhní\n"
+
+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"
+
+#, 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:"
+
+#, c-format
+msgid "E252: Fontset name: %s"
+msgstr "E252: Ainm an tacar cló: %s"
+
+#, c-format
+msgid "Font '%s' is not fixed-width"
+msgstr "Ní cló aonleithid é '%s'"
+
+#, c-format
+msgid "E253: Fontset name: %s\n"
+msgstr "E253: Ainm an tacar cló: %s\n"
+
+#, c-format
+msgid "Font0: %s\n"
+msgstr "Cló0: %s\n"
+
+#, c-format
+msgid "Font1: %s\n"
+msgstr "Cló1: %s\n"
+
+#, c-format
+msgid "Font%ld width is not twice that of font0\n"
+msgstr "Níl Cló%ld níos leithne faoi dhó ná cló0\n"
+
+#, c-format
+msgid "Font0 width: %ld\n"
+msgstr "Leithead Cló0: %ld\n"
+
+#, c-format
+msgid ""
+"Font1 width: %ld\n"
+"\n"
+msgstr ""
+"Leithead Cló1: %ld\n"
+"\n"
+
+msgid "Invalid font specification"
+msgstr "Sonrú neamhbhailí cló"
+
+msgid "&Dismiss"
+msgstr "&Ruaig"
+
+msgid "no specific match"
+msgstr "níl a leithéid ann"
+
+msgid "Vim - Font Selector"
+msgstr "Vim - Roghnú Cló"
+
+msgid "Name:"
+msgstr "Ainm:"
+
+#. create toggle button
+msgid "Show size in Points"
+msgstr "Taispeáin méid (Pointí)"
+
+msgid "Encoding:"
+msgstr "Ionchódú:"
+
+msgid "Font:"
+msgstr "Cló:"
+
+msgid "Style:"
+msgstr "Stíl:"
+
+msgid "Size:"
+msgstr "Méid:"
+
+msgid "E256: Hangul automata ERROR"
+msgstr "E256: EARRÁID leis na huathoibreáin Hangul"
+
+msgid "E550: Missing colon"
+msgstr "E550: Idirstad ar iarraidh"
+
+msgid "E551: Illegal component"
+msgstr "E551: Comhpháirt neamhcheadaithe"
+
+msgid "E552: digit expected"
+msgstr "E552: ag súil le digit"
+
+#, c-format
+msgid "Page %d"
+msgstr "Leathanach %d"
+
+msgid "No text to be printed"
+msgstr "Níl aon téacs le priontáil"
+
+#, c-format
+msgid "Printing page %d (%d%%)"
+msgstr "Leathanach %d (%d%%) á phriontáil"
+
+#, c-format
+msgid " Copy %d of %d"
+msgstr " Cóip %d de %d"
+
+#, c-format
+msgid "Printed: %s"
+msgstr "Priontáilte: %s"
+
+msgid "Printing aborted"
+msgstr "Priontáil tobscortha"
+
+msgid "E455: Error writing to PostScript output file"
+msgstr "E455: Earráid le linn scríobh chuig aschomhad PostScript"
+
+#, c-format
+msgid "E624: Can't open file \"%s\""
+msgstr "E624: Ní féidir an comhad \"%s\" a oscailt"
+
+#, c-format
+msgid "E457: Can't read PostScript resource file \"%s\""
+msgstr "E457: Ní féidir comhad acmhainne PostScript \"%s\" a léamh"
+
+#, c-format
+msgid "E618: file \"%s\" is not a PostScript resource file"
+msgstr "E618: Níl comhad \"%s\" ina chomhad acmhainne PostScript"
+
+#, c-format
+msgid "E619: file \"%s\" is not a supported PostScript resource file"
+msgstr "E619: Tá \"%s\" ina chomhad acmhainne PostScript gan tacú"
+
+#, c-format
+msgid "E621: \"%s\" resource file has wrong version"
+msgstr "E621: Tá an leagan mícheart ar an gcomhad acmhainne \"%s\""
+
+msgid "E673: Incompatible multi-byte encoding and character set."
+msgstr "E673: Ionchódú agus tacar carachtar ilbhirt neamh-chomhoiriúnach."
+
+msgid "E674: printmbcharset cannot be empty with multi-byte encoding."
+msgstr ""
+"E674: ní cheadaítear printmbcharset a bheith folamh le hionchódú ilbhirt."
+
+msgid "E675: No default font specified for multi-byte printing."
+msgstr "E675: Níor réamhshocraíodh cló le haghaidh priontála ilbhirt."
+
+msgid "E324: Can't open PostScript output file"
+msgstr "E324: Ní féidir aschomhad PostScript a oscailt"
+
+#, c-format
+msgid "E456: Can't open file \"%s\""
+msgstr "E456: Ní féidir an comhad \"%s\" a oscailt"
+
+msgid "E456: Can't find PostScript resource file \"prolog.ps\""
+msgstr "E456: Comhad acmhainne PostScript \"prolog.ps\" gan aimsiú"
+
+msgid "E456: Can't find PostScript resource file \"cidfont.ps\""
+msgstr "E456: Comhad acmhainne PostScript \"cidfont.ps\" gan aimsiú"
+
+#, c-format
+msgid "E456: Can't find PostScript resource file \"%s.ps\""
+msgstr "E456: Comhad acmhainne PostScript \"%s.ps\" gan aimsiú"
+
+#, 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ú"
+
+msgid "Sending to printer..."
+msgstr "Á sheoladh chuig an phrintéir..."
+
+msgid "E365: Failed to print PostScript file"
+msgstr "E365: Theip ar phriontáil comhaid PostScript"
+
+msgid "Print job sent."
+msgstr "Seoladh jab priontála."
+
+msgid "Add a new database"
+msgstr "Bunachar sonraí nua"
+
+msgid "Query for a pattern"
+msgstr "Iarratas ar phatrún"
+
+msgid "Show this message"
+msgstr "Taispeáin an teachtaireacht seo"
+
+msgid "Kill a connection"
+msgstr "Maraigh nasc"
+
+msgid "Reinit all connections"
+msgstr "Atúsaigh gach nasc"
+
+msgid "Show connections"
+msgstr "Taispeáin naisc"
+
+#, c-format
+msgid "E560: Usage: cs[cope] %s"
+msgstr "E560: Úsáid: cs[cope] %s"
+
+msgid "This cscope command does not support splitting the window.\n"
+msgstr "Ní féidir fuinneoga a scoilteadh leis an ordú seo `cscope'.\n"
+
+msgid "E562: Usage: cstag <ident>"
+msgstr "E562: Úsáid: cstag <ident>"
+
+msgid "E257: cstag: tag not found"
+msgstr "E257: cstag: clib gan aimsiú"
+
+#, c-format
+msgid "E563: stat(%s) error: %d"
+msgstr "E563: earráid stat(%s): %d"
+
+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í"
+
+#, c-format
+msgid "Added cscope database %s"
+msgstr "Bunachar sonraí nua cscope: %s"
+
+#, c-format
+msgid "E262: error reading cscope connection %ld"
+msgstr "E262: earráid agus an nasc cscope %ld á léamh"
+
+msgid "E561: unknown cscope search type"
+msgstr "E561: cineál anaithnid cuardaigh cscope"
+
+msgid "E566: Could not create cscope pipes"
+msgstr "E566: Níorbh fhéidir píopaí cscope a chruthú"
+
+msgid "E622: Could not fork for cscope"
+msgstr "E622: Níorbh fhéidir forc a dhéanamh le haghaidh cscope"
+
+msgid "cs_create_connection exec failed"
+msgstr "theip ar rith cs_create_connection"
+
+msgid "cs_create_connection: fdopen for to_fp failed"
+msgstr "cs_create_connection: theip ar fdopen le haghaidh to_fp"
+
+msgid "cs_create_connection: fdopen for fr_fp failed"
+msgstr "cs_create_connection: theip ar fdopen le haghaidh fr_fp"
+
+msgid "E623: Could not spawn cscope process"
+msgstr "E623: Níorbh fhéidir próiseas cscope a sceitheadh"
+
+msgid "E567: no cscope connections"
+msgstr "E567: níl aon nasc cscope ann"
+
+#, 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"
+
+#, c-format
+msgid "E469: invalid cscopequickfix flag %c for %c"
+msgstr "E469: bratach neamhbhailí cscopequickfix %c le haghaidh %c"
+
+msgid "cscope commands:\n"
+msgstr "Orduithe cscope:\n"
+
+#, c-format
+msgid "%-5s: %s%*s (Usage: %s)"
+msgstr "%-5s: %s%*s (Úsáid: %s)"
+
+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 assignments to\n"
+msgstr ""
+"\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"
+" f: Aimsigh an comhad seo\n"
+" 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"
+
+#, 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"
+
+msgid "E568: duplicate cscope database not added"
+msgstr "E568: níor cuireadh bunachar sonraí dúblach cscope leis"
+
+#, c-format
+msgid "E261: cscope connection %s not found"
+msgstr "E261: nasc cscope %s gan aimsiú"
+
+#, c-format
+msgid "cscope connection %s closed"
+msgstr "Dúnadh nasc cscope %s"
+
+#. should not reach here
+msgid "E570: fatal error in cs_manage_matches"
+msgstr "E570: earráid mharfach i cs_manage_matches"
+
+#, c-format
+msgid "Cscope tag: %s"
+msgstr "Clib cscope: %s"
+
+msgid ""
+"\n"
+" # line"
+msgstr ""
+"\n"
+" # líne"
+
+msgid "filename / context / line\n"
+msgstr "ainm comhaid / comhthéacs / líne\n"
+
+#, c-format
+msgid "E609: Cscope error: %s"
+msgstr "E609: Earráid cscope: %s"
+
+msgid "All cscope databases reset"
+msgstr "Athshocraíodh gach bunachar sonraí cscope"
+
+msgid "no cscope connections\n"
+msgstr "níl aon nasc cscope\n"
+
+msgid " # pid database name prepend path\n"
+msgstr " # pid ainm bunachair conair thosaigh\n"
+
+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 "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 save undo information"
+msgstr "ní féidir eolas cealaithe a shábháil"
+
+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 "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 ""
+"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 "E659: Cannot invoke Python recursively"
+msgstr "E659: Ní féidir Python a rith go hathchúrsach"
+
+msgid "can't delete OutputObject attributes"
+msgstr "ní féidir tréithe OutputObject a scriosadh"
+
+msgid "softspace must be an integer"
+msgstr "caithfidh softspace a bheith ina shlánuimhir"
+
+msgid "invalid attribute"
+msgstr "aitreabúid neamhbhailí"
+
+msgid "writelines() requires list of strings"
+msgstr "liosta teaghrán ag teastáil ó writelines()"
+
+msgid "E264: Python: Error initialising I/O objects"
+msgstr "E264: Python: Earráid agus réada I/A á dtúsú"
+
+msgid "attempt to refer to deleted buffer"
+msgstr "rinneadh iarracht ar mhaolán scriosta a rochtain"
+
+msgid "line number out of range"
+msgstr "líne-uimhir as raon"
+
+#, c-format
+msgid "<buffer object (deleted) at %p>"
+msgstr "<réad maoláin (scriosta) ag %p>"
+
+msgid "invalid mark name"
+msgstr "ainm neamhbhailí mairc"
+
+msgid "no such buffer"
+msgstr "níl a leithéid de mhaolán ann"
+
+msgid "attempt to refer to deleted window"
+msgstr "rinneadh iarracht ar fhuinneog scriosta a rochtain"
+
+msgid "readonly attribute"
+msgstr "tréith inléite amháin"
+
+msgid "cursor position outside buffer"
+msgstr "cúrsóir taobh amuigh den mhaolán"
+
+#, c-format
+msgid "<window object (deleted) at %p>"
+msgstr "<réad fuinneoige (scriosta) ag %p>"
+
+#, c-format
+msgid "<window object (unknown) at %p>"
+msgstr "<réad fuinneoige (anaithnid) ag %p>"
+
+#, c-format
+msgid "<window %d>"
+msgstr "<fuinneog %d>"
+
+msgid "no such window"
+msgstr "níl a leithéid d'fhuinneog ann"
+
+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 "Toggle implementation/definition"
+msgstr "Scoránaigh feidhmiú/sainmhíniú"
+
+msgid "Show base class of"
+msgstr "Taispeáin an bunaicme de"
+
+msgid "Show overridden member function"
+msgstr "Taispeáin ballfheidhm sáraithe"
+
+msgid "Retrieve from file"
+msgstr "Aisghabh ó chomhad"
+
+msgid "Retrieve from project"
+msgstr "Aisghabh ó thionscadal"
+
+msgid "Retrieve from all projects"
+msgstr "Aisghabh ó gach tionscadal"
+
+msgid "Retrieve"
+msgstr "Aisghabh"
+
+msgid "Show source of"
+msgstr "Taispeáin foinse"
+
+msgid "Find symbol"
+msgstr "Aimsigh siombail"
+
+msgid "Browse class"
+msgstr "Brabhsáil aicme"
+
+msgid "Show class in hierarchy"
+msgstr "Taispeáin an aicme in ordlathas"
+
+msgid "Show class in restricted hierarchy"
+msgstr "Taispeáin an aicme in ordlathas srianta"
+
+msgid "Xref refers to"
+msgstr "Tagraíonn Xref do"
+
+msgid "Xref referred by"
+msgstr "Xref tagartha ag"
+
+msgid "Xref has a"
+msgstr "Rud atá ag Xref:"
+
+msgid "Xref used by"
+msgstr "Xref á úsáid ag"
+
+msgid "Show docu of"
+msgstr "Taispeáin eolas faoi"
+
+msgid "Generate docu for"
+msgstr "Gin eolas faoi"
+
+msgid ""
+"Cannot connect to SNiFF+. Check environment (sniffemacs must be found in "
+"$PATH).\n"
+msgstr ""
+"Ní féidir nasc a dhéanamh le SNiFF+. Seiceáil do chuid athróga "
+"thimpeallachta (caithfidh tú sniffemacs a chur i do $PATH).\n"
+
+msgid "E274: Sniff: Error during read. Disconnected"
+msgstr "E274: Sniff: Earráid sa léamh. Dínasctha"
+
+msgid "SNiFF+ is currently "
+msgstr "SNiFF+ stádas faoi láthair: "
+
+msgid "not "
+msgstr "ní "
+
+msgid "connected"
+msgstr "nasctha"
+
+#, c-format
+msgid "E275: Unknown SNiFF+ request: %s"
+msgstr "E275: Iarratas anaithnid SNiFF+: %s"
+
+msgid "E276: Error connecting to SNiFF+"
+msgstr "E276: Earráid ag nascadh le SNiFF+"
+
+msgid "E278: SNiFF+ not connected"
+msgstr "E278: SNiFF+ gan nasc"
+
+msgid "E279: Not a SNiFF+ buffer"
+msgstr "E279: Ní maolán SNiFF+ é"
+
+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ú"
+
+#, 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 "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ú."
+
+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"
+
+#, 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!"
+
+msgid "Unknown option argument"
+msgstr "Argóint anaithnid rogha"
+
+msgid "Too many edit arguments"
+msgstr "An iomarca argóintí eagarthóireachta"
+
+msgid "Argument missing after"
+msgstr "Argóint ar iarraidh i ndiaidh"
+
+msgid "Garbage after option argument"
+msgstr "Dramhaíl i ndiaidh argóinte rogha"
+
+msgid "Too many \"+command\", \"-c command\" or \"--cmd command\" arguments"
+msgstr ""
+"An iomarca argóintí den chineál \"+ordú\", \"-c ordú\" nó \"--cmd ordú\""
+
+msgid "Invalid argument for"
+msgstr "Argóint neamhbhailí do"
+
+#, c-format
+msgid "%d files to edit\n"
+msgstr "%d comhad le heagrú\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 "'-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 "Attempt to open script file again: \""
+msgstr "Déan iarracht ar oscailt na scripte arís: \""
+
+msgid "Cannot open for reading: \""
+msgstr "Ní féidir é a oscailt chun léamh: \""
+
+msgid "Cannot open for script output: \""
+msgstr "Ní féidir a oscailt le haghaidh an aschuir scripte: \""
+
+msgid "Vim: Error: Failure to start gvim from NetBeans\n"
+msgstr "Vim: Earráid: Theip ar thosú gvim ó NetBeans\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"
+
+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..
+msgid "pre-vimrc command line"
+msgstr "líne na n-orduithe pre-vimrc"
+
+#, c-format
+msgid "E282: Cannot read from \"%s\""
+msgstr "E282: Ní féidir léamh ó \"%s\""
+
+msgid ""
+"\n"
+"More info with: \"vim -h\"\n"
+msgstr ""
+"\n"
+"Tuilleadh eolais: \"vim -h\"\n"
+
+msgid "[file ..] edit specified file(s)"
+msgstr "[comhad ..] cuir na comhaid ceaptha in eagar"
+
+msgid "- read text from stdin"
+msgstr "- scríobh téacs ó stdin"
+
+msgid "-t tag edit file where tag is defined"
+msgstr "-t tag cuir an comhad ina bhfuil an chlib in eagar"
+
+msgid "-q [errorfile] edit file with first error"
+msgstr "-q [comhadearr] cuir comhad leis an chéad earráid in eagar"
+
+msgid ""
+"\n"
+"\n"
+"usage:"
+msgstr ""
+"\n"
+"\n"
+"úsáid:"
+
+msgid " vim [arguments] "
+msgstr " vim [argóintí] "
+
+msgid ""
+"\n"
+" or:"
+msgstr ""
+"\n"
+" nó:"
+
+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"
+"Arguments:\n"
+msgstr ""
+"\n"
+"\n"
+"Argóintí:\n"
+
+msgid "--\t\t\tOnly file names after this"
+msgstr "--\t\t\tNí cheadaítear ach ainmneacha comhaid i ndiaidh é seo"
+
+msgid "--literal\t\tDon't expand wildcards"
+msgstr "--literal\t\tNá leathnaigh saoróga"
+
+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\")"
+
+msgid "-e\t\t\tEx mode (like \"ex\")"
+msgstr "-e\t\t\tMód Ex (mar \"ex\")"
+
+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)"
+
+msgid "-d\t\t\tDiff mode (like \"vimdiff\")"
+msgstr "-d\t\t\tMód diff (mar \"vimdiff\")"
+
+msgid "-y\t\t\tEasy mode (like \"evim\", modeless)"
+msgstr "-y\t\t\tMód éasca (mar \"evim\", gan mhóid)"
+
+msgid "-R\t\t\tReadonly mode (like \"view\")"
+msgstr "-R\t\t\tMód inléite amháin (mar \"view\")"
+
+msgid "-Z\t\t\tRestricted mode (like \"rvim\")"
+msgstr "-Z\t\t\tMód srianta (mar \"rvim\")"
+
+msgid "-m\t\t\tModifications (writing files) not allowed"
+msgstr "-m\t\t\tNí cheadaítear athruithe (.i. scríobh na gcomhad)"
+
+msgid "-M\t\t\tModifications in text not allowed"
+msgstr "-M\t\t\tNí cheadaítear athruithe sa téacs"
+
+msgid "-b\t\t\tBinary mode"
+msgstr "-b\t\t\tMód dénártha"
+
+msgid "-l\t\t\tLisp mode"
+msgstr "-l\t\t\tMód Lisp"
+
+msgid "-C\t\t\tCompatible with Vi: 'compatible'"
+msgstr "-C\t\t\tComhoiriúnach le Vi: 'compatible'"
+
+msgid "-N\t\t\tNot fully Vi compatible: 'nocompatible'"
+msgstr "-N\t\t\tNí comhoiriúnaithe le Vi go hiomlán: 'nocompatible'"
+
+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]"
+
+msgid "-D\t\t\tDebugging mode"
+msgstr "-D\t\t\tMód dífhabhtaithe"
+
+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"
+
+msgid "-r\t\t\tList swap files and exit"
+msgstr "-r\t\t\tTaispeáin comhaid bhabhtála agus scoir"
+
+msgid "-r (with file name)\tRecover crashed session"
+msgstr "-r (le hainm comhaid)\tAthshlánaigh ó chliseadh"
+
+msgid "-L\t\t\tSame as -r"
+msgstr "-L\t\t\tAr comhbhrí le -r"
+
+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"
+
+msgid "-H\t\t\tStart in Hebrew mode"
+msgstr "-H\t\t\tTosaigh sa mhód Eabhraise"
+
+msgid "-F\t\t\tStart in Farsi mode"
+msgstr "-F\t\t\tTosaigh sa mhód Pheirsise"
+
+msgid "-T <terminal>\tSet terminal type to <terminal>"
+msgstr "-T <teirminéal>\tSocraigh cineál teirminéal"
+
+msgid "-u <vimrc>\t\tUse <vimrc> instead of any .vimrc"
+msgstr "-u <vimrc>\t\tÚsáid <vimrc> in ionad aon .vimrc"
+
+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"
+
+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)"
+
+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)"
+
+msgid "-O[N]\t\tLike -o but split vertically"
+msgstr "-O[N]\t\tMar -o, ach roinn go hingearach"
+
+msgid "+\t\t\tStart at end of file"
+msgstr "+\t\t\tTosaigh ag an chomhadchríoch"
+
+msgid "+<lnum>\t\tStart at line <lnum>"
+msgstr "+<lnum>\t\tTosaigh ar líne <lnum>"
+
+msgid "--cmd <command>\tExecute <command> before loading any vimrc file"
+msgstr "--cmd <ordú>\tRith <ordú> roimh aon chomhad vimrc a luchtú"
+
+msgid "-c <command>\t\tExecute <command> after loading the first file"
+msgstr "-c <ordú>\t\tRith <ordú> i ndiaidh luchtú an chéad chomhad"
+
+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"
+
+msgid "-s <scriptin>\tRead Normal mode commands from file <scriptin>"
+msgstr "-s <script>\tLéigh orduithe gnáthmhóid ón chomhad <script>"
+
+msgid "-w <scriptout>\tAppend all typed commands to file <scriptout>"
+msgstr ""
+"-w <script>\tIarcheangail gach ordú iontráilte leis an gcomhad <script>"
+
+msgid "-W <scriptout>\tWrite all typed commands to file <scriptout>"
+msgstr "-W <aschur>\tScríobh gach ordú clóscríofa sa chomhad <aschur>"
+
+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>"
+
+msgid "-i <viminfo>\t\tUse <viminfo> instead of .viminfo"
+msgstr "-i <viminfo>\t\tÚsáid <viminfo> in ionad .viminfo"
+
+msgid "-h or --help\tPrint Help (this message) and exit"
+msgstr "-h nó --help\tTaispeáin an chabhair seo agus scoir"
+
+msgid "--version\t\tPrint version information and exit"
+msgstr "--version\t\tTaispeáin eolas faoin leagan agus scoir"
+
+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 "-name <name>\t\tUse resource as if vim was <name>"
+msgstr "-name <ainm>\t\tÚsáid acmhainn mar a bheadh vim <ainm>"
+
+msgid "\t\t\t (Unimplemented)\n"
+msgstr "\t\t\t (Níl ar fáil)\n"
+
+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 (RISC OS version):\n"
+msgstr ""
+"\n"
+"Argóintí ar eolas do gvim (leagan RISC OS):\n"
+
+msgid "--columns <number>\tInitial width of window in columns"
+msgstr "--columns <uimhir>\tLeithead fuinneoige i dtosach (colúin)"
+
+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"
+
+#. 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"
+
+#, c-format
+msgid "E283: No marks matching \"%s\""
+msgstr "E283: Níl aon mharc comhoiriúnaithe le \"%s\""
+
+#. Highlight title
+msgid ""
+"\n"
+"mark line col file/text"
+msgstr ""
+"\n"
+"marc líne col comhad/téacs"
+
+#. Highlight title
+msgid ""
+"\n"
+" jump line col file/text"
+msgstr ""
+"\n"
+" léim líne col comhad/téacs"
+
+#. Highlight title
+msgid ""
+"\n"
+"change line col text"
+msgstr ""
+"\n"
+"athrú líne col téacs"
+
+#, c-format
+msgid ""
+"\n"
+"# File marks:\n"
+msgstr ""
+"\n"
+"# Marcanna comhaid:\n"
+
+#. Write the jumplist with -'
+#, c-format
+msgid ""
+"\n"
+"# Jumplist (newest first):\n"
+msgstr ""
+"\n"
+"# Liosta léimeanna (is nuaí i dtosach):\n"
+
+#, c-format
+msgid ""
+"\n"
+"# History of marks within files (newest to oldest):\n"
+msgstr ""
+"\n"
+"# Stair na marcanna i gcomhaid (is nuaí ar dtús):\n"
+
+msgid "Missing '>'"
+msgstr "`>' ar iarraidh"
+
+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 "E290: over-the-spot style requires fontset"
+msgstr "E290: tacar cló ag teastáil ó stíl thar-an-spota"
+
+msgid "E291: Your GTK+ is older than 1.2.3. Status area disabled"
+msgstr ""
+"E291: Tá an GTK+ atá agat níos sine ná leagan 1.2.3. Díchumasaítear an "
+"limistéar stádais"
+
+msgid "E292: Input Method Server is not running"
+msgstr "E292: Níl an Freastalaí Mhodh Ionchuir ag rith"
+
+msgid "E293: block was not locked"
+msgstr "E293: ní raibh an bloc faoi ghlas"
+
+msgid "E294: Seek error in swap file read"
+msgstr "E294: Earráid chuardaigh agus comhad babhtála á léamh"
+
+msgid "E295: Read error in swap file"
+msgstr "E295: Earráid sa léamh i gcomhad babhtála"
+
+msgid "E296: Seek error in swap file write"
+msgstr "E296: Earráid chuardaigh agus comhad babhtála á scríobh"
+
+msgid "E297: Write error in swap file"
+msgstr "E297: Earráid sa scríobh i gcomhad babhtála"
+
+msgid "E300: Swap file already exists (symlink attack?)"
+msgstr "E300: Tá comhad babhtála ann cheana (ionsaí le naisc shiombalacha?)"
+
+msgid "E298: Didn't get block nr 0?"
+msgstr "E298: Ní bhfuarthas bloc 0?"
+
+msgid "E298: Didn't get block nr 1?"
+msgstr "E298: Ní bhfuarthas bloc a haon?"
+
+msgid "E298: Didn't get block nr 2?"
+msgstr "E298: Ní bhfuarthas bloc a dó?"
+
+#. could not (re)open the swap file, what can we do????
+msgid "E301: Oops, lost the swap file!!!"
+msgstr "E301: Úps, cailleadh an comhad babhtála!!!"
+
+msgid "E302: Could not rename swap file"
+msgstr "E302: Níorbh fhéidir an comhad babhtála a athainmniú"
+
+#, 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ú"
+
+msgid "E304: ml_upd_block0(): Didn't get block 0??"
+msgstr "E304: ml_upd_block0(): Ní bhfuarthas bloc 0??"
+
+#, c-format
+msgid "E305: No swap file found for %s"
+msgstr "E305: Níor aimsíodh comhad babhtála le haghaidh %s"
+
+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): "
+
+#, c-format
+msgid "E306: Cannot open %s"
+msgstr "E306: Ní féidir %s a oscailt"
+
+msgid "Unable to read block 0 from "
+msgstr "Ní féidir bloc 0 a léamh ó "
+
+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"
+"babhtála as dáta."
+
+msgid " cannot be used with this version of Vim.\n"
+msgstr " níl ar fáil leis an leagan seo de Vim.\n"
+
+msgid "Use Vim version 3.0.\n"
+msgstr "Bain úsáid as Vim, leagan 3.0.\n"
+
+#, 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"
+
+msgid " cannot be used on this computer.\n"
+msgstr " níl ar fáil ar an ríomhaire seo.\n"
+
+msgid "The file was created on "
+msgstr "Cruthaíodh an comhad seo ar "
+
+msgid ""
+",\n"
+"or the file has been damaged."
+msgstr ""
+",\n"
+"is é sin nó rinneadh dochar don chomhad."
+
+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"
+
+#, c-format
+msgid "Using swap file \"%s\""
+msgstr "Comhad babhtála \"%s\" á úsáid"
+
+#, c-format
+msgid "Original file \"%s\""
+msgstr "Comhad bunúsach \"%s\""
+
+msgid "E308: Warning: Original file may have been changed"
+msgstr "E308: Rabhadh: Is féidir gur athraíodh an comhad bunúsach"
+
+#, c-format
+msgid "E309: Unable to read block 1 from %s"
+msgstr "E309: Ní féidir bloc a haon a léamh ó %s"
+
+msgid "???MANY LINES MISSING"
+msgstr "???GO LEOR LÍNTE AR IARRAIDH"
+
+msgid "???LINE COUNT WRONG"
+msgstr "???LÍON MÍCHEART NA LÍNTE"
+
+msgid "???EMPTY BLOCK"
+msgstr "???BLOC FOLAMH"
+
+msgid "???LINES MISSING"
+msgstr "???LÍNTE AR IARRAIDH"
+
+#, 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?)"
+
+msgid "???BLOCK MISSING"
+msgstr "???BLOC AR IARRAIDH"
+
+msgid "??? from here until ???END lines may be messed up"
+msgstr "??? is féidir go ndearnadh praiseach de línte ó anseo go ???END"
+
+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"
+
+msgid "???END"
+msgstr "???DEIREADH"
+
+msgid "E311: Recovery Interrupted"
+msgstr "E311: Idirbhriseadh an t-athshlánú"
+
+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"
+
+msgid "See \":help E312\" for more information."
+msgstr "Bain triail as \":help E312\" chun tuilleadh eolais a fháil."
+
+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."
+
+msgid ""
+"\n"
+"(You might want to write out this file under another name\n"
+msgstr ""
+"\n"
+"(B'fhéidir gur mian leat an comhad seo a shábháil de réir ainm eile\n"
+
+msgid "and run diff with the original file to check for changes)\n"
+msgstr ""
+"agus déan comparáid leis an chomhad bhunúsach (m.sh. le `diff') chun "
+"athruithe a scrúdú)\n"
+
+msgid ""
+"Delete the .swp file afterwards.\n"
+"\n"
+msgstr ""
+"Scrios an comhad .swp tar éis sin.\n"
+"\n"
+
+#. use msg() to start the scrolling properly
+msgid "Swap files found:"
+msgstr "Comhaid bhabhtála aimsithe:"
+
+msgid " In current directory:\n"
+msgstr " Sa chomhadlann reatha:\n"
+
+msgid " Using specified name:\n"
+msgstr " Ag baint úsáid as ainm socraithe:\n"
+
+msgid " In directory "
+msgstr " Sa chomhadlann "
+
+msgid " -- none --\n"
+msgstr " -- neamhní --\n"
+
+msgid " owned by: "
+msgstr " úinéir: "
+
+msgid " dated: "
+msgstr " dátaithe: "
+
+msgid " dated: "
+msgstr " dátaithe: "
+
+msgid " [from Vim version 3.0]"
+msgstr " [ó leagan 3.0 Vim]"
+
+msgid " [does not look like a Vim swap file]"
+msgstr " [ní cosúil le comhad babhtála Vim]"
+
+msgid " file name: "
+msgstr " ainm comhaid: "
+
+msgid ""
+"\n"
+" modified: "
+msgstr ""
+"\n"
+" mionathraithe: "
+
+msgid "YES"
+msgstr "IS SEA"
+
+msgid "no"
+msgstr "ní hea"
+
+msgid ""
+"\n"
+" user name: "
+msgstr ""
+"\n"
+" úsáideoir: "
+
+msgid " host name: "
+msgstr " ainm an óstríomhaire: "
+
+msgid ""
+"\n"
+" host name: "
+msgstr ""
+"\n"
+" óstainm: "
+
+msgid ""
+"\n"
+" process ID: "
+msgstr ""
+"\n"
+" PID: "
+
+msgid " (still running)"
+msgstr " (ag rith fós)"
+
+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]"
+msgstr ""
+"\n"
+" [ní inúsáidte ar an ríomhaire seo]"
+
+msgid " [cannot be read]"
+msgstr " [ní féidir a léamh]"
+
+msgid " [cannot be opened]"
+msgstr " [ní féidir oscailt]"
+
+msgid "E313: Cannot preserve, there is no swap file"
+msgstr "E313: Ní féidir é a chaomhnú, níl aon chomhad babhtála ann"
+
+msgid "File preserved"
+msgstr "Caomhnaíodh an comhad"
+
+msgid "E314: Preserve failed"
+msgstr "E314: Theip ar chaomhnú"
+
+#, c-format
+msgid "E315: ml_get: invalid lnum: %ld"
+msgstr "E315: ml_get: lnum neamhbhailí: %ld"
+
+#, c-format
+msgid "E316: ml_get: cannot find line %ld"
+msgstr "E316: ml_get: líne %ld gan aimsiú"
+
+msgid "E317: pointer block id wrong 3"
+msgstr "E317: aitheantas mícheart ar an mbloc pointeora 3"
+
+msgid "stack_idx should be 0"
+msgstr "ba chóir do stack_idx a bheith 0"
+
+msgid "E318: Updated too many blocks?"
+msgstr "E318: An iomarca bloic nuashonraithe?"
+
+msgid "E317: pointer block id wrong 4"
+msgstr "E317: aitheantas mícheart ar an mbloc pointeora 4"
+
+msgid "deleted block 1?"
+msgstr "bloc a haon scriosta?"
+
+#, c-format
+msgid "E320: Cannot find line %ld"
+msgstr "E320: Líne %ld gan aimsiú"
+
+msgid "E317: pointer block id wrong"
+msgstr "E317: aitheantas mícheart ar an mbloc pointeora"
+
+msgid "pe_line_count is zero"
+msgstr "is 0 pe_line_count\""
+
+#, c-format
+msgid "E322: line number out of range: %ld past the end"
+msgstr "E322: líne-uimhir as raon: %ld thar dheireadh"
+
+#, c-format
+msgid "E323: line count wrong in block %ld"
+msgstr "E323: líon mícheart na línte i mbloc %ld"
+
+msgid "Stack size increases"
+msgstr "Méadaíonn an chruach"
+
+msgid "E317: pointer block id wrong 2"
+msgstr "E317: aitheantas mícheart ar an mbloc pointeora 2"
+
+#, c-format
+msgid "E773: Symlink loop for \"%s\""
+msgstr "E773: Ciogal i naisc shiombalacha le haghaidh \"%s\""
+
+msgid "E325: ATTENTION"
+msgstr "E325: AIRE"
+
+msgid ""
+"\n"
+"Found a swap file by the name \""
+msgstr ""
+"\n"
+"Fuarthas comhad babhtála darbh ainm \""
+
+msgid "While opening file \""
+msgstr "Agus an comhad seo á oscailt: \""
+
+msgid " NEWER than swap file!\n"
+msgstr " NÍOS NUAÍ ná comhad babhtála!\n"
+
+#. Some of these messages are long to allow translation to
+#. * other languages.
+msgid ""
+"\n"
+"(1) Another program may be editing the same file.\n"
+" If this is the case, be careful not to end up with two\n"
+" different instances of the same file when making changes.\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"
+
+msgid " Quit, or continue with caution.\n"
+msgstr " Scoir, nó lean ar aghaidh go hairdeallach.\n"
+
+msgid ""
+"\n"
+"(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"
+
+msgid " If this is the case, use \":recover\" or \"vim -r "
+msgstr " Más amhlaidh, bain úsáid as \":recover\" nó \"vim -r "
+
+msgid ""
+"\"\n"
+" to recover the changes (see \":help recovery\").\n"
+msgstr ""
+"\"\n"
+" chun na hathruithe a fháil ar ais (féach \":help recovery\").\n"
+
+msgid " If you did this already, delete the swap file \""
+msgstr " Má tá sé seo déanta cheana agat, scrios an comhad babhtála \""
+
+msgid ""
+"\"\n"
+" to avoid this message.\n"
+msgstr ""
+"\"\n"
+" chun an teachtaireacht seo a sheachaint.\n"
+
+msgid "Swap file \""
+msgstr "Comhad babhtála \""
+
+msgid "\" already exists!"
+msgstr "\" tá sé ann cheana!"
+
+msgid "VIM - ATTENTION"
+msgstr "VIM - AIRE"
+
+msgid "Swap file already exists!"
+msgstr "Tá comhad babhtála ann cheana!"
+
+msgid ""
+"&Open Read-Only\n"
+"&Edit anyway\n"
+"&Recover\n"
+"&Quit\n"
+"&Abort"
+msgstr ""
+"&Oscail Inléite Amháin\n"
+"&Eagraigh mar sin féin\n"
+"&Athshlánaigh\n"
+"&Scoir\n"
+"&Tobscoir"
+
+msgid ""
+"&Open Read-Only\n"
+"&Edit anyway\n"
+"&Recover\n"
+"&Delete it\n"
+"&Quit\n"
+"&Abort"
+msgstr ""
+"&Oscail Inléite Amháin\n"
+"&Eagraigh mar sin féin\n"
+"&Athshlánaigh\n"
+"S&crios é\n"
+"&Scoir\n"
+"&Tobscoir"
+
+msgid "E326: Too many swap files found"
+msgstr "E326: Aimsíodh an iomarca comhaid bhabhtála"
+
+msgid "E327: Part of menu-item path is not sub-menu"
+msgstr "E327: Ní fo-roghchlár í páirt de chonair roghchláir"
+
+msgid "E328: Menu only exists in another mode"
+msgstr "E328: Níl an roghchlár ar fáil sa mhód seo"
+
+#, 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.
+msgid "E792: Empty menu name"
+msgstr "E792: Ainm folamh ar an roghchlár"
+
+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"
+
+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"
+
+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
+msgid ""
+"\n"
+"--- Menus ---"
+msgstr ""
+"\n"
+"--- Roghchláir ---"
+
+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"
+
+#, c-format
+msgid "E334: Menu not found: %s"
+msgstr "E334: Roghchlár gan aimsiú: %s"
+
+#, c-format
+msgid "E335: Menu not defined for %s mode"
+msgstr "E335: Níl an roghchlár ar fáil sa mhód %s"
+
+msgid "E336: Menu path must lead to a sub-menu"
+msgstr "E336: Ní mór conair roghchláir a threorú chun fo-roghchlár"
+
+msgid "E337: Menu not found - check menu names"
+msgstr "E337: Roghchlár gan aimsiú - deimhnigh ainmneacha na roghchlár"
+
+#, c-format
+msgid "Error detected while processing %s:"
+msgstr "Earráid agus %s á phróiseáil:"
+
+#, c-format
+msgid "line %4ld:"
+msgstr "líne %4ld:"
+
+#, c-format
+msgid "E354: Invalid register name: '%s'"
+msgstr "E354: Ainm neamhbhailí tabhaill: '%s'"
+
+msgid "Messages maintainer: Bram Moolenaar <Bram@vim.org>"
+msgstr ""
+"Cothaitheoir na dteachtaireachtaí: Kevin P. Scannell <scannell@slu.edu>"
+
+msgid "Interrupt: "
+msgstr "Idirbhriseadh: "
+
+msgid "Press ENTER or type command to continue"
+msgstr "Brúigh ENTER nó iontráil ordú le leanúint"
+
+#, c-format
+msgid "%s line %ld"
+msgstr "%s líne %ld"
+
+msgid "-- More --"
+msgstr "-- Tuilleadh --"
+
+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 "
+
+msgid "Question"
+msgstr "Ceist"
+
+msgid ""
+"&Yes\n"
+"&No"
+msgstr ""
+"&Tá\n"
+"&Níl"
+
+msgid ""
+"&Yes\n"
+"&No\n"
+"Save &All\n"
+"&Discard All\n"
+"&Cancel"
+msgstr ""
+"&Tá\n"
+"&Níl\n"
+"Sábháil &Uile\n"
+"&Dealaigh Uile\n"
+"&Cealaigh"
+
+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()"
+
+msgid "E807: Expected Float argument for printf()"
+msgstr "E807: Bhíothas ag súil le hargóint Snámhphointe d'fheidhm printf()"
+
+msgid "E767: Too many arguments to printf()"
+msgstr "E767: An iomarca argóintí d'fheidhm printf()"
+
+msgid "W10: Warning: Changing a readonly file"
+msgstr "W10: Rabhadh: Comhad inléite amháin á athrú"
+
+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ú): "
+
+msgid "Type number and <Enter> (empty cancels): "
+msgstr "Clóscríobh uimhir agus <Enter> (fág folamh le cealú): "
+
+msgid "1 more line"
+msgstr "1 líne eile"
+
+msgid "1 line less"
+msgstr "1 líne níos lú"
+
+#, c-format
+msgid "%ld more lines"
+msgstr "%ld líne eile"
+
+#, c-format
+msgid "%ld fewer lines"
+msgstr "%ld líne níos lú"
+
+msgid " (Interrupted)"
+msgstr " (Idirbhriste)"
+
+msgid "Beep!"
+msgstr "Bíp!"
+
+msgid "Vim: preserving files...\n"
+msgstr "Vim: comhaid á gcaomhnú...\n"
+
+#. close all memfiles, without deleting
+msgid "Vim: Finished.\n"
+msgstr "Vim: Críochnaithe.\n"
+
+#, c-format
+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\""
+
+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 "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!"
+
+#, 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"
+
+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"
+
+#, 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\""
+
+msgid "read from Netbeans socket"
+msgstr "léadh ó shoicéad Netbeans"
+
+#, c-format
+msgid "E658: NetBeans connection lost for buffer %ld"
+msgstr "E658: Cailleadh nasc NetBeans le haghaidh maoláin %ld"
+
+msgid "E505: "
+msgstr "E505: "
+
+msgid "E349: No identifier under cursor"
+msgstr "E349: Níl aitheantóir faoin chúrsóir"
+
+msgid "E774: 'operatorfunc' is empty"
+msgstr "E774: 'operatorfunc' folamh"
+
+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ú"
+
+msgid "E348: No string under cursor"
+msgstr "E348: Níl teaghrán faoin chúrsóir"
+
+msgid "E352: Cannot erase folds with current 'foldmethod'"
+msgstr "E352: Ní féidir fillteacha a léirscriosadh leis an 'foldmethod' reatha"
+
+msgid "E664: changelist is empty"
+msgstr "E664: tá liosta na n-athruithe folamh"
+
+msgid "E662: At start of changelist"
+msgstr "E662: Ag tosach liosta na n-athruithe"
+
+msgid "E663: At end of changelist"
+msgstr "E663: Ag deireadh liosta na n-athruithe"
+
+msgid "Type :quit<Enter> to exit Vim"
+msgstr "Clóscríobh :quit<Enter> chun Vim a scor"
+
+# ouch - English -ed ?
+#, c-format
+msgid "1 line %sed 1 time"
+msgstr "1 líne %s uair amháin"
+
+# ouch - English -ed ?
+#, c-format
+msgid "1 line %sed %d times"
+msgstr "1 líne %s %d uair"
+
+# ouch - English -ed ?
+#, c-format
+msgid "%ld lines %sed 1 time"
+msgstr "%ld líne %sed uair amháin"
+
+# ouch - English -ed ?
+#, c-format
+msgid "%ld lines %sed %d times"
+msgstr "%ld líne %sed %d uair"
+
+#, c-format
+msgid "%ld lines to indent... "
+msgstr "%ld líne le heangú... "
+
+msgid "1 line indented "
+msgstr "eangaíodh líne amháin "
+
+#, c-format
+msgid "%ld lines indented "
+msgstr "%ld líne eangaithe "
+
+msgid "E748: No previously used register"
+msgstr "E748: Níl aon tabhall úsáidte roimhe seo"
+
+#. must display the prompt
+msgid "cannot yank; delete anyway"
+msgstr "ní féidir a sracadh; scrios mar sin féin"
+
+msgid "1 line changed"
+msgstr "athraíodh líne amháin"
+
+#, c-format
+msgid "%ld lines changed"
+msgstr "athraíodh %ld líne"
+
+#, c-format
+msgid "freeing %ld lines"
+msgstr "%ld líne á saoradh"
+
+msgid "block of 1 line yanked"
+msgstr "sracadh bloc de líne amháin"
+
+msgid "1 line yanked"
+msgstr "sracadh líne amháin"
+
+#, c-format
+msgid "block of %ld lines yanked"
+msgstr "sracadh bloc de %ld líne"
+
+#, c-format
+msgid "%ld lines yanked"
+msgstr "%ld líne sractha"
+
+#, c-format
+msgid "E353: Nothing in register %s"
+msgstr "E353: Tabhall folamh %s"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Registers ---"
+msgstr ""
+"\n"
+"--- Tabhaill ---"
+
+msgid "Illegal register name"
+msgstr "Ainm neamhcheadaithe tabhaill"
+
+#, c-format
+msgid ""
+"\n"
+"# Registers:\n"
+msgstr ""
+"\n"
+"# Tabhaill:\n"
+
+#, c-format
+msgid "E574: Unknown register type %d"
+msgstr "E574: Cineál anaithnid tabhaill %d"
+
+#, c-format
+msgid "%ld Cols; "
+msgstr "%ld Colún; "
+
+#, c-format
+msgid "Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Bytes"
+msgstr "Roghnaíodh %s%ld as %ld Líne; %ld as %ld Focal; %ld as %ld Beart"
+
+#, c-format
+msgid ""
+"Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Chars; %ld of %ld "
+"Bytes"
+msgstr ""
+"Roghnaíodh %s%ld as %ld Líne; %ld as %ld Focal; %ld as %ld Carachtar; %ld as "
+"%ld Beart"
+
+#, c-format
+msgid "Col %s of %s; Line %ld of %ld; Word %ld of %ld; Byte %ld of %ld"
+msgstr "Col %s as %s; Líne %ld as %ld; Focal %ld as %ld; Beart %ld as %ld"
+
+#, c-format
+msgid ""
+"Col %s of %s; Line %ld of %ld; Word %ld of %ld; Char %ld of %ld; Byte %ld of "
+"%ld"
+msgstr ""
+"Col %s as %s; Líne %ld as %ld; Focal %ld as %ld; Carachtar %ld as %ld; Beart "
+"%ld as %ld"
+
+#, c-format
+msgid "(+%ld for BOM)"
+msgstr "(+%ld do BOM)"
+
+msgid "%<%f%h%m%=Page %N"
+msgstr "%<%f%h%m%=Leathanach %N"
+
+msgid "Thanks for flying Vim"
+msgstr "Go raibh míle maith agat as Vim a úsáid"
+
+msgid "E518: Unknown option"
+msgstr "E518: Rogha anaithnid"
+
+msgid "E519: Option not supported"
+msgstr "E519: Níl an rogha seo ar fáil"
+
+msgid "E520: Not allowed in a modeline"
+msgstr "E520: Ní cheadaithe i módlíne"
+
+msgid "E521: Number required after ="
+msgstr "E521: Tá gá le huimhir i ndiaidh ="
+
+msgid "E522: Not found in termcap"
+msgstr "E522: Gan aimsiú sa termcap"
+
+#, c-format
+msgid "E539: Illegal character <%s>"
+msgstr "E539: Carachtar neamhcheadaithe <%s>"
+
+msgid "E529: Cannot set 'term' to empty string"
+msgstr "E529: Ní féidir 'term' a shocrú mar theaghrán folamh"
+
+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'"
+
+msgid "E617: Cannot be changed in the GTK+ 2 GUI"
+msgstr "E617: Ní féidir é a athrú sa GUI GTK+ 2"
+
+msgid "E524: Missing colon"
+msgstr "E524: Idirstad ar iarraidh"
+
+msgid "E525: Zero length string"
+msgstr "E525: Teaghrán folamh"
+
+#, c-format
+msgid "E526: Missing number after <%s>"
+msgstr "E526: Uimhir ar iarraidh i ndiaidh <%s>"
+
+msgid "E527: Missing comma"
+msgstr "E527: Camóg ar iarraidh"
+
+msgid "E528: Must specify a ' value"
+msgstr "E528: Caithfidh luach ' a shonrú"
+
+msgid "E595: contains unprintable or wide character"
+msgstr "E595: tá carachtar neamhghrafach nó leathan ann"
+
+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>"
+
+msgid "E536: comma required"
+msgstr "E536: tá gá le camóg"
+
+#, 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"
+
+msgid "E538: No mouse support"
+msgstr "E538: Gan tacaíocht luiche"
+
+msgid "E540: Unclosed expression sequence"
+msgstr "E540: Seicheamh gan dúnadh"
+
+msgid "E541: too many items"
+msgstr "E541: an iomarca míreanna"
+
+msgid "E542: unbalanced groups"
+msgstr "E542: grúpaí neamhchothromaithe"
+
+msgid "E590: A preview window already exists"
+msgstr "E590: Tá fuinneog réamhamhairc ann cheana"
+
+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'"
+
+#, c-format
+msgid "E593: Need at least %d lines"
+msgstr "E593: Tá gá le %d líne ar a laghad"
+
+#, c-format
+msgid "E594: Need at least %d columns"
+msgstr "E594: Tá gá le %d colún ar a laghad"
+
+#, c-format
+msgid "E355: Unknown option: %s"
+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.
+#, c-format
+msgid "E521: Number required: &%s = '%s'"
+msgstr "E521: Uimhir de dhíth: &%s = '%s'"
+
+msgid ""
+"\n"
+"--- Terminal codes ---"
+msgstr ""
+"\n"
+"--- Cóid teirminéil ---"
+
+msgid ""
+"\n"
+"--- Global option values ---"
+msgstr ""
+"\n"
+"--- Luachanna na roghanna comhchoiteann ---"
+
+msgid ""
+"\n"
+"--- Local option values ---"
+msgstr ""
+"\n"
+"--- Luachanna na roghanna logánta ---"
+
+msgid ""
+"\n"
+"--- Options ---"
+msgstr ""
+"\n"
+"--- Roghanna ---"
+
+msgid "E356: get_varp ERROR"
+msgstr "E356: EARRÁID get_varp"
+
+#, c-format
+msgid "E357: 'langmap': Matching character missing for %s"
+msgstr "E357: 'langmap': Carachtar comhoiriúnach ar iarraidh le haghaidh %s"
+
+#, c-format
+msgid "E358: 'langmap': Extra characters after semicolon: %s"
+msgstr "E358: 'langmap': Carachtair breise i ndiaidh an idirstad: %s"
+
+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 "'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"
+
+#, 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 "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"
+
+#, c-format
+msgid "Vim: Caught deadly signal %s\n"
+msgstr "Vim: Fuarthas comhartha marfach %s\n"
+
+#, c-format
+msgid "Vim: Caught deadly signal\n"
+msgstr "Vim: Fuarthas comhartha marfach\n"
+
+#, 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"
+"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"
+"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 "
+
+msgid ""
+"\n"
+"Cannot execute shell "
+msgstr ""
+"\n"
+"Ní féidir blaosc a rith "
+
+msgid ""
+"\n"
+"Cannot execute shell sh\n"
+msgstr ""
+"\n"
+"Ní féidir an bhlaosc sh a rith\n"
+
+msgid ""
+"\n"
+"shell returned "
+msgstr ""
+"\n"
+"d'aisfhill an bhlaosc "
+
+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"
+
+#, c-format
+msgid "dlerror = \"%s\""
+msgstr "dlerror = \"%s\""
+
+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 "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 "shell returned %d"
+msgstr "d'aisfhill an bhlaosc %d"
+
+#, 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 "E372: Too many %%%c in format string"
+msgstr "E372: An iomarca %%%c i dteaghrán formáide"
+
+#, c-format
+msgid "E373: Unexpected %%%c in format string"
+msgstr "E373: %%%c gan choinne i dteaghrán formáide"
+
+msgid "E374: Missing ] in format string"
+msgstr "E374: ] ar iarraidh i dteaghrán formáide"
+
+#, c-format
+msgid "E375: Unsupported %%%c in format string"
+msgstr "E375: %%%c gan tacaíocht i dteaghrán formáide"
+
+#, c-format
+msgid "E376: Invalid %%%c in format string prefix"
+msgstr "E376: %%%c neamhbhailí i réimír an teaghráin formáide"
+
+#, c-format
+msgid "E377: Invalid %%%c in format string"
+msgstr "E377: %%%c neamhbhailí i dteaghrán formáide"
+
+msgid "E378: 'errorformat' contains no pattern"
+msgstr "E378: Níl aon phatrún i 'errorformat'"
+
+msgid "E379: Missing or empty directory name"
+msgstr "E379: Ainm comhadlainne ar iarraidh, nó folamh"
+
+msgid "E553: No more items"
+msgstr "E553: Níl aon mhír eile"
+
+#, c-format
+msgid "(%d of %d)%s%s: "
+msgstr "(%d as %d)%s%s: "
+
+msgid " (line deleted)"
+msgstr " (líne scriosta)"
+
+msgid "E380: At bottom of quickfix stack"
+msgstr "E380: In íochtar na cruaiche quickfix"
+
+msgid "E381: At top of quickfix stack"
+msgstr "E381: In uachtar na cruaiche quickfix"
+
+#, c-format
+msgid "error list %d of %d; %d errors"
+msgstr "liosta earráidí %d as %d; %d earráid"
+
+msgid "E382: Cannot write, 'buftype' option is set"
+msgstr "E382: Ní féidir scríobh, rogha 'buftype' socraithe"
+
+msgid "E683: File name missing or invalid pattern"
+msgstr "E683: Ainm comhaid ar iarraidh, nó patrún neamhbhailí"
+
+#, c-format
+msgid "Cannot open file \"%s\""
+msgstr "Ní féidir comhad \"%s\" a oscailt"
+
+msgid "E681: Buffer is not loaded"
+msgstr "E681: Níl an maolán luchtaithe"
+
+msgid "E777: String or List expected"
+msgstr "E777: Bhíothas ag súil le Teaghrán nó Liosta"
+
+#, c-format
+msgid "E369: invalid item in %s%%[]"
+msgstr "E369: mír neamhbhailí i %s%%[]"
+
+msgid "E339: Pattern too long"
+msgstr "E339: Slonn rófhada"
+
+msgid "E50: Too many \\z("
+msgstr "E50: an iomarca \\z("
+
+#, c-format
+msgid "E51: Too many %s("
+msgstr "E51: an iomarca %s("
+
+msgid "E52: Unmatched \\z("
+msgstr "E52: \\z( corr"
+
+#, c-format
+msgid "E53: Unmatched %s%%("
+msgstr "E53: %s%%( corr"
+
+#, c-format
+msgid "E54: Unmatched %s("
+msgstr "E54: %s( corr"
+
+#, c-format
+msgid "E55: Unmatched %s)"
+msgstr "E55: %s) corr"
+
+#, c-format
+msgid "E59: invalid character after %s@"
+msgstr "E59: carachtar neamhbhailí i ndiaidh %s@"
+
+#, c-format
+msgid "E60: Too many complex %s{...}s"
+msgstr "E60: An iomarca %s{...} coimpléascach"
+
+#, c-format
+msgid "E61: Nested %s*"
+msgstr "E61: %s* neadaithe"
+
+#, c-format
+msgid "E62: Nested %s%c"
+msgstr "E62: %s%c neadaithe"
+
+msgid "E63: invalid use of \\_"
+msgstr "E63: úsáid neamhbhailí de \\_"
+
+#, c-format
+msgid "E64: %s%c follows nothing"
+msgstr "E64: níl aon rud roimh %s%c"
+
+msgid "E65: Illegal back reference"
+msgstr "E65: Cúltagairt neamhbhailí"
+
+msgid "E66: \\z( not allowed here"
+msgstr "E66: ní cheadaítear \\z( anseo"
+
+msgid "E67: \\z1 et al. not allowed here"
+msgstr "E67: ní cheadaítear \\z1 et al. anseo"
+
+msgid "E68: Invalid character after \\z"
+msgstr "E68: Carachtar neamhbhailí i ndiaidh \\z"
+
+#, c-format
+msgid "E69: Missing ] after %s%%["
+msgstr "E69: ] ar iarraidh i ndiaidh %s%%["
+
+#, c-format
+msgid "E70: Empty %s%%[]"
+msgstr "E70: %s%%[] folamh"
+
+#, c-format
+msgid "E678: Invalid character after %s%%[dxouU]"
+msgstr "E678: Carachtar neamhbhailí i ndiaidh %s%%[dxouU]"
+
+#, c-format
+msgid "E71: Invalid character after %s%%"
+msgstr "E71: Carachtar neamhbhailí i ndiaidh %s%%"
+
+#, c-format
+msgid "E769: Missing ] after %s["
+msgstr "E769: ] ar iarraidh i ndiaidh %s["
+
+#, c-format
+msgid "E554: Syntax error in %s{...}"
+msgstr "E554: Earráid chomhréire i %s{...}"
+
+msgid "External submatches:\n"
+msgstr "Fo-mheaitseáil sheachtrach:\n"
+
+msgid " VREPLACE"
+msgstr " V-IONADAIGH"
+
+msgid " REPLACE"
+msgstr " ATHCHUR"
+
+msgid " REVERSE"
+msgstr " TIONTÚ"
+
+msgid " INSERT"
+msgstr " IONSÁ"
+
+msgid " (insert)"
+msgstr " (ionsáigh)"
+
+msgid " (replace)"
+msgstr " (ionadaigh)"
+
+msgid " (vreplace)"
+msgstr " (v-ionadaigh)"
+
+msgid " Hebrew"
+msgstr " Eabhrais"
+
+msgid " Arabic"
+msgstr " Araibis"
+
+msgid " (lang)"
+msgstr " (teanga)"
+
+msgid " (paste)"
+msgstr " (greamaigh)"
+
+msgid " VISUAL"
+msgstr " RADHARCACH"
+
+msgid " VISUAL LINE"
+msgstr " LÍNE RADHARCACH"
+
+msgid " VISUAL BLOCK"
+msgstr " BLOC RADHARCACH"
+
+msgid " SELECT"
+msgstr " ROGHNÚ"
+
+msgid " SELECT LINE"
+msgstr " SELECT LINE"
+
+msgid " SELECT BLOCK"
+msgstr " SELECT BLOCK"
+
+msgid "recording"
+msgstr "á thaifeadadh"
+
+#, c-format
+msgid "E383: Invalid search string: %s"
+msgstr "E383: Teaghrán cuardaigh neamhbhailí: %s"
+
+#, 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"
+
+#, 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"
+
+msgid "E386: Expected '?' or '/' after ';'"
+msgstr "E386: Ag súil le '?' nó '/' i ndiaidh ';'"
+
+msgid " (includes previously listed match)"
+msgstr " (tá an teaghrán comhoiriúnaithe roimhe seo san áireamh)"
+
+#. cursor at status line
+msgid "--- Included files "
+msgstr "--- Comhaid cheanntáisc "
+
+msgid "not found "
+msgstr "gan aimsiú"
+
+msgid "in path ---\n"
+msgstr "i gconair ---\n"
+
+msgid " (Already listed)"
+msgstr " (Liostaithe cheana féin)"
+
+msgid " NOT FOUND"
+msgstr " AR IARRAIDH"
+
+#, c-format
+msgid "Scanning included file: %s"
+msgstr "Comhad ceanntáisc á scanadh: %s"
+
+#, c-format
+msgid "Searching included file %s"
+msgstr "Comhad ceanntáisc %s á chuardach"
+
+msgid "E387: Match is on current line"
+msgstr "E387: Tá an teaghrán comhoiriúnaithe ar an líne reatha"
+
+msgid "All included files were found"
+msgstr "Aimsíodh gach comhad ceanntáisc"
+
+msgid "No included files"
+msgstr "Gan comhaid cheanntáisc"
+
+msgid "E388: Couldn't find definition"
+msgstr "E388: Sainmhíniú gan aimsiú"
+
+msgid "E389: Couldn't find pattern"
+msgstr "E389: Patrún gan aimsiú"
+
+msgid "Substitute "
+msgstr "Ionadú "
+
+# in .viminfo
+#, c-format
+msgid ""
+"\n"
+"# Last %sSearch Pattern:\n"
+"~"
+msgstr ""
+"\n"
+"# %sPatrún Cuardaigh Is Déanaí:\n"
+"~"
+
+msgid "E759: Format error in spell file"
+msgstr "E759: Earráid fhormáide i gcomhad litrithe"
+
+msgid "E758: Truncated spell file"
+msgstr "E758: Comhad teasctha litrithe"
+
+#, c-format
+msgid "Trailing text in %s line %d: %s"
+msgstr "Téacs chun deiridh i %s líne %d: %s"
+
+#, c-format
+msgid "Affix name too long in %s line %d: %s"
+msgstr "Ainm foircinn rófhada i %s líne %d: %s"
+
+msgid "E761: Format error in affix file FOL, LOW or UPP"
+msgstr "E761: Earráid fhormáide i gcomhad foircinn FOL, LOW, nó UPP"
+
+msgid "E762: Character in FOL, LOW or UPP is out of range"
+msgstr "E762: Carachtar i FOL, LOW nó UPP as raon"
+
+msgid "Compressing word tree..."
+msgstr "Crann focal á chomhbhrú..."
+
+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 "Reading spell file \"%s\""
+msgstr "Comhad litrithe \"%s\" á léamh"
+
+msgid "E757: This does not look like a spell file"
+msgstr "E757: Níl sé cosúil le comhad litrithe"
+
+msgid "E771: Old spell file, needs to be updated"
+msgstr "E771: Seanchomhad litrithe, tá gá lena nuashonrú"
+
+msgid "E772: Spell file is for newer version of Vim"
+msgstr "E772: Oibríonn an comhad litrithe le leagan níos nuaí de Vim"
+
+msgid "E770: Unsupported section in spell file"
+msgstr "E770: Rannán gan tacaíocht i gcomhad litrithe"
+
+#, c-format
+msgid "Warning: region %s not supported"
+msgstr "Rabhadh: réigiún %s gan tacaíocht"
+
+#, c-format
+msgid "Reading affix file %s ..."
+msgstr "Comhad foircinn %s á léamh..."
+
+#, c-format
+msgid "Conversion failure for word in %s line %d: %s"
+msgstr "Theip ar thiontú focail i %s líne %d: %s"
+
+#, c-format
+msgid "Conversion in %s not supported: from %s to %s"
+msgstr "Tiontú i %s gan tacaíocht: ó %s go %s"
+
+#, 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"
+
+#, 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"
+
+#, c-format
+msgid ""
+"Defining COMPOUNDFORBIDFLAG after PFX item may give wrong results in %s line "
+"%d"
+msgstr ""
+"Seans go bhfaighfidh tú torthaí míchearta má chuireann tú COMPOUNDFORBIDFLAG "
+"tar éis míre PFX i %s líne %d"
+
+#, c-format
+msgid ""
+"Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in %s line "
+"%d"
+msgstr ""
+"Seans go bhfaighfidh tú torthaí míchearta má chuireann tú COMPOUNDPERMITFLAG "
+"tar éis míre PFX i %s líne %d"
+
+#, c-format
+msgid "Wrong COMPOUNDRULES value in %s line %d: %s"
+msgstr "Luach mícheart ar COMPOUNDRULES i %s líne %d: %s"
+
+#, c-format
+msgid "Wrong COMPOUNDWORDMAX value in %s line %d: %s"
+msgstr "Luach mícheart ar COMPOUNDWORDMAX i %s líne %d: %s"
+
+#, c-format
+msgid "Wrong COMPOUNDMIN value in %s line %d: %s"
+msgstr "Luach mícheart ar COMPOUNDMIN i %s líne %d: %s"
+
+#, c-format
+msgid "Wrong COMPOUNDSYLMAX value in %s line %d: %s"
+msgstr "Luach mícheart ar COMPOUNDSYLMAX i %s líne %d: %s"
+
+#, c-format
+msgid "Wrong CHECKCOMPOUNDPATTERN value in %s line %d: %s"
+msgstr "Luach mícheart ar CHECKCOMPOUNDPATTERN i %s líne %d: %s"
+
+#, 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"
+
+#, c-format
+msgid "Duplicate affix in %s line %d: %s"
+msgstr "Clib dhúblach i %s líne %d: %s"
+
+#, c-format
+msgid ""
+"Affix also used for BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST in %s "
+"line %d: %s"
+msgstr ""
+"Foirceann in úsáid le haghaidh BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/"
+"NOSUGGEST freisin i %s líne %d: %s"
+
+#, 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"
+
+#, c-format
+msgid "Broken condition in %s line %d: %s"
+msgstr "Coinníoll briste i %s líne %d: %s"
+
+#, 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"
+
+#, 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"
+
+#, c-format
+msgid "Duplicate character in MAP in %s line %d"
+msgstr "Carachtar dúblach i MAP i %s líne %d"
+
+#, 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"
+
+#, c-format
+msgid "Missing FOL/LOW/UPP line in %s"
+msgstr "Líne FOL/LOW/UPP ar iarraidh i %s"
+
+msgid "COMPOUNDSYLMAX used without SYLLABLE"
+msgstr "COMPOUNDSYLMAX in úsáid gan SYLLABLE"
+
+msgid "Too many postponed prefixes"
+msgstr "An iomarca réimíreanna curtha siar"
+
+msgid "Too many compound flags"
+msgstr "An iomarca bratach comhfhocail"
+
+msgid "Too many postponed prefixes and/or compound flags"
+msgstr "An iomarca réimíreanna curtha siar agus/nó bratacha comhfhocal"
+
+#, c-format
+msgid "Missing SOFO%s line in %s"
+msgstr "Líne SOFO%s ar iarraidh i %s"
+
+#, c-format
+msgid "Both SAL and SOFO lines in %s"
+msgstr "Línte SAL agus SOFO araon i %s"
+
+#, c-format
+msgid "Flag is not a number in %s line %d: %s"
+msgstr "Ní uimhir í an bhratach i %s líne %d: %s"
+
+#, c-format
+msgid "Illegal flag in %s line %d: %s"
+msgstr "Bratach neamhcheadaithe i %s líne %d: %s"
+
+#, 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"
+
+#, c-format
+msgid "Reading dictionary file %s ..."
+msgstr "Foclóir %s á léamh ..."
+
+#, c-format
+msgid "E760: No word count in %s"
+msgstr "E760: Líon na bhfocal ar iarraidh i %s"
+
+#, c-format
+msgid "line %6d, word %6d - %s"
+msgstr "líne %6d, focal %6d - %s"
+
+#, c-format
+msgid "Duplicate word in %s line %d: %s"
+msgstr "Focal dúblach i %s líne %d: %s"
+
+#, c-format
+msgid "First duplicate word in %s line %d: %s"
+msgstr "An chéad fhocal dúblach i %s líne %d: %s"
+
+#, c-format
+msgid "%d duplicate word(s) in %s"
+msgstr "%d focal dúblach i %s"
+
+#, 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"
+
+#, c-format
+msgid "Reading word file %s ..."
+msgstr "Comhad focail %s á léamh ..."
+
+#, 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"
+
+#, 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"
+
+#, 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"
+
+#, c-format
+msgid "Too many regions in %s line %d: %s"
+msgstr "An iomarca réigiún i %s líne %d: %s"
+
+#, c-format
+msgid "/ line ignored in %s line %d: %s"
+msgstr "Rinneadh neamhshuim ar líne `/' i %s líne %d: %s"
+
+#, c-format
+msgid "Invalid region nr in %s line %d: %s"
+msgstr "Uimhir neamhbhailí réigiúin i %s líne %d: %s"
+
+#, c-format
+msgid "Unrecognized flags in %s line %d: %s"
+msgstr "Bratacha anaithnide i %s líne %d: %s"
+
+#, c-format
+msgid "Ignored %d words with non-ASCII characters"
+msgstr "Rinneadh neamhshuim ar %d focal le carachtair neamh-ASCII"
+
+#, c-format
+msgid "Compressed %d of %d nodes; %d (%d%%) remaining"
+msgstr "Comhbhrúdh %d as %d nód; %d (%d%%) fágtha"
+
+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.
+#.
+msgid "Performing soundfolding..."
+msgstr "Fuaimfhilleadh..."
+
+#, c-format
+msgid "Number of words after soundfolding: %ld"
+msgstr "Líon na bhfocal tar éis fuaimfhillte: %ld"
+
+#, c-format
+msgid "Total number of words: %d"
+msgstr "Líon iomlán na bhfocal: %d"
+
+#, c-format
+msgid "Writing suggestion file %s ..."
+msgstr "Comhad moltaí %s á scríobh ..."
+
+#, c-format
+msgid "Estimated runtime memory use: %d bytes"
+msgstr "Cuimhne measta a bheith in úsáid le linn rite: %d beart"
+
+msgid "E751: Output file name must not have region name"
+msgstr "E751: Ní cheadaítear ainm réigiúin in ainm an aschomhaid"
+
+msgid "E754: Only up to 8 regions supported"
+msgstr "E754: Ní thacaítear le níos mó ná 8 réigiún"
+
+#, c-format
+msgid "E755: Invalid region in %s"
+msgstr "E755: Réigiún neamhbhailí i %s"
+
+msgid "Warning: both compounding and NOBREAK specified"
+msgstr "Rabhadh: sonraíodh comhfhocail agus NOBREAK araon"
+
+#, c-format
+msgid "Writing spell file %s ..."
+msgstr "Comhad litrithe %s á scríobh ..."
+
+msgid "Done!"
+msgstr "Críochnaithe!"
+
+#, c-format
+msgid "E765: 'spellfile' does not have %ld entries"
+msgstr "E765: níl %ld iontráil i 'spellfile'"
+
+#, c-format
+msgid "Word removed from %s"
+msgstr "Baineadh focal ó %s"
+
+#, c-format
+msgid "Word added to %s"
+msgstr "Cuireadh focal le %s"
+
+msgid "E763: Word characters differ between spell files"
+msgstr "E763: Tá carachtair dhifriúla fhocail sna comhaid litrithe"
+
+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"
+
+#, c-format
+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"
+
+#, c-format
+msgid "E782: error while reading .sug file: %s"
+msgstr "E782: earráid agus comhad .sug á léamh: %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"
+
+#, c-format
+msgid "E390: Illegal argument: %s"
+msgstr "E390: Argóint neamhcheadaithe: %s"
+
+#, c-format
+msgid "E391: No such syntax cluster: %s"
+msgstr "E391: Níl a leithéid de mhogall comhréire: %s"
+
+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 "syncing on C-style comments"
+msgstr "ag sioncrónú ar nóta den nós C"
+
+msgid "no syncing"
+msgstr "gan sioncrónú"
+
+msgid "syncing starts "
+msgstr "tosaíonn an sioncrónú "
+
+msgid " lines before top line"
+msgstr " línte roimh an bharr"
+
+msgid ""
+"\n"
+"--- Syntax sync items ---"
+msgstr ""
+"\n"
+"--- Míreanna Comhréire Sionc ---"
+
+msgid ""
+"\n"
+"syncing on items"
+msgstr ""
+"\n"
+"ag sioncrónú ar mhíreanna"
+
+msgid ""
+"\n"
+"--- Syntax items ---"
+msgstr ""
+"\n"
+"--- Míreanna comhréire ---"
+
+#, c-format
+msgid "E392: No such syntax cluster: %s"
+msgstr "E392: Níl a leithéid de mhogall comhréire: %s"
+
+msgid "minimal "
+msgstr "íosta "
+
+msgid "maximal "
+msgstr "uasta "
+
+msgid "; match "
+msgstr "; meaitseáil "
+
+msgid " line breaks"
+msgstr " bristeacha líne"
+
+msgid "E395: contains argument not accepted here"
+msgstr "E395: tá argóint ann nach nglactar leis anseo"
+
+msgid "E396: containedin argument not accepted here"
+msgstr "E396: ní ghlactar leis an argóint containedin anseo"
+
+msgid "E393: group[t]here not accepted here"
+msgstr "E393: ní ghlactar le group[t]here anseo"
+
+#, 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"
+
+msgid "E397: Filename required"
+msgstr "E397: Tá gá le hainm comhaid"
+
+#, c-format
+msgid "E789: Missing ']': %s"
+msgstr "E789: ']' ar iarraidh: %s"
+
+#, c-format
+msgid "E398: Missing '=': %s"
+msgstr "E398: '=' ar iarraidh: %s"
+
+#, 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"
+
+msgid "E400: No cluster specified"
+msgstr "E400: Níor sonraíodh mogall"
+
+#, c-format
+msgid "E401: Pattern delimiter not found: %s"
+msgstr "E401: Teormharcóir patrúin gan aimsiú: %s"
+
+#, c-format
+msgid "E402: Garbage after pattern: %s"
+msgstr "E402: Dramhaíl i ndiaidh patrúin: %s"
+
+msgid "E403: syntax sync: line continuations pattern specified twice"
+msgstr "E403: comhréir sionc: tugadh patrún leanúint líne faoi dhó"
+
+#, c-format
+msgid "E404: Illegal arguments: %s"
+msgstr "E404: Argóintí neamhcheadaithe: %s"
+
+#, c-format
+msgid "E405: Missing equal sign: %s"
+msgstr "E405: Sín chothroime ar iarraidh: %s"
+
+#, c-format
+msgid "E406: Empty argument: %s"
+msgstr "E406: Argóint fholamh: %s"
+
+#, c-format
+msgid "E407: %s not allowed here"
+msgstr "E407: ní cheadaítear %s anseo"
+
+#, 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'"
+
+#, c-format
+msgid "E409: Unknown group name: %s"
+msgstr "E409: Ainm anaithnid grúpa: %s"
+
+#, c-format
+msgid "E410: Invalid :syntax subcommand: %s"
+msgstr "E410: Fo-ordú neamhbhailí :syntax: %s"
+
+msgid "E679: recursive loop loading syncolor.vim"
+msgstr "E679: lúb athchúrsach agus syncolor.vim á luchtú"
+
+#, c-format
+msgid "E411: highlight group not found: %s"
+msgstr "E411: Grúpa aibhsithe gan aimsiú: %s"
+
+#, c-format
+msgid "E412: Not enough arguments: \":highlight link %s\""
+msgstr "E412: Easpa argóintí: \":highlight link %s\""
+
+#, c-format
+msgid "E413: Too many arguments: \":highlight link %s\""
+msgstr "E413: An iomarca argóintí: \":highlight link %s\""
+
+msgid "E414: group has settings, highlight link ignored"
+msgstr ""
+"E414: tá socruithe ag an ghrúpa, ag déanamh neamhshuim ar nasc aibhsithe"
+
+#, c-format
+msgid "E415: unexpected equal sign: %s"
+msgstr "E415: sín chothroime gan choinne: %s"
+
+#, c-format
+msgid "E416: missing equal sign: %s"
+msgstr "E416: sín chothroime ar iarraidh: %s"
+
+#, c-format
+msgid "E417: missing argument: %s"
+msgstr "E417: argóint ar iarraidh: %s"
+
+#, c-format
+msgid "E418: Illegal value: %s"
+msgstr "E418: Luach neamhcheadaithe: %s"
+
+msgid "E419: FG color unknown"
+msgstr "E419: Dath anaithnid an chúlra"
+
+msgid "E420: BG color unknown"
+msgstr "E420: Dath anaithnid an tulra"
+
+#, c-format
+msgid "E421: Color name or number not recognized: %s"
+msgstr "E421: Níor aithníodh ainm/uimhir an datha: %s"
+
+#, c-format
+msgid "E422: terminal code too long: %s"
+msgstr "E422: cód teirminéil rófhada: %s"
+
+#, c-format
+msgid "E423: Illegal argument: %s"
+msgstr "E423: Argóint neamhcheadaithe: %s"
+
+msgid "E424: Too many different highlighting attributes in use"
+msgstr "E424: An iomarca tréithe aibhsithe in úsáid"
+
+msgid "E669: Unprintable character in group name"
+msgstr "E669: Carachtar neamhghrafach in ainm grúpa"
+
+msgid "W18: Invalid character in group name"
+msgstr "W18: Carachtar neamhbhailí in ainm grúpa"
+
+msgid "E555: at bottom of tag stack"
+msgstr "E555: in íochtar na cruaiche clibeanna"
+
+msgid "E556: at top of tag stack"
+msgstr "E556: in uachtar na cruaiche clibeanna"
+
+msgid "E425: Cannot go before first matching tag"
+msgstr "E425: Ní féidir a dhul roimh an chéad chlib chomhoiriúnach"
+
+#, c-format
+msgid "E426: tag not found: %s"
+msgstr "E426: clib gan aimsiú: %s"
+
+msgid " # pri kind tag"
+msgstr " # tos cin clib"
+
+msgid "file\n"
+msgstr "comhad\n"
+
+msgid "E427: There is only one matching tag"
+msgstr "E427: Tá aon chlib chomhoiriúnach amháin"
+
+msgid "E428: Cannot go beyond last matching tag"
+msgstr "E428: Ní féidir a dhul thar an chlib chomhoiriúnach deireanach"
+
+#, 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
+#, c-format
+msgid "tag %d of %d%s"
+msgstr "clib %d as %d%s"
+
+msgid " or more"
+msgstr " nó os a chionn"
+
+msgid " Using tag with different case!"
+msgstr " Ag úsáid clib le cás eile!"
+
+#, c-format
+msgid "E429: File \"%s\" does not exist"
+msgstr "E429: Níl a leithéid de chomhad \"%s\""
+
+#. Highlight title
+msgid ""
+"\n"
+" # TO tag FROM line in file/text"
+msgstr ""
+"\n"
+" # Go clib Ó líne i gcomhad/téacs"
+
+#, c-format
+msgid "Searching tags file %s"
+msgstr "Comhad clibeanna %s á chuardach"
+
+#, c-format
+msgid "E430: Tag file path truncated for %s\n"
+msgstr "E430: Teascadh conair an chomhaid clibeanna le haghaidh %s\n"
+
+#, c-format
+msgid "E431: Format error in tags file \"%s\""
+msgstr "E431: Earráid fhormáide i gcomhad clibeanna \"%s\""
+
+#, c-format
+msgid "Before byte %ld"
+msgstr "Roimh bheart %ld"
+
+#, c-format
+msgid "E432: Tags file not sorted: %s"
+msgstr "E432: Comhad clibeanna gan sórtáil: %s"
+
+#. never opened any tags file
+msgid "E433: No tags file"
+msgstr "E433: Níl aon chomhad clibeanna"
+
+msgid "Ignoring long line in tags file"
+msgstr "Ag déanamh neamhaird de líne fhada sa chomhad clibeanna"
+
+msgid "E434: Can't find tag pattern"
+msgstr "E434: Patrún clibe gan aimsiú"
+
+msgid "E435: Couldn't find tag, just guessing!"
+msgstr "E435: Clib gan aimsiú, ag tabhairt buille faoi thuairim!"
+
+msgid "' not known. Available builtin terminals are:"
+msgstr "' anaithnid. Is iad seo na teirminéil insuite:"
+
+msgid "defaulting to '"
+msgstr "réamhshocrú = '"
+
+msgid "E557: Cannot open termcap file"
+msgstr "E557: Ní féidir an comhad termcap a oscailt"
+
+msgid "E558: Terminal entry not found in terminfo"
+msgstr "E558: Iontráil teirminéil gan aimsiú sa terminfo"
+
+msgid "E559: Terminal entry not found in termcap"
+msgstr "E559: Iontráil teirminéil gan aimsiú sa termcap"
+
+#, c-format
+msgid "E436: No \"%s\" entry in termcap"
+msgstr "E436: Níl aon iontráil \"%s\" sa termcap"
+
+msgid "E437: terminal capability \"cm\" required"
+msgstr "E437: tá gá leis an chumas teirminéil \"cm\""
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Terminal keys ---"
+msgstr ""
+"\n"
+"--- Eochracha teirminéil ---"
+
+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"
+
+#. must display the prompt
+msgid "No undo possible; continue anyway"
+msgstr "Ní féidir a chealú; lean ar aghaidh mar sin féin"
+
+msgid "Already at oldest change"
+msgstr "Ag an athrú is sine cheana"
+
+msgid "Already at newest change"
+msgstr "Ag an athrú is nuaí cheana"
+
+#, c-format
+msgid "Undo number %ld not found"
+msgstr "Níor aimsíodh cealú uimhir a %ld"
+
+msgid "E438: u_undo: line numbers wrong"
+msgstr "E438: u_undo: líne-uimhreacha míchearta"
+
+msgid "more line"
+msgstr "líne eile"
+
+msgid "more lines"
+msgstr "líne eile"
+
+msgid "line less"
+msgstr "líne níos lú"
+
+msgid "fewer lines"
+msgstr "líne níos lú"
+
+msgid "change"
+msgstr "athrú"
+
+msgid "changes"
+msgstr "athrú"
+
+#, c-format
+msgid "%ld %s; %s #%ld %s"
+msgstr "%ld %s; %s #%ld %s"
+
+msgid "before"
+msgstr "roimh"
+
+msgid "after"
+msgstr "tar éis"
+
+msgid "Nothing to undo"
+msgstr "Níl faic le cealú"
+
+# columns?
+msgid "number changes time"
+msgstr "uimhir athruithe am"
+
+#, c-format
+msgid "%ld seconds ago"
+msgstr "%ld soicind ó shin"
+
+msgid "E790: undojoin is not allowed after undo"
+msgstr "E790: ní cheadaítear \"undojoin\" tar éis \"undo\""
+
+msgid "E439: undo list corrupt"
+msgstr "E439: tá an liosta cealaithe truaillithe"
+
+msgid "E440: undo line missing"
+msgstr "E440: líne chealaithe ar iarraidh"
+
+#. Only MS VC 4.1 and earlier can do Win32s
+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"
+"Included patches: "
+msgstr ""
+"\n"
+"Paistí san áireamh: "
+
+msgid ""
+"\n"
+"Extra patches: "
+msgstr ""
+"\n"
+"Paistí sa bhreis: "
+
+msgid "Modified by "
+msgstr "Mionathraithe ag "
+
+msgid ""
+"\n"
+"Compiled "
+msgstr ""
+"\n"
+"Tiomsaithe "
+
+# with "Tiomsaithe"
+msgid "by "
+msgstr "ag "
+
+msgid ""
+"\n"
+"Huge version "
+msgstr ""
+"\n"
+"Leagan ollmhór "
+
+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."
+
+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 " Features included (+) or not (-):\n"
+msgstr " Gnéithe san áireamh (+) nó nach bhfuil (-):\n"
+
+msgid " system vimrc file: \""
+msgstr " comhad vimrc an chórais: \""
+
+msgid " user vimrc file: \""
+msgstr " comhad vimrc úsáideora: \""
+
+msgid " 2nd user vimrc file: \""
+msgstr " dara comhad vimrc úsáideora: \""
+
+msgid " 3rd user vimrc file: \""
+msgstr " tríú comhad vimrc úsáideora: \""
+
+msgid " user exrc file: \""
+msgstr " comhad exrc úsáideora: \""
+
+msgid " 2nd user exrc file: \""
+msgstr " dara comhad úsáideora exrc: \""
+
+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 " fall-back for $VIM: \""
+msgstr " rogha thánaisteach do $VIM: \""
+
+msgid " f-b for $VIMRUNTIME: \""
+msgstr " f-b do $VIMRUNTIME: \""
+
+msgid "Compilation: "
+msgstr "Tiomsú: "
+
+msgid "Compiler: "
+msgstr "Tiomsaitheoir: "
+
+msgid "Linking: "
+msgstr "Nascáil: "
+
+msgid " DEBUG BUILD"
+msgstr " LEAGAN DÍFHABHTAITHE"
+
+msgid "VIM - Vi IMproved"
+msgstr "VIM - Vi IMproved"
+
+msgid "version "
+msgstr "leagan "
+
+msgid "by Bram Moolenaar et al."
+msgstr "le Bram Moolenaar et al."
+
+msgid "Vim is open source and freely distributable"
+msgstr "Is saorbhogearra é Vim"
+
+msgid "Help poor children in Uganda!"
+msgstr "Tabhair cabhair do pháistí bochta in Uganda!"
+
+msgid "type :help iccf<Enter> for information "
+msgstr "clóscríobh :help iccf<Enter> chun eolas a fháil "
+
+msgid "type :q<Enter> to exit "
+msgstr "clóscríobh :q<Enter> chun scoir "
+
+msgid "type :help<Enter> or <F1> for on-line help"
+msgstr "clóscríobh :help<Enter> nó <F1> le haghaidh cabhrach ar líne"
+
+msgid "type :help version7<Enter> for version info"
+msgstr "clóscríobh :help version7<Enter> le haghaidh eolais faoin leagan"
+
+msgid "Running in Vi compatible mode"
+msgstr "Sa mhód comhoiriúnachta Vi"
+
+msgid "type :set nocp<Enter> for Vim defaults"
+msgstr ""
+"clóscríobh :set nocp<Enter> chun na réamhshocruithe Vim a thaispeáint"
+
+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"
+
+# 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!"
+
+msgid "Become a registered Vim user!"
+msgstr "Bí i d'úsáideoir cláraithe Vim!"
+
+msgid "type :help sponsor<Enter> for information "
+msgstr "clóscríobh :help sponsor<Enter> chun eolas a fháil "
+
+msgid "type :help register<Enter> for information "
+msgstr "clóscríobh :help register<Enter> chun eolas a fháil "
+
+msgid "menu Help->Sponsor/Register for information "
+msgstr "roghchlár Help->Sponsor/Register chun eolas a fháil "
+
+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 "Already only one window"
+msgstr "Níl ach aon fhuinneog amháin ann cheana"
+
+msgid "E441: There is no preview window"
+msgstr "E441: Níl aon fhuinneog réamhamhairc ann"
+
+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"
+
+msgid "E443: Cannot rotate when another window is split"
+msgstr "E443: Ní féidir rothlú nuair atá fuinneog eile scoilte"
+
+msgid "E444: Cannot close last window"
+msgstr "E444: Ní féidir an fhuinneog dheiridh a dhúnadh"
+
+msgid "E813: Cannot close autocmd window"
+msgstr "E813: Ní féidir fuinneog autocmd a dhúnadh"
+
+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"
+
+msgid "E445: Other window contains changes"
+msgstr "E445: Tá athruithe ann san fhuinneog eile"
+
+msgid "E446: No file name under cursor"
+msgstr "E446: Níl ainm comhaid faoin chúrsóir"
+
+#, c-format
+msgid "E447: Can't find file \"%s\" in path"
+msgstr "E447: Níl aon fháil ar chomhad \"%s\" sa chonair"
+
+#, c-format
+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"
+
+#. Now concatenate
+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 "--No lines in buffer--"
+msgstr "--Tá an maolán folamh--"
+
+#.
+#. * 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 "E471: Argument required"
+msgstr "E471: Tá gá le hargóint"
+
+msgid "E10: \\ should be followed by /, ? or &"
+msgstr "E10: Ba chóir /, ? nó & a chur i ndiaidh \\"
+
+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 "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 "E171: Missing :endif"
+msgstr "E171: :endif ar iarraidh"
+
+msgid "E600: Missing :endtry"
+msgstr "E600: :endtry ar iarraidh"
+
+msgid "E170: Missing :endwhile"
+msgstr "E170: :endwhile ar iarraidh"
+
+msgid "E170: Missing :endfor"
+msgstr "E170: :endfor ar iarraidh"
+
+msgid "E588: :endwhile without :while"
+msgstr "E588: :endwhile gan :while"
+
+msgid "E588: :endfor without :for"
+msgstr "E588: :endfor gan :for"
+
+msgid "E13: File exists (add ! to override)"
+msgstr "E13: Tá comhad ann cheana (cuir ! leis an ordú chun forscríobh)"
+
+msgid "E472: Command failed"
+msgstr "E472: Theip ar ordú"
+
+#, c-format
+msgid "E234: Unknown fontset: %s"
+msgstr "E234: Tacar cló anaithnid: %s"
+
+#, c-format
+msgid "E235: Unknown font: %s"
+msgstr "E235: Clófhoireann anaithnid: %s"
+
+#, c-format
+msgid "E236: Font \"%s\" is not fixed-width"
+msgstr "E236: Ní cló aonleithid é \"%s\""
+
+msgid "E473: Internal error"
+msgstr "E473: Earráid inmheánach"
+
+msgid "Interrupted"
+msgstr "Idirbhriste"
+
+msgid "E14: Invalid address"
+msgstr "E14: Drochsheoladh"
+
+msgid "E474: Invalid argument"
+msgstr "E474: Argóint neamhbhailí"
+
+#, c-format
+msgid "E475: Invalid argument: %s"
+msgstr "E475: Argóint neamhbhailí: %s"
+
+#, c-format
+msgid "E15: Invalid expression: %s"
+msgstr "E15: Slonn neamhbhailí: %s"
+
+msgid "E16: Invalid range"
+msgstr "E16: Raon neamhbhailí"
+
+msgid "E476: Invalid command"
+msgstr "E476: Ordú neamhbhailí"
+
+#, c-format
+msgid "E17: \"%s\" is a directory"
+msgstr "E17: is comhadlann \"%s\""
+
+#, c-format
+msgid "E364: Library call failed for \"%s()\""
+msgstr "E364: Theip ar ghlao leabharlainne \"%s()\""
+
+#, c-format
+msgid "E448: Could not load library function %s"
+msgstr "E448: Ní féidir feidhm %s leabharlainne a luchtú"
+
+msgid "E19: Mark has invalid line number"
+msgstr "E19: Tá líne-uimhir neamhbhailí ag an mharc"
+
+msgid "E20: Mark not set"
+msgstr "E20: Marc gan socrú"
+
+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 "E22: Scripts nested too deep"
+msgstr "E22: scripteanna neadaithe ródhomhain"
+
+msgid "E23: No alternate file"
+msgstr "E23: Níl aon chomhad malartach"
+
+msgid "E24: No such abbreviation"
+msgstr "E24: Níl a leithéid de ghiorrúchán ann"
+
+msgid "E477: No ! allowed"
+msgstr "E477: Ní cheadaítear !"
+
+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 "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"
+
+#, c-format
+msgid "E28: No such highlight group name: %s"
+msgstr "E28: Níl a leithéid d'ainm grúpa aibhsithe: %s"
+
+msgid "E29: No inserted text yet"
+msgstr "E29: Níl aon téacs ionsáite go dtí seo"
+
+msgid "E30: No previous command line"
+msgstr "E30: Níl aon líne na n-orduithe roimhe seo"
+
+msgid "E31: No such mapping"
+msgstr "E31: Níl a leithéid de mhapáil"
+
+msgid "E479: No match"
+msgstr "E479: Níl aon rud comhoiriúnach ann"
+
+#, c-format
+msgid "E480: No match: %s"
+msgstr "E480: Níl aon rud comhoiriúnach ann: %s"
+
+msgid "E32: No file name"
+msgstr "E32: Níl aon ainm comhaid"
+
+msgid "E33: No previous substitute regular expression"
+msgstr "E33: Níl aon slonn ionadaíochta roimhe seo"
+
+msgid "E34: No previous command"
+msgstr "E34: Níl aon ordú roimhe seo"
+
+msgid "E35: No previous regular expression"
+msgstr "E35: Níl aon slonn ionadaíochta roimhe seo"
+
+msgid "E481: No range allowed"
+msgstr "E481: Ní cheadaítear raon"
+
+msgid "E36: Not enough room"
+msgstr "E36: Níl slí a dhóthain ann"
+
+#, c-format
+msgid "E247: no registered server named \"%s\""
+msgstr "E247: níl aon fhreastalaí cláraithe leis an ainm \"%s\""
+
+#, c-format
+msgid "E482: Can't create file %s"
+msgstr "E482: Ní féidir comhad %s a chruthú"
+
+msgid "E483: Can't get temp file name"
+msgstr "E483: Níl aon fháil ar ainm comhaid sealadach"
+
+#, c-format
+msgid "E484: Can't open file %s"
+msgstr "E484: Ní féidir comhad %s a oscailt"
+
+#, c-format
+msgid "E485: Can't read file %s"
+msgstr "E485: Ní féidir comhad %s a léamh"
+
+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 "E38: Null argument"
+msgstr "E38: Argóint nialasach"
+
+msgid "E39: Number expected"
+msgstr "E39: Ag súil le huimhir"
+
+#, c-format
+msgid "E40: Can't open errorfile %s"
+msgstr "E40: Ní féidir an comhad earráide %s a oscailt"
+
+msgid "E233: cannot open display"
+msgstr "E233: ní féidir an scáileán a oscailt"
+
+msgid "E41: Out of memory!"
+msgstr "E41: Cuimhne ídithe!"
+
+msgid "Pattern not found"
+msgstr "Patrún gan aimsiú"
+
+#, c-format
+msgid "E486: Pattern not found: %s"
+msgstr "E486: Patrún gan aimsiú: %s"
+
+msgid "E487: Argument must be positive"
+msgstr "E487: Ní foláir argóint dheimhneach"
+
+msgid "E459: Cannot go back to previous directory"
+msgstr "E459: Ní féidir a fhilleadh ar an chomhadlann roimhe seo"
+
+msgid "E42: No Errors"
+msgstr "E42: Níl Aon Earráid Ann"
+
+msgid "E776: No location list"
+msgstr "E776: Gan liosta suíomh"
+
+msgid "E43: Damaged match string"
+msgstr "E43: Teaghrán cuardaigh loite"
+
+msgid "E44: Corrupted regexp program"
+msgstr "E44: Clár na sloinn ionadaíochta truaillithe"
+
+msgid "E45: 'readonly' option is set (add ! to override)"
+msgstr "E45: tá an rogha 'readonly' socraithe (cuir ! leis an ordú chun sárú)"
+
+#, c-format
+msgid "E46: Cannot change read-only variable \"%s\""
+msgstr "E46: Ní féidir athróg inléite amháin \"%s\" a athrú"
+
+#, 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 "E47: Error while reading errorfile"
+msgstr "E47: Earráid agus comhad earráide á léamh"
+
+msgid "E48: Not allowed in sandbox"
+msgstr "E48: Ní cheadaítear é seo i mbosca gainimh"
+
+msgid "E523: Not allowed here"
+msgstr "E523: Ní cheadaítear é anseo"
+
+msgid "E359: Screen mode setting not supported"
+msgstr "E359: Ní féidir an mód scáileáin a shocrú"
+
+msgid "E49: Invalid scroll size"
+msgstr "E49: Méid neamhbhailí scrollaithe"
+
+msgid "E91: 'shell' option is empty"
+msgstr "E91: rogha 'shell' folamh"
+
+msgid "E255: Couldn't read in sign data!"
+msgstr "E255: Níorbh fhéidir na sonraí comhartha a léamh!"
+
+msgid "E72: Close error on swap file"
+msgstr "E72: Earráid agus comhad babhtála á dhúnadh"
+
+msgid "E73: tag stack empty"
+msgstr "E73: tá cruach na gclibeanna folamh"
+
+msgid "E74: Command too complex"
+msgstr "E74: Ordú róchasta"
+
+msgid "E75: Name too long"
+msgstr "E75: Ainm rófhada"
+
+msgid "E76: Too many ["
+msgstr "E76: an iomarca ["
+
+msgid "E77: Too many file names"
+msgstr "E77: An iomarca ainmneacha comhaid"
+
+msgid "E488: Trailing characters"
+msgstr "E488: Carachtair chun deiridh"
+
+msgid "E78: Unknown mark"
+msgstr "E78: Marc anaithnid"
+
+msgid "E79: Cannot expand wildcards"
+msgstr "E79: Ní féidir saoróga a leathnú"
+
+msgid "E591: 'winheight' cannot be smaller than 'winminheight'"
+msgstr "E591: ní cheadaítear 'winheight' a bheith níos lú ná 'winminheight'"
+
+msgid "E592: 'winwidth' cannot be smaller than 'winminwidth'"
+msgstr "E592: ní cheadaítear 'winwidth' a bheith níos lú ná 'winminwidth'"
+
+msgid "E80: Error while writing"
+msgstr "E80: Earráid agus á scríobh"
+
+msgid "Zero count"
+msgstr "Nialas"
+
+msgid "E81: Using <SID> not in a script context"
+msgstr "E81: <SID> á úsáid nach i gcomhthéacs scripte"
+
+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"
+
+#, c-format
+msgid "E685: Internal error: %s"
+msgstr "E685: Earráid inmheánach: %s"
+
+msgid "E363: pattern uses more memory than 'maxmempattern'"
+msgstr "E363: úsáideann an patrún níos mó cuimhne ná 'maxmempattern'"
+
+msgid "E749: empty buffer"
+msgstr "E749: maolán folamh"
+
+msgid "E682: Invalid search pattern or delimiter"
+msgstr "E682: Patrún nó teormharcóir neamhbhailí cuardaigh"
+
+msgid "E139: File is loaded in another buffer"
+msgstr "E139: Tá an comhad luchtaithe i maolán eile"
+
+#, c-format
+msgid "E764: Option '%s' is not set"
+msgstr "E764: Rogha '%s' gan socrú"
+
+msgid "search hit TOP, continuing at BOTTOM"
+msgstr "Buaileadh an BARR le linn an chuardaigh, ag leanúint ag an CHRÍOCH"
+
+msgid "search hit BOTTOM, continuing at TOP"
+msgstr "Buaileadh an BUN le linn an chuardaigh, ag leanúint ag an BHARR"
+
+#~ msgid "E569: maximum number of cscope connections reached"
+#~ msgstr "E569: ní cheadaítear níos mó ná an líon uasta nasc cscope"
+
+#~ msgid "[NL found]"
+#~ msgstr "[NL aimsithe]"
+
+#~ msgid "-V[N]\t\tVerbose level"
+#~ msgstr "-V[N]\t\tFoclachas"
+
+#~ msgid "[Error List]"
+#~ msgstr "[Liosta Earráidí]"
+
+#~ msgid ""
+#~ "\n"
+#~ "Arguments recognised by kvim (KDE version):\n"
+#~ msgstr ""
+#~ "\n"
+#~ "Argóintí ar eolas do kvim (leagan KDE):\n"
+
+#~ msgid "-black\t\tUse reverse video"
+#~ msgstr "-black\t\tÚsáid fís aisiompaithe"
+
+#~ msgid "-tip\t\t\tDisplay the tip dialog on startup"
+#~ msgstr "-tip\t\t\tTaispeáin an dialóg leide ar tosach"
+
+#~ msgid "-notip\t\tDisable the tip dialog"
+#~ msgstr "-notip\t\tDíchumasaigh an dialóg leide"
+
+#~ msgid "--display <display>\tRun vim on <display>"
+#~ msgstr "--display <scáileán>\tRith vim ar <scáileán>"
+
+#~ msgid ""
+#~ "&Open Read-Only\n"
+#~ "&Edit anyway\n"
+#~ "&Recover\n"
+#~ "&Quit\n"
+#~ "&Abort\n"
+#~ "&Delete it"
+#~ msgstr ""
+#~ "&Oscail Inléite Amháin\n"
+#~ "&Eagraigh mar sin féin\n"
+#~ "&Athshlánaigh\n"
+#~ "S&coir\n"
+#~ "&Tobscoir\n"
+#~ "&Scrios é"
+
+#~ msgid "...(truncated)"
+#~ msgstr "...(teasctha)"
+
+#~ msgid ""
+#~ "\n"
+#~ "Vim: Got X error but we continue...\n"
+#~ msgstr ""
+#~ "\n"
+#~ "Vim: Fuarthas earráid X ach ar aghaidh linn...\n"
+
+#~ msgid "Character used for SLASH must be ASCII; in %s line %d: %s"
+#~ msgstr ""
+#~ "Ní mór do charachtar a úsáidtear ar SLASH a bheith ASCII; i %s líne %d: %s"
+
+#~ msgid "%ld changes"
+#~ msgstr "%ld athrú"
+
+#~ msgid "with KDE GUI."
+#~ msgstr "le GUI KDE."
+
+#~ msgid "E757: Wrong file ID in spell file"
+#~ msgstr "E757: Aitheantas mícheart comhaid i gcomhad litrithe"
+
+#~ msgid "Duplicate FOL in %s line %d"
+#~ msgstr "FOL dúblach i %s líne %d"
+
+#~ msgid "Duplicate LOW in %s line %d"
+#~ msgstr "LOW dúblach i %s líne %d"
+
+#~ msgid "Duplicate UPP in %s line %d"
+#~ msgstr "UPP dúblach i %s líne %d"
+
+#~ msgid "[string too long]"
+#~ msgstr "[teaghrán rófhada]"
+
+#~ msgid "Hit ENTER to continue"
+#~ msgstr "Brúigh ENTER le leanúint"
+
+#~ msgid " (RET/BS: line, SPACE/b: page, d/u: half page, q: quit)"
+#~ msgstr " (RET/BS: líne, SPÁS/b: lch, d/u: leathlch, q: scoir)"
+
+#~ msgid " (RET: line, SPACE: page, d: half page, q: quit)"
+#~ msgstr " (RET: líne, SPÁS: lch, d: leathlch, q: scoir)"
+
+#~ msgid "E56: %s* operand could be empty"
+#~ msgstr "E56: is féidir go bhfuil an t-oibreann %s* folamh"
+
+#~ msgid "E57: %s+ operand could be empty"
+#~ msgstr "E57: is féidir go bhfuil an t-oibreann %s+ folamh"
+
+#~ msgid "E58: %s{ operand could be empty"
+#~ msgstr "E58: is féidir go bhfuil an t-oibreann %s( folamh"
+
+#~ msgid "Enter nr of choice (<CR> to abort): "
+#~ msgstr "Iontráil uimhir do rogha (<Enter>=tobscor): "
+
+#~ msgid "E361: Crash intercepted; regexp too complex?"
+#~ msgstr "E361: Ceapadh tuairt; slonn ionadaíochta róchasta?"
+
+#~ msgid "E363: pattern caused out-of-stack error"
+#~ msgstr "E363: ghin an patrún earráid as-an-chruach"
diff --git a/src/po/it.po b/src/po/it.po
new file mode 100644
index 0000000000..aabd20e08b
--- /dev/null
+++ b/src/po/it.po
@@ -0,0 +1,6803 @@
+# Italian Translation for Vim
+#
+# FIRST AUTHOR Antonio Colombo <azc100@gmail.com>, 2000
+#
+# Ogni commento è benvenuto...
+# Every remark is very welcome...
+#
+# Translation done under Linux and using an Italian keyboard.
+# English words left in the text are unmodified at plural.
+# Option names are mostly left untouched.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: vim 7.4b\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2013-07-29 16:11+0200\n"
+"PO-Revision-Date: 2013-08-03 17:14+0200\n"
+"Last-Translator: Vlad Sandrini <vlad.gently@gmail.com>\n"
+"Language-Team: Italian"
+" Antonio Colombo <azc100@gmail.com>"
+" Vlad Sandrini <vlad.gently@gmail.com>"
+" Luciano Montanaro <mikelima@cirulla.net>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=ISO_8859-1\n"
+"Content-Transfer-Encoding: 8-bit\n"
+
+msgid "E831: bf_key_init() called with empty password"
+msgstr "E831: chiamata a bf_key_init() con password nulla"
+
+msgid "E820: sizeof(uint32_t) != 4"
+msgstr "E820: sizeof(uint32_t) != 4"
+
+msgid "E817: Blowfish big/little endian use wrong"
+msgstr "E817: uso errato di big/little endian in Blowfish"
+
+msgid "E818: sha256 test failed"
+msgstr "E818: test sha256 fallito"
+
+msgid "E819: Blowfish test failed"
+msgstr "E819: test Blowfish fallito"
+
+msgid "[Location List]"
+msgstr "[Lista Locazioni]"
+
+msgid "[Quickfix List]"
+msgstr "[Lista Quickfix]"
+
+msgid "E855: Autocommands caused command to abort"
+msgstr "E855: Comando non completato a causa di autocomandi"
+
+msgid "E82: Cannot allocate any buffer, exiting..."
+msgstr "E82: Non riesco ad allocare alcun buffer, esco..."
+
+msgid "E83: Cannot allocate buffer, using other one..."
+msgstr "E83: Non riesco ad allocare un buffer, uso l'altro..."
+
+msgid "E515: No buffers were unloaded"
+msgstr "E515: Nessun buffer scaricato"
+
+msgid "E516: No buffers were deleted"
+msgstr "E516: Nessun buffer tolto dalla lista"
+
+msgid "E517: No buffers were wiped out"
+msgstr "E517: Nessun buffer cancellato"
+
+msgid "1 buffer unloaded"
+msgstr "1 buffer scaricato"
+
+#, c-format
+msgid "%d buffers unloaded"
+msgstr "%d buffer scaricati"
+
+msgid "1 buffer deleted"
+msgstr "1 buffer tolto dalla lista"
+
+#, c-format
+msgid "%d buffers deleted"
+msgstr "%d buffer tolti dalla lista"
+
+msgid "1 buffer wiped out"
+msgstr "1 buffer cancellato"
+
+#, c-format
+msgid "%d buffers wiped out"
+msgstr "%d buffer cancellati"
+
+msgid "E84: No modified buffer found"
+msgstr "E84: Nessun buffer risulta modificato"
+
+#. back where we started, didn't find anything.
+msgid "E85: There is no listed buffer"
+msgstr "E85: Non c'è alcun buffer elencato"
+
+#, c-format
+msgid "E86: Buffer %ld does not exist"
+msgstr "E86: Non esiste il buffer %ld"
+
+msgid "E87: Cannot go beyond last buffer"
+msgstr "E87: Non posso oltrepassare l'ultimo buffer"
+
+msgid "E88: Cannot go before first buffer"
+msgstr "E88: Non posso andare prima del primo buffer"
+
+#, c-format
+msgid "E89: No write since last change for buffer %ld (add ! to override)"
+msgstr ""
+"E89: Buffer %ld non salvato dopo modifica (aggiungi ! per eseguire comunque)"
+
+msgid "E90: Cannot unload last buffer"
+msgstr "E90: Non riesco a scaricare l'ultimo buffer"
+
+msgid "W14: Warning: List of file names overflow"
+msgstr "W14: Attenzione: Superato limite della lista dei nomi di file"
+
+#, c-format
+msgid "E92: Buffer %ld not found"
+msgstr "E92: Buffer %ld non trovato"
+
+#, c-format
+msgid "E93: More than one match for %s"
+msgstr "E93: Più di una corrispondenza per %s"
+
+#, c-format
+msgid "E94: No matching buffer for %s"
+msgstr "E94: Nessun buffer corrispondente a %s"
+
+#, c-format
+msgid "line %ld"
+msgstr "linea %ld"
+
+msgid "E95: Buffer with this name already exists"
+msgstr "E95: C'è già un buffer con questo nome"
+
+msgid " [Modified]"
+msgstr " [Modificato]"
+
+msgid "[Not edited]"
+msgstr "[Non elaborato]"
+
+msgid "[New file]"
+msgstr "[File nuovo]"
+
+msgid "[Read errors]"
+msgstr "[Errori in lettura]"
+
+msgid "[RO]"
+msgstr "[Sola Lettura]"
+
+msgid "[readonly]"
+msgstr "[in sola lettura]"
+
+msgid "1 line --%d%%--"
+msgstr "1 linea --%d%%--"
+
+msgid "%ld lines --%d%%--"
+msgstr "%ld linee --%d%%--"
+
+msgid "line %ld of %ld --%d%%-- col "
+msgstr "linea %ld di %ld --%d%%-- col "
+
+msgid "[No Name]"
+msgstr "[Senza nome]"
+
+#. must be a help buffer
+msgid "help"
+msgstr "aiuto"
+
+msgid "[Help]"
+msgstr "[Aiuto]"
+
+msgid "[Preview]"
+msgstr "[Anteprima]"
+
+msgid "All"
+msgstr "Tut"
+
+msgid "Bot"
+msgstr "Fon"
+
+msgid "Top"
+msgstr "Cim"
+
+msgid ""
+"\n"
+"# Buffer list:\n"
+msgstr ""
+"\n"
+"# Lista Buffer:\n"
+
+msgid "[Scratch]"
+msgstr "[Volatile]"
+
+msgid ""
+"\n"
+"--- Signs ---"
+msgstr ""
+"\n"
+"--- Segni ---"
+
+#, c-format
+msgid "Signs for %s:"
+msgstr "Segni per %s:"
+
+#, c-format
+msgid " line=%ld id=%d name=%s"
+msgstr " linea=%ld id=%d, nome=%s"
+
+#, c-format
+msgid "E96: Can not diff more than %ld buffers"
+msgstr "E96: Non supporto differenze fra più di %ld buffer"
+
+msgid "E810: Cannot read or write temp files"
+msgstr "E810: Non riesco a leggere o scrivere file temporanei"
+
+msgid "E97: Cannot create diffs"
+msgstr "E97: Non riesco a creare differenze"
+
+msgid "Patch file"
+msgstr "File di differenze"
+
+msgid "E816: Cannot read patch output"
+msgstr "E816: Non riesco a leggere output del comando 'patch'"
+
+msgid "E98: Cannot read diff output"
+msgstr "E98: Non riesco a leggere output del comando 'diff'"
+
+msgid "E99: Current buffer is not in diff mode"
+msgstr "E99: Buffer corrente non in modalità 'diff'"
+
+msgid "E793: No other buffer in diff mode is modifiable"
+msgstr "E793: Nessun altro buffer è modificabile in modalità 'diff'"
+
+msgid "E100: No other buffer in diff mode"
+msgstr "E100: Non c'è nessun altro buffer in modalità 'diff'"
+
+msgid "E101: More than two buffers in diff mode, don't know which one to use"
+msgstr "E101: Più di due buffer in modalità 'diff', non so quale usare"
+
+#, c-format
+msgid "E102: Can't find buffer \"%s\""
+msgstr "E102: Non riesco a trovare il buffer: \"%s\""
+
+#, c-format
+msgid "E103: Buffer \"%s\" is not in diff mode"
+msgstr "E103: Il buffer \"%s\" non è in modalità 'diff'"
+
+msgid "E787: Buffer changed unexpectedly"
+msgstr "E787: Il buffer è variato inaspettatamente"
+
+msgid "E104: Escape not allowed in digraph"
+msgstr "E104: Escape not ammesso nei digrammi"
+
+msgid "E544: Keymap file not found"
+msgstr "E544: File keymap non trovato"
+
+msgid "E105: Using :loadkeymap not in a sourced file"
+msgstr "E105: Uso di :loadkeymap fuori da un file di comandi"
+
+msgid "E791: Empty keymap entry"
+msgstr "E791: Nessuna keymap per questo tasto"
+
+msgid " Keyword completion (^N^P)"
+msgstr " Completamento Keyword (^N^P)"
+
+#. ctrl_x_mode == 0, ^P/^N compl.
+msgid " ^X mode (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)"
+msgstr " modalità ^X (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)"
+
+msgid " Whole line completion (^L^N^P)"
+msgstr " Completamento Linea Intera (^L^N^P)"
+
+msgid " File name completion (^F^N^P)"
+msgstr " Completamento nomi File (^F^N^P)"
+
+msgid " Tag completion (^]^N^P)"
+msgstr " Completamento Tag (^]^N^P)"
+
+msgid " Path pattern completion (^N^P)"
+msgstr " Completamento modello Path (^N^P)"
+
+msgid " Definition completion (^D^N^P)"
+msgstr " Completamento Definizione (^D^N^P)"
+
+msgid " Dictionary completion (^K^N^P)"
+msgstr " Completamento Dizionario (^K^N^P)"
+
+msgid " Thesaurus completion (^T^N^P)"
+msgstr " Completamento Thesaurus (^T^N^P)"
+
+msgid " Command-line completion (^V^N^P)"
+msgstr " Completamento linea comandi (^V^N^P)"
+
+msgid " User defined completion (^U^N^P)"
+msgstr " Completamento definito dall'utente (^U^N^P)"
+
+msgid " Omni completion (^O^N^P)"
+msgstr " Completamento globale (^O^N^P)"
+
+msgid " Spelling suggestion (s^N^P)"
+msgstr " Suggerimento ortografico (s^N^P)"
+
+msgid " Keyword Local completion (^N^P)"
+msgstr " Completamento Keyword Locale (^N^P)"
+
+msgid "Hit end of paragraph"
+msgstr "Giunto alla fine del paragrafo"
+
+msgid "E839: Completion function changed window"
+msgstr "E839: La funzione di completamento ha modificato la finestra"
+
+msgid "E840: Completion function deleted text"
+msgstr "E840: La funzione di completamento ha eliminato del testo"
+
+msgid "'dictionary' option is empty"
+msgstr "l'opzione 'dictionary' non è impostata"
+
+msgid "'thesaurus' option is empty"
+msgstr "l'opzione 'thesaurus' non è impostata"
+
+#, c-format
+msgid "Scanning dictionary: %s"
+msgstr "Scansione dizionario: %s"
+
+msgid " (insert) Scroll (^E/^Y)"
+msgstr " (inserisci) Scroll (^E/^Y)"
+
+msgid " (replace) Scroll (^E/^Y)"
+msgstr " (sostituisci) Scroll (^E/^Y)"
+
+#, c-format
+msgid "Scanning: %s"
+msgstr "Scansione: %s"
+
+msgid "Scanning tags."
+msgstr "Scansione tag."
+
+msgid " Adding"
+msgstr " Aggiungo"
+
+#. 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.
+#.
+msgid "-- Searching..."
+msgstr "-- Ricerca..."
+
+msgid "Back at original"
+msgstr "Ritorno all'originale"
+
+msgid "Word from other line"
+msgstr "Parola da un'altra linea"
+
+msgid "The only match"
+msgstr "L'unica corrispondenza"
+
+#, c-format
+msgid "match %d of %d"
+msgstr "corrispondenza %d di %d"
+
+#, c-format
+msgid "match %d"
+msgstr "corrispondenza %d"
+
+msgid "E18: Unexpected characters in :let"
+msgstr "E18: Caratteri non previsti in :let"
+
+#, c-format
+msgid "E684: list index out of range: %ld"
+msgstr "E684: indice lista fuori intervallo: %ld"
+
+#, c-format
+msgid "E121: Undefined variable: %s"
+msgstr "E121: Variabile non definita: %s"
+
+msgid "E111: Missing ']'"
+msgstr "E111: Manca ']'"
+
+#, c-format
+msgid "E686: Argument of %s must be a List"
+msgstr "E686: L'argomento di %s deve essere una Lista"
+
+#, c-format
+msgid "E712: Argument of %s must be a List or Dictionary"
+msgstr "E712: L'argomento di %s deve essere una Lista o un Dizionario"
+
+msgid "E713: Cannot use empty key for Dictionary"
+msgstr "E713: Non posso usare una chiave nulla per il Dizionario"
+
+msgid "E714: List required"
+msgstr "E714: È necessaria una Lista"
+
+msgid "E715: Dictionary required"
+msgstr "E715: È necessario un Dizionario"
+
+#, c-format
+msgid "E118: Too many arguments for function: %s"
+msgstr "E118: Troppi argomenti per la funzione: %s"
+
+#, c-format
+msgid "E716: Key not present in Dictionary: %s"
+msgstr "E716: Chiave assente dal Dizionario: %s"
+
+#, c-format
+msgid "E122: Function %s already exists, add ! to replace it"
+msgstr "E122: La funzione %s esiste già, aggiungi ! per sostituirla"
+
+msgid "E717: Dictionary entry already exists"
+msgstr "E717: C'è già la voce nel Dizionario"
+
+msgid "E718: Funcref required"
+msgstr "E718: Funcref necessario"
+
+msgid "E719: Cannot use [:] with a Dictionary"
+msgstr "E719: Non posso usare [:] con un Dizionario"
+
+#, c-format
+msgid "E734: Wrong variable type for %s="
+msgstr "E734: Tipo di variabile errato per %s="
+
+#, c-format
+msgid "E130: Unknown function: %s"
+msgstr "E130: Funzione sconosciuta: %s"
+
+#, c-format
+msgid "E461: Illegal variable name: %s"
+msgstr "E461: Nome di variabile non ammesso: %s"
+
+# nuovo
+msgid "E806: using Float as a String"
+msgstr "E806: uso di un numero con virgola come stringa"
+
+msgid "E687: Less targets than List items"
+msgstr "E687: Destinazioni più numerose degli elementi di Lista"
+
+msgid "E688: More targets than List items"
+msgstr "E688: Destinazioni meno numerose degli elementi di Lista"
+
+msgid "Double ; in list of variables"
+msgstr "Doppio ; nella lista di variabili"
+
+#, c-format
+msgid "E738: Can't list variables for %s"
+msgstr "E738: Non riesco a elencare le variabili per %s"
+
+msgid "E689: Can only index a List or Dictionary"
+msgstr "E689: Posso indicizzare solo una Lista o un Dizionario"
+
+msgid "E708: [:] must come last"
+msgstr "E708: [:] deve essere alla fine"
+
+msgid "E709: [:] requires a List value"
+msgstr "E709: [:] necessita un valore Lista"
+
+msgid "E710: List value has more items than target"
+msgstr "E710: Il valore Lista ha più elementi della destinazione"
+
+msgid "E711: List value has not enough items"
+msgstr "E711: Il valore Lista non ha elementi sufficienti"
+
+msgid "E690: Missing \"in\" after :for"
+msgstr "E690: Manca \"in\" dopo :for"
+
+#, c-format
+msgid "E107: Missing parentheses: %s"
+msgstr "E107: Mancano parentesi: %s"
+
+#, c-format
+msgid "E108: No such variable: \"%s\""
+msgstr "E108: Variabile inesistente: \"%s\""
+
+msgid "E743: variable nested too deep for (un)lock"
+msgstr "E743: variabile troppo nidificata per lock/unlock"
+
+msgid "E109: Missing ':' after '?'"
+msgstr "E109: Manca ':' dopo '?'"
+
+msgid "E691: Can only compare List with List"
+msgstr "E691: Posso confrontare una Lista solo con un'altra Lista"
+
+msgid "E692: Invalid operation for Lists"
+msgstr "E692: Operazione non valida per Liste"
+
+msgid "E735: Can only compare Dictionary with Dictionary"
+msgstr "E735: Posso confrontare un Dizionario solo con un altro Dizionario"
+
+msgid "E736: Invalid operation for Dictionary"
+msgstr "E736: Operazione non valida per Dizionari"
+
+msgid "E693: Can only compare Funcref with Funcref"
+msgstr "E693: Posso confrontare un Funcref solo con un Funcref"
+
+msgid "E694: Invalid operation for Funcrefs"
+msgstr "E694: Operazione non valida per Funcref"
+
+msgid "E804: Cannot use '%' with Float"
+msgstr "E804: Non si può usare '%' con un numero con virgola"
+
+msgid "E110: Missing ')'"
+msgstr "E110: Manca ')'"
+
+msgid "E695: Cannot index a Funcref"
+msgstr "E695: Non posso indicizzare un Funcref"
+
+#, c-format
+msgid "E112: Option name missing: %s"
+msgstr "E112: Nome Opzione mancante: %s"
+
+#, c-format
+msgid "E113: Unknown option: %s"
+msgstr "E113: Opzione inesistente: %s"
+
+#, c-format
+msgid "E114: Missing quote: %s"
+msgstr "E114: Manca '\"': %s"
+
+#, c-format
+msgid "E115: Missing quote: %s"
+msgstr "E115: Manca apostrofo: %s"
+
+#, c-format
+msgid "E696: Missing comma in List: %s"
+msgstr "E696: Manca virgola nella Lista: %s"
+
+#, c-format
+msgid "E697: Missing end of List ']': %s"
+msgstr "E697: Manca ']' a fine Lista: %s"
+
+#, c-format
+msgid "E720: Missing colon in Dictionary: %s"
+msgstr "E720: Manca ':' nel Dizionario: %s"
+
+#, c-format
+msgid "E721: Duplicate key in Dictionary: \"%s\""
+msgstr "E721: Chiave duplicata nel Dizionario: \"%s\""
+
+#, c-format
+msgid "E722: Missing comma in Dictionary: %s"
+msgstr "E722: Manca virgola nel Dizionario: %s"
+
+#, c-format
+msgid "E723: Missing end of Dictionary '}': %s"
+msgstr "E723: Manca '}' a fine Dizionario: %s"
+
+msgid "E724: variable nested too deep for displaying"
+msgstr "E724: variabile troppo nidificata per la visualizzazione"
+
+#, c-format
+msgid "E740: Too many arguments for function %s"
+msgstr "E740: Troppi argomenti per la funzione: %s"
+
+#, c-format
+msgid "E116: Invalid arguments for function %s"
+msgstr "E116: Argomenti non validi per la funzione: %s"
+
+#, c-format
+msgid "E117: Unknown function: %s"
+msgstr "E117: Funzione sconosciuta: %s"
+
+#, c-format
+msgid "E119: Not enough arguments for function: %s"
+msgstr "E119: La funzione: %s richiede più argomenti"
+
+#, c-format
+msgid "E120: Using <SID> not in a script context: %s"
+msgstr "E120: Uso di <SID> fuori dal contesto di uno script: %s"
+
+#, c-format
+msgid "E725: Calling dict function without Dictionary: %s"
+msgstr "E725: Chiamata di funzione dict in assenza di Dizionario: %s"
+
+msgid "E808: Number or Float required"
+msgstr "E808: Ci vuole un numero intero o con virgola"
+
+msgid "add() argument"
+msgstr "argomento di add()"
+
+msgid "E699: Too many arguments"
+msgstr "E699: Troppi argomenti"
+
+msgid "E785: complete() can only be used in Insert mode"
+msgstr "E785: complete() può essere usata solo in modalità inserimento"
+
+#.
+#. * 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"
+
+#, c-format
+msgid "E737: Key already exists: %s"
+msgstr "E737: Chiave già esistente: %s"
+
+msgid "extend() argument"
+msgstr "argomento di extend()"
+
+msgid "map() argument"
+msgstr "argomento di map()"
+
+msgid "filter() argument"
+msgstr "argomento di filter()"
+
+#, c-format
+msgid "+-%s%3ld lines: "
+msgstr "+-%s%3ld linee: "
+
+#, c-format
+msgid "E700: Unknown function: %s"
+msgstr "E700: Funzione sconosciuta: %s"
+
+msgid ""
+"&OK\n"
+"&Cancel"
+msgstr ""
+"&OK\n"
+"&Non eseguire"
+
+msgid "called inputrestore() more often than inputsave()"
+msgstr "inputrestore() chiamata più volte di inputsave()"
+
+msgid "insert() argument"
+msgstr "argomento di insert()"
+
+msgid "E786: Range not allowed"
+msgstr "E786: Intervallo non consentito"
+
+msgid "E701: Invalid type for len()"
+msgstr "E701: Tipo non valido per len()"
+
+msgid "E726: Stride is zero"
+msgstr "E726: Incremento indice a zero"
+
+msgid "E727: Start past end"
+msgstr "E727: Indice iniziale superiore a quello finale"
+
+msgid "<empty>"
+msgstr "<vuoto>"
+
+msgid "E240: No connection to Vim server"
+msgstr "E240: Manca connessione con server Vim"
+
+#, c-format
+msgid "E241: Unable to send to %s"
+msgstr "E241: Impossibile inviare a %s"
+
+msgid "E277: Unable to read a server reply"
+msgstr "E277: Non riesco a leggere una risposta del server"
+
+msgid "remove() argument"
+msgstr "argomento di remove()"
+
+msgid "E655: Too many symbolic links (cycle?)"
+msgstr "E655: Troppi link simbolici (circolarità?)"
+
+msgid "reverse() argument"
+msgstr "argomento di reverse()"
+
+msgid "E258: Unable to send to client"
+msgstr "E258: Impossibile inviare al client"
+
+msgid "sort() argument"
+msgstr "argomento di sort()"
+
+msgid "E702: Sort compare function failed"
+msgstr "E702: Funzione confronto nel sort non riuscita"
+
+msgid "(Invalid)"
+msgstr "(Non valido)"
+
+msgid "E677: Error writing temp file"
+msgstr "E677: Errore in scrittura su file temporaneo"
+
+msgid "E805: Using a Float as a Number"
+msgstr "E805: Uso di un numero con virgola come intero"
+
+msgid "E703: Using a Funcref as a Number"
+msgstr "E703: Uso di Funcref come Numero"
+
+msgid "E745: Using a List as a Number"
+msgstr "E745: Uso di Lista come Numero"
+
+msgid "E728: Using a Dictionary as a Number"
+msgstr "E728: Uso di Dizionario come Numero"
+
+msgid "E729: using Funcref as a String"
+msgstr "E729: uso di Funcref come Stringa"
+
+msgid "E730: using List as a String"
+msgstr "E730: uso di Lista come Stringa"
+
+msgid "E731: using Dictionary as a String"
+msgstr "E731: uso di Dizionario come Stringa"
+
+#, c-format
+msgid "E706: Variable type mismatch for: %s"
+msgstr "E706: Tipo di variabile non corrispondente per: %s"
+
+#, c-format
+msgid "E795: Cannot delete variable %s"
+msgstr "E795: Non posso cancellare la variabile %s"
+
+#, c-format
+msgid "E704: Funcref variable name must start with a capital: %s"
+msgstr ""
+"E704: Il nome della variabile Funcref deve iniziare con una maiuscola: %s"
+
+#, c-format
+msgid "E705: Variable name conflicts with existing function: %s"
+msgstr "E705: Nome di variabile in conflitto con una funzione esistente: %s"
+
+#, c-format
+msgid "E741: Value is locked: %s"
+msgstr "E741: Valore di %s non modificabile"
+
+msgid "Unknown"
+msgstr "Sconosciuto"
+
+#, c-format
+msgid "E742: Cannot change value of %s"
+msgstr "E742: Non riesco a cambiare il valore di %s"
+
+msgid "E698: variable nested too deep for making a copy"
+msgstr "E698: Variabile troppo nidificata per poterla copiare"
+
+#, c-format
+msgid "E123: Undefined function: %s"
+msgstr "E123: Funzione non definita: %s"
+
+#, c-format
+msgid "E124: Missing '(': %s"
+msgstr "E124: Manca '(': %s"
+
+msgid "E862: Cannot use g: here"
+msgstr "E862: Non si può usare g: qui"
+
+#, c-format
+msgid "E125: Illegal argument: %s"
+msgstr "E125: Argomento non ammesso: %s"
+
+#, c-format
+msgid "E853: Duplicate argument name: %s"
+msgstr "E853: Nome argomento duplicato: %s"
+
+msgid "E126: Missing :endfunction"
+msgstr "E126: Manca :endfunction"
+
+#, c-format
+msgid "E707: Function name conflicts with variable: %s"
+msgstr "E707: Nome funzione in conflitto con la variabile: %s"
+
+#, c-format
+msgid "E127: Cannot redefine function %s: It is in use"
+msgstr "E127: Non posso ridefinire la funzione %s: È in uso"
+
+#, c-format
+msgid "E746: Function name does not match script file name: %s"
+msgstr "E746: Il nome funzione non corrisponde al nome file dello script: %s"
+
+msgid "E129: Function name required"
+msgstr "E129: Nome funzione necessario"
+
+#, c-format
+msgid "E128: Function name must start with a capital or contain a colon: %s"
+msgstr ""
+"E128: Il nome funzione deve iniziare con una maiuscola o contenere ':': %s"
+
+#, c-format
+msgid "E131: Cannot delete function %s: It is in use"
+msgstr "E131: Non posso eliminare la funzione %s: È in uso"
+
+msgid "E132: Function call depth is higher than 'maxfuncdepth'"
+msgstr ""
+"E132: Nidificazione della chiamata di funzione maggiore di 'maxfuncdepth'"
+
+#, c-format
+msgid "calling %s"
+msgstr "chiamo %s"
+
+#, c-format
+msgid "%s aborted"
+msgstr "%s non completata"
+
+#, c-format
+msgid "%s returning #%ld"
+msgstr "%s ritorno #%ld"
+
+#, c-format
+msgid "%s returning %s"
+msgstr "%s ritorno %s"
+
+#, c-format
+msgid "continuing in %s"
+msgstr "continuo in %s"
+
+msgid "E133: :return not inside a function"
+msgstr "E133: :return fuori da una funzione"
+
+msgid ""
+"\n"
+"# global variables:\n"
+msgstr ""
+"\n"
+"# variabili globali:\n"
+
+msgid ""
+"\n"
+"\tLast set from "
+msgstr ""
+"\n"
+"\tImpostata l'ultima volta da "
+
+msgid "No old files"
+msgstr "Nessun file elaborato in precedenza"
+
+#, c-format
+msgid "<%s>%s%s %d, Hex %02x, Octal %03o"
+msgstr "<%s>%s%s %d, Esa %02x, Ottale %03o"
+
+#, c-format
+msgid "> %d, Hex %04x, Octal %o"
+msgstr "> %d, Esa %04x, Ottale %o"
+
+#, c-format
+msgid "> %d, Hex %08x, Octal %o"
+msgstr "> %d, Esa %08x, Ottale %o"
+
+msgid "E134: Move lines into themselves"
+msgstr "E134: Movimento di linee verso se stesse"
+
+msgid "1 line moved"
+msgstr "1 linea mossa"
+
+#, c-format
+msgid "%ld lines moved"
+msgstr "%ld linee mosse"
+
+#, c-format
+msgid "%ld lines filtered"
+msgstr "%ld linee filtrate"
+
+msgid "E135: *Filter* Autocommands must not change current buffer"
+msgstr "E135: *Filter* Gli autocomandi non devono modificare il buffer in uso"
+
+msgid "[No write since last change]\n"
+msgstr "[Non salvato dopo l'ultima modifica]\n"
+
+#, c-format
+msgid "%sviminfo: %s in line: "
+msgstr "%sviminfo: %s nella linea: "
+
+msgid "E136: viminfo: Too many errors, skipping rest of file"
+msgstr "E136: viminfo: Troppi errori, ignoro il resto del file"
+
+#, c-format
+msgid "Reading viminfo file \"%s\"%s%s%s"
+msgstr "Lettura file viminfo \"%s\"%s%s%s"
+
+msgid " info"
+msgstr " informazione"
+
+msgid " marks"
+msgstr " mark"
+
+msgid " oldfiles"
+msgstr " file elaborati in precedenza"
+
+msgid " FAILED"
+msgstr " FALLITO"
+
+#. avoid a wait_return for this message, it's annoying
+#, c-format
+msgid "E137: Viminfo file is not writable: %s"
+msgstr "E137: File viminfo \"%s\" inaccessibile in scrittura"
+
+#, c-format
+msgid "E138: Can't write viminfo file %s!"
+msgstr "E138: Non riesco a scrivere il file viminfo %s!"
+
+#, c-format
+msgid "Writing viminfo file \"%s\""
+msgstr "Scrivo file viminfo \"%s\""
+
+#. Write the info:
+#, c-format
+msgid "# This viminfo file was generated by Vim %s.\n"
+msgstr "# Questo file viminfo è stato generato da Vim %s.\n"
+
+msgid ""
+"# You may edit it if you're careful!\n"
+"\n"
+msgstr ""
+"# File modificabile, attento a quel che fai!\n"
+"\n"
+
+msgid "# Value of 'encoding' when this file was written\n"
+msgstr "# Valore di 'encoding' al momento della scrittura di questo file\n"
+
+msgid "Illegal starting char"
+msgstr "Carattere iniziale non ammesso"
+
+msgid "Save As"
+msgstr "Salva con Nome"
+
+msgid "Write partial file?"
+msgstr "Scrivo il file incompleto?"
+
+msgid "E140: Use ! to write partial buffer"
+msgstr "E140: Usa ! per scrivere il buffer incompleto"
+
+#, c-format
+msgid "Overwrite existing file \"%s\"?"
+msgstr "Riscrittura del file esistente \"%s\"?"
+
+#, c-format
+msgid "Swap file \"%s\" exists, overwrite anyway?"
+msgstr "Il file swap \"%s\" esiste già, sovrascrivo?"
+
+#, c-format
+msgid "E768: Swap file exists: %s (:silent! overrides)"
+msgstr "E768: File swap esistente: %s (:silent! per sovrascriverlo)"
+
+#, c-format
+msgid "E141: No file name for buffer %ld"
+msgstr "E141: Manca nome file per il buffer %ld"
+
+msgid "E142: File not written: Writing is disabled by 'write' option"
+msgstr "E142: File non scritto: Scrittura inibita da opzione 'write'"
+
+#, c-format
+msgid ""
+"'readonly' option is set for \"%s\".\n"
+"Do you wish to write anyway?"
+msgstr ""
+"opzione 'readonly' attiva per \"%s\".\n"
+"Vuoi scrivere comunque?"
+
+#, 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 ""
+"I permessi di \"%s\" sono di sola lettura.\n"
+"Questo potrebbe non impedire la scrittura.\n"
+"Vuoi provare?"
+
+#, c-format
+msgid "E505: \"%s\" is read-only (add ! to override)"
+msgstr "E505: \"%s\" è in sola lettura (aggiungi ! per eseguire comunque)"
+
+msgid "Edit File"
+msgstr "Elabora File"
+
+#, c-format
+msgid "E143: Autocommands unexpectedly deleted new buffer %s"
+msgstr ""
+"E143: Gli autocomandi hanno inaspettatamente cancellato il nuovo buffer %s"
+
+msgid "E144: non-numeric argument to :z"
+msgstr "E144: argomento non-numerico a :z"
+
+msgid "E145: Shell commands not allowed in rvim"
+msgstr "E145: Comandi Shell non permessi in rvim"
+
+msgid "E146: Regular expressions can't be delimited by letters"
+msgstr "E146: Le espressioni regolari non possono essere delimitate da lettere"
+
+#, c-format
+msgid "replace with %s (y/n/a/q/l/^E/^Y)?"
+msgstr "sostituire con %s (y/n/a/q/l/^E/^Y)?"
+
+msgid "(Interrupted) "
+msgstr "(Interrotto) "
+
+msgid "1 match"
+msgstr "1 corrisp."
+
+msgid "1 substitution"
+msgstr "1 sostituzione"
+
+#, c-format
+msgid "%ld matches"
+msgstr "%ld corrisp."
+
+#, c-format
+msgid "%ld substitutions"
+msgstr "%ld sostituzioni"
+
+msgid " on 1 line"
+msgstr " in 1 linea"
+
+#, c-format
+msgid " on %ld lines"
+msgstr " in %ld linee"
+
+msgid "E147: Cannot do :global recursive"
+msgstr "E147: :global non può essere usato ricorsivamente"
+
+msgid "E148: Regular expression missing from global"
+msgstr "E148: Manca espressione regolare nel comando 'global'"
+
+#, c-format
+msgid "Pattern found in every line: %s"
+msgstr "Espressione trovata su ogni linea: %s"
+
+#, c-format
+msgid "Pattern not found: %s"
+msgstr "Espressione non trovata: %s"
+
+msgid ""
+"\n"
+"# Last Substitute String:\n"
+"$"
+msgstr ""
+"\n"
+"# Ultima Stringa Sostituzione:\n"
+"$"
+
+msgid "E478: Don't panic!"
+msgstr "E478: Non lasciarti prendere dal panico!"
+
+#, c-format
+msgid "E661: Sorry, no '%s' help for %s"
+msgstr "E661: Spiacente, nessun aiuto '%s' per %s"
+
+#, c-format
+msgid "E149: Sorry, no help for %s"
+msgstr "E149: Spiacente, nessun aiuto per %s"
+
+#, c-format
+msgid "Sorry, help file \"%s\" not found"
+msgstr "Spiacente, non trovo file di aiuto \"%s\""
+
+#, c-format
+msgid "E150: Not a directory: %s"
+msgstr "E150: %s non è una directory"
+
+#, c-format
+msgid "E152: Cannot open %s for writing"
+msgstr "E152: Non posso aprire %s in scrittura"
+
+#, c-format
+msgid "E153: Unable to open %s for reading"
+msgstr "E153: Non riesco ad aprire %s in lettura"
+
+#, c-format
+msgid "E670: Mix of help file encodings within a language: %s"
+msgstr "E670: Codifiche diverse fra file di aiuto nella stessa lingua: %s"
+
+#, c-format
+msgid "E154: Duplicate tag \"%s\" in file %s/%s"
+msgstr "E154: Tag duplicato \"%s\" nel file %s/%s"
+
+#, c-format
+msgid "E160: Unknown sign command: %s"
+msgstr "E160: Comando 'sign' sconosciuto: %s"
+
+msgid "E156: Missing sign name"
+msgstr "E156: Manca nome 'sign'"
+
+msgid "E612: Too many signs defined"
+msgstr "E612: Troppi 'sign' definiti"
+
+#, c-format
+msgid "E239: Invalid sign text: %s"
+msgstr "E239: Testo 'sign' non valido: %s"
+
+#, c-format
+msgid "E155: Unknown sign: %s"
+msgstr "E155: 'sign' sconosciuto: %s"
+
+msgid "E159: Missing sign number"
+msgstr "E159: Manca numero 'sign'"
+
+#, c-format
+msgid "E158: Invalid buffer name: %s"
+msgstr "E158: Nome buffer non valido: %s"
+
+#, c-format
+msgid "E157: Invalid sign ID: %ld"
+msgstr "E157: ID 'sign' non valido: %ld"
+
+msgid " (NOT FOUND)"
+msgstr " (NON TROVATO)"
+
+msgid " (not supported)"
+msgstr " (non supportata)"
+
+msgid "[Deleted]"
+msgstr "[Cancellato]"
+
+msgid "Entering Debug mode. Type \"cont\" to continue."
+msgstr "Entro modalità Debug. Batti \"cont\" per continuare."
+
+#, c-format
+msgid "line %ld: %s"
+msgstr "linea %ld: %s"
+
+#, c-format
+msgid "cmd: %s"
+msgstr "com: %s"
+
+#, c-format
+msgid "Breakpoint in \"%s%s\" line %ld"
+msgstr "Pausa in \"%s%s\" linea %ld"
+
+#, c-format
+msgid "E161: Breakpoint not found: %s"
+msgstr "E161: Breakpoint %s non trovato"
+
+msgid "No breakpoints defined"
+msgstr "Nessun 'breakpoint' definito"
+
+#, c-format
+msgid "%3d %s %s line %ld"
+msgstr "%3d %s %s linea %ld"
+
+msgid "E750: First use \":profile start {fname}\""
+msgstr "E750: Usare prima \":profile start {fname}\""
+
+#, c-format
+msgid "Save changes to \"%s\"?"
+msgstr "Salvare modifiche a \"%s\"?"
+
+msgid "Untitled"
+msgstr "Senza Nome"
+
+#, c-format
+msgid "E162: No write since last change for buffer \"%s\""
+msgstr "E162: Buffer \"%s\" non salvato dopo modifica"
+
+msgid "Warning: Entered other buffer unexpectedly (check autocommands)"
+msgstr ""
+"Attenzione: Entrato in altro buffer inaspettatamente (controllare "
+"autocomandi)"
+
+msgid "E163: There is only one file to edit"
+msgstr "E163: C'è un solo file da elaborare"
+
+msgid "E164: Cannot go before first file"
+msgstr "E164: Non posso andare davanti al primo file"
+
+msgid "E165: Cannot go beyond last file"
+msgstr "E165: Non posso oltrepassare l'ultimo file"
+
+#, c-format
+msgid "E666: compiler not supported: %s"
+msgstr "E666: compilatore non supportato: %s"
+
+#, c-format
+msgid "Searching for \"%s\" in \"%s\""
+msgstr "Cerco \"%s\" in \"%s\""
+
+#, c-format
+msgid "Searching for \"%s\""
+msgstr "Cerco \"%s\""
+
+#, c-format
+msgid "not found in 'runtimepath': \"%s\""
+msgstr "non trovato in 'runtimepath': \"%s\""
+
+msgid "Source Vim script"
+msgstr "Esegui script Vim"
+
+#, c-format
+msgid "Cannot source a directory: \"%s\""
+msgstr "Non riesco ad eseguire una directory: \"%s\""
+
+#, c-format
+msgid "could not source \"%s\""
+msgstr "non riesco ad eseguire \"%s\""
+
+#, c-format
+msgid "line %ld: could not source \"%s\""
+msgstr "linea %ld: non riesco ad eseguire \"%s\""
+
+#, c-format
+msgid "sourcing \"%s\""
+msgstr "eseguo \"%s\""
+
+#, c-format
+msgid "line %ld: sourcing \"%s\""
+msgstr "linea %ld: eseguo \"%s\""
+
+#, c-format
+msgid "finished sourcing %s"
+msgstr "esecuzione di %s terminata"
+
+msgid "modeline"
+msgstr "modeline"
+
+msgid "--cmd argument"
+msgstr "argomento --cmd"
+
+msgid "-c argument"
+msgstr "argomento -c"
+
+msgid "environment variable"
+msgstr "variabile d'ambiente"
+
+msgid "error handler"
+msgstr "gestore di errore"
+
+msgid "W15: Warning: Wrong line separator, ^M may be missing"
+msgstr "W15: Attenzione: Separatore di linea errato, forse manca ^M"
+
+msgid "E167: :scriptencoding used outside of a sourced file"
+msgstr "E167: :scriptencoding usato fuori da un file di comandi"
+
+msgid "E168: :finish used outside of a sourced file"
+msgstr "E168: :finish usato fuori da file di comandi"
+
+#, c-format
+msgid "Current %slanguage: \"%s\""
+msgstr "Lingua %sin uso: \"%s\""
+
+#, c-format
+msgid "E197: Cannot set language to \"%s\""
+msgstr "E197: Non posso impostare lingua a \"%s\""
+
+msgid "Entering Ex mode. Type \"visual\" to go to Normal mode."
+msgstr "Entro modalità Ex. Batti \"visual\" per tornare a modalità Normale."
+
+msgid "E501: At end-of-file"
+msgstr "E501: Alla fine-file"
+
+msgid "E169: Command too recursive"
+msgstr "E169: Comando troppo ricorsivo"
+
+#, c-format
+msgid "E605: Exception not caught: %s"
+msgstr "E605: Eccezione non intercettata: %s"
+
+msgid "End of sourced file"
+msgstr "Fine del file di comandi"
+
+msgid "End of function"
+msgstr "Fine funzione"
+
+msgid "E464: Ambiguous use of user-defined command"
+msgstr "E464: Uso ambiguo di comando definito dall'utente"
+
+msgid "E492: Not an editor command"
+msgstr "E492: Non è un comando dell'editor"
+
+msgid "E493: Backwards range given"
+msgstr "E493: Intervallo rovesciato"
+
+msgid "Backwards range given, OK to swap"
+msgstr "Intervallo rovesciato, OK invertirlo"
+
+msgid "E494: Use w or w>>"
+msgstr "E494: Usa w oppure w>>"
+
+msgid "E319: Sorry, the command is not available in this version"
+msgstr "E319: Spiacente, comando non disponibile in questa versione"
+
+msgid "E172: Only one file name allowed"
+msgstr "E172: Ammesso un solo nome file"
+
+msgid "1 more file to edit. Quit anyway?"
+msgstr "1 ulteriore file da elaborare. Esco lo stesso?"
+
+#, c-format
+msgid "%d more files to edit. Quit anyway?"
+msgstr "%d ulteriori file da elaborare. Esco lo stesso?"
+
+msgid "E173: 1 more file to edit"
+msgstr "E173: ancora 1 file da elaborare"
+
+#, c-format
+msgid "E173: %ld more files to edit"
+msgstr "E173: ancora %ld file da elaborare"
+
+msgid "E174: Command already exists: add ! to replace it"
+msgstr "E174: Il comando esiste già: aggiungi ! per sostituirlo"
+
+msgid ""
+"\n"
+" Name Args Range Complete Definition"
+msgstr ""
+"\n"
+" Nome Arg. Inter Completo Definizione"
+
+msgid "No user-defined commands found"
+msgstr "Non trovo comandi definiti dall'utente"
+
+msgid "E175: No attribute specified"
+msgstr "E175: Nessun attributo specificato"
+
+msgid "E176: Invalid number of arguments"
+msgstr "E176: Numero di argomenti non valido"
+
+msgid "E177: Count cannot be specified twice"
+msgstr "E177: Non si può specificare due volte il contatore"
+
+msgid "E178: Invalid default value for count"
+msgstr "E178: Valore predefinito del contatore non valido"
+
+msgid "E179: argument required for -complete"
+msgstr "E179: argomento necessario per -complete"
+
+#, c-format
+msgid "E181: Invalid attribute: %s"
+msgstr "E181: Attributo non valido: %s"
+
+msgid "E182: Invalid command name"
+msgstr "E182: Nome comando non valido"
+
+msgid "E183: User defined commands must start with an uppercase letter"
+msgstr ""
+"E183: I comandi definiti dall'utente devono iniziare con lettera maiuscola"
+
+msgid "E841: Reserved name, cannot be used for user defined command"
+msgstr "E841: Nome riservato, non usabile in un comando definito dall'utente"
+
+#, c-format
+msgid "E184: No such user-defined command: %s"
+msgstr "E184: Comando definito dall'utente %s inesistente"
+
+#, c-format
+msgid "E180: Invalid complete value: %s"
+msgstr "E180: Valore %s non valido per 'complete'"
+
+msgid "E468: Completion argument only allowed for custom completion"
+msgstr ""
+"E468: Argomento di completamento permesso solo per completamento "
+"personalizzato"
+
+msgid "E467: Custom completion requires a function argument"
+msgstr ""
+"E467: Il completamento personalizzato richiede un argomento di funzione"
+
+msgid "unknown"
+msgstr "sconosciuto"
+
+#, c-format
+msgid "E185: Cannot find color scheme '%s'"
+msgstr "E185: Non riesco a trovare schema colore '%s'"
+
+msgid "Greetings, Vim user!"
+msgstr "Salve, utente Vim!"
+
+msgid "E784: Cannot close last tab page"
+msgstr "E784: Non posso chiudere l'ultima linguetta"
+
+msgid "Already only one tab page"
+msgstr "C'è già una linguetta sola"
+
+msgid "Edit File in new window"
+msgstr "Apri il File in una nuova finestra"
+
+#, c-format
+msgid "Tab page %d"
+msgstr "Linguetta %d"
+
+msgid "No swap file"
+msgstr "Non posso creare un file di swap"
+
+msgid "Append File"
+msgstr "In aggiunta al File"
+
+msgid "E747: Cannot change directory, buffer is modified (add ! to override)"
+msgstr ""
+"E747: Non posso cambiare directory, buffer modificato (aggiungi ! per "
+"eseguire comunque)"
+
+msgid "E186: No previous directory"
+msgstr "E186: Non c'è una directory precedente"
+
+msgid "E187: Unknown"
+msgstr "E187: Sconosciuto"
+
+msgid "E465: :winsize requires two number arguments"
+msgstr "E465: :winsize richiede due argomenti numerici"
+
+#, c-format
+msgid "Window position: X %d, Y %d"
+msgstr "Posizione finestra: X %d, Y %d"
+
+msgid "E188: Obtaining window position not implemented for this platform"
+msgstr ""
+"E188: Informazioni posizione finestra non disponibili su questa piattaforma"
+
+msgid "E466: :winpos requires two number arguments"
+msgstr "E466: :winpos richiede due argomenti numerici"
+
+msgid "Save Redirection"
+msgstr "Salva Redirezione"
+
+msgid "Save View"
+msgstr "Salva Veduta"
+
+msgid "Save Session"
+msgstr "Salva Sessione"
+
+msgid "Save Setup"
+msgstr "Salva Setup"
+
+#, c-format
+msgid "E739: Cannot create directory: %s"
+msgstr "E739: Non posso creare la directory: %s"
+
+#, c-format
+msgid "E189: \"%s\" exists (add ! to override)"
+msgstr "E189: \"%s\" esiste (aggiungi ! per eseguire comunque)"
+
+#, c-format
+msgid "E190: Cannot open \"%s\" for writing"
+msgstr "E190: Non riesco ad aprire \"%s\" in scrittura"
+
+#. set mark
+msgid "E191: Argument must be a letter or forward/backward quote"
+msgstr ""
+"E191: L'argomento deve essere una lettera, oppure un apice/apice retroverso"
+
+msgid "E192: Recursive use of :normal too deep"
+msgstr "E192: Uso ricorsivo di :normal troppo esteso"
+
+msgid "E809: #< is not available without the +eval feature"
+msgstr "E809: #< non disponibile se Vim è compilato senza +eval"
+
+msgid "E194: No alternate file name to substitute for '#'"
+msgstr "E194: Nessun nome file alternativo da sostituire a '#'"
+
+msgid "E495: no autocommand file name to substitute for \"<afile>\""
+msgstr "E495: nessun file di autocomandi da sostituire per \"<afile>\""
+
+msgid "E496: no autocommand buffer number to substitute for \"<abuf>\""
+msgstr ""
+"E496: nessun numero di buffer di autocomandi da sostituire per \"<abuf>\""
+
+msgid "E497: no autocommand match name to substitute for \"<amatch>\""
+msgstr ""
+"E497: nessun nome di autocomandi trovato da sostituire per \"<amatch>\""
+
+msgid "E498: no :source file name to substitute for \"<sfile>\""
+msgstr ""
+"E498: nessun nome di file :source trovato da sostituire per \"<sfile>\""
+
+msgid "E842: no line number to use for \"<slnum>\""
+msgstr "E842: nessun numero di riga da usare per \"<slnum>\""
+
+#, no-c-format
+msgid "E499: Empty file name for '%' or '#', only works with \":p:h\""
+msgstr "E499: Un nome di file nullo per '%' o '#', va bene solo con \":p:h\""
+
+msgid "E500: Evaluates to an empty string"
+msgstr "E500: Il valore è una stringa nulla"
+
+msgid "E195: Cannot open viminfo file for reading"
+msgstr "E195: Non posso aprire il file viminfo in lettura"
+
+msgid "E196: No digraphs in this version"
+msgstr "E196: Digrammi non supportati in questa versione"
+
+msgid "E608: Cannot :throw exceptions with 'Vim' prefix"
+msgstr "E608: Impossibile lanciare eccezioni con prefisso 'Vim'"
+
+#. always scroll up, don't overwrite
+#, c-format
+msgid "Exception thrown: %s"
+msgstr "Eccezione lanciata: %s"
+
+#, c-format
+msgid "Exception finished: %s"
+msgstr "Eccezione finita: %s"
+
+#, c-format
+msgid "Exception discarded: %s"
+msgstr "Eccezione scartata: %s"
+
+#, c-format
+msgid "%s, line %ld"
+msgstr "%s, linea %ld"
+
+#. always scroll up, don't overwrite
+#, c-format
+msgid "Exception caught: %s"
+msgstr "Eccezione intercettata: %s"
+
+#, c-format
+msgid "%s made pending"
+msgstr "%s reso 'pending'"
+
+#, c-format
+msgid "%s resumed"
+msgstr "%s ripristinato"
+
+#, c-format
+msgid "%s discarded"
+msgstr "%s scartato"
+
+msgid "Exception"
+msgstr "Eccezione"
+
+msgid "Error and interrupt"
+msgstr "Errore ed interruzione"
+
+msgid "Error"
+msgstr "Errore"
+
+#. if (pending & CSTP_INTERRUPT)
+msgid "Interrupt"
+msgstr "Interruzione"
+
+msgid "E579: :if nesting too deep"
+msgstr "E579: nidificazione di :if troppo estesa"
+
+msgid "E580: :endif without :if"
+msgstr "E580: :endif senza :if"
+
+msgid "E581: :else without :if"
+msgstr "E581: :else senza :if"
+
+msgid "E582: :elseif without :if"
+msgstr "E582: :elseif senza :if"
+
+msgid "E583: multiple :else"
+msgstr "E583: :else multipli"
+
+msgid "E584: :elseif after :else"
+msgstr "E584: :elseif dopo :else"
+
+msgid "E585: :while/:for nesting too deep"
+msgstr "E585: nidificazione di :while/:for troppo estesa"
+
+msgid "E586: :continue without :while or :for"
+msgstr "E586: :continue senza :while o :for"
+
+msgid "E587: :break without :while or :for"
+msgstr "E587: :break senza :while o :for"
+
+msgid "E732: Using :endfor with :while"
+msgstr "E732: Uso di :endfor con :while"
+
+msgid "E733: Using :endwhile with :for"
+msgstr "E733: Uso di :endwhile con :for"
+
+msgid "E601: :try nesting too deep"
+msgstr "E601: nidificazione di :try troppo estesa"
+
+msgid "E603: :catch without :try"
+msgstr "E603: :catch senza :try"
+
+#. Give up for a ":catch" after ":finally" and ignore it.
+#. * Just parse.
+msgid "E604: :catch after :finally"
+msgstr "E604: :catch dopo :finally"
+
+msgid "E606: :finally without :try"
+msgstr "E606: :finally senza :try"
+
+#. Give up for a multiple ":finally" and ignore it.
+msgid "E607: multiple :finally"
+msgstr "E607: :finally multipli"
+
+msgid "E602: :endtry without :try"
+msgstr "E602: :endtry senza :try"
+
+msgid "E193: :endfunction not inside a function"
+msgstr "E193: :endfunction non contenuto in una funzione"
+
+msgid "E788: Not allowed to edit another buffer now"
+msgstr "E788: Non si può aprire ora un altro buffer"
+
+msgid "E811: Not allowed to change buffer information now"
+msgstr "E811: Non consentito modificare informazioni del buffer ora"
+
+msgid "tagname"
+msgstr "nome_tag"
+
+msgid " kind file\n"
+msgstr " tipo file\n"
+
+msgid "'history' option is zero"
+msgstr "l'opzione 'history' è a zero"
+
+#, c-format
+msgid ""
+"\n"
+"# %s History (newest to oldest):\n"
+msgstr ""
+"\n"
+"# %s Storia (da più recente a meno recente):\n"
+
+msgid "Command Line"
+msgstr "Linea di Comando"
+
+msgid "Search String"
+msgstr "Stringa di Ricerca"
+
+msgid "Expression"
+msgstr "Espressione"
+
+msgid "Input Line"
+msgstr "Linea di Input"
+
+msgid "E198: cmd_pchar beyond the command length"
+msgstr "E198: cmd_pchar dopo la fine del comando"
+
+msgid "E199: Active window or buffer deleted"
+msgstr "E199: Finestra attiva o buffer cancellato"
+
+msgid "E812: Autocommands changed buffer or buffer name"
+msgstr "E812: Gli autocomandi hanno modificato il buffer o il nome del buffer"
+
+msgid "Illegal file name"
+msgstr "Nome di file non ammesso"
+
+msgid "is a directory"
+msgstr "è una directory"
+
+msgid "is not a file"
+msgstr "non è un file"
+
+msgid "is a device (disabled with 'opendevice' option)"
+msgstr "è una periferica (disabilitata con l'opzione 'opendevice')"
+
+msgid "[New File]"
+msgstr "[File nuovo]"
+
+msgid "[New DIRECTORY]"
+msgstr "[Nuova DIRECTORY]"
+
+msgid "[File too big]"
+msgstr "[File troppo grande]"
+
+msgid "[Permission Denied]"
+msgstr "[Tipo di accesso non consentito]"
+
+msgid "E200: *ReadPre autocommands made the file unreadable"
+msgstr "E200: Gli autocomandi *ReadPre hanno reso il file illeggibile"
+
+msgid "E201: *ReadPre autocommands must not change current buffer"
+msgstr "E201: Gli autocomandi *ReadPre non devono modificare il buffer in uso"
+
+msgid "Vim: Reading from stdin...\n"
+msgstr "Vim: Leggo da 'stdin'...\n"
+
+msgid "Reading from stdin..."
+msgstr "Leggo da 'stdin'..."
+
+#. Re-opening the original file failed!
+msgid "E202: Conversion made file unreadable!"
+msgstr "E202: La conversione ha reso il file illeggibile!"
+
+msgid "[fifo/socket]"
+msgstr "[fifo/socket]"
+
+msgid "[fifo]"
+msgstr "[fifo]"
+
+msgid "[socket]"
+msgstr "[socket]"
+
+msgid "[character special]"
+msgstr "[character special]"
+
+msgid "[CR missing]"
+msgstr "[manca CR]"
+
+msgid "[long lines split]"
+msgstr "[linee lunghe divise]"
+
+msgid "[NOT converted]"
+msgstr "[NON convertito]"
+
+msgid "[converted]"
+msgstr "[convertito]"
+
+msgid "[blowfish]"
+msgstr "[blowfish]"
+
+msgid "[crypted]"
+msgstr "[cifrato]"
+
+#, c-format
+msgid "[CONVERSION ERROR in line %ld]"
+msgstr "[ERRORE DI CONVERSIONE alla linea %ld]"
+
+#, c-format
+msgid "[ILLEGAL BYTE in line %ld]"
+msgstr "[BYTE NON VALIDO alla linea %ld]"
+
+msgid "[READ ERRORS]"
+msgstr "[ERRORI IN LETTURA]"
+
+msgid "Can't find temp file for conversion"
+msgstr "Non riesco a trovare il file temp per leggerlo"
+
+msgid "Conversion with 'charconvert' failed"
+msgstr "Conversione fallita con 'charconvert'"
+
+msgid "can't read output of 'charconvert'"
+msgstr "non riesco a leggere il risultato di 'charconvert'"
+
+msgid "E821: File is encrypted with unknown method"
+msgstr "E821: File cifrato con metodo sconosciuto"
+
+msgid "E676: No matching autocommands for acwrite buffer"
+msgstr "E676: Nessun autocomando corrispondente per buffer acwrite"
+
+msgid "E203: Autocommands deleted or unloaded buffer to be written"
+msgstr "E203: Buffer in scrittura cancellato o scaricato dagli autocomandi"
+
+msgid "E204: Autocommand changed number of lines in unexpected way"
+msgstr "E204: L'autocomando ha modificato numero linee in maniera imprevista"
+
+msgid "NetBeans disallows writes of unmodified buffers"
+msgstr "NetBeans non permette la scrittura di un buffer non modificato"
+
+msgid "Partial writes disallowed for NetBeans buffers"
+msgstr "Scrittura parziale disabilitata per i buffer di NetBeans"
+
+msgid "is not a file or writable device"
+msgstr "non è un file o un dispositivo su cui si possa scrivere"
+
+msgid "writing to device disabled with 'opendevice' option"
+msgstr "scrittura su periferica disabilitata con l'opzione 'opendevice'"
+
+msgid "is read-only (add ! to override)"
+msgstr "è in sola lettura (aggiungi ! per eseguire comunque)"
+
+msgid "E506: Can't write to backup file (add ! to override)"
+msgstr ""
+"E506: Non posso scrivere sul file di backup (aggiungi ! per eseguire "
+"comunque)"
+
+msgid "E507: Close error for backup file (add ! to override)"
+msgstr ""
+"E507: Errore in chiusura sul file di backup (aggiungi ! per eseguire "
+"comunque)"
+
+msgid "E508: Can't read file for backup (add ! to override)"
+msgstr ""
+"E508: Non riesco a leggere il file di backup (aggiungi ! per eseguire "
+"comunque)"
+
+msgid "E509: Cannot create backup file (add ! to override)"
+msgstr ""
+"E509: Non posso creare il file di backup (aggiungi ! per eseguire comunque)"
+
+msgid "E510: Can't make backup file (add ! to override)"
+msgstr ""
+"E510: Non posso fare il file di backup (aggiungi ! per eseguire comunque)"
+
+msgid "E460: The resource fork would be lost (add ! to override)"
+msgstr ""
+"E460: La 'fork' sulla risorsa verrebbe persa (aggiungi ! per eseguire "
+"comunque)"
+
+msgid "E214: Can't find temp file for writing"
+msgstr "E214: Non riesco a trovare un file 'temp' su cui scrivere"
+
+msgid "E213: Cannot convert (add ! to write without conversion)"
+msgstr ""
+"E213: Non riesco a convertire (aggiungi ! per scrivere senza conversione)"
+
+msgid "E166: Can't open linked file for writing"
+msgstr "E166: Non posso aprire il file collegato ('linked') in scrittura"
+
+msgid "E212: Can't open file for writing"
+msgstr "E212: Non posso aprire il file in scrittura"
+
+msgid "E667: Fsync failed"
+msgstr "E667: Fsync fallito"
+
+msgid "E512: Close failed"
+msgstr "E512: Chiusura fallita"
+
+msgid "E513: write error, conversion failed (make 'fenc' empty to override)"
+msgstr ""
+"E513: errore in scrittura, conversione fallita (rendere 'fenc' nullo per "
+"eseguire comunque)"
+
+#, c-format
+msgid ""
+"E513: write error, conversion failed in line %ld (make 'fenc' empty to "
+"override)"
+msgstr ""
+"E513: errore in scrittura, conversione fallita alla linea %ld (rendere "
+"'fenc' nullo per eseguire comunque)"
+
+msgid "E514: write error (file system full?)"
+msgstr "E514: errore in scrittura ('File System' pieno?)"
+
+msgid " CONVERSION ERROR"
+msgstr " ERRORE DI CONVERSIONE"
+
+#, c-format
+msgid " in line %ld;"
+msgstr " alla linea %ld;"
+
+msgid "[Device]"
+msgstr "[Dispositivo]"
+
+msgid "[New]"
+msgstr "[Nuovo]"
+
+msgid " [a]"
+msgstr " [a]"
+
+msgid " appended"
+msgstr " aggiunto in fondo"
+
+msgid " [w]"
+msgstr " [s]"
+
+msgid " written"
+msgstr " scritti"
+
+msgid "E205: Patchmode: can't save original file"
+msgstr "E205: Patchmode: non posso salvare il file originale"
+
+msgid "E206: patchmode: can't touch empty original file"
+msgstr "E206: patchmode: non posso alterare il file vuoto originale"
+
+msgid "E207: Can't delete backup file"
+msgstr "E207: Non riesco a cancellare il file di backup"
+
+msgid ""
+"\n"
+"WARNING: Original file may be lost or damaged\n"
+msgstr ""
+"\n"
+"ATTENZIONE: Il file originale può essere perso o danneggiato\n"
+
+msgid "don't quit the editor until the file is successfully written!"
+msgstr "non uscire dall'editor prima della fine della scrittura del file!"
+
+msgid "[dos]"
+msgstr "[DOS]"
+
+msgid "[dos format]"
+msgstr "[in formato DOS]"
+
+msgid "[mac]"
+msgstr "[MAC]"
+
+msgid "[mac format]"
+msgstr "[in formato MAC]"
+
+msgid "[unix]"
+msgstr "[UNIX]"
+
+msgid "[unix format]"
+msgstr "[in formato UNIX]"
+
+msgid "1 line, "
+msgstr "1 linea, "
+
+#, c-format
+msgid "%ld lines, "
+msgstr "%ld linee,"
+
+msgid "1 character"
+msgstr "1 carattere"
+
+#, c-format
+msgid "%lld characters"
+msgstr "%lld caratteri"
+
+#. Explicit typecast avoids warning on Mac OS X 10.6
+#, c-format
+msgid "%ld characters"
+msgstr "%ld caratteri"
+
+msgid "[noeol]"
+msgstr "[noeol]"
+
+msgid "[Incomplete last line]"
+msgstr "[Manca carattere di fine linea]"
+
+#. 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 "ATTENZIONE: File modificato dopo essere stato letto dall'Editor!!!"
+
+msgid "Do you really want to write to it"
+msgstr "Vuoi davvero riscriverlo"
+
+#, c-format
+msgid "E208: Error writing to \"%s\""
+msgstr "E208: Errore in scrittura di \"%s\""
+
+#, c-format
+msgid "E209: Error closing \"%s\""
+msgstr "E209: Errore in chiusura di \"%s\""
+
+#, c-format
+msgid "E210: Error reading \"%s\""
+msgstr "E210: Errore in lettura di \"%s\""
+
+msgid "E246: FileChangedShell autocommand deleted buffer"
+msgstr "E246: L'autocomando 'FileChangedShell' ha cancellato il buffer"
+
+#, c-format
+msgid "E211: File \"%s\" no longer available"
+msgstr "E211: Il file \"%s\" non esiste più"
+
+#, c-format
+msgid ""
+"W12: Warning: File \"%s\" has changed and the buffer was changed in Vim as "
+"well"
+msgstr ""
+"W12: Attenzione: File \"%s\" modificato su disco ed anche nel buffer di Vim"
+
+msgid "See \":help W12\" for more info."
+msgstr "Vedere \":help W12\" per ulteriori informazioni."
+
+#, c-format
+msgid "W11: Warning: File \"%s\" has changed since editing started"
+msgstr "W11: Attenzione: File \"%s\" modificato dopo l'apertura"
+
+msgid "See \":help W11\" for more info."
+msgstr "Vedere \":help W11\" per ulteriori informazioni."
+
+#, c-format
+msgid "W16: Warning: Mode of file \"%s\" has changed since editing started"
+msgstr "W16: Attenzione: Modo File \"%s\" modificato dopo l'apertura"
+
+msgid "See \":help W16\" for more info."
+msgstr "Vedere \":help W16\" per ulteriori informazioni."
+
+#, c-format
+msgid "W13: Warning: File \"%s\" has been created after editing started"
+msgstr "W13: Attenzione: Il file \"%s\" risulta creato dopo l'apertura"
+
+msgid "Warning"
+msgstr "Attenzione"
+
+msgid ""
+"&OK\n"
+"&Load File"
+msgstr ""
+"&OK\n"
+"&Carica File"
+
+#, c-format
+msgid "E462: Could not prepare for reloading \"%s\""
+msgstr "E462: Non riesco a preparare per ri-caricare \"%s\""
+
+#, c-format
+msgid "E321: Could not reload \"%s\""
+msgstr "E321: Non riesco a ri-caricare \"%s\""
+
+msgid "--Deleted--"
+msgstr "--Cancellato--"
+
+#, c-format
+msgid "auto-removing autocommand: %s <buffer=%d>"
+msgstr "auto-rimozione dell'autocomando: %s <buffer=%d>"
+
+#. the group doesn't exist
+#, c-format
+msgid "E367: No such group: \"%s\""
+msgstr "E367: Gruppo inesistente: \"%s\""
+
+#, c-format
+msgid "E215: Illegal character after *: %s"
+msgstr "E215: Carattere non ammesso dopo *: %s"
+
+#, c-format
+msgid "E216: No such event: %s"
+msgstr "E216: Evento inesistente: %s"
+
+#, c-format
+msgid "E216: No such group or event: %s"
+msgstr "E216: Evento o gruppo inesistente: %s"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Auto-Commands ---"
+msgstr ""
+"\n"
+"--- Auto-Comandi ---"
+
+#, c-format
+msgid "E680: <buffer=%d>: invalid buffer number "
+msgstr "E680: <buffer=%d>: numero buffer non valido"
+
+msgid "E217: Can't execute autocommands for ALL events"
+msgstr "E217: Non posso eseguire autocomandi for TUTTI gli eventi"
+
+msgid "No matching autocommands"
+msgstr "Nessun autocomando corrispondente"
+
+msgid "E218: autocommand nesting too deep"
+msgstr "E218: nidificazione dell'autocomando troppo estesa"
+
+#, c-format
+msgid "%s Auto commands for \"%s\""
+msgstr "%s Auto comandi per \"%s\""
+
+#, c-format
+msgid "Executing %s"
+msgstr "Eseguo %s"
+
+#, c-format
+msgid "autocommand %s"
+msgstr "autocomando %s"
+
+msgid "E219: Missing {."
+msgstr "E219: Manca {."
+
+msgid "E220: Missing }."
+msgstr "E220: Manca }."
+
+msgid "E490: No fold found"
+msgstr "E490: Non trovo alcuna piegatura"
+
+msgid "E350: Cannot create fold with current 'foldmethod'"
+msgstr "E350: Non posso create piegatura con il 'foldmethod' in uso"
+
+msgid "E351: Cannot delete fold with current 'foldmethod'"
+msgstr "E351: Non posso cancellare piegatura con il 'foldmethod' in uso"
+
+#, c-format
+msgid "+--%3ld lines folded "
+msgstr "+--%3ld linee piegate"
+
+msgid "E222: Add to read buffer"
+msgstr "E222: Aggiunto al buffer di lettura"
+
+msgid "E223: recursive mapping"
+msgstr "E223: mapping ricorsivo"
+
+#, c-format
+msgid "E224: global abbreviation already exists for %s"
+msgstr "E224: una abbreviazione globale già esiste per %s"
+
+#, c-format
+msgid "E225: global mapping already exists for %s"
+msgstr "E225: un mapping globale già esiste per %s"
+
+#, c-format
+msgid "E226: abbreviation already exists for %s"
+msgstr "E226: una abbreviazione già esiste per %s"
+
+#, c-format
+msgid "E227: mapping already exists for %s"
+msgstr "E227: un mapping già esiste per %s"
+
+msgid "No abbreviation found"
+msgstr "Non trovo l'abbreviazione"
+
+msgid "No mapping found"
+msgstr "Non trovo il mapping"
+
+msgid "E228: makemap: Illegal mode"
+msgstr "E228: makemap: modo non consentito"
+
+msgid "E851: Failed to create a new process for the GUI"
+msgstr "E851: Creazione di un nuovo processo fallita per la GUI"
+
+msgid "E852: The child process failed to start the GUI"
+msgstr "E852: Il processo figlio non è riuscito a far partire la GUI"
+
+msgid "E229: Cannot start the GUI"
+msgstr "E229: Non posso inizializzare la GUI"
+
+#, c-format
+msgid "E230: Cannot read from \"%s\""
+msgstr "E230: Non posso leggere da \"%s\""
+
+msgid "E665: Cannot start GUI, no valid font found"
+msgstr "E665: Non posso inizializzare la GUI, nessun font valido trovato"
+
+msgid "E231: 'guifontwide' invalid"
+msgstr "E231: 'guifontwide' non valido"
+
+msgid "E599: Value of 'imactivatekey' is invalid"
+msgstr "E599: Il valore di 'imactivatekey' non è valido"
+
+#, c-format
+msgid "E254: Cannot allocate color %s"
+msgstr "E254: Non riesco ad allocare il colore %s"
+
+msgid "No match at cursor, finding next"
+msgstr "Nessuna corrispondenza al cursore, cerco la prossima"
+
+msgid "<cannot open> "
+msgstr "<non posso aprire> "
+
+#, c-format
+msgid "E616: vim_SelFile: can't get font %s"
+msgstr "E616: vim_SelFile: non riesco a trovare il font %s"
+
+msgid "E614: vim_SelFile: can't return to current directory"
+msgstr "E614: vim_SelFile: non posso tornare alla directory in uso"
+
+msgid "Pathname:"
+msgstr "Nome percorso:"
+
+msgid "E615: vim_SelFile: can't get current directory"
+msgstr "E615: vim_SelFile: non riesco ad ottenere la directory in uso"
+
+msgid "OK"
+msgstr "OK"
+
+msgid "Cancel"
+msgstr "Non eseguire"
+
+msgid "Scrollbar Widget: Could not get geometry of thumb pixmap."
+msgstr "Scrollbar Widget: Non riesco a ottenere geometria del 'thumb pixmap'."
+
+msgid "Vim dialog"
+msgstr "Dialogo Vim"
+
+msgid "E232: Cannot create BalloonEval with both message and callback"
+msgstr "E232: Non riesco a creare 'BalloonEval' con sia messaggio che callback"
+
+msgid ""
+"&Yes\n"
+"&No\n"
+"&Cancel"
+msgstr ""
+"&Y Sì\n"
+"&No\n"
+"&C Ignora"
+
+msgid "Input _Methods"
+msgstr "_Metodi di inserimento"
+
+msgid "VIM - Search and Replace..."
+msgstr "VIM - Sostituisci..."
+
+msgid "VIM - Search..."
+msgstr "VIM - Cerca..."
+
+msgid "Find what:"
+msgstr "Trova cosa:"
+
+msgid "Replace with:"
+msgstr "Sostituisci con:"
+
+#. whole word only button
+msgid "Match whole word only"
+msgstr "Cerca solo la parola intera"
+
+#. match case button
+msgid "Match case"
+msgstr "Maiuscole/minuscole"
+
+msgid "Direction"
+msgstr "Direzione"
+
+#. 'Up' and 'Down' buttons
+msgid "Up"
+msgstr "Su"
+
+msgid "Down"
+msgstr "Giù"
+
+#. 'Find Next' button
+msgid "Find Next"
+msgstr "Trova il Prossimo"
+
+#. 'Replace' button
+msgid "Replace"
+msgstr "Sostituisci"
+
+#. 'Replace All' button
+msgid "Replace All"
+msgstr "Sostituisci Tutto"
+
+msgid "Vim: Received \"die\" request from session manager\n"
+msgstr "Vim: Ricevuta richiesta \"die\" dal session manager\n"
+
+msgid "Close"
+msgstr "Chiusura"
+
+msgid "New tab"
+msgstr "Nuova linguetta"
+
+msgid "Open Tab..."
+msgstr "Apri linguetta..."
+
+msgid "Vim: Main window unexpectedly destroyed\n"
+msgstr "Vim: Finestra principale distrutta inaspettatamente\n"
+
+msgid "&Filter"
+msgstr "&Filtro"
+
+msgid "&Cancel"
+msgstr "&C Non eseguire"
+
+msgid "Directories"
+msgstr "Directory"
+
+msgid "Filter"
+msgstr "Filtro"
+
+msgid "&Help"
+msgstr "&H Aiuto"
+
+msgid "Files"
+msgstr "File"
+
+msgid "&OK"
+msgstr "&OK"
+
+msgid "Selection"
+msgstr "Selezione"
+
+msgid "Find &Next"
+msgstr "&N Trova il Prossimo"
+
+msgid "&Replace"
+msgstr "&R Sostituisci"
+
+msgid "Replace &All"
+msgstr "&A Sostituisci Tutto"
+
+msgid "&Undo"
+msgstr "&U Disfa"
+
+#, c-format
+msgid "E671: Cannot find window title \"%s\""
+msgstr "E671: Non trovo il titolo della finestra \"%s\""
+
+#, c-format
+msgid "E243: Argument not supported: \"-%s\"; Use the OLE version."
+msgstr "E243: Argomento non supportato: \"-%s\"; Usa la versione OLE."
+
+msgid "E672: Unable to open window inside MDI application"
+msgstr "E672: Non posso aprire la finestra in un'applicazione MDI"
+
+msgid "Close tab"
+msgstr "Chiudi linguetta"
+
+msgid "Open tab..."
+msgstr "Apri linguetta..."
+
+msgid "Find string (use '\\\\' to find a '\\')"
+msgstr "Stringa di ricerca (usa '\\\\' per cercare un '\\')"
+
+msgid "Find & Replace (use '\\\\' to find a '\\')"
+msgstr "Sostituisci (usa '\\\\' per cercare un '\\')"
+
+#. 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 "Non Utilizzato"
+
+msgid "Directory\t*.nothing\n"
+msgstr "Directory\t*.nothing\n"
+
+msgid "Vim E458: Cannot allocate colormap entry, some colors may be incorrect"
+msgstr ""
+"Vim E458: Non riesco ad allocare elemento di colormap, possibili colori "
+"errati"
+
+#, c-format
+msgid "E250: Fonts for the following charsets are missing in fontset %s:"
+msgstr "E250: Mancano descrizioni per i seguenti caratteri nel font: %s"
+
+#, c-format
+msgid "E252: Fontset name: %s"
+msgstr "E252: Nome fontset: %s"
+
+#, c-format
+msgid "Font '%s' is not fixed-width"
+msgstr "Il font '%s' non di larghezza fissa"
+
+#, c-format
+msgid "E253: Fontset name: %s"
+msgstr "E253: Nome fontset: %s"
+
+#, c-format
+msgid "Font0: %s"
+msgstr "Font0: %s"
+
+#, c-format
+msgid "Font1: %s"
+msgstr "Font1: %s"
+
+#, c-format
+msgid "Font%ld width is not twice that of font0"
+msgstr "La larghezza di font%ld non è doppia di quella di font0"
+
+#, c-format
+msgid "Font0 width: %ld"
+msgstr "Larghezza di Font0: %ld"
+
+#, c-format
+msgid "Font1 width: %ld"
+msgstr "Larghezza di Font1: %ld"
+
+msgid "Invalid font specification"
+msgstr "Specifica di font non valida"
+
+msgid "&Dismiss"
+msgstr "&D Non ora"
+
+msgid "no specific match"
+msgstr "nessuna corrispondenza specifica"
+
+msgid "Vim - Font Selector"
+msgstr "Vim - Selettore Font"
+
+msgid "Name:"
+msgstr "Nome:"
+
+#. create toggle button
+msgid "Show size in Points"
+msgstr "Mostra dimensione in Punti"
+
+msgid "Encoding:"
+msgstr "Codifica:"
+
+msgid "Font:"
+msgstr "Font:"
+
+msgid "Style:"
+msgstr "Stile:"
+
+msgid "Size:"
+msgstr "Dimensione:"
+
+msgid "E256: Hangul automata ERROR"
+msgstr "E256: ERRORE processore Hangul"
+
+msgid "E550: Missing colon"
+msgstr "E550: Manca ':'"
+
+msgid "E551: Illegal component"
+msgstr "E551: Componente non valido"
+
+msgid "E552: digit expected"
+msgstr "E552: aspettavo un numero"
+
+#, c-format
+msgid "Page %d"
+msgstr "Pagina %d"
+
+msgid "No text to be printed"
+msgstr "Manca testo da stampare"
+
+msgid "Printing page %d (%d%%)"
+msgstr "Sto stampando pagina %d (%d%%)"
+
+#, c-format
+msgid " Copy %d of %d"
+msgstr " Copia %d di %d"
+
+#, c-format
+msgid "Printed: %s"
+msgstr "Stampato: %s"
+
+msgid "Printing aborted"
+msgstr "Stampa non completata"
+
+msgid "E455: Error writing to PostScript output file"
+msgstr "E455: Errore in scrittura a file PostScript di output"
+
+#, c-format
+msgid "E624: Can't open file \"%s\""
+msgstr "E624: Non riesco ad aprire il file \"%s\""
+
+#, c-format
+msgid "E457: Can't read PostScript resource file \"%s\""
+msgstr "E457: Non riesco a leggere file risorse PostScript \"%s\""
+
+#, c-format
+msgid "E618: file \"%s\" is not a PostScript resource file"
+msgstr "E618: file \"%s\" non è un file di risorse PostScript"
+
+#, c-format
+msgid "E619: file \"%s\" is not a supported PostScript resource file"
+msgstr "E619: file \"%s\" non è un file di risorse PostScript supportato"
+
+#, c-format
+msgid "E621: \"%s\" resource file has wrong version"
+msgstr "E621: il file di risorse \"%s\" ha una versione sbagliata"
+
+msgid "E673: Incompatible multi-byte encoding and character set."
+msgstr "E673: Codifica e set di caratteri multi-byte non compatibili."
+
+msgid "E674: printmbcharset cannot be empty with multi-byte encoding."
+msgstr "E674: printmbcharset non può essere nullo con codifica multi-byte."
+
+msgid "E675: No default font specified for multi-byte printing."
+msgstr "E675: Font predefinito non specificato per stampa multi-byte."
+
+msgid "E324: Can't open PostScript output file"
+msgstr "E324: Non riesco ad aprire file PostScript di output"
+
+#, c-format
+msgid "E456: Can't open file \"%s\""
+msgstr "E456: Non riesco ad aprire il file \"%s\""
+
+msgid "E456: Can't find PostScript resource file \"prolog.ps\""
+msgstr "E456: Non trovo file risorse PostScript \"prolog.ps\""
+
+msgid "E456: Can't find PostScript resource file \"cidfont.ps\""
+msgstr "E456: Non trovo file risorse PostScript \"cidfont.ps\""
+
+#, c-format
+msgid "E456: Can't find PostScript resource file \"%s.ps\""
+msgstr "E456: Non trovo file risorse PostScript \"%s.ps\""
+
+#, c-format
+msgid "E620: Unable to convert to print encoding \"%s\""
+msgstr "E620: Impossibile convertire a codifica di stampa \"%s\""
+
+msgid "Sending to printer..."
+msgstr "Invio a stampante..."
+
+msgid "E365: Failed to print PostScript file"
+msgstr "E365: Non riesco ad aprire file PostScript"
+
+msgid "Print job sent."
+msgstr "Richiesta di stampa inviata."
+
+msgid "Add a new database"
+msgstr "Aggiungi un nuovo database"
+
+msgid "Query for a pattern"
+msgstr "Cerca un modello"
+
+msgid "Show this message"
+msgstr "Visualizza questo messaggio"
+
+msgid "Kill a connection"
+msgstr "Termina una connessione"
+
+msgid "Reinit all connections"
+msgstr "Reinizializza tutte le connessioni"
+
+msgid "Show connections"
+msgstr "Visualizza connessioni"
+
+#, c-format
+msgid "E560: Usage: cs[cope] %s"
+msgstr "E560: Uso: cs[cope] %s"
+
+msgid "This cscope command does not support splitting the window.\n"
+msgstr "Questo comando cscope non gestisce la divisione delle schermo.\n"
+
+msgid "E562: Usage: cstag <ident>"
+msgstr "E562: Uso: cstag <ident>"
+
+msgid "E257: cstag: tag not found"
+msgstr "E257: cstag: tag non trovato"
+
+#, c-format
+msgid "E563: stat(%s) error: %d"
+msgstr "E563: errore stat(%s): %d"
+
+msgid "E563: stat error"
+msgstr "E563: errore stat"
+
+#, c-format
+msgid "E564: %s is not a directory or a valid cscope database"
+msgstr "E564: %s non è una directory o un database cscope valido"
+
+#, c-format
+msgid "Added cscope database %s"
+msgstr "Aggiunto database cscope %s"
+
+#, c-format
+msgid "E262: error reading cscope connection %ld"
+msgstr "E262: errore leggendo connessione cscope %ld"
+
+msgid "E561: unknown cscope search type"
+msgstr "E561: tipo di ricerca cscope sconosciuta"
+
+msgid "E566: Could not create cscope pipes"
+msgstr "E566: Non riesco a creare pipes cscope"
+
+msgid "E622: Could not fork for cscope"
+msgstr "E622: Non riesco a fare fork per cscope"
+
+msgid "cs_create_connection setpgid failed"
+msgstr "cs_create_connection setpgid fallita"
+
+msgid "cs_create_connection exec failed"
+msgstr "cs_create_connection exec fallita"
+
+msgid "cs_create_connection: fdopen for to_fp failed"
+msgstr "cs_create_connection: fdopen di to_fp fallita"
+
+msgid "cs_create_connection: fdopen for fr_fp failed"
+msgstr "cs_create_connection: fdopen di fr_fp fallita"
+
+msgid "E623: Could not spawn cscope process"
+msgstr "E623: Non riesco a generare processo cscope"
+
+msgid "E567: no cscope connections"
+msgstr "E567: nessuna connessione cscope"
+
+#, c-format
+msgid "E469: invalid cscopequickfix flag %c for %c"
+msgstr "E469: flag cscopequickfix %c non valido per %c"
+
+#, c-format
+msgid "E259: no matches found for cscope query %s of %s"
+msgstr "E259: nessuna corrispondenza trovata per la richiesta cscope %s di %s"
+
+msgid "cscope commands:\n"
+msgstr "comandi cscope:\n"
+
+#, c-format
+msgid "%-5s: %s%*s (Usage: %s)"
+msgstr "%-5s: %s%*s (Uso: %s)"
+
+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: Trova funzioni che chiamano questa\n"
+" d: Trova funzioni chiamate da questa\n"
+" e: Trova questa espressione egrep\n"
+" f: Trova questo file\n"
+" g: Trova questa definizione\n"
+" i: Trova file che #includono questo file\n"
+" s: Trova questo simbolo C\n"
+" t: Trova questa stringa\n"
+
+#, c-format
+msgid "E625: cannot open cscope database: %s"
+msgstr "E625: impossibile aprire database cscope: %s"
+
+msgid "E626: cannot get cscope database information"
+msgstr "E626: impossibile leggere informazioni sul database cscope"
+
+msgid "E568: duplicate cscope database not added"
+msgstr "E568: database cscope duplicato, non aggiunto"
+
+#, c-format
+msgid "E261: cscope connection %s not found"
+msgstr "E261: connessione cscope %s non trovata"
+
+#, c-format
+msgid "cscope connection %s closed"
+msgstr "connessione cscope %s chiusa"
+
+#. should not reach here
+msgid "E570: fatal error in cs_manage_matches"
+msgstr "E570: errore irreparabile in cs_manage_matches"
+
+#, c-format
+msgid "Cscope tag: %s"
+msgstr "Tag cscope: %s"
+
+msgid ""
+"\n"
+" # line"
+msgstr ""
+"\n"
+" # linea"
+
+msgid "filename / context / line\n"
+msgstr "nomefile / contest / linea\n"
+
+#, c-format
+msgid "E609: Cscope error: %s"
+msgstr "E609: Errore cscope: %s"
+
+msgid "All cscope databases reset"
+msgstr "Tutti i database cscope annullati"
+
+msgid "no cscope connections\n"
+msgstr "nessuna connessione cscope\n"
+
+msgid " # pid database name prepend path\n"
+msgstr " # pid database nome prepend path\n"
+
+msgid "Lua library cannot be loaded."
+msgstr "Non riesco a caricare libreria Lua."
+
+msgid "cannot save undo information"
+msgstr "non riesco a salvare informazioni per 'undo'"
+
+msgid ""
+"E815: Sorry, this command is disabled, the MzScheme libraries could not be "
+"loaded."
+msgstr ""
+"E815: Spiacente, comando non disponibile, non riesco a caricare librerie "
+"programmi MzScheme."
+
+msgid "invalid expression"
+msgstr "espressione non valida"
+
+msgid "expressions disabled at compile time"
+msgstr "espressioni disabilitate in compilazione"
+
+msgid "hidden option"
+msgstr "opzione nascosta"
+
+msgid "unknown option"
+msgstr "opzione inesistente"
+
+msgid "window index is out of range"
+msgstr "indice della finestra non nell'intervallo"
+
+msgid "couldn't open buffer"
+msgstr "non sono riuscito ad aprire il buffer"
+
+msgid "cannot delete line"
+msgstr "non posso cancellare la linea"
+
+msgid "cannot replace line"
+msgstr "non posso sostituire la linea"
+
+msgid "cannot insert line"
+msgstr "non posso inserire la linea"
+
+msgid "string cannot contain newlines"
+msgstr "la stringa non può contenere caratteri 'A CAPO'"
+
+msgid "error converting Scheme values to Vim"
+msgstr "errore nel convertire i valori Scheme a Vim"
+
+msgid "Vim error: ~a"
+msgstr "Errore Vim: ~a"
+
+msgid "Vim error"
+msgstr "Errore Vim"
+
+msgid "buffer is invalid"
+msgstr "buffer non valido"
+
+msgid "window is invalid"
+msgstr "finestra non valida"
+
+msgid "linenr out of range"
+msgstr "numero linea non nell'intervallo"
+
+msgid "not allowed in the Vim sandbox"
+msgstr "non ammesso in ambiente protetto"
+
+msgid "E836: This Vim cannot execute :python after using :py3"
+msgstr "E836: Python: Impossibile usare :py e :py3 nella stessa sessione"
+
+msgid "E837: This Vim cannot execute :py3 after using :python"
+msgstr "E837: Impossibile usare ora :py3 dopo aver usato :python"
+
+msgid ""
+"E263: Sorry, this command is disabled, the Python library could not be "
+"loaded."
+msgstr ""
+"E263: Spiacente, comando non disponibile, non riesco a caricare libreria "
+"programmi Python."
+
+msgid "E659: Cannot invoke Python recursively"
+msgstr "E659: Python non può essere chiamato ricorsivamente"
+
+msgid "line number out of range"
+msgstr "numero linea non nell'intervallo"
+
+msgid "invalid mark name"
+msgstr "nome di mark non valido"
+
+msgid "E265: $_ must be an instance of String"
+msgstr "E265: $_ deve essere un'istanza di String"
+
+msgid ""
+"E266: Sorry, this command is disabled, the Ruby library could not be loaded."
+msgstr ""
+"E266: Spiacente, comando non disponibile, non riesco a caricare libreria "
+"programmi Ruby."
+
+msgid "E267: unexpected return"
+msgstr "E267: return imprevisto"
+
+msgid "E268: unexpected next"
+msgstr "E268: next imprevisto"
+
+msgid "E269: unexpected break"
+msgstr "E269: break imprevisto"
+
+msgid "E270: unexpected redo"
+msgstr "E270: redo imprevisto"
+
+msgid "E271: retry outside of rescue clause"
+msgstr "E271: retry fuori da clausola rescue"
+
+msgid "E272: unhandled exception"
+msgstr "E272: eccezione non gestita"
+
+#, c-format
+msgid "E273: unknown longjmp status %d"
+msgstr "E273: tipo sconosciuto di salto nel programma %d"
+
+msgid "Toggle implementation/definition"
+msgstr "Implementazione/definizione Sì/No"
+
+msgid "Show base class of"
+msgstr "Visualizza classe base di"
+
+msgid "Show overridden member function"
+msgstr "Visualizza funzione modulo sovrascritto"
+
+msgid "Retrieve from file"
+msgstr "Carica da file"
+
+msgid "Retrieve from project"
+msgstr "Carica da progetto"
+
+msgid "Retrieve from all projects"
+msgstr "Carica da tutti i progetti"
+
+msgid "Retrieve"
+msgstr "Carica successivo"
+
+msgid "Show source of"
+msgstr "Visualizza sorgente di"
+
+msgid "Find symbol"
+msgstr "Trova simbolo"
+
+msgid "Browse class"
+msgstr "Esplora classe"
+
+msgid "Show class in hierarchy"
+msgstr "Visualizza classe in gerarchia"
+
+msgid "Show class in restricted hierarchy"
+msgstr "Visualizza classe nella gerarchia ristretta"
+
+msgid "Xref refers to"
+msgstr "Xref si riferisce a"
+
+msgid "Xref referred by"
+msgstr "Xref referenziato da"
+
+msgid "Xref has a"
+msgstr "Xref ha un"
+
+msgid "Xref used by"
+msgstr "Xref usato da"
+
+msgid "Show docu of"
+msgstr "Visualizza docu di"
+
+msgid "Generate docu for"
+msgstr "Genera docu per"
+
+msgid ""
+"Cannot connect to SNiFF+. Check environment (sniffemacs must be found in "
+"$PATH).\n"
+msgstr ""
+"Non riesco a connettermi a SNiFF+. Controllare ambiente (sniffemacs deve "
+"essere presente in $PATH).\n"
+
+msgid "E274: Sniff: Error during read. Disconnected"
+msgstr "E274: Sniff: Errore in lettura. Disconnessione."
+
+msgid "SNiFF+ is currently "
+msgstr "SNiFF+ è al momento "
+
+msgid "not "
+msgstr "non "
+
+msgid "connected"
+msgstr "connesso"
+
+#, c-format
+msgid "E275: Unknown SNiFF+ request: %s"
+msgstr "E275: Richiesta SNiFF+ sconosciuta: %s"
+
+msgid "E276: Error connecting to SNiFF+"
+msgstr "E276: Errore di connessione a SNiFF+"
+
+msgid "E278: SNiFF+ not connected"
+msgstr "E278: SNiFF+ non connesso"
+
+msgid "E279: Not a SNiFF+ buffer"
+msgstr "E279: Non è un buffer SNiFF+"
+
+msgid "Sniff: Error during write. Disconnected"
+msgstr "Sniff: Errore in scrittura. Disconnesso"
+
+msgid "invalid buffer number"
+msgstr "numero buffer non valido"
+
+msgid "not implemented yet"
+msgstr "non ancora implementato"
+
+#. ???
+msgid "cannot set line(s)"
+msgstr "non posso impostare linea(e)"
+
+msgid "mark not set"
+msgstr "mark non impostato"
+
+#, c-format
+msgid "row %d column %d"
+msgstr "riga %d colonna %d"
+
+msgid "cannot insert/append line"
+msgstr "non riesco a inserire/aggiungere linea"
+
+msgid "unknown flag: "
+msgstr "opzione inesistente: "
+
+msgid "unknown vimOption"
+msgstr "'vimOption' inesistente"
+
+msgid "keyboard interrupt"
+msgstr "interruzione dalla tastiera"
+
+msgid "vim error"
+msgstr "errore vim"
+
+msgid "cannot create buffer/window command: object is being deleted"
+msgstr ""
+"non riesco a creare comando buffer/finestra: oggetto in via di cancellazione"
+
+msgid ""
+"cannot register callback command: buffer/window is already being deleted"
+msgstr ""
+"non posso registrare comando callback: buffer/finestra già in cancellazione"
+
+#. This should never happen. Famous last word?
+msgid ""
+"E280: TCL FATAL ERROR: reflist corrupt!? Please report this to vim-dev@vim."
+"org"
+msgstr ""
+"E280: ERRORE FATALE TCL: reflist corrotta!? Si prega notificare a vim-"
+"dev@vim.org"
+
+msgid "cannot register callback command: buffer/window reference not found"
+msgstr ""
+"non posso registrare comando callback: riferimento a buffer/finestra "
+"inesistente"
+
+msgid ""
+"E571: Sorry, this command is disabled: the Tcl library could not be loaded."
+msgstr ""
+"E571: Spiacente, comando non disponibile, non riesco a caricare libreria "
+"programmi Tcl."
+
+#, c-format
+msgid "E572: exit code %d"
+msgstr "E572: codice di uscita %d"
+
+msgid "cannot get line"
+msgstr "non riesco a ottenere la linea"
+
+msgid "Unable to register a command server name"
+msgstr "Non riesco a registrare un nome di server comando"
+
+msgid "E248: Failed to send command to the destination program"
+msgstr "E248: Fallito invio comando a programma destinatario"
+
+#, c-format
+msgid "E573: Invalid server id used: %s"
+msgstr "E573: Identificativo di server non valido: %s"
+
+msgid "E251: VIM instance registry property is badly formed. Deleted!"
+msgstr "E251: Proprietà registry relative a VIM non adeguate. Cancellate!"
+
+msgid "Unknown option argument"
+msgstr "Argomento di opzione sconosciuto"
+
+msgid "Too many edit arguments"
+msgstr "Troppi argomenti di edit"
+
+msgid "Argument missing after"
+msgstr "Argomento mancante dopo"
+
+msgid "Garbage after option argument"
+msgstr "Spazzatura dopo argomento di opzione"
+
+msgid "Too many \"+command\", \"-c command\" or \"--cmd command\" arguments"
+msgstr "Troppi argomenti \"+command\", \"-c command\" o \"--cmd command\""
+
+msgid "Invalid argument for"
+msgstr "Argomento non valido per"
+
+#, c-format
+msgid "%d files to edit\n"
+msgstr "%d file da elaborare\n"
+
+msgid "netbeans is not supported with this GUI\n"
+msgstr "netbeans non è supportato con questa GUI\n"
+
+msgid "This Vim was not compiled with the diff feature."
+msgstr "Vim non compilato con funzionalità 'diff'."
+
+msgid "'-nb' cannot be used: not enabled at compile time\n"
+msgstr "'-nb' non disponibile: non abilitato in compilazione\n"
+
+msgid "Attempt to open script file again: \""
+msgstr "Tento di riaprire lo script file: \""
+
+msgid "Cannot open for reading: \""
+msgstr "Non posso aprire in lettura: \""
+
+msgid "Cannot open for script output: \""
+msgstr "Non posso aprire come script output: \""
+
+msgid "Vim: Error: Failure to start gvim from NetBeans\n"
+msgstr "Vim: Errore: Avvio di gvim da NetBeans non riuscito\n"
+
+msgid "Vim: Warning: Output is not to a terminal\n"
+msgstr "Vim: Attenzione: Output non diretto a un terminale\n"
+
+msgid "Vim: Warning: Input is not from a terminal\n"
+msgstr "Vim: Attenzione: Input non proveniente da un terminale\n"
+
+#. just in case..
+msgid "pre-vimrc command line"
+msgstr "linea comandi prima di vimrc"
+
+#, c-format
+msgid "E282: Cannot read from \"%s\""
+msgstr "E282: Non posso leggere da \"%s\""
+
+msgid ""
+"\n"
+"More info with: \"vim -h\"\n"
+msgstr ""
+"\n"
+"Maggiori informazioni con: \"vim -h\"\n"
+
+msgid "[file ..] edit specified file(s)"
+msgstr "[file ..] apri file(s) specificati"
+
+msgid "- read text from stdin"
+msgstr "- leggi testo da 'stdin'"
+
+msgid "-t tag edit file where tag is defined"
+msgstr "-t tag apri file in cui è definito il tag"
+
+msgid "-q [errorfile] edit file with first error"
+msgstr "-q [errorfile] apri file col primo errore"
+
+msgid ""
+"\n"
+"\n"
+"usage:"
+msgstr ""
+"\n"
+"\n"
+" uso:"
+
+msgid " vim [arguments] "
+msgstr " vim [argomenti] "
+
+msgid ""
+"\n"
+" or:"
+msgstr ""
+"\n"
+" o:"
+
+msgid ""
+"\n"
+"Where case is ignored prepend / to make flag upper case"
+msgstr ""
+"\n"
+"Quando si ignorano maiusc./minusc. preporre / per rendere il flag maiusc."
+
+msgid ""
+"\n"
+"\n"
+"Arguments:\n"
+msgstr ""
+"\n"
+"\n"
+"Argomenti:\n"
+
+msgid "--\t\t\tOnly file names after this"
+msgstr "--\t\t\tSolo nomi file da qui in poi"
+
+msgid "--literal\t\tDon't expand wildcards"
+msgstr "--literal\t\tNon espandere wildcard"
+
+msgid "-register\t\tRegister this gvim for OLE"
+msgstr "-register\t\tRegistra questo gvim a OLE"
+
+msgid "-unregister\t\tUnregister gvim for OLE"
+msgstr "-unregister\t\tDeregistra gvim a OLE"
+
+msgid "-g\t\t\tRun using GUI (like \"gvim\")"
+msgstr "-g\t\t\tEsegui usando GUI (come \"gvim\")"
+
+msgid "-f or --nofork\tForeground: Don't fork when starting GUI"
+msgstr "-f opp. --nofork\tForeground: Non usare 'fork' inizializzando GUI"
+
+msgid "-v\t\t\tVi mode (like \"vi\")"
+msgstr "-v\t\t\tModalità Vi (come \"vi\")"
+
+msgid "-e\t\t\tEx mode (like \"ex\")"
+msgstr "-e\t\t\tModalità Ex (come \"ex\")"
+
+msgid "-E\t\t\tImproved Ex mode"
+msgstr "-E\t\t\tModalità Ex migliorata"
+
+msgid "-s\t\t\tSilent (batch) mode (only for \"ex\")"
+msgstr "-s\t\t\tModalità Silenziosa (batch) (solo per \"ex\")"
+
+msgid "-d\t\t\tDiff mode (like \"vimdiff\")"
+msgstr "-d\t\t\tModalità Diff (come \"vimdiff\")"
+
+msgid "-y\t\t\tEasy mode (like \"evim\", modeless)"
+msgstr "-y\t\t\tModalità Facile (come \"evim\", senza modalità)"
+
+msgid "-R\t\t\tReadonly mode (like \"view\")"
+msgstr "-R\t\t\tModalità Sola Lettura (come \"view\")"
+
+msgid "-Z\t\t\tRestricted mode (like \"rvim\")"
+msgstr "-Z\t\t\tModalità Ristretta (come \"rvim\")"
+
+msgid "-m\t\t\tModifications (writing files) not allowed"
+msgstr "-m\t\t\tRiscritture del file non permesse"
+
+msgid "-M\t\t\tModifications in text not allowed"
+msgstr "-M\t\t\tModifiche nel file non permesse"
+
+msgid "-b\t\t\tBinary mode"
+msgstr "-b\t\t\tModalità Binaria"
+
+msgid "-l\t\t\tLisp mode"
+msgstr "-l\t\t\tModalità Lisp"
+
+msgid "-C\t\t\tCompatible with Vi: 'compatible'"
+msgstr "-C\t\t\tCompatibile con Vi: 'compatible'"
+
+msgid "-N\t\t\tNot fully Vi compatible: 'nocompatible'"
+msgstr "-N\t\t\tNon interamente compatibile con Vi: 'nocompatible'"
+
+msgid "-V[N][fname]\t\tBe verbose [level N] [log messages to fname]"
+msgstr "-V[N][fname]\t\tVerbosità [livello N] [log su file fname]"
+
+msgid "-D\t\t\tDebugging mode"
+msgstr "-D\t\t\tModalità Debug"
+
+msgid "-n\t\t\tNo swap file, use memory only"
+msgstr "-n\t\t\tNiente file di swap, usa solo memoria"
+
+msgid "-r\t\t\tList swap files and exit"
+msgstr "-r\t\t\tLista swap file ed esci"
+
+msgid "-r (with file name)\tRecover crashed session"
+msgstr "-r (e nome file)\tRecupera da sessione finita male"
+
+msgid "-L\t\t\tSame as -r"
+msgstr "-L\t\t\tCome -r"
+
+msgid "-f\t\t\tDon't use newcli to open window"
+msgstr "-f\t\t\tNon usare newcli per aprire finestra"
+
+msgid "-dev <device>\t\tUse <device> for I/O"
+msgstr "-dev <dispositivo>\t\tUsa <dispositivo> per I/O"
+
+msgid "-A\t\t\tstart in Arabic mode"
+msgstr "-A\t\t\tComincia in modalità Araba"
+
+msgid "-H\t\t\tStart in Hebrew mode"
+msgstr "-H\t\t\tComincia in modalità Ebraica"
+
+msgid "-F\t\t\tStart in Farsi mode"
+msgstr "-F\t\t\tComincia in modalità Farsi (Persiano)"
+
+msgid "-T <terminal>\tSet terminal type to <terminal>"
+msgstr "-T <terminale>\tImposta tipo terminale a <terminale>"
+
+msgid "-u <vimrc>\t\tUse <vimrc> instead of any .vimrc"
+msgstr "-u <vimrc>\t\tUsa <vimrc> invece di .vimrc"
+
+msgid "-U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc"
+msgstr "-U <gvimrc>\t\tUsa <gvimrc> invece di .gvimrc"
+
+msgid "--noplugin\t\tDon't load plugin scripts"
+msgstr "--noplugin\t\tNon caricare script plugin"
+
+msgid "-p[N]\t\tOpen N tab pages (default: one for each file)"
+msgstr "-o[N]\t\tApri N linguette (predefinito: una per ogni file)"
+
+msgid "-o[N]\t\tOpen N windows (default: one for each file)"
+msgstr "-o[N]\t\tApri N finestre (predefinito: una per ogni file)"
+
+msgid "-O[N]\t\tLike -o but split vertically"
+msgstr "-O[N]\t\tCome -o ma dividi le finestre in verticale"
+
+msgid "+\t\t\tStart at end of file"
+msgstr "+\t\t\tPosizionati alla fine del file"
+
+msgid "+<lnum>\t\tStart at line <lnum>"
+msgstr "+<lnum>\t\tPosizionati alla linea <lnum>"
+
+msgid "--cmd <command>\tExecute <command> before loading any vimrc file"
+msgstr ""
+"--cmd <comando>\t\tEsegui <comando> prima di caricare eventuali file vimrc"
+
+msgid "-c <command>\t\tExecute <command> after loading the first file"
+msgstr "-c <comando>\t\tEsegui <comando> dopo caricamento primo file"
+
+msgid "-S <session>\t\tSource file <session> after loading the first file"
+msgstr ""
+"-S <sessione>\tEsegui comandi in file <sessione> dopo caricamento primo file"
+
+msgid "-s <scriptin>\tRead Normal mode commands from file <scriptin>"
+msgstr "-s <scriptin>\tLeggi comandi in modalità normale da file <scriptin>"
+
+msgid "-w <scriptout>\tAppend all typed commands to file <scriptout>"
+msgstr "-w <scriptout>\tAggiungi tutti i comandi immessi a file <scriptout>"
+
+msgid "-W <scriptout>\tWrite all typed commands to file <scriptout>"
+msgstr "-W <scriptout>\tScrivi tutti i comandi immessi in file <scriptout>"
+
+msgid "-x\t\t\tEdit encrypted files"
+msgstr "-x\t\t\tApri un file cifrato"
+
+msgid "-display <display>\tConnect vim to this particular X-server"
+msgstr "-display <schermo>\tEsegui vim a questo particolare server X"
+
+msgid "-X\t\t\tDo not connect to X server"
+msgstr "-X\t\t\tNon connetterti a server X"
+
+msgid "--remote <files>\tEdit <files> in a Vim server if possible"
+msgstr "--remote <file>\tApri <file> in un server Vim se possibile"
+
+msgid "--remote-silent <files> Same, don't complain if there is no server"
+msgstr "--remote-silent <file> Stessa cosa, ignora se non esiste un server"
+
+msgid ""
+"--remote-wait <files> As --remote but wait for files to have been edited"
+msgstr ""
+"--remote-wait <file> Come --remote ma aspetta che i file siano elaborati"
+
+msgid ""
+"--remote-wait-silent <files> Same, don't complain if there is no server"
+msgstr ""
+"--remote-wait-silent <file> Stessa cosa, ignora se non esiste un server"
+
+msgid ""
+"--remote-tab[-wait][-silent] <files> As --remote but use tab page per file"
+msgstr ""
+"--remote-tab[-wait][-silent] <file> Come --remote ma apre una linguetta per "
+"file"
+
+msgid "--remote-send <keys>\tSend <keys> to a Vim server and exit"
+msgstr "--remote-send <tasti>\tInvia <tasti> a un server Vim ed esci"
+
+msgid "--remote-expr <expr>\tEvaluate <expr> in a Vim server and print result"
+msgstr ""
+"--remote--expr <expr>\tEsegui <expr> in un server Vim e stampa risultato"
+
+msgid "--serverlist\t\tList available Vim server names and exit"
+msgstr "--serverlist\t\tLista nomi server Vim disponibili ed esci"
+
+msgid "--servername <name>\tSend to/become the Vim server <name>"
+msgstr "--servername <nome>\tInvia a/diventa server Vim di nome <nome>"
+
+msgid "--startuptime <file>\tWrite startup timing messages to <file>"
+msgstr ""
+"--startuptime <file>\tScrivi tutti i messaggi iniziali di timing in <file>"
+
+msgid "-i <viminfo>\t\tUse <viminfo> instead of .viminfo"
+msgstr "-i <viminfo>\t\tUsa <viminfo> invece di .viminfo"
+
+msgid "-h or --help\tPrint Help (this message) and exit"
+msgstr "-h opp. --help\tStampa Aiuto (questo messaggio) ed esci"
+
+msgid "--version\t\tPrint version information and exit"
+msgstr "--version\t\tStampa informazioni sulla versione ed esci"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (Motif version):\n"
+msgstr ""
+"\n"
+"Opzioni accettate da gvim (versione Motif):\n"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (neXtaw version):\n"
+msgstr ""
+"\n"
+"Opzioni accettate da gvim (versione neXtaw):\n"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (Athena version):\n"
+msgstr ""
+"\n"
+"Opzioni accettate da gvim (versione Athena):\n"
+
+msgid "-display <display>\tRun vim on <display>"
+msgstr "-display <schermo>\tEsegui vim su <schermo>"
+
+msgid "-iconic\t\tStart vim iconified"
+msgstr "-iconic\t\tInizia vim riducendolo ad icona"
+
+msgid "-background <color>\tUse <color> for the background (also: -bg)"
+msgstr "-background <colore>\tUsa <colore> come sfondo (anche: -bg)"
+
+msgid "-foreground <color>\tUse <color> for normal text (also: -fg)"
+msgstr "-foreground <colore>\tUsa <colore> per il testo normale (anche: -fg)"
+
+msgid "-font <font>\t\tUse <font> for normal text (also: -fn)"
+msgstr "-font <font>\t\tUsa <font> for il testo normale (anche: -fn)"
+
+msgid "-boldfont <font>\tUse <font> for bold text"
+msgstr "-boldfont <font>\tUsa <font> per testo in grassetto"
+
+msgid "-italicfont <font>\tUse <font> for italic text"
+msgstr "-italicfont <font>\tUsa <font> per testo in corsivo"
+
+msgid "-geometry <geom>\tUse <geom> for initial geometry (also: -geom)"
+msgstr "-geometry <geom>\tUsa <geom> per la geometria iniziale (anche: -geom)"
+
+msgid "-borderwidth <width>\tUse a border width of <width> (also: -bw)"
+msgstr "-borderwidth <larg>\tUsa larghezza <larg> per bordo (anche: -bw)"
+
+msgid "-scrollbarwidth <width> Use a scrollbar width of <width> (also: -sw)"
+msgstr ""
+"-scrollbarwidth <larg> Usa larghezza <larg> per scrollbar (anche: -sw)"
+
+msgid "-menuheight <height>\tUse a menu bar height of <height> (also: -mh)"
+msgstr "-menuheight <alt>\tUsa altezza <alt> per barra menu (anche: -mh)"
+
+msgid "-reverse\t\tUse reverse video (also: -rv)"
+msgstr "-reverse\t\tUsa colori invertiti (anche: -rv)"
+
+msgid "+reverse\t\tDon't use reverse video (also: +rv)"
+msgstr "+reverse\t\tNon usare colori invertiti (anche: +rv)"
+
+msgid "-xrm <resource>\tSet the specified resource"
+msgstr "-xrm <risorsa>\tImposta la risorsa specificata"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (GTK+ version):\n"
+msgstr ""
+"\n"
+"Argomenti accettati da gvim (versione GTK+):\n"
+
+msgid "-display <display>\tRun vim on <display> (also: --display)"
+msgstr "-display <schermo>\tEsegui vim su <schermo> (anche: --display)"
+
+msgid "--role <role>\tSet a unique role to identify the main window"
+msgstr ""
+"--role <ruolo>\tImposta un ruolo univoco per identificare la finestra "
+"principale"
+
+msgid "--socketid <xid>\tOpen Vim inside another GTK widget"
+msgstr "--socketid <xid>\tApri Vim dentro un altro widget GTK"
+
+msgid "--echo-wid\t\tMake gvim echo the Window ID on stdout"
+msgstr "--echo-wid\t\tStampa il Window ID su stdout"
+
+msgid "-P <parent title>\tOpen Vim inside parent application"
+msgstr "-P <titolo padre>\tApri Vim in un'applicazione padre"
+
+msgid "--windowid <HWND>\tOpen Vim inside another win32 widget"
+msgstr "--windowid <HWND>\tApri Vim dentro un altro widget win32"
+
+msgid "No display"
+msgstr "Manca display"
+
+#. Failed to send, abort.
+msgid ": Send failed.\n"
+msgstr ": Invio fallito.\n"
+
+#. Let vim start normally.
+msgid ": Send failed. Trying to execute locally\n"
+msgstr ": Invio fallito. Tento di eseguire localmente\n"
+
+#, c-format
+msgid "%d of %d edited"
+msgstr "%d di %d elaborato"
+
+msgid "No display: Send expression failed.\n"
+msgstr "Nessun display: Invio di espressione fallito.\n"
+
+msgid ": Send expression failed.\n"
+msgstr ": Invio di espressione fallito.\n"
+
+msgid "No marks set"
+msgstr "Nessun mark impostato"
+
+#, c-format
+msgid "E283: No marks matching \"%s\""
+msgstr "E283: Nessun mark corrispondente a \"%s\""
+
+#. Highlight title
+msgid ""
+"\n"
+"mark line col file/text"
+msgstr ""
+"\n"
+"mark linea col.file/testo"
+
+#. Highlight title
+msgid ""
+"\n"
+" jump line col file/text"
+msgstr ""
+"\n"
+" salt.linea col.file/testo"
+
+#. Highlight title
+msgid ""
+"\n"
+"change line col text"
+msgstr ""
+"\n"
+"modif linea col testo"
+
+msgid ""
+"\n"
+"# File marks:\n"
+msgstr ""
+"\n"
+"# File mark:\n"
+
+#. Write the jumplist with -'
+msgid ""
+"\n"
+"# Jumplist (newest first):\n"
+msgstr ""
+"\n"
+"# Jumplist (dai più recenti):\n"
+
+msgid ""
+"\n"
+"# History of marks within files (newest to oldest):\n"
+msgstr ""
+"\n"
+"# Storia dei mark all'interno dei file (dai più recenti ai meno recenti):\n"
+
+msgid "Missing '>'"
+msgstr "Manca '>'"
+
+msgid "E543: Not a valid codepage"
+msgstr "E543: Codepage non valido"
+
+msgid "E284: Cannot set IC values"
+msgstr "E284: Non posso assegnare valori IC"
+
+msgid "E285: Failed to create input context"
+msgstr "E285: Creazione di un contesto di input fallita"
+
+msgid "E286: Failed to open input method"
+msgstr "E286: Apertura 'input method' fallita"
+
+msgid "E287: Warning: Could not set destroy callback to IM"
+msgstr "E287: Attenzione: Non posso assegnare IM a 'destroy callback'"
+
+msgid "E288: input method doesn't support any style"
+msgstr "E288: 'input method' non sopporta alcuno stile"
+
+msgid "E289: input method doesn't support my preedit type"
+msgstr "E289: 'input method' non supporta il mio tipo di preedit"
+
+msgid "E293: block was not locked"
+msgstr "E293: il blocco non era riservato"
+
+msgid "E294: Seek error in swap file read"
+msgstr "E294: Errore di posizionamento durante lettura swap file"
+
+msgid "E295: Read error in swap file"
+msgstr "E295: Errore leggendo swap file"
+
+msgid "E296: Seek error in swap file write"
+msgstr "E296: Errore di posizionamento scrivendo swap file"
+
+msgid "E297: Write error in swap file"
+msgstr "E297: Errore scrivendo swap file"
+
+msgid "E300: Swap file already exists (symlink attack?)"
+msgstr "E300: Lo swap file esiste già (un link simbolico?)"
+
+msgid "E298: Didn't get block nr 0?"
+msgstr "E298: Non riesco a leggere blocco numero 0?"
+
+msgid "E298: Didn't get block nr 1?"
+msgstr "E298: Non riesco a leggere blocco numero 1?"
+
+msgid "E298: Didn't get block nr 2?"
+msgstr "E298: Non riesco a leggere blocco numero 2?"
+
+msgid "E843: Error while updating swap file crypt"
+msgstr "E843: Errore aggiornando cifratura dello swap file"
+
+#. could not (re)open the swap file, what can we do????
+msgid "E301: Oops, lost the swap file!!!"
+msgstr "E301: Ahimè, lo swap file è perduto!!!"
+
+msgid "E302: Could not rename swap file"
+msgstr "E302: Non riesco a rinominare lo swap file"
+
+#, c-format
+msgid "E303: Unable to open swap file for \"%s\", recovery impossible"
+msgstr ""
+"E303: Non riesco ad aprile lo swap file per \"%s\", recupero impossibile"
+
+msgid "E304: ml_upd_block0(): Didn't get block 0??"
+msgstr "E304: ml_upd_block0(): Non riesco a leggere blocco 0??"
+
+#, c-format
+msgid "E305: No swap file found for %s"
+msgstr "E305: Nessun swap file trovato per %s"
+
+msgid "Enter number of swap file to use (0 to quit): "
+msgstr "Dimmi numero di swap file da usare (0 per lasciar perdere): "
+
+#, c-format
+msgid "E306: Cannot open %s"
+msgstr "E306: Non riesco ad aprire %s"
+
+msgid "Unable to read block 0 from "
+msgstr "Non riesco a leggere il blocco 0 da "
+
+msgid ""
+"\n"
+"Maybe no changes were made or Vim did not update the swap file."
+msgstr ""
+"\n"
+"Forse non ci sono state modifiche oppure Vim non ha aggiornato lo swap file."
+
+msgid " cannot be used with this version of Vim.\n"
+msgstr " non può essere usato con questa versione di Vim.\n"
+
+msgid "Use Vim version 3.0.\n"
+msgstr "Usa Vim versione 3.0.\n"
+
+#, c-format
+msgid "E307: %s does not look like a Vim swap file"
+msgstr "E307: %s non sembra uno swap file Vim"
+
+msgid " cannot be used on this computer.\n"
+msgstr " non può essere usato su questo computer.\n"
+
+msgid "The file was created on "
+msgstr "Il file è stato creato il "
+
+msgid ""
+",\n"
+"or the file has been damaged."
+msgstr ""
+",\n"
+"o il file è stato danneggiato."
+
+#, c-format
+msgid ""
+"E833: %s is encrypted and this version of Vim does not support encryption"
+msgstr "E833: %s è cifrato e questa versione di Vim non supporta la cifratura"
+
+msgid " has been damaged (page size is smaller than minimum value).\n"
+msgstr ""
+" è stato danneggiato (la dimensione della pagina è inferiore al minimo).\n"
+
+#, c-format
+msgid "Using swap file \"%s\""
+msgstr "Uso swap file \"%s\""
+
+#, c-format
+msgid "Original file \"%s\""
+msgstr "File originale \"%s\""
+
+msgid "E308: Warning: Original file may have been changed"
+msgstr ""
+"E308: Attenzione: il file originale può essere stato modificato nel frattempo"
+
+#, c-format
+msgid "Swap file is encrypted: \"%s\""
+msgstr "Il file swap è cifrato: \"%s\""
+
+msgid ""
+"\n"
+"If you entered a new crypt key but did not write the text file,"
+msgstr ""
+"\n"
+"Se hai immesso una chiave di cifratura senza riscrivere il file di testo,"
+
+msgid ""
+"\n"
+"enter the new crypt key."
+msgstr ""
+"\n"
+"immetti la nuova chiave di cifratura."
+
+msgid ""
+"\n"
+"If you wrote the text file after changing the crypt key press enter"
+msgstr ""
+"\n"
+"Se hai riscritto il file dopo aver cambiato chiave di cifr., premi Invio"
+
+msgid ""
+"\n"
+"to use the same key for text file and swap file"
+msgstr ""
+"\n"
+"per usare la stessa chiave sia per il testo che per il file swap"
+
+#, c-format
+msgid "E309: Unable to read block 1 from %s"
+msgstr "E309: Impossibile leggere blocco 1 da %s"
+
+msgid "???MANY LINES MISSING"
+msgstr "???MOLTE LINEE MANCANTI"
+
+msgid "???LINE COUNT WRONG"
+msgstr "???CONTATORE LINEE ERRATO"
+
+msgid "???EMPTY BLOCK"
+msgstr "???BLOCCO VUOTO"
+
+msgid "???LINES MISSING"
+msgstr "???LINEE MANCANTI"
+
+#, c-format
+msgid "E310: Block 1 ID wrong (%s not a .swp file?)"
+msgstr "E310: ID del Blocco 1 errato (che %s non sia un .swp file?)"
+
+msgid "???BLOCK MISSING"
+msgstr "???BLOCCO MANCANTE"
+
+msgid "??? from here until ???END lines may be messed up"
+msgstr "??? da qui fino a ???END le linee possono essere fuori ordine"
+
+msgid "??? from here until ???END lines may have been inserted/deleted"
+msgstr ""
+"??? da qui fino a ???END linee possono essere state inserite/cancellate"
+
+msgid "???END"
+msgstr "???END"
+
+msgid "E311: Recovery Interrupted"
+msgstr "E311: Recupero Interrotto"
+
+msgid ""
+"E312: Errors detected while recovering; look for lines starting with ???"
+msgstr "E312: Errori durante recupero; controlla linee che iniziano con ???"
+
+msgid "See \":help E312\" for more information."
+msgstr "Vedere \":help E312\" per ulteriori informazioni."
+
+msgid "Recovery completed. You should check if everything is OK."
+msgstr "Recupero completato. Dovresti controllare se va tutto bene."
+
+msgid ""
+"\n"
+"(You might want to write out this file under another name\n"
+msgstr ""
+"\n"
+"(Potresti salvare questo file con un altro nome ed eseguire\n"
+
+msgid "and run diff with the original file to check for changes)"
+msgstr "'diff' rispetto al file originale per vedere le differenze)"
+
+msgid "Recovery completed. Buffer contents equals file contents."
+msgstr ""
+"Ripristino effettuato. Il contenuto del buffer coincide con quello del file."
+
+msgid ""
+"\n"
+"You may want to delete the .swp file now.\n"
+"\n"
+msgstr ""
+"\n"
+"È consigliato cancellare il file .swp adesso.\n"
+"\n"
+
+msgid "Using crypt key from swap file for the text file.\n"
+msgstr "Uso la chiave di cifratura del file swap per il file di testo.\n"
+
+#. use msg() to start the scrolling properly
+msgid "Swap files found:"
+msgstr "Swap file trovati:"
+
+msgid " In current directory:\n"
+msgstr " Nella directory in uso:\n"
+
+msgid " Using specified name:\n"
+msgstr " Uso il nome fornito:\n"
+
+msgid " In directory "
+msgstr " Nella directory "
+
+msgid " -- none --\n"
+msgstr " -- nessuno --\n"
+
+msgid " owned by: "
+msgstr " proprietario: "
+
+msgid " dated: "
+msgstr " datato: "
+
+msgid " dated: "
+msgstr " datato: "
+
+msgid " [from Vim version 3.0]"
+msgstr " [da Vim versione 3.0]"
+
+msgid " [does not look like a Vim swap file]"
+msgstr " [non assomiglia ad uno swap file Vim]"
+
+msgid " file name: "
+msgstr " nome file: "
+
+msgid ""
+"\n"
+" modified: "
+msgstr ""
+"\n"
+" modificato: "
+
+msgid "YES"
+msgstr "YES"
+
+msgid "no"
+msgstr "no"
+
+msgid ""
+"\n"
+" user name: "
+msgstr ""
+"\n"
+" nome utente: "
+
+msgid " host name: "
+msgstr " nome computer: "
+
+msgid ""
+"\n"
+" host name: "
+msgstr ""
+"\n"
+" nome computer: "
+
+msgid ""
+"\n"
+" process ID: "
+msgstr ""
+"\n"
+" ID del processo: "
+
+msgid " (still running)"
+msgstr " (ancora attivo)"
+
+msgid ""
+"\n"
+" [not usable with this version of Vim]"
+msgstr ""
+"\n"
+" [non utilizzabile con questa versione di Vim]"
+
+msgid ""
+"\n"
+" [not usable on this computer]"
+msgstr ""
+"\n"
+" [not utilizzabile su questo computer]"
+
+msgid " [cannot be read]"
+msgstr " [non leggibile]"
+
+msgid " [cannot be opened]"
+msgstr " [non riesco ad aprire]"
+
+msgid "E313: Cannot preserve, there is no swap file"
+msgstr "E313: Non posso preservare, manca swap file"
+
+msgid "File preserved"
+msgstr "File preservato"
+
+msgid "E314: Preserve failed"
+msgstr "E314: Preservazione fallita"
+
+#, c-format
+msgid "E315: ml_get: invalid lnum: %ld"
+msgstr "E315: ml_get: numero linea non valido: %ld"
+
+#, c-format
+msgid "E316: ml_get: cannot find line %ld"
+msgstr "E316: ml_get: non riesco a trovare la linea %ld"
+
+msgid "E317: pointer block id wrong 3"
+msgstr "E317: ID blocco puntatori errato 3"
+
+msgid "stack_idx should be 0"
+msgstr "stack_idx dovrebbe essere 0"
+
+msgid "E318: Updated too many blocks?"
+msgstr "E318: Aggiornati troppi blocchi?"
+
+msgid "E317: pointer block id wrong 4"
+msgstr "E317: ID blocco puntatori errato 4"
+
+msgid "deleted block 1?"
+msgstr "cancellato blocco 1?"
+
+#, c-format
+msgid "E320: Cannot find line %ld"
+msgstr "E320: Non riesco a trovare la linea %ld"
+
+msgid "E317: pointer block id wrong"
+msgstr "E317: ID blocco puntatori errato"
+
+msgid "pe_line_count is zero"
+msgstr "pe_line_count a zero"
+
+#, c-format
+msgid "E322: line number out of range: %ld past the end"
+msgstr "E322: numero linea non ammissibile: %ld dopo la fine"
+
+#, c-format
+msgid "E323: line count wrong in block %ld"
+msgstr "E323: contatore linee errato nel blocco %ld"
+
+msgid "Stack size increases"
+msgstr "Dimensione stack aumentata"
+
+msgid "E317: pointer block id wrong 2"
+msgstr "E317: ID blocco puntatori errato 2"
+
+#, c-format
+msgid "E773: Symlink loop for \"%s\""
+msgstr "E773: Collegamento simbolico ricorsivo per \"%s\""
+
+msgid "E325: ATTENTION"
+msgstr "E325: ATTENZIONE"
+
+msgid ""
+"\n"
+"Found a swap file by the name \""
+msgstr ""
+"\n"
+"Trovato uno swap file di nome \""
+
+msgid "While opening file \""
+msgstr "Mentre aprivo file \""
+
+msgid " NEWER than swap file!\n"
+msgstr " più RECENTE dello swap file!\n"
+
+#. 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."
+msgstr ""
+"\n"
+"(1) Un altro programma può essere in edit sullo stesso file.\n"
+" Se è così, attenzione a non trovarti con due versioni\n"
+" differenti dello stesso file a cui vengono apportate modifiche."
+
+msgid " Quit, or continue with caution.\n"
+msgstr " Esci, o continua con prudenza.\n"
+
+msgid "(2) An edit session for this file crashed.\n"
+msgstr "(2) Una sessione di edit per questo file è finita male.\n"
+
+msgid " If this is the case, use \":recover\" or \"vim -r "
+msgstr " Se è così, usa \":recover\" oppure \"vim -r "
+
+msgid ""
+"\"\n"
+" to recover the changes (see \":help recovery\").\n"
+msgstr ""
+"\"\n"
+" per recuperare modifiche fatte (vedi \":help recovery\").\n"
+
+msgid " If you did this already, delete the swap file \""
+msgstr " Se hai già fatto ciò, cancella il file di swap \""
+
+msgid ""
+"\"\n"
+" to avoid this message.\n"
+msgstr ""
+"\"\n"
+" per non ricevere ancora questo messaggio.\n"
+
+msgid "Swap file \""
+msgstr "Swap file \""
+
+msgid "\" already exists!"
+msgstr "\" già esistente!"
+
+msgid "VIM - ATTENTION"
+msgstr "VIM - ATTENZIONE"
+
+msgid "Swap file already exists!"
+msgstr "Lo swap file esiste già!"
+
+msgid ""
+"&Open Read-Only\n"
+"&Edit anyway\n"
+"&Recover\n"
+"&Quit\n"
+"&Abort"
+msgstr ""
+"&O Apri sola-lettura\n"
+"&E Apri comunque\n"
+"&Recupera\n"
+"&Q Esci\n"
+"&Annulla"
+
+msgid ""
+"&Open Read-Only\n"
+"&Edit anyway\n"
+"&Recover\n"
+"&Delete it\n"
+"&Quit\n"
+"&Abort"
+msgstr ""
+"&O Apri sola-lettura\n"
+"&E Apri comunque\n"
+"&Recupera\n"
+"&D Cancellalo\n"
+"&Q Esci\n"
+"&Annulla"
+
+msgid "E326: Too many swap files found"
+msgstr "E326: Trovati troppi swap file"
+
+msgid "E327: Part of menu-item path is not sub-menu"
+msgstr ""
+"E327: Parte del percorso di questo elemento di Menu non è un sotto-Menu"
+
+msgid "E328: Menu only exists in another mode"
+msgstr "E328: I Menu esistono solo in un'altra modalità"
+
+#, c-format
+msgid "E329: No menu \"%s\""
+msgstr "E329: Nessun Menu \"%s\""
+
+#. Only a mnemonic or accelerator is not valid.
+msgid "E792: Empty menu name"
+msgstr "E792: Nome menu non valido"
+
+msgid "E330: Menu path must not lead to a sub-menu"
+msgstr "E330: Il percorso del Menu non deve condurre a un sotto-Menu"
+
+msgid "E331: Must not add menu items directly to menu bar"
+msgstr ""
+"E331: Non devi aggiungere elementi di Menu direttamente alla barra Menu"
+
+msgid "E332: Separator cannot be part of a menu path"
+msgstr "E332: Il separatore non può far parte di un percorso di Menu"
+
+#. Now we have found the matching menu, and we list the mappings
+#. Highlight title
+msgid ""
+"\n"
+"--- Menus ---"
+msgstr ""
+"\n"
+"--- Menu ---"
+
+msgid "Tear off this menu"
+msgstr "Togli questo Menu"
+
+msgid "E333: Menu path must lead to a menu item"
+msgstr "E333: Il percorso Menu deve condurre ad un elemento Menu"
+
+#, c-format
+msgid "E334: Menu not found: %s"
+msgstr "E334: Menu non trovato: %s"
+
+#, c-format
+msgid "E335: Menu not defined for %s mode"
+msgstr "E335: Menu non definito per la modalità %s"
+
+msgid "E336: Menu path must lead to a sub-menu"
+msgstr "E336: Il percorso Menu deve condurre ad un sotto-Menu"
+
+msgid "E337: Menu not found - check menu names"
+msgstr "E337: Menu non trovato - controlla nomi Menu"
+
+#, c-format
+msgid "Error detected while processing %s:"
+msgstr "Errore/i eseguendo %s:"
+
+#, c-format
+msgid "line %4ld:"
+msgstr "linea %4ld:"
+
+#, c-format
+msgid "E354: Invalid register name: '%s'"
+msgstr "E354: Nome registro non valido: '%s'"
+
+msgid "Messages maintainer: Bram Moolenaar <Bram@vim.org>"
+msgstr "Manutentore messaggi: Vlad Sandrini <marco@sandrini.biz>"
+
+msgid "Interrupt: "
+msgstr "Interruzione: "
+
+msgid "Press ENTER or type command to continue"
+msgstr "Premi INVIO o un comando per proseguire"
+
+#, c-format
+msgid "%s line %ld"
+msgstr "%s linea %ld"
+
+msgid "-- More --"
+msgstr "-- Ancora --"
+
+msgid " SPACE/d/j: screen/page/line down, b/u/k: up, q: quit "
+msgstr " SPAZIO/d/j: schermo/pagina/linea giù, b/u/k: su, q: abbandona "
+
+msgid "Question"
+msgstr "Domanda"
+
+msgid ""
+"&Yes\n"
+"&No"
+msgstr ""
+"&Y Sì\n"
+"&No"
+
+msgid ""
+"&Yes\n"
+"&No\n"
+"Save &All\n"
+"&Discard All\n"
+"&Cancel"
+msgstr ""
+"&Y Sì\n"
+"&No\n"
+"&A Salva tutto\n"
+"&D Scarta Tutto\n"
+"&Cancella"
+
+msgid "Select Directory dialog"
+msgstr "Scelta Directory dialogo"
+
+msgid "Save File dialog"
+msgstr "Salva File dialogo"
+
+msgid "Open File dialog"
+msgstr "Apri File dialogo"
+
+#. TODO: non-GUI file selector here
+msgid "E338: Sorry, no file browser in console mode"
+msgstr "E338: Spiacente, niente esplorazione file in modalità console"
+
+msgid "E766: Insufficient arguments for printf()"
+msgstr "E766: Argomenti non sufficienti per printf()"
+
+msgid "E807: Expected Float argument for printf()"
+msgstr "E807: Numero con virgola atteso come argomento per printf()"
+
+msgid "E767: Too many arguments to printf()"
+msgstr "E767: Troppi argomenti per printf()"
+
+msgid "W10: Warning: Changing a readonly file"
+msgstr "W10: Attenzione: Modifica a un file in sola-lettura"
+
+msgid "Type number and <Enter> or click with mouse (empty cancels): "
+msgstr ""
+"Inserire un numero e <Invio> o fare clic (lasciare vuoto per annullare): "
+
+msgid "Type number and <Enter> (empty cancels): "
+msgstr "Inserire numero e <Invio> (vuoto per annullare): "
+
+msgid "1 more line"
+msgstr "1 linea in più"
+
+msgid "1 line less"
+msgstr "1 linea in meno"
+
+#, c-format
+msgid "%ld more lines"
+msgstr "%ld linee in più"
+
+#, c-format
+msgid "%ld fewer lines"
+msgstr "%ld linee in meno"
+
+msgid " (Interrupted)"
+msgstr " (Interrotto)"
+
+msgid "Beep!"
+msgstr "Beep!"
+
+msgid "Vim: preserving files...\n"
+msgstr "Vim: preservo file...\n"
+
+#. close all memfiles, without deleting
+msgid "Vim: Finished.\n"
+msgstr "Vim: Finito.\n"
+
+msgid "ERROR: "
+msgstr "ERRORE: "
+
+#, c-format
+msgid ""
+"\n"
+"[bytes] total alloc-freed %lu-%lu, in use %lu, peak use %lu\n"
+msgstr ""
+"\n"
+"[byte] totali alloc-rilasc %lu-%lu, in uso %lu, max uso %lu\n"
+
+#, c-format
+msgid ""
+"[calls] total re/malloc()'s %lu, total free()'s %lu\n"
+"\n"
+msgstr ""
+"[chiamate] totale re/malloc() %lu, totale free() %lu\n"
+"\n"
+
+msgid "E340: Line is becoming too long"
+msgstr "E340: La linea sta diventando troppo lunga"
+
+#, c-format
+msgid "E341: Internal error: lalloc(%ld, )"
+msgstr "E341: Errore interno: lalloc(%ld, )"
+
+#, c-format
+msgid "E342: Out of memory! (allocating %lu bytes)"
+msgstr "E342: Non c'è più memoria! (stavo allocando %lu byte)"
+
+#, c-format
+msgid "Calling shell to execute: \"%s\""
+msgstr "Chiamo lo shell per eseguire: \"%s\""
+
+msgid "E545: Missing colon"
+msgstr "E545: Manca ':'"
+
+msgid "E546: Illegal mode"
+msgstr "E546: Modalità non valida"
+
+msgid "E547: Illegal mouseshape"
+msgstr "E547: Forma del mouse non valida"
+
+msgid "E548: digit expected"
+msgstr "E548: aspettavo un numero"
+
+msgid "E549: Illegal percentage"
+msgstr "E549: Percentuale non valida"
+
+msgid "Enter encryption key: "
+msgstr "Immetti chiave di cifratura: "
+
+msgid "Enter same key again: "
+msgstr "Ribatti per conferma la stessa chiave: "
+
+msgid "Keys don't match!"
+msgstr "Le chiavi non corrispondono!"
+
+msgid "E854: path too long for completion"
+msgstr "E854: percorso troppo lungo per il completamento"
+
+#, c-format
+msgid ""
+"E343: Invalid path: '**[number]' must be at the end of the path or be "
+"followed by '%s'."
+msgstr ""
+"E343: Percorso non valido: '**[numero]' deve essere a fine percorso o essere "
+"seguito da '%s'."
+
+#, c-format
+msgid "E344: Can't find directory \"%s\" in cdpath"
+msgstr "E344: Non riesco a trovare la directory \"%s\" nel 'cdpath'"
+
+#, c-format
+msgid "E345: Can't find file \"%s\" in path"
+msgstr "E345: Non riesco a trovare il file \"%s\" nel percorso"
+
+#, c-format
+msgid "E346: No more directory \"%s\" found in cdpath"
+msgstr "E346: Nessun altra directory \"%s\" trovata nel 'cdpath'"
+
+#, c-format
+msgid "E347: No more file \"%s\" found in path"
+msgstr "E347: Nessun altro file \"%s\" trovato nel percorso"
+
+msgid "Cannot connect to Netbeans #2"
+msgstr "Non posso connettermi a Netbeans #2"
+
+msgid "Cannot connect to Netbeans"
+msgstr "Non posso connettermi a Netbeans"
+
+#, c-format
+msgid "E668: Wrong access mode for NetBeans connection info file: \"%s\""
+msgstr ""
+"E668: Modalità errata di accesso a file info connessione NetBeans: \"%s\""
+
+msgid "read from Netbeans socket"
+msgstr "lettura da socket Netbeans"
+
+#, c-format
+msgid "E658: NetBeans connection lost for buffer %ld"
+msgstr "E658: Connessione NetBeans persa per il buffer %ld"
+
+msgid "E838: netbeans is not supported with this GUI"
+msgstr "E838: netbeans non è supportato con questa GUI"
+
+msgid "E511: netbeans already connected"
+msgstr "E511: netbeans già connesso"
+
+#, c-format
+msgid "E505: %s is read-only (add ! to override)"
+msgstr "E505: %s è in sola lettura (aggiungi ! per eseguire comunque)"
+
+msgid "E349: No identifier under cursor"
+msgstr "E349: Nessun identificativo sotto il cursore"
+
+msgid "E774: 'operatorfunc' is empty"
+msgstr "E774: opzione 'operatorfunc' non impostata"
+
+msgid "E775: Eval feature not available"
+msgstr "E775: Funzionalità [eval] non disponibile"
+
+msgid "Warning: terminal cannot highlight"
+msgstr "Attenzione: il terminale non è in grado di evidenziare"
+
+msgid "E348: No string under cursor"
+msgstr "E348: Nessuna stringa sotto il cursore"
+
+msgid "E352: Cannot erase folds with current 'foldmethod'"
+msgstr "E352: Non posso togliere piegature con il 'foldmethod' in uso"
+
+msgid "E664: changelist is empty"
+msgstr "E664: lista modifiche assente"
+
+msgid "E662: At start of changelist"
+msgstr "E662: All'inizio della lista modifiche"
+
+msgid "E663: At end of changelist"
+msgstr "E663: Alla fine della lista modifiche"
+
+msgid "Type :quit<Enter> to exit Vim"
+msgstr "Batti :quit<Invio> per uscire da Vim"
+
+#, c-format
+msgid "1 line %sed 1 time"
+msgstr "1 linea %sa 1 volta"
+
+#, c-format
+msgid "1 line %sed %d times"
+msgstr "1 linea %sa %d volte"
+
+#, c-format
+msgid "%ld lines %sed 1 time"
+msgstr "%ld linee %se 1 volta"
+
+#, c-format
+msgid "%ld lines %sed %d times"
+msgstr "%ld linee %se %d volte"
+
+#, c-format
+msgid "%ld lines to indent... "
+msgstr "%ld linee da rientrare... "
+
+msgid "1 line indented "
+msgstr "1 linea rientrata "
+
+#, c-format
+msgid "%ld lines indented "
+msgstr "%ld linee rientrate "
+
+msgid "E748: No previously used register"
+msgstr "E748: Nessun registro usato in precedenza"
+
+#. must display the prompt
+msgid "cannot yank; delete anyway"
+msgstr "non riesco a salvare in un registro; cancello comunque"
+
+msgid "1 line changed"
+msgstr "1 linea cambiata"
+
+#, c-format
+msgid "%ld lines changed"
+msgstr "%ld linee cambiate"
+
+#, c-format
+msgid "freeing %ld lines"
+msgstr "libero %ld linee"
+
+msgid "block of 1 line yanked"
+msgstr "blocco di 1 linea messo in registro"
+
+msgid "1 line yanked"
+msgstr "1 linea messa in registro"
+
+#, c-format
+msgid "block of %ld lines yanked"
+msgstr "blocco di %ld linee messo in registro"
+
+#, c-format
+msgid "%ld lines yanked"
+msgstr "%ld linee messe in registro"
+
+#, c-format
+msgid "E353: Nothing in register %s"
+msgstr "E353: Niente nel registro %s"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Registers ---"
+msgstr ""
+"\n"
+"--- Registri ---"
+
+msgid "Illegal register name"
+msgstr "Nome registro non ammesso"
+
+msgid ""
+"\n"
+"# Registers:\n"
+msgstr ""
+"\n"
+"# Registri:\n"
+
+#, c-format
+msgid "E574: Unknown register type %d"
+msgstr "E574: Tipo di registro sconosciuto: %d"
+
+#, c-format
+msgid "%ld Cols; "
+msgstr "%ld Col.; "
+
+#, c-format
+msgid "Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Bytes"
+msgstr "Selezionate %s%ld di %ld Linee; %ld di %ld Parole; %ld di %ld Caratt."
+
+#, c-format
+msgid ""
+"Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Chars; %ld of %ld "
+"Bytes"
+msgstr ""
+"Selezionate %s%ld di %ld Linee; %ld di %ld Parole; %ld di %ld Caratt.; %ld "
+"di %ld Byte"
+
+#, c-format
+msgid "Col %s of %s; Line %ld of %ld; Word %ld of %ld; Byte %ld of %ld"
+msgstr "Col. %s di %s; Linea %ld di %ld; Parola %ld di %ld; Caratt. %ld di %ld"
+
+#, c-format
+msgid ""
+"Col %s of %s; Line %ld of %ld; Word %ld of %ld; Char %ld of %ld; Byte %ld of "
+"%ld"
+msgstr ""
+"Col. %s di %s; Linea %ld di %ld; Parola %ld di %ld; Caratt. %ld di %ld; Byte "
+"%ld di %ld"
+
+#, c-format
+msgid "(+%ld for BOM)"
+msgstr "(+%ld per BOM)"
+
+msgid "%<%f%h%m%=Page %N"
+msgstr "%<%f%h%m%=Pagina %N"
+
+msgid "Thanks for flying Vim"
+msgstr "Grazie per aver volato con Vim"
+
+msgid "E518: Unknown option"
+msgstr "E518: Opzione inesistente"
+
+msgid "E519: Option not supported"
+msgstr "E519: Opzione non supportata"
+
+msgid "E520: Not allowed in a modeline"
+msgstr "E520: Non consentito in una 'modeline'"
+
+msgid "E846: Key code not set"
+msgstr "E846: Key code non impostato"
+
+msgid "E521: Number required after ="
+msgstr "E521: Ci vuole un numero dopo ="
+
+msgid "E522: Not found in termcap"
+msgstr "E522: Non trovato in 'termcap'"
+
+#, c-format
+msgid "E539: Illegal character <%s>"
+msgstr "E539: Carattere non ammesso <%s>"
+
+msgid "E529: Cannot set 'term' to empty string"
+msgstr "E529: Non posso assegnare a 'term' il valore 'stringa nulla'"
+
+msgid "E530: Cannot change term in GUI"
+msgstr "E530: Non posso modificare 'term' mentre sono nella GUI"
+
+msgid "E531: Use \":gui\" to start the GUI"
+msgstr "E531: Usa \":gui\" per far partire la GUI"
+
+msgid "E589: 'backupext' and 'patchmode' are equal"
+msgstr "E589: 'backupext' e 'patchmode' sono uguali"
+
+msgid "E834: Conflicts with value of 'listchars'"
+msgstr "E834: Conflitto con il valore di 'listchars'"
+
+msgid "E835: Conflicts with value of 'fillchars'"
+msgstr "E835: Conflitto con il valore di 'fillchars'"
+
+msgid "E617: Cannot be changed in the GTK+ 2 GUI"
+msgstr "E617: Non può essere cambiato nella GUI GTK+ 2"
+
+msgid "E524: Missing colon"
+msgstr "E524: Manca ':'"
+
+msgid "E525: Zero length string"
+msgstr "E525: Stringa nulla"
+
+#, c-format
+msgid "E526: Missing number after <%s>"
+msgstr "E526: Manca numero dopo <%s>"
+
+msgid "E527: Missing comma"
+msgstr "E527: Manca virgola"
+
+msgid "E528: Must specify a ' value"
+msgstr "E528: Devi specificare un valore '"
+
+msgid "E595: contains unprintable or wide character"
+msgstr "E595: contiene carattere 'wide' o non-stampabile"
+
+msgid "E596: Invalid font(s)"
+msgstr "E596: Font non validi"
+
+msgid "E597: can't select fontset"
+msgstr "E597: non posso selezionare fontset"
+
+msgid "E598: Invalid fontset"
+msgstr "E598: Fontset non valido"
+
+msgid "E533: can't select wide font"
+msgstr "E533: non posso selezionare 'wide font'"
+
+msgid "E534: Invalid wide font"
+msgstr "E534: 'Wide font' non valido"
+
+#, c-format
+msgid "E535: Illegal character after <%c>"
+msgstr "E535: Carattere non ammesso dopo <%c>"
+
+msgid "E536: comma required"
+msgstr "E536: virgola mancante"
+
+#, c-format
+msgid "E537: 'commentstring' must be empty or contain %s"
+msgstr "E537: 'commentstring' deve essere nulla o contenere %s"
+
+msgid "E538: No mouse support"
+msgstr "E538: Manca supporto mouse"
+
+msgid "E540: Unclosed expression sequence"
+msgstr "E540: Espressione non terminata"
+
+msgid "E541: too many items"
+msgstr "E541: troppi elementi"
+
+msgid "E542: unbalanced groups"
+msgstr "E542: gruppi sbilanciati"
+
+msgid "E590: A preview window already exists"
+msgstr "E590: Una finestra di pre-visualizzazione esiste già"
+
+msgid "W17: Arabic requires UTF-8, do ':set encoding=utf-8'"
+msgstr "W17: Arabo richiede UTF-8, esegui ':set encoding=utf-8'"
+
+#, c-format
+msgid "E593: Need at least %d lines"
+msgstr "E593: Servono almeno %d linee"
+
+#, c-format
+msgid "E594: Need at least %d columns"
+msgstr "E594: Servono almeno %d colonne"
+
+#, c-format
+msgid "E355: Unknown option: %s"
+msgstr "E355: Opzione inesistente: %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.
+#, c-format
+msgid "E521: Number required: &%s = '%s'"
+msgstr "E521: Ci vuole un numero: &%s = '%s'"
+
+msgid ""
+"\n"
+"--- Terminal codes ---"
+msgstr ""
+"\n"
+"--- Codici terminale ---"
+
+msgid ""
+"\n"
+"--- Global option values ---"
+msgstr ""
+"\n"
+"--- Valori opzioni globali ---"
+
+msgid ""
+"\n"
+"--- Local option values ---"
+msgstr ""
+"\n"
+"--- Valore opzioni locali ---"
+
+msgid ""
+"\n"
+"--- Options ---"
+msgstr ""
+"\n"
+"--- Opzioni ---"
+
+msgid "E356: get_varp ERROR"
+msgstr "E356: ERRORE get_varp"
+
+#, c-format
+msgid "E357: 'langmap': Matching character missing for %s"
+msgstr "E357: 'langmap': Manca carattere corrispondente per %s"
+
+#, c-format
+msgid "E358: 'langmap': Extra characters after semicolon: %s"
+msgstr "E358: 'langmap': Caratteri in più dopo il ';': %s"
+
+msgid "cannot open "
+msgstr "non riesco ad aprire "
+
+msgid "VIM: Can't open window!\n"
+msgstr "VIM: Non riesco ad aprire la finestra!\n"
+
+msgid "Need Amigados version 2.04 or later\n"
+msgstr "Serve Amigados versione 2.04 o successiva\n"
+
+#, c-format
+msgid "Need %s version %ld\n"
+msgstr "Serve %s versione %ld\n"
+
+msgid "Cannot open NIL:\n"
+msgstr "Non riesco ad aprire NIL:\n"
+
+msgid "Cannot create "
+msgstr "Non riesco a creare "
+
+#, c-format
+msgid "Vim exiting with %d\n"
+msgstr "Vim esce con %d\n"
+
+msgid "cannot change console mode ?!\n"
+msgstr "non posso modificare modalità console ?!\n"
+
+msgid "mch_get_shellsize: not a console??\n"
+msgstr "mch_get_shellsize: non una console??\n"
+
+#. if Vim opened a window: Executing a shell may cause crashes
+msgid "E360: Cannot execute shell with -f option"
+msgstr "E360: Non posso eseguire lo shell con l'opzione -f"
+
+msgid "Cannot execute "
+msgstr "Non riesco a eseguire "
+
+msgid "shell "
+msgstr "shell "
+
+msgid " returned\n"
+msgstr " ottenuto\n"
+
+msgid "ANCHOR_BUF_SIZE too small."
+msgstr "ANCHOR_BUF_SIZE troppo piccolo."
+
+msgid "I/O ERROR"
+msgstr "ERRORE I/O"
+
+msgid "Message"
+msgstr "Messaggio"
+
+msgid "'columns' is not 80, cannot execute external commands"
+msgstr "'columns' non vale 80, non riesco ad eseguire comandi esterni"
+
+msgid "E237: Printer selection failed"
+msgstr "E237: Scelta stampante non riuscita"
+
+#, c-format
+msgid "to %s on %s"
+msgstr "a %s su %s"
+
+#, c-format
+msgid "E613: Unknown printer font: %s"
+msgstr "E613: Font per stampante sconosciuto: %s"
+
+#, c-format
+msgid "E238: Print error: %s"
+msgstr "E238: Errore durante stampa: %s"
+
+#, c-format
+msgid "Printing '%s'"
+msgstr "Stampato: '%s'"
+
+#, c-format
+msgid "E244: Illegal charset name \"%s\" in font name \"%s\""
+msgstr "E244: Nome di charset non ammesso \"%s\" nel fonte di nome \"%s\""
+
+#, c-format
+msgid "E245: Illegal char '%c' in font name \"%s\""
+msgstr "E245: Carattere non ammesso '%c' nel font di nome \"%s\""
+
+msgid "Vim: Double signal, exiting\n"
+msgstr "Vim: Segnale doppio, esco\n"
+
+#, c-format
+msgid "Vim: Caught deadly signal %s\n"
+msgstr "Vim: Intercettato segnale fatale %s\n"
+
+msgid "Vim: Caught deadly signal\n"
+msgstr "Vim: Intercettato segnale fatale\n"
+
+#, c-format
+msgid "Opening the X display took %ld msec"
+msgstr "Attivazione visualizzazione X ha richiesto %ld msec"
+
+msgid ""
+"\n"
+"Vim: Got X error\n"
+msgstr ""
+"\n"
+"Vim: Preso errore X\n"
+
+msgid "Testing the X display failed"
+msgstr "Prova visualizzazione X fallita"
+
+msgid "Opening the X display timed out"
+msgstr "Apertura visualizzazione X: tempo scaduto"
+
+msgid ""
+"\n"
+"Could not get security context for "
+msgstr ""
+"\n"
+"Non posso ottenere il contesto di sicurezza per "
+
+msgid ""
+"\n"
+"Could not set security context for "
+msgstr ""
+"\n"
+"Non posso impostare il contesto di sicurezza per "
+
+msgid ""
+"\n"
+"Cannot execute shell "
+msgstr ""
+"\n"
+"Non riesco a eseguire shell "
+
+msgid ""
+"\n"
+"Cannot execute shell sh\n"
+msgstr ""
+"\n"
+"Non riesco a eseguire shell sh\n"
+
+msgid ""
+"\n"
+"shell returned "
+msgstr ""
+"\n"
+"shell terminato con return-code "
+
+msgid ""
+"\n"
+"Cannot create pipes\n"
+msgstr ""
+"\n"
+"Non posso creare 'pipe'\n"
+
+msgid ""
+"\n"
+"Cannot fork\n"
+msgstr ""
+"\n"
+"Non riesco ad effettuare 'fork'\n"
+
+msgid ""
+"\n"
+"Command terminated\n"
+msgstr ""
+"\n"
+"Comando terminato\n"
+
+msgid "XSMP lost ICE connection"
+msgstr "XSMP ha perso la connessione ICE"
+
+#, c-format
+msgid "dlerror = \"%s\""
+msgstr "dlerror = \"%s\""
+
+msgid "Opening the X display failed"
+msgstr "Apertura visualizzazione X fallita"
+
+msgid "XSMP handling save-yourself request"
+msgstr "XSMP gestione richiesta 'save-yourself'"
+
+msgid "XSMP opening connection"
+msgstr "XSMP apertura connessione"
+
+msgid "XSMP ICE connection watch failed"
+msgstr "XSMP osservazione connessione ICE fallita"
+
+#, c-format
+msgid "XSMP SmcOpenConnection failed: %s"
+msgstr "XSMP SmcOpenConnection fallita: %s"
+
+msgid "At line"
+msgstr "Alla linea"
+
+msgid "Could not load vim32.dll!"
+msgstr "Non riesco a caricare vim32.dll!"
+
+msgid "VIM Error"
+msgstr "Errore VIM"
+
+msgid "Could not fix up function pointers to the DLL!"
+msgstr "Non sono riuscito a impostare puntatori di funzione verso la DLL!"
+
+#, c-format
+msgid "shell returned %d"
+msgstr "shell terminato con return-code %d"
+
+#, c-format
+msgid "Vim: Caught %s event\n"
+msgstr "Vim: Intercettato evento %s\n"
+
+msgid "close"
+msgstr "chiusura"
+
+msgid "logoff"
+msgstr "logoff"
+
+msgid "shutdown"
+msgstr "shutdown"
+
+msgid "E371: Command not found"
+msgstr "E371: Comando non trovato"
+
+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 non trovato nel tuo $PATH.\n"
+"I comandi esterni non faranno una pausa dopo aver finito l'esecuzione.\n"
+"Vedi :help win32-vimrun per ulteriori informazioni."
+
+msgid "Vim Warning"
+msgstr "Avviso da Vim"
+
+msgid "E372: Too many %%%c in format string"
+msgstr "E372: Troppi %%%c nella stringa di 'format'"
+
+msgid "E373: Unexpected %%%c in format string"
+msgstr "E373: %%%c imprevisto nella stringa di 'format'"
+
+msgid "E374: Missing ] in format string"
+msgstr "E374: Manca ] nella stringa di 'format'"
+
+msgid "E375: Unsupported %%%c in format string"
+msgstr "E375: %%%c non supportato nella stringa di 'format'"
+
+msgid "E376: Invalid %%%c in format string prefix"
+msgstr "E376: %%%c non valido nel prefisso della stringa di 'format'"
+
+msgid "E377: Invalid %%%c in format string"
+msgstr "E377: %%%c non valido nella stringa di 'format'"
+
+msgid "E378: 'errorformat' contains no pattern"
+msgstr "E378: 'errorformat' non contiene alcun modello"
+
+msgid "E379: Missing or empty directory name"
+msgstr "E379: Nome directory mancante o nullo"
+
+msgid "E553: No more items"
+msgstr "E553: Non ci sono più elementi"
+
+#, c-format
+msgid "(%d of %d)%s%s: "
+msgstr "(%d di %d)%s%s: "
+
+msgid " (line deleted)"
+msgstr " (linea cancellata)"
+
+msgid "E380: At bottom of quickfix stack"
+msgstr "E380: Al fondo dello stack di quickfix"
+
+msgid "E381: At top of quickfix stack"
+msgstr "E381: In cima allo stack di quickfix"
+
+#, c-format
+msgid "error list %d of %d; %d errors"
+msgstr "lista errori %d di %d; %d errori"
+
+msgid "E382: Cannot write, 'buftype' option is set"
+msgstr "E382: Non posso scrivere, l'opzione 'buftype' è impostata"
+
+msgid "Error file"
+msgstr "File errori"
+
+msgid "E683: File name missing or invalid pattern"
+msgstr "E683: Nome file mancante o espressione non valida"
+
+#, c-format
+msgid "Cannot open file \"%s\""
+msgstr "Non riesco ad aprire il file \"%s\""
+
+msgid "E681: Buffer is not loaded"
+msgstr "E681: Buffer non caricato"
+
+msgid "E777: String or List expected"
+msgstr "E777: aspettavo Stringa o Lista"
+
+#, c-format
+msgid "E769: Missing ] after %s["
+msgstr "E769: Manca ] dopo %s["
+
+msgid "E53: Unmatched %s%%("
+msgstr "E53: Senza riscontro: %s%%("
+
+#, c-format
+msgid "E54: Unmatched %s("
+msgstr "E54: Senza riscontro: %s("
+
+#, c-format
+msgid "E55: Unmatched %s)"
+msgstr "E55: Senza riscontro: %s)"
+
+msgid "E66: \\z( not allowed here"
+msgstr "E66: \\z( non consentito qui"
+
+msgid "E67: \\z1 et al. not allowed here"
+msgstr "E67: \\z1 ecc. non consentiti qui"
+
+msgid "E69: Missing ] after %s%%["
+msgstr "E69: Manca ] dopo %s%%["
+
+msgid "E70: Empty %s%%[]"
+msgstr "E70: %s%%[] vuoto"
+
+msgid "E339: Pattern too long"
+msgstr "E339: Espressione troppo lunga"
+
+msgid "E50: Too many \\z("
+msgstr "E50: Troppe \\z("
+
+#, c-format
+msgid "E51: Too many %s("
+msgstr "E51: Troppe %s("
+
+msgid "E52: Unmatched \\z("
+msgstr "E52: Senza riscontro: \\z("
+
+#, c-format
+msgid "E59: invalid character after %s@"
+msgstr "E59: Carattere non ammesso dopo %s@"
+
+#, c-format
+msgid "E60: Too many complex %s{...}s"
+msgstr "E60: Troppi %s{...}s complessi"
+
+#, c-format
+msgid "E61: Nested %s*"
+msgstr "E61: %s* nidificato"
+
+#, c-format
+msgid "E62: Nested %s%c"
+msgstr "E62: %s%c nidificato"
+
+msgid "E63: invalid use of \\_"
+msgstr "E63: uso non valido di \\_"
+
+#, c-format
+msgid "E64: %s%c follows nothing"
+msgstr "E64: %s%c senza nulla prima"
+
+msgid "E65: Illegal back reference"
+msgstr "E65: Riferimento all'indietro non ammesso"
+
+msgid "E68: Invalid character after \\z"
+msgstr "E68: Carattere non ammesso dopo \\z"
+
+msgid "E678: Invalid character after %s%%[dxouU]"
+msgstr "E678: Carattere non valido dopo %s%%[dxouU]"
+
+msgid "E71: Invalid character after %s%%"
+msgstr "E71: Carattere non ammesso dopo %s%%"
+
+#, c-format
+msgid "E554: Syntax error in %s{...}"
+msgstr "E554: Errore sintattico in %s{...}"
+
+msgid "External submatches:\n"
+msgstr "Sotto-corrispondenze esterne:\n"
+
+msgid ""
+"E864: \\%#= can only be followed by 0, 1, or 2. The automatic engine will be "
+"used "
+msgstr ""
+"E864: \\%#= può essere seguito solo da 0, 1 o 2. Sarà usato il motore automatico "
+
+#, c-format
+msgid "E866: (NFA regexp) Misplaced %c"
+msgstr "E866: (NFA regexp) %c fuori posto"
+
+msgid "E865: (NFA) Regexp end encountered prematurely"
+msgstr "E865: (NFA) Fine prematura dell'espressione regolare"
+
+#, c-format
+msgid "E867: (NFA) Unknown operator '\\z%c'"
+msgstr "E867: (NFA) Operatore sconosciuto '\\z%c'"
+
+msgid "E867: (NFA) Unknown operator '\\%%%c'"
+msgstr "E867: (NFA) Operatore sconosciuto '\\%%%c'"
+
+#. should never happen
+msgid "E868: Error building NFA with equivalence class!"
+msgstr "E868: Errore nel build di NFA con classe di equivalenza!"
+
+#, c-format
+msgid "E869: (NFA) Unknown operator '\\@%c'"
+msgstr "E869: (NFA) Operatore sconosciuto '\\@%c'"
+
+msgid "E870: (NFA regexp) Error reading repetition limits"
+msgstr "E870: (NFA regexp) Errore nella lettura dei limiti di ripetizione"
+
+#. Can't have a multi follow a multi.
+msgid "E871: (NFA regexp) Can't have a multi follow a multi !"
+msgstr "E871: (NFA regexp) Non si può avere multi dopo multi !"
+
+#. Too many `('
+msgid "E872: (NFA regexp) Too many '('"
+msgstr "E872: (NFA regexp) Troppi '('"
+
+msgid "E879: (NFA regexp) Too many \\z("
+msgstr "E879: (NFA regexp) Troppi \\z("
+
+msgid "E873: (NFA regexp) proper termination error"
+msgstr "E873: (NFA regexp) errore di terminazione corretta"
+
+msgid "E874: (NFA) Could not pop the stack !"
+msgstr "E874: (NFA) Impossibile riprendere lo stack !"
+
+msgid ""
+"E875: (NFA regexp) (While converting from postfix to NFA), too many states "
+"left on stack"
+msgstr "E875: (NFA regexp) (Nella conversione da postfix a NFA), "
+"troppi stati lasciati sullo stack"
+
+msgid "E876: (NFA regexp) Not enough space to store the whole NFA "
+msgstr "E876: (NFA regexp) Non c'è spazio per immagazzinare l'intero NFA "
+
+msgid "E878: (NFA) Could not allocate memory for branch traversal!"
+msgstr "E878: (NFA) Non posso allocare memoria per il zigzag di ramo!"
+
+msgid ""
+"Could not open temporary log file for writing, displaying on stderr ... "
+msgstr ""
+"Non posso aprire il file temporaneo per la scrittura, mostro su stderr ... "
+
+#, c-format
+msgid "(NFA) COULD NOT OPEN %s !"
+msgstr "(NFA) IMPOSSIBILE APRIRE %s !"
+
+msgid "Could not open temporary log file for writing "
+msgstr "Non posso aprire il log temporaneo in scrittura "
+
+msgid " VREPLACE"
+msgstr " V-SOSTITUISCI"
+
+msgid " REPLACE"
+msgstr " SOSTITUISCI"
+
+msgid " REVERSE"
+msgstr " INVERTITO"
+
+msgid " INSERT"
+msgstr " INSERISCI"
+
+msgid " (insert)"
+msgstr " (inserisci)"
+
+msgid " (replace)"
+msgstr " (sostituisci)"
+
+msgid " (vreplace)"
+msgstr " (v-sostituisci)"
+
+msgid " Hebrew"
+msgstr " Ebraico"
+
+msgid " Arabic"
+msgstr " Arabo"
+
+msgid " (lang)"
+msgstr " (lingua)"
+
+msgid " (paste)"
+msgstr " (incolla)"
+
+msgid " VISUAL"
+msgstr " VISUALE"
+
+msgid " VISUAL LINE"
+msgstr " VISUALE LINEA"
+
+msgid " VISUAL BLOCK"
+msgstr " VISUALE BLOCCO"
+
+msgid " SELECT"
+msgstr " SELEZIONA"
+
+msgid " SELECT LINE"
+msgstr " SELEZIONA LINEA"
+
+msgid " SELECT BLOCK"
+msgstr " SELEZIONA BLOCCO"
+
+msgid "recording"
+msgstr "registrazione"
+
+#, c-format
+msgid "E383: Invalid search string: %s"
+msgstr "E383: Stringa di ricerca non valida: %s"
+
+#, c-format
+msgid "E384: search hit TOP without match for: %s"
+msgstr "E384: la ricerca ha raggiunto la CIMA senza successo per: %s"
+
+#, c-format
+msgid "E385: search hit BOTTOM without match for: %s"
+msgstr "E385: la ricerca ha raggiunto il FONDO senza successo per: %s"
+
+msgid "E386: Expected '?' or '/' after ';'"
+msgstr "E386: '?' o '/' atteso dopo ';'"
+
+msgid " (includes previously listed match)"
+msgstr " (comprese corrispondenze elencate prima)"
+
+#. cursor at status line
+msgid "--- Included files "
+msgstr "--- File inclusi "
+
+msgid "not found "
+msgstr "non trovati "
+
+msgid "in path ---\n"
+msgstr "nel percorso ---\n"
+
+msgid " (Already listed)"
+msgstr " (Già elencati)"
+
+msgid " NOT FOUND"
+msgstr " NON TROVATO"
+
+#, c-format
+msgid "Scanning included file: %s"
+msgstr "Scandisco file incluso: %s"
+
+#, c-format
+msgid "Searching included file %s"
+msgstr "Cerco nel file incluso: %s"
+
+msgid "E387: Match is on current line"
+msgstr "E387: Corrispondenza nella linea corrente"
+
+msgid "All included files were found"
+msgstr "Tutti i file inclusi sono stati trovati"
+
+msgid "No included files"
+msgstr "Nessun file incluso"
+
+msgid "E388: Couldn't find definition"
+msgstr "E388: Non sono riuscito a trovare la definizione"
+
+msgid "E389: Couldn't find pattern"
+msgstr "E389: Non sono riuscito a trovare il modello"
+
+msgid "Substitute "
+msgstr "Sostituzione "
+
+#, c-format
+msgid ""
+"\n"
+"# Last %sSearch Pattern:\n"
+"~"
+msgstr ""
+"\n"
+"# Ult. %sEspressione di Ricerca:\n"
+"~"
+
+msgid "E759: Format error in spell file"
+msgstr "E759: Errore di formato nel file ortografico"
+
+msgid "E758: Truncated spell file"
+msgstr "E758: File ortografico troncato"
+
+#, c-format
+msgid "Trailing text in %s line %d: %s"
+msgstr "Testo in eccesso in %s linea %d: %s"
+
+#, c-format
+msgid "Affix name too long in %s line %d: %s"
+msgstr "Nome affisso troppo lungo in %s linea %d: %s"
+
+msgid "E761: Format error in affix file FOL, LOW or UPP"
+msgstr "E761: Errore di formato nel file affissi FOL, LOW o UPP"
+
+msgid "E762: Character in FOL, LOW or UPP is out of range"
+msgstr "E762: Carattere fuori intervallo in FOL, LOW o UPP"
+
+msgid "Compressing word tree..."
+msgstr "Comprimo albero di parole..."
+
+msgid "E756: Spell checking is not enabled"
+msgstr "E756: Controllo ortografico non abilitato"
+
+#, c-format
+msgid "Warning: Cannot find word list \"%s_%s.spl\" or \"%s_ascii.spl\""
+msgstr "Attenzione: Non trovo lista parole \"%s_%s.spl\" o \"%s_ascii.spl\""
+
+#, c-format
+msgid "Warning: Cannot find word list \"%s.%s.spl\" or \"%s.ascii.spl\""
+msgstr "Attenzione: Non trovo lista parole \"%s.%s.spl\" o \"%s.ascii.spl\""
+
+#, c-format
+msgid "Reading spell file \"%s\""
+msgstr "Lettura file ortografico \"%s\""
+
+msgid "E757: This does not look like a spell file"
+msgstr "E757: Questo non sembra un file ortografico"
+
+msgid "E771: Old spell file, needs to be updated"
+msgstr "E771: File ortografico obsoleto, è necessario aggiornarlo"
+
+msgid "E772: Spell file is for newer version of Vim"
+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"
+
+#, c-format
+msgid "Warning: region %s not supported"
+msgstr "Attenzione: regione %s non supportata"
+
+#, c-format
+msgid "Reading affix file %s ..."
+msgstr "Lettura file affissi %s ..."
+
+#, c-format
+msgid "Conversion failure for word in %s line %d: %s"
+msgstr "Conversione fallita per una parola in %s linea %d: %s"
+
+#, c-format
+msgid "Conversion in %s not supported: from %s to %s"
+msgstr "Conversione in %s non supportata: da %s a %s"
+
+#, c-format
+msgid "Conversion in %s not supported"
+msgstr "Conversione in %s non supportata"
+
+#, c-format
+msgid "Invalid value for FLAG in %s line %d: %s"
+msgstr "Valore di FLAG non valido in %s linea %d: %s"
+
+#, c-format
+msgid "FLAG after using flags in %s line %d: %s"
+msgstr "FLAG dopo l'uso di flags in %s linea %d: %s"
+
+#, c-format
+msgid ""
+"Defining COMPOUNDFORBIDFLAG after PFX item may give wrong results in %s line "
+"%d"
+msgstr ""
+"Definire COMPOUNDFORBIDFLAG dopo l'elemento PFX potrebbe dare risultati "
+"errati in %s linea %d"
+
+#, c-format
+msgid ""
+"Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in %s line "
+"%d"
+msgstr ""
+"Definire COMPOUNDPERMITFLAG dopo l'elemento PFX potrebbe dare risultati "
+"errati in %s linea %d"
+
+#, c-format
+msgid "Wrong COMPOUNDRULES value in %s line %d: %s"
+msgstr "Valore errato per COMPOUNDRULES in %s linea %d: %s"
+
+#, c-format
+msgid "Wrong COMPOUNDWORDMAX value in %s line %d: %s"
+msgstr "Valore errato per COMPOUNDWORDMAX in %s linea %d: %s"
+
+#, c-format
+msgid "Wrong COMPOUNDMIN value in %s line %d: %s"
+msgstr "Valore errato per COMPOUNDMIN in %s linea %d: %s"
+
+#, c-format
+msgid "Wrong COMPOUNDSYLMAX value in %s line %d: %s"
+msgstr "Valore errato per COMPOUNDSYLMAX in %s linea %d: %s"
+
+#, c-format
+msgid "Wrong CHECKCOMPOUNDPATTERN value in %s line %d: %s"
+msgstr "Valore errato per CHECKCOMPOUNDPATTERN in %s linea %d: %s"
+
+#, c-format
+msgid "Different combining flag in continued affix block in %s line %d: %s"
+msgstr ""
+"Flag combinazione diverso in blocco affissi continuo in %s linea %d: %s"
+
+#, c-format
+msgid "Duplicate affix in %s line %d: %s"
+msgstr "Affisso duplicato in %s linea %d: %s"
+
+#, c-format
+msgid ""
+"Affix also used for BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST in %s "
+"line %d: %s"
+msgstr ""
+"Affisso usato anche per BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST "
+"in %s linea %d: %s"
+
+#, c-format
+msgid "Expected Y or N in %s line %d: %s"
+msgstr "Y o N deve essere presente in %s linea %d: %s"
+
+#, c-format
+msgid "Broken condition in %s line %d: %s"
+msgstr "Condizione non rispettata in %s linea %d: %s"
+
+#, c-format
+msgid "Expected REP(SAL) count in %s line %d"
+msgstr "Contatore REP(SAL) necessario in %s linea %d"
+
+#, c-format
+msgid "Expected MAP count in %s line %d"
+msgstr "Contatore MAP necessario in %s linea %d"
+
+#, c-format
+msgid "Duplicate character in MAP in %s line %d"
+msgstr "Carattere duplicato in MAP in %s linea %d"
+
+#, c-format
+msgid "Unrecognized or duplicate item in %s line %d: %s"
+msgstr "Elemento non riconosciuto o duplicato in %s linea %d: %s"
+
+#, c-format
+msgid "Missing FOL/LOW/UPP line in %s"
+msgstr "Linea FOL/LOW/UPP mancante in %s"
+
+msgid "COMPOUNDSYLMAX used without SYLLABLE"
+msgstr "COMPOUNDSYLMAX usato senza SYLLABLE"
+
+msgid "Too many postponed prefixes"
+msgstr "Troppi suffissi"
+
+msgid "Too many compound flags"
+msgstr "Troppi flag composti"
+
+msgid "Too many postponed prefixes and/or compound flags"
+msgstr "Troppi suffissi e/o flag composti"
+
+#, c-format
+msgid "Missing SOFO%s line in %s"
+msgstr "Linea SOFO%s mancante in %s"
+
+#, c-format
+msgid "Both SAL and SOFO lines in %s"
+msgstr "Linee sia SAL che SOFO in %s"
+
+#, c-format
+msgid "Flag is not a number in %s line %d: %s"
+msgstr "Il flag non è un numero in %s linea %d: %s"
+
+#, c-format
+msgid "Illegal flag in %s line %d: %s"
+msgstr "Flag non ammesso in %s linea %d: %s"
+
+#, c-format
+msgid "%s value differs from what is used in another .aff file"
+msgstr "Il valore di %s è diverso da quello usato in un altro file .aff"
+
+#, c-format
+msgid "Reading dictionary file %s ..."
+msgstr "Lettura file dizionario %s ..."
+
+#, c-format
+msgid "E760: No word count in %s"
+msgstr "E760: Nessun contatore parole in %s"
+
+#, c-format
+msgid "line %6d, word %6d - %s"
+msgstr "linea %6d, parola %6d - %s"
+
+#, c-format
+msgid "Duplicate word in %s line %d: %s"
+msgstr "Parola duplicata in %s linea %d: %s"
+
+#, c-format
+msgid "First duplicate word in %s line %d: %s"
+msgstr "Prima parola duplicata in %s linea %d: %s"
+
+#, c-format
+msgid "%d duplicate word(s) in %s"
+msgstr "%d parole duplicate in %s"
+
+#, c-format
+msgid "Ignored %d word(s) with non-ASCII characters in %s"
+msgstr "%d parole con caratteri non-ASCII ignorate in %s"
+
+#, c-format
+msgid "Reading word file %s ..."
+msgstr "Lettura file parole %s ..."
+
+#, c-format
+msgid "Duplicate /encoding= line ignored in %s line %d: %s"
+msgstr "Linea /encoding= duplicata ignorata in %s linea %d: %s"
+
+#, c-format
+msgid "/encoding= line after word ignored in %s line %d: %s"
+msgstr "Linea /encoding= dopo parola ignorata in %s linea %d: %s"
+
+#, c-format
+msgid "Duplicate /regions= line ignored in %s line %d: %s"
+msgstr "Linea /regions= duplicata ignorata in %s linea %d: %s"
+
+#, c-format
+msgid "Too many regions in %s line %d: %s"
+msgstr "Troppe regioni in %s linea %d: %s"
+
+#, c-format
+msgid "/ line ignored in %s line %d: %s"
+msgstr "Linea / ignorata in %s linea %d: %s"
+
+#, c-format
+msgid "Invalid region nr in %s line %d: %s"
+msgstr "N. regione non valido in %s linea %d: %s"
+
+#, c-format
+msgid "Unrecognized flags in %s line %d: %s"
+msgstr "Flag non riconosciuti in %s linea %d: %s"
+
+#, c-format
+msgid "Ignored %d words with non-ASCII characters"
+msgstr "%d parole con caratteri non-ASCII ignorate"
+
+msgid "E845: Insufficient memory, word list will be incomplete"
+msgstr "E845: Memoria insufficiente, la lista parole sarà incompleta"
+
+msgid "Compressed %d of %d nodes; %d (%d%%) remaining"
+msgstr "%d di %d nodi compressi; ne restano %d (%d%%)"
+
+msgid "Reading back spell file..."
+msgstr "Rilettura file ortografico..."
+
+#.
+#. * Go through the trie of good words, soundfold each word and add it to
+#. * the soundfold trie.
+#.
+msgid "Performing soundfolding..."
+msgstr "Eseguo soundfolding..."
+
+#, c-format
+msgid "Number of words after soundfolding: %ld"
+msgstr "Numero di parole dopo soundfolding: %ld"
+
+#, c-format
+msgid "Total number of words: %d"
+msgstr "Conteggio totale delle parole: %d"
+
+#, c-format
+msgid "Writing suggestion file %s ..."
+msgstr "Scrivo file di suggerimenti %s ..."
+
+#, c-format
+msgid "Estimated runtime memory use: %d bytes"
+msgstr "Uso stimato di memoria durante esecuzione: %d byte"
+
+msgid "E751: Output file name must not have region name"
+msgstr "E751: Il nome del file di output non deve avere il nome di regione"
+
+msgid "E754: Only up to 8 regions supported"
+msgstr "E754: Sono supportate fino ad 8 regioni"
+
+#, c-format
+msgid "E755: Invalid region in %s"
+msgstr "E755: Regione non valida in %s"
+
+msgid "Warning: both compounding and NOBREAK specified"
+msgstr "Attenzione: specificati sia composizione sia NOBREAK"
+
+#, c-format
+msgid "Writing spell file %s ..."
+msgstr "Scrivo file ortografico %s ..."
+
+msgid "Done!"
+msgstr "Fatto!"
+
+#, c-format
+msgid "E765: 'spellfile' does not have %ld entries"
+msgstr "E765: 'spellfile' non ha %ld elementi"
+
+#, c-format
+msgid "Word removed from %s"
+msgstr "Parola rimossa da %s"
+
+#, c-format
+msgid "Word added to %s"
+msgstr "Parola aggiunta a %s"
+
+msgid "E763: Word characters differ between spell files"
+msgstr "E763: Caratteri di parola differenti nei file ortografici"
+
+msgid "Sorry, no suggestions"
+msgstr "Spiacente, nessun suggerimento"
+
+#, c-format
+msgid "Sorry, only %ld suggestions"
+msgstr "Spiacente, solo %ld suggerimenti"
+
+#. for when 'cmdheight' > 1
+#. avoid more prompt
+#, c-format
+msgid "Change \"%.*s\" to:"
+msgstr "Cambiare \"%.*s\" in:"
+
+#, c-format
+msgid " < \"%.*s\""
+msgstr " < \"%.*s\""
+
+msgid "E752: No previous spell replacement"
+msgstr "E752: Nessuna sostituzione ortografica precedente"
+
+#, c-format
+msgid "E753: Not found: %s"
+msgstr "E753: Non trovato: %s"
+
+#, c-format
+msgid "E778: This does not look like a .sug file: %s"
+msgstr "E778: Questo non sembra un file .sug: %s"
+
+#, c-format
+msgid "E779: Old .sug file, needs to be updated: %s"
+msgstr "E779: File .sug obsoleto, è necessario aggiornarlo: %s"
+
+#, c-format
+msgid "E780: .sug file is for newer version of Vim: %s"
+msgstr "E780: Il file .sug è per versioni di Vim più recenti: %s"
+
+#, c-format
+msgid "E781: .sug file doesn't match .spl file: %s"
+msgstr "E781: Il file .sug non corrisponde al file .spl: %s"
+
+#, c-format
+msgid "E782: error while reading .sug file: %s"
+msgstr "E782: Errore leggendo il file .sug: %s"
+
+#. This should have been checked when generating the .spl
+#. * file.
+msgid "E783: duplicate char in MAP entry"
+msgstr "E783: carattere duplicato nell'elemento MAP"
+
+msgid "No Syntax items defined for this buffer"
+msgstr "Nessun elemento sintattico definito per questo buffer"
+
+#, c-format
+msgid "E390: Illegal argument: %s"
+msgstr "E390: Argomento non ammesso: %s"
+
+#, c-format
+msgid "E391: No such syntax cluster: %s"
+msgstr "E391: 'cluster' sintattico inesistente: %s"
+
+msgid "syncing on C-style comments"
+msgstr "sincronizzo i commenti nello stile C"
+
+msgid "no syncing"
+msgstr "nessuna sincronizzazione"
+
+msgid "syncing starts "
+msgstr "la sincronizzazione inizia "
+
+msgid " lines before top line"
+msgstr " linee prima della linea iniziale"
+
+msgid ""
+"\n"
+"--- Syntax sync items ---"
+msgstr ""
+"\n"
+"--- Elementi sincronizzazione sintassi ---"
+
+msgid ""
+"\n"
+"syncing on items"
+msgstr ""
+"\n"
+"sincronizzo elementi"
+
+msgid ""
+"\n"
+"--- Syntax items ---"
+msgstr ""
+"\n"
+"--- Elementi sintattici ---"
+
+#, c-format
+msgid "E392: No such syntax cluster: %s"
+msgstr "E392: 'cluster' sintattico inesistente: %s"
+
+msgid "minimal "
+msgstr "minimale "
+
+msgid "maximal "
+msgstr "massimale "
+
+msgid "; match "
+msgstr "; corrisp. "
+
+msgid " line breaks"
+msgstr " interruzioni di linea"
+
+msgid "E395: contains argument not accepted here"
+msgstr "E395: contiene argomenti non accettati qui"
+
+msgid "E844: invalid cchar value"
+msgstr "E844: valore cchar non valido"
+
+msgid "E393: group[t]here not accepted here"
+msgstr "E393: group[t]here non ammesso qui"
+
+#, c-format
+msgid "E394: Didn't find region item for %s"
+msgstr "E394: Elemento di 'region' non trovato per %s"
+
+msgid "E397: Filename required"
+msgstr "E397: Nome file necessario"
+
+msgid "E847: Too many syntax includes"
+msgstr "E847: Troppe inclusioni di sintassi"
+
+#, c-format
+msgid "E789: Missing ']': %s"
+msgstr "E789: Manca ']': %s"
+
+#, c-format
+msgid "E398: Missing '=': %s"
+msgstr "E398: Manca '=': %s"
+
+#, c-format
+msgid "E399: Not enough arguments: syntax region %s"
+msgstr "E399: Argomenti non sufficienti per: 'syntax region' %s"
+
+msgid "E848: Too many syntax clusters"
+msgstr "E848: Troppi 'cluster' sintattici"
+
+msgid "E400: No cluster specified"
+msgstr "E400: Nessun 'cluster' specificato"
+
+#, c-format
+msgid "E401: Pattern delimiter not found: %s"
+msgstr "E401: Delimitatore di espressione non trovato: %s"
+
+#, c-format
+msgid "E402: Garbage after pattern: %s"
+msgstr "E402: Spazzatura dopo espressione: %s"
+
+msgid "E403: syntax sync: line continuations pattern specified twice"
+msgstr ""
+"E403: syntax sync: espressione di continuazione linea specificata due volte"
+
+#, c-format
+msgid "E404: Illegal arguments: %s"
+msgstr "E404: Argomenti non validi: %s"
+
+#, c-format
+msgid "E405: Missing equal sign: %s"
+msgstr "E405: Manca '=': %s"
+
+#, c-format
+msgid "E406: Empty argument: %s"
+msgstr "E406: Argomento nullo: %s"
+
+#, c-format
+msgid "E407: %s not allowed here"
+msgstr "E407: %s non consentito qui"
+
+#, c-format
+msgid "E408: %s must be first in contains list"
+msgstr "E408: %s deve venire per primo nella lista 'contains'"
+
+#, c-format
+msgid "E409: Unknown group name: %s"
+msgstr "E409: Nome gruppo sconosciuto: %s"
+
+#, c-format
+msgid "E410: Invalid :syntax subcommand: %s"
+msgstr "E410: Sotto-comando :syntax non valido: %s"
+
+msgid ""
+" TOTAL COUNT MATCH SLOWEST AVERAGE NAME PATTERN"
+msgstr ""
+" TOTALE CONT. CORRIS. PIU LENTO MEDIA NOME MODELLO"
+
+msgid "E679: recursive loop loading syncolor.vim"
+msgstr "E679: ciclo ricorsivo nel caricamento di syncolor.vim"
+
+#, c-format
+msgid "E411: highlight group not found: %s"
+msgstr "E411: gruppo evidenziazione non trovato: %s"
+
+#, c-format
+msgid "E412: Not enough arguments: \":highlight link %s\""
+msgstr "E412: Argomenti non sufficienti: \":highlight link %s\""
+
+#, c-format
+msgid "E413: Too many arguments: \":highlight link %s\""
+msgstr "E413: Troppi argomenti: \":highlight link %s\""
+
+msgid "E414: group has settings, highlight link ignored"
+msgstr "E414: 'group' ha impostazioni, 'highlight link' ignorato"
+
+#, c-format
+msgid "E415: unexpected equal sign: %s"
+msgstr "E415: segno '=' inatteso: %s"
+
+#, c-format
+msgid "E416: missing equal sign: %s"
+msgstr "E416: manca segno '=': %s"
+
+#, c-format
+msgid "E417: missing argument: %s"
+msgstr "E417: manca argomento: %s"
+
+#, c-format
+msgid "E418: Illegal value: %s"
+msgstr "E418: Valore non ammesso: %s"
+
+msgid "E419: FG color unknown"
+msgstr "E419: colore di testo sconosciuto"
+
+msgid "E420: BG color unknown"
+msgstr "E420: colore di sfondo sconosciuto"
+
+#, c-format
+msgid "E421: Color name or number not recognized: %s"
+msgstr "E421: Numero o nome di colore non riconosciuto: %s"
+
+#, c-format
+msgid "E422: terminal code too long: %s"
+msgstr "E422: codice terminale troppo lungo: %s"
+
+#, c-format
+msgid "E423: Illegal argument: %s"
+msgstr "E423: Argomento non ammesso: %s"
+
+msgid "E424: Too many different highlighting attributes in use"
+msgstr "E424: Troppi gruppi evidenziazione differenti in uso"
+
+msgid "E669: Unprintable character in group name"
+msgstr "E669: Carattere non stampabile in un nome di gruppo"
+
+msgid "W18: Invalid character in group name"
+msgstr "W18: Carattere non ammesso in un nome di gruppo"
+
+msgid "E849: Too many highlight and syntax groups"
+msgstr "E849: Troppi gruppi di evidenziazione e sintassi"
+
+msgid "E555: at bottom of tag stack"
+msgstr "E555: al fondo dello stack dei tag"
+
+msgid "E556: at top of tag stack"
+msgstr "E556: in cima allo stack dei tag"
+
+msgid "E425: Cannot go before first matching tag"
+msgstr "E425: Non posso andare prima del primo tag corrispondente"
+
+#, c-format
+msgid "E426: tag not found: %s"
+msgstr "E426: tag non trovato: %s"
+
+msgid " # pri kind tag"
+msgstr " # pri tipo tag"
+
+msgid "file\n"
+msgstr "file\n"
+
+msgid "E427: There is only one matching tag"
+msgstr "E427: C'è solo un tag corrispondente"
+
+msgid "E428: Cannot go beyond last matching tag"
+msgstr "E428: Non posso andare oltre l'ultimo tag corrispondente"
+
+#, c-format
+msgid "File \"%s\" does not exist"
+msgstr "Il file \"%s\" non esiste"
+
+#. Give an indication of the number of matching tags
+#, c-format
+msgid "tag %d of %d%s"
+msgstr "tag %d di %d%s"
+
+msgid " or more"
+msgstr " o più"
+
+msgid " Using tag with different case!"
+msgstr " Uso tag ignorando maiuscole/minuscole!"
+
+#, c-format
+msgid "E429: File \"%s\" does not exist"
+msgstr "E429: Il file \"%s\" non esiste"
+
+#. Highlight title
+msgid ""
+"\n"
+" # TO tag FROM line in file/text"
+msgstr ""
+"\n"
+" # A tag DA__ linea in file/testo"
+
+#, c-format
+msgid "Searching tags file %s"
+msgstr "Ricerca nel tag file %s"
+
+#, c-format
+msgid "E430: Tag file path truncated for %s\n"
+msgstr "E430: Percorso tag file troncato per %s\n"
+
+msgid "Ignoring long line in tags file"
+msgstr "Linea lunga ignorata nel tag file"
+
+#, c-format
+msgid "E431: Format error in tags file \"%s\""
+msgstr "E431: Errore di formato nel tag file \"%s\""
+
+#, c-format
+msgid "Before byte %ld"
+msgstr "Prima del byte %ld"
+
+#, c-format
+msgid "E432: Tags file not sorted: %s"
+msgstr "E432: Tag file non ordinato alfabeticamente: %s"
+
+#. never opened any tags file
+msgid "E433: No tags file"
+msgstr "E433: Nessun tag file"
+
+msgid "E434: Can't find tag pattern"
+msgstr "E434: Non riesco a trovare modello tag"
+
+msgid "E435: Couldn't find tag, just guessing!"
+msgstr "E435: Non riesco a trovare tag, sto solo tirando a indovinare!"
+
+#, c-format
+msgid "Duplicate field name: %s"
+msgstr "Nome di campo duplicato: %s"
+
+msgid "' not known. Available builtin terminals are:"
+msgstr "' non noto. Terminali disponibili predisposti sono:"
+
+msgid "defaulting to '"
+msgstr "predefinito a '"
+
+msgid "E557: Cannot open termcap file"
+msgstr "E557: Non posso aprire file 'termcap'"
+
+msgid "E558: Terminal entry not found in terminfo"
+msgstr "E558: Descrizione terminale non trovata in 'terminfo'"
+
+msgid "E559: Terminal entry not found in termcap"
+msgstr "E559: Descrizione terminale non trovata in 'termcap'"
+
+#, c-format
+msgid "E436: No \"%s\" entry in termcap"
+msgstr "E436: Nessuna descrizione per \"%s\" in 'termcap'"
+
+msgid "E437: terminal capability \"cm\" required"
+msgstr "E437: capacità \"cm\" del terminale necessaria"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Terminal keys ---"
+msgstr ""
+"\n"
+"--- Tasti Terminale ---"
+
+msgid "new shell started\n"
+msgstr "fatto eseguire nuovo shell\n"
+
+msgid "Vim: Error reading input, exiting...\n"
+msgstr "Vim: Errore leggendo l'input, esco...\n"
+
+msgid "Used CUT_BUFFER0 instead of empty selection"
+msgstr "Uso CUT_BUFFER0 invece che una scelta nulla"
+
+#. This happens when the FileChangedRO autocommand changes the
+#. * file in a way it becomes shorter.
+msgid "E834: Line count changed unexpectedly"
+msgstr "E834: Il conteggio delle righe è inaspettatamente cambiato"
+
+#. must display the prompt
+msgid "No undo possible; continue anyway"
+msgstr "'undo' non più possibile; continuo comunque"
+
+#, c-format
+msgid "E828: Cannot open undo file for writing: %s"
+msgstr "E828: Non posso aprire il file Undo in scrittura: %s"
+
+#, c-format
+msgid "E825: Corrupted undo file (%s): %s"
+msgstr "E825: File Undo corrotto (%s): %s"
+
+msgid "Cannot write undo file in any directory in 'undodir'"
+msgstr "Non posso scrivere un file Undo in alcuna directory di 'undodir'"
+
+#, c-format
+msgid "Will not overwrite with undo file, cannot read: %s"
+msgstr "File Undo non sovrascritto, non riesco a leggere: %s"
+
+#, c-format
+msgid "Will not overwrite, this is not an undo file: %s"
+msgstr "Non sovrascritto, non è un file Undo: %s"
+
+msgid "Skipping undo file write, nothing to undo"
+msgstr "Ometto scrittura del file Undo, non ci sono modifiche"
+
+#, c-format
+msgid "Writing undo file: %s"
+msgstr "Scrivo file Undo: %s"
+
+#, c-format
+msgid "E829: write error in undo file: %s"
+msgstr "E829: errore scrivendo nel file Undo: %s"
+
+#, c-format
+msgid "Not reading undo file, owner differs: %s"
+msgstr "Non leggo file Undo, appartiene a un altro utente: %s"
+
+#, c-format
+msgid "Reading undo file: %s"
+msgstr "Lettura file Undo: %s"
+
+#, c-format
+msgid "E822: Cannot open undo file for reading: %s"
+msgstr "E822: Non posso aprire il file Undo in lettura: %s"
+
+#, c-format
+msgid "E823: Not an undo file: %s"
+msgstr "E823: Non è un file Undo: %s"
+
+#, c-format
+msgid "E832: Non-encrypted file has encrypted undo file: %s"
+msgstr "E832: File non cifrato con file Undo cifrato: %s"
+
+#, c-format
+msgid "E826: Undo file decryption failed: %s"
+msgstr "E826: Decifratura fallita del file Undo: %s"
+
+#, c-format
+msgid "E827: Undo file is encrypted: %s"
+msgstr "E827: File Undo cifrato: %s"
+
+#, c-format
+msgid "E824: Incompatible undo file: %s"
+msgstr "E824: File Undo incompatibile: %s"
+
+msgid "File contents changed, cannot use undo info"
+msgstr "File ulteriormente modificato, non posso usare informazioni di Undo"
+
+#, c-format
+msgid "Finished reading undo file %s"
+msgstr "Lettura del file Undo %s effettuata"
+
+msgid "Already at oldest change"
+msgstr "Questa è già la prima modifica"
+
+msgid "Already at newest change"
+msgstr "Questa è già l'ultima modifica"
+
+#, c-format
+msgid "E830: Undo number %ld not found"
+msgstr "E830: Undo numero %ld non trovato"
+
+msgid "E438: u_undo: line numbers wrong"
+msgstr "E438: u_undo: numeri linee errati"
+
+msgid "more line"
+msgstr "linea in più"
+
+msgid "more lines"
+msgstr "linee in più"
+
+msgid "line less"
+msgstr "linea in meno"
+
+msgid "fewer lines"
+msgstr "linee in meno"
+
+msgid "change"
+msgstr "modifica"
+
+msgid "changes"
+msgstr "modifiche"
+
+#, c-format
+msgid "%ld %s; %s #%ld %s"
+msgstr "%ld %s; %s #%ld %s"
+
+msgid "before"
+msgstr "prima"
+
+msgid "after"
+msgstr "dopo"
+
+msgid "Nothing to undo"
+msgstr "Nessuna modifica, Undo impossibile"
+
+msgid "number changes when saved"
+msgstr "numero modif. quando salv."
+
+#, c-format
+msgid "%ld seconds ago"
+msgstr "%ld secondi fa"
+
+msgid "E790: undojoin is not allowed after undo"
+msgstr "E790: undojoin non è consentito dopo undo"
+
+msgid "E439: undo list corrupt"
+msgstr "E439: lista 'undo' non valida"
+
+msgid "E440: undo line missing"
+msgstr "E440: linea di 'undo' mancante"
+
+#. Only MS VC 4.1 and earlier can do Win32s
+msgid ""
+"\n"
+"MS-Windows 16/32-bit GUI version"
+msgstr ""
+"\n"
+"versione MS-Windows 16/32-bit GUI"
+
+msgid ""
+"\n"
+"MS-Windows 64-bit GUI version"
+msgstr ""
+"\n"
+"Versione MS-Windows 64-bit GUI"
+
+msgid ""
+"\n"
+"MS-Windows 32-bit GUI version"
+msgstr ""
+"\n"
+"Versione MS-Windows 32-bit GUI"
+
+msgid " in Win32s mode"
+msgstr " in modalità Win32s"
+
+msgid " with OLE support"
+msgstr " con supporto OLE"
+
+msgid ""
+"\n"
+"MS-Windows 64-bit console version"
+msgstr ""
+"\n"
+"Versione MS-Windows 64-bit console"
+
+msgid ""
+"\n"
+"MS-Windows 32-bit console version"
+msgstr ""
+"\n"
+"Versione MS-Windows 32-bit console"
+
+msgid ""
+"\n"
+"MS-Windows 16-bit version"
+msgstr ""
+"\n"
+"Versione MS-Windows 16-bit"
+
+msgid ""
+"\n"
+"32-bit MS-DOS version"
+msgstr ""
+"\n"
+"Version MS-DOS 32-bit"
+
+msgid ""
+"\n"
+"16-bit MS-DOS version"
+msgstr ""
+"\n"
+"Versione MS-DOS 16-bit"
+
+msgid ""
+"\n"
+"MacOS X (unix) version"
+msgstr ""
+"\n"
+"Versione MacOS X (unix)"
+
+msgid ""
+"\n"
+"MacOS X version"
+msgstr ""
+"\n"
+"Versione X MacOS"
+
+msgid ""
+"\n"
+"MacOS version"
+msgstr ""
+"\n"
+"Versione MacOS"
+
+msgid ""
+"\n"
+"OpenVMS version"
+msgstr ""
+"\n"
+"Versione OpenVMS"
+
+msgid ""
+"\n"
+"Included patches: "
+msgstr ""
+"\n"
+"Patch incluse: "
+
+msgid ""
+"\n"
+"Extra patches: "
+msgstr ""
+"\n"
+"Patch aggiuntive: "
+
+msgid "Modified by "
+msgstr "Modificato da "
+
+msgid ""
+"\n"
+"Compiled "
+msgstr ""
+"\n"
+"Compilato "
+
+msgid "by "
+msgstr "da "
+
+msgid ""
+"\n"
+"Huge version "
+msgstr ""
+"\n"
+"Versione gigante "
+
+msgid ""
+"\n"
+"Big version "
+msgstr ""
+"\n"
+"Versione grande "
+
+msgid ""
+"\n"
+"Normal version "
+msgstr ""
+"\n"
+"Versione normale "
+
+msgid ""
+"\n"
+"Small version "
+msgstr ""
+"\n"
+"Versione piccola "
+
+msgid ""
+"\n"
+"Tiny version "
+msgstr ""
+"\n"
+"Versione minuscola "
+
+msgid "without GUI."
+msgstr "senza GUI."
+
+msgid "with GTK2-GNOME GUI."
+msgstr "con GUI GTK2-GNOME."
+
+msgid "with GTK2 GUI."
+msgstr "con GUI GTK2."
+
+msgid "with X11-Motif GUI."
+msgstr "con GUI X11-Motif."
+
+msgid "with X11-neXtaw GUI."
+msgstr "con GUI X11-neXtaw."
+
+msgid "with X11-Athena GUI."
+msgstr "con GUI X11-Athena."
+
+msgid "with Photon GUI."
+msgstr "con GUI Photon."
+
+msgid "with GUI."
+msgstr "con GUI."
+
+msgid "with Carbon GUI."
+msgstr "con GUI Carbon."
+
+msgid "with Cocoa GUI."
+msgstr "con GUI Cocoa."
+
+msgid "with (classic) GUI."
+msgstr "con GUI (classica)."
+
+msgid " Features included (+) or not (-):\n"
+msgstr " Funzionalità incluse (+) o escluse (-):\n"
+
+msgid " system vimrc file: \""
+msgstr " file vimrc di sistema: \""
+
+msgid " user vimrc file: \""
+msgstr " file vimrc utente: \""
+
+msgid " 2nd user vimrc file: \""
+msgstr " II file vimrc utente: \""
+
+msgid " 3rd user vimrc file: \""
+msgstr " III file vimrc utente: \""
+
+msgid " user exrc file: \""
+msgstr " file exrc utente: \""
+
+msgid " 2nd user exrc file: \""
+msgstr " II file exrc utente: \""
+
+msgid " system gvimrc file: \""
+msgstr " file gvimrc di sistema: \""
+
+msgid " user gvimrc file: \""
+msgstr " file gvimrc utente: \""
+
+msgid "2nd user gvimrc file: \""
+msgstr " II file gvimrc utente: \""
+
+msgid "3rd user gvimrc file: \""
+msgstr " III file gvimrc utente: \""
+
+msgid " system menu file: \""
+msgstr " file menu di sistema: \""
+
+msgid " fall-back for $VIM: \""
+msgstr " $VIM di riserva: \""
+
+msgid " f-b for $VIMRUNTIME: \""
+msgstr " $VIMRUNTIME di riserva: \""
+
+msgid "Compilation: "
+msgstr "Compilazione: "
+
+msgid "Compiler: "
+msgstr "Compilatore: "
+
+msgid "Linking: "
+msgstr "Link: "
+
+msgid " DEBUG BUILD"
+msgstr " VERSIONE DEBUG"
+
+msgid "VIM - Vi IMproved"
+msgstr "VIM - Vi IMproved (VI Migliorato)"
+
+msgid "version "
+msgstr "versione "
+
+msgid "by Bram Moolenaar et al."
+msgstr "di Bram Moolenaar et al."
+
+msgid "Vim is open source and freely distributable"
+msgstr "Vim è 'open source' e può essere distribuito liberamente"
+
+msgid "Help poor children in Uganda!"
+msgstr "Aiuta i bambini poveri dell'Uganda!"
+
+msgid "type :help iccf<Enter> for information "
+msgstr "batti :help iccf<Invio> per informazioni "
+
+msgid "type :q<Enter> to exit "
+msgstr "batti :q<Invio> per uscire "
+
+msgid "type :help<Enter> or <F1> for on-line help"
+msgstr "batti :help<Invio> o <F1> per aiuto online "
+
+msgid "type :help version7<Enter> for version info"
+msgstr "batti :help version7<Invio> per informazioni su versione"
+
+msgid "Running in Vi compatible mode"
+msgstr "Eseguo in modalità compatibile Vi"
+
+msgid "type :set nocp<Enter> for Vim defaults"
+msgstr "batti :set nocp<Invio> per valori predefiniti Vim"
+
+msgid "type :help cp-default<Enter> for info on this"
+msgstr "batti :help cp-default<Enter> per info al riguardo"
+
+msgid "menu Help->Orphans for information "
+msgstr "menu Aiuto->Orfani per informazioni "
+
+msgid "Running modeless, typed text is inserted"
+msgstr "Esecuzione senza modalità: solo inserimento"
+
+msgid "menu Edit->Global Settings->Toggle Insert Mode "
+msgstr "menu Modifica->Impost.Globali->Modal.Inser. Sì/No"
+
+msgid " for two modes "
+msgstr " per modo Inser./Comandi"
+
+msgid "menu Edit->Global Settings->Toggle Vi Compatible"
+msgstr "menu Modifica->Impost.Globali->Compatibile Vi Sì/No"
+
+msgid " for Vim defaults "
+msgstr " modo Vim predefinito "
+
+msgid "Sponsor Vim development!"
+msgstr "Sponsorizza lo sviluppo di Vim!"
+
+msgid "Become a registered Vim user!"
+msgstr "Diventa un utente Vim registrato!"
+
+msgid "type :help sponsor<Enter> for information "
+msgstr "batti :help sponsor<Invio> per informazioni "
+
+msgid "type :help register<Enter> for information "
+msgstr "batti :help register<Invio> per informazioni "
+
+msgid "menu Help->Sponsor/Register for information "
+msgstr "menu Aiuto->Sponsor/Registrazione per informazioni "
+
+msgid "WARNING: Windows 95/98/ME detected"
+msgstr "ATTENZIONE: Trovato Windows 95/98/ME"
+
+msgid "type :help windows95<Enter> for info on this"
+msgstr "batti :help windows95<Enter> per info al riguardo"
+
+msgid "Already only one window"
+msgstr "C'è già una finestra sola"
+
+msgid "E441: There is no preview window"
+msgstr "E441: Non c'è una finestra di pre-visualizzazione"
+
+msgid "E442: Can't split topleft and botright at the same time"
+msgstr "E442: Non riesco a dividere ALTO-SX e BASSO-DX contemporaneamente"
+
+msgid "E443: Cannot rotate when another window is split"
+msgstr "E443: Non posso ruotare quando un'altra finestra è divisa in due"
+
+msgid "E444: Cannot close last window"
+msgstr "E444: Non riesco a chiudere l'ultima finestra"
+
+msgid "E813: Cannot close autocmd window"
+msgstr "E813: Non riesco a chiudere la finestra autocomandi"
+
+msgid "E814: Cannot close window, only autocmd window would remain"
+msgstr ""
+"E814: Non posso chiudere questa finestra, rimarrebbe solo la finestra "
+"autocomandi"
+
+msgid "E445: Other window contains changes"
+msgstr "E445: Altre finestre contengono modifiche"
+
+msgid "E446: No file name under cursor"
+msgstr "E446: Nessun nome file sotto il cursore"
+
+#, c-format
+msgid "E447: Can't find file \"%s\" in path"
+msgstr "E447: Non riesco a trovare il file \"%s\" nel percorso"
+
+#, c-format
+msgid "E370: Could not load library %s"
+msgstr "E370: Non riesco a caricare la libreria %s"
+
+msgid "Sorry, this command is disabled: the Perl library could not be loaded."
+msgstr ""
+"Spiacente, comando non disponibile, non riesco a caricare libreria programmi "
+"Perl."
+
+msgid "E299: Perl evaluation forbidden in sandbox without the Safe module"
+msgstr ""
+"E299: Valorizzazione Perl vietata in ambiente protetto senza il modulo Safe"
+
+msgid "Edit with &multiple Vims"
+msgstr "Apri con &molti Vim"
+
+msgid "Edit with single &Vim"
+msgstr "Apri con un solo &Vim"
+
+msgid "Diff with Vim"
+msgstr "Differenza con Vim"
+
+msgid "Edit with &Vim"
+msgstr "Apri con &Vim"
+
+msgid "Edit with existing Vim - "
+msgstr "Apri con Vim esistente - "
+
+msgid "Edits the selected file(s) with Vim"
+msgstr "Apri i(l) file scelto(i) con Vim"
+
+msgid "Error creating process: Check if gvim is in your path!"
+msgstr ""
+"Errore creando il processo: Controllate che gvim sia incluso nel vostro "
+"percorso (PATH)"
+
+msgid "gvimext.dll error"
+msgstr "errore gvimext.dll"
+
+msgid "Path length too long!"
+msgstr "Percorso file troppo lungo!"
+
+msgid "--No lines in buffer--"
+msgstr "--File vuoto--"
+
+#.
+#. * 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: Comando finito male"
+
+msgid "E471: Argument required"
+msgstr "E471: Argomento necessario"
+
+msgid "E10: \\ should be followed by /, ? or &"
+msgstr "E10: \\ dovrebbe essere seguito da /, ? oppure &"
+
+msgid "E11: Invalid in command-line window; <CR> executes, CTRL-C quits"
+msgstr "E11: Non valido nella finestra comandi; <INVIO> esegue, CTRL-C ignora"
+
+msgid "E12: Command not allowed from exrc/vimrc in current dir or tag search"
+msgstr ""
+"E12: Comando non ammesso da exrc/vimrc nella dir. in uso o nella ricerca tag"
+
+msgid "E171: Missing :endif"
+msgstr "E171: Manca :endif"
+
+msgid "E600: Missing :endtry"
+msgstr "E600: Manca :endtry"
+
+msgid "E170: Missing :endwhile"
+msgstr "E170: Manca :endwhile"
+
+msgid "E170: Missing :endfor"
+msgstr "E170: Manca :endfor"
+
+msgid "E588: :endwhile without :while"
+msgstr "E588: :endwhile senza :while"
+
+msgid "E588: :endfor without :for"
+msgstr "E588: :endfor senza :for"
+
+msgid "E13: File exists (add ! to override)"
+msgstr "E13: File esistente (aggiungi ! per riscriverlo)"
+
+msgid "E472: Command failed"
+msgstr "E472: Comando fallito"
+
+#, c-format
+msgid "E234: Unknown fontset: %s"
+msgstr "E234: Fontset sconosciuto: %s"
+
+#, c-format
+msgid "E235: Unknown font: %s"
+msgstr "E235: Font sconosciuto: %s"
+
+#, c-format
+msgid "E236: Font \"%s\" is not fixed-width"
+msgstr "E236: Font \"%s\" non di larghezza fissa"
+
+msgid "E473: Internal error"
+msgstr "E473: Errore interno"
+
+msgid "Interrupted"
+msgstr "Interrotto"
+
+msgid "E14: Invalid address"
+msgstr "E14: Indirizzo non valido"
+
+msgid "E474: Invalid argument"
+msgstr "E474: Argomento non valido"
+
+#, c-format
+msgid "E475: Invalid argument: %s"
+msgstr "E475: Argomento non valido: %s"
+
+#, c-format
+msgid "E15: Invalid expression: %s"
+msgstr "E15: Espressione non valida: %s"
+
+msgid "E16: Invalid range"
+msgstr "E16: Intervallo non valido"
+
+msgid "E476: Invalid command"
+msgstr "E476: Comando non valido"
+
+#, c-format
+msgid "E17: \"%s\" is a directory"
+msgstr "E17: \"%s\" è una directory"
+
+#, c-format
+msgid "E364: Library call failed for \"%s()\""
+msgstr "E364: Chiamata a libreria fallita per \"%s()\""
+
+#, c-format
+msgid "E448: Could not load library function %s"
+msgstr "E448: Non posso caricare la funzione di libreria %s"
+
+msgid "E19: Mark has invalid line number"
+msgstr "E19: 'Mark' con numero linea non valido"
+
+msgid "E20: Mark not set"
+msgstr "E20: 'Mark' non impostato"
+
+msgid "E21: Cannot make changes, 'modifiable' is off"
+msgstr "E21: Non posso fare modifiche, 'modifiable' è inibito"
+
+msgid "E22: Scripts nested too deep"
+msgstr "E22: Script troppo nidificati"
+
+msgid "E23: No alternate file"
+msgstr "E23: Nessun file alternato"
+
+msgid "E24: No such abbreviation"
+msgstr "E24: Abbreviazione inesistente"
+
+msgid "E477: No ! allowed"
+msgstr "E477: ! non consentito"
+
+msgid "E25: GUI cannot be used: Not enabled at compile time"
+msgstr "E25: GUI non utilizzabile: Non abilitata in compilazione"
+
+msgid "E26: Hebrew cannot be used: Not enabled at compile time\n"
+msgstr "E26: Ebraico non utilizzabile: Non abilitato in compilazione\n"
+
+msgid "E27: Farsi cannot be used: Not enabled at compile time\n"
+msgstr "E27: Farsi non utilizzabile: Non abilitato in compilazione\n"
+
+msgid "E800: Arabic cannot be used: Not enabled at compile time\n"
+msgstr "E800: Arabo non utilizzabile: Non abilitato in compilazione\n"
+
+#, c-format
+msgid "E28: No such highlight group name: %s"
+msgstr "E28: Nome di gruppo di evidenziazione inesistente: %s"
+
+msgid "E29: No inserted text yet"
+msgstr "E29: Ancora nessun testo inserito"
+
+msgid "E30: No previous command line"
+msgstr "E30: Nessuna linea comandi precedente"
+
+msgid "E31: No such mapping"
+msgstr "E31: Mapping inesistente"
+
+msgid "E479: No match"
+msgstr "E479: Nessuna corrispondenza"
+
+#, c-format
+msgid "E480: No match: %s"
+msgstr "E480: Nessuna corrispondenza: %s"
+
+msgid "E32: No file name"
+msgstr "E32: Manca nome file"
+
+msgid "E33: No previous substitute regular expression"
+msgstr "E33: Nessuna espressione regolare precedente di 'substitute'"
+
+msgid "E34: No previous command"
+msgstr "E34: Nessun comando precedente"
+
+msgid "E35: No previous regular expression"
+msgstr "E35: Nessuna espressione regolare precedente"
+
+msgid "E481: No range allowed"
+msgstr "E481: Nessun intervallo consentito"
+
+msgid "E36: Not enough room"
+msgstr "E36: Manca spazio"
+
+#, c-format
+msgid "E247: no registered server named \"%s\""
+msgstr "E247: non esiste server registrato con nome \"%s\""
+
+#, c-format
+msgid "E482: Can't create file %s"
+msgstr "E482: Non riesco a creare il file %s"
+
+msgid "E483: Can't get temp file name"
+msgstr "E483: Non riesco ad ottenere nome file 'temp'"
+
+#, c-format
+msgid "E484: Can't open file %s"
+msgstr "E484: Non riesco ad aprire il file %s"
+
+#, c-format
+msgid "E485: Can't read file %s"
+msgstr "E485: Non riesco a leggere il file %s"
+
+msgid "E37: No write since last change (add ! to override)"
+msgstr "E37: Non salvato dopo modifica (aggiungi ! per eseguire comunque)"
+
+msgid "E38: Null argument"
+msgstr "E38: Argomento nullo"
+
+msgid "E39: Number expected"
+msgstr "E39: Mi aspettavo un numero"
+
+#, c-format
+msgid "E40: Can't open errorfile %s"
+msgstr "E40: Non riesco ad aprire il file errori %s"
+
+msgid "E233: cannot open display"
+msgstr "E233: non riesco ad aprire lo schermo"
+
+msgid "E41: Out of memory!"
+msgstr "E41: Non c'è più memoria!"
+
+msgid "Pattern not found"
+msgstr "Espressione non trovata"
+
+#, c-format
+msgid "E486: Pattern not found: %s"
+msgstr "E486: Espressione non trovata: %s"
+
+msgid "E487: Argument must be positive"
+msgstr "E487: L'argomento deve essere positivo"
+
+msgid "E459: Cannot go back to previous directory"
+msgstr "E459: Non posso tornare alla directory precedente"
+
+msgid "E42: No Errors"
+msgstr "E42: Nessun Errore"
+
+msgid "E776: No location list"
+msgstr "E776: Nessuna lista locazioni"
+
+msgid "E43: Damaged match string"
+msgstr "E43: Stringa di confronto danneggiata"
+
+msgid "E44: Corrupted regexp program"
+msgstr "E44: Programma 'regexp' corrotto"
+
+msgid "E45: 'readonly' option is set (add ! to override)"
+msgstr "E45: file in sola lettura (aggiungi ! per eseguire comunque)"
+
+#, c-format
+msgid "E46: Cannot change read-only variable \"%s\""
+msgstr "E46: Non posso cambiare la variabile read-only \"%s\""
+
+#, c-format
+msgid "E794: Cannot set variable in the sandbox: \"%s\""
+msgstr ""
+"E794: Non posso impostare la variabile read-only in ambiente protetto: \"%s\""
+
+msgid "E47: Error while reading errorfile"
+msgstr "E47: Errore leggendo il file errori"
+
+msgid "E48: Not allowed in sandbox"
+msgstr "E48: Non ammesso in ambiente protetto"
+
+msgid "E523: Not allowed here"
+msgstr "E523: Non consentito qui"
+
+msgid "E359: Screen mode setting not supported"
+msgstr "E359: Impostazione modalità schermo non supportata"
+
+msgid "E49: Invalid scroll size"
+msgstr "E49: Quantità di 'scroll' non valida"
+
+msgid "E91: 'shell' option is empty"
+msgstr "E91: opzione 'shell' non impostata"
+
+msgid "E255: Couldn't read in sign data!"
+msgstr "E255: Errore -- non sono riuscito a leggere i dati del 'sign'!"
+
+msgid "E72: Close error on swap file"
+msgstr "E72: Errore durante chiusura swap file"
+
+msgid "E73: tag stack empty"
+msgstr "E73: tag stack ancora vuoto"
+
+msgid "E74: Command too complex"
+msgstr "E74: Comando troppo complesso"
+
+msgid "E75: Name too long"
+msgstr "E75: Nome troppo lungo"
+
+msgid "E76: Too many ["
+msgstr "E76: Troppe ["
+
+msgid "E77: Too many file names"
+msgstr "E77: Troppi nomi file"
+
+msgid "E488: Trailing characters"
+msgstr "E488: Caratteri in più a fine comando"
+
+msgid "E78: Unknown mark"
+msgstr "E78: 'Mark' sconosciuto"
+
+msgid "E79: Cannot expand wildcards"
+msgstr "E79: Non posso espandere 'wildcard'"
+
+msgid "E591: 'winheight' cannot be smaller than 'winminheight'"
+msgstr "E591: 'winheight' non può essere inferiore a 'winminheight'"
+
+msgid "E592: 'winwidth' cannot be smaller than 'winminwidth'"
+msgstr "E592: 'winwidth' non può essere inferiore a 'winminwidth'"
+
+msgid "E80: Error while writing"
+msgstr "E80: Errore in scrittura"
+
+msgid "Zero count"
+msgstr "Contatore a zero"
+
+msgid "E81: Using <SID> not in a script context"
+msgstr "E81: Uso di <SID> fuori dal contesto di uno script"
+
+msgid "E449: Invalid expression received"
+msgstr "E449: Ricevuta un'espressione non valida"
+
+msgid "E463: Region is guarded, cannot modify"
+msgstr "E463: Regione protetta, impossibile modificare"
+
+msgid "E744: NetBeans does not allow changes in read-only files"
+msgstr "E744: NetBeans non permette modifiche a file di sola lettura"
+
+#, c-format
+msgid "E685: Internal error: %s"
+msgstr "E685: Errore interno: %s"
+
+msgid "E363: pattern uses more memory than 'maxmempattern'"
+msgstr "E363: l'espressione usa troppa memoria rispetto a 'maxmempattern'"
+
+msgid "E749: empty buffer"
+msgstr "E749: buffer vuoto"
+
+msgid "E682: Invalid search pattern or delimiter"
+msgstr "E682: Espressione o delimitatore di ricerca non validi"
+
+msgid "E139: File is loaded in another buffer"
+msgstr "E139: File già caricato in un altro buffer"
+
+#, c-format
+msgid "E764: Option '%s' is not set"
+msgstr "E764: opzione '%s' non impostata"
+
+msgid "E850: Invalid register name"
+msgstr "E850: Nome registro non valido"
+
+msgid "search hit TOP, continuing at BOTTOM"
+msgstr "raggiunta la CIMA nella ricerca, continuo dal FONDO"
+
+msgid "search hit BOTTOM, continuing at TOP"
+msgstr "raggiunto il FONDO nella ricerca, continuo dalla CIMA"
+
+#, c-format
+msgid "Need encryption key for \"%s\""
+msgstr "Serve una chiave di cifratura per \"%s\""
+
+#, c-format
+msgid "expected str() or unicode() instance, but got %s"
+msgstr "attesa istanza di str() o unicode(), trovato invece %s"
+
+#, c-format
+msgid "expected bytes() or str() instance, but got %s"
+msgstr "attesa istanza di bytes() o str(), trovato invece %s"
+
+#, c-format
+msgid ""
+"expected int(), long() or something supporting coercing to long(), but got %s"
+msgstr ""
+"atteso int(), long() o qualcosa che supporti forzatura a long(), trovato invece %s"
+
+#, c-format
+msgid "expected int() or something supporting coercing to int(), but got %s"
+msgstr "atteso int() o qualcosa che supporti forzatura a int(), trovato invece %s"
+
+msgid "value is too large to fit into C int type"
+msgstr "valore troppo grande per il tipo int del C"
+
+msgid "value is too small to fit into C int type"
+msgstr "valore troppo piccolo per il tipo int del C"
+
+msgid "number must be greater then zero"
+msgstr "il numero dev'essere maggiore di zero"
+
+msgid "number must be greater or equal to zero"
+msgstr "il numero dev'essere maggiore o uguale a zero"
+
+msgid "can't delete OutputObject attributes"
+msgstr "non riesco a cancellare gli attributi OutputObject"
+
+#, c-format
+msgid "invalid attribute: %s"
+msgstr "attributo non valido: %s"
+
+msgid "E264: Python: Error initialising I/O objects"
+msgstr "E264: Python: Errore di inizializzazione oggetti I/O"
+
+msgid "failed to change directory"
+msgstr "cambio directory non riuscito"
+
+#, c-format
+msgid "expected 3-tuple as imp.find_module() result, but got %s"
+msgstr "atteso terzetto come risultato di imp.find_module(), trovato invece %s"
+
+#, c-format
+msgid "expected 3-tuple as imp.find_module() result, but got tuple of size %d"
+msgstr "atteso terzetto come risultato di imp.find_module(), trovato invece tuple di dimens. %d"
+
+msgid "internal error: imp.find_module returned tuple with NULL"
+msgstr "errore interno: imp.find_module restituisce tuple con NULL"
+
+msgid "cannot delete vim.Dictionary attributes"
+msgstr "non riesco a cancellare gli attributi vim.Dictionary"
+
+msgid "cannot modify fixed dictionary"
+msgstr "non posso modificare il dizionario fisso"
+
+#, c-format
+msgid "cannot set attribute %s"
+msgstr "non posso impostare attributo %s"
+
+msgid "hashtab changed during iteration"
+msgstr "hashtab cambiato durante l'iterazione"
+
+#, c-format
+msgid "expected sequence element of size 2, but got sequence of size %d"
+msgstr "atteso elemento sequenza di dimensione 2, trovata sequenza di dimensione %d"
+
+msgid "list constructor does not accept keyword arguments"
+msgstr "il costruttore di lista non accetta parole chiave come argomenti"
+
+msgid "list index out of range"
+msgstr "indice di lista non nell'intervallo"
+
+#. No more suitable format specifications in python-2.3
+#, c-format
+msgid "internal error: failed to get vim list item %d"
+msgstr "errore interno: non ho potuto ottenere l'elemento di vim list %d"
+
+msgid "failed to add item to list"
+msgstr "non ho potuto aggiungere un elemento alla lista"
+
+#, c-format
+msgid "internal error: no vim list item %d"
+msgstr "errore interno: non c'è un elemento di vim list %d"
+
+msgid "internal error: failed to add item to list"
+msgstr "errore interno: non ho potuto aggiungere un elemento alla lista"
+
+msgid "cannot delete vim.List attributes"
+msgstr "non riesco a cancellare gli attributi vim.List"
+
+msgid "cannot modify fixed list"
+msgstr "non posso modificare la lista fissa"
+
+#, c-format
+msgid "unnamed function %s does not exist"
+msgstr "la funzione anonima %s non esiste"
+
+#, c-format
+msgid "function %s does not exist"
+msgstr "la funzione %s non esiste"
+
+msgid "function constructor does not accept keyword arguments"
+msgstr "il costruttore di funzione non accetta parole chiave come argomenti"
+
+#, c-format
+msgid "failed to run function %s"
+msgstr "esecuzione non riuscita della funzione %s"
+
+msgid "unable to get option value"
+msgstr "impossibile ottenere il valore di opzione"
+
+msgid "internal error: unknown option type"
+msgstr "errore interno: tipo di opzione sconosciuto"
+
+msgid "problem while switching windows"
+msgstr "problema nel cambio finestra"
+
+#, c-format
+msgid "unable to unset global option %s"
+msgstr "impossibile deimpostare l'opzione globale %s"
+
+#, c-format
+msgid "unable to unset option %s which does not have global value"
+msgstr "impossibile deimpostare l'opzione %s che non ha un valore globale"
+
+msgid "attempt to refer to deleted tab page"
+msgstr "tentativo di riferimento a linguetta cancellata"
+
+msgid "no such tab page"
+msgstr "linguetta inesistente"
+
+msgid "attempt to refer to deleted window"
+msgstr "tentativo di riferimento a una finestra cancellata"
+
+msgid "readonly attribute: buffer"
+msgstr "attributo in sola lettura: buffer"
+
+msgid "cursor position outside buffer"
+msgstr "posizione cursore fuori dal buffer"
+
+msgid "no such window"
+msgstr "finestra inesistente"
+
+msgid "attempt to refer to deleted buffer"
+msgstr "tentativo di riferimento a buffer cancellato"
+
+msgid "failed to rename buffer"
+msgstr "cambio nome buffer non riuscito"
+
+msgid "mark name must be a single character"
+msgstr "il nome mark dev'essere un carattere singolo"
+
+#, c-format
+msgid "expected vim.Buffer object, but got %s"
+msgstr "atteso oggetto vim.Buffer, trovato %s"
+
+#, c-format
+msgid "failed to switch to buffer %d"
+msgstr "passaggio non riuscito al buffer %d"
+
+#, c-format
+msgid "expected vim.Window object, but got %s"
+msgstr "atteso oggetto vim.Window, trovato %s"
+
+msgid "failed to find window in the current tab page"
+msgstr "non è stato possibile trovare la finestra nella pagina con linguette corrente"
+
+msgid "did not switch to the specified window"
+msgstr "passaggio alla finestra specificata non effettuato"
+
+#, c-format
+msgid "expected vim.TabPage object, but got %s"
+msgstr "atteso oggetto vim.TabPage, trovato %s"
+
+msgid "did not switch to the specified tab page"
+msgstr "passaggio alla linguetta specificata non effettuato"
+
+msgid "failed to run the code"
+msgstr "esecuzione del codice non riuscita"
+
+msgid "E858: Eval did not return a valid python object"
+msgstr "E858: Eval non ha restituito un oggetto python valido"
+
+msgid "E859: Failed to convert returned python object to vim value"
+msgstr "E859: Conversione non riuscita dell'oggetto python risultato a un valore vim"
+
+#, c-format
+msgid "unable to convert %s to vim dictionary"
+msgstr "impossibile convertire %s a dizionario vim"
+
+#, c-format
+msgid "unable to convert %s to vim structure"
+msgstr "impossibile convertire %s a struttura vim"
+
+msgid "internal error: NULL reference passed"
+msgstr "errore interno: passato riferimento NULL"
+
+msgid "internal error: invalid value type"
+msgstr "errore interno: tipo di valore non valido"
+
+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 ""
+"Impostazione dell'ancora di percorso non riuscita: sys.path_hooks non è una lista\n"
+"Dovresti fare così:\n"
+"- aggiungere vim.path_hook a vim.path_hooks\n"
+"- aggiungere vim.VIM_SPECIAL_PATH a 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 ""
+"Impostazione di percorso non riuscita: sys.path non è una lista\n"
+"Dovresti aggiungere vim.VIM_SPECIAL_PATH a sys.path"
+
diff --git a/src/po/ja.euc-jp.po b/src/po/ja.euc-jp.po
new file mode 100644
index 0000000000..49ae304eb3
--- /dev/null
+++ b/src/po/ja.euc-jp.po
@@ -0,0 +1,6808 @@
+# Japanese 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.
+#
+# Last Change: 2013 Jul 06
+#
+# Copyright (C) 2001-13 MURAOKA Taro <koron.kaoriya@gmail.com>
+# THIS FILE IS DISTRIBUTED UNDER THE VIM LICENSE.
+#
+# Generated from ja.po, DO NOT EDIT.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Vim 7.4\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2013-07-06 13:50+0900\n"
+"PO-Revision-Date: 2013-07-06 15:00+0900\n"
+"Last-Translator: MURAOKA Taro <koron.kaoriya@gmail.com>\n"
+"Language-Team: MURAOKA Taro <koron.kaoriya@gmail.com>\n"
+"Language: Japanese\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=euc-jp\n"
+"Content-Transfer-Encoding: 8-bit\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°Å¹æ¤Î¥Ó¥Ã¥°/¥ê¥È¥ë¥¨¥ó¥Ç¥£¥¢¥ó¤¬´Ö°ã¤Ã¤Æ¤¤¤Þ¤¹"
+
+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: autocommand¤¬¥³¥Þ¥ó¥É¤ÎÄä»ß¤ò°ú¤­µ¯¤³¤·¤Þ¤·¤¿"
+
+msgid "E82: Cannot allocate any buffer, exiting..."
+msgstr "E82: ¥Ð¥Ã¥Õ¥¡¤ò1¤Ä¤âºîÀ®¤Ç¤­¤Ê¤¤¤Î¤Ç, ½ªÎ»¤·¤Þ¤¹..."
+
+msgid "E83: Cannot allocate buffer, using other one..."
+msgstr "E83: ¥Ð¥Ã¥Õ¥¡¤òºîÀ®¤Ç¤­¤Ê¤¤¤Î¤Ç, ¾¤Î¤ò»ÈÍѤ·¤Þ¤¹..."
+
+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 "E84: No modified buffer found"
+msgstr "E84: Êѹ¹¤µ¤ì¤¿¥Ð¥Ã¥Õ¥¡¤Ï¤¢¤ê¤Þ¤»¤ó"
+
+#. back where we started, didn't find anything.
+msgid "E85: There is no listed buffer"
+msgstr "E85: ¥ê¥¹¥Èɽ¼¨¤µ¤ì¤ë¥Ð¥Ã¥Õ¥¡¤Ï¤¢¤ê¤Þ¤»¤ó"
+
+#, c-format
+msgid "E86: Buffer %ld does not exist"
+msgstr "E86: ¥Ð¥Ã¥Õ¥¡ %ld ¤Ï¤¢¤ê¤Þ¤»¤ó"
+
+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 "E90: Cannot unload last buffer"
+msgstr "E90: ºÇ¸å¤Î¥Ð¥Ã¥Õ¥¡¤Ï²òÊü¤Ç¤­¤Þ¤»¤ó"
+
+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%%-- col "
+
+msgid "[No Name]"
+msgstr "[̵̾]"
+
+#. must be a help buffer
+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 "[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"
+
+#, c-format
+msgid "E96: Can not diff more than %ld buffers"
+msgstr "E96: %ld °Ê¾å¤Î¥Ð¥Ã¥Õ¥¡¤Ïdiff¤Ç¤­¤Þ¤»¤ó"
+
+msgid "E810: Cannot read or write temp files"
+msgstr "E810: °ì»þ¥Õ¥¡¥¤¥ë¤ÎÆÉ¹þ¤â¤·¤¯¤Ï½ñ¹þ¤¬¤Ç¤­¤Þ¤»¤ó"
+
+msgid "E97: Cannot create diffs"
+msgstr "E97: º¹Ê¬¤òºîÀ®¤Ç¤­¤Þ¤»¤ó "
+
+msgid "Patch file"
+msgstr "¥Ñ¥Ã¥Á¥Õ¥¡¥¤¥ë"
+
+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: ¸½ºß¤Î¥Ð¥Ã¥Õ¥¡¤Ïº¹Ê¬¥â¡¼¥É¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó"
+
+msgid "E793: No other buffer in diff mode is modifiable"
+msgstr "E793: º¹Ê¬¥â¡¼¥É¤Ç¤¢¤ë¾¤Î¥Ð¥Ã¥Õ¥¡¤ÏÊѹ¹²Äǽ¤Ç¤¹"
+
+msgid "E100: No other buffer in diff mode"
+msgstr "E100: º¹Ê¬¥â¡¼¥É¤Ç¤¢¤ë¾¤Î¥Ð¥Ã¥Õ¥¡¤Ï¤¢¤ê¤Þ¤»¤ó"
+
+msgid "E101: More than two buffers in diff mode, don't know which one to use"
+msgstr ""
+"E101: º¹Ê¬¥â¡¼¥É¤Î¥Ð¥Ã¥Õ¥¡¤¬2¸Ä°Ê¾å¤¢¤ë¤Î¤Ç¡¢¤É¤ì¤ò»È¤¦¤«ÆÃÄê¤Ç¤­¤Þ¤»¤ó"
+
+#, 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\" ¤Ïº¹Ê¬¥â¡¼¥É¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó"
+
+msgid "E787: Buffer changed unexpectedly"
+msgstr "E787: ͽ´ü¤»¤º¥Ð¥Ã¥Õ¥¡¤¬Êѹ¹Êѹ¹¤µ¤ì¤Þ¤·¤¿"
+
+msgid "E104: Escape not allowed in digraph"
+msgstr "E104: ¹ç»ú¤ËEscape¤Ï»ÈÍѤǤ­¤Þ¤»¤ó"
+
+msgid "E544: Keymap file not found"
+msgstr "E544: ¥­¡¼¥Þ¥Ã¥×¥Õ¥¡¥¤¥ë¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó"
+
+msgid "E105: Using :loadkeymap not in a sourced file"
+msgstr "E105: :source ¤Ç¼è¹þ¤à¥Õ¥¡¥¤¥ë°Ê³°¤Ç¤Ï :loadkeymap ¤ò»È¤¨¤Þ¤»¤ó"
+
+msgid "E791: Empty keymap entry"
+msgstr "E791: ¶õ¤Î¥­¡¼¥Þ¥Ã¥×¥¨¥ó¥È¥ê"
+
+msgid " Keyword completion (^N^P)"
+msgstr " ¥­¡¼¥ï¡¼¥ÉÊä´° (^N^P)"
+
+#. ctrl_x_mode == 0, ^P/^N compl.
+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 " ¥ª¥à¥ËÊä´° (^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 " 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.
+#.
+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 "E684: list index out of range: %ld"
+msgstr "E684: ¥ê¥¹¥È¤Î¥¤¥ó¥Ç¥Ã¥¯¥¹¤¬Èϰϳ°¤Ç¤¹: %ld"
+
+#, c-format
+msgid "E121: Undefined variable: %s"
+msgstr "E121: ̤ÄêµÁ¤ÎÊÑ¿ô¤Ç¤¹: %s"
+
+msgid "E111: Missing ']'"
+msgstr "E111: ']' ¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó"
+
+#, c-format
+msgid "E686: Argument of %s must be a List"
+msgstr "E686: %s ¤Î°ú¿ô¤Ï¥ê¥¹¥È·¿¤Ç¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó"
+
+#, c-format
+msgid "E712: Argument of %s must be a List or Dictionary"
+msgstr "E712: %s ¤Î°ú¿ô¤Ï¥ê¥¹¥È·¿¤Þ¤¿¤Ï¼­½ñ·¿¤Ç¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó"
+
+msgid "E713: Cannot use empty key for Dictionary"
+msgstr "E713: ¼­½ñ·¿¤Ë¶õ¤Î¥­¡¼¤ò»È¤¦¤³¤È¤Ï¤Ç¤­¤Þ¤»¤ó"
+
+msgid "E714: List required"
+msgstr "E714: ¥ê¥¹¥È·¿¤¬É¬ÍפǤ¹"
+
+msgid "E715: Dictionary required"
+msgstr "E715: ¼­½ñ·¿¤¬É¬ÍפǤ¹"
+
+#, 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"
+
+#, 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: ´Ø¿ô»²¾È·¿¤¬Í׵ᤵ¤ì¤Þ¤¹"
+
+msgid "E719: Cannot use [:] with a Dictionary"
+msgstr "E719: [:] ¤ò¼­½ñ·¿¤ÈÁȤ߹ç¤ï¤»¤Æ¤Ï»È¤¨¤Þ¤»¤ó"
+
+#, c-format
+msgid "E734: Wrong variable type for %s="
+msgstr "E734: °Û¤Ê¤Ã¤¿·¿¤ÎÊÑ¿ô¤Ç¤¹ %s="
+
+#, c-format
+msgid "E130: Unknown function: %s"
+msgstr "E130: ̤ÃΤδؿô¤Ç¤¹: %s"
+
+#, c-format
+msgid "E461: Illegal variable name: %s"
+msgstr "E461: ÉÔÀµ¤ÊÊÑ¿ô̾¤Ç¤¹: %s"
+
+msgid "E806: using Float as a String"
+msgstr "E806: ÉâÆ°¾®¿ôÅÀ¿ô¤òʸ»úÎó¤È¤·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹"
+
+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 "¥ê¥¹¥È·¿¤ÎÃͤË2¤Ä°Ê¾å¤Î ; ¤¬¸¡½Ð¤µ¤ì¤Þ¤·¤¿"
+
+#, 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: [:] ¤Ë¤Ï¥ê¥¹¥È·¿¤ÎÃͤ¬É¬ÍפǤ¹"
+
+msgid "E710: List value has more items than target"
+msgstr "E710: ¥ê¥¹¥È·¿ÊÑ¿ô¤Ë¥¿¡¼¥²¥Ã¥È¤è¤ê¤â¿¤¤Í×ÁǤ¬¤¢¤ê¤Þ¤¹"
+
+msgid "E711: List value has not enough items"
+msgstr "E711: ¥ê¥¹¥È·¿ÊÑ¿ô¤Ë½½Ê¬¤Ê¿ô¤ÎÍ×ÁǤ¬¤¢¤ê¤Þ¤»¤ó"
+
+#
+msgid "E690: Missing \"in\" after :for"
+msgstr "E690: :for ¤Î¸å¤Ë \"in\" ¤¬¤¢¤ê¤Þ¤»¤ó"
+
+#, c-format
+msgid "E107: Missing parentheses: %s"
+msgstr "E107: ¥«¥Ã¥³ '(' ¤¬¤¢¤ê¤Þ¤»¤ó: %s"
+
+#, c-format
+msgid "E108: No such variable: \"%s\""
+msgstr "E108: ¤½¤ÎÊÑ¿ô¤Ï¤¢¤ê¤Þ¤»¤ó: \"%s\""
+
+msgid "E743: variable nested too deep for (un)lock"
+msgstr "E743: (¥¢¥ó)¥í¥Ã¥¯¤¹¤ë¤Ë¤ÏÊÑ¿ô¤ÎÆþ¤ì»Ò¤¬¿¼²á¤®¤Þ¤¹"
+
+msgid "E109: Missing ':' after '?'"
+msgstr "E109: '?' ¤Î¸å¤Ë ':' ¤¬¤¢¤ê¤Þ¤»¤ó"
+
+msgid "E691: Can only compare List with List"
+msgstr "E691: ¥ê¥¹¥È·¿¤Ï¥ê¥¹¥È·¿¤È¤·¤«Èæ³Ó¤Ç¤­¤Þ¤»¤ó"
+
+msgid "E692: Invalid operation for Lists"
+msgstr "E692: ¥ê¥¹¥È·¿¤Ë¤Ï̵¸ú¤ÊÁàºî¤Ç¤¹"
+
+msgid "E735: Can only compare Dictionary with Dictionary"
+msgstr "E735: ¼­½ñ·¿¤Ï¼­½ñ·¿¤È¤·¤«Èæ³Ó¤Ç¤­¤Þ¤»¤ó"
+
+msgid "E736: Invalid operation for Dictionary"
+msgstr "E736: ¼­½ñ·¿¤Ë¤Ï̵¸ú¤ÊÁàºî¤Ç¤¹"
+
+msgid "E693: Can only compare Funcref with Funcref"
+msgstr "E693: ´Ø¿ô»²¾È·¿¤Ï´Ø¿ô»²¾È·¿¤È¤·¤«Èæ³Ó¤Ç¤­¤Þ¤»¤ó"
+
+msgid "E694: Invalid operation for Funcrefs"
+msgstr "E694: ´Ø¿ô»²¾È·¿¤Ë¤Ï̵¸ú¤ÊÁàºî¤Ç¤¹"
+
+msgid "E804: Cannot use '%' with Float"
+msgstr "E804: '%' ¤òÉâÆ°¾®¿ôÅÀ¿ô¤ÈÁȤ߹ç¤ï¤»¤Æ¤Ï»È¤¨¤Þ¤»¤ó"
+
+msgid "E110: Missing ')'"
+msgstr "E110: ')' ¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó"
+
+msgid "E695: Cannot index a Funcref"
+msgstr "E695: ´Ø¿ô»²¾È·¿¤Ï¥¤¥ó¥Ç¥Ã¥¯¥¹¤Ç¤­¤Þ¤»¤ó"
+
+#, 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"
+
+#, c-format
+msgid "E696: Missing comma in List: %s"
+msgstr "E696: ¥ê¥¹¥È·¿¤Ë¥«¥ó¥Þ¤¬¤¢¤ê¤Þ¤»¤ó: %s"
+
+#, c-format
+msgid "E697: Missing end of List ']': %s"
+msgstr "E697: ¥ê¥¹¥È·¿¤ÎºÇ¸å¤Ë ']' ¤¬¤¢¤ê¤Þ¤»¤ó: %s"
+
+#, 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 "E724: variable nested too deep for displaying"
+msgstr "E724: ɽ¼¨¤¹¤ë¤Ë¤ÏÊÑ¿ô¤ÎÆþ¤ì»Ò¤¬¿¼²á¤®¤Þ¤¹"
+
+#, 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"
+
+#, c-format
+msgid "E117: Unknown function: %s"
+msgstr "E117: ̤ÃΤδؿô¤Ç¤¹: %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 "E808: Number or Float required"
+msgstr "E808: ¿ôÃͤ«ÉâÆ°¾®¿ôÅÀ¿ô¤¬É¬ÍפǤ¹"
+
+msgid "add() argument"
+msgstr "add() ¤Î°ú¿ô"
+
+msgid "E699: Too many arguments"
+msgstr "E699: °ú¿ô¤¬Â¿²á¤®¤Þ¤¹"
+
+msgid "E785: complete() can only be used in Insert mode"
+msgstr "E785: complete() ¤ÏÁÞÆþ¥â¡¼¥É¤Ç¤·¤«ÍøÍѤǤ­¤Þ¤»¤ó"
+
+#.
+#. * 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"
+
+#, c-format
+msgid "E737: Key already exists: %s"
+msgstr "E737: ¥­¡¼¤Ï´û¤Ë¸ºß¤·¤Þ¤¹: %s"
+
+msgid "extend() argument"
+msgstr "extend() ¤Î°ú¿ô"
+
+msgid "map() argument"
+msgstr "map() ¤Î°ú¿ô"
+
+msgid "filter() argument"
+msgstr "filter() ¤Î°ú¿ô"
+
+#, c-format
+msgid "+-%s%3ld lines: "
+msgstr "+-%s%3ld ¹Ô: "
+
+#, c-format
+msgid "E700: Unknown function: %s"
+msgstr "E700: ̤ÃΤδؿô¤Ç¤¹: %s"
+
+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 "E701: Invalid type for len()"
+msgstr "E701: len() ¤Ë¤Ï̵¸ú¤Ê·¿¤Ç¤¹"
+
+msgid "E726: Stride is zero"
+msgstr "E726: ¥¹¥È¥é¥¤¥É(Á°¿ÊÎÌ)¤¬ 0 ¤Ç¤¹"
+
+msgid "E727: Start past end"
+msgstr "E727: ³«»Ï°ÌÃÖ¤¬½ªÎ»°ÌÃÖ¤ò±Û¤¨¤Þ¤·¤¿"
+
+msgid "<empty>"
+msgstr "<¶õ>"
+
+msgid "E240: No connection to Vim server"
+msgstr "E240: Vim ¥µ¡¼¥Ð¤Ø¤ÎÀܳ¤¬¤¢¤ê¤Þ¤»¤ó"
+
+#, c-format
+msgid "E241: Unable to send to %s"
+msgstr "E241: %s ¤ØÁ÷¤ë¤³¤È¤¬¤Ç¤­¤Þ¤»¤ó"
+
+msgid "E277: Unable to read a server reply"
+msgstr "E277: ¥µ¡¼¥Ð¤Î±þÅú¤¬¤¢¤ê¤Þ¤»¤ó"
+
+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: ¥¯¥é¥¤¥¢¥ó¥È¤ØÁ÷¤ë¤³¤È¤¬¤Ç¤­¤Þ¤»¤ó"
+
+msgid "sort() argument"
+msgstr "sort() ¤Î°ú¿ô"
+
+msgid "E702: Sort compare function failed"
+msgstr "E702: ¥½¡¼¥È¤ÎÈæ³Ó´Ø¿ô¤¬¼ºÇÔ¤·¤Þ¤·¤¿"
+
+msgid "(Invalid)"
+msgstr "(̵¸ú)"
+
+msgid "E677: Error writing temp file"
+msgstr "E677: °ì»þ¥Õ¥¡¥¤¥ë½ñ¹þÃæ¤Ë¥¨¥é¡¼¤¬È¯À¸¤·¤Þ¤·¤¿"
+
+msgid "E805: Using a Float as a Number"
+msgstr "E805: ÉâÆ°¾®¿ôÅÀ¿ô¤ò¿ôÃͤȤ·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹"
+
+msgid "E703: Using a Funcref as a Number"
+msgstr "E703: ´Ø¿ô»²¾È·¿¤ò¿ôÃͤȤ·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹¡£"
+
+msgid "E745: Using a List as a Number"
+msgstr "E745: ¥ê¥¹¥È·¿¤ò¿ôÃͤȤ·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹"
+
+msgid "E728: Using a Dictionary as a Number"
+msgstr "E728: ¼­½ñ·¿¤ò¿ôÃͤȤ·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹"
+
+msgid "E729: using Funcref as a String"
+msgstr "E729: ´Ø¿ô»²¾È·¿¤òʸ»úÎó¤È¤·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹"
+
+msgid "E730: using List as a String"
+msgstr "E730: ¥ê¥¹¥È·¿¤òʸ»úÎó¤È¤·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹"
+
+msgid "E731: using Dictionary as a String"
+msgstr "E731: ¼­½ñ·¿¤òʸ»úÎó¤È¤·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹"
+
+#, c-format
+msgid "E706: Variable type mismatch for: %s"
+msgstr "E706: ÊÑ¿ô¤Î·¿¤¬°ìÃפ·¤Þ¤»¤ó: %s"
+
+#, 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: ´Ø¿ô»²¾È·¿ÊÑ¿ô̾¤ÏÂçʸ»ú¤Ç»Ï¤Þ¤é¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó: %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: ¥³¥Ô¡¼¤ò¼è¤ë¤Ë¤ÏÊÑ¿ô¤ÎÆþ¤ì»Ò¤¬¿¼²á¤®¤Þ¤¹"
+
+#, 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 "E125: Illegal argument: %s"
+msgstr "E125: ÉÔÀµ¤Ê°ú¿ô¤Ç¤¹: %s"
+
+#, c-format
+msgid "E853: Duplicate argument name: %s"
+msgstr "E853: °ú¿ô̾¤¬½ÅÊ£¤·¤Æ¤¤¤Þ¤¹: %s"
+
+msgid "E126: Missing :endfunction"
+msgstr "E126: :endfunction ¤¬¤¢¤ê¤Þ¤»¤ó"
+
+#, 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"
+
+msgid "E129: Function name required"
+msgstr "E129: ´Ø¿ô̾¤¬Í׵ᤵ¤ì¤Þ¤¹"
+
+#, c-format
+msgid "E128: Function name must start with a capital or contain a colon: %s"
+msgstr "E128: ´Ø¿ô̾¤ÏÂçʸ»ú¤Ç»Ï¤Þ¤ë¤«¥³¥í¥ó¤ò´Þ¤Þ¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó: %s"
+
+#, c-format
+msgid "E131: Cannot delete function %s: It is in use"
+msgstr "E131: ´Ø¿ô %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 ¤òÊÖ¤·¤Þ¤·¤¿"
+
+#, c-format
+msgid "continuing in %s"
+msgstr "%s ¤Î¼Â¹Ô¤ò·ÑÂ³Ãæ¤Ç¤¹"
+
+msgid "E133: :return not inside a function"
+msgstr "E133: ´Ø¿ô³°¤Ë :return ¤¬¤¢¤ê¤Þ¤·¤¿"
+
+msgid ""
+"\n"
+"# global variables:\n"
+msgstr ""
+"\n"
+"# ¥°¥í¡¼¥Ð¥ëÊÑ¿ô:\n"
+
+msgid ""
+"\n"
+"\tLast set from "
+msgstr ""
+"\n"
+"\tLast set from "
+
+msgid "No old files"
+msgstr "¸Å¤¤¥Õ¥¡¥¤¥ë¤Ï¤¢¤ê¤Þ¤»¤ó"
+
+#, c-format
+msgid "<%s>%s%s %d, Hex %02x, Octal %03o"
+msgstr "<%s>%s%s %d, 16¿Ê¿ô %02x, 8¿Ê¿ô %03o"
+
+#, c-format
+msgid "> %d, Hex %04x, Octal %o"
+msgstr "> %d, 16¿Ê¿ô %04x, 8¿Ê¿ô %o"
+
+#, c-format
+msgid "> %d, Hex %08x, Octal %o"
+msgstr "> %d, 16¿Ê¿ô %08x, 8¿Ê¿ô %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: *¥Õ¥£¥ë¥¿* autocommand¤Ï¸½ºß¤Î¥Ð¥Ã¥Õ¥¡¤òÊѹ¹¤·¤Æ¤Ï¤¤¤±¤Þ¤»¤ó"
+
+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 " ¼ºÇÔ"
+
+#. avoid a wait_return for this message, it's annoying
+#, c-format
+msgid "E137: Viminfo file is not writable: %s"
+msgstr "E137: viminfo¥Õ¥¡¥¤¥ë¤¬½ñ¹þ¤ß¤Ç¤­¤Þ¤»¤ó: %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\" ¤ò½ñ¹þ¤ßÃæ"
+
+#. Write the info:
+#, 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 "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 "¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë \"%s\" ¤¬Â¸ºß¤·¤Þ¤¹. ¾å½ñ¤­¤ò¶¯À©¤·¤Þ¤¹¤«?"
+
+#, c-format
+msgid "E768: Swap file exists: %s (:silent! overrides)"
+msgstr "E768: ¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤¬Â¸ºß¤·¤Þ¤¹: %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 ""
+"\"%s\" ¤Ë¤Ï 'readonly' ¥ª¥×¥·¥ç¥ó¤¬ÀßÄꤵ¤ì¤Æ¤¤¤Þ¤¹.\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: autocommand¤¬Í½´ü¤»¤º¿·¤·¤¤¥Ð¥Ã¥Õ¥¡ %s ¤òºï½ü¤·¤Þ¤·¤¿"
+
+msgid "E144: non-numeric argument to :z"
+msgstr "E144: ¿ô¤Ç¤Ï¤Ê¤¤°ú¿ô¤¬ :z ¤ËÅϤµ¤ì¤Þ¤·¤¿"
+
+msgid "E145: Shell commands not allowed in rvim"
+msgstr "E145: 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"
+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 "E150: Not a directory: %s"
+msgstr "E150: ¥Ç¥£¥ì¥¯¥È¥ê¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó: %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 ¤ò³«¤±¤Þ¤»¤ó"
+
+# Added at 29-Apr-2004.
+#, c-format
+msgid "E670: Mix of help file encodings within a language: %s"
+msgstr "E670: 1¤Ä¤Î¸À¸ì¤Î¥Ø¥ë¥×¥Õ¥¡¥¤¥ë¤ËÊ£¿ô¤Î¥¨¥ó¥³¡¼¥É¤¬º®ºß¤·¤Æ¤¤¤Þ¤¹: %s"
+
+#, c-format
+msgid "E154: Duplicate tag \"%s\" in file %s/%s"
+msgstr "E154: ¥¿¥° \"%s\" ¤¬¥Õ¥¡¥¤¥ë %s/%s ¤Ë½ÅÊ£¤·¤Æ¤¤¤Þ¤¹"
+
+#, c-format
+msgid "E160: Unknown sign command: %s"
+msgstr "E160: ̤ÃΤÎsign¥³¥Þ¥ó¥É¤Ç¤¹: %s"
+
+msgid "E156: Missing sign name"
+msgstr "E156: sign̾¤¬¤¢¤ê¤Þ¤»¤ó"
+
+msgid "E612: Too many signs defined"
+msgstr "E612: sign¤ÎÄêµÁ¤¬Â¿¿ô¸«¤Ä¤«¤ê¤Þ¤·¤¿"
+
+#, c-format
+msgid "E239: Invalid sign text: %s"
+msgstr "E239: ̵¸ú¤Êsign¤Î¥Æ¥­¥¹¥È¤Ç¤¹: %s"
+
+#, c-format
+msgid "E155: Unknown sign: %s"
+msgstr "E155: ̤ÃΤÎsign¤Ç¤¹: %s"
+
+msgid "E159: Missing sign number"
+msgstr "E159: sign¤ÎÈֹ椬¤¢¤ê¤Þ¤»¤ó"
+
+#, c-format
+msgid "E158: Invalid buffer name: %s"
+msgstr "E158: ̵¸ú¤Ê¥Ð¥Ã¥Õ¥¡Ì¾¤Ç¤¹: %s"
+
+#, c-format
+msgid "E157: Invalid sign ID: %ld"
+msgstr "E157: ̵¸ú¤Êsign¼±Ê̻ҤǤ¹: %ld"
+
+# Added at 27-Jan-2004.
+msgid " (NOT FOUND)"
+msgstr " (¸«¤Ä¤«¤ê¤Þ¤»¤ó)"
+
+msgid " (not supported)"
+msgstr " (È󥵥ݡ¼¥È)"
+
+msgid "[Deleted]"
+msgstr "[ºï½üºÑ]"
+
+msgid "Entering Debug mode. Type \"cont\" to continue."
+msgstr "¥Ç¥Ð¥Ã¥°¥â¡¼¥É¤ËÆþ¤ê¤Þ¤¹. ³¤±¤ë¤Ë¤Ï \"cont\" ¤ÈÆþÎϤ·¤Æ¤¯¤À¤µ¤¤."
+
+#, c-format
+msgid "line %ld: %s"
+msgstr "¹Ô %ld: %s"
+
+#, c-format
+msgid "cmd: %s"
+msgstr "¥³¥Þ¥ó¥É: %s"
+
+#, 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"
+
+msgid "E750: First use \":profile start {fname}\""
+msgstr "E750: ½é¤á¤Ë \":profile start {fname}\" ¤ò¼Â¹Ô¤·¤Æ¤¯¤À¤µ¤¤"
+
+#, c-format
+msgid "Save changes to \"%s\"?"
+msgstr "Êѹ¹¤ò \"%s\" ¤ËÊݸ¤·¤Þ¤¹¤«?"
+
+msgid "Untitled"
+msgstr "̵Âê"
+
+#, c-format
+msgid "E162: No write since last change for buffer \"%s\""
+msgstr "E162: ¥Ð¥Ã¥Õ¥¡ \"%s\" ¤ÎÊѹ¹¤ÏÊݸ¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
+
+msgid "Warning: Entered other buffer unexpectedly (check autocommands)"
+msgstr "·Ù¹ð: ͽ´ü¤»¤ºÂ¾¥Ð¥Ã¥Õ¥¡¤Ø°Üư¤·¤Þ¤·¤¿ (autocommands ¤òÄ´¤Ù¤Æ¤¯¤À¤µ¤¤)"
+
+msgid "E163: There is only one file to edit"
+msgstr "E163: ÊÔ½¸¤¹¤ë¥Õ¥¡¥¤¥ë¤Ï1¤Ä¤·¤«¤¢¤ê¤Þ¤»¤ó"
+
+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 'runtimepath': \"%s\""
+msgstr "'runtimepath' ¤ÎÃæ¤Ë¤Ï¸«¤Ä¤«¤ê¤Þ¤»¤ó: \"%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 ¤Î¼è¹þ¤ò´°Î»"
+
+msgid "modeline"
+msgstr "¥â¡¼¥É¹Ô"
+
+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 "E319: Sorry, the command is not available in this version"
+msgstr "E319: ¤³¤Î¥Ð¡¼¥¸¥ç¥ó¤Ç¤Ï¤³¤Î¥³¥Þ¥ó¥É¤ÏÍøÍѤǤ­¤Þ¤»¤ó, ¤´¤á¤ó¤Ê¤µ¤¤"
+
+msgid "E172: Only one file name allowed"
+msgstr "E172: ¥Õ¥¡¥¤¥ë̾¤Ï 1 ¤Ä¤Ë¤·¤Æ¤¯¤À¤µ¤¤"
+
+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 Range 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: ¥«¥¦¥ó¥È¤ò2½Å»ØÄꤹ¤ë¤³¤È¤Ï¤Ç¤­¤Þ¤»¤ó"
+
+msgid "E178: Invalid default value for count"
+msgstr "E178: ¥«¥¦¥ó¥È¤Î¾ÊάÃͤ¬Ìµ¸ú¤Ç¤¹"
+
+msgid "E179: argument required for -complete"
+msgstr "E179: -Êä´°¤Î¤¿¤á¤Î°ú¿ô¤¬É¬ÍפǤ¹"
+
+#, 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 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 »È¤¤¤µ¤ó¡¢¤ä¤¢!"
+
+msgid "E784: Cannot close last tab page"
+msgstr "E784: ºÇ¸å¤Î¥¿¥Ö¥Ú¡¼¥¸¤òÊĤ¸¤ë¤³¤È¤Ï¤Ç¤­¤Þ¤»¤ó"
+
+msgid "Already only one tab page"
+msgstr "´û¤Ë¥¿¥Ö¥Ú¡¼¥¸¤Ï1¤Ä¤·¤«¤¢¤ê¤Þ¤»¤ó"
+
+msgid "Edit File in new window"
+msgstr "¿·¤·¤¤¥¦¥£¥ó¥É¥¦¤Ç¥Õ¥¡¥¤¥ë¤òÊÔ½¸¤·¤Þ¤¹"
+
+#, c-format
+msgid "Tab page %d"
+msgstr "¥¿¥Ö¥Ú¡¼¥¸ %d"
+
+msgid "No swap file"
+msgstr "¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤¬¤¢¤ê¤Þ¤»¤ó"
+
+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 ¤Ë¤Ï2¤Ä¤Î¿ôÃͤΰú¿ô¤¬É¬ÍפǤ¹"
+
+#, 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 ¤Ë¤Ï2¤Ä¤Î¿ôÃͤΰú¿ô¤¬É¬ÍפǤ¹"
+
+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\" ¤ò½ñ¹þ¤ßÍѤȤ·¤Æ³«¤±¤Þ¤»¤ó"
+
+#. set mark
+msgid "E191: Argument must be a letter or forward/backward quote"
+msgstr "E191: °ú¿ô¤Ï1ʸ»ú¤Î±Ñ»ú¤«°úÍÑÉä (' ¤« `) ¤Ç¤Ê¤±¤ì¤Ð¤¤¤±¤Þ¤»¤ó"
+
+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>\"¤òÃÖ¤­´¹¤¨¤ëautocommand¤Î¥Õ¥¡¥¤¥ë̾¤¬¤¢¤ê¤Þ¤»¤ó"
+
+msgid "E496: no autocommand buffer number to substitute for \"<abuf>\""
+msgstr "E496: \"<abuf>\"¤òÃÖ¤­´¹¤¨¤ëautocommand¥Ð¥Ã¥Õ¥¡Èֹ椬¤¢¤ê¤Þ¤»¤ó"
+
+msgid "E497: no autocommand match name to substitute for \"<amatch>\""
+msgstr "E497: \"<amatch>\"¤òÃÖ¤­´¹¤¨¤ëautocommand¤Î³ºÅö̾¤¬¤¢¤ê¤Þ¤»¤ó"
+
+msgid "E498: no :source file name to substitute for \"<sfile>\""
+msgstr "E498: \"<sfile>\"¤òÃÖ¤­´¹¤¨¤ë :source Âоݥե¡¥¤¥ë̾¤¬¤¢¤ê¤Þ¤»¤ó"
+
+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: '%' ¤ä '#' ¤¬ÌµÌ¾¥Õ¥¡¥¤¥ë¤Ê¤Î¤Ç \":p:h\" ¤òȼ¤ï¤Ê¤¤»È¤¤Êý¤Ï¤Ç¤­¤Þ¤»¤ó"
+
+msgid "E500: Evaluates to an empty string"
+msgstr "E500: ¶õʸ»úÎó¤È¤·¤ÆÉ¾²Á¤µ¤ì¤Þ¤·¤¿"
+
+msgid "E195: Cannot open viminfo file for reading"
+msgstr "E195: viminfo¥Õ¥¡¥¤¥ë¤òÆÉ¹þÍѤȤ·¤Æ³«¤±¤Þ¤»¤ó"
+
+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
+#, 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"
+
+#. always scroll up, don't overwrite
+#, 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 "¥¨¥é¡¼"
+
+#. if (pending & CSTP_INTERRUPT)
+msgid "Interrupt"
+msgstr "³ä¹þ¤ß"
+
+msgid "E579: :if nesting too deep"
+msgstr "E579: :if ¤ÎÆþ¤ì»Ò¤¬¿¼²á¤®¤Þ¤¹"
+
+msgid "E580: :endif without :if"
+msgstr "E580: :if ¤Î¤Ê¤¤ :endif ¤¬¤¢¤ê¤Þ¤¹"
+
+msgid "E581: :else without :if"
+msgstr "E581: :if ¤Î¤Ê¤¤ :else ¤¬¤¢¤ê¤Þ¤¹"
+
+msgid "E582: :elseif without :if"
+msgstr "E582: :if ¤Î¤Ê¤¤ :elseif ¤¬¤¢¤ê¤Þ¤¹"
+
+msgid "E583: multiple :else"
+msgstr "E583: Ê£¿ô¤Î :else ¤¬¤¢¤ê¤Þ¤¹"
+
+msgid "E584: :elseif after :else"
+msgstr "E584: :else ¤Î¸å¤Ë :elseif ¤¬¤¢¤ê¤Þ¤¹"
+
+msgid "E585: :while/:for nesting too deep"
+msgstr "E585: :while ¤ä :for ¤ÎÆþ¤ì»Ò¤¬¿¼²á¤®¤Þ¤¹"
+
+msgid "E586: :continue without :while or :for"
+msgstr "E586: :while ¤ä :for ¤Î¤Ê¤¤ :continue ¤¬¤¢¤ê¤Þ¤¹"
+
+msgid "E587: :break without :while or :for"
+msgstr "E587: :while ¤ä :for ¤Î¤Ê¤¤ :break ¤¬¤¢¤ê¤Þ¤¹"
+
+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: :try ¤Î¤Ê¤¤ :catch ¤¬¤¢¤ê¤Þ¤¹"
+
+#. Give up for a ":catch" after ":finally" and ignore it.
+#. * Just parse.
+msgid "E604: :catch after :finally"
+msgstr "E604: :finally ¤Î¸å¤Ë :catch ¤¬¤¢¤ê¤Þ¤¹"
+
+msgid "E606: :finally without :try"
+msgstr "E606: :try ¤Î¤Ê¤¤ :finally ¤¬¤¢¤ê¤Þ¤¹"
+
+#. Give up for a multiple ":finally" and ignore it.
+msgid "E607: multiple :finally"
+msgstr "E607: Ê£¿ô¤Î :finally ¤¬¤¢¤ê¤Þ¤¹"
+
+msgid "E602: :endtry without :try"
+msgstr "E602: :try ¤Î¤Ê¤¤ :endtry ¤Ç¤¹"
+
+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 "E198: cmd_pchar beyond the command length"
+msgstr "E198: cmd_pchar ¤¬¥³¥Þ¥ó¥ÉŤòͤ¨¤Þ¤·¤¿"
+
+msgid "E199: Active window or buffer deleted"
+msgstr "E199: ¥¢¥¯¥Æ¥£¥Ö¤Ê¥¦¥£¥ó¥É¥¦¤«¥Ð¥Ã¥Õ¥¡¤¬ºï½ü¤µ¤ì¤Þ¤·¤¿"
+
+msgid "E812: Autocommands changed buffer or buffer name"
+msgstr "E812: autocommand¤¬¥Ð¥Ã¥Õ¥¡¤«¥Ð¥Ã¥Õ¥¡Ì¾¤òÊѹ¹¤·¤Þ¤·¤¿"
+
+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 autocommand ¤¬¥Õ¥¡¥¤¥ë¤òÆÉ¹þÉԲĤˤ·¤Þ¤·¤¿"
+
+msgid "E201: *ReadPre autocommands must not change current buffer"
+msgstr "E201: *ReadPre autocommand ¤Ï¸½ºß¤Î¥Ð¥Ã¥Õ¥¡¤òÊѤ¨¤é¤ì¤Þ¤»¤ó"
+
+msgid "Vim: Reading from stdin...\n"
+msgstr "Vim: ɸ½àÆþÎϤ«¤éÆÉ¹þÃæ...\n"
+
+msgid "Reading from stdin..."
+msgstr "ɸ½àÆþÎϤ«¤éÆÉ¹þ¤ßÃæ..."
+
+#. Re-opening the original file failed!
+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 "[ÊÑ´¹ºÑ]"
+
+msgid "[blowfish]"
+msgstr "[blowfish°Å¹æ²½]"
+
+msgid "[crypted]"
+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 "E821: File is encrypted with unknown method"
+msgstr "E821: ¥Õ¥¡¥¤¥ë¤¬Ì¤ÃΤÎÊýË¡¤Ç°Å¹æ²½¤µ¤ì¤Æ¤¤¤Þ¤¹"
+
+msgid "E676: No matching autocommands for acwrite buffer"
+msgstr "E676: acwrite¥Ð¥Ã¥Õ¥¡¤Î³ºÅö¤¹¤ëautocommand¤Ï¸ºß¤·¤Þ¤»¤ó"
+
+msgid "E203: Autocommands deleted or unloaded buffer to be written"
+msgstr "E203: Êݸ¤¹¤ë¥Ð¥Ã¥Õ¥¡¤òautocommand¤¬ºï½ü¤«²òÊü¤·¤Þ¤·¤¿"
+
+msgid "E204: Autocommand changed number of lines in unexpected way"
+msgstr "E204: autocommand¤¬Í½´ü¤»¤ÌÊýË¡¤Ç¹Ô¿ô¤òÊѹ¹¤·¤Þ¤·¤¿"
+
+# 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 "¤Ï¥Õ¥¡¥¤¥ë¤Ç¤â½ñ¹þ¤ß²Äǽ¥Ç¥Ð¥¤¥¹¤Ç¤â¤¢¤ê¤Þ¤»¤ó"
+
+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 "E460: The resource fork would be lost (add ! to override)"
+msgstr "E460: ¥ê¥½¡¼¥¹¥Õ¥©¡¼¥¯¤¬¼º¤ï¤ì¤ë¤«¤â¤·¤ì¤Þ¤»¤ó (! ¤òÄɲäǶ¯À©)"
+
+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 "E667: Fsync failed"
+msgstr "E667: fsync ¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
+
+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 " [a]"
+
+msgid " appended"
+msgstr " ÄɲÃ"
+
+msgid " [w]"
+msgstr " [w]"
+
+msgid " written"
+msgstr " ½ñ¹þ¤ß"
+
+msgid "E205: Patchmode: can't save original file"
+msgstr "E205: patchmode: ¸¶ËÜ¥Õ¥¡¥¤¥ë¤òÊݸ¤Ç¤­¤Þ¤»¤ó"
+
+msgid "E206: patchmode: can't touch empty original file"
+msgstr "E206: patchmode: ¶õ¤Î¸¶ËÜ¥Õ¥¡¥¤¥ë¤òtouch¤Ç¤­¤Þ¤»¤ó"
+
+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 ʸ»ú"
+
+#. Explicit typecast avoids warning on Mac OS X 10.6
+#, c-format
+msgid "%ld characters"
+msgstr "%ld ʸ»ú"
+
+msgid "[noeol]"
+msgstr "[noeol]"
+
+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
+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: autocommand ¤Î 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"
+"¥Õ¥¡¥¤¥ëÆÉ¹þ(&L)"
+
+#, 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 "autocommand: %s <¥Ð¥Ã¥Õ¥¡=%d> ¤¬¼«Æ°Åª¤Ëºï½ü¤µ¤ì¤Þ¤¹"
+
+#. the group doesn't exist
+#, c-format
+msgid "E367: No such group: \"%s\""
+msgstr "E367: ¤½¤Î¥°¥ë¡¼¥×¤Ï¤¢¤ê¤Þ¤»¤ó: \"%s\""
+
+#, 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"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Auto-Commands ---"
+msgstr ""
+"\n"
+"--- Auto-Commands ---"
+
+#, c-format
+msgid "E680: <buffer=%d>: invalid buffer number "
+msgstr "E680: <¥Ð¥Ã¥Õ¥¡=%d>: ̵¸ú¤Ê¥Ð¥Ã¥Õ¥¡ÈÖ¹æ¤Ç¤¹ "
+
+msgid "E217: Can't execute autocommands for ALL events"
+msgstr "E217: Á´¤Æ¤Î¥¤¥Ù¥ó¥È¤ËÂФ·¤Æ¤Îautocommand¤Ï¼Â¹Ô¤Ç¤­¤Þ¤»¤ó"
+
+msgid "No matching autocommands"
+msgstr "³ºÅö¤¹¤ëautocommand¤Ï¸ºß¤·¤Þ¤»¤ó"
+
+msgid "E218: autocommand nesting too deep"
+msgstr "E218: autocommand¤ÎÆþ¤ì»Ò¤¬¿¼²á¤®¤Þ¤¹"
+
+#, c-format
+msgid "%s Auto commands for \"%s\""
+msgstr "%s Auto commands for \"%s\""
+
+#, c-format
+msgid "Executing %s"
+msgstr "%s ¤ò¼Â¹Ô¤·¤Æ¤¤¤Þ¤¹"
+
+#, c-format
+msgid "autocommand %s"
+msgstr "autocommand %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 lines folded "
+msgstr "+--%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 "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 ""
+"&Yes\n"
+"&No\n"
+"&Cancel"
+msgstr ""
+"¤Ï¤¤(&Y)\n"
+"¤¤¤¤¤¨(&N)\n"
+"¥­¥ã¥ó¥»¥ë(&C)"
+
+msgid "Input _Methods"
+msgstr "¥¤¥ó¥×¥Ã¥È¥á¥½¥Ã¥É"
+
+msgid "VIM - Search and Replace..."
+msgstr "VIM - ¸¡º÷¤ÈÃÖ´¹..."
+
+msgid "VIM - Search..."
+msgstr "VIM - ¸¡º÷..."
+
+msgid "Find what:"
+msgstr "¸¡º÷ʸ»úÎó:"
+
+msgid "Replace with:"
+msgstr "ÃÖ´¹Ê¸»úÎó:"
+
+#. whole word only button
+msgid "Match whole word only"
+msgstr "Àµ³Î¤Ë³ºÅö¤¹¤ë¤â¤Î¤À¤±"
+
+#. match case button
+msgid "Match case"
+msgstr "Âçʸ»ú/¾®Ê¸»ú¤ò¶èÊ̤¹¤ë"
+
+msgid "Direction"
+msgstr "Êý¸þ"
+
+#. 'Up' and 'Down' buttons
+msgid "Up"
+msgstr "¾å"
+
+msgid "Down"
+msgstr "²¼"
+
+#. 'Find Next' button
+msgid "Find Next"
+msgstr "¼¡¤ò¸¡º÷"
+
+#. 'Replace' button
+msgid "Replace"
+msgstr "ÃÖ´¹"
+
+#. 'Replace All' button
+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)"
+
+#, 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 "Close tab"
+msgstr "¥¿¥Ö¥Ú¡¼¥¸¤òÊĤ¸¤ë"
+
+msgid "Open tab..."
+msgstr "¥¿¥Ö¥Ú¡¼¥¸¤ò³«¤¯"
+
+msgid "Find string (use '\\\\' to find a '\\')"
+msgstr "¸¡º÷ʸ»úÎó ('\\' ¤ò¸¡º÷¤¹¤ë¤Ë¤Ï '\\\\')"
+
+msgid "Find & Replace (use '\\\\' to find a '\\')"
+msgstr "¸¡º÷¡¦ÃÖ´¹ ('\\' ¤ò¸¡º÷¤¹¤ë¤Ë¤Ï '\\\\')"
+
+#. 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 "»È¤ï¤ì¤Þ¤»¤ó"
+
+msgid "Directory\t*.nothing\n"
+msgstr "¥Ç¥£¥ì¥¯¥È¥ê\t*.nothing\n"
+
+msgid "Vim E458: Cannot allocate colormap entry, some colors may be incorrect"
+msgstr "Vim E458: ¿§»ØÄ꤬Àµ¤·¤¯¤Ê¤¤¤Î¤Ç¥¨¥ó¥È¥ê¤ò³ä¤êÅö¤Æ¤é¤ì¤Þ¤»¤ó"
+
+#, 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¤Î2ÇܤǤϤ¢¤ê¤Þ¤»¤ó"
+
+#, 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 "µÑ²¼¤¹¤ë(&D)"
+
+msgid "no specific match"
+msgstr "¥Þ¥Ã¥Á¤¹¤ë¤â¤Î¤¬¤¢¤ê¤Þ¤»¤ó"
+
+msgid "Vim - Font Selector"
+msgstr "Vim - ¥Õ¥©¥ó¥ÈÁªÂò"
+
+msgid "Name:"
+msgstr "̾Á°:"
+
+#. create toggle button
+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 "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¤Î¥ê¥½¡¼¥¹¥Õ¥¡¥¤¥ë \"%s\" ¤òÆÉ¹þ¤á¤Þ¤»¤ó"
+
+#, c-format
+msgid "E618: file \"%s\" is not a PostScript resource file"
+msgstr "E618: ¥Õ¥¡¥¤¥ë \"%s\" ¤Ï PostScript ¥ê¥½¡¼¥¹¥Õ¥¡¥¤¥ë¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó"
+
+#, c-format
+msgid "E619: file \"%s\" is not a supported PostScript resource file"
+msgstr "E619: ¥Õ¥¡¥¤¥ë \"%s\" ¤ÏÂбþ¤·¤Æ¤¤¤Ê¤¤ PostScript ¥ê¥½¡¼¥¹¥Õ¥¡¥¤¥ë¤Ç¤¹"
+
+#, c-format
+msgid "E621: \"%s\" resource file has wrong version"
+msgstr "E621: ¥ê¥½¡¼¥¹¥Õ¥¡¥¤¥ë \"%s\" ¤Ï¥Ð¡¼¥¸¥ç¥ó¤¬°Û¤Ê¤ê¤Þ¤¹"
+
+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¤Î¥ê¥½¡¼¥¹¥Õ¥¡¥¤¥ë \"prolog.ps\" ¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó"
+
+msgid "E456: Can't find PostScript resource file \"cidfont.ps\""
+msgstr "E456: PostScript¤Î¥ê¥½¡¼¥¹¥Õ¥¡¥¤¥ë \"cidfont.ps\" ¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó"
+
+#, c-format
+msgid "E456: Can't find PostScript resource file \"%s.ps\""
+msgstr "E456: PostScript¤Î¥ê¥½¡¼¥¹¥Õ¥¡¥¤¥ë \"%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¤Îµ¯Æ°½àÈ÷(fork)¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
+
+msgid "cs_create_connection setpgid failed"
+msgstr "cs_create_connection ¤Ø¤Î setpgid ¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
+
+msgid "cs_create_connection exec failed"
+msgstr "cs_create_connection ¤Î¼Â¹Ô¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
+
+msgid "cs_create_connection: fdopen for to_fp failed"
+msgstr "cs_create_connection: to_fp ¤Î fdopen ¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
+
+msgid "cs_create_connection: fdopen for fr_fp failed"
+msgstr "cs_create_connection: fr_fp ¤Î fdopen ¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
+
+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 of %s ¤Ë³ºÅö¤¬¤¢¤ê¤Þ¤»¤ó¤Ç¤·¤¿"
+
+msgid "cscope commands:\n"
+msgstr "cscope¥³¥Þ¥ó¥É:\n"
+
+#, c-format
+msgid "%-5s: %s%*s (Usage: %s)"
+msgstr "%-5s: %s%*s (»ÈÍÑË¡: %s)"
+
+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"
+
+#, 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¥Ç¡¼¥¿¥Ù¡¼¥¹¤ÏÄɲ䵤ì¤Þ¤»¤ó¤Ç¤·¤¿"
+
+#, c-format
+msgid "E261: cscope connection %s not found"
+msgstr "E261: cscopeÀܳ %s ¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó¤Ç¤·¤¿"
+
+#, c-format
+msgid "cscope connection %s closed"
+msgstr "cscopeÀܳ %s ¤¬ÊĤ¸¤é¤ì¤Þ¤·¤¿"
+
+#. should not reach here
+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 ¥Ç¡¼¥¿¥Ù¡¼¥¹Ì¾ prepend ¥Ñ¥¹\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 "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¥é¥¤¥Ö¥é¥ê¤ò¥í¡¼¥É¤Ç¤­¤Þ¤»¤ó"
+"¤Ç¤·¤¿."
+
+# 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 "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 "Àܳ¡×¤Ç¤¹"
+
+#, c-format
+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 "¥Þ¡¼¥¯¤ÏÀßÄꤵ¤ì¤Æ¤¤¤Þ¤»¤ó"
+
+#, 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 ""
+"¥³¡¼¥ë¥Ð¥Ã¥¯¥³¥Þ¥ó¥É¤òÅÐÏ¿¤Ç¤­¤Þ¤»¤ó: ¥Ð¥Ã¥Õ¥¡/¥¦¥£¥ó¥É¥¦¤¬´û¤Ë¾Ãµî¤µ¤ì¤Þ¤·¤¿"
+
+#. This should never happen. Famous last word?
+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 ¼ÂÂΤÎÅÐÏ¿¥×¥í¥Ñ¥Æ¥£¤¬ÉÔÀµ¤Ç¤¹. ¾Ãµî¤·¤Þ¤·¤¿!"
+
+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 "̵¸ú¤Ê°ú¿ô¤Ç¤¹: "
+
+#, 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 "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 "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: ¥¨¥é¡¼: NetBeans¤«¤égvim¤ò¥¹¥¿¡¼¥È¤Ç¤­¤Þ¤»¤ó\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"
+
+#. just in case..
+msgid "pre-vimrc command line"
+msgstr "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 "- ɸ½àÆþÎϤ«¤é¥Æ¥­¥¹¥È¤òÆÉ¹þ¤à"
+
+msgid "-t tag edit file where tag is defined"
+msgstr "-t ¥¿¥° ¥¿¥°¤¬ÄêµÁ¤µ¤ì¤¿¤È¤³¤í¤«¤éÊÔ½¸¤¹¤ë"
+
+msgid "-q [errorfile] edit file with first error"
+msgstr "-q [errorfile] ºÇ½é¤Î¥¨¥é¡¼¤ÇÊÔ½¸¤¹¤ë"
+
+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\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\" ¤ÈƱ¤¸)"
+
+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¥µ¥¤¥ì¥ó¥È(¥Ð¥Ã¥Á)¥â¡¼¥É (\"ex\" ÀìÍÑ)"
+
+msgid "-d\t\t\tDiff mode (like \"vimdiff\")"
+msgstr "-d\t\t\tº¹Ê¬¥â¡¼¥É (\"vidiff\" ¤ÈƱ¤¸)"
+
+msgid "-y\t\t\tEasy mode (like \"evim\", modeless)"
+msgstr "-y\t\t\t¥¤¡¼¥¸¡¼¥â¡¼¥É (\"evim\" ¤ÈƱ¤¸, ¥â¡¼¥É̵)"
+
+msgid "-R\t\t\tReadonly mode (like \"view\")"
+msgstr "-R\t\t\tÆÉ¹þÀìÍѥ⡼¥É (\"view\" ¤ÈƱ¤¸)"
+
+msgid "-Z\t\t\tRestricted mode (like \"rvim\")"
+msgstr "-Z\t\t\tÀ©¸Â¥â¡¼¥É (\"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\tVi¸ß´¹¥â¡¼¥É: 'compatible'"
+
+msgid "-N\t\t\tNot fully Vi compatible: 'nocompatible'"
+msgstr "-N\t\t\tViÈó¸ß´¹¥â¡¼¥É: '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\t¥Ç¥Ð¥Ã¥°¥â¡¼¥É"
+
+msgid "-n\t\t\tNo swap file, use memory only"
+msgstr "-n\t\t\t¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤ò»ÈÍѤ»¤º¥á¥â¥ê¤À¤±"
+
+msgid "-r\t\t\tList swap files and exit"
+msgstr "-r\t\t\t¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤òÎóµó¤·½ªÎ»"
+
+msgid "-r (with file name)\tRecover crashed session"
+msgstr "-r (¥Õ¥¡¥¤¥ë̾)\t¥¯¥é¥Ã¥·¥å¤·¤¿¥»¥Ã¥·¥ç¥ó¤òÉüµ¢"
+
+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¥¦¥£¥ó¥É¥¦¤ò³«¤¯¤Î¤Ë 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¥¢¥é¥Ó¥¢¸ì¥â¡¼¥É¤Çµ¯Æ°¤¹¤ë"
+
+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 <terminal>\tüËö¤ò <terminal> ¤ËÀßÄꤹ¤ë"
+
+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\tN ¸Ä¥¿¥Ö¥Ú¡¼¥¸¤ò³«¤¯(¾ÊάÃÍ: ¥Õ¥¡¥¤¥ë¤Ë¤Ä¤­1¸Ä)"
+
+msgid "-o[N]\t\tOpen N windows (default: one for each file)"
+msgstr "-o[N]\t\tN ¸Ä¥¦¥£¥ó¥É¥¦¤ò³«¤¯(¾ÊάÃÍ: ¥Õ¥¡¥¤¥ë¤Ë¤Ä¤­1¸Ä)"
+
+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 "+<lnum>\t\t<lnum> ¹Ô¤«¤é¤Ï¤¸¤á¤ë"
+
+msgid "--cmd <command>\tExecute <command> before loading any vimrc file"
+msgstr "--cmd <command>\tvimrc¤ò¥í¡¼¥É¤¹¤ëÁ°¤Ë <command> ¤ò¼Â¹Ô¤¹¤ë"
+
+msgid "-c <command>\t\tExecute <command> after loading the first file"
+msgstr "-c <command>\t\tºÇ½é¤Î¥Õ¥¡¥¤¥ë¤ò¥í¡¼¥É¸å <command> ¤ò¼Â¹Ô¤¹¤ë"
+
+msgid "-S <session>\t\tSource file <session> after loading the first file"
+msgstr "-S <session>\t\tºÇ½é¤Î¥Õ¥¡¥¤¥ë¤ò¥í¡¼¥É¸å¥Õ¥¡¥¤¥ë <session> ¤ò¼è¹þ¤à"
+
+msgid "-s <scriptin>\tRead Normal mode commands from file <scriptin>"
+msgstr "-s <scriptin>\t¥Õ¥¡¥¤¥ë <scriptin> ¤«¤é¥Î¡¼¥Þ¥ë¥³¥Þ¥ó¥É¤òÆÉ¹þ¤à"
+
+msgid "-w <scriptout>\tAppend all typed commands to file <scriptout>"
+msgstr "-w <scriptout>\tÆþÎϤ·¤¿Á´¥³¥Þ¥ó¥É¤ò¥Õ¥¡¥¤¥ë <scriptout> ¤ËÄɲ乤ë"
+
+msgid "-W <scriptout>\tWrite all typed commands to file <scriptout>"
+msgstr "-W <scriptout>\tÆþÎϤ·¤¿Á´¥³¥Þ¥ó¥É¤ò¥Õ¥¡¥¤¥ë <scriptout> ¤ËÊݸ¤¹¤ë"
+
+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> ¤Ø½ÐÎϤ¹¤ë"
+
+msgid "-i <viminfo>\t\tUse <viminfo> instead of .viminfo"
+msgstr "-i <viminfo>\t\t.viminfo¤ÎÂå¤ï¤ê¤Ë <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 <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 "¥Ç¥£¥¹¥×¥ì¥¤¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó"
+
+#. Failed to send, abort.
+msgid ": Send failed.\n"
+msgstr ": Á÷¿®¤Ë¼ºÇÔ¤·¤Þ¤·¤¿.\n"
+
+#. Let vim start normally.
+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\" ¤Ë³ºÅö¤¹¤ë¥Þ¡¼¥¯¤¬¤¢¤ê¤Þ¤»¤ó"
+
+#. Highlight title
+msgid ""
+"\n"
+"mark line col file/text"
+msgstr ""
+"\n"
+"mark ¹Ô Îó ¥Õ¥¡¥¤¥ë/¥Æ¥­¥¹¥È"
+
+#. Highlight title
+msgid ""
+"\n"
+" jump line col file/text"
+msgstr ""
+"\n"
+" jump ¹Ô Îó ¥Õ¥¡¥¤¥ë/¥Æ¥­¥¹¥È"
+
+#. Highlight title
+msgid ""
+"\n"
+"change line col text"
+msgstr ""
+"\n"
+"Êѹ¹ ¹Ô Îó ¥Æ¥­¥¹¥È"
+
+msgid ""
+"\n"
+"# File marks:\n"
+msgstr ""
+"\n"
+"# ¥Õ¥¡¥¤¥ë¥Þ¡¼¥¯:\n"
+
+#. Write the jumplist with -'
+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: ¥¤¥ó¥×¥Ã¥È¥á¥½¥Ã¥É¤Ï my preedit type ¤ò¥µ¥Ý¡¼¥È¤·¤Þ¤»¤ó"
+
+msgid "E293: block was not locked"
+msgstr "E293: ¥Ö¥í¥Ã¥¯¤¬¥í¥Ã¥¯¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
+
+msgid "E294: Seek error in swap file read"
+msgstr "E294: ¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ëÆÉ¹þ»þ¤Ë¥·¡¼¥¯¥¨¥é¡¼¤Ç¤¹"
+
+msgid "E295: Read error in swap file"
+msgstr "E295: ¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤ÎÆÉ¹þ¤ß¥¨¥é¡¼¤Ç¤¹"
+
+msgid "E296: Seek error in swap file write"
+msgstr "E296: ¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë½ñ¹þ¤ß»þ¤Ë¥·¡¼¥¯¥¨¥é¡¼¤Ç¤¹"
+
+msgid "E297: Write error in swap file"
+msgstr "E297: ¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤Î½ñ¹þ¤ß¥¨¥é¡¼¤Ç¤¹"
+
+msgid "E300: Swap file already exists (symlink attack?)"
+msgstr "E300: ¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤¬´û¤Ë¸ºß¤·¤Þ¤¹ (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: ¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤Î°Å¹æ¤ò¹¹¿·Ãæ¤Ë¥¨¥é¡¼¤¬È¯À¸¤·¤Þ¤·¤¿"
+
+#. could not (re)open the swap file, what can we do????
+msgid "E301: Oops, lost the swap file!!!"
+msgstr "E301: ¤ª¤Ã¤È, ¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤¬¼º¤ï¤ì¤Þ¤·¤¿!!!"
+
+msgid "E302: Could not rename swap file"
+msgstr "E302: ¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤Î̾Á°¤òÊѤ¨¤é¤ì¤Þ¤»¤ó"
+
+#, c-format
+msgid "E303: Unable to open swap file for \"%s\", recovery impossible"
+msgstr "E303: \"%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 ¤Ë¤Ï¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó"
+
+msgid "Enter number of swap file to use (0 to quit): "
+msgstr "»ÈÍѤ¹¤ë¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤ÎÈÖ¹æ¤òÆþÎϤ·¤Æ¤¯¤À¤µ¤¤(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¤¬¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤ò¹¹¿·¤·¤Æ¤¤¤Þ¤»¤ó."
+
+msgid " cannot be used with this version of Vim.\n"
+msgstr " Vim¤Î¤³¤Î¥Ð¡¼¥¸¥ç¥ó¤Ç¤Ï»ÈÍѤǤ­¤Þ¤»¤ó.\n"
+
+msgid "Use Vim version 3.0.\n"
+msgstr "Vim¤Î¥Ð¡¼¥¸¥ç¥ó3.0¤ò»ÈÍѤ·¤Æ¤¯¤À¤µ¤¤.\n"
+
+#, c-format
+msgid "E307: %s does not look like a Vim swap file"
+msgstr "E307: %s ¤ÏVim¤Î¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤Ç¤Ï¤Ê¤¤¤è¤¦¤Ç¤¹"
+
+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 "¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë \"%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 "¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤Ï°Å¹æ²½¤µ¤ì¤Æ¤¤¤Þ¤¹: \"%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 ¤òÆÉ¹þ¤á¤Þ¤»¤ó"
+
+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: ¥Ö¥í¥Ã¥¯ 1 ¤ÎID¤¬´Ö°ã¤Ã¤Æ¤¤¤Þ¤¹(%s ¤¬.swp¥Õ¥¡¥¤¥ë¤Ç¤Ê¤¤?)"
+
+msgid "???BLOCK MISSING"
+msgstr "???¥Ö¥í¥Ã¥¯¤¬¤¢¤ê¤Þ¤»¤ó"
+
+msgid "??? from here until ???END lines may be messed up"
+msgstr "??? ¤³¤³¤«¤é ???END ¤Þ¤Ç¤Î¹Ô¤¬Ç˲õ¤µ¤ì¤Æ¤¤¤ë¤è¤¦¤Ç¤¹"
+
+msgid "??? from here until ???END lines may have been inserted/deleted"
+msgstr "??? ¤³¤³¤«¤é ???END ¤Þ¤Ç¤Î¹Ô¤¬ÁÞÆþ¤«ºï½ü¤µ¤ì¤¿¤è¤¦¤Ç¤¹"
+
+msgid "???END"
+msgstr "???END"
+
+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 "¥ê¥«¥Ð¥ê¤¬½ªÎ»¤·¤Þ¤·¤¿. Á´¤Æ¤¬Àµ¤·¤¤¤«¥Á¥§¥Ã¥¯¤·¤Æ¤¯¤À¤µ¤¤."
+
+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 "¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤«¤é¼èÆÀ¤·¤¿°Å¹æ¥­¡¼¤ò¥Æ¥­¥¹¥È¥Õ¥¡¥¤¥ë¤Ë»È¤¤¤Þ¤¹.\n"
+
+#. use msg() to start the scrolling properly
+msgid "Swap files found:"
+msgstr "¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤¬Ê£¿ô¸«¤Ä¤«¤ê¤Þ¤·¤¿:"
+
+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 " [from Vim version 3.0]"
+
+msgid " [does not look like a Vim swap file]"
+msgstr " [Vim¤Î¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤Ç¤Ï¤Ê¤¤¤è¤¦¤Ç¤¹]"
+
+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"
+" ¥×¥í¥»¥¹ID: "
+
+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: ¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤¬Ìµ¤¤¤Î¤Ç°Ý»ý¤Ç¤­¤Þ¤»¤ó"
+
+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: ¥Ý¥¤¥ó¥¿¥Ö¥í¥Ã¥¯¤ÎID¤¬´Ö°ã¤Ã¤Æ¤¤¤Þ¤¹ 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: ¥Ý¥¤¥ó¥¿¥Ö¥í¥Ã¥¯¤ÎID¤¬´Ö°ã¤Ã¤Æ¤¤¤Þ¤¹ 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: ¥Ý¥¤¥ó¥¿¥Ö¥í¥Ã¥¯¤ÎID¤¬´Ö°ã¤Ã¤Æ¤¤¤Þ¤¹"
+
+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: ¥Ý¥¤¥ó¥¿¥Ö¥í¥Ã¥¯¤ÎID¤¬´Ö°ã¤Ã¤Æ¤¤¤Þ¤¹ 2"
+
+#, c-format
+msgid "E773: Symlink loop for \"%s\""
+msgstr "E773: \"%s\" ¤Î¥·¥ó¥Ü¥ê¥Ã¥¯¥ê¥ó¥¯¤¬¥ë¡¼¥×¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹"
+
+msgid "E325: ATTENTION"
+msgstr "E325: Ãí°Õ"
+
+msgid ""
+"\n"
+"Found a swap file by the name \""
+msgstr ""
+"\n"
+"¼¡¤Î̾Á°¤Ç¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤ò¸«¤Ä¤±¤Þ¤·¤¿ \""
+
+msgid "While opening file \""
+msgstr "¼¡¤Î¥Õ¥¡¥¤¥ë¤ò³«¤¤¤Æ¤¤¤ëºÇÃæ \""
+
+msgid " NEWER than swap file!\n"
+msgstr " ¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤è¤ê¤â¿·¤·¤¤¤Ç¤¹!\n"
+
+#. 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."
+msgstr ""
+"\n"
+"(1) ÊÌ¤Î¥×¥í¥°¥é¥à¤¬Æ±¤¸¥Õ¥¡¥¤¥ë¤òÊÔ½¸¤·¤Æ¤¤¤ë¤«¤â¤·¤ì¤Þ¤»¤ó.\n"
+" ¤³¤Î¾ì¹ç¤Ë¤Ï, Êѹ¹¤ò¤·¤¿ºÝ¤ËºÇ½ªÅª¤Ë, Ʊ¤¸¥Õ¥¡¥¤¥ë¤Î°Û¤Ê¤ë\n"
+" 2¤Ä¤Î¥¤¥ó¥¹¥¿¥ó¥¹¤¬¤Ç¤­¤Æ¤·¤Þ¤¦¤³¤È¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤."
+
+msgid " Quit, or continue with caution.\n"
+msgstr " ½ªÎ»¤¹¤ë¤«, Ãí°Õ¤·¤Ê¤¬¤é³¤±¤Æ¤¯¤À¤µ¤¤.\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 " ´û¤Ë¤³¤ì¤ò¹Ô¤Ê¤Ã¤¿¤Î¤Ê¤é¤Ð, ¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë \""
+
+msgid ""
+"\"\n"
+" to avoid this message.\n"
+msgstr ""
+"\"\n"
+" ¤ò¾Ã¤»¤Ð¤³¤Î¥á¥Ã¥»¡¼¥¸¤ò²óÈò¤Ç¤­¤Þ¤¹.\n"
+
+msgid "Swap file \""
+msgstr "¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë \""
+
+msgid "\" already exists!"
+msgstr "\" ¤¬´û¤Ë¤¢¤ê¤Þ¤¹!"
+
+msgid "VIM - ATTENTION"
+msgstr "VIM - Ãí°Õ"
+
+msgid "Swap file already exists!"
+msgstr "¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤¬´û¤Ë¸ºß¤·¤Þ¤¹!"
+
+msgid ""
+"&Open Read-Only\n"
+"&Edit anyway\n"
+"&Recover\n"
+"&Quit\n"
+"&Abort"
+msgstr ""
+"ÆÉ¹þÀìÍѤdz«¤¯(&O)\n"
+"¤È¤Ë¤«¤¯ÊÔ½¸¤¹¤ë(&E)\n"
+"Éü³è¤µ¤»¤ë(&R)\n"
+"½ªÎ»¤¹¤ë(&Q)\n"
+"Ãæ»ß¤¹¤ë(&A)"
+
+msgid ""
+"&Open Read-Only\n"
+"&Edit anyway\n"
+"&Recover\n"
+"&Delete it\n"
+"&Quit\n"
+"&Abort"
+msgstr ""
+"ÆÉ¹þÀìÍѤdz«¤¯(&O)\n"
+"¤È¤Ë¤«¤¯ÊÔ½¸¤¹¤ë(&E)\n"
+"Éü³è¤µ¤»¤ë(&R)\n"
+"ºï½ü¤¹¤ë(&D)\n"
+"½ªÎ»¤¹¤ë(&Q)\n"
+"Ãæ»ß¤¹¤ë(&A)"
+
+msgid "E326: Too many swap files found"
+msgstr "E326: ¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤¬Â¿¿ô¸«¤Ä¤«¤ê¤Þ¤·¤¿"
+
+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\" ¤È¤¤¤¦¥á¥Ë¥å¡¼¤Ï¤¢¤ê¤Þ¤»¤ó"
+
+#. Only a mnemonic or accelerator is not valid.
+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: ¶èÀÚ¤ê¤Ï¥á¥Ë¥å¡¼¥Ñ¥¹¤Î°ìÉô¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó"
+
+#. Now we have found the matching menu, and we list the mappings
+#. Highlight title
+msgid ""
+"\n"
+"--- Menus ---"
+msgstr ""
+"\n"
+"--- ¥á¥Ë¥å¡¼ ---"
+
+msgid "Tear off this menu"
+msgstr "¤³¤Î¥á¥Ë¥å¡¼¤òÀÚ¤ê¼è¤ë"
+
+msgid "E333: Menu path must lead to a menu item"
+msgstr "E333: ¥á¥Ë¥å¡¼¥Ñ¥¹¤Ï¥á¥Ë¥å¡¼¥¢¥¤¥Æ¥à¤òÀ¸¤¸¤Ê¤±¤ì¤Ð¤¤¤±¤Þ¤»¤ó"
+
+#, c-format
+msgid "E334: Menu not found: %s"
+msgstr "E334: ¥á¥Ë¥å¡¼¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó: %s"
+
+#, c-format
+msgid "E335: Menu not defined for %s mode"
+msgstr "E335: %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 "ÆüËܸì¥á¥Ã¥»¡¼¥¸ËÝÌõ/´Æ½¤: ¼²¬ ÂÀϺ <koron.kaoriya@gmail.com>"
+
+msgid "Interrupt: "
+msgstr "³ä¹þ¤ß: "
+
+msgid "Press ENTER or type command to continue"
+msgstr "³¤±¤ë¤Ë¤ÏENTER¤ò²¡¤¹¤«¥³¥Þ¥ó¥É¤òÆþÎϤ·¤Æ¤¯¤À¤µ¤¤"
+
+#, 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 " SPACE/d/j: ²èÌÌ/¥Ú¡¼¥¸/¹Ô ²¼, b/u/k: ¾å, q: ½ªÎ» "
+
+msgid "Question"
+msgstr "¼ÁÌä"
+
+msgid ""
+"&Yes\n"
+"&No"
+msgstr ""
+"¤Ï¤¤(&Y)\n"
+"¤¤¤¤¤¨(&N)"
+
+msgid ""
+"&Yes\n"
+"&No\n"
+"Save &All\n"
+"&Discard All\n"
+"&Cancel"
+msgstr ""
+"¤Ï¤¤(&Y)\n"
+"¤¤¤¤¤¨(&N)\n"
+"Á´¤ÆÊݸ(&A)\n"
+"Á´¤ÆÊü´þ(&D)\n"
+"¥­¥ã¥ó¥»¥ë(&C)"
+
+msgid "Select Directory dialog"
+msgstr "¥Ç¥£¥ì¥¯¥È¥êÁªÂò¥À¥¤¥¢¥í¥°"
+
+msgid "Save File dialog"
+msgstr "¥Õ¥¡¥¤¥ëÊݸ¥À¥¤¥¢¥í¥°"
+
+msgid "Open File dialog"
+msgstr "¥Õ¥¡¥¤¥ëÆÉ¹þ¥À¥¤¥¢¥í¥°"
+
+#. TODO: non-GUI file selector here
+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: 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 "Vim: preserving files...\n"
+msgstr "Vim: ¥Õ¥¡¥¤¥ë¤òÊÝÂ¸Ãæ...\n"
+
+#. close all memfiles, without deleting
+msgid "Vim: Finished.\n"
+msgstr "Vim: ½ªÎ»¤·¤Þ¤·¤¿.\n"
+
+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 "Enter encryption key: "
+msgstr "°Å¹æ²½ÍѤΥ­¡¼¤òÆþÎϤ·¤Æ¤¯¤À¤µ¤¤: "
+
+msgid "Enter same key again: "
+msgstr "¤â¤¦°ìÅÙÆ±¤¸¥­¡¼¤òÆþÎϤ·¤Æ¤¯¤À¤µ¤¤: "
+
+msgid "Keys don't match!"
+msgstr "¥­¡¼¤¬°ìÃפ·¤Þ¤»¤ó"
+
+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\" ¤È¤¤¤¦¥Õ¥¡¥¤¥ë¤¬¤¢¤ê¤Þ¤»¤ó"
+
+msgid "Cannot connect to Netbeans #2"
+msgstr "Netbeans #2 ¤ËÀܳ¤Ç¤­¤Þ¤»¤ó"
+
+msgid "Cannot connect to Netbeans"
+msgstr "Netbeans ¤ËÀܳ¤Ç¤­¤Þ¤»¤ó"
+
+#, c-format
+msgid "E668: Wrong access mode for NetBeans connection info file: \"%s\""
+msgstr ""
+"E668: NetBeans¤ÎÀܳ¾ðÊó¥Õ¥¡¥¤¥ë¤Î¥¢¥¯¥»¥¹¥â¡¼¥É¤ËÌäÂ꤬¤¢¤ê¤Þ¤¹: \"%s\""
+
+msgid "read from Netbeans socket"
+msgstr "Netbeans ¤Î¥½¥±¥Ã¥È¤òÆÉ¹þ¤ß"
+
+#, 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: ¥«¡¼¥½¥ë¤Î°ÌÃ֤ˤϼ±Ê̻Ҥ¬¤¢¤ê¤Þ¤»¤ó"
+
+msgid "E774: 'operatorfunc' is empty"
+msgstr "E774: 'operatorfunc' ¥ª¥×¥·¥ç¥ó¤¬¶õ¤Ç¤¹"
+
+msgid "E775: Eval feature not available"
+msgstr "E775: ¼°É¾²Áµ¡Ç½¤¬Ìµ¸ú¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹"
+
+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 :quit<Enter> to exit Vim"
+msgstr "Vim¤ò½ªÎ»¤¹¤ë¤Ë¤Ï :quit<Enter> ¤ÈÆþÎϤ·¤Æ¤¯¤À¤µ¤¤"
+
+#, 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: ¤Þ¤À¥ì¥¸¥¹¥¿¤ò»ÈÍѤ·¤Æ¤¤¤Þ¤»¤ó"
+
+#. must display the prompt
+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 ¹Ô¤ò²òÊüÃæ"
+
+msgid "block of 1 line yanked"
+msgstr "1 ¹Ô¤Î¥Ö¥í¥Ã¥¯¤¬¥ä¥ó¥¯¤µ¤ì¤Þ¤·¤¿"
+
+msgid "1 line yanked"
+msgstr "1 ¹Ô¤¬¥ä¥ó¥¯¤µ¤ì¤Þ¤·¤¿"
+
+#, c-format
+msgid "block of %ld lines yanked"
+msgstr "%ld ¹Ô¤Î¥Ö¥í¥Ã¥¯¤¬¥ä¥ó¥¯¤µ¤ì¤Þ¤·¤¿"
+
+#, c-format
+msgid "%ld lines yanked"
+msgstr "%ld ¹Ô¤¬¥ä¥ó¥¯¤µ¤ì¤Þ¤·¤¿"
+
+#, c-format
+msgid "E353: Nothing in register %s"
+msgstr "E353: ¥ì¥¸¥¹¥¿ %s ¤Ë¤Ï²¿¤â¤¢¤ê¤Þ¤»¤ó"
+
+#. Highlight title
+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 ¤Ç¤¹"
+
+#, c-format
+msgid "%ld Cols; "
+msgstr "%ld Îó; "
+
+#, c-format
+msgid "Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Bytes"
+msgstr "ÁªÂò %s%ld / %ld ¹Ô; %ld / %ld ñ¸ì; %ld / %ld ¥Ð¥¤¥È"
+
+#, c-format
+msgid ""
+"Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Chars; %ld of %ld "
+"Bytes"
+msgstr "ÁªÂò %s%ld / %ld ¹Ô; %ld / %ld ñ¸ì; %ld / %ld ʸ»ú; %ld / %ld ¥Ð¥¤¥È"
+
+#, c-format
+msgid "Col %s of %s; Line %ld of %ld; Word %ld of %ld; Byte %ld of %ld"
+msgstr "Îó %s / %s; ¹Ô %ld of %ld; ñ¸ì %ld / %ld; ¥Ð¥¤¥È %ld / %ld"
+
+#, c-format
+msgid ""
+"Col %s of %s; Line %ld of %ld; Word %ld of %ld; Char %ld of %ld; Byte %ld of "
+"%ld"
+msgstr ""
+"Îó %s / %s; ¹Ô %ld / %ld; ñ¸ì %ld / %ld; ʸ»ú %ld / %ld; ¥Ð¥¤¥È %ld of %ld"
+
+#, c-format
+msgid "(+%ld for BOM)"
+msgstr "(+%ld for BOM)"
+
+msgid "%<%f%h%m%=Page %N"
+msgstr "%<%f%h%m%=%N ¥Ú¡¼¥¸"
+
+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: modeline ¤Ç¤Ïµö²Ä¤µ¤ì¤Þ¤»¤ó"
+
+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>"
+
+msgid "E529: Cannot set 'term' to empty string"
+msgstr "E529: 'term' ¤Ë¤Ï¶õʸ»úÎó¤òÀßÄê¤Ç¤­¤Þ¤»¤ó"
+
+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' ¤¬Æ±¤¸¤Ç¤¹"
+
+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¤Ç¤ÏÊѹ¹¤Ç¤­¤Þ¤»¤ó"
+
+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: ¥Õ¥©¥ó¥È¥»¥Ã¥È¤òÁªÂò¤Ç¤­¤Þ¤»¤ó"
+
+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> ¤Î¸å¤ËÉÔÀµ¤Êʸ»ú¤¬¤¢¤ê¤Þ¤¹"
+
+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 "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' ¤·¤Æ¤¯¤À¤µ¤¤"
+
+#, 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"
+
+#. 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.
+#, 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"
+
+#. if Vim opened a window: Executing a shell may cause crashes
+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: ¥×¥ê¥ó¥¿¤ÎÁªÂò¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
+
+#, 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 "E245: Illegal char '%c' in font name \"%s\""
+msgstr "E245: '%c' ¤ÏÉÔÀµ¤Êʸ»ú¤Ç¤¹ (¥Õ¥©¥ó¥È̾ \"%s\")"
+
+msgid "Vim: Double signal, exiting\n"
+msgstr "Vim: 2½Å¤Î¥·¥°¥Ê¥ë¤Î¤¿¤á, ½ªÎ»¤·¤Þ¤¹\n"
+
+#, c-format
+msgid "Vim: Caught deadly signal %s\n"
+msgstr "Vim: Ã×̿Ū¥·¥°¥Ê¥ë %s ¤ò¸¡ÃΤ·¤Þ¤·¤¿\n"
+
+#, c-format
+msgid "Vim: Caught deadly signal\n"
+msgstr "Vim: Ã×̿Ū¥·¥°¥Ê¥ë¤ò¸¡ÃΤ·¤Þ¤·¤¿\n"
+
+#, c-format
+msgid "Opening the X display took %ld msec"
+msgstr "X¥µ¡¼¥Ð¤Ø¤ÎÀܳ¤Ë %ld ¥ß¥êÉ䫤«¤ê¤Þ¤·¤¿"
+
+msgid ""
+"\n"
+"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 ¤¬¥¿¥¤¥à¥¢¥¦¥È¤·¤Þ¤·¤¿"
+
+msgid ""
+"\n"
+"Could not get security context for "
+msgstr ""
+"\n"
+"¥»¥­¥å¥ê¥Æ¥£¥³¥ó¥Æ¥­¥¹¥È¤ò¼èÆÀ¤Ç¤­¤Þ¤»¤ó "
+
+msgid ""
+"\n"
+"Could not set security context for "
+msgstr ""
+"\n"
+"¥»¥­¥å¥ê¥Æ¥£¥³¥ó¥Æ¥­¥¹¥È¤òÀßÄê¤Ç¤­¤Þ¤»¤ó "
+
+msgid ""
+"\n"
+"Cannot execute shell "
+msgstr ""
+"\n"
+"¥·¥§¥ë¤ò¼Â¹Ô¤Ç¤­¤Þ¤»¤ó "
+
+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"
+"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 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 "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 "shell returned %d"
+msgstr "¥·¥§¥ë¤¬¥³¡¼¥É %d ¤Ç½ªÎ»¤·¤Þ¤·¤¿"
+
+#, 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 "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: Í×ÁǤ¬¤â¤¦¤¢¤ê¤Þ¤»¤ó"
+
+#, c-format
+msgid "(%d of %d)%s%s: "
+msgstr "(%d of %d)%s%s: "
+
+msgid " (line deleted)"
+msgstr " (¹Ô¤¬ºï½ü¤µ¤ì¤Þ¤·¤¿)"
+
+msgid "E380: At bottom of quickfix stack"
+msgstr "E380: quickfix ¥¹¥¿¥Ã¥¯¤ÎËöÈø¤Ç¤¹"
+
+msgid "E381: At top of quickfix stack"
+msgstr "E381: quickfix ¥¹¥¿¥Ã¥¯¤ÎÀèÆ¬¤Ç¤¹"
+
+#, c-format
+msgid "error list %d of %d; %d errors"
+msgstr "¥¨¥é¡¼°ìÍ÷ %d of %d; %d ¸Ä¥¨¥é¡¼"
+
+msgid "E382: Cannot write, 'buftype' option is set"
+msgstr "E382: 'buftype' ¥ª¥×¥·¥ç¥ó¤¬ÀßÄꤵ¤ì¤Æ¤¤¤ë¤Î¤Ç½ñ¹þ¤ß¤Þ¤»¤ó"
+
+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: ʸ»úÎ󤫥ꥹ¥È¤¬É¬ÍפǤ¹"
+
+#, c-format
+msgid "E369: invalid item in %s%%[]"
+msgstr "E369: ̵¸ú¤Ê¹àÌܤǤ¹: %s%%[]"
+
+#
+#, c-format
+msgid "E769: Missing ] after %s["
+msgstr "E769: %s[ ¤Î¸å¤Ë ] ¤¬¤¢¤ê¤Þ¤»¤ó"
+
+#, 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 et al. not allowed here"
+msgstr "E67: \\z1 ¤½¤Î¾¤Ï¥³¥³¤Ç¤Ïµö²Ä¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
+
+#
+#, c-format
+msgid "E69: Missing ] after %s%%["
+msgstr "E69: %s%%[ ¤Î¸å¤Ë ] ¤¬¤¢¤ê¤Þ¤»¤ó"
+
+#, c-format
+msgid "E70: Empty %s%%[]"
+msgstr "E70: %s%%[] ¤¬¶õ¤Ç¤¹"
+
+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{...} ¤¬Â¿²á¤®¤Þ¤¹"
+
+#, 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 ¤Î¸å¤Ë¤Ê¤Ë¤â¤¢¤ê¤Þ¤»¤ó"
+
+#
+msgid "E65: Illegal back reference"
+msgstr "E65: ÉÔÀµ¤Ê¸åÊý»²¾È¤Ç¤¹"
+
+#
+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"
+
+msgid ""
+"E864: \\%#= can only be followed by 0, 1, or 2. The automatic engine will be "
+"used "
+msgstr ""
+"E864: \\%#= ¤Ë¤Ï 0, 1 ¤â¤·¤¯¤Ï 2 ¤Î¤ß¤¬Â³¤±¤é¤ì¤Þ¤¹¡£"
+"Àµµ¬É½¸½¥¨¥ó¥¸¥ó¤Ï¼«Æ°ÁªÂò¤µ¤ì¤Þ¤¹¡£"
+
+#, c-format
+msgid "E866: (NFA regexp) Misplaced %c"
+msgstr "E866: (NFA Àµµ¬É½¸½) °ÌÃÖ¤¬¸í¤Ã¤Æ¤¤¤Þ¤¹: %c"
+
+msgid "E865: (NFA) Regexp end encountered prematurely"
+msgstr "E865: (NFA) ´üÂÔ¤è¤êÁ᤯Àµµ¬É½¸½¤Î½ªÃ¼¤ËÅþ㤷¤Þ¤·¤¿"
+
+#, c-format
+msgid "E867: (NFA) Unknown operator '\\z%c'"
+msgstr "E867: (NFA) ̤ÃΤΥª¥Ú¥ì¡¼¥¿¤Ç¤¹: '\\z%c'"
+
+#, c-format
+msgid "E867: (NFA) Unknown operator '\\%%%c'"
+msgstr "E867: (NFA) ̤ÃΤΥª¥Ú¥ì¡¼¥¿¤Ç¤¹: '\\%%%c'"
+
+#. should never happen
+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 Àµµ¬É½¸½) ·«¤êÊÖ¤·¤ÎÀ©¸Â²ó¿ô¤òÆÉ¹þÃæ¤Ë¥¨¥é¡¼"
+
+#. Can't have a multi follow a multi.
+msgid "E871: (NFA regexp) Can't have a multi follow a multi !"
+msgstr "E871: (NFA Àµµ¬É½¸½) ·«¤êÊÖ¤· ¤Î¸å¤Ë ·«¤êÊÖ¤· ¤Ï¤Ç¤­¤Þ¤»¤ó!"
+
+#. Too many `('
+msgid "E872: (NFA regexp) Too many '('"
+msgstr "E872: (NFA Àµµ¬É½¸½) '(' ¤¬Â¿²á¤®¤Þ¤¹"
+
+msgid "E879: (NFA regexp) Too many \\z("
+msgstr "E879: (NFA Àµµ¬É½¸½) \\z( ¤¬Â¿²á¤®¤Þ¤¹"
+
+msgid "E873: (NFA regexp) proper termination error"
+msgstr "E873: (NFA Àµµ¬É½¸½) ½ªÃ¼µ­¹æ¤¬¤¢¤ê¤Þ¤»¤ó"
+
+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 Àµµ¬É½¸½) (¸åÃÖʸ»úÎó¤òNFA¤ËÊÑ´¹Ãæ¤Ë) "
+"¥¹¥¿¥Ã¥¯¤Ë»Ä¤µ¤ì¤¿¥¹¥Æ¡¼¥È¤¬Â¿²á¤®¤Þ¤¹"
+
+msgid "E876: (NFA regexp) Not enough space to store the whole NFA "
+msgstr "E876: (NFA Àµµ¬É½¸½) 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 "NFAÀµµ¬É½¸½¥¨¥ó¥¸¥óÍÑ¤Î¥í¥°¥Õ¥¡¥¤¥ë¤ò½ñ¹þÍѤȤ·¤Æ³«¤±¤Þ¤»¤ó¡£"
+"¥í¥°¤Ïɸ½à½ÐÎϤ˽ÐÎϤ·¤Þ¤¹¡£"
+
+#, c-format
+msgid "(NFA) COULD NOT OPEN %s !"
+msgstr "(NFA) ¥í¥°¥Õ¥¡¥¤¥ë %s ¤ò³«¤±¤Þ¤»¤ó!"
+
+msgid "Could not open temporary log file for writing "
+msgstr "NFAÀµµ¬É½¸½¥¨¥ó¥¸¥óÍÑ¤Î¥í¥°¥Õ¥¡¥¤¥ë¤ò½ñ¹þÍѤȤ·¤Æ³«¤±¤Þ¤»¤ó¡£"
+
+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 " (lang)"
+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 " (Á°¤ËÎóµó¤·¤¿³ºÅö²Õ½ê¤ò´Þ¤à)"
+
+#. cursor at status line
+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 "Substitute "
+
+#, c-format
+msgid ""
+"\n"
+"# Last %sSearch Pattern:\n"
+"~"
+msgstr ""
+"\n"
+"# ºÇ¸å¤Î %s¸¡º÷¥Ñ¥¿¡¼¥ó:\n"
+"~"
+
+msgid "E759: Format error in spell file"
+msgstr "E759: ¥¹¥Ú¥ë¥Õ¥¡¥¤¥ë¤Î½ñ¼°¥¨¥é¡¼¤Ç¤¹"
+
+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 ¹ÔÌÜ) ¤Î affix ̾¤¬Ä¹²á¤®¤Þ¤¹: %s"
+
+msgid "E761: Format error in affix file FOL, LOW or UPP"
+msgstr ""
+"E761: affix¥Õ¥¡¥¤¥ë¤Î 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 "ñ¸ì¥Ä¥ê¡¼¤ò°µ½Ì¤·¤Æ¤¤¤Þ¤¹..."
+
+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\" ¤Ï¸«¤Ä¤«¤ê¤Þ¤»¤ó"
+
+#, 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 "Warning: region %s not supported"
+msgstr "·Ù¹ð9: %s ¤È¤¤¤¦ÈϰϤϥµ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
+
+#, c-format
+msgid "Reading affix file %s ..."
+msgstr "affix ¥Õ¥¡¥¤¥ë %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 "%s Æâ¤Î %d ¹ÔÌܤΠFLAG ¤Ë̵¸ú¤ÊÃͤ¬¤¢¤ê¤Þ¤¹: %s"
+
+#, c-format
+msgid "FLAG after using flags in %s line %d: %s"
+msgstr "%s Æâ¤Î %d ¹ÔÌܤ˥ե饰¤ÎÆó½Å»ÈÍѤ¬¤¢¤ê¤Þ¤¹: %s"
+
+#, c-format
+msgid ""
+"Defining COMPOUNDFORBIDFLAG after PFX item may give wrong results in %s line "
+"%d"
+msgstr ""
+"%s ¤Î %d ¹ÔÌܤΠPFX ¹àÌܤθå¤Î COMPOUNDFORBIDFLAG ¤ÎÄêµÁ¤Ï¸í¤Ã¤¿·ë²Ì¤òÀ¸¤¸¤ë"
+"¤³¤È¤¬¤¢¤ê¤Þ¤¹"
+
+#, c-format
+msgid ""
+"Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in %s line "
+"%d"
+msgstr ""
+"%s ¤Î %d ¹ÔÌܤΠPFX ¹àÌܤθå¤Î COMPOUNDPERMITFLAG ¤ÎÄêµÁ¤Ï¸í¤Ã¤¿·ë²Ì¤òÀ¸¤¸¤ë"
+"¤³¤È¤¬¤¢¤ê¤Þ¤¹"
+
+#, 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 "%s ¤Î %d ¹ÔÌܤΠCOMPOUNDWORDMAX ¤ÎÃͤ˸í¤ê¤¬¤¢¤ê¤Þ¤¹: %s"
+
+#, c-format
+msgid "Wrong COMPOUNDMIN value in %s line %d: %s"
+msgstr "%s ¤Î %d ¹ÔÌܤΠCOMPOUNDMIN ¤ÎÃͤ˸í¤ê¤¬¤¢¤ê¤Þ¤¹: %s"
+
+#, c-format
+msgid "Wrong COMPOUNDSYLMAX value in %s line %d: %s"
+msgstr "%s ¤Î %d ¹ÔÌܤΠCOMPOUNDSYLMAX ¤ÎÃͤ˸í¤ê¤¬¤¢¤ê¤Þ¤¹: %s"
+
+#, c-format
+msgid "Wrong CHECKCOMPOUNDPATTERN value in %s line %d: %s"
+msgstr "%s ¤Î %d ¹ÔÌܤΠCHECKCOMPOUNDPATTERN ¤ÎÃͤ˸í¤ê¤¬¤¢¤ê¤Þ¤¹: %s"
+
+#, c-format
+msgid "Different combining flag in continued affix block in %s line %d: %s"
+msgstr ""
+"%s ¤Î %d ¹ÔÌܤΠϢ³ affix ¥Ö¥í¥Ã¥¯¤Î¥Õ¥é¥°¤ÎÁȹ礻¤Ë°ã¤¤¤¬¤¢¤ê¤Þ¤¹: %s"
+
+#, c-format
+msgid "Duplicate affix in %s line %d: %s"
+msgstr "%s ¤Î %d ¹ÔÌÜ¤Ë ½ÅÊ£¤·¤¿ affix ¤ò¸¡½Ð¤·¤Þ¤·¤¿: %s"
+
+#, c-format
+msgid ""
+"Affix also used for BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST in %s "
+"line %d: %s"
+msgstr ""
+"%s ¤Î %d ¹ÔÌܤΠaffix ¤Ï BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST "
+"¤Ë»ÈÍѤ·¤Æ¤¯¤À¤µ¤¤: %s"
+
+#, c-format
+msgid "Expected Y or N in %s line %d: %s"
+msgstr "%s ¤Î %d ¹ÔÌÜ¤Ç¤Ï Y ¤« N ¤¬É¬ÍפǤ¹: %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 "%s ¤Î %d ¹ÔÌÜ¤Ë¤Ï REP(SAL) ¤Î²ó¿ô¤¬É¬ÍפǤ¹"
+
+#, c-format
+msgid "Expected MAP count in %s line %d"
+msgstr "%s ¤Î %d ¹ÔÌÜ¤Ë¤Ï MAP ¤Î²ó¿ô¤¬É¬ÍפǤ¹"
+
+#, c-format
+msgid "Duplicate character in MAP in %s line %d"
+msgstr "%s ¤Î %d ¹ÔÌܤΠMAP ¤Ë½ÅÊ£¤·¤¿Ê¸»ú¤¬¤¢¤ê¤Þ¤¹"
+
+#, 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 "%s ¹ÔÌÜ¤Ë FOL/LOW/UPP ¤¬¤¢¤ê¤Þ¤»¤ó"
+
+msgid "COMPOUNDSYLMAX used without SYLLABLE"
+msgstr "SYLLABLE ¤¬»ØÄꤵ¤ì¤Ê¤¤ COMPOUNDSYLMAX"
+
+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 %6d - %s"
+msgstr "¹Ô %6d, ñ¸ì %6d - %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 "ÈóASCIIʸ»ú¤ò´Þ¤à %d ¸Ä¤Îñ¸ì¤ò̵»ë¤·¤Þ¤·¤¿ (%s Æâ)"
+
+#, c-format
+msgid "Reading word file %s ..."
+msgstr "ɸ½àÆþÎϤ«¤éÆÉ¹þ¤ßÃæ %s ..."
+
+#, c-format
+msgid "Duplicate /encoding= line ignored in %s line %d: %s"
+msgstr "%s ¤Î %d ¹ÔÌܤΠ½ÅÊ£¤·¤¿ /encoding= ¹Ô¤ò̵»ë¤·¤Þ¤·¤¿: %s"
+
+#, c-format
+msgid "/encoding= line after word ignored in %s line %d: %s"
+msgstr "%s ¤Î %d ¹ÔÌܤΠñ¸ì¤Î¸å¤Î /encoding= ¹Ô¤ò̵»ë¤·¤Þ¤·¤¿: %s"
+
+#, c-format
+msgid "Duplicate /regions= line ignored in %s line %d: %s"
+msgstr "%s ¤Î %d ¹ÔÌܤΠ½ÅÊ£¤·¤¿ /regions= ¹Ô¤ò̵»ë¤·¤Þ¤·¤¿: %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 ¹ÔÌÜ Ìµ¸ú¤Ê nr Îΰè¤Ç¤¹: %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 "ÈóASCIIʸ»ú¤ò´Þ¤à %d ¸Ä¤Îñ¸ì¤ò̵»ë¤·¤Þ¤·¤¿"
+
+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 "¥¹¥Ú¥ë¥Õ¥¡¥¤¥ë¤òµÕÆÉ¹þÃæ"
+
+#.
+#. * Go through the trie of good words, soundfold each word and add it to
+#. * the soundfold trie.
+#.
+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: ½ÐÎÏ¥Õ¥¡¥¤¥ë̾¤Ë¤ÏÈϰÏ̾¤ò´Þ¤á¤é¤ì¤Þ¤»¤ó"
+
+msgid "E754: Only up to 8 regions supported"
+msgstr "E754: ÈÏ°Ï¤Ï 8 ¸Ä¤Þ¤Ç¤·¤«¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
+
+#, 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 removed from %s"
+msgstr "%s ¤«¤éñ¸ì¤¬ºï½ü¤µ¤ì¤Þ¤·¤¿"
+
+#, c-format
+msgid "Word added to %s"
+msgstr "%s ¤Ëñ¸ì¤¬Äɲ䵤ì¤Þ¤·¤¿"
+
+msgid "E763: Word characters differ between spell files"
+msgstr "E763: ñ¸ì¤Îʸ»ú¤¬¥¹¥Ú¥ë¥Õ¥¡¥¤¥ë¤È°Û¤Ê¤ê¤Þ¤¹"
+
+msgid "Sorry, no suggestions"
+msgstr "»Äǰ¤Ç¤¹¤¬, ½¤Àµ¸õÊä¤Ï¤¢¤ê¤Þ¤»¤ó"
+
+#, c-format
+msgid "Sorry, only %ld suggestions"
+msgstr "»Äǰ¤Ç¤¹¤¬, ½¤Àµ¸õÊä¤Ï %ld ¸Ä¤·¤«¤¢¤ê¤Þ¤»¤ó"
+
+#. for when 'cmdheight' > 1
+#. avoid more prompt
+#, 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"
+
+#, 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: ¤è¤ê¿·¤·¤¤¥Ð¡¼¥¸¥ç¥ó¤Î 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"
+
+#. This should have been checked when generating the .spl
+#. * file.
+msgid "E783: duplicate char in MAP entry"
+msgstr "E783: MAP ¥¨¥ó¥È¥ê¤Ë½Åʣʸ»ú¤¬Â¸ºß¤·¤Þ¤¹"
+
+msgid "No Syntax items defined for this buffer"
+msgstr "¤³¤Î¥Ð¥Ã¥Õ¥¡¤ËÄêµÁ¤µ¤ì¤¿¹½Ê¸Í×ÁǤϤ¢¤ê¤Þ¤»¤ó"
+
+#, c-format
+msgid "E390: Illegal argument: %s"
+msgstr "E390: ÉÔÀµ¤Ê°ú¿ô¤Ç¤¹: %s"
+
+#, 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 "minimal "
+
+msgid "maximal "
+msgstr "maximal "
+
+msgid "; match "
+msgstr "; ³ºÅö "
+
+msgid " line breaks"
+msgstr " ¸Ä¤Î²þ¹Ô"
+
+msgid "E395: contains argument not accepted here"
+msgstr "E395: ¤³¤Î¾ì½ê¤Ç¤Ï°ú¿ôcontains¤Ïµö²Ä¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
+
+msgid "E844: invalid cchar value"
+msgstr "E844: ̵¸ú¤Êcchar¤ÎÃͤǤ¹"
+
+msgid "E393: group[t]here not accepted here"
+msgstr "E393: ¤³¤³¤Ç¤Ï¥°¥ë¡¼¥×¤Ïµö²Ä¤µ¤ì¤Þ¤»¤ó"
+
+#, 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: ¹½Ê¸¤Î¼è¤ê¹þ¤ß(include)¤¬Â¿²á¤®¤Þ¤¹"
+
+#, c-format
+msgid "E789: Missing ']': %s"
+msgstr "E789: ']' ¤¬¤¢¤ê¤Þ¤»¤ó: %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: ¹½Ê¸Æ±´ü: Ϣ³¹Ô¥Ñ¥¿¡¼¥ó¤¬2ÅÙ»ØÄꤵ¤ì¤Þ¤·¤¿"
+
+#, 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 ¤ÏÆâÍÆ¥ê¥¹¥È¤ÎÀèÆ¬¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤"
+
+#, 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 ""
+" TOTAL COUNT MATCH SLOWEST AVERAGE NAME PATTERN"
+
+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: ¥°¥ë¡¼¥×¤¬ÀßÄꤵ¤ì¤Æ¤¤¤ë¤Î¤Ç¥Ï¥¤¥é¥¤¥È¥ê¥ó¥¯¤Ï̵»ë¤µ¤ì¤Þ¤¹"
+
+#, 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: ̤ÃΤÎÁ°·Ê¿§¤Ç¤¹"
+
+msgid "E420: BG color unknown"
+msgstr "E420: ̤ÃΤÎÇØ·Ê¿§¤Ç¤¹"
+
+#, 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 kind tag"
+
+msgid "file\n"
+msgstr "¥Õ¥¡¥¤¥ë\n"
+
+msgid "E427: There is only one matching tag"
+msgstr "E427: ³ºÅö¥¿¥°¤¬1¤Ä¤À¤±¤·¤«¤¢¤ê¤Þ¤»¤ó"
+
+msgid "E428: Cannot go beyond last matching tag"
+msgstr "E428: ºÇ¸å¤Ë³ºÅö¤¹¤ë¥¿¥°¤òͤ¨¤Æ¿Ê¤à¤³¤È¤Ï¤Ç¤­¤Þ¤»¤ó"
+
+#, c-format
+msgid "File \"%s\" does not exist"
+msgstr "¥Õ¥¡¥¤¥ë \"%s\" ¤¬¤¢¤ê¤Þ¤»¤ó"
+
+#. Give an indication of the number of matching tags
+#, c-format
+msgid "tag %d of %d%s"
+msgstr "¥¿¥° %d (Á´%d%s)"
+
+msgid " or more"
+msgstr " ¤«¤½¤ì°Ê¾å"
+
+msgid " Using tag with different case!"
+msgstr " ¥¿¥°¤ò°Û¤Ê¤ëcase¤Ç»ÈÍѤ·¤Þ¤¹!"
+
+#, c-format
+msgid "E429: File \"%s\" does not exist"
+msgstr "E429: ¥Õ¥¡¥¤¥ë \"%s\" ¤¬¤¢¤ê¤Þ¤»¤ó"
+
+#. Highlight title
+msgid ""
+"\n"
+" # TO tag FROM line in file/text"
+msgstr ""
+"\n"
+" # TO ¥¿¥° FROM ¹Ô in file/text"
+
+#, 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"
+
+#. never opened any tags file
+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: termcap¤Ë \"%s\" ¤Î¥¨¥ó¥È¥ê¤¬¤¢¤ê¤Þ¤»¤ó"
+
+msgid "E437: terminal capability \"cm\" required"
+msgstr "E437: üËö¤Ë \"cm\" µ¡Ç½¤¬É¬ÍפǤ¹"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Terminal keys ---"
+msgstr ""
+"\n"
+"--- üËö¥­¡¼ ---"
+
+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¤¬»ÈÍѤµ¤ì¤Þ¤·¤¿"
+
+#. This happens when the FileChangedRO autocommand changes the
+#. * file in a way it becomes shorter.
+msgid "E834: Line count changed unexpectedly"
+msgstr "E834: ͽ´ü¤»¤º¹Ô¥«¥¦¥ó¥È¤¬ÊѤï¤ê¤Þ¤·¤¿"
+
+#. must display the prompt
+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: undo ¤Îľ¸å¤Ë undojoin ¤Ï¤Ç¤­¤Þ¤»¤ó"
+
+msgid "E439: undo list corrupt"
+msgstr "E439: ¥¢¥ó¥É¥¥¥ê¥¹¥È¤¬²õ¤ì¤Æ¤¤¤Þ¤¹"
+
+msgid "E440: undo line missing"
+msgstr "E440: ¥¢¥ó¥É¥¥¹Ô¤¬¤¢¤ê¤Þ¤»¤ó"
+
+#. Only MS VC 4.1 and earlier can do Win32s
+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"
+"Included patches: "
+msgstr ""
+"\n"
+"ŬÍѺѥѥåÁ: "
+
+msgid ""
+"\n"
+"Extra patches: "
+msgstr ""
+"\n"
+"ÄɲóÈÄ¥¥Ñ¥Ã¥Á: "
+
+msgid "Modified by "
+msgstr "Modified by "
+
+msgid ""
+"\n"
+"Compiled "
+msgstr ""
+"\n"
+"Compiled "
+
+msgid "by "
+msgstr "by "
+
+msgid ""
+"\n"
+"Huge version "
+msgstr ""
+"\n"
+"Huge ÈÇ "
+
+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."
+
+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 (¥¯¥é¥·¥Ã¥¯) GUI."
+
+msgid " Features included (+) or not (-):\n"
+msgstr " µ¡Ç½¤Î°ìÍ÷ Í­¸ú(+)/̵¸ú(-)\n"
+
+msgid " system vimrc file: \""
+msgstr " ¥·¥¹¥Æ¥à 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 " 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 "¥Ç¥Ð¥Ã¥°¥Ó¥ë¥É"
+
+msgid "VIM - Vi IMproved"
+msgstr "VIM - Vi IMproved"
+
+msgid "version "
+msgstr "version "
+
+msgid "by Bram Moolenaar et al."
+msgstr "by Bram Moolenaar ¾."
+
+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> "
+
+msgid "type :help version7<Enter> for version info"
+msgstr "¥Ð¡¼¥¸¥ç¥ó¾ðÊó¤Ï :help version7<Enter> "
+
+msgid "Running in Vi compatible mode"
+msgstr "Vi¸ß´¹¥â¡¼¥É¤ÇưºîÃæ"
+
+msgid "type :set nocp<Enter> for Vim defaults"
+msgstr "Vim¿ä¾©Ãͤˤ¹¤ë¤Ë¤Ï :set nocp<Enter> "
+
+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 "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 "Already only one window"
+msgstr "´û¤Ë¥¦¥£¥ó¥É¥¦¤Ï1¤Ä¤·¤«¤¢¤ê¤Þ¤»¤ó"
+
+msgid "E441: There is no preview window"
+msgstr "E441: ¥×¥ì¥Ó¥å¡¼¥¦¥£¥ó¥É¥¦¤¬¤¢¤ê¤Þ¤»¤ó"
+
+msgid "E442: Can't split topleft and botright at the same time"
+msgstr "E442: º¸¾å¤È±¦²¼¤òƱ»þ¤Ëʬ³ä¤¹¤ë¤³¤È¤Ï¤Ç¤­¤Þ¤»¤ó"
+
+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: path¤Ë¤Ï \"%s\" ¤È¤¤¤¦¥Õ¥¡¥¤¥ë¤¬¤¢¤ê¤Þ¤»¤ó"
+
+msgid "Edit with &multiple Vims"
+msgstr "Ê£¿ô¤ÎVim¤ÇÊÔ½¸¤¹¤ë (&M)"
+
+msgid "Edit with single &Vim"
+msgstr "1¤Ä¤ÎVim¤ÇÊÔ½¸¤¹¤ë (&V)"
+
+msgid "Diff with Vim"
+msgstr "Vim¤Çº¹Ê¬¤òɽ¼¨¤¹¤ë"
+
+msgid "Edit with &Vim"
+msgstr "Vim¤ÇÊÔ½¸¤¹¤ë (&V)"
+
+#. Now concatenate
+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¤¬´Ä¶­ÊÑ¿ôPATH¾å¤Ë¤¢¤ë¤«³Îǧ¤·¤Æ¤¯¤À¤µ¤¤!"
+
+msgid "gvimext.dll error"
+msgstr "gvimext.dll ¥¨¥é¡¼"
+
+msgid "Path length too long!"
+msgstr "¥Ñ¥¹¤¬Ä¹¤¹¤®¤Þ¤¹!"
+
+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.
+#.
+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: :while ¤Î¤Ê¤¤ :endwhile ¤¬¤¢¤ê¤Þ¤¹"
+
+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: ̤ÃΤΥե©¥ó¥È¥»¥Ã¥È: %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: ÆâÉô¥¨¥é¡¼¤Ç¤¹"
+
+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 "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\"() ¤Î¥é¥¤¥Ö¥é¥ê¸Æ½Ð¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
+
+#, 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 "E37: No write since last change (add ! to override)"
+msgstr "E37: ºÇ¸å¤ÎÊѹ¹¤¬Êݸ¤µ¤ì¤Æ¤¤¤Þ¤»¤ó (! ¤òÄɲäÇÊѹ¹¤òÇË´þ)"
+
+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: ÉÔÀµ¤ÊÀµµ¬É½¸½¥×¥í¥°¥é¥à¤Ç¤¹"
+
+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: ¥µ¥ó¥É¥Ü¥Ã¥¯¥¹¤Ç¤ÏÊÑ¿ô \"%s\" ¤ËÃͤòÀßÄê¤Ç¤­¤Þ¤»¤ó"
+
+msgid "E47: Error while reading errorfile"
+msgstr "E47: ¥¨¥é¡¼¥Õ¥¡¥¤¥ë¤ÎÆÉ¹þÃæ¤Ë¥¨¥é¡¼¤¬È¯À¸¤·¤Þ¤·¤¿"
+
+msgid "E48: Not allowed in sandbox"
+msgstr "E48: ¥µ¥ó¥É¥Ü¥Ã¥¯¥¹¤Ç¤Ïµö¤µ¤ì¤Þ¤»¤ó"
+
+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: sign ¤Î¥Ç¡¼¥¿¤òÆÉ¹þ¤á¤Þ¤»¤ó¤Ç¤·¤¿"
+
+msgid "E72: Close error on swap file"
+msgstr "E72: ¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤Î¥¯¥í¡¼¥º»þ¥¨¥é¡¼¤Ç¤¹"
+
+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 "Zero count"
+msgstr "¥¼¥í¥«¥¦¥ó¥È"
+
+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 ¤ÏÆÉ¹þÀìÍÑ¥Õ¥¡¥¤¥ë¤òÊѹ¹¤¹¤ë¤³¤È¤òµö¤·¤Þ¤»¤ó"
+
+#, c-format
+msgid "E685: Internal error: %s"
+msgstr "E685: ÆâÉô¥¨¥é¡¼¤Ç¤¹: %s"
+
+msgid "E363: pattern uses more memory than 'maxmempattern'"
+msgstr "E363: ¥Ñ¥¿¡¼¥ó¤¬ 'maxmempattern' °Ê¾å¤Î¥á¥â¥ê¤ò»ÈÍѤ·¤Þ¤¹"
+
+msgid "E749: empty buffer"
+msgstr "E749: ¥Ð¥Ã¥Õ¥¡¤¬¶õ¤Ç¤¹"
+
+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: ̵¸ú¤Ê¥ì¥¸¥¹¥¿Ì¾¤Ç¤¹"
+
+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 "¥¤¥ó¥Ç¥Ã¥¯¥¹¤Ï %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 "long() ¤«¤½¤ì¤ØÊÑ´¹²Äǽ¤Ê¤â¤Î¤¬´üÂÔ¤µ¤ì¤Æ¤¤¤ë¤Î¤Ë %s ¤Ç¤·¤¿"
+
+#, c-format
+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 ·¿¤È¤·¤Æ¤ÏÃͤ¬Â礭²á¤®¤Þ¤¹"
+
+msgid "value is too small to fit into C int type"
+msgstr "C¸À¸ì¤Î int ·¿¤È¤·¤Æ¤ÏÃͤ¬¾®¤µ²á¤®¤Þ¤¹"
+
+msgid "number must be greater then zero"
+msgstr "¿ôÃÍ¤Ï 0 ¤è¤êÂ礭¤¯¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó"
+
+msgid "number must be greater or equal to zero"
+msgstr "¿ôÃÍ¤Ï 0 ¤«¤½¤ì°Ê¾å¤Ç¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó"
+
+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: I/O¥ª¥Ö¥¸¥§¥¯¥È¤Î½é´ü²½¥¨¥é¡¼"
+
+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 ¤òÊÖ¤·¤Þ¤·¤¿ (´üÂÔÃÍ: 2 Í×ÁǤΥ¿¥×¥ë)"
+
+#, c-format
+msgid "expected 3-tuple as imp.find_module() result, but got tuple of size %d"
+msgstr "impl.find_module() ¤¬ %d Í×ÁǤΥ¿¥×¥ë¤òÊÖ¤·¤Þ¤·¤¿ (´üÂÔÃÍ: 2)"
+
+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 "¥ê¥¹¥ÈÈϰϳ°¤Î¥¤¥ó¥Ç¥Ã¥¯¥¹¤Ç¤¹"
+
+#. No more suitable format specifications in python-2.3
+#, c-format
+msgid "internal error: failed to get vim list item %d"
+msgstr "ÆâÉô¥¨¥é¡¼: vim¤Î¥ê¥¹¥ÈÍ×ÁÇ %d ¤Î¼èÆÀ¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
+
+msgid "failed to add item to list"
+msgstr "¥ê¥¹¥È¤Ø¤ÎÍ×ÁÇÄɲä˼ºÇÔ¤·¤Þ¤·¤¿"
+
+#, c-format
+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 "¸ÇÄꤵ¤ì¤¿¥ê¥¹¥È¤ÏÊѹ¹¤Ç¤­¤Þ¤»¤ó"
+
+#, c-format
+msgid "unnamed function %s does not exist"
+msgstr "̵̾´Ø¿ô %s ¤Ï¸ºß¤·¤Þ¤»¤ó"
+
+#, c-format
+msgid "function %s does not exist"
+msgstr "´Ø¿ô %s ¤¬¤¢¤ê¤Þ¤»¤ó"
+
+msgid "function constructor does not accept keyword arguments"
+msgstr "´Ø¿ô¤Î¥³¥ó¥¹¥È¥é¥¯¥¿¤Ï¥­¡¼¥ï¡¼¥É°ú¿ô¤ò¼õ¤±ÉÕ¤±¤Þ¤»¤ó"
+
+#, 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 "¥Þ¡¼¥¯Ì¾¤Ï1ʸ»ú¤Î¥¢¥ë¥Õ¥¡¥Ù¥Ã¥È¤Ç¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó"
+
+#, 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: ¼°É¾²Á¤ÏÍ­¸ú¤Ê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 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_hooks ¤ò 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/po/ja.po b/src/po/ja.po
new file mode 100644
index 0000000000..a0ee4c2afa
--- /dev/null
+++ b/src/po/ja.po
@@ -0,0 +1,6808 @@
+# Japanese 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.
+#
+# Last Change: 2013 Jul 06
+#
+# Copyright (C) 2001-13 MURAOKA Taro <koron.kaoriya@gmail.com>
+# 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: 2013-07-06 13:50+0900\n"
+"PO-Revision-Date: 2013-07-06 15:00+0900\n"
+"Last-Translator: MURAOKA Taro <koron.kaoriya@gmail.com>\n"
+"Language-Team: MURAOKA Taro <koron.kaoriya@gmail.com>\n"
+"Language: Japanese\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8-bit\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æš—å·ã®ãƒ“ッグ/リトルエンディアンãŒé–“é•ã£ã¦ã„ã¾ã™"
+
+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: autocommandãŒã‚³ãƒžãƒ³ãƒ‰ã®åœæ­¢ã‚’引ãèµ·ã“ã—ã¾ã—ãŸ"
+
+msgid "E82: Cannot allocate any buffer, exiting..."
+msgstr "E82: ãƒãƒƒãƒ•ã‚¡ã‚’1ã¤ã‚‚作æˆã§ããªã„ã®ã§, 終了ã—ã¾ã™..."
+
+msgid "E83: Cannot allocate buffer, using other one..."
+msgstr "E83: ãƒãƒƒãƒ•ァを作æˆã§ããªã„ã®ã§, ä»–ã®ã‚’使用ã—ã¾ã™..."
+
+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 "E84: No modified buffer found"
+msgstr "E84: 変更ã•れãŸãƒãƒƒãƒ•ã‚¡ã¯ã‚りã¾ã›ã‚“"
+
+#. back where we started, didn't find anything.
+msgid "E85: There is no listed buffer"
+msgstr "E85: リスト表示ã•れるãƒãƒƒãƒ•ã‚¡ã¯ã‚りã¾ã›ã‚“"
+
+#, c-format
+msgid "E86: Buffer %ld does not exist"
+msgstr "E86: ãƒãƒƒãƒ•ã‚¡ %ld ã¯ã‚りã¾ã›ã‚“"
+
+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 "E90: Cannot unload last buffer"
+msgstr "E90: 最後ã®ãƒãƒƒãƒ•ã‚¡ã¯è§£æ”¾ã§ãã¾ã›ã‚“"
+
+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%%-- col "
+
+msgid "[No Name]"
+msgstr "[ç„¡å]"
+
+#. must be a help buffer
+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 "[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"
+
+#, c-format
+msgid "E96: Can not diff more than %ld buffers"
+msgstr "E96: %ld 以上ã®ãƒãƒƒãƒ•ã‚¡ã¯diffã§ãã¾ã›ã‚“"
+
+msgid "E810: Cannot read or write temp files"
+msgstr "E810: 一時ファイルã®èª­è¾¼ã‚‚ã—ãã¯æ›¸è¾¼ãŒã§ãã¾ã›ã‚“"
+
+msgid "E97: Cannot create diffs"
+msgstr "E97: 差分を作æˆã§ãã¾ã›ã‚“ "
+
+msgid "Patch file"
+msgstr "パッãƒãƒ•ァイル"
+
+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: ç¾åœ¨ã®ãƒãƒƒãƒ•ã‚¡ã¯å·®åˆ†ãƒ¢ãƒ¼ãƒ‰ã§ã¯ã‚りã¾ã›ã‚“"
+
+msgid "E793: No other buffer in diff mode is modifiable"
+msgstr "E793: 差分モードã§ã‚ã‚‹ä»–ã®ãƒãƒƒãƒ•ã‚¡ã¯å¤‰æ›´å¯èƒ½ã§ã™"
+
+msgid "E100: No other buffer in diff mode"
+msgstr "E100: 差分モードã§ã‚ã‚‹ä»–ã®ãƒãƒƒãƒ•ã‚¡ã¯ã‚りã¾ã›ã‚“"
+
+msgid "E101: More than two buffers in diff mode, don't know which one to use"
+msgstr ""
+"E101: 差分モードã®ãƒãƒƒãƒ•ã‚¡ãŒ2個以上ã‚ã‚‹ã®ã§ã€ã©ã‚Œã‚’使ã†ã‹ç‰¹å®šã§ãã¾ã›ã‚“"
+
+#, 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\" ã¯å·®åˆ†ãƒ¢ãƒ¼ãƒ‰ã§ã¯ã‚りã¾ã›ã‚“"
+
+msgid "E787: Buffer changed unexpectedly"
+msgstr "E787: 予期ã›ãšãƒãƒƒãƒ•ã‚¡ãŒå¤‰æ›´å¤‰æ›´ã•れã¾ã—ãŸ"
+
+msgid "E104: Escape not allowed in digraph"
+msgstr "E104: åˆå­—ã«Escapeã¯ä½¿ç”¨ã§ãã¾ã›ã‚“"
+
+msgid "E544: Keymap file not found"
+msgstr "E544: キーマップファイルãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
+
+msgid "E105: Using :loadkeymap not in a sourced file"
+msgstr "E105: :source ã§å–込むファイル以外ã§ã¯ :loadkeymap を使ãˆã¾ã›ã‚“"
+
+msgid "E791: Empty keymap entry"
+msgstr "E791: 空ã®ã‚­ãƒ¼ãƒžãƒƒãƒ—エントリ"
+
+msgid " Keyword completion (^N^P)"
+msgstr " キーワード補完 (^N^P)"
+
+#. ctrl_x_mode == 0, ^P/^N compl.
+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 " オムニ補完 (^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 " 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.
+#.
+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 "E684: list index out of range: %ld"
+msgstr "E684: リストã®ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ãŒç¯„囲外ã§ã™: %ld"
+
+#, c-format
+msgid "E121: Undefined variable: %s"
+msgstr "E121: 未定義ã®å¤‰æ•°ã§ã™: %s"
+
+msgid "E111: Missing ']'"
+msgstr "E111: ']' ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
+
+#, c-format
+msgid "E686: Argument of %s must be a List"
+msgstr "E686: %s ã®å¼•æ•°ã¯ãƒªã‚¹ãƒˆåž‹ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
+
+#, c-format
+msgid "E712: Argument of %s must be a List or Dictionary"
+msgstr "E712: %s ã®å¼•æ•°ã¯ãƒªã‚¹ãƒˆåž‹ã¾ãŸã¯è¾žæ›¸åž‹ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
+
+msgid "E713: Cannot use empty key for Dictionary"
+msgstr "E713: 辞書型ã«ç©ºã®ã‚­ãƒ¼ã‚’使ã†ã“ã¨ã¯ã§ãã¾ã›ã‚“"
+
+msgid "E714: List required"
+msgstr "E714: リスト型ãŒå¿…è¦ã§ã™"
+
+msgid "E715: Dictionary required"
+msgstr "E715: 辞書型ãŒå¿…è¦ã§ã™"
+
+#, 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"
+
+#, 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: 関数å‚ç…§åž‹ãŒè¦æ±‚ã•れã¾ã™"
+
+msgid "E719: Cannot use [:] with a Dictionary"
+msgstr "E719: [:] を辞書型ã¨çµ„ã¿åˆã‚ã›ã¦ã¯ä½¿ãˆã¾ã›ã‚“"
+
+#, c-format
+msgid "E734: Wrong variable type for %s="
+msgstr "E734: ç•°ãªã£ãŸåž‹ã®å¤‰æ•°ã§ã™ %s="
+
+#, c-format
+msgid "E130: Unknown function: %s"
+msgstr "E130: 未知ã®é–¢æ•°ã§ã™: %s"
+
+#, c-format
+msgid "E461: Illegal variable name: %s"
+msgstr "E461: 䏿­£ãªå¤‰æ•°åã§ã™: %s"
+
+msgid "E806: using Float as a String"
+msgstr "E806: æµ®å‹•å°æ•°ç‚¹æ•°ã‚’文字列ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™"
+
+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 "リスト型ã®å€¤ã«2ã¤ä»¥ä¸Šã® ; ãŒæ¤œå‡ºã•れã¾ã—ãŸ"
+
+#, 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: [:] ã«ã¯ãƒªã‚¹ãƒˆåž‹ã®å€¤ãŒå¿…è¦ã§ã™"
+
+msgid "E710: List value has more items than target"
+msgstr "E710: リスト型変数ã«ã‚¿ãƒ¼ã‚²ãƒƒãƒˆã‚ˆã‚Šã‚‚多ã„è¦ç´ ãŒã‚りã¾ã™"
+
+msgid "E711: List value has not enough items"
+msgstr "E711: リスト型変数ã«ååˆ†ãªæ•°ã®è¦ç´ ãŒã‚りã¾ã›ã‚“"
+
+#
+msgid "E690: Missing \"in\" after :for"
+msgstr "E690: :for ã®å¾Œã« \"in\" ãŒã‚りã¾ã›ã‚“"
+
+#, c-format
+msgid "E107: Missing parentheses: %s"
+msgstr "E107: カッコ '(' ãŒã‚りã¾ã›ã‚“: %s"
+
+#, c-format
+msgid "E108: No such variable: \"%s\""
+msgstr "E108: ãã®å¤‰æ•°ã¯ã‚りã¾ã›ã‚“: \"%s\""
+
+msgid "E743: variable nested too deep for (un)lock"
+msgstr "E743: (アン)ロックã™ã‚‹ã«ã¯å¤‰æ•°ã®å…¥ã‚Œå­ãŒæ·±éŽãŽã¾ã™"
+
+msgid "E109: Missing ':' after '?'"
+msgstr "E109: '?' ã®å¾Œã« ':' ãŒã‚りã¾ã›ã‚“"
+
+msgid "E691: Can only compare List with List"
+msgstr "E691: リスト型ã¯ãƒªã‚¹ãƒˆåž‹ã¨ã—ã‹æ¯”較ã§ãã¾ã›ã‚“"
+
+msgid "E692: Invalid operation for Lists"
+msgstr "E692: リスト型ã«ã¯ç„¡åŠ¹ãªæ“作ã§ã™"
+
+msgid "E735: Can only compare Dictionary with Dictionary"
+msgstr "E735: 辞書型ã¯è¾žæ›¸åž‹ã¨ã—ã‹æ¯”較ã§ãã¾ã›ã‚“"
+
+msgid "E736: Invalid operation for Dictionary"
+msgstr "E736: 辞書型ã«ã¯ç„¡åŠ¹ãªæ“作ã§ã™"
+
+msgid "E693: Can only compare Funcref with Funcref"
+msgstr "E693: 関数å‚ç…§åž‹ã¯é–¢æ•°å‚ç…§åž‹ã¨ã—ã‹æ¯”較ã§ãã¾ã›ã‚“"
+
+msgid "E694: Invalid operation for Funcrefs"
+msgstr "E694: 関数å‚ç…§åž‹ã«ã¯ç„¡åŠ¹ãªæ“作ã§ã™"
+
+msgid "E804: Cannot use '%' with Float"
+msgstr "E804: '%' ã‚’æµ®å‹•å°æ•°ç‚¹æ•°ã¨çµ„ã¿åˆã‚ã›ã¦ã¯ä½¿ãˆã¾ã›ã‚“"
+
+msgid "E110: Missing ')'"
+msgstr "E110: ')' ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
+
+msgid "E695: Cannot index a Funcref"
+msgstr "E695: 関数å‚ç…§åž‹ã¯ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã§ãã¾ã›ã‚“"
+
+#, 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"
+
+#, c-format
+msgid "E696: Missing comma in List: %s"
+msgstr "E696: リスト型ã«ã‚«ãƒ³ãƒžãŒã‚りã¾ã›ã‚“: %s"
+
+#, c-format
+msgid "E697: Missing end of List ']': %s"
+msgstr "E697: ãƒªã‚¹ãƒˆåž‹ã®æœ€å¾Œã« ']' ãŒã‚りã¾ã›ã‚“: %s"
+
+#, 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 "E724: variable nested too deep for displaying"
+msgstr "E724: 表示ã™ã‚‹ã«ã¯å¤‰æ•°ã®å…¥ã‚Œå­ãŒæ·±éŽãŽã¾ã™"
+
+#, 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"
+
+#, c-format
+msgid "E117: Unknown function: %s"
+msgstr "E117: 未知ã®é–¢æ•°ã§ã™: %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 "E808: Number or Float required"
+msgstr "E808: æ•°å€¤ã‹æµ®å‹•å°æ•°ç‚¹æ•°ãŒå¿…è¦ã§ã™"
+
+msgid "add() argument"
+msgstr "add() ã®å¼•æ•°"
+
+msgid "E699: Too many arguments"
+msgstr "E699: 引数ãŒå¤šéŽãŽã¾ã™"
+
+msgid "E785: complete() can only be used in Insert mode"
+msgstr "E785: complete() ã¯æŒ¿å…¥ãƒ¢ãƒ¼ãƒ‰ã§ã—ã‹åˆ©ç”¨ã§ãã¾ã›ã‚“"
+
+#.
+#. * 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"
+
+#, c-format
+msgid "E737: Key already exists: %s"
+msgstr "E737: ã‚­ãƒ¼ã¯æ—¢ã«å­˜åœ¨ã—ã¾ã™: %s"
+
+msgid "extend() argument"
+msgstr "extend() ã®å¼•æ•°"
+
+msgid "map() argument"
+msgstr "map() ã®å¼•æ•°"
+
+msgid "filter() argument"
+msgstr "filter() ã®å¼•æ•°"
+
+#, c-format
+msgid "+-%s%3ld lines: "
+msgstr "+-%s%3ld 行: "
+
+#, c-format
+msgid "E700: Unknown function: %s"
+msgstr "E700: 未知ã®é–¢æ•°ã§ã™: %s"
+
+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 "E701: Invalid type for len()"
+msgstr "E701: len() ã«ã¯ç„¡åйãªåž‹ã§ã™"
+
+msgid "E726: Stride is zero"
+msgstr "E726: ストライド(å‰é€²é‡)㌠0 ã§ã™"
+
+msgid "E727: Start past end"
+msgstr "E727: é–‹å§‹ä½ç½®ãŒçµ‚了ä½ç½®ã‚’è¶Šãˆã¾ã—ãŸ"
+
+msgid "<empty>"
+msgstr "<空>"
+
+msgid "E240: No connection to Vim server"
+msgstr "E240: Vim サーãƒã¸ã®æŽ¥ç¶šãŒã‚りã¾ã›ã‚“"
+
+#, c-format
+msgid "E241: Unable to send to %s"
+msgstr "E241: %s ã¸é€ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“"
+
+msgid "E277: Unable to read a server reply"
+msgstr "E277: サーãƒã®å¿œç­”ãŒã‚りã¾ã›ã‚“"
+
+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: クライアントã¸é€ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“"
+
+msgid "sort() argument"
+msgstr "sort() ã®å¼•æ•°"
+
+msgid "E702: Sort compare function failed"
+msgstr "E702: ã‚½ãƒ¼ãƒˆã®æ¯”較関数ãŒå¤±æ•—ã—ã¾ã—ãŸ"
+
+msgid "(Invalid)"
+msgstr "(無効)"
+
+msgid "E677: Error writing temp file"
+msgstr "E677: 一時ファイル書込中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ"
+
+msgid "E805: Using a Float as a Number"
+msgstr "E805: æµ®å‹•å°æ•°ç‚¹æ•°ã‚’数値ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™"
+
+msgid "E703: Using a Funcref as a Number"
+msgstr "E703: 関数å‚照型を数値ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™ã€‚"
+
+msgid "E745: Using a List as a Number"
+msgstr "E745: リスト型を数値ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™"
+
+msgid "E728: Using a Dictionary as a Number"
+msgstr "E728: 辞書型を数値ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™"
+
+msgid "E729: using Funcref as a String"
+msgstr "E729: 関数å‚照型を文字列ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™"
+
+msgid "E730: using List as a String"
+msgstr "E730: リスト型を文字列ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™"
+
+msgid "E731: using Dictionary as a String"
+msgstr "E731: 辞書型を文字列ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™"
+
+#, c-format
+msgid "E706: Variable type mismatch for: %s"
+msgstr "E706: 変数ã®åž‹ãŒä¸€è‡´ã—ã¾ã›ã‚“: %s"
+
+#, 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: 関数å‚照型変数åã¯å¤§æ–‡å­—ã§å§‹ã¾ã‚‰ãªã‘れã°ãªã‚Šã¾ã›ã‚“: %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: コピーをå–ã‚‹ã«ã¯å¤‰æ•°ã®å…¥ã‚Œå­ãŒæ·±éŽãŽã¾ã™"
+
+#, 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 "E125: Illegal argument: %s"
+msgstr "E125: 䏿­£ãªå¼•æ•°ã§ã™: %s"
+
+#, c-format
+msgid "E853: Duplicate argument name: %s"
+msgstr "E853: 引数åãŒé‡è¤‡ã—ã¦ã„ã¾ã™: %s"
+
+msgid "E126: Missing :endfunction"
+msgstr "E126: :endfunction ãŒã‚りã¾ã›ã‚“"
+
+#, 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"
+
+msgid "E129: Function name required"
+msgstr "E129: 関数åãŒè¦æ±‚ã•れã¾ã™"
+
+#, c-format
+msgid "E128: Function name must start with a capital or contain a colon: %s"
+msgstr "E128: 関数åã¯å¤§æ–‡å­—ã§å§‹ã¾ã‚‹ã‹ã‚³ãƒ­ãƒ³ã‚’å«ã¾ãªã‘れã°ãªã‚Šã¾ã›ã‚“: %s"
+
+#, c-format
+msgid "E131: Cannot delete function %s: It is in use"
+msgstr "E131: 関数 %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 ã‚’è¿”ã—ã¾ã—ãŸ"
+
+#, c-format
+msgid "continuing in %s"
+msgstr "%s ã®å®Ÿè¡Œã‚’継続中ã§ã™"
+
+msgid "E133: :return not inside a function"
+msgstr "E133: 関数外㫠:return ãŒã‚りã¾ã—ãŸ"
+
+msgid ""
+"\n"
+"# global variables:\n"
+msgstr ""
+"\n"
+"# グローãƒãƒ«å¤‰æ•°:\n"
+
+msgid ""
+"\n"
+"\tLast set from "
+msgstr ""
+"\n"
+"\tLast set from "
+
+msgid "No old files"
+msgstr "å¤ã„ファイルã¯ã‚りã¾ã›ã‚“"
+
+#, c-format
+msgid "<%s>%s%s %d, Hex %02x, Octal %03o"
+msgstr "<%s>%s%s %d, 16進数 %02x, 8進数 %03o"
+
+#, c-format
+msgid "> %d, Hex %04x, Octal %o"
+msgstr "> %d, 16進数 %04x, 8進数 %o"
+
+#, c-format
+msgid "> %d, Hex %08x, Octal %o"
+msgstr "> %d, 16進数 %08x, 8進数 %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: *フィルタ* autocommandã¯ç¾åœ¨ã®ãƒãƒƒãƒ•ァを変更ã—ã¦ã¯ã„ã‘ã¾ã›ã‚“"
+
+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 " 失敗"
+
+#. avoid a wait_return for this message, it's annoying
+#, c-format
+msgid "E137: Viminfo file is not writable: %s"
+msgstr "E137: viminfoãƒ•ã‚¡ã‚¤ãƒ«ãŒæ›¸è¾¼ã¿ã§ãã¾ã›ã‚“: %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\" を書込ã¿ä¸­"
+
+#. Write the info:
+#, 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 "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 "スワップファイル \"%s\" ãŒå­˜åœ¨ã—ã¾ã™. 上書ãを強制ã—ã¾ã™ã‹?"
+
+#, c-format
+msgid "E768: Swap file exists: %s (:silent! overrides)"
+msgstr "E768: スワップファイルãŒå­˜åœ¨ã—ã¾ã™: %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 ""
+"\"%s\" ã«ã¯ 'readonly' オプションãŒè¨­å®šã•れã¦ã„ã¾ã™.\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: autocommandãŒäºˆæœŸã›ãšæ–°ã—ã„ãƒãƒƒãƒ•ã‚¡ %s を削除ã—ã¾ã—ãŸ"
+
+msgid "E144: non-numeric argument to :z"
+msgstr "E144: æ•°ã§ã¯ãªã„引数㌠:z ã«æ¸¡ã•れã¾ã—ãŸ"
+
+msgid "E145: Shell commands not allowed in rvim"
+msgstr "E145: 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"
+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 "E150: Not a directory: %s"
+msgstr "E150: ディレクトリã§ã¯ã‚りã¾ã›ã‚“: %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 ã‚’é–‹ã‘ã¾ã›ã‚“"
+
+# Added at 29-Apr-2004.
+#, c-format
+msgid "E670: Mix of help file encodings within a language: %s"
+msgstr "E670: 1ã¤ã®è¨€èªžã®ãƒ˜ãƒ«ãƒ—ファイルã«è¤‡æ•°ã®ã‚¨ãƒ³ã‚³ãƒ¼ãƒ‰ãŒæ··åœ¨ã—ã¦ã„ã¾ã™: %s"
+
+#, c-format
+msgid "E154: Duplicate tag \"%s\" in file %s/%s"
+msgstr "E154: ã‚¿ã‚° \"%s\" ãŒãƒ•ァイル %s/%s ã«é‡è¤‡ã—ã¦ã„ã¾ã™"
+
+#, c-format
+msgid "E160: Unknown sign command: %s"
+msgstr "E160: 未知ã®signコマンドã§ã™: %s"
+
+msgid "E156: Missing sign name"
+msgstr "E156: signåãŒã‚りã¾ã›ã‚“"
+
+msgid "E612: Too many signs defined"
+msgstr "E612: signã®å®šç¾©ãŒå¤šæ•°è¦‹ã¤ã‹ã‚Šã¾ã—ãŸ"
+
+#, c-format
+msgid "E239: Invalid sign text: %s"
+msgstr "E239: 無効ãªsignã®ãƒ†ã‚­ã‚¹ãƒˆã§ã™: %s"
+
+#, c-format
+msgid "E155: Unknown sign: %s"
+msgstr "E155: 未知ã®signã§ã™: %s"
+
+msgid "E159: Missing sign number"
+msgstr "E159: signã®ç•ªå·ãŒã‚りã¾ã›ã‚“"
+
+#, c-format
+msgid "E158: Invalid buffer name: %s"
+msgstr "E158: 無効ãªãƒãƒƒãƒ•ã‚¡åã§ã™: %s"
+
+#, c-format
+msgid "E157: Invalid sign ID: %ld"
+msgstr "E157: 無効ãªsign識別å­ã§ã™: %ld"
+
+# Added at 27-Jan-2004.
+msgid " (NOT FOUND)"
+msgstr " (見ã¤ã‹ã‚Šã¾ã›ã‚“)"
+
+msgid " (not supported)"
+msgstr " (éžã‚µãƒãƒ¼ãƒˆ)"
+
+msgid "[Deleted]"
+msgstr "[削除済]"
+
+msgid "Entering Debug mode. Type \"cont\" to continue."
+msgstr "デãƒãƒƒã‚°ãƒ¢ãƒ¼ãƒ‰ã«å…¥ã‚Šã¾ã™. ç¶šã‘ã‚‹ã«ã¯ \"cont\" ã¨å…¥åŠ›ã—ã¦ãã ã•ã„."
+
+#, c-format
+msgid "line %ld: %s"
+msgstr "行 %ld: %s"
+
+#, c-format
+msgid "cmd: %s"
+msgstr "コマンド: %s"
+
+#, 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"
+
+msgid "E750: First use \":profile start {fname}\""
+msgstr "E750: åˆã‚ã« \":profile start {fname}\" を実行ã—ã¦ãã ã•ã„"
+
+#, c-format
+msgid "Save changes to \"%s\"?"
+msgstr "変更を \"%s\" ã«ä¿å­˜ã—ã¾ã™ã‹?"
+
+msgid "Untitled"
+msgstr "無題"
+
+#, c-format
+msgid "E162: No write since last change for buffer \"%s\""
+msgstr "E162: ãƒãƒƒãƒ•ã‚¡ \"%s\" ã®å¤‰æ›´ã¯ä¿å­˜ã•れã¦ã„ã¾ã›ã‚“"
+
+msgid "Warning: Entered other buffer unexpectedly (check autocommands)"
+msgstr "警告: 予期ã›ãšä»–ãƒãƒƒãƒ•ã‚¡ã¸ç§»å‹•ã—ã¾ã—㟠(autocommands を調ã¹ã¦ãã ã•ã„)"
+
+msgid "E163: There is only one file to edit"
+msgstr "E163: 編集ã™ã‚‹ãƒ•ァイルã¯1ã¤ã—ã‹ã‚りã¾ã›ã‚“"
+
+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 'runtimepath': \"%s\""
+msgstr "'runtimepath' ã®ä¸­ã«ã¯è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“: \"%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 ã®å–込を完了"
+
+msgid "modeline"
+msgstr "モード行"
+
+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 "E319: Sorry, the command is not available in this version"
+msgstr "E319: ã“ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã§ã¯ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã¯åˆ©ç”¨ã§ãã¾ã›ã‚“, ã”ã‚ã‚“ãªã•ã„"
+
+msgid "E172: Only one file name allowed"
+msgstr "E172: ファイルå㯠1 ã¤ã«ã—ã¦ãã ã•ã„"
+
+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 Range 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: カウントを2釿Œ‡å®šã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“"
+
+msgid "E178: Invalid default value for count"
+msgstr "E178: カウントã®çœç•¥å€¤ãŒç„¡åйã§ã™"
+
+msgid "E179: argument required for -complete"
+msgstr "E179: -補完ã®ãŸã‚ã®å¼•æ•°ãŒå¿…è¦ã§ã™"
+
+#, 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 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 使ã„ã•ã‚“ã€ã‚„ã‚!"
+
+msgid "E784: Cannot close last tab page"
+msgstr "E784: 最後ã®ã‚¿ãƒ–ページを閉ã˜ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“"
+
+msgid "Already only one tab page"
+msgstr "æ—¢ã«ã‚¿ãƒ–ページã¯1ã¤ã—ã‹ã‚りã¾ã›ã‚“"
+
+msgid "Edit File in new window"
+msgstr "æ–°ã—ã„ウィンドウã§ãƒ•ァイルを編集ã—ã¾ã™"
+
+#, c-format
+msgid "Tab page %d"
+msgstr "タブページ %d"
+
+msgid "No swap file"
+msgstr "スワップファイルãŒã‚りã¾ã›ã‚“"
+
+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 ã«ã¯2ã¤ã®æ•°å€¤ã®å¼•æ•°ãŒå¿…è¦ã§ã™"
+
+#, 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 ã«ã¯2ã¤ã®æ•°å€¤ã®å¼•æ•°ãŒå¿…è¦ã§ã™"
+
+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\" を書込ã¿ç”¨ã¨ã—ã¦é–‹ã‘ã¾ã›ã‚“"
+
+#. set mark
+msgid "E191: Argument must be a letter or forward/backward quote"
+msgstr "E191: 引数ã¯1文字ã®è‹±å­—ã‹å¼•用符 (' ã‹ `) ã§ãªã‘れã°ã„ã‘ã¾ã›ã‚“"
+
+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>\"ã‚’ç½®ãæ›ãˆã‚‹autocommandã®ãƒ•ァイルåãŒã‚りã¾ã›ã‚“"
+
+msgid "E496: no autocommand buffer number to substitute for \"<abuf>\""
+msgstr "E496: \"<abuf>\"ã‚’ç½®ãæ›ãˆã‚‹autocommandãƒãƒƒãƒ•ァ番å·ãŒã‚りã¾ã›ã‚“"
+
+msgid "E497: no autocommand match name to substitute for \"<amatch>\""
+msgstr "E497: \"<amatch>\"ã‚’ç½®ãæ›ãˆã‚‹autocommandã®è©²å½“åãŒã‚りã¾ã›ã‚“"
+
+msgid "E498: no :source file name to substitute for \"<sfile>\""
+msgstr "E498: \"<sfile>\"ã‚’ç½®ãæ›ãˆã‚‹ :source 対象ファイルåãŒã‚りã¾ã›ã‚“"
+
+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: '%' ã‚„ '#' ãŒç„¡åファイルãªã®ã§ \":p:h\" ã‚’ä¼´ã‚ãªã„ä½¿ã„æ–¹ã¯ã§ãã¾ã›ã‚“"
+
+msgid "E500: Evaluates to an empty string"
+msgstr "E500: 空文字列ã¨ã—ã¦è©•価ã•れã¾ã—ãŸ"
+
+msgid "E195: Cannot open viminfo file for reading"
+msgstr "E195: viminfoファイルを読込用ã¨ã—ã¦é–‹ã‘ã¾ã›ã‚“"
+
+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
+#, 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"
+
+#. always scroll up, don't overwrite
+#, 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 "エラー"
+
+#. if (pending & CSTP_INTERRUPT)
+msgid "Interrupt"
+msgstr "割込ã¿"
+
+msgid "E579: :if nesting too deep"
+msgstr "E579: :if ã®å…¥ã‚Œå­ãŒæ·±éŽãŽã¾ã™"
+
+msgid "E580: :endif without :if"
+msgstr "E580: :if ã®ãªã„ :endif ãŒã‚りã¾ã™"
+
+msgid "E581: :else without :if"
+msgstr "E581: :if ã®ãªã„ :else ãŒã‚りã¾ã™"
+
+msgid "E582: :elseif without :if"
+msgstr "E582: :if ã®ãªã„ :elseif ãŒã‚りã¾ã™"
+
+msgid "E583: multiple :else"
+msgstr "E583: 複数㮠:else ãŒã‚りã¾ã™"
+
+msgid "E584: :elseif after :else"
+msgstr "E584: :else ã®å¾Œã« :elseif ãŒã‚りã¾ã™"
+
+msgid "E585: :while/:for nesting too deep"
+msgstr "E585: :while ã‚„ :for ã®å…¥ã‚Œå­ãŒæ·±éŽãŽã¾ã™"
+
+msgid "E586: :continue without :while or :for"
+msgstr "E586: :while ã‚„ :for ã®ãªã„ :continue ãŒã‚りã¾ã™"
+
+msgid "E587: :break without :while or :for"
+msgstr "E587: :while ã‚„ :for ã®ãªã„ :break ãŒã‚りã¾ã™"
+
+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: :try ã®ãªã„ :catch ãŒã‚りã¾ã™"
+
+#. Give up for a ":catch" after ":finally" and ignore it.
+#. * Just parse.
+msgid "E604: :catch after :finally"
+msgstr "E604: :finally ã®å¾Œã« :catch ãŒã‚りã¾ã™"
+
+msgid "E606: :finally without :try"
+msgstr "E606: :try ã®ãªã„ :finally ãŒã‚りã¾ã™"
+
+#. Give up for a multiple ":finally" and ignore it.
+msgid "E607: multiple :finally"
+msgstr "E607: 複数㮠:finally ãŒã‚りã¾ã™"
+
+msgid "E602: :endtry without :try"
+msgstr "E602: :try ã®ãªã„ :endtry ã§ã™"
+
+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 "E198: cmd_pchar beyond the command length"
+msgstr "E198: cmd_pchar ãŒã‚³ãƒžãƒ³ãƒ‰é•·ã‚’è¶…ãˆã¾ã—ãŸ"
+
+msgid "E199: Active window or buffer deleted"
+msgstr "E199: アクティブãªã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã‹ãƒãƒƒãƒ•ã‚¡ãŒå‰Šé™¤ã•れã¾ã—ãŸ"
+
+msgid "E812: Autocommands changed buffer or buffer name"
+msgstr "E812: autocommandãŒãƒãƒƒãƒ•ã‚¡ã‹ãƒãƒƒãƒ•ã‚¡åを変更ã—ã¾ã—ãŸ"
+
+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 autocommand ãŒãƒ•ァイルを読込ä¸å¯ã«ã—ã¾ã—ãŸ"
+
+msgid "E201: *ReadPre autocommands must not change current buffer"
+msgstr "E201: *ReadPre autocommand ã¯ç¾åœ¨ã®ãƒãƒƒãƒ•ァを変ãˆã‚‰ã‚Œã¾ã›ã‚“"
+
+msgid "Vim: Reading from stdin...\n"
+msgstr "Vim: 標準入力ã‹ã‚‰èª­è¾¼ä¸­...\n"
+
+msgid "Reading from stdin..."
+msgstr "標準入力ã‹ã‚‰èª­è¾¼ã¿ä¸­..."
+
+#. Re-opening the original file failed!
+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 "[å¤‰æ›æ¸ˆ]"
+
+msgid "[blowfish]"
+msgstr "[blowfishæš—å·åŒ–]"
+
+msgid "[crypted]"
+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 "E821: File is encrypted with unknown method"
+msgstr "E821: ãƒ•ã‚¡ã‚¤ãƒ«ãŒæœªçŸ¥ã®æ–¹æ³•ã§æš—å·åŒ–ã•れã¦ã„ã¾ã™"
+
+msgid "E676: No matching autocommands for acwrite buffer"
+msgstr "E676: acwriteãƒãƒƒãƒ•ã‚¡ã®è©²å½“ã™ã‚‹autocommandã¯å­˜åœ¨ã—ã¾ã›ã‚“"
+
+msgid "E203: Autocommands deleted or unloaded buffer to be written"
+msgstr "E203: ä¿å­˜ã™ã‚‹ãƒãƒƒãƒ•ã‚¡ã‚’autocommandãŒå‰Šé™¤ã‹è§£æ”¾ã—ã¾ã—ãŸ"
+
+msgid "E204: Autocommand changed number of lines in unexpected way"
+msgstr "E204: autocommandãŒäºˆæœŸã›ã¬æ–¹æ³•ã§è¡Œæ•°ã‚’変更ã—ã¾ã—ãŸ"
+
+# 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 "ã¯ãƒ•ァイルã§ã‚‚書込ã¿å¯èƒ½ãƒ‡ãƒã‚¤ã‚¹ã§ã‚‚ã‚りã¾ã›ã‚“"
+
+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 "E460: The resource fork would be lost (add ! to override)"
+msgstr "E460: リソースフォークãŒå¤±ã‚れるã‹ã‚‚ã—れã¾ã›ã‚“ (! を追加ã§å¼·åˆ¶)"
+
+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 "E667: Fsync failed"
+msgstr "E667: fsync ã«å¤±æ•—ã—ã¾ã—ãŸ"
+
+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 " [a]"
+
+msgid " appended"
+msgstr " 追加"
+
+msgid " [w]"
+msgstr " [w]"
+
+msgid " written"
+msgstr " 書込ã¿"
+
+msgid "E205: Patchmode: can't save original file"
+msgstr "E205: patchmode: 原本ファイルをä¿å­˜ã§ãã¾ã›ã‚“"
+
+msgid "E206: patchmode: can't touch empty original file"
+msgstr "E206: patchmode: 空ã®åŽŸæœ¬ãƒ•ã‚¡ã‚¤ãƒ«ã‚’touchã§ãã¾ã›ã‚“"
+
+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 文字"
+
+#. Explicit typecast avoids warning on Mac OS X 10.6
+#, c-format
+msgid "%ld characters"
+msgstr "%ld 文字"
+
+msgid "[noeol]"
+msgstr "[noeol]"
+
+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
+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: autocommand ã® 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"
+"ファイル読込(&L)"
+
+#, 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 "autocommand: %s <ãƒãƒƒãƒ•ã‚¡=%d> ãŒè‡ªå‹•çš„ã«å‰Šé™¤ã•れã¾ã™"
+
+#. the group doesn't exist
+#, c-format
+msgid "E367: No such group: \"%s\""
+msgstr "E367: ãã®ã‚°ãƒ«ãƒ¼ãƒ—ã¯ã‚りã¾ã›ã‚“: \"%s\""
+
+#, 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"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Auto-Commands ---"
+msgstr ""
+"\n"
+"--- Auto-Commands ---"
+
+#, c-format
+msgid "E680: <buffer=%d>: invalid buffer number "
+msgstr "E680: <ãƒãƒƒãƒ•ã‚¡=%d>: 無効ãªãƒãƒƒãƒ•ァ番å·ã§ã™ "
+
+msgid "E217: Can't execute autocommands for ALL events"
+msgstr "E217: å…¨ã¦ã®ã‚¤ãƒ™ãƒ³ãƒˆã«å¯¾ã—ã¦ã®autocommandã¯å®Ÿè¡Œã§ãã¾ã›ã‚“"
+
+msgid "No matching autocommands"
+msgstr "該当ã™ã‚‹autocommandã¯å­˜åœ¨ã—ã¾ã›ã‚“"
+
+msgid "E218: autocommand nesting too deep"
+msgstr "E218: autocommandã®å…¥ã‚Œå­ãŒæ·±éŽãŽã¾ã™"
+
+#, c-format
+msgid "%s Auto commands for \"%s\""
+msgstr "%s Auto commands for \"%s\""
+
+#, c-format
+msgid "Executing %s"
+msgstr "%s を実行ã—ã¦ã„ã¾ã™"
+
+#, c-format
+msgid "autocommand %s"
+msgstr "autocommand %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 lines folded "
+msgstr "+--%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 "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 ""
+"&Yes\n"
+"&No\n"
+"&Cancel"
+msgstr ""
+"ã¯ã„(&Y)\n"
+"ã„ã„ãˆ(&N)\n"
+"キャンセル(&C)"
+
+msgid "Input _Methods"
+msgstr "インプットメソッド"
+
+msgid "VIM - Search and Replace..."
+msgstr "VIM - 検索ã¨ç½®æ›..."
+
+msgid "VIM - Search..."
+msgstr "VIM - 検索..."
+
+msgid "Find what:"
+msgstr "検索文字列:"
+
+msgid "Replace with:"
+msgstr "ç½®æ›æ–‡å­—列:"
+
+#. whole word only button
+msgid "Match whole word only"
+msgstr "正確ã«è©²å½“ã™ã‚‹ã‚‚ã®ã ã‘"
+
+#. match case button
+msgid "Match case"
+msgstr "大文字/å°æ–‡å­—を区別ã™ã‚‹"
+
+msgid "Direction"
+msgstr "æ–¹å‘"
+
+#. 'Up' and 'Down' buttons
+msgid "Up"
+msgstr "上"
+
+msgid "Down"
+msgstr "下"
+
+#. 'Find Next' button
+msgid "Find Next"
+msgstr "次を検索"
+
+#. 'Replace' button
+msgid "Replace"
+msgstr "ç½®æ›"
+
+#. 'Replace All' button
+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)"
+
+#, 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 "Close tab"
+msgstr "タブページを閉ã˜ã‚‹"
+
+msgid "Open tab..."
+msgstr "タブページを開ã"
+
+msgid "Find string (use '\\\\' to find a '\\')"
+msgstr "検索文字列 ('\\' を検索ã™ã‚‹ã«ã¯ '\\\\')"
+
+msgid "Find & Replace (use '\\\\' to find a '\\')"
+msgstr "æ¤œç´¢ãƒ»ç½®æ› ('\\' を検索ã™ã‚‹ã«ã¯ '\\\\')"
+
+#. 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 "使ã‚れã¾ã›ã‚“"
+
+msgid "Directory\t*.nothing\n"
+msgstr "ディレクトリ\t*.nothing\n"
+
+msgid "Vim E458: Cannot allocate colormap entry, some colors may be incorrect"
+msgstr "Vim E458: è‰²æŒ‡å®šãŒæ­£ã—ããªã„ã®ã§ã‚¨ãƒ³ãƒˆãƒªã‚’割り当ã¦ã‚‰ã‚Œã¾ã›ã‚“"
+
+#, 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ã®2å€ã§ã¯ã‚りã¾ã›ã‚“"
+
+#, 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 "å´ä¸‹ã™ã‚‹(&D)"
+
+msgid "no specific match"
+msgstr "マッãƒã™ã‚‹ã‚‚ã®ãŒã‚りã¾ã›ã‚“"
+
+msgid "Vim - Font Selector"
+msgstr "Vim - ãƒ•ã‚©ãƒ³ãƒˆé¸æŠž"
+
+msgid "Name:"
+msgstr "åå‰:"
+
+#. create toggle button
+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 "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ã®ãƒªã‚½ãƒ¼ã‚¹ãƒ•ァイル \"%s\" を読込ã‚ã¾ã›ã‚“"
+
+#, c-format
+msgid "E618: file \"%s\" is not a PostScript resource file"
+msgstr "E618: ファイル \"%s\" 㯠PostScript リソースファイルã§ã¯ã‚りã¾ã›ã‚“"
+
+#, c-format
+msgid "E619: file \"%s\" is not a supported PostScript resource file"
+msgstr "E619: ファイル \"%s\" ã¯å¯¾å¿œã—ã¦ã„ãªã„ PostScript リソースファイルã§ã™"
+
+#, c-format
+msgid "E621: \"%s\" resource file has wrong version"
+msgstr "E621: リソースファイル \"%s\" ã¯ãƒãƒ¼ã‚¸ãƒ§ãƒ³ãŒç•°ãªã‚Šã¾ã™"
+
+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ã®ãƒªã‚½ãƒ¼ã‚¹ãƒ•ァイル \"prolog.ps\" ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
+
+msgid "E456: Can't find PostScript resource file \"cidfont.ps\""
+msgstr "E456: PostScriptã®ãƒªã‚½ãƒ¼ã‚¹ãƒ•ァイル \"cidfont.ps\" ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
+
+#, c-format
+msgid "E456: Can't find PostScript resource file \"%s.ps\""
+msgstr "E456: PostScriptã®ãƒªã‚½ãƒ¼ã‚¹ãƒ•ァイル \"%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ã®èµ·å‹•準備(fork)ã«å¤±æ•—ã—ã¾ã—ãŸ"
+
+msgid "cs_create_connection setpgid failed"
+msgstr "cs_create_connection ã¸ã® setpgid ã«å¤±æ•—ã—ã¾ã—ãŸ"
+
+msgid "cs_create_connection exec failed"
+msgstr "cs_create_connection ã®å®Ÿè¡Œã«å¤±æ•—ã—ã¾ã—ãŸ"
+
+msgid "cs_create_connection: fdopen for to_fp failed"
+msgstr "cs_create_connection: to_fp ã® fdopen ã«å¤±æ•—ã—ã¾ã—ãŸ"
+
+msgid "cs_create_connection: fdopen for fr_fp failed"
+msgstr "cs_create_connection: fr_fp ã® fdopen ã«å¤±æ•—ã—ã¾ã—ãŸ"
+
+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 of %s ã«è©²å½“ãŒã‚りã¾ã›ã‚“ã§ã—ãŸ"
+
+msgid "cscope commands:\n"
+msgstr "cscopeコマンド:\n"
+
+#, c-format
+msgid "%-5s: %s%*s (Usage: %s)"
+msgstr "%-5s: %s%*s (使用法: %s)"
+
+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"
+
+#, 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データベースã¯è¿½åŠ ã•れã¾ã›ã‚“ã§ã—ãŸ"
+
+#, c-format
+msgid "E261: cscope connection %s not found"
+msgstr "E261: cscope接続 %s ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ"
+
+#, c-format
+msgid "cscope connection %s closed"
+msgstr "cscope接続 %s ãŒé–‰ã˜ã‚‰ã‚Œã¾ã—ãŸ"
+
+#. should not reach here
+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 データベースå prepend パス\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 "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ライブラリをロードã§ãã¾ã›ã‚“"
+"ã§ã—ãŸ."
+
+# 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 "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 "接続ã€ã§ã™"
+
+#, c-format
+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 "マークã¯è¨­å®šã•れã¦ã„ã¾ã›ã‚“"
+
+#, 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 ""
+"コールãƒãƒƒã‚¯ã‚³ãƒžãƒ³ãƒ‰ã‚’登録ã§ãã¾ã›ã‚“: ãƒãƒƒãƒ•ã‚¡/ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ãŒæ—¢ã«æ¶ˆåŽ»ã•れã¾ã—ãŸ"
+
+#. This should never happen. Famous last word?
+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 実体ã®ç™»éŒ²ãƒ—ロパティãŒä¸æ­£ã§ã™. 消去ã—ã¾ã—ãŸ!"
+
+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 "無効ãªå¼•æ•°ã§ã™: "
+
+#, 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 "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 "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: エラー: NetBeansã‹ã‚‰gvimをスタートã§ãã¾ã›ã‚“\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"
+
+#. just in case..
+msgid "pre-vimrc command line"
+msgstr "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 "- 標準入力ã‹ã‚‰ãƒ†ã‚­ã‚¹ãƒˆã‚’読込む"
+
+msgid "-t tag edit file where tag is defined"
+msgstr "-t ã‚¿ã‚° ã‚¿ã‚°ãŒå®šç¾©ã•れãŸã¨ã“ã‚ã‹ã‚‰ç·¨é›†ã™ã‚‹"
+
+msgid "-q [errorfile] edit file with first error"
+msgstr "-q [errorfile] 最åˆã®ã‚¨ãƒ©ãƒ¼ã§ç·¨é›†ã™ã‚‹"
+
+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\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\" ã¨åŒã˜)"
+
+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サイレント(ãƒãƒƒãƒ)モード (\"ex\" 専用)"
+
+msgid "-d\t\t\tDiff mode (like \"vimdiff\")"
+msgstr "-d\t\t\t差分モード (\"vidiff\" ã¨åŒã˜)"
+
+msgid "-y\t\t\tEasy mode (like \"evim\", modeless)"
+msgstr "-y\t\t\tイージーモード (\"evim\" ã¨åŒã˜, モード無)"
+
+msgid "-R\t\t\tReadonly mode (like \"view\")"
+msgstr "-R\t\t\t読込専用モード (\"view\" ã¨åŒã˜)"
+
+msgid "-Z\t\t\tRestricted mode (like \"rvim\")"
+msgstr "-Z\t\t\t制é™ãƒ¢ãƒ¼ãƒ‰ (\"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\tVi互æ›ãƒ¢ãƒ¼ãƒ‰: 'compatible'"
+
+msgid "-N\t\t\tNot fully Vi compatible: 'nocompatible'"
+msgstr "-N\t\t\tViéžäº’æ›ãƒ¢ãƒ¼ãƒ‰: '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\tデãƒãƒƒã‚°ãƒ¢ãƒ¼ãƒ‰"
+
+msgid "-n\t\t\tNo swap file, use memory only"
+msgstr "-n\t\t\tスワップファイルを使用ã›ãšãƒ¡ãƒ¢ãƒªã ã‘"
+
+msgid "-r\t\t\tList swap files and exit"
+msgstr "-r\t\t\tスワップファイルを列挙ã—終了"
+
+msgid "-r (with file name)\tRecover crashed session"
+msgstr "-r (ファイルå)\tクラッシュã—ãŸã‚»ãƒƒã‚·ãƒ§ãƒ³ã‚’復帰"
+
+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ウィンドウを開ãã®ã« 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アラビア語モードã§èµ·å‹•ã™ã‚‹"
+
+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 <terminal>\t端末を <terminal> ã«è¨­å®šã™ã‚‹"
+
+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\tN 個タブページを開ã(çœç•¥å€¤: ファイルã«ã¤ã1個)"
+
+msgid "-o[N]\t\tOpen N windows (default: one for each file)"
+msgstr "-o[N]\t\tN 個ウィンドウを開ã(çœç•¥å€¤: ファイルã«ã¤ã1個)"
+
+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 "+<lnum>\t\t<lnum> 行ã‹ã‚‰ã¯ã˜ã‚ã‚‹"
+
+msgid "--cmd <command>\tExecute <command> before loading any vimrc file"
+msgstr "--cmd <command>\tvimrcをロードã™ã‚‹å‰ã« <command> を実行ã™ã‚‹"
+
+msgid "-c <command>\t\tExecute <command> after loading the first file"
+msgstr "-c <command>\t\t最åˆã®ãƒ•ァイルをロード後 <command> を実行ã™ã‚‹"
+
+msgid "-S <session>\t\tSource file <session> after loading the first file"
+msgstr "-S <session>\t\t最åˆã®ãƒ•ァイルをロード後ファイル <session> ã‚’å–込む"
+
+msgid "-s <scriptin>\tRead Normal mode commands from file <scriptin>"
+msgstr "-s <scriptin>\tファイル <scriptin> ã‹ã‚‰ãƒŽãƒ¼ãƒžãƒ«ã‚³ãƒžãƒ³ãƒ‰ã‚’読込む"
+
+msgid "-w <scriptout>\tAppend all typed commands to file <scriptout>"
+msgstr "-w <scriptout>\t入力ã—ãŸå…¨ã‚³ãƒžãƒ³ãƒ‰ã‚’ファイル <scriptout> ã«è¿½åŠ ã™ã‚‹"
+
+msgid "-W <scriptout>\tWrite all typed commands to file <scriptout>"
+msgstr "-W <scriptout>\t入力ã—ãŸå…¨ã‚³ãƒžãƒ³ãƒ‰ã‚’ファイル <scriptout> ã«ä¿å­˜ã™ã‚‹"
+
+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> ã¸å‡ºåŠ›ã™ã‚‹"
+
+msgid "-i <viminfo>\t\tUse <viminfo> instead of .viminfo"
+msgstr "-i <viminfo>\t\t.viminfoã®ä»£ã‚り㫠<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 <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 "ディスプレイãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
+
+#. Failed to send, abort.
+msgid ": Send failed.\n"
+msgstr ": é€ä¿¡ã«å¤±æ•—ã—ã¾ã—ãŸ.\n"
+
+#. Let vim start normally.
+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\" ã«è©²å½“ã™ã‚‹ãƒžãƒ¼ã‚¯ãŒã‚りã¾ã›ã‚“"
+
+#. Highlight title
+msgid ""
+"\n"
+"mark line col file/text"
+msgstr ""
+"\n"
+"mark 行 列 ファイル/テキスト"
+
+#. Highlight title
+msgid ""
+"\n"
+" jump line col file/text"
+msgstr ""
+"\n"
+" jump 行 列 ファイル/テキスト"
+
+#. Highlight title
+msgid ""
+"\n"
+"change line col text"
+msgstr ""
+"\n"
+"変更 行 列 テキスト"
+
+msgid ""
+"\n"
+"# File marks:\n"
+msgstr ""
+"\n"
+"# ファイルマーク:\n"
+
+#. Write the jumplist with -'
+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: インプットメソッド㯠my preedit type をサãƒãƒ¼ãƒˆã—ã¾ã›ã‚“"
+
+msgid "E293: block was not locked"
+msgstr "E293: ブロックãŒãƒ­ãƒƒã‚¯ã•れã¦ã„ã¾ã›ã‚“"
+
+msgid "E294: Seek error in swap file read"
+msgstr "E294: スワップファイル読込時ã«ã‚·ãƒ¼ã‚¯ã‚¨ãƒ©ãƒ¼ã§ã™"
+
+msgid "E295: Read error in swap file"
+msgstr "E295: スワップファイルã®èª­è¾¼ã¿ã‚¨ãƒ©ãƒ¼ã§ã™"
+
+msgid "E296: Seek error in swap file write"
+msgstr "E296: ã‚¹ãƒ¯ãƒƒãƒ—ãƒ•ã‚¡ã‚¤ãƒ«æ›¸è¾¼ã¿æ™‚ã«ã‚·ãƒ¼ã‚¯ã‚¨ãƒ©ãƒ¼ã§ã™"
+
+msgid "E297: Write error in swap file"
+msgstr "E297: ã‚¹ãƒ¯ãƒƒãƒ—ãƒ•ã‚¡ã‚¤ãƒ«ã®æ›¸è¾¼ã¿ã‚¨ãƒ©ãƒ¼ã§ã™"
+
+msgid "E300: Swap file already exists (symlink attack?)"
+msgstr "E300: ã‚¹ãƒ¯ãƒƒãƒ—ãƒ•ã‚¡ã‚¤ãƒ«ãŒæ—¢ã«å­˜åœ¨ã—ã¾ã™ (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: ã‚¹ãƒ¯ãƒƒãƒ—ãƒ•ã‚¡ã‚¤ãƒ«ã®æš—å·ã‚’更新中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ"
+
+#. could not (re)open the swap file, what can we do????
+msgid "E301: Oops, lost the swap file!!!"
+msgstr "E301: ãŠã£ã¨, スワップファイルãŒå¤±ã‚れã¾ã—ãŸ!!!"
+
+msgid "E302: Could not rename swap file"
+msgstr "E302: スワップファイルã®åå‰ã‚’変ãˆã‚‰ã‚Œã¾ã›ã‚“"
+
+#, c-format
+msgid "E303: Unable to open swap file for \"%s\", recovery impossible"
+msgstr "E303: \"%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 ã«ã¯ã‚¹ãƒ¯ãƒƒãƒ—ファイルãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
+
+msgid "Enter number of swap file to use (0 to quit): "
+msgstr "使用ã™ã‚‹ã‚¹ãƒ¯ãƒƒãƒ—ファイルã®ç•ªå·ã‚’入力ã—ã¦ãã ã•ã„(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ãŒã‚¹ãƒ¯ãƒƒãƒ—ファイルを更新ã—ã¦ã„ã¾ã›ã‚“."
+
+msgid " cannot be used with this version of Vim.\n"
+msgstr " Vimã®ã“ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã§ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“.\n"
+
+msgid "Use Vim version 3.0.\n"
+msgstr "Vimã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³3.0を使用ã—ã¦ãã ã•ã„.\n"
+
+#, c-format
+msgid "E307: %s does not look like a Vim swap file"
+msgstr "E307: %s ã¯Vimã®ã‚¹ãƒ¯ãƒƒãƒ—ファイルã§ã¯ãªã„よã†ã§ã™"
+
+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 "スワップファイル \"%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 "ã‚¹ãƒ¯ãƒƒãƒ—ãƒ•ã‚¡ã‚¤ãƒ«ã¯æš—å·åŒ–ã•れã¦ã„ã¾ã™: \"%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 を読込ã‚ã¾ã›ã‚“"
+
+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: ブロック 1 ã®IDãŒé–“é•ã£ã¦ã„ã¾ã™(%s ãŒ.swpファイルã§ãªã„?)"
+
+msgid "???BLOCK MISSING"
+msgstr "???ブロックãŒã‚りã¾ã›ã‚“"
+
+msgid "??? from here until ???END lines may be messed up"
+msgstr "??? ã“ã“ã‹ã‚‰ ???END ã¾ã§ã®è¡ŒãŒç ´å£Šã•れã¦ã„るよã†ã§ã™"
+
+msgid "??? from here until ???END lines may have been inserted/deleted"
+msgstr "??? ã“ã“ã‹ã‚‰ ???END ã¾ã§ã®è¡ŒãŒæŒ¿å…¥ã‹å‰Šé™¤ã•れãŸã‚ˆã†ã§ã™"
+
+msgid "???END"
+msgstr "???END"
+
+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 "リカãƒãƒªãŒçµ‚了ã—ã¾ã—ãŸ. å…¨ã¦ãŒæ­£ã—ã„ã‹ãƒã‚§ãƒƒã‚¯ã—ã¦ãã ã•ã„."
+
+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 "スワップファイルã‹ã‚‰å–å¾—ã—ãŸæš—å·ã‚­ãƒ¼ã‚’テキストファイルã«ä½¿ã„ã¾ã™.\n"
+
+#. use msg() to start the scrolling properly
+msgid "Swap files found:"
+msgstr "スワップファイルãŒè¤‡æ•°è¦‹ã¤ã‹ã‚Šã¾ã—ãŸ:"
+
+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 " [from Vim version 3.0]"
+
+msgid " [does not look like a Vim swap file]"
+msgstr " [Vimã®ã‚¹ãƒ¯ãƒƒãƒ—ファイルã§ã¯ãªã„よã†ã§ã™]"
+
+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"
+" プロセスID: "
+
+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: スワップファイルãŒç„¡ã„ã®ã§ç¶­æŒã§ãã¾ã›ã‚“"
+
+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: ãƒã‚¤ãƒ³ã‚¿ãƒ–ロックã®IDãŒé–“é•ã£ã¦ã„ã¾ã™ 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: ãƒã‚¤ãƒ³ã‚¿ãƒ–ロックã®IDãŒé–“é•ã£ã¦ã„ã¾ã™ 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: ãƒã‚¤ãƒ³ã‚¿ãƒ–ロックã®IDãŒé–“é•ã£ã¦ã„ã¾ã™"
+
+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: ãƒã‚¤ãƒ³ã‚¿ãƒ–ロックã®IDãŒé–“é•ã£ã¦ã„ã¾ã™ 2"
+
+#, c-format
+msgid "E773: Symlink loop for \"%s\""
+msgstr "E773: \"%s\" ã®ã‚·ãƒ³ãƒœãƒªãƒƒã‚¯ãƒªãƒ³ã‚¯ãŒãƒ«ãƒ¼ãƒ—ã«ãªã£ã¦ã„ã¾ã™"
+
+msgid "E325: ATTENTION"
+msgstr "E325: 注æ„"
+
+msgid ""
+"\n"
+"Found a swap file by the name \""
+msgstr ""
+"\n"
+"次ã®åå‰ã§ã‚¹ãƒ¯ãƒƒãƒ—ファイルを見ã¤ã‘ã¾ã—㟠\""
+
+msgid "While opening file \""
+msgstr "次ã®ãƒ•ァイルを開ã„ã¦ã„る最中 \""
+
+msgid " NEWER than swap file!\n"
+msgstr " スワップファイルよりも新ã—ã„ã§ã™!\n"
+
+#. 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."
+msgstr ""
+"\n"
+"(1) 別ã®ãƒ—ログラムãŒåŒã˜ãƒ•ァイルを編集ã—ã¦ã„ã‚‹ã‹ã‚‚ã—れã¾ã›ã‚“.\n"
+" ã“ã®å ´åˆã«ã¯, 変更をã—ãŸéš›ã«æœ€çµ‚çš„ã«, åŒã˜ãƒ•ァイルã®ç•°ãªã‚‹\n"
+" 2ã¤ã®ã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹ãŒã§ãã¦ã—ã¾ã†ã“ã¨ã«æ³¨æ„ã—ã¦ãã ã•ã„."
+
+msgid " Quit, or continue with caution.\n"
+msgstr " 終了ã™ã‚‹ã‹, 注æ„ã—ãªãŒã‚‰ç¶šã‘ã¦ãã ã•ã„.\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 " æ—¢ã«ã“れを行ãªã£ãŸã®ãªã‚‰ã°, スワップファイル \""
+
+msgid ""
+"\"\n"
+" to avoid this message.\n"
+msgstr ""
+"\"\n"
+" を消ã›ã°ã“ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’回é¿ã§ãã¾ã™.\n"
+
+msgid "Swap file \""
+msgstr "スワップファイル \""
+
+msgid "\" already exists!"
+msgstr "\" ãŒæ—¢ã«ã‚りã¾ã™!"
+
+msgid "VIM - ATTENTION"
+msgstr "VIM - 注æ„"
+
+msgid "Swap file already exists!"
+msgstr "ã‚¹ãƒ¯ãƒƒãƒ—ãƒ•ã‚¡ã‚¤ãƒ«ãŒæ—¢ã«å­˜åœ¨ã—ã¾ã™!"
+
+msgid ""
+"&Open Read-Only\n"
+"&Edit anyway\n"
+"&Recover\n"
+"&Quit\n"
+"&Abort"
+msgstr ""
+"読込専用ã§é–‹ã(&O)\n"
+"ã¨ã«ã‹ã編集ã™ã‚‹(&E)\n"
+"復活ã•ã›ã‚‹(&R)\n"
+"終了ã™ã‚‹(&Q)\n"
+"中止ã™ã‚‹(&A)"
+
+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)"
+
+msgid "E326: Too many swap files found"
+msgstr "E326: スワップファイルãŒå¤šæ•°è¦‹ã¤ã‹ã‚Šã¾ã—ãŸ"
+
+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\" ã¨ã„ã†ãƒ¡ãƒ‹ãƒ¥ãƒ¼ã¯ã‚りã¾ã›ã‚“"
+
+#. Only a mnemonic or accelerator is not valid.
+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: 区切りã¯ãƒ¡ãƒ‹ãƒ¥ãƒ¼ãƒ‘スã®ä¸€éƒ¨ã§ã¯ã‚りã¾ã›ã‚“"
+
+#. Now we have found the matching menu, and we list the mappings
+#. Highlight title
+msgid ""
+"\n"
+"--- Menus ---"
+msgstr ""
+"\n"
+"--- メニュー ---"
+
+msgid "Tear off this menu"
+msgstr "ã“ã®ãƒ¡ãƒ‹ãƒ¥ãƒ¼ã‚’切りå–ã‚‹"
+
+msgid "E333: Menu path must lead to a menu item"
+msgstr "E333: メニューパスã¯ãƒ¡ãƒ‹ãƒ¥ãƒ¼ã‚¢ã‚¤ãƒ†ãƒ ã‚’生ã˜ãªã‘れã°ã„ã‘ã¾ã›ã‚“"
+
+#, c-format
+msgid "E334: Menu not found: %s"
+msgstr "E334: メニューãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“: %s"
+
+#, c-format
+msgid "E335: Menu not defined for %s mode"
+msgstr "E335: %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 "日本語メッセージ翻訳/監修: æ‘岡 太郎 <koron.kaoriya@gmail.com>"
+
+msgid "Interrupt: "
+msgstr "割込ã¿: "
+
+msgid "Press ENTER or type command to continue"
+msgstr "ç¶šã‘ã‚‹ã«ã¯ENTERを押ã™ã‹ã‚³ãƒžãƒ³ãƒ‰ã‚’入力ã—ã¦ãã ã•ã„"
+
+#, 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 " SPACE/d/j: ç”»é¢/ページ/行 下, b/u/k: 上, q: 終了 "
+
+msgid "Question"
+msgstr "質å•"
+
+msgid ""
+"&Yes\n"
+"&No"
+msgstr ""
+"ã¯ã„(&Y)\n"
+"ã„ã„ãˆ(&N)"
+
+msgid ""
+"&Yes\n"
+"&No\n"
+"Save &All\n"
+"&Discard All\n"
+"&Cancel"
+msgstr ""
+"ã¯ã„(&Y)\n"
+"ã„ã„ãˆ(&N)\n"
+"å…¨ã¦ä¿å­˜(&A)\n"
+"å…¨ã¦æ”¾æ£„(&D)\n"
+"キャンセル(&C)"
+
+msgid "Select Directory dialog"
+msgstr "ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªé¸æŠžãƒ€ã‚¤ã‚¢ãƒ­ã‚°"
+
+msgid "Save File dialog"
+msgstr "ファイルä¿å­˜ãƒ€ã‚¤ã‚¢ãƒ­ã‚°"
+
+msgid "Open File dialog"
+msgstr "ファイル読込ダイアログ"
+
+#. TODO: non-GUI file selector here
+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: 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 "Vim: preserving files...\n"
+msgstr "Vim: ファイルをä¿å­˜ä¸­...\n"
+
+#. close all memfiles, without deleting
+msgid "Vim: Finished.\n"
+msgstr "Vim: 終了ã—ã¾ã—ãŸ.\n"
+
+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 "Enter encryption key: "
+msgstr "æš—å·åŒ–用ã®ã‚­ãƒ¼ã‚’入力ã—ã¦ãã ã•ã„: "
+
+msgid "Enter same key again: "
+msgstr "ã‚‚ã†ä¸€åº¦åŒã˜ã‚­ãƒ¼ã‚’入力ã—ã¦ãã ã•ã„: "
+
+msgid "Keys don't match!"
+msgstr "キーãŒä¸€è‡´ã—ã¾ã›ã‚“"
+
+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\" ã¨ã„ã†ãƒ•ァイルãŒã‚りã¾ã›ã‚“"
+
+msgid "Cannot connect to Netbeans #2"
+msgstr "Netbeans #2 ã«æŽ¥ç¶šã§ãã¾ã›ã‚“"
+
+msgid "Cannot connect to Netbeans"
+msgstr "Netbeans ã«æŽ¥ç¶šã§ãã¾ã›ã‚“"
+
+#, c-format
+msgid "E668: Wrong access mode for NetBeans connection info file: \"%s\""
+msgstr ""
+"E668: NetBeansã®æŽ¥ç¶šæƒ…å ±ãƒ•ã‚¡ã‚¤ãƒ«ã®ã‚¢ã‚¯ã‚»ã‚¹ãƒ¢ãƒ¼ãƒ‰ã«å•題ãŒã‚りã¾ã™: \"%s\""
+
+msgid "read from Netbeans socket"
+msgstr "Netbeans ã®ã‚½ã‚±ãƒƒãƒˆã‚’読込ã¿"
+
+#, 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: カーソルã®ä½ç½®ã«ã¯è­˜åˆ¥å­ãŒã‚りã¾ã›ã‚“"
+
+msgid "E774: 'operatorfunc' is empty"
+msgstr "E774: 'operatorfunc' オプションãŒç©ºã§ã™"
+
+msgid "E775: Eval feature not available"
+msgstr "E775: å¼è©•価機能ãŒç„¡åйã«ãªã£ã¦ã„ã¾ã™"
+
+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 :quit<Enter> to exit Vim"
+msgstr "Vimを終了ã™ã‚‹ã«ã¯ :quit<Enter> ã¨å…¥åŠ›ã—ã¦ãã ã•ã„"
+
+#, 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: ã¾ã ãƒ¬ã‚¸ã‚¹ã‚¿ã‚’使用ã—ã¦ã„ã¾ã›ã‚“"
+
+#. must display the prompt
+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 行を解放中"
+
+msgid "block of 1 line yanked"
+msgstr "1 行ã®ãƒ–ロックãŒãƒ¤ãƒ³ã‚¯ã•れã¾ã—ãŸ"
+
+msgid "1 line yanked"
+msgstr "1 行ãŒãƒ¤ãƒ³ã‚¯ã•れã¾ã—ãŸ"
+
+#, c-format
+msgid "block of %ld lines yanked"
+msgstr "%ld 行ã®ãƒ–ロックãŒãƒ¤ãƒ³ã‚¯ã•れã¾ã—ãŸ"
+
+#, c-format
+msgid "%ld lines yanked"
+msgstr "%ld 行ãŒãƒ¤ãƒ³ã‚¯ã•れã¾ã—ãŸ"
+
+#, c-format
+msgid "E353: Nothing in register %s"
+msgstr "E353: レジスタ %s ã«ã¯ä½•ã‚‚ã‚りã¾ã›ã‚“"
+
+#. Highlight title
+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 ã§ã™"
+
+#, c-format
+msgid "%ld Cols; "
+msgstr "%ld 列; "
+
+#, c-format
+msgid "Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Bytes"
+msgstr "é¸æŠž %s%ld / %ld 行; %ld / %ld å˜èªž; %ld / %ld ãƒã‚¤ãƒˆ"
+
+#, c-format
+msgid ""
+"Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Chars; %ld of %ld "
+"Bytes"
+msgstr "é¸æŠž %s%ld / %ld 行; %ld / %ld å˜èªž; %ld / %ld 文字; %ld / %ld ãƒã‚¤ãƒˆ"
+
+#, c-format
+msgid "Col %s of %s; Line %ld of %ld; Word %ld of %ld; Byte %ld of %ld"
+msgstr "列 %s / %s; 行 %ld of %ld; å˜èªž %ld / %ld; ãƒã‚¤ãƒˆ %ld / %ld"
+
+#, c-format
+msgid ""
+"Col %s of %s; Line %ld of %ld; Word %ld of %ld; Char %ld of %ld; Byte %ld of "
+"%ld"
+msgstr ""
+"列 %s / %s; 行 %ld / %ld; å˜èªž %ld / %ld; 文字 %ld / %ld; ãƒã‚¤ãƒˆ %ld of %ld"
+
+#, c-format
+msgid "(+%ld for BOM)"
+msgstr "(+%ld for BOM)"
+
+msgid "%<%f%h%m%=Page %N"
+msgstr "%<%f%h%m%=%N ページ"
+
+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: modeline ã§ã¯è¨±å¯ã•れã¾ã›ã‚“"
+
+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>"
+
+msgid "E529: Cannot set 'term' to empty string"
+msgstr "E529: 'term' ã«ã¯ç©ºæ–‡å­—列を設定ã§ãã¾ã›ã‚“"
+
+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' ãŒåŒã˜ã§ã™"
+
+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ã§ã¯å¤‰æ›´ã§ãã¾ã›ã‚“"
+
+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: ãƒ•ã‚©ãƒ³ãƒˆã‚»ãƒƒãƒˆã‚’é¸æŠžã§ãã¾ã›ã‚“"
+
+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> ã®å¾Œã«ä¸æ­£ãªæ–‡å­—ãŒã‚りã¾ã™"
+
+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 "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' ã—ã¦ãã ã•ã„"
+
+#, 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"
+
+#. 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.
+#, 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"
+
+#. if Vim opened a window: Executing a shell may cause crashes
+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: プリンタã®é¸æŠžã«å¤±æ•—ã—ã¾ã—ãŸ"
+
+#, 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 "E245: Illegal char '%c' in font name \"%s\""
+msgstr "E245: '%c' ã¯ä¸æ­£ãªæ–‡å­—ã§ã™ (フォントå \"%s\")"
+
+msgid "Vim: Double signal, exiting\n"
+msgstr "Vim: 2é‡ã®ã‚·ã‚°ãƒŠãƒ«ã®ãŸã‚, 終了ã—ã¾ã™\n"
+
+#, c-format
+msgid "Vim: Caught deadly signal %s\n"
+msgstr "Vim: 致命的シグナル %s を検知ã—ã¾ã—ãŸ\n"
+
+#, c-format
+msgid "Vim: Caught deadly signal\n"
+msgstr "Vim: 致命的シグナルを検知ã—ã¾ã—ãŸ\n"
+
+#, c-format
+msgid "Opening the X display took %ld msec"
+msgstr "Xサーãƒã¸ã®æŽ¥ç¶šã« %ld ミリ秒ã‹ã‹ã‚Šã¾ã—ãŸ"
+
+msgid ""
+"\n"
+"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 ãŒã‚¿ã‚¤ãƒ ã‚¢ã‚¦ãƒˆã—ã¾ã—ãŸ"
+
+msgid ""
+"\n"
+"Could not get security context for "
+msgstr ""
+"\n"
+"セキュリティコンテキストをå–å¾—ã§ãã¾ã›ã‚“ "
+
+msgid ""
+"\n"
+"Could not set security context for "
+msgstr ""
+"\n"
+"セキュリティコンテキストを設定ã§ãã¾ã›ã‚“ "
+
+msgid ""
+"\n"
+"Cannot execute shell "
+msgstr ""
+"\n"
+"シェルを実行ã§ãã¾ã›ã‚“ "
+
+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"
+"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 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 "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 "shell returned %d"
+msgstr "シェルãŒã‚³ãƒ¼ãƒ‰ %d ã§çµ‚了ã—ã¾ã—ãŸ"
+
+#, 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 "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: è¦ç´ ãŒã‚‚ã†ã‚りã¾ã›ã‚“"
+
+#, c-format
+msgid "(%d of %d)%s%s: "
+msgstr "(%d of %d)%s%s: "
+
+msgid " (line deleted)"
+msgstr " (行ãŒå‰Šé™¤ã•れã¾ã—ãŸ)"
+
+msgid "E380: At bottom of quickfix stack"
+msgstr "E380: quickfix ã‚¹ã‚¿ãƒƒã‚¯ã®æœ«å°¾ã§ã™"
+
+msgid "E381: At top of quickfix stack"
+msgstr "E381: quickfix スタックã®å…ˆé ­ã§ã™"
+
+#, c-format
+msgid "error list %d of %d; %d errors"
+msgstr "エラー一覧 %d of %d; %d 個エラー"
+
+msgid "E382: Cannot write, 'buftype' option is set"
+msgstr "E382: 'buftype' オプションãŒè¨­å®šã•れã¦ã„ã‚‹ã®ã§æ›¸è¾¼ã¿ã¾ã›ã‚“"
+
+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: 文字列ã‹ãƒªã‚¹ãƒˆãŒå¿…è¦ã§ã™"
+
+#, c-format
+msgid "E369: invalid item in %s%%[]"
+msgstr "E369: 無効ãªé …ç›®ã§ã™: %s%%[]"
+
+#
+#, c-format
+msgid "E769: Missing ] after %s["
+msgstr "E769: %s[ ã®å¾Œã« ] ãŒã‚りã¾ã›ã‚“"
+
+#, 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 et al. not allowed here"
+msgstr "E67: \\z1 ãã®ä»–ã¯ã‚³ã‚³ã§ã¯è¨±å¯ã•れã¦ã„ã¾ã›ã‚“"
+
+#
+#, c-format
+msgid "E69: Missing ] after %s%%["
+msgstr "E69: %s%%[ ã®å¾Œã« ] ãŒã‚りã¾ã›ã‚“"
+
+#, c-format
+msgid "E70: Empty %s%%[]"
+msgstr "E70: %s%%[] ãŒç©ºã§ã™"
+
+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{...} ãŒå¤šéŽãŽã¾ã™"
+
+#, 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 ã®å¾Œã«ãªã«ã‚‚ã‚りã¾ã›ã‚“"
+
+#
+msgid "E65: Illegal back reference"
+msgstr "E65: 䏿­£ãªå¾Œæ–¹å‚ç…§ã§ã™"
+
+#
+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"
+
+msgid ""
+"E864: \\%#= can only be followed by 0, 1, or 2. The automatic engine will be "
+"used "
+msgstr ""
+"E864: \\%#= ã«ã¯ 0, 1 ã‚‚ã—ã㯠2 ã®ã¿ãŒç¶šã‘られã¾ã™ã€‚"
+"æ­£è¦è¡¨ç¾ã‚¨ãƒ³ã‚¸ãƒ³ã¯è‡ªå‹•é¸æŠžã•れã¾ã™ã€‚"
+
+#, c-format
+msgid "E866: (NFA regexp) Misplaced %c"
+msgstr "E866: (NFA æ­£è¦è¡¨ç¾) ä½ç½®ãŒèª¤ã£ã¦ã„ã¾ã™: %c"
+
+msgid "E865: (NFA) Regexp end encountered prematurely"
+msgstr "E865: (NFA) æœŸå¾…ã‚ˆã‚Šæ—©ãæ­£è¦è¡¨ç¾ã®çµ‚端ã«åˆ°é”ã—ã¾ã—ãŸ"
+
+#, c-format
+msgid "E867: (NFA) Unknown operator '\\z%c'"
+msgstr "E867: (NFA) 未知ã®ã‚ªãƒšãƒ¬ãƒ¼ã‚¿ã§ã™: '\\z%c'"
+
+#, c-format
+msgid "E867: (NFA) Unknown operator '\\%%%c'"
+msgstr "E867: (NFA) 未知ã®ã‚ªãƒšãƒ¬ãƒ¼ã‚¿ã§ã™: '\\%%%c'"
+
+#. should never happen
+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 æ­£è¦è¡¨ç¾) 繰り返ã—ã®åˆ¶é™å›žæ•°ã‚’読込中ã«ã‚¨ãƒ©ãƒ¼"
+
+#. Can't have a multi follow a multi.
+msgid "E871: (NFA regexp) Can't have a multi follow a multi !"
+msgstr "E871: (NFA æ­£è¦è¡¨ç¾) 繰り返㗠ã®å¾Œã« 繰り返㗠ã¯ã§ãã¾ã›ã‚“!"
+
+#. Too many `('
+msgid "E872: (NFA regexp) Too many '('"
+msgstr "E872: (NFA æ­£è¦è¡¨ç¾) '(' ãŒå¤šéŽãŽã¾ã™"
+
+msgid "E879: (NFA regexp) Too many \\z("
+msgstr "E879: (NFA æ­£è¦è¡¨ç¾) \\z( ãŒå¤šéŽãŽã¾ã™"
+
+msgid "E873: (NFA regexp) proper termination error"
+msgstr "E873: (NFA æ­£è¦è¡¨ç¾) 終端記å·ãŒã‚りã¾ã›ã‚“"
+
+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 æ­£è¦è¡¨ç¾) (後置文字列をNFAã«å¤‰æ›ä¸­ã«) "
+"ã‚¹ã‚¿ãƒƒã‚¯ã«æ®‹ã•れãŸã‚¹ãƒ†ãƒ¼ãƒˆãŒå¤šéŽãŽã¾ã™"
+
+msgid "E876: (NFA regexp) Not enough space to store the whole NFA "
+msgstr "E876: (NFA æ­£è¦è¡¨ç¾) 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 "NFAæ­£è¦è¡¨ç¾ã‚¨ãƒ³ã‚¸ãƒ³ç”¨ã®ãƒ­ã‚°ãƒ•ァイルを書込用ã¨ã—ã¦é–‹ã‘ã¾ã›ã‚“。"
+"ãƒ­ã‚°ã¯æ¨™æº–出力ã«å‡ºåŠ›ã—ã¾ã™ã€‚"
+
+#, c-format
+msgid "(NFA) COULD NOT OPEN %s !"
+msgstr "(NFA) ログファイル %s ã‚’é–‹ã‘ã¾ã›ã‚“!"
+
+msgid "Could not open temporary log file for writing "
+msgstr "NFAæ­£è¦è¡¨ç¾ã‚¨ãƒ³ã‚¸ãƒ³ç”¨ã®ãƒ­ã‚°ãƒ•ァイルを書込用ã¨ã—ã¦é–‹ã‘ã¾ã›ã‚“。"
+
+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 " (lang)"
+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 " (å‰ã«åˆ—挙ã—ãŸè©²å½“箇所をå«ã‚€)"
+
+#. cursor at status line
+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 "Substitute "
+
+#, c-format
+msgid ""
+"\n"
+"# Last %sSearch Pattern:\n"
+"~"
+msgstr ""
+"\n"
+"# 最後㮠%s検索パターン:\n"
+"~"
+
+msgid "E759: Format error in spell file"
+msgstr "E759: ã‚¹ãƒšãƒ«ãƒ•ã‚¡ã‚¤ãƒ«ã®æ›¸å¼ã‚¨ãƒ©ãƒ¼ã§ã™"
+
+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 行目) ã® affix åãŒé•·éŽãŽã¾ã™: %s"
+
+msgid "E761: Format error in affix file FOL, LOW or UPP"
+msgstr ""
+"E761: affixファイル㮠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 "å˜èªžãƒ„リーを圧縮ã—ã¦ã„ã¾ã™..."
+
+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\" ã¯è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
+
+#, 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 "Warning: region %s not supported"
+msgstr "警告9: %s ã¨ã„ã†ç¯„囲ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“"
+
+#, c-format
+msgid "Reading affix file %s ..."
+msgstr "affix ファイル %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 "%s 内㮠%d 行目㮠FLAG ã«ç„¡åйãªå€¤ãŒã‚りã¾ã™: %s"
+
+#, c-format
+msgid "FLAG after using flags in %s line %d: %s"
+msgstr "%s 内㮠%d 行目ã«ãƒ•ラグã®äºŒé‡ä½¿ç”¨ãŒã‚りã¾ã™: %s"
+
+#, c-format
+msgid ""
+"Defining COMPOUNDFORBIDFLAG after PFX item may give wrong results in %s line "
+"%d"
+msgstr ""
+"%s ã® %d 行目㮠PFX é …ç›®ã®å¾Œã® COMPOUNDFORBIDFLAG ã®å®šç¾©ã¯èª¤ã£ãŸçµæžœã‚’生ã˜ã‚‹"
+"ã“ã¨ãŒã‚りã¾ã™"
+
+#, c-format
+msgid ""
+"Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in %s line "
+"%d"
+msgstr ""
+"%s ã® %d 行目㮠PFX é …ç›®ã®å¾Œã® COMPOUNDPERMITFLAG ã®å®šç¾©ã¯èª¤ã£ãŸçµæžœã‚’生ã˜ã‚‹"
+"ã“ã¨ãŒã‚りã¾ã™"
+
+#, 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 "%s ã® %d 行目㮠COMPOUNDWORDMAX ã®å€¤ã«èª¤ã‚ŠãŒã‚りã¾ã™: %s"
+
+#, c-format
+msgid "Wrong COMPOUNDMIN value in %s line %d: %s"
+msgstr "%s ã® %d 行目㮠COMPOUNDMIN ã®å€¤ã«èª¤ã‚ŠãŒã‚りã¾ã™: %s"
+
+#, c-format
+msgid "Wrong COMPOUNDSYLMAX value in %s line %d: %s"
+msgstr "%s ã® %d 行目㮠COMPOUNDSYLMAX ã®å€¤ã«èª¤ã‚ŠãŒã‚りã¾ã™: %s"
+
+#, c-format
+msgid "Wrong CHECKCOMPOUNDPATTERN value in %s line %d: %s"
+msgstr "%s ã® %d 行目㮠CHECKCOMPOUNDPATTERN ã®å€¤ã«èª¤ã‚ŠãŒã‚りã¾ã™: %s"
+
+#, c-format
+msgid "Different combining flag in continued affix block in %s line %d: %s"
+msgstr ""
+"%s ã® %d 行目㮠連続 affix ブロックã®ãƒ•ラグã®çµ„åˆã›ã«é•ã„ãŒã‚りã¾ã™: %s"
+
+#, c-format
+msgid "Duplicate affix in %s line %d: %s"
+msgstr "%s ã® %d 行目㫠é‡è¤‡ã—㟠affix を検出ã—ã¾ã—ãŸ: %s"
+
+#, c-format
+msgid ""
+"Affix also used for BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST in %s "
+"line %d: %s"
+msgstr ""
+"%s 㮠%d 行目㮠affix 㯠BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST "
+"ã«ä½¿ç”¨ã—ã¦ãã ã•ã„: %s"
+
+#, c-format
+msgid "Expected Y or N in %s line %d: %s"
+msgstr "%s ã® %d 行目ã§ã¯ Y ã‹ N ãŒå¿…è¦ã§ã™: %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 "%s ã® %d 行目ã«ã¯ REP(SAL) ã®å›žæ•°ãŒå¿…è¦ã§ã™"
+
+#, c-format
+msgid "Expected MAP count in %s line %d"
+msgstr "%s ã® %d 行目ã«ã¯ MAP ã®å›žæ•°ãŒå¿…è¦ã§ã™"
+
+#, c-format
+msgid "Duplicate character in MAP in %s line %d"
+msgstr "%s ã® %d 行目㮠MAP ã«é‡è¤‡ã—ãŸæ–‡å­—ãŒã‚りã¾ã™"
+
+#, 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 "%s 行目㫠FOL/LOW/UPP ãŒã‚りã¾ã›ã‚“"
+
+msgid "COMPOUNDSYLMAX used without SYLLABLE"
+msgstr "SYLLABLE ãŒæŒ‡å®šã•れãªã„ COMPOUNDSYLMAX"
+
+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 %6d - %s"
+msgstr "行 %6d, å˜èªž %6d - %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 "éžASCII文字をå«ã‚€ %d 個ã®å˜èªžã‚’無視ã—ã¾ã—㟠(%s 内)"
+
+#, c-format
+msgid "Reading word file %s ..."
+msgstr "標準入力ã‹ã‚‰èª­è¾¼ã¿ä¸­ %s ..."
+
+#, c-format
+msgid "Duplicate /encoding= line ignored in %s line %d: %s"
+msgstr "%s ã® %d 行目㮠é‡è¤‡ã—㟠/encoding= 行を無視ã—ã¾ã—ãŸ: %s"
+
+#, c-format
+msgid "/encoding= line after word ignored in %s line %d: %s"
+msgstr "%s ã® %d 行目㮠å˜èªžã®å¾Œã® /encoding= 行を無視ã—ã¾ã—ãŸ: %s"
+
+#, c-format
+msgid "Duplicate /regions= line ignored in %s line %d: %s"
+msgstr "%s ã® %d 行目㮠é‡è¤‡ã—㟠/regions= 行を無視ã—ã¾ã—ãŸ: %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 行目 無効㪠nr 領域ã§ã™: %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 "éžASCII文字をå«ã‚€ %d 個ã®å˜èªžã‚’無視ã—ã¾ã—ãŸ"
+
+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 "スペルファイルを逆読込中"
+
+#.
+#. * Go through the trie of good words, soundfold each word and add it to
+#. * the soundfold trie.
+#.
+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: 出力ファイルåã«ã¯ç¯„囲åã‚’å«ã‚られã¾ã›ã‚“"
+
+msgid "E754: Only up to 8 regions supported"
+msgstr "E754: 範囲㯠8 個ã¾ã§ã—ã‹ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“"
+
+#, 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 removed from %s"
+msgstr "%s ã‹ã‚‰å˜èªžãŒå‰Šé™¤ã•れã¾ã—ãŸ"
+
+#, c-format
+msgid "Word added to %s"
+msgstr "%s ã«å˜èªžãŒè¿½åŠ ã•れã¾ã—ãŸ"
+
+msgid "E763: Word characters differ between spell files"
+msgstr "E763: å˜èªžã®æ–‡å­—ãŒã‚¹ãƒšãƒ«ãƒ•ァイルã¨ç•°ãªã‚Šã¾ã™"
+
+msgid "Sorry, no suggestions"
+msgstr "残念ã§ã™ãŒ, 修正候補ã¯ã‚りã¾ã›ã‚“"
+
+#, c-format
+msgid "Sorry, only %ld suggestions"
+msgstr "残念ã§ã™ãŒ, 修正候補㯠%ld 個ã—ã‹ã‚りã¾ã›ã‚“"
+
+#. for when 'cmdheight' > 1
+#. avoid more prompt
+#, 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"
+
+#, 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: より新ã—ã„ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã® 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"
+
+#. This should have been checked when generating the .spl
+#. * file.
+msgid "E783: duplicate char in MAP entry"
+msgstr "E783: MAP エントリã«é‡è¤‡æ–‡å­—ãŒå­˜åœ¨ã—ã¾ã™"
+
+msgid "No Syntax items defined for this buffer"
+msgstr "ã“ã®ãƒãƒƒãƒ•ã‚¡ã«å®šç¾©ã•ã‚ŒãŸæ§‹æ–‡è¦ç´ ã¯ã‚りã¾ã›ã‚“"
+
+#, c-format
+msgid "E390: Illegal argument: %s"
+msgstr "E390: 䏿­£ãªå¼•æ•°ã§ã™: %s"
+
+#, 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 "minimal "
+
+msgid "maximal "
+msgstr "maximal "
+
+msgid "; match "
+msgstr "; 該当 "
+
+msgid " line breaks"
+msgstr " å€‹ã®æ”¹è¡Œ"
+
+msgid "E395: contains argument not accepted here"
+msgstr "E395: ã“ã®å ´æ‰€ã§ã¯å¼•æ•°containsã¯è¨±å¯ã•れã¦ã„ã¾ã›ã‚“"
+
+msgid "E844: invalid cchar value"
+msgstr "E844: 無効ãªccharã®å€¤ã§ã™"
+
+msgid "E393: group[t]here not accepted here"
+msgstr "E393: ã“ã“ã§ã¯ã‚°ãƒ«ãƒ¼ãƒ—ã¯è¨±å¯ã•れã¾ã›ã‚“"
+
+#, 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: æ§‹æ–‡ã®å–り込ã¿(include)ãŒå¤šéŽãŽã¾ã™"
+
+#, c-format
+msgid "E789: Missing ']': %s"
+msgstr "E789: ']' ãŒã‚りã¾ã›ã‚“: %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: æ§‹æ–‡åŒæœŸ: 連続行パターンãŒ2度指定ã•れã¾ã—ãŸ"
+
+#, 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 ã¯å†…容リストã®å…ˆé ­ã§ãªã‘れã°ãªã‚‰ãªã„"
+
+#, 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 ""
+" TOTAL COUNT MATCH SLOWEST AVERAGE NAME PATTERN"
+
+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: グループãŒè¨­å®šã•れã¦ã„ã‚‹ã®ã§ãƒã‚¤ãƒ©ã‚¤ãƒˆãƒªãƒ³ã‚¯ã¯ç„¡è¦–ã•れã¾ã™"
+
+#, 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: 未知ã®å‰æ™¯è‰²ã§ã™"
+
+msgid "E420: BG color unknown"
+msgstr "E420: 未知ã®èƒŒæ™¯è‰²ã§ã™"
+
+#, 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 kind tag"
+
+msgid "file\n"
+msgstr "ファイル\n"
+
+msgid "E427: There is only one matching tag"
+msgstr "E427: 該当タグãŒ1ã¤ã ã‘ã—ã‹ã‚りã¾ã›ã‚“"
+
+msgid "E428: Cannot go beyond last matching tag"
+msgstr "E428: 最後ã«è©²å½“ã™ã‚‹ã‚¿ã‚°ã‚’è¶…ãˆã¦é€²ã‚€ã“ã¨ã¯ã§ãã¾ã›ã‚“"
+
+#, c-format
+msgid "File \"%s\" does not exist"
+msgstr "ファイル \"%s\" ãŒã‚りã¾ã›ã‚“"
+
+#. Give an indication of the number of matching tags
+#, c-format
+msgid "tag %d of %d%s"
+msgstr "ã‚¿ã‚° %d (å…¨%d%s)"
+
+msgid " or more"
+msgstr " ã‹ãれ以上"
+
+msgid " Using tag with different case!"
+msgstr " ã‚¿ã‚°ã‚’ç•°ãªã‚‹caseã§ä½¿ç”¨ã—ã¾ã™!"
+
+#, c-format
+msgid "E429: File \"%s\" does not exist"
+msgstr "E429: ファイル \"%s\" ãŒã‚りã¾ã›ã‚“"
+
+#. Highlight title
+msgid ""
+"\n"
+" # TO tag FROM line in file/text"
+msgstr ""
+"\n"
+" # TO タグ FROM 行 in file/text"
+
+#, 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"
+
+#. never opened any tags file
+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: termcapã« \"%s\" ã®ã‚¨ãƒ³ãƒˆãƒªãŒã‚りã¾ã›ã‚“"
+
+msgid "E437: terminal capability \"cm\" required"
+msgstr "E437: 端末㫠\"cm\" 機能ãŒå¿…è¦ã§ã™"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Terminal keys ---"
+msgstr ""
+"\n"
+"--- 端末キー ---"
+
+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ãŒä½¿ç”¨ã•れã¾ã—ãŸ"
+
+#. This happens when the FileChangedRO autocommand changes the
+#. * file in a way it becomes shorter.
+msgid "E834: Line count changed unexpectedly"
+msgstr "E834: 予期ã›ãšè¡Œã‚«ã‚¦ãƒ³ãƒˆãŒå¤‰ã‚りã¾ã—ãŸ"
+
+#. must display the prompt
+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: undo ã®ç›´å¾Œã« undojoin ã¯ã§ãã¾ã›ã‚“"
+
+msgid "E439: undo list corrupt"
+msgstr "E439: アンドゥリストãŒå£Šã‚Œã¦ã„ã¾ã™"
+
+msgid "E440: undo line missing"
+msgstr "E440: アンドゥ行ãŒã‚りã¾ã›ã‚“"
+
+#. Only MS VC 4.1 and earlier can do Win32s
+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"
+"Included patches: "
+msgstr ""
+"\n"
+"é©ç”¨æ¸ˆãƒ‘ッãƒ: "
+
+msgid ""
+"\n"
+"Extra patches: "
+msgstr ""
+"\n"
+"追加拡張パッãƒ: "
+
+msgid "Modified by "
+msgstr "Modified by "
+
+msgid ""
+"\n"
+"Compiled "
+msgstr ""
+"\n"
+"Compiled "
+
+msgid "by "
+msgstr "by "
+
+msgid ""
+"\n"
+"Huge version "
+msgstr ""
+"\n"
+"Huge 版 "
+
+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."
+
+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 (クラシック) GUI."
+
+msgid " Features included (+) or not (-):\n"
+msgstr " 機能ã®ä¸€è¦§ 有効(+)/無効(-)\n"
+
+msgid " system vimrc file: \""
+msgstr " システム 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 " 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 "デãƒãƒƒã‚°ãƒ“ルド"
+
+msgid "VIM - Vi IMproved"
+msgstr "VIM - Vi IMproved"
+
+msgid "version "
+msgstr "version "
+
+msgid "by Bram Moolenaar et al."
+msgstr "by Bram Moolenaar ä»–."
+
+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> "
+
+msgid "type :help version7<Enter> for version info"
+msgstr "ãƒãƒ¼ã‚¸ãƒ§ãƒ³æƒ…報㯠:help version7<Enter> "
+
+msgid "Running in Vi compatible mode"
+msgstr "Vi互æ›ãƒ¢ãƒ¼ãƒ‰ã§å‹•作中"
+
+msgid "type :set nocp<Enter> for Vim defaults"
+msgstr "Vim推奨値ã«ã™ã‚‹ã«ã¯ :set nocp<Enter> "
+
+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 "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 "Already only one window"
+msgstr "æ—¢ã«ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã¯1ã¤ã—ã‹ã‚りã¾ã›ã‚“"
+
+msgid "E441: There is no preview window"
+msgstr "E441: プレビューウィンドウãŒã‚りã¾ã›ã‚“"
+
+msgid "E442: Can't split topleft and botright at the same time"
+msgstr "E442: 左上ã¨å³ä¸‹ã‚’åŒæ™‚ã«åˆ†å‰²ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“"
+
+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: pathã«ã¯ \"%s\" ã¨ã„ã†ãƒ•ァイルãŒã‚りã¾ã›ã‚“"
+
+msgid "Edit with &multiple Vims"
+msgstr "複数ã®Vimã§ç·¨é›†ã™ã‚‹ (&M)"
+
+msgid "Edit with single &Vim"
+msgstr "1ã¤ã®Vimã§ç·¨é›†ã™ã‚‹ (&V)"
+
+msgid "Diff with Vim"
+msgstr "Vimã§å·®åˆ†ã‚’表示ã™ã‚‹"
+
+msgid "Edit with &Vim"
+msgstr "Vimã§ç·¨é›†ã™ã‚‹ (&V)"
+
+#. Now concatenate
+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ãŒç’°å¢ƒå¤‰æ•°PATH上ã«ã‚ã‚‹ã‹ç¢ºèªã—ã¦ãã ã•ã„!"
+
+msgid "gvimext.dll error"
+msgstr "gvimext.dll エラー"
+
+msgid "Path length too long!"
+msgstr "パスãŒé•·ã™ãŽã¾ã™!"
+
+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.
+#.
+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: :while ã®ãªã„ :endwhile ãŒã‚りã¾ã™"
+
+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: 未知ã®ãƒ•ォントセット: %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: 内部エラーã§ã™"
+
+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 "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\"() ã®ãƒ©ã‚¤ãƒ–ラリ呼出ã«å¤±æ•—ã—ã¾ã—ãŸ"
+
+#, 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 "E37: No write since last change (add ! to override)"
+msgstr "E37: 最後ã®å¤‰æ›´ãŒä¿å­˜ã•れã¦ã„ã¾ã›ã‚“ (! を追加ã§å¤‰æ›´ã‚’破棄)"
+
+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: 䏿­£ãªæ­£è¦è¡¨ç¾ãƒ—ログラムã§ã™"
+
+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: サンドボックスã§ã¯å¤‰æ•° \"%s\" ã«å€¤ã‚’設定ã§ãã¾ã›ã‚“"
+
+msgid "E47: Error while reading errorfile"
+msgstr "E47: エラーファイルã®èª­è¾¼ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ"
+
+msgid "E48: Not allowed in sandbox"
+msgstr "E48: サンドボックスã§ã¯è¨±ã•れã¾ã›ã‚“"
+
+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: sign ã®ãƒ‡ãƒ¼ã‚¿ã‚’読込ã‚ã¾ã›ã‚“ã§ã—ãŸ"
+
+msgid "E72: Close error on swap file"
+msgstr "E72: スワップファイルã®ã‚¯ãƒ­ãƒ¼ã‚ºæ™‚エラーã§ã™"
+
+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 "Zero count"
+msgstr "ゼロカウント"
+
+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 ã¯èª­è¾¼å°‚用ファイルを変更ã™ã‚‹ã“ã¨ã‚’許ã—ã¾ã›ã‚“"
+
+#, c-format
+msgid "E685: Internal error: %s"
+msgstr "E685: 内部エラーã§ã™: %s"
+
+msgid "E363: pattern uses more memory than 'maxmempattern'"
+msgstr "E363: パターン㌠'maxmempattern' 以上ã®ãƒ¡ãƒ¢ãƒªã‚’使用ã—ã¾ã™"
+
+msgid "E749: empty buffer"
+msgstr "E749: ãƒãƒƒãƒ•ã‚¡ãŒç©ºã§ã™"
+
+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: 無効ãªãƒ¬ã‚¸ã‚¹ã‚¿åã§ã™"
+
+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 "インデックス㯠%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 "long() ã‹ãれã¸å¤‰æ›å¯èƒ½ãªã‚‚ã®ãŒæœŸå¾…ã•れã¦ã„ã‚‹ã®ã« %s ã§ã—ãŸ"
+
+#, c-format
+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 åž‹ã¨ã—ã¦ã¯å€¤ãŒå¤§ãéŽãŽã¾ã™"
+
+msgid "value is too small to fit into C int type"
+msgstr "C言語㮠int åž‹ã¨ã—ã¦ã¯å€¤ãŒå°ã•éŽãŽã¾ã™"
+
+msgid "number must be greater then zero"
+msgstr "数値㯠0 より大ãããªã‘れã°ãªã‚Šã¾ã›ã‚“"
+
+msgid "number must be greater or equal to zero"
+msgstr "数値㯠0 ã‹ãれ以上ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
+
+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: I/Oオブジェクトã®åˆæœŸåŒ–エラー"
+
+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 ã‚’è¿”ã—ã¾ã—㟠(期待値: 2 è¦ç´ ã®ã‚¿ãƒ—ル)"
+
+#, c-format
+msgid "expected 3-tuple as imp.find_module() result, but got tuple of size %d"
+msgstr "impl.find_module() ㌠%d è¦ç´ ã®ã‚¿ãƒ—ルを返ã—ã¾ã—㟠(期待値: 2)"
+
+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 "リスト範囲外ã®ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã§ã™"
+
+#. No more suitable format specifications in python-2.3
+#, c-format
+msgid "internal error: failed to get vim list item %d"
+msgstr "内部エラー: vimã®ãƒªã‚¹ãƒˆè¦ç´  %d ã®å–å¾—ã«å¤±æ•—ã—ã¾ã—ãŸ"
+
+msgid "failed to add item to list"
+msgstr "リストã¸ã®è¦ç´ è¿½åŠ ã«å¤±æ•—ã—ã¾ã—ãŸ"
+
+#, c-format
+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 "固定ã•れãŸãƒªã‚¹ãƒˆã¯å¤‰æ›´ã§ãã¾ã›ã‚“"
+
+#, c-format
+msgid "unnamed function %s does not exist"
+msgstr "ç„¡å関数 %s ã¯å­˜åœ¨ã—ã¾ã›ã‚“"
+
+#, c-format
+msgid "function %s does not exist"
+msgstr "関数 %s ãŒã‚りã¾ã›ã‚“"
+
+msgid "function constructor does not accept keyword arguments"
+msgstr "関数ã®ã‚³ãƒ³ã‚¹ãƒˆãƒ©ã‚¯ã‚¿ã¯ã‚­ãƒ¼ãƒ¯ãƒ¼ãƒ‰å¼•æ•°ã‚’å—ã‘付ã‘ã¾ã›ã‚“"
+
+#, 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 "マークåã¯1文字ã®ã‚¢ãƒ«ãƒ•ァベットã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
+
+#, 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: å¼è©•ä¾¡ã¯æœ‰åйãª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 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_hooks ã‚’ 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/po/ja.sjis.po b/src/po/ja.sjis.po
new file mode 100644
index 0000000000..27659425b6
--- /dev/null
+++ b/src/po/ja.sjis.po
@@ -0,0 +1,6808 @@
+# Japanese 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.
+#
+# Last Change: 2013 Jul 06
+#
+# Copyright (C) 2001-13 MURAOKA Taro <koron.kaoriya@gmail.com>
+# 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: 2013-07-06 13:50+0900\n"
+"PO-Revision-Date: 2013-07-06 15:00+0900\n"
+"Last-Translator: MURAOKA Taro <koron.kaoriya@gmail.com>\n"
+"Language-Team: MURAOKA Taro <koron.kaoriya@gmail.com>\n"
+"Language: Japanese\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=cp932\n"
+"Content-Transfer-Encoding: 8-bit\n"
+
+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 "[Location List]"
+msgstr "[êŠƒŠƒXƒg]"
+
+msgid "[Quickfix List]"
+msgstr "[QuickfixƒŠƒXƒg]"
+
+msgid "E855: Autocommands caused command to abort"
+msgstr "E855: autocommand‚ªƒRƒ}ƒ“ƒh‚Ì’âŽ~‚ðˆø‚«‹N‚±‚µ‚Ü‚µ‚½"
+
+msgid "E82: Cannot allocate any buffer, exiting..."
+msgstr "E82: ƒoƒbƒtƒ@‚ð1‚‚à쬂ł«‚È‚¢‚Ì‚Å, I—¹‚µ‚Ü‚·..."
+
+msgid "E83: Cannot allocate buffer, using other one..."
+msgstr "E83: ƒoƒbƒtƒ@‚ð쬂ł«‚È‚¢‚Ì‚Å, ‘¼‚Ì‚ðŽg—p‚µ‚Ü‚·..."
+
+msgid "E515: No buffers were unloaded"
+msgstr "E515: ‰ð•ú‚³‚ꂽƒoƒbƒtƒ@‚Í‚ ‚è‚Ü‚¹‚ñ"
+
+msgid "E516: No buffers were deleted"
+msgstr "E516: 휂³‚ꂽƒoƒbƒtƒ@‚Í‚ ‚è‚Ü‚¹‚ñ"
+
+msgid "E517: No buffers were wiped out"
+msgstr "E517: ”jŠü‚³‚ꂽƒoƒbƒtƒ@‚Í‚ ‚è‚Ü‚¹‚ñ"
+
+msgid "1 buffer unloaded"
+msgstr "1 ŒÂ‚̃oƒbƒtƒ@‚ª‰ð•ú‚³‚ê‚Ü‚µ‚½"
+
+#, c-format
+msgid "%d buffers unloaded"
+msgstr "%d ŒÂ‚̃oƒbƒtƒ@‚ª‰ð•ú‚³‚ê‚Ü‚µ‚½"
+
+msgid "1 buffer deleted"
+msgstr "1 ŒÂ‚̃oƒbƒtƒ@‚ªíœ‚³‚ê‚Ü‚µ‚½"
+
+#, c-format
+msgid "%d buffers deleted"
+msgstr "%d ŒÂ‚̃oƒbƒtƒ@‚ªíœ‚³‚ê‚Ü‚µ‚½"
+
+msgid "1 buffer wiped out"
+msgstr "1 ŒÂ‚̃oƒbƒtƒ@‚ª”jŠü‚³‚ê‚Ü‚µ‚½"
+
+#, c-format
+msgid "%d buffers wiped out"
+msgstr "%d ŒÂ‚̃oƒbƒtƒ@‚ª”jŠü‚³‚ê‚Ü‚µ‚½"
+
+msgid "E84: No modified buffer found"
+msgstr "E84: •ÏX‚³‚ꂽƒoƒbƒtƒ@‚Í‚ ‚è‚Ü‚¹‚ñ"
+
+#. back where we started, didn't find anything.
+msgid "E85: There is no listed buffer"
+msgstr "E85: ƒŠƒXƒg•\\ަ‚³‚ê‚éƒoƒbƒtƒ@‚Í‚ ‚è‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "E86: Buffer %ld does not exist"
+msgstr "E86: ƒoƒbƒtƒ@ %ld ‚Í‚ ‚è‚Ü‚¹‚ñ"
+
+msgid "E87: Cannot go beyond last buffer"
+msgstr "E87: ÅŒã‚̃oƒbƒtƒ@‚ð‰z‚¦‚Ĉړ®‚͂ł«‚Ü‚¹‚ñ"
+
+msgid "E88: Cannot go before first buffer"
+msgstr "E88: ʼn‚̃oƒbƒtƒ@‚æ‚è‘O‚ւ͈ړ®‚Å‚«‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "E89: No write since last change for buffer %ld (add ! to override)"
+msgstr "E89: ƒoƒbƒtƒ@ %ld ‚Ì•ÏX‚͕ۑ¶‚³‚ê‚Ä‚¢‚Ü‚¹‚ñ (! ‚Å•ÏX‚ð”jŠü)"
+
+msgid "E90: Cannot unload last buffer"
+msgstr "E90: ÅŒã‚̃oƒbƒtƒ@‚͉ð•ú‚Å‚«‚Ü‚¹‚ñ"
+
+msgid "W14: Warning: List of file names overflow"
+msgstr "W14: Œx: ƒtƒ@ƒCƒ‹–¼‚ÌƒŠƒXƒg‚ª’·‰ß‚¬‚Ü‚·"
+
+#, c-format
+msgid "E92: Buffer %ld not found"
+msgstr "E92: ƒoƒbƒtƒ@ %ld ‚ªŒ©‚‚©‚è‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "E93: More than one match for %s"
+msgstr "E93: %s ‚É•¡”‚ÌŠY“–‚ª‚ ‚è‚Ü‚µ‚½"
+
+#, c-format
+msgid "E94: No matching buffer for %s"
+msgstr "E94: %s ‚ÉŠY“–‚·‚éƒoƒbƒtƒ@‚Í‚ ‚è‚Ü‚¹‚ñ‚Å‚µ‚½"
+
+#, c-format
+msgid "line %ld"
+msgstr "s %ld"
+
+msgid "E95: Buffer with this name already exists"
+msgstr "E95: ‚±‚Ì–¼‘O‚̃oƒbƒtƒ@‚ÍŠù‚É‚ ‚è‚Ü‚·"
+
+msgid " [Modified]"
+msgstr " [•ÏX‚ ‚è]"
+
+msgid "[Not edited]"
+msgstr "[–¢•ÒW]"
+
+msgid "[New file]"
+msgstr "[Vƒtƒ@ƒCƒ‹]"
+
+msgid "[Read errors]"
+msgstr "[“ÇžƒGƒ‰[]"
+
+msgid "[RO]"
+msgstr "[“Çê]"
+
+msgid "[readonly]"
+msgstr "[“Çžê—p]"
+
+#, c-format
+msgid "1 line --%d%%--"
+msgstr "1 s --%d%%--"
+
+#, c-format
+msgid "%ld lines --%d%%--"
+msgstr "%ld s --%d%%--"
+
+#, c-format
+msgid "line %ld of %ld --%d%%-- col "
+msgstr "s %ld (‘S‘Ì %ld) --%d%%-- col "
+
+msgid "[No Name]"
+msgstr "[–³–¼]"
+
+#. must be a help buffer
+msgid "help"
+msgstr "ƒwƒ‹ƒv"
+
+msgid "[Help]"
+msgstr "[ƒwƒ‹ƒv]"
+
+msgid "[Preview]"
+msgstr "[ƒvƒŒƒrƒ…[]"
+
+msgid "All"
+msgstr "‘S‚Ä"
+
+msgid "Bot"
+msgstr "––”ö"
+
+msgid "Top"
+msgstr "擪"
+
+msgid ""
+"\n"
+"# Buffer list:\n"
+msgstr ""
+"\n"
+"# ƒoƒbƒtƒ@ƒŠƒXƒg:\n"
+
+msgid "[Scratch]"
+msgstr "[‰º‘‚«]"
+
+msgid ""
+"\n"
+"--- Signs ---"
+msgstr ""
+"\n"
+"--- ƒTƒCƒ“ ---"
+
+#, c-format
+msgid "Signs for %s:"
+msgstr "%s ‚̃TƒCƒ“:"
+
+#, c-format
+msgid " line=%ld id=%d name=%s"
+msgstr " s=%ld ޝ•ÊŽq=%d –¼‘O=%s"
+
+#, c-format
+msgid "E96: Can not diff more than %ld buffers"
+msgstr "E96: %ld ˆÈã‚̃oƒbƒtƒ@‚Ídiff‚Å‚«‚Ü‚¹‚ñ"
+
+msgid "E810: Cannot read or write temp files"
+msgstr "E810: ˆêŽžƒtƒ@ƒCƒ‹‚̓Ǟ‚à‚µ‚­‚Í‘ž‚ª‚Å‚«‚Ü‚¹‚ñ"
+
+msgid "E97: Cannot create diffs"
+msgstr "E97: ·•ª‚ð쬂ł«‚Ü‚¹‚ñ "
+
+msgid "Patch file"
+msgstr "ƒpƒbƒ`ƒtƒ@ƒCƒ‹"
+
+msgid "E816: Cannot read patch output"
+msgstr "E816: patch‚Ìo—Í‚ð“Çž‚߂܂¹‚ñ"
+
+msgid "E98: Cannot read diff output"
+msgstr "E98: diff‚Ìo—Í‚ð“Çž‚߂܂¹‚ñ"
+
+msgid "E99: Current buffer is not in diff mode"
+msgstr "E99: Œ»Ý‚̃oƒbƒtƒ@‚Í·•ªƒ‚[ƒh‚ł͂ ‚è‚Ü‚¹‚ñ"
+
+msgid "E793: No other buffer in diff mode is modifiable"
+msgstr "E793: ·•ªƒ‚[ƒh‚Å‚ ‚鑼‚̃oƒbƒtƒ@‚Í•ÏX‰Â”\\‚Å‚·"
+
+msgid "E100: No other buffer in diff mode"
+msgstr "E100: ·•ªƒ‚[ƒh‚Å‚ ‚鑼‚̃oƒbƒtƒ@‚Í‚ ‚è‚Ü‚¹‚ñ"
+
+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‚¤‚©“Á’è‚Å‚«‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "E102: Can't find buffer \"%s\""
+msgstr "E102: ƒoƒbƒtƒ@ \"%s\" ‚ªŒ©‚‚©‚è‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "E103: Buffer \"%s\" is not in diff mode"
+msgstr "E103: ƒoƒbƒtƒ@ \"%s\" ‚Í·•ªƒ‚[ƒh‚ł͂ ‚è‚Ü‚¹‚ñ"
+
+msgid "E787: Buffer changed unexpectedly"
+msgstr "E787: —\\Šú‚¹‚¸ƒoƒbƒtƒ@‚ª•ÏX•ÏX‚³‚ê‚Ü‚µ‚½"
+
+msgid "E104: Escape not allowed in digraph"
+msgstr "E104: ‡Žš‚ÉEscape‚ÍŽg—p‚Å‚«‚Ü‚¹‚ñ"
+
+msgid "E544: Keymap file not found"
+msgstr "E544: ƒL[ƒ}ƒbƒvƒtƒ@ƒCƒ‹‚ªŒ©‚‚©‚è‚Ü‚¹‚ñ"
+
+msgid "E105: Using :loadkeymap not in a sourced file"
+msgstr "E105: :source ‚Ŏ枂ރtƒ@ƒCƒ‹ˆÈŠO‚Å‚Í :loadkeymap ‚ðŽg‚¦‚Ü‚¹‚ñ"
+
+msgid "E791: Empty keymap entry"
+msgstr "E791: ‹ó‚̃L[ƒ}ƒbƒvƒGƒ“ƒgƒŠ"
+
+msgid " Keyword completion (^N^P)"
+msgstr " ƒL[ƒ[ƒh•⊮ (^N^P)"
+
+#. ctrl_x_mode == 0, ^P/^N compl.
+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)"
+
+msgid " Whole line completion (^L^N^P)"
+msgstr " s(‘S‘Ì)•⊮ (^L^N^P)"
+
+msgid " File name completion (^F^N^P)"
+msgstr "ƒtƒ@ƒCƒ‹–¼•⊮ (^F^N^P)"
+
+msgid " Tag completion (^]^N^P)"
+msgstr " ƒ^ƒO•⊮ (^]^N^P)"
+
+msgid " Path pattern completion (^N^P)"
+msgstr " ƒpƒXƒpƒ^[ƒ“•⊮ (^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 " ƒVƒ\\[ƒ‰ƒX•⊮ (^T^N^P)"
+
+msgid " Command-line completion (^V^N^P)"
+msgstr " ƒRƒ}ƒ“ƒhƒ‰ƒCƒ“•⊮ (^V^N^P)"
+
+msgid " User defined completion (^U^N^P)"
+msgstr " ƒ†[ƒU’è‹`•⊮ (^U^N^P)"
+
+msgid " Omni completion (^O^N^P)"
+msgstr " ƒIƒ€ƒj•⊮ (^O^N^P)"
+
+msgid " Spelling suggestion (s^N^P)"
+msgstr " ’Ô‚èC³Œó•â (s^N^P)"
+
+msgid " Keyword Local completion (^N^P)"
+msgstr " ‹ÇŠƒL[ƒ[ƒh•⊮ (^N^P)"
+
+msgid "Hit end of paragraph"
+msgstr "’i—Ž‚ÌÅŒã‚Ƀqƒbƒg"
+
+msgid "E839: Completion function changed window"
+msgstr "E839: •âŠÔŠÖ”‚ªƒEƒBƒ“ƒhƒE‚ð•ÏX‚µ‚Ü‚µ‚½"
+
+msgid "E840: Completion function deleted text"
+msgstr "E840: •⊮ŠÖ”‚ªƒeƒLƒXƒg‚ð휂µ‚Ü‚µ‚½"
+
+msgid "'dictionary' option is empty"
+msgstr "'dictionary' ƒIƒvƒVƒ‡ƒ“‚ª‹ó‚Å‚·"
+
+msgid "'thesaurus' option is empty"
+msgstr "'thesaurus' ƒIƒvƒVƒ‡ƒ“‚ª‹ó‚Å‚·"
+
+#, c-format
+msgid "Scanning dictionary: %s"
+msgstr "Ž«‘‚ðƒXƒLƒƒƒ“’†: %s"
+
+msgid " (insert) Scroll (^E/^Y)"
+msgstr " (‘}“ü) ƒXƒNƒ[ƒ‹(^E/^Y)"
+
+msgid " (replace) Scroll (^E/^Y)"
+msgstr " (’uŠ·) ƒXƒNƒ[ƒ‹ (^E/^Y)"
+
+#, c-format
+msgid "Scanning: %s"
+msgstr "ƒXƒLƒƒƒ“’†: %s"
+
+msgid "Scanning tags."
+msgstr "ƒ^ƒO‚ðƒXƒLƒƒƒ“’†."
+
+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.
+#.
+msgid "-- Searching..."
+msgstr "-- ŒŸõ’†..."
+
+msgid "Back at original"
+msgstr "Žn‚߂ɖ߂é"
+
+msgid "Word from other line"
+msgstr "‘¼‚Ìs‚Ì’PŒê"
+
+msgid "The only match"
+msgstr "—Bˆê‚ÌŠY“–"
+
+#, c-format
+msgid "match %d of %d"
+msgstr "%d ”Ô–Ú‚ÌŠY“– (‘SŠY“– %d ŒÂ’†)"
+
+#, c-format
+msgid "match %d"
+msgstr "%d ”Ô–Ú‚ÌŠY“–"
+
+msgid "E18: Unexpected characters in :let"
+msgstr "E18: —\\Šú‚¹‚Ê•¶Žš‚ª :let ‚É‚ ‚è‚Ü‚µ‚½"
+
+#, c-format
+msgid "E684: list index out of range: %ld"
+msgstr "E684: ƒŠƒXƒg‚̃Cƒ“ƒfƒbƒNƒX‚ª”͈͊O‚Å‚·: %ld"
+
+#, c-format
+msgid "E121: Undefined variable: %s"
+msgstr "E121: –¢’è‹`‚̕ϔ‚Å‚·: %s"
+
+msgid "E111: Missing ']'"
+msgstr "E111: ']' ‚ªŒ©‚‚©‚è‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "E686: Argument of %s must be a List"
+msgstr "E686: %s ‚̈ø”‚ÍƒŠƒXƒgŒ^‚łȂ¯‚ê‚΂Ȃè‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "E712: Argument of %s must be a List or Dictionary"
+msgstr "E712: %s ‚̈ø”‚ÍƒŠƒXƒgŒ^‚Ü‚½‚ÍŽ«‘Œ^‚łȂ¯‚ê‚΂Ȃè‚Ü‚¹‚ñ"
+
+msgid "E713: Cannot use empty key for Dictionary"
+msgstr "E713: Ž«‘Œ^‚É‹ó‚̃L[‚ðŽg‚¤‚±‚Ƃ͂ł«‚Ü‚¹‚ñ"
+
+msgid "E714: List required"
+msgstr "E714: ƒŠƒXƒgŒ^‚ª•K—v‚Å‚·"
+
+msgid "E715: Dictionary required"
+msgstr "E715: Ž«‘Œ^‚ª•K—v‚Å‚·"
+
+#, 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: Ž«‘Œ^‚ɃL[‚ª‘¶Ý‚µ‚Ü‚¹‚ñ: %s"
+
+#, c-format
+msgid "E122: Function %s already exists, add ! to replace it"
+msgstr "E122: ŠÖ” %s ‚Í’è‹`ςł·, Ä’è‹`‚·‚é‚É‚Í ! ‚ð’ljÁ‚µ‚Ä‚­‚¾‚³‚¢"
+
+msgid "E717: Dictionary entry already exists"
+msgstr "E717: Ž«‘Œ^“à‚ɃGƒ“ƒgƒŠ‚ªŠù‚É‘¶Ý‚µ‚Ü‚·"
+
+msgid "E718: Funcref required"
+msgstr "E718: ŠÖ”ŽQÆŒ^‚ª—v‹‚³‚ê‚Ü‚·"
+
+msgid "E719: Cannot use [:] with a Dictionary"
+msgstr "E719: [:] ‚ðŽ«‘Œ^‚Æ‘g‚݇‚킹‚Ă͎g‚¦‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "E734: Wrong variable type for %s="
+msgstr "E734: ˆÙ‚È‚Á‚½Œ^‚̕ϔ‚Å‚· %s="
+
+#, c-format
+msgid "E130: Unknown function: %s"
+msgstr "E130: –¢’m‚ÌŠÖ”‚Å‚·: %s"
+
+#, c-format
+msgid "E461: Illegal variable name: %s"
+msgstr "E461: •s³‚ȕϔ–¼‚Å‚·: %s"
+
+msgid "E806: using Float as a String"
+msgstr "E806: •‚“®¬”“_”‚ð•¶Žš—ñ‚Æ‚µ‚Ĉµ‚Á‚Ä‚¢‚Ü‚·"
+
+msgid "E687: Less targets than List items"
+msgstr "E687: ƒ^[ƒQƒbƒg‚ªƒŠƒXƒgŒ^“à‚Ì—v‘f‚æ‚è‚à­‚È‚¢‚Å‚·"
+
+msgid "E688: More targets than List items"
+msgstr "E688: ƒ^[ƒQƒbƒg‚ªƒŠƒXƒgŒ^“à‚Ì—v‘f‚æ‚è‚à‘½‚¢‚Å‚·"
+
+msgid "Double ; in list of variables"
+msgstr "ƒŠƒXƒgŒ^‚Ì’l‚É2‚ˆÈã‚Ì ; ‚ªŒŸo‚³‚ê‚Ü‚µ‚½"
+
+#, c-format
+msgid "E738: Can't list variables for %s"
+msgstr "E738: %s ‚Ì’l‚ðˆê——•\\ަ‚Å‚«‚Ü‚¹‚ñ"
+
+msgid "E689: Can only index a List or Dictionary"
+msgstr "E689: ƒŠƒXƒgŒ^‚ÆŽ«‘Œ^ˆÈŠO‚̓Cƒ“ƒfƒbƒNƒXŽw’è‚Å‚«‚Ü‚¹‚ñ"
+
+msgid "E708: [:] must come last"
+msgstr "E708: [:] ‚ÍÅŒã‚łȂ¯‚ê‚΂¢‚¯‚Ü‚¹‚ñ"
+
+msgid "E709: [:] requires a List value"
+msgstr "E709: [:] ‚É‚ÍƒŠƒXƒgŒ^‚Ì’l‚ª•K—v‚Å‚·"
+
+msgid "E710: List value has more items than target"
+msgstr "E710: ƒŠƒXƒgŒ^•Ï”‚Ƀ^[ƒQƒbƒg‚æ‚è‚à‘½‚¢—v‘f‚ª‚ ‚è‚Ü‚·"
+
+msgid "E711: List value has not enough items"
+msgstr "E711: ƒŠƒXƒgŒ^•Ï”‚É\\•ª‚È”‚Ì—v‘f‚ª‚ ‚è‚Ü‚¹‚ñ"
+
+#
+msgid "E690: Missing \"in\" after :for"
+msgstr "E690: :for ‚ÌŒã‚É \"in\" ‚ª‚ ‚è‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "E107: Missing parentheses: %s"
+msgstr "E107: ƒJƒbƒR '(' ‚ª‚ ‚è‚Ü‚¹‚ñ: %s"
+
+#, c-format
+msgid "E108: No such variable: \"%s\""
+msgstr "E108: ‚»‚̕ϔ‚Í‚ ‚è‚Ü‚¹‚ñ: \"%s\""
+
+msgid "E743: variable nested too deep for (un)lock"
+msgstr "E743: (ƒAƒ“)ƒƒbƒN‚·‚é‚ɂ͕ϔ‚Ì“ü‚êŽq‚ª[‰ß‚¬‚Ü‚·"
+
+msgid "E109: Missing ':' after '?'"
+msgstr "E109: '?' ‚ÌŒã‚É ':' ‚ª‚ ‚è‚Ü‚¹‚ñ"
+
+msgid "E691: Can only compare List with List"
+msgstr "E691: ƒŠƒXƒgŒ^‚ÍƒŠƒXƒgŒ^‚Æ‚µ‚©”äŠr‚Å‚«‚Ü‚¹‚ñ"
+
+msgid "E692: Invalid operation for Lists"
+msgstr "E692: ƒŠƒXƒgŒ^‚ɂ͖³Œø‚È‘€ì‚Å‚·"
+
+msgid "E735: Can only compare Dictionary with Dictionary"
+msgstr "E735: Ž«‘Œ^‚ÍŽ«‘Œ^‚Æ‚µ‚©”äŠr‚Å‚«‚Ü‚¹‚ñ"
+
+msgid "E736: Invalid operation for Dictionary"
+msgstr "E736: Ž«‘Œ^‚ɂ͖³Œø‚È‘€ì‚Å‚·"
+
+msgid "E693: Can only compare Funcref with Funcref"
+msgstr "E693: ŠÖ”ŽQÆŒ^‚ÍŠÖ”ŽQÆŒ^‚Æ‚µ‚©”äŠr‚Å‚«‚Ü‚¹‚ñ"
+
+msgid "E694: Invalid operation for Funcrefs"
+msgstr "E694: ŠÖ”ŽQÆŒ^‚ɂ͖³Œø‚È‘€ì‚Å‚·"
+
+msgid "E804: Cannot use '%' with Float"
+msgstr "E804: '%' ‚ð•‚“®¬”“_”‚Æ‘g‚݇‚킹‚Ă͎g‚¦‚Ü‚¹‚ñ"
+
+msgid "E110: Missing ')'"
+msgstr "E110: ')' ‚ªŒ©‚‚©‚è‚Ü‚¹‚ñ"
+
+msgid "E695: Cannot index a Funcref"
+msgstr "E695: ŠÖ”ŽQÆŒ^‚̓Cƒ“ƒfƒbƒNƒX‚Å‚«‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "E112: Option name missing: %s"
+msgstr "E112: ƒIƒvƒVƒ‡ƒ“–¼‚ª‚ ‚è‚Ü‚¹‚ñ: %s"
+
+#, c-format
+msgid "E113: Unknown option: %s"
+msgstr "E113: –¢’m‚̃IƒvƒVƒ‡ƒ“‚Å‚·: %s"
+
+#, c-format
+msgid "E114: Missing quote: %s"
+msgstr "E114: ˆø—p•„ (\") ‚ª‚ ‚è‚Ü‚¹‚ñ: %s"
+
+#, c-format
+msgid "E115: Missing quote: %s"
+msgstr "E115: ˆø—p•„ (') ‚ª‚ ‚è‚Ü‚¹‚ñ: %s"
+
+#, c-format
+msgid "E696: Missing comma in List: %s"
+msgstr "E696: ƒŠƒXƒgŒ^‚ɃJƒ“ƒ}‚ª‚ ‚è‚Ü‚¹‚ñ: %s"
+
+#, c-format
+msgid "E697: Missing end of List ']': %s"
+msgstr "E697: ƒŠƒXƒgŒ^‚ÌÅŒã‚É ']' ‚ª‚ ‚è‚Ü‚¹‚ñ: %s"
+
+#, c-format
+msgid "E720: Missing colon in Dictionary: %s"
+msgstr "E720: Ž«‘Œ^‚ɃRƒƒ“‚ª‚ ‚è‚Ü‚¹‚ñ: %s"
+
+#, c-format
+msgid "E721: Duplicate key in Dictionary: \"%s\""
+msgstr "E721: Ž«‘Œ^‚Éd•¡ƒL[‚ª‚ ‚è‚Ü‚·: \"%s\""
+
+#, c-format
+msgid "E722: Missing comma in Dictionary: %s"
+msgstr "E722: Ž«‘Œ^‚ɃJƒ“ƒ}‚ª‚ ‚è‚Ü‚¹‚ñ: %s"
+
+#, c-format
+msgid "E723: Missing end of Dictionary '}': %s"
+msgstr "E723: Ž«‘Œ^‚ÌÅŒã‚É '}' ‚ª‚ ‚è‚Ü‚¹‚ñ: %s"
+
+msgid "E724: variable nested too deep for displaying"
+msgstr "E724: •\\ަ‚·‚é‚ɂ͕ϔ‚Ì“ü‚êŽq‚ª[‰ß‚¬‚Ü‚·"
+
+#, 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"
+
+#, c-format
+msgid "E117: Unknown function: %s"
+msgstr "E117: –¢’m‚ÌŠÖ”‚Å‚·: %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: ƒXƒNƒŠƒvƒgˆÈŠO‚Å<SID>‚ªŽg‚í‚ê‚Ü‚µ‚½: %s"
+
+#, c-format
+msgid "E725: Calling dict function without Dictionary: %s"
+msgstr "E725: Ž«‘—pŠÖ”‚ªŒÄ‚΂ê‚Ü‚µ‚½‚ªŽ«‘‚ª‚ ‚è‚Ü‚¹‚ñ: %s"
+
+msgid "E808: Number or Float required"
+msgstr "E808: ”’l‚©•‚“®¬”“_”‚ª•K—v‚Å‚·"
+
+msgid "add() argument"
+msgstr "add() ‚̈ø”"
+
+msgid "E699: Too many arguments"
+msgstr "E699: ˆø”‚ª‘½‰ß‚¬‚Ü‚·"
+
+msgid "E785: complete() can only be used in Insert mode"
+msgstr "E785: complete() ‚Í‘}“üƒ‚[ƒh‚Å‚µ‚©—˜—p‚Å‚«‚Ü‚¹‚ñ"
+
+#.
+#. * 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"
+
+#, c-format
+msgid "E737: Key already exists: %s"
+msgstr "E737: ƒL[‚ÍŠù‚É‘¶Ý‚µ‚Ü‚·: %s"
+
+msgid "extend() argument"
+msgstr "extend() ‚̈ø”"
+
+msgid "map() argument"
+msgstr "map() ‚̈ø”"
+
+msgid "filter() argument"
+msgstr "filter() ‚̈ø”"
+
+#, c-format
+msgid "+-%s%3ld lines: "
+msgstr "+-%s%3ld s: "
+
+#, c-format
+msgid "E700: Unknown function: %s"
+msgstr "E700: –¢’m‚ÌŠÖ”‚Å‚·: %s"
+
+msgid ""
+"&OK\n"
+"&Cancel"
+msgstr ""
+"Œˆ’è(&O)\n"
+"ƒLƒƒƒ“ƒZƒ‹(&C)"
+
+msgid "called inputrestore() more often than inputsave()"
+msgstr "inputrestore() ‚ª inputsave() ‚æ‚è‚à‘½‚­ŒÄ‚΂ê‚Ü‚µ‚½"
+
+msgid "insert() argument"
+msgstr "insert() ‚̈ø”"
+
+msgid "E786: Range not allowed"
+msgstr "E786: ”͈͎w’è‚Í‹–‰Â‚³‚ê‚Ä‚¢‚Ü‚¹‚ñ"
+
+msgid "E701: Invalid type for len()"
+msgstr "E701: len() ‚ɂ͖³Œø‚ÈŒ^‚Å‚·"
+
+msgid "E726: Stride is zero"
+msgstr "E726: ƒXƒgƒ‰ƒCƒh(‘Oi—Ê)‚ª 0 ‚Å‚·"
+
+msgid "E727: Start past end"
+msgstr "E727: ŠJŽnˆÊ’u‚ªI—¹ˆÊ’u‚ð‰z‚¦‚Ü‚µ‚½"
+
+msgid "<empty>"
+msgstr "<‹ó>"
+
+msgid "E240: No connection to Vim server"
+msgstr "E240: Vim ƒT[ƒo‚Ö‚ÌÚ‘±‚ª‚ ‚è‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "E241: Unable to send to %s"
+msgstr "E241: %s ‚Ö‘—‚邱‚Æ‚ª‚Å‚«‚Ü‚¹‚ñ"
+
+msgid "E277: Unable to read a server reply"
+msgstr "E277: ƒT[ƒo‚̉ž“š‚ª‚ ‚è‚Ü‚¹‚ñ"
+
+msgid "remove() argument"
+msgstr "remove() ‚̈ø”"
+
+# Added at 10-Mar-2004.
+msgid "E655: Too many symbolic links (cycle?)"
+msgstr "E655: ƒVƒ“ƒ{ƒŠƒbƒNƒŠƒ“ƒN‚ª‘½‰ß‚¬‚Ü‚· (zŠÂ‚µ‚Ä‚¢‚é‰Â”\\«‚ª‚ ‚è‚Ü‚·)"
+
+msgid "reverse() argument"
+msgstr "reverse() ‚̈ø”"
+
+msgid "E258: Unable to send to client"
+msgstr "E258: ƒNƒ‰ƒCƒAƒ“ƒg‚Ö‘—‚邱‚Æ‚ª‚Å‚«‚Ü‚¹‚ñ"
+
+msgid "sort() argument"
+msgstr "sort() ‚̈ø”"
+
+msgid "E702: Sort compare function failed"
+msgstr "E702: ƒ\\[ƒg‚Ì”äŠrŠÖ”‚ªŽ¸”s‚µ‚Ü‚µ‚½"
+
+msgid "(Invalid)"
+msgstr "(–³Œø)"
+
+msgid "E677: Error writing temp file"
+msgstr "E677: ˆêŽžƒtƒ@ƒCƒ‹‘ž’†‚ɃGƒ‰[‚ª”­¶‚µ‚Ü‚µ‚½"
+
+msgid "E805: Using a Float as a Number"
+msgstr "E805: •‚“®¬”“_”‚ð”’l‚Æ‚µ‚Ĉµ‚Á‚Ä‚¢‚Ü‚·"
+
+msgid "E703: Using a Funcref as a Number"
+msgstr "E703: ŠÖ”ŽQÆŒ^‚ð”’l‚Æ‚µ‚Ĉµ‚Á‚Ä‚¢‚Ü‚·B"
+
+msgid "E745: Using a List as a Number"
+msgstr "E745: ƒŠƒXƒgŒ^‚ð”’l‚Æ‚µ‚Ĉµ‚Á‚Ä‚¢‚Ü‚·"
+
+msgid "E728: Using a Dictionary as a Number"
+msgstr "E728: Ž«‘Œ^‚ð”’l‚Æ‚µ‚Ĉµ‚Á‚Ä‚¢‚Ü‚·"
+
+msgid "E729: using Funcref as a String"
+msgstr "E729: ŠÖ”ŽQÆŒ^‚ð•¶Žš—ñ‚Æ‚µ‚Ĉµ‚Á‚Ä‚¢‚Ü‚·"
+
+msgid "E730: using List as a String"
+msgstr "E730: ƒŠƒXƒgŒ^‚ð•¶Žš—ñ‚Æ‚µ‚Ĉµ‚Á‚Ä‚¢‚Ü‚·"
+
+msgid "E731: using Dictionary as a String"
+msgstr "E731: Ž«‘Œ^‚ð•¶Žš—ñ‚Æ‚µ‚Ĉµ‚Á‚Ä‚¢‚Ü‚·"
+
+#, c-format
+msgid "E706: Variable type mismatch for: %s"
+msgstr "E706: •Ï”‚ÌŒ^‚ªˆê’v‚µ‚Ü‚¹‚ñ: %s"
+
+#, 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: ŠÖ”ŽQÆŒ^•Ï”–¼‚Í‘å•¶Žš‚ÅŽn‚Ü‚ç‚È‚¯‚ê‚΂Ȃè‚Ü‚¹‚ñ: %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: ’l‚ªƒƒbƒN‚³‚ê‚Ä‚¢‚Ü‚·: %s"
+
+msgid "Unknown"
+msgstr "•s–¾"
+
+#, c-format
+msgid "E742: Cannot change value of %s"
+msgstr "E742: %s ‚Ì’l‚ð•ÏX‚Å‚«‚Ü‚¹‚ñ"
+
+msgid "E698: variable nested too deep for making a copy"
+msgstr "E698: ƒRƒs[‚ðŽæ‚é‚ɂ͕ϔ‚Ì“ü‚êŽq‚ª[‰ß‚¬‚Ü‚·"
+
+#, 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: ‚ÍŽg‚¦‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "E125: Illegal argument: %s"
+msgstr "E125: •s³‚Ȉø”‚Å‚·: %s"
+
+#, c-format
+msgid "E853: Duplicate argument name: %s"
+msgstr "E853: ˆø”–¼‚ªd•¡‚µ‚Ä‚¢‚Ü‚·: %s"
+
+msgid "E126: Missing :endfunction"
+msgstr "E126: :endfunction ‚ª‚ ‚è‚Ü‚¹‚ñ"
+
+#, 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 ‚ðÄ’è‹`‚Å‚«‚Ü‚¹‚ñ: Žg—p’†‚Å‚·"
+
+#, c-format
+msgid "E746: Function name does not match script file name: %s"
+msgstr "E746: ŠÖ”–¼‚ªƒXƒNƒŠƒvƒg‚̃tƒ@ƒCƒ‹–¼‚ƈê’v‚µ‚Ü‚¹‚ñ: %s"
+
+msgid "E129: Function name required"
+msgstr "E129: ŠÖ”–¼‚ª—v‹‚³‚ê‚Ü‚·"
+
+#, c-format
+msgid "E128: Function name must start with a capital or contain a colon: %s"
+msgstr "E128: ŠÖ”–¼‚Í‘å•¶Žš‚ÅŽn‚܂邩ƒRƒƒ“‚ðŠÜ‚܂Ȃ¯‚ê‚΂Ȃè‚Ü‚¹‚ñ: %s"
+
+#, c-format
+msgid "E131: Cannot delete function %s: It is in use"
+msgstr "E131: ŠÖ” %s ‚ð휂ł«‚Ü‚¹‚ñ: Žg—p’†‚Å‚·"
+
+msgid "E132: Function call depth is higher than 'maxfuncdepth'"
+msgstr "E132: ŠÖ”ŒÄo‚Ì“ü‚êŽq”‚ª 'maxfuncdepth' ‚ð’´‚¦‚Ü‚µ‚½"
+
+#, c-format
+msgid "calling %s"
+msgstr "%s ‚ðŽÀs’†‚Å‚·"
+
+#, c-format
+msgid "%s aborted"
+msgstr "%s ‚ª’†’f‚³‚ê‚Ü‚µ‚½"
+
+#, c-format
+msgid "%s returning #%ld"
+msgstr "%s ‚ª #%ld ‚ð•Ô‚µ‚Ü‚µ‚½"
+
+#, c-format
+msgid "%s returning %s"
+msgstr "%s ‚ª %s ‚ð•Ô‚µ‚Ü‚µ‚½"
+
+#, c-format
+msgid "continuing in %s"
+msgstr "%s ‚ÌŽÀs‚ðŒp‘±’†‚Å‚·"
+
+msgid "E133: :return not inside a function"
+msgstr "E133: ŠÖ”ŠO‚É :return ‚ª‚ ‚è‚Ü‚µ‚½"
+
+msgid ""
+"\n"
+"# global variables:\n"
+msgstr ""
+"\n"
+"# ƒOƒ[ƒoƒ‹•Ï”:\n"
+
+msgid ""
+"\n"
+"\tLast set from "
+msgstr ""
+"\n"
+"\tLast set from "
+
+msgid "No old files"
+msgstr "ŒÃ‚¢ƒtƒ@ƒCƒ‹‚Í‚ ‚è‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "<%s>%s%s %d, Hex %02x, Octal %03o"
+msgstr "<%s>%s%s %d, 16i” %02x, 8i” %03o"
+
+#, c-format
+msgid "> %d, Hex %04x, Octal %o"
+msgstr "> %d, 16i” %04x, 8i” %o"
+
+#, c-format
+msgid "> %d, Hex %08x, Octal %o"
+msgstr "> %d, 16i” %08x, 8i” %o"
+
+msgid "E134: Move lines into themselves"
+msgstr "E134: s‚ð‚»‚êŽ©g‚ɂ͈ړ®‚Å‚«‚Ü‚¹‚ñ"
+
+msgid "1 line moved"
+msgstr "1 s‚ªˆÚ“®‚³‚ê‚Ü‚µ‚½"
+
+#, c-format
+msgid "%ld lines moved"
+msgstr "%ld s‚ªˆÚ“®‚³‚ê‚Ü‚µ‚½"
+
+#, c-format
+msgid "%ld lines filtered"
+msgstr "%ld s‚ªƒtƒBƒ‹ƒ^ˆ—‚³‚ê‚Ü‚µ‚½"
+
+msgid "E135: *Filter* Autocommands must not change current buffer"
+msgstr "E135: *ƒtƒBƒ‹ƒ^* autocommand‚ÍŒ»Ý‚̃oƒbƒtƒ@‚ð•ÏX‚µ‚Ă͂¢‚¯‚Ü‚¹‚ñ"
+
+msgid "[No write since last change]\n"
+msgstr "[ÅŒã‚Ì•ÏX‚ª•Û‘¶‚³‚ê‚Ä‚¢‚Ü‚¹‚ñ]\n"
+
+#, c-format
+msgid "%sviminfo: %s in line: "
+msgstr "%sviminfo: %s s–Ú: "
+
+msgid "E136: viminfo: Too many errors, skipping rest of file"
+msgstr "E136: viminfo: ƒGƒ‰[‚ª‘½‰ß‚¬‚é‚Ì‚Å, ˆÈ~‚̓XƒLƒbƒv‚µ‚Ü‚·"
+
+#, c-format
+msgid "Reading viminfo file \"%s\"%s%s%s"
+msgstr "viminfoƒtƒ@ƒCƒ‹ \"%s\"%s%s%s ‚ð“Çž‚Ý’† "
+
+msgid " info"
+msgstr " î•ñ"
+
+msgid " marks"
+msgstr " ƒ}[ƒN"
+
+msgid " oldfiles"
+msgstr " ‹Œƒtƒ@ƒCƒ‹ŒQ"
+
+msgid " FAILED"
+msgstr " ޏ”s"
+
+#. avoid a wait_return for this message, it's annoying
+#, c-format
+msgid "E137: Viminfo file is not writable: %s"
+msgstr "E137: viminfoƒtƒ@ƒCƒ‹‚ª‘ž‚݂ł«‚Ü‚¹‚ñ: %s"
+
+#, c-format
+msgid "E138: Can't write viminfo file %s!"
+msgstr "E138: viminfoƒtƒ@ƒCƒ‹ %s ‚ð•Û‘¶‚Å‚«‚Ü‚¹‚ñ!"
+
+#, c-format
+msgid "Writing viminfo file \"%s\""
+msgstr "viminfoƒtƒ@ƒCƒ‹ \"%s\" ‚𑞂ݒ†"
+
+#. Write the info:
+#, c-format
+msgid "# This viminfo file was generated by Vim %s.\n"
+msgstr "# ‚±‚Ì viminfo ƒtƒ@ƒCƒ‹‚Í Vim %s ‚É‚æ‚Á‚ͬ‚³‚ê‚Ü‚µ‚½.\n"
+
+msgid ""
+"# You may edit it if you're careful!\n"
+"\n"
+msgstr ""
+"# •ÏX‚·‚éÛ‚É‚Í\\•ª’ˆÓ‚µ‚Ä‚­‚¾‚³‚¢!\n"
+"\n"
+
+msgid "# Value of 'encoding' when this file was written\n"
+msgstr "# ‚±‚̃tƒ@ƒCƒ‹‚ª‘‚©‚ê‚½Žž‚Ì 'encoding' ‚Ì’l\n"
+
+msgid "Illegal starting char"
+msgstr "•s³‚Èæ“ª•¶Žš‚Å‚·"
+
+msgid "Save As"
+msgstr "•Ê–¼‚ŕۑ¶"
+
+msgid "Write partial file?"
+msgstr "ƒtƒ@ƒCƒ‹‚ð•”•ª“I‚ɕۑ¶‚µ‚Ü‚·‚©?"
+
+msgid "E140: Use ! to write partial buffer"
+msgstr "E140: ƒoƒbƒtƒ@‚ð•”•ª“I‚ɕۑ¶‚·‚é‚É‚Í ! ‚ðŽg‚Á‚Ä‚­‚¾‚³‚¢"
+
+#, c-format
+msgid "Overwrite existing file \"%s\"?"
+msgstr "Šù‘¶‚̃tƒ@ƒCƒ‹ \"%s\" ‚ðã‘‚«‚µ‚Ü‚·‚©?"
+
+#, c-format
+msgid "Swap file \"%s\" exists, overwrite anyway?"
+msgstr "ƒXƒƒbƒvƒtƒ@ƒCƒ‹ \"%s\" ‚ª‘¶Ý‚µ‚Ü‚·. ã‘‚«‚ð‹­§‚µ‚Ü‚·‚©?"
+
+#, c-format
+msgid "E768: Swap file exists: %s (:silent! overrides)"
+msgstr "E768: ƒXƒƒbƒvƒtƒ@ƒCƒ‹‚ª‘¶Ý‚µ‚Ü‚·: %s (:silent! ‚ð’ljÁ‚Åã‘)"
+
+#, c-format
+msgid "E141: No file name for buffer %ld"
+msgstr "E141: ƒoƒbƒtƒ@ %ld ‚ɂ͖¼‘O‚ª‚ ‚è‚Ü‚¹‚ñ"
+
+msgid "E142: File not written: Writing is disabled by 'write' option"
+msgstr "E142: ƒtƒ@ƒCƒ‹‚͕ۑ¶‚³‚ê‚Ü‚¹‚ñ‚Å‚µ‚½: 'write' ƒIƒvƒVƒ‡ƒ“‚É‚æ‚è–³Œø‚Å‚·"
+
+#, c-format
+msgid ""
+"'readonly' option is set for \"%s\".\n"
+"Do you wish to write anyway?"
+msgstr ""
+"\"%s\" ‚É‚Í 'readonly' ƒIƒvƒVƒ‡ƒ“‚ªÝ’肳‚ê‚Ä‚¢‚Ü‚·.\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 ""
+"ƒtƒ@ƒCƒ‹ \"%s\" ‚̃p[ƒ~ƒbƒVƒ‡ƒ“‚ª“Çžê—p‚Å‚·.\n"
+"‚»‚ê‚Å‚à‹°‚ç‚­‘‚«ž‚Þ‚±‚Ƃ͉”\\‚Å‚·.\n"
+"Œp‘±‚µ‚Ü‚·‚©?"
+
+#, c-format
+msgid "E505: \"%s\" is read-only (add ! to override)"
+msgstr "E505: \"%s\" ‚͓Ǟê—p‚Å‚· (‹­§‘ž‚É‚Í ! ‚ð’ljÁ)"
+
+msgid "Edit File"
+msgstr "ƒtƒ@ƒCƒ‹‚ð•ÒW"
+
+#, c-format
+msgid "E143: Autocommands unexpectedly deleted new buffer %s"
+msgstr "E143: autocommand‚ª—\\Šú‚¹‚¸V‚µ‚¢ƒoƒbƒtƒ@ %s ‚ð휂µ‚Ü‚µ‚½"
+
+msgid "E144: non-numeric argument to :z"
+msgstr "E144: ”‚ł͂Ȃ¢ˆø”‚ª :z ‚É“n‚³‚ê‚Ü‚µ‚½"
+
+msgid "E145: Shell commands not allowed in rvim"
+msgstr "E145: rvim‚ł̓VƒFƒ‹ƒRƒ}ƒ“ƒh‚ðŽg‚¦‚Ü‚¹‚ñ"
+
+msgid "E146: Regular expressions can't be delimited by letters"
+msgstr "E146: ³‹K•\\Œ»‚Í•¶Žš‚Å‹æØ‚é‚±‚Æ‚ª‚Å‚«‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "replace with %s (y/n/a/q/l/^E/^Y)?"
+msgstr "%s ‚É’uŠ·‚µ‚Ü‚·‚©? (y/n/a/q/l/^E/^Y)"
+
+msgid "(Interrupted) "
+msgstr "(Š„ž‚Ü‚ê‚Ü‚µ‚½) "
+
+msgid "1 match"
+msgstr "1 ‰ÓŠŠY“–‚µ‚Ü‚µ‚½"
+
+msgid "1 substitution"
+msgstr "1 ‰ÓŠ’uŠ·‚µ‚Ü‚µ‚½"
+
+#, c-format
+msgid "%ld matches"
+msgstr "%ld ‰ÓŠŠY“–‚µ‚Ü‚µ‚½"
+
+#, c-format
+msgid "%ld substitutions"
+msgstr "%ld ‰ÓŠ’uŠ·‚µ‚Ü‚µ‚½"
+
+msgid " on 1 line"
+msgstr " (Œv 1 s“à)"
+
+#, c-format
+msgid " on %ld lines"
+msgstr " (Œv %ld s“à)"
+
+msgid "E147: Cannot do :global recursive"
+msgstr "E147: :global ‚ðÄ‹A“I‚ɂ͎g‚¦‚Ü‚¹‚ñ"
+
+msgid "E148: Regular expression missing from global"
+msgstr "E148: globalƒRƒ}ƒ“ƒh‚ɳ‹K•\\Œ»‚ªŽw’肳‚ê‚Ä‚¢‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "Pattern found in every line: %s"
+msgstr "ƒpƒ^[ƒ“‚ª‘S‚Ä‚Ìs‚ÅŒ©‚‚©‚è‚Ü‚µ‚½: %s"
+
+#, c-format
+msgid "Pattern not found: %s"
+msgstr "ƒpƒ^[ƒ“‚ÍŒ©‚‚©‚è‚Ü‚¹‚ñ‚Å‚µ‚½: %s"
+
+msgid ""
+"\n"
+"# Last Substitute String:\n"
+"$"
+msgstr ""
+"\n"
+"# ÅŒã‚É’uŠ·‚³‚ꂽ•¶Žš—ñ:\n"
+"$"
+
+msgid "E478: Don't panic!"
+msgstr "E478: Q‚ĂȂ¢‚Å‚­‚¾‚³‚¢"
+
+#, c-format
+msgid "E661: Sorry, no '%s' help for %s"
+msgstr "E661: Žc”O‚Å‚·‚ª '%s' ‚̃wƒ‹ƒv‚ª %s ‚ɂ͂ ‚è‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "E149: Sorry, no help for %s"
+msgstr "E149: Žc”O‚Å‚·‚ª %s ‚ɂ̓wƒ‹ƒv‚ª‚ ‚è‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "Sorry, help file \"%s\" not found"
+msgstr "Žc”O‚Å‚·‚ªƒwƒ‹ƒvƒtƒ@ƒCƒ‹ \"%s\" ‚ªŒ©‚‚©‚è‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "E150: Not a directory: %s"
+msgstr "E150: ƒfƒBƒŒƒNƒgƒŠ‚ł͂ ‚è‚Ü‚¹‚ñ: %s"
+
+#, c-format
+msgid "E152: Cannot open %s for writing"
+msgstr "E152: ‘ž‚Ý—p‚É %s ‚ðŠJ‚¯‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "E153: Unable to open %s for reading"
+msgstr "E153: “Çž—p‚É %s ‚ðŠJ‚¯‚Ü‚¹‚ñ"
+
+# Added at 29-Apr-2004.
+#, c-format
+msgid "E670: Mix of help file encodings within a language: %s"
+msgstr "E670: 1‚‚̌¾Œê‚̃wƒ‹ƒvƒtƒ@ƒCƒ‹‚É•¡”‚̃Gƒ“ƒR[ƒh‚ª¬Ý‚µ‚Ä‚¢‚Ü‚·: %s"
+
+#, c-format
+msgid "E154: Duplicate tag \"%s\" in file %s/%s"
+msgstr "E154: ƒ^ƒO \"%s\" ‚ªƒtƒ@ƒCƒ‹ %s/%s ‚Éd•¡‚µ‚Ä‚¢‚Ü‚·"
+
+#, c-format
+msgid "E160: Unknown sign command: %s"
+msgstr "E160: –¢’m‚ÌsignƒRƒ}ƒ“ƒh‚Å‚·: %s"
+
+msgid "E156: Missing sign name"
+msgstr "E156: sign–¼‚ª‚ ‚è‚Ü‚¹‚ñ"
+
+msgid "E612: Too many signs defined"
+msgstr "E612: sign‚Ì’è‹`‚ª‘½”Œ©‚‚©‚è‚Ü‚µ‚½"
+
+#, c-format
+msgid "E239: Invalid sign text: %s"
+msgstr "E239: –³Œø‚Èsign‚̃eƒLƒXƒg‚Å‚·: %s"
+
+#, c-format
+msgid "E155: Unknown sign: %s"
+msgstr "E155: –¢’m‚Ìsign‚Å‚·: %s"
+
+msgid "E159: Missing sign number"
+msgstr "E159: sign‚̔Ԇ‚ª‚ ‚è‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "E158: Invalid buffer name: %s"
+msgstr "E158: –³Œø‚ȃoƒbƒtƒ@–¼‚Å‚·: %s"
+
+#, c-format
+msgid "E157: Invalid sign ID: %ld"
+msgstr "E157: –³Œø‚Èsignޝ•ÊŽq‚Å‚·: %ld"
+
+# Added at 27-Jan-2004.
+msgid " (NOT FOUND)"
+msgstr " (Œ©‚‚©‚è‚Ü‚¹‚ñ)"
+
+msgid " (not supported)"
+msgstr " (”ñƒTƒ|[ƒg)"
+
+msgid "[Deleted]"
+msgstr "[íœÏ]"
+
+msgid "Entering Debug mode. Type \"cont\" to continue."
+msgstr "ƒfƒoƒbƒOƒ‚[ƒh‚É“ü‚è‚Ü‚·. ‘±‚¯‚é‚É‚Í \"cont\" ‚Æ“ü—Í‚µ‚Ä‚­‚¾‚³‚¢."
+
+#, c-format
+msgid "line %ld: %s"
+msgstr "s %ld: %s"
+
+#, c-format
+msgid "cmd: %s"
+msgstr "ƒRƒ}ƒ“ƒh: %s"
+
+#, c-format
+msgid "Breakpoint in \"%s%s\" line %ld"
+msgstr "ƒuƒŒ[ƒNƒ|ƒCƒ“ƒg \"%s%s\" s %ld"
+
+#, c-format
+msgid "E161: Breakpoint not found: %s"
+msgstr "E161: ƒuƒŒ[ƒNƒ|ƒCƒ“ƒg‚ªŒ©‚‚©‚è‚Ü‚¹‚ñ: %s"
+
+msgid "No breakpoints defined"
+msgstr "ƒuƒŒ[ƒNƒ|ƒCƒ“ƒg‚ª’è‹`‚³‚ê‚Ä‚¢‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "%3d %s %s line %ld"
+msgstr "%3d %s %s s %ld"
+
+msgid "E750: First use \":profile start {fname}\""
+msgstr "E750: ‰‚ß‚É \":profile start {fname}\" ‚ðŽÀs‚µ‚Ä‚­‚¾‚³‚¢"
+
+#, c-format
+msgid "Save changes to \"%s\"?"
+msgstr "•ÏX‚ð \"%s\" ‚ɕۑ¶‚µ‚Ü‚·‚©?"
+
+msgid "Untitled"
+msgstr "–³‘è"
+
+#, c-format
+msgid "E162: No write since last change for buffer \"%s\""
+msgstr "E162: ƒoƒbƒtƒ@ \"%s\" ‚Ì•ÏX‚͕ۑ¶‚³‚ê‚Ä‚¢‚Ü‚¹‚ñ"
+
+msgid "Warning: Entered other buffer unexpectedly (check autocommands)"
+msgstr "Œx: —\\Šú‚¹‚¸‘¼ƒoƒbƒtƒ@‚ÖˆÚ“®‚µ‚Ü‚µ‚½ (autocommands ‚𒲂ׂĂ­‚¾‚³‚¢)"
+
+msgid "E163: There is only one file to edit"
+msgstr "E163: •ÒW‚·‚éƒtƒ@ƒCƒ‹‚Í1‚‚µ‚©‚ ‚è‚Ü‚¹‚ñ"
+
+msgid "E164: Cannot go before first file"
+msgstr "E164: ʼn‚̃tƒ@ƒCƒ‹‚æ‚è‘O‚É‚Ís‚¯‚Ü‚¹‚ñ"
+
+msgid "E165: Cannot go beyond last file"
+msgstr "E165: ÅŒã‚̃tƒ@ƒCƒ‹‚ð‰z‚¦‚ÄŒã‚É‚Ís‚¯‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "E666: compiler not supported: %s"
+msgstr "E666: ‚»‚̃Rƒ“ƒpƒCƒ‰‚ɂ͑Ήž‚µ‚Ä‚¢‚Ü‚¹‚ñ: %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 'runtimepath': \"%s\""
+msgstr "'runtimepath' ‚Ì’†‚ɂ͌©‚‚©‚è‚Ü‚¹‚ñ: \"%s\""
+
+msgid "Source Vim script"
+msgstr "VimƒXƒNƒŠƒvƒg‚ÌŽæž‚Ý"
+
+#, c-format
+msgid "Cannot source a directory: \"%s\""
+msgstr "ƒfƒBƒŒƒNƒgƒŠ‚͎枂߂܂¹‚ñ: \"%s\""
+
+#, c-format
+msgid "could not source \"%s\""
+msgstr "\"%s\" ‚ðŽæž‚߂܂¹‚ñ"
+
+#, c-format
+msgid "line %ld: could not source \"%s\""
+msgstr "s %ld: \"%s\" ‚ðŽæž‚߂܂¹‚ñ"
+
+#, c-format
+msgid "sourcing \"%s\""
+msgstr "\"%s\" ‚ðŽæž’†"
+
+#, c-format
+msgid "line %ld: sourcing \"%s\""
+msgstr "s %ld: %s ‚ðŽæž’†"
+
+#, c-format
+msgid "finished sourcing %s"
+msgstr "%s ‚ÌŽæž‚ðŠ®—¹"
+
+msgid "modeline"
+msgstr "ƒ‚[ƒhs"
+
+msgid "--cmd argument"
+msgstr "--cmd ˆø”"
+
+msgid "-c argument"
+msgstr "-c ˆø”"
+
+msgid "environment variable"
+msgstr "ŠÂ‹«•Ï”"
+
+msgid "error handler"
+msgstr "ƒGƒ‰[ƒnƒ“ƒhƒ‰"
+
+msgid "W15: Warning: Wrong line separator, ^M may be missing"
+msgstr "W15: Œx: s‹æØ‚ª•s³‚Å‚·. ^M ‚ª‚È‚¢‚̂łµ‚傤"
+
+msgid "E167: :scriptencoding used outside of a sourced file"
+msgstr "E167: :scriptencoding ‚ªŽæžƒXƒNƒŠƒvƒgˆÈŠO‚ÅŽg—p‚³‚ê‚Ü‚µ‚½"
+
+msgid "E168: :finish used outside of a sourced file"
+msgstr "E168: :finish ‚ªŽæžƒXƒNƒŠƒvƒgˆÈŠO‚ÅŽg—p‚³‚ê‚Ü‚µ‚½"
+
+#, 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ƒ‚[ƒh‚É“ü‚è‚Ü‚·. ƒm[ƒ}ƒ‹‚É–ß‚é‚É‚Í\"visual\"‚Æ“ü—Í‚µ‚Ä‚­‚¾‚³‚¢."
+
+msgid "E501: At end-of-file"
+msgstr "E501: ƒtƒ@ƒCƒ‹‚ÌI—¹ˆÊ’u"
+
+msgid "E169: Command too recursive"
+msgstr "E169: ƒRƒ}ƒ“ƒh‚ªÄ‹A“I‰ß‚¬‚Ü‚·"
+
+#, c-format
+msgid "E605: Exception not caught: %s"
+msgstr "E605: —áŠO‚ª•ß‘¨‚³‚ê‚Ü‚¹‚ñ‚Å‚µ‚½: %s"
+
+msgid "End of sourced file"
+msgstr "Žæžƒtƒ@ƒCƒ‹‚ÌÅŒã‚Å‚·"
+
+msgid "End of function"
+msgstr "ŠÖ”‚ÌÅŒã‚Å‚·"
+
+msgid "E464: Ambiguous use of user-defined command"
+msgstr "E464: ƒ†[ƒU’è‹`ƒRƒ}ƒ“ƒh‚Ì‚ ‚¢‚Ü‚¢‚ÈŽg—p‚Å‚·"
+
+msgid "E492: Not an editor command"
+msgstr "E492: ƒGƒfƒBƒ^‚̃Rƒ}ƒ“ƒh‚ł͂ ‚è‚Ü‚¹‚ñ"
+
+msgid "E493: Backwards range given"
+msgstr "E493: ‹t‚³‚܂͈̔͂ªŽw’肳‚ê‚Ü‚µ‚½"
+
+msgid "Backwards range given, OK to swap"
+msgstr "‹t‚³‚܂͈̔͂ªŽw’肳‚ê‚Ü‚µ‚½, “ü‘Ö‚¦‚Ü‚·‚©?"
+
+msgid "E494: Use w or w>>"
+msgstr "E494: w ‚à‚µ‚­‚Í w>> ‚ðŽg—p‚µ‚Ä‚­‚¾‚³‚¢"
+
+msgid "E319: Sorry, the command is not available in this version"
+msgstr "E319: ‚±‚̃o[ƒWƒ‡ƒ“‚ł͂±‚̃Rƒ}ƒ“ƒh‚Í—˜—p‚Å‚«‚Ü‚¹‚ñ, ‚²‚ß‚ñ‚È‚³‚¢"
+
+msgid "E172: Only one file name allowed"
+msgstr "E172: ƒtƒ@ƒCƒ‹–¼‚Í 1 ‚‚ɂµ‚Ä‚­‚¾‚³‚¢"
+
+msgid "1 more file to edit. Quit anyway?"
+msgstr "•ÒW‚·‚ׂ«ƒtƒ@ƒCƒ‹‚ª 1 ŒÂ‚ ‚è‚Ü‚·‚ª, I—¹‚µ‚Ü‚·‚©?"
+
+#, c-format
+msgid "%d more files to edit. Quit anyway?"
+msgstr "•ÒW‚·‚ׂ«ƒtƒ@ƒCƒ‹‚ª‚ ‚Æ %d ŒÂ‚ ‚è‚Ü‚·‚ª, I—¹‚µ‚Ü‚·‚©?"
+
+msgid "E173: 1 more file to edit"
+msgstr "E173: •ÒW‚·‚ׂ«ƒtƒ@ƒCƒ‹‚ª 1 ŒÂ‚ ‚è‚Ü‚·"
+
+#, c-format
+msgid "E173: %ld more files to edit"
+msgstr "E173: •ÒW‚·‚ׂ«ƒtƒ@ƒCƒ‹‚ª‚ ‚Æ %ld ŒÂ‚ ‚è‚Ü‚·"
+
+msgid "E174: Command already exists: add ! to replace it"
+msgstr "E174: ƒRƒ}ƒ“ƒh‚ªŠù‚É‚ ‚è‚Ü‚·: Ä’è‹`‚·‚é‚É‚Í ! ‚ð’ljÁ‚µ‚Ä‚­‚¾‚³‚¢"
+
+msgid ""
+"\n"
+" Name Args Range Complete Definition"
+msgstr ""
+"\n"
+" –¼‘O ˆø” ”ÍˆÍ •⊮ ’è‹`"
+
+msgid "No user-defined commands found"
+msgstr "ƒ†[ƒU’è‹`ƒRƒ}ƒ“ƒh‚ªŒ©‚‚©‚è‚Ü‚¹‚ñ‚Å‚µ‚½"
+
+msgid "E175: No attribute specified"
+msgstr "E175: ‘®«‚Í’è‹`‚³‚ê‚Ä‚¢‚Ü‚¹‚ñ"
+
+msgid "E176: Invalid number of arguments"
+msgstr "E176: ˆø”‚Ì”‚ª–³Œø‚Å‚·"
+
+msgid "E177: Count cannot be specified twice"
+msgstr "E177: ƒJƒEƒ“ƒg‚ð2dŽw’è‚·‚邱‚Ƃ͂ł«‚Ü‚¹‚ñ"
+
+msgid "E178: Invalid default value for count"
+msgstr "E178: ƒJƒEƒ“ƒg‚ÌÈ—ª’l‚ª–³Œø‚Å‚·"
+
+msgid "E179: argument required for -complete"
+msgstr "E179: -•⊮‚Ì‚½‚߂̈ø”‚ª•K—v‚Å‚·"
+
+#, c-format
+msgid "E181: Invalid attribute: %s"
+msgstr "E181: –³Œø‚È‘®«‚Å‚·: %s"
+
+msgid "E182: Invalid command name"
+msgstr "E182: –³Œø‚ȃRƒ}ƒ“ƒh–¼‚Å‚·"
+
+msgid "E183: User defined commands must start with an uppercase letter"
+msgstr "E183: ƒ†[ƒU’è‹`ƒRƒ}ƒ“ƒh‚͉p‘å•¶Žš‚ÅŽn‚Ü‚ç‚È‚¯‚ê‚΂Ȃè‚Ü‚¹‚ñ"
+
+msgid "E841: Reserved name, cannot be used for user defined command"
+msgstr "E841: —\\–ñ–¼‚Ȃ̂Å, ƒ†[ƒU’è‹`ƒRƒ}ƒ“ƒh‚É—˜—p‚Å‚«‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "E184: No such user-defined command: %s"
+msgstr "E184: ‚»‚̃†[ƒU’è‹`ƒRƒ}ƒ“ƒh‚Í‚ ‚è‚Ü‚¹‚ñ: %s"
+
+#, c-format
+msgid "E180: Invalid complete value: %s"
+msgstr "E180: –³Œø‚ȕ⊮Žw’è‚Å‚·: %s"
+
+msgid "E468: Completion argument only allowed for custom completion"
+msgstr "E468: •⊮ˆø”‚̓JƒXƒ^ƒ€•⊮‚Å‚µ‚©Žg—p‚Å‚«‚Ü‚¹‚ñ"
+
+msgid "E467: Custom completion requires a function argument"
+msgstr "E467: ƒJƒXƒ^ƒ€•⊮‚ɂ͈ø”‚Æ‚µ‚ÄŠÖ”‚ª•K—v‚Å‚·"
+
+msgid "unknown"
+msgstr "•s–¾"
+
+#, c-format
+msgid "E185: Cannot find color scheme '%s'"
+msgstr "E185: ƒJƒ‰[ƒXƒL[ƒ€ '%s' ‚ªŒ©‚‚©‚è‚Ü‚¹‚ñ"
+
+msgid "Greetings, Vim user!"
+msgstr "Vim Žg‚¢‚³‚ñA‚â‚ !"
+
+msgid "E784: Cannot close last tab page"
+msgstr "E784: ÅŒã‚̃^ƒuƒy[ƒW‚ð•‚¶‚邱‚Ƃ͂ł«‚Ü‚¹‚ñ"
+
+msgid "Already only one tab page"
+msgstr "Šù‚Ƀ^ƒuƒy[ƒW‚Í1‚‚µ‚©‚ ‚è‚Ü‚¹‚ñ"
+
+msgid "Edit File in new window"
+msgstr "V‚µ‚¢ƒEƒBƒ“ƒhƒE‚Ńtƒ@ƒCƒ‹‚ð•ÒW‚µ‚Ü‚·"
+
+#, c-format
+msgid "Tab page %d"
+msgstr "ƒ^ƒuƒy[ƒW %d"
+
+msgid "No swap file"
+msgstr "ƒXƒƒbƒvƒtƒ@ƒCƒ‹‚ª‚ ‚è‚Ü‚¹‚ñ"
+
+msgid "Append File"
+msgstr "’ljÁƒtƒ@ƒCƒ‹"
+
+msgid "E747: Cannot change directory, buffer is modified (add ! to override)"
+msgstr ""
+"E747: ƒoƒbƒtƒ@‚ªC³‚³‚ê‚Ä‚¢‚é‚Ì‚Å, ƒfƒBƒŒƒNƒgƒŠ‚ð•ÏX‚Å‚«‚Ü‚¹‚ñ (! ‚ð’ljÁ‚Å"
+"ã‘)"
+
+msgid "E186: No previous directory"
+msgstr "E186: ‘O‚̃fƒBƒŒƒNƒgƒŠ‚Í‚ ‚è‚Ü‚¹‚ñ"
+
+msgid "E187: Unknown"
+msgstr "E187: –¢’m"
+
+msgid "E465: :winsize requires two number arguments"
+msgstr "E465: :winsize ‚É‚Í2‚‚̔’l‚̈ø”‚ª•K—v‚Å‚·"
+
+#, c-format
+msgid "Window position: X %d, Y %d"
+msgstr "ƒEƒBƒ“ƒhƒEˆÊ’u: X %d, Y %d"
+
+msgid "E188: Obtaining window position not implemented for this platform"
+msgstr ""
+"E188: ‚±‚̃vƒ‰ƒbƒgƒz[ƒ€‚ɂ̓EƒBƒ“ƒhƒEˆÊ’u‚̎擾‹@”\\‚ÍŽÀ‘•‚³‚ê‚Ä‚¢‚Ü‚¹‚ñ"
+
+msgid "E466: :winpos requires two number arguments"
+msgstr "E466: :winpos ‚É‚Í2‚‚̔’l‚̈ø”‚ª•K—v‚Å‚·"
+
+msgid "Save Redirection"
+msgstr "ƒŠƒ_ƒCƒŒƒNƒg‚ð•Û‘¶‚µ‚Ü‚·"
+
+msgid "Save View"
+msgstr "ƒrƒ…[‚ð•Û‘¶‚µ‚Ü‚·"
+
+msgid "Save Session"
+msgstr "ƒZƒbƒVƒ‡ƒ“î•ñ‚ð•Û‘¶‚µ‚Ü‚·"
+
+msgid "Save Setup"
+msgstr "Ý’è‚ð•Û‘¶‚µ‚Ü‚·"
+
+#, c-format
+msgid "E739: Cannot create directory: %s"
+msgstr "E739: ƒfƒBƒŒƒNƒgƒŠ‚ð쬂ł«‚Ü‚¹‚ñ: %s"
+
+#, c-format
+msgid "E189: \"%s\" exists (add ! to override)"
+msgstr "E189: \"%s\" ‚ª‘¶Ý‚µ‚Ü‚· (ã‘‚·‚é‚É‚Í ! ‚ð’ljÁ‚µ‚Ä‚­‚¾‚³‚¢)"
+
+#, c-format
+msgid "E190: Cannot open \"%s\" for writing"
+msgstr "E190: \"%s\" ‚𑞂ݗp‚Æ‚µ‚ÄŠJ‚¯‚Ü‚¹‚ñ"
+
+#. set mark
+msgid "E191: Argument must be a letter or forward/backward quote"
+msgstr "E191: ˆø”‚Í1•¶Žš‚̉pŽš‚©ˆø—p•„ (' ‚© `) ‚łȂ¯‚ê‚΂¢‚¯‚Ü‚¹‚ñ"
+
+msgid "E192: Recursive use of :normal too deep"
+msgstr "E192: :normal ‚ÌÄ‹A—˜—p‚ª[‚­‚È‚è‰ß‚¬‚Ü‚µ‚½"
+
+msgid "E809: #< is not available without the +eval feature"
+msgstr "E809: #< ‚Í +eval ‹@”\\‚ª–³‚¢‚Æ—˜—p‚Å‚«‚Ü‚¹‚ñ"
+
+msgid "E194: No alternate file name to substitute for '#'"
+msgstr "E194: '#'‚ð’u‚«Š·‚¦‚é•›ƒtƒ@ƒCƒ‹‚Ì–¼‘O‚ª‚ ‚è‚Ü‚¹‚ñ"
+
+msgid "E495: no autocommand file name to substitute for \"<afile>\""
+msgstr "E495: \"<afile>\"‚ð’u‚«Š·‚¦‚éautocommand‚̃tƒ@ƒCƒ‹–¼‚ª‚ ‚è‚Ü‚¹‚ñ"
+
+msgid "E496: no autocommand buffer number to substitute for \"<abuf>\""
+msgstr "E496: \"<abuf>\"‚ð’u‚«Š·‚¦‚éautocommandƒoƒbƒtƒ@”Ô†‚ª‚ ‚è‚Ü‚¹‚ñ"
+
+msgid "E497: no autocommand match name to substitute for \"<amatch>\""
+msgstr "E497: \"<amatch>\"‚ð’u‚«Š·‚¦‚éautocommand‚ÌŠY“––¼‚ª‚ ‚è‚Ü‚¹‚ñ"
+
+msgid "E498: no :source file name to substitute for \"<sfile>\""
+msgstr "E498: \"<sfile>\"‚ð’u‚«Š·‚¦‚é :source ‘ÎÛƒtƒ@ƒCƒ‹–¼‚ª‚ ‚è‚Ü‚¹‚ñ"
+
+msgid "E842: no line number to use for \"<slnum>\""
+msgstr "E842: \"<slnum>\"‚ð’u‚«Š·‚¦‚és”Ô†‚ª‚ ‚è‚Ü‚¹‚ñ"
+
+#, no-c-format
+msgid "E499: Empty file name for '%' or '#', only works with \":p:h\""
+msgstr ""
+"E499: '%' ‚â '#' ‚ª–³–¼ƒtƒ@ƒCƒ‹‚Ȃ̂Š\":p:h\" ‚𔺂í‚È‚¢Žg‚¢•û‚͂ł«‚Ü‚¹‚ñ"
+
+msgid "E500: Evaluates to an empty string"
+msgstr "E500: ‹ó•¶Žš—ñ‚Æ‚µ‚Ä•]‰¿‚³‚ê‚Ü‚µ‚½"
+
+msgid "E195: Cannot open viminfo file for reading"
+msgstr "E195: viminfoƒtƒ@ƒCƒ‹‚ð“Çž—p‚Æ‚µ‚ÄŠJ‚¯‚Ü‚¹‚ñ"
+
+msgid "E196: No digraphs in this version"
+msgstr "E196: ‚±‚̃o[ƒWƒ‡ƒ“‚É‡Žš‚Í‚ ‚è‚Ü‚¹‚ñ"
+
+msgid "E608: Cannot :throw exceptions with 'Vim' prefix"
+msgstr "E608: 'Vim' ‚ÅŽn‚Ü‚é—áŠO‚Í :throw ‚Å‚«‚Ü‚¹‚ñ"
+
+#. always scroll up, don't overwrite
+#, c-format
+msgid "Exception thrown: %s"
+msgstr "—áŠO‚ª”­¶‚µ‚Ü‚µ‚½: %s"
+
+#, c-format
+msgid "Exception finished: %s"
+msgstr "—áŠO‚ªŽû‘©‚µ‚Ü‚µ‚½: %s"
+
+#, c-format
+msgid "Exception discarded: %s"
+msgstr "—áŠO‚ª”jŠü‚³‚ê‚Ü‚µ‚½: %s"
+
+#, c-format
+msgid "%s, line %ld"
+msgstr "%s, s %ld"
+
+#. always scroll up, don't overwrite
+#, c-format
+msgid "Exception caught: %s"
+msgstr "—áŠO‚ª•ß‘¨‚³‚ê‚Ü‚µ‚½: %s"
+
+#, c-format
+msgid "%s made pending"
+msgstr "%s ‚É‚æ‚è–¢Œˆ’èó‘Ô‚ª¶‚¶‚Ü‚µ‚½"
+
+#, c-format
+msgid "%s resumed"
+msgstr "%s ‚ªÄŠJ‚µ‚Ü‚µ‚½"
+
+#, c-format
+msgid "%s discarded"
+msgstr "%s ‚ª”jŠü‚³‚ê‚Ü‚µ‚½"
+
+msgid "Exception"
+msgstr "—áŠO"
+
+msgid "Error and interrupt"
+msgstr "ƒGƒ‰[‚ÆŠ„ž‚Ý"
+
+msgid "Error"
+msgstr "ƒGƒ‰["
+
+#. if (pending & CSTP_INTERRUPT)
+msgid "Interrupt"
+msgstr "Š„ž‚Ý"
+
+msgid "E579: :if nesting too deep"
+msgstr "E579: :if ‚Ì“ü‚êŽq‚ª[‰ß‚¬‚Ü‚·"
+
+msgid "E580: :endif without :if"
+msgstr "E580: :if ‚̂Ȃ¢ :endif ‚ª‚ ‚è‚Ü‚·"
+
+msgid "E581: :else without :if"
+msgstr "E581: :if ‚̂Ȃ¢ :else ‚ª‚ ‚è‚Ü‚·"
+
+msgid "E582: :elseif without :if"
+msgstr "E582: :if ‚̂Ȃ¢ :elseif ‚ª‚ ‚è‚Ü‚·"
+
+msgid "E583: multiple :else"
+msgstr "E583: •¡”‚Ì :else ‚ª‚ ‚è‚Ü‚·"
+
+msgid "E584: :elseif after :else"
+msgstr "E584: :else ‚ÌŒã‚É :elseif ‚ª‚ ‚è‚Ü‚·"
+
+msgid "E585: :while/:for nesting too deep"
+msgstr "E585: :while ‚â :for ‚Ì“ü‚êŽq‚ª[‰ß‚¬‚Ü‚·"
+
+msgid "E586: :continue without :while or :for"
+msgstr "E586: :while ‚â :for ‚̂Ȃ¢ :continue ‚ª‚ ‚è‚Ü‚·"
+
+msgid "E587: :break without :while or :for"
+msgstr "E587: :while ‚â :for ‚̂Ȃ¢ :break ‚ª‚ ‚è‚Ü‚·"
+
+msgid "E732: Using :endfor with :while"
+msgstr "E732: :endfor ‚ð :while ‚Æ‘g‚݇‚킹‚Ä‚¢‚Ü‚·"
+
+msgid "E733: Using :endwhile with :for"
+msgstr "E733: :endwhile ‚ð :for ‚Æ‘g‚݇‚킹‚Ä‚¢‚Ü‚·"
+
+msgid "E601: :try nesting too deep"
+msgstr "E601: :try ‚Ì“ü‚êŽq‚ª[‰ß‚¬‚Ü‚·"
+
+msgid "E603: :catch without :try"
+msgstr "E603: :try ‚̂Ȃ¢ :catch ‚ª‚ ‚è‚Ü‚·"
+
+#. Give up for a ":catch" after ":finally" and ignore it.
+#. * Just parse.
+msgid "E604: :catch after :finally"
+msgstr "E604: :finally ‚ÌŒã‚É :catch ‚ª‚ ‚è‚Ü‚·"
+
+msgid "E606: :finally without :try"
+msgstr "E606: :try ‚̂Ȃ¢ :finally ‚ª‚ ‚è‚Ü‚·"
+
+#. Give up for a multiple ":finally" and ignore it.
+msgid "E607: multiple :finally"
+msgstr "E607: •¡”‚Ì :finally ‚ª‚ ‚è‚Ü‚·"
+
+msgid "E602: :endtry without :try"
+msgstr "E602: :try ‚̂Ȃ¢ :endtry ‚Å‚·"
+
+msgid "E193: :endfunction not inside a function"
+msgstr "E193: ŠÖ”‚ÌŠO‚É :endfunction ‚ª‚ ‚è‚Ü‚µ‚½"
+
+msgid "E788: Not allowed to edit another buffer now"
+msgstr "E788: Œ»Ý‚Í‘¼‚̃oƒbƒtƒ@‚ð•ÒW‚·‚邱‚Ƃ͋–‚³‚ê‚Ü‚¹‚ñ"
+
+msgid "E811: Not allowed to change buffer information now"
+msgstr "E811: Œ»Ý‚̓oƒbƒtƒ@î•ñ‚ð•ÏX‚·‚邱‚Ƃ͋–‚³‚ê‚Ü‚¹‚ñ"
+
+msgid "tagname"
+msgstr "ƒ^ƒO–¼"
+
+msgid " kind file\n"
+msgstr " ƒtƒ@ƒCƒ‹Ží—Þ\n"
+
+msgid "'history' option is zero"
+msgstr "ƒIƒvƒVƒ‡ƒ“ 'history' ‚ªƒ[ƒ‚Å‚·"
+
+#, c-format
+msgid ""
+"\n"
+"# %s History (newest to oldest):\n"
+msgstr ""
+"\n"
+"# %s €–Ú‚Ì—š—ð (V‚µ‚¢‚à‚Ì‚©‚çŒÃ‚¢‚à‚Ì‚Ö):\n"
+
+msgid "Command Line"
+msgstr "ƒRƒ}ƒ“ƒhƒ‰ƒCƒ“"
+
+msgid "Search String"
+msgstr "ŒŸõ•¶Žš—ñ"
+
+msgid "Expression"
+msgstr "Ž®"
+
+msgid "Input Line"
+msgstr "“ü—Ís"
+
+msgid "E198: cmd_pchar beyond the command length"
+msgstr "E198: cmd_pchar ‚ªƒRƒ}ƒ“ƒh’·‚ð’´‚¦‚Ü‚µ‚½"
+
+msgid "E199: Active window or buffer deleted"
+msgstr "E199: ƒAƒNƒeƒBƒu‚ȃEƒBƒ“ƒhƒE‚©ƒoƒbƒtƒ@‚ªíœ‚³‚ê‚Ü‚µ‚½"
+
+msgid "E812: Autocommands changed buffer or buffer name"
+msgstr "E812: autocommand‚ªƒoƒbƒtƒ@‚©ƒoƒbƒtƒ@–¼‚ð•ÏX‚µ‚Ü‚µ‚½"
+
+msgid "Illegal file name"
+msgstr "•s³‚ȃtƒ@ƒCƒ‹–¼"
+
+msgid "is a directory"
+msgstr " ‚̓fƒBƒŒƒNƒgƒŠ‚Å‚·"
+
+msgid "is not a file"
+msgstr " ‚̓tƒ@ƒCƒ‹‚ł͂ ‚è‚Ü‚¹‚ñ"
+
+msgid "is a device (disabled with 'opendevice' option)"
+msgstr " ‚̓fƒoƒCƒX‚Å‚· ('opendevice' ƒIƒvƒVƒ‡ƒ“‚ʼnñ”ð‚Å‚«‚Ü‚·)"
+
+msgid "[New File]"
+msgstr "[Vƒtƒ@ƒCƒ‹]"
+
+msgid "[New DIRECTORY]"
+msgstr "[V‹KƒfƒBƒŒƒNƒgƒŠ]"
+
+msgid "[File too big]"
+msgstr "[ƒtƒ@ƒCƒ‹‰ß‘å]"
+
+msgid "[Permission Denied]"
+msgstr "[”F‰Â‚ª‚ ‚è‚Ü‚¹‚ñ]"
+
+msgid "E200: *ReadPre autocommands made the file unreadable"
+msgstr "E200: *ReadPre autocommand ‚ªƒtƒ@ƒCƒ‹‚ð“Çž•s‰Â‚É‚µ‚Ü‚µ‚½"
+
+msgid "E201: *ReadPre autocommands must not change current buffer"
+msgstr "E201: *ReadPre autocommand ‚ÍŒ»Ý‚̃oƒbƒtƒ@‚ð•Ï‚¦‚ç‚ê‚Ü‚¹‚ñ"
+
+msgid "Vim: Reading from stdin...\n"
+msgstr "Vim: •W€“ü—Í‚©‚ç“Çž’†...\n"
+
+msgid "Reading from stdin..."
+msgstr "•W€“ü—Í‚©‚ç“Çž‚Ý’†..."
+
+#. Re-opening the original file failed!
+msgid "E202: Conversion made file unreadable!"
+msgstr "E202: •ÏŠ·‚ªƒtƒ@ƒCƒ‹‚ð“Çž•s‰Â‚É‚µ‚Ü‚µ‚½"
+
+msgid "[fifo/socket]"
+msgstr "[FIFO/ƒ\\ƒPƒbƒg]"
+
+msgid "[fifo]"
+msgstr "[FIFO]"
+
+msgid "[socket]"
+msgstr "[ƒ\\ƒPƒbƒg]"
+
+msgid "[character special]"
+msgstr "[ƒLƒƒƒ‰ƒNƒ^EƒfƒoƒCƒX]"
+
+msgid "[CR missing]"
+msgstr "[CR–³]"
+
+msgid "[long lines split]"
+msgstr "[’·s•ªŠ„]"
+
+msgid "[NOT converted]"
+msgstr "[–¢•ÏŠ·]"
+
+msgid "[converted]"
+msgstr "[•ÏŠ·Ï]"
+
+msgid "[blowfish]"
+msgstr "[blowfishˆÃ†‰»]"
+
+msgid "[crypted]"
+msgstr "[ˆÃ†‰»]"
+
+#, c-format
+msgid "[CONVERSION ERROR in line %ld]"
+msgstr "[%ld s–ڂŕϊ·ƒGƒ‰[]"
+
+#, c-format
+msgid "[ILLEGAL BYTE in line %ld]"
+msgstr "[%ld s–Ú‚Ì•s³‚ȃoƒCƒg]"
+
+msgid "[READ ERRORS]"
+msgstr "[“ÇžƒGƒ‰[]"
+
+msgid "Can't find temp file for conversion"
+msgstr "•ÏŠ·‚É•K—v‚Ȉꎞƒtƒ@ƒCƒ‹‚ªŒ©‚‚©‚è‚Ü‚¹‚ñ"
+
+msgid "Conversion with 'charconvert' failed"
+msgstr "'charconvert' ‚É‚æ‚é•ÏŠ·‚ªŽ¸”s‚µ‚Ü‚µ‚½"
+
+msgid "can't read output of 'charconvert'"
+msgstr "'charconvert' ‚Ìo—Í‚ð“Çž‚߂܂¹‚ñ‚Å‚µ‚½"
+
+msgid "E821: File is encrypted with unknown method"
+msgstr "E821: ƒtƒ@ƒCƒ‹‚ª–¢’m‚Ì•û–@‚ňƉ»‚³‚ê‚Ä‚¢‚Ü‚·"
+
+msgid "E676: No matching autocommands for acwrite buffer"
+msgstr "E676: acwriteƒoƒbƒtƒ@‚ÌŠY“–‚·‚éautocommand‚Í‘¶Ý‚µ‚Ü‚¹‚ñ"
+
+msgid "E203: Autocommands deleted or unloaded buffer to be written"
+msgstr "E203: •Û‘¶‚·‚éƒoƒbƒtƒ@‚ðautocommand‚ªíœ‚©‰ð•ú‚µ‚Ü‚µ‚½"
+
+msgid "E204: Autocommand changed number of lines in unexpected way"
+msgstr "E204: autocommand‚ª—\\Šú‚¹‚Ê•û–@‚Ås”‚ð•ÏX‚µ‚Ü‚µ‚½"
+
+# 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 "is not a file or writable device"
+msgstr "‚̓tƒ@ƒCƒ‹‚Å‚à‘ž‚݉”\\ƒfƒoƒCƒX‚Å‚à‚ ‚è‚Ü‚¹‚ñ"
+
+msgid "writing to device disabled with 'opendevice' option"
+msgstr "'opendevice' ƒIƒvƒVƒ‡ƒ“‚É‚æ‚èƒfƒoƒCƒX‚Ö‚Ì‘‚«ž‚݂͂ł«‚Ü‚¹‚ñ"
+
+msgid "is read-only (add ! to override)"
+msgstr "‚͓Ǟê—p‚Å‚· (‹­§‘ž‚É‚Í ! ‚ð’ljÁ)"
+
+msgid "E506: Can't write to backup file (add ! to override)"
+msgstr "E506: ƒoƒbƒNƒAƒbƒvƒtƒ@ƒCƒ‹‚ð•Û‘¶‚Å‚«‚Ü‚¹‚ñ (! ‚ð’ljÁ‚Å‹­§•Û‘¶)"
+
+msgid "E507: Close error for backup file (add ! to override)"
+msgstr ""
+"E507: ƒoƒbƒNƒAƒbƒvƒtƒ@ƒCƒ‹‚ð•‚¶‚éۂɃGƒ‰[‚ª”­¶‚µ‚Ü‚µ‚½ (! ‚ð’ljÁ‚Å‹­§)"
+
+msgid "E508: Can't read file for backup (add ! to override)"
+msgstr "E508: ƒoƒbƒNƒAƒbƒv—pƒtƒ@ƒCƒ‹‚ð“Çž‚߂܂¹‚ñ (! ‚ð’ljÁ‚Å‹­§“Çž)"
+
+msgid "E509: Cannot create backup file (add ! to override)"
+msgstr "E509: ƒoƒbƒNƒAƒbƒvƒtƒ@ƒCƒ‹‚ðì‚ê‚Ü‚¹‚ñ (! ‚ð’ljÁ‚Å‹­§ì¬)"
+
+msgid "E510: Can't make backup file (add ! to override)"
+msgstr "E510: ƒoƒbƒNƒAƒbƒvƒtƒ@ƒCƒ‹‚ðì‚ê‚Ü‚¹‚ñ (! ‚ð’ljÁ‚Å‹­§ì¬)"
+
+msgid "E460: The resource fork would be lost (add ! to override)"
+msgstr "E460: ƒŠƒ\\[ƒXƒtƒH[ƒN‚ªŽ¸‚í‚ê‚é‚©‚à‚µ‚ê‚Ü‚¹‚ñ (! ‚ð’ljÁ‚Å‹­§)"
+
+msgid "E214: Can't find temp file for writing"
+msgstr "E214: •Û‘¶—pˆêŽžƒtƒ@ƒCƒ‹‚ªŒ©‚‚©‚è‚Ü‚¹‚ñ"
+
+msgid "E213: Cannot convert (add ! to write without conversion)"
+msgstr "E213: •ÏŠ·‚Å‚«‚Ü‚¹‚ñ (! ‚ð’ljÁ‚ŕϊ·‚¹‚¸‚ɕۑ¶)"
+
+msgid "E166: Can't open linked file for writing"
+msgstr "E166: ƒŠƒ“ƒN‚³‚ꂽƒtƒ@ƒCƒ‹‚É‘ž‚߂܂¹‚ñ"
+
+msgid "E212: Can't open file for writing"
+msgstr "E212: ‘ž‚Ý—p‚Ƀtƒ@ƒCƒ‹‚ðŠJ‚¯‚Ü‚¹‚ñ"
+
+msgid "E667: Fsync failed"
+msgstr "E667: fsync ‚ÉŽ¸”s‚µ‚Ü‚µ‚½"
+
+msgid "E512: Close failed"
+msgstr "E512: •‚¶‚邱‚ƂɎ¸”s"
+
+msgid "E513: write error, conversion failed (make 'fenc' empty to override)"
+msgstr "E513: ‘ž‚݃Gƒ‰[, •ÏŠ·Ž¸”s (ã‘‚·‚é‚É‚Í 'fenc' ‚ð‹ó‚É‚µ‚Ä‚­‚¾‚³‚¢)"
+
+#, c-format
+msgid ""
+"E513: write error, conversion failed in line %ld (make 'fenc' empty to "
+"override)"
+msgstr ""
+"E513: ‘ž‚݃Gƒ‰[, •ÏŠ·Ž¸”s, s” %ld (ã‘‚·‚é‚É‚Í 'fenc' ‚ð‹ó‚É‚µ‚Ä‚­‚¾‚³"
+"‚¢)"
+
+msgid "E514: write error (file system full?)"
+msgstr "E514: ‘ž‚݃Gƒ‰[, (ƒtƒ@ƒCƒ‹ƒVƒXƒeƒ€‚ª–ž”t?)"
+
+msgid " CONVERSION ERROR"
+msgstr " •ÏŠ·ƒGƒ‰["
+
+#, c-format
+msgid " in line %ld;"
+msgstr "s %ld;"
+
+msgid "[Device]"
+msgstr "[ƒfƒoƒCƒX]"
+
+msgid "[New]"
+msgstr "[V]"
+
+msgid " [a]"
+msgstr " [a]"
+
+msgid " appended"
+msgstr " ’ljÁ"
+
+msgid " [w]"
+msgstr " [w]"
+
+msgid " written"
+msgstr " ‘ž‚Ý"
+
+msgid "E205: Patchmode: can't save original file"
+msgstr "E205: patchmode: Œ´–{ƒtƒ@ƒCƒ‹‚ð•Û‘¶‚Å‚«‚Ü‚¹‚ñ"
+
+msgid "E206: patchmode: can't touch empty original file"
+msgstr "E206: patchmode: ‹ó‚ÌŒ´–{ƒtƒ@ƒCƒ‹‚ðtouch‚Å‚«‚Ü‚¹‚ñ"
+
+msgid "E207: Can't delete backup file"
+msgstr "E207: ƒoƒbƒNƒAƒbƒvƒtƒ@ƒCƒ‹‚ðÁ‚¹‚Ü‚¹‚ñ"
+
+msgid ""
+"\n"
+"WARNING: Original file may be lost or damaged\n"
+msgstr ""
+"\n"
+"Œx: Œ´–{ƒtƒ@ƒCƒ‹‚ªŽ¸‚í‚ꂽ‚©•ÏX‚³‚ê‚Ü‚µ‚½\n"
+
+msgid "don't quit the editor until the file is successfully written!"
+msgstr "ƒtƒ@ƒCƒ‹‚̕ۑ¶‚ɬŒ÷‚·‚é‚܂ŃGƒfƒBƒ^‚ðI—¹‚µ‚È‚¢‚Å‚­‚¾‚³‚¢!"
+
+msgid "[dos]"
+msgstr "[dos]"
+
+msgid "[dos format]"
+msgstr "[dosƒtƒH[ƒ}ƒbƒg]"
+
+msgid "[mac]"
+msgstr "[mac]"
+
+msgid "[mac format]"
+msgstr "[macƒtƒH[ƒ}ƒbƒg]"
+
+msgid "[unix]"
+msgstr "[unix]"
+
+msgid "[unix format]"
+msgstr "[unixƒtƒH[ƒ}ƒbƒg]"
+
+msgid "1 line, "
+msgstr "1 s, "
+
+#, c-format
+msgid "%ld lines, "
+msgstr "%ld s, "
+
+msgid "1 character"
+msgstr "1 •¶Žš"
+
+#, c-format
+msgid "%lld characters"
+msgstr "%lld •¶Žš"
+
+#. Explicit typecast avoids warning on Mac OS X 10.6
+#, c-format
+msgid "%ld characters"
+msgstr "%ld •¶Žš"
+
+msgid "[noeol]"
+msgstr "[noeol]"
+
+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
+msgid "WARNING: The file has been changed since reading it!!!"
+msgstr "Œx: “Çž‚ñ‚¾Œã‚Ƀtƒ@ƒCƒ‹‚É•ÏX‚ª‚ ‚è‚Ü‚µ‚½!!!"
+
+msgid "Do you really want to write to it"
+msgstr "–{“–‚Éã‘‚«‚µ‚Ü‚·‚©"
+
+#, c-format
+msgid "E208: Error writing to \"%s\""
+msgstr "E208: \"%s\" ‚𑞂ݒ†‚̃Gƒ‰[‚Å‚·"
+
+#, c-format
+msgid "E209: Error closing \"%s\""
+msgstr "E209: \"%s\" ‚ð•‚¶‚鎞‚ɃGƒ‰[‚Å‚·"
+
+#, c-format
+msgid "E210: Error reading \"%s\""
+msgstr "E210: \"%s\" ‚ð“Çž’†‚̃Gƒ‰[‚Å‚·"
+
+msgid "E246: FileChangedShell autocommand deleted buffer"
+msgstr "E246: autocommand ‚Ì FileChangedShell ‚ªƒoƒbƒtƒ@‚ð휂µ‚Ü‚µ‚½"
+
+#, c-format
+msgid "E211: File \"%s\" no longer available"
+msgstr "E211: ƒtƒ@ƒCƒ‹ \"%s\" ‚ÍŠù‚É‘¶Ý‚µ‚Ü‚¹‚ñ"
+
+#, 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‚³‚ê‚Ü‚µ‚½"
+
+msgid "See \":help W12\" for more info."
+msgstr "Ú×‚Í \":help W12\" ‚ðŽQÆ‚µ‚Ä‚­‚¾‚³‚¢"
+
+#, c-format
+msgid "W11: Warning: File \"%s\" has changed since editing started"
+msgstr "W11: Œx: ƒtƒ@ƒCƒ‹ \"%s\" ‚Í•ÒWŠJŽnŒã‚É•ÏX‚³‚ê‚Ü‚µ‚½"
+
+msgid "See \":help W11\" for more info."
+msgstr "Ú×‚Í \":help W11\" ‚ðŽQÆ‚µ‚Ä‚­‚¾‚³‚¢"
+
+#, 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‚³‚ê‚Ü‚µ‚½"
+
+msgid "See \":help W16\" for more info."
+msgstr "Ú×‚Í \":help W16\" ‚ðŽQÆ‚µ‚Ä‚­‚¾‚³‚¢"
+
+#, c-format
+msgid "W13: Warning: File \"%s\" has been created after editing started"
+msgstr "W13: Œx: ƒtƒ@ƒCƒ‹ \"%s\" ‚Í•ÒWŠJŽnŒã‚É쬂³‚ê‚Ü‚µ‚½"
+
+msgid "Warning"
+msgstr "Œx"
+
+msgid ""
+"&OK\n"
+"&Load File"
+msgstr ""
+"&OK\n"
+"ƒtƒ@ƒCƒ‹“Çž(&L)"
+
+#, c-format
+msgid "E462: Could not prepare for reloading \"%s\""
+msgstr "E462: \"%s\" ‚ðƒŠƒ[ƒh‚·‚途õ‚ª‚Å‚«‚Ü‚¹‚ñ‚Å‚µ‚½"
+
+#, c-format
+msgid "E321: Could not reload \"%s\""
+msgstr "E321: \"%s\" ‚ÍƒŠƒ[ƒh‚Å‚«‚Ü‚¹‚ñ‚Å‚µ‚½"
+
+msgid "--Deleted--"
+msgstr "--íœÏ--"
+
+#, c-format
+msgid "auto-removing autocommand: %s <buffer=%d>"
+msgstr "autocommand: %s <ƒoƒbƒtƒ@=%d> ‚ªŽ©“®“I‚É휂³‚ê‚Ü‚·"
+
+#. the group doesn't exist
+#, c-format
+msgid "E367: No such group: \"%s\""
+msgstr "E367: ‚»‚̃Oƒ‹[ƒv‚Í‚ ‚è‚Ü‚¹‚ñ: \"%s\""
+
+#, c-format
+msgid "E215: Illegal character after *: %s"
+msgstr "E215: * ‚ÌŒã‚É•s³‚È•¶Žš‚ª‚ ‚è‚Ü‚µ‚½: %s"
+
+#, c-format
+msgid "E216: No such event: %s"
+msgstr "E216: ‚»‚̂悤‚ȃCƒxƒ“ƒg‚Í‚ ‚è‚Ü‚¹‚ñ: %s"
+
+#, c-format
+msgid "E216: No such group or event: %s"
+msgstr "E216: ‚»‚̂悤‚ȃOƒ‹[ƒv‚à‚µ‚­‚̓Cƒxƒ“ƒg‚Í‚ ‚è‚Ü‚¹‚ñ: %s"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Auto-Commands ---"
+msgstr ""
+"\n"
+"--- Auto-Commands ---"
+
+#, c-format
+msgid "E680: <buffer=%d>: invalid buffer number "
+msgstr "E680: <ƒoƒbƒtƒ@=%d>: –³Œø‚ȃoƒbƒtƒ@”Ô†‚Å‚· "
+
+msgid "E217: Can't execute autocommands for ALL events"
+msgstr "E217: ‘S‚ẴCƒxƒ“ƒg‚ɑ΂µ‚Ä‚Ìautocommand‚ÍŽÀs‚Å‚«‚Ü‚¹‚ñ"
+
+msgid "No matching autocommands"
+msgstr "ŠY“–‚·‚éautocommand‚Í‘¶Ý‚µ‚Ü‚¹‚ñ"
+
+msgid "E218: autocommand nesting too deep"
+msgstr "E218: autocommand‚Ì“ü‚êŽq‚ª[‰ß‚¬‚Ü‚·"
+
+#, c-format
+msgid "%s Auto commands for \"%s\""
+msgstr "%s Auto commands for \"%s\""
+
+#, c-format
+msgid "Executing %s"
+msgstr "%s ‚ðŽÀs‚µ‚Ä‚¢‚Ü‚·"
+
+#, c-format
+msgid "autocommand %s"
+msgstr "autocommand %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 lines folded "
+msgstr "+--%3ld s‚ªÜô‚Ü‚ê‚Ü‚µ‚½ "
+
+msgid "E222: Add to read buffer"
+msgstr "E222: “Çžƒoƒbƒtƒ@‚֒ljÁ"
+
+msgid "E223: recursive mapping"
+msgstr "E223: Ä‹A“Iƒ}ƒbƒsƒ“ƒO"
+
+#, c-format
+msgid "E224: global abbreviation already exists for %s"
+msgstr "E224: %s ‚Æ‚¢‚¤ƒOƒ[ƒoƒ‹’Zk“ü—͂͊ù‚É‘¶Ý‚µ‚Ü‚·"
+
+#, c-format
+msgid "E225: global mapping already exists for %s"
+msgstr "E225: %s ‚Æ‚¢‚¤ƒOƒ[ƒoƒ‹ƒ}ƒbƒsƒ“ƒO‚ÍŠù‚É‘¶Ý‚µ‚Ü‚·"
+
+#, c-format
+msgid "E226: abbreviation already exists for %s"
+msgstr "E226: %s ‚Æ‚¢‚¤’Zk“ü—͂͊ù‚É‘¶Ý‚µ‚Ü‚·"
+
+#, c-format
+msgid "E227: mapping already exists for %s"
+msgstr "E227: %s ‚Æ‚¢‚¤ƒ}ƒbƒsƒ“ƒO‚ÍŠù‚É‘¶Ý‚µ‚Ü‚·"
+
+msgid "No abbreviation found"
+msgstr "’Zk“ü—͂͌©‚‚©‚è‚Ü‚¹‚ñ‚Å‚µ‚½"
+
+msgid "No mapping found"
+msgstr "ƒ}ƒbƒsƒ“ƒO‚ÍŒ©‚‚©‚è‚Ü‚¹‚ñ‚Å‚µ‚½"
+
+msgid "E228: makemap: Illegal mode"
+msgstr "E228: makemap: •s³‚ȃ‚[ƒh"
+
+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‚Å‚«‚Ü‚¹‚ñ"
+
+#, c-format
+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‚ª–³Œø‚Å‚·"
+
+#, c-format
+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‚¯‚Ü‚¹‚ñ> "
+
+#, c-format
+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 ""
+"&Yes\n"
+"&No\n"
+"&Cancel"
+msgstr ""
+"‚Í‚¢(&Y)\n"
+"‚¢‚¢‚¦(&N)\n"
+"ƒLƒƒƒ“ƒZƒ‹(&C)"
+
+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Š·•¶Žš—ñ:"
+
+#. whole word only button
+msgid "Match whole word only"
+msgstr "³Šm‚ÉŠY“–‚·‚é‚à‚Ì‚¾‚¯"
+
+#. match case button
+msgid "Match case"
+msgstr "‘å•¶Žš/¬•¶Žš‚ð‹æ•Ê‚·‚é"
+
+msgid "Direction"
+msgstr "•ûŒü"
+
+#. 'Up' and 'Down' buttons
+msgid "Up"
+msgstr "ã"
+
+msgid "Down"
+msgstr "‰º"
+
+#. 'Find Next' button
+msgid "Find Next"
+msgstr "ŽŸ‚ðŒŸõ"
+
+#. 'Replace' button
+msgid "Replace"
+msgstr "’uŠ·"
+
+#. 'Replace All' button
+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)"
+
+#, c-format
+msgid "E671: Cannot find window title \"%s\""
+msgstr "E671: ƒ^ƒCƒgƒ‹‚ª \"%s\" ‚̃EƒBƒ“ƒhƒE‚ÍŒ©‚‚©‚è‚Ü‚¹‚ñ"
+
+#, c-format
+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Š· ('\\' ‚ðŒŸõ‚·‚é‚É‚Í '\\\\')"
+
+#. 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 "Ž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ƒŠ‚ðŠ„‚è“–‚Ä‚ç‚ê‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "E250: Fonts for the following charsets are missing in fontset %s:"
+msgstr "E250: ˆÈ‰º‚Ì•¶ŽšƒZƒbƒg‚̃tƒHƒ“ƒg‚ª‚ ‚è‚Ü‚¹‚ñ %s:"
+
+#, c-format
+msgid "E252: Fontset name: %s"
+msgstr "E252: ƒtƒHƒ“ƒgƒZƒbƒg–¼: %s"
+
+#, c-format
+msgid "Font '%s' is not fixed-width"
+msgstr "ƒtƒHƒ“ƒg '%s' ‚͌Œ蕂ł͂ ‚è‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "E253: Fontset name: %s"
+msgstr "E253: ƒtƒHƒ“ƒgƒZƒbƒg–¼: %s"
+
+#, c-format
+msgid "Font0: %s"
+msgstr "ƒtƒHƒ“ƒg0: %s"
+
+#, c-format
+msgid "Font1: %s"
+msgstr "ƒtƒHƒ“ƒg1: %s"
+
+#, c-format
+msgid "Font%ld width is not twice that of font0"
+msgstr "ƒtƒHƒ“ƒg%ld ‚Ì•‚ªƒtƒHƒ“ƒg0‚Ì2”{‚ł͂ ‚è‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "Font0 width: %ld"
+msgstr "ƒtƒHƒ“ƒg0‚Ì•: %ld"
+
+#, c-format
+msgid "Font1 width: %ld"
+msgstr "ƒtƒHƒ“ƒg1‚Ì•: %ld"
+
+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:"
+
+#. create toggle button
+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 "E550: Missing colon"
+msgstr "E550: ƒRƒƒ“‚ª‚ ‚è‚Ü‚¹‚ñ"
+
+msgid "E551: Illegal component"
+msgstr "E551: •s³‚È\\•¶—v‘f‚Å‚·"
+
+msgid "E552: digit expected"
+msgstr "E552: ”’l‚ª•K—v‚Å‚·"
+
+#, c-format
+msgid "Page %d"
+msgstr "%d ƒy[ƒW"
+
+msgid "No text to be printed"
+msgstr "ˆóü‚·‚éƒeƒLƒXƒg‚ª‚ ‚è‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "Printing page %d (%d%%)"
+msgstr "ˆóü’†: ƒy[ƒW %d (%d%%)"
+
+#, c-format
+msgid " Copy %d of %d"
+msgstr " ƒRƒs[ %d (‘S %d ’†)"
+
+#, c-format
+msgid "Printed: %s"
+msgstr "ˆóü‚µ‚Ü‚µ‚½: %s"
+
+msgid "Printing aborted"
+msgstr "ˆóü‚ª’†Ž~‚³‚ê‚Ü‚µ‚½"
+
+msgid "E455: Error writing to PostScript output file"
+msgstr "E455: PostScripto—̓tƒ@ƒCƒ‹‚Ì‘ž‚݃Gƒ‰[‚Å‚·"
+
+#, c-format
+msgid "E624: Can't open file \"%s\""
+msgstr "E624: ƒtƒ@ƒCƒ‹ \"%s\" ‚ðŠJ‚¯‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "E457: Can't read PostScript resource file \"%s\""
+msgstr "E457: PostScript‚ÌƒŠƒ\\[ƒXƒtƒ@ƒCƒ‹ \"%s\" ‚ð“Çž‚߂܂¹‚ñ"
+
+#, c-format
+msgid "E618: file \"%s\" is not a PostScript resource file"
+msgstr "E618: ƒtƒ@ƒCƒ‹ \"%s\" ‚Í PostScript ƒŠƒ\\[ƒXƒtƒ@ƒCƒ‹‚ł͂ ‚è‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "E619: file \"%s\" is not a supported PostScript resource file"
+msgstr "E619: ƒtƒ@ƒCƒ‹ \"%s\" ‚͑Ήž‚µ‚Ä‚¢‚È‚¢ PostScript ƒŠƒ\\[ƒXƒtƒ@ƒCƒ‹‚Å‚·"
+
+#, c-format
+msgid "E621: \"%s\" resource file has wrong version"
+msgstr "E621: ƒŠƒ\\[ƒXƒtƒ@ƒCƒ‹ \"%s\" ‚̓o[ƒWƒ‡ƒ“‚ªˆÙ‚È‚è‚Ü‚·"
+
+msgid "E673: Incompatible multi-byte encoding and character set."
+msgstr "E673: ŒÝŠ·«‚Ì–³‚¢ƒ}ƒ‹ƒ`ƒoƒCƒgƒGƒ“ƒR[ƒfƒBƒ“ƒO‚Æ•¶ŽšƒZƒbƒg‚Å‚·"
+
+msgid "E674: printmbcharset cannot be empty with multi-byte encoding."
+msgstr "E674: ƒ}ƒ‹ƒ`ƒoƒCƒgƒGƒ“ƒR[ƒfƒBƒ“ƒO‚Å‚Í printmbcharset ‚ð‹ó‚ɂł«‚Ü‚¹‚ñ"
+
+msgid "E675: No default font specified for multi-byte printing."
+msgstr ""
+"E675: ƒ}ƒ‹ƒ`ƒoƒCƒg•¶Žš‚ðˆóü‚·‚邽‚߂̃fƒtƒHƒ‹ƒgƒtƒHƒ“ƒg‚ªŽw’肳‚ê‚Ä‚¢‚Ü‚¹‚ñ"
+
+msgid "E324: Can't open PostScript output file"
+msgstr "E324: PostScripto—Í—p‚̃tƒ@ƒCƒ‹‚ðŠJ‚¯‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "E456: Can't open file \"%s\""
+msgstr "E456: ƒtƒ@ƒCƒ‹ \"%s\" ‚ðŠJ‚¯‚Ü‚¹‚ñ"
+
+msgid "E456: Can't find PostScript resource file \"prolog.ps\""
+msgstr "E456: PostScript‚ÌƒŠƒ\\[ƒXƒtƒ@ƒCƒ‹ \"prolog.ps\" ‚ªŒ©‚‚©‚è‚Ü‚¹‚ñ"
+
+msgid "E456: Can't find PostScript resource file \"cidfont.ps\""
+msgstr "E456: PostScript‚ÌƒŠƒ\\[ƒXƒtƒ@ƒCƒ‹ \"cidfont.ps\" ‚ªŒ©‚‚©‚è‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "E456: Can't find PostScript resource file \"%s.ps\""
+msgstr "E456: PostScript‚ÌƒŠƒ\\[ƒXƒtƒ@ƒCƒ‹ \"%s.ps\" ‚ªŒ©‚‚©‚è‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "E620: Unable to convert to print encoding \"%s\""
+msgstr "E620: ˆóüƒGƒ“ƒR[ƒh \"%s\" ‚Ö•ÏŠ·‚Å‚«‚Ü‚¹‚ñ"
+
+msgid "Sending to printer..."
+msgstr "ƒvƒŠƒ“ƒ^‚É‘—M’†..."
+
+msgid "E365: Failed to print PostScript file"
+msgstr "E365: PostScriptƒtƒ@ƒCƒ‹‚̈óü‚ÉŽ¸”s‚µ‚Ü‚µ‚½"
+
+msgid "Print job sent."
+msgstr "ˆóüƒWƒ‡ƒu‚ð‘—M‚µ‚Ü‚µ‚½."
+
+msgid "Add a new database"
+msgstr "Vƒf[ƒ^ƒx[ƒX‚ð’ljÁ"
+
+msgid "Query for a pattern"
+msgstr "ƒpƒ^[ƒ“‚̃NƒGƒŠ[‚ð’ljÁ"
+
+msgid "Show this message"
+msgstr "‚±‚̃ƒbƒZ[ƒW‚ð•\\ަ‚·‚é"
+
+msgid "Kill a connection"
+msgstr "Ú‘±‚ðI—¹‚·‚é"
+
+msgid "Reinit all connections"
+msgstr "‘S‚Ä‚ÌÚ‘±‚ðĉŠú‰»‚·‚é"
+
+msgid "Show connections"
+msgstr "Ú‘±‚ð•\\ަ‚·‚é"
+
+#, c-format
+msgid "E560: Usage: cs[cope] %s"
+msgstr "E560: Žg—p•û–@: cs[cope] %s"
+
+msgid "This cscope command does not support splitting the window.\n"
+msgstr "‚±‚ÌcscopeƒRƒ}ƒ“ƒh‚Í•ªŠ„ƒEƒBƒ“ƒhƒE‚ł̓Tƒ|[ƒg‚³‚ê‚Ü‚¹‚ñ.\n"
+
+msgid "E562: Usage: cstag <ident>"
+msgstr "E562: Žg—p–@: cstag <ident>"
+
+msgid "E257: cstag: tag not found"
+msgstr "E257: cstag: ƒ^ƒO‚ªŒ©‚‚©‚è‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "E563: stat(%s) error: %d"
+msgstr "E563: stat(%s) ƒGƒ‰[: %d"
+
+msgid "E563: stat error"
+msgstr "E563: stat ƒGƒ‰["
+
+#, 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‚ł͂ ‚è‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "Added cscope database %s"
+msgstr "cscopeƒf[ƒ^ƒx[ƒX %s ‚ð’ljÁ"
+
+#, c-format
+msgid "E262: error reading cscope connection %ld"
+msgstr "E262: cscope‚ÌÚ‘± %ld ‚ð“Çž‚Ý’†‚̃Gƒ‰[‚Å‚·"
+
+msgid "E561: unknown cscope search type"
+msgstr "E561: –¢’m‚ÌcscopeŒŸõŒ^‚Å‚·"
+
+msgid "E566: Could not create cscope pipes"
+msgstr "E566: cscopeƒpƒCƒv‚ð쬂ł«‚Ü‚¹‚ñ‚Å‚µ‚½"
+
+msgid "E622: Could not fork for cscope"
+msgstr "E622: cscope‚Ì‹N“®€”õ(fork)‚ÉŽ¸”s‚µ‚Ü‚µ‚½"
+
+msgid "cs_create_connection setpgid failed"
+msgstr "cs_create_connection ‚Ö‚Ì setpgid ‚ÉŽ¸”s‚µ‚Ü‚µ‚½"
+
+msgid "cs_create_connection exec failed"
+msgstr "cs_create_connection ‚ÌŽÀs‚ÉŽ¸”s‚µ‚Ü‚µ‚½"
+
+msgid "cs_create_connection: fdopen for to_fp failed"
+msgstr "cs_create_connection: to_fp ‚Ì fdopen ‚ÉŽ¸”s‚µ‚Ü‚µ‚½"
+
+msgid "cs_create_connection: fdopen for fr_fp failed"
+msgstr "cs_create_connection: fr_fp ‚Ì fdopen ‚ÉŽ¸”s‚µ‚Ü‚µ‚½"
+
+msgid "E623: Could not spawn cscope process"
+msgstr "E623: cscopeƒvƒƒZƒX‚ð‹N“®‚Å‚«‚Ü‚¹‚ñ‚Å‚µ‚½"
+
+msgid "E567: no cscope connections"
+msgstr "E567: cscopeÚ‘±‚ÉŽ¸”s‚µ‚Ü‚µ‚½"
+
+#, c-format
+msgid "E469: invalid cscopequickfix flag %c for %c"
+msgstr "E469: –³Œø‚È cscopequickfix ƒtƒ‰ƒO %c ‚Ì %c ‚Å‚·"
+
+#, c-format
+msgid "E259: no matches found for cscope query %s of %s"
+msgstr "E259: cscopeƒNƒGƒŠ[ %s of %s ‚ÉŠY“–‚ª‚ ‚è‚Ü‚¹‚ñ‚Å‚µ‚½"
+
+msgid "cscope commands:\n"
+msgstr "cscopeƒRƒ}ƒ“ƒh:\n"
+
+#, c-format
+msgid "%-5s: %s%*s (Usage: %s)"
+msgstr "%-5s: %s%*s (Žg—p–@: %s)"
+
+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"
+
+#, c-format
+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 "E568: duplicate cscope database not added"
+msgstr "E568: d•¡‚·‚écscopeƒf[ƒ^ƒx[ƒX‚͒ljÁ‚³‚ê‚Ü‚¹‚ñ‚Å‚µ‚½"
+
+#, c-format
+msgid "E261: cscope connection %s not found"
+msgstr "E261: cscopeÚ‘± %s ‚ªŒ©‚‚©‚è‚Ü‚¹‚ñ‚Å‚µ‚½"
+
+#, c-format
+msgid "cscope connection %s closed"
+msgstr "cscopeÚ‘± %s ‚ª•‚¶‚ç‚ê‚Ü‚µ‚½"
+
+#. should not reach here
+msgid "E570: fatal error in cs_manage_matches"
+msgstr "E570: cs_manage_matches ‚Å’v–½“I‚ȃGƒ‰[‚Å‚·"
+
+#, c-format
+msgid "Cscope tag: %s"
+msgstr "Cscope ƒ^ƒO: %s"
+
+msgid ""
+"\n"
+" # line"
+msgstr ""
+"\n"
+" # s”Ô†"
+
+msgid "filename / context / line\n"
+msgstr "ƒtƒ@ƒCƒ‹–¼ / •¶–¬ / s\n"
+
+#, c-format
+msgid "E609: Cscope error: %s"
+msgstr "E609: cscopeƒGƒ‰[: %s"
+
+msgid "All cscope databases reset"
+msgstr "‘S‚Ä‚Ìcscopeƒf[ƒ^ƒx[ƒX‚ðƒŠƒZƒbƒg‚µ‚Ü‚·"
+
+msgid "no cscope connections\n"
+msgstr "cscopeÚ‘±‚ª‚ ‚è‚Ü‚¹‚ñ\n"
+
+msgid " # pid database name prepend path\n"
+msgstr " # pid ƒf[ƒ^ƒx[ƒX–¼ prepend ƒpƒX\n"
+
+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‚ł͋–‚³‚ê‚Ü‚¹‚ñ"
+
+#, c-format
+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‚ª‚ ‚è‚Ü‚·"
+
+#, c-format
+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‚Å‚·"
+
+#, c-format
+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‚Íݒ肳‚ê‚Ä‚¢‚Ü‚¹‚ñ"
+
+#, c-format
+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‚ªŠù‚ÉÁ‹Ž‚³‚ê‚Ü‚µ‚½"
+
+#. This should never happen. Famous last word?
+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‚Å‚«‚Ü‚¹‚ñ‚Å"
+"‚µ‚½."
+
+#, c-format
+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‚µ‚Ü‚µ‚½"
+
+#, c-format
+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 "Unknown option argument"
+msgstr "–¢’m‚̃IƒvƒVƒ‡ƒ“ˆø”‚Å‚·"
+
+msgid "Too many edit arguments"
+msgstr "•ÒWˆø”‚ª‘½‰ß‚¬‚Ü‚·"
+
+msgid "Argument missing after"
+msgstr "ˆø”‚ª‚ ‚è‚Ü‚¹‚ñ"
+
+msgid "Garbage after option argument"
+msgstr "ƒIƒvƒVƒ‡ƒ“ˆø”‚ÌŒã‚ɃSƒ~‚ª‚ ‚è‚Ü‚·"
+
+msgid "Too many \"+command\", \"-c command\" or \"--cmd command\" arguments"
+msgstr "\"+command\", \"-c command\", \"--cmd command\" ‚̈ø”‚ª‘½‰ß‚¬‚Ü‚·"
+
+msgid "Invalid argument for"
+msgstr "–³Œø‚Ȉø”‚Å‚·: "
+
+#, c-format
+msgid "%d files to edit\n"
+msgstr "%d ŒÂ‚̃tƒ@ƒCƒ‹‚ª•ÒW‚ðT‚¦‚Ä‚¢‚Ü‚·\n"
+
+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 "Attempt to open script file again: \""
+msgstr "ƒXƒNƒŠƒvƒgƒtƒ@ƒCƒ‹‚ðĂъJ‚¢‚Ă݂܂·: \""
+
+msgid "Cannot open for reading: \""
+msgstr "“Çž—p‚Æ‚µ‚ÄŠJ‚¯‚Ü‚¹‚ñ"
+
+msgid "Cannot open for script output: \""
+msgstr "ƒXƒNƒŠƒvƒgo—Í—p‚ðŠJ‚¯‚Ü‚¹‚ñ"
+
+msgid "Vim: Error: Failure to start gvim from NetBeans\n"
+msgstr "Vim: ƒGƒ‰[: NetBeans‚©‚çgvim‚ðƒXƒ^[ƒg‚Å‚«‚Ü‚¹‚ñ\n"
+
+msgid "Vim: Warning: Output is not to a terminal\n"
+msgstr "Vim: Œx: ’[––‚Ö‚Ìo—͂ł͂ ‚è‚Ü‚¹‚ñ\n"
+
+msgid "Vim: Warning: Input is not from a terminal\n"
+msgstr "Vim: Œx: ’[––‚©‚ç‚Ì“ü—͂ł͂ ‚è‚Ü‚¹‚ñ\n"
+
+#. just in case..
+msgid "pre-vimrc command line"
+msgstr "vimrc‘O‚̃Rƒ}ƒ“ƒhƒ‰ƒCƒ“"
+
+#, 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 "[ƒtƒ@ƒCƒ‹..] ‚ ‚éƒtƒ@ƒCƒ‹‚ð•ÒW‚·‚é"
+
+msgid "- read text from stdin"
+msgstr "- •W€“ü—Í‚©‚çƒeƒLƒXƒg‚ð“Çž‚Þ"
+
+msgid "-t tag edit file where tag is defined"
+msgstr "-t ƒ^ƒO ƒ^ƒO‚ª’è‹`‚³‚ꂽ‚Æ‚±‚ë‚©‚ç•ÒW‚·‚é"
+
+msgid "-q [errorfile] edit file with first error"
+msgstr "-q [errorfile] ʼn‚̃Gƒ‰[‚Å•ÒW‚·‚é"
+
+msgid ""
+"\n"
+"\n"
+"usage:"
+msgstr ""
+"\n"
+"\n"
+"Žg—p–@:"
+
+msgid " vim [arguments] "
+msgstr " vim [ˆø”] "
+
+msgid ""
+"\n"
+" or:"
+msgstr ""
+"\n"
+" ‚à‚µ‚­‚Í:"
+
+msgid ""
+"\n"
+"Where case is ignored prepend / to make flag upper case"
+msgstr ""
+"\n"
+"‘嬕¶Žš‚ª–³Ž‹‚³‚ê‚éê‡‚Í‘å•¶Žš‚É‚·‚邽‚ß‚É / ‚ð‘O’u‚µ‚Ä‚­‚¾‚³‚¢"
+
+msgid ""
+"\n"
+"\n"
+"Arguments:\n"
+msgstr ""
+"\n"
+"\n"
+"ˆø”:\n"
+
+msgid "--\t\t\tOnly file names after this"
+msgstr "--\t\t\t‚±‚Ì‚ ‚Ƃɂ̓tƒ@ƒCƒ‹–¼‚¾‚¯"
+
+msgid "--literal\t\tDon't expand wildcards"
+msgstr "--literal\t\tƒƒCƒ‹ƒhƒJ[ƒh‚ð“WŠJ‚µ‚È‚¢"
+
+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 "-v\t\t\tVi mode (like \"vi\")"
+msgstr "-v\t\t\tViƒ‚[ƒh (\"vi\" ‚Æ“¯‚¶)"
+
+msgid "-e\t\t\tEx mode (like \"ex\")"
+msgstr "-e\t\t\tExƒ‚[ƒh (\"ex\" ‚Æ“¯‚¶)"
+
+msgid "-E\t\t\tImproved Ex mode"
+msgstr "-E\t\t\t‰ü—ÇExƒ‚[ƒh"
+
+msgid "-s\t\t\tSilent (batch) mode (only for \"ex\")"
+msgstr "-s\t\t\tƒTƒCƒŒƒ“ƒg(ƒoƒbƒ`)ƒ‚[ƒh (\"ex\" ê—p)"
+
+msgid "-d\t\t\tDiff mode (like \"vimdiff\")"
+msgstr "-d\t\t\t·•ªƒ‚[ƒh (\"vidiff\" ‚Æ“¯‚¶)"
+
+msgid "-y\t\t\tEasy mode (like \"evim\", modeless)"
+msgstr "-y\t\t\tƒC[ƒW[ƒ‚[ƒh (\"evim\" ‚Æ“¯‚¶, ƒ‚[ƒh–³)"
+
+msgid "-R\t\t\tReadonly mode (like \"view\")"
+msgstr "-R\t\t\t“Çžê—pƒ‚[ƒh (\"view\" ‚Æ“¯‚¶)"
+
+msgid "-Z\t\t\tRestricted mode (like \"rvim\")"
+msgstr "-Z\t\t\t§ŒÀƒ‚[ƒh (\"rvim\" ‚Æ“¯‚¶)"
+
+msgid "-m\t\t\tModifications (writing files) not allowed"
+msgstr "-m\t\t\t•ÏX (ƒtƒ@ƒCƒ‹•Û‘¶Žž) ‚ð‚Å‚«‚È‚¢‚悤‚É‚·‚é"
+
+msgid "-M\t\t\tModifications in text not allowed"
+msgstr "-M\t\t\tƒeƒLƒXƒg‚Ì•ÒW‚ðs‚È‚¦‚È‚¢‚悤‚É‚·‚é"
+
+msgid "-b\t\t\tBinary mode"
+msgstr "-b\t\t\tƒoƒCƒiƒŠƒ‚[ƒh"
+
+msgid "-l\t\t\tLisp mode"
+msgstr "-l\t\t\tLispƒ‚[ƒh"
+
+msgid "-C\t\t\tCompatible with Vi: 'compatible'"
+msgstr "-C\t\t\tViŒÝŠ·ƒ‚[ƒh: 'compatible'"
+
+msgid "-N\t\t\tNot fully Vi compatible: 'nocompatible'"
+msgstr "-N\t\t\tVi”ñŒÝŠ·ƒ‚[ƒh: 'nocompatible"
+
+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]"
+
+msgid "-D\t\t\tDebugging mode"
+msgstr "-D\t\t\tƒfƒoƒbƒOƒ‚[ƒh"
+
+msgid "-n\t\t\tNo swap file, use memory only"
+msgstr "-n\t\t\tƒXƒƒbƒvƒtƒ@ƒCƒ‹‚ðŽg—p‚¹‚¸ƒƒ‚ƒŠ‚¾‚¯"
+
+msgid "-r\t\t\tList swap files and exit"
+msgstr "-r\t\t\tƒXƒƒbƒvƒtƒ@ƒCƒ‹‚ð—ñ‹“‚µI—¹"
+
+msgid "-r (with file name)\tRecover crashed session"
+msgstr "-r (ƒtƒ@ƒCƒ‹–¼)\tƒNƒ‰ƒbƒVƒ…‚µ‚½ƒZƒbƒVƒ‡ƒ“‚𕜋A"
+
+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ƒ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 "-A\t\t\tstart in Arabic mode"
+msgstr "-A\t\t\tƒAƒ‰ƒrƒAŒêƒ‚[ƒh‚Å‹N“®‚·‚é"
+
+msgid "-H\t\t\tStart in Hebrew mode"
+msgstr "-H\t\t\tƒwƒuƒ‰ƒCŒêƒ‚[ƒh‚Å‹N“®‚·‚é"
+
+msgid "-F\t\t\tStart in Farsi mode"
+msgstr "-F\t\t\tƒyƒ‹ƒVƒAŒêƒ‚[ƒh‚Å‹N“®‚·‚é"
+
+msgid "-T <terminal>\tSet terminal type to <terminal>"
+msgstr "-T <terminal>\t’[––‚ð <terminal> ‚ÉÝ’è‚·‚é"
+
+msgid "-u <vimrc>\t\tUse <vimrc> instead of any .vimrc"
+msgstr "-u <vimrc>\t\t.vimrc‚Ì‘ã‚í‚è‚É <vimrc> ‚ðŽg‚¤"
+
+msgid "-U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc"
+msgstr "-U <gvimrc>\t\t.gvimrc‚Ì‘ã‚í‚è‚É <gvimrc> ‚ðŽg‚¤"
+
+msgid "--noplugin\t\tDon't load plugin scripts"
+msgstr "--noplugin\t\tƒvƒ‰ƒOƒCƒ“ƒXƒNƒŠƒvƒg‚ðƒ[ƒh‚µ‚È‚¢"
+
+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ŒÂ)"
+
+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ŒÂ)"
+
+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ƒtƒ@ƒCƒ‹‚ÌŌォ‚ç‚Í‚¶‚ß‚é"
+
+msgid "+<lnum>\t\tStart at line <lnum>"
+msgstr "+<lnum>\t\t<lnum> s‚©‚ç‚Í‚¶‚ß‚é"
+
+msgid "--cmd <command>\tExecute <command> before loading any vimrc file"
+msgstr "--cmd <command>\tvimrc‚ðƒ[ƒh‚·‚é‘O‚É <command> ‚ðŽÀs‚·‚é"
+
+msgid "-c <command>\t\tExecute <command> after loading the first file"
+msgstr "-c <command>\t\tʼn‚̃tƒ@ƒCƒ‹‚ðƒ[ƒhŒã <command> ‚ðŽÀs‚·‚é"
+
+msgid "-S <session>\t\tSource file <session> after loading the first file"
+msgstr "-S <session>\t\tʼn‚̃tƒ@ƒCƒ‹‚ðƒ[ƒhŒãƒtƒ@ƒCƒ‹ <session> ‚ðŽæž‚Þ"
+
+msgid "-s <scriptin>\tRead Normal mode commands from file <scriptin>"
+msgstr "-s <scriptin>\tƒtƒ@ƒCƒ‹ <scriptin> ‚©‚çƒm[ƒ}ƒ‹ƒRƒ}ƒ“ƒh‚ð“Çž‚Þ"
+
+msgid "-w <scriptout>\tAppend all typed commands to file <scriptout>"
+msgstr "-w <scriptout>\t“ü—Í‚µ‚½‘SƒRƒ}ƒ“ƒh‚ðƒtƒ@ƒCƒ‹ <scriptout> ‚ɒljÁ‚·‚é"
+
+msgid "-W <scriptout>\tWrite all typed commands to file <scriptout>"
+msgstr "-W <scriptout>\t“ü—Í‚µ‚½‘SƒRƒ}ƒ“ƒh‚ðƒtƒ@ƒCƒ‹ <scriptout> ‚ɕۑ¶‚·‚é"
+
+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 "--startuptime <file>\tWrite startup timing messages to <file>"
+msgstr "--startuptime <file>\t‹N“®‚É‚©‚©‚Á‚½ŽžŠÔ‚ÌÚׂð <file> ‚Öo—Í‚·‚é"
+
+msgid "-i <viminfo>\t\tUse <viminfo> instead of .viminfo"
+msgstr "-i <viminfo>\t\t.viminfo‚Ì‘ã‚í‚è‚É <viminfo> ‚ðŽg‚¤"
+
+msgid "-h or --help\tPrint Help (this message) and exit"
+msgstr "-h or --help\tƒwƒ‹ƒv(‚±‚̃ƒbƒZ[ƒW)‚ð•\\ަ‚µI—¹‚·‚é"
+
+msgid "--version\t\tPrint version information and exit"
+msgstr "--version\t\tƒo[ƒWƒ‡ƒ“î•ñ‚ð•\\ަ‚µI—¹‚·‚é"
+
+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‚ªŒ©‚‚©‚è‚Ü‚¹‚ñ"
+
+#. Failed to send, abort.
+msgid ": Send failed.\n"
+msgstr ": ‘—M‚ÉŽ¸”s‚µ‚Ü‚µ‚½.\n"
+
+#. Let vim start normally.
+msgid ": Send failed. Trying to execute locally\n"
+msgstr ": ‘—M‚ÉŽ¸”s‚µ‚Ü‚µ‚½. ƒ[ƒJƒ‹‚ł̎Às‚ðŽŽ‚Ý‚Ä‚¢‚Ü‚·\n"
+
+#, c-format
+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 "No marks set"
+msgstr "ƒ}[ƒN‚ªÝ’肳‚ê‚Ä‚¢‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "E283: No marks matching \"%s\""
+msgstr "E283: \"%s\" ‚ÉŠY“–‚·‚éƒ}[ƒN‚ª‚ ‚è‚Ü‚¹‚ñ"
+
+#. Highlight title
+msgid ""
+"\n"
+"mark line col file/text"
+msgstr ""
+"\n"
+"mark s —ñ ƒtƒ@ƒCƒ‹/ƒeƒLƒXƒg"
+
+#. Highlight title
+msgid ""
+"\n"
+" jump line col file/text"
+msgstr ""
+"\n"
+" jump s —ñ ƒtƒ@ƒCƒ‹/ƒeƒLƒXƒg"
+
+#. Highlight title
+msgid ""
+"\n"
+"change line col text"
+msgstr ""
+"\n"
+"•ÏX s —ñ ƒeƒLƒXƒg"
+
+msgid ""
+"\n"
+"# File marks:\n"
+msgstr ""
+"\n"
+"# ƒtƒ@ƒCƒ‹ƒ}[ƒN:\n"
+
+#. Write the jumplist with -'
+msgid ""
+"\n"
+"# Jumplist (newest first):\n"
+msgstr ""
+"\n"
+"# ƒWƒƒƒ“ƒvƒŠƒXƒg (V‚µ‚¢‚à‚Ì‚ªæ):\n"
+
+msgid ""
+"\n"
+"# History of marks within files (newest to oldest):\n"
+msgstr ""
+"\n"
+"# ƒtƒ@ƒCƒ‹“àƒ}[ƒN‚Ì—š—ð (V‚µ‚¢‚à‚Ì‚©‚çŒÃ‚¢‚à‚Ì):\n"
+
+msgid "Missing '>'"
+msgstr "'>' ‚ªŒ©‚‚©‚è‚Ü‚¹‚ñ"
+
+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 "E293: block was not locked"
+msgstr "E293: ƒuƒƒbƒN‚ªƒƒbƒN‚³‚ê‚Ä‚¢‚Ü‚¹‚ñ"
+
+msgid "E294: Seek error in swap file read"
+msgstr "E294: ƒXƒƒbƒvƒtƒ@ƒCƒ‹“ÇžŽž‚ɃV[ƒNƒGƒ‰[‚Å‚·"
+
+msgid "E295: Read error in swap file"
+msgstr "E295: ƒXƒƒbƒvƒtƒ@ƒCƒ‹‚̓Ǟ‚݃Gƒ‰[‚Å‚·"
+
+msgid "E296: Seek error in swap file write"
+msgstr "E296: ƒXƒƒbƒvƒtƒ@ƒCƒ‹‘ž‚ÝŽž‚ɃV[ƒNƒGƒ‰[‚Å‚·"
+
+msgid "E297: Write error in swap file"
+msgstr "E297: ƒXƒƒbƒvƒtƒ@ƒCƒ‹‚Ì‘ž‚݃Gƒ‰[‚Å‚·"
+
+msgid "E300: Swap file already exists (symlink attack?)"
+msgstr "E300: ƒXƒƒbƒvƒtƒ@ƒCƒ‹‚ªŠù‚É‘¶Ý‚µ‚Ü‚· (symlink‚É‚æ‚éUŒ‚?)"
+
+msgid "E298: Didn't get block nr 0?"
+msgstr "E298: ƒuƒƒbƒN 0 ‚ðŽæ“¾‚Å‚«‚Ü‚¹‚ñ?"
+
+msgid "E298: Didn't get block nr 1?"
+msgstr "E298: ƒuƒƒbƒN 1 ‚ðŽæ“¾‚Å‚«‚Ü‚¹‚ñ?"
+
+msgid "E298: Didn't get block nr 2?"
+msgstr "E298: ƒuƒƒbƒN 2 ‚ðŽæ“¾‚Å‚«‚Ü‚¹‚ñ?"
+
+msgid "E843: Error while updating swap file crypt"
+msgstr "E843: ƒXƒƒbƒvƒtƒ@ƒCƒ‹‚̈Æ‚ðXV’†‚ɃGƒ‰[‚ª”­¶‚µ‚Ü‚µ‚½"
+
+#. could not (re)open the swap file, what can we do????
+msgid "E301: Oops, lost the swap file!!!"
+msgstr "E301: ‚¨‚Á‚Æ, ƒXƒƒbƒvƒtƒ@ƒCƒ‹‚ªŽ¸‚í‚ê‚Ü‚µ‚½!!!"
+
+msgid "E302: Could not rename swap file"
+msgstr "E302: ƒXƒƒbƒvƒtƒ@ƒCƒ‹‚Ì–¼‘O‚ð•Ï‚¦‚ç‚ê‚Ü‚¹‚ñ"
+
+#, 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‰Â”\\‚Å‚·"
+
+msgid "E304: ml_upd_block0(): Didn't get block 0??"
+msgstr "E304: ml_upd_block0(): ƒuƒƒbƒN 0 ‚ðŽæ“¾‚Å‚«‚Ü‚¹‚ñ‚Å‚µ‚½??"
+
+#, c-format
+msgid "E305: No swap file found for %s"
+msgstr "E305: %s ‚ɂ̓Xƒƒbƒvƒtƒ@ƒCƒ‹‚ªŒ©‚‚©‚è‚Ü‚¹‚ñ"
+
+msgid "Enter number of swap file to use (0 to quit): "
+msgstr "Žg—p‚·‚éƒXƒƒbƒvƒtƒ@ƒCƒ‹‚̔Ԇ‚ð“ü—Í‚µ‚Ä‚­‚¾‚³‚¢(0 ‚ÅI—¹): "
+
+#, c-format
+msgid "E306: Cannot open %s"
+msgstr "E306: %s ‚ðŠJ‚¯‚Ü‚¹‚ñ"
+
+msgid "Unable to read block 0 from "
+msgstr "ƒuƒƒbƒN 0 ‚ð“Çž‚߂܂¹‚ñ "
+
+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‚µ‚Ä‚¢‚Ü‚¹‚ñ."
+
+msgid " cannot be used with this version of Vim.\n"
+msgstr " Vim‚Ì‚±‚̃o[ƒWƒ‡ƒ“‚ł͎g—p‚Å‚«‚Ü‚¹‚ñ.\n"
+
+msgid "Use Vim version 3.0.\n"
+msgstr "Vim‚̃o[ƒWƒ‡ƒ“3.0‚ðŽg—p‚µ‚Ä‚­‚¾‚³‚¢.\n"
+
+#, c-format
+msgid "E307: %s does not look like a Vim swap file"
+msgstr "E307: %s ‚ÍVim‚̃Xƒƒbƒvƒtƒ@ƒCƒ‹‚ł͂Ȃ¢‚悤‚Å‚·"
+
+msgid " cannot be used on this computer.\n"
+msgstr " ‚±‚̃Rƒ“ƒsƒ…[ƒ^‚ł͎g—p‚Å‚«‚Ü‚¹‚ñ.\n"
+
+msgid "The file was created on "
+msgstr "‚±‚̃tƒ@ƒCƒ‹‚ÍŽŸ‚ÌꊂÅì‚ç‚ê‚Ü‚µ‚½ "
+
+msgid ""
+",\n"
+"or the file has been damaged."
+msgstr ""
+",\n"
+"‚à‚µ‚­‚̓tƒ@ƒCƒ‹‚ª‘¹‚µ‚Ä‚¢‚Ü‚·."
+
+#, c-format
+msgid ""
+"E833: %s is encrypted and this version of Vim does not support encryption"
+msgstr ""
+"E833: %s ‚Í‚±‚̃o[ƒWƒ‡ƒ“‚ÌVim‚ŃTƒ|[ƒg‚µ‚Ä‚¢‚È‚¢Œ`Ž®‚ňƉ»‚³‚ê‚Ä‚¢‚Ü‚·"
+
+msgid " has been damaged (page size is smaller than minimum value).\n"
+msgstr " ‚Í‘¹‚µ‚Ä‚¢‚Ü‚· (ƒy[ƒWƒTƒCƒY‚ªÅ¬’l‚ð‰º‰ñ‚Á‚Ä‚¢‚Ü‚·).\n"
+
+#, c-format
+msgid "Using swap file \"%s\""
+msgstr "ƒXƒƒbƒvƒtƒ@ƒCƒ‹ \"%s\" ‚ðŽg—p’†"
+
+#, c-format
+msgid "Original file \"%s\""
+msgstr "Œ´–{ƒtƒ@ƒCƒ‹ \"%s\""
+
+msgid "E308: Warning: Original file may have been changed"
+msgstr "E308: Œx: Œ´–{ƒtƒ@ƒCƒ‹‚ª•ÏX‚³‚ê‚Ä‚¢‚Ü‚·"
+
+#, c-format
+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‚¾‚¯‚ð‰Ÿ‚µ‚Ä‚­‚¾‚³‚¢."
+
+#, c-format
+msgid "E309: Unable to read block 1 from %s"
+msgstr "E309: %s ‚©‚çƒuƒƒbƒN 1 ‚ð“Çž‚߂܂¹‚ñ"
+
+msgid "???MANY LINES MISSING"
+msgstr "???‘½‚­‚Ìs‚ªŽ¸‚í‚ê‚Ä‚¢‚Ü‚·"
+
+msgid "???LINE COUNT WRONG"
+msgstr "???s”‚ªŠÔˆá‚Á‚Ä‚¢‚Ü‚·"
+
+msgid "???EMPTY BLOCK"
+msgstr "???ƒuƒƒbƒN‚ª‹ó‚Å‚·"
+
+msgid "???LINES MISSING"
+msgstr "???s‚ªŽ¸‚í‚ê‚Ä‚¢‚Ü‚·"
+
+#, c-format
+msgid "E310: Block 1 ID wrong (%s not a .swp file?)"
+msgstr "E310: ƒuƒƒbƒN 1 ‚ÌID‚ªŠÔˆá‚Á‚Ä‚¢‚Ü‚·(%s ‚ª.swpƒtƒ@ƒCƒ‹‚łȂ¢?)"
+
+msgid "???BLOCK MISSING"
+msgstr "???ƒuƒƒbƒN‚ª‚ ‚è‚Ü‚¹‚ñ"
+
+msgid "??? from here until ???END lines may be messed up"
+msgstr "??? ‚±‚±‚©‚ç ???END ‚܂łÌs‚ª”j‰ó‚³‚ê‚Ä‚¢‚邿‚¤‚Å‚·"
+
+msgid "??? from here until ???END lines may have been inserted/deleted"
+msgstr "??? ‚±‚±‚©‚ç ???END ‚܂łÌs‚ª‘}“ü‚©íœ‚³‚ꂽ‚悤‚Å‚·"
+
+msgid "???END"
+msgstr "???END"
+
+msgid "E311: Recovery Interrupted"
+msgstr "E311: ƒŠƒJƒoƒŠ‚ªŠ„ž‚Ü‚ê‚Ü‚µ‚½"
+
+msgid ""
+"E312: Errors detected while recovering; look for lines starting with ???"
+msgstr ""
+"E312: ƒŠƒJƒoƒŠ‚ÌÅ’†‚ɃGƒ‰[‚ªŒŸo‚³‚ê‚Ü‚µ‚½; ???‚ÅŽn‚Ü‚és‚ðŽQÆ‚µ‚Ä‚­‚¾‚³‚¢"
+
+msgid "See \":help E312\" for more information."
+msgstr "Ú×‚Í \":help E312\" ‚ðŽQÆ‚µ‚Ä‚­‚¾‚³‚¢"
+
+msgid "Recovery completed. You should check if everything is OK."
+msgstr "ƒŠƒJƒoƒŠ‚ªI—¹‚µ‚Ü‚µ‚½. ‘S‚Ä‚ª³‚µ‚¢‚©ƒ`ƒFƒbƒN‚µ‚Ä‚­‚¾‚³‚¢."
+
+msgid ""
+"\n"
+"(You might want to write out this file under another name\n"
+msgstr ""
+"\n"
+"(•ÏX‚ðƒ`ƒFƒbƒN‚·‚邽‚ß‚É, ‚±‚̃tƒ@ƒCƒ‹‚ð•ʂ̖¼‘O‚ŕۑ¶‚µ‚½ã‚Å\n"
+
+msgid "and run diff with the original file to check for changes)"
+msgstr "Œ´–{ƒtƒ@ƒCƒ‹‚Æ‚Ì diff ‚ðŽÀs‚·‚邯—Ç‚¢‚Å‚µ‚傤)"
+
+msgid "Recovery completed. Buffer contents equals file contents."
+msgstr "•œŒ³Š®—¹. ƒoƒbƒtƒ@‚Ì“à—e‚̓tƒ@ƒCƒ‹‚Æ“¯‚¶‚ɂȂè‚Ü‚µ‚½."
+
+msgid ""
+"\n"
+"You may want to delete the .swp file now.\n"
+"\n"
+msgstr ""
+"\n"
+"‚»‚ê‚©‚ç.swpƒtƒ@ƒCƒ‹‚ð휂µ‚Ä‚­‚¾‚³‚¢\n"
+"\n"
+
+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"
+
+#. use msg() to start the scrolling properly
+msgid "Swap files found:"
+msgstr "ƒXƒƒbƒvƒtƒ@ƒCƒ‹‚ª•¡”Œ©‚‚©‚è‚Ü‚µ‚½:"
+
+msgid " In current directory:\n"
+msgstr " Œ»Ý‚̃fƒBƒŒƒNƒgƒŠ:\n"
+
+msgid " Using specified name:\n"
+msgstr " ‚ ‚é–¼‘O‚ðŽg—p’†:\n"
+
+msgid " In directory "
+msgstr " ƒfƒBƒŒƒNƒgƒŠ "
+
+msgid " -- none --\n"
+msgstr " -- ‚È‚µ --\n"
+
+msgid " owned by: "
+msgstr " Š—LŽÒ: "
+
+msgid " dated: "
+msgstr " “ú•t: "
+
+msgid " dated: "
+msgstr " “ú•t: "
+
+msgid " [from Vim version 3.0]"
+msgstr " [from Vim version 3.0]"
+
+msgid " [does not look like a Vim swap file]"
+msgstr " [Vim‚̃Xƒƒbƒvƒtƒ@ƒCƒ‹‚ł͂Ȃ¢‚悤‚Å‚·]"
+
+msgid " file name: "
+msgstr " ƒtƒ@ƒCƒ‹–¼: "
+
+msgid ""
+"\n"
+" modified: "
+msgstr ""
+"\n"
+" •ÏXó‘Ô: "
+
+msgid "YES"
+msgstr "‚ ‚è"
+
+msgid "no"
+msgstr "‚È‚µ"
+
+msgid ""
+"\n"
+" user name: "
+msgstr ""
+"\n"
+" ƒ†[ƒU–¼: "
+
+msgid " host name: "
+msgstr " ƒzƒXƒg–¼: "
+
+msgid ""
+"\n"
+" host name: "
+msgstr ""
+"\n"
+" ƒzƒXƒg–¼: "
+
+msgid ""
+"\n"
+" process ID: "
+msgstr ""
+"\n"
+" ƒvƒƒZƒXID: "
+
+msgid " (still running)"
+msgstr " (‚Ü‚¾ŽÀs’†)"
+
+msgid ""
+"\n"
+" [not usable with this version of Vim]"
+msgstr ""
+"\n"
+" [‚±‚ÌVimƒo[ƒWƒ‡ƒ“‚ł͎g—p‚Å‚«‚Ü‚¹‚ñ]"
+
+msgid ""
+"\n"
+" [not usable on this computer]"
+msgstr ""
+"\n"
+" [‚±‚̃Rƒ“ƒsƒ…[ƒ^‚ł͎g—p‚Å‚«‚Ü‚¹‚ñ]"
+
+msgid " [cannot be read]"
+msgstr " [“Çž‚߂܂¹‚ñ]"
+
+msgid " [cannot be opened]"
+msgstr " [ŠJ‚¯‚Ü‚¹‚ñ]"
+
+msgid "E313: Cannot preserve, there is no swap file"
+msgstr "E313: ƒXƒƒbƒvƒtƒ@ƒCƒ‹‚ª–³‚¢‚̂ňێ‚Å‚«‚Ü‚¹‚ñ"
+
+msgid "File preserved"
+msgstr "ƒtƒ@ƒCƒ‹‚ªˆÛŽ‚³‚ê‚Ü‚·"
+
+msgid "E314: Preserve failed"
+msgstr "E314: ˆÛŽ‚ÉŽ¸”s‚µ‚Ü‚µ‚½"
+
+#, 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: s %ld ‚ðŒ©‚Â‚¯‚ç‚ê‚Ü‚¹‚ñ"
+
+msgid "E317: pointer block id wrong 3"
+msgstr "E317: ƒ|ƒCƒ“ƒ^ƒuƒƒbƒN‚ÌID‚ªŠÔˆá‚Á‚Ä‚¢‚Ü‚· 3"
+
+msgid "stack_idx should be 0"
+msgstr "stack_idx ‚Í 0 ‚Å‚ ‚é‚ׂ«‚Å‚·"
+
+msgid "E318: Updated too many blocks?"
+msgstr "E318: XV‚³‚ꂽƒuƒƒbƒN‚ª‘½‰ß‚¬‚é‚©‚à?"
+
+msgid "E317: pointer block id wrong 4"
+msgstr "E317: ƒ|ƒCƒ“ƒ^ƒuƒƒbƒN‚ÌID‚ªŠÔˆá‚Á‚Ä‚¢‚Ü‚· 4"
+
+msgid "deleted block 1?"
+msgstr "ƒuƒƒbƒN 1 ‚ÍÁ‚³‚ꂽ?"
+
+#, c-format
+msgid "E320: Cannot find line %ld"
+msgstr "E320: s %ld ‚ªŒ©‚‚©‚è‚Ü‚¹‚ñ"
+
+msgid "E317: pointer block id wrong"
+msgstr "E317: ƒ|ƒCƒ“ƒ^ƒuƒƒbƒN‚ÌID‚ªŠÔˆá‚Á‚Ä‚¢‚Ü‚·"
+
+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: s”Ô†‚ª”͈͊O‚Å‚·: %ld ’´‚¦‚Ä‚¢‚Ü‚·"
+
+#, c-format
+msgid "E323: line count wrong in block %ld"
+msgstr "E323: ƒuƒƒbƒN %ld ‚ÌsƒJƒEƒ“ƒg‚ªŠÔˆá‚Á‚Ä‚¢‚Ü‚·"
+
+msgid "Stack size increases"
+msgstr "ƒXƒ^ƒbƒNƒTƒCƒY‚ª‘‚¦‚Ü‚·"
+
+msgid "E317: pointer block id wrong 2"
+msgstr "E317: ƒ|ƒCƒ“ƒ^ƒuƒƒbƒN‚ÌID‚ªŠÔˆá‚Á‚Ä‚¢‚Ü‚· 2"
+
+#, c-format
+msgid "E773: Symlink loop for \"%s\""
+msgstr "E773: \"%s\" ‚̃Vƒ“ƒ{ƒŠƒbƒNƒŠƒ“ƒN‚ªƒ‹[ƒv‚ɂȂÁ‚Ä‚¢‚Ü‚·"
+
+msgid "E325: ATTENTION"
+msgstr "E325: ’ˆÓ"
+
+msgid ""
+"\n"
+"Found a swap file by the name \""
+msgstr ""
+"\n"
+"ŽŸ‚Ì–¼‘O‚ŃXƒƒbƒvƒtƒ@ƒCƒ‹‚ðŒ©‚Â‚¯‚Ü‚µ‚½ \""
+
+msgid "While opening file \""
+msgstr "ŽŸ‚̃tƒ@ƒCƒ‹‚ðŠJ‚¢‚Ä‚¢‚éÅ’† \""
+
+msgid " NEWER than swap file!\n"
+msgstr " ƒXƒƒbƒvƒtƒ@ƒCƒ‹‚æ‚è‚àV‚µ‚¢‚Å‚·!\n"
+
+#. 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."
+msgstr ""
+"\n"
+"(1) •ʂ̃vƒƒOƒ‰ƒ€‚ª“¯‚¶ƒtƒ@ƒCƒ‹‚ð•ÒW‚µ‚Ä‚¢‚é‚©‚à‚µ‚ê‚Ü‚¹‚ñ.\n"
+" ‚±‚ÌꇂɂÍ, •ÏX‚ð‚µ‚½Û‚ÉÅI“I‚É, “¯‚¶ƒtƒ@ƒCƒ‹‚̈قȂé\n"
+" 2‚‚̃Cƒ“ƒXƒ^ƒ“ƒX‚ª‚Å‚«‚Ä‚µ‚Ü‚¤‚±‚ƂɒˆÓ‚µ‚Ä‚­‚¾‚³‚¢."
+
+msgid " Quit, or continue with caution.\n"
+msgstr " I—¹‚·‚é‚©, ’ˆÓ‚µ‚È‚ª‚瑱‚¯‚Ä‚­‚¾‚³‚¢.\n"
+
+msgid "(2) An edit session for this file crashed.\n"
+msgstr "(2) ‚±‚̃tƒ@ƒCƒ‹‚Ì•ÒWƒZƒbƒVƒ‡ƒ“‚ªƒNƒ‰ƒbƒVƒ…‚µ‚½.\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"
+" ‚ðŽg—p‚µ‚Ä•ÏX‚ðƒŠƒJƒo[‚µ‚Ü‚·(\":help recovery\" ‚ðŽQÆ).\n"
+
+msgid " If you did this already, delete the swap file \""
+msgstr " Šù‚É‚±‚ê‚ðs‚È‚Á‚½‚̂Ȃç‚Î, ƒXƒƒbƒvƒtƒ@ƒCƒ‹ \""
+
+msgid ""
+"\"\n"
+" to avoid this message.\n"
+msgstr ""
+"\"\n"
+" ‚ðÁ‚¹‚΂±‚̃ƒbƒZ[ƒW‚ð‰ñ”ð‚Å‚«‚Ü‚·.\n"
+
+msgid "Swap file \""
+msgstr "ƒXƒƒbƒvƒtƒ@ƒCƒ‹ \""
+
+msgid "\" already exists!"
+msgstr "\" ‚ªŠù‚É‚ ‚è‚Ü‚·!"
+
+msgid "VIM - ATTENTION"
+msgstr "VIM - ’ˆÓ"
+
+msgid "Swap file already exists!"
+msgstr "ƒXƒƒbƒvƒtƒ@ƒCƒ‹‚ªŠù‚É‘¶Ý‚µ‚Ü‚·!"
+
+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)"
+
+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)"
+
+msgid "E326: Too many swap files found"
+msgstr "E326: ƒXƒƒbƒvƒtƒ@ƒCƒ‹‚ª‘½”Œ©‚‚©‚è‚Ü‚µ‚½"
+
+msgid "E327: Part of menu-item path is not sub-menu"
+msgstr "E327: ƒƒjƒ…[ƒAƒCƒeƒ€‚̃pƒX‚Ì•”•ª‚ªƒTƒuƒƒjƒ…[‚ł͂ ‚è‚Ü‚¹‚ñ"
+
+msgid "E328: Menu only exists in another mode"
+msgstr "E328: ƒƒjƒ…[‚Í‘¼‚̃‚[ƒh‚É‚¾‚¯‚ ‚è‚Ü‚·"
+
+#, c-format
+msgid "E329: No menu \"%s\""
+msgstr "E329: \"%s\" ‚Æ‚¢‚¤ƒƒjƒ…[‚Í‚ ‚è‚Ü‚¹‚ñ"
+
+#. Only a mnemonic or accelerator is not valid.
+msgid "E792: Empty menu name"
+msgstr "E792: ƒƒjƒ…[–¼‚ª‹ó‚Å‚·"
+
+msgid "E330: Menu path must not lead to a sub-menu"
+msgstr "E330: ƒƒjƒ…[ƒpƒX‚̓Tƒuƒƒjƒ…[‚ð¶‚¶‚é‚ׂ«‚ł͂ ‚è‚Ü‚¹‚ñ"
+
+msgid "E331: Must not add menu items directly to menu bar"
+msgstr "E331: ƒƒjƒ…[ƒo[‚ɂ͒¼Úƒƒjƒ…[ƒAƒCƒeƒ€‚ð’ljÁ‚Å‚«‚Ü‚¹‚ñ"
+
+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
+msgid ""
+"\n"
+"--- Menus ---"
+msgstr ""
+"\n"
+"--- ƒƒjƒ…[ ---"
+
+msgid "Tear off this menu"
+msgstr "‚±‚̃ƒjƒ…[‚ðØ‚èŽæ‚é"
+
+msgid "E333: Menu path must lead to a menu item"
+msgstr "E333: ƒƒjƒ…[ƒpƒX‚̓ƒjƒ…[ƒAƒCƒeƒ€‚ð¶‚¶‚È‚¯‚ê‚΂¢‚¯‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "E334: Menu not found: %s"
+msgstr "E334: ƒƒjƒ…[‚ªŒ©‚‚©‚è‚Ü‚¹‚ñ: %s"
+
+#, c-format
+msgid "E335: Menu not defined for %s mode"
+msgstr "E335: %s ‚ɂ̓ƒjƒ…[‚ª’è‹`‚³‚ê‚Ä‚¢‚Ü‚¹‚ñ"
+
+msgid "E336: Menu path must lead to a sub-menu"
+msgstr "E336: ƒƒjƒ…[ƒpƒX‚̓Tƒuƒƒjƒ…[‚ð¶‚¶‚È‚¯‚ê‚΂¢‚¯‚Ü‚¹‚ñ"
+
+msgid "E337: Menu not found - check menu names"
+msgstr "E337: ƒƒjƒ…[‚ªŒ©‚‚©‚è‚Ü‚¹‚ñ - ƒƒjƒ…[–¼‚ðŠm”F‚µ‚Ä‚­‚¾‚³‚¢"
+
+#, c-format
+msgid "Error detected while processing %s:"
+msgstr "%s ‚̈—’†‚ɃGƒ‰[‚ªŒŸo‚³‚ê‚Ü‚µ‚½:"
+
+#, c-format
+msgid "line %4ld:"
+msgstr "s %4ld:"
+
+#, c-format
+msgid "E354: Invalid register name: '%s'"
+msgstr "E354: –³Œø‚ȃŒƒWƒXƒ^–¼: '%s'"
+
+msgid "Messages maintainer: Bram Moolenaar <Bram@vim.org>"
+msgstr "“ú–{ŒêƒƒbƒZ[ƒW–|–ó/ŠÄC: ‘º‰ª ‘¾˜Y <koron.kaoriya@gmail.com>"
+
+msgid "Interrupt: "
+msgstr "Š„ž‚Ý: "
+
+msgid "Press ENTER or type command to continue"
+msgstr "‘±‚¯‚é‚É‚ÍENTER‚ð‰Ÿ‚·‚©ƒRƒ}ƒ“ƒh‚ð“ü—Í‚µ‚Ä‚­‚¾‚³‚¢"
+
+#, c-format
+msgid "%s line %ld"
+msgstr "%s s %ld"
+
+msgid "-- More --"
+msgstr "-- Œp‘± --"
+
+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—¹ "
+
+msgid "Question"
+msgstr "Ž¿–â"
+
+msgid ""
+"&Yes\n"
+"&No"
+msgstr ""
+"‚Í‚¢(&Y)\n"
+"‚¢‚¢‚¦(&N)"
+
+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)"
+
+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"
+
+#. TODO: non-GUI file selector here
+msgid "E338: Sorry, no file browser in console mode"
+msgstr "E338: ƒRƒ“ƒ\\[ƒ‹ƒ‚[ƒh‚ł̓tƒ@ƒCƒ‹ƒuƒ‰ƒEƒU‚ðŽg‚¦‚Ü‚¹‚ñ, ‚²‚ß‚ñ‚È‚³‚¢"
+
+msgid "E766: Insufficient arguments for printf()"
+msgstr "E766: printf() ‚̈ø”‚ª•s\\•ª‚Å‚·"
+
+msgid "E807: Expected Float argument for printf()"
+msgstr "E807: printf() ‚̈ø”‚ɂ͕‚“®­”“_”‚ªŠú‘Ò‚³‚ê‚Ä‚¢‚Ü‚·"
+
+msgid "E767: Too many arguments to printf()"
+msgstr "E767: printf() ‚̈ø”‚ª‘½‰ß‚¬‚Ü‚·"
+
+msgid "W10: Warning: Changing a readonly file"
+msgstr "W10: Œx: “Çžê—pƒtƒ@ƒCƒ‹‚ð•ÏX‚µ‚Ü‚·"
+
+msgid "Type number and <Enter> or click with mouse (empty cancels): "
+msgstr ""
+"”Ô†‚Æ<Enter>‚ð“ü—Í‚·‚é‚©ƒ}ƒEƒX‚ŃNƒŠƒbƒN‚µ‚Ä‚­‚¾‚³‚¢ (‹ó‚ŃLƒƒƒ“ƒZƒ‹): "
+
+msgid "Type number and <Enter> (empty cancels): "
+msgstr "”Ô†‚Æ<Enter>‚ð“ü—Í‚µ‚Ä‚­‚¾‚³‚¢ (‹ó‚ŃLƒƒƒ“ƒZƒ‹): "
+
+msgid "1 more line"
+msgstr "1 s ’ljÁ‚µ‚Ü‚µ‚½"
+
+msgid "1 line less"
+msgstr "1 s 휂µ‚Ü‚µ‚½"
+
+#, c-format
+msgid "%ld more lines"
+msgstr "%ld s ’ljÁ‚µ‚Ü‚µ‚½"
+
+#, c-format
+msgid "%ld fewer lines"
+msgstr "%ld s 휂µ‚Ü‚µ‚½"
+
+msgid " (Interrupted)"
+msgstr " (Š„ž‚Ü‚ê‚Ü‚µ‚½)"
+
+msgid "Beep!"
+msgstr "ƒr[ƒb!"
+
+msgid "Vim: preserving files...\n"
+msgstr "Vim: ƒtƒ@ƒCƒ‹‚ð•Û‘¶’†...\n"
+
+#. close all memfiles, without deleting
+msgid "Vim: Finished.\n"
+msgstr "Vim: I—¹‚µ‚Ü‚µ‚½.\n"
+
+msgid "ERROR: "
+msgstr "ƒGƒ‰[: "
+
+#, c-format
+msgid ""
+"\n"
+"[bytes] total alloc-freed %lu-%lu, in use %lu, peak use %lu\n"
+msgstr ""
+"\n"
+"[ƒƒ‚ƒŠ(ƒoƒCƒg)] ‘Š„“–-‰ð•ú—Ê %lu-%lu, Žg—p—Ê %lu, ƒs[ƒNŽž %lu\n"
+
+#, c-format
+msgid ""
+"[calls] total re/malloc()'s %lu, total free()'s %lu\n"
+"\n"
+msgstr ""
+"[ŒÄo] ‘ re/malloc() ‰ñ” %lu, ‘ free() ‰ñ” %lu\n"
+"\n"
+
+msgid "E340: Line is becoming too long"
+msgstr "E340: s‚ª’·‚­‚È‚è‰ß‚¬‚Ü‚µ‚½"
+
+#, c-format
+msgid "E341: Internal error: lalloc(%ld, )"
+msgstr "E341: “à•”ƒGƒ‰[: lalloc(%ld,)"
+
+#, c-format
+msgid "E342: Out of memory! (allocating %lu bytes)"
+msgstr "E342: ƒƒ‚ƒŠ‚ª‘«‚è‚Ü‚¹‚ñ! (%lu ƒoƒCƒg‚ðŠ„“–—v‹)"
+
+#, c-format
+msgid "Calling shell to execute: \"%s\""
+msgstr "ŽÀs‚Ì‚½‚߂ɃVƒFƒ‹‚ðŒÄo‚µ’†: \"%s\""
+
+msgid "E545: Missing colon"
+msgstr "E545: ƒRƒƒ“‚ª‚ ‚è‚Ü‚¹‚ñ"
+
+msgid "E546: Illegal mode"
+msgstr "E546: •s³‚ȃ‚[ƒh‚Å‚·"
+
+msgid "E547: Illegal mouseshape"
+msgstr "E547: •s³‚È 'mouseshape' ‚Å‚·"
+
+msgid "E548: digit expected"
+msgstr "E548: ”’l‚ª•K—v‚Å‚·"
+
+msgid "E549: Illegal percentage"
+msgstr "E549: •s³‚ȃp[ƒZƒ“ƒe[ƒW‚Å‚·"
+
+msgid "Enter encryption key: "
+msgstr "ˆÃ†‰»—p‚̃L[‚ð“ü—Í‚µ‚Ä‚­‚¾‚³‚¢: "
+
+msgid "Enter same key again: "
+msgstr "‚à‚¤ˆê“x“¯‚¶ƒL[‚ð“ü—Í‚µ‚Ä‚­‚¾‚³‚¢: "
+
+msgid "Keys don't match!"
+msgstr "ƒL[‚ªˆê’v‚µ‚Ü‚¹‚ñ"
+
+msgid "E854: path too long for completion"
+msgstr "E854: ƒpƒX‚ª’·‰ß‚¬‚ĕ⊮‚Å‚«‚Ü‚¹‚ñ"
+
+#, 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' ‚ª‘±‚¢‚ĂȂ¢‚Æ‚¢‚¯‚Ü‚¹"
+"‚ñ."
+
+#, c-format
+msgid "E344: Can't find directory \"%s\" in cdpath"
+msgstr "E344: cdpath‚É‚Í \"%s\" ‚Æ‚¢‚¤ƒtƒ@ƒCƒ‹‚ª‚ ‚è‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "E345: Can't find file \"%s\" in path"
+msgstr "E345: path‚É‚Í \"%s\" ‚Æ‚¢‚¤ƒtƒ@ƒCƒ‹‚ª‚ ‚è‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "E346: No more directory \"%s\" found in cdpath"
+msgstr "E346: cdpath‚ɂ͂±‚êˆÈã \"%s\" ‚Æ‚¢‚¤ƒtƒ@ƒCƒ‹‚ª‚ ‚è‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "E347: No more file \"%s\" found in path"
+msgstr "E347: ƒpƒX‚ɂ͂±‚êˆÈã \"%s\" ‚Æ‚¢‚¤ƒtƒ@ƒCƒ‹‚ª‚ ‚è‚Ü‚¹‚ñ"
+
+msgid "Cannot connect to Netbeans #2"
+msgstr "Netbeans #2 ‚ÉÚ‘±‚Å‚«‚Ü‚¹‚ñ"
+
+msgid "Cannot connect to Netbeans"
+msgstr "Netbeans ‚ÉÚ‘±‚Å‚«‚Ü‚¹‚ñ"
+
+#, c-format
+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‚ð“Çž‚Ý"
+
+#, c-format
+msgid "E658: NetBeans connection lost for buffer %ld"
+msgstr "E658: ƒoƒbƒtƒ@ %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 ‚͓Ǟê—p‚Å‚· (‹­§‘ž‚É‚Í ! ‚ð’ljÁ)"
+
+msgid "E349: No identifier under cursor"
+msgstr "E349: ƒJ[ƒ\\ƒ‹‚̈ʒu‚ɂ͎¯•ÊŽq‚ª‚ ‚è‚Ü‚¹‚ñ"
+
+msgid "E774: 'operatorfunc' is empty"
+msgstr "E774: 'operatorfunc' ƒIƒvƒVƒ‡ƒ“‚ª‹ó‚Å‚·"
+
+msgid "E775: Eval feature not available"
+msgstr "E775: Ž®•]‰¿‹@”\\‚ª–³Œø‚ɂȂÁ‚Ä‚¢‚Ü‚·"
+
+msgid "Warning: terminal cannot highlight"
+msgstr "Œx: Žg—p‚µ‚Ä‚¢‚é’[––‚̓nƒCƒ‰ƒCƒg‚Å‚«‚Ü‚¹‚ñ"
+
+msgid "E348: No string under cursor"
+msgstr "E348: ƒJ[ƒ\\ƒ‹‚̈ʒu‚ɂ͕¶Žš—ñ‚ª‚ ‚è‚Ü‚¹‚ñ"
+
+msgid "E352: Cannot erase folds with current 'foldmethod'"
+msgstr "E352: Œ»Ý‚Ì 'foldmethod' ‚Å‚ÍÜô‚Ý‚ðÁ‹Ž‚Å‚«‚Ü‚¹‚ñ"
+
+msgid "E664: changelist is empty"
+msgstr "E664: •ÏXƒŠƒXƒg‚ª‹ó‚Å‚·"
+
+msgid "E662: At start of changelist"
+msgstr "E662: •ÏXƒŠƒXƒg‚Ìæ“ª"
+
+msgid "E663: At end of changelist"
+msgstr "E663: •ÏXƒŠƒXƒg‚Ì––”ö"
+
+msgid "Type :quit<Enter> to exit Vim"
+msgstr "Vim‚ðI—¹‚·‚é‚É‚Í :quit<Enter> ‚Æ“ü—Í‚µ‚Ä‚­‚¾‚³‚¢"
+
+#, c-format
+msgid "1 line %sed 1 time"
+msgstr "1 s‚ª %s ‚Å 1 ‰ñˆ—‚³‚ê‚Ü‚µ‚½"
+
+#, c-format
+msgid "1 line %sed %d times"
+msgstr "1 s‚ª %s ‚Å %d ‰ñˆ—‚³‚ê‚Ü‚µ‚½"
+
+#, c-format
+msgid "%ld lines %sed 1 time"
+msgstr "%ld s‚ª %s ‚Å 1 ‰ñˆ—‚³‚ê‚Ü‚µ‚½"
+
+#, c-format
+msgid "%ld lines %sed %d times"
+msgstr "%ld s‚ª %s ‚Å %d ‰ñˆ—‚³‚ê‚Ü‚µ‚½"
+
+#, c-format
+msgid "%ld lines to indent... "
+msgstr "%ld s‚ªƒCƒ“ƒfƒ“ƒg‚³‚ê‚Ü‚·... "
+
+msgid "1 line indented "
+msgstr "1 s‚ðƒCƒ“ƒfƒ“ƒg‚µ‚Ü‚µ‚½ "
+
+#, c-format
+msgid "%ld lines indented "
+msgstr "%ld s‚ðƒCƒ“ƒfƒ“ƒg‚µ‚Ü‚µ‚½ "
+
+msgid "E748: No previously used register"
+msgstr "E748: ‚Ü‚¾ƒŒƒWƒXƒ^‚ðŽg—p‚µ‚Ä‚¢‚Ü‚¹‚ñ"
+
+#. must display the prompt
+msgid "cannot yank; delete anyway"
+msgstr "ƒ„ƒ“ƒN‚Å‚«‚Ü‚¹‚ñ; ‚Ƃɂ©‚­Á‹Ž"
+
+msgid "1 line changed"
+msgstr "1 s‚ª•ÏX‚³‚ê‚Ü‚µ‚½"
+
+#, c-format
+msgid "%ld lines changed"
+msgstr "%ld s‚ª•ÏX‚³‚ê‚Ü‚µ‚½"
+
+#, c-format
+msgid "freeing %ld lines"
+msgstr "%ld s‚ð‰ð•ú’†"
+
+msgid "block of 1 line yanked"
+msgstr "1 s‚̃uƒƒbƒN‚ªƒ„ƒ“ƒN‚³‚ê‚Ü‚µ‚½"
+
+msgid "1 line yanked"
+msgstr "1 s‚ªƒ„ƒ“ƒN‚³‚ê‚Ü‚µ‚½"
+
+#, c-format
+msgid "block of %ld lines yanked"
+msgstr "%ld s‚̃uƒƒbƒN‚ªƒ„ƒ“ƒN‚³‚ê‚Ü‚µ‚½"
+
+#, c-format
+msgid "%ld lines yanked"
+msgstr "%ld s‚ªƒ„ƒ“ƒN‚³‚ê‚Ü‚µ‚½"
+
+#, c-format
+msgid "E353: Nothing in register %s"
+msgstr "E353: ƒŒƒWƒXƒ^ %s ‚ɂ͉½‚à‚ ‚è‚Ü‚¹‚ñ"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Registers ---"
+msgstr ""
+"\n"
+"--- ƒŒƒWƒXƒ^ ---"
+
+msgid "Illegal register name"
+msgstr "•s³‚ȃŒƒWƒXƒ^–¼"
+
+msgid ""
+"\n"
+"# Registers:\n"
+msgstr ""
+"\n"
+"# ƒŒƒWƒXƒ^:\n"
+
+#, c-format
+msgid "E574: Unknown register type %d"
+msgstr "E574: –¢’m‚̃ŒƒWƒXƒ^Œ^ %d ‚Å‚·"
+
+#, c-format
+msgid "%ld Cols; "
+msgstr "%ld —ñ; "
+
+#, c-format
+msgid "Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Bytes"
+msgstr "‘I‘ð %s%ld / %ld s; %ld / %ld ’PŒê; %ld / %ld ƒoƒCƒg"
+
+#, c-format
+msgid ""
+"Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Chars; %ld of %ld "
+"Bytes"
+msgstr "‘I‘ð %s%ld / %ld s; %ld / %ld ’PŒê; %ld / %ld •¶Žš; %ld / %ld ƒoƒCƒg"
+
+#, c-format
+msgid "Col %s of %s; Line %ld of %ld; Word %ld of %ld; Byte %ld of %ld"
+msgstr "—ñ %s / %s; s %ld of %ld; ’PŒê %ld / %ld; ƒoƒCƒg %ld / %ld"
+
+#, c-format
+msgid ""
+"Col %s of %s; Line %ld of %ld; Word %ld of %ld; Char %ld of %ld; Byte %ld of "
+"%ld"
+msgstr ""
+"—ñ %s / %s; s %ld / %ld; ’PŒê %ld / %ld; •¶Žš %ld / %ld; ƒoƒCƒg %ld of %ld"
+
+#, c-format
+msgid "(+%ld for BOM)"
+msgstr "(+%ld for BOM)"
+
+msgid "%<%f%h%m%=Page %N"
+msgstr "%<%f%h%m%=%N ƒy[ƒW"
+
+msgid "Thanks for flying Vim"
+msgstr "Vim ‚ðŽg‚Á‚Ä‚­‚ê‚Ä‚ ‚肪‚Æ‚¤"
+
+msgid "E518: Unknown option"
+msgstr "E518: –¢’m‚̃IƒvƒVƒ‡ƒ“‚Å‚·"
+
+msgid "E519: Option not supported"
+msgstr "E519: ƒIƒvƒVƒ‡ƒ“‚̓Tƒ|[ƒg‚³‚ê‚Ä‚¢‚Ü‚¹‚ñ"
+
+msgid "E520: Not allowed in a modeline"
+msgstr "E520: modeline ‚ł͋–‰Â‚³‚ê‚Ü‚¹‚ñ"
+
+msgid "E846: Key code not set"
+msgstr "E846: ƒL[ƒR[ƒh‚ªÝ’肳‚ê‚Ä‚¢‚Ü‚¹‚ñ"
+
+msgid "E521: Number required after ="
+msgstr "E521: = ‚ÌŒã‚É‚Í”Žš‚ª•K—v‚Å‚·"
+
+msgid "E522: Not found in termcap"
+msgstr "E522: termcap “à‚ÉŒ©‚‚©‚è‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "E539: Illegal character <%s>"
+msgstr "E539: •s³‚È•¶Žš‚Å‚· <%s>"
+
+msgid "E529: Cannot set 'term' to empty string"
+msgstr "E529: 'term' ‚ɂ͋󕶎š—ñ‚ðÝ’è‚Å‚«‚Ü‚¹‚ñ"
+
+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 "E589: 'backupext' and 'patchmode' are equal"
+msgstr "E589: 'backupext' ‚Æ 'patchmode' ‚ª“¯‚¶‚Å‚·"
+
+msgid "E834: Conflicts with value of 'listchars'"
+msgstr "E834: 'listchars'‚Ì’l‚É–µ‚‚ª‚ ‚è‚Ü‚·"
+
+msgid "E835: Conflicts with value of 'fillchars'"
+msgstr "E835: 'fillchars'‚Ì’l‚É–µ‚‚ª‚ ‚è‚Ü‚·"
+
+msgid "E617: Cannot be changed in the GTK+ 2 GUI"
+msgstr "E617: GTK+2 GUI‚ł͕ÏX‚Å‚«‚Ü‚¹‚ñ"
+
+msgid "E524: Missing colon"
+msgstr "E524: ƒRƒƒ“‚ª‚ ‚è‚Ü‚¹‚ñ"
+
+msgid "E525: Zero length string"
+msgstr "E525: •¶Žš—ñ‚Ì’·‚³‚ªƒ[ƒ‚Å‚·"
+
+#, c-format
+msgid "E526: Missing number after <%s>"
+msgstr "E526: <%s> ‚ÌŒã‚É”Žš‚ª‚ ‚è‚Ü‚¹‚ñ"
+
+msgid "E527: Missing comma"
+msgstr "E527: ƒJƒ“ƒ}‚ª‚ ‚è‚Ü‚¹‚ñ"
+
+msgid "E528: Must specify a ' value"
+msgstr "E528: ' ‚Ì’l‚ðŽw’肵‚È‚¯‚ê‚΂Ȃè‚Ü‚¹‚ñ"
+
+msgid "E595: contains unprintable or wide character"
+msgstr "E595: •\\ަ‚Å‚«‚È‚¢•¶Žš‚©ƒƒCƒh•¶Žš‚ðŠÜ‚ñ‚Å‚¢‚Ü‚·"
+
+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‚Å‚·"
+
+#, c-format
+msgid "E535: Illegal character after <%c>"
+msgstr "E535: <%c> ‚ÌŒã‚É•s³‚È•¶Žš‚ª‚ ‚è‚Ü‚·"
+
+msgid "E536: comma required"
+msgstr "E536: ƒJƒ“ƒ}‚ª•K—v‚Å‚·"
+
+#, c-format
+msgid "E537: 'commentstring' must be empty or contain %s"
+msgstr "E537: 'commentstring' ‚Í‹ó‚Å‚ ‚é‚© %s ‚ðŠÜ‚Þ•K—v‚ª‚ ‚è‚Ü‚·"
+
+msgid "E538: No mouse support"
+msgstr "E538: ƒ}ƒEƒX‚̓Tƒ|[ƒg‚³‚ê‚Ü‚¹‚ñ"
+
+msgid "E540: Unclosed expression sequence"
+msgstr "E540: Ž®‚ªI—¹‚µ‚Ä‚¢‚Ü‚¹‚ñ"
+
+msgid "E541: too many items"
+msgstr "E541: —v‘f‚ª‘½‰ß‚¬‚Ü‚·"
+
+msgid "E542: unbalanced groups"
+msgstr "E542: ƒOƒ‹[ƒv‚ª’Þ‡‚¢‚Ü‚¹‚ñ"
+
+msgid "E590: A preview window already exists"
+msgstr "E590: ƒvƒŒƒrƒ…[ƒEƒBƒ“ƒhƒE‚ªŠù‚É‘¶Ý‚µ‚Ü‚·"
+
+msgid "W17: Arabic requires UTF-8, do ':set encoding=utf-8'"
+msgstr ""
+"W17: ƒAƒ‰ƒrƒA•¶Žš‚É‚ÍUTF-8‚ª•K—v‚Ȃ̂Å, ':set encoding=utf-8' ‚µ‚Ä‚­‚¾‚³‚¢"
+
+#, c-format
+msgid "E593: Need at least %d lines"
+msgstr "E593: Å’á %d ‚Ìs”‚ª•K—v‚Å‚·"
+
+#, c-format
+msgid "E594: Need at least %d columns"
+msgstr "E594: Å’á %d ‚̃Jƒ‰ƒ€•‚ª•K—v‚Å‚·"
+
+#, 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.
+#, c-format
+msgid "E521: Number required: &%s = '%s'"
+msgstr "E521: ”Žš‚ª•K—v‚Å‚·: &%s = '%s'"
+
+msgid ""
+"\n"
+"--- Terminal codes ---"
+msgstr ""
+"\n"
+"--- ’[––ƒR[ƒh ---"
+
+msgid ""
+"\n"
+"--- Global option values ---"
+msgstr ""
+"\n"
+"--- ƒOƒ[ƒoƒ‹ƒIƒvƒVƒ‡ƒ“’l ---"
+
+msgid ""
+"\n"
+"--- Local option values ---"
+msgstr ""
+"\n"
+"--- ƒ[ƒJƒ‹ƒIƒvƒVƒ‡ƒ“’l ---"
+
+msgid ""
+"\n"
+"--- Options ---"
+msgstr ""
+"\n"
+"--- ƒIƒvƒVƒ‡ƒ“ ---"
+
+msgid "E356: get_varp ERROR"
+msgstr "E356: get_varp ƒGƒ‰["
+
+#, 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': ƒZƒ~ƒRƒƒ“‚ÌŒã‚É—]•ª‚È•¶Žš‚ª‚ ‚è‚Ü‚·: %s"
+
+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"
+
+#, c-format
+msgid "Need %s version %ld\n"
+msgstr "%s ‚̃o[ƒWƒ‡ƒ“ %ld ‚ª•K—v‚Å‚·\n"
+
+msgid "Cannot open NIL:\n"
+msgstr "NIL‚ðŠJ‚¯‚Ü‚¹‚ñ:\n"
+
+msgid "Cannot create "
+msgstr "쬂ł«‚Ü‚¹‚ñ "
+
+#, c-format
+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"
+
+#. if Vim opened a window: Executing a shell may cause crashes
+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‚µ‚Ü‚µ‚½"
+
+#, c-format
+msgid "to %s on %s"
+msgstr "%s ‚Ö (%s ã‚Ì)"
+
+#, c-format
+msgid "E613: Unknown printer font: %s"
+msgstr "E613: –¢’m‚̃vƒŠƒ“ƒ^ƒIƒvƒVƒ‡ƒ“‚Å‚·: %s"
+
+#, c-format
+msgid "E238: Print error: %s"
+msgstr "E238: ˆóüƒGƒ‰[: %s"
+
+#, c-format
+msgid "Printing '%s'"
+msgstr "ˆóü‚µ‚Ä‚¢‚Ü‚·: '%s'"
+
+#, c-format
+msgid "E244: Illegal charset name \"%s\" in font name \"%s\""
+msgstr "E244: •¶ŽšƒZƒbƒg–¼ \"%s\" ‚Í•s³‚Å‚· (ƒtƒHƒ“ƒg–¼ \"%s\")"
+
+#, c-format
+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"
+
+#, c-format
+msgid "Vim: Caught deadly signal %s\n"
+msgstr "Vim: ’v–½“IƒVƒOƒiƒ‹ %s ‚ðŒŸ’m‚µ‚Ü‚µ‚½\n"
+
+#, c-format
+msgid "Vim: Caught deadly signal\n"
+msgstr "Vim: ’v–½“IƒVƒOƒiƒ‹‚ðŒŸ’m‚µ‚Ü‚µ‚½\n"
+
+#, c-format
+msgid "Opening the X display took %ld msec"
+msgstr "XƒT[ƒo‚Ö‚ÌÚ‘±‚É %ld ƒ~ƒŠ•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"
+"Could not get security context for "
+msgstr ""
+"\n"
+"ƒZƒLƒ…ƒŠƒeƒBƒRƒ“ƒeƒLƒXƒg‚ðŽæ“¾‚Å‚«‚Ü‚¹‚ñ "
+
+msgid ""
+"\n"
+"Could not set security context for "
+msgstr ""
+"\n"
+"ƒZƒLƒ…ƒŠƒeƒBƒRƒ“ƒeƒLƒXƒg‚ðÝ’è‚Å‚«‚Ü‚¹‚ñ "
+
+msgid ""
+"\n"
+"Cannot execute shell "
+msgstr ""
+"\n"
+"ƒVƒFƒ‹‚ðŽÀs‚Å‚«‚Ü‚¹‚ñ "
+
+msgid ""
+"\n"
+"Cannot execute shell sh\n"
+msgstr ""
+"\n"
+"sh ƒVƒFƒ‹‚ðŽÀs‚Å‚«‚Ü‚¹‚ñ\n"
+
+msgid ""
+"\n"
+"shell returned "
+msgstr ""
+"\n"
+"ƒVƒFƒ‹‚ª’l‚ð•Ô‚µ‚Ü‚µ‚½ "
+
+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Ú‘±‚ðŽ¸‚¢‚Ü‚µ‚½"
+
+#, c-format
+msgid "dlerror = \"%s\""
+msgstr "dlerror = \"%s\""
+
+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‚µ‚½‚悤‚Å‚·"
+
+#, c-format
+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ƒ“ƒ^‚ðŽæ“¾‚Å‚«‚Ü‚¹‚ñ‚Å‚µ‚½"
+
+#, c-format
+msgid "shell returned %d"
+msgstr "ƒVƒFƒ‹‚ªƒR[ƒh %d ‚ÅI—¹‚µ‚Ü‚µ‚½"
+
+#, c-format
+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"
+
+#, c-format
+msgid "E372: Too many %%%c in format string"
+msgstr "E372: ƒtƒH[ƒ}ƒbƒg•¶Žš—ñ‚É %%%c ‚ª‘½‰ß‚¬‚Ü‚·"
+
+#, c-format
+msgid "E373: Unexpected %%%c in format string"
+msgstr "E373: ƒtƒH[ƒ}ƒbƒg•¶Žš—ñ‚É—\\Šú‚¹‚Ê %%%c ‚ª‚ ‚è‚Ü‚µ‚½"
+
+msgid "E374: Missing ] in format string"
+msgstr "E374: ƒtƒH[ƒ}ƒbƒg•¶Žš—ñ‚É ] ‚ª‚ ‚è‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "E375: Unsupported %%%c in format string"
+msgstr "E375: ƒtƒH[ƒ}ƒbƒg•¶Žš—ñ‚Å‚Í %%%c ‚̓Tƒ|[ƒg‚³‚ê‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "E376: Invalid %%%c in format string prefix"
+msgstr "E376: ƒtƒH[ƒ}ƒbƒg•¶Žš—ñ‚Ì‘O’u‚É–³Œø‚È %%%c ‚ª‚ ‚è‚Ü‚·"
+
+#, c-format
+msgid "E377: Invalid %%%c in format string"
+msgstr "E377: ƒtƒH[ƒ}ƒbƒg•¶Žš—ñ‚É–³Œø‚È %%%c ‚ª‚ ‚è‚Ü‚·"
+
+msgid "E378: 'errorformat' contains no pattern"
+msgstr "E378: 'errorformat' ‚Ƀpƒ^[ƒ“‚ªŽw’肳‚ê‚Ä‚¢‚Ü‚¹‚ñ"
+
+msgid "E379: Missing or empty directory name"
+msgstr "E379: ƒfƒBƒŒƒNƒgƒŠ–¼‚ª–³‚¢‚©‹ó‚Å‚·"
+
+msgid "E553: No more items"
+msgstr "E553: —v‘f‚ª‚à‚¤‚ ‚è‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "(%d of %d)%s%s: "
+msgstr "(%d of %d)%s%s: "
+
+msgid " (line deleted)"
+msgstr " (s‚ªíœ‚³‚ê‚Ü‚µ‚½)"
+
+msgid "E380: At bottom of quickfix stack"
+msgstr "E380: quickfix ƒXƒ^ƒbƒN‚Ì––”ö‚Å‚·"
+
+msgid "E381: At top of quickfix stack"
+msgstr "E381: quickfix ƒXƒ^ƒbƒN‚Ìæ“ª‚Å‚·"
+
+#, c-format
+msgid "error list %d of %d; %d errors"
+msgstr "ƒGƒ‰[ˆê—— %d of %d; %d ŒÂƒGƒ‰["
+
+msgid "E382: Cannot write, 'buftype' option is set"
+msgstr "E382: 'buftype' ƒIƒvƒVƒ‡ƒ“‚ªÝ’肳‚ê‚Ä‚¢‚é‚̂őž‚݂܂¹‚ñ"
+
+msgid "Error file"
+msgstr "ƒGƒ‰[ƒtƒ@ƒCƒ‹"
+
+msgid "E683: File name missing or invalid pattern"
+msgstr "E683: ƒtƒ@ƒCƒ‹–¼‚ª–³‚¢‚©–³Œø‚ȃpƒ^[ƒ“‚Å‚·"
+
+#, c-format
+msgid "Cannot open file \"%s\""
+msgstr "ƒtƒ@ƒCƒ‹ \"%s\" ‚ðŠJ‚¯‚Ü‚¹‚ñ"
+
+msgid "E681: Buffer is not loaded"
+msgstr "E681: ƒoƒbƒtƒ@‚͓ǂݞ‚Ü‚ê‚Ü‚¹‚ñ‚Å‚µ‚½"
+
+msgid "E777: String or List expected"
+msgstr "E777: •¶Žš—ñ‚©ƒŠƒXƒg‚ª•K—v‚Å‚·"
+
+#, c-format
+msgid "E369: invalid item in %s%%[]"
+msgstr "E369: –³Œø‚È€–Ú‚Å‚·: %s%%[]"
+
+#
+#, c-format
+msgid "E769: Missing ] after %s["
+msgstr "E769: %s[ ‚ÌŒã‚É ] ‚ª‚ ‚è‚Ü‚¹‚ñ"
+
+#, 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( ‚̓RƒR‚ł͋–‰Â‚³‚ê‚Ä‚¢‚Ü‚¹‚ñ"
+
+#
+msgid "E67: \\z1 et al. not allowed here"
+msgstr "E67: \\z1 ‚»‚Ì‘¼‚̓RƒR‚ł͋–‰Â‚³‚ê‚Ä‚¢‚Ü‚¹‚ñ"
+
+#
+#, c-format
+msgid "E69: Missing ] after %s%%["
+msgstr "E69: %s%%[ ‚ÌŒã‚É ] ‚ª‚ ‚è‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "E70: Empty %s%%[]"
+msgstr "E70: %s%%[] ‚ª‹ó‚Å‚·"
+
+msgid "E339: Pattern too long"
+msgstr "E339: ƒpƒ^[ƒ“‚ª’·‰ß‚¬‚Ü‚·"
+
+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@ ‚ÌŒã‚É•s³‚È•¶Žš‚ª‚ ‚è‚Ü‚µ‚½"
+
+#, c-format
+msgid "E60: Too many complex %s{...}s"
+msgstr "E60: •¡ŽG‚È %s{...} ‚ª‘½‰ß‚¬‚Ü‚·"
+
+#, c-format
+msgid "E61: Nested %s*"
+msgstr "E61:%s* ‚ª“ü‚êŽq‚ɂȂÁ‚Ä‚¢‚Ü‚·"
+
+#, c-format
+msgid "E62: Nested %s%c"
+msgstr "E62:%s%c ‚ª“ü‚êŽq‚ɂȂÁ‚Ä‚¢‚Ü‚·"
+
+#
+msgid "E63: invalid use of \\_"
+msgstr "E63: \\_ ‚Ì–³Œø‚ÈŽg—p•û–@‚Å‚·"
+
+#, c-format
+msgid "E64: %s%c follows nothing"
+msgstr "E64:%s%c ‚ÌŒã‚É‚È‚É‚à‚ ‚è‚Ü‚¹‚ñ"
+
+#
+msgid "E65: Illegal back reference"
+msgstr "E65: •s³‚ÈŒã•ûŽQƂł·"
+
+#
+msgid "E68: Invalid character after \\z"
+msgstr "E68: \\z ‚ÌŒã‚É•s³‚È•¶Žš‚ª‚ ‚è‚Ü‚µ‚½"
+
+#
+#, c-format
+msgid "E678: Invalid character after %s%%[dxouU]"
+msgstr "E678: %s%%[dxouU] ‚ÌŒã‚É•s³‚È•¶Žš‚ª‚ ‚è‚Ü‚µ‚½"
+
+#
+#, c-format
+msgid "E71: Invalid character after %s%%"
+msgstr "E71: %s%% ‚ÌŒã‚É•s³‚È•¶Žš‚ª‚ ‚è‚Ü‚µ‚½"
+
+#, c-format
+msgid "E554: Syntax error in %s{...}"
+msgstr "E554: %s{...} “à‚É•¶–@ƒGƒ‰[‚ª‚ ‚è‚Ü‚·"
+
+msgid "External submatches:\n"
+msgstr "ŠO•”‚Ì•”•ªŠY“–:\n"
+
+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"
+
+#, c-format
+msgid "E866: (NFA regexp) Misplaced %c"
+msgstr "E866: (NFA ³‹K•\\Œ») ˆÊ’u‚ªŒë‚Á‚Ä‚¢‚Ü‚·: %c"
+
+msgid "E865: (NFA) Regexp end encountered prematurely"
+msgstr "E865: (NFA) Šú‘Ò‚æ‚è‘‚­³‹K•\\Œ»‚ÌI’[‚É“ž’B‚µ‚Ü‚µ‚½"
+
+#, c-format
+msgid "E867: (NFA) Unknown operator '\\z%c'"
+msgstr "E867: (NFA) –¢’m‚̃IƒyƒŒ[ƒ^‚Å‚·: '\\z%c'"
+
+#, c-format
+msgid "E867: (NFA) Unknown operator '\\%%%c'"
+msgstr "E867: (NFA) –¢’m‚̃IƒyƒŒ[ƒ^‚Å‚·: '\\%%%c'"
+
+#. should never happen
+msgid "E868: Error building NFA with equivalence class!"
+msgstr "E868: “™‰¿ƒNƒ‰ƒX‚ðŠÜ‚ÞNFA\\’z‚ÉŽ¸”s‚µ‚Ü‚µ‚½!"
+
+#, c-format
+msgid "E869: (NFA) Unknown operator '\\@%c'"
+msgstr "E869: (NFA) –¢’m‚̃IƒyƒŒ[ƒ^‚Å‚·: '\\@%c'"
+
+msgid "E870: (NFA regexp) Error reading repetition limits"
+msgstr "E870: (NFA ³‹K•\\Œ») ŒJ‚è•Ô‚µ‚̧ŒÀ‰ñ”‚ð“Çž’†‚ɃGƒ‰["
+
+#. Can't have a multi follow a multi.
+msgid "E871: (NFA regexp) Can't have a multi follow a multi !"
+msgstr "E871: (NFA ³‹K•\\Œ») ŒJ‚è•Ô‚µ ‚ÌŒã‚É ŒJ‚è•Ô‚µ ‚͂ł«‚Ü‚¹‚ñ!"
+
+#. Too many `('
+msgid "E872: (NFA regexp) Too many '('"
+msgstr "E872: (NFA ³‹K•\\Œ») '(' ‚ª‘½‰ß‚¬‚Ü‚·"
+
+msgid "E879: (NFA regexp) Too many \\z("
+msgstr "E879: (NFA ³‹K•\\Œ») \\z( ‚ª‘½‰ß‚¬‚Ü‚·"
+
+msgid "E873: (NFA regexp) proper termination error"
+msgstr "E873: (NFA ³‹K•\\Œ») I’[‹L†‚ª‚ ‚è‚Ü‚¹‚ñ"
+
+msgid "E874: (NFA) Could not pop the stack !"
+msgstr "E874: (NFA) ƒXƒ^ƒbƒN‚ðƒ|ƒbƒv‚Å‚«‚Ü‚¹‚ñ!"
+
+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‚ª‘½‰ß‚¬‚Ü‚·"
+
+msgid "E876: (NFA regexp) Not enough space to store the whole NFA "
+msgstr "E876: (NFA ³‹K•\\Œ») NFA‘S‘Ì‚ð•Û‘¶‚·‚é‚ɂ͋󂫃Xƒy[ƒX‚ª‘«‚è‚Ü‚¹‚ñ"
+
+msgid "E878: (NFA) Could not allocate memory for branch traversal!"
+msgstr "E878: (NFA) Œ»Ý‰¡’f’†‚̃uƒ‰ƒ“ƒ`‚É\\•ª‚ȃƒ‚ƒŠ‚ðŠ„‚è“–‚Ä‚ç‚ê‚Ü‚¹‚ñ!"
+
+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"
+
+#, c-format
+msgid "(NFA) COULD NOT OPEN %s !"
+msgstr "(NFA) ƒƒOƒtƒ@ƒCƒ‹ %s ‚ðŠJ‚¯‚Ü‚¹‚ñ!"
+
+msgid "Could not open temporary log file for writing "
+msgstr "NFA³‹K•\\Œ»ƒGƒ“ƒWƒ“—p‚̃ƒOƒtƒ@ƒCƒ‹‚𑞗p‚Æ‚µ‚ÄŠJ‚¯‚Ü‚¹‚ñB"
+
+msgid " VREPLACE"
+msgstr " ‰¼‘z’uŠ·"
+
+msgid " REPLACE"
+msgstr " ’uŠ·"
+
+msgid " REVERSE"
+msgstr " ”½“]"
+
+msgid " INSERT"
+msgstr " ‘}“ü"
+
+msgid " (insert)"
+msgstr " (‘}“ü)"
+
+msgid " (replace)"
+msgstr " (’uŠ·)"
+
+msgid " (vreplace)"
+msgstr " (‰¼‘z’uŠ·)"
+
+msgid " Hebrew"
+msgstr " ƒwƒuƒ‰ƒC"
+
+msgid " Arabic"
+msgstr " ƒAƒ‰ƒrƒA"
+
+msgid " (lang)"
+msgstr " (Œ¾Œê)"
+
+msgid " (paste)"
+msgstr " (“\\‚è•t‚¯)"
+
+msgid " VISUAL"
+msgstr " ƒrƒWƒ…ƒAƒ‹"
+
+msgid " VISUAL LINE"
+msgstr " ƒrƒWƒ…ƒAƒ‹ s"
+
+msgid " VISUAL BLOCK"
+msgstr " ƒrƒWƒ…ƒAƒ‹ ‹éŒ`"
+
+msgid " SELECT"
+msgstr " ƒZƒŒƒNƒg"
+
+msgid " SELECT LINE"
+msgstr " sŽwŒü‘I‘ð"
+
+msgid " SELECT BLOCK"
+msgstr " ‹éŒ`‘I‘ð"
+
+msgid "recording"
+msgstr "‹L˜^’†"
+
+#, c-format
+msgid "E383: Invalid search string: %s"
+msgstr "E383: –³Œø‚ÈŒŸõ•¶Žš—ñ‚Å‚·: %s"
+
+#, c-format
+msgid "E384: search hit TOP without match for: %s"
+msgstr "E384: ã‚܂ŌŸõ‚µ‚Ü‚µ‚½‚ªŠY“–‰ÓŠ‚Í‚ ‚è‚Ü‚¹‚ñ: %s"
+
+#, c-format
+msgid "E385: search hit BOTTOM without match for: %s"
+msgstr "E385: ‰º‚܂ŌŸõ‚µ‚Ü‚µ‚½‚ªŠY“–‰ÓŠ‚Í‚ ‚è‚Ü‚¹‚ñ: %s"
+
+msgid "E386: Expected '?' or '/' after ';'"
+msgstr "E386: ';' ‚Ì‚ ‚Æ‚É‚Í '?' ‚© '/' ‚ªŠú‘Ò‚³‚ê‚Ä‚¢‚é"
+
+msgid " (includes previously listed match)"
+msgstr " (‘O‚É—ñ‹“‚µ‚½ŠY“–‰ÓŠ‚ðŠÜ‚Þ)"
+
+#. cursor at status line
+msgid "--- Included files "
+msgstr "--- ƒCƒ“ƒNƒ‹[ƒh‚³‚ꂽƒtƒ@ƒCƒ‹ "
+
+msgid "not found "
+msgstr "Œ©‚‚©‚è‚Ü‚¹‚ñ "
+
+msgid "in path ---\n"
+msgstr "ƒpƒX‚É ----\n"
+
+msgid " (Already listed)"
+msgstr " (Šù‚É—ñ‹“)"
+
+msgid " NOT FOUND"
+msgstr " Œ©‚‚©‚è‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "Scanning included file: %s"
+msgstr "ƒCƒ“ƒNƒ‹[ƒh‚³‚ꂽƒtƒ@ƒCƒ‹‚ðƒXƒLƒƒƒ“’†: %s"
+
+#, c-format
+msgid "Searching included file %s"
+msgstr "ƒCƒ“ƒNƒ‹[ƒh‚³‚ꂽƒtƒ@ƒCƒ‹‚ðƒXƒLƒƒƒ“’† %s"
+
+msgid "E387: Match is on current line"
+msgstr "E387: Œ»Ýs‚ÉŠY“–‚ª‚ ‚è‚Ü‚·"
+
+msgid "All included files were found"
+msgstr "‘S‚ẴCƒ“ƒNƒ‹[ƒh‚³‚ꂽƒtƒ@ƒCƒ‹‚ªŒ©‚‚©‚è‚Ü‚µ‚½"
+
+msgid "No included files"
+msgstr "ƒCƒ“ƒNƒ‹[ƒhƒtƒ@ƒCƒ‹‚Í‚ ‚è‚Ü‚¹‚ñ"
+
+msgid "E388: Couldn't find definition"
+msgstr "E388: ’è‹`‚ðŒ©‚Â‚¯‚ç‚ê‚Ü‚¹‚ñ"
+
+msgid "E389: Couldn't find pattern"
+msgstr "E389: ƒpƒ^[ƒ“‚ðŒ©‚Â‚¯‚ç‚ê‚Ü‚¹‚ñ"
+
+msgid "Substitute "
+msgstr "Substitute "
+
+#, c-format
+msgid ""
+"\n"
+"# Last %sSearch Pattern:\n"
+"~"
+msgstr ""
+"\n"
+"# ÅŒã‚Ì %sŒŸõƒpƒ^[ƒ“:\n"
+"~"
+
+msgid "E759: Format error in spell file"
+msgstr "E759: ƒXƒyƒ‹ƒtƒ@ƒCƒ‹‚Ì‘Ž®ƒGƒ‰[‚Å‚·"
+
+msgid "E758: Truncated spell file"
+msgstr "E758: ƒXƒyƒ‹ƒtƒ@ƒCƒ‹‚ªØŽæ‚ç‚ê‚Ä‚¢‚邿‚¤‚Å‚·"
+
+#, c-format
+msgid "Trailing text in %s line %d: %s"
+msgstr "%s (%d s–Ú) ‚É‘±‚­ƒeƒLƒXƒg: %s"
+
+#, c-format
+msgid "Affix name too long in %s line %d: %s"
+msgstr "%s (%d s–Ú) ‚Ì affix –¼‚ª’·‰ß‚¬‚Ü‚·: %s"
+
+msgid "E761: Format error in affix file FOL, LOW or UPP"
+msgstr ""
+"E761: affixƒtƒ@ƒCƒ‹‚Ì FOL, LOW ‚à‚µ‚­‚Í UPP ‚̃tƒH[ƒ}ƒbƒg‚ɃGƒ‰[‚ª‚ ‚è‚Ü‚·"
+
+msgid "E762: Character in FOL, LOW or UPP is out of range"
+msgstr "E762: FOL, LOW ‚à‚µ‚­‚Í UPP ‚Ì•¶Žš‚ª”͈͊O‚Å‚·"
+
+msgid "Compressing word tree..."
+msgstr "’PŒêƒcƒŠ[‚ðˆ³k‚µ‚Ä‚¢‚Ü‚·..."
+
+msgid "E756: Spell checking is not enabled"
+msgstr "E756: ƒXƒyƒ‹ƒ`ƒFƒbƒN‚Í–³Œø‰»‚³‚ê‚Ä‚¢‚Ü‚·"
+
+#, 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\" ‚ÍŒ©‚‚©‚è‚Ü‚¹‚ñ"
+
+#, 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\" ‚ÍŒ©‚‚©‚è‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "Reading spell file \"%s\""
+msgstr "ƒXƒyƒ‹ƒtƒ@ƒCƒ‹ \"%s\" ‚ð“Çž’†"
+
+msgid "E757: This does not look like a spell file"
+msgstr "E757: ƒXƒyƒ‹ƒtƒ@ƒCƒ‹‚ł͂Ȃ¢‚悤‚Å‚·"
+
+msgid "E771: Old spell file, needs to be updated"
+msgstr "E771: ŒÃ‚¢ƒXƒyƒ‹ƒtƒ@ƒCƒ‹‚Ȃ̂Å, ƒAƒbƒvƒf[ƒg‚µ‚Ä‚­‚¾‚³‚¢"
+
+msgid "E772: Spell file is for newer version of Vim"
+msgstr "E772: ‚æ‚èV‚µ‚¢ƒo[ƒWƒ‡ƒ“‚Ì Vim —p‚̃Xƒyƒ‹ƒtƒ@ƒCƒ‹‚Å‚·"
+
+msgid "E770: Unsupported section in spell file"
+msgstr "E770: ƒXƒyƒ‹ƒtƒ@ƒCƒ‹‚ɃTƒ|[ƒg‚µ‚Ä‚¢‚È‚¢ƒZƒNƒVƒ‡ƒ“‚ª‚ ‚è‚Ü‚·"
+
+#, c-format
+msgid "Warning: region %s not supported"
+msgstr "Œx9: %s ‚Æ‚¢‚¤”͈͂̓Tƒ|[ƒg‚³‚ê‚Ä‚¢‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "Reading affix file %s ..."
+msgstr "affix ƒtƒ@ƒCƒ‹ %s ‚ð“Çž’†..."
+
+#, c-format
+msgid "Conversion failure for word in %s line %d: %s"
+msgstr "%s (%d s–Ú) ‚Ì’PŒê‚ð•ÏŠ·‚Å‚«‚Ü‚¹‚ñ‚Å‚µ‚½: %s"
+
+#, c-format
+msgid "Conversion in %s not supported: from %s to %s"
+msgstr "%s “à‚ÌŽŸ‚̕ϊ·‚̓Tƒ|[ƒg‚³‚ê‚Ä‚¢‚Ü‚¹‚ñ: %s ‚©‚ç %s ‚Ö"
+
+#, c-format
+msgid "Conversion in %s not supported"
+msgstr "%s “à‚̕ϊ·‚̓Tƒ|[ƒg‚³‚ê‚Ä‚¢‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "Invalid value for FLAG in %s line %d: %s"
+msgstr "%s “à‚Ì %d s–Ú‚Ì FLAG ‚É–³Œø‚È’l‚ª‚ ‚è‚Ü‚·: %s"
+
+#, c-format
+msgid "FLAG after using flags in %s line %d: %s"
+msgstr "%s “à‚Ì %d s–ڂɃtƒ‰ƒO‚Ì“ñdŽg—p‚ª‚ ‚è‚Ü‚·: %s"
+
+#, c-format
+msgid ""
+"Defining COMPOUNDFORBIDFLAG after PFX item may give wrong results in %s line "
+"%d"
+msgstr ""
+"%s ‚Ì %d s–Ú‚Ì PFX €–Ú‚ÌŒã‚Ì COMPOUNDFORBIDFLAG ‚Ì’è‹`‚ÍŒë‚Á‚½Œ‹‰Ê‚ð¶‚¶‚é"
+"‚±‚Æ‚ª‚ ‚è‚Ü‚·"
+
+#, c-format
+msgid ""
+"Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in %s line "
+"%d"
+msgstr ""
+"%s ‚Ì %d s–Ú‚Ì PFX €–Ú‚ÌŒã‚Ì COMPOUNDPERMITFLAG ‚Ì’è‹`‚ÍŒë‚Á‚½Œ‹‰Ê‚ð¶‚¶‚é"
+"‚±‚Æ‚ª‚ ‚è‚Ü‚·"
+
+#, c-format
+msgid "Wrong COMPOUNDRULES value in %s line %d: %s"
+msgstr "COMPOUNDRULES ‚Ì’l‚ÉŒë‚肪‚ ‚è‚Ü‚·. ƒtƒ@ƒCƒ‹ %s ‚Ì %d s–Ú: %s"
+
+#, c-format
+msgid "Wrong COMPOUNDWORDMAX value in %s line %d: %s"
+msgstr "%s ‚Ì %d s–Ú‚Ì COMPOUNDWORDMAX ‚Ì’l‚ÉŒë‚肪‚ ‚è‚Ü‚·: %s"
+
+#, c-format
+msgid "Wrong COMPOUNDMIN value in %s line %d: %s"
+msgstr "%s ‚Ì %d s–Ú‚Ì COMPOUNDMIN ‚Ì’l‚ÉŒë‚肪‚ ‚è‚Ü‚·: %s"
+
+#, c-format
+msgid "Wrong COMPOUNDSYLMAX value in %s line %d: %s"
+msgstr "%s ‚Ì %d s–Ú‚Ì COMPOUNDSYLMAX ‚Ì’l‚ÉŒë‚肪‚ ‚è‚Ü‚·: %s"
+
+#, c-format
+msgid "Wrong CHECKCOMPOUNDPATTERN value in %s line %d: %s"
+msgstr "%s ‚Ì %d s–Ú‚Ì CHECKCOMPOUNDPATTERN ‚Ì’l‚ÉŒë‚肪‚ ‚è‚Ü‚·: %s"
+
+#, 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"
+
+#, c-format
+msgid "Duplicate affix in %s line %d: %s"
+msgstr "%s ‚Ì %d s–Ú‚É d•¡‚µ‚½ affix ‚ðŒŸo‚µ‚Ü‚µ‚½: %s"
+
+#, 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"
+
+#, c-format
+msgid "Expected Y or N in %s line %d: %s"
+msgstr "%s ‚Ì %d s–Ú‚Å‚Í Y ‚© N ‚ª•K—v‚Å‚·: %s"
+
+#, c-format
+msgid "Broken condition in %s line %d: %s"
+msgstr "%s ‚Ì %d s–Ú‚Ì ðŒ‚͉ó‚ê‚Ä‚¢‚Ü‚·: %s"
+
+#, c-format
+msgid "Expected REP(SAL) count in %s line %d"
+msgstr "%s ‚Ì %d s–Ú‚É‚Í REP(SAL) ‚̉ñ”‚ª•K—v‚Å‚·"
+
+#, c-format
+msgid "Expected MAP count in %s line %d"
+msgstr "%s ‚Ì %d s–Ú‚É‚Í MAP ‚̉ñ”‚ª•K—v‚Å‚·"
+
+#, c-format
+msgid "Duplicate character in MAP in %s line %d"
+msgstr "%s ‚Ì %d s–Ú‚Ì MAP ‚Éd•¡‚µ‚½•¶Žš‚ª‚ ‚è‚Ü‚·"
+
+#, c-format
+msgid "Unrecognized or duplicate item in %s line %d: %s"
+msgstr "%s ‚Ì %d s–Ú‚É ”Fޝ‚Å‚«‚È‚¢‚©d•¡‚µ‚½€–Ú‚ª‚ ‚è‚Ü‚·: %s"
+
+#, c-format
+msgid "Missing FOL/LOW/UPP line in %s"
+msgstr "%s s–Ú‚É FOL/LOW/UPP ‚ª‚ ‚è‚Ü‚¹‚ñ"
+
+msgid "COMPOUNDSYLMAX used without SYLLABLE"
+msgstr "SYLLABLE ‚ªŽw’肳‚ê‚È‚¢ COMPOUNDSYLMAX"
+
+msgid "Too many postponed prefixes"
+msgstr "’x‰„Œã’uŽq‚ª‘½‰ß‚¬‚Ü‚·"
+
+msgid "Too many compound flags"
+msgstr "•¡‡ƒtƒ‰ƒO‚ª‘½‰ß‚¬‚Ü‚·"
+
+msgid "Too many postponed prefixes and/or compound flags"
+msgstr "’x‰„Œã’uŽq ‚Æ/‚à‚µ‚­‚Í •¡‡ƒtƒ‰ƒO‚ª‘½‰ß‚¬‚Ü‚·"
+
+#, c-format
+msgid "Missing SOFO%s line in %s"
+msgstr "SOFO%s s‚ª %s ‚É‚ ‚è‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "Both SAL and SOFO lines in %s"
+msgstr "SALs ‚Æ SOFOs ‚ª %s ‚Å—¼•ûŽw’肳‚ê‚Ä‚¢‚Ü‚·"
+
+#, c-format
+msgid "Flag is not a number in %s line %d: %s"
+msgstr "%s ‚Ì %d s‚Ì ƒtƒ‰ƒO‚ª”’l‚ł͂ ‚è‚Ü‚¹‚ñ: %s"
+
+#, c-format
+msgid "Illegal flag in %s line %d: %s"
+msgstr "%s ‚Ì %d s–Ú‚Ì ƒtƒ‰ƒO‚ª•s³‚Å‚·: %s"
+
+#, c-format
+msgid "%s value differs from what is used in another .aff file"
+msgstr "’l %s ‚Í‘¼‚Ì .aff ƒtƒ@ƒCƒ‹‚ÅŽg—p‚³‚ꂽ‚̂ƈقȂè‚Ü‚·"
+
+#, c-format
+msgid "Reading dictionary file %s ..."
+msgstr "Ž«‘ƒtƒ@ƒCƒ‹ %s ‚ðƒXƒLƒƒƒ“’†..."
+
+#, c-format
+msgid "E760: No word count in %s"
+msgstr "E760: %s ‚ɂ͒PŒê”‚ª‚ ‚è‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "line %6d, word %6d - %s"
+msgstr "s %6d, ’PŒê %6d - %s"
+
+#, c-format
+msgid "Duplicate word in %s line %d: %s"
+msgstr "%s ‚Ì %d s–Ú‚Å d•¡’PŒê‚ªŒ©‚‚©‚è‚Ü‚µ‚½: %s"
+
+#, c-format
+msgid "First duplicate word in %s line %d: %s"
+msgstr "d•¡‚Ì‚¤‚¿Å‰‚Ì’PŒê‚Í %s ‚Ì %d s–Ú‚Å‚·: %s"
+
+#, c-format
+msgid "%d duplicate word(s) in %s"
+msgstr "%d ŒÂ‚Ì’PŒê‚ªŒ©‚‚©‚è‚Ü‚µ‚½ (%s “à)"
+
+#, c-format
+msgid "Ignored %d word(s) with non-ASCII characters in %s"
+msgstr "”ñASCII•¶Žš‚ðŠÜ‚Þ %d ŒÂ‚Ì’PŒê‚𖳎‹‚µ‚Ü‚µ‚½ (%s “à)"
+
+#, c-format
+msgid "Reading word file %s ..."
+msgstr "•W€“ü—Í‚©‚ç“Çž‚Ý’† %s ..."
+
+#, c-format
+msgid "Duplicate /encoding= line ignored in %s line %d: %s"
+msgstr "%s ‚Ì %d s–Ú‚Ì d•¡‚µ‚½ /encoding= s‚𖳎‹‚µ‚Ü‚µ‚½: %s"
+
+#, c-format
+msgid "/encoding= line after word ignored in %s line %d: %s"
+msgstr "%s ‚Ì %d s–Ú‚Ì ’PŒê‚ÌŒã‚Ì /encoding= s‚𖳎‹‚µ‚Ü‚µ‚½: %s"
+
+#, c-format
+msgid "Duplicate /regions= line ignored in %s line %d: %s"
+msgstr "%s ‚Ì %d s–Ú‚Ì d•¡‚µ‚½ /regions= s‚𖳎‹‚µ‚Ü‚µ‚½: %s"
+
+#, c-format
+msgid "Too many regions in %s line %d: %s"
+msgstr "%s ‚Ì %d s–Ú, ”͈͎w’肪‘½‰ß‚¬‚Ü‚·: %s"
+
+#, c-format
+msgid "/ line ignored in %s line %d: %s"
+msgstr "%s ‚Ì %d s–Ú‚Ì d•¡‚µ‚½ / s‚𖳎‹‚µ‚Ü‚µ‚½: %s"
+
+#, c-format
+msgid "Invalid region nr in %s line %d: %s"
+msgstr "%s ‚Ì %d s–Ú –³Œø‚È nr —̈æ‚Å‚·: %s"
+
+#, c-format
+msgid "Unrecognized flags in %s line %d: %s"
+msgstr "%s ‚Ì %d s–Ú ”Fޝ•s”\\‚ȃtƒ‰ƒO‚Å‚·: %s"
+
+#, c-format
+msgid "Ignored %d words with non-ASCII characters"
+msgstr "”ñASCII•¶Žš‚ðŠÜ‚Þ %d ŒÂ‚Ì’PŒê‚𖳎‹‚µ‚Ü‚µ‚½"
+
+msgid "E845: Insufficient memory, word list will be incomplete"
+msgstr "E845: ƒƒ‚ƒŠ‚ª‘«‚è‚È‚¢‚Ì‚ÅA’PŒêƒŠƒXƒg‚Í•sŠ®‘S‚Å‚·"
+
+#, c-format
+msgid "Compressed %d of %d nodes; %d (%d%%) remaining"
+msgstr "ƒm[ƒh %d ŒÂ(‘S %d ŒÂ’†) ‚ðˆ³k‚µ‚Ü‚µ‚½; Žc‚è %d (%d%%)"
+
+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.
+#.
+msgid "Performing soundfolding..."
+msgstr "‰¹ºôž‚Ý‚ðŽÀs’†..."
+
+#, c-format
+msgid "Number of words after soundfolding: %ld"
+msgstr "‰¹ºôž‚ÝŒã‚Ì‘’PŒê”: %ld"
+
+#, c-format
+msgid "Total number of words: %d"
+msgstr "‘’PŒê”: %d"
+
+#, c-format
+msgid "Writing suggestion file %s ..."
+msgstr "C³Œó•âƒtƒ@ƒCƒ‹ \"%s\" ‚𑞂ݒ†..."
+
+#, c-format
+msgid "Estimated runtime memory use: %d bytes"
+msgstr "„’胃‚ƒŠŽg—p—Ê: %d ƒoƒCƒg"
+
+msgid "E751: Output file name must not have region name"
+msgstr "E751: o—̓tƒ@ƒCƒ‹–¼‚ɂ͔͈͖¼‚ðŠÜ‚ß‚ç‚ê‚Ü‚¹‚ñ"
+
+msgid "E754: Only up to 8 regions supported"
+msgstr "E754: ”ÍˆÍ‚Í 8 ŒÂ‚܂łµ‚©ƒTƒ|[ƒg‚³‚ê‚Ä‚¢‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "E755: Invalid region in %s"
+msgstr "E755: –³Œø‚Ȕ͈͂ł·: %s"
+
+msgid "Warning: both compounding and NOBREAK specified"
+msgstr "Œx: •¡‡ƒtƒ‰ƒO‚Æ NOBREAK ‚ª—¼•û‚Æ‚àŽw’肳‚ê‚Ü‚µ‚½"
+
+#, c-format
+msgid "Writing spell file %s ..."
+msgstr "ƒXƒyƒ‹ƒtƒ@ƒCƒ‹ %s ‚𑞂ݒ†..."
+
+msgid "Done!"
+msgstr "ŽÀs‚µ‚Ü‚µ‚½!"
+
+#, c-format
+msgid "E765: 'spellfile' does not have %ld entries"
+msgstr "E765: 'spellfile' ‚É‚Í %ld ŒÂ‚̃Gƒ“ƒgƒŠ‚Í‚ ‚è‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "Word removed from %s"
+msgstr "%s ‚©‚ç’PŒê‚ªíœ‚³‚ê‚Ü‚µ‚½"
+
+#, c-format
+msgid "Word added to %s"
+msgstr "%s ‚É’PŒê‚ª’ljÁ‚³‚ê‚Ü‚µ‚½"
+
+msgid "E763: Word characters differ between spell files"
+msgstr "E763: ’PŒê‚Ì•¶Žš‚ªƒXƒyƒ‹ƒtƒ@ƒCƒ‹‚ƈقȂè‚Ü‚·"
+
+msgid "Sorry, no suggestions"
+msgstr "Žc”O‚Å‚·‚ª, C³Œó•â‚Í‚ ‚è‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "Sorry, only %ld suggestions"
+msgstr "Žc”O‚Å‚·‚ª, C³Œó•â‚Í %ld ŒÂ‚µ‚©‚ ‚è‚Ü‚¹‚ñ"
+
+#. for when 'cmdheight' > 1
+#. avoid more prompt
+#, c-format
+msgid "Change \"%.*s\" to:"
+msgstr "\"%.*s\" ‚ðŽŸ‚Ö•ÏŠ·:"
+
+#, c-format
+msgid " < \"%.*s\""
+msgstr " < \"%.*s\""
+
+msgid "E752: No previous spell replacement"
+msgstr "E752: ƒXƒyƒ‹’uŠ·‚ª‚Ü‚¾ŽÀs‚³‚ê‚Ä‚¢‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "E753: Not found: %s"
+msgstr "E753: Œ©‚‚©‚è‚Ü‚¹‚ñ: %s"
+
+#, c-format
+msgid "E778: This does not look like a .sug file: %s"
+msgstr "E778: .sug ƒtƒ@ƒCƒ‹‚ł͂Ȃ¢‚悤‚Å‚·: %s"
+
+#, c-format
+msgid "E779: Old .sug file, needs to be updated: %s"
+msgstr "E779: ŒÃ‚¢ .sug ƒtƒ@ƒCƒ‹‚Ȃ̂Å, ƒAƒbƒvƒf[ƒg‚µ‚Ä‚­‚¾‚³‚¢: %s"
+
+#, c-format
+msgid "E780: .sug file is for newer version of Vim: %s"
+msgstr "E780: ‚æ‚èV‚µ‚¢ƒo[ƒWƒ‡ƒ“‚Ì Vim —p‚Ì .sug ƒtƒ@ƒCƒ‹‚Å‚·: %s"
+
+#, c-format
+msgid "E781: .sug file doesn't match .spl file: %s"
+msgstr "E781: .sug ƒtƒ@ƒCƒ‹‚ª .spl ƒtƒ@ƒCƒ‹‚ƈê’v‚µ‚Ü‚¹‚ñ: %s"
+
+#, 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.
+msgid "E783: duplicate char in MAP entry"
+msgstr "E783: MAP ƒGƒ“ƒgƒŠ‚Éd•¡•¶Žš‚ª‘¶Ý‚µ‚Ü‚·"
+
+msgid "No Syntax items defined for this buffer"
+msgstr "‚±‚̃oƒbƒtƒ@‚É’è‹`‚³‚ꂽ\\•¶—v‘f‚Í‚ ‚è‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "E390: Illegal argument: %s"
+msgstr "E390: •s³‚Ȉø”‚Å‚·: %s"
+
+#, c-format
+msgid "E391: No such syntax cluster: %s"
+msgstr "E391: ‚»‚̂悤‚È\\•¶ƒNƒ‰ƒXƒ^‚Í‚ ‚è‚Ü‚¹‚ñ: %s"
+
+msgid "syncing on C-style comments"
+msgstr "CŒ¾Œê•—ƒRƒƒ“ƒg‚©‚瓯Šú’†"
+
+msgid "no syncing"
+msgstr "”ñ“¯Šú"
+
+msgid "syncing starts "
+msgstr "“¯ŠúŠJŽn "
+
+msgid " lines before top line"
+msgstr " s‘O(ƒgƒbƒvs‚æ‚è‚à)"
+
+msgid ""
+"\n"
+"--- Syntax sync items ---"
+msgstr ""
+"\n"
+"--- \\•¶“¯Šú—v‘f ---"
+
+msgid ""
+"\n"
+"syncing on items"
+msgstr ""
+"\n"
+"—v‘fã‚Å“¯Šú’†"
+
+msgid ""
+"\n"
+"--- Syntax items ---"
+msgstr ""
+"\n"
+"--- \\•¶—v‘f ---"
+
+#, c-format
+msgid "E392: No such syntax cluster: %s"
+msgstr "E392: ‚»‚̂悤‚È\\•¶ƒNƒ‰ƒXƒ^‚Í‚ ‚è‚Ü‚¹‚ñ: %s"
+
+msgid "minimal "
+msgstr "minimal "
+
+msgid "maximal "
+msgstr "maximal "
+
+msgid "; match "
+msgstr "; ŠY“– "
+
+msgid " line breaks"
+msgstr " ŒÂ‚̉üs"
+
+msgid "E395: contains argument not accepted here"
+msgstr "E395: ‚±‚Ìꊂł͈ø”contains‚Í‹–‰Â‚³‚ê‚Ä‚¢‚Ü‚¹‚ñ"
+
+msgid "E844: invalid cchar value"
+msgstr "E844: –³Œø‚Ècchar‚Ì’l‚Å‚·"
+
+msgid "E393: group[t]here not accepted here"
+msgstr "E393: ‚±‚±‚ł̓Oƒ‹[ƒv‚Í‹–‰Â‚³‚ê‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "E394: Didn't find region item for %s"
+msgstr "E394: %s ‚͈̔͗v‘f‚ªŒ©‚‚©‚è‚Ü‚¹‚ñ"
+
+msgid "E397: Filename required"
+msgstr "E397: ƒtƒ@ƒCƒ‹–¼‚ª•K—v‚Å‚·"
+
+msgid "E847: Too many syntax includes"
+msgstr "E847: \\•¶‚ÌŽæ‚èž‚Ý(include)‚ª‘½‰ß‚¬‚Ü‚·"
+
+#, c-format
+msgid "E789: Missing ']': %s"
+msgstr "E789: ']' ‚ª‚ ‚è‚Ü‚¹‚ñ: %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: \\•¶ƒNƒ‰ƒXƒ^‚ª‘½‰ß‚¬‚Ü‚·"
+
+msgid "E400: No cluster specified"
+msgstr "E400: ƒNƒ‰ƒXƒ^‚ªŽw’肳‚ê‚Ä‚¢‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "E401: Pattern delimiter not found: %s"
+msgstr "E401: ƒpƒ^[ƒ“‹æØ‚肪Œ©‚‚©‚è‚Ü‚¹‚ñ: %s"
+
+#, c-format
+msgid "E402: Garbage after pattern: %s"
+msgstr "E402: ƒpƒ^[ƒ“‚Ì‚ ‚ƂɃSƒ~‚ª‚ ‚è‚Ü‚·: %s"
+
+msgid "E403: syntax sync: line continuations pattern specified twice"
+msgstr "E403: \\•¶“¯Šú: ˜A‘±sƒpƒ^[ƒ“‚ª2“xŽw’肳‚ê‚Ü‚µ‚½"
+
+#, c-format
+msgid "E404: Illegal arguments: %s"
+msgstr "E404: •s³‚Ȉø”‚Å‚·: %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 ‚̓RƒR‚ł͋–‰Â‚³‚ê‚Ä‚¢‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "E408: %s must be first in contains list"
+msgstr "E408: %s ‚Í“à—eƒŠƒXƒg‚Ìæ“ª‚łȂ¯‚ê‚΂Ȃç‚È‚¢"
+
+#, c-format
+msgid "E409: Unknown group name: %s"
+msgstr "E409: –¢’m‚̃Oƒ‹[ƒv–¼: %s"
+
+#, c-format
+msgid "E410: Invalid :syntax subcommand: %s"
+msgstr "E410: –³Œø‚È :syntax ‚̃TƒuƒRƒ}ƒ“ƒh: %s"
+
+msgid ""
+" TOTAL COUNT MATCH SLOWEST AVERAGE NAME PATTERN"
+msgstr ""
+" TOTAL COUNT MATCH SLOWEST AVERAGE NAME PATTERN"
+
+msgid "E679: recursive loop loading syncolor.vim"
+msgstr "E679: syncolor.vim ‚ÌÄ‹AŒÄ‚Ño‚µ‚ðŒŸo‚µ‚Ü‚µ‚½"
+
+#, c-format
+msgid "E411: highlight group not found: %s"
+msgstr "E411: ƒnƒCƒ‰ƒCƒgƒOƒ‹[ƒv‚ªŒ©‚‚©‚è‚Ü‚¹‚ñ: %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: ƒOƒ‹[ƒv‚ªÝ’肳‚ê‚Ä‚¢‚é‚̂ŃnƒCƒ‰ƒCƒgƒŠƒ“ƒN‚Í–³Ž‹‚³‚ê‚Ü‚·"
+
+#, 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³‚È’l‚Å‚·: %s"
+
+msgid "E419: FG color unknown"
+msgstr "E419: –¢’m‚Ì‘OŒiF‚Å‚·"
+
+msgid "E420: BG color unknown"
+msgstr "E420: –¢’m‚Ì”wŒiF‚Å‚·"
+
+#, c-format
+msgid "E421: Color name or number not recognized: %s"
+msgstr "E421: ƒJƒ‰[–¼‚â”Ô†‚ð”Fޝ‚Å‚«‚Ü‚¹‚ñ: %s"
+
+#, c-format
+msgid "E422: terminal code too long: %s"
+msgstr "E422: I’[ƒR[ƒh‚ª’·‰ß‚¬‚Ü‚·: %s"
+
+#, c-format
+msgid "E423: Illegal argument: %s"
+msgstr "E423: •s³‚Ȉø”‚Å‚·: %s"
+
+msgid "E424: Too many different highlighting attributes in use"
+msgstr "E424: ‘½‚­‚̈قȂéƒnƒCƒ‰ƒCƒg‘®«‚ªŽg‚í‚ê‰ß‚¬‚Ä‚¢‚Ü‚·"
+
+msgid "E669: Unprintable character in group name"
+msgstr "E669: ƒOƒ‹[ƒv–¼‚Ɉóü•s‰Â”\\‚È•¶Žš‚ª‚ ‚è‚Ü‚·"
+
+msgid "W18: Invalid character in group name"
+msgstr "W18: ƒOƒ‹[ƒv–¼‚É•s³‚È•¶Žš‚ª‚ ‚è‚Ü‚·"
+
+msgid "E849: Too many highlight and syntax groups"
+msgstr "E849: ƒnƒCƒ‰ƒCƒg‚Æ\\•¶ƒOƒ‹[ƒv‚ª‘½‰ß‚¬‚Ü‚·"
+
+msgid "E555: at bottom of tag stack"
+msgstr "E555: ƒ^ƒOƒXƒ^ƒbƒN‚Ì––”ö‚Å‚·"
+
+msgid "E556: at top of tag stack"
+msgstr "E556: ƒ^ƒOƒXƒ^ƒbƒN‚Ìæ“ª‚Å‚·"
+
+msgid "E425: Cannot go before first matching tag"
+msgstr "E425: ʼn‚ÌŠY“–ƒ^ƒO‚ð’´‚¦‚Ė߂邱‚Ƃ͂ł«‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "E426: tag not found: %s"
+msgstr "E426: ƒ^ƒO‚ªŒ©‚‚©‚è‚Ü‚¹‚ñ: %s"
+
+msgid " # pri kind tag"
+msgstr " # pri kind tag"
+
+msgid "file\n"
+msgstr "ƒtƒ@ƒCƒ‹\n"
+
+msgid "E427: There is only one matching tag"
+msgstr "E427: ŠY“–ƒ^ƒO‚ª1‚‚¾‚¯‚µ‚©‚ ‚è‚Ü‚¹‚ñ"
+
+msgid "E428: Cannot go beyond last matching tag"
+msgstr "E428: ÅŒã‚ÉŠY“–‚·‚éƒ^ƒO‚ð’´‚¦‚Äi‚Þ‚±‚Ƃ͂ł«‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "File \"%s\" does not exist"
+msgstr "ƒtƒ@ƒCƒ‹ \"%s\" ‚ª‚ ‚è‚Ü‚¹‚ñ"
+
+#. Give an indication of the number of matching tags
+#, c-format
+msgid "tag %d of %d%s"
+msgstr "ƒ^ƒO %d (‘S%d%s)"
+
+msgid " or more"
+msgstr " ‚©‚»‚êˆÈã"
+
+msgid " Using tag with different case!"
+msgstr " ƒ^ƒO‚ðˆÙ‚È‚écase‚ÅŽg—p‚µ‚Ü‚·!"
+
+#, c-format
+msgid "E429: File \"%s\" does not exist"
+msgstr "E429: ƒtƒ@ƒCƒ‹ \"%s\" ‚ª‚ ‚è‚Ü‚¹‚ñ"
+
+#. Highlight title
+msgid ""
+"\n"
+" # TO tag FROM line in file/text"
+msgstr ""
+"\n"
+" # TO ƒ^ƒO FROM s in file/text"
+
+#, c-format
+msgid "Searching tags file %s"
+msgstr "ƒ^ƒOƒtƒ@ƒCƒ‹ %s ‚ðŒŸõ’†"
+
+#, c-format
+msgid "E430: Tag file path truncated for %s\n"
+msgstr "E430: ƒ^ƒOƒtƒ@ƒCƒ‹‚̃pƒX‚ª %s ‚ÉØ‚èŽÌ‚Ä‚ç‚ê‚Ü‚µ‚½\n"
+
+msgid "Ignoring long line in tags file"
+msgstr "ƒ^ƒOƒtƒ@ƒCƒ‹“à‚Ì’·‚¢s‚𖳎‹‚µ‚Ü‚·"
+
+#, c-format
+msgid "E431: Format error in tags file \"%s\""
+msgstr "E431: ƒ^ƒOƒtƒ@ƒCƒ‹ \"%s\" ‚̃tƒH[ƒ}ƒbƒg‚ɃGƒ‰[‚ª‚ ‚è‚Ü‚·"
+
+#, c-format
+msgid "Before byte %ld"
+msgstr "’¼‘O‚Ì %ld ƒoƒCƒg"
+
+#, c-format
+msgid "E432: Tags file not sorted: %s"
+msgstr "E432: ƒ^ƒOƒtƒ@ƒCƒ‹‚ªƒ\\[ƒg‚³‚ê‚Ä‚¢‚Ü‚¹‚ñ: %s"
+
+#. never opened any tags file
+msgid "E433: No tags file"
+msgstr "E433: ƒ^ƒOƒtƒ@ƒCƒ‹‚ª‚ ‚è‚Ü‚¹‚ñ"
+
+msgid "E434: Can't find tag pattern"
+msgstr "E434: ƒ^ƒOƒpƒ^[ƒ“‚ðŒ©‚Â‚¯‚ç‚ê‚Ü‚¹‚ñ"
+
+msgid "E435: Couldn't find tag, just guessing!"
+msgstr "E435: ƒ^ƒO‚ðŒ©‚Â‚¯‚ç‚ê‚È‚¢‚̂ŒP‚É„‘ª‚µ‚Ü‚·!"
+
+#, c-format
+msgid "Duplicate field name: %s"
+msgstr "d•¡‚µ‚½ƒtƒB[ƒ‹ƒh–¼: %s"
+
+msgid "' not known. Available builtin terminals are:"
+msgstr "' ‚Í–¢’m‚Å‚·. Œ»s‚Ì‘g‚Ýž‚Ý’[––‚ÍŽŸ‚̂Ƃ¨‚è‚Å‚·:"
+
+msgid "defaulting to '"
+msgstr "È—ª’l‚ðŽŸ‚Ì‚æ‚¤‚Éݒ肵‚Ü‚· '"
+
+msgid "E557: Cannot open termcap file"
+msgstr "E557: termcapƒtƒ@ƒCƒ‹‚ðŠJ‚¯‚Ü‚¹‚ñ"
+
+msgid "E558: Terminal entry not found in terminfo"
+msgstr "E558: terminfo‚É’[––ƒGƒ“ƒgƒŠ‚ðŒ©‚Â‚¯‚ç‚ê‚Ü‚¹‚ñ"
+
+msgid "E559: Terminal entry not found in termcap"
+msgstr "E559: termcap‚É’[––ƒGƒ“ƒgƒŠ‚ðŒ©‚Â‚¯‚ç‚ê‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "E436: No \"%s\" entry in termcap"
+msgstr "E436: termcap‚É \"%s\" ‚̃Gƒ“ƒgƒŠ‚ª‚ ‚è‚Ü‚¹‚ñ"
+
+msgid "E437: terminal capability \"cm\" required"
+msgstr "E437: ’[––‚É \"cm\" ‹@”\\‚ª•K—v‚Å‚·"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Terminal keys ---"
+msgstr ""
+"\n"
+"--- ’[––ƒL[ ---"
+
+msgid "new shell started\n"
+msgstr "V‚µ‚¢ƒVƒFƒ‹‚ð‹N“®‚µ‚Ü‚·\n"
+
+msgid "Vim: Error reading input, exiting...\n"
+msgstr "Vim: “ü—Í‚ð“Çž‚Ý’†‚̃Gƒ‰[‚É‚æ‚èI—¹‚µ‚Ü‚·...\n"
+
+msgid "Used CUT_BUFFER0 instead of empty selection"
+msgstr "‹ó‚Ì‘I‘ð—̈æ‚Ì‚©‚í‚è‚ÉCUT_BUFFER0‚ªŽg—p‚³‚ê‚Ü‚µ‚½"
+
+#. This happens when the FileChangedRO autocommand changes the
+#. * file in a way it becomes shorter.
+msgid "E834: Line count changed unexpectedly"
+msgstr "E834: —\\Šú‚¹‚¸sƒJƒEƒ“ƒg‚ª•Ï‚í‚è‚Ü‚µ‚½"
+
+#. must display the prompt
+msgid "No undo possible; continue anyway"
+msgstr "‰Â”\\‚ȃAƒ“ƒhƒD‚Í‚ ‚è‚Ü‚¹‚ñ: ‚Ƃ肠‚¦‚¸‘±‚¯‚Ü‚·"
+
+#, c-format
+msgid "E828: Cannot open undo file for writing: %s"
+msgstr "E828: ‘ž‚Ý—p‚ɃAƒ“ƒhƒDƒtƒ@ƒCƒ‹‚ðŠJ‚¯‚Ü‚¹‚ñ: %s"
+
+#, c-format
+msgid "E825: Corrupted undo file (%s): %s"
+msgstr "E825: ƒAƒ“ƒhƒDƒtƒ@ƒCƒ‹‚ª‰ó‚ê‚Ä‚¢‚Ü‚· (%s): %s"
+
+msgid "Cannot write undo file in any directory in 'undodir'"
+msgstr "'undodir'‚̃fƒBƒŒƒNƒgƒŠ‚ɃAƒ“ƒhƒDƒtƒ@ƒCƒ‹‚ð‘‚«ž‚߂܂¹‚ñ"
+
+#, c-format
+msgid "Will not overwrite with undo file, cannot read: %s"
+msgstr "ƒAƒ“ƒhƒDƒtƒ@ƒCƒ‹‚Æ‚µ‚ēǂݞ‚߂Ȃ¢‚Ì‚Åã‘‚«‚µ‚Ü‚¹‚ñ: %s"
+
+#, c-format
+msgid "Will not overwrite, this is not an undo file: %s"
+msgstr "ƒAƒ“ƒhƒDƒtƒ@ƒCƒ‹‚ł͂Ȃ¢‚Ì‚Åã‘‚«‚µ‚Ü‚¹‚ñ: %s"
+
+msgid "Skipping undo file write, nothing to undo"
+msgstr "‘ÎÛ‚ª‚È‚¢‚̂ŃAƒ“ƒhƒDƒtƒ@ƒCƒ‹‚Ì‘‚«ž‚Ý‚ðƒXƒLƒbƒv‚µ‚Ü‚·"
+
+#, c-format
+msgid "Writing undo file: %s"
+msgstr "ƒAƒ“ƒhƒDƒtƒ@ƒCƒ‹‘‚«ž‚Ý’†: %s"
+
+#, c-format
+msgid "E829: write error in undo file: %s"
+msgstr "E829: ƒAƒ“ƒhƒDƒtƒ@ƒCƒ‹‚Ì‘‚«ž‚݃Gƒ‰[‚Å‚·: %s"
+
+#, c-format
+msgid "Not reading undo file, owner differs: %s"
+msgstr "ƒI[ƒi[‚ªˆÙ‚È‚é‚̂ŃAƒ“ƒhƒDƒtƒ@ƒCƒ‹‚ð“ǂݞ‚݂܂¹‚ñ: %s"
+
+#, c-format
+msgid "Reading undo file: %s"
+msgstr "ƒAƒ“ƒhƒDƒtƒ@ƒCƒ‹“Çž’†: %s"
+
+#, c-format
+msgid "E822: Cannot open undo file for reading: %s"
+msgstr "E822: ƒAƒ“ƒhƒDƒtƒ@ƒCƒ‹‚ð“Çž—p‚Æ‚µ‚ÄŠJ‚¯‚Ü‚¹‚ñ: %s"
+
+#, c-format
+msgid "E823: Not an undo file: %s"
+msgstr "E823: ƒAƒ“ƒhƒDƒtƒ@ƒCƒ‹‚ł͂ ‚è‚Ü‚¹‚ñ: %s"
+
+#, c-format
+msgid "E832: Non-encrypted file has encrypted undo file: %s"
+msgstr "E832: ”ñˆÃ†‰»ƒtƒ@ƒCƒ‹‚ªˆÃ†‰»‚³‚ꂽƒAƒ“ƒhƒDƒtƒ@ƒCƒ‹‚ðŽg‚Á‚Ă܂·: %s"
+
+#, c-format
+msgid "E826: Undo file decryption failed: %s"
+msgstr "E826: ˆÃ†‰»‚³‚ꂽƒAƒ“ƒhƒDƒtƒ@ƒCƒ‹‚̉ð“ǂɎ¸”s‚µ‚Ü‚µ‚½: %s"
+
+#, c-format
+msgid "E827: Undo file is encrypted: %s"
+msgstr "E827: ƒAƒ“ƒhƒDƒtƒ@ƒCƒ‹‚ªˆÃ†‰»‚³‚ê‚Ä‚¢‚Ü‚·: %s"
+
+#, c-format
+msgid "E824: Incompatible undo file: %s"
+msgstr "E824: ŒÝŠ·«‚Ì–³‚¢ƒAƒ“ƒhƒDƒtƒ@ƒCƒ‹‚Å‚·: %s"
+
+msgid "File contents changed, cannot use undo info"
+msgstr "ƒtƒ@ƒCƒ‹‚Ì“à—e‚ª•Ï‚í‚Á‚Ä‚¢‚邽‚ßAƒAƒ“ƒhƒDî•ñ‚ð—˜—p‚Å‚«‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "Finished reading undo file %s"
+msgstr "ƒAƒ“ƒhƒDƒtƒ@ƒCƒ‹ %s ‚ÌŽæž‚ðŠ®—¹"
+
+msgid "Already at oldest change"
+msgstr "Šù‚Ɉê”Ԍ¢•ÏX‚Å‚·"
+
+msgid "Already at newest change"
+msgstr "Šù‚Ɉê”ÔV‚µ‚¢•ÏX‚Å‚·"
+
+#, c-format
+msgid "E830: Undo number %ld not found"
+msgstr "E830: ƒAƒ“ƒhƒD”Ô† %ld ‚ÍŒ©‚‚©‚è‚Ü‚¹‚ñ"
+
+msgid "E438: u_undo: line numbers wrong"
+msgstr "E438: u_undo: s”Ô†‚ªŠÔˆá‚Á‚Ä‚¢‚Ü‚·"
+
+msgid "more line"
+msgstr "s ’ljÁ‚µ‚Ü‚µ‚½"
+
+msgid "more lines"
+msgstr "s ’ljÁ‚µ‚Ü‚µ‚½"
+
+msgid "line less"
+msgstr "s 휂µ‚Ü‚µ‚½"
+
+msgid "fewer lines"
+msgstr "s 휂µ‚Ü‚µ‚½"
+
+msgid "change"
+msgstr "‰ÓŠ•ÏX‚µ‚Ü‚µ‚½"
+
+msgid "changes"
+msgstr "‰ÓŠ•ÏX‚µ‚Ü‚µ‚½"
+
+#, c-format
+msgid "%ld %s; %s #%ld %s"
+msgstr "%ld %s; %s #%ld %s"
+
+msgid "before"
+msgstr "‘O•û"
+
+msgid "after"
+msgstr "Œã•û"
+
+msgid "Nothing to undo"
+msgstr "ƒAƒ“ƒhƒD‘ÎÛ‚ª‚ ‚è‚Ü‚¹‚ñ"
+
+msgid "number changes when saved"
+msgstr "’Ê”Ô •ÏX” •ÏXŽžŠú •Û‘¶Ï"
+
+#, c-format
+msgid "%ld seconds ago"
+msgstr "%ld •bŒo‰ß‚µ‚Ä‚¢‚Ü‚·"
+
+msgid "E790: undojoin is not allowed after undo"
+msgstr "E790: undo ‚Ì’¼Œã‚É undojoin ‚͂ł«‚Ü‚¹‚ñ"
+
+msgid "E439: undo list corrupt"
+msgstr "E439: ƒAƒ“ƒhƒDƒŠƒXƒg‚ª‰ó‚ê‚Ä‚¢‚Ü‚·"
+
+msgid "E440: undo line missing"
+msgstr "E440: ƒAƒ“ƒhƒDs‚ª‚ ‚è‚Ü‚¹‚ñ"
+
+#. Only MS VC 4.1 and earlier can do Win32s
+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"
+"Included patches: "
+msgstr ""
+"\n"
+"“K—pσpƒbƒ`: "
+
+msgid ""
+"\n"
+"Extra patches: "
+msgstr ""
+"\n"
+"’ljÁŠg’£ƒpƒbƒ`: "
+
+msgid "Modified by "
+msgstr "Modified by "
+
+msgid ""
+"\n"
+"Compiled "
+msgstr ""
+"\n"
+"Compiled "
+
+msgid "by "
+msgstr "by "
+
+msgid ""
+"\n"
+"Huge version "
+msgstr ""
+"\n"
+"Huge Ӂ "
+
+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."
+
+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 " Features included (+) or not (-):\n"
+msgstr " ‹@”\\‚̈ꗗ —LŒø(+)/–³Œø(-)\n"
+
+msgid " system vimrc file: \""
+msgstr " ƒVƒXƒeƒ€ vimrc: \""
+
+msgid " user vimrc file: \""
+msgstr " ƒ†[ƒU vimrc: \""
+
+msgid " 2nd user vimrc file: \""
+msgstr " ‘æ2ƒ†[ƒU vimrc: \""
+
+msgid " 3rd user vimrc file: \""
+msgstr " ‘æ3ƒ†[ƒU vimrc: \""
+
+msgid " user exrc file: \""
+msgstr " ƒ†[ƒU exrc: \""
+
+msgid " 2nd user exrc file: \""
+msgstr " ‘æ2ƒ†[ƒU exrc: \""
+
+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 " fall-back for $VIM: \""
+msgstr " È—ªŽž‚Ì $VIM: \""
+
+msgid " f-b for $VIMRUNTIME: \""
+msgstr "È—ªŽž‚Ì $VIMRUNTIME: \""
+
+msgid "Compilation: "
+msgstr "ƒRƒ“ƒpƒCƒ‹: "
+
+msgid "Compiler: "
+msgstr "ƒRƒ“ƒpƒCƒ‰: "
+
+msgid "Linking: "
+msgstr "ƒŠƒ“ƒN: "
+
+msgid " DEBUG BUILD"
+msgstr "ƒfƒoƒbƒOƒrƒ‹ƒh"
+
+msgid "VIM - Vi IMproved"
+msgstr "VIM - Vi IMproved"
+
+msgid "version "
+msgstr "version "
+
+msgid "by Bram Moolenaar et al."
+msgstr "by Bram Moolenaar ‘¼."
+
+msgid "Vim is open source and freely distributable"
+msgstr "Vim ‚̓I[ƒvƒ“ƒ\\[ƒX‚Å‚ ‚莩—R‚É”z•z‰Â”\\‚Å‚·"
+
+msgid "Help poor children in Uganda!"
+msgstr "ƒEƒKƒ“ƒ_‚ÌŒb‚Ü‚ê‚È‚¢Žq‹Ÿ‚½‚¿‚ɉ‡•‚ð!"
+
+msgid "type :help iccf<Enter> for information "
+msgstr "ÚׂÈî•ñ‚Í :help iccf<Enter> "
+
+msgid "type :q<Enter> to exit "
+msgstr "I—¹‚·‚é‚É‚Í :q<Enter> "
+
+msgid "type :help<Enter> or <F1> for on-line help"
+msgstr "ƒIƒ“ƒ‰ƒCƒ“ƒwƒ‹ƒv‚Í :help<Enter> ‚© <F1> "
+
+msgid "type :help version7<Enter> for version info"
+msgstr "ƒo[ƒWƒ‡ƒ“î•ñ‚Í :help version7<Enter> "
+
+msgid "Running in Vi compatible mode"
+msgstr "ViŒÝŠ·ƒ‚[ƒh‚Å“®ì’†"
+
+msgid "type :set nocp<Enter> for Vim defaults"
+msgstr "Vim„§’l‚É‚·‚é‚É‚Í :set nocp<Enter> "
+
+msgid "type :help cp-default<Enter> for info on this"
+msgstr "ÚׂÈî•ñ‚Í :help cp-default<Enter>"
+
+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 "Sponsor Vim development!"
+msgstr "Vim‚ÌŠJ”­‚ð‰ž‰‡‚µ‚Ä‚­‚¾‚³‚¢!"
+
+msgid "Become a registered Vim user!"
+msgstr "Vim‚Ì“o˜^ƒ†[ƒU‚ɂȂÁ‚Ä‚­‚¾‚³‚¢!"
+
+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 "Úׂ̓ƒjƒ…[‚Ì ƒwƒ‹ƒv¨ƒXƒ|ƒ“ƒT[/“o˜^ ‚ðŽQÆ‚µ‚ĉº‚³‚¢ "
+
+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 "Already only one window"
+msgstr "Šù‚ɃEƒBƒ“ƒhƒE‚Í1‚‚µ‚©‚ ‚è‚Ü‚¹‚ñ"
+
+msgid "E441: There is no preview window"
+msgstr "E441: ƒvƒŒƒrƒ…[ƒEƒBƒ“ƒhƒE‚ª‚ ‚è‚Ü‚¹‚ñ"
+
+msgid "E442: Can't split topleft and botright at the same time"
+msgstr "E442: ¶ã‚ƉE‰º‚𓯎ž‚É•ªŠ„‚·‚邱‚Ƃ͂ł«‚Ü‚¹‚ñ"
+
+msgid "E443: Cannot rotate when another window is split"
+msgstr "E443: ‘¼‚̃EƒBƒ“ƒhƒE‚ª•ªŠ„‚³‚ê‚Ä‚¢‚鎞‚ɂ͇‰ñ‚Å‚«‚Ü‚¹‚ñ"
+
+msgid "E444: Cannot close last window"
+msgstr "E444: ÅŒã‚̃EƒBƒ“ƒhƒE‚ð•‚¶‚邱‚Ƃ͂ł«‚Ü‚¹‚ñ"
+
+msgid "E813: Cannot close autocmd window"
+msgstr "E813: autocmdƒEƒBƒ“ƒhƒE‚͕‚¶‚ç‚ê‚Ü‚¹‚ñ"
+
+msgid "E814: Cannot close window, only autocmd window would remain"
+msgstr "E814: autocmdƒEƒBƒ“ƒhƒE‚µ‚©Žc‚ç‚È‚¢‚½‚ßAƒEƒBƒ“ƒhƒE‚͕‚¶‚ç‚ê‚Ü‚¹‚ñ"
+
+msgid "E445: Other window contains changes"
+msgstr "E445: ‘¼‚̃EƒBƒ“ƒhƒE‚ɂ͕ÏX‚ª‚ ‚è‚Ü‚·"
+
+msgid "E446: No file name under cursor"
+msgstr "E446: ƒJ[ƒ\\ƒ‹‚̉º‚Ƀtƒ@ƒCƒ‹–¼‚ª‚ ‚è‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "E447: Can't find file \"%s\" in path"
+msgstr "E447: path‚É‚Í \"%s\" ‚Æ‚¢‚¤ƒtƒ@ƒCƒ‹‚ª‚ ‚è‚Ü‚¹‚ñ"
+
+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)"
+
+#. Now concatenate
+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 "--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.
+#.
+msgid "E470: Command aborted"
+msgstr "E470: ƒRƒ}ƒ“ƒh‚ª’†’f‚³‚ê‚Ü‚µ‚½"
+
+msgid "E471: Argument required"
+msgstr "E471: ˆø”‚ª•K—v‚Å‚·"
+
+msgid "E10: \\ should be followed by /, ? or &"
+msgstr "E10: \\ ‚ÌŒã‚Í / ‚© ? ‚© & ‚łȂ¯‚ê‚΂Ȃè‚Ü‚¹‚ñ"
+
+msgid "E11: Invalid in command-line window; <CR> executes, CTRL-C quits"
+msgstr "E11: ƒRƒ}ƒ“ƒhƒ‰ƒCƒ“‚ł͖³Œø‚Å‚·; <CR>‚ÅŽÀs, CTRL-C‚Å‚â‚ß‚é"
+
+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‚Í‹–‰Â‚³‚ê‚Ü‚¹‚ñ"
+
+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: :while ‚̂Ȃ¢ :endwhile ‚ª‚ ‚è‚Ü‚·"
+
+msgid "E588: :endfor without :for"
+msgstr "E588: :endfor ‚̂Ȃ¢ :for ‚ª‚ ‚è‚Ü‚·"
+
+msgid "E13: File exists (add ! to override)"
+msgstr "E13: ƒtƒ@ƒCƒ‹‚ª‘¶Ý‚µ‚Ü‚· (! ‚ð’ljÁ‚Åã‘)"
+
+msgid "E472: Command failed"
+msgstr "E472: ƒRƒ}ƒ“ƒh‚ªŽ¸”s‚µ‚Ü‚µ‚½"
+
+#, c-format
+msgid "E234: Unknown fontset: %s"
+msgstr "E234: –¢’m‚̃tƒHƒ“ƒgƒZƒbƒg: %s"
+
+#, c-format
+msgid "E235: Unknown font: %s"
+msgstr "E235: –¢’m‚̃tƒHƒ“ƒg: %s"
+
+#, c-format
+msgid "E236: Font \"%s\" is not fixed-width"
+msgstr "E236: ƒtƒHƒ“ƒg \"%s\" ‚͌Œ蕂ł͂ ‚è‚Ü‚¹‚ñ"
+
+msgid "E473: Internal error"
+msgstr "E473: “à•”ƒGƒ‰[‚Å‚·"
+
+msgid "Interrupted"
+msgstr "Š„ž‚Ü‚ê‚Ü‚µ‚½"
+
+msgid "E14: Invalid address"
+msgstr "E14: –³Œø‚ȃAƒhƒŒƒX‚Å‚·"
+
+msgid "E474: Invalid argument"
+msgstr "E474: –³Œø‚Ȉø”‚Å‚·"
+
+#, c-format
+msgid "E475: Invalid argument: %s"
+msgstr "E475: –³Œø‚Ȉø”‚Å‚·: %s"
+
+#, c-format
+msgid "E15: Invalid expression: %s"
+msgstr "E15: –³Œø‚ÈŽ®‚Å‚·: %s"
+
+msgid "E16: Invalid range"
+msgstr "E16: –³Œø‚Ȕ͈͂ł·"
+
+msgid "E476: Invalid command"
+msgstr "E476: –³Œø‚ȃRƒ}ƒ“ƒh‚Å‚·"
+
+#, c-format
+msgid "E17: \"%s\" is a directory"
+msgstr "E17: \"%s\" ‚̓fƒBƒŒƒNƒgƒŠ‚Å‚·"
+
+#, c-format
+msgid "E364: Library call failed for \"%s()\""
+msgstr "E364: \"%s\"() ‚̃‰ƒCƒuƒ‰ƒŠŒÄo‚ÉŽ¸”s‚µ‚Ü‚µ‚½"
+
+#, c-format
+msgid "E448: Could not load library function %s"
+msgstr "E448: ƒ‰ƒCƒuƒ‰ƒŠ‚ÌŠÖ” %s ‚ðƒ[ƒh‚Å‚«‚Ü‚¹‚ñ‚Å‚µ‚½"
+
+msgid "E19: Mark has invalid line number"
+msgstr "E19: ƒ}[ƒN‚É–³Œø‚Ès”Ô†‚ªŽw’肳‚ê‚Ä‚¢‚Ü‚µ‚½"
+
+msgid "E20: Mark not set"
+msgstr "E20: ƒ}[ƒN‚Íݒ肳‚ê‚Ä‚¢‚Ü‚¹‚ñ"
+
+msgid "E21: Cannot make changes, 'modifiable' is off"
+msgstr "E21: 'modifiable' ‚ªƒIƒt‚Ȃ̂Å, •ÏX‚Å‚«‚Ü‚¹‚ñ"
+
+msgid "E22: Scripts nested too deep"
+msgstr "E22: ƒXƒNƒŠƒvƒg‚Ì“ü‚êŽq‚ª[‰ß‚¬‚Ü‚·"
+
+msgid "E23: No alternate file"
+msgstr "E23: •›ƒtƒ@ƒCƒ‹‚Í‚ ‚è‚Ü‚¹‚ñ"
+
+msgid "E24: No such abbreviation"
+msgstr "E24: ‚»‚̂悤‚È’Zk“ü—͂͂ ‚è‚Ü‚¹‚ñ"
+
+msgid "E477: No ! allowed"
+msgstr "E477: ! ‚Í‹–‰Â‚³‚ê‚Ä‚¢‚Ü‚¹‚ñ"
+
+msgid "E25: GUI cannot be used: Not enabled at compile time"
+msgstr "E25: GUI‚ÍŽg—p•s‰Â”\\‚Å‚·: ƒRƒ“ƒpƒCƒ‹Žž‚É–³Œø‚É‚³‚ê‚Ä‚¢‚Ü‚·"
+
+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"
+
+#, c-format
+msgid "E28: No such highlight group name: %s"
+msgstr "E28: ‚»‚̂悤‚È–¼‚̃nƒCƒ‰ƒCƒgƒOƒ‹[ƒv‚Í‚ ‚è‚Ü‚¹‚ñ: %s"
+
+msgid "E29: No inserted text yet"
+msgstr "E29: ‚Ü‚¾ƒeƒLƒXƒg‚ª‘}“ü‚³‚ê‚Ä‚¢‚Ü‚¹‚ñ"
+
+msgid "E30: No previous command line"
+msgstr "E30: ˆÈ‘O‚ɃRƒ}ƒ“ƒhs‚ª‚ ‚è‚Ü‚¹‚ñ"
+
+msgid "E31: No such mapping"
+msgstr "E31: ‚»‚̂悤‚ȃ}ƒbƒsƒ“ƒO‚Í‚ ‚è‚Ü‚¹‚ñ"
+
+msgid "E479: No match"
+msgstr "E479: ŠY“–‚Í‚ ‚è‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "E480: No match: %s"
+msgstr "E480: ŠY“–‚Í‚ ‚è‚Ü‚¹‚ñ: %s"
+
+msgid "E32: No file name"
+msgstr "E32: ƒtƒ@ƒCƒ‹–¼‚ª‚ ‚è‚Ü‚¹‚ñ"
+
+msgid "E33: No previous substitute regular expression"
+msgstr "E33: ³‹K•\\Œ»’uŠ·‚ª‚Ü‚¾ŽÀs‚³‚ê‚Ä‚¢‚Ü‚¹‚ñ"
+
+msgid "E34: No previous command"
+msgstr "E34: ƒRƒ}ƒ“ƒh‚ª‚Ü‚¾ŽÀs‚³‚ê‚Ä‚¢‚Ü‚¹‚ñ"
+
+msgid "E35: No previous regular expression"
+msgstr "E35: ³‹K•\\Œ»‚ª‚Ü‚¾ŽÀs‚³‚ê‚Ä‚¢‚Ü‚¹‚ñ"
+
+msgid "E481: No range allowed"
+msgstr "E481: ”͈͎w’è‚Í‹–‰Â‚³‚ê‚Ä‚¢‚Ü‚¹‚ñ"
+
+msgid "E36: Not enough room"
+msgstr "E36: ƒEƒBƒ“ƒhƒE‚É\\•ª‚È‚‚³‚à‚µ‚­‚Í•‚ª‚ ‚è‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "E247: no registered server named \"%s\""
+msgstr "E247: %s ‚Æ‚¢‚¤–¼‘O‚Ì“o˜^‚³‚ꂽƒT[ƒo‚Í‚ ‚è‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "E482: Can't create file %s"
+msgstr "E482: ƒtƒ@ƒCƒ‹ %s ‚ð쬂ł«‚Ü‚¹‚ñ"
+
+msgid "E483: Can't get temp file name"
+msgstr "E483: ˆêŽžƒtƒ@ƒCƒ‹‚Ì–¼‘O‚ðŽæ“¾‚Å‚«‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "E484: Can't open file %s"
+msgstr "E484: ƒtƒ@ƒCƒ‹ \"%s\" ‚ðŠJ‚¯‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "E485: Can't read file %s"
+msgstr "E485: ƒtƒ@ƒCƒ‹ %s ‚ð“Çž‚߂܂¹‚ñ"
+
+msgid "E37: No write since last change (add ! to override)"
+msgstr "E37: ÅŒã‚Ì•ÏX‚ª•Û‘¶‚³‚ê‚Ä‚¢‚Ü‚¹‚ñ (! ‚ð’ljÁ‚Å•ÏX‚ð”jŠü)"
+
+msgid "E38: Null argument"
+msgstr "E38: ˆø”‚ª‹ó‚Å‚·"
+
+msgid "E39: Number expected"
+msgstr "E39: ”’l‚ª—v‹‚³‚ê‚Ä‚¢‚Ü‚·"
+
+#, c-format
+msgid "E40: Can't open errorfile %s"
+msgstr "E40: ƒGƒ‰[ƒtƒ@ƒCƒ‹ %s ‚ðŠJ‚¯‚Ü‚¹‚ñ"
+
+msgid "E233: cannot open display"
+msgstr "E233: ƒfƒBƒXƒvƒŒƒC‚ðŠJ‚¯‚Ü‚¹‚ñ"
+
+msgid "E41: Out of memory!"
+msgstr "E41: ƒƒ‚ƒŠ‚ªs‚«‰Ê‚Ă܂µ‚½!"
+
+msgid "Pattern not found"
+msgstr "ƒpƒ^[ƒ“‚ÍŒ©‚‚©‚è‚Ü‚¹‚ñ‚Å‚µ‚½"
+
+#, c-format
+msgid "E486: Pattern not found: %s"
+msgstr "E486: ƒpƒ^[ƒ“‚ÍŒ©‚‚©‚è‚Ü‚¹‚ñ‚Å‚µ‚½: %s"
+
+msgid "E487: Argument must be positive"
+msgstr "E487: ˆø”‚ͳ‚Ì’l‚łȂ¯‚ê‚΂Ȃè‚Ü‚¹‚ñ"
+
+msgid "E459: Cannot go back to previous directory"
+msgstr "E459: ‘O‚̃fƒBƒŒƒNƒgƒŠ‚É–ß‚ê‚Ü‚¹‚ñ"
+
+msgid "E42: No Errors"
+msgstr "E42: ƒGƒ‰[‚Í‚ ‚è‚Ü‚¹‚ñ"
+
+msgid "E776: No location list"
+msgstr "E776: êŠƒŠƒXƒg‚Í‚ ‚è‚Ü‚¹‚ñ"
+
+msgid "E43: Damaged match string"
+msgstr "E43: ŠY“–•¶Žš—ñ‚ª”j‘¹‚µ‚Ä‚¢‚Ü‚·"
+
+msgid "E44: Corrupted regexp program"
+msgstr "E44: •s³‚ȳ‹K•\\Œ»ƒvƒƒOƒ‰ƒ€‚Å‚·"
+
+msgid "E45: 'readonly' option is set (add ! to override)"
+msgstr "E45: 'readonly' ƒIƒvƒVƒ‡ƒ“‚ªÝ’肳‚ê‚Ä‚¢‚Ü‚· (! ‚ð’ljÁ‚Åã‘‚«)"
+
+#, c-format
+msgid "E46: Cannot change read-only variable \"%s\""
+msgstr "E46: “ÇŽæê—p•Ï” \"%s\" ‚ɂ͒l‚ðÝ’è‚Å‚«‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "E794: Cannot set variable in the sandbox: \"%s\""
+msgstr "E794: ƒTƒ“ƒhƒ{ƒbƒNƒX‚ł͕ϔ \"%s\" ‚É’l‚ðÝ’è‚Å‚«‚Ü‚¹‚ñ"
+
+msgid "E47: Error while reading errorfile"
+msgstr "E47: ƒGƒ‰[ƒtƒ@ƒCƒ‹‚̓Ǟ’†‚ɃGƒ‰[‚ª”­¶‚µ‚Ü‚µ‚½"
+
+msgid "E48: Not allowed in sandbox"
+msgstr "E48: ƒTƒ“ƒhƒ{ƒbƒNƒX‚ł͋–‚³‚ê‚Ü‚¹‚ñ"
+
+msgid "E523: Not allowed here"
+msgstr "E523: ‚±‚±‚ł͋–‰Â‚³‚ê‚Ü‚¹‚ñ"
+
+msgid "E359: Screen mode setting not supported"
+msgstr "E359: ƒXƒNƒŠ[ƒ“ƒ‚[ƒh‚ÌÝ’è‚ɂ͑Ήž‚µ‚Ä‚¢‚Ü‚¹‚ñ"
+
+msgid "E49: Invalid scroll size"
+msgstr "E49: –³Œø‚ȃXƒNƒ[ƒ‹—ʂł·"
+
+msgid "E91: 'shell' option is empty"
+msgstr "E91: 'shell' ƒIƒvƒVƒ‡ƒ“‚ª‹ó‚Å‚·"
+
+msgid "E255: Couldn't read in sign data!"
+msgstr "E255: sign ‚̃f[ƒ^‚ð“Çž‚߂܂¹‚ñ‚Å‚µ‚½"
+
+msgid "E72: Close error on swap file"
+msgstr "E72: ƒXƒƒbƒvƒtƒ@ƒCƒ‹‚̃Nƒ[ƒYŽžƒGƒ‰[‚Å‚·"
+
+msgid "E73: tag stack empty"
+msgstr "E73: ƒ^ƒOƒXƒ^ƒbƒN‚ª‹ó‚Å‚·"
+
+msgid "E74: Command too complex"
+msgstr "E74: ƒRƒ}ƒ“ƒh‚ª•¡ŽG‰ß‚¬‚Ü‚·"
+
+msgid "E75: Name too long"
+msgstr "E75: –¼‘O‚ª’·‰ß‚¬‚Ü‚·"
+
+msgid "E76: Too many ["
+msgstr "E76: [ ‚ª‘½‰ß‚¬‚Ü‚·"
+
+msgid "E77: Too many file names"
+msgstr "E77: ƒtƒ@ƒCƒ‹–¼‚ª‘½‰ß‚¬‚Ü‚·"
+
+msgid "E488: Trailing characters"
+msgstr "E488: —]•ª‚È•¶Žš‚ªŒã‚ë‚É‚ ‚è‚Ü‚·"
+
+msgid "E78: Unknown mark"
+msgstr "E78: –¢’m‚̃}[ƒN"
+
+msgid "E79: Cannot expand wildcards"
+msgstr "E79: ƒƒCƒ‹ƒhƒJ[ƒh‚ð“WŠJ‚Å‚«‚Ü‚¹‚ñ"
+
+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: ‘ž‚Ý’†‚̃Gƒ‰["
+
+msgid "Zero count"
+msgstr "ƒ[ƒƒJƒEƒ“ƒg"
+
+msgid "E81: Using <SID> not in a script context"
+msgstr "E81: ƒXƒNƒŠƒvƒgˆÈŠO‚Å<SID>‚ªŽg‚í‚ê‚Ü‚µ‚½"
+
+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‚·‚邱‚Æ‚ð‹–‚µ‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "E685: Internal error: %s"
+msgstr "E685: “à•”ƒGƒ‰[‚Å‚·: %s"
+
+msgid "E363: pattern uses more memory than 'maxmempattern'"
+msgstr "E363: ƒpƒ^[ƒ“‚ª 'maxmempattern' ˆÈã‚̃ƒ‚ƒŠ‚ðŽg—p‚µ‚Ü‚·"
+
+msgid "E749: empty buffer"
+msgstr "E749: ƒoƒbƒtƒ@‚ª‹ó‚Å‚·"
+
+msgid "E682: Invalid search pattern or delimiter"
+msgstr "E682: ŒŸõƒpƒ^[ƒ“‚©‹æØ‚è‹L†‚ª•s³‚Å‚·"
+
+msgid "E139: File is loaded in another buffer"
+msgstr "E139: “¯‚¶–¼‘O‚̃tƒ@ƒCƒ‹‚ª‘¼‚̃oƒbƒtƒ@‚œǞ‚Ü‚ê‚Ä‚¢‚Ü‚·"
+
+#, c-format
+msgid "E764: Option '%s' is not set"
+msgstr "E764: ƒIƒvƒVƒ‡ƒ“ '%s' ‚Íݒ肳‚ê‚Ä‚¢‚Ü‚¹‚ñ"
+
+msgid "E850: Invalid register name"
+msgstr "E850: –³Œø‚ȃŒƒWƒXƒ^–¼‚Å‚·"
+
+msgid "search hit TOP, continuing at BOTTOM"
+msgstr "ã‚܂ŌŸõ‚µ‚½‚̂ʼnº‚É–ß‚è‚Ü‚·"
+
+msgid "search hit BOTTOM, continuing at TOP"
+msgstr "‰º‚܂ŌŸõ‚µ‚½‚Ì‚Åã‚É–ß‚è‚Ü‚·"
+
+#, c-format
+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‚³‚ê‚Ä‚¢‚Ü‚·"
+
+#, c-format
+msgid "failed to add key '%s' to dictionary"
+msgstr "Ž«‘‚ɃL[ '%s' ‚ð’ljÁ‚·‚é‚̂Ɏ¸”s‚µ‚Ü‚µ‚½"
+
+#, c-format
+msgid "index must be int or slice, not %s"
+msgstr "ƒCƒ“ƒfƒbƒNƒX‚Í %s ‚ł͂Ȃ­®”‚©ƒXƒ‰ƒCƒX‚É‚µ‚Ä‚­‚¾‚³‚¢"
+
+#, c-format
+msgid "expected str() or unicode() instance, but got %s"
+msgstr "str() ‚à‚µ‚­‚Í unicode() ‚̃Cƒ“ƒXƒ^ƒ“ƒX‚ªŠú‘Ò‚³‚ê‚Ä‚¢‚é‚Ì‚É %s ‚Å‚µ‚½"
+
+#, c-format
+msgid "expected bytes() or str() instance, but got %s"
+msgstr "bytes() ‚à‚µ‚­‚Í str() ‚̃Cƒ“ƒXƒ^ƒ“ƒX‚ªŠú‘Ò‚³‚ê‚Ä‚¢‚é‚Ì‚É %s ‚Å‚µ‚½"
+
+#, c-format
+msgid ""
+"expected int(), long() or something supporting coercing to long(), but got %s"
+msgstr "long() ‚©‚»‚ê‚Ö•ÏŠ·‰Â”\\‚È‚à‚Ì‚ªŠú‘Ò‚³‚ê‚Ä‚¢‚é‚Ì‚É %s ‚Å‚µ‚½"
+
+#, c-format
+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‘®«‚ðÁ‚¹‚Ü‚¹‚ñ"
+
+#, c-format
+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‚µ‚Ü‚µ‚½"
+
+#, c-format
+msgid "expected 3-tuple as imp.find_module() result, but got %s"
+msgstr "imp.find_module() ‚ª %s ‚ð•Ô‚µ‚Ü‚µ‚½ (Šú‘Ò’l: 2 —v‘f‚̃^ƒvƒ‹)"
+
+#, c-format
+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‚Å‚«‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "cannot set attribute %s"
+msgstr "‘®« %s ‚ÍÝ’è‚Å‚«‚Ü‚¹‚ñ"
+
+msgid "hashtab changed during iteration"
+msgstr "ƒCƒeƒŒ[ƒVƒ‡ƒ“’†‚É hashtab ‚ª•ÏX‚³‚ê‚Ü‚µ‚½"
+
+#, c-format
+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‚Å‚·"
+
+#. No more suitable format specifications in python-2.3
+#, c-format
+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‚µ‚Ü‚µ‚½"
+
+#, c-format
+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‚Å‚«‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "unnamed function %s does not exist"
+msgstr "–³–¼ŠÖ” %s ‚Í‘¶Ý‚µ‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "function %s does not exist"
+msgstr "ŠÖ” %s ‚ª‚ ‚è‚Ü‚¹‚ñ"
+
+msgid "function constructor does not accept keyword arguments"
+msgstr "ŠÖ”‚̃Rƒ“ƒXƒgƒ‰ƒNƒ^‚̓L[ƒ[ƒhˆø”‚ðŽó‚¯•t‚¯‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "failed to run function %s"
+msgstr "ŠÖ” %s ‚ÌŽÀs‚ÉŽ¸”s‚µ‚Ü‚µ‚½"
+
+msgid "unable to get option value"
+msgstr "ƒIƒvƒVƒ‡ƒ“‚Ì’l‚͎擾‚Å‚«‚Ü‚¹‚ñ"
+
+msgid "internal error: unknown option type"
+msgstr "“à•”ƒGƒ‰[: –¢’m‚̃IƒvƒVƒ‡ƒ“Œ^‚Å‚·"
+
+msgid "problem while switching windows"
+msgstr "ƒEƒBƒ“ƒhƒE‚ðØŠ·’†‚É–â‘肪”­¶‚µ‚Ü‚µ‚½"
+
+#, c-format
+msgid "unable to unset global option %s"
+msgstr "ƒOƒ[ƒoƒ‹ƒIƒvƒVƒ‡ƒ“ %s ‚ÌÝ’è‰ðœ‚͂ł«‚Ü‚¹‚ñ"
+
+#, c-format
+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‚łȂ¯‚ê‚΂Ȃè‚Ü‚¹‚ñ"
+
+#, c-format
+msgid "expected vim.Buffer object, but got %s"
+msgstr "vim.BufferƒIƒuƒWƒFƒNƒg‚ªŠú‘Ò‚³‚ê‚Ä‚¢‚é‚Ì‚É %s ‚Å‚µ‚½"
+
+#, c-format
+msgid "failed to switch to buffer %d"
+msgstr "Žw’肳‚ꂽƒoƒbƒtƒ@ %d ‚Ö‚ÌØ‚è‘Ö‚¦‚ÉŽ¸”s‚µ‚Ü‚µ‚½"
+
+#, c-format
+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‚ÉØ‚è‘Ö‚¦‚Ü‚¹‚ñ‚Å‚µ‚½"
+
+#, c-format
+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‚ɕϊ·‚Å‚«‚Ü‚¹‚ñ‚Å‚µ‚½"
+
+#, c-format
+msgid "unable to convert %s to vim dictionary"
+msgstr "%s vim‚ÌŽ«‘Œ^‚ɕϊ·‚Å‚«‚Ü‚¹‚ñ"
+
+#, c-format
+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/po/ko.UTF-8.po b/src/po/ko.UTF-8.po
new file mode 100644
index 0000000000..3da9a185c7
--- /dev/null
+++ b/src/po/ko.UTF-8.po
@@ -0,0 +1,6447 @@
+# Korean translation for Vim
+#
+# FIRST AUTHOR SungHyun Nam <goweol@gmail.com>, 2000-2011
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: vim 7.3\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2011-02-16 16:18+0900\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"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\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 use wrong"
+
+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 "E82: Cannot allocate any buffer, exiting..."
+msgstr "E82: 버í¼ë¥¼ 할당할 수 없어서 ë냅니다..."
+
+msgid "E83: Cannot allocate buffer, using other one..."
+msgstr "E83: 버í¼ë¥¼ 할당할 수 없어서 다른 걸 사용합니다..."
+
+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 "ë²„í¼ í•œ 개가 내려졌습니다"
+
+#, c-format
+msgid "%d buffers unloaded"
+msgstr "ë²„í¼ %d 개가 내려졌습니다"
+
+msgid "1 buffer deleted"
+msgstr "ë²„í¼ í•œ 개가 지워졌습니다"
+
+#, c-format
+msgid "%d buffers deleted"
+msgstr "ë²„í¼ %d 개가 지워졌습니다"
+
+msgid "1 buffer wiped out"
+msgstr "ë²„í¼ í•œ 개가 완전히 지워졌습니다"
+
+#, c-format
+msgid "%d buffers wiped out"
+msgstr "ë²„í¼ %d개가 완전히 지워졌습니다"
+
+msgid "E84: No modified buffer found"
+msgstr "E84: ë°”ë€ ë²„í¼ë¥¼ ì°¾ì„ ìˆ˜ 없습니다"
+
+#. back where we started, didn't find anything.
+msgid "E85: There is no listed buffer"
+msgstr "E85: ë‚˜ì—´ëœ ë²„í¼ê°€ 없습니다"
+
+#, c-format
+msgid "E86: Buffer %ld does not exist"
+msgstr "E86: ë²„í¼ %ldì´(ê°€) 존재하지 않습니다"
+
+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 "E90: Cannot unload last buffer"
+msgstr "E90: 마지막 버í¼ë¥¼ 내릴 수 없습니다"
+
+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 "[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 "[ì´ë¦„ ì—†ìŒ]"
+
+#. must be a help buffer
+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 "[Scratch]"
+msgstr "[Scratch]"
+
+msgid ""
+"\n"
+"--- Signs ---"
+msgstr ""
+"\n"
+"--- 기호 ---"
+
+#, c-format
+msgid "Signs for %s:"
+msgstr "%sì— ëŒ€í•œ 기호:"
+
+#, c-format
+msgid " line=%ld id=%d name=%s"
+msgstr " 줄=%ld id=%d ì´ë¦„=%s"
+
+#, c-format
+msgid "E96: Can not diff more than %ld buffers"
+msgstr "E96: %ldê°œ ì´ìƒì˜ 버í¼ì— 대해서는 diff를 í•  수 없습니다"
+
+msgid "E810: Cannot read or write temp files"
+msgstr "E810: 임시 파ì¼ì„ ì½ê±°ë‚˜ 쓸 수 없습니다"
+
+msgid "E97: Cannot create diffs"
+msgstr "E97: diff를 만들 수 없습니다"
+
+msgid "Patch file"
+msgstr "패키 파ì¼"
+
+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: digraphì—는 Escapeì„ ì“¸ 수 없습니다"
+
+msgid "E544: Keymap file not found"
+msgstr "E544: 키맵 파ì¼ì„ ì°¾ì„ ìˆ˜ 없습니다"
+
+msgid "E105: Using :loadkeymap not in a sourced file"
+msgstr "E105: ë¶ˆëŸ¬ë“¤ì¸ íŒŒì¼ì—서 :loadkeymapì„ ì‚¬ìš©í•˜ì§€ 않았습니다"
+
+msgid "E791: Empty keymap entry"
+msgstr "E791: 키맵 엔트리가 비어있ìŒ"
+
+msgid " Keyword completion (^N^P)"
+msgstr " ë‚±ë§ ì™„ì„± (^N^P)"
+
+#. ctrl_x_mode == 0, ^P/^N compl.
+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 " Dictionary 완성 (^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: Completion ê¸°ëŠ¥ì´ ì°½ì„ ë°”ê¾¸ì—ˆìŠµë‹ˆë‹¤"
+
+msgid "E840: Completion function deleted text"
+msgstr "E840: Completion ê¸°ëŠ¥ì´ ë¬¸ìžì—´ì„ 지웠습니다"
+
+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 " 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.
+#.
+msgid "-- Searching..."
+msgstr "-- 찾는 중..."
+
+msgid "Back at original"
+msgstr "ì›ëž˜ëŒ€ë¡œ 복구"
+
+msgid "Word from other line"
+msgstr "다른 ì¤„ì— ë‚±ë§"
+
+msgid "The only match"
+msgstr "The only match"
+
+#, c-format
+msgid "match %d of %d"
+msgstr "match %d of %d"
+
+#, c-format
+msgid "match %d"
+msgstr "match %d"
+
+msgid "E18: Unexpected characters in :let"
+msgstr "E18: ':let'ì— ëª¨ë¥´ëŠ” 글ìž"
+
+#, c-format
+msgid "E684: list index out of range: %ld"
+msgstr "E684: ëª©ë¡ ë²ˆí˜¸ê°€ 범위를 벗어남: %ld"
+
+#, c-format
+msgid "E121: Undefined variable: %s"
+msgstr "E121: ì •ì˜ ì•ˆ ëœ ë³€ìˆ˜: %s"
+
+msgid "E111: Missing ']'"
+msgstr "E111: ']'ì´ ì—†ìŠµë‹ˆë‹¤"
+
+#, c-format
+msgid "E686: Argument of %s must be a List"
+msgstr "E686: %s ì¸ìžëŠ” Listì´ì–´ì•¼ 합니다"
+
+#, c-format
+msgid "E712: Argument of %s must be a List or Dictionary"
+msgstr "E712: %s ì¸ìžëŠ” List í˜¹ì€ Dictionary여야 합니다"
+
+msgid "E713: Cannot use empty key for Dictionary"
+msgstr "E713: Dictionaryì— ë¹ˆ 키를 쓸 수 없습니다"
+
+msgid "E714: List required"
+msgstr "E714: List가 필요합니다"
+
+msgid "E715: Dictionary required"
+msgstr "E715: Dictionary가 필요합니다"
+
+#, 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: Dictionaryì— í‚¤ê°€ ì—†ìŒ: %s"
+
+#, c-format
+msgid "E122: Function %s already exists, add ! to replace it"
+msgstr "E122: 함수 %sì´(ê°€) ì´ë¯¸ 있습니다, 바꾸려면 !ì„ ë”하세요"
+
+msgid "E717: Dictionary entry already exists"
+msgstr "E717: ì´ë¯¸ Dictionary í•­ëª©ì´ ìžˆìŠµë‹ˆë‹¤"
+
+msgid "E718: Funcref required"
+msgstr "E718: Funcref가 필요합니다"
+
+msgid "E719: Cannot use [:] with a Dictionary"
+msgstr "E719: Dictionaryì— [:]ì„ ì‚¬ìš©í•  수 없습니다"
+
+#, c-format
+msgid "E734: Wrong variable type for %s="
+msgstr "E734: %s=ì— ëŒ€í•œ ìž˜ëª»ëœ ë³€ìˆ˜í˜•"
+
+#, c-format
+msgid "E130: Unknown function: %s"
+msgstr "E130: 모르는 함수: %s"
+
+#, c-format
+msgid "E461: Illegal variable name: %s"
+msgstr "E461: 비정ìƒì ì¸ 변수 명: %s"
+
+msgid "E687: Less targets than List items"
+msgstr "E687: List 항목보다 ì ì€ 대ìƒ"
+
+msgid "E688: More targets than List items"
+msgstr "E688: List 항목보다 ë§Žì€ ëŒ€ìƒ"
+
+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: List나 Dictionaryë§Œ 색ì¸í•  수 있습니다"
+
+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: :for ë’¤ì— \"in\"ê°€ 없습니다"
+
+#, c-format
+msgid "E107: Missing parentheses: %s"
+msgstr "E107: 괄호 ì—†ìŒ: %s"
+
+#, c-format
+msgid "E108: No such variable: \"%s\""
+msgstr "E108: ì´ëŸ° 변수 ì—†ìŒ: \"%s\""
+
+msgid "E743: variable nested too deep for (un)lock"
+msgstr "E743: 잠금(í•´ì œ)í•˜ê¸°ì— ë³€ìˆ˜ê°€ 너무 ê¹Šì´ ì¤‘ì²©ë˜ì—ˆìŠµë‹ˆë‹¤"
+
+msgid "E109: Missing ':' after '?'"
+msgstr "E109: '?' ë’¤ì— ':'ì´ ì—†ìŠµë‹ˆë‹¤"
+
+msgid "E691: Can only compare List with List"
+msgstr "E691: List는 List와만 비êµí•  수 있습니다"
+
+msgid "E692: Invalid operation for Lists"
+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 "E693: Can only compare Funcref with Funcref"
+msgstr "E693: Funcref는 Funcref와만 비êµí•  수 있습니다"
+
+msgid "E694: Invalid operation for Funcrefs"
+msgstr "E694: Funcrefsì— ëŒ€í•œ ìž˜ëª»ëœ ë™ìž‘"
+
+msgid "E804: Cannot use '%' with Float"
+msgstr "E804: Floatì— '%'는 사용할 수 없습니다"
+
+msgid "E110: Missing ')'"
+msgstr "E110: ')'가 없습니다"
+
+msgid "E695: Cannot index a Funcref"
+msgstr "E695: Funcref를 색ì¸í•  수 없습니다"
+
+#, 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"
+
+#, c-format
+msgid "E696: Missing comma in List: %s"
+msgstr "E696: Listì— ì½¤ë§ˆ 누ë½: %s"
+
+#, c-format
+msgid "E697: Missing end of List ']': %s"
+msgstr "E697: List ëì— ']' 누ë½: %s"
+
+#, c-format
+msgid "E720: Missing colon in Dictionary: %s"
+msgstr "E720: Dictionaryì— ì½œë¡  누ë½: %s"
+
+#, c-format
+msgid "E721: Duplicate key in Dictionary: \"%s\""
+msgstr "E721: Dictionaryì— ì¤‘ë³µëœ í‚¤: \"%s\""
+
+#, c-format
+msgid "E722: Missing comma in Dictionary: %s"
+msgstr "E722: Dictionaryì— ì½¤ë§ˆ 누ë½: %s"
+
+#, c-format
+msgid "E723: Missing end of Dictionary '}': %s"
+msgstr "E723: Dictionary ëì— '}' 누ë½: %s"
+
+msgid "E724: variable nested too deep for displaying"
+msgstr "E724: 변수가 í‘œì‹œí•˜ê¸°ì— ë„ˆë¬´ ê¹Šì´ ì¤‘ì²©ë˜ì—ˆìŠµë‹ˆë‹¤"
+
+#, 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(으)로 ìž˜ëª»ëœ ì¸ìžê°€ 넘겨졌습니다"
+
+#, c-format
+msgid "E117: Unknown function: %s"
+msgstr "E117: 모르는 함수: %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: Dictionaryì—†ì´ ì‚¬ì „í•¨ìˆ˜ê°€ 불려ì§: %s"
+
+msgid "E808: Number or Float required"
+msgstr "E808: Number í˜¹ì€ Floatê°€ 필요합니다"
+
+msgid "E699: Too many arguments"
+msgstr "E699: 너무 ë§Žì€ ì¸ìž"
+
+msgid "E785: complete() can only be used in Insert mode"
+msgstr "E785: complete()ì€ ìž…ë ¥ 모드ì—서만 ì‚¬ìš©ë  ìˆ˜ 있습니다"
+
+#.
+#. * 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 "확ì¸(&O)"
+
+#, c-format
+msgid "E737: Key already exists: %s"
+msgstr "E737: 키가 ì´ë¯¸ 존재함: %s"
+
+#, c-format
+msgid "+-%s%3ld lines: "
+msgstr "+-%s%3ld 줄: "
+
+#, c-format
+msgid "E700: Unknown function: %s"
+msgstr "E700: 모르는 함수: %s"
+
+msgid ""
+"&OK\n"
+"&Cancel"
+msgstr ""
+"확ì¸(&O)\n"
+"취소(&C)"
+
+msgid "called inputrestore() more often than inputsave()"
+msgstr "inputrestore()ê°€ inputsave()보다 ë§Žì´ ë¶ˆë ¤ì¡ŒìŠµë‹ˆë‹¤"
+
+msgid "E786: Range not allowed"
+msgstr "E786: 범위가 허용ë˜ì§€ 않습니다"
+
+msgid "E701: Invalid type for len()"
+msgstr "E701: len()ì— ìž˜ëª»ëœ í˜•"
+
+msgid "E726: Stride is zero"
+msgstr "E726: Strideê°€ 0"
+
+msgid "E727: Start past end"
+msgstr "E727: 시작위치가 ëì„ ì§€ë‚˜ì¹¨"
+
+msgid "<empty>"
+msgstr "<비어있ìŒ>"
+
+msgid "E240: No connection to Vim server"
+msgstr "E240: Vim ì„œë²„ì— ì—°ê²°ë˜ì–´ 있지 않습니다"
+
+#, c-format
+msgid "E241: Unable to send to %s"
+msgstr "E241: %s(으)로 보낼 수 없습니다"
+
+msgid "E277: Unable to read a server reply"
+msgstr "E277: ì„œë²„ì˜ ì‘ë‹µì„ ì½ì„ 수 없습니다"
+
+msgid "E655: Too many symbolic links (cycle?)"
+msgstr "E655: 너무 ë§Žì€ ì‹¬ë³¼ë¦­ ë§í¬ (반복순환?)"
+
+msgid "E258: Unable to send to client"
+msgstr "E258: í´ë¼ì´ì–¸íŠ¸ë¡œ 보낼 수 없습니다"
+
+msgid "E702: Sort compare function failed"
+msgstr "E702: ì •ë ¬ ë¹„êµ ê¸°ëŠ¥ì´ ì‹¤íŒ¨í–ˆìŠµë‹ˆë‹¤"
+
+msgid "(Invalid)"
+msgstr "(잘못ë˜ì—ˆìŠµë‹ˆë‹¤)"
+
+msgid "E677: Error writing temp file"
+msgstr "E677: 임시 íŒŒì¼ ì“°ê¸° ì—러"
+
+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 "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 "E806: using Float as a String"
+msgstr "E806: Float를 String으로 사용"
+
+#, 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 "E706: Variable type mismatch for: %s"
+msgstr "E706: 변수 형 다름: %s"
+
+#, c-format
+msgid "E795: Cannot delete variable %s"
+msgstr "E795: 변수 %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: ë³µì‚¬í•˜ê¸°ì— ë³€ìˆ˜ê°€ 너무 깊게 중첩ë˜ì—ˆìŠµë‹ˆë‹¤"
+
+#, c-format
+msgid "E123: Undefined function: %s"
+msgstr "E123: ì •ì˜ ì•ˆ ëœ í•¨ìˆ˜: %s"
+
+#, c-format
+msgid "E124: Missing '(': %s"
+msgstr "E124: '('ê°€ ì—†ìŒ: %s"
+
+#, c-format
+msgid "E125: Illegal argument: %s"
+msgstr "E125: ìž˜ëª»ëœ ì¸ìž: %s"
+
+msgid "E126: Missing :endfunction"
+msgstr "E126: :endfunctionì´ ì—†ìŠµë‹ˆë‹¤"
+
+#, 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"
+
+msgid "E129: Function name required"
+msgstr "E129: 함수 ì´ë¦„ì´ í•„ìš”í•©ë‹ˆë‹¤"
+
+#, c-format
+msgid "E128: Function name must start with a capital or contain a colon: %s"
+msgstr "E128: 함수 ì´ë¦„ì€ ëŒ€ë¬¸ìžë¡œ 시작하거나 ì½œë¡ ì„ í¬í•¨í•´ì•¼ 함: %s"
+
+#, c-format
+msgid "E131: Cannot delete function %s: It is in use"
+msgstr "E131: 함수 %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ì„(를) ëŒë ¤ì£¼ì—ˆìŠµë‹ˆë‹¤"
+
+#, c-format
+msgid "continuing in %s"
+msgstr "%sì—서 계ì†"
+
+msgid "E133: :return not inside a function"
+msgstr "E133: :returnì´ í•¨ìˆ˜ ì•ˆì— ìžˆì§€ 않습니다"
+
+msgid ""
+"\n"
+"# global variables:\n"
+msgstr ""
+"\n"
+"# 전역 변수:\n"
+
+msgid ""
+"\n"
+"\tLast set from "
+msgstr ""
+"\n"
+"\tLast set from "
+
+msgid "No old files"
+msgstr "old 파ì¼ì´ 없습니다"
+
+#, c-format
+msgid "<%s>%s%s %d, Hex %02x, Octal %03o"
+msgstr "<%s>%s%s %d, 십육진 %02x, 팔진 %03o"
+
+#, 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: *Filter* ìžë™ëª…ë ¹ì€ í˜„ìž¬ 버í¼ë¥¼ 바꾸어서는 안 ë©ë‹ˆë‹¤"
+
+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 " 실패"
+
+#. avoid a wait_return for this message, it's annoying
+#, c-format
+msgid "E137: Viminfo file is not writable: %s"
+msgstr "E137: Viminfo 파ì¼ì˜ 쓰기 ê¶Œí•œì´ ì—†ìŠµë‹ˆë‹¤: %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\"ì„(를) 쓰는 중"
+
+#. Write the info:
+#, 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 "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 "스왑 íŒŒì¼ \"%s\"ê°€ 있습니다, ë®ì–´ì“¸ê¹Œìš”?"
+
+#, c-format
+msgid "E768: Swap file exists: %s (:silent! overrides)"
+msgstr "E768: 스왑 íŒŒì¼ ìžˆìŒ: %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: Autocommandê°€ 뜻 ë°–ì— ìƒˆ ë²„í¼ %sì„(를) 지웠습니다"
+
+msgid "E144: non-numeric argument to :z"
+msgstr "E144: 숫ìžê°€ 아닌 ì¸ìžê°€ :zì— ì£¼ì–´ì¡ŒìŠµë‹ˆë‹¤"
+
+msgid "E145: Shell commands not allowed in rvim"
+msgstr "E145: 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 " 한 줄ì—서"
+
+#, c-format
+msgid " on %ld lines"
+msgstr " %ld 줄ì—서"
+
+msgid "E147: Cannot do :global recursive"
+msgstr "E147: :globalì€ ìž¬ê·€ 호출 ë  ìˆ˜ 없습니다"
+
+msgid "E148: Regular expression missing from global"
+msgstr "E148: globalì—서 정규표현ì‹ì´ 빠졌습니다"
+
+#, c-format
+msgid "Pattern found in every line: %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 "E150: Not a directory: %s"
+msgstr "E150: 디렉토리가 아님: %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 "E160: Unknown sign command: %s"
+msgstr "E160: 모르는 sign 명령: %s"
+
+msgid "E156: Missing sign name"
+msgstr "E156: sign ì´ë¦„ì´ ì—†ìŠµë‹ˆë‹¤"
+
+msgid "E612: Too many signs defined"
+msgstr "E612: 너무 ë§Žì€ signì´ ì •ì˜ë˜ì–´ 있습니다"
+
+#, c-format
+msgid "E239: Invalid sign text: %s"
+msgstr "E239: ìž˜ëª»ëœ sign í…스트: %s"
+
+#, c-format
+msgid "E155: Unknown sign: %s"
+msgstr "E155: 모르는 sign: %s"
+
+msgid "E159: Missing sign number"
+msgstr "E159: sign 번호가 없습니다"
+
+#, c-format
+msgid "E158: Invalid buffer name: %s"
+msgstr "E158: ìž˜ëª»ëœ ë²„í¼ ì´ë¦„: %s"
+
+#, c-format
+msgid "E157: Invalid sign ID: %ld"
+msgstr "E157: ìž˜ëª»ëœ sign ID: %ld"
+
+msgid " (NOT FOUND)"
+msgstr " (못 찾았ìŒ)"
+
+msgid " (not supported)"
+msgstr " (ì§€ì›ë˜ì§€ 않ìŒ)"
+
+msgid "[Deleted]"
+msgstr "[지워졌습니다]"
+
+msgid "Entering Debug mode. Type \"cont\" to continue."
+msgstr "디버그 ìƒíƒœë¡œ 들어ê°. 계ì†í•˜ë ¤ë©´ \"cont\"를 입력하십시오."
+
+#, c-format
+msgid "line %ld: %s"
+msgstr "%ld 줄: %s"
+
+#, c-format
+msgid "cmd: %s"
+msgstr "명령: %s"
+
+#, 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 줄"
+
+msgid "E750: First use \":profile start {fname}\""
+msgstr "E750: 먼저 \":profile start {fname}\"ì„ ì‚¬ìš©í•˜ì„¸ìš”"
+
+#, c-format
+msgid "Save changes to \"%s\"?"
+msgstr "\"%s\"ì— ë°”ë€ ë‚´ìš©ì„ ì €ìž¥í• ê¹Œìš”?"
+
+msgid "Untitled"
+msgstr "제목 ì—†ìŒ"
+
+#, c-format
+msgid "E162: No write since last change for buffer \"%s\""
+msgstr "E162: ë²„í¼ \"%s\"ì— ë‚˜ì¤‘ì— ë°”ë€ ë‚´ìš©ì´ ì¨ì§€ì§€ 않았습니다"
+
+msgid "Warning: Entered other buffer unexpectedly (check autocommands)"
+msgstr "경고: 뜻 ë°–ì— ë‹¤ë¥¸ 버í¼ë¡œ 들어갔습니다 (autocommand를 확ì¸í•˜ì‹­ì‹œì˜¤)"
+
+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 'runtimepath': \"%s\""
+msgstr "'runtimepath'ì—서 ì°¾ì„ ìˆ˜ ì—†ìŒ: \"%s\""
+
+msgid "Source Vim script"
+msgstr "ë¹” 스í¬ë¦½íЏ 로드"
+
+#, c-format
+msgid "Cannot source a directory: \"%s\""
+msgstr "디렉토리는 sourceí•  수 ì—†ìŒ: \"%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 불러들ì´ê¸° ë"
+
+#~ msgid "modeline"
+#~ msgstr ""
+
+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 ìƒíƒœë¡œ 전환. Normal ìƒíƒœë¡œ 가려면 \"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 "E319: Sorry, the command is not available in this version"
+msgstr "E319: 미안합니다, ê·¸ ëª…ë ¹ì€ í˜„ìž¬ íŒì—서 사용할 수 없습니다"
+
+msgid "E172: Only one file name allowed"
+msgstr "E172: 오로지 í•˜ë‚˜ì˜ íŒŒì¼ ì´ë¦„ë§Œ 사용 가능합니다"
+
+msgid "1 more file to edit. Quit anyway?"
+msgstr "ê³ ì¹  파ì¼ì´ 한 ê°œ ë” ìžˆìŠµë‹ˆë‹¤. ê·¸ëž˜ë„ ë낼까요?"
+
+#, c-format
+msgid "%d more files to edit. Quit anyway?"
+msgstr "ê³ ì¹  파ì¼ì´ %d ê°œ ë” ìžˆìŠµë‹ˆë‹¤. ê·¸ëž˜ë„ ë낼까요?"
+
+msgid "E173: 1 more file to edit"
+msgstr "E173: ê³ ì¹  파ì¼ì´ 한 ê°œ ë” ìžˆìŠµë‹ˆë‹¤"
+
+#, 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 Range 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ì— ì¸ìžê°€ 필요합니다"
+
+#, 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 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 "ë¹” 사용ìžë‹˜, 환ì˜í•©ë‹ˆë‹¤!"
+
+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 "스왑 파ì¼ì´ 없습니다"
+
+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 "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\"ì„(를) ì—´ 수 없습니다"
+
+#. set mark
+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: \"<sfile>\"ì— ëŒ€í•´ 치환할 :source íŒŒì¼ ì´ë¦„ì´ ì—†ìŠµë‹ˆë‹¤"
+
+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: '%'나 '#'ì— ëŒ€í•œ 빈 íŒŒì¼ ì´ë¦„, 오로지 \":p:h\"와만 ë™ìž‘합니다"
+
+msgid "E500: Evaluates to an empty string"
+msgstr "E500: 빈 문ìžì—´ì—서 ê°’ì„ êµ¬í•˜ë ¤ê³  합니다"
+
+msgid "E195: Cannot open viminfo file for reading"
+msgstr "E195: ì½ì„ viminfo 파ì¼ì„ ì—´ 수 없습니다"
+
+msgid "E196: No digraphs in this version"
+msgstr "E196: ì´ íŒì—는 digraphê°€ 없습니다"
+
+msgid "E608: Cannot :throw exceptions with 'Vim' prefix"
+msgstr "E608: 'Vim' ì ‘ë‘사로 예외를 :throwí•  수 없습니다"
+
+#. always scroll up, don't overwrite
+#, c-format
+msgid "Exception thrown: %s"
+msgstr "예외 thrown: %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 줄"
+
+#. always scroll up, don't overwrite
+#, c-format
+msgid "Exception caught: %s"
+msgstr "예외 ë°œìƒ: %s"
+
+#, c-format
+msgid "%s made pending"
+msgstr "%sì´(ê°€) pending ë˜ì—ˆìŠµë‹ˆë‹¤"
+
+#, 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 "ì—러"
+
+#. if (pending & CSTP_INTERRUPT)
+msgid "Interrupt"
+msgstr "ì¸í„°ëŸ½íЏ"
+
+msgid "E579: :if nesting too deep"
+msgstr "E579: :ifê°€ 너무 깊게 중첩ë˜ì—ˆìŠµë‹ˆë‹¤"
+
+msgid "E580: :endif without :if"
+msgstr "E580: :ifì—†ì´ :endifê°€ 있습니다"
+
+msgid "E581: :else without :if"
+msgstr "E581: :ifì—†ì´ :elseê°€ 있습니다"
+
+msgid "E582: :elseif without :if"
+msgstr "E582: :ifì—†ì´ :elseifê°€ 있습니다"
+
+msgid "E583: multiple :else"
+msgstr "E583: ì—¬ëŸ¬ê°œì˜ :elseê°€ 있습니다"
+
+msgid "E584: :elseif after :else"
+msgstr "E584: :else ë’¤ì— :elseifê°€ 있습니다"
+
+msgid "E585: :while/:for nesting too deep"
+msgstr "E585: :while/:forê°€ 너무 깊게 중첩ë˜ì—ˆìŠµë‹ˆë‹¤"
+
+msgid "E586: :continue without :while or :for"
+msgstr "E586: :while í˜¹ì€ :forì—†ì´ :continueê°€ 있습니다"
+
+msgid "E587: :break without :while or :for"
+msgstr "E587: :while í˜¹ì€ :forì—†ì´ :breakê°€ 있습니다"
+
+msgid "E732: Using :endfor with :while"
+msgstr "E732: :whileì— :endforê°€ 사용ë˜ì—ˆìŠµë‹ˆë‹¤"
+
+msgid "E733: Using :endwhile with :for"
+msgstr "E733: :forì— :endwhileì´ ì‚¬ìš©ë˜ì—ˆìŠµë‹ˆë‹¤"
+
+msgid "E601: :try nesting too deep"
+msgstr "E601: :tryê°€ 너무 깊게 중첩ë˜ì—ˆìŠµë‹ˆë‹¤"
+
+msgid "E603: :catch without :try"
+msgstr "E603: :tryì—†ì´ :catchê°€ 있습니다"
+
+#. Give up for a ":catch" after ":finally" and ignore it.
+#. * Just parse.
+msgid "E604: :catch after :finally"
+msgstr "E604: :finally ë’¤ì— :catchê°€ 있습니다"
+
+msgid "E606: :finally without :try"
+msgstr "E606: :tryì—†ì´ :finallyê°€ 있습니다"
+
+#. Give up for a multiple ":finally" and ignore it.
+msgid "E607: multiple :finally"
+msgstr "E607: ì—¬ëŸ¬ê°œì˜ :finallyê°€ 있습니다"
+
+msgid "E602: :endtry without :try"
+msgstr "E602: :tryì—†ì´ :endtryê°€ 있습니다"
+
+msgid "E193: :endfunction not inside a function"
+msgstr "E193: :endfunctionì´ function ë‚´ì— ì—†ìŠµë‹ˆë‹¤"
+
+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 " kind file\n"
+
+msgid "'history' option is zero"
+msgstr "'history' ì˜µì…˜ì´ 0입니다"
+
+#, 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 "E198: cmd_pchar beyond the command length"
+msgstr "E198: cmd_pcharê°€ 명령 길ì´ë¥¼ 벗어났습니다"
+
+msgid "E199: Active window or buffer deleted"
+msgstr "E199: í™œì„±ëœ ì°½ì´ë‚˜ 버í¼ê°€ 지워졌습니다"
+
+msgid "E812: Autocommands changed buffer or buffer name"
+msgstr "E812: Autocommandê°€ 버í¼ë‚˜ 버í¼ì´ë¦„ì„ ë°”ê¾¸ì—ˆìŠµë‹ˆë‹¤"
+
+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 "ë¹”: 표준입력ì—서 ì½ëŠ” 중...\n"
+
+msgid "Reading from stdin..."
+msgstr "표준입력ì—서 ì½ëŠ” 중..."
+
+#. Re-opening the original file failed!
+msgid "E202: Conversion made file unreadable!"
+msgstr "E202: ë³€í™˜ëœ íŒŒì¼ì„ ì½ì„ 수가 없습니다!"
+
+msgid "[fifo/socket]"
+msgstr "[피í¬/소켓]"
+
+msgid "[fifo]"
+msgstr "[피í¬]"
+
+msgid "[socket]"
+msgstr "[소켓]"
+
+#~ msgid "[character special]"
+#~ msgstr ""
+
+msgid "[RO]"
+msgstr "[ì½ê¸° ì „ìš©]"
+
+msgid "[CR missing]"
+msgstr "[CR ì—†ìŒ]"
+
+msgid "[long lines split]"
+msgstr "[긴 줄 잘림]"
+
+msgid "[NOT converted]"
+msgstr "[변환 안 ë©ë‹ˆë‹¤]"
+
+msgid "[converted]"
+msgstr "[변환 ë˜ì—ˆìŠµë‹ˆë‹¤]"
+
+msgid "[crypted]"
+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 "E821: File is encrypted with unknown method"
+msgstr "E821: 파ì¼ì´ 모르는 방법으로 암호화ë˜ì–´ 있습니다"
+
+msgid "E676: No matching autocommands for acwrite buffer"
+msgstr "E676: acwrite 버í¼ì— 대한 autocommand를 ì°¾ì„ ìˆ˜ 없습니다"
+
+msgid "E203: Autocommands deleted or unloaded buffer to be written"
+msgstr "E203: 쓸 버í¼ë¥¼ ìžë™ëª…ë ¹ì´ ì§€ìš°ê±°ë‚˜ 닫았습니다"
+
+msgid "E204: Autocommand changed number of lines in unexpected way"
+msgstr "E204: Autocommandê°€ ìž˜ëª»ëœ ë°©ë²•ìœ¼ë¡œ ì¤„ì„ ë°”ê¾¸ì—ˆìŠµë‹ˆë‹¤"
+
+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 "E460: The resource fork would be lost (add ! to override)"
+msgstr "E460: The resource fork will be lost (ë®ì–´ì“°ë ¤ë©´ ! ë”하기)"
+
+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 "E667: Fsync failed"
+msgstr "E667: Fsync가 실패했습니다"
+
+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 " [a]"
+
+msgid " appended"
+msgstr " ë”했습니다"
+
+msgid " [w]"
+msgstr " [w]"
+
+msgid " written"
+msgstr " 저장 했습니다"
+
+msgid "E205: Patchmode: can't save original file"
+msgstr "E205: 패치 ìƒíƒœ: ì›ëž˜ 파ì¼ì„ 저장할 수 없습니다"
+
+msgid "E206: patchmode: can't touch empty original file"
+msgstr "E206: 패치 ìƒíƒœ: 빈 ì›ëž˜ 파ì¼ì„ 만들 수 없습니다"
+
+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 "[ë„스]"
+
+msgid "[dos format]"
+msgstr "[ë„스 형ì‹]"
+
+msgid "[mac]"
+msgstr "[ë§¥]"
+
+msgid "[mac format]"
+msgstr "[ë§¥ 형ì‹]"
+
+msgid "[unix]"
+msgstr "[유닉스]"
+
+msgid "[unix format]"
+msgstr "[유닉스 형ì‹]"
+
+msgid "1 line, "
+msgstr "1 줄, "
+
+#, c-format
+msgid "%ld lines, "
+msgstr "%ld 줄, "
+
+msgid "1 character"
+msgstr "1 글ìž"
+
+#, c-format
+msgid "%lld characters"
+msgstr "%lld 글ìž"
+
+#. Explicit typecast avoids warning on Mac OS X 10.6
+#, c-format
+msgid "%ld characters"
+msgstr "%ld 글ìž"
+
+msgid "[noeol]"
+msgstr "[noeol]"
+
+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
+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\"ì´(ê°€) 바뀌었고 마찬가지로 ë¹”ì˜ ë²„í¼ë„ 바뀌었습니다"
+
+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 ""
+"확ì¸(&O)\n"
+"íŒŒì¼ ë¶ˆëŸ¬ì˜¤ê¸°(&L)"
+
+#, 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 "autocommand ìžë™ì‚­ì œ: %s <buffer=%d>"
+
+#. the group doesn't exist
+#, c-format
+msgid "E367: No such group: \"%s\""
+msgstr "E367: ì´ëŸ° 그룹 ì—†ìŒ: \"%s\""
+
+#, 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"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Auto-Commands ---"
+msgstr ""
+"\n"
+"--- ìžë™-명령 ---"
+
+#, c-format
+msgid "E680: <buffer=%d>: invalid buffer number "
+msgstr "E680: <buffer=%d>: ìž˜ëª»ëœ ë²„í¼ ë²ˆí˜¸"
+
+msgid "E217: Can't execute autocommands for ALL events"
+msgstr "E217: ALL ì´ë²¤íŠ¸ì— ëŒ€í•´ ìžë™ëª…ë ¹ì„ ì‹¤í–‰í•  수 없습니다"
+
+msgid "No matching autocommands"
+msgstr "맞는 ìžë™ëª…ë ¹ì´ ì—†ìŠµë‹ˆë‹¤"
+
+msgid "E218: autocommand nesting too deep"
+msgstr "E218: ìžë™ëª…ë ¹ì´ ë„ˆë¬´ 깊게 중첩ë˜ì—ˆìŠµë‹ˆë‹¤"
+
+#, c-format
+#~ msgid "%s Auto commands for \"%s\""
+#~ msgstr ""
+
+#, 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: fold가 없습니다"
+
+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 lines folded "
+msgstr "+--%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 "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 "스í¬ë¡¤ë°” 위젯: ì¸ í”½ìŠ¤ë§µì˜ ì§€ì˜¤ë¯¸íŠ¸ë¦¬ë¥¼ ì–»ì„ ìˆ˜ 없습니다."
+
+msgid "Vim dialog"
+msgstr "ë¹” 대화ìƒìž"
+
+msgid "E232: Cannot create BalloonEval with both message and callback"
+msgstr "E232: 메시지와 콜백 모ë‘를 사용해서는 BalloonEvalì„ ë§Œë“¤ 수 없습니다"
+
+msgid ""
+"&Yes\n"
+"&No\n"
+"&Cancel"
+msgstr ""
+"예(&Y)\n"
+"아니오(&N)\n"
+"취소(&C)"
+
+msgid "Input _Methods"
+msgstr "입력 방법(_M)"
+
+msgid "VIM - Search and Replace..."
+msgstr "빔 - 찾아서 바꾸기..."
+
+msgid "VIM - Search..."
+msgstr "빔 - 찾기..."
+
+msgid "Find what:"
+msgstr "무얼 ì°¾ì„까요:"
+
+msgid "Replace with:"
+msgstr "바꿀 문ìžì—´:"
+
+#. whole word only button
+msgid "Match whole word only"
+msgstr "ë˜‘ê°™ì€ ë‚±ë§ë§Œ"
+
+#. match case button
+#~ msgid "Match case"
+#~ msgstr ""
+
+msgid "Direction"
+msgstr "ë°©í–¥"
+
+#. 'Up' and 'Down' buttons
+msgid "Up"
+msgstr "위로"
+
+msgid "Down"
+msgstr "아래로"
+
+#. 'Find Next' button
+msgid "Find Next"
+msgstr "ë‹¤ìŒ ì°¾ê¸°"
+
+#. 'Replace' button
+msgid "Replace"
+msgstr "바꾸기"
+
+#. 'Replace All' button
+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)"
+
+#, 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 "Close tab"
+msgstr "탭 닫기"
+
+msgid "Open tab..."
+msgstr "탭 열기..."
+
+msgid "Find string (use '\\\\' to find a '\\')"
+msgstr "문ìžì—´ 찾기 ('\\'를 찾으려면 '\\\\' 사용)"
+
+msgid "Find & Replace (use '\\\\' to find a '\\')"
+msgstr "문ìžì—´ 찾아 바꾸기 ('\\'를 찾으려면 '\\\\' 사용)"
+
+#. 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 "사용 않ë¨"
+
+msgid "Directory\t*.nothing\n"
+msgstr "디렉토리\t*.nothing\n"
+
+msgid "Vim E458: Cannot allocate colormap entry, some colors may be incorrect"
+msgstr ""
+"ë¹” E458: 색ìƒë§µ 엔트리를 할당할 수 없습니다, 몇몇 ìƒ‰ì´ ìž˜ëª»ë  ìˆ˜ 있습니다"
+
+#, 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\n"
+msgstr "E253: 글꼴셋 ì´ë¦„: %s\n"
+
+#, c-format
+msgid "Font0: %s\n"
+msgstr "글꼴0: %s\n"
+
+#, c-format
+msgid "Font1: %s\n"
+msgstr "글꼴1: %s\n"
+
+#, c-format
+msgid "Font%ld width is not twice that of font0\n"
+msgstr "글꼴%ld 너비가 글꼴0ì˜ ë‘ë°°ê°€ 아닙니다\n"
+
+#, c-format
+msgid "Font0 width: %ld\n"
+msgstr "글꼴0 너비: %ld\n"
+
+#, c-format
+msgid ""
+"Font1 width: %ld\n"
+"\n"
+msgstr ""
+"글꼴1 너비: %ld\n"
+"\n"
+
+#~ msgid "Invalid font specification"
+#~ msgstr ""
+
+#~ msgid "&Dismiss"
+#~ msgstr ""
+
+#~ msgid "no specific match"
+#~ msgstr ""
+
+msgid "Vim - Font Selector"
+msgstr "Vim - 글꼴 ì„ íƒê¸°"
+
+msgid "Name:"
+msgstr "ì´ë¦„:"
+
+#. create toggle button
+#~ 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 "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: í¬ìŠ¤íŠ¸ìŠ¤í¬ë¦½íЏ 출력파ì¼ì— 쓸 수 없습니다."
+
+#, 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: í¬ìŠ¤íŠ¸ìŠ¤í¬ë¦½íЏ 리소스 íŒŒì¼ \"%s\"ì„(를) ì½ì„ 수 없습니다"
+
+#, c-format
+msgid "E618: file \"%s\" is not a PostScript resource file"
+msgstr "E618: íŒŒì¼ \"%s\"ì€(는) í¬ìŠ¤íŠ¸ìŠ¤í¬ë¦½íЏ 리소스 파ì¼ì´ 아닙니다"
+
+#, c-format
+msgid "E619: file \"%s\" is not a supported PostScript resource file"
+msgstr "E619: íŒŒì¼ \"%s\"ì€(는) ì§€ì›ë˜ëŠ” í¬ìŠ¤íŠ¸ìŠ¤í¬ë¦½íЏ 리소스 파ì¼ì´ 아닙니다"
+
+#, c-format
+msgid "E621: \"%s\" resource file has wrong version"
+msgstr "E621: \"%s\" 리소스 파ì¼ì€ ë²„ì „ì´ ìž˜ëª»ë˜ì—ˆìŠµë‹ˆë‹¤"
+
+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: í¬ìŠ¤íŠ¸ìŠ¤í¬ë¦½íЏ 출력파ì¼ì„ ì—´ 수 없습니다"
+
+#, c-format
+msgid "E456: Can't open file \"%s\""
+msgstr "E456: \"%s\" 파ì¼ì„ ì—´ 수 없습니다"
+
+msgid "E456: Can't find PostScript resource file \"prolog.ps\""
+msgstr "E456: í¬ìŠ¤íŠ¸ìŠ¤í¬ë¦½íЏ 리소스 íŒŒì¼ \"prolog.ps\"를 ì°¾ì„ ìˆ˜ 없습니다"
+
+msgid "E456: Can't find PostScript resource file \"cidfont.ps\""
+msgstr "E456: í¬ìŠ¤íŠ¸ìŠ¤í¬ë¦½íЏ 리소스 íŒŒì¼ \"cidfont.ps\"를 ì°¾ì„ ìˆ˜ 없습니다"
+
+#, c-format
+msgid "E456: Can't find PostScript resource file \"%s.ps\""
+msgstr "E456: í¬ìŠ¤íŠ¸ìŠ¤í¬ë¦½íЏ 리소스 íŒŒì¼ \"%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: í¬ìŠ¤íŠ¸ìŠ¤í¬ë¦½íЏ 파ì¼ì„ ì¸ì‡„í•  수 없습니다"
+
+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를 fork할 수 없습니다"
+
+msgid "cs_create_connection exec failed"
+msgstr "cs_create_connection ì‹¤í–‰ì´ ì‹¤íŒ¨í–ˆìŠµë‹ˆë‹¤"
+
+msgid "cs_create_connection: fdopen for to_fp failed"
+msgstr "cs_create_connection: to_fpì— ëŒ€í•œ fdopen 실패"
+
+msgid "cs_create_connection: fdopen for fr_fp failed"
+msgstr "cs_create_connection: fr_fpì— ëŒ€í•œ fdopen 실패"
+
+msgid "E623: Could not spawn cscope process"
+msgstr "E623: cscope 프로세스를 spawn할 수 없습니다"
+
+msgid "E567: no cscope connections"
+msgstr "E567: cscope ì—°ê²°ì´ ì—†ìŠµë‹ˆë‹¤"
+
+#, c-format
+#~ msgid "E469: invalid cscopequickfix flag %c for %c"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E259: no matches found for cscope query %s of %s"
+#~ msgstr ""
+
+msgid "cscope commands:\n"
+msgstr "cscope 명령:\n"
+
+#, c-format
+msgid "%-5s: %s%*s (Usage: %s)"
+msgstr "%-5s: %s%*s (사용법: %s)"
+
+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"
+
+#, 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 ë°ì´í„°ë² ì´ìŠ¤ëŠ” ë”해지지 않았습니다"
+
+#, c-format
+msgid "E261: cscope connection %s not found"
+msgstr "E261: cscope ì—°ê²° %sì„(를) ì°¾ì„ ìˆ˜ 없습니다"
+
+#, c-format
+msgid "cscope connection %s closed"
+msgstr "cscope ì—°ê²° %sì´(ê°€) 닫혔습니다"
+
+#. should not reach here
+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 ë°ì´í„°ë² ì´ìФ ì´ë¦„ prepend path\n"
+
+#~ msgid "Lua library cannot be loaded."
+#~ msgstr ""
+
+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 "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 "문ìžì—´ì€ 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 "ìž˜ëª»ëœ ì†ì„±"
+
+#, c-format
+msgid "<buffer object (deleted) at %p>"
+msgstr "<%pì— ë²„í¼ ê°ì²´ (ì‚­ì œë¨)>"
+
+msgid "E837: This Vim cannot execute :py3 after using :python"
+msgstr "E837: ì´ Vimì€ :pythonì„ ì‚¬ìš©í•œ í›„ì— :py3ì„ ì‚¬ìš©í•  수 없습니다"
+
+#~ msgid "E265: $_ must be an instance of String"
+#~ msgstr ""
+
+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 "E271: retry outside of rescue clause"
+#~ msgstr ""
+
+msgid "E272: unhandled exception"
+msgstr "E272: ì²˜ë¦¬ì•Šëœ ì˜ˆì™¸"
+
+#, c-format
+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 ""
+
+#~ msgid "Xref referred by"
+#~ msgstr ""
+
+#~ msgid "Xref has a"
+#~ msgstr ""
+
+#~ msgid "Xref used by"
+#~ msgstr ""
+
+#~ 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+ is currently "
+
+msgid "not "
+msgstr "not "
+
+msgid "connected"
+msgstr "connected"
+
+#, c-format
+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 "마í¬ê°€ 설정ë˜ì§€ 않았습니다"
+
+#, 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 "모르는 빔 옵션"
+
+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 "콜백 ëª…ë ¹ì„ ë“±ë¡í•  수 없습니다: 버í¼/ì°½ì´ ì´ë¯¸ 지워졌습니다"
+
+#. This should never happen. Famous last word?
+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로 알"
+"려주십시오"
+
+#, 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: ë¹” ì¸ìŠ¤í„´ìŠ¤ 레지스트리 ì†ì„±ì´ 잘못ë˜ì–´ 있습니다. 지웠습니다!"
+
+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 ""
+
+#, c-format
+msgid "%d files to edit\n"
+msgstr "%d 파ì¼ì„ 고치기\n"
+
+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 "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: ì—러: NetBeansì—서 gvim 시작 실패\n"
+
+msgid "Vim: Warning: Output is not to a terminal\n"
+msgstr "ë¹”: 경고: 터미ë„로 출력할 수 없습니다\n"
+
+msgid "Vim: Warning: Input is not from a terminal\n"
+msgstr "ë¹”: 경고: 터미ë„로 부터 ìž…ë ¥ë°›ì„ ìˆ˜ 없습니다\n"
+
+#. just in case..
+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 "- 표준입력ì—서 í…스트 ì½ê¸°"
+
+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 ""
+
+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\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 "-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 "-s\t\t\tSilent (batch) mode (only for \"ex\")"
+msgstr "-s\t\t\t조용한 (배치) ìƒíƒœ (\"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\t쉬운 ìƒíƒœ (\"evim\"ê³¼ ê°™ìŒ, modeless)"
+
+msgid "-R\t\t\tReadonly mode (like \"view\")"
+msgstr "-R\t\t\tì½ê¸° ì „ìš© ìƒíƒœ (\"view\"와 ê°™ìŒ)"
+
+msgid "-Z\t\t\tRestricted mode (like \"rvim\")"
+msgstr "-Z\t\t\tì œí•œëœ ìƒíƒœ (\"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\t리스프 ìƒíƒœ"
+
+msgid "-C\t\t\tCompatible with Vi: 'compatible'"
+msgstr "-C\t\t\tVi 호환: 'compatible'"
+
+msgid "-N\t\t\tNot fully Vi compatible: 'nocompatible'"
+msgstr "-N\t\t\tVi와 호환ë˜ì§€ 않ìŒ: 'nocompatible'"
+
+#~ msgid "-V[N][fname]\t\tBe verbose [level N] [log messages to fname]"
+#~ msgstr ""
+
+msgid "-D\t\t\tDebugging mode"
+msgstr "-D\t\t\t디버깅 ìƒíƒœ"
+
+msgid "-n\t\t\tNo swap file, use memory only"
+msgstr "-n\t\t\t스왑 íŒŒì¼ ì—†ì´ ë©”ëª¨ë¦¬ë§Œ 사용"
+
+msgid "-r\t\t\tList swap files and exit"
+msgstr "-r\t\t\t스왑 íŒŒì¼ ëª©ë¡ì„ 표시한 ë’¤ ë내기"
+
+msgid "-r (with file name)\tRecover crashed session"
+msgstr "-r (íŒŒì¼ ì´ë¦„ê³¼ 함께)\t파ì†ë˜ì—ˆë˜ 세션 복구"
+
+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ì°½ì„ ì—´ 때 newcli 사용하지 않ìŒ"
+
+msgid "-dev <device>\t\tUse <device> for I/O"
+msgstr "-dev <장치>\t\tI/Oì— <장치> 사용"
+
+msgid "-A\t\t\tstart in Arabic mode"
+msgstr "-A\t\t\tArabic 모드로 시작"
+
+msgid "-H\t\t\tStart in Hebrew mode"
+msgstr "-H\t\t\tHebrew 모드로 시작"
+
+msgid "-F\t\t\tStart in Farsi mode"
+msgstr "-F\t\t\tFarsi 모드로 시작"
+
+msgid "-T <terminal>\tSet terminal type to <terminal>"
+msgstr "-T <terminal>\tí„°ë¯¸ë„ ì¢…ë¥˜ë¥¼ <terminal>로 설정"
+
+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\tNê°œì˜ íƒ­ 열기 (기본: 파ì¼ë³„로 하나)"
+
+msgid "-o[N]\t\tOpen N windows (default: one for each file)"
+msgstr "-o[N]\t\tNê°œì˜ ì°½ 열기 (기본: 파ì¼ë³„로 하나)"
+
+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 "+<lnum>\t\t<lnum> 줄ì—서 시작"
+
+msgid "--cmd <command>\tExecute <command> before loading any vimrc file"
+msgstr "--cmd <명령>\tvimrc 파ì¼ì„ ì½ê¸° ì „ì— <명령>ì„ ì‹¤í–‰"
+
+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 <scriptin>\t<scriptin> 파ì¼ì—서 Normal ìƒíƒœ 명령 ì½ê¸°"
+
+msgid "-w <scriptout>\tAppend all typed commands to file <scriptout>"
+msgstr "-w <scriptout>\t모든 ìž…ë ¥ëœ ëª…ë ¹ì„ <scriptout> 파ì¼ì— 추가"
+
+msgid "-W <scriptout>\tWrite all typed commands to file <scriptout>"
+msgstr "-W <scriptout>\t모든 ìž…ë ¥ëœ ëª…ë ¹ì„ <scriptout> 파ì¼ì— 저장"
+
+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 "--startuptime <file>\tWrite startup timing messages to <file>"
+msgstr "--startuptime <file>\tstartup timing 메시지를 <file>ì— ì €ìž¥"
+
+msgid "-i <viminfo>\t\tUse <viminfo> instead of .viminfo"
+msgstr "-i <viminfo>\t\t.viminfo 대신 <viminfo>를 사용"
+
+msgid "-h or --help\tPrint Help (this message) and exit"
+msgstr "-h í˜¹ì€ --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ì´ ì•Œê³  있는 ì¸ìž (모티프 íŒ):\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 "디스플레ì´ê°€ 없습니다"
+
+#. Failed to send, abort.
+msgid ": Send failed.\n"
+msgstr ": 보내기가 실패하였습니다.\n"
+
+#. Let vim start normally.
+msgid ": Send failed. Trying to execute locally\n"
+msgstr ": 보내기 실패. 로컬ì—서 실행ë©ë‹ˆë‹¤\n"
+
+#, c-format
+#~ msgid "%d of %d edited"
+#~ msgstr ""
+
+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\"ì— ë§žëŠ” 마í¬ê°€ 없습니다"
+
+#. Highlight title
+msgid ""
+"\n"
+"mark line col file/text"
+msgstr ""
+"\n"
+"ë§ˆí¬ ë¼ì¸ col 파ì¼/í…스트"
+
+#. Highlight title
+msgid ""
+"\n"
+" jump line col file/text"
+msgstr ""
+"\n"
+" ì í”„ ë¼ì¸ col 파ì¼/í…스트"
+
+#. Highlight title
+#~ msgid ""
+#~ "\n"
+#~ "change line col text"
+#~ msgstr ""
+
+msgid ""
+"\n"
+"# File marks:\n"
+msgstr ""
+"\n"
+"# íŒŒì¼ ë§ˆí¬:\n"
+
+#. Write the jumplist with -'
+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: 스왑 파ì¼ì„ ì½ê¸° 위해 특정 위치로 ê°ˆ 수 없습니다"
+
+msgid "E295: Read error in swap file"
+msgstr "E295: 스왑 파ì¼ì„ ì½ì„ 수 없습니다"
+
+msgid "E296: Seek error in swap file write"
+msgstr "E296: 스왑 파ì¼ì„ 쓰기 위해 특정 위치로 ê°ˆ 수 없습니다"
+
+msgid "E297: Write error in swap file"
+msgstr "E297: 스왑 파ì¼ì„ 쓸 수 없습니다"
+
+msgid "E300: Swap file already exists (symlink attack?)"
+msgstr "E300: 스왑 파ì¼ì´ ì´ë¯¸ 존재합니다 (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: 스왑 파ì¼ì„ 암호화할 수 없습니다"
+
+#. could not (re)open the swap file, what can we do????
+msgid "E301: Oops, lost the swap file!!!"
+msgstr "E301: 으윽, 스왑 파ì¼ì„ 잃어버렸습니다!!!"
+
+msgid "E302: Could not rename swap file"
+msgstr "E302: 스왑 íŒŒì¼ ì´ë¦„ì„ ë°”ê¿€ 수 없습니다"
+
+#, c-format
+msgid "E303: Unable to open swap file for \"%s\", recovery impossible"
+msgstr "E303: \"%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ì˜ ìŠ¤ì™‘ 파ì¼ì„ ì°¾ì„ ìˆ˜ 없습니다"
+
+msgid "Enter number of swap file to use (0 to quit): "
+msgstr "사용할 스왑 íŒŒì¼ ë²ˆí˜¸ë¥¼ 입력하십시오 (0ì€ ë내기): "
+
+#, c-format
+msgid "E306: Cannot open %s"
+msgstr "E306: %sì„(를) ì—´ 수 없습니다"
+
+msgid "Unable to read block 0 from "
+msgstr "Unable to read block 0 from "
+
+msgid ""
+"\n"
+"Maybe no changes were made or Vim did not update the swap file."
+msgstr ""
+"\n"
+"ì–´ë–¤ ìˆ˜ì •ë„ ì—†ì—ˆê±°ë‚˜ ë¹”ì´ ìŠ¤ì™‘ 파ì¼ì„ 갱신하지 ì•Šì€ ê²ƒ 같습니다."
+
+msgid " cannot be used with this version of Vim.\n"
+msgstr " cannot be used with this version of Vim.\n"
+
+msgid "Use Vim version 3.0.\n"
+msgstr "ë¹” 3.0 íŒì„ 사용하십시오.\n"
+
+#, c-format
+msgid "E307: %s does not look like a Vim swap file"
+msgstr "E307: %sì€(는) ë¹” 스왑 파ì¼ì´ 아닌 것 같습니다"
+
+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 ""
+
+#, 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 ""
+
+#, c-format
+msgid "Using swap file \"%s\""
+msgstr "스왑 íŒŒì¼ \"%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 "스왑 파ì¼ì´ 암호화ë¨: \"%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"
+"스왑파ì¼ì„ 저장하려면 엔터를 누르세요"
+
+#, c-format
+msgid "E309: Unable to read block 1 from %s"
+msgstr "E309: %sì˜ êµ¬ì—­ 1ì„ ì½ì„ 수 없습니다"
+
+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: 구역 1ì˜ IDê°€ 잘못ë˜ì—ˆìŠµë‹ˆë‹¤ (%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 "복구가 ë났습니다. 모든 게 ì •ìƒì¸ ì§€ 확ì¸í•´ 보셔야만 합니다."
+
+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 "í…스트 파ì¼ì— 스왑파ì¼ì—서 가져온 암호 키를 사용합니다.\n"
+
+#. use msg() to start the scrolling properly
+msgid "Swap files found:"
+msgstr "스왑 파ì¼ì„ 찾았ìŒ:"
+
+msgid " In current directory:\n"
+msgstr " 현재 디렉토리ì—:\n"
+
+msgid " Using specified name:\n"
+msgstr " ëª…ì‹œëœ ì´ë¦„ì„ ì‚¬ìš©:\n"
+
+msgid " In directory "
+msgstr " In directory "
+
+msgid " -- none --\n"
+msgstr " -- ì—†ìŒ --\n"
+
+msgid " owned by: "
+msgstr " 소유ìž: "
+
+msgid " dated: "
+msgstr " 날짜: "
+
+msgid " dated: "
+msgstr " 날짜: "
+
+msgid " [from Vim version 3.0]"
+msgstr " [ë¹” 3.0 íŒì˜ 것]"
+
+msgid " [does not look like a Vim swap file]"
+msgstr " [ë¹” 스왑 파ì¼ë¡œ ë³´ì´ì§€ 않습니다]"
+
+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"
+" 프로세스 ID: "
+
+msgid " (still running)"
+msgstr " (ì•„ì§ ì‹¤í–‰ì¤‘)"
+
+msgid ""
+"\n"
+" [not usable with this version of Vim]"
+msgstr ""
+"\n"
+" [ë¹” ì´ë²ˆ íŒì—서는 사용할 수 ì—†ìŒ]"
+
+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: ë³´ì¡´í•  수 없습니다, 스왑 파ì¼ì´ 없습니다"
+
+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: ìž˜ëª»ëœ í¬ì¸í„° 구역 id 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: ìž˜ëª»ëœ í¬ì¸í„° 구역 id 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: ìž˜ëª»ëœ í¬ì¸í„° 구역 id"
+
+msgid "pe_line_count is zero"
+msgstr "pe_line_count가 0입니다"
+
+#, 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: ìž˜ëª»ëœ í¬ì¸í„° 구역 id 2"
+
+#, c-format
+#~ msgid "E773: Symlink loop for \"%s\""
+#~ msgstr ""
+
+msgid "E325: ATTENTION"
+msgstr "E325: 주목"
+
+msgid ""
+"\n"
+"Found a swap file by the name \""
+msgstr ""
+"\n"
+"Found a swap file by the name \""
+
+msgid "While opening file \""
+msgstr "While opening file \""
+
+msgid " NEWER than swap file!\n"
+msgstr " NEWER than swap file!\n"
+
+#. Some of these messages are long to allow translation to
+#. * other languages.
+msgid ""
+"\n"
+"(1) Another program may be editing the same file.\n"
+" If this is the case, be careful not to end up with two\n"
+" different instances of the same file when making changes.\n"
+msgstr ""
+"\n"
+"(1) 다른 í”„ë¡œê·¸ëž¨ì´ ê°™ì€ íŒŒì¼ì„ 고치고 ìžˆëŠ”ì¤‘ì¼ ìˆ˜ 있습니다.\n"
+" 만약 그렇다면 ê°™ì€ íŒŒì¼ì„ ë‘ ê°œì˜ í”„ë¡œê·¸ëž¨ì—서 고치지\n"
+" 않ë„ë¡ ì¡°ì‹¬í•˜ì‹œê¸° ë°”ëžë‹ˆë‹¤.\n"
+
+msgid " Quit, or continue with caution.\n"
+msgstr " ë내거나 ìœ„í—˜ì„ ê°ìˆ˜í•˜ì‹œë ¤ë©´ 계ì†í•˜ì‹­ì‹œì˜¤.\n"
+
+msgid ""
+"\n"
+"(2) An edit session for this file crashed.\n"
+msgstr ""
+"\n"
+"(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 " ì´ë¯¸ 복구하셨었다면 ìŠ¤ì™‘íŒŒì¼ \""
+
+msgid ""
+"\"\n"
+" to avoid this message.\n"
+msgstr ""
+"\"\n"
+" ì„(를) 지우셔야 ì´ ë©”ì‹œì§€ê°€ 사ë¼ì§‘니다.\n"
+
+msgid "Swap file \""
+msgstr "스왑 íŒŒì¼ \""
+
+msgid "\" already exists!"
+msgstr "\"ì´ ì´ë¯¸ 존재합니다!"
+
+msgid "VIM - ATTENTION"
+msgstr "빔 - 주목"
+
+msgid "Swap file already exists!"
+msgstr "스왑 파ì¼ì´ ì´ë¯¸ 존재합니다!"
+
+msgid ""
+"&Open Read-Only\n"
+"&Edit anyway\n"
+"&Recover\n"
+"&Quit\n"
+"&Abort"
+msgstr ""
+"ì½ê¸° 전용으로 열기(&O)\n"
+"그냥 고치기(&E)\n"
+"복구(&R)\n"
+"ë내기(&Q)\n"
+"버리기(&A)"
+
+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)"
+
+msgid "E326: Too many swap files found"
+msgstr "E326: 너무 ë§Žì€ ìŠ¤ì™‘ 파ì¼ì´ 발견ë˜ì—ˆìŠµë‹ˆë‹¤"
+
+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\" 메뉴 ì—†ìŒ"
+
+#. Only a mnemonic or accelerator is not valid.
+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: 구분ìžëŠ” 메뉴 ê²½ë¡œì˜ ë¶€ë¶„ì´ ë  ìˆ˜ 없습니다"
+
+#. Now we have found the matching menu, and we list the mappings
+#. Highlight title
+msgid ""
+"\n"
+"--- Menus ---"
+msgstr ""
+"\n"
+"--- 메뉴 ---"
+
+msgid "Tear off this menu"
+msgstr "ì´ ë©”ë‰´ë¥¼ 떼어냄"
+
+msgid "E333: Menu path must lead to a menu item"
+msgstr "E333: 메뉴 항목 앞ì—는 메뉴 경로가 있어야 합니다"
+
+#, c-format
+msgid "E334: Menu not found: %s"
+msgstr "E334: 메뉴를 ì°¾ì„ ìˆ˜ 없습니다: %s"
+
+#, c-format
+msgid "E335: Menu not defined for %s mode"
+msgstr "E335: %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 "메시지 관리ìž: Bram Moolenaar <Bram@vim.org>"
+
+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 " SPACE/d/j: 화면/페ì´ì§€/ë¼ì¸ 아래로, b/u/k: 위로, q: 종료 "
+
+msgid "Question"
+msgstr "질문"
+
+msgid ""
+"&Yes\n"
+"&No"
+msgstr ""
+"예(&Y)\n"
+"아니오(&N)"
+
+msgid ""
+"&Yes\n"
+"&No\n"
+"Save &All\n"
+"&Discard All\n"
+"&Cancel"
+msgstr ""
+"예(&Y)\n"
+"아니오(&N)\n"
+"ëª¨ë‘ ì €ìž¥(&A)\n"
+"ëª¨ë‘ ë²„ë¦¼(&D)\n"
+"취소(&C)"
+
+msgid "Select Directory dialog"
+msgstr "디렉토리 ì„ íƒ ëŒ€í™”ìƒìž"
+
+msgid "Save File dialog"
+msgstr "íŒŒì¼ ì €ìž¥ 대화ìƒìž"
+
+msgid "Open File dialog"
+msgstr "íŒŒì¼ ì—´ê¸° 대화ìƒìž"
+
+#. TODO: non-GUI file selector here
+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: printf()ì— ì˜ˆìƒëª»í•œ Float ì¸ìž"
+
+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 "ìˆ«ìž ìž…ë ¥í›„ <엔터>나 마우스 í´ë¦­ (숫ìžì—†ìœ¼ë©´ 취소): "
+
+msgid "Type number and <Enter> (empty cancels): "
+msgstr "ìˆ«ìž ìž…ë ¥í›„ <엔터> (숫ìžì—†ìœ¼ë©´ 취소): "
+
+msgid "1 more line"
+msgstr "한 줄 ì´ìƒ"
+
+msgid "1 line less"
+msgstr "한 줄 ì´í•˜"
+
+#, c-format
+msgid "%ld more lines"
+msgstr "%ld 보다 ë§Žì€ ì¤„"
+
+#, c-format
+msgid "%ld fewer lines"
+msgstr "%ld 보다 ì ì€ 줄"
+
+msgid " (Interrupted)"
+msgstr " (중단ë˜ì—ˆìŠµë‹ˆë‹¤)"
+
+msgid "Beep!"
+msgstr "ì‚‘!"
+
+msgid "Vim: preserving files...\n"
+msgstr "ë¹”: íŒŒì¼ ë³´ì¡´ì¤‘...\n"
+
+#. close all memfiles, without deleting
+msgid "Vim: Finished.\n"
+msgstr "ë¹”: ëŒë‚¬ìŠµë‹ˆë‹¤.\n"
+
+msgid "ERROR: "
+msgstr "ì—러: "
+
+#, c-format
+#~ msgid ""
+#~ "\n"
+#~ "[bytes] total alloc-freed %lu-%lu, in use %lu, peak use %lu\n"
+#~ msgstr ""
+
+#, c-format
+#~ msgid ""
+#~ "[calls] total re/malloc()'s %lu, total free()'s %lu\n"
+#~ "\n"
+#~ msgstr ""
+
+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: ì´ìƒí•œ 마우스모양"
+
+msgid "E548: digit expected"
+msgstr "E548: 숫ìžê°€ 필요합니다"
+
+msgid "E549: Illegal percentage"
+msgstr "E549: ì´ìƒí•œ 백분율"
+
+msgid "Enter encryption key: "
+msgstr "암호 키 입력: "
+
+msgid "Enter same key again: "
+msgstr "ê°™ì€ í‚¤ë¥¼ 다시 ìž…ë ¥: "
+
+msgid "Keys don't match!"
+msgstr "키가 맞지 않습니다!"
+
+#, 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: 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: pathì—서 ë” ì´ìƒì˜ \"%s\" 파ì¼ì„ ì°¾ì„ ìˆ˜ 없습니다"
+
+msgid "Cannot connect to Netbeans #2"
+msgstr "Netbeans #2ì— ì—°ê²°í•  수 없습니다"
+
+msgid "Cannot connect to Netbeans"
+msgstr "Netbeansì— ì—°ê²°í•  수 없습니다"
+
+#, c-format
+msgid "E668: Wrong access mode for NetBeans connection info file: \"%s\""
+msgstr "E668: NetBeans ì—°ê²° ì •ë³´ 파ì¼ì´ ì ‘ê·¼ 모드가 잘못ë¨: \"%s\""
+
+msgid "read from Netbeans socket"
+msgstr "Netbeans 소켓ì—서 ì½ê¸°"
+
+#, 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: ì´ GUI는 netbeans를 ì§€ì›í•˜ì§€ 않습니다"
+
+msgid "E511: netbeans already connected"
+msgstr "E511: netbeansê°€ ì´ë¯¸ ì—°ê²°ë˜ì–´ 있습니다"
+
+msgid "E505: "
+msgstr "E505: "
+
+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: changelist가 비었습니다"
+
+#~ msgid "E662: At start of changelist"
+#~ msgstr ""
+
+#~ msgid "E663: At end of changelist"
+#~ msgstr ""
+
+msgid "Type :quit<Enter> to exit Vim"
+msgstr "VIMì„ ë§ˆì¹˜ë ¤ë©´ :quit<Enter> ìž…ë ¥"
+
+#, c-format
+msgid "1 line %sed 1 time"
+msgstr "1 line %sed 1 time"
+
+#, c-format
+msgid "1 line %sed %d times"
+msgstr "1 line %sed %d times"
+
+#, c-format
+msgid "%ld lines %sed 1 time"
+msgstr "%ld lines %sed 1 time"
+
+#, c-format
+msgid "%ld lines %sed %d times"
+msgstr "%ld lines %sed %d times"
+
+#, c-format
+msgid "%ld lines to indent... "
+msgstr "%ld lines to indent... "
+
+msgid "1 line indented "
+msgstr "1 line indented "
+
+#, c-format
+msgid "%ld lines indented "
+msgstr "%ld lines indented "
+
+#~ msgid "E748: No previously used register"
+#~ msgstr ""
+
+#. must display the prompt
+msgid "cannot yank; delete anyway"
+msgstr "cannot yank; delete anyway"
+
+msgid "1 line changed"
+msgstr "1 line changed"
+
+#, c-format
+msgid "%ld lines changed"
+msgstr "%ld lines changed"
+
+#, c-format
+msgid "freeing %ld lines"
+msgstr "freeing %ld lines"
+
+msgid "block of 1 line yanked"
+msgstr "block of 1 line yanked"
+
+msgid "1 line yanked"
+msgstr "1 line yanked"
+
+#, c-format
+msgid "block of %ld lines yanked"
+msgstr "block of %ld lines yanked"
+
+#, c-format
+msgid "%ld lines yanked"
+msgstr "%ld lines yanked"
+
+#, c-format
+msgid "E353: Nothing in register %s"
+msgstr "E353: %s ë ˆì§€ìŠ¤í„°ì— ì•„ë¬´ ê²ƒë„ ì—†ìŠµë‹ˆë‹¤"
+
+#. Highlight title
+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"
+
+#, c-format
+msgid "%ld Cols; "
+msgstr "%ld ì—´; "
+
+#, c-format
+msgid "Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Bytes"
+msgstr "Selected %s%ld of %ld ë¼ì¸; %ld of %ld 단어; %ld of %ld ë°”ì´íЏ"
+
+#, c-format
+msgid ""
+"Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Chars; %ld of %ld "
+"Bytes"
+msgstr ""
+"Selected %s%ld of %ld ë¼ì¸; %ld of %ld 단어; %ld of %ld 문ìž; %ld of %ld ë°”ì´"
+"트"
+
+#, c-format
+msgid "Col %s of %s; Line %ld of %ld; Word %ld of %ld; Byte %ld of %ld"
+msgstr "Col %s of %s; ë¼ì¸ %ld of %ld; 단어 %ld of %ld; ë°”ì´íЏ %ld of %ld"
+
+#, c-format
+msgid ""
+"Col %s of %s; Line %ld of %ld; Word %ld of %ld; Char %ld of %ld; Byte %ld of "
+"%ld"
+msgstr ""
+"Col %s of %s; ë¼ì¸ %ld of %ld; 단어 %ld of %ld; ë¬¸ìž %ld of %ld; ë°”ì´íЏ %ld "
+"of %ld"
+
+#, c-format
+msgid "(+%ld for BOM)"
+msgstr "(+%ld for BOM)"
+
+msgid "%<%f%h%m%=Page %N"
+msgstr "%<%f%h%m%=페ì´ì§€ %N"
+
+msgid "Thanks for flying Vim"
+msgstr "ë¹”ì„ ë‚ ê²Œ í•´ 주셔서 고맙습니다"
+
+msgid "E518: Unknown option"
+msgstr "E518: 모르는 옵션"
+
+msgid "E519: Option not supported"
+msgstr "E519: ì§€ì›ë˜ì§€ 않는 옵션입니다"
+
+msgid "E520: Not allowed in a modeline"
+msgstr "E520: 모드ë¼ì¸ì—서 ì‚¬ìš©ë  ìˆ˜ 없습니다"
+
+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>"
+
+msgid "E529: Cannot set 'term' to empty string"
+msgstr "E529: 'term'ì„ ë¹ˆ 문ìžì—´ë¡œ 설정할 수 없습니다"
+
+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'ê°€ ë™ì¼í•©ë‹ˆë‹¤"
+
+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ì—서는 바뀔 수 없습니다"
+
+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: ê¸€ê¼´ì…‹ì„ ê³ ë¥¼ 수 없습니다"
+
+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> ë’¤ì— ì´ìƒí•œ 글ìž"
+
+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 "E590: A preview window already exists"
+msgstr "E590: 미리 보기 ì°½ì´ ì´ë¯¸ 존재합니다"
+
+msgid "W17: Arabic requires UTF-8, do ':set encoding=utf-8'"
+msgstr "W17: Arabicì€ UTF-8 ì¸ì½”딩 í•„ìš”, ':set encoding=utf-8' 하세요"
+
+#, 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"
+
+#. 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.
+#, 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 "cannot open "
+
+msgid "VIM: Can't open window!\n"
+msgstr "ë¹”: ì°½ì„ ì—´ 수 없습니다!\n"
+
+msgid "Need Amigados version 2.04 or later\n"
+msgstr "아미가ë„스 2.04나 ë” ë†’ì€ íŒì´ 필요합니다\n"
+
+#, c-format
+msgid "Need %s version %ld\n"
+msgstr "Need %s version %ld\n"
+
+msgid "Cannot open NIL:\n"
+msgstr "NILì„ ì—´ 수 ì—†ìŒ:\n"
+
+msgid "Cannot create "
+msgstr "Cannot create "
+
+#, c-format
+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"
+
+#. if Vim opened a window: Executing a shell may cause crashes
+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: 프린터를 고르지 못했습니다"
+
+#, c-format
+msgid "to %s on %s"
+msgstr "to %s on %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 "E245: Illegal char '%c' in font name \"%s\""
+msgstr "E245: ìž˜ëª»ëœ ê¸€ìž '%c'ì´(ê°€) 글꼴 ì´ë¦„ \"%s\"ì— ìžˆìŠµë‹ˆë‹¤"
+
+msgid "Vim: Double signal, exiting\n"
+msgstr "ë¹”: ê°™ì€ ì‹œê·¸ë„ ë‘ ë²ˆ, ë냅니다\n"
+
+#, c-format
+msgid "Vim: Caught deadly signal %s\n"
+msgstr "ë¹”: %s 시그ë„ì„ ìž¡ì•˜ìŠµë‹ˆë‹¤\n"
+
+#, c-format
+msgid "Vim: Caught deadly signal\n"
+msgstr "ë¹”: ì£½ì„ ì‹œê·¸ë„ì„ ìž¡ì•˜ìŠµë‹ˆë‹¤\n"
+
+#, c-format
+msgid "Opening the X display took %ld msec"
+msgstr "X 디스플레ì´ë¥¼ 여는 ë° %ld 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"
+"Could not get security context for "
+msgstr ""
+"\n"
+"Could not get security context for "
+
+msgid ""
+"\n"
+"Could not set security context for "
+msgstr ""
+"\n"
+"Could not set security context for "
+
+msgid ""
+"\n"
+"Cannot execute shell "
+msgstr ""
+"\n"
+"Cannot execute shell "
+
+msgid ""
+"\n"
+"Cannot execute shell sh\n"
+msgstr ""
+"\n"
+"쉘 sh를 실행할 수 없습니다\n"
+
+msgid ""
+"\n"
+"shell returned "
+msgstr ""
+"\n"
+"shell returned "
+
+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 ì—°ê²°ì„ ìžƒì–´ë²„ë ¸ìŠµë‹ˆë‹¤"
+
+#, c-format
+msgid "dlerror = \"%s\""
+msgstr "dlerror = \"%s\""
+
+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 ì—°ê²° ê°ì‹œë¥¼ 실패했습니다"
+
+#, c-format
+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로 바꿀 수 없습니다!"
+
+#, c-format
+msgid "shell returned %d"
+msgstr "ì‰˜ì´ %dì„(를) ëŒë ¤ì£¼ì—ˆìŠµë‹ˆë‹¤"
+
+#, c-format
+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 "빔 경고"
+
+#, 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: ë” ì´ìƒì˜ í•­ëª©ì´ ì—†ìŠµë‹ˆë‹¤"
+
+#, c-format
+msgid "(%d of %d)%s%s: "
+msgstr "(%d of %d)%s%s: "
+
+msgid " (line deleted)"
+msgstr " (ì¤„ì„ ì§€ì› ìŒ)"
+
+msgid "E380: At bottom of quickfix stack"
+msgstr "E380: 퀵픽스 스íƒì˜ 바닥입니다"
+
+msgid "E381: At top of quickfix stack"
+msgstr "E381: 퀵픽스 스íƒì˜ 꼭대기입니다"
+
+#, c-format
+msgid "error list %d of %d; %d errors"
+msgstr "error list %d of %d; %d errors"
+
+msgid "E382: Cannot write, 'buftype' option is set"
+msgstr "E382: 쓸 수 ì—†ìŒ, 'buftype' ì˜µì…˜ì´ ì„¤ì •ë˜ì–´ 있습니다"
+
+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%%[]ì— ìž˜ëª»ëœ í•­ëª©"
+
+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 "E53: Unmatched %s%%("
+msgstr "E53: 맞지 않는 %s%%("
+
+#, c-format
+msgid "E54: Unmatched %s("
+msgstr "E54: 맞지 않는 %s("
+
+#, c-format
+msgid "E55: Unmatched %s)"
+msgstr "E55: 맞지 않는 %s)"
+
+#, 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: Nested %s*"
+
+#, c-format
+msgid "E62: Nested %s%c"
+msgstr "E62: Nested %s%c"
+
+msgid "E63: invalid use of \\_"
+msgstr "E63: \\_를 잘 못 사용"
+
+#, c-format
+msgid "E64: %s%c follows nothing"
+msgstr "E64: %s%c ë’¤ì— ì•„ë¬´ê²ƒë„ ì—†ìŠµë‹ˆë‹¤"
+
+msgid "E65: Illegal back reference"
+msgstr "E65: ì´ìƒí•œ 후위 참조"
+
+msgid "E66: \\z( not allowed here"
+msgstr "E66: \\z(는 여기ì—서 허용ë˜ì§€ 않습니다"
+
+msgid "E67: \\z1 et al. not allowed here"
+msgstr "E67: \\z1 ë“±ì€ ì—¬ê¸°ì—서 허용ë˜ì§€ 않습니다"
+
+msgid "E68: Invalid character after \\z"
+msgstr "E68: \\z ë’¤ì— ì´ìƒí•œ 문ìž"
+
+#, c-format
+msgid "E69: Missing ] after %s%%["
+msgstr "E69: %s%%[ ë’¤ì— ]ê°€ 없습니다"
+
+#, c-format
+msgid "E70: Empty %s%%[]"
+msgstr "E70: 빈 %s%%[]"
+
+#, 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 "E769: Missing ] after %s["
+msgstr "E769: %s[ ë’¤ì— ]ê°€ 없습니다"
+
+#, c-format
+msgid "E554: Syntax error in %s{...}"
+msgstr "E554: %s{...}ì— êµ¬ë¬¸ ì—러"
+
+msgid "External submatches:\n"
+msgstr "외부 submatches:\n"
+
+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 " (lang)"
+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 " (ì´ì „ì— ë§žì•˜ë˜ ëª©ë¡ í¬í•¨)"
+
+#. cursor at status line
+msgid "--- Included files "
+msgstr "--- Included files "
+
+msgid "not found "
+msgstr "not found "
+
+msgid "in path ---\n"
+msgstr "in path ---\n"
+
+msgid " (Already listed)"
+msgstr " (Already listed)"
+
+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 "Substitute "
+
+#, c-format
+msgid ""
+"\n"
+"# Last %sSearch Pattern:\n"
+"~"
+msgstr ""
+"\n"
+"# Last %sSearch Pattern:\n"
+"~"
+
+msgid "E759: Format error in spell file"
+msgstr "E759: spell íŒŒì¼ í˜•ì‹ ì—러"
+
+msgid "E758: Truncated spell file"
+msgstr "E758: 잘린 spell 파ì¼"
+
+#, c-format
+msgid "Trailing text in %s line %d: %s"
+msgstr "Trailing text in %s line %d: %s"
+
+#, c-format
+msgid "Affix name too long in %s line %d: %s"
+msgstr "Affix name too long in %s line %d: %s"
+
+msgid "E761: Format error in affix file FOL, LOW or UPP"
+msgstr "E761: affix íŒŒì¼ 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 "단어 트리 압축중..."
+
+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\"ì„ ì°¾ì„ ìˆ˜ 없습니다"
+
+#, c-format
+msgid "Reading spell file \"%s\""
+msgstr "spell íŒŒì¼ \"%s\"ì„(를) ì½ê³  있습니다"
+
+msgid "E757: This does not look like a spell file"
+msgstr "E757: spell 파ì¼ì´ 아닌 것 같습니다"
+
+msgid "E771: Old spell file, needs to be updated"
+msgstr "E771: ì˜¤ëž˜ëœ spell 파ì¼, ê°±ì‹ ì´ í•„ìš”í•©ë‹ˆë‹¤"
+
+msgid "E772: Spell file is for newer version of Vim"
+msgstr "E772: Spell 파ì¼ì´ 새 ë²„ì ¼ì˜ Vim용입니다"
+
+msgid "E770: Unsupported section in spell file"
+msgstr "E770: spell 파ì¼ì— ì§€ì›ë˜ì§€ 않는 섹션"
+
+#, c-format
+msgid "Warning: region %s not supported"
+msgstr "경고: %s ì˜ì—­ì€ ì§€ì›ë˜ì§€ 않습니다"
+
+#, c-format
+msgid "Reading affix file %s ..."
+msgstr "affix íŒŒì¼ %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 "%s ë¼ì¸ %dì— FLAGì— ëŒ€í•œ ìž˜ëª»ëœ ê°’: %s"
+
+#, c-format
+msgid "FLAG after using flags in %s line %d: %s"
+msgstr "%s ë¼ì¸ %dì— í”Œëž˜ê·¸ê°€ ì‚¬ìš©ëœ í›„ FLAG: %s"
+
+#, c-format
+msgid ""
+"Defining COMPOUNDFORBIDFLAG after PFX item may give wrong results in %s line "
+"%d"
+msgstr ""
+"%s ë¼ì¸ %dì— PFX ë’¤ì— COMPOUNDFORBIDFLAGì„ ì •ì˜í•œ ê²ƒì€ ìž˜ëª»ëœ ê²°ê³¼ë¥¼ 초래할 "
+"수 있습니다"
+
+#, c-format
+msgid ""
+"Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in %s line "
+"%d"
+msgstr ""
+"%s ë¼ì¸ %dì— PFX ë’¤ì— COMPOUNDPERMITFLAGì„ ì •ì˜í•œ ê²ƒì€ ìž˜ëª»ëœ ê²°ê³¼ë¥¼ 초래할 "
+"수 있습니다"
+
+#, c-format
+msgid "Wrong COMPOUNDRULES value in %s line %d: %s"
+msgstr "%s ë¼ì¸ %dì— ìž˜ëª»ëœ COMPOUNDRULES ê°’: %s"
+
+#, c-format
+msgid "Wrong COMPOUNDWORDMAX value in %s line %d: %s"
+msgstr "%s ë¼ì¸ %dì— ìž˜ëª»ëœ COMPOUNDWORDMAX ê°’: %s"
+
+#, c-format
+msgid "Wrong COMPOUNDMIN value in %s line %d: %s"
+msgstr "%s ë¼ì¸ %dì— ìž˜ëª»ëœ COMPOUNDMIN ê°’: %s"
+
+#, c-format
+msgid "Wrong COMPOUNDSYLMAX value in %s line %d: %s"
+msgstr "%s ë¼ì¸ %dì— ìž˜ëª»ëœ COMPOUNDSYLMAX ê°’: %s"
+
+#, c-format
+msgid "Wrong CHECKCOMPOUNDPATTERN value in %s line %d: %s"
+msgstr "%s ë¼ì¸ %dì— ìž˜ëª»ëœ CHECKCOMPOUNDPATTERN ê°’: %s"
+
+#, c-format
+msgid "Different combining flag in continued affix block in %s line %d: %s"
+msgstr "%s ë¼ì¸ %dì— ì—°ì†ëœ affix 블ë¡ì— 다른 ê²°í•© 플래그: %s"
+
+#, c-format
+msgid "Duplicate affix in %s line %d: %s"
+msgstr "%s ë¼ì¸ %dì— ì¤‘ë³µëœ affix: %s"
+
+#, 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"
+
+#, c-format
+msgid "Expected Y or N in %s line %d: %s"
+msgstr "%s ë¼ì¸ %dì— Y나 Nì´ ê¸°ëŒ€ë¨: %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 "%s ë¼ì¸ %dì— REP(SAL) 카운트가 기대ë¨"
+
+#, c-format
+msgid "Expected MAP count in %s line %d"
+msgstr "%s ë¼ì¸ %dì— MAP 카운트가 기대ë¨"
+
+#, c-format
+msgid "Duplicate character in MAP in %s line %d"
+msgstr "%s ë¼ì¸ %dì˜ MAPì— ì¤‘ë³µëœ ë¬¸ìž"
+
+#, 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 "%sì— FOL/LOW/UPPì´ ëˆ„ë½ëœ ë¼ì¸"
+
+msgid "COMPOUNDSYLMAX used without SYLLABLE"
+msgstr "COMPOUNDSYLMAXì´ SYLLABLEì—†ì´ ì‚¬ìš©ë¨"
+
+msgid "Too many postponed prefixes"
+msgstr "postponed ì ‘ë‘사가 너무 많습니다"
+
+msgid "Too many compound flags"
+msgstr "compound 플래그가 너무 많습니다"
+
+msgid "Too many postponed prefixes and/or compound flags"
+msgstr "postponed ì ‘ë‘사와(나) compound 플래그가 너무 많습니다"
+
+#, c-format
+msgid "Missing SOFO%s line in %s"
+msgstr "SOFO%sê°€ 누ë½ëœ ë¼ì¸ì´ %sì— ìžˆìŠµë‹ˆë‹¤"
+
+#, c-format
+msgid "Both SAL and SOFO lines in %s"
+msgstr "%sì— SALê³¼ SOFO ë¼ì¸ì´ 둘 다 있습니다"
+
+#, 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 %6d - %s"
+msgstr "ë¼ì¸ %6d, 단어 %6d - %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ê°œì˜ ì•„ìŠ¤í‚¤ë¬¸ìžì—´ì´ 아닌 단어가 %sì— ìžˆìŠµë‹ˆë‹¤"
+
+#, c-format
+msgid "Reading word file %s ..."
+msgstr "단어 íŒŒì¼ %s ì½ëŠ” 중 ..."
+
+#, c-format
+msgid "Duplicate /encoding= line ignored in %s line %d: %s"
+msgstr "%s ë¼ì¸ %dì˜ ì¤‘ë³µëœ /encoding= ë¼ì¸ 무시ë¨: %s"
+
+#, c-format
+msgid "/encoding= line after word ignored in %s line %d: %s"
+msgstr "%s ë¼ì¸ %dì˜ ë‹¨ì–´ ë’¤ì˜ /encoding= ë¼ì¸ 무시ë¨: %s"
+
+#, c-format
+msgid "Duplicate /regions= line ignored in %s line %d: %s"
+msgstr "%s ë¼ì¸ %dì˜ ì¤‘ë³µëœ /regions= ë¼ì¸ 무시ë¨: %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ê°œì˜ ë‹¨ì–´ê°€ 무시ë˜ì—ˆìŠµë‹ˆë‹¤"
+
+#~ msgid "E845: Insufficient memory, word list will be incomplete"
+#~ msgstr ""
+
+#, c-format
+msgid "Compressed %d of %d nodes; %d (%d%%) remaining"
+msgstr "%d/%d 노드가 ì••ì¶•ë¨; %d (%d%%)ê°€ 남ìŒ"
+
+msgid "Reading back spell file..."
+msgstr "맞춤법 파ì¼ì„ ì½ëŠ” 중..."
+
+#.
+#. * Go through the trie of good words, soundfold each word and add it to
+#. * the soundfold trie.
+#.
+msgid "Performing soundfolding..."
+msgstr "soundfold 수행중..."
+
+#, c-format
+msgid "Number of words after soundfolding: %ld"
+msgstr "soundfold 수행 í›„ì˜ ë‹¨ì–´ 수: %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: ìƒì„± 파ì¼ëª…ì€ ì˜ì—­ ì´ë¦„ê³¼ 달ë¼ì•¼ 합니다"
+
+msgid "E754: Only up to 8 regions supported"
+msgstr "E754: 최대 8ê°œì˜ ì˜ì—­ì´ ì§€ì›ë©ë‹ˆë‹¤"
+
+#, c-format
+msgid "E755: Invalid region in %s"
+msgstr "E755: %sì— ìž˜ëª»ëœ ì˜ì—­"
+
+msgid "Warning: both compounding and NOBREAK specified"
+msgstr "경고: compound와 NOBREAK 둘 다 명시ë¨"
+
+#, c-format
+msgid "Writing spell file %s ..."
+msgstr "spell íŒŒì¼ %s 쓰는 중 ..."
+
+msgid "Done!"
+msgstr "ë!"
+
+#, c-format
+msgid "E765: 'spellfile' does not have %ld entries"
+msgstr "E765: 'spellfile'ì— %ld í•­ëª©ì´ ì—†ìŠµë‹ˆë‹¤"
+
+#, c-format
+msgid "Word removed from %s"
+msgstr "%sì—서 단어 ì‚­ì œë¨"
+
+#, c-format
+msgid "Word added to %s"
+msgstr "%sì— ë‹¨ì–´ 추가ë¨"
+
+msgid "E763: Word characters differ between spell files"
+msgstr "E763: 단어가 spell íŒŒì¼ ê°„ì— ë‹¤ë¦…ë‹ˆë‹¤"
+
+msgid "Sorry, no suggestions"
+msgstr "죄송, 제안할 게 없습니다"
+
+#, c-format
+msgid "Sorry, only %ld suggestions"
+msgstr "죄송, %ld개만 제안"
+
+#. for when 'cmdheight' > 1
+#. avoid more prompt
+#, c-format
+msgid "Change \"%.*s\" to:"
+msgstr "Change \"%.*s\" to:"
+
+#, c-format
+msgid " < \"%.*s\""
+msgstr " < \"%.*s\""
+
+msgid "E752: No previous spell replacement"
+msgstr "E752: ì² ìžê°€ ë°”ë€ì ì´ 없습니다"
+
+#, c-format
+msgid "E753: Not found: %s"
+msgstr "E753: ì°¾ì„ ìˆ˜ ì—†ìŒ: %s"
+
+#, 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"
+
+#. This should have been checked when generating the .spl
+#. * file.
+msgid "E783: duplicate char in MAP entry"
+msgstr "E783: MAP í•­ëª©ì— ì¤‘ë³µëœ ë¬¸ìž"
+
+#, c-format
+msgid "E390: Illegal argument: %s"
+msgstr "E390: ìž˜ëª»ëœ ì¸ìž: %s"
+
+#, c-format
+msgid "E391: No such syntax cluster: %s"
+msgstr "E391: ì´ëŸ° 구문 í´ëŸ¬ìŠ¤í„°ëŠ” 없습니다: %s"
+
+msgid "No Syntax items defined for this buffer"
+msgstr "ì´ ë²„í¼ì— 대해 ì •ì˜ëœ 구문 í•­ëª©ì´ ì—†ìŠµë‹ˆë‹¤"
+
+msgid "syncing on C-style comments"
+msgstr "C-í˜•ì‹ ì£¼ì„ë¬¸ì— ë™ê¸°ë§žì¶¤"
+
+msgid "no syncing"
+msgstr "ë™ê¸°ë§žì¶¤ ì—†ìŒ"
+
+msgid "syncing starts "
+msgstr "syncing starts "
+
+msgid " lines before top line"
+msgstr " lines before top line"
+
+msgid ""
+"\n"
+"--- Syntax sync items ---"
+msgstr ""
+"\n"
+"--- Syntax sync 항목들 ---"
+
+msgid ""
+"\n"
+"syncing on items"
+msgstr ""
+"\n"
+"syncing on items"
+
+msgid ""
+"\n"
+"--- Syntax items ---"
+msgstr ""
+"\n"
+"--- Syntax 항목 ---"
+
+#, c-format
+msgid "E392: No such syntax cluster: %s"
+msgstr "E392: ì´ëŸ° 구문 í´ëŸ¬ìŠ¤í„°ëŠ” 없습니다: %s"
+
+msgid "minimal "
+msgstr "minimal "
+
+msgid "maximal "
+msgstr "maximal "
+
+msgid "; match "
+msgstr "; match "
+
+msgid " line breaks"
+msgstr " line breaks"
+
+msgid "E395: contains argument not accepted here"
+msgstr "E395: contains ì¸ìžëŠ” ì—¬ê¸°ì— ì“¸ 수 없습니다"
+
+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ì— ëŒ€í•œ region í•­ëª©ì„ ì°¾ì§€ 못했습니다"
+
+msgid "E397: Filename required"
+msgstr "E397: 파ì¼ì´ë¦„ì´ í•„ìš”í•©ë‹ˆë‹¤"
+
+#, c-format
+msgid "E789: Missing ']': %s"
+msgstr "E789: ']' 누ë½: %s"
+
+#, c-format
+msgid "E398: Missing '=': %s"
+msgstr "E398: '=' 누ë½: %s"
+
+#, c-format
+msgid "E399: Not enough arguments: syntax region %s"
+msgstr "E399: 충분치 ì•Šì€ ì¸ìž: 구문 ì˜ì—­ %s"
+
+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: syntax sync: 줄 ì—°ì† íŒ¨í„´ì´ ë‘ ë²ˆ 사용ë˜ì—ˆìŠµë‹ˆë‹¤"
+
+#, 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 "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: groupì´ ì„¤ì •ê°’ì´ ìžˆìŠµë‹ˆë‹¤, 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 "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 kind tag"
+
+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\"ì´(ê°€) 존재하지 않습니다"
+
+#. Give an indication of the number of matching tags
+#, c-format
+msgid "tag %d of %d%s"
+msgstr "tag %d of %d%s"
+
+msgid " or more"
+msgstr " or more"
+
+msgid " Using tag with different case!"
+msgstr " Using tag with different case!"
+
+#, c-format
+msgid "E429: File \"%s\" does not exist"
+msgstr "E429: íŒŒì¼ \"%s\"ì´(ê°€) 존재하지 않습니다"
+
+#. Highlight title
+msgid ""
+"\n"
+" # TO tag FROM line in file/text"
+msgstr ""
+"\n"
+" # TO tag FROM line in file/text"
+
+#, c-format
+msgid "Searching tags file %s"
+msgstr "태그 íŒŒì¼ %s 찾는 중"
+
+#, c-format
+msgid "E430: Tag file path truncated for %s\n"
+msgstr "E430: %sì— ëŒ€í•œ 태그 íŒŒì¼ ê²½ë¡œê°€ 잘렸습니다\n"
+
+#, c-format
+msgid "E431: Format error in tags file \"%s\""
+msgstr "E431: 태그 íŒŒì¼ \"%s\"ì— í˜•ì‹ ì—러가 있습니다"
+
+#, c-format
+msgid "Before byte %ld"
+msgstr "Before byte %ld"
+
+#, c-format
+msgid "E432: Tags file not sorted: %s"
+msgstr "E432: 태그 파ì¼ì´ ì •ë ¬ë˜ì–´ 있지 않ìŒ: %s"
+
+#. never opened any tags file
+msgid "E433: No tags file"
+msgstr "E433: 태그 파ì¼ì´ 없습니다"
+
+msgid "Ignoring long line in tags file"
+msgstr "태그 파ì¼ì˜ 너무 긴 ë¼ì¸ì„ 무시합니다"
+
+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 "' not known. Available builtin terminals are:"
+
+msgid "defaulting to '"
+msgstr "defaulting to '"
+
+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: termcapì— \"%s\" í•­ëª©ì´ ì—†ìŠµë‹ˆë‹¤"
+
+msgid "E437: terminal capability \"cm\" required"
+msgstr "E437: 터미ë„ì´ \"cm\" ê¸°ëŠ¥ì„ ì§€ì›í•´ì•¼ 합니다"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Terminal keys ---"
+msgstr ""
+"\n"
+"--- í„°ë¯¸ë„ í‚¤ ---"
+
+msgid "new shell started\n"
+msgstr "새 ì‰˜ì´ ì‹œìž‘ë˜ì—ˆìŠµë‹ˆë‹¤\n"
+
+msgid "Vim: Error reading input, exiting...\n"
+msgstr "ë¹”: ìž…ë ¥ ì½ëŠ” 중 ì—러, ë내는중...\n"
+
+msgid "Used CUT_BUFFER0 instead of empty selection"
+msgstr "빈 고르기 대신 CUT_BUFFER0ì„ ì‚¬ìš©í–ˆìŠµë‹ˆë‹¤"
+
+#. This happens when the FileChangedRO autocommand changes the
+#. * file in a way it becomes shorter.
+msgid "E834: Line count changed unexpectedly"
+msgstr "E834: 줄 갯수가 모르는 사ì´ì— 바뀌었습니다"
+
+#. must display the prompt
+msgid "No undo possible; continue anyway"
+msgstr "취소 불가능; 어쨌든 계ì†í•©ë‹ˆë‹¤"
+
+#, c-format
+msgid "E828: Cannot open undo file for writing: %s"
+msgstr "E828: 쓰기 위해 undoì„ ì—´ 수 없습니다: %s"
+
+#, c-format
+msgid "E825: Corrupted undo file (%s): %s"
+msgstr "E825: 깨진 undo íŒŒì¼ (%s): %s"
+
+msgid "Cannot write undo file in any directory in 'undodir'"
+msgstr "'undodir'ì— ìžˆëŠ” ì–´ë–¤ 디렉토리ì—ë„ undo 파ì¼ì„ 쓸 수 없습니다"
+
+#, c-format
+msgid "Will not overwrite with undo file, cannot read: %s"
+msgstr "ì½ì„ 수가 없어서 undo 파ì¼ì— ë®ì–´ì“¸ 수 없습니다: %s"
+
+#, c-format
+msgid "Will not overwrite, this is not an undo file: %s"
+msgstr "undo 파ì¼ì´ 아니어서 ë®ì–´ì“¸ 수 없습니다: %s"
+
+msgid "Skipping undo file write, nothing to undo"
+msgstr "undoí•  ë‚´ìš©ì´ ì—†ì–´ì„œ undo íŒŒì¼ ì €ìž¥ì„ ê±´ë„ˆëœë‹ˆë‹¤"
+
+#, c-format
+msgid "Writing undo file: %s"
+msgstr "undo íŒŒì¼ ì“°ëŠ” 중: %s"
+
+#, c-format
+msgid "E829: write error in undo file: %s"
+msgstr "E829: undo íŒŒì¼ ì“°ê¸° ì—러: %s"
+
+#, c-format
+msgid "Not reading undo file, owner differs: %s"
+msgstr "소유ìžê°€ 달ë¼ì„œ undo 파ì¼ì„ ì½ì§€ 않습니다: %s"
+
+#, c-format
+msgid "Reading undo file: %s"
+msgstr "undo íŒŒì¼ ì½ëŠ” 중: %s"
+
+#, c-format
+msgid "E822: Cannot open undo file for reading: %s"
+msgstr "E822: ì½ê¸° 위해 undo 파ì¼ì„ ì—´ 수 없습니다: %s"
+
+#, c-format
+msgid "E823: Not an undo file: %s"
+msgstr "E823: undo 파ì¼ì´ 아닙니다: %s"
+
+#, c-format
+msgid "E832: Non-encrypted file has encrypted undo file: %s"
+msgstr "E832: 암호화ë˜ì§€ ì•Šì€ íŒŒì¼ì´ ì•”í˜¸í™”ëœ undo 파ì¼ì„ 가지고 있습니다: %s"
+
+#, c-format
+msgid "E826: Undo file decryption failed: %s"
+msgstr "E826: Undo 파ì¼ì„ í•´ë…í•  수 없습니다: %s"
+
+#, c-format
+msgid "E827: Undo file is encrypted: %s"
+msgstr "E827: Undo 파ì¼ì´ 암호화ë˜ì—ˆìŠµë‹ˆë‹¤: %s"
+
+#, c-format
+msgid "E824: Incompatible undo file: %s"
+msgstr "E824: 호환ë˜ì§€ 않는 undo 파ì¼: %s"
+
+msgid "File contents changed, cannot use undo info"
+msgstr "íŒŒì¼ ë‚´ìš©ì´ ë°”ë€Œì–´ì„œ, undo 정보를 사용할 수 없습니다"
+
+#, c-format
+msgid "Finished reading undo file %s"
+msgstr "undo íŒŒì¼ %sì„(를) ì½ì–´ë“¤ì˜€ìŠµë‹ˆë‹¤"
+
+msgid "Already at oldest change"
+msgstr "ë” ì´ìƒì˜ ìˆ˜ì •ì´ ì—†ì—ˆìŠµë‹ˆë‹¤"
+
+msgid "Already at newest change"
+msgstr "ë” ì´ìƒì˜ ìˆ˜ì •ì€ ì—†ì—ˆìŠµë‹ˆë‹¤"
+
+#, c-format
+msgid "E830: Undo number %ld not found"
+msgstr "E830: Undo 번호 %ld를 ì°¾ì„ ìˆ˜ 없습니다"
+
+msgid "E438: u_undo: line numbers wrong"
+msgstr "E438: u_undo: ìž˜ëª»ëœ ì¤„ 번호"
+
+msgid "more line"
+msgstr "more line"
+
+msgid "more lines"
+msgstr "more lines"
+
+msgid "line less"
+msgstr "line less"
+
+msgid "fewer lines"
+msgstr "fewer lines"
+
+msgid "change"
+msgstr "change"
+
+msgid "changes"
+msgstr "changes"
+
+#, c-format
+msgid "%ld %s; %s #%ld %s"
+msgstr "%ld %s; %s #%ld %s"
+
+msgid "before"
+msgstr "before"
+
+msgid "after"
+msgstr "after"
+
+msgid "Nothing to undo"
+msgstr "취소할 게 없습니다"
+
+#~ msgid "number changes when saved"
+#~ msgstr ""
+
+#, c-format
+msgid "%ld seconds ago"
+msgstr "%ld seconds ago"
+
+msgid "E790: undojoin is not allowed after undo"
+msgstr "E790: undo ë’¤ì— undojoinì€ í•  수 없습니다"
+
+msgid "E439: undo list corrupt"
+msgstr "E439: undo 목ë¡ì´ 깨졌습니다"
+
+msgid "E440: undo line missing"
+msgstr "E440: undo ì¤„ì´ ì—†ìŠµë‹ˆë‹¤"
+
+#. Only MS VC 4.1 and earlier can do Win32s
+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"
+"Included patches: "
+msgstr ""
+"\n"
+"í¬í•¨ëœ 패치: "
+
+msgid ""
+"\n"
+"Extra patches: "
+msgstr ""
+"\n"
+"별ë„ì˜ íŒ¨ì¹˜: "
+
+msgid "Modified by "
+msgstr "Modified by "
+
+msgid ""
+"\n"
+"Compiled "
+msgstr ""
+"\n"
+"Compiled "
+
+msgid "by "
+msgstr "by "
+
+msgid ""
+"\n"
+"Huge version "
+msgstr ""
+"\n"
+"Huge 버젼 "
+
+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 "without GUI."
+msgstr "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 "with (classic) GUI."
+msgstr "(í´ëž˜ì‹) GUI."
+
+msgid " Features included (+) or not (-):\n"
+msgstr " 기능 (+: í¬í•¨ë¨, -: í¬í•¨ 안 ë¨):\n"
+
+msgid " system vimrc file: \""
+msgstr " 시스템 vimrc 파ì¼: \""
+
+msgid " user vimrc file: \""
+msgstr " ì‚¬ìš©ìž vimrc 파ì¼: \""
+
+msgid " 2nd user vimrc file: \""
+msgstr " ì‚¬ìš©ìž ë‘ ë²ˆì§¸ vimrc 파ì¼: \""
+
+msgid " 3rd user vimrc file: \""
+msgstr " ì‚¬ìš©ìž ì„¸ 번째 vimrc 파ì¼: \""
+
+msgid " user exrc file: \""
+msgstr " ì‚¬ìš©ìž exrc 파ì¼: \""
+
+msgid " 2nd user exrc file: \""
+msgstr " ì‚¬ìš©ìž ë‘ ë²ˆì§¸ exrc 파ì¼: \""
+
+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 " fall-back for $VIM: \""
+msgstr " fall-back for $VIM: \""
+
+msgid " f-b for $VIMRUNTIME: \""
+msgstr " f-b for $VIMRUNTIME: \""
+
+msgid "Compilation: "
+msgstr "컴파ì¼: "
+
+msgid "Compiler: "
+msgstr "컴파ì¼ëŸ¬: "
+
+msgid "Linking: "
+msgstr "ë§í¬: "
+
+msgid " DEBUG BUILD"
+msgstr " 디버그 빌드"
+
+msgid "VIM - Vi IMproved"
+msgstr "ë¹” - í–¥ìƒëœ Vi"
+
+msgid "version "
+msgstr "íŒ "
+
+msgid "by Bram Moolenaar et al."
+msgstr "by Bram Moolenaar et al."
+
+msgid "Vim is open source and freely distributable"
+msgstr "ë¹”ì€ ì†ŒìŠ¤ê°€ ì—´ë ¤ 있고 공짜로 ë°°í¬ë©ë‹ˆë‹¤"
+
+msgid "Help poor children in Uganda!"
+msgstr "ìš°ê°„ë‹¤ì— ì‚¬ëŠ” 가난한 ì•„ì´ë¥¼ ë„와주세요!"
+
+msgid "type :help iccf<Enter> for information "
+msgstr "ì´ì— 대한 정보를 보려면 :help iccf<엔터> ìž…ë ¥"
+
+msgid "type :q<Enter> to exit "
+msgstr "ë내려면 :q<엔터> ìž…ë ¥"
+
+msgid "type :help<Enter> or <F1> for on-line help"
+msgstr "온ë¼ì¸ ë„움ë§ì„ 보려면 :help<엔터> ë˜ëŠ” <F1> ìž…ë ¥"
+
+msgid "type :help version7<Enter> for version info"
+msgstr "íŒ ì •ë³´ë¥¼ 보려면 :help version7<엔터> ìž…ë ¥"
+
+msgid "Running in Vi compatible mode"
+msgstr "Vi 호환 ìƒíƒœë¡œ 실행중입니다"
+
+msgid "type :set nocp<Enter> for Vim defaults"
+msgstr "ë¹” ê¸°ë³¸ê°’ì„ ì‚¬ìš©í•˜ë ¤ë©´ :set nocp<엔터> ìž…ë ¥"
+
+msgid "type :help cp-default<Enter> for info on this"
+msgstr "ì´ì— 대한 정보를 보려면 :help cp-default<엔터> ìž…ë ¥"
+
+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 "ë¹” ê°œë°œì„ í›„ì›í•´ 주세요!"
+
+msgid "Become a registered Vim user!"
+msgstr "ë¹” 사용ìžë¡œ 등ë¡í•˜ì„¸ìš”!"
+
+msgid "type :help sponsor<Enter> for information "
+msgstr "ì´ì— 대한 정보를 보려면 :help sponsor<엔터> ìž…ë ¥"
+
+msgid "type :help register<Enter> for information "
+msgstr "ì´ì— 대한 정보를 보려면 :help register<엔터> ìž…ë ¥"
+
+msgid "menu Help->Sponsor/Register for information "
+msgstr "ì´ì— 대한 정보를 보려면 메뉴 ë„움ë§->Sponsor/Register"
+
+msgid "WARNING: Windows 95/98/ME detected"
+msgstr "경고: 윈ë„우즈 95/98/ME를 찾았ìŒ"
+
+msgid "type :help windows95<Enter> for info on this"
+msgstr "ì´ì— 대한 정보를 보려면 :help windows95<엔터> ìž…ë ¥"
+
+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: 위 왼쪽과 아래 ì˜¤ë¥¸ìª½ì„ ë™ì‹œì— 나눌 수 없습니다"
+
+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: pathì—서 \"%s\" 파ì¼ì„ ì°¾ì„ ìˆ˜ 없습니다"
+
+#, 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 모듈없ì´ëŠ” 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)"
+
+#. Now concatenate
+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 "--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.
+#.
+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: :whileì—†ì´ :endwhileì´ ìžˆìŠµë‹ˆë‹¤"
+
+msgid "E588: :endfor without :for"
+msgstr "E588: :for 없는 :endfor"
+
+msgid "E13: File exists (add ! to override)"
+msgstr "E13: 파ì¼ì´ 있습니다 (ë®ì–´ì“°ë ¤ë©´ ! 사용)"
+
+msgid "E472: Command failed"
+msgstr "E472: ëª…ë ¹ì´ ì‹¤íŒ¨í–ˆìŠµë‹ˆë‹¤"
+
+#, c-format
+msgid "E234: Unknown fontset: %s"
+msgstr "E234: 모르는 글꼴셋: %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: ë‚´ë¶€ ì—러"
+
+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 "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()\" 부르기 실패"
+
+#, 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: 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"
+
+#, 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 "E37: No write since last change (add ! to override)"
+msgstr "E37: 마지막으로 고친 ë’¤ 저장ë˜ì§€ 않았습니다 (무시하려면 ! ë”하기)"
+
+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: 깨진 ì •ê·œí‘œí˜„ì‹ í”„ë¡œê·¸ëž¨"
+
+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 "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: sign ìžë£Œë¥¼ ì½ì„ 수 없습니다"
+
+msgid "E72: Close error on swap file"
+msgstr "E72: 스왑 파ì¼ì„ ë‹«ì„ ìˆ˜ 없습니다"
+
+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 "Zero count"
+msgstr "Zero count"
+
+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는 ì½ê¸° ì „ìš© 파ì¼ì„ 바꿀 수 없습니다"
+
+#, c-format
+msgid "E685: Internal error: %s"
+msgstr "E685: ë‚´ë¶€ ì—러: %s"
+
+msgid "E363: pattern uses more memory than 'maxmempattern'"
+msgstr "E363: íŒ¨í„´ì´ 'maxmempattern'보다 ë§Žì€ ë©”ëª¨ë¦¬ë¥¼ 사용합니다"
+
+msgid "E749: empty buffer"
+msgstr "E749: 빈 버í¼"
+
+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 "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 "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 "í¼ì„œ 위치가 ë²„í¼ ë°–ì— ìžˆìŠµë‹ˆë‹¤"
+
+#, c-format
+msgid "<window object (deleted) at %p>"
+msgstr "<%pì— ì°½ ê°ì²´ (ì‚­ì œë¨)>"
+
+#, c-format
+msgid "<window object (unknown) at %p>"
+msgstr "<%pì— ì°½ ê°ì²´ (모름)>"
+
+#, c-format
+msgid "<window %d>"
+msgstr "<ì°½ %d>"
+
+msgid "no such window"
+msgstr "그런 ì°½ì€ ì—†ìŠµë‹ˆë‹¤"
+
+msgid "attempt to refer to deleted buffer"
+msgstr "지워진 버í¼ë¥¼ 참조하려고 하였습니다"
diff --git a/src/po/ko.po b/src/po/ko.po
new file mode 100644
index 0000000000..5a447dae9b
--- /dev/null
+++ b/src/po/ko.po
@@ -0,0 +1,6447 @@
+# Generated from ko.UTF-8.po, DO NOT EDIT
+#
+# FIRST AUTHOR SungHyun Nam <goweol@gmail.com>, 2000-2011
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: vim 7.3\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2011-02-16 16:18+0900\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"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=euc-kr\n"
+"Content-Transfer-Encoding: 8bit\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 use wrong"
+
+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 "E82: Cannot allocate any buffer, exiting..."
+msgstr "E82: ¹öÆÛ¸¦ ÇÒ´çÇÒ ¼ö ¾ø¾î¼­ ³¡³À´Ï´Ù..."
+
+msgid "E83: Cannot allocate buffer, using other one..."
+msgstr "E83: ¹öÆÛ¸¦ ÇÒ´çÇÒ ¼ö ¾ø¾î¼­ ´Ù¸¥ °É »ç¿ëÇÕ´Ï´Ù..."
+
+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 "¹öÆÛ ÇÑ °³°¡ ³»·ÁÁ³½À´Ï´Ù"
+
+#, c-format
+msgid "%d buffers unloaded"
+msgstr "¹öÆÛ %d °³°¡ ³»·ÁÁ³½À´Ï´Ù"
+
+msgid "1 buffer deleted"
+msgstr "¹öÆÛ ÇÑ °³°¡ Áö¿öÁ³½À´Ï´Ù"
+
+#, c-format
+msgid "%d buffers deleted"
+msgstr "¹öÆÛ %d °³°¡ Áö¿öÁ³½À´Ï´Ù"
+
+msgid "1 buffer wiped out"
+msgstr "¹öÆÛ ÇÑ °³°¡ ¿ÏÀüÈ÷ Áö¿öÁ³½À´Ï´Ù"
+
+#, c-format
+msgid "%d buffers wiped out"
+msgstr "¹öÆÛ %d°³°¡ ¿ÏÀüÈ÷ Áö¿öÁ³½À´Ï´Ù"
+
+msgid "E84: No modified buffer found"
+msgstr "E84: ¹Ù²ï ¹öÆÛ¸¦ ãÀ» ¼ö ¾ø½À´Ï´Ù"
+
+#. back where we started, didn't find anything.
+msgid "E85: There is no listed buffer"
+msgstr "E85: ³ª¿­µÈ ¹öÆÛ°¡ ¾ø½À´Ï´Ù"
+
+#, c-format
+msgid "E86: Buffer %ld does not exist"
+msgstr "E86: ¹öÆÛ %ldÀÌ(°¡) Á¸ÀçÇÏÁö ¾Ê½À´Ï´Ù"
+
+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 "E90: Cannot unload last buffer"
+msgstr "E90: ¸¶Áö¸· ¹öÆÛ¸¦ ³»¸± ¼ö ¾ø½À´Ï´Ù"
+
+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 "[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 "[À̸§ ¾øÀ½]"
+
+#. must be a help buffer
+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 "[Scratch]"
+msgstr "[Scratch]"
+
+msgid ""
+"\n"
+"--- Signs ---"
+msgstr ""
+"\n"
+"--- ±âÈ£ ---"
+
+#, c-format
+msgid "Signs for %s:"
+msgstr "%s¿¡ ´ëÇÑ ±âÈ£:"
+
+#, c-format
+msgid " line=%ld id=%d name=%s"
+msgstr " ÁÙ=%ld id=%d À̸§=%s"
+
+#, c-format
+msgid "E96: Can not diff more than %ld buffers"
+msgstr "E96: %ld°³ ÀÌ»óÀÇ ¹öÆÛ¿¡ ´ëÇØ¼­´Â diff¸¦ ÇÒ ¼ö ¾ø½À´Ï´Ù"
+
+msgid "E810: Cannot read or write temp files"
+msgstr "E810: Àӽà ÆÄÀÏÀ» Àаųª ¾µ ¼ö ¾ø½À´Ï´Ù"
+
+msgid "E97: Cannot create diffs"
+msgstr "E97: diff¸¦ ¸¸µé ¼ö ¾ø½À´Ï´Ù"
+
+msgid "Patch file"
+msgstr "ÆÐŰ ÆÄÀÏ"
+
+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: digraph¿¡´Â EscapeÀ» ¾µ ¼ö ¾ø½À´Ï´Ù"
+
+msgid "E544: Keymap file not found"
+msgstr "E544: Ű¸Ê ÆÄÀÏÀ» ãÀ» ¼ö ¾ø½À´Ï´Ù"
+
+msgid "E105: Using :loadkeymap not in a sourced file"
+msgstr "E105: ºÒ·¯µéÀÎ ÆÄÀÏ¿¡¼­ :loadkeymapÀ» »ç¿ëÇÏÁö ¾Ê¾Ò½À´Ï´Ù"
+
+msgid "E791: Empty keymap entry"
+msgstr "E791: Ű¸Ê ¿£Æ®¸®°¡ ºñ¾îÀÖÀ½"
+
+msgid " Keyword completion (^N^P)"
+msgstr " ³¹¸» ¿Ï¼º (^N^P)"
+
+#. ctrl_x_mode == 0, ^P/^N compl.
+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 " Dictionary ¿Ï¼º (^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: Completion ±â´ÉÀÌ Ã¢À» ¹Ù²Ù¾ú½À´Ï´Ù"
+
+msgid "E840: Completion function deleted text"
+msgstr "E840: Completion ±â´ÉÀÌ ¹®ÀÚ¿­À» Áö¿ü½À´Ï´Ù"
+
+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 " 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.
+#.
+msgid "-- Searching..."
+msgstr "-- ã´Â Áß..."
+
+msgid "Back at original"
+msgstr "¿ø·¡´ë·Î º¹±¸"
+
+msgid "Word from other line"
+msgstr "´Ù¸¥ ÁÙ¿¡ ³¹¸»"
+
+msgid "The only match"
+msgstr "The only match"
+
+#, c-format
+msgid "match %d of %d"
+msgstr "match %d of %d"
+
+#, c-format
+msgid "match %d"
+msgstr "match %d"
+
+msgid "E18: Unexpected characters in :let"
+msgstr "E18: ':let'¿¡ ¸ð¸£´Â ±ÛÀÚ"
+
+#, c-format
+msgid "E684: list index out of range: %ld"
+msgstr "E684: ¸ñ·Ï ¹øÈ£°¡ ¹üÀ§¸¦ ¹þ¾î³²: %ld"
+
+#, c-format
+msgid "E121: Undefined variable: %s"
+msgstr "E121: Á¤ÀÇ ¾È µÈ º¯¼ö: %s"
+
+msgid "E111: Missing ']'"
+msgstr "E111: ']'ÀÌ ¾ø½À´Ï´Ù"
+
+#, c-format
+msgid "E686: Argument of %s must be a List"
+msgstr "E686: %s ÀÎÀÚ´Â ListÀ̾î¾ß ÇÕ´Ï´Ù"
+
+#, c-format
+msgid "E712: Argument of %s must be a List or Dictionary"
+msgstr "E712: %s ÀÎÀÚ´Â List ȤÀº Dictionary¿©¾ß ÇÕ´Ï´Ù"
+
+msgid "E713: Cannot use empty key for Dictionary"
+msgstr "E713: Dictionary¿¡ ºó ۸¦ ¾µ ¼ö ¾ø½À´Ï´Ù"
+
+msgid "E714: List required"
+msgstr "E714: List°¡ ÇÊ¿äÇÕ´Ï´Ù"
+
+msgid "E715: Dictionary required"
+msgstr "E715: Dictionary°¡ ÇÊ¿äÇÕ´Ï´Ù"
+
+#, 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: Dictionary¿¡ ۰¡ ¾øÀ½: %s"
+
+#, c-format
+msgid "E122: Function %s already exists, add ! to replace it"
+msgstr "E122: ÇÔ¼ö %sÀÌ(°¡) ÀÌ¹Ì ÀÖ½À´Ï´Ù, ¹Ù²Ù·Á¸é !À» ´õÇϼ¼¿ä"
+
+msgid "E717: Dictionary entry already exists"
+msgstr "E717: ÀÌ¹Ì Dictionary Ç׸ñÀÌ ÀÖ½À´Ï´Ù"
+
+msgid "E718: Funcref required"
+msgstr "E718: Funcref°¡ ÇÊ¿äÇÕ´Ï´Ù"
+
+msgid "E719: Cannot use [:] with a Dictionary"
+msgstr "E719: Dictionary¿¡ [:]À» »ç¿ëÇÒ ¼ö ¾ø½À´Ï´Ù"
+
+#, c-format
+msgid "E734: Wrong variable type for %s="
+msgstr "E734: %s=¿¡ ´ëÇÑ À߸øµÈ º¯¼öÇü"
+
+#, c-format
+msgid "E130: Unknown function: %s"
+msgstr "E130: ¸ð¸£´Â ÇÔ¼ö: %s"
+
+#, c-format
+msgid "E461: Illegal variable name: %s"
+msgstr "E461: ºñÁ¤»óÀûÀÎ º¯¼ö ¸í: %s"
+
+msgid "E687: Less targets than List items"
+msgstr "E687: List Ç׸ñº¸´Ù ÀûÀº ´ë»ó"
+
+msgid "E688: More targets than List items"
+msgstr "E688: List Ç׸ñº¸´Ù ¸¹Àº ´ë»ó"
+
+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: List³ª Dictionary¸¸ »öÀÎÇÒ ¼ö ÀÖ½À´Ï´Ù"
+
+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: :for µÚ¿¡ \"in\"°¡ ¾ø½À´Ï´Ù"
+
+#, c-format
+msgid "E107: Missing parentheses: %s"
+msgstr "E107: °ýÈ£ ¾øÀ½: %s"
+
+#, c-format
+msgid "E108: No such variable: \"%s\""
+msgstr "E108: ÀÌ·± º¯¼ö ¾øÀ½: \"%s\""
+
+msgid "E743: variable nested too deep for (un)lock"
+msgstr "E743: Àá±Ý(ÇØÁ¦)Çϱ⿡ º¯¼ö°¡ ³Ê¹« ±íÀÌ ÁßøµÇ¾ú½À´Ï´Ù"
+
+msgid "E109: Missing ':' after '?'"
+msgstr "E109: '?' µÚ¿¡ ':'ÀÌ ¾ø½À´Ï´Ù"
+
+msgid "E691: Can only compare List with List"
+msgstr "E691: List´Â List¿Í¸¸ ºñ±³ÇÒ ¼ö ÀÖ½À´Ï´Ù"
+
+msgid "E692: Invalid operation for Lists"
+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 "E693: Can only compare Funcref with Funcref"
+msgstr "E693: Funcref´Â Funcref¿Í¸¸ ºñ±³ÇÒ ¼ö ÀÖ½À´Ï´Ù"
+
+msgid "E694: Invalid operation for Funcrefs"
+msgstr "E694: Funcrefs¿¡ ´ëÇÑ À߸øµÈ µ¿ÀÛ"
+
+msgid "E804: Cannot use '%' with Float"
+msgstr "E804: Float¿¡ '%'´Â »ç¿ëÇÒ ¼ö ¾ø½À´Ï´Ù"
+
+msgid "E110: Missing ')'"
+msgstr "E110: ')'°¡ ¾ø½À´Ï´Ù"
+
+msgid "E695: Cannot index a Funcref"
+msgstr "E695: Funcref¸¦ »öÀÎÇÒ ¼ö ¾ø½À´Ï´Ù"
+
+#, 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"
+
+#, c-format
+msgid "E696: Missing comma in List: %s"
+msgstr "E696: List¿¡ ÄÞ¸¶ ´©¶ô: %s"
+
+#, c-format
+msgid "E697: Missing end of List ']': %s"
+msgstr "E697: List ³¡¿¡ ']' ´©¶ô: %s"
+
+#, c-format
+msgid "E720: Missing colon in Dictionary: %s"
+msgstr "E720: Dictionary¿¡ ÄÝ·Ð ´©¶ô: %s"
+
+#, c-format
+msgid "E721: Duplicate key in Dictionary: \"%s\""
+msgstr "E721: Dictionary¿¡ Áߺ¹µÈ Ű: \"%s\""
+
+#, c-format
+msgid "E722: Missing comma in Dictionary: %s"
+msgstr "E722: Dictionary¿¡ ÄÞ¸¶ ´©¶ô: %s"
+
+#, c-format
+msgid "E723: Missing end of Dictionary '}': %s"
+msgstr "E723: Dictionary ³¡¿¡ '}' ´©¶ô: %s"
+
+msgid "E724: variable nested too deep for displaying"
+msgstr "E724: º¯¼ö°¡ Ç¥½ÃÇϱ⿡ ³Ê¹« ±íÀÌ ÁßøµÇ¾ú½À´Ï´Ù"
+
+#, 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(À¸)·Î À߸øµÈ ÀÎÀÚ°¡ ³Ñ°ÜÁ³½À´Ï´Ù"
+
+#, c-format
+msgid "E117: Unknown function: %s"
+msgstr "E117: ¸ð¸£´Â ÇÔ¼ö: %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: Dictionary¾øÀÌ »çÀüÇÔ¼ö°¡ ºÒ·ÁÁü: %s"
+
+msgid "E808: Number or Float required"
+msgstr "E808: Number ȤÀº Float°¡ ÇÊ¿äÇÕ´Ï´Ù"
+
+msgid "E699: Too many arguments"
+msgstr "E699: ³Ê¹« ¸¹Àº ÀÎÀÚ"
+
+msgid "E785: complete() can only be used in Insert mode"
+msgstr "E785: complete()Àº ÀÔ·Â ¸ðµå¿¡¼­¸¸ »ç¿ëµÉ ¼ö ÀÖ½À´Ï´Ù"
+
+#.
+#. * 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 "È®ÀÎ(&O)"
+
+#, c-format
+msgid "E737: Key already exists: %s"
+msgstr "E737: ۰¡ ÀÌ¹Ì Á¸ÀçÇÔ: %s"
+
+#, c-format
+msgid "+-%s%3ld lines: "
+msgstr "+-%s%3ld ÁÙ: "
+
+#, c-format
+msgid "E700: Unknown function: %s"
+msgstr "E700: ¸ð¸£´Â ÇÔ¼ö: %s"
+
+msgid ""
+"&OK\n"
+"&Cancel"
+msgstr ""
+"È®ÀÎ(&O)\n"
+"Ãë¼Ò(&C)"
+
+msgid "called inputrestore() more often than inputsave()"
+msgstr "inputrestore()°¡ inputsave()º¸´Ù ¸¹ÀÌ ºÒ·ÁÁ³½À´Ï´Ù"
+
+msgid "E786: Range not allowed"
+msgstr "E786: ¹üÀ§°¡ Çã¿ëµÇÁö ¾Ê½À´Ï´Ù"
+
+msgid "E701: Invalid type for len()"
+msgstr "E701: len()¿¡ À߸øµÈ Çü"
+
+msgid "E726: Stride is zero"
+msgstr "E726: Stride°¡ 0"
+
+msgid "E727: Start past end"
+msgstr "E727: ½ÃÀÛÀ§Ä¡°¡ ³¡À» Áö³ªÄ§"
+
+msgid "<empty>"
+msgstr "<ºñ¾îÀÖÀ½>"
+
+msgid "E240: No connection to Vim server"
+msgstr "E240: Vim ¼­¹ö¿¡ ¿¬°áµÇ¾î ÀÖÁö ¾Ê½À´Ï´Ù"
+
+#, c-format
+msgid "E241: Unable to send to %s"
+msgstr "E241: %s(À¸)·Î º¸³¾ ¼ö ¾ø½À´Ï´Ù"
+
+msgid "E277: Unable to read a server reply"
+msgstr "E277: ¼­¹öÀÇ ÀÀ´äÀ» ÀÐÀ» ¼ö ¾ø½À´Ï´Ù"
+
+msgid "E655: Too many symbolic links (cycle?)"
+msgstr "E655: ³Ê¹« ¸¹Àº ½Éº¼¸¯ ¸µÅ© (¹Ýº¹¼øÈ¯?)"
+
+msgid "E258: Unable to send to client"
+msgstr "E258: Ŭ¶óÀÌ¾ðÆ®·Î º¸³¾ ¼ö ¾ø½À´Ï´Ù"
+
+msgid "E702: Sort compare function failed"
+msgstr "E702: Á¤·Ä ºñ±³ ±â´ÉÀÌ ½ÇÆÐÇß½À´Ï´Ù"
+
+msgid "(Invalid)"
+msgstr "(À߸øµÇ¾ú½À´Ï´Ù)"
+
+msgid "E677: Error writing temp file"
+msgstr "E677: Àӽà ÆÄÀÏ ¾²±â ¿¡·¯"
+
+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 "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 "E806: using Float as a String"
+msgstr "E806: Float¸¦ StringÀ¸·Î »ç¿ë"
+
+#, 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 "E706: Variable type mismatch for: %s"
+msgstr "E706: º¯¼ö Çü ´Ù¸§: %s"
+
+#, c-format
+msgid "E795: Cannot delete variable %s"
+msgstr "E795: º¯¼ö %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: º¹»çÇϱ⿡ º¯¼ö°¡ ³Ê¹« ±í°Ô ÁßøµÇ¾ú½À´Ï´Ù"
+
+#, c-format
+msgid "E123: Undefined function: %s"
+msgstr "E123: Á¤ÀÇ ¾È µÈ ÇÔ¼ö: %s"
+
+#, c-format
+msgid "E124: Missing '(': %s"
+msgstr "E124: '('°¡ ¾øÀ½: %s"
+
+#, c-format
+msgid "E125: Illegal argument: %s"
+msgstr "E125: À߸øµÈ ÀÎÀÚ: %s"
+
+msgid "E126: Missing :endfunction"
+msgstr "E126: :endfunctionÀÌ ¾ø½À´Ï´Ù"
+
+#, 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"
+
+msgid "E129: Function name required"
+msgstr "E129: ÇÔ¼ö À̸§ÀÌ ÇÊ¿äÇÕ´Ï´Ù"
+
+#, c-format
+msgid "E128: Function name must start with a capital or contain a colon: %s"
+msgstr "E128: ÇÔ¼ö À̸§Àº ´ë¹®ÀÚ·Î ½ÃÀÛÇϰųª ÄÝ·ÐÀ» Æ÷ÇÔÇØ¾ß ÇÔ: %s"
+
+#, c-format
+msgid "E131: Cannot delete function %s: It is in use"
+msgstr "E131: ÇÔ¼ö %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À»(¸¦) µ¹·ÁÁÖ¾ú½À´Ï´Ù"
+
+#, c-format
+msgid "continuing in %s"
+msgstr "%s¿¡¼­ °è¼Ó"
+
+msgid "E133: :return not inside a function"
+msgstr "E133: :returnÀÌ ÇÔ¼ö ¾È¿¡ ÀÖÁö ¾Ê½À´Ï´Ù"
+
+msgid ""
+"\n"
+"# global variables:\n"
+msgstr ""
+"\n"
+"# Àü¿ª º¯¼ö:\n"
+
+msgid ""
+"\n"
+"\tLast set from "
+msgstr ""
+"\n"
+"\tLast set from "
+
+msgid "No old files"
+msgstr "old ÆÄÀÏÀÌ ¾ø½À´Ï´Ù"
+
+#, c-format
+msgid "<%s>%s%s %d, Hex %02x, Octal %03o"
+msgstr "<%s>%s%s %d, ½ÊÀ°Áø %02x, ÆÈÁø %03o"
+
+#, 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: *Filter* ÀÚµ¿¸í·ÉÀº ÇöÀç ¹öÆÛ¸¦ ¹Ù²Ù¾î¼­´Â ¾È µË´Ï´Ù"
+
+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 " ½ÇÆÐ"
+
+#. avoid a wait_return for this message, it's annoying
+#, c-format
+msgid "E137: Viminfo file is not writable: %s"
+msgstr "E137: Viminfo ÆÄÀÏÀÇ ¾²±â ±ÇÇÑÀÌ ¾ø½À´Ï´Ù: %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\"À»(¸¦) ¾²´Â Áß"
+
+#. Write the info:
+#, 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 "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 "½º¿Ò ÆÄÀÏ \"%s\"°¡ ÀÖ½À´Ï´Ù, µ¤¾î¾µ±î¿ä?"
+
+#, c-format
+msgid "E768: Swap file exists: %s (:silent! overrides)"
+msgstr "E768: ½º¿Ò ÆÄÀÏ ÀÖÀ½: %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: Autocommand°¡ ¶æ ¹Û¿¡ »õ ¹öÆÛ %sÀ»(¸¦) Áö¿ü½À´Ï´Ù"
+
+msgid "E144: non-numeric argument to :z"
+msgstr "E144: ¼ýÀÚ°¡ ¾Æ´Ñ ÀÎÀÚ°¡ :z¿¡ ÁÖ¾îÁ³½À´Ï´Ù"
+
+msgid "E145: Shell commands not allowed in rvim"
+msgstr "E145: 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 " ÇÑ ÁÙ¿¡¼­"
+
+#, c-format
+msgid " on %ld lines"
+msgstr " %ld ÁÙ¿¡¼­"
+
+msgid "E147: Cannot do :global recursive"
+msgstr "E147: :globalÀº Àç±Í È£Ãâ µÉ ¼ö ¾ø½À´Ï´Ù"
+
+msgid "E148: Regular expression missing from global"
+msgstr "E148: global¿¡¼­ Á¤±ÔÇ¥Çö½ÄÀÌ ºüÁ³½À´Ï´Ù"
+
+#, c-format
+msgid "Pattern found in every line: %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 "E150: Not a directory: %s"
+msgstr "E150: µð·ºÅ丮°¡ ¾Æ´Ô: %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 "E160: Unknown sign command: %s"
+msgstr "E160: ¸ð¸£´Â sign ¸í·É: %s"
+
+msgid "E156: Missing sign name"
+msgstr "E156: sign À̸§ÀÌ ¾ø½À´Ï´Ù"
+
+msgid "E612: Too many signs defined"
+msgstr "E612: ³Ê¹« ¸¹Àº signÀÌ Á¤ÀǵǾî ÀÖ½À´Ï´Ù"
+
+#, c-format
+msgid "E239: Invalid sign text: %s"
+msgstr "E239: À߸øµÈ sign ÅØ½ºÆ®: %s"
+
+#, c-format
+msgid "E155: Unknown sign: %s"
+msgstr "E155: ¸ð¸£´Â sign: %s"
+
+msgid "E159: Missing sign number"
+msgstr "E159: sign ¹øÈ£°¡ ¾ø½À´Ï´Ù"
+
+#, c-format
+msgid "E158: Invalid buffer name: %s"
+msgstr "E158: À߸øµÈ ¹öÆÛ À̸§: %s"
+
+#, c-format
+msgid "E157: Invalid sign ID: %ld"
+msgstr "E157: À߸øµÈ sign ID: %ld"
+
+msgid " (NOT FOUND)"
+msgstr " (¸ø ã¾ÒÀ½)"
+
+msgid " (not supported)"
+msgstr " (Áö¿øµÇÁö ¾ÊÀ½)"
+
+msgid "[Deleted]"
+msgstr "[Áö¿öÁ³½À´Ï´Ù]"
+
+msgid "Entering Debug mode. Type \"cont\" to continue."
+msgstr "µð¹ö±× »óÅ·Πµé¾î°¨. °è¼ÓÇÏ·Á¸é \"cont\"¸¦ ÀÔ·ÂÇϽʽÿÀ."
+
+#, c-format
+msgid "line %ld: %s"
+msgstr "%ld ÁÙ: %s"
+
+#, c-format
+msgid "cmd: %s"
+msgstr "¸í·É: %s"
+
+#, 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 ÁÙ"
+
+msgid "E750: First use \":profile start {fname}\""
+msgstr "E750: ¸ÕÀú \":profile start {fname}\"À» »ç¿ëÇϼ¼¿ä"
+
+#, c-format
+msgid "Save changes to \"%s\"?"
+msgstr "\"%s\"¿¡ ¹Ù²ï ³»¿ëÀ» ÀúÀåÇÒ±î¿ä?"
+
+msgid "Untitled"
+msgstr "Á¦¸ñ ¾øÀ½"
+
+#, c-format
+msgid "E162: No write since last change for buffer \"%s\""
+msgstr "E162: ¹öÆÛ \"%s\"¿¡ ³ªÁß¿¡ ¹Ù²ï ³»¿ëÀÌ ½áÁöÁö ¾Ê¾Ò½À´Ï´Ù"
+
+msgid "Warning: Entered other buffer unexpectedly (check autocommands)"
+msgstr "°æ°í: ¶æ ¹Û¿¡ ´Ù¸¥ ¹öÆÛ·Î µé¾î°¬½À´Ï´Ù (autocommand¸¦ È®ÀÎÇϽʽÿÀ)"
+
+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 'runtimepath': \"%s\""
+msgstr "'runtimepath'¿¡¼­ ãÀ» ¼ö ¾øÀ½: \"%s\""
+
+msgid "Source Vim script"
+msgstr "ºö ½ºÅ©¸³Æ® ·Îµå"
+
+#, c-format
+msgid "Cannot source a directory: \"%s\""
+msgstr "µð·ºÅ丮´Â sourceÇÒ ¼ö ¾øÀ½: \"%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 ºÒ·¯µéÀ̱⠳¡"
+
+#~ msgid "modeline"
+#~ msgstr ""
+
+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 »óÅ·ΠÀüȯ. Normal »óÅ·Π°¡·Á¸é \"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 "E319: Sorry, the command is not available in this version"
+msgstr "E319: ¹Ì¾ÈÇÕ´Ï´Ù, ±× ¸í·ÉÀº ÇöÀç ÆÇ¿¡¼­ »ç¿ëÇÒ ¼ö ¾ø½À´Ï´Ù"
+
+msgid "E172: Only one file name allowed"
+msgstr "E172: ¿À·ÎÁö ÇϳªÀÇ ÆÄÀÏ À̸§¸¸ »ç¿ë °¡´ÉÇÕ´Ï´Ù"
+
+msgid "1 more file to edit. Quit anyway?"
+msgstr "°íÄ¥ ÆÄÀÏÀÌ ÇÑ °³ ´õ ÀÖ½À´Ï´Ù. ±×·¡µµ ³¡³¾±î¿ä?"
+
+#, c-format
+msgid "%d more files to edit. Quit anyway?"
+msgstr "°íÄ¥ ÆÄÀÏÀÌ %d °³ ´õ ÀÖ½À´Ï´Ù. ±×·¡µµ ³¡³¾±î¿ä?"
+
+msgid "E173: 1 more file to edit"
+msgstr "E173: °íÄ¥ ÆÄÀÏÀÌ ÇÑ °³ ´õ ÀÖ½À´Ï´Ù"
+
+#, 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 Range 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¿¡ ÀÎÀÚ°¡ ÇÊ¿äÇÕ´Ï´Ù"
+
+#, 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 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 "ºö »ç¿ëÀÚ´Ô, ȯ¿µÇÕ´Ï´Ù!"
+
+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 "½º¿Ò ÆÄÀÏÀÌ ¾ø½À´Ï´Ù"
+
+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 "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\"À»(¸¦) ¿­ ¼ö ¾ø½À´Ï´Ù"
+
+#. set mark
+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: \"<sfile>\"¿¡ ´ëÇØ ġȯÇÒ :source ÆÄÀÏ À̸§ÀÌ ¾ø½À´Ï´Ù"
+
+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: '%'³ª '#'¿¡ ´ëÇÑ ºó ÆÄÀÏ À̸§, ¿À·ÎÁö \":p:h\"¿Í¸¸ µ¿ÀÛÇÕ´Ï´Ù"
+
+msgid "E500: Evaluates to an empty string"
+msgstr "E500: ºó ¹®ÀÚ¿­¿¡¼­ °ªÀ» ±¸ÇÏ·Á°í ÇÕ´Ï´Ù"
+
+msgid "E195: Cannot open viminfo file for reading"
+msgstr "E195: ÀÐÀ» viminfo ÆÄÀÏÀ» ¿­ ¼ö ¾ø½À´Ï´Ù"
+
+msgid "E196: No digraphs in this version"
+msgstr "E196: ÀÌ ÆÇ¿¡´Â digraph°¡ ¾ø½À´Ï´Ù"
+
+msgid "E608: Cannot :throw exceptions with 'Vim' prefix"
+msgstr "E608: 'Vim' Á¢µÎ»ç·Î ¿¹¿Ü¸¦ :throwÇÒ ¼ö ¾ø½À´Ï´Ù"
+
+#. always scroll up, don't overwrite
+#, c-format
+msgid "Exception thrown: %s"
+msgstr "¿¹¿Ü thrown: %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 ÁÙ"
+
+#. always scroll up, don't overwrite
+#, c-format
+msgid "Exception caught: %s"
+msgstr "¿¹¿Ü ¹ß»ý: %s"
+
+#, c-format
+msgid "%s made pending"
+msgstr "%sÀÌ(°¡) pending µÇ¾ú½À´Ï´Ù"
+
+#, 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 "¿¡·¯"
+
+#. if (pending & CSTP_INTERRUPT)
+msgid "Interrupt"
+msgstr "ÀÎÅÍ·´Æ®"
+
+msgid "E579: :if nesting too deep"
+msgstr "E579: :if°¡ ³Ê¹« ±í°Ô ÁßøµÇ¾ú½À´Ï´Ù"
+
+msgid "E580: :endif without :if"
+msgstr "E580: :if¾øÀÌ :endif°¡ ÀÖ½À´Ï´Ù"
+
+msgid "E581: :else without :if"
+msgstr "E581: :if¾øÀÌ :else°¡ ÀÖ½À´Ï´Ù"
+
+msgid "E582: :elseif without :if"
+msgstr "E582: :if¾øÀÌ :elseif°¡ ÀÖ½À´Ï´Ù"
+
+msgid "E583: multiple :else"
+msgstr "E583: ¿©·¯°³ÀÇ :else°¡ ÀÖ½À´Ï´Ù"
+
+msgid "E584: :elseif after :else"
+msgstr "E584: :else µÚ¿¡ :elseif°¡ ÀÖ½À´Ï´Ù"
+
+msgid "E585: :while/:for nesting too deep"
+msgstr "E585: :while/:for°¡ ³Ê¹« ±í°Ô ÁßøµÇ¾ú½À´Ï´Ù"
+
+msgid "E586: :continue without :while or :for"
+msgstr "E586: :while ȤÀº :for¾øÀÌ :continue°¡ ÀÖ½À´Ï´Ù"
+
+msgid "E587: :break without :while or :for"
+msgstr "E587: :while ȤÀº :for¾øÀÌ :break°¡ ÀÖ½À´Ï´Ù"
+
+msgid "E732: Using :endfor with :while"
+msgstr "E732: :while¿¡ :endfor°¡ »ç¿ëµÇ¾ú½À´Ï´Ù"
+
+msgid "E733: Using :endwhile with :for"
+msgstr "E733: :for¿¡ :endwhileÀÌ »ç¿ëµÇ¾ú½À´Ï´Ù"
+
+msgid "E601: :try nesting too deep"
+msgstr "E601: :try°¡ ³Ê¹« ±í°Ô ÁßøµÇ¾ú½À´Ï´Ù"
+
+msgid "E603: :catch without :try"
+msgstr "E603: :try¾øÀÌ :catch°¡ ÀÖ½À´Ï´Ù"
+
+#. Give up for a ":catch" after ":finally" and ignore it.
+#. * Just parse.
+msgid "E604: :catch after :finally"
+msgstr "E604: :finally µÚ¿¡ :catch°¡ ÀÖ½À´Ï´Ù"
+
+msgid "E606: :finally without :try"
+msgstr "E606: :try¾øÀÌ :finally°¡ ÀÖ½À´Ï´Ù"
+
+#. Give up for a multiple ":finally" and ignore it.
+msgid "E607: multiple :finally"
+msgstr "E607: ¿©·¯°³ÀÇ :finally°¡ ÀÖ½À´Ï´Ù"
+
+msgid "E602: :endtry without :try"
+msgstr "E602: :try¾øÀÌ :endtry°¡ ÀÖ½À´Ï´Ù"
+
+msgid "E193: :endfunction not inside a function"
+msgstr "E193: :endfunctionÀÌ function ³»¿¡ ¾ø½À´Ï´Ù"
+
+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 " kind file\n"
+
+msgid "'history' option is zero"
+msgstr "'history' ¿É¼ÇÀÌ 0ÀÔ´Ï´Ù"
+
+#, 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 "E198: cmd_pchar beyond the command length"
+msgstr "E198: cmd_pchar°¡ ¸í·É ±æÀ̸¦ ¹þ¾î³µ½À´Ï´Ù"
+
+msgid "E199: Active window or buffer deleted"
+msgstr "E199: Ȱ¼ºµÈ âÀ̳ª ¹öÆÛ°¡ Áö¿öÁ³½À´Ï´Ù"
+
+msgid "E812: Autocommands changed buffer or buffer name"
+msgstr "E812: Autocommand°¡ ¹öÆÛ³ª ¹öÆÛÀ̸§À» ¹Ù²Ù¾ú½À´Ï´Ù"
+
+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 "ºö: Ç¥ÁØÀԷ¿¡¼­ Àд Áß...\n"
+
+msgid "Reading from stdin..."
+msgstr "Ç¥ÁØÀԷ¿¡¼­ Àд Áß..."
+
+#. Re-opening the original file failed!
+msgid "E202: Conversion made file unreadable!"
+msgstr "E202: º¯È¯µÈ ÆÄÀÏÀ» ÀÐÀ» ¼ö°¡ ¾ø½À´Ï´Ù!"
+
+msgid "[fifo/socket]"
+msgstr "[ÇÇÆ÷/¼ÒÄÏ]"
+
+msgid "[fifo]"
+msgstr "[ÇÇÆ÷]"
+
+msgid "[socket]"
+msgstr "[¼ÒÄÏ]"
+
+#~ msgid "[character special]"
+#~ msgstr ""
+
+msgid "[RO]"
+msgstr "[Àбâ Àü¿ë]"
+
+msgid "[CR missing]"
+msgstr "[CR ¾øÀ½]"
+
+msgid "[long lines split]"
+msgstr "[±ä ÁÙ À߸²]"
+
+msgid "[NOT converted]"
+msgstr "[º¯È¯ ¾È µË´Ï´Ù]"
+
+msgid "[converted]"
+msgstr "[º¯È¯ µÇ¾ú½À´Ï´Ù]"
+
+msgid "[crypted]"
+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 "E821: File is encrypted with unknown method"
+msgstr "E821: ÆÄÀÏÀÌ ¸ð¸£´Â ¹æ¹ýÀ¸·Î ¾ÏȣȭµÇ¾î ÀÖ½À´Ï´Ù"
+
+msgid "E676: No matching autocommands for acwrite buffer"
+msgstr "E676: acwrite ¹öÆÛ¿¡ ´ëÇÑ autocommand¸¦ ãÀ» ¼ö ¾ø½À´Ï´Ù"
+
+msgid "E203: Autocommands deleted or unloaded buffer to be written"
+msgstr "E203: ¾µ ¹öÆÛ¸¦ ÀÚµ¿¸í·ÉÀÌ Áö¿ì°Å³ª ´Ý¾Ò½À´Ï´Ù"
+
+msgid "E204: Autocommand changed number of lines in unexpected way"
+msgstr "E204: Autocommand°¡ À߸øµÈ ¹æ¹ýÀ¸·Î ÁÙÀ» ¹Ù²Ù¾ú½À´Ï´Ù"
+
+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 "E460: The resource fork would be lost (add ! to override)"
+msgstr "E460: The resource fork will be lost (µ¤¾î¾²·Á¸é ! ´õÇϱâ)"
+
+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 "E667: Fsync failed"
+msgstr "E667: Fsync°¡ ½ÇÆÐÇß½À´Ï´Ù"
+
+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 " [a]"
+
+msgid " appended"
+msgstr " ´õÇß½À´Ï´Ù"
+
+msgid " [w]"
+msgstr " [w]"
+
+msgid " written"
+msgstr " ÀúÀå Çß½À´Ï´Ù"
+
+msgid "E205: Patchmode: can't save original file"
+msgstr "E205: ÆÐÄ¡ »óÅÂ: ¿ø·¡ ÆÄÀÏÀ» ÀúÀåÇÒ ¼ö ¾ø½À´Ï´Ù"
+
+msgid "E206: patchmode: can't touch empty original file"
+msgstr "E206: ÆÐÄ¡ »óÅÂ: ºó ¿ø·¡ ÆÄÀÏÀ» ¸¸µé ¼ö ¾ø½À´Ï´Ù"
+
+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 "[µµ½º]"
+
+msgid "[dos format]"
+msgstr "[µµ½º Çü½Ä]"
+
+msgid "[mac]"
+msgstr "[¸Æ]"
+
+msgid "[mac format]"
+msgstr "[¸Æ Çü½Ä]"
+
+msgid "[unix]"
+msgstr "[À¯´Ð½º]"
+
+msgid "[unix format]"
+msgstr "[À¯´Ð½º Çü½Ä]"
+
+msgid "1 line, "
+msgstr "1 ÁÙ, "
+
+#, c-format
+msgid "%ld lines, "
+msgstr "%ld ÁÙ, "
+
+msgid "1 character"
+msgstr "1 ±ÛÀÚ"
+
+#, c-format
+msgid "%lld characters"
+msgstr "%lld ±ÛÀÚ"
+
+#. Explicit typecast avoids warning on Mac OS X 10.6
+#, c-format
+msgid "%ld characters"
+msgstr "%ld ±ÛÀÚ"
+
+msgid "[noeol]"
+msgstr "[noeol]"
+
+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
+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\"ÀÌ(°¡) ¹Ù²î¾ú°í ¸¶Âù°¡Áö·Î ºöÀÇ ¹öÆÛµµ ¹Ù²î¾ú½À´Ï´Ù"
+
+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 ""
+"È®ÀÎ(&O)\n"
+"ÆÄÀÏ ºÒ·¯¿À±â(&L)"
+
+#, 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 "autocommand ÀÚµ¿»èÁ¦: %s <buffer=%d>"
+
+#. the group doesn't exist
+#, c-format
+msgid "E367: No such group: \"%s\""
+msgstr "E367: ÀÌ·± ±×·ì ¾øÀ½: \"%s\""
+
+#, 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"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Auto-Commands ---"
+msgstr ""
+"\n"
+"--- ÀÚµ¿-¸í·É ---"
+
+#, c-format
+msgid "E680: <buffer=%d>: invalid buffer number "
+msgstr "E680: <buffer=%d>: À߸øµÈ ¹öÆÛ ¹øÈ£"
+
+msgid "E217: Can't execute autocommands for ALL events"
+msgstr "E217: ALL À̺¥Æ®¿¡ ´ëÇØ ÀÚµ¿¸í·ÉÀ» ½ÇÇàÇÒ ¼ö ¾ø½À´Ï´Ù"
+
+msgid "No matching autocommands"
+msgstr "¸Â´Â ÀÚµ¿¸í·ÉÀÌ ¾ø½À´Ï´Ù"
+
+msgid "E218: autocommand nesting too deep"
+msgstr "E218: ÀÚµ¿¸í·ÉÀÌ ³Ê¹« ±í°Ô ÁßøµÇ¾ú½À´Ï´Ù"
+
+#, c-format
+#~ msgid "%s Auto commands for \"%s\""
+#~ msgstr ""
+
+#, 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: fold°¡ ¾ø½À´Ï´Ù"
+
+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 lines folded "
+msgstr "+--%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 "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 "½ºÅ©·Ñ¹Ù À§Á¬: ½æ ÇȽº¸ÊÀÇ Áö¿À¹ÌÆ®¸®¸¦ ¾òÀ» ¼ö ¾ø½À´Ï´Ù."
+
+msgid "Vim dialog"
+msgstr "ºö ´ëÈ­»óÀÚ"
+
+msgid "E232: Cannot create BalloonEval with both message and callback"
+msgstr "E232: ¸Þ½ÃÁö¿Í ÄÝ¹é ¸ðµÎ¸¦ »ç¿ëÇØ¼­´Â BalloonEvalÀ» ¸¸µé ¼ö ¾ø½À´Ï´Ù"
+
+msgid ""
+"&Yes\n"
+"&No\n"
+"&Cancel"
+msgstr ""
+"¿¹(&Y)\n"
+"¾Æ´Ï¿À(&N)\n"
+"Ãë¼Ò(&C)"
+
+msgid "Input _Methods"
+msgstr "ÀÔ·Â ¹æ¹ý(_M)"
+
+msgid "VIM - Search and Replace..."
+msgstr "ºö - ã¾Æ¼­ ¹Ù²Ù±â..."
+
+msgid "VIM - Search..."
+msgstr "ºö - ã±â..."
+
+msgid "Find what:"
+msgstr "¹«¾ó ãÀ»±î¿ä:"
+
+msgid "Replace with:"
+msgstr "¹Ù²Ü ¹®ÀÚ¿­:"
+
+#. whole word only button
+msgid "Match whole word only"
+msgstr "¶È°°Àº ³¹¸»¸¸"
+
+#. match case button
+#~ msgid "Match case"
+#~ msgstr ""
+
+msgid "Direction"
+msgstr "¹æÇâ"
+
+#. 'Up' and 'Down' buttons
+msgid "Up"
+msgstr "À§·Î"
+
+msgid "Down"
+msgstr "¾Æ·¡·Î"
+
+#. 'Find Next' button
+msgid "Find Next"
+msgstr "´ÙÀ½ ã±â"
+
+#. 'Replace' button
+msgid "Replace"
+msgstr "¹Ù²Ù±â"
+
+#. 'Replace All' button
+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)"
+
+#, 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 "Close tab"
+msgstr "ÅÇ ´Ý±â"
+
+msgid "Open tab..."
+msgstr "ÅÇ ¿­±â..."
+
+msgid "Find string (use '\\\\' to find a '\\')"
+msgstr "¹®ÀÚ¿­ ã±â ('\\'¸¦ ãÀ¸·Á¸é '\\\\' »ç¿ë)"
+
+msgid "Find & Replace (use '\\\\' to find a '\\')"
+msgstr "¹®ÀÚ¿­ ã¾Æ ¹Ù²Ù±â ('\\'¸¦ ãÀ¸·Á¸é '\\\\' »ç¿ë)"
+
+#. 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 "»ç¿ë ¾ÊµÊ"
+
+msgid "Directory\t*.nothing\n"
+msgstr "µð·ºÅ丮\t*.nothing\n"
+
+msgid "Vim E458: Cannot allocate colormap entry, some colors may be incorrect"
+msgstr ""
+"ºö E458: »ö»ó¸Ê ¿£Æ®¸®¸¦ ÇÒ´çÇÒ ¼ö ¾ø½À´Ï´Ù, ¸î¸î »öÀÌ À߸øµÉ ¼ö ÀÖ½À´Ï´Ù"
+
+#, 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\n"
+msgstr "E253: ±Û²Ã¼Â À̸§: %s\n"
+
+#, c-format
+msgid "Font0: %s\n"
+msgstr "±Û²Ã0: %s\n"
+
+#, c-format
+msgid "Font1: %s\n"
+msgstr "±Û²Ã1: %s\n"
+
+#, c-format
+msgid "Font%ld width is not twice that of font0\n"
+msgstr "±Û²Ã%ld ³Êºñ°¡ ±Û²Ã0ÀÇ µÎ¹è°¡ ¾Æ´Õ´Ï´Ù\n"
+
+#, c-format
+msgid "Font0 width: %ld\n"
+msgstr "±Û²Ã0 ³Êºñ: %ld\n"
+
+#, c-format
+msgid ""
+"Font1 width: %ld\n"
+"\n"
+msgstr ""
+"±Û²Ã1 ³Êºñ: %ld\n"
+"\n"
+
+#~ msgid "Invalid font specification"
+#~ msgstr ""
+
+#~ msgid "&Dismiss"
+#~ msgstr ""
+
+#~ msgid "no specific match"
+#~ msgstr ""
+
+msgid "Vim - Font Selector"
+msgstr "Vim - ±Û²Ã ¼±Åñâ"
+
+msgid "Name:"
+msgstr "À̸§:"
+
+#. create toggle button
+#~ 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 "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: Æ÷½ºÆ®½ºÅ©¸³Æ® Ãâ·ÂÆÄÀÏ¿¡ ¾µ ¼ö ¾ø½À´Ï´Ù."
+
+#, 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: Æ÷½ºÆ®½ºÅ©¸³Æ® ¸®¼Ò½º ÆÄÀÏ \"%s\"À»(¸¦) ÀÐÀ» ¼ö ¾ø½À´Ï´Ù"
+
+#, c-format
+msgid "E618: file \"%s\" is not a PostScript resource file"
+msgstr "E618: ÆÄÀÏ \"%s\"Àº(´Â) Æ÷½ºÆ®½ºÅ©¸³Æ® ¸®¼Ò½º ÆÄÀÏÀÌ ¾Æ´Õ´Ï´Ù"
+
+#, c-format
+msgid "E619: file \"%s\" is not a supported PostScript resource file"
+msgstr "E619: ÆÄÀÏ \"%s\"Àº(´Â) Áö¿øµÇ´Â Æ÷½ºÆ®½ºÅ©¸³Æ® ¸®¼Ò½º ÆÄÀÏÀÌ ¾Æ´Õ´Ï´Ù"
+
+#, c-format
+msgid "E621: \"%s\" resource file has wrong version"
+msgstr "E621: \"%s\" ¸®¼Ò½º ÆÄÀÏÀº ¹öÀüÀÌ À߸øµÇ¾ú½À´Ï´Ù"
+
+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: Æ÷½ºÆ®½ºÅ©¸³Æ® Ãâ·ÂÆÄÀÏÀ» ¿­ ¼ö ¾ø½À´Ï´Ù"
+
+#, c-format
+msgid "E456: Can't open file \"%s\""
+msgstr "E456: \"%s\" ÆÄÀÏÀ» ¿­ ¼ö ¾ø½À´Ï´Ù"
+
+msgid "E456: Can't find PostScript resource file \"prolog.ps\""
+msgstr "E456: Æ÷½ºÆ®½ºÅ©¸³Æ® ¸®¼Ò½º ÆÄÀÏ \"prolog.ps\"¸¦ ãÀ» ¼ö ¾ø½À´Ï´Ù"
+
+msgid "E456: Can't find PostScript resource file \"cidfont.ps\""
+msgstr "E456: Æ÷½ºÆ®½ºÅ©¸³Æ® ¸®¼Ò½º ÆÄÀÏ \"cidfont.ps\"¸¦ ãÀ» ¼ö ¾ø½À´Ï´Ù"
+
+#, c-format
+msgid "E456: Can't find PostScript resource file \"%s.ps\""
+msgstr "E456: Æ÷½ºÆ®½ºÅ©¸³Æ® ¸®¼Ò½º ÆÄÀÏ \"%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: Æ÷½ºÆ®½ºÅ©¸³Æ® ÆÄÀÏÀ» ÀμâÇÒ ¼ö ¾ø½À´Ï´Ù"
+
+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¸¦ forkÇÒ ¼ö ¾ø½À´Ï´Ù"
+
+msgid "cs_create_connection exec failed"
+msgstr "cs_create_connection ½ÇÇàÀÌ ½ÇÆÐÇß½À´Ï´Ù"
+
+msgid "cs_create_connection: fdopen for to_fp failed"
+msgstr "cs_create_connection: to_fp¿¡ ´ëÇÑ fdopen ½ÇÆÐ"
+
+msgid "cs_create_connection: fdopen for fr_fp failed"
+msgstr "cs_create_connection: fr_fp¿¡ ´ëÇÑ fdopen ½ÇÆÐ"
+
+msgid "E623: Could not spawn cscope process"
+msgstr "E623: cscope ÇÁ·Î¼¼½º¸¦ spawnÇÒ ¼ö ¾ø½À´Ï´Ù"
+
+msgid "E567: no cscope connections"
+msgstr "E567: cscope ¿¬°áÀÌ ¾ø½À´Ï´Ù"
+
+#, c-format
+#~ msgid "E469: invalid cscopequickfix flag %c for %c"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E259: no matches found for cscope query %s of %s"
+#~ msgstr ""
+
+msgid "cscope commands:\n"
+msgstr "cscope ¸í·É:\n"
+
+#, c-format
+msgid "%-5s: %s%*s (Usage: %s)"
+msgstr "%-5s: %s%*s (»ç¿ë¹ý: %s)"
+
+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"
+
+#, 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 µ¥ÀÌÅͺ£À̽º´Â ´õÇØÁöÁö ¾Ê¾Ò½À´Ï´Ù"
+
+#, c-format
+msgid "E261: cscope connection %s not found"
+msgstr "E261: cscope ¿¬°á %sÀ»(¸¦) ãÀ» ¼ö ¾ø½À´Ï´Ù"
+
+#, c-format
+msgid "cscope connection %s closed"
+msgstr "cscope ¿¬°á %sÀÌ(°¡) ´ÝÇû½À´Ï´Ù"
+
+#. should not reach here
+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 µ¥ÀÌÅͺ£À̽º À̸§ prepend path\n"
+
+#~ msgid "Lua library cannot be loaded."
+#~ msgstr ""
+
+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 "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 "¹®ÀÚ¿­Àº 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 "À߸øµÈ ¼Ó¼º"
+
+#, c-format
+msgid "<buffer object (deleted) at %p>"
+msgstr "<%p¿¡ ¹öÆÛ °´Ã¼ (»èÁ¦µÊ)>"
+
+msgid "E837: This Vim cannot execute :py3 after using :python"
+msgstr "E837: ÀÌ VimÀº :pythonÀ» »ç¿ëÇÑ ÈÄ¿¡ :py3À» »ç¿ëÇÒ ¼ö ¾ø½À´Ï´Ù"
+
+#~ msgid "E265: $_ must be an instance of String"
+#~ msgstr ""
+
+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 "E271: retry outside of rescue clause"
+#~ msgstr ""
+
+msgid "E272: unhandled exception"
+msgstr "E272: ó¸®¾ÊµÈ ¿¹¿Ü"
+
+#, c-format
+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 ""
+
+#~ msgid "Xref referred by"
+#~ msgstr ""
+
+#~ msgid "Xref has a"
+#~ msgstr ""
+
+#~ msgid "Xref used by"
+#~ msgstr ""
+
+#~ 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+ is currently "
+
+msgid "not "
+msgstr "not "
+
+msgid "connected"
+msgstr "connected"
+
+#, c-format
+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 "¸¶Å©°¡ ¼³Á¤µÇÁö ¾Ê¾Ò½À´Ï´Ù"
+
+#, 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 "¸ð¸£´Â ºö ¿É¼Ç"
+
+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 "ÄÝ¹é ¸í·ÉÀ» µî·ÏÇÒ ¼ö ¾ø½À´Ï´Ù: ¹öÆÛ/âÀÌ ÀÌ¹Ì Áö¿öÁ³½À´Ï´Ù"
+
+#. This should never happen. Famous last word?
+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·Î ¾Ë"
+"·ÁÁֽʽÿÀ"
+
+#, 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: ºö ÀνºÅϽº ·¹Áö½ºÆ®¸® ¼Ó¼ºÀÌ À߸øµÇ¾î ÀÖ½À´Ï´Ù. Áö¿ü½À´Ï´Ù!"
+
+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 ""
+
+#, c-format
+msgid "%d files to edit\n"
+msgstr "%d ÆÄÀÏÀ» °íÄ¡±â\n"
+
+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 "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: ¿¡·¯: NetBeans¿¡¼­ gvim ½ÃÀÛ ½ÇÆÐ\n"
+
+msgid "Vim: Warning: Output is not to a terminal\n"
+msgstr "ºö: °æ°í: Å͹̳ηΠÃâ·ÂÇÒ ¼ö ¾ø½À´Ï´Ù\n"
+
+msgid "Vim: Warning: Input is not from a terminal\n"
+msgstr "ºö: °æ°í: Å͹̳ηΠºÎÅÍ ÀԷ¹ÞÀ» ¼ö ¾ø½À´Ï´Ù\n"
+
+#. just in case..
+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 "- Ç¥ÁØÀԷ¿¡¼­ ÅØ½ºÆ® Àбâ"
+
+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 ""
+
+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\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 "-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 "-s\t\t\tSilent (batch) mode (only for \"ex\")"
+msgstr "-s\t\t\tÁ¶¿ëÇÑ (¹èÄ¡) »óÅ (\"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\t½¬¿î »óÅ (\"evim\"°ú °°À½, modeless)"
+
+msgid "-R\t\t\tReadonly mode (like \"view\")"
+msgstr "-R\t\t\tÀбâ Àü¿ë »óÅ (\"view\"¿Í °°À½)"
+
+msgid "-Z\t\t\tRestricted mode (like \"rvim\")"
+msgstr "-Z\t\t\tÁ¦ÇÑµÈ »óÅ (\"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\t¸®½ºÇÁ »óÅÂ"
+
+msgid "-C\t\t\tCompatible with Vi: 'compatible'"
+msgstr "-C\t\t\tVi ȣȯ: 'compatible'"
+
+msgid "-N\t\t\tNot fully Vi compatible: 'nocompatible'"
+msgstr "-N\t\t\tVi¿Í ȣȯµÇÁö ¾ÊÀ½: 'nocompatible'"
+
+#~ msgid "-V[N][fname]\t\tBe verbose [level N] [log messages to fname]"
+#~ msgstr ""
+
+msgid "-D\t\t\tDebugging mode"
+msgstr "-D\t\t\tµð¹ö±ë »óÅÂ"
+
+msgid "-n\t\t\tNo swap file, use memory only"
+msgstr "-n\t\t\t½º¿Ò ÆÄÀÏ ¾øÀÌ ¸Þ¸ð¸®¸¸ »ç¿ë"
+
+msgid "-r\t\t\tList swap files and exit"
+msgstr "-r\t\t\t½º¿Ò ÆÄÀÏ ¸ñ·ÏÀ» Ç¥½ÃÇÑ µÚ ³¡³»±â"
+
+msgid "-r (with file name)\tRecover crashed session"
+msgstr "-r (ÆÄÀÏ À̸§°ú ÇÔ²²)\tÆÄ¼ÕµÇ¾ú´ø ¼¼¼Ç º¹±¸"
+
+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âÀ» ¿­ ¶§ newcli »ç¿ëÇÏÁö ¾ÊÀ½"
+
+msgid "-dev <device>\t\tUse <device> for I/O"
+msgstr "-dev <ÀåÄ¡>\t\tI/O¿¡ <ÀåÄ¡> »ç¿ë"
+
+msgid "-A\t\t\tstart in Arabic mode"
+msgstr "-A\t\t\tArabic ¸ðµå·Î ½ÃÀÛ"
+
+msgid "-H\t\t\tStart in Hebrew mode"
+msgstr "-H\t\t\tHebrew ¸ðµå·Î ½ÃÀÛ"
+
+msgid "-F\t\t\tStart in Farsi mode"
+msgstr "-F\t\t\tFarsi ¸ðµå·Î ½ÃÀÛ"
+
+msgid "-T <terminal>\tSet terminal type to <terminal>"
+msgstr "-T <terminal>\tÅ͹̳ΠÁ¾·ù¸¦ <terminal>·Î ¼³Á¤"
+
+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\tN°³ÀÇ ÅÇ ¿­±â (±âº»: ÆÄÀϺ°·Î Çϳª)"
+
+msgid "-o[N]\t\tOpen N windows (default: one for each file)"
+msgstr "-o[N]\t\tN°³ÀÇ Ã¢ ¿­±â (±âº»: ÆÄÀϺ°·Î Çϳª)"
+
+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 "+<lnum>\t\t<lnum> ÁÙ¿¡¼­ ½ÃÀÛ"
+
+msgid "--cmd <command>\tExecute <command> before loading any vimrc file"
+msgstr "--cmd <¸í·É>\tvimrc ÆÄÀÏÀ» Àбâ Àü¿¡ <¸í·É>À» ½ÇÇà"
+
+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 <scriptin>\t<scriptin> ÆÄÀÏ¿¡¼­ Normal »óÅ ¸í·É Àбâ"
+
+msgid "-w <scriptout>\tAppend all typed commands to file <scriptout>"
+msgstr "-w <scriptout>\t¸ðµç ÀÔ·ÂµÈ ¸í·ÉÀ» <scriptout> ÆÄÀÏ¿¡ Ãß°¡"
+
+msgid "-W <scriptout>\tWrite all typed commands to file <scriptout>"
+msgstr "-W <scriptout>\t¸ðµç ÀÔ·ÂµÈ ¸í·ÉÀ» <scriptout> ÆÄÀÏ¿¡ ÀúÀå"
+
+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 "--startuptime <file>\tWrite startup timing messages to <file>"
+msgstr "--startuptime <file>\tstartup timing ¸Þ½ÃÁö¸¦ <file>¿¡ ÀúÀå"
+
+msgid "-i <viminfo>\t\tUse <viminfo> instead of .viminfo"
+msgstr "-i <viminfo>\t\t.viminfo ´ë½Å <viminfo>¸¦ »ç¿ë"
+
+msgid "-h or --help\tPrint Help (this message) and exit"
+msgstr "-h ȤÀº --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ÀÌ ¾Ë°í ÀÖ´Â ÀÎÀÚ (¸ðƼÇÁ ÆÇ):\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 "µð½ºÇ÷¹À̰¡ ¾ø½À´Ï´Ù"
+
+#. Failed to send, abort.
+msgid ": Send failed.\n"
+msgstr ": º¸³»±â°¡ ½ÇÆÐÇÏ¿´½À´Ï´Ù.\n"
+
+#. Let vim start normally.
+msgid ": Send failed. Trying to execute locally\n"
+msgstr ": º¸³»±â ½ÇÆÐ. ·ÎÄÿ¡¼­ ½ÇÇàµË´Ï´Ù\n"
+
+#, c-format
+#~ msgid "%d of %d edited"
+#~ msgstr ""
+
+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\"¿¡ ¸Â´Â ¸¶Å©°¡ ¾ø½À´Ï´Ù"
+
+#. Highlight title
+msgid ""
+"\n"
+"mark line col file/text"
+msgstr ""
+"\n"
+"¸¶Å© ¶óÀÎ col ÆÄÀÏ/ÅØ½ºÆ®"
+
+#. Highlight title
+msgid ""
+"\n"
+" jump line col file/text"
+msgstr ""
+"\n"
+" Á¡ÇÁ ¶óÀÎ col ÆÄÀÏ/ÅØ½ºÆ®"
+
+#. Highlight title
+#~ msgid ""
+#~ "\n"
+#~ "change line col text"
+#~ msgstr ""
+
+msgid ""
+"\n"
+"# File marks:\n"
+msgstr ""
+"\n"
+"# ÆÄÀÏ ¸¶Å©:\n"
+
+#. Write the jumplist with -'
+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: ½º¿Ò ÆÄÀÏÀ» Àбâ À§ÇØ Æ¯Á¤ À§Ä¡·Î °¥ ¼ö ¾ø½À´Ï´Ù"
+
+msgid "E295: Read error in swap file"
+msgstr "E295: ½º¿Ò ÆÄÀÏÀ» ÀÐÀ» ¼ö ¾ø½À´Ï´Ù"
+
+msgid "E296: Seek error in swap file write"
+msgstr "E296: ½º¿Ò ÆÄÀÏÀ» ¾²±â À§ÇØ Æ¯Á¤ À§Ä¡·Î °¥ ¼ö ¾ø½À´Ï´Ù"
+
+msgid "E297: Write error in swap file"
+msgstr "E297: ½º¿Ò ÆÄÀÏÀ» ¾µ ¼ö ¾ø½À´Ï´Ù"
+
+msgid "E300: Swap file already exists (symlink attack?)"
+msgstr "E300: ½º¿Ò ÆÄÀÏÀÌ ÀÌ¹Ì Á¸ÀçÇÕ´Ï´Ù (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: ½º¿Ò ÆÄÀÏÀ» ¾ÏȣȭÇÒ ¼ö ¾ø½À´Ï´Ù"
+
+#. could not (re)open the swap file, what can we do????
+msgid "E301: Oops, lost the swap file!!!"
+msgstr "E301: À¸À¹, ½º¿Ò ÆÄÀÏÀ» ÀÒ¾î¹ö·È½À´Ï´Ù!!!"
+
+msgid "E302: Could not rename swap file"
+msgstr "E302: ½º¿Ò ÆÄÀÏ À̸§À» ¹Ù²Ü ¼ö ¾ø½À´Ï´Ù"
+
+#, c-format
+msgid "E303: Unable to open swap file for \"%s\", recovery impossible"
+msgstr "E303: \"%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ÀÇ ½º¿Ò ÆÄÀÏÀ» ãÀ» ¼ö ¾ø½À´Ï´Ù"
+
+msgid "Enter number of swap file to use (0 to quit): "
+msgstr "»ç¿ëÇÒ ½º¿Ò ÆÄÀÏ ¹øÈ£¸¦ ÀÔ·ÂÇϽʽÿÀ (0Àº ³¡³»±â): "
+
+#, c-format
+msgid "E306: Cannot open %s"
+msgstr "E306: %sÀ»(¸¦) ¿­ ¼ö ¾ø½À´Ï´Ù"
+
+msgid "Unable to read block 0 from "
+msgstr "Unable to read block 0 from "
+
+msgid ""
+"\n"
+"Maybe no changes were made or Vim did not update the swap file."
+msgstr ""
+"\n"
+"¾î¶² ¼öÁ¤µµ ¾ø¾ú°Å³ª ºöÀÌ ½º¿Ò ÆÄÀÏÀ» °»½ÅÇÏÁö ¾ÊÀº °Í °°½À´Ï´Ù."
+
+msgid " cannot be used with this version of Vim.\n"
+msgstr " cannot be used with this version of Vim.\n"
+
+msgid "Use Vim version 3.0.\n"
+msgstr "ºö 3.0 ÆÇÀ» »ç¿ëÇϽʽÿÀ.\n"
+
+#, c-format
+msgid "E307: %s does not look like a Vim swap file"
+msgstr "E307: %sÀº(´Â) ºö ½º¿Ò ÆÄÀÏÀÌ ¾Æ´Ñ °Í °°½À´Ï´Ù"
+
+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 ""
+
+#, 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 ""
+
+#, c-format
+msgid "Using swap file \"%s\""
+msgstr "½º¿Ò ÆÄÀÏ \"%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 "½º¿Ò ÆÄÀÏÀÌ ¾ÏȣȭµÊ: \"%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"
+"½º¿ÒÆÄÀÏÀ» ÀúÀåÇÏ·Á¸é ¿£Å͸¦ ´©¸£¼¼¿ä"
+
+#, c-format
+msgid "E309: Unable to read block 1 from %s"
+msgstr "E309: %sÀÇ ±¸¿ª 1À» ÀÐÀ» ¼ö ¾ø½À´Ï´Ù"
+
+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: ±¸¿ª 1ÀÇ ID°¡ À߸øµÇ¾ú½À´Ï´Ù (%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 "º¹±¸°¡ ³¡³µ½À´Ï´Ù. ¸ðµç °Ô Á¤»óÀÎ Áö È®ÀÎÇØ º¸¼Å¾ß¸¸ ÇÕ´Ï´Ù."
+
+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 "ÅØ½ºÆ® ÆÄÀÏ¿¡ ½º¿ÒÆÄÀÏ¿¡¼­ °¡Á®¿Â ¾ÏÈ£ ۸¦ »ç¿ëÇÕ´Ï´Ù.\n"
+
+#. use msg() to start the scrolling properly
+msgid "Swap files found:"
+msgstr "½º¿Ò ÆÄÀÏÀ» ã¾ÒÀ½:"
+
+msgid " In current directory:\n"
+msgstr " ÇöÀç µð·ºÅ丮¿¡:\n"
+
+msgid " Using specified name:\n"
+msgstr " ¸í½ÃµÈ À̸§À» »ç¿ë:\n"
+
+msgid " In directory "
+msgstr " In directory "
+
+msgid " -- none --\n"
+msgstr " -- ¾øÀ½ --\n"
+
+msgid " owned by: "
+msgstr " ¼ÒÀ¯ÀÚ: "
+
+msgid " dated: "
+msgstr " ³¯Â¥: "
+
+msgid " dated: "
+msgstr " ³¯Â¥: "
+
+msgid " [from Vim version 3.0]"
+msgstr " [ºö 3.0 ÆÇÀÇ °Í]"
+
+msgid " [does not look like a Vim swap file]"
+msgstr " [ºö ½º¿Ò ÆÄÀÏ·Î º¸ÀÌÁö ¾Ê½À´Ï´Ù]"
+
+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"
+" ÇÁ·Î¼¼½º ID: "
+
+msgid " (still running)"
+msgstr " (¾ÆÁ÷ ½ÇÇàÁß)"
+
+msgid ""
+"\n"
+" [not usable with this version of Vim]"
+msgstr ""
+"\n"
+" [ºö À̹ø ÆÇ¿¡¼­´Â »ç¿ëÇÒ ¼ö ¾øÀ½]"
+
+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: º¸Á¸ÇÒ ¼ö ¾ø½À´Ï´Ù, ½º¿Ò ÆÄÀÏÀÌ ¾ø½À´Ï´Ù"
+
+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: À߸øµÈ Æ÷ÀÎÅÍ ±¸¿ª id 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: À߸øµÈ Æ÷ÀÎÅÍ ±¸¿ª id 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: À߸øµÈ Æ÷ÀÎÅÍ ±¸¿ª id"
+
+msgid "pe_line_count is zero"
+msgstr "pe_line_count°¡ 0ÀÔ´Ï´Ù"
+
+#, 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: À߸øµÈ Æ÷ÀÎÅÍ ±¸¿ª id 2"
+
+#, c-format
+#~ msgid "E773: Symlink loop for \"%s\""
+#~ msgstr ""
+
+msgid "E325: ATTENTION"
+msgstr "E325: ÁÖ¸ñ"
+
+msgid ""
+"\n"
+"Found a swap file by the name \""
+msgstr ""
+"\n"
+"Found a swap file by the name \""
+
+msgid "While opening file \""
+msgstr "While opening file \""
+
+msgid " NEWER than swap file!\n"
+msgstr " NEWER than swap file!\n"
+
+#. Some of these messages are long to allow translation to
+#. * other languages.
+msgid ""
+"\n"
+"(1) Another program may be editing the same file.\n"
+" If this is the case, be careful not to end up with two\n"
+" different instances of the same file when making changes.\n"
+msgstr ""
+"\n"
+"(1) ´Ù¸¥ ÇÁ·Î±×·¥ÀÌ °°Àº ÆÄÀÏÀ» °íÄ¡°í ÀÖ´ÂÁßÀÏ ¼ö ÀÖ½À´Ï´Ù.\n"
+" ¸¸¾à ±×·¸´Ù¸é °°Àº ÆÄÀÏÀ» µÎ °³ÀÇ ÇÁ·Î±×·¥¿¡¼­ °íÄ¡Áö\n"
+" ¾Êµµ·Ï Á¶½ÉÇϽñ⠹ٶø´Ï´Ù.\n"
+
+msgid " Quit, or continue with caution.\n"
+msgstr " ³¡³»°Å³ª À§ÇèÀ» °¨¼öÇϽ÷Á¸é °è¼ÓÇϽʽÿÀ.\n"
+
+msgid ""
+"\n"
+"(2) An edit session for this file crashed.\n"
+msgstr ""
+"\n"
+"(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 " ÀÌ¹Ì º¹±¸Çϼ̾ú´Ù¸é ½º¿ÒÆÄÀÏ \""
+
+msgid ""
+"\"\n"
+" to avoid this message.\n"
+msgstr ""
+"\"\n"
+" À»(¸¦) Áö¿ì¼Å¾ß ÀÌ ¸Þ½ÃÁö°¡ »ç¶óÁý´Ï´Ù.\n"
+
+msgid "Swap file \""
+msgstr "½º¿Ò ÆÄÀÏ \""
+
+msgid "\" already exists!"
+msgstr "\"ÀÌ ÀÌ¹Ì Á¸ÀçÇÕ´Ï´Ù!"
+
+msgid "VIM - ATTENTION"
+msgstr "ºö - ÁÖ¸ñ"
+
+msgid "Swap file already exists!"
+msgstr "½º¿Ò ÆÄÀÏÀÌ ÀÌ¹Ì Á¸ÀçÇÕ´Ï´Ù!"
+
+msgid ""
+"&Open Read-Only\n"
+"&Edit anyway\n"
+"&Recover\n"
+"&Quit\n"
+"&Abort"
+msgstr ""
+"Àбâ Àü¿ëÀ¸·Î ¿­±â(&O)\n"
+"±×³É °íÄ¡±â(&E)\n"
+"º¹±¸(&R)\n"
+"³¡³»±â(&Q)\n"
+"¹ö¸®±â(&A)"
+
+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)"
+
+msgid "E326: Too many swap files found"
+msgstr "E326: ³Ê¹« ¸¹Àº ½º¿Ò ÆÄÀÏÀÌ ¹ß°ßµÇ¾ú½À´Ï´Ù"
+
+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\" ¸Þ´º ¾øÀ½"
+
+#. Only a mnemonic or accelerator is not valid.
+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: ±¸ºÐÀÚ´Â ¸Þ´º °æ·ÎÀÇ ºÎºÐÀÌ µÉ ¼ö ¾ø½À´Ï´Ù"
+
+#. Now we have found the matching menu, and we list the mappings
+#. Highlight title
+msgid ""
+"\n"
+"--- Menus ---"
+msgstr ""
+"\n"
+"--- ¸Þ´º ---"
+
+msgid "Tear off this menu"
+msgstr "ÀÌ ¸Þ´º¸¦ ¶¼¾î³¿"
+
+msgid "E333: Menu path must lead to a menu item"
+msgstr "E333: ¸Þ´º Ç׸ñ ¾Õ¿¡´Â ¸Þ´º °æ·Î°¡ ÀÖ¾î¾ß ÇÕ´Ï´Ù"
+
+#, c-format
+msgid "E334: Menu not found: %s"
+msgstr "E334: ¸Þ´º¸¦ ãÀ» ¼ö ¾ø½À´Ï´Ù: %s"
+
+#, c-format
+msgid "E335: Menu not defined for %s mode"
+msgstr "E335: %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 "¸Þ½ÃÁö °ü¸®ÀÚ: Bram Moolenaar <Bram@vim.org>"
+
+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 " SPACE/d/j: È­¸é/ÆäÀÌÁö/¶óÀÎ ¾Æ·¡·Î, b/u/k: À§·Î, q: Á¾·á "
+
+msgid "Question"
+msgstr "Áú¹®"
+
+msgid ""
+"&Yes\n"
+"&No"
+msgstr ""
+"¿¹(&Y)\n"
+"¾Æ´Ï¿À(&N)"
+
+msgid ""
+"&Yes\n"
+"&No\n"
+"Save &All\n"
+"&Discard All\n"
+"&Cancel"
+msgstr ""
+"¿¹(&Y)\n"
+"¾Æ´Ï¿À(&N)\n"
+"¸ðµÎ ÀúÀå(&A)\n"
+"¸ðµÎ ¹ö¸²(&D)\n"
+"Ãë¼Ò(&C)"
+
+msgid "Select Directory dialog"
+msgstr "µð·ºÅ丮 ¼±Åà ´ëÈ­»óÀÚ"
+
+msgid "Save File dialog"
+msgstr "ÆÄÀÏ ÀúÀå ´ëÈ­»óÀÚ"
+
+msgid "Open File dialog"
+msgstr "ÆÄÀÏ ¿­±â ´ëÈ­»óÀÚ"
+
+#. TODO: non-GUI file selector here
+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: printf()¿¡ ¿¹»ó¸øÇÑ Float ÀÎÀÚ"
+
+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 "¼ýÀÚ ÀÔ·ÂÈÄ <¿£ÅÍ>³ª ¸¶¿ì½º Ŭ¸¯ (¼ýÀÚ¾øÀ¸¸é Ãë¼Ò): "
+
+msgid "Type number and <Enter> (empty cancels): "
+msgstr "¼ýÀÚ ÀÔ·ÂÈÄ <¿£ÅÍ> (¼ýÀÚ¾øÀ¸¸é Ãë¼Ò): "
+
+msgid "1 more line"
+msgstr "ÇÑ ÁÙ ÀÌ»ó"
+
+msgid "1 line less"
+msgstr "ÇÑ ÁÙ ÀÌÇÏ"
+
+#, c-format
+msgid "%ld more lines"
+msgstr "%ld º¸´Ù ¸¹Àº ÁÙ"
+
+#, c-format
+msgid "%ld fewer lines"
+msgstr "%ld º¸´Ù ÀûÀº ÁÙ"
+
+msgid " (Interrupted)"
+msgstr " (ÁߴܵǾú½À´Ï´Ù)"
+
+msgid "Beep!"
+msgstr "Ȉ!"
+
+msgid "Vim: preserving files...\n"
+msgstr "ºö: ÆÄÀÏ º¸Á¸Áß...\n"
+
+#. close all memfiles, without deleting
+msgid "Vim: Finished.\n"
+msgstr "ºö: ²ø³µ½À´Ï´Ù.\n"
+
+msgid "ERROR: "
+msgstr "¿¡·¯: "
+
+#, c-format
+#~ msgid ""
+#~ "\n"
+#~ "[bytes] total alloc-freed %lu-%lu, in use %lu, peak use %lu\n"
+#~ msgstr ""
+
+#, c-format
+#~ msgid ""
+#~ "[calls] total re/malloc()'s %lu, total free()'s %lu\n"
+#~ "\n"
+#~ msgstr ""
+
+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: ÀÌ»óÇÑ ¸¶¿ì½º¸ð¾ç"
+
+msgid "E548: digit expected"
+msgstr "E548: ¼ýÀÚ°¡ ÇÊ¿äÇÕ´Ï´Ù"
+
+msgid "E549: Illegal percentage"
+msgstr "E549: ÀÌ»óÇÑ ¹éºÐÀ²"
+
+msgid "Enter encryption key: "
+msgstr "¾ÏÈ£ Ű ÀÔ·Â: "
+
+msgid "Enter same key again: "
+msgstr "°°Àº ۸¦ ´Ù½Ã ÀÔ·Â: "
+
+msgid "Keys don't match!"
+msgstr "۰¡ ¸ÂÁö ¾Ê½À´Ï´Ù!"
+
+#, 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: 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: path¿¡¼­ ´õ ÀÌ»óÀÇ \"%s\" ÆÄÀÏÀ» ãÀ» ¼ö ¾ø½À´Ï´Ù"
+
+msgid "Cannot connect to Netbeans #2"
+msgstr "Netbeans #2¿¡ ¿¬°áÇÒ ¼ö ¾ø½À´Ï´Ù"
+
+msgid "Cannot connect to Netbeans"
+msgstr "Netbeans¿¡ ¿¬°áÇÒ ¼ö ¾ø½À´Ï´Ù"
+
+#, c-format
+msgid "E668: Wrong access mode for NetBeans connection info file: \"%s\""
+msgstr "E668: NetBeans ¿¬°á Á¤º¸ ÆÄÀÏÀÌ Á¢±Ù ¸ðµå°¡ À߸øµÊ: \"%s\""
+
+msgid "read from Netbeans socket"
+msgstr "Netbeans ¼ÒÄÏ¿¡¼­ Àбâ"
+
+#, 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: ÀÌ GUI´Â netbeans¸¦ Áö¿øÇÏÁö ¾Ê½À´Ï´Ù"
+
+msgid "E511: netbeans already connected"
+msgstr "E511: netbeans°¡ ÀÌ¹Ì ¿¬°áµÇ¾î ÀÖ½À´Ï´Ù"
+
+msgid "E505: "
+msgstr "E505: "
+
+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: changelist°¡ ºñ¾ú½À´Ï´Ù"
+
+#~ msgid "E662: At start of changelist"
+#~ msgstr ""
+
+#~ msgid "E663: At end of changelist"
+#~ msgstr ""
+
+msgid "Type :quit<Enter> to exit Vim"
+msgstr "VIMÀ» ¸¶Ä¡·Á¸é :quit<Enter> ÀÔ·Â"
+
+#, c-format
+msgid "1 line %sed 1 time"
+msgstr "1 line %sed 1 time"
+
+#, c-format
+msgid "1 line %sed %d times"
+msgstr "1 line %sed %d times"
+
+#, c-format
+msgid "%ld lines %sed 1 time"
+msgstr "%ld lines %sed 1 time"
+
+#, c-format
+msgid "%ld lines %sed %d times"
+msgstr "%ld lines %sed %d times"
+
+#, c-format
+msgid "%ld lines to indent... "
+msgstr "%ld lines to indent... "
+
+msgid "1 line indented "
+msgstr "1 line indented "
+
+#, c-format
+msgid "%ld lines indented "
+msgstr "%ld lines indented "
+
+#~ msgid "E748: No previously used register"
+#~ msgstr ""
+
+#. must display the prompt
+msgid "cannot yank; delete anyway"
+msgstr "cannot yank; delete anyway"
+
+msgid "1 line changed"
+msgstr "1 line changed"
+
+#, c-format
+msgid "%ld lines changed"
+msgstr "%ld lines changed"
+
+#, c-format
+msgid "freeing %ld lines"
+msgstr "freeing %ld lines"
+
+msgid "block of 1 line yanked"
+msgstr "block of 1 line yanked"
+
+msgid "1 line yanked"
+msgstr "1 line yanked"
+
+#, c-format
+msgid "block of %ld lines yanked"
+msgstr "block of %ld lines yanked"
+
+#, c-format
+msgid "%ld lines yanked"
+msgstr "%ld lines yanked"
+
+#, c-format
+msgid "E353: Nothing in register %s"
+msgstr "E353: %s ·¹Áö½ºÅÍ¿¡ ¾Æ¹« °Íµµ ¾ø½À´Ï´Ù"
+
+#. Highlight title
+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"
+
+#, c-format
+msgid "%ld Cols; "
+msgstr "%ld ¿­; "
+
+#, c-format
+msgid "Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Bytes"
+msgstr "Selected %s%ld of %ld ¶óÀÎ; %ld of %ld ´Ü¾î; %ld of %ld ¹ÙÀÌÆ®"
+
+#, c-format
+msgid ""
+"Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Chars; %ld of %ld "
+"Bytes"
+msgstr ""
+"Selected %s%ld of %ld ¶óÀÎ; %ld of %ld ´Ü¾î; %ld of %ld ¹®ÀÚ; %ld of %ld ¹ÙÀÌ"
+"Æ®"
+
+#, c-format
+msgid "Col %s of %s; Line %ld of %ld; Word %ld of %ld; Byte %ld of %ld"
+msgstr "Col %s of %s; ¶óÀÎ %ld of %ld; ´Ü¾î %ld of %ld; ¹ÙÀÌÆ® %ld of %ld"
+
+#, c-format
+msgid ""
+"Col %s of %s; Line %ld of %ld; Word %ld of %ld; Char %ld of %ld; Byte %ld of "
+"%ld"
+msgstr ""
+"Col %s of %s; ¶óÀÎ %ld of %ld; ´Ü¾î %ld of %ld; ¹®ÀÚ %ld of %ld; ¹ÙÀÌÆ® %ld "
+"of %ld"
+
+#, c-format
+msgid "(+%ld for BOM)"
+msgstr "(+%ld for BOM)"
+
+msgid "%<%f%h%m%=Page %N"
+msgstr "%<%f%h%m%=ÆäÀÌÁö %N"
+
+msgid "Thanks for flying Vim"
+msgstr "ºöÀ» ³¯°Ô ÇØ Áּż­ °í¸¿½À´Ï´Ù"
+
+msgid "E518: Unknown option"
+msgstr "E518: ¸ð¸£´Â ¿É¼Ç"
+
+msgid "E519: Option not supported"
+msgstr "E519: Áö¿øµÇÁö ¾Ê´Â ¿É¼ÇÀÔ´Ï´Ù"
+
+msgid "E520: Not allowed in a modeline"
+msgstr "E520: ¸ðµå¶óÀο¡¼­ »ç¿ëµÉ ¼ö ¾ø½À´Ï´Ù"
+
+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>"
+
+msgid "E529: Cannot set 'term' to empty string"
+msgstr "E529: 'term'À» ºó ¹®ÀÚ¿­·Î ¼³Á¤ÇÒ ¼ö ¾ø½À´Ï´Ù"
+
+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'°¡ µ¿ÀÏÇÕ´Ï´Ù"
+
+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¿¡¼­´Â ¹Ù²ð ¼ö ¾ø½À´Ï´Ù"
+
+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: ±Û²Ã¼ÂÀ» °í¸¦ ¼ö ¾ø½À´Ï´Ù"
+
+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> µÚ¿¡ ÀÌ»óÇÑ ±ÛÀÚ"
+
+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 "E590: A preview window already exists"
+msgstr "E590: ¹Ì¸® º¸±â âÀÌ ÀÌ¹Ì Á¸ÀçÇÕ´Ï´Ù"
+
+msgid "W17: Arabic requires UTF-8, do ':set encoding=utf-8'"
+msgstr "W17: ArabicÀº UTF-8 ÀÎÄÚµù ÇÊ¿ä, ':set encoding=utf-8' Çϼ¼¿ä"
+
+#, 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"
+
+#. 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.
+#, 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 "cannot open "
+
+msgid "VIM: Can't open window!\n"
+msgstr "ºö: âÀ» ¿­ ¼ö ¾ø½À´Ï´Ù!\n"
+
+msgid "Need Amigados version 2.04 or later\n"
+msgstr "¾Æ¹Ì°¡µµ½º 2.04³ª ´õ ³ôÀº ÆÇÀÌ ÇÊ¿äÇÕ´Ï´Ù\n"
+
+#, c-format
+msgid "Need %s version %ld\n"
+msgstr "Need %s version %ld\n"
+
+msgid "Cannot open NIL:\n"
+msgstr "NILÀ» ¿­ ¼ö ¾øÀ½:\n"
+
+msgid "Cannot create "
+msgstr "Cannot create "
+
+#, c-format
+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"
+
+#. if Vim opened a window: Executing a shell may cause crashes
+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: ÇÁ¸°Å͸¦ °í¸£Áö ¸øÇß½À´Ï´Ù"
+
+#, c-format
+msgid "to %s on %s"
+msgstr "to %s on %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 "E245: Illegal char '%c' in font name \"%s\""
+msgstr "E245: À߸øµÈ ±ÛÀÚ '%c'ÀÌ(°¡) ±Û²Ã À̸§ \"%s\"¿¡ ÀÖ½À´Ï´Ù"
+
+msgid "Vim: Double signal, exiting\n"
+msgstr "ºö: °°Àº ½Ã±×³Î µÎ ¹ø, ³¡³À´Ï´Ù\n"
+
+#, c-format
+msgid "Vim: Caught deadly signal %s\n"
+msgstr "ºö: %s ½Ã±×³ÎÀ» Àâ¾Ò½À´Ï´Ù\n"
+
+#, c-format
+msgid "Vim: Caught deadly signal\n"
+msgstr "ºö: Á×À» ½Ã±×³ÎÀ» Àâ¾Ò½À´Ï´Ù\n"
+
+#, c-format
+msgid "Opening the X display took %ld msec"
+msgstr "X µð½ºÇ÷¹À̸¦ ¿©´Â µ¥ %ld 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"
+"Could not get security context for "
+msgstr ""
+"\n"
+"Could not get security context for "
+
+msgid ""
+"\n"
+"Could not set security context for "
+msgstr ""
+"\n"
+"Could not set security context for "
+
+msgid ""
+"\n"
+"Cannot execute shell "
+msgstr ""
+"\n"
+"Cannot execute shell "
+
+msgid ""
+"\n"
+"Cannot execute shell sh\n"
+msgstr ""
+"\n"
+"½© sh¸¦ ½ÇÇàÇÒ ¼ö ¾ø½À´Ï´Ù\n"
+
+msgid ""
+"\n"
+"shell returned "
+msgstr ""
+"\n"
+"shell returned "
+
+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 ¿¬°áÀ» ÀÒ¾î¹ö·È½À´Ï´Ù"
+
+#, c-format
+msgid "dlerror = \"%s\""
+msgstr "dlerror = \"%s\""
+
+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 ¿¬°á °¨½Ã¸¦ ½ÇÆÐÇß½À´Ï´Ù"
+
+#, c-format
+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·Î ¹Ù²Ü ¼ö ¾ø½À´Ï´Ù!"
+
+#, c-format
+msgid "shell returned %d"
+msgstr "½©ÀÌ %dÀ»(¸¦) µ¹·ÁÁÖ¾ú½À´Ï´Ù"
+
+#, c-format
+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 "ºö °æ°í"
+
+#, 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: ´õ ÀÌ»óÀÇ Ç׸ñÀÌ ¾ø½À´Ï´Ù"
+
+#, c-format
+msgid "(%d of %d)%s%s: "
+msgstr "(%d of %d)%s%s: "
+
+msgid " (line deleted)"
+msgstr " (ÁÙÀ» Áö¿üÀ½)"
+
+msgid "E380: At bottom of quickfix stack"
+msgstr "E380: ÄüÇȽº ½ºÅÃÀÇ ¹Ù´ÚÀÔ´Ï´Ù"
+
+msgid "E381: At top of quickfix stack"
+msgstr "E381: ÄüÇȽº ½ºÅÃÀÇ ²À´ë±âÀÔ´Ï´Ù"
+
+#, c-format
+msgid "error list %d of %d; %d errors"
+msgstr "error list %d of %d; %d errors"
+
+msgid "E382: Cannot write, 'buftype' option is set"
+msgstr "E382: ¾µ ¼ö ¾øÀ½, 'buftype' ¿É¼ÇÀÌ ¼³Á¤µÇ¾î ÀÖ½À´Ï´Ù"
+
+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%%[]¿¡ À߸øµÈ Ç׸ñ"
+
+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 "E53: Unmatched %s%%("
+msgstr "E53: ¸ÂÁö ¾Ê´Â %s%%("
+
+#, c-format
+msgid "E54: Unmatched %s("
+msgstr "E54: ¸ÂÁö ¾Ê´Â %s("
+
+#, c-format
+msgid "E55: Unmatched %s)"
+msgstr "E55: ¸ÂÁö ¾Ê´Â %s)"
+
+#, 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: Nested %s*"
+
+#, c-format
+msgid "E62: Nested %s%c"
+msgstr "E62: Nested %s%c"
+
+msgid "E63: invalid use of \\_"
+msgstr "E63: \\_¸¦ Àß ¸ø »ç¿ë"
+
+#, c-format
+msgid "E64: %s%c follows nothing"
+msgstr "E64: %s%c µÚ¿¡ ¾Æ¹«°Íµµ ¾ø½À´Ï´Ù"
+
+msgid "E65: Illegal back reference"
+msgstr "E65: ÀÌ»óÇÑ ÈÄÀ§ ÂüÁ¶"
+
+msgid "E66: \\z( not allowed here"
+msgstr "E66: \\z(´Â ¿©±â¿¡¼­ Çã¿ëµÇÁö ¾Ê½À´Ï´Ù"
+
+msgid "E67: \\z1 et al. not allowed here"
+msgstr "E67: \\z1 µîÀº ¿©±â¿¡¼­ Çã¿ëµÇÁö ¾Ê½À´Ï´Ù"
+
+msgid "E68: Invalid character after \\z"
+msgstr "E68: \\z µÚ¿¡ ÀÌ»óÇÑ ¹®ÀÚ"
+
+#, c-format
+msgid "E69: Missing ] after %s%%["
+msgstr "E69: %s%%[ µÚ¿¡ ]°¡ ¾ø½À´Ï´Ù"
+
+#, c-format
+msgid "E70: Empty %s%%[]"
+msgstr "E70: ºó %s%%[]"
+
+#, 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 "E769: Missing ] after %s["
+msgstr "E769: %s[ µÚ¿¡ ]°¡ ¾ø½À´Ï´Ù"
+
+#, c-format
+msgid "E554: Syntax error in %s{...}"
+msgstr "E554: %s{...}¿¡ ±¸¹® ¿¡·¯"
+
+msgid "External submatches:\n"
+msgstr "¿ÜºÎ submatches:\n"
+
+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 " (lang)"
+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 " (ÀÌÀü¿¡ ¸Â¾Ò´ø ¸ñ·Ï Æ÷ÇÔ)"
+
+#. cursor at status line
+msgid "--- Included files "
+msgstr "--- Included files "
+
+msgid "not found "
+msgstr "not found "
+
+msgid "in path ---\n"
+msgstr "in path ---\n"
+
+msgid " (Already listed)"
+msgstr " (Already listed)"
+
+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 "Substitute "
+
+#, c-format
+msgid ""
+"\n"
+"# Last %sSearch Pattern:\n"
+"~"
+msgstr ""
+"\n"
+"# Last %sSearch Pattern:\n"
+"~"
+
+msgid "E759: Format error in spell file"
+msgstr "E759: spell ÆÄÀÏ Çü½Ä ¿¡·¯"
+
+msgid "E758: Truncated spell file"
+msgstr "E758: À߸° spell ÆÄÀÏ"
+
+#, c-format
+msgid "Trailing text in %s line %d: %s"
+msgstr "Trailing text in %s line %d: %s"
+
+#, c-format
+msgid "Affix name too long in %s line %d: %s"
+msgstr "Affix name too long in %s line %d: %s"
+
+msgid "E761: Format error in affix file FOL, LOW or UPP"
+msgstr "E761: affix ÆÄÀÏ 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 "´Ü¾î Æ®¸® ¾ÐÃàÁß..."
+
+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\"À» ãÀ» ¼ö ¾ø½À´Ï´Ù"
+
+#, c-format
+msgid "Reading spell file \"%s\""
+msgstr "spell ÆÄÀÏ \"%s\"À»(¸¦) Àаí ÀÖ½À´Ï´Ù"
+
+msgid "E757: This does not look like a spell file"
+msgstr "E757: spell ÆÄÀÏÀÌ ¾Æ´Ñ °Í °°½À´Ï´Ù"
+
+msgid "E771: Old spell file, needs to be updated"
+msgstr "E771: ¿À·¡µÈ spell ÆÄÀÏ, °»½ÅÀÌ ÇÊ¿äÇÕ´Ï´Ù"
+
+msgid "E772: Spell file is for newer version of Vim"
+msgstr "E772: Spell ÆÄÀÏÀÌ »õ ¹öÁ¯ÀÇ Vim¿ëÀÔ´Ï´Ù"
+
+msgid "E770: Unsupported section in spell file"
+msgstr "E770: spell ÆÄÀÏ¿¡ Áö¿øµÇÁö ¾Ê´Â ¼½¼Ç"
+
+#, c-format
+msgid "Warning: region %s not supported"
+msgstr "°æ°í: %s ¿µ¿ªÀº Áö¿øµÇÁö ¾Ê½À´Ï´Ù"
+
+#, c-format
+msgid "Reading affix file %s ..."
+msgstr "affix ÆÄÀÏ %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 "%s ¶óÀÎ %d¿¡ FLAG¿¡ ´ëÇÑ À߸øµÈ °ª: %s"
+
+#, c-format
+msgid "FLAG after using flags in %s line %d: %s"
+msgstr "%s ¶óÀÎ %d¿¡ Ç÷¡±×°¡ »ç¿ëµÈ ÈÄ FLAG: %s"
+
+#, c-format
+msgid ""
+"Defining COMPOUNDFORBIDFLAG after PFX item may give wrong results in %s line "
+"%d"
+msgstr ""
+"%s ¶óÀÎ %d¿¡ PFX µÚ¿¡ COMPOUNDFORBIDFLAGÀ» Á¤ÀÇÇÑ °ÍÀº À߸øµÈ °á°ú¸¦ ÃÊ·¡ÇÒ "
+"¼ö ÀÖ½À´Ï´Ù"
+
+#, c-format
+msgid ""
+"Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in %s line "
+"%d"
+msgstr ""
+"%s ¶óÀÎ %d¿¡ PFX µÚ¿¡ COMPOUNDPERMITFLAGÀ» Á¤ÀÇÇÑ °ÍÀº À߸øµÈ °á°ú¸¦ ÃÊ·¡ÇÒ "
+"¼ö ÀÖ½À´Ï´Ù"
+
+#, c-format
+msgid "Wrong COMPOUNDRULES value in %s line %d: %s"
+msgstr "%s ¶óÀÎ %d¿¡ À߸øµÈ COMPOUNDRULES °ª: %s"
+
+#, c-format
+msgid "Wrong COMPOUNDWORDMAX value in %s line %d: %s"
+msgstr "%s ¶óÀÎ %d¿¡ À߸øµÈ COMPOUNDWORDMAX °ª: %s"
+
+#, c-format
+msgid "Wrong COMPOUNDMIN value in %s line %d: %s"
+msgstr "%s ¶óÀÎ %d¿¡ À߸øµÈ COMPOUNDMIN °ª: %s"
+
+#, c-format
+msgid "Wrong COMPOUNDSYLMAX value in %s line %d: %s"
+msgstr "%s ¶óÀÎ %d¿¡ À߸øµÈ COMPOUNDSYLMAX °ª: %s"
+
+#, c-format
+msgid "Wrong CHECKCOMPOUNDPATTERN value in %s line %d: %s"
+msgstr "%s ¶óÀÎ %d¿¡ À߸øµÈ CHECKCOMPOUNDPATTERN °ª: %s"
+
+#, c-format
+msgid "Different combining flag in continued affix block in %s line %d: %s"
+msgstr "%s ¶óÀÎ %d¿¡ ¿¬¼ÓµÈ affix ºí·Ï¿¡ ´Ù¸¥ °áÇÕ Ç÷¡±×: %s"
+
+#, c-format
+msgid "Duplicate affix in %s line %d: %s"
+msgstr "%s ¶óÀÎ %d¿¡ Áߺ¹µÈ affix: %s"
+
+#, 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"
+
+#, c-format
+msgid "Expected Y or N in %s line %d: %s"
+msgstr "%s ¶óÀÎ %d¿¡ Y³ª NÀÌ ±â´ëµÊ: %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 "%s ¶óÀÎ %d¿¡ REP(SAL) Ä«¿îÆ®°¡ ±â´ëµÊ"
+
+#, c-format
+msgid "Expected MAP count in %s line %d"
+msgstr "%s ¶óÀÎ %d¿¡ MAP Ä«¿îÆ®°¡ ±â´ëµÊ"
+
+#, c-format
+msgid "Duplicate character in MAP in %s line %d"
+msgstr "%s ¶óÀÎ %dÀÇ MAP¿¡ Áߺ¹µÈ ¹®ÀÚ"
+
+#, 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 "%s¿¡ FOL/LOW/UPPÀÌ ´©¶ôµÈ ¶óÀÎ"
+
+msgid "COMPOUNDSYLMAX used without SYLLABLE"
+msgstr "COMPOUNDSYLMAXÀÌ SYLLABLE¾øÀÌ »ç¿ëµÊ"
+
+msgid "Too many postponed prefixes"
+msgstr "postponed Á¢µÎ»ç°¡ ³Ê¹« ¸¹½À´Ï´Ù"
+
+msgid "Too many compound flags"
+msgstr "compound Ç÷¡±×°¡ ³Ê¹« ¸¹½À´Ï´Ù"
+
+msgid "Too many postponed prefixes and/or compound flags"
+msgstr "postponed Á¢µÎ»ç¿Í(³ª) compound Ç÷¡±×°¡ ³Ê¹« ¸¹½À´Ï´Ù"
+
+#, c-format
+msgid "Missing SOFO%s line in %s"
+msgstr "SOFO%s°¡ ´©¶ôµÈ ¶óÀÎÀÌ %s¿¡ ÀÖ½À´Ï´Ù"
+
+#, c-format
+msgid "Both SAL and SOFO lines in %s"
+msgstr "%s¿¡ SAL°ú SOFO ¶óÀÎÀÌ µÑ ´Ù ÀÖ½À´Ï´Ù"
+
+#, 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 %6d - %s"
+msgstr "¶óÀÎ %6d, ´Ü¾î %6d - %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°³ÀÇ ¾Æ½ºÅ°¹®ÀÚ¿­ÀÌ ¾Æ´Ñ ´Ü¾î°¡ %s¿¡ ÀÖ½À´Ï´Ù"
+
+#, c-format
+msgid "Reading word file %s ..."
+msgstr "´Ü¾î ÆÄÀÏ %s Àд Áß ..."
+
+#, c-format
+msgid "Duplicate /encoding= line ignored in %s line %d: %s"
+msgstr "%s ¶óÀÎ %dÀÇ Áߺ¹µÈ /encoding= ¶óÀÎ ¹«½ÃµÊ: %s"
+
+#, c-format
+msgid "/encoding= line after word ignored in %s line %d: %s"
+msgstr "%s ¶óÀÎ %dÀÇ ´Ü¾î µÚÀÇ /encoding= ¶óÀÎ ¹«½ÃµÊ: %s"
+
+#, c-format
+msgid "Duplicate /regions= line ignored in %s line %d: %s"
+msgstr "%s ¶óÀÎ %dÀÇ Áߺ¹µÈ /regions= ¶óÀÎ ¹«½ÃµÊ: %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°³ÀÇ ´Ü¾î°¡ ¹«½ÃµÇ¾ú½À´Ï´Ù"
+
+#~ msgid "E845: Insufficient memory, word list will be incomplete"
+#~ msgstr ""
+
+#, c-format
+msgid "Compressed %d of %d nodes; %d (%d%%) remaining"
+msgstr "%d/%d ³ëµå°¡ ¾ÐÃàµÊ; %d (%d%%)°¡ ³²À½"
+
+msgid "Reading back spell file..."
+msgstr "¸ÂÃã¹ý ÆÄÀÏÀ» Àд Áß..."
+
+#.
+#. * Go through the trie of good words, soundfold each word and add it to
+#. * the soundfold trie.
+#.
+msgid "Performing soundfolding..."
+msgstr "soundfold ¼öÇàÁß..."
+
+#, c-format
+msgid "Number of words after soundfolding: %ld"
+msgstr "soundfold ¼öÇà ÈÄÀÇ ´Ü¾î ¼ö: %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: »ý¼º ÆÄÀϸíÀº ¿µ¿ª À̸§°ú ´Þ¶ó¾ß ÇÕ´Ï´Ù"
+
+msgid "E754: Only up to 8 regions supported"
+msgstr "E754: ÃÖ´ë 8°³ÀÇ ¿µ¿ªÀÌ Áö¿øµË´Ï´Ù"
+
+#, c-format
+msgid "E755: Invalid region in %s"
+msgstr "E755: %s¿¡ À߸øµÈ ¿µ¿ª"
+
+msgid "Warning: both compounding and NOBREAK specified"
+msgstr "°æ°í: compound¿Í NOBREAK µÑ ´Ù ¸í½ÃµÊ"
+
+#, c-format
+msgid "Writing spell file %s ..."
+msgstr "spell ÆÄÀÏ %s ¾²´Â Áß ..."
+
+msgid "Done!"
+msgstr "³¡!"
+
+#, c-format
+msgid "E765: 'spellfile' does not have %ld entries"
+msgstr "E765: 'spellfile'¿¡ %ld Ç׸ñÀÌ ¾ø½À´Ï´Ù"
+
+#, c-format
+msgid "Word removed from %s"
+msgstr "%s¿¡¼­ ´Ü¾î »èÁ¦µÊ"
+
+#, c-format
+msgid "Word added to %s"
+msgstr "%s¿¡ ´Ü¾î Ãß°¡µÊ"
+
+msgid "E763: Word characters differ between spell files"
+msgstr "E763: ´Ü¾î°¡ spell ÆÄÀÏ °£¿¡ ´Ù¸¨´Ï´Ù"
+
+msgid "Sorry, no suggestions"
+msgstr "Á˼Û, Á¦¾ÈÇÒ °Ô ¾ø½À´Ï´Ù"
+
+#, c-format
+msgid "Sorry, only %ld suggestions"
+msgstr "Á˼Û, %ld°³¸¸ Á¦¾È"
+
+#. for when 'cmdheight' > 1
+#. avoid more prompt
+#, c-format
+msgid "Change \"%.*s\" to:"
+msgstr "Change \"%.*s\" to:"
+
+#, c-format
+msgid " < \"%.*s\""
+msgstr " < \"%.*s\""
+
+msgid "E752: No previous spell replacement"
+msgstr "E752: öÀÚ°¡ ¹Ù²ïÀûÀÌ ¾ø½À´Ï´Ù"
+
+#, c-format
+msgid "E753: Not found: %s"
+msgstr "E753: ãÀ» ¼ö ¾øÀ½: %s"
+
+#, 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"
+
+#. This should have been checked when generating the .spl
+#. * file.
+msgid "E783: duplicate char in MAP entry"
+msgstr "E783: MAP Ç׸ñ¿¡ Áߺ¹µÈ ¹®ÀÚ"
+
+#, c-format
+msgid "E390: Illegal argument: %s"
+msgstr "E390: À߸øµÈ ÀÎÀÚ: %s"
+
+#, c-format
+msgid "E391: No such syntax cluster: %s"
+msgstr "E391: ÀÌ·± ±¸¹® Ŭ·¯½ºÅÍ´Â ¾ø½À´Ï´Ù: %s"
+
+msgid "No Syntax items defined for this buffer"
+msgstr "ÀÌ ¹öÆÛ¿¡ ´ëÇØ Á¤ÀÇµÈ ±¸¹® Ç׸ñÀÌ ¾ø½À´Ï´Ù"
+
+msgid "syncing on C-style comments"
+msgstr "C-Çü½Ä ÁÖ¼®¹®¿¡ µ¿±â¸ÂÃã"
+
+msgid "no syncing"
+msgstr "µ¿±â¸ÂÃã ¾øÀ½"
+
+msgid "syncing starts "
+msgstr "syncing starts "
+
+msgid " lines before top line"
+msgstr " lines before top line"
+
+msgid ""
+"\n"
+"--- Syntax sync items ---"
+msgstr ""
+"\n"
+"--- Syntax sync Ç׸ñµé ---"
+
+msgid ""
+"\n"
+"syncing on items"
+msgstr ""
+"\n"
+"syncing on items"
+
+msgid ""
+"\n"
+"--- Syntax items ---"
+msgstr ""
+"\n"
+"--- Syntax Ç׸ñ ---"
+
+#, c-format
+msgid "E392: No such syntax cluster: %s"
+msgstr "E392: ÀÌ·± ±¸¹® Ŭ·¯½ºÅÍ´Â ¾ø½À´Ï´Ù: %s"
+
+msgid "minimal "
+msgstr "minimal "
+
+msgid "maximal "
+msgstr "maximal "
+
+msgid "; match "
+msgstr "; match "
+
+msgid " line breaks"
+msgstr " line breaks"
+
+msgid "E395: contains argument not accepted here"
+msgstr "E395: contains ÀÎÀÚ´Â ¿©±â¿¡ ¾µ ¼ö ¾ø½À´Ï´Ù"
+
+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¿¡ ´ëÇÑ region Ç׸ñÀ» ãÁö ¸øÇß½À´Ï´Ù"
+
+msgid "E397: Filename required"
+msgstr "E397: ÆÄÀÏÀ̸§ÀÌ ÇÊ¿äÇÕ´Ï´Ù"
+
+#, c-format
+msgid "E789: Missing ']': %s"
+msgstr "E789: ']' ´©¶ô: %s"
+
+#, c-format
+msgid "E398: Missing '=': %s"
+msgstr "E398: '=' ´©¶ô: %s"
+
+#, c-format
+msgid "E399: Not enough arguments: syntax region %s"
+msgstr "E399: ÃæºÐÄ¡ ¾ÊÀº ÀÎÀÚ: ±¸¹® ¿µ¿ª %s"
+
+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: syntax sync: ÁÙ ¿¬¼Ó ÆÐÅÏÀÌ µÎ ¹ø »ç¿ëµÇ¾ú½À´Ï´Ù"
+
+#, 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 "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: groupÀÌ ¼³Á¤°ªÀÌ ÀÖ½À´Ï´Ù, 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 "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 kind tag"
+
+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\"ÀÌ(°¡) Á¸ÀçÇÏÁö ¾Ê½À´Ï´Ù"
+
+#. Give an indication of the number of matching tags
+#, c-format
+msgid "tag %d of %d%s"
+msgstr "tag %d of %d%s"
+
+msgid " or more"
+msgstr " or more"
+
+msgid " Using tag with different case!"
+msgstr " Using tag with different case!"
+
+#, c-format
+msgid "E429: File \"%s\" does not exist"
+msgstr "E429: ÆÄÀÏ \"%s\"ÀÌ(°¡) Á¸ÀçÇÏÁö ¾Ê½À´Ï´Ù"
+
+#. Highlight title
+msgid ""
+"\n"
+" # TO tag FROM line in file/text"
+msgstr ""
+"\n"
+" # TO tag FROM line in file/text"
+
+#, c-format
+msgid "Searching tags file %s"
+msgstr "ÅÂ±× ÆÄÀÏ %s ã´Â Áß"
+
+#, c-format
+msgid "E430: Tag file path truncated for %s\n"
+msgstr "E430: %s¿¡ ´ëÇÑ ÅÂ±× ÆÄÀÏ °æ·Î°¡ À߷ȽÀ´Ï´Ù\n"
+
+#, c-format
+msgid "E431: Format error in tags file \"%s\""
+msgstr "E431: ÅÂ±× ÆÄÀÏ \"%s\"¿¡ Çü½Ä ¿¡·¯°¡ ÀÖ½À´Ï´Ù"
+
+#, c-format
+msgid "Before byte %ld"
+msgstr "Before byte %ld"
+
+#, c-format
+msgid "E432: Tags file not sorted: %s"
+msgstr "E432: ÅÂ±× ÆÄÀÏÀÌ Á¤·ÄµÇ¾î ÀÖÁö ¾ÊÀ½: %s"
+
+#. never opened any tags file
+msgid "E433: No tags file"
+msgstr "E433: ÅÂ±× ÆÄÀÏÀÌ ¾ø½À´Ï´Ù"
+
+msgid "Ignoring long line in tags file"
+msgstr "ÅÂ±× ÆÄÀÏÀÇ ³Ê¹« ±ä ¶óÀÎÀ» ¹«½ÃÇÕ´Ï´Ù"
+
+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 "' not known. Available builtin terminals are:"
+
+msgid "defaulting to '"
+msgstr "defaulting to '"
+
+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: termcap¿¡ \"%s\" Ç׸ñÀÌ ¾ø½À´Ï´Ù"
+
+msgid "E437: terminal capability \"cm\" required"
+msgstr "E437: Å͹̳ÎÀÌ \"cm\" ±â´ÉÀ» Áö¿øÇØ¾ß ÇÕ´Ï´Ù"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Terminal keys ---"
+msgstr ""
+"\n"
+"--- Å͹̳ΠŰ ---"
+
+msgid "new shell started\n"
+msgstr "»õ ½©ÀÌ ½ÃÀ۵Ǿú½À´Ï´Ù\n"
+
+msgid "Vim: Error reading input, exiting...\n"
+msgstr "ºö: ÀÔ·Â Àд Áß ¿¡·¯, ³¡³»´ÂÁß...\n"
+
+msgid "Used CUT_BUFFER0 instead of empty selection"
+msgstr "ºó °í¸£±â ´ë½Å CUT_BUFFER0À» »ç¿ëÇß½À´Ï´Ù"
+
+#. This happens when the FileChangedRO autocommand changes the
+#. * file in a way it becomes shorter.
+msgid "E834: Line count changed unexpectedly"
+msgstr "E834: ÁÙ °¹¼ö°¡ ¸ð¸£´Â »çÀÌ¿¡ ¹Ù²î¾ú½À´Ï´Ù"
+
+#. must display the prompt
+msgid "No undo possible; continue anyway"
+msgstr "Ãë¼Ò ºÒ°¡´É; ¾î·µç °è¼ÓÇÕ´Ï´Ù"
+
+#, c-format
+msgid "E828: Cannot open undo file for writing: %s"
+msgstr "E828: ¾²±â À§ÇØ undoÀ» ¿­ ¼ö ¾ø½À´Ï´Ù: %s"
+
+#, c-format
+msgid "E825: Corrupted undo file (%s): %s"
+msgstr "E825: ±úÁø undo ÆÄÀÏ (%s): %s"
+
+msgid "Cannot write undo file in any directory in 'undodir'"
+msgstr "'undodir'¿¡ ÀÖ´Â ¾î¶² µð·ºÅ丮¿¡µµ undo ÆÄÀÏÀ» ¾µ ¼ö ¾ø½À´Ï´Ù"
+
+#, c-format
+msgid "Will not overwrite with undo file, cannot read: %s"
+msgstr "ÀÐÀ» ¼ö°¡ ¾ø¾î¼­ undo ÆÄÀÏ¿¡ µ¤¾î¾µ ¼ö ¾ø½À´Ï´Ù: %s"
+
+#, c-format
+msgid "Will not overwrite, this is not an undo file: %s"
+msgstr "undo ÆÄÀÏÀÌ ¾Æ´Ï¾î¼­ µ¤¾î¾µ ¼ö ¾ø½À´Ï´Ù: %s"
+
+msgid "Skipping undo file write, nothing to undo"
+msgstr "undoÇÒ ³»¿ëÀÌ ¾ø¾î¼­ undo ÆÄÀÏ ÀúÀåÀ» °Ç³Ê¶Ý´Ï´Ù"
+
+#, c-format
+msgid "Writing undo file: %s"
+msgstr "undo ÆÄÀÏ ¾²´Â Áß: %s"
+
+#, c-format
+msgid "E829: write error in undo file: %s"
+msgstr "E829: undo ÆÄÀÏ ¾²±â ¿¡·¯: %s"
+
+#, c-format
+msgid "Not reading undo file, owner differs: %s"
+msgstr "¼ÒÀ¯ÀÚ°¡ ´Þ¶ó¼­ undo ÆÄÀÏÀ» ÀÐÁö ¾Ê½À´Ï´Ù: %s"
+
+#, c-format
+msgid "Reading undo file: %s"
+msgstr "undo ÆÄÀÏ Àд Áß: %s"
+
+#, c-format
+msgid "E822: Cannot open undo file for reading: %s"
+msgstr "E822: Àбâ À§ÇØ undo ÆÄÀÏÀ» ¿­ ¼ö ¾ø½À´Ï´Ù: %s"
+
+#, c-format
+msgid "E823: Not an undo file: %s"
+msgstr "E823: undo ÆÄÀÏÀÌ ¾Æ´Õ´Ï´Ù: %s"
+
+#, c-format
+msgid "E832: Non-encrypted file has encrypted undo file: %s"
+msgstr "E832: ¾ÏȣȭµÇÁö ¾ÊÀº ÆÄÀÏÀÌ ¾ÏȣȭµÈ undo ÆÄÀÏÀ» °¡Áö°í ÀÖ½À´Ï´Ù: %s"
+
+#, c-format
+msgid "E826: Undo file decryption failed: %s"
+msgstr "E826: Undo ÆÄÀÏÀ» ÇØµ¶ÇÒ ¼ö ¾ø½À´Ï´Ù: %s"
+
+#, c-format
+msgid "E827: Undo file is encrypted: %s"
+msgstr "E827: Undo ÆÄÀÏÀÌ ¾ÏȣȭµÇ¾ú½À´Ï´Ù: %s"
+
+#, c-format
+msgid "E824: Incompatible undo file: %s"
+msgstr "E824: ȣȯµÇÁö ¾Ê´Â undo ÆÄÀÏ: %s"
+
+msgid "File contents changed, cannot use undo info"
+msgstr "ÆÄÀÏ ³»¿ëÀÌ ¹Ù²î¾î¼­, undo Á¤º¸¸¦ »ç¿ëÇÒ ¼ö ¾ø½À´Ï´Ù"
+
+#, c-format
+msgid "Finished reading undo file %s"
+msgstr "undo ÆÄÀÏ %sÀ»(¸¦) Àоîµé¿´½À´Ï´Ù"
+
+msgid "Already at oldest change"
+msgstr "´õ ÀÌ»óÀÇ ¼öÁ¤ÀÌ ¾ø¾ú½À´Ï´Ù"
+
+msgid "Already at newest change"
+msgstr "´õ ÀÌ»óÀÇ ¼öÁ¤Àº ¾ø¾ú½À´Ï´Ù"
+
+#, c-format
+msgid "E830: Undo number %ld not found"
+msgstr "E830: Undo ¹øÈ£ %ld¸¦ ãÀ» ¼ö ¾ø½À´Ï´Ù"
+
+msgid "E438: u_undo: line numbers wrong"
+msgstr "E438: u_undo: À߸øµÈ ÁÙ ¹øÈ£"
+
+msgid "more line"
+msgstr "more line"
+
+msgid "more lines"
+msgstr "more lines"
+
+msgid "line less"
+msgstr "line less"
+
+msgid "fewer lines"
+msgstr "fewer lines"
+
+msgid "change"
+msgstr "change"
+
+msgid "changes"
+msgstr "changes"
+
+#, c-format
+msgid "%ld %s; %s #%ld %s"
+msgstr "%ld %s; %s #%ld %s"
+
+msgid "before"
+msgstr "before"
+
+msgid "after"
+msgstr "after"
+
+msgid "Nothing to undo"
+msgstr "Ãë¼ÒÇÒ °Ô ¾ø½À´Ï´Ù"
+
+#~ msgid "number changes when saved"
+#~ msgstr ""
+
+#, c-format
+msgid "%ld seconds ago"
+msgstr "%ld seconds ago"
+
+msgid "E790: undojoin is not allowed after undo"
+msgstr "E790: undo µÚ¿¡ undojoinÀº ÇÒ ¼ö ¾ø½À´Ï´Ù"
+
+msgid "E439: undo list corrupt"
+msgstr "E439: undo ¸ñ·ÏÀÌ ±úÁ³½À´Ï´Ù"
+
+msgid "E440: undo line missing"
+msgstr "E440: undo ÁÙÀÌ ¾ø½À´Ï´Ù"
+
+#. Only MS VC 4.1 and earlier can do Win32s
+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"
+"Included patches: "
+msgstr ""
+"\n"
+"Æ÷ÇÔµÈ ÆÐÄ¡: "
+
+msgid ""
+"\n"
+"Extra patches: "
+msgstr ""
+"\n"
+"º°µµÀÇ ÆÐÄ¡: "
+
+msgid "Modified by "
+msgstr "Modified by "
+
+msgid ""
+"\n"
+"Compiled "
+msgstr ""
+"\n"
+"Compiled "
+
+msgid "by "
+msgstr "by "
+
+msgid ""
+"\n"
+"Huge version "
+msgstr ""
+"\n"
+"Huge ¹öÁ¯ "
+
+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 "without GUI."
+msgstr "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 "with (classic) GUI."
+msgstr "(Ŭ·¡½Ä) GUI."
+
+msgid " Features included (+) or not (-):\n"
+msgstr " ±â´É (+: Æ÷ÇÔµÊ, -: Æ÷ÇÔ ¾È µÊ):\n"
+
+msgid " system vimrc file: \""
+msgstr " ½Ã½ºÅÛ vimrc ÆÄÀÏ: \""
+
+msgid " user vimrc file: \""
+msgstr " »ç¿ëÀÚ vimrc ÆÄÀÏ: \""
+
+msgid " 2nd user vimrc file: \""
+msgstr " »ç¿ëÀÚ µÎ ¹øÂ° vimrc ÆÄÀÏ: \""
+
+msgid " 3rd user vimrc file: \""
+msgstr " »ç¿ëÀÚ ¼¼ ¹øÂ° vimrc ÆÄÀÏ: \""
+
+msgid " user exrc file: \""
+msgstr " »ç¿ëÀÚ exrc ÆÄÀÏ: \""
+
+msgid " 2nd user exrc file: \""
+msgstr " »ç¿ëÀÚ µÎ ¹øÂ° exrc ÆÄÀÏ: \""
+
+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 " fall-back for $VIM: \""
+msgstr " fall-back for $VIM: \""
+
+msgid " f-b for $VIMRUNTIME: \""
+msgstr " f-b for $VIMRUNTIME: \""
+
+msgid "Compilation: "
+msgstr "ÄÄÆÄÀÏ: "
+
+msgid "Compiler: "
+msgstr "ÄÄÆÄÀÏ·¯: "
+
+msgid "Linking: "
+msgstr "¸µÅ©: "
+
+msgid " DEBUG BUILD"
+msgstr " µð¹ö±× ºôµå"
+
+msgid "VIM - Vi IMproved"
+msgstr "ºö - Çâ»óµÈ Vi"
+
+msgid "version "
+msgstr "ÆÇ "
+
+msgid "by Bram Moolenaar et al."
+msgstr "by Bram Moolenaar et al."
+
+msgid "Vim is open source and freely distributable"
+msgstr "ºöÀº ¼Ò½º°¡ ¿­·Á ÀÖ°í °øÂ¥·Î ¹èÆ÷µË´Ï´Ù"
+
+msgid "Help poor children in Uganda!"
+msgstr "¿ì°£´Ù¿¡ »ç´Â °¡³­ÇÑ ¾ÆÀ̸¦ µµ¿ÍÁÖ¼¼¿ä!"
+
+msgid "type :help iccf<Enter> for information "
+msgstr "ÀÌ¿¡ ´ëÇÑ Á¤º¸¸¦ º¸·Á¸é :help iccf<¿£ÅÍ> ÀÔ·Â"
+
+msgid "type :q<Enter> to exit "
+msgstr "³¡³»·Á¸é :q<¿£ÅÍ> ÀÔ·Â"
+
+msgid "type :help<Enter> or <F1> for on-line help"
+msgstr "¿Â¶óÀÎ µµ¿ò¸»À» º¸·Á¸é :help<¿£ÅÍ> ¶Ç´Â <F1> ÀÔ·Â"
+
+msgid "type :help version7<Enter> for version info"
+msgstr "ÆÇ Á¤º¸¸¦ º¸·Á¸é :help version7<¿£ÅÍ> ÀÔ·Â"
+
+msgid "Running in Vi compatible mode"
+msgstr "Vi ȣȯ »óÅ·Π½ÇÇàÁßÀÔ´Ï´Ù"
+
+msgid "type :set nocp<Enter> for Vim defaults"
+msgstr "ºö ±âº»°ªÀ» »ç¿ëÇÏ·Á¸é :set nocp<¿£ÅÍ> ÀÔ·Â"
+
+msgid "type :help cp-default<Enter> for info on this"
+msgstr "ÀÌ¿¡ ´ëÇÑ Á¤º¸¸¦ º¸·Á¸é :help cp-default<¿£ÅÍ> ÀÔ·Â"
+
+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 "ºö °³¹ßÀ» ÈÄ¿øÇØ ÁÖ¼¼¿ä!"
+
+msgid "Become a registered Vim user!"
+msgstr "ºö »ç¿ëÀÚ·Î µî·ÏÇϼ¼¿ä!"
+
+msgid "type :help sponsor<Enter> for information "
+msgstr "ÀÌ¿¡ ´ëÇÑ Á¤º¸¸¦ º¸·Á¸é :help sponsor<¿£ÅÍ> ÀÔ·Â"
+
+msgid "type :help register<Enter> for information "
+msgstr "ÀÌ¿¡ ´ëÇÑ Á¤º¸¸¦ º¸·Á¸é :help register<¿£ÅÍ> ÀÔ·Â"
+
+msgid "menu Help->Sponsor/Register for information "
+msgstr "ÀÌ¿¡ ´ëÇÑ Á¤º¸¸¦ º¸·Á¸é ¸Þ´º µµ¿ò¸»->Sponsor/Register"
+
+msgid "WARNING: Windows 95/98/ME detected"
+msgstr "°æ°í: À©µµ¿ìÁî 95/98/ME¸¦ ã¾ÒÀ½"
+
+msgid "type :help windows95<Enter> for info on this"
+msgstr "ÀÌ¿¡ ´ëÇÑ Á¤º¸¸¦ º¸·Á¸é :help windows95<¿£ÅÍ> ÀÔ·Â"
+
+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: À§ ¿ÞÂʰú ¾Æ·¡ ¿À¸¥ÂÊÀ» µ¿½Ã¿¡ ³ª´­ ¼ö ¾ø½À´Ï´Ù"
+
+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: path¿¡¼­ \"%s\" ÆÄÀÏÀ» ãÀ» ¼ö ¾ø½À´Ï´Ù"
+
+#, 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 ¸ðµâ¾øÀÌ´Â 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)"
+
+#. Now concatenate
+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 "--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.
+#.
+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: :while¾øÀÌ :endwhileÀÌ ÀÖ½À´Ï´Ù"
+
+msgid "E588: :endfor without :for"
+msgstr "E588: :for ¾ø´Â :endfor"
+
+msgid "E13: File exists (add ! to override)"
+msgstr "E13: ÆÄÀÏÀÌ ÀÖ½À´Ï´Ù (µ¤¾î¾²·Á¸é ! »ç¿ë)"
+
+msgid "E472: Command failed"
+msgstr "E472: ¸í·ÉÀÌ ½ÇÆÐÇß½À´Ï´Ù"
+
+#, c-format
+msgid "E234: Unknown fontset: %s"
+msgstr "E234: ¸ð¸£´Â ±Û²Ã¼Â: %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: ³»ºÎ ¿¡·¯"
+
+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 "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()\" ºÎ¸£±â ½ÇÆÐ"
+
+#, 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: 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"
+
+#, 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 "E37: No write since last change (add ! to override)"
+msgstr "E37: ¸¶Áö¸·À¸·Î °íÄ£ µÚ ÀúÀåµÇÁö ¾Ê¾Ò½À´Ï´Ù (¹«½ÃÇÏ·Á¸é ! ´õÇϱâ)"
+
+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: ±úÁø Á¤±ÔÇ¥Çö½Ä ÇÁ·Î±×·¥"
+
+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 "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: sign ÀڷḦ ÀÐÀ» ¼ö ¾ø½À´Ï´Ù"
+
+msgid "E72: Close error on swap file"
+msgstr "E72: ½º¿Ò ÆÄÀÏÀ» ´ÝÀ» ¼ö ¾ø½À´Ï´Ù"
+
+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 "Zero count"
+msgstr "Zero count"
+
+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´Â Àбâ Àü¿ë ÆÄÀÏÀ» ¹Ù²Ü ¼ö ¾ø½À´Ï´Ù"
+
+#, c-format
+msgid "E685: Internal error: %s"
+msgstr "E685: ³»ºÎ ¿¡·¯: %s"
+
+msgid "E363: pattern uses more memory than 'maxmempattern'"
+msgstr "E363: ÆÐÅÏÀÌ 'maxmempattern'º¸´Ù ¸¹Àº ¸Þ¸ð¸®¸¦ »ç¿ëÇÕ´Ï´Ù"
+
+msgid "E749: empty buffer"
+msgstr "E749: ºó ¹öÆÛ"
+
+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 "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 "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 "ÆÛ¼­ À§Ä¡°¡ ¹öÆÛ ¹Û¿¡ ÀÖ½À´Ï´Ù"
+
+#, c-format
+msgid "<window object (deleted) at %p>"
+msgstr "<%p¿¡ â °´Ã¼ (»èÁ¦µÊ)>"
+
+#, c-format
+msgid "<window object (unknown) at %p>"
+msgstr "<%p¿¡ â °´Ã¼ (¸ð¸§)>"
+
+#, c-format
+msgid "<window %d>"
+msgstr "<â %d>"
+
+msgid "no such window"
+msgstr "±×·± âÀº ¾ø½À´Ï´Ù"
+
+msgid "attempt to refer to deleted buffer"
+msgstr "Áö¿öÁø ¹öÆÛ¸¦ ÂüÁ¶ÇÏ·Á°í ÇÏ¿´½À´Ï´Ù"
diff --git a/src/po/nb.po b/src/po/nb.po
new file mode 100644
index 0000000000..f6d4761cb5
--- /dev/null
+++ b/src/po/nb.po
@@ -0,0 +1,6166 @@
+# Norwegian (Bokmål) translation of Vim.
+# Copyright (C) 2003-2007 Free Software Foundation, Inc.
+# FIRST AUTHOR Øyvind A. Holm <sunny@sunbase.org>, 2003-2007.
+# Id: no.po 435 2007-03-21 10:52:22Z sunny256
+#
+# Comments and error reports appreciated.
+#
+# Information about the "Vim in Norwegian" project:
+#
+# http://www.sunbase.org/src/vim/norwegian/
+#
+# New versions of the translation files can be downloaded in .tar.gz
+# format from
+#
+# http://svn.sunbase.org/repos/norwegian_vim/download/
+#
+# The files are stored in the Subversion version control system and
+# users of this software can check out the latest version with
+#
+# svn checkout http://svn.sunbase.org/repos/norwegian_vim/trunk/msgs norwegian_vim-msgs
+#
+# This will place the message files into the "norwegian_vim-msgs"
+# directory.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Vim 6.x\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2007-03-19 02:09+0100\n"
+"PO-Revision-Date: 2007-03-21 11:51+0100\n"
+"Last-Translator: Øyvind A. Holm <sunny@sunbase.org>\n"
+"Language-Team: Norwegian <vim.in.norwegian@sunbase.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=ISO-8859-1\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+msgid "E82: Cannot allocate any buffer, exiting..."
+msgstr "E82: Kan ikke reservere plass til noen buffere, avslutter ..."
+
+msgid "E83: Cannot allocate buffer, using other one..."
+msgstr "E83: Kan ikke reservere plass til buffer, bruker en annen ..."
+
+msgid "E515: No buffers were unloaded"
+msgstr "E515: Ingen buffere ble lastet ut"
+
+msgid "E516: No buffers were deleted"
+msgstr "E516: Ingen buffere ble slettet"
+
+msgid "E517: No buffers were wiped out"
+msgstr "E517: Ingen buffere ble visket ut"
+
+msgid "1 buffer unloaded"
+msgstr "1 buffer ble lastet ut"
+
+#, c-format
+msgid "%d buffers unloaded"
+msgstr "%d buffere ble lastet ut"
+
+msgid "1 buffer deleted"
+msgstr "1 buffer ble slettet"
+
+#, c-format
+msgid "%d buffers deleted"
+msgstr "%d buffere ble slettet"
+
+msgid "1 buffer wiped out"
+msgstr "1 buffer ble visket ut"
+
+#, c-format
+msgid "%d buffers wiped out"
+msgstr "%d buffere ble visket ut"
+
+msgid "E84: No modified buffer found"
+msgstr "E84: Fant ingen modifisert buffer"
+
+#. back where we started, didn't find anything.
+msgid "E85: There is no listed buffer"
+msgstr "E85: Det finnes ingen listede buffere"
+
+#, c-format
+msgid "E86: Buffer %ld does not exist"
+msgstr "E86: Bufferen %ld finnes ikke"
+
+msgid "E87: Cannot go beyond last buffer"
+msgstr "E87: Kan ikke gå forbi siste buffer"
+
+msgid "E88: Cannot go before first buffer"
+msgstr "E88: Kan ikke gå forbi første buffer"
+
+#, c-format
+msgid "E89: No write since last change for buffer %ld (add ! to override)"
+msgstr ""
+"E89: Ikke lagret siden forrige forandring av bufferen %ld (legg til ! for å "
+"overstyre)"
+
+msgid "E90: Cannot unload last buffer"
+msgstr "E90: Kan ikke laste ut siste buffer"
+
+msgid "W14: Warning: List of file names overflow"
+msgstr "W14: Advarsel: Listen med filnavn er overfylt"
+
+#, c-format
+msgid "E92: Buffer %ld not found"
+msgstr "E92: Fant ikke bufferen %ld"
+
+#, c-format
+msgid "E93: More than one match for %s"
+msgstr "E93: Mer enn ett treff for %s"
+
+#, c-format
+msgid "E94: No matching buffer for %s"
+msgstr "E94: Ingen samsvarende buffer for %s"
+
+#, c-format
+msgid "line %ld"
+msgstr "linje %ld"
+
+msgid "E95: Buffer with this name already exists"
+msgstr "E95: En buffer med dette navnet finnes allerede"
+
+msgid " [Modified]"
+msgstr " [Modifisert]"
+
+msgid "[Not edited]"
+msgstr "[Uredigert]"
+
+msgid "[New file]"
+msgstr "[Ny fil]"
+
+msgid "[Read errors]"
+msgstr "[Lesefeil]"
+
+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 av %ld --%d%%-- kol "
+
+msgid "[No Name]"
+msgstr "[Uten navn]"
+
+#. must be a help buffer
+msgid "help"
+msgstr "hjelp"
+
+msgid "[Help]"
+msgstr "[Hjelp]"
+
+msgid "[Preview]"
+msgstr "[Forhåndsvisning]"
+
+msgid "All"
+msgstr "Alt"
+
+msgid "Bot"
+msgstr "Bunn"
+
+msgid "Top"
+msgstr "Topp"
+
+#, c-format
+msgid ""
+"\n"
+"# Buffer list:\n"
+msgstr ""
+"\n"
+"# Bufferliste:\n"
+
+msgid "[Location List]"
+msgstr "[Plassliste]"
+
+#~ msgid "[Quickfix List]"
+#~ msgstr ""
+
+msgid ""
+"\n"
+"--- Signs ---"
+msgstr ""
+"\n"
+"--- Skilt ---"
+
+#, c-format
+msgid "Signs for %s:"
+msgstr "Skilt for %s:"
+
+#, c-format
+msgid " line=%ld id=%d name=%s"
+msgstr " linje=%ld id=%d navn=%s"
+
+#, c-format
+msgid "E96: Can not diff more than %ld buffers"
+msgstr "E96: Kan ikke sammenligne flere enn %ld buffere"
+
+msgid "E97: Cannot create diffs"
+msgstr "E97: Kan ikke lage differansefiler"
+
+msgid "Patch file"
+msgstr "Patch fil"
+
+msgid "E98: Cannot read diff output"
+msgstr "E98: Kan ikke lese differanse-utdata"
+
+msgid "E99: Current buffer is not in diff mode"
+msgstr "E99: Nåværende buffer er ikke i differansemodus"
+
+msgid "E793: No other buffer in diff mode is modifiable"
+msgstr "E793: Ingen annen buffer i differansemodus er redigerbar"
+
+msgid "E100: No other buffer in diff mode"
+msgstr "E100: Ingen annen buffer i differansemodus"
+
+msgid "E101: More than two buffers in diff mode, don't know which one to use"
+msgstr ""
+"E101: Mer enn to buffere i differansemodus, vet ikke hvilken som skal brukes"
+
+#, c-format
+msgid "E102: Can't find buffer \"%s\""
+msgstr "E102: Kan ikke finne buffer \"%s\""
+
+#, c-format
+msgid "E103: Buffer \"%s\" is not in diff mode"
+msgstr "E103: Bufferen \"%s\" er ikke i differansemodus"
+
+msgid "E787: Buffer changed unexpectedly"
+msgstr "E787: Uventet forandring i buffer"
+
+msgid "E104: Escape not allowed in digraph"
+msgstr "E104: Escape er ikke lovlig i spesialtegn"
+
+msgid "E544: Keymap file not found"
+msgstr "E544: Fant ikke keymap-fil"
+
+msgid "E105: Using :loadkeymap not in a sourced file"
+msgstr "E105: Bruk av :loadkeymap utenfor en kjørt fil"
+
+msgid "E791: Empty keymap entry"
+msgstr "E791: Tom tastaturoppsett-oppføring"
+
+msgid " Keyword completion (^N^P)"
+msgstr " Nøkkelordfullføring (^N^P)"
+
+#. ctrl_x_mode == 0, ^P/^N compl.
+#, fuzzy
+#~ msgid " ^X mode (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)"
+#~ msgstr " ^X-modus (^]^D^E^F^I^K^L^N^O^P^S^U^V^Y)"
+
+msgid " Whole line completion (^L^N^P)"
+msgstr " Fullføring av hel linje (^L^N^P)"
+
+msgid " File name completion (^F^N^P)"
+msgstr " Fullføring av filnavn (^F^N^P)"
+
+msgid " Tag completion (^]^N^P)"
+msgstr " Fullføring av tag (^]^N^P)"
+
+msgid " Path pattern completion (^N^P)"
+msgstr " Stimønster-fullføring (^N^P)"
+
+msgid " Definition completion (^D^N^P)"
+msgstr " Fullføring av defineringer (^D^N^P)"
+
+msgid " Dictionary completion (^K^N^P)"
+msgstr " Fullføring fra ordliste (^K^N^P)"
+
+msgid " Thesaurus completion (^T^N^P)"
+msgstr " Thesaurus-fullføring (^T^N^P)"
+
+msgid " Command-line completion (^V^N^P)"
+msgstr " Kommandolinje-fullføring (^V^N^P)"
+
+msgid " User defined completion (^U^N^P)"
+msgstr " Brukerdefinert fullføring (^U^N^P)"
+
+msgid " Omni completion (^O^N^P)"
+msgstr " Omni-fullføring (^O^N^P)"
+
+#, fuzzy
+#~ msgid " Spelling suggestion (s^N^P)"
+#~ msgstr " Staveforslag (^S^N^P)"
+
+msgid " Keyword Local completion (^N^P)"
+msgstr " Lokal nøkkelordfullføring (^N^P)"
+
+msgid "Hit end of paragraph"
+msgstr "Kom til slutten av avsnittet"
+
+msgid "'dictionary' option is empty"
+msgstr "'dictionary'-valget er tomt"
+
+msgid "'thesaurus' option is empty"
+msgstr "'thesaurus'-valget er tomt"
+
+#, c-format
+msgid "Scanning dictionary: %s"
+msgstr "Leter gjennom ordliste: %s"
+
+msgid " (insert) Scroll (^E/^Y)"
+msgstr " (sett inn) Rulling (^E/^Y)"
+
+msgid " (replace) Scroll (^E/^Y)"
+msgstr " (erstatt) Rulling (^E/^Y)"
+
+#, c-format
+msgid "Scanning: %s"
+msgstr "Leter: %s"
+
+#, c-format
+msgid "Scanning tags."
+msgstr "Leter gjennom tagger."
+
+msgid " Adding"
+msgstr " Legger til"
+
+#. 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.
+#.
+msgid "-- Searching..."
+msgstr "-- Søker ..."
+
+msgid "Back at original"
+msgstr "Tilbake i originalen"
+
+msgid "Word from other line"
+msgstr "Ord fra annen linje"
+
+msgid "The only match"
+msgstr "Det eneste treffet"
+
+#, c-format
+msgid "match %d of %d"
+msgstr "treff %d av %d"
+
+#, c-format
+msgid "match %d"
+msgstr "treff %d"
+
+msgid "E18: Unexpected characters in :let"
+msgstr "E18: Uventede tegn i :let"
+
+#, c-format
+msgid "E684: list index out of range: %ld"
+msgstr "E684: Listeindeks utenfor område: %ld"
+
+#, c-format
+msgid "E121: Undefined variable: %s"
+msgstr "E121: Udefinert variabel: %s"
+
+msgid "E111: Missing ']'"
+msgstr "E111: Mangler ']'"
+
+#, c-format
+msgid "E686: Argument of %s must be a List"
+msgstr "E686: Parameter til %s må være en liste"
+
+#, c-format
+msgid "E712: Argument of %s must be a List or Dictionary"
+msgstr "E712: Parameter til %s må være en liste eller ordliste"
+
+msgid "E713: Cannot use empty key for Dictionary"
+msgstr "E713: Kan ikke bruke tom nøkkel med ordliste"
+
+msgid "E714: List required"
+msgstr "E714: Liste påkrevet"
+
+msgid "E715: Dictionary required"
+msgstr "E715: Ordliste påkrevet"
+
+#, c-format
+msgid "E118: Too many arguments for function: %s"
+msgstr "E118: For mange parametere til funksjonen: %s"
+
+#, c-format
+msgid "E716: Key not present in Dictionary: %s"
+msgstr "E716: Nøkkelen finnes ikke i ordliste: %s"
+
+#, c-format
+msgid "E122: Function %s already exists, add ! to replace it"
+msgstr "E122: Funksjonen %s eksisterer allerede, legg til ! for å erstatte den"
+
+msgid "E717: Dictionary entry already exists"
+msgstr "E717: Ordlisteoppføring finnes allerede"
+
+msgid "E718: Funcref required"
+msgstr "E718: Funksjonsreferanse nødvendig"
+
+msgid "E719: Cannot use [:] with a Dictionary"
+msgstr "E719: Kan ikke bruke [:] sammen med en ordliste"
+
+#, c-format
+msgid "E734: Wrong variable type for %s="
+msgstr "E734: Feil variabeltype for %s="
+
+#, c-format
+msgid "E130: Unknown function: %s"
+msgstr "E130: Ukjent funksjon: %s"
+
+#, c-format
+msgid "E461: Illegal variable name: %s"
+msgstr "E461: Ugyldig variabelnavn: %s"
+
+msgid "E687: Less targets than List items"
+msgstr "E687: Færre mål enn listeelementer"
+
+msgid "E688: More targets than List items"
+msgstr "E688: Flere mål enn listeelementer"
+
+msgid "Double ; in list of variables"
+msgstr "Dobbel ; i variabelliste"
+
+#, c-format
+msgid "E738: Can't list variables for %s"
+msgstr "E738: Kan ikke liste variabler for %s"
+
+msgid "E689: Can only index a List or Dictionary"
+msgstr "E689: Kan bare indeksere en liste eller ordliste"
+
+msgid "E708: [:] must come last"
+msgstr "E708: [:] må komme sist"
+
+msgid "E709: [:] requires a List value"
+msgstr "E709: [:] krever en listeverdi"
+
+msgid "E710: List value has more items than target"
+msgstr "E710: Listeverdien har flere elementer enn mål"
+
+msgid "E711: List value has not enough items"
+msgstr "E711: Listeverdien har ikke nok elementer"
+
+msgid "E690: Missing \"in\" after :for"
+msgstr "E690: Mangler \"in\" etter :for"
+
+#, c-format
+msgid "E107: Missing parentheses: %s"
+msgstr "E107: Mangler parenteser: %s"
+
+#, c-format
+msgid "E108: No such variable: \"%s\""
+msgstr "E108: Variabelen finnes ikke: \"%s\""
+
+msgid "E743: variable nested too deep for (un)lock"
+msgstr "E743: Variabel nøstet for dypt for (un)lock"
+
+msgid "E109: Missing ':' after '?'"
+msgstr "E109: Mangler ':' etter '?'"
+
+msgid "E691: Can only compare List with List"
+msgstr "E691: Kan bare sammenligne liste med liste"
+
+msgid "E692: Invalid operation for Lists"
+msgstr "E692: Ugyldig operasjon for lister"
+
+msgid "E735: Can only compare Dictionary with Dictionary"
+msgstr "E735: Kan bare sammenligne ordliste med ordliste"
+
+msgid "E736: Invalid operation for Dictionary"
+msgstr "E736: Ugyldig operasjon for ordliste"
+
+msgid "E693: Can only compare Funcref with Funcref"
+msgstr "E693: Kan bare sammenligne funksjonsreferanse med funksjonsreferanse"
+
+msgid "E694: Invalid operation for Funcrefs"
+msgstr "E694: Ugyldig operasjon for funksjonsreferanser"
+
+msgid "E110: Missing ')'"
+msgstr "E110: Mangler ')'"
+
+msgid "E695: Cannot index a Funcref"
+msgstr "E695: Kan ikke indeksere en funksjonsreferanse"
+
+#, c-format
+msgid "E112: Option name missing: %s"
+msgstr "E112: Navn på valg mangler: %s"
+
+#, c-format
+msgid "E113: Unknown option: %s"
+msgstr "E113: Ukjent valg: %s"
+
+#, c-format
+msgid "E114: Missing quote: %s"
+msgstr "E114: Mangler anførselstegn (\"): %s"
+
+#, c-format
+msgid "E115: Missing quote: %s"
+msgstr "E115: Mangler apostrof ('): %s"
+
+#, c-format
+msgid "E696: Missing comma in List: %s"
+msgstr "E696: Mangler komma i liste: %s"
+
+#, c-format
+msgid "E697: Missing end of List ']': %s"
+msgstr "E697: Mangler slutt på liste ']': %s"
+
+#, c-format
+msgid "E720: Missing colon in Dictionary: %s"
+msgstr "E720: Mangler kolon i ordliste: %s"
+
+#, c-format
+msgid "E721: Duplicate key in Dictionary: \"%s\""
+msgstr "E721: Duplisert nøkkel i ordliste: \"%s\""
+
+#, c-format
+msgid "E722: Missing comma in Dictionary: %s"
+msgstr "E722: Mangler komma i ordliste: %s"
+
+#, c-format
+msgid "E723: Missing end of Dictionary '}': %s"
+msgstr "E723: Mangler slutt på ordliste '}': %s"
+
+msgid "E724: variable nested too deep for displaying"
+msgstr "E724: Variabel nøstet for dypt for visning"
+
+#, c-format
+msgid "E117: Unknown function: %s"
+msgstr "E117: Ukjent funksjon: %s"
+
+#, c-format
+msgid "E119: Not enough arguments for function: %s"
+msgstr "E119: Ikke nok parametere til funksjonen: %s"
+
+#, c-format
+msgid "E120: Using <SID> not in a script context: %s"
+msgstr "E120: Bruk av \"<SID>\" utenfor skript-sammenheng: %s"
+
+#, c-format
+msgid "E725: Calling dict function without Dictionary: %s"
+msgstr "E725: Kaller ordlistefunksjon uten ordliste: %s"
+
+msgid "E699: Too many arguments"
+msgstr "E699: For mange parametere"
+
+msgid "E785: complete() can only be used in Insert mode"
+msgstr "E785: complete() kan bare brukes i innsettingsmodus"
+
+#.
+#. * 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"
+
+#, c-format
+msgid "E737: Key already exists: %s"
+msgstr "E737: Nøkkelen finnes allerede: %s"
+
+#, c-format
+msgid "+-%s%3ld lines: "
+msgstr "+-%s%3ld linjer: "
+
+#, c-format
+msgid "E700: Unknown function: %s"
+msgstr "E700: Ukjent funksjon: %s"
+
+msgid ""
+"&OK\n"
+"&Cancel"
+msgstr ""
+"&OK\n"
+"&Avbryt"
+
+msgid "called inputrestore() more often than inputsave()"
+msgstr "kalte inputrestore() oftere enn inputsave()"
+
+msgid "E786: Range not allowed"
+msgstr "E786: Område ikke tillatt"
+
+msgid "E701: Invalid type for len()"
+msgstr "E701: Ugyldig type for len()"
+
+msgid "E726: Stride is zero"
+msgstr "E726: Økning er null"
+
+msgid "E727: Start past end"
+msgstr "E727: Starten er bak slutten"
+
+msgid "<empty>"
+msgstr "<tom>"
+
+msgid "E240: No connection to Vim server"
+msgstr "E240: Ingen forbindelse med Vim-tjeneren"
+
+#, c-format
+msgid "E241: Unable to send to %s"
+msgstr "E241: Klarer ikke sende til %s"
+
+msgid "E277: Unable to read a server reply"
+msgstr "E277: Klarer ikke lese svar fra tjeneren"
+
+msgid "E655: Too many symbolic links (cycle?)"
+msgstr "E655: For mange symbolske linker (runddans?)"
+
+msgid "E258: Unable to send to client"
+msgstr "E258: Klarer ikke sende til klienten"
+
+msgid "E702: Sort compare function failed"
+msgstr "E702: Funksjon for sorteringssammenligning feilet"
+
+msgid "(Invalid)"
+msgstr "(Ugyldig)"
+
+msgid "E677: Error writing temp file"
+msgstr "E677: Feil under skriving til midlertidig fil"
+
+msgid "E703: Using a Funcref as a Number"
+msgstr "E703: Bruker en funksjonsreferanse som et nummer"
+
+msgid "E745: Using a List as a Number"
+msgstr "E745: Bruker en liste som et nummer"
+
+msgid "E728: Using a Dictionary as a Number"
+msgstr "E728: Bruker en ordliste som et nummer"
+
+msgid "E729: using Funcref as a String"
+msgstr "E729: Bruker en funksjonsreferanse som en streng"
+
+msgid "E730: using List as a String"
+msgstr "E730: Bruker en liste som en streng"
+
+msgid "E731: using Dictionary as a String"
+msgstr "E731: Bruker en ordliste som en streng"
+
+#, c-format
+msgid "E704: Funcref variable name must start with a capital: %s"
+msgstr "E704: Variabelnavn for funksjonsreferanse må ha stor forbokstav: %s"
+
+#, c-format
+msgid "E705: Variable name conflicts with existing function: %s"
+msgstr "E705: Variabelnavn er i konflikt med en eksisterende funksjon: %s"
+
+#, c-format
+msgid "E706: Variable type mismatch for: %s"
+msgstr "E706: Variabeltype samsvarer ikke med: %s"
+
+#, c-format
+msgid "E795: Cannot delete variable %s"
+msgstr "E795: Kan ikke slette variabel %s"
+
+#, c-format
+msgid "E741: Value is locked: %s"
+msgstr "E741: Verdi er låst: %s"
+
+msgid "Unknown"
+msgstr "Ukjent"
+
+#, c-format
+msgid "E742: Cannot change value of %s"
+msgstr "E742: Kan ikke forandre verdi for %s"
+
+msgid "E698: variable nested too deep for making a copy"
+msgstr "E698: Variabel nøstet for dypt til å lage en kopi"
+
+#, c-format
+msgid "E124: Missing '(': %s"
+msgstr "E124: Mangler '(': %s"
+
+#, c-format
+msgid "E125: Illegal argument: %s"
+msgstr "E125: Ugyldig parameter: %s"
+
+msgid "E126: Missing :endfunction"
+msgstr "E126: Mangler :endfunction"
+
+#, c-format
+msgid "E746: Function name does not match script file name: %s"
+msgstr "E746: Funksjonsnavn samsvarer ikke med skriptfilnavn: %s"
+
+msgid "E129: Function name required"
+msgstr "E129: Funksjonsnavn nødvendig"
+
+#, c-format
+msgid "E128: Function name must start with a capital or contain a colon: %s"
+msgstr "E128: Funksjonsnavn må ha stor forbokstav eller inneholde et kolon: %s"
+
+#, c-format
+msgid "E131: Cannot delete function %s: It is in use"
+msgstr "E131: Kan ikke slette funksjonen %s: Den er i bruk"
+
+msgid "E132: Function call depth is higher than 'maxfuncdepth'"
+msgstr "E132: Funksjonskalldybden er større enn 'maxfuncdepth'"
+
+#, c-format
+msgid "calling %s"
+msgstr "kaller %s"
+
+#, c-format
+msgid "%s aborted"
+msgstr "%s avbrutt"
+
+#, c-format
+msgid "%s returning #%ld"
+msgstr "%s returnerer #%ld"
+
+#, c-format
+msgid "%s returning %s"
+msgstr "%s returnerer %s"
+
+#, c-format
+msgid "continuing in %s"
+msgstr "fortsetter i %s"
+
+msgid "E133: :return not inside a function"
+msgstr "E133: :return er ikke innenfor en funksjon"
+
+#, c-format
+msgid ""
+"\n"
+"# global variables:\n"
+msgstr ""
+"\n"
+"# globale variabler:\n"
+
+msgid ""
+"\n"
+"\tLast set from "
+msgstr ""
+"\n"
+"\tSist satt fra "
+
+#, c-format
+msgid "<%s>%s%s %d, Hex %02x, Octal %03o"
+msgstr "<%s>%s%s %d, Hex %02x, Oktal %03o"
+
+#, c-format
+msgid "> %d, Hex %04x, Octal %o"
+msgstr "> %d, Hex %04x, Oktal %o"
+
+#, c-format
+msgid "> %d, Hex %08x, Octal %o"
+msgstr "> %d, Hex %08x, Oktal %o"
+
+msgid "E134: Move lines into themselves"
+msgstr "E134: Flytting av linjer inn i seg 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 filtrert"
+
+msgid "E135: *Filter* Autocommands must not change current buffer"
+msgstr "E135: *Filter* Autokommandoer må ikke forandre nåværende buffer"
+
+msgid "[No write since last change]\n"
+msgstr "[Ikke lagret siden forrige forandring]\n"
+
+#, c-format
+msgid "%sviminfo: %s in line: "
+msgstr "%sviminfo: %s i linje: "
+
+msgid "E136: viminfo: Too many errors, skipping rest of file"
+msgstr "E136: viminfo: For mange feil, hopper over resten av filen"
+
+#, c-format
+msgid "Reading viminfo file \"%s\"%s%s%s"
+msgstr "Leser viminfo-fil \"%s\"%s%s%s"
+
+msgid " info"
+msgstr " info"
+
+msgid " marks"
+msgstr " merker"
+
+msgid " FAILED"
+msgstr " FEILET"
+
+#. avoid a wait_return for this message, it's annoying
+#, c-format
+msgid "E137: Viminfo file is not writable: %s"
+msgstr "E137: Viminfo-fil er ikke skrivbar: %s"
+
+#, c-format
+msgid "E138: Can't write viminfo file %s!"
+msgstr "E138: Kan ikke lagre viminfo-fil %s!"
+
+#, c-format
+msgid "Writing viminfo file \"%s\""
+msgstr "Lagrer viminfo-fil \"%s\""
+
+#. Write the info:
+#, c-format
+msgid "# This viminfo file was generated by Vim %s.\n"
+msgstr "# Denne viminfo-filen ble generert av Vim %s.\n"
+
+#, c-format
+msgid ""
+"# You may edit it if you're careful!\n"
+"\n"
+msgstr ""
+"# Du kan redigere den hvis du er forsiktig!\n"
+"\n"
+
+#, c-format
+msgid "# Value of 'encoding' when this file was written\n"
+msgstr "# Verdien av 'encoding' når denne filen ble skrevet\n"
+
+msgid "Illegal starting char"
+msgstr "Ulovlig starttegn"
+
+msgid "Save As"
+msgstr "Lagre som"
+
+msgid "Write partial file?"
+msgstr "Skrive delvis fil?"
+
+msgid "E140: Use ! to write partial buffer"
+msgstr "E140: Bruk ! for å skrive delvis buffer"
+
+#, c-format
+msgid "Overwrite existing file \"%s\"?"
+msgstr "Overskrive eksisterende fil \"%s\"?"
+
+#, c-format
+msgid "Swap file \"%s\" exists, overwrite anyway?"
+msgstr "Swapfilen \"%s\" finnes, overskriv likevel?"
+
+#, c-format
+msgid "E768: Swap file exists: %s (:silent! overrides)"
+msgstr "E768: Swapfilen finnes: %s (:silent! overstyrer)"
+
+#, c-format
+msgid "E141: No file name for buffer %ld"
+msgstr "E141: Mangler filnavn for buffer %ld"
+
+msgid "E142: File not written: Writing is disabled by 'write' option"
+msgstr "E142: Filen ble ikke lagret: Lagring er deaktivert med 'write'-valget"
+
+#, c-format
+msgid ""
+"'readonly' option is set for \"%s\".\n"
+"Do you wish to write anyway?"
+msgstr ""
+"'readonly'-valget er satt for \"%s\".\n"
+"Vil du lagre likevel?"
+
+msgid "Edit File"
+msgstr "Rediger fil"
+
+#, c-format
+msgid "E143: Autocommands unexpectedly deleted new buffer %s"
+msgstr "E143: Autokommandoer slettet uventet den nye bufferen %s"
+
+msgid "E144: non-numeric argument to :z"
+msgstr "E144: Ikke-numerisk parameter til :z"
+
+msgid "E145: Shell commands not allowed in rvim"
+msgstr "E145: Skallkommandoer er ikke tillatt i rvim"
+
+msgid "E146: Regular expressions can't be delimited by letters"
+msgstr "E146: Regulære uttrykk kan ikke bli adskilt av bokstaver"
+
+#, c-format
+msgid "replace with %s (y/n/a/q/l/^E/^Y)?"
+msgstr "Erstatt med %s (y/n/a/q/l/^E/^Y)?"
+
+msgid "(Interrupted) "
+msgstr "(Avbrutt) "
+
+msgid "1 match"
+msgstr "1 treff"
+
+msgid "1 substitution"
+msgstr "1 erstatning"
+
+#, c-format
+msgid "%ld matches"
+msgstr "%ld treff"
+
+#, c-format
+msgid "%ld substitutions"
+msgstr "%ld erstatninger"
+
+msgid " on 1 line"
+msgstr " i 1 linje"
+
+#, c-format
+msgid " on %ld lines"
+msgstr " i %ld linjer"
+
+msgid "E147: Cannot do :global recursive"
+msgstr "E147: Kan ikke gjøre :global rekursiv"
+
+msgid "E148: Regular expression missing from global"
+msgstr "E148: Regulært uttrykk mangler i global kommando"
+
+#, c-format
+msgid "Pattern found in every line: %s"
+msgstr "Søkestreng funnet i alle linjene: %s"
+
+#, c-format
+msgid ""
+"\n"
+"# Last Substitute String:\n"
+"$"
+msgstr ""
+"\n"
+"# Siste erstatningstekst:\n"
+"$"
+
+msgid "E478: Don't panic!"
+msgstr "E478: Ingen panikk!"
+
+#, c-format
+msgid "E661: Sorry, no '%s' help for %s"
+msgstr "E661: Dessverre ingen '%s' hjelp for %s"
+
+#, c-format
+msgid "E149: Sorry, no help for %s"
+msgstr "E149: Dessverre ingen hjelp for %s"
+
+#, c-format
+msgid "Sorry, help file \"%s\" not found"
+msgstr "Fant ikke hjelpefilen \"%s\""
+
+#, c-format
+msgid "E150: Not a directory: %s"
+msgstr "E150: Er ikke en katalog: %s"
+
+#, c-format
+msgid "E152: Cannot open %s for writing"
+msgstr "E152: Kan ikke åpne %s for skriving"
+
+#, c-format
+msgid "E153: Unable to open %s for reading"
+msgstr "E153: Kan ikke åpne %s for lesing"
+
+#, c-format
+msgid "E670: Mix of help file encodings within a language: %s"
+msgstr "E670: Tegnsettblanding i hjelpefilen innenfor samme språk: %s"
+
+#, c-format
+msgid "E154: Duplicate tag \"%s\" in file %s/%s"
+msgstr "E154: Duplikat-tag \"%s\" i filen %s/%s"
+
+#, c-format
+msgid "E160: Unknown sign command: %s"
+msgstr "E160: Ukjent skiltkommando: %s"
+
+msgid "E156: Missing sign name"
+msgstr "E156: Mangler skiltnavn"
+
+msgid "E612: Too many signs defined"
+msgstr "E612: For mange skilt definert"
+
+#, c-format
+msgid "E239: Invalid sign text: %s"
+msgstr "E239: Ugyldig skilttekst: %s"
+
+#, c-format
+msgid "E155: Unknown sign: %s"
+msgstr "E155: Ukjent skilt: %s"
+
+msgid "E159: Missing sign number"
+msgstr "E159: Mangler skiltnummer"
+
+#, c-format
+msgid "E158: Invalid buffer name: %s"
+msgstr "E158: Ugyldig buffernavn: %s"
+
+#, c-format
+msgid "E157: Invalid sign ID: %ld"
+msgstr "E157: Ulovlig skilt-ID: %ld"
+
+msgid " (NOT FOUND)"
+msgstr " (IKKE FUNNET)"
+
+msgid " (not supported)"
+msgstr " (ikke støttet)"
+
+msgid "[Deleted]"
+msgstr "[Slettet]"
+
+msgid "Entering Debug mode. Type \"cont\" to continue."
+msgstr "Går inn i debuggingsmodus. Skriv \"cont\" for å fortsette."
+
+#, c-format
+msgid "line %ld: %s"
+msgstr "linje %ld: %s"
+
+#, c-format
+msgid "cmd: %s"
+msgstr "kommando: %s"
+
+#, c-format
+msgid "Breakpoint in \"%s%s\" line %ld"
+msgstr "Stoppunkt i \"%s%s\" linje %ld"
+
+#, c-format
+msgid "E161: Breakpoint not found: %s"
+msgstr "E161: Fant ikke stoppunkt: %s"
+
+msgid "No breakpoints defined"
+msgstr "Ingen stoppunkt definert"
+
+#, c-format
+msgid "%3d %s %s line %ld"
+msgstr "%3d %s %s linje %ld"
+
+msgid "E750: First use :profile start <fname>"
+msgstr "E750: Bruk først :profile start <filnavn>"
+
+#, c-format
+msgid "Save changes to \"%s\"?"
+msgstr "Lagre forandringer til \"%s\"?"
+
+msgid "Untitled"
+msgstr "Uten navn"
+
+#, c-format
+msgid "E162: No write since last change for buffer \"%s\""
+msgstr "E162: Ikke lagret siden siste forandringer i bufferen \"%s\""
+
+msgid "Warning: Entered other buffer unexpectedly (check autocommands)"
+msgstr "Advarsel: Gikk uventet inn i en annen buffer (sjekk autokommandoer)"
+
+msgid "E163: There is only one file to edit"
+msgstr "E163: Det er bare en fil å redigere"
+
+msgid "E164: Cannot go before first file"
+msgstr "E164: Kan ikke gå forbi første fil"
+
+msgid "E165: Cannot go beyond last file"
+msgstr "E165: Kan ikke gå forbi siste fil"
+
+#, c-format
+msgid "E666: compiler not supported: %s"
+msgstr "E666: Kompilatoren er ikke støttet: %s"
+
+#, c-format
+msgid "Searching for \"%s\" in \"%s\""
+msgstr "Søker etter \"%s\" i \"%s\""
+
+#, c-format
+msgid "Searching for \"%s\""
+msgstr "Søker etter \"%s\""
+
+#, c-format
+msgid "not found in 'runtimepath': \"%s\""
+msgstr "ikke funnet i 'runtimepath': \"%s\""
+
+msgid "Source Vim script"
+msgstr "Kjør Vim-skript"
+
+#, c-format
+msgid "Cannot source a directory: \"%s\""
+msgstr "Kan ikke kjøre en katalog: \"%s\""
+
+#, c-format
+msgid "could not source \"%s\""
+msgstr "kunne ikke kjøre \"%s\""
+
+#, c-format
+msgid "line %ld: could not source \"%s\""
+msgstr "linje %ld: Kunne ikke kjøre \"%s\""
+
+#, c-format
+msgid "sourcing \"%s\""
+msgstr "kjører \"%s\""
+
+#, c-format
+msgid "line %ld: sourcing \"%s\""
+msgstr "linje %ld: kjører \"%s\""
+
+#, c-format
+msgid "finished sourcing %s"
+msgstr "ferdig med kjøring av %s"
+
+#, fuzzy
+#~ msgid "modeline"
+#~ msgstr "1 linje lagt til"
+
+#, fuzzy
+#~ msgid "--cmd argument"
+#~ msgstr " vim [parametere] "
+
+#, fuzzy
+#~ msgid "-c argument"
+#~ msgstr " vim [parametere] "
+
+msgid "environment variable"
+msgstr "miljøvariabel"
+
+msgid "error handler"
+msgstr "feilbehandler"
+
+msgid "W15: Warning: Wrong line separator, ^M may be missing"
+msgstr "W15: Advarsel: Feil linjeseparator, det er mulig ^M mangler"
+
+msgid "E167: :scriptencoding used outside of a sourced file"
+msgstr "E167: :scriptencoding brukt utenfor en kjørt fil"
+
+msgid "E168: :finish used outside of a sourced file"
+msgstr "E168: :finish brukt utenfor en kjørt fil"
+
+#, c-format
+msgid "Current %slanguage: \"%s\""
+msgstr "Nåværende %sspråk: \"%s\""
+
+#, c-format
+msgid "E197: Cannot set language to \"%s\""
+msgstr "E197: Kan ikke sette språk til \"%s\""
+
+msgid "Entering Ex mode. Type \"visual\" to go to Normal mode."
+msgstr "Går inn i Ex-modus. Skriv \"visual\" for å gå til normalmodus."
+
+msgid "E501: At end-of-file"
+msgstr "E501: Ved slutten av filen"
+
+msgid "E169: Command too recursive"
+msgstr "E169: Kommando altfor rekursiv"
+
+#, c-format
+msgid "E605: Exception not caught: %s"
+msgstr "E605: Unntak ikke fanget opp: %s"
+
+msgid "End of sourced file"
+msgstr "Slutt på kjørt fil"
+
+msgid "End of function"
+msgstr "Slutt på funksjon"
+
+msgid "E464: Ambiguous use of user-defined command"
+msgstr "E464: Flertydig bruk av brukerdefinert kommando"
+
+msgid "E492: Not an editor command"
+msgstr "E492: Er ikke en editorkommando"
+
+msgid "E493: Backwards range given"
+msgstr "E493: Område bakover er angitt"
+
+msgid "Backwards range given, OK to swap"
+msgstr "Område bakover er angitt, OK å swappe"
+
+msgid "E494: Use w or w>>"
+msgstr "E494: Bruk w eller w>>"
+
+msgid "E319: Sorry, the command is not available in this version"
+msgstr "E319: Kommandoen er ikke tilgjengelig i denne versjonen"
+
+msgid "E172: Only one file name allowed"
+msgstr "E172: Bare ett filnavn tillatt"
+
+msgid "1 more file to edit. Quit anyway?"
+msgstr "1 annen fil å redigere. Avslutt likevel?"
+
+#, c-format
+msgid "%d more files to edit. Quit anyway?"
+msgstr "%d andre filer å redigere. Avslutt likevel?"
+
+msgid "E173: 1 more file to edit"
+msgstr "E173: 1 annen fil å redigere"
+
+#, c-format
+msgid "E173: %ld more files to edit"
+msgstr "E173: %ld andre filer å redigere"
+
+msgid "E174: Command already exists: add ! to replace it"
+msgstr "E174: Kommandoen finnes allerede: Legg til ! for å erstatte den"
+
+msgid ""
+"\n"
+" Name Args Range Complete Definition"
+msgstr ""
+"\n"
+" Navn Prm. Områd Fullfør Definering"
+
+msgid "No user-defined commands found"
+msgstr "Ingen brukerdefinerte kommandoer funnet"
+
+msgid "E175: No attribute specified"
+msgstr "E175: Ingen attributt spesifisert"
+
+msgid "E176: Invalid number of arguments"
+msgstr "E176: Ugyldig antall parametere"
+
+msgid "E177: Count cannot be specified twice"
+msgstr "E177: Antall repeteringer kan ikke bli spesifisert to ganger"
+
+msgid "E178: Invalid default value for count"
+msgstr "E178: Ugyldig standardverdi for antall repeteringer"
+
+msgid "E179: argument required for -complete"
+msgstr "E179: Trenger parameter til -complete"
+
+#, c-format
+msgid "E181: Invalid attribute: %s"
+msgstr "E181: Ugyldig attributt: %s"
+
+msgid "E182: Invalid command name"
+msgstr "E182: Ugyldig kommandonavn"
+
+msgid "E183: User defined commands must start with an uppercase letter"
+msgstr "E183: Brukerdefinerte kommandoer må ha stor forbokstav"
+
+#, c-format
+msgid "E184: No such user-defined command: %s"
+msgstr "E184: Brukerdefinert kommando finnes ikke: %s"
+
+#, c-format
+msgid "E180: Invalid complete value: %s"
+msgstr "E180: Ugyldig \"complete\"-verdi: %s"
+
+msgid "E468: Completion argument only allowed for custom completion"
+msgstr "E468: Fullføringsparameter er bare tillatt for tilpasset fullføring"
+
+msgid "E467: Custom completion requires a function argument"
+msgstr "E467: Tilpassede fullføringer trenger et funksjonsparameter"
+
+#, c-format
+msgid "E185: Cannot find color scheme %s"
+msgstr "E185: Kan ikke finne fargeoppsettet %s"
+
+msgid "Greetings, Vim user!"
+msgstr "Vær hilset, Vim-bruker!"
+
+#, fuzzy
+#~ msgid "E784: Cannot close last tab page"
+#~ msgstr "E444: Kan ikke lukke det siste vinduet"
+
+#, fuzzy
+#~ msgid "Already only one tab page"
+#~ msgstr "Allerede bare ett vindu"
+
+msgid "Edit File in new window"
+msgstr "Rediger fil i nytt vindu"
+
+#, fuzzy, c-format
+#~ msgid "Tab page %d"
+#~ msgstr "Side %d"
+
+msgid "No swap file"
+msgstr "Ingen swapfil"
+
+msgid "Append File"
+msgstr "Legg til fil"
+
+msgid "E747: Cannot change directory, buffer is modified (add ! to override)"
+msgstr ""
+"E747: Kan ikke skifte katalog, bufferen er forandret (legg til ! for å "
+"overstyre)"
+
+msgid "E186: No previous directory"
+msgstr "E186: Ingen tidligere katalog"
+
+msgid "E187: Unknown"
+msgstr "E187: Ukjent"
+
+msgid "E465: :winsize requires two number arguments"
+msgstr "E465: :winsize trenger to numeriske parametere"
+
+#, c-format
+msgid "Window position: X %d, Y %d"
+msgstr "Vindusposisjon: X %d, Y %d"
+
+msgid "E188: Obtaining window position not implemented for this platform"
+msgstr ""
+"E188: Lesing av vindusposisjon er ikke implementert på denne plattformen"
+
+msgid "E466: :winpos requires two number arguments"
+msgstr "E466: :winpos trenger to numeriske parametere"
+
+msgid "Save Redirection"
+msgstr "Lagre omdirigering"
+
+msgid "Save View"
+msgstr "Lagre utseende"
+
+msgid "Save Session"
+msgstr "Lagre økt"
+
+msgid "Save Setup"
+msgstr "Lagre oppsett"
+
+#, c-format
+msgid "E739: Cannot create directory: %s"
+msgstr "E739: Kan ikke lage katalog: %s"
+
+#, c-format
+msgid "E189: \"%s\" exists (add ! to override)"
+msgstr "E189: \"%s\" finnes (legg til ! for å overstyre)"
+
+#, c-format
+msgid "E190: Cannot open \"%s\" for writing"
+msgstr "E190: Kan ikke åpne \"%s\" for skriving"
+
+#. set mark
+msgid "E191: Argument must be a letter or forward/backward quote"
+msgstr "E191: Parameter må være en bokstav eller vanlig/baklengs apostrof"
+
+msgid "E192: Recursive use of :normal too deep"
+msgstr "E192: Rekursiv bruk av :normal er for dyp"
+
+msgid "E194: No alternate file name to substitute for '#'"
+msgstr "E194: Ingen alternative filnavn tilgjengelig som erstatning for '#'"
+
+msgid "E495: no autocommand file name to substitute for \"<afile>\""
+msgstr ""
+"E495: Ingen autokommandofilnavn tilgjengelig som erstatning for \"<afile>\""
+
+msgid "E496: no autocommand buffer number to substitute for \"<abuf>\""
+msgstr ""
+"E496: Ingen buffernummer tilgjengelig som erstatning for \"<abuf>\" i "
+"autokommando"
+
+msgid "E497: no autocommand match name to substitute for \"<amatch>\""
+msgstr ""
+"E497: Ingen autokommandonavn tilgjengelig som erstatning for \"<amatch>\""
+
+msgid "E498: no :source file name to substitute for \"<sfile>\""
+msgstr ""
+"E498: Ingen ':source'-filnavn tilgjengelig som erstatning for \"<sfile>\""
+
+#, no-c-format
+msgid "E499: Empty file name for '%' or '#', only works with \":p:h\""
+msgstr "E499: Tomt filnavn for '%' eller '#', virker bare med \":p:h\""
+
+msgid "E500: Evaluates to an empty string"
+msgstr "E500: Resulterer i en tom streng"
+
+msgid "E195: Cannot open viminfo file for reading"
+msgstr "E195: Kan ikke åpne viminfo-fil for lesing"
+
+msgid "E196: No digraphs in this version"
+msgstr "E196: Ingen spesialtegn i denne versjonen"
+
+msgid "E608: Cannot :throw exceptions with 'Vim' prefix"
+msgstr "E608: Kan ikke :throw unntak med 'Vim'-forstavelse"
+
+#. always scroll up, don't overwrite
+#, c-format
+#~ msgid "Exception thrown: %s"
+#~ msgstr ""
+
+#, c-format
+msgid "Exception finished: %s"
+msgstr "Unntak fullført: %s"
+
+#, c-format
+msgid "Exception discarded: %s"
+msgstr "Unntak forkastet: %s"
+
+#, c-format
+msgid "%s, line %ld"
+msgstr "%s, linje %ld"
+
+#. always scroll up, don't overwrite
+#, c-format
+msgid "Exception caught: %s"
+msgstr "Unntak fanget opp: %s"
+
+#, c-format
+msgid "%s made pending"
+msgstr "%s satt på venting"
+
+#, c-format
+msgid "%s resumed"
+msgstr "%s gjenopptatt"
+
+#, c-format
+msgid "%s discarded"
+msgstr "%s forkastet"
+
+msgid "Exception"
+msgstr "Unntak"
+
+msgid "Error and interrupt"
+msgstr "Feil og avbrudd"
+
+msgid "Error"
+msgstr "Feil"
+
+#. if (pending & CSTP_INTERRUPT)
+msgid "Interrupt"
+msgstr "Avbrudd"
+
+msgid "E579: :if nesting too deep"
+msgstr "E579: Nøsting av :if for dyp"
+
+msgid "E580: :endif without :if"
+msgstr "E580: :endif uten :if"
+
+msgid "E581: :else without :if"
+msgstr "E581: :else uten :if"
+
+msgid "E582: :elseif without :if"
+msgstr "E582: :elseif uten :if"
+
+msgid "E583: multiple :else"
+msgstr "E583: Flere forekomster av :else"
+
+msgid "E584: :elseif after :else"
+msgstr "E584: :elseif etter :else"
+
+msgid "E585: :while/:for nesting too deep"
+msgstr "E585: Nøsting av :while/:for er for dyp"
+
+msgid "E586: :continue without :while or :for"
+msgstr "E586: :continue uten :while eller :for"
+
+msgid "E587: :break without :while or :for"
+msgstr "E587: :break uten :while eller :for"
+
+msgid "E732: Using :endfor with :while"
+msgstr "E732: Bruker :endfor sammen med :while"
+
+msgid "E733: Using :endwhile with :for"
+msgstr "E733: Bruker :endwhile sammen med :for"
+
+msgid "E601: :try nesting too deep"
+msgstr "E601: Nøsting av :try for dyp"
+
+msgid "E603: :catch without :try"
+msgstr "E603: :catch uten :try"
+
+#. Give up for a ":catch" after ":finally" and ignore it.
+#. * Just parse.
+msgid "E604: :catch after :finally"
+msgstr "E604: :catch etter :finally"
+
+msgid "E606: :finally without :try"
+msgstr "E606: :finally uten :try"
+
+#. Give up for a multiple ":finally" and ignore it.
+msgid "E607: multiple :finally"
+msgstr "E607: Flere forekomster av :finally"
+
+msgid "E602: :endtry without :try"
+msgstr "E602: :endtry uten :try"
+
+msgid "E193: :endfunction not inside a function"
+msgstr "E193: :endfunction er ikke innenfor en funksjon"
+
+msgid "E788: Not allowed to edit another buffer now"
+msgstr "E788: Ikke tillatt å redigere en annen buffer nå"
+
+msgid "tagname"
+msgstr "navn på tag"
+
+#~ msgid " kind file\n"
+#~ msgstr ""
+
+msgid "'history' option is zero"
+msgstr "'history'-valget er null"
+
+#, c-format
+msgid ""
+"\n"
+"# %s History (newest to oldest):\n"
+msgstr ""
+"\n"
+"# %s-historie (nyeste til eldste):\n"
+
+msgid "Command Line"
+msgstr "Kommandolinje"
+
+msgid "Search String"
+msgstr "Søkestreng"
+
+msgid "Expression"
+msgstr "Uttrykk"
+
+msgid "Input Line"
+msgstr "Inndatalinje"
+
+msgid "E198: cmd_pchar beyond the command length"
+msgstr "E198: cmd_pchar utenfor kommandolengden"
+
+msgid "E199: Active window or buffer deleted"
+msgstr "E199: Aktivt vindu eller buffer slettet"
+
+msgid "Illegal file name"
+msgstr "Ulovlig filnavn"
+
+msgid "is a directory"
+msgstr "er en katalog"
+
+msgid "is not a file"
+msgstr "er ikke en fil"
+
+msgid "is a device (disabled with 'opendevice' option)"
+msgstr "er en enhet (frakoblet med 'opendevice'-valg)"
+
+msgid "[New File]"
+msgstr "[Ny fil]"
+
+msgid "[New DIRECTORY]"
+msgstr "[Ny KATALOG]"
+
+msgid "[File too big]"
+msgstr "[Filen er for stor]"
+
+msgid "[Permission Denied]"
+msgstr "[Tilgang nektet]"
+
+msgid "E200: *ReadPre autocommands made the file unreadable"
+msgstr "E200: \"*ReadPre\"-autokommandoer gjorde filen uleselig"
+
+msgid "E201: *ReadPre autocommands must not change current buffer"
+msgstr "E201: \"*ReadPre\"-autokommandoer må ikke forandre nåværende buffer"
+
+msgid "Vim: Reading from stdin...\n"
+msgstr "Vim: Leser fra stdin ...\n"
+
+msgid "Reading from stdin..."
+msgstr "Leser fra stdin ..."
+
+#. Re-opening the original file failed!
+msgid "E202: Conversion made file unreadable!"
+msgstr "E202: Konverteringen gjorde filen uleselig!"
+
+msgid "[fifo/socket]"
+msgstr "[fifo/socket]"
+
+msgid "[fifo]"
+msgstr "[fifo]"
+
+msgid "[socket]"
+msgstr "[socket]"
+
+msgid "[RO]"
+msgstr "[SB]"
+
+msgid "[CR missing]"
+msgstr "[CR mangler]"
+
+msgid "[NL found]"
+msgstr "[NL funnet]"
+
+msgid "[long lines split]"
+msgstr "[lange linjer splittes]"
+
+msgid "[NOT converted]"
+msgstr "[IKKE konvertert]"
+
+msgid "[converted]"
+msgstr "[konvertert]"
+
+msgid "[crypted]"
+msgstr "[kryptert]"
+
+#, c-format
+msgid "[CONVERSION ERROR in line %ld]"
+msgstr "[KONVERTERINGSFEIL i linje %ld]"
+
+#, c-format
+msgid "[ILLEGAL BYTE in line %ld]"
+msgstr "[ULOVLIG BYTE i linje %ld]"
+
+msgid "[READ ERRORS]"
+msgstr "[LESEFEIL]"
+
+msgid "Can't find temp file for conversion"
+msgstr "Kan ikke finne midlertidig fil for konvertering"
+
+msgid "Conversion with 'charconvert' failed"
+msgstr "Konvertering med 'charconvert' feilet"
+
+msgid "can't read output of 'charconvert'"
+msgstr "Kan ikke lese utdata fra 'charconvert'"
+
+msgid "E676: No matching autocommands for acwrite buffer"
+msgstr "E676: Ingen samsvarende autokommandoer for 'acwrite'-buffer"
+
+msgid "E203: Autocommands deleted or unloaded buffer to be written"
+msgstr "E203: Autokommandoer slettet eller lastet ut buffer som skulle lagres"
+
+msgid "E204: Autocommand changed number of lines in unexpected way"
+msgstr "E204: Autokommando forandret linjeantall på en uventet måte"
+
+msgid "NetBeans disallows writes of unmodified buffers"
+msgstr "NetBeans forbyr lagring av buffere som ikke er forandret"
+
+msgid "Partial writes disallowed for NetBeans buffers"
+msgstr "Delvis lagring ikke tillatt for NetBeans-buffere"
+
+msgid "is not a file or writable device"
+msgstr "er ikke en fil eller skrivbar enhet"
+
+msgid "writing to device disabled with 'opendevice' option"
+msgstr "skriving til enhet er slått av med 'opendevice'-valg"
+
+msgid "is read-only (add ! to override)"
+msgstr "er skrivebeskyttet (legg til ! for å overstyre)"
+
+msgid "E506: Can't write to backup file (add ! to override)"
+msgstr "E506: Kan ikke skrive til backupfil (legg til ! for å overstyre)"
+
+msgid "E507: Close error for backup file (add ! to override)"
+msgstr "E507: Feil under lukking av backupfil (legg til ! for å overstyre)"
+
+msgid "E508: Can't read file for backup (add ! to override)"
+msgstr "E508: Kan ikke lese fil for backup (legg til ! for å overstyre)"
+
+msgid "E509: Cannot create backup file (add ! to override)"
+msgstr "E509: Kan ikke lese backupfil (legg til ! for å overstyre)"
+
+msgid "E510: Can't make backup file (add ! to override)"
+msgstr "E510: Kan ikke lage backupfil (legg til ! for å overstyre)"
+
+msgid "E460: The resource fork would be lost (add ! to override)"
+msgstr "E460: Ressursforgreningen ville gått tapt (legg til ! for å overstyre)"
+
+msgid "E214: Can't find temp file for writing"
+msgstr "E214: Kan ikke finne midlertidig fil for skriving"
+
+msgid "E213: Cannot convert (add ! to write without conversion)"
+msgstr "E213: Kan ikke konvertere (legg til ! for å lagre uten konvertering)"
+
+msgid "E166: Can't open linked file for writing"
+msgstr "E166: Kan ikke åpne lenket fil for skriving"
+
+msgid "E212: Can't open file for writing"
+msgstr "E212: Kan ikke åpne fil for skriving"
+
+msgid "E667: Fsync failed"
+msgstr "E667: Fsync feilet"
+
+msgid "E512: Close failed"
+msgstr "E512: Lukking feilet"
+
+msgid "E513: write error, conversion failed (make 'fenc' empty to override)"
+msgstr ""
+"E513: Feil under skriving, konvertering feilet (gjør 'fenc' tom for å "
+"overstyre)"
+
+msgid "E514: write error (file system full?)"
+msgstr "E514: Feil under lagring (full disk?)"
+
+msgid " CONVERSION ERROR"
+msgstr " KONVERTERINGSFEIL"
+
+msgid "[Device]"
+msgstr "[Enhet]"
+
+msgid "[New]"
+msgstr "[Ny]"
+
+msgid " [a]"
+msgstr " [l]"
+
+msgid " appended"
+msgstr " lagt til"
+
+msgid " [w]"
+msgstr " [s]"
+
+msgid " written"
+msgstr " skrevet"
+
+msgid "E205: Patchmode: can't save original file"
+msgstr "E205: Patchmode: Kan ikke lagre originalfil"
+
+msgid "E206: patchmode: can't touch empty original file"
+msgstr "E206: patchmode: Kan ikke oppdatere tom originalfil"
+
+msgid "E207: Can't delete backup file"
+msgstr "E207: Kan ikke slette backupfil"
+
+msgid ""
+"\n"
+"WARNING: Original file may be lost or damaged\n"
+msgstr ""
+"\n"
+"ADVARSEL: Originalfilen kan bli tapt eller ødelagt\n"
+
+msgid "don't quit the editor until the file is successfully written!"
+msgstr "ikke avslutt editoren før filen er skikkelig lagret!"
+
+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 "%ld characters"
+msgstr "%ld tegn"
+
+msgid "[noeol]"
+msgstr "[ingenlinjeslutt]"
+
+msgid "[Incomplete last line]"
+msgstr "[Ufullstendig sistelinje]"
+
+#. 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 "ADVARSEL: Filen er blitt forandret siden den ble lest!!!"
+
+msgid "Do you really want to write to it"
+msgstr "Vil du virkelig skrive til den"
+
+#, c-format
+msgid "E208: Error writing to \"%s\""
+msgstr "E208: Feil under skriving til \"%s\""
+
+#, c-format
+msgid "E209: Error closing \"%s\""
+msgstr "E209: Feil under lukking av \"%s\""
+
+#, c-format
+msgid "E210: Error reading \"%s\""
+msgstr "E210: Feil under lesing av \"%s\""
+
+msgid "E246: FileChangedShell autocommand deleted buffer"
+msgstr "E246: Autokommandoen \"FileChangedShell\" slettet buffer"
+
+#, c-format
+msgid "E211: File \"%s\" no longer available"
+msgstr "E211: Filen \"%s\" er ikke lenger tilgjengelig"
+
+#, c-format
+msgid ""
+"W12: Warning: File \"%s\" has changed and the buffer was changed in Vim as "
+"well"
+msgstr ""
+"W12: Advarsel: Filen \"%s\" er forandret og bufferen var også forandret i Vim"
+
+msgid "See \":help W12\" for more info."
+msgstr "Se \":help W12\" for mer informasjon."
+
+#, c-format
+msgid "W11: Warning: File \"%s\" has changed since editing started"
+msgstr "W11: Advarsel: Filen \"%s\" er forandret siden redigeringen startet"
+
+msgid "See \":help W11\" for more info."
+msgstr "Se \":help W11\" for mer informasjon."
+
+#, c-format
+msgid "W16: Warning: Mode of file \"%s\" has changed since editing started"
+msgstr ""
+"W16: Advarsel: Rettighetene til filen \"%s\" er forandret siden redigeringen "
+"startet"
+
+msgid "See \":help W16\" for more info."
+msgstr "Se \":help W16\" for mer informasjon."
+
+#, c-format
+msgid "W13: Warning: File \"%s\" has been created after editing started"
+msgstr ""
+"W13: Advarsel: Filen \"%s\" er blitt opprettet etter at redigeringen startet"
+
+msgid "Warning"
+msgstr "Advarsel"
+
+msgid ""
+"&OK\n"
+"&Load File"
+msgstr ""
+"&OK\n"
+"&Åpne fil"
+
+#, c-format
+msgid "E462: Could not prepare for reloading \"%s\""
+msgstr "E462: Kunne ikke forberede for relasting \"%s\""
+
+#, c-format
+msgid "E321: Could not reload \"%s\""
+msgstr "E321: Kunne ikke laste \"%s\" på nytt"
+
+msgid "--Deleted--"
+msgstr "--Slettet--"
+
+#, c-format
+msgid "auto-removing autocommand: %s <buffer=%d>"
+msgstr "fjerner autokommando automatisk: %s <buffer=%d>"
+
+#. the group doesn't exist
+#, c-format
+msgid "E367: No such group: \"%s\""
+msgstr "E367: Gruppen finnes ikke: \"%s\""
+
+#, c-format
+msgid "E215: Illegal character after *: %s"
+msgstr "E215: Ulovlig tegn etter *: %s"
+
+#, c-format
+msgid "E216: No such event: %s"
+msgstr "E216: Handlingen finnes ikke: %s"
+
+#, c-format
+msgid "E216: No such group or event: %s"
+msgstr "E216: Gruppen eller handlingen finnes ikke: %s"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Auto-Commands ---"
+msgstr ""
+"\n"
+"--- Autokommandoer ---"
+
+#, c-format
+msgid "E680: <buffer=%d>: invalid buffer number "
+msgstr "E680: <buffer=%d>: Ugyldig buffernummer"
+
+msgid "E217: Can't execute autocommands for ALL events"
+msgstr "E217: Kan ikke utføre autokommandoer for ALLE hendelser"
+
+msgid "No matching autocommands"
+msgstr "Ingen samsvarende autokommandoer"
+
+msgid "E218: autocommand nesting too deep"
+msgstr "E218: Nøsting av autokommandoer for dyp"
+
+#, c-format
+msgid "%s Auto commands for \"%s\""
+msgstr "%s Autokommandoer for \"%s\""
+
+#, c-format
+msgid "Executing %s"
+msgstr "Utfører %s"
+
+#, c-format
+msgid "autocommand %s"
+msgstr "autokommando %s"
+
+msgid "E219: Missing {."
+msgstr "E219: Mangler {."
+
+msgid "E220: Missing }."
+msgstr "E220: Mangler }."
+
+msgid "E490: No fold found"
+msgstr "E490: Ingen fold funnet"
+
+msgid "E350: Cannot create fold with current 'foldmethod'"
+msgstr "E350: Kan ikke lage fold med nåværende 'foldmethod'"
+
+msgid "E351: Cannot delete fold with current 'foldmethod'"
+msgstr "E351: Kan ikke slette fold med nåværende 'foldmethod'"
+
+#, c-format
+msgid "+--%3ld lines folded "
+msgstr "+--%3ld linjer foldet "
+
+msgid "E222: Add to read buffer"
+msgstr "E222: Legger til allerede lest buffer"
+
+msgid "E223: recursive mapping"
+msgstr "E223: Rekursiv mapping"
+
+#, c-format
+msgid "E224: global abbreviation already exists for %s"
+msgstr "E224: Global forkortelse finnes allerede for %s"
+
+#, c-format
+msgid "E225: global mapping already exists for %s"
+msgstr "E225: Global mapping finnes allerede for %s"
+
+#, c-format
+msgid "E226: abbreviation already exists for %s"
+msgstr "E226: Forkortelse finnes allerede for %s"
+
+#, c-format
+msgid "E227: mapping already exists for %s"
+msgstr "E227: Mappingen finnes allerede for %s"
+
+msgid "No abbreviation found"
+msgstr "Ingen forkortelse funnet"
+
+msgid "No mapping found"
+msgstr "Ingen mapping funnet"
+
+msgid "E228: makemap: Illegal mode"
+msgstr "E228: makemap: Ulovlig modus"
+
+msgid "E229: Cannot start the GUI"
+msgstr "E229: Kan ikke starte grafisk brukergrensesnitt (GUI)"
+
+#, c-format
+msgid "E230: Cannot read from \"%s\""
+msgstr "E230: Kan ikke lese fra \"%s\""
+
+msgid "E665: Cannot start GUI, no valid font found"
+msgstr ""
+"E665: Kan ikke starte grafisk brukergrensesnitt, fant ingen gyldig font"
+
+msgid "E231: 'guifontwide' invalid"
+msgstr "E231: 'guifontwide' ugyldig"
+
+msgid "E599: Value of 'imactivatekey' is invalid"
+msgstr "E599: Verdien for 'imactivatekey' er ugyldig"
+
+#, c-format
+msgid "E254: Cannot allocate color %s"
+msgstr "E254: Kan ikke reservere farge %s"
+
+msgid "No match at cursor, finding next"
+msgstr "Ingen treff ved markøren, finner neste"
+
+msgid "<cannot open> "
+msgstr "<kan ikke åpne> "
+
+#, c-format
+msgid "E616: vim_SelFile: can't get font %s"
+msgstr "E616: vim_SelFile: Kan ikke bruke skrifttypen %s"
+
+msgid "E614: vim_SelFile: can't return to current directory"
+msgstr "E614: vim_SelFile: Kan ikke returnere til nåværende katalog"
+
+msgid "Pathname:"
+msgstr "Sti:"
+
+msgid "E615: vim_SelFile: can't get current directory"
+msgstr "E615: vim_SelFile: Kan ikke finne nåværende katalog"
+
+msgid "OK"
+msgstr "OK"
+
+msgid "Cancel"
+msgstr "Avbryt"
+
+msgid "Scrollbar Widget: Could not get geometry of thumb pixmap."
+msgstr "Rullefeltelement: Klarte ikke hente dimensjoner på \"thumb pixmap\"."
+
+msgid "Vim dialog"
+msgstr "Dialogvindu for Vim"
+
+msgid "E232: Cannot create BalloonEval with both message and callback"
+msgstr "E232: Kan ikke lage BalloonEval med både melding og tilbakekall"
+
+msgid "Vim dialog..."
+msgstr "Vim dialogvindu ..."
+
+msgid ""
+"&Yes\n"
+"&No\n"
+"&Cancel"
+msgstr ""
+"&Ja\n"
+"&Nei\n"
+"&Avbryt"
+
+msgid "Input _Methods"
+msgstr "Inndata-_metoder"
+
+msgid "VIM - Search and Replace..."
+msgstr "VIM - Søk og erstatt ..."
+
+msgid "VIM - Search..."
+msgstr "VIM - Søk ..."
+
+msgid "Find what:"
+msgstr "Finn hva:"
+
+msgid "Replace with:"
+msgstr "Erstatt med:"
+
+#. whole word only button
+msgid "Match whole word only"
+msgstr "Finn kun hele ord"
+
+#. match case button
+msgid "Match case"
+msgstr "Forskjell på store/små bokstaver"
+
+msgid "Direction"
+msgstr "Retning"
+
+#. 'Up' and 'Down' buttons
+msgid "Up"
+msgstr "Opp"
+
+msgid "Down"
+msgstr "Ned"
+
+msgid "Find Next"
+msgstr "Finn neste"
+
+msgid "Replace"
+msgstr "Erstatt"
+
+msgid "Replace All"
+msgstr "Erstatt alle"
+
+msgid "Vim: Received \"die\" request from session manager\n"
+msgstr "Vim: Mottok \"dø\"-forespørsel fra øktbehandleren\n"
+
+msgid "Close"
+msgstr "Lukk"
+
+#~ msgid "New tab"
+#~ msgstr ""
+
+#~ msgid "Open Tab..."
+#~ msgstr ""
+
+msgid "Vim: Main window unexpectedly destroyed\n"
+msgstr "Vim: Uventet ødeleggelse av hovedvinduet\n"
+
+msgid "Font Selection"
+msgstr "Velge skrifttype"
+
+msgid "Used CUT_BUFFER0 instead of empty selection"
+msgstr "Brukte CUT_BUFFER0 istedenfor tomt valg"
+
+msgid "&Filter"
+msgstr "&Filter"
+
+msgid "&Cancel"
+msgstr "&Avbryt"
+
+msgid "Directories"
+msgstr "Kataloger"
+
+msgid "Filter"
+msgstr "Filter"
+
+msgid "&Help"
+msgstr "&Hjelp"
+
+msgid "Files"
+msgstr "Filer"
+
+msgid "&OK"
+msgstr "&OK"
+
+msgid "Selection"
+msgstr "Valg"
+
+msgid "Find &Next"
+msgstr "Finn &neste"
+
+msgid "&Replace"
+msgstr "E&rstatt"
+
+msgid "Replace &All"
+msgstr "Erstatt &alle"
+
+msgid "&Undo"
+msgstr "&Angre"
+
+#, c-format
+msgid "E671: Cannot find window title \"%s\""
+msgstr "E671: Fant ikke vindutittel \"%s\""
+
+#, c-format
+msgid "E243: Argument not supported: \"-%s\"; Use the OLE version."
+msgstr "E243: Parameter ikke støttet: \"-%s\"; Bruk OLE-versjonen."
+
+msgid "E672: Unable to open window inside MDI application"
+msgstr "E672: Klarer ikke åpne vindu inne i MDI-applikasjon"
+
+#~ msgid "Close tab"
+#~ msgstr ""
+
+#~ msgid "Open tab..."
+#~ msgstr ""
+
+msgid "Find string (use '\\\\' to find a '\\')"
+msgstr "Finn streng (bruk '\\\\' for å finne en '\\')"
+
+msgid "Find & Replace (use '\\\\' to find a '\\')"
+msgstr "Søk og erstatt (bruk '\\\\' for å finne en '\\')"
+
+#. 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 "Ikke brukt"
+
+msgid "Directory\t*.nothing\n"
+msgstr "Katalog\t*.ingenting\n"
+
+msgid "Vim E458: Cannot allocate colormap entry, some colors may be incorrect"
+msgstr "Vim E458: Kan ikke reservere fargekart, noen farger kan være feil"
+
+#, c-format
+msgid "E250: Fonts for the following charsets are missing in fontset %s:"
+msgstr "E250: Skrifttyper for de følgende tegnsett mangler i fontsett %s:"
+
+#, c-format
+msgid "E252: Fontset name: %s"
+msgstr "E252: Navn på skrifttypesett: %s"
+
+#, c-format
+msgid "Font '%s' is not fixed-width"
+msgstr "Skrifttypen '%s' har ikke konstant bredde"
+
+#, c-format
+msgid "E253: Fontset name: %s\n"
+msgstr "E253: Navn på skrifttypesett: %s\n"
+
+#, c-format
+msgid "Font0: %s\n"
+msgstr "Font0: %s\n"
+
+#, c-format
+msgid "Font1: %s\n"
+msgstr "Font1: %s\n"
+
+#, c-format
+msgid "Font%ld width is not twice that of font0\n"
+msgstr "Font%ld-bredde er ikke to ganger bredden av font0\n"
+
+#, c-format
+msgid "Font0 width: %ld\n"
+msgstr "Font0-bredde: %ld\n"
+
+#, c-format
+msgid ""
+"Font1 width: %ld\n"
+"\n"
+msgstr ""
+"Font1-bredde: %ld\n"
+"\n"
+
+msgid "Invalid font specification"
+msgstr "Ugyldig skrifttypespesifisering"
+
+msgid "&Dismiss"
+msgstr "&Forkast"
+
+msgid "no specific match"
+msgstr "ingen spesifikke treff"
+
+msgid "Vim - Font Selector"
+msgstr "Vim - Skrifttypevelger"
+
+msgid "Name:"
+msgstr "Navn:"
+
+#. create toggle button
+msgid "Show size in Points"
+msgstr "Vis størrelse i punkter"
+
+msgid "Encoding:"
+msgstr "Koding:"
+
+msgid "Font:"
+msgstr "Skrifttype:"
+
+msgid "Style:"
+msgstr "Stil:"
+
+msgid "Size:"
+msgstr "Størrelse:"
+
+#~ msgid "E256: Hangul automata ERROR"
+#~ msgstr ""
+
+msgid "E550: Missing colon"
+msgstr "E550: Mangler kolon"
+
+msgid "E551: Illegal component"
+msgstr "E551: Ulovlig komponent"
+
+msgid "E552: digit expected"
+msgstr "E552: Siffer forventet"
+
+#, c-format
+msgid "Page %d"
+msgstr "Side %d"
+
+msgid "No text to be printed"
+msgstr "Ingen tekst for utskrift"
+
+#, c-format
+msgid "Printing page %d (%d%%)"
+msgstr "Skriver ut side %d (%d%%)"
+
+#, c-format
+msgid " Copy %d of %d"
+msgstr " Kopi %d av %d"
+
+#, c-format
+msgid "Printed: %s"
+msgstr "Skrevet ut: %s"
+
+msgid "Printing aborted"
+msgstr "Utskrift avbrutt"
+
+msgid "E455: Error writing to PostScript output file"
+msgstr "E455: Feil under skriving til Postscript-fil"
+
+#, c-format
+msgid "E624: Can't open file \"%s\""
+msgstr "E624: Kan ikke åpne filen \"%s\""
+
+#, c-format
+msgid "E457: Can't read PostScript resource file \"%s\""
+msgstr "E457: Kan ikke lese Postscript-ressursfil \"%s\""
+
+#, c-format
+msgid "E618: file \"%s\" is not a PostScript resource file"
+msgstr "E618: Filen \"%s\" er ikke en Postscript-ressursfil"
+
+#, c-format
+msgid "E619: file \"%s\" is not a supported PostScript resource file"
+msgstr "E619: Det er ikke støtte for Postscript-ressursfilen \"%s\""
+
+#, c-format
+msgid "E621: \"%s\" resource file has wrong version"
+msgstr "E621: Ressursfilen \"%s\" er feil versjon"
+
+msgid "E673: Incompatible multi-byte encoding and character set."
+msgstr "E673: Inkompatibel multibytekoding og tegnsett"
+
+msgid "E674: printmbcharset cannot be empty with multi-byte encoding."
+msgstr "E674: printmbcharset kan ikke være tom med multibytekoding"
+
+msgid "E675: No default font specified for multi-byte printing."
+msgstr "E675: Ingen standardfont spesifisert for multibyteutskrift"
+
+msgid "E324: Can't open PostScript output file"
+msgstr "E324: Kan ikke åpne Postscript-fil for skriving"
+
+#, c-format
+msgid "E456: Can't open file \"%s\""
+msgstr "E456: Kan ikke åpne filen \"%s\""
+
+msgid "E456: Can't find PostScript resource file \"prolog.ps\""
+msgstr "E456: Fant ikke Postscript-ressursfilen \"prolog.ps\""
+
+msgid "E456: Can't find PostScript resource file \"cidfont.ps\""
+msgstr "E456: Fant ikke Postscript-ressursfilen \"cidfont.ps\""
+
+#, c-format
+msgid "E456: Can't find PostScript resource file \"%s.ps\""
+msgstr "E456: Fant ikke Postscript-ressursfilen \"%s.ps\""
+
+#, c-format
+msgid "E620: Unable to convert to print encoding \"%s\""
+msgstr "E620: Klarte ikke å konvertere til utskriftskoding \"%s\""
+
+msgid "Sending to printer..."
+msgstr "Sender til skriver ..."
+
+msgid "E365: Failed to print PostScript file"
+msgstr "E365: Feil under utskrift av Postscript-fil"
+
+msgid "Print job sent."
+msgstr "Skriverjobb sendt."
+
+msgid "Add a new database"
+msgstr "Legg til en ny database"
+
+msgid "Query for a pattern"
+msgstr "Forespørsel etter søkestreng"
+
+msgid "Show this message"
+msgstr "Vis denne meldingen"
+
+msgid "Kill a connection"
+msgstr "Drep en forbindelse"
+
+msgid "Reinit all connections"
+msgstr "Reinitialiser alle forbindelser"
+
+msgid "Show connections"
+msgstr "Vis forbindelser"
+
+#, c-format
+msgid "E560: Usage: cs[cope] %s"
+msgstr "E560: Bruk: cs[cope] %s"
+
+msgid "This cscope command does not support splitting the window.\n"
+msgstr "Denne cscope-kommandoen støtter ikke splitting av vinduet.\n"
+
+msgid "E562: Usage: cstag <ident>"
+msgstr "E562: Bruk: cstag <identifikator>"
+
+msgid "E257: cstag: tag not found"
+msgstr "E257: cstag: Tag ikke funnet"
+
+#, c-format
+msgid "E563: stat(%s) error: %d"
+msgstr "E563: stat(%s) feil: %d"
+
+msgid "E563: stat error"
+msgstr "E563: \"stat\"-feil"
+
+#, c-format
+msgid "E564: %s is not a directory or a valid cscope database"
+msgstr "E564: %s er ikke en katalog eller gyldig cscope-database"
+
+#, c-format
+msgid "Added cscope database %s"
+msgstr "La til cscope-database %s"
+
+#, c-format
+msgid "E262: error reading cscope connection %ld"
+msgstr "E262: Feil under lesing av cscope-forbindelse %ld"
+
+msgid "E561: unknown cscope search type"
+msgstr "E561: Ukjent cscope-søketype"
+
+msgid "E566: Could not create cscope pipes"
+msgstr "E566: Kunne ikke lage cscope-rør (\"pipe\")"
+
+msgid "E622: Could not fork for cscope"
+msgstr "E622: Klarte ikke lage tvillingprosess for cscope"
+
+msgid "cs_create_connection exec failed"
+msgstr "Utføring av cs_create_connection feilet"
+
+msgid "E623: Could not spawn cscope process"
+msgstr "E623: Klarte ikke starte cscope-prosess"
+
+msgid "cs_create_connection: fdopen for to_fp failed"
+msgstr "cs_create_connection: fdopen for to_fp feilet"
+
+msgid "cs_create_connection: fdopen for fr_fp failed"
+msgstr "cs_create_connection: fdopen for fr_fp feilet"
+
+msgid "E567: no cscope connections"
+msgstr "E567: Ingen cscope-forbindelse"
+
+#, c-format
+msgid "E259: no matches found for cscope query %s of %s"
+msgstr "E259: Ingen treff funnet for cscope-forespørsel %s av %s"
+
+#, c-format
+msgid "E469: invalid cscopequickfix flag %c for %c"
+msgstr "E469: Ugyldig \"cscopequickfix\"-flagg %c for %c"
+
+msgid "cscope commands:\n"
+msgstr "cscope-kommandoer:\n"
+
+#, c-format
+msgid "%-5s: %-30s (Usage: %s)"
+msgstr "%-5s: %-30s (Bruk: %s)"
+
+#, c-format
+msgid "E625: cannot open cscope database: %s"
+msgstr "E625: Kan ikke åpne cscope-database: %s"
+
+msgid "E626: cannot get cscope database information"
+msgstr "E626: Kan ikke hente informasjon om cscope-database"
+
+msgid "E568: duplicate cscope database not added"
+msgstr "E568: Duplisert cscope-database ikke lagt til"
+
+msgid "E569: maximum number of cscope connections reached"
+msgstr "E569: Maksimum antall cscope-forbindelser nådd"
+
+#, c-format
+msgid "E261: cscope connection %s not found"
+msgstr "E261: cscope-forbindelse %s ikke funnet"
+
+#, c-format
+msgid "cscope connection %s closed"
+msgstr "cscope-forbindelsen %s stengt"
+
+#. should not reach here
+msgid "E570: fatal error in cs_manage_matches"
+msgstr "E570: Kritisk feil 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: Cscope-feil: %s"
+
+msgid "All cscope databases reset"
+msgstr "Alle cscope-databaser resatt"
+
+msgid "no cscope connections\n"
+msgstr "ingen cscope-forbindelser\n"
+
+msgid " # pid database name prepend path\n"
+msgstr " # pid databasenavn legg til sti\n"
+
+msgid ""
+"???: Sorry, this command is disabled, the MzScheme library could not be "
+"loaded."
+msgstr ""
+"???: Denne kommandoen er deaktivert, MzScheme-biblioteket kunne ikke lastes."
+
+msgid "invalid expression"
+msgstr "ugyldig uttrykk"
+
+msgid "expressions disabled at compile time"
+msgstr "uttrykk deaktivert på kompileringsstadiet"
+
+msgid "hidden option"
+msgstr "skjult valg"
+
+msgid "unknown option"
+msgstr "ukjent valg"
+
+msgid "window index is out of range"
+msgstr "indeks for vindu er utenfor område"
+
+msgid "couldn't open buffer"
+msgstr "klarte ikke å åpne buffer"
+
+msgid "cannot save undo information"
+msgstr "kan ikke lagre angre-informasjon"
+
+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 sette inn linje"
+
+msgid "string cannot contain newlines"
+msgstr "streng kan ikke inneholde linjeskift"
+
+msgid "Vim error: ~a"
+msgstr "Vim-feil: ~a"
+
+msgid "Vim error"
+msgstr "Vim-feil"
+
+msgid "buffer is invalid"
+msgstr "buffer er ugyldig"
+
+msgid "window is invalid"
+msgstr "vindu er ugyldig"
+
+msgid "linenr out of range"
+msgstr "linjenummer utenfor område"
+
+msgid "not allowed in the Vim sandbox"
+msgstr "ikke tillatt i Vim-sandkassen"
+
+msgid ""
+"E263: Sorry, this command is disabled, the Python library could not be "
+"loaded."
+msgstr ""
+"E263: Denne kommandoen er deaktivert, Python-biblioteket kunne ikke lastes."
+
+msgid "E659: Cannot invoke Python recursively"
+msgstr "E659: Kan ikke starte Python rekursivt"
+
+msgid "can't delete OutputObject attributes"
+msgstr "Kan ikke slette \"OutputObject\"-attributter"
+
+msgid "softspace must be an integer"
+msgstr "\"softspace\" må være et heltall"
+
+msgid "invalid attribute"
+msgstr "ugyldig attributt"
+
+msgid "writelines() requires list of strings"
+msgstr "writelines() krever en liste av strenger"
+
+msgid "E264: Python: Error initialising I/O objects"
+msgstr "E264: Python: Feil under initialisering av I/U-objekter"
+
+msgid "attempt to refer to deleted buffer"
+msgstr "forsøk på å referere til slettet buffer"
+
+msgid "line number out of range"
+msgstr "linjenummer utenfor område"
+
+#, c-format
+msgid "<buffer object (deleted) at %8lX>"
+msgstr "<bufferobjekt (slettet) ved %8lX>"
+
+msgid "invalid mark name"
+msgstr "ugyldig merkenavn"
+
+msgid "no such buffer"
+msgstr "bufferen finnes ikke"
+
+msgid "attempt to refer to deleted window"
+msgstr "forsøk på å referere til slettet vindu"
+
+msgid "readonly attribute"
+msgstr "skrivebeskyttet attributt"
+
+msgid "cursor position outside buffer"
+msgstr "markørposisjon utenfor buffer"
+
+#, c-format
+msgid "<window object (deleted) at %.8lX>"
+msgstr "<vindusobjekt (slettet) ved %.8lX>"
+
+#, c-format
+msgid "<window object (unknown) at %.8lX>"
+msgstr "<vindusobjekt (ukjent) ved %.8lX>"
+
+#, c-format
+msgid "<window %d>"
+msgstr "<vindu %d>"
+
+msgid "no such window"
+msgstr "vinduet finnes ikke"
+
+#~ msgid "E265: $_ must be an instance of String"
+#~ msgstr ""
+
+msgid ""
+"E266: Sorry, this command is disabled, the Ruby library could not be loaded."
+msgstr ""
+"E266: Denne kommandoen er deaktivert, Ruby-biblioteket kunne ikke lastes."
+
+msgid "E267: unexpected return"
+msgstr "E267: Uventet return"
+
+msgid "E268: unexpected next"
+msgstr "E268: Uvented 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 ""
+
+msgid "E272: unhandled exception"
+msgstr "E272: Ubehandlet unntak"
+
+#, c-format
+msgid "E273: unknown longjmp status %d"
+msgstr "E273: Ukjent longjmp-status %d"
+
+msgid "Toggle implementation/definition"
+msgstr "Bytt mellom implementasjon/definisjon"
+
+msgid "Show base class of"
+msgstr "Vis basisklasse av"
+
+msgid "Show overridden member function"
+msgstr "Vis overstyrt medlemsfunksjon"
+
+msgid "Retrieve from file"
+msgstr "Hent fra fil"
+
+msgid "Retrieve from project"
+msgstr "Hent fra prosjekt"
+
+msgid "Retrieve from all projects"
+msgstr "Hent fra alle prosjekter"
+
+msgid "Retrieve"
+msgstr "Hent"
+
+msgid "Show source of"
+msgstr "Vis kilde til"
+
+msgid "Find symbol"
+msgstr "Finn symbol"
+
+msgid "Browse class"
+msgstr "Bla gjennom klasse"
+
+msgid "Show class in hierarchy"
+msgstr "Vis klasse i hierarki"
+
+msgid "Show class in restricted hierarchy"
+msgstr "Vis klasse i begrenset hierarki"
+
+msgid "Xref refers to"
+msgstr "Xref refererer til"
+
+msgid "Xref referred by"
+msgstr "Xref referert av"
+
+msgid "Xref has a"
+msgstr "Xref har en"
+
+msgid "Xref used by"
+msgstr "Xref brukt av"
+
+msgid "Show docu of"
+msgstr "Vis docu av"
+
+msgid "Generate docu for"
+msgstr "Generer docu for"
+
+msgid ""
+"Cannot connect to SNiFF+. Check environment (sniffemacs must be found in "
+"$PATH).\n"
+msgstr ""
+"Kan ikke koble til SNiFF+. Sjekk miljøet (\"environment\") (sniffemacs må "
+"bli funnet i $PATH).\n"
+
+msgid "E274: Sniff: Error during read. Disconnected"
+msgstr "E274: Sniff: Feil under lesing. Frakoblet"
+
+msgid "SNiFF+ is currently "
+msgstr "SNiFF+ er for øyeblikket "
+
+msgid "not "
+msgstr "ikke "
+
+msgid "connected"
+msgstr "oppkoblet"
+
+#, c-format
+msgid "E275: Unknown SNiFF+ request: %s"
+msgstr "E275: Ukjent SNiFF+-forespørsel: %s"
+
+msgid "E276: Error connecting to SNiFF+"
+msgstr "E276: Feil ved oppkobling til SNiFF+"
+
+msgid "E278: SNiFF+ not connected"
+msgstr "E278: SNiFF+ ikke tilkoblet"
+
+msgid "E279: Not a SNiFF+ buffer"
+msgstr "E279: Ikke en SNiFF+-buffer"
+
+msgid "Sniff: Error during write. Disconnected"
+msgstr "Sniff: Feil under skriving. Frakoblet"
+
+msgid "invalid buffer number"
+msgstr "ugyldig buffernummer"
+
+msgid "not implemented yet"
+msgstr "ikke implementert enda"
+
+#. ???
+msgid "cannot set line(s)"
+msgstr "kan ikke sette linje(r)"
+
+msgid "mark not set"
+msgstr "merke ikke satt"
+
+#, c-format
+msgid "row %d column %d"
+msgstr "rad %d kolonne %d"
+
+msgid "cannot insert/append line"
+msgstr "kan ikke sette inn/legge til linje"
+
+msgid "unknown flag: "
+msgstr "ukjent flagg: "
+
+msgid "unknown vimOption"
+msgstr "ukjent vimOption"
+
+msgid "keyboard interrupt"
+msgstr "tastaturavbrudd"
+
+msgid "vim error"
+msgstr "vim-feil"
+
+msgid "cannot create buffer/window command: object is being deleted"
+msgstr "kan ikke opprette buffer/vindukommando: Objektet slettes"
+
+msgid ""
+"cannot register callback command: buffer/window is already being deleted"
+msgstr ""
+"kan ikke registrere callback-kommando: Buffer/vindu er allerede slettet"
+
+#. This should never happen. Famous last word?
+msgid ""
+"E280: TCL FATAL ERROR: reflist corrupt!? Please report this to vim-dev@vim."
+"org"
+msgstr ""
+"E280: TCL KRITISK FEIL: reflist skadet!? Vennligst rapporter dette til vim-"
+"dev@vim.org"
+
+msgid "cannot register callback command: buffer/window reference not found"
+msgstr ""
+"kan ikke registrere callback-kommando: Buffer/vindureferanse ikke funnet"
+
+msgid ""
+"E571: Sorry, this command is disabled: the Tcl library could not be loaded."
+msgstr ""
+"E571: Denne kommandoen er deaktivert, Tcl-biblioteket kunne ikke lastes."
+
+msgid ""
+"E281: TCL ERROR: exit code is not int!? Please report this to vim-dev@vim.org"
+msgstr ""
+"E281: TCL-FEIL: Avslutningskode er ikke int!? Vennligst rapporter dette til "
+"vim-dev@vim.org"
+
+#, c-format
+msgid "E572: exit code %d"
+msgstr "E572: Avslutningskode %d"
+
+msgid "cannot get line"
+msgstr "kan ikke hente linje"
+
+msgid "Unable to register a command server name"
+msgstr "Klarer ikke registrere kommandotjenernavn"
+
+msgid "E248: Failed to send command to the destination program"
+msgstr "E248: Klarte ikke sende kommando til destinasjonsprogrammet"
+
+#, c-format
+msgid "E573: Invalid server id used: %s"
+msgstr "E573: Ugyldig tjener-id brukt: %s"
+
+msgid "E251: VIM instance registry property is badly formed. Deleted!"
+msgstr ""
+"E251: Registry-egenskapen for VIM-oppføringen er ikke korrekt. Slettet!"
+
+msgid "Unknown option argument"
+msgstr "Ukjent parameter til valg"
+
+msgid "Too many edit arguments"
+msgstr "For mange redigeringsparametere"
+
+msgid "Argument missing after"
+msgstr "Parameter mangler etter"
+
+msgid "Garbage after option argument"
+msgstr "Søppel etter valgparameter"
+
+msgid "Too many \"+command\", \"-c command\" or \"--cmd command\" arguments"
+msgstr ""
+"For mange \"+command\"-, \"-c command\"- eller \"--cmd kommando\"-parametere"
+
+msgid "Invalid argument for"
+msgstr "Ugyldig parameter for"
+
+#, c-format
+msgid "%d files to edit\n"
+msgstr "%d filer å redigere\n"
+
+msgid "This Vim was not compiled with the diff feature."
+msgstr "Denne Vim-versjonen er kompilert uten differansefunksjonen."
+
+msgid "Attempt to open script file again: \""
+msgstr "Forsøk på å åpne skriptfilen igjen: \""
+
+msgid "Cannot open for reading: \""
+msgstr "Kan ikke åpne for lesing: \""
+
+msgid "Cannot open for script output: \""
+msgstr "Kan ikke åpne for skript-utdata: \""
+
+msgid "Vim: Error: Failure to start gvim from NetBeans\n"
+msgstr "Vim: Feil: Feil under start av gvim fra NetBeans\n"
+
+msgid "Vim: Warning: Output is not to a terminal\n"
+msgstr "Vim: Advarsel: Utdata går ikke til en terminal\n"
+
+msgid "Vim: Warning: Input is not from a terminal\n"
+msgstr "Vim: Advarsel: Inndata kommer ikke fra en terminal\n"
+
+#. just in case..
+msgid "pre-vimrc command line"
+msgstr "pre-vimrc kommandolinje"
+
+#, c-format
+msgid "E282: Cannot read from \"%s\""
+msgstr "E282: Kan ikke lese fra \"%s\""
+
+msgid ""
+"\n"
+"More info with: \"vim -h\"\n"
+msgstr ""
+"\n"
+"Mer info med: \"vim -h\"\n"
+
+msgid "[file ..] edit specified file(s)"
+msgstr "[file ..] rediger spesifisert(e) fil(er)"
+
+msgid "- read text from stdin"
+msgstr "- les tekst fra stdin"
+
+msgid "-t tag edit file where tag is defined"
+msgstr "-t tag rediger fil hvor en tag er definert"
+
+msgid "-q [errorfile] edit file with first error"
+msgstr "-q [feilfil] rediger fil med første feil"
+
+msgid ""
+"\n"
+"\n"
+"usage:"
+msgstr ""
+"\n"
+"\n"
+"bruk:"
+
+msgid " vim [arguments] "
+msgstr " vim [parametere] "
+
+msgid ""
+"\n"
+" or:"
+msgstr ""
+"\n"
+" eller:"
+
+msgid "where case is ignored prepend / to make flag upper case"
+msgstr ""
+"der bokstavstørrelse ignoreres, legg til / i begynnelsen for\n"
+"å gjøre flagget om til stor bokstav"
+
+msgid ""
+"\n"
+"\n"
+"Arguments:\n"
+msgstr ""
+"\n"
+"\n"
+"Parametere:\n"
+
+msgid "--\t\t\tOnly file names after this"
+msgstr "--\t\t\tBare filnavn etter dette"
+
+msgid "--literal\t\tDon't expand wildcards"
+msgstr "--literal\t\tIkke utvid jokertegn"
+
+msgid "-register\t\tRegister this gvim for OLE"
+msgstr "-register\t\tRegistrer gvim for OLE"
+
+msgid "-unregister\t\tUnregister gvim for OLE"
+msgstr "-unregister\t\tFjern OLE-registrering for gvim"
+
+msgid "-g\t\t\tRun using GUI (like \"gvim\")"
+msgstr "-g\t\t\tKjør med GUI (som \"gvim\")"
+
+msgid "-f or --nofork\tForeground: Don't fork when starting GUI"
+msgstr "-f eller --nofork\tForgrunn: Ikke fork når GUI-et startes"
+
+msgid "-v\t\t\tVi mode (like \"vi\")"
+msgstr "-v\t\t\tVi-modus (som \"vi\")"
+
+msgid "-e\t\t\tEx mode (like \"ex\")"
+msgstr "-e\t\t\tEx-modus (som \"ex\")"
+
+msgid "-s\t\t\tSilent (batch) mode (only for \"ex\")"
+msgstr "-s\t\t\tStille (batch) modus (bare for \"ex\")"
+
+msgid "-d\t\t\tDiff mode (like \"vimdiff\")"
+msgstr "-d\t\t\tDifferanse-modus (som \"vimdiff\")"
+
+msgid "-y\t\t\tEasy mode (like \"evim\", modeless)"
+msgstr "-y\t\t\tLett modus (som \"evim\", uten modus)"
+
+msgid "-R\t\t\tReadonly mode (like \"view\")"
+msgstr "-R\t\t\tSkrivebeskyttet modus (som \"view\")"
+
+msgid "-Z\t\t\tRestricted mode (like \"rvim\")"
+msgstr "-Z\t\t\tBegrenset modus (som \"rvim\")"
+
+msgid "-m\t\t\tModifications (writing files) not allowed"
+msgstr "-m\t\t\tModifisering (lagring av filer) ikke tillatt"
+
+msgid "-M\t\t\tModifications in text not allowed"
+msgstr "-M\t\t\tModifiseringer i teksten ikke tillatt"
+
+msgid "-b\t\t\tBinary mode"
+msgstr "-b\t\t\tBinærmodus"
+
+msgid "-l\t\t\tLisp mode"
+msgstr "-l\t\t\tLisp-modus"
+
+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 helt Vi-kompatibel: 'nocompatible'"
+
+msgid "-V[N]\t\tVerbose level"
+msgstr "-V[N]\t\tInformasjonsnivå (\"Verbose\")"
+
+msgid "-D\t\t\tDebugging mode"
+msgstr "-D\t\t\tDebuggingsmodus"
+
+msgid "-n\t\t\tNo swap file, use memory only"
+msgstr "-n\t\t\tIngen swapfil, bruk bare hukommelsen"
+
+msgid "-r\t\t\tList swap files and exit"
+msgstr "-r\t\t\tList swapfiler og avslutt"
+
+msgid "-r (with file name)\tRecover crashed session"
+msgstr "-r (med filnavn)\tGjenopprett kræsjet økt"
+
+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\tIkke bruk newcli for å åpne vindu"
+
+msgid "-dev <device>\t\tUse <device> for I/O"
+msgstr "-dev <enhet>\t\tBruk <enhet> for I/U"
+
+msgid "-A\t\t\tstart in Arabic mode"
+msgstr "-A\t\t\tStart i arabisk modus"
+
+msgid "-H\t\t\tStart in Hebrew mode"
+msgstr "-H\t\t\tStart i hebraisk modus"
+
+msgid "-F\t\t\tStart in Farsi mode"
+msgstr "-F\t\t\tStart i persisk (Farsi) modus"
+
+msgid "-T <terminal>\tSet terminal type to <terminal>"
+msgstr "-T <terminal>\tSett terminaltypen til <terminal>"
+
+msgid "-u <vimrc>\t\tUse <vimrc> instead of any .vimrc"
+msgstr "-u <vimrc>\t\tBruk <vimrc> istedenfor eventuell .vimrc"
+
+msgid "-U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc"
+msgstr "-U <gvimrc>\t\tBruk <gvimrc> istedenfor eventuell .gvimrc"
+
+msgid "--noplugin\t\tDon't load plugin scripts"
+msgstr "--noplugin\t\tIkke last plugin-skripts"
+
+#, fuzzy
+#~ msgid "-p[N]\t\tOpen N tab pages (default: one for each file)"
+#~ msgstr "-o[N]\t\tÅpne N vinduer (standard: Ett for hver fil)"
+
+msgid "-o[N]\t\tOpen N windows (default: one for each file)"
+msgstr "-o[N]\t\tÅpne N vinduer (standard: Ett for hver fil)"
+
+msgid "-O[N]\t\tLike -o but split vertically"
+msgstr "-O[N]\t\tSom -o men splitt loddrett"
+
+msgid "+\t\t\tStart at end of file"
+msgstr "+\t\t\tStart på slutten av filen"
+
+msgid "+<lnum>\t\tStart at line <lnum>"
+msgstr "+<lnr>\t\tStart på linje <lnr>"
+
+msgid "--cmd <command>\tExecute <command> before loading any vimrc file"
+msgstr "--cmd <kommando>\tKjør <kommando> før lasting av vimrc-filer"
+
+msgid "-c <command>\t\tExecute <command> after loading the first file"
+msgstr "-c <kommando>\tKjør <kommando> etter lasting av første fil"
+
+msgid "-S <session>\t\tSource file <session> after loading the first file"
+msgstr "-S <økt>\t\tKjør filen <økt> etter lasting av første fil"
+
+msgid "-s <scriptin>\tRead Normal mode commands from file <scriptin>"
+msgstr "-s <innskript>\tLes normalmodus-kommandoer fra filen <innskript>"
+
+msgid "-w <scriptout>\tAppend all typed commands to file <scriptout>"
+msgstr "-w <utskript>\tLegg alle skrevne kommandoer til filen <utskript>"
+
+msgid "-W <scriptout>\tWrite all typed commands to file <scriptout>"
+msgstr "-W <utskript>\tSkriv alle skrevne kommandoer til filen <utskript>"
+
+msgid "-x\t\t\tEdit encrypted files"
+msgstr "-x\t\t\tRediger krypterte filer"
+
+msgid "-display <display>\tConnect vim to this particular X-server"
+msgstr "-display <display>\tKoble vim til denne spesielle X-tjeneren"
+
+msgid "-X\t\t\tDo not connect to X server"
+msgstr "-X\t\t\tUnngå oppkobling til X-tjener"
+
+msgid "--remote <files>\tEdit <files> in a Vim server if possible"
+msgstr "--remote <filer>\tRediger <filer> på en Vim-tjener hvis mulig"
+
+msgid "--remote-silent <files> Same, don't complain if there is no server"
+msgstr "--remote-silent <filer> Samme, ikke klag hvis tjeneren mangler"
+
+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 blir redigert"
+
+msgid ""
+"--remote-wait-silent <files> Same, don't complain if there is no server"
+msgstr "--remote-wait-silent <files> Samme, ikke klag hvis tjeneren mangler"
+
+#, fuzzy
+#~ msgid "--remote-tab <files> As --remote but open tab page for each file"
+#~ msgstr ""
+#~ "--remote-wait <filer> Som --remote men vent på filer som blir redigert"
+
+msgid "--remote-send <keys>\tSend <keys> to a Vim server and exit"
+msgstr "--remote-send <nøkler>\tSend <nøkler> til en Vim-tjener og avslutt"
+
+msgid "--remote-expr <expr>\tEvaluate <expr> in a Vim server and print result"
+msgstr ""
+"--remote-expr <uttrykk>\tEvaluer <uttrykk> på en Vim-tjener og skriv "
+"resultatet"
+
+msgid "--serverlist\t\tList available Vim server names and exit"
+msgstr "--serverlist\t\tList navn på tilgjengelige Vim-tjenere og avslutt"
+
+msgid "--servername <name>\tSend to/become the Vim server <name>"
+msgstr "--servername <navn>\tSend til/bli Vim-tjeneren <navn>"
+
+msgid "-i <viminfo>\t\tUse <viminfo> instead of .viminfo"
+msgstr "-i <viminfo>\t\tBruk <viminfo> istedenfor .viminfo"
+
+msgid "-h or --help\tPrint Help (this message) and exit"
+msgstr "-h eller --help\tSkriv hjelpen (denne teksten) og avslutt"
+
+msgid "--version\t\tPrint version information and exit"
+msgstr "--version\t\tSkriv versjonsinformasjon og avslutt"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (Motif version):\n"
+msgstr ""
+"\n"
+"Parametere gjenkjent av gvim (Motif-versjon):\n"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (neXtaw version):\n"
+msgstr ""
+"\n"
+"Parametere gjenkjent av gvim (neXtaw-versjon):\n"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (Athena version):\n"
+msgstr ""
+"\n"
+"Parametere gjenkjent av gvim (Athena-versjon):\n"
+
+msgid "-display <display>\tRun vim on <display>"
+msgstr "-display <display>\tKjør vim på <display>"
+
+msgid "-iconic\t\tStart vim iconified"
+msgstr "-iconic\t\tStart vim som ikon"
+
+msgid "-name <name>\t\tUse resource as if vim was <name>"
+msgstr "-name <navn>\t\tBruk ressurs som om Vim var <navn>"
+
+msgid "\t\t\t (Unimplemented)\n"
+msgstr "\t\t\t (Ikke implementert)\n"
+
+msgid "-background <color>\tUse <color> for the background (also: -bg)"
+msgstr "-background <farge>\tBruk <farge> på bakgrunnen (også: -bg)"
+
+msgid "-foreground <color>\tUse <color> for normal text (also: -fg)"
+msgstr "-foreground <farge>\tBruk <farge> på normal tekst (også: -fg)"
+
+msgid "-font <font>\t\tUse <font> for normal text (also: -fn)"
+msgstr "-font <skrifttype>\t\tBruk <skrifttype> på normal tekst (også: -fn)"
+
+msgid "-boldfont <font>\tUse <font> for bold text"
+msgstr "-boldfont <skrifttype>\tBruk <skrifttype> på fet skrift"
+
+msgid "-italicfont <font>\tUse <font> for italic text"
+msgstr "-italicfont <skrifttype>\tBruk <skrifttype> på skrå tekst"
+
+msgid "-geometry <geom>\tUse <geom> for initial geometry (also: -geom)"
+msgstr ""
+"-geometry <geom>\tBruk <geom> for innledende vindusplassering (også: -geom)"
+
+msgid "-borderwidth <width>\tUse a border width of <width> (also: -bw)"
+msgstr ""
+"-borderwidth <bredde>\tBruk en rammebredde tilsvarende <bredde> (også: -bw)"
+
+msgid "-scrollbarwidth <width> Use a scrollbar width of <width> (also: -sw)"
+msgstr ""
+"-scrollbarwidth <bredde> Bruk en rullefeltbredde tilsvarende <bredde> "
+"(også: -sw)"
+
+msgid "-menuheight <height>\tUse a menu bar height of <height> (also: -mh)"
+msgstr ""
+"-menuheight <høyde>\tBruk en menyblokkhøyde tilsvarende <høyde> (også: -mh)"
+
+msgid "-reverse\t\tUse reverse video (also: -rv)"
+msgstr "-reverse\t\tBruk invers video (også: -rv)"
+
+msgid "+reverse\t\tDon't use reverse video (also: +rv)"
+msgstr "+reverse\t\tIkke bruk invers video (også: +rv)"
+
+msgid "-xrm <resource>\tSet the specified resource"
+msgstr "-xrm <ressurs>\tSett den spesifiserte ressursen"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (RISC OS version):\n"
+msgstr ""
+"\n"
+"Parametere gjenkjent av gvim (RISC OS-versjon):\n"
+
+msgid "--columns <number>\tInitial width of window in columns"
+msgstr "--columns <antall>\tInnledende bredde på vindu i kolonner"
+
+msgid "--rows <number>\tInitial height of window in rows"
+msgstr "--rows <antall>\tInnledende høyde på vindu i rader"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (GTK+ version):\n"
+msgstr ""
+"\n"
+"Parametere gjenkjent av gvim (GTK+-versjon):\n"
+
+msgid "-display <display>\tRun vim on <display> (also: --display)"
+msgstr "-display <display>\tKjør vim på <display> (også: --display)"
+
+msgid "--role <role>\tSet a unique role to identify the main window"
+msgstr "--role <role>\tSett en unik \"role\" for å identifisere hovedvinduet"
+
+msgid "--socketid <xid>\tOpen Vim inside another GTK widget"
+msgstr "--socketid <xid>\tÅpne Vim innenfor et annet GTK-skjermelement"
+
+msgid "-P <parent title>\tOpen Vim inside parent application"
+msgstr "-P <foreldretittel>\tStart Vim innenfor et foreldreprogram"
+
+msgid "No display"
+msgstr "Ingen display"
+
+#. Failed to send, abort.
+msgid ": Send failed.\n"
+msgstr ": Send feilet.\n"
+
+#. Let vim start normally.
+msgid ": Send failed. Trying to execute locally\n"
+msgstr ": Send feilet. Prøver å utføre lokalt\n"
+
+#, c-format
+msgid "%d of %d edited"
+msgstr "%d av %d redigert"
+
+msgid "No display: Send expression failed.\n"
+msgstr "Ingen display: Sending av uttrykk feilet.\n"
+
+msgid ": Send expression failed.\n"
+msgstr ": Sending av uttrykk feilet.\n"
+
+msgid "No marks set"
+msgstr "Ingen merker satt"
+
+#, c-format
+msgid "E283: No marks matching \"%s\""
+msgstr "E283: Ingen merker samsvarer med \"%s\""
+
+#. Highlight title
+msgid ""
+"\n"
+"mark line col file/text"
+msgstr ""
+"\n"
+"merk linje kol fil/tekst"
+
+#. Highlight title
+msgid ""
+"\n"
+" jump line col file/text"
+msgstr ""
+"\n"
+" hopp linje kol fil/tekst"
+
+#. Highlight title
+msgid ""
+"\n"
+"change line col text"
+msgstr ""
+"\n"
+"forand linje kol tekst"
+
+#, c-format
+msgid ""
+"\n"
+"# File marks:\n"
+msgstr ""
+"\n"
+"# Filmerker:\n"
+
+#. Write the jumplist with -'
+#, c-format
+msgid ""
+"\n"
+"# Jumplist (newest first):\n"
+msgstr ""
+"\n"
+"# Hoppliste (nyeste først):\n"
+
+#, c-format
+msgid ""
+"\n"
+"# History of marks within files (newest to oldest):\n"
+msgstr ""
+"\n"
+"# Historie for merker inne i filer (yngst til eldst):\n"
+
+msgid "Missing '>'"
+msgstr "Mangler '>'"
+
+msgid "E543: Not a valid codepage"
+msgstr "E543: Er ikke en gyldig codepage"
+
+msgid "E284: Cannot set IC values"
+msgstr "E284: Kan ikke sette IC-verdier (\"Input Context\")"
+
+msgid "E285: Failed to create input context"
+msgstr "E285: Klarte ikke opprette inndatakontekst"
+
+msgid "E286: Failed to open input method"
+msgstr "E286: Klarte ikke åpne inndatametode"
+
+msgid "E287: Warning: Could not set destroy callback to IM"
+msgstr ""
+"E287: Advarsel: Klarte ikke sette \"destroy callback\" til inndatametode"
+
+msgid "E288: input method doesn't support any style"
+msgstr "E288: Inndatametode støtter ikke enhver stil"
+
+msgid "E289: input method doesn't support my preedit type"
+msgstr "E289: Inndatametode støtter ikke min \"preedit\" type"
+
+msgid "E290: over-the-spot style requires fontset"
+msgstr "E290: \"over-the-spot\"-stil trenger et skrifttypesett"
+
+msgid "E291: Your GTK+ is older than 1.2.3. Status area disabled"
+msgstr "E291: Din GTK+ er eldre enn 1.2.3. Statusområde deaktivert"
+
+msgid "E292: Input Method Server is not running"
+msgstr "E292: Inndatametodetjener kjører ikke"
+
+msgid "E293: block was not locked"
+msgstr "E293: Blokken var ikke låst"
+
+msgid "E294: Seek error in swap file read"
+msgstr "E294: Søkefeil i lesing av swapfil"
+
+msgid "E295: Read error in swap file"
+msgstr "E295: Lesefeil i swapfil"
+
+msgid "E296: Seek error in swap file write"
+msgstr "E296: Søkefeil i skriving til swapfil"
+
+msgid "E297: Write error in swap file"
+msgstr "E297: Skrivefeil i swapfil"
+
+msgid "E300: Swap file already exists (symlink attack?)"
+msgstr "E300: Swapfilen finnes allerede (symlenke-angrep?)"
+
+msgid "E298: Didn't get block nr 0?"
+msgstr "E298: Hentet ikke blokk nummer 0?"
+
+msgid "E298: Didn't get block nr 1?"
+msgstr "E298: Hentet ikke blokk nummer 1?"
+
+msgid "E298: Didn't get block nr 2?"
+msgstr "E298: Hentet ikke blokk nummer 2?"
+
+#. could not (re)open the swap file, what can we do????
+msgid "E301: Oops, lost the swap file!!!"
+msgstr "E301: Opps, mistet swapfilen!!!"
+
+msgid "E302: Could not rename swap file"
+msgstr "E302: Klarte ikke skifte navn på swapfil"
+
+#, c-format
+msgid "E303: Unable to open swap file for \"%s\", recovery impossible"
+msgstr "E303: Klarte ikke åpne swapfil for \"%s\", gjenoppretting umulig"
+
+msgid "E304: ml_upd_block0(): Didn't get block 0??"
+msgstr "E304: ml_upd_block0(): Hentet ikke blokk 0??"
+
+#, c-format
+msgid "E305: No swap file found for %s"
+msgstr "E305: Ingen swapfil funnet for %s"
+
+msgid "Enter number of swap file to use (0 to quit): "
+msgstr "Skriv nummeret på swapfil som skal brukes (0 for å avslutte): "
+
+#, c-format
+msgid "E306: Cannot open %s"
+msgstr "E306: Kan ikke åpne %s"
+
+msgid "Unable to read block 0 from "
+msgstr "Klarte ikke lese blokk 0 fra "
+
+msgid ""
+"\n"
+"Maybe no changes were made or Vim did not update the swap file."
+msgstr ""
+"\n"
+"Det er mulig ingen forandringer ble gjort, eller Vim oppdaterte ikke "
+"swapfilen."
+
+msgid " cannot be used with this version of Vim.\n"
+msgstr " kan ikke brukes med denne Vim-versjonen.\n"
+
+msgid "Use Vim version 3.0.\n"
+msgstr "Bruk Vim versjon 3.0.\n"
+
+#, c-format
+msgid "E307: %s does not look like a Vim swap file"
+msgstr "E307: %s ser ikke ut som en Vim-swapfil"
+
+msgid " cannot be used on this computer.\n"
+msgstr " kan ikke brukes på denne maskinen.\n"
+
+msgid "The file was created on "
+msgstr "Filen ble laget på "
+
+msgid ""
+",\n"
+"or the file has been damaged."
+msgstr ""
+",\n"
+"eller filen er blitt ødelagt."
+
+#, c-format
+msgid "Using swap file \"%s\""
+msgstr "Bruker swapfilen \"%s\""
+
+#, c-format
+msgid "Original file \"%s\""
+msgstr "Originalfil \"%s\""
+
+msgid "E308: Warning: Original file may have been changed"
+msgstr "E308: Advarsel: Originalfilen kan ha blitt forandret"
+
+#, c-format
+msgid "E309: Unable to read block 1 from %s"
+msgstr "E309: Klarte ikke lese blokk 1 fra %s"
+
+msgid "???MANY LINES MISSING"
+msgstr "???MANGE LINJER MANGLER"
+
+msgid "???LINE COUNT WRONG"
+msgstr "???FEIL LINJEANTALL"
+
+msgid "???EMPTY BLOCK"
+msgstr "???TOM BLOKK"
+
+msgid "???LINES MISSING"
+msgstr "???LINJER MANGLER"
+
+#, c-format
+msgid "E310: Block 1 ID wrong (%s not a .swp file?)"
+msgstr "E310: ID til blokk 1 er feil (%s ikke en \".swp\"-fil?)"
+
+msgid "???BLOCK MISSING"
+msgstr "???BLOKK MANGLER"
+
+msgid "??? from here until ???END lines may be messed up"
+msgstr "??? Herfra til ???SLUTT kan linjer være rotet til"
+
+msgid "??? from here until ???END lines may have been inserted/deleted"
+msgstr "??? Herfra til ???SLUTT kan linjer ha blitt lagt til eller slettet"
+
+msgid "???END"
+msgstr "???SLUTT"
+
+msgid "E311: Recovery Interrupted"
+msgstr "E311: Gjenoppretting avbrutt"
+
+msgid ""
+"E312: Errors detected while recovering; look for lines starting with ???"
+msgstr ""
+"E312: Feil oppdaget under gjenoppretting; se etter linjer som starter med ???"
+
+msgid "See \":help E312\" for more information."
+msgstr "Se \":help E312\" for mer informasjon."
+
+msgid "Recovery completed. You should check if everything is OK."
+msgstr "Gjenoppretting komplett. Du bør sjekke at alt er i orden."
+
+msgid ""
+"\n"
+"(You might want to write out this file under another name\n"
+msgstr ""
+"\n"
+"(Du vil kanskje lagre denne filen under et annet navn\n"
+
+msgid "and run diff with the original file to check for changes)\n"
+msgstr "og sammenligne den mot den originale filen for å finne forandringer)\n"
+
+msgid ""
+"Delete the .swp file afterwards.\n"
+"\n"
+msgstr ""
+"Slett \".swp\"-filen etterpå.\n"
+"\n"
+
+#. use msg() to start the scrolling properly
+msgid "Swap files found:"
+msgstr "Swapfiler funnet:"
+
+msgid " In current directory:\n"
+msgstr " I nåværende katalog:\n"
+
+msgid " Using specified name:\n"
+msgstr " Bruker spesifisert navn:\n"
+
+msgid " In directory "
+msgstr " I katalog "
+
+msgid " -- none --\n"
+msgstr " -- ingen --\n"
+
+msgid " owned by: "
+msgstr " eies av: "
+
+msgid " dated: "
+msgstr " datert: "
+
+msgid " dated: "
+msgstr " datert: "
+
+msgid " [from Vim version 3.0]"
+msgstr " [fra Vim versjon 3.0]"
+
+msgid " [does not look like a Vim swap file]"
+msgstr " [ser ikke ut som en Vim-swapfil]"
+
+msgid " file name: "
+msgstr " filnavn: "
+
+msgid ""
+"\n"
+" modified: "
+msgstr ""
+"\n"
+" modifisert: "
+
+msgid "YES"
+msgstr "JA"
+
+msgid "no"
+msgstr "nei"
+
+msgid ""
+"\n"
+" user name: "
+msgstr ""
+"\n"
+" brukernavn: "
+
+msgid " host name: "
+msgstr " vertsnavn: "
+
+msgid ""
+"\n"
+" host name: "
+msgstr ""
+"\n"
+" vertsnavn: "
+
+msgid ""
+"\n"
+" process ID: "
+msgstr ""
+"\n"
+" prosess-ID: "
+
+msgid " (still running)"
+msgstr " (kjører fortsatt)"
+
+msgid ""
+"\n"
+" [not usable with this version of Vim]"
+msgstr ""
+"\n"
+" [ikke brukbar med denne Vim-versjonen]"
+
+msgid ""
+"\n"
+" [not usable on this computer]"
+msgstr ""
+"\n"
+" [ikke brukbar på denne maskinen]"
+
+msgid " [cannot be read]"
+msgstr " [kan ikke leses]"
+
+msgid " [cannot be opened]"
+msgstr " [kan ikke åpnes]"
+
+msgid "E313: Cannot preserve, there is no swap file"
+msgstr "E313: Kan ikke bevare, swapfil mangler"
+
+msgid "File preserved"
+msgstr "Fil bevart"
+
+msgid "E314: Preserve failed"
+msgstr "E314: Bevaring feilet"
+
+#, 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 finne linje %ld"
+
+msgid "E317: pointer block id wrong 3"
+msgstr "E317: Pekerblokk-id feil 3"
+
+msgid "stack_idx should be 0"
+msgstr "stack_idx skulle være 0"
+
+msgid "E318: Updated too many blocks?"
+msgstr "E318: Oppdaterte for mange blokker?"
+
+msgid "E317: pointer block id wrong 4"
+msgstr "E317: Pekerblokk-id feil 4"
+
+msgid "deleted block 1?"
+msgstr "slettet blokk 1?"
+
+#, c-format
+msgid "E320: Cannot find line %ld"
+msgstr "E320: Kan ikke finne linje %ld"
+
+msgid "E317: pointer block id wrong"
+msgstr "E317: Pekerblokk-id feil"
+
+msgid "pe_line_count is zero"
+msgstr "pe_line_count er null"
+
+#, c-format
+msgid "E322: line number out of range: %ld past the end"
+msgstr "E322: Linjenummer utenfor område: %ld forbi slutten"
+
+#, c-format
+msgid "E323: line count wrong in block %ld"
+msgstr "E323: Linjeantall feil i blokk %ld"
+
+msgid "Stack size increases"
+msgstr "Stackstørrelse øker"
+
+msgid "E317: pointer block id wrong 2"
+msgstr "E317: Pekerblokk-id feil 2"
+
+#, c-format
+msgid "E773: Symlink loop for \"%s\""
+msgstr "E773: Symlenkesløyfe for \"%s\""
+
+msgid "E325: ATTENTION"
+msgstr "E325: VIKTIG"
+
+msgid ""
+"\n"
+"Found a swap file by the name \""
+msgstr ""
+"\n"
+"Fant en swapfil ved navn \""
+
+msgid "While opening file \""
+msgstr "Under åpning av filen \""
+
+msgid " NEWER than swap file!\n"
+msgstr " NYERE enn swapfil!\n"
+
+#. Some of these messages are long to allow translation to
+#. * other languages.
+msgid ""
+"\n"
+"(1) Another program may be editing the same file.\n"
+" If this is the case, be careful not to end up with two\n"
+" different instances of the same file when making changes.\n"
+msgstr ""
+"\n"
+"(1) Det er mulig et annet program redigerer den samme filen.\n"
+" Hvis det er tilfelle, vær forsiktig så du ikke ender opp med to\n"
+" forskjellige utgaver av den samme filen når du gjør forandringer.\n"
+
+msgid " Quit, or continue with caution.\n"
+msgstr " Avslutt, eller fortsett med varsomhet.\n"
+
+msgid ""
+"\n"
+"(2) An edit session for this file crashed.\n"
+msgstr ""
+"\n"
+"(2) En økt for denne filen kræsjet.\n"
+
+msgid " If this is the case, use \":recover\" or \"vim -r "
+msgstr " Hvis det er tilfelle, bruk \":recover\" eller \"vim -r "
+
+msgid ""
+"\"\n"
+" to recover the changes (see \":help recovery\").\n"
+msgstr ""
+"\"\n"
+" for å gjenopprette forandringene (se \":help recovery\").\n"
+
+msgid " If you did this already, delete the swap file \""
+msgstr " Hvis du har gjort dette allerede, slett swapfilen \""
+
+msgid ""
+"\"\n"
+" to avoid this message.\n"
+msgstr ""
+"\"\n"
+" for å unngå denne meldingen.\n"
+
+msgid "Swap file \""
+msgstr "Swapfilen \""
+
+msgid "\" already exists!"
+msgstr "\" finnes allerede!"
+
+msgid "VIM - ATTENTION"
+msgstr "VIM - VIKTIG"
+
+msgid "Swap file already exists!"
+msgstr "Swapfilen eksisterer allerede!"
+
+msgid ""
+"&Open Read-Only\n"
+"&Edit anyway\n"
+"&Recover\n"
+"&Quit\n"
+"&Abort"
+msgstr ""
+"&Åpne skrivebeskyttet\n"
+"&Rediger likevel\n"
+"&Gjenopprett\n"
+"&Avslutt\n"
+"Av&bryt"
+
+msgid ""
+"&Open Read-Only\n"
+"&Edit anyway\n"
+"&Recover\n"
+"&Delete it\n"
+"&Quit\n"
+"&Abort"
+msgstr ""
+"&Åpne skrivebeskyttet\n"
+"&Rediger likevel\n"
+"&Gjenopprett\n"
+"&Slett den\n"
+"&Avslutt\n"
+"Av&bryt"
+
+msgid "E326: Too many swap files found"
+msgstr "E326: For mange swapfiler funnet"
+
+msgid "E327: Part of menu-item path is not sub-menu"
+msgstr "E327: Del av menyelement er ikke undermeny"
+
+msgid "E328: Menu only exists in another mode"
+msgstr "E328: Menyen eksisterer bare i en annen modus"
+
+#, c-format
+msgid "E329: No menu \"%s\""
+msgstr "E329: Ingen \"%s\"-meny"
+
+#. Only a mnemonic or accelerator is not valid.
+msgid "E792: Empty menu name"
+msgstr "E792: Tomt menynavn"
+
+msgid "E330: Menu path must not lead to a sub-menu"
+msgstr "E330: Menysti kan ikke lede til en undermeny"
+
+msgid "E331: Must not add menu items directly to menu bar"
+msgstr "E331: Kan ikke legge til menyelementer direkte på menylinjen"
+
+msgid "E332: Separator cannot be part of a menu path"
+msgstr "E332: Skilletegn kan ikke være del av en menysti"
+
+#. Now we have found the matching menu, and we list the mappings
+#. Highlight title
+msgid ""
+"\n"
+"--- Menus ---"
+msgstr ""
+"\n"
+"--- Menyer ---"
+
+msgid "Tear off this menu"
+msgstr "Riv av denne menyen"
+
+msgid "E333: Menu path must lead to a menu item"
+msgstr "E333: Menystien må lede til et menyvalg"
+
+#, c-format
+msgid "E334: Menu not found: %s"
+msgstr "E334: Fant ikke menyen: %s"
+
+#, c-format
+msgid "E335: Menu not defined for %s mode"
+msgstr "E335: Menyen er ikke definert for %s-modus"
+
+msgid "E336: Menu path must lead to a sub-menu"
+msgstr "E336: Menystien må lede til en undermeny"
+
+msgid "E337: Menu not found - check menu names"
+msgstr "E337: Fant ikke menyen - sjekk menynavnet"
+
+#, c-format
+msgid "Error detected while processing %s:"
+msgstr "Feil oppdaget under prosessering av %s:"
+
+#, c-format
+msgid "line %4ld:"
+msgstr "linje %4ld:"
+
+#, c-format
+msgid "E354: Invalid register name: '%s'"
+msgstr "E354: Ugyldig registernavn: '%s'"
+
+msgid "Messages maintainer: Bram Moolenaar <Bram@vim.org>"
+msgstr ""
+"Vedlikeholder for norsk oversettelse: Øyvind A. Holm <sunny@sunbase.org>"
+
+msgid "Interrupt: "
+msgstr "Avbryt: "
+
+msgid "Press ENTER or type command to continue"
+msgstr "Trykk ENTER eller skriv kommando for å fortsette"
+
+#, c-format
+msgid "%s line %ld"
+msgstr "%s linje %ld"
+
+msgid "-- More --"
+msgstr "-- Mer --"
+
+msgid " SPACE/d/j: screen/page/line down, b/u/k: up, q: quit "
+msgstr " MELLOMROM/d/j: Skjerm/side/linje ned, b/u/k: Opp, q: Avslutt "
+
+msgid "Question"
+msgstr "Spørsmål"
+
+msgid ""
+"&Yes\n"
+"&No"
+msgstr ""
+"&Ja\n"
+"&Nei"
+
+msgid ""
+"&Yes\n"
+"&No\n"
+"Save &All\n"
+"&Discard All\n"
+"&Cancel"
+msgstr ""
+"&Ja\n"
+"&Nei\n"
+"&Lagre alle\n"
+"&Forkast alle\n"
+"&Avbryt"
+
+msgid "Select Directory dialog"
+msgstr "\"Velge katalog\"-dialogvindu"
+
+msgid "Save File dialog"
+msgstr "\"Lagre fil\"-dialogvindu"
+
+msgid "Open File dialog"
+msgstr "\"Åpne fil\"-dialogvindu"
+
+#. TODO: non-GUI file selector here
+msgid "E338: Sorry, no file browser in console mode"
+msgstr "E338: Dessverre ingen filbehandler i konsollmodus"
+
+msgid "E766: Insufficient arguments for printf()"
+msgstr "E766: Ikke nok parametre for printf()"
+
+msgid "E767: Too many arguments to printf()"
+msgstr "E767: For mange parametere for printf()"
+
+msgid "W10: Warning: Changing a readonly file"
+msgstr "W10: Advarsel: Forandrer en skrivebeskyttet fil"
+
+msgid "Type number or click with mouse (<Enter> cancels): "
+msgstr "Skriv nummer eller velg med musen (<Enter> avbryter)"
+
+msgid "Choice number (<Enter> cancels): "
+msgstr "Valgnummer (<Enter> avbryter)"
+
+msgid "1 more line"
+msgstr "1 linje lagt til"
+
+msgid "1 line less"
+msgstr "1 linje fjernet"
+
+#, c-format
+msgid "%ld more lines"
+msgstr "%ld linjer lagt til"
+
+#, c-format
+msgid "%ld fewer lines"
+msgstr "%ld linjer fjernet"
+
+msgid " (Interrupted)"
+msgstr " (Avbrutt)"
+
+msgid "Beep!"
+msgstr "Pip!"
+
+msgid "Vim: preserving files...\n"
+msgstr "Vim: Bevarer filer ...\n"
+
+#. close all memfiles, without deleting
+msgid "Vim: Finished.\n"
+msgstr "Vim: Ferdig.\n"
+
+#, c-format
+msgid "ERROR: "
+msgstr "FEIL: "
+
+#, c-format
+msgid ""
+"\n"
+"[bytes] total alloc-freed %lu-%lu, in use %lu, peak use %lu\n"
+msgstr ""
+"\n"
+"[bytes] totalt alloc-frigjort %lu-%lu, i bruk %lu, topp-bruk %lu\n"
+
+#, c-format
+msgid ""
+"[calls] total re/malloc()'s %lu, total free()'s %lu\n"
+"\n"
+msgstr ""
+"[kall] totale \"re/malloc()\"-er %lu, totale \"free()\"-er %lu\n"
+"\n"
+
+msgid "E340: Line is becoming too long"
+msgstr "E340: Linjen blir for lang"
+
+#, c-format
+msgid "E341: Internal error: lalloc(%ld, )"
+msgstr "E341: Intern feil: lalloc(%ld, )"
+
+#, c-format
+msgid "E342: Out of memory! (allocating %lu bytes)"
+msgstr "E342: Ikke mer ledig hukommelse! (Reserverer %lu bytes)"
+
+#, c-format
+msgid "Calling shell to execute: \"%s\""
+msgstr "Kaller skall for å utføre \"%s\""
+
+msgid "E545: Missing colon"
+msgstr "E545: Mangler kolon"
+
+msgid "E546: Illegal mode"
+msgstr "E546: Ulovlig modus"
+
+msgid "E547: Illegal mouseshape"
+msgstr "E547: Ulovlig utseende på musepekeren"
+
+msgid "E548: digit expected"
+msgstr "E548: Siffer forventet"
+
+msgid "E549: Illegal percentage"
+msgstr "E549: Ulovlig prosent"
+
+msgid "Enter encryption key: "
+msgstr "Skriv krypteringsnøkkel: "
+
+msgid "Enter same key again: "
+msgstr "Gjenta krypteringsnøkkelen: "
+
+msgid "Keys don't match!"
+msgstr "Krypteringsnøklene stemmer ikke overens!"
+
+#, 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]' må være på slutten av stien eller bli "
+"etterfulgt av '%s'."
+
+#, c-format
+msgid "E344: Can't find directory \"%s\" in cdpath"
+msgstr "E344: Kan ikke finne katalogen \"%s\" i \"cdpath\""
+
+#, c-format
+msgid "E345: Can't find file \"%s\" in path"
+msgstr "E345: Kan ikke finne filen \"%s\" i stien"
+
+#, c-format
+msgid "E346: No more directory \"%s\" found in cdpath"
+msgstr "E346: Ingen flere katalog-\"%s\" funnet i \"cdpath\""
+
+#, c-format
+msgid "E347: No more file \"%s\" found in path"
+msgstr "E347: Ingen flere fil-\"%s\" funnet i stien"
+
+#. Get here when the server can't be found.
+msgid "Cannot connect to Netbeans #2"
+msgstr "Kan ikke koble til Netbeans #2"
+
+msgid "Cannot connect to Netbeans"
+msgstr "Kan ikke koble til Netbeans"
+
+#, c-format
+msgid "E668: Wrong access mode for NetBeans connection info file: \"%s\""
+msgstr ""
+"E668: Feil tilgangsmodus for infofilen til NetBeans-forbindelse: \"%s\""
+
+msgid "read from Netbeans socket"
+msgstr "les fra Netbeans-socket"
+
+#, c-format
+msgid "E658: NetBeans connection lost for buffer %ld"
+msgstr "E658: Mistet NetBeans-forbindelse for buffer %ld"
+
+msgid "E505: "
+msgstr "E505: "
+
+msgid "E774: 'operatorfunc' is empty"
+msgstr "E774: 'operatorfunc' er tomt"
+
+msgid "E775: Eval feature not available"
+msgstr "E775: Eval-funksjonaliteten er ikke tilgjengelig"
+
+msgid "Warning: terminal cannot highlight"
+msgstr "Advarsel: Terminalen kan ikke utheve"
+
+msgid "E348: No string under cursor"
+msgstr "E348: Ingen streng under markør"
+
+msgid "E349: No identifier under cursor"
+msgstr "E349: Ingen identifikator under markør"
+
+msgid "E352: Cannot erase folds with current 'foldmethod'"
+msgstr "E352: Kan ikke slette folder med nåværende 'foldmethod'"
+
+msgid "E664: changelist is empty"
+msgstr "E664: Forandringslisten er tom"
+
+msgid "E662: At start of changelist"
+msgstr "E662: Ved starten av forandringsliste"
+
+msgid "E663: At end of changelist"
+msgstr "E663: Ved slutten av forandringsliste"
+
+msgid "Type :quit<Enter> to exit Vim"
+msgstr "Skriv :quit<Enter> for å avslutte Vim"
+
+#, c-format
+msgid "1 line %sed 1 time"
+msgstr "1 linje \"%s\"-et 1 gang"
+
+#, c-format
+msgid "1 line %sed %d times"
+msgstr "1 linje \"%s\"-et %d ganger"
+
+#, c-format
+msgid "%ld lines %sed 1 time"
+msgstr "%ld linjer \"%s\"-et 1 gang"
+
+#, c-format
+msgid "%ld lines %sed %d times"
+msgstr "%ld linjer \"%s\"-et %d ganger"
+
+#, c-format
+msgid "%ld lines to indent... "
+msgstr "%ld linjer å rykke inn ... "
+
+msgid "1 line indented "
+msgstr "1 linje rykket inn "
+
+#, c-format
+msgid "%ld lines indented "
+msgstr "%ld linjer rykket inn "
+
+msgid "E748: No previously used register"
+msgstr "E748: Register ikke tidligere brukt"
+
+#. must display the prompt
+msgid "cannot yank; delete anyway"
+msgstr "kan ikke kopiere til utklippstavle; slett likevel"
+
+msgid "1 line changed"
+msgstr "1 linje forandret"
+
+#, c-format
+msgid "%ld lines changed"
+msgstr "%ld linjer forandret"
+
+#, c-format
+msgid "freeing %ld lines"
+msgstr "frigjør %ld linjer"
+
+msgid "block of 1 line yanked"
+msgstr "blokk med 1 linje kopiert til utklippstavlen"
+
+msgid "1 line yanked"
+msgstr "1 linje kopiert til utklippstavlen"
+
+#, c-format
+msgid "block of %ld lines yanked"
+msgstr "blokk med %ld linjer kopiert til utklippstavlen"
+
+#, c-format
+msgid "%ld lines yanked"
+msgstr "%ld linjer kopiert til utklippstavlen"
+
+#, c-format
+msgid "E353: Nothing in register %s"
+msgstr "E353: Ingenting i register %s"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Registers ---"
+msgstr ""
+"\n"
+"--- Registere ---"
+
+msgid "Illegal register name"
+msgstr "Ulovlig registernavn"
+
+#, c-format
+msgid ""
+"\n"
+"# Registers:\n"
+msgstr ""
+"\n"
+"# Registere:\n"
+
+#, c-format
+msgid "E574: Unknown register type %d"
+msgstr "E574: Ukjent registertype %d"
+
+#, c-format
+msgid "%ld Cols; "
+msgstr "%ld Kol; "
+
+#, c-format
+msgid "Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Bytes"
+msgstr "Valgte %s%ld av %ld linjer; %ld av %ld ord; %ld av %ld bytes"
+
+#, c-format
+msgid ""
+"Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Chars; %ld of %ld "
+"Bytes"
+msgstr ""
+"Valgte %s%ld av %ld linjer; %ld av %ld ord; %ld av %ld tegn; %ld av %ld bytes"
+
+#, c-format
+msgid "Col %s of %s; Line %ld of %ld; Word %ld of %ld; Byte %ld of %ld"
+msgstr "Kol %s av %s; Linje %ld av %ld; Ord %ld av %ld; Byte %ld av %ld"
+
+#, c-format
+msgid ""
+"Col %s of %s; Line %ld of %ld; Word %ld of %ld; Char %ld of %ld; Byte %ld of "
+"%ld"
+msgstr ""
+"Kol %s av %s; linje %ld av %ld; ord %ld av %ld; tegn %ld av %ld; byte %ld av "
+"%ld"
+
+#, c-format
+msgid "(+%ld for BOM)"
+msgstr "(+%ld for BOM)"
+
+msgid "%<%f%h%m%=Page %N"
+msgstr "%<%f%h%m%=Side %N"
+
+msgid "Thanks for flying Vim"
+msgstr "Takk for at du fløy Vim"
+
+msgid "E518: Unknown option"
+msgstr "E518: Ukjent valg"
+
+msgid "E519: Option not supported"
+msgstr "E519: Valget er ikke støttet"
+
+msgid "E520: Not allowed in a modeline"
+msgstr "E520: Ikke tillatt i moduslinje"
+
+msgid "E521: Number required after ="
+msgstr "E521: Nummer nødvendig etter ="
+
+msgid "E522: Not found in termcap"
+msgstr "E522: Ikke funnet i termcap"
+
+#, c-format
+msgid "E539: Illegal character <%s>"
+msgstr "E539: Ulovlig tegn <%s>"
+
+msgid "E529: Cannot set 'term' to empty string"
+msgstr "E529: Kan ikke sette 'term' til tom streng"
+
+msgid "E530: Cannot change term in GUI"
+msgstr "E530: Kan ikke forandre \"term\" i grafisk brukergrensesnitt"
+
+msgid "E531: Use \":gui\" to start the GUI"
+msgstr "E531: Bruk \":gui\" for å starte med grafisk brukergrensesnitt"
+
+msgid "E589: 'backupext' and 'patchmode' are equal"
+msgstr "E589: 'backupext' og 'patchmode' er like"
+
+msgid "E617: Cannot be changed in the GTK+ 2 GUI"
+msgstr "E617: Kan ikke forandres i GTK+ 2 GUI"
+
+msgid "E524: Missing colon"
+msgstr "E524: Mangler kolon"
+
+msgid "E525: Zero length string"
+msgstr "E525: Tom streng"
+
+#, c-format
+msgid "E526: Missing number after <%s>"
+msgstr "E526: Mangler nummer etter <%s>"
+
+msgid "E527: Missing comma"
+msgstr "E527: Mangler komma"
+
+msgid "E528: Must specify a ' value"
+msgstr "E528: Må spesifisere en \"'\"-verdi"
+
+msgid "E595: contains unprintable or wide character"
+msgstr "E595: Inneholder uskrivelige eller brede tegn"
+
+msgid "E596: Invalid font(s)"
+msgstr "E596: Ugyldig(e) skrifttype(r)"
+
+msgid "E597: can't select fontset"
+msgstr "E597: Kan ikke velge skrifttypesett"
+
+msgid "E598: Invalid fontset"
+msgstr "E598: Ugyldig skrifttypesett"
+
+msgid "E533: can't select wide font"
+msgstr "E533: Kan ikke velge bred skrifttype"
+
+msgid "E534: Invalid wide font"
+msgstr "E534: Ugyldig bred skrifttype"
+
+#, c-format
+msgid "E535: Illegal character after <%c>"
+msgstr "E535: Ulovlig tegn etter <%c>"
+
+msgid "E536: comma required"
+msgstr "E536: Komma nødvendig"
+
+#, c-format
+msgid "E537: 'commentstring' must be empty or contain %s"
+msgstr "E537: 'commentstring' må være tom eller inneholde %s"
+
+msgid "E538: No mouse support"
+msgstr "E538: Ingen støtte for mus"
+
+msgid "E540: Unclosed expression sequence"
+msgstr "E540: Uttrykkssekvens som ikke er lukket"
+
+msgid "E541: too many items"
+msgstr "E541: For mange elementer"
+
+msgid "E542: unbalanced groups"
+msgstr "E542: Ubalanserte grupper"
+
+msgid "E590: A preview window already exists"
+msgstr "E590: Det finnes allerede et forhåndsvisningsvindu"
+
+msgid "W17: Arabic requires UTF-8, do ':set encoding=utf-8'"
+msgstr "W17: Arabisk trenger UTF-8, utfør ':set encoding=utf-8'"
+
+#, c-format
+msgid "E593: Need at least %d lines"
+msgstr "E593: Trenger minst %d linjer"
+
+#, c-format
+msgid "E594: Need at least %d columns"
+msgstr "E594: Trenger minst %d kolonner"
+
+#, c-format
+msgid "E355: Unknown option: %s"
+msgstr "E355: Ukjent valg: %s"
+
+msgid ""
+"\n"
+"--- Terminal codes ---"
+msgstr ""
+"\n"
+"--- Terminalkoder ---"
+
+msgid ""
+"\n"
+"--- Global option values ---"
+msgstr ""
+"\n"
+"--- Globale valgverdier ---"
+
+msgid ""
+"\n"
+"--- Local option values ---"
+msgstr ""
+"\n"
+"--- Lokale valgverdier ---"
+
+msgid ""
+"\n"
+"--- Options ---"
+msgstr ""
+"\n"
+"--- Valg ---"
+
+msgid "E356: get_varp ERROR"
+msgstr "E356: \"get_varp\"-FEIL"
+
+#, c-format
+msgid "E357: 'langmap': Matching character missing for %s"
+msgstr "E357: 'langmap': Samsvarende tegn mangler for %s"
+
+#, c-format
+msgid "E358: 'langmap': Extra characters after semicolon: %s"
+msgstr "E358: 'langmap': Ekstra tegn etter semikolon: %s"
+
+msgid "cannot open "
+msgstr "kan ikke åpne "
+
+msgid "VIM: Can't open window!\n"
+msgstr "VIM: Kan ikke åpne vindu!\n"
+
+msgid "Need Amigados version 2.04 or later\n"
+msgstr "Trenger Amigados versjon 2.04 eller nyere\n"
+
+#, c-format
+msgid "Need %s version %ld\n"
+msgstr "Trenger %s versjon %ld\n"
+
+msgid "Cannot open NIL:\n"
+msgstr "Kan ikke åpne NIL:\n"
+
+msgid "Cannot create "
+msgstr "Kan ikke opprette "
+
+#, c-format
+msgid "Vim exiting with %d\n"
+msgstr "Vim avslutter med %d\n"
+
+msgid "cannot change console mode ?!\n"
+msgstr "kan ikke forandre konsollmodus ?!\n"
+
+msgid "mch_get_shellsize: not a console??\n"
+msgstr "mch_get_shellsize: Ikke et konsoll??\n"
+
+#. if Vim opened a window: Executing a shell may cause crashes
+msgid "E360: Cannot execute shell with -f option"
+msgstr "E360: Kan ikke kjøre skall med \"-f\"-valg"
+
+msgid "Cannot execute "
+msgstr "Kan ikke utføre "
+
+msgid "shell "
+msgstr "skall "
+
+msgid " returned\n"
+msgstr " returnerte\n"
+
+msgid "ANCHOR_BUF_SIZE too small."
+msgstr "ANCHOR_BUF_SIZE for liten."
+
+msgid "I/O ERROR"
+msgstr "I/U-FEIL"
+
+msgid "Message"
+msgstr "Melding"
+
+msgid "'columns' is not 80, cannot execute external commands"
+msgstr "'columns' er ikke 80, kan ikke utføre eksterne kommandoer"
+
+msgid "E237: Printer selection failed"
+msgstr "E237: Valg av skriver feilet"
+
+#, c-format
+msgid "to %s on %s"
+msgstr "til %s på %s"
+
+#, c-format
+msgid "E613: Unknown printer font: %s"
+msgstr "E613: Ukjent skrifttype for skriver: %s"
+
+#, c-format
+msgid "E238: Print error: %s"
+msgstr "E238: Feil under utskrift: %s"
+
+#, c-format
+msgid "Printing '%s'"
+msgstr "Skriver ut '%s'"
+
+#, c-format
+msgid "E244: Illegal charset name \"%s\" in font name \"%s\""
+msgstr "E244: Ulovlig navn på tegnsett \"%s\" i skrifttypenavn \"%s\""
+
+#, c-format
+msgid "E245: Illegal char '%c' in font name \"%s\""
+msgstr "E245: Ulovlig tegn '%c' i skrifttypenavn \"%s\""
+
+msgid "Vim: Double signal, exiting\n"
+msgstr "Vim: Dobbelt signal, avslutter\n"
+
+#, c-format
+msgid "Vim: Caught deadly signal %s\n"
+msgstr "Vim: Mottok dødelig signal %s\n"
+
+#, c-format
+msgid "Vim: Caught deadly signal\n"
+msgstr "Vim: Mottok dødelig signal\n"
+
+#, c-format
+msgid "Opening the X display took %ld msec"
+msgstr "Åpning av X-display tok %ld millisekunder"
+
+msgid ""
+"\n"
+"Vim: Got X error\n"
+msgstr ""
+"\n"
+"Vim: Mottok X-feil\n"
+
+msgid "Testing the X display failed"
+msgstr "Test av X-display feilet"
+
+msgid "Opening the X display timed out"
+msgstr "Tidsavbrudd for åpning av X-display"
+
+msgid ""
+"\n"
+"Cannot execute shell "
+msgstr ""
+"\n"
+"Kan ikke kjøre skall "
+
+msgid ""
+"\n"
+"Cannot execute shell sh\n"
+msgstr ""
+"\n"
+"Kan ikke kjøre skallet sh\n"
+
+msgid ""
+"\n"
+"shell returned "
+msgstr ""
+"\n"
+"skallet returnerte "
+
+msgid ""
+"\n"
+"Cannot create pipes\n"
+msgstr ""
+"\n"
+"Kan ikke opprette rør (\"pipe\")\n"
+
+msgid ""
+"\n"
+"Cannot fork\n"
+msgstr ""
+"\n"
+"Kan ikke opprette tvillingprosess (\"fork\")\n"
+
+msgid ""
+"\n"
+"Command terminated\n"
+msgstr ""
+"\n"
+"Kommando avsluttet\n"
+
+msgid "XSMP lost ICE connection"
+msgstr "XSMP mistet ICE-forbindelsen"
+
+#, c-format
+msgid "dlerror = \"%s\""
+msgstr "dlerror = \"%s\""
+
+msgid "Opening the X display failed"
+msgstr "Åpning av X-display feilet"
+
+msgid "XSMP handling save-yourself request"
+msgstr "XSMP håndterer \"redd-deg-selv\"-forespørsel"
+
+msgid "XSMP opening connection"
+msgstr "XSMP åpner forbindelse"
+
+msgid "XSMP ICE connection watch failed"
+msgstr "Overvåkning av XSMP ICE-forbindelse feilet"
+
+#, c-format
+msgid "XSMP SmcOpenConnection failed: %s"
+msgstr "XSMP SmcOpenConnection feilet: %s"
+
+msgid "At line"
+msgstr "På linje"
+
+msgid "Could not load vim32.dll!"
+msgstr "Klarte ikke laste vim32.dll!"
+
+msgid "VIM Error"
+msgstr "VIM-feil"
+
+msgid "Could not fix up function pointers to the DLL!"
+msgstr "Klarte ikke ordne opp i funksjonspekere til DLL-en!"
+
+#, c-format
+msgid "shell returned %d"
+msgstr "skallet returnerte %d"
+
+#, c-format
+msgid "Vim: Caught %s event\n"
+msgstr "Vim: Mottok \"%s\"-hendelse\n"
+
+msgid "close"
+msgstr "lukk"
+
+msgid "logoff"
+msgstr "logg av"
+
+msgid "shutdown"
+msgstr "kjør ned"
+
+msgid "E371: Command not found"
+msgstr "E371: Kommando ikke funnet"
+
+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 funnet i $PATH.\n"
+"Eksterne kommandoer kommer ikke til å vente etter fullføring.\n"
+"Se \":help win32-vimrun\" for mer informasjon."
+
+msgid "Vim Warning"
+msgstr "Vim-advarsel"
+
+#, c-format
+msgid "E372: Too many %%%c in format string"
+msgstr "E372: For mange %%%c i formatstreng"
+
+#, c-format
+msgid "E373: Unexpected %%%c in format string"
+msgstr "E373: Uventet %%%c i formatstreng"
+
+msgid "E374: Missing ] in format string"
+msgstr "E374: Mangler ] i formatstreng"
+
+#, c-format
+msgid "E375: Unsupported %%%c in format string"
+msgstr "E375: %%%c ikke støttet i formatstreng"
+
+#, c-format
+msgid "E376: Invalid %%%c in format string prefix"
+msgstr "E376: Ugyldig %%%c i formatstreng-prefiks"
+
+#, c-format
+msgid "E377: Invalid %%%c in format string"
+msgstr "E377: Ugyldig %%%c i formatstreng"
+
+msgid "E378: 'errorformat' contains no pattern"
+msgstr "E378: 'errorformat' inneholder ikke søkestreng"
+
+msgid "E379: Missing or empty directory name"
+msgstr "E379: Manglende eller tomt katalognavn"
+
+msgid "E553: No more items"
+msgstr "E553: Ingen flere elementer"
+
+#, c-format
+msgid "(%d of %d)%s%s: "
+msgstr "(%d av %d)%s%s: "
+
+msgid " (line deleted)"
+msgstr " (linjen slettet)"
+
+msgid "E380: At bottom of quickfix stack"
+msgstr "E380: På bunnen av quickfix-stack"
+
+msgid "E381: At top of quickfix stack"
+msgstr "E381: På toppen av quickfix-stack"
+
+#, c-format
+msgid "error list %d of %d; %d errors"
+msgstr "feilliste %d av %d; %d feil"
+
+msgid "E382: Cannot write, 'buftype' option is set"
+msgstr "E382: Kan ikke lagre, 'buftype'-valget er satt"
+
+msgid "E683: File name missing or invalid pattern"
+msgstr "E683: Filnavn mangler eller ugyldig søkestreng"
+
+#, c-format
+msgid "Cannot open file \"%s\""
+msgstr "Kan ikke åpne filen \"%s\""
+
+msgid "E681: Buffer is not loaded"
+msgstr "E681: Bufferen er ikke lastet"
+
+msgid "E777: String or List expected"
+msgstr "E777: Streng eller liste forventet"
+
+#, c-format
+msgid "E369: invalid item in %s%%[]"
+msgstr "E369: Ugyldig element i %s%%[]"
+
+msgid "E339: Pattern too long"
+msgstr "E339: Søkestrengen er for lang"
+
+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: Usamsvarende \\z("
+
+#, c-format
+msgid "E53: Unmatched %s%%("
+msgstr "E53: Usamsvarende %s%%("
+
+#, c-format
+msgid "E54: Unmatched %s("
+msgstr "E54: Usamsvarende %s("
+
+#, c-format
+msgid "E55: Unmatched %s)"
+msgstr "E55: Usamsvarende %s)"
+
+#, c-format
+msgid "E59: invalid character after %s@"
+msgstr "E59: Ugyldig tegn etter %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: Nøstede %s*"
+
+#, c-format
+msgid "E62: Nested %s%c"
+msgstr "E62: Nøstede %s%c"
+
+msgid "E63: invalid use of \\_"
+msgstr "E63: Ugyldig bruk av \\_"
+
+#, c-format
+msgid "E64: %s%c follows nothing"
+msgstr "E64: %s%c etterfølger ingenting"
+
+msgid "E65: Illegal back reference"
+msgstr "E65: Ulovlig tilbakereferanse"
+
+msgid "E66: \\z( not allowed here"
+msgstr "E66: \\z( ikke tillatt her"
+
+msgid "E67: \\z1 et al. not allowed here"
+msgstr "E67: \\z1 med venner er ikke tillatt her"
+
+msgid "E68: Invalid character after \\z"
+msgstr "E68: Ugyldig tegn etter \\z"
+
+#, c-format
+msgid "E69: Missing ] after %s%%["
+msgstr "E69: Mangler ] etter %s%%["
+
+#, c-format
+msgid "E70: Empty %s%%[]"
+msgstr "E70: Tom %s%%[]"
+
+#, c-format
+msgid "E678: Invalid character after %s%%[dxouU]"
+msgstr "E678: Ugyldig tegn etter %s%%[dxouU]"
+
+#, c-format
+msgid "E71: Invalid character after %s%%"
+msgstr "E71: Ugyldig tegn etter %s%%"
+
+#, c-format
+msgid "E769: Missing ] after %s["
+msgstr "E769: Mangler ] etter %s["
+
+#, c-format
+msgid "E554: Syntax error in %s{...}"
+msgstr "E554: Syntaksfeil i %s{...}"
+
+msgid "External submatches:\n"
+msgstr "Eksterne deltreff:\n"
+
+msgid " VREPLACE"
+msgstr " V-ERSTATT"
+
+msgid " REPLACE"
+msgstr " ERSTATT"
+
+msgid " REVERSE"
+msgstr " OMVENDT"
+
+msgid " INSERT"
+msgstr " SETT INN"
+
+msgid " (insert)"
+msgstr " (sett inn)"
+
+msgid " (replace)"
+msgstr " (erstatt)"
+
+msgid " (vreplace)"
+msgstr " (v-erstatt)"
+
+msgid " Hebrew"
+msgstr " hebraisk"
+
+msgid " Arabic"
+msgstr " arabisk"
+
+msgid " (lang)"
+msgstr " (lang)"
+
+msgid " (paste)"
+msgstr " (lim inn)"
+
+msgid " VISUAL"
+msgstr " VISUELL"
+
+msgid " VISUAL LINE"
+msgstr " VISUELL LINJE"
+
+msgid " VISUAL BLOCK"
+msgstr " VISUELL BLOKK"
+
+msgid " SELECT"
+msgstr " VELG"
+
+msgid " SELECT LINE"
+msgstr " VELG LINJE"
+
+msgid " SELECT BLOCK"
+msgstr " VELG BLOKK"
+
+msgid "recording"
+msgstr "spiller inn"
+
+#, c-format
+msgid "E383: Invalid search string: %s"
+msgstr "E383: Ugyldig søkestreng: %s"
+
+#, c-format
+msgid "E384: search hit TOP without match for: %s"
+msgstr "E384: Søket kom til TOPPEN uten treff på: %s"
+
+#, c-format
+msgid "E385: search hit BOTTOM without match for: %s"
+msgstr "E385: Søket kom til BUNNEN uten treff på: %s"
+
+msgid "E386: Expected '?' or '/' after ';'"
+msgstr "E386: Forventet '?' eller '/' etter ';'"
+
+msgid " (includes previously listed match)"
+msgstr " (inkluderer tidligere utlistede treff)"
+
+#. cursor at status line
+msgid "--- Included files "
+msgstr "--- Inkluderte filer "
+
+msgid "not found "
+msgstr "ikke funnet "
+
+msgid "in path ---\n"
+msgstr "i sti ---\n"
+
+msgid " (Already listed)"
+msgstr " (Allerede listet)"
+
+msgid " NOT FOUND"
+msgstr " IKKE FUNNET"
+
+#, c-format
+msgid "Scanning included file: %s"
+msgstr "Leter gjennom inkludert fil: %s"
+
+#, c-format
+msgid "Searching included file %s"
+msgstr "Leter gjennom inkludert fil %s"
+
+msgid "E387: Match is on current line"
+msgstr "E387: Treffet er på nåværende linje"
+
+msgid "All included files were found"
+msgstr "Alle inkluderte filer ble funnet"
+
+msgid "No included files"
+msgstr "Ingen inkluderte filer"
+
+msgid "E388: Couldn't find definition"
+msgstr "E388: Fant ikke definisjonen"
+
+msgid "E389: Couldn't find pattern"
+msgstr "E389: Fant ikke søketeksten"
+
+#, c-format
+#~ msgid ""
+#~ "\n"
+#~ "# Last %sSearch Pattern:\n"
+#~ "~"
+#~ msgstr ""
+
+msgid "E759: Format error in spell file"
+msgstr "E759: Formateringsfeil i stavefil"
+
+msgid "E758: Truncated spell file"
+msgstr "E758: Valg av skriver feilet"
+
+#, c-format
+msgid "Trailing text in %s line %d: %s"
+msgstr "Etterfølgende tekst i %s linje %d: %s"
+
+#, c-format
+msgid "Affix name too long in %s line %d: %s"
+msgstr "Affiksnavn for langt i %s linje %d: %s"
+
+msgid "E761: Format error in affix file FOL, LOW or UPP"
+msgstr "E761: Formatfeil i affiksfil 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 utenfor område"
+
+msgid "Compressing word tree..."
+msgstr "Pakker ordtre ..."
+
+msgid "E756: Spell checking is not enabled"
+msgstr "E756: Stavekontroll er ikke aktivisert"
+
+#, c-format
+msgid "Warning: Cannot find word list \"%s.%s.spl\" or \"%s.ascii.spl\""
+msgstr "Advarsel: Kan ikke finne ordliste \"%s.%s.spl\" eller \"%s.ascii.spl\""
+
+#, c-format
+msgid "Reading spell file \"%s\""
+msgstr "Leser stavefil \"%s\""
+
+msgid "E757: This does not look like a spell file"
+msgstr "E757: Dette ser ikke ut som en stavefil"
+
+msgid "E771: Old spell file, needs to be updated"
+msgstr "E771: Gammel stavefil, trenger oppdatering"
+
+msgid "E772: Spell file is for newer version of Vim"
+msgstr "E772: Stavefilen er for en nyere versjon av Vim"
+
+msgid "E770: Unsupported section in spell file"
+msgstr "E770: Ustøttet seksjon i stavefil"
+
+#, c-format
+msgid "Warning: region %s not supported"
+msgstr "Advarsel: Region %s ikke støttet"
+
+#, c-format
+msgid "Reading affix file %s ..."
+msgstr "Leser affiksfil %s ..."
+
+#, c-format
+msgid "Conversion failure for word in %s line %d: %s"
+msgstr "Konverteringsfeil for ord i %s linje %d: %s"
+
+#, c-format
+msgid "Conversion in %s not supported: from %s to %s"
+msgstr "Konvertering i %s ikke støttet: Fra %s til %s"
+
+#, c-format
+msgid "Conversion in %s not supported"
+msgstr "Konvertering i %s ikke støttet"
+
+#, c-format
+msgid "Invalid value for FLAG in %s line %d: %s"
+msgstr "Ugyldig verdi for FLAG i %s linje %d: %s"
+
+#, c-format
+msgid "FLAG after using flags in %s line %d: %s"
+msgstr "FLAG etter bruk av flagg i %s linje %d: %s"
+
+#, c-format
+#~ msgid ""
+#~ "Defining COMPOUNDFORBIDFLAG after PFX item may give wrong results in %s line "
+#~ "%d"
+#~ msgstr ""
+
+#, c-format
+#~ msgid ""
+#~ "Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in %s line "
+#~ "%d"
+#~ msgstr ""
+
+#, c-format
+msgid "Wrong COMPOUNDWORDMAX value in %s line %d: %s"
+msgstr "Feil COMPOUNDWORDMAX-verdi i %s linje %d: %s"
+
+#, c-format
+msgid "Wrong COMPOUNDMIN value in %s line %d: %s"
+msgstr "Feil COMPOUNDMIN-verdi i %s linje %d: %s"
+
+#, c-format
+msgid "Wrong COMPOUNDSYLMAX value in %s line %d: %s"
+msgstr "Feil COMPOUNDSYLMAX-verdi i %s linje %d: %s"
+
+#, c-format
+msgid "Wrong CHECKCOMPOUNDPATTERN value in %s line %d: %s"
+msgstr "Feil CHECKCOMPOUNDPATTERN-verdi i %s linje %d: %s"
+
+#, c-format
+msgid "Different combining flag in continued affix block in %s line %d: %s"
+msgstr ""
+"Forskjellig kombinasjonsflagg i affiksblokk som fortsetter i %s linje %d: %s"
+
+#, c-format
+msgid "Duplicate affix in %s line %d: %s"
+msgstr "Duplisert affiks i %s linje %d: %s"
+
+#, c-format
+msgid ""
+"Affix also used for BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST in %s "
+"line %d: %s"
+msgstr ""
+"Affiks også brukt 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 "Forventet Y eller N i %s linje %d: %s"
+
+#, c-format
+msgid "Broken condition in %s line %d: %s"
+msgstr "Brutt betingelse i %s linje %d: %s"
+
+#, c-format
+msgid "Expected REP(SAL) count in %s line %d"
+msgstr "Forventet REP(SAL)-antall i %s linje %d"
+
+#, c-format
+msgid "Expected MAP count in %s line %d"
+msgstr "Forventet MAP-antall i %s linje %d"
+
+#, c-format
+msgid "Duplicate character in MAP in %s line %d"
+msgstr "Duplisert tegn i MAP i %s linje %d"
+
+#, c-format
+msgid "Unrecognized or duplicate item in %s line %d: %s"
+msgstr "Ukjent eller duplisert element i %s linje %d: %s"
+
+#, c-format
+msgid "Missing FOL/LOW/UPP line in %s"
+msgstr "Mangler FOL/LOW/UPP-linje i %s"
+
+msgid "COMPOUNDSYLMAX used without SYLLABLE"
+msgstr "COMPOUNDSYLMAX brukt uten SYLLABLE"
+
+msgid "Too many postponed prefixes"
+msgstr "For mange utsatte forstavelser"
+
+msgid "Too many compound flags"
+msgstr "For mange sammensatte flagg"
+
+msgid "Too many postponed prefixes and/or compound flags"
+msgstr "For mange utsatte forstavelser og/eller sammensatte flagg"
+
+#, c-format
+msgid "Missing SOFO%s line in %s"
+msgstr "Mangler 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 "Flagg er ikke et tall i %s linje %d: %s"
+
+#, c-format
+msgid "Illegal flag in %s line %d: %s"
+msgstr "Ulovlig flagg i %s linje %d: %s"
+
+#, c-format
+msgid "%s value differs from what is used in another .aff file"
+msgstr "%s-verdi er forskjellig fra det som er bruk i en annen .aff-fil"
+
+#, c-format
+msgid "Reading dictionary file %s ..."
+msgstr "Leser ordlistefil %s ..."
+
+#, c-format
+msgid "E760: No word count in %s"
+msgstr "E760: Ingen ord-antall i %s"
+
+#, c-format
+msgid "line %6d, word %6d - %s"
+msgstr "linje %6d, ord %6d - %s"
+
+#, c-format
+msgid "Duplicate word in %s line %d: %s"
+msgstr "Duplisert ord i %s linje %d: %s"
+
+#, c-format
+msgid "First duplicate word in %s line %d: %s"
+msgstr "Første dupliserte ord i %s linje %d: %s"
+
+#, c-format
+msgid "%d duplicate word(s) in %s"
+msgstr "%d duplisert(e) ord i %s"
+
+#, c-format
+msgid "Ignored %d word(s) with non-ASCII characters in %s"
+msgstr "Ignorerte %d ord med ikke-ASCII-tegn i %s"
+
+#, c-format
+msgid "Reading word file %s ..."
+msgstr "Leser ordfil %s ..."
+
+#, c-format
+msgid "Duplicate /encoding= line ignored in %s line %d: %s"
+msgstr "Duplisert '/encoding='-linje ignorert i %s linje %d: %s"
+
+#, c-format
+msgid "/encoding= line after word ignored in %s line %d: %s"
+msgstr "'/encoding='-linje etter ord ignorert i %s linje %d: %s"
+
+#, c-format
+msgid "Duplicate /regions= line ignored in %s line %d: %s"
+msgstr "Duplisert '/regions='-linje ignorert 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 ignorert i %s linje %d: %s"
+
+#, c-format
+msgid "Invalid region nr in %s line %d: %s"
+msgstr "Ugyldig regionnummer i %s linje %d: %s"
+
+#, c-format
+msgid "Unrecognized flags in %s line %d: %s"
+msgstr "Ukjent flagg i %s linje %d: %s"
+
+#, c-format
+msgid "Ignored %d words with non-ASCII characters"
+msgstr "Ignorerte %d ord med ikke-ASCII-tegn"
+
+#, c-format
+msgid "Compressed %d of %d nodes; %d (%d%%) remaining"
+msgstr "Pakket %d av %d noder; %d (%d%%) igjen"
+
+#, fuzzy
+#~ msgid "Reading back spell file..."
+#~ msgstr "Leser stavefil \"%s\""
+
+#.
+#. * Go through the trie of good words, soundfold each word and add it to
+#. * the soundfold trie.
+#.
+#~ msgid "Performing soundfolding..."
+#~ msgstr ""
+
+#, c-format
+#~ msgid "Number of words after soundfolding: %ld"
+#~ msgstr ""
+
+#, c-format
+msgid "Total number of words: %d"
+msgstr "Totalt antall ord: %d"
+
+#, c-format
+msgid "Writing suggestion file %s ..."
+msgstr "Skriver forslagsfil %s ..."
+
+#, c-format
+msgid "Estimated runtime memory use: %d bytes"
+msgstr "Anslått hukommelsesbruk under kjøring: %d bytes"
+
+msgid "E751: Output file name must not have region name"
+msgstr "E751: Utdatafilnavn må ikke ha regionnavn"
+
+msgid "E754: Only up to 8 regions supported"
+msgstr "E754: Kun opp til 8 regioner er støttet"
+
+#, c-format
+msgid "E755: Invalid region in %s"
+msgstr "E755: Ugyldig region i %s"
+
+#~ msgid "Warning: both compounding and NOBREAK specified"
+#~ msgstr ""
+
+#, c-format
+msgid "Writing spell file %s ..."
+msgstr "Lagrer stavefil %s ..."
+
+msgid "Done!"
+msgstr "Ferdig!"
+
+#, c-format
+msgid "E765: 'spellfile' does not have %ld entries"
+msgstr "E765: 'spellfile' har ikke %ld poster"
+
+#, c-format
+msgid "Word removed from %s"
+msgstr "Ord fjernet fra %s"
+
+#, c-format
+msgid "Word added to %s"
+msgstr "Ord lagt til %s"
+
+msgid "E763: Word characters differ between spell files"
+msgstr "E763: Tegn i ord varierer mellom stavefiler"
+
+msgid "Sorry, no suggestions"
+msgstr "Dessverre, ingen forslag"
+
+#, c-format
+msgid "Sorry, only %ld suggestions"
+msgstr "Dessverre bare %ld forslag"
+
+#. for when 'cmdheight' > 1
+#. avoid more prompt
+#, c-format
+msgid "Change \"%.*s\" to:"
+msgstr "Forandre \"%.*s\" til:"
+
+#, c-format
+msgid " < \"%.*s\""
+msgstr " < \"%.*s\""
+
+msgid "E752: No previous spell replacement"
+msgstr "E752: Ingen tidligere staveerstatninger"
+
+#, c-format
+msgid "E753: Not found: %s"
+msgstr "E753: Ikke funnet: %s"
+
+#, c-format
+msgid "E778: This does not look like a .sug file: %s"
+msgstr "E778: Dette ser ikke ut som en .sug-fil: %s"
+
+#, c-format
+msgid "E779: Old .sug file, needs to be updated: %s"
+msgstr "E779: Gammel .sug-fil, trenger oppdatering: %s"
+
+#, c-format
+msgid "E780: .sug file is for newer version of Vim: %s"
+msgstr "E780: .sug-fila er for en nyere versjon av Vim: %s"
+
+#, c-format
+msgid "E781: .sug file doesn't match .spl file: %s"
+msgstr "E781: .sug-fil samsvarer ikke med .spl-fil: %s"
+
+#, c-format
+msgid "E782: error while reading .sug file: %s"
+msgstr "E782: Feil under lesing av .sug-fil: %s"
+
+#. This should have been checked when generating the .spl
+#. * file.
+msgid "E783: duplicate char in MAP entry"
+msgstr "E783: Duplisert tegn i MAP-oppføring"
+
+#, c-format
+msgid "E390: Illegal argument: %s"
+msgstr "E390: Ulovlig parameter: %s"
+
+#, c-format
+msgid "E391: No such syntax cluster: %s"
+msgstr "E391: Syntaksklyngen finnes ikke: %s"
+
+msgid "No Syntax items defined for this buffer"
+msgstr "Ingen syntakselementer er definert for denne bufferen"
+
+msgid "syncing on C-style comments"
+msgstr "synkroniserer C-lignende kommentarer"
+
+msgid "no syncing"
+msgstr "ingen synkronisering"
+
+msgid "syncing starts "
+msgstr "synkronisering starter "
+
+msgid " lines before top line"
+msgstr " linjer før topplinje"
+
+msgid ""
+"\n"
+"--- Syntax sync items ---"
+msgstr ""
+"\n"
+"--- \"Syntax sync\"-elementer ---"
+
+msgid ""
+"\n"
+"syncing on items"
+msgstr ""
+"\n"
+"synkroniserer på elementer"
+
+msgid ""
+"\n"
+"--- Syntax items ---"
+msgstr ""
+"\n"
+"--- Syntakselementer ---"
+
+#, c-format
+msgid "E392: No such syntax cluster: %s"
+msgstr "E392: Syntaksklyngen finnes ikke: %s"
+
+msgid "minimal "
+msgstr "minimal "
+
+msgid "maximal "
+msgstr "maksimal "
+
+msgid "; match "
+msgstr "; samsvarer med "
+
+msgid " line breaks"
+msgstr " linjeskift"
+
+msgid "E395: contains argument not accepted here"
+msgstr "E395: \"contains\"-parameter aksepteres ikke her"
+
+msgid "E396: containedin argument not accepted here"
+msgstr "E396: \"containedin\"-parameter aksepteres ikke her"
+
+msgid "E393: group[t]here not accepted here"
+msgstr "E393: \"group[t]here\" aksepteres ikke her"
+
+#, c-format
+msgid "E394: Didn't find region item for %s"
+msgstr "E394: Fant ikke regionelement for %s"
+
+msgid "E397: Filename required"
+msgstr "E397: Trenger filnavn"
+
+#, c-format
+msgid "E789: Missing ']': %s"
+msgstr "E789: Mangler ']': %s"
+
+#, c-format
+msgid "E398: Missing '=': %s"
+msgstr "E398: Mangler '=': %s"
+
+#, c-format
+msgid "E399: Not enough arguments: syntax region %s"
+msgstr "E399: Ikke nok parametere: syntax region %s"
+
+msgid "E400: No cluster specified"
+msgstr "E400: Ingen klynge er spesifisert"
+
+#, c-format
+msgid "E401: Pattern delimiter not found: %s"
+msgstr "E401: Skilletegn for søketekst ble ikke funnet: %s"
+
+#, c-format
+msgid "E402: Garbage after pattern: %s"
+msgstr "E402: Søppel etter søketekst: %s"
+
+msgid "E403: syntax sync: line continuations pattern specified twice"
+msgstr ""
+"E403: syntax sync: Søkestreng for linjefortsettelser er spesifisert to ganger"
+
+#, c-format
+msgid "E404: Illegal arguments: %s"
+msgstr "E404: Ulovlige parametere: %s"
+
+#, c-format
+msgid "E405: Missing equal sign: %s"
+msgstr "E405: Mangler \"er lik\"-tegn: %s"
+
+#, c-format
+msgid "E406: Empty argument: %s"
+msgstr "E406: Tomt parameter: %s"
+
+#, c-format
+msgid "E407: %s not allowed here"
+msgstr "E407: %s er ikke tillatt her"
+
+#, c-format
+msgid "E408: %s must be first in contains list"
+msgstr "E408: %s må være først i \"contains\"-liste"
+
+#, c-format
+msgid "E409: Unknown group name: %s"
+msgstr "E409: Ukjent gruppenavn: %s"
+
+#, c-format
+msgid "E410: Invalid :syntax subcommand: %s"
+msgstr "E410: Ugyldig \":syntax\"-delkommando: %s"
+
+msgid "E679: recursive loop loading syncolor.vim"
+msgstr "E679: Rekursiv løkke laster syncolor.vim"
+
+#, c-format
+msgid "E411: highlight group not found: %s"
+msgstr "E411: Fant ikke uthevingsgruppe: %s"
+
+#, c-format
+msgid "E412: Not enough arguments: \":highlight link %s\""
+msgstr "E412: Ikke nok parametere: \":highlight link %s\""
+
+#, c-format
+msgid "E413: Too many arguments: \":highlight link %s\""
+msgstr "E413: For mange parametere: \":highlight link %s\""
+
+msgid "E414: group has settings, highlight link ignored"
+msgstr "E414: Syntaxgruppen har oppsett, uthevingslenke ignoreres"
+
+#, c-format
+msgid "E415: unexpected equal sign: %s"
+msgstr "E415: Uventet \"er lik\"-tegn: %s"
+
+#, c-format
+msgid "E416: missing equal sign: %s"
+msgstr "E416: Mangler \"er lik\"-tegn: %s"
+
+#, c-format
+msgid "E417: missing argument: %s"
+msgstr "E417: Mangler parameter: %s"
+
+#, c-format
+msgid "E418: Illegal value: %s"
+msgstr "E418: Ulovlig verdi: %s"
+
+msgid "E419: FG color unknown"
+msgstr "E419: Ukjent forgrunnsfarge"
+
+msgid "E420: BG color unknown"
+msgstr "E420: Ukjent bakgrunnsfarge"
+
+#, c-format
+msgid "E421: Color name or number not recognized: %s"
+msgstr "E421: Kjenner ikke til fargenavnet eller -nummeret: %s"
+
+#, c-format
+msgid "E422: terminal code too long: %s"
+msgstr "E422: Terminalkoden er for lang: %s"
+
+#, c-format
+msgid "E423: Illegal argument: %s"
+msgstr "E423: Ulovlig parameter: %s"
+
+msgid "E424: Too many different highlighting attributes in use"
+msgstr "E424: For mange forskjellige uthevingsattributter i bruk"
+
+msgid "E669: Unprintable character in group name"
+msgstr "E669: Ikke-skrivbart tegn i gruppenavn"
+
+msgid "W18: Invalid character in group name"
+msgstr "W18: Ugyldig tegn i gruppenavn"
+
+msgid "E555: at bottom of tag stack"
+msgstr "E555: På bunnen av tag-stack"
+
+msgid "E556: at top of tag stack"
+msgstr "E556: På toppen av tag-stack"
+
+msgid "E425: Cannot go before first matching tag"
+msgstr "E425: Kan ikke gå før første samsvarende tag"
+
+#, c-format
+msgid "E426: tag not found: %s"
+msgstr "E426: Fant ikke tag: %s"
+
+#~ msgid " # pri kind tag"
+#~ msgstr ""
+
+msgid "file\n"
+msgstr "fil\n"
+
+msgid "E427: There is only one matching tag"
+msgstr "E427: Det finnes bare en samsvarende tag"
+
+msgid "E428: Cannot go beyond last matching tag"
+msgstr "E428: Kan ikke gå forbi siste samsvarende tag"
+
+#, c-format
+msgid "File \"%s\" does not exist"
+msgstr "Filen \"%s\" finnes ikke"
+
+#. Give an indication of the number of matching tags
+#, c-format
+msgid "tag %d of %d%s"
+msgstr "tag %d av %d%s"
+
+msgid " or more"
+msgstr " eller mer"
+
+msgid " Using tag with different case!"
+msgstr " Bruker tag med forskjellig bokstavstørrelse!"
+
+#, c-format
+msgid "E429: File \"%s\" does not exist"
+msgstr "E429: Filen \"%s\" finnes ikke"
+
+#. Highlight title
+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 "Leter i tagfil %s"
+
+#, c-format
+msgid "E430: Tag file path truncated for %s\n"
+msgstr "E430: Sti til tagfil kuttet for %s\n"
+
+#, c-format
+msgid "E431: Format error in tags file \"%s\""
+msgstr "E431: Formatfeil i tagfil \"%s\""
+
+#, c-format
+msgid "Before byte %ld"
+msgstr "Før byte %ld"
+
+#, c-format
+msgid "E432: Tags file not sorted: %s"
+msgstr "E432: Tagfil ikke sortert: %s"
+
+#. never opened any tags file
+msgid "E433: No tags file"
+msgstr "E433: Ingen tagfil"
+
+msgid "E434: Can't find tag pattern"
+msgstr "E434: Kan ikke finne tagsøkestreng"
+
+msgid "E435: Couldn't find tag, just guessing!"
+msgstr "E435: Kunne ikke finne tag, bare gjetter!"
+
+msgid "' not known. Available builtin terminals are:"
+msgstr "' ikke kjent. Tilgjengelige innebygde terminaler er:"
+
+msgid "defaulting to '"
+msgstr "faller tilbake på '"
+
+msgid "E557: Cannot open termcap file"
+msgstr "E557: Kan ikke åpne termcap-fil"
+
+msgid "E558: Terminal entry not found in terminfo"
+msgstr "E558: Fant ikke terminaloppføring i terminfo"
+
+msgid "E559: Terminal entry not found in termcap"
+msgstr "E559: Fant ikke terminaloppføring i termcap"
+
+#, c-format
+msgid "E436: No \"%s\" entry in termcap"
+msgstr "E436: Ingen \"%s\"-oppføring i termcap"
+
+msgid "E437: terminal capability \"cm\" required"
+msgstr "E437: Terminalfunksjonen \"cm\" nødvendig"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Terminal keys ---"
+msgstr ""
+"\n"
+"--- Terminaltaster ---"
+
+msgid "new shell started\n"
+msgstr "nytt skall startet\n"
+
+msgid "Vim: Error reading input, exiting...\n"
+msgstr "Vim: Feil under lesing av inndata, avslutter ...\n"
+
+#. must display the prompt
+msgid "No undo possible; continue anyway"
+msgstr "Ingen angremuligheter; fortsett likevel"
+
+msgid "Already at oldest change"
+msgstr "Allerede ved eldste forandring"
+
+msgid "Already at newest change"
+msgstr "Allerede ved nyeste forandring"
+
+#, c-format
+msgid "Undo number %ld not found"
+msgstr "Angrenummer %ld ikke funnet"
+
+msgid "E438: u_undo: line numbers wrong"
+msgstr "E438: u_undo: Gale linjenummer"
+
+msgid "more line"
+msgstr "linje lagt til"
+
+msgid "more lines"
+msgstr "linjer lagt til"
+
+msgid "line less"
+msgstr "linje fjernet"
+
+msgid "fewer lines"
+msgstr "linjer fjernet"
+
+msgid "change"
+msgstr "forandring"
+
+msgid "changes"
+msgstr "forandringer"
+
+#, c-format
+msgid "%ld %s; %s #%ld %s"
+msgstr "%ld %s; %s #%ld %s"
+
+msgid "before"
+msgstr "før"
+
+msgid "after"
+msgstr "etter"
+
+msgid "Nothing to undo"
+msgstr "Ingenting å angre"
+
+msgid "number changes time"
+msgstr "nummer forandringer tidspunkt"
+
+#, c-format
+msgid "%ld seconds ago"
+msgstr "%ld sekunder siden"
+
+msgid "E790: undojoin is not allowed after undo"
+msgstr "E790: undojoin er ikke tillatt etter undo"
+
+msgid "E439: undo list corrupt"
+msgstr "E439: Angrelisten er skadet"
+
+msgid "E440: undo line missing"
+msgstr "E440: Angrelisten mangler"
+
+#. Only MS VC 4.1 and earlier can do Win32s
+msgid ""
+"\n"
+"MS-Windows 16/32-bit GUI version"
+msgstr ""
+"\n"
+"MS Windows 16/32-bits grafisk versjon"
+
+msgid ""
+"\n"
+"MS-Windows 64-bit GUI version"
+msgstr ""
+"\n"
+"MS Windows 64-bits grafisk versjon"
+
+msgid ""
+"\n"
+"MS-Windows 32-bit GUI version"
+msgstr ""
+"\n"
+"MS-Windows 32-bits GUI-versjon"
+
+msgid " in Win32s mode"
+msgstr " i Win32s-modus"
+
+msgid " with OLE support"
+msgstr " med OLE-støtte"
+
+msgid ""
+"\n"
+"MS-Windows 32-bit console version"
+msgstr ""
+"\n"
+"MS-Windows 32-bits konsollversjon"
+
+msgid ""
+"\n"
+"MS-Windows 16-bit version"
+msgstr ""
+"\n"
+"MS-Windows 16-bits versjon"
+
+msgid ""
+"\n"
+"32-bit MS-DOS version"
+msgstr ""
+"\n"
+"32-bits MS-DOS-versjon"
+
+msgid ""
+"\n"
+"16-bit MS-DOS version"
+msgstr ""
+"\n"
+"16-bits MS-DOS-versjon"
+
+msgid ""
+"\n"
+"MacOS X (unix) version"
+msgstr ""
+"\n"
+"MacOS X (unix)-versjon"
+
+msgid ""
+"\n"
+"MacOS X version"
+msgstr ""
+"\n"
+"MacOS X-versjon"
+
+msgid ""
+"\n"
+"MacOS version"
+msgstr ""
+"\n"
+"MacOS-versjon"
+
+msgid ""
+"\n"
+"RISC OS version"
+msgstr ""
+"\n"
+"RISC OS-versjon"
+
+msgid ""
+"\n"
+"Included patches: "
+msgstr ""
+"\n"
+"Inkluderte patcher: "
+
+msgid "Modified by "
+msgstr "Modifisert av "
+
+msgid ""
+"\n"
+"Compiled "
+msgstr ""
+"\n"
+"Kompilert "
+
+msgid "by "
+msgstr "av "
+
+msgid ""
+"\n"
+"Huge version "
+msgstr ""
+"\n"
+"Diger (\"huge\") versjon "
+
+msgid ""
+"\n"
+"Big version "
+msgstr ""
+"\n"
+"Stor (\"big\") versjon "
+
+msgid ""
+"\n"
+"Normal version "
+msgstr ""
+"\n"
+"Normal versjon "
+
+msgid ""
+"\n"
+"Small version "
+msgstr ""
+"\n"
+"Liten (\"small\") versjon "
+
+msgid ""
+"\n"
+"Tiny version "
+msgstr ""
+"\n"
+"Spinkel (\"tiny\") versjon "
+
+msgid "without GUI."
+msgstr "uten GUI."
+
+msgid "with GTK2-GNOME GUI."
+msgstr "med GTK2-GNOME GUI."
+
+msgid "with GTK-GNOME GUI."
+msgstr "med GTK-GNOME GUI."
+
+msgid "with GTK2 GUI."
+msgstr "med GTK2 GUI."
+
+msgid "with GTK GUI."
+msgstr "med GTK 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 "with (classic) GUI."
+msgstr "med (klassisk) GUI."
+
+msgid " Features included (+) or not (-):\n"
+msgstr " Funksjoner inkludert (+) eller ikke (-):\n"
+
+msgid " system vimrc file: \""
+msgstr " vimrc-fil på systemet: \""
+
+msgid " user vimrc file: \""
+msgstr " vimrc-fil for brukere: \""
+
+msgid " 2nd user vimrc file: \""
+msgstr " vimrc-fil nr. 2 for brukere: \""
+
+msgid " 3rd user vimrc file: \""
+msgstr " vimrc-fil nr. 3 for brukere: \""
+
+msgid " user exrc file: \""
+msgstr " exrc-fil for brukere: \""
+
+msgid " 2nd user exrc file: \""
+msgstr " exrc-fil nr. 2 for brukere: \""
+
+msgid " system gvimrc file: \""
+msgstr " gvimrc-fil på systemet: \""
+
+msgid " user gvimrc file: \""
+msgstr " gvimrc-fil for brukere: \""
+
+msgid "2nd user gvimrc file: \""
+msgstr " gvimrc-fil nr. 2 for brukere: \""
+
+msgid "3rd user gvimrc file: \""
+msgstr " gvimrc-fil nr. 3 for brukere: \""
+
+msgid " system menu file: \""
+msgstr " menyfil på systemet: \""
+
+msgid " fall-back for $VIM: \""
+msgstr " $VIM faller tilbake på: \""
+
+msgid " f-b for $VIMRUNTIME: \""
+msgstr "$VIMRUNTIME faller tilbake på: \""
+
+msgid "Compilation: "
+msgstr "Kompilering: "
+
+msgid "Compiler: "
+msgstr "Kompilator: "
+
+msgid "Linking: "
+msgstr "Linking: "
+
+msgid " DEBUG BUILD"
+msgstr " DEBUGGINGSVERSJON"
+
+msgid "VIM - Vi IMproved"
+msgstr "VIM - Vi IMproved - Forbedret Vi"
+
+msgid "version "
+msgstr "versjon "
+
+msgid "by Bram Moolenaar et al."
+msgstr "av Bram Moolenaar med flere"
+
+msgid "Vim is open source and freely distributable"
+msgstr "Vim er åpen kildekode og kan fritt distribueres"
+
+msgid "Help poor children in Uganda!"
+msgstr "Hjelp fattige barn i Uganda!"
+
+msgid "type :help iccf<Enter> for information "
+msgstr "skriv :help iccf<Enter> for informasjon "
+
+msgid "type :q<Enter> to exit "
+msgstr "skriv :q<Enter> for å avslutte "
+
+msgid "type :help<Enter> or <F1> for on-line help"
+msgstr "skriv :help<Enter> eller <F1> for on-line hjelp"
+
+msgid "type :help version7<Enter> for version info"
+msgstr "skriv :help version7<Enter> for versjonsinfo "
+
+msgid "Running in Vi compatible mode"
+msgstr "Kjører i Vi-kompatibel modus"
+
+msgid "type :set nocp<Enter> for Vim defaults"
+msgstr "skriv :set nocp<Enter> for standard Vim "
+
+msgid "type :help cp-default<Enter> for info on this"
+msgstr "skriv :help cp-default<Enter> for informasjon "
+
+msgid "menu Help->Orphans for information "
+msgstr "meny: Hjelp->Foreldreløse for informasjon "
+
+msgid "Running modeless, typed text is inserted"
+msgstr "Kjører uten modus, tastetrykk blir lagt inn i teksten"
+
+msgid "menu Edit->Global Settings->Toggle Insert Mode "
+msgstr "meny: Rediger->Globale innstillinger->Innsettingsmodus av/på"
+
+msgid " for two modes "
+msgstr " for to moduser "
+
+msgid "menu Edit->Global Settings->Toggle Vi Compatible"
+msgstr "meny: Rediger->Globale innstillinger->Vi-kompatibilitet av/på"
+
+msgid " for Vim defaults "
+msgstr " for standard Vim "
+
+msgid "Sponsor Vim development!"
+msgstr "Støtt utviklingen av Vim!"
+
+msgid "Become a registered Vim user!"
+msgstr "Bli registrert bruker av Vim!"
+
+msgid "type :help sponsor<Enter> for information "
+msgstr "skriv :help sponsor<Enter> for informasjon "
+
+msgid "type :help register<Enter> for information "
+msgstr "skriv :help register<Enter> for informasjon "
+
+msgid "menu Help->Sponsor/Register for information "
+msgstr "meny: Hjelp->Støtte/Registrering for informasjon "
+
+msgid "WARNING: Windows 95/98/ME detected"
+msgstr "ADVARSEL: Windows 95/98/ME oppdaget"
+
+msgid "type :help windows95<Enter> for info on this"
+msgstr "skriv :help windows95<Enter> for informasjon "
+
+msgid "Already only one window"
+msgstr "Allerede bare ett vindu"
+
+msgid "E441: There is no preview window"
+msgstr "E441: Vindu for forhåndsvisning finnes ikke"
+
+msgid "E442: Can't split topleft and botright at the same time"
+msgstr "E442: Kan ikke splitte \"topleft\" og \"botright\" på en gang"
+
+msgid "E443: Cannot rotate when another window is split"
+msgstr "E443: Kan ikke rotere når et annet vindu er splittet"
+
+msgid "E444: Cannot close last window"
+msgstr "E444: Kan ikke lukke det siste vinduet"
+
+msgid "E445: Other window contains changes"
+msgstr "E445: Annet vindu inneholder forandringer"
+
+msgid "E446: No file name under cursor"
+msgstr "E446: Ingen filnavn under markøren"
+
+#, c-format
+msgid "E447: Can't find file \"%s\" in path"
+msgstr "E447: Kan ikke finne filen \"%s\" i stien"
+
+#, c-format
+msgid "E370: Could not load library %s"
+msgstr "E370: Klarte ikke laste bibliotek %s"
+
+msgid "Sorry, this command is disabled: the Perl library could not be loaded."
+msgstr "Denne kommandoen er deaktivert, Perl-biblioteket kunne ikke lastes."
+
+msgid "E299: Perl evaluation forbidden in sandbox without the Safe module"
+msgstr ""
+"E299: Evaluering av Perl er ikke tillatt i sandkassen uten \"Safe\"-modulen"
+
+msgid "Edit with &multiple Vims"
+msgstr "Rediger med &flere Vim-er"
+
+msgid "Edit with single &Vim"
+msgstr "Rediger med enkel &Vim"
+
+msgid "Diff with Vim"
+msgstr "Differanse med Vim"
+
+msgid "Edit with &Vim"
+msgstr "Rediger med &Vim"
+
+#. Now concatenate
+msgid "Edit with existing Vim - "
+msgstr "Rediger med eksisterende Vim - "
+
+msgid "Edits the selected file(s) with Vim"
+msgstr "Redigerer de(n) valgte filen(e) med Vim"
+
+msgid "Error creating process: Check if gvim is in your path!"
+msgstr "Klarte ikke lage prosess: Sjekk at gvim er i stien!"
+
+msgid "gvimext.dll error"
+msgstr "Feil i gvimext.dll"
+
+msgid "Path length too long!"
+msgstr "Lengden på stien er for lang!"
+
+msgid "--No lines in buffer--"
+msgstr "--Ingen linjer i bufferen--"
+
+#.
+#. * 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: Kommandoen avbrutt"
+
+msgid "E471: Argument required"
+msgstr "E471: Parameter nødvendig"
+
+msgid "E10: \\ should be followed by /, ? or &"
+msgstr "E10: \\ skulle ha vært fulgt av /, ? eller &"
+
+msgid "E11: Invalid in command-line window; <CR> executes, CTRL-C quits"
+msgstr "E11: Ugyldig i kommandolinjevindu; <ENTER> utfører, CTRL-C avslutter"
+
+msgid "E12: Command not allowed from exrc/vimrc in current dir or tag search"
+msgstr ""
+"E12: Kommandoen er ikke tillatt fra exrc/vimrc i nåværende katalog eller "
+"tagsøk"
+
+msgid "E171: Missing :endif"
+msgstr "E171: Mangler :endif"
+
+msgid "E600: Missing :endtry"
+msgstr "E600: Mangler :endtry"
+
+msgid "E170: Missing :endwhile"
+msgstr "E170: Mangler :endwhile"
+
+msgid "E170: Missing :endfor"
+msgstr "E170: Mangler :endfor"
+
+msgid "E588: :endwhile without :while"
+msgstr "E588: :endwhile uten :while"
+
+msgid "E588: :endfor without :for"
+msgstr "E588: :endfor uten :for"
+
+msgid "E13: File exists (add ! to override)"
+msgstr "E13: Filen finnes (legg til ! for å overstyre)"
+
+msgid "E472: Command failed"
+msgstr "E472: Kommandoen feilet"
+
+#, c-format
+msgid "E234: Unknown fontset: %s"
+msgstr "E234: Ukjent skrifttypesett: %s"
+
+#, c-format
+msgid "E235: Unknown font: %s"
+msgstr "E235: Ukjent skrifttype: %s"
+
+#, c-format
+msgid "E236: Font \"%s\" is not fixed-width"
+msgstr "E236: Skrifttypen \"%s\" har ikke fast bredde"
+
+msgid "E473: Internal error"
+msgstr "E473: Intern feil"
+
+msgid "Interrupted"
+msgstr "Avbrutt"
+
+msgid "E14: Invalid address"
+msgstr "E14: Ugyldig adresse"
+
+msgid "E474: Invalid argument"
+msgstr "E474: Ugyldig parameter"
+
+#, c-format
+msgid "E475: Invalid argument: %s"
+msgstr "E475: Ugyldig paramter: %s"
+
+#, c-format
+msgid "E15: Invalid expression: %s"
+msgstr "E15: Ugyldig uttrykk: %s"
+
+msgid "E16: Invalid range"
+msgstr "E16: Ugyldig område"
+
+msgid "E476: Invalid command"
+msgstr "E476: Ugyldig kommando"
+
+#, c-format
+msgid "E17: \"%s\" is a directory"
+msgstr "E17: \"%s\" er en katalog"
+
+#, c-format
+msgid "E364: Library call failed for \"%s()\""
+msgstr "E364: Bibliotek-kall feilet for \"%s()\""
+
+#, c-format
+msgid "E448: Could not load library function %s"
+msgstr "E448: Klarte ikke laste biblioteksfunksjon %s"
+
+msgid "E19: Mark has invalid line number"
+msgstr "E19: Merket har et ugyldig linjenummer"
+
+msgid "E20: Mark not set"
+msgstr "E20: Merket ble ikke satt"
+
+msgid "E21: Cannot make changes, 'modifiable' is off"
+msgstr "E21: Kan ikke gjøre forandringer, 'modifiable' er av"
+
+msgid "E22: Scripts nested too deep"
+msgstr "E22: Skripts nøstet for dypt"
+
+msgid "E23: No alternate file"
+msgstr "E23: Ingen alternativ fil"
+
+msgid "E24: No such abbreviation"
+msgstr "E24: Forkortelsen finnes ikke"
+
+msgid "E477: No ! allowed"
+msgstr "E477: Ingen ! tillatt"
+
+msgid "E25: GUI cannot be used: Not enabled at compile time"
+msgstr "E25: GUI kan ikke brukes: Ikke slått på under kompilering"
+
+msgid "E26: Hebrew cannot be used: Not enabled at compile time\n"
+msgstr "E26: Hebraisk kan ikke brukes: Ikke slått på under kompilering\n"
+
+msgid "E27: Farsi cannot be used: Not enabled at compile time\n"
+msgstr ""
+"E27: Persisk (Farsi) kan ikke brukes: Ikke slått på under kompilering\n"
+
+msgid "E800: Arabic cannot be used: Not enabled at compile time\n"
+msgstr "E800: Arabisk kan ikke brukes: Ikke slått på under kompilering\n"
+
+#, c-format
+msgid "E28: No such highlight group name: %s"
+msgstr "E28: Uthevingsgruppe finnes ikke: %s"
+
+msgid "E29: No inserted text yet"
+msgstr "E29: Ingen innlagt tekst enda"
+
+msgid "E30: No previous command line"
+msgstr "E30: Ingen tidligere kommandolinje"
+
+msgid "E31: No such mapping"
+msgstr "E31: Mappingen finnes ikke"
+
+msgid "E479: No match"
+msgstr "E479: Ingen treff"
+
+#, c-format
+msgid "E480: No match: %s"
+msgstr "E480: Ingen treff: %s"
+
+msgid "E32: No file name"
+msgstr "E32: Mangler filnavn"
+
+msgid "E33: No previous substitute regular expression"
+msgstr "E33: Ingen tidligere erstatninger med regulære uttrykk"
+
+msgid "E34: No previous command"
+msgstr "E34: Ingen tidligere kommando"
+
+msgid "E35: No previous regular expression"
+msgstr "E35: Ingen tidligere regulære uttrykk"
+
+msgid "E481: No range allowed"
+msgstr "E481: Område er ikke tillatt"
+
+msgid "E36: Not enough room"
+msgstr "E36: Ikke nok plass"
+
+#, c-format
+msgid "E247: no registered server named \"%s\""
+msgstr "E247: Ingen registrert tjener kalt \"%s\""
+
+#, c-format
+msgid "E482: Can't create file %s"
+msgstr "E482: Kan ikke opprette filen %s"
+
+msgid "E483: Can't get temp file name"
+msgstr "E483: Kan ikke hente navn på midlertidig fil"
+
+#, c-format
+msgid "E484: Can't open file %s"
+msgstr "E484: Kan ikke åpne filen %s"
+
+#, c-format
+msgid "E485: Can't read file %s"
+msgstr "E485: Kan ikke lese filen %s"
+
+msgid "E37: No write since last change (add ! to override)"
+msgstr "E37: Ikke lagret siden forrige forandring (legg til ! for å overstyre)"
+
+msgid "E38: Null argument"
+msgstr "E38: Nullparameter"
+
+msgid "E39: Number expected"
+msgstr "E39: Nummer forventet"
+
+#, c-format
+msgid "E40: Can't open errorfile %s"
+msgstr "E40: Kan ikke åpne feilfilen %s"
+
+msgid "E233: cannot open display"
+msgstr "E233: Kan ikke åpne display"
+
+msgid "E41: Out of memory!"
+msgstr "E41: Ikke mer ledig hukommelse!"
+
+msgid "Pattern not found"
+msgstr "Fant ikke søketeksten"
+
+#, c-format
+msgid "E486: Pattern not found: %s"
+msgstr "E486: Fant ikke søketeksten: %s"
+
+msgid "E487: Argument must be positive"
+msgstr "E487: Parameteret må være positivt"
+
+msgid "E459: Cannot go back to previous directory"
+msgstr "E459: Kan ikke gå tilbake til tidligere katalog"
+
+msgid "E42: No Errors"
+msgstr "E42: Ingen feil"
+
+msgid "E776: No location list"
+msgstr "E776: Ingen plassliste"
+
+msgid "E43: Damaged match string"
+msgstr "E43: Ødelagt søkestreng"
+
+msgid "E44: Corrupted regexp program"
+msgstr "E44: Skadet program med regulært uttrykk"
+
+msgid "E45: 'readonly' option is set (add ! to override)"
+msgstr "E45: 'readonly'-valget er satt (legg til ! for å overstyre)"
+
+#, c-format
+msgid "E46: Cannot change read-only variable \"%s\""
+msgstr "E46: Kan ikke forandre skrivebeskyttet variabel \"%s\""
+
+#, c-format
+msgid "E794: Cannot set variable in the sandbox: \"%s\""
+msgstr "E794: Kan ikke sette variabel i sandkassen: \"%s\""
+
+msgid "E47: Error while reading errorfile"
+msgstr "E47: Feil under lesing av feilfilen"
+
+msgid "E48: Not allowed in sandbox"
+msgstr "E48: Ikke tillatt i sandkassen"
+
+msgid "E523: Not allowed here"
+msgstr "E523: Ikke tillatt her"
+
+msgid "E359: Screen mode setting not supported"
+msgstr "E359: Forandring av skjermmodus er ikke støttet"
+
+msgid "E49: Invalid scroll size"
+msgstr "E49: Ugyldig \"scroll\"-verdi"
+
+msgid "E91: 'shell' option is empty"
+msgstr "E91: 'shell'-valget er tomt"
+
+msgid "E255: Couldn't read in sign data!"
+msgstr "E255: Kunne ikke lese inn skiltdata!"
+
+msgid "E72: Close error on swap file"
+msgstr "E72: Feil under lukking av swapfil"
+
+msgid "E73: tag stack empty"
+msgstr "E73: Tag-stack tom"
+
+msgid "E74: Command too complex"
+msgstr "E74: Kommandoen er for kompleks"
+
+msgid "E75: Name too long"
+msgstr "E75: Navnet er for langt"
+
+msgid "E76: Too many ["
+msgstr "E76: For mange ["
+
+msgid "E77: Too many file names"
+msgstr "E77: For mange filnavn"
+
+msgid "E488: Trailing characters"
+msgstr "E488: Etterfølgende tegn"
+
+msgid "E78: Unknown mark"
+msgstr "E78: Ukjent merke"
+
+msgid "E79: Cannot expand wildcards"
+msgstr "E79: Klarte ikke utvide jokertegn"
+
+msgid "E591: 'winheight' cannot be smaller than 'winminheight'"
+msgstr "E591: 'winheight' kan ikke være mindre enn 'winminheight'"
+
+msgid "E592: 'winwidth' cannot be smaller than 'winminwidth'"
+msgstr "E592: 'winwidth' kan ikke være mindre enn 'winminwidth'"
+
+msgid "E80: Error while writing"
+msgstr "E80: Feil under skriving"
+
+msgid "Zero count"
+msgstr "Antall repeteringer er null"
+
+msgid "E81: Using <SID> not in a script context"
+msgstr "E81: Bruker <SID> utenom skript-kontekst"
+
+msgid "E449: Invalid expression received"
+msgstr "E449: Ugyldig uttrykk mottatt"
+
+msgid "E463: Region is guarded, cannot modify"
+msgstr "E463: Regionen er beskyttet og kan ikke modifiseres"
+
+msgid "E744: NetBeans does not allow changes in read-only files"
+msgstr "E744: NetBeans tillater ikke forandringer i skrivebeskyttede filer"
+
+#, c-format
+msgid "E685: Internal error: %s"
+msgstr "E685: Intern feil: %s"
+
+msgid "E363: pattern uses more memory than 'maxmempattern'"
+msgstr "E363: Søkestrengen bruker mer hukommelse enn 'maxmempattern'"
+
+msgid "E749: empty buffer"
+msgstr "E749: Tom buffer"
+
+msgid "E682: Invalid search pattern or delimiter"
+msgstr "E682: Ugyldig søkestreng eller skilletegn"
+
+msgid "E139: File is loaded in another buffer"
+msgstr "E139: Filen er lastet i en annen buffer"
+
+#, c-format
+msgid "E764: Option '%s' is not set"
+msgstr "E764: Valget '%s' er ikke satt"
+
+msgid "search hit TOP, continuing at BOTTOM"
+msgstr "Søket traff TOPPEN, fortsetter fra BUNNEN"
+
+msgid "search hit BOTTOM, continuing at TOP"
+msgstr "Søket traff BUNNEN, fortsetter fra TOPPEN"
diff --git a/src/po/nl.po b/src/po/nl.po
new file mode 100644
index 0000000000..4750d4dbb5
--- /dev/null
+++ b/src/po/nl.po
@@ -0,0 +1,5852 @@
+# Dutch 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.
+# Previous-Translator(s):
+# highlight: oplichten
+# Erwin Poeze <erwin.poeze@gmail.com>, 2011, 2012.
+msgid ""
+msgstr ""
+"Project-Id-Version: vim 7.3\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2011-05-29 07:43+0200\n"
+"PO-Revision-Date: 2012-03-28 08:07+0200\n"
+"Last-Translator: YOUR NAME <E-MAIL@ADDRESS>\n"
+"Language-Team: Dutch <vertaling@vrijschrift.nl>\n"
+"Language: nl\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() uitgevoerd met leeg wachtwoord"
+
+msgid "E820: sizeof(uint32_t) != 4"
+msgstr "E820: sizeof(uint32_t) != 4"
+
+msgid "E817: Blowfish big/little endian use wrong"
+msgstr "E817: gebruik Blowfish big/little endian is onjuist"
+
+msgid "E818: sha256 test failed"
+msgstr "E818: sha256 test mislukt"
+
+msgid "E819: Blowfish test failed"
+msgstr "E819: Blowfish test mislukt"
+
+msgid "E82: Cannot allocate any buffer, exiting..."
+msgstr "E82: kan geen buffer aanmaken, beëindigen..."
+
+msgid "E83: Cannot allocate buffer, using other one..."
+msgstr "E83: kan geen buffer aanmaken, een andere wordt gebruikt..."
+
+msgid "E515: No buffers were unloaded"
+msgstr "E515: geen van de buffers is gelost"
+
+msgid "E516: No buffers were deleted"
+msgstr "E516: geen van de buffers is verwijderd"
+
+msgid "E517: No buffers were wiped out"
+msgstr "E517: geen van de buffers is gewist"
+
+msgid "1 buffer unloaded"
+msgstr "1 buffer gelost"
+
+#, c-format
+msgid "%d buffers unloaded"
+msgstr "%d buffers gelost"
+
+msgid "1 buffer deleted"
+msgstr "1 buffer verwijderd"
+
+#, c-format
+msgid "%d buffers deleted"
+msgstr "%d buffers verwijderd"
+
+msgid "1 buffer wiped out"
+msgstr "1 buffer gewist"
+
+#, c-format
+msgid "%d buffers wiped out"
+msgstr "%d buffers gewist"
+
+msgid "E84: No modified buffer found"
+msgstr "E84: geen aangepast buffer gevonden"
+
+#. back where we started, didn't find anything.
+msgid "E85: There is no listed buffer"
+msgstr "E85: er is geen vermelde buffer"
+
+#, c-format
+msgid "E86: Buffer %ld does not exist"
+msgstr "E86: Buffer %ld bestaat niet"
+
+msgid "E87: Cannot go beyond last buffer"
+msgstr "E87: kan niet voorbij het laatste buffer komen"
+
+msgid "E88: Cannot go before first buffer"
+msgstr "E88: kan niet vóór het eerste buffer komen"
+
+#, c-format
+msgid "E89: No write since last change for buffer %ld (add ! to override)"
+msgstr "E89: niets opgeslagen sinds laatste wijziging van buffer %ld (voeg ! toe om te forceren)"
+
+msgid "E90: Cannot unload last buffer"
+msgstr "E90: kan laatste buffer niet legen"
+
+msgid "W14: Warning: List of file names overflow"
+msgstr "W14: waarschuwing: lijst met bestandsnamen is vol"
+
+#, c-format
+msgid "E92: Buffer %ld not found"
+msgstr "E92: buffer %ld niet gevonden"
+
+#, c-format
+msgid "E93: More than one match for %s"
+msgstr "E93: %s meermaals gevonden"
+
+#, c-format
+msgid "E94: No matching buffer for %s"
+msgstr "E94: geen overeenkomstig buffer voor %s"
+
+#, c-format
+msgid "line %ld"
+msgstr "regel %ld"
+
+msgid "E95: Buffer with this name already exists"
+msgstr "E95: buffer met deze naam bestaat al"
+
+msgid " [Modified]"
+msgstr " [Gewijzigd]"
+
+msgid "[Not edited]"
+msgstr "[Niet bewerkt]"
+
+msgid "[New file]"
+msgstr "[Nieuw bestand]"
+
+msgid "[Read errors]"
+msgstr "[Leesfouten]"
+
+msgid "[readonly]"
+msgstr "[alleen-lezen]"
+
+#, c-format
+msgid "1 line --%d%%--"
+msgstr "1 regel --%d%%--"
+
+#, c-format
+msgid "%ld lines --%d%%--"
+msgstr "%ld regels --%d%%--"
+
+#, c-format
+msgid "line %ld of %ld --%d%%-- col "
+msgstr "regel %ld van %ld --%d%%-- kol "
+
+msgid "[No Name]"
+msgstr "[Geen naam]"
+
+#. must be a help buffer
+msgid "help"
+msgstr "hulp"
+
+msgid "[Help]"
+msgstr "[Hulp]"
+
+msgid "[Preview]"
+msgstr "[Voorvertoning]"
+
+msgid "All"
+msgstr "Alles"
+
+msgid "Bot"
+msgstr "Bodem"
+
+msgid "Top"
+msgstr "Top"
+
+#, c-format
+msgid ""
+"\n"
+"# Buffer list:\n"
+msgstr ""
+"\n"
+"# Bufferlijst:\n"
+
+msgid "[Location List]"
+msgstr "[Locatielijst]"
+
+msgid "[Quickfix list]"
+msgstr "[Quickfix-lijst]"
+
+msgid "[Scratch]"
+msgstr "[Klad]"
+
+msgid ""
+"\n"
+"--- Signs ---"
+msgstr ""
+"\n"
+"--- Tekens ---"
+
+#, c-format
+msgid "Signs for %s:"
+msgstr "Tekens voor %s:"
+
+#, c-format
+msgid " line=%ld id=%d name=%s"
+msgstr " regel=%ld id=%d naam=%s"
+
+#, c-format
+msgid "E96: Can not diff more than %ld buffers"
+msgstr "E96: kan niet meer dan %ld buffers vergelijken"
+
+msgid "E810: Cannot read or write temp files"
+msgstr "E810: kan tijdelijke bestand niet lezen of opslaan"
+
+msgid "E97: Cannot create diffs"
+msgstr "E97: kan geen verschillen genereren"
+
+msgid "Patch file"
+msgstr "Patch-bestand"
+
+msgid "E816: Cannot read patch output"
+msgstr "E816: kan patch-uitvoer niet lezen"
+
+msgid "E98: Cannot read diff output"
+msgstr "E98: kan diff-uitvoer niet lezen"
+
+msgid "E99: Current buffer is not in diff mode"
+msgstr "E99: huidige buffer is niet in diff-modus"
+
+msgid "E793: No other buffer in diff mode is modifiable"
+msgstr "E793: geen ander buffer in diff-modus is bewerkbaar"
+
+msgid "E100: No other buffer in diff mode"
+msgstr "E100: geen ander buffer in diff-modus"
+
+msgid "E101: More than two buffers in diff mode, don't know which one to use"
+msgstr "E101: meer dan twee buffers in diff-modus, weet niet welke gebruikt moet worden"
+
+#, c-format
+msgid "E102: Can't find buffer \"%s\""
+msgstr "E102: kan buffer \"%s\" niet vinden"
+
+#, c-format
+msgid "E103: Buffer \"%s\" is not in diff mode"
+msgstr "E103: buffer \"%s\" is niet in diff-modus"
+
+msgid "E787: Buffer changed unexpectedly"
+msgstr "E787: buffer is onverwacht gewijzigd"
+
+msgid "E104: Escape not allowed in digraph"
+msgstr "E104: Escape in digraph niet toegestaan"
+
+msgid "E544: Keymap file not found"
+msgstr "E544: bestand met toetsbindingen niet gevonden"
+
+msgid "E105: Using :loadkeymap not in a sourced file"
+msgstr "E105: Gebruik van :loadkeymap niet in een 'sourced' bestand"
+
+msgid "E791: Empty keymap entry"
+msgstr "E791: toetsbinding leeg"
+
+msgid " Keyword completion (^N^P)"
+msgstr " trefwoordvoltooiing (^N^P)"
+
+#. ctrl_x_mode == 0, ^P/^N compl.
+msgid " ^X mode (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)"
+msgstr " ^X-modus (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)"
+
+msgid " Whole line completion (^L^N^P)"
+msgstr " gehele-regelvoltooiing (^L^N^P)"
+
+msgid " File name completion (^F^N^P)"
+msgstr " bestandsnaamvoltooiing (^F^N^P)"
+
+msgid " Tag completion (^]^N^P)"
+msgstr " tag-voltooiing (^]^N^P)"
+
+msgid " Path pattern completion (^N^P)"
+msgstr " Padpatroonvoltooiing (^N^P)"
+
+msgid " Definition completion (^D^N^P)"
+msgstr " definitievoltooiiing (^D^N^P)"
+
+msgid " Dictionary completion (^K^N^P)"
+msgstr " Dictionaryvoltooiing (^K^N^P)"
+
+msgid " Thesaurus completion (^T^N^P)"
+msgstr " Thesaurusvoltooiing (^T^N^P)"
+
+msgid " Command-line completion (^V^N^P)"
+msgstr " opdrachtregelvoltooiing (^V^N^P)"
+
+msgid " User defined completion (^U^N^P)"
+msgstr " gebruikergedefinieerde voltooiing (^U^N^P)"
+
+msgid " Omni completion (^O^N^P)"
+msgstr " omni-voltooiing (^O^N^P)"
+
+msgid " Spelling suggestion (s^N^P)"
+msgstr " spellingsuggestie (s^N^P)"
+
+msgid " Keyword Local completion (^N^P)"
+msgstr " lokaal-trefwoordvoltooiing (^N^P)"
+
+msgid "Hit end of paragraph"
+msgstr "Einde van paragraaf"
+
+msgid "'dictionary' option is empty"
+msgstr "'Dictionary'-optie is leeg"
+
+msgid "'thesaurus' option is empty"
+msgstr "'thesaurus'-optie is leeg"
+
+#, c-format
+msgid "Scanning dictionary: %s"
+msgstr "Doorzoeken Dictionary: %s"
+
+msgid " (insert) Scroll (^E/^Y)"
+msgstr " (invoegen) scroll (^E/^Y)"
+
+msgid " (replace) Scroll (^E/^Y)"
+msgstr " (vervangen) scroll (^E/^Y)"
+
+#, c-format
+msgid "Scanning: %s"
+msgstr "doorzoeken: %s"
+
+msgid "Scanning tags."
+msgstr "Doorzoeken tags."
+
+msgid " Adding"
+msgstr " toevoegen"
+
+#. 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.
+#.
+msgid "-- Searching..."
+msgstr "-- doorzoeken..."
+
+msgid "Back at original"
+msgstr "Terug naar origineel"
+
+msgid "Word from other line"
+msgstr "Woord uit andere regel"
+
+msgid "The only match"
+msgstr "Het enige resultaat"
+
+#, c-format
+msgid "match %d of %d"
+msgstr "resultaat %d van %d"
+
+#, c-format
+msgid "match %d"
+msgstr "resultaat %d"
+
+msgid "E18: Unexpected characters in :let"
+msgstr "E18: onverwachte tekens in :let"
+
+#, c-format
+msgid "E684: list index out of range: %ld"
+msgstr "E684: lijstindex buiten bereik: %ld"
+
+#, c-format
+msgid "E121: Undefined variable: %s"
+msgstr "E121: ongedefinieerde variabele: %s"
+
+msgid "E111: Missing ']'"
+msgstr "E111: ontbrekende ']'"
+
+#, c-format
+msgid "E686: Argument of %s must be a List"
+msgstr "E686: argument van %s moet een List zijn"
+
+#, c-format
+msgid "E712: Argument of %s must be a List or Dictionary"
+msgstr "E712: argument van %s moet een List of Dictionary zijn"
+
+msgid "E713: Cannot use empty key for Dictionary"
+msgstr "E713: kan geen leeg trefwoord als Dictionary gebruiken"
+
+msgid "E714: List required"
+msgstr "E714: List is vereist"
+
+msgid "E715: Dictionary required"
+msgstr "E715: Dictionary is vereist"
+
+#, c-format
+msgid "E118: Too many arguments for function: %s"
+msgstr "E118: te veel argumenten voor functie: %s"
+
+#, c-format
+msgid "E716: Key not present in Dictionary: %s"
+msgstr "E716: trefwoord niet aangetroffen in Dictionary: %s"
+
+#, c-format
+msgid "E122: Function %s already exists, add ! to replace it"
+msgstr "E122: function %s bestaat reeds, voeg ! toe om te vervangen"
+
+msgid "E717: Dictionary entry already exists"
+msgstr "E717: woord bestaat al in Dictionary"
+
+msgid "E718: Funcref required"
+msgstr "E718: Funcref is vereist"
+
+msgid "E719: Cannot use [:] with a Dictionary"
+msgstr "E719: kan [:] niet met een Dictionary gebruiken"
+
+#, c-format
+msgid "E734: Wrong variable type for %s="
+msgstr "E734: onjuist type variabele voor %s="
+
+#, c-format
+msgid "E130: Unknown function: %s"
+msgstr "E130: onbekende functie: %s"
+
+#, c-format
+msgid "E461: Illegal variable name: %s"
+msgstr "E461: ongeldige variabelenaam: %s"
+
+msgid "E687: Less targets than List items"
+msgstr "E687: minder doelen dan Listitems"
+
+msgid "E688: More targets than List items"
+msgstr "E688: meer doelen dan Listitems"
+
+msgid "Double ; in list of variables"
+msgstr "Dubbele ; in variabelenlijst"
+
+#, c-format
+msgid "E738: Can't list variables for %s"
+msgstr "E738: kan variabelen voor %s niet tonen"
+
+msgid "E689: Can only index a List or Dictionary"
+msgstr "E689: alleen een List of Dictionary kan geïndexeerd worden"
+
+msgid "E708: [:] must come last"
+msgstr "E708: [:] moet als laatste staan"
+
+msgid "E709: [:] requires a List value"
+msgstr "E709: [:] vereist een Listwaarde"
+
+msgid "E710: List value has more items than target"
+msgstr "E710: Listwaarde heeft meer value has more items than target"
+
+msgid "E711: List value has not enough items"
+msgstr "E711: Listwaarde heeft onvoldoende items"
+
+msgid "E690: Missing \"in\" after :for"
+msgstr "E690: \"in\" ontbreekt na :for"
+
+#, c-format
+msgid "E107: Missing parentheses: %s"
+msgstr "E107: ontbrekende haakjes: %s"
+
+#, c-format
+msgid "E108: No such variable: \"%s\""
+msgstr "E108: onbekende variabele: \"%s\""
+
+msgid "E743: variable nested too deep for (un)lock"
+msgstr "E743: variabele is te diep genest om te beveiligen"
+
+msgid "E109: Missing ':' after '?'"
+msgstr "E109: ':' ontbreekt na '?'"
+
+msgid "E691: Can only compare List with List"
+msgstr "E691: List kan alleen met een Lijst worden vergeleken"
+
+msgid "E692: Invalid operation for Lists"
+msgstr "E692: ongeldige bewerking voor Listen"
+
+msgid "E735: Can only compare Dictionary with Dictionary"
+msgstr "E735: Dictionary kan alleen met Woordenboek worden vergeleken"
+
+msgid "E736: Invalid operation for Dictionary"
+msgstr "E736: ongeldige bewerking voor Dictionary"
+
+msgid "E693: Can only compare Funcref with Funcref"
+msgstr "E693: Funcref kan alleen met Funcref worden vergeleken"
+
+msgid "E694: Invalid operation for Funcrefs"
+msgstr "E694: ongeldige bewerking voor Funcrefs"
+
+msgid "E804: Cannot use '%' with Float"
+msgstr "E804: '%' kan niet met Float worden gebruikt"
+
+msgid "E110: Missing ')'"
+msgstr "E110: ')' ontbreekt"
+
+msgid "E695: Cannot index a Funcref"
+msgstr "E695: een Funcref kan niet geïndexeerd worden"
+
+#, c-format
+msgid "E112: Option name missing: %s"
+msgstr "E112: optienaam ontbreekt: %s"
+
+#, c-format
+msgid "E113: Unknown option: %s"
+msgstr "E113: onbekende optie: %s"
+
+#, c-format
+msgid "E114: Missing quote: %s"
+msgstr "E114: ontbrekend aanhaalteken: %s"
+
+#, c-format
+msgid "E115: Missing quote: %s"
+msgstr "E115: ontbrekend aanhaalteken: %s"
+
+#, c-format
+msgid "E696: Missing comma in List: %s"
+msgstr "E696: komma ontbreekt in List: %s"
+
+#, c-format
+msgid "E697: Missing end of List ']': %s"
+msgstr "E697: einde van List ']' ontbreekt: %s"
+
+#, c-format
+msgid "E720: Missing colon in Dictionary: %s"
+msgstr "E720: dubbelepunt in Dictionary ontbreekt: %s"
+
+#, c-format
+msgid "E721: Duplicate key in Dictionary: \"%s\""
+msgstr "E721: dubbele sleutel in Dictionary: \"%s\""
+
+#, c-format
+msgid "E722: Missing comma in Dictionary: %s"
+msgstr "E722: komma ontbreekt in Dictionary: %s"
+
+#, c-format
+msgid "E723: Missing end of Dictionary '}': %s"
+msgstr "E723: einde van Dictionary '}' ontbreekt: %s"
+
+msgid "E724: variable nested too deep for displaying"
+msgstr "E724: variabele is te diep genest om te tonen"
+
+#, c-format
+msgid "E740: Too many arguments for function %s"
+msgstr "E740: teveel argumenten voor functie %s"
+
+#, c-format
+msgid "E116: Invalid arguments for function %s"
+msgstr "E116: ongeldige argumenten voor functie %s"
+
+#, c-format
+msgid "E117: Unknown function: %s"
+msgstr "E117: onbekende functie: %s"
+
+#, c-format
+msgid "E119: Not enough arguments for function: %s"
+msgstr "E119: onvoldoende argumenten voor functie: %s"
+
+#, c-format
+msgid "E120: Using <SID> not in a script context: %s"
+msgstr "E120: gebruik van <SID> buiten een scriptcontext: %s"
+
+#, c-format
+msgid "E725: Calling dict function without Dictionary: %s"
+msgstr "E725: dict-functie aanroep zonder Dictionary: %s"
+
+msgid "E808: Number or Float required"
+msgstr "E808: Number of Float vereist"
+
+msgid "E699: Too many arguments"
+msgstr "E699:teveel argumenten"
+
+msgid "E785: complete() can only be used in Insert mode"
+msgstr "E785: complete() kan alleen in Invoegmodus worden gebruikt"
+
+#.
+#. * 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"
+
+#, c-format
+msgid "E737: Key already exists: %s"
+msgstr "E737: sleutel bestaat al: %s"
+
+#, c-format
+msgid "+-%s%3ld lines: "
+msgstr "+-%s%3ld regels: "
+
+#, c-format
+msgid "E700: Unknown function: %s"
+msgstr "E700: onbekende functie: %s"
+
+msgid ""
+"&OK\n"
+"&Cancel"
+msgstr ""
+"&OK\n"
+"&Annuleren"
+
+msgid "called inputrestore() more often than inputsave()"
+msgstr "inputrestore() vaker aangeroepen dan inputsave()"
+
+msgid "E786: Range not allowed"
+msgstr "E786: bereik niet toegestaan"
+
+msgid "E701: Invalid type for len()"
+msgstr "E701: ongeldig type voor len()"
+
+msgid "E726: Stride is zero"
+msgstr "E726: stap is nul"
+
+msgid "E727: Start past end"
+msgstr "E727: start na einde"
+
+msgid "<empty>"
+msgstr "<leeg>"
+
+msgid "E240: No connection to Vim server"
+msgstr "E240: geen verbinding met Vim-server"
+
+#, c-format
+msgid "E241: Unable to send to %s"
+msgstr "E241: verzenden naar %s onmogelijk"
+
+msgid "E277: Unable to read a server reply"
+msgstr "E277: lezen van serverantwoord onmogelijk"
+
+msgid "E655: Too many symbolic links (cycle?)"
+msgstr "E655: teveel symbolische koppelingen (oneindige lus?)"
+
+msgid "E258: Unable to send to client"
+msgstr "E258: verzenden nar client onmogelijk"
+
+msgid "E702: Sort compare function failed"
+msgstr "E702: sorteer-vergelijkfunctie mislukt"
+
+msgid "(Invalid)"
+msgstr "(ongeldig)"
+
+msgid "E677: Error writing temp file"
+msgstr "E677: opslaan van temp-bestand is mislukt"
+
+msgid "E805: Using a Float as a Number"
+msgstr "E805: een Float wordt als Number gebruikt"
+
+msgid "E703: Using a Funcref as a Number"
+msgstr "E703: een Funcref wordt als Number gebruikt"
+
+msgid "E745: Using a List as a Number"
+msgstr "E745: List wordt als een Number gebruikt"
+
+msgid "E728: Using a Dictionary as a Number"
+msgstr "E728: Dictionary gebruiken als een Number"
+
+msgid "E729: using Funcref as a String"
+msgstr "E729: Funcref gebruiken als een String"
+
+msgid "E730: using List as a String"
+msgstr "E730: List gebruiken als een String"
+
+msgid "E731: using Dictionary as a String"
+msgstr "E731: Dictionary gebruiken als een String"
+
+msgid "E806: using Float as a String"
+msgstr "E806: Float gebruiken als een String"
+
+#, c-format
+msgid "E704: Funcref variable name must start with a capital: %s"
+msgstr "E704: variabelenaam van Funcref moet beginnen met een hoofdletter: %s"
+
+#, c-format
+msgid "E705: Variable name conflicts with existing function: %s"
+msgstr "E705: variablenaam botst met bestaande functie: %s"
+
+#, c-format
+msgid "E706: Variable type mismatch for: %s"
+msgstr "E706: variabelesoort past niet bij: %s"
+
+#, c-format
+msgid "E795: Cannot delete variable %s"
+msgstr "E795: kan variabele %s niet verwijderen"
+
+#, c-format
+msgid "E741: Value is locked: %s"
+msgstr "E741: waarde is geblokkeerd: %s"
+
+msgid "Unknown"
+msgstr "Onbekend"
+
+#, c-format
+msgid "E742: Cannot change value of %s"
+msgstr "E742: kan waarde van %s niet veranderen"
+
+msgid "E698: variable nested too deep for making a copy"
+msgstr "E698: variabele te diep genest om een kopie te maken"
+
+#, c-format
+msgid "E123: Undefined function: %s"
+msgstr "E123: ongedefinieerde functie: %s"
+
+#, c-format
+msgid "E124: Missing '(': %s"
+msgstr "E124: ontbrekende '(': %s"
+
+#, c-format
+msgid "E125: Illegal argument: %s"
+msgstr "E125: ongeldig argument: %s"
+
+msgid "E126: Missing :endfunction"
+msgstr "E126: ontbrekende :endfunction"
+
+#, c-format
+msgid "E707: Function name conflicts with variable: %s"
+msgstr "E707: functienaam botst met variabele: %s"
+
+#, c-format
+msgid "E127: Cannot redefine function %s: It is in use"
+msgstr "E127: kan functie %s niet opnieuw definiëren, het is in gebruik"
+
+#, c-format
+msgid "E746: Function name does not match script file name: %s"
+msgstr "E746: functienaam komt niet overeen met bestandsnaam van het script: %s"
+
+msgid "E129: Function name required"
+msgstr "E129: functienaam is vereist"
+
+#, c-format
+msgid "E128: Function name must start with a capital or contain a colon: %s"
+msgstr "E128: functionnaam moet met een hoofdletter beginnen of een dubbelepunt bevatten: %s"
+
+#, c-format
+msgid "E131: Cannot delete function %s: It is in use"
+msgstr "E131: functie %s wordt gebruikt en kan niet worden verwijderd"
+
+msgid "E132: Function call depth is higher than 'maxfuncdepth'"
+msgstr "E132: diepte functieaanroep overstijgt 'maxfuncdepth'"
+
+#, c-format
+msgid "calling %s"
+msgstr "%s aanroepen"
+
+#, c-format
+msgid "%s aborted"
+msgstr "%s afgebroken"
+
+#, c-format
+msgid "%s returning #%ld"
+msgstr "%s komt terug met de waarde #%ld"
+
+#, c-format
+msgid "%s returning %s"
+msgstr "%s komt terug met de waarde %s"
+
+#, c-format
+msgid "continuing in %s"
+msgstr "voortzetten in %s"
+
+msgid "E133: :return not inside a function"
+msgstr "E133: :return niet binnen een functie"
+
+msgid ""
+"\n"
+"# global variables:\n"
+msgstr ""
+"\n"
+"# globale variabelen:\n"
+
+msgid ""
+"\n"
+"\tLast set from "
+msgstr ""
+"\n"
+"\tLaatst ingesteld door "
+
+msgid "No old files"
+msgstr "Geen oudere bestanden"
+
+#, 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, 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: verplaats regels in zichzelf"
+
+msgid "1 line moved"
+msgstr "1 regel verplaatst"
+
+#, c-format
+msgid "%ld lines moved"
+msgstr "%ld regels verplaatst"
+
+#, c-format
+msgid "%ld lines filtered"
+msgstr "%ld regels gefilterd"
+
+msgid "E135: *Filter* Autocommands must not change current buffer"
+msgstr "E135: *Filter* Autocommands mogen huidige buffer niet wijzigen"
+
+msgid "[No write since last change]\n"
+msgstr "[Niets opgeslagen sinds laatste wijziging]\n"
+
+#, c-format
+msgid "%sviminfo: %s in line: "
+msgstr "%sviminfo: %s in regel: "
+
+msgid "E136: viminfo: Too many errors, skipping rest of file"
+msgstr "E136: viminfo: teveel fouten, restand van bestand overgeslagen"
+
+#, c-format
+msgid "Reading viminfo file \"%s\"%s%s%s"
+msgstr "Inlezen viminfo-bestand \"%s\"%s%s%s"
+
+msgid " info"
+msgstr " info"
+
+msgid " marks"
+msgstr " markering"
+
+msgid " oldfiles"
+msgstr " oud-bestanden"
+
+msgid " FAILED"
+msgstr " MISLUKT"
+
+#. avoid a wait_return for this message, it's annoying
+#, c-format
+msgid "E137: Viminfo file is not writable: %s"
+msgstr "E137: viminfo-bestand is niet schrijfbaar: %s"
+
+#, c-format
+msgid "E138: Can't write viminfo file %s!"
+msgstr "E138: kan niet naar viminfo-bestand %s schrijven!"
+
+#, c-format
+msgid "Writing viminfo file \"%s\""
+msgstr "viminfo-bestand \"%s\" opslaan"
+
+#. Write the info:
+#, c-format
+msgid "# This viminfo file was generated by Vim %s.\n"
+msgstr "# Dit viminfo-bestand is aangemaakt door Vim %s.\n"
+
+#, c-format
+msgid ""
+"# You may edit it if you're careful!\n"
+"\n"
+msgstr ""
+"# Bewerken is toegestaan, maar doe het met aandacht!\n"
+"\n"
+
+#, c-format
+msgid "# Value of 'encoding' when this file was written\n"
+msgstr "# Waarde van 'encoding' bij het opslaan van dit bestand\n"
+
+msgid "Illegal starting char"
+msgstr "Ongeldig startteken"
+
+msgid "Save As"
+msgstr "Opslaan als"
+
+msgid "Write partial file?"
+msgstr "Gedeeltelijk bestand opslaan?"
+
+msgid "E140: Use ! to write partial buffer"
+msgstr "E140: gebruik ! om gedeeltelijk buffer op te slaan"
+
+#, c-format
+msgid "Overwrite existing file \"%s\"?"
+msgstr "Bestaand bestand \"%s\" overschrijven?"
+
+#, c-format
+msgid "Swap file \"%s\" exists, overwrite anyway?"
+msgstr "Wisselbestand \"%s\" bestaat, toch overschrijven?"
+
+#, c-format
+msgid "E768: Swap file exists: %s (:silent! overrides)"
+msgstr "E768: wisselbestand bestaat: %s (:silent! overschrijft)"
+
+#, c-format
+msgid "E141: No file name for buffer %ld"
+msgstr "E141: buffer %ld heeft geen bestandsnaam"
+
+msgid "E142: File not written: Writing is disabled by 'write' option"
+msgstr "E142: bestand is niet opgeslagen: opslaan is uitgeschakeld door 'write'-optie"
+
+#, c-format
+msgid ""
+"'readonly' option is set for \"%s\".\n"
+"Do you wish to write anyway?"
+msgstr ""
+"'alleen-lezen'-optie is inschakeld voor \"%s\".\n"
+"Toch opslaan?"
+
+#, 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 ""
+"Bestandsrechten van \"%s\" zijn alleen-lezen.\n"
+"Mogelijk kan er toch naar weggeschreven worden.\n"
+"Proberen op te slaan?"
+
+#, c-format
+msgid "E505: \"%s\" is read-only (add ! to override)"
+msgstr "E505: \"%s\" is alleen-lezen (voeg ! toe om te overschrijven)"
+
+msgid "Edit File"
+msgstr "Bestand bewerken"
+
+#, c-format
+msgid "E143: Autocommands unexpectedly deleted new buffer %s"
+msgstr "E143: 'Autocommands' hebben het nieuwe buffer %s onverwacht verwijderd"
+
+msgid "E144: non-numeric argument to :z"
+msgstr "E144: niet-numeriek argument voor :z"
+
+msgid "E145: Shell commands not allowed in rvim"
+msgstr "E145: in rvim zijn shell-opdrachten zijn niet toegestaan"
+
+msgid "E146: Regular expressions can't be delimited by letters"
+msgstr "E146: reguliere expressies kunnen niet begrensd worden door letters"
+
+#, c-format
+msgid "replace with %s (y/n/a/q/l/^E/^Y)?"
+msgstr "vervang door %s (y/n/a/q/l/^E/^Y)?"
+
+msgid "(Interrupted) "
+msgstr "(Onderbroken) "
+
+msgid "1 match"
+msgstr "1 overeenkomst"
+
+msgid "1 substitution"
+msgstr "1 vervanging"
+
+#, c-format
+msgid "%ld matches"
+msgstr "%ld overeenkomsten"
+
+#, c-format
+msgid "%ld substitutions"
+msgstr "%ld vervangingen"
+
+msgid " on 1 line"
+msgstr " op 1 regel"
+
+#, c-format
+msgid " on %ld lines"
+msgstr " op %ld regels"
+
+msgid "E147: Cannot do :global recursive"
+msgstr "E147: kan :global niet recursief uitvoeren"
+
+msgid "E148: Regular expression missing from global"
+msgstr "E148: reguliere expressies ontbreken bij global"
+
+#, c-format
+msgid "Pattern found in every line: %s"
+msgstr "Patroon aangetroffen in iedere regel: %s"
+
+#, c-format
+msgid ""
+"\n"
+"# Last Substitute String:\n"
+"$"
+msgstr ""
+"\n"
+"# Laatst vervangingsstring:\n"
+"$"
+
+msgid "E478: Don't panic!"
+msgstr "E478: geen paniek!"
+
+#, c-format
+msgid "E661: Sorry, no '%s' help for %s"
+msgstr "E661: helaas, geen '%s'-hulp voor %s"
+
+#, c-format
+msgid "E149: Sorry, no help for %s"
+msgstr "E149: helaas, geen hulp voor %s"
+
+#, c-format
+msgid "Sorry, help file \"%s\" not found"
+msgstr "helaas, hulpbestand \"%s\" is niet gevonden"
+
+#, c-format
+msgid "E150: Not a directory: %s"
+msgstr "E150: geen map: %s"
+
+#, c-format
+msgid "E152: Cannot open %s for writing"
+msgstr "E152: kan %s niet openen om naar te schrijven"
+
+#, c-format
+msgid "E153: Unable to open %s for reading"
+msgstr "E153: kan %s niet openen om uit te lezen"
+
+#, c-format
+msgid "E670: Mix of help file encodings within a language: %s"
+msgstr "E670: mengelmoes van hulpbestandcoderingen binnen een taal: %s"
+
+#, c-format
+msgid "E154: Duplicate tag \"%s\" in file %s/%s"
+msgstr "E154: dubbele tag \"%s\" in bestand %s/%s"
+
+#, c-format
+msgid "E160: Unknown sign command: %s"
+msgstr "E160: onbekende opdracht voor margetekens: %s"
+
+msgid "E156: Missing sign name"
+msgstr "E156: ontbrekende naam margeteken"
+
+msgid "E612: Too many signs defined"
+msgstr "E612: teveel margetekens gedefinieerd"
+
+#, c-format
+msgid "E239: Invalid sign text: %s"
+msgstr "E239: ongeldige tekst margeteken: %s"
+
+#, c-format
+msgid "E155: Unknown sign: %s"
+msgstr "E155: onbekend margeteken: %s"
+
+msgid "E159: Missing sign number"
+msgstr "E159: ontbrekend nummer margeteken"
+
+#, c-format
+msgid "E158: Invalid buffer name: %s"
+msgstr "E158: ongeldige buffernaam: %s"
+
+#, c-format
+msgid "E157: Invalid sign ID: %ld"
+msgstr "E157: ongeldige id margeteken: %ld"
+
+msgid " (NOT FOUND)"
+msgstr " (NIET GEVONDEN)"
+
+msgid " (not supported)"
+msgstr "(niet ondersteund)"
+
+msgid "[Deleted]"
+msgstr "[Verwijderd]"
+
+msgid "Entering Debug mode. Type \"cont\" to continue."
+msgstr "Debug-modus gestart. Typ \"cont\" om verder te gaan."
+
+#, c-format
+msgid "line %ld: %s"
+msgstr "regel %ld: %s"
+
+#, c-format
+msgid "cmd: %s"
+msgstr "cmd: %s"
+
+#, c-format
+msgid "Breakpoint in \"%s%s\" line %ld"
+msgstr "'Breakpoint' in \"%s%s\" regel %ld"
+
+#, c-format
+msgid "E161: Breakpoint not found: %s"
+msgstr "E161: 'Breakpoint' niet gevonden: %s"
+
+msgid "No breakpoints defined"
+msgstr "Geen 'breakpoints' opgegeven"
+
+#, c-format
+msgid "%3d %s %s line %ld"
+msgstr "%3d %s %s regel %ld"
+
+msgid "E750: First use \":profile start {fname}\""
+msgstr "E750: gebruik eerst \":profile start {fname}\""
+
+#, c-format
+msgid "Save changes to \"%s\"?"
+msgstr "veranderingen opslaan in \"%s\"?"
+
+msgid "Untitled"
+msgstr "naamloos"
+
+#, c-format
+msgid "E162: No write since last change for buffer \"%s\""
+msgstr "E162: niets opgeslagen sinds laatste wijziging van buffer \"%s\""
+
+msgid "Warning: Entered other buffer unexpectedly (check autocommands)"
+msgstr "Waarschuwing: onverwacht ander buffer binnengegaan (controleer 'autocommands')"
+
+msgid "E163: There is only one file to edit"
+msgstr "E163: slechts een bestand beschikbaar voor bewerking"
+
+msgid "E164: Cannot go before first file"
+msgstr "E164: kan niet verder terug dan eerste bestand"
+
+msgid "E165: Cannot go beyond last file"
+msgstr "E165: kan niet verder dan laatste bestand"
+
+#, c-format
+msgid "E666: compiler not supported: %s"
+msgstr "E666: compiler niet ondersteund: %s"
+
+#, c-format
+msgid "Searching for \"%s\" in \"%s\""
+msgstr "Naar \"%s\" in \"%s\" zoeken"
+
+#, c-format
+msgid "Searching for \"%s\""
+msgstr "Naar \"%s\" zoeken"
+
+#, c-format
+msgid "not found in 'runtimepath': \"%s\""
+msgstr "niet gevonden in 'runtimepath': \"%s\""
+
+msgid "Source Vim script"
+msgstr "Vim-script laden"
+
+#, c-format
+msgid "Cannot source a directory: \"%s\""
+msgstr "kan geen map laden: \"%s\""
+
+#, c-format
+msgid "could not source \"%s\""
+msgstr "kan \"%s\" niet laden"
+
+#, c-format
+msgid "line %ld: could not source \"%s\""
+msgstr "regel %ld: kan \"%s\" niet laden"
+
+#, c-format
+msgid "sourcing \"%s\""
+msgstr "\"%s\" laden"
+
+#, c-format
+msgid "line %ld: sourcing \"%s\""
+msgstr "regel %ld: \"%s\" laden"
+
+#, c-format
+msgid "finished sourcing %s"
+msgstr "laden van %s afgerond"
+
+msgid "modeline"
+msgstr "modusregel"
+
+msgid "--cmd argument"
+msgstr "argument van --cmd"
+
+msgid "-c argument"
+msgstr "argument van -c"
+
+msgid "environment variable"
+msgstr "omgevingsvariabele"
+
+msgid "error handler"
+msgstr "foutafhandeling"
+
+msgid "W15: Warning: Wrong line separator, ^M may be missing"
+msgstr "W15: waarschuwing: ongeldige regelscheiding, ^M kan ontbreken"
+
+msgid "E167: :scriptencoding used outside of a sourced file"
+msgstr "E167: :scriptencoding buiten een geladen bestand gebruikt"
+
+msgid "E168: :finish used outside of a sourced file"
+msgstr "E168: :finish buiten een geladen bestand gebruikt"
+
+#, c-format
+msgid "Current %slanguage: \"%s\""
+msgstr "Huidige %s-taal: \"%s\""
+
+#, c-format
+msgid "E197: Cannot set language to \"%s\""
+msgstr "E197: taal kan niet ingesteld worden op \"%s\""
+
+msgid "Entering Ex mode. Type \"visual\" to go to Normal mode."
+msgstr "Ex-modus betreden. Typ \"visual\" om naar de Normaal-modus te gaan."
+
+msgid "E501: At end-of-file"
+msgstr "E501: bij bestandseinde"
+
+msgid "E169: Command too recursive"
+msgstr "E169: opdracht te recursief"
+
+#, c-format
+msgid "E605: Exception not caught: %s"
+msgstr "E605: uitzondering niet afgevangen: %s"
+
+msgid "End of sourced file"
+msgstr "Einde van geladen bestand"
+
+msgid "End of function"
+msgstr "Einde van functie"
+
+msgid "E464: Ambiguous use of user-defined command"
+msgstr "E464: dubbelzinnig gebruik van gebruikergedefinieerde opdracht"
+
+msgid "E492: Not an editor command"
+msgstr "E492: geen editor-opdracht"
+
+msgid "E493: Backwards range given"
+msgstr "E493: Teruggaand bereik opgegeven"
+
+msgid "Backwards range given, OK to swap"
+msgstr "Teruggaand bereik opgegeven, wisselen is toegestaan"
+
+msgid "E494: Use w or w>>"
+msgstr "E494: w of w>> gebruiken"
+
+msgid "E319: Sorry, the command is not available in this version"
+msgstr "E319: Helaas, in deze versie is de opdracht niet beschikbaar"
+
+msgid "E172: Only one file name allowed"
+msgstr "E172: slechts een bestandsnaam toegestaan"
+
+msgid "1 more file to edit. Quit anyway?"
+msgstr "1 bestand wacht nog op bewerking. Toch stoppen?"
+
+#, c-format
+msgid "%d more files to edit. Quit anyway?"
+msgstr "%d bestanden wachten nog op bewerking. Toch stoppen?"
+
+msgid "E173: 1 more file to edit"
+msgstr "E173: 1 bestand wacht op bewerking"
+
+#, c-format
+msgid "E173: %ld more files to edit"
+msgstr "E173: %ld bestanden wachten op bewerking"
+
+msgid "E174: Command already exists: add ! to replace it"
+msgstr "E174: opdracht bestaat al: voeg ! toe om het te vervangen"
+
+msgid ""
+"\n"
+" Name Args Range Complete Definition"
+msgstr ""
+"\n"
+" Naam Args Berk. Compleet Definitie"
+
+msgid "No user-defined commands found"
+msgstr "Geen gebruikergedefinieerde opdrachten gevonden"
+
+msgid "E175: No attribute specified"
+msgstr "E175: geen attribute opgegeven"
+
+msgid "E176: Invalid number of arguments"
+msgstr "E176: ongeldig aantal argumenten"
+
+msgid "E177: Count cannot be specified twice"
+msgstr "E177: aantal kan niet tweemaal worden opgegeven"
+
+msgid "E178: Invalid default value for count"
+msgstr "E178: ongeldige standaardwaarde voor aantal"
+
+msgid "E179: argument required for -complete"
+msgstr "E179: argument vereist voor -complete"
+
+#, c-format
+msgid "E181: Invalid attribute: %s"
+msgstr "E181: ongeldig attribute: %s"
+
+msgid "E182: Invalid command name"
+msgstr "E182: ongeldige opdrachtnaam"
+
+msgid "E183: User defined commands must start with an uppercase letter"
+msgstr "E183: door gebruiker gedefinieerde opdrachten moet een een hoofdletter beginnen"
+
+#, c-format
+msgid "E184: No such user-defined command: %s"
+msgstr "E184: deze door gebruiker gedefinieerde opdracht bestaat niet: %s"
+
+#, c-format
+msgid "E180: Invalid complete value: %s"
+msgstr "E180: ongeldige voltooiingswaarde: %s"
+
+msgid "E468: Completion argument only allowed for custom completion"
+msgstr "E468: argument voor voltooiing alleen toegestaan bij aangepaste voltooiing"
+
+msgid "E467: Custom completion requires a function argument"
+msgstr "E467: aangepaste voltooiing vereist een functieargument"
+
+msgid "unknown"
+msgstr "onbekend"
+
+#, c-format
+msgid "E185: Cannot find color scheme %s"
+msgstr "E185: kan kleurenschema %s niet vinden"
+
+msgid "Greetings, Vim user!"
+msgstr "Gegroet, Vim-gebruiker!"
+
+msgid "E784: Cannot close last tab page"
+msgstr "E784: laatste tabpagina kan niet afgesloten worden"
+
+msgid "Already only one tab page"
+msgstr "Reeds beperkt tot één tabpagina"
+
+msgid "Edit File in new window"
+msgstr "Bestand in nieuw venster bewerken"
+
+#, c-format
+msgid "Tab page %d"
+msgstr "Tabpagina %d"
+
+msgid "No swap file"
+msgstr "Geen wisselbestand"
+
+msgid "Append File"
+msgstr "Bestand toevoegen"
+
+msgid "E747: Cannot change directory, buffer is modified (add ! to override)"
+msgstr "E747: kan niet van map veranderen, buffer is gewijzigd (voeg ! toe om te forceren)"
+
+msgid "E186: No previous directory"
+msgstr "E186: geen voorgaande map"
+
+msgid "E187: Unknown"
+msgstr "E187: onbekend"
+
+msgid "E465: :winsize requires two number arguments"
+msgstr "E465: :winsize vereist twee getallen als argument"
+
+#, c-format
+msgid "Window position: X %d, Y %d"
+msgstr "Vensterpositie: X %d, Y %d"
+
+msgid "E188: Obtaining window position not implemented for this platform"
+msgstr "E188: verkrijgen van vensterpositie is voor dit platform niet geïmplementeerd"
+
+msgid "E466: :winpos requires two number arguments"
+msgstr "E466: :winpos vereist twee getallen als argument"
+
+msgid "Save Redirection"
+msgstr "'Redirection' opslaan"
+
+msgid "Save View"
+msgstr "Beeld opslaan"
+
+msgid "Save Session"
+msgstr "Sessie opslaan"
+
+msgid "Save Setup"
+msgstr "Instellingen opslaan"
+
+#, c-format
+msgid "E739: Cannot create directory: %s"
+msgstr "E739: kan map %s niet aanmaken"
+
+#, c-format
+msgid "E189: \"%s\" exists (add ! to override)"
+msgstr "E189: \"%s\" bestaat al (voeg ! toe om te forceren)"
+
+#, c-format
+msgid "E190: Cannot open \"%s\" for writing"
+msgstr "E190: \"%s\" kan niet worden beschreven"
+
+#. set mark
+msgid "E191: Argument must be a letter or forward/backward quote"
+msgstr "E191: argument moet een letter zijn of een aanhaalteken, voor of achterwaarts"
+
+msgid "E192: Recursive use of :normal too deep"
+msgstr "E192: recursief gebruik van :normal gaat te diep"
+
+msgid "E809: #< is not available without the +eval feature"
+msgstr "E809: #< is zonder de +eval-functionaliteit niet beschikbaar"
+
+msgid "E194: No alternate file name to substitute for '#'"
+msgstr "E194: er is geen wisselende bestandsnaam beschikbaar om '#' te vervangen"
+
+msgid "E495: no autocommand file name to substitute for \"<afile>\""
+msgstr "E495: er is geen 'autocommand'-bestandsnaam om \"<afile>\" te vervangen"
+
+msgid "E496: no autocommand buffer number to substitute for \"<abuf>\""
+msgstr "E496: er is geen 'autocommand'-buffernummer om \"<abuf>\" te vervangen"
+
+msgid "E497: no autocommand match name to substitute for \"<amatch>\""
+msgstr "E497: er is geen 'autocommand'-naamovereenkomst om \"<amatch>\" te vervangen"
+
+msgid "E498: no :source file name to substitute for \"<sfile>\""
+msgstr "E498: er is geen :source-bestandsnaam om \"<sfile>\" te vervangen"
+
+#, no-c-format
+msgid "E499: Empty file name for '%' or '#', only works with \":p:h\""
+msgstr "E499: lege bestandsnaam voor '%' of '#', werkt alleen samen met \":p:h\""
+
+msgid "E500: Evaluates to an empty string"
+msgstr "E500: resulteert in een lege string"
+
+msgid "E195: Cannot open viminfo file for reading"
+msgstr "E195: het 'viminfo'-bestand kan niet worden gelezen"
+
+msgid "E196: No digraphs in this version"
+msgstr "E196: deze versie bevat geen 'digraphs'"
+
+msgid "E608: Cannot :throw exceptions with 'Vim' prefix"
+msgstr "E608: :throw exceptions met 'Vim' als voorvoegsel zijn niet mogelijk"
+
+#. always scroll up, don't overwrite
+#, c-format
+msgid "Exception thrown: %s"
+msgstr "Geworpen uitzondering: %s"
+
+#, c-format
+msgid "Exception finished: %s"
+msgstr "Afgeronde uitzondering: %s"
+
+#, c-format
+msgid "Exception discarded: %s"
+msgstr "Afgedankte uitzondering: %s"
+
+#, c-format
+msgid "%s, line %ld"
+msgstr "%s, regel %ld"
+
+#. always scroll up, don't overwrite
+#, c-format
+msgid "Exception caught: %s"
+msgstr "Gevangen uitzondering: %s"
+
+#, c-format
+msgid "%s made pending"
+msgstr "%s aanhanging gemaakt"
+
+#, c-format
+msgid "%s resumed"
+msgstr "%s voortgezet"
+
+#, c-format
+msgid "%s discarded"
+msgstr "%s afgedankt"
+
+msgid "Exception"
+msgstr "Uitzondering"
+
+msgid "Error and interrupt"
+msgstr "Fout en onderbreken"
+
+msgid "Error"
+msgstr "Fout"
+
+#. if (pending & CSTP_INTERRUPT)
+msgid "Interrupt"
+msgstr "Onderbreken"
+
+msgid "E579: :if nesting too deep"
+msgstr "E579: te diepe :if-nesting"
+
+msgid "E580: :endif without :if"
+msgstr "E580: :endif zonder :if"
+
+msgid "E581: :else without :if"
+msgstr "E581: :else zonder :if"
+
+msgid "E582: :elseif without :if"
+msgstr "E582: :elseif zonder :if"
+
+msgid "E583: multiple :else"
+msgstr "E583: meerdere :else"
+
+msgid "E584: :elseif after :else"
+msgstr "E584: :elseif na :else"
+
+msgid "E585: :while/:for nesting too deep"
+msgstr "E585: te diepe :while/:for-nesting"
+
+msgid "E586: :continue without :while or :for"
+msgstr "E586: :continue zonder :while of :for"
+
+msgid "E587: :break without :while or :for"
+msgstr "E587: :break zonder :while of :for"
+
+msgid "E732: Using :endfor with :while"
+msgstr "E732: gebruik van :endfor met :while"
+
+msgid "E733: Using :endwhile with :for"
+msgstr "E733: gebruik van :endwhile met :for"
+
+msgid "E601: :try nesting too deep"
+msgstr "E601: te diepe :try-nesting"
+
+msgid "E603: :catch without :try"
+msgstr "E603: :catch zonder :try"
+
+#. Give up for a ":catch" after ":finally" and ignore it.
+#. * Just parse.
+msgid "E604: :catch after :finally"
+msgstr "E604: :catch na :finally"
+
+msgid "E606: :finally without :try"
+msgstr "E606: :finally zonder :try"
+
+#. Give up for a multiple ":finally" and ignore it.
+msgid "E607: multiple :finally"
+msgstr "E607: meerdere :finally"
+
+msgid "E602: :endtry without :try"
+msgstr "E602: :endtry zonder :try"
+
+msgid "E193: :endfunction not inside a function"
+msgstr "E193: :endfunction niet binnen een functie"
+
+msgid "E788: Not allowed to edit another buffer now"
+msgstr "E788: nu een andere buffer bewerken is niet toegestaan"
+
+msgid "E811: Not allowed to change buffer information now"
+msgstr "E811: nu bufferinformatie wijzigen is niet toegestaan"
+
+msgid "tagname"
+msgstr "tagnaam"
+
+msgid " kind file\n"
+msgstr "soor bestand\n"
+
+msgid "'history' option is zero"
+msgstr "'history'-optie is nul"
+
+#, c-format
+msgid ""
+"\n"
+"# %s History (newest to oldest):\n"
+msgstr ""
+"\n"
+"# %s Historie (jongste naar oudste):\n"
+
+msgid "Command Line"
+msgstr "Opdrachtregel"
+
+msgid "Search String"
+msgstr "Zoekstring"
+
+msgid "Expression"
+msgstr "Expressie"
+
+msgid "Input Line"
+msgstr "Invoerregel"
+
+msgid "E198: cmd_pchar beyond the command length"
+msgstr "E198: cmd_pchar is langer dan toegestaan voor een opdracht"
+
+msgid "E199: Active window or buffer deleted"
+msgstr "E199: actieve venster of buffer verwijderd"
+
+msgid "E812: Autocommands changed buffer or buffer name"
+msgstr "E812: buffer of buffernaam gewijzigd door autocommands"
+
+msgid "Illegal file name"
+msgstr "Ongeldige bestandsnaam"
+
+msgid "is a directory"
+msgstr "is een map"
+
+msgid "is not a file"
+msgstr "is geen bestand"
+
+msgid "is a device (disabled with 'opendevice' option)"
+msgstr "is een apparaat (uitgeschakeld door optie 'opendevice'"
+
+msgid "[New File]"
+msgstr "[Nieuw bestand]"
+
+msgid "[New DIRECTORY]"
+msgstr "[Nieuwe MAP]"
+
+msgid "[File too big]"
+msgstr "Bestand te groot"
+
+msgid "[Permission Denied]"
+msgstr "[Geen rechten]"
+
+msgid "E200: *ReadPre autocommands made the file unreadable"
+msgstr "E200: *ReadPre autocommands hebben het bestand niet-leesbaar gemaakt"
+
+msgid "E201: *ReadPre autocommands must not change current buffer"
+msgstr "E201: *ReadPre autocommands mogen huidige buffer niet wijzigen"
+
+msgid "Vim: Reading from stdin...\n"
+msgstr "Vim: lezen van standaardinvoer...\n"
+
+msgid "Reading from stdin..."
+msgstr "Lezen van standaardinvoer..."
+
+#. Re-opening the original file failed!
+msgid "E202: Conversion made file unreadable!"
+msgstr "E202: bestand niet-leesbaar gemaakt door conversatie"
+
+msgid "[fifo/socket]"
+msgstr "[fifo/socket]"
+
+msgid "[fifo]"
+msgstr "[fifo]"
+
+msgid "[socket]"
+msgstr "[socket]"
+
+msgid "[character special]"
+msgstr "[karakter speciaal]"
+
+msgid "[RO]"
+msgstr "[RO]"
+
+msgid "[CR missing]"
+msgstr "[CR ontbreekt]"
+
+msgid "[long lines split]"
+msgstr "[lange regels gesplitst]"
+
+msgid "[NOT converted]"
+msgstr "[NIET omgezet]"
+
+msgid "[converted]"
+msgstr "[omgezet]"
+
+msgid "[crypted]"
+msgstr "[versleuteld]"
+
+#, c-format
+msgid "[CONVERSION ERROR in line %ld]"
+msgstr "[OMZETFOUT in regel %ld]"
+
+#, c-format
+msgid "[ILLEGAL BYTE in line %ld]"
+msgstr "[ONGELDIGE BYTE in regel %ld]"
+
+msgid "[READ ERRORS]"
+msgstr "[LEESFOUTEN]"
+
+msgid "Can't find temp file for conversion"
+msgstr "Tijdelijk bestand voor conversie ontbreekt"
+
+msgid "Conversion with 'charconvert' failed"
+msgstr "Conversatie met 'charconvert' is mislukt"
+
+msgid "can't read output of 'charconvert'"
+msgstr "uitvoer van 'charconvert' kan niet worden gelezen"
+
+msgid "E821: File is encrypted with unknown method"
+msgstr "E821: bestand is met onbekende methode versleuteld"
+
+msgid "E676: No matching autocommands for acwrite buffer"
+msgstr "E676: geen overeenkomende autocommands voor 'acwrite'-buffer"
+
+msgid "E203: Autocommands deleted or unloaded buffer to be written"
+msgstr "E203: autocommands hebben buffer verwijderd of gelost die moest worden opgeslagen"
+
+msgid "E204: Autocommand changed number of lines in unexpected way"
+msgstr "E204: autocommand heeft op onverwachte wijze het aantal regels gewijzigd"
+
+msgid "NetBeans disallows writes of unmodified buffers"
+msgstr "Netbeans staat het opslaan van onveranderde buffers niet toe"
+
+msgid "Partial writes disallowed for NetBeans buffers"
+msgstr "Deelopslag voor buffers van Netbeans niet toegestaan"
+
+msgid "is not a file or writable device"
+msgstr "is geen bestand of schrijfbaar apparaat"
+
+msgid "writing to device disabled with 'opendevice' option"
+msgstr "het schrijven naar apparaat is uitgeschakeld met optie 'opendevice'"
+
+msgid "is read-only (add ! to override)"
+msgstr "is alleen-lezen (voeg ! toe om te schrijven)"
+
+msgid "E506: Can't write to backup file (add ! to override)"
+msgstr "E506: kan niet naar back-upbestand schrijven (voeg hiervoor ! toe)"
+
+msgid "E507: Close error for backup file (add ! to override)"
+msgstr "E507: fout tijdens afsluiten van back-upbestand (voeg ! om toch af te sluiten)"
+
+msgid "E508: Can't read file for backup (add ! to override)"
+msgstr "E508: kan bestand voor back-up niet lezen (voeg ! toe om toch te lezen)"
+
+msgid "E509: Cannot create backup file (add ! to override)"
+msgstr "E509: kan back-upbestand niet aanmaken (voeg ! toe om dit toch aan te maken)"
+
+msgid "E510: Can't make backup file (add ! to override)"
+msgstr "E510: kan back-upbestand niet maken (voeg ! toe om dit toch te maken)"
+
+msgid "E460: The resource fork would be lost (add ! to override)"
+msgstr "E460: de afsplitsing van middelen zou verloren gaan (voeg ! toe om dit toch te doen)"
+
+msgid "E214: Can't find temp file for writing"
+msgstr "E214: kan tijdelijk bestand voor wegschrijven niet vinden"
+
+msgid "E213: Cannot convert (add ! to write without conversion)"
+msgstr "E213: kan niet omzetten (voeg ! toe om zonder omzetting op te slaan)"
+
+msgid "E166: Can't open linked file for writing"
+msgstr "E166: kan niet schrijven naar gekoppeld bestand"
+
+msgid "E212: Can't open file for writing"
+msgstr "E212: kan niet schrijven naar bestand"
+
+msgid "E667: Fsync failed"
+msgstr "E667: fsync is mislukt"
+
+msgid "E512: Close failed"
+msgstr "E512: Afsluiten is mislukt"
+
+msgid "E513: write error, conversion failed (make 'fenc' empty to override)"
+msgstr "E513: schrijffout waarbij omzetting is mislukt (leeg 'fenc' om te overschrijven)"
+
+#, c-format
+msgid "E513: write error, conversion failed in line %ld (make 'fenc' empty to override)"
+msgstr "E513: schrijffout waarbij omzetting in regel %ld is mislukt (leeg 'fenc' om te overschrijven)"
+
+msgid "E514: write error (file system full?)"
+msgstr "E514: schrijffout (is bestandssysteem vol?)"
+
+msgid " CONVERSION ERROR"
+msgstr " OMZETTINGFOUT"
+
+#, c-format
+msgid " in line %ld;"
+msgstr " in regel %ld;"
+
+msgid "[Device]"
+msgstr "[Apparaat]"
+
+msgid "[New]"
+msgstr "[Nieuw]"
+
+msgid " [a]"
+msgstr " [a]"
+
+msgid " appended"
+msgstr " toegevoegd"
+
+msgid " [w]"
+msgstr " [w]"
+
+msgid " written"
+msgstr " opgeslagen"
+
+msgid "E205: Patchmode: can't save original file"
+msgstr "E205: patch-modus: kan oorspronkelijke bestand niet opslaan"
+
+msgid "E206: patchmode: can't touch empty original file"
+msgstr "E206: patch-modus: kan oorspronkelijk leeg bestand niet aanraken"
+
+msgid "E207: Can't delete backup file"
+msgstr "E207: back-upbestand kan niet worden verwijderd"
+
+msgid ""
+"\n"
+"WARNING: Original file may be lost or damaged\n"
+msgstr ""
+"\n"
+"WAARSCHUWING: oorspronkelijk bestand kan verloren gaan of beschadigen\n"
+
+msgid "don't quit the editor until the file is successfully written!"
+msgstr "verlaat vim niet voordat het bestand volledig opgeslagen is!"
+
+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 regel, "
+
+#, c-format
+msgid "%ld lines, "
+msgstr "%ld regels, "
+
+msgid "1 character"
+msgstr "1 teken"
+
+#, c-format
+msgid "%lld characters"
+msgstr "%lld tekens"
+
+#, c-format
+msgid "%ld characters"
+msgstr "%ld tekens"
+
+msgid "[noeol]"
+msgstr "[noeol]"
+
+msgid "[Incomplete last line]"
+msgstr "[Laatste regel onvolledig]"
+
+#. 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 "WAARSCHUWING: het bestand is na het laden gewijzigd!!!"
+
+msgid "Do you really want to write to it"
+msgstr "Wilt u er zeker naar schrijven"
+
+#, c-format
+msgid "E208: Error writing to \"%s\""
+msgstr "E208: schrijven naar \"%s\" is mislukt"
+
+#, c-format
+msgid "E209: Error closing \"%s\""
+msgstr "E209: afsluiten van \"%s\" is mislukt"
+
+#, c-format
+msgid "E210: Error reading \"%s\""
+msgstr "E210: lezen van \"%s\" is mislukt"
+
+msgid "E246: FileChangedShell autocommand deleted buffer"
+msgstr "E246: buffer verwijderd door 'autocommand' FileChangedShell"
+
+#, c-format
+msgid "E211: File \"%s\" no longer available"
+msgstr "E211: bestand \"%s\" is niet meer beschikbaar"
+
+#, c-format
+msgid "W12: Warning: File \"%s\" has changed and the buffer was changed in Vim as well"
+msgstr "W12: waarschuwing: bestand \"%s\" en de buffer zijn gewijzigd in Vim "
+
+msgid "See \":help W12\" for more info."
+msgstr "Lees \":help W12\" voor meer informatie."
+
+#, c-format
+msgid "W11: Warning: File \"%s\" has changed since editing started"
+msgstr "W11: waarschuwing: bestand \"%s\" is gewijzigd sinds het begin van het bewerken"
+
+msgid "See \":help W11\" for more info."
+msgstr "Lees \":help W11\" voor meer informatie."
+
+#, c-format
+msgid "W16: Warning: Mode of file \"%s\" has changed since editing started"
+msgstr "W16: waarschuwing: rechten van bestand \"%s\" zijn gewijzigd sinds het begin van het bewerken"
+
+msgid "See \":help W16\" for more info."
+msgstr "Lees \":help W16\" voor meer informatie"
+
+#, c-format
+msgid "W13: Warning: File \"%s\" has been created after editing started"
+msgstr "W13: waarschuwing: na het begin van het bewerken van bestand \"%s\" is deze ook elders aangemaakt"
+
+msgid "Warning"
+msgstr "Waarschuwing"
+
+msgid ""
+"&OK\n"
+"&Load File"
+msgstr ""
+"&OK\n"
+"Bestand &Laden"
+
+#, c-format
+msgid "E462: Could not prepare for reloading \"%s\""
+msgstr "E462: het voorbereiden van \"%s\" voor het opnieuw laden is mislukt"
+
+#, c-format
+msgid "E321: Could not reload \"%s\""
+msgstr "E321: kan \"%s\" niet opnieuw laden"
+
+msgid "--Deleted--"
+msgstr "--Verwijderd--"
+
+#, c-format
+msgid "auto-removing autocommand: %s <buffer=%d>"
+msgstr "automatisch verwijderen 'autocommand': %s <buffer=%d>"
+
+#. the group doesn't exist
+#, c-format
+msgid "E367: No such group: \"%s\""
+msgstr "E367: groep \"%s\" bestaat niet"
+
+#, c-format
+msgid "E215: Illegal character after *: %s"
+msgstr "E215: ongeldig teken na *: %s"
+
+#, c-format
+msgid "E216: No such event: %s"
+msgstr "E216: onbekend 'event': %s"
+
+#, c-format
+msgid "E216: No such group or event: %s"
+msgstr "E216: onbekende groep of 'event': %s"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Auto-Commands ---"
+msgstr ""
+"\n"
+"--- Auto-Commands ---"
+
+#, c-format
+msgid "E680: <buffer=%d>: invalid buffer number "
+msgstr "E680: <buffer=%d>: ongeldig buffernummer "
+
+msgid "E217: Can't execute autocommands for ALL events"
+msgstr "E217: autocommands kunnen niet voor alle 'events' worden uitgevoerd"
+
+msgid "No matching autocommands"
+msgstr "Geen overeenkomstige autocommands"
+
+msgid "E218: autocommand nesting too deep"
+msgstr "E218: hierarchie van aanroepen autocommands te diep"
+
+#, c-format
+msgid "%s Auto commands for \"%s\""
+msgstr "%s 'Auto commands' voor \"%s\""
+
+#, c-format
+msgid "Executing %s"
+msgstr "%s uitvoeren"
+
+#, c-format
+msgid "autocommand %s"
+msgstr "autocommand %s"
+
+msgid "E219: Missing {."
+msgstr "E219: ontbrekende {."
+
+msgid "E220: Missing }."
+msgstr "E220: ontbrekende }."
+
+msgid "E490: No fold found"
+msgstr "E490: geen vouw gevonden"
+
+msgid "E350: Cannot create fold with current 'foldmethod'"
+msgstr "E350: kan geen vouw aanmaken met huidige 'vouwmethode'"
+
+msgid "E351: Cannot delete fold with current 'foldmethod'"
+msgstr "E351: kan geen vouw verwijderen met huidige 'vouwmethode'"
+
+#, c-format
+msgid "+--%3ld lines folded "
+msgstr "+--%3ld regels gevouwen "
+
+msgid "E222: Add to read buffer"
+msgstr "E222: aan leesbuffer toevoegen"
+
+msgid "E223: recursive mapping"
+msgstr "E223: recursieve toewijzing"
+
+#, c-format
+msgid "E224: global abbreviation already exists for %s"
+msgstr "E224: algemene afkorting bestaat al voor %s"
+
+#, c-format
+msgid "E225: global mapping already exists for %s"
+msgstr "E225: er bestaat al een algemene toewijzing voor %s"
+
+#, c-format
+msgid "E226: abbreviation already exists for %s"
+msgstr "E226: er bestaat al een afkorting voor %s"
+
+#, c-format
+msgid "E227: mapping already exists for %s"
+msgstr "E227: toewijzing bestaat al voor %s"
+
+msgid "No abbreviation found"
+msgstr "Geen afkorting gevonden"
+
+msgid "No mapping found"
+msgstr "Geen toewijzing gevonden"
+
+msgid "E228: makemap: Illegal mode"
+msgstr "E228: makemap: ongeldige modus"
+
+msgid "E229: Cannot start the GUI"
+msgstr "E229: de GUI kan niet worden gestart"
+
+#, c-format
+msgid "E230: Cannot read from \"%s\""
+msgstr "E230: kan niet gelezen worden uit \"%s\""
+
+msgid "E665: Cannot start GUI, no valid font found"
+msgstr "E665: de GUI kan niet gestart worden, er is geen geldig lettertype gevonden"
+
+msgid "E231: 'guifontwide' invalid"
+msgstr "E231: 'guifontwide' ongeldig"
+
+msgid "E599: Value of 'imactivatekey' is invalid"
+msgstr "E599: waarde van 'imactivatekey' is ongeldig"
+
+#, c-format
+msgid "E254: Cannot allocate color %s"
+msgstr "E254: kan de kleur %s niet reserveren"
+
+msgid "No match at cursor, finding next"
+msgstr "Op cursorpositie is geen overeenkomst: de volgende zoeken"
+
+msgid "<cannot open> "
+msgstr "<kan niet openen> "
+
+#, c-format
+msgid "E616: vim_SelFile: can't get font %s"
+msgstr "E616: vim_SelFile: lettertype %s niet gevonden"
+
+msgid "E614: vim_SelFile: can't return to current directory"
+msgstr "E614: vim_SelFile: teruggaan naar huidige map is niet mogelijk"
+
+msgid "Pathname:"
+msgstr "Padnaam:"
+
+msgid "E615: vim_SelFile: can't get current directory"
+msgstr "E615: vim_SelFile: vaststellen huidige map is niet mogelijk"
+
+msgid "OK"
+msgstr "Ok"
+
+msgid "Cancel"
+msgstr "Annuleren"
+
+msgid "Scrollbar Widget: Could not get geometry of thumb pixmap."
+msgstr "Scrollbar-widget: vaststellen afmetingen van miniaturenkaart niet mogelijk."
+
+msgid "Vim dialog"
+msgstr "Vim-dialoog"
+
+msgid "E232: Cannot create BalloonEval with both message and callback"
+msgstr "E232: aanmaken 'BalloonEval' met zowel een bericht als een 'callback' is niet mogelijk"
+
+msgid "Vim dialog..."
+msgstr "Vim-dialoog..."
+
+msgid ""
+"&Yes\n"
+"&No\n"
+"&Cancel"
+msgstr ""
+"&Ja\n"
+"&Nee\n"
+"&Annuleren"
+
+msgid "Input _Methods"
+msgstr "Invoer_wijzen"
+
+msgid "VIM - Search and Replace..."
+msgstr "VIM - zoeken en vervangen..."
+
+msgid "VIM - Search..."
+msgstr "VIM - zoeken..."
+
+msgid "Find what:"
+msgstr "Zoek naar:"
+
+msgid "Replace with:"
+msgstr "Vervang door:"
+
+#. whole word only button
+msgid "Match whole word only"
+msgstr "Alleen volledig woord"
+
+#. match case button
+msgid "Match case"
+msgstr "Hoofdlettergevoelig"
+
+msgid "Direction"
+msgstr "Richting"
+
+#. 'Up' and 'Down' buttons
+msgid "Up"
+msgstr "Opwaarts"
+
+msgid "Down"
+msgstr "Neerwaarts"
+
+msgid "Find Next"
+msgstr "Volgende zoeken"
+
+msgid "Replace"
+msgstr "Vervangen"
+
+msgid "Replace All"
+msgstr "Alles vervangen"
+
+msgid "Vim: Received \"die\" request from session manager\n"
+msgstr "Vim: \"die\"-verzoek van sessiebeheerder ontvangen\n"
+
+msgid "Close"
+msgstr "Sluiten"
+
+msgid "New tab"
+msgstr "Nieuw tabblad"
+
+msgid "Open Tab..."
+msgstr "Tabblad openen..."
+
+msgid "Vim: Main window unexpectedly destroyed\n"
+msgstr "Vim: hoofdvenster onverwacht gesloten\n"
+
+msgid "Font Selection"
+msgstr "Lettertypeselectie"
+
+msgid "&Filter"
+msgstr "&Filter"
+
+msgid "&Cancel"
+msgstr "&Annuleren"
+
+msgid "Directories"
+msgstr "Mappen"
+
+msgid "Filter"
+msgstr "Filter"
+
+msgid "&Help"
+msgstr "&Hulp"
+
+msgid "Files"
+msgstr "Bestanden"
+
+msgid "&OK"
+msgstr "&Ok"
+
+msgid "Selection"
+msgstr "Selectie"
+
+msgid "Find &Next"
+msgstr "&Volgende zoeken"
+
+msgid "&Replace"
+msgstr "Ve&rvangen"
+
+msgid "Replace &All"
+msgstr "&Alles vervangen"
+
+msgid "&Undo"
+msgstr "&Herstellen"
+
+#, c-format
+msgid "E610: Can't load Zap font '%s'"
+msgstr "E610: Zap-lettertype '%s' kan niet worden geladen"
+
+#, c-format
+msgid "E611: Can't use font %s"
+msgstr "E611: lettertype %s kan niet worden gebruikt"
+
+msgid ""
+"\n"
+"Sending message to terminate child process.\n"
+msgstr ""
+"\n"
+"Bericht versturen om kindproces te beëindigen.\n"
+
+#, c-format
+msgid "E671: Cannot find window title \"%s\""
+msgstr "E671: kan venstertitel \"%s\" niet vinden"
+
+#, c-format
+msgid "E243: Argument not supported: \"-%s\"; Use the OLE version."
+msgstr "E243: argument niet ondersteund: \"-%s\"; gebruik de OLE-versie."
+
+msgid "E672: Unable to open window inside MDI application"
+msgstr "E672: kan geen venster binnen MDI-applicatie openen"
+
+msgid "Close tab"
+msgstr "Tabblad sluiten"
+
+msgid "Open tab..."
+msgstr "Tabblad openen..."
+
+msgid "Find string (use '\\\\' to find a '\\')"
+msgstr "Tekenreeks zoeken (gebruik '\\\\' om een '\\' te vinden)"
+
+msgid "Find & Replace (use '\\\\' to find a '\\')"
+msgstr "Zoeken & vervangen (gebruik '\\\\' om een '\\' te vinden')"
+
+#. 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 "Niet gebruikt"
+
+msgid "Directory\t*.nothing\n"
+msgstr "Map\t*.niets\n"
+
+msgid "Vim E458: Cannot allocate colormap entry, some colors may be incorrect"
+msgstr "E458: kan geen kleur toewijzen, sommige kleuren kunnen onjuist zijn"
+
+#, c-format
+msgid "E250: Fonts for the following charsets are missing in fontset %s:"
+msgstr "E250: lettertypen voor de volgende tekenverzamelingen ontbreken in verzameling %s:"
+
+#, c-format
+msgid "E252: Fontset name: %s"
+msgstr "E252: naam lettertypeverzameling: %s"
+
+#, c-format
+msgid "Font '%s' is not fixed-width"
+msgstr "Lettertype '%s' heeft geen vaste breedte"
+
+#, c-format
+msgid "E253: Fontset name: %s\n"
+msgstr "E253: naam lettertypeverzameling: %s\n"
+
+#, c-format
+msgid "Font0: %s\n"
+msgstr "Font0: %s\n"
+
+#, c-format
+msgid "Font1: %s\n"
+msgstr "Font1: %s\n"
+
+#, c-format
+msgid "Font%ld width is not twice that of font0\n"
+msgstr "Breedte font%ld is niet het dubbele van font0\n"
+
+#, c-format
+msgid "Font0 width: %ld\n"
+msgstr "Font0-breedte: %ld\n"
+
+#, c-format
+msgid ""
+"Font1 width: %ld\n"
+"\n"
+msgstr ""
+"Font1-breedte: %ld\n"
+"\n"
+
+msgid "Invalid font specification"
+msgstr "Onjuiste specificatie van lettertype"
+
+msgid "&Dismiss"
+msgstr "&Afwijzen"
+
+msgid "no specific match"
+msgstr "geen specifieke overeenkomst"
+
+msgid "Vim - Font Selector"
+msgstr "Vim - Lettertypekiezer"
+
+msgid "Name:"
+msgstr "Naam:"
+
+#. create toggle button
+msgid "Show size in Points"
+msgstr "Grootte in punten tonen"
+
+msgid "Encoding:"
+msgstr "Codering:"
+
+msgid "Font:"
+msgstr "Lettertype:"
+
+msgid "Style:"
+msgstr "Stijl:"
+
+msgid "Size:"
+msgstr "Grootte:"
+
+msgid "E256: Hangul automata ERROR"
+msgstr "E256: 'Hangul automata'-fout"
+
+msgid "E550: Missing colon"
+msgstr "E550: dubbelepunt ontbreekt"
+
+msgid "E551: Illegal component"
+msgstr "E551: ongeldige component"
+
+msgid "E552: digit expected"
+msgstr "E552: cijfer verwacht"
+
+#, c-format
+msgid "Page %d"
+msgstr "Pagina %d"
+
+msgid "No text to be printed"
+msgstr "Geen tekst om af te drukken"
+
+#, c-format
+msgid "Printing page %d (%d%%)"
+msgstr "Afdrukken van pagina %d (%d%%)"
+
+#, c-format
+msgid " Copy %d of %d"
+msgstr "Kopie %d van %d"
+
+#, c-format
+msgid "Printed: %s"
+msgstr "Afgedrukt: %s"
+
+msgid "Printing aborted"
+msgstr "Afdrukken afgebroken"
+
+msgid "E455: Error writing to PostScript output file"
+msgstr "E455: wegschrijven Postscript-uitvoerbestand is mislukt"
+
+#, c-format
+msgid "E624: Can't open file \"%s\""
+msgstr "E624: openen bestand \"%s\" is mislukt"
+
+#, c-format
+msgid "E457: Can't read PostScript resource file \"%s\""
+msgstr "E457: kan 'Postscript resource'-bestand \"%s\" niet lezen"
+
+#, c-format
+msgid "E618: file \"%s\" is not a PostScript resource file"
+msgstr "E618: bestand \"%s\" is geen 'Postscript resource'-bestand"
+
+#, c-format
+msgid "E619: file \"%s\" is not a supported PostScript resource file"
+msgstr "E619: bestand \"%s\" is geen ondersteund 'Postscript resource'-bestand"
+
+#, c-format
+msgid "E621: \"%s\" resource file has wrong version"
+msgstr "E621: 'resource'-bestand \"%s\" heeft verkeerde versie"
+
+msgid "E673: Incompatible multi-byte encoding and character set."
+msgstr "E673: Multi-byte-codering en de tekenverzameling zijn onverenigbaar."
+
+msgid "E674: printmbcharset cannot be empty with multi-byte encoding."
+msgstr "E674: printmbcharset mag bij multi-byte-codering niet leeg zijn."
+
+msgid "E675: No default font specified for multi-byte printing."
+msgstr "E675: geen standaard lettertype opgegeven voor multi-byte-afdrukken."
+
+msgid "E324: Can't open PostScript output file"
+msgstr "E324: openen van PostScript-uitoverbestand is mislukt"
+
+#, c-format
+msgid "E456: Can't open file \"%s\""
+msgstr "E456: Bestand \"%s\" kan niet worden geopend"
+
+msgid "E456: Can't find PostScript resource file \"prolog.ps\""
+msgstr "E456: 'PostScript resource'-bestand \"prolog.ps\" is niet gevonden"
+
+msgid "E456: Can't find PostScript resource file \"cidfont.ps\""
+msgstr "E456: 'PostScript resource'-bestand \"cidfont.ps\" is niet gevonden"
+
+#, c-format
+msgid "E456: Can't find PostScript resource file \"%s.ps\""
+msgstr "E456: 'PostScript resource'-bestand \"%s.ps\" is niet gevonden"
+
+#, c-format
+msgid "E620: Unable to convert to print encoding \"%s\""
+msgstr "E620: omzetten naar afdrukcodering \"%s\" is mislukt"
+
+msgid "Sending to printer..."
+msgstr "Naar printer versturen..."
+
+msgid "E365: Failed to print PostScript file"
+msgstr "E365: Afdrukken van PostScript-bestand is mislukt"
+
+msgid "Print job sent."
+msgstr "Afdrukopdracht verzonden"
+
+msgid "Add a new database"
+msgstr "Nieuwe databank toevoegen"
+
+msgid "Query for a pattern"
+msgstr "Naar een patroon zoeken"
+
+msgid "Show this message"
+msgstr "Dit bericht tonen"
+
+msgid "Kill a connection"
+msgstr "Een verbinding verbreken"
+
+msgid "Reinit all connections"
+msgstr "Alle verbindingen opnieuw initialiseren"
+
+msgid "Show connections"
+msgstr "Verbindingen tonen"
+
+#, c-format
+msgid "E560: Usage: cs[cope] %s"
+msgstr "E560: Gebruik: cs[cope] %s"
+
+msgid "This cscope command does not support splitting the window.\n"
+msgstr "Deze cscope-opdracht ondersteunt niet het splitsen van het venster.\n"
+
+msgid "E562: Usage: cstag <ident>"
+msgstr "E562: Gebruik: cstag <ident>"
+
+msgid "E257: cstag: tag not found"
+msgstr "E257: cstag: tag is gevonden"
+
+#, c-format
+msgid "E563: stat(%s) error: %d"
+msgstr "E563: bevraag((%s) fout: %d"
+
+msgid "E563: stat error"
+msgstr "E563: bevragingsfout"
+
+#, c-format
+msgid "E564: %s is not a directory or a valid cscope database"
+msgstr "E564: %s is geen map of een geldige cscope-databank"
+
+#, c-format
+msgid "Added cscope database %s"
+msgstr "cscope-databank %s toegevoegd"
+
+#, c-format
+msgid "E262: error reading cscope connection %ld"
+msgstr "E262: lezen van cscope-verbinding %ld is mislukt"
+
+msgid "E561: unknown cscope search type"
+msgstr "E561: soort cscope-zoekopdracht is onbekend"
+
+msgid "E566: Could not create cscope pipes"
+msgstr "E566: aanmaken cscopei-pijp is mislukt"
+
+msgid "E622: Could not fork for cscope"
+msgstr "E622: nieuw cscope-proces beginnen is mislukt"
+
+msgid "cs_create_connection exec failed"
+msgstr "uitvoering cs_create_connection is mislukt"
+
+msgid "cs_create_connection: fdopen for to_fp failed"
+msgstr "cs_create_connection: fdopen voor to_fp is mislukt"
+
+msgid "cs_create_connection: fdopen for fr_fp failed"
+msgstr "cs_create_connection: fdopen voor fr_fp is mislukt"
+
+msgid "E623: Could not spawn cscope process"
+msgstr "E623: voortbrengen cscope-proces is mislukt"
+
+msgid "E567: no cscope connections"
+msgstr "E567: geen cscope-verbindingen"
+
+#, c-format
+msgid "E469: invalid cscopequickfix flag %c for %c"
+msgstr "E469: cscopequickfix-vlag %c voor %c is ongeldig"
+
+#, c-format
+msgid "E259: no matches found for cscope query %s of %s"
+msgstr "E259: cscope-zoekopdracht %s van %s leverde geen resultaten"
+
+msgid "cscope commands:\n"
+msgstr "cscope-opdrachten:\n"
+
+#, c-format
+msgid "%-5s: %s%*s (Usage: %s)"
+msgstr "%-5s: %s%*s (Gebruik: %s)"
+
+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 assignments to\n"
+msgstr ""
+"\n"
+" c: zoek functies die deze functie aanroepen\n"
+" d: zoek functies die door deze functie worden aangeroepen\n"
+" e: zoek op dit egrep-patroon\n"
+" f: zoek dit bestand\n"
+" g: zoek deze definitie\n"
+" i: zoek bestanden #inclusief dit bestand\n"
+" s: zoek dit C-symbool\n"
+" t: zoek toekenningen aan\n"
+
+#, c-format
+msgid "E625: cannot open cscope database: %s"
+msgstr "E625: openen is mislukt van cscope-databank: %s"
+
+msgid "E626: cannot get cscope database information"
+msgstr "E626: opvragen cscope-databankinformatie is mislukt"
+
+msgid "E568: duplicate cscope database not added"
+msgstr "E568: dubbele cscope-databank is niet toegevoegd"
+
+#, c-format
+msgid "E261: cscope connection %s not found"
+msgstr "E261: cscope-verbinding %s is niet gevonden"
+
+#, c-format
+msgid "cscope connection %s closed"
+msgstr "cscope-verbinding %s is verbroken"
+
+#. should not reach here
+msgid "E570: fatal error in cs_manage_matches"
+msgstr "E570: fatale fout in cs_manage_matches"
+
+#, c-format
+msgid "Cscope tag: %s"
+msgstr "Cscope-tag: %s"
+
+msgid ""
+"\n"
+" # line"
+msgstr ""
+"\n"
+" # regel"
+
+msgid "filename / context / line\n"
+msgstr "bestandsnaam / context / regel\n"
+
+#, c-format
+msgid "E609: Cscope error: %s"
+msgstr "E609: Cscope-fout: %s"
+
+msgid "All cscope databases reset"
+msgstr "Alle cscope-databanken opnieuw ingesteld"
+
+msgid "no cscope connections\n"
+msgstr "geen cscope-verbindingen\n"
+
+msgid " # pid database name prepend path\n"
+msgstr " # pid databanknaam padvoorvoegsel\n"
+
+msgid "E815: Sorry, this command is disabled, the MzScheme libraries could not be loaded."
+msgstr "E815: helaas, deze opdracht is uitgeschakeld. De MzScheme-bibliotheken kunnen niet geladen worden."
+
+msgid "invalid expression"
+msgstr "ongeldige uitdrukking"
+
+msgid "expressions disabled at compile time"
+msgstr "tijdens compileren zijn de expressies uitgeschakeld"
+
+msgid "hidden option"
+msgstr "verborgen optie"
+
+msgid "unknown option"
+msgstr "onbekende optie"
+
+msgid "window index is out of range"
+msgstr "vensterindex valt buiten het bereik"
+
+msgid "couldn't open buffer"
+msgstr "buffer openen is mislukt"
+
+msgid "cannot save undo information"
+msgstr "herstelinformatie kan niet worden opgeslagen"
+
+msgid "cannot delete line"
+msgstr "regel kan niet worden verwijderd"
+
+msgid "cannot replace line"
+msgstr "regel kan niet worden vervangen"
+
+msgid "cannot insert line"
+msgstr "regel kan niet worden ingevoegd"
+
+msgid "string cannot contain newlines"
+msgstr "tekenreeks kan geen regeleinden bevatten"
+
+msgid "Vim error: ~a"
+msgstr "Vim-fout: ~a"
+
+msgid "Vim error"
+msgstr "Vim-fout"
+
+msgid "buffer is invalid"
+msgstr "buffer is ongeldig"
+
+msgid "window is invalid"
+msgstr "venster is ongeldig"
+
+msgid "linenr out of range"
+msgstr "regelnummer buiten het bereik"
+
+msgid "not allowed in the Vim sandbox"
+msgstr "niet toegestaan in de Vim-zandbak"
+
+msgid "E263: Sorry, this command is disabled, the Python library could not be loaded."
+msgstr "E263: helaas, deze opdracht is uitgeschakeld. De Python-bibliotheek kan niet worden geladen."
+
+msgid "E659: Cannot invoke Python recursively"
+msgstr "E659: Python kan niet recursief worden aangeroepen"
+
+msgid "can't delete OutputObject attributes"
+msgstr "attributen van OutputObject kunnen niet worden verwijderd"
+
+msgid "softspace must be an integer"
+msgstr "zachte spatie moet een geheel getal zijn"
+
+msgid "invalid attribute"
+msgstr "ongeldig attribuut"
+
+msgid "writelines() requires list of strings"
+msgstr "writelines() vereist een lijst met tekenreeksen"
+
+msgid "E264: Python: Error initialising I/O objects"
+msgstr "E264: Python: initialiseren I/O-objecten is mislukt"
+
+msgid "attempt to refer to deleted buffer"
+msgstr "poging om naar een verwijderd buffer te verwijzen"
+
+msgid "line number out of range"
+msgstr "regelnummer valt buiten het bereik"
+
+#, c-format
+msgid "<buffer object (deleted) at %p>"
+msgstr "<buffer-object (verwijderd) bij %p>"
+
+msgid "invalid mark name"
+msgstr "naam markering ongeldig"
+
+msgid "no such buffer"
+msgstr "onbekende buffer"
+
+msgid "attempt to refer to deleted window"
+msgstr "poging om naar een verwijderd venster te verwijzen"
+
+msgid "readonly attribute"
+msgstr "alleen-lezen attribuut"
+
+msgid "cursor position outside buffer"
+msgstr "cursorpositie valt buiten buffer"
+
+#, c-format
+msgid "<window object (deleted) at %p>"
+msgstr "<venster-object (verwijderd) bij %p>"
+
+#, c-format
+msgid "<window object (unknown) at %p>"
+msgstr "<venster-object (onbekend) bij %p>"
+
+#, c-format
+msgid "<window %d>"
+msgstr "<venster %d>"
+
+msgid "no such window"
+msgstr "onbekend venster"
+
+msgid "E265: $_ must be an instance of String"
+msgstr "E265: $_ moet een instantie van String zijn"
+
+msgid "E266: Sorry, this command is disabled, the Ruby library could not be loaded."
+msgstr "E266: helaas, deze opdracht is uitgeschakeld. De Ruby-bibliotheek kan niet worden geladen."
+
+msgid "E267: unexpected return"
+msgstr "E267: onverwacht resultaat"
+
+msgid "E268: unexpected next"
+msgstr "E268: onverwachte volgende"
+
+msgid "E269: unexpected break"
+msgstr "E269: onverwachte onderbreking"
+
+msgid "E270: unexpected redo"
+msgstr "E270: onverwachte herstelopdracht"
+
+msgid "E271: retry outside of rescue clause"
+msgstr "E271: hernieuwde poging buiten de reddingsclausule"
+
+msgid "E272: unhandled exception"
+msgstr "E272: niet-afgehandelde uitzondering"
+
+#, c-format
+msgid "E273: unknown longjmp status %d"
+msgstr "E273: onbekende longjmp-status %d"
+
+msgid "Toggle implementation/definition"
+msgstr "Implementatie/definitie wisselen"
+
+msgid "Show base class of"
+msgstr "Toon basisklasse van"
+
+msgid "Show overridden member function"
+msgstr "Toon overschreven member-functie"
+
+msgid "Retrieve from file"
+msgstr "Uit bestand halen"
+
+msgid "Retrieve from project"
+msgstr "Uit project halen"
+
+msgid "Retrieve from all projects"
+msgstr "Uit alle projecten halen"
+
+msgid "Retrieve"
+msgstr "Ophalen"
+
+msgid "Show source of"
+msgstr "Toon broncode van"
+
+msgid "Find symbol"
+msgstr "Zoek symbool"
+
+msgid "Browse class"
+msgstr "Bekijk klasse"
+
+msgid "Show class in hierarchy"
+msgstr "Toon klasse in hierarchie"
+
+msgid "Show class in restricted hierarchy"
+msgstr "Toon klasse in beperkte hierarchie"
+
+msgid "Xref refers to"
+msgstr "Xref verwijst naar"
+
+msgid "Xref referred by"
+msgstr "Xref wordt naar verwezen door"
+
+msgid "Xref has a"
+msgstr "Xref heeft een"
+
+msgid "Xref used by"
+msgstr "Xref gebruikt door"
+
+msgid "Show docu of"
+msgstr "Toon documentatie van"
+
+msgid "Generate docu for"
+msgstr "Genereer documentatie voor"
+
+msgid "Cannot connect to SNiFF+. Check environment (sniffemacs must be found in $PATH).\n"
+msgstr "Verbinden met SNiFF+ is mislukt. Controleer omgevingsvariabelen (sniffemacs moet in $PATH staan).\n"
+
+msgid "E274: Sniff: Error during read. Disconnected"
+msgstr "E274: Sniff: leesfout. Verbroken"
+
+msgid "SNiFF+ is currently "
+msgstr "SNiFF+ is momenteel "
+
+msgid "not "
+msgstr "niet "
+
+msgid "connected"
+msgstr "verbonden"
+
+#, c-format
+msgid "E275: Unknown SNiFF+ request: %s"
+msgstr "E275: onbekend SNiFF+-verzoek: %s"
+
+msgid "E276: Error connecting to SNiFF+"
+msgstr "E276: verbinden met SNiFF+ is mislukt"
+
+msgid "E278: SNiFF+ not connected"
+msgstr "E278: SNiFF+ niet verbonden"
+
+msgid "E279: Not a SNiFF+ buffer"
+msgstr "E279: geen SNiFF+-buffer"
+
+msgid "Sniff: Error during write. Disconnected"
+msgstr "Sniff: schrijven is mislukt. Verbroken"
+
+msgid "invalid buffer number"
+msgstr "buffernummer is ongeldig"
+
+msgid "not implemented yet"
+msgstr "nog niet geïmplementeerd"
+
+#. ???
+msgid "cannot set line(s)"
+msgstr "kan regel(s) niet instellen"
+
+msgid "mark not set"
+msgstr "markering niet ingesteld"
+
+#, c-format
+msgid "row %d column %d"
+msgstr "rij %d kolom %d"
+
+msgid "cannot insert/append line"
+msgstr "invoegen/toevoegen regel is mislukt"
+
+msgid "unknown flag: "
+msgstr "unbekende instelling: "
+
+msgid "unknown vimOption"
+msgstr "onbekende vim-optie"
+
+msgid "keyboard interrupt"
+msgstr "toetsenbord-interrupt"
+
+msgid "vim error"
+msgstr "vim-fout"
+
+msgid "cannot create buffer/window command: object is being deleted"
+msgstr "aanmaken buffer-/vensteropdracht is mislukt: object wordt verwijderd"
+
+msgid "cannot register callback command: buffer/window is already being deleted"
+msgstr " kan 'callback'-opdracht niet registreren: buffer/venster is reeds verwijderd"
+
+#. This should never happen. Famous last word?
+msgid "E280: TCL FATAL ERROR: reflist corrupt!? Please report this to vim-dev@vim.org"
+msgstr "E280: TCL FATALE FOUT: reflist misschien corrupt!? Meld dit a.u.b. aan vim-dev@vim.org"
+
+msgid "cannot register callback command: buffer/window reference not found"
+msgstr "'callback'-opdracht kan niet worden geregistreerd: buffer-/vensterreferentie ontbreekt"
+
+msgid "E571: Sorry, this command is disabled: the Tcl library could not be loaded."
+msgstr "E571: Helaas, deze opdracht is uitgeschakeld: het laden van de Tcl-bibliotheek is mislukt."
+
+msgid "E281: TCL ERROR: exit code is not int!? Please report this to vim-dev@vim.org"
+msgstr "E281: Tcl-fout: afsluitcode is geen geheel getal!? Meld dit a.u.b. aan vim-dev@vim.org"
+
+#, c-format
+msgid "E572: exit code %d"
+msgstr "E572: afsluitcode %d"
+
+msgid "cannot get line"
+msgstr "kan regel niet verkrijgen"
+
+msgid "Unable to register a command server name"
+msgstr "Het registreren van een opdrachtservernaam is mislukt"
+
+msgid "E248: Failed to send command to the destination program"
+msgstr "E248: versturen van opdracht naar het doelprogramma is mislukt"
+
+#, c-format
+msgid "E573: Invalid server id used: %s"
+msgstr "E573: ongeldige server-id gebruikt: %s"
+
+msgid "E251: VIM instance registry property is badly formed. Deleted!"
+msgstr "E251: registereigenschap van VIM-instantie is misvormd. Verwijderd!"
+
+msgid "Unknown option argument"
+msgstr "Onbekend optieargument"
+
+msgid "Too many edit arguments"
+msgstr "Teveel bewerkargumenten"
+
+msgid "Argument missing after"
+msgstr "Argument ontbreekt na"
+
+msgid "Garbage after option argument"
+msgstr "Rommel na optieargument"
+
+msgid "Too many \"+command\", \"-c command\" or \"--cmd command\" arguments"
+msgstr "Teveel \"+opdracht\", \"-c opdracht\" of \"--cmd opdracht\"-argumenten"
+
+msgid "Invalid argument for"
+msgstr "Ongeldig argument voor"
+
+#, c-format
+msgid "%d files to edit\n"
+msgstr "%d bestanden om te bewerken\n"
+
+msgid "netbeans is not supported with this GUI\n"
+msgstr "Netbeans wordt door deze GUI niet ondersteund\n"
+
+msgid "This Vim was not compiled with the diff feature."
+msgstr "Deze Vim is niet met de diff-functionaliteit gecompileerd"
+
+msgid "'-nb' cannot be used: not enabled at compile time\n"
+msgstr "'-nb' kan niet worden gebruikt: was tijdens compilatie niet ingeschakeld\n"
+
+msgid "Attempt to open script file again: \""
+msgstr "Poging scriptbestand wederom te openen: \""
+
+msgid "Cannot open for reading: \""
+msgstr "Openen om te lezen is mislukt: \""
+
+msgid "Cannot open for script output: \""
+msgstr "Openen voor script-uitvoer is mislukt: \""
+
+msgid "Vim: Error: Failure to start gvim from NetBeans\n"
+msgstr "Vim: Fout: gvim starten vanuit Netbeans is mislukt\n"
+
+msgid "Vim: Warning: Output is not to a terminal\n"
+msgstr "Vim: Waarschuwing: Uitvoer gaan niet naar een terminal\n"
+
+msgid "Vim: Warning: Input is not from a terminal\n"
+msgstr "Vim: Waarschuwing: Invoer komt niet van een terminal\n"
+
+#. just in case..
+msgid "pre-vimrc command line"
+msgstr "pre-vimrc-opdracjtregel"
+
+#, c-format
+msgid "E282: Cannot read from \"%s\""
+msgstr "E282: Kan niet lezen vanuit \"%s\""
+
+msgid ""
+"\n"
+"More info with: \"vim -h\"\n"
+msgstr ""
+"\n"
+"Meer informatie via: \"vim -h\"\n"
+
+msgid "[file ..] edit specified file(s)"
+msgstr "[bestand ..] bewerk opgegeven bestand(en)"
+
+msgid "- read text from stdin"
+msgstr "- lees tekst vanuit stdin"
+
+msgid "-t tag edit file where tag is defined"
+msgstr "-t tag bewerk bestand waar tag is gedefinieerd"
+
+msgid "-q [errorfile] edit file with first error"
+msgstr "-q [foutbestand] bewerk bestand dat eerste fout bevat"
+
+msgid ""
+"\n"
+"\n"
+"usage:"
+msgstr ""
+"\n"
+"\n"
+"Gebruik:"
+
+msgid " vim [arguments] "
+msgstr " vim [argumenten] "
+
+msgid ""
+"\n"
+" or:"
+msgstr ""
+"\n"
+" of:"
+
+msgid ""
+"\n"
+"Where case is ignored prepend / to make flag upper case"
+msgstr ""
+"\n"
+"Daar waar hoofdletters genegeerd worden kan met / vlag in hoofdletters gezet worden"
+
+msgid ""
+"\n"
+"\n"
+"Arguments:\n"
+msgstr ""
+"\n"
+"\n"
+"Argumenten:\n"
+
+msgid "--\t\t\tOnly file names after this"
+msgstr "--\t\t\tHierna alleen bestandsnamen"
+
+msgid "--literal\t\tDon't expand wildcards"
+msgstr "--literal\t\tJokertekens niet vervangen"
+
+msgid "-register\t\tRegister this gvim for OLE"
+msgstr "-register\t\tDeze gvim voor OLE registreren"
+
+msgid "-unregister\t\tUnregister gvim for OLE"
+msgstr "-unregister\t\tgvim afmelden voor OLE"
+
+msgid "-g\t\t\tRun using GUI (like \"gvim\")"
+msgstr "-g\t\t\tMet GUI opstarten (zoals \"gvim\")"
+
+msgid "-f or --nofork\tForeground: Don't fork when starting GUI"
+msgstr "-f of --nofork\tVoorgrond: niet afsplitsen tijdens opstarten GUI"
+
+msgid "-v\t\t\tVi mode (like \"vi\")"
+msgstr "-v\t\t\tVi-modus (zoals \"vi\")"
+
+msgid "-e\t\t\tEx mode (like \"ex\")"
+msgstr "-e\t\t\tEx-modus (zoals \"ex\")"
+
+msgid "-s\t\t\tSilent (batch) mode (only for \"ex\")"
+msgstr "-s\t\t\tStille (bulk)modus (alleen bij \"ex\")"
+
+msgid "-d\t\t\tDiff mode (like \"vimdiff\")"
+msgstr "-d\t\t\tDiff-modus (zoals \"vimdiff\")"
+
+msgid "-y\t\t\tEasy mode (like \"evim\", modeless)"
+msgstr "-y\t\t\tEenvoudige modus (zoals \"evim\", zonder modus)"
+
+msgid "-R\t\t\tReadonly mode (like \"view\")"
+msgstr "-R\t\t\tAlleen-lezen modus (zoals \"view\")"
+
+msgid "-Z\t\t\tRestricted mode (like \"rvim\")"
+msgstr "-Z\t\t\tBeperkte modus (zoals \"rvim\")"
+
+msgid "-m\t\t\tModifications (writing files) not allowed"
+msgstr "-m\t\t\tAanpassingen (bestanden opslaan) niet toegestaan"
+
+msgid "-M\t\t\tModifications in text not allowed"
+msgstr "-M\t\t\tTekstuele aanpassingen niet toegestaan"
+
+msgid "-b\t\t\tBinary mode"
+msgstr "-b\t\t\tBinaire modus"
+
+msgid "-l\t\t\tLisp mode"
+msgstr "-l\t\t\tLisp-modus"
+
+msgid "-C\t\t\tCompatible with Vi: 'compatible'"
+msgstr "-C\t\t\tUitwisselbaar met Vi: 'compatible'"
+
+msgid "-N\t\t\tNot fully Vi compatible: 'nocompatible'"
+msgstr "-N\t\t\tNiet volledig met Vi uitwisselbaar: 'nocompatible'"
+
+msgid "-V[N][fname]\t\tBe verbose [level N] [log messages to fname]"
+msgstr "-V[N][fname]\t\tWees uitbundig [niveau N] [schrijf berichten naar fname]"
+
+msgid "-D\t\t\tDebugging mode"
+msgstr "-D\t\t\tFoutopspoormodus"
+
+msgid "-n\t\t\tNo swap file, use memory only"
+msgstr "-n\t\t\tGeen wisselbestand, alleen geheugen gebruiken"
+
+msgid "-r\t\t\tList swap files and exit"
+msgstr "-r\t\t\tWisselbestanden tonen en stoppen"
+
+msgid "-r (with file name)\tRecover crashed session"
+msgstr "-r (bestandsnaam)\tHerstel ontspoorde sessie"
+
+msgid "-L\t\t\tSame as -r"
+msgstr "-L\t\t\tGelijk aan -r"
+
+msgid "-f\t\t\tDon't use newcli to open window"
+msgstr "-f\t\t\tGebruik geen newcli om venster te openen"
+
+msgid "-dev <device>\t\tUse <device> for I/O"
+msgstr "-dev <device>\t\tGebruik <device> voor in- en uitvoer"
+
+msgid "-A\t\t\tstart in Arabic mode"
+msgstr "-A\t\t\tIn Arabische modus starten"
+
+msgid "-H\t\t\tStart in Hebrew mode"
+msgstr "-H\t\t\tIn Hebrewsche modus starten"
+
+msgid "-F\t\t\tStart in Farsi mode"
+msgstr "-F\t\t\tIn Perzische modus starten"
+
+msgid "-T <terminal>\tSet terminal type to <terminal>"
+msgstr "-T <terminal>\tTerminalsoort op <terminal> instellen"
+
+msgid "-u <vimrc>\t\tUse <vimrc> instead of any .vimrc"
+msgstr "-u <vimrc>\t\tGebruik <vimrc> in plaats van enige .vimrc"
+
+msgid "-U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc"
+msgstr "-U <gvimrc>\t\tGebruik <gvimrc> in plaats van enige .gvimrc"
+
+msgid "--noplugin\t\tDon't load plugin scripts"
+msgstr "--noplugin\t\tGeen plugin-scripts laden"
+
+msgid "-p[N]\t\tOpen N tab pages (default: one for each file)"
+msgstr "-p[N]\t\tN tabpagina's openen (standaard: 1 per bestand)"
+
+msgid "-o[N]\t\tOpen N windows (default: one for each file)"
+msgstr "-o[N]\t\tN vensters openen (standaard: 1 per bestand)"
+
+msgid "-O[N]\t\tLike -o but split vertically"
+msgstr "-O[N]\t\tGelijk aan -o maar vertikaal gesplitst"
+
+msgid "+\t\t\tStart at end of file"
+msgstr "+\t\t\tAan einde van bestand beginnen"
+
+msgid "+<lnum>\t\tStart at line <lnum>"
+msgstr "+<lnum>\t\tOp regel <lnum> beginnen"
+
+msgid "--cmd <command>\tExecute <command> before loading any vimrc file"
+msgstr "--cmd <opdracht>\tOpdracht <opdracht> uitvoeren voor enige vimrc-bestand"
+
+msgid "-c <command>\t\tExecute <command> after loading the first file"
+msgstr "-c <opdracht>\t\tOpdracht <opdracht> uitvoeren na eerste bestand"
+
+msgid "-h or --help\tPrint Help (this message) and exit"
+msgstr "-h of --help\tDit bericht tonen en stoppen"
+
+msgid "--version\t\tPrint version information and exit"
+msgstr "--version\t\tVersieinformatie tonen en stoppen"
+
+msgid "E298: Didn't get block nr 0?"
+msgstr "E298: Ophalen blok nummer 0 mislukt?"
+
+msgid "E298: Didn't get block nr 1?"
+msgstr "E298: Ophalen blok nummer 1 mislukt?"
+
+msgid "E298: Didn't get block nr 2?"
+msgstr "E298: Ophalen blok nummer 2 mislukt?"
+
+#. could not (re)open the swap file, what can we do????
+msgid "E301: Oops, lost the swap file!!!"
+msgstr "E301: Helaas, wisselbestand is verdwenen!!!"
+
+msgid "Enter number of swap file to use (0 to quit): "
+msgstr "Typ het nummer van het wisselbestand om te gebruiken (0 om te stoppen): "
+
+#, c-format
+msgid "Using swap file \"%s\""
+msgstr "Toepassen van wisselbestand \"%s\""
+
+#, c-format
+msgid "Original file \"%s\""
+msgstr "Oorspronkelijke bestand \"%s\""
+
+msgid "Recovery completed. You should check if everything is OK."
+msgstr "Herstel is afgerond. Controleer of het resultaat juist is."
+
+msgid ""
+"\n"
+"(You might want to write out this file under another name\n"
+msgstr ""
+"\n"
+"(Een advies is dit bestand onder een andere naam op te slaan\n"
+
+msgid "and run diff with the original file to check for changes)"
+msgstr "en met 'diff' te controleren op wijzigingen)"
+
+msgid "Recovery completed. Buffer contents equals file contents."
+msgstr "Herstel is afgerond. Inhoud van het buffer komt overeen met de bestandsinhoud."
+
+msgid ""
+"\n"
+"You may want to delete the .swp file now.\n"
+"\n"
+msgstr ""
+"\n"
+"Het .swp-bestand kan nu verwijderd worden.\n"
+"\n"
+
+#. use msg() to start the scrolling properly
+msgid "Swap files found:"
+msgstr "Gevonden wisselbestanden:"
+
+msgid " In current directory:\n"
+msgstr " In huidige map:\n"
+
+msgid " Using specified name:\n"
+msgstr " Gebruikt opgegeven naam:\n"
+
+msgid " In directory "
+msgstr " In map "
+
+msgid " -- none --\n"
+msgstr " -- geen --\n"
+
+msgid " owned by: "
+msgstr " eigenaar: "
+
+msgid " dated: "
+msgstr " datum: "
+
+msgid " dated: "
+msgstr " datum: "
+
+msgid " [from Vim version 3.0]"
+msgstr " [van Vim-versie 3.0]"
+
+msgid " [does not look like a Vim swap file]"
+msgstr " [lijkt geen Vvim-wisselbestand te zijn]"
+
+msgid " file name: "
+msgstr " bestandsnaam: "
+
+msgid ""
+"\n"
+" modified: "
+msgstr ""
+"\n"
+" bewerkt: "
+
+msgid "YES"
+msgstr "JA"
+
+msgid "no"
+msgstr "nee"
+
+msgid ""
+"\n"
+" user name: "
+msgstr ""
+"\n"
+" gebruikersnaam: "
+
+msgid " host name: "
+msgstr " host-naam:"
+
+msgid ""
+"\n"
+" host name: "
+msgstr ""
+"\n"
+" host-naam: "
+
+msgid ""
+"\n"
+" process ID: "
+msgstr ""
+"\n"
+" proces-id: "
+
+msgid " (still running)"
+msgstr " (nog actief)"
+
+msgid ""
+"\n"
+" [not usable with this version of Vim]"
+msgstr ""
+"\n"
+" [onbruikbaar met deze versie van Vim]"
+
+msgid ""
+"\n"
+" [not usable on this computer]"
+msgstr ""
+"\n"
+" [onbruikbaar op deze computer]"
+
+msgid " [cannot be read]"
+msgstr " [lezen is onmogelijk]"
+
+msgid " [cannot be opened]"
+msgstr " [openen is onmogelijk]"
+
+msgid "E313: Cannot preserve, there is no swap file"
+msgstr "E313: kan niet worden behouden, want er is geen wisselbestand"
+
+msgid "File preserved"
+msgstr "Bestand behouden"
+
+msgid "E314: Preserve failed"
+msgstr "E314: behouden is mislukt"
+
+#, c-format
+msgid "E773: Symlink loop for \"%s\""
+msgstr "E773: Symbolische koppelingslus voor \"%s\""
+
+msgid "E325: ATTENTION"
+msgstr "E325: OPGELET"
+
+msgid ""
+"\n"
+"Found a swap file by the name \""
+msgstr ""
+"\n"
+"Er is een wisselbestand aangetroffen met de naam \""
+
+msgid "While opening file \""
+msgstr "bij het openen van bestand \""
+
+msgid " NEWER than swap file!\n"
+msgstr " NIEUWER dan het wisselbestand!\n"
+
+#. Some of these messages are long to allow translation to
+#. * other languages.
+msgid ""
+"\n"
+"(1) Another program may be editing the same file.\n"
+" If this is the case, be careful not to end up with two\n"
+" different instances of the same file when making changes.\n"
+msgstr ""
+"\n"
+"(1) Mogelijk wordt dit bestand met een ander programma bewerkt.\n"
+" Als dit het geval is, pas dan op niet met twee verschillende\n"
+" versies van hetzelfde bestand te eindigen bij het bewerken.\n"
+
+msgid " Quit, or continue with caution.\n"
+msgstr " Stop of ga aandachtig verder.\n"
+
+msgid ""
+"\n"
+"(2) An edit session for this file crashed.\n"
+msgstr ""
+"\n"
+"(2) Een sessie waarin dit bestand werd bewerkt is onverhoeds gestopt.\n"
+
+msgid " If this is the case, use \":recover\" or \"vim -r "
+msgstr " Als dit het geval is, gebruikt dan \":recover\" of \"vim -r "
+
+msgid ""
+"\"\n"
+" to recover the changes (see \":help recovery\").\n"
+msgstr ""
+"\"\n"
+" om de aanpassingen te herstellen (zie \":help recovery\").\n"
+
+msgid " If you did this already, delete the swap file \""
+msgstr " Als dit al gedaan is, verwijder dan het wisselbestand \""
+
+msgid ""
+"\"\n"
+" to avoid this message.\n"
+msgstr ""
+"\"\n"
+" om dit bericht te voorkomen.\n"
+
+msgid "Swap file \""
+msgstr "Wisselbestand \""
+
+msgid "\" already exists!"
+msgstr "\" bestaat al!"
+
+msgid "VIM - ATTENTION"
+msgstr "VIM - OPGELET"
+
+msgid "Swap file already exists!"
+msgstr "Wisselbestand bestaat reeds."
+
+msgid ""
+"&Open Read-Only\n"
+"&Edit anyway\n"
+"&Recover\n"
+"&Quit\n"
+"&Abort"
+msgstr ""
+"Alleen-lezen &openen\n"
+"Toch b&ewerken\n"
+"He&rstellen\n"
+"&Stoppen\n"
+"&Afbreken"
+
+msgid ""
+"&Open Read-Only\n"
+"&Edit anyway\n"
+"&Recover\n"
+"&Delete it\n"
+"&Quit\n"
+"&Abort"
+msgstr ""
+"Alleen-lezen &openen\n"
+"Toch b&ewerken\n"
+"He&rstellen\n"
+"Verwij&deren\n"
+"&Stoppen\n"
+"&Afbreken"
+
+msgid "E326: Too many swap files found"
+msgstr "E326: teveel wisselbestanden aangetroffen"
+
+msgid "E327: Part of menu-item path is not sub-menu"
+msgstr "E327: deel van menu-itempad is geen submenu"
+
+msgid "E328: Menu only exists in another mode"
+msgstr "E328: menu bestaat alleen in andere modus"
+
+#, c-format
+msgid "E329: No menu \"%s\""
+msgstr "E329: geen menu \"%s\""
+
+#. Only a mnemonic or accelerator is not valid.
+msgid "E792: Empty menu name"
+msgstr "E792: menunaam is leeg"
+
+#, c-format
+#~ msgid "E335: Menu not defined for %s mode"
+#~ msgstr ""
+
+#~ msgid "E336: Menu path must lead to a sub-menu"
+#~ msgstr ""
+
+#~ msgid "E337: Menu not found - check menu names"
+#~ msgstr ""
+
+#, c-format
+msgid "Error detected while processing %s:"
+msgstr "Fout opgetreden tijdens verwerken van %s:"
+
+#, c-format
+msgid "line %4ld:"
+msgstr "regel %4ld:"
+
+#, c-format
+#~ msgid "E354: Invalid register name: '%s'"
+#~ msgstr ""
+
+msgid "Messages maintainer: Bram Moolenaar <Bram@vim.org>"
+msgstr "Vertaald door: Erwin Poeze <erwin.poeze@gmail.com>"
+
+#~ msgid "Interrupt: "
+#~ msgstr ""
+
+msgid "Press ENTER or type command to continue"
+msgstr "Toets ENTER of typ een opdracht om verder te gaan"
+
+#, c-format
+msgid "%s line %ld"
+msgstr "%s regel %ld"
+
+msgid "-- More --"
+msgstr "-- meer --"
+
+#~ msgid " SPACE/d/j: screen/page/line down, b/u/k: up, q: quit "
+#~ msgstr ""
+
+msgid "Question"
+msgstr "Vraag"
+
+#~ msgid ""
+#~ "&Yes\n"
+#~ "&No"
+#~ msgstr ""
+
+#~ msgid ""
+#~ "&Yes\n"
+#~ "&No\n"
+#~ "Save &All\n"
+#~ "&Discard All\n"
+#~ "&Cancel"
+#~ msgstr ""
+
+#~ msgid "Select Directory dialog"
+#~ msgstr ""
+
+#~ msgid "Save File dialog"
+#~ msgstr ""
+
+#~ msgid "Open File dialog"
+#~ msgstr ""
+
+#. TODO: non-GUI file selector here
+#~ msgid "E338: Sorry, no file browser in console mode"
+#~ msgstr ""
+
+#~ msgid "E766: Insufficient arguments for printf()"
+#~ msgstr ""
+
+#~ msgid "E807: Expected Float argument for printf()"
+#~ msgstr ""
+
+#~ msgid "E767: Too many arguments to printf()"
+#~ msgstr ""
+
+#~ msgid "W10: Warning: Changing a readonly file"
+#~ msgstr ""
+
+#~ msgid "Type number and <Enter> or click with mouse (empty cancels): "
+#~ msgstr ""
+
+#~ msgid "Type number and <Enter> (empty cancels): "
+#~ msgstr ""
+
+msgid "1 more line"
+msgstr "1 regel meer"
+
+msgid "1 line less"
+msgstr "1 regel minder"
+
+#, c-format
+msgid "%ld more lines"
+msgstr "%ld regels meer"
+
+#, c-format
+msgid "%ld fewer lines"
+msgstr "%ld regels minder"
+
+msgid " (Interrupted)"
+msgstr " (onderbroken)"
+
+msgid "Beep!"
+msgstr "biep!"
+
+#~ msgid "Vim: preserving files...\n"
+#~ msgstr ""
+
+#. close all memfiles, without deleting
+#~ msgid "Vim: Finished.\n"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "ERROR: "
+#~ msgstr ""
+
+#, c-format
+#~ msgid ""
+#~ "\n"
+#~ "[bytes] total alloc-freed %lu-%lu, in use %lu, peak use %lu\n"
+#~ msgstr ""
+
+#, c-format
+#~ msgid ""
+#~ "[calls] total re/malloc()'s %lu, total free()'s %lu\n"
+#~ "\n"
+#~ msgstr ""
+
+#~ msgid "E340: Line is becoming too long"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E341: Internal error: lalloc(%ld, )"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E342: Out of memory! (allocating %lu bytes)"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "Calling shell to execute: \"%s\""
+#~ msgstr ""
+
+#~ msgid "E545: Missing colon"
+#~ msgstr ""
+
+#~ msgid "E546: Illegal mode"
+#~ msgstr ""
+
+#~ msgid "E547: Illegal mouseshape"
+#~ msgstr ""
+
+#~ msgid "E548: digit expected"
+#~ msgstr ""
+
+#~ msgid "E549: Illegal percentage"
+#~ msgstr ""
+
+#~ msgid "Enter encryption key: "
+#~ msgstr ""
+
+#~ msgid "Enter same key again: "
+#~ msgstr ""
+
+#~ msgid "Keys don't match!"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E343: Invalid path: '**[number]' must be at the end of the path or be followed by '%s'."
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E344: Can't find directory \"%s\" in cdpath"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E345: Can't find file \"%s\" in path"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E346: No more directory \"%s\" found in cdpath"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E347: No more file \"%s\" found in path"
+#~ msgstr ""
+
+#~ msgid "Cannot connect to Netbeans #2"
+#~ msgstr ""
+
+#~ msgid "Cannot connect to Netbeans"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E668: Wrong access mode for NetBeans connection info file: \"%s\""
+#~ msgstr ""
+
+#~ msgid "read from Netbeans socket"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E658: NetBeans connection lost for buffer %ld"
+#~ msgstr ""
+
+#~ msgid "E511: netbeans already connected"
+#~ msgstr ""
+
+#~ msgid "E505: "
+#~ msgstr ""
+
+#~ msgid "E349: No identifier under cursor"
+#~ msgstr ""
+
+#~ msgid "E774: 'operatorfunc' is empty"
+#~ msgstr ""
+
+#~ msgid "E775: Eval feature not available"
+#~ msgstr ""
+
+msgid "Warning: terminal cannot highlight"
+msgstr "waarschuwing: terminal kan niet oplichten"
+
+#~ msgid "E348: No string under cursor"
+#~ msgstr ""
+
+#~ msgid "E352: Cannot erase folds with current 'foldmethod'"
+#~ msgstr ""
+
+msgid "E664: changelist is empty"
+msgstr "E664: wijzigingslijst is leeg"
+
+msgid "E662: At start of changelist"
+msgstr "E662: begin van wijzigingslijst"
+
+msgid "E663: At end of changelist"
+msgstr "E663: einde van wijzigingslijst"
+
+msgid "Type :quit<Enter> to exit Vim"
+msgstr "Typ :quit<Enter> om Vim te verlaten"
+
+#, c-format
+msgid "1 line %sed 1 time"
+msgstr "1 regel %sed 1 maal"
+
+#, c-format
+msgid "1 line %sed %d times"
+msgstr "1 regel %sed %d maal"
+
+#, c-format
+msgid "%ld lines %sed 1 time"
+msgstr "%ld regels %sed 1 maal"
+
+#, c-format
+msgid "%ld lines %sed %d times"
+msgstr "%ld regels %sed %d maal"
+
+#, c-format
+msgid "%ld lines to indent... "
+msgstr "%ld in te springen regels... "
+
+msgid "1 line indented "
+msgstr "1 regel ingesprongen "
+
+#, c-format
+msgid "%ld lines indented "
+msgstr "%ld regels ingesprongen "
+
+#~ msgid "E748: No previously used register"
+#~ msgstr ""
+
+#. must display the prompt
+msgid "cannot yank; delete anyway"
+msgstr "kopiëren niet mogelijk; toch verwijderd"
+
+msgid "1 line changed"
+msgstr "1 regel gewijzigd"
+
+#, c-format
+msgid "%ld lines changed"
+msgstr "%ld regels gewijzigd"
+
+#, c-format
+#~ msgid "freeing %ld lines"
+#~ msgstr ""
+
+msgid "block of 1 line yanked"
+msgstr "blok van 1 regel gekopieerd"
+
+msgid "1 line yanked"
+msgstr "1 regel gekopieerd"
+
+#, c-format
+msgid "block of %ld lines yanked"
+msgstr "blok van %ld regels gekopieerd"
+
+#, c-format
+msgid "%ld lines yanked"
+msgstr "%ld regels gekopieerd"
+
+#, c-format
+msgid "E353: Nothing in register %s"
+msgstr "E353: niets in register %s"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Registers ---"
+msgstr ""
+"\n"
+"--- Registers ---"
+
+msgid "Illegal register name"
+msgstr "ongeldige registernaam"
+
+#, c-format
+msgid ""
+"\n"
+"# Registers:\n"
+msgstr ""
+"\n"
+"# Registers:\n"
+
+#, c-format
+#~ msgid "E574: Unknown register type %d"
+#~ msgstr ""
+
+#, c-format
+msgid "%ld Cols; "
+msgstr "%ld koln; "
+
+#, c-format
+msgid "Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Bytes"
+msgstr "geselecteerd %s%ld van %ld regels; %ld van %ld woorden; %ld van %ld bytes"
+
+#, c-format
+msgid "Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Chars; %ld of %ld Bytes"
+msgstr "geselecteerd %s%ld van %ld regels; %ld van %ld woorden; %ld van %ld rekens; %ld van %ld bytes"
+
+#, c-format
+msgid "Col %s of %s; Line %ld of %ld; Word %ld of %ld; Byte %ld of %ld"
+msgstr "kol %s van %s; regel %ld van %ld; woord %ld van %ld; byte %ld van %ld"
+
+#, c-format
+msgid "Col %s of %s; Line %ld of %ld; Word %ld of %ld; Char %ld of %ld; Byte %ld of %ld"
+msgstr "kol %s van %s; regel %ld van %ld; woord %ld van %ld; teken %ld van %ld; byte %ld van %ld"
+
+#, c-format
+msgid "(+%ld for BOM)"
+msgstr "(+%ld voor BOD)"
+
+msgid "%<%f%h%m%=Page %N"
+msgstr "%<%f%h%m%=pagina %N"
+
+msgid "Thanks for flying Vim"
+msgstr "Dank voor het gebruik van Vim"
+
+msgid "E518: Unknown option"
+msgstr "E518: onbekende optie"
+
+msgid "E519: Option not supported"
+msgstr "E519: optie niet ondersteund"
+
+#~ msgid "E520: Not allowed in a modeline"
+#~ msgstr ""
+
+#~ msgid "E521: Number required after ="
+#~ msgstr ""
+
+#~ msgid "E522: Not found in termcap"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E539: Illegal character <%s>"
+#~ msgstr ""
+
+#~ msgid "E529: Cannot set 'term' to empty string"
+#~ msgstr ""
+
+#~ msgid "E530: Cannot change term in GUI"
+#~ msgstr ""
+
+#~ msgid "E531: Use \":gui\" to start the GUI"
+#~ msgstr ""
+
+#~ msgid "E589: 'backupext' and 'patchmode' are equal"
+#~ msgstr ""
+
+#~ msgid "E617: Cannot be changed in the GTK+ 2 GUI"
+#~ msgstr ""
+
+#~ msgid "E524: Missing colon"
+#~ msgstr ""
+
+#~ msgid "E525: Zero length string"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E526: Missing number after <%s>"
+#~ msgstr ""
+
+#~ msgid "E527: Missing comma"
+#~ msgstr ""
+
+#~ msgid "E528: Must specify a ' value"
+#~ msgstr ""
+
+#~ msgid "E595: contains unprintable or wide character"
+#~ msgstr ""
+
+#~ msgid "E596: Invalid font(s)"
+#~ msgstr ""
+
+#~ msgid "E597: can't select fontset"
+#~ msgstr ""
+
+#~ msgid "E598: Invalid fontset"
+#~ msgstr ""
+
+#~ msgid "E533: can't select wide font"
+#~ msgstr ""
+
+#~ msgid "E534: Invalid wide font"
+#~ msgstr ""
+
+#, c-format
+msgid "E535: Illegal character after <%c>"
+msgstr "E535: ongeldig teken na <%c>"
+
+msgid "E536: comma required"
+msgstr "E536: komma is vereist"
+
+#, c-format
+msgid "E537: 'commentstring' must be empty or contain %s"
+msgstr "E537: 'commentstring' moet leeg zijn of het volgende bevatten: %s"
+
+msgid "E538: No mouse support"
+msgstr "E538: geen muisondersteuning"
+
+msgid "E540: Unclosed expression sequence"
+msgstr "E540: ongepaarde expressie-volgorde"
+
+msgid "E541: too many items"
+msgstr "E541: teveel items"
+
+msgid "E542: unbalanced groups"
+msgstr "E542: ongepaarde groepen"
+
+msgid "E590: A preview window already exists"
+msgstr "E590: een voorvertoningsvenster bestaat al"
+
+msgid "W17: Arabic requires UTF-8, do ':set encoding=utf-8'"
+msgstr "W17: Arabisch vereist UTF-8, typ ':set encoding=utf-8'"
+
+#, c-format
+msgid "E593: Need at least %d lines"
+msgstr "E593: vereist minstens %d regels"
+
+#, c-format
+msgid "E594: Need at least %d columns"
+msgstr "E594: vereist minstens %d kolommen"
+
+#, c-format
+msgid "E355: Unknown option: %s"
+msgstr "E355: onbekende optie: %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.
+#, c-format
+msgid "E521: Number required: &%s = '%s'"
+msgstr "E521: 'Number' vereist: &%s = '%s'"
+
+msgid ""
+"\n"
+"--- Terminal codes ---"
+msgstr ""
+"\n"
+"--- Terminal-codes ---"
+
+msgid ""
+"\n"
+"--- Global option values ---"
+msgstr ""
+"\n"
+"--- Globale optiewaarden ---"
+
+msgid ""
+"\n"
+"--- Local option values ---"
+msgstr ""
+"\n"
+"--- Lokale optiewaarden ---"
+
+msgid ""
+"\n"
+"--- Options ---"
+msgstr ""
+"\n"
+"--- Opties ---"
+
+#~ msgid "E356: get_varp ERROR"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E357: 'langmap': Matching character missing for %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E358: 'langmap': Extra characters after semicolon: %s"
+#~ msgstr ""
+
+msgid "cannot open "
+msgstr "gefaald tijden openen van "
+
+msgid "VIM: Can't open window!\n"
+msgstr "VIM: kan venster niet openen!\n"
+
+msgid "Need Amigados version 2.04 or later\n"
+msgstr "Vereist Amigados versie 2.04 of nieuwer\n"
+
+#, c-format
+msgid "Need %s version %ld\n"
+msgstr "Vereist %s versie %ld\n"
+
+#~ msgid "Cannot open NIL:\n"
+#~ msgstr ""
+
+msgid "Cannot create "
+msgstr "Gefaald tijdens aanmaken van "
+
+#, c-format
+msgid "Vim exiting with %d\n"
+msgstr "Vim stoppen met %d\n"
+
+#~ msgid "cannot change console mode ?!\n"
+#~ msgstr ""
+
+#~ msgid "mch_get_shellsize: not a console??\n"
+#~ msgstr ""
+
+#. if Vim opened a window: Executing a shell may cause crashes
+#~ msgid "E360: Cannot execute shell with -f option"
+#~ msgstr ""
+
+#~ msgid "Cannot execute "
+#~ msgstr ""
+
+#~ msgid "shell "
+#~ msgstr ""
+
+#~ msgid " returned\n"
+#~ msgstr ""
+
+#~ msgid "ANCHOR_BUF_SIZE too small."
+#~ msgstr ""
+
+#~ msgid "I/O ERROR"
+#~ msgstr ""
+
+#~ msgid "Message"
+#~ msgstr ""
+
+#~ msgid "'columns' is not 80, cannot execute external commands"
+#~ msgstr ""
+
+#~ msgid "E237: Printer selection failed"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "to %s on %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E613: Unknown printer font: %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E238: Print error: %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "Printing '%s'"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E244: Illegal charset name \"%s\" in font name \"%s\""
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E245: Illegal char '%c' in font name \"%s\""
+#~ msgstr ""
+
+#~ msgid "E366: Invalid 'osfiletype' option - using Text"
+#~ msgstr ""
+
+msgid "Vim: Double signal, exiting\n"
+msgstr "Vim: dubbel signaal, stoppen\n"
+
+#, c-format
+msgid "Vim: Caught deadly signal %s\n"
+msgstr "Vim: fataal signaal gevangen %s\n"
+
+#, c-format
+msgid "Vim: Caught deadly signal\n"
+msgstr "Vim: fataal signaal gevangen\n"
+
+#, c-format
+msgid "Opening the X display took %ld msec"
+msgstr "Openen van X-display vereiste %ld ms"
+
+#~ msgid ""
+#~ "\n"
+#~ "Vim: Got X error\n"
+#~ msgstr ""
+
+#~ msgid "Testing the X display failed"
+#~ msgstr ""
+
+#~ msgid "Opening the X display timed out"
+#~ msgstr ""
+
+#~ msgid ""
+#~ "\n"
+#~ "Could not get security context for "
+#~ msgstr ""
+
+#~ msgid ""
+#~ "\n"
+#~ "Could not set security context for "
+#~ msgstr ""
+
+#~ msgid ""
+#~ "\n"
+#~ "Cannot execute shell "
+#~ msgstr ""
+
+#~ msgid ""
+#~ "\n"
+#~ "Cannot execute shell sh\n"
+#~ msgstr ""
+
+#~ msgid ""
+#~ "\n"
+#~ "shell returned "
+#~ msgstr ""
+
+#~ msgid ""
+#~ "\n"
+#~ "Cannot create pipes\n"
+#~ msgstr ""
+
+#~ msgid ""
+#~ "\n"
+#~ "Cannot fork\n"
+#~ msgstr ""
+
+#~ msgid ""
+#~ "\n"
+#~ "Command terminated\n"
+#~ msgstr ""
+
+#~ msgid "XSMP lost ICE connection"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "dlerror = \"%s\""
+#~ msgstr ""
+
+#~ msgid "Opening the X display failed"
+#~ msgstr ""
+
+#~ msgid "XSMP handling save-yourself request"
+#~ msgstr ""
+
+#~ msgid "XSMP opening connection"
+#~ msgstr ""
+
+#~ msgid "XSMP ICE connection watch failed"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "XSMP SmcOpenConnection failed: %s"
+#~ msgstr ""
+
+msgid "At line"
+msgstr "Bij regel"
+
+#~ msgid "Could not load vim32.dll!"
+#~ msgstr ""
+
+msgid "VIM Error"
+msgstr "Vim-fout"
+
+#~ msgid "Could not fix up function pointers to the DLL!"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "shell returned %d"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "Vim: Caught %s event\n"
+#~ msgstr ""
+
+msgid "close"
+msgstr "sluiten"
+
+msgid "logoff"
+msgstr "uitloggen"
+
+msgid "shutdown"
+msgstr "afsluiten"
+
+msgid "E371: Command not found"
+msgstr "E371: opdracht niet gevonden"
+
+#~ 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 ""
+
+msgid "Vim Warning"
+msgstr "Vim-waarschuwing"
+
+#, c-format
+#~ msgid "E372: Too many %%%c in format string"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E373: Unexpected %%%c in format string"
+#~ msgstr ""
+
+#~ msgid "E374: Missing ] in format string"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E375: Unsupported %%%c in format string"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E376: Invalid %%%c in format string prefix"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E377: Invalid %%%c in format string"
+#~ msgstr ""
+
+#~ msgid "E378: 'errorformat' contains no pattern"
+#~ msgstr ""
+
+#~ msgid "E379: Missing or empty directory name"
+#~ msgstr ""
+
+#~ msgid "E553: No more items"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "(%d of %d)%s%s: "
+#~ msgstr ""
+
+#~ msgid " (line deleted)"
+#~ msgstr ""
+
+#~ msgid "E380: At bottom of quickfix stack"
+#~ msgstr ""
+
+#~ msgid "E381: At top of quickfix stack"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "error list %d of %d; %d errors"
+#~ msgstr ""
+
+#~ msgid "E382: Cannot write, 'buftype' option is set"
+#~ msgstr ""
+
+#~ msgid "E683: File name missing or invalid pattern"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "Cannot open file \"%s\""
+#~ msgstr ""
+
+msgid "E681: Buffer is not loaded"
+msgstr "E681: buffer is niet geladen"
+
+#~ msgid "E777: String or List expected"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E369: invalid item in %s%%[]"
+#~ msgstr ""
+
+#~ msgid "E339: Pattern too long"
+#~ msgstr ""
+
+#~ msgid "E50: Too many \\z("
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E51: Too many %s("
+#~ msgstr ""
+
+msgid "E52: Unmatched \\z("
+msgstr "E52: \\z( is niet gepaard"
+
+#, c-format
+msgid "E53: Unmatched %s%%("
+msgstr "E53: %s%%( is niet gepaard"
+
+#, c-format
+msgid "E54: Unmatched %s("
+msgstr "E54: %s( is niet gepaard"
+
+#, c-format
+msgid "E55: Unmatched %s)"
+msgstr "E55: %s) is ongepaard"
+
+#, c-format
+#~ msgid "E59: invalid character after %s@"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E60: Too many complex %s{...}s"
+#~ msgstr ""
+
+#, c-format
+msgid "E61: Nested %s*"
+msgstr "E61: geneste %s*"
+
+#, c-format
+msgid "E62: Nested %s%c"
+msgstr "E62: geneste %s%c"
+
+msgid "E63: invalid use of \\_"
+msgstr "E63: onjuist gebruikt van \\_"
+
+#, c-format
+msgid "E64: %s%c follows nothing"
+msgstr "E64: %s%c volgt op niets"
+
+msgid "E65: Illegal back reference"
+msgstr "E65: ongeldige terugverwijzing"
+
+msgid "E66: \\z( not allowed here"
+msgstr "E66: \\z( hier niet toegestaan"
+
+msgid "E67: \\z1 et al. not allowed here"
+msgstr "E67: \\z1 en andere hier niet toegestaan"
+
+msgid "E68: Invalid character after \\z"
+msgstr "E68: ongeldig teken na \\z"
+
+#, c-format
+msgid "E69: Missing ] after %s%%["
+msgstr "E69: ontbrekende ] na %s%%["
+
+#, c-format
+msgid "E70: Empty %s%%[]"
+msgstr "E70: leeg %s%%[]"
+
+#, c-format
+msgid "E678: Invalid character after %s%%[dxouU]"
+msgstr "E678: onjuist teken na %s%%[dxouU]"
+
+#, c-format
+msgid "E71: Invalid character after %s%%"
+msgstr "E71: onjuist teken na %s%%"
+
+#, c-format
+msgid "E769: Missing ] after %s["
+msgstr "E769: ontbrekende ] na %s["
+
+#, c-format
+msgid "E554: Syntax error in %s{...}"
+msgstr "E554: Syntaxfout in %s{...}"
+
+#~ msgid "External submatches:\n"
+#~ msgstr ""
+
+#~ msgid " VREPLACE"
+#~ msgstr ""
+
+msgid " REPLACE"
+msgstr " VERVANGEN"
+
+#~ msgid " REVERSE"
+#~ msgstr ""
+
+msgid " INSERT"
+msgstr " INVOEGEN"
+
+msgid " (insert)"
+msgstr " (invoegen)"
+
+msgid " (replace)"
+msgstr " (vervangen)"
+
+#~ msgid " (vreplace)"
+#~ msgstr ""
+
+#~ msgid " Hebrew"
+#~ msgstr ""
+
+#~ msgid " Arabic"
+#~ msgstr ""
+
+#~ msgid " (lang)"
+#~ msgstr ""
+
+#~ msgid " (paste)"
+#~ msgstr ""
+
+msgid " VISUAL"
+msgstr " VISUEEL"
+
+msgid " VISUAL LINE"
+msgstr " VISUELE REGEL"
+
+msgid " VISUAL BLOCK"
+msgstr " VISUEEL BLOK"
+
+msgid " SELECT"
+msgstr " SELECTEREN"
+
+msgid " SELECT LINE"
+msgstr " REGELSELECTIE"
+
+msgid " SELECT BLOCK"
+msgstr " BLOKSELECTIE"
+
+msgid "recording"
+msgstr "opnemen"
+
+#, c-format
+msgid "E383: Invalid search string: %s"
+msgstr "E383: ongeldige zoekstring: %s"
+
+#, c-format
+msgid "E384: search hit TOP without match for: %s"
+msgstr "E384: TOP bereikt zonder overeenkomst voor: %s"
+
+#, c-format
+msgid "E385: search hit BOTTOM without match for: %s"
+msgstr "E385: BODEM bereikt zonder overeenkomst voor: %s"
+
+msgid "E386: Expected '?' or '/' after ';'"
+msgstr "E386: verwachte '?' of '/' na ';'"
+
+msgid " (includes previously listed match)"
+msgstr " (bevat eerder getoonde overeenkomst)"
+
+#. cursor at status line
+msgid "--- Included files "
+msgstr "--- bevatte bestanden "
+
+msgid "not found "
+msgstr "niet gevonden "
+
+msgid "in path ---\n"
+msgstr "in pad ---\n"
+
+msgid " (Already listed)"
+msgstr " (Reeds getoond)"
+
+msgid " NOT FOUND"
+msgstr " NIET GEVONDEN"
+
+#, c-format
+#~ msgid "Scanning included file: %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "Searching included file %s"
+#~ msgstr ""
+
+#~ msgid "E387: Match is on current line"
+#~ msgstr ""
+
+#~ msgid "All included files were found"
+#~ msgstr ""
+
+#~ msgid "No included files"
+#~ msgstr ""
+
+#~ msgid "E388: Couldn't find definition"
+#~ msgstr ""
+
+msgid "E389: Couldn't find pattern"
+msgstr "E389: kan zoekpatroon niet vinden"
+
+msgid "Substitute "
+msgstr "Vervangen "
+
+#, c-format
+msgid ""
+"\n"
+"# Last %sSearch Pattern:\n"
+"~"
+msgstr ""
+"\n"
+"# Laatste %szoekpatroon:\n"
+"~"
+
+#~ msgid "E759: Format error in spell file"
+#~ msgstr ""
+
+#~ msgid "E758: Truncated spell file"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "Trailing text in %s line %d: %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "Affix name too long in %s line %d: %s"
+#~ msgstr ""
+
+#~ msgid "E761: Format error in affix file FOL, LOW or UPP"
+#~ msgstr ""
+
+#~ msgid "E762: Character in FOL, LOW or UPP is out of range"
+#~ msgstr ""
+
+#~ msgid "Compressing word tree..."
+#~ msgstr ""
+
+#~ msgid "E756: Spell checking is not enabled"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "Warning: Cannot find word list \"%s.%s.spl\" or \"%s.ascii.spl\""
+#~ msgstr ""
+
+#, c-format
+#~ msgid "Reading spell file \"%s\""
+#~ msgstr ""
+
+#~ msgid "E757: This does not look like a spell file"
+#~ msgstr ""
+
+#~ msgid "E771: Old spell file, needs to be updated"
+#~ msgstr ""
+
+#~ msgid "E772: Spell file is for newer version of Vim"
+#~ msgstr ""
+
+#~ msgid "E770: Unsupported section in spell file"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "Warning: region %s not supported"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "Reading affix file %s ..."
+#~ msgstr ""
+
+#, c-format
+#~ msgid "Conversion failure for word in %s line %d: %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "Conversion in %s not supported: from %s to %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "Conversion in %s not supported"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "Invalid value for FLAG in %s line %d: %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "FLAG after using flags in %s line %d: %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "Defining COMPOUNDFORBIDFLAG after PFX item may give wrong results in %s line %d"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in %s line %d"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "Wrong COMPOUNDRULES value in %s line %d: %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "Wrong COMPOUNDWORDMAX value in %s line %d: %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "Wrong COMPOUNDMIN value in %s line %d: %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "Wrong COMPOUNDSYLMAX value in %s line %d: %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "Wrong CHECKCOMPOUNDPATTERN value in %s line %d: %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "Different combining flag in continued affix block in %s line %d: %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "Duplicate affix in %s line %d: %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "Affix also used for BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST in %s line %d: %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "Expected Y or N in %s line %d: %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "Broken condition in %s line %d: %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "Expected REP(SAL) count in %s line %d"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "Expected MAP count in %s line %d"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "Duplicate character in MAP in %s line %d"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "Unrecognized or duplicate item in %s line %d: %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "Missing FOL/LOW/UPP line in %s"
+#~ msgstr ""
+
+#~ msgid "COMPOUNDSYLMAX used without SYLLABLE"
+#~ msgstr ""
+
+#~ 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 ""
+
+#, c-format
+#~ msgid "Both SAL and SOFO lines in %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "Flag is not a number in %s line %d: %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "Illegal flag in %s line %d: %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "%s value differs from what is used in another .aff file"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "Reading dictionary file %s ..."
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E760: No word count in %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "line %6d, word %6d - %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "Duplicate word in %s line %d: %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "First duplicate word in %s line %d: %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "%d duplicate word(s) in %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "Ignored %d word(s) with non-ASCII characters in %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "Reading word file %s ..."
+#~ msgstr ""
+
+#, c-format
+#~ msgid "Duplicate /encoding= line ignored in %s line %d: %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "/encoding= line after word ignored in %s line %d: %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "Duplicate /regions= line ignored in %s line %d: %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "Too many regions in %s line %d: %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "/ line ignored in %s line %d: %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "Invalid region nr in %s line %d: %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "Unrecognized flags in %s line %d: %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "Ignored %d words with non-ASCII characters"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "Compressed %d of %d nodes; %d (%d%%) remaining"
+#~ msgstr ""
+
+#~ msgid "Reading back spell file..."
+#~ msgstr ""
+
+#.
+#. * Go through the trie of good words, soundfold each word and add it to
+#. * the soundfold trie.
+#.
+#~ msgid "Performing soundfolding..."
+#~ msgstr ""
+
+#, c-format
+#~ msgid "Number of words after soundfolding: %ld"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "Total number of words: %d"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "Writing suggestion file %s ..."
+#~ msgstr ""
+
+#, c-format
+#~ msgid "Estimated runtime memory use: %d bytes"
+#~ msgstr ""
+
+#~ msgid "E751: Output file name must not have region name"
+#~ msgstr ""
+
+#~ msgid "E754: Only up to 8 regions supported"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E755: Invalid region in %s"
+#~ msgstr ""
+
+#~ msgid "Warning: both compounding and NOBREAK specified"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "Writing spell file %s ..."
+#~ msgstr ""
+
+#~ msgid "Done!"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E765: 'spellfile' does not have %ld entries"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "Word removed from %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "Word added to %s"
+#~ msgstr ""
+
+#~ msgid "E763: Word characters differ between spell files"
+#~ msgstr ""
+
+#~ msgid "Sorry, no suggestions"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "Sorry, only %ld suggestions"
+#~ msgstr ""
+
+#. for when 'cmdheight' > 1
+#. avoid more prompt
+#, c-format
+#~ msgid "Change \"%.*s\" to:"
+#~ msgstr ""
+
+#, c-format
+#~ msgid " < \"%.*s\""
+#~ msgstr ""
+
+#~ msgid "E752: No previous spell replacement"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E753: Not found: %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E778: This does not look like a .sug file: %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E779: Old .sug file, needs to be updated: %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E780: .sug file is for newer version of Vim: %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E781: .sug file doesn't match .spl file: %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E782: error while reading .sug file: %s"
+#~ msgstr ""
+
+#. This should have been checked when generating the .spl
+#. * file.
+#~ msgid "E783: duplicate char in MAP entry"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E390: Illegal argument: %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E391: No such syntax cluster: %s"
+#~ msgstr ""
+
+#~ msgid "No Syntax items defined for this buffer"
+#~ msgstr ""
+
+#~ msgid "syncing on C-style comments"
+#~ msgstr ""
+
+#~ msgid "no syncing"
+#~ msgstr ""
+
+#~ msgid "syncing starts "
+#~ msgstr ""
+
+#~ msgid " lines before top line"
+#~ msgstr ""
+
+#~ msgid ""
+#~ "\n"
+#~ "--- Syntax sync items ---"
+#~ msgstr ""
+
+#~ msgid ""
+#~ "\n"
+#~ "syncing on items"
+#~ msgstr ""
+
+#~ msgid ""
+#~ "\n"
+#~ "--- Syntax items ---"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E392: No such syntax cluster: %s"
+#~ msgstr ""
+
+#~ msgid "minimal "
+#~ msgstr ""
+
+#~ msgid "maximal "
+#~ msgstr ""
+
+#~ msgid "; match "
+#~ msgstr ""
+
+#~ msgid " line breaks"
+#~ msgstr ""
+
+#~ msgid "E395: contains argument not accepted here"
+#~ msgstr ""
+
+#~ msgid "E396: containedin argument not accepted here"
+#~ msgstr ""
+
+#~ msgid "E393: group[t]here not accepted here"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E394: Didn't find region item for %s"
+#~ msgstr ""
+
+#~ msgid "E397: Filename required"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E789: Missing ']': %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E398: Missing '=': %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E399: Not enough arguments: syntax region %s"
+#~ msgstr ""
+
+#~ msgid "E400: No cluster specified"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E401: Pattern delimiter not found: %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E402: Garbage after pattern: %s"
+#~ msgstr ""
+
+#~ msgid "E403: syntax sync: line continuations pattern specified twice"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E404: Illegal arguments: %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E405: Missing equal sign: %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E406: Empty argument: %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E407: %s not allowed here"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E408: %s must be first in contains list"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E409: Unknown group name: %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E410: Invalid :syntax subcommand: %s"
+#~ msgstr ""
+
+#~ msgid "E679: recursive loop loading syncolor.vim"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E411: highlight group not found: %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E412: Not enough arguments: \":highlight link %s\""
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E413: Too many arguments: \":highlight link %s\""
+#~ msgstr ""
+
+#~ msgid "E414: group has settings, highlight link ignored"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E415: unexpected equal sign: %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E416: missing equal sign: %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E417: missing argument: %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E418: Illegal value: %s"
+#~ msgstr ""
+
+#~ msgid "E419: FG color unknown"
+#~ msgstr ""
+
+#~ msgid "E420: BG color unknown"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E421: Color name or number not recognized: %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E422: terminal code too long: %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E423: Illegal argument: %s"
+#~ msgstr ""
+
+#~ msgid "E424: Too many different highlighting attributes in use"
+#~ msgstr ""
+
+#~ msgid "E669: Unprintable character in group name"
+#~ msgstr ""
+
+#~ msgid "W18: Invalid character in group name"
+#~ msgstr ""
+
+#~ msgid "E555: at bottom of tag stack"
+#~ msgstr ""
+
+#~ msgid "E556: at top of tag stack"
+#~ msgstr ""
+
+#~ msgid "E425: Cannot go before first matching tag"
+#~ msgstr ""
+
+#, c-format
+msgid "E426: tag not found: %s"
+msgstr "E426: tag niet gevonden: %s"
+
+#~ msgid " # pri kind tag"
+#~ msgstr ""
+
+#~ msgid "file\n"
+#~ msgstr ""
+
+#~ msgid "E427: There is only one matching tag"
+#~ msgstr ""
+
+#~ msgid "E428: Cannot go beyond last matching tag"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "File \"%s\" does not exist"
+#~ msgstr ""
+
+#. Give an indication of the number of matching tags
+#, c-format
+#~ msgid "tag %d of %d%s"
+#~ msgstr ""
+
+#~ msgid " or more"
+#~ msgstr ""
+
+#~ msgid " Using tag with different case!"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E429: File \"%s\" does not exist"
+#~ msgstr ""
+
+#. Highlight title
+#~ msgid ""
+#~ "\n"
+#~ " # TO tag FROM line in file/text"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "Searching tags file %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E430: Tag file path truncated for %s\n"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E431: Format error in tags file \"%s\""
+#~ msgstr ""
+
+#, c-format
+#~ msgid "Before byte %ld"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E432: Tags file not sorted: %s"
+#~ msgstr ""
+
+#. never opened any tags file
+msgid "E433: No tags file"
+msgstr "E433: geen tags-bestand"
+
+#~ msgid "Ignoring long line in tags file"
+#~ msgstr ""
+
+#~ msgid "E434: Can't find tag pattern"
+#~ msgstr ""
+
+#~ msgid "E435: Couldn't find tag, just guessing!"
+#~ msgstr ""
+
+#~ msgid "' not known. Available builtin terminals are:"
+#~ msgstr ""
+
+#~ msgid "defaulting to '"
+#~ msgstr ""
+
+#~ msgid "E557: Cannot open termcap file"
+#~ msgstr ""
+
+#~ msgid "E558: Terminal entry not found in terminfo"
+#~ msgstr ""
+
+#~ msgid "E559: Terminal entry not found in termcap"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E436: No \"%s\" entry in termcap"
+#~ msgstr ""
+
+#~ msgid "E437: terminal capability \"cm\" required"
+#~ msgstr ""
+
+#. Highlight title
+#~ msgid ""
+#~ "\n"
+#~ "--- Terminal keys ---"
+#~ msgstr ""
+
+#~ msgid "new shell started\n"
+#~ msgstr ""
+
+msgid "Vim: Error reading input, exiting...\n"
+msgstr "Vim: lezen van de invoer is mislukt. Stoppen...\n"
+
+#~ msgid "Used CUT_BUFFER0 instead of empty selection"
+#~ msgstr ""
+
+#. must display the prompt
+#~ msgid "No undo possible; continue anyway"
+#~ msgstr ""
+
+#. magic at start of header
+#. magic after last header
+#. magic at start of entry
+#. magic after last entry
+#. 2-byte undofile version number
+#. idem, encrypted
+#, c-format
+#~ msgid "E828: Cannot open undo file for writing: %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E825: Corrupted undo file (%s): %s"
+#~ msgstr ""
+
+#~ msgid "Cannot write undo file in any directory in 'undodir'"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "Will not overwrite with undo file, cannot read: %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "Will not overwrite, this is not an undo file: %s"
+#~ msgstr ""
+
+#~ msgid "Skipping undo file write, noting to undo"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "Writing undo file: %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E829: write error in undo file: %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "Not reading undo file, owner differs: %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "Reading undo file: %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E822: Cannot open undo file for reading: %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E823: Not an undo file: %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E832: Non-encrypted file has encrypted undo file: %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E826: Undo file decryption failed: %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E827: Undo file is encrypted: %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E824: Incompatible undo file: %s"
+#~ msgstr ""
+
+#~ msgid "File contents changed, cannot use undo info"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "Finished reading undo file %s"
+#~ msgstr ""
+
+msgid "Already at oldest change"
+msgstr "Reeds de laatste wijziging"
+
+msgid "Already at newest change"
+msgstr "Reeds de nieuwste wijziging"
+
+#, c-format
+msgid "E830: Undo number %ld not found"
+msgstr "E830: Ongedaan-nummer %ld niet gevonden"
+
+msgid "E438: u_undo: line numbers wrong"
+msgstr "E438: u_undo: regelnummers onjuist"
+
+msgid "more line"
+msgstr "extra regel"
+
+msgid "more lines"
+msgstr "extra regel"
+
+msgid "line less"
+msgstr "regel minder"
+
+msgid "fewer lines"
+msgstr "regels minder"
+
+msgid "change"
+msgstr "wijziging"
+
+msgid "changes"
+msgstr "wijzigingen"
+
+#, c-format
+msgid "%ld %s; %s #%ld %s"
+msgstr "%ld %s; %s #%ld %s"
+
+msgid "before"
+msgstr "voor"
+
+msgid "after"
+msgstr "na"
+
+msgid "Nothing to undo"
+msgstr "Niets om ongedaan te maken"
+
+msgid "number changes time"
+msgstr "aantal wijzign tijd"
+
+#, c-format
+msgid "%ld seconds ago"
+msgstr "%ld seconden geleden"
+
+#~ msgid "E790: undojoin is not allowed after undo"
+#~ msgstr ""
+
+#~ msgid "E439: undo list corrupt"
+#~ msgstr ""
+
+#~ msgid "E440: undo line missing"
+#~ msgstr ""
+
+#. Only MS VC 4.1 and earlier can do Win32s
+msgid ""
+"\n"
+"MS-Windows 16/32-bit GUI version"
+msgstr ""
+"\n"
+"MS-Windows 16/32-bit GUI-versie"
+
+msgid ""
+"\n"
+"MS-Windows 64-bit GUI version"
+msgstr ""
+"\n"
+"MS-Windows 64-bit GUI-versie"
+
+msgid ""
+"\n"
+"MS-Windows 32-bit GUI version"
+msgstr ""
+"\n"
+"MS-Windows 32-bit GUIversie"
+
+msgid " in Win32s mode"
+msgstr " in Win32s-modus"
+
+msgid " with OLE support"
+msgstr "met OLE-ondersteuning"
+
+msgid ""
+"\n"
+"MS-Windows 64-bit console version"
+msgstr ""
+"\n"
+"MS-Windows 64-bit console-versie"
+
+msgid ""
+"\n"
+"MS-Windows 32-bit console version"
+msgstr ""
+"\n"
+"MS-Windows 32-bit console-versie"
+
+msgid ""
+"\n"
+"MS-Windows 16-bit version"
+msgstr ""
+"\n"
+"MS-Windows 16-bit-versie"
+
+msgid ""
+"\n"
+"32-bit MS-DOS version"
+msgstr ""
+"\n"
+"32-bit MS-DOS-versie"
+
+msgid ""
+"\n"
+"16-bit MS-DOS version"
+msgstr ""
+"\n"
+"16-bit MS-DOS-versie"
+
+msgid ""
+"\n"
+"MacOS X (unix) version"
+msgstr ""
+"\n"
+"MacOS X (unix)-versie"
+
+msgid ""
+"\n"
+"MacOS X-versie"
+msgstr ""
+"\n"
+"MacOS X version"
+
+msgid ""
+"\n"
+"MacOS version"
+msgstr ""
+"\n"
+"MacOS-versie"
+
+msgid ""
+"\n"
+"RISC OS version"
+msgstr ""
+"\n"
+"RISC OS-versie"
+
+msgid ""
+"\n"
+"OpenVMS version"
+msgstr ""
+"\n"
+"OpenVMS-versie"
+
+msgid ""
+"\n"
+"Included patches: "
+msgstr ""
+"\n"
+"Inclusief 'patches': "
+
+msgid ""
+"\n"
+"Extra patches: "
+msgstr ""
+"\n"
+"Extra 'patches': "
+
+msgid "Modified by "
+msgstr "Aangepast door "
+
+msgid ""
+"\n"
+"Compiled "
+msgstr ""
+"\n"
+"Gecompileerd "
+
+msgid "by "
+msgstr "door "
+
+msgid ""
+"\n"
+"Huge version "
+msgstr ""
+"\n"
+"Enorme versie "
+
+msgid ""
+"\n"
+"Big version "
+msgstr ""
+"\n"
+"Grote versie "
+
+msgid ""
+"\n"
+"Normal version "
+msgstr ""
+"\n"
+"Normale versie "
+
+msgid ""
+"\n"
+"Small version "
+msgstr ""
+"\n"
+"Kleine versie "
+
+msgid ""
+"\n"
+"Tiny version "
+msgstr ""
+"\n"
+"Mini versie "
+
+#~ msgid "without GUI."
+#~ msgstr ""
+
+#~ msgid "with GTK2-GNOME GUI."
+#~ msgstr ""
+
+#~ msgid "with GTK-GNOME GUI."
+#~ msgstr ""
+
+#~ msgid "with GTK2 GUI."
+#~ msgstr ""
+
+#~ msgid "with GTK GUI."
+#~ msgstr ""
+
+#~ msgid "with X11-Motif GUI."
+#~ msgstr ""
+
+#~ msgid "with X11-neXtaw GUI."
+#~ msgstr ""
+
+#~ msgid "with X11-Athena GUI."
+#~ msgstr ""
+
+#~ msgid "with Photon GUI."
+#~ msgstr ""
+
+#~ msgid "with GUI."
+#~ msgstr ""
+
+#~ msgid "with Carbon GUI."
+#~ msgstr ""
+
+#~ msgid "with Cocoa GUI."
+#~ msgstr ""
+
+#~ msgid "with (classic) GUI."
+#~ msgstr ""
+
+#~ msgid " Features included (+) or not (-):\n"
+#~ msgstr ""
+
+#~ msgid " system vimrc file: \""
+#~ msgstr ""
+
+#~ msgid " user vimrc file: \""
+#~ msgstr ""
+
+#~ msgid " 2nd user vimrc file: \""
+#~ msgstr ""
+
+#~ msgid " 3rd user vimrc file: \""
+#~ msgstr ""
+
+#~ msgid " user exrc file: \""
+#~ msgstr ""
+
+#~ msgid " 2nd user exrc file: \""
+#~ msgstr ""
+
+#~ msgid " system gvimrc file: \""
+#~ msgstr ""
+
+#~ msgid " user gvimrc file: \""
+#~ msgstr ""
+
+#~ msgid "2nd user gvimrc file: \""
+#~ msgstr ""
+
+#~ msgid "3rd user gvimrc file: \""
+#~ msgstr ""
+
+#~ msgid " system menu file: \""
+#~ msgstr ""
+
+#~ msgid " fall-back for $VIM: \""
+#~ msgstr ""
+
+#~ msgid " f-b for $VIMRUNTIME: \""
+#~ msgstr ""
+
+msgid "Compilation: "
+msgstr "Compilatie: "
+
+msgid "Compiler: "
+msgstr "Compiler: "
+
+msgid "Linking: "
+msgstr "Linking: "
+
+msgid " DEBUG BUILD"
+msgstr " DEBUG BUILD"
+
+msgid "VIM - Vi IMproved"
+msgstr "VIM - Vi IMproved"
+
+msgid "version "
+msgstr "versie "
+
+msgid "by Bram Moolenaar et al."
+msgstr "door Bram Moolenaar en anderen"
+
+msgid "Vim is open source and freely distributable"
+msgstr "Vim is open-source en vrij verspreidbaar"
+
+msgid "Help poor children in Uganda!"
+msgstr "Help arme kinderen in Uganda!"
+
+msgid "type :help iccf<Enter> for information "
+msgstr "typ :help iccf<Enter> voor informatie"
+
+msgid "type :q<Enter> to exit"
+msgstr "typ :q<Enter> om te stoppen"
+
+msgid "type :help<Enter> or <F1> for on-line help"
+msgstr "typ :help<Enter> of <F1> voor on-line hulp"
+
+msgid "type :help version7<Enter> for version info"
+msgstr "typ :help version7<Enter> voor versieinformatie"
+
+msgid "Running in Vi compatible mode"
+msgstr "wordt uitgevoerd in Vi compatible-modus"
+
+msgid "type :set nocp<Enter> for Vim defaults"
+msgstr "typ :set nocp<Enter> voor standaardinstellingen van Vim"
+
+msgid "type :help cp-default<Enter> for info on this"
+msgstr "typ :help cp-default<Enter> voor informatie hierover"
+
+msgid "menu Help->Orphans for information "
+msgstr "menu Help->Orphans voor informatie"
+
+#~ 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 ""
+
+#~ msgid " for Vim defaults "
+#~ msgstr ""
+
+msgid "Sponsor Vim development!"
+msgstr "Ondersteun de ontwikkeling van Vim!"
+
+msgid "Become a registered Vim user!"
+msgstr "Word een geregistreerde Vim-gebruiker!"
+
+msgid "type :help sponsor<Enter> for information "
+msgstr "typ :help sponsor<Enter> voor informatie "
+
+msgid "type :help register<Enter> for information "
+msgstr "typ :help register<Enter> voor informatie "
+
+msgid "menu Help->Sponsor/Register for information "
+msgstr "menu Help->Sponsor/Register voor informatie "
+
+msgid "WARNING: Windows 95/98/ME detected"
+msgstr "Waarschuwing: Windows 95/98/ME gedetecteerd"
+
+msgid "type :help windows95<Enter> for info on this"
+msgstr "typ :help windows95<Enter> voor informatie hierover"
+
+msgid "Already only one window"
+msgstr "Reeds beperkt tot een venster"
+
+msgid "E441: There is no preview window"
+msgstr "E441: er is geen voorvertoningsvenster"
+
+msgid "E442: Can't split topleft and botright at the same time"
+msgstr "E442: kan linkerbovenzijde en rechteronderzijde niet gelijktijdig splitsen"
+
+#~ msgid "E443: Cannot rotate when another window is split"
+#~ msgstr ""
+
+msgid "E444: Cannot close last window"
+msgstr "E444: sluiten laatste venster is mislukt"
+
+msgid "E813: Cannot close autocmd window"
+msgstr "E813: sluiten autocmd-venster is mislukt"
+
+msgid "E814: Cannot close window, only autocmd window would remain"
+msgstr "E814: venster kan niet sluiten want autocmd-venster blijft als enige achter"
+
+msgid "E445: Other window contains changes"
+msgstr "E445: ander venster blijft achter"
+
+msgid "E446: No file name under cursor"
+msgstr "E446: cursor staat niet op een bestandsnaam"
+
+#, c-format
+msgid "E447: Can't find file \"%s\" in path"
+msgstr "E447: bestand \"%s\" niet in pad gevonden"
+
+#, c-format
+msgid "E370: Could not load library %s"
+msgstr "E370: laden van bibliotheek %s is mislukt"
+
+#~ msgid "Sorry, this command is disabled: the Perl library could not be loaded."
+#~ msgstr ""
+
+#~ msgid "E299: Perl evaluation forbidden in sandbox without the Safe module"
+#~ msgstr ""
+
+#~ msgid "Edit with &multiple Vims"
+#~ msgstr ""
+
+#~ msgid "Edit with single &Vim"
+#~ msgstr ""
+
+#~ msgid "Diff with Vim"
+#~ msgstr ""
+
+#~ msgid "Edit with &Vim"
+#~ msgstr ""
+
+#. Now concatenate
+#~ 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 ""
+
+#~ msgid "gvimext.dll error"
+#~ msgstr ""
+
+#~ msgid "Path length too long!"
+#~ msgstr ""
+
+msgid "--No lines in buffer--"
+msgstr "-- geen regels in buffer --"
+
+#.
+#. * 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: opdracht afgebroken"
+
+msgid "E471: Argument required"
+msgstr "E471: Argument vereist"
+
+msgid "E10: \\ should be followed by /, ? or &"
+msgstr "E10: \\ moet worden gevolgd door /, ? of &"
+
+msgid "E11: Invalid in command-line window; <CR> executes, CTRL-C quits"
+msgstr "E11: ongeldig in opdrachtregelvenster; <CR> voert uit, CTRL-C stopt"
+
+#~ msgid "E12: Command not allowed from exrc/vimrc in current dir or tag search"
+#~ msgstr ""
+
+#~ msgid "E171: Missing :endif"
+#~ msgstr ""
+
+#~ msgid "E600: Missing :endtry"
+#~ msgstr ""
+
+#~ msgid "E170: Missing :endwhile"
+#~ msgstr ""
+
+#~ msgid "E170: Missing :endfor"
+#~ msgstr ""
+
+#~ msgid "E588: :endwhile without :while"
+#~ msgstr ""
+
+#~ msgid "E588: :endfor without :for"
+#~ msgstr ""
+
+#~ msgid "E13: File exists (add ! to override)"
+#~ msgstr ""
+
+#~ msgid "E472: Command failed"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E234: Unknown fontset: %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E235: Unknown font: %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E236: Font \"%s\" is not fixed-width"
+#~ msgstr ""
+
+msgid "E473: Internal error"
+msgstr "E473: interne fout"
+
+msgid "Interrupted"
+msgstr "onderbroken"
+
+msgid "E14: Invalid address"
+msgstr "E14: ongeldig adres"
+
+msgid "E474: Invalid argument"
+msgstr "E474: ongeldig argument"
+
+#, c-format
+msgid "E475: Invalid argument: %s"
+msgstr "E475: ongeldig argument: %s"
+
+#, c-format
+msgid "E15: Invalid expression: %s"
+msgstr "E15: ongeldige expressie: %s"
+
+msgid "E16: Invalid range"
+msgstr "E16: ongeldig bereik"
+
+msgid "E476: Invalid command"
+msgstr "E476: ongeldige opdracht"
+
+#, c-format
+#~ msgid "E17: \"%s\" is a directory"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E364: Library call failed for \"%s()\""
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E448: Could not load library function %s"
+#~ msgstr ""
+
+msgid "E19: Mark has invalid line number"
+msgstr "E19: markering heeft een ongeldig regelnummer"
+
+msgid "E20: Mark not set"
+msgstr "E20: Markering is niet ingesteld"
+
+msgid "E21: Cannot make changes, 'modifiable' is off"
+msgstr "E21: kan geen veranderingen maken, 'modifiable' is uitgeschakeld"
+
+msgid "E22: Scripts nested too deep"
+msgstr "E22: scripts "
+
+#~ msgid "E23: No alternate file"
+#~ msgstr ""
+
+#~ msgid "E24: No such abbreviation"
+#~ msgstr ""
+
+#~ msgid "E477: No ! allowed"
+#~ msgstr ""
+
+#~ msgid "E25: GUI cannot be used: Not enabled at compile time"
+#~ msgstr ""
+
+#~ msgid "E26: Hebrew cannot be used: Not enabled at compile time\n"
+#~ msgstr ""
+
+#~ msgid "E27: Farsi cannot be used: Not enabled at compile time\n"
+#~ msgstr ""
+
+#~ msgid "E800: Arabic cannot be used: Not enabled at compile time\n"
+#~ msgstr ""
+
+#, c-format
+msgid "E28: No such highlight group name: %s"
+msgstr "E28: naam van deze oplichtgroep is onbekend: %s"
+
+#~ msgid "E29: No inserted text yet"
+#~ msgstr ""
+
+#~ msgid "E30: No previous command line"
+#~ msgstr ""
+
+#~ msgid "E31: No such mapping"
+#~ msgstr ""
+
+msgid "E479: No match"
+msgstr "E479: geen overeenkomst"
+
+#, c-format
+msgid "E480: No match: %s"
+msgstr "E480: geen overeenkomst: %s"
+
+msgid "E32: No file name"
+msgstr "E32: geen bestandsnaam"
+
+msgid "E33: No previous substitute regular expression"
+msgstr "E33: geen eerdere reguliere expressie substitutie"
+
+msgid "E34: No previous command"
+msgstr "E34: geen eerdere opdracht"
+
+msgid "E35: No previous regular expression"
+msgstr "E35: geen eerdere reguliere expressie"
+
+msgid "E481: No range allowed"
+msgstr "E481: een bereik is niet toegestaan"
+
+msgid "E36: Not enough room"
+msgstr "E36: onvoldoende ruimte"
+
+#, c-format
+msgid "E247: no registered server named \"%s\""
+msgstr "E247: \"%s\" niet gevonden als geregistreerde server"
+
+#, c-format
+msgid "E482: Can't create file %s"
+msgstr "E482: aanmaken bestand %s is mislukt"
+
+msgid "E483: Can't get temp file name"
+msgstr "E483: bepalen naam tijdelijk bestand is mislukt"
+
+#, c-format
+msgid "E484: Can't open file %s"
+msgstr "E484: openen bestand %s is mislukt"
+
+#, c-format
+msgid "E485: Can't read file %s"
+msgstr "E485: lezen bestand %s is mislukt"
+
+msgid "E37: No write since last change (add ! to override)"
+msgstr "E37: niets opgeslagen sinds laatste wijziging (voeg ! toe om te forceren)"
+
+msgid "E38: Null argument"
+msgstr "E38: leeg argument (null)"
+
+msgid "E39: Number expected"
+msgstr "E39: getal verwacht"
+
+#, c-format
+msgid "E40: Can't open errorfile %s"
+msgstr "E40: openen foutenbestand %s is mislukt"
+
+msgid "E233: cannot open display"
+msgstr "E233: openen scherm is mislukt"
+
+msgid "E41: Out of memory!"
+msgstr "E41: te weinig geheugen!"
+
+msgid "Pattern not found"
+msgstr "patroon niet gevonden"
+
+#, c-format
+msgid "E486: Pattern not found: %s"
+msgstr "E486: patroon niet gevonden: %s"
+
+msgid "E487: Argument must be positive"
+msgstr "E487: argument moet positief zijn"
+
+msgid "E459: Cannot go back to previous directory"
+msgstr "E459: kan niet terug naar vorig Dictionary"
+
+msgid "E42: No Errors"
+msgstr "E42: geen fouten"
+
+#~ msgid "E776: No location list"
+#~ msgstr ""
+
+msgid "E43: Damaged match string"
+msgstr "E43: beschadigde zoekstring"
+
+msgid "E44: Corrupted regexp program"
+msgstr "E44: regexp-programma is misvormd"
+
+msgid "E45: 'readonly' option is set (add ! to override)"
+msgstr "E45: 'alleen-lezen'-optie is ingeschakeld (voeg ! toe om te overschrijven)"
+
+#, c-format
+msgid "E46: Cannot change read-only variable \"%s\""
+msgstr "E46: kan alleen-lezenvariabele \"%s\" niet veranderen"
+
+#, c-format
+msgid "E794: Cannot set variable in the sandbox: \"%s\""
+msgstr "E794: kan variabele niet instellen in de zandbak: \"%s\""
+
+msgid "E47: Error while reading errorfile"
+msgstr "E47: fout tijdens lezen foutenbestand"
+
+msgid "E48: Not allowed in sandbox"
+msgstr "E48: niet toegestaan in zandbak"
+
+msgid "E523: Not allowed here"
+msgstr "E523: hier niet toegestaan"
+
+msgid "E359: Screen mode setting not supported"
+msgstr "E359: instelling schermmodus niet ondersteund"
+
+msgid "E49: Invalid scroll size"
+msgstr "E49: ongeldige scroll-grootte"
+
+msgid "E91: 'shell' option is empty"
+msgstr "E91: 'shell'-optie is leeg"
+
+#~ msgid "E255: Couldn't read in sign data!"
+#~ msgstr ""
+
+#~ msgid "E72: Close error on swap file"
+#~ msgstr ""
+
+#~ msgid "E73: tag stack empty"
+#~ msgstr ""
+
+msgid "E74: Command too complex"
+msgstr "E74: opdracht te ingewikkeld"
+
+msgid "E75: Name too long"
+msgstr "E75: te lange naam"
+
+msgid "E76: Too many ["
+msgstr "E76: teveel ["
+
+msgid "E77: Too many file names"
+msgstr "E77: teveel bestandsnamen"
+
+msgid "E488: Trailing characters"
+msgstr "E488: nakomende tekens"
+
+msgid "E78: Unknown mark"
+msgstr "E78: onbekende markering"
+
+msgid "E79: Cannot expand wildcards"
+msgstr "E79: vervangen jokertekens is mislukt"
+
+msgid "E591: 'winheight' cannot be smaller than 'winminheight'"
+msgstr "E591: 'winheight' kan niet kleiner zijn dan 'winminheight'"
+
+msgid "E592: 'winwidth' cannot be smaller than 'winminwidth'"
+msgstr "E592: 'winwidth' kan niet kleiner zijn dan 'winminwidth'"
+
+msgid "E80: Error while writing"
+msgstr "E80: opslaan is mislukt"
+
+msgid "Zero count"
+msgstr "Aantal is nul"
+
+msgid "E81: Using <SID> not in a script context"
+msgstr "E81: <SID> wordt buiten de scriptcontext gebruikt"
+
+msgid "E449: Invalid expression received"
+msgstr "E449: ontvangen expressie is ongeldig"
+
+msgid "E463: Region is guarded, cannot modify"
+msgstr "E463: Regio is bescherm en kan niet worden veranderd"
+
+msgid "E744: NetBeans does not allow changes in read-only files"
+msgstr "E744: NetBeans staat geen veranderingen in alleen-lezenbestanden toe"
+
+#, c-format
+msgid "E685: Internal error: %s"
+msgstr "E685: interne fout: %s"
+
+msgid "E363: pattern uses more memory than 'maxmempattern'"
+msgstr "E363: patroon gebruikt meer geheugen dan 'maxmempattern'"
+
+msgid "E749: empty buffer"
+msgstr "E749: leeg buffer"
+
+msgid "E682: Invalid search pattern or delimiter"
+msgstr "E682: zoekpatroon of scheidingsteken is ongeldig"
+
+msgid "E139: File is loaded in another buffer"
+msgstr "E139: bestand is in een ander buffer geladen"
+
+#, c-format
+msgid "E764: Option '%s' is not set"
+msgstr "E764: Optie '%s' is niet ingesteld"
+
+msgid "search hit TOP, continuing at BOTTOM"
+msgstr "zoeken bereikte TOP, verder vanaf BODEM"
+
+msgid "search hit BOTTOM, continuing at TOP"
+msgstr "zoeken bereikte BODEM, verder vanaf TOP"
+
diff --git a/src/po/no.po b/src/po/no.po
new file mode 100644
index 0000000000..f6d4761cb5
--- /dev/null
+++ b/src/po/no.po
@@ -0,0 +1,6166 @@
+# Norwegian (Bokmål) translation of Vim.
+# Copyright (C) 2003-2007 Free Software Foundation, Inc.
+# FIRST AUTHOR Øyvind A. Holm <sunny@sunbase.org>, 2003-2007.
+# Id: no.po 435 2007-03-21 10:52:22Z sunny256
+#
+# Comments and error reports appreciated.
+#
+# Information about the "Vim in Norwegian" project:
+#
+# http://www.sunbase.org/src/vim/norwegian/
+#
+# New versions of the translation files can be downloaded in .tar.gz
+# format from
+#
+# http://svn.sunbase.org/repos/norwegian_vim/download/
+#
+# The files are stored in the Subversion version control system and
+# users of this software can check out the latest version with
+#
+# svn checkout http://svn.sunbase.org/repos/norwegian_vim/trunk/msgs norwegian_vim-msgs
+#
+# This will place the message files into the "norwegian_vim-msgs"
+# directory.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Vim 6.x\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2007-03-19 02:09+0100\n"
+"PO-Revision-Date: 2007-03-21 11:51+0100\n"
+"Last-Translator: Øyvind A. Holm <sunny@sunbase.org>\n"
+"Language-Team: Norwegian <vim.in.norwegian@sunbase.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=ISO-8859-1\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+msgid "E82: Cannot allocate any buffer, exiting..."
+msgstr "E82: Kan ikke reservere plass til noen buffere, avslutter ..."
+
+msgid "E83: Cannot allocate buffer, using other one..."
+msgstr "E83: Kan ikke reservere plass til buffer, bruker en annen ..."
+
+msgid "E515: No buffers were unloaded"
+msgstr "E515: Ingen buffere ble lastet ut"
+
+msgid "E516: No buffers were deleted"
+msgstr "E516: Ingen buffere ble slettet"
+
+msgid "E517: No buffers were wiped out"
+msgstr "E517: Ingen buffere ble visket ut"
+
+msgid "1 buffer unloaded"
+msgstr "1 buffer ble lastet ut"
+
+#, c-format
+msgid "%d buffers unloaded"
+msgstr "%d buffere ble lastet ut"
+
+msgid "1 buffer deleted"
+msgstr "1 buffer ble slettet"
+
+#, c-format
+msgid "%d buffers deleted"
+msgstr "%d buffere ble slettet"
+
+msgid "1 buffer wiped out"
+msgstr "1 buffer ble visket ut"
+
+#, c-format
+msgid "%d buffers wiped out"
+msgstr "%d buffere ble visket ut"
+
+msgid "E84: No modified buffer found"
+msgstr "E84: Fant ingen modifisert buffer"
+
+#. back where we started, didn't find anything.
+msgid "E85: There is no listed buffer"
+msgstr "E85: Det finnes ingen listede buffere"
+
+#, c-format
+msgid "E86: Buffer %ld does not exist"
+msgstr "E86: Bufferen %ld finnes ikke"
+
+msgid "E87: Cannot go beyond last buffer"
+msgstr "E87: Kan ikke gå forbi siste buffer"
+
+msgid "E88: Cannot go before first buffer"
+msgstr "E88: Kan ikke gå forbi første buffer"
+
+#, c-format
+msgid "E89: No write since last change for buffer %ld (add ! to override)"
+msgstr ""
+"E89: Ikke lagret siden forrige forandring av bufferen %ld (legg til ! for å "
+"overstyre)"
+
+msgid "E90: Cannot unload last buffer"
+msgstr "E90: Kan ikke laste ut siste buffer"
+
+msgid "W14: Warning: List of file names overflow"
+msgstr "W14: Advarsel: Listen med filnavn er overfylt"
+
+#, c-format
+msgid "E92: Buffer %ld not found"
+msgstr "E92: Fant ikke bufferen %ld"
+
+#, c-format
+msgid "E93: More than one match for %s"
+msgstr "E93: Mer enn ett treff for %s"
+
+#, c-format
+msgid "E94: No matching buffer for %s"
+msgstr "E94: Ingen samsvarende buffer for %s"
+
+#, c-format
+msgid "line %ld"
+msgstr "linje %ld"
+
+msgid "E95: Buffer with this name already exists"
+msgstr "E95: En buffer med dette navnet finnes allerede"
+
+msgid " [Modified]"
+msgstr " [Modifisert]"
+
+msgid "[Not edited]"
+msgstr "[Uredigert]"
+
+msgid "[New file]"
+msgstr "[Ny fil]"
+
+msgid "[Read errors]"
+msgstr "[Lesefeil]"
+
+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 av %ld --%d%%-- kol "
+
+msgid "[No Name]"
+msgstr "[Uten navn]"
+
+#. must be a help buffer
+msgid "help"
+msgstr "hjelp"
+
+msgid "[Help]"
+msgstr "[Hjelp]"
+
+msgid "[Preview]"
+msgstr "[Forhåndsvisning]"
+
+msgid "All"
+msgstr "Alt"
+
+msgid "Bot"
+msgstr "Bunn"
+
+msgid "Top"
+msgstr "Topp"
+
+#, c-format
+msgid ""
+"\n"
+"# Buffer list:\n"
+msgstr ""
+"\n"
+"# Bufferliste:\n"
+
+msgid "[Location List]"
+msgstr "[Plassliste]"
+
+#~ msgid "[Quickfix List]"
+#~ msgstr ""
+
+msgid ""
+"\n"
+"--- Signs ---"
+msgstr ""
+"\n"
+"--- Skilt ---"
+
+#, c-format
+msgid "Signs for %s:"
+msgstr "Skilt for %s:"
+
+#, c-format
+msgid " line=%ld id=%d name=%s"
+msgstr " linje=%ld id=%d navn=%s"
+
+#, c-format
+msgid "E96: Can not diff more than %ld buffers"
+msgstr "E96: Kan ikke sammenligne flere enn %ld buffere"
+
+msgid "E97: Cannot create diffs"
+msgstr "E97: Kan ikke lage differansefiler"
+
+msgid "Patch file"
+msgstr "Patch fil"
+
+msgid "E98: Cannot read diff output"
+msgstr "E98: Kan ikke lese differanse-utdata"
+
+msgid "E99: Current buffer is not in diff mode"
+msgstr "E99: Nåværende buffer er ikke i differansemodus"
+
+msgid "E793: No other buffer in diff mode is modifiable"
+msgstr "E793: Ingen annen buffer i differansemodus er redigerbar"
+
+msgid "E100: No other buffer in diff mode"
+msgstr "E100: Ingen annen buffer i differansemodus"
+
+msgid "E101: More than two buffers in diff mode, don't know which one to use"
+msgstr ""
+"E101: Mer enn to buffere i differansemodus, vet ikke hvilken som skal brukes"
+
+#, c-format
+msgid "E102: Can't find buffer \"%s\""
+msgstr "E102: Kan ikke finne buffer \"%s\""
+
+#, c-format
+msgid "E103: Buffer \"%s\" is not in diff mode"
+msgstr "E103: Bufferen \"%s\" er ikke i differansemodus"
+
+msgid "E787: Buffer changed unexpectedly"
+msgstr "E787: Uventet forandring i buffer"
+
+msgid "E104: Escape not allowed in digraph"
+msgstr "E104: Escape er ikke lovlig i spesialtegn"
+
+msgid "E544: Keymap file not found"
+msgstr "E544: Fant ikke keymap-fil"
+
+msgid "E105: Using :loadkeymap not in a sourced file"
+msgstr "E105: Bruk av :loadkeymap utenfor en kjørt fil"
+
+msgid "E791: Empty keymap entry"
+msgstr "E791: Tom tastaturoppsett-oppføring"
+
+msgid " Keyword completion (^N^P)"
+msgstr " Nøkkelordfullføring (^N^P)"
+
+#. ctrl_x_mode == 0, ^P/^N compl.
+#, fuzzy
+#~ msgid " ^X mode (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)"
+#~ msgstr " ^X-modus (^]^D^E^F^I^K^L^N^O^P^S^U^V^Y)"
+
+msgid " Whole line completion (^L^N^P)"
+msgstr " Fullføring av hel linje (^L^N^P)"
+
+msgid " File name completion (^F^N^P)"
+msgstr " Fullføring av filnavn (^F^N^P)"
+
+msgid " Tag completion (^]^N^P)"
+msgstr " Fullføring av tag (^]^N^P)"
+
+msgid " Path pattern completion (^N^P)"
+msgstr " Stimønster-fullføring (^N^P)"
+
+msgid " Definition completion (^D^N^P)"
+msgstr " Fullføring av defineringer (^D^N^P)"
+
+msgid " Dictionary completion (^K^N^P)"
+msgstr " Fullføring fra ordliste (^K^N^P)"
+
+msgid " Thesaurus completion (^T^N^P)"
+msgstr " Thesaurus-fullføring (^T^N^P)"
+
+msgid " Command-line completion (^V^N^P)"
+msgstr " Kommandolinje-fullføring (^V^N^P)"
+
+msgid " User defined completion (^U^N^P)"
+msgstr " Brukerdefinert fullføring (^U^N^P)"
+
+msgid " Omni completion (^O^N^P)"
+msgstr " Omni-fullføring (^O^N^P)"
+
+#, fuzzy
+#~ msgid " Spelling suggestion (s^N^P)"
+#~ msgstr " Staveforslag (^S^N^P)"
+
+msgid " Keyword Local completion (^N^P)"
+msgstr " Lokal nøkkelordfullføring (^N^P)"
+
+msgid "Hit end of paragraph"
+msgstr "Kom til slutten av avsnittet"
+
+msgid "'dictionary' option is empty"
+msgstr "'dictionary'-valget er tomt"
+
+msgid "'thesaurus' option is empty"
+msgstr "'thesaurus'-valget er tomt"
+
+#, c-format
+msgid "Scanning dictionary: %s"
+msgstr "Leter gjennom ordliste: %s"
+
+msgid " (insert) Scroll (^E/^Y)"
+msgstr " (sett inn) Rulling (^E/^Y)"
+
+msgid " (replace) Scroll (^E/^Y)"
+msgstr " (erstatt) Rulling (^E/^Y)"
+
+#, c-format
+msgid "Scanning: %s"
+msgstr "Leter: %s"
+
+#, c-format
+msgid "Scanning tags."
+msgstr "Leter gjennom tagger."
+
+msgid " Adding"
+msgstr " Legger til"
+
+#. 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.
+#.
+msgid "-- Searching..."
+msgstr "-- Søker ..."
+
+msgid "Back at original"
+msgstr "Tilbake i originalen"
+
+msgid "Word from other line"
+msgstr "Ord fra annen linje"
+
+msgid "The only match"
+msgstr "Det eneste treffet"
+
+#, c-format
+msgid "match %d of %d"
+msgstr "treff %d av %d"
+
+#, c-format
+msgid "match %d"
+msgstr "treff %d"
+
+msgid "E18: Unexpected characters in :let"
+msgstr "E18: Uventede tegn i :let"
+
+#, c-format
+msgid "E684: list index out of range: %ld"
+msgstr "E684: Listeindeks utenfor område: %ld"
+
+#, c-format
+msgid "E121: Undefined variable: %s"
+msgstr "E121: Udefinert variabel: %s"
+
+msgid "E111: Missing ']'"
+msgstr "E111: Mangler ']'"
+
+#, c-format
+msgid "E686: Argument of %s must be a List"
+msgstr "E686: Parameter til %s må være en liste"
+
+#, c-format
+msgid "E712: Argument of %s must be a List or Dictionary"
+msgstr "E712: Parameter til %s må være en liste eller ordliste"
+
+msgid "E713: Cannot use empty key for Dictionary"
+msgstr "E713: Kan ikke bruke tom nøkkel med ordliste"
+
+msgid "E714: List required"
+msgstr "E714: Liste påkrevet"
+
+msgid "E715: Dictionary required"
+msgstr "E715: Ordliste påkrevet"
+
+#, c-format
+msgid "E118: Too many arguments for function: %s"
+msgstr "E118: For mange parametere til funksjonen: %s"
+
+#, c-format
+msgid "E716: Key not present in Dictionary: %s"
+msgstr "E716: Nøkkelen finnes ikke i ordliste: %s"
+
+#, c-format
+msgid "E122: Function %s already exists, add ! to replace it"
+msgstr "E122: Funksjonen %s eksisterer allerede, legg til ! for å erstatte den"
+
+msgid "E717: Dictionary entry already exists"
+msgstr "E717: Ordlisteoppføring finnes allerede"
+
+msgid "E718: Funcref required"
+msgstr "E718: Funksjonsreferanse nødvendig"
+
+msgid "E719: Cannot use [:] with a Dictionary"
+msgstr "E719: Kan ikke bruke [:] sammen med en ordliste"
+
+#, c-format
+msgid "E734: Wrong variable type for %s="
+msgstr "E734: Feil variabeltype for %s="
+
+#, c-format
+msgid "E130: Unknown function: %s"
+msgstr "E130: Ukjent funksjon: %s"
+
+#, c-format
+msgid "E461: Illegal variable name: %s"
+msgstr "E461: Ugyldig variabelnavn: %s"
+
+msgid "E687: Less targets than List items"
+msgstr "E687: Færre mål enn listeelementer"
+
+msgid "E688: More targets than List items"
+msgstr "E688: Flere mål enn listeelementer"
+
+msgid "Double ; in list of variables"
+msgstr "Dobbel ; i variabelliste"
+
+#, c-format
+msgid "E738: Can't list variables for %s"
+msgstr "E738: Kan ikke liste variabler for %s"
+
+msgid "E689: Can only index a List or Dictionary"
+msgstr "E689: Kan bare indeksere en liste eller ordliste"
+
+msgid "E708: [:] must come last"
+msgstr "E708: [:] må komme sist"
+
+msgid "E709: [:] requires a List value"
+msgstr "E709: [:] krever en listeverdi"
+
+msgid "E710: List value has more items than target"
+msgstr "E710: Listeverdien har flere elementer enn mål"
+
+msgid "E711: List value has not enough items"
+msgstr "E711: Listeverdien har ikke nok elementer"
+
+msgid "E690: Missing \"in\" after :for"
+msgstr "E690: Mangler \"in\" etter :for"
+
+#, c-format
+msgid "E107: Missing parentheses: %s"
+msgstr "E107: Mangler parenteser: %s"
+
+#, c-format
+msgid "E108: No such variable: \"%s\""
+msgstr "E108: Variabelen finnes ikke: \"%s\""
+
+msgid "E743: variable nested too deep for (un)lock"
+msgstr "E743: Variabel nøstet for dypt for (un)lock"
+
+msgid "E109: Missing ':' after '?'"
+msgstr "E109: Mangler ':' etter '?'"
+
+msgid "E691: Can only compare List with List"
+msgstr "E691: Kan bare sammenligne liste med liste"
+
+msgid "E692: Invalid operation for Lists"
+msgstr "E692: Ugyldig operasjon for lister"
+
+msgid "E735: Can only compare Dictionary with Dictionary"
+msgstr "E735: Kan bare sammenligne ordliste med ordliste"
+
+msgid "E736: Invalid operation for Dictionary"
+msgstr "E736: Ugyldig operasjon for ordliste"
+
+msgid "E693: Can only compare Funcref with Funcref"
+msgstr "E693: Kan bare sammenligne funksjonsreferanse med funksjonsreferanse"
+
+msgid "E694: Invalid operation for Funcrefs"
+msgstr "E694: Ugyldig operasjon for funksjonsreferanser"
+
+msgid "E110: Missing ')'"
+msgstr "E110: Mangler ')'"
+
+msgid "E695: Cannot index a Funcref"
+msgstr "E695: Kan ikke indeksere en funksjonsreferanse"
+
+#, c-format
+msgid "E112: Option name missing: %s"
+msgstr "E112: Navn på valg mangler: %s"
+
+#, c-format
+msgid "E113: Unknown option: %s"
+msgstr "E113: Ukjent valg: %s"
+
+#, c-format
+msgid "E114: Missing quote: %s"
+msgstr "E114: Mangler anførselstegn (\"): %s"
+
+#, c-format
+msgid "E115: Missing quote: %s"
+msgstr "E115: Mangler apostrof ('): %s"
+
+#, c-format
+msgid "E696: Missing comma in List: %s"
+msgstr "E696: Mangler komma i liste: %s"
+
+#, c-format
+msgid "E697: Missing end of List ']': %s"
+msgstr "E697: Mangler slutt på liste ']': %s"
+
+#, c-format
+msgid "E720: Missing colon in Dictionary: %s"
+msgstr "E720: Mangler kolon i ordliste: %s"
+
+#, c-format
+msgid "E721: Duplicate key in Dictionary: \"%s\""
+msgstr "E721: Duplisert nøkkel i ordliste: \"%s\""
+
+#, c-format
+msgid "E722: Missing comma in Dictionary: %s"
+msgstr "E722: Mangler komma i ordliste: %s"
+
+#, c-format
+msgid "E723: Missing end of Dictionary '}': %s"
+msgstr "E723: Mangler slutt på ordliste '}': %s"
+
+msgid "E724: variable nested too deep for displaying"
+msgstr "E724: Variabel nøstet for dypt for visning"
+
+#, c-format
+msgid "E117: Unknown function: %s"
+msgstr "E117: Ukjent funksjon: %s"
+
+#, c-format
+msgid "E119: Not enough arguments for function: %s"
+msgstr "E119: Ikke nok parametere til funksjonen: %s"
+
+#, c-format
+msgid "E120: Using <SID> not in a script context: %s"
+msgstr "E120: Bruk av \"<SID>\" utenfor skript-sammenheng: %s"
+
+#, c-format
+msgid "E725: Calling dict function without Dictionary: %s"
+msgstr "E725: Kaller ordlistefunksjon uten ordliste: %s"
+
+msgid "E699: Too many arguments"
+msgstr "E699: For mange parametere"
+
+msgid "E785: complete() can only be used in Insert mode"
+msgstr "E785: complete() kan bare brukes i innsettingsmodus"
+
+#.
+#. * 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"
+
+#, c-format
+msgid "E737: Key already exists: %s"
+msgstr "E737: Nøkkelen finnes allerede: %s"
+
+#, c-format
+msgid "+-%s%3ld lines: "
+msgstr "+-%s%3ld linjer: "
+
+#, c-format
+msgid "E700: Unknown function: %s"
+msgstr "E700: Ukjent funksjon: %s"
+
+msgid ""
+"&OK\n"
+"&Cancel"
+msgstr ""
+"&OK\n"
+"&Avbryt"
+
+msgid "called inputrestore() more often than inputsave()"
+msgstr "kalte inputrestore() oftere enn inputsave()"
+
+msgid "E786: Range not allowed"
+msgstr "E786: Område ikke tillatt"
+
+msgid "E701: Invalid type for len()"
+msgstr "E701: Ugyldig type for len()"
+
+msgid "E726: Stride is zero"
+msgstr "E726: Økning er null"
+
+msgid "E727: Start past end"
+msgstr "E727: Starten er bak slutten"
+
+msgid "<empty>"
+msgstr "<tom>"
+
+msgid "E240: No connection to Vim server"
+msgstr "E240: Ingen forbindelse med Vim-tjeneren"
+
+#, c-format
+msgid "E241: Unable to send to %s"
+msgstr "E241: Klarer ikke sende til %s"
+
+msgid "E277: Unable to read a server reply"
+msgstr "E277: Klarer ikke lese svar fra tjeneren"
+
+msgid "E655: Too many symbolic links (cycle?)"
+msgstr "E655: For mange symbolske linker (runddans?)"
+
+msgid "E258: Unable to send to client"
+msgstr "E258: Klarer ikke sende til klienten"
+
+msgid "E702: Sort compare function failed"
+msgstr "E702: Funksjon for sorteringssammenligning feilet"
+
+msgid "(Invalid)"
+msgstr "(Ugyldig)"
+
+msgid "E677: Error writing temp file"
+msgstr "E677: Feil under skriving til midlertidig fil"
+
+msgid "E703: Using a Funcref as a Number"
+msgstr "E703: Bruker en funksjonsreferanse som et nummer"
+
+msgid "E745: Using a List as a Number"
+msgstr "E745: Bruker en liste som et nummer"
+
+msgid "E728: Using a Dictionary as a Number"
+msgstr "E728: Bruker en ordliste som et nummer"
+
+msgid "E729: using Funcref as a String"
+msgstr "E729: Bruker en funksjonsreferanse som en streng"
+
+msgid "E730: using List as a String"
+msgstr "E730: Bruker en liste som en streng"
+
+msgid "E731: using Dictionary as a String"
+msgstr "E731: Bruker en ordliste som en streng"
+
+#, c-format
+msgid "E704: Funcref variable name must start with a capital: %s"
+msgstr "E704: Variabelnavn for funksjonsreferanse må ha stor forbokstav: %s"
+
+#, c-format
+msgid "E705: Variable name conflicts with existing function: %s"
+msgstr "E705: Variabelnavn er i konflikt med en eksisterende funksjon: %s"
+
+#, c-format
+msgid "E706: Variable type mismatch for: %s"
+msgstr "E706: Variabeltype samsvarer ikke med: %s"
+
+#, c-format
+msgid "E795: Cannot delete variable %s"
+msgstr "E795: Kan ikke slette variabel %s"
+
+#, c-format
+msgid "E741: Value is locked: %s"
+msgstr "E741: Verdi er låst: %s"
+
+msgid "Unknown"
+msgstr "Ukjent"
+
+#, c-format
+msgid "E742: Cannot change value of %s"
+msgstr "E742: Kan ikke forandre verdi for %s"
+
+msgid "E698: variable nested too deep for making a copy"
+msgstr "E698: Variabel nøstet for dypt til å lage en kopi"
+
+#, c-format
+msgid "E124: Missing '(': %s"
+msgstr "E124: Mangler '(': %s"
+
+#, c-format
+msgid "E125: Illegal argument: %s"
+msgstr "E125: Ugyldig parameter: %s"
+
+msgid "E126: Missing :endfunction"
+msgstr "E126: Mangler :endfunction"
+
+#, c-format
+msgid "E746: Function name does not match script file name: %s"
+msgstr "E746: Funksjonsnavn samsvarer ikke med skriptfilnavn: %s"
+
+msgid "E129: Function name required"
+msgstr "E129: Funksjonsnavn nødvendig"
+
+#, c-format
+msgid "E128: Function name must start with a capital or contain a colon: %s"
+msgstr "E128: Funksjonsnavn må ha stor forbokstav eller inneholde et kolon: %s"
+
+#, c-format
+msgid "E131: Cannot delete function %s: It is in use"
+msgstr "E131: Kan ikke slette funksjonen %s: Den er i bruk"
+
+msgid "E132: Function call depth is higher than 'maxfuncdepth'"
+msgstr "E132: Funksjonskalldybden er større enn 'maxfuncdepth'"
+
+#, c-format
+msgid "calling %s"
+msgstr "kaller %s"
+
+#, c-format
+msgid "%s aborted"
+msgstr "%s avbrutt"
+
+#, c-format
+msgid "%s returning #%ld"
+msgstr "%s returnerer #%ld"
+
+#, c-format
+msgid "%s returning %s"
+msgstr "%s returnerer %s"
+
+#, c-format
+msgid "continuing in %s"
+msgstr "fortsetter i %s"
+
+msgid "E133: :return not inside a function"
+msgstr "E133: :return er ikke innenfor en funksjon"
+
+#, c-format
+msgid ""
+"\n"
+"# global variables:\n"
+msgstr ""
+"\n"
+"# globale variabler:\n"
+
+msgid ""
+"\n"
+"\tLast set from "
+msgstr ""
+"\n"
+"\tSist satt fra "
+
+#, c-format
+msgid "<%s>%s%s %d, Hex %02x, Octal %03o"
+msgstr "<%s>%s%s %d, Hex %02x, Oktal %03o"
+
+#, c-format
+msgid "> %d, Hex %04x, Octal %o"
+msgstr "> %d, Hex %04x, Oktal %o"
+
+#, c-format
+msgid "> %d, Hex %08x, Octal %o"
+msgstr "> %d, Hex %08x, Oktal %o"
+
+msgid "E134: Move lines into themselves"
+msgstr "E134: Flytting av linjer inn i seg 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 filtrert"
+
+msgid "E135: *Filter* Autocommands must not change current buffer"
+msgstr "E135: *Filter* Autokommandoer må ikke forandre nåværende buffer"
+
+msgid "[No write since last change]\n"
+msgstr "[Ikke lagret siden forrige forandring]\n"
+
+#, c-format
+msgid "%sviminfo: %s in line: "
+msgstr "%sviminfo: %s i linje: "
+
+msgid "E136: viminfo: Too many errors, skipping rest of file"
+msgstr "E136: viminfo: For mange feil, hopper over resten av filen"
+
+#, c-format
+msgid "Reading viminfo file \"%s\"%s%s%s"
+msgstr "Leser viminfo-fil \"%s\"%s%s%s"
+
+msgid " info"
+msgstr " info"
+
+msgid " marks"
+msgstr " merker"
+
+msgid " FAILED"
+msgstr " FEILET"
+
+#. avoid a wait_return for this message, it's annoying
+#, c-format
+msgid "E137: Viminfo file is not writable: %s"
+msgstr "E137: Viminfo-fil er ikke skrivbar: %s"
+
+#, c-format
+msgid "E138: Can't write viminfo file %s!"
+msgstr "E138: Kan ikke lagre viminfo-fil %s!"
+
+#, c-format
+msgid "Writing viminfo file \"%s\""
+msgstr "Lagrer viminfo-fil \"%s\""
+
+#. Write the info:
+#, c-format
+msgid "# This viminfo file was generated by Vim %s.\n"
+msgstr "# Denne viminfo-filen ble generert av Vim %s.\n"
+
+#, c-format
+msgid ""
+"# You may edit it if you're careful!\n"
+"\n"
+msgstr ""
+"# Du kan redigere den hvis du er forsiktig!\n"
+"\n"
+
+#, c-format
+msgid "# Value of 'encoding' when this file was written\n"
+msgstr "# Verdien av 'encoding' når denne filen ble skrevet\n"
+
+msgid "Illegal starting char"
+msgstr "Ulovlig starttegn"
+
+msgid "Save As"
+msgstr "Lagre som"
+
+msgid "Write partial file?"
+msgstr "Skrive delvis fil?"
+
+msgid "E140: Use ! to write partial buffer"
+msgstr "E140: Bruk ! for å skrive delvis buffer"
+
+#, c-format
+msgid "Overwrite existing file \"%s\"?"
+msgstr "Overskrive eksisterende fil \"%s\"?"
+
+#, c-format
+msgid "Swap file \"%s\" exists, overwrite anyway?"
+msgstr "Swapfilen \"%s\" finnes, overskriv likevel?"
+
+#, c-format
+msgid "E768: Swap file exists: %s (:silent! overrides)"
+msgstr "E768: Swapfilen finnes: %s (:silent! overstyrer)"
+
+#, c-format
+msgid "E141: No file name for buffer %ld"
+msgstr "E141: Mangler filnavn for buffer %ld"
+
+msgid "E142: File not written: Writing is disabled by 'write' option"
+msgstr "E142: Filen ble ikke lagret: Lagring er deaktivert med 'write'-valget"
+
+#, c-format
+msgid ""
+"'readonly' option is set for \"%s\".\n"
+"Do you wish to write anyway?"
+msgstr ""
+"'readonly'-valget er satt for \"%s\".\n"
+"Vil du lagre likevel?"
+
+msgid "Edit File"
+msgstr "Rediger fil"
+
+#, c-format
+msgid "E143: Autocommands unexpectedly deleted new buffer %s"
+msgstr "E143: Autokommandoer slettet uventet den nye bufferen %s"
+
+msgid "E144: non-numeric argument to :z"
+msgstr "E144: Ikke-numerisk parameter til :z"
+
+msgid "E145: Shell commands not allowed in rvim"
+msgstr "E145: Skallkommandoer er ikke tillatt i rvim"
+
+msgid "E146: Regular expressions can't be delimited by letters"
+msgstr "E146: Regulære uttrykk kan ikke bli adskilt av bokstaver"
+
+#, c-format
+msgid "replace with %s (y/n/a/q/l/^E/^Y)?"
+msgstr "Erstatt med %s (y/n/a/q/l/^E/^Y)?"
+
+msgid "(Interrupted) "
+msgstr "(Avbrutt) "
+
+msgid "1 match"
+msgstr "1 treff"
+
+msgid "1 substitution"
+msgstr "1 erstatning"
+
+#, c-format
+msgid "%ld matches"
+msgstr "%ld treff"
+
+#, c-format
+msgid "%ld substitutions"
+msgstr "%ld erstatninger"
+
+msgid " on 1 line"
+msgstr " i 1 linje"
+
+#, c-format
+msgid " on %ld lines"
+msgstr " i %ld linjer"
+
+msgid "E147: Cannot do :global recursive"
+msgstr "E147: Kan ikke gjøre :global rekursiv"
+
+msgid "E148: Regular expression missing from global"
+msgstr "E148: Regulært uttrykk mangler i global kommando"
+
+#, c-format
+msgid "Pattern found in every line: %s"
+msgstr "Søkestreng funnet i alle linjene: %s"
+
+#, c-format
+msgid ""
+"\n"
+"# Last Substitute String:\n"
+"$"
+msgstr ""
+"\n"
+"# Siste erstatningstekst:\n"
+"$"
+
+msgid "E478: Don't panic!"
+msgstr "E478: Ingen panikk!"
+
+#, c-format
+msgid "E661: Sorry, no '%s' help for %s"
+msgstr "E661: Dessverre ingen '%s' hjelp for %s"
+
+#, c-format
+msgid "E149: Sorry, no help for %s"
+msgstr "E149: Dessverre ingen hjelp for %s"
+
+#, c-format
+msgid "Sorry, help file \"%s\" not found"
+msgstr "Fant ikke hjelpefilen \"%s\""
+
+#, c-format
+msgid "E150: Not a directory: %s"
+msgstr "E150: Er ikke en katalog: %s"
+
+#, c-format
+msgid "E152: Cannot open %s for writing"
+msgstr "E152: Kan ikke åpne %s for skriving"
+
+#, c-format
+msgid "E153: Unable to open %s for reading"
+msgstr "E153: Kan ikke åpne %s for lesing"
+
+#, c-format
+msgid "E670: Mix of help file encodings within a language: %s"
+msgstr "E670: Tegnsettblanding i hjelpefilen innenfor samme språk: %s"
+
+#, c-format
+msgid "E154: Duplicate tag \"%s\" in file %s/%s"
+msgstr "E154: Duplikat-tag \"%s\" i filen %s/%s"
+
+#, c-format
+msgid "E160: Unknown sign command: %s"
+msgstr "E160: Ukjent skiltkommando: %s"
+
+msgid "E156: Missing sign name"
+msgstr "E156: Mangler skiltnavn"
+
+msgid "E612: Too many signs defined"
+msgstr "E612: For mange skilt definert"
+
+#, c-format
+msgid "E239: Invalid sign text: %s"
+msgstr "E239: Ugyldig skilttekst: %s"
+
+#, c-format
+msgid "E155: Unknown sign: %s"
+msgstr "E155: Ukjent skilt: %s"
+
+msgid "E159: Missing sign number"
+msgstr "E159: Mangler skiltnummer"
+
+#, c-format
+msgid "E158: Invalid buffer name: %s"
+msgstr "E158: Ugyldig buffernavn: %s"
+
+#, c-format
+msgid "E157: Invalid sign ID: %ld"
+msgstr "E157: Ulovlig skilt-ID: %ld"
+
+msgid " (NOT FOUND)"
+msgstr " (IKKE FUNNET)"
+
+msgid " (not supported)"
+msgstr " (ikke støttet)"
+
+msgid "[Deleted]"
+msgstr "[Slettet]"
+
+msgid "Entering Debug mode. Type \"cont\" to continue."
+msgstr "Går inn i debuggingsmodus. Skriv \"cont\" for å fortsette."
+
+#, c-format
+msgid "line %ld: %s"
+msgstr "linje %ld: %s"
+
+#, c-format
+msgid "cmd: %s"
+msgstr "kommando: %s"
+
+#, c-format
+msgid "Breakpoint in \"%s%s\" line %ld"
+msgstr "Stoppunkt i \"%s%s\" linje %ld"
+
+#, c-format
+msgid "E161: Breakpoint not found: %s"
+msgstr "E161: Fant ikke stoppunkt: %s"
+
+msgid "No breakpoints defined"
+msgstr "Ingen stoppunkt definert"
+
+#, c-format
+msgid "%3d %s %s line %ld"
+msgstr "%3d %s %s linje %ld"
+
+msgid "E750: First use :profile start <fname>"
+msgstr "E750: Bruk først :profile start <filnavn>"
+
+#, c-format
+msgid "Save changes to \"%s\"?"
+msgstr "Lagre forandringer til \"%s\"?"
+
+msgid "Untitled"
+msgstr "Uten navn"
+
+#, c-format
+msgid "E162: No write since last change for buffer \"%s\""
+msgstr "E162: Ikke lagret siden siste forandringer i bufferen \"%s\""
+
+msgid "Warning: Entered other buffer unexpectedly (check autocommands)"
+msgstr "Advarsel: Gikk uventet inn i en annen buffer (sjekk autokommandoer)"
+
+msgid "E163: There is only one file to edit"
+msgstr "E163: Det er bare en fil å redigere"
+
+msgid "E164: Cannot go before first file"
+msgstr "E164: Kan ikke gå forbi første fil"
+
+msgid "E165: Cannot go beyond last file"
+msgstr "E165: Kan ikke gå forbi siste fil"
+
+#, c-format
+msgid "E666: compiler not supported: %s"
+msgstr "E666: Kompilatoren er ikke støttet: %s"
+
+#, c-format
+msgid "Searching for \"%s\" in \"%s\""
+msgstr "Søker etter \"%s\" i \"%s\""
+
+#, c-format
+msgid "Searching for \"%s\""
+msgstr "Søker etter \"%s\""
+
+#, c-format
+msgid "not found in 'runtimepath': \"%s\""
+msgstr "ikke funnet i 'runtimepath': \"%s\""
+
+msgid "Source Vim script"
+msgstr "Kjør Vim-skript"
+
+#, c-format
+msgid "Cannot source a directory: \"%s\""
+msgstr "Kan ikke kjøre en katalog: \"%s\""
+
+#, c-format
+msgid "could not source \"%s\""
+msgstr "kunne ikke kjøre \"%s\""
+
+#, c-format
+msgid "line %ld: could not source \"%s\""
+msgstr "linje %ld: Kunne ikke kjøre \"%s\""
+
+#, c-format
+msgid "sourcing \"%s\""
+msgstr "kjører \"%s\""
+
+#, c-format
+msgid "line %ld: sourcing \"%s\""
+msgstr "linje %ld: kjører \"%s\""
+
+#, c-format
+msgid "finished sourcing %s"
+msgstr "ferdig med kjøring av %s"
+
+#, fuzzy
+#~ msgid "modeline"
+#~ msgstr "1 linje lagt til"
+
+#, fuzzy
+#~ msgid "--cmd argument"
+#~ msgstr " vim [parametere] "
+
+#, fuzzy
+#~ msgid "-c argument"
+#~ msgstr " vim [parametere] "
+
+msgid "environment variable"
+msgstr "miljøvariabel"
+
+msgid "error handler"
+msgstr "feilbehandler"
+
+msgid "W15: Warning: Wrong line separator, ^M may be missing"
+msgstr "W15: Advarsel: Feil linjeseparator, det er mulig ^M mangler"
+
+msgid "E167: :scriptencoding used outside of a sourced file"
+msgstr "E167: :scriptencoding brukt utenfor en kjørt fil"
+
+msgid "E168: :finish used outside of a sourced file"
+msgstr "E168: :finish brukt utenfor en kjørt fil"
+
+#, c-format
+msgid "Current %slanguage: \"%s\""
+msgstr "Nåværende %sspråk: \"%s\""
+
+#, c-format
+msgid "E197: Cannot set language to \"%s\""
+msgstr "E197: Kan ikke sette språk til \"%s\""
+
+msgid "Entering Ex mode. Type \"visual\" to go to Normal mode."
+msgstr "Går inn i Ex-modus. Skriv \"visual\" for å gå til normalmodus."
+
+msgid "E501: At end-of-file"
+msgstr "E501: Ved slutten av filen"
+
+msgid "E169: Command too recursive"
+msgstr "E169: Kommando altfor rekursiv"
+
+#, c-format
+msgid "E605: Exception not caught: %s"
+msgstr "E605: Unntak ikke fanget opp: %s"
+
+msgid "End of sourced file"
+msgstr "Slutt på kjørt fil"
+
+msgid "End of function"
+msgstr "Slutt på funksjon"
+
+msgid "E464: Ambiguous use of user-defined command"
+msgstr "E464: Flertydig bruk av brukerdefinert kommando"
+
+msgid "E492: Not an editor command"
+msgstr "E492: Er ikke en editorkommando"
+
+msgid "E493: Backwards range given"
+msgstr "E493: Område bakover er angitt"
+
+msgid "Backwards range given, OK to swap"
+msgstr "Område bakover er angitt, OK å swappe"
+
+msgid "E494: Use w or w>>"
+msgstr "E494: Bruk w eller w>>"
+
+msgid "E319: Sorry, the command is not available in this version"
+msgstr "E319: Kommandoen er ikke tilgjengelig i denne versjonen"
+
+msgid "E172: Only one file name allowed"
+msgstr "E172: Bare ett filnavn tillatt"
+
+msgid "1 more file to edit. Quit anyway?"
+msgstr "1 annen fil å redigere. Avslutt likevel?"
+
+#, c-format
+msgid "%d more files to edit. Quit anyway?"
+msgstr "%d andre filer å redigere. Avslutt likevel?"
+
+msgid "E173: 1 more file to edit"
+msgstr "E173: 1 annen fil å redigere"
+
+#, c-format
+msgid "E173: %ld more files to edit"
+msgstr "E173: %ld andre filer å redigere"
+
+msgid "E174: Command already exists: add ! to replace it"
+msgstr "E174: Kommandoen finnes allerede: Legg til ! for å erstatte den"
+
+msgid ""
+"\n"
+" Name Args Range Complete Definition"
+msgstr ""
+"\n"
+" Navn Prm. Områd Fullfør Definering"
+
+msgid "No user-defined commands found"
+msgstr "Ingen brukerdefinerte kommandoer funnet"
+
+msgid "E175: No attribute specified"
+msgstr "E175: Ingen attributt spesifisert"
+
+msgid "E176: Invalid number of arguments"
+msgstr "E176: Ugyldig antall parametere"
+
+msgid "E177: Count cannot be specified twice"
+msgstr "E177: Antall repeteringer kan ikke bli spesifisert to ganger"
+
+msgid "E178: Invalid default value for count"
+msgstr "E178: Ugyldig standardverdi for antall repeteringer"
+
+msgid "E179: argument required for -complete"
+msgstr "E179: Trenger parameter til -complete"
+
+#, c-format
+msgid "E181: Invalid attribute: %s"
+msgstr "E181: Ugyldig attributt: %s"
+
+msgid "E182: Invalid command name"
+msgstr "E182: Ugyldig kommandonavn"
+
+msgid "E183: User defined commands must start with an uppercase letter"
+msgstr "E183: Brukerdefinerte kommandoer må ha stor forbokstav"
+
+#, c-format
+msgid "E184: No such user-defined command: %s"
+msgstr "E184: Brukerdefinert kommando finnes ikke: %s"
+
+#, c-format
+msgid "E180: Invalid complete value: %s"
+msgstr "E180: Ugyldig \"complete\"-verdi: %s"
+
+msgid "E468: Completion argument only allowed for custom completion"
+msgstr "E468: Fullføringsparameter er bare tillatt for tilpasset fullføring"
+
+msgid "E467: Custom completion requires a function argument"
+msgstr "E467: Tilpassede fullføringer trenger et funksjonsparameter"
+
+#, c-format
+msgid "E185: Cannot find color scheme %s"
+msgstr "E185: Kan ikke finne fargeoppsettet %s"
+
+msgid "Greetings, Vim user!"
+msgstr "Vær hilset, Vim-bruker!"
+
+#, fuzzy
+#~ msgid "E784: Cannot close last tab page"
+#~ msgstr "E444: Kan ikke lukke det siste vinduet"
+
+#, fuzzy
+#~ msgid "Already only one tab page"
+#~ msgstr "Allerede bare ett vindu"
+
+msgid "Edit File in new window"
+msgstr "Rediger fil i nytt vindu"
+
+#, fuzzy, c-format
+#~ msgid "Tab page %d"
+#~ msgstr "Side %d"
+
+msgid "No swap file"
+msgstr "Ingen swapfil"
+
+msgid "Append File"
+msgstr "Legg til fil"
+
+msgid "E747: Cannot change directory, buffer is modified (add ! to override)"
+msgstr ""
+"E747: Kan ikke skifte katalog, bufferen er forandret (legg til ! for å "
+"overstyre)"
+
+msgid "E186: No previous directory"
+msgstr "E186: Ingen tidligere katalog"
+
+msgid "E187: Unknown"
+msgstr "E187: Ukjent"
+
+msgid "E465: :winsize requires two number arguments"
+msgstr "E465: :winsize trenger to numeriske parametere"
+
+#, c-format
+msgid "Window position: X %d, Y %d"
+msgstr "Vindusposisjon: X %d, Y %d"
+
+msgid "E188: Obtaining window position not implemented for this platform"
+msgstr ""
+"E188: Lesing av vindusposisjon er ikke implementert på denne plattformen"
+
+msgid "E466: :winpos requires two number arguments"
+msgstr "E466: :winpos trenger to numeriske parametere"
+
+msgid "Save Redirection"
+msgstr "Lagre omdirigering"
+
+msgid "Save View"
+msgstr "Lagre utseende"
+
+msgid "Save Session"
+msgstr "Lagre økt"
+
+msgid "Save Setup"
+msgstr "Lagre oppsett"
+
+#, c-format
+msgid "E739: Cannot create directory: %s"
+msgstr "E739: Kan ikke lage katalog: %s"
+
+#, c-format
+msgid "E189: \"%s\" exists (add ! to override)"
+msgstr "E189: \"%s\" finnes (legg til ! for å overstyre)"
+
+#, c-format
+msgid "E190: Cannot open \"%s\" for writing"
+msgstr "E190: Kan ikke åpne \"%s\" for skriving"
+
+#. set mark
+msgid "E191: Argument must be a letter or forward/backward quote"
+msgstr "E191: Parameter må være en bokstav eller vanlig/baklengs apostrof"
+
+msgid "E192: Recursive use of :normal too deep"
+msgstr "E192: Rekursiv bruk av :normal er for dyp"
+
+msgid "E194: No alternate file name to substitute for '#'"
+msgstr "E194: Ingen alternative filnavn tilgjengelig som erstatning for '#'"
+
+msgid "E495: no autocommand file name to substitute for \"<afile>\""
+msgstr ""
+"E495: Ingen autokommandofilnavn tilgjengelig som erstatning for \"<afile>\""
+
+msgid "E496: no autocommand buffer number to substitute for \"<abuf>\""
+msgstr ""
+"E496: Ingen buffernummer tilgjengelig som erstatning for \"<abuf>\" i "
+"autokommando"
+
+msgid "E497: no autocommand match name to substitute for \"<amatch>\""
+msgstr ""
+"E497: Ingen autokommandonavn tilgjengelig som erstatning for \"<amatch>\""
+
+msgid "E498: no :source file name to substitute for \"<sfile>\""
+msgstr ""
+"E498: Ingen ':source'-filnavn tilgjengelig som erstatning for \"<sfile>\""
+
+#, no-c-format
+msgid "E499: Empty file name for '%' or '#', only works with \":p:h\""
+msgstr "E499: Tomt filnavn for '%' eller '#', virker bare med \":p:h\""
+
+msgid "E500: Evaluates to an empty string"
+msgstr "E500: Resulterer i en tom streng"
+
+msgid "E195: Cannot open viminfo file for reading"
+msgstr "E195: Kan ikke åpne viminfo-fil for lesing"
+
+msgid "E196: No digraphs in this version"
+msgstr "E196: Ingen spesialtegn i denne versjonen"
+
+msgid "E608: Cannot :throw exceptions with 'Vim' prefix"
+msgstr "E608: Kan ikke :throw unntak med 'Vim'-forstavelse"
+
+#. always scroll up, don't overwrite
+#, c-format
+#~ msgid "Exception thrown: %s"
+#~ msgstr ""
+
+#, c-format
+msgid "Exception finished: %s"
+msgstr "Unntak fullført: %s"
+
+#, c-format
+msgid "Exception discarded: %s"
+msgstr "Unntak forkastet: %s"
+
+#, c-format
+msgid "%s, line %ld"
+msgstr "%s, linje %ld"
+
+#. always scroll up, don't overwrite
+#, c-format
+msgid "Exception caught: %s"
+msgstr "Unntak fanget opp: %s"
+
+#, c-format
+msgid "%s made pending"
+msgstr "%s satt på venting"
+
+#, c-format
+msgid "%s resumed"
+msgstr "%s gjenopptatt"
+
+#, c-format
+msgid "%s discarded"
+msgstr "%s forkastet"
+
+msgid "Exception"
+msgstr "Unntak"
+
+msgid "Error and interrupt"
+msgstr "Feil og avbrudd"
+
+msgid "Error"
+msgstr "Feil"
+
+#. if (pending & CSTP_INTERRUPT)
+msgid "Interrupt"
+msgstr "Avbrudd"
+
+msgid "E579: :if nesting too deep"
+msgstr "E579: Nøsting av :if for dyp"
+
+msgid "E580: :endif without :if"
+msgstr "E580: :endif uten :if"
+
+msgid "E581: :else without :if"
+msgstr "E581: :else uten :if"
+
+msgid "E582: :elseif without :if"
+msgstr "E582: :elseif uten :if"
+
+msgid "E583: multiple :else"
+msgstr "E583: Flere forekomster av :else"
+
+msgid "E584: :elseif after :else"
+msgstr "E584: :elseif etter :else"
+
+msgid "E585: :while/:for nesting too deep"
+msgstr "E585: Nøsting av :while/:for er for dyp"
+
+msgid "E586: :continue without :while or :for"
+msgstr "E586: :continue uten :while eller :for"
+
+msgid "E587: :break without :while or :for"
+msgstr "E587: :break uten :while eller :for"
+
+msgid "E732: Using :endfor with :while"
+msgstr "E732: Bruker :endfor sammen med :while"
+
+msgid "E733: Using :endwhile with :for"
+msgstr "E733: Bruker :endwhile sammen med :for"
+
+msgid "E601: :try nesting too deep"
+msgstr "E601: Nøsting av :try for dyp"
+
+msgid "E603: :catch without :try"
+msgstr "E603: :catch uten :try"
+
+#. Give up for a ":catch" after ":finally" and ignore it.
+#. * Just parse.
+msgid "E604: :catch after :finally"
+msgstr "E604: :catch etter :finally"
+
+msgid "E606: :finally without :try"
+msgstr "E606: :finally uten :try"
+
+#. Give up for a multiple ":finally" and ignore it.
+msgid "E607: multiple :finally"
+msgstr "E607: Flere forekomster av :finally"
+
+msgid "E602: :endtry without :try"
+msgstr "E602: :endtry uten :try"
+
+msgid "E193: :endfunction not inside a function"
+msgstr "E193: :endfunction er ikke innenfor en funksjon"
+
+msgid "E788: Not allowed to edit another buffer now"
+msgstr "E788: Ikke tillatt å redigere en annen buffer nå"
+
+msgid "tagname"
+msgstr "navn på tag"
+
+#~ msgid " kind file\n"
+#~ msgstr ""
+
+msgid "'history' option is zero"
+msgstr "'history'-valget er null"
+
+#, c-format
+msgid ""
+"\n"
+"# %s History (newest to oldest):\n"
+msgstr ""
+"\n"
+"# %s-historie (nyeste til eldste):\n"
+
+msgid "Command Line"
+msgstr "Kommandolinje"
+
+msgid "Search String"
+msgstr "Søkestreng"
+
+msgid "Expression"
+msgstr "Uttrykk"
+
+msgid "Input Line"
+msgstr "Inndatalinje"
+
+msgid "E198: cmd_pchar beyond the command length"
+msgstr "E198: cmd_pchar utenfor kommandolengden"
+
+msgid "E199: Active window or buffer deleted"
+msgstr "E199: Aktivt vindu eller buffer slettet"
+
+msgid "Illegal file name"
+msgstr "Ulovlig filnavn"
+
+msgid "is a directory"
+msgstr "er en katalog"
+
+msgid "is not a file"
+msgstr "er ikke en fil"
+
+msgid "is a device (disabled with 'opendevice' option)"
+msgstr "er en enhet (frakoblet med 'opendevice'-valg)"
+
+msgid "[New File]"
+msgstr "[Ny fil]"
+
+msgid "[New DIRECTORY]"
+msgstr "[Ny KATALOG]"
+
+msgid "[File too big]"
+msgstr "[Filen er for stor]"
+
+msgid "[Permission Denied]"
+msgstr "[Tilgang nektet]"
+
+msgid "E200: *ReadPre autocommands made the file unreadable"
+msgstr "E200: \"*ReadPre\"-autokommandoer gjorde filen uleselig"
+
+msgid "E201: *ReadPre autocommands must not change current buffer"
+msgstr "E201: \"*ReadPre\"-autokommandoer må ikke forandre nåværende buffer"
+
+msgid "Vim: Reading from stdin...\n"
+msgstr "Vim: Leser fra stdin ...\n"
+
+msgid "Reading from stdin..."
+msgstr "Leser fra stdin ..."
+
+#. Re-opening the original file failed!
+msgid "E202: Conversion made file unreadable!"
+msgstr "E202: Konverteringen gjorde filen uleselig!"
+
+msgid "[fifo/socket]"
+msgstr "[fifo/socket]"
+
+msgid "[fifo]"
+msgstr "[fifo]"
+
+msgid "[socket]"
+msgstr "[socket]"
+
+msgid "[RO]"
+msgstr "[SB]"
+
+msgid "[CR missing]"
+msgstr "[CR mangler]"
+
+msgid "[NL found]"
+msgstr "[NL funnet]"
+
+msgid "[long lines split]"
+msgstr "[lange linjer splittes]"
+
+msgid "[NOT converted]"
+msgstr "[IKKE konvertert]"
+
+msgid "[converted]"
+msgstr "[konvertert]"
+
+msgid "[crypted]"
+msgstr "[kryptert]"
+
+#, c-format
+msgid "[CONVERSION ERROR in line %ld]"
+msgstr "[KONVERTERINGSFEIL i linje %ld]"
+
+#, c-format
+msgid "[ILLEGAL BYTE in line %ld]"
+msgstr "[ULOVLIG BYTE i linje %ld]"
+
+msgid "[READ ERRORS]"
+msgstr "[LESEFEIL]"
+
+msgid "Can't find temp file for conversion"
+msgstr "Kan ikke finne midlertidig fil for konvertering"
+
+msgid "Conversion with 'charconvert' failed"
+msgstr "Konvertering med 'charconvert' feilet"
+
+msgid "can't read output of 'charconvert'"
+msgstr "Kan ikke lese utdata fra 'charconvert'"
+
+msgid "E676: No matching autocommands for acwrite buffer"
+msgstr "E676: Ingen samsvarende autokommandoer for 'acwrite'-buffer"
+
+msgid "E203: Autocommands deleted or unloaded buffer to be written"
+msgstr "E203: Autokommandoer slettet eller lastet ut buffer som skulle lagres"
+
+msgid "E204: Autocommand changed number of lines in unexpected way"
+msgstr "E204: Autokommando forandret linjeantall på en uventet måte"
+
+msgid "NetBeans disallows writes of unmodified buffers"
+msgstr "NetBeans forbyr lagring av buffere som ikke er forandret"
+
+msgid "Partial writes disallowed for NetBeans buffers"
+msgstr "Delvis lagring ikke tillatt for NetBeans-buffere"
+
+msgid "is not a file or writable device"
+msgstr "er ikke en fil eller skrivbar enhet"
+
+msgid "writing to device disabled with 'opendevice' option"
+msgstr "skriving til enhet er slått av med 'opendevice'-valg"
+
+msgid "is read-only (add ! to override)"
+msgstr "er skrivebeskyttet (legg til ! for å overstyre)"
+
+msgid "E506: Can't write to backup file (add ! to override)"
+msgstr "E506: Kan ikke skrive til backupfil (legg til ! for å overstyre)"
+
+msgid "E507: Close error for backup file (add ! to override)"
+msgstr "E507: Feil under lukking av backupfil (legg til ! for å overstyre)"
+
+msgid "E508: Can't read file for backup (add ! to override)"
+msgstr "E508: Kan ikke lese fil for backup (legg til ! for å overstyre)"
+
+msgid "E509: Cannot create backup file (add ! to override)"
+msgstr "E509: Kan ikke lese backupfil (legg til ! for å overstyre)"
+
+msgid "E510: Can't make backup file (add ! to override)"
+msgstr "E510: Kan ikke lage backupfil (legg til ! for å overstyre)"
+
+msgid "E460: The resource fork would be lost (add ! to override)"
+msgstr "E460: Ressursforgreningen ville gått tapt (legg til ! for å overstyre)"
+
+msgid "E214: Can't find temp file for writing"
+msgstr "E214: Kan ikke finne midlertidig fil for skriving"
+
+msgid "E213: Cannot convert (add ! to write without conversion)"
+msgstr "E213: Kan ikke konvertere (legg til ! for å lagre uten konvertering)"
+
+msgid "E166: Can't open linked file for writing"
+msgstr "E166: Kan ikke åpne lenket fil for skriving"
+
+msgid "E212: Can't open file for writing"
+msgstr "E212: Kan ikke åpne fil for skriving"
+
+msgid "E667: Fsync failed"
+msgstr "E667: Fsync feilet"
+
+msgid "E512: Close failed"
+msgstr "E512: Lukking feilet"
+
+msgid "E513: write error, conversion failed (make 'fenc' empty to override)"
+msgstr ""
+"E513: Feil under skriving, konvertering feilet (gjør 'fenc' tom for å "
+"overstyre)"
+
+msgid "E514: write error (file system full?)"
+msgstr "E514: Feil under lagring (full disk?)"
+
+msgid " CONVERSION ERROR"
+msgstr " KONVERTERINGSFEIL"
+
+msgid "[Device]"
+msgstr "[Enhet]"
+
+msgid "[New]"
+msgstr "[Ny]"
+
+msgid " [a]"
+msgstr " [l]"
+
+msgid " appended"
+msgstr " lagt til"
+
+msgid " [w]"
+msgstr " [s]"
+
+msgid " written"
+msgstr " skrevet"
+
+msgid "E205: Patchmode: can't save original file"
+msgstr "E205: Patchmode: Kan ikke lagre originalfil"
+
+msgid "E206: patchmode: can't touch empty original file"
+msgstr "E206: patchmode: Kan ikke oppdatere tom originalfil"
+
+msgid "E207: Can't delete backup file"
+msgstr "E207: Kan ikke slette backupfil"
+
+msgid ""
+"\n"
+"WARNING: Original file may be lost or damaged\n"
+msgstr ""
+"\n"
+"ADVARSEL: Originalfilen kan bli tapt eller ødelagt\n"
+
+msgid "don't quit the editor until the file is successfully written!"
+msgstr "ikke avslutt editoren før filen er skikkelig lagret!"
+
+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 "%ld characters"
+msgstr "%ld tegn"
+
+msgid "[noeol]"
+msgstr "[ingenlinjeslutt]"
+
+msgid "[Incomplete last line]"
+msgstr "[Ufullstendig sistelinje]"
+
+#. 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 "ADVARSEL: Filen er blitt forandret siden den ble lest!!!"
+
+msgid "Do you really want to write to it"
+msgstr "Vil du virkelig skrive til den"
+
+#, c-format
+msgid "E208: Error writing to \"%s\""
+msgstr "E208: Feil under skriving til \"%s\""
+
+#, c-format
+msgid "E209: Error closing \"%s\""
+msgstr "E209: Feil under lukking av \"%s\""
+
+#, c-format
+msgid "E210: Error reading \"%s\""
+msgstr "E210: Feil under lesing av \"%s\""
+
+msgid "E246: FileChangedShell autocommand deleted buffer"
+msgstr "E246: Autokommandoen \"FileChangedShell\" slettet buffer"
+
+#, c-format
+msgid "E211: File \"%s\" no longer available"
+msgstr "E211: Filen \"%s\" er ikke lenger tilgjengelig"
+
+#, c-format
+msgid ""
+"W12: Warning: File \"%s\" has changed and the buffer was changed in Vim as "
+"well"
+msgstr ""
+"W12: Advarsel: Filen \"%s\" er forandret og bufferen var også forandret i Vim"
+
+msgid "See \":help W12\" for more info."
+msgstr "Se \":help W12\" for mer informasjon."
+
+#, c-format
+msgid "W11: Warning: File \"%s\" has changed since editing started"
+msgstr "W11: Advarsel: Filen \"%s\" er forandret siden redigeringen startet"
+
+msgid "See \":help W11\" for more info."
+msgstr "Se \":help W11\" for mer informasjon."
+
+#, c-format
+msgid "W16: Warning: Mode of file \"%s\" has changed since editing started"
+msgstr ""
+"W16: Advarsel: Rettighetene til filen \"%s\" er forandret siden redigeringen "
+"startet"
+
+msgid "See \":help W16\" for more info."
+msgstr "Se \":help W16\" for mer informasjon."
+
+#, c-format
+msgid "W13: Warning: File \"%s\" has been created after editing started"
+msgstr ""
+"W13: Advarsel: Filen \"%s\" er blitt opprettet etter at redigeringen startet"
+
+msgid "Warning"
+msgstr "Advarsel"
+
+msgid ""
+"&OK\n"
+"&Load File"
+msgstr ""
+"&OK\n"
+"&Åpne fil"
+
+#, c-format
+msgid "E462: Could not prepare for reloading \"%s\""
+msgstr "E462: Kunne ikke forberede for relasting \"%s\""
+
+#, c-format
+msgid "E321: Could not reload \"%s\""
+msgstr "E321: Kunne ikke laste \"%s\" på nytt"
+
+msgid "--Deleted--"
+msgstr "--Slettet--"
+
+#, c-format
+msgid "auto-removing autocommand: %s <buffer=%d>"
+msgstr "fjerner autokommando automatisk: %s <buffer=%d>"
+
+#. the group doesn't exist
+#, c-format
+msgid "E367: No such group: \"%s\""
+msgstr "E367: Gruppen finnes ikke: \"%s\""
+
+#, c-format
+msgid "E215: Illegal character after *: %s"
+msgstr "E215: Ulovlig tegn etter *: %s"
+
+#, c-format
+msgid "E216: No such event: %s"
+msgstr "E216: Handlingen finnes ikke: %s"
+
+#, c-format
+msgid "E216: No such group or event: %s"
+msgstr "E216: Gruppen eller handlingen finnes ikke: %s"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Auto-Commands ---"
+msgstr ""
+"\n"
+"--- Autokommandoer ---"
+
+#, c-format
+msgid "E680: <buffer=%d>: invalid buffer number "
+msgstr "E680: <buffer=%d>: Ugyldig buffernummer"
+
+msgid "E217: Can't execute autocommands for ALL events"
+msgstr "E217: Kan ikke utføre autokommandoer for ALLE hendelser"
+
+msgid "No matching autocommands"
+msgstr "Ingen samsvarende autokommandoer"
+
+msgid "E218: autocommand nesting too deep"
+msgstr "E218: Nøsting av autokommandoer for dyp"
+
+#, c-format
+msgid "%s Auto commands for \"%s\""
+msgstr "%s Autokommandoer for \"%s\""
+
+#, c-format
+msgid "Executing %s"
+msgstr "Utfører %s"
+
+#, c-format
+msgid "autocommand %s"
+msgstr "autokommando %s"
+
+msgid "E219: Missing {."
+msgstr "E219: Mangler {."
+
+msgid "E220: Missing }."
+msgstr "E220: Mangler }."
+
+msgid "E490: No fold found"
+msgstr "E490: Ingen fold funnet"
+
+msgid "E350: Cannot create fold with current 'foldmethod'"
+msgstr "E350: Kan ikke lage fold med nåværende 'foldmethod'"
+
+msgid "E351: Cannot delete fold with current 'foldmethod'"
+msgstr "E351: Kan ikke slette fold med nåværende 'foldmethod'"
+
+#, c-format
+msgid "+--%3ld lines folded "
+msgstr "+--%3ld linjer foldet "
+
+msgid "E222: Add to read buffer"
+msgstr "E222: Legger til allerede lest buffer"
+
+msgid "E223: recursive mapping"
+msgstr "E223: Rekursiv mapping"
+
+#, c-format
+msgid "E224: global abbreviation already exists for %s"
+msgstr "E224: Global forkortelse finnes allerede for %s"
+
+#, c-format
+msgid "E225: global mapping already exists for %s"
+msgstr "E225: Global mapping finnes allerede for %s"
+
+#, c-format
+msgid "E226: abbreviation already exists for %s"
+msgstr "E226: Forkortelse finnes allerede for %s"
+
+#, c-format
+msgid "E227: mapping already exists for %s"
+msgstr "E227: Mappingen finnes allerede for %s"
+
+msgid "No abbreviation found"
+msgstr "Ingen forkortelse funnet"
+
+msgid "No mapping found"
+msgstr "Ingen mapping funnet"
+
+msgid "E228: makemap: Illegal mode"
+msgstr "E228: makemap: Ulovlig modus"
+
+msgid "E229: Cannot start the GUI"
+msgstr "E229: Kan ikke starte grafisk brukergrensesnitt (GUI)"
+
+#, c-format
+msgid "E230: Cannot read from \"%s\""
+msgstr "E230: Kan ikke lese fra \"%s\""
+
+msgid "E665: Cannot start GUI, no valid font found"
+msgstr ""
+"E665: Kan ikke starte grafisk brukergrensesnitt, fant ingen gyldig font"
+
+msgid "E231: 'guifontwide' invalid"
+msgstr "E231: 'guifontwide' ugyldig"
+
+msgid "E599: Value of 'imactivatekey' is invalid"
+msgstr "E599: Verdien for 'imactivatekey' er ugyldig"
+
+#, c-format
+msgid "E254: Cannot allocate color %s"
+msgstr "E254: Kan ikke reservere farge %s"
+
+msgid "No match at cursor, finding next"
+msgstr "Ingen treff ved markøren, finner neste"
+
+msgid "<cannot open> "
+msgstr "<kan ikke åpne> "
+
+#, c-format
+msgid "E616: vim_SelFile: can't get font %s"
+msgstr "E616: vim_SelFile: Kan ikke bruke skrifttypen %s"
+
+msgid "E614: vim_SelFile: can't return to current directory"
+msgstr "E614: vim_SelFile: Kan ikke returnere til nåværende katalog"
+
+msgid "Pathname:"
+msgstr "Sti:"
+
+msgid "E615: vim_SelFile: can't get current directory"
+msgstr "E615: vim_SelFile: Kan ikke finne nåværende katalog"
+
+msgid "OK"
+msgstr "OK"
+
+msgid "Cancel"
+msgstr "Avbryt"
+
+msgid "Scrollbar Widget: Could not get geometry of thumb pixmap."
+msgstr "Rullefeltelement: Klarte ikke hente dimensjoner på \"thumb pixmap\"."
+
+msgid "Vim dialog"
+msgstr "Dialogvindu for Vim"
+
+msgid "E232: Cannot create BalloonEval with both message and callback"
+msgstr "E232: Kan ikke lage BalloonEval med både melding og tilbakekall"
+
+msgid "Vim dialog..."
+msgstr "Vim dialogvindu ..."
+
+msgid ""
+"&Yes\n"
+"&No\n"
+"&Cancel"
+msgstr ""
+"&Ja\n"
+"&Nei\n"
+"&Avbryt"
+
+msgid "Input _Methods"
+msgstr "Inndata-_metoder"
+
+msgid "VIM - Search and Replace..."
+msgstr "VIM - Søk og erstatt ..."
+
+msgid "VIM - Search..."
+msgstr "VIM - Søk ..."
+
+msgid "Find what:"
+msgstr "Finn hva:"
+
+msgid "Replace with:"
+msgstr "Erstatt med:"
+
+#. whole word only button
+msgid "Match whole word only"
+msgstr "Finn kun hele ord"
+
+#. match case button
+msgid "Match case"
+msgstr "Forskjell på store/små bokstaver"
+
+msgid "Direction"
+msgstr "Retning"
+
+#. 'Up' and 'Down' buttons
+msgid "Up"
+msgstr "Opp"
+
+msgid "Down"
+msgstr "Ned"
+
+msgid "Find Next"
+msgstr "Finn neste"
+
+msgid "Replace"
+msgstr "Erstatt"
+
+msgid "Replace All"
+msgstr "Erstatt alle"
+
+msgid "Vim: Received \"die\" request from session manager\n"
+msgstr "Vim: Mottok \"dø\"-forespørsel fra øktbehandleren\n"
+
+msgid "Close"
+msgstr "Lukk"
+
+#~ msgid "New tab"
+#~ msgstr ""
+
+#~ msgid "Open Tab..."
+#~ msgstr ""
+
+msgid "Vim: Main window unexpectedly destroyed\n"
+msgstr "Vim: Uventet ødeleggelse av hovedvinduet\n"
+
+msgid "Font Selection"
+msgstr "Velge skrifttype"
+
+msgid "Used CUT_BUFFER0 instead of empty selection"
+msgstr "Brukte CUT_BUFFER0 istedenfor tomt valg"
+
+msgid "&Filter"
+msgstr "&Filter"
+
+msgid "&Cancel"
+msgstr "&Avbryt"
+
+msgid "Directories"
+msgstr "Kataloger"
+
+msgid "Filter"
+msgstr "Filter"
+
+msgid "&Help"
+msgstr "&Hjelp"
+
+msgid "Files"
+msgstr "Filer"
+
+msgid "&OK"
+msgstr "&OK"
+
+msgid "Selection"
+msgstr "Valg"
+
+msgid "Find &Next"
+msgstr "Finn &neste"
+
+msgid "&Replace"
+msgstr "E&rstatt"
+
+msgid "Replace &All"
+msgstr "Erstatt &alle"
+
+msgid "&Undo"
+msgstr "&Angre"
+
+#, c-format
+msgid "E671: Cannot find window title \"%s\""
+msgstr "E671: Fant ikke vindutittel \"%s\""
+
+#, c-format
+msgid "E243: Argument not supported: \"-%s\"; Use the OLE version."
+msgstr "E243: Parameter ikke støttet: \"-%s\"; Bruk OLE-versjonen."
+
+msgid "E672: Unable to open window inside MDI application"
+msgstr "E672: Klarer ikke åpne vindu inne i MDI-applikasjon"
+
+#~ msgid "Close tab"
+#~ msgstr ""
+
+#~ msgid "Open tab..."
+#~ msgstr ""
+
+msgid "Find string (use '\\\\' to find a '\\')"
+msgstr "Finn streng (bruk '\\\\' for å finne en '\\')"
+
+msgid "Find & Replace (use '\\\\' to find a '\\')"
+msgstr "Søk og erstatt (bruk '\\\\' for å finne en '\\')"
+
+#. 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 "Ikke brukt"
+
+msgid "Directory\t*.nothing\n"
+msgstr "Katalog\t*.ingenting\n"
+
+msgid "Vim E458: Cannot allocate colormap entry, some colors may be incorrect"
+msgstr "Vim E458: Kan ikke reservere fargekart, noen farger kan være feil"
+
+#, c-format
+msgid "E250: Fonts for the following charsets are missing in fontset %s:"
+msgstr "E250: Skrifttyper for de følgende tegnsett mangler i fontsett %s:"
+
+#, c-format
+msgid "E252: Fontset name: %s"
+msgstr "E252: Navn på skrifttypesett: %s"
+
+#, c-format
+msgid "Font '%s' is not fixed-width"
+msgstr "Skrifttypen '%s' har ikke konstant bredde"
+
+#, c-format
+msgid "E253: Fontset name: %s\n"
+msgstr "E253: Navn på skrifttypesett: %s\n"
+
+#, c-format
+msgid "Font0: %s\n"
+msgstr "Font0: %s\n"
+
+#, c-format
+msgid "Font1: %s\n"
+msgstr "Font1: %s\n"
+
+#, c-format
+msgid "Font%ld width is not twice that of font0\n"
+msgstr "Font%ld-bredde er ikke to ganger bredden av font0\n"
+
+#, c-format
+msgid "Font0 width: %ld\n"
+msgstr "Font0-bredde: %ld\n"
+
+#, c-format
+msgid ""
+"Font1 width: %ld\n"
+"\n"
+msgstr ""
+"Font1-bredde: %ld\n"
+"\n"
+
+msgid "Invalid font specification"
+msgstr "Ugyldig skrifttypespesifisering"
+
+msgid "&Dismiss"
+msgstr "&Forkast"
+
+msgid "no specific match"
+msgstr "ingen spesifikke treff"
+
+msgid "Vim - Font Selector"
+msgstr "Vim - Skrifttypevelger"
+
+msgid "Name:"
+msgstr "Navn:"
+
+#. create toggle button
+msgid "Show size in Points"
+msgstr "Vis størrelse i punkter"
+
+msgid "Encoding:"
+msgstr "Koding:"
+
+msgid "Font:"
+msgstr "Skrifttype:"
+
+msgid "Style:"
+msgstr "Stil:"
+
+msgid "Size:"
+msgstr "Størrelse:"
+
+#~ msgid "E256: Hangul automata ERROR"
+#~ msgstr ""
+
+msgid "E550: Missing colon"
+msgstr "E550: Mangler kolon"
+
+msgid "E551: Illegal component"
+msgstr "E551: Ulovlig komponent"
+
+msgid "E552: digit expected"
+msgstr "E552: Siffer forventet"
+
+#, c-format
+msgid "Page %d"
+msgstr "Side %d"
+
+msgid "No text to be printed"
+msgstr "Ingen tekst for utskrift"
+
+#, c-format
+msgid "Printing page %d (%d%%)"
+msgstr "Skriver ut side %d (%d%%)"
+
+#, c-format
+msgid " Copy %d of %d"
+msgstr " Kopi %d av %d"
+
+#, c-format
+msgid "Printed: %s"
+msgstr "Skrevet ut: %s"
+
+msgid "Printing aborted"
+msgstr "Utskrift avbrutt"
+
+msgid "E455: Error writing to PostScript output file"
+msgstr "E455: Feil under skriving til Postscript-fil"
+
+#, c-format
+msgid "E624: Can't open file \"%s\""
+msgstr "E624: Kan ikke åpne filen \"%s\""
+
+#, c-format
+msgid "E457: Can't read PostScript resource file \"%s\""
+msgstr "E457: Kan ikke lese Postscript-ressursfil \"%s\""
+
+#, c-format
+msgid "E618: file \"%s\" is not a PostScript resource file"
+msgstr "E618: Filen \"%s\" er ikke en Postscript-ressursfil"
+
+#, c-format
+msgid "E619: file \"%s\" is not a supported PostScript resource file"
+msgstr "E619: Det er ikke støtte for Postscript-ressursfilen \"%s\""
+
+#, c-format
+msgid "E621: \"%s\" resource file has wrong version"
+msgstr "E621: Ressursfilen \"%s\" er feil versjon"
+
+msgid "E673: Incompatible multi-byte encoding and character set."
+msgstr "E673: Inkompatibel multibytekoding og tegnsett"
+
+msgid "E674: printmbcharset cannot be empty with multi-byte encoding."
+msgstr "E674: printmbcharset kan ikke være tom med multibytekoding"
+
+msgid "E675: No default font specified for multi-byte printing."
+msgstr "E675: Ingen standardfont spesifisert for multibyteutskrift"
+
+msgid "E324: Can't open PostScript output file"
+msgstr "E324: Kan ikke åpne Postscript-fil for skriving"
+
+#, c-format
+msgid "E456: Can't open file \"%s\""
+msgstr "E456: Kan ikke åpne filen \"%s\""
+
+msgid "E456: Can't find PostScript resource file \"prolog.ps\""
+msgstr "E456: Fant ikke Postscript-ressursfilen \"prolog.ps\""
+
+msgid "E456: Can't find PostScript resource file \"cidfont.ps\""
+msgstr "E456: Fant ikke Postscript-ressursfilen \"cidfont.ps\""
+
+#, c-format
+msgid "E456: Can't find PostScript resource file \"%s.ps\""
+msgstr "E456: Fant ikke Postscript-ressursfilen \"%s.ps\""
+
+#, c-format
+msgid "E620: Unable to convert to print encoding \"%s\""
+msgstr "E620: Klarte ikke å konvertere til utskriftskoding \"%s\""
+
+msgid "Sending to printer..."
+msgstr "Sender til skriver ..."
+
+msgid "E365: Failed to print PostScript file"
+msgstr "E365: Feil under utskrift av Postscript-fil"
+
+msgid "Print job sent."
+msgstr "Skriverjobb sendt."
+
+msgid "Add a new database"
+msgstr "Legg til en ny database"
+
+msgid "Query for a pattern"
+msgstr "Forespørsel etter søkestreng"
+
+msgid "Show this message"
+msgstr "Vis denne meldingen"
+
+msgid "Kill a connection"
+msgstr "Drep en forbindelse"
+
+msgid "Reinit all connections"
+msgstr "Reinitialiser alle forbindelser"
+
+msgid "Show connections"
+msgstr "Vis forbindelser"
+
+#, c-format
+msgid "E560: Usage: cs[cope] %s"
+msgstr "E560: Bruk: cs[cope] %s"
+
+msgid "This cscope command does not support splitting the window.\n"
+msgstr "Denne cscope-kommandoen støtter ikke splitting av vinduet.\n"
+
+msgid "E562: Usage: cstag <ident>"
+msgstr "E562: Bruk: cstag <identifikator>"
+
+msgid "E257: cstag: tag not found"
+msgstr "E257: cstag: Tag ikke funnet"
+
+#, c-format
+msgid "E563: stat(%s) error: %d"
+msgstr "E563: stat(%s) feil: %d"
+
+msgid "E563: stat error"
+msgstr "E563: \"stat\"-feil"
+
+#, c-format
+msgid "E564: %s is not a directory or a valid cscope database"
+msgstr "E564: %s er ikke en katalog eller gyldig cscope-database"
+
+#, c-format
+msgid "Added cscope database %s"
+msgstr "La til cscope-database %s"
+
+#, c-format
+msgid "E262: error reading cscope connection %ld"
+msgstr "E262: Feil under lesing av cscope-forbindelse %ld"
+
+msgid "E561: unknown cscope search type"
+msgstr "E561: Ukjent cscope-søketype"
+
+msgid "E566: Could not create cscope pipes"
+msgstr "E566: Kunne ikke lage cscope-rør (\"pipe\")"
+
+msgid "E622: Could not fork for cscope"
+msgstr "E622: Klarte ikke lage tvillingprosess for cscope"
+
+msgid "cs_create_connection exec failed"
+msgstr "Utføring av cs_create_connection feilet"
+
+msgid "E623: Could not spawn cscope process"
+msgstr "E623: Klarte ikke starte cscope-prosess"
+
+msgid "cs_create_connection: fdopen for to_fp failed"
+msgstr "cs_create_connection: fdopen for to_fp feilet"
+
+msgid "cs_create_connection: fdopen for fr_fp failed"
+msgstr "cs_create_connection: fdopen for fr_fp feilet"
+
+msgid "E567: no cscope connections"
+msgstr "E567: Ingen cscope-forbindelse"
+
+#, c-format
+msgid "E259: no matches found for cscope query %s of %s"
+msgstr "E259: Ingen treff funnet for cscope-forespørsel %s av %s"
+
+#, c-format
+msgid "E469: invalid cscopequickfix flag %c for %c"
+msgstr "E469: Ugyldig \"cscopequickfix\"-flagg %c for %c"
+
+msgid "cscope commands:\n"
+msgstr "cscope-kommandoer:\n"
+
+#, c-format
+msgid "%-5s: %-30s (Usage: %s)"
+msgstr "%-5s: %-30s (Bruk: %s)"
+
+#, c-format
+msgid "E625: cannot open cscope database: %s"
+msgstr "E625: Kan ikke åpne cscope-database: %s"
+
+msgid "E626: cannot get cscope database information"
+msgstr "E626: Kan ikke hente informasjon om cscope-database"
+
+msgid "E568: duplicate cscope database not added"
+msgstr "E568: Duplisert cscope-database ikke lagt til"
+
+msgid "E569: maximum number of cscope connections reached"
+msgstr "E569: Maksimum antall cscope-forbindelser nådd"
+
+#, c-format
+msgid "E261: cscope connection %s not found"
+msgstr "E261: cscope-forbindelse %s ikke funnet"
+
+#, c-format
+msgid "cscope connection %s closed"
+msgstr "cscope-forbindelsen %s stengt"
+
+#. should not reach here
+msgid "E570: fatal error in cs_manage_matches"
+msgstr "E570: Kritisk feil 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: Cscope-feil: %s"
+
+msgid "All cscope databases reset"
+msgstr "Alle cscope-databaser resatt"
+
+msgid "no cscope connections\n"
+msgstr "ingen cscope-forbindelser\n"
+
+msgid " # pid database name prepend path\n"
+msgstr " # pid databasenavn legg til sti\n"
+
+msgid ""
+"???: Sorry, this command is disabled, the MzScheme library could not be "
+"loaded."
+msgstr ""
+"???: Denne kommandoen er deaktivert, MzScheme-biblioteket kunne ikke lastes."
+
+msgid "invalid expression"
+msgstr "ugyldig uttrykk"
+
+msgid "expressions disabled at compile time"
+msgstr "uttrykk deaktivert på kompileringsstadiet"
+
+msgid "hidden option"
+msgstr "skjult valg"
+
+msgid "unknown option"
+msgstr "ukjent valg"
+
+msgid "window index is out of range"
+msgstr "indeks for vindu er utenfor område"
+
+msgid "couldn't open buffer"
+msgstr "klarte ikke å åpne buffer"
+
+msgid "cannot save undo information"
+msgstr "kan ikke lagre angre-informasjon"
+
+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 sette inn linje"
+
+msgid "string cannot contain newlines"
+msgstr "streng kan ikke inneholde linjeskift"
+
+msgid "Vim error: ~a"
+msgstr "Vim-feil: ~a"
+
+msgid "Vim error"
+msgstr "Vim-feil"
+
+msgid "buffer is invalid"
+msgstr "buffer er ugyldig"
+
+msgid "window is invalid"
+msgstr "vindu er ugyldig"
+
+msgid "linenr out of range"
+msgstr "linjenummer utenfor område"
+
+msgid "not allowed in the Vim sandbox"
+msgstr "ikke tillatt i Vim-sandkassen"
+
+msgid ""
+"E263: Sorry, this command is disabled, the Python library could not be "
+"loaded."
+msgstr ""
+"E263: Denne kommandoen er deaktivert, Python-biblioteket kunne ikke lastes."
+
+msgid "E659: Cannot invoke Python recursively"
+msgstr "E659: Kan ikke starte Python rekursivt"
+
+msgid "can't delete OutputObject attributes"
+msgstr "Kan ikke slette \"OutputObject\"-attributter"
+
+msgid "softspace must be an integer"
+msgstr "\"softspace\" må være et heltall"
+
+msgid "invalid attribute"
+msgstr "ugyldig attributt"
+
+msgid "writelines() requires list of strings"
+msgstr "writelines() krever en liste av strenger"
+
+msgid "E264: Python: Error initialising I/O objects"
+msgstr "E264: Python: Feil under initialisering av I/U-objekter"
+
+msgid "attempt to refer to deleted buffer"
+msgstr "forsøk på å referere til slettet buffer"
+
+msgid "line number out of range"
+msgstr "linjenummer utenfor område"
+
+#, c-format
+msgid "<buffer object (deleted) at %8lX>"
+msgstr "<bufferobjekt (slettet) ved %8lX>"
+
+msgid "invalid mark name"
+msgstr "ugyldig merkenavn"
+
+msgid "no such buffer"
+msgstr "bufferen finnes ikke"
+
+msgid "attempt to refer to deleted window"
+msgstr "forsøk på å referere til slettet vindu"
+
+msgid "readonly attribute"
+msgstr "skrivebeskyttet attributt"
+
+msgid "cursor position outside buffer"
+msgstr "markørposisjon utenfor buffer"
+
+#, c-format
+msgid "<window object (deleted) at %.8lX>"
+msgstr "<vindusobjekt (slettet) ved %.8lX>"
+
+#, c-format
+msgid "<window object (unknown) at %.8lX>"
+msgstr "<vindusobjekt (ukjent) ved %.8lX>"
+
+#, c-format
+msgid "<window %d>"
+msgstr "<vindu %d>"
+
+msgid "no such window"
+msgstr "vinduet finnes ikke"
+
+#~ msgid "E265: $_ must be an instance of String"
+#~ msgstr ""
+
+msgid ""
+"E266: Sorry, this command is disabled, the Ruby library could not be loaded."
+msgstr ""
+"E266: Denne kommandoen er deaktivert, Ruby-biblioteket kunne ikke lastes."
+
+msgid "E267: unexpected return"
+msgstr "E267: Uventet return"
+
+msgid "E268: unexpected next"
+msgstr "E268: Uvented 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 ""
+
+msgid "E272: unhandled exception"
+msgstr "E272: Ubehandlet unntak"
+
+#, c-format
+msgid "E273: unknown longjmp status %d"
+msgstr "E273: Ukjent longjmp-status %d"
+
+msgid "Toggle implementation/definition"
+msgstr "Bytt mellom implementasjon/definisjon"
+
+msgid "Show base class of"
+msgstr "Vis basisklasse av"
+
+msgid "Show overridden member function"
+msgstr "Vis overstyrt medlemsfunksjon"
+
+msgid "Retrieve from file"
+msgstr "Hent fra fil"
+
+msgid "Retrieve from project"
+msgstr "Hent fra prosjekt"
+
+msgid "Retrieve from all projects"
+msgstr "Hent fra alle prosjekter"
+
+msgid "Retrieve"
+msgstr "Hent"
+
+msgid "Show source of"
+msgstr "Vis kilde til"
+
+msgid "Find symbol"
+msgstr "Finn symbol"
+
+msgid "Browse class"
+msgstr "Bla gjennom klasse"
+
+msgid "Show class in hierarchy"
+msgstr "Vis klasse i hierarki"
+
+msgid "Show class in restricted hierarchy"
+msgstr "Vis klasse i begrenset hierarki"
+
+msgid "Xref refers to"
+msgstr "Xref refererer til"
+
+msgid "Xref referred by"
+msgstr "Xref referert av"
+
+msgid "Xref has a"
+msgstr "Xref har en"
+
+msgid "Xref used by"
+msgstr "Xref brukt av"
+
+msgid "Show docu of"
+msgstr "Vis docu av"
+
+msgid "Generate docu for"
+msgstr "Generer docu for"
+
+msgid ""
+"Cannot connect to SNiFF+. Check environment (sniffemacs must be found in "
+"$PATH).\n"
+msgstr ""
+"Kan ikke koble til SNiFF+. Sjekk miljøet (\"environment\") (sniffemacs må "
+"bli funnet i $PATH).\n"
+
+msgid "E274: Sniff: Error during read. Disconnected"
+msgstr "E274: Sniff: Feil under lesing. Frakoblet"
+
+msgid "SNiFF+ is currently "
+msgstr "SNiFF+ er for øyeblikket "
+
+msgid "not "
+msgstr "ikke "
+
+msgid "connected"
+msgstr "oppkoblet"
+
+#, c-format
+msgid "E275: Unknown SNiFF+ request: %s"
+msgstr "E275: Ukjent SNiFF+-forespørsel: %s"
+
+msgid "E276: Error connecting to SNiFF+"
+msgstr "E276: Feil ved oppkobling til SNiFF+"
+
+msgid "E278: SNiFF+ not connected"
+msgstr "E278: SNiFF+ ikke tilkoblet"
+
+msgid "E279: Not a SNiFF+ buffer"
+msgstr "E279: Ikke en SNiFF+-buffer"
+
+msgid "Sniff: Error during write. Disconnected"
+msgstr "Sniff: Feil under skriving. Frakoblet"
+
+msgid "invalid buffer number"
+msgstr "ugyldig buffernummer"
+
+msgid "not implemented yet"
+msgstr "ikke implementert enda"
+
+#. ???
+msgid "cannot set line(s)"
+msgstr "kan ikke sette linje(r)"
+
+msgid "mark not set"
+msgstr "merke ikke satt"
+
+#, c-format
+msgid "row %d column %d"
+msgstr "rad %d kolonne %d"
+
+msgid "cannot insert/append line"
+msgstr "kan ikke sette inn/legge til linje"
+
+msgid "unknown flag: "
+msgstr "ukjent flagg: "
+
+msgid "unknown vimOption"
+msgstr "ukjent vimOption"
+
+msgid "keyboard interrupt"
+msgstr "tastaturavbrudd"
+
+msgid "vim error"
+msgstr "vim-feil"
+
+msgid "cannot create buffer/window command: object is being deleted"
+msgstr "kan ikke opprette buffer/vindukommando: Objektet slettes"
+
+msgid ""
+"cannot register callback command: buffer/window is already being deleted"
+msgstr ""
+"kan ikke registrere callback-kommando: Buffer/vindu er allerede slettet"
+
+#. This should never happen. Famous last word?
+msgid ""
+"E280: TCL FATAL ERROR: reflist corrupt!? Please report this to vim-dev@vim."
+"org"
+msgstr ""
+"E280: TCL KRITISK FEIL: reflist skadet!? Vennligst rapporter dette til vim-"
+"dev@vim.org"
+
+msgid "cannot register callback command: buffer/window reference not found"
+msgstr ""
+"kan ikke registrere callback-kommando: Buffer/vindureferanse ikke funnet"
+
+msgid ""
+"E571: Sorry, this command is disabled: the Tcl library could not be loaded."
+msgstr ""
+"E571: Denne kommandoen er deaktivert, Tcl-biblioteket kunne ikke lastes."
+
+msgid ""
+"E281: TCL ERROR: exit code is not int!? Please report this to vim-dev@vim.org"
+msgstr ""
+"E281: TCL-FEIL: Avslutningskode er ikke int!? Vennligst rapporter dette til "
+"vim-dev@vim.org"
+
+#, c-format
+msgid "E572: exit code %d"
+msgstr "E572: Avslutningskode %d"
+
+msgid "cannot get line"
+msgstr "kan ikke hente linje"
+
+msgid "Unable to register a command server name"
+msgstr "Klarer ikke registrere kommandotjenernavn"
+
+msgid "E248: Failed to send command to the destination program"
+msgstr "E248: Klarte ikke sende kommando til destinasjonsprogrammet"
+
+#, c-format
+msgid "E573: Invalid server id used: %s"
+msgstr "E573: Ugyldig tjener-id brukt: %s"
+
+msgid "E251: VIM instance registry property is badly formed. Deleted!"
+msgstr ""
+"E251: Registry-egenskapen for VIM-oppføringen er ikke korrekt. Slettet!"
+
+msgid "Unknown option argument"
+msgstr "Ukjent parameter til valg"
+
+msgid "Too many edit arguments"
+msgstr "For mange redigeringsparametere"
+
+msgid "Argument missing after"
+msgstr "Parameter mangler etter"
+
+msgid "Garbage after option argument"
+msgstr "Søppel etter valgparameter"
+
+msgid "Too many \"+command\", \"-c command\" or \"--cmd command\" arguments"
+msgstr ""
+"For mange \"+command\"-, \"-c command\"- eller \"--cmd kommando\"-parametere"
+
+msgid "Invalid argument for"
+msgstr "Ugyldig parameter for"
+
+#, c-format
+msgid "%d files to edit\n"
+msgstr "%d filer å redigere\n"
+
+msgid "This Vim was not compiled with the diff feature."
+msgstr "Denne Vim-versjonen er kompilert uten differansefunksjonen."
+
+msgid "Attempt to open script file again: \""
+msgstr "Forsøk på å åpne skriptfilen igjen: \""
+
+msgid "Cannot open for reading: \""
+msgstr "Kan ikke åpne for lesing: \""
+
+msgid "Cannot open for script output: \""
+msgstr "Kan ikke åpne for skript-utdata: \""
+
+msgid "Vim: Error: Failure to start gvim from NetBeans\n"
+msgstr "Vim: Feil: Feil under start av gvim fra NetBeans\n"
+
+msgid "Vim: Warning: Output is not to a terminal\n"
+msgstr "Vim: Advarsel: Utdata går ikke til en terminal\n"
+
+msgid "Vim: Warning: Input is not from a terminal\n"
+msgstr "Vim: Advarsel: Inndata kommer ikke fra en terminal\n"
+
+#. just in case..
+msgid "pre-vimrc command line"
+msgstr "pre-vimrc kommandolinje"
+
+#, c-format
+msgid "E282: Cannot read from \"%s\""
+msgstr "E282: Kan ikke lese fra \"%s\""
+
+msgid ""
+"\n"
+"More info with: \"vim -h\"\n"
+msgstr ""
+"\n"
+"Mer info med: \"vim -h\"\n"
+
+msgid "[file ..] edit specified file(s)"
+msgstr "[file ..] rediger spesifisert(e) fil(er)"
+
+msgid "- read text from stdin"
+msgstr "- les tekst fra stdin"
+
+msgid "-t tag edit file where tag is defined"
+msgstr "-t tag rediger fil hvor en tag er definert"
+
+msgid "-q [errorfile] edit file with first error"
+msgstr "-q [feilfil] rediger fil med første feil"
+
+msgid ""
+"\n"
+"\n"
+"usage:"
+msgstr ""
+"\n"
+"\n"
+"bruk:"
+
+msgid " vim [arguments] "
+msgstr " vim [parametere] "
+
+msgid ""
+"\n"
+" or:"
+msgstr ""
+"\n"
+" eller:"
+
+msgid "where case is ignored prepend / to make flag upper case"
+msgstr ""
+"der bokstavstørrelse ignoreres, legg til / i begynnelsen for\n"
+"å gjøre flagget om til stor bokstav"
+
+msgid ""
+"\n"
+"\n"
+"Arguments:\n"
+msgstr ""
+"\n"
+"\n"
+"Parametere:\n"
+
+msgid "--\t\t\tOnly file names after this"
+msgstr "--\t\t\tBare filnavn etter dette"
+
+msgid "--literal\t\tDon't expand wildcards"
+msgstr "--literal\t\tIkke utvid jokertegn"
+
+msgid "-register\t\tRegister this gvim for OLE"
+msgstr "-register\t\tRegistrer gvim for OLE"
+
+msgid "-unregister\t\tUnregister gvim for OLE"
+msgstr "-unregister\t\tFjern OLE-registrering for gvim"
+
+msgid "-g\t\t\tRun using GUI (like \"gvim\")"
+msgstr "-g\t\t\tKjør med GUI (som \"gvim\")"
+
+msgid "-f or --nofork\tForeground: Don't fork when starting GUI"
+msgstr "-f eller --nofork\tForgrunn: Ikke fork når GUI-et startes"
+
+msgid "-v\t\t\tVi mode (like \"vi\")"
+msgstr "-v\t\t\tVi-modus (som \"vi\")"
+
+msgid "-e\t\t\tEx mode (like \"ex\")"
+msgstr "-e\t\t\tEx-modus (som \"ex\")"
+
+msgid "-s\t\t\tSilent (batch) mode (only for \"ex\")"
+msgstr "-s\t\t\tStille (batch) modus (bare for \"ex\")"
+
+msgid "-d\t\t\tDiff mode (like \"vimdiff\")"
+msgstr "-d\t\t\tDifferanse-modus (som \"vimdiff\")"
+
+msgid "-y\t\t\tEasy mode (like \"evim\", modeless)"
+msgstr "-y\t\t\tLett modus (som \"evim\", uten modus)"
+
+msgid "-R\t\t\tReadonly mode (like \"view\")"
+msgstr "-R\t\t\tSkrivebeskyttet modus (som \"view\")"
+
+msgid "-Z\t\t\tRestricted mode (like \"rvim\")"
+msgstr "-Z\t\t\tBegrenset modus (som \"rvim\")"
+
+msgid "-m\t\t\tModifications (writing files) not allowed"
+msgstr "-m\t\t\tModifisering (lagring av filer) ikke tillatt"
+
+msgid "-M\t\t\tModifications in text not allowed"
+msgstr "-M\t\t\tModifiseringer i teksten ikke tillatt"
+
+msgid "-b\t\t\tBinary mode"
+msgstr "-b\t\t\tBinærmodus"
+
+msgid "-l\t\t\tLisp mode"
+msgstr "-l\t\t\tLisp-modus"
+
+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 helt Vi-kompatibel: 'nocompatible'"
+
+msgid "-V[N]\t\tVerbose level"
+msgstr "-V[N]\t\tInformasjonsnivå (\"Verbose\")"
+
+msgid "-D\t\t\tDebugging mode"
+msgstr "-D\t\t\tDebuggingsmodus"
+
+msgid "-n\t\t\tNo swap file, use memory only"
+msgstr "-n\t\t\tIngen swapfil, bruk bare hukommelsen"
+
+msgid "-r\t\t\tList swap files and exit"
+msgstr "-r\t\t\tList swapfiler og avslutt"
+
+msgid "-r (with file name)\tRecover crashed session"
+msgstr "-r (med filnavn)\tGjenopprett kræsjet økt"
+
+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\tIkke bruk newcli for å åpne vindu"
+
+msgid "-dev <device>\t\tUse <device> for I/O"
+msgstr "-dev <enhet>\t\tBruk <enhet> for I/U"
+
+msgid "-A\t\t\tstart in Arabic mode"
+msgstr "-A\t\t\tStart i arabisk modus"
+
+msgid "-H\t\t\tStart in Hebrew mode"
+msgstr "-H\t\t\tStart i hebraisk modus"
+
+msgid "-F\t\t\tStart in Farsi mode"
+msgstr "-F\t\t\tStart i persisk (Farsi) modus"
+
+msgid "-T <terminal>\tSet terminal type to <terminal>"
+msgstr "-T <terminal>\tSett terminaltypen til <terminal>"
+
+msgid "-u <vimrc>\t\tUse <vimrc> instead of any .vimrc"
+msgstr "-u <vimrc>\t\tBruk <vimrc> istedenfor eventuell .vimrc"
+
+msgid "-U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc"
+msgstr "-U <gvimrc>\t\tBruk <gvimrc> istedenfor eventuell .gvimrc"
+
+msgid "--noplugin\t\tDon't load plugin scripts"
+msgstr "--noplugin\t\tIkke last plugin-skripts"
+
+#, fuzzy
+#~ msgid "-p[N]\t\tOpen N tab pages (default: one for each file)"
+#~ msgstr "-o[N]\t\tÅpne N vinduer (standard: Ett for hver fil)"
+
+msgid "-o[N]\t\tOpen N windows (default: one for each file)"
+msgstr "-o[N]\t\tÅpne N vinduer (standard: Ett for hver fil)"
+
+msgid "-O[N]\t\tLike -o but split vertically"
+msgstr "-O[N]\t\tSom -o men splitt loddrett"
+
+msgid "+\t\t\tStart at end of file"
+msgstr "+\t\t\tStart på slutten av filen"
+
+msgid "+<lnum>\t\tStart at line <lnum>"
+msgstr "+<lnr>\t\tStart på linje <lnr>"
+
+msgid "--cmd <command>\tExecute <command> before loading any vimrc file"
+msgstr "--cmd <kommando>\tKjør <kommando> før lasting av vimrc-filer"
+
+msgid "-c <command>\t\tExecute <command> after loading the first file"
+msgstr "-c <kommando>\tKjør <kommando> etter lasting av første fil"
+
+msgid "-S <session>\t\tSource file <session> after loading the first file"
+msgstr "-S <økt>\t\tKjør filen <økt> etter lasting av første fil"
+
+msgid "-s <scriptin>\tRead Normal mode commands from file <scriptin>"
+msgstr "-s <innskript>\tLes normalmodus-kommandoer fra filen <innskript>"
+
+msgid "-w <scriptout>\tAppend all typed commands to file <scriptout>"
+msgstr "-w <utskript>\tLegg alle skrevne kommandoer til filen <utskript>"
+
+msgid "-W <scriptout>\tWrite all typed commands to file <scriptout>"
+msgstr "-W <utskript>\tSkriv alle skrevne kommandoer til filen <utskript>"
+
+msgid "-x\t\t\tEdit encrypted files"
+msgstr "-x\t\t\tRediger krypterte filer"
+
+msgid "-display <display>\tConnect vim to this particular X-server"
+msgstr "-display <display>\tKoble vim til denne spesielle X-tjeneren"
+
+msgid "-X\t\t\tDo not connect to X server"
+msgstr "-X\t\t\tUnngå oppkobling til X-tjener"
+
+msgid "--remote <files>\tEdit <files> in a Vim server if possible"
+msgstr "--remote <filer>\tRediger <filer> på en Vim-tjener hvis mulig"
+
+msgid "--remote-silent <files> Same, don't complain if there is no server"
+msgstr "--remote-silent <filer> Samme, ikke klag hvis tjeneren mangler"
+
+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 blir redigert"
+
+msgid ""
+"--remote-wait-silent <files> Same, don't complain if there is no server"
+msgstr "--remote-wait-silent <files> Samme, ikke klag hvis tjeneren mangler"
+
+#, fuzzy
+#~ msgid "--remote-tab <files> As --remote but open tab page for each file"
+#~ msgstr ""
+#~ "--remote-wait <filer> Som --remote men vent på filer som blir redigert"
+
+msgid "--remote-send <keys>\tSend <keys> to a Vim server and exit"
+msgstr "--remote-send <nøkler>\tSend <nøkler> til en Vim-tjener og avslutt"
+
+msgid "--remote-expr <expr>\tEvaluate <expr> in a Vim server and print result"
+msgstr ""
+"--remote-expr <uttrykk>\tEvaluer <uttrykk> på en Vim-tjener og skriv "
+"resultatet"
+
+msgid "--serverlist\t\tList available Vim server names and exit"
+msgstr "--serverlist\t\tList navn på tilgjengelige Vim-tjenere og avslutt"
+
+msgid "--servername <name>\tSend to/become the Vim server <name>"
+msgstr "--servername <navn>\tSend til/bli Vim-tjeneren <navn>"
+
+msgid "-i <viminfo>\t\tUse <viminfo> instead of .viminfo"
+msgstr "-i <viminfo>\t\tBruk <viminfo> istedenfor .viminfo"
+
+msgid "-h or --help\tPrint Help (this message) and exit"
+msgstr "-h eller --help\tSkriv hjelpen (denne teksten) og avslutt"
+
+msgid "--version\t\tPrint version information and exit"
+msgstr "--version\t\tSkriv versjonsinformasjon og avslutt"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (Motif version):\n"
+msgstr ""
+"\n"
+"Parametere gjenkjent av gvim (Motif-versjon):\n"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (neXtaw version):\n"
+msgstr ""
+"\n"
+"Parametere gjenkjent av gvim (neXtaw-versjon):\n"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (Athena version):\n"
+msgstr ""
+"\n"
+"Parametere gjenkjent av gvim (Athena-versjon):\n"
+
+msgid "-display <display>\tRun vim on <display>"
+msgstr "-display <display>\tKjør vim på <display>"
+
+msgid "-iconic\t\tStart vim iconified"
+msgstr "-iconic\t\tStart vim som ikon"
+
+msgid "-name <name>\t\tUse resource as if vim was <name>"
+msgstr "-name <navn>\t\tBruk ressurs som om Vim var <navn>"
+
+msgid "\t\t\t (Unimplemented)\n"
+msgstr "\t\t\t (Ikke implementert)\n"
+
+msgid "-background <color>\tUse <color> for the background (also: -bg)"
+msgstr "-background <farge>\tBruk <farge> på bakgrunnen (også: -bg)"
+
+msgid "-foreground <color>\tUse <color> for normal text (also: -fg)"
+msgstr "-foreground <farge>\tBruk <farge> på normal tekst (også: -fg)"
+
+msgid "-font <font>\t\tUse <font> for normal text (also: -fn)"
+msgstr "-font <skrifttype>\t\tBruk <skrifttype> på normal tekst (også: -fn)"
+
+msgid "-boldfont <font>\tUse <font> for bold text"
+msgstr "-boldfont <skrifttype>\tBruk <skrifttype> på fet skrift"
+
+msgid "-italicfont <font>\tUse <font> for italic text"
+msgstr "-italicfont <skrifttype>\tBruk <skrifttype> på skrå tekst"
+
+msgid "-geometry <geom>\tUse <geom> for initial geometry (also: -geom)"
+msgstr ""
+"-geometry <geom>\tBruk <geom> for innledende vindusplassering (også: -geom)"
+
+msgid "-borderwidth <width>\tUse a border width of <width> (also: -bw)"
+msgstr ""
+"-borderwidth <bredde>\tBruk en rammebredde tilsvarende <bredde> (også: -bw)"
+
+msgid "-scrollbarwidth <width> Use a scrollbar width of <width> (also: -sw)"
+msgstr ""
+"-scrollbarwidth <bredde> Bruk en rullefeltbredde tilsvarende <bredde> "
+"(også: -sw)"
+
+msgid "-menuheight <height>\tUse a menu bar height of <height> (also: -mh)"
+msgstr ""
+"-menuheight <høyde>\tBruk en menyblokkhøyde tilsvarende <høyde> (også: -mh)"
+
+msgid "-reverse\t\tUse reverse video (also: -rv)"
+msgstr "-reverse\t\tBruk invers video (også: -rv)"
+
+msgid "+reverse\t\tDon't use reverse video (also: +rv)"
+msgstr "+reverse\t\tIkke bruk invers video (også: +rv)"
+
+msgid "-xrm <resource>\tSet the specified resource"
+msgstr "-xrm <ressurs>\tSett den spesifiserte ressursen"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (RISC OS version):\n"
+msgstr ""
+"\n"
+"Parametere gjenkjent av gvim (RISC OS-versjon):\n"
+
+msgid "--columns <number>\tInitial width of window in columns"
+msgstr "--columns <antall>\tInnledende bredde på vindu i kolonner"
+
+msgid "--rows <number>\tInitial height of window in rows"
+msgstr "--rows <antall>\tInnledende høyde på vindu i rader"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (GTK+ version):\n"
+msgstr ""
+"\n"
+"Parametere gjenkjent av gvim (GTK+-versjon):\n"
+
+msgid "-display <display>\tRun vim on <display> (also: --display)"
+msgstr "-display <display>\tKjør vim på <display> (også: --display)"
+
+msgid "--role <role>\tSet a unique role to identify the main window"
+msgstr "--role <role>\tSett en unik \"role\" for å identifisere hovedvinduet"
+
+msgid "--socketid <xid>\tOpen Vim inside another GTK widget"
+msgstr "--socketid <xid>\tÅpne Vim innenfor et annet GTK-skjermelement"
+
+msgid "-P <parent title>\tOpen Vim inside parent application"
+msgstr "-P <foreldretittel>\tStart Vim innenfor et foreldreprogram"
+
+msgid "No display"
+msgstr "Ingen display"
+
+#. Failed to send, abort.
+msgid ": Send failed.\n"
+msgstr ": Send feilet.\n"
+
+#. Let vim start normally.
+msgid ": Send failed. Trying to execute locally\n"
+msgstr ": Send feilet. Prøver å utføre lokalt\n"
+
+#, c-format
+msgid "%d of %d edited"
+msgstr "%d av %d redigert"
+
+msgid "No display: Send expression failed.\n"
+msgstr "Ingen display: Sending av uttrykk feilet.\n"
+
+msgid ": Send expression failed.\n"
+msgstr ": Sending av uttrykk feilet.\n"
+
+msgid "No marks set"
+msgstr "Ingen merker satt"
+
+#, c-format
+msgid "E283: No marks matching \"%s\""
+msgstr "E283: Ingen merker samsvarer med \"%s\""
+
+#. Highlight title
+msgid ""
+"\n"
+"mark line col file/text"
+msgstr ""
+"\n"
+"merk linje kol fil/tekst"
+
+#. Highlight title
+msgid ""
+"\n"
+" jump line col file/text"
+msgstr ""
+"\n"
+" hopp linje kol fil/tekst"
+
+#. Highlight title
+msgid ""
+"\n"
+"change line col text"
+msgstr ""
+"\n"
+"forand linje kol tekst"
+
+#, c-format
+msgid ""
+"\n"
+"# File marks:\n"
+msgstr ""
+"\n"
+"# Filmerker:\n"
+
+#. Write the jumplist with -'
+#, c-format
+msgid ""
+"\n"
+"# Jumplist (newest first):\n"
+msgstr ""
+"\n"
+"# Hoppliste (nyeste først):\n"
+
+#, c-format
+msgid ""
+"\n"
+"# History of marks within files (newest to oldest):\n"
+msgstr ""
+"\n"
+"# Historie for merker inne i filer (yngst til eldst):\n"
+
+msgid "Missing '>'"
+msgstr "Mangler '>'"
+
+msgid "E543: Not a valid codepage"
+msgstr "E543: Er ikke en gyldig codepage"
+
+msgid "E284: Cannot set IC values"
+msgstr "E284: Kan ikke sette IC-verdier (\"Input Context\")"
+
+msgid "E285: Failed to create input context"
+msgstr "E285: Klarte ikke opprette inndatakontekst"
+
+msgid "E286: Failed to open input method"
+msgstr "E286: Klarte ikke åpne inndatametode"
+
+msgid "E287: Warning: Could not set destroy callback to IM"
+msgstr ""
+"E287: Advarsel: Klarte ikke sette \"destroy callback\" til inndatametode"
+
+msgid "E288: input method doesn't support any style"
+msgstr "E288: Inndatametode støtter ikke enhver stil"
+
+msgid "E289: input method doesn't support my preedit type"
+msgstr "E289: Inndatametode støtter ikke min \"preedit\" type"
+
+msgid "E290: over-the-spot style requires fontset"
+msgstr "E290: \"over-the-spot\"-stil trenger et skrifttypesett"
+
+msgid "E291: Your GTK+ is older than 1.2.3. Status area disabled"
+msgstr "E291: Din GTK+ er eldre enn 1.2.3. Statusområde deaktivert"
+
+msgid "E292: Input Method Server is not running"
+msgstr "E292: Inndatametodetjener kjører ikke"
+
+msgid "E293: block was not locked"
+msgstr "E293: Blokken var ikke låst"
+
+msgid "E294: Seek error in swap file read"
+msgstr "E294: Søkefeil i lesing av swapfil"
+
+msgid "E295: Read error in swap file"
+msgstr "E295: Lesefeil i swapfil"
+
+msgid "E296: Seek error in swap file write"
+msgstr "E296: Søkefeil i skriving til swapfil"
+
+msgid "E297: Write error in swap file"
+msgstr "E297: Skrivefeil i swapfil"
+
+msgid "E300: Swap file already exists (symlink attack?)"
+msgstr "E300: Swapfilen finnes allerede (symlenke-angrep?)"
+
+msgid "E298: Didn't get block nr 0?"
+msgstr "E298: Hentet ikke blokk nummer 0?"
+
+msgid "E298: Didn't get block nr 1?"
+msgstr "E298: Hentet ikke blokk nummer 1?"
+
+msgid "E298: Didn't get block nr 2?"
+msgstr "E298: Hentet ikke blokk nummer 2?"
+
+#. could not (re)open the swap file, what can we do????
+msgid "E301: Oops, lost the swap file!!!"
+msgstr "E301: Opps, mistet swapfilen!!!"
+
+msgid "E302: Could not rename swap file"
+msgstr "E302: Klarte ikke skifte navn på swapfil"
+
+#, c-format
+msgid "E303: Unable to open swap file for \"%s\", recovery impossible"
+msgstr "E303: Klarte ikke åpne swapfil for \"%s\", gjenoppretting umulig"
+
+msgid "E304: ml_upd_block0(): Didn't get block 0??"
+msgstr "E304: ml_upd_block0(): Hentet ikke blokk 0??"
+
+#, c-format
+msgid "E305: No swap file found for %s"
+msgstr "E305: Ingen swapfil funnet for %s"
+
+msgid "Enter number of swap file to use (0 to quit): "
+msgstr "Skriv nummeret på swapfil som skal brukes (0 for å avslutte): "
+
+#, c-format
+msgid "E306: Cannot open %s"
+msgstr "E306: Kan ikke åpne %s"
+
+msgid "Unable to read block 0 from "
+msgstr "Klarte ikke lese blokk 0 fra "
+
+msgid ""
+"\n"
+"Maybe no changes were made or Vim did not update the swap file."
+msgstr ""
+"\n"
+"Det er mulig ingen forandringer ble gjort, eller Vim oppdaterte ikke "
+"swapfilen."
+
+msgid " cannot be used with this version of Vim.\n"
+msgstr " kan ikke brukes med denne Vim-versjonen.\n"
+
+msgid "Use Vim version 3.0.\n"
+msgstr "Bruk Vim versjon 3.0.\n"
+
+#, c-format
+msgid "E307: %s does not look like a Vim swap file"
+msgstr "E307: %s ser ikke ut som en Vim-swapfil"
+
+msgid " cannot be used on this computer.\n"
+msgstr " kan ikke brukes på denne maskinen.\n"
+
+msgid "The file was created on "
+msgstr "Filen ble laget på "
+
+msgid ""
+",\n"
+"or the file has been damaged."
+msgstr ""
+",\n"
+"eller filen er blitt ødelagt."
+
+#, c-format
+msgid "Using swap file \"%s\""
+msgstr "Bruker swapfilen \"%s\""
+
+#, c-format
+msgid "Original file \"%s\""
+msgstr "Originalfil \"%s\""
+
+msgid "E308: Warning: Original file may have been changed"
+msgstr "E308: Advarsel: Originalfilen kan ha blitt forandret"
+
+#, c-format
+msgid "E309: Unable to read block 1 from %s"
+msgstr "E309: Klarte ikke lese blokk 1 fra %s"
+
+msgid "???MANY LINES MISSING"
+msgstr "???MANGE LINJER MANGLER"
+
+msgid "???LINE COUNT WRONG"
+msgstr "???FEIL LINJEANTALL"
+
+msgid "???EMPTY BLOCK"
+msgstr "???TOM BLOKK"
+
+msgid "???LINES MISSING"
+msgstr "???LINJER MANGLER"
+
+#, c-format
+msgid "E310: Block 1 ID wrong (%s not a .swp file?)"
+msgstr "E310: ID til blokk 1 er feil (%s ikke en \".swp\"-fil?)"
+
+msgid "???BLOCK MISSING"
+msgstr "???BLOKK MANGLER"
+
+msgid "??? from here until ???END lines may be messed up"
+msgstr "??? Herfra til ???SLUTT kan linjer være rotet til"
+
+msgid "??? from here until ???END lines may have been inserted/deleted"
+msgstr "??? Herfra til ???SLUTT kan linjer ha blitt lagt til eller slettet"
+
+msgid "???END"
+msgstr "???SLUTT"
+
+msgid "E311: Recovery Interrupted"
+msgstr "E311: Gjenoppretting avbrutt"
+
+msgid ""
+"E312: Errors detected while recovering; look for lines starting with ???"
+msgstr ""
+"E312: Feil oppdaget under gjenoppretting; se etter linjer som starter med ???"
+
+msgid "See \":help E312\" for more information."
+msgstr "Se \":help E312\" for mer informasjon."
+
+msgid "Recovery completed. You should check if everything is OK."
+msgstr "Gjenoppretting komplett. Du bør sjekke at alt er i orden."
+
+msgid ""
+"\n"
+"(You might want to write out this file under another name\n"
+msgstr ""
+"\n"
+"(Du vil kanskje lagre denne filen under et annet navn\n"
+
+msgid "and run diff with the original file to check for changes)\n"
+msgstr "og sammenligne den mot den originale filen for å finne forandringer)\n"
+
+msgid ""
+"Delete the .swp file afterwards.\n"
+"\n"
+msgstr ""
+"Slett \".swp\"-filen etterpå.\n"
+"\n"
+
+#. use msg() to start the scrolling properly
+msgid "Swap files found:"
+msgstr "Swapfiler funnet:"
+
+msgid " In current directory:\n"
+msgstr " I nåværende katalog:\n"
+
+msgid " Using specified name:\n"
+msgstr " Bruker spesifisert navn:\n"
+
+msgid " In directory "
+msgstr " I katalog "
+
+msgid " -- none --\n"
+msgstr " -- ingen --\n"
+
+msgid " owned by: "
+msgstr " eies av: "
+
+msgid " dated: "
+msgstr " datert: "
+
+msgid " dated: "
+msgstr " datert: "
+
+msgid " [from Vim version 3.0]"
+msgstr " [fra Vim versjon 3.0]"
+
+msgid " [does not look like a Vim swap file]"
+msgstr " [ser ikke ut som en Vim-swapfil]"
+
+msgid " file name: "
+msgstr " filnavn: "
+
+msgid ""
+"\n"
+" modified: "
+msgstr ""
+"\n"
+" modifisert: "
+
+msgid "YES"
+msgstr "JA"
+
+msgid "no"
+msgstr "nei"
+
+msgid ""
+"\n"
+" user name: "
+msgstr ""
+"\n"
+" brukernavn: "
+
+msgid " host name: "
+msgstr " vertsnavn: "
+
+msgid ""
+"\n"
+" host name: "
+msgstr ""
+"\n"
+" vertsnavn: "
+
+msgid ""
+"\n"
+" process ID: "
+msgstr ""
+"\n"
+" prosess-ID: "
+
+msgid " (still running)"
+msgstr " (kjører fortsatt)"
+
+msgid ""
+"\n"
+" [not usable with this version of Vim]"
+msgstr ""
+"\n"
+" [ikke brukbar med denne Vim-versjonen]"
+
+msgid ""
+"\n"
+" [not usable on this computer]"
+msgstr ""
+"\n"
+" [ikke brukbar på denne maskinen]"
+
+msgid " [cannot be read]"
+msgstr " [kan ikke leses]"
+
+msgid " [cannot be opened]"
+msgstr " [kan ikke åpnes]"
+
+msgid "E313: Cannot preserve, there is no swap file"
+msgstr "E313: Kan ikke bevare, swapfil mangler"
+
+msgid "File preserved"
+msgstr "Fil bevart"
+
+msgid "E314: Preserve failed"
+msgstr "E314: Bevaring feilet"
+
+#, 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 finne linje %ld"
+
+msgid "E317: pointer block id wrong 3"
+msgstr "E317: Pekerblokk-id feil 3"
+
+msgid "stack_idx should be 0"
+msgstr "stack_idx skulle være 0"
+
+msgid "E318: Updated too many blocks?"
+msgstr "E318: Oppdaterte for mange blokker?"
+
+msgid "E317: pointer block id wrong 4"
+msgstr "E317: Pekerblokk-id feil 4"
+
+msgid "deleted block 1?"
+msgstr "slettet blokk 1?"
+
+#, c-format
+msgid "E320: Cannot find line %ld"
+msgstr "E320: Kan ikke finne linje %ld"
+
+msgid "E317: pointer block id wrong"
+msgstr "E317: Pekerblokk-id feil"
+
+msgid "pe_line_count is zero"
+msgstr "pe_line_count er null"
+
+#, c-format
+msgid "E322: line number out of range: %ld past the end"
+msgstr "E322: Linjenummer utenfor område: %ld forbi slutten"
+
+#, c-format
+msgid "E323: line count wrong in block %ld"
+msgstr "E323: Linjeantall feil i blokk %ld"
+
+msgid "Stack size increases"
+msgstr "Stackstørrelse øker"
+
+msgid "E317: pointer block id wrong 2"
+msgstr "E317: Pekerblokk-id feil 2"
+
+#, c-format
+msgid "E773: Symlink loop for \"%s\""
+msgstr "E773: Symlenkesløyfe for \"%s\""
+
+msgid "E325: ATTENTION"
+msgstr "E325: VIKTIG"
+
+msgid ""
+"\n"
+"Found a swap file by the name \""
+msgstr ""
+"\n"
+"Fant en swapfil ved navn \""
+
+msgid "While opening file \""
+msgstr "Under åpning av filen \""
+
+msgid " NEWER than swap file!\n"
+msgstr " NYERE enn swapfil!\n"
+
+#. Some of these messages are long to allow translation to
+#. * other languages.
+msgid ""
+"\n"
+"(1) Another program may be editing the same file.\n"
+" If this is the case, be careful not to end up with two\n"
+" different instances of the same file when making changes.\n"
+msgstr ""
+"\n"
+"(1) Det er mulig et annet program redigerer den samme filen.\n"
+" Hvis det er tilfelle, vær forsiktig så du ikke ender opp med to\n"
+" forskjellige utgaver av den samme filen når du gjør forandringer.\n"
+
+msgid " Quit, or continue with caution.\n"
+msgstr " Avslutt, eller fortsett med varsomhet.\n"
+
+msgid ""
+"\n"
+"(2) An edit session for this file crashed.\n"
+msgstr ""
+"\n"
+"(2) En økt for denne filen kræsjet.\n"
+
+msgid " If this is the case, use \":recover\" or \"vim -r "
+msgstr " Hvis det er tilfelle, bruk \":recover\" eller \"vim -r "
+
+msgid ""
+"\"\n"
+" to recover the changes (see \":help recovery\").\n"
+msgstr ""
+"\"\n"
+" for å gjenopprette forandringene (se \":help recovery\").\n"
+
+msgid " If you did this already, delete the swap file \""
+msgstr " Hvis du har gjort dette allerede, slett swapfilen \""
+
+msgid ""
+"\"\n"
+" to avoid this message.\n"
+msgstr ""
+"\"\n"
+" for å unngå denne meldingen.\n"
+
+msgid "Swap file \""
+msgstr "Swapfilen \""
+
+msgid "\" already exists!"
+msgstr "\" finnes allerede!"
+
+msgid "VIM - ATTENTION"
+msgstr "VIM - VIKTIG"
+
+msgid "Swap file already exists!"
+msgstr "Swapfilen eksisterer allerede!"
+
+msgid ""
+"&Open Read-Only\n"
+"&Edit anyway\n"
+"&Recover\n"
+"&Quit\n"
+"&Abort"
+msgstr ""
+"&Åpne skrivebeskyttet\n"
+"&Rediger likevel\n"
+"&Gjenopprett\n"
+"&Avslutt\n"
+"Av&bryt"
+
+msgid ""
+"&Open Read-Only\n"
+"&Edit anyway\n"
+"&Recover\n"
+"&Delete it\n"
+"&Quit\n"
+"&Abort"
+msgstr ""
+"&Åpne skrivebeskyttet\n"
+"&Rediger likevel\n"
+"&Gjenopprett\n"
+"&Slett den\n"
+"&Avslutt\n"
+"Av&bryt"
+
+msgid "E326: Too many swap files found"
+msgstr "E326: For mange swapfiler funnet"
+
+msgid "E327: Part of menu-item path is not sub-menu"
+msgstr "E327: Del av menyelement er ikke undermeny"
+
+msgid "E328: Menu only exists in another mode"
+msgstr "E328: Menyen eksisterer bare i en annen modus"
+
+#, c-format
+msgid "E329: No menu \"%s\""
+msgstr "E329: Ingen \"%s\"-meny"
+
+#. Only a mnemonic or accelerator is not valid.
+msgid "E792: Empty menu name"
+msgstr "E792: Tomt menynavn"
+
+msgid "E330: Menu path must not lead to a sub-menu"
+msgstr "E330: Menysti kan ikke lede til en undermeny"
+
+msgid "E331: Must not add menu items directly to menu bar"
+msgstr "E331: Kan ikke legge til menyelementer direkte på menylinjen"
+
+msgid "E332: Separator cannot be part of a menu path"
+msgstr "E332: Skilletegn kan ikke være del av en menysti"
+
+#. Now we have found the matching menu, and we list the mappings
+#. Highlight title
+msgid ""
+"\n"
+"--- Menus ---"
+msgstr ""
+"\n"
+"--- Menyer ---"
+
+msgid "Tear off this menu"
+msgstr "Riv av denne menyen"
+
+msgid "E333: Menu path must lead to a menu item"
+msgstr "E333: Menystien må lede til et menyvalg"
+
+#, c-format
+msgid "E334: Menu not found: %s"
+msgstr "E334: Fant ikke menyen: %s"
+
+#, c-format
+msgid "E335: Menu not defined for %s mode"
+msgstr "E335: Menyen er ikke definert for %s-modus"
+
+msgid "E336: Menu path must lead to a sub-menu"
+msgstr "E336: Menystien må lede til en undermeny"
+
+msgid "E337: Menu not found - check menu names"
+msgstr "E337: Fant ikke menyen - sjekk menynavnet"
+
+#, c-format
+msgid "Error detected while processing %s:"
+msgstr "Feil oppdaget under prosessering av %s:"
+
+#, c-format
+msgid "line %4ld:"
+msgstr "linje %4ld:"
+
+#, c-format
+msgid "E354: Invalid register name: '%s'"
+msgstr "E354: Ugyldig registernavn: '%s'"
+
+msgid "Messages maintainer: Bram Moolenaar <Bram@vim.org>"
+msgstr ""
+"Vedlikeholder for norsk oversettelse: Øyvind A. Holm <sunny@sunbase.org>"
+
+msgid "Interrupt: "
+msgstr "Avbryt: "
+
+msgid "Press ENTER or type command to continue"
+msgstr "Trykk ENTER eller skriv kommando for å fortsette"
+
+#, c-format
+msgid "%s line %ld"
+msgstr "%s linje %ld"
+
+msgid "-- More --"
+msgstr "-- Mer --"
+
+msgid " SPACE/d/j: screen/page/line down, b/u/k: up, q: quit "
+msgstr " MELLOMROM/d/j: Skjerm/side/linje ned, b/u/k: Opp, q: Avslutt "
+
+msgid "Question"
+msgstr "Spørsmål"
+
+msgid ""
+"&Yes\n"
+"&No"
+msgstr ""
+"&Ja\n"
+"&Nei"
+
+msgid ""
+"&Yes\n"
+"&No\n"
+"Save &All\n"
+"&Discard All\n"
+"&Cancel"
+msgstr ""
+"&Ja\n"
+"&Nei\n"
+"&Lagre alle\n"
+"&Forkast alle\n"
+"&Avbryt"
+
+msgid "Select Directory dialog"
+msgstr "\"Velge katalog\"-dialogvindu"
+
+msgid "Save File dialog"
+msgstr "\"Lagre fil\"-dialogvindu"
+
+msgid "Open File dialog"
+msgstr "\"Åpne fil\"-dialogvindu"
+
+#. TODO: non-GUI file selector here
+msgid "E338: Sorry, no file browser in console mode"
+msgstr "E338: Dessverre ingen filbehandler i konsollmodus"
+
+msgid "E766: Insufficient arguments for printf()"
+msgstr "E766: Ikke nok parametre for printf()"
+
+msgid "E767: Too many arguments to printf()"
+msgstr "E767: For mange parametere for printf()"
+
+msgid "W10: Warning: Changing a readonly file"
+msgstr "W10: Advarsel: Forandrer en skrivebeskyttet fil"
+
+msgid "Type number or click with mouse (<Enter> cancels): "
+msgstr "Skriv nummer eller velg med musen (<Enter> avbryter)"
+
+msgid "Choice number (<Enter> cancels): "
+msgstr "Valgnummer (<Enter> avbryter)"
+
+msgid "1 more line"
+msgstr "1 linje lagt til"
+
+msgid "1 line less"
+msgstr "1 linje fjernet"
+
+#, c-format
+msgid "%ld more lines"
+msgstr "%ld linjer lagt til"
+
+#, c-format
+msgid "%ld fewer lines"
+msgstr "%ld linjer fjernet"
+
+msgid " (Interrupted)"
+msgstr " (Avbrutt)"
+
+msgid "Beep!"
+msgstr "Pip!"
+
+msgid "Vim: preserving files...\n"
+msgstr "Vim: Bevarer filer ...\n"
+
+#. close all memfiles, without deleting
+msgid "Vim: Finished.\n"
+msgstr "Vim: Ferdig.\n"
+
+#, c-format
+msgid "ERROR: "
+msgstr "FEIL: "
+
+#, c-format
+msgid ""
+"\n"
+"[bytes] total alloc-freed %lu-%lu, in use %lu, peak use %lu\n"
+msgstr ""
+"\n"
+"[bytes] totalt alloc-frigjort %lu-%lu, i bruk %lu, topp-bruk %lu\n"
+
+#, c-format
+msgid ""
+"[calls] total re/malloc()'s %lu, total free()'s %lu\n"
+"\n"
+msgstr ""
+"[kall] totale \"re/malloc()\"-er %lu, totale \"free()\"-er %lu\n"
+"\n"
+
+msgid "E340: Line is becoming too long"
+msgstr "E340: Linjen blir for lang"
+
+#, c-format
+msgid "E341: Internal error: lalloc(%ld, )"
+msgstr "E341: Intern feil: lalloc(%ld, )"
+
+#, c-format
+msgid "E342: Out of memory! (allocating %lu bytes)"
+msgstr "E342: Ikke mer ledig hukommelse! (Reserverer %lu bytes)"
+
+#, c-format
+msgid "Calling shell to execute: \"%s\""
+msgstr "Kaller skall for å utføre \"%s\""
+
+msgid "E545: Missing colon"
+msgstr "E545: Mangler kolon"
+
+msgid "E546: Illegal mode"
+msgstr "E546: Ulovlig modus"
+
+msgid "E547: Illegal mouseshape"
+msgstr "E547: Ulovlig utseende på musepekeren"
+
+msgid "E548: digit expected"
+msgstr "E548: Siffer forventet"
+
+msgid "E549: Illegal percentage"
+msgstr "E549: Ulovlig prosent"
+
+msgid "Enter encryption key: "
+msgstr "Skriv krypteringsnøkkel: "
+
+msgid "Enter same key again: "
+msgstr "Gjenta krypteringsnøkkelen: "
+
+msgid "Keys don't match!"
+msgstr "Krypteringsnøklene stemmer ikke overens!"
+
+#, 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]' må være på slutten av stien eller bli "
+"etterfulgt av '%s'."
+
+#, c-format
+msgid "E344: Can't find directory \"%s\" in cdpath"
+msgstr "E344: Kan ikke finne katalogen \"%s\" i \"cdpath\""
+
+#, c-format
+msgid "E345: Can't find file \"%s\" in path"
+msgstr "E345: Kan ikke finne filen \"%s\" i stien"
+
+#, c-format
+msgid "E346: No more directory \"%s\" found in cdpath"
+msgstr "E346: Ingen flere katalog-\"%s\" funnet i \"cdpath\""
+
+#, c-format
+msgid "E347: No more file \"%s\" found in path"
+msgstr "E347: Ingen flere fil-\"%s\" funnet i stien"
+
+#. Get here when the server can't be found.
+msgid "Cannot connect to Netbeans #2"
+msgstr "Kan ikke koble til Netbeans #2"
+
+msgid "Cannot connect to Netbeans"
+msgstr "Kan ikke koble til Netbeans"
+
+#, c-format
+msgid "E668: Wrong access mode for NetBeans connection info file: \"%s\""
+msgstr ""
+"E668: Feil tilgangsmodus for infofilen til NetBeans-forbindelse: \"%s\""
+
+msgid "read from Netbeans socket"
+msgstr "les fra Netbeans-socket"
+
+#, c-format
+msgid "E658: NetBeans connection lost for buffer %ld"
+msgstr "E658: Mistet NetBeans-forbindelse for buffer %ld"
+
+msgid "E505: "
+msgstr "E505: "
+
+msgid "E774: 'operatorfunc' is empty"
+msgstr "E774: 'operatorfunc' er tomt"
+
+msgid "E775: Eval feature not available"
+msgstr "E775: Eval-funksjonaliteten er ikke tilgjengelig"
+
+msgid "Warning: terminal cannot highlight"
+msgstr "Advarsel: Terminalen kan ikke utheve"
+
+msgid "E348: No string under cursor"
+msgstr "E348: Ingen streng under markør"
+
+msgid "E349: No identifier under cursor"
+msgstr "E349: Ingen identifikator under markør"
+
+msgid "E352: Cannot erase folds with current 'foldmethod'"
+msgstr "E352: Kan ikke slette folder med nåværende 'foldmethod'"
+
+msgid "E664: changelist is empty"
+msgstr "E664: Forandringslisten er tom"
+
+msgid "E662: At start of changelist"
+msgstr "E662: Ved starten av forandringsliste"
+
+msgid "E663: At end of changelist"
+msgstr "E663: Ved slutten av forandringsliste"
+
+msgid "Type :quit<Enter> to exit Vim"
+msgstr "Skriv :quit<Enter> for å avslutte Vim"
+
+#, c-format
+msgid "1 line %sed 1 time"
+msgstr "1 linje \"%s\"-et 1 gang"
+
+#, c-format
+msgid "1 line %sed %d times"
+msgstr "1 linje \"%s\"-et %d ganger"
+
+#, c-format
+msgid "%ld lines %sed 1 time"
+msgstr "%ld linjer \"%s\"-et 1 gang"
+
+#, c-format
+msgid "%ld lines %sed %d times"
+msgstr "%ld linjer \"%s\"-et %d ganger"
+
+#, c-format
+msgid "%ld lines to indent... "
+msgstr "%ld linjer å rykke inn ... "
+
+msgid "1 line indented "
+msgstr "1 linje rykket inn "
+
+#, c-format
+msgid "%ld lines indented "
+msgstr "%ld linjer rykket inn "
+
+msgid "E748: No previously used register"
+msgstr "E748: Register ikke tidligere brukt"
+
+#. must display the prompt
+msgid "cannot yank; delete anyway"
+msgstr "kan ikke kopiere til utklippstavle; slett likevel"
+
+msgid "1 line changed"
+msgstr "1 linje forandret"
+
+#, c-format
+msgid "%ld lines changed"
+msgstr "%ld linjer forandret"
+
+#, c-format
+msgid "freeing %ld lines"
+msgstr "frigjør %ld linjer"
+
+msgid "block of 1 line yanked"
+msgstr "blokk med 1 linje kopiert til utklippstavlen"
+
+msgid "1 line yanked"
+msgstr "1 linje kopiert til utklippstavlen"
+
+#, c-format
+msgid "block of %ld lines yanked"
+msgstr "blokk med %ld linjer kopiert til utklippstavlen"
+
+#, c-format
+msgid "%ld lines yanked"
+msgstr "%ld linjer kopiert til utklippstavlen"
+
+#, c-format
+msgid "E353: Nothing in register %s"
+msgstr "E353: Ingenting i register %s"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Registers ---"
+msgstr ""
+"\n"
+"--- Registere ---"
+
+msgid "Illegal register name"
+msgstr "Ulovlig registernavn"
+
+#, c-format
+msgid ""
+"\n"
+"# Registers:\n"
+msgstr ""
+"\n"
+"# Registere:\n"
+
+#, c-format
+msgid "E574: Unknown register type %d"
+msgstr "E574: Ukjent registertype %d"
+
+#, c-format
+msgid "%ld Cols; "
+msgstr "%ld Kol; "
+
+#, c-format
+msgid "Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Bytes"
+msgstr "Valgte %s%ld av %ld linjer; %ld av %ld ord; %ld av %ld bytes"
+
+#, c-format
+msgid ""
+"Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Chars; %ld of %ld "
+"Bytes"
+msgstr ""
+"Valgte %s%ld av %ld linjer; %ld av %ld ord; %ld av %ld tegn; %ld av %ld bytes"
+
+#, c-format
+msgid "Col %s of %s; Line %ld of %ld; Word %ld of %ld; Byte %ld of %ld"
+msgstr "Kol %s av %s; Linje %ld av %ld; Ord %ld av %ld; Byte %ld av %ld"
+
+#, c-format
+msgid ""
+"Col %s of %s; Line %ld of %ld; Word %ld of %ld; Char %ld of %ld; Byte %ld of "
+"%ld"
+msgstr ""
+"Kol %s av %s; linje %ld av %ld; ord %ld av %ld; tegn %ld av %ld; byte %ld av "
+"%ld"
+
+#, c-format
+msgid "(+%ld for BOM)"
+msgstr "(+%ld for BOM)"
+
+msgid "%<%f%h%m%=Page %N"
+msgstr "%<%f%h%m%=Side %N"
+
+msgid "Thanks for flying Vim"
+msgstr "Takk for at du fløy Vim"
+
+msgid "E518: Unknown option"
+msgstr "E518: Ukjent valg"
+
+msgid "E519: Option not supported"
+msgstr "E519: Valget er ikke støttet"
+
+msgid "E520: Not allowed in a modeline"
+msgstr "E520: Ikke tillatt i moduslinje"
+
+msgid "E521: Number required after ="
+msgstr "E521: Nummer nødvendig etter ="
+
+msgid "E522: Not found in termcap"
+msgstr "E522: Ikke funnet i termcap"
+
+#, c-format
+msgid "E539: Illegal character <%s>"
+msgstr "E539: Ulovlig tegn <%s>"
+
+msgid "E529: Cannot set 'term' to empty string"
+msgstr "E529: Kan ikke sette 'term' til tom streng"
+
+msgid "E530: Cannot change term in GUI"
+msgstr "E530: Kan ikke forandre \"term\" i grafisk brukergrensesnitt"
+
+msgid "E531: Use \":gui\" to start the GUI"
+msgstr "E531: Bruk \":gui\" for å starte med grafisk brukergrensesnitt"
+
+msgid "E589: 'backupext' and 'patchmode' are equal"
+msgstr "E589: 'backupext' og 'patchmode' er like"
+
+msgid "E617: Cannot be changed in the GTK+ 2 GUI"
+msgstr "E617: Kan ikke forandres i GTK+ 2 GUI"
+
+msgid "E524: Missing colon"
+msgstr "E524: Mangler kolon"
+
+msgid "E525: Zero length string"
+msgstr "E525: Tom streng"
+
+#, c-format
+msgid "E526: Missing number after <%s>"
+msgstr "E526: Mangler nummer etter <%s>"
+
+msgid "E527: Missing comma"
+msgstr "E527: Mangler komma"
+
+msgid "E528: Must specify a ' value"
+msgstr "E528: Må spesifisere en \"'\"-verdi"
+
+msgid "E595: contains unprintable or wide character"
+msgstr "E595: Inneholder uskrivelige eller brede tegn"
+
+msgid "E596: Invalid font(s)"
+msgstr "E596: Ugyldig(e) skrifttype(r)"
+
+msgid "E597: can't select fontset"
+msgstr "E597: Kan ikke velge skrifttypesett"
+
+msgid "E598: Invalid fontset"
+msgstr "E598: Ugyldig skrifttypesett"
+
+msgid "E533: can't select wide font"
+msgstr "E533: Kan ikke velge bred skrifttype"
+
+msgid "E534: Invalid wide font"
+msgstr "E534: Ugyldig bred skrifttype"
+
+#, c-format
+msgid "E535: Illegal character after <%c>"
+msgstr "E535: Ulovlig tegn etter <%c>"
+
+msgid "E536: comma required"
+msgstr "E536: Komma nødvendig"
+
+#, c-format
+msgid "E537: 'commentstring' must be empty or contain %s"
+msgstr "E537: 'commentstring' må være tom eller inneholde %s"
+
+msgid "E538: No mouse support"
+msgstr "E538: Ingen støtte for mus"
+
+msgid "E540: Unclosed expression sequence"
+msgstr "E540: Uttrykkssekvens som ikke er lukket"
+
+msgid "E541: too many items"
+msgstr "E541: For mange elementer"
+
+msgid "E542: unbalanced groups"
+msgstr "E542: Ubalanserte grupper"
+
+msgid "E590: A preview window already exists"
+msgstr "E590: Det finnes allerede et forhåndsvisningsvindu"
+
+msgid "W17: Arabic requires UTF-8, do ':set encoding=utf-8'"
+msgstr "W17: Arabisk trenger UTF-8, utfør ':set encoding=utf-8'"
+
+#, c-format
+msgid "E593: Need at least %d lines"
+msgstr "E593: Trenger minst %d linjer"
+
+#, c-format
+msgid "E594: Need at least %d columns"
+msgstr "E594: Trenger minst %d kolonner"
+
+#, c-format
+msgid "E355: Unknown option: %s"
+msgstr "E355: Ukjent valg: %s"
+
+msgid ""
+"\n"
+"--- Terminal codes ---"
+msgstr ""
+"\n"
+"--- Terminalkoder ---"
+
+msgid ""
+"\n"
+"--- Global option values ---"
+msgstr ""
+"\n"
+"--- Globale valgverdier ---"
+
+msgid ""
+"\n"
+"--- Local option values ---"
+msgstr ""
+"\n"
+"--- Lokale valgverdier ---"
+
+msgid ""
+"\n"
+"--- Options ---"
+msgstr ""
+"\n"
+"--- Valg ---"
+
+msgid "E356: get_varp ERROR"
+msgstr "E356: \"get_varp\"-FEIL"
+
+#, c-format
+msgid "E357: 'langmap': Matching character missing for %s"
+msgstr "E357: 'langmap': Samsvarende tegn mangler for %s"
+
+#, c-format
+msgid "E358: 'langmap': Extra characters after semicolon: %s"
+msgstr "E358: 'langmap': Ekstra tegn etter semikolon: %s"
+
+msgid "cannot open "
+msgstr "kan ikke åpne "
+
+msgid "VIM: Can't open window!\n"
+msgstr "VIM: Kan ikke åpne vindu!\n"
+
+msgid "Need Amigados version 2.04 or later\n"
+msgstr "Trenger Amigados versjon 2.04 eller nyere\n"
+
+#, c-format
+msgid "Need %s version %ld\n"
+msgstr "Trenger %s versjon %ld\n"
+
+msgid "Cannot open NIL:\n"
+msgstr "Kan ikke åpne NIL:\n"
+
+msgid "Cannot create "
+msgstr "Kan ikke opprette "
+
+#, c-format
+msgid "Vim exiting with %d\n"
+msgstr "Vim avslutter med %d\n"
+
+msgid "cannot change console mode ?!\n"
+msgstr "kan ikke forandre konsollmodus ?!\n"
+
+msgid "mch_get_shellsize: not a console??\n"
+msgstr "mch_get_shellsize: Ikke et konsoll??\n"
+
+#. if Vim opened a window: Executing a shell may cause crashes
+msgid "E360: Cannot execute shell with -f option"
+msgstr "E360: Kan ikke kjøre skall med \"-f\"-valg"
+
+msgid "Cannot execute "
+msgstr "Kan ikke utføre "
+
+msgid "shell "
+msgstr "skall "
+
+msgid " returned\n"
+msgstr " returnerte\n"
+
+msgid "ANCHOR_BUF_SIZE too small."
+msgstr "ANCHOR_BUF_SIZE for liten."
+
+msgid "I/O ERROR"
+msgstr "I/U-FEIL"
+
+msgid "Message"
+msgstr "Melding"
+
+msgid "'columns' is not 80, cannot execute external commands"
+msgstr "'columns' er ikke 80, kan ikke utføre eksterne kommandoer"
+
+msgid "E237: Printer selection failed"
+msgstr "E237: Valg av skriver feilet"
+
+#, c-format
+msgid "to %s on %s"
+msgstr "til %s på %s"
+
+#, c-format
+msgid "E613: Unknown printer font: %s"
+msgstr "E613: Ukjent skrifttype for skriver: %s"
+
+#, c-format
+msgid "E238: Print error: %s"
+msgstr "E238: Feil under utskrift: %s"
+
+#, c-format
+msgid "Printing '%s'"
+msgstr "Skriver ut '%s'"
+
+#, c-format
+msgid "E244: Illegal charset name \"%s\" in font name \"%s\""
+msgstr "E244: Ulovlig navn på tegnsett \"%s\" i skrifttypenavn \"%s\""
+
+#, c-format
+msgid "E245: Illegal char '%c' in font name \"%s\""
+msgstr "E245: Ulovlig tegn '%c' i skrifttypenavn \"%s\""
+
+msgid "Vim: Double signal, exiting\n"
+msgstr "Vim: Dobbelt signal, avslutter\n"
+
+#, c-format
+msgid "Vim: Caught deadly signal %s\n"
+msgstr "Vim: Mottok dødelig signal %s\n"
+
+#, c-format
+msgid "Vim: Caught deadly signal\n"
+msgstr "Vim: Mottok dødelig signal\n"
+
+#, c-format
+msgid "Opening the X display took %ld msec"
+msgstr "Åpning av X-display tok %ld millisekunder"
+
+msgid ""
+"\n"
+"Vim: Got X error\n"
+msgstr ""
+"\n"
+"Vim: Mottok X-feil\n"
+
+msgid "Testing the X display failed"
+msgstr "Test av X-display feilet"
+
+msgid "Opening the X display timed out"
+msgstr "Tidsavbrudd for åpning av X-display"
+
+msgid ""
+"\n"
+"Cannot execute shell "
+msgstr ""
+"\n"
+"Kan ikke kjøre skall "
+
+msgid ""
+"\n"
+"Cannot execute shell sh\n"
+msgstr ""
+"\n"
+"Kan ikke kjøre skallet sh\n"
+
+msgid ""
+"\n"
+"shell returned "
+msgstr ""
+"\n"
+"skallet returnerte "
+
+msgid ""
+"\n"
+"Cannot create pipes\n"
+msgstr ""
+"\n"
+"Kan ikke opprette rør (\"pipe\")\n"
+
+msgid ""
+"\n"
+"Cannot fork\n"
+msgstr ""
+"\n"
+"Kan ikke opprette tvillingprosess (\"fork\")\n"
+
+msgid ""
+"\n"
+"Command terminated\n"
+msgstr ""
+"\n"
+"Kommando avsluttet\n"
+
+msgid "XSMP lost ICE connection"
+msgstr "XSMP mistet ICE-forbindelsen"
+
+#, c-format
+msgid "dlerror = \"%s\""
+msgstr "dlerror = \"%s\""
+
+msgid "Opening the X display failed"
+msgstr "Åpning av X-display feilet"
+
+msgid "XSMP handling save-yourself request"
+msgstr "XSMP håndterer \"redd-deg-selv\"-forespørsel"
+
+msgid "XSMP opening connection"
+msgstr "XSMP åpner forbindelse"
+
+msgid "XSMP ICE connection watch failed"
+msgstr "Overvåkning av XSMP ICE-forbindelse feilet"
+
+#, c-format
+msgid "XSMP SmcOpenConnection failed: %s"
+msgstr "XSMP SmcOpenConnection feilet: %s"
+
+msgid "At line"
+msgstr "På linje"
+
+msgid "Could not load vim32.dll!"
+msgstr "Klarte ikke laste vim32.dll!"
+
+msgid "VIM Error"
+msgstr "VIM-feil"
+
+msgid "Could not fix up function pointers to the DLL!"
+msgstr "Klarte ikke ordne opp i funksjonspekere til DLL-en!"
+
+#, c-format
+msgid "shell returned %d"
+msgstr "skallet returnerte %d"
+
+#, c-format
+msgid "Vim: Caught %s event\n"
+msgstr "Vim: Mottok \"%s\"-hendelse\n"
+
+msgid "close"
+msgstr "lukk"
+
+msgid "logoff"
+msgstr "logg av"
+
+msgid "shutdown"
+msgstr "kjør ned"
+
+msgid "E371: Command not found"
+msgstr "E371: Kommando ikke funnet"
+
+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 funnet i $PATH.\n"
+"Eksterne kommandoer kommer ikke til å vente etter fullføring.\n"
+"Se \":help win32-vimrun\" for mer informasjon."
+
+msgid "Vim Warning"
+msgstr "Vim-advarsel"
+
+#, c-format
+msgid "E372: Too many %%%c in format string"
+msgstr "E372: For mange %%%c i formatstreng"
+
+#, c-format
+msgid "E373: Unexpected %%%c in format string"
+msgstr "E373: Uventet %%%c i formatstreng"
+
+msgid "E374: Missing ] in format string"
+msgstr "E374: Mangler ] i formatstreng"
+
+#, c-format
+msgid "E375: Unsupported %%%c in format string"
+msgstr "E375: %%%c ikke støttet i formatstreng"
+
+#, c-format
+msgid "E376: Invalid %%%c in format string prefix"
+msgstr "E376: Ugyldig %%%c i formatstreng-prefiks"
+
+#, c-format
+msgid "E377: Invalid %%%c in format string"
+msgstr "E377: Ugyldig %%%c i formatstreng"
+
+msgid "E378: 'errorformat' contains no pattern"
+msgstr "E378: 'errorformat' inneholder ikke søkestreng"
+
+msgid "E379: Missing or empty directory name"
+msgstr "E379: Manglende eller tomt katalognavn"
+
+msgid "E553: No more items"
+msgstr "E553: Ingen flere elementer"
+
+#, c-format
+msgid "(%d of %d)%s%s: "
+msgstr "(%d av %d)%s%s: "
+
+msgid " (line deleted)"
+msgstr " (linjen slettet)"
+
+msgid "E380: At bottom of quickfix stack"
+msgstr "E380: På bunnen av quickfix-stack"
+
+msgid "E381: At top of quickfix stack"
+msgstr "E381: På toppen av quickfix-stack"
+
+#, c-format
+msgid "error list %d of %d; %d errors"
+msgstr "feilliste %d av %d; %d feil"
+
+msgid "E382: Cannot write, 'buftype' option is set"
+msgstr "E382: Kan ikke lagre, 'buftype'-valget er satt"
+
+msgid "E683: File name missing or invalid pattern"
+msgstr "E683: Filnavn mangler eller ugyldig søkestreng"
+
+#, c-format
+msgid "Cannot open file \"%s\""
+msgstr "Kan ikke åpne filen \"%s\""
+
+msgid "E681: Buffer is not loaded"
+msgstr "E681: Bufferen er ikke lastet"
+
+msgid "E777: String or List expected"
+msgstr "E777: Streng eller liste forventet"
+
+#, c-format
+msgid "E369: invalid item in %s%%[]"
+msgstr "E369: Ugyldig element i %s%%[]"
+
+msgid "E339: Pattern too long"
+msgstr "E339: Søkestrengen er for lang"
+
+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: Usamsvarende \\z("
+
+#, c-format
+msgid "E53: Unmatched %s%%("
+msgstr "E53: Usamsvarende %s%%("
+
+#, c-format
+msgid "E54: Unmatched %s("
+msgstr "E54: Usamsvarende %s("
+
+#, c-format
+msgid "E55: Unmatched %s)"
+msgstr "E55: Usamsvarende %s)"
+
+#, c-format
+msgid "E59: invalid character after %s@"
+msgstr "E59: Ugyldig tegn etter %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: Nøstede %s*"
+
+#, c-format
+msgid "E62: Nested %s%c"
+msgstr "E62: Nøstede %s%c"
+
+msgid "E63: invalid use of \\_"
+msgstr "E63: Ugyldig bruk av \\_"
+
+#, c-format
+msgid "E64: %s%c follows nothing"
+msgstr "E64: %s%c etterfølger ingenting"
+
+msgid "E65: Illegal back reference"
+msgstr "E65: Ulovlig tilbakereferanse"
+
+msgid "E66: \\z( not allowed here"
+msgstr "E66: \\z( ikke tillatt her"
+
+msgid "E67: \\z1 et al. not allowed here"
+msgstr "E67: \\z1 med venner er ikke tillatt her"
+
+msgid "E68: Invalid character after \\z"
+msgstr "E68: Ugyldig tegn etter \\z"
+
+#, c-format
+msgid "E69: Missing ] after %s%%["
+msgstr "E69: Mangler ] etter %s%%["
+
+#, c-format
+msgid "E70: Empty %s%%[]"
+msgstr "E70: Tom %s%%[]"
+
+#, c-format
+msgid "E678: Invalid character after %s%%[dxouU]"
+msgstr "E678: Ugyldig tegn etter %s%%[dxouU]"
+
+#, c-format
+msgid "E71: Invalid character after %s%%"
+msgstr "E71: Ugyldig tegn etter %s%%"
+
+#, c-format
+msgid "E769: Missing ] after %s["
+msgstr "E769: Mangler ] etter %s["
+
+#, c-format
+msgid "E554: Syntax error in %s{...}"
+msgstr "E554: Syntaksfeil i %s{...}"
+
+msgid "External submatches:\n"
+msgstr "Eksterne deltreff:\n"
+
+msgid " VREPLACE"
+msgstr " V-ERSTATT"
+
+msgid " REPLACE"
+msgstr " ERSTATT"
+
+msgid " REVERSE"
+msgstr " OMVENDT"
+
+msgid " INSERT"
+msgstr " SETT INN"
+
+msgid " (insert)"
+msgstr " (sett inn)"
+
+msgid " (replace)"
+msgstr " (erstatt)"
+
+msgid " (vreplace)"
+msgstr " (v-erstatt)"
+
+msgid " Hebrew"
+msgstr " hebraisk"
+
+msgid " Arabic"
+msgstr " arabisk"
+
+msgid " (lang)"
+msgstr " (lang)"
+
+msgid " (paste)"
+msgstr " (lim inn)"
+
+msgid " VISUAL"
+msgstr " VISUELL"
+
+msgid " VISUAL LINE"
+msgstr " VISUELL LINJE"
+
+msgid " VISUAL BLOCK"
+msgstr " VISUELL BLOKK"
+
+msgid " SELECT"
+msgstr " VELG"
+
+msgid " SELECT LINE"
+msgstr " VELG LINJE"
+
+msgid " SELECT BLOCK"
+msgstr " VELG BLOKK"
+
+msgid "recording"
+msgstr "spiller inn"
+
+#, c-format
+msgid "E383: Invalid search string: %s"
+msgstr "E383: Ugyldig søkestreng: %s"
+
+#, c-format
+msgid "E384: search hit TOP without match for: %s"
+msgstr "E384: Søket kom til TOPPEN uten treff på: %s"
+
+#, c-format
+msgid "E385: search hit BOTTOM without match for: %s"
+msgstr "E385: Søket kom til BUNNEN uten treff på: %s"
+
+msgid "E386: Expected '?' or '/' after ';'"
+msgstr "E386: Forventet '?' eller '/' etter ';'"
+
+msgid " (includes previously listed match)"
+msgstr " (inkluderer tidligere utlistede treff)"
+
+#. cursor at status line
+msgid "--- Included files "
+msgstr "--- Inkluderte filer "
+
+msgid "not found "
+msgstr "ikke funnet "
+
+msgid "in path ---\n"
+msgstr "i sti ---\n"
+
+msgid " (Already listed)"
+msgstr " (Allerede listet)"
+
+msgid " NOT FOUND"
+msgstr " IKKE FUNNET"
+
+#, c-format
+msgid "Scanning included file: %s"
+msgstr "Leter gjennom inkludert fil: %s"
+
+#, c-format
+msgid "Searching included file %s"
+msgstr "Leter gjennom inkludert fil %s"
+
+msgid "E387: Match is on current line"
+msgstr "E387: Treffet er på nåværende linje"
+
+msgid "All included files were found"
+msgstr "Alle inkluderte filer ble funnet"
+
+msgid "No included files"
+msgstr "Ingen inkluderte filer"
+
+msgid "E388: Couldn't find definition"
+msgstr "E388: Fant ikke definisjonen"
+
+msgid "E389: Couldn't find pattern"
+msgstr "E389: Fant ikke søketeksten"
+
+#, c-format
+#~ msgid ""
+#~ "\n"
+#~ "# Last %sSearch Pattern:\n"
+#~ "~"
+#~ msgstr ""
+
+msgid "E759: Format error in spell file"
+msgstr "E759: Formateringsfeil i stavefil"
+
+msgid "E758: Truncated spell file"
+msgstr "E758: Valg av skriver feilet"
+
+#, c-format
+msgid "Trailing text in %s line %d: %s"
+msgstr "Etterfølgende tekst i %s linje %d: %s"
+
+#, c-format
+msgid "Affix name too long in %s line %d: %s"
+msgstr "Affiksnavn for langt i %s linje %d: %s"
+
+msgid "E761: Format error in affix file FOL, LOW or UPP"
+msgstr "E761: Formatfeil i affiksfil 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 utenfor område"
+
+msgid "Compressing word tree..."
+msgstr "Pakker ordtre ..."
+
+msgid "E756: Spell checking is not enabled"
+msgstr "E756: Stavekontroll er ikke aktivisert"
+
+#, c-format
+msgid "Warning: Cannot find word list \"%s.%s.spl\" or \"%s.ascii.spl\""
+msgstr "Advarsel: Kan ikke finne ordliste \"%s.%s.spl\" eller \"%s.ascii.spl\""
+
+#, c-format
+msgid "Reading spell file \"%s\""
+msgstr "Leser stavefil \"%s\""
+
+msgid "E757: This does not look like a spell file"
+msgstr "E757: Dette ser ikke ut som en stavefil"
+
+msgid "E771: Old spell file, needs to be updated"
+msgstr "E771: Gammel stavefil, trenger oppdatering"
+
+msgid "E772: Spell file is for newer version of Vim"
+msgstr "E772: Stavefilen er for en nyere versjon av Vim"
+
+msgid "E770: Unsupported section in spell file"
+msgstr "E770: Ustøttet seksjon i stavefil"
+
+#, c-format
+msgid "Warning: region %s not supported"
+msgstr "Advarsel: Region %s ikke støttet"
+
+#, c-format
+msgid "Reading affix file %s ..."
+msgstr "Leser affiksfil %s ..."
+
+#, c-format
+msgid "Conversion failure for word in %s line %d: %s"
+msgstr "Konverteringsfeil for ord i %s linje %d: %s"
+
+#, c-format
+msgid "Conversion in %s not supported: from %s to %s"
+msgstr "Konvertering i %s ikke støttet: Fra %s til %s"
+
+#, c-format
+msgid "Conversion in %s not supported"
+msgstr "Konvertering i %s ikke støttet"
+
+#, c-format
+msgid "Invalid value for FLAG in %s line %d: %s"
+msgstr "Ugyldig verdi for FLAG i %s linje %d: %s"
+
+#, c-format
+msgid "FLAG after using flags in %s line %d: %s"
+msgstr "FLAG etter bruk av flagg i %s linje %d: %s"
+
+#, c-format
+#~ msgid ""
+#~ "Defining COMPOUNDFORBIDFLAG after PFX item may give wrong results in %s line "
+#~ "%d"
+#~ msgstr ""
+
+#, c-format
+#~ msgid ""
+#~ "Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in %s line "
+#~ "%d"
+#~ msgstr ""
+
+#, c-format
+msgid "Wrong COMPOUNDWORDMAX value in %s line %d: %s"
+msgstr "Feil COMPOUNDWORDMAX-verdi i %s linje %d: %s"
+
+#, c-format
+msgid "Wrong COMPOUNDMIN value in %s line %d: %s"
+msgstr "Feil COMPOUNDMIN-verdi i %s linje %d: %s"
+
+#, c-format
+msgid "Wrong COMPOUNDSYLMAX value in %s line %d: %s"
+msgstr "Feil COMPOUNDSYLMAX-verdi i %s linje %d: %s"
+
+#, c-format
+msgid "Wrong CHECKCOMPOUNDPATTERN value in %s line %d: %s"
+msgstr "Feil CHECKCOMPOUNDPATTERN-verdi i %s linje %d: %s"
+
+#, c-format
+msgid "Different combining flag in continued affix block in %s line %d: %s"
+msgstr ""
+"Forskjellig kombinasjonsflagg i affiksblokk som fortsetter i %s linje %d: %s"
+
+#, c-format
+msgid "Duplicate affix in %s line %d: %s"
+msgstr "Duplisert affiks i %s linje %d: %s"
+
+#, c-format
+msgid ""
+"Affix also used for BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST in %s "
+"line %d: %s"
+msgstr ""
+"Affiks også brukt 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 "Forventet Y eller N i %s linje %d: %s"
+
+#, c-format
+msgid "Broken condition in %s line %d: %s"
+msgstr "Brutt betingelse i %s linje %d: %s"
+
+#, c-format
+msgid "Expected REP(SAL) count in %s line %d"
+msgstr "Forventet REP(SAL)-antall i %s linje %d"
+
+#, c-format
+msgid "Expected MAP count in %s line %d"
+msgstr "Forventet MAP-antall i %s linje %d"
+
+#, c-format
+msgid "Duplicate character in MAP in %s line %d"
+msgstr "Duplisert tegn i MAP i %s linje %d"
+
+#, c-format
+msgid "Unrecognized or duplicate item in %s line %d: %s"
+msgstr "Ukjent eller duplisert element i %s linje %d: %s"
+
+#, c-format
+msgid "Missing FOL/LOW/UPP line in %s"
+msgstr "Mangler FOL/LOW/UPP-linje i %s"
+
+msgid "COMPOUNDSYLMAX used without SYLLABLE"
+msgstr "COMPOUNDSYLMAX brukt uten SYLLABLE"
+
+msgid "Too many postponed prefixes"
+msgstr "For mange utsatte forstavelser"
+
+msgid "Too many compound flags"
+msgstr "For mange sammensatte flagg"
+
+msgid "Too many postponed prefixes and/or compound flags"
+msgstr "For mange utsatte forstavelser og/eller sammensatte flagg"
+
+#, c-format
+msgid "Missing SOFO%s line in %s"
+msgstr "Mangler 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 "Flagg er ikke et tall i %s linje %d: %s"
+
+#, c-format
+msgid "Illegal flag in %s line %d: %s"
+msgstr "Ulovlig flagg i %s linje %d: %s"
+
+#, c-format
+msgid "%s value differs from what is used in another .aff file"
+msgstr "%s-verdi er forskjellig fra det som er bruk i en annen .aff-fil"
+
+#, c-format
+msgid "Reading dictionary file %s ..."
+msgstr "Leser ordlistefil %s ..."
+
+#, c-format
+msgid "E760: No word count in %s"
+msgstr "E760: Ingen ord-antall i %s"
+
+#, c-format
+msgid "line %6d, word %6d - %s"
+msgstr "linje %6d, ord %6d - %s"
+
+#, c-format
+msgid "Duplicate word in %s line %d: %s"
+msgstr "Duplisert ord i %s linje %d: %s"
+
+#, c-format
+msgid "First duplicate word in %s line %d: %s"
+msgstr "Første dupliserte ord i %s linje %d: %s"
+
+#, c-format
+msgid "%d duplicate word(s) in %s"
+msgstr "%d duplisert(e) ord i %s"
+
+#, c-format
+msgid "Ignored %d word(s) with non-ASCII characters in %s"
+msgstr "Ignorerte %d ord med ikke-ASCII-tegn i %s"
+
+#, c-format
+msgid "Reading word file %s ..."
+msgstr "Leser ordfil %s ..."
+
+#, c-format
+msgid "Duplicate /encoding= line ignored in %s line %d: %s"
+msgstr "Duplisert '/encoding='-linje ignorert i %s linje %d: %s"
+
+#, c-format
+msgid "/encoding= line after word ignored in %s line %d: %s"
+msgstr "'/encoding='-linje etter ord ignorert i %s linje %d: %s"
+
+#, c-format
+msgid "Duplicate /regions= line ignored in %s line %d: %s"
+msgstr "Duplisert '/regions='-linje ignorert 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 ignorert i %s linje %d: %s"
+
+#, c-format
+msgid "Invalid region nr in %s line %d: %s"
+msgstr "Ugyldig regionnummer i %s linje %d: %s"
+
+#, c-format
+msgid "Unrecognized flags in %s line %d: %s"
+msgstr "Ukjent flagg i %s linje %d: %s"
+
+#, c-format
+msgid "Ignored %d words with non-ASCII characters"
+msgstr "Ignorerte %d ord med ikke-ASCII-tegn"
+
+#, c-format
+msgid "Compressed %d of %d nodes; %d (%d%%) remaining"
+msgstr "Pakket %d av %d noder; %d (%d%%) igjen"
+
+#, fuzzy
+#~ msgid "Reading back spell file..."
+#~ msgstr "Leser stavefil \"%s\""
+
+#.
+#. * Go through the trie of good words, soundfold each word and add it to
+#. * the soundfold trie.
+#.
+#~ msgid "Performing soundfolding..."
+#~ msgstr ""
+
+#, c-format
+#~ msgid "Number of words after soundfolding: %ld"
+#~ msgstr ""
+
+#, c-format
+msgid "Total number of words: %d"
+msgstr "Totalt antall ord: %d"
+
+#, c-format
+msgid "Writing suggestion file %s ..."
+msgstr "Skriver forslagsfil %s ..."
+
+#, c-format
+msgid "Estimated runtime memory use: %d bytes"
+msgstr "Anslått hukommelsesbruk under kjøring: %d bytes"
+
+msgid "E751: Output file name must not have region name"
+msgstr "E751: Utdatafilnavn må ikke ha regionnavn"
+
+msgid "E754: Only up to 8 regions supported"
+msgstr "E754: Kun opp til 8 regioner er støttet"
+
+#, c-format
+msgid "E755: Invalid region in %s"
+msgstr "E755: Ugyldig region i %s"
+
+#~ msgid "Warning: both compounding and NOBREAK specified"
+#~ msgstr ""
+
+#, c-format
+msgid "Writing spell file %s ..."
+msgstr "Lagrer stavefil %s ..."
+
+msgid "Done!"
+msgstr "Ferdig!"
+
+#, c-format
+msgid "E765: 'spellfile' does not have %ld entries"
+msgstr "E765: 'spellfile' har ikke %ld poster"
+
+#, c-format
+msgid "Word removed from %s"
+msgstr "Ord fjernet fra %s"
+
+#, c-format
+msgid "Word added to %s"
+msgstr "Ord lagt til %s"
+
+msgid "E763: Word characters differ between spell files"
+msgstr "E763: Tegn i ord varierer mellom stavefiler"
+
+msgid "Sorry, no suggestions"
+msgstr "Dessverre, ingen forslag"
+
+#, c-format
+msgid "Sorry, only %ld suggestions"
+msgstr "Dessverre bare %ld forslag"
+
+#. for when 'cmdheight' > 1
+#. avoid more prompt
+#, c-format
+msgid "Change \"%.*s\" to:"
+msgstr "Forandre \"%.*s\" til:"
+
+#, c-format
+msgid " < \"%.*s\""
+msgstr " < \"%.*s\""
+
+msgid "E752: No previous spell replacement"
+msgstr "E752: Ingen tidligere staveerstatninger"
+
+#, c-format
+msgid "E753: Not found: %s"
+msgstr "E753: Ikke funnet: %s"
+
+#, c-format
+msgid "E778: This does not look like a .sug file: %s"
+msgstr "E778: Dette ser ikke ut som en .sug-fil: %s"
+
+#, c-format
+msgid "E779: Old .sug file, needs to be updated: %s"
+msgstr "E779: Gammel .sug-fil, trenger oppdatering: %s"
+
+#, c-format
+msgid "E780: .sug file is for newer version of Vim: %s"
+msgstr "E780: .sug-fila er for en nyere versjon av Vim: %s"
+
+#, c-format
+msgid "E781: .sug file doesn't match .spl file: %s"
+msgstr "E781: .sug-fil samsvarer ikke med .spl-fil: %s"
+
+#, c-format
+msgid "E782: error while reading .sug file: %s"
+msgstr "E782: Feil under lesing av .sug-fil: %s"
+
+#. This should have been checked when generating the .spl
+#. * file.
+msgid "E783: duplicate char in MAP entry"
+msgstr "E783: Duplisert tegn i MAP-oppføring"
+
+#, c-format
+msgid "E390: Illegal argument: %s"
+msgstr "E390: Ulovlig parameter: %s"
+
+#, c-format
+msgid "E391: No such syntax cluster: %s"
+msgstr "E391: Syntaksklyngen finnes ikke: %s"
+
+msgid "No Syntax items defined for this buffer"
+msgstr "Ingen syntakselementer er definert for denne bufferen"
+
+msgid "syncing on C-style comments"
+msgstr "synkroniserer C-lignende kommentarer"
+
+msgid "no syncing"
+msgstr "ingen synkronisering"
+
+msgid "syncing starts "
+msgstr "synkronisering starter "
+
+msgid " lines before top line"
+msgstr " linjer før topplinje"
+
+msgid ""
+"\n"
+"--- Syntax sync items ---"
+msgstr ""
+"\n"
+"--- \"Syntax sync\"-elementer ---"
+
+msgid ""
+"\n"
+"syncing on items"
+msgstr ""
+"\n"
+"synkroniserer på elementer"
+
+msgid ""
+"\n"
+"--- Syntax items ---"
+msgstr ""
+"\n"
+"--- Syntakselementer ---"
+
+#, c-format
+msgid "E392: No such syntax cluster: %s"
+msgstr "E392: Syntaksklyngen finnes ikke: %s"
+
+msgid "minimal "
+msgstr "minimal "
+
+msgid "maximal "
+msgstr "maksimal "
+
+msgid "; match "
+msgstr "; samsvarer med "
+
+msgid " line breaks"
+msgstr " linjeskift"
+
+msgid "E395: contains argument not accepted here"
+msgstr "E395: \"contains\"-parameter aksepteres ikke her"
+
+msgid "E396: containedin argument not accepted here"
+msgstr "E396: \"containedin\"-parameter aksepteres ikke her"
+
+msgid "E393: group[t]here not accepted here"
+msgstr "E393: \"group[t]here\" aksepteres ikke her"
+
+#, c-format
+msgid "E394: Didn't find region item for %s"
+msgstr "E394: Fant ikke regionelement for %s"
+
+msgid "E397: Filename required"
+msgstr "E397: Trenger filnavn"
+
+#, c-format
+msgid "E789: Missing ']': %s"
+msgstr "E789: Mangler ']': %s"
+
+#, c-format
+msgid "E398: Missing '=': %s"
+msgstr "E398: Mangler '=': %s"
+
+#, c-format
+msgid "E399: Not enough arguments: syntax region %s"
+msgstr "E399: Ikke nok parametere: syntax region %s"
+
+msgid "E400: No cluster specified"
+msgstr "E400: Ingen klynge er spesifisert"
+
+#, c-format
+msgid "E401: Pattern delimiter not found: %s"
+msgstr "E401: Skilletegn for søketekst ble ikke funnet: %s"
+
+#, c-format
+msgid "E402: Garbage after pattern: %s"
+msgstr "E402: Søppel etter søketekst: %s"
+
+msgid "E403: syntax sync: line continuations pattern specified twice"
+msgstr ""
+"E403: syntax sync: Søkestreng for linjefortsettelser er spesifisert to ganger"
+
+#, c-format
+msgid "E404: Illegal arguments: %s"
+msgstr "E404: Ulovlige parametere: %s"
+
+#, c-format
+msgid "E405: Missing equal sign: %s"
+msgstr "E405: Mangler \"er lik\"-tegn: %s"
+
+#, c-format
+msgid "E406: Empty argument: %s"
+msgstr "E406: Tomt parameter: %s"
+
+#, c-format
+msgid "E407: %s not allowed here"
+msgstr "E407: %s er ikke tillatt her"
+
+#, c-format
+msgid "E408: %s must be first in contains list"
+msgstr "E408: %s må være først i \"contains\"-liste"
+
+#, c-format
+msgid "E409: Unknown group name: %s"
+msgstr "E409: Ukjent gruppenavn: %s"
+
+#, c-format
+msgid "E410: Invalid :syntax subcommand: %s"
+msgstr "E410: Ugyldig \":syntax\"-delkommando: %s"
+
+msgid "E679: recursive loop loading syncolor.vim"
+msgstr "E679: Rekursiv løkke laster syncolor.vim"
+
+#, c-format
+msgid "E411: highlight group not found: %s"
+msgstr "E411: Fant ikke uthevingsgruppe: %s"
+
+#, c-format
+msgid "E412: Not enough arguments: \":highlight link %s\""
+msgstr "E412: Ikke nok parametere: \":highlight link %s\""
+
+#, c-format
+msgid "E413: Too many arguments: \":highlight link %s\""
+msgstr "E413: For mange parametere: \":highlight link %s\""
+
+msgid "E414: group has settings, highlight link ignored"
+msgstr "E414: Syntaxgruppen har oppsett, uthevingslenke ignoreres"
+
+#, c-format
+msgid "E415: unexpected equal sign: %s"
+msgstr "E415: Uventet \"er lik\"-tegn: %s"
+
+#, c-format
+msgid "E416: missing equal sign: %s"
+msgstr "E416: Mangler \"er lik\"-tegn: %s"
+
+#, c-format
+msgid "E417: missing argument: %s"
+msgstr "E417: Mangler parameter: %s"
+
+#, c-format
+msgid "E418: Illegal value: %s"
+msgstr "E418: Ulovlig verdi: %s"
+
+msgid "E419: FG color unknown"
+msgstr "E419: Ukjent forgrunnsfarge"
+
+msgid "E420: BG color unknown"
+msgstr "E420: Ukjent bakgrunnsfarge"
+
+#, c-format
+msgid "E421: Color name or number not recognized: %s"
+msgstr "E421: Kjenner ikke til fargenavnet eller -nummeret: %s"
+
+#, c-format
+msgid "E422: terminal code too long: %s"
+msgstr "E422: Terminalkoden er for lang: %s"
+
+#, c-format
+msgid "E423: Illegal argument: %s"
+msgstr "E423: Ulovlig parameter: %s"
+
+msgid "E424: Too many different highlighting attributes in use"
+msgstr "E424: For mange forskjellige uthevingsattributter i bruk"
+
+msgid "E669: Unprintable character in group name"
+msgstr "E669: Ikke-skrivbart tegn i gruppenavn"
+
+msgid "W18: Invalid character in group name"
+msgstr "W18: Ugyldig tegn i gruppenavn"
+
+msgid "E555: at bottom of tag stack"
+msgstr "E555: På bunnen av tag-stack"
+
+msgid "E556: at top of tag stack"
+msgstr "E556: På toppen av tag-stack"
+
+msgid "E425: Cannot go before first matching tag"
+msgstr "E425: Kan ikke gå før første samsvarende tag"
+
+#, c-format
+msgid "E426: tag not found: %s"
+msgstr "E426: Fant ikke tag: %s"
+
+#~ msgid " # pri kind tag"
+#~ msgstr ""
+
+msgid "file\n"
+msgstr "fil\n"
+
+msgid "E427: There is only one matching tag"
+msgstr "E427: Det finnes bare en samsvarende tag"
+
+msgid "E428: Cannot go beyond last matching tag"
+msgstr "E428: Kan ikke gå forbi siste samsvarende tag"
+
+#, c-format
+msgid "File \"%s\" does not exist"
+msgstr "Filen \"%s\" finnes ikke"
+
+#. Give an indication of the number of matching tags
+#, c-format
+msgid "tag %d of %d%s"
+msgstr "tag %d av %d%s"
+
+msgid " or more"
+msgstr " eller mer"
+
+msgid " Using tag with different case!"
+msgstr " Bruker tag med forskjellig bokstavstørrelse!"
+
+#, c-format
+msgid "E429: File \"%s\" does not exist"
+msgstr "E429: Filen \"%s\" finnes ikke"
+
+#. Highlight title
+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 "Leter i tagfil %s"
+
+#, c-format
+msgid "E430: Tag file path truncated for %s\n"
+msgstr "E430: Sti til tagfil kuttet for %s\n"
+
+#, c-format
+msgid "E431: Format error in tags file \"%s\""
+msgstr "E431: Formatfeil i tagfil \"%s\""
+
+#, c-format
+msgid "Before byte %ld"
+msgstr "Før byte %ld"
+
+#, c-format
+msgid "E432: Tags file not sorted: %s"
+msgstr "E432: Tagfil ikke sortert: %s"
+
+#. never opened any tags file
+msgid "E433: No tags file"
+msgstr "E433: Ingen tagfil"
+
+msgid "E434: Can't find tag pattern"
+msgstr "E434: Kan ikke finne tagsøkestreng"
+
+msgid "E435: Couldn't find tag, just guessing!"
+msgstr "E435: Kunne ikke finne tag, bare gjetter!"
+
+msgid "' not known. Available builtin terminals are:"
+msgstr "' ikke kjent. Tilgjengelige innebygde terminaler er:"
+
+msgid "defaulting to '"
+msgstr "faller tilbake på '"
+
+msgid "E557: Cannot open termcap file"
+msgstr "E557: Kan ikke åpne termcap-fil"
+
+msgid "E558: Terminal entry not found in terminfo"
+msgstr "E558: Fant ikke terminaloppføring i terminfo"
+
+msgid "E559: Terminal entry not found in termcap"
+msgstr "E559: Fant ikke terminaloppføring i termcap"
+
+#, c-format
+msgid "E436: No \"%s\" entry in termcap"
+msgstr "E436: Ingen \"%s\"-oppføring i termcap"
+
+msgid "E437: terminal capability \"cm\" required"
+msgstr "E437: Terminalfunksjonen \"cm\" nødvendig"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Terminal keys ---"
+msgstr ""
+"\n"
+"--- Terminaltaster ---"
+
+msgid "new shell started\n"
+msgstr "nytt skall startet\n"
+
+msgid "Vim: Error reading input, exiting...\n"
+msgstr "Vim: Feil under lesing av inndata, avslutter ...\n"
+
+#. must display the prompt
+msgid "No undo possible; continue anyway"
+msgstr "Ingen angremuligheter; fortsett likevel"
+
+msgid "Already at oldest change"
+msgstr "Allerede ved eldste forandring"
+
+msgid "Already at newest change"
+msgstr "Allerede ved nyeste forandring"
+
+#, c-format
+msgid "Undo number %ld not found"
+msgstr "Angrenummer %ld ikke funnet"
+
+msgid "E438: u_undo: line numbers wrong"
+msgstr "E438: u_undo: Gale linjenummer"
+
+msgid "more line"
+msgstr "linje lagt til"
+
+msgid "more lines"
+msgstr "linjer lagt til"
+
+msgid "line less"
+msgstr "linje fjernet"
+
+msgid "fewer lines"
+msgstr "linjer fjernet"
+
+msgid "change"
+msgstr "forandring"
+
+msgid "changes"
+msgstr "forandringer"
+
+#, c-format
+msgid "%ld %s; %s #%ld %s"
+msgstr "%ld %s; %s #%ld %s"
+
+msgid "before"
+msgstr "før"
+
+msgid "after"
+msgstr "etter"
+
+msgid "Nothing to undo"
+msgstr "Ingenting å angre"
+
+msgid "number changes time"
+msgstr "nummer forandringer tidspunkt"
+
+#, c-format
+msgid "%ld seconds ago"
+msgstr "%ld sekunder siden"
+
+msgid "E790: undojoin is not allowed after undo"
+msgstr "E790: undojoin er ikke tillatt etter undo"
+
+msgid "E439: undo list corrupt"
+msgstr "E439: Angrelisten er skadet"
+
+msgid "E440: undo line missing"
+msgstr "E440: Angrelisten mangler"
+
+#. Only MS VC 4.1 and earlier can do Win32s
+msgid ""
+"\n"
+"MS-Windows 16/32-bit GUI version"
+msgstr ""
+"\n"
+"MS Windows 16/32-bits grafisk versjon"
+
+msgid ""
+"\n"
+"MS-Windows 64-bit GUI version"
+msgstr ""
+"\n"
+"MS Windows 64-bits grafisk versjon"
+
+msgid ""
+"\n"
+"MS-Windows 32-bit GUI version"
+msgstr ""
+"\n"
+"MS-Windows 32-bits GUI-versjon"
+
+msgid " in Win32s mode"
+msgstr " i Win32s-modus"
+
+msgid " with OLE support"
+msgstr " med OLE-støtte"
+
+msgid ""
+"\n"
+"MS-Windows 32-bit console version"
+msgstr ""
+"\n"
+"MS-Windows 32-bits konsollversjon"
+
+msgid ""
+"\n"
+"MS-Windows 16-bit version"
+msgstr ""
+"\n"
+"MS-Windows 16-bits versjon"
+
+msgid ""
+"\n"
+"32-bit MS-DOS version"
+msgstr ""
+"\n"
+"32-bits MS-DOS-versjon"
+
+msgid ""
+"\n"
+"16-bit MS-DOS version"
+msgstr ""
+"\n"
+"16-bits MS-DOS-versjon"
+
+msgid ""
+"\n"
+"MacOS X (unix) version"
+msgstr ""
+"\n"
+"MacOS X (unix)-versjon"
+
+msgid ""
+"\n"
+"MacOS X version"
+msgstr ""
+"\n"
+"MacOS X-versjon"
+
+msgid ""
+"\n"
+"MacOS version"
+msgstr ""
+"\n"
+"MacOS-versjon"
+
+msgid ""
+"\n"
+"RISC OS version"
+msgstr ""
+"\n"
+"RISC OS-versjon"
+
+msgid ""
+"\n"
+"Included patches: "
+msgstr ""
+"\n"
+"Inkluderte patcher: "
+
+msgid "Modified by "
+msgstr "Modifisert av "
+
+msgid ""
+"\n"
+"Compiled "
+msgstr ""
+"\n"
+"Kompilert "
+
+msgid "by "
+msgstr "av "
+
+msgid ""
+"\n"
+"Huge version "
+msgstr ""
+"\n"
+"Diger (\"huge\") versjon "
+
+msgid ""
+"\n"
+"Big version "
+msgstr ""
+"\n"
+"Stor (\"big\") versjon "
+
+msgid ""
+"\n"
+"Normal version "
+msgstr ""
+"\n"
+"Normal versjon "
+
+msgid ""
+"\n"
+"Small version "
+msgstr ""
+"\n"
+"Liten (\"small\") versjon "
+
+msgid ""
+"\n"
+"Tiny version "
+msgstr ""
+"\n"
+"Spinkel (\"tiny\") versjon "
+
+msgid "without GUI."
+msgstr "uten GUI."
+
+msgid "with GTK2-GNOME GUI."
+msgstr "med GTK2-GNOME GUI."
+
+msgid "with GTK-GNOME GUI."
+msgstr "med GTK-GNOME GUI."
+
+msgid "with GTK2 GUI."
+msgstr "med GTK2 GUI."
+
+msgid "with GTK GUI."
+msgstr "med GTK 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 "with (classic) GUI."
+msgstr "med (klassisk) GUI."
+
+msgid " Features included (+) or not (-):\n"
+msgstr " Funksjoner inkludert (+) eller ikke (-):\n"
+
+msgid " system vimrc file: \""
+msgstr " vimrc-fil på systemet: \""
+
+msgid " user vimrc file: \""
+msgstr " vimrc-fil for brukere: \""
+
+msgid " 2nd user vimrc file: \""
+msgstr " vimrc-fil nr. 2 for brukere: \""
+
+msgid " 3rd user vimrc file: \""
+msgstr " vimrc-fil nr. 3 for brukere: \""
+
+msgid " user exrc file: \""
+msgstr " exrc-fil for brukere: \""
+
+msgid " 2nd user exrc file: \""
+msgstr " exrc-fil nr. 2 for brukere: \""
+
+msgid " system gvimrc file: \""
+msgstr " gvimrc-fil på systemet: \""
+
+msgid " user gvimrc file: \""
+msgstr " gvimrc-fil for brukere: \""
+
+msgid "2nd user gvimrc file: \""
+msgstr " gvimrc-fil nr. 2 for brukere: \""
+
+msgid "3rd user gvimrc file: \""
+msgstr " gvimrc-fil nr. 3 for brukere: \""
+
+msgid " system menu file: \""
+msgstr " menyfil på systemet: \""
+
+msgid " fall-back for $VIM: \""
+msgstr " $VIM faller tilbake på: \""
+
+msgid " f-b for $VIMRUNTIME: \""
+msgstr "$VIMRUNTIME faller tilbake på: \""
+
+msgid "Compilation: "
+msgstr "Kompilering: "
+
+msgid "Compiler: "
+msgstr "Kompilator: "
+
+msgid "Linking: "
+msgstr "Linking: "
+
+msgid " DEBUG BUILD"
+msgstr " DEBUGGINGSVERSJON"
+
+msgid "VIM - Vi IMproved"
+msgstr "VIM - Vi IMproved - Forbedret Vi"
+
+msgid "version "
+msgstr "versjon "
+
+msgid "by Bram Moolenaar et al."
+msgstr "av Bram Moolenaar med flere"
+
+msgid "Vim is open source and freely distributable"
+msgstr "Vim er åpen kildekode og kan fritt distribueres"
+
+msgid "Help poor children in Uganda!"
+msgstr "Hjelp fattige barn i Uganda!"
+
+msgid "type :help iccf<Enter> for information "
+msgstr "skriv :help iccf<Enter> for informasjon "
+
+msgid "type :q<Enter> to exit "
+msgstr "skriv :q<Enter> for å avslutte "
+
+msgid "type :help<Enter> or <F1> for on-line help"
+msgstr "skriv :help<Enter> eller <F1> for on-line hjelp"
+
+msgid "type :help version7<Enter> for version info"
+msgstr "skriv :help version7<Enter> for versjonsinfo "
+
+msgid "Running in Vi compatible mode"
+msgstr "Kjører i Vi-kompatibel modus"
+
+msgid "type :set nocp<Enter> for Vim defaults"
+msgstr "skriv :set nocp<Enter> for standard Vim "
+
+msgid "type :help cp-default<Enter> for info on this"
+msgstr "skriv :help cp-default<Enter> for informasjon "
+
+msgid "menu Help->Orphans for information "
+msgstr "meny: Hjelp->Foreldreløse for informasjon "
+
+msgid "Running modeless, typed text is inserted"
+msgstr "Kjører uten modus, tastetrykk blir lagt inn i teksten"
+
+msgid "menu Edit->Global Settings->Toggle Insert Mode "
+msgstr "meny: Rediger->Globale innstillinger->Innsettingsmodus av/på"
+
+msgid " for two modes "
+msgstr " for to moduser "
+
+msgid "menu Edit->Global Settings->Toggle Vi Compatible"
+msgstr "meny: Rediger->Globale innstillinger->Vi-kompatibilitet av/på"
+
+msgid " for Vim defaults "
+msgstr " for standard Vim "
+
+msgid "Sponsor Vim development!"
+msgstr "Støtt utviklingen av Vim!"
+
+msgid "Become a registered Vim user!"
+msgstr "Bli registrert bruker av Vim!"
+
+msgid "type :help sponsor<Enter> for information "
+msgstr "skriv :help sponsor<Enter> for informasjon "
+
+msgid "type :help register<Enter> for information "
+msgstr "skriv :help register<Enter> for informasjon "
+
+msgid "menu Help->Sponsor/Register for information "
+msgstr "meny: Hjelp->Støtte/Registrering for informasjon "
+
+msgid "WARNING: Windows 95/98/ME detected"
+msgstr "ADVARSEL: Windows 95/98/ME oppdaget"
+
+msgid "type :help windows95<Enter> for info on this"
+msgstr "skriv :help windows95<Enter> for informasjon "
+
+msgid "Already only one window"
+msgstr "Allerede bare ett vindu"
+
+msgid "E441: There is no preview window"
+msgstr "E441: Vindu for forhåndsvisning finnes ikke"
+
+msgid "E442: Can't split topleft and botright at the same time"
+msgstr "E442: Kan ikke splitte \"topleft\" og \"botright\" på en gang"
+
+msgid "E443: Cannot rotate when another window is split"
+msgstr "E443: Kan ikke rotere når et annet vindu er splittet"
+
+msgid "E444: Cannot close last window"
+msgstr "E444: Kan ikke lukke det siste vinduet"
+
+msgid "E445: Other window contains changes"
+msgstr "E445: Annet vindu inneholder forandringer"
+
+msgid "E446: No file name under cursor"
+msgstr "E446: Ingen filnavn under markøren"
+
+#, c-format
+msgid "E447: Can't find file \"%s\" in path"
+msgstr "E447: Kan ikke finne filen \"%s\" i stien"
+
+#, c-format
+msgid "E370: Could not load library %s"
+msgstr "E370: Klarte ikke laste bibliotek %s"
+
+msgid "Sorry, this command is disabled: the Perl library could not be loaded."
+msgstr "Denne kommandoen er deaktivert, Perl-biblioteket kunne ikke lastes."
+
+msgid "E299: Perl evaluation forbidden in sandbox without the Safe module"
+msgstr ""
+"E299: Evaluering av Perl er ikke tillatt i sandkassen uten \"Safe\"-modulen"
+
+msgid "Edit with &multiple Vims"
+msgstr "Rediger med &flere Vim-er"
+
+msgid "Edit with single &Vim"
+msgstr "Rediger med enkel &Vim"
+
+msgid "Diff with Vim"
+msgstr "Differanse med Vim"
+
+msgid "Edit with &Vim"
+msgstr "Rediger med &Vim"
+
+#. Now concatenate
+msgid "Edit with existing Vim - "
+msgstr "Rediger med eksisterende Vim - "
+
+msgid "Edits the selected file(s) with Vim"
+msgstr "Redigerer de(n) valgte filen(e) med Vim"
+
+msgid "Error creating process: Check if gvim is in your path!"
+msgstr "Klarte ikke lage prosess: Sjekk at gvim er i stien!"
+
+msgid "gvimext.dll error"
+msgstr "Feil i gvimext.dll"
+
+msgid "Path length too long!"
+msgstr "Lengden på stien er for lang!"
+
+msgid "--No lines in buffer--"
+msgstr "--Ingen linjer i bufferen--"
+
+#.
+#. * 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: Kommandoen avbrutt"
+
+msgid "E471: Argument required"
+msgstr "E471: Parameter nødvendig"
+
+msgid "E10: \\ should be followed by /, ? or &"
+msgstr "E10: \\ skulle ha vært fulgt av /, ? eller &"
+
+msgid "E11: Invalid in command-line window; <CR> executes, CTRL-C quits"
+msgstr "E11: Ugyldig i kommandolinjevindu; <ENTER> utfører, CTRL-C avslutter"
+
+msgid "E12: Command not allowed from exrc/vimrc in current dir or tag search"
+msgstr ""
+"E12: Kommandoen er ikke tillatt fra exrc/vimrc i nåværende katalog eller "
+"tagsøk"
+
+msgid "E171: Missing :endif"
+msgstr "E171: Mangler :endif"
+
+msgid "E600: Missing :endtry"
+msgstr "E600: Mangler :endtry"
+
+msgid "E170: Missing :endwhile"
+msgstr "E170: Mangler :endwhile"
+
+msgid "E170: Missing :endfor"
+msgstr "E170: Mangler :endfor"
+
+msgid "E588: :endwhile without :while"
+msgstr "E588: :endwhile uten :while"
+
+msgid "E588: :endfor without :for"
+msgstr "E588: :endfor uten :for"
+
+msgid "E13: File exists (add ! to override)"
+msgstr "E13: Filen finnes (legg til ! for å overstyre)"
+
+msgid "E472: Command failed"
+msgstr "E472: Kommandoen feilet"
+
+#, c-format
+msgid "E234: Unknown fontset: %s"
+msgstr "E234: Ukjent skrifttypesett: %s"
+
+#, c-format
+msgid "E235: Unknown font: %s"
+msgstr "E235: Ukjent skrifttype: %s"
+
+#, c-format
+msgid "E236: Font \"%s\" is not fixed-width"
+msgstr "E236: Skrifttypen \"%s\" har ikke fast bredde"
+
+msgid "E473: Internal error"
+msgstr "E473: Intern feil"
+
+msgid "Interrupted"
+msgstr "Avbrutt"
+
+msgid "E14: Invalid address"
+msgstr "E14: Ugyldig adresse"
+
+msgid "E474: Invalid argument"
+msgstr "E474: Ugyldig parameter"
+
+#, c-format
+msgid "E475: Invalid argument: %s"
+msgstr "E475: Ugyldig paramter: %s"
+
+#, c-format
+msgid "E15: Invalid expression: %s"
+msgstr "E15: Ugyldig uttrykk: %s"
+
+msgid "E16: Invalid range"
+msgstr "E16: Ugyldig område"
+
+msgid "E476: Invalid command"
+msgstr "E476: Ugyldig kommando"
+
+#, c-format
+msgid "E17: \"%s\" is a directory"
+msgstr "E17: \"%s\" er en katalog"
+
+#, c-format
+msgid "E364: Library call failed for \"%s()\""
+msgstr "E364: Bibliotek-kall feilet for \"%s()\""
+
+#, c-format
+msgid "E448: Could not load library function %s"
+msgstr "E448: Klarte ikke laste biblioteksfunksjon %s"
+
+msgid "E19: Mark has invalid line number"
+msgstr "E19: Merket har et ugyldig linjenummer"
+
+msgid "E20: Mark not set"
+msgstr "E20: Merket ble ikke satt"
+
+msgid "E21: Cannot make changes, 'modifiable' is off"
+msgstr "E21: Kan ikke gjøre forandringer, 'modifiable' er av"
+
+msgid "E22: Scripts nested too deep"
+msgstr "E22: Skripts nøstet for dypt"
+
+msgid "E23: No alternate file"
+msgstr "E23: Ingen alternativ fil"
+
+msgid "E24: No such abbreviation"
+msgstr "E24: Forkortelsen finnes ikke"
+
+msgid "E477: No ! allowed"
+msgstr "E477: Ingen ! tillatt"
+
+msgid "E25: GUI cannot be used: Not enabled at compile time"
+msgstr "E25: GUI kan ikke brukes: Ikke slått på under kompilering"
+
+msgid "E26: Hebrew cannot be used: Not enabled at compile time\n"
+msgstr "E26: Hebraisk kan ikke brukes: Ikke slått på under kompilering\n"
+
+msgid "E27: Farsi cannot be used: Not enabled at compile time\n"
+msgstr ""
+"E27: Persisk (Farsi) kan ikke brukes: Ikke slått på under kompilering\n"
+
+msgid "E800: Arabic cannot be used: Not enabled at compile time\n"
+msgstr "E800: Arabisk kan ikke brukes: Ikke slått på under kompilering\n"
+
+#, c-format
+msgid "E28: No such highlight group name: %s"
+msgstr "E28: Uthevingsgruppe finnes ikke: %s"
+
+msgid "E29: No inserted text yet"
+msgstr "E29: Ingen innlagt tekst enda"
+
+msgid "E30: No previous command line"
+msgstr "E30: Ingen tidligere kommandolinje"
+
+msgid "E31: No such mapping"
+msgstr "E31: Mappingen finnes ikke"
+
+msgid "E479: No match"
+msgstr "E479: Ingen treff"
+
+#, c-format
+msgid "E480: No match: %s"
+msgstr "E480: Ingen treff: %s"
+
+msgid "E32: No file name"
+msgstr "E32: Mangler filnavn"
+
+msgid "E33: No previous substitute regular expression"
+msgstr "E33: Ingen tidligere erstatninger med regulære uttrykk"
+
+msgid "E34: No previous command"
+msgstr "E34: Ingen tidligere kommando"
+
+msgid "E35: No previous regular expression"
+msgstr "E35: Ingen tidligere regulære uttrykk"
+
+msgid "E481: No range allowed"
+msgstr "E481: Område er ikke tillatt"
+
+msgid "E36: Not enough room"
+msgstr "E36: Ikke nok plass"
+
+#, c-format
+msgid "E247: no registered server named \"%s\""
+msgstr "E247: Ingen registrert tjener kalt \"%s\""
+
+#, c-format
+msgid "E482: Can't create file %s"
+msgstr "E482: Kan ikke opprette filen %s"
+
+msgid "E483: Can't get temp file name"
+msgstr "E483: Kan ikke hente navn på midlertidig fil"
+
+#, c-format
+msgid "E484: Can't open file %s"
+msgstr "E484: Kan ikke åpne filen %s"
+
+#, c-format
+msgid "E485: Can't read file %s"
+msgstr "E485: Kan ikke lese filen %s"
+
+msgid "E37: No write since last change (add ! to override)"
+msgstr "E37: Ikke lagret siden forrige forandring (legg til ! for å overstyre)"
+
+msgid "E38: Null argument"
+msgstr "E38: Nullparameter"
+
+msgid "E39: Number expected"
+msgstr "E39: Nummer forventet"
+
+#, c-format
+msgid "E40: Can't open errorfile %s"
+msgstr "E40: Kan ikke åpne feilfilen %s"
+
+msgid "E233: cannot open display"
+msgstr "E233: Kan ikke åpne display"
+
+msgid "E41: Out of memory!"
+msgstr "E41: Ikke mer ledig hukommelse!"
+
+msgid "Pattern not found"
+msgstr "Fant ikke søketeksten"
+
+#, c-format
+msgid "E486: Pattern not found: %s"
+msgstr "E486: Fant ikke søketeksten: %s"
+
+msgid "E487: Argument must be positive"
+msgstr "E487: Parameteret må være positivt"
+
+msgid "E459: Cannot go back to previous directory"
+msgstr "E459: Kan ikke gå tilbake til tidligere katalog"
+
+msgid "E42: No Errors"
+msgstr "E42: Ingen feil"
+
+msgid "E776: No location list"
+msgstr "E776: Ingen plassliste"
+
+msgid "E43: Damaged match string"
+msgstr "E43: Ødelagt søkestreng"
+
+msgid "E44: Corrupted regexp program"
+msgstr "E44: Skadet program med regulært uttrykk"
+
+msgid "E45: 'readonly' option is set (add ! to override)"
+msgstr "E45: 'readonly'-valget er satt (legg til ! for å overstyre)"
+
+#, c-format
+msgid "E46: Cannot change read-only variable \"%s\""
+msgstr "E46: Kan ikke forandre skrivebeskyttet variabel \"%s\""
+
+#, c-format
+msgid "E794: Cannot set variable in the sandbox: \"%s\""
+msgstr "E794: Kan ikke sette variabel i sandkassen: \"%s\""
+
+msgid "E47: Error while reading errorfile"
+msgstr "E47: Feil under lesing av feilfilen"
+
+msgid "E48: Not allowed in sandbox"
+msgstr "E48: Ikke tillatt i sandkassen"
+
+msgid "E523: Not allowed here"
+msgstr "E523: Ikke tillatt her"
+
+msgid "E359: Screen mode setting not supported"
+msgstr "E359: Forandring av skjermmodus er ikke støttet"
+
+msgid "E49: Invalid scroll size"
+msgstr "E49: Ugyldig \"scroll\"-verdi"
+
+msgid "E91: 'shell' option is empty"
+msgstr "E91: 'shell'-valget er tomt"
+
+msgid "E255: Couldn't read in sign data!"
+msgstr "E255: Kunne ikke lese inn skiltdata!"
+
+msgid "E72: Close error on swap file"
+msgstr "E72: Feil under lukking av swapfil"
+
+msgid "E73: tag stack empty"
+msgstr "E73: Tag-stack tom"
+
+msgid "E74: Command too complex"
+msgstr "E74: Kommandoen er for kompleks"
+
+msgid "E75: Name too long"
+msgstr "E75: Navnet er for langt"
+
+msgid "E76: Too many ["
+msgstr "E76: For mange ["
+
+msgid "E77: Too many file names"
+msgstr "E77: For mange filnavn"
+
+msgid "E488: Trailing characters"
+msgstr "E488: Etterfølgende tegn"
+
+msgid "E78: Unknown mark"
+msgstr "E78: Ukjent merke"
+
+msgid "E79: Cannot expand wildcards"
+msgstr "E79: Klarte ikke utvide jokertegn"
+
+msgid "E591: 'winheight' cannot be smaller than 'winminheight'"
+msgstr "E591: 'winheight' kan ikke være mindre enn 'winminheight'"
+
+msgid "E592: 'winwidth' cannot be smaller than 'winminwidth'"
+msgstr "E592: 'winwidth' kan ikke være mindre enn 'winminwidth'"
+
+msgid "E80: Error while writing"
+msgstr "E80: Feil under skriving"
+
+msgid "Zero count"
+msgstr "Antall repeteringer er null"
+
+msgid "E81: Using <SID> not in a script context"
+msgstr "E81: Bruker <SID> utenom skript-kontekst"
+
+msgid "E449: Invalid expression received"
+msgstr "E449: Ugyldig uttrykk mottatt"
+
+msgid "E463: Region is guarded, cannot modify"
+msgstr "E463: Regionen er beskyttet og kan ikke modifiseres"
+
+msgid "E744: NetBeans does not allow changes in read-only files"
+msgstr "E744: NetBeans tillater ikke forandringer i skrivebeskyttede filer"
+
+#, c-format
+msgid "E685: Internal error: %s"
+msgstr "E685: Intern feil: %s"
+
+msgid "E363: pattern uses more memory than 'maxmempattern'"
+msgstr "E363: Søkestrengen bruker mer hukommelse enn 'maxmempattern'"
+
+msgid "E749: empty buffer"
+msgstr "E749: Tom buffer"
+
+msgid "E682: Invalid search pattern or delimiter"
+msgstr "E682: Ugyldig søkestreng eller skilletegn"
+
+msgid "E139: File is loaded in another buffer"
+msgstr "E139: Filen er lastet i en annen buffer"
+
+#, c-format
+msgid "E764: Option '%s' is not set"
+msgstr "E764: Valget '%s' er ikke satt"
+
+msgid "search hit TOP, continuing at BOTTOM"
+msgstr "Søket traff TOPPEN, fortsetter fra BUNNEN"
+
+msgid "search hit BOTTOM, continuing at TOP"
+msgstr "Søket traff BUNNEN, fortsetter fra TOPPEN"
diff --git a/src/po/pl.UTF-8.po b/src/po/pl.UTF-8.po
new file mode 100644
index 0000000000..43f958c73f
--- /dev/null
+++ b/src/po/pl.UTF-8.po
@@ -0,0 +1,6904 @@
+# 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: 2013-07-06 19:33+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=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 "
+"|| n%100>=20) ? 1 : 2);\n"
+
+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 "[Location List]"
+msgstr "[Lista lokacji]"
+
+msgid "[Quickfix List]"
+msgstr "[Lista quickfix]"
+
+msgid "E855: Autocommands caused command to abort"
+msgstr "E855: Autokomendy spowodowały porzucenie komendy"
+
+msgid "E82: Cannot allocate any buffer, exiting..."
+msgstr "E82: Nie mogę zarezerwować bufora; zakończenie..."
+
+msgid "E83: Cannot allocate buffer, using other one..."
+msgstr "E83: Nie mogę zarezerwować bufora; używam innego..."
+
+msgid "E515: No buffers were unloaded"
+msgstr "E515: Nie wyładowano żadnego bufora"
+
+msgid "E516: No buffers were deleted"
+msgstr "E516: Nie skasowano żadnego bufora"
+
+msgid "E517: No buffers were wiped out"
+msgstr "E517: Nie wyrzucono żadnego bufora"
+
+msgid "1 buffer unloaded"
+msgstr "1 bufor wyładowany"
+
+#, c-format
+msgid "%d buffers unloaded"
+msgstr "wyładowano %d buforów"
+
+msgid "1 buffer deleted"
+msgstr "1 bufor skasowany"
+
+#, c-format
+msgid "%d buffers deleted"
+msgstr "%d buforów skasowano"
+
+msgid "1 buffer wiped out"
+msgstr "wyrzucono 1 bufor "
+
+#, c-format
+msgid "%d buffers wiped out"
+msgstr "wyrzucono %d buforów"
+
+msgid "E84: No modified buffer found"
+msgstr "E84: Nie znaleziono zmienionych buforów"
+
+#. back where we started, didn't find anything.
+msgid "E85: There is no listed buffer"
+msgstr "E85: Nie ma wylistowanych buforów"
+
+#, c-format
+msgid "E86: Buffer %ld does not exist"
+msgstr "E86: Bufor \"%ld\" nie istnieje"
+
+msgid "E87: Cannot go beyond last buffer"
+msgstr "E87: Nie mogę przejść poza ostatni bufor"
+
+msgid "E88: Cannot go before first buffer"
+msgstr "E88: Nie mogę przejść przed pierwszy bufor"
+
+#, c-format
+msgid "E89: No write since last change for buffer %ld (add ! to override)"
+msgstr "E89: Nie zapisano zmian w buforze %ld (wymuÅ› przez !)"
+
+msgid "E90: Cannot unload last buffer"
+msgstr "E90: Nie mogę wyładować ostatniego bufora"
+
+msgid "W14: Warning: List of file names overflow"
+msgstr "W14: OSTRZEŻENIE: Przepełnienie listy nazw plików"
+
+#, c-format
+msgid "E92: Buffer %ld not found"
+msgstr "E92: Nie znaleziono bufora %ld"
+
+#, c-format
+msgid "E93: More than one match for %s"
+msgstr "E93: Wielokrotne dopasowania dla %s"
+
+#, c-format
+msgid "E94: No matching buffer for %s"
+msgstr "E94: Żaden bufor nie pasuje do %s"
+
+#, c-format
+msgid "line %ld"
+msgstr "wiersz %ld"
+
+msgid "E95: Buffer with this name already exists"
+msgstr "E95: Bufor o tej nazwie już istnieje"
+
+msgid " [Modified]"
+msgstr " [Zmieniony]"
+
+msgid "[Not edited]"
+msgstr "[Nie edytowany]"
+
+msgid "[New file]"
+msgstr "[Nowy Plik]"
+
+msgid "[Read errors]"
+msgstr "[Błąd odczytu]"
+
+msgid "[RO]"
+msgstr "[RO]"
+
+msgid "[readonly]"
+msgstr "[tylko odczyt]"
+
+#, c-format
+msgid "1 line --%d%%--"
+msgstr "1 wiersz --%d%%--"
+
+#, c-format
+msgid "%ld lines --%d%%--"
+msgstr "%ld wiersze --%d%%--"
+
+#, c-format
+msgid "line %ld of %ld --%d%%-- col "
+msgstr "wiersz %ld z %ld --%d%%-- kol "
+
+msgid "[No Name]"
+msgstr "[Bez nazwy]"
+
+#. must be a help buffer
+msgid "help"
+msgstr "pomoc"
+
+msgid "[Help]"
+msgstr "[Pomoc]"
+
+msgid "[Preview]"
+msgstr "[PodglÄ…d]"
+
+msgid "All"
+msgstr "Wszystko"
+
+msgid "Bot"
+msgstr "Dół"
+
+msgid "Top"
+msgstr "Góra"
+
+msgid ""
+"\n"
+"# Buffer list:\n"
+msgstr ""
+"\n"
+"# Lista buforów:\n"
+
+msgid "[Scratch]"
+msgstr "[Notka]"
+
+msgid ""
+"\n"
+"--- Signs ---"
+msgstr ""
+"\n"
+"--- Znaki ---"
+
+#, c-format
+msgid "Signs for %s:"
+msgstr "Znaki dla %s:"
+
+#, c-format
+msgid " line=%ld id=%d name=%s"
+msgstr " wiersz=%ld id=%d nazwa=%s"
+
+#, c-format
+msgid "E96: Can not diff more than %ld buffers"
+msgstr "E96: Nie mogę zróżnicować więcej niż %ld buforów"
+
+msgid "E810: Cannot read or write temp files"
+msgstr "E810: Nie mogę otworzyć lub zapisać plików tymczasowych"
+
+msgid "E97: Cannot create diffs"
+msgstr "E97: Nie mogę stworzyć różnic"
+
+msgid "Patch file"
+msgstr "Plik łata"
+
+msgid "E816: Cannot read patch output"
+msgstr "E816: Nie mogę odczytać wyjścia pliku łaty"
+
+msgid "E98: Cannot read diff output"
+msgstr "E98: Nie mogę wczytać wyjścia różnicy"
+
+msgid "E99: Current buffer is not in diff mode"
+msgstr "E99: Bieżący bufor nie jest w trybie różnic"
+
+msgid "E793: No other buffer in diff mode is modifiable"
+msgstr "E793: Żaden inny bufor w trybie diff nie jest modyfikowalny"
+
+msgid "E100: No other buffer in diff mode"
+msgstr "E100: Brak innego bufora w trybie różnic"
+
+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ć"
+
+#, c-format
+msgid "E102: Can't find buffer \"%s\""
+msgstr "E102: Nie mogę znaleźć bufora \"%s\""
+
+#, c-format
+msgid "E103: Buffer \"%s\" is not in diff mode"
+msgstr "E103: Bufor \"%s\" nie jest w trybie różnicowania"
+
+msgid "E787: Buffer changed unexpectedly"
+msgstr "E787: Nieoczekiwana zmiana bufora"
+
+msgid "E104: Escape not allowed in digraph"
+msgstr "E104: Escape jest niedozwolone w dwugrafie"
+
+msgid "E544: Keymap file not found"
+msgstr "E544: Nie znaleziono pliku rozkładu klawiszy"
+
+msgid "E105: Using :loadkeymap not in a sourced file"
+msgstr "E105: Zastosowano :loadkeymap w niewczytanym pliku"
+
+msgid "E791: Empty keymap entry"
+msgstr "E791: Pusty wpis keymap"
+
+msgid " Keyword completion (^N^P)"
+msgstr " Dopełnianie słów kluczowych (^N^P)"
+
+#. ctrl_x_mode == 0, ^P/^N compl.
+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)"
+
+msgid " Whole line completion (^L^N^P)"
+msgstr " Dopełnianie pełnych wierszy (^L^N^P)"
+
+msgid " File name completion (^F^N^P)"
+msgstr " Dopełnianie nazw plików (^F^N^P)"
+
+msgid " Tag completion (^]^N^P)"
+msgstr " Dopełnianie znaczników (^]^N^P)"
+
+msgid " Path pattern completion (^N^P)"
+msgstr " Dopełnianie wzorców tropów (^N^P)"
+
+msgid " Definition completion (^D^N^P)"
+msgstr " Dopełnianie definicji (^D^N^P)"
+
+msgid " Dictionary completion (^K^N^P)"
+msgstr " Dopełnianie ze słowników (^K^N^P)"
+
+msgid " Thesaurus completion (^T^N^P)"
+msgstr " Dopełnianie z tezaurusa (^T^N^P)"
+
+msgid " Command-line completion (^V^N^P)"
+msgstr " Dopełnianie wiersza poleceń (^V^N^P)"
+
+msgid " User defined completion (^U^N^P)"
+msgstr "Dopełnianie zdefiniowane przez użytkownika (^U^N^P)"
+
+msgid " Omni completion (^O^N^P)"
+msgstr " Omni uzupełnianie (^O^N^P)"
+
+msgid " Spelling suggestion (s^N^P)"
+msgstr "Propozycja pisowni (^L^N^P)"
+
+msgid " Keyword Local completion (^N^P)"
+msgstr " Lokalne dopełnianie słów kluczowych (^N^P)"
+
+msgid "Hit end of paragraph"
+msgstr "Dobiłem do końca akapitu"
+
+msgid "E839: Completion function changed window"
+msgstr "E839: Funkcja uzupełniania zmieniła okno"
+
+msgid "E840: Completion function deleted text"
+msgstr "E840: Funkcja uzupełnania usunęła tekst"
+
+msgid "'dictionary' option is empty"
+msgstr "opcja 'dictionary' jest pusta"
+
+msgid "'thesaurus' option is empty"
+msgstr "opcja 'thesaurus' jest pusta"
+
+#, c-format
+msgid "Scanning dictionary: %s"
+msgstr "Przeglądam słownik: %s"
+
+msgid " (insert) Scroll (^E/^Y)"
+msgstr " (wprowadzanie) Przewijanie (^E/^Y)"
+
+msgid " (replace) Scroll (^E/^Y)"
+msgstr " (zamiana) Przewijanie (^E/^Y)"
+
+#, c-format
+msgid "Scanning: %s"
+msgstr "PrzeglÄ…dam: %s"
+
+msgid "Scanning tags."
+msgstr "PrzeglÄ…dam znaczniki."
+
+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.
+#.
+msgid "-- Searching..."
+msgstr "-- Szukam..."
+
+msgid "Back at original"
+msgstr "Z powrotem na pierwotnym"
+
+msgid "Word from other line"
+msgstr "Wyraz z innego wiersza"
+
+msgid "The only match"
+msgstr "Jedyne dopasowanie"
+
+#, c-format
+msgid "match %d of %d"
+msgstr "pasuje %d z %d"
+
+#, c-format
+msgid "match %d"
+msgstr "pasuje %d"
+
+msgid "E18: Unexpected characters in :let"
+msgstr "E18: Nieoczekiwane znaki w :let"
+
+#, c-format
+msgid "E684: list index out of range: %ld"
+msgstr "E684: Indeks listy poza zakresem: %ld"
+
+#, c-format
+msgid "E121: Undefined variable: %s"
+msgstr "E121: Nieokreślona zmienna: %s"
+
+msgid "E111: Missing ']'"
+msgstr "E111: Brak ']'"
+
+#, c-format
+msgid "E686: Argument of %s must be a List"
+msgstr "E686: Argument %s musi być Listą"
+
+#, c-format
+msgid "E712: Argument of %s must be a List or Dictionary"
+msgstr "E712: Argument %s musi być Listą lub Słownikiem"
+
+msgid "E713: Cannot use empty key for Dictionary"
+msgstr "E713: Nie można użyć pustego klucza dla Słownika"
+
+msgid "E714: List required"
+msgstr "E714: wymagana Lista"
+
+msgid "E715: Dictionary required"
+msgstr "E715: wymagany Słownik"
+
+#, c-format
+msgid "E118: Too many arguments for function: %s"
+msgstr "E118: Zbyt wiele argumentów dla funkcji: %s"
+
+#, c-format
+msgid "E716: Key not present in Dictionary: %s"
+msgstr "E716: Klucz nie istnieje w Słowniku: %s"
+
+#, c-format
+msgid "E122: Function %s already exists, add ! to replace it"
+msgstr "E122: Funkcja %s już istnieje; aby ją zamienić użyj !"
+
+msgid "E717: Dictionary entry already exists"
+msgstr "E717: istnieje już taki element Słownika"
+
+msgid "E718: Funcref required"
+msgstr "E718: wymagana Funcref"
+
+msgid "E719: Cannot use [:] with a Dictionary"
+msgstr "E719: Nie można użyć [:] przy Słowniku"
+
+#, c-format
+msgid "E734: Wrong variable type for %s="
+msgstr "E734: Zły typ zmiennej dla %s="
+
+#, c-format
+msgid "E130: Unknown function: %s"
+msgstr "E130: Nieznana funkcja: %s"
+
+#, c-format
+msgid "E461: Illegal variable name: %s"
+msgstr "E461: Niedozwolona nazwa zmiennej: %s"
+
+msgid "E806: using Float as a String"
+msgstr "E806: Użycie Zmiennoprzecinkowej jako ÅaÅ„cucha"
+
+msgid "E687: Less targets than List items"
+msgstr "E687: Mniej celów niż elementów Listy"
+
+msgid "E688: More targets than List items"
+msgstr "E688: Więcej celów niż elementów Listy"
+
+msgid "Double ; in list of variables"
+msgstr "Podwójny ; w liście zmiennych"
+
+#, c-format
+msgid "E738: Can't list variables for %s"
+msgstr "E738: Nie mogę wypisać zmiennych dla %s"
+
+msgid "E689: Can only index a List or Dictionary"
+msgstr "E689: Indeks może istnieć tylko dla Listy lub Słownika"
+
+msgid "E708: [:] must come last"
+msgstr "E708: [:] musi być ostatnie"
+
+msgid "E709: [:] requires a List value"
+msgstr "E709: [:] wymaga wartości listy"
+
+msgid "E710: List value has more items than target"
+msgstr "E710: Lista ma więcej elementów niż cel"
+
+msgid "E711: List value has not enough items"
+msgstr "E711: Lista nie ma wystarczającej ilości elementów"
+
+msgid "E690: Missing \"in\" after :for"
+msgstr "E690: Brak \"in\" po :for"
+
+#, c-format
+msgid "E107: Missing parentheses: %s"
+msgstr "E107: Brak nawiasów: %s"
+
+#, c-format
+msgid "E108: No such variable: \"%s\""
+msgstr "E108: Nie istnieje zmienna: \"%s\""
+
+msgid "E743: variable nested too deep for (un)lock"
+msgstr "E743: zmienna zagnieżdżona zbyt głęboko dla (un)lock"
+
+msgid "E109: Missing ':' after '?'"
+msgstr "E109: Brak ':' po '?'"
+
+msgid "E691: Can only compare List with List"
+msgstr "E691: Listę mogę porównać tylko z Listą"
+
+msgid "E692: Invalid operation for Lists"
+msgstr "E692: Nieprawidłowa operacja dla Listy"
+
+msgid "E735: Can only compare Dictionary with Dictionary"
+msgstr "E735: Słownik mogę porównać tylko ze Słownikiem"
+
+msgid "E736: Invalid operation for Dictionary"
+msgstr "E736: Nieprawidłowa operacja dla Słownika"
+
+msgid "E693: Can only compare Funcref with Funcref"
+msgstr "E693: Funcref mogę porównać tylko z Funcref"
+
+msgid "E694: Invalid operation for Funcrefs"
+msgstr "E694: Nieprawidłowa operacja dla Funcref"
+
+msgid "E804: Cannot use '%' with Float"
+msgstr "E804: Nie mogę użyć '%' w Zmiennoprzecinkowej"
+
+msgid "E110: Missing ')'"
+msgstr "E110: Brak ')'"
+
+msgid "E695: Cannot index a Funcref"
+msgstr "E695: Nie można zindeksować Funcref"
+
+#, c-format
+msgid "E112: Option name missing: %s"
+msgstr "E112: Brak nazwy opcji: %s"
+
+#, c-format
+msgid "E113: Unknown option: %s"
+msgstr "E113: Nieznana opcja: %s"
+
+#, c-format
+msgid "E114: Missing quote: %s"
+msgstr "E114: Brak cudzysłowu: %s"
+
+#, c-format
+msgid "E115: Missing quote: %s"
+msgstr "E115: Brak cudzysłowu: %s"
+
+#, c-format
+msgid "E696: Missing comma in List: %s"
+msgstr "E696: Brakujący przecinek w Liście: '%s"
+
+#, c-format
+msgid "E697: Missing end of List ']': %s"
+msgstr "E697: Brak zakończenia Listy ']': %s"
+
+#, c-format
+msgid "E720: Missing colon in Dictionary: %s"
+msgstr "E720: Brak dwukropka w Słowniku: %s"
+
+#, c-format
+msgid "E721: Duplicate key in Dictionary: \"%s\""
+msgstr "E721: Powtórzony klucz w Słowniku: \"%s\""
+
+#, c-format
+msgid "E722: Missing comma in Dictionary: %s"
+msgstr "E722: Brakujący przecinek w Słowniku: %s"
+
+#, c-format
+msgid "E723: Missing end of Dictionary '}': %s"
+msgstr "E723: Brak końca w Słowniku '}': %s"
+
+msgid "E724: variable nested too deep for displaying"
+msgstr "E724: Zmienna zagnieżdżona zbyt głęboko by pokazać"
+
+#, c-format
+msgid "E740: Too many arguments for function %s"
+msgstr "E740: Zbyt wiele argumentów dla funkcji %s"
+
+#, c-format
+msgid "E116: Invalid arguments for function %s"
+msgstr "E116: Zbyt wiele argumentów dla funkcji %s"
+
+#, c-format
+msgid "E117: Unknown function: %s"
+msgstr "E117: Nieznana funkcja: %s"
+
+#, c-format
+msgid "E119: Not enough arguments for function: %s"
+msgstr "E119: Za mało argumentów dla funkcji: %s"
+
+#, c-format
+msgid "E120: Using <SID> not in a script context: %s"
+msgstr "E120: Użycie <SID> poza kontekstem skryptu: %s"
+
+#, c-format
+msgid "E725: Calling dict function without Dictionary: %s"
+msgstr "E725: Wywołanie funkcji \"dict\" bez Słownika: %s"
+
+msgid "E808: Number or Float required"
+msgstr "E808: Wymagana Liczba lub Zmiennoprzecinkowa"
+
+msgid "add() argument"
+msgstr "argument add()"
+
+msgid "E699: Too many arguments"
+msgstr "E699: Za dużo argumentów"
+
+msgid "E785: complete() can only be used in Insert mode"
+msgstr "E785: complete() może być użyte tylko w trybie Wprowadzania"
+
+#.
+#. * 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"
+
+#, c-format
+msgid "E737: Key already exists: %s"
+msgstr "E737: Klucz już istnieje: %s"
+
+msgid "extend() argument"
+msgstr "argument extend()"
+
+msgid "map() argument"
+msgstr "argument map()"
+
+msgid "filter() argument"
+msgstr "argument filter()"
+
+#, c-format
+msgid "+-%s%3ld lines: "
+msgstr "+-%s%3ld wierszy: "
+
+#, c-format
+msgid "E700: Unknown function: %s"
+msgstr "E700: Nieznana funkcja: %s"
+
+msgid ""
+"&OK\n"
+"&Cancel"
+msgstr ""
+"&OK\n"
+"&Zakończ"
+
+msgid "called inputrestore() more often than inputsave()"
+msgstr "wywołano inputrestore() więcej razy niż inputsave()"
+
+msgid "insert() argument"
+msgstr "argument insert()"
+
+msgid "E786: Range not allowed"
+msgstr "E786: Zakres niedozwolony"
+
+msgid "E701: Invalid type for len()"
+msgstr "E701: Nieprawidłowy typ dla len()"
+
+msgid "E726: Stride is zero"
+msgstr "E726: Skok to zero"
+
+msgid "E727: Start past end"
+msgstr "E727: Początek po końcu"
+
+msgid "<empty>"
+msgstr "<pusty>"
+
+msgid "E240: No connection to Vim server"
+msgstr "E240: Brak połączenia z serwerem Vim"
+
+#, c-format
+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 "remove() argument"
+msgstr "argument remove()"
+
+msgid "E655: Too many symbolic links (cycle?)"
+msgstr "E655: Za dużo dowiązań symbolicznych (pętla?)"
+
+msgid "reverse() argument"
+msgstr "argument reverse()"
+
+msgid "E258: Unable to send to client"
+msgstr "E258: Nie mogę wysłać do klienta"
+
+msgid "sort() argument"
+msgstr "argument sort()"
+
+msgid "E702: Sort compare function failed"
+msgstr "E702: Funkcja porównywania w sort nie powiodła się"
+
+msgid "(Invalid)"
+msgstr "(Niewłaściwe)"
+
+msgid "E677: Error writing temp file"
+msgstr "E677: Błąd zapisywania pliku tymczasowego"
+
+msgid "E805: Using a Float as a Number"
+msgstr "E805: Użycie Zmiennoprzecinkowej jako Liczby"
+
+msgid "E703: Using a Funcref as a Number"
+msgstr "E703: Użycie Funcref jako Liczby"
+
+msgid "E745: Using a List as a Number"
+msgstr "E745: Użycie Listy jako Liczby"
+
+msgid "E728: Using a Dictionary as a Number"
+msgstr "E728: Użycie Słownika jako Liczby"
+
+msgid "E729: using Funcref as a String"
+msgstr "E729: Użycie Funcref jako ÅaÅ„cucha"
+
+msgid "E730: using List as a String"
+msgstr "E730: Użycie Listy jako ÅaÅ„cucha"
+
+msgid "E731: using Dictionary as a String"
+msgstr "E731: Użycie SÅ‚ownika jako ÅaÅ„cucha"
+
+#, c-format
+msgid "E706: Variable type mismatch for: %s"
+msgstr "E706: Nieprawidłowy typ zmiennej dla: %s"
+
+#, c-format
+msgid "E795: Cannot delete variable %s"
+msgstr "E795: Nie mogę usunąć zmiennej %s"
+
+#, c-format
+msgid "E704: Funcref variable name must start with a capital: %s"
+msgstr "E704: Nazwa Funcref musi się zaczynać wielką literą: %s"
+
+#, c-format
+msgid "E705: Variable name conflicts with existing function: %s"
+msgstr "E705: Nazwa zmiennej jest w konflikcie z istniejÄ…cÄ… funkcjÄ…: %s"
+
+#, c-format
+msgid "E741: Value is locked: %s"
+msgstr "E741: Wartość jest zablokowana: %s"
+
+msgid "Unknown"
+msgstr "Nieznane"
+
+#, c-format
+msgid "E742: Cannot change value of %s"
+msgstr "E742: Nie mogę zmienić wartości %s"
+
+msgid "E698: variable nested too deep for making a copy"
+msgstr "E698: Zmienna zagnieżdżona zbyt głęboko by zrobić kopię"
+
+#, c-format
+msgid "E123: Undefined function: %s"
+msgstr "E123: Nieznana funkcja: %s"
+
+#, c-format
+msgid "E124: Missing '(': %s"
+msgstr "E124: Brak '(': %s"
+
+msgid "E862: Cannot use g: here"
+msgstr "E862: Nie można tutaj użyć g:"
+
+#, c-format
+msgid "E125: Illegal argument: %s"
+msgstr "E125: Niedozwolony argument: %s"
+
+#, c-format
+msgid "E853: Duplicate argument name: %s"
+msgstr "E853: Powtórzona nazwa argumentu: %s"
+
+msgid "E126: Missing :endfunction"
+msgstr "E126: Brak :endfunction"
+
+#, c-format
+msgid "E707: Function name conflicts with variable: %s"
+msgstr "E707: Nazwa funkcji jest w konflikcie ze zmiennÄ…: %s"
+
+#, c-format
+msgid "E127: Cannot redefine function %s: It is in use"
+msgstr "E127: Nie mogę redefiniować funkcji %s: jest w użyciu"
+
+#, c-format
+msgid "E746: Function name does not match script file name: %s"
+msgstr "E746: Nazwa funkcji nie pasuje do nazwy skryptu: %s"
+
+msgid "E129: Function name required"
+msgstr "E129: Wymagana jest nazwa funkcji"
+
+#, c-format
+msgid "E128: Function name must start with a capital or contain a colon: %s"
+msgstr ""
+"E128: Nazwa funkcji musi rozpoczynać się wielką literą lub zawierać "
+"dwukropek: %s"
+
+#, c-format
+msgid "E131: Cannot delete function %s: It is in use"
+msgstr "E131: Nie mogę skasować funkcji %s: jest w użyciu"
+
+msgid "E132: Function call depth is higher than 'maxfuncdepth'"
+msgstr "E132: Zagnieżdżenie wywołań funkcji ponad 'maxfuncdepth'"
+
+#, c-format
+msgid "calling %s"
+msgstr "wywołuję %s"
+
+#, c-format
+msgid "%s aborted"
+msgstr "porzucono %s"
+
+#, c-format
+msgid "%s returning #%ld"
+msgstr "%s zwraca #%ld"
+
+#, c-format
+msgid "%s returning %s"
+msgstr "%s zwraca %s"
+
+#, c-format
+msgid "continuing in %s"
+msgstr "kontynuacja w %s"
+
+msgid "E133: :return not inside a function"
+msgstr "E133: :return poza funkcjÄ…"
+
+msgid ""
+"\n"
+"# global variables:\n"
+msgstr ""
+"\n"
+"# zmienne globalne:\n"
+
+msgid ""
+"\n"
+"\tLast set from "
+msgstr ""
+"\n"
+"\tOstatnie ustawienie przez "
+
+msgid "No old files"
+msgstr "Brak starych plików"
+
+msgid "Entering Debug mode. Type \"cont\" to continue."
+msgstr "Wchodzę w tryb odpluskwiania. Wprowadź \"cont\" aby kontynuować."
+
+#, c-format
+msgid "line %ld: %s"
+msgstr "wiersz %ld: %s"
+
+#, c-format
+msgid "cmd: %s"
+msgstr "cmd: %s"
+
+#, c-format
+msgid "Breakpoint in \"%s%s\" line %ld"
+msgstr "Punkt kontrolny w \"%s%s\" wiersz %ld"
+
+#, c-format
+msgid "E161: Breakpoint not found: %s"
+msgstr "E161: Nie znaleziono punktu kontrolnego: %s"
+
+msgid "No breakpoints defined"
+msgstr "Nie określono żadnych punktów kontrolnych"
+
+#, c-format
+msgid "%3d %s %s line %ld"
+msgstr "%3d %s %s wiersz %ld"
+
+msgid "E750: First use \":profile start {fname}\""
+msgstr "E750: Pierwsze użycie \":profile start {fname}\""
+
+msgid "Save As"
+msgstr "Zapisz jako"
+
+#, c-format
+msgid "Save changes to \"%s\"?"
+msgstr "Zachować zmiany w \"%s\"?"
+
+msgid "Untitled"
+msgstr "Bez Tytułu"
+
+#, c-format
+msgid "E162: No write since last change for buffer \"%s\""
+msgstr "E162: Nie zapisano zmian w buforze \"%s\""
+
+msgid "Warning: Entered other buffer unexpectedly (check autocommands)"
+msgstr "OSTRZEŻENIE: Nieoczekiwane wejście w inny bufor (sprawdź autokomendy)"
+
+msgid "E163: There is only one file to edit"
+msgstr "E163: Tylko jeden plik w edycji"
+
+msgid "E164: Cannot go before first file"
+msgstr "E164: Nie można przejść przed pierwszy plik"
+
+msgid "E165: Cannot go beyond last file"
+msgstr "E165: Nie można przejść za ostatni plik"
+
+#, c-format
+msgid "E666: compiler not supported: %s"
+msgstr "E666: nie wspierany kompilator: %s"
+
+#, c-format
+msgid "Searching for \"%s\" in \"%s\""
+msgstr "Szukanie \"%s\" w \"%s\""
+
+#, c-format
+msgid "Searching for \"%s\""
+msgstr "Szukanie \"%s\""
+
+#, c-format
+msgid "not found in 'runtimepath': \"%s\""
+msgstr "nie znaleziono w 'runtimepath': \"%s\""
+
+msgid "Source Vim script"
+msgstr "Wczytaj skrypt Vima"
+
+#, c-format
+msgid "Cannot source a directory: \"%s\""
+msgstr "Nie można wczytać katalogu: \"%s\""
+
+#, c-format
+msgid "could not source \"%s\""
+msgstr "nie mogłem wczytać \"%s\""
+
+#, c-format
+msgid "line %ld: could not source \"%s\""
+msgstr "wiersz: %ld nie mogłem wczytać \"%s\""
+
+#, c-format
+msgid "sourcing \"%s\""
+msgstr "wczytywanie \"%s\""
+
+#, c-format
+msgid "line %ld: sourcing \"%s\""
+msgstr "wiersz %ld: wczytywanie \"%s\""
+
+#, c-format
+msgid "finished sourcing %s"
+msgstr "skończono wczytywanie %s"
+
+msgid "modeline"
+msgstr "modeline"
+
+msgid "--cmd argument"
+msgstr "--cmd argument"
+
+msgid "-c argument"
+msgstr "-c argument"
+
+msgid "environment variable"
+msgstr "zmienna środowiskowa"
+
+msgid "error handler"
+msgstr "obsługa błędu"
+
+msgid "W15: Warning: Wrong line separator, ^M may be missing"
+msgstr "W15: OSTRZEŻENIE: Niewłaściwy separator wierszy, pewnie brak ^M"
+
+msgid "E167: :scriptencoding used outside of a sourced file"
+msgstr "E167: użyto :scriptencoding poza wczytywanym plikiem"
+
+msgid "E168: :finish used outside of a sourced file"
+msgstr "E168: użyto :finish poza wczytywanym plikiem"
+
+#, c-format
+msgid "Current %slanguage: \"%s\""
+msgstr "Bieżący %sjęzyk: \"%s\""
+
+#, c-format
+msgid "E197: Cannot set language to \"%s\""
+msgstr "E197: Nie mogę ustawić języka na \"%s\""
+
+#, c-format
+msgid "<%s>%s%s %d, Hex %02x, Octal %03o"
+msgstr "<%s>%s%s %d, Hex %02x, Oktal %03o"
+
+#, c-format
+msgid "> %d, Hex %04x, Octal %o"
+msgstr "> %d, Hex %04x, Oktal %o"
+
+#, c-format
+msgid "> %d, Hex %08x, Octal %o"
+msgstr "> %d, Hex %08x, Oktal %o"
+
+msgid "E134: Move lines into themselves"
+msgstr "E134: Przeniesienie wierszy na siebie samych"
+
+msgid "1 line moved"
+msgstr "1 wiersz przeniesiony"
+
+#, c-format
+msgid "%ld lines moved"
+msgstr "%ld wiersze przeniesione"
+
+#, c-format
+msgid "%ld lines filtered"
+msgstr "%ld wierszy przefiltrowanych"
+
+msgid "E135: *Filter* Autocommands must not change current buffer"
+msgstr "E135: Autokomendy *Filter* nie mogą zmieniać bieżącego bufora"
+
+msgid "[No write since last change]\n"
+msgstr "[Brak zapisu od czasu ostatniej zmiany]\n"
+
+#, c-format
+msgid "%sviminfo: %s in line: "
+msgstr "%sviminfo: %s w wierszu: "
+
+msgid "E136: viminfo: Too many errors, skipping rest of file"
+msgstr "E136: viminfo: Zbyt wiele błędów; pomijam resztę pliku"
+
+#, c-format
+msgid "Reading viminfo file \"%s\"%s%s%s"
+msgstr "WczytujÄ™ plik viminfo \"%s\"%s%s%s"
+
+msgid " info"
+msgstr " informacja"
+
+msgid " marks"
+msgstr " zakładki"
+
+msgid " oldfiles"
+msgstr " stare pliki"
+
+msgid " FAILED"
+msgstr " NIE POWIODÅO SIĘ"
+
+#. avoid a wait_return for this message, it's annoying
+#, c-format
+msgid "E137: Viminfo file is not writable: %s"
+msgstr "E137: Plik viminfo jest niezapisywalny: %s"
+
+#, c-format
+msgid "E138: Can't write viminfo file %s!"
+msgstr "E138: Nie mogę zapisać pliku viminfo %s!"
+
+#, c-format
+msgid "Writing viminfo file \"%s\""
+msgstr "ZapisujÄ™ plik viminfo \"%s\""
+
+#. Write the info:
+#, c-format
+msgid "# This viminfo file was generated by Vim %s.\n"
+msgstr "# Ten plik viminfo został wygenerowany przez Vima %s.\n"
+
+msgid ""
+"# You may edit it if you're careful!\n"
+"\n"
+msgstr ""
+"# Możesz go ostrożnie edytować!\n"
+"\n"
+
+msgid "# Value of 'encoding' when this file was written\n"
+msgstr "# Wartość 'encoding' w czasie zapisu tego pliku\n"
+
+msgid "Illegal starting char"
+msgstr "Niedopuszczalny poczÄ…tkowy znak"
+
+msgid "Write partial file?"
+msgstr "Zapisać częściowo plik?"
+
+msgid "E140: Use ! to write partial buffer"
+msgstr "E140: Stosuj ! do zapisania częściowo bufora"
+
+#, c-format
+msgid "Overwrite existing file \"%s\"?"
+msgstr "Nadpisać istniejący plik \"%s\"?"
+
+#, c-format
+msgid "Swap file \"%s\" exists, overwrite anyway?"
+msgstr "Plik wymiany \"%s\" istnieje, czy go nadpisać?"
+
+#, c-format
+msgid "E768: Swap file exists: %s (:silent! overrides)"
+msgstr "E768: Plik wymiany istnieje: %s (wymuÅ› poprzez :silent!)"
+
+#, c-format
+msgid "E141: No file name for buffer %ld"
+msgstr "E141: Brak nazwy pliku dla bufora %ld"
+
+msgid "E142: File not written: Writing is disabled by 'write' option"
+msgstr "E142: Plik niezapisany: Zapis jest wyłączony opcją 'write'"
+
+#, 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ć?"
+
+#, 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ć?"
+
+#, c-format
+msgid "E505: \"%s\" is read-only (add ! to override)"
+msgstr "E505: \"%s\" jest tylko do odczytu (dodaj ! aby wymusić)"
+
+msgid "Edit File"
+msgstr "Edytuj Plik"
+
+#, c-format
+msgid "E143: Autocommands unexpectedly deleted new buffer %s"
+msgstr "E143: Autokomendy nieoczekiwanie skasowały nowy bufor %s"
+
+msgid "E144: non-numeric argument to :z"
+msgstr "E144: nienumeryczny argument dla :z"
+
+msgid "E145: Shell commands not allowed in rvim"
+msgstr "E145: Komendy powłoki są niedozwolone w rvim"
+
+msgid "E146: Regular expressions can't be delimited by letters"
+msgstr "E146: Wzorce regularne nie mogą być rozgraniczane literami"
+
+#, c-format
+msgid "replace with %s (y/n/a/q/l/^E/^Y)?"
+msgstr "zamień na %s (y/n/a/q/l/^E/^Y)?"
+
+msgid "(Interrupted) "
+msgstr "(Przerwane) "
+
+msgid "1 match"
+msgstr "1 pasuje"
+
+msgid "1 substitution"
+msgstr "1 podstawienie "
+
+#, c-format
+msgid "%ld matches"
+msgstr "%ld dopasowań"
+
+#, c-format
+msgid "%ld substitutions"
+msgstr "%ld podstawień"
+
+msgid " on 1 line"
+msgstr " w 1 wierszu"
+
+#, c-format
+msgid " on %ld lines"
+msgstr " w %ld wierszach"
+
+msgid "E147: Cannot do :global recursive"
+msgstr "E147: Nie mogę wykonać :global rekursywnie"
+
+msgid "E148: Regular expression missing from global"
+msgstr "E148: Brak wzorca regularnego w :global"
+
+# c-format
+#, c-format
+msgid "Pattern found in every line: %s"
+msgstr "Wzorzec znaleziono w każdym wierszu: %s"
+
+#, c-format
+msgid "Pattern not found: %s"
+msgstr "Nie znaleziono wzorca: %s"
+
+msgid ""
+"\n"
+"# Last Substitute String:\n"
+"$"
+msgstr ""
+"\n"
+"# Ostatni podstawiany ciÄ…g:\n"
+"$"
+
+msgid "E478: Don't panic!"
+msgstr "E478: Nie panikuj!"
+
+#, c-format
+msgid "E661: Sorry, no '%s' help for %s"
+msgstr "E661: Przykro mi, brak '%s' pomocy dla %s"
+
+#, c-format
+msgid "E149: Sorry, no help for %s"
+msgstr "E149: Przykro mi, ale brak pomocy o %s"
+
+#, c-format
+msgid "Sorry, help file \"%s\" not found"
+msgstr "Przykro mi, nie ma pliku pomocy \"%s\""
+
+#, c-format
+msgid "E150: Not a directory: %s"
+msgstr "E150: Nie jest katalogiem: %s"
+
+#, c-format
+msgid "E152: Cannot open %s for writing"
+msgstr "E152: Nie mogę otworzyć %s do zapisu"
+
+#, c-format
+msgid "E153: Unable to open %s for reading"
+msgstr "E153: Nie mogę otworzyć %s do odczytu"
+
+#, 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"
+
+#, c-format
+msgid "E154: Duplicate tag \"%s\" in file %s/%s"
+msgstr "E154: Powtórzony znacznik \"%s\" w pliku %s/%s"
+
+#, c-format
+msgid "E160: Unknown sign command: %s"
+msgstr "E160: Nieznana komenda znaku: %s"
+
+msgid "E156: Missing sign name"
+msgstr "E156: Brak nazwy znaku"
+
+msgid "E612: Too many signs defined"
+msgstr "E612: Zbyt wiele nazw znaków"
+
+#, c-format
+msgid "E239: Invalid sign text: %s"
+msgstr "E239: Niewłaściwy tekst znaku: %s"
+
+#, c-format
+msgid "E155: Unknown sign: %s"
+msgstr "E155: Nieznany znak: %s"
+
+msgid "E159: Missing sign number"
+msgstr "E159: Brak numeru znaku"
+
+#, c-format
+msgid "E158: Invalid buffer name: %s"
+msgstr "E158: Niewłaściwa nazwa bufora: %s"
+
+#, c-format
+msgid "E157: Invalid sign ID: %ld"
+msgstr "E157: Niewłaściwe ID znaku: %ld"
+
+msgid " (NOT FOUND)"
+msgstr " (NIE ZNALEZIONO)"
+
+msgid " (not supported)"
+msgstr "(nie wspomagane)"
+
+msgid "[Deleted]"
+msgstr "[Skasowano]"
+
+msgid "Entering Ex mode. Type \"visual\" to go to Normal mode."
+msgstr "Wchodzę w tryb Ex. Wprowadź \"visual\" aby przejść do trybu Normal."
+
+msgid "E501: At end-of-file"
+msgstr "E501: Na końcu pliku"
+
+msgid "E169: Command too recursive"
+msgstr "E169: Komenda zbyt rekursywna"
+
+#, c-format
+msgid "E605: Exception not caught: %s"
+msgstr "E605: Nie znaleziono wyjÄ…tku: %s"
+
+msgid "End of sourced file"
+msgstr "Koniec wczytywanego pliku"
+
+msgid "End of function"
+msgstr "Koniec funkcji"
+
+msgid "E464: Ambiguous use of user-defined command"
+msgstr ""
+"E464: Niejednoznaczne zastosowanie komendy zdefiniowanej przez użytkownika"
+
+msgid "E492: Not an editor command"
+msgstr "E492: Nie jest komendÄ… edytora"
+
+msgid "E493: Backwards range given"
+msgstr "E493: Dano wsteczny zakres"
+
+msgid "Backwards range given, OK to swap"
+msgstr "Dano wsteczny zakres; zamiana jest możliwa"
+
+msgid "E494: Use w or w>>"
+msgstr "E494: Stosuj w lub w>>"
+
+msgid "E319: Sorry, the command is not available in this version"
+msgstr "E319: Przykro mi, ale ta komenda nie jest dostępna w tej wersji"
+
+msgid "E172: Only one file name allowed"
+msgstr "E172: Tylko pojedyncza nazwa pliku dozwolona"
+
+msgid "1 more file to edit. Quit anyway?"
+msgstr "1 więcej plik do edycji. Mimo to wyjść?"
+
+#, c-format
+msgid "%d more files to edit. Quit anyway?"
+msgstr "jeszcze %d plików do edycji. Mimo to wyjść?"
+
+msgid "E173: 1 more file to edit"
+msgstr "E173: 1 więcej plik do edycji"
+
+#, c-format
+msgid "E173: %ld more files to edit"
+msgstr "E173: jeszcze %ld plików do edycji"
+
+msgid "E174: Command already exists: add ! to replace it"
+msgstr "E174: Komenda już istnieje; aby ją przedefiniować stosuj !"
+
+msgid ""
+"\n"
+" Name Args Range Complete Definition"
+msgstr ""
+"\n"
+" Nazwa Arg. Zak. Gotowość Definicja"
+
+msgid "No user-defined commands found"
+msgstr "Nie znaleziono komend zdefiniowanych przez użytkownika"
+
+msgid "E175: No attribute specified"
+msgstr "E175: Nie określono atrybutu"
+
+msgid "E176: Invalid number of arguments"
+msgstr "E176: Niewłaściwa ilość argumentów"
+
+msgid "E177: Count cannot be specified twice"
+msgstr "E177: Mnożnik nie może być podany dwukrotnie"
+
+msgid "E178: Invalid default value for count"
+msgstr "E178: Niewłaściwa domyślna wartość mnożnika"
+
+msgid "E179: argument required for -complete"
+msgstr "E179: -complete wymaga argumentu"
+
+#, c-format
+msgid "E181: Invalid attribute: %s"
+msgstr "E181: Niewłaściwy atrybut: %s"
+
+msgid "E182: Invalid command name"
+msgstr "E182: Niewłaściwa nazwa komendy"
+
+msgid "E183: User defined commands must start with an uppercase letter"
+msgstr ""
+"E183: Komendy zdefiniowane przez użytkownika muszą rozpoczynać się dużą "
+"literÄ…"
+
+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"
+
+#, c-format
+msgid "E184: No such user-defined command: %s"
+msgstr "E184: Nie ma takiej komendy użytkownika: %s"
+
+#, c-format
+msgid "E180: Invalid complete value: %s"
+msgstr "E180: Niewłaściwa wartość dopełniania: %s"
+
+msgid "E468: Completion argument only allowed for custom completion"
+msgstr ""
+"E468: Argument depełniania dozwolony wyłącznie dla dopełniania użytkownika"
+
+msgid "E467: Custom completion requires a function argument"
+msgstr "E467: Dopełnianie użytkownika wymaga funkcji jako argumentu"
+
+msgid "unknown"
+msgstr "nieznany"
+
+#, c-format
+msgid "E185: Cannot find color scheme '%s'"
+msgstr "E185: Nie mogę znaleźć zestawu kolorów '%s'"
+
+msgid "Greetings, Vim user!"
+msgstr "Witaj użytkowniku Vima!"
+
+msgid "E784: Cannot close last tab page"
+msgstr "E784: Nie mogę zamknąć ostatniej karty"
+
+msgid "Already only one tab page"
+msgstr "Jest już tylko jedna karta"
+
+msgid "Edit File in new window"
+msgstr "Edytuj plik w nowym oknie"
+
+#, c-format
+msgid "Tab page %d"
+msgstr "Karta %d"
+
+msgid "No swap file"
+msgstr "Brak pliku wymiany"
+
+msgid "Append File"
+msgstr "Dołącz plik"
+
+msgid "E747: Cannot change directory, buffer is modified (add ! to override)"
+msgstr ""
+"E747: Nie mogę zmienić katalogu, bufor został zmodyfikowany (dodaj ! aby "
+"wymusić)"
+
+msgid "E186: No previous directory"
+msgstr "E186: Nie ma poprzedniego katalogu"
+
+msgid "E187: Unknown"
+msgstr "E187: Nieznany"
+
+msgid "E465: :winsize requires two number arguments"
+msgstr "E465: :winsize wymaga dwóch argumentów numerycznych"
+
+#, c-format
+msgid "Window position: X %d, Y %d"
+msgstr "Pozycja okna: X %d, Y %d"
+
+msgid "E188: Obtaining window position not implemented for this platform"
+msgstr ""
+"E188: Pozyskiwanie pozycji okna nie jest zaimplementowane dla tego systemu"
+
+msgid "E466: :winpos requires two number arguments"
+msgstr "E466: :winpos wymaga dwóch argumentów numerycznych"
+
+msgid "Save Redirection"
+msgstr "Zapisz przekierowanie"
+
+msgid "Save View"
+msgstr "Zapisz widok"
+
+msgid "Save Session"
+msgstr "Zapisz sesjÄ™"
+
+msgid "Save Setup"
+msgstr "Zapisz ustawienia"
+
+#, c-format
+msgid "E739: Cannot create directory: %s"
+msgstr "E739: Nie mogę utworzyć katalogu: %s"
+
+#, c-format
+msgid "E189: \"%s\" exists (add ! to override)"
+msgstr "E189: \"%s\" istnieje (wymuÅ› poprzez !)"
+
+#, c-format
+msgid "E190: Cannot open \"%s\" for writing"
+msgstr "E190: Nie mogę otworzyć \"%s\" do zapisu"
+
+#. set mark
+msgid "E191: Argument must be a letter or forward/backward quote"
+msgstr "E191: Argument musi być literą albo cudzysłowem w przód/tył"
+
+msgid "E192: Recursive use of :normal too deep"
+msgstr "E192: Rekursywne zastosowanie :normal za głębokie"
+
+msgid "E809: #< is not available without the +eval feature"
+msgstr "E809: #< nie jest dostępne bez właściwości +eval"
+
+msgid "E194: No alternate file name to substitute for '#'"
+msgstr "E194: Brak nazwy zamiennego pliku do podstawienia pod '#'"
+
+msgid "E495: no autocommand file name to substitute for \"<afile>\""
+msgstr "E495: brak nazwy pliku autokomend do podstawienia pod \"<afile>\""
+
+msgid "E496: no autocommand buffer number to substitute for \"<abuf>\""
+msgstr "E496: brak numeru bufora autokomend do podstawienia pod \"<abuf>\""
+
+msgid "E497: no autocommand match name to substitute for \"<amatch>\""
+msgstr "E497: brak nazwy dopasowania autokomend pod \"<amatch>\""
+
+msgid "E498: no :source file name to substitute for \"<sfile>\""
+msgstr "E498: brak nazwy pliku :source do postawienia pod \"<sfile>\""
+
+msgid "E842: no line number to use for \"<slnum>\""
+msgstr "E842: brak numeru linii by użyć z \"<slnum>\""
+
+#, no-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\""
+
+msgid "E500: Evaluates to an empty string"
+msgstr "E500: Wynikiem jest pusty ciÄ…g"
+
+msgid "E195: Cannot open viminfo file for reading"
+msgstr "E195: Nie mogę otworzyć pliku viminfo do odczytu"
+
+msgid "E196: No digraphs in this version"
+msgstr "E196: Brak dwugrafów w tej wersji"
+
+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
+#, c-format
+msgid "Exception thrown: %s"
+msgstr "WyjÄ…tek: %s"
+
+#, c-format
+msgid "Exception finished: %s"
+msgstr "Wyjątek zakończony: %s"
+
+#, c-format
+msgid "Exception discarded: %s"
+msgstr "WyjÄ…tek odrzucony: %s"
+
+#, c-format
+msgid "%s, line %ld"
+msgstr "%s, wiersz %ld"
+
+#. always scroll up, don't overwrite
+#, c-format
+msgid "Exception caught: %s"
+msgstr "WyjÄ…tek przechwycony: %s"
+
+#, c-format
+msgid "%s made pending"
+msgstr "%s został zawieszony"
+
+#, c-format
+msgid "%s resumed"
+msgstr "%s przywrócony"
+
+#, c-format
+msgid "%s discarded"
+msgstr "%s odrzucony"
+
+msgid "Exception"
+msgstr "WyjÄ…tek"
+
+msgid "Error and interrupt"
+msgstr "Błąd i przerwanie"
+
+msgid "Error"
+msgstr "Błąd"
+
+#. if (pending & CSTP_INTERRUPT)
+msgid "Interrupt"
+msgstr "Przerwanie"
+
+msgid "E579: :if nesting too deep"
+msgstr "E579: zbyt głębokie zagnieżdżenie :if"
+
+msgid "E580: :endif without :if"
+msgstr "E580: :endif bez :if"
+
+msgid "E581: :else without :if"
+msgstr "E581: :else bez :if"
+
+msgid "E582: :elseif without :if"
+msgstr "E582: :elseif bez :if"
+
+msgid "E583: multiple :else"
+msgstr "E583: wielokrotne :else"
+
+msgid "E584: :elseif after :else"
+msgstr "E584: :elseif po :else"
+
+msgid "E585: :while/:for nesting too deep"
+msgstr "E585: zbyt głębokie zagnieżdżenie :while/:for"
+
+msgid "E586: :continue without :while or :for"
+msgstr "E586: :continue bez :while lub :for"
+
+msgid "E587: :break without :while or :for"
+msgstr "E587: :break bez :while lub :for"
+
+msgid "E732: Using :endfor with :while"
+msgstr "E732: Użycie :endfor z :while"
+
+msgid "E733: Using :endwhile with :for"
+msgstr "E733: Użycie :endwhile z :for"
+
+msgid "E601: :try nesting too deep"
+msgstr "E601: zbyt głębokie zagnieżdżenie :try"
+
+msgid "E603: :catch without :try"
+msgstr "E603: :catch bez :try"
+
+#. Give up for a ":catch" after ":finally" and ignore it.
+#. * Just parse.
+msgid "E604: :catch after :finally"
+msgstr "E604: :catch za :finally"
+
+msgid "E606: :finally without :try"
+msgstr "E606: :finally bez :try"
+
+#. Give up for a multiple ":finally" and ignore it.
+msgid "E607: multiple :finally"
+msgstr "E607: wielokrotne :finally"
+
+msgid "E602: :endtry without :try"
+msgstr "E602: :endtry bez :try"
+
+msgid "E193: :endfunction not inside a function"
+msgstr "E193: :endfunction poza funkcjÄ…"
+
+msgid "E788: Not allowed to edit another buffer now"
+msgstr "E788: Nie można teraz edytować innego bufora"
+
+msgid "E811: Not allowed to change buffer information now"
+msgstr "E811: Nie można teraz zmieniać informacji o buforze"
+
+msgid "tagname"
+msgstr "nazwa znacznika"
+
+msgid " kind file\n"
+msgstr " pokrewny plik\n"
+
+msgid "'history' option is zero"
+msgstr "opcja 'history' jest zerowa"
+
+#, c-format
+msgid ""
+"\n"
+"# %s History (newest to oldest):\n"
+msgstr ""
+"\n"
+"# %s Historia (od najnowszych po najstarsze):\n"
+
+msgid "Command Line"
+msgstr "Wiersz poleceń"
+
+msgid "Search String"
+msgstr "Szukany ciÄ…g"
+
+msgid "Expression"
+msgstr "Wyrażenie"
+
+msgid "Input Line"
+msgstr "Wiersz wprowadzeń"
+
+msgid "E198: cmd_pchar beyond the command length"
+msgstr "E198: cmd_pchar przekracza długość polecenia"
+
+msgid "E199: Active window or buffer deleted"
+msgstr "E199: Aktywny widok lub bufor skasowany"
+
+msgid "E812: Autocommands changed buffer or buffer name"
+msgstr "E812: Autokomendy zmieniły bufor lub jego nazwę"
+
+msgid "Illegal file name"
+msgstr "Niedopuszczalna nazwa pliku"
+
+msgid "is a directory"
+msgstr "jest katalogiem"
+
+msgid "is not a file"
+msgstr "nie jest plikiem"
+
+msgid "is a device (disabled with 'opendevice' option)"
+msgstr "jest urządzeniem (wyłączonym w opcji 'opendevice')"
+
+msgid "[New File]"
+msgstr "[Nowy Plik]"
+
+msgid "[New DIRECTORY]"
+msgstr "[Nowy KATALOG]"
+
+msgid "[File too big]"
+msgstr "[Za duży plik]"
+
+msgid "[Permission Denied]"
+msgstr "[Nie dozwolono]"
+
+msgid "E200: *ReadPre autocommands made the file unreadable"
+msgstr "E200: Autokomendy *ReadPre zrobiły plik nieodczytywalnym"
+
+msgid "E201: *ReadPre autocommands must not change current buffer"
+msgstr "E201: Autokomendy *ReadPre nie mogą zmieniać bieżącego bufora"
+
+msgid "Vim: Reading from stdin...\n"
+msgstr "Vim: Wczytywanie ze stdin...\n"
+
+msgid "Reading from stdin..."
+msgstr "Wczytywanie ze stdin..."
+
+#. Re-opening the original file failed!
+msgid "E202: Conversion made file unreadable!"
+msgstr "E202: Nie można otworzyć pliku utworzonego przez przemianę!"
+
+msgid "[fifo/socket]"
+msgstr "[fifo/socket]"
+
+msgid "[fifo]"
+msgstr "[fifo]"
+
+msgid "[socket]"
+msgstr "[socket]"
+
+msgid "[character special]"
+msgstr "[specjalny znak]"
+
+msgid "[CR missing]"
+msgstr "[brak CR]'"
+
+msgid "[long lines split]"
+msgstr "[długie wiersze rozdzielane]"
+
+msgid "[NOT converted]"
+msgstr "[NIE przemienione]"
+
+msgid "[converted]"
+msgstr "[przemienione]"
+
+msgid "[blowfish]"
+msgstr "[blowfish]"
+
+msgid "[crypted]"
+msgstr "[zakodowane]"
+
+#, c-format
+msgid "[CONVERSION ERROR in line %ld]"
+msgstr "[BÅÄ„D W PRZEMIANIE w linii %ld]"
+
+#, c-format
+msgid "[ILLEGAL BYTE in line %ld]"
+msgstr "[NIEDOZWOLONY BAJT w wierszu %ld]"
+
+msgid "[READ ERRORS]"
+msgstr "[BÅĘDY W ODCZYCIE]"
+
+msgid "Can't find temp file for conversion"
+msgstr "Nie mogę znaleźć pliku tymczasowego w celu przemiany"
+
+msgid "Conversion with 'charconvert' failed"
+msgstr "Nieudana przemiana z 'charconvert'"
+
+msgid "can't read output of 'charconvert'"
+msgstr "nie mogę odczytać wyjścia z 'charconvert'"
+
+msgid "E821: File is encrypted with unknown method"
+msgstr "E821: Plik zaszyfrowano w nieznany sposób"
+
+msgid "E676: No matching autocommands for acwrite buffer"
+msgstr "E676: Brak pasujÄ…cych autokomend dla bufora acwrite"
+
+msgid "E203: Autocommands deleted or unloaded buffer to be written"
+msgstr ""
+"E203: Autokomendy skasowały lub wyładowały bufor przeznaczony do zapisu"
+
+msgid "E204: Autocommand changed number of lines in unexpected way"
+msgstr "E204: Autokomenda zmieniła liczbę wierszy w nieoczekiwany 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 "is not a file or writable device"
+msgstr "nie jest plikiem lub zapisywalnym przyrzÄ…dem"
+
+msgid "writing to device disabled with 'opendevice' option"
+msgstr "zapisywanie do urządzenia wyłączone w opcji 'opendevice'"
+
+msgid "is read-only (add ! to override)"
+msgstr "jest tylko do odczytu (wymuÅ› poprzez !)"
+
+msgid "E506: Can't write to backup file (add ! to override)"
+msgstr "E506: Nie mogę zapisać do pliku zabezpieczenia (wymuś przez !)"
+
+msgid "E507: Close error for backup file (add ! to override)"
+msgstr "E507: Błąd podczas zamykania pliku zabezpieczenia (wymuś przez !)"
+
+msgid "E508: Can't read file for backup (add ! to override)"
+msgstr "E508: Nie mogę odczytać pliku w celu zabezpieczenia (wymuś przez !)"
+
+msgid "E509: Cannot create backup file (add ! to override)"
+msgstr "E509: Nie mogę stworzyć pliku zabezpieczenia (wymuś przez !)"
+
+msgid "E510: Can't make backup file (add ! to override)"
+msgstr "E510: Nie mogę zrobić pliku zabezpieczenia (wymuś przez !)"
+
+msgid "E460: The resource fork would be lost (add ! to override)"
+msgstr "E460: Rozdział zasobów zostanie utracony (wymuś przez !)"
+
+msgid "E214: Can't find temp file for writing"
+msgstr "E214: Nie mogę znaleźć pliku tymczasowego do zapisania"
+
+msgid "E213: Cannot convert (add ! to write without conversion)"
+msgstr "E213: Nie mogę przemienić (użyj ! by zapisać bez przemiany)"
+
+msgid "E166: Can't open linked file for writing"
+msgstr "E166: Nie mogę otworzyć podłączonego pliku do zapisu"
+
+msgid "E212: Can't open file for writing"
+msgstr "E212: Nie mogę otworzyć pliku do zapisu"
+
+msgid "E667: Fsync failed"
+msgstr "E667: Fsync nie powiódł się"
+
+msgid "E512: Close failed"
+msgstr "E512: Zamknięcie się nie powiodło"
+
+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ć)"
+
+#, c-format
+msgid ""
+"E513: write error, conversion failed in line %ld (make 'fenc' empty to "
+"override)"
+msgstr ""
+"E513: Błąd zapisu, przemiana się nie powiodła w wierszu %ld (opróżnij 'fenc' "
+"by wymusić)"
+
+msgid "E514: write error (file system full?)"
+msgstr "E514: błąd w zapisie (może system plików jest przepełniony?)"
+
+msgid " CONVERSION ERROR"
+msgstr " BÅÄ„D W PRZEMIANIE"
+
+#, c-format
+msgid " in line %ld;"
+msgstr " w wierszu %ld;"
+
+msgid "[Device]"
+msgstr "[UrzÄ…dzenie]"
+
+msgid "[New]"
+msgstr "[Nowy]"
+
+msgid " [a]"
+msgstr " [a]"
+
+msgid " appended"
+msgstr " dołączono"
+
+msgid " [w]"
+msgstr " [w]"
+
+msgid " written"
+msgstr " zapisano"
+
+msgid "E205: Patchmode: can't save original file"
+msgstr "E205: Patchmode: nie mogę zapisać oryginalnego pliku"
+
+msgid "E206: patchmode: can't touch empty original file"
+msgstr "E206: patchmode: nie mogę stworzyć pustego oryginalnego pliku"
+
+msgid "E207: Can't delete backup file"
+msgstr "E207: Nie mogę skasować pliku zabezpieczenia"
+
+msgid ""
+"\n"
+"WARNING: Original file may be lost or damaged\n"
+msgstr ""
+"\n"
+"OSTRZEŻENIE: Oryginalny plik może zostać utracony lub uszkodzony\n"
+
+msgid "don't quit the editor until the file is successfully written!"
+msgstr "nie wychodź edytora, dopóki plik nie został poprawnie zapisany!"
+
+msgid "[dos]"
+msgstr "[dos]"
+
+msgid "[dos format]"
+msgstr "[format dos-a]"
+
+msgid "[mac]"
+msgstr "[mac]"
+
+msgid "[mac format]"
+msgstr "[format maca]"
+
+msgid "[unix]"
+msgstr "[unix]"
+
+msgid "[unix format]"
+msgstr "[format unixa]"
+
+msgid "1 line, "
+msgstr "1 wiersz, "
+
+#, c-format
+msgid "%ld lines, "
+msgstr "%ld wierszy, "
+
+msgid "1 character"
+msgstr "1 znak"
+
+#, c-format
+msgid "%lld characters"
+msgstr "%lld znaków"
+
+#. Explicit typecast avoids warning on Mac OS X 10.6
+#, c-format
+msgid "%ld characters"
+msgstr "%ld znaków"
+
+msgid "[noeol]"
+msgstr "[noeol]"
+
+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
+msgid "WARNING: The file has been changed since reading it!!!"
+msgstr "OSTRZEŻENIE: Plik zmienił się od czasu ostatniego odczytu!!!"
+
+msgid "Do you really want to write to it"
+msgstr "Czy naprawdę chcesz go zapisać"
+
+#, c-format
+msgid "E208: Error writing to \"%s\""
+msgstr "E208: Błąd zapisywania do \"%s\""
+
+#, c-format
+msgid "E209: Error closing \"%s\""
+msgstr "E209: Błąd w trakcie zamykania \"%s\""
+
+#, c-format
+msgid "E210: Error reading \"%s\""
+msgstr "E210: Błąd odczytu \"%s\""
+
+msgid "E246: FileChangedShell autocommand deleted buffer"
+msgstr "E246: Autokomenda FileChangedShell skasowała bufor"
+
+#, c-format
+msgid "E211: File \"%s\" no longer available"
+msgstr "E211: Plik \"%s\" nie jest dłużej dostępny"
+
+#, 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"
+
+msgid "See \":help W12\" for more info."
+msgstr "Zobacz \":help W12\" dla dalszych informacji."
+
+#, 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"
+
+msgid "See \":help W11\" for more info."
+msgstr "Zobacz \":help W11\" dla dalszych informacji."
+
+#, 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"
+
+msgid "See \":help W16\" for more info."
+msgstr "Zobacz \":help W16\" dla dalszych informacji."
+
+#, 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"
+
+msgid "Warning"
+msgstr "OSTRZEŻENIE"
+
+msgid ""
+"&OK\n"
+"&Load File"
+msgstr ""
+"&OK\n"
+"&Załaduj Plik"
+
+#, c-format
+msgid "E462: Could not prepare for reloading \"%s\""
+msgstr "E462: Nie można przygotować przeładowania \"%s\""
+
+#, c-format
+msgid "E321: Could not reload \"%s\""
+msgstr "E321: Nie można przeładować \"%s\""
+
+msgid "--Deleted--"
+msgstr "--Skasowano--"
+
+#, c-format
+msgid "auto-removing autocommand: %s <buffer=%d>"
+msgstr "auto-usuwanie autokomendy: %s <buffer=%d>"
+
+#. the group doesn't exist
+#, c-format
+msgid "E367: No such group: \"%s\""
+msgstr "E367: Nie ma takiej grupy: \"%s\""
+
+#, c-format
+msgid "E215: Illegal character after *: %s"
+msgstr "E215: Niedopuszczalny znak po *: %s"
+
+#, c-format
+msgid "E216: No such event: %s"
+msgstr "E216: Nie ma takiego wydarzenia: %s"
+
+#, c-format
+msgid "E216: No such group or event: %s"
+msgstr "E216: Nie ma takiej grupy lub wydarzenia: %s"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Auto-Commands ---"
+msgstr ""
+"\n"
+"--- Autokomendy ---"
+
+#, c-format
+msgid "E680: <buffer=%d>: invalid buffer number "
+msgstr "E680: <buffer=%d>: niewłaściwy numer bufora"
+
+msgid "E217: Can't execute autocommands for ALL events"
+msgstr "E217: Nie można wykonywać autokomend dla wydarzeń ALL"
+
+msgid "No matching autocommands"
+msgstr "Brak pasujÄ…cych autokomend"
+
+msgid "E218: autocommand nesting too deep"
+msgstr "E218: zbyt głębokie zagnieżdżenie autokomend"
+
+#, c-format
+msgid "%s Auto commands for \"%s\""
+msgstr "%s Autokomend dla \"%s\""
+
+#, c-format
+msgid "Executing %s"
+msgstr "WykonujÄ™ %s"
+
+#, c-format
+msgid "autocommand %s"
+msgstr "autokomenda %s"
+
+msgid "E219: Missing {."
+msgstr "E219: Brak {."
+
+msgid "E220: Missing }."
+msgstr "E220: Brak }."
+
+msgid "E490: No fold found"
+msgstr "E490: Nie znaleziono zwinięcia"
+
+msgid "E350: Cannot create fold with current 'foldmethod'"
+msgstr "E350: Nie można utworzyć zwinięcia przy bieżącej 'foldmethod'"
+
+msgid "E351: Cannot delete fold with current 'foldmethod'"
+msgstr "E351: Nie można skasować zwinięcia przy bieżącej 'foldmethod'"
+
+#, c-format
+msgid "+--%3ld lines folded "
+msgstr "+--%3ld wierszy zwinięto "
+
+msgid "E222: Add to read buffer"
+msgstr "E222: Dodaj do bufora odczytu"
+
+msgid "E223: recursive mapping"
+msgstr "E223: rekursywne przyporzÄ…dkowanie"
+
+#, c-format
+msgid "E224: global abbreviation already exists for %s"
+msgstr "E224: istnieje już globalny skrót dla %s"
+
+#, c-format
+msgid "E225: global mapping already exists for %s"
+msgstr "E225: istnieje już globalne przyporządkowanie dla %s"
+
+#, c-format
+msgid "E226: abbreviation already exists for %s"
+msgstr "E226: istnieje już skrót dla %s"
+
+#, c-format
+msgid "E227: mapping already exists for %s"
+msgstr "E227: istnieje już przyporządkowanie dla %s"
+
+msgid "No abbreviation found"
+msgstr "Nie znaleziono skrótu"
+
+msgid "No mapping found"
+msgstr "Nie znaleziono przyporzÄ…dkowania"
+
+msgid "E228: makemap: Illegal mode"
+msgstr "E228: makemap: Niedopuszczalny tryb"
+
+msgid "<cannot open> "
+msgstr "<nie mogę otworzyć> "
+
+#, c-format
+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"
+
+#, c-format
+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'"
+
+#, c-format
+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 ""
+"&Yes\n"
+"&No\n"
+"&Cancel"
+msgstr ""
+"&Tak\n"
+"&Nie\n"
+"&Zakończ"
+
+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:"
+
+#. whole word only button
+msgid "Match whole word only"
+msgstr "Dopasuj tylko całe wyrazy"
+
+#. match case button
+msgid "Match case"
+msgstr "Dopasuj wielkość liter"
+
+msgid "Direction"
+msgstr "Kierunek"
+
+#. 'Up' and 'Down' buttons
+msgid "Up"
+msgstr "W górę"
+
+msgid "Down"
+msgstr "W dół"
+
+#. 'Find Next' button
+msgid "Find Next"
+msgstr "Znajdź następne"
+
+#. 'Replace' button
+msgid "Replace"
+msgstr "Zamień"
+
+#. 'Replace All' button
+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"
+
+#, c-format
+msgid "E671: Cannot find window title \"%s\""
+msgstr "E671: Nie mogę znaleźć tytułu okna \"%s\""
+
+#, c-format
+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 '\\')"
+
+#. 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 "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"
+
+#, c-format
+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:"
+
+#, c-format
+msgid "E252: Fontset name: %s"
+msgstr "E252: Nazwa zestawu czcionek: %s"
+
+#, c-format
+msgid "Font '%s' is not fixed-width"
+msgstr "Czcionka '%s' nie posiada znaków jednolitej szerokości"
+
+#, c-format
+msgid "E253: Fontset name: %s"
+msgstr "E253: Nazwa zestawu czcionek: %s"
+
+#, c-format
+msgid "Font0: %s"
+msgstr "Font0: %s"
+
+#, c-format
+msgid "Font1: %s"
+msgstr "Font1: %s"
+
+#, c-format
+msgid "Font%ld width is not twice that of font0"
+msgstr "Szerokość font%ld nie jest podwójną szerokością font0"
+
+#, c-format
+msgid "Font0 width: %ld"
+msgstr "Szerokość font0: %ld"
+
+#, c-format
+msgid "Font1 width: %ld"
+msgstr "Szerokość font1: %ld"
+
+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:"
+
+#. create toggle button
+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 "E550: Missing colon"
+msgstr "E550: Brak dwukropka"
+
+msgid "E551: Illegal component"
+msgstr "E551: Niedozwolona część"
+
+msgid "E552: digit expected"
+msgstr "E552: oczekiwałem na cyfrę"
+
+#, c-format
+msgid "Page %d"
+msgstr "Strona %d"
+
+msgid "No text to be printed"
+msgstr "Brak tekstu do drukowania"
+
+#, c-format
+msgid "Printing page %d (%d%%)"
+msgstr "DrukujÄ™ stronÄ™ %d (%d%%)"
+
+#, c-format
+msgid " Copy %d of %d"
+msgstr " Kopia %d z %d"
+
+#, c-format
+msgid "Printed: %s"
+msgstr "Wydrukowano: %s"
+
+msgid "Printing aborted"
+msgstr "Drukowanie odwołane"
+
+msgid "E455: Error writing to PostScript output file"
+msgstr "E455: Nie można zapisać do wyjściowego pliku PostScriptu"
+
+#, c-format
+msgid "E624: Can't open file \"%s\""
+msgstr "E624: Nie mogę otworzyć pliku \"%s\""
+
+#, c-format
+msgid "E457: Can't read PostScript resource file \"%s\""
+msgstr "E457: Nie można odczytać pliku zasobów PostScriptu \"%s\""
+
+#, c-format
+msgid "E618: file \"%s\" is not a PostScript resource file"
+msgstr "E618: plik \"%s\" nie jest plikiem zasobów PostScriptu"
+
+#, c-format
+msgid "E619: file \"%s\" is not a supported PostScript resource file"
+msgstr "E619: plik \"%s\" nie jest wspieranym plikiem zasobów PostScriptu"
+
+#, c-format
+msgid "E621: \"%s\" resource file has wrong version"
+msgstr "E621: \"%s\" nieprawidłowa wersja pliku zasobów"
+
+msgid "E673: Incompatible multi-byte encoding and character set."
+msgstr "E673: Niekompatybilne kodowanie wielobajtowe i zestaw znaków."
+
+msgid "E674: printmbcharset cannot be empty with multi-byte encoding."
+msgstr "E674: printmbcharset nie może być pusty przy kodowaniu wielobajtowym."
+
+msgid "E675: No default font specified for multi-byte printing."
+msgstr "E675: Nie określono domyślnej czcionki dla drukowania wielobajtowego."
+
+msgid "E324: Can't open PostScript output file"
+msgstr "E324: Nie można otworzyć pliku PostScript do wyjścia"
+
+#, c-format
+msgid "E456: Can't open file \"%s\""
+msgstr "E456: Nie mogę otworzyć pliku \"%s\""
+
+msgid "E456: Can't find PostScript resource file \"prolog.ps\""
+msgstr "E456: Nie można znaleźć pliku zasobów PostScriptu \"prolog.ps\""
+
+msgid "E456: Can't find PostScript resource file \"cidfont.ps\""
+msgstr "E456: Nie można znaleźć pliku zasobów PostScriptu \"cidfont.ps\""
+
+#, c-format
+msgid "E456: Can't find PostScript resource file \"%s.ps\""
+msgstr "E456: Nie można znaleźć pliku zasobów PostScriptu \"%s.ps\""
+
+#, c-format
+msgid "E620: Unable to convert to print encoding \"%s\""
+msgstr "E620: Nie można przekonwertować by drukować kodowanie \"%s\""
+
+msgid "Sending to printer..."
+msgstr "Przesyłam do drukarki..."
+
+msgid "E365: Failed to print PostScript file"
+msgstr "E365: Drukowanie pliku PostScript nie powiodło się"
+
+msgid "Print job sent."
+msgstr "Zadanie drukowanie przesłane."
+
+msgid "Add a new database"
+msgstr "Dodaj nowÄ… bazÄ™ danych"
+
+msgid "Query for a pattern"
+msgstr "Zapytane o wzorzec"
+
+msgid "Show this message"
+msgstr "Pokaż ten komunikat"
+
+msgid "Kill a connection"
+msgstr "Zabij połączenie"
+
+msgid "Reinit all connections"
+msgstr "Ponów wszelkie połączenia"
+
+msgid "Show connections"
+msgstr "Pokaż połączenia"
+
+#, c-format
+msgid "E560: Usage: cs[cope] %s"
+msgstr "E560: Zastosowanie: cs[cope] %s"
+
+msgid "This cscope command does not support splitting the window.\n"
+msgstr "Ta komenda cscope nie wspomaga podzielenia okna.\n"
+
+msgid "E562: Usage: cstag <ident>"
+msgstr "E562: Zastosowanie: cstag <ident>"
+
+msgid "E257: cstag: tag not found"
+msgstr "E257: cstag: nie znaleziono znacznika"
+
+#, c-format
+msgid "E563: stat(%s) error: %d"
+msgstr "E563: stat(%s) błąd: %d"
+
+msgid "E563: stat error"
+msgstr "E563: błąd stat"
+
+#, 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"
+
+#, c-format
+msgid "Added cscope database %s"
+msgstr "Dodano bazÄ™ danych cscope %s"
+
+#, c-format
+msgid "E262: error reading cscope connection %ld"
+msgstr "E262: błąd odczytu połączenia z cscope %ld"
+
+msgid "E561: unknown cscope search type"
+msgstr "E561: nieznany typ szukania cscope"
+
+msgid "E566: Could not create cscope pipes"
+msgstr "E566: Nie mogłem stworzyć potoku do cscope"
+
+msgid "E622: Could not fork for cscope"
+msgstr "E622: Nie mogłem utworzyć rozwidlenia dla cscope"
+
+msgid "cs_create_connection setpgid failed"
+msgstr "nie powiodło się setpgid cs_create_connection"
+
+msgid "cs_create_connection exec failed"
+msgstr "wykonanie cs_create_connection nie powiodło się"
+
+msgid "cs_create_connection: fdopen for to_fp failed"
+msgstr "cs_create_connection: fdopen dla to_fp nie powiodło się"
+
+msgid "cs_create_connection: fdopen for fr_fp failed"
+msgstr "cs_create_connection: fdopen dla fr_fp nie powiodło się"
+
+msgid "E623: Could not spawn cscope process"
+msgstr "E623: Nie mogłem stworzyć procesu cscope"
+
+msgid "E567: no cscope connections"
+msgstr "E567: brak połączenia z cscope"
+
+#, c-format
+msgid "E469: invalid cscopequickfix flag %c for %c"
+msgstr "E469: nieprawidłowa flaga cscopequickfix %c dla %c"
+
+#, c-format
+msgid "E259: no matches found for cscope query %s of %s"
+msgstr "E259: brak dopasowań dla zapytania cscope %s o %s"
+
+msgid "cscope commands:\n"
+msgstr "komendy cscope:\n"
+
+#, c-format
+msgid "%-5s: %s%*s (Usage: %s)"
+msgstr "%-5s: %s%*s (Użycie: %s)"
+
+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"
+
+#, c-format
+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 "E568: duplicate cscope database not added"
+msgstr "E568: nie dodano duplikatu bazy danych cscope"
+
+#, c-format
+msgid "E261: cscope connection %s not found"
+msgstr "E261: nie ma połączenia %s z cscope"
+
+#, c-format
+msgid "cscope connection %s closed"
+msgstr "połączenie %s z cscope zostało zamknięte"
+
+#. should not reach here
+msgid "E570: fatal error in cs_manage_matches"
+msgstr "E570: błąd krytyczny w cs_manage_matches"
+
+#, c-format
+msgid "Cscope tag: %s"
+msgstr "Znacznik cscope: %s"
+
+msgid ""
+"\n"
+" # line"
+msgstr ""
+"\n"
+" # wiersz"
+
+msgid "filename / context / line\n"
+msgstr "nazwa pliku / kontekst / wiersz\n"
+
+#, c-format
+msgid "E609: Cscope error: %s"
+msgstr "E609: Błąd cscope: %s"
+
+msgid "All cscope databases reset"
+msgstr "Wszystkie bazy danych cscope przeładowano"
+
+msgid "no cscope connections\n"
+msgstr "brak połączeń z cscope\n"
+
+msgid " # pid database name prepend path\n"
+msgstr " # pid nazwa bazy danych przedsionek tropu\n"
+
+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"
+
+#, c-format
+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"
+
+#, c-format
+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"
+
+#, c-format
+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"
+
+#. This should never happen. Famous last word?
+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."
+
+#, c-format
+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ę"
+
+#, c-format
+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 "Unknown option argument"
+msgstr "Nieznany argument opcji"
+
+msgid "Too many edit arguments"
+msgstr "Zbyt wiele argumentów"
+
+msgid "Argument missing after"
+msgstr "Brak argumentu po"
+
+msgid "Garbage after option argument"
+msgstr "Åšmiecie po argumencie opcji"
+
+msgid "Too many \"+command\", \"-c command\" or \"--cmd command\" arguments"
+msgstr ""
+"Zbyt wiele argumentów \"+komenda\", \"-c komenda\" lub \"--cmd komenda\""
+
+msgid "Invalid argument for"
+msgstr "Niewłaściwy argument dla"
+
+#, c-format
+msgid "%d files to edit\n"
+msgstr "%d plików do edycji\n"
+
+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 "Attempt to open script file again: \""
+msgstr "Próba ponownego otworzenia pliku skryptu: \""
+
+msgid "Cannot open for reading: \""
+msgstr "Nie mogę otworzyć do odczytu: \""
+
+msgid "Cannot open for script output: \""
+msgstr "Nie mogę otworzyć dla wyjścia skryptu: \""
+
+msgid "Vim: Error: Failure to start gvim from NetBeans\n"
+msgstr "Vim: Błąd: Nie można uruchomić gvim z NetBeans\n"
+
+msgid "Vim: Warning: Output is not to a terminal\n"
+msgstr "Vim: OSTRZEŻENIE: Wyjście nie jest terminalem\n"
+
+msgid "Vim: Warning: Input is not from a terminal\n"
+msgstr "Vim: OSTRZEŻENIE: Wejście nie pochodzi z terminala\n"
+
+#. just in case..
+msgid "pre-vimrc command line"
+msgstr "linia poleceń pre-vimrc"
+
+#, c-format
+msgid "E282: Cannot read from \"%s\""
+msgstr "E282: Nie mogę czytać z \"%s\""
+
+msgid ""
+"\n"
+"More info with: \"vim -h\"\n"
+msgstr ""
+"\n"
+"Dalsze informacje poprzez: \"vim -h\"\n"
+
+msgid "[file ..] edit specified file(s)"
+msgstr "[plik ..] edytuj zadane pliki"
+
+msgid "- read text from stdin"
+msgstr "- czytaj tekst ze stdin"
+
+msgid "-t tag edit file where tag is defined"
+msgstr "-t znacznik edytuj plik, w którym dany znacznik jest zdefiniowany"
+
+msgid "-q [errorfile] edit file with first error"
+msgstr "-q [errorfile] edytuj plik, zawierający pierwszy błąd"
+
+msgid ""
+"\n"
+"\n"
+"usage:"
+msgstr ""
+"\n"
+"\n"
+"użycie:"
+
+msgid " vim [arguments] "
+msgstr " vim [argumenty]"
+
+msgid ""
+"\n"
+" or:"
+msgstr ""
+"\n"
+" lub:"
+
+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 ""
+"\n"
+"\n"
+"Arguments:\n"
+msgstr ""
+"\n"
+"\n"
+"Argumenty:\n"
+
+msgid "--\t\t\tOnly file names after this"
+msgstr "--\t\t\tTylko nazwy plików po tym"
+
+msgid "--literal\t\tDon't expand wildcards"
+msgstr "--literal\t\tNie rozwijaj znaków specjalnych"
+
+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 "-v\t\t\tVi mode (like \"vi\")"
+msgstr "-v\t\t\tTryb vi (jak \"vi\")"
+
+msgid "-e\t\t\tEx mode (like \"ex\")"
+msgstr "-e\t\t\tTryb ex (jak \"ex\")"
+
+msgid "-E\t\t\tImproved Ex mode"
+msgstr "-E\t\t\tUsprawniony tryb Ex"
+
+msgid "-s\t\t\tSilent (batch) mode (only for \"ex\")"
+msgstr "-s\t\t\tCichy tryb (tła) (tylko dla \"ex\")"
+
+msgid "-d\t\t\tDiff mode (like \"vimdiff\")"
+msgstr "-d\t\t\tTryb różnic (jak \"vimdiff\")"
+
+msgid "-y\t\t\tEasy mode (like \"evim\", modeless)"
+msgstr "-y\t\t\tTryb łatwy (jak \"evim\", bez trybów)"
+
+msgid "-R\t\t\tReadonly mode (like \"view\")"
+msgstr "-R\t\t\tTryb wyłącznie do odczytu (jak \"view\")"
+
+msgid "-Z\t\t\tRestricted mode (like \"rvim\")"
+msgstr "-Z\t\t\tTryb ograniczenia (jak \"rvim\")"
+
+msgid "-m\t\t\tModifications (writing files) not allowed"
+msgstr "-m\t\t\tModyfikacje (zapisywanie plików) niedozwolone"
+
+msgid "-M\t\t\tModifications in text not allowed"
+msgstr "-M\t\t\tZakaz modyfikacji tekstu"
+
+msgid "-b\t\t\tBinary mode"
+msgstr "-b\t\t\tTryb binarny"
+
+msgid "-l\t\t\tLisp mode"
+msgstr "-l\t\t\tTryb lisp"
+
+msgid "-C\t\t\tCompatible with Vi: 'compatible'"
+msgstr "-C\t\t\tBądź zgodny z Vi: 'compatible'"
+
+msgid "-N\t\t\tNot fully Vi compatible: 'nocompatible'"
+msgstr "-N\t\t\tBądź niezupełnie zgodny z Vi: 'nocompatible'"
+
+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]"
+
+msgid "-D\t\t\tDebugging mode"
+msgstr "-D\t\t\tTryb odpluskwiania"
+
+msgid "-n\t\t\tNo swap file, use memory only"
+msgstr "-n\t\t\tZamiast pliku wymiany, używaj tylko pamięci"
+
+msgid "-r\t\t\tList swap files and exit"
+msgstr "-r\t\t\tWylicz pliki wymiany i zakończ"
+
+msgid "-r (with file name)\tRecover crashed session"
+msgstr "-r (z nazwą pliku)\tOdtwórz załamaną sesję"
+
+msgid "-L\t\t\tSame as -r"
+msgstr "-L\t\t\tTożsame z -r"
+
+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 "-A\t\t\tstart in Arabic mode"
+msgstr "-A\t\t\trozpocznij w trybie arabskim"
+
+msgid "-H\t\t\tStart in Hebrew mode"
+msgstr "-H\t\t\trozpocznij w trybie hebrajskim"
+
+msgid "-F\t\t\tStart in Farsi mode"
+msgstr "-F\t\t\trozpocznij w trybie farsi"
+
+msgid "-T <terminal>\tSet terminal type to <terminal>"
+msgstr "-T <terminal>\tUstaw typ terminala na <terminal>"
+
+msgid "-u <vimrc>\t\tUse <vimrc> instead of any .vimrc"
+msgstr "-u <vimrc>\t\tUżyj <vimrc> zamiast jakiegokolwiek .vimrc"
+
+msgid "-U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc"
+msgstr "-U <gvimrc>\t\tUżyj <gvimrc> zamiast jakiegokolwiek .gvimrc"
+
+msgid "--noplugin\t\tDon't load plugin scripts"
+msgstr "--noplugin\t\tNie ładuj skryptów wtyczek"
+
+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)"
+
+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)"
+
+msgid "-O[N]\t\tLike -o but split vertically"
+msgstr "-O[N]\t\ttak samo jak -o tylko dziel okno pionowo"
+
+msgid "+\t\t\tStart at end of file"
+msgstr "+\t\t\tZacznij na końcu pliku"
+
+msgid "+<lnum>\t\tStart at line <lnum>"
+msgstr "+<lnum>\t\tZacznij w wierszu <lnum>"
+
+msgid "--cmd <command>\tExecute <command> before loading any vimrc file"
+msgstr ""
+"-cmd <command>\t\tWykonaj komendę <command> przed załadowaniem "
+"jakiegokolwiek pliku vimrc"
+
+msgid "-c <command>\t\tExecute <command> after loading the first file"
+msgstr ""
+"-c <command>\t\tWykonaj komendę <command> po załadowaniu pierwszego pliku"
+
+msgid "-S <session>\t\tSource file <session> after loading the first file"
+msgstr "-S <sesja>\t\tWczytaj plik <sesja> po załadowaniu pierwszego pliku"
+
+msgid "-s <scriptin>\tRead Normal mode commands from file <scriptin>"
+msgstr "-s <scriptin>\tWczytuj komendy trybu normalnego z pliku <scriptin>"
+
+msgid "-w <scriptout>\tAppend all typed commands to file <scriptout>"
+msgstr ""
+"-w <scriptout>\tDołącz wszystkie wprowadzane komendy do pliku <scriptout>"
+
+msgid "-W <scriptout>\tWrite all typed commands to file <scriptout>"
+msgstr ""
+"-W <scriptout>\tZapisuj wszystkie wprowadzane komendy do pliku <scriptout>"
+
+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 "--startuptime <file>\tWrite startup timing messages to <file>"
+msgstr ""
+"--startuptime <plik>\n"
+"Zapisz wiadomości o długości startu do <plik>"
+
+msgid "-i <viminfo>\t\tUse <viminfo> instead of .viminfo"
+msgstr "-i <viminfo>\t\tUżywaj <viminfo> zamiast .viminfo"
+
+msgid "-h or --help\tPrint Help (this message) and exit"
+msgstr "-h lub --help\twyświetl Pomoc (czyli tę wiadomość) i zakończ"
+
+msgid "--version\t\tPrint version information and exit"
+msgstr "--version\t\twyświetl informację o wersji i zakończ"
+
+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"
+
+#. Failed to send, abort.
+msgid ": Send failed.\n"
+msgstr ": Wysłanie nie powiodło się.\n"
+
+#. Let vim start normally.
+msgid ": Send failed. Trying to execute locally\n"
+msgstr ": Wysłanie nie powiodło się. Próbuję wykonać na miejscu\n"
+
+#, c-format
+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 "No marks set"
+msgstr "Brak zakładek"
+
+#, c-format
+msgid "E283: No marks matching \"%s\""
+msgstr "E283: Żadna zakładka nie pasuje do \"%s\""
+
+#. Highlight title
+msgid ""
+"\n"
+"mark line col file/text"
+msgstr ""
+"\n"
+"zakł. wiersz kol plik/tekst"
+
+#. Highlight title
+msgid ""
+"\n"
+" jump line col file/text"
+msgstr ""
+"\n"
+" skok wiersz kol plik/tekst"
+
+#. Highlight title
+msgid ""
+"\n"
+"change line col text"
+msgstr ""
+"\n"
+"zmień wrsz. kol tekst"
+
+msgid ""
+"\n"
+"# File marks:\n"
+msgstr ""
+"\n"
+"# Zakładki w plikach:\n"
+
+#. Write the jumplist with -'
+msgid ""
+"\n"
+"# Jumplist (newest first):\n"
+msgstr ""
+"\n"
+"# Lista odniesień (począwszy od najnowszych):\n"
+
+msgid ""
+"\n"
+"# History of marks within files (newest to oldest):\n"
+msgstr ""
+"\n"
+"# Historia zakładek w plikach (od najnowszych po najstarsze):\n"
+
+msgid "Missing '>'"
+msgstr "Brak '>'"
+
+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 "E293: block was not locked"
+msgstr "E293: blok nie był zablokowany"
+
+msgid "E294: Seek error in swap file read"
+msgstr "E294: Błąd w trakcie czytania pliku wymiany"
+
+msgid "E295: Read error in swap file"
+msgstr "E295: Błąd odczytu pliku wymiany"
+
+msgid "E296: Seek error in swap file write"
+msgstr "E296: Błąd szukania w pliku wymiany"
+
+msgid "E297: Write error in swap file"
+msgstr "E297: Błąd zapisu w pliku wymiany"
+
+msgid "E300: Swap file already exists (symlink attack?)"
+msgstr "E300: Plik wymiany już istnieje (atak symlink?)"
+
+msgid "E298: Didn't get block nr 0?"
+msgstr "E298: Nie otrzymałem bloku nr 0?"
+
+msgid "E298: Didn't get block nr 1?"
+msgstr "E298: Nie otrzymałem bloku nr 1?"
+
+msgid "E298: Didn't get block nr 2?"
+msgstr "E298: Nie otrzymałem bloku nr 2?"
+
+msgid "E843: Error while updating swap file crypt"
+msgstr "E843: Błąd w czasie uaktualniania szyfrowania pliku wymiany"
+
+#. could not (re)open the swap file, what can we do????
+msgid "E301: Oops, lost the swap file!!!"
+msgstr "E301: Ojej, zgubiłem plik wymiany!!!"
+
+msgid "E302: Could not rename swap file"
+msgstr "E302: Nie mogłem zmienić nazwy pliku wymiany"
+
+#, 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"
+
+msgid "E304: ml_upd_block0(): Didn't get block 0??"
+msgstr "E304: ml_upd_block(): Nie otrzymałem bloku 0??"
+
+#, c-format
+msgid "E305: No swap file found for %s"
+msgstr "E305: Nie znaleziono pliku wymiany dla %s"
+
+msgid "Enter number of swap file to use (0 to quit): "
+msgstr "Wprowadź numer pliku wymiany, którego użyć (0 by wyjść): "
+
+#, c-format
+msgid "E306: Cannot open %s"
+msgstr "E306: Nie mogę otworzyć %s"
+
+msgid "Unable to read block 0 from "
+msgstr "Nie mogę odczytać bloku 0 z "
+
+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."
+
+msgid " cannot be used with this version of Vim.\n"
+msgstr " nie może być stosowany z tą wersją Vima.\n"
+
+msgid "Use Vim version 3.0.\n"
+msgstr "Użyj Vima w wersji 3.0.\n"
+
+#, c-format
+msgid "E307: %s does not look like a Vim swap file"
+msgstr "E307: %s nie wyglÄ…da na plik wymiany Vima"
+
+msgid " cannot be used on this computer.\n"
+msgstr " nie może być stosowany na tym komputerze.\n"
+
+msgid "The file was created on "
+msgstr "Ten plik został stworzony na "
+
+msgid ""
+",\n"
+"or the file has been damaged."
+msgstr ""
+",\n"
+"lub plik został uszkodzony."
+
+#, c-format
+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 " has been damaged (page size is smaller than minimum value).\n"
+msgstr ""
+" został uszkodzony (wielkość strony jest mniejsza niż najmniejsza wartość).\n"
+
+#, c-format
+msgid "Using swap file \"%s\""
+msgstr "Używam pliku wymiany \"%s\""
+
+#, c-format
+msgid "Original file \"%s\""
+msgstr "Oryginalny plik \"%s\""
+
+msgid "E308: Warning: Original file may have been changed"
+msgstr "E308: OSTRZEŻENIE: Oryginalny plik mógł być zmieniony"
+
+#, c-format
+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"
+
+#, c-format
+msgid "E309: Unable to read block 1 from %s"
+msgstr "E309: Nie mogę odczytać bloku 1 z %s"
+
+msgid "???MANY LINES MISSING"
+msgstr "???BRAKUJE WIELU WIERSZY"
+
+msgid "???LINE COUNT WRONG"
+msgstr "???LICZNIK WIERSZY NIEZGODNY"
+
+msgid "???EMPTY BLOCK"
+msgstr "???PUSTY BLOK"
+
+msgid "???LINES MISSING"
+msgstr "???BRAKUJE WIERSZY"
+
+#, 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?)"
+
+msgid "???BLOCK MISSING"
+msgstr "???BRAK BLOKU"
+
+msgid "??? from here until ???END lines may be messed up"
+msgstr "??? od tego miejsca po ???KONIEC wiersze mogą być pomieszane"
+
+msgid "??? from here until ???END lines may have been inserted/deleted"
+msgstr "??? od tego miejsca po ???KONIEC wiersze mogą być włożone/skasowane"
+
+msgid "???END"
+msgstr "???KONIEC"
+
+msgid "E311: Recovery Interrupted"
+msgstr "E311: Przerwanie odtwarzania"
+
+msgid ""
+"E312: Errors detected while recovering; look for lines starting with ???"
+msgstr "E312: Wykryto błędy podczas odtwarzania; od których wierszy zacząć ???"
+
+msgid "See \":help E312\" for more information."
+msgstr "Zobacz \":help E312\" dla dalszych informacji."
+
+msgid "Recovery completed. You should check if everything is OK."
+msgstr ""
+"Odtwarzanie zakończono. Powinieneś sprawdzić czy wszystko jest w porządku."
+
+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"
+
+msgid "and run diff with the original file to check for changes)"
+msgstr "i wykonać diff z oryginalnym plikiem aby sprawdzić zmiany)"
+
+msgid "Recovery completed. Buffer contents equals file contents."
+msgstr "Odzyskiwanie zakończone. Zawartość bufora jest równa zawartości pliku."
+
+msgid ""
+"\n"
+"You may want to delete the .swp file now.\n"
+"\n"
+msgstr ""
+"\n"
+"Możesz teraz chcieć usunąć plik .swp.\n"
+"\n"
+
+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"
+
+#. use msg() to start the scrolling properly
+msgid "Swap files found:"
+msgstr "Znalezione pliki wymiany:"
+
+msgid " In current directory:\n"
+msgstr " W bieżącym katalogu:\n"
+
+msgid " Using specified name:\n"
+msgstr " Używam podanej nazwy:\n"
+
+msgid " In directory "
+msgstr " W katalogu "
+
+msgid " -- none --\n"
+msgstr " -- żaden --\n"
+
+msgid " owned by: "
+msgstr " posiadany przez: "
+
+msgid " dated: "
+msgstr " data: "
+
+msgid " dated: "
+msgstr " data: "
+
+msgid " [from Vim version 3.0]"
+msgstr " [po Vimie wersja 3.0]"
+
+msgid " [does not look like a Vim swap file]"
+msgstr " [nie wyglÄ…da na plik wymiany Vima]"
+
+msgid " file name: "
+msgstr " nazwa pliku: "
+
+msgid ""
+"\n"
+" modified: "
+msgstr ""
+"\n"
+" zmieniono: "
+
+msgid "YES"
+msgstr "TAK"
+
+msgid "no"
+msgstr "nie"
+
+msgid ""
+"\n"
+" user name: "
+msgstr ""
+"\n"
+" użytkownik: "
+
+msgid " host name: "
+msgstr " nazwa hosta: "
+
+msgid ""
+"\n"
+" host name: "
+msgstr ""
+"\n"
+" nazwa hosta: "
+
+msgid ""
+"\n"
+" process ID: "
+msgstr ""
+"\n"
+" ID procesu: "
+
+msgid " (still running)"
+msgstr " (dalej działa)"
+
+msgid ""
+"\n"
+" [not usable with this version of Vim]"
+msgstr ""
+"\n"
+" [nie nadaje siÄ™ dla tej wersji Vima]"
+
+msgid ""
+"\n"
+" [not usable on this computer]"
+msgstr ""
+"\n"
+" [nie do użytku na tym komputerze]"
+
+msgid " [cannot be read]"
+msgstr " [nieodczytywalny]"
+
+msgid " [cannot be opened]"
+msgstr " [nieotwieralny]"
+
+msgid "E313: Cannot preserve, there is no swap file"
+msgstr "E313: Nie mogę zabezpieczyć, bo brak pliku wymiany"
+
+msgid "File preserved"
+msgstr "Plik zabezpieczono"
+
+msgid "E314: Preserve failed"
+msgstr "E314: Nieudane zabezpieczenie"
+
+#, c-format
+msgid "E315: ml_get: invalid lnum: %ld"
+msgstr "E315: ml_get: niewłaściwy lnum: %ld"
+
+#, c-format
+msgid "E316: ml_get: cannot find line %ld"
+msgstr "E316: ml_get: nie znaleziono wiersza %ld"
+
+msgid "E317: pointer block id wrong 3"
+msgstr "E317: niepoprawne id wskaźnika bloku 3"
+
+msgid "stack_idx should be 0"
+msgstr "stack_idx powinien być 0"
+
+msgid "E318: Updated too many blocks?"
+msgstr "E318: Zaktualizowano zbyt wiele bloków?"
+
+msgid "E317: pointer block id wrong 4"
+msgstr "E317: niepoprawne id wskaźnika bloku 4"
+
+msgid "deleted block 1?"
+msgstr "blok nr 1 skasowany?"
+
+#, c-format
+msgid "E320: Cannot find line %ld"
+msgstr "E320: Nie mogę znaleźć wiersza %ld"
+
+msgid "E317: pointer block id wrong"
+msgstr "E317: niepoprawne id bloku odniesienia"
+
+msgid "pe_line_count is zero"
+msgstr "pe_line_count wynosi zero"
+
+#, c-format
+msgid "E322: line number out of range: %ld past the end"
+msgstr "E322: numer wiersza poza zakresem: %ld jest poza końcem"
+
+#, c-format
+msgid "E323: line count wrong in block %ld"
+msgstr "E323: liczba wierszy niepoprawna w bloku %ld"
+
+msgid "Stack size increases"
+msgstr "Wielkość stosu wzrasta"
+
+msgid "E317: pointer block id wrong 2"
+msgstr "E317: niepoprawne id bloku odniesienia 2"
+
+#, c-format
+msgid "E773: Symlink loop for \"%s\""
+msgstr "E773: Pętla dowiązań dla \"%s\""
+
+msgid "E325: ATTENTION"
+msgstr "E325: UWAGA"
+
+msgid ""
+"\n"
+"Found a swap file by the name \""
+msgstr ""
+"\n"
+"Znalazłem plik wymiany o nazwie \""
+
+msgid "While opening file \""
+msgstr "Podczas otwierania pliku \""
+
+msgid " NEWER than swap file!\n"
+msgstr " NOWSZE od pliku wymiany!\n"
+
+#. 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.\n"
+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"
+
+msgid " Quit, or continue with caution.\n"
+msgstr " Zakończ lub ostrożnie kontynuuj.\n"
+
+msgid "(2) An edit session for this file crashed.\n"
+msgstr "(2) Sesja edycji dla pliku załamała się.\n"
+
+msgid " If this is the case, use \":recover\" or \"vim -r "
+msgstr " Jeśli tak, to użyj \":recover\" lub \"vim -r "
+
+msgid ""
+"\"\n"
+" to recover the changes (see \":help recovery\").\n"
+msgstr ""
+"\"\n"
+" aby odzyskać zmiany (zobacz \":help recovery)\").\n"
+
+msgid " If you did this already, delete the swap file \""
+msgstr " Jeśli już to zrobiłeś, usuń plik wymiany \""
+
+msgid ""
+"\"\n"
+" to avoid this message.\n"
+msgstr ""
+"\"\n"
+" aby uniknąć tej wiadomości.\n"
+
+msgid "Swap file \""
+msgstr "Plik wymiany \""
+
+msgid "\" already exists!"
+msgstr "\" już istnieje!"
+
+msgid "VIM - ATTENTION"
+msgstr "VIM - UWAGA"
+
+msgid "Swap file already exists!"
+msgstr "Plik wymiany już istnieje!"
+
+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ć"
+
+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ć"
+
+msgid "E326: Too many swap files found"
+msgstr "E326: Znaleziono zbyt wiele plików wymiany"
+
+msgid "E327: Part of menu-item path is not sub-menu"
+msgstr "E327: Część tropu punktu menu nie określa podmenu"
+
+msgid "E328: Menu only exists in another mode"
+msgstr "E328: Menu istnieje tylko w innym trybie"
+
+#, c-format
+msgid "E329: No menu \"%s\""
+msgstr "E329: Nie ma menu \"%s\""
+
+#. Only a mnemonic or accelerator is not valid.
+msgid "E792: Empty menu name"
+msgstr "E792: Pusta nazwa menu"
+
+msgid "E330: Menu path must not lead to a sub-menu"
+msgstr "E330: Trop menu nie może prowadzić do podmenu"
+
+msgid "E331: Must not add menu items directly to menu bar"
+msgstr "E331: Nie wolno dodawać punktów menu wprost do paska menu"
+
+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
+msgid ""
+"\n"
+"--- Menus ---"
+msgstr ""
+"\n"
+"--- Menu ---"
+
+msgid "Tear off this menu"
+msgstr "Oderwij to menu"
+
+msgid "E333: Menu path must lead to a menu item"
+msgstr "E333: Trop menu musi prowadzić do punktu menu"
+
+#, c-format
+msgid "E334: Menu not found: %s"
+msgstr "E334: Nie znaleziono menu: %s"
+
+#, c-format
+msgid "E335: Menu not defined for %s mode"
+msgstr "E335: Menu nie jest zdefiniowane dla trybu %s"
+
+msgid "E336: Menu path must lead to a sub-menu"
+msgstr "E336: Trop menu musi prowadzić do podmenu"
+
+msgid "E337: Menu not found - check menu names"
+msgstr "E337: Nie znaleziono menu - sprawdź nazwy menu"
+
+#, c-format
+msgid "Error detected while processing %s:"
+msgstr "Wykryto błąd podczas przetwarzania %s:"
+
+#, c-format
+msgid "line %4ld:"
+msgstr "wiersz %4ld:"
+
+#, c-format
+msgid "E354: Invalid register name: '%s'"
+msgstr "E354: Niewłaściwa nazwa rejestru: '%s'"
+
+msgid "Messages maintainer: Bram Moolenaar <Bram@vim.org>"
+msgstr "Opiekun komunikatów: Mikołaj Machowski <mikmach@wp.pl>"
+
+msgid "Interrupt: "
+msgstr "Przerwanie: "
+
+msgid "Press ENTER or type command to continue"
+msgstr "Naciśnij ENTER lub wprowadź komendę aby kontynuować"
+
+#, c-format
+msgid "%s line %ld"
+msgstr "%s wiersz %ld"
+
+msgid "-- More --"
+msgstr "-- Więcej --"
+
+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"
+
+msgid "Question"
+msgstr "Pytanie"
+
+msgid ""
+"&Yes\n"
+"&No"
+msgstr ""
+"&Tak\n"
+"&Nie"
+
+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"
+
+msgid "Select Directory dialog"
+msgstr "Dialog wyboru katalogu"
+
+msgid "Save File dialog"
+msgstr "Dialog zapisywania pliku"
+
+msgid "Open File dialog"
+msgstr "Dialog otwierania pliku"
+
+#. TODO: non-GUI file selector here
+msgid "E338: Sorry, no file browser in console mode"
+msgstr "E338: Przykro mi, nie ma przeglądarki plików w trybie konsoli"
+
+msgid "E766: Insufficient arguments for printf()"
+msgstr "E766: Za mało argumentów dla printf()"
+
+msgid "E807: Expected Float argument for printf()"
+msgstr "E807: Spodziewany argument Zmiennoprzecinkowy w printf()"
+
+msgid "E767: Too many arguments to printf()"
+msgstr "E767: Za dużo argumentów dla printf()"
+
+msgid "W10: Warning: Changing a readonly file"
+msgstr "W10: OSTRZEŻENIE: Zmiany w pliku tylko do odczytu"
+
+msgid "Type number and <Enter> or click with mouse (empty cancels): "
+msgstr "Wpisz numer i <Enter> lub wybierz myszą (pusta wartość anuluje): "
+
+msgid "Type number and <Enter> (empty cancels): "
+msgstr "Wpisz numer i <Enter> (puste anuluje): "
+
+msgid "1 more line"
+msgstr "1 wiersz więcej"
+
+msgid "1 line less"
+msgstr "1 wiersz mniej"
+
+#, c-format
+msgid "%ld more lines"
+msgstr "dodano %ld wierszy"
+
+#, c-format
+msgid "%ld fewer lines"
+msgstr "usunięto %ld wierszy"
+
+msgid " (Interrupted)"
+msgstr " (Przerwane)"
+
+msgid "Beep!"
+msgstr "Biiip!"
+
+msgid "Vim: preserving files...\n"
+msgstr "Vim: zachowujÄ™ plik...\n"
+
+#. close all memfiles, without deleting
+msgid "Vim: Finished.\n"
+msgstr "Vim: Zakończono.\n"
+
+msgid "ERROR: "
+msgstr "BÅÄ„D: "
+
+#, c-format
+msgid ""
+"\n"
+"[bytes] total alloc-freed %lu-%lu, in use %lu, peak use %lu\n"
+msgstr ""
+"\n"
+"[bajtów] totalne alokacje-zwolnienia %lu-%lu, w użytku %lu, maksymalne "
+"użycie %lu\n"
+
+#, c-format
+msgid ""
+"[calls] total re/malloc()'s %lu, total free()'s %lu\n"
+"\n"
+msgstr ""
+"[wywołania] wszystkich re/malloc()-ów %lu, wszystkich free()-ów %lu\n"
+"\n"
+
+msgid "E340: Line is becoming too long"
+msgstr "E340: Wiersz staje się zbyt długi"
+
+#, c-format
+msgid "E341: Internal error: lalloc(%ld, )"
+msgstr "E341: Wewnętrzny błąd: lalloc(%ld, )"
+
+#, c-format
+msgid "E342: Out of memory! (allocating %lu bytes)"
+msgstr "E342: Brak pamięci! (rezerwacja %lu bajtów)"
+
+#, c-format
+msgid "Calling shell to execute: \"%s\""
+msgstr "Wywołuję powłokę do wykonania: \"%s\""
+
+msgid "E545: Missing colon"
+msgstr "E545: Brak dwukropka"
+
+msgid "E546: Illegal mode"
+msgstr "E546: Niedozwolony tryb"
+
+msgid "E547: Illegal mouseshape"
+msgstr "E547: Niedozwolony obrys myszki"
+
+msgid "E548: digit expected"
+msgstr "E548: oczekiwałem na cyfrę"
+
+msgid "E549: Illegal percentage"
+msgstr "E549: Niedozwolony procent"
+
+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 "E854: path too long for completion"
+msgstr "E854: ścieżka za długa by uzupełnić"
+
+#, 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'."
+
+#, c-format
+msgid "E344: Can't find directory \"%s\" in cdpath"
+msgstr "E344: Nie mogę znaleźć katalogu \"%s\" w cdpath"
+
+#, c-format
+msgid "E345: Can't find file \"%s\" in path"
+msgstr "E345: Nie mogę znaleźć pliku \"%s\" w tropie"
+
+#, c-format
+msgid "E346: No more directory \"%s\" found in cdpath"
+msgstr "E346: Katalogu \"%s\" nie ma więcej w cdpath"
+
+#, c-format
+msgid "E347: No more file \"%s\" found in path"
+msgstr "E347: Pliku \"%s\" nie ma więcej w tropie"
+
+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"
+
+#, c-format
+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"
+
+#, c-format
+msgid "E658: NetBeans connection lost for buffer %ld"
+msgstr "E658: Bufor %ld 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"
+
+#, c-format
+msgid "E505: %s is read-only (add ! to override)"
+msgstr "E505: %s jest tylko do odczytu (dodaj ! aby wymusić)"
+
+msgid "E349: No identifier under cursor"
+msgstr "E349: Brak identyfikatora pod kursorem"
+
+msgid "E774: 'operatorfunc' is empty"
+msgstr "E774: 'operatorfunc' jest pusta"
+
+msgid "E775: Eval feature not available"
+msgstr "E775: Funkcjonalność eval nie jest dostępna"
+
+msgid "Warning: terminal cannot highlight"
+msgstr "OSTRZEŻENIE: terminal nie wykonuje podświetlania"
+
+msgid "E348: No string under cursor"
+msgstr "E348: Brak ciÄ…gu pod kursorem"
+
+msgid "E352: Cannot erase folds with current 'foldmethod'"
+msgstr "E352: Nie mogę skasować zwinięcia z bieżącą 'foldmethod'"
+
+msgid "E664: changelist is empty"
+msgstr "E664: lista zmian (changelist) jest pusta"
+
+msgid "E662: At start of changelist"
+msgstr "E662: Na poczÄ…tku listy zmian"
+
+msgid "E663: At end of changelist"
+msgstr "E663: Na końcu listy zmian"
+
+msgid "Type :quit<Enter> to exit Vim"
+msgstr "wprowadź :quit<Enter> zakończenie programu"
+
+#, c-format
+msgid "1 line %sed 1 time"
+msgstr "1 wiersz %sed 1 raz"
+
+#, c-format
+msgid "1 line %sed %d times"
+msgstr "1 wiersz %sed %d razy"
+
+#, c-format
+msgid "%ld lines %sed 1 time"
+msgstr "%ld wierszy %sed 1 raz"
+
+#, c-format
+msgid "%ld lines %sed %d times"
+msgstr "%ld wierszy %sed %d razy"
+
+#, c-format
+msgid "%ld lines to indent... "
+msgstr "%ld wierszy do wcięcia... "
+
+msgid "1 line indented "
+msgstr "1 wiersz wcięty "
+
+#, c-format
+msgid "%ld lines indented "
+msgstr "%ld wierszy wciętych "
+
+msgid "E748: No previously used register"
+msgstr "E748: Brak poprzednio użytego rejestru"
+
+#. must display the prompt
+msgid "cannot yank; delete anyway"
+msgstr "nie mogę skopiować, mimo to kasuję"
+
+msgid "1 line changed"
+msgstr "1 wiersz zmieniono"
+
+#, c-format
+msgid "%ld lines changed"
+msgstr "%ld wierszy zmieniono"
+
+#, c-format
+msgid "freeing %ld lines"
+msgstr "zwalniam %ld wierszy"
+
+msgid "block of 1 line yanked"
+msgstr "skopiowano blok 1 wiersza"
+
+msgid "1 line yanked"
+msgstr "1 wiersz skopiowano"
+
+#, c-format
+msgid "block of %ld lines yanked"
+msgstr "%ld wierszy skopiowanych"
+
+#, c-format
+msgid "%ld lines yanked"
+msgstr "%ld wierszy skopiowanych"
+
+#, c-format
+msgid "E353: Nothing in register %s"
+msgstr "E353: Pusty rejestr %s"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Registers ---"
+msgstr ""
+"\n"
+"--- Rejestry ---"
+
+msgid "Illegal register name"
+msgstr "Niedozwolona nazwa rejestru"
+
+msgid ""
+"\n"
+"# Registers:\n"
+msgstr ""
+"\n"
+"# Rejestry:\n"
+
+#, c-format
+msgid "E574: Unknown register type %d"
+msgstr "E574: Nieznany typ rejestru %d"
+
+#, c-format
+msgid "%ld Cols; "
+msgstr "%ld Kolumn; "
+
+#, c-format
+msgid "Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Bytes"
+msgstr "Wybrano %s%ld z %ld Wierszy; %ld z %ld Słów; %ld z %ld Bajtów"
+
+#, c-format
+msgid ""
+"Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Chars; %ld of %ld "
+"Bytes"
+msgstr ""
+"Wybrano %s%ld z %ld Wierszy; %ld z %ld Słów; %ld z %ld Znaków; %ld z %ld "
+"Bajtów"
+
+#, c-format
+msgid "Col %s of %s; Line %ld of %ld; Word %ld of %ld; Byte %ld of %ld"
+msgstr "Kol %s z %s; Wiersz %ld z %ld; Słowo %ld z %ld; Bajt %ld z %ld"
+
+#, c-format
+msgid ""
+"Col %s of %s; Line %ld of %ld; Word %ld of %ld; Char %ld of %ld; Byte %ld of "
+"%ld"
+msgstr ""
+"Kol %s z %s; Wiersz %ld z %ld; Słowo %ld z %ld; Znak %ld z %ld; Bajt %ld z "
+"%ld"
+
+#, c-format
+msgid "(+%ld for BOM)"
+msgstr "(+%ld dla BOM)"
+
+msgid "%<%f%h%m%=Page %N"
+msgstr "%<%f%h%m%=Strona %N"
+
+msgid "Thanks for flying Vim"
+msgstr "Dzięki za lot Vimem"
+
+msgid "E518: Unknown option"
+msgstr "E518: Nieznana opcja"
+
+msgid "E519: Option not supported"
+msgstr "E519: Opcja nie jest wspomagana"
+
+msgid "E520: Not allowed in a modeline"
+msgstr "E520: Niedozwolone w modeline"
+
+msgid "E846: Key code not set"
+msgstr "E846: Kod klucza nie jest ustawiony"
+
+msgid "E521: Number required after ="
+msgstr "E521: Po = wymagany jest numer"
+
+msgid "E522: Not found in termcap"
+msgstr "E522: Nie znaleziono w termcap"
+
+#, c-format
+msgid "E539: Illegal character <%s>"
+msgstr "E539: Niedozwolony znak <%s>"
+
+msgid "E529: Cannot set 'term' to empty string"
+msgstr "E529: Nie mogę ustawić 'term' na pusty ciąg"
+
+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 "E589: 'backupext' and 'patchmode' are equal"
+msgstr "E589: 'backupext' i 'patchmode' są tożsame"
+
+msgid "E834: Conflicts with value of 'listchars'"
+msgstr "E834: Konflikty wartości 'listchars'"
+
+msgid "E835: Conflicts with value of 'fillchars'"
+msgstr "E835: Konflikty wartości 'fillchars'"
+
+msgid "E617: Cannot be changed in the GTK+ 2 GUI"
+msgstr "E617: Nie mogę zmienić w GTK+2 GUI"
+
+msgid "E524: Missing colon"
+msgstr "E524: Brak dwukropka"
+
+msgid "E525: Zero length string"
+msgstr "E525: Ciąg o zerowej długości"
+
+#, c-format
+msgid "E526: Missing number after <%s>"
+msgstr "E526: Brak numeru po <%s>"
+
+msgid "E527: Missing comma"
+msgstr "E527: Brak przecinka"
+
+msgid "E528: Must specify a ' value"
+msgstr "E528: Musi określać wartość '"
+
+msgid "E595: contains unprintable or wide character"
+msgstr "E595: zawiera niewyświetlalny lub szeroki znak"
+
+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"
+
+#, c-format
+msgid "E535: Illegal character after <%c>"
+msgstr "E535: Niedozwolony znak po <%c>"
+
+msgid "E536: comma required"
+msgstr "E536: wymagany przecinek"
+
+#, c-format
+msgid "E537: 'commentstring' must be empty or contain %s"
+msgstr "E537: 'commentstring' musi być pusty lub zawierać %s"
+
+msgid "E538: No mouse support"
+msgstr "E538: Brak wspomagania myszki"
+
+msgid "E540: Unclosed expression sequence"
+msgstr "E540: Niedomknięty ciąg wyrażeń"
+
+msgid "E541: too many items"
+msgstr "E541: zbyt wiele elementów"
+
+msgid "E542: unbalanced groups"
+msgstr "E542: niezbalansowane grupy"
+
+msgid "E590: A preview window already exists"
+msgstr "E590: okno podglądu już istnieje"
+
+msgid "W17: Arabic requires UTF-8, do ':set encoding=utf-8'"
+msgstr "W17: Arabski wymaga UTF-8, zrób ':set encoding=utf-8'"
+
+#, c-format
+msgid "E593: Need at least %d lines"
+msgstr "E593: PotrzebujÄ™ przynajmniej %d wierszy"
+
+#, c-format
+msgid "E594: Need at least %d columns"
+msgstr "E594: PotrzebujÄ™ przynajmniej %d kolumn"
+
+#, 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.
+#, c-format
+msgid "E521: Number required: &%s = '%s'"
+msgstr "E521: Wymagana Liczba: &%s = '%s'"
+
+msgid ""
+"\n"
+"--- Terminal codes ---"
+msgstr ""
+"\n"
+"--- Kody terminala ---"
+
+msgid ""
+"\n"
+"--- Global option values ---"
+msgstr ""
+"\n"
+"--- Globalne wartości opcji ---"
+
+msgid ""
+"\n"
+"--- Local option values ---"
+msgstr ""
+"\n"
+"--- Lokalne wartości opcji ---"
+
+msgid ""
+"\n"
+"--- Options ---"
+msgstr ""
+"\n"
+"--- Opcje ---"
+
+msgid "E356: get_varp ERROR"
+msgstr "E356: BÅÄ„D get_varp"
+
+#, c-format
+msgid "E357: 'langmap': Matching character missing for %s"
+msgstr "E357: 'langmap': Brak pasujÄ…cego znaku dla %s"
+
+#, c-format
+msgid "E358: 'langmap': Extra characters after semicolon: %s"
+msgstr "E358: 'langmap': Dodatkowe znaki po średniku: %s"
+
+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"
+
+#, c-format
+msgid "Need %s version %ld\n"
+msgstr "PotrzebujÄ™ %s w wersji %ld\n"
+
+msgid "Cannot open NIL:\n"
+msgstr "Nie mogę otworzyć NIL:\n"
+
+msgid "Cannot create "
+msgstr "Nie mogę stworzyć "
+
+#, c-format
+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"
+
+#. if Vim opened a window: Executing a shell may cause crashes
+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ę"
+
+#, c-format
+msgid "to %s on %s"
+msgstr "do %s z %s"
+
+#, c-format
+msgid "E613: Unknown printer font: %s"
+msgstr "E613: Nieznana czcionka drukarki: %s"
+
+#, c-format
+msgid "E238: Print error: %s"
+msgstr "E238: Błąd drukarki: %s"
+
+#, c-format
+msgid "Printing '%s'"
+msgstr "Wydrukowano '%s'"
+
+#, c-format
+msgid "E244: Illegal charset name \"%s\" in font name \"%s\""
+msgstr ""
+"E244: Niedozwolona nazwa zestawu znaków \"%s\" w nazwie czcionki \"%s\""
+
+#, c-format
+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"
+
+#, c-format
+msgid "Vim: Caught deadly signal %s\n"
+msgstr "Vim: Załapał śmiertelny sygnał %s\n"
+
+#, c-format
+msgid "Vim: Caught deadly signal\n"
+msgstr "Vim: Załapał śmiertelny sygnał\n"
+
+#, c-format
+msgid "Opening the X display took %ld msec"
+msgstr "Otwieranie ekranu X trwało %ld 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"
+"Could not get security context for "
+msgstr ""
+"\n"
+"Nie mogę uzyskać kontekstu bezpieczeństwa dla"
+
+msgid ""
+"\n"
+"Could not set security context for "
+msgstr ""
+"\n"
+"Nie można uzyskać kontekstu bezpieczeństwa dla"
+
+msgid ""
+"\n"
+"Cannot execute shell "
+msgstr ""
+"\n"
+"Nie mogę wykonać powłoki "
+
+msgid ""
+"\n"
+"Cannot execute shell sh\n"
+msgstr ""
+"\n"
+"Nie mogę wykonać powłoki sh\n"
+
+msgid ""
+"\n"
+"shell returned "
+msgstr ""
+"\n"
+"powłoka zwróciła "
+
+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"
+
+#, c-format
+msgid "dlerror = \"%s\""
+msgstr "dlerror = \"%s\""
+
+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ę"
+
+#, c-format
+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!"
+
+#, c-format
+msgid "shell returned %d"
+msgstr "powłoka zwróciła %d"
+
+#, c-format
+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"
+
+#, c-format
+msgid "E372: Too many %%%c in format string"
+msgstr "E372: Zbyt wiele %%%c w ciÄ…gu formatujÄ…cym"
+
+#, c-format
+msgid "E373: Unexpected %%%c in format string"
+msgstr "E373: Nieoczekiwane %%%c w ciÄ…gu formatujÄ…cym"
+
+msgid "E374: Missing ] in format string"
+msgstr "E374: Brak ] w ciÄ…gu formatujÄ…cym"
+
+#, c-format
+msgid "E375: Unsupported %%%c in format string"
+msgstr "E375: Niewspomagane %%%c w ciÄ…gu formatujÄ…cym"
+
+#, c-format
+msgid "E376: Invalid %%%c in format string prefix"
+msgstr "E376: Niepoprawne %%%c w prefiksie ciÄ…gu formatujÄ…cego"
+
+#, c-format
+msgid "E377: Invalid %%%c in format string"
+msgstr "E377: Niepoprawne %%%c w ciÄ…gu formatujÄ…cym"
+
+msgid "E378: 'errorformat' contains no pattern"
+msgstr "E378: 'errorformat' nie zawiera wzorca"
+
+msgid "E379: Missing or empty directory name"
+msgstr "E379: Pusta nazwa katalogu lub jej brak"
+
+msgid "E553: No more items"
+msgstr "E553: Nie ma więcej elementów"
+
+#, c-format
+msgid "(%d of %d)%s%s: "
+msgstr "(%d z %d)%s%s: "
+
+msgid " (line deleted)"
+msgstr " (wiersz skasowany)"
+
+msgid "E380: At bottom of quickfix stack"
+msgstr "E380: Na dole stosu quickfix"
+
+msgid "E381: At top of quickfix stack"
+msgstr "E381: Na górze stosu quickfix"
+
+#, c-format
+msgid "error list %d of %d; %d errors"
+msgstr "lista błędów %d z %d; %d błędów"
+
+msgid "E382: Cannot write, 'buftype' option is set"
+msgstr "E382: Nie mogę zapisać, opcja 'buftype' jest ustawiona"
+
+msgid "Error file"
+msgstr "Plik błędu"
+
+msgid "E683: File name missing or invalid pattern"
+msgstr "E683: Brak nazwy pliku lub niewłaściwa ścieżka"
+
+#, c-format
+msgid "Cannot open file \"%s\""
+msgstr "Nie mogę otworzyć pliku \"%s\""
+
+msgid "E681: Buffer is not loaded"
+msgstr "E681: Bufor nie jest załadowany"
+
+msgid "E777: String or List expected"
+msgstr "E777: Oczekiwałem na łańcuch lub listę"
+
+#, c-format
+msgid "E369: invalid item in %s%%[]"
+msgstr "E369: Niewłaściwy element w %s%%[]"
+
+#, c-format
+msgid "E769: Missing ] after %s["
+msgstr "E769: Brak ] po %s["
+
+#, c-format
+msgid "E53: Unmatched %s%%("
+msgstr "E53: Niesparowany %s%%("
+
+#, c-format
+msgid "E54: Unmatched %s("
+msgstr "E54: Niesparowany %s("
+
+#, c-format
+msgid "E55: Unmatched %s)"
+msgstr "E55: Niesparowany %s)"
+
+msgid "E66: \\z( not allowed here"
+msgstr "E66: \\z( jest niedozwolone w tym miejscu"
+
+msgid "E67: \\z1 et al. not allowed here"
+msgstr "E67: \\z1 i podobne sÄ… niedozwolone w tym miejscu"
+
+#, c-format
+msgid "E69: Missing ] after %s%%["
+msgstr "E69: Brak ] po %s%%["
+
+#, c-format
+msgid "E70: Empty %s%%[]"
+msgstr "E70: Pusty %s%%[]"
+
+msgid "E339: Pattern too long"
+msgstr "E339: Zbyt długi wzorzec"
+
+msgid "E50: Too many \\z("
+msgstr "E50: Zbyt wiele \\z("
+
+#, c-format
+msgid "E51: Too many %s("
+msgstr "E51: Zbyt wiele %s("
+
+msgid "E52: Unmatched \\z("
+msgstr "E52: Niesparowany \\z("
+
+#, c-format
+msgid "E59: invalid character after %s@"
+msgstr "E59: niedozwolony znak po %s@"
+
+#, c-format
+msgid "E60: Too many complex %s{...}s"
+msgstr "E60: Zbyt wiele złożonych %s{...}"
+
+#, c-format
+msgid "E61: Nested %s*"
+msgstr "E61: Zagnieżdżone %s*"
+
+#, c-format
+msgid "E62: Nested %s%c"
+msgstr "E62: Zagnieżdżone %s%c"
+
+msgid "E63: invalid use of \\_"
+msgstr "E63: Niedozwolone użycie \\_"
+
+#, c-format
+msgid "E64: %s%c follows nothing"
+msgstr "E64: %s%c po niczym"
+
+msgid "E65: Illegal back reference"
+msgstr "E65: Niewłaściwe odwołanie wsteczne"
+
+msgid "E68: Invalid character after \\z"
+msgstr "E68: niedopuszczalny znak po \\z"
+
+#, c-format
+msgid "E678: Invalid character after %s%%[dxouU]"
+msgstr "E678: Niedozwolony znak po %s%%[dxouU]"
+
+#, c-format
+msgid "E71: Invalid character after %s%%"
+msgstr "E71: Niedozwolony znak po %s%%"
+
+#, c-format
+msgid "E554: Syntax error in %s{...}"
+msgstr "E554: Błąd składni w %s{...}"
+
+msgid "External submatches:\n"
+msgstr "Zewnętrzne poddopasowania:\n"
+
+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"
+
+#, c-format
+msgid "E866: (NFA regexp) Misplaced %c"
+msgstr "E866: (wyrażenie regularne NFA) Niepoprawnie umieszczone %c"
+
+msgid "E865: (NFA) Regexp end encountered prematurely"
+msgstr "E865: (NFA) przedwczesny koniec wyrażenia regularnego"
+
+#, c-format
+msgid "E867: (NFA) Unknown operator '\\z%c'"
+msgstr "E867: (NFA) Nieznany operator '\\z%c'"
+
+#, c-format
+msgid "E867: (NFA) Unknown operator '\\%%%c'"
+msgstr "E867: (NFA) Nieznany operator '\\%%%c'"
+
+#. should never happen
+msgid "E868: Error building NFA with equivalence class!"
+msgstr "E868: Błąd przy budowwaniu NFA z klasą ekwiwalencji"
+
+#, c-format
+msgid "E869: (NFA) Unknown operator '\\@%c'"
+msgstr "E869: (NFA) Nieznany operator '\\@%c'"
+
+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.
+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 `('
+msgid "E872: (NFA regexp) Too many '('"
+msgstr "E872: (wyrażenie regularne NFA) Zbyt dużo '('"
+
+msgid "E879: (NFA regexp) Too many \\z("
+msgstr "E879: (wyrażenie regularne NFA) Za dużo \\z("
+
+msgid "E873: (NFA regexp) proper termination error"
+msgstr "E873: (wyrażenie regularne NFA) błąd poprawnego zakończenia"
+
+msgid "E874: (NFA) Could not pop the stack !"
+msgstr "E874: (NFA) Nie można zdjąć elementu ze stosu!"
+
+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"
+
+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 "
+
+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 ""
+"Could not open temporary log file for writing, displaying on stderr ... "
+msgstr "Nie można otworzyć do zapisu tymczasowego pliku, pokazuję na stderr... "
+
+#, c-format
+msgid "(NFA) COULD NOT OPEN %s !"
+msgstr "(NFA) NIE MOŻNA OTWORZYĆ %s !"
+
+msgid "Could not open temporary log file for writing "
+msgstr "Nie można otworzyć do zapisu tymczasowego pliku logowania"
+
+msgid " VREPLACE"
+msgstr " V-ZAMIANA"
+
+msgid " REPLACE"
+msgstr " ZAMIANA"
+
+msgid " REVERSE"
+msgstr " NEGATYW"
+
+msgid " INSERT"
+msgstr " WPROWADZANIE"
+
+msgid " (insert)"
+msgstr " (wprowadzanie)"
+
+msgid " (replace)"
+msgstr " (zamiana)"
+
+msgid " (vreplace)"
+msgstr " (v-zamiana)"
+
+msgid " Hebrew"
+msgstr " Hebrajski"
+
+msgid " Arabic"
+msgstr " Arabski"
+
+msgid " (lang)"
+msgstr " (język)"
+
+msgid " (paste)"
+msgstr " (wklejanie)"
+
+msgid " VISUAL"
+msgstr " WIZUALNY"
+
+msgid " VISUAL LINE"
+msgstr " WIZUALNY LINIOWY"
+
+msgid " VISUAL BLOCK"
+msgstr " WIZUALNY BLOKOWY"
+
+msgid " SELECT"
+msgstr " ZAZNACZANIE"
+
+msgid " SELECT LINE"
+msgstr " ZAZNACZANIE LINIOWE"
+
+msgid " SELECT BLOCK"
+msgstr " ZAZNACZANIE BLOKOWE"
+
+msgid "recording"
+msgstr "zapis"
+
+#, c-format
+msgid "E383: Invalid search string: %s"
+msgstr "E383: Niewłaściwy ciąg do szukania: %s"
+
+#, c-format
+msgid "E384: search hit TOP without match for: %s"
+msgstr "E384: szukanie dobiło GÓRY bez znalezienia: %s"
+
+#, c-format
+msgid "E385: search hit BOTTOM without match for: %s"
+msgstr "E385: szukanie dobiło KOŃCA bez znalezienia : %s"
+
+msgid "E386: Expected '?' or '/' after ';'"
+msgstr "E386: OczekujÄ™ '?' lub '/' po ';'"
+
+msgid " (includes previously listed match)"
+msgstr " (zawiera poprzednio wymienione dopasowanie)"
+
+#. cursor at status line
+msgid "--- Included files "
+msgstr "--- Zawarte pliki "
+
+msgid "not found "
+msgstr "nie znaleziono"
+
+msgid "in path ---\n"
+msgstr "w tropie ---\n"
+
+msgid " (Already listed)"
+msgstr " (Już wymienione)"
+
+msgid " NOT FOUND"
+msgstr " NIE ZNALEZIONO"
+
+#, c-format
+msgid "Scanning included file: %s"
+msgstr "Przegląd włączonego pliku: %s"
+
+#, c-format
+msgid "Searching included file %s"
+msgstr "Przeszukiwanie włączonego pliku %s"
+
+msgid "E387: Match is on current line"
+msgstr "E387: Wzorzec pasuje w bieżącym wierszu"
+
+msgid "All included files were found"
+msgstr "Wszelkie włączane pliki odnaleziono"
+
+msgid "No included files"
+msgstr "Brak włączanych plików"
+
+msgid "E388: Couldn't find definition"
+msgstr "E388: Nie znalazłem definicji"
+
+msgid "E389: Couldn't find pattern"
+msgstr "E389: Nie znalazłem wzorca"
+
+msgid "Substitute "
+msgstr "Podstawienie "
+
+#, c-format
+msgid ""
+"\n"
+"# Last %sSearch Pattern:\n"
+"~"
+msgstr ""
+"\n"
+"# Ostatni %sWyszukiwany wzorzec:\n"
+"~"
+
+msgid "E759: Format error in spell file"
+msgstr "E759: Nieprawidłowy format pliku sprawdzania pisowni"
+
+msgid "E758: Truncated spell file"
+msgstr "E758: Obcięty plik sprawdzania pisowni"
+
+#, c-format
+msgid "Trailing text in %s line %d: %s"
+msgstr "Zbędny tekst w %s wiersz %d: %s"
+
+#, c-format
+msgid "Affix name too long in %s line %d: %s"
+msgstr "Za długa nazwa afiksu w %s wiersz %d: %s"
+
+msgid "E761: Format error in affix file FOL, LOW or UPP"
+msgstr "E761: Błąd formatu w pliku afiksów FOL, LOW lub UPP"
+
+msgid "E762: Character in FOL, LOW or UPP is out of range"
+msgstr "E762: Znak w FOL, LOW lub UPP jest poza zasięgiem"
+
+msgid "Compressing word tree..."
+msgstr "Kompresja drzewa słów..."
+
+msgid "E756: Spell checking is not enabled"
+msgstr "E756: Sprawdzanie pisowni nie jest włączone"
+
+#, 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\""
+
+#, 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\""
+
+#, c-format
+msgid "Reading spell file \"%s\""
+msgstr "OdczytujÄ™ plik sprawdzania pisowni \"%s\""
+
+msgid "E757: This does not look like a spell file"
+msgstr "E757: To nie wyglÄ…da na plik sprawdzania pisowni"
+
+msgid "E771: Old spell file, needs to be updated"
+msgstr "E771: Stary plik sprawdzania pisowni, wymagane uaktualnienie"
+
+msgid "E772: Spell file is for newer version of Vim"
+msgstr "E772: Plik sprawdzania pisowni dla nowszej wersji Vima"
+
+msgid "E770: Unsupported section in spell file"
+msgstr "E770: Niewspierana sekcja w pliku sprawdzania pisowni"
+
+#, c-format
+msgid "Warning: region %s not supported"
+msgstr "Ostrzeżenie: region %s nie jest wspierany"
+
+#, c-format
+msgid "Reading affix file %s ..."
+msgstr "Czytam plik afiksów %s ..."
+
+#, 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"
+
+#, c-format
+msgid "Conversion in %s not supported: from %s to %s"
+msgstr "Konwersja w %s nie jest wspierana: od %s do %s"
+
+#, c-format
+msgid "Conversion in %s not supported"
+msgstr "Konwersja w %s nie jest wspierana"
+
+#, c-format
+msgid "Invalid value for FLAG in %s line %d: %s"
+msgstr "Nieprawidłowa wartość FLAG w %s wierz %d: %s"
+
+#, c-format
+msgid "FLAG after using flags in %s line %d: %s"
+msgstr "FLAG po użyciu flag w %s wiersz %d: %s"
+
+#, 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"
+
+#, 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"
+
+#, c-format
+msgid "Wrong COMPOUNDRULES value in %s line %d: %s"
+msgstr "Zła wartość COMPOUNDRULES w %s wiersz %d: %s"
+
+#, c-format
+msgid "Wrong COMPOUNDWORDMAX value in %s line %d: %s"
+msgstr "Zła wartość COMPOUNDWORDMAX w %s wiersz %d: %s"
+
+#, c-format
+msgid "Wrong COMPOUNDMIN value in %s line %d: %s"
+msgstr "Zła wartość COMPOUNDMIM w %s wiersz %d: %s"
+
+#, c-format
+msgid "Wrong COMPOUNDSYLMAX value in %s line %d: %s"
+msgstr "Zła wartość COMPOUNDSYLMAX w %s wiersz %d: %s"
+
+#, c-format
+msgid "Wrong CHECKCOMPOUNDPATTERN value in %s line %d: %s"
+msgstr "Zła wartość CHECKCOMPOUNDPATTERN w %s wiersz %d: %s"
+
+#, 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"
+
+#, c-format
+msgid "Duplicate affix in %s line %d: %s"
+msgstr "Powtórzony afiks w %s wiersz %d: %s"
+
+#, 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"
+
+#, c-format
+msgid "Expected Y or N in %s line %d: %s"
+msgstr "Oczekiwano Y lub N w %s wierszu %d: %s"
+
+#, c-format
+msgid "Broken condition in %s line %d: %s"
+msgstr "Błędny warunek w %s wiersz %d: %s"
+
+#, c-format
+msgid "Expected REP(SAL) count in %s line %d"
+msgstr "Oczekiwano ilości REP(SAL) w %s wierszu %d"
+
+#, c-format
+msgid "Expected MAP count in %s line %d"
+msgstr "Oczekiwano ilości MAP w %s wierszu %d"
+
+#, c-format
+msgid "Duplicate character in MAP in %s line %d"
+msgstr "Powtórzony znak w MAP w %s wierszu %d"
+
+#, c-format
+msgid "Unrecognized or duplicate item in %s line %d: %s"
+msgstr "Nieznany lub powtórzony element w %s wierszu %d: %s"
+
+#, c-format
+msgid "Missing FOL/LOW/UPP line in %s"
+msgstr "Brak wiersza FOL/LOW/UPP w %s"
+
+msgid "COMPOUNDSYLMAX used without SYLLABLE"
+msgstr "COMPOUNDSYLMAX użyty bez SYLLABLE"
+
+msgid "Too many postponed prefixes"
+msgstr "Zbyt wiele opóźnionych prefiksów"
+
+msgid "Too many compound flags"
+msgstr "Zbyt wiele flag złożeń"
+
+msgid "Too many postponed prefixes and/or compound flags"
+msgstr "Zbyt wiele opóźnionych prefiksów i/lub flag złożeń"
+
+#, c-format
+msgid "Missing SOFO%s line in %s"
+msgstr "Brak wiersza SOFO%s wiersz w %s"
+
+#, c-format
+msgid "Both SAL and SOFO lines in %s"
+msgstr "Wiersze SAL i SOFO w %s"
+
+#, c-format
+msgid "Flag is not a number in %s line %d: %s"
+msgstr "Flaga nie jest liczbÄ… w %s wiersz %d: %s"
+
+#, c-format
+msgid "Illegal flag in %s line %d: %s"
+msgstr "Nieprawidłowa flaga w %s wiersz %d: %s"
+
+#, 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"
+
+#, c-format
+msgid "Reading dictionary file %s ..."
+msgstr "Czytam plik słownika %s ..."
+
+#, c-format
+msgid "E760: No word count in %s"
+msgstr "E760: Brak ilości słów w %s"
+
+#, c-format
+msgid "line %6d, word %6d - %s"
+msgstr "wiersz %6d, słowo %6d - %s"
+
+# c-format
+#, c-format
+msgid "Duplicate word in %s line %d: %s"
+msgstr "Powtórzony wyraz w %s wierszu %d: %s"
+
+# c-format
+#, c-format
+msgid "First duplicate word in %s line %d: %s"
+msgstr "Pierwszy powtórzony wyraz w %s wiersz %d: %s"
+
+# c-format
+#, c-format
+msgid "%d duplicate word(s) in %s"
+msgstr "%d powtórzony(ch) wyraz(ów) w %s"
+
+#, 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"
+
+#, c-format
+msgid "Reading word file %s ..."
+msgstr "Odczytuję plik wyrazów %s ..."
+
+#, c-format
+msgid "Duplicate /encoding= line ignored in %s line %d: %s"
+msgstr "Zignorowano powtórzony wiersz /encoding= w %s wierszu %d: %s"
+
+#, c-format
+msgid "/encoding= line after word ignored in %s line %d: %s"
+msgstr "Zignorowano wiersz /encoding= po wyrazie w %s wierszu %d: %s"
+
+#, c-format
+msgid "Duplicate /regions= line ignored in %s line %d: %s"
+msgstr "Powtórzony wiersz /regions= zignorowano w %s wierszu %d: %s"
+
+#, c-format
+msgid "Too many regions in %s line %d: %s"
+msgstr "Za dużo regionów w %s wiersz %d: %s"
+
+#, c-format
+msgid "/ line ignored in %s line %d: %s"
+msgstr "wiersz / zignorowano w %s wierszu %d: %s"
+
+#, c-format
+msgid "Invalid region nr in %s line %d: %s"
+msgstr "Nieprawidłowy numer regionu w %s wierszu %d: %s"
+
+#, c-format
+msgid "Unrecognized flags in %s line %d: %s"
+msgstr "Nieznane flagi w %s wiersz %d: %s"
+
+#, c-format
+msgid "Ignored %d words with non-ASCII characters"
+msgstr "Zignorowałem %d słów ze znakami nie ASCII"
+
+msgid "E845: Insufficient memory, word list will be incomplete"
+msgstr "E845: Nie wystarczająca ilość pamięci, lista słów będzie niekompletna"
+
+#, c-format
+msgid "Compressed %d of %d nodes; %d (%d%%) remaining"
+msgstr "Skompresowano %d z %d węzłów; pozostaje %d (%d%%)"
+
+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.
+#.
+msgid "Performing soundfolding..."
+msgstr "Wykonuję kompresję dźwiękową..."
+
+#, c-format
+msgid "Number of words after soundfolding: %ld"
+msgstr "Liczba słów po kompresji dźwiękowej: %ld"
+
+#, c-format
+msgid "Total number of words: %d"
+msgstr "Całkowita liczba słów: %d"
+
+#, c-format
+msgid "Writing suggestion file %s ..."
+msgstr "ZapisujÄ™ plik sugestii %s ..."
+
+#, c-format
+msgid "Estimated runtime memory use: %d bytes"
+msgstr "Oczekiwane zużycie pamięci: %d bajtów"
+
+msgid "E751: Output file name must not have region name"
+msgstr "E751: Nazwa pliku wynikowego nie może być nazwą regionu"
+
+msgid "E754: Only up to 8 regions supported"
+msgstr "E754: Wspieram tylko 8 regionów"
+
+#, c-format
+msgid "E755: Invalid region in %s"
+msgstr "E755: Nieprawidłowy region w %s"
+
+msgid "Warning: both compounding and NOBREAK specified"
+msgstr "Ostrzeżenie: określono zarówno złożenia jak i NOBREAK"
+
+#, c-format
+msgid "Writing spell file %s ..."
+msgstr "ZapisujÄ™ plik sprawdzania pisowni %s ..."
+
+msgid "Done!"
+msgstr "Zrobione!"
+
+#, c-format
+msgid "E765: 'spellfile' does not have %ld entries"
+msgstr "E765: 'spellfile' nie posiada wpisów %ld"
+
+#, c-format
+msgid "Word removed from %s"
+msgstr "Usunięto słowo z %s"
+
+#, c-format
+msgid "Word added to %s"
+msgstr "Dodano słowo do %s"
+
+msgid "E763: Word characters differ between spell files"
+msgstr "E763: Znaki wyrazów różnią się między plikami sprawdzania pisowni"
+
+msgid "Sorry, no suggestions"
+msgstr "Przykro mi, brak podpowiedzi"
+
+#, c-format
+msgid "Sorry, only %ld suggestions"
+msgstr "Przykro mi, tylko %ld podpowiedzi"
+
+#. for when 'cmdheight' > 1
+#. avoid more prompt
+#, c-format
+msgid "Change \"%.*s\" to:"
+msgstr "Zmień \"%.*s\" na:"
+
+#, c-format
+msgid " < \"%.*s\""
+msgstr " < \"%.*s\""
+
+msgid "E752: No previous spell replacement"
+msgstr "E752: Brak poprzednich podmian sprawdzania pisowni"
+
+#, c-format
+msgid "E753: Not found: %s"
+msgstr "E753: Nie znaleziono: %s"
+
+#, c-format
+msgid "E778: This does not look like a .sug file: %s"
+msgstr "E778: Ten plik nie wyglÄ…da na plik .sug: %s"
+
+#, c-format
+msgid "E779: Old .sug file, needs to be updated: %s"
+msgstr "E779: Stary plik .sug, konieczne jest uaktualnienie: %s"
+
+#, c-format
+msgid "E780: .sug file is for newer version of Vim: %s"
+msgstr "E780: Plik .sug dla nowszej wersji Vima: %s"
+
+#, c-format
+msgid "E781: .sug file doesn't match .spl file: %s"
+msgstr "E781: Plik .sug nie pasuje do pliku .spl: %s"
+
+#, 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.
+msgid "E783: duplicate char in MAP entry"
+msgstr "E783: Podwojony znak we wpisie MAP"
+
+msgid "No Syntax items defined for this buffer"
+msgstr "Brak elementów składni określonych dla tego bufora"
+
+#, c-format
+msgid "E390: Illegal argument: %s"
+msgstr "E390: Niedozwolony argument: %s"
+
+#, c-format
+msgid "E391: No such syntax cluster: %s"
+msgstr "E391: Nie ma takiego klastra składni: %s"
+
+msgid "syncing on C-style comments"
+msgstr "synchronizacja komentarzy w stylu C"
+
+msgid "no syncing"
+msgstr "brak synchronizacji"
+
+msgid "syncing starts "
+msgstr "poczÄ…tek synchronizacji"
+
+msgid " lines before top line"
+msgstr " wierszy przed górną linią"
+
+msgid ""
+"\n"
+"--- Syntax sync items ---"
+msgstr ""
+"\n"
+"--- Elementy synchronizacji składni ---"
+
+msgid ""
+"\n"
+"syncing on items"
+msgstr ""
+"\n"
+"synchronizujÄ™ na elementach"
+
+msgid ""
+"\n"
+"--- Syntax items ---"
+msgstr ""
+"\n"
+"--- Elementy składni ---"
+
+#, c-format
+msgid "E392: No such syntax cluster: %s"
+msgstr "E392: Nie ma takiego klastra składni: %s"
+
+msgid "minimal "
+msgstr "minimalnie "
+
+msgid "maximal "
+msgstr "maksymalnie "
+
+msgid "; match "
+msgstr "; pasuje "
+
+msgid " line breaks"
+msgstr "znaków nowego wiersza"
+
+msgid "E395: contains argument not accepted here"
+msgstr "E395: argument contains niedozwolony w tym miejscu"
+
+msgid "E844: invalid cchar value"
+msgstr "E844: Niewłaściwa wartość cchar"
+
+msgid "E393: group[t]here not accepted here"
+msgstr "E393: group[t]here niedozwolone w tym miejscu"
+
+#, c-format
+msgid "E394: Didn't find region item for %s"
+msgstr "E394: Nie znalazłem elementów regionu dla %s"
+
+msgid "E397: Filename required"
+msgstr "E397: Wymagana nazwa pliku"
+
+msgid "E847: Too many syntax includes"
+msgstr "E847: Za dużo włączonych składni"
+
+#, c-format
+msgid "E789: Missing ']': %s"
+msgstr "E789: Brak ']': %s"
+
+#, c-format
+msgid "E398: Missing '=': %s"
+msgstr "E398: Brak '=': %s"
+
+#, c-format
+msgid "E399: Not enough arguments: syntax region %s"
+msgstr "E399: Za mało argumentów: syntax region %s"
+
+msgid "E848: Too many syntax clusters"
+msgstr "E848: Za dużo klastrów składni"
+
+msgid "E400: No cluster specified"
+msgstr "E400: Brak specyfikacji klastra"
+
+#, c-format
+msgid "E401: Pattern delimiter not found: %s"
+msgstr "E401: Brak ogranicznika wzorca: %s"
+
+#, c-format
+msgid "E402: Garbage after pattern: %s"
+msgstr "E402: Åšmieci po wzorcu: %s"
+
+msgid "E403: syntax sync: line continuations pattern specified twice"
+msgstr "E403: syntax sync: wielokrotnie podane wzorce kontynuacji wiersza"
+
+#, c-format
+msgid "E404: Illegal arguments: %s"
+msgstr "E404: Niedozwolone argumenty: %s"
+
+#, c-format
+msgid "E405: Missing equal sign: %s"
+msgstr "E405: Brak znaku równości: %s"
+
+#, c-format
+msgid "E406: Empty argument: %s"
+msgstr "E406: Pusty argument: %s"
+
+#, c-format
+msgid "E407: %s not allowed here"
+msgstr "E407: %s jest niedozwolone w tym miejscu"
+
+#, c-format
+msgid "E408: %s must be first in contains list"
+msgstr "E408: %s musi być pierwsze w liście contains"
+
+#, c-format
+msgid "E409: Unknown group name: %s"
+msgstr "E409: Nieznana nazwa grupy: %s"
+
+#, c-format
+msgid "E410: Invalid :syntax subcommand: %s"
+msgstr "E410: Niewłaściwa podkomenda :syntax : %s"
+
+msgid ""
+" TOTAL COUNT MATCH SLOWEST AVERAGE NAME PATTERN"
+msgstr ""
+" WSZYTKO ILOŚĆ PASUJE NAJWOLN. ŚREDNIO NAZWA WZORZEC"
+
+msgid "E679: recursive loop loading syncolor.vim"
+msgstr "E679: rekursywna pętla wczytująca syncolor.vim"
+
+#, c-format
+msgid "E411: highlight group not found: %s"
+msgstr "E411: nie znaleziono grupy podświetlania: %s"
+
+#, c-format
+msgid "E412: Not enough arguments: \":highlight link %s\""
+msgstr "E412: Zbyt mało argumentów: \":highlight link %s\""
+
+#, c-format
+msgid "E413: Too many arguments: \":highlight link %s\""
+msgstr "E413: Zbyt wiele argumentów: \":highlight link %s\""
+
+msgid "E414: group has settings, highlight link ignored"
+msgstr "E414: grupa ma ustawienia; zignorowane podłączenie podświetlania"
+
+#, c-format
+msgid "E415: unexpected equal sign: %s"
+msgstr "E415: nieoczekiwany znak równości: %s"
+
+#, c-format
+msgid "E416: missing equal sign: %s"
+msgstr "E416: brak znaku równości: %s"
+
+#, c-format
+msgid "E417: missing argument: %s"
+msgstr "E417: brak argumentu: %s"
+
+#, c-format
+msgid "E418: Illegal value: %s"
+msgstr "E418: Niedozwolona wartość: %s"
+
+msgid "E419: FG color unknown"
+msgstr "E419: Kolor FG nieznany"
+
+msgid "E420: BG color unknown"
+msgstr "E420: Kolor BG nieznany"
+
+#, c-format
+msgid "E421: Color name or number not recognized: %s"
+msgstr "E421: Nazwa lub liczba koloru nierozpoznana: %s"
+
+#, c-format
+msgid "E422: terminal code too long: %s"
+msgstr "E422: za długi kod terminala: %s"
+
+#, c-format
+msgid "E423: Illegal argument: %s"
+msgstr "E423: Niedozwolony argument: %s"
+
+msgid "E424: Too many different highlighting attributes in use"
+msgstr "E424: Zbyt wiele różnych atrybutów podkreślania w użyciu"
+
+msgid "E669: Unprintable character in group name"
+msgstr "E669: Niedrukowalny znak w nazwie grupy"
+
+msgid "W18: Invalid character in group name"
+msgstr "W18: nieprawidłowy znak w nazwie grupy"
+
+msgid "E849: Too many highlight and syntax groups"
+msgstr "E849: Za dużo grup podświetlania i składni"
+
+msgid "E555: at bottom of tag stack"
+msgstr "E555: na dole stosu znaczników"
+
+msgid "E556: at top of tag stack"
+msgstr "E556: na górze stosu znaczników"
+
+msgid "E425: Cannot go before first matching tag"
+msgstr "E425: Nie można przejść przed pierwszy pasujący znacznik"
+
+#, c-format
+msgid "E426: tag not found: %s"
+msgstr "E426: nie znaleziono znacznika: %s"
+
+msgid " # pri kind tag"
+msgstr " # pri rodzaj znacznik"
+
+msgid "file\n"
+msgstr "plik\n"
+
+msgid "E427: There is only one matching tag"
+msgstr "E427: Pasuje tylko jeden znacznik"
+
+msgid "E428: Cannot go beyond last matching tag"
+msgstr "E428: Nie można przejść za ostatni pasujący znacznik"
+
+#, c-format
+msgid "File \"%s\" does not exist"
+msgstr "Plik \"%s\" nie istnieje"
+
+#. Give an indication of the number of matching tags
+#, c-format
+msgid "tag %d of %d%s"
+msgstr "znacznik %d z %d%s"
+
+msgid " or more"
+msgstr " lub więcej"
+
+msgid " Using tag with different case!"
+msgstr " Używam znacznika o odmiennej wielkości liter!"
+
+#, c-format
+msgid "E429: File \"%s\" does not exist"
+msgstr "E429: Plik \"%s\" nie istnieje"
+
+#. Highlight title
+msgid ""
+"\n"
+" # TO tag FROM line in file/text"
+msgstr ""
+"\n"
+" # DO znacznik OD wiersza w pliku/tekście"
+
+#, c-format
+msgid "Searching tags file %s"
+msgstr "Szukam w pliku znaczników %s"
+
+#, c-format
+msgid "E430: Tag file path truncated for %s\n"
+msgstr "E430: Trop szukania pliku znaczników obcięty dla %s\n"
+
+msgid "Ignoring long line in tags file"
+msgstr "Ignoruję długie wiersze w pliku znaczników"
+
+#, c-format
+msgid "E431: Format error in tags file \"%s\""
+msgstr "E431: Błąd formatu w pliku znaczników \"%s\""
+
+#, c-format
+msgid "Before byte %ld"
+msgstr "Przed bajtem %ld"
+
+#, c-format
+msgid "E432: Tags file not sorted: %s"
+msgstr "E432: Plik znaczników nieuporządkowany: %s"
+
+#. never opened any tags file
+msgid "E433: No tags file"
+msgstr "E433: Brak pliku znaczników"
+
+msgid "E434: Can't find tag pattern"
+msgstr "E434: Nie mogę znaleźć wzorca znacznika"
+
+msgid "E435: Couldn't find tag, just guessing!"
+msgstr "E435: Nie znalazłem znacznika - tylko zgaduję!"
+
+#, c-format
+msgid "Duplicate field name: %s"
+msgstr "Powtórzona nazwa pola: %s"
+
+msgid "' not known. Available builtin terminals are:"
+msgstr "' nieznany. Możliwe typy wbudowanych terminali:"
+
+msgid "defaulting to '"
+msgstr "domyślnie jest '"
+
+msgid "E557: Cannot open termcap file"
+msgstr "E557: Nie mogę otworzyć pliku termcap"
+
+msgid "E558: Terminal entry not found in terminfo"
+msgstr "E558: Nie ma opisu takiego terminala w terminfo"
+
+msgid "E559: Terminal entry not found in termcap"
+msgstr "E559: Nie ma opisu takiego terminala w termcap"
+
+#, c-format
+msgid "E436: No \"%s\" entry in termcap"
+msgstr "E436: Brak opisu \"%s\" w termcap"
+
+msgid "E437: terminal capability \"cm\" required"
+msgstr "E437: wymagana zdolność \"cm\" terminala"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Terminal keys ---"
+msgstr ""
+"\n"
+"--- Klawisze terminala ---"
+
+msgid "new shell started\n"
+msgstr "uruchomiono nową powłokę\n"
+
+msgid "Vim: Error reading input, exiting...\n"
+msgstr "Vim: Błąd podczas wczytywania wejścia, kończę...\n"
+
+msgid "Used CUT_BUFFER0 instead of empty selection"
+msgstr "Używam CUT_BUFFER0 zamiast pustego wyboru"
+
+#. This happens when the FileChangedRO autocommand changes the
+#. * file in a way it becomes shorter.
+msgid "E834: Line count changed unexpectedly"
+msgstr "E834: Niespodziewana zmiana ilości linii"
+
+#. must display the prompt
+msgid "No undo possible; continue anyway"
+msgstr "Cofnięcie niemożliwe; mimo to kontynuuję"
+
+#, c-format
+msgid "E828: Cannot open undo file for writing: %s"
+msgstr "E828: Nie mogę otworzyć do zapisu pliku undo: %s"
+
+#, c-format
+msgid "E825: Corrupted undo file (%s): %s"
+msgstr "E825: Uszkodzony plik undo (%s): %s"
+
+msgid "Cannot write undo file in any directory in 'undodir'"
+msgstr "Nie można zapisać pliku undo w żadnym katalogu z 'undodir'"
+
+#, c-format
+msgid "Will not overwrite with undo file, cannot read: %s"
+msgstr "Nie nadpiszę plikiem undo, nie mogę odczytać: %s"
+
+#, c-format
+msgid "Will not overwrite, this is not an undo file: %s"
+msgstr "Nie nadpiszÄ™, to nie jest plik undo: %s"
+
+msgid "Skipping undo file write, nothing to undo"
+msgstr "Pomijam zapis pliku undo, nic do cofnięcia"
+
+#, c-format
+msgid "Writing undo file: %s"
+msgstr "ZapisujÄ™ plik undo: %s"
+
+#, c-format
+msgid "E829: write error in undo file: %s"
+msgstr "E829: Błąd zapisu w pliku undo: %s"
+
+#, c-format
+msgid "Not reading undo file, owner differs: %s"
+msgstr "Nie wczytuję pliku undo, inny właściciel: %s"
+
+#, c-format
+msgid "Reading undo file: %s"
+msgstr "WczytujÄ™ plik undo: %s"
+
+#, c-format
+msgid "E822: Cannot open undo file for reading: %s"
+msgstr "E822: Nie mogę otworzyć pliku undo do odczytu: %s"
+
+#, c-format
+msgid "E823: Not an undo file: %s"
+msgstr "E823: To nie jest plik undo: %s"
+
+#, c-format
+msgid "E832: Non-encrypted file has encrypted undo file: %s"
+msgstr "E832: Nie zaszyfrowany plik ma zaszyfrowany plik undo: %s"
+
+#, c-format
+msgid "E826: Undo file decryption failed: %s"
+msgstr "E826: Nie powiodło się odszyfrowywanie pliku undo: %s"
+
+#, c-format
+msgid "E827: Undo file is encrypted: %s"
+msgstr "E827: Plik undo jest zaszyfrowany: %s"
+
+#, c-format
+msgid "E824: Incompatible undo file: %s"
+msgstr "E824: Niekompatybilny plik undo: %s"
+
+msgid "File contents changed, cannot use undo info"
+msgstr "Zawartość pliku się zmieniła, nie mogę użyć pliku undo"
+
+#, c-format
+msgid "Finished reading undo file %s"
+msgstr "Skończono wczytywanie pliku undo %s"
+
+msgid "Already at oldest change"
+msgstr "Już w miejscu ostatniej zmiany"
+
+msgid "Already at newest change"
+msgstr "Już w miejscu najnowszej zmiany"
+
+#, c-format
+msgid "E830: Undo number %ld not found"
+msgstr "E830: Nie znaleziono numeru cofnięcia %ld"
+
+msgid "E438: u_undo: line numbers wrong"
+msgstr "E438: u_undo: niewłaściwe numery wierszy"
+
+msgid "more line"
+msgstr "1 wiersz więcej"
+
+msgid "more lines"
+msgstr "więcej wierszy"
+
+msgid "line less"
+msgstr "1 wiersz mniej"
+
+msgid "fewer lines"
+msgstr "mniej wierszy"
+
+msgid "change"
+msgstr "1 zmiana"
+
+msgid "changes"
+msgstr "zmiany"
+
+#, c-format
+msgid "%ld %s; %s #%ld %s"
+msgstr "%ld %s; %s #%ld %s"
+
+msgid "before"
+msgstr "przed"
+
+msgid "after"
+msgstr "za"
+
+msgid "Nothing to undo"
+msgstr "Nie ma zmian do cofnięcia"
+
+msgid "number changes when saved"
+msgstr "liczba zmiany kiedy zapisano"
+
+#, c-format
+msgid "%ld seconds ago"
+msgstr "%ld sekund temu"
+
+msgid "E790: undojoin is not allowed after undo"
+msgstr "E790: undojoin nie jest dozwolone po undo"
+
+msgid "E439: undo list corrupt"
+msgstr "E439: uszkodzona lista cofania"
+
+msgid "E440: undo line missing"
+msgstr "E440: brak wiersza cofania"
+
+#. Only MS VC 4.1 and earlier can do Win32s
+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"
+"Included patches: "
+msgstr ""
+"\n"
+"Zadane łaty: "
+
+msgid ""
+"\n"
+"Extra patches: "
+msgstr ""
+"\n"
+"Ekstra łaty: "
+
+msgid "Modified by "
+msgstr "Zmieniony przez "
+
+msgid ""
+"\n"
+"Compiled "
+msgstr ""
+"\n"
+"Skompilowany "
+
+msgid "by "
+msgstr "przez "
+
+msgid ""
+"\n"
+"Huge version "
+msgstr ""
+"\n"
+"Olbrzymia wersja "
+
+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 "without GUI."
+msgstr "bez GUI."
+
+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 " Features included (+) or not (-):\n"
+msgstr " Opcje włączone (+) lub nie (-):\n"
+
+msgid " system vimrc file: \""
+msgstr " vimrc systemu: \""
+
+msgid " user vimrc file: \""
+msgstr " vimrc użytkownika: \""
+
+msgid " 2nd user vimrc file: \""
+msgstr " 2-gi plik vimrc użytkownika: \""
+
+msgid " 3rd user vimrc file: \""
+msgstr " 3-ci plik vimrc użytkownika: \""
+
+msgid " user exrc file: \""
+msgstr " exrc użytkownika: \""
+
+msgid " 2nd user exrc file: \""
+msgstr " 2-gi plik exrc użytkownika: \""
+
+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 " fall-back for $VIM: \""
+msgstr " odwet dla $VIM-a: \""
+
+msgid " f-b for $VIMRUNTIME: \""
+msgstr "f-b dla $VIMRUNTIME: \""
+
+msgid "Compilation: "
+msgstr "Kompilacja: "
+
+msgid "Compiler: "
+msgstr "Kompilator: "
+
+msgid "Linking: "
+msgstr "Konsolidacja: "
+
+msgid " DEBUG BUILD"
+msgstr " KOMPILACJA DEBUG"
+
+msgid "VIM - Vi IMproved"
+msgstr "VIM - Vi rozbudowany"
+
+msgid "version "
+msgstr "wersja "
+
+msgid "by Bram Moolenaar et al."
+msgstr "Autor: Bram Moolenaar i Inni."
+
+msgid "Vim is open source and freely distributable"
+msgstr "Vim jest open source i rozprowadzany darmowo"
+
+msgid "Help poor children in Uganda!"
+msgstr "Pomóż biednym dzieciom w Ugandzie!"
+
+msgid "type :help iccf<Enter> for information "
+msgstr "wprowadź :help iccf<Enter> dla informacji o tym "
+
+msgid "type :q<Enter> to exit "
+msgstr "wprowadź :q<Enter> zakończenie programu "
+
+msgid "type :help<Enter> or <F1> for on-line help"
+msgstr "wprowadź :help<Enter> lub <F1> pomoc na bieżąco "
+
+msgid "type :help version7<Enter> for version info"
+msgstr "wprowadź :help version7<Enter> dla informacji o wersji"
+
+msgid "Running in Vi compatible mode"
+msgstr "Działam w trybie zgodności z Vi"
+
+msgid "type :set nocp<Enter> for Vim defaults"
+msgstr "wprowadź :set nocp<Enter> wartości domyślne Vim-a"
+
+msgid "type :help cp-default<Enter> for info on this"
+msgstr "wprowadź :help cp-default<Enter> dla informacji to tym "
+
+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 "Sponsor Vim development!"
+msgstr "Sponsoruj rozwój Vima!"
+
+msgid "Become a registered Vim user!"
+msgstr "Zostań zarejestrowanym użytkownikiem Vima!"
+
+msgid "type :help sponsor<Enter> for information "
+msgstr "wprowadź :help sponsor<Enter> dla informacji"
+
+msgid "type :help register<Enter> for information "
+msgstr "wprowadź :help register<Enter> dla informacji"
+
+msgid "menu Help->Sponsor/Register for information "
+msgstr "menu Pomoc->Sponsoruj/Zarejestruj siÄ™ dla informacji"
+
+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 "Already only one window"
+msgstr "Już jest tylko jeden widok"
+
+msgid "E441: There is no preview window"
+msgstr "E441: Nie ma okna podglÄ…du"
+
+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"
+
+msgid "E443: Cannot rotate when another window is split"
+msgstr "E443: Nie mogę przekręcić, gdy inne okno jest rozdzielone"
+
+msgid "E444: Cannot close last window"
+msgstr "E444: Nie mogę zamknąć ostatniego okna"
+
+msgid "E813: Cannot close autocmd window"
+msgstr "E813: Nie można zamknąć okna autocmd"
+
+msgid "E814: Cannot close window, only autocmd window would remain"
+msgstr "E814: Nie można zamknąć okna, zostałoby tylko okno autocmd"
+
+msgid "E445: Other window contains changes"
+msgstr "E445: Inne okno zawiera zmiany"
+
+msgid "E446: No file name under cursor"
+msgstr "E446: Brak nazwy pliku pod kursorem"
+
+#, c-format
+msgid "E447: Can't find file \"%s\" in path"
+msgstr "E447: Nie mogę znaleźć pliku \"%s\" w tropie"
+
+#, c-format
+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"
+
+#. Now concatenate
+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 "--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.
+#.
+msgid "E470: Command aborted"
+msgstr "E470: Przerwanie komendy"
+
+msgid "E471: Argument required"
+msgstr "E471: wymagany argument"
+
+msgid "E10: \\ should be followed by /, ? or &"
+msgstr "E10: po \\ powinno być /, ? lub &"
+
+msgid "E11: Invalid in command-line window; <CR> executes, CTRL-C quits"
+msgstr ""
+"E11: Niedozwolone w oknie wiersza poleceń; <CR> wykonuje, CTRL-C opuszcza"
+
+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"
+
+msgid "E171: Missing :endif"
+msgstr "E171: Brak :endif"
+
+msgid "E600: Missing :endtry"
+msgstr "E600: Brak :endtry"
+
+msgid "E170: Missing :endwhile"
+msgstr "E170: Brak :endwhile"
+
+msgid "E170: Missing :endfor"
+msgstr "E170: Brak :endfor"
+
+msgid "E588: :endwhile without :while"
+msgstr "E588: :endwhile bez :while"
+
+msgid "E588: :endfor without :for"
+msgstr "E588: :endfor bez :for"
+
+msgid "E13: File exists (add ! to override)"
+msgstr "E13: Plik istnieje (wymuÅ› poprzez !)"
+
+msgid "E472: Command failed"
+msgstr "E472: Komenda nie powiodła się"
+
+#, c-format
+msgid "E234: Unknown fontset: %s"
+msgstr "E234: Nieznany zestaw czcionek: %s"
+
+#, c-format
+msgid "E235: Unknown font: %s"
+msgstr "E235: Nieznana czcionka: %s"
+
+#, c-format
+msgid "E236: Font \"%s\" is not fixed-width"
+msgstr "E236: Czcionka \"%s\" nie ma stałej szerokości znaków"
+
+msgid "E473: Internal error"
+msgstr "E473: Błąd wewnętrzny"
+
+msgid "Interrupted"
+msgstr "Przerwane"
+
+msgid "E14: Invalid address"
+msgstr "E14: Niewłaściwy adres"
+
+msgid "E474: Invalid argument"
+msgstr "E474: Niewłaściwy argument"
+
+#, c-format
+msgid "E475: Invalid argument: %s"
+msgstr "E475: Niewłaściwy argument: %s"
+
+#, c-format
+msgid "E15: Invalid expression: %s"
+msgstr "E15: Niewłaściwe wyrażenie: %s"
+
+msgid "E16: Invalid range"
+msgstr "E16: Niewłaściwy zakres"
+
+msgid "E476: Invalid command"
+msgstr "E476: Niewłaściwa komenda"
+
+#, c-format
+msgid "E17: \"%s\" is a directory"
+msgstr "E17: \"%s\" jest katalogiem"
+
+#, c-format
+msgid "E364: Library call failed for \"%s()\""
+msgstr "E364: Wywołanie z biblioteki nie powiodło się dla \"%s()\""
+
+#, c-format
+msgid "E448: Could not load library function %s"
+msgstr "E448: Nie można załadować funkcji biblioteki %s"
+
+msgid "E19: Mark has invalid line number"
+msgstr "E19: Zakładka ma niewłaściwy numer wiersza"
+
+msgid "E20: Mark not set"
+msgstr "E20: Zakładka nienastawiona"
+
+msgid "E21: Cannot make changes, 'modifiable' is off"
+msgstr "E21: Nie mogę wykonać zmian, 'modifiable' jest wyłączone"
+
+msgid "E22: Scripts nested too deep"
+msgstr "E22: Zbyt głębokie zagnieżdżenie skryptów"
+
+msgid "E23: No alternate file"
+msgstr "E23: Brak pliku zamiany"
+
+msgid "E24: No such abbreviation"
+msgstr "E24: Nie ma takiego skrótu"
+
+msgid "E477: No ! allowed"
+msgstr "E477: Niedozwolone !"
+
+msgid "E25: GUI cannot be used: Not enabled at compile time"
+msgstr "E25: GUI nie może być użyte: Nie włączono podczas kompilacji"
+
+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"
+
+#, c-format
+msgid "E28: No such highlight group name: %s"
+msgstr "E28: Brak takiej nazwy grupy podświetlania: %s"
+
+msgid "E29: No inserted text yet"
+msgstr "E29: Nie wprowadzono jeszcze żadnego tekstu"
+
+msgid "E30: No previous command line"
+msgstr "E30: Nie ma poprzedniego wiersza poleceń"
+
+msgid "E31: No such mapping"
+msgstr "E31: Nie ma takiego przyporzÄ…dkowania"
+
+msgid "E479: No match"
+msgstr "E479: Brak dopasowań"
+
+#, c-format
+msgid "E480: No match: %s"
+msgstr "E480: Brak dopasowań: %s"
+
+msgid "E32: No file name"
+msgstr "E32: Brak nazwy pliku"
+
+msgid "E33: No previous substitute regular expression"
+msgstr "E33: Brak poprzedniego podstawieniowego wyrażenia regularnego"
+
+msgid "E34: No previous command"
+msgstr "E34: Brak poprzedniej komendy"
+
+msgid "E35: No previous regular expression"
+msgstr "E35: Brak poprzedniego wyrażenia regularnego"
+
+msgid "E481: No range allowed"
+msgstr "E481: Zakres niedozwolony"
+
+msgid "E36: Not enough room"
+msgstr "E36: Brak miejsca"
+
+#, c-format
+msgid "E247: no registered server named \"%s\""
+msgstr "E247: brak zarejestrowanego serwera o nazwie \"%s\""
+
+#, c-format
+msgid "E482: Can't create file %s"
+msgstr "E482: Nie mogę stworzyć pliku %s"
+
+msgid "E483: Can't get temp file name"
+msgstr "E483: Nie mogę pobrać nazwy pliku tymczasowego"
+
+#, c-format
+msgid "E484: Can't open file %s"
+msgstr "E484: Nie mogę otworzyć pliku %s"
+
+#, c-format
+msgid "E485: Can't read file %s"
+msgstr "E485: Nie mogę odczytać pliku %s"
+
+msgid "E37: No write since last change (add ! to override)"
+msgstr "E37: Nie zapisano od ostatniej zmiany (wymuÅ› przez !)"
+
+msgid "E38: Null argument"
+msgstr "E38: Zerowy argument"
+
+msgid "E39: Number expected"
+msgstr "E39: OczekujÄ™ liczby"
+
+#, c-format
+msgid "E40: Can't open errorfile %s"
+msgstr "E40: Nie mogę otworzyć pliku błędów %s"
+
+msgid "E233: cannot open display"
+msgstr "E233: nie mogę otworzyć ekranu"
+
+msgid "E41: Out of memory!"
+msgstr "E41: Pamięć wyczerpana!"
+
+msgid "Pattern not found"
+msgstr "Nie znaleziono wzorca"
+
+#, c-format
+msgid "E486: Pattern not found: %s"
+msgstr "E486: Nie znaleziono wzorca: %s"
+
+msgid "E487: Argument must be positive"
+msgstr "E487: Argument musi być dodatni"
+
+msgid "E459: Cannot go back to previous directory"
+msgstr "E459: Nie można przejść do poprzedniego katalogu"
+
+msgid "E42: No Errors"
+msgstr "E42: Brak Błędów"
+
+msgid "E776: No location list"
+msgstr "E776: Brak listy lokacji"
+
+msgid "E43: Damaged match string"
+msgstr "E43: Popsuty ciÄ…g wzorca"
+
+msgid "E44: Corrupted regexp program"
+msgstr "E44: Zepsuty program wyrażeń regularnych"
+
+msgid "E45: 'readonly' option is set (add ! to override)"
+msgstr "E45: opcja 'readonly' jest ustawiona (wymuÅ› poprzez !)"
+
+#, c-format
+msgid "E46: Cannot change read-only variable \"%s\""
+msgstr "E46: Nie mogę zmienić zmiennej tylko do odczytu \"%s\""
+
+#, c-format
+msgid "E794: Cannot set variable in the sandbox: \"%s\""
+msgstr "E794: Nie mogę ustawić zmiennej w piaskownicy: \"%s\""
+
+msgid "E47: Error while reading errorfile"
+msgstr "E47: Błąd w trakcie czytania pliku błędów"
+
+msgid "E48: Not allowed in sandbox"
+msgstr "E48: Niedozwolone w piaskownicy"
+
+msgid "E523: Not allowed here"
+msgstr "E523: Niedozwolone w tym miejscu"
+
+msgid "E359: Screen mode setting not supported"
+msgstr "E359: Ustawianie trybu ekranu niewspomagane"
+
+msgid "E49: Invalid scroll size"
+msgstr "E49: Niewłaściwa wielkość przewinięcia"
+
+msgid "E91: 'shell' option is empty"
+msgstr "E91: opcja 'shell' jest pusta"
+
+msgid "E255: Couldn't read in sign data!"
+msgstr "E255: Nie mogłem wczytać danych znaku!"
+
+msgid "E72: Close error on swap file"
+msgstr "E72: Błąd podczas zamykania pliku wymiany"
+
+msgid "E73: tag stack empty"
+msgstr "E73: stos znaczników jest pusty"
+
+msgid "E74: Command too complex"
+msgstr "E74: Komenda jest zbyt skomplikowana"
+
+msgid "E75: Name too long"
+msgstr "E75: Zbyt długa nazwa"
+
+msgid "E76: Too many ["
+msgstr "E76: Zbyt wiele ["
+
+msgid "E77: Too many file names"
+msgstr "E77: Zbyt wiele nazw plików"
+
+msgid "E488: Trailing characters"
+msgstr "E488: Nadstępne znaczki"
+
+msgid "E78: Unknown mark"
+msgstr "E78: Nieznana zakładka"
+
+msgid "E79: Cannot expand wildcards"
+msgstr "E79: Nie mogą rozwinąć znaków wieloznacznych"
+
+msgid "E591: 'winheight' cannot be smaller than 'winminheight'"
+msgstr "E591: 'winheight' nie może być mniejsze niż 'winminheight'"
+
+msgid "E592: 'winwidth' cannot be smaller than 'winminwidth'"
+msgstr "E592: 'winwidth' nie może być mniejsze niż 'winminwidth'"
+
+msgid "E80: Error while writing"
+msgstr "E80: Błąd w trakcie zapisu"
+
+msgid "Zero count"
+msgstr "Zerowy licznik"
+
+msgid "E81: Using <SID> not in a script context"
+msgstr "E81: Użycie <SID> poza kontekstem skryptu"
+
+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"
+
+#, c-format
+msgid "E685: Internal error: %s"
+msgstr "E685: Błąd wewnętrzny: %s"
+
+msgid "E363: pattern uses more memory than 'maxmempattern'"
+msgstr "E363: Wzorzec używa więcej pamięci niż 'maxmempattern'"
+
+msgid "E749: empty buffer"
+msgstr "E749: pusty bufor"
+
+msgid "E682: Invalid search pattern or delimiter"
+msgstr "E682: Niewłaściwy wzorzec wyszukiwania lub delimiter"
+
+msgid "E139: File is loaded in another buffer"
+msgstr "E139: Plik jest załadowany w innym buforze"
+
+#, c-format
+msgid "E764: Option '%s' is not set"
+msgstr "E764: Nie ustawiono opcji '%s'"
+
+msgid "E850: Invalid register name"
+msgstr "E850: Niewłaściwa nazwa rejestru"
+
+msgid "search hit TOP, continuing at BOTTOM"
+msgstr "szukanie dobiło GÓRY; kontynuacja od KOŃCA"
+
+msgid "search hit BOTTOM, continuing at TOP"
+msgstr "szukanie dobiło KOŃCA; kontynuacja od GÓRY"
+
+#, c-format
+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"
+
+#, c-format
+msgid "failed to add key '%s' to dictionary"
+msgstr "nie powiodło się dodanie klucza '%s' do słownika"
+
+#, c-format
+msgid "index must be int or slice, not %s"
+msgstr "indeks musi być liczbą lub wycinkiem, nie %s"
+
+#, c-format
+msgid "expected str() or unicode() instance, but got %s"
+msgstr "czekałem na str() lub unicode(), a dostałem %s"
+
+#, c-format
+msgid "expected bytes() or str() instance, but got %s"
+msgstr "czekałem na bytes() lub str(), a dostałem %s"
+
+#, c-format
+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"
+
+#, c-format
+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"
+
+#, c-format
+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"
+
+#, c-format
+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"
+
+#, c-format
+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"
+
+#, c-format
+msgid "cannot set attribute %s"
+msgstr "nie mogę ustawić atrybutu %s"
+
+msgid "hashtab changed during iteration"
+msgstr "hashtab zmienił się w czasie iteracji"
+
+#, c-format
+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"
+
+#. No more suitable format specifications in python-2.3
+#, c-format
+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"
+
+#, c-format
+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"
+
+#, c-format
+msgid "unnamed function %s does not exist"
+msgstr "nie nazwana funkcja %s nie istnieje"
+
+#, c-format
+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"
+
+#, c-format
+msgid "failed to run function %s"
+msgstr "nie mogę uruchomić funkcji %s"
+
+msgid "unable to get option value"
+msgstr "nie mogę pobrać wartości opcji"
+
+msgid "internal error: unknown option type"
+msgstr "błąd wewnętrzny: nieznany typ opcji"
+
+msgid "problem while switching windows"
+msgstr "wystąpił problem w czasie zmiany okien"
+
+#, c-format
+msgid "unable to unset global option %s"
+msgstr "nie mogę wyzerować opcji globalnej %s"
+
+#, c-format
+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"
+
+#, c-format
+msgid "expected vim.Buffer object, but got %s"
+msgstr "oczekiwałem na obiekt vim.Buffer, a dostałem %s"
+
+#, c-format
+msgid "failed to switch to buffer %d"
+msgstr "nie przeszedłem do bufora %d"
+
+#, c-format
+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"
+
+#, c-format
+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"
+
+#, c-format
+msgid "unable to convert %s to vim dictionary"
+msgstr "nie można konwertować %s do słownika Vima"
+
+#, c-format
+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/po/pl.cp1250.po b/src/po/pl.cp1250.po
new file mode 100644
index 0000000000..c402886b4d
--- /dev/null
+++ b/src/po/pl.cp1250.po
@@ -0,0 +1,6904 @@
+# 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: 2013-07-06 19:33+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"
+
+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 "[Location List]"
+msgstr "[Lista lokacji]"
+
+msgid "[Quickfix List]"
+msgstr "[Lista quickfix]"
+
+msgid "E855: Autocommands caused command to abort"
+msgstr "E855: Autokomendy spowodowa³y porzucenie komendy"
+
+msgid "E82: Cannot allocate any buffer, exiting..."
+msgstr "E82: Nie mogê zarezerwowaæ bufora; zakoñczenie..."
+
+msgid "E83: Cannot allocate buffer, using other one..."
+msgstr "E83: Nie mogê zarezerwowaæ bufora; u¿ywam innego..."
+
+msgid "E515: No buffers were unloaded"
+msgstr "E515: Nie wy³adowano ¿adnego bufora"
+
+msgid "E516: No buffers were deleted"
+msgstr "E516: Nie skasowano ¿adnego bufora"
+
+msgid "E517: No buffers were wiped out"
+msgstr "E517: Nie wyrzucono ¿adnego bufora"
+
+msgid "1 buffer unloaded"
+msgstr "1 bufor wy³adowany"
+
+#, c-format
+msgid "%d buffers unloaded"
+msgstr "wy³adowano %d buforów"
+
+msgid "1 buffer deleted"
+msgstr "1 bufor skasowany"
+
+#, c-format
+msgid "%d buffers deleted"
+msgstr "%d buforów skasowano"
+
+msgid "1 buffer wiped out"
+msgstr "wyrzucono 1 bufor "
+
+#, c-format
+msgid "%d buffers wiped out"
+msgstr "wyrzucono %d buforów"
+
+msgid "E84: No modified buffer found"
+msgstr "E84: Nie znaleziono zmienionych buforów"
+
+#. back where we started, didn't find anything.
+msgid "E85: There is no listed buffer"
+msgstr "E85: Nie ma wylistowanych buforów"
+
+#, c-format
+msgid "E86: Buffer %ld does not exist"
+msgstr "E86: Bufor \"%ld\" nie istnieje"
+
+msgid "E87: Cannot go beyond last buffer"
+msgstr "E87: Nie mogê przejœæ poza ostatni bufor"
+
+msgid "E88: Cannot go before first buffer"
+msgstr "E88: Nie mogê przejœæ przed pierwszy bufor"
+
+#, c-format
+msgid "E89: No write since last change for buffer %ld (add ! to override)"
+msgstr "E89: Nie zapisano zmian w buforze %ld (wymuœ przez !)"
+
+msgid "E90: Cannot unload last buffer"
+msgstr "E90: Nie mogê wy³adowaæ ostatniego bufora"
+
+msgid "W14: Warning: List of file names overflow"
+msgstr "W14: OSTRZE¯ENIE: Przepe³nienie listy nazw plików"
+
+#, c-format
+msgid "E92: Buffer %ld not found"
+msgstr "E92: Nie znaleziono bufora %ld"
+
+#, c-format
+msgid "E93: More than one match for %s"
+msgstr "E93: Wielokrotne dopasowania dla %s"
+
+#, c-format
+msgid "E94: No matching buffer for %s"
+msgstr "E94: ¯aden bufor nie pasuje do %s"
+
+#, c-format
+msgid "line %ld"
+msgstr "wiersz %ld"
+
+msgid "E95: Buffer with this name already exists"
+msgstr "E95: Bufor o tej nazwie ju¿ istnieje"
+
+msgid " [Modified]"
+msgstr " [Zmieniony]"
+
+msgid "[Not edited]"
+msgstr "[Nie edytowany]"
+
+msgid "[New file]"
+msgstr "[Nowy Plik]"
+
+msgid "[Read errors]"
+msgstr "[B³¹d odczytu]"
+
+msgid "[RO]"
+msgstr "[RO]"
+
+msgid "[readonly]"
+msgstr "[tylko odczyt]"
+
+#, c-format
+msgid "1 line --%d%%--"
+msgstr "1 wiersz --%d%%--"
+
+#, c-format
+msgid "%ld lines --%d%%--"
+msgstr "%ld wiersze --%d%%--"
+
+#, c-format
+msgid "line %ld of %ld --%d%%-- col "
+msgstr "wiersz %ld z %ld --%d%%-- kol "
+
+msgid "[No Name]"
+msgstr "[Bez nazwy]"
+
+#. must be a help buffer
+msgid "help"
+msgstr "pomoc"
+
+msgid "[Help]"
+msgstr "[Pomoc]"
+
+msgid "[Preview]"
+msgstr "[Podgl¹d]"
+
+msgid "All"
+msgstr "Wszystko"
+
+msgid "Bot"
+msgstr "Dó³"
+
+msgid "Top"
+msgstr "Góra"
+
+msgid ""
+"\n"
+"# Buffer list:\n"
+msgstr ""
+"\n"
+"# Lista buforów:\n"
+
+msgid "[Scratch]"
+msgstr "[Notka]"
+
+msgid ""
+"\n"
+"--- Signs ---"
+msgstr ""
+"\n"
+"--- Znaki ---"
+
+#, c-format
+msgid "Signs for %s:"
+msgstr "Znaki dla %s:"
+
+#, c-format
+msgid " line=%ld id=%d name=%s"
+msgstr " wiersz=%ld id=%d nazwa=%s"
+
+#, c-format
+msgid "E96: Can not diff more than %ld buffers"
+msgstr "E96: Nie mogê zró¿nicowaæ wiêcej ni¿ %ld buforów"
+
+msgid "E810: Cannot read or write temp files"
+msgstr "E810: Nie mogê otworzyæ lub zapisaæ plików tymczasowych"
+
+msgid "E97: Cannot create diffs"
+msgstr "E97: Nie mogê stworzyæ ró¿nic"
+
+msgid "Patch file"
+msgstr "Plik ³ata"
+
+msgid "E816: Cannot read patch output"
+msgstr "E816: Nie mogê odczytaæ wyjœcia pliku ³aty"
+
+msgid "E98: Cannot read diff output"
+msgstr "E98: Nie mogê wczytaæ wyjœcia ró¿nicy"
+
+msgid "E99: Current buffer is not in diff mode"
+msgstr "E99: Bie¿¹cy bufor nie jest w trybie ró¿nic"
+
+msgid "E793: No other buffer in diff mode is modifiable"
+msgstr "E793: ¯aden inny bufor w trybie diff nie jest modyfikowalny"
+
+msgid "E100: No other buffer in diff mode"
+msgstr "E100: Brak innego bufora w trybie ró¿nic"
+
+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æ"
+
+#, c-format
+msgid "E102: Can't find buffer \"%s\""
+msgstr "E102: Nie mogê znaleŸæ bufora \"%s\""
+
+#, c-format
+msgid "E103: Buffer \"%s\" is not in diff mode"
+msgstr "E103: Bufor \"%s\" nie jest w trybie ró¿nicowania"
+
+msgid "E787: Buffer changed unexpectedly"
+msgstr "E787: Nieoczekiwana zmiana bufora"
+
+msgid "E104: Escape not allowed in digraph"
+msgstr "E104: Escape jest niedozwolone w dwugrafie"
+
+msgid "E544: Keymap file not found"
+msgstr "E544: Nie znaleziono pliku rozk³adu klawiszy"
+
+msgid "E105: Using :loadkeymap not in a sourced file"
+msgstr "E105: Zastosowano :loadkeymap w niewczytanym pliku"
+
+msgid "E791: Empty keymap entry"
+msgstr "E791: Pusty wpis keymap"
+
+msgid " Keyword completion (^N^P)"
+msgstr " Dope³nianie s³ów kluczowych (^N^P)"
+
+#. ctrl_x_mode == 0, ^P/^N compl.
+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)"
+
+msgid " Whole line completion (^L^N^P)"
+msgstr " Dope³nianie pe³nych wierszy (^L^N^P)"
+
+msgid " File name completion (^F^N^P)"
+msgstr " Dope³nianie nazw plików (^F^N^P)"
+
+msgid " Tag completion (^]^N^P)"
+msgstr " Dope³nianie znaczników (^]^N^P)"
+
+msgid " Path pattern completion (^N^P)"
+msgstr " Dope³nianie wzorców tropów (^N^P)"
+
+msgid " Definition completion (^D^N^P)"
+msgstr " Dope³nianie definicji (^D^N^P)"
+
+msgid " Dictionary completion (^K^N^P)"
+msgstr " Dope³nianie ze s³owników (^K^N^P)"
+
+msgid " Thesaurus completion (^T^N^P)"
+msgstr " Dope³nianie z tezaurusa (^T^N^P)"
+
+msgid " Command-line completion (^V^N^P)"
+msgstr " Dope³nianie wiersza poleceñ (^V^N^P)"
+
+msgid " User defined completion (^U^N^P)"
+msgstr "Dope³nianie zdefiniowane przez u¿ytkownika (^U^N^P)"
+
+msgid " Omni completion (^O^N^P)"
+msgstr " Omni uzupe³nianie (^O^N^P)"
+
+msgid " Spelling suggestion (s^N^P)"
+msgstr "Propozycja pisowni (^L^N^P)"
+
+msgid " Keyword Local completion (^N^P)"
+msgstr " Lokalne dope³nianie s³ów kluczowych (^N^P)"
+
+msgid "Hit end of paragraph"
+msgstr "Dobi³em do koñca akapitu"
+
+msgid "E839: Completion function changed window"
+msgstr "E839: Funkcja uzupe³niania zmieni³a okno"
+
+msgid "E840: Completion function deleted text"
+msgstr "E840: Funkcja uzupe³nania usunê³a tekst"
+
+msgid "'dictionary' option is empty"
+msgstr "opcja 'dictionary' jest pusta"
+
+msgid "'thesaurus' option is empty"
+msgstr "opcja 'thesaurus' jest pusta"
+
+#, c-format
+msgid "Scanning dictionary: %s"
+msgstr "Przegl¹dam s³ownik: %s"
+
+msgid " (insert) Scroll (^E/^Y)"
+msgstr " (wprowadzanie) Przewijanie (^E/^Y)"
+
+msgid " (replace) Scroll (^E/^Y)"
+msgstr " (zamiana) Przewijanie (^E/^Y)"
+
+#, c-format
+msgid "Scanning: %s"
+msgstr "Przegl¹dam: %s"
+
+msgid "Scanning tags."
+msgstr "Przegl¹dam znaczniki."
+
+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.
+#.
+msgid "-- Searching..."
+msgstr "-- Szukam..."
+
+msgid "Back at original"
+msgstr "Z powrotem na pierwotnym"
+
+msgid "Word from other line"
+msgstr "Wyraz z innego wiersza"
+
+msgid "The only match"
+msgstr "Jedyne dopasowanie"
+
+#, c-format
+msgid "match %d of %d"
+msgstr "pasuje %d z %d"
+
+#, c-format
+msgid "match %d"
+msgstr "pasuje %d"
+
+msgid "E18: Unexpected characters in :let"
+msgstr "E18: Nieoczekiwane znaki w :let"
+
+#, c-format
+msgid "E684: list index out of range: %ld"
+msgstr "E684: Indeks listy poza zakresem: %ld"
+
+#, c-format
+msgid "E121: Undefined variable: %s"
+msgstr "E121: Nieokreœlona zmienna: %s"
+
+msgid "E111: Missing ']'"
+msgstr "E111: Brak ']'"
+
+#, c-format
+msgid "E686: Argument of %s must be a List"
+msgstr "E686: Argument %s musi byæ List¹"
+
+#, c-format
+msgid "E712: Argument of %s must be a List or Dictionary"
+msgstr "E712: Argument %s musi byæ List¹ lub S³ownikiem"
+
+msgid "E713: Cannot use empty key for Dictionary"
+msgstr "E713: Nie mo¿na u¿yæ pustego klucza dla S³ownika"
+
+msgid "E714: List required"
+msgstr "E714: wymagana Lista"
+
+msgid "E715: Dictionary required"
+msgstr "E715: wymagany S³ownik"
+
+#, c-format
+msgid "E118: Too many arguments for function: %s"
+msgstr "E118: Zbyt wiele argumentów dla funkcji: %s"
+
+#, c-format
+msgid "E716: Key not present in Dictionary: %s"
+msgstr "E716: Klucz nie istnieje w S³owniku: %s"
+
+#, c-format
+msgid "E122: Function %s already exists, add ! to replace it"
+msgstr "E122: Funkcja %s ju¿ istnieje; aby j¹ zamieniæ u¿yj !"
+
+msgid "E717: Dictionary entry already exists"
+msgstr "E717: istnieje ju¿ taki element S³ownika"
+
+msgid "E718: Funcref required"
+msgstr "E718: wymagana Funcref"
+
+msgid "E719: Cannot use [:] with a Dictionary"
+msgstr "E719: Nie mo¿na u¿yæ [:] przy S³owniku"
+
+#, c-format
+msgid "E734: Wrong variable type for %s="
+msgstr "E734: Z³y typ zmiennej dla %s="
+
+#, c-format
+msgid "E130: Unknown function: %s"
+msgstr "E130: Nieznana funkcja: %s"
+
+#, c-format
+msgid "E461: Illegal variable name: %s"
+msgstr "E461: Niedozwolona nazwa zmiennej: %s"
+
+msgid "E806: using Float as a String"
+msgstr "E806: U¿ycie Zmiennoprzecinkowej jako £añcucha"
+
+msgid "E687: Less targets than List items"
+msgstr "E687: Mniej celów ni¿ elementów Listy"
+
+msgid "E688: More targets than List items"
+msgstr "E688: Wiêcej celów ni¿ elementów Listy"
+
+msgid "Double ; in list of variables"
+msgstr "Podwójny ; w liœcie zmiennych"
+
+#, c-format
+msgid "E738: Can't list variables for %s"
+msgstr "E738: Nie mogê wypisaæ zmiennych dla %s"
+
+msgid "E689: Can only index a List or Dictionary"
+msgstr "E689: Indeks mo¿e istnieæ tylko dla Listy lub S³ownika"
+
+msgid "E708: [:] must come last"
+msgstr "E708: [:] musi byæ ostatnie"
+
+msgid "E709: [:] requires a List value"
+msgstr "E709: [:] wymaga wartoœci listy"
+
+msgid "E710: List value has more items than target"
+msgstr "E710: Lista ma wiêcej elementów ni¿ cel"
+
+msgid "E711: List value has not enough items"
+msgstr "E711: Lista nie ma wystarczaj¹cej iloœci elementów"
+
+msgid "E690: Missing \"in\" after :for"
+msgstr "E690: Brak \"in\" po :for"
+
+#, c-format
+msgid "E107: Missing parentheses: %s"
+msgstr "E107: Brak nawiasów: %s"
+
+#, c-format
+msgid "E108: No such variable: \"%s\""
+msgstr "E108: Nie istnieje zmienna: \"%s\""
+
+msgid "E743: variable nested too deep for (un)lock"
+msgstr "E743: zmienna zagnie¿d¿ona zbyt g³êboko dla (un)lock"
+
+msgid "E109: Missing ':' after '?'"
+msgstr "E109: Brak ':' po '?'"
+
+msgid "E691: Can only compare List with List"
+msgstr "E691: Listê mogê porównaæ tylko z List¹"
+
+msgid "E692: Invalid operation for Lists"
+msgstr "E692: Nieprawid³owa operacja dla Listy"
+
+msgid "E735: Can only compare Dictionary with Dictionary"
+msgstr "E735: S³ownik mogê porównaæ tylko ze S³ownikiem"
+
+msgid "E736: Invalid operation for Dictionary"
+msgstr "E736: Nieprawid³owa operacja dla S³ownika"
+
+msgid "E693: Can only compare Funcref with Funcref"
+msgstr "E693: Funcref mogê porównaæ tylko z Funcref"
+
+msgid "E694: Invalid operation for Funcrefs"
+msgstr "E694: Nieprawid³owa operacja dla Funcref"
+
+msgid "E804: Cannot use '%' with Float"
+msgstr "E804: Nie mogê u¿yæ '%' w Zmiennoprzecinkowej"
+
+msgid "E110: Missing ')'"
+msgstr "E110: Brak ')'"
+
+msgid "E695: Cannot index a Funcref"
+msgstr "E695: Nie mo¿na zindeksowaæ Funcref"
+
+#, c-format
+msgid "E112: Option name missing: %s"
+msgstr "E112: Brak nazwy opcji: %s"
+
+#, c-format
+msgid "E113: Unknown option: %s"
+msgstr "E113: Nieznana opcja: %s"
+
+#, c-format
+msgid "E114: Missing quote: %s"
+msgstr "E114: Brak cudzys³owu: %s"
+
+#, c-format
+msgid "E115: Missing quote: %s"
+msgstr "E115: Brak cudzys³owu: %s"
+
+#, c-format
+msgid "E696: Missing comma in List: %s"
+msgstr "E696: Brakuj¹cy przecinek w Liœcie: '%s"
+
+#, c-format
+msgid "E697: Missing end of List ']': %s"
+msgstr "E697: Brak zakoñczenia Listy ']': %s"
+
+#, c-format
+msgid "E720: Missing colon in Dictionary: %s"
+msgstr "E720: Brak dwukropka w S³owniku: %s"
+
+#, c-format
+msgid "E721: Duplicate key in Dictionary: \"%s\""
+msgstr "E721: Powtórzony klucz w S³owniku: \"%s\""
+
+#, c-format
+msgid "E722: Missing comma in Dictionary: %s"
+msgstr "E722: Brakuj¹cy przecinek w S³owniku: %s"
+
+#, c-format
+msgid "E723: Missing end of Dictionary '}': %s"
+msgstr "E723: Brak koñca w S³owniku '}': %s"
+
+msgid "E724: variable nested too deep for displaying"
+msgstr "E724: Zmienna zagnie¿d¿ona zbyt g³êboko by pokazaæ"
+
+#, c-format
+msgid "E740: Too many arguments for function %s"
+msgstr "E740: Zbyt wiele argumentów dla funkcji %s"
+
+#, c-format
+msgid "E116: Invalid arguments for function %s"
+msgstr "E116: Zbyt wiele argumentów dla funkcji %s"
+
+#, c-format
+msgid "E117: Unknown function: %s"
+msgstr "E117: Nieznana funkcja: %s"
+
+#, c-format
+msgid "E119: Not enough arguments for function: %s"
+msgstr "E119: Za ma³o argumentów dla funkcji: %s"
+
+#, c-format
+msgid "E120: Using <SID> not in a script context: %s"
+msgstr "E120: U¿ycie <SID> poza kontekstem skryptu: %s"
+
+#, c-format
+msgid "E725: Calling dict function without Dictionary: %s"
+msgstr "E725: Wywo³anie funkcji \"dict\" bez S³ownika: %s"
+
+msgid "E808: Number or Float required"
+msgstr "E808: Wymagana Liczba lub Zmiennoprzecinkowa"
+
+msgid "add() argument"
+msgstr "argument add()"
+
+msgid "E699: Too many arguments"
+msgstr "E699: Za du¿o argumentów"
+
+msgid "E785: complete() can only be used in Insert mode"
+msgstr "E785: complete() mo¿e byæ u¿yte tylko w trybie Wprowadzania"
+
+#.
+#. * 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"
+
+#, c-format
+msgid "E737: Key already exists: %s"
+msgstr "E737: Klucz ju¿ istnieje: %s"
+
+msgid "extend() argument"
+msgstr "argument extend()"
+
+msgid "map() argument"
+msgstr "argument map()"
+
+msgid "filter() argument"
+msgstr "argument filter()"
+
+#, c-format
+msgid "+-%s%3ld lines: "
+msgstr "+-%s%3ld wierszy: "
+
+#, c-format
+msgid "E700: Unknown function: %s"
+msgstr "E700: Nieznana funkcja: %s"
+
+msgid ""
+"&OK\n"
+"&Cancel"
+msgstr ""
+"&OK\n"
+"&Zakoñcz"
+
+msgid "called inputrestore() more often than inputsave()"
+msgstr "wywo³ano inputrestore() wiêcej razy ni¿ inputsave()"
+
+msgid "insert() argument"
+msgstr "argument insert()"
+
+msgid "E786: Range not allowed"
+msgstr "E786: Zakres niedozwolony"
+
+msgid "E701: Invalid type for len()"
+msgstr "E701: Nieprawid³owy typ dla len()"
+
+msgid "E726: Stride is zero"
+msgstr "E726: Skok to zero"
+
+msgid "E727: Start past end"
+msgstr "E727: Pocz¹tek po koñcu"
+
+msgid "<empty>"
+msgstr "<pusty>"
+
+msgid "E240: No connection to Vim server"
+msgstr "E240: Brak po³¹czenia z serwerem Vim"
+
+#, c-format
+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 "remove() argument"
+msgstr "argument remove()"
+
+msgid "E655: Too many symbolic links (cycle?)"
+msgstr "E655: Za du¿o dowi¹zañ symbolicznych (pêtla?)"
+
+msgid "reverse() argument"
+msgstr "argument reverse()"
+
+msgid "E258: Unable to send to client"
+msgstr "E258: Nie mogê wys³aæ do klienta"
+
+msgid "sort() argument"
+msgstr "argument sort()"
+
+msgid "E702: Sort compare function failed"
+msgstr "E702: Funkcja porównywania w sort nie powiod³a siê"
+
+msgid "(Invalid)"
+msgstr "(Niew³aœciwe)"
+
+msgid "E677: Error writing temp file"
+msgstr "E677: B³¹d zapisywania pliku tymczasowego"
+
+msgid "E805: Using a Float as a Number"
+msgstr "E805: U¿ycie Zmiennoprzecinkowej jako Liczby"
+
+msgid "E703: Using a Funcref as a Number"
+msgstr "E703: U¿ycie Funcref jako Liczby"
+
+msgid "E745: Using a List as a Number"
+msgstr "E745: U¿ycie Listy jako Liczby"
+
+msgid "E728: Using a Dictionary as a Number"
+msgstr "E728: U¿ycie S³ownika jako Liczby"
+
+msgid "E729: using Funcref as a String"
+msgstr "E729: U¿ycie Funcref jako £añcucha"
+
+msgid "E730: using List as a String"
+msgstr "E730: U¿ycie Listy jako £añcucha"
+
+msgid "E731: using Dictionary as a String"
+msgstr "E731: U¿ycie S³ownika jako £añcucha"
+
+#, c-format
+msgid "E706: Variable type mismatch for: %s"
+msgstr "E706: Nieprawid³owy typ zmiennej dla: %s"
+
+#, c-format
+msgid "E795: Cannot delete variable %s"
+msgstr "E795: Nie mogê usun¹æ zmiennej %s"
+
+#, c-format
+msgid "E704: Funcref variable name must start with a capital: %s"
+msgstr "E704: Nazwa Funcref musi siê zaczynaæ wielk¹ liter¹: %s"
+
+#, c-format
+msgid "E705: Variable name conflicts with existing function: %s"
+msgstr "E705: Nazwa zmiennej jest w konflikcie z istniej¹c¹ funkcj¹: %s"
+
+#, c-format
+msgid "E741: Value is locked: %s"
+msgstr "E741: WartoϾ jest zablokowana: %s"
+
+msgid "Unknown"
+msgstr "Nieznane"
+
+#, c-format
+msgid "E742: Cannot change value of %s"
+msgstr "E742: Nie mogê zmieniæ wartoœci %s"
+
+msgid "E698: variable nested too deep for making a copy"
+msgstr "E698: Zmienna zagnie¿d¿ona zbyt g³êboko by zrobiæ kopiê"
+
+#, c-format
+msgid "E123: Undefined function: %s"
+msgstr "E123: Nieznana funkcja: %s"
+
+#, c-format
+msgid "E124: Missing '(': %s"
+msgstr "E124: Brak '(': %s"
+
+msgid "E862: Cannot use g: here"
+msgstr "E862: Nie mo¿na tutaj u¿yæ g:"
+
+#, c-format
+msgid "E125: Illegal argument: %s"
+msgstr "E125: Niedozwolony argument: %s"
+
+#, c-format
+msgid "E853: Duplicate argument name: %s"
+msgstr "E853: Powtórzona nazwa argumentu: %s"
+
+msgid "E126: Missing :endfunction"
+msgstr "E126: Brak :endfunction"
+
+#, c-format
+msgid "E707: Function name conflicts with variable: %s"
+msgstr "E707: Nazwa funkcji jest w konflikcie ze zmienn¹: %s"
+
+#, c-format
+msgid "E127: Cannot redefine function %s: It is in use"
+msgstr "E127: Nie mogê redefiniowaæ funkcji %s: jest w u¿yciu"
+
+#, c-format
+msgid "E746: Function name does not match script file name: %s"
+msgstr "E746: Nazwa funkcji nie pasuje do nazwy skryptu: %s"
+
+msgid "E129: Function name required"
+msgstr "E129: Wymagana jest nazwa funkcji"
+
+#, c-format
+msgid "E128: Function name must start with a capital or contain a colon: %s"
+msgstr ""
+"E128: Nazwa funkcji musi rozpoczynaæ siê wielk¹ liter¹ lub zawieraæ "
+"dwukropek: %s"
+
+#, c-format
+msgid "E131: Cannot delete function %s: It is in use"
+msgstr "E131: Nie mogê skasowaæ funkcji %s: jest w u¿yciu"
+
+msgid "E132: Function call depth is higher than 'maxfuncdepth'"
+msgstr "E132: Zagnie¿d¿enie wywo³añ funkcji ponad 'maxfuncdepth'"
+
+#, c-format
+msgid "calling %s"
+msgstr "wywo³ujê %s"
+
+#, c-format
+msgid "%s aborted"
+msgstr "porzucono %s"
+
+#, c-format
+msgid "%s returning #%ld"
+msgstr "%s zwraca #%ld"
+
+#, c-format
+msgid "%s returning %s"
+msgstr "%s zwraca %s"
+
+#, c-format
+msgid "continuing in %s"
+msgstr "kontynuacja w %s"
+
+msgid "E133: :return not inside a function"
+msgstr "E133: :return poza funkcj¹"
+
+msgid ""
+"\n"
+"# global variables:\n"
+msgstr ""
+"\n"
+"# zmienne globalne:\n"
+
+msgid ""
+"\n"
+"\tLast set from "
+msgstr ""
+"\n"
+"\tOstatnie ustawienie przez "
+
+msgid "No old files"
+msgstr "Brak starych plików"
+
+msgid "Entering Debug mode. Type \"cont\" to continue."
+msgstr "Wchodzê w tryb odpluskwiania. WprowadŸ \"cont\" aby kontynuowaæ."
+
+#, c-format
+msgid "line %ld: %s"
+msgstr "wiersz %ld: %s"
+
+#, c-format
+msgid "cmd: %s"
+msgstr "cmd: %s"
+
+#, c-format
+msgid "Breakpoint in \"%s%s\" line %ld"
+msgstr "Punkt kontrolny w \"%s%s\" wiersz %ld"
+
+#, c-format
+msgid "E161: Breakpoint not found: %s"
+msgstr "E161: Nie znaleziono punktu kontrolnego: %s"
+
+msgid "No breakpoints defined"
+msgstr "Nie okreœlono ¿adnych punktów kontrolnych"
+
+#, c-format
+msgid "%3d %s %s line %ld"
+msgstr "%3d %s %s wiersz %ld"
+
+msgid "E750: First use \":profile start {fname}\""
+msgstr "E750: Pierwsze u¿ycie \":profile start {fname}\""
+
+msgid "Save As"
+msgstr "Zapisz jako"
+
+#, c-format
+msgid "Save changes to \"%s\"?"
+msgstr "Zachowaæ zmiany w \"%s\"?"
+
+msgid "Untitled"
+msgstr "Bez Tytu³u"
+
+#, c-format
+msgid "E162: No write since last change for buffer \"%s\""
+msgstr "E162: Nie zapisano zmian w buforze \"%s\""
+
+msgid "Warning: Entered other buffer unexpectedly (check autocommands)"
+msgstr "OSTRZE¯ENIE: Nieoczekiwane wejœcie w inny bufor (sprawdŸ autokomendy)"
+
+msgid "E163: There is only one file to edit"
+msgstr "E163: Tylko jeden plik w edycji"
+
+msgid "E164: Cannot go before first file"
+msgstr "E164: Nie mo¿na przejœæ przed pierwszy plik"
+
+msgid "E165: Cannot go beyond last file"
+msgstr "E165: Nie mo¿na przejœæ za ostatni plik"
+
+#, c-format
+msgid "E666: compiler not supported: %s"
+msgstr "E666: nie wspierany kompilator: %s"
+
+#, c-format
+msgid "Searching for \"%s\" in \"%s\""
+msgstr "Szukanie \"%s\" w \"%s\""
+
+#, c-format
+msgid "Searching for \"%s\""
+msgstr "Szukanie \"%s\""
+
+#, c-format
+msgid "not found in 'runtimepath': \"%s\""
+msgstr "nie znaleziono w 'runtimepath': \"%s\""
+
+msgid "Source Vim script"
+msgstr "Wczytaj skrypt Vima"
+
+#, c-format
+msgid "Cannot source a directory: \"%s\""
+msgstr "Nie mo¿na wczytaæ katalogu: \"%s\""
+
+#, c-format
+msgid "could not source \"%s\""
+msgstr "nie mog³em wczytaæ \"%s\""
+
+#, c-format
+msgid "line %ld: could not source \"%s\""
+msgstr "wiersz: %ld nie mog³em wczytaæ \"%s\""
+
+#, c-format
+msgid "sourcing \"%s\""
+msgstr "wczytywanie \"%s\""
+
+#, c-format
+msgid "line %ld: sourcing \"%s\""
+msgstr "wiersz %ld: wczytywanie \"%s\""
+
+#, c-format
+msgid "finished sourcing %s"
+msgstr "skoñczono wczytywanie %s"
+
+msgid "modeline"
+msgstr "modeline"
+
+msgid "--cmd argument"
+msgstr "--cmd argument"
+
+msgid "-c argument"
+msgstr "-c argument"
+
+msgid "environment variable"
+msgstr "zmienna œrodowiskowa"
+
+msgid "error handler"
+msgstr "obs³uga b³êdu"
+
+msgid "W15: Warning: Wrong line separator, ^M may be missing"
+msgstr "W15: OSTRZE¯ENIE: Niew³aœciwy separator wierszy, pewnie brak ^M"
+
+msgid "E167: :scriptencoding used outside of a sourced file"
+msgstr "E167: u¿yto :scriptencoding poza wczytywanym plikiem"
+
+msgid "E168: :finish used outside of a sourced file"
+msgstr "E168: u¿yto :finish poza wczytywanym plikiem"
+
+#, c-format
+msgid "Current %slanguage: \"%s\""
+msgstr "Bie¿¹cy %sjêzyk: \"%s\""
+
+#, c-format
+msgid "E197: Cannot set language to \"%s\""
+msgstr "E197: Nie mogê ustawiæ jêzyka na \"%s\""
+
+#, c-format
+msgid "<%s>%s%s %d, Hex %02x, Octal %03o"
+msgstr "<%s>%s%s %d, Hex %02x, Oktal %03o"
+
+#, c-format
+msgid "> %d, Hex %04x, Octal %o"
+msgstr "> %d, Hex %04x, Oktal %o"
+
+#, c-format
+msgid "> %d, Hex %08x, Octal %o"
+msgstr "> %d, Hex %08x, Oktal %o"
+
+msgid "E134: Move lines into themselves"
+msgstr "E134: Przeniesienie wierszy na siebie samych"
+
+msgid "1 line moved"
+msgstr "1 wiersz przeniesiony"
+
+#, c-format
+msgid "%ld lines moved"
+msgstr "%ld wiersze przeniesione"
+
+#, c-format
+msgid "%ld lines filtered"
+msgstr "%ld wierszy przefiltrowanych"
+
+msgid "E135: *Filter* Autocommands must not change current buffer"
+msgstr "E135: Autokomendy *Filter* nie mog¹ zmieniaæ bie¿¹cego bufora"
+
+msgid "[No write since last change]\n"
+msgstr "[Brak zapisu od czasu ostatniej zmiany]\n"
+
+#, c-format
+msgid "%sviminfo: %s in line: "
+msgstr "%sviminfo: %s w wierszu: "
+
+msgid "E136: viminfo: Too many errors, skipping rest of file"
+msgstr "E136: viminfo: Zbyt wiele b³êdów; pomijam resztê pliku"
+
+#, c-format
+msgid "Reading viminfo file \"%s\"%s%s%s"
+msgstr "Wczytujê plik viminfo \"%s\"%s%s%s"
+
+msgid " info"
+msgstr " informacja"
+
+msgid " marks"
+msgstr " zak³adki"
+
+msgid " oldfiles"
+msgstr " stare pliki"
+
+msgid " FAILED"
+msgstr " NIE POWIOD£O SIÊ"
+
+#. avoid a wait_return for this message, it's annoying
+#, c-format
+msgid "E137: Viminfo file is not writable: %s"
+msgstr "E137: Plik viminfo jest niezapisywalny: %s"
+
+#, c-format
+msgid "E138: Can't write viminfo file %s!"
+msgstr "E138: Nie mogê zapisaæ pliku viminfo %s!"
+
+#, c-format
+msgid "Writing viminfo file \"%s\""
+msgstr "Zapisujê plik viminfo \"%s\""
+
+#. Write the info:
+#, c-format
+msgid "# This viminfo file was generated by Vim %s.\n"
+msgstr "# Ten plik viminfo zosta³ wygenerowany przez Vima %s.\n"
+
+msgid ""
+"# You may edit it if you're careful!\n"
+"\n"
+msgstr ""
+"# Mo¿esz go ostro¿nie edytowaæ!\n"
+"\n"
+
+msgid "# Value of 'encoding' when this file was written\n"
+msgstr "# WartoϾ 'encoding' w czasie zapisu tego pliku\n"
+
+msgid "Illegal starting char"
+msgstr "Niedopuszczalny pocz¹tkowy znak"
+
+msgid "Write partial file?"
+msgstr "Zapisaæ czêœciowo plik?"
+
+msgid "E140: Use ! to write partial buffer"
+msgstr "E140: Stosuj ! do zapisania czêœciowo bufora"
+
+#, c-format
+msgid "Overwrite existing file \"%s\"?"
+msgstr "Nadpisaæ istniej¹cy plik \"%s\"?"
+
+#, c-format
+msgid "Swap file \"%s\" exists, overwrite anyway?"
+msgstr "Plik wymiany \"%s\" istnieje, czy go nadpisaæ?"
+
+#, c-format
+msgid "E768: Swap file exists: %s (:silent! overrides)"
+msgstr "E768: Plik wymiany istnieje: %s (wymuœ poprzez :silent!)"
+
+#, c-format
+msgid "E141: No file name for buffer %ld"
+msgstr "E141: Brak nazwy pliku dla bufora %ld"
+
+msgid "E142: File not written: Writing is disabled by 'write' option"
+msgstr "E142: Plik niezapisany: Zapis jest wy³¹czony opcj¹ 'write'"
+
+#, 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æ?"
+
+#, 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æ?"
+
+#, c-format
+msgid "E505: \"%s\" is read-only (add ! to override)"
+msgstr "E505: \"%s\" jest tylko do odczytu (dodaj ! aby wymusiæ)"
+
+msgid "Edit File"
+msgstr "Edytuj Plik"
+
+#, c-format
+msgid "E143: Autocommands unexpectedly deleted new buffer %s"
+msgstr "E143: Autokomendy nieoczekiwanie skasowa³y nowy bufor %s"
+
+msgid "E144: non-numeric argument to :z"
+msgstr "E144: nienumeryczny argument dla :z"
+
+msgid "E145: Shell commands not allowed in rvim"
+msgstr "E145: Komendy pow³oki s¹ niedozwolone w rvim"
+
+msgid "E146: Regular expressions can't be delimited by letters"
+msgstr "E146: Wzorce regularne nie mog¹ byæ rozgraniczane literami"
+
+#, c-format
+msgid "replace with %s (y/n/a/q/l/^E/^Y)?"
+msgstr "zamieñ na %s (y/n/a/q/l/^E/^Y)?"
+
+msgid "(Interrupted) "
+msgstr "(Przerwane) "
+
+msgid "1 match"
+msgstr "1 pasuje"
+
+msgid "1 substitution"
+msgstr "1 podstawienie "
+
+#, c-format
+msgid "%ld matches"
+msgstr "%ld dopasowañ"
+
+#, c-format
+msgid "%ld substitutions"
+msgstr "%ld podstawieñ"
+
+msgid " on 1 line"
+msgstr " w 1 wierszu"
+
+#, c-format
+msgid " on %ld lines"
+msgstr " w %ld wierszach"
+
+msgid "E147: Cannot do :global recursive"
+msgstr "E147: Nie mogê wykonaæ :global rekursywnie"
+
+msgid "E148: Regular expression missing from global"
+msgstr "E148: Brak wzorca regularnego w :global"
+
+# c-format
+#, c-format
+msgid "Pattern found in every line: %s"
+msgstr "Wzorzec znaleziono w ka¿dym wierszu: %s"
+
+#, c-format
+msgid "Pattern not found: %s"
+msgstr "Nie znaleziono wzorca: %s"
+
+msgid ""
+"\n"
+"# Last Substitute String:\n"
+"$"
+msgstr ""
+"\n"
+"# Ostatni podstawiany ci¹g:\n"
+"$"
+
+msgid "E478: Don't panic!"
+msgstr "E478: Nie panikuj!"
+
+#, c-format
+msgid "E661: Sorry, no '%s' help for %s"
+msgstr "E661: Przykro mi, brak '%s' pomocy dla %s"
+
+#, c-format
+msgid "E149: Sorry, no help for %s"
+msgstr "E149: Przykro mi, ale brak pomocy o %s"
+
+#, c-format
+msgid "Sorry, help file \"%s\" not found"
+msgstr "Przykro mi, nie ma pliku pomocy \"%s\""
+
+#, c-format
+msgid "E150: Not a directory: %s"
+msgstr "E150: Nie jest katalogiem: %s"
+
+#, c-format
+msgid "E152: Cannot open %s for writing"
+msgstr "E152: Nie mogê otworzyæ %s do zapisu"
+
+#, c-format
+msgid "E153: Unable to open %s for reading"
+msgstr "E153: Nie mogê otworzyæ %s do odczytu"
+
+#, 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"
+
+#, c-format
+msgid "E154: Duplicate tag \"%s\" in file %s/%s"
+msgstr "E154: Powtórzony znacznik \"%s\" w pliku %s/%s"
+
+#, c-format
+msgid "E160: Unknown sign command: %s"
+msgstr "E160: Nieznana komenda znaku: %s"
+
+msgid "E156: Missing sign name"
+msgstr "E156: Brak nazwy znaku"
+
+msgid "E612: Too many signs defined"
+msgstr "E612: Zbyt wiele nazw znaków"
+
+#, c-format
+msgid "E239: Invalid sign text: %s"
+msgstr "E239: Niew³aœciwy tekst znaku: %s"
+
+#, c-format
+msgid "E155: Unknown sign: %s"
+msgstr "E155: Nieznany znak: %s"
+
+msgid "E159: Missing sign number"
+msgstr "E159: Brak numeru znaku"
+
+#, c-format
+msgid "E158: Invalid buffer name: %s"
+msgstr "E158: Niew³aœciwa nazwa bufora: %s"
+
+#, c-format
+msgid "E157: Invalid sign ID: %ld"
+msgstr "E157: Niew³aœciwe ID znaku: %ld"
+
+msgid " (NOT FOUND)"
+msgstr " (NIE ZNALEZIONO)"
+
+msgid " (not supported)"
+msgstr "(nie wspomagane)"
+
+msgid "[Deleted]"
+msgstr "[Skasowano]"
+
+msgid "Entering Ex mode. Type \"visual\" to go to Normal mode."
+msgstr "Wchodzê w tryb Ex. WprowadŸ \"visual\" aby przejœæ do trybu Normal."
+
+msgid "E501: At end-of-file"
+msgstr "E501: Na koñcu pliku"
+
+msgid "E169: Command too recursive"
+msgstr "E169: Komenda zbyt rekursywna"
+
+#, c-format
+msgid "E605: Exception not caught: %s"
+msgstr "E605: Nie znaleziono wyj¹tku: %s"
+
+msgid "End of sourced file"
+msgstr "Koniec wczytywanego pliku"
+
+msgid "End of function"
+msgstr "Koniec funkcji"
+
+msgid "E464: Ambiguous use of user-defined command"
+msgstr ""
+"E464: Niejednoznaczne zastosowanie komendy zdefiniowanej przez u¿ytkownika"
+
+msgid "E492: Not an editor command"
+msgstr "E492: Nie jest komend¹ edytora"
+
+msgid "E493: Backwards range given"
+msgstr "E493: Dano wsteczny zakres"
+
+msgid "Backwards range given, OK to swap"
+msgstr "Dano wsteczny zakres; zamiana jest mo¿liwa"
+
+msgid "E494: Use w or w>>"
+msgstr "E494: Stosuj w lub w>>"
+
+msgid "E319: Sorry, the command is not available in this version"
+msgstr "E319: Przykro mi, ale ta komenda nie jest dostêpna w tej wersji"
+
+msgid "E172: Only one file name allowed"
+msgstr "E172: Tylko pojedyncza nazwa pliku dozwolona"
+
+msgid "1 more file to edit. Quit anyway?"
+msgstr "1 wiêcej plik do edycji. Mimo to wyjœæ?"
+
+#, c-format
+msgid "%d more files to edit. Quit anyway?"
+msgstr "jeszcze %d plików do edycji. Mimo to wyjœæ?"
+
+msgid "E173: 1 more file to edit"
+msgstr "E173: 1 wiêcej plik do edycji"
+
+#, c-format
+msgid "E173: %ld more files to edit"
+msgstr "E173: jeszcze %ld plików do edycji"
+
+msgid "E174: Command already exists: add ! to replace it"
+msgstr "E174: Komenda ju¿ istnieje; aby j¹ przedefiniowaæ stosuj !"
+
+msgid ""
+"\n"
+" Name Args Range Complete Definition"
+msgstr ""
+"\n"
+" Nazwa Arg. Zak. GotowoϾ Definicja"
+
+msgid "No user-defined commands found"
+msgstr "Nie znaleziono komend zdefiniowanych przez u¿ytkownika"
+
+msgid "E175: No attribute specified"
+msgstr "E175: Nie okreœlono atrybutu"
+
+msgid "E176: Invalid number of arguments"
+msgstr "E176: Niew³aœciwa iloœæ argumentów"
+
+msgid "E177: Count cannot be specified twice"
+msgstr "E177: Mno¿nik nie mo¿e byæ podany dwukrotnie"
+
+msgid "E178: Invalid default value for count"
+msgstr "E178: Niew³aœciwa domyœlna wartoœæ mno¿nika"
+
+msgid "E179: argument required for -complete"
+msgstr "E179: -complete wymaga argumentu"
+
+#, c-format
+msgid "E181: Invalid attribute: %s"
+msgstr "E181: Niew³aœciwy atrybut: %s"
+
+msgid "E182: Invalid command name"
+msgstr "E182: Niew³aœciwa nazwa komendy"
+
+msgid "E183: User defined commands must start with an uppercase letter"
+msgstr ""
+"E183: Komendy zdefiniowane przez u¿ytkownika musz¹ rozpoczynaæ siê du¿¹ "
+"liter¹"
+
+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"
+
+#, c-format
+msgid "E184: No such user-defined command: %s"
+msgstr "E184: Nie ma takiej komendy u¿ytkownika: %s"
+
+#, c-format
+msgid "E180: Invalid complete value: %s"
+msgstr "E180: Niew³aœciwa wartoœæ dope³niania: %s"
+
+msgid "E468: Completion argument only allowed for custom completion"
+msgstr ""
+"E468: Argument depe³niania dozwolony wy³¹cznie dla dope³niania u¿ytkownika"
+
+msgid "E467: Custom completion requires a function argument"
+msgstr "E467: Dope³nianie u¿ytkownika wymaga funkcji jako argumentu"
+
+msgid "unknown"
+msgstr "nieznany"
+
+#, c-format
+msgid "E185: Cannot find color scheme '%s'"
+msgstr "E185: Nie mogê znaleŸæ zestawu kolorów '%s'"
+
+msgid "Greetings, Vim user!"
+msgstr "Witaj u¿ytkowniku Vima!"
+
+msgid "E784: Cannot close last tab page"
+msgstr "E784: Nie mogê zamkn¹æ ostatniej karty"
+
+msgid "Already only one tab page"
+msgstr "Jest ju¿ tylko jedna karta"
+
+msgid "Edit File in new window"
+msgstr "Edytuj plik w nowym oknie"
+
+#, c-format
+msgid "Tab page %d"
+msgstr "Karta %d"
+
+msgid "No swap file"
+msgstr "Brak pliku wymiany"
+
+msgid "Append File"
+msgstr "Do³¹cz plik"
+
+msgid "E747: Cannot change directory, buffer is modified (add ! to override)"
+msgstr ""
+"E747: Nie mogê zmieniæ katalogu, bufor zosta³ zmodyfikowany (dodaj ! aby "
+"wymusiæ)"
+
+msgid "E186: No previous directory"
+msgstr "E186: Nie ma poprzedniego katalogu"
+
+msgid "E187: Unknown"
+msgstr "E187: Nieznany"
+
+msgid "E465: :winsize requires two number arguments"
+msgstr "E465: :winsize wymaga dwóch argumentów numerycznych"
+
+#, c-format
+msgid "Window position: X %d, Y %d"
+msgstr "Pozycja okna: X %d, Y %d"
+
+msgid "E188: Obtaining window position not implemented for this platform"
+msgstr ""
+"E188: Pozyskiwanie pozycji okna nie jest zaimplementowane dla tego systemu"
+
+msgid "E466: :winpos requires two number arguments"
+msgstr "E466: :winpos wymaga dwóch argumentów numerycznych"
+
+msgid "Save Redirection"
+msgstr "Zapisz przekierowanie"
+
+msgid "Save View"
+msgstr "Zapisz widok"
+
+msgid "Save Session"
+msgstr "Zapisz sesjê"
+
+msgid "Save Setup"
+msgstr "Zapisz ustawienia"
+
+#, c-format
+msgid "E739: Cannot create directory: %s"
+msgstr "E739: Nie mogê utworzyæ katalogu: %s"
+
+#, c-format
+msgid "E189: \"%s\" exists (add ! to override)"
+msgstr "E189: \"%s\" istnieje (wymuœ poprzez !)"
+
+#, c-format
+msgid "E190: Cannot open \"%s\" for writing"
+msgstr "E190: Nie mogê otworzyæ \"%s\" do zapisu"
+
+#. set mark
+msgid "E191: Argument must be a letter or forward/backward quote"
+msgstr "E191: Argument musi byæ liter¹ albo cudzys³owem w przód/ty³"
+
+msgid "E192: Recursive use of :normal too deep"
+msgstr "E192: Rekursywne zastosowanie :normal za g³êbokie"
+
+msgid "E809: #< is not available without the +eval feature"
+msgstr "E809: #< nie jest dostêpne bez w³aœciwoœci +eval"
+
+msgid "E194: No alternate file name to substitute for '#'"
+msgstr "E194: Brak nazwy zamiennego pliku do podstawienia pod '#'"
+
+msgid "E495: no autocommand file name to substitute for \"<afile>\""
+msgstr "E495: brak nazwy pliku autokomend do podstawienia pod \"<afile>\""
+
+msgid "E496: no autocommand buffer number to substitute for \"<abuf>\""
+msgstr "E496: brak numeru bufora autokomend do podstawienia pod \"<abuf>\""
+
+msgid "E497: no autocommand match name to substitute for \"<amatch>\""
+msgstr "E497: brak nazwy dopasowania autokomend pod \"<amatch>\""
+
+msgid "E498: no :source file name to substitute for \"<sfile>\""
+msgstr "E498: brak nazwy pliku :source do postawienia pod \"<sfile>\""
+
+msgid "E842: no line number to use for \"<slnum>\""
+msgstr "E842: brak numeru linii by u¿yæ z \"<slnum>\""
+
+#, no-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\""
+
+msgid "E500: Evaluates to an empty string"
+msgstr "E500: Wynikiem jest pusty ci¹g"
+
+msgid "E195: Cannot open viminfo file for reading"
+msgstr "E195: Nie mogê otworzyæ pliku viminfo do odczytu"
+
+msgid "E196: No digraphs in this version"
+msgstr "E196: Brak dwugrafów w tej wersji"
+
+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
+#, c-format
+msgid "Exception thrown: %s"
+msgstr "Wyj¹tek: %s"
+
+#, c-format
+msgid "Exception finished: %s"
+msgstr "Wyj¹tek zakoñczony: %s"
+
+#, c-format
+msgid "Exception discarded: %s"
+msgstr "Wyj¹tek odrzucony: %s"
+
+#, c-format
+msgid "%s, line %ld"
+msgstr "%s, wiersz %ld"
+
+#. always scroll up, don't overwrite
+#, c-format
+msgid "Exception caught: %s"
+msgstr "Wyj¹tek przechwycony: %s"
+
+#, c-format
+msgid "%s made pending"
+msgstr "%s zosta³ zawieszony"
+
+#, c-format
+msgid "%s resumed"
+msgstr "%s przywrócony"
+
+#, c-format
+msgid "%s discarded"
+msgstr "%s odrzucony"
+
+msgid "Exception"
+msgstr "Wyj¹tek"
+
+msgid "Error and interrupt"
+msgstr "B³¹d i przerwanie"
+
+msgid "Error"
+msgstr "B³¹d"
+
+#. if (pending & CSTP_INTERRUPT)
+msgid "Interrupt"
+msgstr "Przerwanie"
+
+msgid "E579: :if nesting too deep"
+msgstr "E579: zbyt g³êbokie zagnie¿d¿enie :if"
+
+msgid "E580: :endif without :if"
+msgstr "E580: :endif bez :if"
+
+msgid "E581: :else without :if"
+msgstr "E581: :else bez :if"
+
+msgid "E582: :elseif without :if"
+msgstr "E582: :elseif bez :if"
+
+msgid "E583: multiple :else"
+msgstr "E583: wielokrotne :else"
+
+msgid "E584: :elseif after :else"
+msgstr "E584: :elseif po :else"
+
+msgid "E585: :while/:for nesting too deep"
+msgstr "E585: zbyt g³êbokie zagnie¿d¿enie :while/:for"
+
+msgid "E586: :continue without :while or :for"
+msgstr "E586: :continue bez :while lub :for"
+
+msgid "E587: :break without :while or :for"
+msgstr "E587: :break bez :while lub :for"
+
+msgid "E732: Using :endfor with :while"
+msgstr "E732: U¿ycie :endfor z :while"
+
+msgid "E733: Using :endwhile with :for"
+msgstr "E733: U¿ycie :endwhile z :for"
+
+msgid "E601: :try nesting too deep"
+msgstr "E601: zbyt g³êbokie zagnie¿d¿enie :try"
+
+msgid "E603: :catch without :try"
+msgstr "E603: :catch bez :try"
+
+#. Give up for a ":catch" after ":finally" and ignore it.
+#. * Just parse.
+msgid "E604: :catch after :finally"
+msgstr "E604: :catch za :finally"
+
+msgid "E606: :finally without :try"
+msgstr "E606: :finally bez :try"
+
+#. Give up for a multiple ":finally" and ignore it.
+msgid "E607: multiple :finally"
+msgstr "E607: wielokrotne :finally"
+
+msgid "E602: :endtry without :try"
+msgstr "E602: :endtry bez :try"
+
+msgid "E193: :endfunction not inside a function"
+msgstr "E193: :endfunction poza funkcj¹"
+
+msgid "E788: Not allowed to edit another buffer now"
+msgstr "E788: Nie mo¿na teraz edytowaæ innego bufora"
+
+msgid "E811: Not allowed to change buffer information now"
+msgstr "E811: Nie mo¿na teraz zmieniaæ informacji o buforze"
+
+msgid "tagname"
+msgstr "nazwa znacznika"
+
+msgid " kind file\n"
+msgstr " pokrewny plik\n"
+
+msgid "'history' option is zero"
+msgstr "opcja 'history' jest zerowa"
+
+#, c-format
+msgid ""
+"\n"
+"# %s History (newest to oldest):\n"
+msgstr ""
+"\n"
+"# %s Historia (od najnowszych po najstarsze):\n"
+
+msgid "Command Line"
+msgstr "Wiersz poleceñ"
+
+msgid "Search String"
+msgstr "Szukany ci¹g"
+
+msgid "Expression"
+msgstr "Wyra¿enie"
+
+msgid "Input Line"
+msgstr "Wiersz wprowadzeñ"
+
+msgid "E198: cmd_pchar beyond the command length"
+msgstr "E198: cmd_pchar przekracza d³ugoœæ polecenia"
+
+msgid "E199: Active window or buffer deleted"
+msgstr "E199: Aktywny widok lub bufor skasowany"
+
+msgid "E812: Autocommands changed buffer or buffer name"
+msgstr "E812: Autokomendy zmieni³y bufor lub jego nazwê"
+
+msgid "Illegal file name"
+msgstr "Niedopuszczalna nazwa pliku"
+
+msgid "is a directory"
+msgstr "jest katalogiem"
+
+msgid "is not a file"
+msgstr "nie jest plikiem"
+
+msgid "is a device (disabled with 'opendevice' option)"
+msgstr "jest urz¹dzeniem (wy³¹czonym w opcji 'opendevice')"
+
+msgid "[New File]"
+msgstr "[Nowy Plik]"
+
+msgid "[New DIRECTORY]"
+msgstr "[Nowy KATALOG]"
+
+msgid "[File too big]"
+msgstr "[Za du¿y plik]"
+
+msgid "[Permission Denied]"
+msgstr "[Nie dozwolono]"
+
+msgid "E200: *ReadPre autocommands made the file unreadable"
+msgstr "E200: Autokomendy *ReadPre zrobi³y plik nieodczytywalnym"
+
+msgid "E201: *ReadPre autocommands must not change current buffer"
+msgstr "E201: Autokomendy *ReadPre nie mog¹ zmieniaæ bie¿¹cego bufora"
+
+msgid "Vim: Reading from stdin...\n"
+msgstr "Vim: Wczytywanie ze stdin...\n"
+
+msgid "Reading from stdin..."
+msgstr "Wczytywanie ze stdin..."
+
+#. Re-opening the original file failed!
+msgid "E202: Conversion made file unreadable!"
+msgstr "E202: Nie mo¿na otworzyæ pliku utworzonego przez przemianê!"
+
+msgid "[fifo/socket]"
+msgstr "[fifo/socket]"
+
+msgid "[fifo]"
+msgstr "[fifo]"
+
+msgid "[socket]"
+msgstr "[socket]"
+
+msgid "[character special]"
+msgstr "[specjalny znak]"
+
+msgid "[CR missing]"
+msgstr "[brak CR]'"
+
+msgid "[long lines split]"
+msgstr "[d³ugie wiersze rozdzielane]"
+
+msgid "[NOT converted]"
+msgstr "[NIE przemienione]"
+
+msgid "[converted]"
+msgstr "[przemienione]"
+
+msgid "[blowfish]"
+msgstr "[blowfish]"
+
+msgid "[crypted]"
+msgstr "[zakodowane]"
+
+#, c-format
+msgid "[CONVERSION ERROR in line %ld]"
+msgstr "[B£¥D W PRZEMIANIE w linii %ld]"
+
+#, c-format
+msgid "[ILLEGAL BYTE in line %ld]"
+msgstr "[NIEDOZWOLONY BAJT w wierszu %ld]"
+
+msgid "[READ ERRORS]"
+msgstr "[B£ÊDY W ODCZYCIE]"
+
+msgid "Can't find temp file for conversion"
+msgstr "Nie mogê znaleŸæ pliku tymczasowego w celu przemiany"
+
+msgid "Conversion with 'charconvert' failed"
+msgstr "Nieudana przemiana z 'charconvert'"
+
+msgid "can't read output of 'charconvert'"
+msgstr "nie mogê odczytaæ wyjœcia z 'charconvert'"
+
+msgid "E821: File is encrypted with unknown method"
+msgstr "E821: Plik zaszyfrowano w nieznany sposób"
+
+msgid "E676: No matching autocommands for acwrite buffer"
+msgstr "E676: Brak pasuj¹cych autokomend dla bufora acwrite"
+
+msgid "E203: Autocommands deleted or unloaded buffer to be written"
+msgstr ""
+"E203: Autokomendy skasowa³y lub wy³adowa³y bufor przeznaczony do zapisu"
+
+msgid "E204: Autocommand changed number of lines in unexpected way"
+msgstr "E204: Autokomenda zmieni³a liczbê wierszy w nieoczekiwany 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 "is not a file or writable device"
+msgstr "nie jest plikiem lub zapisywalnym przyrz¹dem"
+
+msgid "writing to device disabled with 'opendevice' option"
+msgstr "zapisywanie do urz¹dzenia wy³¹czone w opcji 'opendevice'"
+
+msgid "is read-only (add ! to override)"
+msgstr "jest tylko do odczytu (wymuœ poprzez !)"
+
+msgid "E506: Can't write to backup file (add ! to override)"
+msgstr "E506: Nie mogê zapisaæ do pliku zabezpieczenia (wymuœ przez !)"
+
+msgid "E507: Close error for backup file (add ! to override)"
+msgstr "E507: B³¹d podczas zamykania pliku zabezpieczenia (wymuœ przez !)"
+
+msgid "E508: Can't read file for backup (add ! to override)"
+msgstr "E508: Nie mogê odczytaæ pliku w celu zabezpieczenia (wymuœ przez !)"
+
+msgid "E509: Cannot create backup file (add ! to override)"
+msgstr "E509: Nie mogê stworzyæ pliku zabezpieczenia (wymuœ przez !)"
+
+msgid "E510: Can't make backup file (add ! to override)"
+msgstr "E510: Nie mogê zrobiæ pliku zabezpieczenia (wymuœ przez !)"
+
+msgid "E460: The resource fork would be lost (add ! to override)"
+msgstr "E460: Rozdzia³ zasobów zostanie utracony (wymuœ przez !)"
+
+msgid "E214: Can't find temp file for writing"
+msgstr "E214: Nie mogê znaleŸæ pliku tymczasowego do zapisania"
+
+msgid "E213: Cannot convert (add ! to write without conversion)"
+msgstr "E213: Nie mogê przemieniæ (u¿yj ! by zapisaæ bez przemiany)"
+
+msgid "E166: Can't open linked file for writing"
+msgstr "E166: Nie mogê otworzyæ pod³¹czonego pliku do zapisu"
+
+msgid "E212: Can't open file for writing"
+msgstr "E212: Nie mogê otworzyæ pliku do zapisu"
+
+msgid "E667: Fsync failed"
+msgstr "E667: Fsync nie powiód³ siê"
+
+msgid "E512: Close failed"
+msgstr "E512: Zamkniêcie siê nie powiod³o"
+
+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æ)"
+
+#, c-format
+msgid ""
+"E513: write error, conversion failed in line %ld (make 'fenc' empty to "
+"override)"
+msgstr ""
+"E513: B³¹d zapisu, przemiana siê nie powiod³a w wierszu %ld (opró¿nij 'fenc' "
+"by wymusiæ)"
+
+msgid "E514: write error (file system full?)"
+msgstr "E514: b³¹d w zapisie (mo¿e system plików jest przepe³niony?)"
+
+msgid " CONVERSION ERROR"
+msgstr " B£¥D W PRZEMIANIE"
+
+#, c-format
+msgid " in line %ld;"
+msgstr " w wierszu %ld;"
+
+msgid "[Device]"
+msgstr "[Urz¹dzenie]"
+
+msgid "[New]"
+msgstr "[Nowy]"
+
+msgid " [a]"
+msgstr " [a]"
+
+msgid " appended"
+msgstr " do³¹czono"
+
+msgid " [w]"
+msgstr " [w]"
+
+msgid " written"
+msgstr " zapisano"
+
+msgid "E205: Patchmode: can't save original file"
+msgstr "E205: Patchmode: nie mogê zapisaæ oryginalnego pliku"
+
+msgid "E206: patchmode: can't touch empty original file"
+msgstr "E206: patchmode: nie mogê stworzyæ pustego oryginalnego pliku"
+
+msgid "E207: Can't delete backup file"
+msgstr "E207: Nie mogê skasowaæ pliku zabezpieczenia"
+
+msgid ""
+"\n"
+"WARNING: Original file may be lost or damaged\n"
+msgstr ""
+"\n"
+"OSTRZE¯ENIE: Oryginalny plik mo¿e zostaæ utracony lub uszkodzony\n"
+
+msgid "don't quit the editor until the file is successfully written!"
+msgstr "nie wychodŸ edytora, dopóki plik nie zosta³ poprawnie zapisany!"
+
+msgid "[dos]"
+msgstr "[dos]"
+
+msgid "[dos format]"
+msgstr "[format dos-a]"
+
+msgid "[mac]"
+msgstr "[mac]"
+
+msgid "[mac format]"
+msgstr "[format maca]"
+
+msgid "[unix]"
+msgstr "[unix]"
+
+msgid "[unix format]"
+msgstr "[format unixa]"
+
+msgid "1 line, "
+msgstr "1 wiersz, "
+
+#, c-format
+msgid "%ld lines, "
+msgstr "%ld wierszy, "
+
+msgid "1 character"
+msgstr "1 znak"
+
+#, c-format
+msgid "%lld characters"
+msgstr "%lld znaków"
+
+#. Explicit typecast avoids warning on Mac OS X 10.6
+#, c-format
+msgid "%ld characters"
+msgstr "%ld znaków"
+
+msgid "[noeol]"
+msgstr "[noeol]"
+
+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
+msgid "WARNING: The file has been changed since reading it!!!"
+msgstr "OSTRZE¯ENIE: Plik zmieni³ siê od czasu ostatniego odczytu!!!"
+
+msgid "Do you really want to write to it"
+msgstr "Czy naprawdê chcesz go zapisaæ"
+
+#, c-format
+msgid "E208: Error writing to \"%s\""
+msgstr "E208: B³¹d zapisywania do \"%s\""
+
+#, c-format
+msgid "E209: Error closing \"%s\""
+msgstr "E209: B³¹d w trakcie zamykania \"%s\""
+
+#, c-format
+msgid "E210: Error reading \"%s\""
+msgstr "E210: B³¹d odczytu \"%s\""
+
+msgid "E246: FileChangedShell autocommand deleted buffer"
+msgstr "E246: Autokomenda FileChangedShell skasowa³a bufor"
+
+#, c-format
+msgid "E211: File \"%s\" no longer available"
+msgstr "E211: Plik \"%s\" nie jest d³u¿ej dostêpny"
+
+#, 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"
+
+msgid "See \":help W12\" for more info."
+msgstr "Zobacz \":help W12\" dla dalszych informacji."
+
+#, 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"
+
+msgid "See \":help W11\" for more info."
+msgstr "Zobacz \":help W11\" dla dalszych informacji."
+
+#, 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"
+
+msgid "See \":help W16\" for more info."
+msgstr "Zobacz \":help W16\" dla dalszych informacji."
+
+#, 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"
+
+msgid "Warning"
+msgstr "OSTRZE¯ENIE"
+
+msgid ""
+"&OK\n"
+"&Load File"
+msgstr ""
+"&OK\n"
+"&Za³aduj Plik"
+
+#, c-format
+msgid "E462: Could not prepare for reloading \"%s\""
+msgstr "E462: Nie mo¿na przygotowaæ prze³adowania \"%s\""
+
+#, c-format
+msgid "E321: Could not reload \"%s\""
+msgstr "E321: Nie mo¿na prze³adowaæ \"%s\""
+
+msgid "--Deleted--"
+msgstr "--Skasowano--"
+
+#, c-format
+msgid "auto-removing autocommand: %s <buffer=%d>"
+msgstr "auto-usuwanie autokomendy: %s <buffer=%d>"
+
+#. the group doesn't exist
+#, c-format
+msgid "E367: No such group: \"%s\""
+msgstr "E367: Nie ma takiej grupy: \"%s\""
+
+#, c-format
+msgid "E215: Illegal character after *: %s"
+msgstr "E215: Niedopuszczalny znak po *: %s"
+
+#, c-format
+msgid "E216: No such event: %s"
+msgstr "E216: Nie ma takiego wydarzenia: %s"
+
+#, c-format
+msgid "E216: No such group or event: %s"
+msgstr "E216: Nie ma takiej grupy lub wydarzenia: %s"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Auto-Commands ---"
+msgstr ""
+"\n"
+"--- Autokomendy ---"
+
+#, c-format
+msgid "E680: <buffer=%d>: invalid buffer number "
+msgstr "E680: <buffer=%d>: niew³aœciwy numer bufora"
+
+msgid "E217: Can't execute autocommands for ALL events"
+msgstr "E217: Nie mo¿na wykonywaæ autokomend dla wydarzeñ ALL"
+
+msgid "No matching autocommands"
+msgstr "Brak pasuj¹cych autokomend"
+
+msgid "E218: autocommand nesting too deep"
+msgstr "E218: zbyt g³êbokie zagnie¿d¿enie autokomend"
+
+#, c-format
+msgid "%s Auto commands for \"%s\""
+msgstr "%s Autokomend dla \"%s\""
+
+#, c-format
+msgid "Executing %s"
+msgstr "Wykonujê %s"
+
+#, c-format
+msgid "autocommand %s"
+msgstr "autokomenda %s"
+
+msgid "E219: Missing {."
+msgstr "E219: Brak {."
+
+msgid "E220: Missing }."
+msgstr "E220: Brak }."
+
+msgid "E490: No fold found"
+msgstr "E490: Nie znaleziono zwiniêcia"
+
+msgid "E350: Cannot create fold with current 'foldmethod'"
+msgstr "E350: Nie mo¿na utworzyæ zwiniêcia przy bie¿¹cej 'foldmethod'"
+
+msgid "E351: Cannot delete fold with current 'foldmethod'"
+msgstr "E351: Nie mo¿na skasowaæ zwiniêcia przy bie¿¹cej 'foldmethod'"
+
+#, c-format
+msgid "+--%3ld lines folded "
+msgstr "+--%3ld wierszy zwiniêto "
+
+msgid "E222: Add to read buffer"
+msgstr "E222: Dodaj do bufora odczytu"
+
+msgid "E223: recursive mapping"
+msgstr "E223: rekursywne przyporz¹dkowanie"
+
+#, c-format
+msgid "E224: global abbreviation already exists for %s"
+msgstr "E224: istnieje ju¿ globalny skrót dla %s"
+
+#, c-format
+msgid "E225: global mapping already exists for %s"
+msgstr "E225: istnieje ju¿ globalne przyporz¹dkowanie dla %s"
+
+#, c-format
+msgid "E226: abbreviation already exists for %s"
+msgstr "E226: istnieje ju¿ skrót dla %s"
+
+#, c-format
+msgid "E227: mapping already exists for %s"
+msgstr "E227: istnieje ju¿ przyporz¹dkowanie dla %s"
+
+msgid "No abbreviation found"
+msgstr "Nie znaleziono skrótu"
+
+msgid "No mapping found"
+msgstr "Nie znaleziono przyporz¹dkowania"
+
+msgid "E228: makemap: Illegal mode"
+msgstr "E228: makemap: Niedopuszczalny tryb"
+
+msgid "<cannot open> "
+msgstr "<nie mogê otworzyæ> "
+
+#, c-format
+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"
+
+#, c-format
+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'"
+
+#, c-format
+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 ""
+"&Yes\n"
+"&No\n"
+"&Cancel"
+msgstr ""
+"&Tak\n"
+"&Nie\n"
+"&Zakoñcz"
+
+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:"
+
+#. whole word only button
+msgid "Match whole word only"
+msgstr "Dopasuj tylko ca³e wyrazy"
+
+#. match case button
+msgid "Match case"
+msgstr "Dopasuj wielkoϾ liter"
+
+msgid "Direction"
+msgstr "Kierunek"
+
+#. 'Up' and 'Down' buttons
+msgid "Up"
+msgstr "W górê"
+
+msgid "Down"
+msgstr "W dó³"
+
+#. 'Find Next' button
+msgid "Find Next"
+msgstr "ZnajdŸ nastêpne"
+
+#. 'Replace' button
+msgid "Replace"
+msgstr "Zamieñ"
+
+#. 'Replace All' button
+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"
+
+#, c-format
+msgid "E671: Cannot find window title \"%s\""
+msgstr "E671: Nie mogê znaleŸæ tytu³u okna \"%s\""
+
+#, c-format
+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 '\\')"
+
+#. 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 "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"
+
+#, c-format
+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:"
+
+#, c-format
+msgid "E252: Fontset name: %s"
+msgstr "E252: Nazwa zestawu czcionek: %s"
+
+#, c-format
+msgid "Font '%s' is not fixed-width"
+msgstr "Czcionka '%s' nie posiada znaków jednolitej szerokoœci"
+
+#, c-format
+msgid "E253: Fontset name: %s"
+msgstr "E253: Nazwa zestawu czcionek: %s"
+
+#, c-format
+msgid "Font0: %s"
+msgstr "Font0: %s"
+
+#, c-format
+msgid "Font1: %s"
+msgstr "Font1: %s"
+
+#, c-format
+msgid "Font%ld width is not twice that of font0"
+msgstr "Szerokoœæ font%ld nie jest podwójn¹ szerokoœci¹ font0"
+
+#, c-format
+msgid "Font0 width: %ld"
+msgstr "SzerokoϾ font0: %ld"
+
+#, c-format
+msgid "Font1 width: %ld"
+msgstr "SzerokoϾ font1: %ld"
+
+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:"
+
+#. create toggle button
+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 "E550: Missing colon"
+msgstr "E550: Brak dwukropka"
+
+msgid "E551: Illegal component"
+msgstr "E551: Niedozwolona czêœæ"
+
+msgid "E552: digit expected"
+msgstr "E552: oczekiwa³em na cyfrê"
+
+#, c-format
+msgid "Page %d"
+msgstr "Strona %d"
+
+msgid "No text to be printed"
+msgstr "Brak tekstu do drukowania"
+
+#, c-format
+msgid "Printing page %d (%d%%)"
+msgstr "Drukujê stronê %d (%d%%)"
+
+#, c-format
+msgid " Copy %d of %d"
+msgstr " Kopia %d z %d"
+
+#, c-format
+msgid "Printed: %s"
+msgstr "Wydrukowano: %s"
+
+msgid "Printing aborted"
+msgstr "Drukowanie odwo³ane"
+
+msgid "E455: Error writing to PostScript output file"
+msgstr "E455: Nie mo¿na zapisaæ do wyjœciowego pliku PostScriptu"
+
+#, c-format
+msgid "E624: Can't open file \"%s\""
+msgstr "E624: Nie mogê otworzyæ pliku \"%s\""
+
+#, c-format
+msgid "E457: Can't read PostScript resource file \"%s\""
+msgstr "E457: Nie mo¿na odczytaæ pliku zasobów PostScriptu \"%s\""
+
+#, c-format
+msgid "E618: file \"%s\" is not a PostScript resource file"
+msgstr "E618: plik \"%s\" nie jest plikiem zasobów PostScriptu"
+
+#, c-format
+msgid "E619: file \"%s\" is not a supported PostScript resource file"
+msgstr "E619: plik \"%s\" nie jest wspieranym plikiem zasobów PostScriptu"
+
+#, c-format
+msgid "E621: \"%s\" resource file has wrong version"
+msgstr "E621: \"%s\" nieprawid³owa wersja pliku zasobów"
+
+msgid "E673: Incompatible multi-byte encoding and character set."
+msgstr "E673: Niekompatybilne kodowanie wielobajtowe i zestaw znaków."
+
+msgid "E674: printmbcharset cannot be empty with multi-byte encoding."
+msgstr "E674: printmbcharset nie mo¿e byæ pusty przy kodowaniu wielobajtowym."
+
+msgid "E675: No default font specified for multi-byte printing."
+msgstr "E675: Nie okreœlono domyœlnej czcionki dla drukowania wielobajtowego."
+
+msgid "E324: Can't open PostScript output file"
+msgstr "E324: Nie mo¿na otworzyæ pliku PostScript do wyjœcia"
+
+#, c-format
+msgid "E456: Can't open file \"%s\""
+msgstr "E456: Nie mogê otworzyæ pliku \"%s\""
+
+msgid "E456: Can't find PostScript resource file \"prolog.ps\""
+msgstr "E456: Nie mo¿na znaleŸæ pliku zasobów PostScriptu \"prolog.ps\""
+
+msgid "E456: Can't find PostScript resource file \"cidfont.ps\""
+msgstr "E456: Nie mo¿na znaleŸæ pliku zasobów PostScriptu \"cidfont.ps\""
+
+#, c-format
+msgid "E456: Can't find PostScript resource file \"%s.ps\""
+msgstr "E456: Nie mo¿na znaleŸæ pliku zasobów PostScriptu \"%s.ps\""
+
+#, c-format
+msgid "E620: Unable to convert to print encoding \"%s\""
+msgstr "E620: Nie mo¿na przekonwertowaæ by drukowaæ kodowanie \"%s\""
+
+msgid "Sending to printer..."
+msgstr "Przesy³am do drukarki..."
+
+msgid "E365: Failed to print PostScript file"
+msgstr "E365: Drukowanie pliku PostScript nie powiod³o siê"
+
+msgid "Print job sent."
+msgstr "Zadanie drukowanie przes³ane."
+
+msgid "Add a new database"
+msgstr "Dodaj now¹ bazê danych"
+
+msgid "Query for a pattern"
+msgstr "Zapytane o wzorzec"
+
+msgid "Show this message"
+msgstr "Poka¿ ten komunikat"
+
+msgid "Kill a connection"
+msgstr "Zabij po³¹czenie"
+
+msgid "Reinit all connections"
+msgstr "Ponów wszelkie po³¹czenia"
+
+msgid "Show connections"
+msgstr "Poka¿ po³¹czenia"
+
+#, c-format
+msgid "E560: Usage: cs[cope] %s"
+msgstr "E560: Zastosowanie: cs[cope] %s"
+
+msgid "This cscope command does not support splitting the window.\n"
+msgstr "Ta komenda cscope nie wspomaga podzielenia okna.\n"
+
+msgid "E562: Usage: cstag <ident>"
+msgstr "E562: Zastosowanie: cstag <ident>"
+
+msgid "E257: cstag: tag not found"
+msgstr "E257: cstag: nie znaleziono znacznika"
+
+#, c-format
+msgid "E563: stat(%s) error: %d"
+msgstr "E563: stat(%s) b³¹d: %d"
+
+msgid "E563: stat error"
+msgstr "E563: b³¹d stat"
+
+#, 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"
+
+#, c-format
+msgid "Added cscope database %s"
+msgstr "Dodano bazê danych cscope %s"
+
+#, c-format
+msgid "E262: error reading cscope connection %ld"
+msgstr "E262: b³¹d odczytu po³¹czenia z cscope %ld"
+
+msgid "E561: unknown cscope search type"
+msgstr "E561: nieznany typ szukania cscope"
+
+msgid "E566: Could not create cscope pipes"
+msgstr "E566: Nie mog³em stworzyæ potoku do cscope"
+
+msgid "E622: Could not fork for cscope"
+msgstr "E622: Nie mog³em utworzyæ rozwidlenia dla cscope"
+
+msgid "cs_create_connection setpgid failed"
+msgstr "nie powiod³o siê setpgid cs_create_connection"
+
+msgid "cs_create_connection exec failed"
+msgstr "wykonanie cs_create_connection nie powiod³o siê"
+
+msgid "cs_create_connection: fdopen for to_fp failed"
+msgstr "cs_create_connection: fdopen dla to_fp nie powiod³o siê"
+
+msgid "cs_create_connection: fdopen for fr_fp failed"
+msgstr "cs_create_connection: fdopen dla fr_fp nie powiod³o siê"
+
+msgid "E623: Could not spawn cscope process"
+msgstr "E623: Nie mog³em stworzyæ procesu cscope"
+
+msgid "E567: no cscope connections"
+msgstr "E567: brak po³¹czenia z cscope"
+
+#, c-format
+msgid "E469: invalid cscopequickfix flag %c for %c"
+msgstr "E469: nieprawid³owa flaga cscopequickfix %c dla %c"
+
+#, c-format
+msgid "E259: no matches found for cscope query %s of %s"
+msgstr "E259: brak dopasowañ dla zapytania cscope %s o %s"
+
+msgid "cscope commands:\n"
+msgstr "komendy cscope:\n"
+
+#, c-format
+msgid "%-5s: %s%*s (Usage: %s)"
+msgstr "%-5s: %s%*s (U¿ycie: %s)"
+
+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"
+
+#, c-format
+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 "E568: duplicate cscope database not added"
+msgstr "E568: nie dodano duplikatu bazy danych cscope"
+
+#, c-format
+msgid "E261: cscope connection %s not found"
+msgstr "E261: nie ma po³¹czenia %s z cscope"
+
+#, c-format
+msgid "cscope connection %s closed"
+msgstr "po³¹czenie %s z cscope zosta³o zamkniête"
+
+#. should not reach here
+msgid "E570: fatal error in cs_manage_matches"
+msgstr "E570: b³¹d krytyczny w cs_manage_matches"
+
+#, c-format
+msgid "Cscope tag: %s"
+msgstr "Znacznik cscope: %s"
+
+msgid ""
+"\n"
+" # line"
+msgstr ""
+"\n"
+" # wiersz"
+
+msgid "filename / context / line\n"
+msgstr "nazwa pliku / kontekst / wiersz\n"
+
+#, c-format
+msgid "E609: Cscope error: %s"
+msgstr "E609: B³¹d cscope: %s"
+
+msgid "All cscope databases reset"
+msgstr "Wszystkie bazy danych cscope prze³adowano"
+
+msgid "no cscope connections\n"
+msgstr "brak po³¹czeñ z cscope\n"
+
+msgid " # pid database name prepend path\n"
+msgstr " # pid nazwa bazy danych przedsionek tropu\n"
+
+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"
+
+#, c-format
+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"
+
+#, c-format
+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"
+
+#, c-format
+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"
+
+#. This should never happen. Famous last word?
+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."
+
+#, c-format
+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ê"
+
+#, c-format
+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 "Unknown option argument"
+msgstr "Nieznany argument opcji"
+
+msgid "Too many edit arguments"
+msgstr "Zbyt wiele argumentów"
+
+msgid "Argument missing after"
+msgstr "Brak argumentu po"
+
+msgid "Garbage after option argument"
+msgstr "Œmiecie po argumencie opcji"
+
+msgid "Too many \"+command\", \"-c command\" or \"--cmd command\" arguments"
+msgstr ""
+"Zbyt wiele argumentów \"+komenda\", \"-c komenda\" lub \"--cmd komenda\""
+
+msgid "Invalid argument for"
+msgstr "Niew³aœciwy argument dla"
+
+#, c-format
+msgid "%d files to edit\n"
+msgstr "%d plików do edycji\n"
+
+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 "Attempt to open script file again: \""
+msgstr "Próba ponownego otworzenia pliku skryptu: \""
+
+msgid "Cannot open for reading: \""
+msgstr "Nie mogê otworzyæ do odczytu: \""
+
+msgid "Cannot open for script output: \""
+msgstr "Nie mogê otworzyæ dla wyjœcia skryptu: \""
+
+msgid "Vim: Error: Failure to start gvim from NetBeans\n"
+msgstr "Vim: B³¹d: Nie mo¿na uruchomiæ gvim z NetBeans\n"
+
+msgid "Vim: Warning: Output is not to a terminal\n"
+msgstr "Vim: OSTRZE¯ENIE: Wyjœcie nie jest terminalem\n"
+
+msgid "Vim: Warning: Input is not from a terminal\n"
+msgstr "Vim: OSTRZE¯ENIE: Wejœcie nie pochodzi z terminala\n"
+
+#. just in case..
+msgid "pre-vimrc command line"
+msgstr "linia poleceñ pre-vimrc"
+
+#, c-format
+msgid "E282: Cannot read from \"%s\""
+msgstr "E282: Nie mogê czytaæ z \"%s\""
+
+msgid ""
+"\n"
+"More info with: \"vim -h\"\n"
+msgstr ""
+"\n"
+"Dalsze informacje poprzez: \"vim -h\"\n"
+
+msgid "[file ..] edit specified file(s)"
+msgstr "[plik ..] edytuj zadane pliki"
+
+msgid "- read text from stdin"
+msgstr "- czytaj tekst ze stdin"
+
+msgid "-t tag edit file where tag is defined"
+msgstr "-t znacznik edytuj plik, w którym dany znacznik jest zdefiniowany"
+
+msgid "-q [errorfile] edit file with first error"
+msgstr "-q [errorfile] edytuj plik, zawieraj¹cy pierwszy b³¹d"
+
+msgid ""
+"\n"
+"\n"
+"usage:"
+msgstr ""
+"\n"
+"\n"
+"u¿ycie:"
+
+msgid " vim [arguments] "
+msgstr " vim [argumenty]"
+
+msgid ""
+"\n"
+" or:"
+msgstr ""
+"\n"
+" lub:"
+
+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 ""
+"\n"
+"\n"
+"Arguments:\n"
+msgstr ""
+"\n"
+"\n"
+"Argumenty:\n"
+
+msgid "--\t\t\tOnly file names after this"
+msgstr "--\t\t\tTylko nazwy plików po tym"
+
+msgid "--literal\t\tDon't expand wildcards"
+msgstr "--literal\t\tNie rozwijaj znaków specjalnych"
+
+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 "-v\t\t\tVi mode (like \"vi\")"
+msgstr "-v\t\t\tTryb vi (jak \"vi\")"
+
+msgid "-e\t\t\tEx mode (like \"ex\")"
+msgstr "-e\t\t\tTryb ex (jak \"ex\")"
+
+msgid "-E\t\t\tImproved Ex mode"
+msgstr "-E\t\t\tUsprawniony tryb Ex"
+
+msgid "-s\t\t\tSilent (batch) mode (only for \"ex\")"
+msgstr "-s\t\t\tCichy tryb (t³a) (tylko dla \"ex\")"
+
+msgid "-d\t\t\tDiff mode (like \"vimdiff\")"
+msgstr "-d\t\t\tTryb ró¿nic (jak \"vimdiff\")"
+
+msgid "-y\t\t\tEasy mode (like \"evim\", modeless)"
+msgstr "-y\t\t\tTryb ³atwy (jak \"evim\", bez trybów)"
+
+msgid "-R\t\t\tReadonly mode (like \"view\")"
+msgstr "-R\t\t\tTryb wy³¹cznie do odczytu (jak \"view\")"
+
+msgid "-Z\t\t\tRestricted mode (like \"rvim\")"
+msgstr "-Z\t\t\tTryb ograniczenia (jak \"rvim\")"
+
+msgid "-m\t\t\tModifications (writing files) not allowed"
+msgstr "-m\t\t\tModyfikacje (zapisywanie plików) niedozwolone"
+
+msgid "-M\t\t\tModifications in text not allowed"
+msgstr "-M\t\t\tZakaz modyfikacji tekstu"
+
+msgid "-b\t\t\tBinary mode"
+msgstr "-b\t\t\tTryb binarny"
+
+msgid "-l\t\t\tLisp mode"
+msgstr "-l\t\t\tTryb lisp"
+
+msgid "-C\t\t\tCompatible with Vi: 'compatible'"
+msgstr "-C\t\t\tB¹dŸ zgodny z Vi: 'compatible'"
+
+msgid "-N\t\t\tNot fully Vi compatible: 'nocompatible'"
+msgstr "-N\t\t\tB¹dŸ niezupe³nie zgodny z Vi: 'nocompatible'"
+
+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]"
+
+msgid "-D\t\t\tDebugging mode"
+msgstr "-D\t\t\tTryb odpluskwiania"
+
+msgid "-n\t\t\tNo swap file, use memory only"
+msgstr "-n\t\t\tZamiast pliku wymiany, u¿ywaj tylko pamiêci"
+
+msgid "-r\t\t\tList swap files and exit"
+msgstr "-r\t\t\tWylicz pliki wymiany i zakoñcz"
+
+msgid "-r (with file name)\tRecover crashed session"
+msgstr "-r (z nazw¹ pliku)\tOdtwórz za³aman¹ sesjê"
+
+msgid "-L\t\t\tSame as -r"
+msgstr "-L\t\t\tTo¿same z -r"
+
+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 "-A\t\t\tstart in Arabic mode"
+msgstr "-A\t\t\trozpocznij w trybie arabskim"
+
+msgid "-H\t\t\tStart in Hebrew mode"
+msgstr "-H\t\t\trozpocznij w trybie hebrajskim"
+
+msgid "-F\t\t\tStart in Farsi mode"
+msgstr "-F\t\t\trozpocznij w trybie farsi"
+
+msgid "-T <terminal>\tSet terminal type to <terminal>"
+msgstr "-T <terminal>\tUstaw typ terminala na <terminal>"
+
+msgid "-u <vimrc>\t\tUse <vimrc> instead of any .vimrc"
+msgstr "-u <vimrc>\t\tU¿yj <vimrc> zamiast jakiegokolwiek .vimrc"
+
+msgid "-U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc"
+msgstr "-U <gvimrc>\t\tU¿yj <gvimrc> zamiast jakiegokolwiek .gvimrc"
+
+msgid "--noplugin\t\tDon't load plugin scripts"
+msgstr "--noplugin\t\tNie ³aduj skryptów wtyczek"
+
+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)"
+
+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)"
+
+msgid "-O[N]\t\tLike -o but split vertically"
+msgstr "-O[N]\t\ttak samo jak -o tylko dziel okno pionowo"
+
+msgid "+\t\t\tStart at end of file"
+msgstr "+\t\t\tZacznij na koñcu pliku"
+
+msgid "+<lnum>\t\tStart at line <lnum>"
+msgstr "+<lnum>\t\tZacznij w wierszu <lnum>"
+
+msgid "--cmd <command>\tExecute <command> before loading any vimrc file"
+msgstr ""
+"-cmd <command>\t\tWykonaj komendê <command> przed za³adowaniem "
+"jakiegokolwiek pliku vimrc"
+
+msgid "-c <command>\t\tExecute <command> after loading the first file"
+msgstr ""
+"-c <command>\t\tWykonaj komendê <command> po za³adowaniu pierwszego pliku"
+
+msgid "-S <session>\t\tSource file <session> after loading the first file"
+msgstr "-S <sesja>\t\tWczytaj plik <sesja> po za³adowaniu pierwszego pliku"
+
+msgid "-s <scriptin>\tRead Normal mode commands from file <scriptin>"
+msgstr "-s <scriptin>\tWczytuj komendy trybu normalnego z pliku <scriptin>"
+
+msgid "-w <scriptout>\tAppend all typed commands to file <scriptout>"
+msgstr ""
+"-w <scriptout>\tDo³¹cz wszystkie wprowadzane komendy do pliku <scriptout>"
+
+msgid "-W <scriptout>\tWrite all typed commands to file <scriptout>"
+msgstr ""
+"-W <scriptout>\tZapisuj wszystkie wprowadzane komendy do pliku <scriptout>"
+
+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 "--startuptime <file>\tWrite startup timing messages to <file>"
+msgstr ""
+"--startuptime <plik>\n"
+"Zapisz wiadomoœci o d³ugoœci startu do <plik>"
+
+msgid "-i <viminfo>\t\tUse <viminfo> instead of .viminfo"
+msgstr "-i <viminfo>\t\tU¿ywaj <viminfo> zamiast .viminfo"
+
+msgid "-h or --help\tPrint Help (this message) and exit"
+msgstr "-h lub --help\twyœwietl Pomoc (czyli tê wiadomoœæ) i zakoñcz"
+
+msgid "--version\t\tPrint version information and exit"
+msgstr "--version\t\twyœwietl informacjê o wersji i zakoñcz"
+
+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"
+
+#. Failed to send, abort.
+msgid ": Send failed.\n"
+msgstr ": Wys³anie nie powiod³o siê.\n"
+
+#. Let vim start normally.
+msgid ": Send failed. Trying to execute locally\n"
+msgstr ": Wys³anie nie powiod³o siê. Próbujê wykonaæ na miejscu\n"
+
+#, c-format
+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 "No marks set"
+msgstr "Brak zak³adek"
+
+#, c-format
+msgid "E283: No marks matching \"%s\""
+msgstr "E283: ¯adna zak³adka nie pasuje do \"%s\""
+
+#. Highlight title
+msgid ""
+"\n"
+"mark line col file/text"
+msgstr ""
+"\n"
+"zak³. wiersz kol plik/tekst"
+
+#. Highlight title
+msgid ""
+"\n"
+" jump line col file/text"
+msgstr ""
+"\n"
+" skok wiersz kol plik/tekst"
+
+#. Highlight title
+msgid ""
+"\n"
+"change line col text"
+msgstr ""
+"\n"
+"zmieñ wrsz. kol tekst"
+
+msgid ""
+"\n"
+"# File marks:\n"
+msgstr ""
+"\n"
+"# Zak³adki w plikach:\n"
+
+#. Write the jumplist with -'
+msgid ""
+"\n"
+"# Jumplist (newest first):\n"
+msgstr ""
+"\n"
+"# Lista odniesieñ (pocz¹wszy od najnowszych):\n"
+
+msgid ""
+"\n"
+"# History of marks within files (newest to oldest):\n"
+msgstr ""
+"\n"
+"# Historia zak³adek w plikach (od najnowszych po najstarsze):\n"
+
+msgid "Missing '>'"
+msgstr "Brak '>'"
+
+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 "E293: block was not locked"
+msgstr "E293: blok nie by³ zablokowany"
+
+msgid "E294: Seek error in swap file read"
+msgstr "E294: B³¹d w trakcie czytania pliku wymiany"
+
+msgid "E295: Read error in swap file"
+msgstr "E295: B³¹d odczytu pliku wymiany"
+
+msgid "E296: Seek error in swap file write"
+msgstr "E296: B³¹d szukania w pliku wymiany"
+
+msgid "E297: Write error in swap file"
+msgstr "E297: B³¹d zapisu w pliku wymiany"
+
+msgid "E300: Swap file already exists (symlink attack?)"
+msgstr "E300: Plik wymiany ju¿ istnieje (atak symlink?)"
+
+msgid "E298: Didn't get block nr 0?"
+msgstr "E298: Nie otrzyma³em bloku nr 0?"
+
+msgid "E298: Didn't get block nr 1?"
+msgstr "E298: Nie otrzyma³em bloku nr 1?"
+
+msgid "E298: Didn't get block nr 2?"
+msgstr "E298: Nie otrzyma³em bloku nr 2?"
+
+msgid "E843: Error while updating swap file crypt"
+msgstr "E843: B³¹d w czasie uaktualniania szyfrowania pliku wymiany"
+
+#. could not (re)open the swap file, what can we do????
+msgid "E301: Oops, lost the swap file!!!"
+msgstr "E301: Ojej, zgubi³em plik wymiany!!!"
+
+msgid "E302: Could not rename swap file"
+msgstr "E302: Nie mog³em zmieniæ nazwy pliku wymiany"
+
+#, 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"
+
+msgid "E304: ml_upd_block0(): Didn't get block 0??"
+msgstr "E304: ml_upd_block(): Nie otrzyma³em bloku 0??"
+
+#, c-format
+msgid "E305: No swap file found for %s"
+msgstr "E305: Nie znaleziono pliku wymiany dla %s"
+
+msgid "Enter number of swap file to use (0 to quit): "
+msgstr "WprowadŸ numer pliku wymiany, którego u¿yæ (0 by wyjœæ): "
+
+#, c-format
+msgid "E306: Cannot open %s"
+msgstr "E306: Nie mogê otworzyæ %s"
+
+msgid "Unable to read block 0 from "
+msgstr "Nie mogê odczytaæ bloku 0 z "
+
+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."
+
+msgid " cannot be used with this version of Vim.\n"
+msgstr " nie mo¿e byæ stosowany z t¹ wersj¹ Vima.\n"
+
+msgid "Use Vim version 3.0.\n"
+msgstr "U¿yj Vima w wersji 3.0.\n"
+
+#, c-format
+msgid "E307: %s does not look like a Vim swap file"
+msgstr "E307: %s nie wygl¹da na plik wymiany Vima"
+
+msgid " cannot be used on this computer.\n"
+msgstr " nie mo¿e byæ stosowany na tym komputerze.\n"
+
+msgid "The file was created on "
+msgstr "Ten plik zosta³ stworzony na "
+
+msgid ""
+",\n"
+"or the file has been damaged."
+msgstr ""
+",\n"
+"lub plik zosta³ uszkodzony."
+
+#, c-format
+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 " has been damaged (page size is smaller than minimum value).\n"
+msgstr ""
+" zosta³ uszkodzony (wielkoœæ strony jest mniejsza ni¿ najmniejsza wartoœæ).\n"
+
+#, c-format
+msgid "Using swap file \"%s\""
+msgstr "U¿ywam pliku wymiany \"%s\""
+
+#, c-format
+msgid "Original file \"%s\""
+msgstr "Oryginalny plik \"%s\""
+
+msgid "E308: Warning: Original file may have been changed"
+msgstr "E308: OSTRZE¯ENIE: Oryginalny plik móg³ byæ zmieniony"
+
+#, c-format
+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"
+
+#, c-format
+msgid "E309: Unable to read block 1 from %s"
+msgstr "E309: Nie mogê odczytaæ bloku 1 z %s"
+
+msgid "???MANY LINES MISSING"
+msgstr "???BRAKUJE WIELU WIERSZY"
+
+msgid "???LINE COUNT WRONG"
+msgstr "???LICZNIK WIERSZY NIEZGODNY"
+
+msgid "???EMPTY BLOCK"
+msgstr "???PUSTY BLOK"
+
+msgid "???LINES MISSING"
+msgstr "???BRAKUJE WIERSZY"
+
+#, 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?)"
+
+msgid "???BLOCK MISSING"
+msgstr "???BRAK BLOKU"
+
+msgid "??? from here until ???END lines may be messed up"
+msgstr "??? od tego miejsca po ???KONIEC wiersze mog¹ byæ pomieszane"
+
+msgid "??? from here until ???END lines may have been inserted/deleted"
+msgstr "??? od tego miejsca po ???KONIEC wiersze mog¹ byæ w³o¿one/skasowane"
+
+msgid "???END"
+msgstr "???KONIEC"
+
+msgid "E311: Recovery Interrupted"
+msgstr "E311: Przerwanie odtwarzania"
+
+msgid ""
+"E312: Errors detected while recovering; look for lines starting with ???"
+msgstr "E312: Wykryto b³êdy podczas odtwarzania; od których wierszy zacz¹æ ???"
+
+msgid "See \":help E312\" for more information."
+msgstr "Zobacz \":help E312\" dla dalszych informacji."
+
+msgid "Recovery completed. You should check if everything is OK."
+msgstr ""
+"Odtwarzanie zakoñczono. Powinieneœ sprawdziæ czy wszystko jest w porz¹dku."
+
+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"
+
+msgid "and run diff with the original file to check for changes)"
+msgstr "i wykonaæ diff z oryginalnym plikiem aby sprawdziæ zmiany)"
+
+msgid "Recovery completed. Buffer contents equals file contents."
+msgstr "Odzyskiwanie zakoñczone. Zawartoœæ bufora jest równa zawartoœci pliku."
+
+msgid ""
+"\n"
+"You may want to delete the .swp file now.\n"
+"\n"
+msgstr ""
+"\n"
+"Mo¿esz teraz chcieæ usun¹æ plik .swp.\n"
+"\n"
+
+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"
+
+#. use msg() to start the scrolling properly
+msgid "Swap files found:"
+msgstr "Znalezione pliki wymiany:"
+
+msgid " In current directory:\n"
+msgstr " W bie¿¹cym katalogu:\n"
+
+msgid " Using specified name:\n"
+msgstr " U¿ywam podanej nazwy:\n"
+
+msgid " In directory "
+msgstr " W katalogu "
+
+msgid " -- none --\n"
+msgstr " -- ¿aden --\n"
+
+msgid " owned by: "
+msgstr " posiadany przez: "
+
+msgid " dated: "
+msgstr " data: "
+
+msgid " dated: "
+msgstr " data: "
+
+msgid " [from Vim version 3.0]"
+msgstr " [po Vimie wersja 3.0]"
+
+msgid " [does not look like a Vim swap file]"
+msgstr " [nie wygl¹da na plik wymiany Vima]"
+
+msgid " file name: "
+msgstr " nazwa pliku: "
+
+msgid ""
+"\n"
+" modified: "
+msgstr ""
+"\n"
+" zmieniono: "
+
+msgid "YES"
+msgstr "TAK"
+
+msgid "no"
+msgstr "nie"
+
+msgid ""
+"\n"
+" user name: "
+msgstr ""
+"\n"
+" u¿ytkownik: "
+
+msgid " host name: "
+msgstr " nazwa hosta: "
+
+msgid ""
+"\n"
+" host name: "
+msgstr ""
+"\n"
+" nazwa hosta: "
+
+msgid ""
+"\n"
+" process ID: "
+msgstr ""
+"\n"
+" ID procesu: "
+
+msgid " (still running)"
+msgstr " (dalej dzia³a)"
+
+msgid ""
+"\n"
+" [not usable with this version of Vim]"
+msgstr ""
+"\n"
+" [nie nadaje siê dla tej wersji Vima]"
+
+msgid ""
+"\n"
+" [not usable on this computer]"
+msgstr ""
+"\n"
+" [nie do u¿ytku na tym komputerze]"
+
+msgid " [cannot be read]"
+msgstr " [nieodczytywalny]"
+
+msgid " [cannot be opened]"
+msgstr " [nieotwieralny]"
+
+msgid "E313: Cannot preserve, there is no swap file"
+msgstr "E313: Nie mogê zabezpieczyæ, bo brak pliku wymiany"
+
+msgid "File preserved"
+msgstr "Plik zabezpieczono"
+
+msgid "E314: Preserve failed"
+msgstr "E314: Nieudane zabezpieczenie"
+
+#, c-format
+msgid "E315: ml_get: invalid lnum: %ld"
+msgstr "E315: ml_get: niew³aœciwy lnum: %ld"
+
+#, c-format
+msgid "E316: ml_get: cannot find line %ld"
+msgstr "E316: ml_get: nie znaleziono wiersza %ld"
+
+msgid "E317: pointer block id wrong 3"
+msgstr "E317: niepoprawne id wskaŸnika bloku 3"
+
+msgid "stack_idx should be 0"
+msgstr "stack_idx powinien byæ 0"
+
+msgid "E318: Updated too many blocks?"
+msgstr "E318: Zaktualizowano zbyt wiele bloków?"
+
+msgid "E317: pointer block id wrong 4"
+msgstr "E317: niepoprawne id wskaŸnika bloku 4"
+
+msgid "deleted block 1?"
+msgstr "blok nr 1 skasowany?"
+
+#, c-format
+msgid "E320: Cannot find line %ld"
+msgstr "E320: Nie mogê znaleŸæ wiersza %ld"
+
+msgid "E317: pointer block id wrong"
+msgstr "E317: niepoprawne id bloku odniesienia"
+
+msgid "pe_line_count is zero"
+msgstr "pe_line_count wynosi zero"
+
+#, c-format
+msgid "E322: line number out of range: %ld past the end"
+msgstr "E322: numer wiersza poza zakresem: %ld jest poza koñcem"
+
+#, c-format
+msgid "E323: line count wrong in block %ld"
+msgstr "E323: liczba wierszy niepoprawna w bloku %ld"
+
+msgid "Stack size increases"
+msgstr "WielkoϾ stosu wzrasta"
+
+msgid "E317: pointer block id wrong 2"
+msgstr "E317: niepoprawne id bloku odniesienia 2"
+
+#, c-format
+msgid "E773: Symlink loop for \"%s\""
+msgstr "E773: Pêtla dowi¹zañ dla \"%s\""
+
+msgid "E325: ATTENTION"
+msgstr "E325: UWAGA"
+
+msgid ""
+"\n"
+"Found a swap file by the name \""
+msgstr ""
+"\n"
+"Znalaz³em plik wymiany o nazwie \""
+
+msgid "While opening file \""
+msgstr "Podczas otwierania pliku \""
+
+msgid " NEWER than swap file!\n"
+msgstr " NOWSZE od pliku wymiany!\n"
+
+#. 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.\n"
+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"
+
+msgid " Quit, or continue with caution.\n"
+msgstr " Zakoñcz lub ostro¿nie kontynuuj.\n"
+
+msgid "(2) An edit session for this file crashed.\n"
+msgstr "(2) Sesja edycji dla pliku za³ama³a siê.\n"
+
+msgid " If this is the case, use \":recover\" or \"vim -r "
+msgstr " Jeœli tak, to u¿yj \":recover\" lub \"vim -r "
+
+msgid ""
+"\"\n"
+" to recover the changes (see \":help recovery\").\n"
+msgstr ""
+"\"\n"
+" aby odzyskaæ zmiany (zobacz \":help recovery)\").\n"
+
+msgid " If you did this already, delete the swap file \""
+msgstr " Jeœli ju¿ to zrobi³eœ, usuñ plik wymiany \""
+
+msgid ""
+"\"\n"
+" to avoid this message.\n"
+msgstr ""
+"\"\n"
+" aby unikn¹æ tej wiadomoœci.\n"
+
+msgid "Swap file \""
+msgstr "Plik wymiany \""
+
+msgid "\" already exists!"
+msgstr "\" ju¿ istnieje!"
+
+msgid "VIM - ATTENTION"
+msgstr "VIM - UWAGA"
+
+msgid "Swap file already exists!"
+msgstr "Plik wymiany ju¿ istnieje!"
+
+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æ"
+
+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æ"
+
+msgid "E326: Too many swap files found"
+msgstr "E326: Znaleziono zbyt wiele plików wymiany"
+
+msgid "E327: Part of menu-item path is not sub-menu"
+msgstr "E327: Czêœæ tropu punktu menu nie okreœla podmenu"
+
+msgid "E328: Menu only exists in another mode"
+msgstr "E328: Menu istnieje tylko w innym trybie"
+
+#, c-format
+msgid "E329: No menu \"%s\""
+msgstr "E329: Nie ma menu \"%s\""
+
+#. Only a mnemonic or accelerator is not valid.
+msgid "E792: Empty menu name"
+msgstr "E792: Pusta nazwa menu"
+
+msgid "E330: Menu path must not lead to a sub-menu"
+msgstr "E330: Trop menu nie mo¿e prowadziæ do podmenu"
+
+msgid "E331: Must not add menu items directly to menu bar"
+msgstr "E331: Nie wolno dodawaæ punktów menu wprost do paska menu"
+
+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
+msgid ""
+"\n"
+"--- Menus ---"
+msgstr ""
+"\n"
+"--- Menu ---"
+
+msgid "Tear off this menu"
+msgstr "Oderwij to menu"
+
+msgid "E333: Menu path must lead to a menu item"
+msgstr "E333: Trop menu musi prowadziæ do punktu menu"
+
+#, c-format
+msgid "E334: Menu not found: %s"
+msgstr "E334: Nie znaleziono menu: %s"
+
+#, c-format
+msgid "E335: Menu not defined for %s mode"
+msgstr "E335: Menu nie jest zdefiniowane dla trybu %s"
+
+msgid "E336: Menu path must lead to a sub-menu"
+msgstr "E336: Trop menu musi prowadziæ do podmenu"
+
+msgid "E337: Menu not found - check menu names"
+msgstr "E337: Nie znaleziono menu - sprawdŸ nazwy menu"
+
+#, c-format
+msgid "Error detected while processing %s:"
+msgstr "Wykryto b³¹d podczas przetwarzania %s:"
+
+#, c-format
+msgid "line %4ld:"
+msgstr "wiersz %4ld:"
+
+#, c-format
+msgid "E354: Invalid register name: '%s'"
+msgstr "E354: Niew³aœciwa nazwa rejestru: '%s'"
+
+msgid "Messages maintainer: Bram Moolenaar <Bram@vim.org>"
+msgstr "Opiekun komunikatów: Miko³aj Machowski <mikmach@wp.pl>"
+
+msgid "Interrupt: "
+msgstr "Przerwanie: "
+
+msgid "Press ENTER or type command to continue"
+msgstr "Naciœnij ENTER lub wprowadŸ komendê aby kontynuowaæ"
+
+#, c-format
+msgid "%s line %ld"
+msgstr "%s wiersz %ld"
+
+msgid "-- More --"
+msgstr "-- Wiêcej --"
+
+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"
+
+msgid "Question"
+msgstr "Pytanie"
+
+msgid ""
+"&Yes\n"
+"&No"
+msgstr ""
+"&Tak\n"
+"&Nie"
+
+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"
+
+msgid "Select Directory dialog"
+msgstr "Dialog wyboru katalogu"
+
+msgid "Save File dialog"
+msgstr "Dialog zapisywania pliku"
+
+msgid "Open File dialog"
+msgstr "Dialog otwierania pliku"
+
+#. TODO: non-GUI file selector here
+msgid "E338: Sorry, no file browser in console mode"
+msgstr "E338: Przykro mi, nie ma przegl¹darki plików w trybie konsoli"
+
+msgid "E766: Insufficient arguments for printf()"
+msgstr "E766: Za ma³o argumentów dla printf()"
+
+msgid "E807: Expected Float argument for printf()"
+msgstr "E807: Spodziewany argument Zmiennoprzecinkowy w printf()"
+
+msgid "E767: Too many arguments to printf()"
+msgstr "E767: Za du¿o argumentów dla printf()"
+
+msgid "W10: Warning: Changing a readonly file"
+msgstr "W10: OSTRZE¯ENIE: Zmiany w pliku tylko do odczytu"
+
+msgid "Type number and <Enter> or click with mouse (empty cancels): "
+msgstr "Wpisz numer i <Enter> lub wybierz mysz¹ (pusta wartoœæ anuluje): "
+
+msgid "Type number and <Enter> (empty cancels): "
+msgstr "Wpisz numer i <Enter> (puste anuluje): "
+
+msgid "1 more line"
+msgstr "1 wiersz wiêcej"
+
+msgid "1 line less"
+msgstr "1 wiersz mniej"
+
+#, c-format
+msgid "%ld more lines"
+msgstr "dodano %ld wierszy"
+
+#, c-format
+msgid "%ld fewer lines"
+msgstr "usuniêto %ld wierszy"
+
+msgid " (Interrupted)"
+msgstr " (Przerwane)"
+
+msgid "Beep!"
+msgstr "Biiip!"
+
+msgid "Vim: preserving files...\n"
+msgstr "Vim: zachowujê plik...\n"
+
+#. close all memfiles, without deleting
+msgid "Vim: Finished.\n"
+msgstr "Vim: Zakoñczono.\n"
+
+msgid "ERROR: "
+msgstr "B£¥D: "
+
+#, c-format
+msgid ""
+"\n"
+"[bytes] total alloc-freed %lu-%lu, in use %lu, peak use %lu\n"
+msgstr ""
+"\n"
+"[bajtów] totalne alokacje-zwolnienia %lu-%lu, w u¿ytku %lu, maksymalne "
+"u¿ycie %lu\n"
+
+#, c-format
+msgid ""
+"[calls] total re/malloc()'s %lu, total free()'s %lu\n"
+"\n"
+msgstr ""
+"[wywo³ania] wszystkich re/malloc()-ów %lu, wszystkich free()-ów %lu\n"
+"\n"
+
+msgid "E340: Line is becoming too long"
+msgstr "E340: Wiersz staje siê zbyt d³ugi"
+
+#, c-format
+msgid "E341: Internal error: lalloc(%ld, )"
+msgstr "E341: Wewnêtrzny b³¹d: lalloc(%ld, )"
+
+#, c-format
+msgid "E342: Out of memory! (allocating %lu bytes)"
+msgstr "E342: Brak pamiêci! (rezerwacja %lu bajtów)"
+
+#, c-format
+msgid "Calling shell to execute: \"%s\""
+msgstr "Wywo³ujê pow³okê do wykonania: \"%s\""
+
+msgid "E545: Missing colon"
+msgstr "E545: Brak dwukropka"
+
+msgid "E546: Illegal mode"
+msgstr "E546: Niedozwolony tryb"
+
+msgid "E547: Illegal mouseshape"
+msgstr "E547: Niedozwolony obrys myszki"
+
+msgid "E548: digit expected"
+msgstr "E548: oczekiwa³em na cyfrê"
+
+msgid "E549: Illegal percentage"
+msgstr "E549: Niedozwolony procent"
+
+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 "E854: path too long for completion"
+msgstr "E854: œcie¿ka za d³uga by uzupe³niæ"
+
+#, 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'."
+
+#, c-format
+msgid "E344: Can't find directory \"%s\" in cdpath"
+msgstr "E344: Nie mogê znaleŸæ katalogu \"%s\" w cdpath"
+
+#, c-format
+msgid "E345: Can't find file \"%s\" in path"
+msgstr "E345: Nie mogê znaleŸæ pliku \"%s\" w tropie"
+
+#, c-format
+msgid "E346: No more directory \"%s\" found in cdpath"
+msgstr "E346: Katalogu \"%s\" nie ma wiêcej w cdpath"
+
+#, c-format
+msgid "E347: No more file \"%s\" found in path"
+msgstr "E347: Pliku \"%s\" nie ma wiêcej w tropie"
+
+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"
+
+#, c-format
+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"
+
+#, c-format
+msgid "E658: NetBeans connection lost for buffer %ld"
+msgstr "E658: Bufor %ld 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"
+
+#, c-format
+msgid "E505: %s is read-only (add ! to override)"
+msgstr "E505: %s jest tylko do odczytu (dodaj ! aby wymusiæ)"
+
+msgid "E349: No identifier under cursor"
+msgstr "E349: Brak identyfikatora pod kursorem"
+
+msgid "E774: 'operatorfunc' is empty"
+msgstr "E774: 'operatorfunc' jest pusta"
+
+msgid "E775: Eval feature not available"
+msgstr "E775: Funkcjonalnoœæ eval nie jest dostêpna"
+
+msgid "Warning: terminal cannot highlight"
+msgstr "OSTRZE¯ENIE: terminal nie wykonuje podœwietlania"
+
+msgid "E348: No string under cursor"
+msgstr "E348: Brak ci¹gu pod kursorem"
+
+msgid "E352: Cannot erase folds with current 'foldmethod'"
+msgstr "E352: Nie mogê skasowaæ zwiniêcia z bie¿¹c¹ 'foldmethod'"
+
+msgid "E664: changelist is empty"
+msgstr "E664: lista zmian (changelist) jest pusta"
+
+msgid "E662: At start of changelist"
+msgstr "E662: Na pocz¹tku listy zmian"
+
+msgid "E663: At end of changelist"
+msgstr "E663: Na koñcu listy zmian"
+
+msgid "Type :quit<Enter> to exit Vim"
+msgstr "wprowadŸ :quit<Enter> zakoñczenie programu"
+
+#, c-format
+msgid "1 line %sed 1 time"
+msgstr "1 wiersz %sed 1 raz"
+
+#, c-format
+msgid "1 line %sed %d times"
+msgstr "1 wiersz %sed %d razy"
+
+#, c-format
+msgid "%ld lines %sed 1 time"
+msgstr "%ld wierszy %sed 1 raz"
+
+#, c-format
+msgid "%ld lines %sed %d times"
+msgstr "%ld wierszy %sed %d razy"
+
+#, c-format
+msgid "%ld lines to indent... "
+msgstr "%ld wierszy do wciêcia... "
+
+msgid "1 line indented "
+msgstr "1 wiersz wciêty "
+
+#, c-format
+msgid "%ld lines indented "
+msgstr "%ld wierszy wciêtych "
+
+msgid "E748: No previously used register"
+msgstr "E748: Brak poprzednio u¿ytego rejestru"
+
+#. must display the prompt
+msgid "cannot yank; delete anyway"
+msgstr "nie mogê skopiowaæ, mimo to kasujê"
+
+msgid "1 line changed"
+msgstr "1 wiersz zmieniono"
+
+#, c-format
+msgid "%ld lines changed"
+msgstr "%ld wierszy zmieniono"
+
+#, c-format
+msgid "freeing %ld lines"
+msgstr "zwalniam %ld wierszy"
+
+msgid "block of 1 line yanked"
+msgstr "skopiowano blok 1 wiersza"
+
+msgid "1 line yanked"
+msgstr "1 wiersz skopiowano"
+
+#, c-format
+msgid "block of %ld lines yanked"
+msgstr "%ld wierszy skopiowanych"
+
+#, c-format
+msgid "%ld lines yanked"
+msgstr "%ld wierszy skopiowanych"
+
+#, c-format
+msgid "E353: Nothing in register %s"
+msgstr "E353: Pusty rejestr %s"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Registers ---"
+msgstr ""
+"\n"
+"--- Rejestry ---"
+
+msgid "Illegal register name"
+msgstr "Niedozwolona nazwa rejestru"
+
+msgid ""
+"\n"
+"# Registers:\n"
+msgstr ""
+"\n"
+"# Rejestry:\n"
+
+#, c-format
+msgid "E574: Unknown register type %d"
+msgstr "E574: Nieznany typ rejestru %d"
+
+#, c-format
+msgid "%ld Cols; "
+msgstr "%ld Kolumn; "
+
+#, c-format
+msgid "Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Bytes"
+msgstr "Wybrano %s%ld z %ld Wierszy; %ld z %ld S³ów; %ld z %ld Bajtów"
+
+#, c-format
+msgid ""
+"Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Chars; %ld of %ld "
+"Bytes"
+msgstr ""
+"Wybrano %s%ld z %ld Wierszy; %ld z %ld S³ów; %ld z %ld Znaków; %ld z %ld "
+"Bajtów"
+
+#, c-format
+msgid "Col %s of %s; Line %ld of %ld; Word %ld of %ld; Byte %ld of %ld"
+msgstr "Kol %s z %s; Wiersz %ld z %ld; S³owo %ld z %ld; Bajt %ld z %ld"
+
+#, c-format
+msgid ""
+"Col %s of %s; Line %ld of %ld; Word %ld of %ld; Char %ld of %ld; Byte %ld of "
+"%ld"
+msgstr ""
+"Kol %s z %s; Wiersz %ld z %ld; S³owo %ld z %ld; Znak %ld z %ld; Bajt %ld z "
+"%ld"
+
+#, c-format
+msgid "(+%ld for BOM)"
+msgstr "(+%ld dla BOM)"
+
+msgid "%<%f%h%m%=Page %N"
+msgstr "%<%f%h%m%=Strona %N"
+
+msgid "Thanks for flying Vim"
+msgstr "Dziêki za lot Vimem"
+
+msgid "E518: Unknown option"
+msgstr "E518: Nieznana opcja"
+
+msgid "E519: Option not supported"
+msgstr "E519: Opcja nie jest wspomagana"
+
+msgid "E520: Not allowed in a modeline"
+msgstr "E520: Niedozwolone w modeline"
+
+msgid "E846: Key code not set"
+msgstr "E846: Kod klucza nie jest ustawiony"
+
+msgid "E521: Number required after ="
+msgstr "E521: Po = wymagany jest numer"
+
+msgid "E522: Not found in termcap"
+msgstr "E522: Nie znaleziono w termcap"
+
+#, c-format
+msgid "E539: Illegal character <%s>"
+msgstr "E539: Niedozwolony znak <%s>"
+
+msgid "E529: Cannot set 'term' to empty string"
+msgstr "E529: Nie mogê ustawiæ 'term' na pusty ci¹g"
+
+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 "E589: 'backupext' and 'patchmode' are equal"
+msgstr "E589: 'backupext' i 'patchmode' s¹ to¿same"
+
+msgid "E834: Conflicts with value of 'listchars'"
+msgstr "E834: Konflikty wartoœci 'listchars'"
+
+msgid "E835: Conflicts with value of 'fillchars'"
+msgstr "E835: Konflikty wartoœci 'fillchars'"
+
+msgid "E617: Cannot be changed in the GTK+ 2 GUI"
+msgstr "E617: Nie mogê zmieniæ w GTK+2 GUI"
+
+msgid "E524: Missing colon"
+msgstr "E524: Brak dwukropka"
+
+msgid "E525: Zero length string"
+msgstr "E525: Ci¹g o zerowej d³ugoœci"
+
+#, c-format
+msgid "E526: Missing number after <%s>"
+msgstr "E526: Brak numeru po <%s>"
+
+msgid "E527: Missing comma"
+msgstr "E527: Brak przecinka"
+
+msgid "E528: Must specify a ' value"
+msgstr "E528: Musi okreœlaæ wartoœæ '"
+
+msgid "E595: contains unprintable or wide character"
+msgstr "E595: zawiera niewyœwietlalny lub szeroki znak"
+
+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"
+
+#, c-format
+msgid "E535: Illegal character after <%c>"
+msgstr "E535: Niedozwolony znak po <%c>"
+
+msgid "E536: comma required"
+msgstr "E536: wymagany przecinek"
+
+#, c-format
+msgid "E537: 'commentstring' must be empty or contain %s"
+msgstr "E537: 'commentstring' musi byæ pusty lub zawieraæ %s"
+
+msgid "E538: No mouse support"
+msgstr "E538: Brak wspomagania myszki"
+
+msgid "E540: Unclosed expression sequence"
+msgstr "E540: Niedomkniêty ci¹g wyra¿eñ"
+
+msgid "E541: too many items"
+msgstr "E541: zbyt wiele elementów"
+
+msgid "E542: unbalanced groups"
+msgstr "E542: niezbalansowane grupy"
+
+msgid "E590: A preview window already exists"
+msgstr "E590: okno podgl¹du ju¿ istnieje"
+
+msgid "W17: Arabic requires UTF-8, do ':set encoding=utf-8'"
+msgstr "W17: Arabski wymaga UTF-8, zrób ':set encoding=utf-8'"
+
+#, c-format
+msgid "E593: Need at least %d lines"
+msgstr "E593: Potrzebujê przynajmniej %d wierszy"
+
+#, c-format
+msgid "E594: Need at least %d columns"
+msgstr "E594: Potrzebujê przynajmniej %d kolumn"
+
+#, 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.
+#, c-format
+msgid "E521: Number required: &%s = '%s'"
+msgstr "E521: Wymagana Liczba: &%s = '%s'"
+
+msgid ""
+"\n"
+"--- Terminal codes ---"
+msgstr ""
+"\n"
+"--- Kody terminala ---"
+
+msgid ""
+"\n"
+"--- Global option values ---"
+msgstr ""
+"\n"
+"--- Globalne wartoœci opcji ---"
+
+msgid ""
+"\n"
+"--- Local option values ---"
+msgstr ""
+"\n"
+"--- Lokalne wartoœci opcji ---"
+
+msgid ""
+"\n"
+"--- Options ---"
+msgstr ""
+"\n"
+"--- Opcje ---"
+
+msgid "E356: get_varp ERROR"
+msgstr "E356: B£¥D get_varp"
+
+#, c-format
+msgid "E357: 'langmap': Matching character missing for %s"
+msgstr "E357: 'langmap': Brak pasuj¹cego znaku dla %s"
+
+#, c-format
+msgid "E358: 'langmap': Extra characters after semicolon: %s"
+msgstr "E358: 'langmap': Dodatkowe znaki po œredniku: %s"
+
+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"
+
+#, c-format
+msgid "Need %s version %ld\n"
+msgstr "Potrzebujê %s w wersji %ld\n"
+
+msgid "Cannot open NIL:\n"
+msgstr "Nie mogê otworzyæ NIL:\n"
+
+msgid "Cannot create "
+msgstr "Nie mogê stworzyæ "
+
+#, c-format
+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"
+
+#. if Vim opened a window: Executing a shell may cause crashes
+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ê"
+
+#, c-format
+msgid "to %s on %s"
+msgstr "do %s z %s"
+
+#, c-format
+msgid "E613: Unknown printer font: %s"
+msgstr "E613: Nieznana czcionka drukarki: %s"
+
+#, c-format
+msgid "E238: Print error: %s"
+msgstr "E238: B³¹d drukarki: %s"
+
+#, c-format
+msgid "Printing '%s'"
+msgstr "Wydrukowano '%s'"
+
+#, c-format
+msgid "E244: Illegal charset name \"%s\" in font name \"%s\""
+msgstr ""
+"E244: Niedozwolona nazwa zestawu znaków \"%s\" w nazwie czcionki \"%s\""
+
+#, c-format
+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"
+
+#, c-format
+msgid "Vim: Caught deadly signal %s\n"
+msgstr "Vim: Za³apa³ œmiertelny sygna³ %s\n"
+
+#, c-format
+msgid "Vim: Caught deadly signal\n"
+msgstr "Vim: Za³apa³ œmiertelny sygna³\n"
+
+#, c-format
+msgid "Opening the X display took %ld msec"
+msgstr "Otwieranie ekranu X trwa³o %ld 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"
+"Could not get security context for "
+msgstr ""
+"\n"
+"Nie mogê uzyskaæ kontekstu bezpieczeñstwa dla"
+
+msgid ""
+"\n"
+"Could not set security context for "
+msgstr ""
+"\n"
+"Nie mo¿na uzyskaæ kontekstu bezpieczeñstwa dla"
+
+msgid ""
+"\n"
+"Cannot execute shell "
+msgstr ""
+"\n"
+"Nie mogê wykonaæ pow³oki "
+
+msgid ""
+"\n"
+"Cannot execute shell sh\n"
+msgstr ""
+"\n"
+"Nie mogê wykonaæ pow³oki sh\n"
+
+msgid ""
+"\n"
+"shell returned "
+msgstr ""
+"\n"
+"pow³oka zwróci³a "
+
+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"
+
+#, c-format
+msgid "dlerror = \"%s\""
+msgstr "dlerror = \"%s\""
+
+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ê"
+
+#, c-format
+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!"
+
+#, c-format
+msgid "shell returned %d"
+msgstr "pow³oka zwróci³a %d"
+
+#, c-format
+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"
+
+#, c-format
+msgid "E372: Too many %%%c in format string"
+msgstr "E372: Zbyt wiele %%%c w ci¹gu formatuj¹cym"
+
+#, c-format
+msgid "E373: Unexpected %%%c in format string"
+msgstr "E373: Nieoczekiwane %%%c w ci¹gu formatuj¹cym"
+
+msgid "E374: Missing ] in format string"
+msgstr "E374: Brak ] w ci¹gu formatuj¹cym"
+
+#, c-format
+msgid "E375: Unsupported %%%c in format string"
+msgstr "E375: Niewspomagane %%%c w ci¹gu formatuj¹cym"
+
+#, c-format
+msgid "E376: Invalid %%%c in format string prefix"
+msgstr "E376: Niepoprawne %%%c w prefiksie ci¹gu formatuj¹cego"
+
+#, c-format
+msgid "E377: Invalid %%%c in format string"
+msgstr "E377: Niepoprawne %%%c w ci¹gu formatuj¹cym"
+
+msgid "E378: 'errorformat' contains no pattern"
+msgstr "E378: 'errorformat' nie zawiera wzorca"
+
+msgid "E379: Missing or empty directory name"
+msgstr "E379: Pusta nazwa katalogu lub jej brak"
+
+msgid "E553: No more items"
+msgstr "E553: Nie ma wiêcej elementów"
+
+#, c-format
+msgid "(%d of %d)%s%s: "
+msgstr "(%d z %d)%s%s: "
+
+msgid " (line deleted)"
+msgstr " (wiersz skasowany)"
+
+msgid "E380: At bottom of quickfix stack"
+msgstr "E380: Na dole stosu quickfix"
+
+msgid "E381: At top of quickfix stack"
+msgstr "E381: Na górze stosu quickfix"
+
+#, c-format
+msgid "error list %d of %d; %d errors"
+msgstr "lista b³êdów %d z %d; %d b³êdów"
+
+msgid "E382: Cannot write, 'buftype' option is set"
+msgstr "E382: Nie mogê zapisaæ, opcja 'buftype' jest ustawiona"
+
+msgid "Error file"
+msgstr "Plik b³êdu"
+
+msgid "E683: File name missing or invalid pattern"
+msgstr "E683: Brak nazwy pliku lub niew³aœciwa œcie¿ka"
+
+#, c-format
+msgid "Cannot open file \"%s\""
+msgstr "Nie mogê otworzyæ pliku \"%s\""
+
+msgid "E681: Buffer is not loaded"
+msgstr "E681: Bufor nie jest za³adowany"
+
+msgid "E777: String or List expected"
+msgstr "E777: Oczekiwa³em na ³añcuch lub listê"
+
+#, c-format
+msgid "E369: invalid item in %s%%[]"
+msgstr "E369: Niew³aœciwy element w %s%%[]"
+
+#, c-format
+msgid "E769: Missing ] after %s["
+msgstr "E769: Brak ] po %s["
+
+#, c-format
+msgid "E53: Unmatched %s%%("
+msgstr "E53: Niesparowany %s%%("
+
+#, c-format
+msgid "E54: Unmatched %s("
+msgstr "E54: Niesparowany %s("
+
+#, c-format
+msgid "E55: Unmatched %s)"
+msgstr "E55: Niesparowany %s)"
+
+msgid "E66: \\z( not allowed here"
+msgstr "E66: \\z( jest niedozwolone w tym miejscu"
+
+msgid "E67: \\z1 et al. not allowed here"
+msgstr "E67: \\z1 i podobne s¹ niedozwolone w tym miejscu"
+
+#, c-format
+msgid "E69: Missing ] after %s%%["
+msgstr "E69: Brak ] po %s%%["
+
+#, c-format
+msgid "E70: Empty %s%%[]"
+msgstr "E70: Pusty %s%%[]"
+
+msgid "E339: Pattern too long"
+msgstr "E339: Zbyt d³ugi wzorzec"
+
+msgid "E50: Too many \\z("
+msgstr "E50: Zbyt wiele \\z("
+
+#, c-format
+msgid "E51: Too many %s("
+msgstr "E51: Zbyt wiele %s("
+
+msgid "E52: Unmatched \\z("
+msgstr "E52: Niesparowany \\z("
+
+#, c-format
+msgid "E59: invalid character after %s@"
+msgstr "E59: niedozwolony znak po %s@"
+
+#, c-format
+msgid "E60: Too many complex %s{...}s"
+msgstr "E60: Zbyt wiele z³o¿onych %s{...}"
+
+#, c-format
+msgid "E61: Nested %s*"
+msgstr "E61: Zagnie¿d¿one %s*"
+
+#, c-format
+msgid "E62: Nested %s%c"
+msgstr "E62: Zagnie¿d¿one %s%c"
+
+msgid "E63: invalid use of \\_"
+msgstr "E63: Niedozwolone u¿ycie \\_"
+
+#, c-format
+msgid "E64: %s%c follows nothing"
+msgstr "E64: %s%c po niczym"
+
+msgid "E65: Illegal back reference"
+msgstr "E65: Niew³aœciwe odwo³anie wsteczne"
+
+msgid "E68: Invalid character after \\z"
+msgstr "E68: niedopuszczalny znak po \\z"
+
+#, c-format
+msgid "E678: Invalid character after %s%%[dxouU]"
+msgstr "E678: Niedozwolony znak po %s%%[dxouU]"
+
+#, c-format
+msgid "E71: Invalid character after %s%%"
+msgstr "E71: Niedozwolony znak po %s%%"
+
+#, c-format
+msgid "E554: Syntax error in %s{...}"
+msgstr "E554: B³¹d sk³adni w %s{...}"
+
+msgid "External submatches:\n"
+msgstr "Zewnêtrzne poddopasowania:\n"
+
+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"
+
+#, c-format
+msgid "E866: (NFA regexp) Misplaced %c"
+msgstr "E866: (wyra¿enie regularne NFA) Niepoprawnie umieszczone %c"
+
+msgid "E865: (NFA) Regexp end encountered prematurely"
+msgstr "E865: (NFA) przedwczesny koniec wyra¿enia regularnego"
+
+#, c-format
+msgid "E867: (NFA) Unknown operator '\\z%c'"
+msgstr "E867: (NFA) Nieznany operator '\\z%c'"
+
+#, c-format
+msgid "E867: (NFA) Unknown operator '\\%%%c'"
+msgstr "E867: (NFA) Nieznany operator '\\%%%c'"
+
+#. should never happen
+msgid "E868: Error building NFA with equivalence class!"
+msgstr "E868: B³¹d przy budowwaniu NFA z klas¹ ekwiwalencji"
+
+#, c-format
+msgid "E869: (NFA) Unknown operator '\\@%c'"
+msgstr "E869: (NFA) Nieznany operator '\\@%c'"
+
+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.
+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 `('
+msgid "E872: (NFA regexp) Too many '('"
+msgstr "E872: (wyra¿enie regularne NFA) Zbyt du¿o '('"
+
+msgid "E879: (NFA regexp) Too many \\z("
+msgstr "E879: (wyra¿enie regularne NFA) Za du¿o \\z("
+
+msgid "E873: (NFA regexp) proper termination error"
+msgstr "E873: (wyra¿enie regularne NFA) b³¹d poprawnego zakoñczenia"
+
+msgid "E874: (NFA) Could not pop the stack !"
+msgstr "E874: (NFA) Nie mo¿na zdj¹æ elementu ze stosu!"
+
+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"
+
+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 "
+
+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 ""
+"Could not open temporary log file for writing, displaying on stderr ... "
+msgstr "Nie mo¿na otworzyæ do zapisu tymczasowego pliku, pokazujê na stderr... "
+
+#, c-format
+msgid "(NFA) COULD NOT OPEN %s !"
+msgstr "(NFA) NIE MO¯NA OTWORZYÆ %s !"
+
+msgid "Could not open temporary log file for writing "
+msgstr "Nie mo¿na otworzyæ do zapisu tymczasowego pliku logowania"
+
+msgid " VREPLACE"
+msgstr " V-ZAMIANA"
+
+msgid " REPLACE"
+msgstr " ZAMIANA"
+
+msgid " REVERSE"
+msgstr " NEGATYW"
+
+msgid " INSERT"
+msgstr " WPROWADZANIE"
+
+msgid " (insert)"
+msgstr " (wprowadzanie)"
+
+msgid " (replace)"
+msgstr " (zamiana)"
+
+msgid " (vreplace)"
+msgstr " (v-zamiana)"
+
+msgid " Hebrew"
+msgstr " Hebrajski"
+
+msgid " Arabic"
+msgstr " Arabski"
+
+msgid " (lang)"
+msgstr " (jêzyk)"
+
+msgid " (paste)"
+msgstr " (wklejanie)"
+
+msgid " VISUAL"
+msgstr " WIZUALNY"
+
+msgid " VISUAL LINE"
+msgstr " WIZUALNY LINIOWY"
+
+msgid " VISUAL BLOCK"
+msgstr " WIZUALNY BLOKOWY"
+
+msgid " SELECT"
+msgstr " ZAZNACZANIE"
+
+msgid " SELECT LINE"
+msgstr " ZAZNACZANIE LINIOWE"
+
+msgid " SELECT BLOCK"
+msgstr " ZAZNACZANIE BLOKOWE"
+
+msgid "recording"
+msgstr "zapis"
+
+#, c-format
+msgid "E383: Invalid search string: %s"
+msgstr "E383: Niew³aœciwy ci¹g do szukania: %s"
+
+#, c-format
+msgid "E384: search hit TOP without match for: %s"
+msgstr "E384: szukanie dobi³o GÓRY bez znalezienia: %s"
+
+#, c-format
+msgid "E385: search hit BOTTOM without match for: %s"
+msgstr "E385: szukanie dobi³o KOÑCA bez znalezienia : %s"
+
+msgid "E386: Expected '?' or '/' after ';'"
+msgstr "E386: Oczekujê '?' lub '/' po ';'"
+
+msgid " (includes previously listed match)"
+msgstr " (zawiera poprzednio wymienione dopasowanie)"
+
+#. cursor at status line
+msgid "--- Included files "
+msgstr "--- Zawarte pliki "
+
+msgid "not found "
+msgstr "nie znaleziono"
+
+msgid "in path ---\n"
+msgstr "w tropie ---\n"
+
+msgid " (Already listed)"
+msgstr " (Ju¿ wymienione)"
+
+msgid " NOT FOUND"
+msgstr " NIE ZNALEZIONO"
+
+#, c-format
+msgid "Scanning included file: %s"
+msgstr "Przegl¹d w³¹czonego pliku: %s"
+
+#, c-format
+msgid "Searching included file %s"
+msgstr "Przeszukiwanie w³¹czonego pliku %s"
+
+msgid "E387: Match is on current line"
+msgstr "E387: Wzorzec pasuje w bie¿¹cym wierszu"
+
+msgid "All included files were found"
+msgstr "Wszelkie w³¹czane pliki odnaleziono"
+
+msgid "No included files"
+msgstr "Brak w³¹czanych plików"
+
+msgid "E388: Couldn't find definition"
+msgstr "E388: Nie znalaz³em definicji"
+
+msgid "E389: Couldn't find pattern"
+msgstr "E389: Nie znalaz³em wzorca"
+
+msgid "Substitute "
+msgstr "Podstawienie "
+
+#, c-format
+msgid ""
+"\n"
+"# Last %sSearch Pattern:\n"
+"~"
+msgstr ""
+"\n"
+"# Ostatni %sWyszukiwany wzorzec:\n"
+"~"
+
+msgid "E759: Format error in spell file"
+msgstr "E759: Nieprawid³owy format pliku sprawdzania pisowni"
+
+msgid "E758: Truncated spell file"
+msgstr "E758: Obciêty plik sprawdzania pisowni"
+
+#, c-format
+msgid "Trailing text in %s line %d: %s"
+msgstr "Zbêdny tekst w %s wiersz %d: %s"
+
+#, c-format
+msgid "Affix name too long in %s line %d: %s"
+msgstr "Za d³uga nazwa afiksu w %s wiersz %d: %s"
+
+msgid "E761: Format error in affix file FOL, LOW or UPP"
+msgstr "E761: B³¹d formatu w pliku afiksów FOL, LOW lub UPP"
+
+msgid "E762: Character in FOL, LOW or UPP is out of range"
+msgstr "E762: Znak w FOL, LOW lub UPP jest poza zasiêgiem"
+
+msgid "Compressing word tree..."
+msgstr "Kompresja drzewa s³ów..."
+
+msgid "E756: Spell checking is not enabled"
+msgstr "E756: Sprawdzanie pisowni nie jest w³¹czone"
+
+#, 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\""
+
+#, 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\""
+
+#, c-format
+msgid "Reading spell file \"%s\""
+msgstr "Odczytujê plik sprawdzania pisowni \"%s\""
+
+msgid "E757: This does not look like a spell file"
+msgstr "E757: To nie wygl¹da na plik sprawdzania pisowni"
+
+msgid "E771: Old spell file, needs to be updated"
+msgstr "E771: Stary plik sprawdzania pisowni, wymagane uaktualnienie"
+
+msgid "E772: Spell file is for newer version of Vim"
+msgstr "E772: Plik sprawdzania pisowni dla nowszej wersji Vima"
+
+msgid "E770: Unsupported section in spell file"
+msgstr "E770: Niewspierana sekcja w pliku sprawdzania pisowni"
+
+#, c-format
+msgid "Warning: region %s not supported"
+msgstr "Ostrze¿enie: region %s nie jest wspierany"
+
+#, c-format
+msgid "Reading affix file %s ..."
+msgstr "Czytam plik afiksów %s ..."
+
+#, 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"
+
+#, c-format
+msgid "Conversion in %s not supported: from %s to %s"
+msgstr "Konwersja w %s nie jest wspierana: od %s do %s"
+
+#, c-format
+msgid "Conversion in %s not supported"
+msgstr "Konwersja w %s nie jest wspierana"
+
+#, c-format
+msgid "Invalid value for FLAG in %s line %d: %s"
+msgstr "Nieprawid³owa wartoœæ FLAG w %s wierz %d: %s"
+
+#, c-format
+msgid "FLAG after using flags in %s line %d: %s"
+msgstr "FLAG po u¿yciu flag w %s wiersz %d: %s"
+
+#, 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"
+
+#, 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"
+
+#, c-format
+msgid "Wrong COMPOUNDRULES value in %s line %d: %s"
+msgstr "Z³a wartoœæ COMPOUNDRULES w %s wiersz %d: %s"
+
+#, c-format
+msgid "Wrong COMPOUNDWORDMAX value in %s line %d: %s"
+msgstr "Z³a wartoœæ COMPOUNDWORDMAX w %s wiersz %d: %s"
+
+#, c-format
+msgid "Wrong COMPOUNDMIN value in %s line %d: %s"
+msgstr "Z³a wartoœæ COMPOUNDMIM w %s wiersz %d: %s"
+
+#, c-format
+msgid "Wrong COMPOUNDSYLMAX value in %s line %d: %s"
+msgstr "Z³a wartoœæ COMPOUNDSYLMAX w %s wiersz %d: %s"
+
+#, c-format
+msgid "Wrong CHECKCOMPOUNDPATTERN value in %s line %d: %s"
+msgstr "Z³a wartoœæ CHECKCOMPOUNDPATTERN w %s wiersz %d: %s"
+
+#, 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"
+
+#, c-format
+msgid "Duplicate affix in %s line %d: %s"
+msgstr "Powtórzony afiks w %s wiersz %d: %s"
+
+#, 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"
+
+#, c-format
+msgid "Expected Y or N in %s line %d: %s"
+msgstr "Oczekiwano Y lub N w %s wierszu %d: %s"
+
+#, c-format
+msgid "Broken condition in %s line %d: %s"
+msgstr "B³êdny warunek w %s wiersz %d: %s"
+
+#, c-format
+msgid "Expected REP(SAL) count in %s line %d"
+msgstr "Oczekiwano iloœci REP(SAL) w %s wierszu %d"
+
+#, c-format
+msgid "Expected MAP count in %s line %d"
+msgstr "Oczekiwano iloœci MAP w %s wierszu %d"
+
+#, c-format
+msgid "Duplicate character in MAP in %s line %d"
+msgstr "Powtórzony znak w MAP w %s wierszu %d"
+
+#, c-format
+msgid "Unrecognized or duplicate item in %s line %d: %s"
+msgstr "Nieznany lub powtórzony element w %s wierszu %d: %s"
+
+#, c-format
+msgid "Missing FOL/LOW/UPP line in %s"
+msgstr "Brak wiersza FOL/LOW/UPP w %s"
+
+msgid "COMPOUNDSYLMAX used without SYLLABLE"
+msgstr "COMPOUNDSYLMAX u¿yty bez SYLLABLE"
+
+msgid "Too many postponed prefixes"
+msgstr "Zbyt wiele opóŸnionych prefiksów"
+
+msgid "Too many compound flags"
+msgstr "Zbyt wiele flag z³o¿eñ"
+
+msgid "Too many postponed prefixes and/or compound flags"
+msgstr "Zbyt wiele opóŸnionych prefiksów i/lub flag z³o¿eñ"
+
+#, c-format
+msgid "Missing SOFO%s line in %s"
+msgstr "Brak wiersza SOFO%s wiersz w %s"
+
+#, c-format
+msgid "Both SAL and SOFO lines in %s"
+msgstr "Wiersze SAL i SOFO w %s"
+
+#, c-format
+msgid "Flag is not a number in %s line %d: %s"
+msgstr "Flaga nie jest liczb¹ w %s wiersz %d: %s"
+
+#, c-format
+msgid "Illegal flag in %s line %d: %s"
+msgstr "Nieprawid³owa flaga w %s wiersz %d: %s"
+
+#, 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"
+
+#, c-format
+msgid "Reading dictionary file %s ..."
+msgstr "Czytam plik s³ownika %s ..."
+
+#, c-format
+msgid "E760: No word count in %s"
+msgstr "E760: Brak iloœci s³ów w %s"
+
+#, c-format
+msgid "line %6d, word %6d - %s"
+msgstr "wiersz %6d, s³owo %6d - %s"
+
+# c-format
+#, c-format
+msgid "Duplicate word in %s line %d: %s"
+msgstr "Powtórzony wyraz w %s wierszu %d: %s"
+
+# c-format
+#, c-format
+msgid "First duplicate word in %s line %d: %s"
+msgstr "Pierwszy powtórzony wyraz w %s wiersz %d: %s"
+
+# c-format
+#, c-format
+msgid "%d duplicate word(s) in %s"
+msgstr "%d powtórzony(ch) wyraz(ów) w %s"
+
+#, 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"
+
+#, c-format
+msgid "Reading word file %s ..."
+msgstr "Odczytujê plik wyrazów %s ..."
+
+#, c-format
+msgid "Duplicate /encoding= line ignored in %s line %d: %s"
+msgstr "Zignorowano powtórzony wiersz /encoding= w %s wierszu %d: %s"
+
+#, c-format
+msgid "/encoding= line after word ignored in %s line %d: %s"
+msgstr "Zignorowano wiersz /encoding= po wyrazie w %s wierszu %d: %s"
+
+#, c-format
+msgid "Duplicate /regions= line ignored in %s line %d: %s"
+msgstr "Powtórzony wiersz /regions= zignorowano w %s wierszu %d: %s"
+
+#, c-format
+msgid "Too many regions in %s line %d: %s"
+msgstr "Za du¿o regionów w %s wiersz %d: %s"
+
+#, c-format
+msgid "/ line ignored in %s line %d: %s"
+msgstr "wiersz / zignorowano w %s wierszu %d: %s"
+
+#, c-format
+msgid "Invalid region nr in %s line %d: %s"
+msgstr "Nieprawid³owy numer regionu w %s wierszu %d: %s"
+
+#, c-format
+msgid "Unrecognized flags in %s line %d: %s"
+msgstr "Nieznane flagi w %s wiersz %d: %s"
+
+#, c-format
+msgid "Ignored %d words with non-ASCII characters"
+msgstr "Zignorowa³em %d s³ów ze znakami nie ASCII"
+
+msgid "E845: Insufficient memory, word list will be incomplete"
+msgstr "E845: Nie wystarczaj¹ca iloœæ pamiêci, lista s³ów bêdzie niekompletna"
+
+#, c-format
+msgid "Compressed %d of %d nodes; %d (%d%%) remaining"
+msgstr "Skompresowano %d z %d wêz³ów; pozostaje %d (%d%%)"
+
+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.
+#.
+msgid "Performing soundfolding..."
+msgstr "Wykonujê kompresjê dŸwiêkow¹..."
+
+#, c-format
+msgid "Number of words after soundfolding: %ld"
+msgstr "Liczba s³ów po kompresji dŸwiêkowej: %ld"
+
+#, c-format
+msgid "Total number of words: %d"
+msgstr "Ca³kowita liczba s³ów: %d"
+
+#, c-format
+msgid "Writing suggestion file %s ..."
+msgstr "Zapisujê plik sugestii %s ..."
+
+#, c-format
+msgid "Estimated runtime memory use: %d bytes"
+msgstr "Oczekiwane zu¿ycie pamiêci: %d bajtów"
+
+msgid "E751: Output file name must not have region name"
+msgstr "E751: Nazwa pliku wynikowego nie mo¿e byæ nazw¹ regionu"
+
+msgid "E754: Only up to 8 regions supported"
+msgstr "E754: Wspieram tylko 8 regionów"
+
+#, c-format
+msgid "E755: Invalid region in %s"
+msgstr "E755: Nieprawid³owy region w %s"
+
+msgid "Warning: both compounding and NOBREAK specified"
+msgstr "Ostrze¿enie: okreœlono zarówno z³o¿enia jak i NOBREAK"
+
+#, c-format
+msgid "Writing spell file %s ..."
+msgstr "Zapisujê plik sprawdzania pisowni %s ..."
+
+msgid "Done!"
+msgstr "Zrobione!"
+
+#, c-format
+msgid "E765: 'spellfile' does not have %ld entries"
+msgstr "E765: 'spellfile' nie posiada wpisów %ld"
+
+#, c-format
+msgid "Word removed from %s"
+msgstr "Usuniêto s³owo z %s"
+
+#, c-format
+msgid "Word added to %s"
+msgstr "Dodano s³owo do %s"
+
+msgid "E763: Word characters differ between spell files"
+msgstr "E763: Znaki wyrazów ró¿ni¹ siê miêdzy plikami sprawdzania pisowni"
+
+msgid "Sorry, no suggestions"
+msgstr "Przykro mi, brak podpowiedzi"
+
+#, c-format
+msgid "Sorry, only %ld suggestions"
+msgstr "Przykro mi, tylko %ld podpowiedzi"
+
+#. for when 'cmdheight' > 1
+#. avoid more prompt
+#, c-format
+msgid "Change \"%.*s\" to:"
+msgstr "Zmieñ \"%.*s\" na:"
+
+#, c-format
+msgid " < \"%.*s\""
+msgstr " < \"%.*s\""
+
+msgid "E752: No previous spell replacement"
+msgstr "E752: Brak poprzednich podmian sprawdzania pisowni"
+
+#, c-format
+msgid "E753: Not found: %s"
+msgstr "E753: Nie znaleziono: %s"
+
+#, c-format
+msgid "E778: This does not look like a .sug file: %s"
+msgstr "E778: Ten plik nie wygl¹da na plik .sug: %s"
+
+#, c-format
+msgid "E779: Old .sug file, needs to be updated: %s"
+msgstr "E779: Stary plik .sug, konieczne jest uaktualnienie: %s"
+
+#, c-format
+msgid "E780: .sug file is for newer version of Vim: %s"
+msgstr "E780: Plik .sug dla nowszej wersji Vima: %s"
+
+#, c-format
+msgid "E781: .sug file doesn't match .spl file: %s"
+msgstr "E781: Plik .sug nie pasuje do pliku .spl: %s"
+
+#, 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.
+msgid "E783: duplicate char in MAP entry"
+msgstr "E783: Podwojony znak we wpisie MAP"
+
+msgid "No Syntax items defined for this buffer"
+msgstr "Brak elementów sk³adni okreœlonych dla tego bufora"
+
+#, c-format
+msgid "E390: Illegal argument: %s"
+msgstr "E390: Niedozwolony argument: %s"
+
+#, c-format
+msgid "E391: No such syntax cluster: %s"
+msgstr "E391: Nie ma takiego klastra sk³adni: %s"
+
+msgid "syncing on C-style comments"
+msgstr "synchronizacja komentarzy w stylu C"
+
+msgid "no syncing"
+msgstr "brak synchronizacji"
+
+msgid "syncing starts "
+msgstr "pocz¹tek synchronizacji"
+
+msgid " lines before top line"
+msgstr " wierszy przed górn¹ lini¹"
+
+msgid ""
+"\n"
+"--- Syntax sync items ---"
+msgstr ""
+"\n"
+"--- Elementy synchronizacji sk³adni ---"
+
+msgid ""
+"\n"
+"syncing on items"
+msgstr ""
+"\n"
+"synchronizujê na elementach"
+
+msgid ""
+"\n"
+"--- Syntax items ---"
+msgstr ""
+"\n"
+"--- Elementy sk³adni ---"
+
+#, c-format
+msgid "E392: No such syntax cluster: %s"
+msgstr "E392: Nie ma takiego klastra sk³adni: %s"
+
+msgid "minimal "
+msgstr "minimalnie "
+
+msgid "maximal "
+msgstr "maksymalnie "
+
+msgid "; match "
+msgstr "; pasuje "
+
+msgid " line breaks"
+msgstr "znaków nowego wiersza"
+
+msgid "E395: contains argument not accepted here"
+msgstr "E395: argument contains niedozwolony w tym miejscu"
+
+msgid "E844: invalid cchar value"
+msgstr "E844: Niew³aœciwa wartoœæ cchar"
+
+msgid "E393: group[t]here not accepted here"
+msgstr "E393: group[t]here niedozwolone w tym miejscu"
+
+#, c-format
+msgid "E394: Didn't find region item for %s"
+msgstr "E394: Nie znalaz³em elementów regionu dla %s"
+
+msgid "E397: Filename required"
+msgstr "E397: Wymagana nazwa pliku"
+
+msgid "E847: Too many syntax includes"
+msgstr "E847: Za du¿o w³¹czonych sk³adni"
+
+#, c-format
+msgid "E789: Missing ']': %s"
+msgstr "E789: Brak ']': %s"
+
+#, c-format
+msgid "E398: Missing '=': %s"
+msgstr "E398: Brak '=': %s"
+
+#, c-format
+msgid "E399: Not enough arguments: syntax region %s"
+msgstr "E399: Za ma³o argumentów: syntax region %s"
+
+msgid "E848: Too many syntax clusters"
+msgstr "E848: Za du¿o klastrów sk³adni"
+
+msgid "E400: No cluster specified"
+msgstr "E400: Brak specyfikacji klastra"
+
+#, c-format
+msgid "E401: Pattern delimiter not found: %s"
+msgstr "E401: Brak ogranicznika wzorca: %s"
+
+#, c-format
+msgid "E402: Garbage after pattern: %s"
+msgstr "E402: Œmieci po wzorcu: %s"
+
+msgid "E403: syntax sync: line continuations pattern specified twice"
+msgstr "E403: syntax sync: wielokrotnie podane wzorce kontynuacji wiersza"
+
+#, c-format
+msgid "E404: Illegal arguments: %s"
+msgstr "E404: Niedozwolone argumenty: %s"
+
+#, c-format
+msgid "E405: Missing equal sign: %s"
+msgstr "E405: Brak znaku równoœci: %s"
+
+#, c-format
+msgid "E406: Empty argument: %s"
+msgstr "E406: Pusty argument: %s"
+
+#, c-format
+msgid "E407: %s not allowed here"
+msgstr "E407: %s jest niedozwolone w tym miejscu"
+
+#, c-format
+msgid "E408: %s must be first in contains list"
+msgstr "E408: %s musi byæ pierwsze w liœcie contains"
+
+#, c-format
+msgid "E409: Unknown group name: %s"
+msgstr "E409: Nieznana nazwa grupy: %s"
+
+#, c-format
+msgid "E410: Invalid :syntax subcommand: %s"
+msgstr "E410: Niew³aœciwa podkomenda :syntax : %s"
+
+msgid ""
+" TOTAL COUNT MATCH SLOWEST AVERAGE NAME PATTERN"
+msgstr ""
+" WSZYTKO ILOŒÆ PASUJE NAJWOLN. ŒREDNIO NAZWA WZORZEC"
+
+msgid "E679: recursive loop loading syncolor.vim"
+msgstr "E679: rekursywna pêtla wczytuj¹ca syncolor.vim"
+
+#, c-format
+msgid "E411: highlight group not found: %s"
+msgstr "E411: nie znaleziono grupy podœwietlania: %s"
+
+#, c-format
+msgid "E412: Not enough arguments: \":highlight link %s\""
+msgstr "E412: Zbyt ma³o argumentów: \":highlight link %s\""
+
+#, c-format
+msgid "E413: Too many arguments: \":highlight link %s\""
+msgstr "E413: Zbyt wiele argumentów: \":highlight link %s\""
+
+msgid "E414: group has settings, highlight link ignored"
+msgstr "E414: grupa ma ustawienia; zignorowane pod³¹czenie podœwietlania"
+
+#, c-format
+msgid "E415: unexpected equal sign: %s"
+msgstr "E415: nieoczekiwany znak równoœci: %s"
+
+#, c-format
+msgid "E416: missing equal sign: %s"
+msgstr "E416: brak znaku równoœci: %s"
+
+#, c-format
+msgid "E417: missing argument: %s"
+msgstr "E417: brak argumentu: %s"
+
+#, c-format
+msgid "E418: Illegal value: %s"
+msgstr "E418: Niedozwolona wartoϾ: %s"
+
+msgid "E419: FG color unknown"
+msgstr "E419: Kolor FG nieznany"
+
+msgid "E420: BG color unknown"
+msgstr "E420: Kolor BG nieznany"
+
+#, c-format
+msgid "E421: Color name or number not recognized: %s"
+msgstr "E421: Nazwa lub liczba koloru nierozpoznana: %s"
+
+#, c-format
+msgid "E422: terminal code too long: %s"
+msgstr "E422: za d³ugi kod terminala: %s"
+
+#, c-format
+msgid "E423: Illegal argument: %s"
+msgstr "E423: Niedozwolony argument: %s"
+
+msgid "E424: Too many different highlighting attributes in use"
+msgstr "E424: Zbyt wiele ró¿nych atrybutów podkreœlania w u¿yciu"
+
+msgid "E669: Unprintable character in group name"
+msgstr "E669: Niedrukowalny znak w nazwie grupy"
+
+msgid "W18: Invalid character in group name"
+msgstr "W18: nieprawid³owy znak w nazwie grupy"
+
+msgid "E849: Too many highlight and syntax groups"
+msgstr "E849: Za du¿o grup podœwietlania i sk³adni"
+
+msgid "E555: at bottom of tag stack"
+msgstr "E555: na dole stosu znaczników"
+
+msgid "E556: at top of tag stack"
+msgstr "E556: na górze stosu znaczników"
+
+msgid "E425: Cannot go before first matching tag"
+msgstr "E425: Nie mo¿na przejœæ przed pierwszy pasuj¹cy znacznik"
+
+#, c-format
+msgid "E426: tag not found: %s"
+msgstr "E426: nie znaleziono znacznika: %s"
+
+msgid " # pri kind tag"
+msgstr " # pri rodzaj znacznik"
+
+msgid "file\n"
+msgstr "plik\n"
+
+msgid "E427: There is only one matching tag"
+msgstr "E427: Pasuje tylko jeden znacznik"
+
+msgid "E428: Cannot go beyond last matching tag"
+msgstr "E428: Nie mo¿na przejœæ za ostatni pasuj¹cy znacznik"
+
+#, c-format
+msgid "File \"%s\" does not exist"
+msgstr "Plik \"%s\" nie istnieje"
+
+#. Give an indication of the number of matching tags
+#, c-format
+msgid "tag %d of %d%s"
+msgstr "znacznik %d z %d%s"
+
+msgid " or more"
+msgstr " lub wiêcej"
+
+msgid " Using tag with different case!"
+msgstr " U¿ywam znacznika o odmiennej wielkoœci liter!"
+
+#, c-format
+msgid "E429: File \"%s\" does not exist"
+msgstr "E429: Plik \"%s\" nie istnieje"
+
+#. Highlight title
+msgid ""
+"\n"
+" # TO tag FROM line in file/text"
+msgstr ""
+"\n"
+" # DO znacznik OD wiersza w pliku/tekœcie"
+
+#, c-format
+msgid "Searching tags file %s"
+msgstr "Szukam w pliku znaczników %s"
+
+#, c-format
+msgid "E430: Tag file path truncated for %s\n"
+msgstr "E430: Trop szukania pliku znaczników obciêty dla %s\n"
+
+msgid "Ignoring long line in tags file"
+msgstr "Ignorujê d³ugie wiersze w pliku znaczników"
+
+#, c-format
+msgid "E431: Format error in tags file \"%s\""
+msgstr "E431: B³¹d formatu w pliku znaczników \"%s\""
+
+#, c-format
+msgid "Before byte %ld"
+msgstr "Przed bajtem %ld"
+
+#, c-format
+msgid "E432: Tags file not sorted: %s"
+msgstr "E432: Plik znaczników nieuporz¹dkowany: %s"
+
+#. never opened any tags file
+msgid "E433: No tags file"
+msgstr "E433: Brak pliku znaczników"
+
+msgid "E434: Can't find tag pattern"
+msgstr "E434: Nie mogê znaleŸæ wzorca znacznika"
+
+msgid "E435: Couldn't find tag, just guessing!"
+msgstr "E435: Nie znalaz³em znacznika - tylko zgadujê!"
+
+#, c-format
+msgid "Duplicate field name: %s"
+msgstr "Powtórzona nazwa pola: %s"
+
+msgid "' not known. Available builtin terminals are:"
+msgstr "' nieznany. Mo¿liwe typy wbudowanych terminali:"
+
+msgid "defaulting to '"
+msgstr "domyœlnie jest '"
+
+msgid "E557: Cannot open termcap file"
+msgstr "E557: Nie mogê otworzyæ pliku termcap"
+
+msgid "E558: Terminal entry not found in terminfo"
+msgstr "E558: Nie ma opisu takiego terminala w terminfo"
+
+msgid "E559: Terminal entry not found in termcap"
+msgstr "E559: Nie ma opisu takiego terminala w termcap"
+
+#, c-format
+msgid "E436: No \"%s\" entry in termcap"
+msgstr "E436: Brak opisu \"%s\" w termcap"
+
+msgid "E437: terminal capability \"cm\" required"
+msgstr "E437: wymagana zdolnoϾ \"cm\" terminala"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Terminal keys ---"
+msgstr ""
+"\n"
+"--- Klawisze terminala ---"
+
+msgid "new shell started\n"
+msgstr "uruchomiono now¹ pow³okê\n"
+
+msgid "Vim: Error reading input, exiting...\n"
+msgstr "Vim: B³¹d podczas wczytywania wejœcia, koñczê...\n"
+
+msgid "Used CUT_BUFFER0 instead of empty selection"
+msgstr "U¿ywam CUT_BUFFER0 zamiast pustego wyboru"
+
+#. This happens when the FileChangedRO autocommand changes the
+#. * file in a way it becomes shorter.
+msgid "E834: Line count changed unexpectedly"
+msgstr "E834: Niespodziewana zmiana iloœci linii"
+
+#. must display the prompt
+msgid "No undo possible; continue anyway"
+msgstr "Cofniêcie niemo¿liwe; mimo to kontynuujê"
+
+#, c-format
+msgid "E828: Cannot open undo file for writing: %s"
+msgstr "E828: Nie mogê otworzyæ do zapisu pliku undo: %s"
+
+#, c-format
+msgid "E825: Corrupted undo file (%s): %s"
+msgstr "E825: Uszkodzony plik undo (%s): %s"
+
+msgid "Cannot write undo file in any directory in 'undodir'"
+msgstr "Nie mo¿na zapisaæ pliku undo w ¿adnym katalogu z 'undodir'"
+
+#, c-format
+msgid "Will not overwrite with undo file, cannot read: %s"
+msgstr "Nie nadpiszê plikiem undo, nie mogê odczytaæ: %s"
+
+#, c-format
+msgid "Will not overwrite, this is not an undo file: %s"
+msgstr "Nie nadpiszê, to nie jest plik undo: %s"
+
+msgid "Skipping undo file write, nothing to undo"
+msgstr "Pomijam zapis pliku undo, nic do cofniêcia"
+
+#, c-format
+msgid "Writing undo file: %s"
+msgstr "Zapisujê plik undo: %s"
+
+#, c-format
+msgid "E829: write error in undo file: %s"
+msgstr "E829: B³¹d zapisu w pliku undo: %s"
+
+#, c-format
+msgid "Not reading undo file, owner differs: %s"
+msgstr "Nie wczytujê pliku undo, inny w³aœciciel: %s"
+
+#, c-format
+msgid "Reading undo file: %s"
+msgstr "Wczytujê plik undo: %s"
+
+#, c-format
+msgid "E822: Cannot open undo file for reading: %s"
+msgstr "E822: Nie mogê otworzyæ pliku undo do odczytu: %s"
+
+#, c-format
+msgid "E823: Not an undo file: %s"
+msgstr "E823: To nie jest plik undo: %s"
+
+#, c-format
+msgid "E832: Non-encrypted file has encrypted undo file: %s"
+msgstr "E832: Nie zaszyfrowany plik ma zaszyfrowany plik undo: %s"
+
+#, c-format
+msgid "E826: Undo file decryption failed: %s"
+msgstr "E826: Nie powiod³o siê odszyfrowywanie pliku undo: %s"
+
+#, c-format
+msgid "E827: Undo file is encrypted: %s"
+msgstr "E827: Plik undo jest zaszyfrowany: %s"
+
+#, c-format
+msgid "E824: Incompatible undo file: %s"
+msgstr "E824: Niekompatybilny plik undo: %s"
+
+msgid "File contents changed, cannot use undo info"
+msgstr "Zawartoœæ pliku siê zmieni³a, nie mogê u¿yæ pliku undo"
+
+#, c-format
+msgid "Finished reading undo file %s"
+msgstr "Skoñczono wczytywanie pliku undo %s"
+
+msgid "Already at oldest change"
+msgstr "Ju¿ w miejscu ostatniej zmiany"
+
+msgid "Already at newest change"
+msgstr "Ju¿ w miejscu najnowszej zmiany"
+
+#, c-format
+msgid "E830: Undo number %ld not found"
+msgstr "E830: Nie znaleziono numeru cofniêcia %ld"
+
+msgid "E438: u_undo: line numbers wrong"
+msgstr "E438: u_undo: niew³aœciwe numery wierszy"
+
+msgid "more line"
+msgstr "1 wiersz wiêcej"
+
+msgid "more lines"
+msgstr "wiêcej wierszy"
+
+msgid "line less"
+msgstr "1 wiersz mniej"
+
+msgid "fewer lines"
+msgstr "mniej wierszy"
+
+msgid "change"
+msgstr "1 zmiana"
+
+msgid "changes"
+msgstr "zmiany"
+
+#, c-format
+msgid "%ld %s; %s #%ld %s"
+msgstr "%ld %s; %s #%ld %s"
+
+msgid "before"
+msgstr "przed"
+
+msgid "after"
+msgstr "za"
+
+msgid "Nothing to undo"
+msgstr "Nie ma zmian do cofniêcia"
+
+msgid "number changes when saved"
+msgstr "liczba zmiany kiedy zapisano"
+
+#, c-format
+msgid "%ld seconds ago"
+msgstr "%ld sekund temu"
+
+msgid "E790: undojoin is not allowed after undo"
+msgstr "E790: undojoin nie jest dozwolone po undo"
+
+msgid "E439: undo list corrupt"
+msgstr "E439: uszkodzona lista cofania"
+
+msgid "E440: undo line missing"
+msgstr "E440: brak wiersza cofania"
+
+#. Only MS VC 4.1 and earlier can do Win32s
+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"
+"Included patches: "
+msgstr ""
+"\n"
+"Zadane ³aty: "
+
+msgid ""
+"\n"
+"Extra patches: "
+msgstr ""
+"\n"
+"Ekstra ³aty: "
+
+msgid "Modified by "
+msgstr "Zmieniony przez "
+
+msgid ""
+"\n"
+"Compiled "
+msgstr ""
+"\n"
+"Skompilowany "
+
+msgid "by "
+msgstr "przez "
+
+msgid ""
+"\n"
+"Huge version "
+msgstr ""
+"\n"
+"Olbrzymia wersja "
+
+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 "without GUI."
+msgstr "bez GUI."
+
+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 " Features included (+) or not (-):\n"
+msgstr " Opcje w³¹czone (+) lub nie (-):\n"
+
+msgid " system vimrc file: \""
+msgstr " vimrc systemu: \""
+
+msgid " user vimrc file: \""
+msgstr " vimrc u¿ytkownika: \""
+
+msgid " 2nd user vimrc file: \""
+msgstr " 2-gi plik vimrc u¿ytkownika: \""
+
+msgid " 3rd user vimrc file: \""
+msgstr " 3-ci plik vimrc u¿ytkownika: \""
+
+msgid " user exrc file: \""
+msgstr " exrc u¿ytkownika: \""
+
+msgid " 2nd user exrc file: \""
+msgstr " 2-gi plik exrc u¿ytkownika: \""
+
+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 " fall-back for $VIM: \""
+msgstr " odwet dla $VIM-a: \""
+
+msgid " f-b for $VIMRUNTIME: \""
+msgstr "f-b dla $VIMRUNTIME: \""
+
+msgid "Compilation: "
+msgstr "Kompilacja: "
+
+msgid "Compiler: "
+msgstr "Kompilator: "
+
+msgid "Linking: "
+msgstr "Konsolidacja: "
+
+msgid " DEBUG BUILD"
+msgstr " KOMPILACJA DEBUG"
+
+msgid "VIM - Vi IMproved"
+msgstr "VIM - Vi rozbudowany"
+
+msgid "version "
+msgstr "wersja "
+
+msgid "by Bram Moolenaar et al."
+msgstr "Autor: Bram Moolenaar i Inni."
+
+msgid "Vim is open source and freely distributable"
+msgstr "Vim jest open source i rozprowadzany darmowo"
+
+msgid "Help poor children in Uganda!"
+msgstr "Pomó¿ biednym dzieciom w Ugandzie!"
+
+msgid "type :help iccf<Enter> for information "
+msgstr "wprowadŸ :help iccf<Enter> dla informacji o tym "
+
+msgid "type :q<Enter> to exit "
+msgstr "wprowadŸ :q<Enter> zakoñczenie programu "
+
+msgid "type :help<Enter> or <F1> for on-line help"
+msgstr "wprowadŸ :help<Enter> lub <F1> pomoc na bie¿¹co "
+
+msgid "type :help version7<Enter> for version info"
+msgstr "wprowadŸ :help version7<Enter> dla informacji o wersji"
+
+msgid "Running in Vi compatible mode"
+msgstr "Dzia³am w trybie zgodnoœci z Vi"
+
+msgid "type :set nocp<Enter> for Vim defaults"
+msgstr "wprowadŸ :set nocp<Enter> wartoœci domyœlne Vim-a"
+
+msgid "type :help cp-default<Enter> for info on this"
+msgstr "wprowadŸ :help cp-default<Enter> dla informacji to tym "
+
+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 "Sponsor Vim development!"
+msgstr "Sponsoruj rozwój Vima!"
+
+msgid "Become a registered Vim user!"
+msgstr "Zostañ zarejestrowanym u¿ytkownikiem Vima!"
+
+msgid "type :help sponsor<Enter> for information "
+msgstr "wprowadŸ :help sponsor<Enter> dla informacji"
+
+msgid "type :help register<Enter> for information "
+msgstr "wprowadŸ :help register<Enter> dla informacji"
+
+msgid "menu Help->Sponsor/Register for information "
+msgstr "menu Pomoc->Sponsoruj/Zarejestruj siê dla informacji"
+
+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 "Already only one window"
+msgstr "Ju¿ jest tylko jeden widok"
+
+msgid "E441: There is no preview window"
+msgstr "E441: Nie ma okna podgl¹du"
+
+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"
+
+msgid "E443: Cannot rotate when another window is split"
+msgstr "E443: Nie mogê przekrêciæ, gdy inne okno jest rozdzielone"
+
+msgid "E444: Cannot close last window"
+msgstr "E444: Nie mogê zamkn¹æ ostatniego okna"
+
+msgid "E813: Cannot close autocmd window"
+msgstr "E813: Nie mo¿na zamkn¹æ okna autocmd"
+
+msgid "E814: Cannot close window, only autocmd window would remain"
+msgstr "E814: Nie mo¿na zamkn¹æ okna, zosta³oby tylko okno autocmd"
+
+msgid "E445: Other window contains changes"
+msgstr "E445: Inne okno zawiera zmiany"
+
+msgid "E446: No file name under cursor"
+msgstr "E446: Brak nazwy pliku pod kursorem"
+
+#, c-format
+msgid "E447: Can't find file \"%s\" in path"
+msgstr "E447: Nie mogê znaleŸæ pliku \"%s\" w tropie"
+
+#, c-format
+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"
+
+#. Now concatenate
+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 "--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.
+#.
+msgid "E470: Command aborted"
+msgstr "E470: Przerwanie komendy"
+
+msgid "E471: Argument required"
+msgstr "E471: wymagany argument"
+
+msgid "E10: \\ should be followed by /, ? or &"
+msgstr "E10: po \\ powinno byæ /, ? lub &"
+
+msgid "E11: Invalid in command-line window; <CR> executes, CTRL-C quits"
+msgstr ""
+"E11: Niedozwolone w oknie wiersza poleceñ; <CR> wykonuje, CTRL-C opuszcza"
+
+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"
+
+msgid "E171: Missing :endif"
+msgstr "E171: Brak :endif"
+
+msgid "E600: Missing :endtry"
+msgstr "E600: Brak :endtry"
+
+msgid "E170: Missing :endwhile"
+msgstr "E170: Brak :endwhile"
+
+msgid "E170: Missing :endfor"
+msgstr "E170: Brak :endfor"
+
+msgid "E588: :endwhile without :while"
+msgstr "E588: :endwhile bez :while"
+
+msgid "E588: :endfor without :for"
+msgstr "E588: :endfor bez :for"
+
+msgid "E13: File exists (add ! to override)"
+msgstr "E13: Plik istnieje (wymuœ poprzez !)"
+
+msgid "E472: Command failed"
+msgstr "E472: Komenda nie powiod³a siê"
+
+#, c-format
+msgid "E234: Unknown fontset: %s"
+msgstr "E234: Nieznany zestaw czcionek: %s"
+
+#, c-format
+msgid "E235: Unknown font: %s"
+msgstr "E235: Nieznana czcionka: %s"
+
+#, c-format
+msgid "E236: Font \"%s\" is not fixed-width"
+msgstr "E236: Czcionka \"%s\" nie ma sta³ej szerokoœci znaków"
+
+msgid "E473: Internal error"
+msgstr "E473: B³¹d wewnêtrzny"
+
+msgid "Interrupted"
+msgstr "Przerwane"
+
+msgid "E14: Invalid address"
+msgstr "E14: Niew³aœciwy adres"
+
+msgid "E474: Invalid argument"
+msgstr "E474: Niew³aœciwy argument"
+
+#, c-format
+msgid "E475: Invalid argument: %s"
+msgstr "E475: Niew³aœciwy argument: %s"
+
+#, c-format
+msgid "E15: Invalid expression: %s"
+msgstr "E15: Niew³aœciwe wyra¿enie: %s"
+
+msgid "E16: Invalid range"
+msgstr "E16: Niew³aœciwy zakres"
+
+msgid "E476: Invalid command"
+msgstr "E476: Niew³aœciwa komenda"
+
+#, c-format
+msgid "E17: \"%s\" is a directory"
+msgstr "E17: \"%s\" jest katalogiem"
+
+#, c-format
+msgid "E364: Library call failed for \"%s()\""
+msgstr "E364: Wywo³anie z biblioteki nie powiod³o siê dla \"%s()\""
+
+#, c-format
+msgid "E448: Could not load library function %s"
+msgstr "E448: Nie mo¿na za³adowaæ funkcji biblioteki %s"
+
+msgid "E19: Mark has invalid line number"
+msgstr "E19: Zak³adka ma niew³aœciwy numer wiersza"
+
+msgid "E20: Mark not set"
+msgstr "E20: Zak³adka nienastawiona"
+
+msgid "E21: Cannot make changes, 'modifiable' is off"
+msgstr "E21: Nie mogê wykonaæ zmian, 'modifiable' jest wy³¹czone"
+
+msgid "E22: Scripts nested too deep"
+msgstr "E22: Zbyt g³êbokie zagnie¿d¿enie skryptów"
+
+msgid "E23: No alternate file"
+msgstr "E23: Brak pliku zamiany"
+
+msgid "E24: No such abbreviation"
+msgstr "E24: Nie ma takiego skrótu"
+
+msgid "E477: No ! allowed"
+msgstr "E477: Niedozwolone !"
+
+msgid "E25: GUI cannot be used: Not enabled at compile time"
+msgstr "E25: GUI nie mo¿e byæ u¿yte: Nie w³¹czono podczas kompilacji"
+
+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"
+
+#, c-format
+msgid "E28: No such highlight group name: %s"
+msgstr "E28: Brak takiej nazwy grupy podœwietlania: %s"
+
+msgid "E29: No inserted text yet"
+msgstr "E29: Nie wprowadzono jeszcze ¿adnego tekstu"
+
+msgid "E30: No previous command line"
+msgstr "E30: Nie ma poprzedniego wiersza poleceñ"
+
+msgid "E31: No such mapping"
+msgstr "E31: Nie ma takiego przyporz¹dkowania"
+
+msgid "E479: No match"
+msgstr "E479: Brak dopasowañ"
+
+#, c-format
+msgid "E480: No match: %s"
+msgstr "E480: Brak dopasowañ: %s"
+
+msgid "E32: No file name"
+msgstr "E32: Brak nazwy pliku"
+
+msgid "E33: No previous substitute regular expression"
+msgstr "E33: Brak poprzedniego podstawieniowego wyra¿enia regularnego"
+
+msgid "E34: No previous command"
+msgstr "E34: Brak poprzedniej komendy"
+
+msgid "E35: No previous regular expression"
+msgstr "E35: Brak poprzedniego wyra¿enia regularnego"
+
+msgid "E481: No range allowed"
+msgstr "E481: Zakres niedozwolony"
+
+msgid "E36: Not enough room"
+msgstr "E36: Brak miejsca"
+
+#, c-format
+msgid "E247: no registered server named \"%s\""
+msgstr "E247: brak zarejestrowanego serwera o nazwie \"%s\""
+
+#, c-format
+msgid "E482: Can't create file %s"
+msgstr "E482: Nie mogê stworzyæ pliku %s"
+
+msgid "E483: Can't get temp file name"
+msgstr "E483: Nie mogê pobraæ nazwy pliku tymczasowego"
+
+#, c-format
+msgid "E484: Can't open file %s"
+msgstr "E484: Nie mogê otworzyæ pliku %s"
+
+#, c-format
+msgid "E485: Can't read file %s"
+msgstr "E485: Nie mogê odczytaæ pliku %s"
+
+msgid "E37: No write since last change (add ! to override)"
+msgstr "E37: Nie zapisano od ostatniej zmiany (wymuœ przez !)"
+
+msgid "E38: Null argument"
+msgstr "E38: Zerowy argument"
+
+msgid "E39: Number expected"
+msgstr "E39: Oczekujê liczby"
+
+#, c-format
+msgid "E40: Can't open errorfile %s"
+msgstr "E40: Nie mogê otworzyæ pliku b³êdów %s"
+
+msgid "E233: cannot open display"
+msgstr "E233: nie mogê otworzyæ ekranu"
+
+msgid "E41: Out of memory!"
+msgstr "E41: Pamiêæ wyczerpana!"
+
+msgid "Pattern not found"
+msgstr "Nie znaleziono wzorca"
+
+#, c-format
+msgid "E486: Pattern not found: %s"
+msgstr "E486: Nie znaleziono wzorca: %s"
+
+msgid "E487: Argument must be positive"
+msgstr "E487: Argument musi byæ dodatni"
+
+msgid "E459: Cannot go back to previous directory"
+msgstr "E459: Nie mo¿na przejœæ do poprzedniego katalogu"
+
+msgid "E42: No Errors"
+msgstr "E42: Brak B³êdów"
+
+msgid "E776: No location list"
+msgstr "E776: Brak listy lokacji"
+
+msgid "E43: Damaged match string"
+msgstr "E43: Popsuty ci¹g wzorca"
+
+msgid "E44: Corrupted regexp program"
+msgstr "E44: Zepsuty program wyra¿eñ regularnych"
+
+msgid "E45: 'readonly' option is set (add ! to override)"
+msgstr "E45: opcja 'readonly' jest ustawiona (wymuœ poprzez !)"
+
+#, c-format
+msgid "E46: Cannot change read-only variable \"%s\""
+msgstr "E46: Nie mogê zmieniæ zmiennej tylko do odczytu \"%s\""
+
+#, c-format
+msgid "E794: Cannot set variable in the sandbox: \"%s\""
+msgstr "E794: Nie mogê ustawiæ zmiennej w piaskownicy: \"%s\""
+
+msgid "E47: Error while reading errorfile"
+msgstr "E47: B³¹d w trakcie czytania pliku b³êdów"
+
+msgid "E48: Not allowed in sandbox"
+msgstr "E48: Niedozwolone w piaskownicy"
+
+msgid "E523: Not allowed here"
+msgstr "E523: Niedozwolone w tym miejscu"
+
+msgid "E359: Screen mode setting not supported"
+msgstr "E359: Ustawianie trybu ekranu niewspomagane"
+
+msgid "E49: Invalid scroll size"
+msgstr "E49: Niew³aœciwa wielkoœæ przewiniêcia"
+
+msgid "E91: 'shell' option is empty"
+msgstr "E91: opcja 'shell' jest pusta"
+
+msgid "E255: Couldn't read in sign data!"
+msgstr "E255: Nie mog³em wczytaæ danych znaku!"
+
+msgid "E72: Close error on swap file"
+msgstr "E72: B³¹d podczas zamykania pliku wymiany"
+
+msgid "E73: tag stack empty"
+msgstr "E73: stos znaczników jest pusty"
+
+msgid "E74: Command too complex"
+msgstr "E74: Komenda jest zbyt skomplikowana"
+
+msgid "E75: Name too long"
+msgstr "E75: Zbyt d³uga nazwa"
+
+msgid "E76: Too many ["
+msgstr "E76: Zbyt wiele ["
+
+msgid "E77: Too many file names"
+msgstr "E77: Zbyt wiele nazw plików"
+
+msgid "E488: Trailing characters"
+msgstr "E488: Nadstêpne znaczki"
+
+msgid "E78: Unknown mark"
+msgstr "E78: Nieznana zak³adka"
+
+msgid "E79: Cannot expand wildcards"
+msgstr "E79: Nie mog¹ rozwin¹æ znaków wieloznacznych"
+
+msgid "E591: 'winheight' cannot be smaller than 'winminheight'"
+msgstr "E591: 'winheight' nie mo¿e byæ mniejsze ni¿ 'winminheight'"
+
+msgid "E592: 'winwidth' cannot be smaller than 'winminwidth'"
+msgstr "E592: 'winwidth' nie mo¿e byæ mniejsze ni¿ 'winminwidth'"
+
+msgid "E80: Error while writing"
+msgstr "E80: B³¹d w trakcie zapisu"
+
+msgid "Zero count"
+msgstr "Zerowy licznik"
+
+msgid "E81: Using <SID> not in a script context"
+msgstr "E81: U¿ycie <SID> poza kontekstem skryptu"
+
+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"
+
+#, c-format
+msgid "E685: Internal error: %s"
+msgstr "E685: B³¹d wewnêtrzny: %s"
+
+msgid "E363: pattern uses more memory than 'maxmempattern'"
+msgstr "E363: Wzorzec u¿ywa wiêcej pamiêci ni¿ 'maxmempattern'"
+
+msgid "E749: empty buffer"
+msgstr "E749: pusty bufor"
+
+msgid "E682: Invalid search pattern or delimiter"
+msgstr "E682: Niew³aœciwy wzorzec wyszukiwania lub delimiter"
+
+msgid "E139: File is loaded in another buffer"
+msgstr "E139: Plik jest za³adowany w innym buforze"
+
+#, c-format
+msgid "E764: Option '%s' is not set"
+msgstr "E764: Nie ustawiono opcji '%s'"
+
+msgid "E850: Invalid register name"
+msgstr "E850: Niew³aœciwa nazwa rejestru"
+
+msgid "search hit TOP, continuing at BOTTOM"
+msgstr "szukanie dobi³o GÓRY; kontynuacja od KOÑCA"
+
+msgid "search hit BOTTOM, continuing at TOP"
+msgstr "szukanie dobi³o KOÑCA; kontynuacja od GÓRY"
+
+#, c-format
+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"
+
+#, c-format
+msgid "failed to add key '%s' to dictionary"
+msgstr "nie powiod³o siê dodanie klucza '%s' do s³ownika"
+
+#, c-format
+msgid "index must be int or slice, not %s"
+msgstr "indeks musi byæ liczb¹ lub wycinkiem, nie %s"
+
+#, c-format
+msgid "expected str() or unicode() instance, but got %s"
+msgstr "czeka³em na str() lub unicode(), a dosta³em %s"
+
+#, c-format
+msgid "expected bytes() or str() instance, but got %s"
+msgstr "czeka³em na bytes() lub str(), a dosta³em %s"
+
+#, c-format
+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"
+
+#, c-format
+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"
+
+#, c-format
+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"
+
+#, c-format
+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"
+
+#, c-format
+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"
+
+#, c-format
+msgid "cannot set attribute %s"
+msgstr "nie mogê ustawiæ atrybutu %s"
+
+msgid "hashtab changed during iteration"
+msgstr "hashtab zmieni³ siê w czasie iteracji"
+
+#, c-format
+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"
+
+#. No more suitable format specifications in python-2.3
+#, c-format
+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"
+
+#, c-format
+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"
+
+#, c-format
+msgid "unnamed function %s does not exist"
+msgstr "nie nazwana funkcja %s nie istnieje"
+
+#, c-format
+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"
+
+#, c-format
+msgid "failed to run function %s"
+msgstr "nie mogê uruchomiæ funkcji %s"
+
+msgid "unable to get option value"
+msgstr "nie mogê pobraæ wartoœci opcji"
+
+msgid "internal error: unknown option type"
+msgstr "b³¹d wewnêtrzny: nieznany typ opcji"
+
+msgid "problem while switching windows"
+msgstr "wyst¹pi³ problem w czasie zmiany okien"
+
+#, c-format
+msgid "unable to unset global option %s"
+msgstr "nie mogê wyzerowaæ opcji globalnej %s"
+
+#, c-format
+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"
+
+#, c-format
+msgid "expected vim.Buffer object, but got %s"
+msgstr "oczekiwa³em na obiekt vim.Buffer, a dosta³em %s"
+
+#, c-format
+msgid "failed to switch to buffer %d"
+msgstr "nie przeszed³em do bufora %d"
+
+#, c-format
+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"
+
+#, c-format
+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"
+
+#, c-format
+msgid "unable to convert %s to vim dictionary"
+msgstr "nie mo¿na konwertowaæ %s do s³ownika Vima"
+
+#, c-format
+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/po/pl.po b/src/po/pl.po
new file mode 100644
index 0000000000..a629d7b0a3
--- /dev/null
+++ b/src/po/pl.po
@@ -0,0 +1,6904 @@
+# 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: 2013-07-06 19:33+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"
+
+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 "[Location List]"
+msgstr "[Lista lokacji]"
+
+msgid "[Quickfix List]"
+msgstr "[Lista quickfix]"
+
+msgid "E855: Autocommands caused command to abort"
+msgstr "E855: Autokomendy spowodowa³y porzucenie komendy"
+
+msgid "E82: Cannot allocate any buffer, exiting..."
+msgstr "E82: Nie mogê zarezerwowaæ bufora; zakoñczenie..."
+
+msgid "E83: Cannot allocate buffer, using other one..."
+msgstr "E83: Nie mogê zarezerwowaæ bufora; u¿ywam innego..."
+
+msgid "E515: No buffers were unloaded"
+msgstr "E515: Nie wy³adowano ¿adnego bufora"
+
+msgid "E516: No buffers were deleted"
+msgstr "E516: Nie skasowano ¿adnego bufora"
+
+msgid "E517: No buffers were wiped out"
+msgstr "E517: Nie wyrzucono ¿adnego bufora"
+
+msgid "1 buffer unloaded"
+msgstr "1 bufor wy³adowany"
+
+#, c-format
+msgid "%d buffers unloaded"
+msgstr "wy³adowano %d buforów"
+
+msgid "1 buffer deleted"
+msgstr "1 bufor skasowany"
+
+#, c-format
+msgid "%d buffers deleted"
+msgstr "%d buforów skasowano"
+
+msgid "1 buffer wiped out"
+msgstr "wyrzucono 1 bufor "
+
+#, c-format
+msgid "%d buffers wiped out"
+msgstr "wyrzucono %d buforów"
+
+msgid "E84: No modified buffer found"
+msgstr "E84: Nie znaleziono zmienionych buforów"
+
+#. back where we started, didn't find anything.
+msgid "E85: There is no listed buffer"
+msgstr "E85: Nie ma wylistowanych buforów"
+
+#, c-format
+msgid "E86: Buffer %ld does not exist"
+msgstr "E86: Bufor \"%ld\" nie istnieje"
+
+msgid "E87: Cannot go beyond last buffer"
+msgstr "E87: Nie mogê przej¶æ poza ostatni bufor"
+
+msgid "E88: Cannot go before first buffer"
+msgstr "E88: Nie mogê przej¶æ przed pierwszy bufor"
+
+#, c-format
+msgid "E89: No write since last change for buffer %ld (add ! to override)"
+msgstr "E89: Nie zapisano zmian w buforze %ld (wymu¶ przez !)"
+
+msgid "E90: Cannot unload last buffer"
+msgstr "E90: Nie mogê wy³adowaæ ostatniego bufora"
+
+msgid "W14: Warning: List of file names overflow"
+msgstr "W14: OSTRZE¯ENIE: Przepe³nienie listy nazw plików"
+
+#, c-format
+msgid "E92: Buffer %ld not found"
+msgstr "E92: Nie znaleziono bufora %ld"
+
+#, c-format
+msgid "E93: More than one match for %s"
+msgstr "E93: Wielokrotne dopasowania dla %s"
+
+#, c-format
+msgid "E94: No matching buffer for %s"
+msgstr "E94: ¯aden bufor nie pasuje do %s"
+
+#, c-format
+msgid "line %ld"
+msgstr "wiersz %ld"
+
+msgid "E95: Buffer with this name already exists"
+msgstr "E95: Bufor o tej nazwie ju¿ istnieje"
+
+msgid " [Modified]"
+msgstr " [Zmieniony]"
+
+msgid "[Not edited]"
+msgstr "[Nie edytowany]"
+
+msgid "[New file]"
+msgstr "[Nowy Plik]"
+
+msgid "[Read errors]"
+msgstr "[B³±d odczytu]"
+
+msgid "[RO]"
+msgstr "[RO]"
+
+msgid "[readonly]"
+msgstr "[tylko odczyt]"
+
+#, c-format
+msgid "1 line --%d%%--"
+msgstr "1 wiersz --%d%%--"
+
+#, c-format
+msgid "%ld lines --%d%%--"
+msgstr "%ld wiersze --%d%%--"
+
+#, c-format
+msgid "line %ld of %ld --%d%%-- col "
+msgstr "wiersz %ld z %ld --%d%%-- kol "
+
+msgid "[No Name]"
+msgstr "[Bez nazwy]"
+
+#. must be a help buffer
+msgid "help"
+msgstr "pomoc"
+
+msgid "[Help]"
+msgstr "[Pomoc]"
+
+msgid "[Preview]"
+msgstr "[Podgl±d]"
+
+msgid "All"
+msgstr "Wszystko"
+
+msgid "Bot"
+msgstr "Dó³"
+
+msgid "Top"
+msgstr "Góra"
+
+msgid ""
+"\n"
+"# Buffer list:\n"
+msgstr ""
+"\n"
+"# Lista buforów:\n"
+
+msgid "[Scratch]"
+msgstr "[Notka]"
+
+msgid ""
+"\n"
+"--- Signs ---"
+msgstr ""
+"\n"
+"--- Znaki ---"
+
+#, c-format
+msgid "Signs for %s:"
+msgstr "Znaki dla %s:"
+
+#, c-format
+msgid " line=%ld id=%d name=%s"
+msgstr " wiersz=%ld id=%d nazwa=%s"
+
+#, c-format
+msgid "E96: Can not diff more than %ld buffers"
+msgstr "E96: Nie mogê zró¿nicowaæ wiêcej ni¿ %ld buforów"
+
+msgid "E810: Cannot read or write temp files"
+msgstr "E810: Nie mogê otworzyæ lub zapisaæ plików tymczasowych"
+
+msgid "E97: Cannot create diffs"
+msgstr "E97: Nie mogê stworzyæ ró¿nic"
+
+msgid "Patch file"
+msgstr "Plik ³ata"
+
+msgid "E816: Cannot read patch output"
+msgstr "E816: Nie mogê odczytaæ wyj¶cia pliku ³aty"
+
+msgid "E98: Cannot read diff output"
+msgstr "E98: Nie mogê wczytaæ wyj¶cia ró¿nicy"
+
+msgid "E99: Current buffer is not in diff mode"
+msgstr "E99: Bie¿±cy bufor nie jest w trybie ró¿nic"
+
+msgid "E793: No other buffer in diff mode is modifiable"
+msgstr "E793: ¯aden inny bufor w trybie diff nie jest modyfikowalny"
+
+msgid "E100: No other buffer in diff mode"
+msgstr "E100: Brak innego bufora w trybie ró¿nic"
+
+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æ"
+
+#, c-format
+msgid "E102: Can't find buffer \"%s\""
+msgstr "E102: Nie mogê znale¼æ bufora \"%s\""
+
+#, c-format
+msgid "E103: Buffer \"%s\" is not in diff mode"
+msgstr "E103: Bufor \"%s\" nie jest w trybie ró¿nicowania"
+
+msgid "E787: Buffer changed unexpectedly"
+msgstr "E787: Nieoczekiwana zmiana bufora"
+
+msgid "E104: Escape not allowed in digraph"
+msgstr "E104: Escape jest niedozwolone w dwugrafie"
+
+msgid "E544: Keymap file not found"
+msgstr "E544: Nie znaleziono pliku rozk³adu klawiszy"
+
+msgid "E105: Using :loadkeymap not in a sourced file"
+msgstr "E105: Zastosowano :loadkeymap w niewczytanym pliku"
+
+msgid "E791: Empty keymap entry"
+msgstr "E791: Pusty wpis keymap"
+
+msgid " Keyword completion (^N^P)"
+msgstr " Dope³nianie s³ów kluczowych (^N^P)"
+
+#. ctrl_x_mode == 0, ^P/^N compl.
+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)"
+
+msgid " Whole line completion (^L^N^P)"
+msgstr " Dope³nianie pe³nych wierszy (^L^N^P)"
+
+msgid " File name completion (^F^N^P)"
+msgstr " Dope³nianie nazw plików (^F^N^P)"
+
+msgid " Tag completion (^]^N^P)"
+msgstr " Dope³nianie znaczników (^]^N^P)"
+
+msgid " Path pattern completion (^N^P)"
+msgstr " Dope³nianie wzorców tropów (^N^P)"
+
+msgid " Definition completion (^D^N^P)"
+msgstr " Dope³nianie definicji (^D^N^P)"
+
+msgid " Dictionary completion (^K^N^P)"
+msgstr " Dope³nianie ze s³owników (^K^N^P)"
+
+msgid " Thesaurus completion (^T^N^P)"
+msgstr " Dope³nianie z tezaurusa (^T^N^P)"
+
+msgid " Command-line completion (^V^N^P)"
+msgstr " Dope³nianie wiersza poleceñ (^V^N^P)"
+
+msgid " User defined completion (^U^N^P)"
+msgstr "Dope³nianie zdefiniowane przez u¿ytkownika (^U^N^P)"
+
+msgid " Omni completion (^O^N^P)"
+msgstr " Omni uzupe³nianie (^O^N^P)"
+
+msgid " Spelling suggestion (s^N^P)"
+msgstr "Propozycja pisowni (^L^N^P)"
+
+msgid " Keyword Local completion (^N^P)"
+msgstr " Lokalne dope³nianie s³ów kluczowych (^N^P)"
+
+msgid "Hit end of paragraph"
+msgstr "Dobi³em do koñca akapitu"
+
+msgid "E839: Completion function changed window"
+msgstr "E839: Funkcja uzupe³niania zmieni³a okno"
+
+msgid "E840: Completion function deleted text"
+msgstr "E840: Funkcja uzupe³nania usunê³a tekst"
+
+msgid "'dictionary' option is empty"
+msgstr "opcja 'dictionary' jest pusta"
+
+msgid "'thesaurus' option is empty"
+msgstr "opcja 'thesaurus' jest pusta"
+
+#, c-format
+msgid "Scanning dictionary: %s"
+msgstr "Przegl±dam s³ownik: %s"
+
+msgid " (insert) Scroll (^E/^Y)"
+msgstr " (wprowadzanie) Przewijanie (^E/^Y)"
+
+msgid " (replace) Scroll (^E/^Y)"
+msgstr " (zamiana) Przewijanie (^E/^Y)"
+
+#, c-format
+msgid "Scanning: %s"
+msgstr "Przegl±dam: %s"
+
+msgid "Scanning tags."
+msgstr "Przegl±dam znaczniki."
+
+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.
+#.
+msgid "-- Searching..."
+msgstr "-- Szukam..."
+
+msgid "Back at original"
+msgstr "Z powrotem na pierwotnym"
+
+msgid "Word from other line"
+msgstr "Wyraz z innego wiersza"
+
+msgid "The only match"
+msgstr "Jedyne dopasowanie"
+
+#, c-format
+msgid "match %d of %d"
+msgstr "pasuje %d z %d"
+
+#, c-format
+msgid "match %d"
+msgstr "pasuje %d"
+
+msgid "E18: Unexpected characters in :let"
+msgstr "E18: Nieoczekiwane znaki w :let"
+
+#, c-format
+msgid "E684: list index out of range: %ld"
+msgstr "E684: Indeks listy poza zakresem: %ld"
+
+#, c-format
+msgid "E121: Undefined variable: %s"
+msgstr "E121: Nieokre¶lona zmienna: %s"
+
+msgid "E111: Missing ']'"
+msgstr "E111: Brak ']'"
+
+#, c-format
+msgid "E686: Argument of %s must be a List"
+msgstr "E686: Argument %s musi byæ List±"
+
+#, c-format
+msgid "E712: Argument of %s must be a List or Dictionary"
+msgstr "E712: Argument %s musi byæ List± lub S³ownikiem"
+
+msgid "E713: Cannot use empty key for Dictionary"
+msgstr "E713: Nie mo¿na u¿yæ pustego klucza dla S³ownika"
+
+msgid "E714: List required"
+msgstr "E714: wymagana Lista"
+
+msgid "E715: Dictionary required"
+msgstr "E715: wymagany S³ownik"
+
+#, c-format
+msgid "E118: Too many arguments for function: %s"
+msgstr "E118: Zbyt wiele argumentów dla funkcji: %s"
+
+#, c-format
+msgid "E716: Key not present in Dictionary: %s"
+msgstr "E716: Klucz nie istnieje w S³owniku: %s"
+
+#, c-format
+msgid "E122: Function %s already exists, add ! to replace it"
+msgstr "E122: Funkcja %s ju¿ istnieje; aby j± zamieniæ u¿yj !"
+
+msgid "E717: Dictionary entry already exists"
+msgstr "E717: istnieje ju¿ taki element S³ownika"
+
+msgid "E718: Funcref required"
+msgstr "E718: wymagana Funcref"
+
+msgid "E719: Cannot use [:] with a Dictionary"
+msgstr "E719: Nie mo¿na u¿yæ [:] przy S³owniku"
+
+#, c-format
+msgid "E734: Wrong variable type for %s="
+msgstr "E734: Z³y typ zmiennej dla %s="
+
+#, c-format
+msgid "E130: Unknown function: %s"
+msgstr "E130: Nieznana funkcja: %s"
+
+#, c-format
+msgid "E461: Illegal variable name: %s"
+msgstr "E461: Niedozwolona nazwa zmiennej: %s"
+
+msgid "E806: using Float as a String"
+msgstr "E806: U¿ycie Zmiennoprzecinkowej jako £añcucha"
+
+msgid "E687: Less targets than List items"
+msgstr "E687: Mniej celów ni¿ elementów Listy"
+
+msgid "E688: More targets than List items"
+msgstr "E688: Wiêcej celów ni¿ elementów Listy"
+
+msgid "Double ; in list of variables"
+msgstr "Podwójny ; w li¶cie zmiennych"
+
+#, c-format
+msgid "E738: Can't list variables for %s"
+msgstr "E738: Nie mogê wypisaæ zmiennych dla %s"
+
+msgid "E689: Can only index a List or Dictionary"
+msgstr "E689: Indeks mo¿e istnieæ tylko dla Listy lub S³ownika"
+
+msgid "E708: [:] must come last"
+msgstr "E708: [:] musi byæ ostatnie"
+
+msgid "E709: [:] requires a List value"
+msgstr "E709: [:] wymaga warto¶ci listy"
+
+msgid "E710: List value has more items than target"
+msgstr "E710: Lista ma wiêcej elementów ni¿ cel"
+
+msgid "E711: List value has not enough items"
+msgstr "E711: Lista nie ma wystarczaj±cej ilo¶ci elementów"
+
+msgid "E690: Missing \"in\" after :for"
+msgstr "E690: Brak \"in\" po :for"
+
+#, c-format
+msgid "E107: Missing parentheses: %s"
+msgstr "E107: Brak nawiasów: %s"
+
+#, c-format
+msgid "E108: No such variable: \"%s\""
+msgstr "E108: Nie istnieje zmienna: \"%s\""
+
+msgid "E743: variable nested too deep for (un)lock"
+msgstr "E743: zmienna zagnie¿d¿ona zbyt g³êboko dla (un)lock"
+
+msgid "E109: Missing ':' after '?'"
+msgstr "E109: Brak ':' po '?'"
+
+msgid "E691: Can only compare List with List"
+msgstr "E691: Listê mogê porównaæ tylko z List±"
+
+msgid "E692: Invalid operation for Lists"
+msgstr "E692: Nieprawid³owa operacja dla Listy"
+
+msgid "E735: Can only compare Dictionary with Dictionary"
+msgstr "E735: S³ownik mogê porównaæ tylko ze S³ownikiem"
+
+msgid "E736: Invalid operation for Dictionary"
+msgstr "E736: Nieprawid³owa operacja dla S³ownika"
+
+msgid "E693: Can only compare Funcref with Funcref"
+msgstr "E693: Funcref mogê porównaæ tylko z Funcref"
+
+msgid "E694: Invalid operation for Funcrefs"
+msgstr "E694: Nieprawid³owa operacja dla Funcref"
+
+msgid "E804: Cannot use '%' with Float"
+msgstr "E804: Nie mogê u¿yæ '%' w Zmiennoprzecinkowej"
+
+msgid "E110: Missing ')'"
+msgstr "E110: Brak ')'"
+
+msgid "E695: Cannot index a Funcref"
+msgstr "E695: Nie mo¿na zindeksowaæ Funcref"
+
+#, c-format
+msgid "E112: Option name missing: %s"
+msgstr "E112: Brak nazwy opcji: %s"
+
+#, c-format
+msgid "E113: Unknown option: %s"
+msgstr "E113: Nieznana opcja: %s"
+
+#, c-format
+msgid "E114: Missing quote: %s"
+msgstr "E114: Brak cudzys³owu: %s"
+
+#, c-format
+msgid "E115: Missing quote: %s"
+msgstr "E115: Brak cudzys³owu: %s"
+
+#, c-format
+msgid "E696: Missing comma in List: %s"
+msgstr "E696: Brakuj±cy przecinek w Li¶cie: '%s"
+
+#, c-format
+msgid "E697: Missing end of List ']': %s"
+msgstr "E697: Brak zakoñczenia Listy ']': %s"
+
+#, c-format
+msgid "E720: Missing colon in Dictionary: %s"
+msgstr "E720: Brak dwukropka w S³owniku: %s"
+
+#, c-format
+msgid "E721: Duplicate key in Dictionary: \"%s\""
+msgstr "E721: Powtórzony klucz w S³owniku: \"%s\""
+
+#, c-format
+msgid "E722: Missing comma in Dictionary: %s"
+msgstr "E722: Brakuj±cy przecinek w S³owniku: %s"
+
+#, c-format
+msgid "E723: Missing end of Dictionary '}': %s"
+msgstr "E723: Brak koñca w S³owniku '}': %s"
+
+msgid "E724: variable nested too deep for displaying"
+msgstr "E724: Zmienna zagnie¿d¿ona zbyt g³êboko by pokazaæ"
+
+#, c-format
+msgid "E740: Too many arguments for function %s"
+msgstr "E740: Zbyt wiele argumentów dla funkcji %s"
+
+#, c-format
+msgid "E116: Invalid arguments for function %s"
+msgstr "E116: Zbyt wiele argumentów dla funkcji %s"
+
+#, c-format
+msgid "E117: Unknown function: %s"
+msgstr "E117: Nieznana funkcja: %s"
+
+#, c-format
+msgid "E119: Not enough arguments for function: %s"
+msgstr "E119: Za ma³o argumentów dla funkcji: %s"
+
+#, c-format
+msgid "E120: Using <SID> not in a script context: %s"
+msgstr "E120: U¿ycie <SID> poza kontekstem skryptu: %s"
+
+#, c-format
+msgid "E725: Calling dict function without Dictionary: %s"
+msgstr "E725: Wywo³anie funkcji \"dict\" bez S³ownika: %s"
+
+msgid "E808: Number or Float required"
+msgstr "E808: Wymagana Liczba lub Zmiennoprzecinkowa"
+
+msgid "add() argument"
+msgstr "argument add()"
+
+msgid "E699: Too many arguments"
+msgstr "E699: Za du¿o argumentów"
+
+msgid "E785: complete() can only be used in Insert mode"
+msgstr "E785: complete() mo¿e byæ u¿yte tylko w trybie Wprowadzania"
+
+#.
+#. * 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"
+
+#, c-format
+msgid "E737: Key already exists: %s"
+msgstr "E737: Klucz ju¿ istnieje: %s"
+
+msgid "extend() argument"
+msgstr "argument extend()"
+
+msgid "map() argument"
+msgstr "argument map()"
+
+msgid "filter() argument"
+msgstr "argument filter()"
+
+#, c-format
+msgid "+-%s%3ld lines: "
+msgstr "+-%s%3ld wierszy: "
+
+#, c-format
+msgid "E700: Unknown function: %s"
+msgstr "E700: Nieznana funkcja: %s"
+
+msgid ""
+"&OK\n"
+"&Cancel"
+msgstr ""
+"&OK\n"
+"&Zakoñcz"
+
+msgid "called inputrestore() more often than inputsave()"
+msgstr "wywo³ano inputrestore() wiêcej razy ni¿ inputsave()"
+
+msgid "insert() argument"
+msgstr "argument insert()"
+
+msgid "E786: Range not allowed"
+msgstr "E786: Zakres niedozwolony"
+
+msgid "E701: Invalid type for len()"
+msgstr "E701: Nieprawid³owy typ dla len()"
+
+msgid "E726: Stride is zero"
+msgstr "E726: Skok to zero"
+
+msgid "E727: Start past end"
+msgstr "E727: Pocz±tek po koñcu"
+
+msgid "<empty>"
+msgstr "<pusty>"
+
+msgid "E240: No connection to Vim server"
+msgstr "E240: Brak po³±czenia z serwerem Vim"
+
+#, c-format
+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 "remove() argument"
+msgstr "argument remove()"
+
+msgid "E655: Too many symbolic links (cycle?)"
+msgstr "E655: Za du¿o dowi±zañ symbolicznych (pêtla?)"
+
+msgid "reverse() argument"
+msgstr "argument reverse()"
+
+msgid "E258: Unable to send to client"
+msgstr "E258: Nie mogê wys³aæ do klienta"
+
+msgid "sort() argument"
+msgstr "argument sort()"
+
+msgid "E702: Sort compare function failed"
+msgstr "E702: Funkcja porównywania w sort nie powiod³a siê"
+
+msgid "(Invalid)"
+msgstr "(Niew³a¶ciwe)"
+
+msgid "E677: Error writing temp file"
+msgstr "E677: B³±d zapisywania pliku tymczasowego"
+
+msgid "E805: Using a Float as a Number"
+msgstr "E805: U¿ycie Zmiennoprzecinkowej jako Liczby"
+
+msgid "E703: Using a Funcref as a Number"
+msgstr "E703: U¿ycie Funcref jako Liczby"
+
+msgid "E745: Using a List as a Number"
+msgstr "E745: U¿ycie Listy jako Liczby"
+
+msgid "E728: Using a Dictionary as a Number"
+msgstr "E728: U¿ycie S³ownika jako Liczby"
+
+msgid "E729: using Funcref as a String"
+msgstr "E729: U¿ycie Funcref jako £añcucha"
+
+msgid "E730: using List as a String"
+msgstr "E730: U¿ycie Listy jako £añcucha"
+
+msgid "E731: using Dictionary as a String"
+msgstr "E731: U¿ycie S³ownika jako £añcucha"
+
+#, c-format
+msgid "E706: Variable type mismatch for: %s"
+msgstr "E706: Nieprawid³owy typ zmiennej dla: %s"
+
+#, c-format
+msgid "E795: Cannot delete variable %s"
+msgstr "E795: Nie mogê usun±æ zmiennej %s"
+
+#, c-format
+msgid "E704: Funcref variable name must start with a capital: %s"
+msgstr "E704: Nazwa Funcref musi siê zaczynaæ wielk± liter±: %s"
+
+#, c-format
+msgid "E705: Variable name conflicts with existing function: %s"
+msgstr "E705: Nazwa zmiennej jest w konflikcie z istniej±c± funkcj±: %s"
+
+#, c-format
+msgid "E741: Value is locked: %s"
+msgstr "E741: Warto¶æ jest zablokowana: %s"
+
+msgid "Unknown"
+msgstr "Nieznane"
+
+#, c-format
+msgid "E742: Cannot change value of %s"
+msgstr "E742: Nie mogê zmieniæ warto¶ci %s"
+
+msgid "E698: variable nested too deep for making a copy"
+msgstr "E698: Zmienna zagnie¿d¿ona zbyt g³êboko by zrobiæ kopiê"
+
+#, c-format
+msgid "E123: Undefined function: %s"
+msgstr "E123: Nieznana funkcja: %s"
+
+#, c-format
+msgid "E124: Missing '(': %s"
+msgstr "E124: Brak '(': %s"
+
+msgid "E862: Cannot use g: here"
+msgstr "E862: Nie mo¿na tutaj u¿yæ g:"
+
+#, c-format
+msgid "E125: Illegal argument: %s"
+msgstr "E125: Niedozwolony argument: %s"
+
+#, c-format
+msgid "E853: Duplicate argument name: %s"
+msgstr "E853: Powtórzona nazwa argumentu: %s"
+
+msgid "E126: Missing :endfunction"
+msgstr "E126: Brak :endfunction"
+
+#, c-format
+msgid "E707: Function name conflicts with variable: %s"
+msgstr "E707: Nazwa funkcji jest w konflikcie ze zmienn±: %s"
+
+#, c-format
+msgid "E127: Cannot redefine function %s: It is in use"
+msgstr "E127: Nie mogê redefiniowaæ funkcji %s: jest w u¿yciu"
+
+#, c-format
+msgid "E746: Function name does not match script file name: %s"
+msgstr "E746: Nazwa funkcji nie pasuje do nazwy skryptu: %s"
+
+msgid "E129: Function name required"
+msgstr "E129: Wymagana jest nazwa funkcji"
+
+#, c-format
+msgid "E128: Function name must start with a capital or contain a colon: %s"
+msgstr ""
+"E128: Nazwa funkcji musi rozpoczynaæ siê wielk± liter± lub zawieraæ "
+"dwukropek: %s"
+
+#, c-format
+msgid "E131: Cannot delete function %s: It is in use"
+msgstr "E131: Nie mogê skasowaæ funkcji %s: jest w u¿yciu"
+
+msgid "E132: Function call depth is higher than 'maxfuncdepth'"
+msgstr "E132: Zagnie¿d¿enie wywo³añ funkcji ponad 'maxfuncdepth'"
+
+#, c-format
+msgid "calling %s"
+msgstr "wywo³ujê %s"
+
+#, c-format
+msgid "%s aborted"
+msgstr "porzucono %s"
+
+#, c-format
+msgid "%s returning #%ld"
+msgstr "%s zwraca #%ld"
+
+#, c-format
+msgid "%s returning %s"
+msgstr "%s zwraca %s"
+
+#, c-format
+msgid "continuing in %s"
+msgstr "kontynuacja w %s"
+
+msgid "E133: :return not inside a function"
+msgstr "E133: :return poza funkcj±"
+
+msgid ""
+"\n"
+"# global variables:\n"
+msgstr ""
+"\n"
+"# zmienne globalne:\n"
+
+msgid ""
+"\n"
+"\tLast set from "
+msgstr ""
+"\n"
+"\tOstatnie ustawienie przez "
+
+msgid "No old files"
+msgstr "Brak starych plików"
+
+msgid "Entering Debug mode. Type \"cont\" to continue."
+msgstr "Wchodzê w tryb odpluskwiania. Wprowad¼ \"cont\" aby kontynuowaæ."
+
+#, c-format
+msgid "line %ld: %s"
+msgstr "wiersz %ld: %s"
+
+#, c-format
+msgid "cmd: %s"
+msgstr "cmd: %s"
+
+#, c-format
+msgid "Breakpoint in \"%s%s\" line %ld"
+msgstr "Punkt kontrolny w \"%s%s\" wiersz %ld"
+
+#, c-format
+msgid "E161: Breakpoint not found: %s"
+msgstr "E161: Nie znaleziono punktu kontrolnego: %s"
+
+msgid "No breakpoints defined"
+msgstr "Nie okre¶lono ¿adnych punktów kontrolnych"
+
+#, c-format
+msgid "%3d %s %s line %ld"
+msgstr "%3d %s %s wiersz %ld"
+
+msgid "E750: First use \":profile start {fname}\""
+msgstr "E750: Pierwsze u¿ycie \":profile start {fname}\""
+
+msgid "Save As"
+msgstr "Zapisz jako"
+
+#, c-format
+msgid "Save changes to \"%s\"?"
+msgstr "Zachowaæ zmiany w \"%s\"?"
+
+msgid "Untitled"
+msgstr "Bez Tytu³u"
+
+#, c-format
+msgid "E162: No write since last change for buffer \"%s\""
+msgstr "E162: Nie zapisano zmian w buforze \"%s\""
+
+msgid "Warning: Entered other buffer unexpectedly (check autocommands)"
+msgstr "OSTRZE¯ENIE: Nieoczekiwane wej¶cie w inny bufor (sprawd¼ autokomendy)"
+
+msgid "E163: There is only one file to edit"
+msgstr "E163: Tylko jeden plik w edycji"
+
+msgid "E164: Cannot go before first file"
+msgstr "E164: Nie mo¿na przej¶æ przed pierwszy plik"
+
+msgid "E165: Cannot go beyond last file"
+msgstr "E165: Nie mo¿na przej¶æ za ostatni plik"
+
+#, c-format
+msgid "E666: compiler not supported: %s"
+msgstr "E666: nie wspierany kompilator: %s"
+
+#, c-format
+msgid "Searching for \"%s\" in \"%s\""
+msgstr "Szukanie \"%s\" w \"%s\""
+
+#, c-format
+msgid "Searching for \"%s\""
+msgstr "Szukanie \"%s\""
+
+#, c-format
+msgid "not found in 'runtimepath': \"%s\""
+msgstr "nie znaleziono w 'runtimepath': \"%s\""
+
+msgid "Source Vim script"
+msgstr "Wczytaj skrypt Vima"
+
+#, c-format
+msgid "Cannot source a directory: \"%s\""
+msgstr "Nie mo¿na wczytaæ katalogu: \"%s\""
+
+#, c-format
+msgid "could not source \"%s\""
+msgstr "nie mog³em wczytaæ \"%s\""
+
+#, c-format
+msgid "line %ld: could not source \"%s\""
+msgstr "wiersz: %ld nie mog³em wczytaæ \"%s\""
+
+#, c-format
+msgid "sourcing \"%s\""
+msgstr "wczytywanie \"%s\""
+
+#, c-format
+msgid "line %ld: sourcing \"%s\""
+msgstr "wiersz %ld: wczytywanie \"%s\""
+
+#, c-format
+msgid "finished sourcing %s"
+msgstr "skoñczono wczytywanie %s"
+
+msgid "modeline"
+msgstr "modeline"
+
+msgid "--cmd argument"
+msgstr "--cmd argument"
+
+msgid "-c argument"
+msgstr "-c argument"
+
+msgid "environment variable"
+msgstr "zmienna ¶rodowiskowa"
+
+msgid "error handler"
+msgstr "obs³uga b³êdu"
+
+msgid "W15: Warning: Wrong line separator, ^M may be missing"
+msgstr "W15: OSTRZE¯ENIE: Niew³a¶ciwy separator wierszy, pewnie brak ^M"
+
+msgid "E167: :scriptencoding used outside of a sourced file"
+msgstr "E167: u¿yto :scriptencoding poza wczytywanym plikiem"
+
+msgid "E168: :finish used outside of a sourced file"
+msgstr "E168: u¿yto :finish poza wczytywanym plikiem"
+
+#, c-format
+msgid "Current %slanguage: \"%s\""
+msgstr "Bie¿±cy %sjêzyk: \"%s\""
+
+#, c-format
+msgid "E197: Cannot set language to \"%s\""
+msgstr "E197: Nie mogê ustawiæ jêzyka na \"%s\""
+
+#, c-format
+msgid "<%s>%s%s %d, Hex %02x, Octal %03o"
+msgstr "<%s>%s%s %d, Hex %02x, Oktal %03o"
+
+#, c-format
+msgid "> %d, Hex %04x, Octal %o"
+msgstr "> %d, Hex %04x, Oktal %o"
+
+#, c-format
+msgid "> %d, Hex %08x, Octal %o"
+msgstr "> %d, Hex %08x, Oktal %o"
+
+msgid "E134: Move lines into themselves"
+msgstr "E134: Przeniesienie wierszy na siebie samych"
+
+msgid "1 line moved"
+msgstr "1 wiersz przeniesiony"
+
+#, c-format
+msgid "%ld lines moved"
+msgstr "%ld wiersze przeniesione"
+
+#, c-format
+msgid "%ld lines filtered"
+msgstr "%ld wierszy przefiltrowanych"
+
+msgid "E135: *Filter* Autocommands must not change current buffer"
+msgstr "E135: Autokomendy *Filter* nie mog± zmieniaæ bie¿±cego bufora"
+
+msgid "[No write since last change]\n"
+msgstr "[Brak zapisu od czasu ostatniej zmiany]\n"
+
+#, c-format
+msgid "%sviminfo: %s in line: "
+msgstr "%sviminfo: %s w wierszu: "
+
+msgid "E136: viminfo: Too many errors, skipping rest of file"
+msgstr "E136: viminfo: Zbyt wiele b³êdów; pomijam resztê pliku"
+
+#, c-format
+msgid "Reading viminfo file \"%s\"%s%s%s"
+msgstr "Wczytujê plik viminfo \"%s\"%s%s%s"
+
+msgid " info"
+msgstr " informacja"
+
+msgid " marks"
+msgstr " zak³adki"
+
+msgid " oldfiles"
+msgstr " stare pliki"
+
+msgid " FAILED"
+msgstr " NIE POWIOD£O SIÊ"
+
+#. avoid a wait_return for this message, it's annoying
+#, c-format
+msgid "E137: Viminfo file is not writable: %s"
+msgstr "E137: Plik viminfo jest niezapisywalny: %s"
+
+#, c-format
+msgid "E138: Can't write viminfo file %s!"
+msgstr "E138: Nie mogê zapisaæ pliku viminfo %s!"
+
+#, c-format
+msgid "Writing viminfo file \"%s\""
+msgstr "Zapisujê plik viminfo \"%s\""
+
+#. Write the info:
+#, c-format
+msgid "# This viminfo file was generated by Vim %s.\n"
+msgstr "# Ten plik viminfo zosta³ wygenerowany przez Vima %s.\n"
+
+msgid ""
+"# You may edit it if you're careful!\n"
+"\n"
+msgstr ""
+"# Mo¿esz go ostro¿nie edytowaæ!\n"
+"\n"
+
+msgid "# Value of 'encoding' when this file was written\n"
+msgstr "# Warto¶æ 'encoding' w czasie zapisu tego pliku\n"
+
+msgid "Illegal starting char"
+msgstr "Niedopuszczalny pocz±tkowy znak"
+
+msgid "Write partial file?"
+msgstr "Zapisaæ czê¶ciowo plik?"
+
+msgid "E140: Use ! to write partial buffer"
+msgstr "E140: Stosuj ! do zapisania czê¶ciowo bufora"
+
+#, c-format
+msgid "Overwrite existing file \"%s\"?"
+msgstr "Nadpisaæ istniej±cy plik \"%s\"?"
+
+#, c-format
+msgid "Swap file \"%s\" exists, overwrite anyway?"
+msgstr "Plik wymiany \"%s\" istnieje, czy go nadpisaæ?"
+
+#, c-format
+msgid "E768: Swap file exists: %s (:silent! overrides)"
+msgstr "E768: Plik wymiany istnieje: %s (wymu¶ poprzez :silent!)"
+
+#, c-format
+msgid "E141: No file name for buffer %ld"
+msgstr "E141: Brak nazwy pliku dla bufora %ld"
+
+msgid "E142: File not written: Writing is disabled by 'write' option"
+msgstr "E142: Plik niezapisany: Zapis jest wy³±czony opcj± 'write'"
+
+#, 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æ?"
+
+#, 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æ?"
+
+#, c-format
+msgid "E505: \"%s\" is read-only (add ! to override)"
+msgstr "E505: \"%s\" jest tylko do odczytu (dodaj ! aby wymusiæ)"
+
+msgid "Edit File"
+msgstr "Edytuj Plik"
+
+#, c-format
+msgid "E143: Autocommands unexpectedly deleted new buffer %s"
+msgstr "E143: Autokomendy nieoczekiwanie skasowa³y nowy bufor %s"
+
+msgid "E144: non-numeric argument to :z"
+msgstr "E144: nienumeryczny argument dla :z"
+
+msgid "E145: Shell commands not allowed in rvim"
+msgstr "E145: Komendy pow³oki s± niedozwolone w rvim"
+
+msgid "E146: Regular expressions can't be delimited by letters"
+msgstr "E146: Wzorce regularne nie mog± byæ rozgraniczane literami"
+
+#, c-format
+msgid "replace with %s (y/n/a/q/l/^E/^Y)?"
+msgstr "zamieñ na %s (y/n/a/q/l/^E/^Y)?"
+
+msgid "(Interrupted) "
+msgstr "(Przerwane) "
+
+msgid "1 match"
+msgstr "1 pasuje"
+
+msgid "1 substitution"
+msgstr "1 podstawienie "
+
+#, c-format
+msgid "%ld matches"
+msgstr "%ld dopasowañ"
+
+#, c-format
+msgid "%ld substitutions"
+msgstr "%ld podstawieñ"
+
+msgid " on 1 line"
+msgstr " w 1 wierszu"
+
+#, c-format
+msgid " on %ld lines"
+msgstr " w %ld wierszach"
+
+msgid "E147: Cannot do :global recursive"
+msgstr "E147: Nie mogê wykonaæ :global rekursywnie"
+
+msgid "E148: Regular expression missing from global"
+msgstr "E148: Brak wzorca regularnego w :global"
+
+# c-format
+#, c-format
+msgid "Pattern found in every line: %s"
+msgstr "Wzorzec znaleziono w ka¿dym wierszu: %s"
+
+#, c-format
+msgid "Pattern not found: %s"
+msgstr "Nie znaleziono wzorca: %s"
+
+msgid ""
+"\n"
+"# Last Substitute String:\n"
+"$"
+msgstr ""
+"\n"
+"# Ostatni podstawiany ci±g:\n"
+"$"
+
+msgid "E478: Don't panic!"
+msgstr "E478: Nie panikuj!"
+
+#, c-format
+msgid "E661: Sorry, no '%s' help for %s"
+msgstr "E661: Przykro mi, brak '%s' pomocy dla %s"
+
+#, c-format
+msgid "E149: Sorry, no help for %s"
+msgstr "E149: Przykro mi, ale brak pomocy o %s"
+
+#, c-format
+msgid "Sorry, help file \"%s\" not found"
+msgstr "Przykro mi, nie ma pliku pomocy \"%s\""
+
+#, c-format
+msgid "E150: Not a directory: %s"
+msgstr "E150: Nie jest katalogiem: %s"
+
+#, c-format
+msgid "E152: Cannot open %s for writing"
+msgstr "E152: Nie mogê otworzyæ %s do zapisu"
+
+#, c-format
+msgid "E153: Unable to open %s for reading"
+msgstr "E153: Nie mogê otworzyæ %s do odczytu"
+
+#, 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"
+
+#, c-format
+msgid "E154: Duplicate tag \"%s\" in file %s/%s"
+msgstr "E154: Powtórzony znacznik \"%s\" w pliku %s/%s"
+
+#, c-format
+msgid "E160: Unknown sign command: %s"
+msgstr "E160: Nieznana komenda znaku: %s"
+
+msgid "E156: Missing sign name"
+msgstr "E156: Brak nazwy znaku"
+
+msgid "E612: Too many signs defined"
+msgstr "E612: Zbyt wiele nazw znaków"
+
+#, c-format
+msgid "E239: Invalid sign text: %s"
+msgstr "E239: Niew³a¶ciwy tekst znaku: %s"
+
+#, c-format
+msgid "E155: Unknown sign: %s"
+msgstr "E155: Nieznany znak: %s"
+
+msgid "E159: Missing sign number"
+msgstr "E159: Brak numeru znaku"
+
+#, c-format
+msgid "E158: Invalid buffer name: %s"
+msgstr "E158: Niew³a¶ciwa nazwa bufora: %s"
+
+#, c-format
+msgid "E157: Invalid sign ID: %ld"
+msgstr "E157: Niew³a¶ciwe ID znaku: %ld"
+
+msgid " (NOT FOUND)"
+msgstr " (NIE ZNALEZIONO)"
+
+msgid " (not supported)"
+msgstr "(nie wspomagane)"
+
+msgid "[Deleted]"
+msgstr "[Skasowano]"
+
+msgid "Entering Ex mode. Type \"visual\" to go to Normal mode."
+msgstr "Wchodzê w tryb Ex. Wprowad¼ \"visual\" aby przej¶æ do trybu Normal."
+
+msgid "E501: At end-of-file"
+msgstr "E501: Na koñcu pliku"
+
+msgid "E169: Command too recursive"
+msgstr "E169: Komenda zbyt rekursywna"
+
+#, c-format
+msgid "E605: Exception not caught: %s"
+msgstr "E605: Nie znaleziono wyj±tku: %s"
+
+msgid "End of sourced file"
+msgstr "Koniec wczytywanego pliku"
+
+msgid "End of function"
+msgstr "Koniec funkcji"
+
+msgid "E464: Ambiguous use of user-defined command"
+msgstr ""
+"E464: Niejednoznaczne zastosowanie komendy zdefiniowanej przez u¿ytkownika"
+
+msgid "E492: Not an editor command"
+msgstr "E492: Nie jest komend± edytora"
+
+msgid "E493: Backwards range given"
+msgstr "E493: Dano wsteczny zakres"
+
+msgid "Backwards range given, OK to swap"
+msgstr "Dano wsteczny zakres; zamiana jest mo¿liwa"
+
+msgid "E494: Use w or w>>"
+msgstr "E494: Stosuj w lub w>>"
+
+msgid "E319: Sorry, the command is not available in this version"
+msgstr "E319: Przykro mi, ale ta komenda nie jest dostêpna w tej wersji"
+
+msgid "E172: Only one file name allowed"
+msgstr "E172: Tylko pojedyncza nazwa pliku dozwolona"
+
+msgid "1 more file to edit. Quit anyway?"
+msgstr "1 wiêcej plik do edycji. Mimo to wyj¶æ?"
+
+#, c-format
+msgid "%d more files to edit. Quit anyway?"
+msgstr "jeszcze %d plików do edycji. Mimo to wyj¶æ?"
+
+msgid "E173: 1 more file to edit"
+msgstr "E173: 1 wiêcej plik do edycji"
+
+#, c-format
+msgid "E173: %ld more files to edit"
+msgstr "E173: jeszcze %ld plików do edycji"
+
+msgid "E174: Command already exists: add ! to replace it"
+msgstr "E174: Komenda ju¿ istnieje; aby j± przedefiniowaæ stosuj !"
+
+msgid ""
+"\n"
+" Name Args Range Complete Definition"
+msgstr ""
+"\n"
+" Nazwa Arg. Zak. Gotowo¶æ Definicja"
+
+msgid "No user-defined commands found"
+msgstr "Nie znaleziono komend zdefiniowanych przez u¿ytkownika"
+
+msgid "E175: No attribute specified"
+msgstr "E175: Nie okre¶lono atrybutu"
+
+msgid "E176: Invalid number of arguments"
+msgstr "E176: Niew³a¶ciwa ilo¶æ argumentów"
+
+msgid "E177: Count cannot be specified twice"
+msgstr "E177: Mno¿nik nie mo¿e byæ podany dwukrotnie"
+
+msgid "E178: Invalid default value for count"
+msgstr "E178: Niew³a¶ciwa domy¶lna warto¶æ mno¿nika"
+
+msgid "E179: argument required for -complete"
+msgstr "E179: -complete wymaga argumentu"
+
+#, c-format
+msgid "E181: Invalid attribute: %s"
+msgstr "E181: Niew³a¶ciwy atrybut: %s"
+
+msgid "E182: Invalid command name"
+msgstr "E182: Niew³a¶ciwa nazwa komendy"
+
+msgid "E183: User defined commands must start with an uppercase letter"
+msgstr ""
+"E183: Komendy zdefiniowane przez u¿ytkownika musz± rozpoczynaæ siê du¿± "
+"liter±"
+
+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"
+
+#, c-format
+msgid "E184: No such user-defined command: %s"
+msgstr "E184: Nie ma takiej komendy u¿ytkownika: %s"
+
+#, c-format
+msgid "E180: Invalid complete value: %s"
+msgstr "E180: Niew³a¶ciwa warto¶æ dope³niania: %s"
+
+msgid "E468: Completion argument only allowed for custom completion"
+msgstr ""
+"E468: Argument depe³niania dozwolony wy³±cznie dla dope³niania u¿ytkownika"
+
+msgid "E467: Custom completion requires a function argument"
+msgstr "E467: Dope³nianie u¿ytkownika wymaga funkcji jako argumentu"
+
+msgid "unknown"
+msgstr "nieznany"
+
+#, c-format
+msgid "E185: Cannot find color scheme '%s'"
+msgstr "E185: Nie mogê znale¼æ zestawu kolorów '%s'"
+
+msgid "Greetings, Vim user!"
+msgstr "Witaj u¿ytkowniku Vima!"
+
+msgid "E784: Cannot close last tab page"
+msgstr "E784: Nie mogê zamkn±æ ostatniej karty"
+
+msgid "Already only one tab page"
+msgstr "Jest ju¿ tylko jedna karta"
+
+msgid "Edit File in new window"
+msgstr "Edytuj plik w nowym oknie"
+
+#, c-format
+msgid "Tab page %d"
+msgstr "Karta %d"
+
+msgid "No swap file"
+msgstr "Brak pliku wymiany"
+
+msgid "Append File"
+msgstr "Do³±cz plik"
+
+msgid "E747: Cannot change directory, buffer is modified (add ! to override)"
+msgstr ""
+"E747: Nie mogê zmieniæ katalogu, bufor zosta³ zmodyfikowany (dodaj ! aby "
+"wymusiæ)"
+
+msgid "E186: No previous directory"
+msgstr "E186: Nie ma poprzedniego katalogu"
+
+msgid "E187: Unknown"
+msgstr "E187: Nieznany"
+
+msgid "E465: :winsize requires two number arguments"
+msgstr "E465: :winsize wymaga dwóch argumentów numerycznych"
+
+#, c-format
+msgid "Window position: X %d, Y %d"
+msgstr "Pozycja okna: X %d, Y %d"
+
+msgid "E188: Obtaining window position not implemented for this platform"
+msgstr ""
+"E188: Pozyskiwanie pozycji okna nie jest zaimplementowane dla tego systemu"
+
+msgid "E466: :winpos requires two number arguments"
+msgstr "E466: :winpos wymaga dwóch argumentów numerycznych"
+
+msgid "Save Redirection"
+msgstr "Zapisz przekierowanie"
+
+msgid "Save View"
+msgstr "Zapisz widok"
+
+msgid "Save Session"
+msgstr "Zapisz sesjê"
+
+msgid "Save Setup"
+msgstr "Zapisz ustawienia"
+
+#, c-format
+msgid "E739: Cannot create directory: %s"
+msgstr "E739: Nie mogê utworzyæ katalogu: %s"
+
+#, c-format
+msgid "E189: \"%s\" exists (add ! to override)"
+msgstr "E189: \"%s\" istnieje (wymu¶ poprzez !)"
+
+#, c-format
+msgid "E190: Cannot open \"%s\" for writing"
+msgstr "E190: Nie mogê otworzyæ \"%s\" do zapisu"
+
+#. set mark
+msgid "E191: Argument must be a letter or forward/backward quote"
+msgstr "E191: Argument musi byæ liter± albo cudzys³owem w przód/ty³"
+
+msgid "E192: Recursive use of :normal too deep"
+msgstr "E192: Rekursywne zastosowanie :normal za g³êbokie"
+
+msgid "E809: #< is not available without the +eval feature"
+msgstr "E809: #< nie jest dostêpne bez w³a¶ciwo¶ci +eval"
+
+msgid "E194: No alternate file name to substitute for '#'"
+msgstr "E194: Brak nazwy zamiennego pliku do podstawienia pod '#'"
+
+msgid "E495: no autocommand file name to substitute for \"<afile>\""
+msgstr "E495: brak nazwy pliku autokomend do podstawienia pod \"<afile>\""
+
+msgid "E496: no autocommand buffer number to substitute for \"<abuf>\""
+msgstr "E496: brak numeru bufora autokomend do podstawienia pod \"<abuf>\""
+
+msgid "E497: no autocommand match name to substitute for \"<amatch>\""
+msgstr "E497: brak nazwy dopasowania autokomend pod \"<amatch>\""
+
+msgid "E498: no :source file name to substitute for \"<sfile>\""
+msgstr "E498: brak nazwy pliku :source do postawienia pod \"<sfile>\""
+
+msgid "E842: no line number to use for \"<slnum>\""
+msgstr "E842: brak numeru linii by u¿yæ z \"<slnum>\""
+
+#, no-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\""
+
+msgid "E500: Evaluates to an empty string"
+msgstr "E500: Wynikiem jest pusty ci±g"
+
+msgid "E195: Cannot open viminfo file for reading"
+msgstr "E195: Nie mogê otworzyæ pliku viminfo do odczytu"
+
+msgid "E196: No digraphs in this version"
+msgstr "E196: Brak dwugrafów w tej wersji"
+
+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
+#, c-format
+msgid "Exception thrown: %s"
+msgstr "Wyj±tek: %s"
+
+#, c-format
+msgid "Exception finished: %s"
+msgstr "Wyj±tek zakoñczony: %s"
+
+#, c-format
+msgid "Exception discarded: %s"
+msgstr "Wyj±tek odrzucony: %s"
+
+#, c-format
+msgid "%s, line %ld"
+msgstr "%s, wiersz %ld"
+
+#. always scroll up, don't overwrite
+#, c-format
+msgid "Exception caught: %s"
+msgstr "Wyj±tek przechwycony: %s"
+
+#, c-format
+msgid "%s made pending"
+msgstr "%s zosta³ zawieszony"
+
+#, c-format
+msgid "%s resumed"
+msgstr "%s przywrócony"
+
+#, c-format
+msgid "%s discarded"
+msgstr "%s odrzucony"
+
+msgid "Exception"
+msgstr "Wyj±tek"
+
+msgid "Error and interrupt"
+msgstr "B³±d i przerwanie"
+
+msgid "Error"
+msgstr "B³±d"
+
+#. if (pending & CSTP_INTERRUPT)
+msgid "Interrupt"
+msgstr "Przerwanie"
+
+msgid "E579: :if nesting too deep"
+msgstr "E579: zbyt g³êbokie zagnie¿d¿enie :if"
+
+msgid "E580: :endif without :if"
+msgstr "E580: :endif bez :if"
+
+msgid "E581: :else without :if"
+msgstr "E581: :else bez :if"
+
+msgid "E582: :elseif without :if"
+msgstr "E582: :elseif bez :if"
+
+msgid "E583: multiple :else"
+msgstr "E583: wielokrotne :else"
+
+msgid "E584: :elseif after :else"
+msgstr "E584: :elseif po :else"
+
+msgid "E585: :while/:for nesting too deep"
+msgstr "E585: zbyt g³êbokie zagnie¿d¿enie :while/:for"
+
+msgid "E586: :continue without :while or :for"
+msgstr "E586: :continue bez :while lub :for"
+
+msgid "E587: :break without :while or :for"
+msgstr "E587: :break bez :while lub :for"
+
+msgid "E732: Using :endfor with :while"
+msgstr "E732: U¿ycie :endfor z :while"
+
+msgid "E733: Using :endwhile with :for"
+msgstr "E733: U¿ycie :endwhile z :for"
+
+msgid "E601: :try nesting too deep"
+msgstr "E601: zbyt g³êbokie zagnie¿d¿enie :try"
+
+msgid "E603: :catch without :try"
+msgstr "E603: :catch bez :try"
+
+#. Give up for a ":catch" after ":finally" and ignore it.
+#. * Just parse.
+msgid "E604: :catch after :finally"
+msgstr "E604: :catch za :finally"
+
+msgid "E606: :finally without :try"
+msgstr "E606: :finally bez :try"
+
+#. Give up for a multiple ":finally" and ignore it.
+msgid "E607: multiple :finally"
+msgstr "E607: wielokrotne :finally"
+
+msgid "E602: :endtry without :try"
+msgstr "E602: :endtry bez :try"
+
+msgid "E193: :endfunction not inside a function"
+msgstr "E193: :endfunction poza funkcj±"
+
+msgid "E788: Not allowed to edit another buffer now"
+msgstr "E788: Nie mo¿na teraz edytowaæ innego bufora"
+
+msgid "E811: Not allowed to change buffer information now"
+msgstr "E811: Nie mo¿na teraz zmieniaæ informacji o buforze"
+
+msgid "tagname"
+msgstr "nazwa znacznika"
+
+msgid " kind file\n"
+msgstr " pokrewny plik\n"
+
+msgid "'history' option is zero"
+msgstr "opcja 'history' jest zerowa"
+
+#, c-format
+msgid ""
+"\n"
+"# %s History (newest to oldest):\n"
+msgstr ""
+"\n"
+"# %s Historia (od najnowszych po najstarsze):\n"
+
+msgid "Command Line"
+msgstr "Wiersz poleceñ"
+
+msgid "Search String"
+msgstr "Szukany ci±g"
+
+msgid "Expression"
+msgstr "Wyra¿enie"
+
+msgid "Input Line"
+msgstr "Wiersz wprowadzeñ"
+
+msgid "E198: cmd_pchar beyond the command length"
+msgstr "E198: cmd_pchar przekracza d³ugo¶æ polecenia"
+
+msgid "E199: Active window or buffer deleted"
+msgstr "E199: Aktywny widok lub bufor skasowany"
+
+msgid "E812: Autocommands changed buffer or buffer name"
+msgstr "E812: Autokomendy zmieni³y bufor lub jego nazwê"
+
+msgid "Illegal file name"
+msgstr "Niedopuszczalna nazwa pliku"
+
+msgid "is a directory"
+msgstr "jest katalogiem"
+
+msgid "is not a file"
+msgstr "nie jest plikiem"
+
+msgid "is a device (disabled with 'opendevice' option)"
+msgstr "jest urz±dzeniem (wy³±czonym w opcji 'opendevice')"
+
+msgid "[New File]"
+msgstr "[Nowy Plik]"
+
+msgid "[New DIRECTORY]"
+msgstr "[Nowy KATALOG]"
+
+msgid "[File too big]"
+msgstr "[Za du¿y plik]"
+
+msgid "[Permission Denied]"
+msgstr "[Nie dozwolono]"
+
+msgid "E200: *ReadPre autocommands made the file unreadable"
+msgstr "E200: Autokomendy *ReadPre zrobi³y plik nieodczytywalnym"
+
+msgid "E201: *ReadPre autocommands must not change current buffer"
+msgstr "E201: Autokomendy *ReadPre nie mog± zmieniaæ bie¿±cego bufora"
+
+msgid "Vim: Reading from stdin...\n"
+msgstr "Vim: Wczytywanie ze stdin...\n"
+
+msgid "Reading from stdin..."
+msgstr "Wczytywanie ze stdin..."
+
+#. Re-opening the original file failed!
+msgid "E202: Conversion made file unreadable!"
+msgstr "E202: Nie mo¿na otworzyæ pliku utworzonego przez przemianê!"
+
+msgid "[fifo/socket]"
+msgstr "[fifo/socket]"
+
+msgid "[fifo]"
+msgstr "[fifo]"
+
+msgid "[socket]"
+msgstr "[socket]"
+
+msgid "[character special]"
+msgstr "[specjalny znak]"
+
+msgid "[CR missing]"
+msgstr "[brak CR]'"
+
+msgid "[long lines split]"
+msgstr "[d³ugie wiersze rozdzielane]"
+
+msgid "[NOT converted]"
+msgstr "[NIE przemienione]"
+
+msgid "[converted]"
+msgstr "[przemienione]"
+
+msgid "[blowfish]"
+msgstr "[blowfish]"
+
+msgid "[crypted]"
+msgstr "[zakodowane]"
+
+#, c-format
+msgid "[CONVERSION ERROR in line %ld]"
+msgstr "[B£¡D W PRZEMIANIE w linii %ld]"
+
+#, c-format
+msgid "[ILLEGAL BYTE in line %ld]"
+msgstr "[NIEDOZWOLONY BAJT w wierszu %ld]"
+
+msgid "[READ ERRORS]"
+msgstr "[B£ÊDY W ODCZYCIE]"
+
+msgid "Can't find temp file for conversion"
+msgstr "Nie mogê znale¼æ pliku tymczasowego w celu przemiany"
+
+msgid "Conversion with 'charconvert' failed"
+msgstr "Nieudana przemiana z 'charconvert'"
+
+msgid "can't read output of 'charconvert'"
+msgstr "nie mogê odczytaæ wyj¶cia z 'charconvert'"
+
+msgid "E821: File is encrypted with unknown method"
+msgstr "E821: Plik zaszyfrowano w nieznany sposób"
+
+msgid "E676: No matching autocommands for acwrite buffer"
+msgstr "E676: Brak pasuj±cych autokomend dla bufora acwrite"
+
+msgid "E203: Autocommands deleted or unloaded buffer to be written"
+msgstr ""
+"E203: Autokomendy skasowa³y lub wy³adowa³y bufor przeznaczony do zapisu"
+
+msgid "E204: Autocommand changed number of lines in unexpected way"
+msgstr "E204: Autokomenda zmieni³a liczbê wierszy w nieoczekiwany 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 "is not a file or writable device"
+msgstr "nie jest plikiem lub zapisywalnym przyrz±dem"
+
+msgid "writing to device disabled with 'opendevice' option"
+msgstr "zapisywanie do urz±dzenia wy³±czone w opcji 'opendevice'"
+
+msgid "is read-only (add ! to override)"
+msgstr "jest tylko do odczytu (wymu¶ poprzez !)"
+
+msgid "E506: Can't write to backup file (add ! to override)"
+msgstr "E506: Nie mogê zapisaæ do pliku zabezpieczenia (wymu¶ przez !)"
+
+msgid "E507: Close error for backup file (add ! to override)"
+msgstr "E507: B³±d podczas zamykania pliku zabezpieczenia (wymu¶ przez !)"
+
+msgid "E508: Can't read file for backup (add ! to override)"
+msgstr "E508: Nie mogê odczytaæ pliku w celu zabezpieczenia (wymu¶ przez !)"
+
+msgid "E509: Cannot create backup file (add ! to override)"
+msgstr "E509: Nie mogê stworzyæ pliku zabezpieczenia (wymu¶ przez !)"
+
+msgid "E510: Can't make backup file (add ! to override)"
+msgstr "E510: Nie mogê zrobiæ pliku zabezpieczenia (wymu¶ przez !)"
+
+msgid "E460: The resource fork would be lost (add ! to override)"
+msgstr "E460: Rozdzia³ zasobów zostanie utracony (wymu¶ przez !)"
+
+msgid "E214: Can't find temp file for writing"
+msgstr "E214: Nie mogê znale¼æ pliku tymczasowego do zapisania"
+
+msgid "E213: Cannot convert (add ! to write without conversion)"
+msgstr "E213: Nie mogê przemieniæ (u¿yj ! by zapisaæ bez przemiany)"
+
+msgid "E166: Can't open linked file for writing"
+msgstr "E166: Nie mogê otworzyæ pod³±czonego pliku do zapisu"
+
+msgid "E212: Can't open file for writing"
+msgstr "E212: Nie mogê otworzyæ pliku do zapisu"
+
+msgid "E667: Fsync failed"
+msgstr "E667: Fsync nie powiód³ siê"
+
+msgid "E512: Close failed"
+msgstr "E512: Zamkniêcie siê nie powiod³o"
+
+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æ)"
+
+#, c-format
+msgid ""
+"E513: write error, conversion failed in line %ld (make 'fenc' empty to "
+"override)"
+msgstr ""
+"E513: B³±d zapisu, przemiana siê nie powiod³a w wierszu %ld (opró¿nij 'fenc' "
+"by wymusiæ)"
+
+msgid "E514: write error (file system full?)"
+msgstr "E514: b³±d w zapisie (mo¿e system plików jest przepe³niony?)"
+
+msgid " CONVERSION ERROR"
+msgstr " B£¡D W PRZEMIANIE"
+
+#, c-format
+msgid " in line %ld;"
+msgstr " w wierszu %ld;"
+
+msgid "[Device]"
+msgstr "[Urz±dzenie]"
+
+msgid "[New]"
+msgstr "[Nowy]"
+
+msgid " [a]"
+msgstr " [a]"
+
+msgid " appended"
+msgstr " do³±czono"
+
+msgid " [w]"
+msgstr " [w]"
+
+msgid " written"
+msgstr " zapisano"
+
+msgid "E205: Patchmode: can't save original file"
+msgstr "E205: Patchmode: nie mogê zapisaæ oryginalnego pliku"
+
+msgid "E206: patchmode: can't touch empty original file"
+msgstr "E206: patchmode: nie mogê stworzyæ pustego oryginalnego pliku"
+
+msgid "E207: Can't delete backup file"
+msgstr "E207: Nie mogê skasowaæ pliku zabezpieczenia"
+
+msgid ""
+"\n"
+"WARNING: Original file may be lost or damaged\n"
+msgstr ""
+"\n"
+"OSTRZE¯ENIE: Oryginalny plik mo¿e zostaæ utracony lub uszkodzony\n"
+
+msgid "don't quit the editor until the file is successfully written!"
+msgstr "nie wychod¼ edytora, dopóki plik nie zosta³ poprawnie zapisany!"
+
+msgid "[dos]"
+msgstr "[dos]"
+
+msgid "[dos format]"
+msgstr "[format dos-a]"
+
+msgid "[mac]"
+msgstr "[mac]"
+
+msgid "[mac format]"
+msgstr "[format maca]"
+
+msgid "[unix]"
+msgstr "[unix]"
+
+msgid "[unix format]"
+msgstr "[format unixa]"
+
+msgid "1 line, "
+msgstr "1 wiersz, "
+
+#, c-format
+msgid "%ld lines, "
+msgstr "%ld wierszy, "
+
+msgid "1 character"
+msgstr "1 znak"
+
+#, c-format
+msgid "%lld characters"
+msgstr "%lld znaków"
+
+#. Explicit typecast avoids warning on Mac OS X 10.6
+#, c-format
+msgid "%ld characters"
+msgstr "%ld znaków"
+
+msgid "[noeol]"
+msgstr "[noeol]"
+
+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
+msgid "WARNING: The file has been changed since reading it!!!"
+msgstr "OSTRZE¯ENIE: Plik zmieni³ siê od czasu ostatniego odczytu!!!"
+
+msgid "Do you really want to write to it"
+msgstr "Czy naprawdê chcesz go zapisaæ"
+
+#, c-format
+msgid "E208: Error writing to \"%s\""
+msgstr "E208: B³±d zapisywania do \"%s\""
+
+#, c-format
+msgid "E209: Error closing \"%s\""
+msgstr "E209: B³±d w trakcie zamykania \"%s\""
+
+#, c-format
+msgid "E210: Error reading \"%s\""
+msgstr "E210: B³±d odczytu \"%s\""
+
+msgid "E246: FileChangedShell autocommand deleted buffer"
+msgstr "E246: Autokomenda FileChangedShell skasowa³a bufor"
+
+#, c-format
+msgid "E211: File \"%s\" no longer available"
+msgstr "E211: Plik \"%s\" nie jest d³u¿ej dostêpny"
+
+#, 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"
+
+msgid "See \":help W12\" for more info."
+msgstr "Zobacz \":help W12\" dla dalszych informacji."
+
+#, 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"
+
+msgid "See \":help W11\" for more info."
+msgstr "Zobacz \":help W11\" dla dalszych informacji."
+
+#, 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"
+
+msgid "See \":help W16\" for more info."
+msgstr "Zobacz \":help W16\" dla dalszych informacji."
+
+#, 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"
+
+msgid "Warning"
+msgstr "OSTRZE¯ENIE"
+
+msgid ""
+"&OK\n"
+"&Load File"
+msgstr ""
+"&OK\n"
+"&Za³aduj Plik"
+
+#, c-format
+msgid "E462: Could not prepare for reloading \"%s\""
+msgstr "E462: Nie mo¿na przygotowaæ prze³adowania \"%s\""
+
+#, c-format
+msgid "E321: Could not reload \"%s\""
+msgstr "E321: Nie mo¿na prze³adowaæ \"%s\""
+
+msgid "--Deleted--"
+msgstr "--Skasowano--"
+
+#, c-format
+msgid "auto-removing autocommand: %s <buffer=%d>"
+msgstr "auto-usuwanie autokomendy: %s <buffer=%d>"
+
+#. the group doesn't exist
+#, c-format
+msgid "E367: No such group: \"%s\""
+msgstr "E367: Nie ma takiej grupy: \"%s\""
+
+#, c-format
+msgid "E215: Illegal character after *: %s"
+msgstr "E215: Niedopuszczalny znak po *: %s"
+
+#, c-format
+msgid "E216: No such event: %s"
+msgstr "E216: Nie ma takiego wydarzenia: %s"
+
+#, c-format
+msgid "E216: No such group or event: %s"
+msgstr "E216: Nie ma takiej grupy lub wydarzenia: %s"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Auto-Commands ---"
+msgstr ""
+"\n"
+"--- Autokomendy ---"
+
+#, c-format
+msgid "E680: <buffer=%d>: invalid buffer number "
+msgstr "E680: <buffer=%d>: niew³a¶ciwy numer bufora"
+
+msgid "E217: Can't execute autocommands for ALL events"
+msgstr "E217: Nie mo¿na wykonywaæ autokomend dla wydarzeñ ALL"
+
+msgid "No matching autocommands"
+msgstr "Brak pasuj±cych autokomend"
+
+msgid "E218: autocommand nesting too deep"
+msgstr "E218: zbyt g³êbokie zagnie¿d¿enie autokomend"
+
+#, c-format
+msgid "%s Auto commands for \"%s\""
+msgstr "%s Autokomend dla \"%s\""
+
+#, c-format
+msgid "Executing %s"
+msgstr "Wykonujê %s"
+
+#, c-format
+msgid "autocommand %s"
+msgstr "autokomenda %s"
+
+msgid "E219: Missing {."
+msgstr "E219: Brak {."
+
+msgid "E220: Missing }."
+msgstr "E220: Brak }."
+
+msgid "E490: No fold found"
+msgstr "E490: Nie znaleziono zwiniêcia"
+
+msgid "E350: Cannot create fold with current 'foldmethod'"
+msgstr "E350: Nie mo¿na utworzyæ zwiniêcia przy bie¿±cej 'foldmethod'"
+
+msgid "E351: Cannot delete fold with current 'foldmethod'"
+msgstr "E351: Nie mo¿na skasowaæ zwiniêcia przy bie¿±cej 'foldmethod'"
+
+#, c-format
+msgid "+--%3ld lines folded "
+msgstr "+--%3ld wierszy zwiniêto "
+
+msgid "E222: Add to read buffer"
+msgstr "E222: Dodaj do bufora odczytu"
+
+msgid "E223: recursive mapping"
+msgstr "E223: rekursywne przyporz±dkowanie"
+
+#, c-format
+msgid "E224: global abbreviation already exists for %s"
+msgstr "E224: istnieje ju¿ globalny skrót dla %s"
+
+#, c-format
+msgid "E225: global mapping already exists for %s"
+msgstr "E225: istnieje ju¿ globalne przyporz±dkowanie dla %s"
+
+#, c-format
+msgid "E226: abbreviation already exists for %s"
+msgstr "E226: istnieje ju¿ skrót dla %s"
+
+#, c-format
+msgid "E227: mapping already exists for %s"
+msgstr "E227: istnieje ju¿ przyporz±dkowanie dla %s"
+
+msgid "No abbreviation found"
+msgstr "Nie znaleziono skrótu"
+
+msgid "No mapping found"
+msgstr "Nie znaleziono przyporz±dkowania"
+
+msgid "E228: makemap: Illegal mode"
+msgstr "E228: makemap: Niedopuszczalny tryb"
+
+msgid "<cannot open> "
+msgstr "<nie mogê otworzyæ> "
+
+#, c-format
+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"
+
+#, c-format
+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'"
+
+#, c-format
+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 ""
+"&Yes\n"
+"&No\n"
+"&Cancel"
+msgstr ""
+"&Tak\n"
+"&Nie\n"
+"&Zakoñcz"
+
+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:"
+
+#. whole word only button
+msgid "Match whole word only"
+msgstr "Dopasuj tylko ca³e wyrazy"
+
+#. match case button
+msgid "Match case"
+msgstr "Dopasuj wielko¶æ liter"
+
+msgid "Direction"
+msgstr "Kierunek"
+
+#. 'Up' and 'Down' buttons
+msgid "Up"
+msgstr "W górê"
+
+msgid "Down"
+msgstr "W dó³"
+
+#. 'Find Next' button
+msgid "Find Next"
+msgstr "Znajd¼ nastêpne"
+
+#. 'Replace' button
+msgid "Replace"
+msgstr "Zamieñ"
+
+#. 'Replace All' button
+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"
+
+#, c-format
+msgid "E671: Cannot find window title \"%s\""
+msgstr "E671: Nie mogê znale¼æ tytu³u okna \"%s\""
+
+#, c-format
+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 '\\')"
+
+#. 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 "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"
+
+#, c-format
+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:"
+
+#, c-format
+msgid "E252: Fontset name: %s"
+msgstr "E252: Nazwa zestawu czcionek: %s"
+
+#, c-format
+msgid "Font '%s' is not fixed-width"
+msgstr "Czcionka '%s' nie posiada znaków jednolitej szeroko¶ci"
+
+#, c-format
+msgid "E253: Fontset name: %s"
+msgstr "E253: Nazwa zestawu czcionek: %s"
+
+#, c-format
+msgid "Font0: %s"
+msgstr "Font0: %s"
+
+#, c-format
+msgid "Font1: %s"
+msgstr "Font1: %s"
+
+#, c-format
+msgid "Font%ld width is not twice that of font0"
+msgstr "Szeroko¶æ font%ld nie jest podwójn± szeroko¶ci± font0"
+
+#, c-format
+msgid "Font0 width: %ld"
+msgstr "Szeroko¶æ font0: %ld"
+
+#, c-format
+msgid "Font1 width: %ld"
+msgstr "Szeroko¶æ font1: %ld"
+
+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:"
+
+#. create toggle button
+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 "E550: Missing colon"
+msgstr "E550: Brak dwukropka"
+
+msgid "E551: Illegal component"
+msgstr "E551: Niedozwolona czê¶æ"
+
+msgid "E552: digit expected"
+msgstr "E552: oczekiwa³em na cyfrê"
+
+#, c-format
+msgid "Page %d"
+msgstr "Strona %d"
+
+msgid "No text to be printed"
+msgstr "Brak tekstu do drukowania"
+
+#, c-format
+msgid "Printing page %d (%d%%)"
+msgstr "Drukujê stronê %d (%d%%)"
+
+#, c-format
+msgid " Copy %d of %d"
+msgstr " Kopia %d z %d"
+
+#, c-format
+msgid "Printed: %s"
+msgstr "Wydrukowano: %s"
+
+msgid "Printing aborted"
+msgstr "Drukowanie odwo³ane"
+
+msgid "E455: Error writing to PostScript output file"
+msgstr "E455: Nie mo¿na zapisaæ do wyj¶ciowego pliku PostScriptu"
+
+#, c-format
+msgid "E624: Can't open file \"%s\""
+msgstr "E624: Nie mogê otworzyæ pliku \"%s\""
+
+#, c-format
+msgid "E457: Can't read PostScript resource file \"%s\""
+msgstr "E457: Nie mo¿na odczytaæ pliku zasobów PostScriptu \"%s\""
+
+#, c-format
+msgid "E618: file \"%s\" is not a PostScript resource file"
+msgstr "E618: plik \"%s\" nie jest plikiem zasobów PostScriptu"
+
+#, c-format
+msgid "E619: file \"%s\" is not a supported PostScript resource file"
+msgstr "E619: plik \"%s\" nie jest wspieranym plikiem zasobów PostScriptu"
+
+#, c-format
+msgid "E621: \"%s\" resource file has wrong version"
+msgstr "E621: \"%s\" nieprawid³owa wersja pliku zasobów"
+
+msgid "E673: Incompatible multi-byte encoding and character set."
+msgstr "E673: Niekompatybilne kodowanie wielobajtowe i zestaw znaków."
+
+msgid "E674: printmbcharset cannot be empty with multi-byte encoding."
+msgstr "E674: printmbcharset nie mo¿e byæ pusty przy kodowaniu wielobajtowym."
+
+msgid "E675: No default font specified for multi-byte printing."
+msgstr "E675: Nie okre¶lono domy¶lnej czcionki dla drukowania wielobajtowego."
+
+msgid "E324: Can't open PostScript output file"
+msgstr "E324: Nie mo¿na otworzyæ pliku PostScript do wyj¶cia"
+
+#, c-format
+msgid "E456: Can't open file \"%s\""
+msgstr "E456: Nie mogê otworzyæ pliku \"%s\""
+
+msgid "E456: Can't find PostScript resource file \"prolog.ps\""
+msgstr "E456: Nie mo¿na znale¼æ pliku zasobów PostScriptu \"prolog.ps\""
+
+msgid "E456: Can't find PostScript resource file \"cidfont.ps\""
+msgstr "E456: Nie mo¿na znale¼æ pliku zasobów PostScriptu \"cidfont.ps\""
+
+#, c-format
+msgid "E456: Can't find PostScript resource file \"%s.ps\""
+msgstr "E456: Nie mo¿na znale¼æ pliku zasobów PostScriptu \"%s.ps\""
+
+#, c-format
+msgid "E620: Unable to convert to print encoding \"%s\""
+msgstr "E620: Nie mo¿na przekonwertowaæ by drukowaæ kodowanie \"%s\""
+
+msgid "Sending to printer..."
+msgstr "Przesy³am do drukarki..."
+
+msgid "E365: Failed to print PostScript file"
+msgstr "E365: Drukowanie pliku PostScript nie powiod³o siê"
+
+msgid "Print job sent."
+msgstr "Zadanie drukowanie przes³ane."
+
+msgid "Add a new database"
+msgstr "Dodaj now± bazê danych"
+
+msgid "Query for a pattern"
+msgstr "Zapytane o wzorzec"
+
+msgid "Show this message"
+msgstr "Poka¿ ten komunikat"
+
+msgid "Kill a connection"
+msgstr "Zabij po³±czenie"
+
+msgid "Reinit all connections"
+msgstr "Ponów wszelkie po³±czenia"
+
+msgid "Show connections"
+msgstr "Poka¿ po³±czenia"
+
+#, c-format
+msgid "E560: Usage: cs[cope] %s"
+msgstr "E560: Zastosowanie: cs[cope] %s"
+
+msgid "This cscope command does not support splitting the window.\n"
+msgstr "Ta komenda cscope nie wspomaga podzielenia okna.\n"
+
+msgid "E562: Usage: cstag <ident>"
+msgstr "E562: Zastosowanie: cstag <ident>"
+
+msgid "E257: cstag: tag not found"
+msgstr "E257: cstag: nie znaleziono znacznika"
+
+#, c-format
+msgid "E563: stat(%s) error: %d"
+msgstr "E563: stat(%s) b³±d: %d"
+
+msgid "E563: stat error"
+msgstr "E563: b³±d stat"
+
+#, 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"
+
+#, c-format
+msgid "Added cscope database %s"
+msgstr "Dodano bazê danych cscope %s"
+
+#, c-format
+msgid "E262: error reading cscope connection %ld"
+msgstr "E262: b³±d odczytu po³±czenia z cscope %ld"
+
+msgid "E561: unknown cscope search type"
+msgstr "E561: nieznany typ szukania cscope"
+
+msgid "E566: Could not create cscope pipes"
+msgstr "E566: Nie mog³em stworzyæ potoku do cscope"
+
+msgid "E622: Could not fork for cscope"
+msgstr "E622: Nie mog³em utworzyæ rozwidlenia dla cscope"
+
+msgid "cs_create_connection setpgid failed"
+msgstr "nie powiod³o siê setpgid cs_create_connection"
+
+msgid "cs_create_connection exec failed"
+msgstr "wykonanie cs_create_connection nie powiod³o siê"
+
+msgid "cs_create_connection: fdopen for to_fp failed"
+msgstr "cs_create_connection: fdopen dla to_fp nie powiod³o siê"
+
+msgid "cs_create_connection: fdopen for fr_fp failed"
+msgstr "cs_create_connection: fdopen dla fr_fp nie powiod³o siê"
+
+msgid "E623: Could not spawn cscope process"
+msgstr "E623: Nie mog³em stworzyæ procesu cscope"
+
+msgid "E567: no cscope connections"
+msgstr "E567: brak po³±czenia z cscope"
+
+#, c-format
+msgid "E469: invalid cscopequickfix flag %c for %c"
+msgstr "E469: nieprawid³owa flaga cscopequickfix %c dla %c"
+
+#, c-format
+msgid "E259: no matches found for cscope query %s of %s"
+msgstr "E259: brak dopasowañ dla zapytania cscope %s o %s"
+
+msgid "cscope commands:\n"
+msgstr "komendy cscope:\n"
+
+#, c-format
+msgid "%-5s: %s%*s (Usage: %s)"
+msgstr "%-5s: %s%*s (U¿ycie: %s)"
+
+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"
+
+#, c-format
+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 "E568: duplicate cscope database not added"
+msgstr "E568: nie dodano duplikatu bazy danych cscope"
+
+#, c-format
+msgid "E261: cscope connection %s not found"
+msgstr "E261: nie ma po³±czenia %s z cscope"
+
+#, c-format
+msgid "cscope connection %s closed"
+msgstr "po³±czenie %s z cscope zosta³o zamkniête"
+
+#. should not reach here
+msgid "E570: fatal error in cs_manage_matches"
+msgstr "E570: b³±d krytyczny w cs_manage_matches"
+
+#, c-format
+msgid "Cscope tag: %s"
+msgstr "Znacznik cscope: %s"
+
+msgid ""
+"\n"
+" # line"
+msgstr ""
+"\n"
+" # wiersz"
+
+msgid "filename / context / line\n"
+msgstr "nazwa pliku / kontekst / wiersz\n"
+
+#, c-format
+msgid "E609: Cscope error: %s"
+msgstr "E609: B³±d cscope: %s"
+
+msgid "All cscope databases reset"
+msgstr "Wszystkie bazy danych cscope prze³adowano"
+
+msgid "no cscope connections\n"
+msgstr "brak po³±czeñ z cscope\n"
+
+msgid " # pid database name prepend path\n"
+msgstr " # pid nazwa bazy danych przedsionek tropu\n"
+
+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"
+
+#, c-format
+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"
+
+#, c-format
+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"
+
+#, c-format
+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"
+
+#. This should never happen. Famous last word?
+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."
+
+#, c-format
+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ê"
+
+#, c-format
+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 "Unknown option argument"
+msgstr "Nieznany argument opcji"
+
+msgid "Too many edit arguments"
+msgstr "Zbyt wiele argumentów"
+
+msgid "Argument missing after"
+msgstr "Brak argumentu po"
+
+msgid "Garbage after option argument"
+msgstr "¦miecie po argumencie opcji"
+
+msgid "Too many \"+command\", \"-c command\" or \"--cmd command\" arguments"
+msgstr ""
+"Zbyt wiele argumentów \"+komenda\", \"-c komenda\" lub \"--cmd komenda\""
+
+msgid "Invalid argument for"
+msgstr "Niew³a¶ciwy argument dla"
+
+#, c-format
+msgid "%d files to edit\n"
+msgstr "%d plików do edycji\n"
+
+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 "Attempt to open script file again: \""
+msgstr "Próba ponownego otworzenia pliku skryptu: \""
+
+msgid "Cannot open for reading: \""
+msgstr "Nie mogê otworzyæ do odczytu: \""
+
+msgid "Cannot open for script output: \""
+msgstr "Nie mogê otworzyæ dla wyj¶cia skryptu: \""
+
+msgid "Vim: Error: Failure to start gvim from NetBeans\n"
+msgstr "Vim: B³±d: Nie mo¿na uruchomiæ gvim z NetBeans\n"
+
+msgid "Vim: Warning: Output is not to a terminal\n"
+msgstr "Vim: OSTRZE¯ENIE: Wyj¶cie nie jest terminalem\n"
+
+msgid "Vim: Warning: Input is not from a terminal\n"
+msgstr "Vim: OSTRZE¯ENIE: Wej¶cie nie pochodzi z terminala\n"
+
+#. just in case..
+msgid "pre-vimrc command line"
+msgstr "linia poleceñ pre-vimrc"
+
+#, c-format
+msgid "E282: Cannot read from \"%s\""
+msgstr "E282: Nie mogê czytaæ z \"%s\""
+
+msgid ""
+"\n"
+"More info with: \"vim -h\"\n"
+msgstr ""
+"\n"
+"Dalsze informacje poprzez: \"vim -h\"\n"
+
+msgid "[file ..] edit specified file(s)"
+msgstr "[plik ..] edytuj zadane pliki"
+
+msgid "- read text from stdin"
+msgstr "- czytaj tekst ze stdin"
+
+msgid "-t tag edit file where tag is defined"
+msgstr "-t znacznik edytuj plik, w którym dany znacznik jest zdefiniowany"
+
+msgid "-q [errorfile] edit file with first error"
+msgstr "-q [errorfile] edytuj plik, zawieraj±cy pierwszy b³±d"
+
+msgid ""
+"\n"
+"\n"
+"usage:"
+msgstr ""
+"\n"
+"\n"
+"u¿ycie:"
+
+msgid " vim [arguments] "
+msgstr " vim [argumenty]"
+
+msgid ""
+"\n"
+" or:"
+msgstr ""
+"\n"
+" lub:"
+
+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 ""
+"\n"
+"\n"
+"Arguments:\n"
+msgstr ""
+"\n"
+"\n"
+"Argumenty:\n"
+
+msgid "--\t\t\tOnly file names after this"
+msgstr "--\t\t\tTylko nazwy plików po tym"
+
+msgid "--literal\t\tDon't expand wildcards"
+msgstr "--literal\t\tNie rozwijaj znaków specjalnych"
+
+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 "-v\t\t\tVi mode (like \"vi\")"
+msgstr "-v\t\t\tTryb vi (jak \"vi\")"
+
+msgid "-e\t\t\tEx mode (like \"ex\")"
+msgstr "-e\t\t\tTryb ex (jak \"ex\")"
+
+msgid "-E\t\t\tImproved Ex mode"
+msgstr "-E\t\t\tUsprawniony tryb Ex"
+
+msgid "-s\t\t\tSilent (batch) mode (only for \"ex\")"
+msgstr "-s\t\t\tCichy tryb (t³a) (tylko dla \"ex\")"
+
+msgid "-d\t\t\tDiff mode (like \"vimdiff\")"
+msgstr "-d\t\t\tTryb ró¿nic (jak \"vimdiff\")"
+
+msgid "-y\t\t\tEasy mode (like \"evim\", modeless)"
+msgstr "-y\t\t\tTryb ³atwy (jak \"evim\", bez trybów)"
+
+msgid "-R\t\t\tReadonly mode (like \"view\")"
+msgstr "-R\t\t\tTryb wy³±cznie do odczytu (jak \"view\")"
+
+msgid "-Z\t\t\tRestricted mode (like \"rvim\")"
+msgstr "-Z\t\t\tTryb ograniczenia (jak \"rvim\")"
+
+msgid "-m\t\t\tModifications (writing files) not allowed"
+msgstr "-m\t\t\tModyfikacje (zapisywanie plików) niedozwolone"
+
+msgid "-M\t\t\tModifications in text not allowed"
+msgstr "-M\t\t\tZakaz modyfikacji tekstu"
+
+msgid "-b\t\t\tBinary mode"
+msgstr "-b\t\t\tTryb binarny"
+
+msgid "-l\t\t\tLisp mode"
+msgstr "-l\t\t\tTryb lisp"
+
+msgid "-C\t\t\tCompatible with Vi: 'compatible'"
+msgstr "-C\t\t\tB±d¼ zgodny z Vi: 'compatible'"
+
+msgid "-N\t\t\tNot fully Vi compatible: 'nocompatible'"
+msgstr "-N\t\t\tB±d¼ niezupe³nie zgodny z Vi: 'nocompatible'"
+
+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]"
+
+msgid "-D\t\t\tDebugging mode"
+msgstr "-D\t\t\tTryb odpluskwiania"
+
+msgid "-n\t\t\tNo swap file, use memory only"
+msgstr "-n\t\t\tZamiast pliku wymiany, u¿ywaj tylko pamiêci"
+
+msgid "-r\t\t\tList swap files and exit"
+msgstr "-r\t\t\tWylicz pliki wymiany i zakoñcz"
+
+msgid "-r (with file name)\tRecover crashed session"
+msgstr "-r (z nazw± pliku)\tOdtwórz za³aman± sesjê"
+
+msgid "-L\t\t\tSame as -r"
+msgstr "-L\t\t\tTo¿same z -r"
+
+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 "-A\t\t\tstart in Arabic mode"
+msgstr "-A\t\t\trozpocznij w trybie arabskim"
+
+msgid "-H\t\t\tStart in Hebrew mode"
+msgstr "-H\t\t\trozpocznij w trybie hebrajskim"
+
+msgid "-F\t\t\tStart in Farsi mode"
+msgstr "-F\t\t\trozpocznij w trybie farsi"
+
+msgid "-T <terminal>\tSet terminal type to <terminal>"
+msgstr "-T <terminal>\tUstaw typ terminala na <terminal>"
+
+msgid "-u <vimrc>\t\tUse <vimrc> instead of any .vimrc"
+msgstr "-u <vimrc>\t\tU¿yj <vimrc> zamiast jakiegokolwiek .vimrc"
+
+msgid "-U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc"
+msgstr "-U <gvimrc>\t\tU¿yj <gvimrc> zamiast jakiegokolwiek .gvimrc"
+
+msgid "--noplugin\t\tDon't load plugin scripts"
+msgstr "--noplugin\t\tNie ³aduj skryptów wtyczek"
+
+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)"
+
+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)"
+
+msgid "-O[N]\t\tLike -o but split vertically"
+msgstr "-O[N]\t\ttak samo jak -o tylko dziel okno pionowo"
+
+msgid "+\t\t\tStart at end of file"
+msgstr "+\t\t\tZacznij na koñcu pliku"
+
+msgid "+<lnum>\t\tStart at line <lnum>"
+msgstr "+<lnum>\t\tZacznij w wierszu <lnum>"
+
+msgid "--cmd <command>\tExecute <command> before loading any vimrc file"
+msgstr ""
+"-cmd <command>\t\tWykonaj komendê <command> przed za³adowaniem "
+"jakiegokolwiek pliku vimrc"
+
+msgid "-c <command>\t\tExecute <command> after loading the first file"
+msgstr ""
+"-c <command>\t\tWykonaj komendê <command> po za³adowaniu pierwszego pliku"
+
+msgid "-S <session>\t\tSource file <session> after loading the first file"
+msgstr "-S <sesja>\t\tWczytaj plik <sesja> po za³adowaniu pierwszego pliku"
+
+msgid "-s <scriptin>\tRead Normal mode commands from file <scriptin>"
+msgstr "-s <scriptin>\tWczytuj komendy trybu normalnego z pliku <scriptin>"
+
+msgid "-w <scriptout>\tAppend all typed commands to file <scriptout>"
+msgstr ""
+"-w <scriptout>\tDo³±cz wszystkie wprowadzane komendy do pliku <scriptout>"
+
+msgid "-W <scriptout>\tWrite all typed commands to file <scriptout>"
+msgstr ""
+"-W <scriptout>\tZapisuj wszystkie wprowadzane komendy do pliku <scriptout>"
+
+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 "--startuptime <file>\tWrite startup timing messages to <file>"
+msgstr ""
+"--startuptime <plik>\n"
+"Zapisz wiadomo¶ci o d³ugo¶ci startu do <plik>"
+
+msgid "-i <viminfo>\t\tUse <viminfo> instead of .viminfo"
+msgstr "-i <viminfo>\t\tU¿ywaj <viminfo> zamiast .viminfo"
+
+msgid "-h or --help\tPrint Help (this message) and exit"
+msgstr "-h lub --help\twy¶wietl Pomoc (czyli tê wiadomo¶æ) i zakoñcz"
+
+msgid "--version\t\tPrint version information and exit"
+msgstr "--version\t\twy¶wietl informacjê o wersji i zakoñcz"
+
+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"
+
+#. Failed to send, abort.
+msgid ": Send failed.\n"
+msgstr ": Wys³anie nie powiod³o siê.\n"
+
+#. Let vim start normally.
+msgid ": Send failed. Trying to execute locally\n"
+msgstr ": Wys³anie nie powiod³o siê. Próbujê wykonaæ na miejscu\n"
+
+#, c-format
+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 "No marks set"
+msgstr "Brak zak³adek"
+
+#, c-format
+msgid "E283: No marks matching \"%s\""
+msgstr "E283: ¯adna zak³adka nie pasuje do \"%s\""
+
+#. Highlight title
+msgid ""
+"\n"
+"mark line col file/text"
+msgstr ""
+"\n"
+"zak³. wiersz kol plik/tekst"
+
+#. Highlight title
+msgid ""
+"\n"
+" jump line col file/text"
+msgstr ""
+"\n"
+" skok wiersz kol plik/tekst"
+
+#. Highlight title
+msgid ""
+"\n"
+"change line col text"
+msgstr ""
+"\n"
+"zmieñ wrsz. kol tekst"
+
+msgid ""
+"\n"
+"# File marks:\n"
+msgstr ""
+"\n"
+"# Zak³adki w plikach:\n"
+
+#. Write the jumplist with -'
+msgid ""
+"\n"
+"# Jumplist (newest first):\n"
+msgstr ""
+"\n"
+"# Lista odniesieñ (pocz±wszy od najnowszych):\n"
+
+msgid ""
+"\n"
+"# History of marks within files (newest to oldest):\n"
+msgstr ""
+"\n"
+"# Historia zak³adek w plikach (od najnowszych po najstarsze):\n"
+
+msgid "Missing '>'"
+msgstr "Brak '>'"
+
+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 "E293: block was not locked"
+msgstr "E293: blok nie by³ zablokowany"
+
+msgid "E294: Seek error in swap file read"
+msgstr "E294: B³±d w trakcie czytania pliku wymiany"
+
+msgid "E295: Read error in swap file"
+msgstr "E295: B³±d odczytu pliku wymiany"
+
+msgid "E296: Seek error in swap file write"
+msgstr "E296: B³±d szukania w pliku wymiany"
+
+msgid "E297: Write error in swap file"
+msgstr "E297: B³±d zapisu w pliku wymiany"
+
+msgid "E300: Swap file already exists (symlink attack?)"
+msgstr "E300: Plik wymiany ju¿ istnieje (atak symlink?)"
+
+msgid "E298: Didn't get block nr 0?"
+msgstr "E298: Nie otrzyma³em bloku nr 0?"
+
+msgid "E298: Didn't get block nr 1?"
+msgstr "E298: Nie otrzyma³em bloku nr 1?"
+
+msgid "E298: Didn't get block nr 2?"
+msgstr "E298: Nie otrzyma³em bloku nr 2?"
+
+msgid "E843: Error while updating swap file crypt"
+msgstr "E843: B³±d w czasie uaktualniania szyfrowania pliku wymiany"
+
+#. could not (re)open the swap file, what can we do????
+msgid "E301: Oops, lost the swap file!!!"
+msgstr "E301: Ojej, zgubi³em plik wymiany!!!"
+
+msgid "E302: Could not rename swap file"
+msgstr "E302: Nie mog³em zmieniæ nazwy pliku wymiany"
+
+#, 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"
+
+msgid "E304: ml_upd_block0(): Didn't get block 0??"
+msgstr "E304: ml_upd_block(): Nie otrzyma³em bloku 0??"
+
+#, c-format
+msgid "E305: No swap file found for %s"
+msgstr "E305: Nie znaleziono pliku wymiany dla %s"
+
+msgid "Enter number of swap file to use (0 to quit): "
+msgstr "Wprowad¼ numer pliku wymiany, którego u¿yæ (0 by wyj¶æ): "
+
+#, c-format
+msgid "E306: Cannot open %s"
+msgstr "E306: Nie mogê otworzyæ %s"
+
+msgid "Unable to read block 0 from "
+msgstr "Nie mogê odczytaæ bloku 0 z "
+
+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."
+
+msgid " cannot be used with this version of Vim.\n"
+msgstr " nie mo¿e byæ stosowany z t± wersj± Vima.\n"
+
+msgid "Use Vim version 3.0.\n"
+msgstr "U¿yj Vima w wersji 3.0.\n"
+
+#, c-format
+msgid "E307: %s does not look like a Vim swap file"
+msgstr "E307: %s nie wygl±da na plik wymiany Vima"
+
+msgid " cannot be used on this computer.\n"
+msgstr " nie mo¿e byæ stosowany na tym komputerze.\n"
+
+msgid "The file was created on "
+msgstr "Ten plik zosta³ stworzony na "
+
+msgid ""
+",\n"
+"or the file has been damaged."
+msgstr ""
+",\n"
+"lub plik zosta³ uszkodzony."
+
+#, c-format
+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 " has been damaged (page size is smaller than minimum value).\n"
+msgstr ""
+" zosta³ uszkodzony (wielko¶æ strony jest mniejsza ni¿ najmniejsza warto¶æ).\n"
+
+#, c-format
+msgid "Using swap file \"%s\""
+msgstr "U¿ywam pliku wymiany \"%s\""
+
+#, c-format
+msgid "Original file \"%s\""
+msgstr "Oryginalny plik \"%s\""
+
+msgid "E308: Warning: Original file may have been changed"
+msgstr "E308: OSTRZE¯ENIE: Oryginalny plik móg³ byæ zmieniony"
+
+#, c-format
+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"
+
+#, c-format
+msgid "E309: Unable to read block 1 from %s"
+msgstr "E309: Nie mogê odczytaæ bloku 1 z %s"
+
+msgid "???MANY LINES MISSING"
+msgstr "???BRAKUJE WIELU WIERSZY"
+
+msgid "???LINE COUNT WRONG"
+msgstr "???LICZNIK WIERSZY NIEZGODNY"
+
+msgid "???EMPTY BLOCK"
+msgstr "???PUSTY BLOK"
+
+msgid "???LINES MISSING"
+msgstr "???BRAKUJE WIERSZY"
+
+#, 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?)"
+
+msgid "???BLOCK MISSING"
+msgstr "???BRAK BLOKU"
+
+msgid "??? from here until ???END lines may be messed up"
+msgstr "??? od tego miejsca po ???KONIEC wiersze mog± byæ pomieszane"
+
+msgid "??? from here until ???END lines may have been inserted/deleted"
+msgstr "??? od tego miejsca po ???KONIEC wiersze mog± byæ w³o¿one/skasowane"
+
+msgid "???END"
+msgstr "???KONIEC"
+
+msgid "E311: Recovery Interrupted"
+msgstr "E311: Przerwanie odtwarzania"
+
+msgid ""
+"E312: Errors detected while recovering; look for lines starting with ???"
+msgstr "E312: Wykryto b³êdy podczas odtwarzania; od których wierszy zacz±æ ???"
+
+msgid "See \":help E312\" for more information."
+msgstr "Zobacz \":help E312\" dla dalszych informacji."
+
+msgid "Recovery completed. You should check if everything is OK."
+msgstr ""
+"Odtwarzanie zakoñczono. Powiniene¶ sprawdziæ czy wszystko jest w porz±dku."
+
+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"
+
+msgid "and run diff with the original file to check for changes)"
+msgstr "i wykonaæ diff z oryginalnym plikiem aby sprawdziæ zmiany)"
+
+msgid "Recovery completed. Buffer contents equals file contents."
+msgstr "Odzyskiwanie zakoñczone. Zawarto¶æ bufora jest równa zawarto¶ci pliku."
+
+msgid ""
+"\n"
+"You may want to delete the .swp file now.\n"
+"\n"
+msgstr ""
+"\n"
+"Mo¿esz teraz chcieæ usun±æ plik .swp.\n"
+"\n"
+
+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"
+
+#. use msg() to start the scrolling properly
+msgid "Swap files found:"
+msgstr "Znalezione pliki wymiany:"
+
+msgid " In current directory:\n"
+msgstr " W bie¿±cym katalogu:\n"
+
+msgid " Using specified name:\n"
+msgstr " U¿ywam podanej nazwy:\n"
+
+msgid " In directory "
+msgstr " W katalogu "
+
+msgid " -- none --\n"
+msgstr " -- ¿aden --\n"
+
+msgid " owned by: "
+msgstr " posiadany przez: "
+
+msgid " dated: "
+msgstr " data: "
+
+msgid " dated: "
+msgstr " data: "
+
+msgid " [from Vim version 3.0]"
+msgstr " [po Vimie wersja 3.0]"
+
+msgid " [does not look like a Vim swap file]"
+msgstr " [nie wygl±da na plik wymiany Vima]"
+
+msgid " file name: "
+msgstr " nazwa pliku: "
+
+msgid ""
+"\n"
+" modified: "
+msgstr ""
+"\n"
+" zmieniono: "
+
+msgid "YES"
+msgstr "TAK"
+
+msgid "no"
+msgstr "nie"
+
+msgid ""
+"\n"
+" user name: "
+msgstr ""
+"\n"
+" u¿ytkownik: "
+
+msgid " host name: "
+msgstr " nazwa hosta: "
+
+msgid ""
+"\n"
+" host name: "
+msgstr ""
+"\n"
+" nazwa hosta: "
+
+msgid ""
+"\n"
+" process ID: "
+msgstr ""
+"\n"
+" ID procesu: "
+
+msgid " (still running)"
+msgstr " (dalej dzia³a)"
+
+msgid ""
+"\n"
+" [not usable with this version of Vim]"
+msgstr ""
+"\n"
+" [nie nadaje siê dla tej wersji Vima]"
+
+msgid ""
+"\n"
+" [not usable on this computer]"
+msgstr ""
+"\n"
+" [nie do u¿ytku na tym komputerze]"
+
+msgid " [cannot be read]"
+msgstr " [nieodczytywalny]"
+
+msgid " [cannot be opened]"
+msgstr " [nieotwieralny]"
+
+msgid "E313: Cannot preserve, there is no swap file"
+msgstr "E313: Nie mogê zabezpieczyæ, bo brak pliku wymiany"
+
+msgid "File preserved"
+msgstr "Plik zabezpieczono"
+
+msgid "E314: Preserve failed"
+msgstr "E314: Nieudane zabezpieczenie"
+
+#, c-format
+msgid "E315: ml_get: invalid lnum: %ld"
+msgstr "E315: ml_get: niew³a¶ciwy lnum: %ld"
+
+#, c-format
+msgid "E316: ml_get: cannot find line %ld"
+msgstr "E316: ml_get: nie znaleziono wiersza %ld"
+
+msgid "E317: pointer block id wrong 3"
+msgstr "E317: niepoprawne id wska¼nika bloku 3"
+
+msgid "stack_idx should be 0"
+msgstr "stack_idx powinien byæ 0"
+
+msgid "E318: Updated too many blocks?"
+msgstr "E318: Zaktualizowano zbyt wiele bloków?"
+
+msgid "E317: pointer block id wrong 4"
+msgstr "E317: niepoprawne id wska¼nika bloku 4"
+
+msgid "deleted block 1?"
+msgstr "blok nr 1 skasowany?"
+
+#, c-format
+msgid "E320: Cannot find line %ld"
+msgstr "E320: Nie mogê znale¼æ wiersza %ld"
+
+msgid "E317: pointer block id wrong"
+msgstr "E317: niepoprawne id bloku odniesienia"
+
+msgid "pe_line_count is zero"
+msgstr "pe_line_count wynosi zero"
+
+#, c-format
+msgid "E322: line number out of range: %ld past the end"
+msgstr "E322: numer wiersza poza zakresem: %ld jest poza koñcem"
+
+#, c-format
+msgid "E323: line count wrong in block %ld"
+msgstr "E323: liczba wierszy niepoprawna w bloku %ld"
+
+msgid "Stack size increases"
+msgstr "Wielko¶æ stosu wzrasta"
+
+msgid "E317: pointer block id wrong 2"
+msgstr "E317: niepoprawne id bloku odniesienia 2"
+
+#, c-format
+msgid "E773: Symlink loop for \"%s\""
+msgstr "E773: Pêtla dowi±zañ dla \"%s\""
+
+msgid "E325: ATTENTION"
+msgstr "E325: UWAGA"
+
+msgid ""
+"\n"
+"Found a swap file by the name \""
+msgstr ""
+"\n"
+"Znalaz³em plik wymiany o nazwie \""
+
+msgid "While opening file \""
+msgstr "Podczas otwierania pliku \""
+
+msgid " NEWER than swap file!\n"
+msgstr " NOWSZE od pliku wymiany!\n"
+
+#. 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.\n"
+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"
+
+msgid " Quit, or continue with caution.\n"
+msgstr " Zakoñcz lub ostro¿nie kontynuuj.\n"
+
+msgid "(2) An edit session for this file crashed.\n"
+msgstr "(2) Sesja edycji dla pliku za³ama³a siê.\n"
+
+msgid " If this is the case, use \":recover\" or \"vim -r "
+msgstr " Je¶li tak, to u¿yj \":recover\" lub \"vim -r "
+
+msgid ""
+"\"\n"
+" to recover the changes (see \":help recovery\").\n"
+msgstr ""
+"\"\n"
+" aby odzyskaæ zmiany (zobacz \":help recovery)\").\n"
+
+msgid " If you did this already, delete the swap file \""
+msgstr " Je¶li ju¿ to zrobi³e¶, usuñ plik wymiany \""
+
+msgid ""
+"\"\n"
+" to avoid this message.\n"
+msgstr ""
+"\"\n"
+" aby unikn±æ tej wiadomo¶ci.\n"
+
+msgid "Swap file \""
+msgstr "Plik wymiany \""
+
+msgid "\" already exists!"
+msgstr "\" ju¿ istnieje!"
+
+msgid "VIM - ATTENTION"
+msgstr "VIM - UWAGA"
+
+msgid "Swap file already exists!"
+msgstr "Plik wymiany ju¿ istnieje!"
+
+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æ"
+
+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æ"
+
+msgid "E326: Too many swap files found"
+msgstr "E326: Znaleziono zbyt wiele plików wymiany"
+
+msgid "E327: Part of menu-item path is not sub-menu"
+msgstr "E327: Czê¶æ tropu punktu menu nie okre¶la podmenu"
+
+msgid "E328: Menu only exists in another mode"
+msgstr "E328: Menu istnieje tylko w innym trybie"
+
+#, c-format
+msgid "E329: No menu \"%s\""
+msgstr "E329: Nie ma menu \"%s\""
+
+#. Only a mnemonic or accelerator is not valid.
+msgid "E792: Empty menu name"
+msgstr "E792: Pusta nazwa menu"
+
+msgid "E330: Menu path must not lead to a sub-menu"
+msgstr "E330: Trop menu nie mo¿e prowadziæ do podmenu"
+
+msgid "E331: Must not add menu items directly to menu bar"
+msgstr "E331: Nie wolno dodawaæ punktów menu wprost do paska menu"
+
+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
+msgid ""
+"\n"
+"--- Menus ---"
+msgstr ""
+"\n"
+"--- Menu ---"
+
+msgid "Tear off this menu"
+msgstr "Oderwij to menu"
+
+msgid "E333: Menu path must lead to a menu item"
+msgstr "E333: Trop menu musi prowadziæ do punktu menu"
+
+#, c-format
+msgid "E334: Menu not found: %s"
+msgstr "E334: Nie znaleziono menu: %s"
+
+#, c-format
+msgid "E335: Menu not defined for %s mode"
+msgstr "E335: Menu nie jest zdefiniowane dla trybu %s"
+
+msgid "E336: Menu path must lead to a sub-menu"
+msgstr "E336: Trop menu musi prowadziæ do podmenu"
+
+msgid "E337: Menu not found - check menu names"
+msgstr "E337: Nie znaleziono menu - sprawd¼ nazwy menu"
+
+#, c-format
+msgid "Error detected while processing %s:"
+msgstr "Wykryto b³±d podczas przetwarzania %s:"
+
+#, c-format
+msgid "line %4ld:"
+msgstr "wiersz %4ld:"
+
+#, c-format
+msgid "E354: Invalid register name: '%s'"
+msgstr "E354: Niew³a¶ciwa nazwa rejestru: '%s'"
+
+msgid "Messages maintainer: Bram Moolenaar <Bram@vim.org>"
+msgstr "Opiekun komunikatów: Miko³aj Machowski <mikmach@wp.pl>"
+
+msgid "Interrupt: "
+msgstr "Przerwanie: "
+
+msgid "Press ENTER or type command to continue"
+msgstr "Naci¶nij ENTER lub wprowad¼ komendê aby kontynuowaæ"
+
+#, c-format
+msgid "%s line %ld"
+msgstr "%s wiersz %ld"
+
+msgid "-- More --"
+msgstr "-- Wiêcej --"
+
+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"
+
+msgid "Question"
+msgstr "Pytanie"
+
+msgid ""
+"&Yes\n"
+"&No"
+msgstr ""
+"&Tak\n"
+"&Nie"
+
+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"
+
+msgid "Select Directory dialog"
+msgstr "Dialog wyboru katalogu"
+
+msgid "Save File dialog"
+msgstr "Dialog zapisywania pliku"
+
+msgid "Open File dialog"
+msgstr "Dialog otwierania pliku"
+
+#. TODO: non-GUI file selector here
+msgid "E338: Sorry, no file browser in console mode"
+msgstr "E338: Przykro mi, nie ma przegl±darki plików w trybie konsoli"
+
+msgid "E766: Insufficient arguments for printf()"
+msgstr "E766: Za ma³o argumentów dla printf()"
+
+msgid "E807: Expected Float argument for printf()"
+msgstr "E807: Spodziewany argument Zmiennoprzecinkowy w printf()"
+
+msgid "E767: Too many arguments to printf()"
+msgstr "E767: Za du¿o argumentów dla printf()"
+
+msgid "W10: Warning: Changing a readonly file"
+msgstr "W10: OSTRZE¯ENIE: Zmiany w pliku tylko do odczytu"
+
+msgid "Type number and <Enter> or click with mouse (empty cancels): "
+msgstr "Wpisz numer i <Enter> lub wybierz mysz± (pusta warto¶æ anuluje): "
+
+msgid "Type number and <Enter> (empty cancels): "
+msgstr "Wpisz numer i <Enter> (puste anuluje): "
+
+msgid "1 more line"
+msgstr "1 wiersz wiêcej"
+
+msgid "1 line less"
+msgstr "1 wiersz mniej"
+
+#, c-format
+msgid "%ld more lines"
+msgstr "dodano %ld wierszy"
+
+#, c-format
+msgid "%ld fewer lines"
+msgstr "usuniêto %ld wierszy"
+
+msgid " (Interrupted)"
+msgstr " (Przerwane)"
+
+msgid "Beep!"
+msgstr "Biiip!"
+
+msgid "Vim: preserving files...\n"
+msgstr "Vim: zachowujê plik...\n"
+
+#. close all memfiles, without deleting
+msgid "Vim: Finished.\n"
+msgstr "Vim: Zakoñczono.\n"
+
+msgid "ERROR: "
+msgstr "B£¡D: "
+
+#, c-format
+msgid ""
+"\n"
+"[bytes] total alloc-freed %lu-%lu, in use %lu, peak use %lu\n"
+msgstr ""
+"\n"
+"[bajtów] totalne alokacje-zwolnienia %lu-%lu, w u¿ytku %lu, maksymalne "
+"u¿ycie %lu\n"
+
+#, c-format
+msgid ""
+"[calls] total re/malloc()'s %lu, total free()'s %lu\n"
+"\n"
+msgstr ""
+"[wywo³ania] wszystkich re/malloc()-ów %lu, wszystkich free()-ów %lu\n"
+"\n"
+
+msgid "E340: Line is becoming too long"
+msgstr "E340: Wiersz staje siê zbyt d³ugi"
+
+#, c-format
+msgid "E341: Internal error: lalloc(%ld, )"
+msgstr "E341: Wewnêtrzny b³±d: lalloc(%ld, )"
+
+#, c-format
+msgid "E342: Out of memory! (allocating %lu bytes)"
+msgstr "E342: Brak pamiêci! (rezerwacja %lu bajtów)"
+
+#, c-format
+msgid "Calling shell to execute: \"%s\""
+msgstr "Wywo³ujê pow³okê do wykonania: \"%s\""
+
+msgid "E545: Missing colon"
+msgstr "E545: Brak dwukropka"
+
+msgid "E546: Illegal mode"
+msgstr "E546: Niedozwolony tryb"
+
+msgid "E547: Illegal mouseshape"
+msgstr "E547: Niedozwolony obrys myszki"
+
+msgid "E548: digit expected"
+msgstr "E548: oczekiwa³em na cyfrê"
+
+msgid "E549: Illegal percentage"
+msgstr "E549: Niedozwolony procent"
+
+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 "E854: path too long for completion"
+msgstr "E854: ¶cie¿ka za d³uga by uzupe³niæ"
+
+#, 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'."
+
+#, c-format
+msgid "E344: Can't find directory \"%s\" in cdpath"
+msgstr "E344: Nie mogê znale¼æ katalogu \"%s\" w cdpath"
+
+#, c-format
+msgid "E345: Can't find file \"%s\" in path"
+msgstr "E345: Nie mogê znale¼æ pliku \"%s\" w tropie"
+
+#, c-format
+msgid "E346: No more directory \"%s\" found in cdpath"
+msgstr "E346: Katalogu \"%s\" nie ma wiêcej w cdpath"
+
+#, c-format
+msgid "E347: No more file \"%s\" found in path"
+msgstr "E347: Pliku \"%s\" nie ma wiêcej w tropie"
+
+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"
+
+#, c-format
+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"
+
+#, c-format
+msgid "E658: NetBeans connection lost for buffer %ld"
+msgstr "E658: Bufor %ld 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"
+
+#, c-format
+msgid "E505: %s is read-only (add ! to override)"
+msgstr "E505: %s jest tylko do odczytu (dodaj ! aby wymusiæ)"
+
+msgid "E349: No identifier under cursor"
+msgstr "E349: Brak identyfikatora pod kursorem"
+
+msgid "E774: 'operatorfunc' is empty"
+msgstr "E774: 'operatorfunc' jest pusta"
+
+msgid "E775: Eval feature not available"
+msgstr "E775: Funkcjonalno¶æ eval nie jest dostêpna"
+
+msgid "Warning: terminal cannot highlight"
+msgstr "OSTRZE¯ENIE: terminal nie wykonuje pod¶wietlania"
+
+msgid "E348: No string under cursor"
+msgstr "E348: Brak ci±gu pod kursorem"
+
+msgid "E352: Cannot erase folds with current 'foldmethod'"
+msgstr "E352: Nie mogê skasowaæ zwiniêcia z bie¿±c± 'foldmethod'"
+
+msgid "E664: changelist is empty"
+msgstr "E664: lista zmian (changelist) jest pusta"
+
+msgid "E662: At start of changelist"
+msgstr "E662: Na pocz±tku listy zmian"
+
+msgid "E663: At end of changelist"
+msgstr "E663: Na koñcu listy zmian"
+
+msgid "Type :quit<Enter> to exit Vim"
+msgstr "wprowad¼ :quit<Enter> zakoñczenie programu"
+
+#, c-format
+msgid "1 line %sed 1 time"
+msgstr "1 wiersz %sed 1 raz"
+
+#, c-format
+msgid "1 line %sed %d times"
+msgstr "1 wiersz %sed %d razy"
+
+#, c-format
+msgid "%ld lines %sed 1 time"
+msgstr "%ld wierszy %sed 1 raz"
+
+#, c-format
+msgid "%ld lines %sed %d times"
+msgstr "%ld wierszy %sed %d razy"
+
+#, c-format
+msgid "%ld lines to indent... "
+msgstr "%ld wierszy do wciêcia... "
+
+msgid "1 line indented "
+msgstr "1 wiersz wciêty "
+
+#, c-format
+msgid "%ld lines indented "
+msgstr "%ld wierszy wciêtych "
+
+msgid "E748: No previously used register"
+msgstr "E748: Brak poprzednio u¿ytego rejestru"
+
+#. must display the prompt
+msgid "cannot yank; delete anyway"
+msgstr "nie mogê skopiowaæ, mimo to kasujê"
+
+msgid "1 line changed"
+msgstr "1 wiersz zmieniono"
+
+#, c-format
+msgid "%ld lines changed"
+msgstr "%ld wierszy zmieniono"
+
+#, c-format
+msgid "freeing %ld lines"
+msgstr "zwalniam %ld wierszy"
+
+msgid "block of 1 line yanked"
+msgstr "skopiowano blok 1 wiersza"
+
+msgid "1 line yanked"
+msgstr "1 wiersz skopiowano"
+
+#, c-format
+msgid "block of %ld lines yanked"
+msgstr "%ld wierszy skopiowanych"
+
+#, c-format
+msgid "%ld lines yanked"
+msgstr "%ld wierszy skopiowanych"
+
+#, c-format
+msgid "E353: Nothing in register %s"
+msgstr "E353: Pusty rejestr %s"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Registers ---"
+msgstr ""
+"\n"
+"--- Rejestry ---"
+
+msgid "Illegal register name"
+msgstr "Niedozwolona nazwa rejestru"
+
+msgid ""
+"\n"
+"# Registers:\n"
+msgstr ""
+"\n"
+"# Rejestry:\n"
+
+#, c-format
+msgid "E574: Unknown register type %d"
+msgstr "E574: Nieznany typ rejestru %d"
+
+#, c-format
+msgid "%ld Cols; "
+msgstr "%ld Kolumn; "
+
+#, c-format
+msgid "Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Bytes"
+msgstr "Wybrano %s%ld z %ld Wierszy; %ld z %ld S³ów; %ld z %ld Bajtów"
+
+#, c-format
+msgid ""
+"Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Chars; %ld of %ld "
+"Bytes"
+msgstr ""
+"Wybrano %s%ld z %ld Wierszy; %ld z %ld S³ów; %ld z %ld Znaków; %ld z %ld "
+"Bajtów"
+
+#, c-format
+msgid "Col %s of %s; Line %ld of %ld; Word %ld of %ld; Byte %ld of %ld"
+msgstr "Kol %s z %s; Wiersz %ld z %ld; S³owo %ld z %ld; Bajt %ld z %ld"
+
+#, c-format
+msgid ""
+"Col %s of %s; Line %ld of %ld; Word %ld of %ld; Char %ld of %ld; Byte %ld of "
+"%ld"
+msgstr ""
+"Kol %s z %s; Wiersz %ld z %ld; S³owo %ld z %ld; Znak %ld z %ld; Bajt %ld z "
+"%ld"
+
+#, c-format
+msgid "(+%ld for BOM)"
+msgstr "(+%ld dla BOM)"
+
+msgid "%<%f%h%m%=Page %N"
+msgstr "%<%f%h%m%=Strona %N"
+
+msgid "Thanks for flying Vim"
+msgstr "Dziêki za lot Vimem"
+
+msgid "E518: Unknown option"
+msgstr "E518: Nieznana opcja"
+
+msgid "E519: Option not supported"
+msgstr "E519: Opcja nie jest wspomagana"
+
+msgid "E520: Not allowed in a modeline"
+msgstr "E520: Niedozwolone w modeline"
+
+msgid "E846: Key code not set"
+msgstr "E846: Kod klucza nie jest ustawiony"
+
+msgid "E521: Number required after ="
+msgstr "E521: Po = wymagany jest numer"
+
+msgid "E522: Not found in termcap"
+msgstr "E522: Nie znaleziono w termcap"
+
+#, c-format
+msgid "E539: Illegal character <%s>"
+msgstr "E539: Niedozwolony znak <%s>"
+
+msgid "E529: Cannot set 'term' to empty string"
+msgstr "E529: Nie mogê ustawiæ 'term' na pusty ci±g"
+
+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 "E589: 'backupext' and 'patchmode' are equal"
+msgstr "E589: 'backupext' i 'patchmode' s± to¿same"
+
+msgid "E834: Conflicts with value of 'listchars'"
+msgstr "E834: Konflikty warto¶ci 'listchars'"
+
+msgid "E835: Conflicts with value of 'fillchars'"
+msgstr "E835: Konflikty warto¶ci 'fillchars'"
+
+msgid "E617: Cannot be changed in the GTK+ 2 GUI"
+msgstr "E617: Nie mogê zmieniæ w GTK+2 GUI"
+
+msgid "E524: Missing colon"
+msgstr "E524: Brak dwukropka"
+
+msgid "E525: Zero length string"
+msgstr "E525: Ci±g o zerowej d³ugo¶ci"
+
+#, c-format
+msgid "E526: Missing number after <%s>"
+msgstr "E526: Brak numeru po <%s>"
+
+msgid "E527: Missing comma"
+msgstr "E527: Brak przecinka"
+
+msgid "E528: Must specify a ' value"
+msgstr "E528: Musi okre¶laæ warto¶æ '"
+
+msgid "E595: contains unprintable or wide character"
+msgstr "E595: zawiera niewy¶wietlalny lub szeroki znak"
+
+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"
+
+#, c-format
+msgid "E535: Illegal character after <%c>"
+msgstr "E535: Niedozwolony znak po <%c>"
+
+msgid "E536: comma required"
+msgstr "E536: wymagany przecinek"
+
+#, c-format
+msgid "E537: 'commentstring' must be empty or contain %s"
+msgstr "E537: 'commentstring' musi byæ pusty lub zawieraæ %s"
+
+msgid "E538: No mouse support"
+msgstr "E538: Brak wspomagania myszki"
+
+msgid "E540: Unclosed expression sequence"
+msgstr "E540: Niedomkniêty ci±g wyra¿eñ"
+
+msgid "E541: too many items"
+msgstr "E541: zbyt wiele elementów"
+
+msgid "E542: unbalanced groups"
+msgstr "E542: niezbalansowane grupy"
+
+msgid "E590: A preview window already exists"
+msgstr "E590: okno podgl±du ju¿ istnieje"
+
+msgid "W17: Arabic requires UTF-8, do ':set encoding=utf-8'"
+msgstr "W17: Arabski wymaga UTF-8, zrób ':set encoding=utf-8'"
+
+#, c-format
+msgid "E593: Need at least %d lines"
+msgstr "E593: Potrzebujê przynajmniej %d wierszy"
+
+#, c-format
+msgid "E594: Need at least %d columns"
+msgstr "E594: Potrzebujê przynajmniej %d kolumn"
+
+#, 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.
+#, c-format
+msgid "E521: Number required: &%s = '%s'"
+msgstr "E521: Wymagana Liczba: &%s = '%s'"
+
+msgid ""
+"\n"
+"--- Terminal codes ---"
+msgstr ""
+"\n"
+"--- Kody terminala ---"
+
+msgid ""
+"\n"
+"--- Global option values ---"
+msgstr ""
+"\n"
+"--- Globalne warto¶ci opcji ---"
+
+msgid ""
+"\n"
+"--- Local option values ---"
+msgstr ""
+"\n"
+"--- Lokalne warto¶ci opcji ---"
+
+msgid ""
+"\n"
+"--- Options ---"
+msgstr ""
+"\n"
+"--- Opcje ---"
+
+msgid "E356: get_varp ERROR"
+msgstr "E356: B£¡D get_varp"
+
+#, c-format
+msgid "E357: 'langmap': Matching character missing for %s"
+msgstr "E357: 'langmap': Brak pasuj±cego znaku dla %s"
+
+#, c-format
+msgid "E358: 'langmap': Extra characters after semicolon: %s"
+msgstr "E358: 'langmap': Dodatkowe znaki po ¶redniku: %s"
+
+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"
+
+#, c-format
+msgid "Need %s version %ld\n"
+msgstr "Potrzebujê %s w wersji %ld\n"
+
+msgid "Cannot open NIL:\n"
+msgstr "Nie mogê otworzyæ NIL:\n"
+
+msgid "Cannot create "
+msgstr "Nie mogê stworzyæ "
+
+#, c-format
+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"
+
+#. if Vim opened a window: Executing a shell may cause crashes
+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ê"
+
+#, c-format
+msgid "to %s on %s"
+msgstr "do %s z %s"
+
+#, c-format
+msgid "E613: Unknown printer font: %s"
+msgstr "E613: Nieznana czcionka drukarki: %s"
+
+#, c-format
+msgid "E238: Print error: %s"
+msgstr "E238: B³±d drukarki: %s"
+
+#, c-format
+msgid "Printing '%s'"
+msgstr "Wydrukowano '%s'"
+
+#, c-format
+msgid "E244: Illegal charset name \"%s\" in font name \"%s\""
+msgstr ""
+"E244: Niedozwolona nazwa zestawu znaków \"%s\" w nazwie czcionki \"%s\""
+
+#, c-format
+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"
+
+#, c-format
+msgid "Vim: Caught deadly signal %s\n"
+msgstr "Vim: Za³apa³ ¶miertelny sygna³ %s\n"
+
+#, c-format
+msgid "Vim: Caught deadly signal\n"
+msgstr "Vim: Za³apa³ ¶miertelny sygna³\n"
+
+#, c-format
+msgid "Opening the X display took %ld msec"
+msgstr "Otwieranie ekranu X trwa³o %ld 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"
+"Could not get security context for "
+msgstr ""
+"\n"
+"Nie mogê uzyskaæ kontekstu bezpieczeñstwa dla"
+
+msgid ""
+"\n"
+"Could not set security context for "
+msgstr ""
+"\n"
+"Nie mo¿na uzyskaæ kontekstu bezpieczeñstwa dla"
+
+msgid ""
+"\n"
+"Cannot execute shell "
+msgstr ""
+"\n"
+"Nie mogê wykonaæ pow³oki "
+
+msgid ""
+"\n"
+"Cannot execute shell sh\n"
+msgstr ""
+"\n"
+"Nie mogê wykonaæ pow³oki sh\n"
+
+msgid ""
+"\n"
+"shell returned "
+msgstr ""
+"\n"
+"pow³oka zwróci³a "
+
+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"
+
+#, c-format
+msgid "dlerror = \"%s\""
+msgstr "dlerror = \"%s\""
+
+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ê"
+
+#, c-format
+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!"
+
+#, c-format
+msgid "shell returned %d"
+msgstr "pow³oka zwróci³a %d"
+
+#, c-format
+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"
+
+#, c-format
+msgid "E372: Too many %%%c in format string"
+msgstr "E372: Zbyt wiele %%%c w ci±gu formatuj±cym"
+
+#, c-format
+msgid "E373: Unexpected %%%c in format string"
+msgstr "E373: Nieoczekiwane %%%c w ci±gu formatuj±cym"
+
+msgid "E374: Missing ] in format string"
+msgstr "E374: Brak ] w ci±gu formatuj±cym"
+
+#, c-format
+msgid "E375: Unsupported %%%c in format string"
+msgstr "E375: Niewspomagane %%%c w ci±gu formatuj±cym"
+
+#, c-format
+msgid "E376: Invalid %%%c in format string prefix"
+msgstr "E376: Niepoprawne %%%c w prefiksie ci±gu formatuj±cego"
+
+#, c-format
+msgid "E377: Invalid %%%c in format string"
+msgstr "E377: Niepoprawne %%%c w ci±gu formatuj±cym"
+
+msgid "E378: 'errorformat' contains no pattern"
+msgstr "E378: 'errorformat' nie zawiera wzorca"
+
+msgid "E379: Missing or empty directory name"
+msgstr "E379: Pusta nazwa katalogu lub jej brak"
+
+msgid "E553: No more items"
+msgstr "E553: Nie ma wiêcej elementów"
+
+#, c-format
+msgid "(%d of %d)%s%s: "
+msgstr "(%d z %d)%s%s: "
+
+msgid " (line deleted)"
+msgstr " (wiersz skasowany)"
+
+msgid "E380: At bottom of quickfix stack"
+msgstr "E380: Na dole stosu quickfix"
+
+msgid "E381: At top of quickfix stack"
+msgstr "E381: Na górze stosu quickfix"
+
+#, c-format
+msgid "error list %d of %d; %d errors"
+msgstr "lista b³êdów %d z %d; %d b³êdów"
+
+msgid "E382: Cannot write, 'buftype' option is set"
+msgstr "E382: Nie mogê zapisaæ, opcja 'buftype' jest ustawiona"
+
+msgid "Error file"
+msgstr "Plik b³êdu"
+
+msgid "E683: File name missing or invalid pattern"
+msgstr "E683: Brak nazwy pliku lub niew³a¶ciwa ¶cie¿ka"
+
+#, c-format
+msgid "Cannot open file \"%s\""
+msgstr "Nie mogê otworzyæ pliku \"%s\""
+
+msgid "E681: Buffer is not loaded"
+msgstr "E681: Bufor nie jest za³adowany"
+
+msgid "E777: String or List expected"
+msgstr "E777: Oczekiwa³em na ³añcuch lub listê"
+
+#, c-format
+msgid "E369: invalid item in %s%%[]"
+msgstr "E369: Niew³a¶ciwy element w %s%%[]"
+
+#, c-format
+msgid "E769: Missing ] after %s["
+msgstr "E769: Brak ] po %s["
+
+#, c-format
+msgid "E53: Unmatched %s%%("
+msgstr "E53: Niesparowany %s%%("
+
+#, c-format
+msgid "E54: Unmatched %s("
+msgstr "E54: Niesparowany %s("
+
+#, c-format
+msgid "E55: Unmatched %s)"
+msgstr "E55: Niesparowany %s)"
+
+msgid "E66: \\z( not allowed here"
+msgstr "E66: \\z( jest niedozwolone w tym miejscu"
+
+msgid "E67: \\z1 et al. not allowed here"
+msgstr "E67: \\z1 i podobne s± niedozwolone w tym miejscu"
+
+#, c-format
+msgid "E69: Missing ] after %s%%["
+msgstr "E69: Brak ] po %s%%["
+
+#, c-format
+msgid "E70: Empty %s%%[]"
+msgstr "E70: Pusty %s%%[]"
+
+msgid "E339: Pattern too long"
+msgstr "E339: Zbyt d³ugi wzorzec"
+
+msgid "E50: Too many \\z("
+msgstr "E50: Zbyt wiele \\z("
+
+#, c-format
+msgid "E51: Too many %s("
+msgstr "E51: Zbyt wiele %s("
+
+msgid "E52: Unmatched \\z("
+msgstr "E52: Niesparowany \\z("
+
+#, c-format
+msgid "E59: invalid character after %s@"
+msgstr "E59: niedozwolony znak po %s@"
+
+#, c-format
+msgid "E60: Too many complex %s{...}s"
+msgstr "E60: Zbyt wiele z³o¿onych %s{...}"
+
+#, c-format
+msgid "E61: Nested %s*"
+msgstr "E61: Zagnie¿d¿one %s*"
+
+#, c-format
+msgid "E62: Nested %s%c"
+msgstr "E62: Zagnie¿d¿one %s%c"
+
+msgid "E63: invalid use of \\_"
+msgstr "E63: Niedozwolone u¿ycie \\_"
+
+#, c-format
+msgid "E64: %s%c follows nothing"
+msgstr "E64: %s%c po niczym"
+
+msgid "E65: Illegal back reference"
+msgstr "E65: Niew³a¶ciwe odwo³anie wsteczne"
+
+msgid "E68: Invalid character after \\z"
+msgstr "E68: niedopuszczalny znak po \\z"
+
+#, c-format
+msgid "E678: Invalid character after %s%%[dxouU]"
+msgstr "E678: Niedozwolony znak po %s%%[dxouU]"
+
+#, c-format
+msgid "E71: Invalid character after %s%%"
+msgstr "E71: Niedozwolony znak po %s%%"
+
+#, c-format
+msgid "E554: Syntax error in %s{...}"
+msgstr "E554: B³±d sk³adni w %s{...}"
+
+msgid "External submatches:\n"
+msgstr "Zewnêtrzne poddopasowania:\n"
+
+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"
+
+#, c-format
+msgid "E866: (NFA regexp) Misplaced %c"
+msgstr "E866: (wyra¿enie regularne NFA) Niepoprawnie umieszczone %c"
+
+msgid "E865: (NFA) Regexp end encountered prematurely"
+msgstr "E865: (NFA) przedwczesny koniec wyra¿enia regularnego"
+
+#, c-format
+msgid "E867: (NFA) Unknown operator '\\z%c'"
+msgstr "E867: (NFA) Nieznany operator '\\z%c'"
+
+#, c-format
+msgid "E867: (NFA) Unknown operator '\\%%%c'"
+msgstr "E867: (NFA) Nieznany operator '\\%%%c'"
+
+#. should never happen
+msgid "E868: Error building NFA with equivalence class!"
+msgstr "E868: B³±d przy budowwaniu NFA z klas± ekwiwalencji"
+
+#, c-format
+msgid "E869: (NFA) Unknown operator '\\@%c'"
+msgstr "E869: (NFA) Nieznany operator '\\@%c'"
+
+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.
+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 `('
+msgid "E872: (NFA regexp) Too many '('"
+msgstr "E872: (wyra¿enie regularne NFA) Zbyt du¿o '('"
+
+msgid "E879: (NFA regexp) Too many \\z("
+msgstr "E879: (wyra¿enie regularne NFA) Za du¿o \\z("
+
+msgid "E873: (NFA regexp) proper termination error"
+msgstr "E873: (wyra¿enie regularne NFA) b³±d poprawnego zakoñczenia"
+
+msgid "E874: (NFA) Could not pop the stack !"
+msgstr "E874: (NFA) Nie mo¿na zdj±æ elementu ze stosu!"
+
+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"
+
+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 "
+
+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 ""
+"Could not open temporary log file for writing, displaying on stderr ... "
+msgstr "Nie mo¿na otworzyæ do zapisu tymczasowego pliku, pokazujê na stderr... "
+
+#, c-format
+msgid "(NFA) COULD NOT OPEN %s !"
+msgstr "(NFA) NIE MO¯NA OTWORZYÆ %s !"
+
+msgid "Could not open temporary log file for writing "
+msgstr "Nie mo¿na otworzyæ do zapisu tymczasowego pliku logowania"
+
+msgid " VREPLACE"
+msgstr " V-ZAMIANA"
+
+msgid " REPLACE"
+msgstr " ZAMIANA"
+
+msgid " REVERSE"
+msgstr " NEGATYW"
+
+msgid " INSERT"
+msgstr " WPROWADZANIE"
+
+msgid " (insert)"
+msgstr " (wprowadzanie)"
+
+msgid " (replace)"
+msgstr " (zamiana)"
+
+msgid " (vreplace)"
+msgstr " (v-zamiana)"
+
+msgid " Hebrew"
+msgstr " Hebrajski"
+
+msgid " Arabic"
+msgstr " Arabski"
+
+msgid " (lang)"
+msgstr " (jêzyk)"
+
+msgid " (paste)"
+msgstr " (wklejanie)"
+
+msgid " VISUAL"
+msgstr " WIZUALNY"
+
+msgid " VISUAL LINE"
+msgstr " WIZUALNY LINIOWY"
+
+msgid " VISUAL BLOCK"
+msgstr " WIZUALNY BLOKOWY"
+
+msgid " SELECT"
+msgstr " ZAZNACZANIE"
+
+msgid " SELECT LINE"
+msgstr " ZAZNACZANIE LINIOWE"
+
+msgid " SELECT BLOCK"
+msgstr " ZAZNACZANIE BLOKOWE"
+
+msgid "recording"
+msgstr "zapis"
+
+#, c-format
+msgid "E383: Invalid search string: %s"
+msgstr "E383: Niew³a¶ciwy ci±g do szukania: %s"
+
+#, c-format
+msgid "E384: search hit TOP without match for: %s"
+msgstr "E384: szukanie dobi³o GÓRY bez znalezienia: %s"
+
+#, c-format
+msgid "E385: search hit BOTTOM without match for: %s"
+msgstr "E385: szukanie dobi³o KOÑCA bez znalezienia : %s"
+
+msgid "E386: Expected '?' or '/' after ';'"
+msgstr "E386: Oczekujê '?' lub '/' po ';'"
+
+msgid " (includes previously listed match)"
+msgstr " (zawiera poprzednio wymienione dopasowanie)"
+
+#. cursor at status line
+msgid "--- Included files "
+msgstr "--- Zawarte pliki "
+
+msgid "not found "
+msgstr "nie znaleziono"
+
+msgid "in path ---\n"
+msgstr "w tropie ---\n"
+
+msgid " (Already listed)"
+msgstr " (Ju¿ wymienione)"
+
+msgid " NOT FOUND"
+msgstr " NIE ZNALEZIONO"
+
+#, c-format
+msgid "Scanning included file: %s"
+msgstr "Przegl±d w³±czonego pliku: %s"
+
+#, c-format
+msgid "Searching included file %s"
+msgstr "Przeszukiwanie w³±czonego pliku %s"
+
+msgid "E387: Match is on current line"
+msgstr "E387: Wzorzec pasuje w bie¿±cym wierszu"
+
+msgid "All included files were found"
+msgstr "Wszelkie w³±czane pliki odnaleziono"
+
+msgid "No included files"
+msgstr "Brak w³±czanych plików"
+
+msgid "E388: Couldn't find definition"
+msgstr "E388: Nie znalaz³em definicji"
+
+msgid "E389: Couldn't find pattern"
+msgstr "E389: Nie znalaz³em wzorca"
+
+msgid "Substitute "
+msgstr "Podstawienie "
+
+#, c-format
+msgid ""
+"\n"
+"# Last %sSearch Pattern:\n"
+"~"
+msgstr ""
+"\n"
+"# Ostatni %sWyszukiwany wzorzec:\n"
+"~"
+
+msgid "E759: Format error in spell file"
+msgstr "E759: Nieprawid³owy format pliku sprawdzania pisowni"
+
+msgid "E758: Truncated spell file"
+msgstr "E758: Obciêty plik sprawdzania pisowni"
+
+#, c-format
+msgid "Trailing text in %s line %d: %s"
+msgstr "Zbêdny tekst w %s wiersz %d: %s"
+
+#, c-format
+msgid "Affix name too long in %s line %d: %s"
+msgstr "Za d³uga nazwa afiksu w %s wiersz %d: %s"
+
+msgid "E761: Format error in affix file FOL, LOW or UPP"
+msgstr "E761: B³±d formatu w pliku afiksów FOL, LOW lub UPP"
+
+msgid "E762: Character in FOL, LOW or UPP is out of range"
+msgstr "E762: Znak w FOL, LOW lub UPP jest poza zasiêgiem"
+
+msgid "Compressing word tree..."
+msgstr "Kompresja drzewa s³ów..."
+
+msgid "E756: Spell checking is not enabled"
+msgstr "E756: Sprawdzanie pisowni nie jest w³±czone"
+
+#, 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\""
+
+#, 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\""
+
+#, c-format
+msgid "Reading spell file \"%s\""
+msgstr "Odczytujê plik sprawdzania pisowni \"%s\""
+
+msgid "E757: This does not look like a spell file"
+msgstr "E757: To nie wygl±da na plik sprawdzania pisowni"
+
+msgid "E771: Old spell file, needs to be updated"
+msgstr "E771: Stary plik sprawdzania pisowni, wymagane uaktualnienie"
+
+msgid "E772: Spell file is for newer version of Vim"
+msgstr "E772: Plik sprawdzania pisowni dla nowszej wersji Vima"
+
+msgid "E770: Unsupported section in spell file"
+msgstr "E770: Niewspierana sekcja w pliku sprawdzania pisowni"
+
+#, c-format
+msgid "Warning: region %s not supported"
+msgstr "Ostrze¿enie: region %s nie jest wspierany"
+
+#, c-format
+msgid "Reading affix file %s ..."
+msgstr "Czytam plik afiksów %s ..."
+
+#, 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"
+
+#, c-format
+msgid "Conversion in %s not supported: from %s to %s"
+msgstr "Konwersja w %s nie jest wspierana: od %s do %s"
+
+#, c-format
+msgid "Conversion in %s not supported"
+msgstr "Konwersja w %s nie jest wspierana"
+
+#, c-format
+msgid "Invalid value for FLAG in %s line %d: %s"
+msgstr "Nieprawid³owa warto¶æ FLAG w %s wierz %d: %s"
+
+#, c-format
+msgid "FLAG after using flags in %s line %d: %s"
+msgstr "FLAG po u¿yciu flag w %s wiersz %d: %s"
+
+#, 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"
+
+#, 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"
+
+#, c-format
+msgid "Wrong COMPOUNDRULES value in %s line %d: %s"
+msgstr "Z³a warto¶æ COMPOUNDRULES w %s wiersz %d: %s"
+
+#, c-format
+msgid "Wrong COMPOUNDWORDMAX value in %s line %d: %s"
+msgstr "Z³a warto¶æ COMPOUNDWORDMAX w %s wiersz %d: %s"
+
+#, c-format
+msgid "Wrong COMPOUNDMIN value in %s line %d: %s"
+msgstr "Z³a warto¶æ COMPOUNDMIM w %s wiersz %d: %s"
+
+#, c-format
+msgid "Wrong COMPOUNDSYLMAX value in %s line %d: %s"
+msgstr "Z³a warto¶æ COMPOUNDSYLMAX w %s wiersz %d: %s"
+
+#, c-format
+msgid "Wrong CHECKCOMPOUNDPATTERN value in %s line %d: %s"
+msgstr "Z³a warto¶æ CHECKCOMPOUNDPATTERN w %s wiersz %d: %s"
+
+#, 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"
+
+#, c-format
+msgid "Duplicate affix in %s line %d: %s"
+msgstr "Powtórzony afiks w %s wiersz %d: %s"
+
+#, 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"
+
+#, c-format
+msgid "Expected Y or N in %s line %d: %s"
+msgstr "Oczekiwano Y lub N w %s wierszu %d: %s"
+
+#, c-format
+msgid "Broken condition in %s line %d: %s"
+msgstr "B³êdny warunek w %s wiersz %d: %s"
+
+#, c-format
+msgid "Expected REP(SAL) count in %s line %d"
+msgstr "Oczekiwano ilo¶ci REP(SAL) w %s wierszu %d"
+
+#, c-format
+msgid "Expected MAP count in %s line %d"
+msgstr "Oczekiwano ilo¶ci MAP w %s wierszu %d"
+
+#, c-format
+msgid "Duplicate character in MAP in %s line %d"
+msgstr "Powtórzony znak w MAP w %s wierszu %d"
+
+#, c-format
+msgid "Unrecognized or duplicate item in %s line %d: %s"
+msgstr "Nieznany lub powtórzony element w %s wierszu %d: %s"
+
+#, c-format
+msgid "Missing FOL/LOW/UPP line in %s"
+msgstr "Brak wiersza FOL/LOW/UPP w %s"
+
+msgid "COMPOUNDSYLMAX used without SYLLABLE"
+msgstr "COMPOUNDSYLMAX u¿yty bez SYLLABLE"
+
+msgid "Too many postponed prefixes"
+msgstr "Zbyt wiele opó¼nionych prefiksów"
+
+msgid "Too many compound flags"
+msgstr "Zbyt wiele flag z³o¿eñ"
+
+msgid "Too many postponed prefixes and/or compound flags"
+msgstr "Zbyt wiele opó¼nionych prefiksów i/lub flag z³o¿eñ"
+
+#, c-format
+msgid "Missing SOFO%s line in %s"
+msgstr "Brak wiersza SOFO%s wiersz w %s"
+
+#, c-format
+msgid "Both SAL and SOFO lines in %s"
+msgstr "Wiersze SAL i SOFO w %s"
+
+#, c-format
+msgid "Flag is not a number in %s line %d: %s"
+msgstr "Flaga nie jest liczb± w %s wiersz %d: %s"
+
+#, c-format
+msgid "Illegal flag in %s line %d: %s"
+msgstr "Nieprawid³owa flaga w %s wiersz %d: %s"
+
+#, 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"
+
+#, c-format
+msgid "Reading dictionary file %s ..."
+msgstr "Czytam plik s³ownika %s ..."
+
+#, c-format
+msgid "E760: No word count in %s"
+msgstr "E760: Brak ilo¶ci s³ów w %s"
+
+#, c-format
+msgid "line %6d, word %6d - %s"
+msgstr "wiersz %6d, s³owo %6d - %s"
+
+# c-format
+#, c-format
+msgid "Duplicate word in %s line %d: %s"
+msgstr "Powtórzony wyraz w %s wierszu %d: %s"
+
+# c-format
+#, c-format
+msgid "First duplicate word in %s line %d: %s"
+msgstr "Pierwszy powtórzony wyraz w %s wiersz %d: %s"
+
+# c-format
+#, c-format
+msgid "%d duplicate word(s) in %s"
+msgstr "%d powtórzony(ch) wyraz(ów) w %s"
+
+#, 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"
+
+#, c-format
+msgid "Reading word file %s ..."
+msgstr "Odczytujê plik wyrazów %s ..."
+
+#, c-format
+msgid "Duplicate /encoding= line ignored in %s line %d: %s"
+msgstr "Zignorowano powtórzony wiersz /encoding= w %s wierszu %d: %s"
+
+#, c-format
+msgid "/encoding= line after word ignored in %s line %d: %s"
+msgstr "Zignorowano wiersz /encoding= po wyrazie w %s wierszu %d: %s"
+
+#, c-format
+msgid "Duplicate /regions= line ignored in %s line %d: %s"
+msgstr "Powtórzony wiersz /regions= zignorowano w %s wierszu %d: %s"
+
+#, c-format
+msgid "Too many regions in %s line %d: %s"
+msgstr "Za du¿o regionów w %s wiersz %d: %s"
+
+#, c-format
+msgid "/ line ignored in %s line %d: %s"
+msgstr "wiersz / zignorowano w %s wierszu %d: %s"
+
+#, c-format
+msgid "Invalid region nr in %s line %d: %s"
+msgstr "Nieprawid³owy numer regionu w %s wierszu %d: %s"
+
+#, c-format
+msgid "Unrecognized flags in %s line %d: %s"
+msgstr "Nieznane flagi w %s wiersz %d: %s"
+
+#, c-format
+msgid "Ignored %d words with non-ASCII characters"
+msgstr "Zignorowa³em %d s³ów ze znakami nie ASCII"
+
+msgid "E845: Insufficient memory, word list will be incomplete"
+msgstr "E845: Nie wystarczaj±ca ilo¶æ pamiêci, lista s³ów bêdzie niekompletna"
+
+#, c-format
+msgid "Compressed %d of %d nodes; %d (%d%%) remaining"
+msgstr "Skompresowano %d z %d wêz³ów; pozostaje %d (%d%%)"
+
+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.
+#.
+msgid "Performing soundfolding..."
+msgstr "Wykonujê kompresjê d¼wiêkow±..."
+
+#, c-format
+msgid "Number of words after soundfolding: %ld"
+msgstr "Liczba s³ów po kompresji d¼wiêkowej: %ld"
+
+#, c-format
+msgid "Total number of words: %d"
+msgstr "Ca³kowita liczba s³ów: %d"
+
+#, c-format
+msgid "Writing suggestion file %s ..."
+msgstr "Zapisujê plik sugestii %s ..."
+
+#, c-format
+msgid "Estimated runtime memory use: %d bytes"
+msgstr "Oczekiwane zu¿ycie pamiêci: %d bajtów"
+
+msgid "E751: Output file name must not have region name"
+msgstr "E751: Nazwa pliku wynikowego nie mo¿e byæ nazw± regionu"
+
+msgid "E754: Only up to 8 regions supported"
+msgstr "E754: Wspieram tylko 8 regionów"
+
+#, c-format
+msgid "E755: Invalid region in %s"
+msgstr "E755: Nieprawid³owy region w %s"
+
+msgid "Warning: both compounding and NOBREAK specified"
+msgstr "Ostrze¿enie: okre¶lono zarówno z³o¿enia jak i NOBREAK"
+
+#, c-format
+msgid "Writing spell file %s ..."
+msgstr "Zapisujê plik sprawdzania pisowni %s ..."
+
+msgid "Done!"
+msgstr "Zrobione!"
+
+#, c-format
+msgid "E765: 'spellfile' does not have %ld entries"
+msgstr "E765: 'spellfile' nie posiada wpisów %ld"
+
+#, c-format
+msgid "Word removed from %s"
+msgstr "Usuniêto s³owo z %s"
+
+#, c-format
+msgid "Word added to %s"
+msgstr "Dodano s³owo do %s"
+
+msgid "E763: Word characters differ between spell files"
+msgstr "E763: Znaki wyrazów ró¿ni± siê miêdzy plikami sprawdzania pisowni"
+
+msgid "Sorry, no suggestions"
+msgstr "Przykro mi, brak podpowiedzi"
+
+#, c-format
+msgid "Sorry, only %ld suggestions"
+msgstr "Przykro mi, tylko %ld podpowiedzi"
+
+#. for when 'cmdheight' > 1
+#. avoid more prompt
+#, c-format
+msgid "Change \"%.*s\" to:"
+msgstr "Zmieñ \"%.*s\" na:"
+
+#, c-format
+msgid " < \"%.*s\""
+msgstr " < \"%.*s\""
+
+msgid "E752: No previous spell replacement"
+msgstr "E752: Brak poprzednich podmian sprawdzania pisowni"
+
+#, c-format
+msgid "E753: Not found: %s"
+msgstr "E753: Nie znaleziono: %s"
+
+#, c-format
+msgid "E778: This does not look like a .sug file: %s"
+msgstr "E778: Ten plik nie wygl±da na plik .sug: %s"
+
+#, c-format
+msgid "E779: Old .sug file, needs to be updated: %s"
+msgstr "E779: Stary plik .sug, konieczne jest uaktualnienie: %s"
+
+#, c-format
+msgid "E780: .sug file is for newer version of Vim: %s"
+msgstr "E780: Plik .sug dla nowszej wersji Vima: %s"
+
+#, c-format
+msgid "E781: .sug file doesn't match .spl file: %s"
+msgstr "E781: Plik .sug nie pasuje do pliku .spl: %s"
+
+#, 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.
+msgid "E783: duplicate char in MAP entry"
+msgstr "E783: Podwojony znak we wpisie MAP"
+
+msgid "No Syntax items defined for this buffer"
+msgstr "Brak elementów sk³adni okre¶lonych dla tego bufora"
+
+#, c-format
+msgid "E390: Illegal argument: %s"
+msgstr "E390: Niedozwolony argument: %s"
+
+#, c-format
+msgid "E391: No such syntax cluster: %s"
+msgstr "E391: Nie ma takiego klastra sk³adni: %s"
+
+msgid "syncing on C-style comments"
+msgstr "synchronizacja komentarzy w stylu C"
+
+msgid "no syncing"
+msgstr "brak synchronizacji"
+
+msgid "syncing starts "
+msgstr "pocz±tek synchronizacji"
+
+msgid " lines before top line"
+msgstr " wierszy przed górn± lini±"
+
+msgid ""
+"\n"
+"--- Syntax sync items ---"
+msgstr ""
+"\n"
+"--- Elementy synchronizacji sk³adni ---"
+
+msgid ""
+"\n"
+"syncing on items"
+msgstr ""
+"\n"
+"synchronizujê na elementach"
+
+msgid ""
+"\n"
+"--- Syntax items ---"
+msgstr ""
+"\n"
+"--- Elementy sk³adni ---"
+
+#, c-format
+msgid "E392: No such syntax cluster: %s"
+msgstr "E392: Nie ma takiego klastra sk³adni: %s"
+
+msgid "minimal "
+msgstr "minimalnie "
+
+msgid "maximal "
+msgstr "maksymalnie "
+
+msgid "; match "
+msgstr "; pasuje "
+
+msgid " line breaks"
+msgstr "znaków nowego wiersza"
+
+msgid "E395: contains argument not accepted here"
+msgstr "E395: argument contains niedozwolony w tym miejscu"
+
+msgid "E844: invalid cchar value"
+msgstr "E844: Niew³a¶ciwa warto¶æ cchar"
+
+msgid "E393: group[t]here not accepted here"
+msgstr "E393: group[t]here niedozwolone w tym miejscu"
+
+#, c-format
+msgid "E394: Didn't find region item for %s"
+msgstr "E394: Nie znalaz³em elementów regionu dla %s"
+
+msgid "E397: Filename required"
+msgstr "E397: Wymagana nazwa pliku"
+
+msgid "E847: Too many syntax includes"
+msgstr "E847: Za du¿o w³±czonych sk³adni"
+
+#, c-format
+msgid "E789: Missing ']': %s"
+msgstr "E789: Brak ']': %s"
+
+#, c-format
+msgid "E398: Missing '=': %s"
+msgstr "E398: Brak '=': %s"
+
+#, c-format
+msgid "E399: Not enough arguments: syntax region %s"
+msgstr "E399: Za ma³o argumentów: syntax region %s"
+
+msgid "E848: Too many syntax clusters"
+msgstr "E848: Za du¿o klastrów sk³adni"
+
+msgid "E400: No cluster specified"
+msgstr "E400: Brak specyfikacji klastra"
+
+#, c-format
+msgid "E401: Pattern delimiter not found: %s"
+msgstr "E401: Brak ogranicznika wzorca: %s"
+
+#, c-format
+msgid "E402: Garbage after pattern: %s"
+msgstr "E402: ¦mieci po wzorcu: %s"
+
+msgid "E403: syntax sync: line continuations pattern specified twice"
+msgstr "E403: syntax sync: wielokrotnie podane wzorce kontynuacji wiersza"
+
+#, c-format
+msgid "E404: Illegal arguments: %s"
+msgstr "E404: Niedozwolone argumenty: %s"
+
+#, c-format
+msgid "E405: Missing equal sign: %s"
+msgstr "E405: Brak znaku równo¶ci: %s"
+
+#, c-format
+msgid "E406: Empty argument: %s"
+msgstr "E406: Pusty argument: %s"
+
+#, c-format
+msgid "E407: %s not allowed here"
+msgstr "E407: %s jest niedozwolone w tym miejscu"
+
+#, c-format
+msgid "E408: %s must be first in contains list"
+msgstr "E408: %s musi byæ pierwsze w li¶cie contains"
+
+#, c-format
+msgid "E409: Unknown group name: %s"
+msgstr "E409: Nieznana nazwa grupy: %s"
+
+#, c-format
+msgid "E410: Invalid :syntax subcommand: %s"
+msgstr "E410: Niew³a¶ciwa podkomenda :syntax : %s"
+
+msgid ""
+" TOTAL COUNT MATCH SLOWEST AVERAGE NAME PATTERN"
+msgstr ""
+" WSZYTKO ILO¦Æ PASUJE NAJWOLN. ¦REDNIO NAZWA WZORZEC"
+
+msgid "E679: recursive loop loading syncolor.vim"
+msgstr "E679: rekursywna pêtla wczytuj±ca syncolor.vim"
+
+#, c-format
+msgid "E411: highlight group not found: %s"
+msgstr "E411: nie znaleziono grupy pod¶wietlania: %s"
+
+#, c-format
+msgid "E412: Not enough arguments: \":highlight link %s\""
+msgstr "E412: Zbyt ma³o argumentów: \":highlight link %s\""
+
+#, c-format
+msgid "E413: Too many arguments: \":highlight link %s\""
+msgstr "E413: Zbyt wiele argumentów: \":highlight link %s\""
+
+msgid "E414: group has settings, highlight link ignored"
+msgstr "E414: grupa ma ustawienia; zignorowane pod³±czenie pod¶wietlania"
+
+#, c-format
+msgid "E415: unexpected equal sign: %s"
+msgstr "E415: nieoczekiwany znak równo¶ci: %s"
+
+#, c-format
+msgid "E416: missing equal sign: %s"
+msgstr "E416: brak znaku równo¶ci: %s"
+
+#, c-format
+msgid "E417: missing argument: %s"
+msgstr "E417: brak argumentu: %s"
+
+#, c-format
+msgid "E418: Illegal value: %s"
+msgstr "E418: Niedozwolona warto¶æ: %s"
+
+msgid "E419: FG color unknown"
+msgstr "E419: Kolor FG nieznany"
+
+msgid "E420: BG color unknown"
+msgstr "E420: Kolor BG nieznany"
+
+#, c-format
+msgid "E421: Color name or number not recognized: %s"
+msgstr "E421: Nazwa lub liczba koloru nierozpoznana: %s"
+
+#, c-format
+msgid "E422: terminal code too long: %s"
+msgstr "E422: za d³ugi kod terminala: %s"
+
+#, c-format
+msgid "E423: Illegal argument: %s"
+msgstr "E423: Niedozwolony argument: %s"
+
+msgid "E424: Too many different highlighting attributes in use"
+msgstr "E424: Zbyt wiele ró¿nych atrybutów podkre¶lania w u¿yciu"
+
+msgid "E669: Unprintable character in group name"
+msgstr "E669: Niedrukowalny znak w nazwie grupy"
+
+msgid "W18: Invalid character in group name"
+msgstr "W18: nieprawid³owy znak w nazwie grupy"
+
+msgid "E849: Too many highlight and syntax groups"
+msgstr "E849: Za du¿o grup pod¶wietlania i sk³adni"
+
+msgid "E555: at bottom of tag stack"
+msgstr "E555: na dole stosu znaczników"
+
+msgid "E556: at top of tag stack"
+msgstr "E556: na górze stosu znaczników"
+
+msgid "E425: Cannot go before first matching tag"
+msgstr "E425: Nie mo¿na przej¶æ przed pierwszy pasuj±cy znacznik"
+
+#, c-format
+msgid "E426: tag not found: %s"
+msgstr "E426: nie znaleziono znacznika: %s"
+
+msgid " # pri kind tag"
+msgstr " # pri rodzaj znacznik"
+
+msgid "file\n"
+msgstr "plik\n"
+
+msgid "E427: There is only one matching tag"
+msgstr "E427: Pasuje tylko jeden znacznik"
+
+msgid "E428: Cannot go beyond last matching tag"
+msgstr "E428: Nie mo¿na przej¶æ za ostatni pasuj±cy znacznik"
+
+#, c-format
+msgid "File \"%s\" does not exist"
+msgstr "Plik \"%s\" nie istnieje"
+
+#. Give an indication of the number of matching tags
+#, c-format
+msgid "tag %d of %d%s"
+msgstr "znacznik %d z %d%s"
+
+msgid " or more"
+msgstr " lub wiêcej"
+
+msgid " Using tag with different case!"
+msgstr " U¿ywam znacznika o odmiennej wielko¶ci liter!"
+
+#, c-format
+msgid "E429: File \"%s\" does not exist"
+msgstr "E429: Plik \"%s\" nie istnieje"
+
+#. Highlight title
+msgid ""
+"\n"
+" # TO tag FROM line in file/text"
+msgstr ""
+"\n"
+" # DO znacznik OD wiersza w pliku/tek¶cie"
+
+#, c-format
+msgid "Searching tags file %s"
+msgstr "Szukam w pliku znaczników %s"
+
+#, c-format
+msgid "E430: Tag file path truncated for %s\n"
+msgstr "E430: Trop szukania pliku znaczników obciêty dla %s\n"
+
+msgid "Ignoring long line in tags file"
+msgstr "Ignorujê d³ugie wiersze w pliku znaczników"
+
+#, c-format
+msgid "E431: Format error in tags file \"%s\""
+msgstr "E431: B³±d formatu w pliku znaczników \"%s\""
+
+#, c-format
+msgid "Before byte %ld"
+msgstr "Przed bajtem %ld"
+
+#, c-format
+msgid "E432: Tags file not sorted: %s"
+msgstr "E432: Plik znaczników nieuporz±dkowany: %s"
+
+#. never opened any tags file
+msgid "E433: No tags file"
+msgstr "E433: Brak pliku znaczników"
+
+msgid "E434: Can't find tag pattern"
+msgstr "E434: Nie mogê znale¼æ wzorca znacznika"
+
+msgid "E435: Couldn't find tag, just guessing!"
+msgstr "E435: Nie znalaz³em znacznika - tylko zgadujê!"
+
+#, c-format
+msgid "Duplicate field name: %s"
+msgstr "Powtórzona nazwa pola: %s"
+
+msgid "' not known. Available builtin terminals are:"
+msgstr "' nieznany. Mo¿liwe typy wbudowanych terminali:"
+
+msgid "defaulting to '"
+msgstr "domy¶lnie jest '"
+
+msgid "E557: Cannot open termcap file"
+msgstr "E557: Nie mogê otworzyæ pliku termcap"
+
+msgid "E558: Terminal entry not found in terminfo"
+msgstr "E558: Nie ma opisu takiego terminala w terminfo"
+
+msgid "E559: Terminal entry not found in termcap"
+msgstr "E559: Nie ma opisu takiego terminala w termcap"
+
+#, c-format
+msgid "E436: No \"%s\" entry in termcap"
+msgstr "E436: Brak opisu \"%s\" w termcap"
+
+msgid "E437: terminal capability \"cm\" required"
+msgstr "E437: wymagana zdolno¶æ \"cm\" terminala"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Terminal keys ---"
+msgstr ""
+"\n"
+"--- Klawisze terminala ---"
+
+msgid "new shell started\n"
+msgstr "uruchomiono now± pow³okê\n"
+
+msgid "Vim: Error reading input, exiting...\n"
+msgstr "Vim: B³±d podczas wczytywania wej¶cia, koñczê...\n"
+
+msgid "Used CUT_BUFFER0 instead of empty selection"
+msgstr "U¿ywam CUT_BUFFER0 zamiast pustego wyboru"
+
+#. This happens when the FileChangedRO autocommand changes the
+#. * file in a way it becomes shorter.
+msgid "E834: Line count changed unexpectedly"
+msgstr "E834: Niespodziewana zmiana ilo¶ci linii"
+
+#. must display the prompt
+msgid "No undo possible; continue anyway"
+msgstr "Cofniêcie niemo¿liwe; mimo to kontynuujê"
+
+#, c-format
+msgid "E828: Cannot open undo file for writing: %s"
+msgstr "E828: Nie mogê otworzyæ do zapisu pliku undo: %s"
+
+#, c-format
+msgid "E825: Corrupted undo file (%s): %s"
+msgstr "E825: Uszkodzony plik undo (%s): %s"
+
+msgid "Cannot write undo file in any directory in 'undodir'"
+msgstr "Nie mo¿na zapisaæ pliku undo w ¿adnym katalogu z 'undodir'"
+
+#, c-format
+msgid "Will not overwrite with undo file, cannot read: %s"
+msgstr "Nie nadpiszê plikiem undo, nie mogê odczytaæ: %s"
+
+#, c-format
+msgid "Will not overwrite, this is not an undo file: %s"
+msgstr "Nie nadpiszê, to nie jest plik undo: %s"
+
+msgid "Skipping undo file write, nothing to undo"
+msgstr "Pomijam zapis pliku undo, nic do cofniêcia"
+
+#, c-format
+msgid "Writing undo file: %s"
+msgstr "Zapisujê plik undo: %s"
+
+#, c-format
+msgid "E829: write error in undo file: %s"
+msgstr "E829: B³±d zapisu w pliku undo: %s"
+
+#, c-format
+msgid "Not reading undo file, owner differs: %s"
+msgstr "Nie wczytujê pliku undo, inny w³a¶ciciel: %s"
+
+#, c-format
+msgid "Reading undo file: %s"
+msgstr "Wczytujê plik undo: %s"
+
+#, c-format
+msgid "E822: Cannot open undo file for reading: %s"
+msgstr "E822: Nie mogê otworzyæ pliku undo do odczytu: %s"
+
+#, c-format
+msgid "E823: Not an undo file: %s"
+msgstr "E823: To nie jest plik undo: %s"
+
+#, c-format
+msgid "E832: Non-encrypted file has encrypted undo file: %s"
+msgstr "E832: Nie zaszyfrowany plik ma zaszyfrowany plik undo: %s"
+
+#, c-format
+msgid "E826: Undo file decryption failed: %s"
+msgstr "E826: Nie powiod³o siê odszyfrowywanie pliku undo: %s"
+
+#, c-format
+msgid "E827: Undo file is encrypted: %s"
+msgstr "E827: Plik undo jest zaszyfrowany: %s"
+
+#, c-format
+msgid "E824: Incompatible undo file: %s"
+msgstr "E824: Niekompatybilny plik undo: %s"
+
+msgid "File contents changed, cannot use undo info"
+msgstr "Zawarto¶æ pliku siê zmieni³a, nie mogê u¿yæ pliku undo"
+
+#, c-format
+msgid "Finished reading undo file %s"
+msgstr "Skoñczono wczytywanie pliku undo %s"
+
+msgid "Already at oldest change"
+msgstr "Ju¿ w miejscu ostatniej zmiany"
+
+msgid "Already at newest change"
+msgstr "Ju¿ w miejscu najnowszej zmiany"
+
+#, c-format
+msgid "E830: Undo number %ld not found"
+msgstr "E830: Nie znaleziono numeru cofniêcia %ld"
+
+msgid "E438: u_undo: line numbers wrong"
+msgstr "E438: u_undo: niew³a¶ciwe numery wierszy"
+
+msgid "more line"
+msgstr "1 wiersz wiêcej"
+
+msgid "more lines"
+msgstr "wiêcej wierszy"
+
+msgid "line less"
+msgstr "1 wiersz mniej"
+
+msgid "fewer lines"
+msgstr "mniej wierszy"
+
+msgid "change"
+msgstr "1 zmiana"
+
+msgid "changes"
+msgstr "zmiany"
+
+#, c-format
+msgid "%ld %s; %s #%ld %s"
+msgstr "%ld %s; %s #%ld %s"
+
+msgid "before"
+msgstr "przed"
+
+msgid "after"
+msgstr "za"
+
+msgid "Nothing to undo"
+msgstr "Nie ma zmian do cofniêcia"
+
+msgid "number changes when saved"
+msgstr "liczba zmiany kiedy zapisano"
+
+#, c-format
+msgid "%ld seconds ago"
+msgstr "%ld sekund temu"
+
+msgid "E790: undojoin is not allowed after undo"
+msgstr "E790: undojoin nie jest dozwolone po undo"
+
+msgid "E439: undo list corrupt"
+msgstr "E439: uszkodzona lista cofania"
+
+msgid "E440: undo line missing"
+msgstr "E440: brak wiersza cofania"
+
+#. Only MS VC 4.1 and earlier can do Win32s
+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"
+"Included patches: "
+msgstr ""
+"\n"
+"Zadane ³aty: "
+
+msgid ""
+"\n"
+"Extra patches: "
+msgstr ""
+"\n"
+"Ekstra ³aty: "
+
+msgid "Modified by "
+msgstr "Zmieniony przez "
+
+msgid ""
+"\n"
+"Compiled "
+msgstr ""
+"\n"
+"Skompilowany "
+
+msgid "by "
+msgstr "przez "
+
+msgid ""
+"\n"
+"Huge version "
+msgstr ""
+"\n"
+"Olbrzymia wersja "
+
+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 "without GUI."
+msgstr "bez GUI."
+
+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 " Features included (+) or not (-):\n"
+msgstr " Opcje w³±czone (+) lub nie (-):\n"
+
+msgid " system vimrc file: \""
+msgstr " vimrc systemu: \""
+
+msgid " user vimrc file: \""
+msgstr " vimrc u¿ytkownika: \""
+
+msgid " 2nd user vimrc file: \""
+msgstr " 2-gi plik vimrc u¿ytkownika: \""
+
+msgid " 3rd user vimrc file: \""
+msgstr " 3-ci plik vimrc u¿ytkownika: \""
+
+msgid " user exrc file: \""
+msgstr " exrc u¿ytkownika: \""
+
+msgid " 2nd user exrc file: \""
+msgstr " 2-gi plik exrc u¿ytkownika: \""
+
+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 " fall-back for $VIM: \""
+msgstr " odwet dla $VIM-a: \""
+
+msgid " f-b for $VIMRUNTIME: \""
+msgstr "f-b dla $VIMRUNTIME: \""
+
+msgid "Compilation: "
+msgstr "Kompilacja: "
+
+msgid "Compiler: "
+msgstr "Kompilator: "
+
+msgid "Linking: "
+msgstr "Konsolidacja: "
+
+msgid " DEBUG BUILD"
+msgstr " KOMPILACJA DEBUG"
+
+msgid "VIM - Vi IMproved"
+msgstr "VIM - Vi rozbudowany"
+
+msgid "version "
+msgstr "wersja "
+
+msgid "by Bram Moolenaar et al."
+msgstr "Autor: Bram Moolenaar i Inni."
+
+msgid "Vim is open source and freely distributable"
+msgstr "Vim jest open source i rozprowadzany darmowo"
+
+msgid "Help poor children in Uganda!"
+msgstr "Pomó¿ biednym dzieciom w Ugandzie!"
+
+msgid "type :help iccf<Enter> for information "
+msgstr "wprowad¼ :help iccf<Enter> dla informacji o tym "
+
+msgid "type :q<Enter> to exit "
+msgstr "wprowad¼ :q<Enter> zakoñczenie programu "
+
+msgid "type :help<Enter> or <F1> for on-line help"
+msgstr "wprowad¼ :help<Enter> lub <F1> pomoc na bie¿±co "
+
+msgid "type :help version7<Enter> for version info"
+msgstr "wprowad¼ :help version7<Enter> dla informacji o wersji"
+
+msgid "Running in Vi compatible mode"
+msgstr "Dzia³am w trybie zgodno¶ci z Vi"
+
+msgid "type :set nocp<Enter> for Vim defaults"
+msgstr "wprowad¼ :set nocp<Enter> warto¶ci domy¶lne Vim-a"
+
+msgid "type :help cp-default<Enter> for info on this"
+msgstr "wprowad¼ :help cp-default<Enter> dla informacji to tym "
+
+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 "Sponsor Vim development!"
+msgstr "Sponsoruj rozwój Vima!"
+
+msgid "Become a registered Vim user!"
+msgstr "Zostañ zarejestrowanym u¿ytkownikiem Vima!"
+
+msgid "type :help sponsor<Enter> for information "
+msgstr "wprowad¼ :help sponsor<Enter> dla informacji"
+
+msgid "type :help register<Enter> for information "
+msgstr "wprowad¼ :help register<Enter> dla informacji"
+
+msgid "menu Help->Sponsor/Register for information "
+msgstr "menu Pomoc->Sponsoruj/Zarejestruj siê dla informacji"
+
+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 "Already only one window"
+msgstr "Ju¿ jest tylko jeden widok"
+
+msgid "E441: There is no preview window"
+msgstr "E441: Nie ma okna podgl±du"
+
+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"
+
+msgid "E443: Cannot rotate when another window is split"
+msgstr "E443: Nie mogê przekrêciæ, gdy inne okno jest rozdzielone"
+
+msgid "E444: Cannot close last window"
+msgstr "E444: Nie mogê zamkn±æ ostatniego okna"
+
+msgid "E813: Cannot close autocmd window"
+msgstr "E813: Nie mo¿na zamkn±æ okna autocmd"
+
+msgid "E814: Cannot close window, only autocmd window would remain"
+msgstr "E814: Nie mo¿na zamkn±æ okna, zosta³oby tylko okno autocmd"
+
+msgid "E445: Other window contains changes"
+msgstr "E445: Inne okno zawiera zmiany"
+
+msgid "E446: No file name under cursor"
+msgstr "E446: Brak nazwy pliku pod kursorem"
+
+#, c-format
+msgid "E447: Can't find file \"%s\" in path"
+msgstr "E447: Nie mogê znale¼æ pliku \"%s\" w tropie"
+
+#, c-format
+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"
+
+#. Now concatenate
+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 "--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.
+#.
+msgid "E470: Command aborted"
+msgstr "E470: Przerwanie komendy"
+
+msgid "E471: Argument required"
+msgstr "E471: wymagany argument"
+
+msgid "E10: \\ should be followed by /, ? or &"
+msgstr "E10: po \\ powinno byæ /, ? lub &"
+
+msgid "E11: Invalid in command-line window; <CR> executes, CTRL-C quits"
+msgstr ""
+"E11: Niedozwolone w oknie wiersza poleceñ; <CR> wykonuje, CTRL-C opuszcza"
+
+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"
+
+msgid "E171: Missing :endif"
+msgstr "E171: Brak :endif"
+
+msgid "E600: Missing :endtry"
+msgstr "E600: Brak :endtry"
+
+msgid "E170: Missing :endwhile"
+msgstr "E170: Brak :endwhile"
+
+msgid "E170: Missing :endfor"
+msgstr "E170: Brak :endfor"
+
+msgid "E588: :endwhile without :while"
+msgstr "E588: :endwhile bez :while"
+
+msgid "E588: :endfor without :for"
+msgstr "E588: :endfor bez :for"
+
+msgid "E13: File exists (add ! to override)"
+msgstr "E13: Plik istnieje (wymu¶ poprzez !)"
+
+msgid "E472: Command failed"
+msgstr "E472: Komenda nie powiod³a siê"
+
+#, c-format
+msgid "E234: Unknown fontset: %s"
+msgstr "E234: Nieznany zestaw czcionek: %s"
+
+#, c-format
+msgid "E235: Unknown font: %s"
+msgstr "E235: Nieznana czcionka: %s"
+
+#, c-format
+msgid "E236: Font \"%s\" is not fixed-width"
+msgstr "E236: Czcionka \"%s\" nie ma sta³ej szeroko¶ci znaków"
+
+msgid "E473: Internal error"
+msgstr "E473: B³±d wewnêtrzny"
+
+msgid "Interrupted"
+msgstr "Przerwane"
+
+msgid "E14: Invalid address"
+msgstr "E14: Niew³a¶ciwy adres"
+
+msgid "E474: Invalid argument"
+msgstr "E474: Niew³a¶ciwy argument"
+
+#, c-format
+msgid "E475: Invalid argument: %s"
+msgstr "E475: Niew³a¶ciwy argument: %s"
+
+#, c-format
+msgid "E15: Invalid expression: %s"
+msgstr "E15: Niew³a¶ciwe wyra¿enie: %s"
+
+msgid "E16: Invalid range"
+msgstr "E16: Niew³a¶ciwy zakres"
+
+msgid "E476: Invalid command"
+msgstr "E476: Niew³a¶ciwa komenda"
+
+#, c-format
+msgid "E17: \"%s\" is a directory"
+msgstr "E17: \"%s\" jest katalogiem"
+
+#, c-format
+msgid "E364: Library call failed for \"%s()\""
+msgstr "E364: Wywo³anie z biblioteki nie powiod³o siê dla \"%s()\""
+
+#, c-format
+msgid "E448: Could not load library function %s"
+msgstr "E448: Nie mo¿na za³adowaæ funkcji biblioteki %s"
+
+msgid "E19: Mark has invalid line number"
+msgstr "E19: Zak³adka ma niew³a¶ciwy numer wiersza"
+
+msgid "E20: Mark not set"
+msgstr "E20: Zak³adka nienastawiona"
+
+msgid "E21: Cannot make changes, 'modifiable' is off"
+msgstr "E21: Nie mogê wykonaæ zmian, 'modifiable' jest wy³±czone"
+
+msgid "E22: Scripts nested too deep"
+msgstr "E22: Zbyt g³êbokie zagnie¿d¿enie skryptów"
+
+msgid "E23: No alternate file"
+msgstr "E23: Brak pliku zamiany"
+
+msgid "E24: No such abbreviation"
+msgstr "E24: Nie ma takiego skrótu"
+
+msgid "E477: No ! allowed"
+msgstr "E477: Niedozwolone !"
+
+msgid "E25: GUI cannot be used: Not enabled at compile time"
+msgstr "E25: GUI nie mo¿e byæ u¿yte: Nie w³±czono podczas kompilacji"
+
+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"
+
+#, c-format
+msgid "E28: No such highlight group name: %s"
+msgstr "E28: Brak takiej nazwy grupy pod¶wietlania: %s"
+
+msgid "E29: No inserted text yet"
+msgstr "E29: Nie wprowadzono jeszcze ¿adnego tekstu"
+
+msgid "E30: No previous command line"
+msgstr "E30: Nie ma poprzedniego wiersza poleceñ"
+
+msgid "E31: No such mapping"
+msgstr "E31: Nie ma takiego przyporz±dkowania"
+
+msgid "E479: No match"
+msgstr "E479: Brak dopasowañ"
+
+#, c-format
+msgid "E480: No match: %s"
+msgstr "E480: Brak dopasowañ: %s"
+
+msgid "E32: No file name"
+msgstr "E32: Brak nazwy pliku"
+
+msgid "E33: No previous substitute regular expression"
+msgstr "E33: Brak poprzedniego podstawieniowego wyra¿enia regularnego"
+
+msgid "E34: No previous command"
+msgstr "E34: Brak poprzedniej komendy"
+
+msgid "E35: No previous regular expression"
+msgstr "E35: Brak poprzedniego wyra¿enia regularnego"
+
+msgid "E481: No range allowed"
+msgstr "E481: Zakres niedozwolony"
+
+msgid "E36: Not enough room"
+msgstr "E36: Brak miejsca"
+
+#, c-format
+msgid "E247: no registered server named \"%s\""
+msgstr "E247: brak zarejestrowanego serwera o nazwie \"%s\""
+
+#, c-format
+msgid "E482: Can't create file %s"
+msgstr "E482: Nie mogê stworzyæ pliku %s"
+
+msgid "E483: Can't get temp file name"
+msgstr "E483: Nie mogê pobraæ nazwy pliku tymczasowego"
+
+#, c-format
+msgid "E484: Can't open file %s"
+msgstr "E484: Nie mogê otworzyæ pliku %s"
+
+#, c-format
+msgid "E485: Can't read file %s"
+msgstr "E485: Nie mogê odczytaæ pliku %s"
+
+msgid "E37: No write since last change (add ! to override)"
+msgstr "E37: Nie zapisano od ostatniej zmiany (wymu¶ przez !)"
+
+msgid "E38: Null argument"
+msgstr "E38: Zerowy argument"
+
+msgid "E39: Number expected"
+msgstr "E39: Oczekujê liczby"
+
+#, c-format
+msgid "E40: Can't open errorfile %s"
+msgstr "E40: Nie mogê otworzyæ pliku b³êdów %s"
+
+msgid "E233: cannot open display"
+msgstr "E233: nie mogê otworzyæ ekranu"
+
+msgid "E41: Out of memory!"
+msgstr "E41: Pamiêæ wyczerpana!"
+
+msgid "Pattern not found"
+msgstr "Nie znaleziono wzorca"
+
+#, c-format
+msgid "E486: Pattern not found: %s"
+msgstr "E486: Nie znaleziono wzorca: %s"
+
+msgid "E487: Argument must be positive"
+msgstr "E487: Argument musi byæ dodatni"
+
+msgid "E459: Cannot go back to previous directory"
+msgstr "E459: Nie mo¿na przej¶æ do poprzedniego katalogu"
+
+msgid "E42: No Errors"
+msgstr "E42: Brak B³êdów"
+
+msgid "E776: No location list"
+msgstr "E776: Brak listy lokacji"
+
+msgid "E43: Damaged match string"
+msgstr "E43: Popsuty ci±g wzorca"
+
+msgid "E44: Corrupted regexp program"
+msgstr "E44: Zepsuty program wyra¿eñ regularnych"
+
+msgid "E45: 'readonly' option is set (add ! to override)"
+msgstr "E45: opcja 'readonly' jest ustawiona (wymu¶ poprzez !)"
+
+#, c-format
+msgid "E46: Cannot change read-only variable \"%s\""
+msgstr "E46: Nie mogê zmieniæ zmiennej tylko do odczytu \"%s\""
+
+#, c-format
+msgid "E794: Cannot set variable in the sandbox: \"%s\""
+msgstr "E794: Nie mogê ustawiæ zmiennej w piaskownicy: \"%s\""
+
+msgid "E47: Error while reading errorfile"
+msgstr "E47: B³±d w trakcie czytania pliku b³êdów"
+
+msgid "E48: Not allowed in sandbox"
+msgstr "E48: Niedozwolone w piaskownicy"
+
+msgid "E523: Not allowed here"
+msgstr "E523: Niedozwolone w tym miejscu"
+
+msgid "E359: Screen mode setting not supported"
+msgstr "E359: Ustawianie trybu ekranu niewspomagane"
+
+msgid "E49: Invalid scroll size"
+msgstr "E49: Niew³a¶ciwa wielko¶æ przewiniêcia"
+
+msgid "E91: 'shell' option is empty"
+msgstr "E91: opcja 'shell' jest pusta"
+
+msgid "E255: Couldn't read in sign data!"
+msgstr "E255: Nie mog³em wczytaæ danych znaku!"
+
+msgid "E72: Close error on swap file"
+msgstr "E72: B³±d podczas zamykania pliku wymiany"
+
+msgid "E73: tag stack empty"
+msgstr "E73: stos znaczników jest pusty"
+
+msgid "E74: Command too complex"
+msgstr "E74: Komenda jest zbyt skomplikowana"
+
+msgid "E75: Name too long"
+msgstr "E75: Zbyt d³uga nazwa"
+
+msgid "E76: Too many ["
+msgstr "E76: Zbyt wiele ["
+
+msgid "E77: Too many file names"
+msgstr "E77: Zbyt wiele nazw plików"
+
+msgid "E488: Trailing characters"
+msgstr "E488: Nadstêpne znaczki"
+
+msgid "E78: Unknown mark"
+msgstr "E78: Nieznana zak³adka"
+
+msgid "E79: Cannot expand wildcards"
+msgstr "E79: Nie mog± rozwin±æ znaków wieloznacznych"
+
+msgid "E591: 'winheight' cannot be smaller than 'winminheight'"
+msgstr "E591: 'winheight' nie mo¿e byæ mniejsze ni¿ 'winminheight'"
+
+msgid "E592: 'winwidth' cannot be smaller than 'winminwidth'"
+msgstr "E592: 'winwidth' nie mo¿e byæ mniejsze ni¿ 'winminwidth'"
+
+msgid "E80: Error while writing"
+msgstr "E80: B³±d w trakcie zapisu"
+
+msgid "Zero count"
+msgstr "Zerowy licznik"
+
+msgid "E81: Using <SID> not in a script context"
+msgstr "E81: U¿ycie <SID> poza kontekstem skryptu"
+
+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"
+
+#, c-format
+msgid "E685: Internal error: %s"
+msgstr "E685: B³±d wewnêtrzny: %s"
+
+msgid "E363: pattern uses more memory than 'maxmempattern'"
+msgstr "E363: Wzorzec u¿ywa wiêcej pamiêci ni¿ 'maxmempattern'"
+
+msgid "E749: empty buffer"
+msgstr "E749: pusty bufor"
+
+msgid "E682: Invalid search pattern or delimiter"
+msgstr "E682: Niew³a¶ciwy wzorzec wyszukiwania lub delimiter"
+
+msgid "E139: File is loaded in another buffer"
+msgstr "E139: Plik jest za³adowany w innym buforze"
+
+#, c-format
+msgid "E764: Option '%s' is not set"
+msgstr "E764: Nie ustawiono opcji '%s'"
+
+msgid "E850: Invalid register name"
+msgstr "E850: Niew³a¶ciwa nazwa rejestru"
+
+msgid "search hit TOP, continuing at BOTTOM"
+msgstr "szukanie dobi³o GÓRY; kontynuacja od KOÑCA"
+
+msgid "search hit BOTTOM, continuing at TOP"
+msgstr "szukanie dobi³o KOÑCA; kontynuacja od GÓRY"
+
+#, c-format
+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"
+
+#, c-format
+msgid "failed to add key '%s' to dictionary"
+msgstr "nie powiod³o siê dodanie klucza '%s' do s³ownika"
+
+#, c-format
+msgid "index must be int or slice, not %s"
+msgstr "indeks musi byæ liczb± lub wycinkiem, nie %s"
+
+#, c-format
+msgid "expected str() or unicode() instance, but got %s"
+msgstr "czeka³em na str() lub unicode(), a dosta³em %s"
+
+#, c-format
+msgid "expected bytes() or str() instance, but got %s"
+msgstr "czeka³em na bytes() lub str(), a dosta³em %s"
+
+#, c-format
+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"
+
+#, c-format
+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"
+
+#, c-format
+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"
+
+#, c-format
+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"
+
+#, c-format
+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"
+
+#, c-format
+msgid "cannot set attribute %s"
+msgstr "nie mogê ustawiæ atrybutu %s"
+
+msgid "hashtab changed during iteration"
+msgstr "hashtab zmieni³ siê w czasie iteracji"
+
+#, c-format
+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"
+
+#. No more suitable format specifications in python-2.3
+#, c-format
+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"
+
+#, c-format
+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"
+
+#, c-format
+msgid "unnamed function %s does not exist"
+msgstr "nie nazwana funkcja %s nie istnieje"
+
+#, c-format
+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"
+
+#, c-format
+msgid "failed to run function %s"
+msgstr "nie mogê uruchomiæ funkcji %s"
+
+msgid "unable to get option value"
+msgstr "nie mogê pobraæ warto¶ci opcji"
+
+msgid "internal error: unknown option type"
+msgstr "b³±d wewnêtrzny: nieznany typ opcji"
+
+msgid "problem while switching windows"
+msgstr "wyst±pi³ problem w czasie zmiany okien"
+
+#, c-format
+msgid "unable to unset global option %s"
+msgstr "nie mogê wyzerowaæ opcji globalnej %s"
+
+#, c-format
+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"
+
+#, c-format
+msgid "expected vim.Buffer object, but got %s"
+msgstr "oczekiwa³em na obiekt vim.Buffer, a dosta³em %s"
+
+#, c-format
+msgid "failed to switch to buffer %d"
+msgstr "nie przeszed³em do bufora %d"
+
+#, c-format
+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"
+
+#, c-format
+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"
+
+#, c-format
+msgid "unable to convert %s to vim dictionary"
+msgstr "nie mo¿na konwertowaæ %s do s³ownika Vima"
+
+#, c-format
+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/po/pt_BR.po b/src/po/pt_BR.po
new file mode 100644
index 0000000000..a88cf2ca86
--- /dev/null
+++ b/src/po/pt_BR.po
@@ -0,0 +1,6236 @@
+# Brazilian Portuguese Translation for Vim vim:set foldmethod=marker:
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Vim 7.3\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2010-08-04 20:05-0300\n"
+"PO-Revision-Date: 2010-08-04 20:36-0300\n"
+"Last-Translator: Eduardo S. Dobay <edudobay@gmail.com>\n"
+"Language-Team: Brazilian Portuguese <pt-br@li.org>\n"
+"Language: pt_BR\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=ISO-8859-1\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+msgid "E82: Cannot allocate any buffer, exiting..."
+msgstr "E82: Não foi possível alocar nenhum buffer, saindo do Vim..."
+
+msgid "E83: Cannot allocate buffer, using other one..."
+msgstr "E83: Impossível alocar buffer; tentando usar outro..."
+
+msgid "E515: No buffers were unloaded"
+msgstr "E515: Nenhum buffer foi descarregado"
+
+msgid "E516: No buffers were deleted"
+msgstr "E516: Nenhum buffer foi apagado"
+
+msgid "E517: No buffers were wiped out"
+msgstr "E517: Nenhum buffer foi eliminado"
+
+msgid "1 buffer unloaded"
+msgstr "1 buffer descarregado"
+
+#, c-format
+msgid "%d buffers unloaded"
+msgstr "%d buffers descarregados"
+
+msgid "1 buffer deleted"
+msgstr "1 buffer apagado"
+
+#, c-format
+msgid "%d buffers deleted"
+msgstr "%d buffers apagados"
+
+msgid "1 buffer wiped out"
+msgstr "1 buffer eliminado"
+
+#, c-format
+msgid "%d buffers wiped out"
+msgstr "%d buffers eliminados"
+
+msgid "E84: No modified buffer found"
+msgstr "E84: Não foram encontrados buffers modificados"
+
+#. back where we started, didn't find anything.
+msgid "E85: There is no listed buffer"
+msgstr "E85: Não há buffers listados"
+
+#, c-format
+msgid "E86: Buffer %ld does not exist"
+msgstr "E86: Buffer %ld não existe"
+
+msgid "E87: Cannot go beyond last buffer"
+msgstr "E87: Não é possível ir além do último buffer"
+
+msgid "E88: Cannot go before first buffer"
+msgstr "E88: Não é possível ir para antes do primeiro buffer"
+
+#, c-format
+msgid "E89: No write since last change for buffer %ld (add ! to override)"
+msgstr "E89: Alterações no buffer %ld não foram gravadas (adicione ! para forçar)"
+
+msgid "E90: Cannot unload last buffer"
+msgstr "E90: Impossível descarregar último buffer"
+
+msgid "W14: Warning: List of file names overflow"
+msgstr "W14: Aviso: Estouro da lista de nomes de arquivos"
+
+#, c-format
+msgid "E92: Buffer %ld not found"
+msgstr "E92: Buffer %ld não encontrado"
+
+#, c-format
+msgid "E93: More than one match for %s"
+msgstr "E93: Mais de uma correspondência com %s"
+
+#, c-format
+msgid "E94: No matching buffer for %s"
+msgstr "E94: Nenhum buffer coincide com %s"
+
+#, c-format
+msgid "line %ld"
+msgstr "linha %ld"
+
+msgid "E95: Buffer with this name already exists"
+msgstr "E95: Já existe um buffer com esse nome"
+
+msgid " [Modified]"
+msgstr " [Modificado]"
+
+msgid "[Not edited]"
+msgstr "[Não editado]"
+
+msgid "[New file]"
+msgstr "[Novo arquivo]"
+
+msgid "[Read errors]"
+msgstr "[Erros de leitura]"
+
+msgid "[readonly]"
+msgstr "[somente-leitura]"
+
+#, c-format
+msgid "1 line --%d%%--"
+msgstr "1 linha --%d%%--"
+
+#, c-format
+msgid "%ld lines --%d%%--"
+msgstr "%ld linhas --%d%%--"
+
+#, c-format
+msgid "line %ld of %ld --%d%%-- col "
+msgstr "linha %ld de %ld --%d%%-- col "
+
+msgid "[No Name]"
+msgstr "[Sem nome]"
+
+#. must be a help buffer
+msgid "help"
+msgstr "ajuda"
+
+msgid "[Help]"
+msgstr "[Ajuda]"
+
+msgid "[Preview]"
+msgstr "[Visualização]"
+
+msgid "All"
+msgstr "Tudo"
+
+msgid "Bot"
+msgstr "Fim"
+
+msgid "Top"
+msgstr "Topo"
+
+#, c-format
+msgid ""
+"\n"
+"# Buffer list:\n"
+msgstr ""
+"\n"
+"# Lista de buffers:\n"
+
+msgid "[Location List]"
+msgstr "[Lista de locais]"
+
+msgid "[Quickfix List]"
+msgstr "[Lista quickfix]"
+
+msgid "[Scratch]"
+msgstr "[Rascunho]"
+
+msgid ""
+"\n"
+"--- Signs ---"
+msgstr ""
+"\n"
+"--- Sinais ---"
+
+#, c-format
+msgid "Signs for %s:"
+msgstr "Sinais para %s:"
+
+#, c-format
+msgid " line=%ld id=%d name=%s"
+msgstr " linha=%ld id=%d nome=%s"
+
+#, c-format
+msgid "E96: Can not diff more than %ld buffers"
+msgstr "E96: Não é possível usar diff com mais de %ld buffers"
+
+msgid "E810: Cannot read or write temp files"
+msgstr "E810: Não foi possível ler ou gravar arquivos temporários"
+
+msgid "E97: Cannot create diffs"
+msgstr "E97: diff não funcionou"
+
+msgid "Patch file"
+msgstr "Selecionar arquivo de patch"
+
+msgid "E816: Cannot read patch output"
+msgstr "E816: Não foi possível ler o resultado do patch"
+
+msgid "E98: Cannot read diff output"
+msgstr "E98: Não foi possível ler o resultado do diff"
+
+msgid "E99: Current buffer is not in diff mode"
+msgstr "E99: O buffer atual não está no modo diff"
+
+msgid "E793: No other buffer in diff mode is modifiable"
+msgstr "E793: Não há nenhum outro buffer modificável em modo diff"
+
+msgid "E100: No other buffer in diff mode"
+msgstr "E100: Não há nenhum outro buffer no modo diff"
+
+msgid "E101: More than two buffers in diff mode, don't know which one to use"
+msgstr "E101: Há mais de dois buffers no modo diff; não sei quais usar"
+
+#, c-format
+msgid "E102: Can't find buffer \"%s\""
+msgstr "E102: Buffer \"%s\" não encontrado"
+
+#, c-format
+msgid "E103: Buffer \"%s\" is not in diff mode"
+msgstr "E103: Buffer \"%s\" não está no modo diff"
+
+msgid "E787: Buffer changed unexpectedly"
+msgstr "E787: Buffer foi alterado inesperadamente"
+
+msgid "E104: Escape not allowed in digraph"
+msgstr "E104: Caractere escape não é permitido em dígrafos"
+
+msgid "E544: Keymap file not found"
+msgstr "E544: Arquivo de mapa de teclado não encontrado"
+
+msgid "E105: Using :loadkeymap not in a sourced file"
+msgstr "E105: :loadkeymap usado fora de um script Vim"
+
+msgid "E791: Empty keymap entry"
+msgstr "E791: Entrada vazia no mapa de teclado"
+
+msgid " Keyword completion (^N^P)"
+msgstr " Completar palavra-chave (^N^P)"
+
+#. ctrl_x_mode == 0, ^P/^N compl.
+msgid " ^X mode (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)"
+msgstr " modo ^X (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)"
+
+msgid " Whole line completion (^L^N^P)"
+msgstr " Completar linha inteira (^L^N^P)"
+
+msgid " File name completion (^F^N^P)"
+msgstr " Completar nome de arquivo (^F^N^P)"
+
+msgid " Tag completion (^]^N^P)"
+msgstr " Completar marcador (^]^N^P)"
+
+msgid " Path pattern completion (^N^P)"
+msgstr " Completar padrão de caminho (^N^P)"
+
+msgid " Definition completion (^D^N^P)"
+msgstr " Completar definição (^D^N^P)"
+
+msgid " Dictionary completion (^K^N^P)"
+msgstr " Completar do dicionário (^K^N^P)"
+
+msgid " Thesaurus completion (^T^N^P)"
+msgstr " Completar do dicionário de sinônimos (^T^N^P)"
+
+msgid " Command-line completion (^V^N^P)"
+msgstr " Completar da linha de comando (^V^N^P)"
+
+msgid " User defined completion (^U^N^P)"
+msgstr " Completar definido pelo usuário (^U^N^P)"
+
+msgid " Omni completion (^O^N^P)"
+msgstr " Completação inteligente (^O^N^P)"
+
+msgid " Spelling suggestion (s^N^P)"
+msgstr " Sugestão de ortografia (s^N^P)"
+
+msgid " Keyword Local completion (^N^P)"
+msgstr " Completar palavra-chave local (^N^P)"
+
+msgid "Hit end of paragraph"
+msgstr "Fim do parágrafo atingido"
+
+msgid "'dictionary' option is empty"
+msgstr "opção 'dictionary' vazia"
+
+msgid "'thesaurus' option is empty"
+msgstr "opção 'thesaurus' vazia"
+
+#, c-format
+msgid "Scanning dictionary: %s"
+msgstr "Examinando dicionário: %s"
+
+msgid " (insert) Scroll (^E/^Y)"
+msgstr " (inserção) Rolagem (^E/^Y)"
+
+msgid " (replace) Scroll (^E/^Y)"
+msgstr " (substituição) Rolagem (^E/^Y)"
+
+#, c-format
+msgid "Scanning: %s"
+msgstr "Examinando: %s"
+
+msgid "Scanning tags."
+msgstr "Examinando tags."
+
+msgid " Adding"
+msgstr " Adicionando"
+
+#. 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.
+#.
+msgid "-- Searching..."
+msgstr "-- Procurando..."
+
+msgid "Back at original"
+msgstr "De volta ao original"
+
+msgid "Word from other line"
+msgstr "Palavra de outra linha"
+
+msgid "The only match"
+msgstr "A única correspondência"
+
+#, c-format
+msgid "match %d of %d"
+msgstr "correspondência %d de %d"
+
+#, c-format
+msgid "match %d"
+msgstr "correspondência %d"
+
+msgid "E18: Unexpected characters in :let"
+msgstr "E18: Caracteres inesperados em :let"
+
+#, c-format
+msgid "E684: list index out of range: %ld"
+msgstr "E684: índice da lista fora dos limites: %ld"
+
+#, c-format
+msgid "E121: Undefined variable: %s"
+msgstr "E121: Variável indefinida: %s"
+
+msgid "E111: Missing ']'"
+msgstr "E111: ']' faltando"
+
+#, c-format
+msgid "E686: Argument of %s must be a List"
+msgstr "E686: Argumento de %s deve ser uma Lista"
+
+#, c-format
+msgid "E712: Argument of %s must be a List or Dictionary"
+msgstr "E712: Argumento de %s deve ser uma Lista ou Dicionário"
+
+msgid "E713: Cannot use empty key for Dictionary"
+msgstr "E713: Impossível usar chave vazia num Dicionário"
+
+msgid "E714: List required"
+msgstr "E714: Lista requerida"
+
+msgid "E715: Dictionary required"
+msgstr "E715: Dicionário requerido"
+
+#, c-format
+msgid "E118: Too many arguments for function: %s"
+msgstr "E118: Muitos argumentos para a função: %s"
+
+#, c-format
+msgid "E716: Key not present in Dictionary: %s"
+msgstr "E716: Chave inexistente no Dicionário: %s"
+
+#, c-format
+msgid "E122: Function %s already exists, add ! to replace it"
+msgstr "E122: Função %s já existe, adicione ! para substituí-la"
+
+msgid "E717: Dictionary entry already exists"
+msgstr "E717: Entrada do Dicionário já existente"
+
+msgid "E718: Funcref required"
+msgstr "E718: Referência de função (Funcref) requerida"
+
+msgid "E719: Cannot use [:] with a Dictionary"
+msgstr "E719: Não é possível usar [:] com um Dicionário"
+
+#, c-format
+msgid "E734: Wrong variable type for %s="
+msgstr "E734: Variável de tipo errado para %s="
+
+#, c-format
+msgid "E130: Unknown function: %s"
+msgstr "E130: Função desconhecida: %s"
+
+#, c-format
+msgid "E461: Illegal variable name: %s"
+msgstr "E461: Nome ilegal para variável: %s"
+
+msgid "E687: Less targets than List items"
+msgstr "E687: Há menos destinos que itens na Lista"
+
+msgid "E688: More targets than List items"
+msgstr "E688: Há mais destinos que itens na Lista"
+
+msgid "Double ; in list of variables"
+msgstr "; duplo na lista de variáveis"
+
+#, c-format
+msgid "E738: Can't list variables for %s"
+msgstr "E738: Impossível listar variáveis %s"
+
+msgid "E689: Can only index a List or Dictionary"
+msgstr "E689: Só Listas ou Dicionários podem ser indexados"
+
+msgid "E708: [:] must come last"
+msgstr "E708: [:] deve vir por último"
+
+msgid "E709: [:] requires a List value"
+msgstr "E709: [:] requer uma Lista"
+
+msgid "E710: List value has more items than target"
+msgstr "E710: a Lista tem mais itens que o destino"
+
+msgid "E711: List value has not enough items"
+msgstr "E711: a Lista não tem itens suficientes"
+
+msgid "E690: Missing \"in\" after :for"
+msgstr "E690: \"in\" faltando após :for"
+
+#, c-format
+msgid "E107: Missing parentheses: %s"
+msgstr "E107: Parênteses faltando: %s"
+
+#, c-format
+msgid "E108: No such variable: \"%s\""
+msgstr "E108: Variável inexistente: \"%s\""
+
+msgid "E743: variable nested too deep for (un)lock"
+msgstr "E743: variável aninhada demais para ser (des)bloqueada"
+
+msgid "E109: Missing ':' after '?'"
+msgstr "E109: ':' faltando depois de '?'"
+
+msgid "E691: Can only compare List with List"
+msgstr "E691: Uma Lista só pode ser comparada com outra Lista"
+
+msgid "E692: Invalid operation for Lists"
+msgstr "E692: Operação inválida para Listas"
+
+msgid "E735: Can only compare Dictionary with Dictionary"
+msgstr "E735: Um Dicionário só pode ser comparado com outro Dicionário"
+
+msgid "E736: Invalid operation for Dictionary"
+msgstr "E736: Operação inválida para um Dicionário"
+
+msgid "E693: Can only compare Funcref with Funcref"
+msgstr "E693: Funcref só pode ser comparada com outra Funcref"
+
+msgid "E694: Invalid operation for Funcrefs"
+msgstr "E694: Operação inválida para Funcrefs"
+
+msgid "E804: Cannot use '%' with Float"
+msgstr "E804: Não é possível usar '%' com Float"
+
+msgid "E110: Missing ')'"
+msgstr "E110: ')' faltando"
+
+msgid "E695: Cannot index a Funcref"
+msgstr "E695: Não é possível indexar uma Funcref"
+
+#, c-format
+msgid "E112: Option name missing: %s"
+msgstr "E112: Nome de opção faltando: %s"
+
+#, c-format
+msgid "E113: Unknown option: %s"
+msgstr "E113: Opção desconhecida: %s"
+
+#, c-format
+msgid "E114: Missing quote: %s"
+msgstr "E114: Aspas duplas (\") faltando: %s"
+
+#, c-format
+msgid "E115: Missing quote: %s"
+msgstr "E115: Aspas simples (') faltando: %s"
+
+#, c-format
+msgid "E696: Missing comma in List: %s"
+msgstr "E696: Falta uma vírgula na Lista: %s"
+
+#, c-format
+msgid "E697: Missing end of List ']': %s"
+msgstr "E697: Lista não finalizada com ']': %s"
+
+#, c-format
+msgid "E720: Missing colon in Dictionary: %s"
+msgstr "E720: Dois-pontos faltando no Dicionário: %s"
+
+#, c-format
+msgid "E721: Duplicate key in Dictionary: \"%s\""
+msgstr "E721: Chave duplicada no Dicionário: \"%s\""
+
+#, c-format
+msgid "E722: Missing comma in Dictionary: %s"
+msgstr "E722: Vírgula faltando no Dicionário: %s"
+
+#, c-format
+msgid "E723: Missing end of Dictionary '}': %s"
+msgstr "E723: Dicionário não finalizado com '}': %s"
+
+msgid "E724: variable nested too deep for displaying"
+msgstr "E724: variável aninhada demais para ser exibida"
+
+#, c-format
+msgid "E740: Too many arguments for function %s"
+msgstr "E740: Argumentos demais para a função %s"
+
+#, c-format
+msgid "E116: Invalid arguments for function %s"
+msgstr "E116: Argumentos inválidos para a função %s"
+
+#, c-format
+msgid "E117: Unknown function: %s"
+msgstr "E117: Função desconhecida: %s"
+
+#, c-format
+msgid "E119: Not enough arguments for function: %s"
+msgstr "E119: Argumentos insuficientes para a função: %s"
+
+#, c-format
+msgid "E120: Using <SID> not in a script context: %s"
+msgstr "E120: <SID> usado fora de um script: %s"
+
+#, c-format
+msgid "E725: Calling dict function without Dictionary: %s"
+msgstr "E725: Função dict chamada sem um Dicionário: %s"
+
+msgid "E808: Number or Float required"
+msgstr "E808: Número ou Float requerido"
+
+msgid "E699: Too many arguments"
+msgstr "E699: Argumentos demais"
+
+msgid "E785: complete() can only be used in Insert mode"
+msgstr "E785: complete() só pode ser usado no modo de Inserção"
+
+#.
+#. * 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"
+
+#, c-format
+msgid "E737: Key already exists: %s"
+msgstr "E737: Chave já existe: %s"
+
+#, c-format
+msgid "+-%s%3ld lines: "
+msgstr "+-%s%3ld linhas: "
+
+#, c-format
+msgid "E700: Unknown function: %s"
+msgstr "E700: Função desconhecida: %s"
+
+msgid ""
+"&OK\n"
+"&Cancel"
+msgstr ""
+"&OK\n"
+"&Cancelar"
+
+msgid "called inputrestore() more often than inputsave()"
+msgstr "inputrestore() foi chamado mais vezes que inputsave()"
+
+msgid "E786: Range not allowed"
+msgstr "E786: Intervalos não são permitidos"
+
+msgid "E701: Invalid type for len()"
+msgstr "E701: Tipo inválido para len()"
+
+msgid "E726: Stride is zero"
+msgstr "E726: Incremento nulo"
+
+msgid "E727: Start past end"
+msgstr "E727: O início está depois do fim"
+
+msgid "<empty>"
+msgstr "<vazio>"
+
+msgid "E240: No connection to Vim server"
+msgstr "E240: Nenhuma conexão a um servidor do Vim"
+
+#, c-format
+msgid "E241: Unable to send to %s"
+msgstr "E241: Não foi possível enviar para %s"
+
+msgid "E277: Unable to read a server reply"
+msgstr "E277: Não foi possível ler a resposta do servidor"
+
+msgid "E655: Too many symbolic links (cycle?)"
+msgstr "E655: Links simbólicos em excesso (cíclicos?)"
+
+msgid "E258: Unable to send to client"
+msgstr "E258: Não foi possível enviar ao cliente"
+
+msgid "E702: Sort compare function failed"
+msgstr "E702: A função de comparação para a classificação falhou"
+
+msgid "(Invalid)"
+msgstr "(Inválido)"
+
+msgid "E677: Error writing temp file"
+msgstr "E677: Erro ao gravar o arquivo temporário"
+
+msgid "E805: Using a Float as a Number"
+msgstr "E805: Float usado como Número"
+
+msgid "E703: Using a Funcref as a Number"
+msgstr "E703: Funcref usada como Número"
+
+msgid "E745: Using a List as a Number"
+msgstr "E745: Lista usada como Número"
+
+msgid "E728: Using a Dictionary as a Number"
+msgstr "E728: Dicionário usado como Número"
+
+msgid "E729: using Funcref as a String"
+msgstr "E729: Funcref usada como String"
+
+msgid "E730: using List as a String"
+msgstr "E730: Lista usada como String"
+
+msgid "E731: using Dictionary as a String"
+msgstr "E731: Dicionário usado como String"
+
+msgid "E806: using Float as a String"
+msgstr "E806: Float usado como String"
+
+#, c-format
+msgid "E704: Funcref variable name must start with a capital: %s"
+msgstr "E704: Nome de variável Funcref deve começar com letra maiúscula: %s"
+
+#, c-format
+msgid "E705: Variable name conflicts with existing function: %s"
+msgstr "E705: Nome da variável em conflito com função já existente: %s"
+
+#, c-format
+msgid "E706: Variable type mismatch for: %s"
+msgstr "E706: Tipo de variável incoerente para: %s"
+
+#, c-format
+msgid "E795: Cannot delete variable %s"
+msgstr "E795: Impossível excluir variável %s"
+
+#, c-format
+msgid "E741: Value is locked: %s"
+msgstr "E741: Valor bloqueado: %s"
+
+msgid "Unknown"
+msgstr "Desconhecido"
+
+#, c-format
+msgid "E742: Cannot change value of %s"
+msgstr "E742: Não é possível mudar valor de %s"
+
+msgid "E698: variable nested too deep for making a copy"
+msgstr "E698: variável aninhada demais para fazer uma cópia"
+
+#, c-format
+msgid "E123: Undefined function: %s"
+msgstr "E123: Função indefinida: %s"
+
+#, c-format
+msgid "E124: Missing '(': %s"
+msgstr "E124: '(' faltando: %s"
+
+#, c-format
+msgid "E125: Illegal argument: %s"
+msgstr "E125: Argumento inválido: %s"
+
+msgid "E126: Missing :endfunction"
+msgstr "E126: :endfunction faltando"
+
+#, c-format
+msgid "E707: Function name conflicts with variable: %s"
+msgstr "E707: Nome da função em conflito com variável: %s"
+
+#, c-format
+msgid "E127: Cannot redefine function %s: It is in use"
+msgstr "E127: Não é possível redefinir a função %s: ela está em uso"
+
+#, c-format
+msgid "E746: Function name does not match script file name: %s"
+msgstr "E746: Nome da função não coincide com o nome de arquivo do script: %s"
+
+msgid "E129: Function name required"
+msgstr "E129: Nome da função requerido"
+
+#, c-format
+msgid "E128: Function name must start with a capital or contain a colon: %s"
+msgstr "E128: Nome da função deve começar com letra maiúscula ou conter dois-pontos: %s"
+
+#, c-format
+msgid "E131: Cannot delete function %s: It is in use"
+msgstr "E131: Não é possível excluir a função %s: ela está em uso"
+
+msgid "E132: Function call depth is higher than 'maxfuncdepth'"
+msgstr "E132: Profundidade de chamadas de função é maior que 'maxfuncdepth'"
+
+#, c-format
+msgid "calling %s"
+msgstr "chamando %s"
+
+#, c-format
+msgid "%s aborted"
+msgstr "%s cancelada"
+
+#, c-format
+msgid "%s returning #%ld"
+msgstr "%s devolveu #%ld"
+
+#, c-format
+msgid "%s returning %s"
+msgstr "%s devolveu %s"
+
+#, c-format
+msgid "continuing in %s"
+msgstr "continuando em %s"
+
+msgid "E133: :return not inside a function"
+msgstr "E133: :return fora de uma função"
+
+msgid ""
+"\n"
+"# global variables:\n"
+msgstr ""
+"\n"
+"# variáveis globais:\n"
+
+msgid ""
+"\n"
+"\tLast set from "
+msgstr ""
+"\n"
+"\tDefinido pela última vez em "
+
+msgid "No old files"
+msgstr "Não há arquivos antigos"
+
+msgid "Entering Debug mode. Type \"cont\" to continue."
+msgstr "Entrando modo de depuração. Digite \"cont\" para continuar."
+
+#, c-format
+msgid "line %ld: %s"
+msgstr "linha %ld: %s"
+
+#, c-format
+msgid "cmd: %s"
+msgstr "cmdo: %s"
+
+#, c-format
+msgid "Breakpoint in \"%s%s\" line %ld"
+msgstr "Ponto de interrupção em \"%s%s\", linha %ld"
+
+#, c-format
+msgid "E161: Breakpoint not found: %s"
+msgstr "E161: Ponto de interrupção não encontrado: %s"
+
+msgid "No breakpoints defined"
+msgstr "Nenhum ponto de interrupção definido"
+
+#, c-format
+msgid "%3d %s %s line %ld"
+msgstr "%3d %s %s linha %ld"
+
+msgid "E750: First use \":profile start {fname}\""
+msgstr "E750: Primeiro digite \":profile start {nome_arquivo}\""
+
+msgid "Save As"
+msgstr "Salvar como"
+
+#, c-format
+msgid "Save changes to \"%s\"?"
+msgstr "Salvar as alterações em \"%s\"?"
+
+msgid "Untitled"
+msgstr "(Sem título)"
+
+#, c-format
+msgid "E162: No write since last change for buffer \"%s\""
+msgstr "E162: Alterações no buffer \"%s\" não foram gravadas"
+
+msgid "Warning: Entered other buffer unexpectedly (check autocommands)"
+msgstr "Aviso: Entrada inesperada em outro buffer (verifique os autocomandos)"
+
+msgid "E163: There is only one file to edit"
+msgstr "E163: Só há um arquivo para editar"
+
+msgid "E164: Cannot go before first file"
+msgstr "E164: Impossível ir antes do primeiro arquivo"
+
+msgid "E165: Cannot go beyond last file"
+msgstr "E165: Impossível ir além do último arquivo"
+
+#, c-format
+msgid "E666: compiler not supported: %s"
+msgstr "E666: compilador não suportado: %s"
+
+#, c-format
+msgid "Searching for \"%s\" in \"%s\""
+msgstr "Procurando por \"%s\" em \"%s\""
+
+#, c-format
+msgid "Searching for \"%s\""
+msgstr "Procurando por \"%s\""
+
+#, c-format
+msgid "not found in 'runtimepath': \"%s\""
+msgstr "não encontrado em 'runtimepath': \"%s\""
+
+msgid "Source Vim script"
+msgstr "Executar script do Vim"
+
+#, c-format
+msgid "Cannot source a directory: \"%s\""
+msgstr "Impossível executar um diretório: \"%s\""
+
+#, c-format
+msgid "could not source \"%s\""
+msgstr "não foi possível executar \"%s\""
+
+#, c-format
+msgid "line %ld: could not source \"%s\""
+msgstr "linha %ld: não foi possível executar \"%s\""
+
+#, c-format
+msgid "sourcing \"%s\""
+msgstr "executando \"%s\""
+
+#, c-format
+msgid "line %ld: sourcing \"%s\""
+msgstr "linha %ld: executando \"%s\""
+
+#, c-format
+msgid "finished sourcing %s"
+msgstr "fim da execução de %s"
+
+msgid "modeline"
+msgstr "modeline"
+
+msgid "--cmd argument"
+msgstr "argumento --cmd"
+
+msgid "-c argument"
+msgstr "argumento -c"
+
+msgid "environment variable"
+msgstr "variável de ambiente"
+
+msgid "error handler"
+msgstr "tratador de erro"
+
+msgid "W15: Warning: Wrong line separator, ^M may be missing"
+msgstr "W15: Aviso: Separador de linha incorreto; ^M pode estar faltando"
+
+msgid "E167: :scriptencoding used outside of a sourced file"
+msgstr "E167: :scriptencoding usado fora de um script"
+
+msgid "E168: :finish used outside of a sourced file"
+msgstr "E168: :finish usado fora de um script"
+
+#, c-format
+msgid "Current %slanguage: \"%s\""
+msgstr "Idioma atual para %s: \"%s\""
+
+#, c-format
+msgid "E197: Cannot set language to \"%s\""
+msgstr "E197: Impossível definir idioma como \"%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, 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: O destino coincide com a origem"
+
+msgid "1 line moved"
+msgstr "1 linha movida"
+
+#, c-format
+msgid "%ld lines moved"
+msgstr "%ld linhas movidas"
+
+#, c-format
+msgid "%ld lines filtered"
+msgstr "%ld linhas filtradas"
+
+msgid "E135: *Filter* Autocommands must not change current buffer"
+msgstr "E135: Os autocomandos *Filter* não devem modificar o buffer atual"
+
+msgid "[No write since last change]\n"
+msgstr "[Alterações não gravadas]\n"
+
+#, c-format
+msgid "%sviminfo: %s in line: "
+msgstr "%sviminfo: %s na linha: "
+
+msgid "E136: viminfo: Too many errors, skipping rest of file"
+msgstr "E136: viminfo: Há erros demais; abandonando a leitura do arquivo"
+
+#, c-format
+msgid "Reading viminfo file \"%s\"%s%s%s"
+msgstr "Lendo arquivo viminfo \"%s\"%s%s%s"
+
+msgid " info"
+msgstr " info"
+
+msgid " marks"
+msgstr " marcas"
+
+msgid " oldfiles"
+msgstr " arquivos antigos"
+
+msgid " FAILED"
+msgstr " FALHOU"
+
+#. avoid a wait_return for this message, it's annoying
+#, c-format
+msgid "E137: Viminfo file is not writable: %s"
+msgstr "E137: O arquivo viminfo não pode ser escrito: %s"
+
+#, c-format
+msgid "E138: Can't write viminfo file %s!"
+msgstr "E138: Não é possível gravar o arquivo viminfo %s!"
+
+#, c-format
+msgid "Writing viminfo file \"%s\""
+msgstr "Gravando arquivo viminfo \"%s\""
+
+#. Write the info:
+#, c-format
+msgid "# This viminfo file was generated by Vim %s.\n"
+msgstr "# Este arquivo viminfo foi gerado pelo Vim %s.\n"
+
+#, c-format
+msgid ""
+"# You may edit it if you're careful!\n"
+"\n"
+msgstr ""
+"# Você pode editá-lo se for cuidadoso!\n"
+"\n"
+
+#, c-format
+msgid "# Value of 'encoding' when this file was written\n"
+msgstr "# Valor de 'encoding' quando este arquivo foi escrito\n"
+
+msgid "Illegal starting char"
+msgstr "Caractere inicial inválido"
+
+msgid "Write partial file?"
+msgstr "Gravar arquivo parcial?"
+
+msgid "E140: Use ! to write partial buffer"
+msgstr "E140: Use ! para gravar o buffer apenas parcialmente"
+
+#, c-format
+msgid "Overwrite existing file \"%s\"?"
+msgstr "Sobrescrever arquivo existente \"%s\"?"
+
+#, c-format
+msgid "Swap file \"%s\" exists, overwrite anyway?"
+msgstr "O arquivo de troca \"%s\" existe. Sobrescrevê-lo?"
+
+#, c-format
+msgid "E768: Swap file exists: %s (:silent! overrides)"
+msgstr "E768: Arquivo de troca existe: %s (:silent! para forçar)"
+
+#, c-format
+msgid "E141: No file name for buffer %ld"
+msgstr "E141: Sem nome de arquivo para o buffer %ld"
+
+msgid "E142: File not written: Writing is disabled by 'write' option"
+msgstr "E142: Arquivo não gravado: gravação desativada pela opção 'write'"
+
+#, c-format
+msgid ""
+"'readonly' option is set for \"%s\".\n"
+"Do you wish to write anyway?"
+msgstr ""
+"\"%s\" está com a opção 'readonly' (somente-leitura) ativada.\n"
+"Você deseja gravar assim mesmo?"
+
+#, 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 ""
+"As permissões para \"%s\" são somente-leitura.\n"
+"Ainda pode ser possível gravar no arquivo.\n"
+"Você deseja tentar?"
+
+#, c-format
+msgid "E505: \"%s\" is read-only (add ! to override)"
+msgstr "E505: \"%s\" é somente-leitura (adicione ! para forçar)"
+
+msgid "Edit File"
+msgstr "Editar arquivo"
+
+#, c-format
+msgid "E143: Autocommands unexpectedly deleted new buffer %s"
+msgstr "E143: Algum autocomando inesperadamente apagou o buffer %s recém-criado"
+
+msgid "E144: non-numeric argument to :z"
+msgstr "E144: argumento não-numérico passado a :z"
+
+msgid "E145: Shell commands not allowed in rvim"
+msgstr "E145: Comandos do shell não são permitidos no rvim"
+
+msgid "E146: Regular expressions can't be delimited by letters"
+msgstr "E146: Expressões regulares não podem ser delimitadas por letras"
+
+#, c-format
+msgid "replace with %s (y/n/a/q/l/^E/^Y)?"
+msgstr "substituir por %s (y/n/a/q/l/^E/^Y)?"
+
+msgid "(Interrupted) "
+msgstr "(Interrompido) "
+
+msgid "1 match"
+msgstr "1 correspondência"
+
+msgid "1 substitution"
+msgstr "1 substituição"
+
+#, c-format
+msgid "%ld matches"
+msgstr "%ld correspondências"
+
+#, c-format
+msgid "%ld substitutions"
+msgstr "%ld substituições"
+
+msgid " on 1 line"
+msgstr " em 1 linha"
+
+#, c-format
+msgid " on %ld lines"
+msgstr " em %ld linhas"
+
+msgid "E147: Cannot do :global recursive"
+msgstr "E147: :global não pode ser executado recursivamente"
+
+msgid "E148: Regular expression missing from global"
+msgstr "E148: Expressão regular faltando no comando :global"
+
+#, c-format
+msgid "Pattern found in every line: %s"
+msgstr "Padrão encontrado em toda linha: %s"
+
+#, c-format
+msgid ""
+"\n"
+"# Last Substitute String:\n"
+"$"
+msgstr ""
+"\n"
+"# Última string de substituição:\n"
+"$"
+
+msgid "E478: Don't panic!"
+msgstr "E478: Não entre em pânico!"
+
+#, c-format
+msgid "E661: Sorry, no '%s' help for %s"
+msgstr "E661: Desculpe, nenhuma ajuda para %s em '%s'"
+
+#, c-format
+msgid "E149: Sorry, no help for %s"
+msgstr "E149: Desculpe, nenhuma ajuda para %s"
+
+#, c-format
+msgid "Sorry, help file \"%s\" not found"
+msgstr "Desculpe, arquivo de ajuda \"%s\" não encontrado"
+
+#, c-format
+msgid "E150: Not a directory: %s"
+msgstr "E150: Não é um diretório: %s"
+
+#, c-format
+msgid "E152: Cannot open %s for writing"
+msgstr "E152: Não foi possível abrir %s para escrita"
+
+#, c-format
+msgid "E153: Unable to open %s for reading"
+msgstr "E153: Não foi possível abrir %s para leitura"
+
+#, c-format
+msgid "E670: Mix of help file encodings within a language: %s"
+msgstr "E670: Mistura de codificações nos arquivos de ajuda na língua: %s"
+
+#, c-format
+msgid "E154: Duplicate tag \"%s\" in file %s/%s"
+msgstr "E154: Marcador duplicado \"%s\" no arquivo %s/%s"
+
+#, c-format
+msgid "E160: Unknown sign command: %s"
+msgstr "E160: Subcomando sign desconhecido: %s"
+
+msgid "E156: Missing sign name"
+msgstr "E156: Nome do sinal faltando"
+
+msgid "E612: Too many signs defined"
+msgstr "E612: Muitos sinais definidos"
+
+#, c-format
+msgid "E239: Invalid sign text: %s"
+msgstr "E239: Texto de sinal inválido: %s"
+
+#, c-format
+msgid "E155: Unknown sign: %s"
+msgstr "E155: Sinal desconhecido: %s"
+
+msgid "E159: Missing sign number"
+msgstr "E159: Número do sinal faltando"
+
+#, c-format
+msgid "E158: Invalid buffer name: %s"
+msgstr "E158: Nome de buffer inválido: %s"
+
+#, c-format
+msgid "E157: Invalid sign ID: %ld"
+msgstr "E157: ID de sinal inválido: %ld"
+
+msgid " (NOT FOUND)"
+msgstr " (NÃO ENCONTRADO)"
+
+msgid " (not supported)"
+msgstr " (não suportado)"
+
+msgid "[Deleted]"
+msgstr "[Excluído]"
+
+msgid "Entering Ex mode. Type \"visual\" to go to Normal mode."
+msgstr "Entrando no modo Ex. Digite \"visual\" para ir para o modo Normal."
+
+msgid "E501: At end-of-file"
+msgstr "E501: Fim do arquivo"
+
+msgid "E169: Command too recursive"
+msgstr "E169: Comando recursivo demais"
+
+#, c-format
+msgid "E605: Exception not caught: %s"
+msgstr "E605: Exceção não interceptada: %s"
+
+msgid "End of sourced file"
+msgstr "Fim do arquivo executado"
+
+msgid "End of function"
+msgstr "Fim da função"
+
+msgid "E464: Ambiguous use of user-defined command"
+msgstr "E464: Uso ambíguo de comando definido pelo usuário"
+
+msgid "E492: Not an editor command"
+msgstr "E492: Não é um comando do editor"
+
+msgid "E493: Backwards range given"
+msgstr "E493: Intervalo com limites invertidos"
+
+msgid "Backwards range given, OK to swap"
+msgstr "O intervalo dado está com os limites invertidos. OK para reverter"
+
+msgid "E494: Use w or w>>"
+msgstr "E494: Use w ou w>>"
+
+msgid "E319: Sorry, the command is not available in this version"
+msgstr "E319: Desculpe, esse comando não está disponível nesta versão"
+
+msgid "E172: Only one file name allowed"
+msgstr "E172: Só é permitido um nome de arquivo"
+
+msgid "1 more file to edit. Quit anyway?"
+msgstr "Ainda há 1 arquivo para editar. Sair mesmo assim?"
+
+#, c-format
+msgid "%d more files to edit. Quit anyway?"
+msgstr "Há mais %d arquivos para editar. Sair mesmo assim?"
+
+msgid "E173: 1 more file to edit"
+msgstr "E173: Mais 1 arquivo para editar"
+
+#, c-format
+msgid "E173: %ld more files to edit"
+msgstr "E173: Mais %ld arquivos para editar"
+
+msgid "E174: Command already exists: add ! to replace it"
+msgstr "E174: Comando já existe; adicione ! para substituí-lo"
+
+msgid ""
+"\n"
+" Name Args Range Complete Definition"
+msgstr ""
+"\n"
+" Nome Args Intrv Complet. Definição"
+
+msgid "No user-defined commands found"
+msgstr "Nenhum comando definido pelo usuário foi encontrado"
+
+msgid "E175: No attribute specified"
+msgstr "E175: Nenhum atributo foi especificado"
+
+msgid "E176: Invalid number of arguments"
+msgstr "E176: Número inválido de argumentos"
+
+msgid "E177: Count cannot be specified twice"
+msgstr "E177: Quantificador não pode ser especificado duas vezes"
+
+msgid "E178: Invalid default value for count"
+msgstr "E178: Valor padrão inválido para o quantificador"
+
+msgid "E179: argument required for -complete"
+msgstr "E179: argumento necessário para -complete"
+
+#, c-format
+msgid "E181: Invalid attribute: %s"
+msgstr "E181: Atributo inválido: %s"
+
+msgid "E182: Invalid command name"
+msgstr "E182: Nome de comando inválido"
+
+msgid "E183: User defined commands must start with an uppercase letter"
+msgstr "E183: Comandos definidos pelo usuário devem começar com letra maiúscula"
+
+#, c-format
+msgid "E184: No such user-defined command: %s"
+msgstr "E184: Não existe tal comando definido pelo usuário: %s"
+
+#, c-format
+msgid "E180: Invalid complete value: %s"
+msgstr "E180: Valor inválido para -complete: %s"
+
+msgid "E468: Completion argument only allowed for custom completion"
+msgstr "E468: Argumento só é permitido para completação personalizada"
+
+msgid "E467: Custom completion requires a function argument"
+msgstr "E467: Completação automática requer função como argumento"
+
+msgid "unknown"
+msgstr "desconhecido"
+
+#, c-format
+msgid "E185: Cannot find color scheme %s"
+msgstr "E185: Esquema de cores %s não encontrado"
+
+msgid "Greetings, Vim user!"
+msgstr "Saudações, usuário do Vim!"
+
+msgid "E784: Cannot close last tab page"
+msgstr "E784: Não é possível fechar a última aba"
+
+msgid "Already only one tab page"
+msgstr "Já há apenas uma aba"
+
+msgid "Edit File in new window"
+msgstr "Editar arquivo em nova janela"
+
+#, c-format
+msgid "Tab page %d"
+msgstr "Aba %d"
+
+msgid "No swap file"
+msgstr "Sem arquivo de troca"
+
+msgid "Append File"
+msgstr "Adicionar arquivo"
+
+msgid "E747: Cannot change directory, buffer is modified (add ! to override)"
+msgstr "E747: Impossível mudar de diretório, o buffer foi alterado (adicione ! para forçar)"
+
+msgid "E186: No previous directory"
+msgstr "E186: Não há diretório anterior"
+
+msgid "E187: Unknown"
+msgstr "E187: Desconhecido"
+
+msgid "E465: :winsize requires two number arguments"
+msgstr "E465: :winsize requer dois argumentos numéricos"
+
+#, c-format
+msgid "Window position: X %d, Y %d"
+msgstr "Posição da janela: X %d, Y %d"
+
+msgid "E188: Obtaining window position not implemented for this platform"
+msgstr "E188: A obtenção da posição da janela não foi implementada para esta plataforma"
+
+msgid "E466: :winpos requires two number arguments"
+msgstr "E466: :winpos requer dois argumentos numéricos"
+
+msgid "Save Redirection"
+msgstr "Salvar redirecionamento"
+
+msgid "Save View"
+msgstr "Salvar visão atual"
+
+msgid "Save Session"
+msgstr "Salvar sessão"
+
+msgid "Save Setup"
+msgstr "Salvar configurações"
+
+#, c-format
+msgid "E739: Cannot create directory: %s"
+msgstr "E739: Diretório não pode ser criado: %s"
+
+#, c-format
+msgid "E189: \"%s\" exists (add ! to override)"
+msgstr "E189: \"%s\" existe (adicione ! para forçar)"
+
+#, c-format
+msgid "E190: Cannot open \"%s\" for writing"
+msgstr "E190: \"%s\" não pode ser aberto para escrita"
+
+#. set mark
+msgid "E191: Argument must be a letter or forward/backward quote"
+msgstr "E191: Argumento deve ser uma letra ou aspa (` ou ')"
+
+msgid "E192: Recursive use of :normal too deep"
+msgstr "E192: Recursão excessiva de :normal"
+
+msgid "E809: #< is not available without the +eval feature"
+msgstr "E809: #< não está disponível sem o recurso +eval"
+
+msgid "E194: No alternate file name to substitute for '#'"
+msgstr "E194: Sem nome de arquivo alternativo para substituir '#'"
+
+msgid "E495: no autocommand file name to substitute for \"<afile>\""
+msgstr "E495: nenhum nome de arquivo de autocomandos para substituir \"<afile>\""
+
+msgid "E496: no autocommand buffer number to substitute for \"<abuf>\""
+msgstr "E496: nenhum número de buffer de autocomandos para substituir \"<abuf>\""
+
+msgid "E497: no autocommand match name to substitute for \"<amatch>\""
+msgstr "E497: nenhum critério de autocomando para substituir \"<amatch>\""
+
+msgid "E498: no :source file name to substitute for \"<sfile>\""
+msgstr "E498: nenhum nome de arquivo :source para substituir \"<sfile>\""
+
+#, no-c-format
+msgid "E499: Empty file name for '%' or '#', only works with \":p:h\""
+msgstr "E499: Nome de arquivo vazio para '%' ou '#' só funciona com \":p:h\""
+
+msgid "E500: Evaluates to an empty string"
+msgstr "E500: Expressão resulta em string vazia"
+
+msgid "E195: Cannot open viminfo file for reading"
+msgstr "E195: O arquivo viminfo não pode ser aberto para leitura"
+
+msgid "E196: No digraphs in this version"
+msgstr "E196: Sem suporte a dígrafos nesta versão"
+
+msgid "E608: Cannot :throw exceptions with 'Vim' prefix"
+msgstr "E608: Não é possível lançar exceções com o prefixo 'Vim'"
+
+#. always scroll up, don't overwrite
+#, c-format
+msgid "Exception thrown: %s"
+msgstr "Exceção lançada: %s"
+
+#, c-format
+msgid "Exception finished: %s"
+msgstr "Exceção concluída: %s"
+
+#, c-format
+msgid "Exception discarded: %s"
+msgstr "Exceção descartada: %s"
+
+#, c-format
+msgid "%s, line %ld"
+msgstr "%s, linha %ld"
+
+#. always scroll up, don't overwrite
+#, c-format
+msgid "Exception caught: %s"
+msgstr "Exceção interceptada: %s"
+
+#, c-format
+msgid "%s made pending"
+msgstr "%s tornado(s) pendente(s)"
+
+#, c-format
+msgid "%s resumed"
+msgstr "%s continuado(s)"
+
+#, c-format
+msgid "%s discarded"
+msgstr "%s descartado(s)"
+
+msgid "Exception"
+msgstr "Exceção"
+
+msgid "Error and interrupt"
+msgstr "Erro e interrupção"
+
+msgid "Error"
+msgstr "Erro"
+
+#. if (pending & CSTP_INTERRUPT)
+msgid "Interrupt"
+msgstr "Interrupção"
+
+msgid "E579: :if nesting too deep"
+msgstr "E579: :if aninhado demais"
+
+msgid "E580: :endif without :if"
+msgstr "E580: :endif sem :if"
+
+msgid "E581: :else without :if"
+msgstr "E581: :else sem :if"
+
+msgid "E582: :elseif without :if"
+msgstr "E582: :elseif sem :if"
+
+msgid "E583: multiple :else"
+msgstr "E583: mais de um :else"
+
+msgid "E584: :elseif after :else"
+msgstr "E584: :elseif depois de :else"
+
+msgid "E585: :while/:for nesting too deep"
+msgstr "E585: :while/:for aninhados demais"
+
+msgid "E586: :continue without :while or :for"
+msgstr "E586: :continue sem :while ou :for"
+
+msgid "E587: :break without :while or :for"
+msgstr "E587: :break sem :while ou :for"
+
+msgid "E732: Using :endfor with :while"
+msgstr "E732: :endfor usado com :while"
+
+msgid "E733: Using :endwhile with :for"
+msgstr "E733: :endwhile usado com :for"
+
+msgid "E601: :try nesting too deep"
+msgstr "E601: :try aninhado demais"
+
+msgid "E603: :catch without :try"
+msgstr "E603: :catch sem :try"
+
+#. Give up for a ":catch" after ":finally" and ignore it.
+#. * Just parse.
+msgid "E604: :catch after :finally"
+msgstr "E604: :catch depois de :finally"
+
+msgid "E606: :finally without :try"
+msgstr "E606: :finally sem :try"
+
+#. Give up for a multiple ":finally" and ignore it.
+msgid "E607: multiple :finally"
+msgstr "E607: mais de um :finally"
+
+msgid "E602: :endtry without :try"
+msgstr "E602: :endtry sem :try"
+
+msgid "E193: :endfunction not inside a function"
+msgstr "E193: :endfunction fora de uma função"
+
+msgid "E788: Not allowed to edit another buffer now"
+msgstr "E788: Não é possível editar outro buffer agora"
+
+msgid "E811: Not allowed to change buffer information now"
+msgstr "E811: Não é permitido mudar as informações do buffer agora"
+
+msgid "tagname"
+msgstr "marcador"
+
+msgid " kind file\n"
+msgstr " tipo arquivo\n"
+
+msgid "'history' option is zero"
+msgstr "opção 'history' vale zero"
+
+#, c-format
+msgid ""
+"\n"
+"# %s History (newest to oldest):\n"
+msgstr ""
+"\n"
+"# Histórico de %s (mais recente primeiro):\n"
+
+msgid "Command Line"
+msgstr "Linha de comando"
+
+msgid "Search String"
+msgstr "Expressões de busca"
+
+msgid "Expression"
+msgstr "Expressão"
+
+msgid "Input Line"
+msgstr "Linhas de entrada"
+
+msgid "E198: cmd_pchar beyond the command length"
+msgstr "E198: cmd_pchar além do final do comando"
+
+msgid "E199: Active window or buffer deleted"
+msgstr "E199: A janela ou buffer ativo foi apagado"
+
+msgid "E812: Autocommands changed buffer or buffer name"
+msgstr "E812: Autocomandos alteraram o buffer ou o nome do buffer"
+
+msgid "Illegal file name"
+msgstr "Nome de arquivo inválido"
+
+msgid "is a directory"
+msgstr "é um diretório"
+
+msgid "is not a file"
+msgstr "não é um arquivo"
+
+msgid "is a device (disabled with 'opendevice' option)"
+msgstr "é um dispositivo (desativado pela opção 'opendevice')"
+
+msgid "[New File]"
+msgstr "[Novo arquivo]"
+
+msgid "[New DIRECTORY]"
+msgstr "[Novo DIRETÓRIO]"
+
+msgid "[File too big]"
+msgstr "[Arquivo muito grande]"
+
+msgid "[Permission Denied]"
+msgstr "[Permissão negada]"
+
+msgid "E200: *ReadPre autocommands made the file unreadable"
+msgstr "E200: Autocomandos *ReadPre tornaram o arquivo ilegível"
+
+msgid "E201: *ReadPre autocommands must not change current buffer"
+msgstr "E201: Os autocomandos *ReadPre não devem alterar o buffer atual"
+
+msgid "Vim: Reading from stdin...\n"
+msgstr "Vim: Lendo da entrada padrão...\n"
+
+msgid "Reading from stdin..."
+msgstr "Lendo da entrada padrão..."
+
+#. Re-opening the original file failed!
+msgid "E202: Conversion made file unreadable!"
+msgstr "E202: A conversão tornou o arquivo ilegível!"
+
+msgid "[fifo/socket]"
+msgstr "[fifo/socket]"
+
+msgid "[fifo]"
+msgstr "[fifo]"
+
+msgid "[socket]"
+msgstr "[socket]"
+
+msgid "[character special]"
+msgstr "[dispositivo de caractere]"
+
+msgid "[RO]"
+msgstr "[S/L]"
+
+msgid "[CR missing]"
+msgstr "[CR faltando]"
+
+msgid "[long lines split]"
+msgstr "[linhas longas divididas]"
+
+msgid "[NOT converted]"
+msgstr "[NÃO convertido]"
+
+msgid "[converted]"
+msgstr "[convertido]"
+
+msgid "[crypted]"
+msgstr "[criptografado]"
+
+#, c-format
+msgid "[CONVERSION ERROR in line %ld]"
+msgstr "[ERRO DE CONVERSÃO na linha %ld]"
+
+#, c-format
+msgid "[ILLEGAL BYTE in line %ld]"
+msgstr "[BYTE INVÁLIDO na linha %ld]"
+
+msgid "[READ ERRORS]"
+msgstr "[ERROS DE LEITURA]"
+
+msgid "Can't find temp file for conversion"
+msgstr "Não foi possível encontrar um arquivo temporário para a conversão"
+
+msgid "Conversion with 'charconvert' failed"
+msgstr "Conversão com 'charconvert' falhou"
+
+msgid "can't read output of 'charconvert'"
+msgstr "não foi possível ler o resultado de 'charconvert'"
+
+msgid "E676: No matching autocommands for acwrite buffer"
+msgstr "E676: Nenhum comando automático correspondente para acwrite buffer"
+
+msgid "E203: Autocommands deleted or unloaded buffer to be written"
+msgstr "E203: Os autocomandos apagaram ou descarregaram o buffer a ser gravado"
+
+msgid "E204: Autocommand changed number of lines in unexpected way"
+msgstr "E204: Autocomando alterou número de linhas de maneira inesperada"
+
+msgid "NetBeans disallows writes of unmodified buffers"
+msgstr "NetBeans não permite gravação de buffers não modificados"
+
+msgid "Partial writes disallowed for NetBeans buffers"
+msgstr "Gravação parcial não é permitida em buffers do NetBeans"
+
+msgid "is not a file or writable device"
+msgstr "não é um arquivo ou dispositivo com permissão de escrita"
+
+msgid "writing to device disabled with 'opendevice' option"
+msgstr "escrita em dispositivo desativada pela opção 'opendevice'"
+
+msgid "is read-only (add ! to override)"
+msgstr "é somente-leitura (adicione ! para forçar)"
+
+msgid "E506: Can't write to backup file (add ! to override)"
+msgstr "E506: Impossível gravar arquivo de backup (adicione ! para forçar)"
+
+msgid "E507: Close error for backup file (add ! to override)"
+msgstr "E507: Erro de fechamento no arquivo de backup (adicione ! para forçar)"
+
+msgid "E508: Can't read file for backup (add ! to override)"
+msgstr "E508: Impossível ler o arquivo para backup (adicione ! para forçar)"
+
+msgid "E509: Cannot create backup file (add ! to override)"
+msgstr "E509: Impossível criar arquivo de backup (adicione ! para forçar)"
+
+msgid "E510: Can't make backup file (add ! to override)"
+msgstr "E510: Impossível fazer o backup (adicione ! para forçar)"
+
+msgid "E460: The resource fork would be lost (add ! to override)"
+msgstr "E460: O resource fork seria perdido (adicione ! para forçar)"
+
+msgid "E214: Can't find temp file for writing"
+msgstr "E214: Não foi possível encontrar arquivo temporário para escrita"
+
+msgid "E213: Cannot convert (add ! to write without conversion)"
+msgstr "E213: Impossível converter (adicione ! para gravar sem converter)"
+
+msgid "E166: Can't open linked file for writing"
+msgstr "E166: Impossível abrir ligação para escrita"
+
+msgid "E212: Can't open file for writing"
+msgstr "E212: Impossível abrir arquivo para escrita"
+
+msgid "E667: Fsync failed"
+msgstr "E667: Fsync falhou"
+
+msgid "E512: Close failed"
+msgstr "E512: Falha no fechamento do arquivo"
+
+msgid "E513: write error, conversion failed (make 'fenc' empty to override)"
+msgstr "E513: erro de gravação, conversão falhou (torne 'fenc' vazio para forçar)"
+
+#, c-format
+msgid "E513: write error, conversion failed in line %ld (make 'fenc' empty to override)"
+msgstr "E513: erro de gravação, conversão falhou na linha %ld (deixe 'fenc' vazio para forçar)"
+
+msgid "E514: write error (file system full?)"
+msgstr "E514: erro de gravação (sistema de arquivos cheio?)"
+
+msgid " CONVERSION ERROR"
+msgstr " ERRO DE CONVERSÃO"
+
+#, c-format
+msgid " in line %ld;"
+msgstr "na linha %ld;"
+
+msgid "[Device]"
+msgstr "[Dispositivo]"
+
+msgid "[New]"
+msgstr "[Novo]"
+
+msgid " [a]"
+msgstr " [a]"
+
+msgid " appended"
+msgstr " adicionado(s)"
+
+msgid " [w]"
+msgstr " [g]"
+
+msgid " written"
+msgstr " gravado(s)"
+
+msgid "E205: Patchmode: can't save original file"
+msgstr "E205: patchmode: impossível salvar o arquivo original"
+
+msgid "E206: patchmode: can't touch empty original file"
+msgstr "E206: patchmode: impossível criar arquivo original vazio"
+
+msgid "E207: Can't delete backup file"
+msgstr "E207: Impossível excluir arquivo de backup"
+
+msgid ""
+"\n"
+"WARNING: Original file may be lost or damaged\n"
+msgstr ""
+"\n"
+"AVISO: O arquivo original pode ter sido perdido ou danificado\n"
+
+msgid "don't quit the editor until the file is successfully written!"
+msgstr "não saia do editor até que o arquivo tenha sido gravado com sucesso!"
+
+msgid "[dos]"
+msgstr "[dos]"
+
+msgid "[dos format]"
+msgstr "[formato dos]"
+
+msgid "[mac]"
+msgstr "[mac]"
+
+msgid "[mac format]"
+msgstr "[formato mac]"
+
+msgid "[unix]"
+msgstr "[unix]"
+
+msgid "[unix format]"
+msgstr "[formato unix]"
+
+msgid "1 line, "
+msgstr "1 linha, "
+
+#, c-format
+msgid "%ld lines, "
+msgstr "%ld linhas, "
+
+msgid "1 character"
+msgstr "1 caractere"
+
+#, c-format
+msgid "%ld characters"
+msgstr "%ld caracteres"
+
+msgid "[noeol]"
+msgstr "[sem fim de linha]"
+
+msgid "[Incomplete last line]"
+msgstr "[Última linha incompleta]"
+
+#. 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 "AVISO: O arquivo foi alterado desde que foi carregado!!!"
+
+msgid "Do you really want to write to it"
+msgstr "Você realmente deseja gravá-lo"
+
+#, c-format
+msgid "E208: Error writing to \"%s\""
+msgstr "E208: Erro ao gravar \"%s\""
+
+#, c-format
+msgid "E209: Error closing \"%s\""
+msgstr "E209: Erro ao fechar \"%s\""
+
+#, c-format
+msgid "E210: Error reading \"%s\""
+msgstr "E210: Erro ao ler \"%s\""
+
+msgid "E246: FileChangedShell autocommand deleted buffer"
+msgstr "E246: O autocomando FileChangedShell apagou o buffer"
+
+#, c-format
+msgid "E211: File \"%s\" no longer available"
+msgstr "E211: Arquivo \"%s\" não está mais disponível"
+
+#, c-format
+msgid "W12: Warning: File \"%s\" has changed and the buffer was changed in Vim as well"
+msgstr "W12: Aviso: O arquivo \"%s\" foi alterado e o buffer também foi alterado no Vim!"
+
+msgid "See \":help W12\" for more info."
+msgstr "Veja \":help W12\" para mais informações."
+
+#, c-format
+msgid "W11: Warning: File \"%s\" has changed since editing started"
+msgstr "W11: Aviso: O arquivo \"%s\" foi alterado desde o início da edição!"
+
+msgid "See \":help W11\" for more info."
+msgstr "Veja \":help W11\" para mais informações."
+
+#, c-format
+msgid "W16: Warning: Mode of file \"%s\" has changed since editing started"
+msgstr "W16: Aviso: O modo do arquivo \"%s\" foi alterado desde o início da edição!"
+
+msgid "See \":help W16\" for more info."
+msgstr "Veja \":help W16\" para mais informações."
+
+#, c-format
+msgid "W13: Warning: File \"%s\" has been created after editing started"
+msgstr "W13: Aviso: O arquivo \"%s\" foi criado após o início da edição!"
+
+msgid "Warning"
+msgstr "Aviso"
+
+msgid ""
+"&OK\n"
+"&Load File"
+msgstr ""
+"&OK\n"
+"&Carregar arquivo"
+
+#, c-format
+msgid "E462: Could not prepare for reloading \"%s\""
+msgstr "E462: Não foi possível preparar \"%s\" para ser recarregado"
+
+#, c-format
+msgid "E321: Could not reload \"%s\""
+msgstr "E321: Não foi possível recarregar \"%s\""
+
+msgid "--Deleted--"
+msgstr "--Excluído--"
+
+#, c-format
+msgid "auto-removing autocommand: %s <buffer=%d>"
+msgstr "removendo automaticamente o autocomando: %s <buffer=%d>"
+
+#. the group doesn't exist
+#, c-format
+msgid "E367: No such group: \"%s\""
+msgstr "E367: Grupo inexistente: \"%s\""
+
+#, c-format
+msgid "E215: Illegal character after *: %s"
+msgstr "E215: Caractere inválido após *: %s"
+
+#, c-format
+msgid "E216: No such event: %s"
+msgstr "E216: Evento inexistente: %s"
+
+#, c-format
+msgid "E216: No such group or event: %s"
+msgstr "E216: Grupo ou evento inexistente: %s"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Auto-Commands ---"
+msgstr ""
+"\n"
+"--- Autocomandos ---"
+
+#, c-format
+msgid "E680: <buffer=%d>: invalid buffer number "
+msgstr "E680: <buffer=%d>: número inválido de buffer "
+
+msgid "E217: Can't execute autocommands for ALL events"
+msgstr "E217: Não é possível executar autocomandos para TODOS os eventos"
+
+msgid "No matching autocommands"
+msgstr "Nenhum autocomando coincidente"
+
+msgid "E218: autocommand nesting too deep"
+msgstr "E218: autocomandos aninhados demais"
+
+#, c-format
+msgid "%s Auto commands for \"%s\""
+msgstr "Comandos automáticos %s para \"%s\""
+
+#, c-format
+msgid "Executing %s"
+msgstr "Executando %s"
+
+#, c-format
+msgid "autocommand %s"
+msgstr "autocomando %s"
+
+msgid "E219: Missing {."
+msgstr "E219: { faltando."
+
+msgid "E220: Missing }."
+msgstr "E220: } faltando."
+
+msgid "E490: No fold found"
+msgstr "E490: Nenhuma dobra encontrada"
+
+msgid "E350: Cannot create fold with current 'foldmethod'"
+msgstr "E350: Impossível criar dobra com a configuração atual de 'foldmethod'"
+
+msgid "E351: Cannot delete fold with current 'foldmethod'"
+msgstr "E351: Impossível excluir dobra com a configuração atual de 'foldmethod'"
+
+#, c-format
+msgid "+--%3ld lines folded "
+msgstr "+--%3ld linhas dobradas "
+
+msgid "E222: Add to read buffer"
+msgstr "E222: Adição a um buffer já lido"
+
+msgid "E223: recursive mapping"
+msgstr "E223: associação recursiva"
+
+#, c-format
+msgid "E224: global abbreviation already exists for %s"
+msgstr "E224: já existe uma abreviação global para %s"
+
+#, c-format
+msgid "E225: global mapping already exists for %s"
+msgstr "E225: já existe uma associação global para %s"
+
+#, c-format
+msgid "E226: abbreviation already exists for %s"
+msgstr "E226: já existe uma abreviação para %s"
+
+#, c-format
+msgid "E227: mapping already exists for %s"
+msgstr "E227: já existe uma associação para %s"
+
+msgid "No abbreviation found"
+msgstr "Nenhuma abreviação encontrada"
+
+msgid "No mapping found"
+msgstr "Nenhuma associação encontrada"
+
+msgid "E228: makemap: Illegal mode"
+msgstr "E228: makemap: Modo inválido"
+
+msgid "<cannot open> "
+msgstr "<impossível abrir> "
+
+#, c-format
+msgid "E616: vim_SelFile: can't get font %s"
+msgstr "E616: vim_SelFile: impossível obter fonte %s"
+
+msgid "E614: vim_SelFile: can't return to current directory"
+msgstr "E614: vim_SelFile: impossível voltar ao diretório atual"
+
+msgid "Pathname:"
+msgstr "Caminho:"
+
+msgid "E615: vim_SelFile: can't get current directory"
+msgstr "E615: vim_SelFile: impossível obter diretório atual"
+
+msgid "OK"
+msgstr "OK"
+
+msgid "Cancel"
+msgstr "Cancelar"
+
+msgid "Vim dialog"
+msgstr "Diálogo do Vim"
+
+msgid "Scrollbar Widget: Could not get geometry of thumb pixmap."
+msgstr "Widget barra de rolagem: impossível obter geometria do pixmap 'thumb'"
+
+msgid "E232: Cannot create BalloonEval with both message and callback"
+msgstr "E232: Impossível criar BalloonEval com mensagem E callback"
+
+msgid "E229: Cannot start the GUI"
+msgstr "E229: Não é possível iniciar a interface gráfica"
+
+#, c-format
+msgid "E230: Cannot read from \"%s\""
+msgstr "E230: Impossível ler de \"%s\""
+
+msgid "E665: Cannot start GUI, no valid font found"
+msgstr "E665: Impossível iniciar a interface gráfica, nenhuma fonte válida encontrada"
+
+msgid "E231: 'guifontwide' invalid"
+msgstr "E231: Valor inválido para 'guifontwide'"
+
+msgid "E599: Value of 'imactivatekey' is invalid"
+msgstr "E599: Valor inválido para 'imactivatekey'"
+
+#, c-format
+msgid "E254: Cannot allocate color %s"
+msgstr "E254: Impossível alocar cor %s"
+
+msgid "No match at cursor, finding next"
+msgstr "Nenhum resultado sob o cursor; procurando próximo"
+
+msgid "Vim dialog..."
+msgstr "Diálogo do Vim..."
+
+msgid ""
+"&Yes\n"
+"&No\n"
+"&Cancel"
+msgstr ""
+"&Sim\n"
+"&Não\n"
+"&Cancelar"
+
+msgid "Input _Methods"
+msgstr "_Métodos de entrada"
+
+msgid "VIM - Search and Replace..."
+msgstr "VIM - Procurar e substituir..."
+
+msgid "VIM - Search..."
+msgstr "VIM - Procurar..."
+
+msgid "Find what:"
+msgstr "Localizar:"
+
+msgid "Replace with:"
+msgstr "Substituir por:"
+
+#. whole word only button
+msgid "Match whole word only"
+msgstr "Coincidir palavra inteira"
+
+#. match case button
+msgid "Match case"
+msgstr "Diferenciar maiúsculas/minúsculas"
+
+msgid "Direction"
+msgstr "Direção"
+
+#. 'Up' and 'Down' buttons
+msgid "Up"
+msgstr "Acima"
+
+msgid "Down"
+msgstr "Abaixo"
+
+msgid "Find Next"
+msgstr "Localizar próxima"
+
+msgid "Replace"
+msgstr "Substituir"
+
+msgid "Replace All"
+msgstr "Substituir todas"
+
+msgid "Vim: Received \"die\" request from session manager\n"
+msgstr "Vim: Recebido um pedido \"die\" do gerenciador de sessão\n"
+
+msgid "Close"
+msgstr "Fechar"
+
+msgid "New tab"
+msgstr "Nova aba"
+
+msgid "Open Tab..."
+msgstr "Abrir aba..."
+
+msgid "Vim: Main window unexpectedly destroyed\n"
+msgstr "Vim: Janela principal destruída inesperadamente\n"
+
+msgid "Font Selection"
+msgstr "Selecionar fonte"
+
+msgid "&Filter"
+msgstr "&Filtrar"
+
+msgid "&Cancel"
+msgstr "&Cancelar"
+
+msgid "Directories"
+msgstr "Diretórios"
+
+msgid "Filter"
+msgstr "Filtro"
+
+msgid "&Help"
+msgstr "A&juda"
+
+msgid "Files"
+msgstr "Arquivos"
+
+msgid "&OK"
+msgstr "&OK"
+
+msgid "Selection"
+msgstr "Seleção"
+
+msgid "Find &Next"
+msgstr "Localizar &próxima"
+
+msgid "&Replace"
+msgstr "&Substituir"
+
+msgid "Replace &All"
+msgstr "Substituir &todas"
+
+msgid "&Undo"
+msgstr "&Desfazer"
+
+#, c-format
+msgid "E671: Cannot find window title \"%s\""
+msgstr "E671: Impossível encontrar janela de título \"%s\""
+
+#, c-format
+msgid "E243: Argument not supported: \"-%s\"; Use the OLE version."
+msgstr "E243: Argumento não suportado: \"-%s\"; Use a versão OLE."
+
+msgid "E672: Unable to open window inside MDI application"
+msgstr "E672: Impossível abrir janela dentro de aplicação MDI"
+
+msgid "Close tab"
+msgstr "Fechar aba"
+
+msgid "Open tab..."
+msgstr "Abrir aba..."
+
+msgid "Find string (use '\\\\' to find a '\\')"
+msgstr "Localizar cadeia de caracteres (use '\\\\' para procurar por '\\')"
+
+msgid "Find & Replace (use '\\\\' to find a '\\')"
+msgstr "Localizar e Substituir (use '\\\\' para procurar por '\\')"
+
+#. 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 "Não usado"
+
+msgid "Directory\t*.nothing\n"
+msgstr "Diretório\t*.nada\n"
+
+msgid "Vim E458: Cannot allocate colormap entry, some colors may be incorrect"
+msgstr "Vim E458: Impossível alocar entrada do mapa de cores; algumas cores podem estar erradas"
+
+#, c-format
+msgid "E250: Fonts for the following charsets are missing in fontset %s:"
+msgstr "E250: Faltam fontes para os seguintes conjuntos de caracteres no conjunto de fontes %s:"
+
+#, c-format
+msgid "E252: Fontset name: %s"
+msgstr "E252: Nome do conjunto de fontes: %s"
+
+#, c-format
+msgid "Font '%s' is not fixed-width"
+msgstr "Fonte '%s' não é de largura fixa"
+
+#, c-format
+msgid "E253: Fontset name: %s\n"
+msgstr "E253: Nome do conjunto de fontes: %s\n"
+
+#, c-format
+msgid "Font0: %s\n"
+msgstr "Fonte0: %s\n"
+
+#, c-format
+msgid "Font1: %s\n"
+msgstr "Fonte1: %s\n"
+
+#, c-format
+msgid "Font%ld width is not twice that of font0\n"
+msgstr "O tamanho da Fonte%ld não é o dobro do da Fonte0\n"
+
+#, c-format
+msgid "Font0 width: %ld\n"
+msgstr "Tamanho da Fonte0: %ld\n"
+
+#, c-format
+msgid ""
+"Font1 width: %ld\n"
+"\n"
+msgstr ""
+"Tamanho da Fonte1: %ld\n"
+"\n"
+
+msgid "Invalid font specification"
+msgstr "Especificação de fonte inválida"
+
+msgid "&Dismiss"
+msgstr "&Dispensar"
+
+msgid "no specific match"
+msgstr "nenhuma coincidência exata"
+
+msgid "Vim - Font Selector"
+msgstr "Vim - Seletor de fontes"
+
+msgid "Name:"
+msgstr "Nome:"
+
+#. create toggle button
+msgid "Show size in Points"
+msgstr "Mostrar tamanho em pontos"
+
+msgid "Encoding:"
+msgstr "Codificação:"
+
+msgid "Font:"
+msgstr "Fonte:"
+
+msgid "Style:"
+msgstr "Estilo:"
+
+msgid "Size:"
+msgstr "Tamanho:"
+
+msgid "E256: Hangul automata ERROR"
+msgstr "E256: ERRO no autômato Hangul"
+
+msgid "E550: Missing colon"
+msgstr "E550: Dois-pontos faltando"
+
+msgid "E551: Illegal component"
+msgstr "E551: Elemento inválido"
+
+msgid "E552: digit expected"
+msgstr "E552: era esperado um algarismo"
+
+#, c-format
+msgid "Page %d"
+msgstr "Página %d"
+
+msgid "No text to be printed"
+msgstr "Sem texto para imprimir"
+
+#, c-format
+msgid "Printing page %d (%d%%)"
+msgstr "Imprimindo página %d (%d%%)"
+
+#, c-format
+msgid " Copy %d of %d"
+msgstr " Cópia %d de %d"
+
+#, c-format
+msgid "Printed: %s"
+msgstr "Impresso: %s"
+
+msgid "Printing aborted"
+msgstr "Impressão cancelada"
+
+msgid "E455: Error writing to PostScript output file"
+msgstr "E455: Erro ao escrever no arquivo PostScript"
+
+#, c-format
+msgid "E624: Can't open file \"%s\""
+msgstr "E624: Impossível abrir arquivo \"%s\""
+
+#, c-format
+msgid "E457: Can't read PostScript resource file \"%s\""
+msgstr "E457: Impossível ler o arquivo de recursos de PostScript \"%s\""
+
+#, c-format
+msgid "E618: file \"%s\" is not a PostScript resource file"
+msgstr "E618: arquivo \"%s\" não é um arquivo de recursos de PostScript"
+
+#, c-format
+msgid "E619: file \"%s\" is not a supported PostScript resource file"
+msgstr "E619: arquivo \"%s\" não é um arquivo de recursos de PostScript suportado"
+
+#, c-format
+msgid "E621: \"%s\" resource file has wrong version"
+msgstr "E621: versão errada do arquivo de recursos \"%s\""
+
+msgid "E673: Incompatible multi-byte encoding and character set."
+msgstr "E673: Codificação multi-byte incompatível com o conjunto de caracteres."
+
+msgid "E674: printmbcharset cannot be empty with multi-byte encoding."
+msgstr "E674: 'printmbcharset' não pode estar vazio com codificações multi-byte."
+
+msgid "E675: No default font specified for multi-byte printing."
+msgstr "E675: Nenhuma fonte padrão especificada para impressão em multi-byte."
+
+msgid "E324: Can't open PostScript output file"
+msgstr "E324: Impossível abrir arquivo PostScript para saída"
+
+#, c-format
+msgid "E456: Can't open file \"%s\""
+msgstr "E456: Impossível abrir arquivo \"%s\""
+
+msgid "E456: Can't find PostScript resource file \"prolog.ps\""
+msgstr "E456: Arquivo de recursos de PostScript \"prolog.ps\" não encontrado"
+
+msgid "E456: Can't find PostScript resource file \"cidfont.ps\""
+msgstr "E456: Arquivo de recursos de PostScript \"cidfont.ps\" não encontrado"
+
+#, c-format
+msgid "E456: Can't find PostScript resource file \"%s.ps\""
+msgstr "E456: Arquivo de recursos de PostScript \"%s.ps\" não encontrado"
+
+#, c-format
+msgid "E620: Unable to convert to print encoding \"%s\""
+msgstr "E620: Impossível converter para a codificação \"%s\" para impressão"
+
+msgid "Sending to printer..."
+msgstr "Enviando à impressora..."
+
+msgid "E365: Failed to print PostScript file"
+msgstr "E365: Não foi possível imprimir o arquivo PostScript"
+
+msgid "Print job sent."
+msgstr "Trabalho de impressão enviado."
+
+msgid "Add a new database"
+msgstr "Adicionar novo banco de dados"
+
+msgid "Query for a pattern"
+msgstr "Procurar por um padrão"
+
+msgid "Show this message"
+msgstr "Mostrar esta mensagem"
+
+msgid "Kill a connection"
+msgstr "Terminar uma conexão"
+
+msgid "Reinit all connections"
+msgstr "Reinicializar todas as conexões"
+
+msgid "Show connections"
+msgstr "Mostrar conexões"
+
+#, c-format
+msgid "E560: Usage: cs[cope] %s"
+msgstr "E560: Forma de uso: cs[cope] %s"
+
+msgid "This cscope command does not support splitting the window.\n"
+msgstr "Este comando cscope não suporta a divisão da janela.\n"
+
+msgid "E562: Usage: cstag <ident>"
+msgstr "E562: Forma de uso: cstag <ident>"
+
+msgid "E257: cstag: tag not found"
+msgstr "E257: cstag: marcador não encontrado"
+
+#, c-format
+msgid "E563: stat(%s) error: %d"
+msgstr "E563: erro em stat(%s): %d"
+
+msgid "E563: stat error"
+msgstr "E563: erro em stat"
+
+#, c-format
+msgid "E564: %s is not a directory or a valid cscope database"
+msgstr "E564: %s não é um diretório ou um banco de dados válido do cscope"
+
+#, c-format
+msgid "Added cscope database %s"
+msgstr "Adicionado banco de dados do cscope %s"
+
+#, c-format
+msgid "E262: error reading cscope connection %ld"
+msgstr "E262: erro ao ler a conexão %ld do cscope"
+
+msgid "E561: unknown cscope search type"
+msgstr "E561: tipo desconhecido de busca do cscope"
+
+msgid "E566: Could not create cscope pipes"
+msgstr "E566: Não foi possível criar os pipes para comunicação com o cscope"
+
+msgid "E622: Could not fork for cscope"
+msgstr "E622: Não foi possível fazer a bifurcação de processo para o cscope"
+
+msgid "cs_create_connection exec failed"
+msgstr "a execução do cscope em cs_create_connection falhou"
+
+msgid "cs_create_connection: fdopen for to_fp failed"
+msgstr "cs_create_connection: fdopen para to_fp falhou"
+
+msgid "cs_create_connection: fdopen for fr_fp failed"
+msgstr "cs_create_connection: fdopen para fr_fp falhou"
+
+msgid "E623: Could not spawn cscope process"
+msgstr "E623: Não foi possível invocar o processo do cscope"
+
+msgid "E567: no cscope connections"
+msgstr "E567: não há conexões com o cscope"
+
+#, c-format
+msgid "E469: invalid cscopequickfix flag %c for %c"
+msgstr "E469: marca %c inválida para %c em 'cscopequickfix'"
+
+#, c-format
+msgid "E259: no matches found for cscope query %s of %s"
+msgstr "E259: nenhum resultado para a busca cscope %s de %s"
+
+msgid "cscope commands:\n"
+msgstr "comandos do cscope:\n"
+
+#, c-format
+msgid "%-5s: %s%*s (Usage: %s)"
+msgstr "%-5s: %s%*s (Forma de uso: %s)"
+
+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 assignments to\n"
+msgstr ""
+"\n"
+" c: Procurar funções que chamam esta função\n"
+" d: Procurar funções chamadas por esta função\n"
+" e: Procurar este padrão do egrep\n"
+" f: Procurar este arquivo\n"
+" g: Procurar esta definição\n"
+" i: Procurar arquivos com #include para este arquivo\n"
+" s: Procurar este símbolo do C\n"
+" t: Procurar atribuições para isto\n"
+
+#, c-format
+msgid "E625: cannot open cscope database: %s"
+msgstr "E625: impossível abrir banco de dados do cscope: %s"
+
+msgid "E626: cannot get cscope database information"
+msgstr "E626: impossível obter informações do banco de dados do cscope"
+
+msgid "E568: duplicate cscope database not added"
+msgstr "E568: banco de dados do cscope repetido; não foi adicionado"
+
+#, c-format
+msgid "E261: cscope connection %s not found"
+msgstr "E261: conexão %s com o cscope não encontrada"
+
+#, c-format
+msgid "cscope connection %s closed"
+msgstr "conexão %s com o cscope fechada"
+
+#. should not reach here
+msgid "E570: fatal error in cs_manage_matches"
+msgstr "E570: erro fatal em cs_manage_matches"
+
+#, c-format
+msgid "Cscope tag: %s"
+msgstr "Tag do cscope: %s"
+
+msgid ""
+"\n"
+" # line"
+msgstr ""
+"\n"
+" # linha"
+
+msgid "filename / context / line\n"
+msgstr "arquivo / contexto / linha\n"
+
+#, c-format
+msgid "E609: Cscope error: %s"
+msgstr "E609: Erro do cscope: %s"
+
+msgid "All cscope databases reset"
+msgstr "Todos os bancos de dados do cscope redefinidos"
+
+msgid "no cscope connections\n"
+msgstr "nenhuma conexão ao cscope\n"
+
+msgid " # pid database name prepend path\n"
+msgstr " # pid nome do banco de dados adicionar caminho\n"
+
+msgid "E815: Sorry, this command is disabled, the MzScheme libraries could not be loaded."
+msgstr "E815: Desculpe, este comando está desativado. As bibliotecas do MzScheme não puderam ser carregadas."
+
+msgid "invalid expression"
+msgstr "expressão inválida"
+
+msgid "expressions disabled at compile time"
+msgstr "expressões desativadas na compilação"
+
+msgid "hidden option"
+msgstr "opção oculta"
+
+msgid "unknown option"
+msgstr "opção desconhecida"
+
+msgid "window index is out of range"
+msgstr "número da janela fora dos limites"
+
+msgid "couldn't open buffer"
+msgstr "impossível abrir buffer"
+
+msgid "cannot save undo information"
+msgstr "impossível salvar informações para desfazer"
+
+msgid "cannot delete line"
+msgstr "impossível excluir linha"
+
+msgid "cannot replace line"
+msgstr "impossível substituir linha"
+
+msgid "cannot insert line"
+msgstr "impossível inserir linha"
+
+msgid "string cannot contain newlines"
+msgstr "a cadeia não pode conter quebras de linha"
+
+msgid "Vim error: ~a"
+msgstr "Erro do Vim: ~a"
+
+msgid "Vim error"
+msgstr "Erro do Vim"
+
+msgid "buffer is invalid"
+msgstr "buffer inválido"
+
+msgid "window is invalid"
+msgstr "janela inválida"
+
+msgid "linenr out of range"
+msgstr "número de linha fora dos limites"
+
+msgid "not allowed in the Vim sandbox"
+msgstr "não permitido na caixa de areia do Vim"
+
+msgid "E263: Sorry, this command is disabled, the Python library could not be loaded."
+msgstr "E263: Desculpe, este comando está desativado. A biblioteca do Python não pôde ser carregada."
+
+msgid "E659: Cannot invoke Python recursively"
+msgstr "E659: Não é possível invocar o Python recursivamente"
+
+msgid "can't delete OutputObject attributes"
+msgstr "impossível excluir os atributos do OutputObject"
+
+msgid "softspace must be an integer"
+msgstr "'softspace' deve ser um inteiro"
+
+msgid "invalid attribute"
+msgstr "atributo inválido"
+
+msgid "writelines() requires list of strings"
+msgstr "writelines() requer uma lista de cadeias de caracteres"
+
+msgid "E264: Python: Error initialising I/O objects"
+msgstr "E264: Python: Erro ao inicializar objetos de E/S"
+
+msgid "attempt to refer to deleted buffer"
+msgstr "tentativa de referência a buffer apagado"
+
+msgid "line number out of range"
+msgstr "número de linha fora dos limites"
+
+#, c-format
+msgid "<buffer object (deleted) at %p>"
+msgstr "<objeto buffer (apagado) em %p>"
+
+msgid "invalid mark name"
+msgstr "nome de marca inválido"
+
+msgid "no such buffer"
+msgstr "buffer inexistente"
+
+msgid "attempt to refer to deleted window"
+msgstr "tentativa de referência a janela excluída"
+
+msgid "readonly attribute"
+msgstr "atributo somente-leitura"
+
+msgid "cursor position outside buffer"
+msgstr "cursor posicionado fora do buffer"
+
+#, c-format
+msgid "<window object (deleted) at %p>"
+msgstr "<objeto janela (apagado) em %p>"
+
+#, c-format
+msgid "<window object (unknown) at %p>"
+msgstr "<objeto janela (desconhecido) em %p>"
+
+#, c-format
+msgid "<window %d>"
+msgstr "<janela %d>"
+
+msgid "no such window"
+msgstr "janela inexistente"
+
+msgid "E265: $_ must be an instance of String"
+msgstr "E265: $_ deve ser uma instância de String"
+
+msgid "E266: Sorry, this command is disabled, the Ruby library could not be loaded."
+msgstr "E266: Desculpe, este comando está desativado. A biblioteca do Ruby não pôde ser carregada."
+
+msgid "E267: unexpected return"
+msgstr "E267: \"return\" inesperado"
+
+msgid "E268: unexpected next"
+msgstr "E268: \"next\" inesperado"
+
+msgid "E269: unexpected break"
+msgstr "E269: \"break\" inesperado"
+
+msgid "E270: unexpected redo"
+msgstr "E270: \"redo\" inesperado"
+
+msgid "E271: retry outside of rescue clause"
+msgstr "E271: \"retry\" fora de bloco \"rescue\""
+
+msgid "E272: unhandled exception"
+msgstr "E272: exceção não tratada"
+
+#, c-format
+msgid "E273: unknown longjmp status %d"
+msgstr "E273: status %d de longjmp desconhecido"
+
+msgid "Toggle implementation/definition"
+msgstr "Alternar implementação/definição"
+
+msgid "Show base class of"
+msgstr "Mostrar classe base de"
+
+msgid "Show overridden member function"
+msgstr "Mostrar função membro sobrescrita"
+
+msgid "Retrieve from file"
+msgstr "Recuperar do arquivo"
+
+msgid "Retrieve from project"
+msgstr "Recuperar do projeto"
+
+msgid "Retrieve from all projects"
+msgstr "Recuperar de todos os projetos"
+
+msgid "Retrieve"
+msgstr "Recuperar"
+
+msgid "Show source of"
+msgstr "Mostrar código de"
+
+msgid "Find symbol"
+msgstr "Procurar símbolo"
+
+msgid "Browse class"
+msgstr "Navegador de classe"
+
+msgid "Show class in hierarchy"
+msgstr "Mostrar classe na hierarquia"
+
+msgid "Show class in restricted hierarchy"
+msgstr "Mostrar classe em hierarquia restrita"
+
+msgid "Xref refers to"
+msgstr "Xref refere-se a"
+
+msgid "Xref referred by"
+msgstr "Xref referido por"
+
+msgid "Xref has a"
+msgstr "Xref tem um"
+
+msgid "Xref used by"
+msgstr "Xref usado por"
+
+msgid "Show docu of"
+msgstr "Mostrar docum. de"
+
+msgid "Generate docu for"
+msgstr "Gerar docum. para"
+
+msgid "Cannot connect to SNiFF+. Check environment (sniffemacs must be found in $PATH).\n"
+msgstr "Não foi possível conectar-se ao SNiFF+. Verifique o ambiente (sniffemacs precisa ser encontrado no $PATH).\n"
+
+msgid "E274: Sniff: Error during read. Disconnected"
+msgstr "E274: Sniff: Erro durante a leitura. Desconectado"
+
+msgid "SNiFF+ is currently "
+msgstr "SNiFF+ está atualmente "
+
+msgid "not "
+msgstr "des"
+
+msgid "connected"
+msgstr "conectado"
+
+#, c-format
+msgid "E275: Unknown SNiFF+ request: %s"
+msgstr "E275: Pedido do SNiFF+ desconhecido: %s"
+
+msgid "E276: Error connecting to SNiFF+"
+msgstr "E276: Erro ao conectar-se ao SNiFF+"
+
+msgid "E278: SNiFF+ not connected"
+msgstr "E278: SNiFF+ desconectado"
+
+msgid "E279: Not a SNiFF+ buffer"
+msgstr "E279: Não é um buffer do SNiFF+"
+
+msgid "Sniff: Error during write. Disconnected"
+msgstr "Sniff: Erro durante a gravação. Desconectado"
+
+msgid "invalid buffer number"
+msgstr "número inválido de buffer"
+
+msgid "not implemented yet"
+msgstr "ainda não implementado"
+
+#. ???
+msgid "cannot set line(s)"
+msgstr "não foi possível redefinir a(s) linha(s)"
+
+msgid "mark not set"
+msgstr "marca não definida"
+
+#, c-format
+msgid "row %d column %d"
+msgstr "linha %d coluna %d"
+
+msgid "cannot insert/append line"
+msgstr "impossível inserir/adicionar linha"
+
+msgid "unknown flag: "
+msgstr "opção desconhecida: "
+
+msgid "unknown vimOption"
+msgstr "opção do Vim desconhecida"
+
+msgid "keyboard interrupt"
+msgstr "interrompido pelo teclado"
+
+msgid "vim error"
+msgstr "erro do vim"
+
+msgid "cannot create buffer/window command: object is being deleted"
+msgstr "impossível criar comando de buffer/janela: o objeto está sendo excluído"
+
+msgid "cannot register callback command: buffer/window is already being deleted"
+msgstr "não foi possível registrar o comando de callback: o buffer/janela já está sendo excluído"
+
+#. This should never happen. Famous last word?
+msgid "E280: TCL FATAL ERROR: reflist corrupt!? Please report this to vim-dev@vim.org"
+msgstr "E280: ERRO FATAL DO TCL: reflist corrompida!? Por favor relate isso para vim-dev@vim.org"
+
+msgid "cannot register callback command: buffer/window reference not found"
+msgstr "não foi possível registrar o comando de callback: referência a buffer/janela não encontrada"
+
+msgid "E571: Sorry, this command is disabled: the Tcl library could not be loaded."
+msgstr "E571: Desculpe, este comando está desativado. A biblioteca do Tcl não pôde ser carregada."
+
+msgid "E281: TCL ERROR: exit code is not int!? Please report this to vim-dev@vim.org"
+msgstr "E281: ERRO DO TCL: código de saída não é int!? Por favor relate isso para vim-dev@vim.org"
+
+#, c-format
+msgid "E572: exit code %d"
+msgstr "E572: código de saída %d"
+
+msgid "cannot get line"
+msgstr "não foi possível obter a linha"
+
+msgid "Unable to register a command server name"
+msgstr "Não foi possível registrar um nome para o servidor de comandos"
+
+msgid "E248: Failed to send command to the destination program"
+msgstr "E248: Falha ao enviar comando ao programa de destino"
+
+#, c-format
+msgid "E573: Invalid server id used: %s"
+msgstr "E573: Foi usada uma id de servidor inválida: %s"
+
+msgid "E251: VIM instance registry property is badly formed. Deleted!"
+msgstr "E251: Propriedade de registro de instância do VIM malformada encontrada e excluída!"
+
+msgid "Unknown option argument"
+msgstr "Argumento de opção desconhecido"
+
+msgid "Too many edit arguments"
+msgstr "Argumentos de edição em excesso"
+
+msgid "Argument missing after"
+msgstr "Argumento faltando após"
+
+msgid "Garbage after option argument"
+msgstr "Lixo após argumento de opção"
+
+msgid "Too many \"+command\", \"-c command\" or \"--cmd command\" arguments"
+msgstr "Demasiados argumentos \"+comando\", \"-c comando\" ou \"--cmd comando\""
+
+msgid "Invalid argument for"
+msgstr "Argumento inválido para"
+
+#, c-format
+msgid "%d files to edit\n"
+msgstr "%d arquivos para editar\n"
+
+msgid "This Vim was not compiled with the diff feature."
+msgstr "Este Vim não foi compilado com o recurso diff."
+
+msgid "'-nb' cannot be used: not enabled at compile time\n"
+msgstr "'-nb' não pode ser usado: não foi ativado na compilação\n"
+
+msgid "Attempt to open script file again: \""
+msgstr "Tentando abrir novamente arquivo de script: \""
+
+msgid "Cannot open for reading: \""
+msgstr "Impossível abrir para leitura: \""
+
+msgid "Cannot open for script output: \""
+msgstr "Impossível abrir para transcrição do script: \""
+
+msgid "Vim: Error: Failure to start gvim from NetBeans\n"
+msgstr "Vim: Erro: Não foi possível iniciar o gvim a partir do NetBeans\n"
+
+msgid "Vim: Warning: Output is not to a terminal\n"
+msgstr "Vim: Aviso: Saída não é um terminal\n"
+
+msgid "Vim: Warning: Input is not from a terminal\n"
+msgstr "Vim: Aviso: Entrada não é de um terminal\n"
+
+#. just in case..
+msgid "pre-vimrc command line"
+msgstr "linha de comando pré-vimrc"
+
+#, c-format
+msgid "E282: Cannot read from \"%s\""
+msgstr "E282: Impossível ler de \"%s\""
+
+msgid ""
+"\n"
+"More info with: \"vim -h\"\n"
+msgstr ""
+"\n"
+"Mais informações com: \"vim -h\"\n"
+
+msgid "[file ..] edit specified file(s)"
+msgstr "[arquivo ..] abrir o(s) arquivo(s) especificado(s)"
+
+msgid "- read text from stdin"
+msgstr "- ler texto a partir da entrada padrão"
+
+msgid "-t tag edit file where tag is defined"
+msgstr "-t marcador editar arquivo onde o marcador é definido"
+
+msgid "-q [errorfile] edit file with first error"
+msgstr "-q [arq.erro] editar arquivo e abrir no primeiro erro"
+
+msgid ""
+"\n"
+"\n"
+"usage:"
+msgstr ""
+"\n"
+"\n"
+"uso:"
+
+msgid " vim [arguments] "
+msgstr " vim [argumentos] "
+
+msgid ""
+"\n"
+" or:"
+msgstr ""
+"\n"
+" ou:"
+
+msgid ""
+"\n"
+"Where case is ignored prepend / to make flag upper case"
+msgstr ""
+"\n"
+"Se a caixa é ignorada, insira / antes da opção para torná-la maiúscula"
+
+msgid ""
+"\n"
+"\n"
+"Arguments:\n"
+msgstr ""
+"\n"
+"\n"
+"Argumentos:\n"
+
+msgid "--\t\t\tOnly file names after this"
+msgstr "--\t\t\tApenas nomes de arquivo depois daqui"
+
+msgid "--literal\t\tDon't expand wildcards"
+msgstr "--literal\t\tNão expandir caracteres-curinga"
+
+msgid "-register\t\tRegister this gvim for OLE"
+msgstr "-register\t\tRegistrar o gvim para o OLE"
+
+msgid "-unregister\t\tUnregister gvim for OLE"
+msgstr "-unregister\t\tDesregistrar o gvim para o OLE"
+
+msgid "-g\t\t\tRun using GUI (like \"gvim\")"
+msgstr "-g\t\t\tExecutar a interface gráfica (como \"gvim\")"
+
+msgid "-f or --nofork\tForeground: Don't fork when starting GUI"
+msgstr "-f ou --nofork\tPrimeiro plano: Não separar a interface gráfica do terminal"
+
+msgid "-v\t\t\tVi mode (like \"vi\")"
+msgstr "-v\t\t\tModo Vi (como \"vi\")"
+
+msgid "-e\t\t\tEx mode (like \"ex\")"
+msgstr "-e\t\t\tModo Ex (como \"ex\")"
+
+msgid "-s\t\t\tSilent (batch) mode (only for \"ex\")"
+msgstr "-s\t\t\tModo silencioso ou \"batch\" (apenas para \"ex\")"
+
+msgid "-d\t\t\tDiff mode (like \"vimdiff\")"
+msgstr "-d\t\t\tModo diff (como \"vimdiff\")"
+
+msgid "-y\t\t\tEasy mode (like \"evim\", modeless)"
+msgstr "-y\t\t\tModo fácil (como \"evim\", o Vim não modal)"
+
+msgid "-R\t\t\tReadonly mode (like \"view\")"
+msgstr "-R\t\t\tmodo somente-leitura (como \"view\")"
+
+msgid "-Z\t\t\tRestricted mode (like \"rvim\")"
+msgstr "-Z\t\t\tmodo restrito (como \"rvim\")"
+
+msgid "-m\t\t\tModifications (writing files) not allowed"
+msgstr "-m\t\t\tNão permitir alterações (gravação de arquivos)"
+
+msgid "-M\t\t\tModifications in text not allowed"
+msgstr "-M\t\t\tNão permitir alterações no texto"
+
+msgid "-b\t\t\tBinary mode"
+msgstr "-b\t\t\tModo binário"
+
+msgid "-l\t\t\tLisp mode"
+msgstr "-l\t\t\tModo Lisp"
+
+msgid "-C\t\t\tCompatible with Vi: 'compatible'"
+msgstr "-C\t\t\tCompatível com o Vi: 'compatible'"
+
+msgid "-N\t\t\tNot fully Vi compatible: 'nocompatible'"
+msgstr "-N\t\t\tNão totalmente compatível com o Vi: 'nocompatible'"
+
+msgid "-V[N][fname]\t\tBe verbose [level N] [log messages to fname]"
+msgstr "-V[N][arq]\t\tDetalhado [nível N] [gravar mensagens em 'arq']"
+
+msgid "-D\t\t\tDebugging mode"
+msgstr "-D\t\t\tModo de depuração (debug)"
+
+msgid "-n\t\t\tNo swap file, use memory only"
+msgstr "-n\t\t\tNão usar arquivo de troca, apenas a memória"
+
+msgid "-r\t\t\tList swap files and exit"
+msgstr "-r\t\t\tListar arquivos de troca e sair"
+
+msgid "-r (with file name)\tRecover crashed session"
+msgstr "-r (nome de arquivo)\tRecuperar sessão perdida"
+
+msgid "-L\t\t\tSame as -r"
+msgstr "-L\t\t\tMesmo que -r"
+
+msgid "-f\t\t\tDon't use newcli to open window"
+msgstr "-f\t\t\tNão usar newcli para abrir janela"
+
+msgid "-dev <device>\t\tUse <device> for I/O"
+msgstr "-dev <dispositivo>\tUsar <dispositivo> para E/S"
+
+msgid "-A\t\t\tstart in Arabic mode"
+msgstr "-A\t\t\tiniciar no modo Árabe"
+
+msgid "-H\t\t\tStart in Hebrew mode"
+msgstr "-H\t\t\tIniciar no modo Hebraico"
+
+msgid "-F\t\t\tStart in Farsi mode"
+msgstr "-F\t\t\tIniciar no modo Farsi (persa)"
+
+msgid "-T <terminal>\tSet terminal type to <terminal>"
+msgstr "-T <terminal>\tDefinir tipo de terminal como <terminal>"
+
+msgid "-u <vimrc>\t\tUse <vimrc> instead of any .vimrc"
+msgstr "-u <vimrc>\t\tUsar <vimrc> em vez de qualquer outro .vimrc"
+
+msgid "-U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc"
+msgstr "-U <gvimrc>\t\tUsar <gvimrc> em vez de qualquer outro .gvimrc"
+
+msgid "--noplugin\t\tDon't load plugin scripts"
+msgstr "--noplugin\t\tNão carregar scripts de plugins"
+
+msgid "-p[N]\t\tOpen N tab pages (default: one for each file)"
+msgstr "-p[N]\t\tAbrir N abas (padrão: uma para cada arquivo)"
+
+msgid "-o[N]\t\tOpen N windows (default: one for each file)"
+msgstr "-o[N]\t\tAbrir N janelas (padrão: uma para cada arquivo)"
+
+msgid "-O[N]\t\tLike -o but split vertically"
+msgstr "-O[N]\t\tComo -o, mas dividindo verticalmente"
+
+msgid "+\t\t\tStart at end of file"
+msgstr "+\t\t\tAbrir no final do arquivo"
+
+msgid "+<lnum>\t\tStart at line <lnum>"
+msgstr "+<núm.l>\t\tComeçar na linha <núm.l>"
+
+msgid "--cmd <command>\tExecute <command> before loading any vimrc file"
+msgstr "--cmd <comando>\tExecutar <comando> antes de carregar qualquer vimrc"
+
+msgid "-c <command>\t\tExecute <command> after loading the first file"
+msgstr "-c <comando>\t\tExecutar <comando> depois de carregar o primeiro arquivo"
+
+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"
+
+msgid "-s <scriptin>\tRead Normal mode commands from file <scriptin>"
+msgstr "-s <script>\t\tLer comandos do modo Normal do arquivo <script>"
+
+msgid "-w <scriptout>\tAppend all typed commands to file <scriptout>"
+msgstr "-w <script>\t\tAdicionar todos os comandos digitados ao arquivo <script>"
+
+msgid "-W <scriptout>\tWrite all typed commands to file <scriptout>"
+msgstr "-W <script>\t\tGravar todos os comandos digitados no arquivo <script>"
+
+msgid "-x\t\t\tEdit encrypted files"
+msgstr "-x\t\t\tEditar arquivos criptografados"
+
+msgid "-display <display>\tConnect vim to this particular X-server"
+msgstr "-display <display>\tConectar o vim a este servidor X específico"
+
+msgid "-X\t\t\tDo not connect to X server"
+msgstr "-X\t\t\tNão conectar ao servidor X"
+
+msgid "--remote <files>\tEdit <files> in a Vim server if possible"
+msgstr "--remote <arquivos>\tEditar <arquivos> num servidor Vim se possível"
+
+msgid "--remote-silent <files> Same, don't complain if there is no server"
+msgstr "--remote-silent <arqs.> Idem, sem reclamar se não houver servidor"
+
+msgid "--remote-wait <files> As --remote but wait for files to have been edited"
+msgstr "--remote-wait <arqs.> Como --remote, mas esperar a edição dos arquivos"
+
+msgid "--remote-wait-silent <files> Same, don't complain if there is no server"
+msgstr "--remote-wait-silent <arqs.> Idem, sem reclamar se não houver servidor"
+
+msgid "--remote-tab[-wait][-silent] <files> As --remote but use tab page per file"
+msgstr "--remote-tab[-wait][-silent] <arqs.> Como --remote, mas com uma aba por arquivo"
+
+msgid "--remote-send <keys>\tSend <keys> to a Vim server and exit"
+msgstr "--remote-send <teclas> Enviar <teclas> para um servidor Vim e sair"
+
+msgid "--remote-expr <expr>\tEvaluate <expr> in a Vim server and print result"
+msgstr "--remote-expr <expr>\tAvaliar <expr> num servidor Vim e exibir o resultado"
+
+msgid "--serverlist\t\tList available Vim server names and exit"
+msgstr "--serverlist\t\tListar servidores Vim disponíveis e sair"
+
+msgid "--servername <name>\tSend to/become the Vim server <name>"
+msgstr "--servername <nome>\tEnviar para/tornar-se o servidor Vim <nome>"
+
+msgid "--startuptime <file>\tWrite startup timing messages to <file>"
+msgstr "--startuptime <arq.>\tGravar mensagens de cronometragem da inicialização para <arquivo>"
+
+msgid "-i <viminfo>\t\tUse <viminfo> instead of .viminfo"
+msgstr "-i <viminfo>\t\tUsar <viminfo> em vez do .viminfo normal"
+
+msgid "-h or --help\tPrint Help (this message) and exit"
+msgstr "-h ou --help\tImprimir a ajuda (esta mensagem) e sair"
+
+msgid "--version\t\tPrint version information and exit"
+msgstr "--version\t\tImprimir informações da versão e sair"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (Motif version):\n"
+msgstr ""
+"\n"
+"Argumentos reconhecidos pelo gvim (versão Motif):\n"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (neXtaw version):\n"
+msgstr ""
+"\n"
+"Argumentos reconhecidos pelo gvim (versão neXtaw):\n"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (Athena version):\n"
+msgstr ""
+"\n"
+"Argumentos reconhecidos pelo gvim (versão Athena):\n"
+
+msgid "-display <display>\tRun vim on <display>"
+msgstr "-display <display>\tExecutar vim em <display>"
+
+msgid "-iconic\t\tStart vim iconified"
+msgstr "-iconic\t\tIniciar vim iconizado"
+
+msgid "-name <name>\t\tUse resource as if vim was <name>"
+msgstr "-name <nome>\t\tUsar recurso como se o vim fosse <nome>"
+
+msgid "\t\t\t (Unimplemented)\n"
+msgstr "\t\t\t (Não implementado)\n"
+
+msgid "-background <color>\tUse <color> for the background (also: -bg)"
+msgstr "-background <cor>\tUsar <cor> para o fundo (abrev.: -bg)"
+
+msgid "-foreground <color>\tUse <color> for normal text (also: -fg)"
+msgstr "-foreground <cor>\tUsar <cor> para texto normal (abrev.: -fg)"
+
+msgid "-font <font>\t\tUse <font> for normal text (also: -fn)"
+msgstr "-font <fonte>\tUsar <fonte> para texto normal (abrev.: -fn)"
+
+msgid "-boldfont <font>\tUse <font> for bold text"
+msgstr "-boldfont <fonte>\tUsar <fonte> para texto em negrito"
+
+msgid "-italicfont <font>\tUse <font> for italic text"
+msgstr "-italicfont <fonte>\tUsar <fonte> para texto em itálico"
+
+msgid "-geometry <geom>\tUse <geom> for initial geometry (also: -geom)"
+msgstr "-geometry <geom>\tUsar <geom> como geometria inicial (abrev.: -geom)"
+
+msgid "-borderwidth <width>\tUse a border width of <width> (also: -bw)"
+msgstr "-borderwidth <larg.>\tUsar <larg.> como largura da borda (abrev.: -bw)"
+
+msgid "-scrollbarwidth <width> Use a scrollbar width of <width> (also: -sw)"
+msgstr "-scrollbarwidth <larg.> Usar <larg.> como largura da barra de rolagem (abrev.: -sw)"
+
+msgid "-menuheight <height>\tUse a menu bar height of <height> (also: -mh)"
+msgstr "-menuheight <altura>\tUsar <altura> para a barra de menus (abrev.: -mh)"
+
+msgid "-reverse\t\tUse reverse video (also: -rv)"
+msgstr "-reverse\t\tUsar vídeo reverso (abrev.: -rv)"
+
+msgid "+reverse\t\tDon't use reverse video (also: +rv)"
+msgstr "+reverse\t\tNão usar vídeo reverso (abrev.: +rv)"
+
+msgid "-xrm <resource>\tSet the specified resource"
+msgstr "-xrm <recurso>\tDefinir o recurso especificado"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (RISC OS version):\n"
+msgstr ""
+"\n"
+"Argumentos reconhecidos pelo gvim (versão RISC OS):\n"
+
+msgid "--columns <number>\tInitial width of window in columns"
+msgstr "--columns <número>\tLargura inicial da janela, em colunas"
+
+msgid "--rows <number>\tInitial height of window in rows"
+msgstr "--rows <número>\tAltura inicial da janela, em linhas"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (GTK+ version):\n"
+msgstr ""
+"\n"
+"Argumentos reconhecidos pelo gvim (versão GTK+):\n"
+
+msgid "-display <display>\tRun vim on <display> (also: --display)"
+msgstr "-display <display>\tExecutar vim no <display> (alt.: --display)"
+
+msgid "--role <role>\tSet a unique role to identify the main window"
+msgstr ""
+"--role <papel>\tDefine um papel único para identificar a janela\n"
+"\t\t\tprincipal"
+
+msgid "--socketid <xid>\tOpen Vim inside another GTK widget"
+msgstr "--socketid <xid>\tAbrir o Vim dentro de outro widget do GTK"
+
+msgid "-P <parent title>\tOpen Vim inside parent application"
+msgstr "-P <título pai>\tAbrir o Vim dentro de uma aplicação-pai"
+
+msgid "--windowid <HWND>\tOpen Vim inside another win32 widget"
+msgstr "--windowid <HWND>\tAbrir o Vim dentro de outro widget win32"
+
+msgid "No display"
+msgstr "Não há display"
+
+#. Failed to send, abort.
+msgid ": Send failed.\n"
+msgstr ": Envio falhou.\n"
+
+#. Let vim start normally.
+msgid ": Send failed. Trying to execute locally\n"
+msgstr ": Envio falhou. Tentando executar localmente\n"
+
+#, c-format
+msgid "%d of %d edited"
+msgstr "%d de %d editados"
+
+msgid "No display: Send expression failed.\n"
+msgstr "Não há display: Envio da expressão falhou.\n"
+
+msgid ": Send expression failed.\n"
+msgstr ": Envio da expressão falhou.\n"
+
+msgid "No marks set"
+msgstr "Nenhuma marca definida"
+
+#, c-format
+msgid "E283: No marks matching \"%s\""
+msgstr "E283: Nenhuma marca coincide com \"%s\""
+
+#. Highlight title
+msgid ""
+"\n"
+"mark line col file/text"
+msgstr ""
+"\n"
+"marc linha col arquivo/texto"
+
+#. Highlight title
+msgid ""
+"\n"
+" jump line col file/text"
+msgstr ""
+"\n"
+"salto linha col arquivo/texto"
+
+#. Highlight title
+msgid ""
+"\n"
+"change line col text"
+msgstr ""
+"\n"
+"alter. linha col texto"
+
+#, c-format
+msgid ""
+"\n"
+"# File marks:\n"
+msgstr ""
+"\n"
+"# Marcas nos arquivos:\n"
+
+#. Write the jumplist with -'
+#, c-format
+msgid ""
+"\n"
+"# Jumplist (newest first):\n"
+msgstr ""
+"\n"
+"# Lista de saltos (mais recente primeiro):\n"
+
+#, c-format
+msgid ""
+"\n"
+"# History of marks within files (newest to oldest):\n"
+msgstr ""
+"\n"
+"# Histórico de marcas nos arquivos (mais recente primeiro):\n"
+
+msgid "Missing '>'"
+msgstr "'>' faltando"
+
+msgid "E543: Not a valid codepage"
+msgstr "E543: Página de códigos inválida"
+
+msgid "E284: Cannot set IC values"
+msgstr "E284: Não foi possível definir os valores do contexto de entrada"
+
+msgid "E285: Failed to create input context"
+msgstr "E285: Falha ao criar o contexto de entrada"
+
+msgid "E286: Failed to open input method"
+msgstr "E286: Falha ao abrir o método de entrada"
+
+msgid "E287: Warning: Could not set destroy callback to IM"
+msgstr "E287: Aviso: Não foi possível definir o callback de destruição do ME"
+
+msgid "E288: input method doesn't support any style"
+msgstr "E288: o método de entrada não suporta nenhum estilo"
+
+msgid "E289: input method doesn't support my preedit type"
+msgstr "E289: o método de entrada não suporta meu tipo de pré-edição"
+
+msgid "E290: over-the-spot style requires fontset"
+msgstr "E290: o estilo over-the-spot requer um conjunto de fontes"
+
+msgid "E291: Your GTK+ is older than 1.2.3. Status area disabled"
+msgstr "E291: Sua versão do GTK+ é anterior à 1.2.3. A área de status foi desativada"
+
+msgid "E292: Input Method Server is not running"
+msgstr "E292: O Servidor de Método de Entrada não está em execução"
+
+msgid "E293: block was not locked"
+msgstr "E293: o bloco não estava travado"
+
+msgid "E294: Seek error in swap file read"
+msgstr "E294: Erro de posicionamento na leitura do arquivo de troca"
+
+msgid "E295: Read error in swap file"
+msgstr "E295: Erro de leitura no arquivo de troca"
+
+msgid "E296: Seek error in swap file write"
+msgstr "E296: Erro de posicionamento na escrita do arquivo de troca"
+
+msgid "E297: Write error in swap file"
+msgstr "E297: Erro de escrita no arquivo de troca"
+
+msgid "E300: Swap file already exists (symlink attack?)"
+msgstr "E300: Arquivo de troca já existe (ataque de symlink?)"
+
+msgid "E298: Didn't get block nr 0?"
+msgstr "E298: Não foi obtido o bloco nº 0?"
+
+msgid "E298: Didn't get block nr 1?"
+msgstr "E298: Não foi obtido o bloco nº 1?"
+
+msgid "E298: Didn't get block nr 2?"
+msgstr "E298: Não foi obtido o bloco nº 2?"
+
+#. could not (re)open the swap file, what can we do????
+msgid "E301: Oops, lost the swap file!!!"
+msgstr "E301: Oops, o arquivo de troca foi perdido!!!"
+
+msgid "E302: Could not rename swap file"
+msgstr "E302: Não foi possível renomear o arquivo de troca"
+
+#, c-format
+msgid "E303: Unable to open swap file for \"%s\", recovery impossible"
+msgstr "E303: Impossível abrir arquivo de troca para \"%s\", recuperação impossível"
+
+msgid "E304: ml_upd_block0(): Didn't get block 0??"
+msgstr "E304: ml_upd_block0(): Não foi obtido o bloco 0??"
+
+#, c-format
+msgid "E305: No swap file found for %s"
+msgstr "E305: Nenhum arquivo de troca encontrado para %s"
+
+msgid "Enter number of swap file to use (0 to quit): "
+msgstr "Insira o número do arquivo de troca a usar (0 para sair): "
+
+#, c-format
+msgid "E306: Cannot open %s"
+msgstr "E306: Impossível abrir %s"
+
+msgid "Unable to read block 0 from "
+msgstr "Impossível ler o bloco 0 de "
+
+msgid ""
+"\n"
+"Maybe no changes were made or Vim did not update the swap file."
+msgstr ""
+"\n"
+"Talvez nenhuma mudança tenha sido feita ou o Vim não tenha atualizado o arquivo\n"
+"de troca."
+
+msgid " cannot be used with this version of Vim.\n"
+msgstr " não pode ser usado com esta versão do Vim.\n"
+
+msgid "Use Vim version 3.0.\n"
+msgstr "Use o Vim versão 3.0.\n"
+
+#, c-format
+msgid "E307: %s does not look like a Vim swap file"
+msgstr "E307: %s não se parece com um arquivo de troca do Vim"
+
+msgid " cannot be used on this computer.\n"
+msgstr " não pode ser usado neste computador.\n"
+
+msgid "The file was created on "
+msgstr "O arquivo foi criado em "
+
+msgid ""
+",\n"
+"or the file has been damaged."
+msgstr ""
+",\n"
+"ou o arquivo foi danificado."
+
+msgid " has been damaged (page size is smaller than minimum value).\n"
+msgstr " foi danificado (o tamanho da página é menor que o valor mínimo).\n"
+
+#, c-format
+msgid "Using swap file \"%s\""
+msgstr "Usando arquivo de troca \"%s\""
+
+#, c-format
+msgid "Original file \"%s\""
+msgstr "Arquivo original \"%s\""
+
+msgid "E308: Warning: Original file may have been changed"
+msgstr "E308: Aviso: O arquivo original pode ter sido alterado"
+
+#, c-format
+msgid "E309: Unable to read block 1 from %s"
+msgstr "E309: Impossível ler o bloco 1 de %s"
+
+msgid "???MANY LINES MISSING"
+msgstr "???MUITAS LINHAS FALTANDO"
+
+msgid "???LINE COUNT WRONG"
+msgstr "???NÚMERO DE LINHAS ERRADO"
+
+msgid "???EMPTY BLOCK"
+msgstr "???BLOCO VAZIO"
+
+msgid "???LINES MISSING"
+msgstr "???LINHAS FALTANDO"
+
+#, c-format
+msgid "E310: Block 1 ID wrong (%s not a .swp file?)"
+msgstr "E310: ID do bloco 1 está errado (%s não é um arquivo .swp?)"
+
+msgid "???BLOCK MISSING"
+msgstr "???BLOCO FALTANDO"
+
+msgid "??? from here until ???END lines may be messed up"
+msgstr "??? daqui até ???FIM as linhas podem estar corrompidas"
+
+msgid "??? from here until ???END lines may have been inserted/deleted"
+msgstr "??? daqui até ???FIM linhas podem ter sido inseridas/excluídas"
+
+msgid "???END"
+msgstr "???FIM"
+
+msgid "E311: Recovery Interrupted"
+msgstr "E311: Recuperação interrompida"
+
+msgid "E312: Errors detected while recovering; look for lines starting with ???"
+msgstr "E312: Erros detectados durante a recuperação; procure por linhas começando com ???"
+
+msgid "See \":help E312\" for more information."
+msgstr "Veja \":help E312\" para mais informações."
+
+msgid "Recovery completed. You should check if everything is OK."
+msgstr "Recuperação concluída. Você deve verificar se está tudo certo."
+
+msgid ""
+"\n"
+"(You might want to write out this file under another name\n"
+msgstr ""
+"\n"
+"(Você talvez queira salvar este arquivo com outro nome\n"
+
+msgid "and run diff with the original file to check for changes)\n"
+msgstr "e executar diff com o arquivo original para verificar se houve alterações)\n"
+
+msgid ""
+"Delete the .swp file afterwards.\n"
+"\n"
+msgstr ""
+"Exclua o arquivo .swp em seguida.\n"
+"\n"
+
+#. use msg() to start the scrolling properly
+msgid "Swap files found:"
+msgstr "Arquivos de troca encontrados:"
+
+msgid " In current directory:\n"
+msgstr " No diretório atual:\n"
+
+msgid " Using specified name:\n"
+msgstr " Usando o nome especificado:\n"
+
+msgid " In directory "
+msgstr " No diretório "
+
+msgid " -- none --\n"
+msgstr " -- nenhum --\n"
+
+msgid " owned by: "
+msgstr " pertence a: "
+
+msgid " dated: "
+msgstr "com data: "
+
+msgid " dated: "
+msgstr " com data de: "
+
+msgid " [from Vim version 3.0]"
+msgstr " [do Vim versão 3.0]"
+
+msgid " [does not look like a Vim swap file]"
+msgstr " [não se parece com um arquivo de troca do Vim]"
+
+msgid " file name: "
+msgstr " nome do arquivo: "
+
+msgid ""
+"\n"
+" modified: "
+msgstr ""
+"\n"
+" modificado: "
+
+msgid "YES"
+msgstr "SIM"
+
+msgid "no"
+msgstr "não"
+
+msgid ""
+"\n"
+" user name: "
+msgstr ""
+"\n"
+" nome de usuário: "
+
+msgid " host name: "
+msgstr " nome do host: "
+
+msgid ""
+"\n"
+" host name: "
+msgstr ""
+"\n"
+" nome do host: "
+
+msgid ""
+"\n"
+" process ID: "
+msgstr ""
+"\n"
+" ID do processo: "
+
+msgid " (still running)"
+msgstr " (ainda executando)"
+
+msgid ""
+"\n"
+" [not usable with this version of Vim]"
+msgstr ""
+"\n"
+" [não pode ser usado com esta versão do Vim]"
+
+msgid ""
+"\n"
+" [not usable on this computer]"
+msgstr ""
+"\n"
+" [não pode ser usado neste computador]"
+
+msgid " [cannot be read]"
+msgstr " [não pode ser lido]"
+
+msgid " [cannot be opened]"
+msgstr " [não pode ser aberto]"
+
+msgid "E313: Cannot preserve, there is no swap file"
+msgstr "E313: Impossível preservar, não há um arquivo de troca"
+
+msgid "File preserved"
+msgstr "Arquivo preservado"
+
+msgid "E314: Preserve failed"
+msgstr "E314: Preservação falhou"
+
+#, c-format
+msgid "E315: ml_get: invalid lnum: %ld"
+msgstr "E315: ml_get: número de linha inválido: %ld"
+
+#, c-format
+msgid "E316: ml_get: cannot find line %ld"
+msgstr "E316: ml_get: linha %ld não encontrada"
+
+msgid "E317: pointer block id wrong 3"
+msgstr "E317: id do bloco de ponteiros incorreto: 3"
+
+msgid "stack_idx should be 0"
+msgstr "stack_idx deveria ser 0"
+
+msgid "E318: Updated too many blocks?"
+msgstr "E318: Foram atualizados blocos demais?"
+
+msgid "E317: pointer block id wrong 4"
+msgstr "E317: id do bloco de ponteiros incorreto: 4"
+
+msgid "deleted block 1?"
+msgstr "bloco 1 apagado?"
+
+#, c-format
+msgid "E320: Cannot find line %ld"
+msgstr "E320: Linha %ld não encontrada"
+
+msgid "E317: pointer block id wrong"
+msgstr "E317: id do bloco de ponteiros incorreto"
+
+msgid "pe_line_count is zero"
+msgstr "pe_line_count é zero"
+
+#, c-format
+msgid "E322: line number out of range: %ld past the end"
+msgstr "E322: número da linha fora dos limites: %ld além do fim"
+
+#, c-format
+msgid "E323: line count wrong in block %ld"
+msgstr "E323: número de linhas incorreto no bloco %ld"
+
+msgid "Stack size increases"
+msgstr "Aumenta o tamanho da pilha"
+
+msgid "E317: pointer block id wrong 2"
+msgstr "E317: id do bloco de ponteiros incorreto: 2"
+
+#, c-format
+msgid "E773: Symlink loop for \"%s\""
+msgstr "E773: Links simbólicos cíclicos para \"%s\""
+
+msgid "E325: ATTENTION"
+msgstr "E325: ATENÇÃO"
+
+msgid ""
+"\n"
+"Found a swap file by the name \""
+msgstr ""
+"\n"
+"Foi encontrado um arquivo de troca de nome \""
+
+msgid "While opening file \""
+msgstr "Ao abrir o arquivo \""
+
+msgid " NEWER than swap file!\n"
+msgstr " MAIS NOVO que o arquivo de troca!\n"
+
+#. Some of these messages are long to allow translation to
+#. * other languages.
+msgid ""
+"\n"
+"(1) Another program may be editing the same file.\n"
+" If this is the case, be careful not to end up with two\n"
+" different instances of the same file when making changes.\n"
+msgstr ""
+"\n"
+"(1) Outro programa pode estar editando o mesmo arquivo.\n"
+" Se for esse o caso, cuidado para não acabar com duas\n"
+" versões do mesmo arquivo ao fazer alterações.\n"
+
+msgid " Quit, or continue with caution.\n"
+msgstr " Saia do programa, ou continue com cuidado.\n"
+
+msgid ""
+"\n"
+"(2) An edit session for this file crashed.\n"
+msgstr ""
+"\n"
+"(2) Ocorreu um travamento numa sessão de edição desse arquivo.\n"
+
+msgid " If this is the case, use \":recover\" or \"vim -r "
+msgstr " Se esse for o caso, use \":recover\" ou \"vim -r "
+
+msgid ""
+"\"\n"
+" to recover the changes (see \":help recovery\").\n"
+msgstr ""
+"\"\n"
+" para recuperar as alterações (veja \":help recovery\").\n"
+
+msgid " If you did this already, delete the swap file \""
+msgstr " Se você já vez isso, exclua o arquivo de troca \""
+
+msgid ""
+"\"\n"
+" to avoid this message.\n"
+msgstr ""
+"\"\n"
+" para evitar esta mensagem.\n"
+
+msgid "Swap file \""
+msgstr "O arquivo de troca \""
+
+msgid "\" already exists!"
+msgstr "\" já existe!"
+
+msgid "VIM - ATTENTION"
+msgstr "VIM - ATENÇÃO"
+
+msgid "Swap file already exists!"
+msgstr "O arquivo de troca já existe!"
+
+msgid ""
+"&Open Read-Only\n"
+"&Edit anyway\n"
+"&Recover\n"
+"&Quit\n"
+"&Abort"
+msgstr ""
+"&Abrir somente-leitura\n"
+"&Editar mesmo assim\n"
+"&Recuperar\n"
+"&Sair\n"
+"&Cancelar"
+
+msgid ""
+"&Open Read-Only\n"
+"&Edit anyway\n"
+"&Recover\n"
+"&Delete it\n"
+"&Quit\n"
+"&Abort"
+msgstr ""
+"&Abrir somente-leitura\n"
+"&Editar mesmo assim\n"
+"&Recuperar\n"
+"E&xcluí-lo\n"
+"&Sair\n"
+"&Cancelar"
+
+msgid "E326: Too many swap files found"
+msgstr "E326: Foram encontrados arquivos de troca demais"
+
+msgid "E327: Part of menu-item path is not sub-menu"
+msgstr "E327: Parte do caminho do item do menu não é um submenu"
+
+msgid "E328: Menu only exists in another mode"
+msgstr "E328: Menu só existe em outro modo"
+
+#, c-format
+msgid "E329: No menu \"%s\""
+msgstr "E329: Não há o menu \"%s\""
+
+#. Only a mnemonic or accelerator is not valid.
+msgid "E792: Empty menu name"
+msgstr "E792: Menu com nome vazio"
+
+msgid "E330: Menu path must not lead to a sub-menu"
+msgstr "E330: Caminho do menu não deve levar a um submenu"
+
+msgid "E331: Must not add menu items directly to menu bar"
+msgstr "E331: Itens não devem ser adicionados diretamente à barra de menus"
+
+msgid "E332: Separator cannot be part of a menu path"
+msgstr "E332: Um separador não pode ser parte de um caminho de menu"
+
+#. Now we have found the matching menu, and we list the mappings
+#. Highlight title
+msgid ""
+"\n"
+"--- Menus ---"
+msgstr ""
+"\n"
+"--- Menus ---"
+
+msgid "Tear off this menu"
+msgstr "Destacar este menu"
+
+msgid "E333: Menu path must lead to a menu item"
+msgstr "E333: Caminho de menu deve levar a um item de menu"
+
+#, c-format
+msgid "E334: Menu not found: %s"
+msgstr "E334: Menu não encontrado: %s"
+
+#, c-format
+msgid "E335: Menu not defined for %s mode"
+msgstr "E335: Menu não definido para o modo %s"
+
+msgid "E336: Menu path must lead to a sub-menu"
+msgstr "E336: O caminho do menu deve levar a um submenu"
+
+msgid "E337: Menu not found - check menu names"
+msgstr "E337: Menu não encontrado - verifique os nomes dos menus"
+
+#, c-format
+msgid "Error detected while processing %s:"
+msgstr "Erro detectado ao processar %s:"
+
+#, c-format
+msgid "line %4ld:"
+msgstr "linha %4ld:"
+
+#, c-format
+msgid "E354: Invalid register name: '%s'"
+msgstr "E354: Nome de registrador inválido: '%s'"
+
+msgid "Messages maintainer: Bram Moolenaar <Bram@vim.org>"
+msgstr "Tradutor das mensagens: Eduardo Dobay <edudobay@gmail.com>"
+
+msgid "Interrupt: "
+msgstr "Interrupção: "
+
+msgid "Press ENTER or type command to continue"
+msgstr "Aperte ENTER ou digite um comando para continuar"
+
+#, c-format
+msgid "%s line %ld"
+msgstr "%s, linha %ld"
+
+msgid "-- More --"
+msgstr "-- Mais --"
+
+msgid " SPACE/d/j: screen/page/line down, b/u/k: up, q: quit "
+msgstr " ESPAÇO/d/j: tela/página/linha abaixo, b/u/k: acima, q: sair "
+
+msgid "Question"
+msgstr "Questão"
+
+msgid ""
+"&Yes\n"
+"&No"
+msgstr ""
+"&Sim\n"
+"&Não"
+
+msgid ""
+"&Yes\n"
+"&No\n"
+"Save &All\n"
+"&Discard All\n"
+"&Cancel"
+msgstr ""
+"&Sim\n"
+"&Não\n"
+"Salvar &tudo\n"
+"&Descartar tudo\n"
+"&Cancelar"
+
+msgid "Select Directory dialog"
+msgstr "Seletor de diretório"
+
+msgid "Save File dialog"
+msgstr "Salvar arquivo"
+
+msgid "Open File dialog"
+msgstr "Abrir arquivo"
+
+#. TODO: non-GUI file selector here
+msgid "E338: Sorry, no file browser in console mode"
+msgstr "E338: Desculpe, não há um seletor de arquivos no modo console"
+
+msgid "E766: Insufficient arguments for printf()"
+msgstr "E766: Argumentos insuficientes para printf()"
+
+msgid "E807: Expected Float argument for printf()"
+msgstr "E807: Era esperado um argumento Float para printf()"
+
+msgid "E767: Too many arguments to printf()"
+msgstr "E767: Argumentos demais para printf()"
+
+msgid "W10: Warning: Changing a readonly file"
+msgstr "W10: Aviso: Modificando um arquivo somente-leitura"
+
+msgid "Type number and <Enter> or click with mouse (empty cancels): "
+msgstr "Digite um número e <Enter> ou clique com o mouse (deixe em branco para cancelar): "
+
+msgid "Type number and <Enter> (empty cancels): "
+msgstr "Digite um número e <Enter> (deixe em branco para cancelar): "
+
+msgid "1 more line"
+msgstr "1 linha a mais"
+
+msgid "1 line less"
+msgstr "1 linha a menos"
+
+#, c-format
+msgid "%ld more lines"
+msgstr "%ld linhas a mais"
+
+#, c-format
+msgid "%ld fewer lines"
+msgstr "%ld linhas a menos"
+
+msgid " (Interrupted)"
+msgstr " (Interrompido)"
+
+msgid "Beep!"
+msgstr "Bip!"
+
+msgid "Vim: preserving files...\n"
+msgstr "Vim: preservando arquivos...\n"
+
+#. close all memfiles, without deleting
+msgid "Vim: Finished.\n"
+msgstr "Vim: Concluído.\n"
+
+#, c-format
+msgid "ERROR: "
+msgstr "ERRO: "
+
+#, c-format
+msgid ""
+"\n"
+"[bytes] total alloc-freed %lu-%lu, in use %lu, peak use %lu\n"
+msgstr ""
+"\n"
+"[bytes] total alocado-liberado %lu-%lu, em uso %lu, pico %lu\n"
+
+#, c-format
+msgid ""
+"[calls] total re/malloc()'s %lu, total free()'s %lu\n"
+"\n"
+msgstr ""
+"[total de chamadas] re/malloc() %lu, free() %lu\n"
+"\n"
+
+msgid "E340: Line is becoming too long"
+msgstr "E340: A linha está tornando-se muito longa"
+
+#, c-format
+msgid "E341: Internal error: lalloc(%ld, )"
+msgstr "E341: Erro interno: lalloc(%ld, )"
+
+#, c-format
+msgid "E342: Out of memory! (allocating %lu bytes)"
+msgstr "E342: Memória esgotada! (ao alocar %lu bytes)"
+
+#, c-format
+msgid "Calling shell to execute: \"%s\""
+msgstr "Chamando o shell para executar: \"%s\""
+
+msgid "E545: Missing colon"
+msgstr "E545: Dois-pontos faltando"
+
+msgid "E546: Illegal mode"
+msgstr "E546: Modo de operação inválido"
+
+msgid "E547: Illegal mouseshape"
+msgstr "E547: 'mouseshape' inválido"
+
+msgid "E548: digit expected"
+msgstr "E548: era esperado um algarismo"
+
+msgid "E549: Illegal percentage"
+msgstr "E549: Porcentagem inválida"
+
+msgid "Enter encryption key: "
+msgstr "Insira a chave criptográfica: "
+
+msgid "Enter same key again: "
+msgstr "Insira a mesma chave novamente: "
+
+msgid "Keys don't match!"
+msgstr "As chaves não coincidem!"
+
+#, c-format
+msgid "E343: Invalid path: '**[number]' must be at the end of the path or be followed by '%s'."
+msgstr "E343: Caminho inválido: '**[número]' deve estar no final do caminho ou seguido de '%s'."
+
+#, c-format
+msgid "E344: Can't find directory \"%s\" in cdpath"
+msgstr "E344: Diretório \"%s\" não encontrado em 'cdpath'"
+
+#, c-format
+msgid "E345: Can't find file \"%s\" in path"
+msgstr "E345: Arquivo \"%s\" não encontrado em 'path'"
+
+#, c-format
+msgid "E346: No more directory \"%s\" found in cdpath"
+msgstr "E346: Mais nenhum diretório \"%s\" encontrado em 'cdpath'"
+
+#, c-format
+msgid "E347: No more file \"%s\" found in path"
+msgstr "E347: Mais nenhum arquivo \"%s\" encontrado em 'path'"
+
+msgid "Cannot connect to Netbeans #2"
+msgstr "Não foi possível conectar-se ao Netbeans #2"
+
+msgid "Cannot connect to Netbeans"
+msgstr "Não foi possível conectar-se ao Netbeans"
+
+#, c-format
+msgid "E668: Wrong access mode for NetBeans connection info file: \"%s\""
+msgstr "E668: Modo de acesso errado para o arquivo de informação de conexão do NetBeans: \"%s\""
+
+msgid "read from Netbeans socket"
+msgstr "lido do socket do NetBeans"
+
+#, c-format
+msgid "E658: NetBeans connection lost for buffer %ld"
+msgstr "E658: Conexão com o NetBeans perdida para o buffer %ld"
+
+msgid "E505: "
+msgstr "E505: "
+
+msgid "E349: No identifier under cursor"
+msgstr "E349: Nenhum identificador sob o cursor"
+
+msgid "E774: 'operatorfunc' is empty"
+msgstr "E774: 'operatorfunc' está vazio"
+
+msgid "E775: Eval feature not available"
+msgstr "E775: O recurso eval não está disponível"
+
+msgid "Warning: terminal cannot highlight"
+msgstr "Aviso: o terminal não suporta destaque no modo visual"
+
+msgid "E348: No string under cursor"
+msgstr "E348: Nenhuma cadeia de caracteres sob o cursor"
+
+msgid "E352: Cannot erase folds with current 'foldmethod'"
+msgstr "E352: Impossível eliminar dobras com o 'foldmethod' atual"
+
+msgid "E664: changelist is empty"
+msgstr "E664: lista de modificações está vazia"
+
+msgid "E662: At start of changelist"
+msgstr "E662: No início da lista de modificações"
+
+msgid "E663: At end of changelist"
+msgstr "E663: No final da lista de modificações"
+
+msgid "Type :quit<Enter> to exit Vim"
+msgstr "Digite :quit<Enter> para sair do Vim"
+
+#, c-format
+msgid "1 line %sed 1 time"
+msgstr "1 linha %sada 1 vez"
+
+#, c-format
+msgid "1 line %sed %d times"
+msgstr "1 linha %sada %d vezes"
+
+#, c-format
+msgid "%ld lines %sed 1 time"
+msgstr "%ld linhas %sadas 1 vez"
+
+#, c-format
+msgid "%ld lines %sed %d times"
+msgstr "%ld linhas %sadas %d vezes"
+
+#, c-format
+msgid "%ld lines to indent... "
+msgstr "%ld linhas para indentar... "
+
+msgid "1 line indented "
+msgstr "1 linha indentada "
+
+#, c-format
+msgid "%ld lines indented "
+msgstr "%ld linhas indentadas "
+
+msgid "E748: No previously used register"
+msgstr "E748: Nenhum registrador foi anteriormente utilizado"
+
+#. must display the prompt
+msgid "cannot yank; delete anyway"
+msgstr "impossível copiar; excluir assim mesmo"
+
+msgid "1 line changed"
+msgstr "1 linha alterada"
+
+#, c-format
+msgid "%ld lines changed"
+msgstr "%ld linhas alteradas"
+
+#, c-format
+msgid "freeing %ld lines"
+msgstr "liberando %ld linhas"
+
+msgid "block of 1 line yanked"
+msgstr "bloco de uma linha copiado"
+
+msgid "1 line yanked"
+msgstr "1 linha copiada"
+
+#, c-format
+msgid "block of %ld lines yanked"
+msgstr "bloco de %ld linhas copiado"
+
+#, c-format
+msgid "%ld lines yanked"
+msgstr "%ld linhas copiadas"
+
+#, c-format
+msgid "E353: Nothing in register %s"
+msgstr "E353: Não há nada no registrador %s"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Registers ---"
+msgstr ""
+"\n"
+"--- Registradores ---"
+
+msgid "Illegal register name"
+msgstr "Nome de registrador inválido"
+
+#, c-format
+msgid ""
+"\n"
+"# Registers:\n"
+msgstr ""
+"\n"
+"# Registradores:\n"
+
+#, c-format
+msgid "E574: Unknown register type %d"
+msgstr "E574: Registrador de tipo desconhecido %d"
+
+#, c-format
+msgid "%ld Cols; "
+msgstr "%ld colunas; "
+
+#, c-format
+msgid "Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Bytes"
+msgstr "Selecionadas %s%ld de %ld linhas; %ld de %ld palavras; %ld de %ld bytes"
+
+#, c-format
+msgid "Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Chars; %ld of %ld Bytes"
+msgstr "Selecionadas %s%ld de %ld linhas; %ld de %ld palavras; %ld de %ld caracteres; %ld de %ld bytes"
+
+#, c-format
+msgid "Col %s of %s; Line %ld of %ld; Word %ld of %ld; Byte %ld of %ld"
+msgstr "Coluna %s de %s; linha %ld de %ld; palavra %ld de %ld; byte %ld de %ld"
+
+#, c-format
+msgid "Col %s of %s; Line %ld of %ld; Word %ld of %ld; Char %ld of %ld; Byte %ld of %ld"
+msgstr "Coluna %s de %s; linha %ld de %ld; palavra %ld de %ld; caractere %ld de %ld; byte %ld de %ld"
+
+#, c-format
+msgid "(+%ld for BOM)"
+msgstr "(+%ld para BOM)"
+
+msgid "%<%f%h%m%=Page %N"
+msgstr "%<%f%h%m%=Página %N"
+
+msgid "Thanks for flying Vim"
+msgstr "Obrigado por voar com o Vim"
+
+msgid "E518: Unknown option"
+msgstr "E518: Opção desconhecida"
+
+msgid "E519: Option not supported"
+msgstr "E519: Opção não suportada"
+
+msgid "E520: Not allowed in a modeline"
+msgstr "E520: Não permitido em modelines"
+
+msgid "E521: Number required after ="
+msgstr "E521: Número requerido após ="
+
+msgid "E522: Not found in termcap"
+msgstr "E522: Não encontrado no termcap"
+
+#, c-format
+msgid "E539: Illegal character <%s>"
+msgstr "E539: Caractere ilegal <%s>"
+
+msgid "E529: Cannot set 'term' to empty string"
+msgstr "E529: 'term' não pode ser uma string vazia"
+
+msgid "E530: Cannot change term in GUI"
+msgstr "E530: term não pode ser alterado na interface gráfica"
+
+msgid "E531: Use \":gui\" to start the GUI"
+msgstr "E531: Use \":gui\" para iniciar a interface gráfica"
+
+msgid "E589: 'backupext' and 'patchmode' are equal"
+msgstr "E589: 'backupext' e 'patchmode' são iguais"
+
+msgid "E617: Cannot be changed in the GTK+ 2 GUI"
+msgstr "E617: Não pode ser modificado na interface GTK+ 2"
+
+msgid "E524: Missing colon"
+msgstr "E524: Dois-pontos faltando"
+
+msgid "E525: Zero length string"
+msgstr "E525: Cadeia de comprimento zero"
+
+#, c-format
+msgid "E526: Missing number after <%s>"
+msgstr "E526: Número faltando após <%s>"
+
+msgid "E527: Missing comma"
+msgstr "E527: Vírgula faltando"
+
+msgid "E528: Must specify a ' value"
+msgstr "E528: É necessário especificar um valor para '"
+
+msgid "E595: contains unprintable or wide character"
+msgstr "E595: contém caracteres não-imprimíveis ou largos"
+
+msgid "E596: Invalid font(s)"
+msgstr "E596: Fonte(s) inválida(s)"
+
+msgid "E597: can't select fontset"
+msgstr "E597: impossível selecionar conjunto de fontes"
+
+msgid "E598: Invalid fontset"
+msgstr "E598: Conjunto de fontes inválido"
+
+msgid "E533: can't select wide font"
+msgstr "E533: impossível selecionar fonte de caracteres largos"
+
+msgid "E534: Invalid wide font"
+msgstr "E534: Fonte de caracteres largos inválida."
+
+#, c-format
+msgid "E535: Illegal character after <%c>"
+msgstr "E535: Caractere inválido após <%c>"
+
+msgid "E536: comma required"
+msgstr "E536: vírgula requerida"
+
+#, c-format
+msgid "E537: 'commentstring' must be empty or contain %s"
+msgstr "E537: 'commentstring' deve estar vazia ou conter %s"
+
+msgid "E538: No mouse support"
+msgstr "E538: Não há suporte a mouse"
+
+msgid "E540: Unclosed expression sequence"
+msgstr "E540: Expressão não terminada com '}'"
+
+msgid "E541: too many items"
+msgstr "E541: itens demais"
+
+msgid "E542: unbalanced groups"
+msgstr "E542: parênteses desequilibrados"
+
+msgid "E590: A preview window already exists"
+msgstr "E590: Já existe uma janela de visualização"
+
+msgid "W17: Arabic requires UTF-8, do ':set encoding=utf-8'"
+msgstr "W17: Árabe requer UTF-8; digite ':set encoding=utf-8'"
+
+#, c-format
+msgid "E593: Need at least %d lines"
+msgstr "E593: São necessárias pelo menos %d linhas"
+
+#, c-format
+msgid "E594: Need at least %d columns"
+msgstr "E594: São necessárias pelo menos %d colunas"
+
+#, c-format
+msgid "E355: Unknown option: %s"
+msgstr "E355: Opção desconhecida: %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.
+#, c-format
+msgid "E521: Number required: &%s = '%s'"
+msgstr "E521: Número requerido: &%s = '%s'"
+
+msgid ""
+"\n"
+"--- Terminal codes ---"
+msgstr ""
+"\n"
+"--- Códigos de terminal ---"
+
+msgid ""
+"\n"
+"--- Global option values ---"
+msgstr ""
+"\n"
+"--- Valores de opções globais ---"
+
+msgid ""
+"\n"
+"--- Local option values ---"
+msgstr ""
+"\n"
+"--- Valores de opções locais ---"
+
+msgid ""
+"\n"
+"--- Options ---"
+msgstr ""
+"\n"
+"--- Opções ---"
+
+msgid "E356: get_varp ERROR"
+msgstr "E356: ERRO em get_varp"
+
+#, c-format
+msgid "E357: 'langmap': Matching character missing for %s"
+msgstr "E357: 'langmap': Falta um caractere para corresponder com %s"
+
+#, c-format
+msgid "E358: 'langmap': Extra characters after semicolon: %s"
+msgstr "E358: 'langmap': Caracteres a mais após ponto-e-vírgula: %s"
+
+msgid "cannot open "
+msgstr "impossível abrir "
+
+msgid "VIM: Can't open window!\n"
+msgstr "VIM: Não foi possível abrir a janela!\n"
+
+msgid "Need Amigados version 2.04 or later\n"
+msgstr "Necessário Amigados versão 2.04 ou mais nova\n"
+
+#, c-format
+msgid "Need %s version %ld\n"
+msgstr "Necessário %s versão %ld\n"
+
+msgid "Cannot open NIL:\n"
+msgstr "Impossível abrir NIL:\n"
+
+msgid "Cannot create "
+msgstr "Impossível criar "
+
+#, c-format
+msgid "Vim exiting with %d\n"
+msgstr "Vim terminando com %d\n"
+
+msgid "cannot change console mode ?!\n"
+msgstr "impossível alterar o modo de console ?!\n"
+
+msgid "mch_get_shellsize: not a console??\n"
+msgstr "mch_get_shellsize: não é um console??\n"
+
+#. if Vim opened a window: Executing a shell may cause crashes
+msgid "E360: Cannot execute shell with -f option"
+msgstr "E360: Impossível executar shell com opção -f"
+
+msgid "Cannot execute "
+msgstr "Não é possível executar "
+
+msgid "shell "
+msgstr "shell "
+
+msgid " returned\n"
+msgstr " devolveu\n"
+
+msgid "ANCHOR_BUF_SIZE too small."
+msgstr "ANCHOR_BUF_SIZE pequeno demais."
+
+msgid "I/O ERROR"
+msgstr "ERRO DE E/S"
+
+msgid "Message"
+msgstr "Mensagem"
+
+msgid "'columns' is not 80, cannot execute external commands"
+msgstr "'columns' não vale 80; impossível executar comandos externos"
+
+msgid "E237: Printer selection failed"
+msgstr "E237: Seleção da impressora falhou"
+
+#, c-format
+msgid "to %s on %s"
+msgstr "para %s em %s"
+
+#, c-format
+msgid "E613: Unknown printer font: %s"
+msgstr "E613: Fonte de impressão desconhecida: %s"
+
+#, c-format
+msgid "E238: Print error: %s"
+msgstr "E238: Erro de impressão: %s"
+
+#, c-format
+msgid "Printing '%s'"
+msgstr "Imprimindo '%s'"
+
+#, c-format
+msgid "E244: Illegal charset name \"%s\" in font name \"%s\""
+msgstr "E244: Conjunto de caracteres \"%s\" inválido no nome da fonte \"%s\""
+
+#, c-format
+msgid "E245: Illegal char '%c' in font name \"%s\""
+msgstr "E245: Caractere '%c' inválido no nome da fonte \"%s\""
+
+msgid "Vim: Double signal, exiting\n"
+msgstr "Vim: Sinal duplo, saindo\n"
+
+#, c-format
+msgid "Vim: Caught deadly signal %s\n"
+msgstr "Vim: Sinal mortal %s interceptado\n"
+
+#, c-format
+msgid "Vim: Caught deadly signal\n"
+msgstr "Vim: Sinal mortal interceptado\n"
+
+#, c-format
+msgid "Opening the X display took %ld msec"
+msgstr "Abertura do display X demorou %ld ms"
+
+msgid ""
+"\n"
+"Vim: Got X error\n"
+msgstr ""
+"\n"
+"Vim: Recebido erro do X\n"
+
+msgid "Testing the X display failed"
+msgstr "Teste do display X falhou"
+
+msgid "Opening the X display timed out"
+msgstr "Abertura do display X excedeu o tempo-limite"
+
+msgid ""
+"\n"
+"Could not get security context for "
+msgstr ""
+"\n"
+"Não foi possível obter o contexto de segurança para "
+
+msgid ""
+"\n"
+"Could not set security context for "
+msgstr ""
+"\n"
+"Não foi possível definir o contexto de segurança para "
+
+msgid ""
+"\n"
+"Cannot execute shell "
+msgstr ""
+"\n"
+"Não foi possível executar o shell "
+
+msgid ""
+"\n"
+"Cannot execute shell sh\n"
+msgstr ""
+"\n"
+"Não foi possível executar o shell sh\n"
+
+msgid ""
+"\n"
+"shell returned "
+msgstr ""
+"\n"
+"o shell devolveu "
+
+msgid ""
+"\n"
+"Cannot create pipes\n"
+msgstr ""
+"\n"
+"Impossível criar pipes de comunicação\n"
+
+msgid ""
+"\n"
+"Cannot fork\n"
+msgstr ""
+"\n"
+"Impossível realizar bifurcação de processo\n"
+
+msgid ""
+"\n"
+"Command terminated\n"
+msgstr ""
+"\n"
+"Comando interrompido\n"
+
+msgid "XSMP lost ICE connection"
+msgstr "XSMP perdeu a conexão ICE"
+
+#, c-format
+msgid "dlerror = \"%s\""
+msgstr "dlerror = \"%s\""
+
+msgid "Opening the X display failed"
+msgstr "Abertura do display X falhou"
+
+msgid "XSMP handling save-yourself request"
+msgstr "XSMP tratando pedido de auto-salvamento"
+
+msgid "XSMP opening connection"
+msgstr "XSMP abrindo conexão"
+
+msgid "XSMP ICE connection watch failed"
+msgstr "Falha no vigia de conexões ICE do XSMP"
+
+#, c-format
+msgid "XSMP SmcOpenConnection failed: %s"
+msgstr "Falha em SmcOpenConnection do XSMP: %s"
+
+msgid "At line"
+msgstr "Na linha"
+
+msgid "Could not load vim32.dll!"
+msgstr "Não foi possível carregar vim32.dll!"
+
+msgid "VIM Error"
+msgstr "Erro do VIM"
+
+msgid "Could not fix up function pointers to the DLL!"
+msgstr "Não foi possível definir os ponteiros de função para a DLL!"
+
+#, c-format
+msgid "shell returned %d"
+msgstr "shell devolveu %d"
+
+#, c-format
+msgid "Vim: Caught %s event\n"
+msgstr "Vim: Evento %s interceptado\n"
+
+msgid "close"
+msgstr "de fechamento"
+
+msgid "logoff"
+msgstr "de logoff"
+
+msgid "shutdown"
+msgstr "de desligamento"
+
+msgid "E371: Command not found"
+msgstr "E371: Comando não encontrado"
+
+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ão foi encontrado no seu $PATH.\n"
+"Comandos externos não farão uma pausa ao terminar.\n"
+"Veja :help win32-vimrun para mais informações."
+
+msgid "Vim Warning"
+msgstr "Alerta do Vim"
+
+#, c-format
+msgid "E372: Too many %%%c in format string"
+msgstr "E372: Muitos %%%c na especificação do formato"
+
+#, c-format
+msgid "E373: Unexpected %%%c in format string"
+msgstr "E373: %%%c inesperado na especificação do formato"
+
+msgid "E374: Missing ] in format string"
+msgstr "E374: ] faltando na especificação do formato"
+
+#, c-format
+msgid "E375: Unsupported %%%c in format string"
+msgstr "E375: %%%c não suportado na especificação de formato"
+
+#, c-format
+msgid "E376: Invalid %%%c in format string prefix"
+msgstr "E376: %%%c inválido no prefixo da especificação de formato"
+
+#, c-format
+msgid "E377: Invalid %%%c in format string"
+msgstr "E377: %%%c inválido na especificação de formato"
+
+msgid "E378: 'errorformat' contains no pattern"
+msgstr "E378: 'errorformat' não contém nenhum padrão"
+
+msgid "E379: Missing or empty directory name"
+msgstr "E379: O nome do diretório está faltando ou vazio"
+
+msgid "E553: No more items"
+msgstr "E553: Não há mais itens"
+
+#, c-format
+msgid "(%d of %d)%s%s: "
+msgstr "(%d de %d)%s%s: "
+
+msgid " (line deleted)"
+msgstr " (linha excluída)"
+
+msgid "E380: At bottom of quickfix stack"
+msgstr "E380: No final da pilha do quickfix"
+
+msgid "E381: At top of quickfix stack"
+msgstr "E381: No topo da pilha do quickfix"
+
+#, c-format
+msgid "error list %d of %d; %d errors"
+msgstr "lista de erros %d de %d; %d erros"
+
+msgid "E382: Cannot write, 'buftype' option is set"
+msgstr "E382: Impossível gravar, opção 'buftype' foi definida"
+
+msgid "E683: File name missing or invalid pattern"
+msgstr "E683: Nome de arquivo faltando ou padrão inválido"
+
+#, c-format
+msgid "Cannot open file \"%s\""
+msgstr "Impossível abrir arquivo \"%s\""
+
+msgid "E681: Buffer is not loaded"
+msgstr "E681: Buffer não está carregado"
+
+msgid "E777: String or List expected"
+msgstr "E777: Era esperada uma String ou uma Lista"
+
+#, c-format
+msgid "E369: invalid item in %s%%[]"
+msgstr "E369: item inválido em %s%%[]"
+
+msgid "E339: Pattern too long"
+msgstr "E339: Padrão longo demais"
+
+msgid "E50: Too many \\z("
+msgstr "E50: Muitos \\z("
+
+#, c-format
+msgid "E51: Too many %s("
+msgstr "E51: Muitos %s("
+
+msgid "E52: Unmatched \\z("
+msgstr "E52: \\z( sem correspondente"
+
+#, c-format
+msgid "E53: Unmatched %s%%("
+msgstr "E53: %s%%( sem correspondente"
+
+#, c-format
+msgid "E54: Unmatched %s("
+msgstr "E54: %s( sem correspondente"
+
+#, c-format
+msgid "E55: Unmatched %s)"
+msgstr "E55: %s) sem correspondente"
+
+#, c-format
+msgid "E59: invalid character after %s@"
+msgstr "E59: caractere inválido após %s@"
+
+#, c-format
+msgid "E60: Too many complex %s{...}s"
+msgstr "E60: Muitos %s{...}s complexos"
+
+#, c-format
+msgid "E61: Nested %s*"
+msgstr "E61: %s* aninhado"
+
+#, c-format
+msgid "E62: Nested %s%c"
+msgstr "E62: %s%c aninhado"
+
+msgid "E63: invalid use of \\_"
+msgstr "E63: uso inválido de \\_"
+
+#, c-format
+msgid "E64: %s%c follows nothing"
+msgstr "E64: %s%c não segue nenhum item"
+
+msgid "E65: Illegal back reference"
+msgstr "E65: Retrorreferência inválida"
+
+msgid "E66: \\z( not allowed here"
+msgstr "E66: \\z( não é permitido aqui"
+
+msgid "E67: \\z1 et al. not allowed here"
+msgstr "E67: \\z1 e cia. não são permitidos aqui"
+
+msgid "E68: Invalid character after \\z"
+msgstr "E68: Caractere inválido após \\z"
+
+#, c-format
+msgid "E69: Missing ] after %s%%["
+msgstr "E69: ] faltando após %s%%["
+
+#, c-format
+msgid "E70: Empty %s%%[]"
+msgstr "E70: %s%%[] vazio"
+
+#, c-format
+msgid "E678: Invalid character after %s%%[dxouU]"
+msgstr "E678: Caractere inválido após %s%%[dxouU]"
+
+#, c-format
+msgid "E71: Invalid character after %s%%"
+msgstr "E71: Caractere inválido após %s%%"
+
+#, c-format
+msgid "E769: Missing ] after %s["
+msgstr "E769: ] faltando após %s["
+
+#, c-format
+msgid "E554: Syntax error in %s{...}"
+msgstr "E554: Erro de sintaxe em %s{...}"
+
+msgid "External submatches:\n"
+msgstr "Subcoincidências externas:\n"
+
+msgid " VREPLACE"
+msgstr " SUBSTITUIÇÃO VISUAL"
+
+msgid " REPLACE"
+msgstr " SUBSTITUIÇÃO"
+
+# ESD - In Portuguese it would sound more natural if the message for
+# "REVERSE" came *after* the message for "INSERT".
+msgid " REVERSE"
+msgstr " (INVERTIDA)"
+
+msgid " INSERT"
+msgstr " INSERÇÃO"
+
+msgid " (insert)"
+msgstr " (inserção)"
+
+msgid " (replace)"
+msgstr " (substituição)"
+
+msgid " (vreplace)"
+msgstr " (substituição visual)"
+
+msgid " Hebrew"
+msgstr " Hebraico"
+
+msgid " Arabic"
+msgstr " Árabe"
+
+msgid " (lang)"
+msgstr " (língua)"
+
+msgid " (paste)"
+msgstr " (colar)"
+
+msgid " VISUAL"
+msgstr " VISUAL"
+
+msgid " VISUAL LINE"
+msgstr " VISUAL/LINHA"
+
+msgid " VISUAL BLOCK"
+msgstr " VISUAL/BLOCO"
+
+msgid " SELECT"
+msgstr " SELEÇÃO"
+
+msgid " SELECT LINE"
+msgstr " SELEÇÃO DE LINHAS"
+
+msgid " SELECT BLOCK"
+msgstr " SELEÇÃO EM BLOCO"
+
+msgid "recording"
+msgstr "gravando"
+
+#, c-format
+msgid "E383: Invalid search string: %s"
+msgstr "E383: Texto de busca inválido: %s"
+
+#, c-format
+msgid "E384: search hit TOP without match for: %s"
+msgstr "E384: busca atingiu o TOPO sem encontrar: %s"
+
+#, c-format
+msgid "E385: search hit BOTTOM without match for: %s"
+msgstr "E385: busca atingiu o FIM sem encontrar: %s"
+
+msgid "E386: Expected '?' or '/' after ';'"
+msgstr "E386: '?' ou '/' esperado após ';'"
+
+msgid " (includes previously listed match)"
+msgstr " (inclui coincidências listadas anteriormente)"
+
+#. cursor at status line
+msgid "--- Included files "
+msgstr "--- Arquivos incluídos "
+
+msgid "not found "
+msgstr "não encontrados "
+
+msgid "in path ---\n"
+msgstr "no caminho de busca ---\n"
+
+msgid " (Already listed)"
+msgstr " (Já listado)"
+
+msgid " NOT FOUND"
+msgstr " NÃO ENCONTRADO"
+
+#, c-format
+msgid "Scanning included file: %s"
+msgstr "Examinando arquivo incluído: %s"
+
+#, c-format
+msgid "Searching included file %s"
+msgstr "Examinando arquivo incluído %s"
+
+msgid "E387: Match is on current line"
+msgstr "E387: A correspondência está na linha atual"
+
+msgid "All included files were found"
+msgstr "Todos os arquivos incluídos foram encontrados"
+
+msgid "No included files"
+msgstr "Não há arquivos incluídos"
+
+msgid "E388: Couldn't find definition"
+msgstr "E388: Definição não foi encontrada"
+
+msgid "E389: Couldn't find pattern"
+msgstr "E389: Padrão não foi encontrado"
+
+msgid "Substitute "
+msgstr " de substituição"
+
+# ESD - The %s is replaced by the argument which is given to the wvsp_one()
+# function (search.c). The "Substitute " argument which may be given
+# to it should be translated as well.
+#, c-format
+msgid ""
+"\n"
+"# Last %sSearch Pattern:\n"
+"~"
+msgstr ""
+"\n"
+"# Último padrão de busca %s:\n"
+"~"
+
+msgid "E759: Format error in spell file"
+msgstr "E759: Erro de formato no arquivo de verificação ortográfica"
+
+msgid "E758: Truncated spell file"
+msgstr "E758: Arquivo de verificação ortográfica truncado"
+
+#, c-format
+msgid "Trailing text in %s line %d: %s"
+msgstr "Texto a mais em %s, linha %d: %s"
+
+#, c-format
+msgid "Affix name too long in %s line %d: %s"
+msgstr "Nome do afixo longo demais em %s, linha %d: %s"
+
+msgid "E761: Format error in affix file FOL, LOW or UPP"
+msgstr "E761: Erro de formato em FOL, LOW ou UPP no arquivo de afixos"
+
+msgid "E762: Character in FOL, LOW or UPP is out of range"
+msgstr "E762: Há um caractere fora dos limites em FOL, LOW ou UPP"
+
+msgid "Compressing word tree..."
+msgstr "Comprimindo árvore de palavras..."
+
+msgid "E756: Spell checking is not enabled"
+msgstr "E756: A verificação ortográfica não está ativada"
+
+#, c-format
+msgid "Warning: Cannot find word list \"%s.%s.spl\" or \"%s.ascii.spl\""
+msgstr "Aviso: A lista de palavras \"%s.%s.spl\" ou \"%s.ascii.spl\" não foi encontrada"
+
+#, c-format
+msgid "Reading spell file \"%s\""
+msgstr "Lendo arquivo de verificação ortográfica \"%s\""
+
+msgid "E757: This does not look like a spell file"
+msgstr "E757: Este não se parece com um arquivo de verificação ortográfica"
+
+msgid "E771: Old spell file, needs to be updated"
+msgstr "E771: Arquivo de verificação ortográfica antigo; é necessário atualizá-lo"
+
+msgid "E772: Spell file is for newer version of Vim"
+msgstr "E772: Arquivo de verificação ortográfica é para uma versão mais nova do Vim"
+
+msgid "E770: Unsupported section in spell file"
+msgstr "E770: Seção não suportada no arquivo de verificação ortográfica"
+
+#, c-format
+msgid "Warning: region %s not supported"
+msgstr "Aviso: região %s não é suportada"
+
+#, c-format
+msgid "Reading affix file %s ..."
+msgstr "Lendo arquivo de afixos %s..."
+
+#, c-format
+msgid "Conversion failure for word in %s line %d: %s"
+msgstr "Falha na conversão para palavra em %s, linha %d: %s"
+
+#, c-format
+msgid "Conversion in %s not supported: from %s to %s"
+msgstr "Conversão em %s não é suportada: de %s para %s"
+
+#, c-format
+msgid "Conversion in %s not supported"
+msgstr "Conversão em %s não é suportada"
+
+#, c-format
+msgid "Invalid value for FLAG in %s line %d: %s"
+msgstr "Valor inválido para FLAG em %s, linha %d: %s"
+
+#, c-format
+msgid "FLAG after using flags in %s line %d: %s"
+msgstr "FLAG encontrado após outros indicadores em %s, linha %d: %s"
+
+#, c-format
+msgid "Defining COMPOUNDFORBIDFLAG after PFX item may give wrong results in %s line %d"
+msgstr "Definir COMPOUNDFORBIDFLAG após um item PFX pode causar resultados errados em %s, linha %d"
+
+#, c-format
+msgid "Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in %s line %d"
+msgstr "Definir COMPOUNDPERMITFLAG após um item PFX pode causar resultados errados em %s, linha %d"
+
+#, c-format
+msgid "Wrong COMPOUNDRULES value in %s line %d: %s"
+msgstr "Valor COMPOUNDRULES incorreto em %s, linha %d: %s"
+
+#, c-format
+msgid "Wrong COMPOUNDWORDMAX value in %s line %d: %s"
+msgstr "Valor COMPOUNDWORDMAX incorreto em %s, linha %d: %s"
+
+#, c-format
+msgid "Wrong COMPOUNDMIN value in %s line %d: %s"
+msgstr "Valor COMPOUNDMIN incorreto em %s, linha %d: %s"
+
+#, c-format
+msgid "Wrong COMPOUNDSYLMAX value in %s line %d: %s"
+msgstr "Valor COMPOUNDSYLMAX incorreto em %s, linha %d: %s"
+
+#, c-format
+msgid "Wrong CHECKCOMPOUNDPATTERN value in %s line %d: %s"
+msgstr "Valor CHECKCOMPOUNDPATTERN incorreto em %s, linha %d: %s"
+
+#, c-format
+msgid "Different combining flag in continued affix block in %s line %d: %s"
+msgstr "Indicadores de combinação diferentes no bloco de afixos continuado em %s linha %d: %s"
+
+#, c-format
+msgid "Duplicate affix in %s line %d: %s"
+msgstr "Afixo duplicado em %s, linha %d: %s"
+
+#, c-format
+msgid "Affix also used for BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST in %s line %d: %s"
+msgstr "Afixo também usado para BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST em %s, linha %d: %s"
+
+#, c-format
+msgid "Expected Y or N in %s line %d: %s"
+msgstr "Esperado Y ou N em %s, linha %d: %s"
+
+#, c-format
+msgid "Broken condition in %s line %d: %s"
+msgstr "Condição defeituosa em %s, linha %d: %s"
+
+#, c-format
+msgid "Expected REP(SAL) count in %s line %d"
+msgstr "Esperado número de REP(SAL) em %s, linha %d"
+
+#, c-format
+msgid "Expected MAP count in %s line %d"
+msgstr "Esperado número de MAP em %s, linha %d"
+
+#, c-format
+msgid "Duplicate character in MAP in %s line %d"
+msgstr "Caractere duplicado em MAP em %s, linha %d"
+
+#, c-format
+msgid "Unrecognized or duplicate item in %s line %d: %s"
+msgstr "Item não reconhecido ou duplicado em %s, linha %d: %s"
+
+#, c-format
+msgid "Missing FOL/LOW/UPP line in %s"
+msgstr "Linha FOL/LOW/UPP faltando em %s"
+
+msgid "COMPOUNDSYLMAX used without SYLLABLE"
+msgstr "COMPOUNDSYLMAX usado sem SYLLABLE"
+
+msgid "Too many postponed prefixes"
+msgstr "Há muitos prefixos postergados"
+
+msgid "Too many compound flags"
+msgstr "Há muitos indicadores de composição"
+
+msgid "Too many postponed prefixes and/or compound flags"
+msgstr "Há muitos prefixos postergados e/ou indicadores de composição"
+
+#, c-format
+msgid "Missing SOFO%s line in %s"
+msgstr "Linha SOFO%s faltando em %s"
+
+#, c-format
+msgid "Both SAL and SOFO lines in %s"
+msgstr "Linhas SAL e SOFO presentes em %s"
+
+#, c-format
+msgid "Flag is not a number in %s line %d: %s"
+msgstr "Indicador não numérico em %s, linha %d: %s"
+
+#, c-format
+msgid "Illegal flag in %s line %d: %s"
+msgstr "Indicador inválido em %s, linha %d: %s"
+
+#, c-format
+msgid "%s value differs from what is used in another .aff file"
+msgstr "O valor de %s é diferente daquele usado em outro arquivo .aff"
+
+#, c-format
+msgid "Reading dictionary file %s ..."
+msgstr "Lendo arquivo-dicionário %s ..."
+
+#, c-format
+msgid "E760: No word count in %s"
+msgstr "E760: Número de palavras não indicado em %s"
+
+#, c-format
+msgid "line %6d, word %6d - %s"
+msgstr "linha %6d, palavra %6d - %s"
+
+#, c-format
+msgid "Duplicate word in %s line %d: %s"
+msgstr "Palavra duplicada em %s, linha %d: %s"
+
+#, c-format
+msgid "First duplicate word in %s line %d: %s"
+msgstr "Primeira palavra duplicada em %s, linha %d: %s"
+
+#, c-format
+msgid "%d duplicate word(s) in %s"
+msgstr "%d palavra(s) duplicada(s) em %s"
+
+#, c-format
+msgid "Ignored %d word(s) with non-ASCII characters in %s"
+msgstr "Foram ignoradas %d palavra(s) com caracteres não-ASCII em %s"
+
+#, c-format
+msgid "Reading word file %s ..."
+msgstr "Lendo arquivo de palavras %s ..."
+
+#, c-format
+msgid "Duplicate /encoding= line ignored in %s line %d: %s"
+msgstr "Linha /encoding= duplicada ignorada em %s, linha %d: %s"
+
+#, c-format
+msgid "/encoding= line after word ignored in %s line %d: %s"
+msgstr "Linha /encoding= ignorada após uma palavra em %s, linha %d: %s"
+
+#, c-format
+msgid "Duplicate /regions= line ignored in %s line %d: %s"
+msgstr "Linha /regions= duplicada ignorada em %s, linha %d: %s"
+
+#, c-format
+msgid "Too many regions in %s line %d: %s"
+msgstr "Regiões demais em %s, linha %d: %s"
+
+#, c-format
+msgid "/ line ignored in %s line %d: %s"
+msgstr "Linha / ignorada em %s, linha %d: %s"
+
+#, c-format
+msgid "Invalid region nr in %s line %d: %s"
+msgstr "Núm. de região inválido em %s, linha %d: %s"
+
+#, c-format
+msgid "Unrecognized flags in %s line %d: %s"
+msgstr "Indicadores não reconhecidos em %s, linha %d: %s"
+
+#, c-format
+msgid "Ignored %d words with non-ASCII characters"
+msgstr "Ignoradas %d palavras com caracteres não-ASCII"
+
+#, c-format
+msgid "Compressed %d of %d nodes; %d (%d%%) remaining"
+msgstr "%d de %d nós comprimidos; %d (%d%%) restantes"
+
+msgid "Reading back spell file..."
+msgstr "Relendo o arquivo de verificação ortográfica..."
+
+#.
+#. * Go through the trie of good words, soundfold each word and add it to
+#. * the soundfold trie.
+#.
+msgid "Performing soundfolding..."
+msgstr "Realizando análise fonética..."
+
+#, c-format
+msgid "Number of words after soundfolding: %ld"
+msgstr "Número de palavras após análise fonética: %ld"
+
+#, c-format
+msgid "Total number of words: %d"
+msgstr "Número total de palavras: %d"
+
+#, c-format
+msgid "Writing suggestion file %s ..."
+msgstr "Gravando arquivo de sugestões %s ..."
+
+#, c-format
+msgid "Estimated runtime memory use: %d bytes"
+msgstr "Consumo estimado de memória: %d bytes"
+
+msgid "E751: Output file name must not have region name"
+msgstr "E751: O nome do arquivo não deve conter o nome da região"
+
+msgid "E754: Only up to 8 regions supported"
+msgstr "E754: São suportadas apenas 8 regiões no máximo"
+
+#, c-format
+msgid "E755: Invalid region in %s"
+msgstr "E755: Região inválida em %s"
+
+msgid "Warning: both compounding and NOBREAK specified"
+msgstr "Aviso: tanto composição quanto NOBREAK foram especificados"
+
+#, c-format
+msgid "Writing spell file %s ..."
+msgstr "Gravando arquivo de verificação ortográfica %s ..."
+
+msgid "Done!"
+msgstr "Concluído!"
+
+#, c-format
+msgid "E765: 'spellfile' does not have %ld entries"
+msgstr "E765: 'spellfile' não contém %ld elementos"
+
+#, c-format
+msgid "Word removed from %s"
+msgstr "Palavra removida de %s"
+
+#, c-format
+msgid "Word added to %s"
+msgstr "Palavra adicionada a %s"
+
+msgid "E763: Word characters differ between spell files"
+msgstr "E763: Caracteres das palavras diferem entre os arquivos ortográficos"
+
+msgid "Sorry, no suggestions"
+msgstr "Desculpe, não há sugestões"
+
+#, c-format
+msgid "Sorry, only %ld suggestions"
+msgstr "Desculpe, apenas %ld sugestões"
+
+#. for when 'cmdheight' > 1
+#. avoid more prompt
+#, c-format
+msgid "Change \"%.*s\" to:"
+msgstr "Alterar \"%.*s\" para:"
+
+#, c-format
+msgid " < \"%.*s\""
+msgstr " < \"%.*s\""
+
+msgid "E752: No previous spell replacement"
+msgstr "E752: Nenhuma substituição ortográfica anterior"
+
+#, c-format
+msgid "E753: Not found: %s"
+msgstr "E753: Não encontrado: %s"
+
+#, c-format
+msgid "E778: This does not look like a .sug file: %s"
+msgstr "E778: Este não parece com um arquivo .sug: %s"
+
+#, c-format
+msgid "E779: Old .sug file, needs to be updated: %s"
+msgstr "E779: Arquivo .sug antigo, precisa ser atualizado: %s"
+
+#, c-format
+msgid "E780: .sug file is for newer version of Vim: %s"
+msgstr "E780: Arquivo .sug é para uma versão mais nova do Vim: %s"
+
+#, c-format
+msgid "E781: .sug file doesn't match .spl file: %s"
+msgstr "E781: O arquivo .sug não corresponde ao arquivo .spl: %s"
+
+#, c-format
+msgid "E782: error while reading .sug file: %s"
+msgstr "E782: erro ao ler o arquivo .sug: %s"
+
+#. This should have been checked when generating the .spl
+#. * file.
+msgid "E783: duplicate char in MAP entry"
+msgstr "E783: caractere duplicado na entrada MAP"
+
+#, c-format
+msgid "E390: Illegal argument: %s"
+msgstr "E390: Argumento inválido: %s"
+
+#, c-format
+msgid "E391: No such syntax cluster: %s"
+msgstr "E391: Não existe o agrupamento sintático: %s"
+
+msgid "No Syntax items defined for this buffer"
+msgstr "Nenhum item sintático definido para este buffer"
+
+msgid "syncing on C-style comments"
+msgstr "sincronização nos comentários no estilo do C"
+
+msgid "no syncing"
+msgstr "sem sincronização"
+
+msgid "syncing starts "
+msgstr "sincronização começa "
+
+msgid " lines before top line"
+msgstr " linhas antes do topo da tela"
+
+msgid ""
+"\n"
+"--- Syntax sync items ---"
+msgstr ""
+"\n"
+"--- Elementos de sincronização da sintaxe ---"
+
+msgid ""
+"\n"
+"syncing on items"
+msgstr ""
+"\n"
+"sincronização sobre elementos"
+
+msgid ""
+"\n"
+"--- Syntax items ---"
+msgstr ""
+"\n"
+"--- Elementos de sintaxe ---"
+
+#, c-format
+msgid "E392: No such syntax cluster: %s"
+msgstr "E392: Não existe o agrupamento de sintaxe: %s"
+
+msgid "minimal "
+msgstr "mínimo "
+
+msgid "maximal "
+msgstr "máximo "
+
+msgid "; match "
+msgstr "; corresponder com "
+
+msgid " line breaks"
+msgstr " quebras de linha"
+
+msgid "E395: contains argument not accepted here"
+msgstr "E395: o parâmetro \"contains\" não é aceito aqui"
+
+msgid "E396: containedin argument not accepted here"
+msgstr "E396: o parâmetro \"containedin\" não é aceito aqui"
+
+msgid "E393: group[t]here not accepted here"
+msgstr "E393: o parâmetro \"group[t]here\" não é aceito aqui"
+
+#, c-format
+msgid "E394: Didn't find region item for %s"
+msgstr "E394: Não foi encontrado um item de região para %s"
+
+msgid "E397: Filename required"
+msgstr "E397: Nome de arquivo requerido"
+
+#, c-format
+msgid "E789: Missing ']': %s"
+msgstr "E789: ']' faltando: %s"
+
+#, c-format
+msgid "E398: Missing '=': %s"
+msgstr "E398: '=' faltando: %s"
+
+#, c-format
+msgid "E399: Not enough arguments: syntax region %s"
+msgstr "E399: Argumentos insuficientes: syntax region %s"
+
+msgid "E400: No cluster specified"
+msgstr "E400: Nenhum agrupamento especificado"
+
+#, c-format
+msgid "E401: Pattern delimiter not found: %s"
+msgstr "E401: Delimitador de padrão não encontrado: %s"
+
+#, c-format
+msgid "E402: Garbage after pattern: %s"
+msgstr "E402: Caracteres indevidos após o padrão: %s"
+
+msgid "E403: syntax sync: line continuations pattern specified twice"
+msgstr "E403: syntax sync: padrão de continuação de linha informado duas vezes"
+
+#, c-format
+msgid "E404: Illegal arguments: %s"
+msgstr "E404: Argumentos inválidos: %s"
+
+#, c-format
+msgid "E405: Missing equal sign: %s"
+msgstr "E405: Sinal de igual faltando: %s"
+
+#, c-format
+msgid "E406: Empty argument: %s"
+msgstr "E406: Argumento vazio: %s"
+
+#, c-format
+msgid "E407: %s not allowed here"
+msgstr "E407: %s não é permitido aqui"
+
+#, c-format
+msgid "E408: %s must be first in contains list"
+msgstr "E408: %s deve ser o primeiro na lista de \"contains\""
+
+#, c-format
+msgid "E409: Unknown group name: %s"
+msgstr "E409: Nome de grupo desconhecido: %s"
+
+#, c-format
+msgid "E410: Invalid :syntax subcommand: %s"
+msgstr "E410: Subcomando inválido para :syntax: %s"
+
+msgid "E679: recursive loop loading syncolor.vim"
+msgstr "E679: loop recursivo ao carregar syncolor.vim"
+
+#, c-format
+msgid "E411: highlight group not found: %s"
+msgstr "E411: grupo de destaque não encontrado: %s"
+
+#, c-format
+msgid "E412: Not enough arguments: \":highlight link %s\""
+msgstr "E412: Argumentos insuficientes: \":highlight link %s\""
+
+#, c-format
+msgid "E413: Too many arguments: \":highlight link %s\""
+msgstr "E413: Argumentos demais: \":highlight link %s\""
+
+msgid "E414: group has settings, highlight link ignored"
+msgstr "E414: o grupo já tem suas definições; associação de destaque ignorada"
+
+#, c-format
+msgid "E415: unexpected equal sign: %s"
+msgstr "E415: sinal de igual inesperado: %s"
+
+#, c-format
+msgid "E416: missing equal sign: %s"
+msgstr "E416: sinal de igual faltando: %s"
+
+#, c-format
+msgid "E417: missing argument: %s"
+msgstr "E417: argumento faltando: %s"
+
+#, c-format
+msgid "E418: Illegal value: %s"
+msgstr "E418: Valor inválido: %s"
+
+msgid "E419: FG color unknown"
+msgstr "E419: cor do texto desconhecida"
+
+msgid "E420: BG color unknown"
+msgstr "E420: cor de fundo desconhecida"
+
+#, c-format
+msgid "E421: Color name or number not recognized: %s"
+msgstr "E421: Nome ou número de cor não reconhecido: %s"
+
+#, c-format
+msgid "E422: terminal code too long: %s"
+msgstr "E422: código de terminal longo demais: %s"
+
+#, c-format
+msgid "E423: Illegal argument: %s"
+msgstr "E423: Argumento inválido: %s"
+
+msgid "E424: Too many different highlighting attributes in use"
+msgstr "E424: Muitos atributos diferentes de destaque sendo usados simultaneamente"
+
+msgid "E669: Unprintable character in group name"
+msgstr "E669: Caractere não-imprimível no nome do grupo"
+
+msgid "W18: Invalid character in group name"
+msgstr "W18: Caractere inválido no nome do grupo"
+
+msgid "E555: at bottom of tag stack"
+msgstr "E555: no fim da pilha de marcadores"
+
+msgid "E556: at top of tag stack"
+msgstr "E556: no topo da pilha de marcadores"
+
+msgid "E425: Cannot go before first matching tag"
+msgstr "E425: Impossível ir para antes do primeiro marcador correspondente"
+
+#, c-format
+msgid "E426: tag not found: %s"
+msgstr "E426: marcador não encontrado: %s"
+
+msgid " # pri kind tag"
+msgstr " # pri tipo marcador"
+
+msgid "file\n"
+msgstr "arquivo\n"
+
+msgid "E427: There is only one matching tag"
+msgstr "E427: Só há um marcador coincidente"
+
+msgid "E428: Cannot go beyond last matching tag"
+msgstr "E428: Impossível ir além do último marcador coincidente"
+
+#, c-format
+msgid "File \"%s\" does not exist"
+msgstr "Arquivo \"%s\" não existe"
+
+#. Give an indication of the number of matching tags
+#, c-format
+msgid "tag %d of %d%s"
+msgstr "marcador %d de %d%s"
+
+msgid " or more"
+msgstr " ou mais"
+
+msgid " Using tag with different case!"
+msgstr " Usando etiqueta com caixa diferente!"
+
+#, c-format
+msgid "E429: File \"%s\" does not exist"
+msgstr "E429: Arquivo \"%s\" não existe"
+
+#. Highlight title
+msgid ""
+"\n"
+" # TO tag FROM line in file/text"
+msgstr ""
+"\n"
+" # PARA marcador DA linha no arquivo/texto"
+
+#, c-format
+msgid "Searching tags file %s"
+msgstr "Examinando arquivo de marcadores %s"
+
+#, c-format
+msgid "E430: Tag file path truncated for %s\n"
+msgstr "E430: Caminho dos arquivos de marcadores truncado para %s\n"
+
+#, c-format
+msgid "E431: Format error in tags file \"%s\""
+msgstr "E431: Erro de formato no arquivo de marcadores \"%s\""
+
+#, c-format
+msgid "Before byte %ld"
+msgstr "Antes do byte %ld"
+
+#, c-format
+msgid "E432: Tags file not sorted: %s"
+msgstr "E432: Arquivo de marcadores não ordenado: %s"
+
+#. never opened any tags file
+msgid "E433: No tags file"
+msgstr "E433: Não há arquivo de marcadores"
+
+msgid "Ignoring long line in tags file"
+msgstr "Ignorando linha muito longa no arquivo de marcas"
+
+msgid "E434: Can't find tag pattern"
+msgstr "E434: Padrão do marcador não encontrado"
+
+msgid "E435: Couldn't find tag, just guessing!"
+msgstr "E435: Marcador não foi encontrado, tentando adivinhar apenas!"
+
+#, c-format
+msgid "Duplicate field name: %s"
+msgstr "Nome de campo duplicado: %s"
+
+msgid "' not known. Available builtin terminals are:"
+msgstr "' desconhecido. Os terminais incorporados disponíveis são:"
+
+msgid "defaulting to '"
+msgstr "usando por omissão '"
+
+msgid "E557: Cannot open termcap file"
+msgstr "E557: Impossível abrir arquivo termcap"
+
+msgid "E558: Terminal entry not found in terminfo"
+msgstr "E558: Descrição do terminal não encontrada em terminfo"
+
+msgid "E559: Terminal entry not found in termcap"
+msgstr "E559: Descrição do terminal não encontrada em termcap"
+
+#, c-format
+msgid "E436: No \"%s\" entry in termcap"
+msgstr "E436: Nenhuma entrada \"%s\" em termcap"
+
+msgid "E437: terminal capability \"cm\" required"
+msgstr "E437: é necessário o recurso de terminal \"cm\""
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Terminal keys ---"
+msgstr ""
+"\n"
+"--- Teclas do terminal ---"
+
+msgid "new shell started\n"
+msgstr "novo shell iniciado\n"
+
+msgid "Vim: Error reading input, exiting...\n"
+msgstr "Vim: Erro ao ler a entrada; saindo...\n"
+
+msgid "Used CUT_BUFFER0 instead of empty selection"
+msgstr "Foi usado CUT_BUFFER0 em vez de uma seleção vazia"
+
+#. must display the prompt
+msgid "No undo possible; continue anyway"
+msgstr "Impossível desfazer; continuando assim mesmo"
+
+msgid "Already at oldest change"
+msgstr "Já está na alteração mais antiga"
+
+msgid "Already at newest change"
+msgstr "Já está na alteração mais nova"
+
+#, c-format
+msgid "Undo number %ld not found"
+msgstr "Desfazimento nº %ld não encontrado"
+
+msgid "E438: u_undo: line numbers wrong"
+msgstr "E438: u_undo: números de linha errados"
+
+msgid "more line"
+msgstr "linha a mais"
+
+msgid "more lines"
+msgstr "linhas a mais"
+
+msgid "line less"
+msgstr "linha a menos"
+
+msgid "fewer lines"
+msgstr "linhas a menos"
+
+msgid "change"
+msgstr "alteração"
+
+msgid "changes"
+msgstr "alterações"
+
+#, c-format
+msgid "%ld %s; %s #%ld %s"
+msgstr "%ld %s; %s #%ld %s"
+
+msgid "before"
+msgstr "antes de"
+
+msgid "after"
+msgstr "após"
+
+msgid "Nothing to undo"
+msgstr "Nada a desfazer"
+
+msgid "number changes time"
+msgstr "número alteraç. hora"
+
+#, c-format
+msgid "%ld seconds ago"
+msgstr "%ld segundos atrás"
+
+msgid "E790: undojoin is not allowed after undo"
+msgstr "E790: undojoin não é permitido depois de desfazer"
+
+msgid "E439: undo list corrupt"
+msgstr "E439: lista de desfazimentos corrompida"
+
+msgid "E440: undo line missing"
+msgstr "E440: a linha para desfazer está faltando"
+
+#. Only MS VC 4.1 and earlier can do Win32s
+msgid ""
+"\n"
+"MS-Windows 16/32-bit GUI version"
+msgstr ""
+"\n"
+"Versão gráfica para MS-Windows 16/32 bits"
+
+msgid ""
+"\n"
+"MS-Windows 64-bit GUI version"
+msgstr ""
+"\n"
+"Versão gráfica para MS-Windows 64 bits"
+
+msgid ""
+"\n"
+"MS-Windows 32-bit GUI version"
+msgstr ""
+"\n"
+"Versão gráfica para MS-Windows 32 bits"
+
+msgid " in Win32s mode"
+msgstr " no modo Win32s"
+
+msgid " with OLE support"
+msgstr " com suporte a OLE"
+
+msgid ""
+"\n"
+"MS-Windows 64-bit console version"
+msgstr ""
+"\n"
+"Versão console para MS-Windows 64 bits"
+
+msgid ""
+"\n"
+"MS-Windows 32-bit console version"
+msgstr ""
+"\n"
+"Versão console para MS-Windows 32 bits"
+
+msgid ""
+"\n"
+"MS-Windows 16-bit version"
+msgstr ""
+"\n"
+"Versão para MS-Windows 16 bits"
+
+msgid ""
+"\n"
+"32-bit MS-DOS version"
+msgstr ""
+"\n"
+"Versão MS-DOS 32 bits"
+
+msgid ""
+"\n"
+"16-bit MS-DOS version"
+msgstr ""
+"\n"
+"Versão MS-DOS 16 bits"
+
+msgid ""
+"\n"
+"MacOS X (unix) version"
+msgstr ""
+"\n"
+"Versão MacOS X (unix)"
+
+msgid ""
+"\n"
+"MacOS X version"
+msgstr ""
+"\n"
+"Versão MacOS X"
+
+msgid ""
+"\n"
+"MacOS version"
+msgstr ""
+"\n"
+"Versão MacOS"
+
+msgid ""
+"\n"
+"RISC OS version"
+msgstr ""
+"\n"
+"Versão RISC OS"
+
+msgid ""
+"\n"
+"OpenVMS version"
+msgstr ""
+"\n"
+"Versão OpenVMS"
+
+msgid ""
+"\n"
+"Included patches: "
+msgstr ""
+"\n"
+"Correções incluídas: "
+
+msgid ""
+"\n"
+"Extra patches: "
+msgstr ""
+"\n"
+"Correções extras:"
+
+msgid "Modified by "
+msgstr "Modificado por "
+
+msgid ""
+"\n"
+"Compiled "
+msgstr ""
+"\n"
+"Compilado "
+
+msgid "by "
+msgstr "por "
+
+msgid ""
+"\n"
+"Huge version "
+msgstr ""
+"\n"
+"Versão enorme "
+
+msgid ""
+"\n"
+"Big version "
+msgstr ""
+"\n"
+"Versão grande "
+
+msgid ""
+"\n"
+"Normal version "
+msgstr ""
+"\n"
+"Versão normal "
+
+msgid ""
+"\n"
+"Small version "
+msgstr ""
+"\n"
+"Versão pequena "
+
+msgid ""
+"\n"
+"Tiny version "
+msgstr ""
+"\n"
+"Versão minúscula "
+
+msgid "without GUI."
+msgstr "sem interface gráfica."
+
+msgid "with GTK2-GNOME GUI."
+msgstr "com interface GTK2-GNOME."
+
+msgid "with GTK-GNOME GUI."
+msgstr "com interface GTK-GNOME."
+
+msgid "with GTK2 GUI."
+msgstr "com interface GTK2."
+
+msgid "with GTK GUI."
+msgstr "com interface GTK."
+
+msgid "with X11-Motif GUI."
+msgstr "com interface X11-Motif."
+
+msgid "with X11-neXtaw GUI."
+msgstr "com interface X11-neXtaw."
+
+msgid "with X11-Athena GUI."
+msgstr "com interface X11-Athena."
+
+msgid "with Photon GUI."
+msgstr "com interface Photon."
+
+msgid "with GUI."
+msgstr "com interface gráfica."
+
+msgid "with Carbon GUI."
+msgstr "com interface Carbon."
+
+msgid "with Cocoa GUI."
+msgstr "com interface Cocoa."
+
+msgid "with (classic) GUI."
+msgstr "com interface gráfica (clássica)."
+
+msgid " Features included (+) or not (-):\n"
+msgstr " Recursos incluídos (+) ou não (-):\n"
+
+msgid " system vimrc file: \""
+msgstr " arquivo vimrc de sistema: \""
+
+msgid " user vimrc file: \""
+msgstr " arquivo vimrc do usuário: \""
+
+msgid " 2nd user vimrc file: \""
+msgstr " 2º arquivo vimrc do usuário: \""
+
+msgid " 3rd user vimrc file: \""
+msgstr " 3º arquivo vimrc do usuário: \""
+
+msgid " user exrc file: \""
+msgstr " arquivo exrc do usuário: \""
+
+msgid " 2nd user exrc file: \""
+msgstr " 2º arquivo exrc do usuário: \""
+
+msgid " system gvimrc file: \""
+msgstr " arquivo gvimrc de sistema: \""
+
+msgid " user gvimrc file: \""
+msgstr " arquivo gvimrc do usuário: \""
+
+msgid "2nd user gvimrc file: \""
+msgstr "2º arquivo gvimrc do usuário: \""
+
+msgid "3rd user gvimrc file: \""
+msgstr "3º arquivo gvimrc do usuário: \""
+
+msgid " system menu file: \""
+msgstr " arquivo de menu do sistema: \""
+
+msgid " fall-back for $VIM: \""
+msgstr " padrão para $VIM: \""
+
+msgid " f-b for $VIMRUNTIME: \""
+msgstr " padrão para $VIMRUNTIME: \""
+
+msgid "Compilation: "
+msgstr "Compilação: "
+
+msgid "Compiler: "
+msgstr "Compilador: "
+
+msgid "Linking: "
+msgstr "Vinculação: "
+
+msgid " DEBUG BUILD"
+msgstr " VERSÃO DE DEPURAÇÃO"
+
+msgid "VIM - Vi IMproved"
+msgstr "VIM - VI Melhorado"
+
+msgid "version "
+msgstr "versão "
+
+msgid "by Bram Moolenaar et al."
+msgstr "por Bram Moolenaar et al."
+
+msgid "Vim is open source and freely distributable"
+msgstr "Vim tem código aberto e é livremente distribuível"
+
+msgid "Help poor children in Uganda!"
+msgstr "Ajude crianças pobres em Uganda!"
+
+msgid "type :help iccf<Enter> for information "
+msgstr "digite :help iccf<Enter> para informações "
+
+msgid "type :q<Enter> to exit "
+msgstr "digite :q<Enter> para sair "
+
+msgid "type :help<Enter> or <F1> for on-line help"
+msgstr "digite :help<Enter> ou <F1> para ajuda on-line "
+
+msgid "type :help version7<Enter> for version info"
+msgstr "digite :help version7<Enter> para info da versão"
+
+msgid "Running in Vi compatible mode"
+msgstr "Executando no modo compatível com Vi"
+
+msgid "type :set nocp<Enter> for Vim defaults"
+msgstr "digite :set nocp<Enter> para restaurar padrões do Vim"
+
+msgid "type :help cp-default<Enter> for info on this"
+msgstr "digite :help cp-default<Enter> para informações sobre isso"
+
+msgid "menu Help->Orphans for information "
+msgstr " menu Ajuda->Órfãos para informações "
+
+msgid "Running modeless, typed text is inserted"
+msgstr "Execução não modal; todo texto digitado é inserido"
+
+msgid "menu Edit->Global Settings->Toggle Insert Mode "
+msgstr " menu Editar->Opções globais->Alternar modo de inserção "
+
+msgid " for two modes "
+msgstr " para voltar à execução modal "
+
+msgid "menu Edit->Global Settings->Toggle Vi Compatible"
+msgstr " menu Editar->Opções globais->Alternar compatível com Vi "
+
+msgid " for Vim defaults "
+msgstr " para restaurar padrões do Vim"
+
+msgid "Sponsor Vim development!"
+msgstr "Patrocine o desenvolvimento do Vim!"
+
+msgid "Become a registered Vim user!"
+msgstr "Torne-se um usuário registrado do Vim!"
+
+msgid "type :help sponsor<Enter> for information "
+msgstr "digite :help sponsor<Enter> para informações "
+
+msgid "type :help register<Enter> for information "
+msgstr "digite :help register<Enter> para informações "
+
+msgid "menu Help->Sponsor/Register for information "
+msgstr "menu Ajuda->Doar/Registrar para informações"
+
+msgid "WARNING: Windows 95/98/ME detected"
+msgstr "AVISO: Windows 95/98/ME detectado"
+
+msgid "type :help windows95<Enter> for info on this"
+msgstr "digite :help windows95<Enter> para informações sobre isso"
+
+msgid "Already only one window"
+msgstr "Já há apenas uma janela"
+
+msgid "E441: There is no preview window"
+msgstr "E441: Não há janela de visualização"
+
+msgid "E442: Can't split topleft and botright at the same time"
+msgstr "E442: Impossível dividir nos cantos sup.esquerdo e inf.direito ao mesmo tempo"
+
+msgid "E443: Cannot rotate when another window is split"
+msgstr "E443: Impossível rodar quando outra janela está dividida"
+
+msgid "E444: Cannot close last window"
+msgstr "E444: Não posso fechar a última janela"
+
+msgid "E813: Cannot close autocmd window"
+msgstr "E813: Não é possível fechar a janela autocmd"
+
+msgid "E814: Cannot close window, only autocmd window would remain"
+msgstr "E814: Não é possível fechar a janela, só restaria a janela autocmd"
+
+msgid "E445: Other window contains changes"
+msgstr "E445: Outra janela contém alterações"
+
+msgid "E446: No file name under cursor"
+msgstr "E446: Nenhum nome de arquivo sob o cursor"
+
+#, c-format
+msgid "E447: Can't find file \"%s\" in path"
+msgstr "E447: Arquivo \"%s\" não encontrado nos caminhos de busca"
+
+#, c-format
+msgid "E370: Could not load library %s"
+msgstr "E370: Não foi possível carregar a biblioteca %s"
+
+msgid "Sorry, this command is disabled: the Perl library could not be loaded."
+msgstr "Desculpe, este comando está desativado: a biblioteca do Perl não pôde ser carregada."
+
+msgid "E299: Perl evaluation forbidden in sandbox without the Safe module"
+msgstr "E299: Avaliação de expressões Perl na caixa de areia proibida sem o módulo Safe"
+
+msgid "Edit with &multiple Vims"
+msgstr "Editar em &múltiplos Vims"
+
+msgid "Edit with single &Vim"
+msgstr "Editar com único &Vim"
+
+msgid "Diff with Vim"
+msgstr "Comparar (diff) com Vim"
+
+msgid "Edit with &Vim"
+msgstr "Editar com &Vim"
+
+#. Now concatenate
+msgid "Edit with existing Vim - "
+msgstr "Editar com Vim existente - "
+
+msgid "Edits the selected file(s) with Vim"
+msgstr "Edita o(s) arquivo(s) selecionado(s) com o Vim"
+
+msgid "Error creating process: Check if gvim is in your path!"
+msgstr "Erro ao criar processo: verifique se o gvim está no caminho de busca!"
+
+msgid "gvimext.dll error"
+msgstr "erro da gvimext.dll"
+
+msgid "Path length too long!"
+msgstr "Caminho comprido demais!"
+
+msgid "--No lines in buffer--"
+msgstr "--Sem linhas no buffer--"
+
+#.
+#. * 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: Comando cancelado"
+
+msgid "E471: Argument required"
+msgstr "E471: Argumento requerido"
+
+msgid "E10: \\ should be followed by /, ? or &"
+msgstr "E10: \\ deve ser seguido de /, ? ou &"
+
+msgid "E11: Invalid in command-line window; <CR> executes, CTRL-C quits"
+msgstr "E11: Inválido na janela da linha de comando; <CR> executa, CTRL-C sai"
+
+msgid "E12: Command not allowed from exrc/vimrc in current dir or tag search"
+msgstr "E12: Comando não permitido no exrc/vimrc do diretório atual ou num arquivo de marcadores"
+
+msgid "E171: Missing :endif"
+msgstr "E171: :endif faltando"
+
+msgid "E600: Missing :endtry"
+msgstr "E600: :endtry faltando"
+
+msgid "E170: Missing :endwhile"
+msgstr "E170: :endwhile faltando"
+
+msgid "E170: Missing :endfor"
+msgstr "E170: :endfor faltando"
+
+msgid "E588: :endwhile without :while"
+msgstr "E588: :endwhile sem :while"
+
+msgid "E588: :endfor without :for"
+msgstr "E588: :endfor sem :for"
+
+msgid "E13: File exists (add ! to override)"
+msgstr "E13: Arquivo existe (adicione ! para forçar)"
+
+msgid "E472: Command failed"
+msgstr "E472: Comando falhou"
+
+#, c-format
+msgid "E234: Unknown fontset: %s"
+msgstr "E234: Conjunto de fontes desconhecido: %s"
+
+#, c-format
+msgid "E235: Unknown font: %s"
+msgstr "E235: Fonte desconhecida: %s"
+
+#, c-format
+msgid "E236: Font \"%s\" is not fixed-width"
+msgstr "E236: Fonte \"%s\" não é de largura fixa"
+
+msgid "E473: Internal error"
+msgstr "E473: Erro interno"
+
+msgid "Interrupted"
+msgstr "Interrompido"
+
+msgid "E14: Invalid address"
+msgstr "E14: Endereço inválido"
+
+msgid "E474: Invalid argument"
+msgstr "E474: Argumento inválido"
+
+#, c-format
+msgid "E475: Invalid argument: %s"
+msgstr "E475: Argumento inválido: %s"
+
+#, c-format
+msgid "E15: Invalid expression: %s"
+msgstr "E15: Expressão inválida: %s"
+
+msgid "E16: Invalid range"
+msgstr "E16: Intervalo inválido"
+
+msgid "E476: Invalid command"
+msgstr "E476: Comando inválido"
+
+#, c-format
+msgid "E17: \"%s\" is a directory"
+msgstr "E17: \"%s\" é um diretório"
+
+#, c-format
+msgid "E364: Library call failed for \"%s()\""
+msgstr "E364: Chamada à biblioteca falhou para \"%s()\""
+
+#, c-format
+msgid "E448: Could not load library function %s"
+msgstr "E448: Não foi possível carregar a função %s de biblioteca"
+
+msgid "E19: Mark has invalid line number"
+msgstr "E19: Marca tem número de linha inválido"
+
+msgid "E20: Mark not set"
+msgstr "E20: Marca não definida"
+
+msgid "E21: Cannot make changes, 'modifiable' is off"
+msgstr "E21: Impossível fazer mudanças, 'modifiable' está desativado"
+
+msgid "E22: Scripts nested too deep"
+msgstr "E22: Scripts excessivamente aninhados"
+
+msgid "E23: No alternate file"
+msgstr "E23: Nenhum arquivo alternativo"
+
+msgid "E24: No such abbreviation"
+msgstr "E24: Abreviação inexistente"
+
+msgid "E477: No ! allowed"
+msgstr "E477: '!' não permitido"
+
+msgid "E25: GUI cannot be used: Not enabled at compile time"
+msgstr "E25: Interface gráfica não pode ser usada, não foi ativada na compilação"
+
+msgid "E26: Hebrew cannot be used: Not enabled at compile time\n"
+msgstr "E26: Hebraico não pode ser usado, não foi ativado na compilação\n"
+
+msgid "E27: Farsi cannot be used: Not enabled at compile time\n"
+msgstr "E27: Farsi (persa) não pode ser usado, não foi ativado na compilação\n"
+
+msgid "E800: Arabic cannot be used: Not enabled at compile time\n"
+msgstr "E800: Árabe não pode ser usado, não foi ativado na compilação\n"
+
+#, c-format
+msgid "E28: No such highlight group name: %s"
+msgstr "E28: Não existe grupo de destaque com tal nome: %s"
+
+msgid "E29: No inserted text yet"
+msgstr "E29: Nenhum texto foi inserido ainda"
+
+msgid "E30: No previous command line"
+msgstr "E30: Nenhuma linha de comando anterior"
+
+msgid "E31: No such mapping"
+msgstr "E31: Associação inexistente"
+
+msgid "E479: No match"
+msgstr "E479: Nenhuma correspondência"
+
+#, c-format
+msgid "E480: No match: %s"
+msgstr "E480: Nenhuma correspondência: %s"
+
+msgid "E32: No file name"
+msgstr "E32: Nenhum nome de arquivo"
+
+msgid "E33: No previous substitute regular expression"
+msgstr "E33: Nenhuma expressão regular de substituição anterior"
+
+msgid "E34: No previous command"
+msgstr "E34: Nenhum comando anterior"
+
+msgid "E35: No previous regular expression"
+msgstr "E35: Nenhuma expressão regular anterior"
+
+msgid "E481: No range allowed"
+msgstr "E481: Intervalos não são permitidos"
+
+msgid "E36: Not enough room"
+msgstr "E36: Não há espaço suficiente"
+
+#, c-format
+msgid "E247: no registered server named \"%s\""
+msgstr "E247: nenhum servidor registrado com o nome \"%s\""
+
+#, c-format
+msgid "E482: Can't create file %s"
+msgstr "E482: Impossível criar arquivo %s"
+
+msgid "E483: Can't get temp file name"
+msgstr "E483: Impossível obter nome do arquivo temporário"
+
+#, c-format
+msgid "E484: Can't open file %s"
+msgstr "E484: Impossível abrir arquivo %s"
+
+#, c-format
+msgid "E485: Can't read file %s"
+msgstr "E485: Impossível ler arquivo %s"
+
+msgid "E37: No write since last change (add ! to override)"
+msgstr "E37: Alterações não foram gravadas (adicione ! para forçar)"
+
+msgid "E38: Null argument"
+msgstr "E38: Argumento nulo"
+
+msgid "E39: Number expected"
+msgstr "E39: Número era esperado"
+
+#, c-format
+msgid "E40: Can't open errorfile %s"
+msgstr "E40: Impossível abrir o arquivo de erros %s"
+
+msgid "E233: cannot open display"
+msgstr "E233: impossível abrir display"
+
+msgid "E41: Out of memory!"
+msgstr "E41: Memória esgotada!"
+
+msgid "Pattern not found"
+msgstr "Padrão não encontrado"
+
+#, c-format
+msgid "E486: Pattern not found: %s"
+msgstr "E486: Padrão não encontrado: %s"
+
+msgid "E487: Argument must be positive"
+msgstr "E487: Argumento deve ser positivo"
+
+msgid "E459: Cannot go back to previous directory"
+msgstr "E459: Impossível voltar ao diretório anterior"
+
+msgid "E42: No Errors"
+msgstr "E42: Nenhum erro"
+
+msgid "E776: No location list"
+msgstr "E776: Nenhuma lista de locais"
+
+msgid "E43: Damaged match string"
+msgstr "E43: String de busca danificada"
+
+msgid "E44: Corrupted regexp program"
+msgstr "E44: Autômato de expressão regular corrompido"
+
+msgid "E45: 'readonly' option is set (add ! to override)"
+msgstr "E45: opção 'readonly' está definida (adicione ! para forçar)"
+
+#, c-format
+msgid "E46: Cannot change read-only variable \"%s\""
+msgstr "E46: Impossível alterar variável somente-leitura \"%s\""
+
+#, c-format
+msgid "E794: Cannot set variable in the sandbox: \"%s\""
+msgstr "E794: Não é possível definir a variável na caixa de areia: \"%s\""
+
+msgid "E47: Error while reading errorfile"
+msgstr "E47: Erro ao ler arquivo de erros"
+
+msgid "E48: Not allowed in sandbox"
+msgstr "E48: Isso não é permitido na caixa de areia"
+
+msgid "E523: Not allowed here"
+msgstr "E523: Isso não é permitido aqui"
+
+msgid "E359: Screen mode setting not supported"
+msgstr "E359: Configuração do modo de tela não é suportada"
+
+msgid "E49: Invalid scroll size"
+msgstr "E49: Tamanho de rolagem inválido"
+
+msgid "E91: 'shell' option is empty"
+msgstr "E91: Opção 'shell' está vazia"
+
+msgid "E255: Couldn't read in sign data!"
+msgstr "E255: Não foi possível ler os dados dos símbolos!"
+
+msgid "E72: Close error on swap file"
+msgstr "E72: Erro ao fechar o arquivo de troca"
+
+msgid "E73: tag stack empty"
+msgstr "E73: pilha de marcadores vazia"
+
+msgid "E74: Command too complex"
+msgstr "E74: Comando complexo demais"
+
+msgid "E75: Name too long"
+msgstr "E75: Nome longo demais"
+
+msgid "E76: Too many ["
+msgstr "E76: Muitos ["
+
+msgid "E77: Too many file names"
+msgstr "E77: Muitos nomes de arquivos"
+
+msgid "E488: Trailing characters"
+msgstr "E488: Caracteres em excesso no final da linha"
+
+msgid "E78: Unknown mark"
+msgstr "E78: Marca desconhecida"
+
+msgid "E79: Cannot expand wildcards"
+msgstr "E79: Impossível expandir os caracteres-curinga"
+
+msgid "E591: 'winheight' cannot be smaller than 'winminheight'"
+msgstr "E591: 'winheight' não pode ser menor que 'winminheight'"
+
+msgid "E592: 'winwidth' cannot be smaller than 'winminwidth'"
+msgstr "E592: 'winwidth' não pode ser menor que 'winminwidth'"
+
+msgid "E80: Error while writing"
+msgstr "E80: Erro na escrita"
+
+msgid "Zero count"
+msgstr "Quantificador nulo"
+
+msgid "E81: Using <SID> not in a script context"
+msgstr "E81: <SID> usado fora de um script"
+
+msgid "E449: Invalid expression received"
+msgstr "E449: Expressão inválida recebida"
+
+msgid "E463: Region is guarded, cannot modify"
+msgstr "E463: A região é protegida; impossível modificá-la"
+
+msgid "E744: NetBeans does not allow changes in read-only files"
+msgstr "E744: O NetBeans não permite alterações em arquivos somente-leitura"
+
+#, c-format
+msgid "E685: Internal error: %s"
+msgstr "E685: Erro interno: %s"
+
+msgid "E363: pattern uses more memory than 'maxmempattern'"
+msgstr "E363: padrão usa mais memória que 'maxmempattern'"
+
+msgid "E749: empty buffer"
+msgstr "E749: buffer vazio"
+
+msgid "E682: Invalid search pattern or delimiter"
+msgstr "E682: Padrão de busca ou delimitador inválido"
+
+msgid "E139: File is loaded in another buffer"
+msgstr "E139: O arquivo está carregado em outro buffer"
+
+#, c-format
+msgid "E764: Option '%s' is not set"
+msgstr "E764: Opção '%s' não está definida"
+
+msgid "search hit TOP, continuing at BOTTOM"
+msgstr "busca atingiu TOPO; continuando do FIM"
+
+msgid "search hit BOTTOM, continuing at TOP"
+msgstr "busca atingiu FIM; continuando do TOPO"
+
diff --git a/src/po/ru.cp1251.po b/src/po/ru.cp1251.po
new file mode 100644
index 0000000000..e35ebe04ca
--- /dev/null
+++ b/src/po/ru.cp1251.po
@@ -0,0 +1,6893 @@
+# 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_7.4_ru\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2013-08-31 16:42+0400\n"
+"PO-Revision-Date: 2013-08-31 21:11+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"
+
+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 "[Location List]"
+msgstr "[Ñïèñîê ðàñïîëîæåíèé]"
+
+msgid "[Quickfix List]"
+msgstr "[Ñïèñîê áûñòðûõ èñïðàâëåíèé]"
+
+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 "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 "Îäèí áóôåð âûãðóæåí èç ïàìÿòè"
+
+#, c-format
+msgid "%d buffers unloaded"
+msgstr "Âñåãî âûãðóæåíî áóôåðîâ èç ïàìÿòè: %d"
+
+msgid "1 buffer deleted"
+msgstr "Îäèí áóôåð óäàë¸í"
+
+#, c-format
+msgid "%d buffers deleted"
+msgstr "Âñåãî óäàëåíî áóôåðîâ: %d"
+
+msgid "1 buffer wiped out"
+msgstr "Îäèí áóôåð î÷èùåí"
+
+#, c-format
+msgid "%d buffers wiped out"
+msgstr "Âñåãî î÷èùåíî áóôåðîâ: %d"
+
+msgid "E84: No modified buffer found"
+msgstr "E84: Èçìåí¸ííûõ áóôåðîâ íå îáíàðóæåíî"
+
+#. back where we started, didn't find anything.
+msgid "E85: There is no listed buffer"
+msgstr "E85: Áóôåðû â ñïèñêå îòñóòñòâóþò"
+
+#, c-format
+msgid "E86: Buffer %ld does not exist"
+msgstr "E86: Áóôåð %ld íå ñóùåñòâóåò"
+
+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 "E90: Cannot unload last buffer"
+msgstr "E90: Íåâîçìîæíî âûãðóçèòü èç ïàìÿòè ïîñëåäíèé áóôåð"
+
+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 "Îäíà ñòðîêà --%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 "[Íåò èìåíè]"
+
+#. must be a help buffer
+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 "[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 id=%d èìÿ=%s"
+
+#, c-format
+msgid "E96: Can not 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: Íåâîçìîæíî ñîçäàòü ôàéëû îòëè÷èé"
+
+msgid "Patch file"
+msgstr "Ôàéë-çàïëàòêà"
+
+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: Àêòèâíûé áóôåð íå íàõîäèòñÿ â ðåæèìå îòëè÷èé"
+
+msgid "E793: No other buffer in diff mode is modifiable"
+msgstr "E793: Áîëüøå íåò èçìåíÿåìûõ áóôåðîâ â ðåæèìå îòëè÷èé"
+
+msgid "E100: No other buffer in diff mode"
+msgstr "E100: Áîëüøå íåò áóôåðîâ â ðåæèìå îòëè÷èé"
+
+msgid "E101: More than two buffers in diff mode, don't know which one to use"
+msgstr "E101:  ðåæèìå îòëè÷èé áîëåå äâóõ áóôåðîâ, íå ìîãó âûáðàòü"
+
+#, 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\" íå íàõîäèòñÿ â ðåæèìå îòëè÷èé"
+
+msgid "E787: Buffer changed unexpectedly"
+msgstr "E787: Áóôåð íåîæèäàííî èçìåíèëñÿ"
+
+msgid "E104: Escape not allowed in digraph"
+msgstr "E104: Ýêðàíèðóþùèé ñèìâîë Escape íåëüçÿ èñïîëüçîâàòü â äèãðàôå"
+
+msgid "E544: Keymap file not found"
+msgstr "E544: Ôàéë ñ ðàñêëàäêîé êëàâèàòóðû íå íàéäåí"
+
+msgid "E105: Using :loadkeymap not in a sourced file"
+msgstr "E105: Êîìàíäà :loadkeymap ïðèìåíåíà âíå ôàéëà ñöåíàðèÿ"
+
+msgid "E791: Empty keymap entry"
+msgstr "E791: ïóñòàÿ çàïèñü ðàñêëàäêè êëàâèàòóðû"
+
+msgid " Keyword completion (^N^P)"
+msgstr " Àâòîäîïîëíåíèå êëþ÷åâîãî ñëîâà (^N^P)"
+
+#. ctrl_x_mode == 0, ^P/^N compl.
+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 " 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.
+#.
+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 "E684: list index out of range: %ld"
+msgstr "E684: Èíäåêñ ñïèñêà çà ïðåäåëàìè äèàïàçîíà: %ld"
+
+#, c-format
+msgid "E121: Undefined variable: %s"
+msgstr "E121: Íåîïðåäåë¸ííàÿ ïåðåìåííàÿ: %s"
+
+msgid "E111: Missing ']'"
+msgstr "E111: Ïðîïóùåíà ']'"
+
+#, c-format
+msgid "E686: Argument of %s must be a List"
+msgstr "E686: Ïàðàìåòð %s äîëæåí áûòü ñïèñêîì"
+
+#, c-format
+msgid "E712: Argument of %s must be a List or Dictionary"
+msgstr "E712: Ïàðàìåòð %s äîëæåí áûòü ñïèñêîì èëè ñëîâàð¸ì"
+
+msgid "E713: Cannot use empty key for Dictionary"
+msgstr "E713: Íåâîçìîæíî èñïîëüçîâàòü ïóñòîé êëþ÷ äëÿ ñëîâàðÿ"
+
+msgid "E714: List required"
+msgstr "E714: Òðåáóåòñÿ ñïèñîê"
+
+msgid "E715: Dictionary required"
+msgstr "E715: Òðåáóåòñÿ ñëîâàðü"
+
+#, 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"
+
+#, 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: Òðåáóåòñÿ ññûëêà íà ôóíêöèþ"
+
+msgid "E719: Cannot use [:] with a Dictionary"
+msgstr "E719: Íåâîçìîæíî èñïîëüçîâàòü [:] ñî ñëîâàð¸ì"
+
+#, c-format
+msgid "E734: Wrong variable type for %s="
+msgstr "E734: Íåïðàâèëüíûé òèï ïåðåìåííîé äëÿ %s="
+
+#, c-format
+msgid "E130: Unknown function: %s"
+msgstr "E130: Íåèçâåñòíàÿ ôóíêöèÿ: %s"
+
+#, c-format
+msgid "E461: Illegal variable name: %s"
+msgstr "E461: Íåäîïóñòèìîå èìÿ ïåðåìåííîé: %s"
+
+msgid "E806: using Float as a String"
+msgstr "E806: Èñïîëüçîâàíèå ÷èñëà ñ ïëàâàþùåé òî÷êîé êàê ñòðîêè"
+
+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: [:] òðåáóåò çíà÷åíèåì ñïèñîê"
+
+msgid "E710: List value has more items than target"
+msgstr "E710: Ýëåìåíòîâ ñïèñêà-çíà÷åíèÿ áîëüøå ÷åì â öåëè"
+
+msgid "E711: List value has not enough items"
+msgstr "E711: Ñïèñîê-çíà÷åíèå íå ñîäåðæèò äîñòàòî÷íî ýëåìåíòîâ"
+
+msgid "E690: Missing \"in\" after :for"
+msgstr "E690: Ïðîïóùåíî \"in\" ïîñëå :for"
+
+#, c-format
+msgid "E107: Missing parentheses: %s"
+msgstr "E107: Ïðîïóùåíû ñêîáêè: %s"
+
+#, c-format
+msgid "E108: No such variable: \"%s\""
+msgstr "E108: Íåò òàêîé ïåðåìåííîé: \"%s\""
+
+msgid "E743: variable nested too deep for (un)lock"
+msgstr "E743: Ñëèøêîì ãëóáîêî âëîæåííûå ïåðåìåííûå äëÿ (ðàç)áëîêèðîâêè"
+
+msgid "E109: Missing ':' after '?'"
+msgstr "E109: Ïðîïóùåíî ':' ïîñëå '?'"
+
+msgid "E691: Can only compare List with List"
+msgstr "E691: Ñïèñîê ìîæíî ñðàâíèâàòü òîëüêî ñî ñïèñêîì"
+
+msgid "E692: Invalid operation for Lists"
+msgstr "E692: Íåäîïóñòèìàÿ îïåðàöèÿ äëÿ ñïèñêîâ"
+
+msgid "E735: Can only compare Dictionary with Dictionary"
+msgstr "E735: Ñëîâàðü ìîæíî ñðàâíèâàòü òîëüêî ñî ñëîâàð¸ì"
+
+msgid "E736: Invalid operation for Dictionary"
+msgstr "E736: Íåäîïóñòèìàÿ îïåðàöèÿ äëÿ ñëîâàðÿ"
+
+msgid "E693: Can only compare Funcref with Funcref"
+msgstr "E693: Ññûëêó íà ôóíêöèþ ìîæíî ñðàâíèâàòü òîëüêî ñ ññûëêîé íà ôóíêöèþ"
+
+msgid "E694: Invalid operation for Funcrefs"
+msgstr "E694: Íåäîïóñòèìàÿ îïåðàöèÿ äëÿ ññûëêè íà ôóíêöèþ"
+
+msgid "E804: Cannot use '%' with Float"
+msgstr "E804: Íåâîçìîæíî èñïîëüçîâàòü '%' ñ ÷èñëîì ñ ïëàâàþùåé òî÷êîé"
+
+msgid "E110: Missing ')'"
+msgstr "E110: Ïðîïóùåíà ')'"
+
+msgid "E695: Cannot index a Funcref"
+msgstr "E695: Íåâîçìîæíî èíäåêñèðîâàòü ññûëêó íà ôóíêöèþ"
+
+#, 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"
+
+#, c-format
+msgid "E696: Missing comma in List: %s"
+msgstr "E696: Ïðîïóùåíà çàïÿòàÿ â ñïèñêå: %s"
+
+#, c-format
+msgid "E697: Missing end of List ']': %s"
+msgstr "E697: Ïðîïóùåíî îêîí÷àíèå ñïèñêà ']': %s"
+
+#, 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 "E724: variable nested too deep for displaying"
+msgstr "E724: Ñëèøêîì ãëóáîêî âëîæåííûå ïåðåìåííûå äëÿ îòîáðàæåíèÿ"
+
+#, 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 çàäàíû íåâåðíî"
+
+#, c-format
+msgid "E117: Unknown function: %s"
+msgstr "E117: Íåèçâåñòíàÿ ôóíêöèÿ: %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 "E808: Number or Float required"
+msgstr "E808: Òðåáóåòñÿ öåëîå ÷èñëî èëè ñ ïëàâàþùåé òî÷êîé"
+
+#. Èñïîëüçóåòñÿ äëÿ ïîëó÷åíèÿ "çíà÷åíèå ïàðàìåòðà p()" â E741 è E742
+msgid "add() argument"
+msgstr "ïàðàìåòðà add()"
+
+msgid "E699: Too many arguments"
+msgstr "E699: Ñëèøêîì ìíîãî ïàðàìåòðîâ"
+
+msgid "E785: complete() can only be used in Insert mode"
+msgstr "E785: complete() ìîæåò èñïîëüçîâàòüñÿ òîëüêî â ðåæèìå Âñòàâêè"
+
+#.
+#. * 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"
+
+#, c-format
+msgid "E737: Key already exists: %s"
+msgstr "E737: Êëþ÷ óæå ñóùåñòâóåò: %s"
+
+#. Èñïîëüçóåòñÿ äëÿ ïîëó÷åíèÿ "çíà÷åíèå ïàðàìåòðà p()" â E741 è E742
+msgid "extend() argument"
+msgstr "ïàðàìåòðà extend()"
+
+#. Èñïîëüçóåòñÿ äëÿ ïîëó÷åíèÿ "çíà÷åíèå ïàðàìåòðà p()" â E741 è E742
+msgid "map() argument"
+msgstr "ïàðàìåòðà map()"
+
+#. Èñïîëüçóåòñÿ äëÿ ïîëó÷åíèÿ "çíà÷åíèå ïàðàìåòðà p()" â E741 è E742
+msgid "filter() argument"
+msgstr "ïàðàìåòðà filter()"
+
+#, c-format
+msgid "+-%s%3ld lines: "
+msgstr "+-%s%3ld ñòðîê: "
+
+#, c-format
+msgid "E700: Unknown function: %s"
+msgstr "E700: Íåèçâåñòíàÿ ôóíêöèÿ: %s"
+
+msgid ""
+"&OK\n"
+"&Cancel"
+msgstr ""
+"&OK\n"
+"&C Îòìåíà"
+
+msgid "called inputrestore() more often than inputsave()"
+msgstr "Ôóíêöèÿ inputrestore() âûçûâàåòñÿ ÷àùå, ÷åì ôóíêöèÿ inputsave()"
+
+#. Èñïîëüçóåòñÿ äëÿ ïîëó÷åíèÿ "çíà÷åíèå ïàðàìåòðà p()" â E741 è E742
+msgid "insert() argument"
+msgstr "ïàðàìåòðà insert()"
+
+msgid "E786: Range not allowed"
+msgstr "E786: Äèàïàçîí íå äîïóñêàåòñÿ"
+
+msgid "E701: Invalid type for len()"
+msgstr "E701: Íåïðàâèëüíûå òèï äëÿ len()"
+
+msgid "E726: Stride is zero"
+msgstr "E726: Íóëåâîé øàã"
+
+msgid "E727: Start past end"
+msgstr "E727: Íà÷àëî ïîñëå êîíöà"
+
+msgid "<empty>"
+msgstr "<ïóñòî>"
+
+msgid "E240: No connection to Vim server"
+msgstr "E240: Íåò ñâÿçè ñ ñåðâåðîì Vim"
+
+#, c-format
+msgid "E241: Unable to send to %s"
+msgstr "E241: Íå ìîãó îòïðàâèòü ñîîáùåíèå äëÿ %s"
+
+msgid "E277: Unable to read a server reply"
+msgstr "E277: Ñåðâåð íå îòâå÷àåò"
+
+#. Èñïîëüçóåòñÿ äëÿ ïîëó÷åíèÿ "çíà÷åíèå ïàðàìåòðà p()" â E741 è E742
+msgid "remove() argument"
+msgstr "ïàðàìåòðà remove()"
+
+msgid "E655: Too many symbolic links (cycle?)"
+msgstr "E655: Ñëèøêîì ìíîãî ñèìâîëè÷åñêèõ ññûëîê (öèêë?)"
+
+#. Èñïîëüçóåòñÿ äëÿ ïîëó÷åíèÿ "çíà÷åíèå ïàðàìåòðà p()" â E741 è E742
+msgid "reverse() argument"
+msgstr "ïàðàìåòðà reverse()"
+
+msgid "E258: Unable to send to client"
+msgstr "E258: Íå ìîãó îòâåòèòü êëèåíòó"
+
+#. Èñïîëüçóåòñÿ äëÿ ïîëó÷åíèÿ "çíà÷åíèå ïàðàìåòðà p()" â E741 è E742
+msgid "sort() argument"
+msgstr "ïàðàìåòðà sort()"
+
+msgid "E702: Sort compare function failed"
+msgstr "E702: Íåóäà÷íîå çàâåðøåíèå ôóíêöèè ñðàâíåíèÿ ïðè ñîðòèðîâêå"
+
+msgid "(Invalid)"
+msgstr "(Íåïðàâèëüíî)"
+
+msgid "E677: Error writing temp file"
+msgstr "E677: Îøèáêà çàïèñè âî âðåìåííûé ôàéë"
+
+msgid "E805: Using a Float as a Number"
+msgstr "E805: Èñïîëüçîâàíèå ÷èñëà ñ ïëàâàþùåé òî÷êîé êàê öåëîãî"
+
+msgid "E703: Using a Funcref as a Number"
+msgstr "E703: Èñïîëüçîâàíèå ññûëêè íà ôóíêöèþ êàê ÷èñëà"
+
+msgid "E745: Using a List as a Number"
+msgstr "E745: Èñïîëüçîâàíèå ñïèñêà êàê ÷èñëà"
+
+msgid "E728: Using a Dictionary as a Number"
+msgstr "E728: Èñïîëüçîâàíèå ñëîâàðÿ êàê ÷èñëà"
+
+msgid "E729: using Funcref as a String"
+msgstr "E729: Èñïîëüçîâàíèå ññûëêè íà ôóíêöèþ êàê ñòðîêè"
+
+msgid "E730: using List as a String"
+msgstr "E730: Èñïîëüçîâàíèå ñïèñêà êàê ñòðîêè"
+
+msgid "E731: using Dictionary as a String"
+msgstr "E731: Èñïîëüçîâàíèå ñëîâàðÿ êàê ñòðîêè"
+
+#, c-format
+msgid "E706: Variable type mismatch for: %s"
+msgstr "E706: Íåñîîòâåòñòâèå òèïà ïåðåìåííîé äëÿ: %s"
+
+#, 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: Èìÿ ïåðåìåííîé ññûëêè íà ôóíêöèþ äîëæíî íà÷èíàòüñÿ ñ çàãëàâíîé áóêâû: "
+"%s"
+
+#, c-format
+msgid "E705: Variable name conflicts with existing function: %s"
+msgstr "E705: Èìÿ ïåðåìåííîé êîíôëèêòóåò ñ ñóùåñòâóþùåé ôóíêöèåé: %s"
+
+#. Èñïîëüçóåòñÿ ñ %s = "ïàðàìåòåðà p"
+#, c-format
+msgid "E741: Value is locked: %s"
+msgstr "E741: Çíà÷åíèå %s çàáëîêèðîâàíî"
+
+msgid "Unknown"
+msgstr "Íåèçâåñòíî"
+
+#. Èñïîëüçóåòñÿ ñ %s = "ïàðàìåòåðà p()"
+#, c-format
+msgid "E742: Cannot change value of %s"
+msgstr "E742: Íåâîçìîæíî èçìåíèòü çíà÷åíèå %s"
+
+msgid "E698: variable nested too deep for making a copy"
+msgstr "E698: Ñëèøêîì ãëóáîêî âëîæåííûå ïåðåìåííûå äëÿ êîïèðîâàíèÿ"
+
+#, 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 "E125: Illegal argument: %s"
+msgstr "E125: Íåäîïóñòèìûé ïàðàìåòð: %s"
+
+#, c-format
+msgid "E853: Duplicate argument name: %s"
+msgstr "E853: Ïîâòîðÿþùååñÿ èìÿ ïàðàìåòðà: %s"
+
+msgid "E126: Missing :endfunction"
+msgstr "E126: Ïðîïóùåíà êîìàíäà :endfunction"
+
+#, 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"
+
+msgid "E129: Function name required"
+msgstr "E129: Òðåáóåòñÿ èìÿ ôóíêöèè"
+
+#, c-format
+msgid "E128: Function name must start with a capital or contain a colon: %s"
+msgstr ""
+"E128: Èìÿ ôóíêöèè äîëæíî íà÷èíàòüñÿ ñ çàãëàâíîé áóêâû èëè ñîäåðæàòü "
+"äâîåòî÷èå: %s"
+
+#, c-format
+msgid "E131: Cannot delete function %s: It is in use"
+msgstr "E131: Íåâîçìîæíî óäàëèòü ôóíêöèþ %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"
+
+#, c-format
+msgid "continuing in %s"
+msgstr "ïðîäîëæåíèå â %s"
+
+msgid "E133: :return not inside a function"
+msgstr "E133: êîìàíäà :return âíå ôóíêöèè"
+
+msgid ""
+"\n"
+"# global variables:\n"
+msgstr ""
+"\n"
+"# ãëîáàëüíûå ïåðåìåííûå:\n"
+
+msgid ""
+"\n"
+"\tLast set from "
+msgstr ""
+"\n"
+"\t ïîñëåäíèé ðàç îïöèÿ èçìåíåíà â "
+
+msgid "No old files"
+msgstr "Íåò ñòàðûõ ôàéëîâ"
+
+#, 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, 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: Ñòðîêè ïåðåìåùàþòñÿ ñàìè íà ñåáÿ"
+
+msgid "1 line moved"
+msgstr "Ïåðåìåùåíà îäíà ñòðîêà"
+
+#, 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: Àâòîêîìàíäû *Filter* íå äîëæíû èçìåíÿòü àêòèâíûé áóôåð"
+
+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 " ÍÅÓÄÀ×ÍÎ"
+
+#. avoid a wait_return for this message, it's annoying
+#, c-format
+msgid "E137: Viminfo file is not writable: %s"
+msgstr "E137: Ïðàâà íà çàïèñü ôàéëà viminfo îòñóòñòâóþò: %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\""
+
+#. Write the info:
+#, 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 "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 "Ñâîï-ôàéë \"%s\" ñóùåñòâóåò, ïåðåçàïèñàòü?"
+
+#, c-format
+msgid "E768: Swap file exists: %s (:silent! overrides)"
+msgstr "E768: Ñâîï-ôàéë ñóùåñòâóåò: %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 ""
+"Äëÿ \"%s\" âêëþ÷åíà îïöèÿ 'readonly'.\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: Èñïîëüçîâàíèå êîìàíä îáîëî÷êè íå äîïóñêàåòñÿ â 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 "Îäíî ñîîòâåòñòâèå"
+
+msgid "1 substitution"
+msgstr "Îäíà çàìåíà"
+
+#, c-format
+msgid "%ld matches"
+msgstr "%ld ñîîòâåòñòâèé"
+
+#, c-format
+msgid "%ld substitutions"
+msgstr "%ld çàìåí"
+
+msgid " on 1 line"
+msgstr " â îäíîé ñòðîêå"
+
+#, c-format
+msgid " on %ld lines"
+msgstr " â %ld ñòð."
+
+msgid "E147: Cannot do :global recursive"
+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 "E150: Not a directory: %s"
+msgstr "E150: %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 "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"
+
+#, c-format
+msgid "E157: Invalid sign ID: %ld"
+msgstr "E157: Íåïðàâèëüíûé ID çíà÷êà: %ld"
+
+msgid " (NOT FOUND)"
+msgstr " (ÍÅ ÍÀÉÄÅÍÎ)"
+
+msgid " (not supported)"
+msgstr " (íå ïîääåðæèâàåòñÿ)"
+
+msgid "[Deleted]"
+msgstr "[Óäàëåíî]"
+
+msgid "Entering Debug mode. Type \"cont\" to continue."
+msgstr "Âêëþ÷¸í ðåæèì îòëàäêè. Äëÿ ïðîäîëæåíèÿ íàáåðèòå \"cont\""
+
+#, c-format
+msgid "line %ld: %s"
+msgstr "ñòðîêà %ld: %s"
+
+#, c-format
+msgid "cmd: %s"
+msgstr "êîìàíäà: %s"
+
+#, 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"
+
+msgid "E750: First use \":profile start {fname}\""
+msgstr "E750: Ïåðâîå èñïîëüçîâàíèå \":profile start {èìÿ-ôàéëà}\""
+
+#, c-format
+msgid "Save changes to \"%s\"?"
+msgstr "Ñîõðàíèòü èçìåíåíèÿ â \"%s\"?"
+
+msgid "Untitled"
+msgstr "Áåç èìåíè"
+
+#, 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 'runtimepath': \"%s\""
+msgstr "íå íàéäåíî â 'runtimepath': \"%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 çàâåðøåíî"
+
+msgid "modeline"
+msgstr "ðåæèìíàÿ ñòðîêà"
+
+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 "E319: Sorry, the command is not available in this version"
+msgstr "E319: Èçâèíèòå, ýòà êîìàíäà íåäîñòóïíà â äàííîé âåðñèè"
+
+msgid "E172: Only one file name allowed"
+msgstr "E172: Ðàçðåøåíî èñïîëüçîâàòü òîëüêî îäíî èìÿ ôàéëà"
+
+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 Range 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 òðåáóåòñÿ óêàçàòü ïàðàìåòð"
+
+#, 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 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!"
+
+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 "Áåç ñâîï-ôàéëà"
+
+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 "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\""
+
+#. set mark
+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: Ïóñòîå èìÿ ôàéëà äëÿ '%' èëè '#', âîçìîæíî òîëüêî c \":p:h\""
+
+msgid "E500: Evaluates to an empty string"
+msgstr "E500: Ðåçóëüòàòîì âûðàæåíèÿ ÿâëÿåòñÿ ïóñòàÿ ñòðîêà"
+
+msgid "E195: Cannot open viminfo file for reading"
+msgstr "E195: Íåâîçìîæíî îòêðûòü ôàéë viminfo äëÿ ÷òåíèÿ"
+
+msgid "E196: No digraphs in this version"
+msgstr "E196: Â ýòîé âåðñèè äèãðàôû íå ðàáîòàþò"
+
+msgid "E608: Cannot :throw exceptions with 'Vim' prefix"
+msgstr ""
+"E608: Íåâîçìîæíî âûïîëíèòü êîìàíäó :throw äëÿ èñêëþ÷åíèé ñ ïðèñòàâêîé 'Vim'"
+
+#. always scroll up, don't overwrite
+#, 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"
+
+#. always scroll up, don't overwrite
+#, 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 "Îøèáêà"
+
+#. if (pending & CSTP_INTERRUPT)
+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"
+
+#. Give up for a ":catch" after ":finally" and ignore it.
+#. * Just parse.
+msgid "E604: :catch after :finally"
+msgstr "E604: :catch áåç :finally"
+
+msgid "E606: :finally without :try"
+msgstr "E606: :finally áåç :try"
+
+#. Give up for a multiple ":finally" and ignore it.
+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 "E198: cmd_pchar beyond the command length"
+msgstr "E198: cmd_pchar áîëüøå äëèíû êîìàíäû"
+
+msgid "E199: Active window or buffer deleted"
+msgstr "E199: Óäàëåíî àêòèâíîå îêíî èëè áóôåð"
+
+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..."
+
+#. Re-opening the original file failed!
+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 "[ïåðåêîäèðîâàíî]"
+
+msgid "[blowfish]"
+msgstr "[blowfish]"
+
+msgid "[crypted]"
+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 "E821: File is encrypted with unknown method"
+msgstr "E821: Ôàéë çàøèôðîâàí íåèçâåñòíûì ìåòîäîì"
+
+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 "E460: The resource fork would be lost (add ! to override)"
+msgstr "E460: Âåòâü ðåñóðñà áóäåò ïîòåðÿíà (äîáàâüòå !, ÷òîáû îáîéòè ïðîâåðêó)"
+
+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 "E667: Fsync failed"
+msgstr "E667: Íå óäàëîñü âûïîëíèòü ôóíêöèþ fsync()"
+
+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: Ðåæèì çàïëàòêè: íåâîçìîæíî ñîõðàíåíèå èñõîäíîãî ôàéëà"
+
+msgid "E206: patchmode: can't touch empty original file"
+msgstr ""
+"E206: Ðåæèì çàïëàòêè: íåâîçìîæíî ñìåíèòü ïàðàìåòðû ïóñòîãî èñõîäíîãî ôàéëà"
+
+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"
+
+#. Explicit typecast avoids warning on Mac OS X 10.6
+#, c-format
+msgid "%ld characters"
+msgstr "ñèìâîëîâ: %ld"
+
+msgid "[noeol]"
+msgstr "[noeol]"
+
+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
+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"
+"&L Çàãðóçèòü ôàéë"
+
+#, 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>"
+
+#. the group doesn't exist
+#, c-format
+msgid "E367: No such group: \"%s\""
+msgstr "E367: Ãðóïïà \"%s\" íå ñóùåñòâóåò"
+
+#, 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"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Auto-Commands ---"
+msgstr ""
+"\n"
+"--- Àâòîêîìàíäû ---"
+
+#, c-format
+msgid "E680: <buffer=%d>: invalid buffer number "
+msgstr "E680: <buffer=%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 Auto commands 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 lines folded "
+msgstr "+--%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: Íåâîçìîæíî ñîçäàòü íîâûé ïðîöåññ äëÿ ãðàô. èíòåðôåéñà"
+
+msgid "E852: The child process failed to start the GUI"
+msgstr "E852: Ïðîöåññó-ïîòîìêó íå óäàëîñü çàïóñòèòü ãðàô. èíòåðôåéñ"
+
+msgid "E229: Cannot start the GUI"
+msgstr "E229: Íåâîçìîæíî ïåðåéòè â ðåæèì ãðàôè÷åñêîãî èíòåðôåéñà"
+
+#, c-format
+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'"
+
+#, 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 "Ïîëîñà ïðîêðóòêè: íå ìîãó îïðåäåëèòü ãåîìåòðèþ ïîëçóíêà"
+
+msgid "Vim dialog"
+msgstr "Äèàëîãîâîå îêíî Vim"
+
+msgid "E232: Cannot create BalloonEval with both message and callback"
+msgstr ""
+"E232: \"Ïóçûðü\" äëÿ âû÷èñëåíèé, âêëþ÷àþùèé è ñîîáùåíèå, è îáðàòíûé âûçîâ, "
+"íå ìîæåò áûòü ñîçäàí"
+
+msgid ""
+"&Yes\n"
+"&No\n"
+"&Cancel"
+msgstr ""
+"&Äà\n"
+"&Íåò\n"
+"Î&òìåíà"
+
+msgid "Input _Methods"
+msgstr "Ìåòîäû Ââîäà"
+
+msgid "VIM - Search and Replace..."
+msgstr "VIM — Ïîèñê è çàìåíà..."
+
+msgid "VIM - Search..."
+msgstr "VIM — Ïîèñê..."
+
+msgid "Find what:"
+msgstr "×òî èùåì:"
+
+msgid "Replace with:"
+msgstr "Íà ÷òî çàìåíÿåì:"
+
+#. whole word only button
+msgid "Match whole word only"
+msgstr "Òîëüêî òî÷íûå ñîîòâåòñòâèÿ"
+
+#. match case button
+msgid "Match case"
+msgstr "Ðåãèñòðîçàâèñèìûå ñîîòâåòñòâèÿ"
+
+msgid "Direction"
+msgstr "Íàïðàâëåíèå"
+
+#. 'Up' and 'Down' buttons
+msgid "Up"
+msgstr "Ââåðõ"
+
+msgid "Down"
+msgstr "Âíèç"
+
+#. 'Find Next' button
+msgid "Find Next"
+msgstr "Íàéòè ñëåäóþùåå"
+
+#. 'Replace' button
+msgid "Replace"
+msgstr "Çàìåíà"
+
+#. 'Replace All' button
+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 "Î&òìåíà"
+
+#, 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 "Close tab"
+msgstr "Çàêðûòü âêëàäêó"
+
+msgid "Open tab..."
+msgstr "Îòêðûòü âêëàäêó..."
+
+msgid "Find string (use '\\\\' to find a '\\')"
+msgstr "Ïîèñê ñòðîêè (èñïîëüçóéòå '\\\\' äëÿ ïîèñêà '\\')"
+
+msgid "Find & Replace (use '\\\\' to find a '\\')"
+msgstr "Ïîèñê è çàìåíà (èñïîëüçóéòå '\\\\' äëÿ ïîèñêà '\\')"
+
+#. 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 "Íå èñïîëüçóåòñÿ"
+
+msgid "Directory\t*.nothing\n"
+msgstr "Êàòàëîã\t*.íè÷åãî\n"
+
+msgid "Vim E458: Cannot allocate colormap entry, some colors may be incorrect"
+msgstr ""
+"Vim E458: Íåâîçìîæíî âûäåëèòü çàïèñü â òàáëèöå öâåòà, íåêîòîðûå öâåòà ìîãóò "
+"îòîáðàæàòüñÿ íåïðàâèëüíî"
+
+#, 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 "Font0: %s"
+
+#, c-format
+msgid "Font1: %s"
+msgstr "Font1: %s"
+
+#, c-format
+msgid "Font%ld width is not twice that of font0"
+msgstr "Øèðèíà øðèôòà font%ld äîëæíà áûòü âäâîå áîëüøå øèðèíû øðèôòà font0"
+
+#, c-format
+msgid "Font0 width: %ld"
+msgstr "Øèðèíà øðèôòà font0: %ld"
+
+#, c-format
+msgid "Font1 width: %ld"
+msgstr "Øèðèíà øðèôòà font1: %ld"
+
+msgid "Invalid font specification"
+msgstr "Íåïðàâèëüíîå îïðåäåëåíèå øðèôòà"
+
+msgid "&Dismiss"
+msgstr "Î&òêëîíèòü"
+
+msgid "no specific match"
+msgstr "íåò ñïåöèàëüíîãî ñîâïàäåíèÿ"
+
+msgid "Vim - Font Selector"
+msgstr "Vim — Âûáîð øðèôòà"
+
+msgid "Name:"
+msgstr "Íàçâàíèå:"
+
+#. create toggle button
+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 "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 \"%s\""
+
+#, c-format
+msgid "E618: file \"%s\" is not a PostScript resource file"
+msgstr "E618: Ôàéë \"%s\" íå ÿâëÿåòñÿ ôàéëîì ðåñóðñîâ PostScript"
+
+#, c-format
+msgid "E619: file \"%s\" is not a supported PostScript resource file"
+msgstr "E619: Ôàéë \"%s\" íå ÿâëÿåòñÿ äîïóñòèìûì ôàéëîì ðåñóðñîâ PostScript"
+
+#, c-format
+msgid "E621: \"%s\" resource file has wrong version"
+msgstr "E621: Ôàéë ðåñóðñîâ \"%s\" íåèçâåñòíîé âåðñèè"
+
+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 \"prolog.ps\" íå íàéäåí"
+
+msgid "E456: Can't find PostScript resource file \"cidfont.ps\""
+msgstr "E456: Ôàéë ðåñóðñîâ PostScript \"cidfont.ps\" íå íàéäåí"
+
+#, c-format
+msgid "E456: Can't find PostScript resource file \"%s.ps\""
+msgstr "E456: Ôàéë ðåñóðñîâ PostScript \"%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 <èìÿ>"
+
+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: Íåâîçìîæíî âûïîëíèòü fork() äëÿ 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"
+" 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"
+
+#, 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 óæå ïîäñîåäèíåíà"
+
+#, c-format
+msgid "E261: cscope connection %s not found"
+msgstr "E261: Ñîåäèíåíèå ñ cscope %s íå îáíàðóæåíî"
+
+#, c-format
+msgid "cscope connection %s closed"
+msgstr "ñîåäèíåíèå ñ cscope %s çàêðûòî"
+
+#. should not reach here
+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 "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: Íåîáðàáîòàííîå èñêëþ÷åíèå"
+
+#, c-format
+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 "ïîäñîåäèí¸í"
+
+#, c-format
+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 "îòìåòêà íå óñòàíîâëåíà"
+
+#, 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 ""
+"íåâîçìîæíî çàðåãèñòðèðîâàòü êîìàíäó ñ îáðàòíûì âûçîâîì: áóôåð èëè îêíî â "
+"ïðîöåññå óäàëåíèÿ"
+
+#. This should never happen. Famous last word?
+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"
+
+#, 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 â ðååñòðå. "
+"Óäàëåíî!"
+
+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 ""
+"Ñëèøêîì ìíîãî ïàðàìåòðîâ \"+êîìàíäà\", \"-c êîìàíäà\" èëè \"--cmd êîìàíäà\""
+
+msgid "Invalid argument for"
+msgstr "Íåäîïóñòèìûé ïàðàìåòð äëÿ"
+
+#, c-format
+msgid "%d files to edit\n"
+msgstr "Ôàéëîâ äëÿ ðåäàêòèðîâàíèÿ: %d\n"
+
+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 "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: Warning: Output is not to a terminal\n"
+msgstr "Vim: Ïðåäóïðåæäåíèå: Âûâîä îñóùåñòâëÿåòñÿ íå íà òåðìèíàë\n"
+
+msgid "Vim: Warning: Input is not from a terminal\n"
+msgstr "Vim: Ïðåäóïðåæäåíèå: Ââîä ïðîèñõîäèò íå ñ òåðìèíàëà\n"
+
+#. just in case..
+msgid "pre-vimrc command line"
+msgstr "êîìàíäíàÿ ñòðîêà ïåðåä âûïîëíåíèåì 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 ìåòêà ðåäàêòèðîâàíèå ôàéëà ñ óêàçàííîé ìåòêîé"
+
+# \n\t\t.. äëÿ óìåùåíèÿ â 80 ñòîëáöîâ
+msgid "-q [errorfile] edit file with first error"
+msgstr ""
+"-q [ôàéë-îøèáîê]\n"
+"\t\t\t\t ðåäàêòèðîâàíèå ôàéëà ñ ïåðâîé îøèáêîé"
+
+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Çàïóñòèòü ñ ãðàôè÷åñêèì èíòåðôåéñîì (êàê \"gvim\")"
+
+msgid "-f or --nofork\tForeground: Don't fork when starting GUI"
+msgstr "-f èëè --nofork\t àêòèâíîé çàäà÷å: Íå âûïîëíÿòü fork ïðè çàïóñêå GUI"
+
+msgid "-v\t\t\tVi mode (like \"vi\")"
+msgstr "-v\t\t\tÐåæèì Vi (êàê \"vi\")"
+
+msgid "-e\t\t\tEx mode (like \"ex\")"
+msgstr "-e\t\t\tÐåæèì Ex (êàê \"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Òèõèé (ïàêåòíûé) ðåæèì (òîëüêî äëÿ \"ex\")"
+
+msgid "-d\t\t\tDiff mode (like \"vimdiff\")"
+msgstr "-d\t\t\tÐåæèì îòëè÷èé (êàê \"vimdiff\")"
+
+msgid "-y\t\t\tEasy mode (like \"evim\", modeless)"
+msgstr "-y\t\t\tÏðîñòîé ðåæèì (êàê \"evim\", áåçðåæèìíûé)"
+
+msgid "-R\t\t\tReadonly mode (like \"view\")"
+msgstr "-R\t\t\tÒîëüêî äëÿ ÷òåíèÿ (êàê \"view\")"
+
+msgid "-Z\t\t\tRestricted mode (like \"rvim\")"
+msgstr "-Z\t\t\tÎãðàíè÷åííûé ðåæèì (êàê \"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\tÐåæèì Lisp"
+
+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'"
+
+# \n\t\t.. äëÿ óìåùåíèÿ â 80 ñòîëáöîâ
+msgid "-V[N][fname]\t\tBe verbose [level N] [log messages to fname]"
+msgstr ""
+"-V[N][ôàéë]\t\tÂûâîäèòü äîïîëíèòåëüíûå ñîîáùåíèÿ\n"
+"\t\t\t\t[óðîâåíü N] [çàïèñûâàòü â ôàéë]"
+
+msgid "-D\t\t\tDebugging mode"
+msgstr "-D\t\t\tÐåæèì îòëàäêè"
+
+msgid "-n\t\t\tNo swap file, use memory only"
+msgstr "-n\t\t\tÁåç ñâîï-ôàéëà, èñïîëüçóåòñÿ òîëüêî ïàìÿòü"
+
+msgid "-r\t\t\tList swap files and exit"
+msgstr "-r\t\t\tÂûâåñòè ñïèñîê ñâîï-ôàéëîâ è çàâåðøèòü ðàáîòó"
+
+msgid "-r (with file name)\tRecover crashed session"
+msgstr "-r (ñ èìåíåì ôàéëà)\tÂîññòàíîâèòü àâàðèéíî çàâåðø¸ííûé ñåàíñ"
+
+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Íå èñïîëüçîâàòü newcli äëÿ îòêðûòèÿ îêíà"
+
+msgid "-dev <device>\t\tUse <device> for I/O"
+msgstr "-dev <óñòðîéñòâî>\t\tÈñïîëüçîâàòü äëÿ I/O óêàçàííîå <óñòðîéñòâî>"
+
+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 "-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Íå çàãðóæàòü ñöåíàðèè ìîäóëåé"
+
+# \n\t\t.. äëÿ óìåùåíèÿ â 80 ñòîëáöîâ
+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 ñòîëáöîâ
+msgid "-o[N]\t\tOpen N windows (default: one for each file)"
+msgstr ""
+"-o[N]\t\tÎòêðûòü N îêîí (ïî óìîë÷àíèþ: ïî îäíîìó\n"
+"\t\t\t\tíà êàæäûé ôàéë)"
+
+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 "+<lnum>\t\tÍà÷àòü ðåäàêòèðîâàíèå â ñòðîêå ñ íîìåðîì <lnum>"
+
+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Âûïîëíèòü <êîìàíäó> ïîñëå çàãðóçêè ïåðâîãî ôàéëà"
+
+# \n\t\t.. äëÿ óìåùåíèÿ â 80 ñòîëáöîâ
+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 ñòîëáöîâ
+msgid "-s <scriptin>\tRead Normal mode commands from file <scriptin>"
+msgstr ""
+"-s <ñöåíàðèé>\tÏðî÷èòàòü êîìàíäû Îáû÷íîãî ðåæèìà èç\n"
+"\t\t\t\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 "-h or --help\tPrint Help (this message) and exit"
+msgstr "-h èëè --help\tÂûâåñòè ñïðàâêó (ýòî ñîîáùåíèå) è çàâåðøèòü ðàáîòó"
+
+msgid "--version\t\tPrint version information and exit"
+msgstr "--version\t\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 "Íåò äèñïëåÿ"
+
+#. Failed to send, abort.
+msgid ": Send failed.\n"
+msgstr ": Îòïðàâêà íå óäàëàñü.\n"
+
+#. Let vim start normally.
+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\""
+
+#. Highlight title
+msgid ""
+"\n"
+"mark line col file/text"
+msgstr ""
+"\n"
+"îòìåò ñòð êîë ôàéë/òåêñò"
+
+#. Highlight title
+msgid ""
+"\n"
+" jump line col file/text"
+msgstr ""
+"\n"
+"ïðûæîê ñòð êîë ôàéë/òåêñò"
+
+#. Highlight title
+msgid ""
+"\n"
+"change line col text"
+msgstr ""
+"\n"
+"èçìåí. ñòð êîë òåêñò"
+
+msgid ""
+"\n"
+"# File marks:\n"
+msgstr ""
+"\n"
+"# Ãëîáàëüíûå îòìåòêè:\n"
+
+#. Write the jumplist with -'
+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: Íåâîçìîæíî íàçíà÷èòü çíà÷åíèÿ êîíòåêñòà ââîäà"
+
+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 "E293: block was not locked"
+msgstr "E293: Áëîê íå çàáëîêèðîâàí"
+
+msgid "E294: Seek error in swap file read"
+msgstr "E294: Îøèáêà ïîèñêà ïðè ÷òåíèè ñâîï-ôàéëà"
+
+msgid "E295: Read error in swap file"
+msgstr "E295: Îøèáêà ÷òåíèÿ ñâîï-ôàéëà"
+
+msgid "E296: Seek error in swap file write"
+msgstr "E296: Îøèáêà ïîèñêà ïðè çàïèñè ñâîï-ôàéëà"
+
+msgid "E297: Write error in swap file"
+msgstr "E297: Îøèáêà ïðè çàïèñè ñâîï-ôàéëà"
+
+msgid "E300: Swap file already exists (symlink attack?)"
+msgstr ""
+"E300: Ñâîï-ôàéë óæå ñóùåñòâóåò (àòàêà ñ èñïîëüçîâàíèåì ñèìâîëüíîé ññûëêè?)"
+
+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: Îøèáêà ïðè îáíîâëåíèè øèôðîâàíèÿ ñâîï-ôàéëà"
+
+#. could not (re)open the swap file, what can we do????
+msgid "E301: Oops, lost the swap file!!!"
+msgstr "E301: Îé, ïîòåðÿëñÿ ñâîï-ôàéë!!!"
+
+msgid "E302: Could not rename swap file"
+msgstr "E302: Íåâîçìîæíî ïåðåèìåíîâàòü ñâîï-ôàéë"
+
+#, c-format
+msgid "E303: Unable to open swap file for \"%s\", recovery impossible"
+msgstr ""
+"E303: Íå óäàëîñü îòêðûòü ñâîï-ôàéë äëÿ \"%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 íå íàéäåí"
+
+msgid "Enter number of swap file to use (0 to quit): "
+msgstr ""
+"Ââåäèòå íîìåð ñâîï-ôàéëà, êîòîðûé ñëåäóåò èñïîëüçîâàòü (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 íå ñìîã îáíîâèòü ñâîï-ôàéë"
+
+msgid " cannot be used with this version of Vim.\n"
+msgstr " íåëüçÿ èñïîëüçîâàòü â äàííîé âåðñèè Vim.\n"
+
+msgid "Use Vim version 3.0.\n"
+msgstr "Èñïîëüçóéòå Vim âåðñèè 3.0.\n"
+
+#, c-format
+msgid "E307: %s does not look like a Vim swap file"
+msgstr "E307: %s íå ÿâëÿåòñÿ ñâîï-ôàéëîì Vim"
+
+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 "Èñïîëüçóåòñÿ ñâîï-ôàéë \"%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 "Ñâîï-ôàéë çàøèôðîâàí: \"%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: Íåâîçìîæíî ïðî÷èòàòü áëîê 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: Íåïðàâèëüíûé áëîê 1 ID (%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 "Âîññòàíîâëåíèå çàâåðøåíî. Ïðîâåðüòå, âñ¸ ëè â ïîðÿäêå."
+
+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 "Èñïîëüçîâàíèå êëþ÷à øèôðîâàíèÿ èç ñâîï-ôàéëà äëÿ òåêñòîâîãî ôàéëà.\n"
+
+#. use msg() to start the scrolling properly
+msgid "Swap files found:"
+msgstr "Îáíàðóæåíû ñâîï-ôàéëû:"
+
+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]"
+
+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: Íåâîçìîæíî îáíîâèòü ñâîï-ôàéë, ïîñêîëüêó îí íå îáíàðóæåí"
+
+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: Ïåòëÿ ñèìâîëüíûõ ññûëîê äëÿ \"%s\""
+
+msgid "E325: ATTENTION"
+msgstr "E325: ÂÍÈÌÀÍÈÅ"
+
+msgid ""
+"\n"
+"Found a swap file by the name \""
+msgstr ""
+"\n"
+"Îáíàðóæåí ñâîï-ôàéë ñ èìåíåì \""
+
+# Ñ ìàëåíüêîé áóêâû, ÷òîáû ñîîòâåòñòâîâàëî ïî ñòèëþ ñîñåäíèì ñîîáùåíèÿì.
+msgid "While opening file \""
+msgstr "ïðè îòêðûòèè ôàéëà: \""
+
+msgid " NEWER than swap file!\n"
+msgstr " Áîëåå ÑÂÅÆÈÉ, ÷åì ñâîï-ôàéë!\n"
+
+#. 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."
+msgstr ""
+"\n"
+"(1) Âîçìîæíî, ðåäàêòèðîâàíèå ýòîãî æå ôàéëà âûïîëíÿåòñÿ â äðóãîé ïðîãðàììå.\n"
+" Åñëè ýòî òàê, òî áóäüòå âíèìàòåëüíû ïðè âíåñåíèè èçìåíåíèé, ÷òîáû\n"
+" ó âàñ íå ïîÿâèëîñü äâà ðàçíûõ âàðèàíòà îäíîãî è òîãî æå ôàéëà."
+
+# Ñîîáùåíèå ðàçäåëåíî, " \n" äîáàâëåíî ò.ê. ñòðîêà íå ïîìåùàåòñÿ.
+msgid " Quit, or continue with caution.\n"
+msgstr ""
+" \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 " Åñëè âû óæå âûïîëíÿëè ýòó îïåðàöèþ, óäàëèòå ñâîï-ôàéë \""
+
+msgid ""
+"\"\n"
+" to avoid this message.\n"
+msgstr ""
+"\"\n"
+" ÷òîáû èçáåæàòü ïîÿâëåíèÿ ýòîãî ñîîáùåíèÿ â áóäóùåì.\n"
+
+msgid "Swap file \""
+msgstr "Ñâîï-ôàéë \""
+
+msgid "\" already exists!"
+msgstr "\" óæå ñóùåñòâóåò!"
+
+msgid "VIM - ATTENTION"
+msgstr "VIM — ÂÍÈÌÀÍÈÅ"
+
+msgid "Swap file already exists!"
+msgstr "Ñâîï-ôàéë óæå ñóùåñòâóåò!"
+
+msgid ""
+"&Open Read-Only\n"
+"&Edit anyway\n"
+"&Recover\n"
+"&Quit\n"
+"&Abort"
+msgstr ""
+"&O Îòêðûòü äëÿ ÷òåíèÿ\n"
+"&E Ðåäàêòèðîâàòü\n"
+"&R Âîññòàíîâèòü\n"
+"&Q Âûõîä\n"
+"&A Ïðåðâàòü"
+
+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 Ïðåðâàòü"
+
+msgid "E326: Too many swap files found"
+msgstr "E326: Îáíàðóæåíî ñëèøêîì ìíîãî ñâîï-ôàéëîâ"
+
+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"
+
+#. Only a mnemonic or accelerator is not valid.
+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: Ðàçäåëèòåëè íå ìîãóò áûòü êîìïîíåíòîì ïóòè ê ìåíþ"
+
+#. Now we have found the matching menu, and we list the mappings
+#. Highlight title
+msgid ""
+"\n"
+"--- Menus ---"
+msgstr ""
+"\n"
+"--- Ìåíþ ---"
+
+msgid "Tear off this menu"
+msgstr "Îòîðâàòü ýòî ìåíþ"
+
+msgid "E333: Menu path must lead to a menu item"
+msgstr "E333: Ïóòü ê ìåíþ äîëæåí âåñòè ê ýëåìåíòó ìåíþ"
+
+#, c-format
+msgid "E334: Menu not found: %s"
+msgstr "E334: Ìåíþ íå íàéäåíî: %s"
+
+#, c-format
+msgid "E335: Menu not defined for %s mode"
+msgstr "E335: Ìåíþ íå îïðåäåëåíî äëÿ ðåæèìà %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 ""
+"Ïåðåâîä ñîîáùåíèé íà ðóññêèé ÿçûê: Âàñèëèé Ðàãîçèí <vrr@users.sourceforge."
+"net>, Ñåðãåé Àë¸øèí <alyoshin.s@gmail.com>"
+
+msgid "Interrupt: "
+msgstr "Ïðåðûâàíèå: "
+
+msgid "Press ENTER or type command to continue"
+msgstr "Íàæìèòå ENTER èëè ââåäèòå êîìàíäó äëÿ ïðîäîëæåíèÿ"
+
+#, 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 " SPACE/d/j: ýêðàí/ñòðàíèöà/ñòðîêà âíèç, b/u/k: ââåðõ, q: âûõîä "
+
+msgid "Question"
+msgstr "Âîïðîñ"
+
+msgid ""
+"&Yes\n"
+"&No"
+msgstr ""
+"&Y Äà\n"
+"&N Íåò"
+
+msgid ""
+"&Yes\n"
+"&No\n"
+"Save &All\n"
+"&Discard All\n"
+"&Cancel"
+msgstr ""
+"&Y Äà\n"
+"&N Íåò\n"
+"&A Ñîõðàíèòü âñå\n"
+"&D Ïîòåðÿòü âñå\n"
+"&C Îòìåíà"
+
+msgid "Select Directory dialog"
+msgstr "Âûáîð êàòàëîãà"
+
+msgid "Save File dialog"
+msgstr "Ñîõðàíåíèå ôàéëà"
+
+msgid "Open File dialog"
+msgstr "Îòêðûòèå ôàéëà"
+
+#. TODO: non-GUI file selector here
+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: Îæèäàëñÿ ïàðàìåòð òèïà ñ ïëàâàþùåé òî÷êîé äëÿ 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 "Äîáàâëåíà îäíà ñòðîêà"
+
+msgid "1 line less"
+msgstr "Óáðàíà îäíà ñòðîêà"
+
+#, c-format
+msgid "%ld more lines"
+msgstr "Äîáàâëåíî ñòðîê: %ld"
+
+#, c-format
+msgid "%ld fewer lines"
+msgstr "Óáðàíî ñòðîê: %ld"
+
+msgid " (Interrupted)"
+msgstr " (Ïðåðâàíî)"
+
+msgid "Beep!"
+msgstr "Áè-áè!"
+
+msgid "Vim: preserving files...\n"
+msgstr "Vim: ñîõðàíåíèå ôàéëîâ...\n"
+
+#. close all memfiles, without deleting
+msgid "Vim: Finished.\n"
+msgstr "Vim: Ãîòîâî.\n"
+
+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: Íåäîïóñòèìàÿ ôîðìà êóðñîðà"
+
+msgid "E548: digit expected"
+msgstr "E548: Òðåáóåòñÿ ââåñòè öèôðó"
+
+msgid "E549: Illegal percentage"
+msgstr "E549: Íåäîïóñòèìîå çíà÷åíèå ïðîöåíòîâ"
+
+msgid "Enter encryption key: "
+msgstr "Ââåäèòå ïàðîëü äëÿ øèôðîâàíèÿ: "
+
+msgid "Enter same key again: "
+msgstr "Ïîâòîðèòå ââîä ïàðîëÿ: "
+
+msgid "Keys don't match!"
+msgstr "Ââåä¸ííûå ïàðîëè íå ñîâïàäàþò!"
+
+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\" íå íàéäåí â ïóòè äëÿ ñìåíû êàòàëîãà"
+
+#, c-format
+msgid "E345: Can't find file \"%s\" in path"
+msgstr "E345: Ôàéë \"%s\" â èçâåñòíûõ êàòàëîãàõ íå íàéäåí"
+
+#, c-format
+msgid "E346: No more directory \"%s\" found in cdpath"
+msgstr "E346: Â ïóòè ñìåíû êàòàëîãà áîëüøå íåò êàòàëîãîâ \"%s\""
+
+#, c-format
+msgid "E347: No more file \"%s\" found in path"
+msgstr "E347: Â èçâåñòíûõ êàòàëîãàõ áîëüøå íåò ôàéëîâ \"%s\""
+
+msgid "Cannot connect to Netbeans #2"
+msgstr "Íåâîçìîæíî ñîåäèíèòüñÿ ñ NetBeans #2"
+
+msgid "Cannot connect to Netbeans"
+msgstr "Íåâîçìîæíî ñîåäèíèòüñÿ ñ NetBeans"
+
+#, c-format
+msgid "E668: Wrong access mode for NetBeans connection info file: \"%s\""
+msgstr ""
+"E668: Íåïðàâèëüíûé ðåæèì äîñòóïà ê èíôîðìàöèè î ñîåäèíåíèè ñ NetBeans: \"%s\""
+
+msgid "read from Netbeans socket"
+msgstr "÷òåíèå èç ãíåçäà NetBeans"
+
+#, 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 íå ïîääåðæèâàåòñÿ ñ ýòèì ãðàôè÷åñêèì èíòåðôåéñîì"
+
+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 :quit<Enter> to exit Vim"
+msgstr "Ââåäèòå :quit<Enter> äëÿ âûõîäà èç 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 "Èçìåí¸í îòñòóï â îäíîé ñòðîêå "
+
+#, c-format
+msgid "%ld lines indented "
+msgstr "Èçìåíåíû îòñòóïû â ñòðîêàõ (%ld) "
+
+msgid "E748: No previously used register"
+msgstr "E748: Íåò ïðåäûäóùåãî èñïîëüçîâàííîãî ðåãèñòðà"
+
+#. must display the prompt
+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"
+
+msgid "block of 1 line yanked"
+msgstr "ñêîïèðîâàí áëîê èç îäíîé ñòðîêè"
+
+msgid "1 line yanked"
+msgstr "ñêîïèðîâàíà îäíà ñòðîêà"
+
+#, c-format
+msgid "block of %ld lines yanked"
+msgstr "ñêîïèðîâàí áëîê èç ñòðîê: %ld"
+
+#, c-format
+msgid "%ld lines yanked"
+msgstr "ñêîïèðîâàíî ñòðîê: %ld"
+
+#, c-format
+msgid "E353: Nothing in register %s"
+msgstr "E353:  ðåãèñòðå %s íè÷åãî íåò"
+
+#. Highlight title
+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"
+
+#, c-format
+msgid "%ld Cols; "
+msgstr "Êîëîíîê: %ld; "
+
+#, c-format
+msgid "Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Bytes"
+msgstr "Âûäåëåíî %s%ld èç %ld ñòðîê; %ld èç %ld ñëîâ; %ld èç %ld áàéò"
+
+#, c-format
+msgid ""
+"Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Chars; %ld of %ld "
+"Bytes"
+msgstr ""
+"Âûäåëåíî %s%ld èç %ld ñòð.; %ld èç %ld ñëîâ; %ld èç %ld ñèìâ.; %ld èç %ld "
+"áàéò"
+
+#, c-format
+msgid "Col %s of %s; Line %ld of %ld; Word %ld of %ld; Byte %ld of %ld"
+msgstr "Êîë. %s èç %s; ñòð. %ld èç %ld; ñë. %ld èç %ld; áàéò %ld èç %ld"
+
+#, c-format
+msgid ""
+"Col %s of %s; Line %ld of %ld; Word %ld of %ld; Char %ld of %ld; Byte %ld of "
+"%ld"
+msgstr ""
+"Êîë. %s èç %s; ñòð. %ld èç %ld; ñë. %ld èç %ld; ñèìâ. %ld èç %ld; áàéò %ld "
+"èç %ld"
+
+#, c-format
+msgid "(+%ld for BOM)"
+msgstr "(+%ld ñ ó÷¸òîì BOM)"
+
+msgid "%<%f%h%m%=Page %N"
+msgstr "%<%f%h%m%=Ñòð. %N"
+
+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>"
+
+msgid "E529: Cannot set 'term' to empty string"
+msgstr "E529: Çíà÷åíèå îïöèè 'term' íå ìîæåò áûòü ïóñòîé ñòðîêîé"
+
+msgid "E530: Cannot change term in GUI"
+msgstr "E530:  ãðàôè÷åñêîì èíòåðôåéñå èçìåíÿòü òåðìèíàë íåâîçìîæíî"
+
+msgid "E531: Use \":gui\" to start the GUI"
+msgstr "E531: Äëÿ çàïóñêà ãðàôè÷åñêîãî èíòåðôåéñà èñïîëüçóéòå \":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"
+
+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: Íåâîçìîæíî âûáðàòü øðèôòîâîé íàáîð"
+
+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>"
+
+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 "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'"
+
+#, 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"
+
+#. 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.
+#, 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"
+
+#. if Vim opened a window: Executing a shell may cause crashes
+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: Íåóäà÷íîå çàâåðøåíèå âûáîðà ïðèíòåðà"
+
+#, 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 "E245: Illegal char '%c' in font name \"%s\""
+msgstr "E245: Íåäîïóñòèìûé ñèìâîë '%c' â èìåíè øðèôòà \"%s\""
+
+msgid "Vim: Double signal, exiting\n"
+msgstr "Vim: Äâîéíîé ñèãíàë, çàâåðøåíèå ðàáîòû\n"
+
+#, c-format
+msgid "Vim: Caught deadly signal %s\n"
+msgstr "Vim: Ïîëó÷åí óáèéñòâåííûé ñèãíàë %s\n"
+
+#, c-format
+msgid "Vim: Caught deadly signal\n"
+msgstr "Vim: Ïîëó÷åí óáèéñòâåííûé ñèãíàë\n"
+
+#, c-format
+msgid "Opening the X display took %ld msec"
+msgstr "Îòêðûòèå äèñïëåÿ X çàíÿëî %ld 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"
+"Could not get security context for "
+msgstr ""
+"\n"
+"Íåâîçìîæíî ïîëó÷èòü êîíòåêñò áåçîïàñíîñòè äëÿ "
+
+msgid ""
+"\n"
+"Could not set security context for "
+msgstr ""
+"\n"
+"Íåâîçìîæíî óñòàíîâèòü êîíòåêñò áåçîïàñíîñòè äëÿ "
+
+msgid ""
+"\n"
+"Cannot execute shell "
+msgstr ""
+"\n"
+"Íåâîçìîæíî çàïóñòèòü îáîëî÷êó "
+
+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"
+"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 "shell returned %d"
+msgstr "çàâåðøåíèå ðàáîòû îáîëî÷êè ñ êîäîì %d"
+
+#, 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 "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: Áîëüøå íåò ýëåìåíòîâ"
+
+#, c-format
+msgid "(%d of %d)%s%s: "
+msgstr "(%d èç %d)%s%s: "
+
+msgid " (line deleted)"
+msgstr " (ñòðîêà óäàëåíà)"
+
+msgid "E380: At bottom of quickfix stack"
+msgstr "E380: Âíèçó ñòåêà áûñòðûõ èñïðàâëåíèé"
+
+msgid "E381: At top of quickfix stack"
+msgstr "E381: Íàâåðõó ñòåêà áûñòðûõ èñïðàâëåíèé"
+
+#, c-format
+msgid "error list %d of %d; %d errors"
+msgstr "ñïèñîê îøèáîê %d èç %d; %d îøèáîê"
+
+msgid "E382: Cannot write, 'buftype' option is set"
+msgstr ""
+"E382: Çàïèñü íåâîçìîæíà, çíà÷åíèå îïöèè 'buftype' íå ÿâëÿåòñÿ ïóñòîé ñòðîêîé"
+
+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: Òðåáóåòñÿ ñòðîêà èëè ñïèñîê"
+
+#, c-format
+msgid "E369: invalid item in %s%%[]"
+msgstr "E369: Íåäîïóñòèìûé ýëåìåíò â %s%%[]"
+
+#, c-format
+msgid "E769: Missing ] after %s["
+msgstr "E769: Ïðîïóùåíà ] ïîñëå %s["
+
+#, 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 et al. not allowed here"
+msgstr "E67: \\z1 è ò.ï. íå ìîãóò áûòü èñïîëüçîâàíû çäåñü"
+
+#, c-format
+msgid "E69: Missing ] after %s%%["
+msgstr "E69: Ïðîïóùåíà ] ïîñëå %s%%["
+
+#, c-format
+msgid "E70: Empty %s%%[]"
+msgstr "E70: Ïóñòîå %s%%[]"
+
+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{...}"
+
+#, 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 íè çà ÷åì íå ñëåäóåò"
+
+msgid "E65: Illegal back reference"
+msgstr "E65: Íåäîïóñòèìàÿ îáðàòíàÿ ññûëêà"
+
+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"
+
+msgid ""
+"E864: \\%#= can only be followed by 0, 1, or 2. The automatic engine will be "
+"used "
+msgstr ""
+"E864: ïîñëå \\%#= ìîæåò áûòü òîëüêî 0, 1 èëè 2. Áóäåò èñïîëüçîâàòüñÿ "
+"àâòîìàòè÷åñêàÿ ìàøèíà"
+
+#, c-format
+msgid "E866: (NFA regexp) Misplaced %c"
+msgstr "E866: (ðåã. âûðàæåíèå ÍÊÀ) íåîæèäàííûé %c"
+
+msgid "E865: (NFA) Regexp end encountered prematurely"
+msgstr "E865: (ÍÊÀ) íåîæèäàííûé êîíåö ðåãóëÿðíîãî âûðàæåíèÿ"
+
+#, c-format
+msgid "E867: (NFA) Unknown operator '\\z%c'"
+msgstr "E867: (ÍÊÀ) íåèçâåñòíûé îïåðàòîð '\\z%c'"
+
+#, c-format
+msgid "E867: (NFA) Unknown operator '\\%%%c'"
+msgstr "E867: (ÍÊÀ) íåèçâåñòíûé îïåðàòîð '\\%%%c'"
+
+#. should never happen
+msgid "E868: Error building NFA with equivalence class!"
+msgstr "E868: îøèáêà ïðè ñîçäàíèè ÍÊÀ ñ êëàññîì ýêâèâàëåíòíîñòè!"
+
+#, c-format
+msgid "E869: (NFA) Unknown operator '\\@%c'"
+msgstr "E869: (ÍÊÀ) íåèçâåñòíûé îïåðàòîð '\\@%c'"
+
+msgid "E870: (NFA regexp) Error reading repetition limits"
+msgstr "E870: (ðåã. âûðàæåíèå ÍÊÀ) îøèáêà ïðè ÷òåíèè ãðàíèö ïîâòîðåíèÿ"
+
+#. Can't have a multi follow a multi.
+msgid "E871: (NFA regexp) Can't have a multi follow a multi !"
+msgstr "E871: (ðåã. âûðàæåíèå ÍÊÀ) ìíîæåñòâî íå ìîæåò ñëåäîâàòü çà ìíîæåñòâîì!"
+
+#. Too many `('
+msgid "E872: (NFA regexp) Too many '('"
+msgstr "E872: (ðåã. âûðàæåíèå ÍÊÀ) ñëèøêîì ìíîãî '('"
+
+msgid "E879: (NFA regexp) Too many \\z("
+msgstr "E879: (ðåã. âûðàæåíèå ÍÊÀ) ñëèøêîì ìíîãî \\z("
+
+msgid "E873: (NFA regexp) proper termination error"
+msgstr "E873: (ðåã. âûðàæåíèå ÍÊÀ) îøèáêà êîððåêòíîãî çàâåðøåíèÿ"
+
+msgid "E874: (NFA) Could not pop the stack !"
+msgstr "E874: (ðåã. âûðàæåíèå ÍÊÀ) íåâîçìîæíî âçÿòü èç ñòåêà!"
+
+msgid ""
+"E875: (NFA regexp) (While converting from postfix to NFA), too many states "
+"left on stack"
+msgstr ""
+"E875: (ðåã. âûðàæåíèå ÍÊÀ) â ñòåêå îñòàëîñü ñëèøêîì ìíîãî ñîñòîÿíèé (ïðè "
+"ïðåîáðàçîâàíèè èç postfix â ÍÊÀ)"
+
+msgid "E876: (NFA regexp) Not enough space to store the whole NFA "
+msgstr "E876: (ðåã. âûðàæåíèå ÍÊÀ) íåäîñòàòî÷íî ìåñòà äëÿ õðàíåíèÿ âñåãî ÍÊÀ"
+
+msgid "E878: (NFA) Could not allocate memory for branch traversal!"
+msgstr "E878: (ÍÊÀ) íåâîçìîæíî âûäåëèòü ïàìÿòü äëÿ ïðîõîäà âåòâè!"
+
+msgid ""
+"Could not open temporary log file for writing, displaying on stderr ... "
+msgstr ""
+"Íåâîçìîæíî îòêðûòü ôàéë âðåìåííîãî æóðíàëà äëÿ çàïèñè, âûâîä íà stderr..."
+
+#, c-format
+msgid "(NFA) COULD NOT OPEN %s !"
+msgstr "(ÍÊÀ) íåâîçìîæíî îòêðûòü %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 " (lang)"
+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 " (âêëþ÷àåò ðàííåå ïîêàçàííûå ñîîòâåòñòâèÿ)"
+
+#. cursor at status line
+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 "E759: Format error in spell file"
+msgstr "E759: Îøèáêà ôîðìàòà â ôàéëå ïðàâîïèñàíèÿ"
+
+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 "Ñæàòèå äåðåâà ñëîâ..."
+
+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"
+"\""
+
+#, 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 "Warning: region %s not supported"
+msgstr "Ïðåäóïðåæäåíèå: ðåãèîí %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, ñòðîêà %d"
+
+#, c-format
+msgid ""
+"Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in %s line "
+"%d"
+msgstr ""
+"Îïðåäåëåíèå COMPOUNDPERMITFLAG ïîñëå ýëåìåíòà PFX ìîæåò äàòü íåïðàâèëüíûå "
+"ðåçóëüòàòû â %s, ñòðîêà %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 %6d - %s"
+msgstr "ñòðîêà %6d, ñëîâî %6d — %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 "×òåíèå çàïèñàííîãî ôàéëà ïðàâîïèñàíèÿ..."
+
+#.
+#. * Go through the trie of good words, soundfold each word and add it to
+#. * the soundfold trie.
+#.
+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: Èìÿ âûõîäíîãî ôàéëà íå äîëæíî ñîäåðæàòü íàçâàíèÿ ðåãèîíà"
+
+msgid "E754: Only up to 8 regions supported"
+msgstr "E754: Ïîääåðæèâàåòñÿ íå áîëåå 8-ìè ðåãèîíîâ"
+
+#, 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 removed from %s"
+msgstr "Ñëîâî óäàëåíî èç %s"
+
+#, c-format
+msgid "Word added to %s"
+msgstr "Ñëîâî äîáàâëåíî â %s"
+
+msgid "E763: Word characters differ between spell files"
+msgstr "E763: Ñèìâîëû ñëîâ îòëè÷àþòñÿ â ôàéëàõ ïðàâîïèñàíèÿ"
+
+msgid "Sorry, no suggestions"
+msgstr "Èçâèíèòå, íåò ïðåäïîëîæåíèé"
+
+#, c-format
+msgid "Sorry, only %ld suggestions"
+msgstr "Èçâèíèòå, òîëüêî %ld ïðåäïîëîæåíèé"
+
+#. for when 'cmdheight' > 1
+#. avoid more prompt
+#, 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"
+
+#, 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"
+
+#. This should have been checked when generating the .spl
+#. * file.
+msgid "E783: duplicate char in MAP entry"
+msgstr "E783: Ïîâòîðÿþùèéñÿ ñèìâîë â ýëåìåíòå MAP"
+
+msgid "No Syntax items defined for this buffer"
+msgstr "Ñèíòàêñè÷åñêèå ýëåìåíòû äëÿ äàííîãî áóôåðà íå îïðåäåëåíû"
+
+#, c-format
+msgid "E390: Illegal argument: %s"
+msgstr "E390: Íåäîïóñòèìûé ïàðàìåòð: %s"
+
+#, 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: Çäåñü íåëüçÿ èñïîëüçîâàòü ïàðàìåòð contains"
+
+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 "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: Íåèçâåñòíûé öâåò òåêñòà"
+
+msgid "E420: BG color unknown"
+msgstr "E420: Íåèçâåñòíûé öâåò ôîíà"
+
+#, 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 " # ïðè òèï ìåòêà"
+
+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\" íå ñóùåñòâóåò"
+
+#. Give an indication of the number of matching tags
+#, 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\" íå ñóùåñòâóåò"
+
+#. Highlight title
+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 "Èãíîðèðîâàíèå äëèííîé ñòðîêè â ôàéëå tags"
+
+#, 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"
+
+#. never opened any tags file
+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: Â termcap íåò çàïèñè \"%s\""
+
+msgid "E437: terminal capability \"cm\" required"
+msgstr "E437: Òðåáóåòñÿ ñïîñîáíîñòü òåðìèíàëà \"cm\""
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Terminal keys ---"
+msgstr ""
+"\n"
+"--- Êíîïêè òåðìèíàëà ---"
+
+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"
+
+#. This happens when the FileChangedRO autocommand changes the
+#. * file in a way it becomes shorter.
+msgid "E834: Line count changed unexpectedly"
+msgstr "E834: Íåîæèäàííî èçìåíèëñÿ ñ÷¸ò÷èê ñòðîê"
+
+#. must display the prompt
+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 "Íå÷åãî îòìåíÿòü"
+
+# Çàãîëîâîê òàáëèöû :undolist
+msgid "number changes when saved"
+msgstr " íîìåð èçìåí. êîãäà ñîõðàíåíî"
+
+#, c-format
+msgid "%ld seconds ago"
+msgstr "%ld ñ íàçàä"
+
+msgid "E790: undojoin is not allowed after undo"
+msgstr "E790: Îáúåäèíåíèå îòìåí íå äîïóñêàåòñÿ ïîñëå îòìåíû"
+
+msgid "E439: undo list corrupt"
+msgstr "E439: Ïîâðåæä¸í ñïèñîê îòìåíû"
+
+msgid "E440: undo line missing"
+msgstr "E440: Ïîòåðÿíà ñòðîêà îòìåíû"
+
+#. Only MS VC 4.1 and earlier can do Win32s
+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"
+"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 "áåç ãðàôè÷åñêîãî èíòåðôåéñà."
+
+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 " Features included (+) or not (-):\n"
+msgstr " Âêëþ÷¸ííûå (+) è îòêëþ÷¸ííûå (-) îñîáåííîñòè:\n"
+
+msgid " system vimrc file: \""
+msgstr " îáùåñèñòåìíûé ôàéë vimrc: \""
+
+msgid " user vimrc file: \""
+msgstr " ïîëüçîâàòåëüñêèé ôàéë vimrc: \""
+
+msgid " 2nd user vimrc file: \""
+msgstr " âòîðîé ïîëüçîâàòåëüñêèé ôàéë vimrc: \""
+
+msgid " 3rd user vimrc file: \""
+msgstr " òðåòèé ïîëüçîâàòåëüñêèé ôàéë vimrc: \""
+
+msgid " user exrc file: \""
+msgstr " ïîëüçîâàòåëüñêèé ôàéë exrc: \""
+
+msgid " 2nd user exrc file: \""
+msgstr " âòîðîé ïîëüçîâàòåëüñêèé ôàéë exrc: \""
+
+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 " 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 " ÎÒËÀÄÎ×ÍÀß ÑÁÎÐÊÀ"
+
+msgid "VIM - Vi IMproved"
+msgstr "VIM — Vi IMproved (óëó÷øåííûé Vi)"
+
+msgid "version "
+msgstr "âåðñèÿ "
+
+msgid "by Bram Moolenaar et al."
+msgstr "Áðàì Ìîîëåíààð è äðóãèå"
+
+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> äëÿ ïîëó÷åíèÿ ñïðàâêè "
+
+msgid "type :help version7<Enter> for version info"
+msgstr "íàáåðèòå :help version7<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 "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 "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: Îêíî íå ìîæåò áûòü îäíîâðåìåííî ñëåâà ââåðõó è ñïðàâà âíèçó"
+
+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: Íåëüçÿ çàêðûòü îêíî àâòîêîìàíä"
+
+msgid "E814: Cannot close window, only autocmd window would remain"
+msgstr "E814: Íåëüçÿ çàêðûòü îêíî, îñòàíåòñÿ òîëüêî îêíî àâòîêîìàíä"
+
+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 "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"
+
+#. Now concatenate
+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 "-- Íåò ñòðîê â áóôåðå --"
+
+#.
+#. * 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: Âûïîëíåíèå êîìàíäû ïðåðâàíî"
+
+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: Íåèçâåñòíûé øðèôòîâîé íàáîð: %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: Âíóòðåííÿÿ îøèáêà"
+
+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 "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()\" èç áèáëèîòåêè"
+
+#, 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: Âîçìîæíîñòü èñïîëüçîâàíèÿ ãðàôè÷åñêîãî èíòåðôåéñà âûêëþ÷åíà ïðè "
+"êîìïèëÿöèè"
+
+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 "E37: No write since last change (add ! to override)"
+msgstr "E37: Èçìåíåíèÿ íå ñîõðàíåíû (äîáàâüòå !, ÷òîáû îáîéòè ïðîâåðêó)"
+
+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: Ïðîãðàììà îáðàáîòêè ðåãóëÿðíûõ âûðàæåíèé ïîâðåæäåíà"
+
+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: Íåâîçìîæíî èçìåíèòü ïåðåìåííóþ â ïåñî÷íèöå: \"%s\""
+
+msgid "E47: Error while reading errorfile"
+msgstr "E47: Îøèáêà ïðè ÷òåíèè ôàéëà îøèáîê"
+
+msgid "E48: Not allowed in sandbox"
+msgstr "E48: Íå äîïóñêàåòñÿ â ïåñî÷íèöå"
+
+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: Îøèáêà çàêðûòèÿ ñâîï-ôàéëà"
+
+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 "Zero count"
+msgstr "Íóëåâîå çíà÷åíèå ñ÷¸ò÷èêà"
+
+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 íå äîïóñêàåò èçìåíåíèé â ôàéëàõ òîëüêî äëÿ ÷òåíèÿ"
+
+#, c-format
+msgid "E685: Internal error: %s"
+msgstr "E685: Âíóòðåííÿÿ îøèáêà: %s"
+
+msgid "E363: pattern uses more memory than 'maxmempattern'"
+msgstr "E363: Øàáëîí èñïîëüçóåò áîëüøå ïàìÿòè ÷åì 'maxmempattern'"
+
+msgid "E749: empty buffer"
+msgstr "E749: Ïóñòîé áóôåð"
+
+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: Íåäîïóñòèìîå èìÿ ðåãèñòðà"
+
+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 "Èíäåêñ äîëæåí áûòü öåëûì ÷èñëîì èëè âûáîðêîé, à íå %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"
+
+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"
+
+#, c-format
+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 "Íåâîçìîæíî ñìåíèòü êàòàëîã"
+
+#, c-format
+msgid "expected 3-tuple as imp.find_module() result, but got %s"
+msgstr "Îæèäàëñÿ 3-êîðòåæ êàê ðåçóëüòàò imp.find_module(), íî ïîëó÷åí %s"
+
+#, c-format
+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 "Íåâîçìîæíî èçìåíèòü ôèêñèðîâàííûé ñëîâàðü"
+
+#, c-format
+msgid "cannot set attribute %s"
+msgstr "Íåâîçìîæíî óñòàíîâèòü àòðèáóò %s"
+
+msgid "hashtab changed during iteration"
+msgstr "Õýø-òàáëèöà èçìåíèëàñü ïðè èòåðàöèè"
+
+#, 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 "Èíäåêñ ñïèñêà çà ïðåäåëàìè äèàïàçîíà"
+
+#. No more suitable format specifications in python-2.3
+#, c-format
+msgid "internal error: failed to get vim list item %d"
+msgstr "Âíóòðåííÿÿ îøèáêà: íå óäàëîñü ïîëó÷èòü ýëåìåíò VIM-ñïèñêà %d"
+
+msgid "failed to add item to list"
+msgstr "Íåâîçìîæíî äîáàâèòü ýëåìåíò â ñïèñîê"
+
+#, c-format
+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 "Íåâîçìîæíî èçìåíèòü ôèêñèðîâàííûé ñïèñîê"
+
+#, c-format
+msgid "unnamed function %s does not exist"
+msgstr "Íå ñóùåñòâóåò áåçûìÿííîé ôóíêöèè %s"
+
+#, c-format
+msgid "function %s does not exist"
+msgstr "Ôóíêöèÿ %s íå ñóùåñòâóåò"
+
+msgid "function constructor does not accept keyword arguments"
+msgstr "Êîíñòðóêòîð ôóíêöèè íå äîïóñêàåò êëþ÷åâûå ñëîâà êàê àðãóìåíòû"
+
+#, 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 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/po/ru.po b/src/po/ru.po
new file mode 100644
index 0000000000..1a43381256
--- /dev/null
+++ b/src/po/ru.po
@@ -0,0 +1,6893 @@
+# 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_7.4_ru\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2013-08-31 16:42+0400\n"
+"PO-Revision-Date: 2013-08-31 21:11+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=utf-8\n"
+"Content-Transfer-Encoding: 8bit\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"
+
+msgid "E818: sha256 test failed"
+msgstr "E818: Ðе удалоÑÑŒ выполнить теÑÑ‚ sha256"
+
+msgid "E819: Blowfish test failed"
+msgstr "E819: Ðе удалоÑÑŒ выполнить теÑÑ‚ Blowfish"
+
+msgid "[Location List]"
+msgstr "[СпиÑок раÑположений]"
+
+msgid "[Quickfix List]"
+msgstr "[СпиÑок быÑтрых иÑправлений]"
+
+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 "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 "Один буфер выгружен из памÑти"
+
+#, c-format
+msgid "%d buffers unloaded"
+msgstr "Ð’Ñего выгружено буферов из памÑти: %d"
+
+msgid "1 buffer deleted"
+msgstr "Один буфер удалён"
+
+#, c-format
+msgid "%d buffers deleted"
+msgstr "Ð’Ñего удалено буферов: %d"
+
+msgid "1 buffer wiped out"
+msgstr "Один буфер очищен"
+
+#, c-format
+msgid "%d buffers wiped out"
+msgstr "Ð’Ñего очищено буферов: %d"
+
+msgid "E84: No modified buffer found"
+msgstr "E84: Изменённых буферов не обнаружено"
+
+#. back where we started, didn't find anything.
+msgid "E85: There is no listed buffer"
+msgstr "E85: Буферы в ÑпиÑке отÑутÑтвуют"
+
+#, c-format
+msgid "E86: Buffer %ld does not exist"
+msgstr "E86: Буфер %ld не ÑущеÑтвует"
+
+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 "E90: Cannot unload last buffer"
+msgstr "E90: Ðевозможно выгрузить из памÑти поÑледний буфер"
+
+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 "Одна Ñтрока --%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 "[Ðет имени]"
+
+#. must be a help buffer
+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 "[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 id=%d имÑ=%s"
+
+#, c-format
+msgid "E96: Can not 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: Ðевозможно Ñоздать файлы отличий"
+
+msgid "Patch file"
+msgstr "Файл-заплатка"
+
+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: Ðктивный буфер не находитÑÑ Ð² режиме отличий"
+
+msgid "E793: No other buffer in diff mode is modifiable"
+msgstr "E793: Больше нет изменÑемых буферов в режиме отличий"
+
+msgid "E100: No other buffer in diff mode"
+msgstr "E100: Больше нет буферов в режиме отличий"
+
+msgid "E101: More than two buffers in diff mode, don't know which one to use"
+msgstr "E101: В режиме отличий более двух буферов, не могу выбрать"
+
+#, 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\" не находитÑÑ Ð² режиме отличий"
+
+msgid "E787: Buffer changed unexpectedly"
+msgstr "E787: Буфер неожиданно изменилÑÑ"
+
+msgid "E104: Escape not allowed in digraph"
+msgstr "E104: Экранирующий Ñимвол Escape Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать в диграфе"
+
+msgid "E544: Keymap file not found"
+msgstr "E544: Файл Ñ Ñ€Ð°Ñкладкой клавиатуры не найден"
+
+msgid "E105: Using :loadkeymap not in a sourced file"
+msgstr "E105: Команда :loadkeymap применена вне файла ÑценариÑ"
+
+msgid "E791: Empty keymap entry"
+msgstr "E791: пуÑÑ‚Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑŒ раÑкладки клавиатуры"
+
+msgid " Keyword completion (^N^P)"
+msgstr " Ðвтодополнение ключевого Ñлова (^N^P)"
+
+#. ctrl_x_mode == 0, ^P/^N compl.
+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 " 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.
+#.
+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 "E684: list index out of range: %ld"
+msgstr "E684: Ð˜Ð½Ð´ÐµÐºÑ ÑпиÑка за пределами диапазона: %ld"
+
+#, c-format
+msgid "E121: Undefined variable: %s"
+msgstr "E121: ÐÐµÐ¾Ð¿Ñ€ÐµÐ´ÐµÐ»Ñ‘Ð½Ð½Ð°Ñ Ð¿ÐµÑ€ÐµÐ¼ÐµÐ½Ð½Ð°Ñ: %s"
+
+msgid "E111: Missing ']'"
+msgstr "E111: Пропущена ']'"
+
+#, c-format
+msgid "E686: Argument of %s must be a List"
+msgstr "E686: Параметр %s должен быть ÑпиÑком"
+
+#, c-format
+msgid "E712: Argument of %s must be a List or Dictionary"
+msgstr "E712: Параметр %s должен быть ÑпиÑком или Ñловарём"
+
+msgid "E713: Cannot use empty key for Dictionary"
+msgstr "E713: Ðевозможно иÑпользовать пуÑтой ключ Ð´Ð»Ñ ÑловарÑ"
+
+msgid "E714: List required"
+msgstr "E714: ТребуетÑÑ ÑпиÑок"
+
+msgid "E715: Dictionary required"
+msgstr "E715: ТребуетÑÑ Ñловарь"
+
+#, 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"
+
+#, 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: ТребуетÑÑ ÑÑылка на функцию"
+
+msgid "E719: Cannot use [:] with a Dictionary"
+msgstr "E719: Ðевозможно иÑпользовать [:] Ñо Ñловарём"
+
+#, c-format
+msgid "E734: Wrong variable type for %s="
+msgstr "E734: Ðеправильный тип переменной Ð´Ð»Ñ %s="
+
+#, c-format
+msgid "E130: Unknown function: %s"
+msgstr "E130: ÐеизвеÑÑ‚Ð½Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ: %s"
+
+#, c-format
+msgid "E461: Illegal variable name: %s"
+msgstr "E461: ÐедопуÑтимое Ð¸Ð¼Ñ Ð¿ÐµÑ€ÐµÐ¼ÐµÐ½Ð½Ð¾Ð¹: %s"
+
+msgid "E806: using Float as a String"
+msgstr "E806: ИÑпользование чиÑла Ñ Ð¿Ð»Ð°Ð²Ð°ÑŽÑ‰ÐµÐ¹ точкой как Ñтроки"
+
+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: [:] требует значением ÑпиÑок"
+
+msgid "E710: List value has more items than target"
+msgstr "E710: Элементов ÑпиÑка-Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð±Ð¾Ð»ÑŒÑˆÐµ чем в цели"
+
+msgid "E711: List value has not enough items"
+msgstr "E711: СпиÑок-значение не Ñодержит доÑтаточно Ñлементов"
+
+msgid "E690: Missing \"in\" after :for"
+msgstr "E690: Пропущено \"in\" поÑле :for"
+
+#, c-format
+msgid "E107: Missing parentheses: %s"
+msgstr "E107: Пропущены Ñкобки: %s"
+
+#, c-format
+msgid "E108: No such variable: \"%s\""
+msgstr "E108: Ðет такой переменной: \"%s\""
+
+msgid "E743: variable nested too deep for (un)lock"
+msgstr "E743: Слишком глубоко вложенные переменные Ð´Ð»Ñ (раз)блокировки"
+
+msgid "E109: Missing ':' after '?'"
+msgstr "E109: Пропущено ':' поÑле '?'"
+
+msgid "E691: Can only compare List with List"
+msgstr "E691: СпиÑок можно Ñравнивать только Ñо ÑпиÑком"
+
+msgid "E692: Invalid operation for Lists"
+msgstr "E692: ÐедопуÑÑ‚Ð¸Ð¼Ð°Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ†Ð¸Ñ Ð´Ð»Ñ ÑпиÑков"
+
+msgid "E735: Can only compare Dictionary with Dictionary"
+msgstr "E735: Словарь можно Ñравнивать только Ñо Ñловарём"
+
+msgid "E736: Invalid operation for Dictionary"
+msgstr "E736: ÐедопуÑÑ‚Ð¸Ð¼Ð°Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ†Ð¸Ñ Ð´Ð»Ñ ÑловарÑ"
+
+msgid "E693: Can only compare Funcref with Funcref"
+msgstr "E693: СÑылку на функцию можно Ñравнивать только Ñ ÑÑылкой на функцию"
+
+msgid "E694: Invalid operation for Funcrefs"
+msgstr "E694: ÐедопуÑÑ‚Ð¸Ð¼Ð°Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ†Ð¸Ñ Ð´Ð»Ñ ÑÑылки на функцию"
+
+msgid "E804: Cannot use '%' with Float"
+msgstr "E804: Ðевозможно иÑпользовать '%' Ñ Ñ‡Ð¸Ñлом Ñ Ð¿Ð»Ð°Ð²Ð°ÑŽÑ‰ÐµÐ¹ точкой"
+
+msgid "E110: Missing ')'"
+msgstr "E110: Пропущена ')'"
+
+msgid "E695: Cannot index a Funcref"
+msgstr "E695: Ðевозможно индекÑировать ÑÑылку на функцию"
+
+#, 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"
+
+#, c-format
+msgid "E696: Missing comma in List: %s"
+msgstr "E696: Пропущена запÑÑ‚Ð°Ñ Ð² ÑпиÑке: %s"
+
+#, c-format
+msgid "E697: Missing end of List ']': %s"
+msgstr "E697: Пропущено окончание ÑпиÑка ']': %s"
+
+#, 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 "E724: variable nested too deep for displaying"
+msgstr "E724: Слишком глубоко вложенные переменные Ð´Ð»Ñ Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ"
+
+#, 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 заданы неверно"
+
+#, c-format
+msgid "E117: Unknown function: %s"
+msgstr "E117: ÐеизвеÑÑ‚Ð½Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ: %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 "E808: Number or Float required"
+msgstr "E808: ТребуетÑÑ Ñ†ÐµÐ»Ð¾Ðµ чиÑло или Ñ Ð¿Ð»Ð°Ð²Ð°ÑŽÑ‰ÐµÐ¹ точкой"
+
+#. ИÑпользуетÑÑ Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ "значение параметра p()" в E741 и E742
+msgid "add() argument"
+msgstr "параметра add()"
+
+msgid "E699: Too many arguments"
+msgstr "E699: Слишком много параметров"
+
+msgid "E785: complete() can only be used in Insert mode"
+msgstr "E785: complete() может иÑпользоватьÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ в режиме Ð’Ñтавки"
+
+#.
+#. * 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"
+
+#, c-format
+msgid "E737: Key already exists: %s"
+msgstr "E737: Ключ уже ÑущеÑтвует: %s"
+
+#. ИÑпользуетÑÑ Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ "значение параметра p()" в E741 и E742
+msgid "extend() argument"
+msgstr "параметра extend()"
+
+#. ИÑпользуетÑÑ Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ "значение параметра p()" в E741 и E742
+msgid "map() argument"
+msgstr "параметра map()"
+
+#. ИÑпользуетÑÑ Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ "значение параметра p()" в E741 и E742
+msgid "filter() argument"
+msgstr "параметра filter()"
+
+#, c-format
+msgid "+-%s%3ld lines: "
+msgstr "+-%s%3ld Ñтрок: "
+
+#, c-format
+msgid "E700: Unknown function: %s"
+msgstr "E700: ÐеизвеÑÑ‚Ð½Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ: %s"
+
+msgid ""
+"&OK\n"
+"&Cancel"
+msgstr ""
+"&OK\n"
+"&C Отмена"
+
+msgid "called inputrestore() more often than inputsave()"
+msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ inputrestore() вызываетÑÑ Ñ‡Ð°Ñ‰Ðµ, чем Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ inputsave()"
+
+#. ИÑпользуетÑÑ Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ "значение параметра p()" в E741 и E742
+msgid "insert() argument"
+msgstr "параметра insert()"
+
+msgid "E786: Range not allowed"
+msgstr "E786: Диапазон не допуÑкаетÑÑ"
+
+msgid "E701: Invalid type for len()"
+msgstr "E701: Ðеправильные тип Ð´Ð»Ñ len()"
+
+msgid "E726: Stride is zero"
+msgstr "E726: Ðулевой шаг"
+
+msgid "E727: Start past end"
+msgstr "E727: Ðачало поÑле конца"
+
+msgid "<empty>"
+msgstr "<пуÑто>"
+
+msgid "E240: No connection to Vim server"
+msgstr "E240: Ðет ÑвÑзи Ñ Ñервером Vim"
+
+#, c-format
+msgid "E241: Unable to send to %s"
+msgstr "E241: Ðе могу отправить Ñообщение Ð´Ð»Ñ %s"
+
+msgid "E277: Unable to read a server reply"
+msgstr "E277: Сервер не отвечает"
+
+#. ИÑпользуетÑÑ Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ "значение параметра p()" в E741 и E742
+msgid "remove() argument"
+msgstr "параметра remove()"
+
+msgid "E655: Too many symbolic links (cycle?)"
+msgstr "E655: Слишком много ÑимволичеÑких ÑÑылок (цикл?)"
+
+#. ИÑпользуетÑÑ Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ "значение параметра p()" в E741 и E742
+msgid "reverse() argument"
+msgstr "параметра reverse()"
+
+msgid "E258: Unable to send to client"
+msgstr "E258: Ðе могу ответить клиенту"
+
+#. ИÑпользуетÑÑ Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ "значение параметра p()" в E741 и E742
+msgid "sort() argument"
+msgstr "параметра sort()"
+
+msgid "E702: Sort compare function failed"
+msgstr "E702: Ðеудачное завершение функции ÑÑ€Ð°Ð²Ð½ÐµÐ½Ð¸Ñ Ð¿Ñ€Ð¸ Ñортировке"
+
+msgid "(Invalid)"
+msgstr "(Ðеправильно)"
+
+msgid "E677: Error writing temp file"
+msgstr "E677: Ошибка запиÑи во временный файл"
+
+msgid "E805: Using a Float as a Number"
+msgstr "E805: ИÑпользование чиÑла Ñ Ð¿Ð»Ð°Ð²Ð°ÑŽÑ‰ÐµÐ¹ точкой как целого"
+
+msgid "E703: Using a Funcref as a Number"
+msgstr "E703: ИÑпользование ÑÑылки на функцию как чиÑла"
+
+msgid "E745: Using a List as a Number"
+msgstr "E745: ИÑпользование ÑпиÑка как чиÑла"
+
+msgid "E728: Using a Dictionary as a Number"
+msgstr "E728: ИÑпользование ÑÐ»Ð¾Ð²Ð°Ñ€Ñ ÐºÐ°Ðº чиÑла"
+
+msgid "E729: using Funcref as a String"
+msgstr "E729: ИÑпользование ÑÑылки на функцию как Ñтроки"
+
+msgid "E730: using List as a String"
+msgstr "E730: ИÑпользование ÑпиÑка как Ñтроки"
+
+msgid "E731: using Dictionary as a String"
+msgstr "E731: ИÑпользование ÑÐ»Ð¾Ð²Ð°Ñ€Ñ ÐºÐ°Ðº Ñтроки"
+
+#, c-format
+msgid "E706: Variable type mismatch for: %s"
+msgstr "E706: ÐеÑоответÑтвие типа переменной длÑ: %s"
+
+#, 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: Ð˜Ð¼Ñ Ð¿ÐµÑ€ÐµÐ¼ÐµÐ½Ð½Ð¾Ð¹ ÑÑылки на функцию должно начинатьÑÑ Ñ Ð·Ð°Ð³Ð»Ð°Ð²Ð½Ð¾Ð¹ буквы: "
+"%s"
+
+#, c-format
+msgid "E705: Variable name conflicts with existing function: %s"
+msgstr "E705: Ð˜Ð¼Ñ Ð¿ÐµÑ€ÐµÐ¼ÐµÐ½Ð½Ð¾Ð¹ конфликтует Ñ ÑущеÑтвующей функцией: %s"
+
+#. ИÑпользуетÑÑ Ñ %s = "параметера p"
+#, c-format
+msgid "E741: Value is locked: %s"
+msgstr "E741: Значение %s заблокировано"
+
+msgid "Unknown"
+msgstr "ÐеизвеÑтно"
+
+#. ИÑпользуетÑÑ Ñ %s = "параметера p()"
+#, c-format
+msgid "E742: Cannot change value of %s"
+msgstr "E742: Ðевозможно изменить значение %s"
+
+msgid "E698: variable nested too deep for making a copy"
+msgstr "E698: Слишком глубоко вложенные переменные Ð´Ð»Ñ ÐºÐ¾Ð¿Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ"
+
+#, 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 "E125: Illegal argument: %s"
+msgstr "E125: ÐедопуÑтимый параметр: %s"
+
+#, c-format
+msgid "E853: Duplicate argument name: %s"
+msgstr "E853: ПовторÑющееÑÑ Ð¸Ð¼Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð°: %s"
+
+msgid "E126: Missing :endfunction"
+msgstr "E126: Пропущена команда :endfunction"
+
+#, 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"
+
+msgid "E129: Function name required"
+msgstr "E129: ТребуетÑÑ Ð¸Ð¼Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ð¸"
+
+#, c-format
+msgid "E128: Function name must start with a capital or contain a colon: %s"
+msgstr ""
+"E128: Ð˜Ð¼Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ð¸ должно начинатьÑÑ Ñ Ð·Ð°Ð³Ð»Ð°Ð²Ð½Ð¾Ð¹ буквы или Ñодержать "
+"двоеточие: %s"
+
+#, c-format
+msgid "E131: Cannot delete function %s: It is in use"
+msgstr "E131: Ðевозможно удалить функцию %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"
+
+#, c-format
+msgid "continuing in %s"
+msgstr "продолжение в %s"
+
+msgid "E133: :return not inside a function"
+msgstr "E133: команда :return вне функции"
+
+msgid ""
+"\n"
+"# global variables:\n"
+msgstr ""
+"\n"
+"# глобальные переменные:\n"
+
+msgid ""
+"\n"
+"\tLast set from "
+msgstr ""
+"\n"
+"\tÐ’ поÑледний раз Ð¾Ð¿Ñ†Ð¸Ñ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð° в "
+
+msgid "No old files"
+msgstr "Ðет Ñтарых файлов"
+
+#, 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, 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: Строки перемещаютÑÑ Ñами на ÑебÑ"
+
+msgid "1 line moved"
+msgstr "Перемещена одна Ñтрока"
+
+#, 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: Ðвтокоманды *Filter* не должны изменÑть активный буфер"
+
+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 " ÐЕУДÐЧÐО"
+
+#. avoid a wait_return for this message, it's annoying
+#, c-format
+msgid "E137: Viminfo file is not writable: %s"
+msgstr "E137: Права на запиÑÑŒ файла viminfo отÑутÑтвуют: %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\""
+
+#. Write the info:
+#, 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 "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 "Своп-файл \"%s\" ÑущеÑтвует, перезапиÑать?"
+
+#, c-format
+msgid "E768: Swap file exists: %s (:silent! overrides)"
+msgstr "E768: Своп-файл ÑущеÑтвует: %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 ""
+"Ð”Ð»Ñ \"%s\" включена Ð¾Ð¿Ñ†Ð¸Ñ 'readonly'.\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: ИÑпользование команд оболочки не допуÑкаетÑÑ Ð² 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 "Одно ÑоответÑтвие"
+
+msgid "1 substitution"
+msgstr "Одна замена"
+
+#, c-format
+msgid "%ld matches"
+msgstr "%ld ÑоответÑтвий"
+
+#, c-format
+msgid "%ld substitutions"
+msgstr "%ld замен"
+
+msgid " on 1 line"
+msgstr " в одной Ñтроке"
+
+#, c-format
+msgid " on %ld lines"
+msgstr " в %ld Ñтр."
+
+msgid "E147: Cannot do :global recursive"
+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 "E150: Not a directory: %s"
+msgstr "E150: %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 "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"
+
+#, c-format
+msgid "E157: Invalid sign ID: %ld"
+msgstr "E157: Ðеправильный ID значка: %ld"
+
+msgid " (NOT FOUND)"
+msgstr " (ÐЕ ÐÐЙДЕÐО)"
+
+msgid " (not supported)"
+msgstr " (не поддерживаетÑÑ)"
+
+msgid "[Deleted]"
+msgstr "[Удалено]"
+
+msgid "Entering Debug mode. Type \"cont\" to continue."
+msgstr "Включён режим отладки. Ð”Ð»Ñ Ð¿Ñ€Ð¾Ð´Ð¾Ð»Ð¶ÐµÐ½Ð¸Ñ Ð½Ð°Ð±ÐµÑ€Ð¸Ñ‚Ðµ \"cont\""
+
+#, c-format
+msgid "line %ld: %s"
+msgstr "Ñтрока %ld: %s"
+
+#, c-format
+msgid "cmd: %s"
+msgstr "команда: %s"
+
+#, 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"
+
+msgid "E750: First use \":profile start {fname}\""
+msgstr "E750: Первое иÑпользование \":profile start {имÑ-файла}\""
+
+#, c-format
+msgid "Save changes to \"%s\"?"
+msgstr "Сохранить Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð² \"%s\"?"
+
+msgid "Untitled"
+msgstr "Без имени"
+
+#, 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 'runtimepath': \"%s\""
+msgstr "не найдено в 'runtimepath': \"%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 завершено"
+
+msgid "modeline"
+msgstr "Ñ€ÐµÐ¶Ð¸Ð¼Ð½Ð°Ñ Ñтрока"
+
+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 "E319: Sorry, the command is not available in this version"
+msgstr "E319: Извините, Ñта команда недоÑтупна в данной верÑии"
+
+msgid "E172: Only one file name allowed"
+msgstr "E172: Разрешено иÑпользовать только одно Ð¸Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð°"
+
+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 Range 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 требуетÑÑ ÑƒÐºÐ°Ð·Ð°Ñ‚ÑŒ параметр"
+
+#, 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 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!"
+
+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 "Без Ñвоп-файла"
+
+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 "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\""
+
+#. set mark
+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: ПуÑтое Ð¸Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð° Ð´Ð»Ñ '%' или '#', возможно только c \":p:h\""
+
+msgid "E500: Evaluates to an empty string"
+msgstr "E500: Результатом Ð²Ñ‹Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ ÑвлÑетÑÑ Ð¿ÑƒÑÑ‚Ð°Ñ Ñтрока"
+
+msgid "E195: Cannot open viminfo file for reading"
+msgstr "E195: Ðевозможно открыть файл viminfo Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ"
+
+msgid "E196: No digraphs in this version"
+msgstr "E196: Ð’ Ñтой верÑии диграфы не работают"
+
+msgid "E608: Cannot :throw exceptions with 'Vim' prefix"
+msgstr ""
+"E608: Ðевозможно выполнить команду :throw Ð´Ð»Ñ Ð¸Ñключений Ñ Ð¿Ñ€Ð¸Ñтавкой 'Vim'"
+
+#. always scroll up, don't overwrite
+#, 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"
+
+#. always scroll up, don't overwrite
+#, 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 "Ошибка"
+
+#. if (pending & CSTP_INTERRUPT)
+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"
+
+#. Give up for a ":catch" after ":finally" and ignore it.
+#. * Just parse.
+msgid "E604: :catch after :finally"
+msgstr "E604: :catch без :finally"
+
+msgid "E606: :finally without :try"
+msgstr "E606: :finally без :try"
+
+#. Give up for a multiple ":finally" and ignore it.
+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 "E198: cmd_pchar beyond the command length"
+msgstr "E198: cmd_pchar больше длины команды"
+
+msgid "E199: Active window or buffer deleted"
+msgstr "E199: Удалено активное окно или буфер"
+
+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..."
+
+#. Re-opening the original file failed!
+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 "[перекодировано]"
+
+msgid "[blowfish]"
+msgstr "[blowfish]"
+
+msgid "[crypted]"
+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 "E821: File is encrypted with unknown method"
+msgstr "E821: Файл зашифрован неизвеÑтным методом"
+
+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 "E460: The resource fork would be lost (add ! to override)"
+msgstr "E460: Ветвь реÑурÑа будет потерÑна (добавьте !, чтобы обойти проверку)"
+
+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 "E667: Fsync failed"
+msgstr "E667: Ðе удалоÑÑŒ выполнить функцию fsync()"
+
+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: Режим заплатки: невозможно Ñохранение иÑходного файла"
+
+msgid "E206: patchmode: can't touch empty original file"
+msgstr ""
+"E206: Режим заплатки: невозможно Ñменить параметры пуÑтого иÑходного файла"
+
+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"
+
+#. Explicit typecast avoids warning on Mac OS X 10.6
+#, c-format
+msgid "%ld characters"
+msgstr "Ñимволов: %ld"
+
+msgid "[noeol]"
+msgstr "[noeol]"
+
+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
+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"
+"&L Загрузить файл"
+
+#, 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>"
+
+#. the group doesn't exist
+#, c-format
+msgid "E367: No such group: \"%s\""
+msgstr "E367: Группа \"%s\" не ÑущеÑтвует"
+
+#, 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"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Auto-Commands ---"
+msgstr ""
+"\n"
+"--- Ðвтокоманды ---"
+
+#, c-format
+msgid "E680: <buffer=%d>: invalid buffer number "
+msgstr "E680: <buffer=%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 Auto commands 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 lines folded "
+msgstr "+--%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: Ðевозможно Ñоздать новый процеÑÑ Ð´Ð»Ñ Ð³Ñ€Ð°Ñ„. интерфейÑа"
+
+msgid "E852: The child process failed to start the GUI"
+msgstr "E852: ПроцеÑÑу-потомку не удалоÑÑŒ запуÑтить граф. интерфейÑ"
+
+msgid "E229: Cannot start the GUI"
+msgstr "E229: Ðевозможно перейти в режим графичеÑкого интерфейÑа"
+
+#, c-format
+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'"
+
+#, 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 "ПолоÑа прокрутки: не могу определить геометрию ползунка"
+
+msgid "Vim dialog"
+msgstr "Диалоговое окно Vim"
+
+msgid "E232: Cannot create BalloonEval with both message and callback"
+msgstr ""
+"E232: \"Пузырь\" Ð´Ð»Ñ Ð²Ñ‹Ñ‡Ð¸Ñлений, включающий и Ñообщение, и обратный вызов, "
+"не может быть Ñоздан"
+
+msgid ""
+"&Yes\n"
+"&No\n"
+"&Cancel"
+msgstr ""
+"&Да\n"
+"&Ðет\n"
+"О&тмена"
+
+msgid "Input _Methods"
+msgstr "Методы Ввода"
+
+msgid "VIM - Search and Replace..."
+msgstr "VIM — ПоиÑк и замена..."
+
+msgid "VIM - Search..."
+msgstr "VIM — ПоиÑк..."
+
+msgid "Find what:"
+msgstr "Что ищем:"
+
+msgid "Replace with:"
+msgstr "Ðа что заменÑем:"
+
+#. whole word only button
+msgid "Match whole word only"
+msgstr "Только точные ÑоответÑтвиÑ"
+
+#. match case button
+msgid "Match case"
+msgstr "РегиÑтрозавиÑимые ÑоответÑтвиÑ"
+
+msgid "Direction"
+msgstr "Ðаправление"
+
+#. 'Up' and 'Down' buttons
+msgid "Up"
+msgstr "Вверх"
+
+msgid "Down"
+msgstr "Вниз"
+
+#. 'Find Next' button
+msgid "Find Next"
+msgstr "Ðайти Ñледующее"
+
+#. 'Replace' button
+msgid "Replace"
+msgstr "Замена"
+
+#. 'Replace All' button
+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 "О&тмена"
+
+#, 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 "Close tab"
+msgstr "Закрыть вкладку"
+
+msgid "Open tab..."
+msgstr "Открыть вкладку..."
+
+msgid "Find string (use '\\\\' to find a '\\')"
+msgstr "ПоиÑк Ñтроки (иÑпользуйте '\\\\' Ð´Ð»Ñ Ð¿Ð¾Ð¸Ñка '\\')"
+
+msgid "Find & Replace (use '\\\\' to find a '\\')"
+msgstr "ПоиÑк и замена (иÑпользуйте '\\\\' Ð´Ð»Ñ Ð¿Ð¾Ð¸Ñка '\\')"
+
+#. 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 "Ðе иÑпользуетÑÑ"
+
+msgid "Directory\t*.nothing\n"
+msgstr "Каталог\t*.ничего\n"
+
+msgid "Vim E458: Cannot allocate colormap entry, some colors may be incorrect"
+msgstr ""
+"Vim E458: Ðевозможно выделить запиÑÑŒ в таблице цвета, некоторые цвета могут "
+"отображатьÑÑ Ð½ÐµÐ¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ð¾"
+
+#, 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 "Font0: %s"
+
+#, c-format
+msgid "Font1: %s"
+msgstr "Font1: %s"
+
+#, c-format
+msgid "Font%ld width is not twice that of font0"
+msgstr "Ширина шрифта font%ld должна быть вдвое больше ширины шрифта font0"
+
+#, c-format
+msgid "Font0 width: %ld"
+msgstr "Ширина шрифта font0: %ld"
+
+#, c-format
+msgid "Font1 width: %ld"
+msgstr "Ширина шрифта font1: %ld"
+
+msgid "Invalid font specification"
+msgstr "Ðеправильное определение шрифта"
+
+msgid "&Dismiss"
+msgstr "О&тклонить"
+
+msgid "no specific match"
+msgstr "нет Ñпециального ÑовпадениÑ"
+
+msgid "Vim - Font Selector"
+msgstr "Vim — Выбор шрифта"
+
+msgid "Name:"
+msgstr "Ðазвание:"
+
+#. create toggle button
+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 "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 \"%s\""
+
+#, c-format
+msgid "E618: file \"%s\" is not a PostScript resource file"
+msgstr "E618: Файл \"%s\" не ÑвлÑетÑÑ Ñ„Ð°Ð¹Ð»Ð¾Ð¼ реÑурÑов PostScript"
+
+#, c-format
+msgid "E619: file \"%s\" is not a supported PostScript resource file"
+msgstr "E619: Файл \"%s\" не ÑвлÑетÑÑ Ð´Ð¾Ð¿ÑƒÑтимым файлом реÑурÑов PostScript"
+
+#, c-format
+msgid "E621: \"%s\" resource file has wrong version"
+msgstr "E621: Файл реÑурÑов \"%s\" неизвеÑтной верÑии"
+
+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 \"prolog.ps\" не найден"
+
+msgid "E456: Can't find PostScript resource file \"cidfont.ps\""
+msgstr "E456: Файл реÑурÑов PostScript \"cidfont.ps\" не найден"
+
+#, c-format
+msgid "E456: Can't find PostScript resource file \"%s.ps\""
+msgstr "E456: Файл реÑурÑов PostScript \"%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 <имÑ>"
+
+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: Ðевозможно выполнить fork() Ð´Ð»Ñ 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"
+" 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"
+
+#, 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 уже подÑоединена"
+
+#, c-format
+msgid "E261: cscope connection %s not found"
+msgstr "E261: Соединение Ñ cscope %s не обнаружено"
+
+#, c-format
+msgid "cscope connection %s closed"
+msgstr "Ñоединение Ñ cscope %s закрыто"
+
+#. should not reach here
+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 "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: Ðеобработанное иÑключение"
+
+#, c-format
+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 "подÑоединён"
+
+#, c-format
+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 "отметка не уÑтановлена"
+
+#, 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 ""
+"невозможно зарегиÑтрировать команду Ñ Ð¾Ð±Ñ€Ð°Ñ‚Ð½Ñ‹Ð¼ вызовом: буфер или окно в "
+"процеÑÑе удалениÑ"
+
+#. This should never happen. Famous last word?
+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"
+
+#, 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 в рееÑтре. "
+"Удалено!"
+
+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 ""
+"Слишком много параметров \"+команда\", \"-c команда\" или \"--cmd команда\""
+
+msgid "Invalid argument for"
+msgstr "ÐедопуÑтимый параметр длÑ"
+
+#, c-format
+msgid "%d files to edit\n"
+msgstr "Файлов Ð´Ð»Ñ Ñ€ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ: %d\n"
+
+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 "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: Warning: Output is not to a terminal\n"
+msgstr "Vim: Предупреждение: Вывод оÑущеÑтвлÑетÑÑ Ð½Ðµ на терминал\n"
+
+msgid "Vim: Warning: Input is not from a terminal\n"
+msgstr "Vim: Предупреждение: Ввод проиÑходит не Ñ Ñ‚ÐµÑ€Ð¼Ð¸Ð½Ð°Ð»Ð°\n"
+
+#. just in case..
+msgid "pre-vimrc command line"
+msgstr "ÐºÐ¾Ð¼Ð°Ð½Ð´Ð½Ð°Ñ Ñтрока перед выполнением 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 метка редактирование файла Ñ ÑƒÐºÐ°Ð·Ð°Ð½Ð½Ð¾Ð¹ меткой"
+
+# \n\t\t.. Ð´Ð»Ñ ÑƒÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ Ð² 80 Ñтолбцов
+msgid "-q [errorfile] edit file with first error"
+msgstr ""
+"-q [файл-ошибок]\n"
+"\t\t\t\t редактирование файла Ñ Ð¿ÐµÑ€Ð²Ð¾Ð¹ ошибкой"
+
+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ЗапуÑтить Ñ Ð³Ñ€Ð°Ñ„Ð¸Ñ‡ÐµÑким интерфейÑом (как \"gvim\")"
+
+msgid "-f or --nofork\tForeground: Don't fork when starting GUI"
+msgstr "-f или --nofork\tÐ’ активной задаче: Ðе выполнÑть fork при запуÑке GUI"
+
+msgid "-v\t\t\tVi mode (like \"vi\")"
+msgstr "-v\t\t\tРежим Vi (как \"vi\")"
+
+msgid "-e\t\t\tEx mode (like \"ex\")"
+msgstr "-e\t\t\tРежим Ex (как \"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Тихий (пакетный) режим (только Ð´Ð»Ñ \"ex\")"
+
+msgid "-d\t\t\tDiff mode (like \"vimdiff\")"
+msgstr "-d\t\t\tРежим отличий (как \"vimdiff\")"
+
+msgid "-y\t\t\tEasy mode (like \"evim\", modeless)"
+msgstr "-y\t\t\tПроÑтой режим (как \"evim\", безрежимный)"
+
+msgid "-R\t\t\tReadonly mode (like \"view\")"
+msgstr "-R\t\t\tТолько Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ (как \"view\")"
+
+msgid "-Z\t\t\tRestricted mode (like \"rvim\")"
+msgstr "-Z\t\t\tОграниченный режим (как \"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\tРежим Lisp"
+
+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'"
+
+# \n\t\t.. Ð´Ð»Ñ ÑƒÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ Ð² 80 Ñтолбцов
+msgid "-V[N][fname]\t\tBe verbose [level N] [log messages to fname]"
+msgstr ""
+"-V[N][файл]\t\tВыводить дополнительные ÑообщениÑ\n"
+"\t\t\t\t[уровень N] [запиÑывать в файл]"
+
+msgid "-D\t\t\tDebugging mode"
+msgstr "-D\t\t\tРежим отладки"
+
+msgid "-n\t\t\tNo swap file, use memory only"
+msgstr "-n\t\t\tБез Ñвоп-файла, иÑпользуетÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ памÑть"
+
+msgid "-r\t\t\tList swap files and exit"
+msgstr "-r\t\t\tВывеÑти ÑпиÑок Ñвоп-файлов и завершить работу"
+
+msgid "-r (with file name)\tRecover crashed session"
+msgstr "-r (Ñ Ð¸Ð¼ÐµÐ½ÐµÐ¼ файла)\tВоÑÑтановить аварийно завершённый ÑеанÑ"
+
+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Ðе иÑпользовать newcli Ð´Ð»Ñ Ð¾Ñ‚ÐºÑ€Ñ‹Ñ‚Ð¸Ñ Ð¾ÐºÐ½Ð°"
+
+msgid "-dev <device>\t\tUse <device> for I/O"
+msgstr "-dev <уÑтройÑтво>\t\tИÑпользовать Ð´Ð»Ñ I/O указанное <уÑтройÑтво>"
+
+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 "-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Ðе загружать Ñценарии модулей"
+
+# \n\t\t.. Ð´Ð»Ñ ÑƒÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ Ð² 80 Ñтолбцов
+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 Ñтолбцов
+msgid "-o[N]\t\tOpen N windows (default: one for each file)"
+msgstr ""
+"-o[N]\t\tОткрыть N окон (по умолчанию: по одному\n"
+"\t\t\t\tна каждый файл)"
+
+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 "+<lnum>\t\tÐачать редактирование в Ñтроке Ñ Ð½Ð¾Ð¼ÐµÑ€Ð¾Ð¼ <lnum>"
+
+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Выполнить <команду> поÑле загрузки первого файла"
+
+# \n\t\t.. Ð´Ð»Ñ ÑƒÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ Ð² 80 Ñтолбцов
+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 Ñтолбцов
+msgid "-s <scriptin>\tRead Normal mode commands from file <scriptin>"
+msgstr ""
+"-s <Ñценарий>\tПрочитать команды Обычного режима из\n"
+"\t\t\t\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 "-h or --help\tPrint Help (this message) and exit"
+msgstr "-h или --help\tВывеÑти Ñправку (Ñто Ñообщение) и завершить работу"
+
+msgid "--version\t\tPrint version information and exit"
+msgstr "--version\t\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 "Ðет диÑплеÑ"
+
+#. Failed to send, abort.
+msgid ": Send failed.\n"
+msgstr ": Отправка не удалаÑÑŒ.\n"
+
+#. Let vim start normally.
+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\""
+
+#. Highlight title
+msgid ""
+"\n"
+"mark line col file/text"
+msgstr ""
+"\n"
+"отмет Ñтр кол файл/текÑÑ‚"
+
+#. Highlight title
+msgid ""
+"\n"
+" jump line col file/text"
+msgstr ""
+"\n"
+"прыжок Ñтр кол файл/текÑÑ‚"
+
+#. Highlight title
+msgid ""
+"\n"
+"change line col text"
+msgstr ""
+"\n"
+"измен. Ñтр кол текÑÑ‚"
+
+msgid ""
+"\n"
+"# File marks:\n"
+msgstr ""
+"\n"
+"# Глобальные отметки:\n"
+
+#. Write the jumplist with -'
+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: Ðевозможно назначить Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ ÐºÐ¾Ð½Ñ‚ÐµÐºÑта ввода"
+
+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 "E293: block was not locked"
+msgstr "E293: Блок не заблокирован"
+
+msgid "E294: Seek error in swap file read"
+msgstr "E294: Ошибка поиÑка при чтении Ñвоп-файла"
+
+msgid "E295: Read error in swap file"
+msgstr "E295: Ошибка Ñ‡Ñ‚ÐµÐ½Ð¸Ñ Ñвоп-файла"
+
+msgid "E296: Seek error in swap file write"
+msgstr "E296: Ошибка поиÑка при запиÑи Ñвоп-файла"
+
+msgid "E297: Write error in swap file"
+msgstr "E297: Ошибка при запиÑи Ñвоп-файла"
+
+msgid "E300: Swap file already exists (symlink attack?)"
+msgstr ""
+"E300: Своп-файл уже ÑущеÑтвует (атака Ñ Ð¸Ñпользованием Ñимвольной ÑÑылки?)"
+
+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: Ошибка при обновлении ÑˆÐ¸Ñ„Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ñвоп-файла"
+
+#. could not (re)open the swap file, what can we do????
+msgid "E301: Oops, lost the swap file!!!"
+msgstr "E301: Ой, потерÑлÑÑ Ñвоп-файл!!!"
+
+msgid "E302: Could not rename swap file"
+msgstr "E302: Ðевозможно переименовать Ñвоп-файл"
+
+#, c-format
+msgid "E303: Unable to open swap file for \"%s\", recovery impossible"
+msgstr ""
+"E303: Ðе удалоÑÑŒ открыть Ñвоп-файл Ð´Ð»Ñ \"%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 не найден"
+
+msgid "Enter number of swap file to use (0 to quit): "
+msgstr ""
+"Введите номер Ñвоп-файла, который Ñледует иÑпользовать (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 не Ñмог обновить Ñвоп-файл"
+
+msgid " cannot be used with this version of Vim.\n"
+msgstr " Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать в данной верÑии Vim.\n"
+
+msgid "Use Vim version 3.0.\n"
+msgstr "ИÑпользуйте Vim верÑии 3.0.\n"
+
+#, c-format
+msgid "E307: %s does not look like a Vim swap file"
+msgstr "E307: %s не ÑвлÑетÑÑ Ñвоп-файлом Vim"
+
+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 "ИÑпользуетÑÑ Ñвоп-файл \"%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 "Своп-файл зашифрован: \"%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: Ðевозможно прочитать блок 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: Ðеправильный блок 1 ID (%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 "ВоÑÑтановление завершено. Проверьте, вÑÑ‘ ли в порÑдке."
+
+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 "ИÑпользование ключа ÑˆÐ¸Ñ„Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¸Ð· Ñвоп-файла Ð´Ð»Ñ Ñ‚ÐµÐºÑтового файла.\n"
+
+#. use msg() to start the scrolling properly
+msgid "Swap files found:"
+msgstr "Обнаружены Ñвоп-файлы:"
+
+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]"
+
+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: Ðевозможно обновить Ñвоп-файл, поÑкольку он не обнаружен"
+
+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: ÐŸÐµÑ‚Ð»Ñ Ñимвольных ÑÑылок Ð´Ð»Ñ \"%s\""
+
+msgid "E325: ATTENTION"
+msgstr "E325: Ð’ÐИМÐÐИЕ"
+
+msgid ""
+"\n"
+"Found a swap file by the name \""
+msgstr ""
+"\n"
+"Обнаружен Ñвоп-файл Ñ Ð¸Ð¼ÐµÐ½ÐµÐ¼ \""
+
+# С маленькой буквы, чтобы ÑоответÑтвовало по Ñтилю ÑоÑедним ÑообщениÑм.
+msgid "While opening file \""
+msgstr "при открытии файла: \""
+
+msgid " NEWER than swap file!\n"
+msgstr " Более СВЕЖИЙ, чем Ñвоп-файл!\n"
+
+#. 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."
+msgstr ""
+"\n"
+"(1) Возможно, редактирование Ñтого же файла выполнÑетÑÑ Ð² другой программе.\n"
+" ЕÑли Ñто так, то будьте внимательны при внеÑении изменений, чтобы\n"
+" у Ð²Ð°Ñ Ð½Ðµ поÑвилоÑÑŒ два разных варианта одного и того же файла."
+
+# Сообщение разделено, " \n" добавлено Ñ‚.к. Ñтрока не помещаетÑÑ.
+msgid " Quit, or continue with caution.\n"
+msgstr ""
+" \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 " ЕÑли вы уже выполнÑли Ñту операцию, удалите Ñвоп-файл \""
+
+msgid ""
+"\"\n"
+" to avoid this message.\n"
+msgstr ""
+"\"\n"
+" чтобы избежать поÑÐ²Ð»ÐµÐ½Ð¸Ñ Ñтого ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð² будущем.\n"
+
+msgid "Swap file \""
+msgstr "Своп-файл \""
+
+msgid "\" already exists!"
+msgstr "\" уже ÑущеÑтвует!"
+
+msgid "VIM - ATTENTION"
+msgstr "VIM — Ð’ÐИМÐÐИЕ"
+
+msgid "Swap file already exists!"
+msgstr "Своп-файл уже ÑущеÑтвует!"
+
+msgid ""
+"&Open Read-Only\n"
+"&Edit anyway\n"
+"&Recover\n"
+"&Quit\n"
+"&Abort"
+msgstr ""
+"&O Открыть Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ\n"
+"&E Редактировать\n"
+"&R ВоÑÑтановить\n"
+"&Q Выход\n"
+"&A Прервать"
+
+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 Прервать"
+
+msgid "E326: Too many swap files found"
+msgstr "E326: Обнаружено Ñлишком много Ñвоп-файлов"
+
+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"
+
+#. Only a mnemonic or accelerator is not valid.
+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: Разделители не могут быть компонентом пути к меню"
+
+#. Now we have found the matching menu, and we list the mappings
+#. Highlight title
+msgid ""
+"\n"
+"--- Menus ---"
+msgstr ""
+"\n"
+"--- Меню ---"
+
+msgid "Tear off this menu"
+msgstr "Оторвать Ñто меню"
+
+msgid "E333: Menu path must lead to a menu item"
+msgstr "E333: Путь к меню должен веÑти к Ñлементу меню"
+
+#, c-format
+msgid "E334: Menu not found: %s"
+msgstr "E334: Меню не найдено: %s"
+
+#, c-format
+msgid "E335: Menu not defined for %s mode"
+msgstr "E335: Меню не определено Ð´Ð»Ñ Ñ€ÐµÐ¶Ð¸Ð¼Ð° %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 ""
+"Перевод Ñообщений на руÑÑкий Ñзык: ВаÑилий Рагозин <vrr@users.sourceforge."
+"net>, Сергей Ðлёшин <alyoshin.s@gmail.com>"
+
+msgid "Interrupt: "
+msgstr "Прерывание: "
+
+msgid "Press ENTER or type command to continue"
+msgstr "Ðажмите ENTER или введите команду Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð´Ð¾Ð»Ð¶ÐµÐ½Ð¸Ñ"
+
+#, 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 " SPACE/d/j: Ñкран/Ñтраница/Ñтрока вниз, b/u/k: вверх, q: выход "
+
+msgid "Question"
+msgstr "ВопроÑ"
+
+msgid ""
+"&Yes\n"
+"&No"
+msgstr ""
+"&Y Да\n"
+"&N Ðет"
+
+msgid ""
+"&Yes\n"
+"&No\n"
+"Save &All\n"
+"&Discard All\n"
+"&Cancel"
+msgstr ""
+"&Y Да\n"
+"&N Ðет\n"
+"&A Сохранить вÑе\n"
+"&D ПотерÑть вÑе\n"
+"&C Отмена"
+
+msgid "Select Directory dialog"
+msgstr "Выбор каталога"
+
+msgid "Save File dialog"
+msgstr "Сохранение файла"
+
+msgid "Open File dialog"
+msgstr "Открытие файла"
+
+#. TODO: non-GUI file selector here
+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: ОжидалÑÑ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€ типа Ñ Ð¿Ð»Ð°Ð²Ð°ÑŽÑ‰ÐµÐ¹ точкой Ð´Ð»Ñ 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 "Добавлена одна Ñтрока"
+
+msgid "1 line less"
+msgstr "Убрана одна Ñтрока"
+
+#, c-format
+msgid "%ld more lines"
+msgstr "Добавлено Ñтрок: %ld"
+
+#, c-format
+msgid "%ld fewer lines"
+msgstr "Убрано Ñтрок: %ld"
+
+msgid " (Interrupted)"
+msgstr " (Прервано)"
+
+msgid "Beep!"
+msgstr "Би-би!"
+
+msgid "Vim: preserving files...\n"
+msgstr "Vim: Ñохранение файлов...\n"
+
+#. close all memfiles, without deleting
+msgid "Vim: Finished.\n"
+msgstr "Vim: Готово.\n"
+
+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: ÐедопуÑÑ‚Ð¸Ð¼Ð°Ñ Ñ„Ð¾Ñ€Ð¼Ð° курÑора"
+
+msgid "E548: digit expected"
+msgstr "E548: ТребуетÑÑ Ð²Ð²ÐµÑти цифру"
+
+msgid "E549: Illegal percentage"
+msgstr "E549: ÐедопуÑтимое значение процентов"
+
+msgid "Enter encryption key: "
+msgstr "Введите пароль Ð´Ð»Ñ ÑˆÐ¸Ñ„Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ: "
+
+msgid "Enter same key again: "
+msgstr "Повторите ввод паролÑ: "
+
+msgid "Keys don't match!"
+msgstr "Введённые пароли не Ñовпадают!"
+
+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\" не найден в пути Ð´Ð»Ñ Ñмены каталога"
+
+#, c-format
+msgid "E345: Can't find file \"%s\" in path"
+msgstr "E345: Файл \"%s\" в извеÑтных каталогах не найден"
+
+#, c-format
+msgid "E346: No more directory \"%s\" found in cdpath"
+msgstr "E346: Ð’ пути Ñмены каталога больше нет каталогов \"%s\""
+
+#, c-format
+msgid "E347: No more file \"%s\" found in path"
+msgstr "E347: Ð’ извеÑтных каталогах больше нет файлов \"%s\""
+
+msgid "Cannot connect to Netbeans #2"
+msgstr "Ðевозможно ÑоединитьÑÑ Ñ NetBeans #2"
+
+msgid "Cannot connect to Netbeans"
+msgstr "Ðевозможно ÑоединитьÑÑ Ñ NetBeans"
+
+#, c-format
+msgid "E668: Wrong access mode for NetBeans connection info file: \"%s\""
+msgstr ""
+"E668: Ðеправильный режим доÑтупа к информации о Ñоединении Ñ NetBeans: \"%s\""
+
+msgid "read from Netbeans socket"
+msgstr "чтение из гнезда NetBeans"
+
+#, 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 не поддерживаетÑÑ Ñ Ñтим графичеÑким интерфейÑом"
+
+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 :quit<Enter> to exit Vim"
+msgstr "Введите :quit<Enter> Ð´Ð»Ñ Ð²Ñ‹Ñ…Ð¾Ð´Ð° из 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 "Изменён отÑтуп в одной Ñтроке "
+
+#, c-format
+msgid "%ld lines indented "
+msgstr "Изменены отÑтупы в Ñтроках (%ld) "
+
+msgid "E748: No previously used register"
+msgstr "E748: Ðет предыдущего иÑпользованного региÑтра"
+
+#. must display the prompt
+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"
+
+msgid "block of 1 line yanked"
+msgstr "Ñкопирован блок из одной Ñтроки"
+
+msgid "1 line yanked"
+msgstr "Ñкопирована одна Ñтрока"
+
+#, c-format
+msgid "block of %ld lines yanked"
+msgstr "Ñкопирован блок из Ñтрок: %ld"
+
+#, c-format
+msgid "%ld lines yanked"
+msgstr "Ñкопировано Ñтрок: %ld"
+
+#, c-format
+msgid "E353: Nothing in register %s"
+msgstr "E353: Ð’ региÑтре %s ничего нет"
+
+#. Highlight title
+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"
+
+#, c-format
+msgid "%ld Cols; "
+msgstr "Колонок: %ld; "
+
+#, c-format
+msgid "Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Bytes"
+msgstr "Выделено %s%ld из %ld Ñтрок; %ld из %ld Ñлов; %ld из %ld байт"
+
+#, c-format
+msgid ""
+"Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Chars; %ld of %ld "
+"Bytes"
+msgstr ""
+"Выделено %s%ld из %ld Ñтр.; %ld из %ld Ñлов; %ld из %ld Ñимв.; %ld из %ld "
+"байт"
+
+#, c-format
+msgid "Col %s of %s; Line %ld of %ld; Word %ld of %ld; Byte %ld of %ld"
+msgstr "Кол. %s из %s; Ñтр. %ld из %ld; Ñл. %ld из %ld; байт %ld из %ld"
+
+#, c-format
+msgid ""
+"Col %s of %s; Line %ld of %ld; Word %ld of %ld; Char %ld of %ld; Byte %ld of "
+"%ld"
+msgstr ""
+"Кол. %s из %s; Ñтр. %ld из %ld; Ñл. %ld из %ld; Ñимв. %ld из %ld; байт %ld "
+"из %ld"
+
+#, c-format
+msgid "(+%ld for BOM)"
+msgstr "(+%ld Ñ ÑƒÑ‡Ñ‘Ñ‚Ð¾Ð¼ BOM)"
+
+msgid "%<%f%h%m%=Page %N"
+msgstr "%<%f%h%m%=Стр. %N"
+
+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>"
+
+msgid "E529: Cannot set 'term' to empty string"
+msgstr "E529: Значение опции 'term' не может быть пуÑтой Ñтрокой"
+
+msgid "E530: Cannot change term in GUI"
+msgstr "E530: Ð’ графичеÑком интерфейÑе изменÑть терминал невозможно"
+
+msgid "E531: Use \":gui\" to start the GUI"
+msgstr "E531: Ð”Ð»Ñ Ð·Ð°Ð¿ÑƒÑка графичеÑкого интерфейÑа иÑпользуйте \":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"
+
+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: Ðевозможно выбрать шрифтовой набор"
+
+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>"
+
+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 "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'"
+
+#, 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"
+
+#. 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.
+#, 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"
+
+#. if Vim opened a window: Executing a shell may cause crashes
+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: Ðеудачное завершение выбора принтера"
+
+#, 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 "E245: Illegal char '%c' in font name \"%s\""
+msgstr "E245: ÐедопуÑтимый Ñимвол '%c' в имени шрифта \"%s\""
+
+msgid "Vim: Double signal, exiting\n"
+msgstr "Vim: Двойной Ñигнал, завершение работы\n"
+
+#, c-format
+msgid "Vim: Caught deadly signal %s\n"
+msgstr "Vim: Получен убийÑтвенный Ñигнал %s\n"
+
+#, c-format
+msgid "Vim: Caught deadly signal\n"
+msgstr "Vim: Получен убийÑтвенный Ñигнал\n"
+
+#, c-format
+msgid "Opening the X display took %ld msec"
+msgstr "Открытие диÑÐ¿Ð»ÐµÑ X занÑло %ld 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"
+"Could not get security context for "
+msgstr ""
+"\n"
+"Ðевозможно получить контекÑÑ‚ безопаÑноÑти Ð´Ð»Ñ "
+
+msgid ""
+"\n"
+"Could not set security context for "
+msgstr ""
+"\n"
+"Ðевозможно уÑтановить контекÑÑ‚ безопаÑноÑти Ð´Ð»Ñ "
+
+msgid ""
+"\n"
+"Cannot execute shell "
+msgstr ""
+"\n"
+"Ðевозможно запуÑтить оболочку "
+
+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"
+"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 "shell returned %d"
+msgstr "завершение работы оболочки Ñ ÐºÐ¾Ð´Ð¾Ð¼ %d"
+
+#, 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 "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: Больше нет Ñлементов"
+
+#, c-format
+msgid "(%d of %d)%s%s: "
+msgstr "(%d из %d)%s%s: "
+
+msgid " (line deleted)"
+msgstr " (Ñтрока удалена)"
+
+msgid "E380: At bottom of quickfix stack"
+msgstr "E380: Внизу Ñтека быÑтрых иÑправлений"
+
+msgid "E381: At top of quickfix stack"
+msgstr "E381: Ðаверху Ñтека быÑтрых иÑправлений"
+
+#, c-format
+msgid "error list %d of %d; %d errors"
+msgstr "ÑпиÑок ошибок %d из %d; %d ошибок"
+
+msgid "E382: Cannot write, 'buftype' option is set"
+msgstr ""
+"E382: ЗапиÑÑŒ невозможна, значение опции 'buftype' не ÑвлÑетÑÑ Ð¿ÑƒÑтой Ñтрокой"
+
+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: ТребуетÑÑ Ñтрока или ÑпиÑок"
+
+#, c-format
+msgid "E369: invalid item in %s%%[]"
+msgstr "E369: ÐедопуÑтимый Ñлемент в %s%%[]"
+
+#, c-format
+msgid "E769: Missing ] after %s["
+msgstr "E769: Пропущена ] поÑле %s["
+
+#, 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 et al. not allowed here"
+msgstr "E67: \\z1 и Ñ‚.п. не могут быть иÑпользованы здеÑÑŒ"
+
+#, c-format
+msgid "E69: Missing ] after %s%%["
+msgstr "E69: Пропущена ] поÑле %s%%["
+
+#, c-format
+msgid "E70: Empty %s%%[]"
+msgstr "E70: ПуÑтое %s%%[]"
+
+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{...}"
+
+#, 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 ни за чем не Ñледует"
+
+msgid "E65: Illegal back reference"
+msgstr "E65: ÐедопуÑÑ‚Ð¸Ð¼Ð°Ñ Ð¾Ð±Ñ€Ð°Ñ‚Ð½Ð°Ñ ÑÑылка"
+
+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"
+
+msgid ""
+"E864: \\%#= can only be followed by 0, 1, or 2. The automatic engine will be "
+"used "
+msgstr ""
+"E864: поÑле \\%#= может быть только 0, 1 или 2. Будет иÑпользоватьÑÑ "
+"автоматичеÑÐºÐ°Ñ Ð¼Ð°ÑˆÐ¸Ð½Ð°"
+
+#, c-format
+msgid "E866: (NFA regexp) Misplaced %c"
+msgstr "E866: (рег. выражение ÐКÐ) неожиданный %c"
+
+msgid "E865: (NFA) Regexp end encountered prematurely"
+msgstr "E865: (ÐКÐ) неожиданный конец регулÑрного выражениÑ"
+
+#, c-format
+msgid "E867: (NFA) Unknown operator '\\z%c'"
+msgstr "E867: (ÐКÐ) неизвеÑтный оператор '\\z%c'"
+
+#, c-format
+msgid "E867: (NFA) Unknown operator '\\%%%c'"
+msgstr "E867: (ÐКÐ) неизвеÑтный оператор '\\%%%c'"
+
+#. should never happen
+msgid "E868: Error building NFA with equivalence class!"
+msgstr "E868: ошибка при Ñоздании ÐÐšÐ Ñ ÐºÐ»Ð°ÑÑом ÑквивалентноÑти!"
+
+#, c-format
+msgid "E869: (NFA) Unknown operator '\\@%c'"
+msgstr "E869: (ÐКÐ) неизвеÑтный оператор '\\@%c'"
+
+msgid "E870: (NFA regexp) Error reading repetition limits"
+msgstr "E870: (рег. выражение ÐКÐ) ошибка при чтении границ повторениÑ"
+
+#. Can't have a multi follow a multi.
+msgid "E871: (NFA regexp) Can't have a multi follow a multi !"
+msgstr "E871: (рег. выражение ÐКÐ) множеÑтво не может Ñледовать за множеÑтвом!"
+
+#. Too many `('
+msgid "E872: (NFA regexp) Too many '('"
+msgstr "E872: (рег. выражение ÐКÐ) Ñлишком много '('"
+
+msgid "E879: (NFA regexp) Too many \\z("
+msgstr "E879: (рег. выражение ÐКÐ) Ñлишком много \\z("
+
+msgid "E873: (NFA regexp) proper termination error"
+msgstr "E873: (рег. выражение ÐКÐ) ошибка корректного завершениÑ"
+
+msgid "E874: (NFA) Could not pop the stack !"
+msgstr "E874: (рег. выражение ÐКÐ) невозможно взÑть из Ñтека!"
+
+msgid ""
+"E875: (NFA regexp) (While converting from postfix to NFA), too many states "
+"left on stack"
+msgstr ""
+"E875: (рег. выражение ÐКÐ) в Ñтеке оÑталоÑÑŒ Ñлишком много ÑоÑтоÑний (при "
+"преобразовании из postfix в ÐКÐ)"
+
+msgid "E876: (NFA regexp) Not enough space to store the whole NFA "
+msgstr "E876: (рег. выражение ÐКÐ) недоÑтаточно меÑта Ð´Ð»Ñ Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð²Ñего ÐКÐ"
+
+msgid "E878: (NFA) Could not allocate memory for branch traversal!"
+msgstr "E878: (ÐКÐ) невозможно выделить памÑть Ð´Ð»Ñ Ð¿Ñ€Ð¾Ñ…Ð¾Ð´Ð° ветви!"
+
+msgid ""
+"Could not open temporary log file for writing, displaying on stderr ... "
+msgstr ""
+"Ðевозможно открыть файл временного журнала Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñи, вывод на stderr..."
+
+#, c-format
+msgid "(NFA) COULD NOT OPEN %s !"
+msgstr "(ÐКÐ) невозможно открыть %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 " (lang)"
+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 " (включает раннее показанные ÑоответÑтвиÑ)"
+
+#. cursor at status line
+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 "E759: Format error in spell file"
+msgstr "E759: Ошибка формата в файле правопиÑаниÑ"
+
+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 "Сжатие дерева Ñлов..."
+
+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"
+"\""
+
+#, 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 "Warning: region %s not supported"
+msgstr "Предупреждение: регион %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, Ñтрока %d"
+
+#, c-format
+msgid ""
+"Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in %s line "
+"%d"
+msgstr ""
+"Определение COMPOUNDPERMITFLAG поÑле Ñлемента PFX может дать неправильные "
+"результаты в %s, Ñтрока %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 %6d - %s"
+msgstr "Ñтрока %6d, Ñлово %6d — %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 "Чтение запиÑанного файла правопиÑаниÑ..."
+
+#.
+#. * Go through the trie of good words, soundfold each word and add it to
+#. * the soundfold trie.
+#.
+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: Ð˜Ð¼Ñ Ð²Ñ‹Ñ…Ð¾Ð´Ð½Ð¾Ð³Ð¾ файла не должно Ñодержать Ð½Ð°Ð·Ð²Ð°Ð½Ð¸Ñ Ñ€ÐµÐ³Ð¸Ð¾Ð½Ð°"
+
+msgid "E754: Only up to 8 regions supported"
+msgstr "E754: ПоддерживаетÑÑ Ð½Ðµ более 8-ми регионов"
+
+#, 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 removed from %s"
+msgstr "Слово удалено из %s"
+
+#, c-format
+msgid "Word added to %s"
+msgstr "Слово добавлено в %s"
+
+msgid "E763: Word characters differ between spell files"
+msgstr "E763: Символы Ñлов отличаютÑÑ Ð² файлах правопиÑаниÑ"
+
+msgid "Sorry, no suggestions"
+msgstr "Извините, нет предположений"
+
+#, c-format
+msgid "Sorry, only %ld suggestions"
+msgstr "Извините, только %ld предположений"
+
+#. for when 'cmdheight' > 1
+#. avoid more prompt
+#, 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"
+
+#, 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"
+
+#. This should have been checked when generating the .spl
+#. * file.
+msgid "E783: duplicate char in MAP entry"
+msgstr "E783: ПовторÑющийÑÑ Ñимвол в Ñлементе MAP"
+
+msgid "No Syntax items defined for this buffer"
+msgstr "СинтакÑичеÑкие Ñлементы Ð´Ð»Ñ Ð´Ð°Ð½Ð½Ð¾Ð³Ð¾ буфера не определены"
+
+#, c-format
+msgid "E390: Illegal argument: %s"
+msgstr "E390: ÐедопуÑтимый параметр: %s"
+
+#, 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: ЗдеÑÑŒ Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать параметр contains"
+
+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 "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: ÐеизвеÑтный цвет текÑта"
+
+msgid "E420: BG color unknown"
+msgstr "E420: ÐеизвеÑтный цвет фона"
+
+#, 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 " # при тип метка"
+
+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\" не ÑущеÑтвует"
+
+#. Give an indication of the number of matching tags
+#, 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\" не ÑущеÑтвует"
+
+#. Highlight title
+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 "Игнорирование длинной Ñтроки в файле tags"
+
+#, 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"
+
+#. never opened any tags file
+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: Ð’ termcap нет запиÑи \"%s\""
+
+msgid "E437: terminal capability \"cm\" required"
+msgstr "E437: ТребуетÑÑ ÑпоÑобноÑть терминала \"cm\""
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Terminal keys ---"
+msgstr ""
+"\n"
+"--- Кнопки терминала ---"
+
+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"
+
+#. This happens when the FileChangedRO autocommand changes the
+#. * file in a way it becomes shorter.
+msgid "E834: Line count changed unexpectedly"
+msgstr "E834: Ðеожиданно изменилÑÑ Ñчётчик Ñтрок"
+
+#. must display the prompt
+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 "Ðечего отменÑть"
+
+# Заголовок таблицы :undolist
+msgid "number changes when saved"
+msgstr " номер измен. когда Ñохранено"
+
+#, c-format
+msgid "%ld seconds ago"
+msgstr "%ld Ñ Ð½Ð°Ð·Ð°Ð´"
+
+msgid "E790: undojoin is not allowed after undo"
+msgstr "E790: Объединение отмен не допуÑкаетÑÑ Ð¿Ð¾Ñле отмены"
+
+msgid "E439: undo list corrupt"
+msgstr "E439: Повреждён ÑпиÑок отмены"
+
+msgid "E440: undo line missing"
+msgstr "E440: ПотерÑна Ñтрока отмены"
+
+#. Only MS VC 4.1 and earlier can do Win32s
+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"
+"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 "без графичеÑкого интерфейÑа."
+
+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 " Features included (+) or not (-):\n"
+msgstr " Включённые (+) и отключённые (-) оÑобенноÑти:\n"
+
+msgid " system vimrc file: \""
+msgstr " общеÑиÑтемный файл vimrc: \""
+
+msgid " user vimrc file: \""
+msgstr " пользовательÑкий файл vimrc: \""
+
+msgid " 2nd user vimrc file: \""
+msgstr " второй пользовательÑкий файл vimrc: \""
+
+msgid " 3rd user vimrc file: \""
+msgstr " третий пользовательÑкий файл vimrc: \""
+
+msgid " user exrc file: \""
+msgstr " пользовательÑкий файл exrc: \""
+
+msgid " 2nd user exrc file: \""
+msgstr " второй пользовательÑкий файл exrc: \""
+
+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 " 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 " ОТЛÐДОЧÐÐЯ СБОРКÐ"
+
+msgid "VIM - Vi IMproved"
+msgstr "VIM — Vi IMproved (улучшенный Vi)"
+
+msgid "version "
+msgstr "верÑÐ¸Ñ "
+
+msgid "by Bram Moolenaar et al."
+msgstr "Брам Мооленаар и другие"
+
+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> Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ñправки "
+
+msgid "type :help version7<Enter> for version info"
+msgstr "наберите :help version7<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 "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 "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: Окно не может быть одновременно Ñлева вверху и Ñправа внизу"
+
+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: ÐÐµÐ»ÑŒÐ·Ñ Ð·Ð°ÐºÑ€Ñ‹Ñ‚ÑŒ окно автокоманд"
+
+msgid "E814: Cannot close window, only autocmd window would remain"
+msgstr "E814: ÐÐµÐ»ÑŒÐ·Ñ Ð·Ð°ÐºÑ€Ñ‹Ñ‚ÑŒ окно, оÑтанетÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ окно автокоманд"
+
+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 "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"
+
+#. Now concatenate
+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 "-- Ðет Ñтрок в буфере --"
+
+#.
+#. * 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: Выполнение команды прервано"
+
+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: ÐеизвеÑтный шрифтовой набор: %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: ВнутреннÑÑ Ð¾ÑˆÐ¸Ð±ÐºÐ°"
+
+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 "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()\" из библиотеки"
+
+#, 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: ВозможноÑть иÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð³Ñ€Ð°Ñ„Ð¸Ñ‡ÐµÑкого интерфейÑа выключена при "
+"компилÑции"
+
+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 "E37: No write since last change (add ! to override)"
+msgstr "E37: Ð˜Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð½Ðµ Ñохранены (добавьте !, чтобы обойти проверку)"
+
+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: Программа обработки регулÑрных выражений повреждена"
+
+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: Ðевозможно изменить переменную в пеÑочнице: \"%s\""
+
+msgid "E47: Error while reading errorfile"
+msgstr "E47: Ошибка при чтении файла ошибок"
+
+msgid "E48: Not allowed in sandbox"
+msgstr "E48: Ðе допуÑкаетÑÑ Ð² пеÑочнице"
+
+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: Ошибка Ð·Ð°ÐºÑ€Ñ‹Ñ‚Ð¸Ñ Ñвоп-файла"
+
+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 "Zero count"
+msgstr "Ðулевое значение Ñчётчика"
+
+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 не допуÑкает изменений в файлах только Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ"
+
+#, c-format
+msgid "E685: Internal error: %s"
+msgstr "E685: ВнутреннÑÑ Ð¾ÑˆÐ¸Ð±ÐºÐ°: %s"
+
+msgid "E363: pattern uses more memory than 'maxmempattern'"
+msgstr "E363: Шаблон иÑпользует больше памÑти чем 'maxmempattern'"
+
+msgid "E749: empty buffer"
+msgstr "E749: ПуÑтой буфер"
+
+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: ÐедопуÑтимое Ð¸Ð¼Ñ Ñ€ÐµÐ³Ð¸Ñтра"
+
+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 "Ð˜Ð½Ð´ÐµÐºÑ Ð´Ð¾Ð»Ð¶ÐµÐ½ быть целым чиÑлом или выборкой, а не %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"
+
+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"
+
+#, c-format
+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 "Ðевозможно Ñменить каталог"
+
+#, c-format
+msgid "expected 3-tuple as imp.find_module() result, but got %s"
+msgstr "ОжидалÑÑ 3-кортеж как результат imp.find_module(), но получен %s"
+
+#, c-format
+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 "Ðевозможно изменить фикÑированный Ñловарь"
+
+#, c-format
+msgid "cannot set attribute %s"
+msgstr "Ðевозможно уÑтановить атрибут %s"
+
+msgid "hashtab changed during iteration"
+msgstr "Ð¥Ñш-таблица изменилаÑÑŒ при итерации"
+
+#, 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 "Ð˜Ð½Ð´ÐµÐºÑ ÑпиÑка за пределами диапазона"
+
+#. No more suitable format specifications in python-2.3
+#, c-format
+msgid "internal error: failed to get vim list item %d"
+msgstr "ВнутреннÑÑ Ð¾ÑˆÐ¸Ð±ÐºÐ°: не удалоÑÑŒ получить Ñлемент VIM-ÑпиÑка %d"
+
+msgid "failed to add item to list"
+msgstr "Ðевозможно добавить Ñлемент в ÑпиÑок"
+
+#, c-format
+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 "Ðевозможно изменить фикÑированный ÑпиÑок"
+
+#, c-format
+msgid "unnamed function %s does not exist"
+msgstr "Ðе ÑущеÑтвует безымÑнной функции %s"
+
+#, c-format
+msgid "function %s does not exist"
+msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ %s не ÑущеÑтвует"
+
+msgid "function constructor does not accept keyword arguments"
+msgstr "КонÑтруктор функции не допуÑкает ключевые Ñлова как аргументы"
+
+#, 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 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/po/sjiscorr.c b/src/po/sjiscorr.c
new file mode 100644
index 0000000000..fec4740c04
--- /dev/null
+++ b/src/po/sjiscorr.c
@@ -0,0 +1,50 @@
+/*
+ * 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(argc, argv)
+ 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, "ja.po - Japanese message file", 29) == 0)
+ {
+ fputs("ja.sjis.po - Japanese message file for Vim (version 6.x)\n", stdout);
+ 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/po/sk.cp1250.po b/src/po/sk.cp1250.po
new file mode 100644
index 0000000000..ebc31c1ed7
--- /dev/null
+++ b/src/po/sk.cp1250.po
@@ -0,0 +1,5821 @@
+# Slovak translation of vim
+# Lubomir Host 'rajo' <rajo AT platon.sk>
+# 2005 - Platon Group, http://platon.sk/
+# $Revision: 1.4 $
+# $LastChangedDate: 2005-10-08 12:00:24 +0200 (Sat, 08 Oct 2005) $
+msgid ""
+msgstr ""
+"Project-Id-Version: vim\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2005-09-30 15:58+0200\n"
+"PO-Revision-Date: 2005-09-30 15:58+0200\n"
+"Last-Translator: Lubomir Host <rajo@platon.sk>\n"
+"Language-Team: Slovak <sk-i18n@lists.linux.sk>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=cp1250\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: Vim 7.x\n"
+
+msgid "E82: Cannot allocate any buffer, exiting..."
+msgstr "E82: Nedá sa alokova buffer, konèím..."
+
+msgid "E83: Cannot allocate buffer, using other one..."
+msgstr "E83: Nedá sa alokova buffer, použijem iný..."
+
+msgid "E515: No buffers were unloaded"
+msgstr "E515: Žiadny buffer nebol uvo¾nený"
+
+msgid "E516: No buffers were deleted"
+msgstr "E516: Žiadny buffer nebol vymazaný"
+
+msgid "E517: No buffers were wiped out"
+msgstr "E517: Žiadny buffer nebol vymazaný"
+
+msgid "1 buffer unloaded"
+msgstr "1 buffer uvo¾nený"
+
+#, c-format
+msgid "%d buffers unloaded"
+msgstr "%d bufferov uvo¾nených"
+
+msgid "1 buffer deleted"
+msgstr "1 buffer vymazaný"
+
+#, c-format
+msgid "%d buffers deleted"
+msgstr "%d bufferov vymazaných"
+
+msgid "1 buffer wiped out"
+msgstr "1 buffer odstránený"
+
+#, c-format
+msgid "%d buffers wiped out"
+msgstr "%d bufferov odstránených"
+
+msgid "E84: No modified buffer found"
+msgstr "E84: Nebol nájdený žiadny zmenený buffer"
+
+#. back where we started, didn't find anything.
+msgid "E85: There is no listed buffer"
+msgstr "E85: Nenašiel som žiadny buffer"
+
+msgid "E86: Buffer %ld does not exist"
+msgstr "E86: Buffer %ld neexistuje"
+
+msgid "E87: Cannot go beyond last buffer"
+msgstr "E87: Za posledný buffer sa nedá preskoèi"
+
+msgid "E88: Cannot go before first buffer"
+msgstr "E88: Pred prvý buffer sa nedá preskoèi"
+
+msgid "E89: No write since last change for buffer %ld (add ! to override)"
+msgstr "E89: Zmeny v bufferi %ld neboli uložené (! pre vynútenie)"
+
+msgid "E90: Cannot unload last buffer"
+msgstr "E90: Posledný buffer sa nedá odstráni"
+
+msgid "W14: Warning: List of file names overflow"
+msgstr "W14: Varovanie: preteèenie zoznamu s názvami súborov"
+
+#, c-format
+msgid "E92: Buffer %ld not found"
+msgstr "E92: buffer %ld nenájdený"
+
+#, c-format
+msgid "E93: More than one match for %s"
+msgstr "E93: Vzoru %s vyhovuje viac bufferov"
+
+#, c-format
+msgid "E94: No matching buffer for %s"
+msgstr "E94: Vzoru %s nevyhovuje žiadny buffer"
+
+#, c-format
+msgid "line %ld"
+msgstr "riadok %ld"
+
+msgid "E95: Buffer with this name already exists"
+msgstr "E95: Buffer takéhoto mena už existuje"
+
+msgid " [Modified]"
+msgstr " [Zmenený]"
+
+msgid "[Not edited]"
+msgstr "[Neupravovaný]"
+
+msgid "[New file]"
+msgstr "[Nový súbor]"
+
+msgid "[Read errors]"
+msgstr "[Chyby pri èítaní]"
+
+msgid "[readonly]"
+msgstr "[iba pre èítanie]"
+
+#, c-format
+msgid "1 line --%d%%--"
+msgstr "1 riadok --%d%%--"
+
+#, c-format
+msgid "%ld lines --%d%%--"
+msgstr "%ld riadkov --%d%%--"
+
+#, c-format
+msgid "line %ld of %ld --%d%%-- col "
+msgstr "riadok %ld z %ld --%d%%-- ståpec"
+
+msgid "[No Name]"
+msgstr "[Bez mena]"
+
+#. must be a help buffer
+msgid "help"
+msgstr "pomocník"
+
+msgid "[help]"
+msgstr "[pomocník]"
+
+msgid "[Preview]"
+msgstr "[Náh¾ad]"
+
+msgid "All"
+msgstr "Všetko"
+
+msgid "Bot"
+msgstr "Koniec"
+
+msgid "Top"
+msgstr "Zaèiatok"
+
+#, c-format
+msgid ""
+"\n"
+"# Buffer list:\n"
+msgstr ""
+"\n"
+"# Zoznam bufferov:\n"
+
+msgid "[Error List]"
+msgstr "[Zoznam chýb]"
+
+msgid ""
+"\n"
+"--- Signs ---"
+msgstr ""
+"\n"
+"--- Znaky ---"
+
+#, c-format
+msgid "Signs for %s:"
+msgstr "Znaky pre %s:"
+
+#, c-format
+msgid " line=%ld id=%d name=%s"
+msgstr " riadok=%ld id=%d meno=%s"
+
+#, c-format
+msgid "E96: Can not diff more than %ld buffers"
+msgstr "E96: Nemôžem porovna viac ako %ld bufferov"
+
+msgid "E97: Cannot create diffs"
+msgstr "E97: Nedajú sa vytvori porovnania"
+
+msgid "Patch file"
+msgstr "Záplatový súbor"
+
+msgid "E98: Cannot read diff output"
+msgstr "E98: Nedá sa èíta výstup porovnania"
+
+msgid "E99: Current buffer is not in diff mode"
+msgstr "E99: Aktuálny buffer nie je v porovnávacom móde"
+
+msgid "E100: No other buffer in diff mode"
+msgstr "E100: V porovnávacom móde sa nenachádza iný buffer"
+
+msgid "E101: More than two buffers in diff mode, don't know which one to use"
+msgstr "E101: Viac ako dva buffery v porovnávacom móde; neviem, ktorý použi"
+
+#, c-format
+msgid "E102: Can't find buffer \"%s\""
+msgstr "E102: Nedá sa nájs buffer \"%s\""
+
+#, c-format
+msgid "E103: Buffer \"%s\" is not in diff mode"
+msgstr "E103: Buffer \"%s\" nie je v porovnávacom móde"
+
+# TODO: digraph
+msgid "E104: Escape not allowed in digraph"
+msgstr "E104: digraph nesmie obsahova znak Escape"
+
+msgid "E544: Keymap file not found"
+msgstr "E544: Mapa kláves nenájdená"
+
+msgid "E105: Using :loadkeymap not in a sourced file"
+msgstr "E105: Použitý príkaz :loadkeymap v súbore, ktorý nie je interpretovaný"
+
+msgid " Keyword completion (^N^P)"
+msgstr " Doplòovanie k¾úèových slov (^N^P)"
+
+#. ctrl_x_mode == 0, ^P/^N compl.
+msgid " ^X mode (^]^D^E^F^I^K^L^N^O^P^S^U^V^Y)"
+msgstr " ^X režim (^]^D^E^F^I^K^L^N^O^P^S^U^V^Y)"
+
+msgid " Whole line completion (^L^N^P)"
+msgstr " Doplòovanie celých riadkov (^L^N^P)"
+
+msgid " File name completion (^F^N^P)"
+msgstr " Doplòovanie názvov súborov (^F^N^P)"
+
+msgid " Tag completion (^]^N^P)"
+msgstr " Doplòovanie tagov (^]^N^P)"
+
+msgid " Path pattern completion (^N^P)"
+msgstr " Doplòovanie vzoru ciest (^N^P)"
+
+msgid " Definition completion (^D^N^P)"
+msgstr " Doplòovanie definícií (^D^N^P)"
+
+msgid " Dictionary completion (^K^N^P)"
+msgstr " Doplòovanie pod¾a slovníka (^K^N^P)"
+
+msgid " Thesaurus completion (^T^N^P)"
+msgstr " Doplòovanie pod¾a lexikonu (^T^N^P)"
+
+msgid " Command-line completion (^V^N^P)"
+msgstr " Doplòovanie príkazového riadka (^V^N^P)"
+
+msgid " User defined completion (^U^N^P)"
+msgstr " Doplòovanie celých riadkov (^U^N^P)"
+
+msgid " Omni completion (^O^N^P)"
+msgstr " Doplòovanie tagov (^O^N^P)"
+
+msgid " Spelling suggestion (^S^N^P)"
+msgstr " Doplòovanie celých riadkov (^S^N^P)"
+
+msgid " Keyword Local completion (^N^P)"
+msgstr " Miestne doplòovanie k¾úèových slov (^N^P)"
+
+msgid "Hit end of paragraph"
+msgstr "Koniec odstavca"
+
+msgid "'dictionary' option is empty"
+msgstr "vo¾ba 'dictionary' (slovník) je prázdna"
+
+msgid "'thesaurus' option is empty"
+msgstr "vo¾ba 'thesaurus' (lexikon) je prázdna"
+
+#, c-format
+msgid "Scanning dictionary: %s"
+msgstr "preh¾adávam slovník %s"
+
+msgid " (insert) Scroll (^E/^Y)"
+msgstr " (insert) Rolovanie (^E/^Y)"
+
+msgid " (replace) Scroll (^E/^Y)"
+msgstr " (replace) Rolovanie (^E/^Y)"
+
+#, c-format
+msgid "Scanning: %s"
+msgstr "Preh¾adávam: %s"
+
+#, c-format
+msgid "Scanning tags."
+msgstr "Preh¾adávam tagy."
+
+msgid " Adding"
+msgstr " Pridávam"
+
+#. 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.
+#.
+msgid "-- Searching..."
+msgstr "-- H¾adám..."
+
+msgid "Back at original"
+msgstr "Východzia podoba"
+
+msgid "Word from other line"
+msgstr "Slovo z iného riadku"
+
+msgid "The only match"
+msgstr "Jediná zhoda"
+
+#, c-format
+msgid "match %d of %d"
+msgstr "zhoda %d z %d"
+
+#, c-format
+msgid "match %d"
+msgstr "zhoda %d"
+
+msgid "E18: Unexpected characters in :let"
+msgstr "E18: Neoèekávané znaky v :let"
+
+msgid "E684: list index out of range: %ld"
+msgstr "E684: index v zozname je mimo rozsah: %ld"
+
+#, c-format
+msgid "E121: Undefined variable: %s"
+msgstr "E121: Nedefinovaná premenná: %s"
+
+msgid "E111: Missing ']'"
+msgstr "E111: Chýba ']'"
+
+msgid "E686: Argument of %s must be a List"
+msgstr "E686: Argument %s musí by Zoznam (List)"
+
+#, c-format
+msgid "E712: Argument of %s must be a List or Dictionary"
+msgstr "E712: Argument %s musí by Zoznam (List) alebo Slovník (Dictionary)"
+
+msgid "E713: Cannot use empty key for Dictionary"
+msgstr "E713: Nemožno použi prázdny k¾úè pre Slovník (Dictionary)"
+
+msgid "E714: List required"
+msgstr "E714: vyžaduje sa Zoznam (List)"
+
+msgid "E715: Dictionary required"
+msgstr "E715: Vyžaduje sa Slovník (Dictionary)"
+
+#, c-format
+msgid "E118: Too many arguments for function: %s"
+msgstr "E118: Príliš mnoho argumentov pre funkciu %s"
+
+#, c-format
+msgid "E716: Key not present in Dictionary: %s"
+msgstr "E716: k¾úè sa v Slovníku (Dictionary) nenachádza: %s"
+
+msgid "E122: Function %s already exists, add ! to replace it"
+msgstr "E122: Funkcia %s už existuje. Použite ! pre jej nahradenie."
+
+msgid "E717: Dictionary entry already exists"
+msgstr "E717: Záznam v Slovníku (Dictionary) už existuje"
+
+msgid "E718: Funcref required"
+msgstr "E718: Je vyžadovaný odkaz na Funkciu (Funcref)"
+
+msgid "E719: Cannot use [:] with a Dictionary"
+msgstr "E719: Nemožno použit [:] so Slovníkom (Dictionary)"
+
+#, c-format
+msgid "E734: Wrong variable type for %s="
+msgstr "E734: Zlý typ premennej pre %s="
+
+msgid "E130: Unknown function: %s"
+msgstr "E130: Neznáma funkcia: %s"
+
+msgid "E461: Illegal variable name: %s"
+msgstr "E461: Neprípustné meno premennej: %s"
+
+msgid "E687: Less targets than List items"
+msgstr "E687: Menej cie¾ov ako položiek Po¾a (List items)"
+
+msgid "E688: More targets than List items"
+msgstr "E688: Viac cie¾ov ako položiek Po¾a (List items)"
+
+msgid "Double ; in list of variables"
+msgstr "Dvojitá ; v zozname premenných"
+
+msgid "E738: Can't list variables for %s"
+msgstr "E738: Nemožno vypísa premenné pre %s"
+
+msgid "E689: Can only index a List or Dictionary"
+msgstr "E689: Indexova možno iba Zoznam (List) alebo Slovník (Dictionary)"
+
+msgid "E708: [:] must come last"
+msgstr "E708: [:] musí prís ako posledná"
+
+msgid "E709: [:] requires a List value"
+msgstr "E709: [:] vyžaduje hodnotu Po¾a (List value)"
+
+msgid "E710: List value has more items than target"
+msgstr "E710: Hodnota Po¾a (List value) má viac položiek ako cie¾"
+
+msgid "E711: List value has not enough items"
+msgstr "E711: Hodnota Po¾a (List value) nemá dostatok položiek"
+
+msgid "E690: Missing \"in\" after :for"
+msgstr "E690: Chýba \"in\" po :for"
+
+#, c-format
+msgid "E107: Missing parentheses: %s"
+msgstr "E107: Chýbajú zátvorky: %s"
+
+#, c-format
+msgid "E108: No such variable: \"%s\""
+msgstr "E108: Premenná \"%s\" neexistuje"
+
+msgid "E743: variable nested too deep for (un)lock"
+msgstr "E743: premenná je príliš vnorená na (od)blokovanie"
+
+msgid "E109: Missing ':' after '?'"
+msgstr "E109: Po '?' chýba ':'"
+
+msgid "E691: Can only compare List with List"
+msgstr "E691: Porovnáva možno iba Zoznam so Zoznamom (List with List)"
+
+msgid "E692: Invalid operation for Lists"
+msgstr "E692: Neplatná operácia pre Zoznamy (Lists)"
+
+msgid "E735: Can only compare Dictionary with Dictionary"
+msgstr "E735: Porovnáva možno iba Slovník so Slovníkom (Dictionary with Dictionary)"
+
+msgid "E736: Invalid operation for Dictionary"
+msgstr "E736: Neplatná operácia pre Slovník"
+
+msgid "E693: Can only compare Funcref with Funcref"
+msgstr "E693: Porovnáva možno iba odkaz na Funkciu s odkazom na Funkciu (Funcref with Funcref)"
+
+msgid "E694: Invalid operation for Funcrefs"
+msgstr "E694: Neplatná operácia pre odkazy na Funkcie (Funcrefs)"
+
+msgid "E110: Missing ')'"
+msgstr "E110: Chýba ')'"
+
+msgid "E695: Cannot index a Funcref"
+msgstr "E695: Nemožno indexova odkaz na Funkciu (Funcref)"
+
+#, c-format
+msgid "E112: Option name missing: %s"
+msgstr "E112: Chýba meno vo¾by: %s"
+
+#, c-format
+msgid "E113: Unknown option: %s"
+msgstr "E113: Neznáma vo¾ba: %s"
+
+#, c-format
+msgid "E114: Missing quote: %s"
+msgstr "E114: Chýbajú úvodzovky: %s"
+
+#, c-format
+msgid "E115: Missing quote: %s"
+msgstr "E115: Chýbajú úvodzovky: %s"
+
+msgid "E696: Missing comma in List: %s"
+msgstr "E696: Chýba èiarka v Zozname: %s"
+
+msgid "E697: Missing end of List ']': %s"
+msgstr "E697: Chýba koniec Zoznamu (List) ']': %s"
+
+msgid "E720: Missing colon in Dictionary: %s"
+msgstr "E720: Chýba dvojbodka v Slovníku (Dictionary): %s"
+
+#, c-format
+msgid "E721: Duplicate key in Dictionary: \"%s\""
+msgstr "E721: Duplikovaný k¾úè v Slovníku (Dictionary): \"%s\""
+
+msgid "E722: Missing comma in Dictionary: %s"
+msgstr "E722: Chýba èiarka v Slovníku (Dictionary): %s"
+
+msgid "E723: Missing end of Dictionary '}': %s"
+msgstr "E723: Chýba koniec Slovníka (Dictionary) '}': %s"
+
+msgid "E724: variable nested too deep for displaying"
+msgstr "E724: premenná je vnorená príliš hlboko pre zobrazenie"
+
+msgid "E699: Too many arguments"
+msgstr "E699: Príliš mnoho argumentov"
+
+#.
+#. * 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"
+
+msgid "E737: Key already exists: %s"
+msgstr "E737: K¾úè už existuje: %s"
+
+#, c-format
+msgid "+-%s%3ld lines: "
+msgstr "+-%s%3ld riadky: "
+
+msgid "E700: Unknown function: %s"
+msgstr "E700: Neznáma funkcia: %s"
+
+msgid ""
+"&OK\n"
+"&Cancel"
+msgstr ""
+"&OK\n"
+"&Zruši"
+
+msgid "called inputrestore() more often than inputsave()"
+msgstr "funkcia inputrestore() volaná èastejšie ako inputsave()"
+
+msgid "E745: Range not allowed"
+msgstr "E745: Rozsah nie je povolený"
+
+msgid "E701: Invalid type for len()"
+msgstr "E701: Neplatný typ pre len()"
+
+msgid "E726: Stride is zero"
+msgstr "E726: Krok je nulový"
+
+msgid "E727: Start past end"
+msgstr "E727: Zaèiatok presahuje koniec"
+
+msgid "<empty>"
+msgstr "<prázdny>"
+
+msgid "E240: No connection to Vim server"
+msgstr "E240: Neexistuje pripojenie k Vim serveru"
+
+#, c-format
+msgid "E241: Unable to send to %s"
+msgstr "E241: Nemôžem posla na %s"
+
+msgid "E277: Unable to read a server reply"
+msgstr "E277: Nemôžem èíta odpoveï servra"
+
+msgid "E655: Too many symbolic links (cycle?)"
+msgstr "E655: Príliš mnoho symbolických odkazov (sluèka?)"
+
+msgid "E258: Unable to send to client"
+msgstr "E258: Nemôžem posla klientovi"
+
+msgid "E702: Sort compare function failed"
+msgstr "E702: Funkcia na utriedenie/porovnanie zlyhala"
+
+msgid "(Invalid)"
+msgstr "(Chybný)"
+
+msgid "E677: Error writing temp file"
+msgstr "E677: Chyba pri zápise doèasného súboru"
+
+msgid "E703: Using a Funcref as a Number"
+msgstr "E703: Použitý odkaz na Funkciu (Funcref) ako èíslo"
+
+msgid "E745: Using a List as a Number"
+msgstr "E745: Zoznam (List) použitý ako èíslo"
+
+msgid "E728: Using a Dictionary as a Number"
+msgstr "E728: Slovník (Dictionary) použitý ako èíslo"
+
+msgid "E729: using Funcref as a String"
+msgstr "E729: Odkaz na Funkciu (Funcref) použitý ako Reazec (String)"
+
+msgid "E730: using List as a String"
+msgstr "E730: Zoznam (List) použitý ako Reazec (String)"
+
+msgid "E731: using Dictionary as a String"
+msgstr "E731: Slovník (Dictionary) použitý ako Reazec (String)"
+
+msgid "E704: Funcref variable name must start with a capital: %s"
+msgstr "E704: Premenná typu odkaz na Funkciu (Funcref) musí zaèína s ve¾kým písmenom: %s"
+
+#, c-format
+msgid "E705: Variable name conflicts with existing function: %s"
+msgstr "E705: Meno premennej je v konflikte s existujúcou funkciou: %s"
+
+msgid "E706: Variable type mismatch for: %s"
+msgstr "E706: Typ premennej sa nezhoduje: %s"
+
+#, c-format
+msgid "E741: Value is locked: %s"
+msgstr "E741: Hodnota je uzamknutá: %s"
+
+msgid "Unknown"
+msgstr "Neznámy"
+
+msgid "E742: Cannot change value of %s"
+msgstr "E742: Nemožno zmeni hodnotu %s"
+
+msgid "E698: variable nested too deep for making a copy"
+msgstr "E698: premenná je vnorená príliš hlboko pre skopírovanie"
+
+#, c-format
+msgid "E124: Missing '(': %s"
+msgstr "E124: Chýba '(': %s"
+
+#, c-format
+msgid "E125: Illegal argument: %s"
+msgstr "E125: Neprípustný argument: %s"
+
+msgid "E126: Missing :endfunction"
+msgstr "E126: Chýba :endfunction"
+
+msgid "E746: Function name does not match script file name: %s"
+msgstr "E746: Meno funkcie sa nezhoduje s menom interpretovaného súboru: %s"
+
+msgid "E129: Function name required"
+msgstr "E129: Je vyžadované meno funkcie"
+
+msgid "E128: Function name must start with a capital or contain a colon: %s"
+msgstr "E128: Názov funkcie musí zaèína ve¾kým písmenom alebo obsahova dvojbodku: %s"
+
+#, c-format
+msgid "E131: Cannot delete function %s: It is in use"
+msgstr "E131: Nedá sa vymaza funkcia %s: je používaná"
+
+msgid "E132: Function call depth is higher than 'maxfuncdepth'"
+msgstr "E132: Zanorenie funkcií je hlbšie než 'maxfuncdepth'"
+
+#, c-format
+msgid "calling %s"
+msgstr "volám %s"
+
+msgid "%s aborted"
+msgstr "%s zrušený"
+
+#, c-format
+msgid "%s returning #%ld"
+msgstr "%s vrátilo #%ld"
+
+msgid "%s returning %s"
+msgstr "%s vrátilo %s"
+
+#, c-format
+msgid "continuing in %s"
+msgstr "pokraèujem v %s"
+
+msgid "E133: :return not inside a function"
+msgstr "E133: :return mimo funkciu"
+
+#, c-format
+msgid ""
+"\n"
+"# global variables:\n"
+msgstr ""
+"\n"
+"# globálne premenné:\n"
+
+msgid ""
+"\n"
+"\tLast set from "
+msgstr ""
+"\n"
+"\tPosledné nastavenie z "
+
+#, c-format
+msgid "<%s>%s%s %d, Hex %02x, Octal %03o"
+msgstr "<%s>%s%s %d, šestnástkovo %02x, osmièkovo %03o"
+
+msgid "> %d, Hex %04x, Octal %o"
+msgstr "> %d, šestnástkovo %04x, osmièkovo %o"
+
+msgid "> %d, Hex %08x, Octal %o"
+msgstr "> %d, šestnástkovo %08x, osmièkovo %o"
+
+msgid "E134: Move lines into themselves"
+msgstr "E134: Prekrytie riadkov sebou samými"
+
+msgid "1 line moved"
+msgstr "1 riadok presunutý"
+
+#, c-format
+msgid "%ld lines moved"
+msgstr "%ld riadkov presunutých"
+
+#, c-format
+msgid "%ld lines filtered"
+msgstr "%ld riadkov filtrovaných"
+
+msgid "E135: *Filter* Autocommands must not change current buffer"
+msgstr "E135: Automatické príkazy *Filter* nesmú meni aktuálny buffer"
+
+msgid "[No write since last change]\n"
+msgstr "[Neuložené zmeny]\n"
+
+msgid "%sviminfo: %s in line: "
+msgstr "%sviminfo: %s na riadku: "
+
+msgid "E136: viminfo: Too many errors, skipping rest of file"
+msgstr "E136: viminfo: príliš mnoho chýb, preskakujem zbytok súboru"
+
+#, c-format
+msgid "Reading viminfo file \"%s\"%s%s%s"
+msgstr "Èítam viminfo súbor \"%s\"%s%s%s"
+
+msgid " info"
+msgstr " informácie"
+
+msgid " marks"
+msgstr " znaèky"
+
+msgid " FAILED"
+msgstr " ZLYHALO"
+
+#, c-format
+msgid "E137: Viminfo file is not writable: %s"
+msgstr "E137: Do viminfo súboru %s sa nedá zapisova"
+
+#, c-format
+msgid "E138: Can't write viminfo file %s!"
+msgstr "E138: Nedá sa uloži viminfo súbor %s!"
+
+#, c-format
+msgid "Writing viminfo file \"%s\""
+msgstr "Ukládám viminfo súboru \"%s\""
+
+#. Write the info:
+#, c-format
+msgid "# This viminfo file was generated by Vim %s.\n"
+msgstr "# Tento viminfo súbor bol vytvorený editorom Vim %s.\n"
+
+#, c-format
+msgid ""
+"# You may edit it if you're careful!\n"
+"\n"
+msgstr ""
+"# Pokia¾ budete opatrný, môžete ho upravova.\n"
+"\n"
+
+#, c-format
+msgid "# Value of 'encoding' when this file was written\n"
+msgstr "# Hodnota 'encoding' (kódovania) poèas zápisu tohoto súboru\n"
+
+msgid "Illegal starting char"
+msgstr "Neprípustný zaèiatoèný znak"
+
+msgid "Save As"
+msgstr "Uloži ako"
+
+msgid "Write partial file?"
+msgstr "Uloži neúplný súbor?"
+
+msgid "E140: Use ! to write partial buffer"
+msgstr "E140: Použite ! pre uloženie neúplného bufferu"
+
+msgid "Overwrite existing file \"%s\"?"
+msgstr "Prepísa existujúci súbor \"%s\"?"
+
+#, c-format
+msgid "Swap file \"%s\" exists, overwrite anyway?"
+msgstr "Odkladací súbor \"%s\" existuje, aj tak prepísa?"
+
+msgid "E768: Swap file exists: %s (:silent! overrides)"
+msgstr "E768: Odkladací súbor existuje: %s (použite :silent! pre prepísanie)"
+
+#, c-format
+msgid "E141: No file name for buffer %ld"
+msgstr "E141: Žiadny názov súboru pre buffer %ld"
+
+msgid "E142: File not written: Writing is disabled by 'write' option"
+msgstr "E142: Súbor nebol uložený: ukladanie je zakázané vo¾bou 'write'"
+
+msgid ""
+"'readonly' option is set for \"%s\".\n"
+"Do you wish to write anyway?"
+msgstr ""
+"Pre \"%s\" je nastavená vo¾ba 'readonly' (iba na èítanie).\n"
+"Prajete si aj tak uloži?"
+
+msgid "Edit File"
+msgstr "Upravova súbor"
+
+#, c-format
+msgid "E143: Autocommands unexpectedly deleted new buffer %s"
+msgstr "E143: Automatické príkazy neoèakávane zmazali nový buffer %s"
+
+msgid "E144: non-numeric argument to :z"
+msgstr "E144: neèíselný argument pre :z"
+
+msgid "E145: Shell commands not allowed in rvim"
+msgstr "E145: rvim nepovo¾uje použitie príkazov shellu"
+
+msgid "E146: Regular expressions can't be delimited by letters"
+msgstr "E146: Regulárne výrazy nesmú by oddelené písmenami"
+
+#, c-format
+msgid "replace with %s (y/n/a/q/l/^E/^Y)?"
+msgstr "nahradi %s (y/n/a/q/l/^E/^Y)?"
+
+msgid "(Interrupted) "
+msgstr "(prerušený) "
+
+msgid "1 match"
+msgstr "1 zhoda"
+
+msgid "1 substitution"
+msgstr "1 nahradenie"
+
+msgid "%ld matches"
+msgstr "%ld zhôd"
+
+#, c-format
+msgid "%ld substitutions"
+msgstr "%ld nahradení"
+
+msgid " on 1 line"
+msgstr " na 1 riadku"
+
+#, c-format
+msgid " on %ld lines"
+msgstr " na %ld riadkov"
+
+msgid "E147: Cannot do :global recursive"
+msgstr "E147: :global sa nedá vola rekurzívne"
+
+msgid "E148: Regular expression missing from global"
+msgstr "E148: Pri príkaze global chýba regulárny výraz"
+
+#, c-format
+msgid "Pattern found in every line: %s"
+msgstr "Vzor nájdený na každom riadku: %s"
+
+#, c-format
+msgid ""
+"\n"
+"# Last Substitute String:\n"
+"$"
+msgstr ""
+"\n"
+"# Posledný zamieòaný reazec:\n"
+"$"
+
+msgid "E478: Don't panic!"
+msgstr "E478: Žiadnu paniku!"
+
+msgid "E661: Sorry, no '%s' help for %s"
+msgstr "E661: ¼utujem, žiadny '%s' pomocník pre %s"
+
+#, c-format
+msgid "E149: Sorry, no help for %s"
+msgstr "E149: ¼utujem, pre %s nie je žiadny pomocník"
+
+#, c-format
+msgid "Sorry, help file \"%s\" not found"
+msgstr "¼utujem, súbor \"%s\" s pomocníkom nebol nájdený"
+
+#, c-format
+msgid "E150: Not a directory: %s"
+msgstr "E150: %s nie je adresárom"
+
+#, c-format
+msgid "E152: Cannot open %s for writing"
+msgstr "E152: %s sa nedá sa otvori pre zápis"
+
+#, c-format
+msgid "E153: Unable to open %s for reading"
+msgstr "E153: %s as nedá otvori pre èítanie"
+
+#, c-format
+msgid "E670: Mix of help file encodings within a language: %s"
+msgstr "E670: Rôzne kódovania pre súbory s pomocníkom pre jazyk: %s"
+
+msgid "E154: Duplicate tag \"%s\" in file %s/%s"
+msgstr "E154: Duplicitný tag \"%s\" v súbore %s/%s"
+
+#, c-format
+msgid "E160: Unknown sign command: %s"
+msgstr "E160: Neznámu príkaz pre znaèky: %s"
+
+msgid "E156: Missing sign name"
+msgstr "E156: Chýba meno pre znaèku"
+
+msgid "E612: Too many signs defined"
+msgstr "E612: Príliš mnoho definovaných znaèiek"
+
+#, c-format
+msgid "E239: Invalid sign text: %s"
+msgstr "E239: Chybný text znaèky: %s"
+
+#, c-format
+msgid "E155: Unknown sign: %s"
+msgstr "E155: Neznáma znaèka: %s"
+
+msgid "E159: Missing sign number"
+msgstr "E159: Chýba èislo znaèky"
+
+#, c-format
+msgid "E158: Invalid buffer name: %s"
+msgstr "E158: Chybné meno bufferu: %s"
+
+#, c-format
+msgid "E157: Invalid sign ID: %ld"
+msgstr "E157: Chybné ID znaèky: %ld"
+
+msgid " (NOT FOUND)"
+msgstr " (NENÁJDENÉ)"
+
+msgid " (not supported)"
+msgstr " (nepodporované)"
+
+msgid "[Deleted]"
+msgstr "[vymazaný]"
+
+msgid "Entering Debug mode. Type \"cont\" to continue."
+msgstr "Spúšam režim ladenia. Pre ukonèenie napíšte \"cont\"."
+
+#, c-format
+msgid "line %ld: %s"
+msgstr "riadok %ld: %s"
+
+#, c-format
+msgid "cmd: %s"
+msgstr "príkaz: %s"
+
+#, c-format
+msgid "Breakpoint in \"%s%s\" line %ld"
+msgstr "Bod prerušenia v \"%s%s\" na riadku %ld"
+
+#, c-format
+msgid "E161: Breakpoint not found: %s"
+msgstr "E161: Bod prerušenia nenájdený: %s"
+
+msgid "No breakpoints defined"
+msgstr "Neboli definovné žiadne body prerušenia"
+
+#, c-format
+msgid "%3d %s %s line %ld"
+msgstr "%3d %s %s riadok %ld"
+
+msgid "E750: First use :profile start <fname>"
+msgstr "E750: Najprv použite príkaz :profile start <meno_suboru>"
+
+msgid "Save changes to \"%s\"?"
+msgstr "Uloži zmeny do \"%s\"?"
+
+msgid "Untitled"
+msgstr "Bez mena"
+
+#, c-format
+msgid "E162: No write since last change for buffer \"%s\""
+msgstr "E162: Buffer \"%s\" obsahuje neuložené zmeny"
+
+msgid "Warning: Entered other buffer unexpectedly (check autocommands)"
+msgstr ""
+"Varovanie: Neèakaný vstup do iného bufferu (skontrolujte automatické príkazy)"
+
+msgid "E163: There is only one file to edit"
+msgstr "E163: Pre úpravu bol zadaný iba jeden súbor"
+
+msgid "E164: Cannot go before first file"
+msgstr "E164: Nedá sa preskoèi pred prvý súbor"
+
+msgid "E165: Cannot go beyond last file"
+msgstr "E165: Nedá sa preskoèi za posledný súbor"
+
+msgid "E666: compiler not supported: %s"
+msgstr "E666: prekladaè nie je podporovaný: %s"
+
+#, c-format
+msgid "Searching for \"%s\" in \"%s\""
+msgstr "H¾adám \"%s\" v \"%s\""
+
+#, c-format
+msgid "Searching for \"%s\""
+msgstr "H¾adám \"%s\""
+
+#, c-format
+msgid "not found in 'runtimepath': \"%s\""
+msgstr "súbor \"%s\" nebol nájdený v 'runtimepath'"
+
+msgid "Source Vim script"
+msgstr "Zdrojový skript Vim"
+
+#, c-format
+msgid "Cannot source a directory: \"%s\""
+msgstr "Nemožno interpretova adresár: \"%s\""
+
+#, c-format
+msgid "could not source \"%s\""
+msgstr "nedá sa interpretova \"%s\""
+
+#, c-format
+msgid "line %ld: could not source \"%s\""
+msgstr "riadok %ld: nemôžno interpretova \"%s\""
+
+#, c-format
+msgid "sourcing \"%s\""
+msgstr "interpretujem \"%s\""
+
+#, c-format
+msgid "line %ld: sourcing \"%s\""
+msgstr "riadok %ld: interpretujem \"%s\""
+
+#, c-format
+msgid "finished sourcing %s"
+msgstr "dokonèená interpretácia %s"
+
+msgid "W15: Warning: Wrong line separator, ^M may be missing"
+msgstr "W15: Varovanie: chybný odde¾ovaè riadkov. Možno chýba ^M"
+
+msgid "E167: :scriptencoding used outside of a sourced file"
+msgstr "E167: príkaz :scriptencoding použitý mimo interpretovaný súbor"
+
+msgid "E168: :finish used outside of a sourced file"
+msgstr "E168: príkaz :finish použitý mimo interpretovaný súbor"
+
+#, c-format
+msgid "Current %slanguage: \"%s\""
+msgstr "Aktuálny %sjazyk: \"%s\""
+
+#, c-format
+msgid "E197: Cannot set language to \"%s\""
+msgstr "E197: Nedá sa nastavi jazyk na \"%s\""
+
+msgid "Entering Ex mode. Type \"visual\" to go to Normal mode."
+msgstr "Spúšam Ex režim. Napíšte \"visual\" pre návrat do Normálneho režimu."
+
+msgid "E501: At end-of-file"
+msgstr "E501: Koniec súboru"
+
+msgid "E169: Command too recursive"
+msgstr "E169: Príkaz je príliš rekurzívny"
+
+msgid "E605: Exception not caught: %s"
+msgstr "E605: Výnimka nezachytená: %s"
+
+msgid "End of sourced file"
+msgstr "Koniec interpretovaného súboru"
+
+msgid "End of function"
+msgstr "Koniec funkcie"
+
+msgid "E464: Ambiguous use of user-defined command"
+msgstr "E464: Nejednoznaèné použitie používate¾om definovaného príkazu"
+
+msgid "E492: Not an editor command"
+msgstr "E492: Nie je príkazom editoru"
+
+msgid "E493: Backwards range given"
+msgstr "E493: Zadaný spätný rozsah"
+
+msgid "Backwards range given, OK to swap"
+msgstr "Zadaný spätný rozsah. OK pre zámenu"
+
+msgid "E494: Use w or w>>"
+msgstr "E494: Použite w alebo w>>"
+
+msgid "E319: Sorry, the command is not available in this version"
+msgstr "E319: ¼utujem, ale tento príkaz nie je dostupný v tejto verzii"
+
+msgid "E172: Only one file name allowed"
+msgstr "E172: Prípustný je iba jeden názov súboru"
+
+msgid "1 more file to edit. Quit anyway?"
+msgstr "Ešte zostáva 1 súbor k úprave. Chcete napriek tomu ukonèi editor?"
+
+#, c-format
+msgid "%d more files to edit. Quit anyway?"
+msgstr "Ešte zostáva %d súborov k úprave. Chcete napriek tomu ukonèi editor?"
+
+msgid "E173: 1 more file to edit"
+msgstr "E173: Ešte zostáva 1 súbor k úprave."
+
+#, c-format
+msgid "E173: %ld more files to edit"
+msgstr "E173: Ešte zostáva %ld súborov k úprave."
+
+msgid "E174: Command already exists: add ! to replace it"
+msgstr "E174: Príkaz už existuje: použite ! pre predefinovanie"
+
+msgid ""
+"\n"
+" Name Args Range Complete Definition"
+msgstr ""
+"\n"
+" Meno Args Rozsah Úplnos Definícia"
+
+msgid "No user-defined commands found"
+msgstr "Neboli nájdené žiadne použivate¾om definované príkazy"
+
+msgid "E175: No attribute specified"
+msgstr "E175: Neboli zadané žiadne vlastnosti"
+
+msgid "E176: Invalid number of arguments"
+msgstr "E176: Chybný poèet argumentov"
+
+msgid "E177: Count cannot be specified twice"
+msgstr "E177: Poèet nemôže by zadaný dvakrát"
+
+msgid "E178: Invalid default value for count"
+msgstr "E178: Chybná implicitná hodnota pre poèet"
+
+msgid "E179: argument required for -complete"
+msgstr "E179: pre doplnenie (-complete) je potrebný argument"
+
+#, c-format
+msgid "E181: Invalid attribute: %s"
+msgstr "E181: Chybná vlastnos: %s"
+
+msgid "E182: Invalid command name"
+msgstr "E182: Chybné meno príkazu"
+
+msgid "E183: User defined commands must start with an uppercase letter"
+msgstr "E183: Používate¾om definované príkazy musia zaèína ve¾kým písmenom"
+
+#, c-format
+msgid "E184: No such user-defined command: %s"
+msgstr "E184: Používate¾om definovaný príkaz %s neexistuje"
+
+#, c-format
+msgid "E180: Invalid complete value: %s"
+msgstr "E180: Chybná hodnota doplnenia: %s"
+
+msgid "E468: Completion argument only allowed for custom completion"
+msgstr "E468: Argument doplnenia je povolený iba pre vlastné dopåòania (completion)"
+
+msgid "E467: Custom completion requires a function argument"
+msgstr "E467: Vlastné doplnenia vyžadujú meno funkcie ako argument"
+
+#, c-format
+msgid "E185: Cannot find color scheme %s"
+msgstr "E185: Schéma farieb %s nenájdená"
+
+msgid "Greetings, Vim user!"
+msgstr "Pozdravujem, užívate¾ Vimu!"
+
+msgid "Edit File in new window"
+msgstr "Upravi súbor v novom okne"
+
+msgid "No swap file"
+msgstr "Žiadny odkladací súbor"
+
+msgid "Append File"
+msgstr "Pripoji súbor"
+
+msgid "E747: Cannot change directory, buffer is modified (add ! to override)"
+msgstr "E747: Nemožno zmeni adresár, buffer je modifikovaný (použite ! pre vynútenie)"
+
+msgid "E186: No previous directory"
+msgstr "E186: Žiadny predchádzajúci adresár"
+
+msgid "E187: Unknown"
+msgstr "E187: Neznámy"
+
+msgid "E465: :winsize requires two number arguments"
+msgstr "E465: :winsize (ve¾kos okna) vyžaduje dva argumenty"
+
+#, c-format
+msgid "Window position: X %d, Y %d"
+msgstr "Pozícia okna: X %d, Y %d"
+
+msgid "E188: Obtaining window position not implemented for this platform"
+msgstr "E188: Na tejto platforme sa nedá zisti umiestnenie okna"
+
+msgid "E466: :winpos requires two number arguments"
+msgstr "E466: :winpos (pozícia okna) vyžaduje dva argumenty"
+
+msgid "Save Redirection"
+msgstr "Uloži presmerovanie"
+
+msgid "Save View"
+msgstr "Uloži poh¾ad"
+
+msgid "Save Session"
+msgstr "Uloži sedenie"
+
+msgid "Save Setup"
+msgstr "Uloži nastavenie"
+
+msgid "E739: Cannot create directory: %s"
+msgstr "E739: Nemožno vytvori adresár: %s"
+
+msgid "E189: \"%s\" exists (add ! to override)"
+msgstr "E189: \"%s\" existuje (použite ! pre vynútenie)"
+
+#, c-format
+msgid "E190: Cannot open \"%s\" for writing"
+msgstr "E190: \"%s\" sa nedá otvori pre zápis"
+
+#. set mark
+msgid "E191: Argument must be a letter or forward/backward quote"
+msgstr "E191: Argumentem môže by iba písmeno alebo pravý èi ¾avý apostrof"
+
+msgid "E192: Recursive use of :normal too deep"
+msgstr "E192: Rekurzívne použitie príkazu :normal príliš hlboké"
+
+msgid "E194: No alternate file name to substitute for '#'"
+msgstr ""
+"E194: Žiadny alternatívny názov súboru, ktorým by bolo možné nahradi '#'"
+
+msgid "E495: no autocommand file name to substitute for \"<afile>\""
+msgstr "E495: žiadny názov súboru, ktorým by bolo možné nahradi \"<afile>\""
+
+msgid "E496: no autocommand buffer number to substitute for \"<abuf>\""
+msgstr "E496: žiadne èíslo bufferu, ktorým by bolo možné nahradi \"<abuf>\""
+
+msgid "E497: no autocommand match name to substitute for \"<amatch>\""
+msgstr ""
+"E497: žiadna zhoda automatických príkazov, ktorou by bolo možné nahradi \"<amatch>"
+"\""
+
+msgid "E498: no :source file name to substitute for \"<sfile>\""
+msgstr "E498: žiadny :source súbor, ktorým by bolo možné nahradi \"<sfile>\""
+
+msgid "E499: Empty file name for '%' or '#', only works with \":p:h\""
+msgstr "E499: Prázdný názov súboru pre '%' alebo '#', funguje iba s \":p:h\""
+
+msgid "E500: Evaluates to an empty string"
+msgstr "E500: Výsledkom vyhodnotenia je prázdny reazec"
+
+msgid "E195: Cannot open viminfo file for reading"
+msgstr "E195: Súbor viminfo sa nedá sa otvori na èítanie"
+
+msgid "E196: No digraphs in this version"
+msgstr "E196: V tejto verzi nie sú digraphy podporované"
+
+msgid "E608: Cannot :throw exceptions with 'Vim' prefix"
+msgstr "E608: Nemožno spracova výnimku :throw s preponou 'Vim'"
+
+#. always scroll up, don't overwrite
+#, c-format
+msgid "Exception thrown: %s"
+msgstr "Spracovanie výnimky: %s"
+
+#, c-format
+msgid "Exception finished: %s"
+msgstr "Výnimka ukonèená: %s"
+
+#, c-format
+msgid "Exception discarded: %s"
+msgstr "Výnimka zahodená: %s"
+
+msgid "%s, line %ld"
+msgstr "%s, riadok %ld"
+
+#. always scroll up, don't overwrite
+msgid "Exception caught: %s"
+msgstr "Zachytená výnimka: %s"
+
+#, c-format
+msgid "%s made pending"
+msgstr "%s prebieha"
+
+msgid "%s resumed"
+msgstr "%s vrátené"
+
+#, c-format
+msgid "%s discarded"
+msgstr "%s zahodené"
+
+msgid "Exception"
+msgstr "Výnimka"
+
+msgid "Error and interrupt"
+msgstr "Chyba a prerušené"
+
+msgid "Error"
+msgstr "Chyba"
+
+#. if (pending & CSTP_INTERRUPT)
+msgid "Interrupt"
+msgstr "Prerušené"
+
+msgid "E579: :if nesting too deep"
+msgstr "E579: vnorenie :if je príliš hlboké"
+
+msgid "E580: :endif without :if"
+msgstr "E580: :endif bez zodpovedajúceho :if"
+
+msgid "E581: :else without :if"
+msgstr "E581: :else bez zodpovedajúceho :if"
+
+msgid "E582: :elseif without :if"
+msgstr "E582: :elseif bez zodpovedajúceho :if"
+
+msgid "E583: multiple :else"
+msgstr "E583: viacnásobné :else"
+
+msgid "E584: :elseif after :else"
+msgstr "E584: :elseif nasleduje po :else"
+
+msgid "E585: :while/:for nesting too deep"
+msgstr "E585: vnorenie :while/:for je príliš hlboké"
+
+msgid "E586: :continue without :while or :for"
+msgstr "E586: :continue bez zodpovedajúceho :while alebo :for"
+
+msgid "E587: :break without :while or :for"
+msgstr "E587: :break bez zodpovedajúceho :while alebo :for"
+
+msgid "E732: Using :endfor with :while"
+msgstr "E732: Použité :endfor spolu s :while"
+
+msgid "E733: Using :endwhile with :for"
+msgstr "E733: Použité :endwhile spolu s :for"
+
+msgid "E601: :try nesting too deep"
+msgstr "E601: vnorenie :try je príliš hlboké"
+
+msgid "E603: :catch without :try"
+msgstr "E603: :catch bez :try"
+
+#. Give up for a ":catch" after ":finally" and ignore it.
+#. * Just parse.
+msgid "E604: :catch after :finally"
+msgstr "E604: :catch nasleduje po :finally"
+
+msgid "E606: :finally without :try"
+msgstr "E606: :finally bez :try"
+
+#. Give up for a multiple ":finally" and ignore it.
+msgid "E607: multiple :finally"
+msgstr "E607: viacnásobné použité :finally"
+
+msgid "E602: :endtry without :try"
+msgstr "E602: :endtry bez :try"
+
+msgid "E193: :endfunction not inside a function"
+msgstr "E193: :endfunction mimo funkciu"
+
+msgid "tagname"
+msgstr "meno tagu"
+
+msgid " kind file\n"
+msgstr " typ súboru\n"
+
+msgid "'history' option is zero"
+msgstr "'vo¾ba 'history' je nastavená na nulu"
+
+#, c-format
+msgid ""
+"\n"
+"# %s History (newest to oldest):\n"
+msgstr ""
+"\n"
+"# História %s (zaèínajúci najnovšou položkou):\n"
+
+msgid "Command Line"
+msgstr "Príkazový riadok"
+
+msgid "Search String"
+msgstr "Vyh¾adávaný reazec"
+
+msgid "Expression"
+msgstr "Výraz"
+
+msgid "Input Line"
+msgstr "Vstupný riadok"
+
+msgid "E198: cmd_pchar beyond the command length"
+msgstr "E198: cmd_pchar prevyšuje dåžku príkazu"
+
+msgid "E199: Active window or buffer deleted"
+msgstr "E199: Aktívne okno alebo buffer bol vymazaný"
+
+msgid "Illegal file name"
+msgstr "Neprípustný názov súboru"
+
+msgid "is a directory"
+msgstr "je adresárom"
+
+msgid "is not a file"
+msgstr "nie je súborom"
+
+msgid "[New File]"
+msgstr "[nový súbor]"
+
+msgid "[Permission Denied]"
+msgstr "[prístup odmietnutý]"
+
+msgid "E200: *ReadPre autocommands made the file unreadable"
+msgstr "E200: automatické príkazy *ReadPre urobili súbor neèitate¾ným"
+
+msgid "E201: *ReadPre autocommands must not change current buffer"
+msgstr "E201: automatické príkazy *ReadPre nesmú meni aktuálny buffer"
+
+msgid "Vim: Reading from stdin...\n"
+msgstr "Vim: èítam zo štandardného vstupu...\n"
+
+msgid "Reading from stdin..."
+msgstr "Èítam zo štandardného vstupu..."
+
+#. Re-opening the original file failed!
+msgid "E202: Conversion made file unreadable!"
+msgstr "E202: Po konverzii je súbor neèitate¾ný!"
+
+msgid "[fifo/socket]"
+msgstr "[pomenovaná rúra/soket]"
+
+msgid "[fifo]"
+msgstr "[pomenovaná rúra]"
+
+msgid "[socket]"
+msgstr "[soket]"
+
+msgid "[RO]"
+msgstr "[RO]"
+
+msgid "[CR missing]"
+msgstr "[chýba CR]"
+
+msgid "[NL found]"
+msgstr "[nájdené NL]"
+
+msgid "[long lines split]"
+msgstr "[dlhé riadky zalomené]"
+
+msgid "[NOT converted]"
+msgstr "[neskonvertovaný]"
+
+msgid "[converted]"
+msgstr "[skonvertovaný]"
+
+msgid "[crypted]"
+msgstr "[šifrovaný]"
+
+msgid "[CONVERSION ERROR]"
+msgstr "[CHYBA PREVODU]"
+
+#, c-format
+msgid "[ILLEGAL BYTE in line %ld]"
+msgstr "[NEPRÍPUSTNÝ BAJT na riadku %ld]"
+
+msgid "[READ ERRORS]"
+msgstr "[CHYBY ÈÍTANIA]"
+
+msgid "Can't find temp file for conversion"
+msgstr "Nedá sa nájs doèasný súbor pre konverziu"
+
+msgid "Conversion with 'charconvert' failed"
+msgstr "Konverzia s 'charconvert' sa nepodarila"
+
+msgid "can't read output of 'charconvert'"
+msgstr "nedá sa èíta výstup 'charconvert'"
+
+msgid "E676: No matching autocommands for acwrite buffer"
+msgstr "E676: Žiadne vyhovujúce automatické príkazy pre acwrite buffer "
+
+msgid "E203: Autocommands deleted or unloaded buffer to be written"
+msgstr ""
+"E203: Automatické príkazy zmazali èi deaktivovali buffer, ktorý mal by "
+"uložený"
+
+msgid "E204: Autocommand changed number of lines in unexpected way"
+msgstr "E204: Automatický príkaz neoèakávaným spôsobom zmenil poèet riadkov"
+
+msgid "NetBeans disallows writes of unmodified buffers"
+msgstr "NetBeans rozhranie nedovolilo zapísa nemodifikované buffre"
+
+msgid "Partial writes disallowed for NetBeans buffers"
+msgstr "Èiastoèné zápisy nie sú povolené pre NetBeans buffre"
+
+msgid "is not a file or writable device"
+msgstr "nie je súborom ani zapisovatelným zariadením"
+
+msgid "is read-only (add ! to override)"
+msgstr "je iba pre èítanie (použite ! pre vynútenie)"
+
+msgid "E506: Can't write to backup file (add ! to override)"
+msgstr "E506: Nedá sa zapisova do záložného súboru (použite ! pre vynútenie)"
+
+msgid "E507: Close error for backup file (add ! to override)"
+msgstr "E507: Chyba pri uzatváraní záložného súboru (použite ! pre vynútenie)"
+
+msgid "E508: Can't read file for backup (add ! to override)"
+msgstr "E508: Nedá sa naèíta súbor pre zálohu (použite ! pre vynútenie)"
+
+msgid "E509: Cannot create backup file (add ! to override)"
+msgstr "E509: Nedá sa vytvori záložný súbor (použite ! pre vynútenie)"
+
+msgid "E510: Can't make backup file (add ! to override)"
+msgstr "E510: Nedá sa vytvori záložný súbor (použite ! pre vynútenie)"
+
+# TODO: resource fork ?! Note: used only in MACOS_X version
+msgid "E460: The resource fork would be lost (add ! to override)"
+msgstr "E460: 'Resource fork' bude stratený (použite ! pre vynútenie)"
+
+msgid "E214: Can't find temp file for writing"
+msgstr "E214: Nedá sa nájs doèasný súbor pre ukladanie"
+
+msgid "E213: Cannot convert (add ! to write without conversion)"
+msgstr "E213: Nedá sa spravi konverzia (použite ! pre zápis bez konverzie)"
+
+msgid "E166: Can't open linked file for writing"
+msgstr "E166: Súbor sa nedá otvori pre ukladanie"
+
+msgid "E212: Can't open file for writing"
+msgstr "E212: Súbor sa nedá otvori pre ukladanie"
+
+msgid "E667: Fsync failed"
+msgstr "E667: Fsync zlyhal"
+
+msgid "E512: Close failed"
+msgstr "E512: Zatvorenie zlyhalo"
+
+msgid "E513: write error, conversion failed (make 'fenc' empty to override)"
+msgstr "E513: chyba pri zápise, konverzia sa nepodarila (nastavte vo¾bu 'fenc' na prázdnu pre vynútenie)"
+
+msgid "E514: write error (file system full?)"
+msgstr "E514: chyba pri ukladaní (plný disk?)"
+
+msgid " CONVERSION ERROR"
+msgstr " CHYBA PREVODU"
+
+msgid "[Device]"
+msgstr "[zariadenie]"
+
+msgid "[New]"
+msgstr "[nový]"
+
+msgid " [a]"
+msgstr " [p]"
+
+msgid " appended"
+msgstr " pripojený"
+
+msgid " [w]"
+msgstr " [u]"
+
+msgid " written"
+msgstr " uložený"
+
+msgid "E205: Patchmode: can't save original file"
+msgstr "E205: patchmode: nedá sa uloži pôvodný súbor"
+
+msgid "E206: patchmode: can't touch empty original file"
+msgstr "E206: patchmode: nedá sa zapisova do prázdneho pôvodného súboru"
+
+msgid "E207: Can't delete backup file"
+msgstr "E207: Nedá sa vymaza záložný súbor"
+
+msgid ""
+"\n"
+"WARNING: Original file may be lost or damaged\n"
+msgstr ""
+"\n"
+"VAROVANIE: Obsah pôvodného súboru môže by stratený alebo poškodený\n"
+
+msgid "don't quit the editor until the file is successfully written!"
+msgstr "neukonèujte editor skôr, než bude súbor úspešne uložený!"
+
+msgid "[dos]"
+msgstr "[dos]"
+
+msgid "[dos format]"
+msgstr "[dos formát]"
+
+msgid "[mac]"
+msgstr "[mac]"
+
+msgid "[mac format]"
+msgstr "[mac formát]"
+
+msgid "[unix]"
+msgstr "[unix]"
+
+msgid "[unix format]"
+msgstr "[unix formát]"
+
+msgid "1 line, "
+msgstr "1 riadok, "
+
+#, c-format
+msgid "%ld lines, "
+msgstr "%ld riadkov, "
+
+msgid "1 character"
+msgstr "1 znak"
+
+#, c-format
+msgid "%ld characters"
+msgstr "%ld znakov"
+
+msgid "[noeol]"
+msgstr "[bez znaku konca riadku]"
+
+msgid "[Incomplete last line]"
+msgstr "[neúplný posledný riadok]"
+
+#. 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 "VAROVANIE: Súbor bol zmenený od jeho naèítania!!!"
+
+msgid "Do you really want to write to it"
+msgstr "Chcete ho naozaj uloži"
+
+#, c-format
+msgid "E208: Error writing to \"%s\""
+msgstr "E208: Chyba pri zápise do \"%s\""
+
+#, c-format
+msgid "E209: Error closing \"%s\""
+msgstr "E209: Chyba pri uzatváraní \"%s\""
+
+#, c-format
+msgid "E210: Error reading \"%s\""
+msgstr "E210: Chyba pri èítaní \"%s\""
+
+msgid "E246: FileChangedShell autocommand deleted buffer"
+msgstr "E246: automatický príkaz FileChangedShell vymazal buffer"
+
+msgid "E211: File \"%s\" no longer available"
+msgstr "E211: Varovanie: súbor \"%s\" už nie je dostupný"
+
+#, c-format
+msgid ""
+"W12: Warning: File \"%s\" has changed and the buffer was changed in Vim as "
+"well"
+msgstr ""
+"W12: Varovanie: súbor \"%s\" bol po zaèatí úpravy zmenený a buffer sa tiež "
+"zmenil "
+
+msgid "See \":help W12\" for more info."
+msgstr "Pozrite \":help W12\" pre viac informácií."
+
+#, c-format
+msgid "W11: Warning: File \"%s\" has changed since editing started"
+msgstr "W11: Varovanie: súbor \"%s\" bol po zaèatí úpravy zmenený"
+
+msgid "See \":help W11\" for more info."
+msgstr "Pozrite \":help W11\" pre viac informácií."
+
+#, c-format
+msgid "W16: Warning: Mode of file \"%s\" has changed since editing started"
+msgstr ""
+"W16: Varovanie: Prístupové práva k súboru \"%s\" boli po zaèatí úprav zmenené"
+
+msgid "See \":help W16\" for more info."
+msgstr "Pozrite \":help W16\" pre viac informácií."
+
+#, c-format
+msgid "W13: Warning: File \"%s\" has been created after editing started"
+msgstr "W13: Varovanie: Súbor \"%s\" bol vytvorený po zaèatí úpravy"
+
+msgid "Warning"
+msgstr "Varovanie"
+
+msgid ""
+"&OK\n"
+"&Load File"
+msgstr ""
+"&OK\n"
+"&Naèíta súbor"
+
+msgid "E462: Could not prepare for reloading \"%s\""
+msgstr "E462: Nemožno pripravi na opätovné naèítanie \"%s\""
+
+#, c-format
+msgid "E321: Could not reload \"%s\""
+msgstr "E321: nedá sa obnovi \"%s\""
+
+msgid "--Deleted--"
+msgstr "--Vymazaný--"
+
+#, c-format
+msgid "auto-removing autocommand: %s <buffer=%d>"
+msgstr "samomazací automatický príkaz: %s <buffer=%d>"
+
+#. the group doesn't exist
+#, c-format
+msgid "E367: No such group: \"%s\""
+msgstr "E367: Skupina \"%s\" neexistuje"
+
+#, c-format
+msgid "E215: Illegal character after *: %s"
+msgstr "E215: Neprípustný znak po *: %s"
+
+#, c-format
+msgid "E216: No such event: %s"
+msgstr "E216: Udalos %s neexistuje"
+
+msgid "E216: No such group or event: %s"
+msgstr "E216: Udalos alebo skupina %s neexistuje"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Auto-Commands ---"
+msgstr ""
+"\n"
+"--- Automatické príkazy ---"
+
+msgid "E680: <buffer=%d>: invalid buffer number "
+msgstr "E680: <buffer=%d>: chybné èíslo bufferu"
+
+msgid "E217: Can't execute autocommands for ALL events"
+msgstr "E217: Automatické príkazy sa nedajú spusti pre VŠETKY udalosti"
+
+msgid "No matching autocommands"
+msgstr "Žiadne vyhovujúce automatické príkazy"
+
+msgid "E218: autocommand nesting too deep"
+msgstr "E218: vnorenia automatického príkazu sú príliš hlboké"
+
+#, c-format
+msgid "%s Auto commands for \"%s\""
+msgstr "%s Automatické príkazy pre \"%s\""
+
+#, c-format
+msgid "Executing %s"
+msgstr "Spúšam %s"
+
+#, c-format
+msgid "autocommand %s"
+msgstr "automatický príkaz %s"
+
+msgid "E219: Missing {."
+msgstr "E219: Chýba {."
+
+msgid "E220: Missing }."
+msgstr "E220: Chýba }."
+
+msgid "E490: No fold found"
+msgstr "E490: Nebol nájdené žiadne vnorenie"
+
+msgid "E350: Cannot create fold with current 'foldmethod'"
+msgstr "E350: Nedá sa vytvori vnorenie s aktuálnou metódou 'foldmethod'"
+
+msgid "E351: Cannot delete fold with current 'foldmethod'"
+msgstr "E351: Nedá sa zruši vnorenie s aktuálnou metódou 'foldmethod'"
+
+#, c-format
+msgid "+--%3ld lines folded "
+msgstr "+--%3ld riadkov zahnutých "
+
+msgid "E222: Add to read buffer"
+msgstr "E222: Prida do bufferu pre èítanie"
+
+msgid "E223: recursive mapping"
+msgstr "E223: rekurzívne mapovanie"
+
+#, c-format
+msgid "E224: global abbreviation already exists for %s"
+msgstr "E224: pre %s už globálna skratka existuje"
+
+#, c-format
+msgid "E225: global mapping already exists for %s"
+msgstr "E225: pre %s už globálne mapovanie existuje"
+
+#, c-format
+msgid "E226: abbreviation already exists for %s"
+msgstr "E226: pre %s už skratka existuje"
+
+#, c-format
+msgid "E227: mapping already exists for %s"
+msgstr "E227: pre %s už mapovanie existuje"
+
+msgid "No abbreviation found"
+msgstr "Žiadna skratka nebola nájdená"
+
+msgid "No mapping found"
+msgstr "Žiadne mapovanie nebolo nájdené"
+
+msgid "E228: makemap: Illegal mode"
+msgstr "E228: makemap: neprípustný mód"
+
+msgid "E229: Cannot start the GUI"
+msgstr "E229: Nedá sa spusti GUI (grafické rozhranie)"
+
+#, c-format
+msgid "E230: Cannot read from \"%s\""
+msgstr "E230: Nedá sa èíta z \"%s\""
+
+msgid "E665: Cannot start GUI, no valid font found"
+msgstr "E665: Nemožno naštartova grafické rozhranie, nenájdený žiaden použitelný font"
+
+msgid "E231: 'guifontwide' invalid"
+msgstr ""
+"E231: vo¾ba 'guifontwide' (nastavenie širokého písma) je chybne nastavená"
+
+msgid "E599: Value of 'imactivatekey' is invalid"
+msgstr "E599: Hodnota 'imactivatekey' je nesprávne nastavená"
+
+#, c-format
+msgid "E254: Cannot allocate color %s"
+msgstr "E254: Nedá sa alokova farba %s"
+
+msgid "No match at cursor, finding next"
+msgstr "Žiadna zhoda na pozícii kurzora, h¾adám ïalej"
+
+msgid "<cannot open> "
+msgstr "<nedá sa otvori> "
+
+msgid "E616: vim_SelFile: can't get font %s"
+msgstr "E616: vim_SelFile: písmo %s nie je dostupné"
+
+msgid "E614: vim_SelFile: can't return to current directory"
+msgstr "E614: vim_SelFile: nedá sa vráti do aktuálneho adresára"
+
+msgid "Pathname:"
+msgstr "Názov cesty:"
+
+msgid "E615: vim_SelFile: can't get current directory"
+msgstr "E615: vim_SelFile: nedá sa zisti aktuálny adresár"
+
+msgid "OK"
+msgstr "OK"
+
+msgid "Cancel"
+msgstr "Zruši"
+
+msgid "Scrollbar Widget: Could not get geometry of thumb pixmap."
+msgstr "Prípravok posuvnej lišty: nedá sa zisti geometria náh¾adu obrázku."
+
+msgid "Vim dialog"
+msgstr "Vim dialóg"
+
+msgid "E232: Cannot create BalloonEval with both message and callback"
+msgstr "E232: BalloonEval nedá sa vytvori správou a zároveò spätným volaním"
+
+msgid "Vim dialog..."
+msgstr "Vim dialóg.."
+
+# TODO: Translate as "&Ano\n&Nie\n&Zruši" ?
+msgid ""
+"&Yes\n"
+"&No\n"
+"&Cancel"
+msgstr ""
+"&Ano\n"
+"&Nie\n"
+"&Zruši"
+
+msgid "Input _Methods"
+msgstr "Vstupné metódy (_Methods)"
+
+msgid "VIM - Search and Replace..."
+msgstr "VIM - Nájs a nahradi..."
+
+msgid "VIM - Search..."
+msgstr "VIM - Nájs..."
+
+msgid "Find what:"
+msgstr "Vyh¾ada:"
+
+msgid "Replace with:"
+msgstr "Nahradi s:"
+
+#. whole word only button
+msgid "Match whole word only"
+msgstr "H¾ada len celé slová"
+
+#. match case button
+msgid "Match case"
+msgstr "Zhoda ve¾kosti písmen"
+
+msgid "Direction"
+msgstr "Smer"
+
+#. 'Up' and 'Down' buttons
+msgid "Up"
+msgstr "Hore"
+
+msgid "Down"
+msgstr "Dolu"
+
+msgid "Find Next"
+msgstr "Nájs ïalšie"
+
+msgid "Replace"
+msgstr "Nahradi"
+
+msgid "Replace All"
+msgstr "Nahradi Všetko"
+
+msgid "Vim: Received \"die\" request from session manager\n"
+msgstr "Vim: Prijatá požiadavka na ukonèenie (die) od manažéra sedení\n"
+
+msgid "Vim: Main window unexpectedly destroyed\n"
+msgstr "Vim: Hlavné okno neoèakávane zrušené\n"
+
+msgid "Font Selection"
+msgstr "Výber Písma"
+
+msgid "Used CUT_BUFFER0 instead of empty selection"
+msgstr "Použitý CUT_BUFFER0 namiesto prázdneho výberu"
+
+msgid "&Filter"
+msgstr "&Filter"
+
+msgid "&Cancel"
+msgstr "&Zruši"
+
+msgid "Directories"
+msgstr "Adresáre"
+
+msgid "Filter"
+msgstr "Filter"
+
+msgid "&Help"
+msgstr "&Pomocník"
+
+msgid "Files"
+msgstr "Súbory"
+
+msgid "&OK"
+msgstr "&OK"
+
+msgid "Selection"
+msgstr "Výber"
+
+msgid "Find &Next"
+msgstr "Nájs ïa&lšie"
+
+msgid "&Replace"
+msgstr "&Nahradi"
+
+msgid "Replace &All"
+msgstr "Nahradi &Všetko"
+
+msgid "&Undo"
+msgstr "&Spä"
+
+msgid "E671: Cannot find window title \"%s\""
+msgstr "E671: Nemožno nájs okno s titulkom \"%s\""
+
+#, c-format
+msgid "E243: Argument not supported: \"-%s\"; Use the OLE version."
+msgstr "E243: Argument nie je podporovaný: \"-%s\"; Použite OLE verziu."
+
+msgid "E672: Unable to open window inside MDI application"
+msgstr "E672: Nemožno otvori okno vnútri MDI aplikácie"
+
+msgid "Find string (use '\\\\' to find a '\\')"
+msgstr "Nájs reazec (použite '\\\\' ak chete nájs '\\')"
+
+# Following warning can be ignored:
+# msgfmt -v --statistics --check -C --check-accelerators="&" -o sk.mo sk.po
+# sk.po:2497: msgstr lacks the keyboard accelerator mark '&'
+msgid "Find & Replace (use '\\\\' to find a '\\')"
+msgstr "Nájs a Nahradi (použite '\\\\' ak chcete nájs '\\')"
+
+#. 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 "[neupravovaný]"
+
+msgid "Directory\t*.nothing\n"
+msgstr "Adresár\t*.niè\n"
+
+msgid "Vim E458: Cannot allocate colormap entry, some colors may be incorrect"
+msgstr ""
+"Vim E458: Nedá sa alokova položka mapy farieb, niektoré farby môžu by "
+"nesprávne"
+
+#, c-format
+msgid "E250: Fonts for the following charsets are missing in fontset %s:"
+msgstr "E250: Chýba písmo pre nasledujúce znakové sady %s:"
+
+#, c-format
+msgid "E252: Fontset name: %s"
+msgstr "E252: Názov sady písiem: %s"
+
+#, c-format
+msgid "Font '%s' is not fixed-width"
+msgstr "Písmo '%s' nemá pevnou šírku"
+
+#, c-format
+msgid "E253: Fontset name: %s\n"
+msgstr "E253: Názov sady písiem: %s\n"
+
+#, c-format
+msgid "Font0: %s\n"
+msgstr "Písmo0: %s\n"
+
+#, c-format
+msgid "Font1: %s\n"
+msgstr "Písmo1: %s\n"
+
+msgid "Font%ld width is not twice that of font0\n"
+msgstr "Písmo%ld nie je dvakrát širšie ako písmo0\n"
+
+#, c-format
+msgid "Font0 width: %ld\n"
+msgstr "Šírka písma0: %ld\n"
+
+#, c-format
+msgid ""
+"Font1 width: %ld\n"
+"\n"
+msgstr ""
+"Šírka písma1: %ld\n"
+"\n"
+
+msgid "Invalid font specification"
+msgstr "Chybná špecifikácia písma"
+
+msgid "&Dismiss"
+msgstr "&Zruši"
+
+msgid "no specific match"
+msgstr "žiadna špecifická zhoda"
+
+msgid "Vim - Font Selector"
+msgstr "Vim - Výber písma"
+
+msgid "Name:"
+msgstr "Meno:"
+
+#. create toggle button
+msgid "Show size in Points"
+msgstr "Ukazuj ve¾kos v bodoch"
+
+msgid "Encoding:"
+msgstr "Kódujem:"
+
+msgid "Font:"
+msgstr "Písmo:"
+
+msgid "Style:"
+msgstr "Štýl"
+
+msgid "Size:"
+msgstr "Ve¾kos:"
+
+msgid "E256: Hangul automata ERROR"
+msgstr "E256: Hangul ERROR - chyba kórejského spôsobu vkladania znakov"
+
+msgid "E550: Missing colon"
+msgstr "E550: Chýba dvojbodka"
+
+msgid "E551: Illegal component"
+msgstr "E551: Neprípustný komponent"
+
+msgid "E552: digit expected"
+msgstr "E552: oèakávaná èíslica"
+
+#, c-format
+msgid "Page %d"
+msgstr "Strana %d"
+
+msgid "No text to be printed"
+msgstr "Žiadny text na tlaè"
+
+#, c-format
+msgid "Printing page %d (%d%%)"
+msgstr "Tlaèím stranu %d (%d%%)"
+
+#, c-format
+msgid " Copy %d of %d"
+msgstr " Kópia %d z %d"
+
+#, c-format
+msgid "Printed: %s"
+msgstr "Vytlaèené: %s"
+
+msgid "Printing aborted"
+msgstr "Tlaè bola zrušená"
+
+msgid "E455: Error writing to PostScript output file"
+msgstr "E455: Nedá sa zapisova do výstupného PostScriptového súboru"
+
+msgid "E624: Can't open file \"%s\""
+msgstr "E624: Nedá sa otvori súbor \"%s\""
+
+#, c-format
+msgid "E457: Can't read PostScript resource file \"%s\""
+msgstr "E457: Nedá sa èíta PostScriptový súbor \"%s\""
+
+msgid "E618: file \"%s\" is not a PostScript resource file"
+msgstr "E618: súbor \"%s\" nie je vo formáte PostScript"
+
+msgid "E619: file \"%s\" is not a supported PostScript resource file"
+msgstr "E619: súbor \"%s\" nie je podporvaný PostScriptový súbor"
+
+#, c-format
+msgid "E621: \"%s\" resource file has wrong version"
+msgstr "E621: \"%s\" zdrojový súbor má zlé èíslo verzie"
+
+msgid "E673: Incompatible multi-byte encoding and character set."
+msgstr "E673: nekompatibilné viacbajtové kódovanie a znaková sada."
+
+msgid "E674: printmbcharset cannot be empty with multi-byte encoding."
+msgstr "E674: vo¾ba printmbcharset nemôže by prázdna pri viacbajtovom kódovaní."
+
+msgid "E675: No default font specified for multi-byte printing."
+msgstr "E675: Nie je špecifikované žiadne písmo pre viacbajtové tlaèenie."
+
+msgid "E324: Can't open PostScript output file"
+msgstr "E324: Nedá sa otvori výstupný PostScriptový súbor"
+
+#, c-format
+msgid "E456: Can't open file \"%s\""
+msgstr "E456: Nedá sa otvori súbor \"%s\""
+
+msgid "E456: Can't find PostScript resource file \"prolog.ps\""
+msgstr "E456: Nemožno nájs PostScriptový zdrojový súbor \"prolog.ps\""
+
+msgid "E456: Can't find PostScript resource file \"cidfont.ps\""
+msgstr "E456: Nemožno nájs PostScriptový zdrojový súbor \"cidfont.ps\""
+
+msgid "E456: Can't find PostScript resource file \"%s.ps\""
+msgstr "E456: Nemožno nájs PostScriptový zdrojový súbor \"%s.ps\""
+
+#, c-format
+msgid "E620: Unable to convert to print encoding \"%s\""
+msgstr "E620: Nemožno skonvertova do kódovania na tlaèenie \"%s\""
+
+msgid "Sending to printer..."
+msgstr "Posielam na tlaèiareò..."
+
+msgid "E365: Failed to print PostScript file"
+msgstr "E365: PostScriptový súbor sa nepodarilo vytlaèi"
+
+msgid "Print job sent."
+msgstr "Tlaèová úloha bola odoslaná."
+
+msgid "Add a new database"
+msgstr "Prida novú databázu"
+
+msgid "Query for a pattern"
+msgstr "H¾adanie vzoru"
+
+msgid "Show this message"
+msgstr "Zobrazi túto správu"
+
+msgid "Kill a connection"
+msgstr "Ukonèi spojenie"
+
+msgid "Reinit all connections"
+msgstr "Znovu inicializova všetky spojenia"
+
+msgid "Show connections"
+msgstr "Zobrazi spojenia"
+
+msgid "E560: Usage: cs[cope] %s"
+msgstr "E560: Použitie: cs[cope] %s"
+
+msgid "This cscope command does not support splitting the window.\n"
+msgstr "Tento cscope príkaz nepodporuje rozde¾ovanie okna.\n"
+
+msgid "E562: Usage: cstag <ident>"
+msgstr "E562: Použitie: cstag <odsadenie>"
+
+msgid "E257: cstag: tag not found"
+msgstr "E257: cstag: tag nenájdený"
+
+msgid "E563: stat(%s) error: %d"
+msgstr "E563: stat(%s) chyba: %d"
+
+msgid "E563: stat error"
+msgstr "E563: chyba stat"
+
+msgid "E564: %s is not a directory or a valid cscope database"
+msgstr "E564: %s nie je ani adresárom ani správnou cscope databázou"
+
+#, c-format
+msgid "Added cscope database %s"
+msgstr "Pridaná cscope databáza %s"
+
+msgid "E262: error reading cscope connection %ld"
+msgstr "E262: chyba pri èítaní cscope spojenia %ld"
+
+msgid "E561: unknown cscope search type"
+msgstr "E561: neznámy typ cscope h¾adania"
+
+msgid "E566: Could not create cscope pipes"
+msgstr "E566: Nedajú sa vytvori cscope rúry"
+
+msgid "E622: Could not fork for cscope"
+msgstr "E622: Nemožno spusti proces pre cscope"
+
+msgid "cs_create_connection exec failed"
+msgstr "spustenie cs_create_connection zlyhalo"
+
+msgid "E623: Could not spawn cscope process"
+msgstr "E623: Nedajú sa vytvori cscope rúry"
+
+msgid "cs_create_connection: fdopen for to_fp failed"
+msgstr "cs_create_connection: volanie fdopen pre to_fp zlyhalo"
+
+msgid "cs_create_connection: fdopen for fr_fp failed"
+msgstr "cs_create_connection: volanie fdopen pre fr_fp zlyhalo"
+
+msgid "E567: no cscope connections"
+msgstr "E567: žiadne cscope spojenia"
+
+#, c-format
+msgid "E259: no matches found for cscope query %s of %s"
+msgstr "E259: cscope h¾adanie %s vo vzore %s nenašlo žiadnu zhodu"
+
+#, c-format
+msgid "E469: invalid cscopequickfix flag %c for %c"
+msgstr "E469: chybný cscopequickfix príznak %c pre %c"
+
+msgid "cscope commands:\n"
+msgstr "príkazy cscope:\n"
+
+msgid "%-5s: %-30s (Usage: %s)"
+msgstr "%-5s: %-30s (Použitie: %s)"
+
+msgid "E625: cannot open cscope database: %s"
+msgstr "E625: nemožno otvori cscope databázu: %s"
+
+msgid "E626: cannot get cscope database information"
+msgstr "E626: nemožno získa cscope databázové informácie"
+
+msgid "E568: duplicate cscope database not added"
+msgstr "E568: duplicitná cscope databáza nebola pridaná"
+
+msgid "E569: maximum number of cscope connections reached"
+msgstr "E569: dosiahnutý maximálny poèet cscope spojení"
+
+#, c-format
+msgid "E261: cscope connection %s not found"
+msgstr "E261: cscope spojenie %s nenájdené"
+
+msgid "cscope connection %s closed"
+msgstr "cscope spojenie %s ukonèené"
+
+#. should not reach here
+msgid "E570: fatal error in cs_manage_matches"
+msgstr "E570: vážna chyba v cs_manage_matches"
+
+msgid "Cscope tag: %s"
+msgstr "Cscope tag: %s"
+
+msgid ""
+"\n"
+" # line"
+msgstr ""
+"\n"
+" # riadok"
+
+msgid "filename / context / line\n"
+msgstr "názov súboru/ kontext / riadok\n"
+
+msgid "E609: Cscope error: %s"
+msgstr "E609: Chyba cscope: %s"
+
+msgid "All cscope databases reset"
+msgstr "Všetky cscope databáze resetované"
+
+msgid "no cscope connections\n"
+msgstr "žiadne cscope spojenia\n"
+
+msgid " # pid database name prepend path\n"
+msgstr " # pid názov databázy predpona cesty\n"
+
+msgid ""
+"???: Sorry, this command is disabled, the MzScheme library could not be "
+"loaded."
+msgstr "???: Prepáète, tento príkaz je vypnutý, MzScheme knižnica nemôže by naèítaná."
+
+msgid "invalid expression"
+msgstr "chybný výraz"
+
+msgid "expressions disabled at compile time"
+msgstr "podpora výrazov bola vypnutá pri preklade programu"
+
+msgid "hidden option"
+msgstr "skrytá vo¾ba"
+
+msgid "unknown option"
+msgstr "neznáma vo¾ba"
+
+msgid "window index is out of range"
+msgstr "èíslo okna mimo rozsah"
+
+msgid "couldn't open buffer"
+msgstr "nemožno otvori buffer"
+
+msgid "cannot save undo information"
+msgstr "nedajú sa uloži záložne (opravné) informácie"
+
+msgid "cannot delete line"
+msgstr "nedá sa vymaza riadok"
+
+msgid "cannot replace line"
+msgstr "nedá sa nahradi riadok"
+
+msgid "cannot insert line"
+msgstr "nedá sa vloži riadok"
+
+msgid "string cannot contain newlines"
+msgstr "reazec nesmie obsahova znaky nového riadku"
+
+msgid "Vim error: ~a"
+msgstr "Chyba Vim: ~a"
+
+msgid "Vim error"
+msgstr "Chyba Vim"
+
+msgid "buffer is invalid"
+msgstr "buffer je neplatný"
+
+msgid "window is invalid"
+msgstr "okno je neplatné"
+
+msgid "linenr out of range"
+msgstr "èíslo riadka mimo rozsah"
+
+msgid "not allowed in the Vim sandbox"
+msgstr "nie je dovolené v bezpeènostnej schránke"
+
+msgid ""
+"E263: Sorry, this command is disabled, the Python library could not be "
+"loaded."
+msgstr ""
+"E262: Prepáète, tento príkaz je vypnutý, Python knižnica nemôže by naèítaná."
+
+msgid "E659: Cannot invoke Python recursively"
+msgstr "E659: Python nemôže by spustený rekurzívne"
+
+msgid "can't delete OutputObject attributes"
+msgstr "nedá sa vymaza vlastnos OutputObject"
+
+msgid "softspace must be an integer"
+msgstr "softspace musí by kladné celé èíslo"
+
+msgid "invalid attribute"
+msgstr "chybná vlastnos"
+
+msgid "writelines() requires list of strings"
+msgstr "writelines() vyžaduje zoznam reazcov"
+
+msgid "E264: Python: Error initialising I/O objects"
+msgstr "E264: Python: Chyba pri inicializácii I/O objektov"
+
+msgid "attempt to refer to deleted buffer"
+msgstr "pokus o odkaz na vymazaný buffer"
+
+msgid "line number out of range"
+msgstr "èíslo riadka mimo rozsah"
+
+#, c-format
+msgid "<buffer object (deleted) at %8lX>"
+msgstr "<objekt bufferu (vymazaný) na %8lX>"
+
+msgid "invalid mark name"
+msgstr "chybné meno znaèky"
+
+msgid "no such buffer"
+msgstr "žiadny taký buffer"
+
+msgid "attempt to refer to deleted window"
+msgstr "pokus o odkaz na vymazané okno"
+
+msgid "readonly attribute"
+msgstr "vlastnos iba pre èítanie"
+
+msgid "cursor position outside buffer"
+msgstr "umiestnenie kurzoru mimo buffer"
+
+#, c-format
+msgid "<window object (deleted) at %.8lX>"
+msgstr "<objekt okna (vymazaný) na %.8lX>"
+
+#, c-format
+msgid "<window object (unknown) at %.8lX>"
+msgstr "<objekt okna (neznámy) na %.8lX>"
+
+#, c-format
+msgid "<window %d>"
+msgstr "<okno %d>"
+
+msgid "no such window"
+msgstr "žiadne také okno"
+
+msgid ""
+"E266: Sorry, this command is disabled, the Ruby library could not be loaded."
+msgstr ""
+"E266: Prepáète, tento príkaz je vypnutý, Ruby knižnica nemôže by naèítaná."
+
+#, c-format
+msgid "E273: unknown longjmp status %d"
+msgstr "E273: Neznámy 'longjmp' stav %d"
+
+msgid "Toggle implementation/definition"
+msgstr "Prepnú implementáciu/definíciu"
+
+msgid "Show base class of"
+msgstr "Ukáza základnú triedu"
+
+msgid "Show overridden member function"
+msgstr "Ukáza preaženú èlenskú funkciu"
+
+msgid "Retrieve from file"
+msgstr "Obnovi zo súboru"
+
+msgid "Retrieve from project"
+msgstr "Obnovi z projektu"
+
+msgid "Retrieve from all projects"
+msgstr "Obnovi zo všetkých projektov"
+
+msgid "Retrieve"
+msgstr "Obnovi"
+
+msgid "Show source of"
+msgstr "Ukáza zdroj"
+
+msgid "Find symbol"
+msgstr "Nájs znak"
+
+msgid "Browse class"
+msgstr "Prezrie triedu"
+
+msgid "Show class in hierarchy"
+msgstr "Ukáza triedu v hierarchii"
+
+msgid "Show class in restricted hierarchy"
+msgstr "Ukáza triedu v obmedzenej hierarchii"
+
+msgid "Xref refers to"
+msgstr "Xref odkazuje na"
+
+msgid "Xref referred by"
+msgstr "Xref odkázaný z"
+
+msgid "Xref has a"
+msgstr "Xref má"
+
+msgid "Xref used by"
+msgstr "Xref použitý"
+
+msgid "Show docu of"
+msgstr "Ukáza dokumentáciu"
+
+msgid "Generate docu for"
+msgstr "Vytvori dokumentáciu pre"
+
+msgid ""
+"Cannot connect to SNiFF+. Check environment (sniffemacs must be found in "
+"$PATH).\n"
+msgstr ""
+"Zlyhalo pripojenie na SNiFF+, Preverte prostredie (sniffemacs sa musí "
+"nachádza v $PATH).\n"
+
+msgid "E274: Sniff: Error during read. Disconnected"
+msgstr "E274: Sniff: Chyba poèas èítania. Odpojené"
+
+msgid "SNiFF+ is currently "
+msgstr "SNiFF+ je aktuálne "
+
+msgid "not "
+msgstr "ne"
+
+msgid "connected"
+msgstr "pripojený"
+
+#, c-format
+msgid "E275: Unknown SNiFF+ request: %s"
+msgstr "E275: Neznáma SNiFF+ požiadavka: %s"
+
+msgid "E276: Error connecting to SNiFF+"
+msgstr "E276: Chyba pripojenia na SNiFF+"
+
+msgid "E278: SNiFF+ not connected"
+msgstr "E278: SNiFF+ nie je pripojený"
+
+msgid "E279: Not a SNiFF+ buffer"
+msgstr "E279: Nie je SNiFF+ bufferom"
+
+msgid "Sniff: Error during write. Disconnected"
+msgstr "Sniff: Chyba zápisu. Odpojené"
+
+msgid "invalid buffer number"
+msgstr "chybné èíslo bufferu"
+
+msgid "not implemented yet"
+msgstr "nie je ešte podporované"
+
+#. ???
+msgid "cannot set line(s)"
+msgstr "nedajú sa nastavi riadky"
+
+msgid "mark not set"
+msgstr "znaèka nie je nastavená"
+
+#, c-format
+msgid "row %d column %d"
+msgstr "riadok %d ståpec %d"
+
+msgid "cannot insert/append line"
+msgstr "nedá sa vloži/pripoji riadok"
+
+msgid "unknown flag: "
+msgstr "neznámy príznak: "
+
+msgid "unknown vimOption"
+msgstr "neznáma vo¾ba (vimOption)"
+
+msgid "keyboard interrupt"
+msgstr "prerušenie z klávesnice"
+
+msgid "vim error"
+msgstr "chyba Vim"
+
+msgid "cannot create buffer/window command: object is being deleted"
+msgstr "nedá sa vytvori príkaz bufferu/okna: objekt bude vymazaný"
+
+msgid ""
+"cannot register callback command: buffer/window is already being deleted"
+msgstr ""
+"nedá sa zaregistrova príkaz spätného volania: buffer/okno už bol vymazaný"
+
+#. This should never happen. Famous last word?
+msgid ""
+"E280: TCL FATAL ERROR: reflist corrupt!? Please report this to vim-dev@vim."
+"org"
+msgstr ""
+"E280: TCL FATAL ERROR: reflist poškodený!? Oznámte, prosím, túto chybu na "
+"vim-dev@vim.org"
+
+msgid "cannot register callback command: buffer/window reference not found"
+msgstr ""
+"nedá sa zaregistrova príkaz spätného volania: odkaz na buffer/okno nenájdený"
+
+msgid ""
+"E571: Sorry, this command is disabled: the Tcl library could not be loaded."
+msgstr ""
+"E571: Prepáète, tento príkaz je vypnutý, Tcl knižnica nemôže by naèítaná."
+
+msgid ""
+"E281: TCL ERROR: exit code is not int!? Please report this to vim-dev@vim.org"
+msgstr ""
+"E281: TCL CHYBA: návratový kód nie je celé èíslo!? Oznámte, prosím, túto "
+"chybu na vim-dev@vim.org"
+
+#, c-format
+msgid "E572: exit code %d"
+msgstr "E572: návratový kód %d"
+
+msgid "cannot get line"
+msgstr "nedá sa preèíta riadok"
+
+msgid "Unable to register a command server name"
+msgstr "Nemôžem zaregistrova meno príkazového servra"
+
+msgid "E248: Failed to send command to the destination program"
+msgstr "E248: Chyba poèas prenosu príkazu do cie¾ového programu"
+
+msgid "E573: Invalid server id used: %s"
+msgstr "E573: Použíté chybné èíslo servera: %s"
+
+msgid "E251: VIM instance registry property is badly formed. Deleted!"
+msgstr "E251: VIM registrová vlastnos je zle formátovaná. Vymazané!"
+
+msgid "Unknown option argument"
+msgstr "Neznámy parameter vo¾by"
+
+msgid "Too many edit arguments"
+msgstr "Príliš mnoho upravovacích argumentov"
+
+msgid "Argument missing after"
+msgstr "Chýba argument po"
+
+msgid "Garbage after option argument"
+msgstr "Chyby za parametrom vo¾by"
+
+msgid "Too many \"+command\", \"-c command\" or \"--cmd command\" arguments"
+msgstr "Príliš mnoho \"+príkaz\", \"-c príkaz\" alebo \"--cmd príkaz\" argumentov"
+
+msgid "Invalid argument for"
+msgstr "Chybný argument pre"
+
+#, c-format
+msgid "%d files to edit\n"
+msgstr "%d súborov pre úpravu\n"
+
+msgid "This Vim was not compiled with the diff feature."
+msgstr "Tento Vim nebol kompilovaný s porovnávacími funkciami."
+
+msgid "Attempt to open script file again: \""
+msgstr "Pokus o opätovné otvorenie skriptu: \""
+
+msgid "Cannot open for reading: \""
+msgstr "Nedá sa otvori pre zápis: \""
+
+msgid "Cannot open for script output: \""
+msgstr "Nedá sa otvori pre výstup skriptu: \""
+
+msgid "Vim: Error: Failure to start gvim from NetBeans\n"
+msgstr "Vim: Chyba: Chyba spúšania gvim pre NetBeans\n"
+
+msgid "Vim: Warning: Output is not to a terminal\n"
+msgstr "Vim: Varovanie: Výstup nesmeruje na terminál\n"
+
+msgid "Vim: Warning: Input is not from a terminal\n"
+msgstr "Vim: Varovanie: Vstup nepochádza z terminálu\n"
+
+#. just in case..
+msgid "pre-vimrc command line"
+msgstr "pre-vimrc príkazový riadok"
+
+#, c-format
+msgid "E282: Cannot read from \"%s\""
+msgstr "E282: Nedá sa èíta z \"%s\""
+
+msgid ""
+"\n"
+"More info with: \"vim -h\"\n"
+msgstr ""
+"\n"
+"Podrobnejšie informácie získáte pomocou \"vim -h\"\n"
+
+msgid "[file ..] edit specified file(s)"
+msgstr "[súbor ..] .. upravi súbor(y)"
+
+msgid "- read text from stdin"
+msgstr "- èíta text z štandardného vstupu"
+
+msgid "-t tag edit file where tag is defined"
+msgstr "-t tag upravi súbor na mieste definície tagu"
+
+msgid "-q [errorfile] edit file with first error"
+msgstr "-q [chybový súbor] upravi súbor na mieste výskytu prvej chyby"
+
+msgid ""
+"\n"
+"\n"
+"usage:"
+msgstr ""
+"\n"
+"\n"
+"použitie:"
+
+msgid " vim [arguments] "
+msgstr "vim [argumenty] "
+
+msgid ""
+"\n"
+" or:"
+msgstr ""
+"\n"
+" alebo:"
+
+#. TODO: is translation correct?
+msgid "where case is ignored prepend / to make flag upper case"
+msgstr "v prípade, že je ignorovaná ve¾kos písmen, použite znak '/' na zaèiatku, aby mal príznak význam ve¾kého písmena"
+
+msgid ""
+"\n"
+"\n"
+"Arguments:\n"
+msgstr ""
+"\n"
+"\n"
+"Argumenty:\n"
+
+msgid "--\t\t\tOnly file names after this"
+msgstr "--\t\t\tMôžu nasledova iba názvy súborov"
+
+msgid "--literal\t\tDon't expand wildcards"
+msgstr "--literal\t\tNexpandova žolíkové znaky (wildcards)"
+
+msgid "-register\t\tRegister this gvim for OLE"
+msgstr "-register\t\tPrihlási gvim na OLE"
+
+msgid "-unregister\t\tUnregister gvim for OLE"
+msgstr "-register\t\tOdhlási gvim z OLE"
+
+msgid "-g\t\t\tRun using GUI (like \"gvim\")"
+msgstr "-g\t\t\tSpusti v grafickom (GUI) móde (rovnaké ako \"gvim\")"
+
+msgid "-f or --nofork\tForeground: Don't fork when starting GUI"
+msgstr ""
+"-f alebo --nofork\tPopredie: Pri spustení grafického (GUI) módu sa nepresunie do pozadia"
+
+msgid "-v\t\t\tVi mode (like \"vi\")"
+msgstr "-v\t\t\tVi mód (rovnaké ako \"vi\")"
+
+msgid "-e\t\t\tEx mode (like \"ex\")"
+msgstr "-e\t\t\tEx mód (rovnaké ako \"ex\")"
+
+msgid "-s\t\t\tSilent (batch) mode (only for \"ex\")"
+msgstr "-s\t\t\tTichý (dávkový) mód (iba pre \"ex\")"
+
+msgid "-d\t\t\tDiff mode (like \"vimdiff\")"
+msgstr "-d\t\t\tPorovnávací mód (rovnaké ako \"vimdiff\")"
+
+msgid "-y\t\t\tEasy mode (like \"evim\", modeless)"
+msgstr "-y\t\t\tJednoduchý mód (rovnaké ako \"evim\", bezmódový)"
+
+msgid "-R\t\t\tReadonly mode (like \"view\")"
+msgstr "-R\t\t\tMód iba pre èítanie (ako \"view\")"
+
+msgid "-Z\t\t\tRestricted mode (like \"rvim\")"
+msgstr "-Z\t\t\tObmedzený mód (rovnaké ako \"rvim\")"
+
+msgid "-m\t\t\tModifications (writing files) not allowed"
+msgstr "-m\t\t\tZmeny (ukladanie súborov) zakázané"
+
+msgid "-M\t\t\tModifications in text not allowed"
+msgstr "-M\t\t\tZmeny v texte zakázané"
+
+msgid "-b\t\t\tBinary mode"
+msgstr "-b\t\t\tBinárny mód"
+
+msgid "-l\t\t\tLisp mode"
+msgstr "-l\t\t\tLisp mód"
+
+msgid "-C\t\t\tCompatible with Vi: 'compatible'"
+msgstr "-C\t\t\tKompatabilný s Vi: 'compatible'"
+
+msgid "-N\t\t\tNot fully Vi compatible: 'nocompatible'"
+msgstr "-N\t\t\tKompatibilita s Vi vypnutá: 'nocompatible'"
+
+msgid "-V[N]\t\tVerbose level"
+msgstr "-V[N]\t\tÚroveò výpisu hlášok"
+
+msgid "-D\t\t\tDebugging mode"
+msgstr "-D\t\t\tLadiaci mód"
+
+msgid "-n\t\t\tNo swap file, use memory only"
+msgstr "-n\t\t\tNevytvára odkladací súbor, používa iba pamä"
+
+msgid "-r\t\t\tList swap files and exit"
+msgstr "-r\t\t\tVypíš zoznam odkladacích súborov a skonèi"
+
+msgid "-r (with file name)\tRecover crashed session"
+msgstr "-r (s názvom súboru)\tObnoví prerušené sedenie"
+
+msgid "-L\t\t\tSame as -r"
+msgstr "-L\t\t\tRovnaké ako -r"
+
+msgid "-f\t\t\tDon't use newcli to open window"
+msgstr "-f\t\t\tNebude používa newcli pre otvorenie okna"
+
+msgid "-dev <device>\t\tUse <device> for I/O"
+msgstr "-dev <zariadenie>\t\tPouži <zariadenie> pre I/O"
+
+msgid "-A\t\t\tstart in Arabic mode"
+msgstr "-A\t\t\tspusti v Arabic móde"
+
+msgid "-H\t\t\tStart in Hebrew mode"
+msgstr "-H\t\t\tspusti v hebrejskom móde"
+
+msgid "-F\t\t\tStart in Farsi mode"
+msgstr "-F\t\t\tspusti vo Farsi móde"
+
+msgid "-T <terminal>\tSet terminal type to <terminal>"
+msgstr "-T <terminál>\tNastaví typ terminálu na <terminál>"
+
+msgid "-u <vimrc>\t\tUse <vimrc> instead of any .vimrc"
+msgstr "-u <vimrc>\t\tPoužije <vimrc> namiesto akéhoko¾vek .vimrc"
+
+msgid "-U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc"
+msgstr "-U <gvimrc>\t\tPoužije <gvimrc> namiesto akéhoko¾vek .gvimrc"
+
+msgid "--noplugin\t\tDon't load plugin scripts"
+msgstr "--noplugin\t\tNenahrá zásuvné moduly(plugin skripty)"
+
+msgid "-o[N]\t\tOpen N windows (default: one for each file)"
+msgstr "-o[N]\t\tOtvorí N okien (implicitne jedno pre každý súbor)"
+
+msgid "-O[N]\t\tLike -o but split vertically"
+msgstr "-O[N]\t\tAko -o ale rozdelí vertikálne"
+
+msgid "+\t\t\tStart at end of file"
+msgstr "+\t\t\tNastaví kurzor na koniec súboru"
+
+msgid "+<lnum>\t\tStart at line <lnum>"
+msgstr "+<riadok>\t\tNastaví kurzor na <riadok>"
+
+msgid "--cmd <command>\tExecute <command> before loading any vimrc file"
+msgstr "--cmd <príkaz>\t\tVykoná <príkaz> pred nahratím vimrc súboru"
+
+msgid "-c <command>\t\tExecute <command> after loading the first file"
+msgstr "-c <príkaz>\t\tPo nahratí prvého súboru vykoná <príkaz>"
+
+msgid "-S <session>\t\tSource file <session> after loading the first file"
+msgstr ""
+"-S <sedenie>\t\tPo nahratí prvého súboru vykoná príkazy v súbore <sedenie>"
+
+msgid "-s <scriptin>\tRead Normal mode commands from file <scriptin>"
+msgstr "-s <skript>\t\tNaèíta príkazy normálneho módu zo <skriptu>"
+
+msgid "-w <scriptout>\tAppend all typed commands to file <scriptout>"
+msgstr "-w <skript>\t\tPripojí všetky napísané príkazy do súboru <skript>"
+
+msgid "-W <scriptout>\tWrite all typed commands to file <scriptout>"
+msgstr "-W <skript>\t\tUloží všetky napísané príkazy do súboru <skript>"
+
+msgid "-x\t\t\tEdit encrypted files"
+msgstr "-x\t\t\tÚprava zašifrovaných súborov"
+
+msgid "-display <display>\tConnect vim to this particular X-server"
+msgstr "-display <displej>\tPripojí vim na príslušný X-server"
+
+msgid "-X\t\t\tDo not connect to X server"
+msgstr "-X\t\t\tNepripojí sa k X serveru"
+
+msgid "--remote <files>\tEdit <files> in a Vim server if possible"
+msgstr "--remote <súbory>\tUpravi <súbory> na Vim servri ak je to možné"
+
+msgid "--remote-silent <files> Same, don't complain if there is no server"
+msgstr "--remote-silent <súbory>\tTo isté, ale nesažuj si, ak neexistuje server"
+
+msgid ""
+"--remote-wait <files> As --remote but wait for files to have been edited"
+msgstr ""
+"--remote-wait <súbory>\tAko --remote ale èaká na súbory pre ukonèenie úprav"
+
+msgid ""
+"--remote-wait-silent <files> Same, don't complain if there is no server"
+msgstr "--remote-wait-silent <súbory>\tTo isté, ale nesažuj si, ak neexistuje server"
+
+msgid "--remote-send <keys>\tSend <keys> to a Vim server and exit"
+msgstr "--remote-send <vo¾by>\tOdošle <vo¾by> na Vim server a skonèí"
+
+msgid "--remote-expr <expr>\tEvaluate <expr> in a Vim server and print result"
+msgstr "--remote-expr <výraz>\tSpusti <výraz> na servri a vytlaèí výsledok"
+
+msgid "--serverlist\t\tList available Vim server names and exit"
+msgstr "--serverlist\t\tVypíše zoznam mien dostupných Vim servrov a skonèí"
+
+msgid "--servername <name>\tSend to/become the Vim server <name>"
+msgstr "--servername <názov>\tOdošle na Vim server <názov>"
+
+msgid "-i <viminfo>\t\tUse <viminfo> instead of .viminfo"
+msgstr "-i <viminfo>\t\tPoužije <viminfo> namiesto akéhoko¾vek .viminfo"
+
+msgid "-h or --help\tPrint Help (this message) and exit"
+msgstr "-h alebo --help\tVypíše túto nápovedu a skonèí"
+
+msgid "--version\t\tPrint version information and exit"
+msgstr "--version\t\tVypíše informácie o verzii a skonèí"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (Motif version):\n"
+msgstr ""
+"\n"
+"Argumenty dostupné pre gvim (Motif verzia):\n"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (neXtaw version):\n"
+msgstr ""
+"\n"
+"Argumenty dostupné pre gvim (neXtaw verzia):\n"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (Athena version):\n"
+msgstr ""
+"\n"
+"Argumenty dostupné pre gvim (Athena verzia):\n"
+
+msgid "-display <display>\tRun vim on <display>"
+msgstr "-display <displej>\tSpustí vim na <displej>"
+
+msgid "-iconic\t\tStart vim iconified"
+msgstr "-iconic\t\tSpustí vim minimalizované"
+
+msgid "-name <name>\t\tUse resource as if vim was <name>"
+msgstr "-name <názov>\t\tPoužije resource ako by vim mal <názov>"
+
+msgid "\t\t\t (Unimplemented)\n"
+msgstr "\t\t\t (nie je implementované)\n"
+
+msgid "-background <color>\tUse <color> for the background (also: -bg)"
+msgstr "-background <farba>\tNastaví sa <farba> pozadia (tiež -bg)"
+
+msgid "-foreground <color>\tUse <color> for normal text (also: -fg)"
+msgstr "-foreground <farba>\tNastaví sa <farba> popredia (tiež -fg)"
+
+msgid "-font <font>\t\tUse <font> for normal text (also: -fn)"
+msgstr "-font <písmo>\t\tNastaví <písmo> normálneho textu (tiež -fn)"
+
+msgid "-boldfont <font>\tUse <font> for bold text"
+msgstr "-boldfont <písmo>\tNastaví <písmo> pre zvýraznený text"
+
+msgid "-italicfont <font>\tUse <font> for italic text"
+msgstr "-italicfont <písmo>\tNastaví <písmo> pre kurzívu"
+
+msgid "-geometry <geom>\tUse <geom> for initial geometry (also: -geom)"
+msgstr "-geometry <geometrie>\tNastaví sa <geometria> (tiež -geom)"
+
+msgid "-borderwidth <width>\tUse a border width of <width> (also: -bw)"
+msgstr "-borderwidth <šírka>\tNastaví <šírku> okrajov (tiež -bw)"
+
+msgid "-scrollbarwidth <width> Use a scrollbar width of <width> (also: -sw)"
+msgstr "-scrollbarwidth <šírka> Nastaví <šírku> posuvnej lišty (tiež -sw)"
+
+msgid "-menuheight <height>\tUse a menu bar height of <height> (also: -mh)"
+msgstr "-menuheight <výška>\tNastaví <výšku> ponuky (tiež -mh)"
+
+msgid "-reverse\t\tUse reverse video (also: -rv)"
+msgstr "-reverse\t\tPoužije reverzné farby (tiež -rv)"
+
+msgid "+reverse\t\tDon't use reverse video (also: +rv)"
+msgstr "+reverse\t\tNepoužije reverzné farby (tiež +rv)"
+
+# TODO: howto translate 'resource' in this case?
+msgid "-xrm <resource>\tSet the specified resource"
+msgstr "-xrm <resource>\tNastaví zadaný <resource>"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (RISC OS version):\n"
+msgstr ""
+"\n"
+"Argumenty dostupné pre gvim (RISC OS verzia):\n"
+
+msgid "--columns <number>\tInitial width of window in columns"
+msgstr "--columns <poèet>\tPoèiatoèná šírka okna v ståpcoch"
+
+msgid "--rows <number>\tInitial height of window in rows"
+msgstr "--rows <poèet>\tPoèiatoèná výška okna v riadkoch"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (GTK+ version):\n"
+msgstr ""
+"\n"
+"Argumenty dostupné pre gvim (GTK+ verzia):\n"
+
+msgid "-display <display>\tRun vim on <display> (also: --display)"
+msgstr "-display <displej>\tSpustí vim na <displej> (tiež --display)"
+
+msgid "--role <role>\tSet a unique role to identify the main window"
+msgstr "-role <rola>\tNastaví unikátnu rolu pre identifikáciu hlavného okna"
+
+msgid "--socketid <xid>\tOpen Vim inside another GTK widget"
+msgstr "--socketid <xid>\tOtvorí Vim vnútri iného GTK programu."
+
+msgid ""
+"\n"
+"Arguments recognised by kvim (KDE version):\n"
+msgstr ""
+"\n"
+"Argumenty dostupné pre kvim (KDE verzia):\n"
+
+msgid "-black\t\tUse reverse video"
+msgstr "-black\t\tPoužije reverzné farby"
+
+msgid "-tip\t\t\tDisplay the tip dialog on startup"
+msgstr "-tip\t\t\tZobraz tip pri štarte"
+
+msgid "-notip\t\tDisable the tip dialog"
+msgstr "-notip\t\tNezobrazuj tip pri štarte"
+
+msgid "--display <display>\tRun vim on <display>"
+msgstr "-display <displej>\tSpustí vim na <displej>"
+
+msgid "-P <parent title>\tOpen Vim inside parent application"
+msgstr "-P <titulok rodièa>\tOtvor Vim vnútri materskej aplikácie"
+
+msgid "No display"
+msgstr "Bez grafického rozhrania"
+
+#. Failed to send, abort.
+msgid ": Send failed.\n"
+msgstr ": Odoslanie zlyhalo.\n"
+
+#. Let vim start normally.
+msgid ": Send failed. Trying to execute locally\n"
+msgstr ": Odoslanie zlyhalo. Pokúšam sa spusti lokálne\n"
+
+#, c-format
+msgid "%d of %d edited"
+msgstr "%d upravených súborov z %d"
+
+msgid "No display: Send expression failed.\n"
+msgstr "Žiaden graf. mód: Odoslanie výrazu zlyhalo.\n"
+
+msgid ": Send expression failed.\n"
+msgstr ": Odoslanie výrazu zlyhalo.\n"
+
+msgid "No marks set"
+msgstr "Nie sú nastavené žiadne znaèky"
+
+#, c-format
+msgid "E283: No marks matching \"%s\""
+msgstr "E283:\"%s\" nevyhovujú žiadne znaèky"
+
+#. Highlight title
+msgid ""
+"\n"
+"mark line col file/text"
+msgstr ""
+"\n"
+"znaèka riadok ståpec súbor/text"
+
+#. Highlight title
+msgid ""
+"\n"
+" jump line col file/text"
+msgstr ""
+"\n"
+" skok riadok ståpec súbor/text"
+
+#. Highlight title
+msgid ""
+"\n"
+"change line col text"
+msgstr ""
+"\n"
+"znaèka riadok ståpec text"
+
+#, c-format
+msgid ""
+"\n"
+"# File marks:\n"
+msgstr ""
+"\n"
+"# Súborové znaèky:\n"
+
+#. Write the jumplist with -'
+#, c-format
+msgid ""
+"\n"
+"# Jumplist (newest first):\n"
+msgstr ""
+"\n"
+"# Zoznam skokov (zaèínajúci najnovšou položkou):\n"
+
+#, c-format
+msgid ""
+"\n"
+"# History of marks within files (newest to oldest):\n"
+msgstr ""
+"\n"
+"# História znaèiek v súboroch (zaèínajúci najnovšou položkou):\n"
+
+msgid "Missing '>'"
+msgstr "Chýba '>'"
+
+msgid "E543: Not a valid codepage"
+msgstr "E543: Chybná kódová stránka"
+
+msgid "E284: Cannot set IC values"
+msgstr "E284: Nedajú sa nastavi IC hodnoty"
+
+msgid "E285: Failed to create input context"
+msgstr "E285: Nepodarilo sa vytvori vstupný kontext"
+
+msgid "E286: Failed to open input method"
+msgstr "E286: Nepodarilo sa otvori vstupnú metódu"
+
+msgid "E287: Warning: Could not set destroy callback to IM"
+msgstr "E287: Varovanie: likvidaèné spätné volanie sa nedá nastavi na IM"
+
+msgid "E288: input method doesn't support any style"
+msgstr "E288: vstupná metóda nepodporuje žiadny štýl"
+
+msgid "E289: input method doesn't support my preedit type"
+msgstr "E289: vstupná metóda nepodporuje môj 'preedit' typ"
+
+msgid "E290: over-the-spot style requires fontset"
+msgstr "E290: Nadbodový štýl vyžaduje sadu fontov (fontset)"
+
+msgid "E291: Your GTK+ is older than 1.2.3. Status area disabled"
+msgstr "E291: Máte GTK+ verziu staršiu než 1.2.3. Stavová plocha vypnutá."
+
+msgid "E292: Input Method Server is not running"
+msgstr "E292: Server vstupných metód nebeží"
+
+msgid "E293: block was not locked"
+msgstr "E293: blok nebol zamknutý"
+
+msgid "E294: Seek error in swap file read"
+msgstr "E294: Chyba posunu pri èítaní odkladacieho súboru"
+
+msgid "E295: Read error in swap file"
+msgstr "E295: Chyba pri èítaní odkladacieho súboru"
+
+msgid "E296: Seek error in swap file write"
+msgstr "E296: Chyba posunu pri ukladaní do odkladacieho súboru"
+
+msgid "E297: Write error in swap file"
+msgstr "E297: Chyba pri ukladaní do odkladacieho súboru"
+
+msgid "E300: Swap file already exists (symlink attack?)"
+msgstr "E300: Odkladací súbor už existuje (symlink útok?)"
+
+msgid "E298: Didn't get block nr 0?"
+msgstr "E298: Nedá sa získa blok 0?"
+
+msgid "E298: Didn't get block nr 1?"
+msgstr "E298: Nedá sa získa blok 1?"
+
+msgid "E298: Didn't get block nr 2?"
+msgstr "E298: Nedá sa získa blok 2?"
+
+#. could not (re)open the swap file, what can we do????
+msgid "E301: Oops, lost the swap file!!!"
+msgstr "E301: Ups, odkladací súbor bol stratený!!!"
+
+msgid "E302: Could not rename swap file"
+msgstr "E302: Nedá sa premenova odkladací súbor"
+
+#, c-format
+msgid "E303: Unable to open swap file for \"%s\", recovery impossible"
+msgstr "E303: Nedá sa otvori odkladací súbor pre \"%s\", oprava nemožná"
+
+msgid "E304: ml_upd_block0(): Didn't get block 0??"
+msgstr "E304: ml_upd_block0(): nedá sa získa blok 0??"
+
+#, c-format
+msgid "E305: No swap file found for %s"
+msgstr "E305: Odkladací súbor pre %s nebol nájdený"
+
+msgid "Enter number of swap file to use (0 to quit): "
+msgstr ""
+"Zadajte èíslo odkladacieho súboru, ktorý sa má použit (0 pre ukonèenie): "
+
+#, c-format
+msgid "E306: Cannot open %s"
+msgstr "E306: Nedá sa otvori %s"
+
+msgid "Unable to read block 0 from "
+msgstr "Nedá sa èíta blok 0 z "
+
+msgid ""
+"\n"
+"Maybe no changes were made or Vim did not update the swap file."
+msgstr ""
+"\n"
+"Možno nedošlo k žiadnym zmenám, alebo Vim neaktualizoval odkladací súbor."
+
+msgid " cannot be used with this version of Vim.\n"
+msgstr " nedá sa použi s touto verziou Vim.\n"
+
+msgid "Use Vim version 3.0.\n"
+msgstr "Použite Vim verziu 3.0.\n"
+
+#, c-format
+msgid "E307: %s does not look like a Vim swap file"
+msgstr "E307: %s sa nezdá by odkladacím súborom Vim"
+
+msgid " cannot be used on this computer.\n"
+msgstr " nedá sa použí na tomto poèítaèi.\n"
+
+msgid "The file was created on "
+msgstr "Súbor bol vytvorený "
+
+msgid ""
+",\n"
+"or the file has been damaged."
+msgstr ""
+",\n"
+"alebo bol súbor poškodený."
+
+#, c-format
+msgid "Using swap file \"%s\""
+msgstr "Používam odkladací súbor \"%s\""
+
+#, c-format
+msgid "Original file \"%s\""
+msgstr "Pôvodný súbor \"%s\""
+
+msgid "E308: Warning: Original file may have been changed"
+msgstr "E308: Varovanie: Pôvodný súbor mohol by zmenený"
+
+#, c-format
+msgid "E309: Unable to read block 1 from %s"
+msgstr "E309: Nedá sa èíta blok 1 z %s"
+
+msgid "???MANY LINES MISSING"
+msgstr "???CHÝBA MNOHO RIADKOV"
+
+msgid "???LINE COUNT WRONG"
+msgstr "???CHYBNÝ POÈET RIADKOV"
+
+msgid "???EMPTY BLOCK"
+msgstr "???PRÁZDNY BLOK"
+
+msgid "???LINES MISSING"
+msgstr "???CHÝBAJÚCE RIADKY"
+
+#, c-format
+msgid "E310: Block 1 ID wrong (%s not a .swp file?)"
+msgstr "E310: ID bloku 1 je chybné (je %s odkladacím súborom?)"
+
+msgid "???BLOCK MISSING"
+msgstr "???CHÝBA BLOK"
+
+msgid "??? from here until ???END lines may be messed up"
+msgstr "od ??? po ???END môžu by riadky pomiešané"
+
+msgid "??? from here until ???END lines may have been inserted/deleted"
+msgstr "od ??? po ???END môžu by riadky vložené/vymazané"
+
+msgid "???END"
+msgstr "???KONIEC"
+
+msgid "E311: Recovery Interrupted"
+msgstr "E311: Obnova prerušená"
+
+msgid ""
+"E312: Errors detected while recovering; look for lines starting with ???"
+msgstr ""
+"E312: V priebehu obnovy došlo k chybám; skontrolujte riadky zaèínajúce na ???"
+
+msgid "See \":help E312\" for more information."
+msgstr "Pozrite \":help E312\" pre ïalšie informácie"
+
+msgid "Recovery completed. You should check if everything is OK."
+msgstr "Obnova dokonèená. Skontrolujte, èi je všetko v poriadku."
+
+msgid ""
+"\n"
+"(You might want to write out this file under another name\n"
+msgstr ""
+"\n"
+"(Zvážte uloženie tohoto súboru pod iným menom\n"
+
+msgid "and run diff with the original file to check for changes)\n"
+msgstr "a pomocou programu diff zistite zmeny oproti pôvodnému súboru)\n"
+
+msgid ""
+"Delete the .swp file afterwards.\n"
+"\n"
+msgstr "Potom vymažte odkladací súbor s príponou .swp.\n"
+
+#. use msg() to start the scrolling properly
+msgid "Swap files found:"
+msgstr "Nájdené odkladacie súbory:"
+
+msgid " In current directory:\n"
+msgstr " V aktuálnom adresári:\n"
+
+msgid " Using specified name:\n"
+msgstr " So zadaným menom:\n"
+
+msgid " In directory "
+msgstr " V adresári "
+
+msgid " -- none --\n"
+msgstr " -- žiadne --\n"
+
+msgid " owned by: "
+msgstr " vlastník: "
+
+msgid " dated: "
+msgstr " dátum vytvorenia: "
+
+msgid " dated: "
+msgstr " dátum vytvorenia: "
+
+msgid " [from Vim version 3.0]"
+msgstr " [od Vim verzie 3.0]"
+
+msgid " [does not look like a Vim swap file]"
+msgstr " [nevyzerá ako odkladací súbor Vim]"
+
+msgid " file name: "
+msgstr " názov súboru: "
+
+msgid ""
+"\n"
+" modified: "
+msgstr ""
+"\n"
+" zmenený: "
+
+msgid "YES"
+msgstr "ÁNO"
+
+msgid "no"
+msgstr "nie"
+
+msgid ""
+"\n"
+" user name: "
+msgstr ""
+"\n"
+" užívate¾ské meno: "
+
+msgid " host name: "
+msgstr " názov poèítaèa: "
+
+msgid ""
+"\n"
+" host name: "
+msgstr ""
+"\n"
+" názov poèítaèa: "
+
+msgid ""
+"\n"
+" process ID: "
+msgstr ""
+"\n"
+" ID procesu : "
+
+msgid " (still running)"
+msgstr " (stále beží)"
+
+msgid ""
+"\n"
+" [not usable with this version of Vim]"
+msgstr ""
+"\n"
+" [nepoužite¾né s touto verziou Vim]"
+
+msgid ""
+"\n"
+" [not usable on this computer]"
+msgstr ""
+"\n"
+" [nepoužitelné na tomto poèítaèi]"
+
+msgid " [cannot be read]"
+msgstr " [nedá sa preèíta]"
+
+msgid " [cannot be opened]"
+msgstr " [nedá sa otvori]"
+
+msgid "E313: Cannot preserve, there is no swap file"
+msgstr "E313: Nedá sa zachova - odkladací súbor neexistuje"
+
+msgid "File preserved"
+msgstr "Súbor zachovaný"
+
+msgid "E314: Preserve failed"
+msgstr "E314: Uchovanie sa nepodarilo"
+
+#, c-format
+msgid "E315: ml_get: invalid lnum: %ld"
+msgstr "E315: ml_get: chybné èíslo riadku: %ld"
+
+#, c-format
+msgid "E316: ml_get: cannot find line %ld"
+msgstr "E316: ml_get: nedá sa nájs riadok %ld"
+
+msgid "E317: pointer block id wrong 3"
+msgstr "E317: chybné èíslo ukazovate¾a na blok 3"
+
+msgid "stack_idx should be 0"
+msgstr "stack_idx by mal ma hodnotu 3"
+
+msgid "E318: Updated too many blocks?"
+msgstr "E318: Aktualizovaných príliš ve¾a blokov?"
+
+msgid "E317: pointer block id wrong 4"
+msgstr "E317: chybné èíslo ukazovate¾a na blok 4"
+
+msgid "deleted block 1?"
+msgstr "vymazaný blok 1?"
+
+#, c-format
+msgid "E320: Cannot find line %ld"
+msgstr "E320: Nedá sa nájs riadok %ld"
+
+msgid "E317: pointer block id wrong"
+msgstr "E317: chybné èíslo ukazovate¾a na blok"
+
+msgid "pe_line_count is zero"
+msgstr "pe_line_count má nulovú hodnotu"
+
+#, c-format
+msgid "E322: line number out of range: %ld past the end"
+msgstr "E322: èíslo riadku je mimo rozsah: %ld (za koncom)"
+
+#, c-format
+msgid "E323: line count wrong in block %ld"
+msgstr "E323: chybný poèet riadkov v bloku %ld"
+
+msgid "Stack size increases"
+msgstr "Nárast ve¾kosti zásobníku"
+
+msgid "E317: pointer block id wrong 2"
+msgstr "E317: chybný èíslo ukazovate¾a na blok 2"
+
+msgid "E325: ATTENTION"
+msgstr "E325: POZOR"
+
+msgid ""
+"\n"
+"Found a swap file by the name \""
+msgstr ""
+"\n"
+"Nájdený odkladací súbor s menom \""
+
+msgid "While opening file \""
+msgstr "Pri otváraní súboru \""
+
+msgid " NEWER than swap file!\n"
+msgstr " NOVŠÍ ako odkladací súbor!\n"
+
+#. Some of these messages are long to allow translation to
+#. * other languages.
+msgid ""
+"\n"
+"(1) Another program may be editing the same file.\n"
+" If this is the case, be careful not to end up with two\n"
+" different instances of the same file when making changes.\n"
+msgstr ""
+"\n"
+"(1) Súbor môže by upravovaný iným programom.\n"
+" Ak je tomu tak, potom si dajte pozor, aby ste po uložení zmien\n"
+" nemali dve rôzne verzie toho istého súboru.\n"
+
+msgid " Quit, or continue with caution.\n"
+msgstr " Ukonèite program, alebo opatrne pokraèujte v úpravách.\n"
+
+msgid ""
+"\n"
+"(2) An edit session for this file crashed.\n"
+msgstr ""
+"\n"
+"(2) Úprava tohoto súboru bola prerušená neoèakávaným ukonèením programu.\n"
+
+msgid " If this is the case, use \":recover\" or \"vim -r "
+msgstr " Ak je tomu tak, potom použite \":recover\" alebo \"vim -r "
+
+msgid ""
+"\"\n"
+" to recover the changes (see \":help recovery\").\n"
+msgstr ""
+"\"\n"
+" pre obnovenie zmien (viï \":help recovery)\".\n"
+
+msgid " If you did this already, delete the swap file \""
+msgstr " Pokia¾ ste tak už urobili, tak vymažte odkladací súbor \""
+
+msgid ""
+"\"\n"
+" to avoid this message.\n"
+msgstr ""
+"\"\n"
+" a táto správa sa už nebude objavova.\n"
+
+msgid "Swap file \""
+msgstr "Odkladací súbor \""
+
+msgid "\" already exists!"
+msgstr "\" už existuje!"
+
+msgid "VIM - ATTENTION"
+msgstr "VIM - POZOR"
+
+msgid "Swap file already exists!"
+msgstr "Odkladací súbor už existuje!"
+
+msgid ""
+"&Open Read-Only\n"
+"&Edit anyway\n"
+"&Recover\n"
+"&Quit\n"
+"&Abort"
+msgstr ""
+"&Otvori iba pre èítanie\n"
+"&Pokraèova v úpravách\n"
+"O&bnovi súbor\n"
+"&Koniec\n"
+"&Zruši"
+
+msgid ""
+"&Open Read-Only\n"
+"&Edit anyway\n"
+"&Recover\n"
+"&Quit\n"
+"&Abort\n"
+"&Delete it"
+msgstr ""
+"&Otvori iba pre èítanie\n"
+"&Pokraèovat v úpravách\n"
+"O&bnovi súbor\n"
+"&Koniec\n"
+"&Zruši\n"
+"Z&maza"
+
+msgid "E326: Too many swap files found"
+msgstr "E326: Príliš mnoho odkladacích súborov"
+
+msgid "E327: Part of menu-item path is not sub-menu"
+msgstr "E327: Èas cesty k predmetu ponuky nie je podponukou"
+
+msgid "E328: Menu only exists in another mode"
+msgstr "E328: Ponuka existuje iba v inom móde"
+
+msgid "E329: No menu \"%s\""
+msgstr "E329: Ponuka \"%s\" neexistuje"
+
+msgid "E330: Menu path must not lead to a sub-menu"
+msgstr "E330: Cesta ponuky nesmie vies do podponuky"
+
+msgid "E331: Must not add menu items directly to menu bar"
+msgstr "E331: Položky ponuky sa nejdú pridáva priamo na lištu"
+
+msgid "E332: Separator cannot be part of a menu path"
+msgstr "E332: Odde¾ovaè nesmie by èasou cesty ponuky"
+
+#. Now we have found the matching menu, and we list the mappings
+#. Highlight title
+msgid ""
+"\n"
+"--- Menus ---"
+msgstr ""
+"\n"
+"--- Ponuky ---"
+
+msgid "Tear off this menu"
+msgstr "Odtrhnú tuto ponuku"
+
+msgid "E333: Menu path must lead to a menu item"
+msgstr "E333: Cesta ponuky musí vies k položke ponuky"
+
+#, c-format
+msgid "E334: Menu not found: %s"
+msgstr "E334: Ponuka nenájdená: %s"
+
+#, c-format
+msgid "E335: Menu not defined for %s mode"
+msgstr "E335: V %s móde nie je ponuka definovaná"
+
+msgid "E336: Menu path must lead to a sub-menu"
+msgstr "E336: Cesta ponuky musí vies do podponuky"
+
+msgid "E337: Menu not found - check menu names"
+msgstr "E337: Ponuka nenájdená - skontrolujte názvy ponúk"
+
+#, c-format
+msgid "Error detected while processing %s:"
+msgstr "Chyba pri spracovaní %s:"
+
+#, c-format
+msgid "line %4ld:"
+msgstr "riadok %4ld:"
+
+#, c-format
+msgid "E354: Invalid register name: '%s'"
+msgstr "E354: '%s' nie je prístupné meno registru"
+
+msgid "Messages maintainer: Bram Moolenaar <Bram@vim.org>"
+msgstr "Správca prekladu: Lubomir Host <rajo@platon.sk>"
+
+msgid "Interrupt: "
+msgstr "Prerušenie: "
+
+msgid "Press ENTER or type command to continue"
+msgstr "Stlaète ENTER alebo zadajte príkaz pre pokraèovanie"
+
+msgid "-- More --"
+msgstr "-- Pokraèovanie --"
+
+msgid " SPACE/d/j: screen/page/line down, b/u/k: up, q: quit "
+msgstr " MEDZERA/d/j: obrazovka/stránka/riadok dole, b/u/k: hore, q: koniec "
+
+msgid "Question"
+msgstr "Otázka"
+
+# TODO: Translate as "&Ano\n&Nie" ?
+msgid ""
+"&Yes\n"
+"&No"
+msgstr ""
+"&Ano\n"
+"&Nie"
+
+# TODO: Translate as "&Ano\n&Nie\n&Uloži všetko\nZahodi &všetko\n&Zruši" ?
+msgid ""
+"&Yes\n"
+"&No\n"
+"Save &All\n"
+"&Discard All\n"
+"&Cancel"
+msgstr ""
+"&Ano\n"
+"&Nie\n"
+"&Uloži všetko\n"
+"Zahodi &všetko\n"
+"&Zruši"
+
+msgid "Select Directory dialog"
+msgstr "Dialóg pre vytvorenie adresára"
+
+msgid "Save File dialog"
+msgstr "Dialóg pre ukladanie súborov"
+
+msgid "Open File dialog"
+msgstr "Dialóg pre otváranie súborov"
+
+msgid "E338: Sorry, no file browser in console mode"
+msgstr "E338: ¼utujem, ale konzolová verzia nepodporuje prehliadaè súborov"
+
+msgid "E766: Insufficient arguments for printf()"
+msgstr "E766: Chybné argumenty pre funkciu printf()"
+
+msgid "E767: Too many arguments to printf()"
+msgstr "E767: Príliš mnoho argumentov pre funkciu printf()"
+
+msgid "W10: Warning: Changing a readonly file"
+msgstr "W10: Varovanie: mením súbor iba pre èítanie"
+
+msgid "Type number or click with mouse (<Enter> cancels): "
+msgstr "Zadajte èíslo ale kliknite myšou (<Enter> zruší): "
+
+msgid "Choice number (<Enter> cancels): "
+msgstr "Zvo¾te èíslo (<Enter> zruší): "
+
+msgid "1 more line"
+msgstr "1 nový riadok"
+
+msgid "1 line less"
+msgstr "1 vymazaný riadok"
+
+#, c-format
+msgid "%ld more lines"
+msgstr "%ld nových riadkov"
+
+#, c-format
+msgid "%ld fewer lines"
+msgstr "%ld vymazaných riadkov"
+
+msgid " (Interrupted)"
+msgstr " (Prerušené)"
+
+msgid "Beep!"
+msgstr "Piip!"
+
+msgid "Vim: preserving files...\n"
+msgstr "Vim: zachovávam súbory...\n"
+
+#. close all memfiles, without deleting
+msgid "Vim: Finished.\n"
+msgstr "Vim: ukonèený\n"
+
+#, c-format
+msgid "ERROR: "
+msgstr "CHYBA: "
+
+#, c-format
+msgid ""
+"\n"
+"[bytes] total alloc-freed %lu-%lu, in use %lu, peak use %lu\n"
+msgstr ""
+"\n"
+"[bajtov] celkom uvolnené-alokované %lu-%lu, využité %lu, maximálne využitie %lu\n"
+
+#, c-format
+msgid ""
+"[calls] total re/malloc()'s %lu, total free()'s %lu\n"
+"\n"
+msgstr ""
+"[volanie] celkom re/malloc(): %lu, celkom free() %lu\n"
+"\n"
+
+msgid "E340: Line is becoming too long"
+msgstr "E340: Riadok sa stáva príliš dlhým"
+
+#, c-format
+msgid "E341: Internal error: lalloc(%ld, )"
+msgstr "E341: Vnútorná chyba: lalloc(%ld, )"
+
+#, c-format
+msgid "E342: Out of memory! (allocating %lu bytes)"
+msgstr "E342: Nedostatok pamäte! (alokujem %lu bajtov)"
+
+#, c-format
+msgid "Calling shell to execute: \"%s\""
+msgstr "Volám shell na spustenie: \"%s\""
+
+msgid "E545: Missing colon"
+msgstr "E545: Chýba dvojbodka"
+
+msgid "E546: Illegal mode"
+msgstr "E546: Neprípustný mód"
+
+msgid "E547: Illegal mouseshape"
+msgstr "E547: Chybný tvar myši"
+
+msgid "E548: digit expected"
+msgstr "E548: oèakávaná èíslica"
+
+msgid "E549: Illegal percentage"
+msgstr "E549: Neprípustné percento"
+
+msgid "Enter encryption key: "
+msgstr "Zadajte šifrovací k¾úè: "
+
+msgid "Enter same key again: "
+msgstr "Vložte ten istý k¾úè znova: "
+
+msgid "Keys don't match!"
+msgstr "K¾úèe sa nezhodujú!"
+
+#, c-format
+msgid ""
+"E343: Invalid path: '**[number]' must be at the end of the path or be "
+"followed by '%s'."
+msgstr ""
+"E343: Chybná cesta: '**[èíslo] musí by buï na konci cesty, alebo musí by\n"
+"nasledované '%s. Viï :help path."
+
+#, c-format
+msgid "E344: Can't find directory \"%s\" in cdpath"
+msgstr "E344: Adresár \"%s\" sa nedá nájs v cdpath"
+
+#, c-format
+msgid "E345: Can't find file \"%s\" in path"
+msgstr "E345: Súbor \"%s\" sa nepodarilo nájs"
+
+#, c-format
+msgid "E346: No more directory \"%s\" found in cdpath"
+msgstr "E346: Žiadny ïalší adresár \"%s\" nebol v cdpath nájdený"
+
+#, c-format
+msgid "E347: No more file \"%s\" found in path"
+msgstr "E347: Žiadny ïalší súbor \"%s\" nebol v ceste nájdený"
+
+#. Get here when the server can't be found.
+msgid "Cannot connect to Netbeans #2"
+msgstr "Nedá sa pripoji na Netbeans #2"
+
+msgid "Cannot connect to Netbeans"
+msgstr "Nedá sa pripoji na Netbeans"
+
+#, c-format
+msgid "E668: Wrong access mode for NetBeans connection info file: \"%s\""
+msgstr "E668: Zlé prístupové práva pre súbor s informáciami pre NetBeans spojenie: \"%s\""
+
+msgid "read from Netbeans socket"
+msgstr "èítanie z Netbeans soketu"
+
+msgid "E658: NetBeans connection lost for buffer %ld"
+msgstr "E658: Stratené NetBeans spojenie pre buffer %ld"
+
+msgid "E505: "
+msgstr "E505: "
+
+msgid "Warning: terminal cannot highlight"
+msgstr "Varovanie: terminál nepodporuje zvýrazòovanie"
+
+msgid "E348: No string under cursor"
+msgstr "E348: Pod kurzorom nie je žiadny reazec"
+
+msgid "E349: No identifier under cursor"
+msgstr "E349: Pod kurzorom nie je žiadny identifikátor"
+
+msgid "E352: Cannot erase folds with current 'foldmethod'"
+msgstr "E352: Pomocou 'foldmethod' sa nedá vymaza vnorenie"
+
+msgid "E664: changelist is empty"
+msgstr "E664: zoznam zmien je prázdny"
+
+msgid "E662: At start of changelist"
+msgstr "E662: Na zaèiatku zoznamu zmien"
+
+msgid "E663: At end of changelist"
+msgstr "E663: Na konci zoznamu zmien"
+
+msgid "Type :quit<Enter> to exit Vim"
+msgstr "Zadajte :quit<Enter> pre ukonèenie programu Vim"
+
+#, c-format
+msgid "1 line %sed 1 time"
+msgstr "poèet riadkov upravených naraz pomocou %s: 1"
+
+#, c-format
+msgid "1 line %sed %d times"
+msgstr "1 riadok upravený pomocou %s %d krát"
+
+#, c-format
+msgid "%ld lines %sed 1 time"
+msgstr "%ld riadkov upravených naraz pomocou %s"
+
+#, c-format
+msgid "%ld lines %sed %d times"
+msgstr "%ld riadkov upravených pomocou %s %d krát"
+
+#, c-format
+msgid "%ld lines to indent... "
+msgstr "%ld riadkov pre odsadenie..."
+
+msgid "1 line indented "
+msgstr "1 riadok odsadený "
+
+#, c-format
+msgid "%ld lines indented "
+msgstr "%ld riadkov odsadených "
+
+msgid "E748: No previously used register"
+msgstr "E748: Žiadny predtým používaný register"
+
+#. must display the prompt
+msgid "cannot yank; delete anyway"
+msgstr "nedá sa kopírova; napriek tomu vymazané"
+
+msgid "1 line changed"
+msgstr "1 riadok zmenený"
+
+#, c-format
+msgid "%ld lines changed"
+msgstr "%ld zmenených riadkov"
+
+#, c-format
+msgid "freeing %ld lines"
+msgstr "uvolòujem %ld riadkov"
+
+msgid "block of 1 line yanked"
+msgstr "skopírovaný blok 1 riadku"
+
+msgid "1 line yanked"
+msgstr "1 riadok skopírovaný"
+
+msgid "block of %ld lines yanked"
+msgstr "skopírovaný blok %ld riadkov"
+
+#, c-format
+msgid "%ld lines yanked"
+msgstr "%ld skopírovaných riadkov"
+
+#, c-format
+msgid "E353: Nothing in register %s"
+msgstr "E353: Register %s je prázdny"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Registers ---"
+msgstr ""
+"\n"
+"--- Registre ---"
+
+msgid "Illegal register name"
+msgstr "Neprípustný názov registra"
+
+#, c-format
+msgid ""
+"\n"
+"# Registers:\n"
+msgstr ""
+"\n"
+"# Registre:\n"
+
+msgid "E574: Unknown register type %d"
+msgstr "E574: Neznámy typ registra %d"
+
+#, c-format
+msgid "%ld Cols; "
+msgstr "%ld Ståpcov; "
+
+#, c-format
+msgid "Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Bytes"
+msgstr "Vybraných %s%ld z %ld Riadkov; %ld zo %ld Slov; %ld z %ld Bajtov"
+
+msgid ""
+"Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Chars; %ld of %ld "
+"Bytes"
+msgstr "Vybraných %s%ld z %ld Riadkov; %ld zo %ld Slov; %ld z %ld Znakov; %ld z %ld Bajtov"
+
+#, c-format
+msgid "Col %s of %s; Line %ld of %ld; Word %ld of %ld; Byte %ld of %ld"
+msgstr "Ståpec %s z %s; Riadok %ld z %ld; Slovo %ld z %ld; Bajt %ld z %ld"
+
+#, c-format
+msgid ""
+"Col %s of %s; Line %ld of %ld; Word %ld of %ld; Char %ld of %ld; Byte %ld of "
+"%ld"
+msgstr "Ståpec %s z %s; Riadok %ld z %ld; Slovo %ld z %ld; Znak %ld z %ld; Bajt %ld z %ld"
+
+#, c-format
+msgid "(+%ld for BOM)"
+msgstr "(+%ld pre BOM)"
+
+msgid "%<%f%h%m%=Page %N"
+msgstr "%<%f%h%m%=Strana %N"
+
+msgid "Thanks for flying Vim"
+msgstr "Ïakujeme za použitie Vim"
+
+msgid "E518: Unknown option"
+msgstr "E518: Neznáma vo¾ba"
+
+msgid "E519: Option not supported"
+msgstr "E519: Vo¾ba nie je podporovaná"
+
+msgid "E520: Not allowed in a modeline"
+msgstr "E520: Nie je v modeline povolené"
+
+msgid "E521: Number required after ="
+msgstr "E521: Po = je vyžadované èíslo"
+
+msgid "E522: Not found in termcap"
+msgstr "E522: Nenájdený v termcape"
+
+#, c-format
+msgid "E539: Illegal character <%s>"
+msgstr "E539: Neprípustný znak <%s>"
+
+msgid "E529: Cannot set 'term' to empty string"
+msgstr "E529: Vo¾ba 'term' nemôže by prázdna"
+
+msgid "E530: Cannot change term in GUI"
+msgstr "E530: V grafickom móde (GUI) sa nedá meni typ terminálu"
+
+msgid "E531: Use \":gui\" to start the GUI"
+msgstr "E531: Použite \"gui\" pre spustenie GUI"
+
+msgid "E589: 'backupext' and 'patchmode' are equal"
+msgstr "E589: vo¾by 'backupext' a 'patchmode' majú rovnakú hodnotu"
+
+msgid "E617: Cannot be changed in the GTK+ 2 GUI"
+msgstr "E617: Nedá sa zmeni v grafickom rozhraní GTK+ 2"
+
+msgid "E524: Missing colon"
+msgstr "E524: Chýba dvojbodka"
+
+msgid "E525: Zero length string"
+msgstr "E525: Reazec s nulovou dåžkou"
+
+#, c-format
+msgid "E526: Missing number after <%s>"
+msgstr "E526: Po <%s> chýba èíslo"
+
+msgid "E527: Missing comma"
+msgstr "E527: Chýba èiarka"
+
+msgid "E528: Must specify a ' value"
+msgstr "E528: Je nutné zada hodnotu '"
+
+msgid "E595: contains unprintable or wide character"
+msgstr "E595: obsahuje netlaèite¾né znaky"
+
+msgid "E596: Invalid font(s)"
+msgstr "E596: Chybné písma"
+
+msgid "E597: can't select fontset"
+msgstr "E597: nedá sa vybra sada písiem"
+
+msgid "E598: Invalid fontset"
+msgstr "E598: Chybná sada písiem"
+
+msgid "E533: can't select wide font"
+msgstr "E533: nedá sa vybra široký font"
+
+msgid "E534: Invalid wide font"
+msgstr "E534: Chybné široké písmo"
+
+#, c-format
+msgid "E535: Illegal character after <%c>"
+msgstr "E535: Neprípustný znak po <%c>"
+
+msgid "E536: comma required"
+msgstr "E536: je nutná èiarka"
+
+#, c-format
+msgid "E537: 'commentstring' must be empty or contain %s"
+msgstr "E537: 'commentstring' (komentár) musí by prázdny alebo musí obsahova %s"
+
+msgid "E538: No mouse support"
+msgstr "E538: Bez podpory myši"
+
+msgid "E540: Unclosed expression sequence"
+msgstr "E540: Neuzatvorené zoskupenie výrazov"
+
+msgid "E541: too many items"
+msgstr "E541: príliš mnoho položiek"
+
+msgid "E542: unbalanced groups"
+msgstr "E542: nevyvážené skupiny"
+
+msgid "E590: A preview window already exists"
+msgstr "E590: Okno náh¾adu už existuje"
+
+msgid "W17: Arabic requires UTF-8, do ':set encoding=utf-8'"
+msgstr "W17: Mód Arabic vyžaduje kódovanie UTF-8, nastavte to príkazom ':set encoding=utf-8'"
+
+#, c-format
+msgid "E593: Need at least %d lines"
+msgstr "E593: Minimálny potrebný poèet riadkov je %d"
+
+#, c-format
+msgid "E594: Need at least %d columns"
+msgstr "E594: Minimálne potrebný poèet ståpcov je %d"
+
+#, c-format
+msgid "E355: Unknown option: %s"
+msgstr "E355: Neznáma vo¾ba: %s"
+
+msgid ""
+"\n"
+"--- Terminal codes ---"
+msgstr ""
+"\n"
+"--- Kódy terminálu ---"
+
+msgid ""
+"\n"
+"--- Global option values ---"
+msgstr ""
+"\n"
+"--- Nastavenie globálnych volieb ---"
+
+msgid ""
+"\n"
+"--- Local option values ---"
+msgstr ""
+"\n"
+"--- Nastavenie lokálnych volieb ---"
+
+msgid ""
+"\n"
+"--- Options ---"
+msgstr ""
+"\n"
+"--- Možnosti ---"
+
+msgid "E356: get_varp ERROR"
+msgstr "E356: get_varp CHYBA"
+
+#, c-format
+msgid "E357: 'langmap': Matching character missing for %s"
+msgstr "E357: 'langmap': pre %s chýba vyhovujúci znak"
+
+#, c-format
+msgid "E358: 'langmap': Extra characters after semicolon: %s"
+msgstr "E358: 'langmap': nadbytoèné znaky po bodkoèiarke: %s"
+
+msgid "cannot open "
+msgstr "nedá sa otvori "
+
+msgid "VIM: Can't open window!\n"
+msgstr "VIM: Nedá sa otvori okno!\n"
+
+msgid "Need Amigados version 2.04 or later\n"
+msgstr "Je potrebná Amigados verzia 2.04 alebo novšia\n"
+
+#, c-format
+msgid "Need %s version %ld\n"
+msgstr "Potrebná %s verzia %ld\n"
+
+msgid "Cannot open NIL:\n"
+msgstr "Nedá sa otvori NIL:\n"
+
+msgid "Cannot create "
+msgstr "Nedá sa vytvori "
+
+#, c-format
+msgid "Vim exiting with %d\n"
+msgstr "Vim ukonèený s %d\n"
+
+msgid "cannot change console mode ?!\n"
+msgstr "nemôžem zmeni konzolový mód ?!\n"
+
+msgid "mch_get_shellsize: not a console??\n"
+msgstr "mch_get_shellsize: nie je konzolou??\n"
+
+#. if Vim opened a window: Executing a shell may cause crashes
+msgid "E360: Cannot execute shell with -f option"
+msgstr "E360: Nedá sa spusti shell s -f vo¾bou"
+
+msgid "Cannot execute "
+msgstr "Nedá sa spusti "
+
+msgid "shell "
+msgstr "shell "
+
+msgid " returned\n"
+msgstr " vrátené\n"
+
+msgid "ANCHOR_BUF_SIZE too small."
+msgstr "ANCHOR_BUF_SIZE príliš malá."
+
+msgid "I/O ERROR"
+msgstr "I/O CHYBA"
+
+msgid "...(truncated)"
+msgstr "...(skrátené)"
+
+msgid "'columns' is not 80, cannot execute external commands"
+msgstr "'ståpce' nie je 80, nemôžem spusti externý príkaz"
+
+msgid "E237: Printer selection failed"
+msgstr "E237: Zlyhal výber tlaèiarne"
+
+#, c-format
+msgid "to %s on %s"
+msgstr "%s na %s"
+
+#, c-format
+msgid "E613: Unknown printer font: %s"
+msgstr "E613: Neznámy font tlaèiarne: %s"
+
+#, c-format
+msgid "E238: Print error: %s"
+msgstr "E238: Chyba tlaèe: %s"
+
+#, c-format
+msgid "Printing '%s'"
+msgstr "Tlaèím '%s'"
+
+#, c-format
+msgid "E244: Illegal charset name \"%s\" in font name \"%s\""
+msgstr "E244: Chybný názov znakovej sady \"%s\" v názve písma \"%s\""
+
+#, c-format
+msgid "E245: Illegal char '%c' in font name \"%s\""
+msgstr "E245: Chybný znak '%c' v názve písma \"%s\""
+
+msgid "Vim: Double signal, exiting\n"
+msgstr "Vim: dvojitý signál, konèím\n"
+
+#, c-format
+msgid "Vim: Caught deadly signal %s\n"
+msgstr "Vim: Zachytený smrtiaci signál %s\n"
+
+#, c-format
+msgid "Vim: Caught deadly signal\n"
+msgstr "Vim: Zachytený smrtiaci signál\n"
+
+#, c-format
+msgid "Opening the X display took %ld msec"
+msgstr "Otvorenie X displej zabralo %ld msec"
+
+#. KDE sometimes produces X error that we want to ignore
+msgid ""
+"\n"
+"Vim: Got X error but we continue...\n"
+msgstr ""
+"\n"
+"Vim: Chyba X ale pokraèujem ...\n"
+
+msgid ""
+"\n"
+"Vim: Got X error\n"
+msgstr ""
+"\n"
+"Vim: Chyba X\n"
+
+msgid "Testing the X display failed"
+msgstr "Testovanie X displeja zlyhalo"
+
+msgid "Opening the X display timed out"
+msgstr "Uplynul èas otvorenia X displeja"
+
+msgid ""
+"\n"
+"Cannot execute shell "
+msgstr ""
+"\n"
+"Nedá sa spusti shell "
+
+msgid ""
+"\n"
+"Cannot execute shell sh\n"
+msgstr ""
+"\n"
+"Nedá sa spusti sh shell\n"
+
+msgid ""
+"\n"
+"shell returned "
+msgstr ""
+"\n"
+" návratová hodnota shellu "
+
+msgid ""
+"\n"
+"Cannot create pipes\n"
+msgstr ""
+"\n"
+"Nedjú sa vytvori rúry\n"
+
+msgid ""
+"\n"
+"Cannot fork\n"
+msgstr ""
+"\n"
+"Vyvolanie fork zlyhalo\n"
+
+msgid ""
+"\n"
+"Command terminated\n"
+msgstr ""
+"\n"
+"Príkaz ukonèený\n"
+
+msgid "XSMP lost ICE connection"
+msgstr "XSMP stratilo ICE spojenie"
+
+#, c-format
+msgid "dlerror = \"%s\""
+msgstr "dlerror = \"%s\""
+
+msgid "Opening the X display failed"
+msgstr "Otvorenie X displeja zlyhalo"
+
+msgid "XSMP handling save-yourself request"
+msgstr "XSMP spracuváva požiadavku na samouloženie"
+
+msgid "XSMP opening connection"
+msgstr "XSMP otvára spojenie"
+
+msgid "XSMP ICE connection watch failed"
+msgstr "XSMP kontrola spojenia ICE zlyhala"
+
+#, c-format
+msgid "XSMP SmcOpenConnection failed: %s"
+msgstr "XSMP SmcOpenConnection zlyhalo: %s"
+
+msgid "At line"
+msgstr "Na riadku"
+
+msgid "Could not load vim32.dll!"
+msgstr "Nemôžem nahra vim32.dll!"
+
+msgid "VIM Error"
+msgstr "VIM Chyba"
+
+msgid "Could not fix up function pointers to the DLL!"
+msgstr "Nemôžem opravi odkazy funkcií na DLL!"
+
+#, c-format
+msgid "shell returned %d"
+msgstr "návratová hodnota shellu %d"
+
+#, c-format
+msgid "Vim: Caught %s event\n"
+msgstr "Vim: Zachytená udalos %s\n"
+
+msgid "close"
+msgstr "zavrie"
+
+msgid "logoff"
+msgstr "odhlási"
+
+msgid "shutdown"
+msgstr "vypnú"
+
+msgid "E371: Command not found"
+msgstr "E371: Príkaz nenájdený"
+
+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 nenájdený v $PATH.\n"
+"Po dokonèení externých príkazov nebude výstup pozastavený.\n"
+"Pozrite :help win32-vimrun pre viac informácií."
+
+msgid "Vim Warning"
+msgstr "Vim Varovanie"
+
+#, c-format
+msgid "E372: Too many %%%c in format string"
+msgstr "E372: Príliš mnoho %%%c vo formátovacom reazci"
+
+#, c-format
+msgid "E373: Unexpected %%%c in format string"
+msgstr "E373: Neoèakávaný výskyt %%%c vo formátovacom reazci"
+
+msgid "E374: Missing ] in format string"
+msgstr "E374: Vo formátovacom reazci chýba ]"
+
+#, c-format
+msgid "E375: Unsupported %%%c in format string"
+msgstr ""
+"E375: Nepodporovaná formátová špecifikácia %%%c vo formátovacom reazci"
+
+#, c-format
+msgid "E376: Invalid %%%c in format string prefix"
+msgstr "E376: Neprístupné %%%c v prefixe formátovacieho reazca"
+
+#, c-format
+msgid "E377: Invalid %%%c in format string"
+msgstr "E377: Neprístupné %%%c vo formátovacom reazci"
+
+msgid "E378: 'errorformat' contains no pattern"
+msgstr "E378: 'errorformat' neobsahuje žiadny vzor"
+
+msgid "E379: Missing or empty directory name"
+msgstr "E379: Chýbajúci alebo prázdny názov adresára"
+
+msgid "E553: No more items"
+msgstr "E553: Žiadne ïalšie položky"
+
+#, c-format
+msgid "(%d of %d)%s%s: "
+msgstr "(%d z %d)%s%s: "
+
+msgid " (line deleted)"
+msgstr " (riadok vymazaný)"
+
+msgid "E380: At bottom of quickfix stack"
+msgstr "E380: Koniec quickfix zoznamu"
+
+msgid "E381: At top of quickfix stack"
+msgstr "E381: Zaèiatok quickfix zoznamu"
+
+#, c-format
+msgid "error list %d of %d; %d errors"
+msgstr "zoznam chýb %d z %d; %d chýb"
+
+msgid "E382: Cannot write, 'buftype' option is set"
+msgstr "E382: Nedá sa uloži, je nastavená vo¾ba 'buftype'"
+
+msgid "E683: File name missing or invalid pattern"
+msgstr "E683: Chýba meno súboru alebo chybný vzor"
+
+msgid "Cannot open file \"%s\""
+msgstr "Nedá sa otvori súbor \"%s\""
+
+msgid "E681: Buffer is not loaded"
+msgstr "E681: Buffer nie je naèítaný"
+
+#, c-format
+msgid "E369: invalid item in %s%%[]"
+msgstr "E369: chybná položka v %s%%[]"
+
+msgid "E339: Pattern too long"
+msgstr "E339: Vzor je príliš dlhý"
+
+msgid "E50: Too many \\z("
+msgstr "E50: Príliš mnoho \\z("
+
+#, c-format
+msgid "E51: Too many %s("
+msgstr "E51: Príliš mnoho %s("
+
+msgid "E52: Unmatched \\z("
+msgstr "E52: Nespárované \\z("
+
+#, c-format
+msgid "E53: Unmatched %s%%("
+msgstr "E53: Nespárované %s%%("
+
+#, c-format
+msgid "E54: Unmatched %s("
+msgstr "E54: Nespárované %s("
+
+#, c-format
+msgid "E55: Unmatched %s)"
+msgstr "E55: Nespárované %s)"
+
+#, c-format
+msgid "E59: invalid character after %s@"
+msgstr "E59: Neprípustný znak po %s@"
+
+#, c-format
+msgid "E60: Too many complex %s{...}s"
+msgstr "E60: Príliš komplexné %s{...}"
+
+#, c-format
+msgid "E61: Nested %s*"
+msgstr "E61: Vnorený %s*"
+
+#, c-format
+msgid "E62: Nested %s%c"
+msgstr "E62: Vnorený %s%c"
+
+msgid "E63: invalid use of \\_"
+msgstr "E63: Chybne použité \\_"
+
+#, c-format
+msgid "E64: %s%c follows nothing"
+msgstr "E64: %s%c niè nenasleduje"
+
+msgid "E65: Illegal back reference"
+msgstr "E65: Chybná spätná referencia"
+
+msgid "E66: \\z( not allowed here"
+msgstr "E66: \\z( tu nie je povolené"
+
+msgid "E67: \\z1 et al. not allowed here"
+msgstr "E67: \\z1 a spol. tu nie je povolené"
+
+msgid "E68: Invalid character after \\z"
+msgstr "E68: Neprípustný znak po \\z"
+
+#, c-format
+msgid "E69: Missing ] after %s%%["
+msgstr "E69: Chýbajúca ] po %s%%["
+
+#, c-format
+msgid "E70: Empty %s%%[]"
+msgstr "E70: Prázdny %s%%[]"
+
+#, c-format
+msgid "E678: Invalid character after %s%%[dxouU]"
+msgstr "E678: Neprípustný znak po %s%%[dxouU]"
+
+#, c-format
+msgid "E71: Invalid character after %s%%"
+msgstr "E71: Neprípustný znak po %s%%"
+
+#, c-format
+msgid "E769: Missing ] after %s["
+msgstr "E769: Chýbajúca ] po %s["
+
+#, c-format
+msgid "E554: Syntax error in %s{...}"
+msgstr "E554: Chyba syntaxe v %s{...}"
+
+msgid "External submatches:\n"
+msgstr "Vnútorné podradené zhody:\n"
+
+msgid " VREPLACE"
+msgstr " NAHRADI VERTIKÁLNE"
+
+msgid " REPLACE"
+msgstr " NAHRADI"
+
+msgid " REVERSE"
+msgstr " OBRÁTI"
+
+msgid " INSERT"
+msgstr " VLOŽI"
+
+msgid " (insert)"
+msgstr " (vloži)"
+
+msgid " (replace)"
+msgstr " (nahradi)"
+
+msgid " (vreplace)"
+msgstr " (nahradi vertikálne)"
+
+msgid " Hebrew"
+msgstr " Hebrejský"
+
+msgid " Arabic"
+msgstr " Arabský"
+
+msgid " (lang)"
+msgstr " (jazyk)"
+
+msgid " (paste)"
+msgstr " (vloži)"
+
+msgid " VISUAL"
+msgstr " VIZUÁLNE"
+
+msgid " VISUAL LINE"
+msgstr " VIZUÁLNY RIADOK"
+
+msgid " VISUAL BLOCK"
+msgstr " VIZUÁLNY BLOK"
+
+msgid " SELECT"
+msgstr " ZHODY"
+
+msgid " SELECT LINE"
+msgstr " OZNAÈ RIADOK"
+
+msgid " SELECT BLOCK"
+msgstr " OZNAÈ BLOK"
+
+msgid "recording"
+msgstr "nahrávam"
+
+#, c-format
+msgid "E383: Invalid search string: %s"
+msgstr "E383: Neprípustný h¾adaný reazec: %s"
+
+#, c-format
+msgid "E384: search hit TOP without match for: %s"
+msgstr "E384: h¾adanie dosiahlo zaèiatok bez nájdenia %s"
+
+#, c-format
+msgid "E385: search hit BOTTOM without match for: %s"
+msgstr "E385: h¾adanie dosiahlo koniec bez nájdenia %s"
+
+msgid "E386: Expected '?' or '/' after ';'"
+msgstr "E386: Po ';' oèakávam '?' alebo '/'"
+
+msgid " (includes previously listed match)"
+msgstr " (vrátane už vypísaných zhôd)"
+
+#. cursor at status line
+msgid "--- Included files "
+msgstr "--- Vložené súbory"
+
+msgid "not found "
+msgstr "nenájdené "
+
+msgid "in path ---\n"
+msgstr "v ceste ---\n"
+
+msgid " (Already listed)"
+msgstr " (Už vypísané)"
+
+msgid " NOT FOUND"
+msgstr " NENÁJDENÉ"
+
+#, c-format
+msgid "Scanning included file: %s"
+msgstr "Preh¾adávam vložené súbory: %s"
+
+msgid "E387: Match is on current line"
+msgstr "E387: Zhoda je na aktuálnom riadku"
+
+msgid "All included files were found"
+msgstr "Všetky vložené súbory boli nájdené"
+
+msgid "No included files"
+msgstr "Žiadne vložené súbory"
+
+msgid "E388: Couldn't find definition"
+msgstr "E388: Nedá sa nájs definícia"
+
+msgid "E389: Couldn't find pattern"
+msgstr "E389: Nedá sa nájs vzor"
+
+msgid "E759: Format error in spell file"
+msgstr "E759: Chyba formátovania v spell súbore (kontrola pravopisu)"
+
+msgid "E758: Truncated spell file"
+msgstr "E758: Odseknutý spell súbor (kontrola pravopisu)"
+
+#, c-format
+msgid "Trailing text in %s line %d: %s"
+msgstr "Prebytoèný text v %s na riadku %d: %s"
+
+#, c-format
+msgid "Affix name too long in %s line %d: %s"
+msgstr "Prípona príliœ dlhá v %s riadok %d: %s"
+
+msgid "E761: Format error in affix file FOL, LOW or UPP"
+msgstr "E761: Chyba formátovania v súbore prípon FOL, LOW alebo UPP (NASLEDUJE, MALÉ alebo VE¼KÉ)"
+
+msgid "E762: Character in FOL, LOW or UPP is out of range"
+msgstr "E762: Znak v FOL, LOW alebo UPP (NASLEDUJE, MALÉ alebo VE¼KÉ) je mimo rozsah"
+
+msgid "Compressing word tree..."
+msgstr "Robím kompresiu stromu slov..."
+
+msgid "E756: Spell checking is not enabled"
+msgstr "E756: Kontrola pravopisu nie je zapnutá"
+
+#, c-format
+msgid "Warning: Cannot find word list \"%s.%s.spl\" or \"%s.ascii.spl\""
+msgstr "Varovanie: Nemožno nájs zoznam slov \"%s.%s.spl\" alebo \"%s.ascii.spl\""
+
+#, c-format
+msgid "Reading spell file \"%s\""
+msgstr "Èítam slovníkový súbor \"%s\""
+
+msgid "E757: This does not look like a spell file"
+msgstr "E757: Toto sa nezdá by slovníkovým súborom"
+
+msgid "E771: Old spell file, needs to be updated"
+msgstr "E771: Starý slovníkový súbor, potrebuje by zaktualizovaný"
+
+msgid "E772: Spell file is for newer version of Vim"
+msgstr "E772: Slovníkový súbor je pre novšiu verziu Vim"
+
+msgid "E770: Unsupported section in spell file"
+msgstr "E770: Nepodporovaná sekcia v slovníkovom súbore"
+
+#, c-format
+msgid "Warning: region %s not supported"
+msgstr "Varovanie: región %s nie je podporovaný"
+
+#, c-format
+msgid "Reading affix file %s ..."
+msgstr "Naèítavam súbor s príponami %s ..."
+
+#, c-format
+msgid "Conversion failure for word in %s line %d: %s"
+msgstr "Konverzia slova zlyhala v %s riadok %d: %s"
+
+#, c-format
+msgid "Conversion in %s not supported: from %s to %s"
+msgstr "Konverzia v %s nie je podporovaná: z %s do %s"
+
+#, c-format
+msgid "Conversion in %s not supported"
+msgstr "Konverzia v %s nie je podporovaná"
+
+#, c-format
+msgid "Invalid value for FLAG in %s line %d: %s"
+msgstr "Neplatná hodnota pre príznak (FLAG) v %s riadok %d: %s"
+
+#, c-format
+msgid "FLAG after using flags in %s line %d: %s"
+msgstr "Príznak (FLAG) po použití príznakov v %s riadok %d: %s"
+
+#, c-format
+msgid "Character used for SLASH must be ASCII; in %s line %d: %s"
+msgstr "Znak použitý pre SLASH musí by ASCII; v %s riadok %d: %s"
+
+#, c-format
+msgid "Wrong COMPOUNDMAX value in %s line %d: %s"
+msgstr "Zlá hodnota COMPOUNDMAX v %s riadok %d: %s"
+
+#, c-format
+msgid "Wrong COMPOUNDMIN value in %s line %d: %s"
+msgstr "Zlá hodnota COMPOUNDMIN v %s riadok %d: %s"
+
+#, c-format
+msgid "Wrong COMPOUNDSYLMAX value in %s line %d: %s"
+msgstr "Zlá hodnota COMPOUNDSYLMAX v %s riadok %d: %s"
+
+#, c-format
+msgid "Different combining flag in continued affix block in %s line %d: %s"
+msgstr "Rozdielna kombinácia príznakov v nasledujúcom bloku prípon v %s riadok %d: %s"
+
+#, c-format
+msgid "Duplicate affix in %s line %d: %s"
+msgstr "Duplicitná prípona v %s riadok %d: %s"
+
+#, c-format
+msgid ""
+"Affix also used for BAD/RAR/KEP/NEEDAFFIX/NEEDCOMPOUND in %s line %d: %s"
+msgstr ""
+"Prípona použitá aj pre BAD/RAR/KEP/NEEDAFFIX/NEEDCOMPOUND in %s line %d: %s"
+
+#, c-format
+msgid "Expected Y or N in %s line %d: %s"
+msgstr "Oèakávane Y alebo N v %s riadok %d: %s"
+
+#, c-format
+msgid "Broken condition in %s line %d: %s"
+msgstr "Narušená podmienka v %s riadok %d: %s"
+
+#, c-format
+msgid "Expected REP count in %s line %d"
+msgstr "Oèakávam poèet REP v %s riadok %d"
+
+#, c-format
+msgid "Expected MAP count in %s line %d"
+msgstr "Oèakávam poèet MAP v %s riadok %d"
+
+#, c-format
+msgid "Duplicate character in MAP in %s line %d"
+msgstr "Opakovaný znak v MAP v %s riadok %d"
+
+#, c-format
+msgid "Unrecognized or duplicate item in %s line %d: %s"
+msgstr "Nerozpoznaná alebo opakujúca sa položka v %s riadok %d: %s"
+
+#, c-format
+msgid "Missing FOL/LOW/UPP line in %s"
+msgstr "Chýbajúci riadok FOL/LOW/UPP v %s"
+
+msgid "COMPOUNDSYLMAX used without SYLLABLE"
+msgstr "COMPOUNDSYLMAX použitý bez SYLLABLE"
+
+msgid "Too many postponed prefixes"
+msgstr "Príliš mnoho odložených prípon"
+
+msgid "Too many compound flags"
+msgstr "Príliš mnoho upravovacích príznakov"
+
+msgid "Too many postponed prefixes and/or compound flags"
+msgstr "Príliš mnoho odložených prípon a/alebo upravovacích príznakov"
+
+#, c-format
+msgid "Missing SOFO%s line in %s"
+msgstr "Chýba SOFO%s riadok v %s"
+
+#, c-format
+msgid "Both SAL and SOFO lines in %s"
+msgstr "SAL a SOFO riadky zároveò v %s"
+
+#, c-format
+msgid "Flag is not a number in %s line %d: %s"
+msgstr "Príznak nie je èíslo v %s na riadku %d: %s"
+
+#, c-format
+msgid "Illegal flag in %s line %d: %s"
+msgstr "Neprípustný príznak v %s riadok %d: %s"
+
+#, c-format
+msgid "%s value differs from what is used in another .aff file"
+msgstr "Hodnota %s sa odlišuje od hodnoty použitej v inom .aff súbore"
+
+#, c-format
+msgid "Reading dictionary file %s ..."
+msgstr "Naèítavam slovník %s ..."
+
+#, c-format
+msgid "E760: No word count in %s"
+msgstr "E760: Chýajúci poèet slov v %s"
+
+#, c-format
+msgid "line %6d, word %6d - %s"
+msgstr "riadok %6d, slovo %6d - %s"
+
+#, c-format
+msgid "Duplicate word in %s line %d: %s"
+msgstr "Opakujúce sa slovo v %s riadok %d: %s"
+
+#, c-format
+msgid "First duplicate word in %s line %d: %s"
+msgstr "Prvé duplicitné slovo v %s riadok %d: %s"
+
+#, c-format
+msgid "%d duplicate word(s) in %s"
+msgstr "%d duplicitné slovo(á) v %s"
+
+#, c-format
+msgid "Ignored %d word(s) with non-ASCII characters in %s"
+msgstr "Ignorovaných %d slov s nepísmennými znakmi v %s"
+
+#, c-format
+msgid "Reading word file %s ..."
+msgstr "Naèítavam súbor so slovami %s ..."
+
+#, c-format
+msgid "Duplicate /encoding= line ignored in %s line %d: %s"
+msgstr "Duplicitný riadok /encoding= v %s riadok %d ignorovaný: %s "
+
+#, c-format
+msgid "/encoding= line after word ignored in %s line %d: %s"
+msgstr "/encoding= riadok nasledujúci po slove v %s riadok %d ignorovaný: %s"
+
+#, c-format
+msgid "Duplicate /regions= line ignored in %s line %d: %s"
+msgstr "Duplicitný riadok /regions= v %s riadok %d ignorovaný: %s"
+
+#, c-format
+msgid "Too many regions in %s line %d: %s"
+msgstr "Príliš mnoho regiónov v %s riadok %d: %s"
+
+#, c-format
+msgid "/ line ignored in %s line %d: %s"
+msgstr "Riadok / v %s riadok %d ignorovaný: %s"
+
+#, c-format
+msgid "Invalid region nr in %s line %d: %s"
+msgstr "Použíté chybné èíslo regiónu v %s riadok %d: %s"
+
+#, c-format
+msgid "Unrecognized flags in %s line %d: %s"
+msgstr "Nerozpoznaný príznak v %s riadok %d: %s"
+
+#, c-format
+msgid "Ignored %d words with non-ASCII characters"
+msgstr "Ignorovaných %d slov s nepísmennými znakmi"
+
+#, c-format
+msgid "Compressed %d of %d nodes; %d%% remaining"
+msgstr "Skomprimovaných %d z %d uzlov; %d%% zostáva"
+
+msgid "E751: Output file name must not have region name"
+msgstr "E751: Výstupné meno súboru nesmie ma názov regiónu"
+
+msgid "E754: Only up to 8 regions supported"
+msgstr "E754: Podporovaných max. 8 regiónov"
+
+#, c-format
+msgid "E755: Invalid region in %s"
+msgstr "E755: Chybný región v %s"
+
+msgid "Warning: both compounding and NOBREAK specified"
+msgstr "Varovanie: špecifikované spájanie a nezalamovanie"
+
+#, c-format
+msgid "Writing spell file %s ..."
+msgstr "Ukládám slovníkový súbor %s ..."
+
+msgid "Done!"
+msgstr "Hotovo!"
+
+#, c-format
+msgid "Estimated runtime memory use: %d bytes"
+msgstr "Ve¾kos používanej pamäte: %d bajtov"
+
+#, c-format
+msgid "E765: 'spellfile' does not have %ld entries"
+msgstr "E765: 'spellfile' nemá %ld položiek"
+
+msgid "E763: Word characters differ between spell files"
+msgstr "E763: Znaky slov sa odlišujú medzi slovníkovými súbormi"
+
+msgid "Sorry, no suggestions"
+msgstr "Prepáète, žiadne návrhy"
+
+#, c-format
+msgid "Sorry, only %ld suggestions"
+msgstr "Prepáète, iba %ld návrhov"
+
+#. avoid more prompt
+#, c-format
+msgid "Change \"%.*s\" to:"
+msgstr "Zmeni \"%.*s\" na:"
+
+#, c-format
+msgid " < \"%.*s\""
+msgstr " < \"%.*s\""
+
+msgid "E752: No previous spell replacement"
+msgstr "E752: Žiadny predchádzajúce nahradenie pod¾a slovníka"
+
+#, c-format
+msgid "E753: Not found: %s"
+msgstr "E753: Nenájdené: %s"
+
+#. This should have been checked when generating the .spl
+#. * file.
+msgid "E783: duplicate char in MAP entry"
+msgstr "E783: duplicitný znak v MAP položke"
+
+#, c-format
+msgid "E390: Illegal argument: %s"
+msgstr "E390: Neprípustný argument: %s"
+
+#, c-format
+msgid "E391: No such syntax cluster: %s"
+msgstr "E391: Syntaktická zostava %s neexistuje"
+
+msgid "No Syntax items defined for this buffer"
+msgstr "Pre tento buffer nie sú definované žiadne položky syntaxe"
+
+msgid "syncing on C-style comments"
+msgstr "synchronizujem pod¾a komentárov jazyka C"
+
+msgid "no syncing"
+msgstr "žiadne synchronizácie"
+
+msgid "syncing starts "
+msgstr "synchronizácia zaèína "
+
+msgid " lines before top line"
+msgstr " riadkov pred zaèiatkom"
+
+msgid ""
+"\n"
+"--- Syntax sync items ---"
+msgstr ""
+"\n"
+"--- Položky synchronizácie syntaxe ---"
+
+msgid ""
+"\n"
+"syncing on items"
+msgstr ""
+"\n"
+"synchronizujem položky"
+
+msgid ""
+"\n"
+"--- Syntax items ---"
+msgstr ""
+"\n"
+"--- Položky syntaxe ---"
+
+#, c-format
+msgid "E392: No such syntax cluster: %s"
+msgstr "E392: Syntaktická zostava %s neexistuje"
+
+msgid "minimal "
+msgstr "minimálne "
+
+msgid "maximal "
+msgstr "maximálne "
+
+msgid "; match "
+msgstr "; zhoda "
+
+msgid " line breaks"
+msgstr " zalomení riadkov"
+
+msgid "E395: contains argument not accepted here"
+msgstr "E395: obsahuje argumenty, ktoré tu nie sú povolené"
+
+msgid "E396: containedin argument not accepted here"
+msgstr "E396: obsahuje argumenty, ktoré tu nie sú povolené"
+
+msgid "E393: group[t]here not accepted here"
+msgstr "E393: group[t]here nesmie by na tomto mieste"
+
+#, c-format
+msgid "E394: Didn't find region item for %s"
+msgstr "E394: Pre %s chýba položka regiónu"
+
+msgid "E397: Filename required"
+msgstr "E397: Vyžadovaný názov súboru"
+
+#, c-format
+msgid "E789: Missing ']': %s"
+msgstr "E789: Chýba ']': %s"
+
+#, c-format
+msgid "E398: Missing '=': %s"
+msgstr "E398: Chýba '=': %s"
+
+#, c-format
+msgid "E399: Not enough arguments: syntax region %s"
+msgstr "E399: Príliš málo argumentov: oblas syntaxe %s"
+
+msgid "E400: No cluster specified"
+msgstr "E400: Nebola zadaná žiadna zostava"
+
+#, c-format
+msgid "E401: Pattern delimiter not found: %s"
+msgstr "E401: Odde¾ovaè vzoru %s nenájdený"
+
+#, c-format
+msgid "E402: Garbage after pattern: %s"
+msgstr "E402: Chyba za vzorom: %s"
+
+msgid "E403: syntax sync: line continuations pattern specified twice"
+msgstr "E403: synchronizácia syntaxe: vzor pokraèovania riadkov zadaný dvakrát"
+
+#, c-format
+msgid "E404: Illegal arguments: %s"
+msgstr "E404: Chybné argumenty: %s"
+
+#, c-format
+msgid "E405: Missing equal sign: %s"
+msgstr "E405: Chýba znamienko rovná sa: %s"
+
+#, c-format
+msgid "E406: Empty argument: %s"
+msgstr "E406: Prázdny argument: %s"
+
+#, c-format
+msgid "E407: %s not allowed here"
+msgstr "E407: %s tu nie je povolené"
+
+#, c-format
+msgid "E408: %s must be first in contains list"
+msgstr "E408: %s musí by prvý v 'contains' zozname"
+
+#, c-format
+msgid "E409: Unknown group name: %s"
+msgstr "E409: Neznámy názov skupiny: %s"
+
+#, c-format
+msgid "E410: Invalid :syntax subcommand: %s"
+msgstr "E410: Chybný podradený príkaz :syntax : %s "
+
+msgid "E679: recursive loop loading syncolor.vim"
+msgstr "E679: rekurzívna sluèka pri naèítavaní syncolor.vim"
+
+#, c-format
+msgid "E411: highlight group not found: %s"
+msgstr "E411: skupina zvýraznenia %s nebola nájdená"
+
+#, c-format
+msgid "E412: Not enough arguments: \":highlight link %s\""
+msgstr "E412: Príliš málo argumentov: \":highlight link %s\""
+
+#, c-format
+msgid "E413: Too many arguments: \":highlight link %s\""
+msgstr "E413: Príliš mnoho argumentov: \":highlight link %s\""
+
+msgid "E414: group has settings, highlight link ignored"
+msgstr "E414: skupina je nastavená, odkaz na zvýrazòovaciu skupinu ignorovaný"
+
+#, c-format
+msgid "E415: unexpected equal sign: %s"
+msgstr "E415: neoèakávané znamienko rovná sa: %s"
+
+#, c-format
+msgid "E416: missing equal sign: %s"
+msgstr "E416: chýba znamienko rovná sa: %s"
+
+#, c-format
+msgid "E417: missing argument: %s"
+msgstr "E417: chýba argument: %s"
+
+#, c-format
+msgid "E418: Illegal value: %s"
+msgstr "E418: Neprípustná hodnota: %s"
+
+msgid "E419: FG color unknown"
+msgstr "E419: farba popredia nie je známa"
+
+msgid "E420: BG color unknown"
+msgstr "E420: farba pozadia nie je známa"
+
+#, c-format
+msgid "E421: Color name or number not recognized: %s"
+msgstr "E421: Názov alebo èíslo farby nebolo rozpoznané: %s"
+
+#, c-format
+msgid "E422: terminal code too long: %s"
+msgstr "E422: terminálový kód je príliš dlhý: %s"
+
+#, c-format
+msgid "E423: Illegal argument: %s"
+msgstr "E423: Neprípustný argument: %s"
+
+msgid "E424: Too many different highlighting attributes in use"
+msgstr "E424: Používaných príliš ve¾a odlišných zvýrazòovacích vlastností"
+
+msgid "E669: Unprintable character in group name"
+msgstr "E669: Netlaèitelný znak v mene skupiny"
+
+msgid "W18: Invalid character in group name"
+msgstr "W18: Chybný znak v mene skupiny"
+
+msgid "E555: at bottom of tag stack"
+msgstr "E555: na konci zoznamu tagov"
+
+msgid "E556: at top of tag stack"
+msgstr "E556: na zaèiatku zoznamu tagov"
+
+msgid "E425: Cannot go before first matching tag"
+msgstr "E425: Nedá sa skoèi pred prvý vyhovujúci tag"
+
+#, c-format
+msgid "E426: tag not found: %s"
+msgstr "E426: tag %s nenájdený"
+
+msgid " # pri kind tag"
+msgstr " # pri typ tag"
+
+msgid "file\n"
+msgstr "súbor\n"
+
+msgid "E427: There is only one matching tag"
+msgstr "E427: Vyhovuje iba jeden tag"
+
+msgid "E428: Cannot go beyond last matching tag"
+msgstr "E428: Za posledný vyhovujúci tag sa nedá preskoèi"
+
+#, c-format
+msgid "File \"%s\" does not exist"
+msgstr "Súbor \"%s\" neexistuje"
+
+#. Give an indication of the number of matching tags
+#, c-format
+msgid "tag %d of %d%s"
+msgstr "tag %d z %d%s"
+
+msgid " or more"
+msgstr " alebo viac"
+
+msgid " Using tag with different case!"
+msgstr " Používam tag s písmom inej ve¾kosti!"
+
+#, c-format
+msgid "E429: File \"%s\" does not exist"
+msgstr "E429: Súbor \"%s\" neexistuje"
+
+#. Highlight title
+msgid ""
+"\n"
+" # TO tag FROM line in file/text"
+msgstr ""
+"\n"
+" # CIE¼ tag ŠTART riadok v súbore/texte"
+
+#, c-format
+msgid "Searching tags file %s"
+msgstr "Preh¾adávam súbor tagov %s"
+
+#, c-format
+msgid "E430: Tag file path truncated for %s\n"
+msgstr "E430: Cesta k súboru tagov %s bola orezaná\n"
+
+#, c-format
+msgid "E431: Format error in tags file \"%s\""
+msgstr "E431: Chyba formátovania v súbore tagov \"%s\""
+
+#, c-format
+msgid "Before byte %ld"
+msgstr "Pred bajtom %ld"
+
+#, c-format
+msgid "E432: Tags file not sorted: %s"
+msgstr "E432: Obsah súboru tagov %s nie je zoradený"
+
+#. never opened any tags file
+msgid "E433: No tags file"
+msgstr "E433: Žiadny súbor tagov"
+
+msgid "E434: Can't find tag pattern"
+msgstr "E434: Nedá sa nájs vzor tagov"
+
+msgid "E435: Couldn't find tag, just guessing!"
+msgstr "E435: Tag sa nedá nájs, iba hádam!"
+
+msgid "' not known. Available builtin terminals are:"
+msgstr "' nie je známy. Dostupné vstavané terminály:"
+
+msgid "defaulting to '"
+msgstr "nastavujem na '"
+
+msgid "E557: Cannot open termcap file"
+msgstr "E557: Nedá sa otvori termcap súbor"
+
+msgid "E558: Terminal entry not found in terminfo"
+msgstr "E558: Terminfo neobsahuje položku pre tento terminál"
+
+msgid "E559: Terminal entry not found in termcap"
+msgstr "E559: Termcap neobsahuje položku pre tento terminál"
+
+#, c-format
+msgid "E436: No \"%s\" entry in termcap"
+msgstr "E436: Termcap neobsahuje položku \"%s\""
+
+msgid "E437: terminal capability \"cm\" required"
+msgstr "E437: Terminál musí ma schopnos \"cm\" (schopnos pohybu kurzora)"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Terminal keys ---"
+msgstr ""
+"\n"
+"--- Klávesy terminálu ---"
+
+msgid "new shell started\n"
+msgstr "spustený nový shell\n"
+
+msgid "Vim: Error reading input, exiting...\n"
+msgstr "Vim: Chyba pri èítaní vstupu, konèím...\n"
+
+#. must display the prompt
+msgid "No undo possible; continue anyway"
+msgstr "Odstránenie zmien nie je možné; chcete napriek tomu pokraèova"
+
+msgid "E438: u_undo: line numbers wrong"
+msgstr "E438: u_undo: èísla riadkov sú chybné"
+
+msgid "1 change"
+msgstr "1 zmena"
+
+#, c-format
+msgid "%ld changes"
+msgstr "%ld zmien"
+
+msgid "E439: undo list corrupt"
+msgstr "E439: záznam o zmenách poškodený"
+
+msgid "E440: undo line missing"
+msgstr "E440: chýba opravný riadok"
+
+#. Only MS VC 4.1 and earlier can do Win32s
+msgid ""
+"\n"
+"MS-Windows 16/32-bit GUI version"
+msgstr ""
+"\n"
+"16/32 bitová GUI verzia pre MS Windows"
+
+msgid ""
+"\n"
+"MS-Windows 32-bit GUI version"
+msgstr ""
+"\n"
+"32 bitová GUI verzia pre MS Windows"
+
+msgid " in Win32s mode"
+msgstr " vo Win32 režime"
+
+msgid " with OLE support"
+msgstr " s OLE podporou"
+
+msgid ""
+"\n"
+"MS-Windows 32-bit console version"
+msgstr ""
+"\n"
+"32 bitová verzia pre MS Windows konzolu"
+
+msgid ""
+"\n"
+"MS-Windows 16-bit version"
+msgstr ""
+"\n"
+"16 bitová verzia pre MS Windows"
+
+msgid ""
+"\n"
+"32-bit MS-DOS version"
+msgstr ""
+"\n"
+"32 bitová verzia pre MS-DOS"
+
+msgid ""
+"\n"
+"16-bit MS-DOS version"
+msgstr ""
+"\n"
+"16 bitová MS-DOS verzia"
+
+msgid ""
+"\n"
+"MacOS X (unix) version"
+msgstr ""
+"\n"
+"MacOS X (unix) verzia"
+
+msgid ""
+"\n"
+"MacOS X version"
+msgstr ""
+"\n"
+"MacOS X verzia"
+
+msgid ""
+"\n"
+"MacOS version"
+msgstr ""
+"\n"
+"MacOS verzia"
+
+msgid ""
+"\n"
+"RISC OS version"
+msgstr ""
+"\n"
+"RISC OS verzia"
+
+msgid ""
+"\n"
+"Included patches: "
+msgstr ""
+"\n"
+"Použité záplaty: "
+
+msgid "Modified by "
+msgstr "Zmenil "
+
+msgid ""
+"\n"
+"Compiled "
+msgstr ""
+"\n"
+"Preložená "
+
+msgid "by "
+msgstr " "
+
+msgid ""
+"\n"
+"Huge version "
+msgstr ""
+"\n"
+"Maximálna verzia"
+
+msgid ""
+"\n"
+"Big version "
+msgstr ""
+"\n"
+"Ve¾ká verzia "
+
+msgid ""
+"\n"
+"Normal version "
+msgstr ""
+"\n"
+"Normálna verzia"
+
+msgid ""
+"\n"
+"Small version "
+msgstr ""
+"\n"
+"Malá verzia "
+
+msgid ""
+"\n"
+"Tiny version "
+msgstr ""
+"\n"
+"Minimálna verzia "
+
+msgid "without GUI."
+msgstr "bez grafického rozhrania."
+
+msgid "with GTK2-GNOME GUI."
+msgstr "s grafickým rozhraním GTK2-GNOME."
+
+msgid "with GTK-GNOME GUI."
+msgstr "s grafickým rozhraním GTK-GNOME."
+
+msgid "with GTK2 GUI."
+msgstr "s grafickým rozhraním GTK2."
+
+msgid "with GTK GUI."
+msgstr "s grafickým rozhraním GTK."
+
+msgid "with X11-Motif GUI."
+msgstr "s grafickým rozhraním X11-Motif."
+
+msgid "with X11-neXtaw GUI."
+msgstr "s grafickým rozhraním X11-neXtaw."
+
+msgid "with X11-Athena GUI."
+msgstr "s grafickým rozhraním X11-Athena."
+
+msgid "with Photon GUI."
+msgstr "s grafickým rozhraním Photon."
+
+msgid "with GUI."
+msgstr "s grafickým rozhraním."
+
+msgid "with Carbon GUI."
+msgstr "s grafickým rozhraním Carbon."
+
+msgid "with Cocoa GUI."
+msgstr "s grafickým rozhraním Cocoa."
+
+msgid "with (classic) GUI."
+msgstr "s klasickým grafickým rozhraním."
+
+msgid "with KDE GUI."
+msgstr "s grafickým rozhraním KDE."
+
+msgid " Features included (+) or not (-):\n"
+msgstr " Vlastnosti zahrnuté (+) a nezahrnuté (-):\n"
+
+msgid " system vimrc file: \""
+msgstr " systémový vimrc súbor: \""
+
+msgid " user vimrc file: \""
+msgstr " užívate¾ský vimrc súbor: \""
+
+msgid " 2nd user vimrc file: \""
+msgstr " druhý užívate¾ský vimrc súbor: \""
+
+msgid " 3rd user vimrc file: \""
+msgstr " tretí užívate¾ský vimrc súbor: \""
+
+msgid " user exrc file: \""
+msgstr " užívate¾ský exrc súbor: \""
+
+msgid " 2nd user exrc file: \""
+msgstr " druhý užívate¾ský exrc súbor: \""
+
+msgid " system gvimrc file: \""
+msgstr " systémový gvimrc súbor: \""
+
+msgid " user gvimrc file: \""
+msgstr " užívate¾ský gvimrc súbor: \""
+
+msgid "2nd user gvimrc file: \""
+msgstr "druhý užívate¾ský gvimrc súbor: \""
+
+msgid "3rd user gvimrc file: \""
+msgstr "tretí užívate¾ský gvimrc súbor: \""
+
+msgid " system menu file: \""
+msgstr " systémový súbor s ponukou: \""
+
+msgid " fall-back for $VIM: \""
+msgstr " implicitná hodnota $VIM:\""
+
+msgid " f-b for $VIMRUNTIME: \""
+msgstr " f-b pre $VIMRUNTIME: \""
+
+msgid "Compilation: "
+msgstr "Preklad: "
+
+msgid "Compiler: "
+msgstr "Prekladaè: "
+
+msgid "Linking: "
+msgstr "Zlinkované: "
+
+msgid " DEBUG BUILD"
+msgstr " PODPORA LADENIA"
+
+msgid "VIM - Vi IMproved"
+msgstr "VIM - Vi IMproved"
+
+msgid "version "
+msgstr "verzia "
+
+msgid "by Bram Moolenaar et al."
+msgstr "od Brama Moolenaara a ïalších"
+
+msgid "Vim is open source and freely distributable"
+msgstr "Vim je vo¾ne šírite¾ný program s otvoreným kódom"
+
+msgid "Help poor children in Uganda!"
+msgstr "Pomôžte chudobným deom v Ugande!"
+
+msgid "type :help iccf<Enter> for information "
+msgstr "zadajte :help iccf<Enter> pre informácie "
+
+msgid "type :q<Enter> to exit "
+msgstr "zadajte :q<Enter> pre ukonèenie programu "
+
+msgid "type :help<Enter> or <F1> for on-line help"
+msgstr "zadajte :help<Enter> alebo <F1> pre pomocníka "
+
+msgid "type :help version7<Enter> for version info"
+msgstr "zadajte :help version7<Enter> pre informácie o verzii"
+
+msgid "Running in Vi compatible mode"
+msgstr "Pracujem v režime kompatibility s Vi"
+
+msgid "type :set nocp<Enter> for Vim defaults"
+msgstr "zadajte :set nocp<Enter> pre implicitné nastavenie Vim"
+
+msgid "type :help cp-default<Enter> for info on this"
+msgstr "podrobnejšie informácie získate pomocou :help cp-default<Enter>"
+
+msgid "menu Help->Orphans for information "
+msgstr "bližšie informácie v ponuke Pomocník->Samostatné"
+
+msgid "Running modeless, typed text is inserted"
+msgstr "Spúšam v bezmódovom režime, písaný text je vložený"
+
+msgid "menu Edit->Global Settings->Toggle Insert Mode "
+msgstr "ponuka Úpravy->Globálne možnosti->Prepnú režim vloženia "
+
+msgid " for two modes "
+msgstr " pre dva režimy "
+
+msgid "menu Edit->Global Settings->Toggle Vi Compatible"
+msgstr "ponuka Úpravy->Globálne možnostt->Prepnú Vi kompatibilný režim"
+
+msgid " for Vim defaults "
+msgstr " pre predvolené vlastnosti Vim "
+
+msgid "Sponsor Vim development!"
+msgstr "Zasponzorujte vývoj Vimu!"
+
+msgid "Become a registered Vim user!"
+msgstr "Staòte sa registrovaným užívate¾om Vimu!"
+
+msgid "type :help sponsor<Enter> for information "
+msgstr "zadajte :help sponsor<Enter> pre informácie "
+
+msgid "type :help register<Enter> for information "
+msgstr "zadajte :help register<Enter> pre informácie "
+
+msgid "menu Help->Sponsor/Register for information "
+msgstr "bližšie informácie v ponuke Pomocník->Sponzor/Registrácia"
+
+msgid "WARNING: Windows 95/98/ME detected"
+msgstr "VAROVANIE: detekované Windows 95/98/ME"
+
+msgid "type :help windows95<Enter> for info on this"
+msgstr "zadajte :help windows95<Enter> pre podrobnejšie informácie"
+
+msgid "E441: There is no preview window"
+msgstr "E441: Nenájdené žiadne okno náh¾adu"
+
+msgid "E442: Can't split topleft and botright at the same time"
+msgstr ""
+"E442: Okno sa nedá rozdeli zároveò v móde 'vrchný-¾avý' a 'spodný-"
+"pravý' ('topleft' a 'botright')"
+
+msgid "E443: Cannot rotate when another window is split"
+msgstr "E443: Nedá sa rotova, ak je iné okno rozdelené"
+
+msgid "E444: Cannot close last window"
+msgstr "E444: Posledné okno sa nedá zatvori"
+
+msgid "Already only one window"
+msgstr "Existuje už iba jedno okno"
+
+msgid "E445: Other window contains changes"
+msgstr "E445: Iné okno obsahuje zmeny"
+
+msgid "E446: No file name under cursor"
+msgstr "E446: Pod kurzorom sa nenachádza názov súboru"
+
+#, c-format
+msgid "E447: Can't find file \"%s\" in path"
+msgstr "E447: Súbor \"%s\" sa nedá nájs v ceste"
+
+#, c-format
+msgid "E370: Could not load library %s"
+msgstr "E370: Nepodarilo sa nahra knižnicu %s"
+
+msgid "Sorry, this command is disabled: the Perl library could not be loaded."
+msgstr "Prepáète, tento príkaz je vypnutý, Perl knižnica nemôže by naèítaná."
+
+msgid "E299: Perl evaluation forbidden in sandbox without the Safe module"
+msgstr "E299: Vykonanie kódu v jazyku Perl nie je možné v bezpeènostnej schránke bez bezpeènostného modulu"
+
+msgid "Edit with &multiple Vims"
+msgstr "Upravi s viacerý&mi Vimmi"
+
+msgid "Edit with single &Vim"
+msgstr "Upravi s jedným &Vimom"
+
+msgid "Diff with Vim"
+msgstr "Porovna &Vimom"
+
+msgid "Edit with &Vim"
+msgstr "Upravi s &Vimom"
+
+#. Now concatenate
+msgid "Edit with existing Vim - "
+msgstr "Upravi s existujúcim Vimom - "
+
+msgid "Edits the selected file(s) with Vim"
+msgstr "Upravi vybrané súbory s Vimom"
+
+msgid "Error creating process: Check if gvim is in your path!"
+msgstr "Chyba vytvárania procesu: Skontrolujte, èi je gvim vo vašej ceste!"
+
+msgid "gvimext.dll error"
+msgstr "chyba gvimext.dll"
+
+msgid "Path length too long!"
+msgstr "Príliš dlhá cesta!"
+
+msgid "--No lines in buffer--"
+msgstr "--Buffer neobsahuje žiadne riadky--"
+
+#.
+#. * 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: Príkaz prerušený"
+
+msgid "E471: Argument required"
+msgstr "E471: Je vyžadovaný argument"
+
+msgid "E10: \\ should be followed by /, ? or &"
+msgstr "E10: po \\ by malo nasledova /, ? alebo &"
+
+msgid "E11: Invalid in command-line window; <CR> executes, CTRL-C quits"
+msgstr ""
+"E11: Chybný príkaz v okne príkazového riadku; <Enter> spúša, CTRL-C ukonèuje"
+
+msgid "E12: Command not allowed from exrc/vimrc in current dir or tag search"
+msgstr ""
+"E12: Príkaz nie je z exrc/vimrc v aktuálnom adresári alebo pri h¾adaní tagu "
+"povolený."
+
+msgid "E171: Missing :endif"
+msgstr "E171: Chýba :endif"
+
+msgid "E600: Missing :endtry"
+msgstr "E600: Chýba :endtry"
+
+msgid "E170: Missing :endwhile"
+msgstr "E170: Chýba :endwhile"
+
+msgid "E170: Missing :endfor"
+msgstr "E170: Chýba :endfor"
+
+msgid "E588: :endwhile without :while"
+msgstr "E588: :endwhile bez zodpovedajúceho :while"
+
+msgid "E588: :endfor without :for"
+msgstr "E588: :endfor bez zodpovedajúceho :for"
+
+msgid "E13: File exists (add ! to override)"
+msgstr "E13: Súbor existuje (použite ! pre prepísanie)"
+
+msgid "E472: Command failed"
+msgstr "E472: Príkaz zlyhal"
+
+#, c-format
+msgid "E234: Unknown fontset: %s"
+msgstr "E234: Neznáma sada písiem: %s"
+
+#, c-format
+msgid "E235: Unknown font: %s"
+msgstr "E235: Neznáme písmo: %s"
+
+#, c-format
+msgid "E236: Font \"%s\" is not fixed-width"
+msgstr "E236: Písmo \"%s\" nemá pevnú šírku"
+
+msgid "E473: Internal error"
+msgstr "E473: Vnútorná chyba"
+
+msgid "Interrupted"
+msgstr "Prerušené"
+
+msgid "E14: Invalid address"
+msgstr "E14: Chybná adresa"
+
+msgid "E474: Invalid argument"
+msgstr "E474: Chybný argument"
+
+#, c-format
+msgid "E475: Invalid argument: %s"
+msgstr "E475: Chybný argument: %s"
+
+#, c-format
+msgid "E15: Invalid expression: %s"
+msgstr "E15: Chybný výraz: %s"
+
+msgid "E16: Invalid range"
+msgstr "E16: Chybný rozsah"
+
+msgid "E476: Invalid command"
+msgstr "E476: Chybný príkaz"
+
+#, c-format
+msgid "E17: \"%s\" is a directory"
+msgstr "E17: \"%s\" je adresárom"
+
+#, c-format
+msgid "E364: Library call failed for \"%s()\""
+msgstr "E364: Vyvolanie knižniènej funkcia zlyhalo pre \"%s()\""
+
+#, c-format
+msgid "E448: Could not load library function %s"
+msgstr "E448: Nepodarilo sa nahra funkciu knižnice %s"
+
+msgid "E19: Mark has invalid line number"
+msgstr "E19: Znaèka má chybné èíslo riadku"
+
+msgid "E20: Mark not set"
+msgstr "E20: Znaèka nie je nastavená"
+
+msgid "E21: Cannot make changes, 'modifiable' is off"
+msgstr "E21: Nemožno robi zmeny, vo¾ba 'modifiable' je vypnutá"
+
+msgid "E22: Scripts nested too deep"
+msgstr "E22: Skripty vnorené príliš hlboko"
+
+msgid "E23: No alternate file"
+msgstr "E23: Žiadny alternatívny súbor"
+
+msgid "E24: No such abbreviation"
+msgstr "E24: Taká skratka neexistuje"
+
+msgid "E477: No ! allowed"
+msgstr "E477: ! nie je povolený"
+
+msgid "E25: GUI cannot be used: Not enabled at compile time"
+msgstr "E25: Nedá sa použí GUI: nebolo zapnuté pri preklade programu"
+
+msgid "E26: Hebrew cannot be used: Not enabled at compile time\n"
+msgstr ""
+"E26: Nedá sa použí hebrejský režim: nebol zapnutý pri preklade programu\n"
+
+msgid "E27: Farsi cannot be used: Not enabled at compile time\n"
+msgstr "E27: Nedá sa použí farsi režim: nebol zapnutý pri preklade programu\n"
+
+msgid "E800: Arabic cannot be used: Not enabled at compile time\n"
+msgstr "E800: Nedá sa použí arabic režim: nebol zapnutý pri preklade programu\n"
+
+#, c-format
+msgid "E28: No such highlight group name: %s"
+msgstr "E28: Skupina zvýraznenia %s neexistuje"
+
+msgid "E29: No inserted text yet"
+msgstr "E29: Zatia¾ nie je vložený žiaden text"
+
+msgid "E30: No previous command line"
+msgstr "E30: Žiadny predchádzajúci príkazový riadok"
+
+msgid "E31: No such mapping"
+msgstr "E31: Mapovanie nenájdené"
+
+msgid "E479: No match"
+msgstr "E479: Žiadna zhoda"
+
+#, c-format
+msgid "E480: No match: %s"
+msgstr "E480: Žiadna zhoda: %s"
+
+msgid "E32: No file name"
+msgstr "E32: Žiadny názov súboru"
+
+msgid "E33: No previous substitute regular expression"
+msgstr "E33: Žiadny predchádzajúci prislúchajúci správny výraz"
+
+msgid "E34: No previous command"
+msgstr "E34: Žiadny predchádzajúci príkaz"
+
+msgid "E35: No previous regular expression"
+msgstr "E35: Žiadny predchádzajúci regulárny výraz"
+
+msgid "E481: No range allowed"
+msgstr "E481: Rozsah nie je povolený"
+
+msgid "E36: Not enough room"
+msgstr "E36: Nedostatok miesta"
+
+#, c-format
+msgid "E247: no registered server named \"%s\""
+msgstr "E247: žiaden registrovaný server pomenovaný \"%s\""
+
+#, c-format
+msgid "E482: Can't create file %s"
+msgstr "E482: Nedá sa vytvori súbor %s"
+
+msgid "E483: Can't get temp file name"
+msgstr "E483: Nedá sa získa názov doèasného súboru"
+
+#, c-format
+msgid "E484: Can't open file %s"
+msgstr "E484: Nedá sa otvori súbor %s"
+
+#, c-format
+msgid "E485: Can't read file %s"
+msgstr "E485: Nedá sa èíta súbor %s"
+
+msgid "E37: No write since last change (add ! to override)"
+msgstr "E37: Neuložené zmeny (použite ! pre vynútenie)"
+
+msgid "E38: Null argument"
+msgstr "E38: Nulový argument"
+
+msgid "E39: Number expected"
+msgstr "E39: Oèakávané èíslo"
+
+#, c-format
+msgid "E40: Can't open errorfile %s"
+msgstr "E40: Nedá sa otvori chybový súbor %s"
+
+msgid "E233: cannot open display"
+msgstr "E233: nedá sa otvori displej"
+
+msgid "E41: Out of memory!"
+msgstr "E41: Nedostatok pamäti!"
+
+msgid "Pattern not found"
+msgstr "Vzor nenájdený"
+
+#, c-format
+msgid "E486: Pattern not found: %s"
+msgstr "E486: Vzor nenájdený: %s"
+
+msgid "E487: Argument must be positive"
+msgstr "E487: Argument musí by kladný"
+
+msgid "E459: Cannot go back to previous directory"
+msgstr "E459: Žiadny predchádzajúci adresár"
+
+msgid "E42: No Errors"
+msgstr "E42: Žiadne chyby"
+
+msgid "E43: Damaged match string"
+msgstr "E43: Poškodený reazac pre vyh¾adávanie"
+
+msgid "E44: Corrupted regexp program"
+msgstr "E44: Poškodený regexp program"
+
+msgid "E45: 'readonly' option is set (add ! to override)"
+msgstr ""
+"E45: vo¾ba 'readonly' (iba na èítanie) je nastavená (použite ! pre "
+"prepísanie)"
+
+#, c-format
+msgid "E46: Cannot change read-only variable \"%s\""
+msgstr "E46: Nedá sa nastavi premenná len na èítanie \"%s\""
+
+#, c-format
+msgid "E46: Cannot set variable in the sandbox: \"%s\""
+msgstr "E46: Nedá sa nastavi premenná v bezpeènostnej schránke: \"%s\""
+
+msgid "E47: Error while reading errorfile"
+msgstr "E47: Chyba pri èítaní chybového súboru"
+
+msgid "E48: Not allowed in sandbox"
+msgstr "E48: Nie je dovolené v bezpeènostnej schránke"
+
+msgid "E523: Not allowed here"
+msgstr "E523: Nie je na povolené na tomto mieste"
+
+msgid "E359: Screen mode setting not supported"
+msgstr "E359: Nastavovanie režimu obrazovky nie je podporované"
+
+msgid "E49: Invalid scroll size"
+msgstr "E49: Chybná hodnota ve¾kosti rolovania"
+
+msgid "E91: 'shell' option is empty"
+msgstr "E91: vo¾ba 'shell' je prázdna"
+
+msgid "E255: Couldn't read in sign data!"
+msgstr "E255: Chyba -- nedájú sa preèíta oznaèovacie dáta!"
+
+msgid "E72: Close error on swap file"
+msgstr "E72: Chyba pri uzatváraní odkladacieho súboru"
+
+msgid "E73: tag stack empty"
+msgstr "E73: zoznam tagov je prázdny"
+
+msgid "E74: Command too complex"
+msgstr "E74: Príkaz je príliš zložitý"
+
+msgid "E75: Name too long"
+msgstr "E75: Názov je príliš dlhý"
+
+msgid "E76: Too many ["
+msgstr "E76: Príliš mnoho ["
+
+msgid "E77: Too many file names"
+msgstr "E77: Príliš mnoho názvov súborov"
+
+msgid "E488: Trailing characters"
+msgstr "E488: Nadbytoèné znaky na konci"
+
+msgid "E78: Unknown mark"
+msgstr "E78: Neznáma znaèka"
+
+msgid "E79: Cannot expand wildcards"
+msgstr "E79: Nemožno expandova žolíkové znaky (wildcards)"
+
+msgid "E591: 'winheight' cannot be smaller than 'winminheight'"
+msgstr ""
+"E591: hodnota vo¾by 'winheight' (výška okna) nesmie by menšia než hodnota vo¾by 'winminheight' (minimálna výška okna)"
+
+msgid "E592: 'winwidth' cannot be smaller than 'winminwidth'"
+msgstr ""
+"E592: hodnota vo¾by 'winwidth' (šírka okna) nesmie by menšia než hodnota vol¾y 'winminwidth' (minimálna šírka okna)"
+
+msgid "E80: Error while writing"
+msgstr "E80: Chyba pri ukladaní"
+
+msgid "Zero count"
+msgstr "Nulový poèet"
+
+msgid "E81: Using <SID> not in a script context"
+msgstr "E81: Použitie <SID> mimo kontext skriptu"
+
+msgid "E449: Invalid expression received"
+msgstr "E449: Bol prijatý chybný výraz"
+
+msgid "E463: Region is guarded, cannot modify"
+msgstr "E463: Región je uzamknutý, nemožno modifikova"
+
+msgid "E744: NetBeans does not allow changes in read-only files"
+msgstr "E744: NetBeans nepovo¾uje zmeny v súboroch len na èítanie"
+
+#, c-format
+msgid "E685: Internal error: %s"
+msgstr "E685: Vnútorná chyba: %s"
+
+msgid "E363: pattern uses more memory than 'maxmempattern'"
+msgstr "E363: vzor používa viac pamäte ako 'maxmempattern'"
+
+msgid "E749: empty buffer"
+msgstr "E749: prázdny buffer"
+
+msgid "E682: Invalid search pattern or delimiter"
+msgstr "E682: Neprípustný h¾adaný reazec alebo odde¾ovaè"
+
+msgid "E139: File is loaded in another buffer"
+msgstr "E139: Súbor je naèítaný v inom buffere"
+
+#, c-format
+msgid "E764: Option '%s' is not set"
+msgstr "E764: Vo¾ba \"%s\" nie je nastavená"
+
+msgid "search hit TOP, continuing at BOTTOM"
+msgstr "h¾adanie dosiahlo zaèiatok, pokraèovanie od konca"
+
+msgid "search hit BOTTOM, continuing at TOP"
+msgstr "h¾adanie dosiahlo koniec, pokraèovanie od zaèiatku"
+
diff --git a/src/po/sk.po b/src/po/sk.po
new file mode 100644
index 0000000000..477f441f11
--- /dev/null
+++ b/src/po/sk.po
@@ -0,0 +1,5821 @@
+# Slovak translation of vim
+# Lubomir Host 'rajo' <rajo AT platon.sk>
+# 2005 - Platon Group, http://platon.sk/
+# $Revision: 1.4 $
+# $LastChangedDate: 2005-10-08 12:00:24 +0200 (Sat, 08 Oct 2005) $
+msgid ""
+msgstr ""
+"Project-Id-Version: vim\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2005-09-30 15:58+0200\n"
+"PO-Revision-Date: 2005-09-30 15:58+0200\n"
+"Last-Translator: Lubomir Host <rajo@platon.sk>\n"
+"Language-Team: Slovak <sk-i18n@lists.linux.sk>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=ISO-8859-2\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: Vim 7.x\n"
+
+msgid "E82: Cannot allocate any buffer, exiting..."
+msgstr "E82: Nedá sa alokova» buffer, konèím..."
+
+msgid "E83: Cannot allocate buffer, using other one..."
+msgstr "E83: Nedá sa alokova» buffer, pou¾ijem iný..."
+
+msgid "E515: No buffers were unloaded"
+msgstr "E515: ®iadny buffer nebol uvoµnený"
+
+msgid "E516: No buffers were deleted"
+msgstr "E516: ®iadny buffer nebol vymazaný"
+
+msgid "E517: No buffers were wiped out"
+msgstr "E517: ®iadny buffer nebol vymazaný"
+
+msgid "1 buffer unloaded"
+msgstr "1 buffer uvoµnený"
+
+#, c-format
+msgid "%d buffers unloaded"
+msgstr "%d bufferov uvoµnených"
+
+msgid "1 buffer deleted"
+msgstr "1 buffer vymazaný"
+
+#, c-format
+msgid "%d buffers deleted"
+msgstr "%d bufferov vymazaných"
+
+msgid "1 buffer wiped out"
+msgstr "1 buffer odstránený"
+
+#, c-format
+msgid "%d buffers wiped out"
+msgstr "%d bufferov odstránených"
+
+msgid "E84: No modified buffer found"
+msgstr "E84: Nebol nájdený ¾iadny zmenený buffer"
+
+#. back where we started, didn't find anything.
+msgid "E85: There is no listed buffer"
+msgstr "E85: Nena¹iel som ¾iadny buffer"
+
+msgid "E86: Buffer %ld does not exist"
+msgstr "E86: Buffer %ld neexistuje"
+
+msgid "E87: Cannot go beyond last buffer"
+msgstr "E87: Za posledný buffer sa nedá preskoèi»"
+
+msgid "E88: Cannot go before first buffer"
+msgstr "E88: Pred prvý buffer sa nedá preskoèi»"
+
+msgid "E89: No write since last change for buffer %ld (add ! to override)"
+msgstr "E89: Zmeny v bufferi %ld neboli ulo¾ené (! pre vynútenie)"
+
+msgid "E90: Cannot unload last buffer"
+msgstr "E90: Posledný buffer sa nedá odstráni»"
+
+msgid "W14: Warning: List of file names overflow"
+msgstr "W14: Varovanie: preteèenie zoznamu s názvami súborov"
+
+#, c-format
+msgid "E92: Buffer %ld not found"
+msgstr "E92: buffer %ld nenájdený"
+
+#, c-format
+msgid "E93: More than one match for %s"
+msgstr "E93: Vzoru %s vyhovuje viac bufferov"
+
+#, c-format
+msgid "E94: No matching buffer for %s"
+msgstr "E94: Vzoru %s nevyhovuje ¾iadny buffer"
+
+#, c-format
+msgid "line %ld"
+msgstr "riadok %ld"
+
+msgid "E95: Buffer with this name already exists"
+msgstr "E95: Buffer takéhoto mena u¾ existuje"
+
+msgid " [Modified]"
+msgstr " [Zmenený]"
+
+msgid "[Not edited]"
+msgstr "[Neupravovaný]"
+
+msgid "[New file]"
+msgstr "[Nový súbor]"
+
+msgid "[Read errors]"
+msgstr "[Chyby pri èítaní]"
+
+msgid "[readonly]"
+msgstr "[iba pre èítanie]"
+
+#, c-format
+msgid "1 line --%d%%--"
+msgstr "1 riadok --%d%%--"
+
+#, c-format
+msgid "%ld lines --%d%%--"
+msgstr "%ld riadkov --%d%%--"
+
+#, c-format
+msgid "line %ld of %ld --%d%%-- col "
+msgstr "riadok %ld z %ld --%d%%-- ståpec"
+
+msgid "[No Name]"
+msgstr "[Bez mena]"
+
+#. must be a help buffer
+msgid "help"
+msgstr "pomocník"
+
+msgid "[help]"
+msgstr "[pomocník]"
+
+msgid "[Preview]"
+msgstr "[Náhµad]"
+
+msgid "All"
+msgstr "V¹etko"
+
+msgid "Bot"
+msgstr "Koniec"
+
+msgid "Top"
+msgstr "Zaèiatok"
+
+#, c-format
+msgid ""
+"\n"
+"# Buffer list:\n"
+msgstr ""
+"\n"
+"# Zoznam bufferov:\n"
+
+msgid "[Error List]"
+msgstr "[Zoznam chýb]"
+
+msgid ""
+"\n"
+"--- Signs ---"
+msgstr ""
+"\n"
+"--- Znaky ---"
+
+#, c-format
+msgid "Signs for %s:"
+msgstr "Znaky pre %s:"
+
+#, c-format
+msgid " line=%ld id=%d name=%s"
+msgstr " riadok=%ld id=%d meno=%s"
+
+#, c-format
+msgid "E96: Can not diff more than %ld buffers"
+msgstr "E96: Nemô¾em porovna» viac ako %ld bufferov"
+
+msgid "E97: Cannot create diffs"
+msgstr "E97: Nedajú sa vytvori» porovnania"
+
+msgid "Patch file"
+msgstr "Záplatový súbor"
+
+msgid "E98: Cannot read diff output"
+msgstr "E98: Nedá sa èíta» výstup porovnania"
+
+msgid "E99: Current buffer is not in diff mode"
+msgstr "E99: Aktuálny buffer nie je v porovnávacom móde"
+
+msgid "E100: No other buffer in diff mode"
+msgstr "E100: V porovnávacom móde sa nenachádza iný buffer"
+
+msgid "E101: More than two buffers in diff mode, don't know which one to use"
+msgstr "E101: Viac ako dva buffery v porovnávacom móde; neviem, ktorý pou¾i»"
+
+#, c-format
+msgid "E102: Can't find buffer \"%s\""
+msgstr "E102: Nedá sa nájs» buffer \"%s\""
+
+#, c-format
+msgid "E103: Buffer \"%s\" is not in diff mode"
+msgstr "E103: Buffer \"%s\" nie je v porovnávacom móde"
+
+# TODO: digraph
+msgid "E104: Escape not allowed in digraph"
+msgstr "E104: digraph nesmie obsahova» znak Escape"
+
+msgid "E544: Keymap file not found"
+msgstr "E544: Mapa kláves nenájdená"
+
+msgid "E105: Using :loadkeymap not in a sourced file"
+msgstr "E105: Pou¾itý príkaz :loadkeymap v súbore, ktorý nie je interpretovaný"
+
+msgid " Keyword completion (^N^P)"
+msgstr " Doplòovanie kµúèových slov (^N^P)"
+
+#. ctrl_x_mode == 0, ^P/^N compl.
+msgid " ^X mode (^]^D^E^F^I^K^L^N^O^P^S^U^V^Y)"
+msgstr " ^X re¾im (^]^D^E^F^I^K^L^N^O^P^S^U^V^Y)"
+
+msgid " Whole line completion (^L^N^P)"
+msgstr " Doplòovanie celých riadkov (^L^N^P)"
+
+msgid " File name completion (^F^N^P)"
+msgstr " Doplòovanie názvov súborov (^F^N^P)"
+
+msgid " Tag completion (^]^N^P)"
+msgstr " Doplòovanie tagov (^]^N^P)"
+
+msgid " Path pattern completion (^N^P)"
+msgstr " Doplòovanie vzoru ciest (^N^P)"
+
+msgid " Definition completion (^D^N^P)"
+msgstr " Doplòovanie definícií (^D^N^P)"
+
+msgid " Dictionary completion (^K^N^P)"
+msgstr " Doplòovanie podµa slovníka (^K^N^P)"
+
+msgid " Thesaurus completion (^T^N^P)"
+msgstr " Doplòovanie podµa lexikonu (^T^N^P)"
+
+msgid " Command-line completion (^V^N^P)"
+msgstr " Doplòovanie príkazového riadka (^V^N^P)"
+
+msgid " User defined completion (^U^N^P)"
+msgstr " Doplòovanie celých riadkov (^U^N^P)"
+
+msgid " Omni completion (^O^N^P)"
+msgstr " Doplòovanie tagov (^O^N^P)"
+
+msgid " Spelling suggestion (^S^N^P)"
+msgstr " Doplòovanie celých riadkov (^S^N^P)"
+
+msgid " Keyword Local completion (^N^P)"
+msgstr " Miestne doplòovanie kµúèových slov (^N^P)"
+
+msgid "Hit end of paragraph"
+msgstr "Koniec odstavca"
+
+msgid "'dictionary' option is empty"
+msgstr "voµba 'dictionary' (slovník) je prázdna"
+
+msgid "'thesaurus' option is empty"
+msgstr "voµba 'thesaurus' (lexikon) je prázdna"
+
+#, c-format
+msgid "Scanning dictionary: %s"
+msgstr "prehµadávam slovník %s"
+
+msgid " (insert) Scroll (^E/^Y)"
+msgstr " (insert) Rolovanie (^E/^Y)"
+
+msgid " (replace) Scroll (^E/^Y)"
+msgstr " (replace) Rolovanie (^E/^Y)"
+
+#, c-format
+msgid "Scanning: %s"
+msgstr "Prehµadávam: %s"
+
+#, c-format
+msgid "Scanning tags."
+msgstr "Prehµadávam tagy."
+
+msgid " Adding"
+msgstr " Pridávam"
+
+#. 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.
+#.
+msgid "-- Searching..."
+msgstr "-- Hµadám..."
+
+msgid "Back at original"
+msgstr "Východzia podoba"
+
+msgid "Word from other line"
+msgstr "Slovo z iného riadku"
+
+msgid "The only match"
+msgstr "Jediná zhoda"
+
+#, c-format
+msgid "match %d of %d"
+msgstr "zhoda %d z %d"
+
+#, c-format
+msgid "match %d"
+msgstr "zhoda %d"
+
+msgid "E18: Unexpected characters in :let"
+msgstr "E18: Neoèekávané znaky v :let"
+
+msgid "E684: list index out of range: %ld"
+msgstr "E684: index v zozname je mimo rozsah: %ld"
+
+#, c-format
+msgid "E121: Undefined variable: %s"
+msgstr "E121: Nedefinovaná premenná: %s"
+
+msgid "E111: Missing ']'"
+msgstr "E111: Chýba ']'"
+
+msgid "E686: Argument of %s must be a List"
+msgstr "E686: Argument %s musí by» Zoznam (List)"
+
+#, c-format
+msgid "E712: Argument of %s must be a List or Dictionary"
+msgstr "E712: Argument %s musí by» Zoznam (List) alebo Slovník (Dictionary)"
+
+msgid "E713: Cannot use empty key for Dictionary"
+msgstr "E713: Nemo¾no pou¾i» prázdny kµúè pre Slovník (Dictionary)"
+
+msgid "E714: List required"
+msgstr "E714: vy¾aduje sa Zoznam (List)"
+
+msgid "E715: Dictionary required"
+msgstr "E715: Vy¾aduje sa Slovník (Dictionary)"
+
+#, c-format
+msgid "E118: Too many arguments for function: %s"
+msgstr "E118: Príli¹ mnoho argumentov pre funkciu %s"
+
+#, c-format
+msgid "E716: Key not present in Dictionary: %s"
+msgstr "E716: kµúè sa v Slovníku (Dictionary) nenachádza: %s"
+
+msgid "E122: Function %s already exists, add ! to replace it"
+msgstr "E122: Funkcia %s u¾ existuje. Pou¾ite ! pre jej nahradenie."
+
+msgid "E717: Dictionary entry already exists"
+msgstr "E717: Záznam v Slovníku (Dictionary) u¾ existuje"
+
+msgid "E718: Funcref required"
+msgstr "E718: Je vy¾adovaný odkaz na Funkciu (Funcref)"
+
+msgid "E719: Cannot use [:] with a Dictionary"
+msgstr "E719: Nemo¾no pou¾it [:] so Slovníkom (Dictionary)"
+
+#, c-format
+msgid "E734: Wrong variable type for %s="
+msgstr "E734: Zlý typ premennej pre %s="
+
+msgid "E130: Unknown function: %s"
+msgstr "E130: Neznáma funkcia: %s"
+
+msgid "E461: Illegal variable name: %s"
+msgstr "E461: Neprípustné meno premennej: %s"
+
+msgid "E687: Less targets than List items"
+msgstr "E687: Menej cieµov ako polo¾iek Poµa (List items)"
+
+msgid "E688: More targets than List items"
+msgstr "E688: Viac cieµov ako polo¾iek Poµa (List items)"
+
+msgid "Double ; in list of variables"
+msgstr "Dvojitá ; v zozname premenných"
+
+msgid "E738: Can't list variables for %s"
+msgstr "E738: Nemo¾no vypísa» premenné pre %s"
+
+msgid "E689: Can only index a List or Dictionary"
+msgstr "E689: Indexova» mo¾no iba Zoznam (List) alebo Slovník (Dictionary)"
+
+msgid "E708: [:] must come last"
+msgstr "E708: [:] musí prís» ako posledná"
+
+msgid "E709: [:] requires a List value"
+msgstr "E709: [:] vy¾aduje hodnotu Poµa (List value)"
+
+msgid "E710: List value has more items than target"
+msgstr "E710: Hodnota Poµa (List value) má viac polo¾iek ako cieµ"
+
+msgid "E711: List value has not enough items"
+msgstr "E711: Hodnota Poµa (List value) nemá dostatok polo¾iek"
+
+msgid "E690: Missing \"in\" after :for"
+msgstr "E690: Chýba \"in\" po :for"
+
+#, c-format
+msgid "E107: Missing parentheses: %s"
+msgstr "E107: Chýbajú zátvorky: %s"
+
+#, c-format
+msgid "E108: No such variable: \"%s\""
+msgstr "E108: Premenná \"%s\" neexistuje"
+
+msgid "E743: variable nested too deep for (un)lock"
+msgstr "E743: premenná je príli¹ vnorená na (od)blokovanie"
+
+msgid "E109: Missing ':' after '?'"
+msgstr "E109: Po '?' chýba ':'"
+
+msgid "E691: Can only compare List with List"
+msgstr "E691: Porovnáva» mo¾no iba Zoznam so Zoznamom (List with List)"
+
+msgid "E692: Invalid operation for Lists"
+msgstr "E692: Neplatná operácia pre Zoznamy (Lists)"
+
+msgid "E735: Can only compare Dictionary with Dictionary"
+msgstr "E735: Porovnáva» mo¾no iba Slovník so Slovníkom (Dictionary with Dictionary)"
+
+msgid "E736: Invalid operation for Dictionary"
+msgstr "E736: Neplatná operácia pre Slovník"
+
+msgid "E693: Can only compare Funcref with Funcref"
+msgstr "E693: Porovnáva» mo¾no iba odkaz na Funkciu s odkazom na Funkciu (Funcref with Funcref)"
+
+msgid "E694: Invalid operation for Funcrefs"
+msgstr "E694: Neplatná operácia pre odkazy na Funkcie (Funcrefs)"
+
+msgid "E110: Missing ')'"
+msgstr "E110: Chýba ')'"
+
+msgid "E695: Cannot index a Funcref"
+msgstr "E695: Nemo¾no indexova» odkaz na Funkciu (Funcref)"
+
+#, c-format
+msgid "E112: Option name missing: %s"
+msgstr "E112: Chýba meno voµby: %s"
+
+#, c-format
+msgid "E113: Unknown option: %s"
+msgstr "E113: Neznáma voµba: %s"
+
+#, c-format
+msgid "E114: Missing quote: %s"
+msgstr "E114: Chýbajú úvodzovky: %s"
+
+#, c-format
+msgid "E115: Missing quote: %s"
+msgstr "E115: Chýbajú úvodzovky: %s"
+
+msgid "E696: Missing comma in List: %s"
+msgstr "E696: Chýba èiarka v Zozname: %s"
+
+msgid "E697: Missing end of List ']': %s"
+msgstr "E697: Chýba koniec Zoznamu (List) ']': %s"
+
+msgid "E720: Missing colon in Dictionary: %s"
+msgstr "E720: Chýba dvojbodka v Slovníku (Dictionary): %s"
+
+#, c-format
+msgid "E721: Duplicate key in Dictionary: \"%s\""
+msgstr "E721: Duplikovaný kµúè v Slovníku (Dictionary): \"%s\""
+
+msgid "E722: Missing comma in Dictionary: %s"
+msgstr "E722: Chýba èiarka v Slovníku (Dictionary): %s"
+
+msgid "E723: Missing end of Dictionary '}': %s"
+msgstr "E723: Chýba koniec Slovníka (Dictionary) '}': %s"
+
+msgid "E724: variable nested too deep for displaying"
+msgstr "E724: premenná je vnorená príli¹ hlboko pre zobrazenie"
+
+msgid "E699: Too many arguments"
+msgstr "E699: Príli¹ mnoho argumentov"
+
+#.
+#. * 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"
+
+msgid "E737: Key already exists: %s"
+msgstr "E737: Kµúè u¾ existuje: %s"
+
+#, c-format
+msgid "+-%s%3ld lines: "
+msgstr "+-%s%3ld riadky: "
+
+msgid "E700: Unknown function: %s"
+msgstr "E700: Neznáma funkcia: %s"
+
+msgid ""
+"&OK\n"
+"&Cancel"
+msgstr ""
+"&OK\n"
+"&Zru¹i»"
+
+msgid "called inputrestore() more often than inputsave()"
+msgstr "funkcia inputrestore() volaná èastej¹ie ako inputsave()"
+
+msgid "E745: Range not allowed"
+msgstr "E745: Rozsah nie je povolený"
+
+msgid "E701: Invalid type for len()"
+msgstr "E701: Neplatný typ pre len()"
+
+msgid "E726: Stride is zero"
+msgstr "E726: Krok je nulový"
+
+msgid "E727: Start past end"
+msgstr "E727: Zaèiatok presahuje koniec"
+
+msgid "<empty>"
+msgstr "<prázdny>"
+
+msgid "E240: No connection to Vim server"
+msgstr "E240: Neexistuje pripojenie k Vim serveru"
+
+#, c-format
+msgid "E241: Unable to send to %s"
+msgstr "E241: Nemô¾em posla» na %s"
+
+msgid "E277: Unable to read a server reply"
+msgstr "E277: Nemô¾em èíta» odpoveï servra"
+
+msgid "E655: Too many symbolic links (cycle?)"
+msgstr "E655: Príli¹ mnoho symbolických odkazov (sluèka?)"
+
+msgid "E258: Unable to send to client"
+msgstr "E258: Nemô¾em posla» klientovi"
+
+msgid "E702: Sort compare function failed"
+msgstr "E702: Funkcia na utriedenie/porovnanie zlyhala"
+
+msgid "(Invalid)"
+msgstr "(Chybný)"
+
+msgid "E677: Error writing temp file"
+msgstr "E677: Chyba pri zápise doèasného súboru"
+
+msgid "E703: Using a Funcref as a Number"
+msgstr "E703: Pou¾itý odkaz na Funkciu (Funcref) ako èíslo"
+
+msgid "E745: Using a List as a Number"
+msgstr "E745: Zoznam (List) pou¾itý ako èíslo"
+
+msgid "E728: Using a Dictionary as a Number"
+msgstr "E728: Slovník (Dictionary) pou¾itý ako èíslo"
+
+msgid "E729: using Funcref as a String"
+msgstr "E729: Odkaz na Funkciu (Funcref) pou¾itý ako Re»azec (String)"
+
+msgid "E730: using List as a String"
+msgstr "E730: Zoznam (List) pou¾itý ako Re»azec (String)"
+
+msgid "E731: using Dictionary as a String"
+msgstr "E731: Slovník (Dictionary) pou¾itý ako Re»azec (String)"
+
+msgid "E704: Funcref variable name must start with a capital: %s"
+msgstr "E704: Premenná typu odkaz na Funkciu (Funcref) musí zaèína» s veµkým písmenom: %s"
+
+#, c-format
+msgid "E705: Variable name conflicts with existing function: %s"
+msgstr "E705: Meno premennej je v konflikte s existujúcou funkciou: %s"
+
+msgid "E706: Variable type mismatch for: %s"
+msgstr "E706: Typ premennej sa nezhoduje: %s"
+
+#, c-format
+msgid "E741: Value is locked: %s"
+msgstr "E741: Hodnota je uzamknutá: %s"
+
+msgid "Unknown"
+msgstr "Neznámy"
+
+msgid "E742: Cannot change value of %s"
+msgstr "E742: Nemo¾no zmeni» hodnotu %s"
+
+msgid "E698: variable nested too deep for making a copy"
+msgstr "E698: premenná je vnorená príli¹ hlboko pre skopírovanie"
+
+#, c-format
+msgid "E124: Missing '(': %s"
+msgstr "E124: Chýba '(': %s"
+
+#, c-format
+msgid "E125: Illegal argument: %s"
+msgstr "E125: Neprípustný argument: %s"
+
+msgid "E126: Missing :endfunction"
+msgstr "E126: Chýba :endfunction"
+
+msgid "E746: Function name does not match script file name: %s"
+msgstr "E746: Meno funkcie sa nezhoduje s menom interpretovaného súboru: %s"
+
+msgid "E129: Function name required"
+msgstr "E129: Je vy¾adované meno funkcie"
+
+msgid "E128: Function name must start with a capital or contain a colon: %s"
+msgstr "E128: Názov funkcie musí zaèína» veµkým písmenom alebo obsahova» dvojbodku: %s"
+
+#, c-format
+msgid "E131: Cannot delete function %s: It is in use"
+msgstr "E131: Nedá sa vymaza» funkcia %s: je pou¾ívaná"
+
+msgid "E132: Function call depth is higher than 'maxfuncdepth'"
+msgstr "E132: Zanorenie funkcií je hlb¹ie ne¾ 'maxfuncdepth'"
+
+#, c-format
+msgid "calling %s"
+msgstr "volám %s"
+
+msgid "%s aborted"
+msgstr "%s zru¹ený"
+
+#, c-format
+msgid "%s returning #%ld"
+msgstr "%s vrátilo #%ld"
+
+msgid "%s returning %s"
+msgstr "%s vrátilo %s"
+
+#, c-format
+msgid "continuing in %s"
+msgstr "pokraèujem v %s"
+
+msgid "E133: :return not inside a function"
+msgstr "E133: :return mimo funkciu"
+
+#, c-format
+msgid ""
+"\n"
+"# global variables:\n"
+msgstr ""
+"\n"
+"# globálne premenné:\n"
+
+msgid ""
+"\n"
+"\tLast set from "
+msgstr ""
+"\n"
+"\tPosledné nastavenie z "
+
+#, c-format
+msgid "<%s>%s%s %d, Hex %02x, Octal %03o"
+msgstr "<%s>%s%s %d, ¹estnástkovo %02x, osmièkovo %03o"
+
+msgid "> %d, Hex %04x, Octal %o"
+msgstr "> %d, ¹estnástkovo %04x, osmièkovo %o"
+
+msgid "> %d, Hex %08x, Octal %o"
+msgstr "> %d, ¹estnástkovo %08x, osmièkovo %o"
+
+msgid "E134: Move lines into themselves"
+msgstr "E134: Prekrytie riadkov sebou samými"
+
+msgid "1 line moved"
+msgstr "1 riadok presunutý"
+
+#, c-format
+msgid "%ld lines moved"
+msgstr "%ld riadkov presunutých"
+
+#, c-format
+msgid "%ld lines filtered"
+msgstr "%ld riadkov filtrovaných"
+
+msgid "E135: *Filter* Autocommands must not change current buffer"
+msgstr "E135: Automatické príkazy *Filter* nesmú meni» aktuálny buffer"
+
+msgid "[No write since last change]\n"
+msgstr "[Neulo¾ené zmeny]\n"
+
+msgid "%sviminfo: %s in line: "
+msgstr "%sviminfo: %s na riadku: "
+
+msgid "E136: viminfo: Too many errors, skipping rest of file"
+msgstr "E136: viminfo: príli¹ mnoho chýb, preskakujem zbytok súboru"
+
+#, c-format
+msgid "Reading viminfo file \"%s\"%s%s%s"
+msgstr "Èítam viminfo súbor \"%s\"%s%s%s"
+
+msgid " info"
+msgstr " informácie"
+
+msgid " marks"
+msgstr " znaèky"
+
+msgid " FAILED"
+msgstr " ZLYHALO"
+
+#, c-format
+msgid "E137: Viminfo file is not writable: %s"
+msgstr "E137: Do viminfo súboru %s sa nedá zapisova»"
+
+#, c-format
+msgid "E138: Can't write viminfo file %s!"
+msgstr "E138: Nedá sa ulo¾i» viminfo súbor %s!"
+
+#, c-format
+msgid "Writing viminfo file \"%s\""
+msgstr "Ukládám viminfo súboru \"%s\""
+
+#. Write the info:
+#, c-format
+msgid "# This viminfo file was generated by Vim %s.\n"
+msgstr "# Tento viminfo súbor bol vytvorený editorom Vim %s.\n"
+
+#, c-format
+msgid ""
+"# You may edit it if you're careful!\n"
+"\n"
+msgstr ""
+"# Pokiaµ budete opatrný, mô¾ete ho upravova».\n"
+"\n"
+
+#, c-format
+msgid "# Value of 'encoding' when this file was written\n"
+msgstr "# Hodnota 'encoding' (kódovania) poèas zápisu tohoto súboru\n"
+
+msgid "Illegal starting char"
+msgstr "Neprípustný zaèiatoèný znak"
+
+msgid "Save As"
+msgstr "Ulo¾i» ako"
+
+msgid "Write partial file?"
+msgstr "Ulo¾i» neúplný súbor?"
+
+msgid "E140: Use ! to write partial buffer"
+msgstr "E140: Pou¾ite ! pre ulo¾enie neúplného bufferu"
+
+msgid "Overwrite existing file \"%s\"?"
+msgstr "Prepísa» existujúci súbor \"%s\"?"
+
+#, c-format
+msgid "Swap file \"%s\" exists, overwrite anyway?"
+msgstr "Odkladací súbor \"%s\" existuje, aj tak prepísa»?"
+
+msgid "E768: Swap file exists: %s (:silent! overrides)"
+msgstr "E768: Odkladací súbor existuje: %s (pou¾ite :silent! pre prepísanie)"
+
+#, c-format
+msgid "E141: No file name for buffer %ld"
+msgstr "E141: ®iadny názov súboru pre buffer %ld"
+
+msgid "E142: File not written: Writing is disabled by 'write' option"
+msgstr "E142: Súbor nebol ulo¾ený: ukladanie je zakázané voµbou 'write'"
+
+msgid ""
+"'readonly' option is set for \"%s\".\n"
+"Do you wish to write anyway?"
+msgstr ""
+"Pre \"%s\" je nastavená voµba 'readonly' (iba na èítanie).\n"
+"Prajete si aj tak ulo¾i»?"
+
+msgid "Edit File"
+msgstr "Upravova» súbor"
+
+#, c-format
+msgid "E143: Autocommands unexpectedly deleted new buffer %s"
+msgstr "E143: Automatické príkazy neoèakávane zmazali nový buffer %s"
+
+msgid "E144: non-numeric argument to :z"
+msgstr "E144: neèíselný argument pre :z"
+
+msgid "E145: Shell commands not allowed in rvim"
+msgstr "E145: rvim nepovoµuje pou¾itie príkazov shellu"
+
+msgid "E146: Regular expressions can't be delimited by letters"
+msgstr "E146: Regulárne výrazy nesmú by» oddelené písmenami"
+
+#, c-format
+msgid "replace with %s (y/n/a/q/l/^E/^Y)?"
+msgstr "nahradi» %s (y/n/a/q/l/^E/^Y)?"
+
+msgid "(Interrupted) "
+msgstr "(preru¹ený) "
+
+msgid "1 match"
+msgstr "1 zhoda"
+
+msgid "1 substitution"
+msgstr "1 nahradenie"
+
+msgid "%ld matches"
+msgstr "%ld zhôd"
+
+#, c-format
+msgid "%ld substitutions"
+msgstr "%ld nahradení"
+
+msgid " on 1 line"
+msgstr " na 1 riadku"
+
+#, c-format
+msgid " on %ld lines"
+msgstr " na %ld riadkov"
+
+msgid "E147: Cannot do :global recursive"
+msgstr "E147: :global sa nedá vola» rekurzívne"
+
+msgid "E148: Regular expression missing from global"
+msgstr "E148: Pri príkaze global chýba regulárny výraz"
+
+#, c-format
+msgid "Pattern found in every line: %s"
+msgstr "Vzor nájdený na ka¾dom riadku: %s"
+
+#, c-format
+msgid ""
+"\n"
+"# Last Substitute String:\n"
+"$"
+msgstr ""
+"\n"
+"# Posledný zamieòaný re»azec:\n"
+"$"
+
+msgid "E478: Don't panic!"
+msgstr "E478: ®iadnu paniku!"
+
+msgid "E661: Sorry, no '%s' help for %s"
+msgstr "E661: ¥utujem, ¾iadny '%s' pomocník pre %s"
+
+#, c-format
+msgid "E149: Sorry, no help for %s"
+msgstr "E149: ¥utujem, pre %s nie je ¾iadny pomocník"
+
+#, c-format
+msgid "Sorry, help file \"%s\" not found"
+msgstr "¥utujem, súbor \"%s\" s pomocníkom nebol nájdený"
+
+#, c-format
+msgid "E150: Not a directory: %s"
+msgstr "E150: %s nie je adresárom"
+
+#, c-format
+msgid "E152: Cannot open %s for writing"
+msgstr "E152: %s sa nedá sa otvori» pre zápis"
+
+#, c-format
+msgid "E153: Unable to open %s for reading"
+msgstr "E153: %s as nedá otvori» pre èítanie"
+
+#, c-format
+msgid "E670: Mix of help file encodings within a language: %s"
+msgstr "E670: Rôzne kódovania pre súbory s pomocníkom pre jazyk: %s"
+
+msgid "E154: Duplicate tag \"%s\" in file %s/%s"
+msgstr "E154: Duplicitný tag \"%s\" v súbore %s/%s"
+
+#, c-format
+msgid "E160: Unknown sign command: %s"
+msgstr "E160: Neznámu príkaz pre znaèky: %s"
+
+msgid "E156: Missing sign name"
+msgstr "E156: Chýba meno pre znaèku"
+
+msgid "E612: Too many signs defined"
+msgstr "E612: Príli¹ mnoho definovaných znaèiek"
+
+#, c-format
+msgid "E239: Invalid sign text: %s"
+msgstr "E239: Chybný text znaèky: %s"
+
+#, c-format
+msgid "E155: Unknown sign: %s"
+msgstr "E155: Neznáma znaèka: %s"
+
+msgid "E159: Missing sign number"
+msgstr "E159: Chýba èislo znaèky"
+
+#, c-format
+msgid "E158: Invalid buffer name: %s"
+msgstr "E158: Chybné meno bufferu: %s"
+
+#, c-format
+msgid "E157: Invalid sign ID: %ld"
+msgstr "E157: Chybné ID znaèky: %ld"
+
+msgid " (NOT FOUND)"
+msgstr " (NENÁJDENÉ)"
+
+msgid " (not supported)"
+msgstr " (nepodporované)"
+
+msgid "[Deleted]"
+msgstr "[vymazaný]"
+
+msgid "Entering Debug mode. Type \"cont\" to continue."
+msgstr "Spú¹»am re¾im ladenia. Pre ukonèenie napí¹te \"cont\"."
+
+#, c-format
+msgid "line %ld: %s"
+msgstr "riadok %ld: %s"
+
+#, c-format
+msgid "cmd: %s"
+msgstr "príkaz: %s"
+
+#, c-format
+msgid "Breakpoint in \"%s%s\" line %ld"
+msgstr "Bod preru¹enia v \"%s%s\" na riadku %ld"
+
+#, c-format
+msgid "E161: Breakpoint not found: %s"
+msgstr "E161: Bod preru¹enia nenájdený: %s"
+
+msgid "No breakpoints defined"
+msgstr "Neboli definovné ¾iadne body preru¹enia"
+
+#, c-format
+msgid "%3d %s %s line %ld"
+msgstr "%3d %s %s riadok %ld"
+
+msgid "E750: First use :profile start <fname>"
+msgstr "E750: Najprv pou¾ite príkaz :profile start <meno_suboru>"
+
+msgid "Save changes to \"%s\"?"
+msgstr "Ulo¾i» zmeny do \"%s\"?"
+
+msgid "Untitled"
+msgstr "Bez mena"
+
+#, c-format
+msgid "E162: No write since last change for buffer \"%s\""
+msgstr "E162: Buffer \"%s\" obsahuje neulo¾ené zmeny"
+
+msgid "Warning: Entered other buffer unexpectedly (check autocommands)"
+msgstr ""
+"Varovanie: Neèakaný vstup do iného bufferu (skontrolujte automatické príkazy)"
+
+msgid "E163: There is only one file to edit"
+msgstr "E163: Pre úpravu bol zadaný iba jeden súbor"
+
+msgid "E164: Cannot go before first file"
+msgstr "E164: Nedá sa preskoèi» pred prvý súbor"
+
+msgid "E165: Cannot go beyond last file"
+msgstr "E165: Nedá sa preskoèi» za posledný súbor"
+
+msgid "E666: compiler not supported: %s"
+msgstr "E666: prekladaè nie je podporovaný: %s"
+
+#, c-format
+msgid "Searching for \"%s\" in \"%s\""
+msgstr "Hµadám \"%s\" v \"%s\""
+
+#, c-format
+msgid "Searching for \"%s\""
+msgstr "Hµadám \"%s\""
+
+#, c-format
+msgid "not found in 'runtimepath': \"%s\""
+msgstr "súbor \"%s\" nebol nájdený v 'runtimepath'"
+
+msgid "Source Vim script"
+msgstr "Zdrojový skript Vim"
+
+#, c-format
+msgid "Cannot source a directory: \"%s\""
+msgstr "Nemo¾no interpretova» adresár: \"%s\""
+
+#, c-format
+msgid "could not source \"%s\""
+msgstr "nedá sa interpretova» \"%s\""
+
+#, c-format
+msgid "line %ld: could not source \"%s\""
+msgstr "riadok %ld: nemô¾no interpretova» \"%s\""
+
+#, c-format
+msgid "sourcing \"%s\""
+msgstr "interpretujem \"%s\""
+
+#, c-format
+msgid "line %ld: sourcing \"%s\""
+msgstr "riadok %ld: interpretujem \"%s\""
+
+#, c-format
+msgid "finished sourcing %s"
+msgstr "dokonèená interpretácia %s"
+
+msgid "W15: Warning: Wrong line separator, ^M may be missing"
+msgstr "W15: Varovanie: chybný oddeµovaè riadkov. Mo¾no chýba ^M"
+
+msgid "E167: :scriptencoding used outside of a sourced file"
+msgstr "E167: príkaz :scriptencoding pou¾itý mimo interpretovaný súbor"
+
+msgid "E168: :finish used outside of a sourced file"
+msgstr "E168: príkaz :finish pou¾itý mimo interpretovaný súbor"
+
+#, c-format
+msgid "Current %slanguage: \"%s\""
+msgstr "Aktuálny %sjazyk: \"%s\""
+
+#, c-format
+msgid "E197: Cannot set language to \"%s\""
+msgstr "E197: Nedá sa nastavi» jazyk na \"%s\""
+
+msgid "Entering Ex mode. Type \"visual\" to go to Normal mode."
+msgstr "Spú¹»am Ex re¾im. Napí¹te \"visual\" pre návrat do Normálneho re¾imu."
+
+msgid "E501: At end-of-file"
+msgstr "E501: Koniec súboru"
+
+msgid "E169: Command too recursive"
+msgstr "E169: Príkaz je príli¹ rekurzívny"
+
+msgid "E605: Exception not caught: %s"
+msgstr "E605: Výnimka nezachytená: %s"
+
+msgid "End of sourced file"
+msgstr "Koniec interpretovaného súboru"
+
+msgid "End of function"
+msgstr "Koniec funkcie"
+
+msgid "E464: Ambiguous use of user-defined command"
+msgstr "E464: Nejednoznaèné pou¾itie pou¾ívateµom definovaného príkazu"
+
+msgid "E492: Not an editor command"
+msgstr "E492: Nie je príkazom editoru"
+
+msgid "E493: Backwards range given"
+msgstr "E493: Zadaný spätný rozsah"
+
+msgid "Backwards range given, OK to swap"
+msgstr "Zadaný spätný rozsah. OK pre zámenu"
+
+msgid "E494: Use w or w>>"
+msgstr "E494: Pou¾ite w alebo w>>"
+
+msgid "E319: Sorry, the command is not available in this version"
+msgstr "E319: ¥utujem, ale tento príkaz nie je dostupný v tejto verzii"
+
+msgid "E172: Only one file name allowed"
+msgstr "E172: Prípustný je iba jeden názov súboru"
+
+msgid "1 more file to edit. Quit anyway?"
+msgstr "E¹te zostáva 1 súbor k úprave. Chcete napriek tomu ukonèi» editor?"
+
+#, c-format
+msgid "%d more files to edit. Quit anyway?"
+msgstr "E¹te zostáva %d súborov k úprave. Chcete napriek tomu ukonèi» editor?"
+
+msgid "E173: 1 more file to edit"
+msgstr "E173: E¹te zostáva 1 súbor k úprave."
+
+#, c-format
+msgid "E173: %ld more files to edit"
+msgstr "E173: E¹te zostáva %ld súborov k úprave."
+
+msgid "E174: Command already exists: add ! to replace it"
+msgstr "E174: Príkaz u¾ existuje: pou¾ite ! pre predefinovanie"
+
+msgid ""
+"\n"
+" Name Args Range Complete Definition"
+msgstr ""
+"\n"
+" Meno Args Rozsah Úplnos» Definícia"
+
+msgid "No user-defined commands found"
+msgstr "Neboli nájdené ¾iadne pou¾ivateµom definované príkazy"
+
+msgid "E175: No attribute specified"
+msgstr "E175: Neboli zadané ¾iadne vlastnosti"
+
+msgid "E176: Invalid number of arguments"
+msgstr "E176: Chybný poèet argumentov"
+
+msgid "E177: Count cannot be specified twice"
+msgstr "E177: Poèet nemô¾e by» zadaný dvakrát"
+
+msgid "E178: Invalid default value for count"
+msgstr "E178: Chybná implicitná hodnota pre poèet"
+
+msgid "E179: argument required for -complete"
+msgstr "E179: pre doplnenie (-complete) je potrebný argument"
+
+#, c-format
+msgid "E181: Invalid attribute: %s"
+msgstr "E181: Chybná vlastnos»: %s"
+
+msgid "E182: Invalid command name"
+msgstr "E182: Chybné meno príkazu"
+
+msgid "E183: User defined commands must start with an uppercase letter"
+msgstr "E183: Pou¾ívateµom definované príkazy musia zaèína» veµkým písmenom"
+
+#, c-format
+msgid "E184: No such user-defined command: %s"
+msgstr "E184: Pou¾ívateµom definovaný príkaz %s neexistuje"
+
+#, c-format
+msgid "E180: Invalid complete value: %s"
+msgstr "E180: Chybná hodnota doplnenia: %s"
+
+msgid "E468: Completion argument only allowed for custom completion"
+msgstr "E468: Argument doplnenia je povolený iba pre vlastné dopåòania (completion)"
+
+msgid "E467: Custom completion requires a function argument"
+msgstr "E467: Vlastné doplnenia vy¾adujú meno funkcie ako argument"
+
+#, c-format
+msgid "E185: Cannot find color scheme %s"
+msgstr "E185: Schéma farieb %s nenájdená"
+
+msgid "Greetings, Vim user!"
+msgstr "Pozdravujem, u¾ívateµ Vimu!"
+
+msgid "Edit File in new window"
+msgstr "Upravi» súbor v novom okne"
+
+msgid "No swap file"
+msgstr "®iadny odkladací súbor"
+
+msgid "Append File"
+msgstr "Pripoji» súbor"
+
+msgid "E747: Cannot change directory, buffer is modified (add ! to override)"
+msgstr "E747: Nemo¾no zmeni» adresár, buffer je modifikovaný (pou¾ite ! pre vynútenie)"
+
+msgid "E186: No previous directory"
+msgstr "E186: ®iadny predchádzajúci adresár"
+
+msgid "E187: Unknown"
+msgstr "E187: Neznámy"
+
+msgid "E465: :winsize requires two number arguments"
+msgstr "E465: :winsize (veµkos» okna) vy¾aduje dva argumenty"
+
+#, c-format
+msgid "Window position: X %d, Y %d"
+msgstr "Pozícia okna: X %d, Y %d"
+
+msgid "E188: Obtaining window position not implemented for this platform"
+msgstr "E188: Na tejto platforme sa nedá zisti» umiestnenie okna"
+
+msgid "E466: :winpos requires two number arguments"
+msgstr "E466: :winpos (pozícia okna) vy¾aduje dva argumenty"
+
+msgid "Save Redirection"
+msgstr "Ulo¾i» presmerovanie"
+
+msgid "Save View"
+msgstr "Ulo¾i» pohµad"
+
+msgid "Save Session"
+msgstr "Ulo¾i» sedenie"
+
+msgid "Save Setup"
+msgstr "Ulo¾i» nastavenie"
+
+msgid "E739: Cannot create directory: %s"
+msgstr "E739: Nemo¾no vytvori» adresár: %s"
+
+msgid "E189: \"%s\" exists (add ! to override)"
+msgstr "E189: \"%s\" existuje (pou¾ite ! pre vynútenie)"
+
+#, c-format
+msgid "E190: Cannot open \"%s\" for writing"
+msgstr "E190: \"%s\" sa nedá otvori» pre zápis"
+
+#. set mark
+msgid "E191: Argument must be a letter or forward/backward quote"
+msgstr "E191: Argumentem mô¾e by» iba písmeno alebo pravý èi µavý apostrof"
+
+msgid "E192: Recursive use of :normal too deep"
+msgstr "E192: Rekurzívne pou¾itie príkazu :normal príli¹ hlboké"
+
+msgid "E194: No alternate file name to substitute for '#'"
+msgstr ""
+"E194: ®iadny alternatívny názov súboru, ktorým by bolo mo¾né nahradi» '#'"
+
+msgid "E495: no autocommand file name to substitute for \"<afile>\""
+msgstr "E495: ¾iadny názov súboru, ktorým by bolo mo¾né nahradi» \"<afile>\""
+
+msgid "E496: no autocommand buffer number to substitute for \"<abuf>\""
+msgstr "E496: ¾iadne èíslo bufferu, ktorým by bolo mo¾né nahradi» \"<abuf>\""
+
+msgid "E497: no autocommand match name to substitute for \"<amatch>\""
+msgstr ""
+"E497: ¾iadna zhoda automatických príkazov, ktorou by bolo mo¾né nahradi» \"<amatch>"
+"\""
+
+msgid "E498: no :source file name to substitute for \"<sfile>\""
+msgstr "E498: ¾iadny :source súbor, ktorým by bolo mo¾né nahradi» \"<sfile>\""
+
+msgid "E499: Empty file name for '%' or '#', only works with \":p:h\""
+msgstr "E499: Prázdný názov súboru pre '%' alebo '#', funguje iba s \":p:h\""
+
+msgid "E500: Evaluates to an empty string"
+msgstr "E500: Výsledkom vyhodnotenia je prázdny re»azec"
+
+msgid "E195: Cannot open viminfo file for reading"
+msgstr "E195: Súbor viminfo sa nedá sa otvori» na èítanie"
+
+msgid "E196: No digraphs in this version"
+msgstr "E196: V tejto verzi nie sú digraphy podporované"
+
+msgid "E608: Cannot :throw exceptions with 'Vim' prefix"
+msgstr "E608: Nemo¾no spracova» výnimku :throw s preponou 'Vim'"
+
+#. always scroll up, don't overwrite
+#, c-format
+msgid "Exception thrown: %s"
+msgstr "Spracovanie výnimky: %s"
+
+#, c-format
+msgid "Exception finished: %s"
+msgstr "Výnimka ukonèená: %s"
+
+#, c-format
+msgid "Exception discarded: %s"
+msgstr "Výnimka zahodená: %s"
+
+msgid "%s, line %ld"
+msgstr "%s, riadok %ld"
+
+#. always scroll up, don't overwrite
+msgid "Exception caught: %s"
+msgstr "Zachytená výnimka: %s"
+
+#, c-format
+msgid "%s made pending"
+msgstr "%s prebieha"
+
+msgid "%s resumed"
+msgstr "%s vrátené"
+
+#, c-format
+msgid "%s discarded"
+msgstr "%s zahodené"
+
+msgid "Exception"
+msgstr "Výnimka"
+
+msgid "Error and interrupt"
+msgstr "Chyba a preru¹ené"
+
+msgid "Error"
+msgstr "Chyba"
+
+#. if (pending & CSTP_INTERRUPT)
+msgid "Interrupt"
+msgstr "Preru¹ené"
+
+msgid "E579: :if nesting too deep"
+msgstr "E579: vnorenie :if je príli¹ hlboké"
+
+msgid "E580: :endif without :if"
+msgstr "E580: :endif bez zodpovedajúceho :if"
+
+msgid "E581: :else without :if"
+msgstr "E581: :else bez zodpovedajúceho :if"
+
+msgid "E582: :elseif without :if"
+msgstr "E582: :elseif bez zodpovedajúceho :if"
+
+msgid "E583: multiple :else"
+msgstr "E583: viacnásobné :else"
+
+msgid "E584: :elseif after :else"
+msgstr "E584: :elseif nasleduje po :else"
+
+msgid "E585: :while/:for nesting too deep"
+msgstr "E585: vnorenie :while/:for je príli¹ hlboké"
+
+msgid "E586: :continue without :while or :for"
+msgstr "E586: :continue bez zodpovedajúceho :while alebo :for"
+
+msgid "E587: :break without :while or :for"
+msgstr "E587: :break bez zodpovedajúceho :while alebo :for"
+
+msgid "E732: Using :endfor with :while"
+msgstr "E732: Pou¾ité :endfor spolu s :while"
+
+msgid "E733: Using :endwhile with :for"
+msgstr "E733: Pou¾ité :endwhile spolu s :for"
+
+msgid "E601: :try nesting too deep"
+msgstr "E601: vnorenie :try je príli¹ hlboké"
+
+msgid "E603: :catch without :try"
+msgstr "E603: :catch bez :try"
+
+#. Give up for a ":catch" after ":finally" and ignore it.
+#. * Just parse.
+msgid "E604: :catch after :finally"
+msgstr "E604: :catch nasleduje po :finally"
+
+msgid "E606: :finally without :try"
+msgstr "E606: :finally bez :try"
+
+#. Give up for a multiple ":finally" and ignore it.
+msgid "E607: multiple :finally"
+msgstr "E607: viacnásobné pou¾ité :finally"
+
+msgid "E602: :endtry without :try"
+msgstr "E602: :endtry bez :try"
+
+msgid "E193: :endfunction not inside a function"
+msgstr "E193: :endfunction mimo funkciu"
+
+msgid "tagname"
+msgstr "meno tagu"
+
+msgid " kind file\n"
+msgstr " typ súboru\n"
+
+msgid "'history' option is zero"
+msgstr "'voµba 'history' je nastavená na nulu"
+
+#, c-format
+msgid ""
+"\n"
+"# %s History (newest to oldest):\n"
+msgstr ""
+"\n"
+"# História %s (zaèínajúci najnov¹ou polo¾kou):\n"
+
+msgid "Command Line"
+msgstr "Príkazový riadok"
+
+msgid "Search String"
+msgstr "Vyhµadávaný re»azec"
+
+msgid "Expression"
+msgstr "Výraz"
+
+msgid "Input Line"
+msgstr "Vstupný riadok"
+
+msgid "E198: cmd_pchar beyond the command length"
+msgstr "E198: cmd_pchar prevy¹uje då¾ku príkazu"
+
+msgid "E199: Active window or buffer deleted"
+msgstr "E199: Aktívne okno alebo buffer bol vymazaný"
+
+msgid "Illegal file name"
+msgstr "Neprípustný názov súboru"
+
+msgid "is a directory"
+msgstr "je adresárom"
+
+msgid "is not a file"
+msgstr "nie je súborom"
+
+msgid "[New File]"
+msgstr "[nový súbor]"
+
+msgid "[Permission Denied]"
+msgstr "[prístup odmietnutý]"
+
+msgid "E200: *ReadPre autocommands made the file unreadable"
+msgstr "E200: automatické príkazy *ReadPre urobili súbor neèitateµným"
+
+msgid "E201: *ReadPre autocommands must not change current buffer"
+msgstr "E201: automatické príkazy *ReadPre nesmú meni» aktuálny buffer"
+
+msgid "Vim: Reading from stdin...\n"
+msgstr "Vim: èítam zo ¹tandardného vstupu...\n"
+
+msgid "Reading from stdin..."
+msgstr "Èítam zo ¹tandardného vstupu..."
+
+#. Re-opening the original file failed!
+msgid "E202: Conversion made file unreadable!"
+msgstr "E202: Po konverzii je súbor neèitateµný!"
+
+msgid "[fifo/socket]"
+msgstr "[pomenovaná rúra/soket]"
+
+msgid "[fifo]"
+msgstr "[pomenovaná rúra]"
+
+msgid "[socket]"
+msgstr "[soket]"
+
+msgid "[RO]"
+msgstr "[RO]"
+
+msgid "[CR missing]"
+msgstr "[chýba CR]"
+
+msgid "[NL found]"
+msgstr "[nájdené NL]"
+
+msgid "[long lines split]"
+msgstr "[dlhé riadky zalomené]"
+
+msgid "[NOT converted]"
+msgstr "[neskonvertovaný]"
+
+msgid "[converted]"
+msgstr "[skonvertovaný]"
+
+msgid "[crypted]"
+msgstr "[¹ifrovaný]"
+
+msgid "[CONVERSION ERROR]"
+msgstr "[CHYBA PREVODU]"
+
+#, c-format
+msgid "[ILLEGAL BYTE in line %ld]"
+msgstr "[NEPRÍPUSTNÝ BAJT na riadku %ld]"
+
+msgid "[READ ERRORS]"
+msgstr "[CHYBY ÈÍTANIA]"
+
+msgid "Can't find temp file for conversion"
+msgstr "Nedá sa nájs» doèasný súbor pre konverziu"
+
+msgid "Conversion with 'charconvert' failed"
+msgstr "Konverzia s 'charconvert' sa nepodarila"
+
+msgid "can't read output of 'charconvert'"
+msgstr "nedá sa èíta» výstup 'charconvert'"
+
+msgid "E676: No matching autocommands for acwrite buffer"
+msgstr "E676: ®iadne vyhovujúce automatické príkazy pre acwrite buffer "
+
+msgid "E203: Autocommands deleted or unloaded buffer to be written"
+msgstr ""
+"E203: Automatické príkazy zmazali èi deaktivovali buffer, ktorý mal by» "
+"ulo¾ený"
+
+msgid "E204: Autocommand changed number of lines in unexpected way"
+msgstr "E204: Automatický príkaz neoèakávaným spôsobom zmenil poèet riadkov"
+
+msgid "NetBeans disallows writes of unmodified buffers"
+msgstr "NetBeans rozhranie nedovolilo zapísa» nemodifikované buffre"
+
+msgid "Partial writes disallowed for NetBeans buffers"
+msgstr "Èiastoèné zápisy nie sú povolené pre NetBeans buffre"
+
+msgid "is not a file or writable device"
+msgstr "nie je súborom ani zapisovatelným zariadením"
+
+msgid "is read-only (add ! to override)"
+msgstr "je iba pre èítanie (pou¾ite ! pre vynútenie)"
+
+msgid "E506: Can't write to backup file (add ! to override)"
+msgstr "E506: Nedá sa zapisova» do zálo¾ného súboru (pou¾ite ! pre vynútenie)"
+
+msgid "E507: Close error for backup file (add ! to override)"
+msgstr "E507: Chyba pri uzatváraní zálo¾ného súboru (pou¾ite ! pre vynútenie)"
+
+msgid "E508: Can't read file for backup (add ! to override)"
+msgstr "E508: Nedá sa naèíta» súbor pre zálohu (pou¾ite ! pre vynútenie)"
+
+msgid "E509: Cannot create backup file (add ! to override)"
+msgstr "E509: Nedá sa vytvori» zálo¾ný súbor (pou¾ite ! pre vynútenie)"
+
+msgid "E510: Can't make backup file (add ! to override)"
+msgstr "E510: Nedá sa vytvori» zálo¾ný súbor (pou¾ite ! pre vynútenie)"
+
+# TODO: resource fork ?! Note: used only in MACOS_X version
+msgid "E460: The resource fork would be lost (add ! to override)"
+msgstr "E460: 'Resource fork' bude stratený (pou¾ite ! pre vynútenie)"
+
+msgid "E214: Can't find temp file for writing"
+msgstr "E214: Nedá sa nájs» doèasný súbor pre ukladanie"
+
+msgid "E213: Cannot convert (add ! to write without conversion)"
+msgstr "E213: Nedá sa spravi» konverzia (pou¾ite ! pre zápis bez konverzie)"
+
+msgid "E166: Can't open linked file for writing"
+msgstr "E166: Súbor sa nedá otvori» pre ukladanie"
+
+msgid "E212: Can't open file for writing"
+msgstr "E212: Súbor sa nedá otvori» pre ukladanie"
+
+msgid "E667: Fsync failed"
+msgstr "E667: Fsync zlyhal"
+
+msgid "E512: Close failed"
+msgstr "E512: Zatvorenie zlyhalo"
+
+msgid "E513: write error, conversion failed (make 'fenc' empty to override)"
+msgstr "E513: chyba pri zápise, konverzia sa nepodarila (nastavte voµbu 'fenc' na prázdnu pre vynútenie)"
+
+msgid "E514: write error (file system full?)"
+msgstr "E514: chyba pri ukladaní (plný disk?)"
+
+msgid " CONVERSION ERROR"
+msgstr " CHYBA PREVODU"
+
+msgid "[Device]"
+msgstr "[zariadenie]"
+
+msgid "[New]"
+msgstr "[nový]"
+
+msgid " [a]"
+msgstr " [p]"
+
+msgid " appended"
+msgstr " pripojený"
+
+msgid " [w]"
+msgstr " [u]"
+
+msgid " written"
+msgstr " ulo¾ený"
+
+msgid "E205: Patchmode: can't save original file"
+msgstr "E205: patchmode: nedá sa ulo¾i» pôvodný súbor"
+
+msgid "E206: patchmode: can't touch empty original file"
+msgstr "E206: patchmode: nedá sa zapisova» do prázdneho pôvodného súboru"
+
+msgid "E207: Can't delete backup file"
+msgstr "E207: Nedá sa vymaza» zálo¾ný súbor"
+
+msgid ""
+"\n"
+"WARNING: Original file may be lost or damaged\n"
+msgstr ""
+"\n"
+"VAROVANIE: Obsah pôvodného súboru mô¾e by» stratený alebo po¹kodený\n"
+
+msgid "don't quit the editor until the file is successfully written!"
+msgstr "neukonèujte editor skôr, ne¾ bude súbor úspe¹ne ulo¾ený!"
+
+msgid "[dos]"
+msgstr "[dos]"
+
+msgid "[dos format]"
+msgstr "[dos formát]"
+
+msgid "[mac]"
+msgstr "[mac]"
+
+msgid "[mac format]"
+msgstr "[mac formát]"
+
+msgid "[unix]"
+msgstr "[unix]"
+
+msgid "[unix format]"
+msgstr "[unix formát]"
+
+msgid "1 line, "
+msgstr "1 riadok, "
+
+#, c-format
+msgid "%ld lines, "
+msgstr "%ld riadkov, "
+
+msgid "1 character"
+msgstr "1 znak"
+
+#, c-format
+msgid "%ld characters"
+msgstr "%ld znakov"
+
+msgid "[noeol]"
+msgstr "[bez znaku konca riadku]"
+
+msgid "[Incomplete last line]"
+msgstr "[neúplný posledný riadok]"
+
+#. 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 "VAROVANIE: Súbor bol zmenený od jeho naèítania!!!"
+
+msgid "Do you really want to write to it"
+msgstr "Chcete ho naozaj ulo¾i»"
+
+#, c-format
+msgid "E208: Error writing to \"%s\""
+msgstr "E208: Chyba pri zápise do \"%s\""
+
+#, c-format
+msgid "E209: Error closing \"%s\""
+msgstr "E209: Chyba pri uzatváraní \"%s\""
+
+#, c-format
+msgid "E210: Error reading \"%s\""
+msgstr "E210: Chyba pri èítaní \"%s\""
+
+msgid "E246: FileChangedShell autocommand deleted buffer"
+msgstr "E246: automatický príkaz FileChangedShell vymazal buffer"
+
+msgid "E211: File \"%s\" no longer available"
+msgstr "E211: Varovanie: súbor \"%s\" u¾ nie je dostupný"
+
+#, c-format
+msgid ""
+"W12: Warning: File \"%s\" has changed and the buffer was changed in Vim as "
+"well"
+msgstr ""
+"W12: Varovanie: súbor \"%s\" bol po zaèatí úpravy zmenený a buffer sa tie¾ "
+"zmenil "
+
+msgid "See \":help W12\" for more info."
+msgstr "Pozrite \":help W12\" pre viac informácií."
+
+#, c-format
+msgid "W11: Warning: File \"%s\" has changed since editing started"
+msgstr "W11: Varovanie: súbor \"%s\" bol po zaèatí úpravy zmenený"
+
+msgid "See \":help W11\" for more info."
+msgstr "Pozrite \":help W11\" pre viac informácií."
+
+#, c-format
+msgid "W16: Warning: Mode of file \"%s\" has changed since editing started"
+msgstr ""
+"W16: Varovanie: Prístupové práva k súboru \"%s\" boli po zaèatí úprav zmenené"
+
+msgid "See \":help W16\" for more info."
+msgstr "Pozrite \":help W16\" pre viac informácií."
+
+#, c-format
+msgid "W13: Warning: File \"%s\" has been created after editing started"
+msgstr "W13: Varovanie: Súbor \"%s\" bol vytvorený po zaèatí úpravy"
+
+msgid "Warning"
+msgstr "Varovanie"
+
+msgid ""
+"&OK\n"
+"&Load File"
+msgstr ""
+"&OK\n"
+"&Naèíta» súbor"
+
+msgid "E462: Could not prepare for reloading \"%s\""
+msgstr "E462: Nemo¾no pripravi» na opätovné naèítanie \"%s\""
+
+#, c-format
+msgid "E321: Could not reload \"%s\""
+msgstr "E321: nedá sa obnovi» \"%s\""
+
+msgid "--Deleted--"
+msgstr "--Vymazaný--"
+
+#, c-format
+msgid "auto-removing autocommand: %s <buffer=%d>"
+msgstr "samomazací automatický príkaz: %s <buffer=%d>"
+
+#. the group doesn't exist
+#, c-format
+msgid "E367: No such group: \"%s\""
+msgstr "E367: Skupina \"%s\" neexistuje"
+
+#, c-format
+msgid "E215: Illegal character after *: %s"
+msgstr "E215: Neprípustný znak po *: %s"
+
+#, c-format
+msgid "E216: No such event: %s"
+msgstr "E216: Udalos» %s neexistuje"
+
+msgid "E216: No such group or event: %s"
+msgstr "E216: Udalos» alebo skupina %s neexistuje"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Auto-Commands ---"
+msgstr ""
+"\n"
+"--- Automatické príkazy ---"
+
+msgid "E680: <buffer=%d>: invalid buffer number "
+msgstr "E680: <buffer=%d>: chybné èíslo bufferu"
+
+msgid "E217: Can't execute autocommands for ALL events"
+msgstr "E217: Automatické príkazy sa nedajú spusti» pre V©ETKY udalosti"
+
+msgid "No matching autocommands"
+msgstr "®iadne vyhovujúce automatické príkazy"
+
+msgid "E218: autocommand nesting too deep"
+msgstr "E218: vnorenia automatického príkazu sú príli¹ hlboké"
+
+#, c-format
+msgid "%s Auto commands for \"%s\""
+msgstr "%s Automatické príkazy pre \"%s\""
+
+#, c-format
+msgid "Executing %s"
+msgstr "Spú¹»am %s"
+
+#, c-format
+msgid "autocommand %s"
+msgstr "automatický príkaz %s"
+
+msgid "E219: Missing {."
+msgstr "E219: Chýba {."
+
+msgid "E220: Missing }."
+msgstr "E220: Chýba }."
+
+msgid "E490: No fold found"
+msgstr "E490: Nebol nájdené ¾iadne vnorenie"
+
+msgid "E350: Cannot create fold with current 'foldmethod'"
+msgstr "E350: Nedá sa vytvori» vnorenie s aktuálnou metódou 'foldmethod'"
+
+msgid "E351: Cannot delete fold with current 'foldmethod'"
+msgstr "E351: Nedá sa zru¹i» vnorenie s aktuálnou metódou 'foldmethod'"
+
+#, c-format
+msgid "+--%3ld lines folded "
+msgstr "+--%3ld riadkov zahnutých "
+
+msgid "E222: Add to read buffer"
+msgstr "E222: Prida» do bufferu pre èítanie"
+
+msgid "E223: recursive mapping"
+msgstr "E223: rekurzívne mapovanie"
+
+#, c-format
+msgid "E224: global abbreviation already exists for %s"
+msgstr "E224: pre %s u¾ globálna skratka existuje"
+
+#, c-format
+msgid "E225: global mapping already exists for %s"
+msgstr "E225: pre %s u¾ globálne mapovanie existuje"
+
+#, c-format
+msgid "E226: abbreviation already exists for %s"
+msgstr "E226: pre %s u¾ skratka existuje"
+
+#, c-format
+msgid "E227: mapping already exists for %s"
+msgstr "E227: pre %s u¾ mapovanie existuje"
+
+msgid "No abbreviation found"
+msgstr "®iadna skratka nebola nájdená"
+
+msgid "No mapping found"
+msgstr "®iadne mapovanie nebolo nájdené"
+
+msgid "E228: makemap: Illegal mode"
+msgstr "E228: makemap: neprípustný mód"
+
+msgid "E229: Cannot start the GUI"
+msgstr "E229: Nedá sa spusti» GUI (grafické rozhranie)"
+
+#, c-format
+msgid "E230: Cannot read from \"%s\""
+msgstr "E230: Nedá sa èíta» z \"%s\""
+
+msgid "E665: Cannot start GUI, no valid font found"
+msgstr "E665: Nemo¾no na¹tartova» grafické rozhranie, nenájdený ¾iaden pou¾itelný font"
+
+msgid "E231: 'guifontwide' invalid"
+msgstr ""
+"E231: voµba 'guifontwide' (nastavenie ¹irokého písma) je chybne nastavená"
+
+msgid "E599: Value of 'imactivatekey' is invalid"
+msgstr "E599: Hodnota 'imactivatekey' je nesprávne nastavená"
+
+#, c-format
+msgid "E254: Cannot allocate color %s"
+msgstr "E254: Nedá sa alokova» farba %s"
+
+msgid "No match at cursor, finding next"
+msgstr "®iadna zhoda na pozícii kurzora, hµadám ïalej"
+
+msgid "<cannot open> "
+msgstr "<nedá sa otvori»> "
+
+msgid "E616: vim_SelFile: can't get font %s"
+msgstr "E616: vim_SelFile: písmo %s nie je dostupné"
+
+msgid "E614: vim_SelFile: can't return to current directory"
+msgstr "E614: vim_SelFile: nedá sa vráti» do aktuálneho adresára"
+
+msgid "Pathname:"
+msgstr "Názov cesty:"
+
+msgid "E615: vim_SelFile: can't get current directory"
+msgstr "E615: vim_SelFile: nedá sa zisti» aktuálny adresár"
+
+msgid "OK"
+msgstr "OK"
+
+msgid "Cancel"
+msgstr "Zru¹i»"
+
+msgid "Scrollbar Widget: Could not get geometry of thumb pixmap."
+msgstr "Prípravok posuvnej li¹ty: nedá sa zisti» geometria náhµadu obrázku."
+
+msgid "Vim dialog"
+msgstr "Vim dialóg"
+
+msgid "E232: Cannot create BalloonEval with both message and callback"
+msgstr "E232: BalloonEval nedá sa vytvori» správou a zároveò spätným volaním"
+
+msgid "Vim dialog..."
+msgstr "Vim dialóg.."
+
+# TODO: Translate as "&Ano\n&Nie\n&Zru¹i»" ?
+msgid ""
+"&Yes\n"
+"&No\n"
+"&Cancel"
+msgstr ""
+"&Ano\n"
+"&Nie\n"
+"&Zru¹i»"
+
+msgid "Input _Methods"
+msgstr "Vstupné metódy (_Methods)"
+
+msgid "VIM - Search and Replace..."
+msgstr "VIM - Nájs» a nahradi»..."
+
+msgid "VIM - Search..."
+msgstr "VIM - Nájs»..."
+
+msgid "Find what:"
+msgstr "Vyhµada»:"
+
+msgid "Replace with:"
+msgstr "Nahradi» s:"
+
+#. whole word only button
+msgid "Match whole word only"
+msgstr "Hµada» len celé slová"
+
+#. match case button
+msgid "Match case"
+msgstr "Zhoda veµkosti písmen"
+
+msgid "Direction"
+msgstr "Smer"
+
+#. 'Up' and 'Down' buttons
+msgid "Up"
+msgstr "Hore"
+
+msgid "Down"
+msgstr "Dolu"
+
+msgid "Find Next"
+msgstr "Nájs» ïal¹ie"
+
+msgid "Replace"
+msgstr "Nahradi»"
+
+msgid "Replace All"
+msgstr "Nahradi» V¹etko"
+
+msgid "Vim: Received \"die\" request from session manager\n"
+msgstr "Vim: Prijatá po¾iadavka na ukonèenie (die) od mana¾éra sedení\n"
+
+msgid "Vim: Main window unexpectedly destroyed\n"
+msgstr "Vim: Hlavné okno neoèakávane zru¹ené\n"
+
+msgid "Font Selection"
+msgstr "Výber Písma"
+
+msgid "Used CUT_BUFFER0 instead of empty selection"
+msgstr "Pou¾itý CUT_BUFFER0 namiesto prázdneho výberu"
+
+msgid "&Filter"
+msgstr "&Filter"
+
+msgid "&Cancel"
+msgstr "&Zru¹i»"
+
+msgid "Directories"
+msgstr "Adresáre"
+
+msgid "Filter"
+msgstr "Filter"
+
+msgid "&Help"
+msgstr "&Pomocník"
+
+msgid "Files"
+msgstr "Súbory"
+
+msgid "&OK"
+msgstr "&OK"
+
+msgid "Selection"
+msgstr "Výber"
+
+msgid "Find &Next"
+msgstr "Nájs» ïa&l¹ie"
+
+msgid "&Replace"
+msgstr "&Nahradi»"
+
+msgid "Replace &All"
+msgstr "Nahradi» &V¹etko"
+
+msgid "&Undo"
+msgstr "&Spä»"
+
+msgid "E671: Cannot find window title \"%s\""
+msgstr "E671: Nemo¾no nájs» okno s titulkom \"%s\""
+
+#, c-format
+msgid "E243: Argument not supported: \"-%s\"; Use the OLE version."
+msgstr "E243: Argument nie je podporovaný: \"-%s\"; Pou¾ite OLE verziu."
+
+msgid "E672: Unable to open window inside MDI application"
+msgstr "E672: Nemo¾no otvori» okno vnútri MDI aplikácie"
+
+msgid "Find string (use '\\\\' to find a '\\')"
+msgstr "Nájs» re»azec (pou¾ite '\\\\' ak chete nájs» '\\')"
+
+# Following warning can be ignored:
+# msgfmt -v --statistics --check -C --check-accelerators="&" -o sk.mo sk.po
+# sk.po:2497: msgstr lacks the keyboard accelerator mark '&'
+msgid "Find & Replace (use '\\\\' to find a '\\')"
+msgstr "Nájs» a Nahradi» (pou¾ite '\\\\' ak chcete nájs» '\\')"
+
+#. 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 "[neupravovaný]"
+
+msgid "Directory\t*.nothing\n"
+msgstr "Adresár\t*.niè\n"
+
+msgid "Vim E458: Cannot allocate colormap entry, some colors may be incorrect"
+msgstr ""
+"Vim E458: Nedá sa alokova» polo¾ka mapy farieb, niektoré farby mô¾u by» "
+"nesprávne"
+
+#, c-format
+msgid "E250: Fonts for the following charsets are missing in fontset %s:"
+msgstr "E250: Chýba písmo pre nasledujúce znakové sady %s:"
+
+#, c-format
+msgid "E252: Fontset name: %s"
+msgstr "E252: Názov sady písiem: %s"
+
+#, c-format
+msgid "Font '%s' is not fixed-width"
+msgstr "Písmo '%s' nemá pevnou ¹írku"
+
+#, c-format
+msgid "E253: Fontset name: %s\n"
+msgstr "E253: Názov sady písiem: %s\n"
+
+#, c-format
+msgid "Font0: %s\n"
+msgstr "Písmo0: %s\n"
+
+#, c-format
+msgid "Font1: %s\n"
+msgstr "Písmo1: %s\n"
+
+msgid "Font%ld width is not twice that of font0\n"
+msgstr "Písmo%ld nie je dvakrát ¹ir¹ie ako písmo0\n"
+
+#, c-format
+msgid "Font0 width: %ld\n"
+msgstr "©írka písma0: %ld\n"
+
+#, c-format
+msgid ""
+"Font1 width: %ld\n"
+"\n"
+msgstr ""
+"©írka písma1: %ld\n"
+"\n"
+
+msgid "Invalid font specification"
+msgstr "Chybná ¹pecifikácia písma"
+
+msgid "&Dismiss"
+msgstr "&Zru¹i»"
+
+msgid "no specific match"
+msgstr "¾iadna ¹pecifická zhoda"
+
+msgid "Vim - Font Selector"
+msgstr "Vim - Výber písma"
+
+msgid "Name:"
+msgstr "Meno:"
+
+#. create toggle button
+msgid "Show size in Points"
+msgstr "Ukazuj veµkos» v bodoch"
+
+msgid "Encoding:"
+msgstr "Kódujem:"
+
+msgid "Font:"
+msgstr "Písmo:"
+
+msgid "Style:"
+msgstr "©týl"
+
+msgid "Size:"
+msgstr "Veµkos»:"
+
+msgid "E256: Hangul automata ERROR"
+msgstr "E256: Hangul ERROR - chyba kórejského spôsobu vkladania znakov"
+
+msgid "E550: Missing colon"
+msgstr "E550: Chýba dvojbodka"
+
+msgid "E551: Illegal component"
+msgstr "E551: Neprípustný komponent"
+
+msgid "E552: digit expected"
+msgstr "E552: oèakávaná èíslica"
+
+#, c-format
+msgid "Page %d"
+msgstr "Strana %d"
+
+msgid "No text to be printed"
+msgstr "®iadny text na tlaè"
+
+#, c-format
+msgid "Printing page %d (%d%%)"
+msgstr "Tlaèím stranu %d (%d%%)"
+
+#, c-format
+msgid " Copy %d of %d"
+msgstr " Kópia %d z %d"
+
+#, c-format
+msgid "Printed: %s"
+msgstr "Vytlaèené: %s"
+
+msgid "Printing aborted"
+msgstr "Tlaè bola zru¹ená"
+
+msgid "E455: Error writing to PostScript output file"
+msgstr "E455: Nedá sa zapisova» do výstupného PostScriptového súboru"
+
+msgid "E624: Can't open file \"%s\""
+msgstr "E624: Nedá sa otvori» súbor \"%s\""
+
+#, c-format
+msgid "E457: Can't read PostScript resource file \"%s\""
+msgstr "E457: Nedá sa èíta» PostScriptový súbor \"%s\""
+
+msgid "E618: file \"%s\" is not a PostScript resource file"
+msgstr "E618: súbor \"%s\" nie je vo formáte PostScript"
+
+msgid "E619: file \"%s\" is not a supported PostScript resource file"
+msgstr "E619: súbor \"%s\" nie je podporvaný PostScriptový súbor"
+
+#, c-format
+msgid "E621: \"%s\" resource file has wrong version"
+msgstr "E621: \"%s\" zdrojový súbor má zlé èíslo verzie"
+
+msgid "E673: Incompatible multi-byte encoding and character set."
+msgstr "E673: nekompatibilné viacbajtové kódovanie a znaková sada."
+
+msgid "E674: printmbcharset cannot be empty with multi-byte encoding."
+msgstr "E674: voµba printmbcharset nemô¾e by» prázdna pri viacbajtovom kódovaní."
+
+msgid "E675: No default font specified for multi-byte printing."
+msgstr "E675: Nie je ¹pecifikované ¾iadne písmo pre viacbajtové tlaèenie."
+
+msgid "E324: Can't open PostScript output file"
+msgstr "E324: Nedá sa otvori» výstupný PostScriptový súbor"
+
+#, c-format
+msgid "E456: Can't open file \"%s\""
+msgstr "E456: Nedá sa otvori» súbor \"%s\""
+
+msgid "E456: Can't find PostScript resource file \"prolog.ps\""
+msgstr "E456: Nemo¾no nájs» PostScriptový zdrojový súbor \"prolog.ps\""
+
+msgid "E456: Can't find PostScript resource file \"cidfont.ps\""
+msgstr "E456: Nemo¾no nájs» PostScriptový zdrojový súbor \"cidfont.ps\""
+
+msgid "E456: Can't find PostScript resource file \"%s.ps\""
+msgstr "E456: Nemo¾no nájs» PostScriptový zdrojový súbor \"%s.ps\""
+
+#, c-format
+msgid "E620: Unable to convert to print encoding \"%s\""
+msgstr "E620: Nemo¾no skonvertova» do kódovania na tlaèenie \"%s\""
+
+msgid "Sending to printer..."
+msgstr "Posielam na tlaèiareò..."
+
+msgid "E365: Failed to print PostScript file"
+msgstr "E365: PostScriptový súbor sa nepodarilo vytlaèi»"
+
+msgid "Print job sent."
+msgstr "Tlaèová úloha bola odoslaná."
+
+msgid "Add a new database"
+msgstr "Prida» novú databázu"
+
+msgid "Query for a pattern"
+msgstr "Hµadanie vzoru"
+
+msgid "Show this message"
+msgstr "Zobrazi» túto správu"
+
+msgid "Kill a connection"
+msgstr "Ukonèi» spojenie"
+
+msgid "Reinit all connections"
+msgstr "Znovu inicializova» v¹etky spojenia"
+
+msgid "Show connections"
+msgstr "Zobrazi» spojenia"
+
+msgid "E560: Usage: cs[cope] %s"
+msgstr "E560: Pou¾itie: cs[cope] %s"
+
+msgid "This cscope command does not support splitting the window.\n"
+msgstr "Tento cscope príkaz nepodporuje rozdeµovanie okna.\n"
+
+msgid "E562: Usage: cstag <ident>"
+msgstr "E562: Pou¾itie: cstag <odsadenie>"
+
+msgid "E257: cstag: tag not found"
+msgstr "E257: cstag: tag nenájdený"
+
+msgid "E563: stat(%s) error: %d"
+msgstr "E563: stat(%s) chyba: %d"
+
+msgid "E563: stat error"
+msgstr "E563: chyba stat"
+
+msgid "E564: %s is not a directory or a valid cscope database"
+msgstr "E564: %s nie je ani adresárom ani správnou cscope databázou"
+
+#, c-format
+msgid "Added cscope database %s"
+msgstr "Pridaná cscope databáza %s"
+
+msgid "E262: error reading cscope connection %ld"
+msgstr "E262: chyba pri èítaní cscope spojenia %ld"
+
+msgid "E561: unknown cscope search type"
+msgstr "E561: neznámy typ cscope hµadania"
+
+msgid "E566: Could not create cscope pipes"
+msgstr "E566: Nedajú sa vytvori» cscope rúry"
+
+msgid "E622: Could not fork for cscope"
+msgstr "E622: Nemo¾no spusti» proces pre cscope"
+
+msgid "cs_create_connection exec failed"
+msgstr "spustenie cs_create_connection zlyhalo"
+
+msgid "E623: Could not spawn cscope process"
+msgstr "E623: Nedajú sa vytvori» cscope rúry"
+
+msgid "cs_create_connection: fdopen for to_fp failed"
+msgstr "cs_create_connection: volanie fdopen pre to_fp zlyhalo"
+
+msgid "cs_create_connection: fdopen for fr_fp failed"
+msgstr "cs_create_connection: volanie fdopen pre fr_fp zlyhalo"
+
+msgid "E567: no cscope connections"
+msgstr "E567: ¾iadne cscope spojenia"
+
+#, c-format
+msgid "E259: no matches found for cscope query %s of %s"
+msgstr "E259: cscope hµadanie %s vo vzore %s nena¹lo ¾iadnu zhodu"
+
+#, c-format
+msgid "E469: invalid cscopequickfix flag %c for %c"
+msgstr "E469: chybný cscopequickfix príznak %c pre %c"
+
+msgid "cscope commands:\n"
+msgstr "príkazy cscope:\n"
+
+msgid "%-5s: %-30s (Usage: %s)"
+msgstr "%-5s: %-30s (Pou¾itie: %s)"
+
+msgid "E625: cannot open cscope database: %s"
+msgstr "E625: nemo¾no otvori» cscope databázu: %s"
+
+msgid "E626: cannot get cscope database information"
+msgstr "E626: nemo¾no získa» cscope databázové informácie"
+
+msgid "E568: duplicate cscope database not added"
+msgstr "E568: duplicitná cscope databáza nebola pridaná"
+
+msgid "E569: maximum number of cscope connections reached"
+msgstr "E569: dosiahnutý maximálny poèet cscope spojení"
+
+#, c-format
+msgid "E261: cscope connection %s not found"
+msgstr "E261: cscope spojenie %s nenájdené"
+
+msgid "cscope connection %s closed"
+msgstr "cscope spojenie %s ukonèené"
+
+#. should not reach here
+msgid "E570: fatal error in cs_manage_matches"
+msgstr "E570: vá¾na chyba v cs_manage_matches"
+
+msgid "Cscope tag: %s"
+msgstr "Cscope tag: %s"
+
+msgid ""
+"\n"
+" # line"
+msgstr ""
+"\n"
+" # riadok"
+
+msgid "filename / context / line\n"
+msgstr "názov súboru/ kontext / riadok\n"
+
+msgid "E609: Cscope error: %s"
+msgstr "E609: Chyba cscope: %s"
+
+msgid "All cscope databases reset"
+msgstr "V¹etky cscope databáze resetované"
+
+msgid "no cscope connections\n"
+msgstr "¾iadne cscope spojenia\n"
+
+msgid " # pid database name prepend path\n"
+msgstr " # pid názov databázy predpona cesty\n"
+
+msgid ""
+"???: Sorry, this command is disabled, the MzScheme library could not be "
+"loaded."
+msgstr "???: Prepáète, tento príkaz je vypnutý, MzScheme kni¾nica nemô¾e by» naèítaná."
+
+msgid "invalid expression"
+msgstr "chybný výraz"
+
+msgid "expressions disabled at compile time"
+msgstr "podpora výrazov bola vypnutá pri preklade programu"
+
+msgid "hidden option"
+msgstr "skrytá voµba"
+
+msgid "unknown option"
+msgstr "neznáma voµba"
+
+msgid "window index is out of range"
+msgstr "èíslo okna mimo rozsah"
+
+msgid "couldn't open buffer"
+msgstr "nemo¾no otvori» buffer"
+
+msgid "cannot save undo information"
+msgstr "nedajú sa ulo¾i» zálo¾ne (opravné) informácie"
+
+msgid "cannot delete line"
+msgstr "nedá sa vymaza» riadok"
+
+msgid "cannot replace line"
+msgstr "nedá sa nahradi» riadok"
+
+msgid "cannot insert line"
+msgstr "nedá sa vlo¾i» riadok"
+
+msgid "string cannot contain newlines"
+msgstr "re»azec nesmie obsahova» znaky nového riadku"
+
+msgid "Vim error: ~a"
+msgstr "Chyba Vim: ~a"
+
+msgid "Vim error"
+msgstr "Chyba Vim"
+
+msgid "buffer is invalid"
+msgstr "buffer je neplatný"
+
+msgid "window is invalid"
+msgstr "okno je neplatné"
+
+msgid "linenr out of range"
+msgstr "èíslo riadka mimo rozsah"
+
+msgid "not allowed in the Vim sandbox"
+msgstr "nie je dovolené v bezpeènostnej schránke"
+
+msgid ""
+"E263: Sorry, this command is disabled, the Python library could not be "
+"loaded."
+msgstr ""
+"E262: Prepáète, tento príkaz je vypnutý, Python kni¾nica nemô¾e by» naèítaná."
+
+msgid "E659: Cannot invoke Python recursively"
+msgstr "E659: Python nemô¾e by» spustený rekurzívne"
+
+msgid "can't delete OutputObject attributes"
+msgstr "nedá sa vymaza» vlastnos» OutputObject"
+
+msgid "softspace must be an integer"
+msgstr "softspace musí by» kladné celé èíslo"
+
+msgid "invalid attribute"
+msgstr "chybná vlastnos»"
+
+msgid "writelines() requires list of strings"
+msgstr "writelines() vy¾aduje zoznam re»azcov"
+
+msgid "E264: Python: Error initialising I/O objects"
+msgstr "E264: Python: Chyba pri inicializácii I/O objektov"
+
+msgid "attempt to refer to deleted buffer"
+msgstr "pokus o odkaz na vymazaný buffer"
+
+msgid "line number out of range"
+msgstr "èíslo riadka mimo rozsah"
+
+#, c-format
+msgid "<buffer object (deleted) at %8lX>"
+msgstr "<objekt bufferu (vymazaný) na %8lX>"
+
+msgid "invalid mark name"
+msgstr "chybné meno znaèky"
+
+msgid "no such buffer"
+msgstr "¾iadny taký buffer"
+
+msgid "attempt to refer to deleted window"
+msgstr "pokus o odkaz na vymazané okno"
+
+msgid "readonly attribute"
+msgstr "vlastnos» iba pre èítanie"
+
+msgid "cursor position outside buffer"
+msgstr "umiestnenie kurzoru mimo buffer"
+
+#, c-format
+msgid "<window object (deleted) at %.8lX>"
+msgstr "<objekt okna (vymazaný) na %.8lX>"
+
+#, c-format
+msgid "<window object (unknown) at %.8lX>"
+msgstr "<objekt okna (neznámy) na %.8lX>"
+
+#, c-format
+msgid "<window %d>"
+msgstr "<okno %d>"
+
+msgid "no such window"
+msgstr "¾iadne také okno"
+
+msgid ""
+"E266: Sorry, this command is disabled, the Ruby library could not be loaded."
+msgstr ""
+"E266: Prepáète, tento príkaz je vypnutý, Ruby kni¾nica nemô¾e by» naèítaná."
+
+#, c-format
+msgid "E273: unknown longjmp status %d"
+msgstr "E273: Neznámy 'longjmp' stav %d"
+
+msgid "Toggle implementation/definition"
+msgstr "Prepnú» implementáciu/definíciu"
+
+msgid "Show base class of"
+msgstr "Ukáza» základnú triedu"
+
+msgid "Show overridden member function"
+msgstr "Ukáza» pre»a¾enú èlenskú funkciu"
+
+msgid "Retrieve from file"
+msgstr "Obnovi» zo súboru"
+
+msgid "Retrieve from project"
+msgstr "Obnovi» z projektu"
+
+msgid "Retrieve from all projects"
+msgstr "Obnovi» zo v¹etkých projektov"
+
+msgid "Retrieve"
+msgstr "Obnovi»"
+
+msgid "Show source of"
+msgstr "Ukáza» zdroj"
+
+msgid "Find symbol"
+msgstr "Nájs» znak"
+
+msgid "Browse class"
+msgstr "Prezrie» triedu"
+
+msgid "Show class in hierarchy"
+msgstr "Ukáza» triedu v hierarchii"
+
+msgid "Show class in restricted hierarchy"
+msgstr "Ukáza» triedu v obmedzenej hierarchii"
+
+msgid "Xref refers to"
+msgstr "Xref odkazuje na"
+
+msgid "Xref referred by"
+msgstr "Xref odkázaný z"
+
+msgid "Xref has a"
+msgstr "Xref má"
+
+msgid "Xref used by"
+msgstr "Xref pou¾itý"
+
+msgid "Show docu of"
+msgstr "Ukáza» dokumentáciu"
+
+msgid "Generate docu for"
+msgstr "Vytvori» dokumentáciu pre"
+
+msgid ""
+"Cannot connect to SNiFF+. Check environment (sniffemacs must be found in "
+"$PATH).\n"
+msgstr ""
+"Zlyhalo pripojenie na SNiFF+, Preverte prostredie (sniffemacs sa musí "
+"nachádza» v $PATH).\n"
+
+msgid "E274: Sniff: Error during read. Disconnected"
+msgstr "E274: Sniff: Chyba poèas èítania. Odpojené"
+
+msgid "SNiFF+ is currently "
+msgstr "SNiFF+ je aktuálne "
+
+msgid "not "
+msgstr "ne"
+
+msgid "connected"
+msgstr "pripojený"
+
+#, c-format
+msgid "E275: Unknown SNiFF+ request: %s"
+msgstr "E275: Neznáma SNiFF+ po¾iadavka: %s"
+
+msgid "E276: Error connecting to SNiFF+"
+msgstr "E276: Chyba pripojenia na SNiFF+"
+
+msgid "E278: SNiFF+ not connected"
+msgstr "E278: SNiFF+ nie je pripojený"
+
+msgid "E279: Not a SNiFF+ buffer"
+msgstr "E279: Nie je SNiFF+ bufferom"
+
+msgid "Sniff: Error during write. Disconnected"
+msgstr "Sniff: Chyba zápisu. Odpojené"
+
+msgid "invalid buffer number"
+msgstr "chybné èíslo bufferu"
+
+msgid "not implemented yet"
+msgstr "nie je e¹te podporované"
+
+#. ???
+msgid "cannot set line(s)"
+msgstr "nedajú sa nastavi» riadky"
+
+msgid "mark not set"
+msgstr "znaèka nie je nastavená"
+
+#, c-format
+msgid "row %d column %d"
+msgstr "riadok %d ståpec %d"
+
+msgid "cannot insert/append line"
+msgstr "nedá sa vlo¾i»/pripoji» riadok"
+
+msgid "unknown flag: "
+msgstr "neznámy príznak: "
+
+msgid "unknown vimOption"
+msgstr "neznáma voµba (vimOption)"
+
+msgid "keyboard interrupt"
+msgstr "preru¹enie z klávesnice"
+
+msgid "vim error"
+msgstr "chyba Vim"
+
+msgid "cannot create buffer/window command: object is being deleted"
+msgstr "nedá sa vytvori» príkaz bufferu/okna: objekt bude vymazaný"
+
+msgid ""
+"cannot register callback command: buffer/window is already being deleted"
+msgstr ""
+"nedá sa zaregistrova» príkaz spätného volania: buffer/okno u¾ bol vymazaný"
+
+#. This should never happen. Famous last word?
+msgid ""
+"E280: TCL FATAL ERROR: reflist corrupt!? Please report this to vim-dev@vim."
+"org"
+msgstr ""
+"E280: TCL FATAL ERROR: reflist po¹kodený!? Oznámte, prosím, túto chybu na "
+"vim-dev@vim.org"
+
+msgid "cannot register callback command: buffer/window reference not found"
+msgstr ""
+"nedá sa zaregistrova» príkaz spätného volania: odkaz na buffer/okno nenájdený"
+
+msgid ""
+"E571: Sorry, this command is disabled: the Tcl library could not be loaded."
+msgstr ""
+"E571: Prepáète, tento príkaz je vypnutý, Tcl kni¾nica nemô¾e by» naèítaná."
+
+msgid ""
+"E281: TCL ERROR: exit code is not int!? Please report this to vim-dev@vim.org"
+msgstr ""
+"E281: TCL CHYBA: návratový kód nie je celé èíslo!? Oznámte, prosím, túto "
+"chybu na vim-dev@vim.org"
+
+#, c-format
+msgid "E572: exit code %d"
+msgstr "E572: návratový kód %d"
+
+msgid "cannot get line"
+msgstr "nedá sa preèíta» riadok"
+
+msgid "Unable to register a command server name"
+msgstr "Nemô¾em zaregistrova» meno príkazového servra"
+
+msgid "E248: Failed to send command to the destination program"
+msgstr "E248: Chyba poèas prenosu príkazu do cieµového programu"
+
+msgid "E573: Invalid server id used: %s"
+msgstr "E573: Pou¾íté chybné èíslo servera: %s"
+
+msgid "E251: VIM instance registry property is badly formed. Deleted!"
+msgstr "E251: VIM registrová vlastnos» je zle formátovaná. Vymazané!"
+
+msgid "Unknown option argument"
+msgstr "Neznámy parameter voµby"
+
+msgid "Too many edit arguments"
+msgstr "Príli¹ mnoho upravovacích argumentov"
+
+msgid "Argument missing after"
+msgstr "Chýba argument po"
+
+msgid "Garbage after option argument"
+msgstr "Chyby za parametrom voµby"
+
+msgid "Too many \"+command\", \"-c command\" or \"--cmd command\" arguments"
+msgstr "Príli¹ mnoho \"+príkaz\", \"-c príkaz\" alebo \"--cmd príkaz\" argumentov"
+
+msgid "Invalid argument for"
+msgstr "Chybný argument pre"
+
+#, c-format
+msgid "%d files to edit\n"
+msgstr "%d súborov pre úpravu\n"
+
+msgid "This Vim was not compiled with the diff feature."
+msgstr "Tento Vim nebol kompilovaný s porovnávacími funkciami."
+
+msgid "Attempt to open script file again: \""
+msgstr "Pokus o opätovné otvorenie skriptu: \""
+
+msgid "Cannot open for reading: \""
+msgstr "Nedá sa otvori» pre zápis: \""
+
+msgid "Cannot open for script output: \""
+msgstr "Nedá sa otvori» pre výstup skriptu: \""
+
+msgid "Vim: Error: Failure to start gvim from NetBeans\n"
+msgstr "Vim: Chyba: Chyba spú¹»ania gvim pre NetBeans\n"
+
+msgid "Vim: Warning: Output is not to a terminal\n"
+msgstr "Vim: Varovanie: Výstup nesmeruje na terminál\n"
+
+msgid "Vim: Warning: Input is not from a terminal\n"
+msgstr "Vim: Varovanie: Vstup nepochádza z terminálu\n"
+
+#. just in case..
+msgid "pre-vimrc command line"
+msgstr "pre-vimrc príkazový riadok"
+
+#, c-format
+msgid "E282: Cannot read from \"%s\""
+msgstr "E282: Nedá sa èíta» z \"%s\""
+
+msgid ""
+"\n"
+"More info with: \"vim -h\"\n"
+msgstr ""
+"\n"
+"Podrobnej¹ie informácie získáte pomocou \"vim -h\"\n"
+
+msgid "[file ..] edit specified file(s)"
+msgstr "[súbor ..] .. upravi» súbor(y)"
+
+msgid "- read text from stdin"
+msgstr "- èíta» text z ¹tandardného vstupu"
+
+msgid "-t tag edit file where tag is defined"
+msgstr "-t tag upravi» súbor na mieste definície tagu"
+
+msgid "-q [errorfile] edit file with first error"
+msgstr "-q [chybový súbor] upravi» súbor na mieste výskytu prvej chyby"
+
+msgid ""
+"\n"
+"\n"
+"usage:"
+msgstr ""
+"\n"
+"\n"
+"pou¾itie:"
+
+msgid " vim [arguments] "
+msgstr "vim [argumenty] "
+
+msgid ""
+"\n"
+" or:"
+msgstr ""
+"\n"
+" alebo:"
+
+#. TODO: is translation correct?
+msgid "where case is ignored prepend / to make flag upper case"
+msgstr "v prípade, ¾e je ignorovaná veµkos» písmen, pou¾ite znak '/' na zaèiatku, aby mal príznak význam veµkého písmena"
+
+msgid ""
+"\n"
+"\n"
+"Arguments:\n"
+msgstr ""
+"\n"
+"\n"
+"Argumenty:\n"
+
+msgid "--\t\t\tOnly file names after this"
+msgstr "--\t\t\tMô¾u nasledova» iba názvy súborov"
+
+msgid "--literal\t\tDon't expand wildcards"
+msgstr "--literal\t\tNexpandova» ¾olíkové znaky (wildcards)"
+
+msgid "-register\t\tRegister this gvim for OLE"
+msgstr "-register\t\tPrihlási» gvim na OLE"
+
+msgid "-unregister\t\tUnregister gvim for OLE"
+msgstr "-register\t\tOdhlási» gvim z OLE"
+
+msgid "-g\t\t\tRun using GUI (like \"gvim\")"
+msgstr "-g\t\t\tSpusti» v grafickom (GUI) móde (rovnaké ako \"gvim\")"
+
+msgid "-f or --nofork\tForeground: Don't fork when starting GUI"
+msgstr ""
+"-f alebo --nofork\tPopredie: Pri spustení grafického (GUI) módu sa nepresunie do pozadia"
+
+msgid "-v\t\t\tVi mode (like \"vi\")"
+msgstr "-v\t\t\tVi mód (rovnaké ako \"vi\")"
+
+msgid "-e\t\t\tEx mode (like \"ex\")"
+msgstr "-e\t\t\tEx mód (rovnaké ako \"ex\")"
+
+msgid "-s\t\t\tSilent (batch) mode (only for \"ex\")"
+msgstr "-s\t\t\tTichý (dávkový) mód (iba pre \"ex\")"
+
+msgid "-d\t\t\tDiff mode (like \"vimdiff\")"
+msgstr "-d\t\t\tPorovnávací mód (rovnaké ako \"vimdiff\")"
+
+msgid "-y\t\t\tEasy mode (like \"evim\", modeless)"
+msgstr "-y\t\t\tJednoduchý mód (rovnaké ako \"evim\", bezmódový)"
+
+msgid "-R\t\t\tReadonly mode (like \"view\")"
+msgstr "-R\t\t\tMód iba pre èítanie (ako \"view\")"
+
+msgid "-Z\t\t\tRestricted mode (like \"rvim\")"
+msgstr "-Z\t\t\tObmedzený mód (rovnaké ako \"rvim\")"
+
+msgid "-m\t\t\tModifications (writing files) not allowed"
+msgstr "-m\t\t\tZmeny (ukladanie súborov) zakázané"
+
+msgid "-M\t\t\tModifications in text not allowed"
+msgstr "-M\t\t\tZmeny v texte zakázané"
+
+msgid "-b\t\t\tBinary mode"
+msgstr "-b\t\t\tBinárny mód"
+
+msgid "-l\t\t\tLisp mode"
+msgstr "-l\t\t\tLisp mód"
+
+msgid "-C\t\t\tCompatible with Vi: 'compatible'"
+msgstr "-C\t\t\tKompatabilný s Vi: 'compatible'"
+
+msgid "-N\t\t\tNot fully Vi compatible: 'nocompatible'"
+msgstr "-N\t\t\tKompatibilita s Vi vypnutá: 'nocompatible'"
+
+msgid "-V[N]\t\tVerbose level"
+msgstr "-V[N]\t\tÚroveò výpisu hlá¹ok"
+
+msgid "-D\t\t\tDebugging mode"
+msgstr "-D\t\t\tLadiaci mód"
+
+msgid "-n\t\t\tNo swap file, use memory only"
+msgstr "-n\t\t\tNevytvára» odkladací súbor, pou¾íva» iba pamä»"
+
+msgid "-r\t\t\tList swap files and exit"
+msgstr "-r\t\t\tVypí¹ zoznam odkladacích súborov a skonèi"
+
+msgid "-r (with file name)\tRecover crashed session"
+msgstr "-r (s názvom súboru)\tObnoví preru¹ené sedenie"
+
+msgid "-L\t\t\tSame as -r"
+msgstr "-L\t\t\tRovnaké ako -r"
+
+msgid "-f\t\t\tDon't use newcli to open window"
+msgstr "-f\t\t\tNebude pou¾íva» newcli pre otvorenie okna"
+
+msgid "-dev <device>\t\tUse <device> for I/O"
+msgstr "-dev <zariadenie>\t\tPou¾i» <zariadenie> pre I/O"
+
+msgid "-A\t\t\tstart in Arabic mode"
+msgstr "-A\t\t\tspusti v Arabic móde"
+
+msgid "-H\t\t\tStart in Hebrew mode"
+msgstr "-H\t\t\tspusti v hebrejskom móde"
+
+msgid "-F\t\t\tStart in Farsi mode"
+msgstr "-F\t\t\tspusti vo Farsi móde"
+
+msgid "-T <terminal>\tSet terminal type to <terminal>"
+msgstr "-T <terminál>\tNastaví typ terminálu na <terminál>"
+
+msgid "-u <vimrc>\t\tUse <vimrc> instead of any .vimrc"
+msgstr "-u <vimrc>\t\tPou¾ije <vimrc> namiesto akéhokoµvek .vimrc"
+
+msgid "-U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc"
+msgstr "-U <gvimrc>\t\tPou¾ije <gvimrc> namiesto akéhokoµvek .gvimrc"
+
+msgid "--noplugin\t\tDon't load plugin scripts"
+msgstr "--noplugin\t\tNenahrá zásuvné moduly(plugin skripty)"
+
+msgid "-o[N]\t\tOpen N windows (default: one for each file)"
+msgstr "-o[N]\t\tOtvorí N okien (implicitne jedno pre ka¾dý súbor)"
+
+msgid "-O[N]\t\tLike -o but split vertically"
+msgstr "-O[N]\t\tAko -o ale rozdelí vertikálne"
+
+msgid "+\t\t\tStart at end of file"
+msgstr "+\t\t\tNastaví kurzor na koniec súboru"
+
+msgid "+<lnum>\t\tStart at line <lnum>"
+msgstr "+<riadok>\t\tNastaví kurzor na <riadok>"
+
+msgid "--cmd <command>\tExecute <command> before loading any vimrc file"
+msgstr "--cmd <príkaz>\t\tVykoná <príkaz> pred nahratím vimrc súboru"
+
+msgid "-c <command>\t\tExecute <command> after loading the first file"
+msgstr "-c <príkaz>\t\tPo nahratí prvého súboru vykoná <príkaz>"
+
+msgid "-S <session>\t\tSource file <session> after loading the first file"
+msgstr ""
+"-S <sedenie>\t\tPo nahratí prvého súboru vykoná príkazy v súbore <sedenie>"
+
+msgid "-s <scriptin>\tRead Normal mode commands from file <scriptin>"
+msgstr "-s <skript>\t\tNaèíta príkazy normálneho módu zo <skriptu>"
+
+msgid "-w <scriptout>\tAppend all typed commands to file <scriptout>"
+msgstr "-w <skript>\t\tPripojí v¹etky napísané príkazy do súboru <skript>"
+
+msgid "-W <scriptout>\tWrite all typed commands to file <scriptout>"
+msgstr "-W <skript>\t\tUlo¾í v¹etky napísané príkazy do súboru <skript>"
+
+msgid "-x\t\t\tEdit encrypted files"
+msgstr "-x\t\t\tÚprava za¹ifrovaných súborov"
+
+msgid "-display <display>\tConnect vim to this particular X-server"
+msgstr "-display <displej>\tPripojí vim na príslu¹ný X-server"
+
+msgid "-X\t\t\tDo not connect to X server"
+msgstr "-X\t\t\tNepripojí sa k X serveru"
+
+msgid "--remote <files>\tEdit <files> in a Vim server if possible"
+msgstr "--remote <súbory>\tUpravi» <súbory> na Vim servri ak je to mo¾né"
+
+msgid "--remote-silent <files> Same, don't complain if there is no server"
+msgstr "--remote-silent <súbory>\tTo isté, ale nes»a¾uj si, ak neexistuje server"
+
+msgid ""
+"--remote-wait <files> As --remote but wait for files to have been edited"
+msgstr ""
+"--remote-wait <súbory>\tAko --remote ale èaká na súbory pre ukonèenie úprav"
+
+msgid ""
+"--remote-wait-silent <files> Same, don't complain if there is no server"
+msgstr "--remote-wait-silent <súbory>\tTo isté, ale nes»a¾uj si, ak neexistuje server"
+
+msgid "--remote-send <keys>\tSend <keys> to a Vim server and exit"
+msgstr "--remote-send <voµby>\tOdo¹le <voµby> na Vim server a skonèí"
+
+msgid "--remote-expr <expr>\tEvaluate <expr> in a Vim server and print result"
+msgstr "--remote-expr <výraz>\tSpusti <výraz> na servri a vytlaèí výsledok"
+
+msgid "--serverlist\t\tList available Vim server names and exit"
+msgstr "--serverlist\t\tVypí¹e zoznam mien dostupných Vim servrov a skonèí"
+
+msgid "--servername <name>\tSend to/become the Vim server <name>"
+msgstr "--servername <názov>\tOdo¹le na Vim server <názov>"
+
+msgid "-i <viminfo>\t\tUse <viminfo> instead of .viminfo"
+msgstr "-i <viminfo>\t\tPou¾ije <viminfo> namiesto akéhokoµvek .viminfo"
+
+msgid "-h or --help\tPrint Help (this message) and exit"
+msgstr "-h alebo --help\tVypí¹e túto nápovedu a skonèí"
+
+msgid "--version\t\tPrint version information and exit"
+msgstr "--version\t\tVypí¹e informácie o verzii a skonèí"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (Motif version):\n"
+msgstr ""
+"\n"
+"Argumenty dostupné pre gvim (Motif verzia):\n"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (neXtaw version):\n"
+msgstr ""
+"\n"
+"Argumenty dostupné pre gvim (neXtaw verzia):\n"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (Athena version):\n"
+msgstr ""
+"\n"
+"Argumenty dostupné pre gvim (Athena verzia):\n"
+
+msgid "-display <display>\tRun vim on <display>"
+msgstr "-display <displej>\tSpustí vim na <displej>"
+
+msgid "-iconic\t\tStart vim iconified"
+msgstr "-iconic\t\tSpustí vim minimalizované"
+
+msgid "-name <name>\t\tUse resource as if vim was <name>"
+msgstr "-name <názov>\t\tPou¾ije resource ako by vim mal <názov>"
+
+msgid "\t\t\t (Unimplemented)\n"
+msgstr "\t\t\t (nie je implementované)\n"
+
+msgid "-background <color>\tUse <color> for the background (also: -bg)"
+msgstr "-background <farba>\tNastaví sa <farba> pozadia (tie¾ -bg)"
+
+msgid "-foreground <color>\tUse <color> for normal text (also: -fg)"
+msgstr "-foreground <farba>\tNastaví sa <farba> popredia (tie¾ -fg)"
+
+msgid "-font <font>\t\tUse <font> for normal text (also: -fn)"
+msgstr "-font <písmo>\t\tNastaví <písmo> normálneho textu (tie¾ -fn)"
+
+msgid "-boldfont <font>\tUse <font> for bold text"
+msgstr "-boldfont <písmo>\tNastaví <písmo> pre zvýraznený text"
+
+msgid "-italicfont <font>\tUse <font> for italic text"
+msgstr "-italicfont <písmo>\tNastaví <písmo> pre kurzívu"
+
+msgid "-geometry <geom>\tUse <geom> for initial geometry (also: -geom)"
+msgstr "-geometry <geometrie>\tNastaví sa <geometria> (tie¾ -geom)"
+
+msgid "-borderwidth <width>\tUse a border width of <width> (also: -bw)"
+msgstr "-borderwidth <¹írka>\tNastaví <¹írku> okrajov (tie¾ -bw)"
+
+msgid "-scrollbarwidth <width> Use a scrollbar width of <width> (also: -sw)"
+msgstr "-scrollbarwidth <¹írka> Nastaví <¹írku> posuvnej li¹ty (tie¾ -sw)"
+
+msgid "-menuheight <height>\tUse a menu bar height of <height> (also: -mh)"
+msgstr "-menuheight <vý¹ka>\tNastaví <vý¹ku> ponuky (tie¾ -mh)"
+
+msgid "-reverse\t\tUse reverse video (also: -rv)"
+msgstr "-reverse\t\tPou¾ije reverzné farby (tie¾ -rv)"
+
+msgid "+reverse\t\tDon't use reverse video (also: +rv)"
+msgstr "+reverse\t\tNepou¾ije reverzné farby (tie¾ +rv)"
+
+# TODO: howto translate 'resource' in this case?
+msgid "-xrm <resource>\tSet the specified resource"
+msgstr "-xrm <resource>\tNastaví zadaný <resource>"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (RISC OS version):\n"
+msgstr ""
+"\n"
+"Argumenty dostupné pre gvim (RISC OS verzia):\n"
+
+msgid "--columns <number>\tInitial width of window in columns"
+msgstr "--columns <poèet>\tPoèiatoèná ¹írka okna v ståpcoch"
+
+msgid "--rows <number>\tInitial height of window in rows"
+msgstr "--rows <poèet>\tPoèiatoèná vý¹ka okna v riadkoch"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (GTK+ version):\n"
+msgstr ""
+"\n"
+"Argumenty dostupné pre gvim (GTK+ verzia):\n"
+
+msgid "-display <display>\tRun vim on <display> (also: --display)"
+msgstr "-display <displej>\tSpustí vim na <displej> (tie¾ --display)"
+
+msgid "--role <role>\tSet a unique role to identify the main window"
+msgstr "-role <rola>\tNastaví unikátnu rolu pre identifikáciu hlavného okna"
+
+msgid "--socketid <xid>\tOpen Vim inside another GTK widget"
+msgstr "--socketid <xid>\tOtvorí Vim vnútri iného GTK programu."
+
+msgid ""
+"\n"
+"Arguments recognised by kvim (KDE version):\n"
+msgstr ""
+"\n"
+"Argumenty dostupné pre kvim (KDE verzia):\n"
+
+msgid "-black\t\tUse reverse video"
+msgstr "-black\t\tPou¾ije reverzné farby"
+
+msgid "-tip\t\t\tDisplay the tip dialog on startup"
+msgstr "-tip\t\t\tZobraz tip pri ¹tarte"
+
+msgid "-notip\t\tDisable the tip dialog"
+msgstr "-notip\t\tNezobrazuj tip pri ¹tarte"
+
+msgid "--display <display>\tRun vim on <display>"
+msgstr "-display <displej>\tSpustí vim na <displej>"
+
+msgid "-P <parent title>\tOpen Vim inside parent application"
+msgstr "-P <titulok rodièa>\tOtvor Vim vnútri materskej aplikácie"
+
+msgid "No display"
+msgstr "Bez grafického rozhrania"
+
+#. Failed to send, abort.
+msgid ": Send failed.\n"
+msgstr ": Odoslanie zlyhalo.\n"
+
+#. Let vim start normally.
+msgid ": Send failed. Trying to execute locally\n"
+msgstr ": Odoslanie zlyhalo. Pokú¹am sa spusti» lokálne\n"
+
+#, c-format
+msgid "%d of %d edited"
+msgstr "%d upravených súborov z %d"
+
+msgid "No display: Send expression failed.\n"
+msgstr "®iaden graf. mód: Odoslanie výrazu zlyhalo.\n"
+
+msgid ": Send expression failed.\n"
+msgstr ": Odoslanie výrazu zlyhalo.\n"
+
+msgid "No marks set"
+msgstr "Nie sú nastavené ¾iadne znaèky"
+
+#, c-format
+msgid "E283: No marks matching \"%s\""
+msgstr "E283:\"%s\" nevyhovujú ¾iadne znaèky"
+
+#. Highlight title
+msgid ""
+"\n"
+"mark line col file/text"
+msgstr ""
+"\n"
+"znaèka riadok ståpec súbor/text"
+
+#. Highlight title
+msgid ""
+"\n"
+" jump line col file/text"
+msgstr ""
+"\n"
+" skok riadok ståpec súbor/text"
+
+#. Highlight title
+msgid ""
+"\n"
+"change line col text"
+msgstr ""
+"\n"
+"znaèka riadok ståpec text"
+
+#, c-format
+msgid ""
+"\n"
+"# File marks:\n"
+msgstr ""
+"\n"
+"# Súborové znaèky:\n"
+
+#. Write the jumplist with -'
+#, c-format
+msgid ""
+"\n"
+"# Jumplist (newest first):\n"
+msgstr ""
+"\n"
+"# Zoznam skokov (zaèínajúci najnov¹ou polo¾kou):\n"
+
+#, c-format
+msgid ""
+"\n"
+"# History of marks within files (newest to oldest):\n"
+msgstr ""
+"\n"
+"# História znaèiek v súboroch (zaèínajúci najnov¹ou polo¾kou):\n"
+
+msgid "Missing '>'"
+msgstr "Chýba '>'"
+
+msgid "E543: Not a valid codepage"
+msgstr "E543: Chybná kódová stránka"
+
+msgid "E284: Cannot set IC values"
+msgstr "E284: Nedajú sa nastavi» IC hodnoty"
+
+msgid "E285: Failed to create input context"
+msgstr "E285: Nepodarilo sa vytvori» vstupný kontext"
+
+msgid "E286: Failed to open input method"
+msgstr "E286: Nepodarilo sa otvori» vstupnú metódu"
+
+msgid "E287: Warning: Could not set destroy callback to IM"
+msgstr "E287: Varovanie: likvidaèné spätné volanie sa nedá nastavi» na IM"
+
+msgid "E288: input method doesn't support any style"
+msgstr "E288: vstupná metóda nepodporuje ¾iadny ¹týl"
+
+msgid "E289: input method doesn't support my preedit type"
+msgstr "E289: vstupná metóda nepodporuje môj 'preedit' typ"
+
+msgid "E290: over-the-spot style requires fontset"
+msgstr "E290: Nadbodový ¹týl vy¾aduje sadu fontov (fontset)"
+
+msgid "E291: Your GTK+ is older than 1.2.3. Status area disabled"
+msgstr "E291: Máte GTK+ verziu star¹iu ne¾ 1.2.3. Stavová plocha vypnutá."
+
+msgid "E292: Input Method Server is not running"
+msgstr "E292: Server vstupných metód nebe¾í"
+
+msgid "E293: block was not locked"
+msgstr "E293: blok nebol zamknutý"
+
+msgid "E294: Seek error in swap file read"
+msgstr "E294: Chyba posunu pri èítaní odkladacieho súboru"
+
+msgid "E295: Read error in swap file"
+msgstr "E295: Chyba pri èítaní odkladacieho súboru"
+
+msgid "E296: Seek error in swap file write"
+msgstr "E296: Chyba posunu pri ukladaní do odkladacieho súboru"
+
+msgid "E297: Write error in swap file"
+msgstr "E297: Chyba pri ukladaní do odkladacieho súboru"
+
+msgid "E300: Swap file already exists (symlink attack?)"
+msgstr "E300: Odkladací súbor u¾ existuje (symlink útok?)"
+
+msgid "E298: Didn't get block nr 0?"
+msgstr "E298: Nedá sa získa» blok 0?"
+
+msgid "E298: Didn't get block nr 1?"
+msgstr "E298: Nedá sa získa» blok 1?"
+
+msgid "E298: Didn't get block nr 2?"
+msgstr "E298: Nedá sa získa» blok 2?"
+
+#. could not (re)open the swap file, what can we do????
+msgid "E301: Oops, lost the swap file!!!"
+msgstr "E301: Ups, odkladací súbor bol stratený!!!"
+
+msgid "E302: Could not rename swap file"
+msgstr "E302: Nedá sa premenova» odkladací súbor"
+
+#, c-format
+msgid "E303: Unable to open swap file for \"%s\", recovery impossible"
+msgstr "E303: Nedá sa otvori» odkladací súbor pre \"%s\", oprava nemo¾ná"
+
+msgid "E304: ml_upd_block0(): Didn't get block 0??"
+msgstr "E304: ml_upd_block0(): nedá sa získa» blok 0??"
+
+#, c-format
+msgid "E305: No swap file found for %s"
+msgstr "E305: Odkladací súbor pre %s nebol nájdený"
+
+msgid "Enter number of swap file to use (0 to quit): "
+msgstr ""
+"Zadajte èíslo odkladacieho súboru, ktorý sa má pou¾it (0 pre ukonèenie): "
+
+#, c-format
+msgid "E306: Cannot open %s"
+msgstr "E306: Nedá sa otvori» %s"
+
+msgid "Unable to read block 0 from "
+msgstr "Nedá sa èíta» blok 0 z "
+
+msgid ""
+"\n"
+"Maybe no changes were made or Vim did not update the swap file."
+msgstr ""
+"\n"
+"Mo¾no nedo¹lo k ¾iadnym zmenám, alebo Vim neaktualizoval odkladací súbor."
+
+msgid " cannot be used with this version of Vim.\n"
+msgstr " nedá sa pou¾i» s touto verziou Vim.\n"
+
+msgid "Use Vim version 3.0.\n"
+msgstr "Pou¾ite Vim verziu 3.0.\n"
+
+#, c-format
+msgid "E307: %s does not look like a Vim swap file"
+msgstr "E307: %s sa nezdá by» odkladacím súborom Vim"
+
+msgid " cannot be used on this computer.\n"
+msgstr " nedá sa pou¾í» na tomto poèítaèi.\n"
+
+msgid "The file was created on "
+msgstr "Súbor bol vytvorený "
+
+msgid ""
+",\n"
+"or the file has been damaged."
+msgstr ""
+",\n"
+"alebo bol súbor po¹kodený."
+
+#, c-format
+msgid "Using swap file \"%s\""
+msgstr "Pou¾ívam odkladací súbor \"%s\""
+
+#, c-format
+msgid "Original file \"%s\""
+msgstr "Pôvodný súbor \"%s\""
+
+msgid "E308: Warning: Original file may have been changed"
+msgstr "E308: Varovanie: Pôvodný súbor mohol by» zmenený"
+
+#, c-format
+msgid "E309: Unable to read block 1 from %s"
+msgstr "E309: Nedá sa èíta» blok 1 z %s"
+
+msgid "???MANY LINES MISSING"
+msgstr "???CHÝBA MNOHO RIADKOV"
+
+msgid "???LINE COUNT WRONG"
+msgstr "???CHYBNÝ POÈET RIADKOV"
+
+msgid "???EMPTY BLOCK"
+msgstr "???PRÁZDNY BLOK"
+
+msgid "???LINES MISSING"
+msgstr "???CHÝBAJÚCE RIADKY"
+
+#, c-format
+msgid "E310: Block 1 ID wrong (%s not a .swp file?)"
+msgstr "E310: ID bloku 1 je chybné (je %s odkladacím súborom?)"
+
+msgid "???BLOCK MISSING"
+msgstr "???CHÝBA BLOK"
+
+msgid "??? from here until ???END lines may be messed up"
+msgstr "od ??? po ???END mô¾u by» riadky pomie¹ané"
+
+msgid "??? from here until ???END lines may have been inserted/deleted"
+msgstr "od ??? po ???END mô¾u by» riadky vlo¾ené/vymazané"
+
+msgid "???END"
+msgstr "???KONIEC"
+
+msgid "E311: Recovery Interrupted"
+msgstr "E311: Obnova preru¹ená"
+
+msgid ""
+"E312: Errors detected while recovering; look for lines starting with ???"
+msgstr ""
+"E312: V priebehu obnovy do¹lo k chybám; skontrolujte riadky zaèínajúce na ???"
+
+msgid "See \":help E312\" for more information."
+msgstr "Pozrite \":help E312\" pre ïal¹ie informácie"
+
+msgid "Recovery completed. You should check if everything is OK."
+msgstr "Obnova dokonèená. Skontrolujte, èi je v¹etko v poriadku."
+
+msgid ""
+"\n"
+"(You might want to write out this file under another name\n"
+msgstr ""
+"\n"
+"(Zvá¾te ulo¾enie tohoto súboru pod iným menom\n"
+
+msgid "and run diff with the original file to check for changes)\n"
+msgstr "a pomocou programu diff zistite zmeny oproti pôvodnému súboru)\n"
+
+msgid ""
+"Delete the .swp file afterwards.\n"
+"\n"
+msgstr "Potom vyma¾te odkladací súbor s príponou .swp.\n"
+
+#. use msg() to start the scrolling properly
+msgid "Swap files found:"
+msgstr "Nájdené odkladacie súbory:"
+
+msgid " In current directory:\n"
+msgstr " V aktuálnom adresári:\n"
+
+msgid " Using specified name:\n"
+msgstr " So zadaným menom:\n"
+
+msgid " In directory "
+msgstr " V adresári "
+
+msgid " -- none --\n"
+msgstr " -- ¾iadne --\n"
+
+msgid " owned by: "
+msgstr " vlastník: "
+
+msgid " dated: "
+msgstr " dátum vytvorenia: "
+
+msgid " dated: "
+msgstr " dátum vytvorenia: "
+
+msgid " [from Vim version 3.0]"
+msgstr " [od Vim verzie 3.0]"
+
+msgid " [does not look like a Vim swap file]"
+msgstr " [nevyzerá ako odkladací súbor Vim]"
+
+msgid " file name: "
+msgstr " názov súboru: "
+
+msgid ""
+"\n"
+" modified: "
+msgstr ""
+"\n"
+" zmenený: "
+
+msgid "YES"
+msgstr "ÁNO"
+
+msgid "no"
+msgstr "nie"
+
+msgid ""
+"\n"
+" user name: "
+msgstr ""
+"\n"
+" u¾ívateµské meno: "
+
+msgid " host name: "
+msgstr " názov poèítaèa: "
+
+msgid ""
+"\n"
+" host name: "
+msgstr ""
+"\n"
+" názov poèítaèa: "
+
+msgid ""
+"\n"
+" process ID: "
+msgstr ""
+"\n"
+" ID procesu : "
+
+msgid " (still running)"
+msgstr " (stále be¾í)"
+
+msgid ""
+"\n"
+" [not usable with this version of Vim]"
+msgstr ""
+"\n"
+" [nepou¾iteµné s touto verziou Vim]"
+
+msgid ""
+"\n"
+" [not usable on this computer]"
+msgstr ""
+"\n"
+" [nepou¾itelné na tomto poèítaèi]"
+
+msgid " [cannot be read]"
+msgstr " [nedá sa preèíta»]"
+
+msgid " [cannot be opened]"
+msgstr " [nedá sa otvori»]"
+
+msgid "E313: Cannot preserve, there is no swap file"
+msgstr "E313: Nedá sa zachova» - odkladací súbor neexistuje"
+
+msgid "File preserved"
+msgstr "Súbor zachovaný"
+
+msgid "E314: Preserve failed"
+msgstr "E314: Uchovanie sa nepodarilo"
+
+#, c-format
+msgid "E315: ml_get: invalid lnum: %ld"
+msgstr "E315: ml_get: chybné èíslo riadku: %ld"
+
+#, c-format
+msgid "E316: ml_get: cannot find line %ld"
+msgstr "E316: ml_get: nedá sa nájs» riadok %ld"
+
+msgid "E317: pointer block id wrong 3"
+msgstr "E317: chybné èíslo ukazovateµa na blok 3"
+
+msgid "stack_idx should be 0"
+msgstr "stack_idx by mal ma» hodnotu 3"
+
+msgid "E318: Updated too many blocks?"
+msgstr "E318: Aktualizovaných príli¹ veµa blokov?"
+
+msgid "E317: pointer block id wrong 4"
+msgstr "E317: chybné èíslo ukazovateµa na blok 4"
+
+msgid "deleted block 1?"
+msgstr "vymazaný blok 1?"
+
+#, c-format
+msgid "E320: Cannot find line %ld"
+msgstr "E320: Nedá sa nájs» riadok %ld"
+
+msgid "E317: pointer block id wrong"
+msgstr "E317: chybné èíslo ukazovateµa na blok"
+
+msgid "pe_line_count is zero"
+msgstr "pe_line_count má nulovú hodnotu"
+
+#, c-format
+msgid "E322: line number out of range: %ld past the end"
+msgstr "E322: èíslo riadku je mimo rozsah: %ld (za koncom)"
+
+#, c-format
+msgid "E323: line count wrong in block %ld"
+msgstr "E323: chybný poèet riadkov v bloku %ld"
+
+msgid "Stack size increases"
+msgstr "Nárast veµkosti zásobníku"
+
+msgid "E317: pointer block id wrong 2"
+msgstr "E317: chybný èíslo ukazovateµa na blok 2"
+
+msgid "E325: ATTENTION"
+msgstr "E325: POZOR"
+
+msgid ""
+"\n"
+"Found a swap file by the name \""
+msgstr ""
+"\n"
+"Nájdený odkladací súbor s menom \""
+
+msgid "While opening file \""
+msgstr "Pri otváraní súboru \""
+
+msgid " NEWER than swap file!\n"
+msgstr " NOV©Í ako odkladací súbor!\n"
+
+#. Some of these messages are long to allow translation to
+#. * other languages.
+msgid ""
+"\n"
+"(1) Another program may be editing the same file.\n"
+" If this is the case, be careful not to end up with two\n"
+" different instances of the same file when making changes.\n"
+msgstr ""
+"\n"
+"(1) Súbor mô¾e by» upravovaný iným programom.\n"
+" Ak je tomu tak, potom si dajte pozor, aby ste po ulo¾ení zmien\n"
+" nemali dve rôzne verzie toho istého súboru.\n"
+
+msgid " Quit, or continue with caution.\n"
+msgstr " Ukonèite program, alebo opatrne pokraèujte v úpravách.\n"
+
+msgid ""
+"\n"
+"(2) An edit session for this file crashed.\n"
+msgstr ""
+"\n"
+"(2) Úprava tohoto súboru bola preru¹ená neoèakávaným ukonèením programu.\n"
+
+msgid " If this is the case, use \":recover\" or \"vim -r "
+msgstr " Ak je tomu tak, potom pou¾ite \":recover\" alebo \"vim -r "
+
+msgid ""
+"\"\n"
+" to recover the changes (see \":help recovery\").\n"
+msgstr ""
+"\"\n"
+" pre obnovenie zmien (viï \":help recovery)\".\n"
+
+msgid " If you did this already, delete the swap file \""
+msgstr " Pokiaµ ste tak u¾ urobili, tak vyma¾te odkladací súbor \""
+
+msgid ""
+"\"\n"
+" to avoid this message.\n"
+msgstr ""
+"\"\n"
+" a táto správa sa u¾ nebude objavova».\n"
+
+msgid "Swap file \""
+msgstr "Odkladací súbor \""
+
+msgid "\" already exists!"
+msgstr "\" u¾ existuje!"
+
+msgid "VIM - ATTENTION"
+msgstr "VIM - POZOR"
+
+msgid "Swap file already exists!"
+msgstr "Odkladací súbor u¾ existuje!"
+
+msgid ""
+"&Open Read-Only\n"
+"&Edit anyway\n"
+"&Recover\n"
+"&Quit\n"
+"&Abort"
+msgstr ""
+"&Otvori» iba pre èítanie\n"
+"&Pokraèova» v úpravách\n"
+"O&bnovi» súbor\n"
+"&Koniec\n"
+"&Zru¹i»"
+
+msgid ""
+"&Open Read-Only\n"
+"&Edit anyway\n"
+"&Recover\n"
+"&Quit\n"
+"&Abort\n"
+"&Delete it"
+msgstr ""
+"&Otvori» iba pre èítanie\n"
+"&Pokraèovat v úpravách\n"
+"O&bnovi» súbor\n"
+"&Koniec\n"
+"&Zru¹i»\n"
+"Z&maza»"
+
+msgid "E326: Too many swap files found"
+msgstr "E326: Príli¹ mnoho odkladacích súborov"
+
+msgid "E327: Part of menu-item path is not sub-menu"
+msgstr "E327: Èas» cesty k predmetu ponuky nie je podponukou"
+
+msgid "E328: Menu only exists in another mode"
+msgstr "E328: Ponuka existuje iba v inom móde"
+
+msgid "E329: No menu \"%s\""
+msgstr "E329: Ponuka \"%s\" neexistuje"
+
+msgid "E330: Menu path must not lead to a sub-menu"
+msgstr "E330: Cesta ponuky nesmie vies» do podponuky"
+
+msgid "E331: Must not add menu items directly to menu bar"
+msgstr "E331: Polo¾ky ponuky sa nejdú pridáva» priamo na li¹tu"
+
+msgid "E332: Separator cannot be part of a menu path"
+msgstr "E332: Oddeµovaè nesmie by» èas»ou cesty ponuky"
+
+#. Now we have found the matching menu, and we list the mappings
+#. Highlight title
+msgid ""
+"\n"
+"--- Menus ---"
+msgstr ""
+"\n"
+"--- Ponuky ---"
+
+msgid "Tear off this menu"
+msgstr "Odtrhnú» tuto ponuku"
+
+msgid "E333: Menu path must lead to a menu item"
+msgstr "E333: Cesta ponuky musí vies» k polo¾ke ponuky"
+
+#, c-format
+msgid "E334: Menu not found: %s"
+msgstr "E334: Ponuka nenájdená: %s"
+
+#, c-format
+msgid "E335: Menu not defined for %s mode"
+msgstr "E335: V %s móde nie je ponuka definovaná"
+
+msgid "E336: Menu path must lead to a sub-menu"
+msgstr "E336: Cesta ponuky musí vies» do podponuky"
+
+msgid "E337: Menu not found - check menu names"
+msgstr "E337: Ponuka nenájdená - skontrolujte názvy ponúk"
+
+#, c-format
+msgid "Error detected while processing %s:"
+msgstr "Chyba pri spracovaní %s:"
+
+#, c-format
+msgid "line %4ld:"
+msgstr "riadok %4ld:"
+
+#, c-format
+msgid "E354: Invalid register name: '%s'"
+msgstr "E354: '%s' nie je prístupné meno registru"
+
+msgid "Messages maintainer: Bram Moolenaar <Bram@vim.org>"
+msgstr "Správca prekladu: Lubomir Host <rajo@platon.sk>"
+
+msgid "Interrupt: "
+msgstr "Preru¹enie: "
+
+msgid "Press ENTER or type command to continue"
+msgstr "Stlaète ENTER alebo zadajte príkaz pre pokraèovanie"
+
+msgid "-- More --"
+msgstr "-- Pokraèovanie --"
+
+msgid " SPACE/d/j: screen/page/line down, b/u/k: up, q: quit "
+msgstr " MEDZERA/d/j: obrazovka/stránka/riadok dole, b/u/k: hore, q: koniec "
+
+msgid "Question"
+msgstr "Otázka"
+
+# TODO: Translate as "&Ano\n&Nie" ?
+msgid ""
+"&Yes\n"
+"&No"
+msgstr ""
+"&Ano\n"
+"&Nie"
+
+# TODO: Translate as "&Ano\n&Nie\n&Ulo¾i» v¹etko\nZahodi» &v¹etko\n&Zru¹i»" ?
+msgid ""
+"&Yes\n"
+"&No\n"
+"Save &All\n"
+"&Discard All\n"
+"&Cancel"
+msgstr ""
+"&Ano\n"
+"&Nie\n"
+"&Ulo¾i» v¹etko\n"
+"Zahodi» &v¹etko\n"
+"&Zru¹i»"
+
+msgid "Select Directory dialog"
+msgstr "Dialóg pre vytvorenie adresára"
+
+msgid "Save File dialog"
+msgstr "Dialóg pre ukladanie súborov"
+
+msgid "Open File dialog"
+msgstr "Dialóg pre otváranie súborov"
+
+msgid "E338: Sorry, no file browser in console mode"
+msgstr "E338: ¥utujem, ale konzolová verzia nepodporuje prehliadaè súborov"
+
+msgid "E766: Insufficient arguments for printf()"
+msgstr "E766: Chybné argumenty pre funkciu printf()"
+
+msgid "E767: Too many arguments to printf()"
+msgstr "E767: Príli¹ mnoho argumentov pre funkciu printf()"
+
+msgid "W10: Warning: Changing a readonly file"
+msgstr "W10: Varovanie: mením súbor iba pre èítanie"
+
+msgid "Type number or click with mouse (<Enter> cancels): "
+msgstr "Zadajte èíslo ale kliknite my¹ou (<Enter> zru¹í): "
+
+msgid "Choice number (<Enter> cancels): "
+msgstr "Zvoµte èíslo (<Enter> zru¹í): "
+
+msgid "1 more line"
+msgstr "1 nový riadok"
+
+msgid "1 line less"
+msgstr "1 vymazaný riadok"
+
+#, c-format
+msgid "%ld more lines"
+msgstr "%ld nových riadkov"
+
+#, c-format
+msgid "%ld fewer lines"
+msgstr "%ld vymazaných riadkov"
+
+msgid " (Interrupted)"
+msgstr " (Preru¹ené)"
+
+msgid "Beep!"
+msgstr "Piip!"
+
+msgid "Vim: preserving files...\n"
+msgstr "Vim: zachovávam súbory...\n"
+
+#. close all memfiles, without deleting
+msgid "Vim: Finished.\n"
+msgstr "Vim: ukonèený\n"
+
+#, c-format
+msgid "ERROR: "
+msgstr "CHYBA: "
+
+#, c-format
+msgid ""
+"\n"
+"[bytes] total alloc-freed %lu-%lu, in use %lu, peak use %lu\n"
+msgstr ""
+"\n"
+"[bajtov] celkom uvolnené-alokované %lu-%lu, vyu¾ité %lu, maximálne vyu¾itie %lu\n"
+
+#, c-format
+msgid ""
+"[calls] total re/malloc()'s %lu, total free()'s %lu\n"
+"\n"
+msgstr ""
+"[volanie] celkom re/malloc(): %lu, celkom free() %lu\n"
+"\n"
+
+msgid "E340: Line is becoming too long"
+msgstr "E340: Riadok sa stáva príli¹ dlhým"
+
+#, c-format
+msgid "E341: Internal error: lalloc(%ld, )"
+msgstr "E341: Vnútorná chyba: lalloc(%ld, )"
+
+#, c-format
+msgid "E342: Out of memory! (allocating %lu bytes)"
+msgstr "E342: Nedostatok pamäte! (alokujem %lu bajtov)"
+
+#, c-format
+msgid "Calling shell to execute: \"%s\""
+msgstr "Volám shell na spustenie: \"%s\""
+
+msgid "E545: Missing colon"
+msgstr "E545: Chýba dvojbodka"
+
+msgid "E546: Illegal mode"
+msgstr "E546: Neprípustný mód"
+
+msgid "E547: Illegal mouseshape"
+msgstr "E547: Chybný tvar my¹i"
+
+msgid "E548: digit expected"
+msgstr "E548: oèakávaná èíslica"
+
+msgid "E549: Illegal percentage"
+msgstr "E549: Neprípustné percento"
+
+msgid "Enter encryption key: "
+msgstr "Zadajte ¹ifrovací kµúè: "
+
+msgid "Enter same key again: "
+msgstr "Vlo¾te ten istý kµúè znova: "
+
+msgid "Keys don't match!"
+msgstr "Kµúèe sa nezhodujú!"
+
+#, c-format
+msgid ""
+"E343: Invalid path: '**[number]' must be at the end of the path or be "
+"followed by '%s'."
+msgstr ""
+"E343: Chybná cesta: '**[èíslo] musí by» buï na konci cesty, alebo musí by»\n"
+"nasledované '%s. Viï :help path."
+
+#, c-format
+msgid "E344: Can't find directory \"%s\" in cdpath"
+msgstr "E344: Adresár \"%s\" sa nedá nájs» v cdpath"
+
+#, c-format
+msgid "E345: Can't find file \"%s\" in path"
+msgstr "E345: Súbor \"%s\" sa nepodarilo nájs»"
+
+#, c-format
+msgid "E346: No more directory \"%s\" found in cdpath"
+msgstr "E346: ®iadny ïal¹í adresár \"%s\" nebol v cdpath nájdený"
+
+#, c-format
+msgid "E347: No more file \"%s\" found in path"
+msgstr "E347: ®iadny ïal¹í súbor \"%s\" nebol v ceste nájdený"
+
+#. Get here when the server can't be found.
+msgid "Cannot connect to Netbeans #2"
+msgstr "Nedá sa pripoji» na Netbeans #2"
+
+msgid "Cannot connect to Netbeans"
+msgstr "Nedá sa pripoji» na Netbeans"
+
+#, c-format
+msgid "E668: Wrong access mode for NetBeans connection info file: \"%s\""
+msgstr "E668: Zlé prístupové práva pre súbor s informáciami pre NetBeans spojenie: \"%s\""
+
+msgid "read from Netbeans socket"
+msgstr "èítanie z Netbeans soketu"
+
+msgid "E658: NetBeans connection lost for buffer %ld"
+msgstr "E658: Stratené NetBeans spojenie pre buffer %ld"
+
+msgid "E505: "
+msgstr "E505: "
+
+msgid "Warning: terminal cannot highlight"
+msgstr "Varovanie: terminál nepodporuje zvýrazòovanie"
+
+msgid "E348: No string under cursor"
+msgstr "E348: Pod kurzorom nie je ¾iadny re»azec"
+
+msgid "E349: No identifier under cursor"
+msgstr "E349: Pod kurzorom nie je ¾iadny identifikátor"
+
+msgid "E352: Cannot erase folds with current 'foldmethod'"
+msgstr "E352: Pomocou 'foldmethod' sa nedá vymaza» vnorenie"
+
+msgid "E664: changelist is empty"
+msgstr "E664: zoznam zmien je prázdny"
+
+msgid "E662: At start of changelist"
+msgstr "E662: Na zaèiatku zoznamu zmien"
+
+msgid "E663: At end of changelist"
+msgstr "E663: Na konci zoznamu zmien"
+
+msgid "Type :quit<Enter> to exit Vim"
+msgstr "Zadajte :quit<Enter> pre ukonèenie programu Vim"
+
+#, c-format
+msgid "1 line %sed 1 time"
+msgstr "poèet riadkov upravených naraz pomocou %s: 1"
+
+#, c-format
+msgid "1 line %sed %d times"
+msgstr "1 riadok upravený pomocou %s %d krát"
+
+#, c-format
+msgid "%ld lines %sed 1 time"
+msgstr "%ld riadkov upravených naraz pomocou %s"
+
+#, c-format
+msgid "%ld lines %sed %d times"
+msgstr "%ld riadkov upravených pomocou %s %d krát"
+
+#, c-format
+msgid "%ld lines to indent... "
+msgstr "%ld riadkov pre odsadenie..."
+
+msgid "1 line indented "
+msgstr "1 riadok odsadený "
+
+#, c-format
+msgid "%ld lines indented "
+msgstr "%ld riadkov odsadených "
+
+msgid "E748: No previously used register"
+msgstr "E748: ®iadny predtým pou¾ívaný register"
+
+#. must display the prompt
+msgid "cannot yank; delete anyway"
+msgstr "nedá sa kopírova»; napriek tomu vymazané"
+
+msgid "1 line changed"
+msgstr "1 riadok zmenený"
+
+#, c-format
+msgid "%ld lines changed"
+msgstr "%ld zmenených riadkov"
+
+#, c-format
+msgid "freeing %ld lines"
+msgstr "uvolòujem %ld riadkov"
+
+msgid "block of 1 line yanked"
+msgstr "skopírovaný blok 1 riadku"
+
+msgid "1 line yanked"
+msgstr "1 riadok skopírovaný"
+
+msgid "block of %ld lines yanked"
+msgstr "skopírovaný blok %ld riadkov"
+
+#, c-format
+msgid "%ld lines yanked"
+msgstr "%ld skopírovaných riadkov"
+
+#, c-format
+msgid "E353: Nothing in register %s"
+msgstr "E353: Register %s je prázdny"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Registers ---"
+msgstr ""
+"\n"
+"--- Registre ---"
+
+msgid "Illegal register name"
+msgstr "Neprípustný názov registra"
+
+#, c-format
+msgid ""
+"\n"
+"# Registers:\n"
+msgstr ""
+"\n"
+"# Registre:\n"
+
+msgid "E574: Unknown register type %d"
+msgstr "E574: Neznámy typ registra %d"
+
+#, c-format
+msgid "%ld Cols; "
+msgstr "%ld Ståpcov; "
+
+#, c-format
+msgid "Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Bytes"
+msgstr "Vybraných %s%ld z %ld Riadkov; %ld zo %ld Slov; %ld z %ld Bajtov"
+
+msgid ""
+"Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Chars; %ld of %ld "
+"Bytes"
+msgstr "Vybraných %s%ld z %ld Riadkov; %ld zo %ld Slov; %ld z %ld Znakov; %ld z %ld Bajtov"
+
+#, c-format
+msgid "Col %s of %s; Line %ld of %ld; Word %ld of %ld; Byte %ld of %ld"
+msgstr "Ståpec %s z %s; Riadok %ld z %ld; Slovo %ld z %ld; Bajt %ld z %ld"
+
+#, c-format
+msgid ""
+"Col %s of %s; Line %ld of %ld; Word %ld of %ld; Char %ld of %ld; Byte %ld of "
+"%ld"
+msgstr "Ståpec %s z %s; Riadok %ld z %ld; Slovo %ld z %ld; Znak %ld z %ld; Bajt %ld z %ld"
+
+#, c-format
+msgid "(+%ld for BOM)"
+msgstr "(+%ld pre BOM)"
+
+msgid "%<%f%h%m%=Page %N"
+msgstr "%<%f%h%m%=Strana %N"
+
+msgid "Thanks for flying Vim"
+msgstr "Ïakujeme za pou¾itie Vim"
+
+msgid "E518: Unknown option"
+msgstr "E518: Neznáma voµba"
+
+msgid "E519: Option not supported"
+msgstr "E519: Voµba nie je podporovaná"
+
+msgid "E520: Not allowed in a modeline"
+msgstr "E520: Nie je v modeline povolené"
+
+msgid "E521: Number required after ="
+msgstr "E521: Po = je vy¾adované èíslo"
+
+msgid "E522: Not found in termcap"
+msgstr "E522: Nenájdený v termcape"
+
+#, c-format
+msgid "E539: Illegal character <%s>"
+msgstr "E539: Neprípustný znak <%s>"
+
+msgid "E529: Cannot set 'term' to empty string"
+msgstr "E529: Voµba 'term' nemô¾e by» prázdna"
+
+msgid "E530: Cannot change term in GUI"
+msgstr "E530: V grafickom móde (GUI) sa nedá meni» typ terminálu"
+
+msgid "E531: Use \":gui\" to start the GUI"
+msgstr "E531: Pou¾ite \"gui\" pre spustenie GUI"
+
+msgid "E589: 'backupext' and 'patchmode' are equal"
+msgstr "E589: voµby 'backupext' a 'patchmode' majú rovnakú hodnotu"
+
+msgid "E617: Cannot be changed in the GTK+ 2 GUI"
+msgstr "E617: Nedá sa zmeni» v grafickom rozhraní GTK+ 2"
+
+msgid "E524: Missing colon"
+msgstr "E524: Chýba dvojbodka"
+
+msgid "E525: Zero length string"
+msgstr "E525: Re»azec s nulovou då¾kou"
+
+#, c-format
+msgid "E526: Missing number after <%s>"
+msgstr "E526: Po <%s> chýba èíslo"
+
+msgid "E527: Missing comma"
+msgstr "E527: Chýba èiarka"
+
+msgid "E528: Must specify a ' value"
+msgstr "E528: Je nutné zada» hodnotu '"
+
+msgid "E595: contains unprintable or wide character"
+msgstr "E595: obsahuje netlaèiteµné znaky"
+
+msgid "E596: Invalid font(s)"
+msgstr "E596: Chybné písma"
+
+msgid "E597: can't select fontset"
+msgstr "E597: nedá sa vybra» sada písiem"
+
+msgid "E598: Invalid fontset"
+msgstr "E598: Chybná sada písiem"
+
+msgid "E533: can't select wide font"
+msgstr "E533: nedá sa vybra» ¹iroký font"
+
+msgid "E534: Invalid wide font"
+msgstr "E534: Chybné ¹iroké písmo"
+
+#, c-format
+msgid "E535: Illegal character after <%c>"
+msgstr "E535: Neprípustný znak po <%c>"
+
+msgid "E536: comma required"
+msgstr "E536: je nutná èiarka"
+
+#, c-format
+msgid "E537: 'commentstring' must be empty or contain %s"
+msgstr "E537: 'commentstring' (komentár) musí by» prázdny alebo musí obsahova» %s"
+
+msgid "E538: No mouse support"
+msgstr "E538: Bez podpory my¹i"
+
+msgid "E540: Unclosed expression sequence"
+msgstr "E540: Neuzatvorené zoskupenie výrazov"
+
+msgid "E541: too many items"
+msgstr "E541: príli¹ mnoho polo¾iek"
+
+msgid "E542: unbalanced groups"
+msgstr "E542: nevyvá¾ené skupiny"
+
+msgid "E590: A preview window already exists"
+msgstr "E590: Okno náhµadu u¾ existuje"
+
+msgid "W17: Arabic requires UTF-8, do ':set encoding=utf-8'"
+msgstr "W17: Mód Arabic vy¾aduje kódovanie UTF-8, nastavte to príkazom ':set encoding=utf-8'"
+
+#, c-format
+msgid "E593: Need at least %d lines"
+msgstr "E593: Minimálny potrebný poèet riadkov je %d"
+
+#, c-format
+msgid "E594: Need at least %d columns"
+msgstr "E594: Minimálne potrebný poèet ståpcov je %d"
+
+#, c-format
+msgid "E355: Unknown option: %s"
+msgstr "E355: Neznáma voµba: %s"
+
+msgid ""
+"\n"
+"--- Terminal codes ---"
+msgstr ""
+"\n"
+"--- Kódy terminálu ---"
+
+msgid ""
+"\n"
+"--- Global option values ---"
+msgstr ""
+"\n"
+"--- Nastavenie globálnych volieb ---"
+
+msgid ""
+"\n"
+"--- Local option values ---"
+msgstr ""
+"\n"
+"--- Nastavenie lokálnych volieb ---"
+
+msgid ""
+"\n"
+"--- Options ---"
+msgstr ""
+"\n"
+"--- Mo¾nosti ---"
+
+msgid "E356: get_varp ERROR"
+msgstr "E356: get_varp CHYBA"
+
+#, c-format
+msgid "E357: 'langmap': Matching character missing for %s"
+msgstr "E357: 'langmap': pre %s chýba vyhovujúci znak"
+
+#, c-format
+msgid "E358: 'langmap': Extra characters after semicolon: %s"
+msgstr "E358: 'langmap': nadbytoèné znaky po bodkoèiarke: %s"
+
+msgid "cannot open "
+msgstr "nedá sa otvori» "
+
+msgid "VIM: Can't open window!\n"
+msgstr "VIM: Nedá sa otvori» okno!\n"
+
+msgid "Need Amigados version 2.04 or later\n"
+msgstr "Je potrebná Amigados verzia 2.04 alebo nov¹ia\n"
+
+#, c-format
+msgid "Need %s version %ld\n"
+msgstr "Potrebná %s verzia %ld\n"
+
+msgid "Cannot open NIL:\n"
+msgstr "Nedá sa otvori» NIL:\n"
+
+msgid "Cannot create "
+msgstr "Nedá sa vytvori» "
+
+#, c-format
+msgid "Vim exiting with %d\n"
+msgstr "Vim ukonèený s %d\n"
+
+msgid "cannot change console mode ?!\n"
+msgstr "nemô¾em zmeni» konzolový mód ?!\n"
+
+msgid "mch_get_shellsize: not a console??\n"
+msgstr "mch_get_shellsize: nie je konzolou??\n"
+
+#. if Vim opened a window: Executing a shell may cause crashes
+msgid "E360: Cannot execute shell with -f option"
+msgstr "E360: Nedá sa spusti» shell s -f voµbou"
+
+msgid "Cannot execute "
+msgstr "Nedá sa spusti» "
+
+msgid "shell "
+msgstr "shell "
+
+msgid " returned\n"
+msgstr " vrátené\n"
+
+msgid "ANCHOR_BUF_SIZE too small."
+msgstr "ANCHOR_BUF_SIZE príli¹ malá."
+
+msgid "I/O ERROR"
+msgstr "I/O CHYBA"
+
+msgid "...(truncated)"
+msgstr "...(skrátené)"
+
+msgid "'columns' is not 80, cannot execute external commands"
+msgstr "'ståpce' nie je 80, nemô¾em spusti» externý príkaz"
+
+msgid "E237: Printer selection failed"
+msgstr "E237: Zlyhal výber tlaèiarne"
+
+#, c-format
+msgid "to %s on %s"
+msgstr "%s na %s"
+
+#, c-format
+msgid "E613: Unknown printer font: %s"
+msgstr "E613: Neznámy font tlaèiarne: %s"
+
+#, c-format
+msgid "E238: Print error: %s"
+msgstr "E238: Chyba tlaèe: %s"
+
+#, c-format
+msgid "Printing '%s'"
+msgstr "Tlaèím '%s'"
+
+#, c-format
+msgid "E244: Illegal charset name \"%s\" in font name \"%s\""
+msgstr "E244: Chybný názov znakovej sady \"%s\" v názve písma \"%s\""
+
+#, c-format
+msgid "E245: Illegal char '%c' in font name \"%s\""
+msgstr "E245: Chybný znak '%c' v názve písma \"%s\""
+
+msgid "Vim: Double signal, exiting\n"
+msgstr "Vim: dvojitý signál, konèím\n"
+
+#, c-format
+msgid "Vim: Caught deadly signal %s\n"
+msgstr "Vim: Zachytený smrtiaci signál %s\n"
+
+#, c-format
+msgid "Vim: Caught deadly signal\n"
+msgstr "Vim: Zachytený smrtiaci signál\n"
+
+#, c-format
+msgid "Opening the X display took %ld msec"
+msgstr "Otvorenie X displej zabralo %ld msec"
+
+#. KDE sometimes produces X error that we want to ignore
+msgid ""
+"\n"
+"Vim: Got X error but we continue...\n"
+msgstr ""
+"\n"
+"Vim: Chyba X ale pokraèujem ...\n"
+
+msgid ""
+"\n"
+"Vim: Got X error\n"
+msgstr ""
+"\n"
+"Vim: Chyba X\n"
+
+msgid "Testing the X display failed"
+msgstr "Testovanie X displeja zlyhalo"
+
+msgid "Opening the X display timed out"
+msgstr "Uplynul èas otvorenia X displeja"
+
+msgid ""
+"\n"
+"Cannot execute shell "
+msgstr ""
+"\n"
+"Nedá sa spusti» shell "
+
+msgid ""
+"\n"
+"Cannot execute shell sh\n"
+msgstr ""
+"\n"
+"Nedá sa spusti» sh shell\n"
+
+msgid ""
+"\n"
+"shell returned "
+msgstr ""
+"\n"
+" návratová hodnota shellu "
+
+msgid ""
+"\n"
+"Cannot create pipes\n"
+msgstr ""
+"\n"
+"Nedjú sa vytvori» rúry\n"
+
+msgid ""
+"\n"
+"Cannot fork\n"
+msgstr ""
+"\n"
+"Vyvolanie fork zlyhalo\n"
+
+msgid ""
+"\n"
+"Command terminated\n"
+msgstr ""
+"\n"
+"Príkaz ukonèený\n"
+
+msgid "XSMP lost ICE connection"
+msgstr "XSMP stratilo ICE spojenie"
+
+#, c-format
+msgid "dlerror = \"%s\""
+msgstr "dlerror = \"%s\""
+
+msgid "Opening the X display failed"
+msgstr "Otvorenie X displeja zlyhalo"
+
+msgid "XSMP handling save-yourself request"
+msgstr "XSMP spracuváva po¾iadavku na samoulo¾enie"
+
+msgid "XSMP opening connection"
+msgstr "XSMP otvára spojenie"
+
+msgid "XSMP ICE connection watch failed"
+msgstr "XSMP kontrola spojenia ICE zlyhala"
+
+#, c-format
+msgid "XSMP SmcOpenConnection failed: %s"
+msgstr "XSMP SmcOpenConnection zlyhalo: %s"
+
+msgid "At line"
+msgstr "Na riadku"
+
+msgid "Could not load vim32.dll!"
+msgstr "Nemô¾em nahra» vim32.dll!"
+
+msgid "VIM Error"
+msgstr "VIM Chyba"
+
+msgid "Could not fix up function pointers to the DLL!"
+msgstr "Nemô¾em opravi» odkazy funkcií na DLL!"
+
+#, c-format
+msgid "shell returned %d"
+msgstr "návratová hodnota shellu %d"
+
+#, c-format
+msgid "Vim: Caught %s event\n"
+msgstr "Vim: Zachytená udalos» %s\n"
+
+msgid "close"
+msgstr "zavrie»"
+
+msgid "logoff"
+msgstr "odhlási»"
+
+msgid "shutdown"
+msgstr "vypnú»"
+
+msgid "E371: Command not found"
+msgstr "E371: Príkaz nenájdený"
+
+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 nenájdený v $PATH.\n"
+"Po dokonèení externých príkazov nebude výstup pozastavený.\n"
+"Pozrite :help win32-vimrun pre viac informácií."
+
+msgid "Vim Warning"
+msgstr "Vim Varovanie"
+
+#, c-format
+msgid "E372: Too many %%%c in format string"
+msgstr "E372: Príli¹ mnoho %%%c vo formátovacom re»azci"
+
+#, c-format
+msgid "E373: Unexpected %%%c in format string"
+msgstr "E373: Neoèakávaný výskyt %%%c vo formátovacom re»azci"
+
+msgid "E374: Missing ] in format string"
+msgstr "E374: Vo formátovacom re»azci chýba ]"
+
+#, c-format
+msgid "E375: Unsupported %%%c in format string"
+msgstr ""
+"E375: Nepodporovaná formátová ¹pecifikácia %%%c vo formátovacom re»azci"
+
+#, c-format
+msgid "E376: Invalid %%%c in format string prefix"
+msgstr "E376: Neprístupné %%%c v prefixe formátovacieho re»azca"
+
+#, c-format
+msgid "E377: Invalid %%%c in format string"
+msgstr "E377: Neprístupné %%%c vo formátovacom re»azci"
+
+msgid "E378: 'errorformat' contains no pattern"
+msgstr "E378: 'errorformat' neobsahuje ¾iadny vzor"
+
+msgid "E379: Missing or empty directory name"
+msgstr "E379: Chýbajúci alebo prázdny názov adresára"
+
+msgid "E553: No more items"
+msgstr "E553: ®iadne ïal¹ie polo¾ky"
+
+#, c-format
+msgid "(%d of %d)%s%s: "
+msgstr "(%d z %d)%s%s: "
+
+msgid " (line deleted)"
+msgstr " (riadok vymazaný)"
+
+msgid "E380: At bottom of quickfix stack"
+msgstr "E380: Koniec quickfix zoznamu"
+
+msgid "E381: At top of quickfix stack"
+msgstr "E381: Zaèiatok quickfix zoznamu"
+
+#, c-format
+msgid "error list %d of %d; %d errors"
+msgstr "zoznam chýb %d z %d; %d chýb"
+
+msgid "E382: Cannot write, 'buftype' option is set"
+msgstr "E382: Nedá sa ulo¾i», je nastavená voµba 'buftype'"
+
+msgid "E683: File name missing or invalid pattern"
+msgstr "E683: Chýba meno súboru alebo chybný vzor"
+
+msgid "Cannot open file \"%s\""
+msgstr "Nedá sa otvori» súbor \"%s\""
+
+msgid "E681: Buffer is not loaded"
+msgstr "E681: Buffer nie je naèítaný"
+
+#, c-format
+msgid "E369: invalid item in %s%%[]"
+msgstr "E369: chybná polo¾ka v %s%%[]"
+
+msgid "E339: Pattern too long"
+msgstr "E339: Vzor je príli¹ dlhý"
+
+msgid "E50: Too many \\z("
+msgstr "E50: Príli¹ mnoho \\z("
+
+#, c-format
+msgid "E51: Too many %s("
+msgstr "E51: Príli¹ mnoho %s("
+
+msgid "E52: Unmatched \\z("
+msgstr "E52: Nespárované \\z("
+
+#, c-format
+msgid "E53: Unmatched %s%%("
+msgstr "E53: Nespárované %s%%("
+
+#, c-format
+msgid "E54: Unmatched %s("
+msgstr "E54: Nespárované %s("
+
+#, c-format
+msgid "E55: Unmatched %s)"
+msgstr "E55: Nespárované %s)"
+
+#, c-format
+msgid "E59: invalid character after %s@"
+msgstr "E59: Neprípustný znak po %s@"
+
+#, c-format
+msgid "E60: Too many complex %s{...}s"
+msgstr "E60: Príli¹ komplexné %s{...}"
+
+#, c-format
+msgid "E61: Nested %s*"
+msgstr "E61: Vnorený %s*"
+
+#, c-format
+msgid "E62: Nested %s%c"
+msgstr "E62: Vnorený %s%c"
+
+msgid "E63: invalid use of \\_"
+msgstr "E63: Chybne pou¾ité \\_"
+
+#, c-format
+msgid "E64: %s%c follows nothing"
+msgstr "E64: %s%c niè nenasleduje"
+
+msgid "E65: Illegal back reference"
+msgstr "E65: Chybná spätná referencia"
+
+msgid "E66: \\z( not allowed here"
+msgstr "E66: \\z( tu nie je povolené"
+
+msgid "E67: \\z1 et al. not allowed here"
+msgstr "E67: \\z1 a spol. tu nie je povolené"
+
+msgid "E68: Invalid character after \\z"
+msgstr "E68: Neprípustný znak po \\z"
+
+#, c-format
+msgid "E69: Missing ] after %s%%["
+msgstr "E69: Chýbajúca ] po %s%%["
+
+#, c-format
+msgid "E70: Empty %s%%[]"
+msgstr "E70: Prázdny %s%%[]"
+
+#, c-format
+msgid "E678: Invalid character after %s%%[dxouU]"
+msgstr "E678: Neprípustný znak po %s%%[dxouU]"
+
+#, c-format
+msgid "E71: Invalid character after %s%%"
+msgstr "E71: Neprípustný znak po %s%%"
+
+#, c-format
+msgid "E769: Missing ] after %s["
+msgstr "E769: Chýbajúca ] po %s["
+
+#, c-format
+msgid "E554: Syntax error in %s{...}"
+msgstr "E554: Chyba syntaxe v %s{...}"
+
+msgid "External submatches:\n"
+msgstr "Vnútorné podradené zhody:\n"
+
+msgid " VREPLACE"
+msgstr " NAHRADI« VERTIKÁLNE"
+
+msgid " REPLACE"
+msgstr " NAHRADI«"
+
+msgid " REVERSE"
+msgstr " OBRÁTI«"
+
+msgid " INSERT"
+msgstr " VLO®I«"
+
+msgid " (insert)"
+msgstr " (vlo¾i»)"
+
+msgid " (replace)"
+msgstr " (nahradi»)"
+
+msgid " (vreplace)"
+msgstr " (nahradi» vertikálne)"
+
+msgid " Hebrew"
+msgstr " Hebrejský"
+
+msgid " Arabic"
+msgstr " Arabský"
+
+msgid " (lang)"
+msgstr " (jazyk)"
+
+msgid " (paste)"
+msgstr " (vlo¾i»)"
+
+msgid " VISUAL"
+msgstr " VIZUÁLNE"
+
+msgid " VISUAL LINE"
+msgstr " VIZUÁLNY RIADOK"
+
+msgid " VISUAL BLOCK"
+msgstr " VIZUÁLNY BLOK"
+
+msgid " SELECT"
+msgstr " ZHODY"
+
+msgid " SELECT LINE"
+msgstr " OZNAÈ RIADOK"
+
+msgid " SELECT BLOCK"
+msgstr " OZNAÈ BLOK"
+
+msgid "recording"
+msgstr "nahrávam"
+
+#, c-format
+msgid "E383: Invalid search string: %s"
+msgstr "E383: Neprípustný hµadaný re»azec: %s"
+
+#, c-format
+msgid "E384: search hit TOP without match for: %s"
+msgstr "E384: hµadanie dosiahlo zaèiatok bez nájdenia %s"
+
+#, c-format
+msgid "E385: search hit BOTTOM without match for: %s"
+msgstr "E385: hµadanie dosiahlo koniec bez nájdenia %s"
+
+msgid "E386: Expected '?' or '/' after ';'"
+msgstr "E386: Po ';' oèakávam '?' alebo '/'"
+
+msgid " (includes previously listed match)"
+msgstr " (vrátane u¾ vypísaných zhôd)"
+
+#. cursor at status line
+msgid "--- Included files "
+msgstr "--- Vlo¾ené súbory"
+
+msgid "not found "
+msgstr "nenájdené "
+
+msgid "in path ---\n"
+msgstr "v ceste ---\n"
+
+msgid " (Already listed)"
+msgstr " (U¾ vypísané)"
+
+msgid " NOT FOUND"
+msgstr " NENÁJDENÉ"
+
+#, c-format
+msgid "Scanning included file: %s"
+msgstr "Prehµadávam vlo¾ené súbory: %s"
+
+msgid "E387: Match is on current line"
+msgstr "E387: Zhoda je na aktuálnom riadku"
+
+msgid "All included files were found"
+msgstr "V¹etky vlo¾ené súbory boli nájdené"
+
+msgid "No included files"
+msgstr "®iadne vlo¾ené súbory"
+
+msgid "E388: Couldn't find definition"
+msgstr "E388: Nedá sa nájs» definícia"
+
+msgid "E389: Couldn't find pattern"
+msgstr "E389: Nedá sa nájs» vzor"
+
+msgid "E759: Format error in spell file"
+msgstr "E759: Chyba formátovania v spell súbore (kontrola pravopisu)"
+
+msgid "E758: Truncated spell file"
+msgstr "E758: Odseknutý spell súbor (kontrola pravopisu)"
+
+#, c-format
+msgid "Trailing text in %s line %d: %s"
+msgstr "Prebytoèný text v %s na riadku %d: %s"
+
+#, c-format
+msgid "Affix name too long in %s line %d: %s"
+msgstr "Prípona príli¶ dlhá v %s riadok %d: %s"
+
+msgid "E761: Format error in affix file FOL, LOW or UPP"
+msgstr "E761: Chyba formátovania v súbore prípon FOL, LOW alebo UPP (NASLEDUJE, MALÉ alebo VE¥KÉ)"
+
+msgid "E762: Character in FOL, LOW or UPP is out of range"
+msgstr "E762: Znak v FOL, LOW alebo UPP (NASLEDUJE, MALÉ alebo VE¥KÉ) je mimo rozsah"
+
+msgid "Compressing word tree..."
+msgstr "Robím kompresiu stromu slov..."
+
+msgid "E756: Spell checking is not enabled"
+msgstr "E756: Kontrola pravopisu nie je zapnutá"
+
+#, c-format
+msgid "Warning: Cannot find word list \"%s.%s.spl\" or \"%s.ascii.spl\""
+msgstr "Varovanie: Nemo¾no nájs» zoznam slov \"%s.%s.spl\" alebo \"%s.ascii.spl\""
+
+#, c-format
+msgid "Reading spell file \"%s\""
+msgstr "Èítam slovníkový súbor \"%s\""
+
+msgid "E757: This does not look like a spell file"
+msgstr "E757: Toto sa nezdá by» slovníkovým súborom"
+
+msgid "E771: Old spell file, needs to be updated"
+msgstr "E771: Starý slovníkový súbor, potrebuje by» zaktualizovaný"
+
+msgid "E772: Spell file is for newer version of Vim"
+msgstr "E772: Slovníkový súbor je pre nov¹iu verziu Vim"
+
+msgid "E770: Unsupported section in spell file"
+msgstr "E770: Nepodporovaná sekcia v slovníkovom súbore"
+
+#, c-format
+msgid "Warning: region %s not supported"
+msgstr "Varovanie: región %s nie je podporovaný"
+
+#, c-format
+msgid "Reading affix file %s ..."
+msgstr "Naèítavam súbor s príponami %s ..."
+
+#, c-format
+msgid "Conversion failure for word in %s line %d: %s"
+msgstr "Konverzia slova zlyhala v %s riadok %d: %s"
+
+#, c-format
+msgid "Conversion in %s not supported: from %s to %s"
+msgstr "Konverzia v %s nie je podporovaná: z %s do %s"
+
+#, c-format
+msgid "Conversion in %s not supported"
+msgstr "Konverzia v %s nie je podporovaná"
+
+#, c-format
+msgid "Invalid value for FLAG in %s line %d: %s"
+msgstr "Neplatná hodnota pre príznak (FLAG) v %s riadok %d: %s"
+
+#, c-format
+msgid "FLAG after using flags in %s line %d: %s"
+msgstr "Príznak (FLAG) po pou¾ití príznakov v %s riadok %d: %s"
+
+#, c-format
+msgid "Character used for SLASH must be ASCII; in %s line %d: %s"
+msgstr "Znak pou¾itý pre SLASH musí by» ASCII; v %s riadok %d: %s"
+
+#, c-format
+msgid "Wrong COMPOUNDMAX value in %s line %d: %s"
+msgstr "Zlá hodnota COMPOUNDMAX v %s riadok %d: %s"
+
+#, c-format
+msgid "Wrong COMPOUNDMIN value in %s line %d: %s"
+msgstr "Zlá hodnota COMPOUNDMIN v %s riadok %d: %s"
+
+#, c-format
+msgid "Wrong COMPOUNDSYLMAX value in %s line %d: %s"
+msgstr "Zlá hodnota COMPOUNDSYLMAX v %s riadok %d: %s"
+
+#, c-format
+msgid "Different combining flag in continued affix block in %s line %d: %s"
+msgstr "Rozdielna kombinácia príznakov v nasledujúcom bloku prípon v %s riadok %d: %s"
+
+#, c-format
+msgid "Duplicate affix in %s line %d: %s"
+msgstr "Duplicitná prípona v %s riadok %d: %s"
+
+#, c-format
+msgid ""
+"Affix also used for BAD/RAR/KEP/NEEDAFFIX/NEEDCOMPOUND in %s line %d: %s"
+msgstr ""
+"Prípona pou¾itá aj pre BAD/RAR/KEP/NEEDAFFIX/NEEDCOMPOUND in %s line %d: %s"
+
+#, c-format
+msgid "Expected Y or N in %s line %d: %s"
+msgstr "Oèakávane Y alebo N v %s riadok %d: %s"
+
+#, c-format
+msgid "Broken condition in %s line %d: %s"
+msgstr "Naru¹ená podmienka v %s riadok %d: %s"
+
+#, c-format
+msgid "Expected REP count in %s line %d"
+msgstr "Oèakávam poèet REP v %s riadok %d"
+
+#, c-format
+msgid "Expected MAP count in %s line %d"
+msgstr "Oèakávam poèet MAP v %s riadok %d"
+
+#, c-format
+msgid "Duplicate character in MAP in %s line %d"
+msgstr "Opakovaný znak v MAP v %s riadok %d"
+
+#, c-format
+msgid "Unrecognized or duplicate item in %s line %d: %s"
+msgstr "Nerozpoznaná alebo opakujúca sa polo¾ka v %s riadok %d: %s"
+
+#, c-format
+msgid "Missing FOL/LOW/UPP line in %s"
+msgstr "Chýbajúci riadok FOL/LOW/UPP v %s"
+
+msgid "COMPOUNDSYLMAX used without SYLLABLE"
+msgstr "COMPOUNDSYLMAX pou¾itý bez SYLLABLE"
+
+msgid "Too many postponed prefixes"
+msgstr "Príli¹ mnoho odlo¾ených prípon"
+
+msgid "Too many compound flags"
+msgstr "Príli¹ mnoho upravovacích príznakov"
+
+msgid "Too many postponed prefixes and/or compound flags"
+msgstr "Príli¹ mnoho odlo¾ených prípon a/alebo upravovacích príznakov"
+
+#, c-format
+msgid "Missing SOFO%s line in %s"
+msgstr "Chýba SOFO%s riadok v %s"
+
+#, c-format
+msgid "Both SAL and SOFO lines in %s"
+msgstr "SAL a SOFO riadky zároveò v %s"
+
+#, c-format
+msgid "Flag is not a number in %s line %d: %s"
+msgstr "Príznak nie je èíslo v %s na riadku %d: %s"
+
+#, c-format
+msgid "Illegal flag in %s line %d: %s"
+msgstr "Neprípustný príznak v %s riadok %d: %s"
+
+#, c-format
+msgid "%s value differs from what is used in another .aff file"
+msgstr "Hodnota %s sa odli¹uje od hodnoty pou¾itej v inom .aff súbore"
+
+#, c-format
+msgid "Reading dictionary file %s ..."
+msgstr "Naèítavam slovník %s ..."
+
+#, c-format
+msgid "E760: No word count in %s"
+msgstr "E760: Chýajúci poèet slov v %s"
+
+#, c-format
+msgid "line %6d, word %6d - %s"
+msgstr "riadok %6d, slovo %6d - %s"
+
+#, c-format
+msgid "Duplicate word in %s line %d: %s"
+msgstr "Opakujúce sa slovo v %s riadok %d: %s"
+
+#, c-format
+msgid "First duplicate word in %s line %d: %s"
+msgstr "Prvé duplicitné slovo v %s riadok %d: %s"
+
+#, c-format
+msgid "%d duplicate word(s) in %s"
+msgstr "%d duplicitné slovo(á) v %s"
+
+#, c-format
+msgid "Ignored %d word(s) with non-ASCII characters in %s"
+msgstr "Ignorovaných %d slov s nepísmennými znakmi v %s"
+
+#, c-format
+msgid "Reading word file %s ..."
+msgstr "Naèítavam súbor so slovami %s ..."
+
+#, c-format
+msgid "Duplicate /encoding= line ignored in %s line %d: %s"
+msgstr "Duplicitný riadok /encoding= v %s riadok %d ignorovaný: %s "
+
+#, c-format
+msgid "/encoding= line after word ignored in %s line %d: %s"
+msgstr "/encoding= riadok nasledujúci po slove v %s riadok %d ignorovaný: %s"
+
+#, c-format
+msgid "Duplicate /regions= line ignored in %s line %d: %s"
+msgstr "Duplicitný riadok /regions= v %s riadok %d ignorovaný: %s"
+
+#, c-format
+msgid "Too many regions in %s line %d: %s"
+msgstr "Príli¹ mnoho regiónov v %s riadok %d: %s"
+
+#, c-format
+msgid "/ line ignored in %s line %d: %s"
+msgstr "Riadok / v %s riadok %d ignorovaný: %s"
+
+#, c-format
+msgid "Invalid region nr in %s line %d: %s"
+msgstr "Pou¾íté chybné èíslo regiónu v %s riadok %d: %s"
+
+#, c-format
+msgid "Unrecognized flags in %s line %d: %s"
+msgstr "Nerozpoznaný príznak v %s riadok %d: %s"
+
+#, c-format
+msgid "Ignored %d words with non-ASCII characters"
+msgstr "Ignorovaných %d slov s nepísmennými znakmi"
+
+#, c-format
+msgid "Compressed %d of %d nodes; %d%% remaining"
+msgstr "Skomprimovaných %d z %d uzlov; %d%% zostáva"
+
+msgid "E751: Output file name must not have region name"
+msgstr "E751: Výstupné meno súboru nesmie ma» názov regiónu"
+
+msgid "E754: Only up to 8 regions supported"
+msgstr "E754: Podporovaných max. 8 regiónov"
+
+#, c-format
+msgid "E755: Invalid region in %s"
+msgstr "E755: Chybný región v %s"
+
+msgid "Warning: both compounding and NOBREAK specified"
+msgstr "Varovanie: ¹pecifikované spájanie a nezalamovanie"
+
+#, c-format
+msgid "Writing spell file %s ..."
+msgstr "Ukládám slovníkový súbor %s ..."
+
+msgid "Done!"
+msgstr "Hotovo!"
+
+#, c-format
+msgid "Estimated runtime memory use: %d bytes"
+msgstr "Veµkos» pou¾ívanej pamäte: %d bajtov"
+
+#, c-format
+msgid "E765: 'spellfile' does not have %ld entries"
+msgstr "E765: 'spellfile' nemá %ld polo¾iek"
+
+msgid "E763: Word characters differ between spell files"
+msgstr "E763: Znaky slov sa odli¹ujú medzi slovníkovými súbormi"
+
+msgid "Sorry, no suggestions"
+msgstr "Prepáète, ¾iadne návrhy"
+
+#, c-format
+msgid "Sorry, only %ld suggestions"
+msgstr "Prepáète, iba %ld návrhov"
+
+#. avoid more prompt
+#, c-format
+msgid "Change \"%.*s\" to:"
+msgstr "Zmeni» \"%.*s\" na:"
+
+#, c-format
+msgid " < \"%.*s\""
+msgstr " < \"%.*s\""
+
+msgid "E752: No previous spell replacement"
+msgstr "E752: ®iadny predchádzajúce nahradenie podµa slovníka"
+
+#, c-format
+msgid "E753: Not found: %s"
+msgstr "E753: Nenájdené: %s"
+
+#. This should have been checked when generating the .spl
+#. * file.
+msgid "E783: duplicate char in MAP entry"
+msgstr "E783: duplicitný znak v MAP polo¾ke"
+
+#, c-format
+msgid "E390: Illegal argument: %s"
+msgstr "E390: Neprípustný argument: %s"
+
+#, c-format
+msgid "E391: No such syntax cluster: %s"
+msgstr "E391: Syntaktická zostava %s neexistuje"
+
+msgid "No Syntax items defined for this buffer"
+msgstr "Pre tento buffer nie sú definované ¾iadne polo¾ky syntaxe"
+
+msgid "syncing on C-style comments"
+msgstr "synchronizujem podµa komentárov jazyka C"
+
+msgid "no syncing"
+msgstr "¾iadne synchronizácie"
+
+msgid "syncing starts "
+msgstr "synchronizácia zaèína "
+
+msgid " lines before top line"
+msgstr " riadkov pred zaèiatkom"
+
+msgid ""
+"\n"
+"--- Syntax sync items ---"
+msgstr ""
+"\n"
+"--- Polo¾ky synchronizácie syntaxe ---"
+
+msgid ""
+"\n"
+"syncing on items"
+msgstr ""
+"\n"
+"synchronizujem polo¾ky"
+
+msgid ""
+"\n"
+"--- Syntax items ---"
+msgstr ""
+"\n"
+"--- Polo¾ky syntaxe ---"
+
+#, c-format
+msgid "E392: No such syntax cluster: %s"
+msgstr "E392: Syntaktická zostava %s neexistuje"
+
+msgid "minimal "
+msgstr "minimálne "
+
+msgid "maximal "
+msgstr "maximálne "
+
+msgid "; match "
+msgstr "; zhoda "
+
+msgid " line breaks"
+msgstr " zalomení riadkov"
+
+msgid "E395: contains argument not accepted here"
+msgstr "E395: obsahuje argumenty, ktoré tu nie sú povolené"
+
+msgid "E396: containedin argument not accepted here"
+msgstr "E396: obsahuje argumenty, ktoré tu nie sú povolené"
+
+msgid "E393: group[t]here not accepted here"
+msgstr "E393: group[t]here nesmie by» na tomto mieste"
+
+#, c-format
+msgid "E394: Didn't find region item for %s"
+msgstr "E394: Pre %s chýba polo¾ka regiónu"
+
+msgid "E397: Filename required"
+msgstr "E397: Vy¾adovaný názov súboru"
+
+#, c-format
+msgid "E789: Missing ']': %s"
+msgstr "E789: Chýba ']': %s"
+
+#, c-format
+msgid "E398: Missing '=': %s"
+msgstr "E398: Chýba '=': %s"
+
+#, c-format
+msgid "E399: Not enough arguments: syntax region %s"
+msgstr "E399: Príli¹ málo argumentov: oblas» syntaxe %s"
+
+msgid "E400: No cluster specified"
+msgstr "E400: Nebola zadaná ¾iadna zostava"
+
+#, c-format
+msgid "E401: Pattern delimiter not found: %s"
+msgstr "E401: Oddeµovaè vzoru %s nenájdený"
+
+#, c-format
+msgid "E402: Garbage after pattern: %s"
+msgstr "E402: Chyba za vzorom: %s"
+
+msgid "E403: syntax sync: line continuations pattern specified twice"
+msgstr "E403: synchronizácia syntaxe: vzor pokraèovania riadkov zadaný dvakrát"
+
+#, c-format
+msgid "E404: Illegal arguments: %s"
+msgstr "E404: Chybné argumenty: %s"
+
+#, c-format
+msgid "E405: Missing equal sign: %s"
+msgstr "E405: Chýba znamienko rovná sa: %s"
+
+#, c-format
+msgid "E406: Empty argument: %s"
+msgstr "E406: Prázdny argument: %s"
+
+#, c-format
+msgid "E407: %s not allowed here"
+msgstr "E407: %s tu nie je povolené"
+
+#, c-format
+msgid "E408: %s must be first in contains list"
+msgstr "E408: %s musí by» prvý v 'contains' zozname"
+
+#, c-format
+msgid "E409: Unknown group name: %s"
+msgstr "E409: Neznámy názov skupiny: %s"
+
+#, c-format
+msgid "E410: Invalid :syntax subcommand: %s"
+msgstr "E410: Chybný podradený príkaz :syntax : %s "
+
+msgid "E679: recursive loop loading syncolor.vim"
+msgstr "E679: rekurzívna sluèka pri naèítavaní syncolor.vim"
+
+#, c-format
+msgid "E411: highlight group not found: %s"
+msgstr "E411: skupina zvýraznenia %s nebola nájdená"
+
+#, c-format
+msgid "E412: Not enough arguments: \":highlight link %s\""
+msgstr "E412: Príli¹ málo argumentov: \":highlight link %s\""
+
+#, c-format
+msgid "E413: Too many arguments: \":highlight link %s\""
+msgstr "E413: Príli¹ mnoho argumentov: \":highlight link %s\""
+
+msgid "E414: group has settings, highlight link ignored"
+msgstr "E414: skupina je nastavená, odkaz na zvýrazòovaciu skupinu ignorovaný"
+
+#, c-format
+msgid "E415: unexpected equal sign: %s"
+msgstr "E415: neoèakávané znamienko rovná sa: %s"
+
+#, c-format
+msgid "E416: missing equal sign: %s"
+msgstr "E416: chýba znamienko rovná sa: %s"
+
+#, c-format
+msgid "E417: missing argument: %s"
+msgstr "E417: chýba argument: %s"
+
+#, c-format
+msgid "E418: Illegal value: %s"
+msgstr "E418: Neprípustná hodnota: %s"
+
+msgid "E419: FG color unknown"
+msgstr "E419: farba popredia nie je známa"
+
+msgid "E420: BG color unknown"
+msgstr "E420: farba pozadia nie je známa"
+
+#, c-format
+msgid "E421: Color name or number not recognized: %s"
+msgstr "E421: Názov alebo èíslo farby nebolo rozpoznané: %s"
+
+#, c-format
+msgid "E422: terminal code too long: %s"
+msgstr "E422: terminálový kód je príli¹ dlhý: %s"
+
+#, c-format
+msgid "E423: Illegal argument: %s"
+msgstr "E423: Neprípustný argument: %s"
+
+msgid "E424: Too many different highlighting attributes in use"
+msgstr "E424: Pou¾ívaných príli¹ veµa odli¹ných zvýrazòovacích vlastností"
+
+msgid "E669: Unprintable character in group name"
+msgstr "E669: Netlaèitelný znak v mene skupiny"
+
+msgid "W18: Invalid character in group name"
+msgstr "W18: Chybný znak v mene skupiny"
+
+msgid "E555: at bottom of tag stack"
+msgstr "E555: na konci zoznamu tagov"
+
+msgid "E556: at top of tag stack"
+msgstr "E556: na zaèiatku zoznamu tagov"
+
+msgid "E425: Cannot go before first matching tag"
+msgstr "E425: Nedá sa skoèi» pred prvý vyhovujúci tag"
+
+#, c-format
+msgid "E426: tag not found: %s"
+msgstr "E426: tag %s nenájdený"
+
+msgid " # pri kind tag"
+msgstr " # pri typ tag"
+
+msgid "file\n"
+msgstr "súbor\n"
+
+msgid "E427: There is only one matching tag"
+msgstr "E427: Vyhovuje iba jeden tag"
+
+msgid "E428: Cannot go beyond last matching tag"
+msgstr "E428: Za posledný vyhovujúci tag sa nedá preskoèi»"
+
+#, c-format
+msgid "File \"%s\" does not exist"
+msgstr "Súbor \"%s\" neexistuje"
+
+#. Give an indication of the number of matching tags
+#, c-format
+msgid "tag %d of %d%s"
+msgstr "tag %d z %d%s"
+
+msgid " or more"
+msgstr " alebo viac"
+
+msgid " Using tag with different case!"
+msgstr " Pou¾ívam tag s písmom inej veµkosti!"
+
+#, c-format
+msgid "E429: File \"%s\" does not exist"
+msgstr "E429: Súbor \"%s\" neexistuje"
+
+#. Highlight title
+msgid ""
+"\n"
+" # TO tag FROM line in file/text"
+msgstr ""
+"\n"
+" # CIE¥ tag ©TART riadok v súbore/texte"
+
+#, c-format
+msgid "Searching tags file %s"
+msgstr "Prehµadávam súbor tagov %s"
+
+#, c-format
+msgid "E430: Tag file path truncated for %s\n"
+msgstr "E430: Cesta k súboru tagov %s bola orezaná\n"
+
+#, c-format
+msgid "E431: Format error in tags file \"%s\""
+msgstr "E431: Chyba formátovania v súbore tagov \"%s\""
+
+#, c-format
+msgid "Before byte %ld"
+msgstr "Pred bajtom %ld"
+
+#, c-format
+msgid "E432: Tags file not sorted: %s"
+msgstr "E432: Obsah súboru tagov %s nie je zoradený"
+
+#. never opened any tags file
+msgid "E433: No tags file"
+msgstr "E433: ®iadny súbor tagov"
+
+msgid "E434: Can't find tag pattern"
+msgstr "E434: Nedá sa nájs» vzor tagov"
+
+msgid "E435: Couldn't find tag, just guessing!"
+msgstr "E435: Tag sa nedá nájs», iba hádam!"
+
+msgid "' not known. Available builtin terminals are:"
+msgstr "' nie je známy. Dostupné vstavané terminály:"
+
+msgid "defaulting to '"
+msgstr "nastavujem na '"
+
+msgid "E557: Cannot open termcap file"
+msgstr "E557: Nedá sa otvori» termcap súbor"
+
+msgid "E558: Terminal entry not found in terminfo"
+msgstr "E558: Terminfo neobsahuje polo¾ku pre tento terminál"
+
+msgid "E559: Terminal entry not found in termcap"
+msgstr "E559: Termcap neobsahuje polo¾ku pre tento terminál"
+
+#, c-format
+msgid "E436: No \"%s\" entry in termcap"
+msgstr "E436: Termcap neobsahuje polo¾ku \"%s\""
+
+msgid "E437: terminal capability \"cm\" required"
+msgstr "E437: Terminál musí ma» schopnos» \"cm\" (schopnos» pohybu kurzora)"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Terminal keys ---"
+msgstr ""
+"\n"
+"--- Klávesy terminálu ---"
+
+msgid "new shell started\n"
+msgstr "spustený nový shell\n"
+
+msgid "Vim: Error reading input, exiting...\n"
+msgstr "Vim: Chyba pri èítaní vstupu, konèím...\n"
+
+#. must display the prompt
+msgid "No undo possible; continue anyway"
+msgstr "Odstránenie zmien nie je mo¾né; chcete napriek tomu pokraèova»"
+
+msgid "E438: u_undo: line numbers wrong"
+msgstr "E438: u_undo: èísla riadkov sú chybné"
+
+msgid "1 change"
+msgstr "1 zmena"
+
+#, c-format
+msgid "%ld changes"
+msgstr "%ld zmien"
+
+msgid "E439: undo list corrupt"
+msgstr "E439: záznam o zmenách po¹kodený"
+
+msgid "E440: undo line missing"
+msgstr "E440: chýba opravný riadok"
+
+#. Only MS VC 4.1 and earlier can do Win32s
+msgid ""
+"\n"
+"MS-Windows 16/32-bit GUI version"
+msgstr ""
+"\n"
+"16/32 bitová GUI verzia pre MS Windows"
+
+msgid ""
+"\n"
+"MS-Windows 32-bit GUI version"
+msgstr ""
+"\n"
+"32 bitová GUI verzia pre MS Windows"
+
+msgid " in Win32s mode"
+msgstr " vo Win32 re¾ime"
+
+msgid " with OLE support"
+msgstr " s OLE podporou"
+
+msgid ""
+"\n"
+"MS-Windows 32-bit console version"
+msgstr ""
+"\n"
+"32 bitová verzia pre MS Windows konzolu"
+
+msgid ""
+"\n"
+"MS-Windows 16-bit version"
+msgstr ""
+"\n"
+"16 bitová verzia pre MS Windows"
+
+msgid ""
+"\n"
+"32-bit MS-DOS version"
+msgstr ""
+"\n"
+"32 bitová verzia pre MS-DOS"
+
+msgid ""
+"\n"
+"16-bit MS-DOS version"
+msgstr ""
+"\n"
+"16 bitová MS-DOS verzia"
+
+msgid ""
+"\n"
+"MacOS X (unix) version"
+msgstr ""
+"\n"
+"MacOS X (unix) verzia"
+
+msgid ""
+"\n"
+"MacOS X version"
+msgstr ""
+"\n"
+"MacOS X verzia"
+
+msgid ""
+"\n"
+"MacOS version"
+msgstr ""
+"\n"
+"MacOS verzia"
+
+msgid ""
+"\n"
+"RISC OS version"
+msgstr ""
+"\n"
+"RISC OS verzia"
+
+msgid ""
+"\n"
+"Included patches: "
+msgstr ""
+"\n"
+"Pou¾ité záplaty: "
+
+msgid "Modified by "
+msgstr "Zmenil "
+
+msgid ""
+"\n"
+"Compiled "
+msgstr ""
+"\n"
+"Prelo¾ená "
+
+msgid "by "
+msgstr " "
+
+msgid ""
+"\n"
+"Huge version "
+msgstr ""
+"\n"
+"Maximálna verzia"
+
+msgid ""
+"\n"
+"Big version "
+msgstr ""
+"\n"
+"Veµká verzia "
+
+msgid ""
+"\n"
+"Normal version "
+msgstr ""
+"\n"
+"Normálna verzia"
+
+msgid ""
+"\n"
+"Small version "
+msgstr ""
+"\n"
+"Malá verzia "
+
+msgid ""
+"\n"
+"Tiny version "
+msgstr ""
+"\n"
+"Minimálna verzia "
+
+msgid "without GUI."
+msgstr "bez grafického rozhrania."
+
+msgid "with GTK2-GNOME GUI."
+msgstr "s grafickým rozhraním GTK2-GNOME."
+
+msgid "with GTK-GNOME GUI."
+msgstr "s grafickým rozhraním GTK-GNOME."
+
+msgid "with GTK2 GUI."
+msgstr "s grafickým rozhraním GTK2."
+
+msgid "with GTK GUI."
+msgstr "s grafickým rozhraním GTK."
+
+msgid "with X11-Motif GUI."
+msgstr "s grafickým rozhraním X11-Motif."
+
+msgid "with X11-neXtaw GUI."
+msgstr "s grafickým rozhraním X11-neXtaw."
+
+msgid "with X11-Athena GUI."
+msgstr "s grafickým rozhraním X11-Athena."
+
+msgid "with Photon GUI."
+msgstr "s grafickým rozhraním Photon."
+
+msgid "with GUI."
+msgstr "s grafickým rozhraním."
+
+msgid "with Carbon GUI."
+msgstr "s grafickým rozhraním Carbon."
+
+msgid "with Cocoa GUI."
+msgstr "s grafickým rozhraním Cocoa."
+
+msgid "with (classic) GUI."
+msgstr "s klasickým grafickým rozhraním."
+
+msgid "with KDE GUI."
+msgstr "s grafickým rozhraním KDE."
+
+msgid " Features included (+) or not (-):\n"
+msgstr " Vlastnosti zahrnuté (+) a nezahrnuté (-):\n"
+
+msgid " system vimrc file: \""
+msgstr " systémový vimrc súbor: \""
+
+msgid " user vimrc file: \""
+msgstr " u¾ívateµský vimrc súbor: \""
+
+msgid " 2nd user vimrc file: \""
+msgstr " druhý u¾ívateµský vimrc súbor: \""
+
+msgid " 3rd user vimrc file: \""
+msgstr " tretí u¾ívateµský vimrc súbor: \""
+
+msgid " user exrc file: \""
+msgstr " u¾ívateµský exrc súbor: \""
+
+msgid " 2nd user exrc file: \""
+msgstr " druhý u¾ívateµský exrc súbor: \""
+
+msgid " system gvimrc file: \""
+msgstr " systémový gvimrc súbor: \""
+
+msgid " user gvimrc file: \""
+msgstr " u¾ívateµský gvimrc súbor: \""
+
+msgid "2nd user gvimrc file: \""
+msgstr "druhý u¾ívateµský gvimrc súbor: \""
+
+msgid "3rd user gvimrc file: \""
+msgstr "tretí u¾ívateµský gvimrc súbor: \""
+
+msgid " system menu file: \""
+msgstr " systémový súbor s ponukou: \""
+
+msgid " fall-back for $VIM: \""
+msgstr " implicitná hodnota $VIM:\""
+
+msgid " f-b for $VIMRUNTIME: \""
+msgstr " f-b pre $VIMRUNTIME: \""
+
+msgid "Compilation: "
+msgstr "Preklad: "
+
+msgid "Compiler: "
+msgstr "Prekladaè: "
+
+msgid "Linking: "
+msgstr "Zlinkované: "
+
+msgid " DEBUG BUILD"
+msgstr " PODPORA LADENIA"
+
+msgid "VIM - Vi IMproved"
+msgstr "VIM - Vi IMproved"
+
+msgid "version "
+msgstr "verzia "
+
+msgid "by Bram Moolenaar et al."
+msgstr "od Brama Moolenaara a ïal¹ích"
+
+msgid "Vim is open source and freely distributable"
+msgstr "Vim je voµne ¹íriteµný program s otvoreným kódom"
+
+msgid "Help poor children in Uganda!"
+msgstr "Pomô¾te chudobným de»om v Ugande!"
+
+msgid "type :help iccf<Enter> for information "
+msgstr "zadajte :help iccf<Enter> pre informácie "
+
+msgid "type :q<Enter> to exit "
+msgstr "zadajte :q<Enter> pre ukonèenie programu "
+
+msgid "type :help<Enter> or <F1> for on-line help"
+msgstr "zadajte :help<Enter> alebo <F1> pre pomocníka "
+
+msgid "type :help version7<Enter> for version info"
+msgstr "zadajte :help version7<Enter> pre informácie o verzii"
+
+msgid "Running in Vi compatible mode"
+msgstr "Pracujem v re¾ime kompatibility s Vi"
+
+msgid "type :set nocp<Enter> for Vim defaults"
+msgstr "zadajte :set nocp<Enter> pre implicitné nastavenie Vim"
+
+msgid "type :help cp-default<Enter> for info on this"
+msgstr "podrobnej¹ie informácie získate pomocou :help cp-default<Enter>"
+
+msgid "menu Help->Orphans for information "
+msgstr "bli¾¹ie informácie v ponuke Pomocník->Samostatné"
+
+msgid "Running modeless, typed text is inserted"
+msgstr "Spú¹»am v bezmódovom re¾ime, písaný text je vlo¾ený"
+
+msgid "menu Edit->Global Settings->Toggle Insert Mode "
+msgstr "ponuka Úpravy->Globálne mo¾nosti->Prepnú» re¾im vlo¾enia "
+
+msgid " for two modes "
+msgstr " pre dva re¾imy "
+
+msgid "menu Edit->Global Settings->Toggle Vi Compatible"
+msgstr "ponuka Úpravy->Globálne mo¾nostt->Prepnú» Vi kompatibilný re¾im"
+
+msgid " for Vim defaults "
+msgstr " pre predvolené vlastnosti Vim "
+
+msgid "Sponsor Vim development!"
+msgstr "Zasponzorujte vývoj Vimu!"
+
+msgid "Become a registered Vim user!"
+msgstr "Staòte sa registrovaným u¾ívateµom Vimu!"
+
+msgid "type :help sponsor<Enter> for information "
+msgstr "zadajte :help sponsor<Enter> pre informácie "
+
+msgid "type :help register<Enter> for information "
+msgstr "zadajte :help register<Enter> pre informácie "
+
+msgid "menu Help->Sponsor/Register for information "
+msgstr "bli¾¹ie informácie v ponuke Pomocník->Sponzor/Registrácia"
+
+msgid "WARNING: Windows 95/98/ME detected"
+msgstr "VAROVANIE: detekované Windows 95/98/ME"
+
+msgid "type :help windows95<Enter> for info on this"
+msgstr "zadajte :help windows95<Enter> pre podrobnej¹ie informácie"
+
+msgid "E441: There is no preview window"
+msgstr "E441: Nenájdené ¾iadne okno náhµadu"
+
+msgid "E442: Can't split topleft and botright at the same time"
+msgstr ""
+"E442: Okno sa nedá rozdeli» zároveò v móde 'vrchný-µavý' a 'spodný-"
+"pravý' ('topleft' a 'botright')"
+
+msgid "E443: Cannot rotate when another window is split"
+msgstr "E443: Nedá sa rotova», ak je iné okno rozdelené"
+
+msgid "E444: Cannot close last window"
+msgstr "E444: Posledné okno sa nedá zatvori»"
+
+msgid "Already only one window"
+msgstr "Existuje u¾ iba jedno okno"
+
+msgid "E445: Other window contains changes"
+msgstr "E445: Iné okno obsahuje zmeny"
+
+msgid "E446: No file name under cursor"
+msgstr "E446: Pod kurzorom sa nenachádza názov súboru"
+
+#, c-format
+msgid "E447: Can't find file \"%s\" in path"
+msgstr "E447: Súbor \"%s\" sa nedá nájs» v ceste"
+
+#, c-format
+msgid "E370: Could not load library %s"
+msgstr "E370: Nepodarilo sa nahra» kni¾nicu %s"
+
+msgid "Sorry, this command is disabled: the Perl library could not be loaded."
+msgstr "Prepáète, tento príkaz je vypnutý, Perl kni¾nica nemô¾e by» naèítaná."
+
+msgid "E299: Perl evaluation forbidden in sandbox without the Safe module"
+msgstr "E299: Vykonanie kódu v jazyku Perl nie je mo¾né v bezpeènostnej schránke bez bezpeènostného modulu"
+
+msgid "Edit with &multiple Vims"
+msgstr "Upravi» s viacerý&mi Vimmi"
+
+msgid "Edit with single &Vim"
+msgstr "Upravi» s jedným &Vimom"
+
+msgid "Diff with Vim"
+msgstr "Porovna» &Vimom"
+
+msgid "Edit with &Vim"
+msgstr "Upravi» s &Vimom"
+
+#. Now concatenate
+msgid "Edit with existing Vim - "
+msgstr "Upravi» s existujúcim Vimom - "
+
+msgid "Edits the selected file(s) with Vim"
+msgstr "Upravi» vybrané súbory s Vimom"
+
+msgid "Error creating process: Check if gvim is in your path!"
+msgstr "Chyba vytvárania procesu: Skontrolujte, èi je gvim vo va¹ej ceste!"
+
+msgid "gvimext.dll error"
+msgstr "chyba gvimext.dll"
+
+msgid "Path length too long!"
+msgstr "Príli¹ dlhá cesta!"
+
+msgid "--No lines in buffer--"
+msgstr "--Buffer neobsahuje ¾iadne riadky--"
+
+#.
+#. * 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: Príkaz preru¹ený"
+
+msgid "E471: Argument required"
+msgstr "E471: Je vy¾adovaný argument"
+
+msgid "E10: \\ should be followed by /, ? or &"
+msgstr "E10: po \\ by malo nasledova» /, ? alebo &"
+
+msgid "E11: Invalid in command-line window; <CR> executes, CTRL-C quits"
+msgstr ""
+"E11: Chybný príkaz v okne príkazového riadku; <Enter> spú¹»a, CTRL-C ukonèuje"
+
+msgid "E12: Command not allowed from exrc/vimrc in current dir or tag search"
+msgstr ""
+"E12: Príkaz nie je z exrc/vimrc v aktuálnom adresári alebo pri hµadaní tagu "
+"povolený."
+
+msgid "E171: Missing :endif"
+msgstr "E171: Chýba :endif"
+
+msgid "E600: Missing :endtry"
+msgstr "E600: Chýba :endtry"
+
+msgid "E170: Missing :endwhile"
+msgstr "E170: Chýba :endwhile"
+
+msgid "E170: Missing :endfor"
+msgstr "E170: Chýba :endfor"
+
+msgid "E588: :endwhile without :while"
+msgstr "E588: :endwhile bez zodpovedajúceho :while"
+
+msgid "E588: :endfor without :for"
+msgstr "E588: :endfor bez zodpovedajúceho :for"
+
+msgid "E13: File exists (add ! to override)"
+msgstr "E13: Súbor existuje (pou¾ite ! pre prepísanie)"
+
+msgid "E472: Command failed"
+msgstr "E472: Príkaz zlyhal"
+
+#, c-format
+msgid "E234: Unknown fontset: %s"
+msgstr "E234: Neznáma sada písiem: %s"
+
+#, c-format
+msgid "E235: Unknown font: %s"
+msgstr "E235: Neznáme písmo: %s"
+
+#, c-format
+msgid "E236: Font \"%s\" is not fixed-width"
+msgstr "E236: Písmo \"%s\" nemá pevnú ¹írku"
+
+msgid "E473: Internal error"
+msgstr "E473: Vnútorná chyba"
+
+msgid "Interrupted"
+msgstr "Preru¹ené"
+
+msgid "E14: Invalid address"
+msgstr "E14: Chybná adresa"
+
+msgid "E474: Invalid argument"
+msgstr "E474: Chybný argument"
+
+#, c-format
+msgid "E475: Invalid argument: %s"
+msgstr "E475: Chybný argument: %s"
+
+#, c-format
+msgid "E15: Invalid expression: %s"
+msgstr "E15: Chybný výraz: %s"
+
+msgid "E16: Invalid range"
+msgstr "E16: Chybný rozsah"
+
+msgid "E476: Invalid command"
+msgstr "E476: Chybný príkaz"
+
+#, c-format
+msgid "E17: \"%s\" is a directory"
+msgstr "E17: \"%s\" je adresárom"
+
+#, c-format
+msgid "E364: Library call failed for \"%s()\""
+msgstr "E364: Vyvolanie kni¾niènej funkcia zlyhalo pre \"%s()\""
+
+#, c-format
+msgid "E448: Could not load library function %s"
+msgstr "E448: Nepodarilo sa nahra» funkciu kni¾nice %s"
+
+msgid "E19: Mark has invalid line number"
+msgstr "E19: Znaèka má chybné èíslo riadku"
+
+msgid "E20: Mark not set"
+msgstr "E20: Znaèka nie je nastavená"
+
+msgid "E21: Cannot make changes, 'modifiable' is off"
+msgstr "E21: Nemo¾no robi» zmeny, voµba 'modifiable' je vypnutá"
+
+msgid "E22: Scripts nested too deep"
+msgstr "E22: Skripty vnorené príli¹ hlboko"
+
+msgid "E23: No alternate file"
+msgstr "E23: ®iadny alternatívny súbor"
+
+msgid "E24: No such abbreviation"
+msgstr "E24: Taká skratka neexistuje"
+
+msgid "E477: No ! allowed"
+msgstr "E477: ! nie je povolený"
+
+msgid "E25: GUI cannot be used: Not enabled at compile time"
+msgstr "E25: Nedá sa pou¾í» GUI: nebolo zapnuté pri preklade programu"
+
+msgid "E26: Hebrew cannot be used: Not enabled at compile time\n"
+msgstr ""
+"E26: Nedá sa pou¾í» hebrejský re¾im: nebol zapnutý pri preklade programu\n"
+
+msgid "E27: Farsi cannot be used: Not enabled at compile time\n"
+msgstr "E27: Nedá sa pou¾í» farsi re¾im: nebol zapnutý pri preklade programu\n"
+
+msgid "E800: Arabic cannot be used: Not enabled at compile time\n"
+msgstr "E800: Nedá sa pou¾í» arabic re¾im: nebol zapnutý pri preklade programu\n"
+
+#, c-format
+msgid "E28: No such highlight group name: %s"
+msgstr "E28: Skupina zvýraznenia %s neexistuje"
+
+msgid "E29: No inserted text yet"
+msgstr "E29: Zatiaµ nie je vlo¾ený ¾iaden text"
+
+msgid "E30: No previous command line"
+msgstr "E30: ®iadny predchádzajúci príkazový riadok"
+
+msgid "E31: No such mapping"
+msgstr "E31: Mapovanie nenájdené"
+
+msgid "E479: No match"
+msgstr "E479: ®iadna zhoda"
+
+#, c-format
+msgid "E480: No match: %s"
+msgstr "E480: ®iadna zhoda: %s"
+
+msgid "E32: No file name"
+msgstr "E32: ®iadny názov súboru"
+
+msgid "E33: No previous substitute regular expression"
+msgstr "E33: ®iadny predchádzajúci prislúchajúci správny výraz"
+
+msgid "E34: No previous command"
+msgstr "E34: ®iadny predchádzajúci príkaz"
+
+msgid "E35: No previous regular expression"
+msgstr "E35: ®iadny predchádzajúci regulárny výraz"
+
+msgid "E481: No range allowed"
+msgstr "E481: Rozsah nie je povolený"
+
+msgid "E36: Not enough room"
+msgstr "E36: Nedostatok miesta"
+
+#, c-format
+msgid "E247: no registered server named \"%s\""
+msgstr "E247: ¾iaden registrovaný server pomenovaný \"%s\""
+
+#, c-format
+msgid "E482: Can't create file %s"
+msgstr "E482: Nedá sa vytvori» súbor %s"
+
+msgid "E483: Can't get temp file name"
+msgstr "E483: Nedá sa získa» názov doèasného súboru"
+
+#, c-format
+msgid "E484: Can't open file %s"
+msgstr "E484: Nedá sa otvori» súbor %s"
+
+#, c-format
+msgid "E485: Can't read file %s"
+msgstr "E485: Nedá sa èíta» súbor %s"
+
+msgid "E37: No write since last change (add ! to override)"
+msgstr "E37: Neulo¾ené zmeny (pou¾ite ! pre vynútenie)"
+
+msgid "E38: Null argument"
+msgstr "E38: Nulový argument"
+
+msgid "E39: Number expected"
+msgstr "E39: Oèakávané èíslo"
+
+#, c-format
+msgid "E40: Can't open errorfile %s"
+msgstr "E40: Nedá sa otvori» chybový súbor %s"
+
+msgid "E233: cannot open display"
+msgstr "E233: nedá sa otvori» displej"
+
+msgid "E41: Out of memory!"
+msgstr "E41: Nedostatok pamäti!"
+
+msgid "Pattern not found"
+msgstr "Vzor nenájdený"
+
+#, c-format
+msgid "E486: Pattern not found: %s"
+msgstr "E486: Vzor nenájdený: %s"
+
+msgid "E487: Argument must be positive"
+msgstr "E487: Argument musí by» kladný"
+
+msgid "E459: Cannot go back to previous directory"
+msgstr "E459: ®iadny predchádzajúci adresár"
+
+msgid "E42: No Errors"
+msgstr "E42: ®iadne chyby"
+
+msgid "E43: Damaged match string"
+msgstr "E43: Po¹kodený re»azac pre vyhµadávanie"
+
+msgid "E44: Corrupted regexp program"
+msgstr "E44: Po¹kodený regexp program"
+
+msgid "E45: 'readonly' option is set (add ! to override)"
+msgstr ""
+"E45: voµba 'readonly' (iba na èítanie) je nastavená (pou¾ite ! pre "
+"prepísanie)"
+
+#, c-format
+msgid "E46: Cannot change read-only variable \"%s\""
+msgstr "E46: Nedá sa nastavi» premenná len na èítanie \"%s\""
+
+#, c-format
+msgid "E46: Cannot set variable in the sandbox: \"%s\""
+msgstr "E46: Nedá sa nastavi» premenná v bezpeènostnej schránke: \"%s\""
+
+msgid "E47: Error while reading errorfile"
+msgstr "E47: Chyba pri èítaní chybového súboru"
+
+msgid "E48: Not allowed in sandbox"
+msgstr "E48: Nie je dovolené v bezpeènostnej schránke"
+
+msgid "E523: Not allowed here"
+msgstr "E523: Nie je na povolené na tomto mieste"
+
+msgid "E359: Screen mode setting not supported"
+msgstr "E359: Nastavovanie re¾imu obrazovky nie je podporované"
+
+msgid "E49: Invalid scroll size"
+msgstr "E49: Chybná hodnota veµkosti rolovania"
+
+msgid "E91: 'shell' option is empty"
+msgstr "E91: voµba 'shell' je prázdna"
+
+msgid "E255: Couldn't read in sign data!"
+msgstr "E255: Chyba -- nedájú sa preèíta» oznaèovacie dáta!"
+
+msgid "E72: Close error on swap file"
+msgstr "E72: Chyba pri uzatváraní odkladacieho súboru"
+
+msgid "E73: tag stack empty"
+msgstr "E73: zoznam tagov je prázdny"
+
+msgid "E74: Command too complex"
+msgstr "E74: Príkaz je príli¹ zlo¾itý"
+
+msgid "E75: Name too long"
+msgstr "E75: Názov je príli¹ dlhý"
+
+msgid "E76: Too many ["
+msgstr "E76: Príli¹ mnoho ["
+
+msgid "E77: Too many file names"
+msgstr "E77: Príli¹ mnoho názvov súborov"
+
+msgid "E488: Trailing characters"
+msgstr "E488: Nadbytoèné znaky na konci"
+
+msgid "E78: Unknown mark"
+msgstr "E78: Neznáma znaèka"
+
+msgid "E79: Cannot expand wildcards"
+msgstr "E79: Nemo¾no expandova» ¾olíkové znaky (wildcards)"
+
+msgid "E591: 'winheight' cannot be smaller than 'winminheight'"
+msgstr ""
+"E591: hodnota voµby 'winheight' (vý¹ka okna) nesmie by» men¹ia ne¾ hodnota voµby 'winminheight' (minimálna vý¹ka okna)"
+
+msgid "E592: 'winwidth' cannot be smaller than 'winminwidth'"
+msgstr ""
+"E592: hodnota voµby 'winwidth' (¹írka okna) nesmie by» men¹ia ne¾ hodnota volµy 'winminwidth' (minimálna ¹írka okna)"
+
+msgid "E80: Error while writing"
+msgstr "E80: Chyba pri ukladaní"
+
+msgid "Zero count"
+msgstr "Nulový poèet"
+
+msgid "E81: Using <SID> not in a script context"
+msgstr "E81: Pou¾itie <SID> mimo kontext skriptu"
+
+msgid "E449: Invalid expression received"
+msgstr "E449: Bol prijatý chybný výraz"
+
+msgid "E463: Region is guarded, cannot modify"
+msgstr "E463: Región je uzamknutý, nemo¾no modifikova»"
+
+msgid "E744: NetBeans does not allow changes in read-only files"
+msgstr "E744: NetBeans nepovoµuje zmeny v súboroch len na èítanie"
+
+#, c-format
+msgid "E685: Internal error: %s"
+msgstr "E685: Vnútorná chyba: %s"
+
+msgid "E363: pattern uses more memory than 'maxmempattern'"
+msgstr "E363: vzor pou¾íva viac pamäte ako 'maxmempattern'"
+
+msgid "E749: empty buffer"
+msgstr "E749: prázdny buffer"
+
+msgid "E682: Invalid search pattern or delimiter"
+msgstr "E682: Neprípustný hµadaný re»azec alebo oddeµovaè"
+
+msgid "E139: File is loaded in another buffer"
+msgstr "E139: Súbor je naèítaný v inom buffere"
+
+#, c-format
+msgid "E764: Option '%s' is not set"
+msgstr "E764: Voµba \"%s\" nie je nastavená"
+
+msgid "search hit TOP, continuing at BOTTOM"
+msgstr "hµadanie dosiahlo zaèiatok, pokraèovanie od konca"
+
+msgid "search hit BOTTOM, continuing at TOP"
+msgstr "hµadanie dosiahlo koniec, pokraèovanie od zaèiatku"
+
diff --git a/src/po/sv.po b/src/po/sv.po
new file mode 100644
index 0000000000..43c8de9e95
--- /dev/null
+++ b/src/po/sv.po
@@ -0,0 +1,6148 @@
+# Swedish translation for Vim.
+# Copyright (C) 2003-2007 Free Software Foundation, Inc.
+# Johan Svedberg <johan@svedberg.com>, 2003-2007.
+msgid ""
+msgstr ""
+"Project-Id-Version: Vim 7.1\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2007-05-09 14:27+0200\n"
+"PO-Revision-Date: 2007-05-09 14:52\n"
+"Last-Translator: Johan Svedberg <johan@svedberg.com>\n"
+"Language-Team: Swedish <tp-sv@listor.tp-sv.se>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=ISO-8859-1\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+msgid "E82: Cannot allocate any buffer, exiting..."
+msgstr "E82: Kan inte allokera någon buffert, avslutar..."
+
+msgid "E83: Cannot allocate buffer, using other one..."
+msgstr "E83: Kan inte allokera buffert, använder en annan..."
+
+msgid "E515: No buffers were unloaded"
+msgstr "E515: Inga buffertar blev urladdade"
+
+msgid "E516: No buffers were deleted"
+msgstr "E516: Inga buffertar blev borttagna"
+
+msgid "E517: No buffers were wiped out"
+msgstr "E517: Inga buffertar blev utraderade"
+
+msgid "1 buffer unloaded"
+msgstr "1 buffert laddades ur"
+
+#, c-format
+msgid "%d buffers unloaded"
+msgstr "%d buffertar laddades ur"
+
+msgid "1 buffer deleted"
+msgstr "1 buffert borttagen"
+
+#, c-format
+msgid "%d buffers deleted"
+msgstr "%d buffertar borttagna"
+
+msgid "1 buffer wiped out"
+msgstr "1 buffert utraderad"
+
+#, c-format
+msgid "%d buffers wiped out"
+msgstr "%d buffertar utraderade"
+
+msgid "E84: No modified buffer found"
+msgstr "E84: Ingen modifierad buffert hittad"
+
+#. back where we started, didn't find anything.
+msgid "E85: There is no listed buffer"
+msgstr "E85: Det finns inga listade buffertar"
+
+#, c-format
+msgid "E86: Buffer %ld does not exist"
+msgstr "E86: Buffert %ld existerar inte"
+
+msgid "E87: Cannot go beyond last buffer"
+msgstr "E87: Kan inte gå bortom sista buffert"
+
+msgid "E88: Cannot go before first buffer"
+msgstr "E88: Kan inte gå före första buffert"
+
+#, c-format
+msgid "E89: No write since last change for buffer %ld (add ! to override)"
+msgstr ""
+"E89: Ingen skrivning sedan senaste ändring för buffert %ld (lägg till ! för "
+"att tvinga)"
+
+msgid "E90: Cannot unload last buffer"
+msgstr "E90: Kan inte ladda ur senaste buffert"
+
+msgid "W14: Warning: List of file names overflow"
+msgstr "W14: Varning: Lista över filnamn flödar över"
+
+#, c-format
+msgid "E92: Buffer %ld not found"
+msgstr "E92: Buffer %ld hittades inte"
+
+#, c-format
+msgid "E93: More than one match for %s"
+msgstr "E93: Fler än en träff för %s"
+
+#, c-format
+msgid "E94: No matching buffer for %s"
+msgstr "E94: Ingen matchande buffert för %s"
+
+#, c-format
+msgid "line %ld"
+msgstr "rad %ld"
+
+msgid "E95: Buffer with this name already exists"
+msgstr "E95: Buffer med det här namnet existerar redan"
+
+msgid " [Modified]"
+msgstr " [Modifierad]"
+
+msgid "[Not edited]"
+msgstr "[Inte redigerad]"
+
+msgid "[New file]"
+msgstr "[Ny fil]"
+
+msgid "[Read errors]"
+msgstr "[Läsfel]"
+
+msgid "[readonly]"
+msgstr "[skrivskyddad]"
+
+#, c-format
+msgid "1 line --%d%%--"
+msgstr "1 rad --%d%%--"
+
+#, c-format
+msgid "%ld lines --%d%%--"
+msgstr "%ld rader --%d%%--"
+
+#, c-format
+msgid "line %ld of %ld --%d%%-- col "
+msgstr "rad %ld av %ld --%d%%-- kol "
+
+msgid "[No Name]"
+msgstr "[Inget Namn]"
+
+#. must be a help buffer
+msgid "help"
+msgstr "hjälp"
+
+msgid "[Help]"
+msgstr "[Hjälp]"
+
+msgid "[Preview]"
+msgstr "[Förhandsvisning]"
+
+msgid "All"
+msgstr "Alla"
+
+msgid "Bot"
+msgstr "Bott"
+
+msgid "Top"
+msgstr "Topp"
+
+#, c-format
+msgid ""
+"\n"
+"# Buffer list:\n"
+msgstr ""
+"\n"
+"# Buffertlista:\n"
+
+msgid "[Location List]"
+msgstr "[Positionslista]"
+
+msgid "[Quickfix List]"
+msgstr "[Quickfix-lista]"
+
+msgid ""
+"\n"
+"--- Signs ---"
+msgstr ""
+"\n"
+"--- Tecken ---"
+
+#, c-format
+msgid "Signs for %s:"
+msgstr "Tecken för %s:"
+
+#, c-format
+msgid " line=%ld id=%d name=%s"
+msgstr " line=%ld id=%d namn=%s"
+
+#, c-format
+msgid "E96: Can not diff more than %ld buffers"
+msgstr "E96: Kan inte skilja fler än %ld buffertar"
+
+msgid "E97: Cannot create diffs"
+msgstr "E97: Kan inte skapa skiljare"
+
+msgid "Patch file"
+msgstr "Patchfil"
+
+msgid "E98: Cannot read diff output"
+msgstr "E98: Kan inte läsa skiljeutdata"
+
+msgid "E99: Current buffer is not in diff mode"
+msgstr "E99: Aktuell buffert är inte i skiljeläge"
+
+msgid "E793: No other buffer in diff mode is modifiable"
+msgstr "E793: Ingen annan buffert i skiljeläge är ändringsbar"
+
+msgid "E100: No other buffer in diff mode"
+msgstr "E100: Ingen annan buffert i skiljeläge"
+
+msgid "E101: More than two buffers in diff mode, don't know which one to use"
+msgstr ""
+"E101: Fler än två buffertar i skiljeläge, vet inte vilken som ska användas"
+
+#, c-format
+msgid "E102: Can't find buffer \"%s\""
+msgstr "E102: Kan inte hitta buffert \"%s\""
+
+#, c-format
+msgid "E103: Buffer \"%s\" is not in diff mode"
+msgstr "E103: Buffert \"%s\" är inte i skiljeläge"
+
+msgid "E787: Buffer changed unexpectedly"
+msgstr "E787: Buffert ändrades oväntat"
+
+msgid "E104: Escape not allowed in digraph"
+msgstr "E104: Escape inte tillåtet i digraf"
+
+msgid "E544: Keymap file not found"
+msgstr "E544: Keymap-fil hittades inte"
+
+msgid "E105: Using :loadkeymap not in a sourced file"
+msgstr "E105: Användning av :loadkeymap utanför en körd fil"
+
+msgid "E791: Empty keymap entry"
+msgstr "E791: Tomt tangentbords-post"
+
+msgid " Keyword completion (^N^P)"
+msgstr " Nyckelordskomplettering (^N^P)"
+
+#. ctrl_x_mode == 0, ^P/^N compl.
+msgid " ^X mode (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)"
+msgstr " ^X-läge (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)"
+
+msgid " Whole line completion (^L^N^P)"
+msgstr " Helradskomplettering (^L^N^P)"
+
+msgid " File name completion (^F^N^P)"
+msgstr " Filnamnskomplettering (^F^N^P)"
+
+msgid " Tag completion (^]^N^P)"
+msgstr " Taggkomplettering (^]^N^P)"
+
+msgid " Path pattern completion (^N^P)"
+msgstr " Sökvägsmönsterkomplettering (^N^P)"
+
+msgid " Definition completion (^D^N^P)"
+msgstr " Definitionskomplettering (^D^N^P)"
+
+msgid " Dictionary completion (^K^N^P)"
+msgstr " Ordbokskomplettering (^K^N^P)"
+
+msgid " Thesaurus completion (^T^N^P)"
+msgstr " Tesaurkomplettering (^T^N^P)"
+
+msgid " Command-line completion (^V^N^P)"
+msgstr " Kommandoradskomplettering (^V^N^P)"
+
+msgid " User defined completion (^U^N^P)"
+msgstr " Användardefinierad komplettering (^U^N^P)"
+
+msgid " Omni completion (^O^N^P)"
+msgstr " Omnikomplettering (^O^N^P)"
+
+msgid " Spelling suggestion (s^N^P)"
+msgstr " Stavningsförslag (s^N^P)"
+
+msgid " Keyword Local completion (^N^P)"
+msgstr " Lokal nyckelordskomplettering (^N^P)"
+
+msgid "Hit end of paragraph"
+msgstr "Stötte på slutet på stycket"
+
+msgid "'dictionary' option is empty"
+msgstr "'dictionary'-flagga är tom"
+
+msgid "'thesaurus' option is empty"
+msgstr "'thesaurus'-flagga är tom"
+
+#, c-format
+msgid "Scanning dictionary: %s"
+msgstr "Söker igenom ordbok: %s"
+
+msgid " (insert) Scroll (^E/^Y)"
+msgstr " (infoga) Rulla (^E/^Y)"
+
+msgid " (replace) Scroll (^E/^Y)"
+msgstr " (ersätt) Rulla (^E/^Y)"
+
+#, c-format
+msgid "Scanning: %s"
+msgstr "Söker igenom: %s"
+
+#, c-format
+msgid "Scanning tags."
+msgstr "Söker igenom taggar."
+
+msgid " Adding"
+msgstr " Lägger till"
+
+#. 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.
+#.
+msgid "-- Searching..."
+msgstr "-- Söker..."
+
+msgid "Back at original"
+msgstr "Tillbaka på orginalet"
+
+msgid "Word from other line"
+msgstr "Ord från annan rad"
+
+msgid "The only match"
+msgstr "Den enda träffen"
+
+#, c-format
+msgid "match %d of %d"
+msgstr "träff %d av %d"
+
+#, c-format
+msgid "match %d"
+msgstr "träff %d"
+
+msgid "E18: Unexpected characters in :let"
+msgstr "E18: Oväntade tecken i :let"
+
+#, c-format
+msgid "E684: list index out of range: %ld"
+msgstr "E684: listindex utanför område: %ld"
+
+#, c-format
+msgid "E121: Undefined variable: %s"
+msgstr "E121: Odefinierad variabel: %s"
+
+msgid "E111: Missing ']'"
+msgstr "E111: Saknar ']'"
+
+#, c-format
+msgid "E686: Argument of %s must be a List"
+msgstr "E686: Argument av %s måste vara en List"
+
+#, c-format
+msgid "E712: Argument of %s must be a List or Dictionary"
+msgstr "E712: Argument av %s måste vara en Lista eller Tabell"
+
+msgid "E713: Cannot use empty key for Dictionary"
+msgstr "E713: Kan inte använda tom nyckel för Tabell"
+
+msgid "E714: List required"
+msgstr "E714: Lista krävs"
+
+msgid "E715: Dictionary required"
+msgstr "E715: Tabell krävs"
+
+#, c-format
+msgid "E118: Too many arguments for function: %s"
+msgstr "E118: För många argument till funktion: %s"
+
+#, c-format
+msgid "E716: Key not present in Dictionary: %s"
+msgstr "E716: Tangent finns inte i Tabell: %s"
+
+#, c-format
+msgid "E122: Function %s already exists, add ! to replace it"
+msgstr "E122: Funktionen %s existerar redan, lägg till ! för att ersätta den"
+
+msgid "E717: Dictionary entry already exists"
+msgstr "E717: Tabell-post existerar redan"
+
+msgid "E718: Funcref required"
+msgstr "E718: Funcref krävs"
+
+msgid "E719: Cannot use [:] with a Dictionary"
+msgstr "E719: Kan inte använda [:] med en Tabell"
+
+#, c-format
+msgid "E734: Wrong variable type for %s="
+msgstr "E734: Fel variabeltyp för %s="
+
+#, c-format
+msgid "E130: Unknown function: %s"
+msgstr "E130: Okänd funktion: %s"
+
+#, c-format
+msgid "E461: Illegal variable name: %s"
+msgstr "E461: Otillåtet variabelnamn: %s"
+
+msgid "E687: Less targets than List items"
+msgstr "E687: Färre mål än List-poster"
+
+msgid "E688: More targets than List items"
+msgstr "E688: Fler mål än List-poster"
+
+msgid "Double ; in list of variables"
+msgstr "Double ; i listan med variabler"
+
+#, c-format
+msgid "E738: Can't list variables for %s"
+msgstr "E738: Kan inte lista variabler för %s"
+
+msgid "E689: Can only index a List or Dictionary"
+msgstr "E689: Kan bara indexera en Lista eller Tabell"
+
+msgid "E708: [:] must come last"
+msgstr "E708: [:] måste komma sist"
+
+msgid "E709: [:] requires a List value"
+msgstr "E709: [:] kräver ett List-värde"
+
+msgid "E710: List value has more items than target"
+msgstr "E710: List-värde har mer föremål än mål"
+
+msgid "E711: List value has not enough items"
+msgstr "E711: List-värde har inte tillräckligt med föremål"
+
+msgid "E690: Missing \"in\" after :for"
+msgstr "E690: Saknar \"in\" efter :for"
+
+#, c-format
+msgid "E107: Missing parentheses: %s"
+msgstr "E107: Saknar hakparantes: %s"
+
+#, c-format
+msgid "E108: No such variable: \"%s\""
+msgstr "E108: Ingen sådan variabel: \"%s\""
+
+msgid "E743: variable nested too deep for (un)lock"
+msgstr "E743: variabel nästlade för djupt för (un)lock"
+
+msgid "E109: Missing ':' after '?'"
+msgstr "E109: Saknar ':' efter '?'"
+
+msgid "E691: Can only compare List with List"
+msgstr "E691: Kan bara jämföra Lista med Lista"
+
+msgid "E692: Invalid operation for Lists"
+msgstr "E692: Ogiltig operation för Listor"
+
+msgid "E735: Can only compare Dictionary with Dictionary"
+msgstr "E735: Kan bara jämföra Tabell med Tabell"
+
+msgid "E736: Invalid operation for Dictionary"
+msgstr "E736: Ogiltig operation för Tabell"
+
+msgid "E693: Can only compare Funcref with Funcref"
+msgstr "E693: Kan bara jämföra Funcref med Funcref"
+
+msgid "E694: Invalid operation for Funcrefs"
+msgstr "E694: Ogiltig operation för Funcrefs"
+
+msgid "E110: Missing ')'"
+msgstr "E110: Saknar ')'"
+
+msgid "E695: Cannot index a Funcref"
+msgstr "E695: Kan inte indexera en Funcref"
+
+#, c-format
+msgid "E112: Option name missing: %s"
+msgstr "E112: Flaggnamn saknas: %s"
+
+#, c-format
+msgid "E113: Unknown option: %s"
+msgstr "E113: Okänd flagga: %s"
+
+#, c-format
+msgid "E114: Missing quote: %s"
+msgstr "E114: Saknar citattecken: %s"
+
+#, c-format
+msgid "E115: Missing quote: %s"
+msgstr "E115: Saknar citattecken: %s"
+
+#, c-format
+msgid "E696: Missing comma in List: %s"
+msgstr "E696: Saknar komma i Lista: %s"
+
+#, c-format
+msgid "E697: Missing end of List ']': %s"
+msgstr "E697: Saknar slut på Lista ']': %s"
+
+#, c-format
+msgid "E720: Missing colon in Dictionary: %s"
+msgstr "E720: Saknar kolon i Tabell: %s"
+
+#, c-format
+msgid "E721: Duplicate key in Dictionary: \"%s\""
+msgstr "E721: Duplicerad nyckel i Tabell: \"%s\""
+
+#, c-format
+msgid "E722: Missing comma in Dictionary: %s"
+msgstr "E722: Saknar komma i Tabell: %s"
+
+#, c-format
+msgid "E723: Missing end of Dictionary '}': %s"
+msgstr "E723: Saknar slut på Tabell '}': %s"
+
+msgid "E724: variable nested too deep for displaying"
+msgstr "E724: variabel nästlad för djupt för att visas"
+
+#, c-format
+msgid "E117: Unknown function: %s"
+msgstr "E117: Okänd funktion: %s"
+
+#, c-format
+msgid "E119: Not enough arguments for function: %s"
+msgstr "E119: För få argument till funktion: %s"
+
+#, c-format
+msgid "E120: Using <SID> not in a script context: %s"
+msgstr "E120: Använder inte <SID> i ett skriptsammanhang: %s"
+
+#, c-format
+msgid "E725: Calling dict function without Dictionary: %s"
+msgstr "E725: Anropar tabell-funktion utan Tabell: %s"
+
+msgid "E699: Too many arguments"
+msgstr "E699: För många argument"
+
+msgid "E785: complete() can only be used in Insert mode"
+msgstr "E785: complete() kan bara användas i infogningsläge"
+
+#.
+#. * 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"
+
+#, c-format
+msgid "E737: Key already exists: %s"
+msgstr "E737: Tangenten finns redan: %s"
+
+#, c-format
+msgid "+-%s%3ld lines: "
+msgstr "+-%s%3ld rader: "
+
+#, c-format
+msgid "E700: Unknown function: %s"
+msgstr "E700: Okänd funktion: %s"
+
+msgid ""
+"&OK\n"
+"&Cancel"
+msgstr ""
+"&OK\n"
+"&Avbryt"
+
+msgid "called inputrestore() more often than inputsave()"
+msgstr "anropade inputrestore() oftare än inputsave()"
+
+msgid "E786: Range not allowed"
+msgstr "E786: Område otillåtet"
+
+msgid "E701: Invalid type for len()"
+msgstr "E701: Ogiltig typ för len()"
+
+msgid "E726: Stride is zero"
+msgstr "E726: Kliv är noll"
+
+msgid "E727: Start past end"
+msgstr "E727: Start efter slut"
+
+msgid "<empty>"
+msgstr "<tom>"
+
+msgid "E240: No connection to Vim server"
+msgstr "E240: Ingen anslutning till Vim-server"
+
+#, c-format
+msgid "E241: Unable to send to %s"
+msgstr "E241: Kunde inte sända till %s"
+
+msgid "E277: Unable to read a server reply"
+msgstr "E277: Kunde inte läsa ett serversvar"
+
+msgid "E655: Too many symbolic links (cycle?)"
+msgstr "E655: För många symboliska länkar (slinga?)"
+
+msgid "E258: Unable to send to client"
+msgstr "E258: Kunde inte sända till klient"
+
+msgid "E702: Sort compare function failed"
+msgstr "E702: Jämförelsefunktionen för sortering misslyckades"
+
+msgid "(Invalid)"
+msgstr "(Ogiltig)"
+
+msgid "E677: Error writing temp file"
+msgstr "E677: Fel vid skrivning av temporär fil"
+
+msgid "E703: Using a Funcref as a Number"
+msgstr "E703: Använder en Funcref som en siffra"
+
+msgid "E745: Using a List as a Number"
+msgstr "E745: Använder en Lista som en siffra"
+
+msgid "E728: Using a Dictionary as a Number"
+msgstr "E728: Använder en Tabell som en siffra"
+
+msgid "E729: using Funcref as a String"
+msgstr "E729: använder Funcref som en Sträng"
+
+msgid "E730: using List as a String"
+msgstr "E730: använder Lista som en Sträng"
+
+msgid "E731: using Dictionary as a String"
+msgstr "E731: använder Tabell som en Sträng"
+
+#, c-format
+msgid "E704: Funcref variable name must start with a capital: %s"
+msgstr "E704: Variabelnamn för Funcref måste börja med en versal: %s"
+
+#, c-format
+msgid "E705: Variable name conflicts with existing function: %s"
+msgstr "E705: Variabelnamn konflikterar med existerande funktion %s"
+
+#, c-format
+msgid "E706: Variable type mismatch for: %s"
+msgstr "E706: Variabeltyp matchar inte för: %s"
+
+#, c-format
+msgid "E795: Cannot delete variable %s"
+msgstr "E795: Kan inte ta bort variabel %s"
+
+#, c-format
+msgid "E741: Value is locked: %s"
+msgstr "E741: Värde är låst: %s"
+
+msgid "Unknown"
+msgstr "Okänd"
+
+#, c-format
+msgid "E742: Cannot change value of %s"
+msgstr "E742: Kan inte ändra värde av %s"
+
+msgid "E698: variable nested too deep for making a copy"
+msgstr "E698: variabel nästlad för djupt för att skapa en kopia"
+
+#, c-format
+msgid "E124: Missing '(': %s"
+msgstr "E124: Saknar '(': %s"
+
+#, c-format
+msgid "E125: Illegal argument: %s"
+msgstr "E125: Otillåtet argument: %s"
+
+msgid "E126: Missing :endfunction"
+msgstr "E126: Saknar :endfunction"
+
+#, c-format
+msgid "E746: Function name does not match script file name: %s"
+msgstr "E746: Funktionsnamn matchar inte skriptfilnamn: %s"
+
+msgid "E129: Function name required"
+msgstr "E129: Funktionsnamn krävs"
+
+#, c-format
+msgid "E128: Function name must start with a capital or contain a colon: %s"
+msgstr ""
+"E128: Funktionsnamn måste börja med en versal eller innehålla ett kolon: %s"
+
+#, c-format
+msgid "E131: Cannot delete function %s: It is in use"
+msgstr "E131: Kan inte ta bort funktion %s: Den används"
+
+msgid "E132: Function call depth is higher than 'maxfuncdepth'"
+msgstr "E132: Djupet på funktionsanropet är högre än 'maxfuncdepth'"
+
+#, c-format
+msgid "calling %s"
+msgstr "anropar %s"
+
+#, c-format
+msgid "%s aborted"
+msgstr "%s avbröts"
+
+#, c-format
+msgid "%s returning #%ld"
+msgstr "%s returnerar #%ld"
+
+#, c-format
+msgid "%s returning %s"
+msgstr "%s returnerar %s"
+
+#, c-format
+msgid "continuing in %s"
+msgstr "fortsätter i %s"
+
+msgid "E133: :return not inside a function"
+msgstr "E133: :return inte inom en funktion"
+
+#, c-format
+msgid ""
+"\n"
+"# global variables:\n"
+msgstr ""
+"\n"
+"# globala variabler:\n"
+
+msgid ""
+"\n"
+"\tLast set from "
+msgstr ""
+"\n"
+"\tSenast satt från "
+
+msgid "Entering Debug mode. Type \"cont\" to continue."
+msgstr "Går in i felsökningsläge. Skriv \"cont\" för att fortsätta."
+
+#, c-format
+msgid "line %ld: %s"
+msgstr "rad %ld: %s"
+
+#, c-format
+msgid "cmd: %s"
+msgstr "kommando: %s"
+
+#, c-format
+msgid "Breakpoint in \"%s%s\" line %ld"
+msgstr "Brytpunkt i \"%s%s\" rad %ld"
+
+#, c-format
+msgid "E161: Breakpoint not found: %s"
+msgstr "E161: Brytpunkt hittades inte: %s"
+
+msgid "No breakpoints defined"
+msgstr "Inga brytpunkter definierade"
+
+#, c-format
+msgid "%3d %s %s line %ld"
+msgstr "%3d %s %s rad %ld"
+
+msgid "E750: First use :profile start <fname>"
+msgstr "E750: Använd :profile start <fnamn> först"
+
+msgid "Save As"
+msgstr "Spara som"
+
+#, c-format
+msgid "Save changes to \"%s\"?"
+msgstr "Spara ändringar till \"%s\"?"
+
+msgid "Untitled"
+msgstr "Namnlös"
+
+#, c-format
+msgid "E162: No write since last change for buffer \"%s\""
+msgstr "E162: Ingen skrivning sedan senaste ändring för buffert \"%s\""
+
+msgid "Warning: Entered other buffer unexpectedly (check autocommands)"
+msgstr "Varning: Gick in i andra buffertar oväntat (kontrollera autokommandon)"
+
+msgid "E163: There is only one file to edit"
+msgstr "E163: Det finns bara en fil att redigera"
+
+msgid "E164: Cannot go before first file"
+msgstr "E164: Kan inte gå före första filen"
+
+msgid "E165: Cannot go beyond last file"
+msgstr "E165: Kan inte gå bortom sista filen"
+
+#, c-format
+msgid "E666: compiler not supported: %s"
+msgstr "E666: kompilator stöds inte: %s"
+
+#, c-format
+msgid "Searching for \"%s\" in \"%s\""
+msgstr "Söker efter \"%s\" i \"%s\""
+
+#, c-format
+msgid "Searching for \"%s\""
+msgstr "Söker efter \"%s\""
+
+#, c-format
+msgid "not found in 'runtimepath': \"%s\""
+msgstr "hittades inte i 'runtimepath': \"%s\""
+
+msgid "Source Vim script"
+msgstr "Läs Vim-skript"
+
+#, c-format
+msgid "Cannot source a directory: \"%s\""
+msgstr "Kan inte läsa en katalog: \"%s\""
+
+#, c-format
+msgid "could not source \"%s\""
+msgstr "kunde inte läsa \"%s\""
+
+#, c-format
+msgid "line %ld: could not source \"%s\""
+msgstr "rad %ld: kunde inte läsa \"%s\""
+
+#, c-format
+msgid "sourcing \"%s\""
+msgstr "läser \"%s\""
+
+#, c-format
+msgid "line %ld: sourcing \"%s\""
+msgstr "rad %ld: läser \"%s\""
+
+#, c-format
+msgid "finished sourcing %s"
+msgstr "läste klart %s"
+
+msgid "modeline"
+msgstr "lägesrad"
+
+msgid "--cmd argument"
+msgstr "--cmd argument"
+
+msgid "-c argument"
+msgstr "-c argument"
+
+msgid "environment variable"
+msgstr "miljövariabel"
+
+msgid "error handler"
+msgstr "felhanterare"
+
+msgid "W15: Warning: Wrong line separator, ^M may be missing"
+msgstr "W15: Varning: Fel radavskiljare, ^M kan saknas"
+
+msgid "E167: :scriptencoding used outside of a sourced file"
+msgstr "E167: :scriptencoding används utanför en körd fil"
+
+msgid "E168: :finish used outside of a sourced file"
+msgstr "E168: :finish används utanför en körd fil"
+
+#, c-format
+msgid "Current %slanguage: \"%s\""
+msgstr "Aktuellt %sspråk: \"%s\""
+
+#, c-format
+msgid "E197: Cannot set language to \"%s\""
+msgstr "E197: Kan inte sätta språk till \"%s\""
+
+#, c-format
+msgid "<%s>%s%s %d, Hex %02x, Octal %03o"
+msgstr "<%s>%s%s %d, Hex %02x, Oktalt %03o"
+
+#, c-format
+msgid "> %d, Hex %04x, Octal %o"
+msgstr "> %d, Hex %04x, Oktalt %o"
+
+#, c-format
+msgid "> %d, Hex %08x, Octal %o"
+msgstr "> %d, Hex %08x, Oktalt %o"
+
+msgid "E134: Move lines into themselves"
+msgstr "E134: Flytta rader in i dem själva"
+
+msgid "1 line moved"
+msgstr "1 rad flyttad"
+
+#, c-format
+msgid "%ld lines moved"
+msgstr "%ld rader flyttade"
+
+#, c-format
+msgid "%ld lines filtered"
+msgstr "%ld rader filtrerade"
+
+msgid "E135: *Filter* Autocommands must not change current buffer"
+msgstr "E135: *Filter*-Autokommandon får inte ändra aktuell buffert"
+
+msgid "[No write since last change]\n"
+msgstr "[Ingen skrivning sedan senaste ändring]\n"
+
+#, c-format
+msgid "%sviminfo: %s in line: "
+msgstr "%sviminfo: %s på rad: "
+
+msgid "E136: viminfo: Too many errors, skipping rest of file"
+msgstr "E136: viminfo: För många fel, hoppar över resten av filen"
+
+#, c-format
+msgid "Reading viminfo file \"%s\"%s%s%s"
+msgstr "Läser viminfo-fil \"%s\"%s%s%s"
+
+msgid " info"
+msgstr " info"
+
+msgid " marks"
+msgstr " märken"
+
+msgid " FAILED"
+msgstr " MISSLYCKADES"
+
+#. avoid a wait_return for this message, it's annoying
+#, c-format
+msgid "E137: Viminfo file is not writable: %s"
+msgstr "E137: Viminfo-fil är inte skrivbar: %s"
+
+#, c-format
+msgid "E138: Can't write viminfo file %s!"
+msgstr "E138: Kan inte skriva viminfo-fil %s!"
+
+#, c-format
+msgid "Writing viminfo file \"%s\""
+msgstr "Skriver viminfo-fil \"%s\""
+
+#. Write the info:
+#, c-format
+msgid "# This viminfo file was generated by Vim %s.\n"
+msgstr "# Den här viminfo-filen genererades av Vim %s.\n"
+
+#, c-format
+msgid ""
+"# You may edit it if you're careful!\n"
+"\n"
+msgstr ""
+"# Du får redigera den om du är försiktig!\n"
+"\n"
+
+#, c-format
+msgid "# Value of 'encoding' when this file was written\n"
+msgstr "# Värde av 'encoding' när den här filen blev skriven\n"
+
+msgid "Illegal starting char"
+msgstr "Otillåtet starttecken"
+
+msgid "Write partial file?"
+msgstr "Skriv ofullständig fil?"
+
+msgid "E140: Use ! to write partial buffer"
+msgstr "E140: Använd ! för att skriva ofullständig buffert"
+
+#, c-format
+msgid "Overwrite existing file \"%s\"?"
+msgstr "Skriv över befintlig fil \"%s\"?"
+
+#, c-format
+msgid "Swap file \"%s\" exists, overwrite anyway?"
+msgstr "Växlingsfil \"%s\" existerar, skriv över ändå?"
+
+#, c-format
+msgid "E768: Swap file exists: %s (:silent! overrides)"
+msgstr "E768: Växlingsfil existerar: %s (:silent! tvingar)"
+
+#, c-format
+msgid "E141: No file name for buffer %ld"
+msgstr "E141: Inget filnamn för buffert %ld"
+
+msgid "E142: File not written: Writing is disabled by 'write' option"
+msgstr "E142: Filen skrevs inte: Skrivning är inaktiverat med 'write'-flaggan"
+
+#, c-format
+msgid ""
+"'readonly' option is set for \"%s\".\n"
+"Do you wish to write anyway?"
+msgstr ""
+"'readonly' flaggan är satt för \"%s\".\n"
+"Önskar du att skriva ändå?"
+
+msgid "Edit File"
+msgstr "Redigera fil"
+
+#, c-format
+msgid "E143: Autocommands unexpectedly deleted new buffer %s"
+msgstr "E143: Autokommandon tog oväntat bort ny buffert %s"
+
+msgid "E144: non-numeric argument to :z"
+msgstr "E144: ickenumeriskt argument till :z"
+
+msgid "E145: Shell commands not allowed in rvim"
+msgstr "E145: Skalkommandon inte tillåtna i rvim"
+
+msgid "E146: Regular expressions can't be delimited by letters"
+msgstr "E146: Reguljära uttryck kan inte vara åtskilda av bokstäver"
+
+#, c-format
+msgid "replace with %s (y/n/a/q/l/^E/^Y)?"
+msgstr "ersätt med %s (y/n/a/q/l/^E/^Y)?"
+
+msgid "(Interrupted) "
+msgstr "(Avbruten) "
+
+msgid "1 match"
+msgstr "1 träff"
+
+msgid "1 substitution"
+msgstr "1 ersättning"
+
+#, c-format
+msgid "%ld matches"
+msgstr "%ld träffar"
+
+#, c-format
+msgid "%ld substitutions"
+msgstr "%ld ersättningar"
+
+msgid " on 1 line"
+msgstr " på 1 rad"
+
+#, c-format
+msgid " on %ld lines"
+msgstr " på %ld rader"
+
+msgid "E147: Cannot do :global recursive"
+msgstr "E147: Kan inte göra :global rekursivt"
+
+msgid "E148: Regular expression missing from global"
+msgstr "E148: Reguljärt uttryck saknas från global"
+
+#, c-format
+msgid "Pattern found in every line: %s"
+msgstr "Mönster funnet i varje rad: %s"
+
+#, c-format
+msgid ""
+"\n"
+"# Last Substitute String:\n"
+"$"
+msgstr ""
+"\n"
+"# Senaste ersättningssträng:\n"
+"$"
+
+msgid "E478: Don't panic!"
+msgstr "E478: Få inte panik!"
+
+#, c-format
+msgid "E661: Sorry, no '%s' help for %s"
+msgstr "E661: Tyvärr, ingen \"%s\"-hjälp för %s"
+
+#, c-format
+msgid "E149: Sorry, no help for %s"
+msgstr "E149: Tyvärr, ingen hjälp för %s"
+
+#, c-format
+msgid "Sorry, help file \"%s\" not found"
+msgstr "Tyvärr, hjälpfil \"%s\" hittades inte"
+
+#, c-format
+msgid "E150: Not a directory: %s"
+msgstr "E150: Inte en katalog: %s"
+
+#, c-format
+msgid "E152: Cannot open %s for writing"
+msgstr "E152: Kan inte öppna %s för skrivning"
+
+#, c-format
+msgid "E153: Unable to open %s for reading"
+msgstr "E153: Kunde inte öppna %s för läsning"
+
+#, c-format
+msgid "E670: Mix of help file encodings within a language: %s"
+msgstr "E670: Blandning av hjälpfilskodning inom ett språk: %s"
+
+#, c-format
+msgid "E154: Duplicate tag \"%s\" in file %s/%s"
+msgstr "E154: Duplicerad tagg \"%s\" i fil %s/%s"
+
+#, c-format
+msgid "E160: Unknown sign command: %s"
+msgstr "E160: Okänt signaturkommando: %s"
+
+msgid "E156: Missing sign name"
+msgstr "E156: Saknar signaturnamn"
+
+msgid "E612: Too many signs defined"
+msgstr "E612: För många signaturer definierade"
+
+#, c-format
+msgid "E239: Invalid sign text: %s"
+msgstr "E239: Ogiltig signaturtext: %s"
+
+#, c-format
+msgid "E155: Unknown sign: %s"
+msgstr "E155: Okänd signatur: %s"
+
+msgid "E159: Missing sign number"
+msgstr "E159: Saknar signaturnummer"
+
+#, c-format
+msgid "E158: Invalid buffer name: %s"
+msgstr "E158: Ogiltigt buffertnamn: %s"
+
+#, c-format
+msgid "E157: Invalid sign ID: %ld"
+msgstr "E157: Ogiltigt signatur-ID: %ld"
+
+msgid " (NOT FOUND)"
+msgstr " (INTE HITTADE)"
+
+msgid " (not supported)"
+msgstr " (stöds inte)"
+
+msgid "[Deleted]"
+msgstr "[Borttagen]"
+
+msgid "Entering Ex mode. Type \"visual\" to go to Normal mode."
+msgstr "Går in i Ex-läge. Skriv \"visual\" för att gå till Normal-läge."
+
+msgid "E501: At end-of-file"
+msgstr "E501: Vid filslut"
+
+msgid "E169: Command too recursive"
+msgstr "E169: Kommando för rekursivt"
+
+#, c-format
+msgid "E605: Exception not caught: %s"
+msgstr "E605: Undantag inte fångat: %s"
+
+msgid "End of sourced file"
+msgstr "Slut på läst fil"
+
+msgid "End of function"
+msgstr "Slut på funktion"
+
+msgid "E464: Ambiguous use of user-defined command"
+msgstr "E464: Otydlig användning av användardefinierat kommando"
+
+msgid "E492: Not an editor command"
+msgstr "E492: Inte ett redigerarkommando"
+
+msgid "E493: Backwards range given"
+msgstr "E493: Bakåtområde givet"
+
+msgid "Backwards range given, OK to swap"
+msgstr "Bakåtområde givet, OK att växla"
+
+msgid "E494: Use w or w>>"
+msgstr "E494: Använd w eller w>>"
+
+msgid "E319: Sorry, the command is not available in this version"
+msgstr "E319: Tyvärr, kommandot är inte tillgängligt i den här versionen"
+
+msgid "E172: Only one file name allowed"
+msgstr "E172: Bara ett filnamn tillåtet"
+
+msgid "1 more file to edit. Quit anyway?"
+msgstr "1 fil till att redigera. Avsluta ändå?"
+
+#, c-format
+msgid "%d more files to edit. Quit anyway?"
+msgstr "%d filer till att redigera. Avsluta ändå?"
+
+msgid "E173: 1 more file to edit"
+msgstr "E173: 1 fil till att redigera"
+
+#, c-format
+msgid "E173: %ld more files to edit"
+msgstr "E173: %ld filer till att redigera"
+
+msgid "E174: Command already exists: add ! to replace it"
+msgstr "E174: Kommando existerar redan: lägg till ! för att ersätta det"
+
+msgid ""
+"\n"
+" Name Args Range Complete Definition"
+msgstr ""
+"\n"
+" Namn Arg Område Färdigt Definition"
+
+msgid "No user-defined commands found"
+msgstr "Inga användardefinierade kommandon hittade"
+
+msgid "E175: No attribute specified"
+msgstr "E175: Inga attribut angivna"
+
+msgid "E176: Invalid number of arguments"
+msgstr "E176: Ogiltigt antal argument"
+
+msgid "E177: Count cannot be specified twice"
+msgstr "E177: Antal kan inte anges två gånger"
+
+msgid "E178: Invalid default value for count"
+msgstr "E178: Ogiltigt standardvärde för antal"
+
+msgid "E179: argument required for -complete"
+msgstr "E179: argument krävs för -complete"
+
+#, c-format
+msgid "E181: Invalid attribute: %s"
+msgstr "E181: Ogiltigt attribut: %s"
+
+msgid "E182: Invalid command name"
+msgstr "E182: Ogiltigt kommandonamn"
+
+msgid "E183: User defined commands must start with an uppercase letter"
+msgstr "E183: Användardefinierade kommandon måste börja med en stor bokstav"
+
+#, c-format
+msgid "E184: No such user-defined command: %s"
+msgstr "E184: Inget sådant användardefinierat kommando: %s"
+
+#, c-format
+msgid "E180: Invalid complete value: %s"
+msgstr "E180: Ogiltigt kompletteringsvärde: %s"
+
+msgid "E468: Completion argument only allowed for custom completion"
+msgstr "E468: Kompletteringsargument bara tillåtet för specialkomplettering"
+
+msgid "E467: Custom completion requires a function argument"
+msgstr "E467: Specialkomplettering kräver ett funktionsargument"
+
+#, c-format
+msgid "E185: Cannot find color scheme %s"
+msgstr "E185: Kan inte hitta färgschema %s"
+
+msgid "Greetings, Vim user!"
+msgstr "Välkommen, Vim-användare!"
+
+msgid "E784: Cannot close last tab page"
+msgstr "E784: Kan inte stänga senaste flik"
+
+msgid "Already only one tab page"
+msgstr "Redan bara en flik"
+
+msgid "Edit File in new window"
+msgstr "Redigera fil i nytt fönster"
+
+#, c-format
+msgid "Tab page %d"
+msgstr "Flik %d"
+
+msgid "No swap file"
+msgstr "Ingen växlingsfil"
+
+msgid "Append File"
+msgstr "Lägg till fil"
+
+msgid "E747: Cannot change directory, buffer is modified (add ! to override)"
+msgstr ""
+"E747: Kan inte ändra katalog, buffert är ändrad (lägg till ! för att tvinga)"
+
+msgid "E186: No previous directory"
+msgstr "E186: Ingen tidigare katalog"
+
+msgid "E187: Unknown"
+msgstr "E187: Okänt"
+
+msgid "E465: :winsize requires two number arguments"
+msgstr "E465: :winsize kräver två sifferargument"
+
+#, c-format
+msgid "Window position: X %d, Y %d"
+msgstr "Fönsterposition: X %d, Y %d"
+
+msgid "E188: Obtaining window position not implemented for this platform"
+msgstr ""
+"E188: Förskaffa fönsterposition inte implementerat för den här plattformen"
+
+msgid "E466: :winpos requires two number arguments"
+msgstr "E466: :winpos kräver två sifferargument"
+
+msgid "Save Redirection"
+msgstr "Spara omdirigering"
+
+msgid "Save View"
+msgstr "Spara vy"
+
+msgid "Save Session"
+msgstr "Spara session"
+
+msgid "Save Setup"
+msgstr "Spara konfiguration"
+
+#, c-format
+msgid "E739: Cannot create directory: %s"
+msgstr "E739: Kan inte skapa katalog: %s"
+
+#, c-format
+msgid "E189: \"%s\" exists (add ! to override)"
+msgstr "E189: \"%s\" existerar (lägg till ! för att tvinga)"
+
+#, c-format
+msgid "E190: Cannot open \"%s\" for writing"
+msgstr "E190: Kan inte öppna \"%s\" för skrivning"
+
+#. set mark
+msgid "E191: Argument must be a letter or forward/backward quote"
+msgstr ""
+"E191: Argument måste vara en bokstav eller framåt-/bakåtvänt citattecken"
+
+msgid "E192: Recursive use of :normal too deep"
+msgstr "E192: Rekursiv användning av :normal för djup"
+
+msgid "E194: No alternate file name to substitute for '#'"
+msgstr "E194: Inget alternativt filnamn att byta ut '#' med"
+
+msgid "E495: no autocommand file name to substitute for \"<afile>\""
+msgstr "E495: inget autokommando-filnamn att ersätta \"<afile>\" med"
+
+msgid "E496: no autocommand buffer number to substitute for \"<abuf>\""
+msgstr "E496: inget autokommando-buffernummer att ersätta \"<abuf>\" med"
+
+msgid "E497: no autocommand match name to substitute for \"<amatch>\""
+msgstr "E497: inget autokommando-träffnamn att byta ut \"<amatch>\" med"
+
+msgid "E498: no :source file name to substitute for \"<sfile>\""
+msgstr "E498: inget :source-filnamn att byta ut \"<sfile>\" med"
+
+#, no-c-format
+msgid "E499: Empty file name for '%' or '#', only works with \":p:h\""
+msgstr "E499: Tomt filnamn för '%' or '#', fungerar bara med \":p:h\""
+
+msgid "E500: Evaluates to an empty string"
+msgstr "E500: Evaluerar till en tom sträng"
+
+msgid "E195: Cannot open viminfo file for reading"
+msgstr "E195: Kan inte öppna viminfo-fil för läsning"
+
+msgid "E196: No digraphs in this version"
+msgstr "E196: Inga digrafer i den här versionen"
+
+msgid "E608: Cannot :throw exceptions with 'Vim' prefix"
+msgstr "E608: Kan inte :throw undantag med 'Vim'-prefix"
+
+#. always scroll up, don't overwrite
+#, c-format
+msgid "Exception thrown: %s"
+msgstr "Undantag kastade: %s"
+
+#, c-format
+msgid "Exception finished: %s"
+msgstr "Undantag färdiga: %s"
+
+#, c-format
+msgid "Exception discarded: %s"
+msgstr "Undantag förkastade: %s"
+
+#, c-format
+msgid "%s, line %ld"
+msgstr "%s, rad %ld"
+
+#. always scroll up, don't overwrite
+#, c-format
+msgid "Exception caught: %s"
+msgstr "Undantag fångade: %s"
+
+#, c-format
+msgid "%s made pending"
+msgstr "%s gjordes avvaktande"
+
+#, c-format
+msgid "%s resumed"
+msgstr "%s återupptagen"
+
+#, c-format
+msgid "%s discarded"
+msgstr "%s förkastad"
+
+msgid "Exception"
+msgstr "Undantag"
+
+msgid "Error and interrupt"
+msgstr "Fel och avbrytet"
+
+msgid "Error"
+msgstr "Fel"
+
+#. if (pending & CSTP_INTERRUPT)
+msgid "Interrupt"
+msgstr "Avbryt"
+
+msgid "E579: :if nesting too deep"
+msgstr "E579: :if nästlad för djupt"
+
+msgid "E580: :endif without :if"
+msgstr "E580: :endif utan :if"
+
+msgid "E581: :else without :if"
+msgstr "E581: :else utan :if"
+
+msgid "E582: :elseif without :if"
+msgstr "E582: :elseif utan :if"
+
+msgid "E583: multiple :else"
+msgstr "E583: flera :else"
+
+msgid "E584: :elseif after :else"
+msgstr "E584: :elseif efter :else"
+
+msgid "E585: :while/:for nesting too deep"
+msgstr "E585: :while/:for nästlad för djupt"
+
+msgid "E586: :continue without :while or :for"
+msgstr "E586: :continue utan :while eller :for"
+
+msgid "E587: :break without :while or :for"
+msgstr "E587: :break utan :while eller :for"
+
+msgid "E732: Using :endfor with :while"
+msgstr "E732: Använder :endfor med :while"
+
+msgid "E733: Using :endwhile with :for"
+msgstr "E733: Använder :endwhile med :for"
+
+msgid "E601: :try nesting too deep"
+msgstr "E601: :try nästlad för djupt"
+
+msgid "E603: :catch without :try"
+msgstr "E603: :catch utan :try"
+
+#. Give up for a ":catch" after ":finally" and ignore it.
+#. * Just parse.
+msgid "E604: :catch after :finally"
+msgstr "E604: :catch efter :finally"
+
+msgid "E606: :finally without :try"
+msgstr "E606: :finally utan :try"
+
+#. Give up for a multiple ":finally" and ignore it.
+msgid "E607: multiple :finally"
+msgstr "E607: flera :finally"
+
+msgid "E602: :endtry without :try"
+msgstr "E602: :endtry utan :try"
+
+msgid "E193: :endfunction not inside a function"
+msgstr "E193: :endfunction inte inom en funktion"
+
+msgid "E788: Not allowed to edit another buffer now"
+msgstr "E788: Inte tillåtet att redigera en annan buffert nu"
+
+msgid "tagname"
+msgstr "taggnamn"
+
+msgid " kind file\n"
+msgstr " snäll fil\n"
+
+msgid "'history' option is zero"
+msgstr "'history'-flagga är noll"
+
+#, c-format
+msgid ""
+"\n"
+"# %s History (newest to oldest):\n"
+msgstr ""
+"\n"
+"# %s Historia (nyaste till äldsta):\n"
+
+msgid "Command Line"
+msgstr "Kommandorad"
+
+msgid "Search String"
+msgstr "Söksträng"
+
+msgid "Expression"
+msgstr "Uttryck"
+
+msgid "Input Line"
+msgstr "Inmatningsrad"
+
+msgid "E198: cmd_pchar beyond the command length"
+msgstr "E198: cmd_pchar bortom kommandolängden"
+
+msgid "E199: Active window or buffer deleted"
+msgstr "E199: Aktivt fönster eller buffert borttagen"
+
+msgid "Illegal file name"
+msgstr "Otillåtet filnamn"
+
+msgid "is a directory"
+msgstr "är en katalog"
+
+msgid "is not a file"
+msgstr "är inte en fil"
+
+msgid "is a device (disabled with 'opendevice' option)"
+msgstr "är en enhet (inaktiverad med 'opendevice'-flagga)"
+
+msgid "[New File]"
+msgstr "[Ny fil]"
+
+msgid "[New DIRECTORY]"
+msgstr "[Ny KATALOG]"
+
+msgid "[File too big]"
+msgstr "[Fil för stor]"
+
+msgid "[Permission Denied]"
+msgstr "[Tillåtelse nekas]"
+
+msgid "E200: *ReadPre autocommands made the file unreadable"
+msgstr "E200: *ReadPre autokommandon gjorde filen oläsbar"
+
+msgid "E201: *ReadPre autocommands must not change current buffer"
+msgstr "E201: *ReadPre autokommandon får inte ändra nuvarande buffert"
+
+msgid "Vim: Reading from stdin...\n"
+msgstr "Vim: Läser från standard in...\n"
+
+msgid "Reading from stdin..."
+msgstr "Läser från standard in..."
+
+#. Re-opening the original file failed!
+msgid "E202: Conversion made file unreadable!"
+msgstr "E202: Konvertering gjorde filen oläsbar!"
+
+msgid "[fifo/socket]"
+msgstr "[fifo/uttag]"
+
+msgid "[fifo]"
+msgstr "[fifo]"
+
+msgid "[socket]"
+msgstr "[uttag]"
+
+msgid "[RO]"
+msgstr "[EL]"
+
+msgid "[CR missing]"
+msgstr "[CR saknas]"
+
+msgid "[NL found]"
+msgstr "[NL hittat]"
+
+msgid "[long lines split]"
+msgstr "[långa rader delade]"
+
+msgid "[NOT converted]"
+msgstr "[INTE konverterad]"
+
+msgid "[converted]"
+msgstr "[konverterad]"
+
+msgid "[crypted]"
+msgstr "[krypterad]"
+
+#, c-format
+msgid "[CONVERSION ERROR in line %ld]"
+msgstr "[KONVERTERINGSFEL på rad %ld]"
+
+#, c-format
+msgid "[ILLEGAL BYTE in line %ld]"
+msgstr "[OTILLÅTEN BIT på rad %ld]"
+
+msgid "[READ ERRORS]"
+msgstr "[LÄSFEL]"
+
+msgid "Can't find temp file for conversion"
+msgstr "Kan inte hitta temporär fil för konvertering"
+
+msgid "Conversion with 'charconvert' failed"
+msgstr "Konvertering med 'charconvert' misslyckades"
+
+msgid "can't read output of 'charconvert'"
+msgstr "kan inte läsa utdata av 'charconvert'"
+
+msgid "E676: No matching autocommands for acwrite buffer"
+msgstr "E676: Inga matchande autokommandon för acwrite buffert"
+
+msgid "E203: Autocommands deleted or unloaded buffer to be written"
+msgstr ""
+"E203: Autokommandon tog bort eller laddade ur buffert som skulle skrivas"
+
+msgid "E204: Autocommand changed number of lines in unexpected way"
+msgstr "E204: Autokommado ändrade antal rader på ett oväntat sätt"
+
+msgid "NetBeans disallows writes of unmodified buffers"
+msgstr "NetBeans tillåter inte skrivning av omodifierade buffertar"
+
+msgid "Partial writes disallowed for NetBeans buffers"
+msgstr "Delvisa skrivningar tillåts inte i NetBeans-buffertar"
+
+msgid "is not a file or writable device"
+msgstr "är inte en fil eller skrivbar enhet"
+
+msgid "writing to device disabled with 'opendevice' option"
+msgstr "skriver till en enhet inaktiverad med 'opendevice'-flagga"
+
+msgid "is read-only (add ! to override)"
+msgstr "är skrivskyddad (lägg till ! för att tvinga)"
+
+msgid "E506: Can't write to backup file (add ! to override)"
+msgstr "E506: Kan inte skriva till säkerhetskopia (lägg till ! för att tvinga)"
+
+msgid "E507: Close error for backup file (add ! to override)"
+msgstr "E507: Stängningsfel för säkerhetskopia (lägg till ! för att tvinga)"
+
+msgid "E508: Can't read file for backup (add ! to override)"
+msgstr ""
+"E508: Kan inte läsa fil för säkerhetskopia (lägg till ! för att tvinga)"
+
+msgid "E509: Cannot create backup file (add ! to override)"
+msgstr "E509: Kan inte skapa säkerhetskopia (lägg till ! för att tvinga)"
+
+msgid "E510: Can't make backup file (add ! to override)"
+msgstr "E510: Kan inte göra säkerhetskopia (lägg till ! för att tvinga)"
+
+msgid "E460: The resource fork would be lost (add ! to override)"
+msgstr "E460: Resursgrenen skulle tappas bort (lägg till ! för att tvinga)"
+
+msgid "E214: Can't find temp file for writing"
+msgstr "E214: Kan inte hitta temporär fil för skrivning"
+
+msgid "E213: Cannot convert (add ! to write without conversion)"
+msgstr ""
+"E213: Kan inte konvertera (lägg till ! för att skriva utan konvertering)"
+
+msgid "E166: Can't open linked file for writing"
+msgstr "E166: Kan inte öppna länkad fil för skrivning"
+
+msgid "E212: Can't open file for writing"
+msgstr "E212: Kan inte öppna fil för skrivning"
+
+msgid "E667: Fsync failed"
+msgstr "E667: Fsync misslyckades"
+
+msgid "E512: Close failed"
+msgstr "E512: Stängning misslyckades"
+
+msgid "E513: write error, conversion failed (make 'fenc' empty to override)"
+msgstr ""
+"E513: skrivfel, konvertering misslyckades (gör 'fenc' tom för att tvinga)"
+
+msgid "E514: write error (file system full?)"
+msgstr "E514: skrivfel (filsystem fullt?)"
+
+msgid " CONVERSION ERROR"
+msgstr " KONVERTERINGSFEL"
+
+msgid "[Device]"
+msgstr "[Enhet]"
+
+msgid "[New]"
+msgstr "[Ny]"
+
+msgid " [a]"
+msgstr " [l]"
+
+msgid " appended"
+msgstr " lade till"
+
+msgid " [w]"
+msgstr " [s]"
+
+msgid " written"
+msgstr " skriven"
+
+msgid "E205: Patchmode: can't save original file"
+msgstr "E205: Patchläge: kan inte spara orginalfil"
+
+msgid "E206: patchmode: can't touch empty original file"
+msgstr "E206: patchläge: kan inte skapa tom orginalfil"
+
+msgid "E207: Can't delete backup file"
+msgstr "E207: Kan inte ta bort säkerhetskopia"
+
+msgid ""
+"\n"
+"WARNING: Original file may be lost or damaged\n"
+msgstr ""
+"\n"
+"VARNING: Orginalfilen kan vara förlorad eller skadad\n"
+
+msgid "don't quit the editor until the file is successfully written!"
+msgstr "avsluta inte redigeraren innan filen är framgångsrikt skriven"
+
+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 rad, "
+
+#, c-format
+msgid "%ld lines, "
+msgstr "%ld rader, "
+
+msgid "1 character"
+msgstr "1 tecken"
+
+#, c-format
+msgid "%ld characters"
+msgstr "%ld tecken"
+
+msgid "[noeol]"
+msgstr "[inget radslut]"
+
+msgid "[Incomplete last line]"
+msgstr "[Ofullständig sistarad]"
+
+#. 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 "VARNING: Filen har ändrats sedan den lästes in!!!"
+
+msgid "Do you really want to write to it"
+msgstr "Vill du verkligen skriva till den"
+
+#, c-format
+msgid "E208: Error writing to \"%s\""
+msgstr "E208: Fel vid skrivning till \"%s\""
+
+#, c-format
+msgid "E209: Error closing \"%s\""
+msgstr "E209: Fel vid stängning av \"%s\""
+
+#, c-format
+msgid "E210: Error reading \"%s\""
+msgstr "E210: Fel vid läsning av \"%s\""
+
+msgid "E246: FileChangedShell autocommand deleted buffer"
+msgstr "E246: FileChangedShell-autokommandot tog bort buffert"
+
+#, c-format
+msgid "E211: File \"%s\" no longer available"
+msgstr "E211: Filen \"%s\" är inte längre tillgänglig"
+
+#, c-format
+msgid ""
+"W12: Warning: File \"%s\" has changed and the buffer was changed in Vim as "
+"well"
+msgstr ""
+"W12: Varning: Filen \"%s\" har ändrats och bufferten ändrades i Vim också"
+
+msgid "See \":help W12\" for more info."
+msgstr "Se \":help W12\" för mer info."
+
+#, c-format
+msgid "W11: Warning: File \"%s\" has changed since editing started"
+msgstr "W11: Varning: Filen \"%s\" har ändrats sedan redigeringen började"
+
+msgid "See \":help W11\" for more info."
+msgstr "Se \":help W11\" för mer info."
+
+#, c-format
+msgid "W16: Warning: Mode of file \"%s\" has changed since editing started"
+msgstr ""
+"W16: Varning: Rättigheterna på filen \"%s\" har ändrats sedan redigeringen "
+"började"
+
+msgid "See \":help W16\" for more info."
+msgstr "Se \":help W16\" för mer info."
+
+#, c-format
+msgid "W13: Warning: File \"%s\" has been created after editing started"
+msgstr "W13: Varning: Filen \"%s\" har skapats efter redigeringen började"
+
+msgid "Warning"
+msgstr "Varning"
+
+msgid ""
+"&OK\n"
+"&Load File"
+msgstr ""
+"&OK\n"
+"&Läs in filen"
+
+#, c-format
+msgid "E462: Could not prepare for reloading \"%s\""
+msgstr "E462: Kunde inte förbereda för att läsa om \"%s\""
+
+#, c-format
+msgid "E321: Could not reload \"%s\""
+msgstr "E321: Kunde inte läsa om \"%s\""
+
+msgid "--Deleted--"
+msgstr "--Borttagen--"
+
+#, c-format
+msgid "auto-removing autocommand: %s <buffer=%d>"
+msgstr "tar bort autokommando automatiskt: %s <buffert=%d>"
+
+#. the group doesn't exist
+#, c-format
+msgid "E367: No such group: \"%s\""
+msgstr "E367: Ingen sådan grupp: \"%s\""
+
+#, c-format
+msgid "E215: Illegal character after *: %s"
+msgstr "E215: Otillåtet tecken 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 grupp eller händelse: %s"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Auto-Commands ---"
+msgstr ""
+"\n"
+"--- Autokommandon ---"
+
+#, c-format
+msgid "E680: <buffer=%d>: invalid buffer number "
+msgstr "E680: <buffert=%d>: ogiltigt buffertnummer "
+
+msgid "E217: Can't execute autocommands for ALL events"
+msgstr "E217: Kan inte köra autokommandon för ALLA händelser"
+
+msgid "No matching autocommands"
+msgstr "Inga matchande autokommandon"
+
+msgid "E218: autocommand nesting too deep"
+msgstr "E218: autokommando nästlad för djupt"
+
+#, c-format
+msgid "%s Auto commands for \"%s\""
+msgstr "%s Autokommandon för \"%s\""
+
+#, c-format
+msgid "Executing %s"
+msgstr "Kör %s"
+
+#, c-format
+msgid "autocommand %s"
+msgstr "autokommando %s"
+
+msgid "E219: Missing {."
+msgstr "E219: Saknar {."
+
+msgid "E220: Missing }."
+msgstr "E220: Saknar }."
+
+msgid "E490: No fold found"
+msgstr "E490: Inget veck funnet"
+
+msgid "E350: Cannot create fold with current 'foldmethod'"
+msgstr "E350: Kan inte skapa veck med nuvarande 'foldmethod'"
+
+msgid "E351: Cannot delete fold with current 'foldmethod'"
+msgstr "E351: Kan inte ta bort veck med nuvarande 'foldmethod'"
+
+#, c-format
+msgid "+--%3ld lines folded "
+msgstr "+--%3ld rader vikta "
+
+msgid "E222: Add to read buffer"
+msgstr "E222: Lägg till i läsbuffert"
+
+msgid "E223: recursive mapping"
+msgstr "E223: rekursiv mappning"
+
+#, c-format
+msgid "E224: global abbreviation already exists for %s"
+msgstr "E224: global förkortning existerar redan för %s"
+
+#, c-format
+msgid "E225: global mapping already exists for %s"
+msgstr "E225: global mappning existerar redan för %s"
+
+#, c-format
+msgid "E226: abbreviation already exists for %s"
+msgstr "E226: förkortning existerar redan för %s"
+
+#, c-format
+msgid "E227: mapping already exists for %s"
+msgstr "E227: mappning existerar redan för %s"
+
+msgid "No abbreviation found"
+msgstr "Ingen förkortning hittades"
+
+msgid "No mapping found"
+msgstr "Ingen mappning hittades"
+
+msgid "E228: makemap: Illegal mode"
+msgstr "E228: makemap: Otillåtet läge"
+
+msgid "<cannot open> "
+msgstr "<kan inte öppna> "
+
+#, c-format
+msgid "E616: vim_SelFile: can't get font %s"
+msgstr "E616: vim_SelFile: kan inte hämta typsnitt %s"
+
+msgid "E614: vim_SelFile: can't return to current directory"
+msgstr "E614: vim_SelFile: Kan inte återvända till aktuell katalog"
+
+msgid "Pathname:"
+msgstr "Sökväg:"
+
+msgid "E615: vim_SelFile: can't get current directory"
+msgstr "E615: vim_SelFile: kan inte hämta aktuell katalog"
+
+msgid "OK"
+msgstr "OK"
+
+msgid "Cancel"
+msgstr "Avbryt"
+
+msgid "Vim dialog"
+msgstr "Vim-dialog"
+
+msgid "Scrollbar Widget: Could not get geometry of thumb pixmap."
+msgstr "Rullningslist: Kunde inte hämta geometrin på miniatyrbild."
+
+msgid "E232: Cannot create BalloonEval with both message and callback"
+msgstr "E232: Kan inte skapa BalloonEval med både meddelande och återkallning"
+
+msgid "E229: Cannot start the GUI"
+msgstr "E229: Kan inte starta GUI"
+
+#, c-format
+msgid "E230: Cannot read from \"%s\""
+msgstr "E230: Kan inte läsa från \"%s\""
+
+msgid "E665: Cannot start GUI, no valid font found"
+msgstr "E665: Kan inte starta GUI, ingen giltig font hittad"
+
+msgid "E231: 'guifontwide' invalid"
+msgstr "E231: 'guifontwide' ogiltig"
+
+msgid "E599: Value of 'imactivatekey' is invalid"
+msgstr "E599: Värdet av 'imactivatekey' är ogiltigt"
+
+#, c-format
+msgid "E254: Cannot allocate color %s"
+msgstr "E254: Kan inte allokera färg %s"
+
+msgid "No match at cursor, finding next"
+msgstr "Ingen matchning vid markör, söker nästa"
+
+msgid "Vim dialog..."
+msgstr "Vim-dialog..."
+
+msgid ""
+"&Yes\n"
+"&No\n"
+"&Cancel"
+msgstr ""
+"&Ja\n"
+"&Nej\n"
+"&Avbryt"
+
+msgid "Input _Methods"
+msgstr "Inmatnings_metoder"
+
+msgid "VIM - Search and Replace..."
+msgstr "VIM - Sök och ersätt..."
+
+msgid "VIM - Search..."
+msgstr "VIM - Sök..."
+
+msgid "Find what:"
+msgstr "Hitta vad:"
+
+msgid "Replace with:"
+msgstr "Ersätt med:"
+
+#. whole word only button
+msgid "Match whole word only"
+msgstr "Matcha endast hela ord"
+
+#. match case button
+msgid "Match case"
+msgstr "Skilj på stora/små bokstäver"
+
+msgid "Direction"
+msgstr "Riktning"
+
+#. 'Up' and 'Down' buttons
+msgid "Up"
+msgstr "Upp"
+
+msgid "Down"
+msgstr "Ned"
+
+msgid "Find Next"
+msgstr "Hitta nästa"
+
+msgid "Replace"
+msgstr "Ersätt"
+
+msgid "Replace All"
+msgstr "Ersätt alla"
+
+msgid "Vim: Received \"die\" request from session manager\n"
+msgstr "Vim: Tog emot \"die\"-begäran från sessionshanteraren\n"
+
+msgid "Close"
+msgstr "Stäng"
+
+msgid "New tab"
+msgstr "Ny flik"
+
+msgid "Open Tab..."
+msgstr "Öppna flik..."
+
+msgid "Vim: Main window unexpectedly destroyed\n"
+msgstr "Vim: Huvudfönster oväntat förstört\n"
+
+msgid "Font Selection"
+msgstr "Typsnittsval"
+
+msgid "Used CUT_BUFFER0 instead of empty selection"
+msgstr "Använd CUT_BUFFER0 istället för tomt val"
+
+msgid "&Filter"
+msgstr "&Filter"
+
+msgid "&Cancel"
+msgstr "&Avbryt"
+
+msgid "Directories"
+msgstr "Kataloger"
+
+msgid "Filter"
+msgstr "Filter"
+
+msgid "&Help"
+msgstr "&Hjälp"
+
+msgid "Files"
+msgstr "Filer"
+
+msgid "&OK"
+msgstr "&OK"
+
+msgid "Selection"
+msgstr "Val"
+
+msgid "Find &Next"
+msgstr "Hitta &nästa"
+
+msgid "&Replace"
+msgstr "&Ersätt"
+
+msgid "Replace &All"
+msgstr "Ersätt &alla"
+
+msgid "&Undo"
+msgstr "&Ångra"
+
+#, c-format
+msgid "E671: Cannot find window title \"%s\""
+msgstr "E671: Kan inte hitta fönstertitel \"%s\""
+
+#, c-format
+msgid "E243: Argument not supported: \"-%s\"; Use the OLE version."
+msgstr "E243: Argument stöds inte: \"-%s\"; Används OLE-versionen."
+
+msgid "E672: Unable to open window inside MDI application"
+msgstr "E672: Kunde inte öppna fönster inuti MDI-applikation"
+
+msgid "Close tab"
+msgstr "Stäng flik"
+
+msgid "Open tab..."
+msgstr "Öppna flik..."
+
+msgid "Find string (use '\\\\' to find a '\\')"
+msgstr "Sök sträng (använd '\\\\' för att hitta '\\')"
+
+msgid "Find & Replace (use '\\\\' to find a '\\')"
+msgstr "Sök & ersätt (använd '\\\\' för att hitta '\\')"
+
+#. 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 "Inte använd"
+
+msgid "Directory\t*.nothing\n"
+msgstr "Katalog\t*.nothing\n"
+
+msgid "Vim E458: Cannot allocate colormap entry, some colors may be incorrect"
+msgstr ""
+"Vim E458: Kan inte allokera post i färgkarta, några färger kan bli felaktiga"
+
+#, c-format
+msgid "E250: Fonts for the following charsets are missing in fontset %s:"
+msgstr ""
+"E250: Typsnitt för följande teckenkoder saknas i typsnittsuppsättningen %s:"
+
+#, c-format
+msgid "E252: Fontset name: %s"
+msgstr "E252: Typsnittsuppsättningsnamn: %s"
+
+#, c-format
+msgid "Font '%s' is not fixed-width"
+msgstr "Font '%s' är inte fast bredd"
+
+#, c-format
+msgid "E253: Fontset name: %s\n"
+msgstr "E253: Typsnittsuppsättningsnamn: %s\n"
+
+#, c-format
+msgid "Font0: %s\n"
+msgstr "Typsnitt0: %s\n"
+
+#, c-format
+msgid "Font1: %s\n"
+msgstr "Typsnitt1: %s\n"
+
+#, c-format
+msgid "Font%ld width is not twice that of font0\n"
+msgstr "Typsnitt%ld är inte dubbelt så bred som font0\n"
+
+#, c-format
+msgid "Font0 width: %ld\n"
+msgstr "Typsnitt0 bredd: %ld\n"
+
+#, c-format
+msgid ""
+"Font1 width: %ld\n"
+"\n"
+msgstr ""
+"Typsnitt1 bredd: %ld\n"
+"\n"
+
+msgid "Invalid font specification"
+msgstr "Ogiltig typsnittsuppsättning"
+
+msgid "&Dismiss"
+msgstr "&Förkasta"
+
+msgid "no specific match"
+msgstr "ingen specifik matchning"
+
+msgid "Vim - Font Selector"
+msgstr "Vim - Typsnittsväljare"
+
+msgid "Name:"
+msgstr "Namn:"
+
+#. create toggle button
+msgid "Show size in Points"
+msgstr "Visa storlek i punkter"
+
+msgid "Encoding:"
+msgstr "Teckenkodning:"
+
+msgid "Font:"
+msgstr "Typsnitt:"
+
+msgid "Style:"
+msgstr "Stil:"
+
+msgid "Size:"
+msgstr "Storlek:"
+
+msgid "E256: Hangul automata ERROR"
+msgstr "E256: Hangul automata FEL"
+
+msgid "E550: Missing colon"
+msgstr "E550: Saknar kolon"
+
+msgid "E551: Illegal component"
+msgstr "E551: Otillåten komponent"
+
+msgid "E552: digit expected"
+msgstr "E552: siffra förväntades"
+
+#, c-format
+msgid "Page %d"
+msgstr "Sida %d"
+
+msgid "No text to be printed"
+msgstr "Ingen text att skriva ut"
+
+#, c-format
+msgid "Printing page %d (%d%%)"
+msgstr "Skriver ut sida %d (%d%%)"
+
+#, c-format
+msgid " Copy %d of %d"
+msgstr " Kopia %d av %d"
+
+#, c-format
+msgid "Printed: %s"
+msgstr "Skrev ut: %s"
+
+msgid "Printing aborted"
+msgstr "Utskrift avbruten"
+
+msgid "E455: Error writing to PostScript output file"
+msgstr "E455: Fel vid skrivning av utdata till PostScript-fil"
+
+#, c-format
+msgid "E624: Can't open file \"%s\""
+msgstr "E624: Kan inte öppna fil \"%s\""
+
+#, c-format
+msgid "E457: Can't read PostScript resource file \"%s\""
+msgstr "E457: Kan inte läsa PostScript-resursfil \"%s\""
+
+#, c-format
+msgid "E618: file \"%s\" is not a PostScript resource file"
+msgstr "E618: fil \"%s\" är inte en PostScript-resursfil"
+
+#, c-format
+msgid "E619: file \"%s\" is not a supported PostScript resource file"
+msgstr "E619: fil \"%s\" är inte en PostScript-resursfil som stöds"
+
+#, c-format
+msgid "E621: \"%s\" resource file has wrong version"
+msgstr "E621: \"%s\"-källfilen har fel version"
+
+msgid "E673: Incompatible multi-byte encoding and character set."
+msgstr "E673: Inkompatibel flerbitskodning och teckenuppsättning."
+
+msgid "E674: printmbcharset cannot be empty with multi-byte encoding."
+msgstr "E674: printmbcharset kan inte vara tom med flerbitskodning."
+
+msgid "E675: No default font specified for multi-byte printing."
+msgstr "E675: Ingen standardfont angiven för flerbitsutskrifter."
+
+msgid "E324: Can't open PostScript output file"
+msgstr "E324: Kan inte öppna PostScript-utfil"
+
+#, c-format
+msgid "E456: Can't open file \"%s\""
+msgstr "E456: Kan inte öppna fil \"%s\""
+
+msgid "E456: Can't find PostScript resource file \"prolog.ps\""
+msgstr "E456: Kan inte hitta PostScript-källfilen \"prolog.ps\""
+
+msgid "E456: Can't find PostScript resource file \"cidfont.ps\""
+msgstr "E456: Kan inte hitta PostScript-källfilen \"cidfont.ps\""
+
+#, c-format
+msgid "E456: Can't find PostScript resource file \"%s.ps\""
+msgstr "E456: Kan inte hitta PostScript-källfilen \"%s.ps\""
+
+#, c-format
+msgid "E620: Unable to convert to print encoding \"%s\""
+msgstr "E620: Kunde inte konvertera från utskriftkodning \"%s\""
+
+msgid "Sending to printer..."
+msgstr "Skickar till skrivare..."
+
+msgid "E365: Failed to print PostScript file"
+msgstr "E365: Misslyckades med att skriva ut PostScript-fil"
+
+msgid "Print job sent."
+msgstr "Skrivarjobb skickat."
+
+msgid "Add a new database"
+msgstr "Lägg till en ny databas"
+
+msgid "Query for a pattern"
+msgstr "Fråga efter ett mönster"
+
+msgid "Show this message"
+msgstr "Visa detta meddelande"
+
+msgid "Kill a connection"
+msgstr "Döda en anslutning"
+
+msgid "Reinit all connections"
+msgstr "Ominitiera alla anslutningar"
+
+msgid "Show connections"
+msgstr "Visa anslutningar"
+
+#, c-format
+msgid "E560: Usage: cs[cope] %s"
+msgstr "E560: Användning: cs[cope] %s"
+
+msgid "This cscope command does not support splitting the window.\n"
+msgstr "Det här scope-kommandot stöder inte delning av fönstret.\n"
+
+msgid "E562: Usage: cstag <ident>"
+msgstr "E562: Användning: cstag <identifierare>"
+
+msgid "E257: cstag: tag not found"
+msgstr "E257: cstag: tagg hittades inte"
+
+#, c-format
+msgid "E563: stat(%s) error: %d"
+msgstr "E563: stat(%s)-fel: %d"
+
+msgid "E563: stat error"
+msgstr "E563: stat-fel"
+
+#, c-format
+msgid "E564: %s is not a directory or a valid cscope database"
+msgstr "E564: %s är inte en katalog eller en godkänd cscope-databas"
+
+#, c-format
+msgid "Added cscope database %s"
+msgstr "Lade till cscope-databas %s"
+
+#, c-format
+msgid "E262: error reading cscope connection %ld"
+msgstr "E262: fel vid läsning av cscope-anslutning %ld"
+
+msgid "E561: unknown cscope search type"
+msgstr "E561: okänd cscope-söktyp"
+
+msgid "E566: Could not create cscope pipes"
+msgstr "E566: Kunde inte skapa cscope-rör"
+
+msgid "E622: Could not fork for cscope"
+msgstr "E622: Kunde inte grena för cscope"
+
+msgid "cs_create_connection exec failed"
+msgstr "cs_create_connection-exekvering misslyckades"
+
+msgid "E623: Could not spawn cscope process"
+msgstr "E623: Kunde inte starta cscope-process"
+
+msgid "cs_create_connection: fdopen for to_fp failed"
+msgstr "cs_create_connection: fdopen för to_fp misslyckades"
+
+msgid "cs_create_connection: fdopen for fr_fp failed"
+msgstr "cs_create_connection: fdopen för fr_fp misslyckades"
+
+msgid "E567: no cscope connections"
+msgstr "E567: inga cscope-anslutningar"
+
+#, c-format
+msgid "E259: no matches found for cscope query %s of %s"
+msgstr "E259: inga träffar funna för cscope-förfrågan %s av %s"
+
+#, c-format
+msgid "E469: invalid cscopequickfix flag %c for %c"
+msgstr "E469: ogiltig cscopequickfix flagga %c för %c"
+
+msgid "cscope commands:\n"
+msgstr "cscope-kommandon:\n"
+
+#, c-format
+msgid "%-5s: %-30s (Usage: %s)"
+msgstr "%-5s: %-30s (Användning: %s)"
+
+#, c-format
+msgid "E625: cannot open cscope database: %s"
+msgstr "E625: kan inte öppna cscope-databas: %s"
+
+msgid "E626: cannot get cscope database information"
+msgstr "E626: kan inte hämta cscope-databasinformation"
+
+msgid "E568: duplicate cscope database not added"
+msgstr "E568: dubblerad cscope-databas inte lagd till"
+
+msgid "E569: maximum number of cscope connections reached"
+msgstr "E569: maximalt antal av cscope-anslutningar nått"
+
+#, c-format
+msgid "E261: cscope connection %s not found"
+msgstr "E261: cscope-anslutning %s hittades inte"
+
+#, c-format
+msgid "cscope connection %s closed"
+msgstr "cscope-anslutning %s stängd"
+
+#. should not reach here
+msgid "E570: fatal error in cs_manage_matches"
+msgstr "E570: ödesdigert fel i cs_manage_matches"
+
+#, c-format
+msgid "Cscope tag: %s"
+msgstr "Cscope-tagg: %s"
+
+msgid ""
+"\n"
+" # line"
+msgstr ""
+"\n"
+" # rad"
+
+msgid "filename / context / line\n"
+msgstr "filnamn / sammanhang / rad\n"
+
+#, c-format
+msgid "E609: Cscope error: %s"
+msgstr "E609: Cscope-fel: %s"
+
+msgid "All cscope databases reset"
+msgstr "Alla cscope-databaser återställda"
+
+msgid "no cscope connections\n"
+msgstr "inga cscope-anslutningar\n"
+
+msgid " # pid database name prepend path\n"
+msgstr " # pid databasnamn först i sökväg\n"
+
+msgid ""
+"???: Sorry, this command is disabled, the MzScheme library could not be "
+"loaded."
+msgstr ""
+"???: Tyvärr, det här kommandot är inaktiverat: MzScheme-biblioteket kunde "
+"inte läsas in."
+
+msgid "invalid expression"
+msgstr "ogiltigt uttryck"
+
+msgid "expressions disabled at compile time"
+msgstr "uttryck inaktiverat vid kompilering"
+
+msgid "hidden option"
+msgstr "gömd flagga"
+
+msgid "unknown option"
+msgstr "okänd flagga"
+
+msgid "window index is out of range"
+msgstr "fönsterindex är utanför område"
+
+msgid "couldn't open buffer"
+msgstr "kunde inte öppna buffert"
+
+msgid "cannot save undo information"
+msgstr "kan inte spara ångra-information"
+
+msgid "cannot delete line"
+msgstr "kan inte ta bort rad"
+
+msgid "cannot replace line"
+msgstr "kan inte ersätta rad"
+
+msgid "cannot insert line"
+msgstr "kan inte infoga rad"
+
+msgid "string cannot contain newlines"
+msgstr "sträng kan inte innehålla nyrader"
+
+msgid "Vim error: ~a"
+msgstr "Vim-fel: ~a"
+
+msgid "Vim error"
+msgstr "Vim-fel"
+
+msgid "buffer is invalid"
+msgstr "buffert är ogiltig"
+
+msgid "window is invalid"
+msgstr "fönster är ogiltigt"
+
+msgid "linenr out of range"
+msgstr "radnummer utanför område"
+
+msgid "not allowed in the Vim sandbox"
+msgstr "inte tillåtet i Vim-sandlådan"
+
+msgid ""
+"E263: Sorry, this command is disabled, the Python library could not be "
+"loaded."
+msgstr ""
+"E263: Tyvärr, detta kommandot är inaktiverat, Python-biblioteket kunde inte "
+"läsas in."
+
+msgid "E659: Cannot invoke Python recursively"
+msgstr "E659: Kan inte anropa Python rekursivt"
+
+msgid "can't delete OutputObject attributes"
+msgstr "kan inte ta bort OutputObject-attribut"
+
+msgid "softspace must be an integer"
+msgstr "softspace måste vara ett heltal"
+
+msgid "invalid attribute"
+msgstr "ogiltigt attribut"
+
+msgid "writelines() requires list of strings"
+msgstr "writelines() kräver lista av strängar"
+
+msgid "E264: Python: Error initialising I/O objects"
+msgstr "E264: Python: Fel vid initiering av I/O-objekt"
+
+msgid "attempt to refer to deleted buffer"
+msgstr "försök att referera till borttagen buffert"
+
+msgid "line number out of range"
+msgstr "radnummer utanför område"
+
+#, c-format
+msgid "<buffer object (deleted) at %8lX>"
+msgstr "<buffertobjekt (borttaget) vid %8lX>"
+
+msgid "invalid mark name"
+msgstr "ogiltigt märknamn"
+
+msgid "no such buffer"
+msgstr "ingen sådan buffert"
+
+msgid "attempt to refer to deleted window"
+msgstr "försök att referera till borttaget fönster"
+
+msgid "readonly attribute"
+msgstr "skrivskyddad attribut"
+
+msgid "cursor position outside buffer"
+msgstr "markörposition utanför buffert"
+
+#, c-format
+msgid "<window object (deleted) at %.8lX>"
+msgstr "<fönsterobjekt (borttaget) vid %.8lX>"
+
+#, c-format
+msgid "<window object (unknown) at %.8lX>"
+msgstr "<fönsterobjekt (okänt) vid %.8lX>"
+
+#, c-format
+msgid "<window %d>"
+msgstr "<fönster %d>"
+
+msgid "no such window"
+msgstr "inget sådant fönster"
+
+msgid "E265: $_ must be an instance of String"
+msgstr "E265: $_ måste vara en instans av String"
+
+msgid ""
+"E266: Sorry, this command is disabled, the Ruby library could not be loaded."
+msgstr ""
+"E266: Tyvärr, detta kommandot är inaktiverat, Ruby-biblioteket kunde inte "
+"läsas in."
+
+msgid "E267: unexpected return"
+msgstr "E267: oväntad returnering"
+
+msgid "E268: unexpected next"
+msgstr "E268: oväntad next"
+
+msgid "E269: unexpected break"
+msgstr "E269: oväntad break"
+
+msgid "E270: unexpected redo"
+msgstr "E270: oväntad redo"
+
+msgid "E271: retry outside of rescue clause"
+msgstr "E271: retry utanför rescue-block"
+
+msgid "E272: unhandled exception"
+msgstr "E272: ohanterat undantag"
+
+#, c-format
+msgid "E273: unknown longjmp status %d"
+msgstr "E273: okänt longjmp-status %d"
+
+msgid "Toggle implementation/definition"
+msgstr "Växla mellan implementation/definition"
+
+msgid "Show base class of"
+msgstr "Visa basklass av"
+
+msgid "Show overridden member function"
+msgstr "Visa åsidosatt medlemsfunktion"
+
+msgid "Retrieve from file"
+msgstr "Hämta från fil"
+
+msgid "Retrieve from project"
+msgstr "Hämta från projekt"
+
+msgid "Retrieve from all projects"
+msgstr "Hämta från alla projekt"
+
+msgid "Retrieve"
+msgstr "Hämta"
+
+msgid "Show source of"
+msgstr "Visa källa för"
+
+msgid "Find symbol"
+msgstr "Hitta symbol"
+
+msgid "Browse class"
+msgstr "Bläddra i klass"
+
+msgid "Show class in hierarchy"
+msgstr "Visa klass i hierarki"
+
+msgid "Show class in restricted hierarchy"
+msgstr "Visa klass i begränsad hierarki"
+
+msgid "Xref refers to"
+msgstr "Xref refererar till"
+
+msgid "Xref referred by"
+msgstr "Xref refereras av"
+
+msgid "Xref has a"
+msgstr "Xref har en"
+
+msgid "Xref used by"
+msgstr "Xref används av"
+
+msgid "Show docu of"
+msgstr "Visa docu av"
+
+msgid "Generate docu for"
+msgstr "Generera docu för"
+
+msgid ""
+"Cannot connect to SNiFF+. Check environment (sniffemacs must be found in "
+"$PATH).\n"
+msgstr ""
+"Kan inte ansluta till SNiFF+. Kontrollera miljö (sniffemacs måste kunna "
+"hittas i $PATH).\n"
+
+msgid "E274: Sniff: Error during read. Disconnected"
+msgstr "E274: Sniff: Fel vid läsning. Frånkopplad"
+
+msgid "SNiFF+ is currently "
+msgstr "SNiFF+ är för närvarande "
+
+msgid "not "
+msgstr "inte "
+
+msgid "connected"
+msgstr "ansluten"
+
+#, c-format
+msgid "E275: Unknown SNiFF+ request: %s"
+msgstr "E275: Okänd SNiFF+-begäran: %s"
+
+msgid "E276: Error connecting to SNiFF+"
+msgstr "E276: Fel vid anslutning till SNiFF+"
+
+msgid "E278: SNiFF+ not connected"
+msgstr "E278: SNiFF+ inte ansluten"
+
+msgid "E279: Not a SNiFF+ buffer"
+msgstr "E279: Inte en SNiFF+-buffert"
+
+msgid "Sniff: Error during write. Disconnected"
+msgstr "Sniff: Fel vid skrivning. Frånkopplad"
+
+msgid "invalid buffer number"
+msgstr "ogiltigt buffertnummer"
+
+msgid "not implemented yet"
+msgstr "inte implementerat än"
+
+#. ???
+msgid "cannot set line(s)"
+msgstr "kan inte ställa in rad(er)"
+
+msgid "mark not set"
+msgstr "märke inte satt"
+
+#, c-format
+msgid "row %d column %d"
+msgstr "rad %d kolumn %d"
+
+msgid "cannot insert/append line"
+msgstr "kan inte infoga/lägga till rad"
+
+msgid "unknown flag: "
+msgstr "okänd flagga: "
+
+msgid "unknown vimOption"
+msgstr "okänd vimOption"
+
+msgid "keyboard interrupt"
+msgstr "tangentbordsavbrott"
+
+msgid "vim error"
+msgstr "vim-fel"
+
+msgid "cannot create buffer/window command: object is being deleted"
+msgstr "kan inte skapa buffert/fönster-kommando: objekt håller på att tas bort"
+
+msgid ""
+"cannot register callback command: buffer/window is already being deleted"
+msgstr ""
+"kan inte registera återkallningskommando: buffert/fönster håller redan på "
+"att tas bort"
+
+#. This should never happen. Famous last word?
+msgid ""
+"E280: TCL FATAL ERROR: reflist corrupt!? Please report this to vim-dev@vim."
+"org"
+msgstr ""
+"E280: TCL ÖDESDIGERT FEL: reflist trasig!? Var snäll och rapportera detta "
+"till vim-dev@vim.org"
+
+msgid "cannot register callback command: buffer/window reference not found"
+msgstr ""
+"kan inte registrera återkallningskommando: buffert-/fönsterreferens hittades "
+"inte"
+
+msgid ""
+"E571: Sorry, this command is disabled: the Tcl library could not be loaded."
+msgstr ""
+"E571: Tyvärr, detta kommando är inaktiverat: Tcl-biblioteket kunde inte "
+"läsas in."
+
+msgid ""
+"E281: TCL ERROR: exit code is not int!? Please report this to vim-dev@vim.org"
+msgstr ""
+"E281: TCL-FEL: Avslutningskoden är inte int!? Var snäll och rapportera detta "
+"till vim-dev@vim.org"
+
+#, c-format
+msgid "E572: exit code %d"
+msgstr "E572: avslutningskod %d"
+
+msgid "cannot get line"
+msgstr "kan inte hämta rad"
+
+msgid "Unable to register a command server name"
+msgstr "Kunde inte registrera ett kommandoservernamn"
+
+msgid "E248: Failed to send command to the destination program"
+msgstr "E248: Misslyckades att skicka kommando till målprogrammet"
+
+#, c-format
+msgid "E573: Invalid server id used: %s"
+msgstr "E573: Ogiltigt server-id använt: %s"
+
+msgid "E251: VIM instance registry property is badly formed. Deleted!"
+msgstr "E251: VIM instansregisteregenskap är dåligt format. Borttaget!"
+
+msgid "Unknown option argument"
+msgstr "Okänt flaggargument"
+
+msgid "Too many edit arguments"
+msgstr "För många redigeringsargument"
+
+msgid "Argument missing after"
+msgstr "Argument saknas efter"
+
+msgid "Garbage after option argument"
+msgstr "Skräp efter flaggargument"
+
+msgid "Too many \"+command\", \"-c command\" or \"--cmd command\" arguments"
+msgstr ""
+"För många \"+kommando\"-, \"-c kommando\"- eller \"--cmd kommando\"-argument"
+
+msgid "Invalid argument for"
+msgstr "Ogiltigt argument för"
+
+#, c-format
+msgid "%d files to edit\n"
+msgstr "%d filer att redigera\n"
+
+msgid "This Vim was not compiled with the diff feature."
+msgstr "Denna Vim blev inte kompilerad med diff-funktionen."
+
+msgid "Attempt to open script file again: \""
+msgstr "Försök att öppna skriptfil igen: \""
+
+msgid "Cannot open for reading: \""
+msgstr "Kan inte öppna för läsning: \""
+
+msgid "Cannot open for script output: \""
+msgstr "Kan inte öppna för skriptutmatning: \""
+
+msgid "Vim: Error: Failure to start gvim from NetBeans\n"
+msgstr "Vim: Fel: Misslyckades att starta gvim från NetBeans\n"
+
+msgid "Vim: Warning: Output is not to a terminal\n"
+msgstr "Vim: Varning: Utmatning är inte till en terminal\n"
+
+msgid "Vim: Warning: Input is not from a terminal\n"
+msgstr "Vim: Varning: Inmatning är inte från en terminal\n"
+
+#. just in case..
+msgid "pre-vimrc command line"
+msgstr "pre-vimrc kommandorad"
+
+#, c-format
+msgid "E282: Cannot read from \"%s\""
+msgstr "E282: Kan inte läsa från \"%s\""
+
+msgid ""
+"\n"
+"More info with: \"vim -h\"\n"
+msgstr ""
+"\n"
+"Mer info med: \"vim -h\"\n"
+
+msgid "[file ..] edit specified file(s)"
+msgstr "[fil ..] redigera angivna fil(er)"
+
+msgid "- read text from stdin"
+msgstr "- läs text från standard in"
+
+msgid "-t tag edit file where tag is defined"
+msgstr "-t tagg redigera fil där tagg är definierad"
+
+msgid "-q [errorfile] edit file with first error"
+msgstr "-q [felfil] redigera fil med första fel"
+
+msgid ""
+"\n"
+"\n"
+"usage:"
+msgstr ""
+"\n"
+"\n"
+"användning:"
+
+msgid " vim [arguments] "
+msgstr " vim [argument] "
+
+msgid ""
+"\n"
+" or:"
+msgstr ""
+"\n"
+" eller:"
+
+msgid ""
+"\n"
+"Where case is ignored prepend / to make flag upper case"
+msgstr ""
+"\n"
+"Där storlek ignoreras börja med / för att göra flagga versal"
+
+msgid ""
+"\n"
+"\n"
+"Arguments:\n"
+msgstr ""
+"\n"
+"\n"
+"Argument:\n"
+
+msgid "--\t\t\tOnly file names after this"
+msgstr "--\t\t\tBara filnamn efter det här"
+
+msgid "--literal\t\tDon't expand wildcards"
+msgstr "--literal\t\tExpandera inte jokertecken"
+
+msgid "-register\t\tRegister this gvim for OLE"
+msgstr "-register\t\tRegistrera gvim för OLE"
+
+msgid "-unregister\t\tUnregister gvim for OLE"
+msgstr "-unregister\t\tAvregistrera gvim för OLE"
+
+msgid "-g\t\t\tRun using GUI (like \"gvim\")"
+msgstr "-g\t\t\tKör som GUI (som \"gvim\")"
+
+msgid "-f or --nofork\tForeground: Don't fork when starting GUI"
+msgstr "-f eller --nofork\tFörgrund: Grena inte vid start av GUI"
+
+msgid "-v\t\t\tVi mode (like \"vi\")"
+msgstr "-v\t\t\tVi-läge (som \"vi\")"
+
+msgid "-e\t\t\tEx mode (like \"ex\")"
+msgstr "-e\t\t\tEx-läge (som \"ex\")"
+
+msgid "-s\t\t\tSilent (batch) mode (only for \"ex\")"
+msgstr "-s\t\t\tTyst (batch) läge (bara för \"ex\")"
+
+msgid "-d\t\t\tDiff mode (like \"vimdiff\")"
+msgstr "-d\t\t\tDiff-läge (som \"vimdiff\")"
+
+msgid "-y\t\t\tEasy mode (like \"evim\", modeless)"
+msgstr "-y\t\t\tLätt läge (som \"evim\", lägeslös)"
+
+msgid "-R\t\t\tReadonly mode (like \"view\")"
+msgstr "-R\t\t\tSkrivskyddat läge (som \"view\")"
+
+msgid "-Z\t\t\tRestricted mode (like \"rvim\")"
+msgstr "-Z\t\t\tBegränsat läge (som \"rvim\")"
+
+msgid "-m\t\t\tModifications (writing files) not allowed"
+msgstr "-m\t\t\tModifieringar (skriva filer) inte tillåtet"
+
+msgid "-M\t\t\tModifications in text not allowed"
+msgstr "-M\t\t\tModifieringar i text inte tillåtet"
+
+msgid "-b\t\t\tBinary mode"
+msgstr "-b\t\t\tBinärläge"
+
+msgid "-l\t\t\tLisp mode"
+msgstr "-l\t\t\tLisp-läge"
+
+msgid "-C\t\t\tCompatible with Vi: 'compatible'"
+msgstr "-C\t\t\tKompatibelt med Vi: 'compatible'"
+
+msgid "-N\t\t\tNot fully Vi compatible: 'nocompatible'"
+msgstr "-N\t\t\tInte fullt Vi-kompatibel: 'nocompatible'"
+
+msgid "-V[N][fname]\t\tBe verbose [level N] [log messages to fname]"
+msgstr "-V[N][fnamn]\t\tVar mångordig [nivå N] [logga meddelanden till fnamn]"
+
+msgid "-D\t\t\tDebugging mode"
+msgstr "-D\t\t\tFelsökningsläge"
+
+msgid "-n\t\t\tNo swap file, use memory only"
+msgstr "-n\t\t\tIngen växlingsfil, använd endast minnet"
+
+msgid "-r\t\t\tList swap files and exit"
+msgstr "-r\t\t\tLista växlingsfiler och avsluta"
+
+msgid "-r (with file name)\tRecover crashed session"
+msgstr "-r (med filnamn)\tÅterskapa kraschad session"
+
+msgid "-L\t\t\tSame as -r"
+msgstr "-L\t\t\tSamma som -r"
+
+msgid "-f\t\t\tDon't use newcli to open window"
+msgstr "-f\t\t\tAnvända inte newcli för att öppna fönster"
+
+msgid "-dev <device>\t\tUse <device> for I/O"
+msgstr "-dev <enhet>\t\tAnvänd <enhet> för I/O"
+
+msgid "-A\t\t\tstart in Arabic mode"
+msgstr "-A\t\t\tstarta i arabiskt läge"
+
+msgid "-H\t\t\tStart in Hebrew mode"
+msgstr "-H\t\t\tStarta i hebreiskt läge"
+
+msgid "-F\t\t\tStart in Farsi mode"
+msgstr "-F\t\t\tStarta i persiskt läge (Farsi)"
+
+msgid "-T <terminal>\tSet terminal type to <terminal>"
+msgstr "-T <terminal>\tStäll in terminaltyp till <terminal>"
+
+msgid "-u <vimrc>\t\tUse <vimrc> instead of any .vimrc"
+msgstr "-u <vimrc>\t\tAnvänd <vimrc> istället för någon .vimrc"
+
+msgid "-U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc"
+msgstr "-U <gvimrc>\t\tAnvänd <gvimrc> istället för någon .gvimrc"
+
+msgid "--noplugin\t\tDon't load plugin scripts"
+msgstr "--noplugin\t\tLäs inte in insticksskript"
+
+msgid "-p[N]\t\tOpen N tab pages (default: one for each file)"
+msgstr "-p[N]\t\tÖppna N flikar (standard: en för varje fil)"
+
+msgid "-o[N]\t\tOpen N windows (default: one for each file)"
+msgstr "-o[N]\t\tÖppna N fönster (standard: ett för varje fil)"
+
+msgid "-O[N]\t\tLike -o but split vertically"
+msgstr "-O[N]\t\tSom -o men dela vertikalt"
+
+msgid "+\t\t\tStart at end of file"
+msgstr "+\t\t\tStarta vid slut av fil"
+
+msgid "+<lnum>\t\tStart at line <lnum>"
+msgstr "+<lnr>\t\tStarta på rad <rnr>"
+
+msgid "--cmd <command>\tExecute <command> before loading any vimrc file"
+msgstr "--cmd <kommando>\tKör <kommando> före inläsning av någon vimrc fil"
+
+msgid "-c <command>\t\tExecute <command> after loading the first file"
+msgstr "-c <kommando>\tKör <kommando> efter inläsning av den första filen"
+
+msgid "-S <session>\t\tSource file <session> after loading the first file"
+msgstr "-S <session>\t\tKör fil <session> efter inläsning av den första filen"
+
+msgid "-s <scriptin>\tRead Normal mode commands from file <scriptin>"
+msgstr "-s <inskript>\tLäs Normallägeskommandon från fil <inskript>"
+
+msgid "-w <scriptout>\tAppend all typed commands to file <scriptout>"
+msgstr "-w <utskript>\tLägg till alla skrivna kommandon till fil <utskript>"
+
+msgid "-W <scriptout>\tWrite all typed commands to file <scriptout>"
+msgstr "-W <utskript>\tSkriv alla skrivna kommandon till fil <utskript>"
+
+msgid "-x\t\t\tEdit encrypted files"
+msgstr "-x\t\t\tRedigera krypterade filer"
+
+msgid "-display <display>\tConnect vim to this particular X-server"
+msgstr "-display <display>\tAnslut vim till just denna X-server"
+
+msgid "-X\t\t\tDo not connect to X server"
+msgstr "-X\t\t\tAnslut inte till X server"
+
+msgid "--remote <files>\tEdit <files> in a Vim server if possible"
+msgstr "--remote <filer>\tRedigera <filer> i en Vim-server om möjligt"
+
+msgid "--remote-silent <files> Same, don't complain if there is no server"
+msgstr ""
+"--remote-silent <filer>\tSamma, klaga inte om det inte finns någon server"
+
+msgid ""
+"--remote-wait <files> As --remote but wait for files to have been edited"
+msgstr ""
+"--remote-wait <filer>\tSom --remote men vänta på att filer har blivit "
+"redigerade"
+
+msgid ""
+"--remote-wait-silent <files> Same, don't complain if there is no server"
+msgstr ""
+"--remote-wait-silent <filer>\tSamma, klaga inte om det inte finns någon "
+"server"
+
+msgid "--remote-tab <files> As --remote but open tab page for each file"
+msgstr "--remote-tab <filer> Som --remote men öppna flik för varje fil"
+
+msgid "--remote-send <keys>\tSend <keys> to a Vim server and exit"
+msgstr ""
+"--remote-send <nycklar>\tSkicka <nycklar> till en Vim-server och avsluta"
+
+msgid "--remote-expr <expr>\tEvaluate <expr> in a Vim server and print result"
+msgstr ""
+"--remote-expr <uttryck>\tEvaluera <uttryck> i en Vim-server och skriv ut "
+"resultatet"
+
+msgid "--serverlist\t\tList available Vim server names and exit"
+msgstr "--serverlist\t\tLista tillgängliga Vim-servernamn och avsluta"
+
+msgid "--servername <name>\tSend to/become the Vim server <name>"
+msgstr "--servername <namn>\tSkicka till/för att bli Vim-servern <namn>"
+
+msgid "-i <viminfo>\t\tUse <viminfo> instead of .viminfo"
+msgstr "-i <viminfo>\t\tAnvänd <viminfo> istället för .viminfo"
+
+msgid "-h or --help\tPrint Help (this message) and exit"
+msgstr "-h eller --help\tSkriv ut Hjälp (det här meddelandet) och avsluta"
+
+msgid "--version\t\tPrint version information and exit"
+msgstr "--version\t\tSkriv ut versionsinformation och avsluta"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (Motif version):\n"
+msgstr ""
+"\n"
+"Argument som stöds av gvim (Motif-version):\n"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (neXtaw version):\n"
+msgstr ""
+"\n"
+"Argument som stöds av gvim (neXtaw-version):\n"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (Athena version):\n"
+msgstr ""
+"\n"
+"Argument som stöds av 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\tStarta vim som ikon"
+
+msgid "-name <name>\t\tUse resource as if vim was <name>"
+msgstr "-name <namn>\t\tAnvänd resurs som om vim var <namn>"
+
+msgid "\t\t\t (Unimplemented)\n"
+msgstr "\t\t\t (Oimplementerat)\n"
+
+msgid "-background <color>\tUse <color> for the background (also: -bg)"
+msgstr "-background <färg>\tAnvänd <färg> för bakgrunden (även: -bg)"
+
+msgid "-foreground <color>\tUse <color> for normal text (also: -fg)"
+msgstr "-foreground <färg>\tAnvänd <färg> för vanlig text (även: -fg)"
+
+msgid "-font <font>\t\tUse <font> for normal text (also: -fn)"
+msgstr "-font <typsnitt>\t\tAnvänd <typsnitt> för vanlig text (även: -fn)"
+
+msgid "-boldfont <font>\tUse <font> for bold text"
+msgstr "­boldfont <typsnitt>\tAnvänd <typsnitt> för fet text"
+
+msgid "-italicfont <font>\tUse <font> for italic text"
+msgstr "-italicfont <typsnitt>\tAnvänd <typsnitt> för kursiv text"
+
+msgid "-geometry <geom>\tUse <geom> for initial geometry (also: -geom)"
+msgstr ""
+"-geometry <geom>\tAnvänd <geom> för inledande fönsterplacering (även: -geom)"
+
+msgid "-borderwidth <width>\tUse a border width of <width> (also: -bw)"
+msgstr "-borderwidth <bredd>\tAnvänd en rambredd med <bredd> (även: -bw)"
+
+msgid "-scrollbarwidth <width> Use a scrollbar width of <width> (also: -sw)"
+msgstr ""
+"-scrollbarwidth <bredd> Använd en rullningslistbredd på <bredd> (även: -sw)"
+
+msgid "-menuheight <height>\tUse a menu bar height of <height> (also: -mh)"
+msgstr "-menuheight <höjd>\tAnvänd en menyradshöjd med <höjd> (även: -mh)"
+
+msgid "-reverse\t\tUse reverse video (also: -rv)"
+msgstr "-reverse\t\tAnvänd omvänd video (även: -rv)"
+
+msgid "+reverse\t\tDon't use reverse video (also: +rv)"
+msgstr "+reverse\t\tAnvänd inte omvänd video (även: +rv)"
+
+msgid "-xrm <resource>\tSet the specified resource"
+msgstr "-xrm <tillgång>\tStäll in den angivna tillgången"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (RISC OS version):\n"
+msgstr ""
+"\n"
+"Argument igenkända av gvim (RISC OS-version):\n"
+
+msgid "--columns <number>\tInitial width of window in columns"
+msgstr "--columns <antal>\tInledande bredd på fönster i kolumner"
+
+msgid "--rows <number>\tInitial height of window in rows"
+msgstr "--rows <antal>\tInledande höjd på fönster i rader"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (GTK+ version):\n"
+msgstr ""
+"\n"
+"Argument igenkända av gvim (GTK+-version):\n"
+
+msgid "-display <display>\tRun vim on <display> (also: --display)"
+msgstr "-display <display>\tKör vim på <display> (även: --display)"
+
+msgid "--role <role>\tSet a unique role to identify the main window"
+msgstr "--role <roll>\tStäll in en unik roll för att identifiera huvudfönstret"
+
+msgid "--socketid <xid>\tOpen Vim inside another GTK widget"
+msgstr "--socketid <xid>\tÖppna Vim innanför en annan GTK-widget"
+
+msgid "-P <parent title>\tOpen Vim inside parent application"
+msgstr "-P <förälder fönster>\tÖppna Vim inuti förälderapplikation"
+
+msgid "No display"
+msgstr "Ingen display"
+
+#. Failed to send, abort.
+msgid ": Send failed.\n"
+msgstr ": Överföring misslyckades.\n"
+
+#. Let vim start normally.
+msgid ": Send failed. Trying to execute locally\n"
+msgstr ": Överföring misslyckades. Försöker att köra lokalt\n"
+
+#, c-format
+msgid "%d of %d edited"
+msgstr "%d av %d redigerade"
+
+msgid "No display: Send expression failed.\n"
+msgstr "Ingen display: Överföringsuttryck misslyckades.\n"
+
+msgid ": Send expression failed.\n"
+msgstr ": Överföringsuttryck misslyckades.\n"
+
+msgid "No marks set"
+msgstr "Inga märken satta"
+
+#, c-format
+msgid "E283: No marks matching \"%s\""
+msgstr "E283: Inga märken matchade \"%s\""
+
+#. Highlight title
+msgid ""
+"\n"
+"mark line col file/text"
+msgstr ""
+"\n"
+"märke rad kol fil/text"
+
+#. Highlight title
+msgid ""
+"\n"
+" jump line col file/text"
+msgstr ""
+"\n"
+" hopp rad kol fil/text"
+
+#. Highlight title
+msgid ""
+"\n"
+"change line col text"
+msgstr ""
+"\n"
+"ändring rad kol text"
+
+#, c-format
+msgid ""
+"\n"
+"# File marks:\n"
+msgstr ""
+"\n"
+"# Filmärken:\n"
+
+#. Write the jumplist with -'
+#, c-format
+msgid ""
+"\n"
+"# Jumplist (newest first):\n"
+msgstr ""
+"\n"
+"# Hopplista (nyaste först):\n"
+
+#, c-format
+msgid ""
+"\n"
+"# History of marks within files (newest to oldest):\n"
+msgstr ""
+"\n"
+"# Historia för märken inne i filer (nyaste till äldsta):\n"
+
+msgid "Missing '>'"
+msgstr "Saknar '>'"
+
+msgid "E543: Not a valid codepage"
+msgstr "E543: Inte en godkänd teckentabell"
+
+msgid "E284: Cannot set IC values"
+msgstr "E284: Kan inte ställa in IC-värden"
+
+msgid "E285: Failed to create input context"
+msgstr "E285: Misslyckades att skapa inmatningsmiljö"
+
+msgid "E286: Failed to open input method"
+msgstr "E286: Misslyckades att öppna inmatningsmetod"
+
+msgid "E287: Warning: Could not set destroy callback to IM"
+msgstr "E287: Varning: Kunde inte ställa in förstörningsåterkallning till IM"
+
+msgid "E288: input method doesn't support any style"
+msgstr "E288: inmatningsmetod stöder inte någon stil"
+
+msgid "E289: input method doesn't support my preedit type"
+msgstr "E289: inmatningsmetod stöder inte min förredigeringstyp"
+
+msgid "E290: over-the-spot style requires fontset"
+msgstr "E290: över-pricken-stil kräver typsnittsuppsättning"
+
+msgid "E291: Your GTK+ is older than 1.2.3. Status area disabled"
+msgstr "E291: Din GTK+ är äldre än 1.2.3. Statusområde inaktiverat"
+
+msgid "E292: Input Method Server is not running"
+msgstr "E292: Inmatningsmetodserver körs inte"
+
+msgid "E293: block was not locked"
+msgstr "E293: block låstes inte"
+
+msgid "E294: Seek error in swap file read"
+msgstr "E294: Sökfel i växelfilsläsning"
+
+msgid "E295: Read error in swap file"
+msgstr "E295: Läsfel i växelfil"
+
+msgid "E296: Seek error in swap file write"
+msgstr "E296: Sökfel i växelfilskrivning"
+
+msgid "E297: Write error in swap file"
+msgstr "E297: Skrivfel i växelfil"
+
+msgid "E300: Swap file already exists (symlink attack?)"
+msgstr "E300: Växelfil existerar redan (symlänksattack?)"
+
+msgid "E298: Didn't get block nr 0?"
+msgstr "E298: Tog inte emot block nr 0?"
+
+msgid "E298: Didn't get block nr 1?"
+msgstr "E298: Tog inte emot block nr 1?"
+
+msgid "E298: Didn't get block nr 2?"
+msgstr "E298: Tog inte emot block nr 2?"
+
+#. could not (re)open the swap file, what can we do????
+msgid "E301: Oops, lost the swap file!!!"
+msgstr "E301: Hoppsan, tappat bort växelfilen!!!"
+
+msgid "E302: Could not rename swap file"
+msgstr "E302: Kunde inte döpa om växelfil"
+
+#, c-format
+msgid "E303: Unable to open swap file for \"%s\", recovery impossible"
+msgstr "E303: Kunde inte öppna växelfil för \"%s\", återskapning omöjlig"
+
+msgid "E304: ml_upd_block0(): Didn't get block 0??"
+msgstr "E304: ml_upd_block0(): Tog inte emot block 0??"
+
+#, c-format
+msgid "E305: No swap file found for %s"
+msgstr "E305: Ingen växelfil hittad för %s"
+
+msgid "Enter number of swap file to use (0 to quit): "
+msgstr "Ange nummer på växelfil att använda (0 för att avsluta): "
+
+#, c-format
+msgid "E306: Cannot open %s"
+msgstr "E306: Kan inte öppna %s"
+
+msgid "Unable to read block 0 from "
+msgstr "Kunde inte läsa block 0 från "
+
+msgid ""
+"\n"
+"Maybe no changes were made or Vim did not update the swap file."
+msgstr ""
+"\n"
+"Kanske gjordes inte några förändringar eller så uppdaterade inte Vim "
+"växlingsfilen."
+
+msgid " cannot be used with this version of Vim.\n"
+msgstr " kan inte användas med den här versionen av Vim.\n"
+
+msgid "Use Vim version 3.0.\n"
+msgstr "Använd Vim version 3.0.\n"
+
+#, c-format
+msgid "E307: %s does not look like a Vim swap file"
+msgstr "E307: %s ser inte ut som en Vim-växlingsfil"
+
+msgid " cannot be used on this computer.\n"
+msgstr " kan inte användas på den här datorn.\n"
+
+msgid "The file was created on "
+msgstr "Filen skapades på "
+
+msgid ""
+",\n"
+"or the file has been damaged."
+msgstr ""
+",\n"
+"eller så har filen blivit skadad."
+
+msgid " has been damaged (page size is smaller than minimum value).\n"
+msgstr " har skadats (sid-storlek är mindre än minimumvärdet).\n"
+
+#, c-format
+msgid "Using swap file \"%s\""
+msgstr "Använder växlingsfil \"%s\""
+
+#, c-format
+msgid "Original file \"%s\""
+msgstr "Orginalfil \"%s\""
+
+msgid "E308: Warning: Original file may have been changed"
+msgstr "E308: Varning: Orginalfilen kan ha blivit skadad"
+
+#, c-format
+msgid "E309: Unable to read block 1 from %s"
+msgstr "E309: Kunde inte läsa block 1 från %s"
+
+msgid "???MANY LINES MISSING"
+msgstr "???MÅNGA RADER SAKNAS"
+
+msgid "???LINE COUNT WRONG"
+msgstr "???RADANTAL FEL"
+
+msgid "???EMPTY BLOCK"
+msgstr "???TOMT BLOCK"
+
+msgid "???LINES MISSING"
+msgstr "???RADER SAKNAS"
+
+#, c-format
+msgid "E310: Block 1 ID wrong (%s not a .swp file?)"
+msgstr "E310: Block 1 ID fel (%s inte en .swp-fil?)"
+
+msgid "???BLOCK MISSING"
+msgstr "???BLOCK SAKNAS"
+
+msgid "??? from here until ???END lines may be messed up"
+msgstr "??? från här till ???SLUT kan rader vara tillstökade"
+
+msgid "??? from here until ???END lines may have been inserted/deleted"
+msgstr "??? från här till ???SLUT kan rader ha blivit infogade/borttagna"
+
+msgid "???END"
+msgstr "??SLUT"
+
+msgid "E311: Recovery Interrupted"
+msgstr "E311: Återskapning avbruten"
+
+msgid ""
+"E312: Errors detected while recovering; look for lines starting with ???"
+msgstr ""
+"E312: Fel upptäckt vid återskapning; titta efter rader som börjar med ???"
+
+msgid "See \":help E312\" for more information."
+msgstr "Se \":help E312\" för mer information."
+
+msgid "Recovery completed. You should check if everything is OK."
+msgstr "Återskapning klar. Du borde kontrollera om allting är OK."
+
+msgid ""
+"\n"
+"(You might want to write out this file under another name\n"
+msgstr ""
+"\n"
+"(Du kanske vill spara den här filen under ett annat namn\n"
+
+msgid "and run diff with the original file to check for changes)\n"
+msgstr ""
+"och kör diff med orginalfilen för att kontrollera efter förändringar)\n"
+
+msgid ""
+"Delete the .swp file afterwards.\n"
+"\n"
+msgstr ""
+"Ta bort .swp-filen efteråt.\n"
+"\n"
+
+#. use msg() to start the scrolling properly
+msgid "Swap files found:"
+msgstr "Växlingsfiler hittade:"
+
+msgid " In current directory:\n"
+msgstr " I aktuell katalog:\n"
+
+msgid " Using specified name:\n"
+msgstr " Använder angivet namn:\n"
+
+msgid " In directory "
+msgstr " I katalog "
+
+msgid " -- none --\n"
+msgstr " -- inget --\n"
+
+msgid " owned by: "
+msgstr " ägd av: "
+
+msgid " dated: "
+msgstr " daterad: "
+
+msgid " dated: "
+msgstr " daterad: "
+
+msgid " [from Vim version 3.0]"
+msgstr " [från Vim version 3.0]"
+
+msgid " [does not look like a Vim swap file]"
+msgstr " [ser inte ut som en Vim-växlingsfil]"
+
+msgid " file name: "
+msgstr " filnamn: "
+
+msgid ""
+"\n"
+" modified: "
+msgstr ""
+"\n"
+" modifierad: "
+
+msgid "YES"
+msgstr "JA"
+
+msgid "no"
+msgstr "nej"
+
+msgid ""
+"\n"
+" user name: "
+msgstr ""
+"\n"
+" användarnamn: "
+
+msgid " host name: "
+msgstr " värdnamn: "
+
+msgid ""
+"\n"
+" host name: "
+msgstr ""
+"\n"
+" värdnamn: "
+
+msgid ""
+"\n"
+" process ID: "
+msgstr ""
+"\n"
+" process-ID: "
+
+msgid " (still running)"
+msgstr " (körs fortfarande)"
+
+msgid ""
+"\n"
+" [not usable with this version of Vim]"
+msgstr ""
+"\n"
+" [inte användbar med den här versionen av Vim]"
+
+msgid ""
+"\n"
+" [not usable on this computer]"
+msgstr ""
+"\n"
+" [inte användbar på den här datorn]"
+
+msgid " [cannot be read]"
+msgstr " [kan inte läsas]"
+
+msgid " [cannot be opened]"
+msgstr " [kan inte öppnas]"
+
+msgid "E313: Cannot preserve, there is no swap file"
+msgstr "E313: Kan inte bevara, det finns ingen växlingsfil"
+
+msgid "File preserved"
+msgstr "Fil bevarad"
+
+msgid "E314: Preserve failed"
+msgstr "E314: Bevaring misslyckades"
+
+#, c-format
+msgid "E315: ml_get: invalid lnum: %ld"
+msgstr "E315: ml_get: ogiltigt lnum: %ld"
+
+#, c-format
+msgid "E316: ml_get: cannot find line %ld"
+msgstr "E316: ml_get: kan inte hitta rad %ld"
+
+msgid "E317: pointer block id wrong 3"
+msgstr "E317: pekarblock-id fel 3"
+
+msgid "stack_idx should be 0"
+msgstr "stack_idx ska vara 0"
+
+msgid "E318: Updated too many blocks?"
+msgstr "E318: Uppdaterade för många block?"
+
+msgid "E317: pointer block id wrong 4"
+msgstr "E317: pekarblock-id fel 4"
+
+msgid "deleted block 1?"
+msgstr "tagit bort block 1?"
+
+#, c-format
+msgid "E320: Cannot find line %ld"
+msgstr "E320: Kan inte hitta rad %ld"
+
+msgid "E317: pointer block id wrong"
+msgstr "E317: pekarblock-id fel"
+
+msgid "pe_line_count is zero"
+msgstr "pe_line_count är noll"
+
+#, c-format
+msgid "E322: line number out of range: %ld past the end"
+msgstr "E322: radnummer utanför område: %ld bakom slutet"
+
+#, c-format
+msgid "E323: line count wrong in block %ld"
+msgstr "E323: radantal fel i block %ld"
+
+msgid "Stack size increases"
+msgstr "Stackstorlek ökar"
+
+msgid "E317: pointer block id wrong 2"
+msgstr "E317: pekarblock-id fel 2"
+
+#, c-format
+msgid "E773: Symlink loop for \"%s\""
+msgstr "E773: Symbolisk länk-loop för \"%s\""
+
+msgid "E325: ATTENTION"
+msgstr "E325: LYSTRING"
+
+msgid ""
+"\n"
+"Found a swap file by the name \""
+msgstr ""
+"\n"
+"Hittade en växlingsfil med namnet \""
+
+msgid "While opening file \""
+msgstr "Vid öppning av fil \""
+
+msgid " NEWER than swap file!\n"
+msgstr " NYARE än växelfil!\n"
+
+#. Some of these messages are long to allow translation to
+#. * other languages.
+msgid ""
+"\n"
+"(1) Another program may be editing the same file.\n"
+" If this is the case, be careful not to end up with two\n"
+" different instances of the same file when making changes.\n"
+msgstr ""
+"\n"
+"(1) Ett annat program kan redigera samma fil.\n"
+" Om så är fallet, var försiktig så att det inte slutar med två\n"
+" versioner av samma fil vid förändringar.\n"
+
+msgid " Quit, or continue with caution.\n"
+msgstr " Avsluta, eller fortsätt på egen risk.\n"
+
+msgid ""
+"\n"
+"(2) An edit session for this file crashed.\n"
+msgstr ""
+"\n"
+"(2) En redigeringssession för den här filen kraschade.\n"
+
+msgid " If this is the case, use \":recover\" or \"vim -r "
+msgstr " Om så är fallet, använd \":recover\" eller \"vim -r "
+
+msgid ""
+"\"\n"
+" to recover the changes (see \":help recovery\").\n"
+msgstr ""
+"\"\n"
+" för att återskapa förändringarna (se \":help recovery\").\n"
+
+msgid " If you did this already, delete the swap file \""
+msgstr " Om du redan har gjort det, ta bort växlingsfilen \""
+
+msgid ""
+"\"\n"
+" to avoid this message.\n"
+msgstr ""
+"\"\n"
+" för att undvika det här meddelandet.\n"
+
+msgid "Swap file \""
+msgstr "Växlingsfil \""
+
+msgid "\" already exists!"
+msgstr "\" existerar redan!"
+
+msgid "VIM - ATTENTION"
+msgstr "VIM - LYSTRING"
+
+msgid "Swap file already exists!"
+msgstr "Växlingsfil existerar redan!"
+
+msgid ""
+"&Open Read-Only\n"
+"&Edit anyway\n"
+"&Recover\n"
+"&Quit\n"
+"&Abort"
+msgstr ""
+"&Öppna skrivskyddad\n"
+"&Redigera ändå\n"
+"&Återskapa\n"
+"&Avsluta\n"
+"A&vbryt"
+
+msgid ""
+"&Open Read-Only\n"
+"&Edit anyway\n"
+"&Recover\n"
+"&Delete it\n"
+"&Quit\n"
+"&Abort"
+msgstr ""
+"&Öppna skrivskyddad\n"
+"&Redigera ändå\n"
+"&Återskapa\n"
+"&Ta bort den\n"
+"&Avsluta\n"
+"A&vbryt"
+
+msgid "E326: Too many swap files found"
+msgstr "E326: För många växlingsfiler hittade"
+
+msgid "E327: Part of menu-item path is not sub-menu"
+msgstr "E327: Del av menyföremål sökväg är inte undermeny"
+
+msgid "E328: Menu only exists in another mode"
+msgstr "E328: Meny existerar bara i ett annat läge"
+
+#, c-format
+msgid "E329: No menu \"%s\""
+msgstr "E329: Ingen meny \"%s\""
+
+#. Only a mnemonic or accelerator is not valid.
+msgid "E792: Empty menu name"
+msgstr "E792: Tomt menynamn"
+
+msgid "E330: Menu path must not lead to a sub-menu"
+msgstr "E330: Menysökväg får inte leda till en undermeny"
+
+msgid "E331: Must not add menu items directly to menu bar"
+msgstr "E331: Får inte lägga till menyföremål direkt till menyrad"
+
+msgid "E332: Separator cannot be part of a menu path"
+msgstr "E332: Avskiljare kam inte vara en del av en menysökväg"
+
+#. Now we have found the matching menu, and we list the mappings
+#. Highlight title
+msgid ""
+"\n"
+"--- Menus ---"
+msgstr ""
+"\n"
+"--- Menyer ---"
+
+msgid "Tear off this menu"
+msgstr "Ta loss den här menyn"
+
+msgid "E333: Menu path must lead to a menu item"
+msgstr "E333: Menysökväg måste leda till ett menyföremål"
+
+#, c-format
+msgid "E334: Menu not found: %s"
+msgstr "E334: Meny hittades inte: %s"
+
+#, c-format
+msgid "E335: Menu not defined for %s mode"
+msgstr "E335: Meny inte definierad för %s läge"
+
+msgid "E336: Menu path must lead to a sub-menu"
+msgstr "E336: Menysökväg måste leda till en undermeny"
+
+msgid "E337: Menu not found - check menu names"
+msgstr "E337: Meny hittades inte - kontrollera menynamn"
+
+#, c-format
+msgid "Error detected while processing %s:"
+msgstr "Fel upptäcktes vid bearbetning av %s:"
+
+#, c-format
+msgid "line %4ld:"
+msgstr "rad %4ld:"
+
+#, c-format
+msgid "E354: Invalid register name: '%s'"
+msgstr "E354: Otillåtet registernamn: '%s'"
+
+msgid "Messages maintainer: Bram Moolenaar <Bram@vim.org>"
+msgstr "Meddelandeansvarig: Johan Svedberg <johan@svedberg.com>"
+
+msgid "Interrupt: "
+msgstr "Avbrott: "
+
+msgid "Press ENTER or type command to continue"
+msgstr "Tryck RETUR eller skriv kommando för att fortsätta"
+
+#, c-format
+msgid "%s line %ld"
+msgstr "%s rad %ld"
+
+msgid "-- More --"
+msgstr "-- Mer --"
+
+msgid " SPACE/d/j: screen/page/line down, b/u/k: up, q: quit "
+msgstr " BLANKSTEG/d/j: skärm/sida/rad ned, b/u/k: upp, q: quit "
+
+msgid "Question"
+msgstr "Fråga"
+
+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"
+"&Spara &alla\n"
+"&Kasta bort alla\n"
+"&Avbryt"
+
+msgid "Select Directory dialog"
+msgstr "Välj katalog-dialog"
+
+msgid "Save File dialog"
+msgstr "Spara fil-dialog"
+
+msgid "Open File dialog"
+msgstr "Öppna fil-dialog"
+
+#. TODO: non-GUI file selector here
+msgid "E338: Sorry, no file browser in console mode"
+msgstr "E338: Tyvärr, ingen filbläddrare i konsoll-läge"
+
+msgid "E766: Insufficient arguments for printf()"
+msgstr "E766: Otillräckliga argument för printf()"
+
+msgid "E767: Too many arguments to printf()"
+msgstr "E767: För många argument till printf()"
+
+msgid "W10: Warning: Changing a readonly file"
+msgstr "W10: Varning: Ändrar en skrivskyddad fil"
+
+msgid "Type number or click with mouse (<Enter> cancels): "
+msgstr "Skriv siffra eller klicka med musen (<Retur> avbryter): "
+
+msgid "Choice number (<Enter> cancels): "
+msgstr "Välj siffra (<Retur> avbryter): "
+
+msgid "1 more line"
+msgstr "1 rad till"
+
+msgid "1 line less"
+msgstr "1 rad mindre"
+
+#, c-format
+msgid "%ld more lines"
+msgstr "%ld rad till"
+
+#, c-format
+msgid "%ld fewer lines"
+msgstr "%ld färre rader"
+
+msgid " (Interrupted)"
+msgstr " (Avbruten)"
+
+msgid "Beep!"
+msgstr "Piip!"
+
+msgid "Vim: preserving files...\n"
+msgstr "Vim: bevarar filer...\n"
+
+#. close all memfiles, without deleting
+msgid "Vim: Finished.\n"
+msgstr "Vim: Färdig.\n"
+
+#, c-format
+msgid "ERROR: "
+msgstr "FEL: "
+
+#, c-format
+msgid ""
+"\n"
+"[bytes] total alloc-freed %lu-%lu, in use %lu, peak use %lu\n"
+msgstr ""
+"\n"
+"[byte] sammanlagd allok-frigjord %lu-%lu, i användning %lu, toppanvändning %"
+"lu\n"
+
+#, c-format
+msgid ""
+"[calls] total re/malloc()'s %lu, total free()'s %lu\n"
+"\n"
+msgstr ""
+"[anrop] sammanlagda om/malloc()'s %lu, sammanlagda free()'s %lu\n"
+"\n"
+
+msgid "E340: Line is becoming too long"
+msgstr "E340: Rad börjar bli för lång"
+
+#, c-format
+msgid "E341: Internal error: lalloc(%ld, )"
+msgstr "E341: Internt fel: lalloc(%ld, )"
+
+#, c-format
+msgid "E342: Out of memory! (allocating %lu bytes)"
+msgstr "E342: Slut på minne! (allokerar %lu byte)"
+
+#, c-format
+msgid "Calling shell to execute: \"%s\""
+msgstr "Anropar skal att köra: \"%s\""
+
+msgid "E545: Missing colon"
+msgstr "E545: Saknar kolon"
+
+msgid "E546: Illegal mode"
+msgstr "E546: Otillåtet läge"
+
+msgid "E547: Illegal mouseshape"
+msgstr "E547: Otillåten musform"
+
+msgid "E548: digit expected"
+msgstr "E548: siffra förväntades"
+
+msgid "E549: Illegal percentage"
+msgstr "E549: Otillåten procentsats"
+
+msgid "Enter encryption key: "
+msgstr "Ange krypteringsnyckel: "
+
+msgid "Enter same key again: "
+msgstr "Ange samma nyckel igen: "
+
+msgid "Keys don't match!"
+msgstr "Nycklar matchar inte!"
+
+#, c-format
+msgid ""
+"E343: Invalid path: '**[number]' must be at the end of the path or be "
+"followed by '%s'."
+msgstr ""
+"E343: Ogiltig sökväg: '**[nummer]' måste vara i slutet på sökvägen eller "
+"följas av '%s'."
+
+#, c-format
+msgid "E344: Can't find directory \"%s\" in cdpath"
+msgstr "E344: Kan inte hitta katalog \"%s\" i cdpath"
+
+#, c-format
+msgid "E345: Can't find file \"%s\" in path"
+msgstr "E345: Kan inte hitta fil \"%s\" i sökväg"
+
+#, c-format
+msgid "E346: No more directory \"%s\" found in cdpath"
+msgstr "E346: Ingen katalog \"%s\" hittades i cdpath"
+
+#, c-format
+msgid "E347: No more file \"%s\" found in path"
+msgstr "E347: Ingen fil \"%s\" hittades i sökvägen"
+
+#. Get here when the server can't be found.
+msgid "Cannot connect to Netbeans #2"
+msgstr "Kan inte ansluta till Netbeans #2"
+
+msgid "Cannot connect to Netbeans"
+msgstr "Kan inte ansluta till Netbeans"
+
+#, c-format
+msgid "E668: Wrong access mode for NetBeans connection info file: \"%s\""
+msgstr "E668: Fel rättighetsläge för NetBeans-anslutningens info fil: \"%s\""
+
+msgid "read from Netbeans socket"
+msgstr "läs från Netbeans-uttag"
+
+#, c-format
+msgid "E658: NetBeans connection lost for buffer %ld"
+msgstr "E658: NetBeans-anslutning tappad för buffert %ld"
+
+msgid "E505: "
+msgstr "E505: "
+
+msgid "E774: 'operatorfunc' is empty"
+msgstr "E774: 'operatorfunc' är tom"
+
+msgid "E775: Eval feature not available"
+msgstr "E775: Eval-funktionen inte tillgänglig"
+
+msgid "Warning: terminal cannot highlight"
+msgstr "Varning: terminal kan inte framhäva"
+
+msgid "E348: No string under cursor"
+msgstr "E348: Ingen sträng under markör"
+
+msgid "E349: No identifier under cursor"
+msgstr "E349: Ingen identifierare under markör"
+
+msgid "E352: Cannot erase folds with current 'foldmethod'"
+msgstr "E352: Kan inte ta bort veck med aktuell 'foldmethod'"
+
+msgid "E664: changelist is empty"
+msgstr "E664: ändringslista är tom"
+
+msgid "E662: At start of changelist"
+msgstr "E662: Vid början av ändringslista"
+
+msgid "E663: At end of changelist"
+msgstr "E663: Vid slutet av ändringslista"
+
+msgid "Type :quit<Enter> to exit Vim"
+msgstr "skriv :q<Enter> för att avsluta Vim "
+
+#, c-format
+msgid "1 line %sed 1 time"
+msgstr "1 rad %sad 1 gång"
+
+#, c-format
+msgid "1 line %sed %d times"
+msgstr "1 rad %sade %d gånger"
+
+#, c-format
+msgid "%ld lines %sed 1 time"
+msgstr "%ld rader %sad 1 gång"
+
+#, c-format
+msgid "%ld lines %sed %d times"
+msgstr "%ld rader %sade %d gånger"
+
+#, c-format
+msgid "%ld lines to indent... "
+msgstr "%ld rader att indentera... "
+
+msgid "1 line indented "
+msgstr "1 rad indenterad "
+
+#, c-format
+msgid "%ld lines indented "
+msgstr "%ld rader indenterade "
+
+msgid "E748: No previously used register"
+msgstr "E748: Inget tidigare använt register"
+
+#. must display the prompt
+msgid "cannot yank; delete anyway"
+msgstr "kan inte kopiera; ta bort ändå"
+
+msgid "1 line changed"
+msgstr "1 rad ändrad"
+
+#, c-format
+msgid "%ld lines changed"
+msgstr "%ld rader ändrade"
+
+#, c-format
+msgid "freeing %ld lines"
+msgstr "frigör %ld rader"
+
+msgid "block of 1 line yanked"
+msgstr "block om 1 rad kopierat"
+
+msgid "1 line yanked"
+msgstr "1 rad kopierad"
+
+#, c-format
+msgid "block of %ld lines yanked"
+msgstr "block om %ld rader kopierade"
+
+#, c-format
+msgid "%ld lines yanked"
+msgstr "%ld rader kopierade"
+
+#, c-format
+msgid "E353: Nothing in register %s"
+msgstr "E353: Ingenting i register %s"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Registers ---"
+msgstr ""
+"\n"
+"--- Register ---"
+
+msgid "Illegal register name"
+msgstr "Otillåtet registernamn"
+
+#, c-format
+msgid ""
+"\n"
+"# Registers:\n"
+msgstr ""
+"\n"
+"# Register:\n"
+
+#, c-format
+msgid "E574: Unknown register type %d"
+msgstr "E574: Okänd registertyp %d"
+
+#, c-format
+msgid "%ld Cols; "
+msgstr "%ld kolumner; "
+
+#, c-format
+msgid "Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Bytes"
+msgstr "Markerade %s%ld av %ld rader; %ld av %ld ord; %ld av %ld bitar"
+
+#, c-format
+msgid ""
+"Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Chars; %ld of %ld "
+"Bytes"
+msgstr ""
+"Markerade %s%ld av %ld rader; %ld av %ld ord; %ld av %ld tecken; %ld av %ld "
+"bitar"
+
+#, c-format
+msgid "Col %s of %s; Line %ld of %ld; Word %ld of %ld; Byte %ld of %ld"
+msgstr "Kol %s av %s; rad %ld av %ld; ord %ld av %ld; bit %ld av %ld"
+
+#, c-format
+msgid ""
+"Col %s of %s; Line %ld of %ld; Word %ld of %ld; Char %ld of %ld; Byte %ld of "
+"%ld"
+msgstr ""
+"Kol %s av %s; rad %ld av %ld; ord %ld av %ld; tecken %ld av %ld; bit %ld av %"
+"ld"
+
+#, c-format
+msgid "(+%ld for BOM)"
+msgstr "(+%ld för BOM)"
+
+msgid "%<%f%h%m%=Page %N"
+msgstr "%<%f%h%m%=Sida %N"
+
+msgid "Thanks for flying Vim"
+msgstr "Tack för att du flyger med Vim"
+
+msgid "E518: Unknown option"
+msgstr "E518: Okänd flagga"
+
+msgid "E519: Option not supported"
+msgstr "E519: Flagga stöds inte"
+
+msgid "E520: Not allowed in a modeline"
+msgstr "E520: Inte tillåtet i en lägesrad"
+
+msgid "E521: Number required after ="
+msgstr "E521: Nummer krävs efter ="
+
+msgid "E522: Not found in termcap"
+msgstr "E522: Inte hittat i termcap"
+
+#, c-format
+msgid "E539: Illegal character <%s>"
+msgstr "E539: Otillåtet tecken <%s>"
+
+msgid "E529: Cannot set 'term' to empty string"
+msgstr "E529: Kan inte sätta 'term' till tom sträng"
+
+msgid "E530: Cannot change term in GUI"
+msgstr "E530: Kan inte ändra term i GUI"
+
+msgid "E531: Use \":gui\" to start the GUI"
+msgstr "E531: Använd \":gui\" för att starta GUI"
+
+msgid "E589: 'backupext' and 'patchmode' are equal"
+msgstr "E589: 'backuptext' och 'patchmode' är lika"
+
+msgid "E617: Cannot be changed in the GTK+ 2 GUI"
+msgstr "E617: Kan inte bli ändrat i GTK+ 2-GUI"
+
+msgid "E524: Missing colon"
+msgstr "E524: Saknar kolon"
+
+msgid "E525: Zero length string"
+msgstr "E525: Nollängdssträng"
+
+#, c-format
+msgid "E526: Missing number after <%s>"
+msgstr "E526: Saknar nummer efter <%s>"
+
+msgid "E527: Missing comma"
+msgstr "E527: Saknar komma"
+
+msgid "E528: Must specify a ' value"
+msgstr "E528: Måste ange ett '-värde"
+
+msgid "E595: contains unprintable or wide character"
+msgstr "E595: innehåller outskrivbara eller breda tecken"
+
+msgid "E596: Invalid font(s)"
+msgstr "E596: Ogiltig(a) typsnitt"
+
+msgid "E597: can't select fontset"
+msgstr "E597: kan inte välja typsnittsuppsättning"
+
+msgid "E598: Invalid fontset"
+msgstr "E598: Ogiltig typsnittsuppsättning"
+
+msgid "E533: can't select wide font"
+msgstr "E533: kan inte välja brett typsnitt"
+
+msgid "E534: Invalid wide font"
+msgstr "E534: Ogiltigt brett typsnitt"
+
+#, c-format
+msgid "E535: Illegal character after <%c>"
+msgstr "E535: Otillåtet tecken efter <%c>"
+
+msgid "E536: comma required"
+msgstr "E536: komma krävs"
+
+#, c-format
+msgid "E537: 'commentstring' must be empty or contain %s"
+msgstr "E537: 'commentstring' måste vara tom eller innehålla %s"
+
+msgid "E538: No mouse support"
+msgstr "E538: Inget musstöd"
+
+msgid "E540: Unclosed expression sequence"
+msgstr "E540: Ostängd uttryckssekvens"
+
+msgid "E541: too many items"
+msgstr "E541: för många föremål"
+
+msgid "E542: unbalanced groups"
+msgstr "E542: obalanserade grupper"
+
+msgid "E590: A preview window already exists"
+msgstr "E590: Ett förhandsvisningsfönster existerar redan"
+
+msgid "W17: Arabic requires UTF-8, do ':set encoding=utf-8'"
+msgstr "W17: Arabiska kräver UTF-8, gör ':set encoding=utf-8'"
+
+#, c-format
+msgid "E593: Need at least %d lines"
+msgstr "E593: Behöver åtminstone %d rader"
+
+#, c-format
+msgid "E594: Need at least %d columns"
+msgstr "E594: Behöver åtminstone %d kolumner"
+
+#, c-format
+msgid "E355: Unknown option: %s"
+msgstr "E355: Okänd flagga: %s"
+
+msgid ""
+"\n"
+"--- Terminal codes ---"
+msgstr ""
+"\n"
+"--- Terminalkoder ---"
+
+msgid ""
+"\n"
+"--- Global option values ---"
+msgstr ""
+"\n"
+"--- Globala flaggvärden ---"
+
+msgid ""
+"\n"
+"--- Local option values ---"
+msgstr ""
+"\n"
+"--- Lokala flaggvärden ---"
+
+msgid ""
+"\n"
+"--- Options ---"
+msgstr ""
+"\n"
+"--- Flaggor ---"
+
+msgid "E356: get_varp ERROR"
+msgstr "E356: get_varp-FEL"
+
+#, c-format
+msgid "E357: 'langmap': Matching character missing for %s"
+msgstr "E357: 'langmap': Matchande tecken saknas för %s"
+
+#, c-format
+msgid "E358: 'langmap': Extra characters after semicolon: %s"
+msgstr "E358: 'langmap': Extra tecken efter semikolon: %s"
+
+msgid "cannot open "
+msgstr "kan inte öppna "
+
+msgid "VIM: Can't open window!\n"
+msgstr "VIM: Kan inte öppna fönster!\n"
+
+msgid "Need Amigados version 2.04 or later\n"
+msgstr "Behöver Amigados version 2.04 eller senare\n"
+
+#, c-format
+msgid "Need %s version %ld\n"
+msgstr "Behöver %s version %ld\n"
+
+msgid "Cannot open NIL:\n"
+msgstr "Kan inte öppna NIL:\n"
+
+msgid "Cannot create "
+msgstr "Kan inte skapa "
+
+#, c-format
+msgid "Vim exiting with %d\n"
+msgstr "Vim avslutar med %d\n"
+
+msgid "cannot change console mode ?!\n"
+msgstr "kan inte ändra konsoll-läge ?!\n"
+
+msgid "mch_get_shellsize: not a console??\n"
+msgstr "mch_get_shellsize: inte en konsoll??\n"
+
+#. if Vim opened a window: Executing a shell may cause crashes
+msgid "E360: Cannot execute shell with -f option"
+msgstr "E360: Kan inte köra skal med -f-flagga"
+
+msgid "Cannot execute "
+msgstr "Kan inte köra "
+
+msgid "shell "
+msgstr "skal "
+
+msgid " returned\n"
+msgstr " returnerade\n"
+
+msgid "ANCHOR_BUF_SIZE too small."
+msgstr "ANCHOR_BUF_SIZE för liten."
+
+msgid "I/O ERROR"
+msgstr "I/O-FEL"
+
+msgid "Message"
+msgstr "Meddelande"
+
+msgid "'columns' is not 80, cannot execute external commands"
+msgstr "'columns' är inte 80, kan inte köra externa kommandon"
+
+msgid "E237: Printer selection failed"
+msgstr "E237: Skrivarval misslyckades"
+
+#, c-format
+msgid "to %s on %s"
+msgstr "till %s på %s"
+
+#, c-format
+msgid "E613: Unknown printer font: %s"
+msgstr "E613: Okänt skrivartypsnitt: %s"
+
+#, c-format
+msgid "E238: Print error: %s"
+msgstr "E238: Skrivarfel: %s"
+
+#, c-format
+msgid "Printing '%s'"
+msgstr "Skriver ut '%s'"
+
+#, c-format
+msgid "E244: Illegal charset name \"%s\" in font name \"%s\""
+msgstr "E244: Otillåtet teckenkodsnamn \"%s\" i typsnittsnamn \"%s\""
+
+#, c-format
+msgid "E245: Illegal char '%c' in font name \"%s\""
+msgstr "E245: Otillåtet tecken '%c' i typsnittsnamn \"%s\""
+
+msgid "Vim: Double signal, exiting\n"
+msgstr "Vim: Dubbelsignal, avslutar\n"
+
+#, c-format
+msgid "Vim: Caught deadly signal %s\n"
+msgstr "Vim: Fångade dödlig signal %s\n"
+
+#, c-format
+msgid "Vim: Caught deadly signal\n"
+msgstr "Vim: Fångade dödlig signal\n"
+
+#, c-format
+msgid "Opening the X display took %ld msec"
+msgstr "Öppning av X-display tog %ld ms"
+
+msgid ""
+"\n"
+"Vim: Got X error\n"
+msgstr ""
+"\n"
+"Vim: Fick X-error\n"
+
+msgid "Testing the X display failed"
+msgstr "Testning av X-displayen misslyckades"
+
+msgid "Opening the X display timed out"
+msgstr "Öppning av X-displayen tog för lång tid"
+
+msgid ""
+"\n"
+"Cannot execute shell "
+msgstr ""
+"\n"
+"Kan inte köra skal "
+
+msgid ""
+"\n"
+"Cannot execute shell sh\n"
+msgstr ""
+"\n"
+"Kan inte köra skal sh\n"
+
+msgid ""
+"\n"
+"shell returned "
+msgstr ""
+"\n"
+"skal returnerade "
+
+msgid ""
+"\n"
+"Cannot create pipes\n"
+msgstr ""
+"\n"
+"Kan inte skapa rör\n"
+
+msgid ""
+"\n"
+"Cannot fork\n"
+msgstr ""
+"\n"
+"Kan inte grena\n"
+
+msgid ""
+"\n"
+"Command terminated\n"
+msgstr ""
+"\n"
+"Kommando avslutades\n"
+
+msgid "XSMP lost ICE connection"
+msgstr "XSMP tappade ICE-anslutning"
+
+#, c-format
+msgid "dlerror = \"%s\""
+msgstr "dlfel = \"%s\""
+
+msgid "Opening the X display failed"
+msgstr "Öppning av X-displayen misslyckades"
+
+msgid "XSMP handling save-yourself request"
+msgstr "XSMP hanterar spara-själv-förfrågan"
+
+msgid "XSMP opening connection"
+msgstr "XSMP öppnar anslutning"
+
+msgid "XSMP ICE connection watch failed"
+msgstr "XSMP ICE-anslutning övervakning misslyckades"
+
+#, c-format
+msgid "XSMP SmcOpenConnection failed: %s"
+msgstr "XSMP SmcOpenConnection misslyckades: %s"
+
+msgid "Could not load vim32.dll!"
+msgstr "Kunde inte läsa in vim32.dll!"
+
+msgid "VIM Error"
+msgstr "VIM-fel"
+
+msgid "Could not fix up function pointers to the DLL!"
+msgstr "Kunde inte ordna upp funktionspekare till DLL:en!"
+
+#, c-format
+msgid "shell returned %d"
+msgstr "skal returnerade %d"
+
+#, c-format
+msgid "Vim: Caught %s event\n"
+msgstr "Vim: Fångade %s-händelse\n"
+
+msgid "close"
+msgstr "stäng"
+
+msgid "logoff"
+msgstr "logga ut"
+
+msgid "shutdown"
+msgstr "stäng av"
+
+msgid "E371: Command not found"
+msgstr "E371: Kommando hittades inte"
+
+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 hittades inte i din $PATH.\n"
+"Externa kommandon vill inte stå stilla efter färdigställning.\n"
+"Se :help win32-vimrun för mer information."
+
+msgid "Vim Warning"
+msgstr "Vim-varning"
+
+msgid "At line"
+msgstr "På rad"
+
+#, c-format
+msgid "E372: Too many %%%c in format string"
+msgstr "E372: För många %%%c i formatsträng"
+
+#, c-format
+msgid "E373: Unexpected %%%c in format string"
+msgstr "E373: Oväntad %%%c i formatsträng"
+
+msgid "E374: Missing ] in format string"
+msgstr "E374: Saknar ] i formatsträng"
+
+#, c-format
+msgid "E375: Unsupported %%%c in format string"
+msgstr "E375: Ostödd %%%c i formatsträng"
+
+#, c-format
+msgid "E376: Invalid %%%c in format string prefix"
+msgstr "E376: Ogiltig %%%c i formatsträngprefix"
+
+#, c-format
+msgid "E377: Invalid %%%c in format string"
+msgstr "E377: Ogiltig %%%c i formatsträng"
+
+msgid "E378: 'errorformat' contains no pattern"
+msgstr "E378: 'errorformat' innehåller inga mönster"
+
+msgid "E379: Missing or empty directory name"
+msgstr "E379: Saknar eller tomt katalognamn"
+
+msgid "E553: No more items"
+msgstr "E553: Inga fler föremål"
+
+#, c-format
+msgid "(%d of %d)%s%s: "
+msgstr "(%d av %d)%s%s: "
+
+msgid " (line deleted)"
+msgstr " (rad borttagen)"
+
+msgid "E380: At bottom of quickfix stack"
+msgstr "E380: På botten av quickfix-stack"
+
+msgid "E381: At top of quickfix stack"
+msgstr "E381: På toppen av quickfix-stack"
+
+#, c-format
+msgid "error list %d of %d; %d errors"
+msgstr "fellista %d av %d; %d fel"
+
+msgid "E382: Cannot write, 'buftype' option is set"
+msgstr "E382: Kan inte skriva, 'buftype'-flagga är satt"
+
+msgid "E683: File name missing or invalid pattern"
+msgstr "E683: Filnamn saknas eller ogiltigt mönster"
+
+#, c-format
+msgid "Cannot open file \"%s\""
+msgstr "Kan inte öppna fil \"%s\""
+
+msgid "E681: Buffer is not loaded"
+msgstr "E681: Buffert är inte laddad"
+
+msgid "E777: String or List expected"
+msgstr "E777: Sträng eller Lista förväntades"
+
+#, c-format
+msgid "E369: invalid item in %s%%[]"
+msgstr "E369: ogiltigt föremål i %s%%[]"
+
+msgid "E339: Pattern too long"
+msgstr "E339: Mönster för långt"
+
+msgid "E50: Too many \\z("
+msgstr "E50: För många \\z("
+
+#, c-format
+msgid "E51: Too many %s("
+msgstr "E51: För många %s("
+
+msgid "E52: Unmatched \\z("
+msgstr "E52: Omatchade \\z("
+
+#, c-format
+msgid "E53: Unmatched %s%%("
+msgstr "E53: Omatchade %s%%("
+
+#, c-format
+msgid "E54: Unmatched %s("
+msgstr "E54: Omatchade %s("
+
+#, c-format
+msgid "E55: Unmatched %s)"
+msgstr "E55: Omatchade %s)"
+
+#, c-format
+msgid "E59: invalid character after %s@"
+msgstr "E59: ogiltigt tecken efter %s@"
+
+#, c-format
+msgid "E60: Too many complex %s{...}s"
+msgstr "E60: För många komplexa %s{...}s"
+
+#, c-format
+msgid "E61: Nested %s*"
+msgstr "E61: Nästlade %s*"
+
+#, c-format
+msgid "E62: Nested %s%c"
+msgstr "E62: Nästlade %s%c"
+
+msgid "E63: invalid use of \\_"
+msgstr "E63: ogiltig användning av \\_"
+
+#, c-format
+msgid "E64: %s%c follows nothing"
+msgstr "E64: %s%c följer ingenting"
+
+msgid "E65: Illegal back reference"
+msgstr "E65: Otillåten bakåtreferens"
+
+msgid "E66: \\z( not allowed here"
+msgstr "E66: \\z{ inte tillåtet här"
+
+msgid "E67: \\z1 et al. not allowed here"
+msgstr "E67: \\z1 m.fl. inte tillåtet här"
+
+msgid "E68: Invalid character after \\z"
+msgstr "E68: Ogiltigt tecken efter \\z"
+
+#, c-format
+msgid "E69: Missing ] after %s%%["
+msgstr "E69: Saknar ] efter %s%%["
+
+#, c-format
+msgid "E70: Empty %s%%[]"
+msgstr "E70: Tom %s%%[]"
+
+#, c-format
+msgid "E678: Invalid character after %s%%[dxouU]"
+msgstr "E678: Ogiltigt tecken efter %s%%[dxouU]"
+
+#, c-format
+msgid "E71: Invalid character after %s%%"
+msgstr "E71: Ogiltigt tecken efter %s%%"
+
+#, c-format
+msgid "E769: Missing ] after %s["
+msgstr "E769: Saknar ] efter %s["
+
+#, c-format
+msgid "E554: Syntax error in %s{...}"
+msgstr "E554: Syntaxfel i %s{...}"
+
+msgid "External submatches:\n"
+msgstr "Externa underträffar:\n"
+
+msgid " VREPLACE"
+msgstr " VERSÄTT"
+
+msgid " REPLACE"
+msgstr " ERSÄTT"
+
+msgid " REVERSE"
+msgstr " OMVÄND"
+
+msgid " INSERT"
+msgstr " INFOGA"
+
+msgid " (insert)"
+msgstr " (infoga)"
+
+msgid " (replace)"
+msgstr " (ersätt)"
+
+msgid " (vreplace)"
+msgstr " (versätt)"
+
+msgid " Hebrew"
+msgstr " Hebreiska"
+
+msgid " Arabic"
+msgstr " Arabiska"
+
+msgid " (lang)"
+msgstr " (språk)"
+
+msgid " (paste)"
+msgstr " (klistra in)"
+
+msgid " VISUAL"
+msgstr " VISUELL"
+
+msgid " VISUAL LINE"
+msgstr " VISUELL RAD"
+
+msgid " VISUAL BLOCK"
+msgstr " VISUELLT BLOCK"
+
+msgid " SELECT"
+msgstr " MARKERA"
+
+msgid " SELECT LINE"
+msgstr " MARKERA RAD"
+
+msgid " SELECT BLOCK"
+msgstr " MARKERA BLOCK"
+
+msgid "recording"
+msgstr "spelar in"
+
+#, c-format
+msgid "E383: Invalid search string: %s"
+msgstr "E383: Ogiltig söksträng: %s"
+
+#, c-format
+msgid "E384: search hit TOP without match for: %s"
+msgstr "E384: sökning nådde TOPPEN utan träff av: %s"
+
+#, c-format
+msgid "E385: search hit BOTTOM without match for: %s"
+msgstr "E385: sökning nådde BOTTEN utan träff av: %s"
+
+msgid "E386: Expected '?' or '/' after ';'"
+msgstr "E386: Förväntade '?' eller '/' efter ';'"
+
+msgid " (includes previously listed match)"
+msgstr " (inkluderar tidigare listad träff)"
+
+#. cursor at status line
+msgid "--- Included files "
+msgstr "--- Inkluderade filer "
+
+msgid "not found "
+msgstr "hittades inte "
+
+msgid "in path ---\n"
+msgstr "i sökväg ---\n"
+
+msgid " (Already listed)"
+msgstr " (Redan listade)"
+
+msgid " NOT FOUND"
+msgstr " INTE HITTADE"
+
+#, c-format
+msgid "Scanning included file: %s"
+msgstr "Söker igenom inkluderad fil: %s"
+
+#, c-format
+msgid "Searching included file %s"
+msgstr "Söker igenom inkluderad fil %s"
+
+msgid "E387: Match is on current line"
+msgstr "E387: Matchning är på aktuell rad"
+
+msgid "All included files were found"
+msgstr "Alla inkluderade filer hittades"
+
+msgid "No included files"
+msgstr "Inga inkluderade filer"
+
+msgid "E388: Couldn't find definition"
+msgstr "E388: Kunde inte hitta definition"
+
+msgid "E389: Couldn't find pattern"
+msgstr "E389: Kunde inte hitta mönster"
+
+#, c-format
+msgid ""
+"\n"
+"# Last %sSearch Pattern:\n"
+"~"
+msgstr ""
+"\n"
+"# Senaste %sSökmönster:\n"
+"~"
+
+msgid "E759: Format error in spell file"
+msgstr "E759: Formateringsfel i stavningsfil"
+
+msgid "E758: Truncated spell file"
+msgstr "E758: Trunkerad stavningsfil"
+
+#, c-format
+msgid "Trailing text in %s line %d: %s"
+msgstr "Eftersläpande text i %s rad %d: %s"
+
+#, c-format
+msgid "Affix name too long in %s line %d: %s"
+msgstr "Affix-namn för långt i %s rad %d: %s"
+
+msgid "E761: Format error in affix file FOL, LOW or UPP"
+msgstr "E761: Formateringsfel i affix-fil FOL, LOW eller UPP"
+
+msgid "E762: Character in FOL, LOW or UPP is out of range"
+msgstr "E762: Tecken i FOL, LOW eller UPP är utanför område"
+
+msgid "Compressing word tree..."
+msgstr "Komprimerar ordträd..."
+
+msgid "E756: Spell checking is not enabled"
+msgstr "E756: Stavningskontroll är inte aktiverat"
+
+#, c-format
+msgid "Warning: Cannot find word list \"%s.%s.spl\" or \"%s.ascii.spl\""
+msgstr "Varning: Kan inte hitta ordlista \"%s.%s.spl\" eller \"%s.ascii.spl\""
+
+#, c-format
+msgid "Reading spell file \"%s\""
+msgstr "Läser stavningsfil \"%s\""
+
+msgid "E757: This does not look like a spell file"
+msgstr "E757: Det här ser inte ut som en stavningsfil"
+
+msgid "E771: Old spell file, needs to be updated"
+msgstr "E771: Gammal stavningsfil, behöver bli uppdaterad"
+
+msgid "E772: Spell file is for newer version of Vim"
+msgstr "E772: Stavningsfil är för nyare version av Vim"
+
+msgid "E770: Unsupported section in spell file"
+msgstr "E770: Ostödd sektion i stavningsfil"
+
+#, c-format
+msgid "Warning: region %s not supported"
+msgstr "Varning: region %s stöds inte"
+
+#, c-format
+msgid "Reading affix file %s ..."
+msgstr "Läser affix-fil %s ..."
+
+#, c-format
+msgid "Conversion failure for word in %s line %d: %s"
+msgstr "Konvertering misslyckades för ord i %s rad %d: %s"
+
+#, c-format
+msgid "Conversion in %s not supported: from %s to %s"
+msgstr "Konvertering i %s stöds inte: från %s till %s"
+
+#, c-format
+msgid "Conversion in %s not supported"
+msgstr "Konvertering i %s stöds inte"
+
+#, c-format
+msgid "Invalid value for FLAG in %s line %d: %s"
+msgstr "Ogiltigt värde för FLAG i %s rad %d: %s"
+
+#, c-format
+msgid "FLAG after using flags in %s line %d: %s"
+msgstr "FLAG efter användning av flags i %s rad %d: %s"
+
+#, c-format
+msgid ""
+"Defining COMPOUNDFORBIDFLAG after PFX item may give wrong results in %s line "
+"%d"
+msgstr ""
+"Definiera COMPOUNDFORBIDFLAG efter PFX-post kan ge fel resultat i %s rad %d"
+
+#, c-format
+msgid ""
+"Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in %s line "
+"%d"
+msgstr "Definiera COMPOUNDPERMITFLAG efter PFX-post kan ge fel resultat i %s "
+"rad %d"
+
+#, c-format
+msgid "Wrong COMPOUNDWORDMAX value in %s line %d: %s"
+msgstr "Fel COMPOUNDWORDMAX-värde i %s rad %d: %s"
+
+#, c-format
+msgid "Wrong COMPOUNDMIN value in %s line %d: %s"
+msgstr "Fel COMPOUNDMIN-värde i %s rad %d: %s"
+
+#, c-format
+msgid "Wrong COMPOUNDSYLMAX value in %s line %d: %s"
+msgstr "Fel COMPOUNDSYLMAX-värde i %s rad %d: %s"
+
+#, c-format
+msgid "Wrong CHECKCOMPOUNDPATTERN value in %s line %d: %s"
+msgstr "Fel CHECKCOMPOUNDPATTERN-värde i %s rad %d: %s"
+
+#, c-format
+msgid "Different combining flag in continued affix block in %s line %d: %s"
+msgstr "Annan kombinerande flagga i efterföljande affix-block i %s rad %d: %s"
+
+#, c-format
+msgid "Duplicate affix in %s line %d: %s"
+msgstr "Duplicerad affix i %s rad %d: %s"
+
+#, c-format
+msgid ""
+"Affix also used for BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST in %s "
+"line %d: %s"
+msgstr ""
+"Affix också använd för BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST i %"
+"s rad %d: %s"
+
+#, c-format
+msgid "Expected Y or N in %s line %d: %s"
+msgstr "Förväntade Y eller N i %s rad %d: %s"
+
+#, c-format
+msgid "Broken condition in %s line %d: %s"
+msgstr "Trasigt villkor i %s rad %d: %s"
+
+#, c-format
+msgid "Expected REP(SAL) count in %s line %d"
+msgstr "Förväntade REP(SAL)-antal i %s rad %d"
+
+#, c-format
+msgid "Expected MAP count in %s line %d"
+msgstr "Förväntade MAP-antal i %s rad %d"
+
+#, c-format
+msgid "Duplicate character in MAP in %s line %d"
+msgstr "Duplicerat tecken i MAP i %s rad %d"
+
+#, c-format
+msgid "Unrecognized or duplicate item in %s line %d: %s"
+msgstr "Okänd eller duplicerad post i %s rad %d: %s"
+
+#, c-format
+msgid "Missing FOL/LOW/UPP line in %s"
+msgstr "Saknar FOL/LOW/UPP rad i %s"
+
+msgid "COMPOUNDSYLMAX used without SYLLABLE"
+msgstr "COMPOUNDSYLMAX använd utan SYLLABLE"
+
+msgid "Too many postponed prefixes"
+msgstr "För många uppskjutna prefix"
+
+msgid "Too many compound flags"
+msgstr "För många sammansatta flaggor"
+
+msgid "Too many postponed prefixes and/or compound flags"
+msgstr "För många uppskjutna prefix och/eller sammansatta flaggor"
+
+#, c-format
+msgid "Missing SOFO%s line in %s"
+msgstr "Saknar SOFO%s rad i %s"
+
+#, c-format
+msgid "Both SAL and SOFO lines in %s"
+msgstr "Både SAL och SOFO rader i %s"
+
+#, c-format
+msgid "Flag is not a number in %s line %d: %s"
+msgstr "Flagga är inte ett nummer i %s rad %d: %s"
+
+#, c-format
+msgid "Illegal flag in %s line %d: %s"
+msgstr "Ogiltig flagga i %s rad %d: %s"
+
+#, c-format
+msgid "%s value differs from what is used in another .aff file"
+msgstr "%s värde skiljer sig från vad som används i en annan .aff-fil."
+
+#, c-format
+msgid "Reading dictionary file %s ..."
+msgstr "Läser ordboksfil %s ..."
+
+#, c-format
+msgid "E760: No word count in %s"
+msgstr "E760: Inget ordantal i %s"
+
+#, c-format
+msgid "line %6d, word %6d - %s"
+msgstr "rad %6d, ord %6d - %s"
+
+#, c-format
+msgid "Duplicate word in %s line %d: %s"
+msgstr "Duplicerat ord i %s rad %d: %s"
+
+#, c-format
+msgid "First duplicate word in %s line %d: %s"
+msgstr "Första duplicerade ordet i %s rad %d: %s"
+
+#, c-format
+msgid "%d duplicate word(s) in %s"
+msgstr "%d duplicerade ord i %s"
+
+#, c-format
+msgid "Ignored %d word(s) with non-ASCII characters in %s"
+msgstr "Ignorerade %d ord med icke-ASCII tecken i %s"
+
+#, c-format
+msgid "Reading word file %s ..."
+msgstr "Läser ordfil %s ..."
+
+#, c-format
+msgid "Duplicate /encoding= line ignored in %s line %d: %s"
+msgstr "Duplicerad /encoding=-rad ignorerad i %s rad %d: %s"
+
+#, c-format
+msgid "/encoding= line after word ignored in %s line %d: %s"
+msgstr "/encoding=-rad efter ord ignorerad i %s rad %d: %s"
+
+#, c-format
+msgid "Duplicate /regions= line ignored in %s line %d: %s"
+msgstr "Duplicerad /regions=-rad ignorerad i %s rad %d: %s"
+
+#, c-format
+msgid "Too many regions in %s line %d: %s"
+msgstr "För många regioner i %s rad %d: %s"
+
+#, c-format
+msgid "/ line ignored in %s line %d: %s"
+msgstr "/-rad ignorerad i %s rad %d: %s"
+
+#, c-format
+msgid "Invalid region nr in %s line %d: %s"
+msgstr "Ogiltigt regionsnr i %s rad %d: %s"
+
+#, c-format
+msgid "Unrecognized flags in %s line %d: %s"
+msgstr "Okända flaggot i %s rad %d: %s"
+
+#, c-format
+msgid "Ignored %d words with non-ASCII characters"
+msgstr "Ignorerade %d ord med icke-ASCII tecken"
+
+#, c-format
+msgid "Compressed %d of %d nodes; %d (%d%%) remaining"
+msgstr "Komprimerade %d av %d noder; %d (%d%%) återstår"
+
+msgid "Reading back spell file..."
+msgstr "Läser tillbaka stavningsfil..."
+
+#.
+#. * Go through the trie of good words, soundfold each word and add it to
+#. * the soundfold trie.
+#.
+msgid "Performing soundfolding..."
+msgstr "Utför ljudvikning..."
+
+#, c-format
+msgid "Number of words after soundfolding: %ld"
+msgstr "Antal ord efter ljudvikning: %ld"
+
+#, c-format
+msgid "Total number of words: %d"
+msgstr "Totalt antal ord: %d"
+
+#, c-format
+msgid "Writing suggestion file %s ..."
+msgstr "Skriver förslagsfil %s ..."
+
+#, c-format
+msgid "Estimated runtime memory use: %d bytes"
+msgstr "Beräknat körtidsminne använt: %d byte"
+
+msgid "E751: Output file name must not have region name"
+msgstr "E751: Utmatningsfilnamn får inte ha regionnamn"
+
+msgid "E754: Only up to 8 regions supported"
+msgstr "E754: Bara upp till 8 regioner stöds"
+
+#, c-format
+msgid "E755: Invalid region in %s"
+msgstr "E755: Ogiltig region i %s"
+
+msgid "Warning: both compounding and NOBREAK specified"
+msgstr "Varning: både sammansättning och NOBREAK specifierad"
+
+#, c-format
+msgid "Writing spell file %s ..."
+msgstr "Skriver stavningsfil %s ..."
+
+msgid "Done!"
+msgstr "Klar!"
+
+#, c-format
+msgid "E765: 'spellfile' does not have %ld entries"
+msgstr "E765: 'spellfile' har inte %ld poster"
+
+#, c-format
+msgid "Word removed from %s"
+msgstr "Ord borttaget från %s"
+
+#, c-format
+msgid "Word added to %s"
+msgstr "Ord lagd till %s"
+
+msgid "E763: Word characters differ between spell files"
+msgstr "E763: Ordtecken skiljer sig mellan stavningsfiler"
+
+msgid "Sorry, no suggestions"
+msgstr "Tyvärr, inga föreslag"
+
+#, c-format
+msgid "Sorry, only %ld suggestions"
+msgstr "Tyvärr, bara %ld föreslag"
+
+#. for when 'cmdheight' > 1
+#. avoid more prompt
+#, c-format
+msgid "Change \"%.*s\" to:"
+msgstr "Ändra \"%.*s\" till:"
+
+#, c-format
+msgid " < \"%.*s\""
+msgstr " < \"%.*s\""
+
+msgid "E752: No previous spell replacement"
+msgstr "E752: Ingen tidigare stavningsersättning"
+
+#, c-format
+msgid "E753: Not found: %s"
+msgstr "E753: Hittades inte: %s"
+
+#, c-format
+msgid "E778: This does not look like a .sug file: %s"
+msgstr "E778: Det här ser inte ut som en .sug-fil: %s"
+
+#, c-format
+msgid "E779: Old .sug file, needs to be updated: %s"
+msgstr "E779: Gammal .sug-fil, behöver bli uppdaterad: %s"
+
+#, c-format
+msgid "E780: .sug file is for newer version of Vim: %s"
+msgstr "E780: .sug-fil är för nyare version av Vim: %s"
+
+#, c-format
+msgid "E781: .sug file doesn't match .spl file: %s"
+msgstr "E781: .sug-fil matchar inte .spl-fil: %s"
+
+#, c-format
+msgid "E782: error while reading .sug file: %s"
+msgstr "E782: fel vid läsning av .sug-fil: %s"
+
+#. This should have been checked when generating the .spl
+#. * file.
+msgid "E783: duplicate char in MAP entry"
+msgstr "E783: dubblerat tecken i MAP-post"
+
+#, c-format
+msgid "E390: Illegal argument: %s"
+msgstr "E390: Otillåtet argument: %s"
+
+#, c-format
+msgid "E391: No such syntax cluster: %s"
+msgstr "E391: Inget sådant syntax-kluster: %s"
+
+msgid "No Syntax items defined for this buffer"
+msgstr "Inga syntax-föremål definierade för den här bufferten"
+
+msgid "syncing on C-style comments"
+msgstr "synkning av C-stil-kommentarer"
+
+msgid "no syncing"
+msgstr "ingen synkning"
+
+msgid "syncing starts "
+msgstr "synkning startar"
+
+msgid " lines before top line"
+msgstr " rader före topprad"
+
+msgid ""
+"\n"
+"--- Syntax sync items ---"
+msgstr ""
+"\n"
+"--- Syntax-synkföremål ---"
+
+msgid ""
+"\n"
+"syncing on items"
+msgstr ""
+"\n"
+"synkning av föremål"
+
+msgid ""
+"\n"
+"--- Syntax items ---"
+msgstr ""
+"\n"
+"--- Syntax föremål ---"
+
+#, c-format
+msgid "E392: No such syntax cluster: %s"
+msgstr "E392: Inga sådana syntaxkluster: %s"
+
+msgid "minimal "
+msgstr "minimal "
+
+msgid "maximal "
+msgstr "maximal "
+
+msgid "; match "
+msgstr "; träff "
+
+msgid " line breaks"
+msgstr " radbrytningar"
+
+msgid "E395: contains argument not accepted here"
+msgstr "E395: innehåller argument som inte är tillåtna här"
+
+msgid "E396: containedin argument not accepted here"
+msgstr "E396: innehöll argument som inte är tillåtna här"
+
+msgid "E393: group[t]here not accepted here"
+msgstr "E393: grupper inte tillåtna här"
+
+#, c-format
+msgid "E394: Didn't find region item for %s"
+msgstr "E394: Hittade inte regionföremål för %s"
+
+msgid "E397: Filename required"
+msgstr "E397: Filnamn krävs"
+
+#, c-format
+msgid "E789: Missing ']': %s"
+msgstr "E789: Saknar ']': %s"
+
+#, c-format
+msgid "E398: Missing '=': %s"
+msgstr "E398: Saknar '=': %s"
+
+#, c-format
+msgid "E399: Not enough arguments: syntax region %s"
+msgstr "E399: Inte tillräckliga argument: syntaxregion %s"
+
+msgid "E400: No cluster specified"
+msgstr "E400: Inget kluster angivet"
+
+#, c-format
+msgid "E401: Pattern delimiter not found: %s"
+msgstr "E401: Mönsteravgränsare hittades inte: %s"
+
+#, c-format
+msgid "E402: Garbage after pattern: %s"
+msgstr "E402: Skräp efter mönster: %s"
+
+msgid "E403: syntax sync: line continuations pattern specified twice"
+msgstr "E403: syntax-synk: radfortsättningsmönster angivet två gånger"
+
+#, c-format
+msgid "E404: Illegal arguments: %s"
+msgstr "E404: Otillåtna argument: %s"
+
+#, c-format
+msgid "E405: Missing equal sign: %s"
+msgstr "E405: Saknar likamed-tecken: %s"
+
+#, c-format
+msgid "E406: Empty argument: %s"
+msgstr "E406: Tomt argument: %s"
+
+#, c-format
+msgid "E407: %s not allowed here"
+msgstr "E407: %s inte tillåtet här"
+
+#, c-format
+msgid "E408: %s must be first in contains list"
+msgstr "E408: %s måste vara först i innehållslista"
+
+#, c-format
+msgid "E409: Unknown group name: %s"
+msgstr "E409: Okänt gruppnamn: %s"
+
+#, c-format
+msgid "E410: Invalid :syntax subcommand: %s"
+msgstr "E410: Ogiltigt :syntax-underkommando: %s"
+
+msgid "E679: recursive loop loading syncolor.vim"
+msgstr "E679: rekursiv loop laddar syncolor.vim"
+
+#, c-format
+msgid "E411: highlight group not found: %s"
+msgstr "E411: framhävningsgrupp hittades inte: %s"
+
+#, c-format
+msgid "E412: Not enough arguments: \":highlight link %s\""
+msgstr "E412: Inte tillräckliga argument: \":highlight länk %s\""
+
+#, c-format
+msgid "E413: Too many arguments: \":highlight link %s\""
+msgstr "E413: För många argument: \":highlight länk %s\""
+
+msgid "E414: group has settings, highlight link ignored"
+msgstr "E414: grupp har inställningar, framhävningslänk ignorerad"
+
+#, c-format
+msgid "E415: unexpected equal sign: %s"
+msgstr "E415: oväntat likamed-tecken: %s"
+
+#, c-format
+msgid "E416: missing equal sign: %s"
+msgstr "E416: saknar likamed-tecken: %s"
+
+#, c-format
+msgid "E417: missing argument: %s"
+msgstr "E417: saknar argument: %s"
+
+#, c-format
+msgid "E418: Illegal value: %s"
+msgstr "E418: Otillåtet värde: %s"
+
+msgid "E419: FG color unknown"
+msgstr "E419: FG-färg okänd"
+
+msgid "E420: BG color unknown"
+msgstr "E420: BG-färg okänd"
+
+#, c-format
+msgid "E421: Color name or number not recognized: %s"
+msgstr "E421: Färgnamn eller nummer inte igenkänt: %s"
+
+#, c-format
+msgid "E422: terminal code too long: %s"
+msgstr "E422: terminalkod för lång: %s"
+
+#, c-format
+msgid "E423: Illegal argument: %s"
+msgstr "E423: Otillåtet argument: %s"
+
+msgid "E424: Too many different highlighting attributes in use"
+msgstr "E424: För många olika framhävningsattribut i användning"
+
+msgid "E669: Unprintable character in group name"
+msgstr "E669: Outskrivbart tecken i gruppnamn"
+
+msgid "W18: Invalid character in group name"
+msgstr "W18: Ogiltigt tecken i gruppnamn"
+
+msgid "E555: at bottom of tag stack"
+msgstr "E555: på botten av taggstack"
+
+msgid "E556: at top of tag stack"
+msgstr "E556: på toppen av taggstack"
+
+msgid "E425: Cannot go before first matching tag"
+msgstr "E425: Kan inte gå före första matchande tagg"
+
+#, c-format
+msgid "E426: tag not found: %s"
+msgstr "E426: tagg hittades inte: %s"
+
+msgid " # pri kind tag"
+msgstr " # pri-typ-tagg"
+
+msgid "file\n"
+msgstr "fil\n"
+
+msgid "E427: There is only one matching tag"
+msgstr "E427: Det finns bara en matchande tagg"
+
+msgid "E428: Cannot go beyond last matching tag"
+msgstr "E428: Kan inte gå bortom sista matchande tagg"
+
+#, c-format
+msgid "File \"%s\" does not exist"
+msgstr "Fil \"%s\" existerar inte"
+
+#. Give an indication of the number of matching tags
+#, c-format
+msgid "tag %d of %d%s"
+msgstr "tagg %d av %d%s"
+
+msgid " or more"
+msgstr " eller fler"
+
+msgid " Using tag with different case!"
+msgstr " Använder tagg med annan storlek!"
+
+#, c-format
+msgid "E429: File \"%s\" does not exist"
+msgstr "E429: Fil \"%s\" existerar inte"
+
+#. Highlight title
+msgid ""
+"\n"
+" # TO tag FROM line in file/text"
+msgstr ""
+"\n"
+" # TILL tagg FRÅN LINJE i fil/text"
+
+#, c-format
+msgid "Searching tags file %s"
+msgstr "Söker tagg-fil %s"
+
+#, c-format
+msgid "E430: Tag file path truncated for %s\n"
+msgstr "E430: Taggfilsökväg trunkerades för %s\n"
+
+#, c-format
+msgid "E431: Format error in tags file \"%s\""
+msgstr "E431: Formateringsfel i tagg-fil \"%s\""
+
+#, c-format
+msgid "Before byte %ld"
+msgstr "Före byte %ld"
+
+#, c-format
+msgid "E432: Tags file not sorted: %s"
+msgstr "E432: Tagg-fil inte sorterad: %s"
+
+#. never opened any tags file
+msgid "E433: No tags file"
+msgstr "E433: Ingen tagg-fil"
+
+msgid "E434: Can't find tag pattern"
+msgstr "E434: Kan inte hitta taggmönster"
+
+msgid "E435: Couldn't find tag, just guessing!"
+msgstr "E435: Kunde inte hitta tagg, gissar bara!"
+
+msgid "' not known. Available builtin terminals are:"
+msgstr "' inte känd. Tillgängliga inbyggda terminaler är:"
+
+msgid "defaulting to '"
+msgstr "använder standard '"
+
+msgid "E557: Cannot open termcap file"
+msgstr "E557: Kan inte öppna termcap-fil"
+
+msgid "E558: Terminal entry not found in terminfo"
+msgstr "E558: Terminalnotering hittades inte i terminfo"
+
+msgid "E559: Terminal entry not found in termcap"
+msgstr "E559: Terminalnotering hittades inte i termcap"
+
+#, c-format
+msgid "E436: No \"%s\" entry in termcap"
+msgstr "E436: Ingen \"%s\"-notering i termcap"
+
+msgid "E437: terminal capability \"cm\" required"
+msgstr "E437: terminalkapacitet \"cm\" krävs"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Terminal keys ---"
+msgstr ""
+"\n"
+"--- Terminalnycklar ---"
+
+msgid "new shell started\n"
+msgstr "nytt skal startat\n"
+
+msgid "Vim: Error reading input, exiting...\n"
+msgstr "Vim: Fel vid läsning av inmatning, avslutar...\n"
+
+#. must display the prompt
+msgid "No undo possible; continue anyway"
+msgstr "Ingen ångring möjlig; fortsätter ändå"
+
+msgid "Already at oldest change"
+msgstr "Redan vid äldsta ändring"
+
+msgid "Already at newest change"
+msgstr "Redan vid nyaste ändring"
+
+#, c-format
+msgid "Undo number %ld not found"
+msgstr "Ångra-nummer %ld hittades inte"
+
+msgid "E438: u_undo: line numbers wrong"
+msgstr "E438: u_undo: radnummer fel"
+
+msgid "more line"
+msgstr "en rad till"
+
+msgid "more lines"
+msgstr "fler rader"
+
+msgid "line less"
+msgstr "en rad mindre"
+
+msgid "fewer lines"
+msgstr "färre rader"
+
+msgid "change"
+msgstr "ändring"
+
+msgid "changes"
+msgstr "ändringar"
+
+#, c-format
+msgid "%ld %s; %s #%ld %s"
+msgstr "%ld %s; %s #%ld %s"
+
+msgid "before"
+msgstr "före"
+
+msgid "after"
+msgstr "efter"
+
+msgid "Nothing to undo"
+msgstr "Inget att ångra"
+
+msgid "number changes time"
+msgstr "antal ändringar tid"
+
+#, c-format
+msgid "%ld seconds ago"
+msgstr "%ld sekunder sedan"
+
+msgid "E790: undojoin is not allowed after undo"
+msgstr "E790: undojoin är inte tillåtet efter undo"
+
+msgid "E439: undo list corrupt"
+msgstr "E439: ångra-lista trasig"
+
+msgid "E440: undo line missing"
+msgstr "E440: ångra-rad saknas"
+
+#. Only MS VC 4.1 and earlier can do Win32s
+msgid ""
+"\n"
+"MS-Windows 16/32-bit GUI version"
+msgstr ""
+"\n"
+"MS-Windows 16/32-bitars GUI-version"
+
+msgid ""
+"\n"
+"MS-Windows 64-bit GUI version"
+msgstr ""
+"\n"
+"MS-Windows 64-bitars GUI-version"
+
+msgid ""
+"\n"
+"MS-Windows 32-bit GUI version"
+msgstr ""
+"\n"
+"MS-Windows 32-bitars GUI-version"
+
+msgid " in Win32s mode"
+msgstr " i Win32s-läge"
+
+msgid " with OLE support"
+msgstr " med OLE-stöd"
+
+msgid ""
+"\n"
+"MS-Windows 32-bit console version"
+msgstr ""
+"\n"
+"MS-Windows 32-bitars konsollversion"
+
+msgid ""
+"\n"
+"MS-Windows 16-bit version"
+msgstr ""
+"\n"
+"MS-Windows 16-bitars version"
+
+msgid ""
+"\n"
+"32-bit MS-DOS version"
+msgstr ""
+"\n"
+"32-bitars MS-DOS-version"
+
+msgid ""
+"\n"
+"16-bit MS-DOS version"
+msgstr ""
+"\n"
+"16-bitars MS-DOS-version"
+
+msgid ""
+"\n"
+"MacOS X (unix) version"
+msgstr ""
+"\n"
+"MacOS X-version (unix)"
+
+msgid ""
+"\n"
+"MacOS X version"
+msgstr ""
+"\n"
+"MacOS X-version"
+
+msgid ""
+"\n"
+"MacOS version"
+msgstr ""
+"\n"
+"MacOS-version"
+
+msgid ""
+"\n"
+"RISC OS version"
+msgstr ""
+"\n"
+"RISC OS-version"
+
+msgid ""
+"\n"
+"Included patches: "
+msgstr ""
+"\n"
+"Inkluderade patchar: "
+
+msgid "Modified by "
+msgstr "Modifierad av "
+
+msgid ""
+"\n"
+"Compiled "
+msgstr ""
+"\n"
+"Kompilerad "
+
+msgid "by "
+msgstr "av "
+
+msgid ""
+"\n"
+"Huge version "
+msgstr ""
+"\n"
+"Enorm version "
+
+msgid ""
+"\n"
+"Big version "
+msgstr ""
+"\n"
+"Stor version "
+
+msgid ""
+"\n"
+"Normal version "
+msgstr ""
+"\n"
+"Normal version "
+
+msgid ""
+"\n"
+"Small version "
+msgstr ""
+"\n"
+"Liten version "
+
+msgid ""
+"\n"
+"Tiny version "
+msgstr ""
+"\n"
+"Jätteliten version "
+
+msgid "without GUI."
+msgstr "utan GUI."
+
+msgid "with GTK2-GNOME GUI."
+msgstr "med GTK2-GNOME-GUI."
+
+msgid "with GTK-GNOME GUI."
+msgstr "med GTK-GNOME-GUI."
+
+msgid "with GTK2 GUI."
+msgstr "med GTK2-GUI."
+
+msgid "with GTK GUI."
+msgstr "med GTK-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 "with (classic) GUI."
+msgstr "med (klassiskt) GUI."
+
+msgid " Features included (+) or not (-):\n"
+msgstr " Funktioner inkluderade (+) eller inte (-):\n"
+
+msgid " system vimrc file: \""
+msgstr " system-vimrc-fil: \""
+
+msgid " user vimrc file: \""
+msgstr " användar-vimrc-fil: \""
+
+msgid " 2nd user vimrc file: \""
+msgstr " Andra användar-vimrc-fil: \""
+
+msgid " 3rd user vimrc file: \""
+msgstr " Tredje användar-vimrc-fil: \""
+
+msgid " user exrc file: \""
+msgstr " användar-exrc-fil: \""
+
+msgid " 2nd user exrc file: \""
+msgstr " Andra användar-exrc-fil: \""
+
+msgid " system gvimrc file: \""
+msgstr " system-gvimrc-fil: \""
+
+msgid " user gvimrc file: \""
+msgstr " användar-gvimrc-fil: \""
+
+msgid "2nd user gvimrc file: \""
+msgstr "Andra användar-gvimrc-fil: \""
+
+msgid "3rd user gvimrc file: \""
+msgstr "Tredje användar-gvimrc-fil: \""
+
+msgid " system menu file: \""
+msgstr " systemmenyfil: \""
+
+msgid " fall-back for $VIM: \""
+msgstr " reserv för $VIM: \""
+
+msgid " f-b for $VIMRUNTIME: \""
+msgstr " reserv för $VIMRUNTIME: \""
+
+msgid "Compilation: "
+msgstr "Kompilering: "
+
+msgid "Compiler: "
+msgstr "Kompilator: "
+
+msgid "Linking: "
+msgstr "Länkning: "
+
+msgid " DEBUG BUILD"
+msgstr " FELSÖKNINGSBYGGD"
+
+msgid "VIM - Vi IMproved"
+msgstr "VIM - Vi IMproved"
+
+msgid "version "
+msgstr "version "
+
+msgid "by Bram Moolenaar et al."
+msgstr "av Bram Moolenaar m.fl."
+
+msgid "Vim is open source and freely distributable"
+msgstr "Vim är öppen källkod och fri att distribuera"
+
+msgid "Help poor children in Uganda!"
+msgstr "Hjälp fattiga barn i Uganda!"
+
+msgid "type :help iccf<Enter> for information "
+msgstr "skriv :help iccf<Enter> för information "
+
+msgid "type :q<Enter> to exit "
+msgstr "skriv :q<Enter> för att avsluta "
+
+msgid "type :help<Enter> or <F1> for on-line help"
+msgstr "skriv :help<Enter> eller <F1> för online-hjälp "
+
+msgid "type :help version7<Enter> for version info"
+msgstr "skriv :help version7<Enter> för versioninformation "
+
+msgid "Running in Vi compatible mode"
+msgstr "Kör i Vi-kompatibelt läge"
+
+msgid "type :set nocp<Enter> for Vim defaults"
+msgstr "skriv :set nocp<Enter> för Vim- standarder "
+
+msgid "type :help cp-default<Enter> for info on this"
+msgstr "skriv :help cp-default<Enter> för information om det här"
+
+msgid "menu Help->Orphans for information "
+msgstr "meny Hjälp->Föräldralösa för information "
+
+msgid "Running modeless, typed text is inserted"
+msgstr "Kör lägeslöst, skriven text blir infogad"
+
+msgid "menu Edit->Global Settings->Toggle Insert Mode "
+msgstr "meny Redigera->Globala inställningar->Växla infogningsläge "
+
+msgid " for two modes "
+msgstr " för två lägen "
+
+msgid "menu Edit->Global Settings->Toggle Vi Compatible"
+msgstr "meny Redigera->Globala Inställningar->Växla Vi Komptaibel"
+
+msgid " for Vim defaults "
+msgstr " för vim-standardalternativ "
+
+msgid "Sponsor Vim development!"
+msgstr "Stöd utvecklingen av Vim!"
+
+msgid "Become a registered Vim user!"
+msgstr "Bli en registrerad Vim-användare!"
+
+msgid "type :help sponsor<Enter> for information "
+msgstr "skriv :help sponsor<Enter> för information "
+
+msgid "type :help register<Enter> for information "
+msgstr "skriv :help register<Enter> för information "
+
+msgid "menu Help->Sponsor/Register for information "
+msgstr "meny Hjälp->Stöd/Registrera för information "
+
+msgid "WARNING: Windows 95/98/ME detected"
+msgstr "VARNING: Windows 95/98/ME upptäckt"
+
+msgid "type :help windows95<Enter> for info on this"
+msgstr "skriv :help windows95<Enter> för info om det här"
+
+msgid "Already only one window"
+msgstr "Redan bara ett fönster"
+
+msgid "E441: There is no preview window"
+msgstr "E441: Det finns inget förhandsvisningsfönster"
+
+msgid "E442: Can't split topleft and botright at the same time"
+msgstr "E442: Kan inte dela toppvänster och bottenhöger samtidigt"
+
+msgid "E443: Cannot rotate when another window is split"
+msgstr "E443: Kan inte rotera när ett annat fönster är delat"
+
+msgid "E444: Cannot close last window"
+msgstr "E444: Kan inte stänga senaste fönstret"
+
+msgid "E445: Other window contains changes"
+msgstr "E445: Andra fönster innehåller ändringar"
+
+msgid "E446: No file name under cursor"
+msgstr "E446: Inget filnamn under markör"
+
+#, c-format
+msgid "E447: Can't find file \"%s\" in path"
+msgstr "E447: Kan inte hitta fil \"%s\" i sökväg"
+
+#, c-format
+msgid "E370: Could not load library %s"
+msgstr "E370: Kunde inte läsa in bibliotek %s"
+
+msgid "Sorry, this command is disabled: the Perl library could not be loaded."
+msgstr ""
+"Tyvärr, det här kommandot är inaktiverat: Perl-biblioteket kunde inte läsas "
+"in."
+
+msgid "E299: Perl evaluation forbidden in sandbox without the Safe module"
+msgstr "E299: Perl-evaluering förbjuden i sandlåda utan Safe-modulen"
+
+msgid "Edit with &multiple Vims"
+msgstr "Redigera med &flera Vims"
+
+msgid "Edit with single &Vim"
+msgstr "Redigera med en &Vim"
+
+msgid "Diff with Vim"
+msgstr "Diff med Vim"
+
+msgid "Edit with &Vim"
+msgstr "Redigera med &Vim"
+
+#. Now concatenate
+msgid "Edit with existing Vim - "
+msgstr "Redigera med befintlig Vim - "
+
+msgid "Edits the selected file(s) with Vim"
+msgstr "Redigerar markerade fil(erna) med Vim"
+
+msgid "Error creating process: Check if gvim is in your path!"
+msgstr "Felskapande process: Kontrollera om gvim är i din sökväg!"
+
+msgid "gvimext.dll error"
+msgstr "gvimext.dll-fel"
+
+msgid "Path length too long!"
+msgstr "Sökvägslängd för lång!"
+
+msgid "--No lines in buffer--"
+msgstr "--Inga rader i buffert--"
+
+#.
+#. * 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: Kommando avbrutet"
+
+msgid "E471: Argument required"
+msgstr "E471: Argument krävs"
+
+msgid "E10: \\ should be followed by /, ? or &"
+msgstr "E10: \\ borde följas av /, ? eller &"
+
+msgid "E11: Invalid in command-line window; <CR> executes, CTRL-C quits"
+msgstr "E11: Felaktighet i kommandoradsfönster; <CR> kör, CTRL-C avslutar"
+
+msgid "E12: Command not allowed from exrc/vimrc in current dir or tag search"
+msgstr ""
+"E12: Kommando inte tillåtet från exrc/vimrc i aktuell katalog eller "
+"taggsökning"
+
+msgid "E171: Missing :endif"
+msgstr "E171: Saknar :endif"
+
+msgid "E600: Missing :endtry"
+msgstr "E600: Saknar :endtry"
+
+msgid "E170: Missing :endwhile"
+msgstr "E170: Saknar :endwhile"
+
+msgid "E170: Missing :endfor"
+msgstr "E170: Saknar :endfor"
+
+msgid "E588: :endwhile without :while"
+msgstr "E588: :endwhile utan :while"
+
+msgid "E588: :endfor without :for"
+msgstr "E588: :endfor utan :for"
+
+msgid "E13: File exists (add ! to override)"
+msgstr "E13: Fil existerar (lägg till ! för att tvinga)"
+
+msgid "E472: Command failed"
+msgstr "E472: Kommando misslyckades"
+
+#, c-format
+msgid "E234: Unknown fontset: %s"
+msgstr "E234: Okänd typsnittsuppsättning: %s"
+
+#, c-format
+msgid "E235: Unknown font: %s"
+msgstr "E235: Okänt typsnitt: %s"
+
+#, c-format
+msgid "E236: Font \"%s\" is not fixed-width"
+msgstr "E236: Typsnitt \"%s\" är inte bredd-fixerad"
+
+msgid "E473: Internal error"
+msgstr "E473: Internt fel"
+
+msgid "Interrupted"
+msgstr "Avbruten"
+
+msgid "E14: Invalid address"
+msgstr "E14: Ogiltig address"
+
+msgid "E474: Invalid argument"
+msgstr "E474: Ogiltigt argument"
+
+#, c-format
+msgid "E475: Invalid argument: %s"
+msgstr "E475: Ogiltigt argument: %s"
+
+#, c-format
+msgid "E15: Invalid expression: %s"
+msgstr "E15: Ogiltigt uttryck: %s"
+
+msgid "E16: Invalid range"
+msgstr "E16: Ogiltigt område"
+
+msgid "E476: Invalid command"
+msgstr "E476: Ogiltigt kommando"
+
+#, c-format
+msgid "E17: \"%s\" is a directory"
+msgstr "E17: \"%s\" är en katalog"
+
+#, c-format
+msgid "E364: Library call failed for \"%s()\""
+msgstr "E364: Biblioteksanrop misslyckades för \"%s()\""
+
+#, c-format
+msgid "E448: Could not load library function %s"
+msgstr "E448: Kunde inte läsa in biblioteksfunktion %s"
+
+msgid "E19: Mark has invalid line number"
+msgstr "E19: Markering har ogiltigt radnummer"
+
+msgid "E20: Mark not set"
+msgstr "E20: Markering inte satt"
+
+msgid "E21: Cannot make changes, 'modifiable' is off"
+msgstr "E21: Kan inte göra ändringar, 'modifiable' är av"
+
+msgid "E22: Scripts nested too deep"
+msgstr "E22: Skript nästlade för djupt"
+
+msgid "E23: No alternate file"
+msgstr "E23: Ingen alternativ fil"
+
+msgid "E24: No such abbreviation"
+msgstr "E24: Ingen sådan förkortning"
+
+msgid "E477: No ! allowed"
+msgstr "E477: Inget ! tillåtet"
+
+msgid "E25: GUI cannot be used: Not enabled at compile time"
+msgstr "E25: GUI kan inte användas: Inte aktiverat vid kompilering"
+
+msgid "E26: Hebrew cannot be used: Not enabled at compile time\n"
+msgstr "E26: Hebreiska kan inte användas: Inte aktiverat vid kompilering\n"
+
+msgid "E27: Farsi cannot be used: Not enabled at compile time\n"
+msgstr "E27: Persiska kan inte användas: Inte aktiverat vid kompilering\n"
+
+msgid "E800: Arabic cannot be used: Not enabled at compile time\n"
+msgstr "E800: Arabiska kan inte användas: Inte aktiverat vid kompilering\n"
+
+#, c-format
+msgid "E28: No such highlight group name: %s"
+msgstr "E28: Inget sådant framhävningsgruppnamn: %s"
+
+msgid "E29: No inserted text yet"
+msgstr "E29: Ingen infogad text än"
+
+msgid "E30: No previous command line"
+msgstr "E30: Ingen tidigare kommandorad"
+
+msgid "E31: No such mapping"
+msgstr "E31: Ingen sådan mappning"
+
+msgid "E479: No match"
+msgstr "E479: Ingen träff"
+
+#, c-format
+msgid "E480: No match: %s"
+msgstr "E480: Ingen träff: %s"
+
+msgid "E32: No file name"
+msgstr "E32: Inget filnamn"
+
+msgid "E33: No previous substitute regular expression"
+msgstr "E33: Inget tidigare utbytningsreguljäruttryck"
+
+msgid "E34: No previous command"
+msgstr "E34: Inget tidigare kommando"
+
+msgid "E35: No previous regular expression"
+msgstr "E35: Inget tidigare reguljärt uttryck"
+
+msgid "E481: No range allowed"
+msgstr "E481: Inget område tillåtet"
+
+msgid "E36: Not enough room"
+msgstr "E36: Inte tillräckligt med utrymme"
+
+#, c-format
+msgid "E247: no registered server named \"%s\""
+msgstr "E247: ingen registrerad server med namnet \"%s\""
+
+#, c-format
+msgid "E482: Can't create file %s"
+msgstr "E482: Kan inte skapa fil %s"
+
+msgid "E483: Can't get temp file name"
+msgstr "E483: Kan inte hämta temporärt filnamn"
+
+#, c-format
+msgid "E484: Can't open file %s"
+msgstr "E484: Kan inte öppna fil %s"
+
+#, c-format
+msgid "E485: Can't read file %s"
+msgstr "E485: Kan inte läsa fil %s"
+
+msgid "E37: No write since last change (add ! to override)"
+msgstr ""
+"E37: Ingen skrivning sedan senaste ändring (lägg till ! för att tvinga)"
+
+msgid "E38: Null argument"
+msgstr "E38: Null-argument"
+
+msgid "E39: Number expected"
+msgstr "E39: Nummer väntat"
+
+#, c-format
+msgid "E40: Can't open errorfile %s"
+msgstr "E40: Kan inte öppna felfil %s"
+
+msgid "E233: cannot open display"
+msgstr "E233: kan inte öppna display"
+
+msgid "E41: Out of memory!"
+msgstr "E41: Slut på minne!"
+
+msgid "Pattern not found"
+msgstr "Mönster hittades inte"
+
+#, c-format
+msgid "E486: Pattern not found: %s"
+msgstr "E486: Mönster hittades inte: %s"
+
+msgid "E487: Argument must be positive"
+msgstr "E487: Argument måste vara positivt"
+
+msgid "E459: Cannot go back to previous directory"
+msgstr "E459: Kan inte gå tillbaka till tidigare katalog"
+
+msgid "E42: No Errors"
+msgstr "E42: Inga fel"
+
+msgid "E776: No location list"
+msgstr "E776: Ingen positionslista"
+
+msgid "E43: Damaged match string"
+msgstr "E43: Skadad träffsträng"
+
+msgid "E44: Corrupted regexp program"
+msgstr "E44: Trasigt program för reguljära uttryck"
+
+msgid "E45: 'readonly' option is set (add ! to override)"
+msgstr "E45: 'readonly' flagga är satt (lägg till ! för att tvinga)"
+
+#, c-format
+msgid "E46: Cannot change read-only variable \"%s\""
+msgstr "E46: Kan inte ändra skrivskyddad variabel \"%s\""
+
+#, c-format
+msgid "E794: Cannot set variable in the sandbox: \"%s\""
+msgstr "E794: Kan inte sätta variabel i sandlådan: \"%s\""
+
+msgid "E47: Error while reading errorfile"
+msgstr "E47: Fel vid läsning av felfil"
+
+msgid "E48: Not allowed in sandbox"
+msgstr "E48: Inte tillåtet i sandlåda"
+
+msgid "E523: Not allowed here"
+msgstr "E523: Inte tillåtet här"
+
+msgid "E359: Screen mode setting not supported"
+msgstr "E359: Skärmläge inställning stöds inte"
+
+msgid "E49: Invalid scroll size"
+msgstr "E49: Ogiltig rullningsstorlek"
+
+msgid "E91: 'shell' option is empty"
+msgstr "E91: 'shell' flagga är tom"
+
+msgid "E255: Couldn't read in sign data!"
+msgstr "E255: Kunde inte läsa in teckendata!"
+
+msgid "E72: Close error on swap file"
+msgstr "E72: Stängningsfel på växlingsfil"
+
+msgid "E73: tag stack empty"
+msgstr "E73: taggstack tom"
+
+msgid "E74: Command too complex"
+msgstr "E74: Kommando för komplext"
+
+msgid "E75: Name too long"
+msgstr "E75: Namn för långt"
+
+msgid "E76: Too many ["
+msgstr "E76: För många ["
+
+msgid "E77: Too many file names"
+msgstr "E77: För många filnamn"
+
+msgid "E488: Trailing characters"
+msgstr "E488: Eftersläpande tecken"
+
+msgid "E78: Unknown mark"
+msgstr "E78: Okänt märke"
+
+msgid "E79: Cannot expand wildcards"
+msgstr "E79: Kan inte expandera jokertecken"
+
+msgid "E591: 'winheight' cannot be smaller than 'winminheight'"
+msgstr "E591: 'winheight' kan inte vara mindre än 'winminheight'"
+
+msgid "E592: 'winwidth' cannot be smaller than 'winminwidth'"
+msgstr "E592: 'winwidth' kan inte vara mindre än 'winminwidth'"
+
+msgid "E80: Error while writing"
+msgstr "E80: Fel vid skrivning"
+
+msgid "Zero count"
+msgstr "Noll-längd"
+
+msgid "E81: Using <SID> not in a script context"
+msgstr "E81: Använder inte <SID> i ett skriptsammanhang"
+
+msgid "E449: Invalid expression received"
+msgstr "E449: Ogiltigt uttryck mottaget"
+
+msgid "E463: Region is guarded, cannot modify"
+msgstr "E463: Region är vaktad, kan inte modifiera"
+
+msgid "E744: NetBeans does not allow changes in read-only files"
+msgstr "E744: NetBeans tillåter inte ändringar i skrivskyddade filer"
+
+#, c-format
+msgid "E685: Internal error: %s"
+msgstr "E685: Internt fel: %s"
+
+msgid "E363: pattern uses more memory than 'maxmempattern'"
+msgstr "E363: mönster använder mer minne än 'maxmempattern'"
+
+msgid "E749: empty buffer"
+msgstr "E749: tom buffert"
+
+msgid "E682: Invalid search pattern or delimiter"
+msgstr "E682: Ogiltigt sökmönster eller delimiter"
+
+msgid "E139: File is loaded in another buffer"
+msgstr "E139: Filen är inläst i en annan buffert"
+
+#, c-format
+msgid "E764: Option '%s' is not set"
+msgstr "E764: Flagga '%s' är inte satt"
+
+msgid "search hit TOP, continuing at BOTTOM"
+msgstr "sökning nådde TOPPEN, fortsätter vid BOTTEN"
+
+msgid "search hit BOTTOM, continuing at TOP"
+msgstr "sökning nådde BOTTEN, forsätter vid TOPPEN"
diff --git a/src/po/uk.cp1251.po b/src/po/uk.cp1251.po
new file mode 100644
index 0000000000..b3cc871070
--- /dev/null
+++ b/src/po/uk.cp1251.po
@@ -0,0 +1,7027 @@
+#
+# 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: 2013-09-29 09:05+0300\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"
+
+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 "[Location List]"
+msgstr "[Ñïèñîê ì³ñöü]"
+
+msgid "[Quickfix List]"
+msgstr "[Ñïèñîê âèïðàâëåíü]"
+
+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 "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 "Âèâàíòàæåíî îäèí áóôåð"
+
+#, c-format
+msgid "%d buffers unloaded"
+msgstr "Âèâàíòàæåíî %d áóôåðè(³â)"
+
+msgid "1 buffer deleted"
+msgstr "Çíèùåíî îäèí áóôåð"
+
+#, c-format
+msgid "%d buffers deleted"
+msgstr "Çíèùåíî %d áóôåðè(³â)"
+
+msgid "1 buffer wiped out"
+msgstr "Âèòåðòî îäèí áóôåð"
+
+#, c-format
+msgid "%d buffers wiped out"
+msgstr "Âèòåðòî %d áóôåðè(³â)"
+
+msgid "E84: No modified buffer found"
+msgstr "E84: Æîäåí áóôåð íå çì³íåíî"
+
+#. back where we started, didn't find anything.
+msgid "E85: There is no listed buffer"
+msgstr "E85: Ó ñïèñêó íåìຠáóôåð³â"
+
+#, c-format
+msgid "E86: Buffer %ld does not exist"
+msgstr "E86: Áóôåðà %ld íåìàº"
+
+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 "E90: Cannot unload last buffer"
+msgstr "E90: Íå ìîæó âèâàíòàæèòè îñòàíí³é áóôåð"
+
+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 "[RO]"
+
+msgid "[readonly]"
+msgstr "[ëèøå ÷èòàòè]"
+
+#, c-format
+msgid "1 line --%d%%--"
+msgstr "îäèí ðÿäîê --%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 "[Áåç íàçâè]"
+
+#. must be a help buffer
+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 "[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 id=%d íàçâà=%s"
+
+#, c-format
+msgid "E96: Can not 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: Íå âäàëîñÿ ñòâîðèòè ïîð³âíÿííÿ"
+
+msgid "Patch file"
+msgstr "Ëàòêà"
+
+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: Öåé áóôåð íå â ðåæèì³ ïîð³âíÿííÿ"
+
+msgid "E793: No other buffer in diff mode is modifiable"
+msgstr "E793: Íåìຠá³ëüøå ìîäèô³êîâíèõ áóôåð³â â ðåæèì³ ïîð³âíÿííÿ"
+
+msgid "E100: No other buffer in diff mode"
+msgstr "E100: Íåìຠ³íøèõ áóôåð³â â ðåæèì³ ïîð³âíÿííÿ"
+
+msgid "E101: More than two buffers in diff mode, don't know which one to use"
+msgstr ""
+"E101: Ïîíàä äâà áóôåðè ó ðåæèì³ ïîð³âíÿííÿ, íå çðîçóì³ëî, êîòðèé ³ç íèõ "
+"âèêîðèñòàòè"
+
+#, 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» íå â ðåæèì³ ïîð³âíÿííÿ"
+
+msgid "E787: Buffer changed unexpectedly"
+msgstr "E787: Áóôåð íåñïîä³âàíî çì³íèâñÿ"
+
+msgid "E104: Escape not allowed in digraph"
+msgstr "E104: Ó äèãðàôàõ íå ìîæå ì³ñòèòèñÿ escape"
+
+msgid "E544: Keymap file not found"
+msgstr "E544: Íå çíàéäåíî ôàéë ðîçêëàäêè"
+
+msgid "E105: Using :loadkeymap not in a sourced file"
+msgstr "E105: :loadkeymap âèêîðèñòàíî íå ó ôàéë³ êîìàíä"
+
+msgid "E791: Empty keymap entry"
+msgstr "E791: Åëåìåíò ðîçêëàäêè ïîðîæí³é"
+
+msgid " Keyword completion (^N^P)"
+msgstr " Äîïîâíåííÿ êëþ÷îâèõ ñë³â (^N^P)"
+
+#. ctrl_x_mode == 0, ^P/^N compl.
+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 " Êì³òëèâå äîïîâíåííÿ (^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 "Òðàïèâñÿ ê³íåöü ïàðàãðàôà"
+
+# msgstr "E443: "
+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 " 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.
+#.
+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"
+
+# msgstr "E17: "
+msgid "E18: Unexpected characters in :let"
+msgstr "E18: Íåî÷³êóâàí³ ñèìâîëè ó :let"
+
+#, c-format
+msgid "E684: list index out of range: %ld"
+msgstr "E684: ²íäåêñ ñïèñêó ïîçà ìåæàìè: %ld"
+
+#, c-format
+msgid "E121: Undefined variable: %s"
+msgstr "E121: Íåâèçíà÷åíà çì³ííà: %s"
+
+msgid "E111: Missing ']'"
+msgstr "E111: Áðàêóº ']'"
+
+#, c-format
+msgid "E686: Argument of %s must be a List"
+msgstr "E686: Àðãóìåíò ó %s ìຠáóòè ñïèñêîì"
+
+#, c-format
+msgid "E712: Argument of %s must be a List or Dictionary"
+msgstr "E712: Àðãóìåíò ó %s ìຠáóòè ñïèñêîì ÷è ñëîâíèêîì"
+
+msgid "E713: Cannot use empty key for Dictionary"
+msgstr "E713: Êëþ÷ ñëîâíèêà íå ìîæå áóòè ïîðîæí³ì"
+
+# msgstr "E396: "
+msgid "E714: List required"
+msgstr "E714: Ïîòð³áåí ñïèñîê"
+
+msgid "E715: Dictionary required"
+msgstr "E715: Ïîòð³áåí ñëîâíèê"
+
+#, 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"
+
+#, 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: Òðåáà ïîñèëàííÿ íà ôóíêö³þ"
+
+msgid "E719: Cannot use [:] with a Dictionary"
+msgstr "E719: Íå ìîæíà âèêîðèñòàòè [:] ç³ ñëîâíèêîì"
+
+#, c-format
+msgid "E734: Wrong variable type for %s="
+msgstr "E734: Íåïðàâèëüíèé òèï çì³ííî¿ äëÿ %s="
+
+#, c-format
+msgid "E130: Unknown function: %s"
+msgstr "E130: Íåâ³äîìà ôóíêö³ÿ: %s"
+
+#, c-format
+msgid "E461: Illegal variable name: %s"
+msgstr "E461: Íåïðèïóñòèìà íàçâà çì³ííî¿: %s"
+
+# msgstr "E373: "
+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 "Äðóãà ; ó ñïèñêó çì³ííèõ"
+
+# msgstr "E235: "
+#, 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: [:] âèìàãຠñïèñîê"
+
+msgid "E710: List value has more items than target"
+msgstr "E710: Ñïèñîê ìຠá³ëüøå åëåìåíò³â, í³æ ö³ëü"
+
+msgid "E711: List value has not enough items"
+msgstr "E711: Ñïèñîê ìຠíåäîñòàòíüî åëåìåíò³â"
+
+msgid "E690: Missing \"in\" after :for"
+msgstr "E690: Ïðîïóùåíî «in» ï³ñëÿ :for"
+
+#, c-format
+msgid "E107: Missing parentheses: %s"
+msgstr "E107: Ïðîïóùåíî äóæêè: %s"
+
+#, c-format
+msgid "E108: No such variable: \"%s\""
+msgstr "E108: Çì³ííî¿ íåìàº: «%s»"
+
+msgid "E743: variable nested too deep for (un)lock"
+msgstr "E743: Çì³ííà ìຠçàáàãàòî âêëàäåíü ùîá áóòè çà-/â³äêðèòîþ."
+
+msgid "E109: Missing ':' after '?'"
+msgstr "E109: Áðàêóº ':' ï³ñëÿ '?'"
+
+msgid "E691: Can only compare List with List"
+msgstr "E691: Ñïèñîê ìîæíà ïîð³âíÿòè ò³ëüêè ç³ ñïèñêîì"
+
+msgid "E692: Invalid operation for Lists"
+msgstr "E692: Íåêîðåêòíà îïåðàö³ÿ íàä ñïèñêîì"
+
+msgid "E735: Can only compare Dictionary with Dictionary"
+msgstr "E735: Ñëîâíèê ìîæíà ïîð³âíÿòè ò³ëüêè ³ç ñëîâíèêîì"
+
+msgid "E736: Invalid operation for Dictionary"
+msgstr "E736: Íåêîðåêòíà îïåðàö³ÿ íàä ñëîâíèêîì"
+
+msgid "E693: Can only compare Funcref with Funcref"
+msgstr "E693: Ôóíêö³þ ìîæíà ïîð³âíÿòè ò³ëüêè ç ôóíêö³ºþ"
+
+msgid "E694: Invalid operation for Funcrefs"
+msgstr "E694: Íåêîðåêòíà îïåðàö³ÿ íàä ôóíêö³ºþ"
+
+msgid "E804: Cannot use '%' with Float"
+msgstr "E804: Íå ìîæíà âèêîíàòè '%' íàä Float"
+
+msgid "E110: Missing ')'"
+msgstr "E110: Ïðîïóùåíî ')'"
+
+msgid "E695: Cannot index a Funcref"
+msgstr "E695: Ôóíêö³ÿ íå ìຠ³íäåêñàö³¿"
+
+#, 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"
+
+# msgstr "E404: "
+#, c-format
+msgid "E696: Missing comma in List: %s"
+msgstr "E696: Áðàêóº êîìè ó ñïèñêó: %s"
+
+#, c-format
+msgid "E697: Missing end of List ']': %s"
+msgstr "E697: Íåìຠê³íö³âêè ñïèñêó ']': %s"
+
+# msgstr "E235: "
+#, c-format
+msgid "E720: Missing colon in Dictionary: %s"
+msgstr "E720: Áðàêóº äâîêðàïêè ó ñëîâíèêó: %s"
+
+#, c-format
+msgid "E721: Duplicate key in Dictionary: \"%s\""
+msgstr "E721: Ïîâòîðåííÿ êëþ÷à â ñëîâíèêó: «%s»"
+
+# msgstr "E235: "
+#, c-format
+msgid "E722: Missing comma in Dictionary: %s"
+msgstr "E722: Áðàêóº êîìè ó ñëîâíèêó: %s"
+
+#, c-format
+msgid "E723: Missing end of Dictionary '}': %s"
+msgstr "E723: Íåìຠê³íö³âêè ñëîâíèêà '}': %s"
+
+# msgstr "E21: "
+msgid "E724: variable nested too deep for displaying"
+msgstr "E724: Ó çì³íí³é çàáàãàòî âêëàäåíü ùîá ¿¿ ïîêàçàòè"
+
+#, 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"
+
+#, c-format
+msgid "E117: Unknown function: %s"
+msgstr "E117: Íåâ³äîìà ôóíêö³ÿ: %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 "E808: Number or Float required"
+msgstr "E808: Òðåáà âêàçàòè Number ÷è Float"
+
+# msgstr "E14: "
+msgid "add() argument"
+msgstr "àðãóìåíò add()"
+
+msgid "E699: Too many arguments"
+msgstr "E699: Çàáàãàòî àðãóìåíò³â"
+
+# msgstr "E327: "
+msgid "E785: complete() can only be used in Insert mode"
+msgstr "E785: complete() ìîæíà âæèâàòè ò³ëüêè â ðåæèì³ âñòàâêè"
+
+#.
+#. * 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 "&O:Ãàðàçä"
+
+# msgstr "E226: "
+#, c-format
+msgid "E737: Key already exists: %s"
+msgstr "E737: Êëþ÷ âæå ³ñíóº: %s"
+
+# msgstr "E14: "
+msgid "extend() argument"
+msgstr "àðãóìåíò extend()"
+
+# msgstr "E14: "
+msgid "map() argument"
+msgstr "àðãóìåíò map()"
+
+# msgstr "E14: "
+msgid "filter() argument"
+msgstr "àðãóìåíò filter()"
+
+#, c-format
+msgid "+-%s%3ld lines: "
+msgstr "+-%s%3ld ðÿäê³â: "
+
+#, c-format
+msgid "E700: Unknown function: %s"
+msgstr "E700: Íåâ³äîìà ôóíêö³ÿ: %s"
+
+msgid ""
+"&OK\n"
+"&Cancel"
+msgstr ""
+"&O:Ãàðàçä\n"
+"&C:Ñêàñóâàòè"
+
+msgid "called inputrestore() more often than inputsave()"
+msgstr "Âèêëèêè äî inputrestore() ÷àñò³øå, í³æ äî inputsave()"
+
+# msgstr "E14: "
+msgid "insert() argument"
+msgstr "àðãóìåíò insert()"
+
+# msgstr "E406: "
+msgid "E786: Range not allowed"
+msgstr "E786: ²íòåðâàë íå äîçâîëåíî"
+
+# msgstr "E177: "
+msgid "E701: Invalid type for len()"
+msgstr "E701: Íåêîðåêòíèé òèï äëÿ len()"
+
+msgid "E726: Stride is zero"
+msgstr "E726: Êðîê íóëüîâèé"
+
+msgid "E727: Start past end"
+msgstr "E727: Ïî÷àòîê çà ê³íöåì"
+
+msgid "<empty>"
+msgstr "<í³÷îãî>"
+
+msgid "E240: No connection to Vim server"
+msgstr "E240: Íåìຠç'ºäíàííÿ ³ç ñåðâåðîì Vim"
+
+#, c-format
+msgid "E241: Unable to send to %s"
+msgstr "E241: Íå âäàëîñÿ â³ä³ñëàòè äî %s"
+
+msgid "E277: Unable to read a server reply"
+msgstr "E277: Íå âäàëîñÿ ïðî÷èòàòè â³äïîâ³äü ñåðâåðà"
+
+# msgstr "E14: "
+msgid "remove() argument"
+msgstr "àðãóìåíò remove()"
+
+msgid "E655: Too many symbolic links (cycle?)"
+msgstr "E655: Çàáàãàòî ñèìâîëüíèõ ïîñèëàíü (öèêë?)"
+
+# msgstr "E14: "
+msgid "reverse() argument"
+msgstr "àðãóìåíò reverse()"
+
+msgid "E258: Unable to send to client"
+msgstr "E258: Íå âäàëîñÿ íàä³ñëàòè ê볺íòó"
+
+# msgstr "E14: "
+msgid "sort() argument"
+msgstr "àðãóìåíò sort()"
+
+# msgstr "E364: "
+msgid "E702: Sort compare function failed"
+msgstr "E702: Ïîìèëêà ó ôóíêö³¿ ïîð³âíÿííÿ"
+
+msgid "(Invalid)"
+msgstr "(Íåìîæëèâî)"
+
+msgid "E677: Error writing temp file"
+msgstr "E677: Íå âäàëîñÿ çàïèñàòè òèì÷àñîâèé ôàéë"
+
+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 "E729: using Funcref as a String"
+msgstr "E729: Funcref âæèòî ÿê String"
+
+# msgstr "E373: "
+msgid "E730: using List as a String"
+msgstr "E730: List âæèòî ÿê String"
+
+msgid "E731: using Dictionary as a String"
+msgstr "E731: Dictionary âæèòî ÿê String"
+
+#, c-format
+msgid "E706: Variable type mismatch for: %s"
+msgstr "E706: Íåïðàâèëüíèé òèï çì³ííî¿: %s"
+
+#, 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: Çì³ííà âêëàäåíà çàíàäòî ãëèáîêî ùîá çðîáèòè ¿¿ êîï³þ"
+
+#, 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 "E125: Illegal argument: %s"
+msgstr "E125: Íåäîçâîëåíèé àðãóìåíò: %s"
+
+#, c-format
+msgid "E853: Duplicate argument name: %s"
+msgstr "E853: Íàçâà àðãóìåíòó ïîâòîðþºòüñÿ: %s"
+
+msgid "E126: Missing :endfunction"
+msgstr "E126: Áðàêóº :endfunction"
+
+#, 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"
+
+msgid "E129: Function name required"
+msgstr "E129: Íå âêàçàíî íàçâó ôóíêö³¿"
+
+#, c-format
+msgid "E128: Function name must start with a capital or contain a colon: %s"
+msgstr ""
+"E128: Íàçâà ôóíêö³¿ ìຠïî÷èíàòèñÿ ç âåëèêî¿ ë³òåðè àáî ì³ñòèòè äâîêðàïêó: %s"
+
+#, c-format
+msgid "E131: Cannot delete function %s: It is in use"
+msgstr "E131: Íå âäàëîñÿ çíèùèòè ôóíêö³þ %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"
+
+#, c-format
+msgid "continuing in %s"
+msgstr "ïðîäîâæåííÿ â %s"
+
+msgid "E133: :return not inside a function"
+msgstr "E133: :return ïîçà ìåæàìè ôóíêö³¿"
+
+msgid ""
+"\n"
+"# global variables:\n"
+msgstr ""
+"\n"
+"# ãëîáàëüí³ çì³íí³:\n"
+
+msgid ""
+"\n"
+"\tLast set from "
+msgstr ""
+"\n"
+"\tÂîñòàííº çì³íåíà ó "
+
+msgid "No old files"
+msgstr "Æîäíîãî ñòàðîãî ôàéëó"
+
+msgid "Entering Debug mode. Type \"cont\" to continue."
+msgstr "Ðåæèì íàëàãîäæåííÿ. Ùîá ïðîäîâæèòè ââåä³òü «cont»."
+
+#, c-format
+msgid "line %ld: %s"
+msgstr "ðÿäîê %ld: %s"
+
+#, c-format
+msgid "cmd: %s"
+msgstr "êîìàíäà: %s"
+
+#, 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"
+
+msgid "E750: First use \":profile start {fname}\""
+msgstr "E750: Ñïî÷àòêó çðîá³òü «:profile start {ôàéë}»"
+
+msgid "Save As"
+msgstr "Çáåðåãòè ÿê"
+
+#, c-format
+msgid "Save changes to \"%s\"?"
+msgstr "Çáåðåãòè çì³íè â «%s»?"
+
+msgid "Untitled"
+msgstr "Íåíàçâàíèé"
+
+#, 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"
+
+# msgstr "E195: "
+#, 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 'runtimepath': \"%s\""
+msgstr "Â 'runtimepath' íå çíàéäåíî «%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"
+
+msgid "modeline"
+msgstr "modeline"
+
+# msgstr "E14: "
+msgid "--cmd argument"
+msgstr "--cmd àðãóìåíò"
+
+# msgstr "E14: "
+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»"
+
+#, c-format
+msgid "<%s>%s%s %d, Hex %02x, Octal %03o"
+msgstr "<%s>%s%s %d, ø³ñò %02x, â³ñ %03o"
+
+#, 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 "Ïåðåì³ùåíî îäèí ðÿäîê"
+
+#, 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: Àâòîêîìàíäè *Filter* íå ïîâèíí³ çì³íþâàòè ïîòî÷íèé áóôåð"
+
+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 " ÍÅ ÂÄÀËÎÑß"
+
+#. avoid a wait_return for this message, it's annoying
+#, c-format
+msgid "E137: Viminfo file is not writable: %s"
+msgstr "E137: Íå äîçâîëåíî çàïèñ ó ôàéë viminfo: %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»"
+
+#. Write the info:
+#, c-format
+msgid "# This viminfo file was generated by Vim %s.\n"
+msgstr "# Öåé ôàéë àâòîìàòè÷íî ñòâîðåíèé 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 "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 "Ôàéë îáì³íó «%s» ³ñíóº, ïåðåçàïèñàòè?"
+
+#, c-format
+msgid "E768: Swap file exists: %s (:silent! overrides)"
+msgstr "E768: Ôàéë îáì³íó ³ñíóº: %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 ""
+"Äëÿ «%s» âñòàíîâëåíî 'readonly'.\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: Ó 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 "(Ïåðåðâàíî) "
+
+# msgstr "E31: "
+msgid "1 match"
+msgstr "Îäèí çá³ã"
+
+msgid "1 substitution"
+msgstr "Îäíà çàì³íà"
+
+#, c-format
+msgid "%ld matches"
+msgstr "%ld çá³ãè(³â)"
+
+#, c-format
+msgid "%ld substitutions"
+msgstr "%ld çàì³í(è)"
+
+msgid " on 1 line"
+msgstr " â îäíîìó ðÿäêó"
+
+#, c-format
+msgid " on %ld lines"
+msgstr " â %ld ðÿäêàõ"
+
+msgid "E147: Cannot do :global recursive"
+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 "E150: Not a directory: %s"
+msgstr "E150: Íå º êàòàëîãîì: %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 "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"
+
+#, c-format
+msgid "E157: Invalid sign ID: %ld"
+msgstr "E157: Íåïðàâèëüíèé ID íàäïèñó: %ld"
+
+msgid " (NOT FOUND)"
+msgstr " (ÍÅ ÇÍÀÉÄÅÍÎ)"
+
+msgid " (not supported)"
+msgstr " (íå ï³äòðèìóºòüñÿ)"
+
+msgid "[Deleted]"
+msgstr "[Çíèùåíî]"
+
+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 "E319: Sorry, the command is not available in this version"
+msgstr "E319: Âèáà÷òå, ö³º¿ êîìàíäè íåìຠó ö³é âåðñ³¿"
+
+msgid "E172: Only one file name allowed"
+msgstr "E172: Äîçâîëåíî ò³ëüêè îäíó íàçâó ôàéëó"
+
+msgid "1 more file to edit. Quit anyway?"
+msgstr "Çàëèøèëîñÿ â³äðåäàãóâàòè ùå îäèí ôàéë. Âñå îäíî âèéòè?"
+
+#, c-format
+msgid "%d more files to edit. Quit anyway?"
+msgstr "Ùå º %d íå ðåäàãîâàíèõ ôàéë³â. Âñå îäíî âèéòè?"
+
+msgid "E173: 1 more file to edit"
+msgstr "E173: Çàëèøèëîñÿ â³äðåäàãóâàòè ùå îäèí ôàéë"
+
+#, 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 Range 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: ˳÷èëüíèê íå ìîæå áóòè âêàçàíî äâ³÷³"
+
+# msgstr "E177: "
+msgid "E178: Invalid default value for count"
+msgstr "E178: Íåïðàâèëüíå ïî÷àòêîâå çíà÷åííÿ ë³÷èëüíèêà"
+
+# msgstr "E178: "
+msgid "E179: argument required for -complete"
+msgstr "E179: äëÿ -complete ïîòð³áíèé àðãóìåíò"
+
+# msgstr "E180: "
+#, c-format
+msgid "E181: Invalid attribute: %s"
+msgstr "E181: Íåïðàâèëüíèé àòðèáóò: %s"
+
+# msgstr "E181: "
+msgid "E182: Invalid command name"
+msgstr "E182: Íåïðàâèëüíà íàçâà êîìàíäè"
+
+# 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: Çàðåçåðâîâàíà íàçâà, íå ìîæíà âèêîðèñòàòè äëÿ êîðèñòóâàöüêî¿ êîìàíäè"
+
+# msgstr "E183: "
+#, c-format
+msgid "E184: No such user-defined command: %s"
+msgstr "E184: Êîìàíäó êîðèñòóâà÷à íå çíàéäåíî: %s"
+
+# msgstr "E179: "
+#, 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 "Íåâ³äîìî"
+
+# msgstr "E184: "
+#, c-format
+msgid "E185: Cannot find color scheme '%s'"
+msgstr "E185: Íå âäàëîñÿ çíàéòè ñõåìó êîëüîð³â «%s»"
+
+msgid "Greetings, Vim user!"
+msgstr "³òàííÿ, êîðèñòóâà÷ó Vim!"
+
+# msgstr "E443: "
+msgid "E784: Cannot close last tab page"
+msgstr "E784: Íå ìîæíà çàêðèòè îñòàííþ âêëàäêó"
+
+# msgstr "E444: "
+msgid "Already only one tab page"
+msgstr "Âæå é òàê ëèøå îäíà âêëàäêà"
+
+# msgstr "E185: "
+msgid "Edit File in new window"
+msgstr "Ðåäàãóâàòè ôàéë ó íîâîìó â³êí³"
+
+#, c-format
+msgid "Tab page %d"
+msgstr "Âêëàäêà %d"
+
+msgid "No swap file"
+msgstr "Íåìຠôàéëó îáì³íó"
+
+msgid "Append File"
+msgstr "Äîïèñàòè ôàéë"
+
+msgid "E747: Cannot change directory, buffer is modified (add ! to override)"
+msgstr "E747: Íå âäàëîñÿ çì³íèòè êàòàëîã, áóôåð ìຠçì³íè (! ùîá íå çâàæàòè)"
+
+msgid "E186: No previous directory"
+msgstr "E186: Öå âæå íàéïåðøèé êàòàëîã"
+
+# msgstr "E186: "
+msgid "E187: Unknown"
+msgstr "E187: Íåâ³äîìî"
+
+msgid "E465: :winsize requires two number arguments"
+msgstr "E465: :winsize âèìàãຠäâà ÷èñëîâèõ àðãóìåíòè"
+
+# msgstr "E187: "
+#, 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 âèìàãຠäâà ÷èñëîâèõ àðãóìåíòè"
+
+# msgstr "E188: "
+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» ³ñíóº (! ùîá íå çâàæàòè)"
+
+# msgstr "E189: "
+#, c-format
+msgid "E190: Cannot open \"%s\" for writing"
+msgstr "E190: Íå âäàëîñÿ â³äêðèòè «%s» äëÿ çàïèñó"
+
+# msgstr "E190: "
+#. set mark
+msgid "E191: Argument must be a letter or forward/backward quote"
+msgstr "E191: Àðãóìåíò ìຠáóòè ë³òåðîþ, ` àáî '"
+
+# 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"
+
+# msgstr "E193: "
+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: íåìຠíîìåðà ðÿäêà, ùîá âèêîðèñòàòè ç «<sfile>»"
+
+#, no-c-format
+msgid "E499: Empty file name for '%' or '#', only works with \":p:h\""
+msgstr "E499: Íàçâà ôàéëó äëÿ '%' ÷è '#' ïîðîæíÿ, ïðàöþº ëèøå ç «:p:h»"
+
+msgid "E500: Evaluates to an empty string"
+msgstr "E500: Ðåçóëüòàò — ïîðîæí³é ðÿäîê"
+
+msgid "E195: Cannot open viminfo file for reading"
+msgstr "E195: Íå âäàëîñÿ ïðî÷èòàòè ôàéë viminfo"
+
+msgid "E196: No digraphs in this version"
+msgstr "E196: Ó ö³é âåðñ³¿ íåìຠäèãðàô³â"
+
+msgid "E608: Cannot :throw exceptions with 'Vim' prefix"
+msgstr "E608: Íå ìîæíà âèêèäàòè (:throw) âèíÿòêè ç ïðåô³êñîì 'Vim'"
+
+#. always scroll up, don't overwrite
+#, 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"
+
+#. always scroll up, don't overwrite
+#, 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 "Ïîìèëêà, ïåðåðâàíî"
+
+# msgstr "E231: "
+msgid "Error"
+msgstr "Ïîìèëêà"
+
+#. if (pending & CSTP_INTERRUPT)
+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"
+
+#. Give up for a ":catch" after ":finally" and ignore it.
+#. * Just parse.
+msgid "E604: :catch after :finally"
+msgstr "E604: :catch ï³ñëÿ :finally"
+
+msgid "E606: :finally without :try"
+msgstr "E606: :finally áåç :try"
+
+#. Give up for a multiple ":finally" and ignore it.
+msgid "E607: multiple :finally"
+msgstr "E607: Íå îäíå :finally"
+
+msgid "E602: :endtry without :try"
+msgstr "E602: :entry áåç :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: Çàðàç íå ìîæíà çì³íþâàòè ³íôîðìàö³þ áóôåðà"
+
+# msgstr "E197: "
+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 "E198: cmd_pchar beyond the command length"
+msgstr "E198: cmd_pchar ïîçà ìåæàìè êîìàíäè"
+
+msgid "E199: Active window or buffer deleted"
+msgstr "E199: Àêòèâíå â³êíî àáî áóôåð áóëî çíèùåíî"
+
+msgid "E812: Autocommands changed buffer or buffer name"
+msgstr "E812: Àâòîêîìàíäè çì³íèëè áóôåð ÷è éîãî íàçâó"
+
+# msgstr "E199: "
+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 óíåìîæëèâèëè ÷èòàííÿ ôàéëó"
+
+# msgstr "E200: "
+msgid "E201: *ReadPre autocommands must not change current buffer"
+msgstr "E201: Àâòîêîìàíäè *ReadPre íå ïîâèíí³ çì³íþâàòè öåé áóôåð"
+
+# msgstr "E201: "
+msgid "Vim: Reading from stdin...\n"
+msgstr "Vim: ×èòàºòüñÿ ç stdin...\n"
+
+msgid "Reading from stdin..."
+msgstr "×èòàºòüñÿ ç stdin..."
+
+#. Re-opening the original file failed!
+msgid "E202: Conversion made file unreadable!"
+msgstr "E202: Êîíâåðòàö³ÿ óíåìîæëèâèëà ÷èòàííÿ ôàéëó!"
+
+# msgstr "E202: "
+msgid "[fifo/socket]"
+msgstr "[êàíàë/ñîêåò]"
+
+msgid "[fifo]"
+msgstr "[êàíàë]"
+
+msgid "[socket]"
+msgstr "[ñîêåò]"
+
+msgid "[character special]"
+msgstr "[ñïåö. ñèìâîëüíèé]"
+
+msgid "[CR missing]"
+msgstr "[Áðàêóº CR]"
+
+msgid "[long lines split]"
+msgstr "[Ðîçáèòî äîâã³ ðÿäêè]"
+
+msgid "[NOT converted]"
+msgstr "[ÍÅ êîíâåðòîâàíî]"
+
+msgid "[converted]"
+msgstr "[êîíâåðòîâàíî]"
+
+msgid "[blowfish]"
+msgstr "[blowfish]"
+
+msgid "[crypted]"
+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 "E821: File is encrypted with unknown method"
+msgstr "E821: Ôàéë çàøèôðîâàíî íåâ³äîìèì ìåòîäîì"
+
+# msgstr "E217: "
+msgid "E676: No matching autocommands for acwrite buffer"
+msgstr "E676: Íåìຠâ³äïîâ³äíèõ àâòîêîìàíä"
+
+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 íå äîçâîëÿº çàïèñóâàòè ó íåçì³íåí³ áóôåðè"
+
+# msgstr "E391: "
+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 "E460: The resource fork would be lost (add ! to override)"
+msgstr "E460: óëêó ðåñóðñ³â ìîæíà âòðàòèòè (! ùîá íå çâàæàòè)"
+
+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 "E667: Fsync failed"
+msgstr "E667: Íå âäàëîñÿ âèêîíàòè fsync"
+
+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: Ëàòàííÿ: íå âäàëîñÿ çáåðåãòè îðèã³íàë"
+
+msgid "E206: patchmode: can't touch empty original file"
+msgstr "E206: Ëàòàííÿ: íå âäàëîñÿ ñòâîðèòè îðèã³íàë"
+
+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 "îäèí ðÿäîê, "
+
+#, c-format
+msgid "%ld lines, "
+msgstr "%ld ðÿäê³â, "
+
+msgid "1 character"
+msgstr "îäèí ñèìâîë"
+
+#, c-format
+msgid "%lld characters"
+msgstr "%lld ñèìâîë³â"
+
+#. Explicit typecast avoids warning on Mac OS X 10.6
+#, c-format
+msgid "%ld characters"
+msgstr "%ld ñèìâîë³â"
+
+msgid "[noeol]"
+msgstr "[noeol]"
+
+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
+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 ""
+"&O:Ãàðàçä\n"
+"&L:Çàâàíòàæèòè"
+
+#, 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>"
+
+#. the group doesn't exist
+#, c-format
+msgid "E367: No such group: \"%s\""
+msgstr "E367: Íåìຠòàêî¿ ãðóïè: «%s»"
+
+#, c-format
+msgid "E215: Illegal character after *: %s"
+msgstr "E215: Íåäîçâîëåíèé ñèìâîë ï³ñëÿ *: %s"
+
+# msgstr "E215: "
+#, c-format
+msgid "E216: No such event: %s"
+msgstr "E216: Íåìຠòàêî¿ ïî䳿: %s"
+
+# msgstr "E215: "
+#, c-format
+msgid "E216: No such group or event: %s"
+msgstr "E216: Íåìຠòàêî¿ ãðóïè ÷è ïî䳿: %s"
+
+# msgstr "E216: "
+#. Highlight title
+msgid ""
+"\n"
+"--- Auto-Commands ---"
+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: Íå ìîæó âèêîíóâàòè àâòîêîìàíäè äëÿ ÓÑ²Õ ïîä³é"
+
+# msgstr "E217: "
+msgid "No matching autocommands"
+msgstr "Íåìຠâ³äïîâ³äíèõ àâòîêîìàíä"
+
+msgid "E218: autocommand nesting too deep"
+msgstr "E218: Çàáàãàòî âêëàäåíèõ àâòîêîìàíä"
+
+# msgstr "E218: "
+#, c-format
+msgid "%s Auto commands for \"%s\""
+msgstr "Àâòîêîìàíäè %s äëÿ «%s»"
+
+#, c-format
+msgid "Executing %s"
+msgstr "Âèêîíóºòüñÿ %s"
+
+#, c-format
+msgid "autocommand %s"
+msgstr "àâòîêîìàíäà %s"
+
+msgid "E219: Missing {."
+msgstr "E219: Áðàêóº {."
+
+# msgstr "E219: "
+msgid "E220: Missing }."
+msgstr "E220: Áðàêóº }."
+
+# msgstr "E220: "
+msgid "E490: No fold found"
+msgstr "E490: Çãîðòîê íå çíàéäåíî"
+
+# msgstr "E349: "
+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 lines folded "
+msgstr "+-- çãîðíóòî %3ld ðÿäê³â "
+
+msgid "E222: Add to read buffer"
+msgstr "E222: Äîäàòè äî áóôåðà ÷èòàííÿ"
+
+msgid "E223: recursive mapping"
+msgstr "E223: Çàì³íà ðåêóðñèâíà"
+
+# msgstr "E223: "
+#, c-format
+msgid "E224: global abbreviation already exists for %s"
+msgstr "E224: Çàãàëüíå ñêîðî÷åííÿ äëÿ %s âæå ³ñíóº"
+
+# msgstr "E224: "
+#, c-format
+msgid "E225: global mapping already exists for %s"
+msgstr "E225: Çàãàëüíà çàì³íà äëÿ %s âæå ³ñíóº"
+
+# msgstr "E225: "
+#, c-format
+msgid "E226: abbreviation already exists for %s"
+msgstr "E226: Âæå º ñêîðî÷åííÿ äëÿ %s"
+
+# msgstr "E226: "
+#, c-format
+msgid "E227: mapping already exists for %s"
+msgstr "E227: Âæå º çàì³íà äëÿ %s"
+
+# msgstr "E227: "
+msgid "No abbreviation found"
+msgstr "Ñêîðî÷åííÿ íå çíàéäåíî"
+
+msgid "No mapping found"
+msgstr "Çàì³íè íå çíàéäåíî"
+
+msgid "E228: makemap: Illegal mode"
+msgstr "E228: makemap: Íåïðèïóñòèìèé ðåæèì"
+
+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 "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: "
+#, c-format
+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' íåêîðåêòíå"
+
+#, c-format
+msgid "E254: Cannot allocate color %s"
+msgstr "E254: Íå âäàëîñÿ îòðèìàòè êîë³ð %s"
+
+msgid "No match at cursor, finding next"
+msgstr "Íåìຠíàä êóðñîðîì, ïîøóê òðèâàº"
+
+msgid ""
+"&Yes\n"
+"&No\n"
+"&Cancel"
+msgstr ""
+"&Y:Òàê\n"
+"&N:ͳ\n"
+"&C:Ñêàñóâàòè"
+
+msgid "Input _Methods"
+msgstr "Ìåòîäè ââåäåííÿ"
+
+msgid "VIM - Search and Replace..."
+msgstr "VIM - Çíàéòè é çàì³íèòè..."
+
+msgid "VIM - Search..."
+msgstr "VIM - Ïîøóê..."
+
+msgid "Find what:"
+msgstr "Çíàéòè:"
+
+msgid "Replace with:"
+msgstr "Çàì³íèòè íà:"
+
+#. whole word only button
+msgid "Match whole word only"
+msgstr "Ëèøå ïîâíå ñëîâî"
+
+#. match case button
+msgid "Match case"
+msgstr "Çâàæàòè íà ðåã³ñòð"
+
+msgid "Direction"
+msgstr "Íàïðÿì"
+
+#. 'Up' and 'Down' buttons
+msgid "Up"
+msgstr "Âãîðó"
+
+msgid "Down"
+msgstr "Óíèç"
+
+#. 'Find Next' button
+msgid "Find Next"
+msgstr "Íàñòóïíå"
+
+#. 'Replace' button
+msgid "Replace"
+msgstr "Çàì³íèòè"
+
+#. 'Replace All' button
+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:Ñêàñóâàòè"
+
+#, 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 "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 "Çíàéòè ³ çàì³íèòè ('\\\\' ùîá çíàéòè '\\')"
+
+#. 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 "Íåìàº"
+
+msgid "Directory\t*.nothing\n"
+msgstr "Êàòàëîã\t*.í³÷îãî\n"
+
+msgid "Vim E458: Cannot allocate colormap entry, some colors may be incorrect"
+msgstr ""
+"Vim E458: Íåìຠâ³ëüíèõ êîì³ðîê ó ïàë³òð³, äåÿê³ êîëüîðè ìîæóòü áóòè "
+"íåïðàâèëüí³"
+
+#, c-format
+msgid "E250: Fonts for the following charsets are missing in fontset %s:"
+msgstr "E250: Øðèôòè äëÿ öèõ ñèìâîë³â â³äñóòí³ ó íàáîð³ %s:"
+
+# msgstr "E250: "
+#, c-format
+msgid "E252: Fontset name: %s"
+msgstr "E252: Íàçâà íàáîðó øðèôò³â: %s"
+
+# msgstr "E252: "
+#, 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 "&D:Ïðèïèíèòè"
+
+msgid "no specific match"
+msgstr "íåìຠêîíêðåòíîãî çá³ãó"
+
+# msgstr "E234: "
+msgid "Vim - Font Selector"
+msgstr "Vim - Âèá³ð øðèôòó"
+
+msgid "Name:"
+msgstr "Íàçâà:"
+
+#. create toggle button
+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: Ïðîïóùåíî äâîêðàïêó"
+
+# msgstr "E347: "
+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 «%s»"
+
+#, c-format
+msgid "E618: file \"%s\" is not a PostScript resource file"
+msgstr "E618: «%s» íå º ôàéëîì ðåñóðñ³â PostScript"
+
+#, c-format
+msgid "E619: file \"%s\" is not a supported PostScript resource file"
+msgstr "E619: «%s» íå º ï³äòðèìóâàíèì ôàéëîì ðåñóðñ³â PostScript"
+
+#, c-format
+msgid "E621: \"%s\" resource file has wrong version"
+msgstr "E621: Íåïðàâèëüíà âåðñ³ÿ ôàéëó ðåñóðñ³â «%s»"
+
+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 «prolog.ps»"
+
+msgid "E456: Can't find PostScript resource file \"cidfont.ps\""
+msgstr "E456: Íå âäàëîñÿ çíàéòè ôàéë ðåñóðñ³â PostScript «cidfont.ps»"
+
+#, c-format
+msgid "E456: Can't find PostScript resource file \"%s.ps\""
+msgstr "E456: Íå âäàëîñÿ çíàéòè ôàéë ðåñóðñ³â PostScript «%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 "Çàâäàííÿ äðóêó â³ä³ñëàíî."
+
+# msgstr "E255: "
+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 <³äåíòèô-îð>"
+
+msgid "E257: cstag: tag not found"
+msgstr "E257: cstag: òå´ íå çíàéäåíî"
+
+# msgstr "E257: "
+#, 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: ïîìèëêà ï³ä ÷àñ âèêîíàííÿ"
+
+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"
+
+# msgstr "E258: "
+#, c-format
+msgid "E259: no matches found for cscope query %s of %s"
+msgstr "E259: Äëÿ çàïèòó cscope %s ç %s í³÷îãî íå çíàéäåíî"
+
+# msgstr "E259: "
+msgid "cscope commands:\n"
+msgstr "Êîìàíäè cscope:\n"
+
+#, c-format
+msgid "%-5s: %s%*s (Usage: %s)"
+msgstr "%-5s: %s%*s (Âèêîðèñòàííÿ: %s)"
+
+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"
+
+#, 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 íå äîäàíà"
+
+# msgstr "E260: "
+#, c-format
+msgid "E261: cscope connection %s not found"
+msgstr "E261: Ç'ºäíàííÿ ç cscope %s íå çíàéäåíî"
+
+#, c-format
+msgid "cscope connection %s closed"
+msgstr "Ç'ºäíàííÿ ç cscope %s çàê³í÷åíî"
+
+#. should not reach here
+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 "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: "
+#, c-format
+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 "ï³ä'ºäíàíèé"
+
+#, c-format
+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 "ïîì³òêó íå âêàçàíî"
+
+#, 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 "Íå âäàëîñÿ çàðåºñòðóâàòè ïîä³þ: áóôåð/â³êíî óæå çíèùóºòüñÿ"
+
+#. This should never happen. Famous last word?
+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 íå ìîæå áóòè çàâàíòàæåíà."
+
+#, 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: Ðåêâ³çèò ðåºñòðó çðàçêó VIM ñôîðìîâàíèé íåïðàâèëüíî. Çíèùåíî!"
+
+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 "Çàáàãàòî àðãóìåíò³â ó «+êîìàíäà», «-c êîìàíäà» àáî «--cmd êîìàíäà»"
+
+# msgstr "E14: "
+msgid "Invalid argument for"
+msgstr "Íåïðàâèëüíèé àðãóìåíò ó"
+
+#, 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 "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 "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: Warning: Output is not to a terminal\n"
+msgstr "Vim: Çàñòåðåæåííÿ: Âèâ³ä íå ó òåðì³íàë\n"
+
+msgid "Vim: Warning: Input is not from a terminal\n"
+msgstr "Vim: Çàñòåðåæåííÿ: Óâåäåííÿ íå ç òåðì³íàëó\n"
+
+#. just in case..
+msgid "pre-vimrc command line"
+msgstr "êîìàíäè ïåðåä vimrc"
+
+#, c-format
+msgid "E282: Cannot read from \"%s\""
+msgstr "E282: Íå âäàëîñÿ ïðî÷èòàòè ç «%s»"
+
+# msgstr "E282: "
+msgid ""
+"\n"
+"More info with: \"vim -h\"\n"
+msgstr ""
+"\n"
+"ijçíàéòåñÿ á³ëüøå: «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 ïîì³òêà ïåðåéòè äî òå´ó"
+
+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\tÐåæèì Vi (í³áè «vi»)"
+
+msgid "-e\t\t\tEx mode (like \"ex\")"
+msgstr "-e\t\t\tÐåæèì Ex (í³áè «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Ìîâ÷àçíèé (ïàêåòíèé) ðåæèì (ëèøå äëÿ «ex»)"
+
+msgid "-d\t\t\tDiff mode (like \"vimdiff\")"
+msgstr "-d\t\t\tÐåæèì ïîð³âíÿííÿ (í³áè «vimdiff»)"
+
+msgid "-y\t\t\tEasy mode (like \"evim\", modeless)"
+msgstr "-y\t\t\tÏðîñòèé ðåæèì (í³áè «evim», áåç ðåæèì³â)"
+
+msgid "-R\t\t\tReadonly mode (like \"view\")"
+msgstr "-R\t\t\tÐåæèì ïåðåãëÿäó (í³áè «view»)"
+
+msgid "-Z\t\t\tRestricted mode (like \"rvim\")"
+msgstr "-Z\t\t\tÎáìåæåíèé ðåæèì (í³áè «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\tÐåæèì lisp"
+
+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][ôàéë]\t\tÁ³ëüøå ïîâ³äîìëåíü [ð³âåíü N] [ôàéë æóðí. ïîâ³äîìëåíü]"
+
+msgid "-D\t\t\tDebugging mode"
+msgstr "-D\t\t\tÐåæèì íàëàãîäæåííÿ"
+
+msgid "-n\t\t\tNo swap file, use memory only"
+msgstr "-n\t\t\tÍå âèêîðèñòîâóâàòè ôàéë îáì³íó, òðèìàòè óñå â ïàì'ÿò³"
+
+msgid "-r\t\t\tList swap files and exit"
+msgstr "-r\t\t\tÏîêàçàòè ôàéëè îáì³íó ³ âèéòè"
+
+msgid "-r (with file name)\tRecover crashed session"
+msgstr "-r (íàçâà ôàéëó)\t³äíîâèòè àâàð³éíî çàê³í÷åíèé ñåàíñ"
+
+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Íå âèêîðèñòîâóâàòè newcli äëÿ â³äêðèòòÿ â³êíà"
+
+msgid "-dev <device>\t\tUse <device> for I/O"
+msgstr "-dev <ïðèñòð³é>\t\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 "-u <vimrc>\t\tUse <vimrc> instead of any .vimrc"
+msgstr "-u <vimrc>\t\tÂèêîðèñòàòè ïîäàíèé ôàéë çàì³ñòü .vimrc"
+
+msgid "-U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc"
+msgstr "-u <gvimrc>\t\tÂèêîðèñòàòè ïîäàíèé ôàéë çàì³ñòü .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\tÇ÷èòàòè êîìàíäè íîðìàëüíîãî ðåæèìó ç ôàéëó <ñêðèïò>"
+
+msgid "-w <scriptout>\tAppend all typed commands to file <scriptout>"
+msgstr "-w <ñêðèïò>\t\tÄîïèñàòè óñ³ íàáðàí³ êîìàíäè äî ôàéëó <ñêðèïò>"
+
+msgid "-W <scriptout>\tWrite all typed commands to file <scriptout>"
+msgstr "-w <ñêðèïò>\t\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 <ôàéëè> ..., àëå çà÷åêàòè ïîêè óñ³ ôàéëè áóäóòü â³äðåäàãîâàí³"
+
+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 "--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 "-h or --help\tPrint Help (this message) and exit"
+msgstr "-h ÷è --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Âèêîðèñòàòè <øðèôò> äëÿ çâè÷àéíîãî òåêñòó (òàêîæ: -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 "Íåìຠäèñïëåþ"
+
+#. Failed to send, abort.
+msgid ": Send failed.\n"
+msgstr ": Íå âäàëîñÿ â³ä³ñëàòè.\n"
+
+#. Let vim start normally.
+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» íå çíàéäåíî"
+
+# msgstr "E283: "
+#. Highlight title
+msgid ""
+"\n"
+"mark line col file/text"
+msgstr ""
+"\n"
+"ïîì. ðÿä. êîë. ôàéë/òåêñò"
+
+#. Highlight title
+msgid ""
+"\n"
+" jump line col file/text"
+msgstr ""
+"\n"
+" òî÷êà ðÿä. ñòîâï. ôàéë/òåêñò"
+
+# msgstr "E283: "
+#. Highlight title
+msgid ""
+"\n"
+"change line col text"
+msgstr ""
+"\n"
+"çì³íèòè ðÿä. ñòîâï. òåêñò"
+
+# TODO
+msgid ""
+"\n"
+"# File marks:\n"
+msgstr ""
+"\n"
+"# Ïîì³òêè:\n"
+
+#. Write the jumplist with -'
+msgid ""
+"\n"
+"# Jumplist (newest first):\n"
+msgstr ""
+"\n"
+"# Ñïèñîê ïåðåõîä³â (â³ä íàéíîâ³øèõ):\n"
+
+# TODO
+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: Íå âäàëîñÿ âñòàíîâèòè çíà÷åííÿ êîíòåêñòó ââîäó"
+
+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: Ìåòîä ââîäó íå ï³äòðèìóº â³äðåäàãîâàí³ òèïè"
+
+# msgstr "E292: "
+msgid "E293: block was not locked"
+msgstr "E293: Áëîê íå áóëî çàô³êñîâàíî"
+
+# msgstr "E293: "
+msgid "E294: Seek error in swap file read"
+msgstr "E294: Ïîìèëêà çì³íè ïîçèö³¿ ó ôàéë³ îáì³íó"
+
+msgid "E295: Read error in swap file"
+msgstr "E295: Ïîìèëêà ç÷èòóâàííÿ ôàéëó îáì³íó"
+
+msgid "E296: Seek error in swap file write"
+msgstr "E296: Ïîìèëêà çì³íè ïîçèö³¿ ï³ä ÷àñ çàïèñó ó ôàéë îáì³íó"
+
+msgid "E297: Write error in swap file"
+msgstr "E297: Ïîìèëêà çàïèñó ôàéëó îáì³íó"
+
+msgid "E300: Swap file already exists (symlink attack?)"
+msgstr "E300: Ôàéë îáì³íó âæå ³ñíóº (àòàêà ñèìâîëüíèì ïîñèëàííÿì?)"
+
+msgid "E298: Didn't get block nr 0?"
+msgstr "E298: Íåìຠáëîêó 0?"
+
+msgid "E298: Didn't get block nr 1?"
+msgstr "E298: Íåìຠáëîêó 1?"
+
+# msgstr "E298: "
+msgid "E298: Didn't get block nr 2?"
+msgstr "E298: Íåìຠáëîêó 2?"
+
+msgid "E843: Error while updating swap file crypt"
+msgstr "E843: Ïîìèëêà ïîíîâëåííÿ øèôðóâàííÿ ôàéëó îáì³íó"
+
+#. could not (re)open the swap file, what can we do????
+msgid "E301: Oops, lost the swap file!!!"
+msgstr "E301: Îé, âòðà÷åíî ôàéë îáì³íó!!!"
+
+# msgstr "E301: "
+msgid "E302: Could not rename swap file"
+msgstr "E302: Íå âäàëîñÿ ïåðåéìåíóâàòè ôàéëó îáì³íó"
+
+# msgstr "E302: "
+#, c-format
+msgid "E303: Unable to open swap file for \"%s\", recovery impossible"
+msgstr "E303: Íå âäàëîñÿ ïðî÷èòàòè ôàéë îáì³íó äëÿ «%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"
+
+# msgstr "E305: "
+msgid "Enter number of swap file to use (0 to quit): "
+msgstr "Ââåä³òü íîìåð ôàéëó îáì³íó, êîòðèé âèêîðèñòàòè, (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 íå ïîíîâèâ ôàéë îáì³íó."
+
+msgid " cannot be used with this version of Vim.\n"
+msgstr " íå ìîæíà âèêîðèñòàòè ç ö³ºþ âåðñ³ºþ Vim.\n"
+
+msgid "Use Vim version 3.0.\n"
+msgstr "Çíàéä³òü Vim 3.0\n"
+
+#, c-format
+msgid "E307: %s does not look like a Vim swap file"
+msgstr "E307: %s íå ñõîæå íà ôàéë îáì³íó Vim"
+
+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 "Âèêîðèñòîâóºòüñÿ ôàéë îáì³íó «%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 "Ôàéë îáì³íó çàøèôðîâàíèé: «%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"
+"ùîá âèêîðèñòàòè îäíàêîâèé êëþ÷ äëÿ òåêñòîâîãî ôàéëó òà ôàéëó îáì³íó"
+
+# msgstr "E308: "
+#, c-format
+msgid "E309: Unable to read block 1 from %s"
+msgstr "E309: Íå âäàëîñÿ ïðî÷èòàòè áëîê 1 ç %s"
+
+# msgstr "E309: "
+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: ²äåíòèô³êàòîð áëîêó 1 íåïðàâèëüíèé (%s íå º ôàéëîì îáì³íó?)"
+
+# msgstr "E310: "
+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 "³äíîâëåííÿ çàê³í÷åíî, ïåðåâ³ðòå ÷è âñå ãàðàçä."
+
+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 "Äëÿ òåêñòîâîãî ôàéëó âèêîðèñòîâóºòüñÿ êëþ÷ øèôðó ç ôàéëó îáì³íó.\n"
+
+#. use msg() to start the scrolling properly
+msgid "Swap files found:"
+msgstr "Çíàéäåíî ôàéëè îáì³íó:"
+
+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 " [íå ñõîæå íà ôàéë îáì³íó]"
+
+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"
+" ID ïðîöåñó: "
+
+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: Íå âäàëîñÿ çàãîòîâèòè, íåìຠôàéëó îáì³íó"
+
+# msgstr "E313: "
+msgid "File preserved"
+msgstr "Ôàéë çáåðåæåíî"
+
+msgid "E314: Preserve failed"
+msgstr "E314: Çáåðåæåííÿ íå âäàëîñÿ"
+
+# msgstr "E314: "
+#, c-format
+msgid "E315: ml_get: invalid lnum: %ld"
+msgstr "E315: ml_get: íåïðàâèëüíèé lnum: %ld"
+
+# msgstr "E315: "
+#, c-format
+msgid "E316: ml_get: cannot find line %ld"
+msgstr "E316: ml_get: íå çíàéøîâ ðÿäîê %ld"
+
+# msgstr "E316: "
+msgid "E317: pointer block id wrong 3"
+msgstr "E317: Âêàç³âíèê áëîêó ïîìèëêîâèé 3"
+
+# msgstr "E317: "
+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: Âêàç³âíèê áëîêó ïîìèëêîâèé"
+
+# msgstr "E317: "
+msgid "pe_line_count is zero"
+msgstr "pe_line_count äîð³âíþº 0"
+
+#, c-format
+msgid "E322: line number out of range: %ld past the end"
+msgstr "E322: Íîìåð ðÿäêà âèéøîâ çà ìåæ³: %ld çà ê³íöåì"
+
+# msgstr "E322: "
+#, c-format
+msgid "E323: line count wrong in block %ld"
+msgstr "E323: ʳëüê³ñòü ðÿäê³â ó áëîö³ %ld"
+
+# msgstr "E323: "
+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: Öèêë³÷í³ ñèìâîëüí³ ïîñèëàííÿ «%s»"
+
+# msgstr "E317: "
+msgid "E325: ATTENTION"
+msgstr "E325: ÓÂÀÃÀ"
+
+msgid ""
+"\n"
+"Found a swap file by the name \""
+msgstr ""
+"\n"
+"Çíàéäåíî ôàéë îáì³íó ç íàçâîþ \""
+
+msgid "While opening file \""
+msgstr "Ïðè â³äêðèòò³ ôàéëó \""
+
+msgid " NEWER than swap file!\n"
+msgstr " ÍβØÈÉ çà ôàéë îáì³íó!\n"
+
+#. 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."
+msgstr ""
+"\n"
+"(1) Ìîæëèâî, ³íøà ïðîãðàìà âæå ðåäàãóº öåé ñàìèé ôàéë. ßêùî öå òàê,\n"
+" áóäüòå îáåðåæí³, ùîá íå çàëèøèëèñÿ äâà ð³çí³ åêçåìïëÿðè\n"
+" îäíîãî é òîãî ñàìîãî ôàéëó ï³ñëÿ çì³í."
+
+msgid " Quit, or continue with caution.\n"
+msgstr " Âèéä³òü àáî ïðîäîâæóéòå îáåðåæíî.\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 " ßêùî âè âæå öå çðîáèëè, çíèù³òü ôàéë îáì³íó «"
+
+msgid ""
+"\"\n"
+" to avoid this message.\n"
+msgstr ""
+"»,\n"
+" ùîá ïîçáóòèñÿ öüîãî ïîâ³äîìëåííÿ.\n"
+"\n"
+
+msgid "Swap file \""
+msgstr "Ôàéë îáì³íó «"
+
+msgid "\" already exists!"
+msgstr "» âæå ³ñíóº!"
+
+msgid "VIM - ATTENTION"
+msgstr "VIM — ÓÂÀÃÀ"
+
+msgid "Swap file already exists!"
+msgstr "Ôàéë îáì³íó âæå ³ñíóº!"
+
+msgid ""
+"&Open Read-Only\n"
+"&Edit anyway\n"
+"&Recover\n"
+"&Quit\n"
+"&Abort"
+msgstr ""
+"&O:³äêðèòè ëèøå äëÿ ÷èòàííÿ\n"
+"&E:Âñå îäíî ðåäàãóâàòè\n"
+"&R:³äíîâèòè\n"
+"&Q:Âèéòè\n"
+"&A:Ïåðåðâàòè"
+
+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:Ïåðåðâàòè"
+
+msgid "E326: Too many swap files found"
+msgstr "E326: Çíàéäåíî çàáàãàòî ôàéë³â îáì³íó"
+
+# msgstr "E326: "
+msgid "E327: Part of menu-item path is not sub-menu"
+msgstr "E327: ×àñòèíà øëÿõó äî åëåìåíòà ìåíþ íå º ï³äìåíþ"
+
+# msgstr "E327: "
+msgid "E328: Menu only exists in another mode"
+msgstr "E328: Ìåíþ ìîæå áóòè ò³ëüêè â ³íøîìó ðåæèì³"
+
+# msgstr "E328: "
+#, c-format
+msgid "E329: No menu \"%s\""
+msgstr "E329: Íåìຠìåíþ «%s»"
+
+#. Only a mnemonic or accelerator is not valid.
+msgid "E792: Empty menu name"
+msgstr "E792: Ïîðîæíÿ íàçâà ìåíþ"
+
+# msgstr "E329: "
+msgid "E330: Menu path must not lead to a sub-menu"
+msgstr "E330: Øëÿõ äî ìåíþ íå ïîâèíåí âåñòè äî ï³äìåíþ"
+
+# msgstr "E330: "
+msgid "E331: Must not add menu items directly to menu bar"
+msgstr "E331: Íå ìîæíà äîäàâàòè åëåìåíòè ìåíþ ïðîñòî äî âåðõíüîãî ìåíþ"
+
+# msgstr "E331: "
+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
+msgid ""
+"\n"
+"--- Menus ---"
+msgstr ""
+"\n"
+"--- Ìåíþ ---"
+
+msgid "Tear off this menu"
+msgstr "³ä³ðâàòè öå ìåíþ"
+
+msgid "E333: Menu path must lead to a menu item"
+msgstr "E333: Øëÿõ ïîâèíåí âåñòè äî åëåìåíòà ìåíþ"
+
+# msgstr "E333: "
+#, c-format
+msgid "E334: Menu not found: %s"
+msgstr "E334: Ìåíþ íå çíàéäåíî: %s"
+
+# msgstr "E334: "
+#, c-format
+msgid "E335: Menu not defined for %s mode"
+msgstr "E335: Äëÿ ðåæèìó %s ìåíþ íå âèçíà÷åíî"
+
+# msgstr "E335: "
+msgid "E336: Menu path must lead to a sub-menu"
+msgstr "E336: Øëÿõ ïîâèíåí âåñòè äî ï³äìåíþ"
+
+# msgstr "E336: "
+msgid "E337: Menu not found - check menu names"
+msgstr "E337: Ìåíþ íå çíàéäåíî — ïåðåâ³ðòå íàçâó"
+
+# 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 "Óêðà¿í³çàö³ÿ: Àíàòîë³é Ñàõí³ê <sakhnik@gmail.com>"
+
+msgid "Interrupt: "
+msgstr "Ïåðåðâàíî: "
+
+msgid "Press ENTER or type command to continue"
+msgstr "Íàòèñí³òü ENTER àáî ââåä³òü êîìàíäó äëÿ ïðîäîâæåííÿ"
+
+#, 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 ""
+"&Y:Òàê\n"
+"&N:ͳ"
+
+msgid ""
+"&Yes\n"
+"&No\n"
+"Save &All\n"
+"&Discard All\n"
+"&Cancel"
+msgstr ""
+"&Y:Òàê\n"
+"&N:ͳ\n"
+"&A:Óñ³\n"
+"&D:Æîäíîãî\n"
+"&C:Ñêàñóâàòè"
+
+msgid "Select Directory dialog"
+msgstr "Âèáðàòè êàòàëîã"
+
+msgid "Save File dialog"
+msgstr "Çàïàì'ÿòàòè ôàéë"
+
+msgid "Open File dialog"
+msgstr "³äêðèòè ôàéë"
+
+#. TODO: non-GUI file selector here
+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()"
+
+# msgstr "E338: "
+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 "äîäàíî îäèí ðÿäîê"
+
+msgid "1 line less"
+msgstr "çíèùåíî îäèí ðÿäîê"
+
+#, 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: Ðÿäîê ñòຠçàíàäòî äîâãèì"
+
+# msgstr "E340: "
+#, c-format
+msgid "E341: Internal error: lalloc(%ld, )"
+msgstr "E341: Âíóòð³øíÿ ïîìèëêà: lalloc(%ld, )"
+
+# msgstr "E341: "
+#, c-format
+msgid "E342: Out of memory! (allocating %lu bytes)"
+msgstr "E342: Çàáðàêëî ïàì'ÿò³! (ïîòð³áíî áóëî %lu áàéò³â)"
+
+# msgstr "E342: "
+#, 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: Íåïðàâèëüíèé âèãëÿä ìèø³"
+
+msgid "E548: digit expected"
+msgstr "E548: Ïîòð³áíà öèôðà"
+
+msgid "E549: Illegal percentage"
+msgstr "E549: Íåïðàâèëüíèé â³äñîòîê"
+
+msgid "Enter encryption key: "
+msgstr "Âêàæ³òü êëþ÷ øèôðó: "
+
+msgid "Enter same key again: "
+msgstr "Ïîâòîð³òü êëþ÷: "
+
+msgid "Keys don't match!"
+msgstr "Êëþ÷³ íå îäíàêîâ³!"
+
+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'."
+
+# msgstr "E343: "
+#, c-format
+msgid "E344: Can't find directory \"%s\" in cdpath"
+msgstr "E344: Íå âäàëîñÿ çíàéòè êàòàëîã «%s» ó cdpath"
+
+# msgstr "E344: "
+#, c-format
+msgid "E345: Can't find file \"%s\" in path"
+msgstr "E345: Íå âäàëîñÿ çíàéòè ôàéë «%s» ó path"
+
+# msgstr "E345: "
+#, c-format
+msgid "E346: No more directory \"%s\" found in cdpath"
+msgstr "E346: Ó cdpath íåìຠá³ëüøå êàòàëîãó «%s»"
+
+# msgstr "E346: "
+#, c-format
+msgid "E347: No more file \"%s\" found in path"
+msgstr "E347: Ó øëÿõó ïîøóêó á³ëüøå íåìຠôàéë³â «%s»"
+
+msgid "Cannot connect to Netbeans #2"
+msgstr "Íå âäàëîñÿ ç'ºäíàòèñÿ ³ç Netbeans #2"
+
+msgid "Cannot connect to Netbeans"
+msgstr "Íå âäàëîñÿ ç'ºäíàòèñÿ ³ç Netbeans"
+
+#, c-format
+msgid "E668: Wrong access mode for NetBeans connection info file: \"%s\""
+msgstr ""
+"E668: Íåïðàâèëüíèé ðåæèì äîñòóïó äî ôàéëó ³íôîðìàö³¿ ïðî ç'ºäíàííÿ ç "
+"NetBenans: «%s»"
+
+msgid "read from Netbeans socket"
+msgstr "÷èòàºòüñÿ ç ñîêåòà Netbeans"
+
+#, 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 ò³ëüêè äëÿ ÷èòàííÿ (! ùîá íå çâàæàòè)"
+
+# msgstr "E348: "
+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 :quit<Enter> to exit Vim"
+msgstr "Óâåä³òü :quit<Enter> ùîá âèéòè ç Vim"
+
+#, c-format
+msgid "1 line %sed 1 time"
+msgstr "Îäèí ðÿäîê %s-íî"
+
+#, c-format
+msgid "1 line %sed %d times"
+msgstr "Îäèí ðÿäîê %s-íî %d ðàç³â"
+
+#, c-format
+msgid "%ld lines %sed 1 time"
+msgstr "%ld ðÿäê³â %s-íî"
+
+#, 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 "Âèð³âíÿíî îäèí ðÿäîê"
+
+#, c-format
+msgid "%ld lines indented "
+msgstr "Âèð³âíÿíî ðÿäê³â: %ld"
+
+msgid "E748: No previously used register"
+msgstr "E748: Ðåã³ñòðè ïåðåä öèì íå âæèâàëèñü"
+
+#. must display the prompt
+msgid "cannot yank; delete anyway"
+msgstr "íå âäàëîñÿ çàïàì'ÿòàòè; âñå îäíî çíèùèòè?"
+
+msgid "1 line changed"
+msgstr "Îäèí ðÿäîê çì³íåíî"
+
+#, c-format
+msgid "%ld lines changed"
+msgstr "Çì³íåíî ðÿäê³â: %ld"
+
+#, c-format
+msgid "freeing %ld lines"
+msgstr "Çâ³ëüíåíî ðÿäê³â: %ld"
+
+msgid "block of 1 line yanked"
+msgstr "Çàïàì'ÿòàâ áëîê ç îäíîãî ðÿäêà"
+
+msgid "1 line yanked"
+msgstr "Çàïàì'ÿòàâ îäèí ðÿäîê"
+
+#, c-format
+msgid "block of %ld lines yanked"
+msgstr "Çàïàì'ÿòàâ áëîê ³ç %ld ðÿäê³â"
+
+#, c-format
+msgid "%ld lines yanked"
+msgstr "Çàïàì'ÿòàâ ðÿäê³â: %ld"
+
+#, c-format
+msgid "E353: Nothing in register %s"
+msgstr "E353: Ó ðåã³ñòð³ %s í³÷îãî íåìàº"
+
+# msgstr "E353: "
+#. Highlight title
+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"
+
+#, c-format
+msgid "%ld Cols; "
+msgstr "äîâæ.: %ld; "
+
+#, c-format
+msgid "Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Bytes"
+msgstr "Âèáðàíî %s%ld ç %ld ðÿäê³â; %ld ç %ld ñë³â; %ld ç %ld áàéò³â"
+
+#, c-format
+msgid ""
+"Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Chars; %ld of %ld "
+"Bytes"
+msgstr ""
+"Âèáðàíî %s%ld ç %ld ðÿäê³â; %ld ç %ld ñë³â; %ld of %ld ñèìâîë³â; %ld ç %ld "
+"áàéò³â"
+
+#, c-format
+msgid "Col %s of %s; Line %ld of %ld; Word %ld of %ld; Byte %ld of %ld"
+msgstr "Êîëîíêà %s ç %s; ðÿäîê %ld ç %ld; ñëîâî %ld ç %ld; áàéò %ld ç %ld"
+
+#, c-format
+msgid ""
+"Col %s of %s; Line %ld of %ld; Word %ld of %ld; Char %ld of %ld; Byte %ld of "
+"%ld"
+msgstr ""
+"Êîëîíêà %s ç %s; ðÿäîê %ld ç %ld; ñëîâî %ld ç %ld; ñèìâîë %ld of %ld; áàéò "
+"%ld ç %ld"
+
+#, c-format
+msgid "(+%ld for BOM)"
+msgstr "(+%ld äëÿ BOM)"
+
+msgid "%<%f%h%m%=Page %N"
+msgstr "%<%f%h%m%=Ñòîð. %N"
+
+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: Íå äîçâîëåíî ó modeline"
+
+msgid "E846: Key code not set"
+msgstr "E846: Êîä êëþ÷à íå âñòàíîâëåíî"
+
+msgid "E521: Number required after ="
+msgstr "E521: ϳñëÿ = ïîòð³áíî âêàçàòè ÷èñëî"
+
+msgid "E522: Not found in termcap"
+msgstr "E522: Íå çíàéäåíî ñåðåä ìîæëèâîñòåé òåðì³íàë³â"
+
+#, c-format
+msgid "E539: Illegal character <%s>"
+msgstr "E539: Íåäîçâîëåíèé ñèìâîë <%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: Íå ìîæíà çì³íèòè â GUI GTK+ 2"
+
+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: Íå âäàëîñÿ âèáðàòè íàá³ð øðèôò³â"
+
+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>"
+
+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 "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'"
+
+#, 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"
+
+#. 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.
+#, c-format
+msgid "E521: Number required: &%s = '%s'"
+msgstr "E521: Ïîòð³áíî âêàçàòè Number: &%s = '%s'"
+
+# msgstr "E355: "
+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"
+
+# msgstr "E356: "
+#, c-format
+msgid "E357: 'langmap': Matching character missing for %s"
+msgstr "E357: 'langmap': Äëÿ ñèìâîëó %s íåìຠïàðè"
+
+# msgstr "E357: "
+#, c-format
+msgid "E358: 'langmap': Extra characters after semicolon: %s"
+msgstr "E358: 'langmap': Çàéâ³ ñèìâîëè ï³ñëÿ `;': %s"
+
+# 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"
+
+#, 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"
+
+# msgstr "E359: "
+msgid "mch_get_shellsize: not a console??\n"
+msgstr "mch_get_shellsize: íå êîíñîëü??\n"
+
+#. if Vim opened a window: Executing a shell may cause crashes
+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: Íå âäàëîñÿ âèáðàòè ïðèíòåð"
+
+#, 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 "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 "Äèñïëåé Õ íå ïðîéøîâ ïåðåâ³ðêó"
+
+msgid "Opening the X display timed out"
+msgstr "Ñïëèâ ÷àñ î÷³êóâàííÿ â³äêðèòòÿ äèñïëåþ Õ"
+
+msgid ""
+"\n"
+"Could not get security context for "
+msgstr ""
+"\n"
+"Íå âäàëîñÿ îòðèìàòè êîíòåêñò áåçïåêè äëÿ "
+
+msgid ""
+"\n"
+"Could not set security context for "
+msgstr ""
+"\n"
+"Íå âäàëîñÿ âñòàíîâèòè êîíòåêñò áåçïåêè äëÿ "
+
+msgid ""
+"\n"
+"Cannot execute shell "
+msgstr ""
+"\n"
+"Íå âäàëîñÿ çàïóñòèòè îáîëîíêó"
+
+msgid ""
+"\n"
+"Cannot execute shell sh\n"
+msgstr ""
+"\n"
+"Íå âäàëîñÿ çàïóñòèòè îáîëîíêó `sh'\n"
+
+# msgstr "E362: "
+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"
+"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 "shell returned %d"
+msgstr "îáîëîíêà ïîâåðíóëà %d"
+
+#, c-format
+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 "E371: "
+#, c-format
+msgid "E372: Too many %%%c in format string"
+msgstr "E372: Çàáàãàòî %%%c ó ðÿäêó ôîðìàòó"
+
+# msgstr "E372: "
+#, c-format
+msgid "E373: Unexpected %%%c in format string"
+msgstr "E373: Íåî÷³êóâàíèé `%%%c' ó ðÿäêó ôîðìàòó"
+
+# msgstr "E373: "
+msgid "E374: Missing ] in format string"
+msgstr "E374: Ïðîïóùåíî ] ó ðÿäêó ôîðìàòó"
+
+# msgstr "E374: "
+#, c-format
+msgid "E375: Unsupported %%%c in format string"
+msgstr "E375: %%%c ó ðÿäêó ôîðìàòó íå ï³äòðèìóºòüñÿ"
+
+# msgstr "E375: "
+#, c-format
+msgid "E376: Invalid %%%c in format string prefix"
+msgstr "E376: Ïîìèëêîâèé `%%%c' ó ïðåô³êñ³ ðÿäêó ôîðìàòó"
+
+# msgstr "E376: "
+#, c-format
+msgid "E377: Invalid %%%c in format string"
+msgstr "E377: Ïîìèëêîâèé `%%%c' ó ðÿäêó ôîðìàòó"
+
+# msgstr "E377: "
+msgid "E378: 'errorformat' contains no pattern"
+msgstr "E378: 'errorformat' íå ì³ñòèòü çðàçîê"
+
+# msgstr "E378: "
+msgid "E379: Missing or empty directory name"
+msgstr "E379: Ïðîïóùåíà ÷è ïîðîæíÿ íàçâà êàòàëîãó"
+
+msgid "E553: No more items"
+msgstr "E553: Íåìຠá³ëüøå åëåìåíò³â"
+
+#, c-format
+msgid "(%d of %d)%s%s: "
+msgstr "(%d ç %d)%s%s: "
+
+msgid " (line deleted)"
+msgstr " (ðÿäîê çíèùåíî)"
+
+msgid "E380: At bottom of quickfix stack"
+msgstr "E380: Äíî ñòåêó âèïðàâëåíü"
+
+msgid "E381: At top of quickfix stack"
+msgstr "E381: Âåðøèíà ñòåêó âèïðàâëåíü"
+
+#, c-format
+msgid "error list %d of %d; %d errors"
+msgstr "ñïèñîê ïîìèëîê %d ç %d; %d ïîìèëîê"
+
+msgid "E382: Cannot write, 'buftype' option is set"
+msgstr "E382: Íå ìîæó çàïèñàòè, âêàçàíà îïö³ÿ 'buftype'"
+
+# msgstr "E231: "
+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["
+
+#, 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)"
+
+# msgstr "E406: "
+msgid "E66: \\z( not allowed here"
+msgstr "E66: \\z( òóò íå äîçâîëåíî"
+
+# msgstr "E406: "
+msgid "E67: \\z1 et al. not allowed here"
+msgstr "E67: \\z1 òà ³í. òóò íå äîçâîëåíî"
+
+#, c-format
+msgid "E69: Missing ] after %s%%["
+msgstr "E69: Ïðîïóùåíî ] ï³ñëÿ %s%%["
+
+#, c-format
+msgid "E70: Empty %s%%[]"
+msgstr "E70: %s%%[] ïîðîæí³é"
+
+# msgstr "E382: "
+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{...}"
+
+# msgstr "E339: "
+#, c-format
+msgid "E61: Nested %s*"
+msgstr "E61: Âêëàäåí³ %s*"
+
+# msgstr "E61: "
+#, c-format
+msgid "E62: Nested %s%c"
+msgstr "E62: Âêëàäåí³ %s%c"
+
+msgid "E63: invalid use of \\_"
+msgstr "E63: Íåêîðåêòíî âæèòî \\_"
+
+# msgstr "E62: "
+#, c-format
+msgid "E64: %s%c follows nothing"
+msgstr "E64: ϳñëÿ %s%c í³÷îãî íåìàº"
+
+msgid "E65: Illegal back reference"
+msgstr "E65: Íåêîðåêòíå çâîðîòíº ïîñèëàííÿ"
+
+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%%"
+
+# msgstr "E64: "
+#, c-format
+msgid "E554: Syntax error in %s{...}"
+msgstr "E554: Ñèíòàêñè÷íà ïîìèëêà â %s{...}"
+
+msgid "External submatches:\n"
+msgstr "Çîâí³øí³ ï³ä-çá³ãè:\n"
+
+msgid ""
+"E864: \\%#= can only be followed by 0, 1, or 2. The automatic engine will be "
+"used "
+msgstr ""
+"E864: ï³ñëÿ \\%#= ìîæå áóòè ò³ëüêè 0, 1, or 2. Áóäå âèêîðèñòàíî àâòîìàòè÷íèé ìåõàí³çì "
+
+#, c-format
+msgid "E866: (NFA regexp) Misplaced %c"
+msgstr "E866: (NFA regexp) Íå íà ì³ñö³ %c"
+
+msgid "E865: (NFA) Regexp end encountered prematurely"
+msgstr "E865: (NFA) Çàðàíî òðàïèâñÿ ê³íåöü ðåãóëÿðíîãî âèðàçó"
+
+#, c-format
+msgid "E867: (NFA) Unknown operator '\\z%c'"
+msgstr "E867: (NFA) Íåâ³äîìèé îïåðàòîð '\\z%c'"
+
+#, c-format
+msgid "E867: (NFA) Unknown operator '\\%%%c'"
+msgstr "E867: (NFA) Íåâ³äîìèé îïåðàòîð '\\%%%c'"
+
+#. should never happen
+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) Íå âäàëîñÿ ïðî÷èòàòè ìåæ³ ïîâòîðåííÿ"
+
+#. Can't have a multi follow a multi.
+msgid "E871: (NFA regexp) Can't have a multi follow a multi !"
+msgstr "E871: (NFA regexp) Ìóëüòè íå ìîæå áóòè çà ìóëüòè!"
+
+#. Too many `('
+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) (ϳä ÷àñ ïåðåòâîðåííÿ ç ïîñòô³êñ ó 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 " (lang)"
+msgstr " (ìîâà)"
+
+msgid " (paste)"
+msgstr " (êëåé)"
+
+msgid " VISUAL"
+msgstr " ÂÈÁ²Ð"
+
+msgid " VISUAL LINE"
+msgstr " ÂÈÁ²Ð ÐßÄʲÂ"
+
+msgid " VISUAL BLOCK"
+msgstr " ÂÈÁ²Ð ÁËÎÊÓ"
+
+msgid " SELECT"
+msgstr " ÂÈIJËÅÍÍß"
+
+msgid " SELECT LINE"
+msgstr " ÂÈIJËÅÍÍß ÐßÄʲÂ"
+
+msgid " SELECT BLOCK"
+msgstr " ÂÈIJËÅÍÍß ÁËÎÊÓ"
+
+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: ϳñëÿ `;' ìຠáóòè `?' àáî `/'"
+
+# msgstr "E386: "
+msgid " (includes previously listed match)"
+msgstr " (ðàçîì ç ïîïåðåäí³ìè çá³ãàìè)"
+
+#. cursor at status line
+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 "E759: Format error in spell file"
+msgstr "E759: Ïîìèëêà ôîðìàòó ó ôàéë³ îðôîãðàô³¿"
+
+# msgstr "E364: "
+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"
+
+# msgstr "E430: "
+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 "Ñòèñêóºòüñÿ äåðåâî ñë³â..."
+
+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»"
+
+#, 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 "Warning: region %s not supported"
+msgstr "Çàñòåðåæåííÿ: ðåã³îí %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 ó ðÿäêó %d"
+
+#, c-format
+msgid ""
+"Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in %s line "
+"%d"
+msgstr ""
+"Âèçíà÷åííÿ COMPOUNDPERMITFLAG ï³ñëÿ åëåìåíòó PFX ìîæó äàòè íåïðàâèëüíèé "
+"ðåçóëüòàò ó %s ó ðÿäêó %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 %6d - %s"
+msgstr "ðÿäîê %6d, ñëîâî %6d - %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 "Ïåðå÷èòóºòüñÿ ôàéë îðôîãðàô³¿..."
+
+#.
+#. * Go through the trie of good words, soundfold each word and add it to
+#. * the soundfold trie.
+#.
+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: Âèõ³äíèé ôàéë íå ïîâèíåí ìàòè íàçâó ðåã³îíó"
+
+msgid "E754: Only up to 8 regions supported"
+msgstr "E754: ϳäòðèìóºòüñÿ ò³ëüêè äî âîñüìè ðåã³îí³â"
+
+#, 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 "Sorry, no suggestions"
+msgstr "Ïðîáà÷òå, íåìຠïðîïîçèö³é"
+
+#, c-format
+msgid "Sorry, only %ld suggestions"
+msgstr "Ïðîáà÷òå, ò³ëüêè %ld ïðîïîçèö³é"
+
+#. for when 'cmdheight' > 1
+#. avoid more prompt
+#, c-format
+msgid "Change \"%.*s\" to:"
+msgstr "Çàì³íèòè «%.*s» íà:"
+
+#, c-format
+msgid " < \"%.*s\""
+msgstr " < «%.*s»"
+
+# msgstr "E34: "
+msgid "E752: No previous spell replacement"
+msgstr "E752: Íåìຠïîïåðåäíüî¿ çàì³íè"
+
+# msgstr "E333: "
+#, c-format
+msgid "E753: Not found: %s"
+msgstr "E753: Íå çíàéäåíî: %s"
+
+#, 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"
+
+#. This should have been checked when generating the .spl
+#. * file.
+msgid "E783: duplicate char in MAP entry"
+msgstr "E783: Ïîâòîðåíî ñèìâîë ó åëåìåíò³ MAP"
+
+# msgstr "E391: "
+msgid "No Syntax items defined for this buffer"
+msgstr "Äëÿ áóôåðà íå âèçíà÷åíî åëåìåíò³â ñèíòàêñèñó"
+
+#, c-format
+msgid "E390: Illegal argument: %s"
+msgstr "E390: Íåïðàâèëüíèé àðãóìåíò: %s"
+
+#, c-format
+msgid "E391: No such syntax cluster: %s"
+msgstr "E391: Íåìຠòàêîãî ñèíòàêñè÷íîãî êëàñòåðà: %s"
+
+msgid "syncing on C-style comments"
+msgstr "ñèíõðîí³çóºòüñÿ ïî êîìåíòàðÿõ ñòèëþ Ñ"
+
+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: ̳ñòèòü íåïðèéíÿòí³ òóò àðãóìåíòè"
+
+# msgstr "E14: "
+msgid "E844: invalid cchar value"
+msgstr "E844: Íåêîðåêòíå çíà÷åííÿ cchar"
+
+msgid "E393: group[t]here not accepted here"
+msgstr "E393: group[t]hete òóò íåïðèéíÿòíèé"
+
+#, c-format
+msgid "E394: Didn't find region item for %s"
+msgstr "E394: Íå çíàéäåíî åëåìåíò ðåã³îíó äëÿ %s"
+
+# msgstr "E396: "
+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 "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"
+
+# msgstr "E402: "
+msgid "E403: syntax sync: line continuations pattern specified twice"
+msgstr ""
+"E403: Ñèíòàêñè÷íà ñèíõðîí³çàö³ÿ: çðàçîê äëÿ ïðîäîâæåííÿ ðÿäêà âêàçàíî äâ³÷³"
+
+#, c-format
+msgid "E404: Illegal arguments: %s"
+msgstr "E404: Íåïðàâèëüí³ àðãóìåíòè: %s"
+
+# msgstr "E404: "
+#, c-format
+msgid "E405: Missing equal sign: %s"
+msgstr "E405: Ïðîïóùåíî çíàê ð³âíîñò³: %s"
+
+# msgstr "E405: "
+#, c-format
+msgid "E406: Empty argument: %s"
+msgstr "E406: Ïîðîæí³é àðãóìåíò: %s"
+
+# msgstr "E406: "
+#, 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"
+
+# msgstr "E409: "
+#, 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"
+
+# msgstr "E410: "
+#, c-format
+msgid "E411: highlight group not found: %s"
+msgstr "E411: Ãðóïó ï³äñâ³÷óâàííÿ íå çíàéäåíî: %s"
+
+# msgstr "E411: "
+#, c-format
+msgid "E412: Not enough arguments: \":highlight link %s\""
+msgstr "E412: Íåäîñòàòíüî àðãóìåíò³â: «:highlight link %s»"
+
+# msgstr "E412: "
+#, c-format
+msgid "E413: Too many arguments: \":highlight link %s\""
+msgstr "E413: Çàáàãàòî àðãóìåíò³â: «:highlight link %s»"
+
+# msgstr "E413: "
+msgid "E414: group has settings, highlight link ignored"
+msgstr "E414: Ãðóìà ìຠsettings, highlight link ïðî³ãíîðîâàíî"
+
+# msgstr "E414: "
+#, c-format
+msgid "E415: unexpected equal sign: %s"
+msgstr "E415: Íåñïîä³âàíèé çíàê ð³âíîñò³: %s"
+
+# msgstr "E415: "
+#, 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"
+
+# msgstr "E418: "
+msgid "E419: FG color unknown"
+msgstr "E419: Íåâ³äîìèé êîë³ð òåêñòó"
+
+# msgstr "E419: "
+msgid "E420: BG color unknown"
+msgstr "E420: Íåâ³äîìèé êîë³ð ôîíó"
+
+# msgstr "E420: "
+#, c-format
+msgid "E421: Color name or number not recognized: %s"
+msgstr "E421: Íåðîçï³çíàíà íàçâà àáî íîìåð êîëüîðó: %s"
+
+# msgstr "E421: "
+#, c-format
+msgid "E422: terminal code too long: %s"
+msgstr "E422: Çàíàäòî äîâãèé êîä òåðì³íàëó: %s"
+
+# msgstr "E422: "
+#, c-format
+msgid "E423: Illegal argument: %s"
+msgstr "E423: Íåïðàâèëüíèé àðãóìåíò: %s"
+
+# msgstr "E423: "
+msgid "E424: Too many different highlighting attributes in use"
+msgstr "E424: Âèêîðèñòàíî çàáàãàòî ð³çíèõ àòðèáóò³â êîëüîðó"
+
+msgid "E669: Unprintable character in group name"
+msgstr "E669: Íåäðóêîâíèé ñèìâîë ó íàçâ³ ãðóïè"
+
+# msgstr "E181: "
+msgid "W18: Invalid character in group name"
+msgstr "W18: Íåêîðåêòíèé ñèìâîë ó íàçâ³ ãðóïè"
+
+msgid "E849: Too many highlight and syntax groups"
+msgstr "E849: Çàáàãàòî ãðóï ï³äñâ³÷óâàííÿ ³ ñèíòàêñèñó"
+
+# msgstr "E424: "
+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: Öå âæå íàéïåðøèé â³äïîâ³äíèé òå´"
+
+# msgstr "E425: "
+#, c-format
+msgid "E426: tag not found: %s"
+msgstr "E426: Òå´ íå çíàéäåíî: %s"
+
+# msgstr "E426: "
+msgid " # pri kind tag"
+msgstr " # ïð³ òèï òå´"
+
+msgid "file\n"
+msgstr "ôàéë\n"
+
+msgid "E427: There is only one matching tag"
+msgstr "E427: Ëèøå îäèí â³äïîâ³äíèé òå´"
+
+# msgstr "E427: "
+msgid "E428: Cannot go beyond last matching tag"
+msgstr "E428: Öå âæå îñòàíí³é â³äïîâ³äíèé òå´"
+
+# msgstr "E428: "
+#, c-format
+msgid "File \"%s\" does not exist"
+msgstr "Ôàéë «%s» íå ³ñíóº"
+
+#. Give an indication of the number of matching tags
+#, 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» íå ³ñíóº"
+
+# msgstr "E429: "
+#. Highlight title
+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 "²ãíîðóºòüñÿ äîâãèé ðÿäîê ó ôàéë³ ç ïîçíà÷êàìè"
+
+# msgstr "E430: "
+#, c-format
+msgid "E431: Format error in tags file \"%s\""
+msgstr "E431: Ïîìèëêà ôîðìàòó ó ôàéë³ ò崳⠫%s»"
+
+# msgstr "E431: "
+#, c-format
+msgid "Before byte %ld"
+msgstr "Ïåðåä áàéòîì %ld"
+
+#, c-format
+msgid "E432: Tags file not sorted: %s"
+msgstr "E432: Ôàéë òå´³â íå âïîðÿäêîâàíèé: %s"
+
+# msgstr "E432: "
+#. never opened any tags file
+msgid "E433: No tags file"
+msgstr "E433: Íåìຠôàéëó òå´³â"
+
+# msgstr "E433: "
+msgid "E434: Can't find tag pattern"
+msgstr "E434: Íå âäàëîñÿ çíàéòè çðàçîê òå´ó"
+
+# msgstr "E434: "
+msgid "E435: Couldn't find tag, just guessing!"
+msgstr "E435: Íå âäàëîñÿ çíàéòè òå´, ò³ëüêè ïðèïóùåííÿ!"
+
+#, c-format
+msgid "Duplicate field name: %s"
+msgstr "Íàçâà ïîëÿ ïîâòîðþºòüñÿ: %s"
+
+# msgstr "E435: "
+msgid "' not known. Available builtin terminals are:"
+msgstr "' íå â³äîìèé. Âáóäîâàí³ òåðì³íàëè:"
+
+msgid "defaulting to '"
+msgstr "ïî÷àòêîâî '"
+
+msgid "E557: Cannot open termcap file"
+msgstr "E557: Íå âäàëîñÿ â³äêðèòè ôàéë ìîæëèâîñòåé òåðì³íàë³â"
+
+msgid "E558: Terminal entry not found in terminfo"
+msgstr "E558: Íåìຠ³íôîðìàö³¿ ïðî òåðì³íàë"
+
+msgid "E559: Terminal entry not found in termcap"
+msgstr "E559: Íåìຠ³íôîðìàö³¿ ïðî ìîæëèâîñò³ òåðì³íàëó"
+
+#, c-format
+msgid "E436: No \"%s\" entry in termcap"
+msgstr "E436: Íåìຠçàïèñó «%s» ïðî ìîæëèâîñò³ òåðì³íàëó"
+
+msgid "E437: terminal capability \"cm\" required"
+msgstr "E437: Ïîòð³áíà ìîæëèâ³ñòü òåðì³íàëó «cm»"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Terminal keys ---"
+msgstr ""
+"\n"
+"--- Êëàâ³ø³ òåðì³íàëó ---"
+
+msgid "new shell started\n"
+msgstr "çàïóùåíî íîâó îáîëîíêó\n"
+
+msgid "Vim: Error reading input, exiting...\n"
+msgstr "Vim: Ïîìèëêà ÷èòàííÿ ââîäó, ðîáîòà çàâåðøóºòüñÿ...\n"
+
+# msgstr "E242: "
+msgid "Used CUT_BUFFER0 instead of empty selection"
+msgstr "Âèêîðèñòàíî CUT_BUFFER0 çàì³ñòü ïîðîæíüîãî âèä³ëåííÿ"
+
+#. This happens when the FileChangedRO autocommand changes the
+#. * file in a way it becomes shorter.
+msgid "E834: Line count changed unexpectedly"
+msgstr "E834: ʳëüê³ñòü ðÿäê³â íåñïîä³âàíî çì³íèëàñÿ"
+
+#. must display the prompt
+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 "Will not overwrite with undo file, cannot read: %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"
+
+# msgstr "E333: "
+#, 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 "ðÿäê³â çíèùåíî"
+
+# msgstr "E438: "
+msgid "change"
+msgstr "çì³íà"
+
+# msgstr "E438: "
+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 ñåêóíä òîìó"
+
+# msgstr "E406: "
+msgid "E790: undojoin is not allowed after undo"
+msgstr "E790: Íå ìîæíà âèêîíàòè undojoin ï³ñëÿ undo"
+
+msgid "E439: undo list corrupt"
+msgstr "E439: Ñïèñîê ñêàñóâàííÿ ïîøêîäæåíî"
+
+# msgstr "E439: "
+msgid "E440: undo line missing"
+msgstr "E440: ³äñóòí³é ðÿäîê ñêàñóâàííÿ"
+
+# msgstr "E440: "
+# ---------------------------------------
+#. Only MS VC 4.1 and earlier can do Win32s
+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"
+"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 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 " Features included (+) or not (-):\n"
+msgstr " Âêëþ÷åí³ (+) àáî íå âêëþ÷åí³ (-) êîìïîíåíòè:\n"
+
+msgid " system vimrc file: \""
+msgstr " ñèñòåìíèé vimrc: \""
+
+msgid " user vimrc file: \""
+msgstr " vimrc êîðèñòóâà÷à: \""
+
+msgid " 2nd user vimrc file: \""
+msgstr " äðóãèé vimrc êîðèñòóâà÷à: \""
+
+msgid " 3rd user vimrc file: \""
+msgstr " òðåò³é vimrc êîðèñòóâà÷à: \""
+
+msgid " user exrc file: \""
+msgstr " exrc êîðèñòóâà÷à: \""
+
+msgid " 2nd user exrc file: \""
+msgstr " äðóãèé exrc êîðèñòóâà÷à: \""
+
+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 " 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 " ÂÅÐÑ²ß ÄËß ÍÀËÀÃÎÄÆÅÍÍß"
+
+msgid "VIM - Vi IMproved"
+msgstr "VIM - Ïîêðàùåíèé Vi"
+
+msgid "version "
+msgstr "âåðñ³ÿ "
+
+msgid "by Bram Moolenaar et al."
+msgstr "àâòîð: Bram Moolenaar òà ³í."
+
+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> âèõ³ä ç Vim "
+
+msgid "type :help<Enter> or <F1> for on-line help"
+msgstr ":help<Enter> àáî <F1> ïåðåãëÿä äîïîìîãè "
+
+msgid "type :help version7<Enter> for version info"
+msgstr ":help version7<Enter> ³íôîðìàö³ÿ ïðî âåðñ³þ "
+
+msgid "Running in Vi compatible mode"
+msgstr "Âè ïðàöþºòå â ðåæèì³ ñóì³ñíîìó ç Vi"
+
+msgid "type :set nocp<Enter> for Vim defaults"
+msgstr ":set nocp<Enter> ðåæèì íåñóì³ñíèé ç Vi "
+
+msgid "type :help cp-default<Enter> for info on this"
+msgstr ":help cp-default<Enter> ³íôîðìàö³ÿ ïðî ñóì³ñí³ñòü"
+
+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 "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 "WARNING: Windows 95/98/ME detected"
+msgstr "ÇÀÑÒÅÐÅÆÅÍÍß: Âè êîðèñòóºòåñÿ Windows 95/98/ME"
+
+msgid "type :help windows95<Enter> for info on this"
+msgstr ":help windows95<Enter> ³íôîðìàö³ÿ ïðî öå "
+
+# msgstr "E444: "
+msgid "Already only one window"
+msgstr "Öå âæå ºäèíå â³êíî"
+
+msgid "E441: There is no preview window"
+msgstr "E441: Íåìຠâ³êíà ïåðåãëÿäó"
+
+# msgstr "E441: "
+msgid "E442: Can't split topleft and botright at the same time"
+msgstr "E442: Íå âäàëîñÿ îäíî÷àñíî ðîçáèòè topleft ³ botright"
+
+# msgstr "E442: "
+msgid "E443: Cannot rotate when another window is split"
+msgstr "E443: Íå âäàëîñÿ ïåðåì³ñòèòè â³êíî, çàâàæàþòü ³íø³"
+
+# msgstr "E443: "
+msgid "E444: Cannot close last window"
+msgstr "E444: Íå âäàëîñÿ çàêðèòè îñòàííº â³êíî"
+
+# msgstr "E443: "
+msgid "E813: Cannot close autocmd window"
+msgstr "E813: Íå âäàëîñÿ çàêðèòè â³êíî autocmd"
+
+# msgstr "E443: "
+msgid "E814: Cannot close window, only autocmd window would remain"
+msgstr "E814: Íå âäàëîñÿ çàêðèòè â³êíî, çàëèøèëîñÿ á ò³ëüêè â³êíî autocmd"
+
+msgid "E445: Other window contains changes"
+msgstr "E445: Ó ³íøîìó â³êí³ º çì³íè"
+
+# msgstr "E445: "
+msgid "E446: No file name under cursor"
+msgstr "E446: Íåìຠíàçâè ôàéëó íàä êóðñîðîì"
+
+# msgstr "E446: "
+#, c-format
+msgid "E447: Can't find file \"%s\" in path"
+msgstr "E447: Ôàéë «%s» íå çíàéäåíî ó øëÿõó ïîøóêó"
+
+#, 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 çàáîðîíåíå ó ï³ñî÷íèö³ áåç ìîäóëÿ 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"
+
+#. Now concatenate
+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 "E447: "
+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.
+#.
+msgid "E470: Command aborted"
+msgstr "E470: Êîìàíäó ïåðåðâàíî"
+
+msgid "E471: Argument required"
+msgstr "E471: Íåîáõ³äíî âêàçàòè àðãóìåíò"
+
+msgid "E10: \\ should be followed by /, ? or &"
+msgstr "E10: Çà \\ ìຠéòè /, ? àáî &"
+
+# 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: Êîìàíäà íà âäàëàñü"
+
+# msgstr "E233: "
+#, c-format
+msgid "E234: Unknown fontset: %s"
+msgstr "E234: Íåâ³äîìèé íàá³ð øðèôò³â: %s"
+
+#, c-format
+msgid "E235: Unknown font: %s"
+msgstr "E235: Íåâ³äîìèé øðèôò: %s"
+
+# msgstr "E235: "
+#, c-format
+msgid "E236: Font \"%s\" is not fixed-width"
+msgstr "E236: Øðèôò «%s» íå ìîíîøèðèííèé"
+
+msgid "E473: Internal error"
+msgstr "E473: Âíóòð³øíÿ ïîìèëêà"
+
+msgid "Interrupted"
+msgstr "Ïåðåðâàíî"
+
+msgid "E14: Invalid address"
+msgstr "E14: Íåïðàâèëüíà àäðåñà"
+
+# msgstr "E14: "
+msgid "E474: Invalid argument"
+msgstr "E474: Íåêîðåêòíèé àðãóìåíò"
+
+#, c-format
+msgid "E475: Invalid argument: %s"
+msgstr "E475: Íåêîðåêòíèé àðãóìåíò: %s"
+
+#, c-format
+msgid "E15: Invalid expression: %s"
+msgstr "E15: Íåïðàâèëüíèé âèðàç: %s"
+
+# msgstr "E15: "
+msgid "E16: Invalid range"
+msgstr "E16: Íåïðàâèëüí³ ìåæ³"
+
+# 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()» íå âäàâñÿ"
+
+#, c-format
+msgid "E448: Could not load library function %s"
+msgstr "E448: Íå âäàëîñÿ çàâàíòàæèòè á³áë³îòå÷íó ôóíêö³þ %s"
+
+# msgstr "E18: "
+msgid "E19: Mark has invalid line number"
+msgstr "E19: Ó ïîì³òêè íåêîðåêòíèé íîìåð ðÿäêà"
+
+# msgstr "E19: "
+msgid "E20: Mark not set"
+msgstr "E20: Ïîì³òêó íå âñòàíîâëåíî"
+
+# msgstr "E20: "
+msgid "E21: Cannot make changes, 'modifiable' is off"
+msgstr "E21: Çì³íè íå äîçâîëåí³: âèìêíåíî 'modifiable'"
+
+# msgstr "E21: "
+msgid "E22: Scripts nested too deep"
+msgstr "E22: Çàáàãàòî âêëàäåíèõ ñêðèïò³â"
+
+# msgstr "E22: "
+msgid "E23: No alternate file"
+msgstr "E23: Íåìຠâòîðèííîãî ôàéëó"
+
+# msgstr "E23: "
+msgid "E24: No such abbreviation"
+msgstr "E24: Òàêîãî ñêîðî÷åííÿ íåìàº"
+
+# 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"
+
+# msgstr "E25: "
+#, c-format
+msgid "E28: No such highlight group name: %s"
+msgstr "E28: Íåìຠòàêî¿ ãðóïè ï³äñâ³÷óâàííÿ: %s"
+
+# msgstr "E28: "
+msgid "E29: No inserted text yet"
+msgstr "E29: Òåêñò ùå íå áóëî äîäàíî"
+
+# msgstr "E29: "
+msgid "E30: No previous command line"
+msgstr "E30: Ùå íå áóëî êîìàíä"
+
+# msgstr "E30: "
+msgid "E31: No such mapping"
+msgstr "E31: Íåìຠòàêî¿ çàì³íè"
+
+# 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: Áðàêóº íàçâè ôàéëó"
+
+# msgstr "E32: "
+msgid "E33: No previous substitute regular expression"
+msgstr "E33: Çàì³íà çðàçê³â ùå íå âèêîðèñòîâóâàëàñü"
+
+# msgstr "E33: "
+msgid "E34: No previous command"
+msgstr "E34: Êîìàíä ùå íå áóëî"
+
+# msgstr "E34: "
+msgid "E35: No previous regular expression"
+msgstr "E35: Çðàçê³â ïîøóêó ùå íå áóëî"
+
+# 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»"
+
+# msgstr "E36: "
+#, 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 "E37: No write since last change (add ! to override)"
+msgstr "E37: Çì³íè íå áóëî çàïèñàíî (! ùîá íå çâàæàòè)"
+
+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: dzïñîâàíà ïðîãðàìà ðåãóëÿðíèõ âèðàç³â"
+
+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: Íå ìîæíà âñòàíîâèòè çì³ííó ó ï³ñî÷íèö³: «%s»"
+
+msgid "E47: Error while reading errorfile"
+msgstr "E47: Ïîìèëêà ÷èòàííÿ ôàéëó ïîìèëîê"
+
+msgid "E48: Not allowed in sandbox"
+msgstr "E48: Íà äîçâîëåíî ó ï³ñî÷íèö³"
+
+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' ïîðîæíÿ"
+
+# msgstr "E254: "
+msgid "E255: Couldn't read in sign data!"
+msgstr "E255: Íå ìîæíà ç÷èòàòè äàí³ íàïèñó!"
+
+msgid "E72: Close error on swap file"
+msgstr "E72: Ïîìèëêà ï³ä ÷àñ çàêðèòòÿ ôàéëó îáì³íó"
+
+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'"
+
+# msgstr "E79: "
+msgid "E80: Error while writing"
+msgstr "E80: Ïîìèëêà ï³ä ÷àñ çàïèñó"
+
+msgid "Zero count"
+msgstr "Íóëüîâà ê³ëüê³ñòü"
+
+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 íå äîçâîëÿº çì³íþâàòè çàõèùåí³ â³ä çàïèñó ôàéëè"
+
+#, c-format
+msgid "E685: Internal error: %s"
+msgstr "E685: Âíóòð³øíÿ ïîìèëêà: %s"
+
+msgid "E363: pattern uses more memory than 'maxmempattern'"
+msgstr "E363: Çðàçîê âèêîðèñòîâóº á³ëüøå, í³æ 'maxmempattern', ïàì'ÿò³"
+
+msgid "E749: empty buffer"
+msgstr "E749: Ïîðîæí³é áóôåð"
+
+msgid "E682: Invalid search pattern or delimiter"
+msgstr "E682: Íåêîðåêòíèé çðàçîê äëÿ ïîøóêó ÷è ðîçä³ëüíèê"
+
+msgid "E139: File is loaded in another buffer"
+msgstr "E139: Ôàéë óæå çàâàíòàæåíî â ³íøèé áóôåð"
+
+# msgstr "E235: "
+#, c-format
+msgid "E764: Option '%s' is not set"
+msgstr "E764: Îïö³ÿ '%s' íå âñòàíîâëåíà"
+
+msgid "E850: Invalid register name"
+msgstr "E850: Íåïðàâèëüíà íàçâà ðåã³ñòðó"
+
+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» ïîòð³áåí êëþ÷: "
+
+# msgstr "E406: "
+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 "³íäåêñ ìຠáóòè ö³ëèé ÷è çð³ç, íå %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 then zero"
+msgstr "÷èñëî ìຠáóòè á³ëüøå, í³æ íóëü"
+
+msgid "number must be greater or equal to zero"
+msgstr "÷èñëî ìຠáóòè íå ìåíøå, í³æ íóëü"
+
+msgid "can't delete OutputObject attributes"
+msgstr "íå âäàëîñÿ çíèùèòè àòðèáóòè OutputObject"
+
+# msgstr "E180: "
+#, 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 "î÷³êóâàâñÿ 3-êîðòåæ ÿê ðåçóëüòàò imp.find_module(), àëå îòðèìàíî %s"
+
+#, c-format
+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 "íå ìîæíà çì³íèòè ô³êñîâàíèé ñëîâíèê"
+
+#, c-format
+msgid "cannot set attribute %s"
+msgstr "íå ìîæíà âñòàíîâèòè àòðèáóò %s"
+
+msgid "hashtab changed during iteration"
+msgstr "õåø-òàáëèöÿ çì³íèëàñÿ ï³ä ÷àñ ïåðåáèðàííÿ"
+
+#, 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 "³íäåêñ ñïèñêó çà ìåæàìè"
+
+#. No more suitable format specifications in python-2.3
+#, c-format
+msgid "internal error: failed to get vim list item %d"
+msgstr "âíóòð³øíÿ ïîìèëêà: íå âäàëîñÿ îòðèìàòè åëåìåíò ñïèñêó vim %d"
+
+msgid "failed to add item to list"
+msgstr "íå âäàëîñÿ äîäàòè åëåìåíò äî ñïèñêó"
+
+#, c-format
+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: "
+#, c-format
+msgid "unnamed function %s does not exist"
+msgstr "áåç³ìåííî¿ ôóíêö³¿ %s íå ³ñíóº"
+
+# msgstr "E428: "
+#, c-format
+msgid "function %s does not exist"
+msgstr "ôóíêö³¿ %s íå ³ñíóº"
+
+msgid "function constructor does not accept keyword arguments"
+msgstr "êîíñòðóêòîð ôóíêö³¿ íå ïðèéìຠ³ìåíîâàí³ àðãóìåíòè"
+
+#, 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 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/po/uk.po b/src/po/uk.po
new file mode 100644
index 0000000000..645a992785
--- /dev/null
+++ b/src/po/uk.po
@@ -0,0 +1,7027 @@
+#
+# 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: 2013-09-29 09:05+0300\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=utf-8\n"
+"Content-Transfer-Encoding: 8bit\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 (BE/LE)"
+
+msgid "E818: sha256 test failed"
+msgstr "E818: Ðе пройшла перевірка sha256"
+
+msgid "E819: Blowfish test failed"
+msgstr "E819: Ðе пройшла перевірка Blowfish"
+
+msgid "[Location List]"
+msgstr "[СпиÑок міÑць]"
+
+msgid "[Quickfix List]"
+msgstr "[СпиÑок виправлень]"
+
+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 "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 "Вивантажено один буфер"
+
+#, c-format
+msgid "%d buffers unloaded"
+msgstr "Вивантажено %d буфери(ів)"
+
+msgid "1 buffer deleted"
+msgstr "Знищено один буфер"
+
+#, c-format
+msgid "%d buffers deleted"
+msgstr "Знищено %d буфери(ів)"
+
+msgid "1 buffer wiped out"
+msgstr "Витерто один буфер"
+
+#, c-format
+msgid "%d buffers wiped out"
+msgstr "Витерто %d буфери(ів)"
+
+msgid "E84: No modified buffer found"
+msgstr "E84: Жоден буфер не змінено"
+
+#. back where we started, didn't find anything.
+msgid "E85: There is no listed buffer"
+msgstr "E85: У ÑпиÑку немає буферів"
+
+#, c-format
+msgid "E86: Buffer %ld does not exist"
+msgstr "E86: Буфера %ld немає"
+
+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 "E90: Cannot unload last buffer"
+msgstr "E90: Ðе можу вивантажити оÑтанній буфер"
+
+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 "[RO]"
+
+msgid "[readonly]"
+msgstr "[лише читати]"
+
+#, c-format
+msgid "1 line --%d%%--"
+msgstr "один Ñ€Ñдок --%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 "[Без назви]"
+
+#. must be a help buffer
+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 "[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 id=%d назва=%s"
+
+#, c-format
+msgid "E96: Can not 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: Ðе вдалоÑÑ Ñтворити порівнÑннÑ"
+
+msgid "Patch file"
+msgstr "Латка"
+
+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: Цей буфер не в режимі порівнÑннÑ"
+
+msgid "E793: No other buffer in diff mode is modifiable"
+msgstr "E793: Ðемає більше модифіковних буферів в режимі порівнÑннÑ"
+
+msgid "E100: No other buffer in diff mode"
+msgstr "E100: Ðемає інших буферів в режимі порівнÑннÑ"
+
+msgid "E101: More than two buffers in diff mode, don't know which one to use"
+msgstr ""
+"E101: Понад два буфери у режимі порівнÑннÑ, не зрозуміло, котрий із них "
+"викориÑтати"
+
+#, 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» не в режимі порівнÑннÑ"
+
+msgid "E787: Buffer changed unexpectedly"
+msgstr "E787: Буфер неÑподівано змінивÑÑ"
+
+msgid "E104: Escape not allowed in digraph"
+msgstr "E104: У диграфах не може міÑтитиÑÑ escape"
+
+msgid "E544: Keymap file not found"
+msgstr "E544: Ðе знайдено файл розкладки"
+
+msgid "E105: Using :loadkeymap not in a sourced file"
+msgstr "E105: :loadkeymap викориÑтано не у файлі команд"
+
+msgid "E791: Empty keymap entry"
+msgstr "E791: Елемент розкладки порожній"
+
+msgid " Keyword completion (^N^P)"
+msgstr " Ð”Ð¾Ð¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ ÐºÐ»ÑŽÑ‡Ð¾Ð²Ð¸Ñ… Ñлів (^N^P)"
+
+#. ctrl_x_mode == 0, ^P/^N compl.
+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 " Кмітливе Ð´Ð¾Ð¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ (^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 "ТрапивÑÑ ÐºÑ–Ð½ÐµÑ†ÑŒ параграфа"
+
+# msgstr "E443: "
+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 " 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.
+#.
+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"
+
+# msgstr "E17: "
+msgid "E18: Unexpected characters in :let"
+msgstr "E18: Ðеочікувані Ñимволи у :let"
+
+#, c-format
+msgid "E684: list index out of range: %ld"
+msgstr "E684: Ð†Ð½Ð´ÐµÐºÑ ÑпиÑку поза межами: %ld"
+
+#, c-format
+msgid "E121: Undefined variable: %s"
+msgstr "E121: Ðевизначена змінна: %s"
+
+msgid "E111: Missing ']'"
+msgstr "E111: Бракує ']'"
+
+#, c-format
+msgid "E686: Argument of %s must be a List"
+msgstr "E686: Ðргумент у %s має бути ÑпиÑком"
+
+#, c-format
+msgid "E712: Argument of %s must be a List or Dictionary"
+msgstr "E712: Ðргумент у %s має бути ÑпиÑком чи Ñловником"
+
+msgid "E713: Cannot use empty key for Dictionary"
+msgstr "E713: Ключ Ñловника не може бути порожнім"
+
+# msgstr "E396: "
+msgid "E714: List required"
+msgstr "E714: Потрібен ÑпиÑок"
+
+msgid "E715: Dictionary required"
+msgstr "E715: Потрібен Ñловник"
+
+#, 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"
+
+#, 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: Треба поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð½Ð° функцію"
+
+msgid "E719: Cannot use [:] with a Dictionary"
+msgstr "E719: Ðе можна викориÑтати [:] зі Ñловником"
+
+#, c-format
+msgid "E734: Wrong variable type for %s="
+msgstr "E734: Ðеправильний тип змінної Ð´Ð»Ñ %s="
+
+#, c-format
+msgid "E130: Unknown function: %s"
+msgstr "E130: Ðевідома функціÑ: %s"
+
+#, c-format
+msgid "E461: Illegal variable name: %s"
+msgstr "E461: ÐеприпуÑтима назва змінної: %s"
+
+# msgstr "E373: "
+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 "Друга ; у ÑпиÑку змінних"
+
+# msgstr "E235: "
+#, 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: [:] вимагає ÑпиÑок"
+
+msgid "E710: List value has more items than target"
+msgstr "E710: СпиÑок має більше елементів, ніж ціль"
+
+msgid "E711: List value has not enough items"
+msgstr "E711: СпиÑок має недоÑтатньо елементів"
+
+msgid "E690: Missing \"in\" after :for"
+msgstr "E690: Пропущено «in» піÑÐ»Ñ :for"
+
+#, c-format
+msgid "E107: Missing parentheses: %s"
+msgstr "E107: Пропущено дужки: %s"
+
+#, c-format
+msgid "E108: No such variable: \"%s\""
+msgstr "E108: Змінної немає: «%s»"
+
+msgid "E743: variable nested too deep for (un)lock"
+msgstr "E743: Змінна має забагато вкладень щоб бути за-/відкритою."
+
+msgid "E109: Missing ':' after '?'"
+msgstr "E109: Бракує ':' піÑÐ»Ñ '?'"
+
+msgid "E691: Can only compare List with List"
+msgstr "E691: СпиÑок можна порівнÑти тільки зі ÑпиÑком"
+
+msgid "E692: Invalid operation for Lists"
+msgstr "E692: Ðекоректна Ð¾Ð¿ÐµÑ€Ð°Ñ†Ñ–Ñ Ð½Ð°Ð´ ÑпиÑком"
+
+msgid "E735: Can only compare Dictionary with Dictionary"
+msgstr "E735: Словник можна порівнÑти тільки із Ñловником"
+
+msgid "E736: Invalid operation for Dictionary"
+msgstr "E736: Ðекоректна Ð¾Ð¿ÐµÑ€Ð°Ñ†Ñ–Ñ Ð½Ð°Ð´ Ñловником"
+
+msgid "E693: Can only compare Funcref with Funcref"
+msgstr "E693: Функцію можна порівнÑти тільки з функцією"
+
+msgid "E694: Invalid operation for Funcrefs"
+msgstr "E694: Ðекоректна Ð¾Ð¿ÐµÑ€Ð°Ñ†Ñ–Ñ Ð½Ð°Ð´ функцією"
+
+msgid "E804: Cannot use '%' with Float"
+msgstr "E804: Ðе можна виконати '%' над Float"
+
+msgid "E110: Missing ')'"
+msgstr "E110: Пропущено ')'"
+
+msgid "E695: Cannot index a Funcref"
+msgstr "E695: Ð¤ÑƒÐ½ÐºÑ†Ñ–Ñ Ð½Ðµ має індекÑації"
+
+#, 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"
+
+# msgstr "E404: "
+#, c-format
+msgid "E696: Missing comma in List: %s"
+msgstr "E696: Бракує коми у ÑпиÑку: %s"
+
+#, c-format
+msgid "E697: Missing end of List ']': %s"
+msgstr "E697: Ðемає кінцівки ÑпиÑку ']': %s"
+
+# msgstr "E235: "
+#, c-format
+msgid "E720: Missing colon in Dictionary: %s"
+msgstr "E720: Бракує двокрапки у Ñловнику: %s"
+
+#, c-format
+msgid "E721: Duplicate key in Dictionary: \"%s\""
+msgstr "E721: ÐŸÐ¾Ð²Ñ‚Ð¾Ñ€ÐµÐ½Ð½Ñ ÐºÐ»ÑŽÑ‡Ð° в Ñловнику: «%s»"
+
+# msgstr "E235: "
+#, c-format
+msgid "E722: Missing comma in Dictionary: %s"
+msgstr "E722: Бракує коми у Ñловнику: %s"
+
+#, c-format
+msgid "E723: Missing end of Dictionary '}': %s"
+msgstr "E723: Ðемає кінцівки Ñловника '}': %s"
+
+# msgstr "E21: "
+msgid "E724: variable nested too deep for displaying"
+msgstr "E724: У змінній забагато вкладень щоб її показати"
+
+#, 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"
+
+#, c-format
+msgid "E117: Unknown function: %s"
+msgstr "E117: Ðевідома функціÑ: %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 "E808: Number or Float required"
+msgstr "E808: Треба вказати Number чи Float"
+
+# msgstr "E14: "
+msgid "add() argument"
+msgstr "аргумент add()"
+
+msgid "E699: Too many arguments"
+msgstr "E699: Забагато аргументів"
+
+# msgstr "E327: "
+msgid "E785: complete() can only be used in Insert mode"
+msgstr "E785: complete() можна вживати тільки в режимі вÑтавки"
+
+#.
+#. * 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 "&O:Гаразд"
+
+# msgstr "E226: "
+#, c-format
+msgid "E737: Key already exists: %s"
+msgstr "E737: Ключ вже Ñ–Ñнує: %s"
+
+# msgstr "E14: "
+msgid "extend() argument"
+msgstr "аргумент extend()"
+
+# msgstr "E14: "
+msgid "map() argument"
+msgstr "аргумент map()"
+
+# msgstr "E14: "
+msgid "filter() argument"
+msgstr "аргумент filter()"
+
+#, c-format
+msgid "+-%s%3ld lines: "
+msgstr "+-%s%3ld Ñ€Ñдків: "
+
+#, c-format
+msgid "E700: Unknown function: %s"
+msgstr "E700: Ðевідома функціÑ: %s"
+
+msgid ""
+"&OK\n"
+"&Cancel"
+msgstr ""
+"&O:Гаразд\n"
+"&C:СкаÑувати"
+
+msgid "called inputrestore() more often than inputsave()"
+msgstr "Виклики до inputrestore() чаÑтіше, ніж до inputsave()"
+
+# msgstr "E14: "
+msgid "insert() argument"
+msgstr "аргумент insert()"
+
+# msgstr "E406: "
+msgid "E786: Range not allowed"
+msgstr "E786: Інтервал не дозволено"
+
+# msgstr "E177: "
+msgid "E701: Invalid type for len()"
+msgstr "E701: Ðекоректний тип Ð´Ð»Ñ len()"
+
+msgid "E726: Stride is zero"
+msgstr "E726: Крок нульовий"
+
+msgid "E727: Start past end"
+msgstr "E727: Початок за кінцем"
+
+msgid "<empty>"
+msgstr "<нічого>"
+
+msgid "E240: No connection to Vim server"
+msgstr "E240: Ðемає з'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ñ–Ð· Ñервером Vim"
+
+#, c-format
+msgid "E241: Unable to send to %s"
+msgstr "E241: Ðе вдалоÑÑ Ð²Ñ–Ð´Ñ–Ñлати до %s"
+
+msgid "E277: Unable to read a server reply"
+msgstr "E277: Ðе вдалоÑÑ Ð¿Ñ€Ð¾Ñ‡Ð¸Ñ‚Ð°Ñ‚Ð¸ відповідь Ñервера"
+
+# msgstr "E14: "
+msgid "remove() argument"
+msgstr "аргумент remove()"
+
+msgid "E655: Too many symbolic links (cycle?)"
+msgstr "E655: Забагато Ñимвольних поÑилань (цикл?)"
+
+# msgstr "E14: "
+msgid "reverse() argument"
+msgstr "аргумент reverse()"
+
+msgid "E258: Unable to send to client"
+msgstr "E258: Ðе вдалоÑÑ Ð½Ð°Ð´Ñ–Ñлати клієнту"
+
+# msgstr "E14: "
+msgid "sort() argument"
+msgstr "аргумент sort()"
+
+# msgstr "E364: "
+msgid "E702: Sort compare function failed"
+msgstr "E702: Помилка у функції порівнÑннÑ"
+
+msgid "(Invalid)"
+msgstr "(Ðеможливо)"
+
+msgid "E677: Error writing temp file"
+msgstr "E677: Ðе вдалоÑÑ Ð·Ð°Ð¿Ð¸Ñати тимчаÑовий файл"
+
+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 "E729: using Funcref as a String"
+msgstr "E729: Funcref вжито Ñк String"
+
+# msgstr "E373: "
+msgid "E730: using List as a String"
+msgstr "E730: List вжито Ñк String"
+
+msgid "E731: using Dictionary as a String"
+msgstr "E731: Dictionary вжито Ñк String"
+
+#, c-format
+msgid "E706: Variable type mismatch for: %s"
+msgstr "E706: Ðеправильний тип змінної: %s"
+
+#, 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: Змінна вкладена занадто глибоко щоб зробити її копію"
+
+#, 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 "E125: Illegal argument: %s"
+msgstr "E125: Ðедозволений аргумент: %s"
+
+#, c-format
+msgid "E853: Duplicate argument name: %s"
+msgstr "E853: Ðазва аргументу повторюєтьÑÑ: %s"
+
+msgid "E126: Missing :endfunction"
+msgstr "E126: Бракує :endfunction"
+
+#, 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"
+
+msgid "E129: Function name required"
+msgstr "E129: Ðе вказано назву функції"
+
+#, c-format
+msgid "E128: Function name must start with a capital or contain a colon: %s"
+msgstr ""
+"E128: Ðазва функції має починатиÑÑ Ð· великої літери або міÑтити двокрапку: %s"
+
+#, c-format
+msgid "E131: Cannot delete function %s: It is in use"
+msgstr "E131: Ðе вдалоÑÑ Ð·Ð½Ð¸Ñ‰Ð¸Ñ‚Ð¸ функцію %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"
+
+#, c-format
+msgid "continuing in %s"
+msgstr "Ð¿Ñ€Ð¾Ð´Ð¾Ð²Ð¶ÐµÐ½Ð½Ñ Ð² %s"
+
+msgid "E133: :return not inside a function"
+msgstr "E133: :return поза межами функції"
+
+msgid ""
+"\n"
+"# global variables:\n"
+msgstr ""
+"\n"
+"# глобальні змінні:\n"
+
+msgid ""
+"\n"
+"\tLast set from "
+msgstr ""
+"\n"
+"\tВоÑтаннє змінена у "
+
+msgid "No old files"
+msgstr "Жодного Ñтарого файлу"
+
+msgid "Entering Debug mode. Type \"cont\" to continue."
+msgstr "Режим налагодженнÑ. Щоб продовжити введіть «cont»."
+
+#, c-format
+msgid "line %ld: %s"
+msgstr "Ñ€Ñдок %ld: %s"
+
+#, c-format
+msgid "cmd: %s"
+msgstr "команда: %s"
+
+#, 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"
+
+msgid "E750: First use \":profile start {fname}\""
+msgstr "E750: Спочатку зробіть «:profile start {файл}»"
+
+msgid "Save As"
+msgstr "Зберегти Ñк"
+
+#, c-format
+msgid "Save changes to \"%s\"?"
+msgstr "Зберегти зміни в «%s»?"
+
+msgid "Untitled"
+msgstr "Ðеназваний"
+
+#, 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"
+
+# msgstr "E195: "
+#, 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 'runtimepath': \"%s\""
+msgstr "В 'runtimepath' не знайдено «%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"
+
+msgid "modeline"
+msgstr "modeline"
+
+# msgstr "E14: "
+msgid "--cmd argument"
+msgstr "--cmd аргумент"
+
+# msgstr "E14: "
+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»"
+
+#, c-format
+msgid "<%s>%s%s %d, Hex %02x, Octal %03o"
+msgstr "<%s>%s%s %d, шіÑÑ‚ %02x, Ð²Ñ–Ñ %03o"
+
+#, 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 "Переміщено один Ñ€Ñдок"
+
+#, 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: Ðвтокоманди *Filter* не повинні змінювати поточний буфер"
+
+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 " ÐЕ ВДÐЛОСЯ"
+
+#. avoid a wait_return for this message, it's annoying
+#, c-format
+msgid "E137: Viminfo file is not writable: %s"
+msgstr "E137: Ðе дозволено Ð·Ð°Ð¿Ð¸Ñ Ñƒ файл viminfo: %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»"
+
+#. Write the info:
+#, c-format
+msgid "# This viminfo file was generated by Vim %s.\n"
+msgstr "# Цей файл автоматично Ñтворений 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 "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 "Файл обміну «%s» Ñ–Ñнує, перезапиÑати?"
+
+#, c-format
+msgid "E768: Swap file exists: %s (:silent! overrides)"
+msgstr "E768: Файл обміну Ñ–Ñнує: %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 ""
+"Ð”Ð»Ñ Â«%s» вÑтановлено 'readonly'.\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: У 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 "(Перервано) "
+
+# msgstr "E31: "
+msgid "1 match"
+msgstr "Один збіг"
+
+msgid "1 substitution"
+msgstr "Одна заміна"
+
+#, c-format
+msgid "%ld matches"
+msgstr "%ld збіги(ів)"
+
+#, c-format
+msgid "%ld substitutions"
+msgstr "%ld замін(и)"
+
+msgid " on 1 line"
+msgstr " в одному Ñ€Ñдку"
+
+#, c-format
+msgid " on %ld lines"
+msgstr " в %ld Ñ€Ñдках"
+
+msgid "E147: Cannot do :global recursive"
+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 "E150: Not a directory: %s"
+msgstr "E150: Ðе Ñ” каталогом: %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 "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"
+
+#, c-format
+msgid "E157: Invalid sign ID: %ld"
+msgstr "E157: Ðеправильний ID надпиÑу: %ld"
+
+msgid " (NOT FOUND)"
+msgstr " (ÐЕ ЗÐÐЙДЕÐО)"
+
+msgid " (not supported)"
+msgstr " (не підтримуєтьÑÑ)"
+
+msgid "[Deleted]"
+msgstr "[Знищено]"
+
+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 "E319: Sorry, the command is not available in this version"
+msgstr "E319: Вибачте, цієї команди немає у цій верÑÑ–Ñ—"
+
+msgid "E172: Only one file name allowed"
+msgstr "E172: Дозволено тільки одну назву файлу"
+
+msgid "1 more file to edit. Quit anyway?"
+msgstr "ЗалишилоÑÑ Ð²Ñ–Ð´Ñ€ÐµÐ´Ð°Ð³ÑƒÐ²Ð°Ñ‚Ð¸ ще один файл. Ð’Ñе одно вийти?"
+
+#, c-format
+msgid "%d more files to edit. Quit anyway?"
+msgstr "Ще Ñ” %d не редагованих файлів. Ð’Ñе одно вийти?"
+
+msgid "E173: 1 more file to edit"
+msgstr "E173: ЗалишилоÑÑ Ð²Ñ–Ð´Ñ€ÐµÐ´Ð°Ð³ÑƒÐ²Ð°Ñ‚Ð¸ ще один файл"
+
+#, 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 Range 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: Лічильник не може бути вказано двічі"
+
+# msgstr "E177: "
+msgid "E178: Invalid default value for count"
+msgstr "E178: Ðеправильне початкове Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð»Ñ–Ñ‡Ð¸Ð»ÑŒÐ½Ð¸ÐºÐ°"
+
+# msgstr "E178: "
+msgid "E179: argument required for -complete"
+msgstr "E179: Ð´Ð»Ñ -complete потрібний аргумент"
+
+# msgstr "E180: "
+#, c-format
+msgid "E181: Invalid attribute: %s"
+msgstr "E181: Ðеправильний атрибут: %s"
+
+# msgstr "E181: "
+msgid "E182: Invalid command name"
+msgstr "E182: Ðеправильна назва команди"
+
+# 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: Зарезервована назва, не можна викориÑтати Ð´Ð»Ñ ÐºÐ¾Ñ€Ð¸Ñтувацької команди"
+
+# msgstr "E183: "
+#, c-format
+msgid "E184: No such user-defined command: %s"
+msgstr "E184: Команду кориÑтувача не знайдено: %s"
+
+# msgstr "E179: "
+#, 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 "Ðевідомо"
+
+# msgstr "E184: "
+#, c-format
+msgid "E185: Cannot find color scheme '%s'"
+msgstr "E185: Ðе вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ Ñхему кольорів «%s»"
+
+msgid "Greetings, Vim user!"
+msgstr "ВітаннÑ, кориÑтувачу Vim!"
+
+# msgstr "E443: "
+msgid "E784: Cannot close last tab page"
+msgstr "E784: Ðе можна закрити оÑтанню вкладку"
+
+# msgstr "E444: "
+msgid "Already only one tab page"
+msgstr "Вже й так лише одна вкладка"
+
+# msgstr "E185: "
+msgid "Edit File in new window"
+msgstr "Редагувати файл у новому вікні"
+
+#, c-format
+msgid "Tab page %d"
+msgstr "Вкладка %d"
+
+msgid "No swap file"
+msgstr "Ðемає файлу обміну"
+
+msgid "Append File"
+msgstr "ДопиÑати файл"
+
+msgid "E747: Cannot change directory, buffer is modified (add ! to override)"
+msgstr "E747: Ðе вдалоÑÑ Ð·Ð¼Ñ–Ð½Ð¸Ñ‚Ð¸ каталог, буфер має зміни (! щоб не зважати)"
+
+msgid "E186: No previous directory"
+msgstr "E186: Це вже найперший каталог"
+
+# msgstr "E186: "
+msgid "E187: Unknown"
+msgstr "E187: Ðевідомо"
+
+msgid "E465: :winsize requires two number arguments"
+msgstr "E465: :winsize вимагає два чиÑлових аргументи"
+
+# msgstr "E187: "
+#, 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 вимагає два чиÑлових аргументи"
+
+# msgstr "E188: "
+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» Ñ–Ñнує (! щоб не зважати)"
+
+# msgstr "E189: "
+#, c-format
+msgid "E190: Cannot open \"%s\" for writing"
+msgstr "E190: Ðе вдалоÑÑ Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ð¸ «%s» Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñу"
+
+# msgstr "E190: "
+#. set mark
+msgid "E191: Argument must be a letter or forward/backward quote"
+msgstr "E191: Ðргумент має бути літерою, ` або '"
+
+# 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"
+
+# msgstr "E193: "
+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: немає номера Ñ€Ñдка, щоб викориÑтати з «<sfile>»"
+
+#, no-c-format
+msgid "E499: Empty file name for '%' or '#', only works with \":p:h\""
+msgstr "E499: Ðазва файлу Ð´Ð»Ñ '%' чи '#' порожнÑ, працює лише з «:p:h»"
+
+msgid "E500: Evaluates to an empty string"
+msgstr "E500: Результат — порожній Ñ€Ñдок"
+
+msgid "E195: Cannot open viminfo file for reading"
+msgstr "E195: Ðе вдалоÑÑ Ð¿Ñ€Ð¾Ñ‡Ð¸Ñ‚Ð°Ñ‚Ð¸ файл viminfo"
+
+msgid "E196: No digraphs in this version"
+msgstr "E196: У цій верÑÑ–Ñ— немає диграфів"
+
+msgid "E608: Cannot :throw exceptions with 'Vim' prefix"
+msgstr "E608: Ðе можна викидати (:throw) винÑтки з префікÑом 'Vim'"
+
+#. always scroll up, don't overwrite
+#, 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"
+
+#. always scroll up, don't overwrite
+#, 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 "Помилка, перервано"
+
+# msgstr "E231: "
+msgid "Error"
+msgstr "Помилка"
+
+#. if (pending & CSTP_INTERRUPT)
+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"
+
+#. Give up for a ":catch" after ":finally" and ignore it.
+#. * Just parse.
+msgid "E604: :catch after :finally"
+msgstr "E604: :catch піÑÐ»Ñ :finally"
+
+msgid "E606: :finally without :try"
+msgstr "E606: :finally без :try"
+
+#. Give up for a multiple ":finally" and ignore it.
+msgid "E607: multiple :finally"
+msgstr "E607: Ðе одне :finally"
+
+msgid "E602: :endtry without :try"
+msgstr "E602: :entry без :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: Зараз не можна змінювати інформацію буфера"
+
+# msgstr "E197: "
+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 "E198: cmd_pchar beyond the command length"
+msgstr "E198: cmd_pchar поза межами команди"
+
+msgid "E199: Active window or buffer deleted"
+msgstr "E199: Ðктивне вікно або буфер було знищено"
+
+msgid "E812: Autocommands changed buffer or buffer name"
+msgstr "E812: Ðвтокоманди змінили буфер чи його назву"
+
+# msgstr "E199: "
+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 унеможливили Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ Ñ„Ð°Ð¹Ð»Ñƒ"
+
+# msgstr "E200: "
+msgid "E201: *ReadPre autocommands must not change current buffer"
+msgstr "E201: Ðвтокоманди *ReadPre не повинні змінювати цей буфер"
+
+# msgstr "E201: "
+msgid "Vim: Reading from stdin...\n"
+msgstr "Vim: ЧитаєтьÑÑ Ð· stdin...\n"
+
+msgid "Reading from stdin..."
+msgstr "ЧитаєтьÑÑ Ð· stdin..."
+
+#. Re-opening the original file failed!
+msgid "E202: Conversion made file unreadable!"
+msgstr "E202: ÐšÐ¾Ð½Ð²ÐµÑ€Ñ‚Ð°Ñ†Ñ–Ñ ÑƒÐ½ÐµÐ¼Ð¾Ð¶Ð»Ð¸Ð²Ð¸Ð»Ð° Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ Ñ„Ð°Ð¹Ð»Ñƒ!"
+
+# msgstr "E202: "
+msgid "[fifo/socket]"
+msgstr "[канал/Ñокет]"
+
+msgid "[fifo]"
+msgstr "[канал]"
+
+msgid "[socket]"
+msgstr "[Ñокет]"
+
+msgid "[character special]"
+msgstr "[Ñпец. Ñимвольний]"
+
+msgid "[CR missing]"
+msgstr "[Бракує CR]"
+
+msgid "[long lines split]"
+msgstr "[Розбито довгі Ñ€Ñдки]"
+
+msgid "[NOT converted]"
+msgstr "[ÐЕ конвертовано]"
+
+msgid "[converted]"
+msgstr "[конвертовано]"
+
+msgid "[blowfish]"
+msgstr "[blowfish]"
+
+msgid "[crypted]"
+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 "E821: File is encrypted with unknown method"
+msgstr "E821: Файл зашифровано невідомим методом"
+
+# msgstr "E217: "
+msgid "E676: No matching autocommands for acwrite buffer"
+msgstr "E676: Ðемає відповідних автокоманд"
+
+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 не дозволÑÑ” запиÑувати у незмінені буфери"
+
+# msgstr "E391: "
+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 "E460: The resource fork would be lost (add ! to override)"
+msgstr "E460: Гілку реÑурÑів можна втратити (! щоб не зважати)"
+
+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 "E667: Fsync failed"
+msgstr "E667: Ðе вдалоÑÑ Ð²Ð¸ÐºÐ¾Ð½Ð°Ñ‚Ð¸ fsync"
+
+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: ЛатаннÑ: не вдалоÑÑ Ð·Ð±ÐµÑ€ÐµÐ³Ñ‚Ð¸ оригінал"
+
+msgid "E206: patchmode: can't touch empty original file"
+msgstr "E206: ЛатаннÑ: не вдалоÑÑ Ñтворити оригінал"
+
+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 "один Ñ€Ñдок, "
+
+#, c-format
+msgid "%ld lines, "
+msgstr "%ld Ñ€Ñдків, "
+
+msgid "1 character"
+msgstr "один Ñимвол"
+
+#, c-format
+msgid "%lld characters"
+msgstr "%lld Ñимволів"
+
+#. Explicit typecast avoids warning on Mac OS X 10.6
+#, c-format
+msgid "%ld characters"
+msgstr "%ld Ñимволів"
+
+msgid "[noeol]"
+msgstr "[noeol]"
+
+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
+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 ""
+"&O:Гаразд\n"
+"&L:Завантажити"
+
+#, 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>"
+
+#. the group doesn't exist
+#, c-format
+msgid "E367: No such group: \"%s\""
+msgstr "E367: Ðемає такої групи: «%s»"
+
+#, c-format
+msgid "E215: Illegal character after *: %s"
+msgstr "E215: Ðедозволений Ñимвол піÑÐ»Ñ *: %s"
+
+# msgstr "E215: "
+#, c-format
+msgid "E216: No such event: %s"
+msgstr "E216: Ðемає такої події: %s"
+
+# msgstr "E215: "
+#, c-format
+msgid "E216: No such group or event: %s"
+msgstr "E216: Ðемає такої групи чи події: %s"
+
+# msgstr "E216: "
+#. Highlight title
+msgid ""
+"\n"
+"--- Auto-Commands ---"
+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: Ðе можу виконувати автокоманди Ð´Ð»Ñ Ð£Ð¡Ð†Ð¥ подій"
+
+# msgstr "E217: "
+msgid "No matching autocommands"
+msgstr "Ðемає відповідних автокоманд"
+
+msgid "E218: autocommand nesting too deep"
+msgstr "E218: Забагато вкладених автокоманд"
+
+# msgstr "E218: "
+#, c-format
+msgid "%s Auto commands for \"%s\""
+msgstr "Ðвтокоманди %s Ð´Ð»Ñ Â«%s»"
+
+#, c-format
+msgid "Executing %s"
+msgstr "ВиконуєтьÑÑ %s"
+
+#, c-format
+msgid "autocommand %s"
+msgstr "автокоманда %s"
+
+msgid "E219: Missing {."
+msgstr "E219: Бракує {."
+
+# msgstr "E219: "
+msgid "E220: Missing }."
+msgstr "E220: Бракує }."
+
+# msgstr "E220: "
+msgid "E490: No fold found"
+msgstr "E490: Згорток не знайдено"
+
+# msgstr "E349: "
+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 lines folded "
+msgstr "+-- згорнуто %3ld Ñ€Ñдків "
+
+msgid "E222: Add to read buffer"
+msgstr "E222: Додати до буфера читаннÑ"
+
+msgid "E223: recursive mapping"
+msgstr "E223: Заміна рекурÑивна"
+
+# msgstr "E223: "
+#, c-format
+msgid "E224: global abbreviation already exists for %s"
+msgstr "E224: Загальне ÑÐºÐ¾Ñ€Ð¾Ñ‡ÐµÐ½Ð½Ñ Ð´Ð»Ñ %s вже Ñ–Ñнує"
+
+# msgstr "E224: "
+#, c-format
+msgid "E225: global mapping already exists for %s"
+msgstr "E225: Загальна заміна Ð´Ð»Ñ %s вже Ñ–Ñнує"
+
+# msgstr "E225: "
+#, c-format
+msgid "E226: abbreviation already exists for %s"
+msgstr "E226: Вже Ñ” ÑÐºÐ¾Ñ€Ð¾Ñ‡ÐµÐ½Ð½Ñ Ð´Ð»Ñ %s"
+
+# msgstr "E226: "
+#, c-format
+msgid "E227: mapping already exists for %s"
+msgstr "E227: Вже Ñ” заміна Ð´Ð»Ñ %s"
+
+# msgstr "E227: "
+msgid "No abbreviation found"
+msgstr "Ð¡ÐºÐ¾Ñ€Ð¾Ñ‡ÐµÐ½Ð½Ñ Ð½Ðµ знайдено"
+
+msgid "No mapping found"
+msgstr "Заміни не знайдено"
+
+msgid "E228: makemap: Illegal mode"
+msgstr "E228: makemap: ÐеприпуÑтимий режим"
+
+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 "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: "
+#, c-format
+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' некоректне"
+
+#, c-format
+msgid "E254: Cannot allocate color %s"
+msgstr "E254: Ðе вдалоÑÑ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ñ‚Ð¸ колір %s"
+
+msgid "No match at cursor, finding next"
+msgstr "Ðемає над курÑором, пошук триває"
+
+msgid ""
+"&Yes\n"
+"&No\n"
+"&Cancel"
+msgstr ""
+"&Y:Так\n"
+"&N:ÐÑ–\n"
+"&C:СкаÑувати"
+
+msgid "Input _Methods"
+msgstr "Методи введеннÑ"
+
+msgid "VIM - Search and Replace..."
+msgstr "VIM - Знайти й замінити..."
+
+msgid "VIM - Search..."
+msgstr "VIM - Пошук..."
+
+msgid "Find what:"
+msgstr "Знайти:"
+
+msgid "Replace with:"
+msgstr "Замінити на:"
+
+#. whole word only button
+msgid "Match whole word only"
+msgstr "Лише повне Ñлово"
+
+#. match case button
+msgid "Match case"
+msgstr "Зважати на регіÑтр"
+
+msgid "Direction"
+msgstr "ÐапрÑм"
+
+#. 'Up' and 'Down' buttons
+msgid "Up"
+msgstr "Вгору"
+
+msgid "Down"
+msgstr "Униз"
+
+#. 'Find Next' button
+msgid "Find Next"
+msgstr "ÐаÑтупне"
+
+#. 'Replace' button
+msgid "Replace"
+msgstr "Замінити"
+
+#. 'Replace All' button
+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:СкаÑувати"
+
+#, 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 "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 "Знайти і замінити ('\\\\' щоб знайти '\\')"
+
+#. 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 "Ðемає"
+
+msgid "Directory\t*.nothing\n"
+msgstr "Каталог\t*.нічого\n"
+
+msgid "Vim E458: Cannot allocate colormap entry, some colors may be incorrect"
+msgstr ""
+"Vim E458: Ðемає вільних комірок у палітрі, деÑкі кольори можуть бути "
+"неправильні"
+
+#, c-format
+msgid "E250: Fonts for the following charsets are missing in fontset %s:"
+msgstr "E250: Шрифти Ð´Ð»Ñ Ñ†Ð¸Ñ… Ñимволів відÑутні у наборі %s:"
+
+# msgstr "E250: "
+#, c-format
+msgid "E252: Fontset name: %s"
+msgstr "E252: Ðазва набору шрифтів: %s"
+
+# msgstr "E252: "
+#, 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 "&D:Припинити"
+
+msgid "no specific match"
+msgstr "немає конкретного збігу"
+
+# msgstr "E234: "
+msgid "Vim - Font Selector"
+msgstr "Vim - Вибір шрифту"
+
+msgid "Name:"
+msgstr "Ðазва:"
+
+#. create toggle button
+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: Пропущено двокрапку"
+
+# msgstr "E347: "
+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 «%s»"
+
+#, c-format
+msgid "E618: file \"%s\" is not a PostScript resource file"
+msgstr "E618: «%s» не Ñ” файлом реÑурÑів PostScript"
+
+#, c-format
+msgid "E619: file \"%s\" is not a supported PostScript resource file"
+msgstr "E619: «%s» не Ñ” підтримуваним файлом реÑурÑів PostScript"
+
+#, c-format
+msgid "E621: \"%s\" resource file has wrong version"
+msgstr "E621: Ðеправильна верÑÑ–Ñ Ñ„Ð°Ð¹Ð»Ñƒ реÑурÑів «%s»"
+
+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 «prolog.ps»"
+
+msgid "E456: Can't find PostScript resource file \"cidfont.ps\""
+msgstr "E456: Ðе вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ файл реÑурÑів PostScript «cidfont.ps»"
+
+#, c-format
+msgid "E456: Can't find PostScript resource file \"%s.ps\""
+msgstr "E456: Ðе вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ файл реÑурÑів PostScript «%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 "Ð—Ð°Ð²Ð´Ð°Ð½Ð½Ñ Ð´Ñ€ÑƒÐºÑƒ відіÑлано."
+
+# msgstr "E255: "
+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 <ідентиф-ор>"
+
+msgid "E257: cstag: tag not found"
+msgstr "E257: cstag: теґ не знайдено"
+
+# msgstr "E257: "
+#, 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: помилка під Ñ‡Ð°Ñ Ð²Ð¸ÐºÐ¾Ð½Ð°Ð½Ð½Ñ"
+
+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"
+
+# msgstr "E258: "
+#, c-format
+msgid "E259: no matches found for cscope query %s of %s"
+msgstr "E259: Ð”Ð»Ñ Ð·Ð°Ð¿Ð¸Ñ‚Ñƒ cscope %s з %s нічого не знайдено"
+
+# msgstr "E259: "
+msgid "cscope commands:\n"
+msgstr "Команди cscope:\n"
+
+#, c-format
+msgid "%-5s: %s%*s (Usage: %s)"
+msgstr "%-5s: %s%*s (ВикориÑтаннÑ: %s)"
+
+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"
+
+#, 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 не додана"
+
+# msgstr "E260: "
+#, c-format
+msgid "E261: cscope connection %s not found"
+msgstr "E261: З'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð· cscope %s не знайдено"
+
+#, c-format
+msgid "cscope connection %s closed"
+msgstr "З'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð· cscope %s закінчено"
+
+#. should not reach here
+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 "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: "
+#, c-format
+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 "під'єднаний"
+
+#, c-format
+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 "помітку не вказано"
+
+#, 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 "Ðе вдалоÑÑ Ð·Ð°Ñ€ÐµÑ”Ñтрувати подію: буфер/вікно уже знищуєтьÑÑ"
+
+#. This should never happen. Famous last word?
+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 не може бути завантажена."
+
+#, 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: Реквізит реєÑтру зразку VIM Ñформований неправильно. Знищено!"
+
+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 "Забагато аргументів у «+команда», «-c команда» або «--cmd команда»"
+
+# msgstr "E14: "
+msgid "Invalid argument for"
+msgstr "Ðеправильний аргумент у"
+
+#, 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 "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 "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: Warning: Output is not to a terminal\n"
+msgstr "Vim: ЗаÑтереженнÑ: Вивід не у термінал\n"
+
+msgid "Vim: Warning: Input is not from a terminal\n"
+msgstr "Vim: ЗаÑтереженнÑ: Ð£Ð²ÐµÐ´ÐµÐ½Ð½Ñ Ð½Ðµ з терміналу\n"
+
+#. just in case..
+msgid "pre-vimrc command line"
+msgstr "команди перед vimrc"
+
+#, c-format
+msgid "E282: Cannot read from \"%s\""
+msgstr "E282: Ðе вдалоÑÑ Ð¿Ñ€Ð¾Ñ‡Ð¸Ñ‚Ð°Ñ‚Ð¸ з «%s»"
+
+# msgstr "E282: "
+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 помітка перейти до теґу"
+
+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\tРежим Vi (ніби «vi»)"
+
+msgid "-e\t\t\tEx mode (like \"ex\")"
+msgstr "-e\t\t\tРежим Ex (ніби «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Мовчазний (пакетний) режим (лише Ð´Ð»Ñ Â«ex»)"
+
+msgid "-d\t\t\tDiff mode (like \"vimdiff\")"
+msgstr "-d\t\t\tРежим порівнÑÐ½Ð½Ñ (ніби «vimdiff»)"
+
+msgid "-y\t\t\tEasy mode (like \"evim\", modeless)"
+msgstr "-y\t\t\tПроÑтий режим (ніби «evim», без режимів)"
+
+msgid "-R\t\t\tReadonly mode (like \"view\")"
+msgstr "-R\t\t\tРежим переглÑду (ніби «view»)"
+
+msgid "-Z\t\t\tRestricted mode (like \"rvim\")"
+msgstr "-Z\t\t\tОбмежений режим (ніби «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\tРежим lisp"
+
+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][файл]\t\tБільше повідомлень [рівень N] [файл журн. повідомлень]"
+
+msgid "-D\t\t\tDebugging mode"
+msgstr "-D\t\t\tРежим налагодженнÑ"
+
+msgid "-n\t\t\tNo swap file, use memory only"
+msgstr "-n\t\t\tÐе викориÑтовувати файл обміну, тримати уÑе в пам'Ñті"
+
+msgid "-r\t\t\tList swap files and exit"
+msgstr "-r\t\t\tПоказати файли обміну і вийти"
+
+msgid "-r (with file name)\tRecover crashed session"
+msgstr "-r (назва файлу)\tВідновити аварійно закінчений ÑеанÑ"
+
+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Ðе викориÑтовувати newcli Ð´Ð»Ñ Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ñ‚Ñ Ð²Ñ–ÐºÐ½Ð°"
+
+msgid "-dev <device>\t\tUse <device> for I/O"
+msgstr "-dev <приÑтрій>\t\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 "-u <vimrc>\t\tUse <vimrc> instead of any .vimrc"
+msgstr "-u <vimrc>\t\tВикориÑтати поданий файл заміÑть .vimrc"
+
+msgid "-U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc"
+msgstr "-u <gvimrc>\t\tВикориÑтати поданий файл заміÑть .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\tЗчитати команди нормального режиму з файлу <Ñкрипт>"
+
+msgid "-w <scriptout>\tAppend all typed commands to file <scriptout>"
+msgstr "-w <Ñкрипт>\t\tДопиÑати уÑÑ– набрані команди до файлу <Ñкрипт>"
+
+msgid "-W <scriptout>\tWrite all typed commands to file <scriptout>"
+msgstr "-w <Ñкрипт>\t\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 <файли> ..., але зачекати поки уÑÑ– файли будуть відредаговані"
+
+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 "--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 "-h or --help\tPrint Help (this message) and exit"
+msgstr "-h чи --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ВикориÑтати <шрифт> Ð´Ð»Ñ Ð·Ð²Ð¸Ñ‡Ð°Ð¹Ð½Ð¾Ð³Ð¾ текÑту (також: -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 "Ðемає диÑплею"
+
+#. Failed to send, abort.
+msgid ": Send failed.\n"
+msgstr ": Ðе вдалоÑÑ Ð²Ñ–Ð´Ñ–Ñлати.\n"
+
+#. Let vim start normally.
+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» не знайдено"
+
+# msgstr "E283: "
+#. Highlight title
+msgid ""
+"\n"
+"mark line col file/text"
+msgstr ""
+"\n"
+"пом. Ñ€Ñд. кол. файл/текÑÑ‚"
+
+#. Highlight title
+msgid ""
+"\n"
+" jump line col file/text"
+msgstr ""
+"\n"
+" точка Ñ€Ñд. Ñтовп. файл/текÑÑ‚"
+
+# msgstr "E283: "
+#. Highlight title
+msgid ""
+"\n"
+"change line col text"
+msgstr ""
+"\n"
+"змінити Ñ€Ñд. Ñтовп. текÑÑ‚"
+
+# TODO
+msgid ""
+"\n"
+"# File marks:\n"
+msgstr ""
+"\n"
+"# Помітки:\n"
+
+#. Write the jumplist with -'
+msgid ""
+"\n"
+"# Jumplist (newest first):\n"
+msgstr ""
+"\n"
+"# СпиÑок переходів (від найновіших):\n"
+
+# TODO
+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: Ðе вдалоÑÑ Ð²Ñтановити Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ ÐºÐ¾Ð½Ñ‚ÐµÐºÑту вводу"
+
+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: Метод вводу не підтримує відредаговані типи"
+
+# msgstr "E292: "
+msgid "E293: block was not locked"
+msgstr "E293: Блок не було зафікÑовано"
+
+# msgstr "E293: "
+msgid "E294: Seek error in swap file read"
+msgstr "E294: Помилка зміни позиції у файлі обміну"
+
+msgid "E295: Read error in swap file"
+msgstr "E295: Помилка Ð·Ñ‡Ð¸Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ñ„Ð°Ð¹Ð»Ñƒ обміну"
+
+msgid "E296: Seek error in swap file write"
+msgstr "E296: Помилка зміни позиції під Ñ‡Ð°Ñ Ð·Ð°Ð¿Ð¸Ñу у файл обміну"
+
+msgid "E297: Write error in swap file"
+msgstr "E297: Помилка запиÑу файлу обміну"
+
+msgid "E300: Swap file already exists (symlink attack?)"
+msgstr "E300: Файл обміну вже Ñ–Ñнує (атака Ñимвольним поÑиланнÑм?)"
+
+msgid "E298: Didn't get block nr 0?"
+msgstr "E298: Ðемає блоку 0?"
+
+msgid "E298: Didn't get block nr 1?"
+msgstr "E298: Ðемає блоку 1?"
+
+# msgstr "E298: "
+msgid "E298: Didn't get block nr 2?"
+msgstr "E298: Ðемає блоку 2?"
+
+msgid "E843: Error while updating swap file crypt"
+msgstr "E843: Помилка Ð¿Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ ÑˆÐ¸Ñ„Ñ€ÑƒÐ²Ð°Ð½Ð½Ñ Ñ„Ð°Ð¹Ð»Ñƒ обміну"
+
+#. could not (re)open the swap file, what can we do????
+msgid "E301: Oops, lost the swap file!!!"
+msgstr "E301: Ой, втрачено файл обміну!!!"
+
+# msgstr "E301: "
+msgid "E302: Could not rename swap file"
+msgstr "E302: Ðе вдалоÑÑ Ð¿ÐµÑ€ÐµÐ¹Ð¼ÐµÐ½ÑƒÐ²Ð°Ñ‚Ð¸ файлу обміну"
+
+# msgstr "E302: "
+#, c-format
+msgid "E303: Unable to open swap file for \"%s\", recovery impossible"
+msgstr "E303: Ðе вдалоÑÑ Ð¿Ñ€Ð¾Ñ‡Ð¸Ñ‚Ð°Ñ‚Ð¸ файл обміну Ð´Ð»Ñ Â«%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"
+
+# msgstr "E305: "
+msgid "Enter number of swap file to use (0 to quit): "
+msgstr "Введіть номер файлу обміну, котрий викориÑтати, (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 не поновив файл обміну."
+
+msgid " cannot be used with this version of Vim.\n"
+msgstr " не можна викориÑтати з цією верÑією Vim.\n"
+
+msgid "Use Vim version 3.0.\n"
+msgstr "Знайдіть Vim 3.0\n"
+
+#, c-format
+msgid "E307: %s does not look like a Vim swap file"
+msgstr "E307: %s не Ñхоже на файл обміну Vim"
+
+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 "ВикориÑтовуєтьÑÑ Ñ„Ð°Ð¹Ð» обміну «%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 "Файл обміну зашифрований: «%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"
+"щоб викориÑтати однаковий ключ Ð´Ð»Ñ Ñ‚ÐµÐºÑтового файлу та файлу обміну"
+
+# msgstr "E308: "
+#, c-format
+msgid "E309: Unable to read block 1 from %s"
+msgstr "E309: Ðе вдалоÑÑ Ð¿Ñ€Ð¾Ñ‡Ð¸Ñ‚Ð°Ñ‚Ð¸ блок 1 з %s"
+
+# msgstr "E309: "
+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: Ідентифікатор блоку 1 неправильний (%s не є файлом обміну?)"
+
+# msgstr "E310: "
+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 "Ð’Ñ–Ð´Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð·Ð°ÐºÑ–Ð½Ñ‡ÐµÐ½Ð¾, перевірте чи вÑе гаразд."
+
+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 "Ð”Ð»Ñ Ñ‚ÐµÐºÑтового файлу викориÑтовуєтьÑÑ ÐºÐ»ÑŽÑ‡ шифру з файлу обміну.\n"
+
+#. use msg() to start the scrolling properly
+msgid "Swap files found:"
+msgstr "Знайдено файли обміну:"
+
+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 " [не Ñхоже на файл обміну]"
+
+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"
+" ID процеÑу: "
+
+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: Ðе вдалоÑÑ Ð·Ð°Ð³Ð¾Ñ‚Ð¾Ð²Ð¸Ñ‚Ð¸, немає файлу обміну"
+
+# msgstr "E313: "
+msgid "File preserved"
+msgstr "Файл збережено"
+
+msgid "E314: Preserve failed"
+msgstr "E314: Ð—Ð±ÐµÑ€ÐµÐ¶ÐµÐ½Ð½Ñ Ð½Ðµ вдалоÑÑ"
+
+# msgstr "E314: "
+#, c-format
+msgid "E315: ml_get: invalid lnum: %ld"
+msgstr "E315: ml_get: неправильний lnum: %ld"
+
+# msgstr "E315: "
+#, c-format
+msgid "E316: ml_get: cannot find line %ld"
+msgstr "E316: ml_get: не знайшов Ñ€Ñдок %ld"
+
+# msgstr "E316: "
+msgid "E317: pointer block id wrong 3"
+msgstr "E317: Вказівник блоку помилковий 3"
+
+# msgstr "E317: "
+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: Вказівник блоку помилковий"
+
+# msgstr "E317: "
+msgid "pe_line_count is zero"
+msgstr "pe_line_count дорівнює 0"
+
+#, c-format
+msgid "E322: line number out of range: %ld past the end"
+msgstr "E322: Ðомер Ñ€Ñдка вийшов за межі: %ld за кінцем"
+
+# msgstr "E322: "
+#, c-format
+msgid "E323: line count wrong in block %ld"
+msgstr "E323: КількіÑть Ñ€Ñдків у блоці %ld"
+
+# msgstr "E323: "
+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: Циклічні Ñимвольні поÑÐ¸Ð»Ð°Ð½Ð½Ñ Â«%s»"
+
+# msgstr "E317: "
+msgid "E325: ATTENTION"
+msgstr "E325: УВÐГÐ"
+
+msgid ""
+"\n"
+"Found a swap file by the name \""
+msgstr ""
+"\n"
+"Знайдено файл обміну з назвою \""
+
+msgid "While opening file \""
+msgstr "При відкритті файлу \""
+
+msgid " NEWER than swap file!\n"
+msgstr " ÐОВІШИЙ за файл обміну!\n"
+
+#. 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."
+msgstr ""
+"\n"
+"(1) Можливо, інша програма вже редагує цей Ñамий файл. Якщо це так,\n"
+" будьте обережні, щоб не залишилиÑÑ Ð´Ð²Ð° різні екземплÑри\n"
+" одного й того Ñамого файлу піÑÐ»Ñ Ð·Ð¼Ñ–Ð½."
+
+msgid " Quit, or continue with caution.\n"
+msgstr " Вийдіть або продовжуйте обережно.\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 " Якщо ви вже це зробили, знищіть файл обміну «"
+
+msgid ""
+"\"\n"
+" to avoid this message.\n"
+msgstr ""
+"»,\n"
+" щоб позбутиÑÑ Ñ†ÑŒÐ¾Ð³Ð¾ повідомленнÑ.\n"
+"\n"
+
+msgid "Swap file \""
+msgstr "Файл обміну «"
+
+msgid "\" already exists!"
+msgstr "» вже Ñ–Ñнує!"
+
+msgid "VIM - ATTENTION"
+msgstr "VIM — УВÐГÐ"
+
+msgid "Swap file already exists!"
+msgstr "Файл обміну вже Ñ–Ñнує!"
+
+msgid ""
+"&Open Read-Only\n"
+"&Edit anyway\n"
+"&Recover\n"
+"&Quit\n"
+"&Abort"
+msgstr ""
+"&O:Відкрити лише Ð´Ð»Ñ Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ\n"
+"&E:Ð’Ñе одно редагувати\n"
+"&R:Відновити\n"
+"&Q:Вийти\n"
+"&A:Перервати"
+
+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:Перервати"
+
+msgid "E326: Too many swap files found"
+msgstr "E326: Знайдено забагато файлів обміну"
+
+# msgstr "E326: "
+msgid "E327: Part of menu-item path is not sub-menu"
+msgstr "E327: ЧаÑтина шлÑху до елемента меню не Ñ” підменю"
+
+# msgstr "E327: "
+msgid "E328: Menu only exists in another mode"
+msgstr "E328: Меню може бути тільки в іншому режимі"
+
+# msgstr "E328: "
+#, c-format
+msgid "E329: No menu \"%s\""
+msgstr "E329: Ðемає меню «%s»"
+
+#. Only a mnemonic or accelerator is not valid.
+msgid "E792: Empty menu name"
+msgstr "E792: ÐŸÐ¾Ñ€Ð¾Ð¶Ð½Ñ Ð½Ð°Ð·Ð²Ð° меню"
+
+# msgstr "E329: "
+msgid "E330: Menu path must not lead to a sub-menu"
+msgstr "E330: ШлÑÑ… до меню не повинен веÑти до підменю"
+
+# msgstr "E330: "
+msgid "E331: Must not add menu items directly to menu bar"
+msgstr "E331: Ðе можна додавати елементи меню проÑто до верхнього меню"
+
+# msgstr "E331: "
+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
+msgid ""
+"\n"
+"--- Menus ---"
+msgstr ""
+"\n"
+"--- Меню ---"
+
+msgid "Tear off this menu"
+msgstr "Відірвати це меню"
+
+msgid "E333: Menu path must lead to a menu item"
+msgstr "E333: ШлÑÑ… повинен веÑти до елемента меню"
+
+# msgstr "E333: "
+#, c-format
+msgid "E334: Menu not found: %s"
+msgstr "E334: Меню не знайдено: %s"
+
+# msgstr "E334: "
+#, c-format
+msgid "E335: Menu not defined for %s mode"
+msgstr "E335: Ð”Ð»Ñ Ñ€ÐµÐ¶Ð¸Ð¼Ñƒ %s меню не визначено"
+
+# msgstr "E335: "
+msgid "E336: Menu path must lead to a sub-menu"
+msgstr "E336: ШлÑÑ… повинен веÑти до підменю"
+
+# msgstr "E336: "
+msgid "E337: Menu not found - check menu names"
+msgstr "E337: Меню не знайдено — перевірте назву"
+
+# 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 "УкраїнізаціÑ: Ðнатолій Сахнік <sakhnik@gmail.com>"
+
+msgid "Interrupt: "
+msgstr "Перервано: "
+
+msgid "Press ENTER or type command to continue"
+msgstr "ÐатиÑніть ENTER або введіть команду Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð´Ð¾Ð²Ð¶ÐµÐ½Ð½Ñ"
+
+#, 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 ""
+"&Y:Так\n"
+"&N:ÐÑ–"
+
+msgid ""
+"&Yes\n"
+"&No\n"
+"Save &All\n"
+"&Discard All\n"
+"&Cancel"
+msgstr ""
+"&Y:Так\n"
+"&N:ÐÑ–\n"
+"&A:УÑÑ–\n"
+"&D:Жодного\n"
+"&C:СкаÑувати"
+
+msgid "Select Directory dialog"
+msgstr "Вибрати каталог"
+
+msgid "Save File dialog"
+msgstr "Запам'Ñтати файл"
+
+msgid "Open File dialog"
+msgstr "Відкрити файл"
+
+#. TODO: non-GUI file selector here
+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()"
+
+# msgstr "E338: "
+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 "додано один Ñ€Ñдок"
+
+msgid "1 line less"
+msgstr "знищено один Ñ€Ñдок"
+
+#, 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: РÑдок Ñтає занадто довгим"
+
+# msgstr "E340: "
+#, c-format
+msgid "E341: Internal error: lalloc(%ld, )"
+msgstr "E341: Ð’Ð½ÑƒÑ‚Ñ€Ñ–ÑˆÐ½Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ°: lalloc(%ld, )"
+
+# msgstr "E341: "
+#, c-format
+msgid "E342: Out of memory! (allocating %lu bytes)"
+msgstr "E342: Забракло пам'Ñті! (потрібно було %lu байтів)"
+
+# msgstr "E342: "
+#, 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: Ðеправильний виглÑд миші"
+
+msgid "E548: digit expected"
+msgstr "E548: Потрібна цифра"
+
+msgid "E549: Illegal percentage"
+msgstr "E549: Ðеправильний відÑоток"
+
+msgid "Enter encryption key: "
+msgstr "Вкажіть ключ шифру: "
+
+msgid "Enter same key again: "
+msgstr "Повторіть ключ: "
+
+msgid "Keys don't match!"
+msgstr "Ключі не однакові!"
+
+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'."
+
+# msgstr "E343: "
+#, c-format
+msgid "E344: Can't find directory \"%s\" in cdpath"
+msgstr "E344: Ðе вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ каталог «%s» у cdpath"
+
+# msgstr "E344: "
+#, c-format
+msgid "E345: Can't find file \"%s\" in path"
+msgstr "E345: Ðе вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ файл «%s» у path"
+
+# msgstr "E345: "
+#, c-format
+msgid "E346: No more directory \"%s\" found in cdpath"
+msgstr "E346: У cdpath немає більше каталогу «%s»"
+
+# msgstr "E346: "
+#, c-format
+msgid "E347: No more file \"%s\" found in path"
+msgstr "E347: У шлÑху пошуку більше немає файлів «%s»"
+
+msgid "Cannot connect to Netbeans #2"
+msgstr "Ðе вдалоÑÑ Ð·'єднатиÑÑ Ñ–Ð· Netbeans #2"
+
+msgid "Cannot connect to Netbeans"
+msgstr "Ðе вдалоÑÑ Ð·'єднатиÑÑ Ñ–Ð· Netbeans"
+
+#, c-format
+msgid "E668: Wrong access mode for NetBeans connection info file: \"%s\""
+msgstr ""
+"E668: Ðеправильний режим доÑтупу до файлу інформації про з'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð· "
+"NetBenans: «%s»"
+
+msgid "read from Netbeans socket"
+msgstr "читаєтьÑÑ Ð· Ñокета Netbeans"
+
+#, 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 тільки Ð´Ð»Ñ Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ (! щоб не зважати)"
+
+# msgstr "E348: "
+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 :quit<Enter> to exit Vim"
+msgstr "Уведіть :quit<Enter> щоб вийти з Vim"
+
+#, c-format
+msgid "1 line %sed 1 time"
+msgstr "Один Ñ€Ñдок %s-но"
+
+#, c-format
+msgid "1 line %sed %d times"
+msgstr "Один Ñ€Ñдок %s-но %d разів"
+
+#, c-format
+msgid "%ld lines %sed 1 time"
+msgstr "%ld Ñ€Ñдків %s-но"
+
+#, 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 "ВирівнÑно один Ñ€Ñдок"
+
+#, c-format
+msgid "%ld lines indented "
+msgstr "ВирівнÑно Ñ€Ñдків: %ld"
+
+msgid "E748: No previously used register"
+msgstr "E748: РегіÑтри перед цим не вживалиÑÑŒ"
+
+#. must display the prompt
+msgid "cannot yank; delete anyway"
+msgstr "не вдалоÑÑ Ð·Ð°Ð¿Ð°Ð¼'Ñтати; вÑе одно знищити?"
+
+msgid "1 line changed"
+msgstr "Один Ñ€Ñдок змінено"
+
+#, c-format
+msgid "%ld lines changed"
+msgstr "Змінено Ñ€Ñдків: %ld"
+
+#, c-format
+msgid "freeing %ld lines"
+msgstr "Звільнено Ñ€Ñдків: %ld"
+
+msgid "block of 1 line yanked"
+msgstr "Запам'Ñтав блок з одного Ñ€Ñдка"
+
+msgid "1 line yanked"
+msgstr "Запам'Ñтав один Ñ€Ñдок"
+
+#, c-format
+msgid "block of %ld lines yanked"
+msgstr "Запам'Ñтав блок із %ld Ñ€Ñдків"
+
+#, c-format
+msgid "%ld lines yanked"
+msgstr "Запам'Ñтав Ñ€Ñдків: %ld"
+
+#, c-format
+msgid "E353: Nothing in register %s"
+msgstr "E353: У регіÑтрі %s нічого немає"
+
+# msgstr "E353: "
+#. Highlight title
+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"
+
+#, c-format
+msgid "%ld Cols; "
+msgstr "довж.: %ld; "
+
+#, c-format
+msgid "Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Bytes"
+msgstr "Вибрано %s%ld з %ld Ñ€Ñдків; %ld з %ld Ñлів; %ld з %ld байтів"
+
+#, c-format
+msgid ""
+"Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Chars; %ld of %ld "
+"Bytes"
+msgstr ""
+"Вибрано %s%ld з %ld Ñ€Ñдків; %ld з %ld Ñлів; %ld of %ld Ñимволів; %ld з %ld "
+"байтів"
+
+#, c-format
+msgid "Col %s of %s; Line %ld of %ld; Word %ld of %ld; Byte %ld of %ld"
+msgstr "Колонка %s з %s; Ñ€Ñдок %ld з %ld; Ñлово %ld з %ld; байт %ld з %ld"
+
+#, c-format
+msgid ""
+"Col %s of %s; Line %ld of %ld; Word %ld of %ld; Char %ld of %ld; Byte %ld of "
+"%ld"
+msgstr ""
+"Колонка %s з %s; Ñ€Ñдок %ld з %ld; Ñлово %ld з %ld; Ñимвол %ld of %ld; байт "
+"%ld з %ld"
+
+#, c-format
+msgid "(+%ld for BOM)"
+msgstr "(+%ld Ð´Ð»Ñ BOM)"
+
+msgid "%<%f%h%m%=Page %N"
+msgstr "%<%f%h%m%=Стор. %N"
+
+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: Ðе дозволено у modeline"
+
+msgid "E846: Key code not set"
+msgstr "E846: Код ключа не вÑтановлено"
+
+msgid "E521: Number required after ="
+msgstr "E521: ПіÑÐ»Ñ = потрібно вказати чиÑло"
+
+msgid "E522: Not found in termcap"
+msgstr "E522: Ðе знайдено Ñеред можливоÑтей терміналів"
+
+#, c-format
+msgid "E539: Illegal character <%s>"
+msgstr "E539: Ðедозволений Ñимвол <%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: Ðе можна змінити в GUI GTK+ 2"
+
+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: Ðе вдалоÑÑ Ð²Ð¸Ð±Ñ€Ð°Ñ‚Ð¸ набір шрифтів"
+
+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>"
+
+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 "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'"
+
+#, 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"
+
+#. 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.
+#, c-format
+msgid "E521: Number required: &%s = '%s'"
+msgstr "E521: Потрібно вказати Number: &%s = '%s'"
+
+# msgstr "E355: "
+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"
+
+# msgstr "E356: "
+#, c-format
+msgid "E357: 'langmap': Matching character missing for %s"
+msgstr "E357: 'langmap': Ð”Ð»Ñ Ñимволу %s немає пари"
+
+# msgstr "E357: "
+#, c-format
+msgid "E358: 'langmap': Extra characters after semicolon: %s"
+msgstr "E358: 'langmap': Зайві Ñимволи піÑÐ»Ñ `;': %s"
+
+# 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"
+
+#, 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"
+
+# msgstr "E359: "
+msgid "mch_get_shellsize: not a console??\n"
+msgstr "mch_get_shellsize: не конÑоль??\n"
+
+#. if Vim opened a window: Executing a shell may cause crashes
+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: Ðе вдалоÑÑ Ð²Ð¸Ð±Ñ€Ð°Ñ‚Ð¸ принтер"
+
+#, 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 "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 "ДиÑплей Ð¥ не пройшов перевірку"
+
+msgid "Opening the X display timed out"
+msgstr "Сплив Ñ‡Ð°Ñ Ð¾Ñ‡Ñ–ÐºÑƒÐ²Ð°Ð½Ð½Ñ Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ñ‚Ñ Ð´Ð¸Ñплею Ð¥"
+
+msgid ""
+"\n"
+"Could not get security context for "
+msgstr ""
+"\n"
+"Ðе вдалоÑÑ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ñ‚Ð¸ контекÑÑ‚ безпеки Ð´Ð»Ñ "
+
+msgid ""
+"\n"
+"Could not set security context for "
+msgstr ""
+"\n"
+"Ðе вдалоÑÑ Ð²Ñтановити контекÑÑ‚ безпеки Ð´Ð»Ñ "
+
+msgid ""
+"\n"
+"Cannot execute shell "
+msgstr ""
+"\n"
+"Ðе вдалоÑÑ Ð·Ð°Ð¿ÑƒÑтити оболонку"
+
+msgid ""
+"\n"
+"Cannot execute shell sh\n"
+msgstr ""
+"\n"
+"Ðе вдалоÑÑ Ð·Ð°Ð¿ÑƒÑтити оболонку `sh'\n"
+
+# msgstr "E362: "
+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"
+"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 "shell returned %d"
+msgstr "оболонка повернула %d"
+
+#, c-format
+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 "E371: "
+#, c-format
+msgid "E372: Too many %%%c in format string"
+msgstr "E372: Забагато %%%c у Ñ€Ñдку формату"
+
+# msgstr "E372: "
+#, c-format
+msgid "E373: Unexpected %%%c in format string"
+msgstr "E373: Ðеочікуваний `%%%c' у Ñ€Ñдку формату"
+
+# msgstr "E373: "
+msgid "E374: Missing ] in format string"
+msgstr "E374: Пропущено ] у Ñ€Ñдку формату"
+
+# msgstr "E374: "
+#, c-format
+msgid "E375: Unsupported %%%c in format string"
+msgstr "E375: %%%c у Ñ€Ñдку формату не підтримуєтьÑÑ"
+
+# msgstr "E375: "
+#, c-format
+msgid "E376: Invalid %%%c in format string prefix"
+msgstr "E376: Помилковий `%%%c' у префікÑÑ– Ñ€Ñдку формату"
+
+# msgstr "E376: "
+#, c-format
+msgid "E377: Invalid %%%c in format string"
+msgstr "E377: Помилковий `%%%c' у Ñ€Ñдку формату"
+
+# msgstr "E377: "
+msgid "E378: 'errorformat' contains no pattern"
+msgstr "E378: 'errorformat' не міÑтить зразок"
+
+# msgstr "E378: "
+msgid "E379: Missing or empty directory name"
+msgstr "E379: Пропущена чи Ð¿Ð¾Ñ€Ð¾Ð¶Ð½Ñ Ð½Ð°Ð·Ð²Ð° каталогу"
+
+msgid "E553: No more items"
+msgstr "E553: Ðемає більше елементів"
+
+#, c-format
+msgid "(%d of %d)%s%s: "
+msgstr "(%d з %d)%s%s: "
+
+msgid " (line deleted)"
+msgstr " (Ñ€Ñдок знищено)"
+
+msgid "E380: At bottom of quickfix stack"
+msgstr "E380: Дно Ñтеку виправлень"
+
+msgid "E381: At top of quickfix stack"
+msgstr "E381: Вершина Ñтеку виправлень"
+
+#, c-format
+msgid "error list %d of %d; %d errors"
+msgstr "ÑпиÑок помилок %d з %d; %d помилок"
+
+msgid "E382: Cannot write, 'buftype' option is set"
+msgstr "E382: Ðе можу запиÑати, вказана Ð¾Ð¿Ñ†Ñ–Ñ 'buftype'"
+
+# msgstr "E231: "
+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["
+
+#, 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)"
+
+# msgstr "E406: "
+msgid "E66: \\z( not allowed here"
+msgstr "E66: \\z( тут не дозволено"
+
+# msgstr "E406: "
+msgid "E67: \\z1 et al. not allowed here"
+msgstr "E67: \\z1 та ін. тут не дозволено"
+
+#, c-format
+msgid "E69: Missing ] after %s%%["
+msgstr "E69: Пропущено ] піÑÐ»Ñ %s%%["
+
+#, c-format
+msgid "E70: Empty %s%%[]"
+msgstr "E70: %s%%[] порожній"
+
+# msgstr "E382: "
+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{...}"
+
+# msgstr "E339: "
+#, c-format
+msgid "E61: Nested %s*"
+msgstr "E61: Вкладені %s*"
+
+# msgstr "E61: "
+#, c-format
+msgid "E62: Nested %s%c"
+msgstr "E62: Вкладені %s%c"
+
+msgid "E63: invalid use of \\_"
+msgstr "E63: Ðекоректно вжито \\_"
+
+# msgstr "E62: "
+#, c-format
+msgid "E64: %s%c follows nothing"
+msgstr "E64: ПіÑÐ»Ñ %s%c нічого немає"
+
+msgid "E65: Illegal back reference"
+msgstr "E65: Ðекоректне зворотнє поÑиланнÑ"
+
+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%%"
+
+# msgstr "E64: "
+#, c-format
+msgid "E554: Syntax error in %s{...}"
+msgstr "E554: СинтакÑична помилка в %s{...}"
+
+msgid "External submatches:\n"
+msgstr "Зовнішні під-збіги:\n"
+
+msgid ""
+"E864: \\%#= can only be followed by 0, 1, or 2. The automatic engine will be "
+"used "
+msgstr ""
+"E864: піÑÐ»Ñ \\%#= може бути тільки 0, 1, or 2. Буде викориÑтано автоматичний механізм "
+
+#, c-format
+msgid "E866: (NFA regexp) Misplaced %c"
+msgstr "E866: (NFA regexp) Ðе на міÑці %c"
+
+msgid "E865: (NFA) Regexp end encountered prematurely"
+msgstr "E865: (NFA) Зарано трапивÑÑ ÐºÑ–Ð½ÐµÑ†ÑŒ регулÑрного виразу"
+
+#, c-format
+msgid "E867: (NFA) Unknown operator '\\z%c'"
+msgstr "E867: (NFA) Ðевідомий оператор '\\z%c'"
+
+#, c-format
+msgid "E867: (NFA) Unknown operator '\\%%%c'"
+msgstr "E867: (NFA) Ðевідомий оператор '\\%%%c'"
+
+#. should never happen
+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) Ðе вдалоÑÑ Ð¿Ñ€Ð¾Ñ‡Ð¸Ñ‚Ð°Ñ‚Ð¸ межі повтореннÑ"
+
+#. Can't have a multi follow a multi.
+msgid "E871: (NFA regexp) Can't have a multi follow a multi !"
+msgstr "E871: (NFA regexp) Мульти не може бути за мульти!"
+
+#. Too many `('
+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) (Під Ñ‡Ð°Ñ Ð¿ÐµÑ€ÐµÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð· поÑÑ‚Ñ„Ñ–ÐºÑ Ñƒ 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 " (lang)"
+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: ПіÑÐ»Ñ `;' має бути `?' або `/'"
+
+# msgstr "E386: "
+msgid " (includes previously listed match)"
+msgstr " (разом з попередніми збігами)"
+
+#. cursor at status line
+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 "E759: Format error in spell file"
+msgstr "E759: Помилка формату у файлі орфографії"
+
+# msgstr "E364: "
+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"
+
+# msgstr "E430: "
+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 "СтиÑкуєтьÑÑ Ð´ÐµÑ€ÐµÐ²Ð¾ Ñлів..."
+
+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»"
+
+#, 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 "Warning: region %s not supported"
+msgstr "ЗаÑтереженнÑ: регіон %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 у Ñ€Ñдку %d"
+
+#, c-format
+msgid ""
+"Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in %s line "
+"%d"
+msgstr ""
+"Ð’Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ COMPOUNDPERMITFLAG піÑÐ»Ñ ÐµÐ»ÐµÐ¼ÐµÐ½Ñ‚Ñƒ PFX можу дати неправильний "
+"результат у %s у Ñ€Ñдку %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 %6d - %s"
+msgstr "Ñ€Ñдок %6d, Ñлово %6d - %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 "ПеречитуєтьÑÑ Ñ„Ð°Ð¹Ð» орфографії..."
+
+#.
+#. * Go through the trie of good words, soundfold each word and add it to
+#. * the soundfold trie.
+#.
+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: Вихідний файл не повинен мати назву регіону"
+
+msgid "E754: Only up to 8 regions supported"
+msgstr "E754: ПідтримуєтьÑÑ Ñ‚Ñ–Ð»ÑŒÐºÐ¸ до воÑьми регіонів"
+
+#, 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 "Sorry, no suggestions"
+msgstr "Пробачте, немає пропозицій"
+
+#, c-format
+msgid "Sorry, only %ld suggestions"
+msgstr "Пробачте, тільки %ld пропозицій"
+
+#. for when 'cmdheight' > 1
+#. avoid more prompt
+#, c-format
+msgid "Change \"%.*s\" to:"
+msgstr "Замінити «%.*s» на:"
+
+#, c-format
+msgid " < \"%.*s\""
+msgstr " < «%.*s»"
+
+# msgstr "E34: "
+msgid "E752: No previous spell replacement"
+msgstr "E752: Ðемає попередньої заміни"
+
+# msgstr "E333: "
+#, c-format
+msgid "E753: Not found: %s"
+msgstr "E753: Ðе знайдено: %s"
+
+#, 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"
+
+#. This should have been checked when generating the .spl
+#. * file.
+msgid "E783: duplicate char in MAP entry"
+msgstr "E783: Повторено Ñимвол у елементі MAP"
+
+# msgstr "E391: "
+msgid "No Syntax items defined for this buffer"
+msgstr "Ð”Ð»Ñ Ð±ÑƒÑ„ÐµÑ€Ð° не визначено елементів ÑинтакÑиÑу"
+
+#, c-format
+msgid "E390: Illegal argument: %s"
+msgstr "E390: Ðеправильний аргумент: %s"
+
+#, c-format
+msgid "E391: No such syntax cluster: %s"
+msgstr "E391: Ðемає такого ÑинтакÑичного клаÑтера: %s"
+
+msgid "syncing on C-style comments"
+msgstr "ÑинхронізуєтьÑÑ Ð¿Ð¾ коментарÑÑ… Ñтилю С"
+
+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: МіÑтить неприйнÑтні тут аргументи"
+
+# msgstr "E14: "
+msgid "E844: invalid cchar value"
+msgstr "E844: Ðекоректне Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ cchar"
+
+msgid "E393: group[t]here not accepted here"
+msgstr "E393: group[t]hete тут неприйнÑтний"
+
+#, c-format
+msgid "E394: Didn't find region item for %s"
+msgstr "E394: Ðе знайдено елемент регіону Ð´Ð»Ñ %s"
+
+# msgstr "E396: "
+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 "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"
+
+# msgstr "E402: "
+msgid "E403: syntax sync: line continuations pattern specified twice"
+msgstr ""
+"E403: СинтакÑична ÑинхронізаціÑ: зразок Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð´Ð¾Ð²Ð¶ÐµÐ½Ð½Ñ Ñ€Ñдка вказано двічі"
+
+#, c-format
+msgid "E404: Illegal arguments: %s"
+msgstr "E404: Ðеправильні аргументи: %s"
+
+# msgstr "E404: "
+#, c-format
+msgid "E405: Missing equal sign: %s"
+msgstr "E405: Пропущено знак рівноÑті: %s"
+
+# msgstr "E405: "
+#, c-format
+msgid "E406: Empty argument: %s"
+msgstr "E406: Порожній аргумент: %s"
+
+# msgstr "E406: "
+#, 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"
+
+# msgstr "E409: "
+#, 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"
+
+# msgstr "E410: "
+#, c-format
+msgid "E411: highlight group not found: %s"
+msgstr "E411: Групу підÑÐ²Ñ–Ñ‡ÑƒÐ²Ð°Ð½Ð½Ñ Ð½Ðµ знайдено: %s"
+
+# msgstr "E411: "
+#, c-format
+msgid "E412: Not enough arguments: \":highlight link %s\""
+msgstr "E412: ÐедоÑтатньо аргументів: «:highlight link %s»"
+
+# msgstr "E412: "
+#, c-format
+msgid "E413: Too many arguments: \":highlight link %s\""
+msgstr "E413: Забагато аргументів: «:highlight link %s»"
+
+# msgstr "E413: "
+msgid "E414: group has settings, highlight link ignored"
+msgstr "E414: Грума має settings, highlight link проігноровано"
+
+# msgstr "E414: "
+#, c-format
+msgid "E415: unexpected equal sign: %s"
+msgstr "E415: ÐеÑподіваний знак рівноÑті: %s"
+
+# msgstr "E415: "
+#, 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"
+
+# msgstr "E418: "
+msgid "E419: FG color unknown"
+msgstr "E419: Ðевідомий колір текÑту"
+
+# msgstr "E419: "
+msgid "E420: BG color unknown"
+msgstr "E420: Ðевідомий колір фону"
+
+# msgstr "E420: "
+#, c-format
+msgid "E421: Color name or number not recognized: %s"
+msgstr "E421: Ðерозпізнана назва або номер кольору: %s"
+
+# msgstr "E421: "
+#, c-format
+msgid "E422: terminal code too long: %s"
+msgstr "E422: Занадто довгий код терміналу: %s"
+
+# msgstr "E422: "
+#, c-format
+msgid "E423: Illegal argument: %s"
+msgstr "E423: Ðеправильний аргумент: %s"
+
+# msgstr "E423: "
+msgid "E424: Too many different highlighting attributes in use"
+msgstr "E424: ВикориÑтано забагато різних атрибутів кольору"
+
+msgid "E669: Unprintable character in group name"
+msgstr "E669: Ðедруковний Ñимвол у назві групи"
+
+# msgstr "E181: "
+msgid "W18: Invalid character in group name"
+msgstr "W18: Ðекоректний Ñимвол у назві групи"
+
+msgid "E849: Too many highlight and syntax groups"
+msgstr "E849: Забагато груп підÑÐ²Ñ–Ñ‡ÑƒÐ²Ð°Ð½Ð½Ñ Ñ– ÑинтакÑиÑу"
+
+# msgstr "E424: "
+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: Це вже найперший відповідний теґ"
+
+# msgstr "E425: "
+#, c-format
+msgid "E426: tag not found: %s"
+msgstr "E426: Теґ не знайдено: %s"
+
+# msgstr "E426: "
+msgid " # pri kind tag"
+msgstr " # прі тип теґ"
+
+msgid "file\n"
+msgstr "файл\n"
+
+msgid "E427: There is only one matching tag"
+msgstr "E427: Лише один відповідний теґ"
+
+# msgstr "E427: "
+msgid "E428: Cannot go beyond last matching tag"
+msgstr "E428: Це вже оÑтанній відповідний теґ"
+
+# msgstr "E428: "
+#, c-format
+msgid "File \"%s\" does not exist"
+msgstr "Файл «%s» не Ñ–Ñнує"
+
+#. Give an indication of the number of matching tags
+#, 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» не Ñ–Ñнує"
+
+# msgstr "E429: "
+#. Highlight title
+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 "ІгноруєтьÑÑ Ð´Ð¾Ð²Ð³Ð¸Ð¹ Ñ€Ñдок у файлі з позначками"
+
+# msgstr "E430: "
+#, c-format
+msgid "E431: Format error in tags file \"%s\""
+msgstr "E431: Помилка формату у файлі теґів «%s»"
+
+# msgstr "E431: "
+#, c-format
+msgid "Before byte %ld"
+msgstr "Перед байтом %ld"
+
+#, c-format
+msgid "E432: Tags file not sorted: %s"
+msgstr "E432: Файл теґів не впорÑдкований: %s"
+
+# msgstr "E432: "
+#. never opened any tags file
+msgid "E433: No tags file"
+msgstr "E433: Ðемає файлу теґів"
+
+# msgstr "E433: "
+msgid "E434: Can't find tag pattern"
+msgstr "E434: Ðе вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ зразок теґу"
+
+# msgstr "E434: "
+msgid "E435: Couldn't find tag, just guessing!"
+msgstr "E435: Ðе вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ теґ, тільки припущеннÑ!"
+
+#, c-format
+msgid "Duplicate field name: %s"
+msgstr "Ðазва Ð¿Ð¾Ð»Ñ Ð¿Ð¾Ð²Ñ‚Ð¾Ñ€ÑŽÑ”Ñ‚ÑŒÑÑ: %s"
+
+# msgstr "E435: "
+msgid "' not known. Available builtin terminals are:"
+msgstr "' не відомий. Вбудовані термінали:"
+
+msgid "defaulting to '"
+msgstr "початково '"
+
+msgid "E557: Cannot open termcap file"
+msgstr "E557: Ðе вдалоÑÑ Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ð¸ файл можливоÑтей терміналів"
+
+msgid "E558: Terminal entry not found in terminfo"
+msgstr "E558: Ðемає інформації про термінал"
+
+msgid "E559: Terminal entry not found in termcap"
+msgstr "E559: Ðемає інформації про можливоÑті терміналу"
+
+#, c-format
+msgid "E436: No \"%s\" entry in termcap"
+msgstr "E436: Ðемає запиÑу «%s» про можливоÑті терміналу"
+
+msgid "E437: terminal capability \"cm\" required"
+msgstr "E437: Потрібна можливіÑть терміналу «cm»"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Terminal keys ---"
+msgstr ""
+"\n"
+"--- Клавіші терміналу ---"
+
+msgid "new shell started\n"
+msgstr "запущено нову оболонку\n"
+
+msgid "Vim: Error reading input, exiting...\n"
+msgstr "Vim: Помилка Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ Ð²Ð²Ð¾Ð´Ñƒ, робота завершуєтьÑÑ...\n"
+
+# msgstr "E242: "
+msgid "Used CUT_BUFFER0 instead of empty selection"
+msgstr "ВикориÑтано CUT_BUFFER0 заміÑть порожнього виділеннÑ"
+
+#. This happens when the FileChangedRO autocommand changes the
+#. * file in a way it becomes shorter.
+msgid "E834: Line count changed unexpectedly"
+msgstr "E834: КількіÑть Ñ€Ñдків неÑподівано змінилаÑÑ"
+
+#. must display the prompt
+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 "Will not overwrite with undo file, cannot read: %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"
+
+# msgstr "E333: "
+#, 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 "Ñ€Ñдків знищено"
+
+# msgstr "E438: "
+msgid "change"
+msgstr "зміна"
+
+# msgstr "E438: "
+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 Ñекунд тому"
+
+# msgstr "E406: "
+msgid "E790: undojoin is not allowed after undo"
+msgstr "E790: Ðе можна виконати undojoin піÑÐ»Ñ undo"
+
+msgid "E439: undo list corrupt"
+msgstr "E439: СпиÑок ÑкаÑÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ð¾ÑˆÐºÐ¾Ð´Ð¶ÐµÐ½Ð¾"
+
+# msgstr "E439: "
+msgid "E440: undo line missing"
+msgstr "E440: ВідÑутній Ñ€Ñдок ÑкаÑуваннÑ"
+
+# msgstr "E440: "
+# ---------------------------------------
+#. Only MS VC 4.1 and earlier can do Win32s
+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"
+"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 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 " Features included (+) or not (-):\n"
+msgstr " Включені (+) або не включені (-) компоненти:\n"
+
+msgid " system vimrc file: \""
+msgstr " ÑиÑтемний vimrc: \""
+
+msgid " user vimrc file: \""
+msgstr " vimrc кориÑтувача: \""
+
+msgid " 2nd user vimrc file: \""
+msgstr " другий vimrc кориÑтувача: \""
+
+msgid " 3rd user vimrc file: \""
+msgstr " третій vimrc кориÑтувача: \""
+
+msgid " user exrc file: \""
+msgstr " exrc кориÑтувача: \""
+
+msgid " 2nd user exrc file: \""
+msgstr " другий exrc кориÑтувача: \""
+
+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 " 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 " ВЕРСІЯ ДЛЯ ÐÐЛÐГОДЖЕÐÐЯ"
+
+msgid "VIM - Vi IMproved"
+msgstr "VIM - Покращений Vi"
+
+msgid "version "
+msgstr "верÑÑ–Ñ "
+
+msgid "by Bram Moolenaar et al."
+msgstr "автор: Bram Moolenaar та ін."
+
+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> вихід з Vim "
+
+msgid "type :help<Enter> or <F1> for on-line help"
+msgstr ":help<Enter> або <F1> переглÑд допомоги "
+
+msgid "type :help version7<Enter> for version info"
+msgstr ":help version7<Enter> Ñ–Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ Ð¿Ñ€Ð¾ верÑÑ–ÑŽ "
+
+msgid "Running in Vi compatible mode"
+msgstr "Ви працюєте в режимі ÑуміÑному з Vi"
+
+msgid "type :set nocp<Enter> for Vim defaults"
+msgstr ":set nocp<Enter> режим неÑуміÑний з Vi "
+
+msgid "type :help cp-default<Enter> for info on this"
+msgstr ":help cp-default<Enter> Ñ–Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ Ð¿Ñ€Ð¾ ÑуміÑніÑть"
+
+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 "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 "WARNING: Windows 95/98/ME detected"
+msgstr "ЗÐСТЕРЕЖЕÐÐЯ: Ви кориÑтуєтеÑÑ Windows 95/98/ME"
+
+msgid "type :help windows95<Enter> for info on this"
+msgstr ":help windows95<Enter> Ñ–Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ Ð¿Ñ€Ð¾ це "
+
+# msgstr "E444: "
+msgid "Already only one window"
+msgstr "Це вже єдине вікно"
+
+msgid "E441: There is no preview window"
+msgstr "E441: Ðемає вікна переглÑду"
+
+# msgstr "E441: "
+msgid "E442: Can't split topleft and botright at the same time"
+msgstr "E442: Ðе вдалоÑÑ Ð¾Ð´Ð½Ð¾Ñ‡Ð°Ñно розбити topleft Ñ– botright"
+
+# msgstr "E442: "
+msgid "E443: Cannot rotate when another window is split"
+msgstr "E443: Ðе вдалоÑÑ Ð¿ÐµÑ€ÐµÐ¼Ñ–Ñтити вікно, заважають інші"
+
+# msgstr "E443: "
+msgid "E444: Cannot close last window"
+msgstr "E444: Ðе вдалоÑÑ Ð·Ð°ÐºÑ€Ð¸Ñ‚Ð¸ оÑтаннє вікно"
+
+# msgstr "E443: "
+msgid "E813: Cannot close autocmd window"
+msgstr "E813: Ðе вдалоÑÑ Ð·Ð°ÐºÑ€Ð¸Ñ‚Ð¸ вікно autocmd"
+
+# msgstr "E443: "
+msgid "E814: Cannot close window, only autocmd window would remain"
+msgstr "E814: Ðе вдалоÑÑ Ð·Ð°ÐºÑ€Ð¸Ñ‚Ð¸ вікно, залишилоÑÑ Ð± тільки вікно autocmd"
+
+msgid "E445: Other window contains changes"
+msgstr "E445: У іншому вікні є зміни"
+
+# msgstr "E445: "
+msgid "E446: No file name under cursor"
+msgstr "E446: Ðемає назви файлу над курÑором"
+
+# msgstr "E446: "
+#, c-format
+msgid "E447: Can't find file \"%s\" in path"
+msgstr "E447: Файл «%s» не знайдено у шлÑху пошуку"
+
+#, 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 заборонене у піÑочниці без Ð¼Ð¾Ð´ÑƒÐ»Ñ 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"
+
+#. Now concatenate
+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 "E447: "
+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.
+#.
+msgid "E470: Command aborted"
+msgstr "E470: Команду перервано"
+
+msgid "E471: Argument required"
+msgstr "E471: Ðеобхідно вказати аргумент"
+
+msgid "E10: \\ should be followed by /, ? or &"
+msgstr "E10: За \\ має йти /, ? або &"
+
+# 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: Команда на вдалаÑÑŒ"
+
+# msgstr "E233: "
+#, c-format
+msgid "E234: Unknown fontset: %s"
+msgstr "E234: Ðевідомий набір шрифтів: %s"
+
+#, c-format
+msgid "E235: Unknown font: %s"
+msgstr "E235: Ðевідомий шрифт: %s"
+
+# msgstr "E235: "
+#, c-format
+msgid "E236: Font \"%s\" is not fixed-width"
+msgstr "E236: Шрифт «%s» не моноширинний"
+
+msgid "E473: Internal error"
+msgstr "E473: Ð’Ð½ÑƒÑ‚Ñ€Ñ–ÑˆÐ½Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ°"
+
+msgid "Interrupted"
+msgstr "Перервано"
+
+msgid "E14: Invalid address"
+msgstr "E14: Ðеправильна адреÑа"
+
+# msgstr "E14: "
+msgid "E474: Invalid argument"
+msgstr "E474: Ðекоректний аргумент"
+
+#, c-format
+msgid "E475: Invalid argument: %s"
+msgstr "E475: Ðекоректний аргумент: %s"
+
+#, c-format
+msgid "E15: Invalid expression: %s"
+msgstr "E15: Ðеправильний вираз: %s"
+
+# msgstr "E15: "
+msgid "E16: Invalid range"
+msgstr "E16: Ðеправильні межі"
+
+# 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()» не вдавÑÑ"
+
+#, c-format
+msgid "E448: Could not load library function %s"
+msgstr "E448: Ðе вдалоÑÑ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶Ð¸Ñ‚Ð¸ бібліотечну функцію %s"
+
+# msgstr "E18: "
+msgid "E19: Mark has invalid line number"
+msgstr "E19: У помітки некоректний номер Ñ€Ñдка"
+
+# msgstr "E19: "
+msgid "E20: Mark not set"
+msgstr "E20: Помітку не вÑтановлено"
+
+# msgstr "E20: "
+msgid "E21: Cannot make changes, 'modifiable' is off"
+msgstr "E21: Зміни не дозволені: вимкнено 'modifiable'"
+
+# msgstr "E21: "
+msgid "E22: Scripts nested too deep"
+msgstr "E22: Забагато вкладених Ñкриптів"
+
+# msgstr "E22: "
+msgid "E23: No alternate file"
+msgstr "E23: Ðемає вторинного файлу"
+
+# msgstr "E23: "
+msgid "E24: No such abbreviation"
+msgstr "E24: Такого ÑÐºÐ¾Ñ€Ð¾Ñ‡ÐµÐ½Ð½Ñ Ð½ÐµÐ¼Ð°Ñ”"
+
+# 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"
+
+# msgstr "E25: "
+#, c-format
+msgid "E28: No such highlight group name: %s"
+msgstr "E28: Ðемає такої групи підÑвічуваннÑ: %s"
+
+# msgstr "E28: "
+msgid "E29: No inserted text yet"
+msgstr "E29: ТекÑÑ‚ ще не було додано"
+
+# msgstr "E29: "
+msgid "E30: No previous command line"
+msgstr "E30: Ще не було команд"
+
+# msgstr "E30: "
+msgid "E31: No such mapping"
+msgstr "E31: Ðемає такої заміни"
+
+# 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: Бракує назви файлу"
+
+# msgstr "E32: "
+msgid "E33: No previous substitute regular expression"
+msgstr "E33: Заміна зразків ще не викориÑтовувалаÑÑŒ"
+
+# msgstr "E33: "
+msgid "E34: No previous command"
+msgstr "E34: Команд ще не було"
+
+# msgstr "E34: "
+msgid "E35: No previous regular expression"
+msgstr "E35: Зразків пошуку ще не було"
+
+# 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»"
+
+# msgstr "E36: "
+#, 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 "E37: No write since last change (add ! to override)"
+msgstr "E37: Зміни не було запиÑано (! щоб не зважати)"
+
+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: ЗіпÑована програма регулÑрних виразів"
+
+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: Ðе можна вÑтановити змінну у піÑочниці: «%s»"
+
+msgid "E47: Error while reading errorfile"
+msgstr "E47: Помилка Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ Ñ„Ð°Ð¹Ð»Ñƒ помилок"
+
+msgid "E48: Not allowed in sandbox"
+msgstr "E48: Ðа дозволено у піÑочниці"
+
+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' порожнÑ"
+
+# msgstr "E254: "
+msgid "E255: Couldn't read in sign data!"
+msgstr "E255: Ðе можна зчитати дані напиÑу!"
+
+msgid "E72: Close error on swap file"
+msgstr "E72: Помилка під Ñ‡Ð°Ñ Ð·Ð°ÐºÑ€Ð¸Ñ‚Ñ‚Ñ Ñ„Ð°Ð¹Ð»Ñƒ обміну"
+
+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'"
+
+# msgstr "E79: "
+msgid "E80: Error while writing"
+msgstr "E80: Помилка під Ñ‡Ð°Ñ Ð·Ð°Ð¿Ð¸Ñу"
+
+msgid "Zero count"
+msgstr "Ðульова кількіÑть"
+
+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 не дозволÑÑ” змінювати захищені від запиÑу файли"
+
+#, c-format
+msgid "E685: Internal error: %s"
+msgstr "E685: Ð’Ð½ÑƒÑ‚Ñ€Ñ–ÑˆÐ½Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ°: %s"
+
+msgid "E363: pattern uses more memory than 'maxmempattern'"
+msgstr "E363: Зразок викориÑтовує більше, ніж 'maxmempattern', пам'Ñті"
+
+msgid "E749: empty buffer"
+msgstr "E749: Порожній буфер"
+
+msgid "E682: Invalid search pattern or delimiter"
+msgstr "E682: Ðекоректний зразок Ð´Ð»Ñ Ð¿Ð¾ÑˆÑƒÐºÑƒ чи роздільник"
+
+msgid "E139: File is loaded in another buffer"
+msgstr "E139: Файл уже завантажено в інший буфер"
+
+# msgstr "E235: "
+#, c-format
+msgid "E764: Option '%s' is not set"
+msgstr "E764: ÐžÐ¿Ñ†Ñ–Ñ '%s' не вÑтановлена"
+
+msgid "E850: Invalid register name"
+msgstr "E850: Ðеправильна назва регіÑтру"
+
+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» потрібен ключ: "
+
+# msgstr "E406: "
+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 "Ñ–Ð½Ð´ÐµÐºÑ Ð¼Ð°Ñ” бути цілий чи зріз, не %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 then zero"
+msgstr "чиÑло має бути більше, ніж нуль"
+
+msgid "number must be greater or equal to zero"
+msgstr "чиÑло має бути не менше, ніж нуль"
+
+msgid "can't delete OutputObject attributes"
+msgstr "не вдалоÑÑ Ð·Ð½Ð¸Ñ‰Ð¸Ñ‚Ð¸ атрибути OutputObject"
+
+# msgstr "E180: "
+#, 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 "очікувавÑÑ 3-кортеж Ñк результат imp.find_module(), але отримано %s"
+
+#, c-format
+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 "не можна змінити фікÑований Ñловник"
+
+#, c-format
+msgid "cannot set attribute %s"
+msgstr "не можна вÑтановити атрибут %s"
+
+msgid "hashtab changed during iteration"
+msgstr "хеш-Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ñ Ð·Ð¼Ñ–Ð½Ð¸Ð»Ð°ÑÑ Ð¿Ñ–Ð´ Ñ‡Ð°Ñ Ð¿ÐµÑ€ÐµÐ±Ð¸Ñ€Ð°Ð½Ð½Ñ"
+
+#, 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 "Ñ–Ð½Ð´ÐµÐºÑ ÑпиÑку за межами"
+
+#. No more suitable format specifications in python-2.3
+#, c-format
+msgid "internal error: failed to get vim list item %d"
+msgstr "Ð²Ð½ÑƒÑ‚Ñ€Ñ–ÑˆÐ½Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ°: не вдалоÑÑ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ñ‚Ð¸ елемент ÑпиÑку vim %d"
+
+msgid "failed to add item to list"
+msgstr "не вдалоÑÑ Ð´Ð¾Ð´Ð°Ñ‚Ð¸ елемент до ÑпиÑку"
+
+#, c-format
+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: "
+#, c-format
+msgid "unnamed function %s does not exist"
+msgstr "безіменної функції %s не Ñ–Ñнує"
+
+# msgstr "E428: "
+#, c-format
+msgid "function %s does not exist"
+msgstr "функції %s не Ñ–Ñнує"
+
+msgid "function constructor does not accept keyword arguments"
+msgstr "конÑтруктор функції не приймає іменовані аргументи"
+
+#, 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 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/po/vi.po b/src/po/vi.po
new file mode 100644
index 0000000000..908b2eb158
--- /dev/null
+++ b/src/po/vi.po
@@ -0,0 +1,5196 @@
+# Vietnamese translation for Vim
+# first translator(s): Phan Vinh Thinh <teppi@vnlinux.org>, 2005
+# Original translations.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Vim 6.3 \n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2005-02-25 22:51+0300\n"
+"PO-Revision-Date: 2005-02-30 21:37+0400\n"
+"Last-Translator: Phan Vinh Thinh <teppi@vnlinux.org>\n"
+"Language-Team: Phan Vinh Thinh <teppi@vnlinux.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+msgid "E82: Cannot allocate any buffer, exiting..."
+msgstr "E82: Không thể phân chia bộ nhớ thậm chí cho một bộ đệm, thoát..."
+
+msgid "E83: Cannot allocate buffer, using other one..."
+msgstr "E83: Không thể phân chia bộ nhớ cho bộ đệm, sử dụng bộ đệm khác..."
+
+msgid "E515: No buffers were unloaded"
+msgstr "E515: Không có bộ đệm nào được bỠnạp từ bộ nhớ"
+
+msgid "E516: No buffers were deleted"
+msgstr "E516: Không có bộ đệm nào bị xóa"
+
+msgid "E517: No buffers were wiped out"
+msgstr "E517: Không có bộ đệm nào được làm sạch"
+
+msgid "1 buffer unloaded"
+msgstr "1 bộ đệm được bỠnạp từ bộ nhớ"
+
+#, c-format
+msgid "%d buffers unloaded"
+msgstr "%d bộ đệm được bỠnạp từ bộ nhớ"
+
+msgid "1 buffer deleted"
+msgstr "1 bộ đệm bị xóa"
+
+#, c-format
+msgid "%d buffers deleted"
+msgstr "%d bộ đệm được bỠnạp"
+
+msgid "1 buffer wiped out"
+msgstr "1 bộ đệm được làm sạch"
+
+#, c-format
+msgid "%d buffers wiped out"
+msgstr "%d bộ đệm được làm sạch"
+
+msgid "E84: No modified buffer found"
+msgstr "E84: Không tìm thấy bộ đệm có thay đổi"
+
+#. back where we started, didn't find anything.
+msgid "E85: There is no listed buffer"
+msgstr "E85: Không có bộ đệm được liệt kê"
+
+#, c-format
+msgid "E86: Buffer %ld does not exist"
+msgstr "E86: Bộ đệm %ld không tồn tại"
+
+msgid "E87: Cannot go beyond last buffer"
+msgstr "E87: Äây là bá»™ đệm cuối cùng"
+
+msgid "E88: Cannot go before first buffer"
+msgstr "E88: Äây là bá»™ đệm đầu tiên"
+
+#, c-format
+msgid "E89: No write since last change for buffer %ld (add ! to override)"
+msgstr ""
+"E89: Thay đổi trong bộ đệm %ld chưa được ghi lại (thêm ! để thoát ra bằng "
+"má»i giá)"
+
+msgid "E90: Cannot unload last buffer"
+msgstr "E90: Không thể bỠnạp từ bộ nhớ bộ đệm cuối cùng"
+
+msgid "W14: Warning: List of file names overflow"
+msgstr "W14: Cảnh báo: Danh sách tên tập tin quá đầy"
+
+#, c-format
+msgid "E92: Buffer %ld not found"
+msgstr "E92: Bộ đệm %ld không được tìm thấy"
+
+#, c-format
+msgid "E93: More than one match for %s"
+msgstr "E93: Tìm thấy vài tương ứng với %s"
+
+#, c-format
+msgid "E94: No matching buffer for %s"
+msgstr "E94: Không có bộ đệm tương ứng với %s"
+
+#, c-format
+msgid "line %ld"
+msgstr "dòng %ld"
+
+msgid "E95: Buffer with this name already exists"
+msgstr "E95: Äã có bá»™ đệm vá»›i tên như vậy"
+
+msgid " [Modified]"
+msgstr " [Äã thay đổi]"
+
+msgid "[Not edited]"
+msgstr "[Chưa soạn thảo]"
+
+msgid "[New file]"
+msgstr "[Tập tin mới]"
+
+msgid "[Read errors]"
+msgstr "[Lá»—i Ä‘á»c]"
+
+msgid "[readonly]"
+msgstr "[chỉ Ä‘á»c]"
+
+#, c-format
+msgid "1 line --%d%%--"
+msgstr "1 dòng --%d%%--"
+
+#, c-format
+msgid "%ld lines --%d%%--"
+msgstr "%ld dòng --%d%%--"
+
+#, c-format
+msgid "line %ld of %ld --%d%%-- col "
+msgstr "dòng %ld của %ld --%d%%-- cột "
+
+msgid "[No file]"
+msgstr "[Không có tập tin]"
+
+#. must be a help buffer
+msgid "help"
+msgstr "trợ giúp"
+
+msgid "[help]"
+msgstr "[trợ giúp]"
+
+msgid "[Preview]"
+msgstr "[Xem trước]"
+
+msgid "All"
+msgstr "Tất cả"
+
+msgid "Bot"
+msgstr "Cuối"
+
+msgid "Top"
+msgstr "Äầu"
+
+msgid ""
+"\n"
+"# Buffer list:\n"
+msgstr ""
+"\n"
+"# Danh sách bộ đệm:\n"
+
+msgid "[Error List]"
+msgstr "[Danh sách lỗi]"
+
+msgid "[No File]"
+msgstr "[Không có tập tin]"
+
+msgid ""
+"\n"
+"--- Signs ---"
+msgstr ""
+"\n"
+"--- Ký hiệu ---"
+
+#, c-format
+msgid "Signs for %s:"
+msgstr "Ký hiệu cho %s:"
+
+#, c-format
+msgid " line=%ld id=%d name=%s"
+msgstr " dòng=%ld id=%d tên=%s"
+
+#, c-format
+msgid "E96: Can not diff more than %ld buffers"
+msgstr "E96: Chỉ có thể theo dõi sá»± khác nhau trong nhiá»u nhất %ld bá»™ đệm"
+
+msgid "E97: Cannot create diffs"
+msgstr "E97: Không thể tạo tập tin khác biệt (diff)"
+
+msgid "Patch file"
+msgstr "Tập tin vá lỗi (patch)"
+
+msgid "E98: Cannot read diff output"
+msgstr "E98: Không thể Ä‘á»c dữ liệu ra cá»§a lệnh diff"
+
+msgid "E99: Current buffer is not in diff mode"
+msgstr "E99: Bá»™ đệm hiện thá»i không nằm trong chế độ khác biệt (diff)"
+
+msgid "E100: No other buffer in diff mode"
+msgstr "E100: Không còn bộ đệm trong chế độ khác biệt (diff) nào nữa"
+
+msgid "E101: More than two buffers in diff mode, don't know which one to use"
+msgstr ""
+"E101: Có nhiá»u hÆ¡n hai bá»™ đệm trong chế độ khác biệt (diff), không biết chá»n"
+
+#, c-format
+msgid "E102: Can't find buffer \"%s\""
+msgstr "E102: Không tìm thấy bộ đệm \"%s\""
+
+#, c-format
+msgid "E103: Buffer \"%s\" is not in diff mode"
+msgstr "E103: Bộ đệm \"%s\" không nằm trong chế độ khác biệt (diff)"
+
+msgid "E104: Escape not allowed in digraph"
+msgstr "E104: Không cho phép dùng ký tự thoát Escape trong chữ ghép"
+
+msgid "E544: Keymap file not found"
+msgstr "E544: Không tìm thấy tập tin sơ đồ bàn phím"
+
+msgid "E105: Using :loadkeymap not in a sourced file"
+msgstr "E105: Câu lệnh :loadkeymap được sử dụng ngoài tập tin script"
+
+msgid " Keyword completion (^N^P)"
+msgstr " Tự động kết thúc cho từ khóa (^N^P)"
+
+#. ctrl_x_mode == 0, ^P/^N compl.
+msgid " ^X mode (^E^Y^L^]^F^I^K^D^V^N^P)"
+msgstr " Chế độ ^X (^E^Y^L^]^F^I^K^D^V^N^P)"
+
+#. Scroll has it's own msgs, in it's place there is the msg for local
+#. * ctrl_x_mode = 0 (eg continue_status & CONT_LOCAL) -- Acevedo
+msgid " Keyword Local completion (^N^P)"
+msgstr " Tự động kết thúc nội bộ cho từ khóa (^N^P)"
+
+msgid " Whole line completion (^L^N^P)"
+msgstr " Tự động kết thúc cho cả dòng (^L^N^P)"
+
+msgid " File name completion (^F^N^P)"
+msgstr " Tự động kết thúc tên tập tin (^F^N^P)"
+
+msgid " Tag completion (^]^N^P)"
+msgstr " Tự động kết thúc thẻ đánh dấu (^]^N^P)"
+
+msgid " Path pattern completion (^N^P)"
+msgstr " Tá»± động kết thúc mẫu đưá»ng dẫn (^N^P)"
+
+msgid " Definition completion (^D^N^P)"
+msgstr " Tự động kết thúc định nghĩa (^D^N^P)"
+
+msgid " Dictionary completion (^K^N^P)"
+msgstr " Tự động kết thúc theo từ điển (^K^N^P)"
+
+msgid " Thesaurus completion (^T^N^P)"
+msgstr " Tự động kết thúc từ đồng âm (^T^N^P)"
+
+msgid " Command-line completion (^V^N^P)"
+msgstr " Tự động kết thúc dòng lệnh (^V^N^P)"
+
+msgid "Hit end of paragraph"
+msgstr "Kết thúc của đoạn văn"
+
+msgid "'thesaurus' option is empty"
+msgstr "Không đưa ra giá trị cá»§a tùy chá»n 'thesaurus'"
+
+msgid "'dictionary' option is empty"
+msgstr "Không đưa ra giá trị cá»§a tùy chá»n 'dictionary'"
+
+#, c-format
+msgid "Scanning dictionary: %s"
+msgstr "Quét từ điển: %s"
+
+msgid " (insert) Scroll (^E/^Y)"
+msgstr " (chèn) Cuộn (^E/^Y)"
+
+msgid " (replace) Scroll (^E/^Y)"
+msgstr " (thay thế) Cuộn (^E/^Y)"
+
+#, c-format
+msgid "Scanning: %s"
+msgstr "Quét: %s"
+
+msgid "Scanning tags."
+msgstr "Tìm kiếm trong số thẻ đánh dấu."
+
+msgid " Adding"
+msgstr " Thêm"
+
+#. 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.
+#.
+msgid "-- Searching..."
+msgstr "-- Tìm kiếm..."
+
+msgid "Back at original"
+msgstr "Từ ban đầu"
+
+msgid "Word from other line"
+msgstr "Từ của dòng khác"
+
+msgid "The only match"
+msgstr "Tương ứng duy nhất"
+
+#, c-format
+msgid "match %d of %d"
+msgstr "Tương ứng %d của %d"
+
+#, c-format
+msgid "match %d"
+msgstr "Tương ứng %d"
+
+#. Skip further arguments but do continue to
+#. * search for a trailing command.
+#, c-format
+msgid "E106: Unknown variable: \"%s\""
+msgstr "E106: Biến không biết: \"%s\""
+
+#, c-format
+msgid "E107: Missing parentheses: %s"
+msgstr "E107: Thiếu dấu ngoặc: %s"
+
+#, c-format
+msgid "E108: No such variable: \"%s\""
+msgstr "E108: Không có biến như vậy: \"%s\""
+
+msgid "E109: Missing ':' after '?'"
+msgstr "E109: Thiếu ':' sau '?'"
+
+msgid "E110: Missing ')'"
+msgstr "E110: Thiếu ')'"
+
+msgid "E111: Missing ']'"
+msgstr "E111: Thiếu ']'"
+
+#, c-format
+msgid "E112: Option name missing: %s"
+msgstr "E112: Không đưa ra tên tùy chá»n: %s"
+
+#, c-format
+msgid "E113: Unknown option: %s"
+msgstr "E113: Tùy chá»n không biết: %s"
+
+#, c-format
+msgid "E114: Missing quote: %s"
+msgstr "E114: Thiếu ngoặc kép: %s"
+
+#, c-format
+msgid "E115: Missing quote: %s"
+msgstr "E115: Thiếu ngoặc kép: %s"
+
+#, c-format
+msgid "E116: Invalid arguments for function %s"
+msgstr "E116: Tham số cho hàm %s đưa ra không đúng"
+
+#, c-format
+msgid "E117: Unknown function: %s"
+msgstr "E117: Hàm số không biết: %s"
+
+#, c-format
+msgid "E118: Too many arguments for function: %s"
+msgstr "E118: Quá nhiá»u tham số cho hàm: %s"
+
+#, c-format
+msgid "E119: Not enough arguments for function: %s"
+msgstr "E119: Không đủ tham số cho hàm: %s"
+
+#, c-format
+msgid "E120: Using <SID> not in a script context: %s"
+msgstr "E120: Sử dụng <SID> ngoài script: %s"
+
+#.
+#. * 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"
+
+#, c-format
+msgid "+-%s%3ld lines: "
+msgstr "+-%s%3ld dòng: "
+
+msgid ""
+"&OK\n"
+"&Cancel"
+msgstr ""
+"&OK\n"
+"&Há»§y bá»"
+
+msgid "called inputrestore() more often than inputsave()"
+msgstr "Hàm số inputrestore() được gá»i nhiá»u hÆ¡n hàm inputsave()"
+
+msgid "E655: Too many symbolic links (cycle?)"
+msgstr "E655: Quá nhiá»u liên kết tượng trưng (vòng lặp?)"
+
+msgid "E240: No connection to Vim server"
+msgstr "E240: Không có kết nối với máy chủ Vim"
+
+msgid "E277: Unable to read a server reply"
+msgstr "E277: Máy chá»§ không trả lá»i"
+
+msgid "E258: Unable to send to client"
+msgstr "E258: Không thể trả lá»i cho máy con"
+
+#, c-format
+msgid "E241: Unable to send to %s"
+msgstr "E241: Không thể gửi tin nhắn tới %s"
+
+msgid "(Invalid)"
+msgstr "(Không đúng)"
+
+#, c-format
+msgid "E121: Undefined variable: %s"
+msgstr "E121: Biến không xác định: %s"
+
+#, c-format
+msgid "E461: Illegal variable name: %s"
+msgstr "E461: Tên biến không cho phép: %s"
+
+#, c-format
+msgid "E122: Function %s already exists, add ! to replace it"
+msgstr "E122: Hàm số %s đã có, hãy thêm ! để thay thế nó."
+
+#, c-format
+msgid "E123: Undefined function: %s"
+msgstr "E123: Hàm số không xác định: %s"
+
+#, c-format
+msgid "E124: Missing '(': %s"
+msgstr "E124: Thiếu '(': %s"
+
+#, c-format
+msgid "E125: Illegal argument: %s"
+msgstr "E125: Tham số không cho phép: %s"
+
+msgid "E126: Missing :endfunction"
+msgstr "E126: Thiếu lệnh :endfunction"
+
+#, c-format
+msgid "E127: Cannot redefine function %s: It is in use"
+msgstr "E127: Không thể định nghĩa lại hàm số %s: hàm đang được sử dụng"
+
+msgid "E129: Function name required"
+msgstr "E129: Cần tên hàm số"
+
+#, c-format
+msgid "E128: Function name must start with a capital: %s"
+msgstr "E128: Tên hàm số phải bắt đầu với một chữ cái hoa: %s"
+
+#, c-format
+msgid "E130: Undefined function: %s"
+msgstr "E130: Hàm số %s chưa xác định"
+
+#, c-format
+msgid "E131: Cannot delete function %s: It is in use"
+msgstr "E131: Không thể xóa hàm số %s: Hàm đang được sử dụng"
+
+msgid "E132: Function call depth is higher than 'maxfuncdepth'"
+msgstr "E132: Äá»™ sâu cá»§a lá»i gá»i hàm số lá»›n hÆ¡n giá trị 'maxfuncdepth'"
+
+#. always scroll up, don't overwrite
+#, c-format
+msgid "calling %s"
+msgstr "lá»i gá»i %s"
+
+#, c-format
+msgid "%s aborted"
+msgstr "%s dừng"
+
+#, c-format
+msgid "%s returning #%ld"
+msgstr "%s trả lại #%ld"
+
+#, c-format
+msgid "%s returning \"%s\""
+msgstr "%s trả lại \"%s\""
+
+#. always scroll up, don't overwrite
+#, c-format
+msgid "continuing in %s"
+msgstr "tiếp tục trong %s"
+
+msgid "E133: :return not inside a function"
+msgstr "E133: lệnh :return ở ngoài một hàm"
+
+msgid ""
+"\n"
+"# global variables:\n"
+msgstr ""
+"\n"
+"# biến toàn cầu:\n"
+
+msgid "Entering Debug mode. Type \"cont\" to continue."
+msgstr "Bật chế độ sửa lỗi (Debug). Gõ \"cont\" để tiếp tục."
+
+#, c-format
+msgid "line %ld: %s"
+msgstr "dòng %ld: %s"
+
+#, c-format
+msgid "cmd: %s"
+msgstr "câu lệnh: %s"
+
+#, c-format
+msgid "Breakpoint in \"%s%s\" line %ld"
+msgstr "Äiểm dừng trên \"%s%s\" dòng %ld"
+
+#, c-format
+msgid "E161: Breakpoint not found: %s"
+msgstr "E161: Không tìm thấy điểm dừng: %s"
+
+msgid "No breakpoints defined"
+msgstr "Äiểm dừng không được xác định"
+
+#, c-format
+msgid "%3d %s %s line %ld"
+msgstr "%3d %s %s dòng %ld"
+
+msgid "Save As"
+msgstr "Ghi nhớ như"
+
+#, c-format
+msgid "Save changes to \"%.*s\"?"
+msgstr "Ghi nhớ thay đổi vào \"%.*s\"?"
+
+msgid "Untitled"
+msgstr "Chưa đặt tên"
+
+#, c-format
+msgid "E162: No write since last change for buffer \"%s\""
+msgstr "E162: Thay đổi chưa được ghi nhớ trong bộ đệm \"%s\""
+
+msgid "Warning: Entered other buffer unexpectedly (check autocommands)"
+msgstr ""
+"Cảnh báo: Chuyển tới bộ đệm khác không theo ý muốn (hãy kiểm tra câu lệnh tự "
+"động)"
+
+msgid "E163: There is only one file to edit"
+msgstr "E163: Chỉ có một tập tin để soạn thảo"
+
+msgid "E164: Cannot go before first file"
+msgstr "E164: Äây là tập tin đầu tiên"
+
+msgid "E165: Cannot go beyond last file"
+msgstr "E165: Äây là tập tin cuối cùng"
+
+#, c-format
+msgid "E666: compiler not supported: %s"
+msgstr "E666: trình biên dịch không được hỗ trợ: %s"
+
+#, c-format
+msgid "Searching for \"%s\" in \"%s\""
+msgstr "Tìm kiếm \"%s\" trong \"%s\""
+
+#, c-format
+msgid "Searching for \"%s\""
+msgstr "Tìm kiếm \"%s\""
+
+#, c-format
+msgid "not found in 'runtimepath': \"%s\""
+msgstr "không tìm thấy trong 'runtimepath': \"%s\""
+
+msgid "Source Vim script"
+msgstr "Thực hiện script của Vim"
+
+#, c-format
+msgid "Cannot source a directory: \"%s\""
+msgstr "Không thể thực hiện một thư mục: \"%s\""
+
+#, c-format
+msgid "could not source \"%s\""
+msgstr "không thực hiện được \"%s\""
+
+#, c-format
+msgid "line %ld: could not source \"%s\""
+msgstr "dòng %ld: không thực hiện được \"%s\""
+
+#, c-format
+msgid "sourcing \"%s\""
+msgstr "thực hiện \"%s\""
+
+#, c-format
+msgid "line %ld: sourcing \"%s\""
+msgstr "dòng %ld: thực hiện \"%s\""
+
+#, c-format
+msgid "finished sourcing %s"
+msgstr "thực hiện xong %s"
+
+msgid "W15: Warning: Wrong line separator, ^M may be missing"
+msgstr "W15: Cảnh báo: Ký tự phân cách dòng không đúng. Rất có thể thiếu ^M"
+
+msgid "E167: :scriptencoding used outside of a sourced file"
+msgstr "E167: Lệnh :scriptencoding sử dụng ngoài tập tin script"
+
+msgid "E168: :finish used outside of a sourced file"
+msgstr "E168: Lệnh :finish sử dụng ngoài tập tin script"
+
+#, c-format
+msgid "Page %d"
+msgstr "Trang %d"
+
+msgid "No text to be printed"
+msgstr "Không có gì để in"
+
+#, c-format
+msgid "Printing page %d (%d%%)"
+msgstr "In trang %d (%d%%)"
+
+#, c-format
+msgid " Copy %d of %d"
+msgstr " Sao chép %d của %d"
+
+#, c-format
+msgid "Printed: %s"
+msgstr "Äã in: %s"
+
+msgid "Printing aborted"
+msgstr "In bị dừng"
+
+msgid "E455: Error writing to PostScript output file"
+msgstr "E455: Lỗi ghi nhớ vào tập tin PostScript"
+
+#, c-format
+msgid "E624: Can't open file \"%s\""
+msgstr "E624: Không thể mở tập tin \"%s\""
+
+#, c-format
+msgid "E457: Can't read PostScript resource file \"%s\""
+msgstr "E457: Không thể Ä‘á»c tập tin tài nguyên PostScript \"%s\""
+
+#, c-format
+msgid "E618: file \"%s\" is not a PostScript resource file"
+msgstr "E618: \"%s\" không phải là tập tin tài nguyên PostScript"
+
+#, c-format
+msgid "E619: file \"%s\" is not a supported PostScript resource file"
+msgstr "E619: \"%s\" không phải là tập tin tài nguyên PostScript được hỗ trợ"
+
+#, c-format
+msgid "E621: \"%s\" resource file has wrong version"
+msgstr "E621: tập tin tài nguyên \"%s\" có phiên bản không đúng"
+
+msgid "E324: Can't open PostScript output file"
+msgstr "E324: Không thể mở tập tin PostScript"
+
+#, c-format
+msgid "E456: Can't open file \"%s\""
+msgstr "E456: Không thể mở tập tin \"%s\""
+
+msgid "E456: Can't find PostScript resource file \"prolog.ps\""
+msgstr "E456: Không tìm thấy tập tin tài nguyên PostScript \"prolog.ps\""
+
+#, c-format
+msgid "E456: Can't find PostScript resource file \"%s.ps\""
+msgstr "E456: Không tìm thấy tập tin tài nguyên PostScript \"%s.ps\""
+
+#, c-format
+msgid "E620: Unable to convert from multi-byte to \"%s\" encoding"
+msgstr "E620: Không thể chuyển từ các ký tá»± nhiá»u byte thành bảng mã \"%s\""
+
+msgid "Sending to printer..."
+msgstr "Gửi tới máy in..."
+
+msgid "E365: Failed to print PostScript file"
+msgstr "E365: In tập tin PostScript không thành công"
+
+msgid "Print job sent."
+msgstr "Äã gá»­i công việc in."
+
+#, c-format
+msgid "Current %slanguage: \"%s\""
+msgstr "Ngôn ngữ %shiện thá»i: \"%s\""
+
+#, c-format
+msgid "E197: Cannot set language to \"%s\""
+msgstr "E197: Không thể thay đổi ngôn ngữ thành \"%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, 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: Di chuyển các dòng lên chính chúng"
+
+msgid "1 line moved"
+msgstr "Äã di chuyển 1 dòng"
+
+#, c-format
+msgid "%ld lines moved"
+msgstr "Äã di chuyển %ld dòng"
+
+#, c-format
+msgid "%ld lines filtered"
+msgstr "Äã lá»c %ld dòng"
+
+msgid "E135: *Filter* Autocommands must not change current buffer"
+msgstr "E135: Các lệnh tá»± động *Filter* không được thay đổi bá»™ đệm hiện thá»i"
+
+msgid "[No write since last change]\n"
+msgstr "[Thay đổi chưa được ghi nhớ]\n"
+
+#, c-format
+msgid "%sviminfo: %s in line: "
+msgstr "%sviminfo: %s trên dòng: "
+
+msgid "E136: viminfo: Too many errors, skipping rest of file"
+msgstr "E136: viminfo: Quá nhiá»u lá»—i, phần còn lại cá»§a tập tin sẽ được bá» qua"
+
+#, c-format
+msgid "Reading viminfo file \"%s\"%s%s%s"
+msgstr "Äá»c tập tin viminfo \"%s\"%s%s%s"
+
+msgid " info"
+msgstr " thông tin"
+
+msgid " marks"
+msgstr " dấu hiệu"
+
+msgid " FAILED"
+msgstr " KHÔNG THÀNH CÔNG"
+
+#, c-format
+msgid "E137: Viminfo file is not writable: %s"
+msgstr "E137: Thiếu quyá»n ghi lên tập tin viminfo: %s"
+
+#, c-format
+msgid "E138: Can't write viminfo file %s!"
+msgstr "E138: Không thể ghi tập tin viminfo %s!"
+
+#, c-format
+msgid "Writing viminfo file \"%s\""
+msgstr "Ghi tập tin viminfo \"%s\""
+
+#. Write the info:
+#, c-format
+msgid "# This viminfo file was generated by Vim %s.\n"
+msgstr "# Tập tin viminfo này được tự động tạo bởi Vim %s.\n"
+
+msgid ""
+"# You may edit it if you're careful!\n"
+"\n"
+msgstr ""
+"# Bạn có thể sá»­a tập tin này, nhưng hãy thận trá»ng!\n"
+"\n"
+
+msgid "# Value of 'encoding' when this file was written\n"
+msgstr "# Giá trị cá»§a tùy chá»n 'encoding' vào thá»i Ä‘iểm ghi tập tin\n"
+
+msgid "Illegal starting char"
+msgstr "Ký tự đầu tiên không cho phép"
+
+#. Overwriting a file that is loaded in another buffer is not a
+#. * good idea.
+msgid "E139: File is loaded in another buffer"
+msgstr "E139: Tập tin được nạp trong bộ đệm khác"
+
+msgid "Write partial file?"
+msgstr "Ghi nhớ một phần tập tin?"
+
+msgid "E140: Use ! to write partial buffer"
+msgstr "E140: Sử dụng ! để ghi nhớ một phần bộ đệm"
+
+#, c-format
+msgid "Overwrite existing file \"%.*s\"?"
+msgstr "Ghi đè lên tập tin đã có \"%.*s\"?"
+
+#, c-format
+msgid "E141: No file name for buffer %ld"
+msgstr "E141: Không có tên tập tin cho bộ đệm %ld"
+
+msgid "E142: File not written: Writing is disabled by 'write' option"
+msgstr "E142: Tập tin chưa được ghi nhá»›: Ghi nhá»› bị tắt bởi tùy chá»n 'write'"
+
+#, c-format
+msgid ""
+"'readonly' option is set for \"%.*s\".\n"
+"Do you wish to write anyway?"
+msgstr ""
+"Tùy chá»n 'readonly' được đặt cho \"%.*s\".\n"
+"Ghi nhá»› bằng má»i giá?"
+
+msgid "Edit File"
+msgstr "Soạn thảo tập tin"
+
+#, c-format
+msgid "E143: Autocommands unexpectedly deleted new buffer %s"
+msgstr "E143: Các lệnh tự động xóa bộ đệm mới ngoài ý muốn %s"
+
+msgid "E144: non-numeric argument to :z"
+msgstr "E144: Tham số của lệnh :z phải là số"
+
+msgid "E145: Shell commands not allowed in rvim"
+msgstr "E145: Không cho phép sử dụng lệnh shell trong rvim."
+
+msgid "E146: Regular expressions can't be delimited by letters"
+msgstr "E146: Không thể phân cách biểu thức chính quy bằng chữ cái"
+
+#, c-format
+msgid "replace with %s (y/n/a/q/l/^E/^Y)?"
+msgstr "thay thế bằng %s? (y/n/a/q/l/^E/^Y)"
+
+msgid "(Interrupted) "
+msgstr "(bị dừng)"
+
+msgid "1 substitution"
+msgstr "1 thay thế"
+
+#, c-format
+msgid "%ld substitutions"
+msgstr "%ld thay thế"
+
+msgid " on 1 line"
+msgstr " trên 1 dòng"
+
+#, c-format
+msgid " on %ld lines"
+msgstr " trên %ld dòng"
+
+msgid "E147: Cannot do :global recursive"
+msgstr "E147: Không thực hiện được lệnh :global đệ qui"
+
+msgid "E148: Regular expression missing from global"
+msgstr "E148: Thiếu biểu thức chính quy trong lệnh :global"
+
+#, c-format
+msgid "Pattern found in every line: %s"
+msgstr "Tìm thấy tương ứng trên má»i dòng: %s"
+
+msgid ""
+"\n"
+"# Last Substitute String:\n"
+"$"
+msgstr ""
+"\n"
+"# Chuỗi thay thế cuối cùng:\n"
+"$"
+
+msgid "E478: Don't panic!"
+msgstr "E478: Hãy bình tĩnh, đừng hoảng hốt!"
+
+#, c-format
+msgid "E661: Sorry, no '%s' help for %s"
+msgstr "E661: Rất tiếc, không có trợ giúp '%s' cho %s"
+
+#, c-format
+msgid "E149: Sorry, no help for %s"
+msgstr "E149: Rất tiếc không có trợ giúp cho %s"
+
+#, c-format
+msgid "Sorry, help file \"%s\" not found"
+msgstr "Xin lỗi, không tìm thấy tập tin trợ giúp \"%s\""
+
+#, c-format
+msgid "E150: Not a directory: %s"
+msgstr "E150: %s không phải là một thư mục"
+
+#, c-format
+msgid "E152: Cannot open %s for writing"
+msgstr "E152: Không thể mở %s để ghi"
+
+#, c-format
+msgid "E153: Unable to open %s for reading"
+msgstr "E153: Không thể mở %s để Ä‘á»c"
+
+#, c-format
+msgid "E670: Mix of help file encodings within a language: %s"
+msgstr ""
+"E670: Tập tin trợ giúp sá»­ dụng nhiá»u bảng mã khác nhau cho má»™t ngôn ngữ: %s"
+
+#, c-format
+msgid "E154: Duplicate tag \"%s\" in file %s"
+msgstr "E154: Thẻ ghi lặp lại \"%s\" trong tập tin %s"
+
+#, c-format
+msgid "E160: Unknown sign command: %s"
+msgstr "E160: Câu lệnh ký hiệu không biết: %s"
+
+msgid "E156: Missing sign name"
+msgstr "E156: Thiếu tên ký hiệu"
+
+msgid "E612: Too many signs defined"
+msgstr "E612: Äịnh nghÄ©a quá nhiá»u ký hiệu"
+
+#, c-format
+msgid "E239: Invalid sign text: %s"
+msgstr "E239: Văn bản ký hiệu không thích hợp: %s"
+
+#, c-format
+msgid "E155: Unknown sign: %s"
+msgstr "E155: Ký hiệu không biết: %s"
+
+msgid "E159: Missing sign number"
+msgstr "E159: Thiếu số của ký hiệu"
+
+#, c-format
+msgid "E158: Invalid buffer name: %s"
+msgstr "E158: Tên bộ đệm không đúng: %s"
+
+#, c-format
+msgid "E157: Invalid sign ID: %ld"
+msgstr "E157: ID của ký hiệu không đúng: %ld"
+
+msgid " (NOT FOUND)"
+msgstr " (KHÔNG TÌM THẤY)"
+
+msgid " (not supported)"
+msgstr " (không được hỗ trợ)"
+
+msgid "[Deleted]"
+msgstr "[bị xóa]"
+
+msgid "Entering Ex mode. Type \"visual\" to go to Normal mode."
+msgstr ""
+"Chuyển vào chế độ Ex. Äể chuyển vá» chế độ Thông thưá»ng hãy gõ \"visual\""
+
+#. must be at EOF
+msgid "E501: At end-of-file"
+msgstr "E501: Ở cuối tập tin"
+
+msgid "E169: Command too recursive"
+msgstr "E169: Câu lệnh quá đệ quy"
+
+#, c-format
+msgid "E605: Exception not caught: %s"
+msgstr "E605: Trưá»ng hợp đặc biệt không được xá»­ lý: %s"
+
+msgid "End of sourced file"
+msgstr "Kết thúc tập tin script"
+
+msgid "End of function"
+msgstr "Kết thúc của hàm số"
+
+msgid "E464: Ambiguous use of user-defined command"
+msgstr "E464: Sá»± sá»­ dụng không rõ ràng câu lệnh do ngưá»i dùng định nghÄ©a"
+
+msgid "E492: Not an editor command"
+msgstr "E492: Không phải là câu lệnh của trình soạn thảo"
+
+msgid "E493: Backwards range given"
+msgstr "E493: ÄÆ°a ra phạm vi ngược lại"
+
+msgid "Backwards range given, OK to swap"
+msgstr "ÄÆ°a ra phạm vi ngược lại, thay đổi vị trí hai giá»›i hạn"
+
+msgid "E494: Use w or w>>"
+msgstr "E494: Hãy sử dụng w hoặc w>>"
+
+msgid "E319: Sorry, the command is not available in this version"
+msgstr "E319: Xin lỗi, câu lệnh này không có trong phiên bản này"
+
+msgid "E172: Only one file name allowed"
+msgstr "E172: Chỉ cho phép sử dụng một tên tập tin"
+
+msgid "1 more file to edit. Quit anyway?"
+msgstr "Còn 1 tập tin nữa cần soạn thảo. Thoát?"
+
+#, c-format
+msgid "%d more files to edit. Quit anyway?"
+msgstr "Còn %d tập tin nữa chưa soạn thảo. Thoát?"
+
+msgid "E173: 1 more file to edit"
+msgstr "E173: 1 tập tin nữa chỠsoạn thảo."
+
+#, c-format
+msgid "E173: %ld more files to edit"
+msgstr "E173: %ld tập tin nữa chưa soạn thảo."
+
+msgid "E174: Command already exists: add ! to replace it"
+msgstr "E174: Äã có câu lệnh: Thêm ! để thay thế"
+
+msgid ""
+"\n"
+" Name Args Range Complete Definition"
+msgstr ""
+"\n"
+" Tên\t\tTham_số Phạm_vi Phần_phụ Äịnh_nghÄ©a"
+
+msgid "No user-defined commands found"
+msgstr "Không tìm thấy câu lệnh do ngưá»i dùng định nghÄ©a"
+
+msgid "E175: No attribute specified"
+msgstr "E175: Không có tham số được chỉ ra"
+
+msgid "E176: Invalid number of arguments"
+msgstr "E176: Số lượng tham số không đúng"
+
+msgid "E177: Count cannot be specified twice"
+msgstr "E177: Số đếm không thể được chỉ ra hai lần"
+
+msgid "E178: Invalid default value for count"
+msgstr "E178: Giá trị của số đếm theo mặc định không đúng"
+
+msgid "E179: argument required for complete"
+msgstr "E179: yêu cầu đưa ra tham số để kết thúc"
+
+#, c-format
+msgid "E180: Invalid complete value: %s"
+msgstr "E180: Giá trị phần phụ không đúng: %s"
+
+msgid "E468: Completion argument only allowed for custom completion"
+msgstr ""
+"E468: Tham số tự động kết thúc chỉ cho phép sử dụng với phần phụ đặc biệt"
+
+msgid "E467: Custom completion requires a function argument"
+msgstr "E467: Phần phục đặc biệt yêu cầu một tham số của hàm"
+
+#, c-format
+msgid "E181: Invalid attribute: %s"
+msgstr "E181: Thuộc tính không đúng: %s"
+
+msgid "E182: Invalid command name"
+msgstr "E182: Tên câu lệnh không đúng"
+
+msgid "E183: User defined commands must start with an uppercase letter"
+msgstr "E183: Câu lệnh ngưá»i dùng định nghÄ©a phải bắt đầu vá»›i má»™t ký tá»± hoa"
+
+#, c-format
+msgid "E184: No such user-defined command: %s"
+msgstr "E184: Không có câu lệnh ngưá»i dùng định nghÄ©a như vậy: %s"
+
+#, c-format
+msgid "E185: Cannot find color scheme %s"
+msgstr "E185: Không tin thấy sơ đồ màu sắc %s"
+
+msgid "Greetings, Vim user!"
+msgstr "Xin chào ngưá»i dùng Vim!"
+
+msgid "Edit File in new window"
+msgstr "Soạn thảo tập tin trong cửa sổ mới"
+
+msgid "No swap file"
+msgstr "Không có tập tin swap"
+
+msgid "Append File"
+msgstr "Thêm tập tin"
+
+msgid "E186: No previous directory"
+msgstr "E186: Không có thư mục trước"
+
+msgid "E187: Unknown"
+msgstr "E187: Không rõ"
+
+msgid "E465: :winsize requires two number arguments"
+msgstr "E465: câu lệnh :winsize yêu cầu hai tham số bằng số"
+
+#, c-format
+msgid "Window position: X %d, Y %d"
+msgstr "Vị trí cửa sổ: X %d, Y %d"
+
+msgid "E188: Obtaining window position not implemented for this platform"
+msgstr "E188: Trên hệ thống này việc xác định vị trí cửa sổ không làm việc"
+
+msgid "E466: :winpos requires two number arguments"
+msgstr "E466: câu lệnh :winpos yêu câu hai tham số bằng số"
+
+msgid "Save Redirection"
+msgstr "Chuyển hướng ghi nhớ"
+
+msgid "Save View"
+msgstr "Ghi nhớ vẻ ngoài"
+
+msgid "Save Session"
+msgstr "Ghi nhớ buổi làm việc"
+
+msgid "Save Setup"
+msgstr "Ghi nhớ cấu hình"
+
+#, c-format
+msgid "E189: \"%s\" exists (add ! to override)"
+msgstr "E189: \"%s\" đã có (thêm !, để ghi đè)"
+
+#, c-format
+msgid "E190: Cannot open \"%s\" for writing"
+msgstr "E190: Không mở được \"%s\" để ghi nhớ"
+
+#. set mark
+msgid "E191: Argument must be a letter or forward/backward quote"
+msgstr "E191: Tham số phải là một chữ cái hoặc dấu ngoặc thẳng/ngược"
+
+msgid "E192: Recursive use of :normal too deep"
+msgstr "E192: Sử dụng đệ quy lệnh :normal quá sâu"
+
+msgid "E194: No alternate file name to substitute for '#'"
+msgstr "E194: Không có tên tập tin tương đương để thay thế '#'"
+
+msgid "E495: no autocommand file name to substitute for \"<afile>\""
+msgstr "E495: Không có tên tập tin câu lệnh tự động để thay thế \"<afile>\""
+
+msgid "E496: no autocommand buffer number to substitute for \"<abuf>\""
+msgstr ""
+"E496: Không có số thứ tự bộ đệm câu lệnh tự động để thay thế \"<abuf>\""
+
+msgid "E497: no autocommand match name to substitute for \"<amatch>\""
+msgstr "E497: Không có tên tương ứng câu lệnh tự động để thay thế \"<amatch>\""
+
+msgid "E498: no :source file name to substitute for \"<sfile>\""
+msgstr "E498: không có tên tập tin :source để thay thế \"<sfile>\""
+
+#, no-c-format
+msgid "E499: Empty file name for '%' or '#', only works with \":p:h\""
+msgstr "E499: Tên tập tin rỗng cho '%' hoặc '#', chỉ làm việc với \":p:h\""
+
+msgid "E500: Evaluates to an empty string"
+msgstr "E500: Kết quả của biểu thức là một chuỗi rỗng"
+
+msgid "E195: Cannot open viminfo file for reading"
+msgstr "E195: Không thể mở tập tin viminfo để Ä‘á»c"
+
+msgid "E196: No digraphs in this version"
+msgstr "E196: Trong phiên bản này chữ ghép không được hỗ trợ"
+
+msgid "E608: Cannot :throw exceptions with 'Vim' prefix"
+msgstr ""
+"E608: Không thể thá»±c hiện lệnh :throw cho những ngoại lệ vá»›i tiá»n tố 'Vim'"
+
+#. always scroll up, don't overwrite
+#, c-format
+msgid "Exception thrown: %s"
+msgstr "Trưá»ng hợp ngoại lệ: %s"
+
+#, c-format
+msgid "Exception finished: %s"
+msgstr "Kết thúc việc xá»­ lý trưá»ng hợp ngoại lệ: %s"
+
+#, c-format
+msgid "Exception discarded: %s"
+msgstr "Trưá»ng hợp ngoại lệ bị bá» qua: %s"
+
+#, c-format
+msgid "%s, line %ld"
+msgstr "%s, dòng %ld"
+
+#. always scroll up, don't overwrite
+#, c-format
+msgid "Exception caught: %s"
+msgstr "Xá»­ lý trưá»ng hợp ngoại lệ: %s"
+
+#, c-format
+msgid "%s made pending"
+msgstr "%s thực hiện việc chỠđợi"
+
+#, c-format
+msgid "%s resumed"
+msgstr "%s được phục hồi lại"
+
+#, c-format
+msgid "%s discarded"
+msgstr "%s bị bỠqua"
+
+msgid "Exception"
+msgstr "Trưá»ng hợp ngoại lệ"
+
+msgid "Error and interrupt"
+msgstr "Lỗi và sự gián đoạn"
+
+msgid "Error"
+msgstr "Lá»—i"
+
+#. if (pending & CSTP_INTERRUPT)
+msgid "Interrupt"
+msgstr "Sự gián đoạn"
+
+msgid "E579: :if nesting too deep"
+msgstr "E579: :if xếp lồng vào nhau quá sâu"
+
+msgid "E580: :endif without :if"
+msgstr "E580: :endif không có :if"
+
+msgid "E581: :else without :if"
+msgstr "E581: :else không có :if"
+
+msgid "E582: :elseif without :if"
+msgstr "E582: :elseif không có :if"
+
+msgid "E583: multiple :else"
+msgstr "E583: phát hiện vài :else"
+
+msgid "E584: :elseif after :else"
+msgstr "E584: :elseif sau :else"
+
+msgid "E585: :while nesting too deep"
+msgstr "E585: :while xếp lồng vào nhau quá sâu"
+
+msgid "E586: :continue without :while"
+msgstr "E586: :continue không có :while"
+
+msgid "E587: :break without :while"
+msgstr "E587: :break không có :while"
+
+msgid "E601: :try nesting too deep"
+msgstr "E601: :try xếp lồng vào nhau quá sâu"
+
+msgid "E603: :catch without :try"
+msgstr "E603: :catch không có :try"
+
+#. Give up for a ":catch" after ":finally" and ignore it.
+#. * Just parse.
+msgid "E604: :catch after :finally"
+msgstr "E604: :catch đứng sau :finally"
+
+msgid "E606: :finally without :try"
+msgstr "E606: :finally không có :try"
+
+#. Give up for a multiple ":finally" and ignore it.
+msgid "E607: multiple :finally"
+msgstr "E607: phát hiện vài :finally"
+
+msgid "E602: :endtry without :try"
+msgstr "E602: :endtry không có :try"
+
+msgid "E193: :endfunction not inside a function"
+msgstr "E193: lệnh :endfunction chỉ được sử dụng trong một hàm số"
+
+msgid "tagname"
+msgstr "tên thẻ ghi"
+
+msgid " kind file\n"
+msgstr " loại tập tin\n"
+
+msgid "'history' option is zero"
+msgstr "giá trị cá»§a tùy chá»n 'history' bằng không"
+
+#, c-format
+msgid ""
+"\n"
+"# %s History (newest to oldest):\n"
+msgstr ""
+"\n"
+"# %s, Lịch sử (bắt đầu từ mới nhất tới cũ nhất):\n"
+
+msgid "Command Line"
+msgstr "Dòng lệnh"
+
+msgid "Search String"
+msgstr "Chuỗi tìm kiếm"
+
+msgid "Expression"
+msgstr "Biểu thức"
+
+msgid "Input Line"
+msgstr "Dòng nhập"
+
+msgid "E198: cmd_pchar beyond the command length"
+msgstr "E198: cmd_pchar lá»›n hÆ¡n chiá»u dài câu lệnh"
+
+msgid "E199: Active window or buffer deleted"
+msgstr "E199: Cửa sổ hoặc bộ đệm hoạt động bị xóa"
+
+msgid "Illegal file name"
+msgstr "Tên tập tin không cho phép"
+
+msgid "is a directory"
+msgstr "là một thư mục"
+
+msgid "is not a file"
+msgstr "không phải là một tập tin"
+
+msgid "[New File]"
+msgstr "[Tập tin mới]"
+
+msgid "[Permission Denied]"
+msgstr "[Truy cập bị từ chối]"
+
+msgid "E200: *ReadPre autocommands made the file unreadable"
+msgstr ""
+"E200: Câu lệnh tá»± động *ReadPre làm cho tập tin trở thành không thể Ä‘á»c"
+
+msgid "E201: *ReadPre autocommands must not change current buffer"
+msgstr "E201: Câu lệnh tự động *ReadPre không được thay đổi bộ đệm hoạt động"
+
+msgid "Vim: Reading from stdin...\n"
+msgstr "Vim: Äá»c từ đầu vào tiêu chuẩn stdin...\n"
+
+msgid "Reading from stdin..."
+msgstr "Äá»c từ đầu vào tiêu chuẩn stdin..."
+
+#. Re-opening the original file failed!
+msgid "E202: Conversion made file unreadable!"
+msgstr "E202: Sá»± biến đổi làm cho tập tin trở thành không thể Ä‘á»c!"
+
+msgid "[fifo/socket]"
+msgstr "[fifo/socket]"
+
+msgid "[fifo]"
+msgstr "[fifo]"
+
+msgid "[socket]"
+msgstr "[socket]"
+
+msgid "[RO]"
+msgstr "[Chỉ Ä‘á»c]"
+
+msgid "[CR missing]"
+msgstr "[thiếu ký tự CR]"
+
+msgid "[NL found]"
+msgstr "[tìm thấy ký tự NL]"
+
+msgid "[long lines split]"
+msgstr "[dòng dài được chia nhá»]"
+
+msgid "[NOT converted]"
+msgstr "[KHÔNG được chuyển đổi]"
+
+msgid "[converted]"
+msgstr "[đã chuyển bảng mã]"
+
+msgid "[crypted]"
+msgstr "[đã mã hóa]"
+
+msgid "[CONVERSION ERROR]"
+msgstr "[LỖI CHUYỂN BẢNG MÃ]"
+
+#, c-format
+msgid "[ILLEGAL BYTE in line %ld]"
+msgstr "[BYTE KHÔNG CHO PHÉP trên dòng %ld]"
+
+msgid "[READ ERRORS]"
+msgstr "[Lá»–I ÄỌC]"
+
+msgid "Can't find temp file for conversion"
+msgstr "Không tìm thấy tập tin tạm thá»i (temp) để chuyển bảng mã"
+
+msgid "Conversion with 'charconvert' failed"
+msgstr "Chuyển đổi nhỠ'charconvert' không được thực hiện"
+
+msgid "can't read output of 'charconvert'"
+msgstr "không Ä‘á»c được đầu ra cá»§a 'charconvert'"
+
+msgid "E203: Autocommands deleted or unloaded buffer to be written"
+msgstr "E203: Câu lệnh tự động đã xóa hoặc bỠnạp bộ đệm cần ghi nhớ"
+
+msgid "E204: Autocommand changed number of lines in unexpected way"
+msgstr "E204: Câu lệnh tự động đã thay đổ số dòng theo cách không mong muốn"
+
+msgid "NetBeans disallows writes of unmodified buffers"
+msgstr "NetBeans không cho phép ghi nhớ bộ đệm chưa có thay đổi nào"
+
+msgid "Partial writes disallowed for NetBeans buffers"
+msgstr "Ghi nhớ một phần bộ đệm NetBeans không được cho phép"
+
+msgid "is not a file or writable device"
+msgstr "không phải là một tập tin thay một thiết bị có thể ghi nhớ"
+
+msgid "is read-only (add ! to override)"
+msgstr "là tập tin chỉ Ä‘á»c (thêm ! để ghi nhá»› bằng má»i giá)"
+
+msgid "E506: Can't write to backup file (add ! to override)"
+msgstr ""
+"E506: Không thể ghi nhá»› vào tập tin lưu trữ (thêm ! để ghi nhá»› bằng má»i giá"
+
+msgid "E507: Close error for backup file (add ! to override)"
+msgstr "E507: Lỗi đóng tập tin lưu trữ (thêm ! để bỠqua việc kiểm tra lại)"
+
+msgid "E508: Can't read file for backup (add ! to override)"
+msgstr ""
+"E508: Không Ä‘á»c được tập tin lưu trữ (thêm ! để bá» qua việc kiểm tra lại)"
+
+msgid "E509: Cannot create backup file (add ! to override)"
+msgstr ""
+"E509: Không tạo được tập tin lưu trữ (thêm ! để bỠqua việc kiểm tra lại)"
+
+msgid "E510: Can't make backup file (add ! to override)"
+msgstr ""
+"E510: Không tạo được tập tin lưu trữ (thêm ! để bỠqua việc kiểm tra lại)"
+
+msgid "E460: The resource fork would be lost (add ! to override)"
+msgstr "E460: Nhánh tài nguyên sẽ bị mất (thêm ! để bỠqua việc kiểm tra lại)"
+
+msgid "E214: Can't find temp file for writing"
+msgstr "E214: Không tìm thấy tập tin tạm thá»i (temp) để ghi nhá»›"
+
+msgid "E213: Cannot convert (add ! to write without conversion)"
+msgstr ""
+"E213: Không thể chuyển đổi bảng mã (thêm ! để ghi nhớ mà không chuyển đổi)"
+
+msgid "E166: Can't open linked file for writing"
+msgstr "E166: Không thể mở tập tin liên kết để ghi nhớ"
+
+msgid "E212: Can't open file for writing"
+msgstr "E212: Không thể mở tập tin để ghi nhớ"
+
+msgid "E667: Fsync failed"
+msgstr "E667: Không thực hiện thành công hàm số fsync()"
+
+msgid "E512: Close failed"
+msgstr "E512: Thao tác đóng không thành công"
+
+msgid "E513: write error, conversion failed"
+msgstr "E513: Lỗi ghi nhớ, biến đổi không thành công"
+
+msgid "E514: write error (file system full?)"
+msgstr "E514: lỗi ghi nhớ (không còn chỗ trống?)"
+
+msgid " CONVERSION ERROR"
+msgstr " Lá»–I BIẾN Äá»”I"
+
+msgid "[Device]"
+msgstr "[Thiết bị]"
+
+msgid "[New]"
+msgstr "[Má»›i]"
+
+msgid " [a]"
+msgstr " [a]"
+
+msgid " appended"
+msgstr " đã thêm"
+
+msgid " [w]"
+msgstr " [w]"
+
+msgid " written"
+msgstr " đã ghi"
+
+msgid "E205: Patchmode: can't save original file"
+msgstr "E205: Chế độ vá lỗi (patch): không thể ghi nhớ tập tin gốc"
+
+msgid "E206: patchmode: can't touch empty original file"
+msgstr ""
+"E206: Chế độ vá lỗi (patch): không thể thay đổi tham số của tập tin gốc "
+"trống rỗng"
+
+msgid "E207: Can't delete backup file"
+msgstr "E207: Không thể xóa tập tin lưu trữ (backup)"
+
+msgid ""
+"\n"
+"WARNING: Original file may be lost or damaged\n"
+msgstr ""
+"\n"
+"CẢNH BÃO: Tập tin gốc có thể bị mất hoặc bị há»ng\n"
+
+msgid "don't quit the editor until the file is successfully written!"
+msgstr ""
+"đừng thoát khởi trình soạn thảo, khi tập tin còn chưa được ghi nhớ thành cồng"
+
+msgid "[dos]"
+msgstr "[dos]"
+
+msgid "[dos format]"
+msgstr "[định dạng dos]"
+
+msgid "[mac]"
+msgstr "[mac]"
+
+msgid "[mac format]"
+msgstr "[định dạng mac]"
+
+msgid "[unix]"
+msgstr "[unix]"
+
+msgid "[unix format]"
+msgstr "[định dạng unix]"
+
+msgid "1 line, "
+msgstr "1 dòng, "
+
+#, c-format
+msgid "%ld lines, "
+msgstr "%ld dòng, "
+
+msgid "1 character"
+msgstr "1 ký tự"
+
+#, c-format
+msgid "%ld characters"
+msgstr "%ld ký tự"
+
+msgid "[noeol]"
+msgstr "[noeol]"
+
+msgid "[Incomplete last line]"
+msgstr "[Dòng cuối cùng không đầy đủ]"
+
+#. 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 "CẢNH BÃO: Tập tin đã thay đổi so vá»›i thá»i Ä‘iểm Ä‘á»c!!!"
+
+msgid "Do you really want to write to it"
+msgstr "Bạn có chắc muốn ghi nhớ vào tập tin này"
+
+#, c-format
+msgid "E208: Error writing to \"%s\""
+msgstr "E208: Lỗi ghi nhớ vào \"%s\""
+
+#, c-format
+msgid "E209: Error closing \"%s\""
+msgstr "E209: Lỗi đóng \"%s\""
+
+#, c-format
+msgid "E210: Error reading \"%s\""
+msgstr "E210: Lá»—i Ä‘á»c \"%s\""
+
+msgid "E246: FileChangedShell autocommand deleted buffer"
+msgstr "E246: Bộ đệm bị xóa khi thực hiện câu lệnh tự động FileChangedShell"
+
+#, c-format
+msgid "E211: Warning: File \"%s\" no longer available"
+msgstr "E211: Cảnh báo: Tập tin \"%s\" không còn truy cập được nữa"
+
+#, c-format
+msgid ""
+"W12: Warning: File \"%s\" has changed and the buffer was changed in Vim as "
+"well"
+msgstr ""
+"W12: Cảnh báo: Tập tin \"%s\" và bộ đệm Vim đã thay đổi không phụ thuộc vào "
+"nhau"
+
+#, c-format
+msgid "W11: Warning: File \"%s\" has changed since editing started"
+msgstr ""
+"W11: Cảnh báo: Tập tin \"%s\" đã thay đổi sau khi việc soạn thảo bắt đầu"
+
+#, c-format
+msgid "W16: Warning: Mode of file \"%s\" has changed since editing started"
+msgstr ""
+"W16: Cảnh báo: chế độ truy cập tới tập tin \"%s\" đã thay đổi sau khi bắt "
+"đầu soạn thảo"
+
+#, c-format
+msgid "W13: Warning: File \"%s\" has been created after editing started"
+msgstr ""
+"W13: Cảnh báo: tập tin \"%s\" được tạo ra sau khi việc soạn thảo bắt đầu"
+
+msgid "See \":help W11\" for more info."
+msgstr "Hãy xem thông tin chi tiết trong \":help W11\"."
+
+msgid "Warning"
+msgstr "Cảnh báo"
+
+msgid ""
+"&OK\n"
+"&Load File"
+msgstr ""
+"&OK\n"
+"&Nạp tập tin"
+
+#, c-format
+msgid "E462: Could not prepare for reloading \"%s\""
+msgstr "E462: Không thể chuẩn bị để nạp lại \"%s\""
+
+#, c-format
+msgid "E321: Could not reload \"%s\""
+msgstr "E321: Không thể nạp lại \"%s\""
+
+msgid "--Deleted--"
+msgstr "--Bị xóa--"
+
+#. the group doesn't exist
+#, c-format
+msgid "E367: No such group: \"%s\""
+msgstr "E367: Nhóm \"%s\" không tồn tại"
+
+#, c-format
+msgid "E215: Illegal character after *: %s"
+msgstr "E215: Ký tự không cho phép sau *: %s"
+
+#, c-format
+msgid "E216: No such event: %s"
+msgstr "E216: Sự kiện không có thật: %s"
+
+#, c-format
+msgid "E216: No such group or event: %s"
+msgstr "E216: Nhóm hoặc sự kiện không có thật: %s"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Auto-Commands ---"
+msgstr ""
+"\n"
+"--- Câu lệnh tự động ---"
+
+msgid "E217: Can't execute autocommands for ALL events"
+msgstr "E217: Không thể thực hiện câu lệnh tự động cho MỌI sự kiện"
+
+msgid "No matching autocommands"
+msgstr "Không có câu lệnh tự động tương ứng"
+
+msgid "E218: autocommand nesting too deep"
+msgstr "E218: câu lệnh tự động xếp lồng vào nhau quá xâu"
+
+#, c-format
+msgid "%s Auto commands for \"%s\""
+msgstr "%s câu lệnh tự động cho \"%s\""
+
+#, c-format
+msgid "Executing %s"
+msgstr "Thực hiện %s"
+
+#. always scroll up, don't overwrite
+#, c-format
+msgid "autocommand %s"
+msgstr "câu lệnh tự động %s"
+
+msgid "E219: Missing {."
+msgstr "E219: Thiếu {."
+
+msgid "E220: Missing }."
+msgstr "E220: Thiếu }."
+
+msgid "E490: No fold found"
+msgstr "E490: Không tìm thấy nếp gấp"
+
+msgid "E350: Cannot create fold with current 'foldmethod'"
+msgstr ""
+"E350: Không thể tạo nếp gấp vá»›i giá trị hiện thá»i cá»§a tùy chá»n 'foldmethod'"
+
+msgid "E351: Cannot delete fold with current 'foldmethod'"
+msgstr ""
+"E351: Không thể xóa nếp gấp vá»›i giá trị hiện thá»i cá»§a tùy chá»n 'foldmethod'"
+
+msgid "E222: Add to read buffer"
+msgstr "E222: Thêm vào bá»™ đệm Ä‘ang Ä‘á»c"
+
+msgid "E223: recursive mapping"
+msgstr "E223: ánh xạ đệ quy"
+
+#, c-format
+msgid "E224: global abbreviation already exists for %s"
+msgstr "E224: đã có sự viết tắt toàn cầu cho %s"
+
+#, c-format
+msgid "E225: global mapping already exists for %s"
+msgstr "E225: đã có ánh xạ toàn cầu cho %s"
+
+#, c-format
+msgid "E226: abbreviation already exists for %s"
+msgstr "E226: đã có sự viết tắt cho %s"
+
+#, c-format
+msgid "E227: mapping already exists for %s"
+msgstr "E227: đã có ánh xạ cho %s"
+
+msgid "No abbreviation found"
+msgstr "Không tìm thấy viết tắt"
+
+msgid "No mapping found"
+msgstr "Không tìm thấy ánh xạ"
+
+msgid "E228: makemap: Illegal mode"
+msgstr "E228: makemap: Chế độ không cho phép"
+
+msgid "<cannot open> "
+msgstr "<không thể mở> "
+
+#, c-format
+msgid "E616: vim_SelFile: can't get font %s"
+msgstr "E616: vim_SelFile: không tìm thấy phông chữ %s"
+
+msgid "E614: vim_SelFile: can't return to current directory"
+msgstr "E614: vim_SelFile: không trở lại được thư mục hiện thá»i"
+
+msgid "Pathname:"
+msgstr "ÄÆ°á»ng dẫn tá»›i tập tin:"
+
+msgid "E615: vim_SelFile: can't get current directory"
+msgstr "E615: vim_SelFile: không tìm thấy thư mục hiện thá»i"
+
+msgid "OK"
+msgstr "Äồng ý"
+
+msgid "Cancel"
+msgstr "Há»§y bá»"
+
+msgid "Vim dialog"
+msgstr "Hộp thoại Vim"
+
+msgid "Scrollbar Widget: Could not get geometry of thumb pixmap."
+msgstr "Thanh cuá»™n: Không thể xác định hình há»c cá»§a thanh cuá»™n."
+
+msgid "E232: Cannot create BalloonEval with both message and callback"
+msgstr "E232: Không tạo được BalloonEval vá»›i cả thông báo và lá»i gá»i ngược lại"
+
+msgid "E229: Cannot start the GUI"
+msgstr "E229: Không chạy được giao diện đồ há»a GUI"
+
+#, c-format
+msgid "E230: Cannot read from \"%s\""
+msgstr "E230: Không Ä‘á»c được từ \"%s\""
+
+msgid "E665: Cannot start GUI, no valid font found"
+msgstr ""
+"E665: Không chạy được giao diện đồ há»a GUI, đưa ra phông chữ không đúng"
+
+msgid "E231: 'guifontwide' invalid"
+msgstr "E231: 'guifontwide' có giá trị không đúng"
+
+msgid "E599: Value of 'imactivatekey' is invalid"
+msgstr "E599: Giá trị của 'imactivatekey' không đúng"
+
+#, c-format
+msgid "E254: Cannot allocate color %s"
+msgstr "E254: Không chỉ định được màu %s"
+
+msgid "Vim dialog..."
+msgstr "Hộp thoại Vim..."
+
+msgid ""
+"&Yes\n"
+"&No\n"
+"&Cancel"
+msgstr ""
+"&Có\n"
+"&Không\n"
+"&Dừng"
+
+msgid "Input _Methods"
+msgstr "Phương pháp _nhập liệu"
+
+msgid "VIM - Search and Replace..."
+msgstr "VIM - Tìm kiếm và thay thế..."
+
+msgid "VIM - Search..."
+msgstr "VIM - Tìm kiếm..."
+
+msgid "Find what:"
+msgstr "Tìm kiếm gì:"
+
+msgid "Replace with:"
+msgstr "Thay thế bởi:"
+
+#. whole word only button
+msgid "Match whole word only"
+msgstr "Chỉ tìm tương ứng hoàn toàn với từ"
+
+#. match case button
+msgid "Match case"
+msgstr "Có tính kiểu chữ"
+
+msgid "Direction"
+msgstr "Hướng"
+
+#. 'Up' and 'Down' buttons
+msgid "Up"
+msgstr "Lên"
+
+msgid "Down"
+msgstr "Xuống"
+
+msgid "Find Next"
+msgstr "Tìm tiếp"
+
+msgid "Replace"
+msgstr "Thay thế"
+
+msgid "Replace All"
+msgstr "Thay thế tất cả"
+
+msgid "Vim: Received \"die\" request from session manager\n"
+msgstr "Vim: Nhận được yêu cầu \"chết\" (dừng) từ trình quản lý màn hình\n"
+
+msgid "Vim: Main window unexpectedly destroyed\n"
+msgstr "Vim: Cửa sổ chính đã bị đóng đột ngột\n"
+
+msgid "Font Selection"
+msgstr "Chá»n phông chữ"
+
+msgid "Used CUT_BUFFER0 instead of empty selection"
+msgstr "Sá»­ dụng CUT_BUFFER0 thay cho lá»±a chá»n trống rá»—ng"
+
+msgid "Filter"
+msgstr "Äầu lá»c"
+
+msgid "Directories"
+msgstr "Thư mục"
+
+msgid "Help"
+msgstr "Trợ giúp"
+
+msgid "Files"
+msgstr "Tập tin"
+
+msgid "Selection"
+msgstr "Lá»±a chá»n"
+
+msgid "Undo"
+msgstr "Hủy thao tác"
+
+#, c-format
+msgid "E671: Cannot find window title \"%s\""
+msgstr "E671: Không tìm được tiêu đỠcửa sổ \"%s\""
+
+#, c-format
+msgid "E243: Argument not supported: \"-%s\"; Use the OLE version."
+msgstr "E243: Tham số không được hỗ trợ: \"-%s\"; Hãy sử dụng phiên bản OLE."
+
+msgid "E672: Unable to open window inside MDI application"
+msgstr "E672: Không mở được cửa sổ bên trong ứng dụng MDI"
+
+msgid "Find string (use '\\\\' to find a '\\')"
+msgstr "Tìm kiếm chuỗi (hãy sử dụng '\\\\' để tìm kiếm dấu '\\')"
+
+msgid "Find & Replace (use '\\\\' to find a '\\')"
+msgstr "Tìm kiếm và Thay thế (hãy sử dụng '\\\\' để tìm kiếm dấu '\\')"
+
+msgid "Vim E458: Cannot allocate colormap entry, some colors may be incorrect"
+msgstr ""
+"Vim E458: Không chỉ định được bản ghi trong bảng màu, một vài màu có thể "
+"hiển thị không chính xác"
+
+#, c-format
+msgid "E250: Fonts for the following charsets are missing in fontset %s:"
+msgstr "E250: Trong bộ phông chữ %s thiếu phông cho các bảng mã sau:"
+
+#, c-format
+msgid "E252: Fontset name: %s"
+msgstr "E252: Bộ phông chữ: %s"
+
+#, c-format
+msgid "Font '%s' is not fixed-width"
+msgstr "Phông chữ '%s' không phải là phông có độ rộng cố định (fixed-width)"
+
+#, c-format
+msgid "E253: Fontset name: %s\n"
+msgstr "E253: Bộ phông chữ: %s\n"
+
+#, c-format
+msgid "Font0: %s\n"
+msgstr "Font0: %s\n"
+
+#, c-format
+msgid "Font1: %s\n"
+msgstr "Font1: %s\n"
+
+#, c-format
+msgid "Font%ld width is not twice that of font0\n"
+msgstr ""
+"Chiá»u rá»™ng phông chữ font%ld phải lá»›n hÆ¡n hai lần so vá»›i chiá»u rá»™ng font0\n"
+
+#, c-format
+msgid "Font0 width: %ld\n"
+msgstr "Chiá»u rá»™ng font0: %ld\n"
+
+#, c-format
+msgid ""
+"Font1 width: %ld\n"
+"\n"
+msgstr ""
+"Chiá»u rá»™ng font1: %ld\n"
+"\n"
+
+msgid "E256: Hangul automata ERROR"
+msgstr "E256: LỖI máy tự động Hangual (tiếng Hàn)"
+
+msgid "Add a new database"
+msgstr "Thêm một cơ sở dữ liệu mới"
+
+msgid "Query for a pattern"
+msgstr "Yêu cầu theo một mẫu"
+
+msgid "Show this message"
+msgstr "Hiển thị thông báo này"
+
+msgid "Kill a connection"
+msgstr "Hủy kết nối"
+
+msgid "Reinit all connections"
+msgstr "Khởi đầu lại tất cả các kết nối"
+
+msgid "Show connections"
+msgstr "Hiển thị kết nối"
+
+#, c-format
+msgid "E560: Usage: cs[cope] %s"
+msgstr "E560: Sử dụng: cs[cope] %s"
+
+msgid "This cscope command does not support splitting the window.\n"
+msgstr "Câu lệnh cscope này không hỗ trợ việc chia (split) cửa sổ.\n"
+
+msgid "E562: Usage: cstag <ident>"
+msgstr "E562: Sử dụng: cstag <tên>"
+
+msgid "E257: cstag: tag not found"
+msgstr "E257: cstag: không tìm thấy thẻ ghi"
+
+#, c-format
+msgid "E563: stat(%s) error: %d"
+msgstr "E563: lá»—i stat(%s): %d"
+
+msgid "E563: stat error"
+msgstr "E563: lá»—i stat"
+
+#, c-format
+msgid "E564: %s is not a directory or a valid cscope database"
+msgstr ""
+"E564: %s không phải là một thư mục hoặc một cơ sở dữ liệu cscope thích hợp"
+
+#, c-format
+msgid "Added cscope database %s"
+msgstr "Äã thêm cÆ¡ sở dữ liệu cscope %s"
+
+#, c-format
+msgid "E262: error reading cscope connection %ld"
+msgstr "E262: lỗi lấy thông tin từ kết nối cscope %ld"
+
+msgid "E561: unknown cscope search type"
+msgstr "E561: không rõ loại tìm kiếm cscope"
+
+msgid "E566: Could not create cscope pipes"
+msgstr "E566: Không tạo được đưá»ng ống (pipe) cho cscope"
+
+msgid "E622: Could not fork for cscope"
+msgstr "E622: Không thực hiện được fork() cho cscope"
+
+msgid "cs_create_connection exec failed"
+msgstr "thực hiện cs_create_connection không thành công"
+
+msgid "E623: Could not spawn cscope process"
+msgstr "E623: Chạy tiến trình cscope không thành công"
+
+msgid "cs_create_connection: fdopen for to_fp failed"
+msgstr "cs_create_connection: thực hiện fdopen cho to_fp không thành công"
+
+msgid "cs_create_connection: fdopen for fr_fp failed"
+msgstr "cs_create_connection: thực hiện fdopen cho fr_fp không thành công"
+
+msgid "E567: no cscope connections"
+msgstr "E567: không có kết nối với cscope"
+
+#, c-format
+msgid "E259: no matches found for cscope query %s of %s"
+msgstr "E259: không tìm thấy tương ứng với yêu cầu cscope %s cho %s"
+
+#, c-format
+msgid "E469: invalid cscopequickfix flag %c for %c"
+msgstr "E469: cỠcscopequickfix %c cho %c không chính xác"
+
+msgid "cscope commands:\n"
+msgstr "các lệnh cscope:\n"
+
+#, c-format
+msgid "%-5s: %-30s (Usage: %s)"
+msgstr "%-5s: %-30s (Sử dụng: %s)"
+
+#, c-format
+msgid "E625: cannot open cscope database: %s"
+msgstr "E625: không mở được cơ sở dữ liệu cscope: %s"
+
+msgid "E626: cannot get cscope database information"
+msgstr "E626: không lấy được thông tin vỠcơ sở dữ liệu cscope"
+
+msgid "E568: duplicate cscope database not added"
+msgstr "E568: cơ sở dữ liệu này của cscope đã được gắn vào từ trước"
+
+msgid "E569: maximum number of cscope connections reached"
+msgstr "E569: đã đạt tới số kết nối lớn nhất cho phép với cscope"
+
+#, c-format
+msgid "E261: cscope connection %s not found"
+msgstr "E261: kết nối với cscope %s không được tìm thấy"
+
+#, c-format
+msgid "cscope connection %s closed"
+msgstr "kết nối %s với cscope đã bị đóng"
+
+#. should not reach here
+msgid "E570: fatal error in cs_manage_matches"
+msgstr "E570: lỗi nặng trong cs_manage_matches"
+
+#, c-format
+msgid "Cscope tag: %s"
+msgstr "Thẻ ghi cscope: %s"
+
+msgid ""
+"\n"
+" # line"
+msgstr ""
+"\n"
+" # dòng"
+
+msgid "filename / context / line\n"
+msgstr "tên tập tin / nội dung / dòng\n"
+
+#, c-format
+msgid "E609: Cscope error: %s"
+msgstr "E609: Lá»—i cscope: %s"
+
+msgid "All cscope databases reset"
+msgstr "Khởi động lại tất cả cơ sở dữ liệu cscope"
+
+msgid "no cscope connections\n"
+msgstr "không có kết nối với cscope\n"
+
+msgid " # pid database name prepend path\n"
+msgstr " # pid tên cÆ¡ sở dữ liệu đưá»ng dẫn ban đầu\n"
+
+msgid ""
+"E263: Sorry, this command is disabled, the Python library could not be "
+"loaded."
+msgstr ""
+"E263: Rất tiếc câu lệnh này không làm việc, vì thư viện Python chưa được nạp."
+
+msgid "E659: Cannot invoke Python recursively"
+msgstr "E659: Không thể gá»i Python má»™t cách đệ quy"
+
+msgid "can't delete OutputObject attributes"
+msgstr "Không xóa được thuộc tính OutputObject"
+
+msgid "softspace must be an integer"
+msgstr "giá trị softspace phải là một số nguyên"
+
+msgid "invalid attribute"
+msgstr "thuộc tính không đúng"
+
+msgid "writelines() requires list of strings"
+msgstr "writelines() yêu cầu một danh sách các chuỗi"
+
+msgid "E264: Python: Error initialising I/O objects"
+msgstr "E264: Python: Lỗi khi bắt đầu sử dụng vật thể I/O"
+
+msgid "invalid expression"
+msgstr "biểu thức không đúng"
+
+msgid "expressions disabled at compile time"
+msgstr "biểu thức bị tắt khi biên dịch"
+
+msgid "attempt to refer to deleted buffer"
+msgstr "cố chỉ đến bộ đệm đã bị xóa"
+
+msgid "line number out of range"
+msgstr "số thứ tự của dòng vượt quá giới hạn"
+
+#, c-format
+msgid "<buffer object (deleted) at %8lX>"
+msgstr "<vật thể của bộ đệm (bị xóa) tại %8lX>"
+
+msgid "invalid mark name"
+msgstr "tên dấu hiệu không đúng"
+
+msgid "no such buffer"
+msgstr "không có bộ đệm như vậy"
+
+msgid "attempt to refer to deleted window"
+msgstr "cố chỉ đến cửa sổ đã bị đóng"
+
+msgid "readonly attribute"
+msgstr "thuá»™c tính chỉ Ä‘á»c"
+
+msgid "cursor position outside buffer"
+msgstr "vị trí con trỠnằm ngoài bộ đệm"
+
+#, c-format
+msgid "<window object (deleted) at %.8lX>"
+msgstr "<vật thể của cửa sổ (bị xóa) tại %.8lX>"
+
+#, c-format
+msgid "<window object (unknown) at %.8lX>"
+msgstr "<vật thể của cửa sổ (không rõ) tại %.8lX>"
+
+#, c-format
+msgid "<window %d>"
+msgstr "<cửa sổ %d>"
+
+msgid "no such window"
+msgstr "không có cửa sổ như vậy"
+
+msgid "cannot save undo information"
+msgstr "không ghi được thông tin vỠviệc hủy thao tác"
+
+msgid "cannot delete line"
+msgstr "không xóa được dòng"
+
+msgid "cannot replace line"
+msgstr "không thay thế được dòng"
+
+msgid "cannot insert line"
+msgstr "không chèn được dòng"
+
+msgid "string cannot contain newlines"
+msgstr "chuỗi không thể chứa ký tự dòng mới"
+
+msgid ""
+"E266: Sorry, this command is disabled, the Ruby library could not be loaded."
+msgstr ""
+"E266: Rất tiếc câu lệnh này không làm việc, vì thư viện Ruby chưa đượcnạp."
+
+#, c-format
+msgid "E273: unknown longjmp status %d"
+msgstr "E273: không rõ trạng thái của longjmp %d"
+
+msgid "Toggle implementation/definition"
+msgstr "Bật tắt giữa thi hành/định nghĩa"
+
+msgid "Show base class of"
+msgstr "Hiển thị hạng cơ bản của"
+
+msgid "Show overridden member function"
+msgstr "Hiển thị hàm số bị nạp đè lên"
+
+msgid "Retrieve from file"
+msgstr "Nhận từ tập tin"
+
+msgid "Retrieve from project"
+msgstr "Nhận từ dự án"
+
+msgid "Retrieve from all projects"
+msgstr "Nhận từ tất cả các dự án"
+
+msgid "Retrieve"
+msgstr "Nhận"
+
+msgid "Show source of"
+msgstr "Hiển thị mã nguồn"
+
+msgid "Find symbol"
+msgstr "Tìm ký hiệu"
+
+msgid "Browse class"
+msgstr "Duyệt hạng"
+
+msgid "Show class in hierarchy"
+msgstr "Hiển thị hạng trong hệ thống cấp bậc"
+
+msgid "Show class in restricted hierarchy"
+msgstr "Hiển thị hạng trong hệ thống cấp bậc giới hạn"
+
+msgid "Xref refers to"
+msgstr "Xref chỉ đến"
+
+msgid "Xref referred by"
+msgstr "Liên kết đến xref từ"
+
+msgid "Xref has a"
+msgstr "Xref có một"
+
+msgid "Xref used by"
+msgstr "Xref được sử dụng bởi"
+
+msgid "Show docu of"
+msgstr "Hiển thị docu của"
+
+msgid "Generate docu for"
+msgstr "Tạo docu cho"
+
+msgid ""
+"Cannot connect to SNiFF+. Check environment (sniffemacs must be found in "
+"$PATH).\n"
+msgstr ""
+"Không kết nối được tá»›i SNiFF+. Hãy kiểm tra cấu hình môi trưá»ng.(sniffemacs "
+"phải được chỉ ra trong biến $PATH).\n"
+
+msgid "E274: Sniff: Error during read. Disconnected"
+msgstr "E274: Sniff: Lá»—i trong thá»i gian Ä‘á»c. Ngắt kết nối"
+
+msgid "SNiFF+ is currently "
+msgstr "Trong thá»i Ä‘iểm hiện nay SNiFF+ "
+
+msgid "not "
+msgstr "không "
+
+msgid "connected"
+msgstr "được kết nối"
+
+#, c-format
+msgid "E275: Unknown SNiFF+ request: %s"
+msgstr "E275: không rõ yêu cầu của SNiFF+: %s"
+
+msgid "E276: Error connecting to SNiFF+"
+msgstr "E276: Lỗi kết nối với SNiFF+"
+
+msgid "E278: SNiFF+ not connected"
+msgstr "E278: SNiFF+ chưa được kết nối"
+
+msgid "E279: Not a SNiFF+ buffer"
+msgstr "E279: Äây không phải là bá»™ đệm SNiFF+"
+
+msgid "Sniff: Error during write. Disconnected"
+msgstr "Sniff: Lá»—i trong thá»i gian ghi nhá»›. Ngắt kết nối"
+
+msgid "invalid buffer number"
+msgstr "số của bộ đệm không đúng"
+
+msgid "not implemented yet"
+msgstr "tạm thá»i chưa được thá»±c thi"
+
+msgid "unknown option"
+msgstr "tùy chá»n không rõ"
+
+#. ???
+msgid "cannot set line(s)"
+msgstr "không thể đặt (các) dòng"
+
+msgid "mark not set"
+msgstr "dấu hiệu chưa được đặt"
+
+#, c-format
+msgid "row %d column %d"
+msgstr "hàng %d cột %d"
+
+msgid "cannot insert/append line"
+msgstr "không thể chèn hoặc thêm dòng"
+
+msgid "unknown flag: "
+msgstr "cỠkhông biết: "
+
+msgid "unknown vimOption"
+msgstr "không rõ tùy chá»n vimOption"
+
+msgid "keyboard interrupt"
+msgstr "sự gián đoạn của bàn phím"
+
+msgid "vim error"
+msgstr "lá»—i cá»§a vim"
+
+msgid "cannot create buffer/window command: object is being deleted"
+msgstr "không tạo được câu lệnh của bộ đệm hay của cửa sổ: vật thể đang bị xóa"
+
+msgid ""
+"cannot register callback command: buffer/window is already being deleted"
+msgstr "không đăng ký được câu lệnh gá»i ngược: bá»™ đệm hoặc cá»­a sổ Ä‘ang bị xóa"
+
+#. This should never happen. Famous last word?
+msgid ""
+"E280: TCL FATAL ERROR: reflist corrupt!? Please report this to vim-dev@vim."
+"org"
+msgstr ""
+"E280: Lá»–I NẶNG CỦA TCL: bị há»ng danh sách liên kết!? Hãy thông báo việc "
+"nàyđến danh sách thư (mailing list) vim-dev@vim.org"
+
+msgid "cannot register callback command: buffer/window reference not found"
+msgstr ""
+"không đăng ký được câu lệnh gá»i ngược: không tìm thấy liên kết đến bá»™ đệm "
+"hoặc cửa sổ"
+
+msgid ""
+"E571: Sorry, this command is disabled: the Tcl library could not be loaded."
+msgstr ""
+"E571: Rất tiếc là câu lệnh này không làm việc, vì thư viện Tcl chưa được nạp"
+
+msgid ""
+"E281: TCL ERROR: exit code is not int!? Please report this to vim-dev@vim.org"
+msgstr ""
+"E281: Lá»–I TCL: mã thoát ra không phải là má»™t số nguyên!? Hãy thông báo Ä‘iá»u "
+"này đến danh sách thư (mailing list) vim-dev@vim.org"
+
+msgid "cannot get line"
+msgstr "không nhận được dòng"
+
+msgid "Unable to register a command server name"
+msgstr "Không đăng ký được một tên cho máy chủ câu lệnh"
+
+msgid "E248: Failed to send command to the destination program"
+msgstr "E248: Gửi câu lệnh vào chương trình khác không thành công"
+
+#, c-format
+msgid "E573: Invalid server id used: %s"
+msgstr "E573: Sử dụng id máy chủ không đúng: %s"
+
+msgid "E251: VIM instance registry property is badly formed. Deleted!"
+msgstr "E251: Thuộc tính đăng ký của Vim được định dạng không đúng. Xóa!"
+
+msgid "Unknown option"
+msgstr "Tùy chá»n không biết"
+
+msgid "Too many edit arguments"
+msgstr "Có quá nhiá»u tham số soạn thảo"
+
+msgid "Argument missing after"
+msgstr "Thiếu tham số sau"
+
+msgid "Garbage after option"
+msgstr "Rác sau tùy chá»n"
+
+msgid "Too many \"+command\", \"-c command\" or \"--cmd command\" arguments"
+msgstr ""
+"Quá nhiá»u tham số \"+câu lệnh\", \"-c câu lệnh\" hoặc \"--cmd câu lệnh\""
+
+msgid "Invalid argument for"
+msgstr "Tham số không được phép cho"
+
+msgid "This Vim was not compiled with the diff feature."
+msgstr "Vim không được biên dịch với tính năng hỗ trợ xem khác biệt (diff)."
+
+msgid "Attempt to open script file again: \""
+msgstr "Thử mở tập tin script một lần nữa: \""
+
+msgid "Cannot open for reading: \""
+msgstr "Không mở để Ä‘á»c được: \""
+
+msgid "Cannot open for script output: \""
+msgstr "Không mở cho đầu ra script được: \""
+
+#, c-format
+msgid "%d files to edit\n"
+msgstr "%d tập tin để soạn thảo\n"
+
+msgid "Vim: Warning: Output is not to a terminal\n"
+msgstr "Vim: Cảnh báo: Äầu ra không hướng tá»›i má»™t terminal\n"
+
+msgid "Vim: Warning: Input is not from a terminal\n"
+msgstr "Vim: Cảnh báo: Äầu vào không phải đến từ má»™t terminal\n"
+
+#. just in case..
+msgid "pre-vimrc command line"
+msgstr "dòng lệnh chạy trước khi thực hiện vimrc"
+
+#, c-format
+msgid "E282: Cannot read from \"%s\""
+msgstr "E282: Không Ä‘á»c được từ \"%s\""
+
+msgid ""
+"\n"
+"More info with: \"vim -h\"\n"
+msgstr ""
+"\n"
+"Xem thông tin chi tiết với: \"vim -h\"\n"
+
+msgid "[file ..] edit specified file(s)"
+msgstr "[tập tin ..] soạn thảo (các) tập tin chỉ ra"
+
+msgid "- read text from stdin"
+msgstr "- Ä‘á»c văn bản từ đầu vào stdin"
+
+msgid "-t tag edit file where tag is defined"
+msgstr "-t thẻ ghi soạn thảo tập tin từ chỗ thẻ ghi chỉ ra"
+
+msgid "-q [errorfile] edit file with first error"
+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:"
+msgstr ""
+"\n"
+"\n"
+"Sử dụng:"
+
+msgid " vim [arguments] "
+msgstr " vim [các tham số] "
+
+msgid ""
+"\n"
+" or:"
+msgstr ""
+"\n"
+" hoặc:"
+
+msgid ""
+"\n"
+"\n"
+"Arguments:\n"
+msgstr ""
+"\n"
+"\n"
+"Tham số:\n"
+
+msgid "--\t\t\tOnly file names after this"
+msgstr "--\t\t\tSau tham số chỉ đưa ra tên tập tin"
+
+msgid "--literal\t\tDon't expand wildcards"
+msgstr "--literal\t\tKhông thực hiện việc mở rộng wildcard"
+
+msgid "-register\t\tRegister this gvim for OLE"
+msgstr "-register\t\tÄăng ký gvim này cho OLE"
+
+msgid "-unregister\t\tUnregister gvim for OLE"
+msgstr "-unregister\t\tBỠđăng ký gvim này cho OLE"
+
+msgid "-g\t\t\tRun using GUI (like \"gvim\")"
+msgstr "-g\t\t\tSá»­ dụng giao diện đồ há»a GUI (giống \"gvim\")"
+
+msgid "-f or --nofork\tForeground: Don't fork when starting GUI"
+msgstr ""
+"-f hoặc --nofork\tTrong chương trình hoạt động: Không thực hiện fork khi "
+"chạy GUI"
+
+msgid "-v\t\t\tVi mode (like \"vi\")"
+msgstr "-v\t\t\tChế độ Vi (giống \"vi\")"
+
+msgid "-e\t\t\tEx mode (like \"ex\")"
+msgstr "-e\t\t\tChế độ Ex (giống \"ex\")"
+
+msgid "-s\t\t\tSilent (batch) mode (only for \"ex\")"
+msgstr "-s\t\t\tChế độ ít đưa thông báo (gói) (chỉ dành cho \"ex\")"
+
+msgid "-d\t\t\tDiff mode (like \"vimdiff\")"
+msgstr "-d\t\t\tChế độ khác biệt, diff (giống \"vimdiff\")"
+
+msgid "-y\t\t\tEasy mode (like \"evim\", modeless)"
+msgstr "-y\t\t\tChế độ đơn giản (giống \"evim\", không có chế độ)"
+
+msgid "-R\t\t\tReadonly mode (like \"view\")"
+msgstr "-R\t\t\tChế độ chỉ Ä‘á»c (giống \"view\")"
+
+msgid "-Z\t\t\tRestricted mode (like \"rvim\")"
+msgstr "-Z\t\t\tChế độ hạn chế (giống \"rvim\")"
+
+msgid "-m\t\t\tModifications (writing files) not allowed"
+msgstr "-m\t\t\tKhông có khả năng ghi nhớ thay đổi (ghi nhớ tập tin)"
+
+msgid "-M\t\t\tModifications in text not allowed"
+msgstr "-M\t\t\tKhông có khả năng thay đổi văn bản"
+
+msgid "-b\t\t\tBinary mode"
+msgstr "-b\t\t\tChế độ nhị phân (binary)"
+
+msgid "-l\t\t\tLisp mode"
+msgstr "-l\t\t\tChế độ Lisp"
+
+msgid "-C\t\t\tCompatible with Vi: 'compatible'"
+msgstr "-C\t\t\tChế độ tương thích với Vi: 'compatible'"
+
+msgid "-N\t\t\tNot fully Vi compatible: 'nocompatible'"
+msgstr "-N\t\t\tChế độ không tương thích hoàn toàn với Vi: 'nocompatible'"
+
+msgid "-V[N]\t\tVerbose level"
+msgstr "-V[N]\t\tMức độ chi tiết của thông báo"
+
+msgid "-D\t\t\tDebugging mode"
+msgstr "-D\t\t\tChế độ sửa lỗi (debug)"
+
+msgid "-n\t\t\tNo swap file, use memory only"
+msgstr "-n\t\t\tKhông sử dụng tập tin swap, chỉ sử dụng bộ nhớ"
+
+msgid "-r\t\t\tList swap files and exit"
+msgstr "-r\t\t\tLiệt kê các tập tin swap rồi thoát"
+
+msgid "-r (with file name)\tRecover crashed session"
+msgstr "-r (với tên tập tin)\tPhục hồi lần soạn thảo gặp sự cố"
+
+msgid "-L\t\t\tSame as -r"
+msgstr "-L\t\t\tGiống với -r"
+
+msgid "-f\t\t\tDon't use newcli to open window"
+msgstr "-f\t\t\tKhông sử dụng newcli để mở cửa sổ"
+
+msgid "-dev <device>\t\tUse <device> for I/O"
+msgstr "-dev <thiết bị>\t\tSử dụng <thiết bị> cho I/O"
+
+msgid "-A\t\t\tstart in Arabic mode"
+msgstr "-A\t\t\tKhởi động vào chế độ Ả Rập"
+
+msgid "-H\t\t\tStart in Hebrew mode"
+msgstr "-H\t\t\tKhởi động vào chế độ Do thái"
+
+msgid "-F\t\t\tStart in Farsi mode"
+msgstr "-F\t\t\tKhởi động vào chế độ Farsi"
+
+msgid "-T <terminal>\tSet terminal type to <terminal>"
+msgstr "-T <terminal>\tÄặt loại terminal thành <terminal>"
+
+msgid "-u <vimrc>\t\tUse <vimrc> instead of any .vimrc"
+msgstr "-u <vimrc>\t\tSá»­ dụng <vimrc> thay thế cho má»i .vimrc"
+
+msgid "-U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc"
+msgstr "-U <gvimrc>\t\tSá»­ dụng <gvimrc> thay thế cho má»i .gvimrc"
+
+msgid "--noplugin\t\tDon't load plugin scripts"
+msgstr "--noplugin\t\tKhông nạp bất kỳ script môđun nào"
+
+msgid "-o[N]\t\tOpen N windows (default: one for each file)"
+msgstr "-o[N]\t\tMở N cửa sổ (theo mặc định: mỗi cửa sổ cho một tập tin)"
+
+msgid "-O[N]\t\tLike -o but split vertically"
+msgstr "-O[N]\t\tGiống vá»›i -o nhưng phân chia theo đưá»ng thẳng đứng"
+
+msgid "+\t\t\tStart at end of file"
+msgstr "+\t\t\tBắt đầu soạn thảo từ cuối tập tin"
+
+msgid "+<lnum>\t\tStart at line <lnum>"
+msgstr "+<lnum>\t\tBắt đầu soạn thảo từ dòng thứ <lnum> (số thứ tự của dòng)"
+
+msgid "--cmd <command>\tExecute <command> before loading any vimrc file"
+msgstr "--cmd <câu lệnh>\tThực hiện <câu lệnh> trước khi nạp tập tin vimrc"
+
+msgid "-c <command>\t\tExecute <command> after loading the first file"
+msgstr "-c <câu lệnh>\t\tThực hiện <câu lệnh> sau khi nạp tập tin đầu tiên"
+
+msgid "-S <session>\t\tSource file <session> after loading the first file"
+msgstr "-S <session>\t\tThực hiện <session> sau khi nạp tập tin đầu tiên"
+
+msgid "-s <scriptin>\tRead Normal mode commands from file <scriptin>"
+msgstr ""
+"-s <scriptin>\tÄá»c các lệnh cá»§a chế độ Thông thưá»ng từ tập tin <scriptin>"
+
+msgid "-w <scriptout>\tAppend all typed commands to file <scriptout>"
+msgstr "-w <scriptout>\tThêm tất cả các lệnh đã gõ vào tập tin <scriptout>"
+
+msgid "-W <scriptout>\tWrite all typed commands to file <scriptout>"
+msgstr "-W <scriptout>\tGhi nhớ tất cả các lệnh đã gõ vào tập tin <scriptout>"
+
+msgid "-x\t\t\tEdit encrypted files"
+msgstr "-x\t\t\tSoạn thảo tập tin đã mã hóa"
+
+msgid "-display <display>\tConnect vim to this particular X-server"
+msgstr "-display <màn hình>\tKết nối vim tới máy chủ X đã chỉ ra"
+
+msgid "-X\t\t\tDo not connect to X server"
+msgstr "-X\t\t\tKhông thực hiện việc kết nối tới máy chủ X"
+
+msgid "--remote <files>\tEdit <files> in a Vim server if possible"
+msgstr "--remote <tập tin>\tSoạn thảo <tập tin> trên máy chủ Vim nếu có thể"
+
+msgid "--remote-silent <files> Same, don't complain if there is no server"
+msgstr ""
+"--remote-silent <tập tin> Cũng vậy, nhưng không kêu ca dù không có máy chủ"
+
+msgid ""
+"--remote-wait <files> As --remote but wait for files to have been edited"
+msgstr "--remote-wait <tập tin> Cũng như --remote, nhưng chỠsự kết thúc"
+
+msgid ""
+"--remote-wait-silent <files> Same, don't complain if there is no server"
+msgstr ""
+"--remote-wait-silent <tập tin> Cũng vậy, nhưng không kêu ca dù không có máy "
+"chá»§"
+
+msgid "--remote-send <keys>\tSend <keys> to a Vim server and exit"
+msgstr "--remote-send <phím>\tGửi <phím> lên máy chủ Vim và thoát"
+
+msgid "--remote-expr <expr>\tEvaluate <expr> in a Vim server and print result"
+msgstr ""
+"--remote-expr <biểu thức>\tTính <biểu thức> trên máy chủ Vim và in ra kết quả"
+
+msgid "--serverlist\t\tList available Vim server names and exit"
+msgstr "--serverlist\t\tHiển thị danh sách máy chủ Vim và thoát"
+
+msgid "--servername <name>\tSend to/become the Vim server <name>"
+msgstr "--servername <tên>\tGửi lên (hoặc trở thành) máy chủ Vim với <tên>"
+
+msgid "-i <viminfo>\t\tUse <viminfo> instead of .viminfo"
+msgstr "-i <viminfo>\t\tSử dụng tập tin <viminfo> thay cho .viminfo"
+
+msgid "-h or --help\tPrint Help (this message) and exit"
+msgstr "-h hoặc --help\tHiển thị Trợ giúp (thông tin này) và thoát"
+
+msgid "--version\t\tPrint version information and exit"
+msgstr "--version\t\tÄÆ°a ra thông tin vá» phiên bản Vim và thoát"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (Motif version):\n"
+msgstr ""
+"\n"
+"Tham số cho gvim (phiên bản Motif):\n"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (neXtaw version):\n"
+msgstr ""
+"\n"
+"Tham số cho gvim (phiên bản neXtaw):\n"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (Athena version):\n"
+msgstr ""
+"\n"
+"Tham số cho gvim (phiên bản Athena):\n"
+
+msgid "-display <display>\tRun vim on <display>"
+msgstr "-display <màn hình>\tChạy vim trong <màn hình> đã chỉ ra"
+
+msgid "-iconic\t\tStart vim iconified"
+msgstr "-iconic\t\tChạy vim ở dạng thu nhá»"
+
+msgid "-name <name>\t\tUse resource as if vim was <name>"
+msgstr "-name <tên>\t\tSử dụng tài nguyên giống như khi vim có <tên>"
+
+msgid "\t\t\t (Unimplemented)\n"
+msgstr "\t\t\t (Chưa được thực thi)\n"
+
+msgid "-background <color>\tUse <color> for the background (also: -bg)"
+msgstr "-background <màu>\tSá»­ dụng <màu> chỉ ra cho ná»n (cÅ©ng như: -bg)"
+
+msgid "-foreground <color>\tUse <color> for normal text (also: -fg)"
+msgstr ""
+"-foreground <màu>\tSá»­ dụng <màu> cho văn bản thông thưá»ng (cÅ©ng như: -fg)"
+
+msgid "-font <font>\t\tUse <font> for normal text (also: -fn)"
+msgstr ""
+"-font <phông>\t\tSá»­ dụng <phông> chữ cho văn bản thông thưá»ng (cÅ©ng như: -fn)"
+
+msgid "-boldfont <font>\tUse <font> for bold text"
+msgstr "-boldfont <phông>\tSử dụng <phông> chữ cho văn bản in đậm"
+
+msgid "-italicfont <font>\tUse <font> for italic text"
+msgstr "-italicfont <phông>\tSử dụng <phông> chữ cho văn bản in nghiêng"
+
+msgid "-geometry <geom>\tUse <geom> for initial geometry (also: -geom)"
+msgstr "-geometry <kích thước>\tSử dụng <kích thước> ban đầu (cũng như: -geom)"
+
+msgid "-borderwidth <width>\tUse a border width of <width> (also: -bw)"
+msgstr ""
+"-borderwidth <rá»™ng>\tSá»­ dụng đưá»ng viá»n có chiá»u <rá»™ng> (cÅ©ng như: -bw)"
+
+msgid "-scrollbarwidth <width> Use a scrollbar width of <width> (also: -sw)"
+msgstr ""
+"-scrollbarwidth <rá»™ng> Sá»­ dụng thanh cuá»™n vá»›i chiá»u <rá»™ng> (cÅ©ng như: -sw)"
+
+msgid "-menuheight <height>\tUse a menu bar height of <height> (also: -mh)"
+msgstr ""
+"-menuheight <cao>\tSá»­ dụng thanh trình đơn vá»›i chiá»u <cao> (cÅ©ng như: -mh)"
+
+msgid "-reverse\t\tUse reverse video (also: -rv)"
+msgstr "-reverse\t\tSử dụng chế độ video đảo ngược (cũng như: -rv)"
+
+msgid "+reverse\t\tDon't use reverse video (also: +rv)"
+msgstr "+reverse\t\tKhông sử dụng chế độ video đảo ngược (cũng như: +rv)"
+
+msgid "-xrm <resource>\tSet the specified resource"
+msgstr "-xrm <tài nguyên>\tÄặt <tài nguyên> chỉ ra"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (RISC OS version):\n"
+msgstr ""
+"\n"
+"Tham số cho gvim (phiên bản RISC OS):\n"
+
+msgid "--columns <number>\tInitial width of window in columns"
+msgstr "--columns <số>\tChiá»u rá»™ng ban đầu cá»§a cá»­a sổ tính theo số cá»™t"
+
+msgid "--rows <number>\tInitial height of window in rows"
+msgstr "--rows <số>\tChiá»u cao ban đầu cá»§a cá»­a sổ tính theo số dòng"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (GTK+ version):\n"
+msgstr ""
+"\n"
+"Tham số cho gvim (phiên bản GTK+):\n"
+
+msgid "-display <display>\tRun vim on <display> (also: --display)"
+msgstr ""
+"-display <màn hình>\tChạy vim trên <màn hình> chỉ ra (cũng như: --display)"
+
+msgid "--role <role>\tSet a unique role to identify the main window"
+msgstr "--role <vai trò>\tÄặt <vai trò> duy nhất để nhận diện cá»­a sổ chính"
+
+msgid "--socketid <xid>\tOpen Vim inside another GTK widget"
+msgstr "--socketid <xid>\tMở Vim bên trong thành phần GTK khác"
+
+msgid "-P <parent title>\tOpen Vim inside parent application"
+msgstr "-P <tiêu đỠcủa mẹ>\tMở Vim bên trong ứng dụng mẹ"
+
+msgid "No display"
+msgstr "Không có màn hình"
+
+#. Failed to send, abort.
+msgid ": Send failed.\n"
+msgstr ": Gửi không thành công.\n"
+
+#. Let vim start normally.
+msgid ": Send failed. Trying to execute locally\n"
+msgstr ": Gửi không thành công. Thử thực hiện nội bộ\n"
+
+#, c-format
+msgid "%d of %d edited"
+msgstr "đã soạn thảo %d từ %d"
+
+msgid "No display: Send expression failed.\n"
+msgstr "Không có màn hình: gửi biểu thức không thành công.\n"
+
+msgid ": Send expression failed.\n"
+msgstr ": Gửi biểu thức không thành công.\n"
+
+msgid "No marks set"
+msgstr "Không có dấu hiệu nào được đặt."
+
+#, c-format
+msgid "E283: No marks matching \"%s\""
+msgstr "E283: Không có dấu hiệu tương ứng với \"%s\""
+
+#. Highlight title
+msgid ""
+"\n"
+"mark line col file/text"
+msgstr ""
+"\n"
+"nhãn dòng cột tập tin/văn bản"
+
+#. Highlight title
+msgid ""
+"\n"
+" jump line col file/text"
+msgstr ""
+"\n"
+" bước_nhảy dòng cột tập tin/văn bản"
+
+#. Highlight title
+msgid ""
+"\n"
+"change line col text"
+msgstr ""
+"\n"
+"thay_đổi dòng cột văn_bản"
+
+msgid ""
+"\n"
+"# File marks:\n"
+msgstr ""
+"\n"
+"# Nhãn của tập tin:\n"
+
+#. Write the jumplist with -'
+msgid ""
+"\n"
+"# Jumplist (newest first):\n"
+msgstr ""
+"\n"
+"# Danh sách bước nhảy (mới hơn đứng trước):\n"
+
+msgid ""
+"\n"
+"# History of marks within files (newest to oldest):\n"
+msgstr ""
+"\n"
+"# Lịch sử các nhãn trong tập tin (từ mới nhất đến cũ nhất):\n"
+
+msgid "Missing '>'"
+msgstr "Thiếu '>'"
+
+msgid "E543: Not a valid codepage"
+msgstr "E543: Bảng mã không cho phép"
+
+msgid "E284: Cannot set IC values"
+msgstr "E284: Không đặt được giá trị nội dung nhập vào (IC)"
+
+msgid "E285: Failed to create input context"
+msgstr "E285: Không tạo được nội dung nhập vào"
+
+msgid "E286: Failed to open input method"
+msgstr "E286: Việc thử mở phương pháp nhập không thành công"
+
+msgid "E287: Warning: Could not set destroy callback to IM"
+msgstr ""
+"E287: Cảnh báo: không đặt được sá»± gá»i ngược há»§y diệt thành phương pháp nhập"
+
+msgid "E288: input method doesn't support any style"
+msgstr "E288: phương pháp nhập không hỗ trợ bất kỳ phong cách (style) nào"
+
+msgid "E289: input method doesn't support my preedit type"
+msgstr "E289: phương pháp nhập không hỗ trợ loại soạn thảo trước của Vim"
+
+msgid "E290: over-the-spot style requires fontset"
+msgstr "E290: phong cách over-the-spot yêu cầu một bộ phông chữ"
+
+msgid "E291: Your GTK+ is older than 1.2.3. Status area disabled"
+msgstr "E291: GTK+ cũ hơn 1.2.3. Vùng chỉ trạng thái không làm việc"
+
+msgid "E292: Input Method Server is not running"
+msgstr "E292: Máy chủ phương pháp nhập liệu chưa được chạy"
+
+msgid "E293: block was not locked"
+msgstr "E293: khối chưa bị khóa"
+
+msgid "E294: Seek error in swap file read"
+msgstr "E294: Lá»—i tìm kiếm khi Ä‘á»c tập tin trao đổi (swap)"
+
+msgid "E295: Read error in swap file"
+msgstr "E295: Lá»—i Ä‘á»c tập tin trao đổi (swap)"
+
+msgid "E296: Seek error in swap file write"
+msgstr "E296: Lỗi tìm kiếm khi ghi nhớ tập tin trao đổi (swap)"
+
+msgid "E297: Write error in swap file"
+msgstr "E297: Lỗi ghi nhớ tập tin trao đổi (swap)"
+
+msgid "E300: Swap file already exists (symlink attack?)"
+msgstr ""
+"E300: Tập tin trao đổi (swap) đã tồn tại (sá»­ dụng liên kết má»m tấn công?)"
+
+msgid "E298: Didn't get block nr 0?"
+msgstr "E298: Chưa lấy khối số 0?"
+
+msgid "E298: Didn't get block nr 1?"
+msgstr "E298: Chưa lấy khối số 12?"
+
+msgid "E298: Didn't get block nr 2?"
+msgstr "E298: Chưa lấy khối số 2?"
+
+#. could not (re)open the swap file, what can we do????
+msgid "E301: Oops, lost the swap file!!!"
+msgstr "E301: á»i, mất tập tin trao đổi (swap)!!!"
+
+msgid "E302: Could not rename swap file"
+msgstr "E302: Không đổi được tên tập tin trao đổi (swap)"
+
+#, c-format
+msgid "E303: Unable to open swap file for \"%s\", recovery impossible"
+msgstr ""
+"E303: Không mở được tập tin trao đổi (swap) cho \"%s\", nên không thể phục "
+"hồi"
+
+msgid "E304: ml_timestamp: Didn't get block 0??"
+msgstr "E304: ml_timestamp: Chưa lấy khối số 0??"
+
+#, c-format
+msgid "E305: No swap file found for %s"
+msgstr "E305: Không tìm thấy tập tin trao đổi (swap) cho %s"
+
+msgid "Enter number of swap file to use (0 to quit): "
+msgstr "Hãy nhập số của tập tin trao đổi (swap) muốn sử dụng (0 để thoát): "
+
+#, c-format
+msgid "E306: Cannot open %s"
+msgstr "E306: Không mở được %s"
+
+msgid "Unable to read block 0 from "
+msgstr "Không thể Ä‘á»c khối số 0 từ "
+
+msgid ""
+"\n"
+"Maybe no changes were made or Vim did not update the swap file."
+msgstr ""
+"\n"
+"Chưa có thay đổi nào hoặc Vim không thể cập nhật tập tin trao đổi (swap)"
+
+msgid " cannot be used with this version of Vim.\n"
+msgstr " không thể sử dụng trong phiên bản Vim này.\n"
+
+msgid "Use Vim version 3.0.\n"
+msgstr "Hãy sử dụng Vim phiên bản 3.0.\n"
+
+#, c-format
+msgid "E307: %s does not look like a Vim swap file"
+msgstr "E307: %s không phải là tập tin trao đổi (swap) của Vim"
+
+msgid " cannot be used on this computer.\n"
+msgstr " không thể sử dụng trên máy tính này.\n"
+
+msgid "The file was created on "
+msgstr "Tập tin đã được tạo trên "
+
+msgid ""
+",\n"
+"or the file has been damaged."
+msgstr ""
+",\n"
+"hoặc tập tin đã bị há»ng."
+
+#, c-format
+msgid "Using swap file \"%s\""
+msgstr "Äang sá»­ dụng tập tin trao đổi (swap) \"%s\""
+
+#, c-format
+msgid "Original file \"%s\""
+msgstr "Tập tin gốc \"%s\""
+
+msgid "E308: Warning: Original file may have been changed"
+msgstr "E308: Cảnh báo: Tập tin gốc có thể đã bị thay đổi"
+
+#, c-format
+msgid "E309: Unable to read block 1 from %s"
+msgstr "E309: Không Ä‘á»c được khối số 1 từ %s"
+
+msgid "???MANY LINES MISSING"
+msgstr "???THIẾU NHIỀU DÒNG"
+
+msgid "???LINE COUNT WRONG"
+msgstr "???GIà TRỊ CỦA Sá» ÄẾM DÃ’NG BỊ SAI"
+
+msgid "???EMPTY BLOCK"
+msgstr "???KHá»I Rá»–NG"
+
+msgid "???LINES MISSING"
+msgstr "???THIẾU DÒNG"
+
+#, c-format
+msgid "E310: Block 1 ID wrong (%s not a .swp file?)"
+msgstr "E310: Khối 1 ID sai (%s không phải là tập tin .swp?)"
+
+msgid "???BLOCK MISSING"
+msgstr "???THIẾU KHá»I"
+
+msgid "??? from here until ???END lines may be messed up"
+msgstr "??? từ đây tá»›i ???CUá»I, các dòng có thể đã bị há»ng"
+
+msgid "??? from here until ???END lines may have been inserted/deleted"
+msgstr "??? từ đây tá»›i ???CUá»I, các dòng có thể đã bị chèn hoặc xóa"
+
+msgid "???END"
+msgstr "???CUá»I"
+
+msgid "E311: Recovery Interrupted"
+msgstr "E311: Việc phục hồi bị gián đoạn"
+
+msgid ""
+"E312: Errors detected while recovering; look for lines starting with ???"
+msgstr ""
+"E312: Phát hiện ra lỗi trong khi phục hồi; hãy xem những dòng bắt đầu với ???"
+
+msgid "See \":help E312\" for more information."
+msgstr "Hãy xem thông tin bổ sung trong trợ giúp \":help E312\""
+
+msgid "Recovery completed. You should check if everything is OK."
+msgstr "Việc phục hồi đã hoàn thành. Nên kiểm tra xem má»i thứ có ổn không."
+
+msgid ""
+"\n"
+"(You might want to write out this file under another name\n"
+msgstr ""
+"\n"
+"(Có thể ghi nhớ tập tin với tên khác và so sánh với tập\n"
+
+msgid "and run diff with the original file to check for changes)\n"
+msgstr "gốc bằng chương trình diff).\n"
+
+msgid ""
+"Delete the .swp file afterwards.\n"
+"\n"
+msgstr ""
+"Sau đó hãy xóa tập tin .swp.\n"
+"\n"
+
+#. use msg() to start the scrolling properly
+msgid "Swap files found:"
+msgstr "Tìm thấy tập tin trao đổi (swap):"
+
+msgid " In current directory:\n"
+msgstr " Trong thư mục hiện thá»i:\n"
+
+msgid " Using specified name:\n"
+msgstr " Với tên chỉ ra:\n"
+
+msgid " In directory "
+msgstr " Trong thư mục "
+
+msgid " -- none --\n"
+msgstr " -- không --\n"
+
+msgid " owned by: "
+msgstr " ngưá»i sở hữu: "
+
+msgid " dated: "
+msgstr " ngày: "
+
+msgid " dated: "
+msgstr " ngày: "
+
+msgid " [from Vim version 3.0]"
+msgstr " [từ Vim phiên bản 3.0]"
+
+msgid " [does not look like a Vim swap file]"
+msgstr " [không phải là tập tin trao đổi (swap) của Vim]"
+
+msgid " file name: "
+msgstr " tên tập tin: "
+
+msgid ""
+"\n"
+" modified: "
+msgstr ""
+"\n"
+" thay đổi: "
+
+msgid "YES"
+msgstr "CÓ"
+
+msgid "no"
+msgstr "không"
+
+msgid ""
+"\n"
+" user name: "
+msgstr ""
+"\n"
+" tên ngưá»i dùng: "
+
+msgid " host name: "
+msgstr " tên máy: "
+
+msgid ""
+"\n"
+" host name: "
+msgstr ""
+"\n"
+" tên máy: "
+
+msgid ""
+"\n"
+" process ID: "
+msgstr ""
+"\n"
+" ID tiến trình: "
+
+msgid " (still running)"
+msgstr " (vẫn đang chạy)"
+
+msgid ""
+"\n"
+" [not usable with this version of Vim]"
+msgstr ""
+"\n"
+" [không sử dụng được với phiên bản này của Vim]"
+
+msgid ""
+"\n"
+" [not usable on this computer]"
+msgstr ""
+"\n"
+" [không sử dụng được trên máy tính này]"
+
+msgid " [cannot be read]"
+msgstr " [không Ä‘á»c được]"
+
+msgid " [cannot be opened]"
+msgstr " [không mở được]"
+
+msgid "E313: Cannot preserve, there is no swap file"
+msgstr "E313: Không cập nhật được tập tin trao đổi (swap) vì không tìm thấy nó"
+
+msgid "File preserved"
+msgstr "Äã cập nhật tập tin trao đổi (swap)"
+
+msgid "E314: Preserve failed"
+msgstr "E314: Cập nhật không thành công"
+
+#, c-format
+msgid "E315: ml_get: invalid lnum: %ld"
+msgstr "E315: ml_get: giá trị lnum không đúng: %ld"
+
+#, c-format
+msgid "E316: ml_get: cannot find line %ld"
+msgstr "E316: ml_get: không tìm được dòng %ld"
+
+msgid "E317: pointer block id wrong 3"
+msgstr "E317: Giá trị của pointer khối số 3 không đúng"
+
+msgid "stack_idx should be 0"
+msgstr "giá trị stack_idx phải bằng 0"
+
+msgid "E318: Updated too many blocks?"
+msgstr "E318: Äã cập nhật quá nhiá»u khối?"
+
+msgid "E317: pointer block id wrong 4"
+msgstr "E317: Giá trị của pointer khối số 4 không đúng"
+
+msgid "deleted block 1?"
+msgstr "đã xóa khối số 1?"
+
+#, c-format
+msgid "E320: Cannot find line %ld"
+msgstr "E320: Không tìm được dòng %ld"
+
+msgid "E317: pointer block id wrong"
+msgstr "E317: giá trị của pointer khối không đúng"
+
+msgid "pe_line_count is zero"
+msgstr "giá trị pe_line_count bằng không"
+
+#, c-format
+msgid "E322: line number out of range: %ld past the end"
+msgstr "E322: số thứ tự dòng vượt quá giới hạn : %ld"
+
+#, c-format
+msgid "E323: line count wrong in block %ld"
+msgstr "E323: giá trị đếm dòng không đúng trong khối %ld"
+
+msgid "Stack size increases"
+msgstr "Kích thước của đống tăng lên"
+
+msgid "E317: pointer block id wrong 2"
+msgstr "E317: Giá trị của cái chỉ (pointer) khối số 2 không đúng"
+
+msgid "E325: ATTENTION"
+msgstr "E325: CHÚ Ã"
+
+msgid ""
+"\n"
+"Found a swap file by the name \""
+msgstr ""
+"\n"
+"Tìm thấy một tập tin trao đổi (swap) với tên \""
+
+msgid "While opening file \""
+msgstr "Khi mở tập tin: \""
+
+msgid " NEWER than swap file!\n"
+msgstr " MỚI hơn so với tập tin trao đổi (swap)\n"
+
+#. Some of these messages are long to allow translation to
+#. * other languages.
+msgid ""
+"\n"
+"(1) Another program may be editing the same file.\n"
+" If this is the case, be careful not to end up with two\n"
+" different instances of the same file when making changes.\n"
+msgstr ""
+"\n"
+"(1) Rất có thể một chương trình khác đang soạn thảo tập tin.\n"
+" Nếu như vậy, hãy cẩn thận khi thay đổi, làm sao để không thu\n"
+" được hai phương án khác nhau của cùng một tập tin.\n"
+
+msgid " Quit, or continue with caution.\n"
+msgstr " Thoát hoặc tiếp tục với sự cẩn thận.\n"
+
+msgid ""
+"\n"
+"(2) An edit session for this file crashed.\n"
+msgstr ""
+"\n"
+"(2) Lần soạn thảo trước của tập tin này gặp sự cố.\n"
+
+msgid " If this is the case, use \":recover\" or \"vim -r "
+msgstr ""
+" Trong trưá»ng hợp này, hãy sá»­ dụng câu lệnh \":recover\" hoặc \"vim -r "
+
+msgid ""
+"\"\n"
+" to recover the changes (see \":help recovery\").\n"
+msgstr ""
+"\"\n"
+" để phục hồi những thay đổi (hãy xem \":help recovery\").\n"
+
+msgid " If you did this already, delete the swap file \""
+msgstr ""
+" Nếu đã thực hiện thao tác này rồi, thì hãy xóa tập tin trao đổi (swap) \""
+
+msgid ""
+"\"\n"
+" to avoid this message.\n"
+msgstr ""
+"\"\n"
+" để tránh sự xuất hiện của thông báo này trong tương lai.\n"
+
+msgid "Swap file \""
+msgstr "Tập tin trao đổi (swap) \""
+
+msgid "\" already exists!"
+msgstr "\" đã có rồi!"
+
+msgid "VIM - ATTENTION"
+msgstr "VIM - CHÚ Ã"
+
+msgid "Swap file already exists!"
+msgstr "Tập tin trao đổi (swap) đã rồi!"
+
+msgid ""
+"&Open Read-Only\n"
+"&Edit anyway\n"
+"&Recover\n"
+"&Quit\n"
+"&Abort"
+msgstr ""
+"&O Mở chỉ để Ä‘á»c\n"
+"&E Vẫn soạn thảo\n"
+"&R Phục hồi\n"
+"&Q Thoát\n"
+"&A Gián đoạn"
+
+msgid ""
+"&Open Read-Only\n"
+"&Edit anyway\n"
+"&Recover\n"
+"&Quit\n"
+"&Abort\n"
+"&Delete it"
+msgstr ""
+"&O Mở chỉ để Ä‘á»c\n"
+"&E Vẫn soạn thảo\n"
+"&R Phục hồi\n"
+"&Q Thoát\n"
+"&A Gián đoạn&D Xóa nó"
+
+msgid "E326: Too many swap files found"
+msgstr "E326: Tìm thấy quá nhiá»u tập tin trao đổi (swap)"
+
+msgid "E327: Part of menu-item path is not sub-menu"
+msgstr ""
+"E327: Má»™t phần cá»§a đưá»ng dẫn tá»›i phần tá»­ cá»§a trình đơn không phải là trình "
+"đơn con"
+
+msgid "E328: Menu only exists in another mode"
+msgstr "E328: Trình đơn chỉ có trong chế độ khác"
+
+msgid "E329: No menu of that name"
+msgstr "E329: Không có trình đơn với tên như vậy"
+
+msgid "E330: Menu path must not lead to a sub-menu"
+msgstr "E330: ÄÆ°á»ng dẫn tá»›i trình đơn không được đưa tá»›i trình đơn con"
+
+msgid "E331: Must not add menu items directly to menu bar"
+msgstr ""
+"E331: Các phần tử của trình đơn không thể thêm trực tiếp vào thanh trình đơn"
+
+msgid "E332: Separator cannot be part of a menu path"
+msgstr "E332: Cái phân chia không thể là má»™t phần cá»§a đưá»ng dẫn tá»›i trình đơn"
+
+#. Now we have found the matching menu, and we list the mappings
+#. Highlight title
+msgid ""
+"\n"
+"--- Menus ---"
+msgstr ""
+"\n"
+"--- Trình đơn ---"
+
+msgid "Tear off this menu"
+msgstr "Chia cắt trình đơn này"
+
+msgid "E333: Menu path must lead to a menu item"
+msgstr "E333: ÄÆ°á»ng dẫn tá»›i trình đơn phải đưa tá»›i má»™t phần tá»­ cuả trình đơn"
+
+#, c-format
+msgid "E334: Menu not found: %s"
+msgstr "E334: Không tìm thấy trình đơn: %s"
+
+#, c-format
+msgid "E335: Menu not defined for %s mode"
+msgstr "E335: Trình đơn không được định nghĩa cho chế độ %s"
+
+msgid "E336: Menu path must lead to a sub-menu"
+msgstr "E336: ÄÆ°á»ng dẫn tá»›i trình đơn phải đưa tá»›i má»™t trình đơn con"
+
+msgid "E337: Menu not found - check menu names"
+msgstr "E337: Không tìm thấy trình đơn - hãy kiểm tra tên trình đơn"
+
+#, c-format
+msgid "Error detected while processing %s:"
+msgstr "Phát hiện lỗi khi xử lý %s:"
+
+#, c-format
+msgid "line %4ld:"
+msgstr "dòng %4ld:"
+
+msgid "[string too long]"
+msgstr "[chuỗi quá dài]"
+
+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>"
+
+msgid "Interrupt: "
+msgstr "Gián đoạn: "
+
+msgid "Hit ENTER to continue"
+msgstr "Nhấn phím ENTER để tiếp tục"
+
+msgid "Hit ENTER or type command to continue"
+msgstr "Nhấn phím ENTER hoặc nhập câu lệnh để tiếp tục"
+
+msgid "-- More --"
+msgstr "-- Còn nữa --"
+
+msgid " (RET/BS: line, SPACE/b: page, d/u: half page, q: quit)"
+msgstr " (RET/BS: dòng, SPACE/b: trang, d/u: nửa trang, q: thoát)"
+
+msgid " (RET: line, SPACE: page, d: half page, q: quit)"
+msgstr " (RET: dòng, SPACE: trang, d: nửa trang, q: thoát)"
+
+msgid "Question"
+msgstr "Câu há»i"
+
+msgid ""
+"&Yes\n"
+"&No"
+msgstr ""
+"&Có\n"
+"&Không"
+
+msgid ""
+"&Yes\n"
+"&No\n"
+"Save &All\n"
+"&Discard All\n"
+"&Cancel"
+msgstr ""
+"&Có\n"
+"&Không&Ghi nhớ tất cả\n"
+"&Vứt bỠtất cả\n"
+"&Dừng lại"
+
+msgid "Save File dialog"
+msgstr "Ghi nhớ tập tin"
+
+msgid "Open File dialog"
+msgstr "Mở tập tin"
+
+#. TODO: non-GUI file selector here
+msgid "E338: Sorry, no file browser in console mode"
+msgstr ""
+"E338: Xin lỗi nhưng không có trình duyệt tập tin trong chế độ kênh giao tác "
+"(console)"
+
+msgid "W10: Warning: Changing a readonly file"
+msgstr "W10: Cảnh báo: Thay đổi má»™t tập tin chỉ có quyá»n Ä‘á»c"
+
+msgid "1 more line"
+msgstr "Thêm 1 dòng"
+
+msgid "1 line less"
+msgstr "Bớt 1 dòng"
+
+#, c-format
+msgid "%ld more lines"
+msgstr "Thêm %ld dòng"
+
+#, c-format
+msgid "%ld fewer lines"
+msgstr "Bớt %ld dòng"
+
+msgid " (Interrupted)"
+msgstr " (Bị gián đoạn)"
+
+msgid "Vim: preserving files...\n"
+msgstr "Vim: ghi nhớ các tập tin...\n"
+
+#. close all memfiles, without deleting
+msgid "Vim: Finished.\n"
+msgstr "Vim: Äã xong.\n"
+
+msgid "ERROR: "
+msgstr "Lá»–I: "
+
+#, c-format
+msgid ""
+"\n"
+"[bytes] total alloc-freed %lu-%lu, in use %lu, peak use %lu\n"
+msgstr ""
+"\n"
+"[byte] tổng phân phối-còn trống %lu-%lu, sử dụng %lu, píc sử dụng %lu\n"
+
+#, c-format
+msgid ""
+"[calls] total re/malloc()'s %lu, total free()'s %lu\n"
+"\n"
+msgstr ""
+"[gá»i] tổng re/malloc() %lu, tổng free() %lu\n"
+"\n"
+
+msgid "E340: Line is becoming too long"
+msgstr "E340: Dòng đang trở thành quá dài"
+
+#, c-format
+msgid "E341: Internal error: lalloc(%ld, )"
+msgstr "E341: Lá»—i ná»™i bá»™: lalloc(%ld, )"
+
+#, c-format
+msgid "E342: Out of memory! (allocating %lu bytes)"
+msgstr "E342: Không đủ bộ nhớ! (phân chia %lu byte)"
+
+#, c-format
+msgid "Calling shell to execute: \"%s\""
+msgstr "Gá»i shell để thá»±c hiện: \"%s\""
+
+msgid "E545: Missing colon"
+msgstr "E545: Thiếu dấu hai chấm"
+
+msgid "E546: Illegal mode"
+msgstr "E546: Chế độ không cho phép"
+
+msgid "E547: Illegal mouseshape"
+msgstr "E547: Dạng trỠchuột không cho phép"
+
+msgid "E548: digit expected"
+msgstr "E548: yêu cầu một số"
+
+msgid "E549: Illegal percentage"
+msgstr "E549: Tỷ lệ phần trăm không cho phép"
+
+msgid "Enter encryption key: "
+msgstr "Nhập mật khẩu để mã hóa: "
+
+msgid "Enter same key again: "
+msgstr " Nhập lại mật khẩu:"
+
+msgid "Keys don't match!"
+msgstr "Hai mật khẩu không trùng nhau!"
+
+#, c-format
+msgid ""
+"E343: Invalid path: '**[number]' must be at the end of the path or be "
+"followed by '%s'."
+msgstr ""
+"E343: ÄÆ°á»ng dẫn đưa ra không đúng: '**[số]' phải ở cuối đưá»ng dẫn hoặc theo "
+"sau bởi '%s'"
+
+#, c-format
+msgid "E344: Can't find directory \"%s\" in cdpath"
+msgstr "E344: Không tìm thấy thư mục \"%s\" để chuyển thư mục"
+
+#, c-format
+msgid "E345: Can't find file \"%s\" in path"
+msgstr "E345: Không tìm thấy tập tin \"%s\" trong đưá»ng dẫn"
+
+#, c-format
+msgid "E346: No more directory \"%s\" found in cdpath"
+msgstr "E346: Trong đưá»ng dẫn thay đổi thư mục không còn có thư mục \"%s\" nữa"
+
+#, c-format
+msgid "E347: No more file \"%s\" found in path"
+msgstr "E347: Trong đưá»ng dẫn path không còn có tập tin \"%s\" nữa"
+
+msgid "E550: Missing colon"
+msgstr "E550: Thiếu dấu hai chấm"
+
+msgid "E551: Illegal component"
+msgstr "E551: Thành phần không cho phép"
+
+msgid "E552: digit expected"
+msgstr "E552: Cần chỉ ra một số"
+
+#. Get here when the server can't be found.
+msgid "Cannot connect to Netbeans #2"
+msgstr "Không kết nối được với Netbeans #2"
+
+msgid "Cannot connect to Netbeans"
+msgstr "Không kết nối được với NetBeans"
+
+#, c-format
+msgid "E668: Wrong access mode for NetBeans connection info file: \"%s\""
+msgstr ""
+"E668: Chế độ truy cập thông tin vỠliên kết với NetBeans không đúng: \"%s\""
+
+msgid "read from Netbeans socket"
+msgstr "Ä‘á»c từ socket NetBeans"
+
+#, c-format
+msgid "E658: NetBeans connection lost for buffer %ld"
+msgstr "E658: Bị mất liên kết với NetBeans cho bộ đệm %ld"
+
+msgid "Warning: terminal cannot highlight"
+msgstr "Cảnh báo: terminal không thực hiện được sự chiếu sáng"
+
+msgid "E348: No string under cursor"
+msgstr "E348: Không có chuá»—i ở vị trí con trá»"
+
+msgid "E349: No identifier under cursor"
+msgstr "E349: Không có tên ở vị trí con trá»"
+
+msgid "E352: Cannot erase folds with current 'foldmethod'"
+msgstr ""
+"E352: Không thể tẩy xóa nếp gấp vá»›i giá trị hiện thá»i cá»§a tùy chá»n "
+"'foldmethod'"
+
+msgid "E664: changelist is empty"
+msgstr "E664: danh sách những thay đổi trống rỗng"
+
+msgid "E662: At start of changelist"
+msgstr "E662: Ở đầu danh sách những thay đổi"
+
+msgid "E663: At end of changelist"
+msgstr "E663: Ở cuối danh sách những thay đổi"
+
+msgid "Type :quit<Enter> to exit Vim"
+msgstr "Gõ :quit<Enter> để thoát khá»i Vim"
+
+#, c-format
+msgid "1 line %sed 1 time"
+msgstr "Trên 1 dòng %s 1 lần"
+
+#, c-format
+msgid "1 line %sed %d times"
+msgstr "Trên 1 dòng %s %d lần"
+
+#, c-format
+msgid "%ld lines %sed 1 time"
+msgstr "Trên %ld dòng %s 1 lần"
+
+#, c-format
+msgid "%ld lines %sed %d times"
+msgstr "Trên %ld dòng %s %d lần"
+
+#, c-format
+msgid "%ld lines to indent... "
+msgstr "Thụt đầu %ld dòng..."
+
+msgid "1 line indented "
+msgstr "Äã thụt đầu 1 dòng"
+
+#, c-format
+msgid "%ld lines indented "
+msgstr "%ld dòng đã thụt đầu"
+
+#. must display the prompt
+msgid "cannot yank; delete anyway"
+msgstr "sao chép không thành công; đã xóa"
+
+msgid "1 line changed"
+msgstr "1 dòng đã thay đổi"
+
+#, c-format
+msgid "%ld lines changed"
+msgstr "%ld đã thay đổi"
+
+#, c-format
+msgid "freeing %ld lines"
+msgstr "đã làm sạch %ld dòng"
+
+msgid "1 line yanked"
+msgstr "đã sao chép 1 dòng"
+
+#, c-format
+msgid "%ld lines yanked"
+msgstr "đã sao chép %ld dòng"
+
+#, c-format
+msgid "E353: Nothing in register %s"
+msgstr "E353: Trong sổ đăng ký %s không có gì hết"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Registers ---"
+msgstr ""
+"\n"
+"--- Sổ đăng ký ---"
+
+msgid "Illegal register name"
+msgstr "Tên sổ đăng ký không cho phép"
+
+msgid ""
+"\n"
+"# Registers:\n"
+msgstr ""
+"\n"
+"# Sổ đăng ký:\n"
+
+#, c-format
+msgid "E574: Unknown register type %d"
+msgstr "E574: Loại sổ đăng ký không biết %d"
+
+#, c-format
+msgid "E354: Invalid register name: '%s'"
+msgstr "E354: Tên sổ đăng ký không cho phép: '%s'"
+
+#, c-format
+msgid "%ld Cols; "
+msgstr "%ld Cá»™t; "
+
+#, c-format
+msgid "Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Bytes"
+msgstr "Chá»n %s%ld cá»§a %ld Dòng; %ld cá»§a %ld Từ; %ld cá»§a %ld Byte"
+
+#, c-format
+msgid "Col %s of %s; Line %ld of %ld; Word %ld of %ld; Byte %ld of %ld"
+msgstr "Cột %s của %s; Dòng %ld của %ld; Từ %ld của %ld; Byte %ld của %ld"
+
+#, c-format
+msgid "(+%ld for BOM)"
+msgstr "(+%ld cho BOM)"
+
+msgid "%<%f%h%m%=Page %N"
+msgstr "%<%f%h%m%=Trang %N"
+
+msgid "Thanks for flying Vim"
+msgstr "Xin cảm ơn đã sử dụng Vim"
+
+msgid "E518: Unknown option"
+msgstr "E518: Tùy chá»n không biết"
+
+msgid "E519: Option not supported"
+msgstr "E519: Tùy chá»n không được há»— trợ"
+
+msgid "E520: Not allowed in a modeline"
+msgstr "E520: Không cho phép trên dòng chế độ (modeline)"
+
+msgid ""
+"\n"
+"\tLast set from "
+msgstr ""
+"\n"
+"\tLần cuối cùng tùy chá»n thay đổi vào "
+
+msgid "E521: Number required after ="
+msgstr "E521: Sau dấu = cần đưa ra một số"
+
+msgid "E522: Not found in termcap"
+msgstr "E522: Không tìm thấy trong termcap"
+
+#, c-format
+msgid "E539: Illegal character <%s>"
+msgstr "E539: Ký tự không cho phép <%s>"
+
+msgid "E529: Cannot set 'term' to empty string"
+msgstr "E529: Giá trị cá»§a tùy chá»n 'term' không thể là má»™t chuá»—i trống rá»—ng"
+
+msgid "E530: Cannot change term in GUI"
+msgstr "E530: Không thể thay đổi terminal trong giao diện đồ há»a GUI"
+
+msgid "E531: Use \":gui\" to start the GUI"
+msgstr "E531: Hãy sá»­ dụng \":gui\" để chạy giao diện đồ há»a GUI"
+
+msgid "E589: 'backupext' and 'patchmode' are equal"
+msgstr "E589: giá trị cá»§a tùy chá»n 'backupext' và 'patchmode' bằng nhau"
+
+msgid "E617: Cannot be changed in the GTK+ 2 GUI"
+msgstr "E617: Không thể thay đổi trong giao diện đồ há»a GTK+ 2"
+
+msgid "E524: Missing colon"
+msgstr "E524: Thiếu dấu hai chấm"
+
+msgid "E525: Zero length string"
+msgstr "E525: Chuỗi có độ dài bằng không"
+
+#, c-format
+msgid "E526: Missing number after <%s>"
+msgstr "E526: Thiếu một số sau <%s>"
+
+msgid "E527: Missing comma"
+msgstr "E527: Thiếu dấu phẩy"
+
+msgid "E528: Must specify a ' value"
+msgstr "E528: Cần đưa ra một giá trị cho '"
+
+msgid "E595: contains unprintable or wide character"
+msgstr "E595: chứa ký tá»± không in ra hoặc ký tá»± vá»›i chiá»u rá»™ng gấp đôi"
+
+msgid "E596: Invalid font(s)"
+msgstr "E596: Phông chữ không đúng"
+
+msgid "E597: can't select fontset"
+msgstr "E597: không chá»n được bá»™ phông chữ"
+
+msgid "E598: Invalid fontset"
+msgstr "E598: Bộ phông chữ không đúng"
+
+msgid "E533: can't select wide font"
+msgstr "E533: không chá»n được phông chữ vá»›i các ký tá»± có chiá»u rá»™ng gấp đôi"
+
+msgid "E534: Invalid wide font"
+msgstr "E534: Phông chữ, vá»›i ký tá»± có chiá»u rá»™ng gấp đôi, không đúng"
+
+#, c-format
+msgid "E535: Illegal character after <%c>"
+msgstr "E535: Ký tự sau <%c> không chính xác"
+
+msgid "E536: comma required"
+msgstr "E536: cầu có dấu phẩy"
+
+#, c-format
+msgid "E537: 'commentstring' must be empty or contain %s"
+msgstr "E537: Giá trị cá»§a tùy chá»n 'commentstring' phải rá»—ng hoặc chứa %s"
+
+msgid "E538: No mouse support"
+msgstr "E538: Chuột không được hỗ trợ"
+
+msgid "E540: Unclosed expression sequence"
+msgstr "E540: Dãy các biểu thức không đóng"
+
+msgid "E541: too many items"
+msgstr "E541: quá nhiá»u phần tá»­"
+
+msgid "E542: unbalanced groups"
+msgstr "E542: các nhóm không cân bằng"
+
+msgid "E590: A preview window already exists"
+msgstr "E590: Cửa sổ xem trước đã có"
+
+msgid "W17: Arabic requires UTF-8, do ':set encoding=utf-8'"
+msgstr "W17: Tiếng Ả Rập yêu cầu sử dụng UTF-8, hãy nhập ':set encoding=utf-8'"
+
+#, c-format
+msgid "E593: Need at least %d lines"
+msgstr "E593: Cần ít nhất %d dòng"
+
+#, c-format
+msgid "E594: Need at least %d columns"
+msgstr "E594: Cần ít nhất %d cột"
+
+#, c-format
+msgid "E355: Unknown option: %s"
+msgstr "E355: Tùy chá»n không biết: %s"
+
+msgid ""
+"\n"
+"--- Terminal codes ---"
+msgstr ""
+"\n"
+"--- Mã terminal ---"
+
+msgid ""
+"\n"
+"--- Global option values ---"
+msgstr ""
+"\n"
+"--- Giá trị tùy chá»n toàn cầu ---"
+
+msgid ""
+"\n"
+"--- Local option values ---"
+msgstr ""
+"\n"
+"--- Giá trị tùy chá»n ná»™i bá»™ ---"
+
+msgid ""
+"\n"
+"--- Options ---"
+msgstr ""
+"\n"
+"--- Tùy chá»n ---"
+
+msgid "E356: get_varp ERROR"
+msgstr "E356: Lá»–I get_varp"
+
+#, c-format
+msgid "E357: 'langmap': Matching character missing for %s"
+msgstr "E357: 'langmap': Thiếu ký tự tương ứng cho %s"
+
+#, c-format
+msgid "E358: 'langmap': Extra characters after semicolon: %s"
+msgstr "E358: 'langmap': Thừa ký tự sau dấu chấm phẩy: %s"
+
+msgid "cannot open "
+msgstr "không mở được "
+
+msgid "VIM: Can't open window!\n"
+msgstr "VIM: Không mở được cửa sổ!\n"
+
+msgid "Need Amigados version 2.04 or later\n"
+msgstr "Cần Amigados phiên bản 2.04 hoặc mới hơn\n"
+
+#, c-format
+msgid "Need %s version %ld\n"
+msgstr "Cần %s phiên bản %ld\n"
+
+msgid "Cannot open NIL:\n"
+msgstr "Không mở được NIL:\n"
+
+msgid "Cannot create "
+msgstr "Không tạo được "
+
+#, c-format
+msgid "Vim exiting with %d\n"
+msgstr "Thoát Vim với mã %d\n"
+
+msgid "cannot change console mode ?!\n"
+msgstr "không thay đổi được chế độ kênh giao tác (console)?!\n"
+
+msgid "mch_get_shellsize: not a console??\n"
+msgstr "mch_get_shellsize: không phải là kênh giao tác (console)??\n"
+
+#. if Vim opened a window: Executing a shell may cause crashes
+msgid "E360: Cannot execute shell with -f option"
+msgstr "E360: Không chạy được shell vá»›i tùy chá»n -f"
+
+msgid "Cannot execute "
+msgstr "Không chạy được "
+
+msgid "shell "
+msgstr "shell "
+
+msgid " returned\n"
+msgstr " thoát\n"
+
+msgid "ANCHOR_BUF_SIZE too small."
+msgstr "Giá trị ANCHOR_BUF_SIZE quá nhá»."
+
+msgid "I/O ERROR"
+msgstr "LỖI I/O (NHẬP/XUẤT)"
+
+msgid "...(truncated)"
+msgstr "...(bị cắt bớt)"
+
+msgid "'columns' is not 80, cannot execute external commands"
+msgstr "Tùy chá»n 'columns' khác 80, chương trình ngoại trú không thể thá»±c hiện"
+
+msgid "E237: Printer selection failed"
+msgstr "E237: Chá»n máy in không thành công"
+
+#, c-format
+msgid "to %s on %s"
+msgstr "tới %s trên %s"
+
+#, c-format
+msgid "E613: Unknown printer font: %s"
+msgstr "E613: Không rõ phông chữ của máy in: %s"
+
+#, c-format
+msgid "E238: Print error: %s"
+msgstr "E238: Lá»—i in: %s"
+
+msgid "Unknown"
+msgstr "Không rõ"
+
+#, c-format
+msgid "Printing '%s'"
+msgstr "Äang in '%s'"
+
+#, c-format
+msgid "E244: Illegal charset name \"%s\" in font name \"%s\""
+msgstr "E244: Tên bảng mã không cho phép \"%s\" trong tên phông chữ \"%s\""
+
+#, c-format
+msgid "E245: Illegal char '%c' in font name \"%s\""
+msgstr "E245: Ký tự không cho phép '%c' trong tên phông chữ \"%s\""
+
+msgid "Vim: Double signal, exiting\n"
+msgstr "Vim: Tín hiệu đôi, thoát\n"
+
+#, c-format
+msgid "Vim: Caught deadly signal %s\n"
+msgstr "Vim: Nhận được tín hiệu chết %s\n"
+
+msgid "Vim: Caught deadly signal\n"
+msgstr "Vim: Nhận được tín hiệu chết\n"
+
+#, c-format
+msgid "Opening the X display took %ld msec"
+msgstr "Mở màn hình X mất %ld mili giây"
+
+msgid ""
+"\n"
+"Vim: Got X error\n"
+msgstr ""
+"\n"
+"Vim: Lá»—i X\n"
+
+msgid "Testing the X display failed"
+msgstr "Kiểm tra màn hình X không thành công"
+
+msgid "Opening the X display timed out"
+msgstr "Không mở được màn hình X trong thá»i gian cho phép (time out)"
+
+msgid ""
+"\n"
+"Cannot execute shell "
+msgstr ""
+"\n"
+"Không chạy được shell "
+
+msgid ""
+"\n"
+"Cannot execute shell sh\n"
+msgstr ""
+"\n"
+"Không chạy được shell sh\n"
+
+msgid ""
+"\n"
+"shell returned "
+msgstr ""
+"\n"
+"shell dừng làm việc "
+
+msgid ""
+"\n"
+"Cannot create pipes\n"
+msgstr ""
+"\n"
+"Không tạo được đưá»ng ống (pipe)\n"
+
+msgid ""
+"\n"
+"Cannot fork\n"
+msgstr ""
+"\n"
+"Không thực hiện được fork()\n"
+
+msgid ""
+"\n"
+"Command terminated\n"
+msgstr ""
+"\n"
+"Câu lệnh bị gián đoạn\n"
+
+msgid "XSMP lost ICE connection"
+msgstr "XSMP mất kết nối ICE"
+
+msgid "Opening the X display failed"
+msgstr "Mở màn hình X không thành công"
+
+msgid "XSMP handling save-yourself request"
+msgstr "XSMP xử lý yêu cầu tự động ghi nhớ"
+
+msgid "XSMP opening connection"
+msgstr "XSMP mở kết nối"
+
+msgid "XSMP ICE connection watch failed"
+msgstr "XSMP mất theo dõi kết nối ICE"
+
+#, c-format
+msgid "XSMP SmcOpenConnection failed: %s"
+msgstr "XSMP thực hiện SmcOpenConnection không thành công: %s"
+
+msgid "At line"
+msgstr "Tại dòng"
+
+msgid "Could not allocate memory for command line."
+msgstr "Không phân chia được bộ nhớ cho dòng lệnh."
+
+msgid "VIM Error"
+msgstr "Lá»—i VIM"
+
+msgid "Could not load vim32.dll!"
+msgstr "Không nạp được vim32.dll!"
+
+msgid "Could not fix up function pointers to the DLL!"
+msgstr "Không sửa được cái chỉ (pointer) hàm số tới DLL!"
+
+#, c-format
+msgid "shell returned %d"
+msgstr "thoát shell với mã %d"
+
+#, c-format
+msgid "Vim: Caught %s event\n"
+msgstr "Vim: Nhận được sự kiện %s\n"
+
+msgid "close"
+msgstr "đóng"
+
+msgid "logoff"
+msgstr "thoát"
+
+msgid "shutdown"
+msgstr "tắt máy"
+
+msgid "E371: Command not found"
+msgstr "E371: Câu lệnh không tìm thấy"
+
+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 ""
+"Không tìm thấy VIMRUN.EXE trong $PATH.\n"
+"Lệnh ngoại trú sẽ không dừng lại sau khi hoàn thành.\n"
+"Thông tin chi tiết xem trong :help win32-vimrun"
+
+msgid "Vim Warning"
+msgstr "Cảnh báo Vim"
+
+#, c-format
+msgid "E372: Too many %%%c in format string"
+msgstr "E372: Quá nhiá»u %%%c trong chuá»—i định dạng"
+
+#, c-format
+msgid "E373: Unexpected %%%c in format string"
+msgstr "E373: Không mong đợi %%%c trong chuỗi định dạng"
+
+msgid "E374: Missing ] in format string"
+msgstr "E374: Thiếu ] trong chuỗi định dạng"
+
+#, c-format
+msgid "E375: Unsupported %%%c in format string"
+msgstr "E375: %%%c không được hỗ trợ trong chuỗi định dạng"
+
+#, c-format
+msgid "E376: Invalid %%%c in format string prefix"
+msgstr "E376: Không cho phép %%%c trong tiá»n tố cá»§a chuá»—i định dạng"
+
+#, c-format
+msgid "E377: Invalid %%%c in format string"
+msgstr "E377: Không cho phép %%%c trong chuỗi định dạng"
+
+msgid "E378: 'errorformat' contains no pattern"
+msgstr "E378: Trong giá trị 'errorformat' thiếu mẫu (pattern)"
+
+msgid "E379: Missing or empty directory name"
+msgstr "E379: Tên thư mục không được đưa ra hoặc bằng một chuỗi rỗng"
+
+msgid "E553: No more items"
+msgstr "E553: Không còn phần tử nào nữa"
+
+#, c-format
+msgid "(%d of %d)%s%s: "
+msgstr "(%d cá»§a %d)%s%s: "
+
+msgid " (line deleted)"
+msgstr " (dòng bị xóa)"
+
+msgid "E380: At bottom of quickfix stack"
+msgstr "E380: Ở dưới của đống sửa nhanh"
+
+msgid "E381: At top of quickfix stack"
+msgstr "E381: Ở đầu của đống sửa nhanh"
+
+#, c-format
+msgid "error list %d of %d; %d errors"
+msgstr "danh sách lỗi %d của %d; %d lỗi"
+
+msgid "E382: Cannot write, 'buftype' option is set"
+msgstr "E382: Không ghi nhớ được, giá trị 'buftype' không phải là chuỗi rỗng"
+
+#, c-format
+msgid "E369: invalid item in %s%%[]"
+msgstr "E369: phần tử không cho phép trong %s%%[]"
+
+msgid "E339: Pattern too long"
+msgstr "E339: Mẫu (pattern) quá dài"
+
+msgid "E50: Too many \\z("
+msgstr "E50: Quá nhiá»u \\z("
+
+#, c-format
+msgid "E51: Too many %s("
+msgstr "E51: Quá nhiá»u %s("
+
+msgid "E52: Unmatched \\z("
+msgstr "E52: Không có cặp cho \\z("
+
+#, c-format
+msgid "E53: Unmatched %s%%("
+msgstr "E53: Không có cặp cho %s%%("
+
+#, c-format
+msgid "E54: Unmatched %s("
+msgstr "E54: Không có cặp cho %s("
+
+#, c-format
+msgid "E55: Unmatched %s)"
+msgstr "E55: Không có cặp cho %s)"
+
+#, c-format
+msgid "E56: %s* operand could be empty"
+msgstr "E56: operand %s* không thể rỗng"
+
+#, c-format
+msgid "E57: %s+ operand could be empty"
+msgstr "E57: operand %s+ không thể rỗng"
+
+#, c-format
+msgid "E59: invalid character after %s@"
+msgstr "E59: ký tự không cho phép sau %s@"
+
+#, c-format
+msgid "E58: %s{ operand could be empty"
+msgstr "E58: operand %s{ không thể rỗng"
+
+#, c-format
+msgid "E60: Too many complex %s{...}s"
+msgstr "E60: Quá nhiá»u cấu trúc phức tạp %s{...}"
+
+#, c-format
+msgid "E61: Nested %s*"
+msgstr "E61: %s* lồng vào"
+
+#, c-format
+msgid "E62: Nested %s%c"
+msgstr "E62: %s%c lồng vào"
+
+msgid "E63: invalid use of \\_"
+msgstr "E63: không cho phép sử dụng \\_"
+
+#, c-format
+msgid "E64: %s%c follows nothing"
+msgstr "E64: %s%c không theo sau gì cả"
+
+msgid "E65: Illegal back reference"
+msgstr "E65: Không cho phép liên kết ngược lại"
+
+msgid "E66: \\z( not allowed here"
+msgstr "E66: \\z( không thể sử dụng ở đây"
+
+msgid "E67: \\z1 et al. not allowed here"
+msgstr "E67: \\z1 và tương tự không được sử dụng ở đây"
+
+msgid "E68: Invalid character after \\z"
+msgstr "E68: Ký tự không cho phép sau \\z"
+
+#, c-format
+msgid "E69: Missing ] after %s%%["
+msgstr "E69: Thiếu ] sau %s%%["
+
+#, c-format
+msgid "E70: Empty %s%%[]"
+msgstr "E70: %s%%[] rá»—ng"
+
+#, c-format
+msgid "E71: Invalid character after %s%%"
+msgstr "E71: Ký tự không cho phép sau %s%%"
+
+#, c-format
+msgid "E554: Syntax error in %s{...}"
+msgstr "E554: Lỗi cú pháp trong %s{...}"
+
+msgid "E361: Crash intercepted; regexp too complex?"
+msgstr "E361: Sự cố được ngăn chặn; biểu thức chính quy quá phức tạp?"
+
+msgid "E363: pattern caused out-of-stack error"
+msgstr "E363: sử dụng mẫu (pattern) gây ra lỗi out-of-stack"
+
+msgid "External submatches:\n"
+msgstr "Sự tương ứng con ngoài:\n"
+
+#, c-format
+msgid "+--%3ld lines folded "
+msgstr "+--%3ld dòng được gấp"
+
+msgid " VREPLACE"
+msgstr " THAY THẾ ẢO"
+
+msgid " REPLACE"
+msgstr " THAY THẾ"
+
+msgid " REVERSE"
+msgstr " NGƯỢC LẠI"
+
+msgid " INSERT"
+msgstr " CHÈN"
+
+msgid " (insert)"
+msgstr " (chèn)"
+
+msgid " (replace)"
+msgstr " (thay thế)"
+
+msgid " (vreplace)"
+msgstr " (thay thế ảo)"
+
+msgid " Hebrew"
+msgstr " Do thái"
+
+msgid " Arabic"
+msgstr " Ả rập"
+
+msgid " (lang)"
+msgstr " (ngôn ngữ)"
+
+msgid " (paste)"
+msgstr " (dán)"
+
+msgid " VISUAL"
+msgstr " CHẾ ÄỘ VISUAL"
+
+msgid " VISUAL LINE"
+msgstr " DÃ’NG VISUAL"
+
+msgid " VISUAL BLOCK"
+msgstr " KHá»I VISUAL"
+
+msgid " SELECT"
+msgstr " LỰA CHỌN"
+
+msgid " SELECT LINE"
+msgstr " LỰA CHỌN DÒNG"
+
+msgid " SELECT BLOCK"
+msgstr " Lá»°A CHỌN KHá»I"
+
+msgid "recording"
+msgstr "đang ghi"
+
+msgid "search hit TOP, continuing at BOTTOM"
+msgstr "tìm kiếm sẽ được tiếp tục từ CUá»I tài liệu"
+
+msgid "search hit BOTTOM, continuing at TOP"
+msgstr "tìm kiếm sẽ được tiếp tục từ ÄẦU tài liệu"
+
+#, c-format
+msgid "E383: Invalid search string: %s"
+msgstr "E383: Chuỗi tìm kiếm không đúng: %s"
+
+#, c-format
+msgid "E384: search hit TOP without match for: %s"
+msgstr "E384: tìm kiếm kết thúc ở ÄẦU tập tin; không tìm thấy %s"
+
+#, c-format
+msgid "E385: search hit BOTTOM without match for: %s"
+msgstr "E385: tìm kiếm kết thúc ở CUá»I tập tin; không tìm thấy %s"
+
+msgid "E386: Expected '?' or '/' after ';'"
+msgstr "E386: Mong đợi nhập '?' hoặc '/' sau ';'"
+
+msgid " (includes previously listed match)"
+msgstr " (gồm cả những tương ứng đã liệt kê trước đây)"
+
+#. cursor at status line
+msgid "--- Included files "
+msgstr "--- Tập tin tính đến "
+
+msgid "not found "
+msgstr "không tìm thấy "
+
+msgid "in path ---\n"
+msgstr "trong đưá»ng dẫn ---\n"
+
+msgid " (Already listed)"
+msgstr " (Äã liệt kê)"
+
+msgid " NOT FOUND"
+msgstr " KHÔNG TÌM THẤY"
+
+#, c-format
+msgid "Scanning included file: %s"
+msgstr "Quét trong tập tin được tính đến: %s"
+
+msgid "E387: Match is on current line"
+msgstr "E387: Tương ứng nằm trên dòng hiện tại"
+
+msgid "All included files were found"
+msgstr "Tìm thấy tất cả các tập tin được tính đến"
+
+msgid "No included files"
+msgstr "Không có tập tin được tính đến"
+
+msgid "E388: Couldn't find definition"
+msgstr "E388: Không tìm thấy định nghĩa"
+
+msgid "E389: Couldn't find pattern"
+msgstr "E389: Không tìm thấy mẫu (pattern)"
+
+#, c-format
+msgid "E390: Illegal argument: %s"
+msgstr "E390: Tham số không cho phép: %s"
+
+#, c-format
+msgid "E391: No such syntax cluster: %s"
+msgstr "E391: Không có cụm cú pháp như vậy: %s"
+
+msgid "No Syntax items defined for this buffer"
+msgstr "Không có phần tử cú pháp nào được định nghĩa cho bộ đệm này"
+
+msgid "syncing on C-style comments"
+msgstr "Äồng bá»™ hóa theo chú thích kiểu C"
+
+msgid "no syncing"
+msgstr "không đồng bộ hóa"
+
+msgid "syncing starts "
+msgstr "đồng bộ hóa bắt đầu "
+
+msgid " lines before top line"
+msgstr " dòng trước dòng đầu tiên"
+
+msgid ""
+"\n"
+"--- Syntax sync items ---"
+msgstr ""
+"\n"
+"--- Phần tử đồng bộ hóa cú pháp ---"
+
+msgid ""
+"\n"
+"syncing on items"
+msgstr ""
+"\n"
+"đồng bộ hóa theo phần tử"
+
+msgid ""
+"\n"
+"--- Syntax items ---"
+msgstr ""
+"\n"
+"--- Phần tử cú pháp ---"
+
+#, c-format
+msgid "E392: No such syntax cluster: %s"
+msgstr "E392: Không có cụm cú pháp như vậy: %s"
+
+msgid "minimal "
+msgstr "nhỠnhất "
+
+msgid "maximal "
+msgstr "lớn nhất "
+
+msgid "; match "
+msgstr "; tương ứng "
+
+msgid " line breaks"
+msgstr " chuyển dòng"
+
+msgid "E393: group[t]here not accepted here"
+msgstr "E393: không được sử dụng group[t]here ở đây"
+
+#, c-format
+msgid "E394: Didn't find region item for %s"
+msgstr "E394: Phần tử vùng cho %s không tìm thấy"
+
+msgid "E395: contains argument not accepted here"
+msgstr "E395: không được sử dụng tham số contains ở đây"
+
+msgid "E396: containedin argument not accepted here"
+msgstr "E396: không được sử dụng tham số containedin ở đây"
+
+msgid "E397: Filename required"
+msgstr "E397: Yêu cầu tên tập tin"
+
+#, c-format
+msgid "E398: Missing '=': %s"
+msgstr "E398: Thiếu '=': %s"
+
+#, c-format
+msgid "E399: Not enough arguments: syntax region %s"
+msgstr "E399: Không đủ tham số: vùng cú pháp %s"
+
+msgid "E400: No cluster specified"
+msgstr "E400: Chưa chỉ ra cụm"
+
+#, c-format
+msgid "E401: Pattern delimiter not found: %s"
+msgstr "E401: Không tìm thấy ký tự phân chia mẫu (pattern): %s"
+
+#, c-format
+msgid "E402: Garbage after pattern: %s"
+msgstr "E402: Rác ở sau mẫu (pattern): %s"
+
+msgid "E403: syntax sync: line continuations pattern specified twice"
+msgstr "E403: đồng bộ hóa cú pháp: mẫu tiếp tục của dòng chỉ ra hai lần"
+
+#, c-format
+msgid "E404: Illegal arguments: %s"
+msgstr "E404: Tham số không cho phép: %s"
+
+#, c-format
+msgid "E405: Missing equal sign: %s"
+msgstr "E405: Thiếu dấu bằng: %s"
+
+#, c-format
+msgid "E406: Empty argument: %s"
+msgstr "E406: Tham số trống rỗng: %s"
+
+#, c-format
+msgid "E407: %s not allowed here"
+msgstr "E407: %s không được cho phép ở đây"
+
+#, c-format
+msgid "E408: %s must be first in contains list"
+msgstr "E408: %s phải là đầu tiên trong danh sách contains"
+
+#, c-format
+msgid "E409: Unknown group name: %s"
+msgstr "E409: Tên nhóm không biết: %s"
+
+#, c-format
+msgid "E410: Invalid :syntax subcommand: %s"
+msgstr "E410: Câu lệnh con :syntax không đúng: %s"
+
+#, c-format
+msgid "E411: highlight group not found: %s"
+msgstr "E411: không tìm thấy nhóm chiếu sáng cú pháp: %s"
+
+#, c-format
+msgid "E412: Not enough arguments: \":highlight link %s\""
+msgstr "E412: Không đủ tham số: \":highlight link %s\""
+
+#, c-format
+msgid "E413: Too many arguments: \":highlight link %s\""
+msgstr "E413: Quá nhiá»u tham số: \":highlight link %s\""
+
+msgid "E414: group has settings, highlight link ignored"
+msgstr "E414: nhóm có thiết lập riêng, chiếu sáng liên kết bị bỠqua"
+
+#, c-format
+msgid "E415: unexpected equal sign: %s"
+msgstr "E415: dấu bằng không được mong đợi: %s"
+
+#, c-format
+msgid "E416: missing equal sign: %s"
+msgstr "E416: thiếu dấu bằng: %s"
+
+#, c-format
+msgid "E417: missing argument: %s"
+msgstr "E417: thiếu tham số: %s"
+
+#, c-format
+msgid "E418: Illegal value: %s"
+msgstr "E418: Giá trị không cho phép: %s"
+
+msgid "E419: FG color unknown"
+msgstr "E419: Không rõ màu văn bản (FG)"
+
+msgid "E420: BG color unknown"
+msgstr "E420: Không rõ màu ná»n sau (BG)"
+
+#, c-format
+msgid "E421: Color name or number not recognized: %s"
+msgstr "E421: Tên hoặc số của màu không được nhận ra: %s"
+
+#, c-format
+msgid "E422: terminal code too long: %s"
+msgstr "E422: mã terminal quá dài: %s"
+
+#, c-format
+msgid "E423: Illegal argument: %s"
+msgstr "E423: Tham số không cho phép: %s"
+
+msgid "E424: Too many different highlighting attributes in use"
+msgstr "E424: Sá»­ dụng quá nhiá»u thuá»™c tính chiếu sáng cú pháp"
+
+msgid "E669: Unprintable character in group name"
+msgstr "E669: Ký tự không thể tin ra trong tên nhóm"
+
+#. This is an error, but since there previously was no check only
+#. * give a warning.
+msgid "W18: Invalid character in group name"
+msgstr "W18: Ký tự không cho phép trong tên nhóm"
+
+msgid "E555: at bottom of tag stack"
+msgstr "E555: ở cuối đống thẻ ghi"
+
+msgid "E556: at top of tag stack"
+msgstr "E556: ở đầu đống thẻ ghi"
+
+msgid "E425: Cannot go before first matching tag"
+msgstr "E425: Không chuyển được tới vị trí ở trước thẻ ghi tương ứng đầu tiên"
+
+#, c-format
+msgid "E426: tag not found: %s"
+msgstr "E426: không tìm thấy thẻ ghi: %s"
+
+msgid " # pri kind tag"
+msgstr " # pri loại thẻ ghi"
+
+msgid "file\n"
+msgstr "tập tin\n"
+
+#.
+#. * Ask to select a tag from the list.
+#. * When using ":silent" assume that <CR> was entered.
+#.
+msgid "Enter nr of choice (<CR> to abort): "
+msgstr "Hãy chá»n số cần thiết (<CR> để dừng):"
+
+msgid "E427: There is only one matching tag"
+msgstr "E427: Chỉ có một thẻ ghi tương ứng"
+
+msgid "E428: Cannot go beyond last matching tag"
+msgstr "E428: Không chuyển được tới vị trí ở sau thẻ ghi tương ứng cuối cùng"
+
+#, c-format
+msgid "File \"%s\" does not exist"
+msgstr "Tập tin \"%s\" không tồn tại"
+
+#. Give an indication of the number of matching tags
+#, c-format
+msgid "tag %d of %d%s"
+msgstr "thẻ ghi %d của %d%s"
+
+msgid " or more"
+msgstr " và hơn nữa"
+
+msgid " Using tag with different case!"
+msgstr " Äang sá»­ dụng thẻ ghi vá»›i kiểu chữ khác!"
+
+#, c-format
+msgid "E429: File \"%s\" does not exist"
+msgstr "E429: Tập tin \"%s\" không tồn tại"
+
+#. Highlight title
+msgid ""
+"\n"
+" # TO tag FROM line in file/text"
+msgstr ""
+"\n"
+" # TỚI thẻ ghi TỪ dòng trong tập tin/văn bản"
+
+#, c-format
+msgid "Searching tags file %s"
+msgstr "Tìm kiếm tập tin thẻ ghi %s"
+
+#, c-format
+msgid "E430: Tag file path truncated for %s\n"
+msgstr "E430: ÄÆ°á»ng dẫn tá»›i tập tin thẻ ghi bị cắt bá»›t cho %s\n"
+
+#, c-format
+msgid "E431: Format error in tags file \"%s\""
+msgstr "E431: Lỗi định dạng trong tập tin thẻ ghi \"%s\""
+
+#, c-format
+msgid "Before byte %ld"
+msgstr "Trước byte %ld"
+
+#, c-format
+msgid "E432: Tags file not sorted: %s"
+msgstr "E432: Tập tin thẻ ghi chưa được sắp xếp: %s"
+
+#. never opened any tags file
+msgid "E433: No tags file"
+msgstr "E433: Không có tập tin thẻ ghi"
+
+msgid "E434: Can't find tag pattern"
+msgstr "E434: Không tìm thấy mẫu thẻ ghi"
+
+msgid "E435: Couldn't find tag, just guessing!"
+msgstr "E435: Không tìm thấy thẻ ghi, đang thử đoán!"
+
+msgid "' not known. Available builtin terminals are:"
+msgstr "' không rõ. Có các terminal gắn sẵn (builtin) sau:"
+
+msgid "defaulting to '"
+msgstr "theo mặc định '"
+
+msgid "E557: Cannot open termcap file"
+msgstr "E557: Không thể mở tập tin termcap"
+
+msgid "E558: Terminal entry not found in terminfo"
+msgstr "E558: Trong terminfo không có bản ghi nào vỠterminal này"
+
+msgid "E559: Terminal entry not found in termcap"
+msgstr "E559: Trong termcap không có bản ghi nào vỠterminal này"
+
+#, c-format
+msgid "E436: No \"%s\" entry in termcap"
+msgstr "E436: Trong termcap không có bản ghi \"%s\""
+
+msgid "E437: terminal capability \"cm\" required"
+msgstr "E437: cần khả năng của terminal \"cm\""
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Terminal keys ---"
+msgstr ""
+"\n"
+"--- Phím terminal ---"
+
+msgid "new shell started\n"
+msgstr "đã chạy shell mới\n"
+
+msgid "Vim: Error reading input, exiting...\n"
+msgstr "Vim: Lá»—i Ä‘á»c dữ liệu nhập, thoát...\n"
+
+#. must display the prompt
+msgid "No undo possible; continue anyway"
+msgstr "Không thể hủy thao tác; tiếp tục thực hiện"
+
+msgid "E438: u_undo: line numbers wrong"
+msgstr "E438: u_undo: số thứ tự dòng không đúng"
+
+msgid "1 change"
+msgstr "duy nhất 1 thay đổi"
+
+#, c-format
+msgid "%ld changes"
+msgstr "%ld thay đổi"
+
+msgid "E439: undo list corrupt"
+msgstr "E439: danh sách há»§y thao tác (undo) bị há»ng"
+
+msgid "E440: undo line missing"
+msgstr "E440: bị mất dòng hủy thao tác"
+
+#. Only MS VC 4.1 and earlier can do Win32s
+msgid ""
+"\n"
+"MS-Windows 16/32-bit GUI version"
+msgstr ""
+"\n"
+"Phiên bản vá»›i giao diện đồ há»a GUI cho MS-Windows 16/32 bit"
+
+msgid ""
+"\n"
+"MS-Windows 32-bit GUI version"
+msgstr ""
+"\n"
+"Phiên bản vá»›i giao diện đồ há»a GUI cho MS-Windows 32 bit"
+
+msgid " in Win32s mode"
+msgstr " trong chế độ Win32"
+
+msgid " with OLE support"
+msgstr " với hỗ trợ OLE"
+
+msgid ""
+"\n"
+"MS-Windows 32-bit console version"
+msgstr ""
+"\n"
+"Phiên bản console cho MS-Windows 32 bit"
+
+msgid ""
+"\n"
+"MS-Windows 16-bit version"
+msgstr ""
+"\n"
+"Phiên bản cho MS-Windows 16 bit"
+
+msgid ""
+"\n"
+"32-bit MS-DOS version"
+msgstr ""
+"\n"
+"Phiên bản cho MS-DOS 32 bit"
+
+msgid ""
+"\n"
+"16-bit MS-DOS version"
+msgstr ""
+"\n"
+"Phiên bản cho MS-DOS 16 bit"
+
+msgid ""
+"\n"
+"MacOS X (unix) version"
+msgstr ""
+"\n"
+"Phiên bản cho MacOS X (unix)"
+
+msgid ""
+"\n"
+"MacOS X version"
+msgstr ""
+"\n"
+"Phiên bản cho MacOS X"
+
+msgid ""
+"\n"
+"MacOS version"
+msgstr ""
+"\n"
+"Phiên bản cho MacOS"
+
+msgid ""
+"\n"
+"RISC OS version"
+msgstr ""
+"\n"
+"Phiên bản cho RISC OS"
+
+msgid ""
+"\n"
+"Included patches: "
+msgstr ""
+"\n"
+"Bao gồm các bản vá lỗi: "
+
+msgid "Modified by "
+msgstr "Với các thay đổi bởi "
+
+msgid ""
+"\n"
+"Compiled "
+msgstr ""
+"\n"
+"ÄÆ°á»£c biên dịch "
+
+msgid "by "
+msgstr "bởi "
+
+msgid ""
+"\n"
+"Huge version "
+msgstr ""
+"\n"
+"Phiên bản khổng lồ "
+
+msgid ""
+"\n"
+"Big version "
+msgstr ""
+"\n"
+"Phiên bản lớn "
+
+msgid ""
+"\n"
+"Normal version "
+msgstr ""
+"\n"
+"Phiên bản thông thưá»ng "
+
+msgid ""
+"\n"
+"Small version "
+msgstr ""
+"\n"
+"Phiên bản nhỠ"
+
+msgid ""
+"\n"
+"Tiny version "
+msgstr ""
+"\n"
+"Phiên bản \"tí hon\" "
+
+msgid "without GUI."
+msgstr "không có giao diện đồ há»a GUI."
+
+msgid "with GTK2-GNOME GUI."
+msgstr "vá»›i giao diện đồ há»a GUI GTK2-GNOME."
+
+msgid "with GTK-GNOME GUI."
+msgstr "vá»›i giao diện đồ há»a GUI GTK-GNOME."
+
+msgid "with GTK2 GUI."
+msgstr "vá»›i giao diện đồ há»a GUI GTK2."
+
+msgid "with GTK GUI."
+msgstr "vá»›i giao diện đồ há»a GUI GTK."
+
+msgid "with X11-Motif GUI."
+msgstr "vá»›i giao diện đồ há»a GUI X11-Motif."
+
+msgid "with X11-neXtaw GUI."
+msgstr "vá»›i giao diện đồ há»a GUI X11-neXtaw."
+
+msgid "with X11-Athena GUI."
+msgstr "vá»›i giao diện đồ há»a GUI X11-Athena."
+
+msgid "with BeOS GUI."
+msgstr "vá»›i giao diện đồ há»a GUI BeOS."
+
+msgid "with Photon GUI."
+msgstr "vá»›i giao diện đồ há»a GUI Photon."
+
+msgid "with GUI."
+msgstr "vá»›i giao diện đồ há»a GUI."
+
+msgid "with Carbon GUI."
+msgstr "vá»›i giao diện đồ há»a GUI Carbon."
+
+msgid "with Cocoa GUI."
+msgstr "vá»›i giao diện đồ há»a GUI Cocoa."
+
+msgid "with (classic) GUI."
+msgstr "vá»›i giao diện đồ há»a (cổ Ä‘iển) GUI."
+
+msgid " Features included (+) or not (-):\n"
+msgstr " Tính năng có (+) hoặc không (-):\n"
+
+msgid " system vimrc file: \""
+msgstr " tập tin vimrc chung cho hệ thống: \""
+
+msgid " user vimrc file: \""
+msgstr " tập tin vimrc cá»§a ngưá»i dùng: \""
+
+msgid " 2nd user vimrc file: \""
+msgstr " tập tin vimrc thứ hai cá»§a ngưá»i dùng: \""
+
+msgid " 3rd user vimrc file: \""
+msgstr " tập tin vimrc thứ ba cá»§a ngưá»i dùng: \""
+
+msgid " user exrc file: \""
+msgstr " tập tin exrc cá»§a ngưá»i dùng: \""
+
+msgid " 2nd user exrc file: \""
+msgstr " tập tin exrc thứ hai cá»§a ngưá»i dùng: \""
+
+msgid " system gvimrc file: \""
+msgstr " tập tin gvimrc chung cho hệ thống: \""
+
+msgid " user gvimrc file: \""
+msgstr " tập tin gvimrc cá»§a ngưá»i dùng: \""
+
+msgid "2nd user gvimrc file: \""
+msgstr " tập tin gvimrc thứ hai cá»§a ngưá»i dùng: \""
+
+msgid "3rd user gvimrc file: \""
+msgstr " tập tin gvimrc thứ ba cá»§a ngưá»i dùng: \""
+
+msgid " system menu file: \""
+msgstr " tập tin trình đơn chung cho hệ thống: \""
+
+msgid " fall-back for $VIM: \""
+msgstr " giá trị $VIM theo mặc định: \""
+
+msgid " f-b for $VIMRUNTIME: \""
+msgstr " giá trị $VIMRUNTIME theo mặc định: \""
+
+msgid "Compilation: "
+msgstr "Tham số biên dịch: "
+
+msgid "Compiler: "
+msgstr "Trình biên dịch: "
+
+msgid "Linking: "
+msgstr "Liên kết: "
+
+msgid " DEBUG BUILD"
+msgstr " BIÊN DỊCH SỬA LỖI (DEBUG)"
+
+msgid "VIM - Vi IMproved"
+msgstr "VIM ::: Vi IMproved (Vi cải tiến) ::: Phiên bản tiếng Việt"
+
+msgid "version "
+msgstr "phiên bản "
+
+msgid "by Bram Moolenaar et al."
+msgstr "Do Bram Moolenaar và những ngưá»i khác thá»±c hiện"
+
+msgid "Vim is open source and freely distributable"
+msgstr "Vim là chương trình mã nguồn mở và phân phối tự do"
+
+msgid "Help poor children in Uganda!"
+msgstr "Hãy giúp đỡ trẻ em nghèo Uganda!"
+
+msgid "type :help iccf<Enter> for information "
+msgstr "hãy gõ :help iccf<Enter> để biết thêm thông tin"
+
+msgid "type :q<Enter> to exit "
+msgstr " hãy gõ :q<Enter> để thoát khá»i chương trình "
+
+msgid "type :help<Enter> or <F1> for on-line help"
+msgstr " hãy gõ :help<Enter> hoặc <F1> để có được trợ giúp "
+
+msgid "type :help version7<Enter> for version info"
+msgstr "hãy gõ :help version7<Enter> để biết vỠphiên bản này "
+
+msgid "Running in Vi compatible mode"
+msgstr "Làm việc trong chế độ tương thích với Vi"
+
+msgid "type :set nocp<Enter> for Vim defaults"
+msgstr "hãy gõ :set nocp<Enter> để chuyển vào chế độ Vim "
+
+msgid "type :help cp-default<Enter> for info on this"
+msgstr "hãy gõ :help cp-default<Enter> để có thêm thông tin vá» Ä‘iá»u này"
+
+msgid "menu Help->Orphans for information "
+msgstr "trình đơn Trợ giúp->Mồ côi để có thêm thông tin "
+
+msgid "Running modeless, typed text is inserted"
+msgstr "Không chế độ, văn bản nhập vào sẽ được chèn"
+
+msgid "menu Edit->Global Settings->Toggle Insert Mode "
+msgstr "trình đơn Soạn thảo->Thiết lập chung->Chế độ chèn "
+
+msgid " for two modes "
+msgstr " cho hai chế độ "
+
+msgid "menu Edit->Global Settings->Toggle Vi Compatible"
+msgstr ""
+"trình đơn Soạn thảo->Thiết lập chung->Tương thích với Vi "
+
+msgid " for Vim defaults "
+msgstr ""
+" để chuyển vào chế độ Vim mặc định "
+
+msgid "Sponsor Vim development!"
+msgstr "Hãy giúp đỡ phát triển Vim!"
+
+msgid "Become a registered Vim user!"
+msgstr "Hãy trở thành ngưá»i dùng đăng ký cá»§a Vim!"
+
+msgid "type :help sponsor<Enter> for information "
+msgstr "hãy gõ :help sponsor<Enter> để biết thêm thông tin "
+
+msgid "type :help register<Enter> for information "
+msgstr "hãy gõ :help register<Enter> để biết thêm thông tin "
+
+msgid "menu Help->Sponsor/Register for information "
+msgstr "trình đơn Trợ giúp->Giúp đỡ/Äăng ký để biết thêm thông tin "
+
+msgid "WARNING: Windows 95/98/ME detected"
+msgstr "CẢNH BÃO: nhận ra Windows 95/98/ME"
+
+msgid "type :help windows95<Enter> for info on this"
+msgstr "hãy gõ :help windows95<Enter> để biết thêm thông tin "
+
+msgid "E441: There is no preview window"
+msgstr "E441: Không có cửa sổ xem trước"
+
+msgid "E442: Can't split topleft and botright at the same time"
+msgstr ""
+"E442: Cá»­a sổ không thể đồng thá»i ở bên trái phía trên và bên phải phía dưới"
+
+msgid "E443: Cannot rotate when another window is split"
+msgstr "E443: Không đổi được chỗ khi cửa sổ khác được chia"
+
+msgid "E444: Cannot close last window"
+msgstr "E444: Không được đóng cửa sổ cuối cùng"
+
+msgid "Already only one window"
+msgstr "Chỉ có một cửa sổ"
+
+msgid "E445: Other window contains changes"
+msgstr "E445: Cửa sổ khác có thay đổi chưa được ghi nhớ"
+
+msgid "E446: No file name under cursor"
+msgstr "E446: Không có tên tập tin tại vị trí con trá»"
+
+#, c-format
+msgid "E447: Can't find file \"%s\" in path"
+msgstr "E447: Không tìm thấy tập tin \"%s\" trong đưá»ng dẫn"
+
+#, c-format
+msgid "E370: Could not load library %s"
+msgstr "E370: Không nạp được thư viện %s"
+
+msgid "Sorry, this command is disabled: the Perl library could not be loaded."
+msgstr "Xin lỗi, câu lệnh này bị tắt: không nạp được thư viện Perl."
+
+msgid "E299: Perl evaluation forbidden in sandbox without the Safe module"
+msgstr ""
+"E299: Không cho phép sự tính toán Perl trong hộp cát mà không có môđun An "
+"toàn"
+
+msgid "Edit with &multiple Vims"
+msgstr "Soạn thảo trong nhiá»u Vi&m"
+
+msgid "Edit with single &Vim"
+msgstr "Soạn thảo trong một &Vim"
+
+msgid "&Diff with Vim"
+msgstr "&So sánh (diff) qua Vim"
+
+msgid "Edit with &Vim"
+msgstr "Soạn thảo trong &Vim"
+
+#. Now concatenate
+msgid "Edit with existing Vim - &"
+msgstr "Soạn thảo trong Vim đã chạy - &"
+
+msgid "Edits the selected file(s) with Vim"
+msgstr "Soạn thảo (các) tập tin đã chá»n trong Vim"
+
+msgid "Error creating process: Check if gvim is in your path!"
+msgstr "Lá»—i tạo tiến trình: Hãy kiểm tra xem gvim có trong đưá»ng dẫn không!"
+
+msgid "gvimext.dll error"
+msgstr "lá»—i gvimext.dll"
+
+msgid "Path length too long!"
+msgstr "ÄÆ°á»ng dẫn quá dài!"
+
+msgid "--No lines in buffer--"
+msgstr "-- Không có dòng nào trong bộ đệm --"
+
+#.
+#. * 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: Câu lệnh bị dừng"
+
+msgid "E471: Argument required"
+msgstr "E471: Cần chỉ ra tham số"
+
+msgid "E10: \\ should be followed by /, ? or &"
+msgstr "E10: Sau \\ phải là các ký tự /, ? hoặc &"
+
+msgid "E11: Invalid in command-line window; <CR> executes, CTRL-C quits"
+msgstr "E11: Lỗi trong cửa sổ dòng lệnh; <CR> thực hiện, CTRL-C thoát"
+
+msgid "E12: Command not allowed from exrc/vimrc in current dir or tag search"
+msgstr ""
+"E12: Câu lệnh không cho phép từ exrc/vimrc trong thư mục hiện thá»i hoặc "
+"trong tìm kiếm thẻ ghi"
+
+msgid "E171: Missing :endif"
+msgstr "E171: Thiếu câu lệnh :endif"
+
+msgid "E600: Missing :endtry"
+msgstr "E600: Thiếu câu lệnh :endtry"
+
+msgid "E170: Missing :endwhile"
+msgstr "E170: Thiếu câu lệnh :endwhile"
+
+msgid "E588: :endwhile without :while"
+msgstr "E588: Câu lệnh :endwhile không có lệnh :while (1 cặp)"
+
+msgid "E13: File exists (add ! to override)"
+msgstr "E13: Tập tin đã tồn tại (thêm ! để ghi chèn)"
+
+msgid "E472: Command failed"
+msgstr "E472: Không thực hiện thành công câu lệnh"
+
+#, c-format
+msgid "E234: Unknown fontset: %s"
+msgstr "E234: Không rõ bộ phông chữ: %s"
+
+#, c-format
+msgid "E235: Unknown font: %s"
+msgstr "E235: Không rõ phông chữ: %s"
+
+#, c-format
+msgid "E236: Font \"%s\" is not fixed-width"
+msgstr "E236: Phông chữ \"%s\" không có độ rộng cố định (fixed-width)"
+
+msgid "E473: Internal error"
+msgstr "E473: Lá»—i ná»™i bá»™"
+
+msgid "Interrupted"
+msgstr "Bị gián đoạn"
+
+msgid "E14: Invalid address"
+msgstr "E14: Äịa chỉ không cho phép"
+
+msgid "E474: Invalid argument"
+msgstr "E474: Tham số không cho phép"
+
+#, c-format
+msgid "E475: Invalid argument: %s"
+msgstr "E475: Tham số không cho phép: %s"
+
+#, c-format
+msgid "E15: Invalid expression: %s"
+msgstr "E15: Biểu thức không cho phép: %s"
+
+msgid "E16: Invalid range"
+msgstr "E16: Vùng không cho phép"
+
+msgid "E476: Invalid command"
+msgstr "E476: Câu lệnh không cho phép"
+
+#, c-format
+msgid "E17: \"%s\" is a directory"
+msgstr "E17: \"%s\" là mộ thư mục"
+
+msgid "E18: Unexpected characters before '='"
+msgstr "E18: Ở trước '=' có các ký tự không mong đợi"
+
+#, c-format
+msgid "E364: Library call failed for \"%s()\""
+msgstr "E364: Gá»i hàm số \"%s()\" cá»§a thư viện không thành công"
+
+#, c-format
+msgid "E448: Could not load library function %s"
+msgstr "E448: Nạp hàm số %s của thư viện không thành công"
+
+msgid "E19: Mark has invalid line number"
+msgstr "E19: Dấu hiệu chỉ đến một số thứ tự dòng không đúng"
+
+msgid "E20: Mark not set"
+msgstr "E20: Dấu hiệu không được xác định"
+
+msgid "E21: Cannot make changes, 'modifiable' is off"
+msgstr "E21: Không thể thay đổi, vì tùy chá»n 'modifiable' bị tắt"
+
+msgid "E22: Scripts nested too deep"
+msgstr "E22: Các script lồng vào nhau quá sâu"
+
+msgid "E23: No alternate file"
+msgstr "E23: Không có tập tin xen kẽ"
+
+msgid "E24: No such abbreviation"
+msgstr "E24: Không có chữ viết tắt như vậy"
+
+msgid "E477: No ! allowed"
+msgstr "E477: Không cho phép !"
+
+msgid "E25: GUI cannot be used: Not enabled at compile time"
+msgstr "E25: Không sá»­ dụng được giao diện đồ há»a vì không chá»n khi biên dịch"
+
+msgid "E26: Hebrew cannot be used: Not enabled at compile time\n"
+msgstr "E26: Tiếng Do thái không được chá»n khi biên dịch\n"
+
+msgid "E27: Farsi cannot be used: Not enabled at compile time\n"
+msgstr "E27: Tiếng Farsi không được chá»n khi biên dịch\n"
+
+msgid "E800: Arabic cannot be used: Not enabled at compile time\n"
+msgstr "E800: Tiếng Ả Rập không được chá»n khi biên dịch\n"
+
+#, c-format
+msgid "E28: No such highlight group name: %s"
+msgstr "E28: Nhóm chiếu sáng cú pháp %s không tồn tại"
+
+msgid "E29: No inserted text yet"
+msgstr "E29: Tạm thá»i chưa có văn bản được chèn"
+
+msgid "E30: No previous command line"
+msgstr "E30: Không có dòng lệnh trước"
+
+msgid "E31: No such mapping"
+msgstr "E31: Không có ánh xạ (mapping) như vậy"
+
+msgid "E479: No match"
+msgstr "E479: Không có tương ứng"
+
+#, c-format
+msgid "E480: No match: %s"
+msgstr "E480: Không có tương ứng: %s"
+
+msgid "E32: No file name"
+msgstr "E32: Không có tên tập tin"
+
+msgid "E33: No previous substitute regular expression"
+msgstr "E33: Không có biểu thức chính quy trước để thay thế"
+
+msgid "E34: No previous command"
+msgstr "E34: Không có câu lệnh trước"
+
+msgid "E35: No previous regular expression"
+msgstr "E35: Không có biểu thức chính quy trước"
+
+msgid "E481: No range allowed"
+msgstr "E481: Không cho phép sử dụng phạm vi"
+
+msgid "E36: Not enough room"
+msgstr "E36: Không đủ chỗ trống"
+
+#, c-format
+msgid "E247: no registered server named \"%s\""
+msgstr "E247: máy chủ \"%s\" chưa đăng ký"
+
+#, c-format
+msgid "E482: Can't create file %s"
+msgstr "E482: Không tạo được tập tin %s"
+
+msgid "E483: Can't get temp file name"
+msgstr "E483: Không nhận được tên tập tin tạm thá»i (temp)"
+
+#, c-format
+msgid "E484: Can't open file %s"
+msgstr "E484: Không mở được tập tin %s"
+
+#, c-format
+msgid "E485: Can't read file %s"
+msgstr "E485: Không Ä‘á»c được tập tin %s"
+
+msgid "E37: No write since last change (add ! to override)"
+msgstr "E37: Thay đổi chưa được ghi nhớ (thêm ! để bỠqua ghi nhớ)"
+
+msgid "E38: Null argument"
+msgstr "E38: Tham sô bằng 0"
+
+msgid "E39: Number expected"
+msgstr "E39: Yêu cầu một số"
+
+#, c-format
+msgid "E40: Can't open errorfile %s"
+msgstr "E40: Không mở được tập tin lỗi %s"
+
+msgid "E233: cannot open display"
+msgstr "E233: không mở được màn hình"
+
+msgid "E41: Out of memory!"
+msgstr "E41: Không đủ bộ nhớ!"
+
+msgid "Pattern not found"
+msgstr "Không tìm thấy mẫu (pattern)"
+
+#, c-format
+msgid "E486: Pattern not found: %s"
+msgstr "E486: Không tìm thấy mẫu (pattern): %s"
+
+msgid "E487: Argument must be positive"
+msgstr "E487: Tham số phải là một số dương"
+
+msgid "E459: Cannot go back to previous directory"
+msgstr "E459: Không quay lại được thư mục trước đó"
+
+msgid "E42: No Errors"
+msgstr "E42: Không có lỗi"
+
+msgid "E43: Damaged match string"
+msgstr "E43: Chuá»—i tương ứng bị há»ng"
+
+msgid "E44: Corrupted regexp program"
+msgstr "E44: Chương trình xá»­ lý biểu thức chính quy bị há»ng"
+
+msgid "E45: 'readonly' option is set (add ! to override)"
+msgstr "E45: Tùy chá»n 'readonly' được bật (Hãy thêm ! để lá» Ä‘i)"
+
+#, c-format
+msgid "E46: Cannot set read-only variable \"%s\""
+msgstr "E46: Không thay đổi được biến chỉ Ä‘á»c \"%s\""
+
+msgid "E47: Error while reading errorfile"
+msgstr "E47: Lá»—i khi Ä‘á»c tập tin lá»—i"
+
+msgid "E48: Not allowed in sandbox"
+msgstr "E48: Không cho phép trong hộp cát (sandbox)"
+
+msgid "E523: Not allowed here"
+msgstr "E523: Không cho phép ở đây"
+
+msgid "E359: Screen mode setting not supported"
+msgstr "E359: Chế độ màn hình không được hỗ trợ"
+
+msgid "E49: Invalid scroll size"
+msgstr "E49: Kích thước thanh cuộn không cho phép"
+
+msgid "E91: 'shell' option is empty"
+msgstr "E91: Tùy chá»n 'shell' là má»™t chuá»—i rá»—ng"
+
+msgid "E255: Couldn't read in sign data!"
+msgstr "E255: Không Ä‘á»c được dữ liệu vá» ký tá»±!"
+
+msgid "E72: Close error on swap file"
+msgstr "E72: Lỗi đóng tập tin trao đổi (swap)"
+
+msgid "E73: tag stack empty"
+msgstr "E73: đống thẻ ghi rỗng"
+
+msgid "E74: Command too complex"
+msgstr "E74: Câu lệnh quá phức tạp"
+
+msgid "E75: Name too long"
+msgstr "E75: Tên quá dài"
+
+msgid "E76: Too many ["
+msgstr "E76: Quá nhiá»u ký tá»± ["
+
+msgid "E77: Too many file names"
+msgstr "E77: Quá nhiá»u tên tập tin"
+
+msgid "E488: Trailing characters"
+msgstr "E488: Ký tự thừa ở đuôi"
+
+msgid "E78: Unknown mark"
+msgstr "E78: Dấu hiệu không biết"
+
+msgid "E79: Cannot expand wildcards"
+msgstr "E79: Không thực hiện được phép thế theo wildcard"
+
+msgid "E591: 'winheight' cannot be smaller than 'winminheight'"
+msgstr "E591: giá trị của 'winheight' không thể nhỠhơn 'winminheight'"
+
+msgid "E592: 'winwidth' cannot be smaller than 'winminwidth'"
+msgstr "E592: giá trị của 'winwidth' không thể nhỠhơn 'winminwidth'"
+
+msgid "E80: Error while writing"
+msgstr "E80: Lá»—i khi ghi nhá»›"
+
+msgid "Zero count"
+msgstr "Giá trị của bộ đếm bằng 0"
+
+msgid "E81: Using <SID> not in a script context"
+msgstr "E81: Sử dụng <SID> ngoài phạm vi script"
+
+msgid "E449: Invalid expression received"
+msgstr "E449: Nhận được một biểu thức không cho phép"
+
+msgid "E463: Region is guarded, cannot modify"
+msgstr "E463: Không thể thay đổi vùng đã được bảo vệ"
diff --git a/src/po/zh_CN.UTF-8.po b/src/po/zh_CN.UTF-8.po
new file mode 100644
index 0000000000..419913abd0
--- /dev/null
+++ b/src/po/zh_CN.UTF-8.po
@@ -0,0 +1,6139 @@
+# 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: 2006-04-21 15:16+0800\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"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8-bit\n"
+
+msgid "E82: Cannot allocate any buffer, exiting..."
+msgstr "E82: 无法分é…任何缓冲区,退出程åº..."
+
+msgid "E83: Cannot allocate buffer, using other one..."
+msgstr "E83: 无法分é…缓冲区,使用å¦ä¸€ä¸ªç¼“冲区..."
+
+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 "E84: No modified buffer found"
+msgstr "E84: 没有修改过的缓冲区"
+
+#. back where we started, didn't find anything.
+msgid "E85: There is no listed buffer"
+msgstr "E85: 没有å¯åˆ—出的缓冲区"
+
+#, c-format
+msgid "E86: Buffer %ld does not exist"
+msgstr "E86: 缓冲区 %ld ä¸å­˜åœ¨"
+
+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 "E90: Cannot unload last buffer"
+msgstr "E90: 无法释放最åŽä¸€ä¸ªç¼“冲区"
+
+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 "[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 "[未命å]"
+
+#. must be a help buffer
+msgid "help"
+msgstr "帮助"
+
+msgid "[Help]"
+msgstr "[帮助]"
+
+msgid "[Preview]"
+msgstr "[预览]"
+
+msgid "All"
+msgstr "全部"
+
+msgid "Bot"
+msgstr "底端"
+
+msgid "Top"
+msgstr "顶端"
+
+#, c-format
+msgid ""
+"\n"
+"# Buffer list:\n"
+msgstr ""
+"\n"
+"# 缓冲区列表:\n"
+
+msgid "[Location List]"
+msgstr "[Location 列表]"
+
+msgid "[Quickfix List]"
+msgstr "[Quickfix 列表]"
+
+msgid ""
+"\n"
+"--- Signs ---"
+msgstr ""
+"\n"
+"--- Signs ---"
+
+#, c-format
+msgid "Signs for %s:"
+msgstr "%s çš„ Signs:"
+
+#, c-format
+msgid " line=%ld id=%d name=%s"
+msgstr " 行=%ld id=%d åç§°=%s"
+
+#, c-format
+msgid "E96: Can not diff more than %ld buffers"
+msgstr "E96: ä¸èƒ½æ¯”较(diff) %ld 个以上的缓冲区"
+
+msgid "E97: Cannot create diffs"
+msgstr "E97: 无法创建 diff"
+
+msgid "Patch file"
+msgstr "Patch 文件"
+
+msgid "E98: Cannot read diff output"
+msgstr "E98: æ— æ³•è¯»å– diff 的输出"
+
+msgid "E99: Current buffer is not in diff mode"
+msgstr "E99: 当å‰ç¼“冲区ä¸åœ¨ 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: å¤åˆå­—符(digraph)中ä¸èƒ½ä½¿ç”¨ Escape"
+
+msgid "E544: Keymap file not found"
+msgstr "E544: 找ä¸åˆ° Keymap 文件"
+
+msgid "E105: Using :loadkeymap not in a sourced file"
+msgstr "E105: 䏿˜¯åœ¨è„šæœ¬æ–‡ä»¶ä¸­ä½¿ç”¨ :loadkeymap "
+
+msgid " Keyword completion (^N^P)"
+msgstr " 关键字补全 (^N^P)"
+
+#. ctrl_x_mode == 0, ^P/^N compl.
+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 " Tag 补全 (^]^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 " Dictionary 补全 (^K^N^P)"
+
+msgid " Thesaurus completion (^T^N^P)"
+msgstr " Thesaurus 补全 (^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 " 全能补全 (^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 "'dictionary' option is empty"
+msgstr "选项 'dictionary' 为空"
+
+msgid "'thesaurus' option is empty"
+msgstr "选项 'thesaurus' 为空"
+
+#, c-format
+msgid "Scanning dictionary: %s"
+msgstr "正在扫æ dictionary: %s"
+
+msgid " (insert) Scroll (^E/^Y)"
+msgstr " (æ’å…¥) Scroll (^E/^Y)"
+
+msgid " (replace) Scroll (^E/^Y)"
+msgstr " (替æ¢) Scroll (^E/^Y)"
+
+#, c-format
+msgid "Scanning: %s"
+msgstr "正在扫æ: %s"
+
+#, c-format
+msgid "Scanning tags."
+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.
+#.
+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 "E684: list index out of range: %ld"
+msgstr "E684: List 索引超出范围: %ld"
+
+#, c-format
+msgid "E121: Undefined variable: %s"
+msgstr "E121: 未定义的å˜é‡: %s"
+
+msgid "E111: Missing ']'"
+msgstr "E111: 缺少 ']'"
+
+#, c-format
+msgid "E686: Argument of %s must be a List"
+msgstr "E686: %s çš„å‚æ•°å¿…须是 List"
+
+#, c-format
+msgid "E712: Argument of %s must be a List or Dictionary"
+msgstr "E712: %s çš„å‚æ•°å¿…须是 List 或者 Dictionary"
+
+msgid "E713: Cannot use empty key for Dictionary"
+msgstr "E713: Dictionary 的键ä¸èƒ½ä¸ºç©º"
+
+msgid "E714: List required"
+msgstr "E714: éœ€è¦ List"
+
+msgid "E715: Dictionary required"
+msgstr "E715: éœ€è¦ Dictionary"
+
+#, 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: Dictionary 中ä¸å­˜åœ¨é”®: %s"
+
+#, c-format
+msgid "E122: Function %s already exists, add ! to replace it"
+msgstr "E122: 函数 %s 已存在,请加 ! 强制替æ¢"
+
+msgid "E717: Dictionary entry already exists"
+msgstr "E717: Dictionary 项已存在"
+
+msgid "E718: Funcref required"
+msgstr "E718: éœ€è¦ Funcref"
+
+msgid "E719: Cannot use [:] with a Dictionary"
+msgstr "E719: ä¸èƒ½å¯¹ Dictionary 使用 [:]"
+
+#, c-format
+msgid "E734: Wrong variable type for %s="
+msgstr "E734: %s= çš„å˜é‡ç±»åž‹ä¸æ­£ç¡®"
+
+#, c-format
+msgid "E130: Unknown function: %s"
+msgstr "E130: 未知的函数: %s"
+
+#, c-format
+msgid "E461: Illegal variable name: %s"
+msgstr "E461: 无效的å˜é‡å: %s"
+
+msgid "E687: Less targets than List items"
+msgstr "E687: 目标比 List 项数少"
+
+msgid "E688: More targets than List items"
+msgstr "E688: 目标比 List 项数多"
+
+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: åªèƒ½ç´¢å¼• List 或 Dictionary"
+
+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: :for åŽç¼ºå°‘ \"in\""
+
+#, c-format
+msgid "E107: Missing parentheses: %s"
+msgstr "E107: 缺少括å·: %s"
+
+#, c-format
+msgid "E108: No such variable: \"%s\""
+msgstr "E108: æ— æ­¤å˜é‡: \"%s\""
+
+msgid "E743: variable nested too deep for (un)lock"
+msgstr "E743: (un)lock çš„å˜é‡åµŒå¥—过深"
+
+msgid "E109: Missing ':' after '?'"
+msgstr "E109: '?' åŽç¼ºå°‘ ':'"
+
+msgid "E691: Can only compare List with List"
+msgstr "E691: åªèƒ½æ¯”较 List å’Œ List"
+
+msgid "E692: Invalid operation for Lists"
+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 "E693: Can only compare Funcref with Funcref"
+msgstr "E693: åªèƒ½æ¯”较 Funcref å’Œ Funcref"
+
+msgid "E694: Invalid operation for Funcrefs"
+msgstr "E694: 对 Funcrefs 无效的æ“作"
+
+msgid "E110: Missing ')'"
+msgstr "E110: 缺少 ')'"
+
+msgid "E695: Cannot index a Funcref"
+msgstr "E695: ä¸èƒ½ç´¢å¼•一个 Funcref"
+
+#, 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"
+
+#, c-format
+msgid "E696: Missing comma in List: %s"
+msgstr "E696: List 中缺少逗å·: %s"
+
+#, c-format
+msgid "E697: Missing end of List ']': %s"
+msgstr "E697: List 缺少结æŸç¬¦ ']': %s"
+
+#, c-format
+msgid "E720: Missing colon in Dictionary: %s"
+msgstr "E720: Dictionary 中缺少冒å·: %s"
+
+#, c-format
+msgid "E721: Duplicate key in Dictionary: \"%s\""
+msgstr "E721: Dictionary 中出现é‡å¤çš„é”®: \"%s\""
+
+#, c-format
+msgid "E722: Missing comma in Dictionary: %s"
+msgstr "E722: Dictionary 中缺少逗å·: %s"
+
+#, c-format
+msgid "E723: Missing end of Dictionary '}': %s"
+msgstr "E723: Dictionary 缺少结æŸç¬¦ '}': %s"
+
+msgid "E724: variable nested too deep for displaying"
+msgstr "E724: å˜é‡åµŒå¥—过深无法显示"
+
+msgid "E699: Too many arguments"
+msgstr "E699: 傿•°è¿‡å¤š"
+
+msgid "E785: complete() can only be used in Insert mode"
+msgstr "E785: complete() åªèƒ½åœ¨æ’入模å¼ä¸­ä½¿ç”¨"
+
+#.
+#. * 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 "确定(&O)"
+
+#, c-format
+msgid "E737: Key already exists: %s"
+msgstr "E737: 键已存在: %s"
+
+#, c-format
+msgid "+-%s%3ld lines: "
+msgstr "+-%s%3ld 行: "
+
+#, c-format
+msgid "E700: Unknown function: %s"
+msgstr "E700: 未知的函数: %s"
+
+msgid ""
+"&OK\n"
+"&Cancel"
+msgstr ""
+"确定(&O)\n"
+"å–æ¶ˆ(&C)"
+
+msgid "called inputrestore() more often than inputsave()"
+msgstr "inputrestore() 的调用次数多于 inputsave()"
+
+msgid "E786: Range not allowed"
+msgstr "E786: ä¸å…许的范围"
+
+msgid "E701: Invalid type for len()"
+msgstr "E701: len() 的类型无效"
+
+msgid "E726: Stride is zero"
+msgstr "E726: 步长为零"
+
+msgid "E727: Start past end"
+msgstr "E727: 起始值在终止值åŽ"
+
+msgid "<empty>"
+msgstr "<空>"
+
+msgid "E240: No connection to Vim server"
+msgstr "E240: 没有到 Vim æœåŠ¡å™¨çš„è¿žæŽ¥"
+
+#, c-format
+msgid "E241: Unable to send to %s"
+msgstr "E241: 无法å‘é€åˆ° %s"
+
+msgid "E277: Unable to read a server reply"
+msgstr "E277: æ— æ³•è¯»å–æœåС噍å“应"
+
+msgid "E655: Too many symbolic links (cycle?)"
+msgstr "E655: 符å·è¿žæŽ¥è¿‡å¤š(循环?)"
+
+msgid "E258: Unable to send to client"
+msgstr "E258: 无法å‘é€åˆ°å®¢æˆ·ç«¯"
+
+msgid "E702: Sort compare function failed"
+msgstr "E702: Sort 比较函数失败"
+
+msgid "(Invalid)"
+msgstr "(无效)"
+
+msgid "E677: Error writing temp file"
+msgstr "E677: 写临时文件出错"
+
+msgid "E703: Using a Funcref as a Number"
+msgstr "E703: 将 Funcref 作数字使用"
+
+msgid "E745: Using a List as a Number"
+msgstr "E745: 将 List 作数字使用"
+
+msgid "E728: Using a Dictionary as a Number"
+msgstr "E728: 将 Dictionary 作数字使用"
+
+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 使用"
+
+#, 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 "E706: Variable type mismatch for: %s"
+msgstr "E706: å˜é‡ç±»åž‹ä¸åŒ¹é…: %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: å˜é‡åµŒå¥—过深无法å¤åˆ¶"
+
+#, c-format
+msgid "E124: Missing '(': %s"
+msgstr "E124: 缺少 '(': %s"
+
+#, c-format
+msgid "E125: Illegal argument: %s"
+msgstr "E125: æ— æ•ˆçš„å‚æ•°: %s"
+
+msgid "E126: Missing :endfunction"
+msgstr "E126: 缺少 :endfunction"
+
+#, c-format
+msgid "E746: Function name does not match script file name: %s"
+msgstr "E746: 函数å与脚本文件åä¸åŒ¹é…: %s"
+
+msgid "E129: Function name required"
+msgstr "E129: 需è¦å‡½æ•°å"
+
+#, c-format
+msgid "E128: Function name must start with a capital or contain a colon: %s"
+msgstr "E128: 函数å必须以大写字æ¯å¼€å¤´æˆ–者包å«å†’å·: %s"
+
+#, c-format
+msgid "E131: Cannot delete function %s: It is in use"
+msgstr "E131: 无法删除函数 %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"
+
+#, c-format
+msgid "continuing in %s"
+msgstr "在 %s 中继续"
+
+msgid "E133: :return not inside a function"
+msgstr "E133: :return ä¸åœ¨å‡½æ•°ä¸­"
+
+#, c-format
+msgid ""
+"\n"
+"# global variables:\n"
+msgstr ""
+"\n"
+"# 全局å˜é‡:\n"
+
+msgid ""
+"\n"
+"\tLast set from "
+msgstr ""
+"\n"
+"\t最近修改于 "
+
+#, c-format
+msgid "<%s>%s%s %d, Hex %02x, Octal %03o"
+msgstr "<%s>%s%s %d, å六进制 %02x, 八进制 %03o"
+
+#, 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: *Filter* 自动命令ä¸å¯ä»¥æ”¹å˜å½“å‰ç¼“冲区"
+
+msgid "[No write since last change]\n"
+msgstr "[已修改但尚未ä¿å­˜]\n"
+
+# bad to translate
+#, 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 " FAILED"
+msgstr " 失败"
+
+#, c-format
+msgid "E137: Viminfo file is not writable: %s"
+msgstr "E137: Viminfo 文件ä¸å¯å†™å…¥: %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\""
+
+# do not translate to avoid writing Chinese in files
+#. Write the info:
+#, fuzzy, c-format
+#~ msgid "# This viminfo file was generated by Vim %s.\n"
+#~ msgstr "# 这个 viminfo 文件是由 Vim %s 生æˆçš„。\n"
+
+# do not translate to avoid writing Chinese in files
+#, fuzzy, c-format
+msgid ""
+"# You may edit it if you're careful!\n"
+"\n"
+msgstr ""
+"# 如果è¦è‡ªè¡Œä¿®æ”¹è¯·ç‰¹åˆ«å°å¿ƒï¼\n"
+"\n"
+
+# do not translate to avoid writing Chinese in files
+#, fuzzy, c-format
+#~ msgid "# Value of 'encoding' when this file was written\n"
+#~ msgstr "# 'encoding' 在此文件建立时的值\n"
+
+msgid "Illegal starting char"
+msgstr "无效的å¯åŠ¨å­—ç¬¦"
+
+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 "äº¤æ¢æ–‡ä»¶ \"%s\" 已存在,确实è¦è¦†ç›–å—?"
+
+#, c-format
+msgid "E768: Swap file exists: %s (:silent! overrides)"
+msgstr "E768: äº¤æ¢æ–‡ä»¶å·²å­˜åœ¨: %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 ""
+"\"%s\" 已设定 'readonly' 选项。\n"
+"确实è¦è¦†ç›–å—?"
+
+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: rvim ä¸­ç¦æ­¢ä½¿ç”¨ shell 命令"
+
+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"
+msgstr "E147: :global ä¸èƒ½é€’归执行"
+
+msgid "E148: Regular expression missing from global"
+msgstr "E148: global 缺少正则表达å¼"
+
+#, c-format
+msgid "Pattern found in every line: %s"
+msgstr "æ¯è¡Œéƒ½åŒ¹é…表达å¼: %s"
+
+# do not translate to avoid writing Chinese in files
+#, fuzzy, c-format
+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 "E150: Not a directory: %s"
+msgstr "E150: 䏿˜¯ç›®å½•: %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: Tag \"%s\" 在文件 %s/%s 中é‡å¤å‡ºçް"
+
+#, c-format
+msgid "E160: Unknown sign command: %s"
+msgstr "E160: 未知的 sign 命令: %s"
+
+msgid "E156: Missing sign name"
+msgstr "E156: 缺少 sign åç§°"
+
+msgid "E612: Too many signs defined"
+msgstr "E612: Signs 定义过多"
+
+#, c-format
+msgid "E239: Invalid sign text: %s"
+msgstr "E239: 无效的 sign 文字: %s"
+
+#, c-format
+msgid "E155: Unknown sign: %s"
+msgstr "E155: 未知的 sign: %s"
+
+msgid "E159: Missing sign number"
+msgstr "E159: 缺少 sign å·"
+
+#, c-format
+msgid "E158: Invalid buffer name: %s"
+msgstr "E158: 无效的缓冲区å: %s"
+
+#, c-format
+msgid "E157: Invalid sign ID: %ld"
+msgstr "E157: 无效的 sign ID: %ld"
+
+msgid " (NOT FOUND)"
+msgstr " (找ä¸åˆ°)"
+
+msgid " (not supported)"
+msgstr " (䏿”¯æŒ)"
+
+msgid "[Deleted]"
+msgstr "[已删除]"
+
+msgid "Entering Debug mode. Type \"cont\" to continue."
+msgstr "进入调试模å¼ã€‚输入 \"cont\" ç»§ç»­è¿è¡Œã€‚"
+
+#, c-format
+msgid "line %ld: %s"
+msgstr "第 %ld 行: %s"
+
+#, c-format
+msgid "cmd: %s"
+msgstr "命令: %s"
+
+#, 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 行"
+
+msgid "E750: First use :profile start <fname>"
+msgstr "E750: 请先使用 :profile start <fname>"
+
+#, c-format
+msgid "Save changes to \"%s\"?"
+msgstr "将改å˜ä¿å­˜åˆ° \"%s\" å—?"
+
+msgid "Untitled"
+msgstr "未命å"
+
+#, 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 'runtimepath': \"%s\""
+msgstr "在 'runtimepath' 中找ä¸åˆ° \"%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"
+
+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 "E319: Sorry, the command is not available in this version"
+msgstr "E319: 抱歉,命令在此版本中ä¸å¯ç”¨"
+
+msgid "E172: Only one file name allowed"
+msgstr "E172: åªå…许一个文件å"
+
+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 Range 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 需è¦å‚æ•°"
+
+#, 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: 用户自定义命令必须以大写字æ¯å¼€å¤´"
+
+#, c-format
+msgid "E184: No such user-defined command: %s"
+msgstr "E184: 没有这个用户自定义命令: %s"
+
+#, c-format
+msgid "E180: Invalid complete value: %s"
+msgstr "E180: 无效的补全类型: %s"
+
+msgid "E468: Completion argument only allowed for custom completion"
+msgstr "E468: åªæœ‰ custom 补全æ‰å…è®¸å‚æ•°"
+
+msgid "E467: Custom completion requires a function argument"
+msgstr "E467: Custom 补全需è¦ä¸€ä¸ªå‡½æ•°å‚æ•°"
+
+#, c-format
+msgid "E185: Cannot find color scheme %s"
+msgstr "E185: 找ä¸åˆ°é…色方案 %s"
+
+msgid "Greetings, Vim user!"
+msgstr "您好,Vim 用户ï¼"
+
+msgid "E784: Cannot close last tab page"
+msgstr "E784: ä¸èƒ½å…³é—­æœ€åŽä¸€ä¸ª tab 页"
+
+msgid "Already only one tab page"
+msgstr "å·²ç»åªå‰©ä¸€ä¸ª tab 页了"
+
+msgid "Edit File in new window"
+msgstr "在新窗å£ç¼–辑文件"
+
+#, c-format
+msgid "Tab page %d"
+msgstr "Tab 页 %d"
+
+msgid "No swap file"
+msgstr "æ— äº¤æ¢æ–‡ä»¶"
+
+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 "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\""
+
+#. set mark
+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 "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: æ²¡æœ‰ç”¨äºŽæ›¿æ¢ \"<sfile>\" çš„ :source 文件å"
+
+#, no-c-format
+msgid "E499: Empty file name for '%' or '#', only works with \":p:h\""
+msgstr "E499: '%' 或 '#' 为空文件å,åªèƒ½ç”¨äºŽ \":p:h\""
+
+msgid "E500: Evaluates to an empty string"
+msgstr "E500: 结果为空字符串"
+
+msgid "E195: Cannot open viminfo file for reading"
+msgstr "E195: æ— æ³•æ‰“å¼€å¹¶è¯»å– viminfo 文件"
+
+msgid "E196: No digraphs in this version"
+msgstr "E196: 此版本无å¤åˆå­—符(digraph)"
+
+msgid "E608: Cannot :throw exceptions with 'Vim' prefix"
+msgstr "E608: ä¸èƒ½ :throw å‰ç¼€ä¸º 'Vim' 的异常"
+
+#. always scroll up, don't overwrite
+#, 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 行"
+
+#. always scroll up, don't overwrite
+#, c-format
+msgid "Exception caught: %s"
+msgstr "æ•获异常: %s"
+
+#, c-format
+#~ msgid "%s made pending"
+#~ msgstr ""
+
+#, fuzzy, c-format
+#~ msgid "%s resumed"
+#~ msgstr " 已返回\n"
+
+#, c-format
+#~ msgid "%s discarded"
+#~ msgstr ""
+
+msgid "Exception"
+msgstr "异常"
+
+msgid "Error and interrupt"
+msgstr "错误和中断"
+
+msgid "Error"
+msgstr "错误"
+
+#. if (pending & CSTP_INTERRUPT)
+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: :while 以 :endfor 结尾"
+
+msgid "E733: Using :endwhile with :for"
+msgstr "E733: :for 以 :endwhile 结尾"
+
+msgid "E601: :try nesting too deep"
+msgstr "E601: :try 嵌套层数过深"
+
+msgid "E603: :catch without :try"
+msgstr "E603: :catch 缺少对应的 :try"
+
+#. Give up for a ":catch" after ":finally" and ignore it.
+#. * Just parse.
+msgid "E604: :catch after :finally"
+msgstr "E604: :catch 在 :finally åŽé¢"
+
+msgid "E606: :finally without :try"
+msgstr "E606: :finally 缺少对应的 :try"
+
+#. Give up for a multiple ":finally" and ignore it.
+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 "tagname"
+msgstr "tag å"
+
+msgid " kind file\n"
+msgstr " 类型 文件\n"
+
+msgid "'history' option is zero"
+msgstr "选项 'history' 为零"
+
+# do not translate to avoid writing Chinese in files
+#, fuzzy, c-format
+msgid ""
+"\n"
+"# %s History (newest to oldest):\n"
+msgstr ""
+"\n"
+"# %s 历å²è®°å½• (从新到旧):\n"
+
+# do not translate to avoid writing Chinese in files
+#, fuzzy
+#~ msgid "Command Line"
+#~ msgstr "命令行"
+
+# do not translate to avoid writing Chinese in files
+#, fuzzy
+#~ msgid "Search String"
+#~ msgstr "查找字符串"
+
+# do not translate to avoid writing Chinese in files
+#, fuzzy
+#~ msgid "Expression"
+#~ msgstr "表达å¼"
+
+# do not translate to avoid writing Chinese in files
+#, fuzzy
+#~ msgid "Input Line"
+#~ msgstr "输入行"
+
+msgid "E198: cmd_pchar beyond the command length"
+msgstr "E198: cmd_pchar 超过命令长度"
+
+msgid "E199: Active window or buffer deleted"
+msgstr "E199: æ´»åŠ¨çª—å£æˆ–缓冲区已被删除"
+
+msgid "Illegal file name"
+msgstr "无效的文件å"
+
+msgid "is a directory"
+msgstr "是目录"
+
+msgid "is not a file"
+msgstr "䏿˜¯æ–‡ä»¶"
+
+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: 从标准输入读å–...\n"
+
+msgid "Reading from stdin..."
+msgstr "从标准输入读å–..."
+
+#. Re-opening the original file failed!
+msgid "E202: Conversion made file unreadable!"
+msgstr "E202: 转æ¢å¯¼è‡´æ–‡ä»¶ä¸å¯è¯»"
+
+msgid "[fifo/socket]"
+msgstr "[fifo/socket]"
+
+msgid "[fifo]"
+msgstr "[fifo]"
+
+msgid "[socket]"
+msgstr "[socket]"
+
+msgid "[RO]"
+msgstr "[åªè¯»]"
+
+msgid "[CR missing]"
+msgstr "[缺少 CR]'"
+
+msgid "[NL found]"
+msgstr "[找到 NL]"
+
+msgid "[long lines split]"
+msgstr "[长行分割]"
+
+msgid "[NOT converted]"
+msgstr "[未转æ¢]"
+
+msgid "[converted]"
+msgstr "[已转æ¢]"
+
+msgid "[crypted]"
+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 "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 "E460: The resource fork would be lost (add ! to override)"
+msgstr "E460: Resource fork 会丢失 (请加 ! 强制执行)"
+
+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 "E667: Fsync failed"
+msgstr "E667: åŒæ­¥å¤±è´¥"
+
+msgid "E512: Close failed"
+msgstr "E512: 关闭失败"
+
+msgid "E513: write error, conversion failed (make 'fenc' empty to override)"
+msgstr "E513: 写入错误,转æ¢å¤±è´¥ (请将 'fenc' 置空以强制执行)"
+
+msgid "E514: write error (file system full?)"
+msgstr "E514: 写入错误 (文件系统已满?)"
+
+msgid " CONVERSION ERROR"
+msgstr " 转æ¢é”™è¯¯"
+
+msgid "[Device]"
+msgstr "[设备]"
+
+msgid "[New]"
+msgstr "[æ–°]"
+
+msgid " [a]"
+msgstr " [a]"
+
+msgid " appended"
+msgstr " 已追加"
+
+msgid " [w]"
+msgstr " [w]"
+
+msgid " written"
+msgstr " 已写入"
+
+msgid "E205: Patchmode: can't save original file"
+msgstr "E205: Patchmode: 无法ä¿å­˜åŽŸå§‹æ–‡ä»¶"
+
+msgid "E206: patchmode: can't touch empty original file"
+msgstr "E206: Patchmode: 无法生æˆç©ºçš„原始文件"
+
+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 "%ld characters"
+msgstr "%ld 个字符"
+
+msgid "[noeol]"
+msgstr "[noeol]"
+
+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
+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 ""
+"确定(&O)\n"
+"加载文件(&L)"
+
+#, 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 ""
+
+#. the group doesn't exist
+#, c-format
+msgid "E367: No such group: \"%s\""
+msgstr "E367: 无此组: \"%s\""
+
+#, 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"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Auto-Commands ---"
+msgstr ""
+"\n"
+"--- 自动命令 ---"
+
+#, c-format
+msgid "E680: <buffer=%d>: invalid buffer number "
+msgstr "E680: <buffer=%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 Auto commands 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 lines folded "
+msgstr "+--å·²æŠ˜å  %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 "E229: Cannot start the GUI"
+msgstr "E229: 无法å¯åŠ¨å›¾å½¢ç•Œé¢"
+
+#, c-format
+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' 的值无效"
+
+#, 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 "滚动æ¡éƒ¨ä»¶: æ— æ³•èŽ·å–æ»‘å—图åƒçš„几何大å°"
+
+msgid "Vim dialog"
+msgstr "Vim å¯¹è¯æ¡†"
+
+msgid "E232: Cannot create BalloonEval with both message and callback"
+msgstr "E232: ä¸èƒ½åŒæ—¶ä½¿ç”¨æ¶ˆæ¯å’Œå›žè°ƒå‡½æ•°æ¥åˆ›å»º BalloonEval"
+
+msgid "Vim dialog..."
+msgstr "Vim å¯¹è¯æ¡†..."
+
+msgid ""
+"&Yes\n"
+"&No\n"
+"&Cancel"
+msgstr ""
+"是(&Y)\n"
+"å¦(&N)\n"
+"å–æ¶ˆ(&C)"
+
+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 "替æ¢ä¸º:"
+
+#. whole word only button
+msgid "Match whole word only"
+msgstr "匹é…完整的è¯"
+
+#. match case button
+msgid "Match case"
+msgstr "匹é…大å°å†™"
+
+msgid "Direction"
+msgstr "æ–¹å‘"
+
+#. 'Up' and 'Down' buttons
+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)"
+
+#, 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 "Close tab"
+msgstr "关闭标签"
+
+msgid "Open tab..."
+msgstr "打开标签..."
+
+msgid "Find string (use '\\\\' to find a '\\')"
+msgstr "查找字符串 (使用 '\\\\' æ¥æŸ¥æ‰¾ '\\')"
+
+msgid "Find & Replace (use '\\\\' to find a '\\')"
+msgstr "查找和替æ¢å­—符串 (使用 '\\\\' æ¥æŸ¥æ‰¾ '\\')"
+
+#. 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 "未使用"
+
+msgid "Directory\t*.nothing\n"
+msgstr "目录\t*.nothing\n"
+
+msgid "Vim E458: Cannot allocate colormap entry, some colors may be incorrect"
+msgstr "Vim E458: 无法分é…颜色表项,æŸäº›é¢œè‰²å¯èƒ½ä¸æ­£ç¡®"
+
+#, c-format
+msgid "E250: Fonts for the following charsets are missing in fontset %s:"
+msgstr "E250: Fontset %s 缺少下列字符集的字体:"
+
+#, c-format
+msgid "E252: Fontset name: %s"
+msgstr "E252: Fontset åç§°: %s"
+
+#, c-format
+msgid "Font '%s' is not fixed-width"
+msgstr "'%s' 䏿˜¯å›ºå®šå®½åº¦çš„字体"
+
+#, c-format
+msgid "E253: Fontset name: %s\n"
+msgstr "E253: Fontset åç§°: %s\n"
+
+#, c-format
+msgid "Font0: %s\n"
+msgstr "字体0: %s\n"
+
+#, c-format
+msgid "Font1: %s\n"
+msgstr "字体1: %s\n"
+
+#, c-format
+msgid "Font%ld width is not twice that of font0\n"
+msgstr "字体%ldçš„å®½åº¦ä¸æ˜¯å­—体0的两å€\n"
+
+#, c-format
+msgid "Font0 width: %ld\n"
+msgstr "字体0的宽度:%ld\n"
+
+#, c-format
+msgid ""
+"Font1 width: %ld\n"
+"\n"
+msgstr ""
+"字体1的宽度: %ld\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 "åç§°:"
+
+#. create toggle button
+#~ 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 automata 错误"
+
+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 èµ„æºæ–‡ä»¶ \"%s\""
+
+#, c-format
+msgid "E618: file \"%s\" is not a PostScript resource file"
+msgstr "E618: 文件 \"%s\" 䏿˜¯ PostScript èµ„æºæ–‡ä»¶"
+
+#, c-format
+msgid "E619: file \"%s\" is not a supported PostScript resource file"
+msgstr "E619: 文件 \"%s\" 䏿˜¯å·²æ”¯æŒçš„ PostScript èµ„æºæ–‡ä»¶"
+
+#, c-format
+msgid "E621: \"%s\" resource file has wrong version"
+msgstr "E621: \"%s\" èµ„æºæ–‡ä»¶ç‰ˆæœ¬ä¸æ­£ç¡®"
+
+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 èµ„æºæ–‡ä»¶ \"prolog.ps\""
+
+msgid "E456: Can't find PostScript resource file \"cidfont.ps\""
+msgstr "E456: 找ä¸åˆ° PostScript èµ„æºæ–‡ä»¶ \"cidfont.ps\""
+
+#, c-format
+msgid "E456: Can't find PostScript resource file \"%s.ps\""
+msgstr "E456: 找ä¸åˆ° PostScript èµ„æºæ–‡ä»¶ \"%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: 找ä¸åˆ° tag"
+
+#, 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 进行 fork"
+
+msgid "cs_create_connection exec failed"
+msgstr "cs_create_connection 执行失败"
+
+msgid "E623: Could not spawn cscope process"
+msgstr "E623: æ— æ³•ç”Ÿæˆ cscope 进程"
+
+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 "E567: no cscope connections"
+msgstr "E567: 没有 cscope 连接"
+
+#, c-format
+msgid "E259: no matches found for cscope query %s of %s"
+msgstr "E259: cscope 查询 %s %s 没有找到匹é…的结果"
+
+#, c-format
+msgid "E469: invalid cscopequickfix flag %c for %c"
+msgstr "E469: cscopequickfix 标志 %c 对 %c 无效"
+
+msgid "cscope commands:\n"
+msgstr "cscope 命令:\n"
+
+#, c-format
+msgid "%-5s: %-30s (Usage: %s)"
+msgstr "%-5s: %-30s (用法: %s)"
+
+#, 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 æ•°æ®åº“未被加入"
+
+msgid "E569: maximum number of cscope connections reached"
+msgstr "E569: 已达到 cscope 的最大连接数"
+
+#, c-format
+msgid "E261: cscope connection %s not found"
+msgstr "E261: 找ä¸åˆ° cscope 连接 %s"
+
+#, c-format
+msgid "cscope connection %s closed"
+msgstr "cscope 连接 %s 已关闭"
+
+#. should not reach here
+msgid "E570: fatal error in cs_manage_matches"
+msgstr "E570: cs_manage_matches 严é‡é”™è¯¯"
+
+#, c-format
+msgid "Cscope tag: %s"
+msgstr "Cscope tag: %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 æ•°æ®åº“å prepend path\n"
+
+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 "行å·è¶…出范围"
+
+#, c-format
+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 "光标ä½ç½®åœ¨ç¼“冲区外"
+
+#, c-format
+msgid "<window object (deleted) at %.8lX>"
+msgstr "<窗å£å¯¹è±¡(已删除): %.8lX>"
+
+#, c-format
+msgid "<window object (unknown) at %.8lX>"
+msgstr "<窗å£å¯¹è±¡(未知): %.8lX>"
+
+#, c-format
+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 库"
+
+#, c-format
+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 "连接中"
+
+#, c-format
+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 "没有设定标记"
+
+#, c-format
+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 "无法注册回调命令: 缓冲区/窗å£å·²è¢«åˆ é™¤"
+
+#. This should never happen. Famous last word?
+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"
+
+#, 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 实例注册属性有误。已删除ï¼"
+
+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 "æ— æ•ˆçš„å‚æ•°"
+
+#, c-format
+msgid "%d files to edit\n"
+msgstr "还有 %d 个文件等待编辑\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: 错误: 无法从 NetBeans 中å¯åЍ gvim\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"
+
+#. just in case..
+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 编辑 tag 定义处的文件"
+
+msgid "-q [errorfile] edit file with first error"
+msgstr "-q [errorfile] 编辑第一个出错处的文件"
+
+msgid ""
+"\n"
+"\n"
+"usage:"
+msgstr ""
+"\n"
+"\n"
+"用法:"
+
+msgid " vim [arguments] "
+msgstr " vim [傿•°] "
+
+msgid ""
+"\n"
+" or:"
+msgstr ""
+"\n"
+" 或:"
+
+#~ msgid "where case is ignored prepend / to make flag upper case"
+#~ msgstr ""
+
+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å–æ¶ˆ 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\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 "-s\t\t\tSilent (batch) mode (only for \"ex\")"
+msgstr "-s\t\t\t安é™(批处ç†)æ¨¡å¼ (åªèƒ½ä¸Ž \"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\tå®¹æ˜“æ¨¡å¼ (åŒ \"evim\",无模å¼)"
+
+msgid "-R\t\t\tReadonly mode (like \"view\")"
+msgstr "-R\t\t\tåªè¯»æ¨¡å¼ (åŒ \"view\")"
+
+msgid "-Z\t\t\tRestricted mode (like \"rvim\")"
+msgstr "-Z\t\t\té™åˆ¶æ¨¡å¼ (åŒ \"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]\t\tVerbose level"
+msgstr "-V[N]\t\tVerbose 等级"
+
+msgid "-D\t\t\tDebugging mode"
+msgstr "-D\t\t\t调试模å¼"
+
+msgid "-n\t\t\tNo swap file, use memory only"
+msgstr "-n\t\t\tä¸ä½¿ç”¨äº¤æ¢æ–‡ä»¶ï¼Œåªä½¿ç”¨å†…å­˜"
+
+msgid "-r\t\t\tList swap files and exit"
+msgstr "-r\t\t\tåˆ—å‡ºäº¤æ¢æ–‡ä»¶å¹¶é€€å‡º"
+
+msgid "-r (with file name)\tRecover crashed session"
+msgstr "-r (跟文件å)\t\tæ¢å¤å´©æºƒçš„会è¯"
+
+msgid "-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ä¸ä½¿ç”¨ newcli æ¥æ‰“开窗å£"
+
+msgid "-dev <device>\t\tUse <device> for I/O"
+msgstr "-dev <device>\t\t使用 <device> 进行输入输出"
+
+msgid "-A\t\t\tstart in Arabic mode"
+msgstr "-A\t\t\t以 Arabic 模å¼å¯åЍ"
+
+msgid "-H\t\t\tStart in Hebrew mode"
+msgstr "-H\t\t\t以 Hebrew 模å¼å¯åЍ"
+
+msgid "-F\t\t\tStart in Farsi mode"
+msgstr "-F\t\t\t以 Farsi 模å¼å¯åЍ"
+
+msgid "-T <terminal>\tSet terminal type to <terminal>"
+msgstr "-T <terminal>\t设定终端类型为 <terminal>"
+
+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ä¸åŠ è½½ plugin 脚本"
+
+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 "+<lnum>\t\tå¯åЍåŽè·³åˆ°ç¬¬ <lnum> 行"
+
+msgid "--cmd <command>\tExecute <command> before loading any vimrc file"
+msgstr "--cmd <command>\t加载任何 vimrc æ–‡ä»¶å‰æ‰§è¡Œ <command>"
+
+msgid "-c <command>\t\tExecute <command> after loading the first file"
+msgstr "-c <command>\t\tåŠ è½½ç¬¬ä¸€ä¸ªæ–‡ä»¶åŽæ‰§è¡Œ <command>"
+
+msgid "-S <session>\t\tSource file <session> after loading the first file"
+msgstr "-S <session>\t\tåŠ è½½ç¬¬ä¸€ä¸ªæ–‡ä»¶åŽæ‰§è¡Œæ–‡ä»¶ <session>"
+
+msgid "-s <scriptin>\tRead Normal mode commands from file <scriptin>"
+msgstr "-s <scriptin>\t从文件 <scriptin> 读入正常模å¼çš„命令"
+
+msgid "-w <scriptout>\tAppend all typed commands to file <scriptout>"
+msgstr "-w <scriptout>\t将所有输入的命令追加到文件 <scriptout>"
+
+msgid "-W <scriptout>\tWrite all typed commands to file <scriptout>"
+msgstr "-W <scriptout>\t将所有输入的命令写入到文件 <scriptout>"
+
+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 "-i <viminfo>\t\tUse <viminfo> instead of .viminfo"
+msgstr "-i <viminfo>\t\t使用 <viminfo> å–代 .viminfo"
+
+msgid "-h or --help\tPrint Help (this message) and exit"
+msgstr "-h 或 --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 <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"
+
+#. Failed to send, abort.
+msgid ": Send failed.\n"
+msgstr ": å‘é€å¤±è´¥ã€‚\n"
+
+#. Let vim start normally.
+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 "没有 display: å‘é€è¡¨è¾¾å¼å¤±è´¥ã€‚\n"
+
+msgid ": Send expression failed.\n"
+msgstr ": å‘é€è¡¨è¾¾å¼å¤±è´¥ã€‚\n"
+
+msgid "No marks set"
+msgstr "没有设定标记"
+
+#, c-format
+msgid "E283: No marks matching \"%s\""
+msgstr "E283: æ²¡æœ‰åŒ¹é… \"%s\" 的标记"
+
+#. Highlight title
+msgid ""
+"\n"
+"mark line col file/text"
+msgstr ""
+"\n"
+"标记 行 列 文件/文本"
+
+#. Highlight title
+msgid ""
+"\n"
+" jump line col file/text"
+msgstr ""
+"\n"
+" 跳转 行 列 文件/文本"
+
+#. Highlight title
+msgid ""
+"\n"
+"change line col text"
+msgstr ""
+"\n"
+" æ”¹å˜ è¡Œ 列 文本"
+
+#, c-format
+msgid ""
+"\n"
+"# File marks:\n"
+msgstr ""
+"\n"
+"# 文件标记:\n"
+
+#. Write the jumplist with -'
+#, c-format
+msgid ""
+"\n"
+"# Jumplist (newest first):\n"
+msgstr ""
+"\n"
+"# 跳转列表 (从新到旧):\n"
+
+#, c-format
+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: 警告: 无法设定输入法的释放回调函数"
+
+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 "E293: block was not locked"
+msgstr "E293: å—æœªè¢«é”定"
+
+msgid "E294: Seek error in swap file read"
+msgstr "E294: äº¤æ¢æ–‡ä»¶è¯»å–定ä½é”™è¯¯"
+
+msgid "E295: Read error in swap file"
+msgstr "E295: äº¤æ¢æ–‡ä»¶è¯»å–错误"
+
+msgid "E296: Seek error in swap file write"
+msgstr "E296: äº¤æ¢æ–‡ä»¶å†™å…¥å®šä½é”™è¯¯"
+
+msgid "E297: Write error in swap file"
+msgstr "E297: äº¤æ¢æ–‡ä»¶å†™å…¥é”™è¯¯"
+
+msgid "E300: Swap file already exists (symlink attack?)"
+msgstr "E300: äº¤æ¢æ–‡ä»¶å·²å­˜åœ¨ (符å·è¿žæŽ¥æ”»å‡»ï¼Ÿ)"
+
+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?"
+
+#. could not (re)open the swap file, what can we do????
+msgid "E301: Oops, lost the swap file!!!"
+msgstr "E301: å™¢ï¼Œäº¤æ¢æ–‡ä»¶ä¸è§äº†ï¼ï¼ï¼"
+
+msgid "E302: Could not rename swap file"
+msgstr "E302: 无法é‡å‘½åäº¤æ¢æ–‡ä»¶"
+
+#, c-format
+msgid "E303: Unable to open swap file for \"%s\", recovery impossible"
+msgstr "E303: 无法打开 \"%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 çš„äº¤æ¢æ–‡ä»¶"
+
+msgid "Enter number of swap file to use (0 to quit): "
+msgstr "请输入è¦ä½¿ç”¨çš„äº¤æ¢æ–‡ä»¶ç¼–å· (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 还æ¥ä¸åŠæ›´æ–°äº¤æ¢æ–‡ä»¶ã€‚"
+
+msgid " cannot be used with this version of Vim.\n"
+msgstr " ä¸èƒ½åœ¨è¯¥ç‰ˆæœ¬çš„ Vim 中使用。\n"
+
+msgid "Use Vim version 3.0.\n"
+msgstr "使用 Vim 3.0。\n"
+
+#, c-format
+msgid "E307: %s does not look like a Vim swap file"
+msgstr "E307: %s 看起æ¥ä¸åƒæ˜¯ Vim äº¤æ¢æ–‡ä»¶"
+
+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 "Using swap file \"%s\""
+msgstr "ä½¿ç”¨äº¤æ¢æ–‡ä»¶ \"%s\""
+
+#, c-format
+msgid "Original file \"%s\""
+msgstr "原始文件 \"%s\""
+
+msgid "E308: Warning: Original file may have been changed"
+msgstr "E308: 警告: 原始文件å¯èƒ½å·²è¢«ä¿®æ”¹"
+
+#, c-format
+msgid "E309: Unable to read block 1 from %s"
+msgstr "E309: 无法从 %s 读å–å— 1"
+
+# do not translate to avoid writing Chinese in files
+#, fuzzy
+#~ msgid "???MANY LINES MISSING"
+#~ msgstr "???缺少了太多行"
+
+# do not translate to avoid writing Chinese in files
+#, fuzzy
+#~ msgid "???LINE COUNT WRONG"
+#~ msgstr "???行数错误"
+
+# do not translate to avoid writing Chinese in files
+#, fuzzy
+#~ msgid "???EMPTY BLOCK"
+#~ msgstr "???空的å—"
+
+# do not translate to avoid writing Chinese in files
+#, fuzzy
+#~ msgid "???LINES MISSING"
+#~ msgstr "???缺少了一些行"
+
+#, 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
+#, fuzzy
+#~ msgid "???BLOCK MISSING"
+#~ msgstr "???缺少å—"
+
+# do not translate to avoid writing Chinese in files
+#, fuzzy
+#~ msgid "??? from here until ???END lines may be messed up"
+#~ msgstr "??? 从这里到 ???END 的行å¯èƒ½å·²æ··ä¹±"
+
+# do not translate to avoid writing Chinese in files
+#, fuzzy
+#~ msgid "??? from here until ???END lines may have been inserted/deleted"
+#~ msgstr "??? 从这里到 ???END 的行å¯èƒ½å·²è¢«æ’å…¥/删除过"
+
+# do not translate to avoid writing Chinese in files
+#, fuzzy
+#~ msgid "???END"
+#~ msgstr "???END"
+
+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 "æ¢å¤å®Œæ¯•。请确定一切正常。"
+
+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)\n"
+msgstr "å†è¿è¡Œ diff ä¸ŽåŽŸæ–‡ä»¶æ¯”è¾ƒä»¥æ£€æŸ¥æ˜¯å¦æœ‰æ”¹å˜)\n"
+
+msgid ""
+"Delete the .swp file afterwards.\n"
+"\n"
+msgstr ""
+"ç„¶åŽæŠŠ .swp 文件删掉。\n"
+"\n"
+
+#. use msg() to start the scrolling properly
+msgid "Swap files found:"
+msgstr "æ‰¾åˆ°äº¤æ¢æ–‡ä»¶:"
+
+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 äº¤æ¢æ–‡ä»¶]"
+
+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"
+" 进程 ID: "
+
+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: 无法ä¿ç•™ï¼Œæ²¡æœ‰äº¤æ¢æ–‡ä»¶"
+
+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: æŒ‡é’ˆå— id 错误 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: æŒ‡é’ˆå— id 错误 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: æŒ‡é’ˆå— id 错误"
+
+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: æŒ‡é’ˆå— id 错误 2"
+
+#, c-format
+msgid "E773: Symlink loop for \"%s\""
+msgstr "E773: \"%s\" 符å·è¿žæŽ¥å‡ºçŽ°å¾ªçŽ¯"
+
+msgid "E325: ATTENTION"
+msgstr "E325: 注æ„"
+
+msgid ""
+"\n"
+"Found a swap file by the name \""
+msgstr ""
+"\n"
+"å‘çŽ°äº¤æ¢æ–‡ä»¶ \""
+
+msgid "While opening file \""
+msgstr "正在打开文件 \""
+
+msgid " NEWER than swap file!\n"
+msgstr " æ¯”äº¤æ¢æ–‡ä»¶æ–°ï¼\n"
+
+#. Some of these messages are long to allow translation to
+#. * other languages.
+msgid ""
+"\n"
+"(1) Another program may be editing the same file.\n"
+" If this is the case, be careful not to end up with two\n"
+" different instances of the same file when making changes.\n"
+msgstr ""
+"\n"
+"(1) å¦ä¸€ä¸ªç¨‹åºå¯èƒ½ä¹Ÿåœ¨ç¼–辑åŒä¸€ä¸ªæ–‡ä»¶ã€‚\n"
+" 如果是这样,修改时请注æ„é¿å…åŒä¸€ä¸ªæ–‡ä»¶äº§ç”Ÿä¸¤ä¸ªä¸åŒçš„版本。\n"
+"\n"
+
+msgid " Quit, or continue with caution.\n"
+msgstr " 退出,或å°å¿ƒåœ°ç»§ç»­ã€‚\n"
+
+msgid ""
+"\n"
+"(2) An edit session for this file crashed.\n"
+msgstr ""
+"\n"
+"(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 " 如果你已ç»è¿›è¡Œäº†æ¢å¤ï¼Œè¯·åˆ é™¤äº¤æ¢æ–‡ä»¶ \""
+
+msgid ""
+"\"\n"
+" to avoid this message.\n"
+msgstr ""
+"\"\n"
+" 以é¿å…å†çœ‹åˆ°æ­¤æ¶ˆæ¯ã€‚\n"
+
+msgid "Swap file \""
+msgstr "äº¤æ¢æ–‡ä»¶ \""
+
+msgid "\" already exists!"
+msgstr "\" 已存在ï¼"
+
+msgid "VIM - ATTENTION"
+msgstr "VIM - 注æ„"
+
+msgid "Swap file already exists!"
+msgstr "äº¤æ¢æ–‡ä»¶å·²å­˜åœ¨ï¼"
+
+msgid ""
+"&Open Read-Only\n"
+"&Edit anyway\n"
+"&Recover\n"
+"&Quit\n"
+"&Abort"
+msgstr ""
+"以åªè¯»æ–¹å¼æ‰“å¼€(&O)\n"
+"直接编辑(&E)\n"
+"æ¢å¤(&R)\n"
+"退出(&Q)\n"
+"中止(&A)"
+
+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)"
+
+msgid "E326: Too many swap files found"
+msgstr "E326: æ‰¾åˆ°å¤ªå¤šäº¤æ¢æ–‡ä»¶"
+
+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 "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: 分隔线ä¸èƒ½æ˜¯èœå•路径的一部分"
+
+#. Now we have found the matching menu, and we list the mappings
+#. Highlight title
+msgid ""
+"\n"
+"--- Menus ---"
+msgstr ""
+"\n"
+"--- èœå• ---"
+
+msgid "Tear off this menu"
+msgstr "撕下此èœå•"
+
+msgid "E333: Menu path must lead to a menu item"
+msgstr "E333: èœå•路径必须指å‘èœå•项"
+
+#, c-format
+msgid "E334: Menu not found: %s"
+msgstr "E334: 找ä¸åˆ°èœå•: %s"
+
+#, c-format
+msgid "E335: Menu not defined for %s mode"
+msgstr "E335: %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 "简体中文消æ¯ç»´æŠ¤è€…: Yuheng Xie <elephant@linux.net.cn>"
+
+msgid "Interrupt: "
+msgstr "已中断: "
+
+msgid "Press ENTER or type command to continue"
+msgstr "请按 ENTER 或其它命令继续"
+
+#, 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 ""
+"是(&Y)\n"
+"å¦(&N)"
+
+msgid ""
+"&Yes\n"
+"&No\n"
+"Save &All\n"
+"&Discard All\n"
+"&Cancel"
+msgstr ""
+"是(&Y)\n"
+"å¦(&N)\n"
+"全部ä¿å­˜(&A)\n"
+"全部丢弃(&D)\n"
+"å–æ¶ˆ(&C)"
+
+msgid "Select Directory dialog"
+msgstr "é€‰æ‹©ç›®å½•å¯¹è¯æ¡†"
+
+msgid "Save File dialog"
+msgstr "ä¿å­˜æ–‡ä»¶å¯¹è¯æ¡†"
+
+msgid "Open File dialog"
+msgstr "æ‰“å¼€æ–‡ä»¶å¯¹è¯æ¡†"
+
+#. TODO: non-GUI file selector here
+msgid "E338: Sorry, no file browser in console mode"
+msgstr "E338: æŠ±æ­‰ï¼ŒæŽ§åˆ¶å°æ¨¡å¼ä¸‹æ²¡æœ‰æ–‡ä»¶æµè§ˆå™¨"
+
+msgid "E766: Insufficient arguments for printf()"
+msgstr "E766: printf() çš„å‚æ•°ä¸è¶³"
+
+msgid "E767: Too many arguments to printf()"
+msgstr "E767: printf() çš„å‚æ•°è¿‡å¤š"
+
+msgid "W10: Warning: Changing a readonly file"
+msgstr "W10: 警告: 正在修改一个åªè¯»æ–‡ä»¶"
+
+msgid "Type number or click with mouse (<Enter> cancels): "
+msgstr "请输入数字或点击鼠标 (<Enter> å–æ¶ˆ): "
+
+msgid "Choice number (<Enter> 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 "Beep!"
+
+msgid "Vim: preserving files...\n"
+msgstr "Vim: 正在ä¿ç•™æ–‡ä»¶â€¦â€¦\n"
+
+#. close all memfiles, without deleting
+msgid "Vim: Finished.\n"
+msgstr "Vim: 结æŸã€‚\n"
+
+#, c-format
+msgid "ERROR: "
+msgstr "错误: "
+
+#, c-format
+msgid ""
+"\n"
+"[bytes] total alloc-freed %lu-%lu, in use %lu, peak use %lu\n"
+msgstr ""
+"\n"
+"[字节] 总共 alloc-free %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 "调用 shell 执行: \"%s\""
+
+msgid "E545: Missing colon"
+msgstr "E545: 缺少冒å·"
+
+msgid "E546: Illegal mode"
+msgstr "E546: 无效的模å¼"
+
+msgid "E547: Illegal mouseshape"
+msgstr "E547: 无效的鼠标形状"
+
+msgid "E548: digit expected"
+msgstr "E548: æ­¤å¤„éœ€è¦æ•°å­—"
+
+msgid "E549: Illegal percentage"
+msgstr "E549: 无效的百分比"
+
+msgid "Enter encryption key: "
+msgstr "输入密ç : "
+
+msgid "Enter same key again: "
+msgstr "请å†è¾“入一次: "
+
+msgid "Keys don't match!"
+msgstr "两次密ç ä¸åŒ¹é…ï¼"
+
+#, c-format
+msgid ""
+"E343: Invalid path: '**[number]' must be at the end of the path or be "
+"followed by '%s'."
+msgstr "E343: 无效的路径: '**[number]' 必须在路径末尾或者åŽé¢æŽ¥ '%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: 在路径中找ä¸åˆ°æ–‡ä»¶ \"%s\""
+
+#, c-format
+msgid "E346: No more directory \"%s\" found in cdpath"
+msgstr "E346: 在路径中找ä¸åˆ°æ›´å¤šçš„æ–‡ä»¶ \"%s\""
+
+#, c-format
+msgid "E347: No more file \"%s\" found in path"
+msgstr "E347: 在路径中找ä¸åˆ°æ›´å¤šçš„æ–‡ä»¶ \"%s\""
+
+#. Get here when the server can't be found.
+msgid "Cannot connect to Netbeans #2"
+msgstr "无法连接到 Netbeans #2"
+
+msgid "Cannot connect to Netbeans"
+msgstr "无法连接到 Netbeans"
+
+#, c-format
+msgid "E668: Wrong access mode for NetBeans connection info file: \"%s\""
+msgstr "E668: NetBeans è¿žæŽ¥ä¿¡æ¯æ–‡ä»¶ä¸­é”™è¯¯çš„访问模å¼: \"%s\""
+
+msgid "read from Netbeans socket"
+msgstr "从 Netbeans 套接字读å–"
+
+#, c-format
+msgid "E658: NetBeans connection lost for buffer %ld"
+msgstr "E658: 缓冲区 %ld 丢失 NetBeans 连接"
+
+msgid "E505: "
+msgstr "E505: "
+
+msgid "E774: 'operatorfunc' is empty"
+msgstr "E774: 'operatorfunc' 为空"
+
+msgid "E775: Eval feature not available"
+msgstr "E775: 求值功能ä¸å¯ç”¨"
+
+msgid "Warning: terminal cannot highlight"
+msgstr "警告: 你的终端ä¸èƒ½æ˜¾ç¤ºé«˜äº®"
+
+msgid "E348: No string under cursor"
+msgstr "E348: 光标处没有字符串"
+
+msgid "E349: No identifier under cursor"
+msgstr "E349: 光标处没有识别字"
+
+msgid "E352: Cannot erase folds with current 'foldmethod'"
+msgstr "E352: ä¸èƒ½åœ¨å½“å‰çš„ 'foldmethod' 下删除 fold"
+
+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 :quit<Enter> to exit Vim"
+msgstr "输入 :quit<Enter> 退出 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: 没有å‰ä¸€ä¸ªä½¿ç”¨çš„寄存器"
+
+#. must display the prompt
+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 行"
+
+msgid "block of 1 line yanked"
+msgstr "å¤åˆ¶äº† 1 行的å—"
+
+msgid "1 line yanked"
+msgstr "å¤åˆ¶äº† 1 行"
+
+#, c-format
+msgid "block of %ld lines yanked"
+msgstr "å¤åˆ¶äº† %ld 行的å—"
+
+#, c-format
+msgid "%ld lines yanked"
+msgstr "å¤åˆ¶äº† %ld 行"
+
+#, c-format
+msgid "E353: Nothing in register %s"
+msgstr "E353: 寄存器 %s 里没有东西"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Registers ---"
+msgstr ""
+"\n"
+"--- 寄存器 ---"
+
+msgid "Illegal register name"
+msgstr "无效的寄存器å"
+
+#, c-format
+msgid ""
+"\n"
+"# Registers:\n"
+msgstr ""
+"\n"
+"# 寄存器:\n"
+
+#, c-format
+msgid "E574: Unknown register type %d"
+msgstr "E574: 未知的寄存器类型 %d"
+
+#, c-format
+msgid "%ld Cols; "
+msgstr "%ld 列; "
+
+#, c-format
+msgid "Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Bytes"
+msgstr "选择了 %s%ld/%ld 行; %ld/%ld 个è¯; %ld/%ld 个字节"
+
+#, c-format
+msgid ""
+"Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Chars; %ld of %ld "
+"Bytes"
+msgstr "选择了 %s%ld/%ld 行; %ld/%ld 个è¯; %ld/%ld 个字符; %ld/%ld 个字节"
+
+#, c-format
+msgid "Col %s of %s; Line %ld of %ld; Word %ld of %ld; Byte %ld of %ld"
+msgstr "第 %s/%s 列; 第 %ld/%ld 行; 第 %ld/%ld 个è¯; 第 %ld/%ld 个字节"
+
+#, c-format
+msgid ""
+"Col %s of %s; Line %ld of %ld; Word %ld of %ld; Char %ld of %ld; Byte %ld of "
+"%ld"
+msgstr ""
+"第 %s/%s 列; 第 %ld/%ld 行; 第 %ld/%ld 个è¯; 第 %ld/%ld 个字符; 第 %ld/%ld 个"
+"字节"
+
+#, c-format
+#~ msgid "(+%ld for BOM)"
+#~ msgstr ""
+
+#~ msgid "%<%f%h%m%=Page %N"
+#~ msgstr ""
+
+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: ä¸å…许在 modeline 中使用"
+
+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>"
+
+msgid "E529: Cannot set 'term' to empty string"
+msgstr "E529: ä¸èƒ½è®¾å®š 'term' 为空字符串"
+
+msgid "E530: Cannot change term in GUI"
+msgstr "E530: 在图形界é¢ä¸­ä¸èƒ½æ”¹å˜ç»ˆç«¯"
+
+msgid "E531: Use \":gui\" to start the GUI"
+msgstr "E531: 请用 \":gui\" å¯åŠ¨å›¾å½¢ç•Œé¢"
+
+msgid "E589: 'backupext' and 'patchmode' are equal"
+msgstr "E589: 'backupext' 和 'patchmode' 相等"
+
+msgid "E617: Cannot be changed in the GTK+ 2 GUI"
+msgstr "E617: 在 GTK+ 2 图形界é¢ä¸­ä¸èƒ½æ›´æ”¹"
+
+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 "E590: A preview window already exists"
+msgstr "E590: 预览窗å£å·²å­˜åœ¨"
+
+msgid "W17: Arabic requires UTF-8, do ':set encoding=utf-8'"
+msgstr "W17: Arabic éœ€è¦ UTF-8,请执行 ':set encoding=utf-8'"
+
+#, 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"
+
+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 "ä¸èƒ½åˆ‡æ¢ä¸»æŽ§å°(console)æ¨¡å¼ !?\n"
+
+msgid "mch_get_shellsize: not a console??\n"
+msgstr "mch_get_shellsize: 䏿˜¯ä¸»æŽ§å°(console)??\n"
+
+#. if Vim opened a window: Executing a shell may cause crashes
+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: é€‰æ‹©æ‰“å°æœºå¤±è´¥"
+
+#, 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 "E245: Illegal char '%c' in font name \"%s\""
+msgstr "E245: 䏿­£ç¡®çš„字符 '%c' 出现在字体åç§° \"%s\" 内"
+
+msgid "Vim: Double signal, exiting\n"
+msgstr "Vim: åŒé‡ä¿¡å·ï¼Œé€€å‡ºä¸­\n"
+
+#, c-format
+msgid "Vim: Caught deadly signal %s\n"
+msgstr "Vim: 拦截到致命信å·(deadly signal) %s\n"
+
+#, c-format
+msgid "Vim: Caught deadly signal\n"
+msgstr "Vim: 拦截到致命信å·(deadly signal)\n"
+
+#, c-format
+msgid "Opening the X display took %ld msec"
+msgstr "打开 X display 用时 %ld 秒"
+
+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 "
+msgstr ""
+"\n"
+"无法执行 shell"
+
+msgid ""
+"\n"
+"Cannot execute shell sh\n"
+msgstr ""
+"\n"
+"无法执行 shell sh\n"
+
+msgid ""
+"\n"
+"shell returned "
+msgstr ""
+"\n"
+"Shell 已返回"
+
+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 的连接"
+
+# do not translate
+#, c-format
+msgid "dlerror = \"%s\""
+msgstr "dlerror = \"%s\""
+
+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 连接监视失败"
+
+#, 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 "shell returned %d"
+msgstr "Shell 返回 %d"
+
+#, 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 ""
+"在你的 $PATH 中找ä¸åˆ° VIMRUN.EXE。\n"
+"外部命令执行完毕åŽå°†ä¸ä¼šæš‚åœã€‚\n"
+"è¿›ä¸€æ­¥è¯´æ˜Žè¯·è§ :help win32-vimrun"
+
+msgid "Vim Warning"
+msgstr "Vim 警告"
+
+#, 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: 没有更多的项"
+
+#, c-format
+msgid "(%d of %d)%s%s: "
+msgstr "(%d / %d)%s%s: "
+
+msgid " (line deleted)"
+msgstr " (行已删除)"
+
+msgid "E380: At bottom of quickfix stack"
+msgstr "E380: Quickfix 堆栈底端"
+
+msgid "E381: At top of quickfix stack"
+msgstr "E381: Quickfix 堆栈顶端"
+
+#, c-format
+msgid "error list %d of %d; %d errors"
+msgstr "错误列表 %d / %d;共 %d 个错误"
+
+msgid "E382: Cannot write, 'buftype' option is set"
+msgstr "E382: 无法写入,已设定选项 'buftype'"
+
+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%%[] 中有无效的项"
+
+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 "E53: Unmatched %s%%("
+msgstr "E53: ä¸åŒ¹é…çš„ %s%%("
+
+#, c-format
+msgid "E54: Unmatched %s("
+msgstr "E54: ä¸åŒ¹é…çš„ %s("
+
+#, c-format
+msgid "E55: Unmatched %s)"
+msgstr "E55: ä¸åŒ¹é…çš„ %s)"
+
+#, 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 å‰é¢æ— å†…容"
+
+msgid "E65: Illegal back reference"
+msgstr "E65: 无效的回引"
+
+msgid "E66: \\z( not allowed here"
+msgstr "E66: 此处ä¸å…许 \\z("
+
+msgid "E67: \\z1 et al. not allowed here"
+msgstr "E67: 此处ä¸å…许 \\z1 ç­‰"
+
+msgid "E68: Invalid character after \\z"
+msgstr "E68: \\z åŽé¢æœ‰æ— æ•ˆçš„字符"
+
+#, c-format
+msgid "E69: Missing ] after %s%%["
+msgstr "E69: %s%%[ åŽç¼ºå°‘ ]"
+
+#, c-format
+msgid "E70: Empty %s%%[]"
+msgstr "E70: 空的 %s%%[]"
+
+#, 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 "E769: Missing ] after %s["
+msgstr "E769: %s[ åŽç¼ºå°‘ ]"
+
+#, c-format
+msgid "E554: Syntax error in %s{...}"
+msgstr "E554: %s{...} 中语法错误"
+
+msgid "External submatches:\n"
+msgstr "外部符åˆ:\n"
+
+msgid " VREPLACE"
+msgstr " V-替æ¢"
+
+msgid " REPLACE"
+msgstr " 替æ¢"
+
+msgid " REVERSE"
+msgstr " åå‘"
+
+msgid " INSERT"
+msgstr " æ’å…¥"
+
+msgid " (insert)"
+msgstr " (æ’å…¥)"
+
+msgid " (replace)"
+msgstr " (替æ¢)"
+
+msgid " (vreplace)"
+msgstr " (V-替æ¢)"
+
+msgid " Hebrew"
+msgstr " Hebrew"
+
+msgid " Arabic"
+msgstr " Arabic"
+
+msgid " (lang)"
+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 " (包括上次列出符åˆé¡¹)"
+
+#. cursor at status line
+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: 找ä¸åˆ° pattern"
+
+msgid "E759: Format error in spell file"
+msgstr "E759: 拼写文件格å¼é”™è¯¯"
+
+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 "压缩å•è¯æ ‘……"
+
+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\" or \"%s.ascii.spl\""
+
+#, 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 "Warning: region %s not supported"
+msgstr "警告: 区域 %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 "%s 第 %d 行,FLAG 的值无效: %s"
+
+#, c-format
+msgid "FLAG after using flags in %s line %d: %s"
+msgstr "%s 第 %d 行,在使用标志åŽå‡ºçް FLAG: %s"
+
+#, c-format
+#~ msgid ""
+#~ "Defining COMPOUNDFORBIDFLAG after PFX item may give wrong results in %s line "
+#~ "%d"
+#~ msgstr ""
+
+#, c-format
+#~ msgid ""
+#~ "Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in %s line "
+#~ "%d"
+#~ msgstr ""
+
+#, c-format
+msgid "Wrong COMPOUNDWORDMAX value in %s line %d: %s"
+msgstr "%s 第 %d 行,错误的 COMPOUNDWORDMAX 值: %s"
+
+#, c-format
+msgid "Wrong COMPOUNDMIN value in %s line %d: %s"
+msgstr "%s 第 %d 行,错误的 COMPOUNDMIN 值: %s"
+
+#, c-format
+msgid "Wrong COMPOUNDSYLMAX value in %s line %d: %s"
+msgstr "%s 第 %d 行,错误的 COMPOUNDSYLMAX 值: %s"
+
+#, c-format
+msgid "Wrong CHECKCOMPOUNDPATTERN value in %s line %d: %s"
+msgstr "%s 第 %d 行,错误的 CHECKCOMPOUNDPATTERN 值: %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 ""
+"%s 第 %d 行,附加项被 BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST 使"
+"用: %s"
+
+#, c-format
+msgid "Expected Y or N in %s line %d: %s"
+msgstr "%s 第 %d è¡Œï¼Œæ­¤å¤„éœ€è¦ Y 或 N: %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 "%s 第 %d è¡Œï¼Œæ­¤å¤„éœ€è¦ REP(SAL) 计数"
+
+#, c-format
+msgid "Expected MAP count in %s line %d"
+msgstr "%s 第 %d è¡Œï¼Œæ­¤å¤„éœ€è¦ MAP 计数"
+
+#, c-format
+msgid "Duplicate character in MAP in %s line %d"
+msgstr "%s 第 %d 行,MAP 中存在é‡å¤çš„字符"
+
+#, 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 "%s 中缺少 FOL/LOW/UPP 行"
+
+msgid "COMPOUNDSYLMAX used without SYLLABLE"
+msgstr "在没有 SYLLABLE 的情况下使用了 COMPOUNDSYLMAX"
+
+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 "%s 中缺少 SOFO%s 行"
+
+#, c-format
+msgid "Both SAL and SOFO lines in %s"
+msgstr "%s åŒæ—¶å‡ºçް SQL å’Œ SOFO 行"
+
+#, 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 %6d - %s"
+msgstr "第 %6d 行,第 %6d 个å•è¯ - %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 "å¿½ç•¥äº†å«æœ‰éž ASCII 字符的 %d 个å•è¯ï¼Œåœ¨ %s 中"
+
+#, c-format
+msgid "Reading word file %s ..."
+msgstr "读å–å•è¯æ–‡ä»¶ %s ……"
+
+#, c-format
+#~ msgid "Duplicate /encoding= line ignored in %s line %d: %s"
+#~ msgstr ""
+
+#, c-format
+msgid "/encoding= line after word ignored in %s line %d: %s"
+msgstr "%s 第 %d 行,å•è¯åŽçš„ /encoding= 行已被忽略: %s"
+
+#, c-format
+msgid "Duplicate /regions= line ignored in %s line %d: %s"
+msgstr "%s 第 %d 行,é‡å¤çš„ /regions= 行已被忽略: %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 "å¿½ç•¥äº†å«æœ‰éž ASCII 字符的 %d 个å•è¯"
+
+#, c-format
+msgid "Compressed %d of %d nodes; %d (%d%%) remaining"
+msgstr "压缩了 %d/%d 个节点;剩余 %d (%d%%)"
+
+msgid "Reading back spell file..."
+msgstr "è¯»å–æ‹¼å†™æ–‡ä»¶â€¦â€¦"
+
+#.
+#. * Go through the trie of good words, soundfold each word and add it to
+#. * the soundfold trie.
+#.
+msgid "Performing soundfolding..."
+msgstr "正在 soundfolding……"
+
+#, c-format
+msgid "Number of words after soundfolding: %ld"
+msgstr "soundfolding åŽçš„å•è¯æ•°: %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: 输出文件åä¸èƒ½å«æœ‰åŒºåŸŸå"
+
+msgid "E754: Only up to 8 regions supported"
+msgstr "E754: æœ€å¤šåªæ”¯æŒ 8 个区域"
+
+#, c-format
+msgid "E755: Invalid region in %s"
+msgstr "E755: %s 出现无效的范围"
+
+msgid "Warning: both compounding and NOBREAK specified"
+msgstr "警告: åŒæ—¶æŒ‡å®šäº† compounding å’Œ 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 removed from %s"
+msgstr "从 %s 中删除了å•è¯"
+
+#, c-format
+msgid "Word added to %s"
+msgstr "å‘ %s 中添加了å•è¯"
+
+msgid "E763: Word characters differ between spell files"
+msgstr "E763: 拼写文件之间的字符ä¸ç›¸åŒ"
+
+msgid "Sorry, no suggestions"
+msgstr "抱歉,没有建议"
+
+#, c-format
+msgid "Sorry, only %ld suggestions"
+msgstr "æŠ±æ­‰ï¼Œåªæœ‰ %ld æ¡å»ºè®®"
+
+#. avoid more prompt
+#, 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"
+
+#, 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 ""
+
+#, c-format
+#~ msgid "E780: .sug file is for newer version of Vim: %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E781: .sug file doesn't match .spl file: %s"
+#~ msgstr ""
+
+#, fuzzy, c-format
+#~ msgid "E782: error while reading .sug file: %s"
+#~ msgstr "E47: 读å–错误文件失败"
+
+#. This should have been checked when generating the .spl
+#. * file.
+#~ msgid "E783: duplicate char in MAP entry"
+#~ msgstr ""
+
+#, c-format
+msgid "E390: Illegal argument: %s"
+msgstr "E390: æ— æ•ˆçš„å‚æ•°: %s"
+
+#, c-format
+msgid "E391: No such syntax cluster: %s"
+msgstr "E391: 无此语法 cluster: \"%s\""
+
+msgid "No Syntax items defined for this buffer"
+msgstr "这个缓冲区没有定义任何语法项"
+
+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"
+"--- è¯­æ³•åŒæ­¥é¡¹ç›® (Syntax sync items) ---"
+
+msgid ""
+"\n"
+"syncing on items"
+msgstr ""
+"\n"
+"åŒæ­¥ä¸­:"
+
+msgid ""
+"\n"
+"--- Syntax items ---"
+msgstr ""
+"\n"
+"--- 语法项目 ---"
+
+#, c-format
+msgid "E392: No such syntax cluster: %s"
+msgstr "E392: 无此语法 cluster: \"%s\""
+
+msgid "minimal "
+msgstr "最å°"
+
+msgid "maximal "
+msgstr "最大"
+
+#, fuzzy
+#~ msgid "; match "
+#~ msgstr "åŒ¹é… %d"
+
+#, fuzzy
+#~ msgid " line breaks"
+#~ msgstr "少于一行"
+
+msgid "E395: contains argument not accepted here"
+msgstr "E395: ä½¿ç”¨äº†ä¸æ­£ç¡®çš„傿•°"
+
+msgid "E396: containedin argument not accepted here"
+msgstr "E396: ä½¿ç”¨äº†ä¸æ­£ç¡®çš„傿•°"
+
+msgid "E393: group[t]here not accepted here"
+msgstr "E393: ä½¿ç”¨äº†ä¸æ­£ç¡®çš„傿•°"
+
+#, c-format
+msgid "E394: Didn't find region item for %s"
+msgstr "E394: 找ä¸åˆ° %s çš„ region item"
+
+msgid "E397: Filename required"
+msgstr "E397: éœ€è¦æ–‡ä»¶åç§°"
+
+#, c-format
+msgid "E747: Missing ']': %s"
+msgstr "E747: 缺少 ']': %s"
+
+#, c-format
+msgid "E398: Missing '=': %s"
+msgstr "E398: 缺少 '=': %s"
+
+#, c-format
+msgid "E399: Not enough arguments: syntax region %s"
+msgstr "E399: syntax region %s çš„å‚æ•°å¤ªå°‘"
+
+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 必须是列表里的第一个"
+
+#, c-format
+msgid "E409: Unknown group name: %s"
+msgstr "E409: 䏿­£ç¡®çš„组å: %s"
+
+#, c-format
+msgid "E410: Invalid :syntax subcommand: %s"
+msgstr "E410: 䏿­£ç¡®çš„ :syntax å­å‘½ä»¤: %s"
+
+msgid "E679: recursive loop loading syncolor.vim"
+msgstr "E679: 加载 syncolor.vim 时出现嵌套循环"
+
+#, c-format
+msgid "E411: highlight group not found: %s"
+msgstr "E411: 找ä¸åˆ° highlight group: %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: é”™è¯¯çš„å‰æ™¯é¢œè‰²"
+
+msgid "E420: BG color unknown"
+msgstr "E420: 错误的背景颜色"
+
+#, 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 "E555: at bottom of tag stack"
+msgstr "E555: 已在 tag 堆栈底部"
+
+msgid "E556: at top of tag stack"
+msgstr "E556: 已在 tag 堆栈顶部"
+
+msgid "E425: Cannot go before first matching tag"
+msgstr "E425: 已到第一个匹é…çš„ tag"
+
+#, c-format
+msgid "E426: tag not found: %s"
+msgstr "E426: 找ä¸åˆ° tag: %s"
+
+msgid " # pri kind tag"
+msgstr " # pri kind tag"
+
+msgid "file\n"
+msgstr "文件\n"
+
+msgid "E427: There is only one matching tag"
+msgstr "E427: åªæœ‰ä¸€ä¸ªåŒ¹é…çš„ tag"
+
+msgid "E428: Cannot go beyond last matching tag"
+msgstr "E428: 己到最åŽä¸€ä¸ªåŒ¹é…çš„ tag"
+
+#, c-format
+msgid "File \"%s\" does not exist"
+msgstr "文件 \"%s\" ä¸å­˜åœ¨"
+
+#. Give an indication of the number of matching tags
+#, c-format
+msgid "tag %d of %d%s"
+msgstr "找到 tag: %d / %d%s"
+
+msgid " or more"
+msgstr " 或更多"
+
+msgid " Using tag with different case!"
+msgstr " 以ä¸åŒå¤§å°å†™æ¥ä½¿ç”¨ tagï¼"
+
+#, c-format
+msgid "E429: File \"%s\" does not exist"
+msgstr "E429: 文件 \"%s\" ä¸å­˜åœ¨"
+
+#. Highlight title
+msgid ""
+"\n"
+" # TO tag FROM line in file/text"
+msgstr ""
+"\n"
+" # 到 tag 从 行 在 文件/文本"
+
+#, c-format
+msgid "Searching tags file %s"
+msgstr "查找 tag 文件 %s"
+
+#, c-format
+msgid "E430: Tag file path truncated for %s\n"
+msgstr "E430: Tag 文件路径被截断为 %s\n"
+
+#, c-format
+msgid "E431: Format error in tags file \"%s\""
+msgstr "E431: Tag 文件 \"%s\" æ ¼å¼é”™è¯¯"
+
+#, c-format
+msgid "Before byte %ld"
+msgstr "在第 %ld 字节之å‰"
+
+#, c-format
+msgid "E432: Tags file not sorted: %s"
+msgstr "E432: Tag 文件未排åº: %s"
+
+#. never opened any tags file
+msgid "E433: No tags file"
+msgstr "E433: 没有 tag 文件"
+
+msgid "E434: Can't find tag pattern"
+msgstr "E434: 找ä¸åˆ° tag 模å¼"
+
+msgid "E435: Couldn't find tag, just guessing!"
+msgstr "E435: 找ä¸åˆ° tag,试ç€çŒœï¼"
+
+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: termcap 中没有 \"%s\" 项"
+
+msgid "E437: terminal capability \"cm\" required"
+msgstr "E437: 终端需è¦èƒ½åŠ› \"cm\""
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Terminal keys ---"
+msgstr ""
+"\n"
+"--- 终端按键 ---"
+
+msgid "new shell started\n"
+msgstr "å¯åŠ¨æ–° shell\n"
+
+msgid "Vim: Error reading input, exiting...\n"
+msgstr "Vim: 读错误,退出中...\n"
+
+#. must display the prompt
+msgid "No undo possible; continue anyway"
+msgstr "无法撤销;ä»ç„¶ç»§ç»­"
+
+msgid "Already at oldest change"
+msgstr "å·²ä½äºŽæœ€æ—§çš„æ”¹å˜"
+
+msgid "Already at newest change"
+msgstr "å·²ä½äºŽæœ€æ–°çš„æ”¹å˜"
+
+#, c-format
+msgid "Undo number %ld not found"
+msgstr "找ä¸åˆ°æ’¤é”€å· %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 "before"
+
+msgid "after"
+msgstr "after"
+
+msgid "Nothing to undo"
+msgstr "æ— å¯æ’¤é”€"
+
+msgid "number changes time"
+msgstr " ç¼–å· æ”¹å˜ æ—¶é—´"
+
+msgid "E439: undo list corrupt"
+msgstr "E439: 撤销列表æŸå"
+
+msgid "E440: undo line missing"
+msgstr "E440: 找ä¸åˆ°è¦æ’¤é”€çš„行"
+
+#. Only MS VC 4.1 and earlier can do Win32s
+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"
+"Included 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 "无图形界é¢ã€‚"
+
+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 " Features included (+) or not (-):\n"
+msgstr " å¯ä½¿ç”¨(+)与ä¸å¯ä½¿ç”¨(-)的功能:\n"
+
+msgid " system vimrc file: \""
+msgstr " 系统 vimrc 文件: \""
+
+msgid " user vimrc file: \""
+msgstr " 用户 vimrc 文件: \""
+
+msgid " 2nd user vimrc file: \""
+msgstr " 第二用户 vimrc 文件: \""
+
+msgid " 3rd user vimrc file: \""
+msgstr " 第三用户 vimrc 文件: \""
+
+msgid " user exrc file: \""
+msgstr " 用户 exrc 文件: \""
+
+msgid " 2nd user exrc file: \""
+msgstr " 第二用户 exrc 文件: \""
+
+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 " 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 " 调试版本"
+
+msgid "VIM - Vi IMproved"
+msgstr "VIM - Vi IMproved"
+
+msgid "version "
+msgstr "版本 "
+
+msgid "by Bram Moolenaar et al."
+msgstr "维护人 Bram Moolenaar 等"
+
+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> 查看在线帮助 "
+
+msgid "type :help version7<Enter> for version info"
+msgstr "输入 :help version7<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 "èœå• 编辑->全局设定->å¼€/å…³æ’å…¥æ¨¡å¼ "
+
+#, fuzzy
+#~ msgid " for two modes "
+#~ msgstr " # pid æ•°æ®åº“åç§° prepend path\n"
+
+#~ msgid "menu Edit->Global Settings->Toggle Vi Compatible"
+#~ msgstr ""
+
+#, fuzzy
+#~ msgid " for Vim defaults "
+#~ msgstr " # pid æ•°æ®åº“åç§° prepend path\n"
+
+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 "èœå• Help->Sponsor/Register 查看说明 "
+
+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 "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 "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 "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 ""
+
+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)"
+
+#. Now concatenate
+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 "--缓冲区无内容--"
+
+#.
+#. * 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: 命令被中止"
+
+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 或 tag 查找中ä¸å…许此命令"
+
+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: 内部错误"
+
+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 "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()\" 失败"
+
+#, 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: 无法使用图形界é¢: 编译时没有å¯ç”¨"
+
+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"
+
+#, 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 "E37: No write since last change (add ! to override)"
+msgstr "E37: 已修改但尚未ä¿å­˜ (å¯ç”¨ ! 强制执行)"
+
+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: 无法打开 display"
+
+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: 没有 location 列表"
+
+msgid "E43: Damaged match string"
+msgstr "E43: å·²æŸå的匹é…字符串"
+
+msgid "E44: Corrupted regexp program"
+msgstr "E44: å·²æŸå的正则表达å¼ç¨‹åº"
+
+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 "E46: Cannot set variable in the sandbox: \"%s\""
+msgstr "E46: ä¸èƒ½åœ¨ sandbox 中设定å˜é‡: \"%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: æ— æ³•è¯»å– sign æ•°æ®ï¼"
+
+msgid "E72: Close error on swap file"
+msgstr "E72: äº¤æ¢æ–‡ä»¶å…³é—­é”™è¯¯"
+
+msgid "E73: tag stack empty"
+msgstr "E73: tag 堆栈为空"
+
+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 "Zero count"
+msgstr "计数为零"
+
+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 ""
+
+msgid "E744: NetBeans does not allow changes in read-only files"
+msgstr "E744: NetBeans ä¸å…许改å˜åªè¯»æ–‡ä»¶"
+
+#, c-format
+msgid "E685: Internal error: %s"
+msgstr "E685: 内部错误: %s"
+
+msgid "E363: pattern uses more memory than 'maxmempattern'"
+msgstr "E363: 表达å¼çš„内存使用超出 'maxmempattern'"
+
+msgid "E749: empty buffer"
+msgstr "E749: 空的缓冲区"
+
+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 "search hit TOP, continuing at BOTTOM"
+msgstr "已查找到文件开头,å†ä»Žç»“尾继续查找"
+
+msgid "search hit BOTTOM, continuing at TOP"
+msgstr "已查找到文件结尾,å†ä»Žå¼€å¤´ç»§ç»­æŸ¥æ‰¾"
+
+#~ 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 "E119: Not enough arguments for function: %s"
+#~ msgstr "E119: 函数 %s çš„å‚æ•°å¤ªå°‘"
+
+#~ msgid "E120: Using <SID> not in a script context: %s"
+#~ msgstr "E120: <SID> ä¸èƒ½åœ¨ script 上下文外使用: %s"
+
+#~ msgid "E123: Undefined function: %s"
+#~ msgstr "E123: 函数 %s 尚未定义"
+
+#~ msgid "E127: Cannot redefine function %s: It is in use"
+#~ msgstr "E127: 函数 %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/po/zh_CN.cp936.po b/src/po/zh_CN.cp936.po
new file mode 100644
index 0000000000..585789e956
--- /dev/null
+++ b/src/po/zh_CN.cp936.po
@@ -0,0 +1,6140 @@
+# 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: 2006-04-21 15:16+0800\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"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=gbk\n"
+"Content-Transfer-Encoding: 8-bit\n"
+
+msgid "E82: Cannot allocate any buffer, exiting..."
+msgstr "E82: ÎÞ·¨·ÖÅäÈκλº³åÇø£¬Í˳ö³ÌÐò..."
+
+msgid "E83: Cannot allocate buffer, using other one..."
+msgstr "E83: ÎÞ·¨·ÖÅ仺³åÇø£¬Ê¹ÓÃÁíÒ»¸ö»º³åÇø..."
+
+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 "E84: No modified buffer found"
+msgstr "E84: ûÓÐÐ޸ĹýµÄ»º³åÇø"
+
+#. back where we started, didn't find anything.
+msgid "E85: There is no listed buffer"
+msgstr "E85: ûÓпÉÁгöµÄ»º³åÇø"
+
+#, c-format
+msgid "E86: Buffer %ld does not exist"
+msgstr "E86: »º³åÇø %ld ²»´æÔÚ"
+
+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 "E90: Cannot unload last buffer"
+msgstr "E90: ÎÞ·¨ÊÍ·Å×îºóÒ»¸ö»º³åÇø"
+
+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 "[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 "[δÃüÃû]"
+
+#. must be a help buffer
+msgid "help"
+msgstr "°ïÖú"
+
+msgid "[Help]"
+msgstr "[°ïÖú]"
+
+msgid "[Preview]"
+msgstr "[Ô¤ÀÀ]"
+
+msgid "All"
+msgstr "È«²¿"
+
+msgid "Bot"
+msgstr "µ×¶Ë"
+
+msgid "Top"
+msgstr "¶¥¶Ë"
+
+#, c-format
+msgid ""
+"\n"
+"# Buffer list:\n"
+msgstr ""
+"\n"
+"# »º³åÇøÁбí:\n"
+
+msgid "[Location List]"
+msgstr "[Location Áбí]"
+
+msgid "[Quickfix List]"
+msgstr "[Quickfix Áбí]"
+
+msgid ""
+"\n"
+"--- Signs ---"
+msgstr ""
+"\n"
+"--- Signs ---"
+
+#, c-format
+msgid "Signs for %s:"
+msgstr "%s µÄ Signs:"
+
+#, c-format
+msgid " line=%ld id=%d name=%s"
+msgstr " ÐÐ=%ld id=%d Ãû³Æ=%s"
+
+#, c-format
+msgid "E96: Can not diff more than %ld buffers"
+msgstr "E96: ²»ÄܱȽÏ(diff) %ld ¸öÒÔÉϵĻº³åÇø"
+
+msgid "E97: Cannot create diffs"
+msgstr "E97: ÎÞ·¨´´½¨ diff"
+
+msgid "Patch file"
+msgstr "Patch Îļþ"
+
+msgid "E98: Cannot read diff output"
+msgstr "E98: ÎÞ·¨¶ÁÈ¡ diff µÄÊä³ö"
+
+msgid "E99: Current buffer is not in diff mode"
+msgstr "E99: µ±Ç°»º³åÇø²»ÔÚ 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: ¸´ºÏ×Ö·û(digraph)Öв»ÄÜʹÓà Escape"
+
+msgid "E544: Keymap file not found"
+msgstr "E544: ÕÒ²»µ½ Keymap Îļþ"
+
+msgid "E105: Using :loadkeymap not in a sourced file"
+msgstr "E105: ²»ÊÇÔڽű¾ÎļþÖÐʹÓà :loadkeymap "
+
+msgid " Keyword completion (^N^P)"
+msgstr " ¹Ø¼ü×Ö²¹È« (^N^P)"
+
+#. ctrl_x_mode == 0, ^P/^N compl.
+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 " Tag ²¹È« (^]^N^P)"
+
+#, fuzzy
+#~ 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 " Dictionary ²¹È« (^K^N^P)"
+
+msgid " Thesaurus completion (^T^N^P)"
+msgstr " Thesaurus ²¹È« (^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 " È«Äܲ¹È« (^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 "'dictionary' option is empty"
+msgstr "Ñ¡Ïî 'dictionary' Ϊ¿Õ"
+
+msgid "'thesaurus' option is empty"
+msgstr "Ñ¡Ïî 'thesaurus' Ϊ¿Õ"
+
+#, c-format
+msgid "Scanning dictionary: %s"
+msgstr "ÕýÔÚɨÃè dictionary: %s"
+
+msgid " (insert) Scroll (^E/^Y)"
+msgstr " (²åÈë) Scroll (^E/^Y)"
+
+msgid " (replace) Scroll (^E/^Y)"
+msgstr " (Ìæ»») Scroll (^E/^Y)"
+
+#, c-format
+msgid "Scanning: %s"
+msgstr "ÕýÔÚɨÃè: %s"
+
+#, c-format
+msgid "Scanning tags."
+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.
+#.
+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 "E684: list index out of range: %ld"
+msgstr "E684: List Ë÷Òý³¬³ö·¶Î§: %ld"
+
+#, c-format
+msgid "E121: Undefined variable: %s"
+msgstr "E121: 䶨ÒåµÄ±äÁ¿: %s"
+
+msgid "E111: Missing ']'"
+msgstr "E111: ȱÉÙ ']'"
+
+#, c-format
+msgid "E686: Argument of %s must be a List"
+msgstr "E686: %s µÄ²ÎÊý±ØÐëÊÇ List"
+
+#, c-format
+msgid "E712: Argument of %s must be a List or Dictionary"
+msgstr "E712: %s µÄ²ÎÊý±ØÐëÊÇ List »òÕß Dictionary"
+
+msgid "E713: Cannot use empty key for Dictionary"
+msgstr "E713: Dictionary µÄ¼ü²»ÄÜΪ¿Õ"
+
+msgid "E714: List required"
+msgstr "E714: ÐèÒª List"
+
+msgid "E715: Dictionary required"
+msgstr "E715: ÐèÒª Dictionary"
+
+#, 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: Dictionary Öв»´æÔÚ¼ü: %s"
+
+#, c-format
+msgid "E122: Function %s already exists, add ! to replace it"
+msgstr "E122: º¯Êý %s ÒÑ´æÔÚ£¬Çë¼Ó ! Ç¿ÖÆÌæ»»"
+
+msgid "E717: Dictionary entry already exists"
+msgstr "E717: Dictionary ÏîÒÑ´æÔÚ"
+
+msgid "E718: Funcref required"
+msgstr "E718: ÐèÒª Funcref"
+
+msgid "E719: Cannot use [:] with a Dictionary"
+msgstr "E719: ²»ÄÜ¶Ô Dictionary ʹÓà [:]"
+
+#, c-format
+msgid "E734: Wrong variable type for %s="
+msgstr "E734: %s= µÄ±äÁ¿ÀàÐͲ»ÕýÈ·"
+
+#, c-format
+msgid "E130: Unknown function: %s"
+msgstr "E130: δ֪µÄº¯Êý: %s"
+
+#, c-format
+msgid "E461: Illegal variable name: %s"
+msgstr "E461: ÎÞЧµÄ±äÁ¿Ãû: %s"
+
+msgid "E687: Less targets than List items"
+msgstr "E687: Ä¿±ê±È List ÏîÊýÉÙ"
+
+msgid "E688: More targets than List items"
+msgstr "E688: Ä¿±ê±È List ÏîÊý¶à"
+
+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: Ö»ÄÜË÷Òý List »ò Dictionary"
+
+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: :for ºóȱÉÙ \"in\""
+
+#, c-format
+msgid "E107: Missing parentheses: %s"
+msgstr "E107: ȱÉÙÀ¨ºÅ: %s"
+
+#, c-format
+msgid "E108: No such variable: \"%s\""
+msgstr "E108: Î޴˱äÁ¿: \"%s\""
+
+msgid "E743: variable nested too deep for (un)lock"
+msgstr "E743: (un)lock µÄ±äÁ¿Ç¶Ì×¹ýÉî"
+
+msgid "E109: Missing ':' after '?'"
+msgstr "E109: '?' ºóȱÉÙ ':'"
+
+msgid "E691: Can only compare List with List"
+msgstr "E691: Ö»ÄÜ±È½Ï List ºÍ List"
+
+msgid "E692: Invalid operation for Lists"
+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 "E693: Can only compare Funcref with Funcref"
+msgstr "E693: Ö»ÄÜ±È½Ï Funcref ºÍ Funcref"
+
+msgid "E694: Invalid operation for Funcrefs"
+msgstr "E694: ¶Ô Funcrefs ÎÞЧµÄ²Ù×÷"
+
+msgid "E110: Missing ')'"
+msgstr "E110: ȱÉÙ ')'"
+
+msgid "E695: Cannot index a Funcref"
+msgstr "E695: ²»ÄÜË÷ÒýÒ»¸ö Funcref"
+
+#, 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"
+
+#, c-format
+msgid "E696: Missing comma in List: %s"
+msgstr "E696: List ÖÐȱÉÙ¶ººÅ: %s"
+
+#, c-format
+msgid "E697: Missing end of List ']': %s"
+msgstr "E697: List ȱÉÙ½áÊø·û ']': %s"
+
+#, c-format
+msgid "E720: Missing colon in Dictionary: %s"
+msgstr "E720: Dictionary ÖÐȱÉÙðºÅ: %s"
+
+#, c-format
+msgid "E721: Duplicate key in Dictionary: \"%s\""
+msgstr "E721: Dictionary ÖгöÏÖÖØ¸´µÄ¼ü: \"%s\""
+
+#, c-format
+msgid "E722: Missing comma in Dictionary: %s"
+msgstr "E722: Dictionary ÖÐȱÉÙ¶ººÅ: %s"
+
+#, c-format
+msgid "E723: Missing end of Dictionary '}': %s"
+msgstr "E723: Dictionary ȱÉÙ½áÊø·û '}': %s"
+
+msgid "E724: variable nested too deep for displaying"
+msgstr "E724: ±äÁ¿Ç¶Ì×¹ýÉîÎÞ·¨ÏÔʾ"
+
+msgid "E699: Too many arguments"
+msgstr "E699: ²ÎÊý¹ý¶à"
+
+msgid "E785: complete() can only be used in Insert mode"
+msgstr "E785: complete() Ö»ÄÜÔÚ²åÈëģʽÖÐʹÓÃ"
+
+#.
+#. * 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 "È·¶¨(&O)"
+
+#, c-format
+msgid "E737: Key already exists: %s"
+msgstr "E737: ¼üÒÑ´æÔÚ: %s"
+
+#, c-format
+msgid "+-%s%3ld lines: "
+msgstr "+-%s%3ld ÐÐ: "
+
+#, c-format
+msgid "E700: Unknown function: %s"
+msgstr "E700: δ֪µÄº¯Êý: %s"
+
+msgid ""
+"&OK\n"
+"&Cancel"
+msgstr ""
+"È·¶¨(&O)\n"
+"È¡Ïû(&C)"
+
+msgid "called inputrestore() more often than inputsave()"
+msgstr "inputrestore() µÄµ÷ÓôÎÊý¶àÓÚ inputsave()"
+
+msgid "E786: Range not allowed"
+msgstr "E786: ²»ÔÊÐíµÄ·¶Î§"
+
+msgid "E701: Invalid type for len()"
+msgstr "E701: len() µÄÀàÐÍÎÞЧ"
+
+msgid "E726: Stride is zero"
+msgstr "E726: ²½³¤ÎªÁã"
+
+msgid "E727: Start past end"
+msgstr "E727: ÆðʼֵÔÚÖÕÖ¹Öµºó"
+
+msgid "<empty>"
+msgstr "<¿Õ>"
+
+msgid "E240: No connection to Vim server"
+msgstr "E240: ûÓе½ Vim ·þÎñÆ÷µÄÁ¬½Ó"
+
+#, c-format
+msgid "E241: Unable to send to %s"
+msgstr "E241: ÎÞ·¨·¢Ë͵½ %s"
+
+msgid "E277: Unable to read a server reply"
+msgstr "E277: ÎÞ·¨¶ÁÈ¡·þÎñÆ÷ÏìÓ¦"
+
+msgid "E655: Too many symbolic links (cycle?)"
+msgstr "E655: ·ûºÅÁ¬½Ó¹ý¶à(Ñ­»·£¿)"
+
+msgid "E258: Unable to send to client"
+msgstr "E258: ÎÞ·¨·¢Ë͵½¿Í»§¶Ë"
+
+msgid "E702: Sort compare function failed"
+msgstr "E702: Sort ±È½Ïº¯Êýʧ°Ü"
+
+msgid "(Invalid)"
+msgstr "(ÎÞЧ)"
+
+msgid "E677: Error writing temp file"
+msgstr "E677: дÁÙʱÎļþ³ö´í"
+
+msgid "E703: Using a Funcref as a Number"
+msgstr "E703: ½« Funcref ×÷Êý×ÖʹÓÃ"
+
+msgid "E745: Using a List as a Number"
+msgstr "E745: ½« List ×÷Êý×ÖʹÓÃ"
+
+msgid "E728: Using a Dictionary as a Number"
+msgstr "E728: ½« Dictionary ×÷Êý×ÖʹÓÃ"
+
+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 ʹÓÃ"
+
+#, 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 "E706: Variable type mismatch for: %s"
+msgstr "E706: ±äÁ¿ÀàÐͲ»Æ¥Åä: %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: ±äÁ¿Ç¶Ì×¹ýÉîÎÞ·¨¸´ÖÆ"
+
+#, c-format
+msgid "E124: Missing '(': %s"
+msgstr "E124: ȱÉÙ '(': %s"
+
+#, c-format
+msgid "E125: Illegal argument: %s"
+msgstr "E125: ÎÞЧµÄ²ÎÊý: %s"
+
+msgid "E126: Missing :endfunction"
+msgstr "E126: ȱÉÙ :endfunction"
+
+#, c-format
+msgid "E746: Function name does not match script file name: %s"
+msgstr "E746: º¯ÊýÃûÓë½Å±¾ÎļþÃû²»Æ¥Åä: %s"
+
+msgid "E129: Function name required"
+msgstr "E129: ÐèÒªº¯ÊýÃû"
+
+#, c-format
+msgid "E128: Function name must start with a capital or contain a colon: %s"
+msgstr "E128: º¯ÊýÃû±ØÐëÒÔ´óд×Öĸ¿ªÍ·»òÕß°üº¬Ã°ºÅ: %s"
+
+#, c-format
+msgid "E131: Cannot delete function %s: It is in use"
+msgstr "E131: ÎÞ·¨É¾³ýº¯Êý %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"
+
+#, c-format
+msgid "continuing in %s"
+msgstr "ÔÚ %s ÖмÌÐø"
+
+msgid "E133: :return not inside a function"
+msgstr "E133: :return ²»ÔÚº¯ÊýÖÐ"
+
+#, c-format
+msgid ""
+"\n"
+"# global variables:\n"
+msgstr ""
+"\n"
+"# È«¾Ö±äÁ¿:\n"
+
+msgid ""
+"\n"
+"\tLast set from "
+msgstr ""
+"\n"
+"\t×î½üÐÞ¸ÄÓÚ "
+
+#, c-format
+msgid "<%s>%s%s %d, Hex %02x, Octal %03o"
+msgstr "<%s>%s%s %d, Ê®Áù½øÖÆ %02x, °Ë½øÖÆ %03o"
+
+#, 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: *Filter* ×Ô¶¯ÃüÁî²»¿ÉÒԸı䵱ǰ»º³åÇø"
+
+msgid "[No write since last change]\n"
+msgstr "[ÒÑÐ޸ĵ«ÉÐδ±£´æ]\n"
+
+# bad to translate
+#, 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 " FAILED"
+msgstr " ʧ°Ü"
+
+#, c-format
+msgid "E137: Viminfo file is not writable: %s"
+msgstr "E137: Viminfo Îļþ²»¿ÉдÈë: %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\""
+
+# do not translate to avoid writing Chinese in files
+#. Write the info:
+#, fuzzy, c-format
+#~ msgid "# This viminfo file was generated by Vim %s.\n"
+#~ msgstr "# Õâ¸ö viminfo ÎļþÊÇÓÉ Vim %s Éú³ÉµÄ¡£\n"
+
+# do not translate to avoid writing Chinese in files
+#, fuzzy, c-format
+msgid ""
+"# You may edit it if you're careful!\n"
+"\n"
+msgstr ""
+"# Èç¹ûÒª×ÔÐÐÐÞ¸ÄÇëÌØ±ðСÐÄ£¡\n"
+"\n"
+
+# do not translate to avoid writing Chinese in files
+#, fuzzy, c-format
+#~ msgid "# Value of 'encoding' when this file was written\n"
+#~ msgstr "# 'encoding' ÔÚ´ËÎļþ½¨Á¢Ê±µÄÖµ\n"
+
+msgid "Illegal starting char"
+msgstr "ÎÞЧµÄÆô¶¯×Ö·û"
+
+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 "½»»»Îļþ \"%s\" ÒÑ´æÔÚ£¬È·ÊµÒª¸²¸ÇÂð£¿"
+
+#, c-format
+msgid "E768: Swap file exists: %s (:silent! overrides)"
+msgstr "E768: ½»»»ÎļþÒÑ´æÔÚ: %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 ""
+"\"%s\" ÒÑÉ趨 'readonly' Ñ¡Ïî¡£\n"
+"ȷʵҪ¸²¸ÇÂð£¿"
+
+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 ²»½ÓÊÜ·ÇÊý×ֵIJÎÊý"
+
+msgid "E145: Shell commands not allowed in rvim"
+msgstr "E145: rvim ÖнûֹʹÓà shell ÃüÁî"
+
+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"
+msgstr "E147: :global ²»ÄܵݹéÖ´ÐÐ"
+
+msgid "E148: Regular expression missing from global"
+msgstr "E148: global ȱÉÙÕýÔò±í´ïʽ"
+
+#, c-format
+msgid "Pattern found in every line: %s"
+msgstr "ÿÐж¼Æ¥Åä±í´ïʽ: %s"
+
+# do not translate to avoid writing Chinese in files
+#, fuzzy, c-format
+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 "E150: Not a directory: %s"
+msgstr "E150: ²»ÊÇĿ¼: %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: Tag \"%s\" ÔÚÎļþ %s/%s ÖÐÖØ¸´³öÏÖ"
+
+#, c-format
+msgid "E160: Unknown sign command: %s"
+msgstr "E160: δ֪µÄ sign ÃüÁî: %s"
+
+msgid "E156: Missing sign name"
+msgstr "E156: ȱÉÙ sign Ãû³Æ"
+
+msgid "E612: Too many signs defined"
+msgstr "E612: Signs ¶¨Òå¹ý¶à"
+
+#, c-format
+msgid "E239: Invalid sign text: %s"
+msgstr "E239: ÎÞЧµÄ sign ÎÄ×Ö: %s"
+
+#, c-format
+msgid "E155: Unknown sign: %s"
+msgstr "E155: δ֪µÄ sign: %s"
+
+msgid "E159: Missing sign number"
+msgstr "E159: ȱÉÙ sign ºÅ"
+
+#, c-format
+msgid "E158: Invalid buffer name: %s"
+msgstr "E158: ÎÞЧµÄ»º³åÇøÃû: %s"
+
+#, c-format
+msgid "E157: Invalid sign ID: %ld"
+msgstr "E157: ÎÞЧµÄ sign ID: %ld"
+
+msgid " (NOT FOUND)"
+msgstr " (ÕÒ²»µ½)"
+
+msgid " (not supported)"
+msgstr " (²»Ö§³Ö)"
+
+msgid "[Deleted]"
+msgstr "[ÒÑɾ³ý]"
+
+msgid "Entering Debug mode. Type \"cont\" to continue."
+msgstr "½øÈëµ÷ÊÔģʽ¡£ÊäÈë \"cont\" ¼ÌÐøÔËÐС£"
+
+#, c-format
+msgid "line %ld: %s"
+msgstr "µÚ %ld ÐÐ: %s"
+
+#, c-format
+msgid "cmd: %s"
+msgstr "ÃüÁî: %s"
+
+#, 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 ÐÐ"
+
+msgid "E750: First use :profile start <fname>"
+msgstr "E750: ÇëÏÈʹÓà :profile start <fname>"
+
+#, c-format
+msgid "Save changes to \"%s\"?"
+msgstr "½«¸Ä±ä±£´æµ½ \"%s\" Âð£¿"
+
+msgid "Untitled"
+msgstr "δÃüÃû"
+
+#, 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 'runtimepath': \"%s\""
+msgstr "ÔÚ 'runtimepath' ÖÐÕÒ²»µ½ \"%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"
+
+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: ²»ÊDZ༭Æ÷µÄÃüÁî"
+
+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 "E319: Sorry, the command is not available in this version"
+msgstr "E319: ±§Ç¸£¬ÃüÁîÔڴ˰汾Öв»¿ÉÓÃ"
+
+msgid "E172: Only one file name allowed"
+msgstr "E172: Ö»ÔÊÐíÒ»¸öÎļþÃû"
+
+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 Range 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 ÐèÒª²ÎÊý"
+
+#, 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: Óû§×Ô¶¨ÒåÃüÁî±ØÐëÒÔ´óд×Öĸ¿ªÍ·"
+
+#, c-format
+msgid "E184: No such user-defined command: %s"
+msgstr "E184: ûÓÐÕâ¸öÓû§×Ô¶¨ÒåÃüÁî: %s"
+
+#, c-format
+msgid "E180: Invalid complete value: %s"
+msgstr "E180: ÎÞЧµÄ²¹È«ÀàÐÍ: %s"
+
+msgid "E468: Completion argument only allowed for custom completion"
+msgstr "E468: Ö»ÓÐ custom ²¹È«²ÅÔÊÐí²ÎÊý"
+
+msgid "E467: Custom completion requires a function argument"
+msgstr "E467: Custom ²¹È«ÐèÒªÒ»¸öº¯Êý²ÎÊý"
+
+#, c-format
+msgid "E185: Cannot find color scheme %s"
+msgstr "E185: ÕÒ²»µ½ÅäÉ«·½°¸ %s"
+
+msgid "Greetings, Vim user!"
+msgstr "ÄúºÃ£¬Vim Óû§£¡"
+
+msgid "E784: Cannot close last tab page"
+msgstr "E784: ²»ÄܹرÕ×îºóÒ»¸ö tab Ò³"
+
+msgid "Already only one tab page"
+msgstr "ÒѾ­Ö»Ê£Ò»¸ö tab Ò³ÁË"
+
+msgid "Edit File in new window"
+msgstr "ÔÚд°¿Ú±à¼­Îļþ"
+
+#, c-format
+msgid "Tab page %d"
+msgstr "Tab Ò³ %d"
+
+msgid "No swap file"
+msgstr "ÎÞ½»»»Îļþ"
+
+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 "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\""
+
+#. set mark
+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 "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: ûÓÐÓÃÓÚÌæ»» \"<sfile>\" µÄ :source ÎļþÃû"
+
+#, no-c-format
+msgid "E499: Empty file name for '%' or '#', only works with \":p:h\""
+msgstr "E499: '%' »ò '#' Ϊ¿ÕÎļþÃû£¬Ö»ÄÜÓÃÓÚ \":p:h\""
+
+msgid "E500: Evaluates to an empty string"
+msgstr "E500: ½á¹ûΪ¿Õ×Ö·û´®"
+
+msgid "E195: Cannot open viminfo file for reading"
+msgstr "E195: ÎÞ·¨´ò¿ª²¢¶ÁÈ¡ viminfo Îļþ"
+
+msgid "E196: No digraphs in this version"
+msgstr "E196: ´Ë°æ±¾ÎÞ¸´ºÏ×Ö·û(digraph)"
+
+msgid "E608: Cannot :throw exceptions with 'Vim' prefix"
+msgstr "E608: ²»ÄÜ :throw ǰ׺Ϊ 'Vim' µÄÒì³£"
+
+#. always scroll up, don't overwrite
+#, 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 ÐÐ"
+
+#. always scroll up, don't overwrite
+#, c-format
+msgid "Exception caught: %s"
+msgstr "²¶»ñÒì³£: %s"
+
+#, c-format
+#~ msgid "%s made pending"
+#~ msgstr ""
+
+#, fuzzy, c-format
+#~ msgid "%s resumed"
+#~ msgstr " ÒÑ·µ»Ø\n"
+
+#, c-format
+#~ msgid "%s discarded"
+#~ msgstr ""
+
+msgid "Exception"
+msgstr "Òì³£"
+
+msgid "Error and interrupt"
+msgstr "´íÎóºÍÖжÏ"
+
+msgid "Error"
+msgstr "´íÎó"
+
+#. if (pending & CSTP_INTERRUPT)
+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: :while ÒÔ :endfor ½áβ"
+
+msgid "E733: Using :endwhile with :for"
+msgstr "E733: :for ÒÔ :endwhile ½áβ"
+
+msgid "E601: :try nesting too deep"
+msgstr "E601: :try ǶÌײãÊý¹ýÉî"
+
+msgid "E603: :catch without :try"
+msgstr "E603: :catch ȱÉÙ¶ÔÓ¦µÄ :try"
+
+#. Give up for a ":catch" after ":finally" and ignore it.
+#. * Just parse.
+msgid "E604: :catch after :finally"
+msgstr "E604: :catch ÔÚ :finally ºóÃæ"
+
+msgid "E606: :finally without :try"
+msgstr "E606: :finally ȱÉÙ¶ÔÓ¦µÄ :try"
+
+#. Give up for a multiple ":finally" and ignore it.
+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 "tagname"
+msgstr "tag Ãû"
+
+msgid " kind file\n"
+msgstr " ÀàÐÍ Îļþ\n"
+
+msgid "'history' option is zero"
+msgstr "Ñ¡Ïî 'history' ΪÁã"
+
+# do not translate to avoid writing Chinese in files
+#, fuzzy, c-format
+msgid ""
+"\n"
+"# %s History (newest to oldest):\n"
+msgstr ""
+"\n"
+"# %s ÀúÊ·¼Ç¼ (´Óе½¾É):\n"
+
+# do not translate to avoid writing Chinese in files
+#, fuzzy
+#~ msgid "Command Line"
+#~ msgstr "ÃüÁîÐÐ"
+
+# do not translate to avoid writing Chinese in files
+#, fuzzy
+#~ msgid "Search String"
+#~ msgstr "²éÕÒ×Ö·û´®"
+
+# do not translate to avoid writing Chinese in files
+#, fuzzy
+#~ msgid "Expression"
+#~ msgstr "±í´ïʽ"
+
+# do not translate to avoid writing Chinese in files
+#, fuzzy
+#~ msgid "Input Line"
+#~ msgstr "ÊäÈëÐÐ"
+
+msgid "E198: cmd_pchar beyond the command length"
+msgstr "E198: cmd_pchar ³¬¹ýÃüÁ¶È"
+
+msgid "E199: Active window or buffer deleted"
+msgstr "E199: »î¶¯´°¿Ú»ò»º³åÇøÒѱ»É¾³ý"
+
+msgid "Illegal file name"
+msgstr "ÎÞЧµÄÎļþÃû"
+
+msgid "is a directory"
+msgstr "ÊÇĿ¼"
+
+msgid "is not a file"
+msgstr "²»ÊÇÎļþ"
+
+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: ´Ó±ê×¼ÊäÈë¶ÁÈ¡...\n"
+
+msgid "Reading from stdin..."
+msgstr "´Ó±ê×¼ÊäÈë¶ÁÈ¡..."
+
+#. Re-opening the original file failed!
+msgid "E202: Conversion made file unreadable!"
+msgstr "E202: ת»»µ¼ÖÂÎļþ²»¿É¶Á"
+
+msgid "[fifo/socket]"
+msgstr "[fifo/socket]"
+
+msgid "[fifo]"
+msgstr "[fifo]"
+
+msgid "[socket]"
+msgstr "[socket]"
+
+msgid "[RO]"
+msgstr "[Ö»¶Á]"
+
+msgid "[CR missing]"
+msgstr "[ȱÉÙ CR]'"
+
+msgid "[NL found]"
+msgstr "[ÕÒµ½ NL]"
+
+msgid "[long lines split]"
+msgstr "[³¤Ðзָî]"
+
+msgid "[NOT converted]"
+msgstr "[δת»»]"
+
+msgid "[converted]"
+msgstr "[ÒÑת»»]"
+
+msgid "[crypted]"
+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 "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 "E460: The resource fork would be lost (add ! to override)"
+msgstr "E460: Resource fork »á¶ªÊ§ (Çë¼Ó ! Ç¿ÖÆÖ´ÐÐ)"
+
+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 "E667: Fsync failed"
+msgstr "E667: ͬ²½Ê§°Ü"
+
+msgid "E512: Close failed"
+msgstr "E512: ¹Ø±Õʧ°Ü"
+
+msgid "E513: write error, conversion failed (make 'fenc' empty to override)"
+msgstr "E513: дÈë´íÎó£¬×ª»»Ê§°Ü (Ç뽫 'fenc' ÖÿÕÒÔÇ¿ÖÆÖ´ÐÐ)"
+
+msgid "E514: write error (file system full?)"
+msgstr "E514: дÈë´íÎó (ÎļþϵͳÒÑÂú£¿)"
+
+msgid " CONVERSION ERROR"
+msgstr " ת»»´íÎó"
+
+msgid "[Device]"
+msgstr "[É豸]"
+
+msgid "[New]"
+msgstr "[ÐÂ]"
+
+msgid " [a]"
+msgstr " [a]"
+
+msgid " appended"
+msgstr " ÒÑ×·¼Ó"
+
+msgid " [w]"
+msgstr " [w]"
+
+msgid " written"
+msgstr " ÒÑдÈë"
+
+msgid "E205: Patchmode: can't save original file"
+msgstr "E205: Patchmode: ÎÞ·¨±£´æÔ­Ê¼Îļþ"
+
+msgid "E206: patchmode: can't touch empty original file"
+msgstr "E206: Patchmode: ÎÞ·¨Éú³É¿ÕµÄԭʼÎļþ"
+
+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 "%ld characters"
+msgstr "%ld ¸ö×Ö·û"
+
+msgid "[noeol]"
+msgstr "[noeol]"
+
+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
+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 ""
+"È·¶¨(&O)\n"
+"¼ÓÔØÎļþ(&L)"
+
+#, 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 ""
+
+#. the group doesn't exist
+#, c-format
+msgid "E367: No such group: \"%s\""
+msgstr "E367: ÎÞ´Ë×é: \"%s\""
+
+#, 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"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Auto-Commands ---"
+msgstr ""
+"\n"
+"--- ×Ô¶¯ÃüÁî ---"
+
+#, c-format
+msgid "E680: <buffer=%d>: invalid buffer number "
+msgstr "E680: <buffer=%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 Auto commands 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 lines folded "
+msgstr "+--ÒÑÕÛµþ %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 "E229: Cannot start the GUI"
+msgstr "E229: ÎÞ·¨Æô¶¯Í¼ÐνçÃæ"
+
+#, c-format
+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' µÄÖµÎÞЧ"
+
+#, 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 "¹ö¶¯Ìõ²¿¼þ: ÎÞ·¨»ñÈ¡»¬¿éͼÏñµÄ¼¸ºÎ´óС"
+
+msgid "Vim dialog"
+msgstr "Vim ¶Ô»°¿ò"
+
+msgid "E232: Cannot create BalloonEval with both message and callback"
+msgstr "E232: ²»ÄÜͬʱʹÓÃÏûÏ¢ºÍ»Øµ÷º¯ÊýÀ´´´½¨ BalloonEval"
+
+msgid "Vim dialog..."
+msgstr "Vim ¶Ô»°¿ò..."
+
+msgid ""
+"&Yes\n"
+"&No\n"
+"&Cancel"
+msgstr ""
+"ÊÇ(&Y)\n"
+"·ñ(&N)\n"
+"È¡Ïû(&C)"
+
+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 "Ìæ»»Îª:"
+
+#. whole word only button
+msgid "Match whole word only"
+msgstr "Æ¥ÅäÍêÕûµÄ´Ê"
+
+#. match case button
+msgid "Match case"
+msgstr "Æ¥Åä´óСд"
+
+msgid "Direction"
+msgstr "·½Ïò"
+
+#. 'Up' and 'Down' buttons
+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)"
+
+#, 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 "Close tab"
+msgstr "¹Ø±Õ±êÇ©"
+
+msgid "Open tab..."
+msgstr "´ò¿ª±êÇ©..."
+
+msgid "Find string (use '\\\\' to find a '\\')"
+msgstr "²éÕÒ×Ö·û´® (ʹÓà '\\\\' À´²éÕÒ '\\')"
+
+msgid "Find & Replace (use '\\\\' to find a '\\')"
+msgstr "²éÕÒºÍÌæ»»×Ö·û´® (ʹÓà '\\\\' À´²éÕÒ '\\')"
+
+#. 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 "δʹÓÃ"
+
+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ЩÑÕÉ«¿ÉÄܲ»ÕýÈ·"
+
+#, c-format
+msgid "E250: Fonts for the following charsets are missing in fontset %s:"
+msgstr "E250: Fontset %s ȱÉÙÏÂÁÐ×Ö·û¼¯µÄ×ÖÌå:"
+
+#, c-format
+msgid "E252: Fontset name: %s"
+msgstr "E252: Fontset Ãû³Æ: %s"
+
+#, c-format
+msgid "Font '%s' is not fixed-width"
+msgstr "'%s' ²»Êǹ̶¨¿í¶ÈµÄ×ÖÌå"
+
+#, c-format
+msgid "E253: Fontset name: %s\n"
+msgstr "E253: Fontset Ãû³Æ: %s\n"
+
+#, c-format
+msgid "Font0: %s\n"
+msgstr "×ÖÌå0: %s\n"
+
+#, c-format
+msgid "Font1: %s\n"
+msgstr "×ÖÌå1: %s\n"
+
+#, c-format
+msgid "Font%ld width is not twice that of font0\n"
+msgstr "×ÖÌå%ldµÄ¿í¶È²»ÊÇ×ÖÌå0µÄÁ½±¶\n"
+
+#, c-format
+msgid "Font0 width: %ld\n"
+msgstr "×ÖÌå0µÄ¿í¶È£º%ld\n"
+
+#, c-format
+msgid ""
+"Font1 width: %ld\n"
+"\n"
+msgstr ""
+"×ÖÌå1µÄ¿í¶È: %ld\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 "Ãû³Æ:"
+
+#. create toggle button
+#~ 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 automata ´íÎó"
+
+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 ×ÊÔ´Îļþ \"%s\""
+
+#, c-format
+msgid "E618: file \"%s\" is not a PostScript resource file"
+msgstr "E618: Îļþ \"%s\" ²»ÊÇ PostScript ×ÊÔ´Îļþ"
+
+#, c-format
+msgid "E619: file \"%s\" is not a supported PostScript resource file"
+msgstr "E619: Îļþ \"%s\" ²»ÊÇÒÑÖ§³ÖµÄ PostScript ×ÊÔ´Îļþ"
+
+#, c-format
+msgid "E621: \"%s\" resource file has wrong version"
+msgstr "E621: \"%s\" ×ÊÔ´Îļþ°æ±¾²»ÕýÈ·"
+
+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 ×ÊÔ´Îļþ \"prolog.ps\""
+
+msgid "E456: Can't find PostScript resource file \"cidfont.ps\""
+msgstr "E456: ÕÒ²»µ½ PostScript ×ÊÔ´Îļþ \"cidfont.ps\""
+
+#, c-format
+msgid "E456: Can't find PostScript resource file \"%s.ps\""
+msgstr "E456: ÕÒ²»µ½ PostScript ×ÊÔ´Îļþ \"%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: ÕÒ²»µ½ tag"
+
+#, 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 ½øÐÐ fork"
+
+msgid "cs_create_connection exec failed"
+msgstr "cs_create_connection Ö´ÐÐʧ°Ü"
+
+msgid "E623: Could not spawn cscope process"
+msgstr "E623: ÎÞ·¨Éú³É cscope ½ø³Ì"
+
+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 "E567: no cscope connections"
+msgstr "E567: ûÓÐ cscope Á¬½Ó"
+
+#, c-format
+msgid "E259: no matches found for cscope query %s of %s"
+msgstr "E259: cscope ²éѯ %s %s ûÓÐÕÒµ½Æ¥ÅäµÄ½á¹û"
+
+#, c-format
+msgid "E469: invalid cscopequickfix flag %c for %c"
+msgstr "E469: cscopequickfix ±êÖ¾ %c ¶Ô %c ÎÞЧ"
+
+msgid "cscope commands:\n"
+msgstr "cscope ÃüÁî:\n"
+
+#, c-format
+msgid "%-5s: %-30s (Usage: %s)"
+msgstr "%-5s: %-30s (Ó÷¨: %s)"
+
+#, 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 Êý¾Ý¿âδ±»¼ÓÈë"
+
+msgid "E569: maximum number of cscope connections reached"
+msgstr "E569: ÒÑ´ïµ½ cscope µÄ×î´óÁ¬½ÓÊý"
+
+#, c-format
+msgid "E261: cscope connection %s not found"
+msgstr "E261: ÕÒ²»µ½ cscope Á¬½Ó %s"
+
+#, c-format
+msgid "cscope connection %s closed"
+msgstr "cscope Á¬½Ó %s ÒѹرÕ"
+
+#. should not reach here
+msgid "E570: fatal error in cs_manage_matches"
+msgstr "E570: cs_manage_matches ÑÏÖØ´íÎó"
+
+#, c-format
+msgid "Cscope tag: %s"
+msgstr "Cscope tag: %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 Êý¾Ý¿âÃû prepend path\n"
+
+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 "Ðкų¬³ö·¶Î§"
+
+#, c-format
+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 "¹â±êλÖÃÔÚ»º³åÇøÍâ"
+
+#, c-format
+msgid "<window object (deleted) at %.8lX>"
+msgstr "<´°¿Ú¶ÔÏó(ÒÑɾ³ý): %.8lX>"
+
+#, c-format
+msgid "<window object (unknown) at %.8lX>"
+msgstr "<´°¿Ú¶ÔÏó(δ֪): %.8lX>"
+
+#, c-format
+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 ¿â"
+
+#, c-format
+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 "Á¬½ÓÖÐ"
+
+#, c-format
+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 "ûÓÐÉ趨±ê¼Ç"
+
+#, c-format
+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 "ÎÞ·¨×¢²á»Øµ÷ÃüÁî: »º³åÇø/´°¿ÚÒѱ»É¾³ý"
+
+#. This should never happen. Famous last word?
+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"
+
+#, 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 ʵÀý×¢²áÊôÐÔÓÐÎó¡£ÒÑɾ³ý£¡"
+
+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 "ÎÞЧµÄ²ÎÊý"
+
+#, c-format
+msgid "%d files to edit\n"
+msgstr "»¹ÓÐ %d ¸öÎļþµÈ´ý±à¼­\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: ´íÎó: ÎÞ·¨´Ó NetBeans ÖÐÆô¶¯ gvim\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"
+
+#. just in case..
+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 ±à¼­ tag ¶¨Òå´¦µÄÎļþ"
+
+msgid "-q [errorfile] edit file with first error"
+msgstr "-q [errorfile] ±à¼­µÚÒ»¸ö³ö´í´¦µÄÎļþ"
+
+msgid ""
+"\n"
+"\n"
+"usage:"
+msgstr ""
+"\n"
+"\n"
+"Ó÷¨:"
+
+msgid " vim [arguments] "
+msgstr " vim [²ÎÊý] "
+
+msgid ""
+"\n"
+" or:"
+msgstr ""
+"\n"
+" »ò:"
+
+#~ msgid "where case is ignored prepend / to make flag upper case"
+#~ msgstr ""
+
+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È¡Ïû 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\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 "-s\t\t\tSilent (batch) mode (only for \"ex\")"
+msgstr "-s\t\t\t°²¾²(Åú´¦Àí)ģʽ (Ö»ÄÜÓë \"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\tÈÝÒ×ģʽ (ͬ \"evim\"£¬ÎÞģʽ)"
+
+msgid "-R\t\t\tReadonly mode (like \"view\")"
+msgstr "-R\t\t\tÖ»¶Áģʽ (ͬ \"view\")"
+
+msgid "-Z\t\t\tRestricted mode (like \"rvim\")"
+msgstr "-Z\t\t\tÏÞÖÆÄ£Ê½ (ͬ \"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]\t\tVerbose level"
+msgstr "-V[N]\t\tVerbose µÈ¼¶"
+
+msgid "-D\t\t\tDebugging mode"
+msgstr "-D\t\t\tµ÷ÊÔģʽ"
+
+msgid "-n\t\t\tNo swap file, use memory only"
+msgstr "-n\t\t\t²»Ê¹Óý»»»Îļþ£¬Ö»Ê¹ÓÃÄÚ´æ"
+
+msgid "-r\t\t\tList swap files and exit"
+msgstr "-r\t\t\tÁгö½»»»Îļþ²¢Í˳ö"
+
+msgid "-r (with file name)\tRecover crashed session"
+msgstr "-r (¸úÎļþÃû)\t\t»Ö¸´±ÀÀ£µÄ»á»°"
+
+msgid "-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²»Ê¹Óà newcli À´´ò¿ª´°¿Ú"
+
+msgid "-dev <device>\t\tUse <device> for I/O"
+msgstr "-dev <device>\t\tʹÓà <device> ½øÐÐÊäÈëÊä³ö"
+
+msgid "-A\t\t\tstart in Arabic mode"
+msgstr "-A\t\t\tÒÔ Arabic ģʽÆô¶¯"
+
+msgid "-H\t\t\tStart in Hebrew mode"
+msgstr "-H\t\t\tÒÔ Hebrew ģʽÆô¶¯"
+
+msgid "-F\t\t\tStart in Farsi mode"
+msgstr "-F\t\t\tÒÔ Farsi ģʽÆô¶¯"
+
+msgid "-T <terminal>\tSet terminal type to <terminal>"
+msgstr "-T <terminal>\tÉ趨ÖÕ¶ËÀàÐÍΪ <terminal>"
+
+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²»¼ÓÔØ plugin ½Å±¾"
+
+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 "+<lnum>\t\tÆô¶¯ºóÌøµ½µÚ <lnum> ÐÐ"
+
+msgid "--cmd <command>\tExecute <command> before loading any vimrc file"
+msgstr "--cmd <command>\t¼ÓÔØÈκΠvimrc ÎļþǰִÐÐ <command>"
+
+msgid "-c <command>\t\tExecute <command> after loading the first file"
+msgstr "-c <command>\t\t¼ÓÔØµÚÒ»¸öÎļþºóÖ´ÐÐ <command>"
+
+msgid "-S <session>\t\tSource file <session> after loading the first file"
+msgstr "-S <session>\t\t¼ÓÔØµÚÒ»¸öÎļþºóÖ´ÐÐÎļþ <session>"
+
+msgid "-s <scriptin>\tRead Normal mode commands from file <scriptin>"
+msgstr "-s <scriptin>\t´ÓÎļþ <scriptin> ¶ÁÈëÕý³£Ä£Ê½µÄÃüÁî"
+
+msgid "-w <scriptout>\tAppend all typed commands to file <scriptout>"
+msgstr "-w <scriptout>\t½«ËùÓÐÊäÈëµÄÃüÁî×·¼Óµ½Îļþ <scriptout>"
+
+msgid "-W <scriptout>\tWrite all typed commands to file <scriptout>"
+msgstr "-W <scriptout>\t½«ËùÓÐÊäÈëµÄÃüÁîдÈëµ½Îļþ <scriptout>"
+
+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 "-i <viminfo>\t\tUse <viminfo> instead of .viminfo"
+msgstr "-i <viminfo>\t\tʹÓà <viminfo> È¡´ú .viminfo"
+
+msgid "-h or --help\tPrint Help (this message) and exit"
+msgstr "-h »ò --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 <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"
+
+#. Failed to send, abort.
+msgid ": Send failed.\n"
+msgstr ": ·¢ËÍʧ°Ü¡£\n"
+
+#. Let vim start normally.
+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 "ûÓÐ display: ·¢Ëͱí´ïʽʧ°Ü¡£\n"
+
+msgid ": Send expression failed.\n"
+msgstr ": ·¢Ëͱí´ïʽʧ°Ü¡£\n"
+
+msgid "No marks set"
+msgstr "ûÓÐÉ趨±ê¼Ç"
+
+#, c-format
+msgid "E283: No marks matching \"%s\""
+msgstr "E283: ûÓÐÆ¥Åä \"%s\" µÄ±ê¼Ç"
+
+#. Highlight title
+msgid ""
+"\n"
+"mark line col file/text"
+msgstr ""
+"\n"
+"±ê¼Ç ÐÐ ÁÐ Îļþ/Îı¾"
+
+#. Highlight title
+msgid ""
+"\n"
+" jump line col file/text"
+msgstr ""
+"\n"
+" Ìø×ª ÐÐ ÁÐ Îļþ/Îı¾"
+
+#. Highlight title
+msgid ""
+"\n"
+"change line col text"
+msgstr ""
+"\n"
+" ¸Ä±ä ÐÐ ÁÐ Îı¾"
+
+#, c-format
+msgid ""
+"\n"
+"# File marks:\n"
+msgstr ""
+"\n"
+"# Îļþ±ê¼Ç:\n"
+
+#. Write the jumplist with -'
+#, c-format
+msgid ""
+"\n"
+"# Jumplist (newest first):\n"
+msgstr ""
+"\n"
+"# Ìø×ªÁбí (´Óе½¾É):\n"
+
+#, c-format
+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: ¾¯¸æ: ÎÞ·¨É趨ÊäÈë·¨µÄÊͷŻص÷º¯Êý"
+
+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 "E293: block was not locked"
+msgstr "E293: ¿éδ±»Ëø¶¨"
+
+msgid "E294: Seek error in swap file read"
+msgstr "E294: ½»»»Îļþ¶ÁÈ¡¶¨Î»´íÎó"
+
+msgid "E295: Read error in swap file"
+msgstr "E295: ½»»»Îļþ¶ÁÈ¡´íÎó"
+
+msgid "E296: Seek error in swap file write"
+msgstr "E296: ½»»»ÎļþдÈ붨λ´íÎó"
+
+msgid "E297: Write error in swap file"
+msgstr "E297: ½»»»ÎļþдÈë´íÎó"
+
+msgid "E300: Swap file already exists (symlink attack?)"
+msgstr "E300: ½»»»ÎļþÒÑ´æÔÚ (·ûºÅÁ¬½Ó¹¥»÷£¿)"
+
+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£¿"
+
+#. could not (re)open the swap file, what can we do????
+msgid "E301: Oops, lost the swap file!!!"
+msgstr "E301: àÞ£¬½»»»Îļþ²»¼ûÁË£¡£¡£¡"
+
+msgid "E302: Could not rename swap file"
+msgstr "E302: ÎÞ·¨ÖØÃüÃû½»»»Îļþ"
+
+#, c-format
+msgid "E303: Unable to open swap file for \"%s\", recovery impossible"
+msgstr "E303: ÎÞ·¨´ò¿ª \"%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 µÄ½»»»Îļþ"
+
+msgid "Enter number of swap file to use (0 to quit): "
+msgstr "ÇëÊäÈëҪʹÓõĽ»»»Îļþ±àºÅ (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 »¹À´²»¼°¸üн»»»Îļþ¡£"
+
+msgid " cannot be used with this version of Vim.\n"
+msgstr " ²»ÄÜÔڸð汾µÄ Vim ÖÐʹÓá£\n"
+
+msgid "Use Vim version 3.0.\n"
+msgstr "ʹÓà Vim 3.0¡£\n"
+
+#, c-format
+msgid "E307: %s does not look like a Vim swap file"
+msgstr "E307: %s ¿´ÆðÀ´²»ÏñÊÇ Vim ½»»»Îļþ"
+
+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 "Using swap file \"%s\""
+msgstr "ʹÓý»»»Îļþ \"%s\""
+
+#, c-format
+msgid "Original file \"%s\""
+msgstr "ԭʼÎļþ \"%s\""
+
+msgid "E308: Warning: Original file may have been changed"
+msgstr "E308: ¾¯¸æ: ԭʼÎļþ¿ÉÄÜÒѱ»ÐÞ¸Ä"
+
+#, c-format
+msgid "E309: Unable to read block 1 from %s"
+msgstr "E309: ÎÞ·¨´Ó %s ¶ÁÈ¡¿é 1"
+
+# do not translate to avoid writing Chinese in files
+#, fuzzy
+#~ msgid "???MANY LINES MISSING"
+#~ msgstr "???ȱÉÙÁËÌ«¶àÐÐ"
+
+# do not translate to avoid writing Chinese in files
+#, fuzzy
+#~ msgid "???LINE COUNT WRONG"
+#~ msgstr "???ÐÐÊý´íÎó"
+
+# do not translate to avoid writing Chinese in files
+#, fuzzy
+#~ msgid "???EMPTY BLOCK"
+#~ msgstr "???¿ÕµÄ¿é"
+
+# do not translate to avoid writing Chinese in files
+#, fuzzy
+#~ msgid "???LINES MISSING"
+#~ msgstr "???ȱÉÙÁËһЩÐÐ"
+
+#, 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
+#, fuzzy
+#~ msgid "???BLOCK MISSING"
+#~ msgstr "???ȱÉÙ¿é"
+
+# do not translate to avoid writing Chinese in files
+#, fuzzy
+#~ msgid "??? from here until ???END lines may be messed up"
+#~ msgstr "??? ´ÓÕâÀïµ½ ???END µÄÐпÉÄÜÒÑ»ìÂÒ"
+
+# do not translate to avoid writing Chinese in files
+#, fuzzy
+#~ msgid "??? from here until ???END lines may have been inserted/deleted"
+#~ msgstr "??? ´ÓÕâÀïµ½ ???END µÄÐпÉÄÜÒѱ»²åÈë/ɾ³ý¹ý"
+
+# do not translate to avoid writing Chinese in files
+#, fuzzy
+#~ msgid "???END"
+#~ msgstr "???END"
+
+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 "»Ö¸´Íê±Ï¡£ÇëÈ·¶¨Ò»ÇÐÕý³£¡£"
+
+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)\n"
+msgstr "ÔÙÔËÐÐ diff ÓëÔ­Îļþ±È½ÏÒÔ¼ì²éÊÇ·ñÓиıä)\n"
+
+msgid ""
+"Delete the .swp file afterwards.\n"
+"\n"
+msgstr ""
+"È»ºó°Ñ .swp Îļþɾµô¡£\n"
+"\n"
+
+#. use msg() to start the scrolling properly
+msgid "Swap files found:"
+msgstr "ÕÒµ½½»»»Îļþ:"
+
+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 ½»»»Îļþ]"
+
+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"
+" ½ø³Ì ID: "
+
+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: ÎÞ·¨±£Áô£¬Ã»Óн»»»Îļþ"
+
+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: Ö¸Õë¿é id ´íÎó 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: Ö¸Õë¿é id ´íÎó 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: Ö¸Õë¿é id ´íÎó"
+
+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: Ö¸Õë¿é id ´íÎó 2"
+
+#, c-format
+msgid "E773: Symlink loop for \"%s\""
+msgstr "E773: \"%s\" ·ûºÅÁ¬½Ó³öÏÖÑ­»·"
+
+msgid "E325: ATTENTION"
+msgstr "E325: ×¢Òâ"
+
+msgid ""
+"\n"
+"Found a swap file by the name \""
+msgstr ""
+"\n"
+"·¢ÏÖ½»»»Îļþ \""
+
+msgid "While opening file \""
+msgstr "ÕýÔÚ´ò¿ªÎļþ \""
+
+msgid " NEWER than swap file!\n"
+msgstr " ±È½»»»ÎļþУ¡\n"
+
+#. Some of these messages are long to allow translation to
+#. * other languages.
+msgid ""
+"\n"
+"(1) Another program may be editing the same file.\n"
+" If this is the case, be careful not to end up with two\n"
+" different instances of the same file when making changes.\n"
+msgstr ""
+"\n"
+"(1) ÁíÒ»¸ö³ÌÐò¿ÉÄÜÒ²Ôڱ༭ͬһ¸öÎļþ¡£\n"
+" Èç¹ûÊÇÕâÑù£¬ÐÞ¸ÄʱÇë×¢Òâ±ÜÃâͬһ¸öÎļþ²úÉúÁ½¸ö²»Í¬µÄ°æ±¾¡£\n"
+"\n"
+
+msgid " Quit, or continue with caution.\n"
+msgstr " Í˳ö£¬»òСÐĵؼÌÐø¡£\n"
+
+msgid ""
+"\n"
+"(2) An edit session for this file crashed.\n"
+msgstr ""
+"\n"
+"(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 " Èç¹ûÄãÒѾ­½øÐÐÁ˻ָ´£¬Çëɾ³ý½»»»Îļþ \""
+
+msgid ""
+"\"\n"
+" to avoid this message.\n"
+msgstr ""
+"\"\n"
+" ÒÔ±ÜÃâÔÙ¿´µ½´ËÏûÏ¢¡£\n"
+
+msgid "Swap file \""
+msgstr "½»»»Îļþ \""
+
+msgid "\" already exists!"
+msgstr "\" ÒÑ´æÔÚ£¡"
+
+msgid "VIM - ATTENTION"
+msgstr "VIM - ×¢Òâ"
+
+msgid "Swap file already exists!"
+msgstr "½»»»ÎļþÒÑ´æÔÚ£¡"
+
+msgid ""
+"&Open Read-Only\n"
+"&Edit anyway\n"
+"&Recover\n"
+"&Quit\n"
+"&Abort"
+msgstr ""
+"ÒÔÖ»¶Á·½Ê½´ò¿ª(&O)\n"
+"Ö±½Ó±à¼­(&E)\n"
+"»Ö¸´(&R)\n"
+"Í˳ö(&Q)\n"
+"ÖÐÖ¹(&A)"
+
+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)"
+
+msgid "E326: Too many swap files found"
+msgstr "E326: ÕÒµ½Ì«¶à½»»»Îļþ"
+
+msgid "E327: Part of menu-item path is not sub-menu"
+msgstr "E327: ²Ëµ¥ÏîµÄij²¿·Ö·¾¶²»ÊÇ×Ӳ˵¥"
+
+msgid "E328: Menu only exists in another mode"
+msgstr "E328: ²Ëµ¥Ö»ÔÚÆäËüģʽÖдæÔÚ"
+
+#, c-format
+msgid "E329: No menu \"%s\""
+msgstr "E329: ûÓв˵¥ \"%s\""
+
+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: ·Ö¸ôÏß²»ÄÜÊDz˵¥Â·¾¶µÄÒ»²¿·Ö"
+
+#. Now we have found the matching menu, and we list the mappings
+#. Highlight title
+msgid ""
+"\n"
+"--- Menus ---"
+msgstr ""
+"\n"
+"--- ²Ëµ¥ ---"
+
+msgid "Tear off this menu"
+msgstr "˺Ï´˲˵¥"
+
+msgid "E333: Menu path must lead to a menu item"
+msgstr "E333: ²Ëµ¥Â·¾¶±ØÐëÖ¸Ïò²Ëµ¥Ïî"
+
+#, c-format
+msgid "E334: Menu not found: %s"
+msgstr "E334: ÕÒ²»µ½²Ëµ¥: %s"
+
+#, c-format
+msgid "E335: Menu not defined for %s mode"
+msgstr "E335: %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 "¼òÌåÖÐÎÄÏûϢά»¤Õß: Yuheng Xie <elephant@linux.net.cn>"
+
+msgid "Interrupt: "
+msgstr "ÒÑÖжÏ: "
+
+msgid "Press ENTER or type command to continue"
+msgstr "Çë°´ ENTER »òÆäËüÃüÁî¼ÌÐø"
+
+#, 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 ""
+"ÊÇ(&Y)\n"
+"·ñ(&N)"
+
+msgid ""
+"&Yes\n"
+"&No\n"
+"Save &All\n"
+"&Discard All\n"
+"&Cancel"
+msgstr ""
+"ÊÇ(&Y)\n"
+"·ñ(&N)\n"
+"È«²¿±£´æ(&A)\n"
+"È«²¿¶ªÆú(&D)\n"
+"È¡Ïû(&C)"
+
+msgid "Select Directory dialog"
+msgstr "Ñ¡ÔñĿ¼¶Ô»°¿ò"
+
+msgid "Save File dialog"
+msgstr "±£´æÎļþ¶Ô»°¿ò"
+
+msgid "Open File dialog"
+msgstr "´ò¿ªÎļþ¶Ô»°¿ò"
+
+#. TODO: non-GUI file selector here
+msgid "E338: Sorry, no file browser in console mode"
+msgstr "E338: ±§Ç¸£¬¿ØÖÆÌ¨Ä£Ê½ÏÂûÓÐÎļþä¯ÀÀÆ÷"
+
+msgid "E766: Insufficient arguments for printf()"
+msgstr "E766: printf() µÄ²ÎÊý²»×ã"
+
+msgid "E767: Too many arguments to printf()"
+msgstr "E767: printf() µÄ²ÎÊý¹ý¶à"
+
+msgid "W10: Warning: Changing a readonly file"
+msgstr "W10: ¾¯¸æ: ÕýÔÚÐÞ¸ÄÒ»¸öÖ»¶ÁÎļþ"
+
+msgid "Type number or click with mouse (<Enter> cancels): "
+msgstr "ÇëÊäÈëÊý×Ö»òµã»÷Êó±ê (<Enter> È¡Ïû): "
+
+msgid "Choice number (<Enter> 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 "Beep!"
+
+msgid "Vim: preserving files...\n"
+msgstr "Vim: ÕýÔÚ±£ÁôÎļþ¡­¡­\n"
+
+#. close all memfiles, without deleting
+msgid "Vim: Finished.\n"
+msgstr "Vim: ½áÊø¡£\n"
+
+#, c-format
+msgid "ERROR: "
+msgstr "´íÎó: "
+
+#, c-format
+msgid ""
+"\n"
+"[bytes] total alloc-freed %lu-%lu, in use %lu, peak use %lu\n"
+msgstr ""
+"\n"
+"[×Ö½Ú] ×ܹ² alloc-free %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 "µ÷ÓÃ shell Ö´ÐÐ: \"%s\""
+
+msgid "E545: Missing colon"
+msgstr "E545: ȱÉÙðºÅ"
+
+msgid "E546: Illegal mode"
+msgstr "E546: ÎÞЧµÄģʽ"
+
+msgid "E547: Illegal mouseshape"
+msgstr "E547: ÎÞЧµÄÊó±êÐÎ×´"
+
+msgid "E548: digit expected"
+msgstr "E548: ´Ë´¦ÐèÒªÊý×Ö"
+
+msgid "E549: Illegal percentage"
+msgstr "E549: ÎÞЧµÄ°Ù·Ö±È"
+
+msgid "Enter encryption key: "
+msgstr "ÊäÈëÃÜÂë: "
+
+msgid "Enter same key again: "
+msgstr "ÇëÔÙÊäÈëÒ»´Î: "
+
+msgid "Keys don't match!"
+msgstr "Á½´ÎÃÜÂ벻ƥÅ䣡"
+
+#, c-format
+msgid ""
+"E343: Invalid path: '**[number]' must be at the end of the path or be "
+"followed by '%s'."
+msgstr "E343: ÎÞЧµÄ·¾¶: '**[number]' ±ØÐëÔÚ·¾¶Ä©Î²»òÕߺóÃæ½Ó '%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: ÔÚ·¾¶ÖÐÕÒ²»µ½Îļþ \"%s\""
+
+#, c-format
+msgid "E346: No more directory \"%s\" found in cdpath"
+msgstr "E346: ÔÚ·¾¶ÖÐÕÒ²»µ½¸ü¶àµÄÎļþ \"%s\""
+
+#, c-format
+msgid "E347: No more file \"%s\" found in path"
+msgstr "E347: ÔÚ·¾¶ÖÐÕÒ²»µ½¸ü¶àµÄÎļþ \"%s\""
+
+#. Get here when the server can't be found.
+msgid "Cannot connect to Netbeans #2"
+msgstr "ÎÞ·¨Á¬½Óµ½ Netbeans #2"
+
+msgid "Cannot connect to Netbeans"
+msgstr "ÎÞ·¨Á¬½Óµ½ Netbeans"
+
+#, c-format
+msgid "E668: Wrong access mode for NetBeans connection info file: \"%s\""
+msgstr "E668: NetBeans Á¬½ÓÐÅÏ¢ÎļþÖдíÎóµÄ·ÃÎÊģʽ: \"%s\""
+
+msgid "read from Netbeans socket"
+msgstr "´Ó Netbeans Ì×½Ó×Ö¶ÁÈ¡"
+
+#, c-format
+msgid "E658: NetBeans connection lost for buffer %ld"
+msgstr "E658: »º³åÇø %ld ¶ªÊ§ NetBeans Á¬½Ó"
+
+msgid "E505: "
+msgstr "E505: "
+
+msgid "E774: 'operatorfunc' is empty"
+msgstr "E774: 'operatorfunc' Ϊ¿Õ"
+
+msgid "E775: Eval feature not available"
+msgstr "E775: ÇóÖµ¹¦Äܲ»¿ÉÓÃ"
+
+msgid "Warning: terminal cannot highlight"
+msgstr "¾¯¸æ: ÄãµÄÖն˲»ÄÜÏÔʾ¸ßÁÁ"
+
+msgid "E348: No string under cursor"
+msgstr "E348: ¹â±ê´¦Ã»ÓÐ×Ö·û´®"
+
+msgid "E349: No identifier under cursor"
+msgstr "E349: ¹â±ê´¦Ã»ÓÐʶ±ð×Ö"
+
+msgid "E352: Cannot erase folds with current 'foldmethod'"
+msgstr "E352: ²»ÄÜÔÚµ±Ç°µÄ 'foldmethod' ÏÂɾ³ý fold"
+
+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 :quit<Enter> to exit Vim"
+msgstr "ÊäÈë :quit<Enter> Í˳ö 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: ûÓÐǰһ¸öʹÓõļĴæÆ÷"
+
+#. must display the prompt
+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 ÐÐ"
+
+msgid "block of 1 line yanked"
+msgstr "¸´ÖÆÁË 1 ÐеĿé"
+
+msgid "1 line yanked"
+msgstr "¸´ÖÆÁË 1 ÐÐ"
+
+#, c-format
+msgid "block of %ld lines yanked"
+msgstr "¸´ÖÆÁË %ld ÐеĿé"
+
+#, c-format
+msgid "%ld lines yanked"
+msgstr "¸´ÖÆÁË %ld ÐÐ"
+
+#, c-format
+msgid "E353: Nothing in register %s"
+msgstr "E353: ¼Ä´æÆ÷ %s ÀïûÓж«Î÷"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Registers ---"
+msgstr ""
+"\n"
+"--- ¼Ä´æÆ÷ ---"
+
+msgid "Illegal register name"
+msgstr "ÎÞЧµÄ¼Ä´æÆ÷Ãû"
+
+#, c-format
+msgid ""
+"\n"
+"# Registers:\n"
+msgstr ""
+"\n"
+"# ¼Ä´æÆ÷:\n"
+
+#, c-format
+msgid "E574: Unknown register type %d"
+msgstr "E574: δ֪µÄ¼Ä´æÆ÷ÀàÐÍ %d"
+
+#, c-format
+msgid "%ld Cols; "
+msgstr "%ld ÁÐ; "
+
+#, c-format
+msgid "Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Bytes"
+msgstr "Ñ¡ÔñÁË %s%ld/%ld ÐÐ; %ld/%ld ¸ö´Ê; %ld/%ld ¸ö×Ö½Ú"
+
+#, c-format
+msgid ""
+"Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Chars; %ld of %ld "
+"Bytes"
+msgstr "Ñ¡ÔñÁË %s%ld/%ld ÐÐ; %ld/%ld ¸ö´Ê; %ld/%ld ¸ö×Ö·û; %ld/%ld ¸ö×Ö½Ú"
+
+#, c-format
+msgid "Col %s of %s; Line %ld of %ld; Word %ld of %ld; Byte %ld of %ld"
+msgstr "µÚ %s/%s ÁÐ; µÚ %ld/%ld ÐÐ; µÚ %ld/%ld ¸ö´Ê; µÚ %ld/%ld ¸ö×Ö½Ú"
+
+#, c-format
+msgid ""
+"Col %s of %s; Line %ld of %ld; Word %ld of %ld; Char %ld of %ld; Byte %ld of "
+"%ld"
+msgstr ""
+"µÚ %s/%s ÁÐ; µÚ %ld/%ld ÐÐ; µÚ %ld/%ld ¸ö´Ê; µÚ %ld/%ld ¸ö×Ö·û; µÚ %ld/%ld ¸ö"
+"×Ö½Ú"
+
+#, c-format
+#~ msgid "(+%ld for BOM)"
+#~ msgstr ""
+
+#~ msgid "%<%f%h%m%=Page %N"
+#~ msgstr ""
+
+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: ²»ÔÊÐíÔÚ modeline ÖÐʹÓÃ"
+
+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>"
+
+msgid "E529: Cannot set 'term' to empty string"
+msgstr "E529: ²»ÄÜÉ趨 'term' Ϊ¿Õ×Ö·û´®"
+
+msgid "E530: Cannot change term in GUI"
+msgstr "E530: ÔÚͼÐνçÃæÖв»ÄܸıäÖÕ¶Ë"
+
+msgid "E531: Use \":gui\" to start the GUI"
+msgstr "E531: ÇëÓà \":gui\" Æô¶¯Í¼ÐνçÃæ"
+
+msgid "E589: 'backupext' and 'patchmode' are equal"
+msgstr "E589: 'backupext' ºÍ 'patchmode' ÏàµÈ"
+
+msgid "E617: Cannot be changed in the GTK+ 2 GUI"
+msgstr "E617: ÔÚ GTK+ 2 ͼÐνçÃæÖв»Äܸü¸Ä"
+
+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 "E590: A preview window already exists"
+msgstr "E590: Ô¤ÀÀ´°¿ÚÒÑ´æÔÚ"
+
+msgid "W17: Arabic requires UTF-8, do ':set encoding=utf-8'"
+msgstr "W17: Arabic ÐèÒª UTF-8£¬ÇëÖ´ÐÐ ':set encoding=utf-8'"
+
+#, 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"
+
+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 "²»ÄÜÇл»Ö÷¿ØÌ¨(console)ģʽ !?\n"
+
+msgid "mch_get_shellsize: not a console??\n"
+msgstr "mch_get_shellsize: ²»ÊÇÖ÷¿ØÌ¨(console)??\n"
+
+#. if Vim opened a window: Executing a shell may cause crashes
+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: Ñ¡Ôñ´òÓ¡»úʧ°Ü"
+
+#, 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 "E245: Illegal char '%c' in font name \"%s\""
+msgstr "E245: ²»ÕýÈ·µÄ×Ö·û '%c' ³öÏÖÔÚ×ÖÌåÃû³Æ \"%s\" ÄÚ"
+
+msgid "Vim: Double signal, exiting\n"
+msgstr "Vim: Ë«ÖØÐźţ¬Í˳öÖÐ\n"
+
+#, c-format
+msgid "Vim: Caught deadly signal %s\n"
+msgstr "Vim: À¹½Øµ½ÖÂÃüÐźÅ(deadly signal) %s\n"
+
+#, c-format
+msgid "Vim: Caught deadly signal\n"
+msgstr "Vim: À¹½Øµ½ÖÂÃüÐźÅ(deadly signal)\n"
+
+#, c-format
+msgid "Opening the X display took %ld msec"
+msgstr "´ò¿ª X display ÓÃʱ %ld Ãë"
+
+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 "
+msgstr ""
+"\n"
+"ÎÞ·¨Ö´ÐÐ shell"
+
+msgid ""
+"\n"
+"Cannot execute shell sh\n"
+msgstr ""
+"\n"
+"ÎÞ·¨Ö´ÐÐ shell sh\n"
+
+msgid ""
+"\n"
+"shell returned "
+msgstr ""
+"\n"
+"Shell ÒÑ·µ»Ø"
+
+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 µÄÁ¬½Ó"
+
+# do not translate
+#, c-format
+msgid "dlerror = \"%s\""
+msgstr "dlerror = \"%s\""
+
+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 Á¬½Ó¼àÊÓʧ°Ü"
+
+#, 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 "shell returned %d"
+msgstr "Shell ·µ»Ø %d"
+
+#, 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 ""
+"ÔÚÄãµÄ $PATH ÖÐÕÒ²»µ½ VIMRUN.EXE¡£\n"
+"ÍⲿÃüÁîÖ´ÐÐÍê±Ïºó½«²»»áÔÝÍ£¡£\n"
+"½øÒ»²½ËµÃ÷Çë¼û :help win32-vimrun"
+
+msgid "Vim Warning"
+msgstr "Vim ¾¯¸æ"
+
+#, 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: ûÓиü¶àµÄÏî"
+
+#, c-format
+msgid "(%d of %d)%s%s: "
+msgstr "(%d / %d)%s%s: "
+
+msgid " (line deleted)"
+msgstr " (ÐÐÒÑɾ³ý)"
+
+msgid "E380: At bottom of quickfix stack"
+msgstr "E380: Quickfix ¶ÑÕ»µ×¶Ë"
+
+msgid "E381: At top of quickfix stack"
+msgstr "E381: Quickfix ¶ÑÕ»¶¥¶Ë"
+
+#, c-format
+msgid "error list %d of %d; %d errors"
+msgstr "´íÎóÁбí %d / %d£»¹² %d ¸ö´íÎó"
+
+msgid "E382: Cannot write, 'buftype' option is set"
+msgstr "E382: ÎÞ·¨Ð´È룬ÒÑÉ趨ѡÏî 'buftype'"
+
+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%%[] ÖÐÓÐÎÞЧµÄÏî"
+
+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 "E53: Unmatched %s%%("
+msgstr "E53: ²»Æ¥ÅäµÄ %s%%("
+
+#, c-format
+msgid "E54: Unmatched %s("
+msgstr "E54: ²»Æ¥ÅäµÄ %s("
+
+#, c-format
+msgid "E55: Unmatched %s)"
+msgstr "E55: ²»Æ¥ÅäµÄ %s)"
+
+#, 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 Ç°ÃæÎÞÄÚÈÝ"
+
+msgid "E65: Illegal back reference"
+msgstr "E65: ÎÞЧµÄ»ØÒý"
+
+msgid "E66: \\z( not allowed here"
+msgstr "E66: ´Ë´¦²»ÔÊÐí \\z("
+
+msgid "E67: \\z1 et al. not allowed here"
+msgstr "E67: ´Ë´¦²»ÔÊÐí \\z1 µÈ"
+
+msgid "E68: Invalid character after \\z"
+msgstr "E68: \\z ºóÃæÓÐÎÞЧµÄ×Ö·û"
+
+#, c-format
+msgid "E69: Missing ] after %s%%["
+msgstr "E69: %s%%[ ºóȱÉÙ ]"
+
+#, c-format
+msgid "E70: Empty %s%%[]"
+msgstr "E70: ¿ÕµÄ %s%%[]"
+
+#, 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 "E769: Missing ] after %s["
+msgstr "E769: %s[ ºóȱÉÙ ]"
+
+#, c-format
+msgid "E554: Syntax error in %s{...}"
+msgstr "E554: %s{...} ÖÐÓï·¨´íÎó"
+
+msgid "External submatches:\n"
+msgstr "Íⲿ·ûºÏ:\n"
+
+msgid " VREPLACE"
+msgstr " V-Ìæ»»"
+
+msgid " REPLACE"
+msgstr " Ìæ»»"
+
+msgid " REVERSE"
+msgstr " ·´Ïò"
+
+msgid " INSERT"
+msgstr " ²åÈë"
+
+msgid " (insert)"
+msgstr " (²åÈë)"
+
+msgid " (replace)"
+msgstr " (Ìæ»»)"
+
+msgid " (vreplace)"
+msgstr " (V-Ìæ»»)"
+
+msgid " Hebrew"
+msgstr " Hebrew"
+
+msgid " Arabic"
+msgstr " Arabic"
+
+msgid " (lang)"
+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 " (°üÀ¨ÉÏ´ÎÁгö·ûºÏÏî)"
+
+#. cursor at status line
+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: ÕÒ²»µ½ pattern"
+
+msgid "E759: Format error in spell file"
+msgstr "E759: ƴдÎļþ¸ñʽ´íÎó"
+
+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 "ѹËõµ¥´ÊÊ÷¡­¡­"
+
+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\" or \"%s.ascii.spl\""
+
+#, 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 "Warning: region %s not supported"
+msgstr "¾¯¸æ: ÇøÓò %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 "%s µÚ %d ÐУ¬FLAG µÄÖµÎÞЧ: %s"
+
+#, c-format
+msgid "FLAG after using flags in %s line %d: %s"
+msgstr "%s µÚ %d ÐУ¬ÔÚʹÓñêÖ¾ºó³öÏÖ FLAG: %s"
+
+#, c-format
+#~ msgid ""
+#~ "Defining COMPOUNDFORBIDFLAG after PFX item may give wrong results in %s line "
+#~ "%d"
+#~ msgstr ""
+
+#, c-format
+#~ msgid ""
+#~ "Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in %s line "
+#~ "%d"
+#~ msgstr ""
+
+#, c-format
+msgid "Wrong COMPOUNDWORDMAX value in %s line %d: %s"
+msgstr "%s µÚ %d ÐУ¬´íÎóµÄ COMPOUNDWORDMAX Öµ: %s"
+
+#, c-format
+msgid "Wrong COMPOUNDMIN value in %s line %d: %s"
+msgstr "%s µÚ %d ÐУ¬´íÎóµÄ COMPOUNDMIN Öµ: %s"
+
+#, c-format
+msgid "Wrong COMPOUNDSYLMAX value in %s line %d: %s"
+msgstr "%s µÚ %d ÐУ¬´íÎóµÄ COMPOUNDSYLMAX Öµ: %s"
+
+#, c-format
+msgid "Wrong CHECKCOMPOUNDPATTERN value in %s line %d: %s"
+msgstr "%s µÚ %d ÐУ¬´íÎóµÄ CHECKCOMPOUNDPATTERN Öµ: %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 ""
+"%s µÚ %d ÐУ¬¸½¼ÓÏî±» BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST ʹ"
+"ÓÃ: %s"
+
+#, c-format
+msgid "Expected Y or N in %s line %d: %s"
+msgstr "%s µÚ %d ÐУ¬´Ë´¦ÐèÒª Y »ò N: %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 "%s µÚ %d ÐУ¬´Ë´¦ÐèÒª REP(SAL) ¼ÆÊý"
+
+#, c-format
+msgid "Expected MAP count in %s line %d"
+msgstr "%s µÚ %d ÐУ¬´Ë´¦ÐèÒª MAP ¼ÆÊý"
+
+#, c-format
+msgid "Duplicate character in MAP in %s line %d"
+msgstr "%s µÚ %d ÐУ¬MAP ÖдæÔÚÖØ¸´µÄ×Ö·û"
+
+#, 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 "%s ÖÐȱÉÙ FOL/LOW/UPP ÐÐ"
+
+msgid "COMPOUNDSYLMAX used without SYLLABLE"
+msgstr "ÔÚûÓÐ SYLLABLE µÄÇé¿öÏÂʹÓÃÁË COMPOUNDSYLMAX"
+
+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 "%s ÖÐȱÉÙ SOFO%s ÐÐ"
+
+#, c-format
+msgid "Both SAL and SOFO lines in %s"
+msgstr "%s ͬʱ³öÏÖ SQL ºÍ SOFO ÐÐ"
+
+#, 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 %6d - %s"
+msgstr "µÚ %6d ÐУ¬µÚ %6d ¸öµ¥´Ê - %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 "ºöÂÔÁ˺¬ÓÐ·Ç ASCII ×Ö·ûµÄ %d ¸öµ¥´Ê£¬ÔÚ %s ÖÐ"
+
+#, c-format
+msgid "Reading word file %s ..."
+msgstr "¶ÁÈ¡µ¥´ÊÎļþ %s ¡­¡­"
+
+#, c-format
+#~ msgid "Duplicate /encoding= line ignored in %s line %d: %s"
+#~ msgstr ""
+
+#, c-format
+msgid "/encoding= line after word ignored in %s line %d: %s"
+msgstr "%s µÚ %d ÐУ¬µ¥´ÊºóµÄ /encoding= ÐÐÒѱ»ºöÂÔ: %s"
+
+#, c-format
+msgid "Duplicate /regions= line ignored in %s line %d: %s"
+msgstr "%s µÚ %d ÐУ¬Öظ´µÄ /regions= ÐÐÒѱ»ºöÂÔ: %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 "ºöÂÔÁ˺¬ÓÐ·Ç ASCII ×Ö·ûµÄ %d ¸öµ¥´Ê"
+
+#, c-format
+msgid "Compressed %d of %d nodes; %d (%d%%) remaining"
+msgstr "ѹËõÁË %d/%d ¸ö½Úµã£»Ê£Óà %d (%d%%)"
+
+msgid "Reading back spell file..."
+msgstr "¶ÁȡƴдÎļþ¡­¡­"
+
+#.
+#. * Go through the trie of good words, soundfold each word and add it to
+#. * the soundfold trie.
+#.
+msgid "Performing soundfolding..."
+msgstr "ÕýÔÚ soundfolding¡­¡­"
+
+#, c-format
+msgid "Number of words after soundfolding: %ld"
+msgstr "soundfolding ºóµÄµ¥´ÊÊý: %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: Êä³öÎļþÃû²»Äܺ¬ÓÐÇøÓòÃû"
+
+msgid "E754: Only up to 8 regions supported"
+msgstr "E754: ×î¶àÖ»Ö§³Ö 8 ¸öÇøÓò"
+
+#, c-format
+msgid "E755: Invalid region in %s"
+msgstr "E755: %s ³öÏÖÎÞЧµÄ·¶Î§"
+
+msgid "Warning: both compounding and NOBREAK specified"
+msgstr "¾¯¸æ: ͬʱָ¶¨ÁË compounding ºÍ 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 removed from %s"
+msgstr "´Ó %s ÖÐɾ³ýÁ˵¥´Ê"
+
+#, c-format
+msgid "Word added to %s"
+msgstr "Ïò %s ÖÐÌí¼ÓÁ˵¥´Ê"
+
+msgid "E763: Word characters differ between spell files"
+msgstr "E763: ƴдÎļþÖ®¼äµÄ×Ö·û²»Ïàͬ"
+
+msgid "Sorry, no suggestions"
+msgstr "±§Ç¸£¬Ã»Óн¨Òé"
+
+#, c-format
+msgid "Sorry, only %ld suggestions"
+msgstr "±§Ç¸£¬Ö»ÓÐ %ld Ìõ½¨Òé"
+
+#. avoid more prompt
+#, 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"
+
+#, 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 ""
+
+#, c-format
+#~ msgid "E780: .sug file is for newer version of Vim: %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E781: .sug file doesn't match .spl file: %s"
+#~ msgstr ""
+
+#, fuzzy, c-format
+#~ msgid "E782: error while reading .sug file: %s"
+#~ msgstr "E47: ¶ÁÈ¡´íÎóÎļþʧ°Ü"
+
+#. This should have been checked when generating the .spl
+#. * file.
+#~ msgid "E783: duplicate char in MAP entry"
+#~ msgstr ""
+
+#, c-format
+msgid "E390: Illegal argument: %s"
+msgstr "E390: ÎÞЧµÄ²ÎÊý: %s"
+
+#, c-format
+msgid "E391: No such syntax cluster: %s"
+msgstr "E391: ÎÞ´ËÓï·¨ cluster: \"%s\""
+
+msgid "No Syntax items defined for this buffer"
+msgstr "Õâ¸ö»º³åÇøÃ»Óж¨ÒåÈκÎÓï·¨Ïî"
+
+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"
+"--- Ó﷨ͬ²½ÏîÄ¿ (Syntax sync items) ---"
+
+msgid ""
+"\n"
+"syncing on items"
+msgstr ""
+"\n"
+"ͬ²½ÖÐ:"
+
+msgid ""
+"\n"
+"--- Syntax items ---"
+msgstr ""
+"\n"
+"--- Óï·¨ÏîÄ¿ ---"
+
+#, c-format
+msgid "E392: No such syntax cluster: %s"
+msgstr "E392: ÎÞ´ËÓï·¨ cluster: \"%s\""
+
+msgid "minimal "
+msgstr "×îС"
+
+msgid "maximal "
+msgstr "×î´ó"
+
+#, fuzzy
+#~ msgid "; match "
+#~ msgstr "Æ¥Åä %d"
+
+#, fuzzy
+#~ msgid " line breaks"
+#~ msgstr "ÉÙÓÚÒ»ÐÐ"
+
+msgid "E395: contains argument not accepted here"
+msgstr "E395: ʹÓÃÁ˲»ÕýÈ·µÄ²ÎÊý"
+
+msgid "E396: containedin argument not accepted here"
+msgstr "E396: ʹÓÃÁ˲»ÕýÈ·µÄ²ÎÊý"
+
+msgid "E393: group[t]here not accepted here"
+msgstr "E393: ʹÓÃÁ˲»ÕýÈ·µÄ²ÎÊý"
+
+#, c-format
+msgid "E394: Didn't find region item for %s"
+msgstr "E394: ÕÒ²»µ½ %s µÄ region item"
+
+msgid "E397: Filename required"
+msgstr "E397: ÐèÒªÎļþÃû³Æ"
+
+#, c-format
+msgid "E747: Missing ']': %s"
+msgstr "E747: ȱÉÙ ']': %s"
+
+#, c-format
+msgid "E398: Missing '=': %s"
+msgstr "E398: ȱÉÙ '=': %s"
+
+#, c-format
+msgid "E399: Not enough arguments: syntax region %s"
+msgstr "E399: syntax region %s µÄ²ÎÊýÌ«ÉÙ"
+
+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 ±ØÐëÊÇÁбíÀïµÄµÚÒ»¸ö"
+
+#, c-format
+msgid "E409: Unknown group name: %s"
+msgstr "E409: ²»ÕýÈ·µÄ×éÃû: %s"
+
+#, c-format
+msgid "E410: Invalid :syntax subcommand: %s"
+msgstr "E410: ²»ÕýÈ·µÄ :syntax ×ÓÃüÁî: %s"
+
+msgid "E679: recursive loop loading syncolor.vim"
+msgstr "E679: ¼ÓÔØ syncolor.vim ʱ³öÏÖǶÌ×Ñ­»·"
+
+#, c-format
+msgid "E411: highlight group not found: %s"
+msgstr "E411: ÕÒ²»µ½ highlight group: %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: ´íÎóµÄǰ¾°ÑÕÉ«"
+
+msgid "E420: BG color unknown"
+msgstr "E420: ´íÎóµÄ±³¾°ÑÕÉ«"
+
+#, 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 "E555: at bottom of tag stack"
+msgstr "E555: ÒÑÔÚ tag ¶ÑÕ»µ×²¿"
+
+msgid "E556: at top of tag stack"
+msgstr "E556: ÒÑÔÚ tag ¶ÑÕ»¶¥²¿"
+
+msgid "E425: Cannot go before first matching tag"
+msgstr "E425: Òѵ½µÚÒ»¸öÆ¥ÅäµÄ tag"
+
+#, c-format
+msgid "E426: tag not found: %s"
+msgstr "E426: ÕÒ²»µ½ tag: %s"
+
+msgid " # pri kind tag"
+msgstr " # pri kind tag"
+
+msgid "file\n"
+msgstr "Îļþ\n"
+
+msgid "E427: There is only one matching tag"
+msgstr "E427: Ö»ÓÐÒ»¸öÆ¥ÅäµÄ tag"
+
+msgid "E428: Cannot go beyond last matching tag"
+msgstr "E428: ¼ºµ½×îºóÒ»¸öÆ¥ÅäµÄ tag"
+
+#, c-format
+msgid "File \"%s\" does not exist"
+msgstr "Îļþ \"%s\" ²»´æÔÚ"
+
+#. Give an indication of the number of matching tags
+#, c-format
+msgid "tag %d of %d%s"
+msgstr "ÕÒµ½ tag: %d / %d%s"
+
+msgid " or more"
+msgstr " »ò¸ü¶à"
+
+msgid " Using tag with different case!"
+msgstr " ÒÔ²»Í¬´óСдÀ´Ê¹Óà tag£¡"
+
+#, c-format
+msgid "E429: File \"%s\" does not exist"
+msgstr "E429: Îļþ \"%s\" ²»´æÔÚ"
+
+#. Highlight title
+msgid ""
+"\n"
+" # TO tag FROM line in file/text"
+msgstr ""
+"\n"
+" # µ½ tag ´Ó ÐÐ ÔÚ Îļþ/Îı¾"
+
+#, c-format
+msgid "Searching tags file %s"
+msgstr "²éÕÒ tag Îļþ %s"
+
+#, c-format
+msgid "E430: Tag file path truncated for %s\n"
+msgstr "E430: Tag Îļþ·¾¶±»½Ø¶ÏΪ %s\n"
+
+#, c-format
+msgid "E431: Format error in tags file \"%s\""
+msgstr "E431: Tag Îļþ \"%s\" ¸ñʽ´íÎó"
+
+#, c-format
+msgid "Before byte %ld"
+msgstr "ÔÚµÚ %ld ×Ö½Ú֮ǰ"
+
+#, c-format
+msgid "E432: Tags file not sorted: %s"
+msgstr "E432: Tag ÎļþδÅÅÐò: %s"
+
+#. never opened any tags file
+msgid "E433: No tags file"
+msgstr "E433: ûÓÐ tag Îļþ"
+
+msgid "E434: Can't find tag pattern"
+msgstr "E434: ÕÒ²»µ½ tag ģʽ"
+
+msgid "E435: Couldn't find tag, just guessing!"
+msgstr "E435: ÕÒ²»µ½ tag£¬ÊÔ×Ų£¡"
+
+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: termcap ÖÐûÓÐ \"%s\" Ïî"
+
+msgid "E437: terminal capability \"cm\" required"
+msgstr "E437: ÖÕ¶ËÐèÒªÄÜÁ¦ \"cm\""
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Terminal keys ---"
+msgstr ""
+"\n"
+"--- Öն˰´¼ü ---"
+
+msgid "new shell started\n"
+msgstr "Æô¶¯Ð shell\n"
+
+msgid "Vim: Error reading input, exiting...\n"
+msgstr "Vim: ¶Á´íÎó£¬Í˳öÖÐ...\n"
+
+#. must display the prompt
+msgid "No undo possible; continue anyway"
+msgstr "ÎÞ·¨³·Ïú£»Çë¼ÌÐø"
+
+msgid "Already at oldest change"
+msgstr "ÒÑλÓÚ×î¾ÉµÄ¸Ä±ä"
+
+msgid "Already at newest change"
+msgstr "ÒÑλÓÚ×îеĸıä"
+
+#, c-format
+msgid "Undo number %ld not found"
+msgstr "ÕÒ²»µ½³·ÏúºÅ %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 "before"
+
+msgid "after"
+msgstr "after"
+
+msgid "Nothing to undo"
+msgstr "Î޿ɳ·Ïú"
+
+msgid "number changes time"
+msgstr " ±àºÅ ¸Ä±ä ʱ¼ä"
+
+msgid "E439: undo list corrupt"
+msgstr "E439: ³·ÏúÁбíËð»µ"
+
+msgid "E440: undo line missing"
+msgstr "E440: ÕÒ²»µ½Òª³·ÏúµÄÐÐ"
+
+#. Only MS VC 4.1 and earlier can do Win32s
+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"
+"Included 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 "ÎÞͼÐνçÃæ¡£"
+
+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 " Features included (+) or not (-):\n"
+msgstr " ¿ÉʹÓÃ(+)Óë²»¿ÉʹÓÃ(-)µÄ¹¦ÄÜ:\n"
+
+msgid " system vimrc file: \""
+msgstr " ϵͳ vimrc Îļþ: \""
+
+msgid " user vimrc file: \""
+msgstr " Óû§ vimrc Îļþ: \""
+
+msgid " 2nd user vimrc file: \""
+msgstr " µÚ¶þÓû§ vimrc Îļþ: \""
+
+msgid " 3rd user vimrc file: \""
+msgstr " µÚÈýÓû§ vimrc Îļþ: \""
+
+msgid " user exrc file: \""
+msgstr " Óû§ exrc Îļþ: \""
+
+msgid " 2nd user exrc file: \""
+msgstr " µÚ¶þÓû§ exrc Îļþ: \""
+
+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 " 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 " µ÷ÊÔ°æ±¾"
+
+msgid "VIM - Vi IMproved"
+msgstr "VIM - Vi IMproved"
+
+msgid "version "
+msgstr "°æ±¾ "
+
+msgid "by Bram Moolenaar et al."
+msgstr "ά»¤ÈË Bram Moolenaar µÈ"
+
+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> ²é¿´ÔÚÏß°ïÖú "
+
+msgid "type :help version7<Enter> for version info"
+msgstr "ÊäÈë :help version7<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 "²Ëµ¥ 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"
+
+#~ msgid "menu Edit->Global Settings->Toggle Vi Compatible"
+#~ msgstr ""
+
+#, fuzzy
+#~ msgid " for Vim defaults "
+#~ msgstr " # pid Êý¾Ý¿âÃû³Æ prepend path\n"
+
+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 "²Ëµ¥ Help->Sponsor/Register ²é¿´ËµÃ÷ "
+
+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 "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 "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 "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 ""
+
+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)"
+
+#. Now concatenate
+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 "--»º³åÇøÎÞÄÚÈÝ--"
+
+#.
+#. * 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: ÃüÁî±»ÖÐÖ¹"
+
+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 »ò tag ²éÕÒÖв»ÔÊÐí´ËÃüÁî"
+
+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: ÄÚ²¿´íÎó"
+
+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 "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()\" ʧ°Ü"
+
+#, 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: ÎÞ·¨Ê¹ÓÃͼÐνçÃæ: ±àÒëʱûÓÐÆôÓÃ"
+
+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"
+
+#, 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 "E37: No write since last change (add ! to override)"
+msgstr "E37: ÒÑÐ޸ĵ«ÉÐδ±£´æ (¿ÉÓà ! Ç¿ÖÆÖ´ÐÐ)"
+
+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: ÎÞ·¨´ò¿ª display"
+
+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: ûÓÐ location Áбí"
+
+msgid "E43: Damaged match string"
+msgstr "E43: ÒÑËð»µµÄÆ¥Åä×Ö·û´®"
+
+msgid "E44: Corrupted regexp program"
+msgstr "E44: ÒÑË𻵵ÄÕýÔò±í´ïʽ³ÌÐò"
+
+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 "E46: Cannot set variable in the sandbox: \"%s\""
+msgstr "E46: ²»ÄÜÔÚ sandbox ÖÐÉ趨±äÁ¿: \"%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: ÎÞ·¨¶ÁÈ¡ sign Êý¾Ý£¡"
+
+msgid "E72: Close error on swap file"
+msgstr "E72: ½»»»Îļþ¹Ø±Õ´íÎó"
+
+msgid "E73: tag stack empty"
+msgstr "E73: tag ¶ÑջΪ¿Õ"
+
+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 "Zero count"
+msgstr "¼ÆÊýΪÁã"
+
+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 ""
+
+msgid "E744: NetBeans does not allow changes in read-only files"
+msgstr "E744: NetBeans ²»ÔÊÐí¸Ä±äÖ»¶ÁÎļþ"
+
+#, c-format
+msgid "E685: Internal error: %s"
+msgstr "E685: ÄÚ²¿´íÎó: %s"
+
+msgid "E363: pattern uses more memory than 'maxmempattern'"
+msgstr "E363: ±í´ïʽµÄÄÚ´æÊ¹Óó¬³ö 'maxmempattern'"
+
+msgid "E749: empty buffer"
+msgstr "E749: ¿ÕµÄ»º³åÇø"
+
+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 "search hit TOP, continuing at BOTTOM"
+msgstr "ÒѲéÕÒµ½Îļþ¿ªÍ·£¬ÔÙ´Ó½áβ¼ÌÐø²éÕÒ"
+
+msgid "search hit BOTTOM, continuing at TOP"
+msgstr "ÒѲéÕÒµ½Îļþ½á⣬ÔÙ´Ó¿ªÍ·¼ÌÐø²éÕÒ"
+
+#~ 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 "E119: Not enough arguments for function: %s"
+#~ msgstr "E119: º¯Êý %s µÄ²ÎÊýÌ«ÉÙ"
+
+#~ msgid "E120: Using <SID> not in a script context: %s"
+#~ msgstr "E120: <SID> ²»ÄÜÔÚ script ÉÏÏÂÎÄÍâʹÓÃ: %s"
+
+#~ msgid "E123: Undefined function: %s"
+#~ msgstr "E123: º¯Êý %s ÉÐ䶨Òå"
+
+#~ msgid "E127: Cannot redefine function %s: It is in use"
+#~ msgstr "E127: º¯Êý %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/po/zh_CN.po b/src/po/zh_CN.po
new file mode 100644
index 0000000000..3db2241c56
--- /dev/null
+++ b/src/po/zh_CN.po
@@ -0,0 +1,6140 @@
+# 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: 2006-04-21 15:16+0800\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"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=gb2312\n"
+"Content-Transfer-Encoding: 8-bit\n"
+
+msgid "E82: Cannot allocate any buffer, exiting..."
+msgstr "E82: ÎÞ·¨·ÖÅäÈκλº³åÇø£¬Í˳ö³ÌÐò..."
+
+msgid "E83: Cannot allocate buffer, using other one..."
+msgstr "E83: ÎÞ·¨·ÖÅ仺³åÇø£¬Ê¹ÓÃÁíÒ»¸ö»º³åÇø..."
+
+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 "E84: No modified buffer found"
+msgstr "E84: ûÓÐÐ޸ĹýµÄ»º³åÇø"
+
+#. back where we started, didn't find anything.
+msgid "E85: There is no listed buffer"
+msgstr "E85: ûÓпÉÁгöµÄ»º³åÇø"
+
+#, c-format
+msgid "E86: Buffer %ld does not exist"
+msgstr "E86: »º³åÇø %ld ²»´æÔÚ"
+
+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 "E90: Cannot unload last buffer"
+msgstr "E90: ÎÞ·¨ÊÍ·Å×îºóÒ»¸ö»º³åÇø"
+
+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 "[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 "[δÃüÃû]"
+
+#. must be a help buffer
+msgid "help"
+msgstr "°ïÖú"
+
+msgid "[Help]"
+msgstr "[°ïÖú]"
+
+msgid "[Preview]"
+msgstr "[Ô¤ÀÀ]"
+
+msgid "All"
+msgstr "È«²¿"
+
+msgid "Bot"
+msgstr "µ×¶Ë"
+
+msgid "Top"
+msgstr "¶¥¶Ë"
+
+#, c-format
+msgid ""
+"\n"
+"# Buffer list:\n"
+msgstr ""
+"\n"
+"# »º³åÇøÁбí:\n"
+
+msgid "[Location List]"
+msgstr "[Location Áбí]"
+
+msgid "[Quickfix List]"
+msgstr "[Quickfix Áбí]"
+
+msgid ""
+"\n"
+"--- Signs ---"
+msgstr ""
+"\n"
+"--- Signs ---"
+
+#, c-format
+msgid "Signs for %s:"
+msgstr "%s µÄ Signs:"
+
+#, c-format
+msgid " line=%ld id=%d name=%s"
+msgstr " ÐÐ=%ld id=%d Ãû³Æ=%s"
+
+#, c-format
+msgid "E96: Can not diff more than %ld buffers"
+msgstr "E96: ²»ÄܱȽÏ(diff) %ld ¸öÒÔÉϵĻº³åÇø"
+
+msgid "E97: Cannot create diffs"
+msgstr "E97: ÎÞ·¨´´½¨ diff"
+
+msgid "Patch file"
+msgstr "Patch Îļþ"
+
+msgid "E98: Cannot read diff output"
+msgstr "E98: ÎÞ·¨¶ÁÈ¡ diff µÄÊä³ö"
+
+msgid "E99: Current buffer is not in diff mode"
+msgstr "E99: µ±Ç°»º³åÇø²»ÔÚ 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: ¸´ºÏ×Ö·û(digraph)Öв»ÄÜʹÓà Escape"
+
+msgid "E544: Keymap file not found"
+msgstr "E544: ÕÒ²»µ½ Keymap Îļþ"
+
+msgid "E105: Using :loadkeymap not in a sourced file"
+msgstr "E105: ²»ÊÇÔڽű¾ÎļþÖÐʹÓà :loadkeymap "
+
+msgid " Keyword completion (^N^P)"
+msgstr " ¹Ø¼ü×Ö²¹È« (^N^P)"
+
+#. ctrl_x_mode == 0, ^P/^N compl.
+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 " Tag ²¹È« (^]^N^P)"
+
+#, fuzzy
+#~ 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 " Dictionary ²¹È« (^K^N^P)"
+
+msgid " Thesaurus completion (^T^N^P)"
+msgstr " Thesaurus ²¹È« (^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 " È«Äܲ¹È« (^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 "'dictionary' option is empty"
+msgstr "Ñ¡Ïî 'dictionary' Ϊ¿Õ"
+
+msgid "'thesaurus' option is empty"
+msgstr "Ñ¡Ïî 'thesaurus' Ϊ¿Õ"
+
+#, c-format
+msgid "Scanning dictionary: %s"
+msgstr "ÕýÔÚɨÃè dictionary: %s"
+
+msgid " (insert) Scroll (^E/^Y)"
+msgstr " (²åÈë) Scroll (^E/^Y)"
+
+msgid " (replace) Scroll (^E/^Y)"
+msgstr " (Ìæ»») Scroll (^E/^Y)"
+
+#, c-format
+msgid "Scanning: %s"
+msgstr "ÕýÔÚɨÃè: %s"
+
+#, c-format
+msgid "Scanning tags."
+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.
+#.
+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 "E684: list index out of range: %ld"
+msgstr "E684: List Ë÷Òý³¬³ö·¶Î§: %ld"
+
+#, c-format
+msgid "E121: Undefined variable: %s"
+msgstr "E121: 䶨ÒåµÄ±äÁ¿: %s"
+
+msgid "E111: Missing ']'"
+msgstr "E111: ȱÉÙ ']'"
+
+#, c-format
+msgid "E686: Argument of %s must be a List"
+msgstr "E686: %s µÄ²ÎÊý±ØÐëÊÇ List"
+
+#, c-format
+msgid "E712: Argument of %s must be a List or Dictionary"
+msgstr "E712: %s µÄ²ÎÊý±ØÐëÊÇ List »òÕß Dictionary"
+
+msgid "E713: Cannot use empty key for Dictionary"
+msgstr "E713: Dictionary µÄ¼ü²»ÄÜΪ¿Õ"
+
+msgid "E714: List required"
+msgstr "E714: ÐèÒª List"
+
+msgid "E715: Dictionary required"
+msgstr "E715: ÐèÒª Dictionary"
+
+#, 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: Dictionary Öв»´æÔÚ¼ü: %s"
+
+#, c-format
+msgid "E122: Function %s already exists, add ! to replace it"
+msgstr "E122: º¯Êý %s ÒÑ´æÔÚ£¬Çë¼Ó ! Ç¿ÖÆÌæ»»"
+
+msgid "E717: Dictionary entry already exists"
+msgstr "E717: Dictionary ÏîÒÑ´æÔÚ"
+
+msgid "E718: Funcref required"
+msgstr "E718: ÐèÒª Funcref"
+
+msgid "E719: Cannot use [:] with a Dictionary"
+msgstr "E719: ²»ÄÜ¶Ô Dictionary ʹÓà [:]"
+
+#, c-format
+msgid "E734: Wrong variable type for %s="
+msgstr "E734: %s= µÄ±äÁ¿ÀàÐͲ»ÕýÈ·"
+
+#, c-format
+msgid "E130: Unknown function: %s"
+msgstr "E130: δ֪µÄº¯Êý: %s"
+
+#, c-format
+msgid "E461: Illegal variable name: %s"
+msgstr "E461: ÎÞЧµÄ±äÁ¿Ãû: %s"
+
+msgid "E687: Less targets than List items"
+msgstr "E687: Ä¿±ê±È List ÏîÊýÉÙ"
+
+msgid "E688: More targets than List items"
+msgstr "E688: Ä¿±ê±È List ÏîÊý¶à"
+
+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: Ö»ÄÜË÷Òý List »ò Dictionary"
+
+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: :for ºóȱÉÙ \"in\""
+
+#, c-format
+msgid "E107: Missing parentheses: %s"
+msgstr "E107: ȱÉÙÀ¨ºÅ: %s"
+
+#, c-format
+msgid "E108: No such variable: \"%s\""
+msgstr "E108: Î޴˱äÁ¿: \"%s\""
+
+msgid "E743: variable nested too deep for (un)lock"
+msgstr "E743: (un)lock µÄ±äÁ¿Ç¶Ì×¹ýÉî"
+
+msgid "E109: Missing ':' after '?'"
+msgstr "E109: '?' ºóȱÉÙ ':'"
+
+msgid "E691: Can only compare List with List"
+msgstr "E691: Ö»ÄÜ±È½Ï List ºÍ List"
+
+msgid "E692: Invalid operation for Lists"
+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 "E693: Can only compare Funcref with Funcref"
+msgstr "E693: Ö»ÄÜ±È½Ï Funcref ºÍ Funcref"
+
+msgid "E694: Invalid operation for Funcrefs"
+msgstr "E694: ¶Ô Funcrefs ÎÞЧµÄ²Ù×÷"
+
+msgid "E110: Missing ')'"
+msgstr "E110: ȱÉÙ ')'"
+
+msgid "E695: Cannot index a Funcref"
+msgstr "E695: ²»ÄÜË÷ÒýÒ»¸ö Funcref"
+
+#, 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"
+
+#, c-format
+msgid "E696: Missing comma in List: %s"
+msgstr "E696: List ÖÐȱÉÙ¶ººÅ: %s"
+
+#, c-format
+msgid "E697: Missing end of List ']': %s"
+msgstr "E697: List ȱÉÙ½áÊø·û ']': %s"
+
+#, c-format
+msgid "E720: Missing colon in Dictionary: %s"
+msgstr "E720: Dictionary ÖÐȱÉÙðºÅ: %s"
+
+#, c-format
+msgid "E721: Duplicate key in Dictionary: \"%s\""
+msgstr "E721: Dictionary ÖгöÏÖÖØ¸´µÄ¼ü: \"%s\""
+
+#, c-format
+msgid "E722: Missing comma in Dictionary: %s"
+msgstr "E722: Dictionary ÖÐȱÉÙ¶ººÅ: %s"
+
+#, c-format
+msgid "E723: Missing end of Dictionary '}': %s"
+msgstr "E723: Dictionary ȱÉÙ½áÊø·û '}': %s"
+
+msgid "E724: variable nested too deep for displaying"
+msgstr "E724: ±äÁ¿Ç¶Ì×¹ýÉîÎÞ·¨ÏÔʾ"
+
+msgid "E699: Too many arguments"
+msgstr "E699: ²ÎÊý¹ý¶à"
+
+msgid "E785: complete() can only be used in Insert mode"
+msgstr "E785: complete() Ö»ÄÜÔÚ²åÈëģʽÖÐʹÓÃ"
+
+#.
+#. * 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 "È·¶¨(&O)"
+
+#, c-format
+msgid "E737: Key already exists: %s"
+msgstr "E737: ¼üÒÑ´æÔÚ: %s"
+
+#, c-format
+msgid "+-%s%3ld lines: "
+msgstr "+-%s%3ld ÐÐ: "
+
+#, c-format
+msgid "E700: Unknown function: %s"
+msgstr "E700: δ֪µÄº¯Êý: %s"
+
+msgid ""
+"&OK\n"
+"&Cancel"
+msgstr ""
+"È·¶¨(&O)\n"
+"È¡Ïû(&C)"
+
+msgid "called inputrestore() more often than inputsave()"
+msgstr "inputrestore() µÄµ÷ÓôÎÊý¶àÓÚ inputsave()"
+
+msgid "E786: Range not allowed"
+msgstr "E786: ²»ÔÊÐíµÄ·¶Î§"
+
+msgid "E701: Invalid type for len()"
+msgstr "E701: len() µÄÀàÐÍÎÞЧ"
+
+msgid "E726: Stride is zero"
+msgstr "E726: ²½³¤ÎªÁã"
+
+msgid "E727: Start past end"
+msgstr "E727: ÆðʼֵÔÚÖÕÖ¹Öµºó"
+
+msgid "<empty>"
+msgstr "<¿Õ>"
+
+msgid "E240: No connection to Vim server"
+msgstr "E240: ûÓе½ Vim ·þÎñÆ÷µÄÁ¬½Ó"
+
+#, c-format
+msgid "E241: Unable to send to %s"
+msgstr "E241: ÎÞ·¨·¢Ë͵½ %s"
+
+msgid "E277: Unable to read a server reply"
+msgstr "E277: ÎÞ·¨¶ÁÈ¡·þÎñÆ÷ÏìÓ¦"
+
+msgid "E655: Too many symbolic links (cycle?)"
+msgstr "E655: ·ûºÅÁ¬½Ó¹ý¶à(Ñ­»·£¿)"
+
+msgid "E258: Unable to send to client"
+msgstr "E258: ÎÞ·¨·¢Ë͵½¿Í»§¶Ë"
+
+msgid "E702: Sort compare function failed"
+msgstr "E702: Sort ±È½Ïº¯Êýʧ°Ü"
+
+msgid "(Invalid)"
+msgstr "(ÎÞЧ)"
+
+msgid "E677: Error writing temp file"
+msgstr "E677: дÁÙʱÎļþ³ö´í"
+
+msgid "E703: Using a Funcref as a Number"
+msgstr "E703: ½« Funcref ×÷Êý×ÖʹÓÃ"
+
+msgid "E745: Using a List as a Number"
+msgstr "E745: ½« List ×÷Êý×ÖʹÓÃ"
+
+msgid "E728: Using a Dictionary as a Number"
+msgstr "E728: ½« Dictionary ×÷Êý×ÖʹÓÃ"
+
+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 ʹÓÃ"
+
+#, 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 "E706: Variable type mismatch for: %s"
+msgstr "E706: ±äÁ¿ÀàÐͲ»Æ¥Åä: %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: ±äÁ¿Ç¶Ì×¹ýÉîÎÞ·¨¸´ÖÆ"
+
+#, c-format
+msgid "E124: Missing '(': %s"
+msgstr "E124: ȱÉÙ '(': %s"
+
+#, c-format
+msgid "E125: Illegal argument: %s"
+msgstr "E125: ÎÞЧµÄ²ÎÊý: %s"
+
+msgid "E126: Missing :endfunction"
+msgstr "E126: ȱÉÙ :endfunction"
+
+#, c-format
+msgid "E746: Function name does not match script file name: %s"
+msgstr "E746: º¯ÊýÃûÓë½Å±¾ÎļþÃû²»Æ¥Åä: %s"
+
+msgid "E129: Function name required"
+msgstr "E129: ÐèÒªº¯ÊýÃû"
+
+#, c-format
+msgid "E128: Function name must start with a capital or contain a colon: %s"
+msgstr "E128: º¯ÊýÃû±ØÐëÒÔ´óд×Öĸ¿ªÍ·»òÕß°üº¬Ã°ºÅ: %s"
+
+#, c-format
+msgid "E131: Cannot delete function %s: It is in use"
+msgstr "E131: ÎÞ·¨É¾³ýº¯Êý %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"
+
+#, c-format
+msgid "continuing in %s"
+msgstr "ÔÚ %s ÖмÌÐø"
+
+msgid "E133: :return not inside a function"
+msgstr "E133: :return ²»ÔÚº¯ÊýÖÐ"
+
+#, c-format
+msgid ""
+"\n"
+"# global variables:\n"
+msgstr ""
+"\n"
+"# È«¾Ö±äÁ¿:\n"
+
+msgid ""
+"\n"
+"\tLast set from "
+msgstr ""
+"\n"
+"\t×î½üÐÞ¸ÄÓÚ "
+
+#, c-format
+msgid "<%s>%s%s %d, Hex %02x, Octal %03o"
+msgstr "<%s>%s%s %d, Ê®Áù½øÖÆ %02x, °Ë½øÖÆ %03o"
+
+#, 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: *Filter* ×Ô¶¯ÃüÁî²»¿ÉÒԸı䵱ǰ»º³åÇø"
+
+msgid "[No write since last change]\n"
+msgstr "[ÒÑÐ޸ĵ«ÉÐδ±£´æ]\n"
+
+# bad to translate
+#, 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 " FAILED"
+msgstr " ʧ°Ü"
+
+#, c-format
+msgid "E137: Viminfo file is not writable: %s"
+msgstr "E137: Viminfo Îļþ²»¿ÉдÈë: %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\""
+
+# do not translate to avoid writing Chinese in files
+#. Write the info:
+#, fuzzy, c-format
+#~ msgid "# This viminfo file was generated by Vim %s.\n"
+#~ msgstr "# Õâ¸ö viminfo ÎļþÊÇÓÉ Vim %s Éú³ÉµÄ¡£\n"
+
+# do not translate to avoid writing Chinese in files
+#, fuzzy, c-format
+msgid ""
+"# You may edit it if you're careful!\n"
+"\n"
+msgstr ""
+"# Èç¹ûÒª×ÔÐÐÐÞ¸ÄÇëÌØ±ðСÐÄ£¡\n"
+"\n"
+
+# do not translate to avoid writing Chinese in files
+#, fuzzy, c-format
+#~ msgid "# Value of 'encoding' when this file was written\n"
+#~ msgstr "# 'encoding' ÔÚ´ËÎļþ½¨Á¢Ê±µÄÖµ\n"
+
+msgid "Illegal starting char"
+msgstr "ÎÞЧµÄÆô¶¯×Ö·û"
+
+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 "½»»»Îļþ \"%s\" ÒÑ´æÔÚ£¬È·ÊµÒª¸²¸ÇÂð£¿"
+
+#, c-format
+msgid "E768: Swap file exists: %s (:silent! overrides)"
+msgstr "E768: ½»»»ÎļþÒÑ´æÔÚ: %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 ""
+"\"%s\" ÒÑÉ趨 'readonly' Ñ¡Ïî¡£\n"
+"ȷʵҪ¸²¸ÇÂð£¿"
+
+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 ²»½ÓÊÜ·ÇÊý×ֵIJÎÊý"
+
+msgid "E145: Shell commands not allowed in rvim"
+msgstr "E145: rvim ÖнûֹʹÓà shell ÃüÁî"
+
+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"
+msgstr "E147: :global ²»ÄܵݹéÖ´ÐÐ"
+
+msgid "E148: Regular expression missing from global"
+msgstr "E148: global ȱÉÙÕýÔò±í´ïʽ"
+
+#, c-format
+msgid "Pattern found in every line: %s"
+msgstr "ÿÐж¼Æ¥Åä±í´ïʽ: %s"
+
+# do not translate to avoid writing Chinese in files
+#, fuzzy, c-format
+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 "E150: Not a directory: %s"
+msgstr "E150: ²»ÊÇĿ¼: %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: Tag \"%s\" ÔÚÎļþ %s/%s ÖÐÖØ¸´³öÏÖ"
+
+#, c-format
+msgid "E160: Unknown sign command: %s"
+msgstr "E160: δ֪µÄ sign ÃüÁî: %s"
+
+msgid "E156: Missing sign name"
+msgstr "E156: ȱÉÙ sign Ãû³Æ"
+
+msgid "E612: Too many signs defined"
+msgstr "E612: Signs ¶¨Òå¹ý¶à"
+
+#, c-format
+msgid "E239: Invalid sign text: %s"
+msgstr "E239: ÎÞЧµÄ sign ÎÄ×Ö: %s"
+
+#, c-format
+msgid "E155: Unknown sign: %s"
+msgstr "E155: δ֪µÄ sign: %s"
+
+msgid "E159: Missing sign number"
+msgstr "E159: ȱÉÙ sign ºÅ"
+
+#, c-format
+msgid "E158: Invalid buffer name: %s"
+msgstr "E158: ÎÞЧµÄ»º³åÇøÃû: %s"
+
+#, c-format
+msgid "E157: Invalid sign ID: %ld"
+msgstr "E157: ÎÞЧµÄ sign ID: %ld"
+
+msgid " (NOT FOUND)"
+msgstr " (ÕÒ²»µ½)"
+
+msgid " (not supported)"
+msgstr " (²»Ö§³Ö)"
+
+msgid "[Deleted]"
+msgstr "[ÒÑɾ³ý]"
+
+msgid "Entering Debug mode. Type \"cont\" to continue."
+msgstr "½øÈëµ÷ÊÔģʽ¡£ÊäÈë \"cont\" ¼ÌÐøÔËÐС£"
+
+#, c-format
+msgid "line %ld: %s"
+msgstr "µÚ %ld ÐÐ: %s"
+
+#, c-format
+msgid "cmd: %s"
+msgstr "ÃüÁî: %s"
+
+#, 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 ÐÐ"
+
+msgid "E750: First use :profile start <fname>"
+msgstr "E750: ÇëÏÈʹÓà :profile start <fname>"
+
+#, c-format
+msgid "Save changes to \"%s\"?"
+msgstr "½«¸Ä±ä±£´æµ½ \"%s\" Âð£¿"
+
+msgid "Untitled"
+msgstr "δÃüÃû"
+
+#, 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 'runtimepath': \"%s\""
+msgstr "ÔÚ 'runtimepath' ÖÐÕÒ²»µ½ \"%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"
+
+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: ²»ÊDZ༭Æ÷µÄÃüÁî"
+
+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 "E319: Sorry, the command is not available in this version"
+msgstr "E319: ±§Ç¸£¬ÃüÁîÔڴ˰汾Öв»¿ÉÓÃ"
+
+msgid "E172: Only one file name allowed"
+msgstr "E172: Ö»ÔÊÐíÒ»¸öÎļþÃû"
+
+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 Range 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 ÐèÒª²ÎÊý"
+
+#, 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: Óû§×Ô¶¨ÒåÃüÁî±ØÐëÒÔ´óд×Öĸ¿ªÍ·"
+
+#, c-format
+msgid "E184: No such user-defined command: %s"
+msgstr "E184: ûÓÐÕâ¸öÓû§×Ô¶¨ÒåÃüÁî: %s"
+
+#, c-format
+msgid "E180: Invalid complete value: %s"
+msgstr "E180: ÎÞЧµÄ²¹È«ÀàÐÍ: %s"
+
+msgid "E468: Completion argument only allowed for custom completion"
+msgstr "E468: Ö»ÓÐ custom ²¹È«²ÅÔÊÐí²ÎÊý"
+
+msgid "E467: Custom completion requires a function argument"
+msgstr "E467: Custom ²¹È«ÐèÒªÒ»¸öº¯Êý²ÎÊý"
+
+#, c-format
+msgid "E185: Cannot find color scheme %s"
+msgstr "E185: ÕÒ²»µ½ÅäÉ«·½°¸ %s"
+
+msgid "Greetings, Vim user!"
+msgstr "ÄúºÃ£¬Vim Óû§£¡"
+
+msgid "E784: Cannot close last tab page"
+msgstr "E784: ²»ÄܹرÕ×îºóÒ»¸ö tab Ò³"
+
+msgid "Already only one tab page"
+msgstr "ÒѾ­Ö»Ê£Ò»¸ö tab Ò³ÁË"
+
+msgid "Edit File in new window"
+msgstr "ÔÚд°¿Ú±à¼­Îļþ"
+
+#, c-format
+msgid "Tab page %d"
+msgstr "Tab Ò³ %d"
+
+msgid "No swap file"
+msgstr "ÎÞ½»»»Îļþ"
+
+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 "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\""
+
+#. set mark
+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 "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: ûÓÐÓÃÓÚÌæ»» \"<sfile>\" µÄ :source ÎļþÃû"
+
+#, no-c-format
+msgid "E499: Empty file name for '%' or '#', only works with \":p:h\""
+msgstr "E499: '%' »ò '#' Ϊ¿ÕÎļþÃû£¬Ö»ÄÜÓÃÓÚ \":p:h\""
+
+msgid "E500: Evaluates to an empty string"
+msgstr "E500: ½á¹ûΪ¿Õ×Ö·û´®"
+
+msgid "E195: Cannot open viminfo file for reading"
+msgstr "E195: ÎÞ·¨´ò¿ª²¢¶ÁÈ¡ viminfo Îļþ"
+
+msgid "E196: No digraphs in this version"
+msgstr "E196: ´Ë°æ±¾ÎÞ¸´ºÏ×Ö·û(digraph)"
+
+msgid "E608: Cannot :throw exceptions with 'Vim' prefix"
+msgstr "E608: ²»ÄÜ :throw ǰ׺Ϊ 'Vim' µÄÒì³£"
+
+#. always scroll up, don't overwrite
+#, 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 ÐÐ"
+
+#. always scroll up, don't overwrite
+#, c-format
+msgid "Exception caught: %s"
+msgstr "²¶»ñÒì³£: %s"
+
+#, c-format
+#~ msgid "%s made pending"
+#~ msgstr ""
+
+#, fuzzy, c-format
+#~ msgid "%s resumed"
+#~ msgstr " ÒÑ·µ»Ø\n"
+
+#, c-format
+#~ msgid "%s discarded"
+#~ msgstr ""
+
+msgid "Exception"
+msgstr "Òì³£"
+
+msgid "Error and interrupt"
+msgstr "´íÎóºÍÖжÏ"
+
+msgid "Error"
+msgstr "´íÎó"
+
+#. if (pending & CSTP_INTERRUPT)
+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: :while ÒÔ :endfor ½áβ"
+
+msgid "E733: Using :endwhile with :for"
+msgstr "E733: :for ÒÔ :endwhile ½áβ"
+
+msgid "E601: :try nesting too deep"
+msgstr "E601: :try ǶÌײãÊý¹ýÉî"
+
+msgid "E603: :catch without :try"
+msgstr "E603: :catch ȱÉÙ¶ÔÓ¦µÄ :try"
+
+#. Give up for a ":catch" after ":finally" and ignore it.
+#. * Just parse.
+msgid "E604: :catch after :finally"
+msgstr "E604: :catch ÔÚ :finally ºóÃæ"
+
+msgid "E606: :finally without :try"
+msgstr "E606: :finally ȱÉÙ¶ÔÓ¦µÄ :try"
+
+#. Give up for a multiple ":finally" and ignore it.
+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 "tagname"
+msgstr "tag Ãû"
+
+msgid " kind file\n"
+msgstr " ÀàÐÍ Îļþ\n"
+
+msgid "'history' option is zero"
+msgstr "Ñ¡Ïî 'history' ΪÁã"
+
+# do not translate to avoid writing Chinese in files
+#, fuzzy, c-format
+msgid ""
+"\n"
+"# %s History (newest to oldest):\n"
+msgstr ""
+"\n"
+"# %s ÀúÊ·¼Ç¼ (´Óе½¾É):\n"
+
+# do not translate to avoid writing Chinese in files
+#, fuzzy
+#~ msgid "Command Line"
+#~ msgstr "ÃüÁîÐÐ"
+
+# do not translate to avoid writing Chinese in files
+#, fuzzy
+#~ msgid "Search String"
+#~ msgstr "²éÕÒ×Ö·û´®"
+
+# do not translate to avoid writing Chinese in files
+#, fuzzy
+#~ msgid "Expression"
+#~ msgstr "±í´ïʽ"
+
+# do not translate to avoid writing Chinese in files
+#, fuzzy
+#~ msgid "Input Line"
+#~ msgstr "ÊäÈëÐÐ"
+
+msgid "E198: cmd_pchar beyond the command length"
+msgstr "E198: cmd_pchar ³¬¹ýÃüÁ¶È"
+
+msgid "E199: Active window or buffer deleted"
+msgstr "E199: »î¶¯´°¿Ú»ò»º³åÇøÒѱ»É¾³ý"
+
+msgid "Illegal file name"
+msgstr "ÎÞЧµÄÎļþÃû"
+
+msgid "is a directory"
+msgstr "ÊÇĿ¼"
+
+msgid "is not a file"
+msgstr "²»ÊÇÎļþ"
+
+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: ´Ó±ê×¼ÊäÈë¶ÁÈ¡...\n"
+
+msgid "Reading from stdin..."
+msgstr "´Ó±ê×¼ÊäÈë¶ÁÈ¡..."
+
+#. Re-opening the original file failed!
+msgid "E202: Conversion made file unreadable!"
+msgstr "E202: ת»»µ¼ÖÂÎļþ²»¿É¶Á"
+
+msgid "[fifo/socket]"
+msgstr "[fifo/socket]"
+
+msgid "[fifo]"
+msgstr "[fifo]"
+
+msgid "[socket]"
+msgstr "[socket]"
+
+msgid "[RO]"
+msgstr "[Ö»¶Á]"
+
+msgid "[CR missing]"
+msgstr "[ȱÉÙ CR]'"
+
+msgid "[NL found]"
+msgstr "[ÕÒµ½ NL]"
+
+msgid "[long lines split]"
+msgstr "[³¤Ðзָî]"
+
+msgid "[NOT converted]"
+msgstr "[δת»»]"
+
+msgid "[converted]"
+msgstr "[ÒÑת»»]"
+
+msgid "[crypted]"
+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 "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 "E460: The resource fork would be lost (add ! to override)"
+msgstr "E460: Resource fork »á¶ªÊ§ (Çë¼Ó ! Ç¿ÖÆÖ´ÐÐ)"
+
+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 "E667: Fsync failed"
+msgstr "E667: ͬ²½Ê§°Ü"
+
+msgid "E512: Close failed"
+msgstr "E512: ¹Ø±Õʧ°Ü"
+
+msgid "E513: write error, conversion failed (make 'fenc' empty to override)"
+msgstr "E513: дÈë´íÎó£¬×ª»»Ê§°Ü (Ç뽫 'fenc' ÖÿÕÒÔÇ¿ÖÆÖ´ÐÐ)"
+
+msgid "E514: write error (file system full?)"
+msgstr "E514: дÈë´íÎó (ÎļþϵͳÒÑÂú£¿)"
+
+msgid " CONVERSION ERROR"
+msgstr " ת»»´íÎó"
+
+msgid "[Device]"
+msgstr "[É豸]"
+
+msgid "[New]"
+msgstr "[ÐÂ]"
+
+msgid " [a]"
+msgstr " [a]"
+
+msgid " appended"
+msgstr " ÒÑ×·¼Ó"
+
+msgid " [w]"
+msgstr " [w]"
+
+msgid " written"
+msgstr " ÒÑдÈë"
+
+msgid "E205: Patchmode: can't save original file"
+msgstr "E205: Patchmode: ÎÞ·¨±£´æÔ­Ê¼Îļþ"
+
+msgid "E206: patchmode: can't touch empty original file"
+msgstr "E206: Patchmode: ÎÞ·¨Éú³É¿ÕµÄԭʼÎļþ"
+
+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 "%ld characters"
+msgstr "%ld ¸ö×Ö·û"
+
+msgid "[noeol]"
+msgstr "[noeol]"
+
+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
+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 ""
+"È·¶¨(&O)\n"
+"¼ÓÔØÎļþ(&L)"
+
+#, 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 ""
+
+#. the group doesn't exist
+#, c-format
+msgid "E367: No such group: \"%s\""
+msgstr "E367: ÎÞ´Ë×é: \"%s\""
+
+#, 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"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Auto-Commands ---"
+msgstr ""
+"\n"
+"--- ×Ô¶¯ÃüÁî ---"
+
+#, c-format
+msgid "E680: <buffer=%d>: invalid buffer number "
+msgstr "E680: <buffer=%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 Auto commands 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 lines folded "
+msgstr "+--ÒÑÕÛµþ %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 "E229: Cannot start the GUI"
+msgstr "E229: ÎÞ·¨Æô¶¯Í¼ÐνçÃæ"
+
+#, c-format
+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' µÄÖµÎÞЧ"
+
+#, 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 "¹ö¶¯Ìõ²¿¼þ: ÎÞ·¨»ñÈ¡»¬¿éͼÏñµÄ¼¸ºÎ´óС"
+
+msgid "Vim dialog"
+msgstr "Vim ¶Ô»°¿ò"
+
+msgid "E232: Cannot create BalloonEval with both message and callback"
+msgstr "E232: ²»ÄÜͬʱʹÓÃÏûÏ¢ºÍ»Øµ÷º¯ÊýÀ´´´½¨ BalloonEval"
+
+msgid "Vim dialog..."
+msgstr "Vim ¶Ô»°¿ò..."
+
+msgid ""
+"&Yes\n"
+"&No\n"
+"&Cancel"
+msgstr ""
+"ÊÇ(&Y)\n"
+"·ñ(&N)\n"
+"È¡Ïû(&C)"
+
+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 "Ìæ»»Îª:"
+
+#. whole word only button
+msgid "Match whole word only"
+msgstr "Æ¥ÅäÍêÕûµÄ´Ê"
+
+#. match case button
+msgid "Match case"
+msgstr "Æ¥Åä´óСд"
+
+msgid "Direction"
+msgstr "·½Ïò"
+
+#. 'Up' and 'Down' buttons
+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)"
+
+#, 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 "Close tab"
+msgstr "¹Ø±Õ±êÇ©"
+
+msgid "Open tab..."
+msgstr "´ò¿ª±êÇ©..."
+
+msgid "Find string (use '\\\\' to find a '\\')"
+msgstr "²éÕÒ×Ö·û´® (ʹÓà '\\\\' À´²éÕÒ '\\')"
+
+msgid "Find & Replace (use '\\\\' to find a '\\')"
+msgstr "²éÕÒºÍÌæ»»×Ö·û´® (ʹÓà '\\\\' À´²éÕÒ '\\')"
+
+#. 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 "δʹÓÃ"
+
+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ЩÑÕÉ«¿ÉÄܲ»ÕýÈ·"
+
+#, c-format
+msgid "E250: Fonts for the following charsets are missing in fontset %s:"
+msgstr "E250: Fontset %s ȱÉÙÏÂÁÐ×Ö·û¼¯µÄ×ÖÌå:"
+
+#, c-format
+msgid "E252: Fontset name: %s"
+msgstr "E252: Fontset Ãû³Æ: %s"
+
+#, c-format
+msgid "Font '%s' is not fixed-width"
+msgstr "'%s' ²»Êǹ̶¨¿í¶ÈµÄ×ÖÌå"
+
+#, c-format
+msgid "E253: Fontset name: %s\n"
+msgstr "E253: Fontset Ãû³Æ: %s\n"
+
+#, c-format
+msgid "Font0: %s\n"
+msgstr "×ÖÌå0: %s\n"
+
+#, c-format
+msgid "Font1: %s\n"
+msgstr "×ÖÌå1: %s\n"
+
+#, c-format
+msgid "Font%ld width is not twice that of font0\n"
+msgstr "×ÖÌå%ldµÄ¿í¶È²»ÊÇ×ÖÌå0µÄÁ½±¶\n"
+
+#, c-format
+msgid "Font0 width: %ld\n"
+msgstr "×ÖÌå0µÄ¿í¶È£º%ld\n"
+
+#, c-format
+msgid ""
+"Font1 width: %ld\n"
+"\n"
+msgstr ""
+"×ÖÌå1µÄ¿í¶È: %ld\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 "Ãû³Æ:"
+
+#. create toggle button
+#~ 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 automata ´íÎó"
+
+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 ×ÊÔ´Îļþ \"%s\""
+
+#, c-format
+msgid "E618: file \"%s\" is not a PostScript resource file"
+msgstr "E618: Îļþ \"%s\" ²»ÊÇ PostScript ×ÊÔ´Îļþ"
+
+#, c-format
+msgid "E619: file \"%s\" is not a supported PostScript resource file"
+msgstr "E619: Îļþ \"%s\" ²»ÊÇÒÑÖ§³ÖµÄ PostScript ×ÊÔ´Îļþ"
+
+#, c-format
+msgid "E621: \"%s\" resource file has wrong version"
+msgstr "E621: \"%s\" ×ÊÔ´Îļþ°æ±¾²»ÕýÈ·"
+
+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 ×ÊÔ´Îļþ \"prolog.ps\""
+
+msgid "E456: Can't find PostScript resource file \"cidfont.ps\""
+msgstr "E456: ÕÒ²»µ½ PostScript ×ÊÔ´Îļþ \"cidfont.ps\""
+
+#, c-format
+msgid "E456: Can't find PostScript resource file \"%s.ps\""
+msgstr "E456: ÕÒ²»µ½ PostScript ×ÊÔ´Îļþ \"%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: ÕÒ²»µ½ tag"
+
+#, 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 ½øÐÐ fork"
+
+msgid "cs_create_connection exec failed"
+msgstr "cs_create_connection Ö´ÐÐʧ°Ü"
+
+msgid "E623: Could not spawn cscope process"
+msgstr "E623: ÎÞ·¨Éú³É cscope ½ø³Ì"
+
+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 "E567: no cscope connections"
+msgstr "E567: ûÓÐ cscope Á¬½Ó"
+
+#, c-format
+msgid "E259: no matches found for cscope query %s of %s"
+msgstr "E259: cscope ²éѯ %s %s ûÓÐÕÒµ½Æ¥ÅäµÄ½á¹û"
+
+#, c-format
+msgid "E469: invalid cscopequickfix flag %c for %c"
+msgstr "E469: cscopequickfix ±êÖ¾ %c ¶Ô %c ÎÞЧ"
+
+msgid "cscope commands:\n"
+msgstr "cscope ÃüÁî:\n"
+
+#, c-format
+msgid "%-5s: %-30s (Usage: %s)"
+msgstr "%-5s: %-30s (Ó÷¨: %s)"
+
+#, 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 Êý¾Ý¿âδ±»¼ÓÈë"
+
+msgid "E569: maximum number of cscope connections reached"
+msgstr "E569: ÒÑ´ïµ½ cscope µÄ×î´óÁ¬½ÓÊý"
+
+#, c-format
+msgid "E261: cscope connection %s not found"
+msgstr "E261: ÕÒ²»µ½ cscope Á¬½Ó %s"
+
+#, c-format
+msgid "cscope connection %s closed"
+msgstr "cscope Á¬½Ó %s ÒѹرÕ"
+
+#. should not reach here
+msgid "E570: fatal error in cs_manage_matches"
+msgstr "E570: cs_manage_matches ÑÏÖØ´íÎó"
+
+#, c-format
+msgid "Cscope tag: %s"
+msgstr "Cscope tag: %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 Êý¾Ý¿âÃû prepend path\n"
+
+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 "Ðкų¬³ö·¶Î§"
+
+#, c-format
+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 "¹â±êλÖÃÔÚ»º³åÇøÍâ"
+
+#, c-format
+msgid "<window object (deleted) at %.8lX>"
+msgstr "<´°¿Ú¶ÔÏó(ÒÑɾ³ý): %.8lX>"
+
+#, c-format
+msgid "<window object (unknown) at %.8lX>"
+msgstr "<´°¿Ú¶ÔÏó(δ֪): %.8lX>"
+
+#, c-format
+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 ¿â"
+
+#, c-format
+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 "Á¬½ÓÖÐ"
+
+#, c-format
+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 "ûÓÐÉ趨±ê¼Ç"
+
+#, c-format
+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 "ÎÞ·¨×¢²á»Øµ÷ÃüÁî: »º³åÇø/´°¿ÚÒѱ»É¾³ý"
+
+#. This should never happen. Famous last word?
+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"
+
+#, 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 ʵÀý×¢²áÊôÐÔÓÐÎó¡£ÒÑɾ³ý£¡"
+
+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 "ÎÞЧµÄ²ÎÊý"
+
+#, c-format
+msgid "%d files to edit\n"
+msgstr "»¹ÓÐ %d ¸öÎļþµÈ´ý±à¼­\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: ´íÎó: ÎÞ·¨´Ó NetBeans ÖÐÆô¶¯ gvim\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"
+
+#. just in case..
+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 ±à¼­ tag ¶¨Òå´¦µÄÎļþ"
+
+msgid "-q [errorfile] edit file with first error"
+msgstr "-q [errorfile] ±à¼­µÚÒ»¸ö³ö´í´¦µÄÎļþ"
+
+msgid ""
+"\n"
+"\n"
+"usage:"
+msgstr ""
+"\n"
+"\n"
+"Ó÷¨:"
+
+msgid " vim [arguments] "
+msgstr " vim [²ÎÊý] "
+
+msgid ""
+"\n"
+" or:"
+msgstr ""
+"\n"
+" »ò:"
+
+#~ msgid "where case is ignored prepend / to make flag upper case"
+#~ msgstr ""
+
+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È¡Ïû 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\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 "-s\t\t\tSilent (batch) mode (only for \"ex\")"
+msgstr "-s\t\t\t°²¾²(Åú´¦Àí)ģʽ (Ö»ÄÜÓë \"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\tÈÝÒ×ģʽ (ͬ \"evim\"£¬ÎÞģʽ)"
+
+msgid "-R\t\t\tReadonly mode (like \"view\")"
+msgstr "-R\t\t\tÖ»¶Áģʽ (ͬ \"view\")"
+
+msgid "-Z\t\t\tRestricted mode (like \"rvim\")"
+msgstr "-Z\t\t\tÏÞÖÆÄ£Ê½ (ͬ \"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]\t\tVerbose level"
+msgstr "-V[N]\t\tVerbose µÈ¼¶"
+
+msgid "-D\t\t\tDebugging mode"
+msgstr "-D\t\t\tµ÷ÊÔģʽ"
+
+msgid "-n\t\t\tNo swap file, use memory only"
+msgstr "-n\t\t\t²»Ê¹Óý»»»Îļþ£¬Ö»Ê¹ÓÃÄÚ´æ"
+
+msgid "-r\t\t\tList swap files and exit"
+msgstr "-r\t\t\tÁгö½»»»Îļþ²¢Í˳ö"
+
+msgid "-r (with file name)\tRecover crashed session"
+msgstr "-r (¸úÎļþÃû)\t\t»Ö¸´±ÀÀ£µÄ»á»°"
+
+msgid "-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²»Ê¹Óà newcli À´´ò¿ª´°¿Ú"
+
+msgid "-dev <device>\t\tUse <device> for I/O"
+msgstr "-dev <device>\t\tʹÓà <device> ½øÐÐÊäÈëÊä³ö"
+
+msgid "-A\t\t\tstart in Arabic mode"
+msgstr "-A\t\t\tÒÔ Arabic ģʽÆô¶¯"
+
+msgid "-H\t\t\tStart in Hebrew mode"
+msgstr "-H\t\t\tÒÔ Hebrew ģʽÆô¶¯"
+
+msgid "-F\t\t\tStart in Farsi mode"
+msgstr "-F\t\t\tÒÔ Farsi ģʽÆô¶¯"
+
+msgid "-T <terminal>\tSet terminal type to <terminal>"
+msgstr "-T <terminal>\tÉ趨ÖÕ¶ËÀàÐÍΪ <terminal>"
+
+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²»¼ÓÔØ plugin ½Å±¾"
+
+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 "+<lnum>\t\tÆô¶¯ºóÌøµ½µÚ <lnum> ÐÐ"
+
+msgid "--cmd <command>\tExecute <command> before loading any vimrc file"
+msgstr "--cmd <command>\t¼ÓÔØÈκΠvimrc ÎļþǰִÐÐ <command>"
+
+msgid "-c <command>\t\tExecute <command> after loading the first file"
+msgstr "-c <command>\t\t¼ÓÔØµÚÒ»¸öÎļþºóÖ´ÐÐ <command>"
+
+msgid "-S <session>\t\tSource file <session> after loading the first file"
+msgstr "-S <session>\t\t¼ÓÔØµÚÒ»¸öÎļþºóÖ´ÐÐÎļþ <session>"
+
+msgid "-s <scriptin>\tRead Normal mode commands from file <scriptin>"
+msgstr "-s <scriptin>\t´ÓÎļþ <scriptin> ¶ÁÈëÕý³£Ä£Ê½µÄÃüÁî"
+
+msgid "-w <scriptout>\tAppend all typed commands to file <scriptout>"
+msgstr "-w <scriptout>\t½«ËùÓÐÊäÈëµÄÃüÁî×·¼Óµ½Îļþ <scriptout>"
+
+msgid "-W <scriptout>\tWrite all typed commands to file <scriptout>"
+msgstr "-W <scriptout>\t½«ËùÓÐÊäÈëµÄÃüÁîдÈëµ½Îļþ <scriptout>"
+
+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 "-i <viminfo>\t\tUse <viminfo> instead of .viminfo"
+msgstr "-i <viminfo>\t\tʹÓà <viminfo> È¡´ú .viminfo"
+
+msgid "-h or --help\tPrint Help (this message) and exit"
+msgstr "-h »ò --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 <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"
+
+#. Failed to send, abort.
+msgid ": Send failed.\n"
+msgstr ": ·¢ËÍʧ°Ü¡£\n"
+
+#. Let vim start normally.
+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 "ûÓÐ display: ·¢Ëͱí´ïʽʧ°Ü¡£\n"
+
+msgid ": Send expression failed.\n"
+msgstr ": ·¢Ëͱí´ïʽʧ°Ü¡£\n"
+
+msgid "No marks set"
+msgstr "ûÓÐÉ趨±ê¼Ç"
+
+#, c-format
+msgid "E283: No marks matching \"%s\""
+msgstr "E283: ûÓÐÆ¥Åä \"%s\" µÄ±ê¼Ç"
+
+#. Highlight title
+msgid ""
+"\n"
+"mark line col file/text"
+msgstr ""
+"\n"
+"±ê¼Ç ÐÐ ÁÐ Îļþ/Îı¾"
+
+#. Highlight title
+msgid ""
+"\n"
+" jump line col file/text"
+msgstr ""
+"\n"
+" Ìø×ª ÐÐ ÁÐ Îļþ/Îı¾"
+
+#. Highlight title
+msgid ""
+"\n"
+"change line col text"
+msgstr ""
+"\n"
+" ¸Ä±ä ÐÐ ÁÐ Îı¾"
+
+#, c-format
+msgid ""
+"\n"
+"# File marks:\n"
+msgstr ""
+"\n"
+"# Îļþ±ê¼Ç:\n"
+
+#. Write the jumplist with -'
+#, c-format
+msgid ""
+"\n"
+"# Jumplist (newest first):\n"
+msgstr ""
+"\n"
+"# Ìø×ªÁбí (´Óе½¾É):\n"
+
+#, c-format
+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: ¾¯¸æ: ÎÞ·¨É趨ÊäÈë·¨µÄÊͷŻص÷º¯Êý"
+
+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 "E293: block was not locked"
+msgstr "E293: ¿éδ±»Ëø¶¨"
+
+msgid "E294: Seek error in swap file read"
+msgstr "E294: ½»»»Îļþ¶ÁÈ¡¶¨Î»´íÎó"
+
+msgid "E295: Read error in swap file"
+msgstr "E295: ½»»»Îļþ¶ÁÈ¡´íÎó"
+
+msgid "E296: Seek error in swap file write"
+msgstr "E296: ½»»»ÎļþдÈ붨λ´íÎó"
+
+msgid "E297: Write error in swap file"
+msgstr "E297: ½»»»ÎļþдÈë´íÎó"
+
+msgid "E300: Swap file already exists (symlink attack?)"
+msgstr "E300: ½»»»ÎļþÒÑ´æÔÚ (·ûºÅÁ¬½Ó¹¥»÷£¿)"
+
+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£¿"
+
+#. could not (re)open the swap file, what can we do????
+msgid "E301: Oops, lost the swap file!!!"
+msgstr "E301: àÞ£¬½»»»Îļþ²»¼ûÁË£¡£¡£¡"
+
+msgid "E302: Could not rename swap file"
+msgstr "E302: ÎÞ·¨ÖØÃüÃû½»»»Îļþ"
+
+#, c-format
+msgid "E303: Unable to open swap file for \"%s\", recovery impossible"
+msgstr "E303: ÎÞ·¨´ò¿ª \"%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 µÄ½»»»Îļþ"
+
+msgid "Enter number of swap file to use (0 to quit): "
+msgstr "ÇëÊäÈëҪʹÓõĽ»»»Îļþ±àºÅ (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 »¹À´²»¼°¸üн»»»Îļþ¡£"
+
+msgid " cannot be used with this version of Vim.\n"
+msgstr " ²»ÄÜÔڸð汾µÄ Vim ÖÐʹÓá£\n"
+
+msgid "Use Vim version 3.0.\n"
+msgstr "ʹÓà Vim 3.0¡£\n"
+
+#, c-format
+msgid "E307: %s does not look like a Vim swap file"
+msgstr "E307: %s ¿´ÆðÀ´²»ÏñÊÇ Vim ½»»»Îļþ"
+
+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 "Using swap file \"%s\""
+msgstr "ʹÓý»»»Îļþ \"%s\""
+
+#, c-format
+msgid "Original file \"%s\""
+msgstr "ԭʼÎļþ \"%s\""
+
+msgid "E308: Warning: Original file may have been changed"
+msgstr "E308: ¾¯¸æ: ԭʼÎļþ¿ÉÄÜÒѱ»ÐÞ¸Ä"
+
+#, c-format
+msgid "E309: Unable to read block 1 from %s"
+msgstr "E309: ÎÞ·¨´Ó %s ¶ÁÈ¡¿é 1"
+
+# do not translate to avoid writing Chinese in files
+#, fuzzy
+#~ msgid "???MANY LINES MISSING"
+#~ msgstr "???ȱÉÙÁËÌ«¶àÐÐ"
+
+# do not translate to avoid writing Chinese in files
+#, fuzzy
+#~ msgid "???LINE COUNT WRONG"
+#~ msgstr "???ÐÐÊý´íÎó"
+
+# do not translate to avoid writing Chinese in files
+#, fuzzy
+#~ msgid "???EMPTY BLOCK"
+#~ msgstr "???¿ÕµÄ¿é"
+
+# do not translate to avoid writing Chinese in files
+#, fuzzy
+#~ msgid "???LINES MISSING"
+#~ msgstr "???ȱÉÙÁËһЩÐÐ"
+
+#, 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
+#, fuzzy
+#~ msgid "???BLOCK MISSING"
+#~ msgstr "???ȱÉÙ¿é"
+
+# do not translate to avoid writing Chinese in files
+#, fuzzy
+#~ msgid "??? from here until ???END lines may be messed up"
+#~ msgstr "??? ´ÓÕâÀïµ½ ???END µÄÐпÉÄÜÒÑ»ìÂÒ"
+
+# do not translate to avoid writing Chinese in files
+#, fuzzy
+#~ msgid "??? from here until ???END lines may have been inserted/deleted"
+#~ msgstr "??? ´ÓÕâÀïµ½ ???END µÄÐпÉÄÜÒѱ»²åÈë/ɾ³ý¹ý"
+
+# do not translate to avoid writing Chinese in files
+#, fuzzy
+#~ msgid "???END"
+#~ msgstr "???END"
+
+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 "»Ö¸´Íê±Ï¡£ÇëÈ·¶¨Ò»ÇÐÕý³£¡£"
+
+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)\n"
+msgstr "ÔÙÔËÐÐ diff ÓëÔ­Îļþ±È½ÏÒÔ¼ì²éÊÇ·ñÓиıä)\n"
+
+msgid ""
+"Delete the .swp file afterwards.\n"
+"\n"
+msgstr ""
+"È»ºó°Ñ .swp Îļþɾµô¡£\n"
+"\n"
+
+#. use msg() to start the scrolling properly
+msgid "Swap files found:"
+msgstr "ÕÒµ½½»»»Îļþ:"
+
+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 ½»»»Îļþ]"
+
+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"
+" ½ø³Ì ID: "
+
+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: ÎÞ·¨±£Áô£¬Ã»Óн»»»Îļþ"
+
+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: Ö¸Õë¿é id ´íÎó 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: Ö¸Õë¿é id ´íÎó 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: Ö¸Õë¿é id ´íÎó"
+
+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: Ö¸Õë¿é id ´íÎó 2"
+
+#, c-format
+msgid "E773: Symlink loop for \"%s\""
+msgstr "E773: \"%s\" ·ûºÅÁ¬½Ó³öÏÖÑ­»·"
+
+msgid "E325: ATTENTION"
+msgstr "E325: ×¢Òâ"
+
+msgid ""
+"\n"
+"Found a swap file by the name \""
+msgstr ""
+"\n"
+"·¢ÏÖ½»»»Îļþ \""
+
+msgid "While opening file \""
+msgstr "ÕýÔÚ´ò¿ªÎļþ \""
+
+msgid " NEWER than swap file!\n"
+msgstr " ±È½»»»ÎļþУ¡\n"
+
+#. Some of these messages are long to allow translation to
+#. * other languages.
+msgid ""
+"\n"
+"(1) Another program may be editing the same file.\n"
+" If this is the case, be careful not to end up with two\n"
+" different instances of the same file when making changes.\n"
+msgstr ""
+"\n"
+"(1) ÁíÒ»¸ö³ÌÐò¿ÉÄÜÒ²Ôڱ༭ͬһ¸öÎļþ¡£\n"
+" Èç¹ûÊÇÕâÑù£¬ÐÞ¸ÄʱÇë×¢Òâ±ÜÃâͬһ¸öÎļþ²úÉúÁ½¸ö²»Í¬µÄ°æ±¾¡£\n"
+"\n"
+
+msgid " Quit, or continue with caution.\n"
+msgstr " Í˳ö£¬»òСÐĵؼÌÐø¡£\n"
+
+msgid ""
+"\n"
+"(2) An edit session for this file crashed.\n"
+msgstr ""
+"\n"
+"(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 " Èç¹ûÄãÒѾ­½øÐÐÁ˻ָ´£¬Çëɾ³ý½»»»Îļþ \""
+
+msgid ""
+"\"\n"
+" to avoid this message.\n"
+msgstr ""
+"\"\n"
+" ÒÔ±ÜÃâÔÙ¿´µ½´ËÏûÏ¢¡£\n"
+
+msgid "Swap file \""
+msgstr "½»»»Îļþ \""
+
+msgid "\" already exists!"
+msgstr "\" ÒÑ´æÔÚ£¡"
+
+msgid "VIM - ATTENTION"
+msgstr "VIM - ×¢Òâ"
+
+msgid "Swap file already exists!"
+msgstr "½»»»ÎļþÒÑ´æÔÚ£¡"
+
+msgid ""
+"&Open Read-Only\n"
+"&Edit anyway\n"
+"&Recover\n"
+"&Quit\n"
+"&Abort"
+msgstr ""
+"ÒÔÖ»¶Á·½Ê½´ò¿ª(&O)\n"
+"Ö±½Ó±à¼­(&E)\n"
+"»Ö¸´(&R)\n"
+"Í˳ö(&Q)\n"
+"ÖÐÖ¹(&A)"
+
+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)"
+
+msgid "E326: Too many swap files found"
+msgstr "E326: ÕÒµ½Ì«¶à½»»»Îļþ"
+
+msgid "E327: Part of menu-item path is not sub-menu"
+msgstr "E327: ²Ëµ¥ÏîµÄij²¿·Ö·¾¶²»ÊÇ×Ӳ˵¥"
+
+msgid "E328: Menu only exists in another mode"
+msgstr "E328: ²Ëµ¥Ö»ÔÚÆäËüģʽÖдæÔÚ"
+
+#, c-format
+msgid "E329: No menu \"%s\""
+msgstr "E329: ûÓв˵¥ \"%s\""
+
+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: ·Ö¸ôÏß²»ÄÜÊDz˵¥Â·¾¶µÄÒ»²¿·Ö"
+
+#. Now we have found the matching menu, and we list the mappings
+#. Highlight title
+msgid ""
+"\n"
+"--- Menus ---"
+msgstr ""
+"\n"
+"--- ²Ëµ¥ ---"
+
+msgid "Tear off this menu"
+msgstr "˺Ï´˲˵¥"
+
+msgid "E333: Menu path must lead to a menu item"
+msgstr "E333: ²Ëµ¥Â·¾¶±ØÐëÖ¸Ïò²Ëµ¥Ïî"
+
+#, c-format
+msgid "E334: Menu not found: %s"
+msgstr "E334: ÕÒ²»µ½²Ëµ¥: %s"
+
+#, c-format
+msgid "E335: Menu not defined for %s mode"
+msgstr "E335: %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 "¼òÌåÖÐÎÄÏûϢά»¤Õß: Yuheng Xie <elephant@linux.net.cn>"
+
+msgid "Interrupt: "
+msgstr "ÒÑÖжÏ: "
+
+msgid "Press ENTER or type command to continue"
+msgstr "Çë°´ ENTER »òÆäËüÃüÁî¼ÌÐø"
+
+#, 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 ""
+"ÊÇ(&Y)\n"
+"·ñ(&N)"
+
+msgid ""
+"&Yes\n"
+"&No\n"
+"Save &All\n"
+"&Discard All\n"
+"&Cancel"
+msgstr ""
+"ÊÇ(&Y)\n"
+"·ñ(&N)\n"
+"È«²¿±£´æ(&A)\n"
+"È«²¿¶ªÆú(&D)\n"
+"È¡Ïû(&C)"
+
+msgid "Select Directory dialog"
+msgstr "Ñ¡ÔñĿ¼¶Ô»°¿ò"
+
+msgid "Save File dialog"
+msgstr "±£´æÎļþ¶Ô»°¿ò"
+
+msgid "Open File dialog"
+msgstr "´ò¿ªÎļþ¶Ô»°¿ò"
+
+#. TODO: non-GUI file selector here
+msgid "E338: Sorry, no file browser in console mode"
+msgstr "E338: ±§Ç¸£¬¿ØÖÆÌ¨Ä£Ê½ÏÂûÓÐÎļþä¯ÀÀÆ÷"
+
+msgid "E766: Insufficient arguments for printf()"
+msgstr "E766: printf() µÄ²ÎÊý²»×ã"
+
+msgid "E767: Too many arguments to printf()"
+msgstr "E767: printf() µÄ²ÎÊý¹ý¶à"
+
+msgid "W10: Warning: Changing a readonly file"
+msgstr "W10: ¾¯¸æ: ÕýÔÚÐÞ¸ÄÒ»¸öÖ»¶ÁÎļþ"
+
+msgid "Type number or click with mouse (<Enter> cancels): "
+msgstr "ÇëÊäÈëÊý×Ö»òµã»÷Êó±ê (<Enter> È¡Ïû): "
+
+msgid "Choice number (<Enter> 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 "Beep!"
+
+msgid "Vim: preserving files...\n"
+msgstr "Vim: ÕýÔÚ±£ÁôÎļþ¡­¡­\n"
+
+#. close all memfiles, without deleting
+msgid "Vim: Finished.\n"
+msgstr "Vim: ½áÊø¡£\n"
+
+#, c-format
+msgid "ERROR: "
+msgstr "´íÎó: "
+
+#, c-format
+msgid ""
+"\n"
+"[bytes] total alloc-freed %lu-%lu, in use %lu, peak use %lu\n"
+msgstr ""
+"\n"
+"[×Ö½Ú] ×ܹ² alloc-free %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 "µ÷ÓÃ shell Ö´ÐÐ: \"%s\""
+
+msgid "E545: Missing colon"
+msgstr "E545: ȱÉÙðºÅ"
+
+msgid "E546: Illegal mode"
+msgstr "E546: ÎÞЧµÄģʽ"
+
+msgid "E547: Illegal mouseshape"
+msgstr "E547: ÎÞЧµÄÊó±êÐÎ×´"
+
+msgid "E548: digit expected"
+msgstr "E548: ´Ë´¦ÐèÒªÊý×Ö"
+
+msgid "E549: Illegal percentage"
+msgstr "E549: ÎÞЧµÄ°Ù·Ö±È"
+
+msgid "Enter encryption key: "
+msgstr "ÊäÈëÃÜÂë: "
+
+msgid "Enter same key again: "
+msgstr "ÇëÔÙÊäÈëÒ»´Î: "
+
+msgid "Keys don't match!"
+msgstr "Á½´ÎÃÜÂ벻ƥÅ䣡"
+
+#, c-format
+msgid ""
+"E343: Invalid path: '**[number]' must be at the end of the path or be "
+"followed by '%s'."
+msgstr "E343: ÎÞЧµÄ·¾¶: '**[number]' ±ØÐëÔÚ·¾¶Ä©Î²»òÕߺóÃæ½Ó '%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: ÔÚ·¾¶ÖÐÕÒ²»µ½Îļþ \"%s\""
+
+#, c-format
+msgid "E346: No more directory \"%s\" found in cdpath"
+msgstr "E346: ÔÚ·¾¶ÖÐÕÒ²»µ½¸ü¶àµÄÎļþ \"%s\""
+
+#, c-format
+msgid "E347: No more file \"%s\" found in path"
+msgstr "E347: ÔÚ·¾¶ÖÐÕÒ²»µ½¸ü¶àµÄÎļþ \"%s\""
+
+#. Get here when the server can't be found.
+msgid "Cannot connect to Netbeans #2"
+msgstr "ÎÞ·¨Á¬½Óµ½ Netbeans #2"
+
+msgid "Cannot connect to Netbeans"
+msgstr "ÎÞ·¨Á¬½Óµ½ Netbeans"
+
+#, c-format
+msgid "E668: Wrong access mode for NetBeans connection info file: \"%s\""
+msgstr "E668: NetBeans Á¬½ÓÐÅÏ¢ÎļþÖдíÎóµÄ·ÃÎÊģʽ: \"%s\""
+
+msgid "read from Netbeans socket"
+msgstr "´Ó Netbeans Ì×½Ó×Ö¶ÁÈ¡"
+
+#, c-format
+msgid "E658: NetBeans connection lost for buffer %ld"
+msgstr "E658: »º³åÇø %ld ¶ªÊ§ NetBeans Á¬½Ó"
+
+msgid "E505: "
+msgstr "E505: "
+
+msgid "E774: 'operatorfunc' is empty"
+msgstr "E774: 'operatorfunc' Ϊ¿Õ"
+
+msgid "E775: Eval feature not available"
+msgstr "E775: ÇóÖµ¹¦Äܲ»¿ÉÓÃ"
+
+msgid "Warning: terminal cannot highlight"
+msgstr "¾¯¸æ: ÄãµÄÖն˲»ÄÜÏÔʾ¸ßÁÁ"
+
+msgid "E348: No string under cursor"
+msgstr "E348: ¹â±ê´¦Ã»ÓÐ×Ö·û´®"
+
+msgid "E349: No identifier under cursor"
+msgstr "E349: ¹â±ê´¦Ã»ÓÐʶ±ð×Ö"
+
+msgid "E352: Cannot erase folds with current 'foldmethod'"
+msgstr "E352: ²»ÄÜÔÚµ±Ç°µÄ 'foldmethod' ÏÂɾ³ý fold"
+
+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 :quit<Enter> to exit Vim"
+msgstr "ÊäÈë :quit<Enter> Í˳ö 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: ûÓÐǰһ¸öʹÓõļĴæÆ÷"
+
+#. must display the prompt
+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 ÐÐ"
+
+msgid "block of 1 line yanked"
+msgstr "¸´ÖÆÁË 1 ÐеĿé"
+
+msgid "1 line yanked"
+msgstr "¸´ÖÆÁË 1 ÐÐ"
+
+#, c-format
+msgid "block of %ld lines yanked"
+msgstr "¸´ÖÆÁË %ld ÐеĿé"
+
+#, c-format
+msgid "%ld lines yanked"
+msgstr "¸´ÖÆÁË %ld ÐÐ"
+
+#, c-format
+msgid "E353: Nothing in register %s"
+msgstr "E353: ¼Ä´æÆ÷ %s ÀïûÓж«Î÷"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Registers ---"
+msgstr ""
+"\n"
+"--- ¼Ä´æÆ÷ ---"
+
+msgid "Illegal register name"
+msgstr "ÎÞЧµÄ¼Ä´æÆ÷Ãû"
+
+#, c-format
+msgid ""
+"\n"
+"# Registers:\n"
+msgstr ""
+"\n"
+"# ¼Ä´æÆ÷:\n"
+
+#, c-format
+msgid "E574: Unknown register type %d"
+msgstr "E574: δ֪µÄ¼Ä´æÆ÷ÀàÐÍ %d"
+
+#, c-format
+msgid "%ld Cols; "
+msgstr "%ld ÁÐ; "
+
+#, c-format
+msgid "Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Bytes"
+msgstr "Ñ¡ÔñÁË %s%ld/%ld ÐÐ; %ld/%ld ¸ö´Ê; %ld/%ld ¸ö×Ö½Ú"
+
+#, c-format
+msgid ""
+"Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Chars; %ld of %ld "
+"Bytes"
+msgstr "Ñ¡ÔñÁË %s%ld/%ld ÐÐ; %ld/%ld ¸ö´Ê; %ld/%ld ¸ö×Ö·û; %ld/%ld ¸ö×Ö½Ú"
+
+#, c-format
+msgid "Col %s of %s; Line %ld of %ld; Word %ld of %ld; Byte %ld of %ld"
+msgstr "µÚ %s/%s ÁÐ; µÚ %ld/%ld ÐÐ; µÚ %ld/%ld ¸ö´Ê; µÚ %ld/%ld ¸ö×Ö½Ú"
+
+#, c-format
+msgid ""
+"Col %s of %s; Line %ld of %ld; Word %ld of %ld; Char %ld of %ld; Byte %ld of "
+"%ld"
+msgstr ""
+"µÚ %s/%s ÁÐ; µÚ %ld/%ld ÐÐ; µÚ %ld/%ld ¸ö´Ê; µÚ %ld/%ld ¸ö×Ö·û; µÚ %ld/%ld ¸ö"
+"×Ö½Ú"
+
+#, c-format
+#~ msgid "(+%ld for BOM)"
+#~ msgstr ""
+
+#~ msgid "%<%f%h%m%=Page %N"
+#~ msgstr ""
+
+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: ²»ÔÊÐíÔÚ modeline ÖÐʹÓÃ"
+
+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>"
+
+msgid "E529: Cannot set 'term' to empty string"
+msgstr "E529: ²»ÄÜÉ趨 'term' Ϊ¿Õ×Ö·û´®"
+
+msgid "E530: Cannot change term in GUI"
+msgstr "E530: ÔÚͼÐνçÃæÖв»ÄܸıäÖÕ¶Ë"
+
+msgid "E531: Use \":gui\" to start the GUI"
+msgstr "E531: ÇëÓà \":gui\" Æô¶¯Í¼ÐνçÃæ"
+
+msgid "E589: 'backupext' and 'patchmode' are equal"
+msgstr "E589: 'backupext' ºÍ 'patchmode' ÏàµÈ"
+
+msgid "E617: Cannot be changed in the GTK+ 2 GUI"
+msgstr "E617: ÔÚ GTK+ 2 ͼÐνçÃæÖв»Äܸü¸Ä"
+
+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 "E590: A preview window already exists"
+msgstr "E590: Ô¤ÀÀ´°¿ÚÒÑ´æÔÚ"
+
+msgid "W17: Arabic requires UTF-8, do ':set encoding=utf-8'"
+msgstr "W17: Arabic ÐèÒª UTF-8£¬ÇëÖ´ÐÐ ':set encoding=utf-8'"
+
+#, 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"
+
+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 "²»ÄÜÇл»Ö÷¿ØÌ¨(console)ģʽ !?\n"
+
+msgid "mch_get_shellsize: not a console??\n"
+msgstr "mch_get_shellsize: ²»ÊÇÖ÷¿ØÌ¨(console)??\n"
+
+#. if Vim opened a window: Executing a shell may cause crashes
+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: Ñ¡Ôñ´òÓ¡»úʧ°Ü"
+
+#, 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 "E245: Illegal char '%c' in font name \"%s\""
+msgstr "E245: ²»ÕýÈ·µÄ×Ö·û '%c' ³öÏÖÔÚ×ÖÌåÃû³Æ \"%s\" ÄÚ"
+
+msgid "Vim: Double signal, exiting\n"
+msgstr "Vim: Ë«ÖØÐźţ¬Í˳öÖÐ\n"
+
+#, c-format
+msgid "Vim: Caught deadly signal %s\n"
+msgstr "Vim: À¹½Øµ½ÖÂÃüÐźÅ(deadly signal) %s\n"
+
+#, c-format
+msgid "Vim: Caught deadly signal\n"
+msgstr "Vim: À¹½Øµ½ÖÂÃüÐźÅ(deadly signal)\n"
+
+#, c-format
+msgid "Opening the X display took %ld msec"
+msgstr "´ò¿ª X display ÓÃʱ %ld Ãë"
+
+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 "
+msgstr ""
+"\n"
+"ÎÞ·¨Ö´ÐÐ shell"
+
+msgid ""
+"\n"
+"Cannot execute shell sh\n"
+msgstr ""
+"\n"
+"ÎÞ·¨Ö´ÐÐ shell sh\n"
+
+msgid ""
+"\n"
+"shell returned "
+msgstr ""
+"\n"
+"Shell ÒÑ·µ»Ø"
+
+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 µÄÁ¬½Ó"
+
+# do not translate
+#, c-format
+msgid "dlerror = \"%s\""
+msgstr "dlerror = \"%s\""
+
+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 Á¬½Ó¼àÊÓʧ°Ü"
+
+#, 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 "shell returned %d"
+msgstr "Shell ·µ»Ø %d"
+
+#, 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 ""
+"ÔÚÄãµÄ $PATH ÖÐÕÒ²»µ½ VIMRUN.EXE¡£\n"
+"ÍⲿÃüÁîÖ´ÐÐÍê±Ïºó½«²»»áÔÝÍ£¡£\n"
+"½øÒ»²½ËµÃ÷Çë¼û :help win32-vimrun"
+
+msgid "Vim Warning"
+msgstr "Vim ¾¯¸æ"
+
+#, 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: ûÓиü¶àµÄÏî"
+
+#, c-format
+msgid "(%d of %d)%s%s: "
+msgstr "(%d / %d)%s%s: "
+
+msgid " (line deleted)"
+msgstr " (ÐÐÒÑɾ³ý)"
+
+msgid "E380: At bottom of quickfix stack"
+msgstr "E380: Quickfix ¶ÑÕ»µ×¶Ë"
+
+msgid "E381: At top of quickfix stack"
+msgstr "E381: Quickfix ¶ÑÕ»¶¥¶Ë"
+
+#, c-format
+msgid "error list %d of %d; %d errors"
+msgstr "´íÎóÁбí %d / %d£»¹² %d ¸ö´íÎó"
+
+msgid "E382: Cannot write, 'buftype' option is set"
+msgstr "E382: ÎÞ·¨Ð´È룬ÒÑÉ趨ѡÏî 'buftype'"
+
+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%%[] ÖÐÓÐÎÞЧµÄÏî"
+
+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 "E53: Unmatched %s%%("
+msgstr "E53: ²»Æ¥ÅäµÄ %s%%("
+
+#, c-format
+msgid "E54: Unmatched %s("
+msgstr "E54: ²»Æ¥ÅäµÄ %s("
+
+#, c-format
+msgid "E55: Unmatched %s)"
+msgstr "E55: ²»Æ¥ÅäµÄ %s)"
+
+#, 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 Ç°ÃæÎÞÄÚÈÝ"
+
+msgid "E65: Illegal back reference"
+msgstr "E65: ÎÞЧµÄ»ØÒý"
+
+msgid "E66: \\z( not allowed here"
+msgstr "E66: ´Ë´¦²»ÔÊÐí \\z("
+
+msgid "E67: \\z1 et al. not allowed here"
+msgstr "E67: ´Ë´¦²»ÔÊÐí \\z1 µÈ"
+
+msgid "E68: Invalid character after \\z"
+msgstr "E68: \\z ºóÃæÓÐÎÞЧµÄ×Ö·û"
+
+#, c-format
+msgid "E69: Missing ] after %s%%["
+msgstr "E69: %s%%[ ºóȱÉÙ ]"
+
+#, c-format
+msgid "E70: Empty %s%%[]"
+msgstr "E70: ¿ÕµÄ %s%%[]"
+
+#, 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 "E769: Missing ] after %s["
+msgstr "E769: %s[ ºóȱÉÙ ]"
+
+#, c-format
+msgid "E554: Syntax error in %s{...}"
+msgstr "E554: %s{...} ÖÐÓï·¨´íÎó"
+
+msgid "External submatches:\n"
+msgstr "Íⲿ·ûºÏ:\n"
+
+msgid " VREPLACE"
+msgstr " V-Ìæ»»"
+
+msgid " REPLACE"
+msgstr " Ìæ»»"
+
+msgid " REVERSE"
+msgstr " ·´Ïò"
+
+msgid " INSERT"
+msgstr " ²åÈë"
+
+msgid " (insert)"
+msgstr " (²åÈë)"
+
+msgid " (replace)"
+msgstr " (Ìæ»»)"
+
+msgid " (vreplace)"
+msgstr " (V-Ìæ»»)"
+
+msgid " Hebrew"
+msgstr " Hebrew"
+
+msgid " Arabic"
+msgstr " Arabic"
+
+msgid " (lang)"
+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 " (°üÀ¨ÉÏ´ÎÁгö·ûºÏÏî)"
+
+#. cursor at status line
+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: ÕÒ²»µ½ pattern"
+
+msgid "E759: Format error in spell file"
+msgstr "E759: ƴдÎļþ¸ñʽ´íÎó"
+
+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 "ѹËõµ¥´ÊÊ÷¡­¡­"
+
+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\" or \"%s.ascii.spl\""
+
+#, 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 "Warning: region %s not supported"
+msgstr "¾¯¸æ: ÇøÓò %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 "%s µÚ %d ÐУ¬FLAG µÄÖµÎÞЧ: %s"
+
+#, c-format
+msgid "FLAG after using flags in %s line %d: %s"
+msgstr "%s µÚ %d ÐУ¬ÔÚʹÓñêÖ¾ºó³öÏÖ FLAG: %s"
+
+#, c-format
+#~ msgid ""
+#~ "Defining COMPOUNDFORBIDFLAG after PFX item may give wrong results in %s line "
+#~ "%d"
+#~ msgstr ""
+
+#, c-format
+#~ msgid ""
+#~ "Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in %s line "
+#~ "%d"
+#~ msgstr ""
+
+#, c-format
+msgid "Wrong COMPOUNDWORDMAX value in %s line %d: %s"
+msgstr "%s µÚ %d ÐУ¬´íÎóµÄ COMPOUNDWORDMAX Öµ: %s"
+
+#, c-format
+msgid "Wrong COMPOUNDMIN value in %s line %d: %s"
+msgstr "%s µÚ %d ÐУ¬´íÎóµÄ COMPOUNDMIN Öµ: %s"
+
+#, c-format
+msgid "Wrong COMPOUNDSYLMAX value in %s line %d: %s"
+msgstr "%s µÚ %d ÐУ¬´íÎóµÄ COMPOUNDSYLMAX Öµ: %s"
+
+#, c-format
+msgid "Wrong CHECKCOMPOUNDPATTERN value in %s line %d: %s"
+msgstr "%s µÚ %d ÐУ¬´íÎóµÄ CHECKCOMPOUNDPATTERN Öµ: %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 ""
+"%s µÚ %d ÐУ¬¸½¼ÓÏî±» BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST ʹ"
+"ÓÃ: %s"
+
+#, c-format
+msgid "Expected Y or N in %s line %d: %s"
+msgstr "%s µÚ %d ÐУ¬´Ë´¦ÐèÒª Y »ò N: %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 "%s µÚ %d ÐУ¬´Ë´¦ÐèÒª REP(SAL) ¼ÆÊý"
+
+#, c-format
+msgid "Expected MAP count in %s line %d"
+msgstr "%s µÚ %d ÐУ¬´Ë´¦ÐèÒª MAP ¼ÆÊý"
+
+#, c-format
+msgid "Duplicate character in MAP in %s line %d"
+msgstr "%s µÚ %d ÐУ¬MAP ÖдæÔÚÖØ¸´µÄ×Ö·û"
+
+#, 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 "%s ÖÐȱÉÙ FOL/LOW/UPP ÐÐ"
+
+msgid "COMPOUNDSYLMAX used without SYLLABLE"
+msgstr "ÔÚûÓÐ SYLLABLE µÄÇé¿öÏÂʹÓÃÁË COMPOUNDSYLMAX"
+
+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 "%s ÖÐȱÉÙ SOFO%s ÐÐ"
+
+#, c-format
+msgid "Both SAL and SOFO lines in %s"
+msgstr "%s ͬʱ³öÏÖ SQL ºÍ SOFO ÐÐ"
+
+#, 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 %6d - %s"
+msgstr "µÚ %6d ÐУ¬µÚ %6d ¸öµ¥´Ê - %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 "ºöÂÔÁ˺¬ÓÐ·Ç ASCII ×Ö·ûµÄ %d ¸öµ¥´Ê£¬ÔÚ %s ÖÐ"
+
+#, c-format
+msgid "Reading word file %s ..."
+msgstr "¶ÁÈ¡µ¥´ÊÎļþ %s ¡­¡­"
+
+#, c-format
+#~ msgid "Duplicate /encoding= line ignored in %s line %d: %s"
+#~ msgstr ""
+
+#, c-format
+msgid "/encoding= line after word ignored in %s line %d: %s"
+msgstr "%s µÚ %d ÐУ¬µ¥´ÊºóµÄ /encoding= ÐÐÒѱ»ºöÂÔ: %s"
+
+#, c-format
+msgid "Duplicate /regions= line ignored in %s line %d: %s"
+msgstr "%s µÚ %d ÐУ¬Öظ´µÄ /regions= ÐÐÒѱ»ºöÂÔ: %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 "ºöÂÔÁ˺¬ÓÐ·Ç ASCII ×Ö·ûµÄ %d ¸öµ¥´Ê"
+
+#, c-format
+msgid "Compressed %d of %d nodes; %d (%d%%) remaining"
+msgstr "ѹËõÁË %d/%d ¸ö½Úµã£»Ê£Óà %d (%d%%)"
+
+msgid "Reading back spell file..."
+msgstr "¶ÁȡƴдÎļþ¡­¡­"
+
+#.
+#. * Go through the trie of good words, soundfold each word and add it to
+#. * the soundfold trie.
+#.
+msgid "Performing soundfolding..."
+msgstr "ÕýÔÚ soundfolding¡­¡­"
+
+#, c-format
+msgid "Number of words after soundfolding: %ld"
+msgstr "soundfolding ºóµÄµ¥´ÊÊý: %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: Êä³öÎļþÃû²»Äܺ¬ÓÐÇøÓòÃû"
+
+msgid "E754: Only up to 8 regions supported"
+msgstr "E754: ×î¶àÖ»Ö§³Ö 8 ¸öÇøÓò"
+
+#, c-format
+msgid "E755: Invalid region in %s"
+msgstr "E755: %s ³öÏÖÎÞЧµÄ·¶Î§"
+
+msgid "Warning: both compounding and NOBREAK specified"
+msgstr "¾¯¸æ: ͬʱָ¶¨ÁË compounding ºÍ 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 removed from %s"
+msgstr "´Ó %s ÖÐɾ³ýÁ˵¥´Ê"
+
+#, c-format
+msgid "Word added to %s"
+msgstr "Ïò %s ÖÐÌí¼ÓÁ˵¥´Ê"
+
+msgid "E763: Word characters differ between spell files"
+msgstr "E763: ƴдÎļþÖ®¼äµÄ×Ö·û²»Ïàͬ"
+
+msgid "Sorry, no suggestions"
+msgstr "±§Ç¸£¬Ã»Óн¨Òé"
+
+#, c-format
+msgid "Sorry, only %ld suggestions"
+msgstr "±§Ç¸£¬Ö»ÓÐ %ld Ìõ½¨Òé"
+
+#. avoid more prompt
+#, 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"
+
+#, 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 ""
+
+#, c-format
+#~ msgid "E780: .sug file is for newer version of Vim: %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E781: .sug file doesn't match .spl file: %s"
+#~ msgstr ""
+
+#, fuzzy, c-format
+#~ msgid "E782: error while reading .sug file: %s"
+#~ msgstr "E47: ¶ÁÈ¡´íÎóÎļþʧ°Ü"
+
+#. This should have been checked when generating the .spl
+#. * file.
+#~ msgid "E783: duplicate char in MAP entry"
+#~ msgstr ""
+
+#, c-format
+msgid "E390: Illegal argument: %s"
+msgstr "E390: ÎÞЧµÄ²ÎÊý: %s"
+
+#, c-format
+msgid "E391: No such syntax cluster: %s"
+msgstr "E391: ÎÞ´ËÓï·¨ cluster: \"%s\""
+
+msgid "No Syntax items defined for this buffer"
+msgstr "Õâ¸ö»º³åÇøÃ»Óж¨ÒåÈκÎÓï·¨Ïî"
+
+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"
+"--- Ó﷨ͬ²½ÏîÄ¿ (Syntax sync items) ---"
+
+msgid ""
+"\n"
+"syncing on items"
+msgstr ""
+"\n"
+"ͬ²½ÖÐ:"
+
+msgid ""
+"\n"
+"--- Syntax items ---"
+msgstr ""
+"\n"
+"--- Óï·¨ÏîÄ¿ ---"
+
+#, c-format
+msgid "E392: No such syntax cluster: %s"
+msgstr "E392: ÎÞ´ËÓï·¨ cluster: \"%s\""
+
+msgid "minimal "
+msgstr "×îС"
+
+msgid "maximal "
+msgstr "×î´ó"
+
+#, fuzzy
+#~ msgid "; match "
+#~ msgstr "Æ¥Åä %d"
+
+#, fuzzy
+#~ msgid " line breaks"
+#~ msgstr "ÉÙÓÚÒ»ÐÐ"
+
+msgid "E395: contains argument not accepted here"
+msgstr "E395: ʹÓÃÁ˲»ÕýÈ·µÄ²ÎÊý"
+
+msgid "E396: containedin argument not accepted here"
+msgstr "E396: ʹÓÃÁ˲»ÕýÈ·µÄ²ÎÊý"
+
+msgid "E393: group[t]here not accepted here"
+msgstr "E393: ʹÓÃÁ˲»ÕýÈ·µÄ²ÎÊý"
+
+#, c-format
+msgid "E394: Didn't find region item for %s"
+msgstr "E394: ÕÒ²»µ½ %s µÄ region item"
+
+msgid "E397: Filename required"
+msgstr "E397: ÐèÒªÎļþÃû³Æ"
+
+#, c-format
+msgid "E747: Missing ']': %s"
+msgstr "E747: ȱÉÙ ']': %s"
+
+#, c-format
+msgid "E398: Missing '=': %s"
+msgstr "E398: ȱÉÙ '=': %s"
+
+#, c-format
+msgid "E399: Not enough arguments: syntax region %s"
+msgstr "E399: syntax region %s µÄ²ÎÊýÌ«ÉÙ"
+
+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 ±ØÐëÊÇÁбíÀïµÄµÚÒ»¸ö"
+
+#, c-format
+msgid "E409: Unknown group name: %s"
+msgstr "E409: ²»ÕýÈ·µÄ×éÃû: %s"
+
+#, c-format
+msgid "E410: Invalid :syntax subcommand: %s"
+msgstr "E410: ²»ÕýÈ·µÄ :syntax ×ÓÃüÁî: %s"
+
+msgid "E679: recursive loop loading syncolor.vim"
+msgstr "E679: ¼ÓÔØ syncolor.vim ʱ³öÏÖǶÌ×Ñ­»·"
+
+#, c-format
+msgid "E411: highlight group not found: %s"
+msgstr "E411: ÕÒ²»µ½ highlight group: %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: ´íÎóµÄǰ¾°ÑÕÉ«"
+
+msgid "E420: BG color unknown"
+msgstr "E420: ´íÎóµÄ±³¾°ÑÕÉ«"
+
+#, 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 "E555: at bottom of tag stack"
+msgstr "E555: ÒÑÔÚ tag ¶ÑÕ»µ×²¿"
+
+msgid "E556: at top of tag stack"
+msgstr "E556: ÒÑÔÚ tag ¶ÑÕ»¶¥²¿"
+
+msgid "E425: Cannot go before first matching tag"
+msgstr "E425: Òѵ½µÚÒ»¸öÆ¥ÅäµÄ tag"
+
+#, c-format
+msgid "E426: tag not found: %s"
+msgstr "E426: ÕÒ²»µ½ tag: %s"
+
+msgid " # pri kind tag"
+msgstr " # pri kind tag"
+
+msgid "file\n"
+msgstr "Îļþ\n"
+
+msgid "E427: There is only one matching tag"
+msgstr "E427: Ö»ÓÐÒ»¸öÆ¥ÅäµÄ tag"
+
+msgid "E428: Cannot go beyond last matching tag"
+msgstr "E428: ¼ºµ½×îºóÒ»¸öÆ¥ÅäµÄ tag"
+
+#, c-format
+msgid "File \"%s\" does not exist"
+msgstr "Îļþ \"%s\" ²»´æÔÚ"
+
+#. Give an indication of the number of matching tags
+#, c-format
+msgid "tag %d of %d%s"
+msgstr "ÕÒµ½ tag: %d / %d%s"
+
+msgid " or more"
+msgstr " »ò¸ü¶à"
+
+msgid " Using tag with different case!"
+msgstr " ÒÔ²»Í¬´óСдÀ´Ê¹Óà tag£¡"
+
+#, c-format
+msgid "E429: File \"%s\" does not exist"
+msgstr "E429: Îļþ \"%s\" ²»´æÔÚ"
+
+#. Highlight title
+msgid ""
+"\n"
+" # TO tag FROM line in file/text"
+msgstr ""
+"\n"
+" # µ½ tag ´Ó ÐÐ ÔÚ Îļþ/Îı¾"
+
+#, c-format
+msgid "Searching tags file %s"
+msgstr "²éÕÒ tag Îļþ %s"
+
+#, c-format
+msgid "E430: Tag file path truncated for %s\n"
+msgstr "E430: Tag Îļþ·¾¶±»½Ø¶ÏΪ %s\n"
+
+#, c-format
+msgid "E431: Format error in tags file \"%s\""
+msgstr "E431: Tag Îļþ \"%s\" ¸ñʽ´íÎó"
+
+#, c-format
+msgid "Before byte %ld"
+msgstr "ÔÚµÚ %ld ×Ö½Ú֮ǰ"
+
+#, c-format
+msgid "E432: Tags file not sorted: %s"
+msgstr "E432: Tag ÎļþδÅÅÐò: %s"
+
+#. never opened any tags file
+msgid "E433: No tags file"
+msgstr "E433: ûÓÐ tag Îļþ"
+
+msgid "E434: Can't find tag pattern"
+msgstr "E434: ÕÒ²»µ½ tag ģʽ"
+
+msgid "E435: Couldn't find tag, just guessing!"
+msgstr "E435: ÕÒ²»µ½ tag£¬ÊÔ×Ų£¡"
+
+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: termcap ÖÐûÓÐ \"%s\" Ïî"
+
+msgid "E437: terminal capability \"cm\" required"
+msgstr "E437: ÖÕ¶ËÐèÒªÄÜÁ¦ \"cm\""
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Terminal keys ---"
+msgstr ""
+"\n"
+"--- Öն˰´¼ü ---"
+
+msgid "new shell started\n"
+msgstr "Æô¶¯Ð shell\n"
+
+msgid "Vim: Error reading input, exiting...\n"
+msgstr "Vim: ¶Á´íÎó£¬Í˳öÖÐ...\n"
+
+#. must display the prompt
+msgid "No undo possible; continue anyway"
+msgstr "ÎÞ·¨³·Ïú£»Çë¼ÌÐø"
+
+msgid "Already at oldest change"
+msgstr "ÒÑλÓÚ×î¾ÉµÄ¸Ä±ä"
+
+msgid "Already at newest change"
+msgstr "ÒÑλÓÚ×îеĸıä"
+
+#, c-format
+msgid "Undo number %ld not found"
+msgstr "ÕÒ²»µ½³·ÏúºÅ %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 "before"
+
+msgid "after"
+msgstr "after"
+
+msgid "Nothing to undo"
+msgstr "Î޿ɳ·Ïú"
+
+msgid "number changes time"
+msgstr " ±àºÅ ¸Ä±ä ʱ¼ä"
+
+msgid "E439: undo list corrupt"
+msgstr "E439: ³·ÏúÁбíËð»µ"
+
+msgid "E440: undo line missing"
+msgstr "E440: ÕÒ²»µ½Òª³·ÏúµÄÐÐ"
+
+#. Only MS VC 4.1 and earlier can do Win32s
+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"
+"Included 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 "ÎÞͼÐνçÃæ¡£"
+
+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 " Features included (+) or not (-):\n"
+msgstr " ¿ÉʹÓÃ(+)Óë²»¿ÉʹÓÃ(-)µÄ¹¦ÄÜ:\n"
+
+msgid " system vimrc file: \""
+msgstr " ϵͳ vimrc Îļþ: \""
+
+msgid " user vimrc file: \""
+msgstr " Óû§ vimrc Îļþ: \""
+
+msgid " 2nd user vimrc file: \""
+msgstr " µÚ¶þÓû§ vimrc Îļþ: \""
+
+msgid " 3rd user vimrc file: \""
+msgstr " µÚÈýÓû§ vimrc Îļþ: \""
+
+msgid " user exrc file: \""
+msgstr " Óû§ exrc Îļþ: \""
+
+msgid " 2nd user exrc file: \""
+msgstr " µÚ¶þÓû§ exrc Îļþ: \""
+
+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 " 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 " µ÷ÊÔ°æ±¾"
+
+msgid "VIM - Vi IMproved"
+msgstr "VIM - Vi IMproved"
+
+msgid "version "
+msgstr "°æ±¾ "
+
+msgid "by Bram Moolenaar et al."
+msgstr "ά»¤ÈË Bram Moolenaar µÈ"
+
+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> ²é¿´ÔÚÏß°ïÖú "
+
+msgid "type :help version7<Enter> for version info"
+msgstr "ÊäÈë :help version7<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 "²Ëµ¥ 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"
+
+#~ msgid "menu Edit->Global Settings->Toggle Vi Compatible"
+#~ msgstr ""
+
+#, fuzzy
+#~ msgid " for Vim defaults "
+#~ msgstr " # pid Êý¾Ý¿âÃû³Æ prepend path\n"
+
+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 "²Ëµ¥ Help->Sponsor/Register ²é¿´ËµÃ÷ "
+
+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 "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 "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 "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 ""
+
+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)"
+
+#. Now concatenate
+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 "--»º³åÇøÎÞÄÚÈÝ--"
+
+#.
+#. * 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: ÃüÁî±»ÖÐÖ¹"
+
+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 »ò tag ²éÕÒÖв»ÔÊÐí´ËÃüÁî"
+
+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: ÄÚ²¿´íÎó"
+
+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 "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()\" ʧ°Ü"
+
+#, 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: ÎÞ·¨Ê¹ÓÃͼÐνçÃæ: ±àÒëʱûÓÐÆôÓÃ"
+
+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"
+
+#, 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 "E37: No write since last change (add ! to override)"
+msgstr "E37: ÒÑÐ޸ĵ«ÉÐδ±£´æ (¿ÉÓà ! Ç¿ÖÆÖ´ÐÐ)"
+
+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: ÎÞ·¨´ò¿ª display"
+
+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: ûÓÐ location Áбí"
+
+msgid "E43: Damaged match string"
+msgstr "E43: ÒÑËð»µµÄÆ¥Åä×Ö·û´®"
+
+msgid "E44: Corrupted regexp program"
+msgstr "E44: ÒÑË𻵵ÄÕýÔò±í´ïʽ³ÌÐò"
+
+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 "E46: Cannot set variable in the sandbox: \"%s\""
+msgstr "E46: ²»ÄÜÔÚ sandbox ÖÐÉ趨±äÁ¿: \"%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: ÎÞ·¨¶ÁÈ¡ sign Êý¾Ý£¡"
+
+msgid "E72: Close error on swap file"
+msgstr "E72: ½»»»Îļþ¹Ø±Õ´íÎó"
+
+msgid "E73: tag stack empty"
+msgstr "E73: tag ¶ÑջΪ¿Õ"
+
+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 "Zero count"
+msgstr "¼ÆÊýΪÁã"
+
+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 ""
+
+msgid "E744: NetBeans does not allow changes in read-only files"
+msgstr "E744: NetBeans ²»ÔÊÐí¸Ä±äÖ»¶ÁÎļþ"
+
+#, c-format
+msgid "E685: Internal error: %s"
+msgstr "E685: ÄÚ²¿´íÎó: %s"
+
+msgid "E363: pattern uses more memory than 'maxmempattern'"
+msgstr "E363: ±í´ïʽµÄÄÚ´æÊ¹Óó¬³ö 'maxmempattern'"
+
+msgid "E749: empty buffer"
+msgstr "E749: ¿ÕµÄ»º³åÇø"
+
+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 "search hit TOP, continuing at BOTTOM"
+msgstr "ÒѲéÕÒµ½Îļþ¿ªÍ·£¬ÔÙ´Ó½áβ¼ÌÐø²éÕÒ"
+
+msgid "search hit BOTTOM, continuing at TOP"
+msgstr "ÒѲéÕÒµ½Îļþ½á⣬ÔÙ´Ó¿ªÍ·¼ÌÐø²éÕÒ"
+
+#~ 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 "E119: Not enough arguments for function: %s"
+#~ msgstr "E119: º¯Êý %s µÄ²ÎÊýÌ«ÉÙ"
+
+#~ msgid "E120: Using <SID> not in a script context: %s"
+#~ msgstr "E120: <SID> ²»ÄÜÔÚ script ÉÏÏÂÎÄÍâʹÓÃ: %s"
+
+#~ msgid "E123: Undefined function: %s"
+#~ msgstr "E123: º¯Êý %s ÉÐ䶨Òå"
+
+#~ msgid "E127: Cannot redefine function %s: It is in use"
+#~ msgstr "E127: º¯Êý %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/po/zh_TW.UTF-8.po b/src/po/zh_TW.UTF-8.po
new file mode 100644
index 0000000000..d7b6501a17
--- /dev/null
+++ b/src/po/zh_TW.UTF-8.po
@@ -0,0 +1,5282 @@
+# 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
+# MAINTAINER: Debian VIM Maintainers <pkg-vim-maintainers@lists.alioth.debian.org>
+#
+# Last update: $LastChangedDate: 2006-04-16 22:06:40 -0400 (dom, 16 apr 2006) $
+#
+# XXX This file is in need of a new maintainer, Debian VIM Maintainers maintain
+# it only because patches have been submitted for it by Debian users and the
+# former maintainer was MIA (Missing In Action), taking over its
+# maintenance was thus the only way to include those patches.
+# If you care about this file, and have time to maintain it please do so!
+#
+# 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 "%ld fewer lines" "on %ld lines"
+# If you don't put more (at least 2) spaces after %ld
+# 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 termencoding=utf-8
+# 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: 2005-01-27 19:00+0800\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"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8-bit\n"
+
+msgid "E82: Cannot allocate any buffer, exiting..."
+msgstr "E82: 無法é…置任何緩è¡å€ï¼Œé›¢é–‹ç¨‹å¼..."
+
+msgid "E83: Cannot allocate buffer, using other one..."
+msgstr "E83: 無法é…置緩è¡å€ï¼Œä½¿ç”¨å¦ä¸€å€‹ç·©è¡å€...."
+
+#, c-format
+msgid "E515: No buffers were unloaded"
+msgstr "E515: 沒有釋放任何緩è¡å€"
+
+#, c-format
+msgid "E516: No buffers were deleted"
+msgstr "E516: 沒有刪除任何緩è¡å€"
+
+#, c-format
+msgid "E517: No buffers were wiped out"
+msgstr "E517: 沒有清除任何緩è¡å€"
+
+msgid "1 buffer unloaded"
+msgstr "已釋放一個緩è¡å€"
+
+#, c-format
+msgid "%d buffers unloaded"
+msgstr "已釋放 %d 個緩è¡å€"
+
+msgid "1 buffer deleted"
+msgstr "已刪除一個緩è¡å€"
+
+#, c-format
+msgid "%d buffers deleted"
+msgstr "已刪除 %d 個緩è¡å€"
+
+msgid "1 buffer wiped out"
+msgstr "已刪除一個緩è¡å€"
+
+#, c-format
+msgid "%d buffers wiped out"
+msgstr "已刪除 %d 個緩è¡å€"
+
+msgid "E84: No modified buffer found"
+msgstr "E84: 沒有修改éŽçš„ç·©è¡å€"
+
+#. back where we started, didn't find anything.
+msgid "E85: There is no listed buffer"
+msgstr "E85: 沒有列出的緩è¡å€"
+
+#, c-format
+msgid "E86: Buffer %ld does not exist"
+msgstr "E86: ç·©è¡å€ %ld ä¸å­˜åœ¨"
+
+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 "E90: Cannot unload last buffer"
+msgstr "E90: 無法釋放最後一個緩è¡å€"
+
+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 "[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 file]"
+msgstr "[未命å]"
+
+#. must be a help buffer
+msgid "help"
+msgstr "[輔助說明]"
+
+msgid "[help]"
+msgstr "[輔助說明]"
+
+msgid "[Preview]"
+msgstr "[é è¦½]"
+
+msgid "All"
+msgstr "全部"
+
+msgid "Bot"
+msgstr "底端"
+
+msgid "Top"
+msgstr "頂端"
+
+#, c-format
+msgid ""
+"\n"
+"# Buffer list:\n"
+msgstr ""
+"\n"
+"# ç·©è¡å€åˆ—表:\n"
+
+msgid "[Error List]"
+msgstr "[錯誤列表]"
+
+msgid "[No File]"
+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 id=%d å稱=%s"
+
+#, c-format
+msgid "E96: Can not diff more than %ld buffers"
+msgstr "E96: 無法比較(diff) %ld個以上的緩è¡å€"
+
+msgid "E97: Cannot create diffs"
+msgstr "E97: ä¸èƒ½å»ºç«‹ "
+
+msgid "Patch file"
+msgstr "Patch 檔案"
+
+msgid "E98: Cannot read diff output"
+msgstr "E98: ç„¡æ³•è®€å– diff 的輸出"
+
+msgid "E99: Current buffer is not in diff mode"
+msgstr "E99: ç›®å‰çš„ç·©è¡å€ä¸æ˜¯åœ¨ 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 "E104: Escape not allowed in digraph"
+msgstr "E104: 複åˆå­—å…ƒ(digraph)中ä¸èƒ½ä½¿ç”¨ Escape"
+
+msgid "E544: Keymap file not found"
+msgstr "E544: 找ä¸åˆ° keymap 檔"
+
+msgid "E105: Using :loadkeymap not in a sourced file"
+msgstr "E105: 使用 :loadkeymap "
+
+msgid " Keyword completion (^N^P)"
+msgstr " é—œéµå­—è‡ªå‹•å®Œæˆ (^N^P)"
+
+#. ctrl_x_mode == 0, ^P/^N compl.
+msgid " ^X mode (^E^Y^L^]^F^I^K^D^V^N^P)"
+msgstr " ^X æ¨¡å¼ (^E^Y^L^]^F^I^K^D^N^P)"
+
+#. Scroll has it's own msgs, in it's place there is the msg for local
+#. * ctrl_x_mode = 0 (eg continue_status & CONT_LOCAL) -- Acevedo
+msgid " Keyword Local completion (^N^P)"
+msgstr " å€åŸŸé—œéµå­—è‡ªå‹•å®Œæˆ (^N^P)"
+
+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 " Thesaurus è‡ªå‹•å®Œæˆ (^T^N^P)"
+
+msgid " Command-line completion (^V^N^P)"
+msgstr " å‘½ä»¤åˆ—è‡ªå‹•å®Œæˆ (^V^N^P)"
+
+msgid "Hit end of paragraph"
+msgstr "已到段è½çµå°¾"
+
+msgid "'thesaurus' option is empty"
+msgstr "é¸é … 'thesaurus' 未設定"
+
+msgid "'dictionary' option is empty"
+msgstr "é¸é … 'dictionary' 未設定"
+
+#, c-format
+msgid "Scanning dictionary: %s"
+msgstr "掃瞄字典: %s"
+
+msgid " (insert) Scroll (^E/^Y)"
+msgstr " (æ’å…¥) Scroll (^E/^Y)"
+
+msgid " (replace) Scroll (^E/^Y)"
+msgstr " (å–代) Scroll (^E/^Y)"
+
+#, c-format
+msgid "Scanning: %s"
+msgstr "掃瞄中: %s"
+
+#, c-format
+msgid "Scanning tags."
+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.
+#.
+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"
+
+#. Skip further arguments but do continue to
+#. * search for a trailing command.
+#, c-format
+msgid "E106: Unknown variable: \"%s\""
+msgstr "E106: 未定義的變數: \"%s\""
+
+#, c-format
+msgid "E107: Missing parentheses: %s"
+msgstr "E107: ç¼ºå°‘å°æ‡‰çš„æ‹¬è™Ÿ: %s"
+
+#, c-format
+msgid "E108: No such variable: \"%s\""
+msgstr "E108: 無此變數: \"%s\""
+
+msgid "E109: Missing ':' after '?'"
+msgstr "E109: '?' 後缺少 ':'"
+
+msgid "E110: Missing ')'"
+msgstr "E110: ç¼ºå°‘å°æ‡‰çš„ \")\""
+
+msgid "E111: Missing ']'"
+msgstr "E111: ç¼ºå°‘å°æ‡‰çš„ \"]\""
+
+#, 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"
+
+#, c-format
+msgid "E116: Invalid arguments for function %s"
+msgstr "E116: å‡½å¼ %s çš„å¼•æ•¸ä¸æ­£ç¢º"
+
+#, c-format
+msgid "E117: Unknown function: %s"
+msgstr "E117: 未定義的函å¼: %s"
+
+#, c-format
+msgid "E118: Too many arguments for function: %s"
+msgstr "E118: å‡½å¼ %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> ä¸èƒ½åœ¨ script 本文外使用: %s"
+
+#.
+#. * 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 "確定(&O)"
+
+#, c-format
+msgid "+-%s%3ld lines: "
+msgstr "+-%s%3ld 行: "
+
+msgid ""
+"&OK\n"
+"&Cancel"
+msgstr ""
+"確定(&O)\n"
+"å–æ¶ˆ(&C)"
+
+msgid "called inputrestore() more often than inputsave()"
+msgstr "å‘¼å« inputrestore() 的次數比 inputsave() 還多"
+
+msgid "E655: Too many symbolic links (cycle?)"
+msgstr "E655: 太多層的符號éˆçµ(symlink) (循環?)"
+
+msgid "E240: No connection to Vim server"
+msgstr "E240: 沒有與 Vim Server 建立連線"
+
+msgid "E277: Unable to read a server reply"
+msgstr "E277: 無法讀å–伺æœå™¨çš„回應"
+
+msgid "E258: Unable to send to client"
+msgstr "E258: 無法傳é€åˆ° client"
+
+#, c-format
+msgid "E241: Unable to send to %s"
+msgstr "E241: 無法傳é€åˆ° %s"
+
+msgid "(Invalid)"
+msgstr "(䏿­£ç¢º)"
+
+#, c-format
+msgid "E121: Undefined variable: %s"
+msgstr "E121: 變數 %s 尚未定義"
+
+#, c-format
+msgid "E461: Illegal variable name: %s"
+msgstr "E461: ä¸åˆæ³•的變數å稱: %s"
+
+#, c-format
+msgid "E122: Function %s already exists, add ! to replace it"
+msgstr "E122: å‡½å¼ %s 已經存在, 請使用 ! 強制å–代"
+
+#, c-format
+msgid "E123: Undefined function: %s"
+msgstr "E123: å‡½å¼ %s 尚未定義"
+
+#, c-format
+msgid "E124: Missing '(': %s"
+msgstr "E124: 缺少 \"(\": %s"
+
+#, c-format
+msgid "E125: Illegal argument: %s"
+msgstr "E125: åƒæ•¸ä¸æ­£ç¢º: %s"
+
+msgid "E126: Missing :endfunction"
+msgstr "E126: 缺少 :endfunction"
+
+#, c-format
+msgid "E127: Cannot redefine function %s: It is in use"
+msgstr "E127: å‡½å¼ %s æ­£åœ¨ä½¿ç”¨ä¸­ï¼Œç„¡æ³•é‡æ–°å®šç¾©"
+
+msgid "E129: Function name required"
+msgstr "E129: 需è¦å‡½å¼å稱"
+
+#, c-format
+msgid "E128: Function name must start with a capital: %s"
+msgstr "E128: 函å¼å稱第一個字æ¯å¿…須大寫: %s"
+
+#, c-format
+msgid "E130: Undefined function: %s"
+msgstr "E130: å‡½å¼ %s 尚未定義"
+
+#, c-format
+msgid "E131: Cannot delete function %s: It is in use"
+msgstr "E131: å‡½å¼ %s 正在使用中,無法刪除"
+
+msgid "E132: Function call depth is higher than 'maxfuncdepth'"
+msgstr "E132: 函å¼éžè¿´å‘¼å«å±¤æ•¸è¶…éŽ 'maxfuncdepth'"
+
+#. always scroll up, don't overwrite
+#, 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\""
+
+#. always scroll up, don't overwrite
+#, c-format
+msgid "continuing in %s"
+msgstr "繼續: %s"
+
+msgid "E133: :return not inside a function"
+msgstr "E133: :return 必須在函å¼è£¡ä½¿ç”¨"
+
+#, c-format
+msgid ""
+"\n"
+"# global variables:\n"
+msgstr ""
+"\n"
+"# 全域變數:\n"
+
+#, c-format
+msgid "<%s>%s%s %d, Hex %02x, Octal %03o"
+msgstr "<%s>%s%s %d, åå…­é€²ä½ %02x, å…«é€²ä½ %03o"
+
+#, 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: *Filter* Autocommand ä¸å¯ä»¥æ›´æ”¹ç·©è¡å€çš„內容"
+
+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 " FAILED"
+msgstr " 失敗"
+
+#, c-format
+msgid "E137: Viminfo file is not writable: %s"
+msgstr "E137: Viminfo 檔案無法寫入: %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\" 中"
+
+#. Write the info:
+#, c-format
+msgid "# This viminfo file was generated by Vim %s.\n"
+msgstr "# 本 viminfo 檔案是由 Vim %s 所產生.\n"
+
+#, c-format
+msgid ""
+"# You may edit it if you're careful!\n"
+"\n"
+msgstr ""
+"# 如果想è¦è‡ªè¡Œä¿®æ”¹è«‹ç‰¹åˆ¥å°å¿ƒï¼\n"
+"\n"
+
+#, c-format
+msgid "# Value of 'encoding' when this file was written\n"
+msgstr "# 'encoding' 在此檔建立時的值\n"
+
+msgid "Illegal starting char"
+msgstr "無效的起始字元"
+
+msgid "Save As"
+msgstr "å¦å­˜æ–°æª”"
+
+#. Overwriting a file that is loaded in another buffer is not a
+#. * good idea.
+msgid "E139: File is loaded in another buffer"
+msgstr "E139: 您在å¦ä¸€å€‹ç·©è¡å€ä¹Ÿè¼‰å…¥äº†é€™å€‹æª”案"
+
+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 "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 ""
+"\"%.*s\" 已設定 'readonly' é¸é ….\n"
+"確定è¦è¦†å¯«å—Žï¼Ÿ"
+
+msgid "Edit File"
+msgstr "編輯檔案"
+
+#, c-format
+msgid "E143: Autocommands unexpectedly deleted new buffer %s"
+msgstr "E143: Autocommands æ„外地刪除新緩è¡å€ %s"
+
+msgid "E144: non-numeric argument to :z"
+msgstr "E144: :z 䏿ޥå—éžæ•¸å­—çš„åƒæ•¸"
+
+msgid "E145: Shell commands not allowed in rvim"
+msgstr "E145: rvim ä¸­ç¦æ­¢ä½¿ç”¨ shell 命令"
+
+msgid "E146: Regular expressions can't be delimited by letters"
+msgstr "E146: Regular expression 無法用字æ¯åˆ†éš” (?)"
+
+#, c-format
+msgid "replace with %s (y/n/a/q/l/^E/^Y)?"
+msgstr "å–代為 %s (y/n/a/q/^E/^Y)?"
+
+msgid "(Interrupted) "
+msgstr "(已中斷) "
+
+msgid "1 substitution"
+msgstr "å–代一組 "
+
+#, c-format
+msgid "%ld substitutions"
+msgstr "å–代 %ld 組 "
+
+msgid " on 1 line"
+msgstr ",範åœï¼šä¸€è¡Œ "
+
+#, c-format
+msgid " on %ld lines"
+msgstr ",範åœï¼š %ld 行 "
+
+msgid "E147: Cannot do :global recursive"
+msgstr "E147: :global 無法éžè¿´åŸ·è¡Œ "
+
+msgid "E148: Regular expression missing from global"
+msgstr "E148: æ²’æœ‰ä½¿ç”¨éŽ Regular expression (?)"
+
+#, c-format
+msgid "Pattern found in every line: %s"
+msgstr "æ¯ä¸€è¡Œéƒ½æ‰¾ä¸åˆ°: %s"
+
+#, c-format
+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 "E150: Not a directory: %s"
+msgstr "E150: %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"
+msgstr "E154: 標籤(tag) \"%s\" 在檔案 %s 裡é‡è¤‡å‡ºç¾å¤šæ¬¡"
+
+#, c-format
+msgid "E160: Unknown sign command: %s"
+msgstr "E160: 未定義的 sign command: %s"
+
+msgid "E156: Missing sign name"
+msgstr "E156: 缺少 sign å稱"
+
+msgid "E612: Too many signs defined"
+msgstr "E612: 已定義太多 signs"
+
+#, c-format
+msgid "E239: Invalid sign text: %s"
+msgstr "E239: 䏿­£ç¢ºçš„ sign 文字: %s"
+
+#, c-format
+msgid "E155: Unknown sign: %s"
+msgstr "E155: 䏿­£ç¢ºçš„ sign: %s"
+
+msgid "E159: Missing sign number"
+msgstr "E159: 缺少 sign number"
+
+#, c-format
+msgid "E158: Invalid buffer name: %s"
+msgstr "E158: ç·©è¡å€å稱錯誤: %s"
+
+#, c-format
+msgid "E157: Invalid sign ID: %ld"
+msgstr "E157: Sign ID 錯誤: %ld"
+
+msgid " (NOT FOUND)"
+msgstr " (找ä¸åˆ°) "
+
+msgid " (not supported)"
+msgstr " (䏿”¯æ´) "
+
+msgid "[Deleted]"
+msgstr "[已刪除]"
+
+msgid "Entering Debug mode. Type \"cont\" to continue."
+msgstr "進入除錯模å¼. 輸入 \"cont\" 以回到正常模å¼."
+
+#, c-format
+msgid "line %ld: %s"
+msgstr "行 %ld: %s"
+
+#, c-format
+msgid "cmd: %s"
+msgstr "cmd: %s"
+
+#, 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 "Save changes to \"%.*s\"?"
+msgstr "將變動存儲至 \"%.*s\"?"
+
+msgid "Untitled"
+msgstr "未命å"
+
+#, c-format
+msgid "E162: No write since last change for buffer \"%s\""
+msgstr "E162: 已更改éŽç·©è¡å€ \"%s\" 但尚未存檔 (å¯ç”¨ ! 強制執行)"
+
+msgid "Warning: Entered other buffer unexpectedly (check autocommands)"
+msgstr "注æ„: 已切æ›åˆ°å…¶å®ƒç·©è¡å€ (請檢查 Autocommands 有無錯誤)"
+
+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 'runtimepath': \"%s\""
+msgstr "在 'runtimepath' 裡找ä¸åˆ° \"%s\""
+
+msgid "Source Vim script"
+msgstr "執行 Vim script"
+
+#, 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"
+
+msgid "W15: Warning: Wrong line separator, ^M may be missing"
+msgstr "W15: 注æ„: 錯誤的行分隔字元,å¯èƒ½æ˜¯å°‘了 ^M"
+
+msgid "E167: :scriptencoding used outside of a sourced file"
+msgstr "E167: 在執行 script 檔案外ä¸å¯ä½¿ç”¨ :scriptencoding"
+
+msgid "E168: :finish used outside of a sourced file"
+msgstr "E168: 在執行 script 檔案外ä¸å¯ä½¿ç”¨ :finish"
+
+#, 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"
+
+#, c-format
+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 è³‡æºæª” \"%s\""
+
+#, c-format
+msgid "E618: file \"%s\" is not a PostScript resource file"
+msgstr "E618: 檔案 \"%s\" 䏿˜¯ PostScript è³‡æºæª” "
+
+#, c-format
+msgid "E619: file \"%s\" is not a supported PostScript resource file"
+msgstr "E619: 䏿”¯æ´ PostScript è³‡æºæª” \"%s\""
+
+#, c-format
+msgid "E621: \"%s\" resource file has wrong version"
+msgstr "E621: \"%s\" è³‡æºæª”版本錯誤"
+
+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 è³‡æºæª” \"prolog.ps\""
+
+#, c-format
+msgid "E456: Can't find PostScript resource file \"%s.ps\""
+msgstr "E456: ç„¡æ³•è®€å– PostScript è³‡æºæª” \"%s.ps\""
+
+#, c-format
+msgid "E620: Unable to convert from multi-byte to \"%s\" encoding"
+msgstr "E620:無法轉æ›è‡³ \"%s\" 字元編碼"
+
+msgid "Sending to printer..."
+msgstr "傳é€è³‡æ–™åˆ°å°è¡¨æ©Ÿ..."
+
+msgid "E365: Failed to print PostScript file"
+msgstr "E365: ç„¡æ³•åˆ—å° PostScript 檔案"
+
+msgid "Print job sent."
+msgstr "å·²é€å‡ºåˆ—å°å·¥ä½œã€‚"
+
+#, 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 模å¼. 輸入 \"visua\" 以回到正常模å¼."
+
+#. must be at EOF
+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 "指定了å‘å‰åƒè€ƒçš„範åœï¼ŒOK to swap"
+
+msgid "E494: Use w or w>>"
+msgstr "E494: 請使用 w 或 w>>"
+
+msgid "E319: Sorry, the command is not available in this version"
+msgstr "E319: 抱歉, 本命令在此版本中沒有實作"
+
+msgid "E172: Only one file name allowed"
+msgstr "E172: åªèƒ½æœ‰ä¸€å€‹æª”"
+
+msgid "1 more file to edit. Quit anyway?"
+msgstr "還有一個檔案未編輯. 確定è¦é›¢é–‹ï¼Ÿ"
+
+#, c-format
+msgid "%d more files to edit. Quit anyway?"
+msgstr "還有 %d 個檔案未編輯. 確定è¦é›¢é–‹ï¼Ÿ"
+
+msgid "E173: 1 more file to edit"
+msgstr "E173: 還有一個檔案未編輯 "
+
+#, 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 Range 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: 指令需è¦åƒæ•¸æ‰èƒ½å®Œæˆ"
+
+#, 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: 自訂補完需è¦å‡½å¼ç‚ºåƒæ•¸"
+
+#, 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: 使用者自定指令必須以大寫字æ¯é–‹å§‹"
+
+#, c-format
+msgid "E184: No such user-defined command: %s"
+msgstr "E184: 沒有使用者自定的命令: %s"
+
+#, c-format
+msgid "E185: Cannot find color scheme %s"
+msgstr "E185: 找ä¸åˆ°é¡è‰²æ¨£å¼ %s"
+
+msgid "Greetings, Vim user!"
+msgstr "å—¨, Vim 使用者ï¼"
+
+msgid "Edit File in new window"
+msgstr "在新視窗編輯檔案"
+
+msgid "No swap file"
+msgstr "無暫存檔"
+
+msgid "Append File"
+msgstr "附加檔案"
+
+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 "Save Redirection"
+msgstr "儲存 Redirection"
+
+msgid "Save View"
+msgstr "儲存 View"
+
+msgid "Save Session"
+msgstr "儲存 Session"
+
+msgid "Save Setup"
+msgstr "儲存設定"
+
+#, c-format
+msgid "E189: \"%s\" exists (add ! to override)"
+msgstr "E189: \"%s\" 已存在 (請用 ! 強制執行)"
+
+#, c-format
+msgid "E190: Cannot open \"%s\" for writing"
+msgstr "E190: 無法以寫入模å¼é–‹å•Ÿ \"%s\""
+
+#. set mark
+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 "E194: No alternate file name to substitute for '#'"
+msgstr "E194: 沒有 '#' 坿›¿ä»£çš„æª”å"
+
+msgid "E495: no autocommand file name to substitute for \"<afile>\""
+msgstr "E495: 沒有 Autocommand 檔å以å–代 \"<afile>\""
+
+msgid "E496: no autocommand buffer number to substitute for \"<abuf>\""
+msgstr "E496: 沒有 Autocommand ç·©è¡å€å稱以å–代 \"<abuf>\""
+
+msgid "E497: no autocommand match name to substitute for \"<amatch>\""
+msgstr "E497: 沒有 Autocommand 符åˆå稱以å–代 \"<amatch>\""
+
+msgid "E498: no :source file name to substitute for \"<sfile>\""
+msgstr "E498: 沒有 :source 檔å以å–代 \"<sfile>\""
+
+#, no-c-format
+msgid "E499: Empty file name for '%' or '#', only works with \":p:h\""
+msgstr "E499: '%' 或 '#' 指å‘空檔å,åªèƒ½ç”¨æ–¼ \":p:h\""
+
+msgid "E500: Evaluates to an empty string"
+msgstr "E500: 輸入為空字串"
+
+msgid "E195: Cannot open viminfo file for reading"
+msgstr "E195: ç„¡æ³•è®€å– viminfo"
+
+msgid "E196: No digraphs in this version"
+msgstr "E196: 本版本無複åˆå­—å…ƒ(digraph)"
+
+msgid "E608: Cannot :throw exceptions with 'Vim' prefix"
+msgstr "E608: ä¸èƒ½ :throw 用 'Vim' 開頭的例外"
+
+#. always scroll up, don't overwrite
+#, 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"
+
+#. always scroll up, don't overwrite
+#, c-format
+msgid "Exception caught: %s"
+msgstr "發生例外:%s"
+
+#, c-format
+msgid "%s made pending"
+msgstr "%s é€ æˆ pending"
+
+#, 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 "錯誤"
+
+#. if (pending & CSTP_INTERRUPT)
+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 nesting too deep"
+msgstr "E585: :while å±¤æ•¸éŽæ·±"
+
+msgid "E586: :continue without :while"
+msgstr "E586: :continue ç¼ºå°‘å°æ‡‰çš„ :while"
+
+msgid "E587: :break without :while"
+msgstr "E587: :break ç¼ºå°‘å°æ‡‰çš„ :while"
+
+msgid "E601: :try nesting too deep"
+msgstr "E601: :if å±¤æ•¸éŽæ·±"
+
+msgid "E603: :catch without :try"
+msgstr "E603: :catch 沒有 :try"
+
+#. Give up for a ":catch" after ":finally" and ignore it.
+#. * Just parse.
+msgid "E604: :catch after :finally"
+msgstr "E604: :catch 在 :finally 之後"
+
+msgid "E606: :finally without :try"
+msgstr "E606: :finally 沒有 :try"
+
+#. Give up for a multiple ":finally" and ignore it.
+msgid "E607: multiple :finally"
+msgstr "E607: å¤šé‡ :finally"
+
+msgid "E602: :endtry without :try"
+msgstr "E602: :endif ç¼ºå°‘å°æ‡‰çš„ :if"
+
+msgid "E193: :endfunction not inside a function"
+msgstr "E193: :endfunction 必須在函å¼å…§éƒ¨ä½¿ç”¨"
+
+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 "E198: cmd_pchar beyond the command length"
+msgstr "E198: cmd_pchar è¶…éŽå‘½ä»¤é•·åº¦"
+
+msgid "E199: Active window or buffer deleted"
+msgstr "E199: 已刪除掉作用中的視窗或暫存å€"
+
+msgid "Illegal file name"
+msgstr "䏿­£ç¢ºçš„æª”å"
+
+msgid "is a directory"
+msgstr "是目錄"
+
+msgid "is not a file"
+msgstr "䏿˜¯æª”案"
+
+msgid "[New File]"
+msgstr "[未命å]"
+
+msgid "[Permission Denied]"
+msgstr "[權é™ä¸è¶³]"
+
+msgid "E200: *ReadPre autocommands made the file unreadable"
+msgstr "E200: *ReadPre Autocommand 使程å¼ç„¡æ³•è®€å–æ­¤æª”"
+
+msgid "E201: *ReadPre autocommands must not change current buffer"
+msgstr "E201: *Filter* Autocommand ä¸å¯ä»¥æ›´æ”¹ç·©è¡å€çš„內容"
+
+msgid "Vim: Reading from stdin...\n"
+msgstr "Vim: 從標準輸入讀å–...\n"
+
+msgid "Reading from stdin..."
+msgstr "從標準輸入讀å–..."
+
+#. Re-opening the original file failed!
+msgid "E202: Conversion made file unreadable!"
+msgstr "E202: 轉æ›éŒ¯èª¤"
+
+msgid "[fifo/socket]"
+msgstr "[fifo/socket]"
+
+msgid "[fifo]"
+msgstr "[fifo]"
+
+msgid "[socket]"
+msgstr "[socket]"
+
+msgid "[RO]"
+msgstr "[唯讀]"
+
+msgid "[CR missing]"
+msgstr "[缺少CR]'"
+
+msgid "[NL found]"
+msgstr "[找到NL]"
+
+msgid "[long lines split]"
+msgstr "[分割éŽé•·è¡Œ]"
+
+msgid "[NOT converted]"
+msgstr "[未轉æ›]"
+
+msgid "[converted]"
+msgstr "[已轉æ›]"
+
+msgid "[crypted]"
+msgstr "[已加密]"
+
+msgid "[CONVERSION ERROR]"
+msgstr "轉æ›éŒ¯èª¤"
+
+#, 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 "字元集轉æ›éŒ¯èª¤"
+
+msgid "can't read output of 'charconvert'"
+msgstr "ç„¡æ³•è®€å– 'charconvert' 的輸出"
+
+msgid "E203: Autocommands deleted or unloaded buffer to be written"
+msgstr "E203: Autocommand 刪除或釋放了è¦å¯«å…¥çš„ç·©è¡å€"
+
+msgid "E204: Autocommand changed number of lines in unexpected way"
+msgstr "E204: Autocommand æ„外地改變了行號"
+
+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 "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 "E460: The resource fork would be lost (add ! to override)"
+msgstr "E460: Resource fork 會消失 (請使用 ! 強制執行)"
+
+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 "E667: Fsync failed"
+msgstr "E667: Fsync 命令執行失敗"
+
+msgid "E512: Close failed"
+msgstr "E512: 關閉失敗"
+
+msgid "E513: write error, conversion failed"
+msgstr "E513: 無法寫入 -- 轉æ›å¤±æ•—"
+
+msgid "E514: write error (file system full?)"
+msgstr "E514: 寫入錯誤 (檔案系統已滿?)"
+
+msgid " CONVERSION ERROR"
+msgstr "轉æ›éŒ¯èª¤"
+
+msgid "[Device]"
+msgstr "[è£ç½®]"
+
+msgid "[New]"
+msgstr "[æ–°]"
+
+msgid " [a]"
+msgstr "[a]"
+
+msgid " appended"
+msgstr " 已附加"
+
+msgid " [w]"
+msgstr "[w]"
+
+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 "一個字元"
+
+#, c-format
+msgid "%ld characters"
+msgstr "%ld個字元"
+
+msgid "[noeol]"
+msgstr "[noeol]"
+
+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
+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 autocommand 刪除緩è¡å€"
+
+#, c-format
+msgid "E211: Warning: 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\" 自上次讀入後已變動, 而且編輯中的緩è¡å€ä¹Ÿæ›´å‹•了"
+
+#, c-format
+msgid "W11: Warning: File \"%s\" has changed since editing started"
+msgstr "W11: 警告: 檔案 \"%s\" 自上次讀入後已變動"
+
+#, c-format
+msgid "W16: Warning: Mode of file \"%s\" has changed since editing started"
+msgstr "W16: 警告: 檔案 \"%s\" 的權é™èˆ‡ä¸Šæ¬¡è®€å…¥æ™‚ä¸ä¸€æ¨£ (有變動éŽ)"
+
+# 'mode' seems better as translated to 'permission'?
+#, c-format
+msgid "W13: Warning: File \"%s\" has been created after editing started"
+msgstr "W13: 警告: 檔案 \"%s\" 在開始編輯後åˆè¢«å»ºç«‹äº†"
+
+msgid "See \":help W11\" for more info."
+msgstr "進一步說明請見 \":help W11\"。"
+
+msgid "Warning"
+msgstr "警告"
+
+msgid ""
+"&OK\n"
+"&Load File"
+msgstr ""
+"確定(&O)\n"
+"載入檔案(&L)"
+
+#, 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 "--已刪除--"
+
+#. the group doesn't exist
+#, c-format
+msgid "E367: No such group: \"%s\""
+msgstr "E367: 無此群組: \"%s\""
+
+#, 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"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Auto-Commands ---"
+msgstr ""
+"\n"
+"--- Auto-Commands ---"
+
+msgid "E217: Can't execute autocommands for ALL events"
+msgstr "E217: ç„¡æ³•å°æ‰€æœ‰äº‹ä»¶åŸ·è¡Œ autocommand"
+
+msgid "No matching autocommands"
+msgstr "找ä¸åˆ°å°æ‡‰çš„ autocommand"
+
+msgid "E218: autocommand nesting too deep"
+msgstr "E218: autocommand å±¤æ•¸éŽæ·±"
+
+#, c-format
+msgid "%s Auto commands for \"%s\""
+msgstr "%s Auto commands: \"%s\""
+
+#, c-format
+msgid "Executing %s"
+msgstr "執行 %s"
+
+#. always scroll up, don't overwrite
+#, c-format
+msgid "autocommand %s"
+msgstr "autocommand %s"
+
+msgid "E219: Missing {."
+msgstr "E219: 缺少 {."
+
+msgid "E220: Missing }."
+msgstr "E220: 缺少 }."
+
+msgid "E490: No fold found"
+msgstr "E490: 找ä¸åˆ°ä»»ä½• fold"
+
+msgid "E350: Cannot create fold with current 'foldmethod'"
+msgstr "E350: 無法在目å‰çš„ 'foldmethod' 下建立 fold"
+
+msgid "E351: Cannot delete fold with current 'foldmethod'"
+msgstr "E351: 無法在目å‰çš„ 'foldmethod' 下刪除 fold"
+
+msgid "E222: Add to read buffer"
+msgstr "E222: 加入讀å–ç·©è¡å€ä¸­"
+
+msgid "E223: recursive mapping"
+msgstr "E223: éžè¿´ mapping"
+
+#, c-format
+msgid "E224: global abbreviation already exists for %s"
+msgstr "E224: %s 已經有全域 abbreviation 了"
+
+#, c-format
+msgid "E225: global mapping already exists for %s"
+msgstr "E225: %s 已經有全域 mapping 了"
+
+#, c-format
+msgid "E226: abbreviation already exists for %s"
+msgstr "E226: %s 已經有 abbreviation 了"
+
+#, c-format
+msgid "E227: mapping already exists for %s"
+msgstr "E227: %s 的 mapping 已經存在"
+
+msgid "No abbreviation found"
+msgstr "找ä¸åˆ° abbreviation"
+
+msgid "No mapping found"
+msgstr "沒有這個 mapping å°æ‡‰"
+
+msgid "E228: makemap: Illegal mode"
+msgstr "E228: makemap: 䏿­£ç¢ºçš„æ¨¡å¼"
+
+msgid "E229: Cannot start the GUI"
+msgstr "E229: 無法啟動圖型界é¢"
+
+#, c-format
+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' çš„å€¼ä¸æ­£ç¢º"
+
+#, c-format
+msgid "E254: Cannot allocate color %s"
+msgstr "E254: ä¸èƒ½é…ç½®é¡è‰² %s"
+
+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 "æ²å‹•軸: ä¸èƒ½è¨­å®š thumb pixmap çš„ä½ç½®"
+
+msgid "Vim dialog"
+msgstr "Vim å°è©±ç›’"
+
+msgid "E232: Cannot create BalloonEval with both message and callback"
+msgstr "E232: ä¸èƒ½å°è¨Šæ¯èˆ‡ callback 建立 BallonEval"
+
+msgid "Vim dialog..."
+msgstr "Vim å°è©±ç›’..."
+
+msgid ""
+"&Yes\n"
+"&No\n"
+"&Cancel"
+msgstr ""
+"&Y是\n"
+"&Nå¦\n"
+"&Cå–æ¶ˆ"
+
+msgid "Input _Methods"
+msgstr "輸入法"
+
+msgid "VIM - Search and Replace..."
+msgstr "VIM - 尋找與å–代..."
+
+msgid "VIM - Search..."
+msgstr "VIM - 尋找..."
+
+msgid "Find what:"
+msgstr "æœå°‹:"
+
+msgid "Replace with:"
+msgstr "å–代為:"
+
+#. whole word only button
+msgid "Match whole word only"
+msgstr "åªæœå°‹å®Œå…¨ç›¸åŒçš„å­—"
+
+#. match case button
+msgid "Match case"
+msgstr "符åˆå¤§å°å¯«"
+
+msgid "Direction"
+msgstr "æ–¹å‘"
+
+#. 'Up' and 'Down' buttons
+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: ç”± Session 管ç†å“¡æ”¶åˆ° \"die\" è¦æ±‚\n"
+
+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 "éŽæ¿¾å™¨"
+
+msgid "Directories"
+msgstr "目錄"
+
+msgid "Help"
+msgstr "輔助說明"
+
+msgid "Files"
+msgstr "檔案"
+
+msgid "Selection"
+msgstr "鏿“‡"
+
+msgid "Undo"
+msgstr "復原"
+
+#, 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 "Find string (use '\\\\' to find a '\\')"
+msgstr "æœå°‹å­—串 (使用 '\\\\' 來表示 '\\')"
+
+msgid "Find & Replace (use '\\\\' to find a '\\')"
+msgstr "æœå°‹åŠå–代字串 (使用 '\\\\' 來表示 '\\')"
+
+msgid "Vim E458: Cannot allocate colormap entry, some colors may be incorrect"
+msgstr "Vim E458: 無法é…ç½® color map 項目,有些é¡è‰²çœ‹èµ·ä¾†æœƒæ€ªæ€ªçš„"
+
+#, c-format
+msgid "E250: Fonts for the following charsets are missing in fontset %s:"
+msgstr "E250: Fontset %s 沒有設定正確的字型以供顯示這些字元集:"
+
+#, c-format
+msgid "E252: Fontset name: %s"
+msgstr "E252: 字型集(Fontset)å稱: %s"
+
+#, c-format
+msgid "Font '%s' is not fixed-width"
+msgstr "'%s' 䏿˜¯å›ºå®šå¯¬åº¦å­—åž‹"
+
+#, c-format
+msgid "E253: Fontset name: %s\n"
+msgstr "E253: 字型集(Fontset)å稱: %s\n"
+
+#, c-format
+msgid "Font0: %s\n"
+msgstr "Font0: %s\n"
+
+#, c-format
+msgid "Font1: %s\n"
+msgstr "Font1: %s\n"
+
+#, c-format
+msgid "Font%ld width is not twice that of font0\n"
+msgstr "å­—åž‹%ld å¯¬åº¦ä¸æ˜¯ å­—åž‹0 的兩å€\n"
+
+#, c-format
+msgid "Font0 width: %ld\n"
+msgstr "字型0的寬度:%ld\n"
+
+#, c-format
+msgid ""
+"Font1 width: %ld\n"
+"\n"
+msgstr ""
+"字型1寬度: %ld\n"
+"\n"
+
+msgid "E256: Hangul automata ERROR"
+msgstr "E256: Hangul automata 錯誤"
+
+msgid "Add a new database"
+msgstr "新增資料庫"
+
+msgid "Query for a pattern"
+msgstr "輸入 pattern"
+
+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: 找ä¸åˆ° tag"
+
+#, 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 的 pipe 連線"
+
+msgid "E622: Could not fork for cscope"
+msgstr "E622: 無法 fork 以執行 cscope "
+
+msgid "cs_create_connection exec failed"
+msgstr "cs_create_connection 執行失敗"
+
+msgid "E623: Could not spawn cscope process"
+msgstr "E623: 無法執行 cscope "
+
+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 "E567: no cscope connections"
+msgstr "E567: 沒有 cscope 連線"
+
+#, c-format
+msgid "E259: no matches found for cscope query %s of %s"
+msgstr "E259: 找ä¸åˆ°ç¬¦åˆ cscope çš„æœå°‹ %s / %s"
+
+#, c-format
+msgid "E469: invalid cscopequickfix flag %c for %c"
+msgstr "E469: cscopequickfix çš„ flac %c (%c) 䏿­£ç¢º"
+
+msgid "cscope commands:\n"
+msgstr "cscope 命令:\n"
+
+#, c-format
+msgid "%-5s: %-30s (Usage: %s)"
+msgstr "%-5s: %-30s (用法: %s)"
+
+#, 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 資料庫未被加入"
+
+msgid "E569: maximum number of cscope connections reached"
+msgstr "E569: å·²é”到 cscope 最大連線數目"
+
+#, c-format
+msgid "E261: cscope connection %s not found"
+msgstr "E261: 找ä¸åˆ° cscope 連線 %s"
+
+#, c-format
+msgid "cscope connection %s closed"
+msgstr "cscope 連線 %s 已關閉"
+
+#. should not reach here
+msgid "E570: fatal error in cs_manage_matches"
+msgstr "E570: cs_manage_matches åš´é‡éŒ¯èª¤"
+
+#, c-format
+msgid "Cscope tag: %s"
+msgstr "Cscope 標籤(tag): %s"
+
+msgid ""
+"\n"
+" # line"
+msgstr ""
+"\n"
+" # 行 "
+
+msgid "filename / context / line\n"
+msgstr "檔å / å…§æ–‡ / 行號\n"
+
+#, c-format
+msgid "E609: Cscope error: %s"
+msgstr "E609: Csope 錯誤: %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 資料庫å稱 prepend path\n"
+
+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() éœ€è¦ string list ç•¶åƒæ•¸"
+
+msgid "E264: Python: Error initialising I/O objects"
+msgstr "E264: Python: 無法åˆå§‹ I/O 物件"
+
+msgid "invalid expression"
+msgstr "䏿­£ç¢ºçš„é‹ç®—å¼"
+
+msgid "expressions disabled at compile time"
+msgstr "因為編譯時沒有加入é‹ç®—å¼(expression)的程å¼ç¢¼ï¼Œæ‰€ä»¥ç„¡æ³•使用é‹ç®—å¼"
+
+msgid "attempt to refer to deleted buffer"
+msgstr "試圖使用已被刪除的 buffer"
+
+msgid "line number out of range"
+msgstr "行號超出範åœ"
+
+#, c-format
+msgid "<buffer object (deleted) at %8lX>"
+msgstr "<buffer 物件 (已刪除): %8lX>"
+
+msgid "invalid mark name"
+msgstr "標記åç¨±ä¸æ­£ç¢º"
+
+msgid "no such buffer"
+msgstr "ç„¡æ­¤ buffer"
+
+msgid "attempt to refer to deleted window"
+msgstr "試圖使用已被刪除的視窗"
+
+msgid "readonly attribute"
+msgstr "唯讀屬性"
+
+msgid "cursor position outside buffer"
+msgstr "游標定ä½åœ¨ç·©è¡å€ä¹‹å¤–"
+
+#, c-format
+msgid "<window object (deleted) at %.8lX>"
+msgstr "<視窗物件(已刪除): %.8lX>"
+
+#, c-format
+msgid "<window object (unknown) at %.8lX>"
+msgstr "<視窗物件(未知): %.8lX>"
+
+#, c-format
+msgid "<window %d>"
+msgstr "<視窗 %d>"
+
+msgid "no such window"
+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 "å­—ä¸²ç„¡æ³•åŒ…å«æ–°è¡Œ "
+
+msgid ""
+"E266: Sorry, this command is disabled, the Ruby library could not be loaded."
+msgstr "E266: 此命令無法使用,無法載入 Ruby 程å¼åº«(Library)"
+
+#, c-format
+msgid "E273: unknown longjmp status %d"
+msgstr "E273: 未知的 longjmp status %d"
+
+msgid "Toggle implementation/definition"
+msgstr "切æ›å¯¦ä½œ/定義"
+
+msgid "Show base class of"
+msgstr "顯示 base class of:"
+
+msgid "Show overridden member function"
+msgstr "顯示被 override 的 member function"
+
+msgid "Retrieve from file"
+msgstr "讀å–: 從檔案"
+
+msgid "Retrieve from project"
+msgstr "讀å–: 從物件"
+
+msgid "Retrieve from all projects"
+msgstr "讀å–: 從所有 project"
+
+msgid "Retrieve"
+msgstr "讀å–"
+
+msgid "Show source of"
+msgstr "顯示原始碼: "
+
+msgid "Find symbol"
+msgstr "æœå°‹ symbol"
+
+msgid "Browse class"
+msgstr "ç€è¦½ class"
+
+msgid "Show class in hierarchy"
+msgstr "顯示階層å¼çš„ class"
+
+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 "連線中"
+
+#, c-format
+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 "unknown option"
+msgstr "䏿­£ç¢ºçš„é¸é …"
+
+#. ???
+msgid "cannot set line(s)"
+msgstr "ä¸èƒ½è¨­å®šè¡Œ "
+
+msgid "mark not set"
+msgstr "沒有設定標記"
+
+#, c-format
+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 "無法註冊 callback 命令: ç·©è¡å€/視窗已經被刪除了"
+
+#. This should never happen. Famous last word?
+msgid ""
+"E280: TCL FATAL ERROR: reflist corrupt!? Please report this to vim-dev@vim."
+"org"
+msgstr "E280: TCL åš´é‡éŒ¯èª¤: reflist 爛掉了!? 請報告給 to vim-dev@vim.org"
+
+msgid "cannot register callback command: buffer/window reference not found"
+msgstr "無法註冊 callback 命令: 找ä¸åˆ°ç·©è¡å€/視窗"
+
+msgid ""
+"E571: Sorry, this command is disabled: the Tcl library could not be loaded."
+msgstr "E571: 此命令無法使用, 因為無法載入 Tcl 程å¼åº«(Library)"
+
+msgid ""
+"E281: TCL ERROR: exit code is not int!? Please report this to vim-dev@vim.org"
+msgstr "E281: TCL 錯誤: çµæŸç¢¼ä¸æ˜¯æ•´æ•¸!? 請報告給 to vim-dev@vim.org"
+
+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 的 registry 設定項有誤。已刪除。"
+
+msgid "Unknown option"
+msgstr "䏿­£ç¢ºçš„é¸é …"
+
+msgid "Too many edit arguments"
+msgstr "å¤ªå¤šç·¨è¼¯åƒæ•¸"
+
+msgid "Argument missing after"
+msgstr "缺少必è¦çš„åƒæ•¸:"
+
+msgid "Garbage after option"
+msgstr "ç„¡æ³•è¾¨èªæ­¤é¸é …後的命令: "
+
+msgid "Too many \"+command\", \"-c command\" or \"--cmd command\" arguments"
+msgstr "太多 \"+command\" 〠\"-c command\" 或 \"--cmd command\" åƒæ•¸"
+
+msgid "Invalid argument for"
+msgstr "䏿­£ç¢ºçš„åƒæ•¸: "
+
+msgid "This Vim was not compiled with the diff feature."
+msgstr "您的 Vim 編譯時沒有加入 diff 的能力"
+
+msgid "Attempt to open script file again: \""
+msgstr "è©¦åœ–å†æ¬¡é–‹å•Ÿ script 檔: \""
+
+msgid "Cannot open for reading: \""
+msgstr "無法開啟以讀å–: \""
+
+msgid "Cannot open for script output: \""
+msgstr "無法開啟為 script 輸出: \""
+
+#, c-format
+msgid "%d files to edit\n"
+msgstr "還有 %d 個檔案等待編輯\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"
+
+#. just in case..
+msgid "pre-vimrc command line"
+msgstr "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 編輯時使用指定的 tag"
+
+msgid "-q [errorfile] edit file with first error"
+msgstr "-q [errorfile] 編輯時載入第一個錯誤"
+
+msgid ""
+"\n"
+"\n"
+"usage:"
+msgstr ""
+"\n"
+"\n"
+" 用法:"
+
+msgid " vim [arguments] "
+msgstr "vim [åƒæ•¸] "
+
+msgid ""
+"\n"
+" or:"
+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å–æ¶ˆ 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\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 "-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\tç°¡æ˜“æ¨¡å¼ (åŒ \"evim\", modeless)"
+
+msgid "-R\t\t\tReadonly mode (like \"view\")"
+msgstr "-R\t\t\tå”¯è®€æ¨¡å¼ (åŒ \"view\")"
+
+msgid "-Z\t\t\tRestricted mode (like \"rvim\")"
+msgstr "-Z\t\t\té™åˆ¶æ¨¡å¼ (åŒ \"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'compatible' 傳統 Vi 相容模å¼"
+
+msgid "-N\t\t\tNot fully Vi compatible: 'nocompatible'"
+msgstr "-N\t\t\t'nocompatible' ä¸å®Œå…¨èˆ‡å‚³çµ± Vi 相容,å¯ä½¿ç”¨ Vim 加強能力"
+
+msgid "-V[N]\t\tVerbose level"
+msgstr "-V[N]\t\tVerbose 等級"
+
+msgid "-D\t\t\tDebugging mode"
+msgstr "-D\t\t\t除錯模å¼"
+
+msgid "-n\t\t\tNo swap file, use memory only"
+msgstr "-n\t\t\tä¸ä½¿ç”¨æš«å­˜æª”, åªä½¿ç”¨è¨˜æ†¶é«”"
+
+msgid "-r\t\t\tList swap files and exit"
+msgstr "-r\t\t\t列出暫存檔後離開"
+
+msgid "-r (with file name)\tRecover crashed session"
+msgstr "-r (加檔å) \tä¿®å¾©ä¸Šæ¬¡ææ¯€çš„資料(Recover crashed session)"
+
+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ä¸ä½¿ç”¨ newcli 來開啟視窗"
+
+msgid "-dev <device>\t\tUse <device> for I/O"
+msgstr "-dev <device>\t\t使用 <device> åšè¼¸å‡ºå…¥"
+
+msgid "-A\t\t\tstart in Arabic mode"
+msgstr "-A\t\t\t啟動為 Arabic 模å¼"
+
+msgid "-H\t\t\tStart in Hebrew mode"
+msgstr "-H\t\t\t啟動為 Hebrew 模å¼"
+
+msgid "-F\t\t\tStart in Farsi mode"
+msgstr "-F\t\t\t啟動為 Farsi 模å¼"
+
+msgid "-T <terminal>\tSet terminal type to <terminal>"
+msgstr "-T <terminal>\t設定終端機為 <terminal>"
+
+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ä¸è¼‰å…¥ä»»ä½• plugin"
+
+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 "+<lnum>\t\t啟動後跳到第 <lnum> 行 "
+
+msgid "--cmd <command>\tExecute <command> before loading any vimrc file"
+msgstr "--cmd <command>\t載入任何 vimrc å‰åŸ·è¡Œ <command>"
+
+msgid "-c <command>\t\tExecute <command> after loading the first file"
+msgstr "-c <command>\t\t載入第一個檔案後執行 <command>"
+
+msgid "-S <session>\t\tSource file <session> after loading the first file"
+msgstr "-S <session>\t\t載入第一個檔案後載入 Session 檔 <session>"
+
+msgid "-s <scriptin>\tRead Normal mode commands from file <scriptin>"
+msgstr "-s <scriptin>\t從 <scriptin> 讀入一般模å¼å‘½ä»¤"
+
+msgid "-w <scriptout>\tAppend all typed commands to file <scriptout>"
+msgstr "-w <scriptout>\tå°æª”案 <scriptout> 附加(append)所有輸入的命令"
+
+msgid "-W <scriptout>\tWrite all typed commands to file <scriptout>"
+msgstr "-W <scriptout>\tå°æª”案 <scriptout> 寫入所有輸入的命令"
+
+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-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在伺æœå™¨ä¸ŠåŸ·è¡Œ <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 "-i <viminfo>\t\tUse <viminfo> instead of .viminfo"
+msgstr "-i <viminfo>\t\t使用 <viminfo> è€Œéž .viminfo"
+
+msgid "-h or --help\tPrint Help (this message) and exit"
+msgstr "-h 或 --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 <display>\t在視窗 <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 çš„å稱視為 <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設定指定的 resource"
+
+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設定ç¨ç‰¹çš„角色(role)以å€åˆ†ä¸»è¦–窗"
+
+msgid "--socketid <xid>\tOpen Vim inside another GTK widget"
+msgstr "--socketid <xid>\t在å¦ä¸€å€‹ GTK widget 內開啟 Vim"
+
+msgid "-P <parent title>\tOpen Vim inside parent application"
+msgstr "-P <parent title>\t在父程å¼ä¸­é–‹å•Ÿ Vim"
+
+msgid "No display"
+msgstr "無顯示"
+
+#. Failed to send, abort.
+msgid ": Send failed.\n"
+msgstr ": 傳é€å¤±æ•—。\n"
+
+#. Let vim start normally.
+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 "ç„¡ Display: 無法傳é€é‹ç®—å¼ã€‚\n"
+
+msgid ": Send expression failed.\n"
+msgstr ": 無法傳é€é‹ç®—å¼ã€‚\n"
+
+msgid "No marks set"
+msgstr "沒有設定標記 (mark)"
+
+#, c-format
+msgid "E283: No marks matching \"%s\""
+msgstr "E283: 找ä¸åˆ°ç¬¦åˆ \"%s\" 的標記(mark)"
+
+#. Highlight title
+msgid ""
+"\n"
+"mark line col file/text"
+msgstr ""
+"\n"
+"標記 行號 欄 檔案/文字"
+
+#. Highlight title
+msgid ""
+"\n"
+" jump line col file/text"
+msgstr ""
+"\n"
+" jump 行號 欄 檔案/文字"
+
+#. Highlight title
+msgid ""
+"\n"
+"change line col text"
+msgstr ""
+"\n"
+"改變 行號 欄 文字"
+
+#, c-format
+msgid ""
+"\n"
+"# File marks:\n"
+msgstr ""
+"\n"
+"# 檔案標記:\n"
+
+#. Write the jumplist with -'
+#, c-format
+msgid ""
+"\n"
+"# Jumplist (newest first):\n"
+msgstr ""
+"\n"
+"# Jumplist (由新到舊):\n"
+
+#, c-format
+msgid ""
+"\n"
+"# History of marks within files (newest to oldest):\n"
+msgstr ""
+"\n"
+"# 檔案內 Mark 記錄 (由新到舊):\n"
+
+msgid "Missing '>'"
+msgstr "ç¼ºå°‘å°æ‡‰çš„ '>'"
+
+msgid "E543: Not a valid codepage"
+msgstr "E543: 䏿­£ç¢ºçš„ codepage"
+
+msgid "E284: Cannot set IC values"
+msgstr "E284: ä¸èƒ½è¨­å®š IC 數值"
+
+msgid "E285: Failed to create input context"
+msgstr "E285: 無法建立 input context"
+
+msgid "E286: Failed to open input method"
+msgstr "E286: 無法開啟輸入法"
+
+msgid "E287: Warning: Could not set destroy callback to IM"
+msgstr "E287: 警告: 無法移除 IM 的 callback"
+
+msgid "E288: input method doesn't support any style"
+msgstr "E288: è¼¸å…¥æ³•ä¸æ”¯æ´ä»»ä½• style"
+
+msgid "E289: input method doesn't support my preedit type"
+msgstr "E289: è¼¸å…¥æ³•ä¸æ”¯æ´ä»»ä½• style"
+
+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: 沒有執行中的輸入法管ç†ç¨‹å¼(Input Method Server)"
+
+msgid "E293: block was not locked"
+msgstr "E293: å€å¡Šæœªè¢«éŽ–å®š"
+
+msgid "E294: Seek error in swap file read"
+msgstr "E294: 暫存檔讀å–錯誤"
+
+msgid "E295: Read error in swap file"
+msgstr "E295: 暫存檔讀å–錯誤"
+
+msgid "E296: Seek error in swap file write"
+msgstr "E296: 暫存檔寫入錯誤"
+
+msgid "E297: Write error in swap file"
+msgstr "E297: 暫存檔寫入錯誤"
+
+msgid "E300: Swap file already exists (symlink attack?)"
+msgstr "E300: 暫存檔已經存在! (å°å¿ƒç¬¦è™Ÿé€£çµçš„å®‰å…¨æ¼æ´ž!?)"
+
+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?"
+
+#. could not (re)open the swap file, what can we do????
+msgid "E301: Oops, lost the swap file!!!"
+msgstr "E301: 噢噢, 暫存檔ä¸è¦‹äº†!!!"
+
+msgid "E302: Could not rename swap file"
+msgstr "E302: 無法改變暫存檔的å稱"
+
+#, c-format
+msgid "E303: Unable to open swap file for \"%s\", recovery impossible"
+msgstr "E303: 無法開啟暫存檔 \"%s\", ä¸å¯èƒ½ä¿®å¾©äº†"
+
+msgid "E304: ml_timestamp: Didn't get block 0??"
+msgstr "E304: ml_timestamp: 找ä¸åˆ°å€å¡Š 0??"
+
+#, c-format
+msgid "E305: No swap file found for %s"
+msgstr "E305: 找ä¸åˆ° %s 的暫存檔"
+
+msgid "Enter number of swap file to use (0 to quit): "
+msgstr "è«‹é¸æ“‡ä½ è¦ä½¿ç”¨çš„æš«å­˜æª” (按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 還來ä¸åŠæ›´æ–°æš«å­˜æª”."
+
+msgid " cannot be used with this version of Vim.\n"
+msgstr " 無法在本版本的 Vim 中使用.\n"
+
+msgid "Use Vim version 3.0.\n"
+msgstr "使用 Vim 3.0。\n"
+
+#, c-format
+msgid "E307: %s does not look like a Vim swap file"
+msgstr "E307: %s 看起來ä¸åƒæ˜¯ Vim 暫存檔"
+
+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 "Using swap file \"%s\""
+msgstr "使用暫存檔 \"%s\""
+
+#, c-format
+msgid "Original file \"%s\""
+msgstr "原始檔 \"%s\""
+
+msgid "E308: Warning: Original file may have been changed"
+msgstr "E308: 警告: 原始檔案å¯èƒ½å·²ç¶“修改éŽäº†"
+
+#, c-format
+msgid "E309: Unable to read block 1 from %s"
+msgstr "E309: 無法從 %s 讀å–å€å¡Š 1"
+
+msgid "???MANY LINES MISSING"
+msgstr "???缺少太多行 "
+
+msgid "???LINE COUNT WRONG"
+msgstr "???行號錯誤"
+
+msgid "???EMPTY BLOCK"
+msgstr "???空的 BLOCK"
+
+msgid "???LINES MISSING"
+msgstr "???找ä¸åˆ°ä¸€äº›è¡Œ "
+
+#, c-format
+msgid "E310: Block 1 ID wrong (%s not a .swp file?)"
+msgstr "E310: å€å¡Š 1 ID 錯誤 (%s 䏿˜¯æš«å­˜æª”?)"
+
+msgid "???BLOCK MISSING"
+msgstr "???找ä¸åˆ°BLOCK"
+
+msgid "??? from here until ???END lines may be messed up"
+msgstr "??? 從這裡到 ???END 的內容å¯èƒ½æœ‰å•題"
+
+msgid "??? from here until ???END lines may have been inserted/deleted"
+msgstr "??? 從這裡到 ???END 的內容å¯èƒ½è¢«åˆªé™¤/æ’å…¥éŽ"
+
+# do not translate
+msgid "???END"
+msgstr "???END"
+
+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 "復原完æˆ. 請確定一切正常."
+
+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)\n"
+msgstr "å†åŸ·è¡Œ diff èˆ‡åŽŸæª”æ¡ˆæ¯”è¼ƒä»¥æª¢æŸ¥æ˜¯å¦æœ‰æ”¹è®Š)\n"
+
+msgid ""
+"Delete the .swp file afterwards.\n"
+"\n"
+msgstr ""
+"(D)直接刪除 .swp 暫存檔\n"
+"\n"
+
+#. use msg() to start the scrolling properly
+msgid "Swap files found:"
+msgstr "找到以下的暫存檔:"
+
+msgid " In current directory:\n"
+msgstr " 在目å‰çš„目錄:\n"
+
+msgid " Using specified name:\n"
+msgstr " Using specified name:\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 的暫存檔]"
+
+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"
+" process ID: "
+
+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: 無法ä¿ç•™, ä¸ä½¿ç”¨æš«å­˜æª”"
+
+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: 指標å€å¡Š id 錯誤 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: 指標å€å¡Š id 錯誤 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: 指標å€å¡Š id 錯誤"
+
+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: 指標å€å¡Š id 錯 2"
+
+msgid "E325: ATTENTION"
+msgstr "E325: 注æ„"
+
+msgid ""
+"\n"
+"Found a swap file by the name \""
+msgstr ""
+"\n"
+"找到暫存檔 \""
+
+msgid "While opening file \""
+msgstr "在開啟檔案 \""
+
+msgid " NEWER than swap file!\n"
+msgstr " 比暫存檔更新!\n"
+
+#. Some of these messages are long to allow translation to
+#. * other languages.
+msgid ""
+"\n"
+"(1) Another program may be editing the same file.\n"
+" If this is the case, be careful not to end up with two\n"
+" different instances of the same file when making changes.\n"
+msgstr ""
+"\n"
+"(1) å¯èƒ½æœ‰å¦ä¸€å€‹ç¨‹å¼ä¹Ÿåœ¨ç·¨è¼¯åŒä¸€å€‹æª”案.\n"
+" 如果是這樣,請å°å¿ƒä¸è¦å…©é‚Šä¸€èµ·å¯«å…¥ï¼Œä¸ç„¶ä½ çš„åŠªåŠ›éƒ½æœƒè² è«¸æµæ°´ã€‚\n"
+
+msgid " Quit, or continue with caution.\n"
+msgstr " 離開,或是繼續編輯。\n"
+
+msgid ""
+"\n"
+"(2) An edit session for this file crashed.\n"
+msgstr ""
+"\n"
+"(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 " 如果該救的都已經救了, 請直接刪除此暫存檔 \""
+
+msgid ""
+"\"\n"
+" to avoid this message.\n"
+msgstr ""
+"\"\n"
+" 以é¿å…å†çœ‹åˆ°æ­¤è¨Šæ¯.\n"
+
+msgid "Swap file \""
+msgstr "暫存檔 \""
+
+msgid "\" already exists!"
+msgstr "\" 已經存在了!"
+
+msgid "VIM - ATTENTION"
+msgstr "VIM - 注æ„"
+
+msgid "Swap file already exists!"
+msgstr "暫存檔已經存在!"
+
+msgid ""
+"&Open Read-Only\n"
+"&Edit anyway\n"
+"&Recover\n"
+"&Quit\n"
+"&Abort"
+msgstr ""
+"以唯讀方å¼é–‹å•Ÿ(&O)\n"
+"直接編輯(&E)\n"
+"修復(&R)\n"
+"離開(&Q)\n"
+"跳出(&A)"
+
+msgid ""
+"&Open Read-Only\n"
+"&Edit anyway\n"
+"&Recover\n"
+"&Quit\n"
+"&Abort\n"
+"&Delete it"
+msgstr ""
+"以唯讀方å¼é–‹å•Ÿ(&O)\n"
+"直接編輯(&E)\n"
+"修復(&R)\n"
+"離開(&Q)\n"
+"跳出(&A)\n"
+"刪除暫存檔(&D)"
+
+msgid "E326: Too many swap files found"
+msgstr "E326: 找到太多暫存檔"
+
+msgid "E327: Part of menu-item path is not sub-menu"
+msgstr "E327: 部份é¸é …è·¯å¾‘ä¸æ˜¯å­é¸å–®"
+
+msgid "E328: Menu only exists in another mode"
+msgstr "E328: é¸å–®åªèƒ½åœ¨å…¶å®ƒæ¨¡å¼ä¸­ä½¿ç”¨"
+
+msgid "E329: No menu of that name"
+msgstr "E329: 沒有那樣的é¸å–®"
+
+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: 分隔線ä¸èƒ½æ˜¯é¸å–®è·¯å¾‘的一部份"
+
+#. Now we have found the matching menu, and we list the mappings
+#. Highlight title
+msgid ""
+"\n"
+"--- Menus ---"
+msgstr ""
+"\n"
+"--- é¸å–® ---"
+
+msgid "Tear off this menu"
+msgstr "切下此é¸å–®"
+
+msgid "E333: Menu path must lead to a menu item"
+msgstr "E333: é¸å–®è·¯å¾‘必需指å‘一個é¸é …"
+
+#, c-format
+msgid "E334: Menu not found: %s"
+msgstr "E334: [é¸å–®] 找ä¸åˆ° %s"
+
+#, c-format
+msgid "E335: Menu not defined for %s mode"
+msgstr "E335: %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:"
+
+msgid "[string too long]"
+msgstr "[此行éŽé•·]"
+
+msgid "Messages maintainer: Bram Moolenaar <Bram@vim.org>"
+msgstr ""
+"正體中文訊æ¯ç¶­è­·è€…: Francis S.Lin <piaip@csie.ntu.edu."
+"tw>, Cecil Sheng <b7506022@csie.ntu.edu.tw>"
+
+msgid "Interrupt: "
+msgstr "已中斷: "
+
+msgid "Hit ENTER to continue"
+msgstr "請按 ENTER 繼續"
+
+msgid "Hit ENTER or type command to continue"
+msgstr "請按 ENTER 或其它命令以繼續"
+
+msgid "-- More --"
+msgstr "-- 尚有 --"
+
+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 "Question"
+msgstr "å•題"
+
+msgid ""
+"&Yes\n"
+"&No"
+msgstr ""
+"&Y是\n"
+"&Nå¦"
+
+msgid ""
+"&Yes\n"
+"&No\n"
+"Save &All\n"
+"&Discard All\n"
+"&Cancel"
+msgstr ""
+"&Y是\n"
+"&Nå¦\n"
+"&A全部存檔\n"
+"&D全部ä¸å­˜\n"
+"&Cå–æ¶ˆ"
+
+msgid "Save File dialog"
+msgstr "存檔"
+
+msgid "Open File dialog"
+msgstr "開檔"
+
+#. TODO: non-GUI file selector here
+msgid "E338: Sorry, no file browser in console mode"
+msgstr "E338: 主控å°(Console)æ¨¡å¼æ™‚沒有檔案ç€è¦½å™¨(file browser)"
+
+msgid "W10: Warning: Changing a readonly file"
+msgstr "W10: 注æ„: 你正在修改一個唯讀檔"
+
+msgid "1 more line"
+msgstr "還有一行 "
+
+msgid "1 line less"
+msgstr "少於一行 "
+
+#, c-format
+msgid "%ld more lines"
+msgstr "多了 %ld 行 "
+
+#, c-format
+msgid "%ld fewer lines"
+msgstr "少了 %ld 行 "
+
+msgid " (Interrupted)"
+msgstr " (已中斷)"
+
+msgid "Vim: preserving files...\n"
+msgstr "Vim: ä¿ç•™æª”案中...\n"
+
+#. close all memfiles, without deleting
+msgid "Vim: Finished.\n"
+msgstr "Vim: çµæŸ.\n"
+
+#, c-format
+msgid "ERROR: "
+msgstr "錯誤: "
+
+#, c-format
+msgid ""
+"\n"
+"[bytes] total alloc-freed %lu-%lu, in use %lu, peak use %lu\n"
+msgstr ""
+"\n"
+"[bytes] 全部 alloc-freed %lu-%lu, 使用中 %lu, peak 使用 %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 "å‘¼å« shell 執行: \"%s\""
+
+msgid "E545: Missing colon"
+msgstr "E545: 缺少 colon"
+
+msgid "E546: Illegal mode"
+msgstr "E546: 䏿­£ç¢ºçš„æ¨¡å¼"
+
+msgid "E547: Illegal mouseshape"
+msgstr "E547: 䏿­£ç¢ºçš„æ»‘鼠形狀"
+
+msgid "E548: digit expected"
+msgstr "E548: æ‡‰è©²è¦æœ‰æ•¸å­—"
+
+msgid "E549: Illegal percentage"
+msgstr "E549: 䏿­£ç¢ºçš„百分比"
+
+msgid "Enter encryption key: "
+msgstr "輸入密碼: "
+
+msgid "Enter same key again: "
+msgstr "è«‹å†è¼¸å…¥ä¸€æ¬¡: "
+
+msgid "Keys don't match!"
+msgstr "兩次輸入密碼ä¸ç›¸åŒ!"
+
+#, c-format
+msgid ""
+"E343: Invalid path: '**[number]' must be at the end of the path or be "
+"followed by '%s'."
+msgstr "E343: 䏿­£ç¢ºçš„路徑: '**[number]' 必需è¦åœ¨è·¯å¾‘çµå°¾æˆ–è¦æŽ¥è‘— '%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: 在路徑中找ä¸åˆ°æª”案 \"%s\""
+
+#, c-format
+msgid "E346: No more directory \"%s\" found in cdpath"
+msgstr "E346: 在路徑中找ä¸åˆ°æ›´å¤šçš„æª”案 \"%s\""
+
+#, c-format
+msgid "E347: No more file \"%s\" found in path"
+msgstr "E347: 在路徑中找ä¸åˆ°æ›´å¤šçš„æª”案 \"%s\""
+
+msgid "E550: Missing colon"
+msgstr "E550: 缺少 colon"
+
+msgid "E551: Illegal component"
+msgstr "E551: 䏿­£ç¢ºçš„æ¨¡å¼"
+
+msgid "E552: digit expected"
+msgstr "E552: æ‡‰è©²è¦æœ‰æ•¸å­—"
+
+#. Get here when the server can't be found.
+msgid "Cannot connect to Netbeans #2"
+msgstr "無法連接到 Netbeans #2"
+
+msgid "Cannot connect to Netbeans"
+msgstr "無法連接到 Netbeans"
+
+#, c-format
+msgid "E668: Wrong access mode for NetBeans connection info file: \"%s\""
+msgstr "E668: NetBeans 連線資訊檔案: \"%s\" å­˜å–æ¨¡å¼ä¸æ­£ç¢º"
+
+msgid "read from Netbeans socket"
+msgstr "ç”± Netbeans socket 讀å–"
+
+#, c-format
+msgid "E658: NetBeans connection lost for buffer %ld"
+msgstr "E658: ç·©è¡å€ %ld 與 NetBeans 的連線已中斷"
+
+msgid "Warning: terminal cannot highlight"
+msgstr "注æ„: 你的終端機無法顯示高亮度"
+
+msgid "E348: No string under cursor"
+msgstr "E348: 游標處沒有字串"
+
+msgid "E349: No identifier under cursor"
+msgstr "E349: 游標處沒有識別字"
+
+msgid "E352: Cannot erase folds with current 'foldmethod'"
+msgstr "E352: 無法在目å‰çš„ 'foldmethod' 下刪除 fold"
+
+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 :quit<Enter> to exit Vim"
+msgstr "è¦é›¢é–‹ Vim 請輸入 :quit<Enter> "
+
+#, c-format
+msgid "1 line %sed 1 time"
+msgstr "一行 %s éŽ ä¸€æ¬¡"
+
+#, c-format
+msgid "1 line %sed %d times"
+msgstr "一行 %s éŽ %d 次"
+
+#, c-format
+msgid "%ld lines %sed 1 time"
+msgstr "%ld 行 %s éŽ ä¸€æ¬¡"
+
+#, 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 "一行已縮排"
+
+#, c-format
+msgid "%ld lines indented "
+msgstr "已縮排 %ld 行 "
+
+#. must display the prompt
+msgid "cannot yank; delete anyway"
+msgstr "無法剪下; 直接刪除"
+
+msgid "1 line changed"
+msgstr " 1 行 ~ed"
+
+#, c-format
+msgid "%ld lines changed"
+msgstr "已改變 %ld 行 "
+
+#, c-format
+msgid "freeing %ld lines"
+msgstr "釋放 %ld 行中 "
+
+msgid "1 line yanked"
+msgstr "已複製 1 行 "
+
+#, c-format
+msgid "%ld lines yanked"
+msgstr "已複製 %ld 行 "
+
+#, c-format
+msgid "E353: Nothing in register %s"
+msgstr "E353: 暫存器 %s 裡沒有æ±è¥¿"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Registers ---"
+msgstr ""
+"\n"
+"--- 暫存器 ---"
+
+msgid "Illegal register name"
+msgstr "䏿­£ç¢ºçš„æš«å­˜å™¨å稱"
+
+#, c-format
+msgid ""
+"\n"
+"# Registers:\n"
+msgstr ""
+"\n"
+"# 暫存器:\n"
+
+#, c-format
+msgid "E574: Unknown register type %d"
+msgstr "E574: 未知的註冊型態: %d"
+
+#, c-format
+msgid "E354: Invalid register name: '%s'"
+msgstr "E354: 暫存器å稱錯誤: '%s'"
+
+#, c-format
+msgid "%ld Cols; "
+msgstr "%ld 欄; "
+
+#, c-format
+msgid "Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Bytes"
+msgstr "鏿“‡äº† %s%ld/%ld 行; %ld/%ld å­—(Word); %ld/%ld å­—å…ƒ(Bytes)"
+
+#, c-format
+msgid "Col %s of %s; Line %ld of %ld; Word %ld of %ld; Byte %ld of %ld"
+msgstr "欄 %s/%s; 行 %ld/%ld; 字(Word) %ld/%ld; 字元(Byte) %ld/%ld"
+
+#, c-format
+msgid "(+%ld for BOM)"
+msgstr "(+%ld for BOM)"
+
+msgid "%<%f%h%m%=Page %N"
+msgstr "%<%f%h%m%=第 %N é "
+
+# ? what's this for?
+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: ä¸èƒ½åœ¨ Modeline 裡出ç¾"
+
+msgid ""
+"\n"
+"\tLast set from "
+msgstr ""
+"\n"
+"\t上次設定: "
+
+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>"
+
+msgid "E529: Cannot set 'term' to empty string"
+msgstr "E529: 無法設定 'term' 為空字串"
+
+msgid "E530: Cannot change term in GUI"
+msgstr "E530: 在圖型界é¢ä¸­ç„¡æ³•åˆ‡æ› term"
+
+msgid "E531: Use \":gui\" to start the GUI"
+msgstr "E531: 輸入 \":gui\" 來啟動圖形界é¢"
+
+msgid "E589: 'backupext' and 'patchmode' are equal"
+msgstr "E589: 'backupext' 跟 'patchmode' 是一樣的"
+
+msgid "E617: Cannot be changed in the GTK+ 2 GUI"
+msgstr "E617: 在圖型界é¢ä¸­ç„¡æ³•åˆ‡æ› term"
+
+msgid "E524: Missing colon"
+msgstr "E524: 缺少 colon"
+
+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: 無法使用設定的中文字型(Widefont)"
+
+msgid "E534: Invalid wide font"
+msgstr "E534: 䏿­£ç¢ºçš„å­—åž‹(Widefont)"
+
+#, 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: ä¸å°ç¨±çš„ group"
+
+msgid "E590: A preview window already exists"
+msgstr "E590: é è¦–的視窗已經存在了"
+
+msgid "W17: Arabic requires UTF-8, do ':set encoding=utf-8'"
+msgstr "W17: Arabic éœ€è¦ UTF-8, 請執行 ':set encoding=utf-8'"
+
+#, 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"
+
+msgid ""
+"\n"
+"--- Terminal codes ---"
+msgstr ""
+"\n"
+"--- 終端機碼 ---"
+
+msgid ""
+"\n"
+"--- Global option values ---"
+msgstr ""
+"\n"
+"--- Global é¸é …值 ---"
+
+msgid ""
+"\n"
+"--- Local option values ---"
+msgstr ""
+"\n"
+"--- Local é¸é …值 ---"
+
+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 "無法切æ›ä¸»æŽ§å°(console)æ¨¡å¼ !?\n"
+
+msgid "mch_get_shellsize: not a console??\n"
+msgstr "mch_get_shellsize: 䏿˜¯ä¸»æŽ§å°(console)??\n"
+
+#. if Vim opened a window: Executing a shell may cause crashes
+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 "...(truncated)"
+msgstr "...(已切掉)"
+
+msgid "'columns' is not 80, cannot execute external commands"
+msgstr "'columns' 䏿˜¯ 80, 無法執行外部命令"
+
+msgid "E237: Printer selection failed"
+msgstr "E237: ç„¡æ³•é¸æ“‡æ­¤å°è¡¨æ©Ÿ"
+
+#, c-format
+msgid "to %s on %s"
+msgstr "到 %s on %s"
+
+#, c-format
+msgid "E613: Unknown printer font: %s"
+msgstr "E613: 䏿­£ç¢ºçš„å°è¡¨æ©Ÿå­—åž‹: %s"
+
+#, c-format
+msgid "E238: Print error: %s"
+msgstr "E238: 列å°éŒ¯èª¤: %s"
+
+msgid "Unknown"
+msgstr "未知"
+
+#, 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 "E245: Illegal char '%c' in font name \"%s\""
+msgstr "E245: 䏿­£ç¢ºçš„å­—å…ƒ '%c' 出ç¾åœ¨å­—åž‹å稱 \"%s\" å…§"
+
+msgid "Vim: Double signal, exiting\n"
+msgstr "Vim: é›™é‡signal, 離開中\n"
+
+#, c-format
+msgid "Vim: Caught deadly signal %s\n"
+msgstr "Vim: CVim: 攔截到信號(signal) %s\n"
+
+#, c-format
+msgid "Vim: Caught deadly signal\n"
+msgstr "Vim: 攔截到致命的信號(deadly signale)\n"
+
+#, c-format
+msgid "Opening the X display took %ld msec"
+msgstr "開啟 X Window 耗時 %ld 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 逾時"
+
+msgid ""
+"\n"
+"Cannot execute shell "
+msgstr ""
+"\n"
+"ä¸èƒ½åŸ·è¡Œ shell"
+
+msgid ""
+"\n"
+"Cannot execute shell sh\n"
+msgstr ""
+"\n"
+"ä¸èƒ½åŸ·è¡Œ shell sh\n"
+
+msgid ""
+"\n"
+"shell returned "
+msgstr ""
+"\n"
+"Shell 已返回"
+
+msgid ""
+"\n"
+"Cannot create pipes\n"
+msgstr ""
+"\n"
+"ä¸èƒ½å»ºç«‹ pipe 管線\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 Window 失敗"
+
+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 allocate memory for command line."
+msgstr "無法為命令列é…置記憶體。"
+
+msgid "VIM Error"
+msgstr "VIM 錯誤"
+
+msgid "Could not load vim32.dll!"
+msgstr "無法載入 vim32.dllï¼"
+
+msgid "Could not fix up function pointers to the DLL!"
+msgstr "ä¸èƒ½ä¿®æ­£å‡½å¼æŒ‡æ¨™åˆ° DLL!"
+
+#, c-format
+msgid "shell returned %d"
+msgstr "Shell 傳回值 %d"
+
+#, 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 ""
+"在你的 $PATH 中找ä¸åˆ° VIMRUN.EXE.\n"
+"å¤–éƒ¨å‘½ä»¤åŸ·è¡Œå®Œç•¢å¾Œå°‡ä¸æœƒæš«åœ.\n"
+"進一步說明請執行 :help win32-vimrun "
+
+msgid "Vim Warning"
+msgstr "Vim 警告"
+
+#, 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: 沒有其它項目"
+
+#, c-format
+msgid "(%d of %d)%s%s: "
+msgstr "(%d / %d)%s%s: "
+
+msgid " (line deleted)"
+msgstr " (行已刪除)"
+
+msgid "E380: At bottom of quickfix stack"
+msgstr "E380: Quickfix 堆疊çµå°¾"
+
+msgid "E381: At top of quickfix stack"
+msgstr "E381: Quickfix 堆疊頂端"
+
+#, c-format
+msgid "error list %d of %d; %d errors"
+msgstr "錯誤列表 %d/%d; 共有 %d 項錯誤"
+
+msgid "E382: Cannot write, 'buftype' option is set"
+msgstr "E382: 無法寫入,'buftype' é¸é …已設定"
+
+#, c-format
+msgid "E369: invalid item in %s%%[]"
+msgstr "E369: 䏿­£ç¢ºçš„項目: %s%%[]"
+
+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 "E53: Unmatched %s%%("
+msgstr "E53: ç„¡å°æ‡‰çš„ %s%%("
+
+#, c-format
+msgid "E54: Unmatched %s("
+msgstr "E54: ç„¡å°æ‡‰çš„ %s("
+
+#, c-format
+msgid "E55: Unmatched %s)"
+msgstr "E55: ç„¡å°æ‡‰çš„ %s)"
+
+#, c-format
+msgid "E56: %s* operand could be empty"
+msgstr "E56: %s* é‹ç®—å…ƒå¯ä»¥æ˜¯ç©ºçš„"
+
+#, c-format
+msgid "E57: %s+ operand could be empty"
+msgstr "E57: %s+ é‹ç®—å…ƒå¯ä»¥æ˜¯ç©ºçš„"
+
+#, c-format
+msgid "E59: invalid character after %s@"
+msgstr "E59: å¾Œé¢æœ‰ä¸æ­£ç¢ºçš„å­—å…ƒ: %s@"
+
+#, c-format
+msgid "E58: %s{ operand could be empty"
+msgstr "E58: %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 沒有接æ±è¥¿"
+
+msgid "E65: Illegal back reference"
+msgstr "E65: 䏿­£ç¢ºçš„åå‘åƒè€ƒ"
+
+msgid "E66: \\z( not allowed here"
+msgstr "E66: \\z( ä¸èƒ½åœ¨æ­¤å‡ºç¾"
+
+msgid "E67: \\z1 et al. not allowed here"
+msgstr "E67: \\z1 et al. ä¸èƒ½åœ¨æ­¤å‡ºç¾"
+
+msgid "E68: Invalid character after \\z"
+msgstr "E68: å¾Œé¢æœ‰ä¸æ­£ç¢ºçš„å­—å…ƒ: \\z"
+
+#, c-format
+msgid "E69: Missing ] after %s%%["
+msgstr "E69: %s%%[ 後缺少 ]"
+
+#, c-format
+msgid "E70: Empty %s%%[]"
+msgstr "E70: 空的 %s%%[]"
+
+#, c-format
+msgid "E71: Invalid character after %s%%"
+msgstr "E71: å¾Œé¢æœ‰ä¸æ­£ç¢ºçš„å­—å…ƒ: %s%%"
+
+#, c-format
+msgid "E554: Syntax error in %s{...}"
+msgstr "E554: 語法錯誤: %s{...}"
+
+msgid "E361: Crash intercepted; regexp too complex?"
+msgstr "E361: 無法執行; regular expression 太複雜?"
+
+msgid "E363: pattern caused out-of-stack error"
+msgstr "E363: regular expression 造æˆå †ç–Šç”¨å…‰çš„錯誤"
+
+msgid "External submatches:\n"
+msgstr "外部符åˆ:\n"
+
+#, c-format
+msgid "+--%3ld lines folded "
+msgstr "+--已 fold %3ld 行 "
+
+msgid " VREPLACE"
+msgstr " V-å–代"
+
+msgid " REPLACE"
+msgstr " å–代"
+
+msgid " REVERSE"
+msgstr " å轉"
+
+msgid " INSERT"
+msgstr " æ’å…¥"
+
+msgid " (insert)"
+msgstr " (æ’å…¥)"
+
+msgid " (replace)"
+msgstr " (å–代)"
+
+msgid " (vreplace)"
+msgstr " (v-å–代)"
+
+msgid " Hebrew"
+msgstr " Hebrew"
+
+msgid " Arabic"
+msgstr " Arabic"
+
+msgid " (lang)"
+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 "記錄中"
+
+msgid "search hit TOP, continuing at BOTTOM"
+msgstr "å·²æœå°‹åˆ°æª”案開頭;å†å¾žçµå°¾ç¹¼çºŒæœå°‹"
+
+msgid "search hit BOTTOM, continuing at TOP"
+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 " (åŒ…æ‹¬å‰æ¬¡åˆ—出符åˆé …)"
+
+#. cursor at status line
+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"
+
+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: 找ä¸åˆ° pattern"
+
+#, c-format
+msgid "E390: Illegal argument: %s"
+msgstr "E390: åƒæ•¸ä¸æ­£ç¢º: %s"
+
+#, c-format
+msgid "E391: No such syntax cluster: %s"
+msgstr "E391: ç„¡æ­¤ syntax cluster: \"%s\""
+
+msgid "No Syntax items defined for this buffer"
+msgstr "這個緩è¡å€æ²’有定義任何語法"
+
+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"
+"--- èªžæ³•åŒæ­¥ç‰©ä»¶ (Syntax sync items) ---"
+
+msgid ""
+"\n"
+"syncing on items"
+msgstr ""
+"\n"
+"åŒæ­¥åŒ–中:"
+
+msgid ""
+"\n"
+"--- Syntax items ---"
+msgstr ""
+"\n"
+"--- 語法項目 ---"
+
+#, c-format
+msgid "E392: No such syntax cluster: %s"
+msgstr "E392: ç„¡æ­¤ syntax cluster: \"%s\""
+
+msgid "minimal "
+msgstr "最å°"
+
+msgid "maximal "
+msgstr "最大"
+
+msgid "; match "
+msgstr "; ç¬¦åˆ "
+
+msgid " line breaks"
+msgstr "斷行 "
+
+msgid "E393: group[t]here not accepted here"
+msgstr "E393: ä½¿ç”¨äº†ä¸æ­£ç¢ºçš„åƒæ•¸"
+
+#, c-format
+msgid "E394: Didn't find region item for %s"
+msgstr "E394: 找ä¸åˆ° %s çš„ region item"
+
+msgid "E395: contains argument not accepted here"
+msgstr "E395: ä½¿ç”¨äº†ä¸æ­£ç¢ºçš„åƒæ•¸"
+
+msgid "E396: containedin argument not accepted here"
+msgstr "E396: ä½¿ç”¨äº†ä¸æ­£ç¢ºçš„åƒæ•¸"
+
+msgid "E397: Filename required"
+msgstr "E397: éœ€è¦æª”案å稱"
+
+#, c-format
+msgid "E398: Missing '=': %s"
+msgstr "E398: 缺少 \"=\": %s"
+
+#, c-format
+msgid "E399: Not enough arguments: syntax region %s"
+msgstr "E399: syntax region %s 的引數太少"
+
+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 必須是列表裡的第一個"
+
+#, c-format
+msgid "E409: Unknown group name: %s"
+msgstr "E409: 䏿­£ç¢ºçš„群組å稱: %s"
+
+#, c-format
+msgid "E410: Invalid :syntax subcommand: %s"
+msgstr "E410: 䏿­£ç¢ºçš„ :syntax å­å‘½ä»¤: %s"
+
+#, c-format
+msgid "E411: highlight group not found: %s"
+msgstr "E411: 找ä¸åˆ° highlight group: %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: éŒ¯èª¤çš„å‰æ™¯é¡è‰²"
+
+msgid "E420: BG color unknown"
+msgstr "E420: 錯誤的背景é¡è‰²"
+
+#, 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: 群組å稱中有無法列å°çš„å­—å…ƒ"
+
+#. This is an error, but since there previously was no check only
+#. * give a warning.
+msgid "W18: Invalid character in group name"
+msgstr "W18: 群組åç¨±ä¸­æœ‰ä¸æ­£ç¢ºçš„å­—å…ƒ"
+
+msgid "E555: at bottom of tag stack"
+msgstr "E555: 標籤(tag)堆疊çµå°¾"
+
+msgid "E556: at top of tag stack"
+msgstr "E556: 標籤(tag)堆疊開頭"
+
+msgid "E425: Cannot go before first matching tag"
+msgstr "E425: 已經在最å‰é¢çš„æ¨™ç±¤(tag)了"
+
+#, c-format
+msgid "E426: tag not found: %s"
+msgstr "E426: 找ä¸åˆ°æ¨™ç±¤(tag): %s"
+
+msgid " # pri kind tag"
+msgstr " # pri kind tag"
+
+msgid "file\n"
+msgstr "檔案\n"
+
+#.
+#. * Ask to select a tag from the list.
+#. * When using ":silent" assume that <CR> was entered.
+#.
+msgid "Enter nr of choice (<CR> to abort): "
+msgstr "輸入 nr æˆ–é¸æ“‡ (<CR> 離開): "
+
+msgid "E427: There is only one matching tag"
+msgstr "E427: åªæœ‰æ­¤é …符åˆ"
+
+msgid "E428: Cannot go beyond last matching tag"
+msgstr "E428: 己經在最後一個符åˆçš„ tag 了"
+
+#, c-format
+msgid "File \"%s\" does not exist"
+msgstr "檔案 \"%s\" ä¸å­˜åœ¨"
+
+#. Give an indication of the number of matching tags
+#, c-format
+msgid "tag %d of %d%s"
+msgstr "找到 tag: %d/%d%s"
+
+msgid " or more"
+msgstr " 或更多"
+
+msgid " Using tag with different case!"
+msgstr " 以ä¸åŒå¤§å°å¯«ä¾†ä½¿ç”¨ tag!"
+
+#, c-format
+msgid "E429: File \"%s\" does not exist"
+msgstr "E429: 檔案 \"%s\" ä¸å­˜åœ¨"
+
+#. Highlight title
+msgid ""
+"\n"
+" # TO tag FROM line in file/text"
+msgstr ""
+"\n"
+" # 到 tag 從 行 在 檔案/文字"
+
+#, c-format
+msgid "Searching tags file %s"
+msgstr "æœå°‹ tag 檔案 \"%s\""
+
+#, c-format
+msgid "E430: Tag file path truncated for %s\n"
+msgstr "E430: Tag 檔案路徑被截斷為 %s\n"
+
+#, c-format
+msgid "E431: Format error in tags file \"%s\""
+msgstr "E431: Tag 檔 \"%s\" æ ¼å¼éŒ¯èª¤"
+
+#, c-format
+msgid "Before byte %ld"
+msgstr "在 %ld ä½å…ƒä¹‹å‰"
+
+#, c-format
+msgid "E432: Tags file not sorted: %s"
+msgstr "E432: Tag 檔案未排åº: %s"
+
+#. never opened any tags file
+msgid "E433: No tags file"
+msgstr "E433: 沒有 tag 檔"
+
+msgid "E434: Can't find tag pattern"
+msgstr "E434: 找ä¸åˆ° tag"
+
+msgid "E435: Couldn't find tag, just guessing!"
+msgstr "E435: 找ä¸åˆ° tag, 用猜的!"
+
+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: termcap 沒有 \"%s\" entry"
+
+msgid "E437: terminal capability \"cm\" required"
+msgstr "E437: çµ‚ç«¯æ©Ÿéœ€è¦ \"cm\" 的能力"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Terminal keys ---"
+msgstr ""
+"\n"
+"--- çµ‚ç«¯æ©ŸæŒ‰éµ ---"
+
+msgid "new shell started\n"
+msgstr "èµ·å‹•æ–° shell\n"
+
+msgid "Vim: Error reading input, exiting...\n"
+msgstr "Vim: 讀å–輸入錯誤,離開中...\n"
+
+#. must display the prompt
+msgid "No undo possible; continue anyway"
+msgstr "無法還原;請繼續努力"
+
+msgid "E438: u_undo: line numbers wrong"
+msgstr "E438: u_undo: 行號錯誤"
+
+msgid "1 change"
+msgstr "一項改變"
+
+#, c-format
+msgid "%ld changes"
+msgstr "%ld 項改變"
+
+msgid "E439: undo list corrupt"
+msgstr "E439: 復原列表æå£ž"
+
+msgid "E440: undo line missing"
+msgstr "E440: 找ä¸åˆ°è¦ undo 的行 "
+
+#. Only MS VC 4.1 and earlier can do Win32s
+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"
+"Included 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 "ä¸ä½¿ç”¨åœ–型界é¢ã€‚"
+
+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 BeOS GUI."
+msgstr "使用 BeOS 圖型界é¢ã€‚"
+
+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 " Features included (+) or not (-):\n"
+msgstr " ç›®å‰å¯ä½¿ç”¨(+)與ä¸å¯ä½¿ç”¨(-)的模組列表:\n"
+
+msgid " system vimrc file: \""
+msgstr " 系統 vimrc 設定檔: \""
+
+msgid " user vimrc file: \""
+msgstr " 使用者個人 vimrc 設定檔: \""
+
+msgid " 2nd user vimrc file: \""
+msgstr " 第二組個人 vimrc 檔案: \""
+
+msgid " 3rd user vimrc file: \""
+msgstr " 第三組個人 vimrc 檔案: \""
+
+msgid " user exrc file: \""
+msgstr " 使用者個人 exrc 設定檔: \""
+
+msgid " 2nd user exrc file: \""
+msgstr " 第二組使用者 exrc 檔案: \""
+
+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 " 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 " 除錯版本"
+
+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> "
+
+msgid "type :help version7<Enter> for version info"
+msgstr "新版本資訊請輸入 :help version7<Enter>"
+
+msgid "Running in Vi compatible mode"
+msgstr "Vi 相容模å¼"
+
+msgid "type :set nocp<Enter> for Vim defaults"
+msgstr "如果è¦å®Œå…¨æ¨¡æ“¬å‚³çµ± Vi 請輸入 :set nocp<Enter>"
+
+msgid "type :help cp-default<Enter> for info on this"
+msgstr "如果需è¦å° Vi 相容模å¼çš„進一步說明請輸入 :help cp-default<Enter>"
+
+msgid "menu Help->Orphans for information "
+msgstr "進一步說明請é¸å–é¸å–®çš„ 輔助說明->拯救孤兒"
+
+msgid "Running modeless, typed text is inserted"
+msgstr "執行 Modeless 模å¼ï¼Œè¼¸å…¥çš„æ–‡å­—會自動æ’å…¥"
+
+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 "WARNING: Windows 95/98/ME detected"
+msgstr "注æ„: 嵿¸¬åˆ° Windows 95/98/ME"
+
+msgid "type :help windows95<Enter> for info on this"
+msgstr "如果需è¦å° Windows 95 支æ´çš„æ›´å¤šè³‡è¨Šè«‹è¼¸å…¥ :help windows95<Enter>"
+
+msgid "E441: There is no preview window"
+msgstr "E441: 沒有é è¦½è¦–窗"
+
+msgid "E442: Can't split topleft and botright at the same time"
+msgstr "E442: ä¸èƒ½åŒæ™‚分割視窗為左上和å³ä¸‹è§’"
+
+msgid "E443: Cannot rotate when another window is split"
+msgstr "E443: 有其它分割視窗時無法旋轉"
+
+msgid "E444: Cannot close last window"
+msgstr "E444: ä¸èƒ½é—œé–‰æœ€å¾Œä¸€å€‹è¦–窗"
+
+msgid "Already only one window"
+msgstr "已經åªå‰©ä¸€å€‹è¦–窗了"
+
+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 "E370: Could not load library %s"
+msgstr "E370: ç„¡æ³•é‡æ–°è¼‰å…¥ç¨‹å¼åº« %s"
+
+msgid "Sorry, this command is disabled: the Perl library could not be loaded."
+msgstr "抱歉, 此命令無法使用. 原因: 無法載入 Perl 程å¼åº«(Library)"
+
+msgid "E299: Perl evaluation forbidden in sandbox without the Safe module"
+msgstr "E299: 在 sandbox 中無 Safe 模組時無法執行 Perl"
+
+msgid "Edit with &multiple Vims"
+msgstr "使用多個 Vim session 編輯(&M)"
+
+msgid "Edit with single &Vim"
+msgstr "åªä½¿ç”¨åŒä¸€å€‹ Vim session 編輯(&V)"
+
+msgid "&Diff with Vim"
+msgstr "使用 Vim 來比較(&Diff)"
+
+msgid "Edit with &Vim"
+msgstr "使用 Vim 編輯此檔(&V)"
+
+#. Now concatenate
+msgid "Edit with existing Vim - &"
+msgstr "使用執行中的 Vim session 編輯 - &"
+
+msgid "Edits the selected file(s) with Vim"
+msgstr "使用 Vim 編輯已é¸å–的檔案"
+
+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 "--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.
+#.
+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 "E588: :endwhile without :while"
+msgstr "E588: :endwhile ç¼ºå°‘å°æ‡‰çš„ :while"
+
+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: 內部錯誤"
+
+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 "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\" 是目錄"
+
+msgid "E18: Unexpected characters before '='"
+msgstr "E18: '=' å‰é¢å‡ºç¾äº†éŒ¯èª¤çš„å­—å…ƒ"
+
+#, c-format
+msgid "E364: Library call failed for \"%s()\""
+msgstr "E364: 呼å«å‡½å¼åº« \"%s\"() 失敗"
+
+#, 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: 沒有這個 abbreviation å°æ‡‰"
+
+msgid "E477: No ! allowed"
+msgstr "E477: ä¸å¯ä½¿ç”¨ '!'"
+
+msgid "E25: GUI cannot be used: Not enabled at compile time"
+msgstr "E25: 因為編譯時沒有加入圖型界é¢çš„程å¼ç¢¼ï¼Œæ‰€ä»¥ç„¡æ³•使用圖型界é¢"
+
+msgid "E26: Hebrew cannot be used: Not enabled at compile time\n"
+msgstr "E26: 因為編譯時沒有加入 Hebrew 的程å¼ç¢¼ï¼Œæ‰€ä»¥ç„¡æ³•使用 Hebrew\n"
+
+msgid "E27: Farsi cannot be used: Not enabled at compile time\n"
+msgstr "E27: 因為編譯時沒有加入 Farsi 的程å¼ç¢¼ï¼Œæ‰€ä»¥ç„¡æ³•使用 Farsi\n"
+
+msgid "E800: Arabic cannot be used: Not enabled at compile time\n"
+msgstr "E800: 因為編譯時沒有加入 Arabic 的程å¼ç¢¼ï¼Œæ‰€ä»¥ç„¡æ³•使用\n"
+
+#, c-format
+msgid "E28: No such highlight group name: %s"
+msgstr "E28: 沒有å為 '%s' çš„ highlight group"
+
+msgid "E29: No inserted text yet"
+msgstr "E29: 還沒有æ’入文字éŽ"
+
+msgid "E30: No previous command line"
+msgstr "E30: 沒有å‰ä¸€é …命令"
+
+msgid "E31: No such mapping"
+msgstr "E31: 沒有這個 mapping å°æ‡‰"
+
+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 "E37: No write since last change (add ! to override)"
+msgstr "E37: å·²æ›´æ”¹éŽæª”案但尚未存檔 (å¯ç”¨ ! 強制執行)"
+
+msgid "E38: Null argument"
+msgstr "E38: 空的 (Null) åƒæ•¸"
+
+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: <ä¸èƒ½é–‹å•Ÿ X Server DISPLAY>"
+
+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 "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 set read-only variable \"%s\""
+msgstr "E46: 無法設定唯讀變數 \"%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: 'E71: é¸é … 'shell' 未設定"
+
+msgid "E255: Couldn't read in sign data!"
+msgstr "E255: ç„¡æ³•è®€å– sign data!"
+
+msgid "E72: Close error on swap file"
+msgstr "E72: 暫存檔關閉錯誤"
+
+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 "Zero count"
+msgstr "數到零 (?)"
+
+msgid "E81: Using <SID> not in a script context"
+msgstr "E81: <SID> ä¸èƒ½åœ¨ script 本文外使用."
+
+msgid "E449: Invalid expression received"
+msgstr "E449: æ”¶åˆ°ä¸æ­£ç¢ºçš„é‹ç®—å¼"
+
+msgid "E463: Region is guarded, cannot modify"
+msgstr "E463: å€åŸŸè¢«ä¿è­·ï¼Œç„¡æ³•修改"
+
+#~ msgid "E565: error reading cscope connection %d"
+#~ msgstr "E565: è®€å– 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 "\"\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 "線性æœå°‹æ¨™ç±¤ (Tags)"
+
+#~ msgid "Binary tag search"
+#~ msgstr "二分æœå°‹(Binary search) 標籤(Tags)"
+
+#~ msgid "function "
+#~ msgstr "å‡½å¼ "
+
+#~ msgid "Run Macro"
+#~ msgstr "執行巨集"
+
+#~ msgid "E221: 'commentstring' is empty"
+#~ msgstr "E221: é¸é … 'commentstring' 未設定"
+
+#~ msgid "E242: Color name not recognized: %s"
+#~ msgstr "E242: %s 為無法識別的é¡è‰²å稱"
+
+#~ msgid "E242: Missing color: %s"
+#~ msgstr "E242: 找ä¸åˆ°é¡è‰²: %s"
+
+#~ msgid "error reading cscope connection %d"
+#~ msgstr "è®€å– cscope 連線 %d 時錯誤"
+
+#~ msgid "E249: couldn't read VIM instance registry property"
+#~ msgstr "E249: ç„¡æ³•è®€å– VIM çš„ registry 設定項"
+
+#~ msgid "Can't open file %s"
+#~ msgstr "無法開啟檔案 %s"
+
+#~ msgid "Unable to send reply"
+#~ msgstr "無法傳é€å›žæ‡‰è¨Šæ¯"
+
+#~ msgid "E241: Unable to send to Vim server"
+#~ msgstr "E241: 無法傳é€åˆ° Vim 伺æœå™¨"
+
+#~ msgid ""
+#~ "\n"
+#~ "Send failed. No command server present ?\n"
+#~ msgstr ""
+#~ "\n"
+#~ "傳é€å¤±æ•—。沒有命令伺æœå™¨å­˜åœ¨ ?\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沒有伺æœå™¨(Servers)"
+
+#~ msgid "E258: no matches found in cscope connections"
+#~ msgstr "E258: cscope 連線找ä¸åˆ°ç¬¦åˆçš„"
+
+#~ msgid ""
+#~ "\n"
+#~ "MacOS Carbon"
+#~ msgstr ""
+#~ "\n"
+#~ "MacOS Carbon"
+
+#~ msgid ""
+#~ "\n"
+#~ "MacOS 8"
+#~ msgstr ""
+#~ "\n"
+#~ "MacOS 8"
+
+#~ msgid "Retrieve next symbol"
+#~ msgstr "讀å–: 從下個 symbol"
+
+#~ msgid "-- SNiFF+ commands --"
+#~ msgstr "-- SNiFF+ 命令 --"
+
+#~ msgid "E277: Unrecognized sniff request [%s]"
+#~ msgstr "E277: 無法辨識 sniff 命令 [%s]"
diff --git a/src/po/zh_TW.po b/src/po/zh_TW.po
new file mode 100644
index 0000000000..6f43c8025a
--- /dev/null
+++ b/src/po/zh_TW.po
@@ -0,0 +1,5275 @@
+# 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 "%ld fewer lines" "on %ld lines"
+# If you don't put more (at least 2) spaces after %ld
+# 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 termencoding=utf-8
+# 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: 2005-01-27 19:00+0800\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"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=big5\n"
+"Content-Transfer-Encoding: 8-bit\n"
+
+msgid "E82: Cannot allocate any buffer, exiting..."
+msgstr "E82: µLªk°t¸m¥ô¦ó½w½Ä°Ï¡AÂ÷¶}µ{¦¡..."
+
+msgid "E83: Cannot allocate buffer, using other one..."
+msgstr "E83: µLªk°t¸m½w½Ä°Ï¡A¨Ï¥Î¥t¤@­Ó½w½Ä°Ï...."
+
+#, c-format
+msgid "E515: No buffers were unloaded"
+msgstr "E515: ¨S¦³ÄÀ©ñ¥ô¦ó½w½Ä°Ï"
+
+#, c-format
+msgid "E516: No buffers were deleted"
+msgstr "E516: ¨S¦³§R°£¥ô¦ó½w½Ä°Ï"
+
+#, c-format
+msgid "E517: No buffers were wiped out"
+msgstr "E517: ¨S¦³²M°£¥ô¦ó½w½Ä°Ï"
+
+msgid "1 buffer unloaded"
+msgstr "¤wÄÀ©ñ¤@­Ó½w½Ä°Ï"
+
+#, c-format
+msgid "%d buffers unloaded"
+msgstr "¤wÄÀ©ñ %d ­Ó½w½Ä°Ï"
+
+msgid "1 buffer deleted"
+msgstr "¤w§R°£¤@­Ó½w½Ä°Ï"
+
+#, c-format
+msgid "%d buffers deleted"
+msgstr "¤w§R°£ %d ­Ó½w½Ä°Ï"
+
+msgid "1 buffer wiped out"
+msgstr "¤w§R°£¤@­Ó½w½Ä°Ï"
+
+#, c-format
+msgid "%d buffers wiped out"
+msgstr "¤w§R°£ %d ­Ó½w½Ä°Ï"
+
+msgid "E84: No modified buffer found"
+msgstr "E84: ¨S¦³­×§ï¹Lªº½w½Ä°Ï"
+
+#. back where we started, didn't find anything.
+msgid "E85: There is no listed buffer"
+msgstr "E85: ¨S¦³¦C¥Xªº½w½Ä°Ï"
+
+#, c-format
+msgid "E86: Buffer %ld does not exist"
+msgstr "E86: ½w½Ä°Ï %ld ¤£¦s¦b"
+
+msgid "E87: Cannot go beyond last buffer"
+msgstr "E87: µLªk¤Á´«¨ì§ó«á­±ªº½w½Ä°Ï"
+
+msgid "E88: Cannot go before first buffer"
+msgstr "E88: µLªk¤Á´«¨ì§ó«e­±ªº½w½Ä°Ï"
+
+#, c-format
+msgid "E89: No write since last change for buffer %ld (add ! to override)"
+msgstr "E89: ¤w§ó§ï¹L½w½Ä°Ï %ld ¦ý©|¥¼¦sÀÉ (¥i¥Î ! ±j¨î°õ¦æ)"
+
+msgid "E90: Cannot unload last buffer"
+msgstr "E90: µLªkÄÀ©ñ³Ì«á¤@­Ó½w½Ä°Ï"
+
+msgid "W14: Warning: List of file names overflow"
+msgstr "W14: ĵ§i: ÀɦW¹L¦h"
+
+#, c-format
+msgid "E92: Buffer %ld not found"
+msgstr "E92: §ä¤£¨ì²Ä %ld ­Ó½w½Ä°Ï"
+
+#, c-format
+msgid "E93: More than one match for %s"
+msgstr "E93: §ä¨ì¤@­Ó¥H¤Wªº %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: ¤w¦³½w½Ä°Ï¨Ï¥Î³o­Ó¦W¦r"
+
+msgid " [Modified]"
+msgstr " [¤w­×§ï]"
+
+msgid "[Not edited]"
+msgstr "[¥¼½s¿è]"
+
+msgid "[New file]"
+msgstr "[·sÀÉ®×]"
+
+msgid "[Read errors]"
+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 file]"
+msgstr "[¥¼©R¦W]"
+
+#. must be a help buffer
+msgid "help"
+msgstr "[»²§U»¡©ú]"
+
+msgid "[help]"
+msgstr "[»²§U»¡©ú]"
+
+msgid "[Preview]"
+msgstr "[¹wÄý]"
+
+msgid "All"
+msgstr "¥þ³¡"
+
+msgid "Bot"
+msgstr "©³ºÝ"
+
+msgid "Top"
+msgstr "³»ºÝ"
+
+#, c-format
+msgid ""
+"\n"
+"# Buffer list:\n"
+msgstr ""
+"\n"
+"# ½w½Ä°Ï¦Cªí:\n"
+
+msgid "[Error List]"
+msgstr "[¿ù»~¦Cªí]"
+
+msgid "[No File]"
+msgstr "[¥¼©R¦W]"
+
+msgid ""
+"\n"
+"--- Signs ---"
+msgstr ""
+"\n"
+"--- ²Å¸¹ ---"
+
+#, c-format
+msgid "Signs for %s:"
+msgstr "%s ªº²Å¸¹:"
+
+#, c-format
+msgid " line=%ld id=%d name=%s"
+msgstr " ¦æ=%ld id=%d ¦WºÙ=%s"
+
+#, c-format
+msgid "E96: Can not diff more than %ld buffers"
+msgstr "E96: µLªk¤ñ¸û(diff) %ld­Ó¥H¤Wªº½w½Ä°Ï"
+
+msgid "E97: Cannot create diffs"
+msgstr "E97: ¤£¯à«Ø¥ß "
+
+msgid "Patch file"
+msgstr "Patch ÀÉ®×"
+
+msgid "E98: Cannot read diff output"
+msgstr "E98: µLªkŪ¨ú diff ªº¿é¥X"
+
+msgid "E99: Current buffer is not in diff mode"
+msgstr "E99: ¥Ø«eªº½w½Ä°Ï¤£¬O¦b diff ¼Ò¦¡"
+
+msgid "E100: No other buffer in diff mode"
+msgstr "E100: ¨S¦³½w½Ä°Ï¦b diff ¼Ò¦¡"
+
+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¥Î­þ¤@­Ó"
+
+#, c-format
+msgid "E102: Can't find buffer \"%s\""
+msgstr "E102: §ä¤£¨ì½w½Ä°Ï: \"%s\""
+
+#, c-format
+msgid "E103: Buffer \"%s\" is not in diff mode"
+msgstr "E103: ½w½Ä°Ï \"%s\" ¤£¬O¦b diff ¼Ò¦¡"
+
+msgid "E104: Escape not allowed in digraph"
+msgstr "E104: ½Æ¦X¦r¤¸(digraph)¤¤¤£¯à¨Ï¥Î Escape"
+
+msgid "E544: Keymap file not found"
+msgstr "E544: §ä¤£¨ì keymap ÀÉ"
+
+msgid "E105: Using :loadkeymap not in a sourced file"
+msgstr "E105: ¨Ï¥Î :loadkeymap "
+
+msgid " Keyword completion (^N^P)"
+msgstr " ÃöÁä¦r¦Û°Ê§¹¦¨ (^N^P)"
+
+#. ctrl_x_mode == 0, ^P/^N compl.
+msgid " ^X mode (^E^Y^L^]^F^I^K^D^V^N^P)"
+msgstr " ^X ¼Ò¦¡ (^E^Y^L^]^F^I^K^D^N^P)"
+
+#. Scroll has it's own msgs, in it's place there is the msg for local
+#. * ctrl_x_mode = 0 (eg continue_status & CONT_LOCAL) -- Acevedo
+msgid " Keyword Local completion (^N^P)"
+msgstr " °Ï°ìÃöÁä¦r¦Û°Ê§¹¦¨ (^N^P)"
+
+msgid " Whole line completion (^L^N^P)"
+msgstr " ¾ã¦æ¦Û°Ê§¹¦¨ (^L^N^P)"
+
+msgid " File name completion (^F^N^P)"
+msgstr " ÀɦW¦Û°Ê§¹¦¨ (^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 " ©w¸q¦Û°Ê§¹¦¨ (^D^N^P)"
+
+msgid " Dictionary completion (^K^N^P)"
+msgstr " ¦r¨å¦Û°Ê§¹¦¨ (^K^N^P)"
+
+msgid " Thesaurus completion (^T^N^P)"
+msgstr " Thesaurus ¦Û°Ê§¹¦¨ (^T^N^P)"
+
+msgid " Command-line completion (^V^N^P)"
+msgstr " ©R¥O¦C¦Û°Ê§¹¦¨ (^V^N^P)"
+
+msgid "Hit end of paragraph"
+msgstr "¤w¨ì¬q¸¨µ²§À"
+
+msgid "'thesaurus' option is empty"
+msgstr "¿ï¶µ 'thesaurus' ¥¼³]©w"
+
+msgid "'dictionary' option is empty"
+msgstr "¿ï¶µ 'dictionary' ¥¼³]©w"
+
+#, c-format
+msgid "Scanning dictionary: %s"
+msgstr "±½ºË¦r¨å: %s"
+
+msgid " (insert) Scroll (^E/^Y)"
+msgstr " (´¡¤J) Scroll (^E/^Y)"
+
+msgid " (replace) Scroll (^E/^Y)"
+msgstr " (¨ú¥N) Scroll (^E/^Y)"
+
+#, c-format
+msgid "Scanning: %s"
+msgstr "±½ºË¤¤: %s"
+
+#, c-format
+msgid "Scanning tags."
+msgstr "±½ºË¼ÐÅÒ."
+
+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.
+#.
+msgid "-- Searching..."
+msgstr "-- ·j´M¤¤..."
+
+msgid "Back at original"
+msgstr "¦^¨ì°_ÂI"
+
+msgid "Word from other line"
+msgstr "±q§O¦æ¶}©lªº¦r (?)"
+
+msgid "The only match"
+msgstr "¥u¦³¦¹¶µ²Å¦X"
+
+#, c-format
+msgid "match %d of %d"
+msgstr "§ä¨ì %d / %d"
+
+#, c-format
+msgid "match %d"
+msgstr "²Å¦X %d"
+
+#. Skip further arguments but do continue to
+#. * search for a trailing command.
+#, c-format
+msgid "E106: Unknown variable: \"%s\""
+msgstr "E106: ¥¼©w¸qªºÅܼÆ: \"%s\""
+
+#, c-format
+msgid "E107: Missing parentheses: %s"
+msgstr "E107: ¯Ê¤Ö¹ïÀ³ªº¬A¸¹: %s"
+
+#, c-format
+msgid "E108: No such variable: \"%s\""
+msgstr "E108: µL¦¹ÅܼÆ: \"%s\""
+
+msgid "E109: Missing ':' after '?'"
+msgstr "E109: '?' «á¯Ê¤Ö ':'"
+
+msgid "E110: Missing ')'"
+msgstr "E110: ¯Ê¤Ö¹ïÀ³ªº \")\""
+
+msgid "E111: Missing ']'"
+msgstr "E111: ¯Ê¤Ö¹ïÀ³ªº \"]\""
+
+#, c-format
+msgid "E112: Option name missing: %s"
+msgstr "E112: ¯Ê¤Ö¿ï¶µ¦WºÙ: %s"
+
+#, c-format
+msgid "E113: Unknown option: %s"
+msgstr "E113: ¤£¥¿½Tªº¿ï¶µ: %s"
+
+#, c-format
+msgid "E114: Missing quote: %s"
+msgstr "E114: ¯Ê¤Ö¤Þ¸¹: %s"
+
+#, c-format
+msgid "E115: Missing quote: %s"
+msgstr "E115: ¯Ê¤Ö¤Þ¸¹: %s"
+
+#, c-format
+msgid "E116: Invalid arguments for function %s"
+msgstr "E116: ¨ç¦¡ %s ªº¤Þ¼Æ¤£¥¿½T"
+
+#, c-format
+msgid "E117: Unknown function: %s"
+msgstr "E117: ¥¼©w¸qªº¨ç¦¡: %s"
+
+#, c-format
+msgid "E118: Too many arguments for function: %s"
+msgstr "E118: ¨ç¦¡ %s ªº¤Þ¼Æ¹L¦h"
+
+#, 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> ¤£¯à¦b script ¥»¤å¥~¨Ï¥Î: %s"
+
+#.
+#. * 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 "½T©w(&O)"
+
+#, c-format
+msgid "+-%s%3ld lines: "
+msgstr "+-%s%3ld ¦æ: "
+
+msgid ""
+"&OK\n"
+"&Cancel"
+msgstr ""
+"½T©w(&O)\n"
+"¨ú®ø(&C)"
+
+msgid "called inputrestore() more often than inputsave()"
+msgstr "©I¥s inputrestore() ªº¦¸¼Æ¤ñ inputsave() ÁÙ¦h"
+
+msgid "E655: Too many symbolic links (cycle?)"
+msgstr "E655: ¤Ó¦h¼hªº²Å¸¹Ãìµ²(symlink) (´`Àô?)"
+
+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"
+
+#, c-format
+msgid "E241: Unable to send to %s"
+msgstr "E241: µLªk¶Ç°e¨ì %s"
+
+msgid "(Invalid)"
+msgstr "(¤£¥¿½T)"
+
+#, c-format
+msgid "E121: Undefined variable: %s"
+msgstr "E121: ÅÜ¼Æ %s ©|¥¼©w¸q"
+
+#, c-format
+msgid "E461: Illegal variable name: %s"
+msgstr "E461: ¤£¦XªkªºÅܼƦWºÙ: %s"
+
+#, c-format
+msgid "E122: Function %s already exists, add ! to replace it"
+msgstr "E122: ¨ç¦¡ %s ¤w¸g¦s¦b, ½Ð¨Ï¥Î ! ±j¨î¨ú¥N"
+
+#, c-format
+msgid "E123: Undefined function: %s"
+msgstr "E123: ¨ç¦¡ %s ©|¥¼©w¸q"
+
+#, c-format
+msgid "E124: Missing '(': %s"
+msgstr "E124: ¯Ê¤Ö \"(\": %s"
+
+#, c-format
+msgid "E125: Illegal argument: %s"
+msgstr "E125: °Ñ¼Æ¤£¥¿½T: %s"
+
+msgid "E126: Missing :endfunction"
+msgstr "E126: ¯Ê¤Ö :endfunction"
+
+#, c-format
+msgid "E127: Cannot redefine function %s: It is in use"
+msgstr "E127: ¨ç¦¡ %s ¥¿¦b¨Ï¥Î¤¤¡AµLªk­«·s©w¸q"
+
+msgid "E129: Function name required"
+msgstr "E129: »Ý­n¨ç¦¡¦WºÙ"
+
+#, c-format
+msgid "E128: Function name must start with a capital: %s"
+msgstr "E128: ¨ç¦¡¦WºÙ²Ä¤@­Ó¦r¥À¥²¶·¤j¼g: %s"
+
+#, c-format
+msgid "E130: Undefined function: %s"
+msgstr "E130: ¨ç¦¡ %s ©|¥¼©w¸q"
+
+#, c-format
+msgid "E131: Cannot delete function %s: It is in use"
+msgstr "E131: ¨ç¦¡ %s ¥¿¦b¨Ï¥Î¤¤¡AµLªk§R°£"
+
+msgid "E132: Function call depth is higher than 'maxfuncdepth'"
+msgstr "E132: ¨ç¦¡»¼°j©I¥s¼h¼Æ¶W¹L 'maxfuncdepth'"
+
+#. always scroll up, don't overwrite
+#, c-format
+msgid "calling %s"
+msgstr "©I¥s %s"
+
+#, c-format
+msgid "%s aborted"
+msgstr "%s ³Q±j¨î¤¤Â_°õ¦æ "
+
+#, c-format
+msgid "%s returning #%ld"
+msgstr "%s ¶Ç¦^­È #%ld "
+
+#, c-format
+msgid "%s returning \"%s\""
+msgstr "%s ¶Ç¦^­È \"%s\""
+
+#. always scroll up, don't overwrite
+#, c-format
+msgid "continuing in %s"
+msgstr "Ä~Äò: %s"
+
+msgid "E133: :return not inside a function"
+msgstr "E133: :return ¥²¶·¦b¨ç¦¡¸Ì¨Ï¥Î"
+
+#, c-format
+msgid ""
+"\n"
+"# global variables:\n"
+msgstr ""
+"\n"
+"# ¥þ°ìÅܼÆ:\n"
+
+#, c-format
+msgid "<%s>%s%s %d, Hex %02x, Octal %03o"
+msgstr "<%s>%s%s %d, ¤Q¤»¶i¦ì %02x, ¤K¶i¦ì %03o"
+
+#, c-format
+msgid "> %d, Hex %04x, Octal %o"
+msgstr "> %d, ¤Q¤»¶i¦ì %04x, ¤K¶i¦ì %o"
+
+#, c-format
+msgid "> %d, Hex %08x, Octal %o"
+msgstr "> %d, ¤Q¤»¶i¦ì %08x, ¤K¶i¦ì %o"
+
+msgid "E134: Move lines into themselves"
+msgstr "E134: µLªk§â¦æ²¾¨ì¥¦¦Û¤w¤º"
+
+msgid "1 line moved"
+msgstr "¤w·h²¾ 1 ¦æ "
+
+#, c-format
+msgid "%ld lines moved"
+msgstr "¤w·h²¾ %ld ¦æ "
+
+#, c-format
+msgid "%ld lines filtered"
+msgstr "¤w³B²z %ld ¦æ "
+
+msgid "E135: *Filter* Autocommands must not change current buffer"
+msgstr "E135: *Filter* Autocommand ¤£¥i¥H§ó§ï½w½Ä°Ïªº¤º®e"
+
+msgid "[No write since last change]\n"
+msgstr "[§ó·s«á©|¥¼Àx¦s]\n"
+
+#, c-format
+msgid "%sviminfo: %s in line: "
+msgstr "%sviminfo: %s ¦b¦æ¤¤: "
+
+msgid "E136: viminfo: Too many errors, skipping rest of file"
+msgstr "E136: viminfo: ¹L¦h¿ù»~, ©¿²¤Àɮרä¾l³¡¤À"
+
+#, c-format
+msgid "Reading viminfo file \"%s\"%s%s%s"
+msgstr "Ū¨ú viminfo ÀÉ®× \"%s\"%s%s%s"
+
+msgid " info"
+msgstr " °T®§"
+
+msgid " marks"
+msgstr " ¼Ð°O"
+
+msgid " FAILED"
+msgstr " ¥¢±Ñ"
+
+#, c-format
+msgid "E137: Viminfo file is not writable: %s"
+msgstr "E137: Viminfo ÀÉ®×µLªk¼g¤J: %s"
+
+#, c-format
+msgid "E138: Can't write viminfo file %s!"
+msgstr "E138: µLªk¼g¤J viminfo ÀÉ®× %s !"
+
+#, c-format
+msgid "Writing viminfo file \"%s\""
+msgstr "¼g¤J viminfo ÀÉ®× \"%s\" ¤¤"
+
+#. Write the info:
+#, c-format
+msgid "# This viminfo file was generated by Vim %s.\n"
+msgstr "# ¥» viminfo Àɮ׬O¥Ñ Vim %s ©Ò²£¥Í.\n"
+
+#, c-format
+msgid ""
+"# You may edit it if you're careful!\n"
+"\n"
+msgstr ""
+"# ¦pªG·Q­n¦Û¦æ­×§ï½Ð¯S§O¤p¤ß¡I\n"
+"\n"
+
+#, c-format
+msgid "# Value of 'encoding' when this file was written\n"
+msgstr "# 'encoding' ¦b¦¹Àɫإ߮ɪº­È\n"
+
+msgid "Illegal starting char"
+msgstr "µL®Äªº°_©l¦r¤¸"
+
+msgid "Save As"
+msgstr "¥t¦s·sÀÉ"
+
+#. Overwriting a file that is loaded in another buffer is not a
+#. * good idea.
+msgid "E139: File is loaded in another buffer"
+msgstr "E139: ±z¦b¥t¤@­Ó½w½Ä°Ï¤]¸ü¤J¤F³o­ÓÀÉ®×"
+
+msgid "Write partial file?"
+msgstr "­n¼g¤J³¡¤ÀÀÉ®×¶Ü¡H"
+
+msgid "E140: Use ! to write partial buffer"
+msgstr "E140: ½Ð¨Ï¥Î ! ¥H¼g¤J³¡¤À½w½Ä°Ï"
+
+#, c-format
+msgid "Overwrite existing file \"%.*s\"?"
+msgstr "­nÂмg¤w¦s¦bªºÀÉ®× \"%.*s\"¡H"
+
+#, c-format
+msgid "E141: No file name for buffer %ld"
+msgstr "E141: ½w½Ä°Ï %ld ¨S¦³ÀɮצWºÙ"
+
+msgid "E142: File not written: Writing is disabled by 'write' option"
+msgstr "E142: ÀÉ®×¥¼¼g¤J¡A¦]¬° 'write' ¿ï¶µ³QÃö³¬"
+
+#, 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"
+
+msgid "Edit File"
+msgstr "½s¿èÀÉ®×"
+
+#, c-format
+msgid "E143: Autocommands unexpectedly deleted new buffer %s"
+msgstr "E143: Autocommands ·N¥~¦a§R°£·s½w½Ä°Ï %s"
+
+msgid "E144: non-numeric argument to :z"
+msgstr "E144: :z ¤£±µ¨ü«D¼Æ¦rªº°Ñ¼Æ"
+
+msgid "E145: Shell commands not allowed in rvim"
+msgstr "E145: rvim ¤¤¸T¤î¨Ï¥Î shell ©R¥O"
+
+msgid "E146: Regular expressions can't be delimited by letters"
+msgstr "E146: Regular expression µLªk¥Î¦r¥À¤À¹j (?)"
+
+#, c-format
+msgid "replace with %s (y/n/a/q/l/^E/^Y)?"
+msgstr "¨ú¥N¬° %s (y/n/a/q/^E/^Y)?"
+
+msgid "(Interrupted) "
+msgstr "(¤w¤¤Â_) "
+
+msgid "1 substitution"
+msgstr "¨ú¥N¤@²Õ "
+
+#, c-format
+msgid "%ld substitutions"
+msgstr "¨ú¥N %ld ²Õ "
+
+msgid " on 1 line"
+msgstr "¡A½d³ò¡G¤@¦æ "
+
+#, c-format
+msgid " on %ld lines"
+msgstr "¡A½d³ò¡G %ld ¦æ "
+
+msgid "E147: Cannot do :global recursive"
+msgstr "E147: :global µLªk»¼°j°õ¦æ "
+
+msgid "E148: Regular expression missing from global"
+msgstr "E148: ¨S¦³¨Ï¥Î¹L Regular expression (?)"
+
+#, c-format
+msgid "Pattern found in every line: %s"
+msgstr "¨C¤@¦æ³£§ä¤£¨ì: %s"
+
+#, c-format
+msgid ""
+"\n"
+"# Last Substitute String:\n"
+"$"
+msgstr ""
+"\n"
+"# «e¤@²Õ´À¥N¦r¦ê:\n"
+"$"
+
+msgid "E478: Don't panic!"
+msgstr "E478: ¤£­nÅå·W!"
+
+#, c-format
+msgid "E661: Sorry, no '%s' help for %s"
+msgstr "E661: ©êºp, ¨S¦³Ãö©ó %s-%s ªº»¡©ú"
+
+#, c-format
+msgid "E149: Sorry, no help for %s"
+msgstr "E149: ©êºp, ¨S¦³ %s ªº»¡©ú"
+
+#, c-format
+msgid "Sorry, help file \"%s\" not found"
+msgstr "©êºp, §ä¤£¨ì»¡©úÀÉ \"%s\""
+
+#, c-format
+msgid "E150: Not a directory: %s"
+msgstr "E150: %s ¤£¬O¥Ø¿ý"
+
+#, c-format
+msgid "E152: Cannot open %s for writing"
+msgstr "E152: µLªk¥H¼g¤J¼Ò¦¡¶}±Ò \"%s\""
+
+#, c-format
+msgid "E153: Unable to open %s for reading"
+msgstr "E153: µLªkŪ¨úÀÉ®×: %s"
+
+#, c-format
+msgid "E670: Mix of help file encodings within a language: %s"
+msgstr "E670: ¦P¤@»y¨¥ (%s) ¤¤¦³²V¦X¤£¦P¦r¤¸½s½Xªº»¡©úÀÉ"
+
+#, c-format
+msgid "E154: Duplicate tag \"%s\" in file %s"
+msgstr "E154: ¼ÐÅÒ(tag) \"%s\" ¦bÀÉ®× %s ¸Ì­«½Æ¥X²{¦h¦¸"
+
+#, c-format
+msgid "E160: Unknown sign command: %s"
+msgstr "E160: ¥¼©w¸qªº sign command: %s"
+
+msgid "E156: Missing sign name"
+msgstr "E156: ¯Ê¤Ö sign ¦WºÙ"
+
+msgid "E612: Too many signs defined"
+msgstr "E612: ¤w©w¸q¤Ó¦h signs"
+
+#, c-format
+msgid "E239: Invalid sign text: %s"
+msgstr "E239: ¤£¥¿½Tªº sign ¤å¦r: %s"
+
+#, c-format
+msgid "E155: Unknown sign: %s"
+msgstr "E155: ¤£¥¿½Tªº sign: %s"
+
+msgid "E159: Missing sign number"
+msgstr "E159: ¯Ê¤Ö sign number"
+
+#, c-format
+msgid "E158: Invalid buffer name: %s"
+msgstr "E158: ½w½Ä°Ï¦WºÙ¿ù»~: %s"
+
+#, c-format
+msgid "E157: Invalid sign ID: %ld"
+msgstr "E157: Sign ID ¿ù»~: %ld"
+
+msgid " (NOT FOUND)"
+msgstr " (§ä¤£¨ì) "
+
+msgid " (not supported)"
+msgstr " (¤£¤ä´©) "
+
+msgid "[Deleted]"
+msgstr "[¤w§R°£]"
+
+msgid "Entering Debug mode. Type \"cont\" to continue."
+msgstr "¶i¤J°£¿ù¼Ò¦¡. ¿é¤J \"cont\" ¥H¦^¨ì¥¿±`¼Ò¦¡."
+
+#, c-format
+msgid "line %ld: %s"
+msgstr "¦æ %ld: %s"
+
+#, c-format
+msgid "cmd: %s"
+msgstr "cmd: %s"
+
+#, c-format
+msgid "Breakpoint in \"%s%s\" line %ld"
+msgstr "\"%s%s\" ¤¤Â_ÂI: ²Ä %ld ¦æ "
+
+#, c-format
+msgid "E161: Breakpoint not found: %s"
+msgstr "E161: §ä¤£¨ì¤¤Â_ÂI: %s"
+
+msgid "No breakpoints defined"
+msgstr "¨S¦³©w¸q¤¤Â_ÂI"
+
+#, c-format
+msgid "%3d %s %s line %ld"
+msgstr "%3d %s %s ²Ä %ld ¦æ "
+
+#, c-format
+msgid "Save changes to \"%.*s\"?"
+msgstr "±NÅܰʦsÀx¦Ü \"%.*s\"?"
+
+msgid "Untitled"
+msgstr "¥¼©R¦W"
+
+#, c-format
+msgid "E162: No write since last change for buffer \"%s\""
+msgstr "E162: ¤w§ó§ï¹L½w½Ä°Ï \"%s\" ¦ý©|¥¼¦sÀÉ (¥i¥Î ! ±j¨î°õ¦æ)"
+
+msgid "Warning: Entered other buffer unexpectedly (check autocommands)"
+msgstr "ª`·N: ¤w¤Á´«¨ì¨ä¥¦½w½Ä°Ï (½ÐÀˬd Autocommands ¦³µL¿ù»~)"
+
+msgid "E163: There is only one file to edit"
+msgstr "E163: ¥u¦³¤@­ÓÀÉ®×¥i½s¿è"
+
+msgid "E164: Cannot go before first file"
+msgstr "E164: ¤w¸g¦b²Ä¤@­ÓÀɮפF"
+
+msgid "E165: Cannot go beyond last file"
+msgstr "E165: ¤w¸g¦b³Ì«á¤@­ÓÀɮפF"
+
+#, c-format
+msgid "E666: compiler not supported: %s"
+msgstr "E666: ½s;¹¤£¤ä´©: %s"
+
+#, c-format
+msgid "Searching for \"%s\" in \"%s\""
+msgstr "·j´M¤¤: \"%s\" -- \"%s\""
+
+#, c-format
+msgid "Searching for \"%s\""
+msgstr "·j´M¤¤: \"%s\""
+
+#, c-format
+msgid "not found in 'runtimepath': \"%s\""
+msgstr "¦b 'runtimepath' ¸Ì§ä¤£¨ì \"%s\""
+
+msgid "Source Vim script"
+msgstr "°õ¦æ Vim script"
+
+#, c-format
+msgid "Cannot source a directory: \"%s\""
+msgstr "µLªk°õ¦æ¥Ø¿ý¡G \"%s\""
+
+#, c-format
+msgid "could not source \"%s\""
+msgstr "µLªk°õ¦æ \"%s\""
+
+#, c-format
+msgid "line %ld: could not source \"%s\""
+msgstr "²Ä %ld ¦æ: µLªk°õ¦æ \"%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"
+
+msgid "W15: Warning: Wrong line separator, ^M may be missing"
+msgstr "W15: ª`·N: ¿ù»~ªº¦æ¤À¹j¦r¤¸¡A¥i¯à¬O¤Ö¤F ^M"
+
+msgid "E167: :scriptencoding used outside of a sourced file"
+msgstr "E167: ¦b°õ¦æ script ÀÉ®×¥~¤£¥i¨Ï¥Î :scriptencoding"
+
+msgid "E168: :finish used outside of a sourced file"
+msgstr "E168: ¦b°õ¦æ script ÀÉ®×¥~¤£¥i¨Ï¥Î :finish"
+
+#, c-format
+msgid "Page %d"
+msgstr "²Ä %d ­¶"
+
+msgid "No text to be printed"
+msgstr "¨S¦³­n¦C¦Lªº¤å¦r"
+
+#, c-format
+msgid "Printing page %d (%d%%)"
+msgstr "¦C¦L¤¤: ²Ä %d ­¶ (%d%%)"
+
+#, c-format
+msgid " Copy %d of %d"
+msgstr "½Æ»s %d / %d"
+
+#, c-format
+msgid "Printed: %s"
+msgstr "¤w¦C¦L: %s"
+
+#, c-format
+msgid "Printing aborted"
+msgstr "¤w¨ú®ø¦C¦L"
+
+msgid "E455: Error writing to PostScript output file"
+msgstr "E455: µLªk¼g¤J PostScript ¿é¥XÀÉ"
+
+#, c-format
+msgid "E624: Can't open file \"%s\""
+msgstr "E624: µLªk¶}±ÒÀÉ®× \"%s\""
+
+#, c-format
+msgid "E457: Can't read PostScript resource file \"%s\""
+msgstr "E457: µLªkŪ¨ú PostScript ¸ê·½ÀÉ \"%s\""
+
+#, c-format
+msgid "E618: file \"%s\" is not a PostScript resource file"
+msgstr "E618: ÀÉ®× \"%s\" ¤£¬O PostScript ¸ê·½ÀÉ "
+
+#, c-format
+msgid "E619: file \"%s\" is not a supported PostScript resource file"
+msgstr "E619: ¤£¤ä´© PostScript ¸ê·½ÀÉ \"%s\""
+
+#, c-format
+msgid "E621: \"%s\" resource file has wrong version"
+msgstr "E621: \"%s\" ¸ê·½Àɪ©¥»¿ù»~"
+
+msgid "E324: Can't open PostScript output file"
+msgstr "E324: µLªk¶}±Ò PostScript ¿é¥XÀÉ"
+
+#, c-format
+msgid "E456: Can't open file \"%s\""
+msgstr "E456: µLªk¶}±ÒÀÉ®× \"%s\""
+
+msgid "E456: Can't find PostScript resource file \"prolog.ps\""
+msgstr "E456: µLªkŪ¨ú PostScript ¸ê·½ÀÉ \"prolog.ps\""
+
+#, c-format
+msgid "E456: Can't find PostScript resource file \"%s.ps\""
+msgstr "E456: µLªkŪ¨ú PostScript ¸ê·½ÀÉ \"%s.ps\""
+
+#, c-format
+msgid "E620: Unable to convert from multi-byte to \"%s\" encoding"
+msgstr "E620:µLªkÂà´«¦Ü \"%s\" ¦r¤¸½s½X"
+
+msgid "Sending to printer..."
+msgstr "¶Ç°e¸ê®Æ¨ì¦Lªí¾÷..."
+
+msgid "E365: Failed to print PostScript file"
+msgstr "E365: µLªk¦C¦L PostScript ÀÉ®×"
+
+msgid "Print job sent."
+msgstr "¤w°e¥X¦C¦L¤u§@¡C"
+
+#, c-format
+msgid "Current %slanguage: \"%s\""
+msgstr "¥Ø«eªº %s»y¨¥: \"%s\""
+
+#, c-format
+msgid "E197: Cannot set language to \"%s\""
+msgstr "E197: ¤£¯à³]©w»y¨¥¦¨ \"%s\""
+
+msgid "Entering Ex mode. Type \"visual\" to go to Normal mode."
+msgstr "¶i¤J Ex ¼Ò¦¡. ¿é¤J \"visua\" ¥H¦^¨ì¥¿±`¼Ò¦¡."
+
+#. must be at EOF
+msgid "E501: At end-of-file"
+msgstr "E501: ¤w¨ìÀÉ®×µ²§À"
+
+msgid "E169: Command too recursive"
+msgstr "E169: ©R¥O»¼°j¼h¼Æ¹L¦h"
+
+#, c-format
+msgid "E605: Exception not caught: %s"
+msgstr "E605: ¥¼ÄdºIªº¨Ò¥~¡G %s"
+
+msgid "End of sourced file"
+msgstr "©R¥OÀɵ²§ô"
+
+msgid "End of function"
+msgstr "¨ç¦¡µ²§À"
+
+msgid "E464: Ambiguous use of user-defined command"
+msgstr "E464: ¨Ï¥ÎªÌ©w¸qªº©R¥O·|²V²c"
+
+msgid "E492: Not an editor command"
+msgstr "E492: ¤£¬O½s¿è¾¹ªº©R¥O"
+
+msgid "E493: Backwards range given"
+msgstr "E493: «ü©w¤F¦V«e°Ñ¦Òªº½d³ò"
+
+msgid "Backwards range given, OK to swap"
+msgstr "«ü©w¤F¦V«e°Ñ¦Òªº½d³ò¡AOK to swap"
+
+msgid "E494: Use w or w>>"
+msgstr "E494: ½Ð¨Ï¥Î w ©Î w>>"
+
+msgid "E319: Sorry, the command is not available in this version"
+msgstr "E319: ©êºp, ¥»©R¥O¦b¦¹ª©¥»¤¤¨S¦³¹ê§@"
+
+msgid "E172: Only one file name allowed"
+msgstr "E172: ¥u¯à¦³¤@­ÓÀÉ"
+
+msgid "1 more file to edit. Quit anyway?"
+msgstr "ÁÙ¦³¤@­ÓÀÉ®×¥¼½s¿è. ½T©w­nÂ÷¶}¡H"
+
+#, c-format
+msgid "%d more files to edit. Quit anyway?"
+msgstr "ÁÙ¦³ %d ­ÓÀÉ®×¥¼½s¿è. ½T©w­nÂ÷¶}¡H"
+
+msgid "E173: 1 more file to edit"
+msgstr "E173: ÁÙ¦³¤@­ÓÀÉ®×¥¼½s¿è "
+
+#, c-format
+msgid "E173: %ld more files to edit"
+msgstr "E173: ÁÙ¦³ %ld ­ÓÀÉ®×¥¼½s¿è"
+
+msgid "E174: Command already exists: add ! to replace it"
+msgstr "E174: ©R¥O¤w¸g¦s¦b, ½Ð¨Ï¥Î ! ±j¨î­«·s©w¸q"
+
+msgid ""
+"\n"
+" Name Args Range Complete Definition"
+msgstr ""
+"\n"
+" ¦WºÙ °Ñ¼Æ ½d³ò §¹¾ã ©w¸q "
+
+msgid "No user-defined commands found"
+msgstr "§ä¤£¨ì¨Ï¥ÎªÌ©w¸qªº©R¥O"
+
+msgid "E175: No attribute specified"
+msgstr "E175: ¨S¦³«ü©wªºÄÝ©Ê"
+
+msgid "E176: Invalid number of arguments"
+msgstr "E176: ¤£¥¿½Tªº°Ñ¼Æ¼Æ¥Ø"
+
+msgid "E177: Count cannot be specified twice"
+msgstr "E177: ¤£¯à«ü©w¨â¦¸¼Æ¥Ø"
+
+msgid "E178: Invalid default value for count"
+msgstr "E178: ¼Æ¥Øªº¹w³]°Ñ¼Æ¤£¥¿½T"
+
+msgid "E179: argument required for complete"
+msgstr "E179: «ü¥O»Ý­n°Ñ¼Æ¤~¯à§¹¦¨"
+
+#, c-format
+msgid "E180: Invalid complete value: %s"
+msgstr "E180: ¤£§¹¾ãªº­È: '%s'"
+
+msgid "E468: Completion argument only allowed for custom completion"
+msgstr "E468: ¦Û­q¸É§¹®É¤~¥i¸É§¹°Ñ¼Æ"
+
+msgid "E467: Custom completion requires a function argument"
+msgstr "E467: ¦Û­q¸É§¹»Ý­n¨ç¦¡¬°°Ñ¼Æ"
+
+#, c-format
+msgid "E181: Invalid attribute: %s"
+msgstr "E181: ¤£¥¿½TªºÄÝ©Ê: %s"
+
+msgid "E182: Invalid command name"
+msgstr "E182: «ü¥O¦WºÙ¤£¥¿½T"
+
+msgid "E183: User defined commands must start with an uppercase letter"
+msgstr "E183: ¨Ï¥ÎªÌ¦Û©w«ü¥O¥²¶·¥H¤j¼g¦r¥À¶}©l"
+
+#, c-format
+msgid "E184: No such user-defined command: %s"
+msgstr "E184: ¨S¦³¨Ï¥ÎªÌ¦Û©wªº©R¥O¡G %s"
+
+#, c-format
+msgid "E185: Cannot find color scheme %s"
+msgstr "E185: §ä¤£¨ìÃC¦â¼Ë¦¡ %s"
+
+msgid "Greetings, Vim user!"
+msgstr "¶Ù, Vim ¨Ï¥ÎªÌ¡I"
+
+msgid "Edit File in new window"
+msgstr "¦b·sµøµ¡½s¿èÀÉ®×"
+
+msgid "No swap file"
+msgstr "µL¼È¦sÀÉ"
+
+msgid "Append File"
+msgstr "ªþ¥[ÀÉ®×"
+
+msgid "E186: No previous directory"
+msgstr "E186: ¨S¦³«e¤@­Ó¥Ø¿ý"
+
+msgid "E187: Unknown"
+msgstr "E187: µLªk¿ìÃѪº¼Ð°O"
+
+msgid "E465: :winsize requires two number arguments"
+msgstr "E465: :winsize »Ý­n¨â­Ó°Ñ¼Æ"
+
+#, c-format
+msgid "Window position: X %d, Y %d"
+msgstr "µøµ¡¦ì¸m: X %d, Y %d"
+
+msgid "E188: Obtaining window position not implemented for this platform"
+msgstr "E188: ¦b±zªº¥­¥x¤WµLªkÀò±oµøµ¡¦ì¸m"
+
+msgid "E466: :winpos requires two number arguments"
+msgstr "E466: :winpos »Ý­n¨â­Ó°Ñ¼Æ"
+
+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"
+
+#, c-format
+msgid "E189: \"%s\" exists (add ! to override)"
+msgstr "E189: \"%s\" ¤w¦s¦b (½Ð¥Î ! ±j¨î°õ¦æ)"
+
+#, c-format
+msgid "E190: Cannot open \"%s\" for writing"
+msgstr "E190: µLªk¥H¼g¤J¼Ò¦¡¶}±Ò \"%s\""
+
+#. set mark
+msgid "E191: Argument must be a letter or forward/backward quote"
+msgstr "E191: °Ñ¼Æ¥²¶·¬O­^¤å¦r¥À©Î¦V«e/«áªº¤Þ¸¹"
+
+msgid "E192: Recursive use of :normal too deep"
+msgstr "E192: :normal »¼°j¼h¼Æ¹L²`"
+
+msgid "E194: No alternate file name to substitute for '#'"
+msgstr "E194: ¨S¦³ '#' ¥i´À¥NªºÀɦW"
+
+msgid "E495: no autocommand file name to substitute for \"<afile>\""
+msgstr "E495: ¨S¦³ Autocommand ÀɦW¥H¨ú¥N \"<afile>\""
+
+msgid "E496: no autocommand buffer number to substitute for \"<abuf>\""
+msgstr "E496: ¨S¦³ Autocommand ½w½Ä°Ï¦WºÙ¥H¨ú¥N \"<abuf>\""
+
+msgid "E497: no autocommand match name to substitute for \"<amatch>\""
+msgstr "E497: ¨S¦³ Autocommand ²Å¦X¦WºÙ¥H¨ú¥N \"<amatch>\""
+
+msgid "E498: no :source file name to substitute for \"<sfile>\""
+msgstr "E498: ¨S¦³ :source ÀɦW¥H¨ú¥N \"<sfile>\""
+
+#, no-c-format
+msgid "E499: Empty file name for '%' or '#', only works with \":p:h\""
+msgstr "E499: '%' ©Î '#' «ü¦VªÅÀɦW¡A¥u¯à¥Î©ó \":p:h\""
+
+msgid "E500: Evaluates to an empty string"
+msgstr "E500: ¿é¤J¬°ªÅ¦r¦ê"
+
+msgid "E195: Cannot open viminfo file for reading"
+msgstr "E195: µLªkŪ¨ú viminfo"
+
+msgid "E196: No digraphs in this version"
+msgstr "E196: ¥»ª©¥»µL½Æ¦X¦r¤¸(digraph)"
+
+msgid "E608: Cannot :throw exceptions with 'Vim' prefix"
+msgstr "E608: ¤£¯à :throw ¥Î 'Vim' ¶}ÀYªº¨Ò¥~"
+
+#. always scroll up, don't overwrite
+#, c-format
+msgid "Exception thrown: %s"
+msgstr "¥á¥X¨Ò¥~¡G %s"
+
+#, c-format
+msgid "Exception finished: %s"
+msgstr "¨Ò¥~µ²§ô¡G %s"
+
+#, c-format
+msgid "Exception discarded: %s"
+msgstr "¤w¥á±ó¨Ò¥~¡G %s"
+
+#, c-format
+msgid "%s, line %ld"
+msgstr "%s, ¦æ %ld"
+
+#. always scroll up, don't overwrite
+#, c-format
+msgid "Exception caught: %s"
+msgstr "µo¥Í¨Ò¥~¡G%s"
+
+#, c-format
+msgid "%s made pending"
+msgstr "%s ³y¦¨ pending"
+
+#, c-format
+msgid "%s resumed"
+msgstr "%s ¤w¦^´_"
+
+#, c-format
+msgid "%s discarded"
+msgstr "%s ¤w¥á±ó"
+
+msgid "Exception"
+msgstr "¨Ò¥~"
+
+msgid "Error and interrupt"
+msgstr "¿ù»~»P¤¤Â_"
+
+msgid "Error"
+msgstr "¿ù»~"
+
+#. if (pending & CSTP_INTERRUPT)
+msgid "Interrupt"
+msgstr "¤¤Â_"
+
+msgid "E579: :if nesting too deep"
+msgstr "E579: :if ¼h¼Æ¹L²`"
+
+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: ¦h­« :else"
+
+msgid "E584: :elseif after :else"
+msgstr "E584: :elseif ¦b :else ¤§«á"
+
+msgid "E585: :while nesting too deep"
+msgstr "E585: :while ¼h¼Æ¹L²`"
+
+msgid "E586: :continue without :while"
+msgstr "E586: :continue ¯Ê¤Ö¹ïÀ³ªº :while"
+
+msgid "E587: :break without :while"
+msgstr "E587: :break ¯Ê¤Ö¹ïÀ³ªº :while"
+
+msgid "E601: :try nesting too deep"
+msgstr "E601: :if ¼h¼Æ¹L²`"
+
+msgid "E603: :catch without :try"
+msgstr "E603: :catch ¨S¦³ :try"
+
+#. Give up for a ":catch" after ":finally" and ignore it.
+#. * Just parse.
+msgid "E604: :catch after :finally"
+msgstr "E604: :catch ¦b :finally ¤§«á"
+
+msgid "E606: :finally without :try"
+msgstr "E606: :finally ¨S¦³ :try"
+
+#. Give up for a multiple ":finally" and ignore it.
+msgid "E607: multiple :finally"
+msgstr "E607: ¦h­« :finally"
+
+msgid "E602: :endtry without :try"
+msgstr "E602: :endif ¯Ê¤Ö¹ïÀ³ªº :if"
+
+msgid "E193: :endfunction not inside a function"
+msgstr "E193: :endfunction ¥²¶·¦b¨ç¦¡¤º³¡¨Ï¥Î"
+
+msgid "tagname"
+msgstr "¼ÐÅÒ¦WºÙ"
+
+msgid " kind file\n"
+msgstr "ÃþÀÉ®×\n"
+
+msgid "'history' option is zero"
+msgstr "¿ï¶µ 'history' ¬O¹s"
+
+#, c-format
+msgid ""
+"\n"
+"# %s History (newest to oldest):\n"
+msgstr ""
+"\n"
+"# %s ¾ú¥v°O¿ý (·s¨ìÂÂ):\n"
+
+msgid "Command Line"
+msgstr "©R¥O¦C"
+
+msgid "Search String"
+msgstr "·j´M¦r¦ê"
+
+msgid "Expression"
+msgstr "¹Bºâ¦¡"
+
+msgid "Input Line"
+msgstr "¿é¤J¦æ "
+
+msgid "E198: cmd_pchar beyond the command length"
+msgstr "E198: cmd_pchar ¶W¹L©R¥Oªø«×"
+
+msgid "E199: Active window or buffer deleted"
+msgstr "E199: ¤w§R°£±¼§@¥Î¤¤ªºµøµ¡©Î¼È¦s°Ï"
+
+msgid "Illegal file name"
+msgstr "¤£¥¿½TªºÀɦW"
+
+msgid "is a directory"
+msgstr "¬O¥Ø¿ý"
+
+msgid "is not a file"
+msgstr "¤£¬OÀÉ®×"
+
+msgid "[New File]"
+msgstr "[¥¼©R¦W]"
+
+msgid "[Permission Denied]"
+msgstr "[Åv­­¤£¨¬]"
+
+msgid "E200: *ReadPre autocommands made the file unreadable"
+msgstr "E200: *ReadPre Autocommand ¨Ïµ{¦¡µLªkŪ¨ú¦¹ÀÉ"
+
+msgid "E201: *ReadPre autocommands must not change current buffer"
+msgstr "E201: *Filter* Autocommand ¤£¥i¥H§ó§ï½w½Ä°Ïªº¤º®e"
+
+msgid "Vim: Reading from stdin...\n"
+msgstr "Vim: ±q¼Ð·Ç¿é¤JŪ¨ú...\n"
+
+msgid "Reading from stdin..."
+msgstr "±q¼Ð·Ç¿é¤JŪ¨ú..."
+
+#. Re-opening the original file failed!
+msgid "E202: Conversion made file unreadable!"
+msgstr "E202: Âà´«¿ù»~"
+
+msgid "[fifo/socket]"
+msgstr "[fifo/socket]"
+
+msgid "[fifo]"
+msgstr "[fifo]"
+
+msgid "[socket]"
+msgstr "[socket]"
+
+msgid "[RO]"
+msgstr "[°ßŪ]"
+
+msgid "[CR missing]"
+msgstr "[¯Ê¤ÖCR]'"
+
+msgid "[NL found]"
+msgstr "[§ä¨ìNL]"
+
+msgid "[long lines split]"
+msgstr "[¤À³Î¹Lªø¦æ]"
+
+msgid "[NOT converted]"
+msgstr "[¥¼Âà´«]"
+
+msgid "[converted]"
+msgstr "[¤wÂà´«]"
+
+msgid "[crypted]"
+msgstr "[¤w¥[±K]"
+
+msgid "[CONVERSION ERROR]"
+msgstr "Âà´«¿ù»~"
+
+#, c-format
+msgid "[ILLEGAL BYTE in line %ld]"
+msgstr "[¦æ %ld ¦³¤£¥¿½Tªº¦ì¤¸]"
+
+msgid "[READ ERRORS]"
+msgstr "[Ū¨ú¿ù»~]"
+
+msgid "Can't find temp file for conversion"
+msgstr "§ä¤£¨ìÂà´«¥Îªº¼È¦sÀÉ"
+
+msgid "Conversion with 'charconvert' failed"
+msgstr "¦r¤¸¶°Âà´«¿ù»~"
+
+msgid "can't read output of 'charconvert'"
+msgstr "µLªkŪ¨ú 'charconvert' ªº¿é¥X"
+
+msgid "E203: Autocommands deleted or unloaded buffer to be written"
+msgstr "E203: Autocommand §R°£©ÎÄÀ©ñ¤F­n¼g¤Jªº½w½Ä°Ï"
+
+msgid "E204: Autocommand changed number of lines in unexpected way"
+msgstr "E204: Autocommand ·N¥~¦a§ïÅܤF¦æ¸¹"
+
+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 "is not a file or writable device"
+msgstr "¤£¬OÀɮשΥi¼g¤Jªº¸Ë¸m"
+
+msgid "is read-only (add ! to override)"
+msgstr "¬O°ßŪÀÉ (½Ð¨Ï¥Î ! ±j¨î°õ¦æ)"
+
+msgid "E506: Can't write to backup file (add ! to override)"
+msgstr "E506: µLªk¼g¤J³Æ¥÷ÀÉ (½Ð¨Ï¥Î ! ±j¨î°õ¦æ)"
+
+msgid "E507: Close error for backup file (add ! to override)"
+msgstr "E507: µLªkÃö³¬³Æ¥÷ÀÉ (½Ð¨Ï¥Î ! ±j¨î°õ¦æ)"
+
+msgid "E508: Can't read file for backup (add ! to override)"
+msgstr "E508: µLªkŪ¨úÀÉ®×¥H¨Ñ³Æ¥÷ (½Ð¨Ï¥Î ! ±j¨î°õ¦æ)"
+
+msgid "E509: Cannot create backup file (add ! to override)"
+msgstr "E509: µLªk«Ø¥ß³Æ¥÷ÀÉ (½Ð¨Ï¥Î ! ±j¨î°õ¦æ)"
+
+msgid "E510: Can't make backup file (add ! to override)"
+msgstr "E510: µLªk»s§@³Æ¥÷ÀÉ (½Ð¨Ï¥Î ! ±j¨î°õ¦æ)"
+
+msgid "E460: The resource fork would be lost (add ! to override)"
+msgstr "E460: Resource fork ·|®ø¥¢ (½Ð¨Ï¥Î ! ±j¨î°õ¦æ)"
+
+msgid "E214: Can't find temp file for writing"
+msgstr "E214: §ä¤£¨ì¼g¤J¥Îªº¼È¦sÀÉ"
+
+msgid "E213: Cannot convert (add ! to write without conversion)"
+msgstr "E213: µLªkÂà´« (½Ð¨Ï¥Î ! ±j¨î¤£Âà´«¼g¤J)"
+
+msgid "E166: Can't open linked file for writing"
+msgstr "E166: µLªk¥H¼g¤J¼Ò¦¡¶}±Ò³sµ²ÀÉ®×"
+
+msgid "E212: Can't open file for writing"
+msgstr "E212: µLªk¥H¼g¤J¼Ò¦¡¶}±Ò"
+
+msgid "E667: Fsync failed"
+msgstr "E667: Fsync ©R¥O°õ¦æ¥¢±Ñ"
+
+msgid "E512: Close failed"
+msgstr "E512: Ãö³¬¥¢±Ñ"
+
+msgid "E513: write error, conversion failed"
+msgstr "E513: µLªk¼g¤J -- Âà´«¥¢±Ñ"
+
+msgid "E514: write error (file system full?)"
+msgstr "E514: ¼g¤J¿ù»~ (Àɮרt²Î¤wº¡¡H)"
+
+msgid " CONVERSION ERROR"
+msgstr "Âà´«¿ù»~"
+
+msgid "[Device]"
+msgstr "[¸Ë¸m]"
+
+msgid "[New]"
+msgstr "[·s]"
+
+msgid " [a]"
+msgstr "[a]"
+
+msgid " appended"
+msgstr " ¤wªþ¥["
+
+msgid " [w]"
+msgstr "[w]"
+
+msgid " written"
+msgstr " ¤w¼g¤J"
+
+msgid "E205: Patchmode: can't save original file"
+msgstr "E205: Patch ¼Ò¦¡: µLªkÀx¦s­ì©lÀÉ®×"
+
+msgid "E206: patchmode: can't touch empty original file"
+msgstr "E206: Patch ¼Ò¦¡: µLªkÅܧóªÅªº­ì©lÀÉ®×"
+
+msgid "E207: Can't delete backup file"
+msgstr "E207: µLªk§R°£³Æ¥÷ÀÉ"
+
+msgid ""
+"\n"
+"WARNING: Original file may be lost or damaged\n"
+msgstr ""
+"\n"
+"ĵ§i: ­ì©lÀɮ׬y¥¢©Î·lÃa\n"
+
+msgid "don't quit the editor until the file is successfully written!"
+msgstr "¦bÀÉ®×¥¿½T¼g¤J«e½Ð¤ÅÂ÷¶}½s¿è¾¹!"
+
+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 "¤@­Ó¦r¤¸"
+
+#, c-format
+msgid "%ld characters"
+msgstr "%ld­Ó¦r¤¸"
+
+msgid "[noeol]"
+msgstr "[noeol]"
+
+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
+msgid "WARNING: The file has been changed since reading it!!!"
+msgstr "ĵ§i: ¥»ÀɮצۤW¦¸Åª¤J«á¤wÅܰÊ!!!"
+
+msgid "Do you really want to write to it"
+msgstr "½T©w­n¼g¤J¶Ü"
+
+#, c-format
+msgid "E208: Error writing to \"%s\""
+msgstr "E208: ¼g¤JÀÉ®× \"%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 autocommand §R°£½w½Ä°Ï"
+
+#, c-format
+msgid "E211: Warning: File \"%s\" no longer available"
+msgstr "E211: ĵ§i: ÀÉ®× \"%s\" ¤w¸g¤£¦s¦b"
+
+#, 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"
+
+#, c-format
+msgid "W11: Warning: File \"%s\" has changed since editing started"
+msgstr "W11: ĵ§i: ÀÉ®× \"%s\" ¦Û¤W¦¸Åª¤J«á¤wÅܰÊ"
+
+#, c-format
+msgid "W16: Warning: Mode of file \"%s\" has changed since editing started"
+msgstr "W16: ĵ§i: ÀÉ®× \"%s\" ªºÅv­­»P¤W¦¸Åª¤J®É¤£¤@¼Ë (¦³ÅܰʹL)"
+
+# 'mode' seems better as translated to 'permission'?
+#, c-format
+msgid "W13: Warning: File \"%s\" has been created after editing started"
+msgstr "W13: ĵ§i: ÀÉ®× \"%s\" ¦b¶}©l½s¿è«á¤S³Q«Ø¥ß¤F"
+
+msgid "See \":help W11\" for more info."
+msgstr "¶i¤@¨B»¡©ú½Ð¨£ \":help W11\"¡C"
+
+msgid "Warning"
+msgstr "ĵ§i"
+
+msgid ""
+"&OK\n"
+"&Load File"
+msgstr ""
+"½T©w(&O)\n"
+"¸ü¤JÀÉ®×(&L)"
+
+#, c-format
+msgid "E462: Could not prepare for reloading \"%s\""
+msgstr "E462: µLªk·Ç³Æ­«·s¸ü¤J \"%s\""
+
+#, c-format
+msgid "E321: Could not reload \"%s\""
+msgstr "E321: µLªk­«·s¸ü¤J \"%s\""
+
+msgid "--Deleted--"
+msgstr "--¤w§R°£--"
+
+#. the group doesn't exist
+#, c-format
+msgid "E367: No such group: \"%s\""
+msgstr "E367: µL¦¹¸s²Õ: \"%s\""
+
+#, c-format
+msgid "E215: Illegal character after *: %s"
+msgstr "E215: * «á­±¦³¤£¥¿½Tªº¦r¤¸: %s"
+
+#, c-format
+msgid "E216: No such event: %s"
+msgstr "E216: µL¦¹¨Æ¥ó: %s"
+
+#, c-format
+msgid "E216: No such group or event: %s"
+msgstr "E216: µL¦¹¸s²Õ©Î¨Æ¥ó: %s"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Auto-Commands ---"
+msgstr ""
+"\n"
+"--- Auto-Commands ---"
+
+msgid "E217: Can't execute autocommands for ALL events"
+msgstr "E217: µLªk¹ï©Ò¦³¨Æ¥ó°õ¦æ autocommand"
+
+msgid "No matching autocommands"
+msgstr "§ä¤£¨ì¹ïÀ³ªº autocommand"
+
+msgid "E218: autocommand nesting too deep"
+msgstr "E218: autocommand ¼h¼Æ¹L²`"
+
+#, c-format
+msgid "%s Auto commands for \"%s\""
+msgstr "%s Auto commands: \"%s\""
+
+#, c-format
+msgid "Executing %s"
+msgstr "°õ¦æ %s"
+
+#. always scroll up, don't overwrite
+#, c-format
+msgid "autocommand %s"
+msgstr "autocommand %s"
+
+msgid "E219: Missing {."
+msgstr "E219: ¯Ê¤Ö {."
+
+msgid "E220: Missing }."
+msgstr "E220: ¯Ê¤Ö }."
+
+msgid "E490: No fold found"
+msgstr "E490: §ä¤£¨ì¥ô¦ó fold"
+
+msgid "E350: Cannot create fold with current 'foldmethod'"
+msgstr "E350: µLªk¦b¥Ø«eªº 'foldmethod' ¤U«Ø¥ß fold"
+
+msgid "E351: Cannot delete fold with current 'foldmethod'"
+msgstr "E351: µLªk¦b¥Ø«eªº 'foldmethod' ¤U§R°£ fold"
+
+msgid "E222: Add to read buffer"
+msgstr "E222: ¥[¤JŪ¨ú½w½Ä°Ï¤¤"
+
+msgid "E223: recursive mapping"
+msgstr "E223: »¼°j mapping"
+
+#, c-format
+msgid "E224: global abbreviation already exists for %s"
+msgstr "E224: %s ¤w¸g¦³¥þ°ì abbreviation ¤F"
+
+#, c-format
+msgid "E225: global mapping already exists for %s"
+msgstr "E225: %s ¤w¸g¦³¥þ°ì mapping ¤F"
+
+#, c-format
+msgid "E226: abbreviation already exists for %s"
+msgstr "E226: %s ¤w¸g¦³ abbreviation ¤F"
+
+#, c-format
+msgid "E227: mapping already exists for %s"
+msgstr "E227: %s ªº mapping ¤w¸g¦s¦b"
+
+msgid "No abbreviation found"
+msgstr "§ä¤£¨ì abbreviation"
+
+msgid "No mapping found"
+msgstr "¨S¦³³o­Ó mapping ¹ïÀ³"
+
+msgid "E228: makemap: Illegal mode"
+msgstr "E228: makemap: ¤£¥¿½Tªº¼Ò¦¡"
+
+msgid "E229: Cannot start the GUI"
+msgstr "E229: µLªk±Ò°Ê¹Ï«¬¬É­±"
+
+#, c-format
+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"
+
+#, c-format
+msgid "E254: Cannot allocate color %s"
+msgstr "E254: ¤£¯à°t¸mÃC¦â %s"
+
+msgid "<cannot open> "
+msgstr "<¤£¯à¶}±Ò>"
+
+#, c-format
+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 ""
+"&Yes\n"
+"&No\n"
+"&Cancel"
+msgstr ""
+"&Y¬O\n"
+"&N§_\n"
+"&C¨ú®ø"
+
+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¬°:"
+
+#. whole word only button
+msgid "Match whole word only"
+msgstr "¥u·j´M§¹¥þ¬Û¦Pªº¦r"
+
+#. match case button
+msgid "Match case"
+msgstr "²Å¦X¤j¤p¼g"
+
+msgid "Direction"
+msgstr "¤è¦V"
+
+#. 'Up' and 'Down' buttons
+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 "´_­ì"
+
+#, c-format
+msgid "E671: Cannot find window title \"%s\""
+msgstr "E671: §ä¤£¨ì¼ÐÃD¬° \"%s\" ªºµøµ¡"
+
+#, c-format
+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¦â¬Ý°_¨Ó·|©Ç©Çªº"
+
+#, c-format
+msgid "E250: Fonts for the following charsets are missing in fontset %s:"
+msgstr "E250: Fontset %s ¨S¦³³]©w¥¿½Tªº¦r«¬¥H¨ÑÅã¥Ü³o¨Ç¦r¤¸¶°:"
+
+#, c-format
+msgid "E252: Fontset name: %s"
+msgstr "E252: ¦r«¬¶°(Fontset)¦WºÙ: %s"
+
+#, c-format
+msgid "Font '%s' is not fixed-width"
+msgstr "'%s' ¤£¬O©T©w¼e«×¦r«¬"
+
+#, c-format
+msgid "E253: Fontset name: %s\n"
+msgstr "E253: ¦r«¬¶°(Fontset)¦WºÙ: %s\n"
+
+#, c-format
+msgid "Font0: %s\n"
+msgstr "Font0: %s\n"
+
+#, c-format
+msgid "Font1: %s\n"
+msgstr "Font1: %s\n"
+
+#, c-format
+msgid "Font%ld width is not twice that of font0\n"
+msgstr "¦r«¬%ld ¼e«×¤£¬O ¦r«¬0 ªº¨â­¿\n"
+
+#, c-format
+msgid "Font0 width: %ld\n"
+msgstr "¦r«¬0ªº¼e«×¡G%ld\n"
+
+#, c-format
+msgid ""
+"Font1 width: %ld\n"
+"\n"
+msgstr ""
+"¦r«¬1¼e«×: %ld\n"
+"\n"
+
+msgid "E256: Hangul automata ERROR"
+msgstr "E256: Hangul automata ¿ù»~"
+
+msgid "Add a new database"
+msgstr "·s¼W¸ê®Æ®w"
+
+msgid "Query for a pattern"
+msgstr "¿é¤J pattern"
+
+msgid "Show this message"
+msgstr "Åã¥Ü¦¹°T®§"
+
+msgid "Kill a connection"
+msgstr "µ²§ô³s½u"
+
+msgid "Reinit all connections"
+msgstr "­«³]©Ò¦³³s½u"
+
+msgid "Show connections"
+msgstr "Åã¥Ü³s½u"
+
+#, c-format
+msgid "E560: Usage: cs[cope] %s"
+msgstr "E560: ¥Îªk: cs[cope] %s"
+
+msgid "This cscope command does not support splitting the window.\n"
+msgstr "³o­Ó cscope ©R¥O¤£¤ä´©¤À³Î¿Ã¹õ\n"
+
+msgid "E562: Usage: cstag <ident>"
+msgstr "E562: ¥Îªk: cstag <ÃѧO¦rident>"
+
+msgid "E257: cstag: tag not found"
+msgstr "E257: cstag: §ä¤£¨ì tag"
+
+#, 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 ¤£¬O¥Ø¿ý©Î cscope ¸ê®Æ®w"
+
+#, c-format
+msgid "Added cscope database %s"
+msgstr "·s¼W cscope ¸ê®Æ®w %s"
+
+#, c-format
+msgid "E262: error reading cscope connection %ld"
+msgstr "E262: Ū¨ú cscope ³s½u %ld ¿ù»~"
+
+msgid "E561: unknown cscope search type"
+msgstr "E561: ¥¼ª¾ªº cscope ·j´M§ÎºA"
+
+msgid "E566: Could not create cscope pipes"
+msgstr "E566: µLªk«Ø¥ß»P cscope ªº pipe ³s½u"
+
+msgid "E622: Could not fork for cscope"
+msgstr "E622: µLªk fork ¥H°õ¦æ cscope "
+
+msgid "cs_create_connection exec failed"
+msgstr "cs_create_connection °õ¦æ¥¢±Ñ"
+
+msgid "E623: Could not spawn cscope process"
+msgstr "E623: µLªk°õ¦æ cscope "
+
+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 "E567: no cscope connections"
+msgstr "E567: ¨S¦³ cscope ³s½u"
+
+#, c-format
+msgid "E259: no matches found for cscope query %s of %s"
+msgstr "E259: §ä¤£¨ì²Å¦X cscope ªº·j´M %s / %s"
+
+#, c-format
+msgid "E469: invalid cscopequickfix flag %c for %c"
+msgstr "E469: cscopequickfix ªº flac %c (%c) ¤£¥¿½T"
+
+msgid "cscope commands:\n"
+msgstr "cscope ©R¥O:\n"
+
+#, c-format
+msgid "%-5s: %-30s (Usage: %s)"
+msgstr "%-5s: %-30s (¥Îªk: %s)"
+
+#, c-format
+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 "E568: duplicate cscope database not added"
+msgstr "E568: ­«½Æªº cscope ¸ê®Æ®w¥¼³Q¥[¤J"
+
+msgid "E569: maximum number of cscope connections reached"
+msgstr "E569: ¤w¹F¨ì cscope ³Ì¤j³s½u¼Æ¥Ø"
+
+#, c-format
+msgid "E261: cscope connection %s not found"
+msgstr "E261: §ä¤£¨ì cscope ³s½u %s"
+
+#, c-format
+msgid "cscope connection %s closed"
+msgstr "cscope ³s½u %s ¤wÃö³¬"
+
+#. should not reach here
+msgid "E570: fatal error in cs_manage_matches"
+msgstr "E570: cs_manage_matches ÄY­«¿ù»~"
+
+#, c-format
+msgid "Cscope tag: %s"
+msgstr "Cscope ¼ÐÅÒ(tag): %s"
+
+msgid ""
+"\n"
+" # line"
+msgstr ""
+"\n"
+" # ¦æ "
+
+msgid "filename / context / line\n"
+msgstr "ÀɦW / ¤º¤å / ¦æ¸¹\n"
+
+#, c-format
+msgid "E609: Cscope error: %s"
+msgstr "E609: Csope ¿ù»~: %s"
+
+msgid "All cscope databases reset"
+msgstr "­«³]©Ò¦³ cscope ¸ê®Æ®w"
+
+msgid "no cscope connections\n"
+msgstr "¨S¦³ cscope ³s½u\n"
+
+msgid " # pid database name prepend path\n"
+msgstr " # pid ¸ê®Æ®w¦WºÙ prepend path\n"
+
+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³ò"
+
+#, c-format
+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½Ä°Ï¤§¥~"
+
+#, c-format
+msgid "<window object (deleted) at %.8lX>"
+msgstr "<µøµ¡ª«¥ó(¤w§R°£): %.8lX>"
+
+#, c-format
+msgid "<window object (unknown) at %.8lX>"
+msgstr "<µøµ¡ª«¥ó(¥¼ª¾): %.8lX>"
+
+#, c-format
+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)"
+
+#, c-format
+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¤¤"
+
+#, c-format
+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 "E279: Not a SNiFF+ buffer"
+msgstr "E279: ¤£¬O SNiFF+ ªº½w½Ä°Ï"
+
+msgid "Sniff: Error during write. Disconnected"
+msgstr "Sniff: ¼g¤J¿ù»~¡Cµ²§ô³s½u"
+
+msgid "invalid buffer number"
+msgstr "½w½Ä°Ï¸¹½X¿ù»~"
+
+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"
+
+#, c-format
+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"
+
+#. This should never happen. Famous last word?
+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µ{¦¡"
+
+#, c-format
+msgid "E573: Invalid server id used: %s"
+msgstr "E573: ¤£¥¿½Tªº¦øªA¾¹ id : %s"
+
+msgid "E251: VIM instance registry property is badly formed. Deleted!"
+msgstr "E251: VIM ªº registry ³]©w¶µ¦³»~¡C¤w§R°£¡C"
+
+msgid "Unknown option"
+msgstr "¤£¥¿½Tªº¿ï¶µ"
+
+msgid "Too many edit arguments"
+msgstr "¤Ó¦h½s¿è°Ñ¼Æ"
+
+msgid "Argument missing after"
+msgstr "¯Ê¤Ö¥²­nªº°Ñ¼Æ:"
+
+msgid "Garbage after option"
+msgstr "µLªk¿ë»{¦¹¿ï¶µ«áªº©R¥O: "
+
+msgid "Too many \"+command\", \"-c command\" or \"--cmd command\" arguments"
+msgstr "¤Ó¦h \"+command\" ¡B \"-c command\" ©Î \"--cmd command\" °Ñ¼Æ"
+
+msgid "Invalid argument for"
+msgstr "¤£¥¿½Tªº°Ñ¼Æ: "
+
+msgid "This Vim was not compiled with the diff feature."
+msgstr "±zªº Vim ½sͮɍS¦³¥[¤J diff ªº¯à¤O"
+
+msgid "Attempt to open script file again: \""
+msgstr "¸Õ¹Ï¦A¦¸¶}±Ò script ÀÉ: \""
+
+msgid "Cannot open for reading: \""
+msgstr "µLªk¶}±Ò¥HŪ¨ú: \""
+
+msgid "Cannot open for script output: \""
+msgstr "µLªk¶}±Ò¬° script ¿é¥X: \""
+
+#, c-format
+msgid "%d files to edit\n"
+msgstr "ÁÙ¦³ %d ­ÓÀÉ®×µ¥«Ý½s¿è\n"
+
+msgid "Vim: Warning: Output is not to a terminal\n"
+msgstr "Vim: ª`·N: ¿é¥X¤£¬O²×ºÝ¾÷(¿Ã¹õ)\n"
+
+msgid "Vim: Warning: Input is not from a terminal\n"
+msgstr "Vim: ª`·N: ¿é¤J¤£¬O²×ºÝ¾÷(Áä½L)\n"
+
+#. just in case..
+msgid "pre-vimrc command line"
+msgstr "vimrc «e©R¥O¦C"
+
+#, c-format
+msgid "E282: Cannot read from \"%s\""
+msgstr "E282: µLªkŪ¨úÀÉ®× \"%s\""
+
+msgid ""
+"\n"
+"More info with: \"vim -h\"\n"
+msgstr ""
+"\n"
+"¬d¸ß§ó¦h¸ê°T½Ð°õ¦æ: \"vim -h\"\n"
+
+msgid "[file ..] edit specified file(s)"
+msgstr "[ÀÉ®× ..] ½s¿è«ü©wªºÀÉ®×"
+
+msgid "- read text from stdin"
+msgstr "- ±q¼Ð·Ç¿é¤J(stdin)Ū¨úÀÉ®×"
+
+msgid "-t tag edit file where tag is defined"
+msgstr "-t tag ½s¿è®É¨Ï¥Î«ü©wªº tag"
+
+msgid "-q [errorfile] edit file with first error"
+msgstr "-q [errorfile] ½s¿è®É¸ü¤J²Ä¤@­Ó¿ù»~"
+
+msgid ""
+"\n"
+"\n"
+"usage:"
+msgstr ""
+"\n"
+"\n"
+" ¥Îªk:"
+
+msgid " vim [arguments] "
+msgstr "vim [°Ñ¼Æ] "
+
+msgid ""
+"\n"
+" or:"
+msgstr ""
+"\n"
+" ©Î:"
+
+msgid ""
+"\n"
+"\n"
+"Arguments:\n"
+msgstr ""
+"\n"
+"\n"
+"°Ñ¼Æ:\n"
+
+msgid "--\t\t\tOnly file names after this"
+msgstr "--\t\t\t¥u¦³¦b³o¤§«áªºÀÉ®×"
+
+msgid "--literal\t\tDon't expand wildcards"
+msgstr "--literal\t\t¤£®i¶}¸U¥Î¦r¤¸"
+
+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\t\t\tVi mode (like \"vi\")"
+msgstr "-v\t\t\tVi ¼Ò¦¡ (¦P \"vi\")"
+
+msgid "-e\t\t\tEx mode (like \"ex\")"
+msgstr "-e\t\t\tEx ¼Ò¦¡ (¦P \"ex\")"
+
+msgid "-s\t\t\tSilent (batch) mode (only for \"ex\")"
+msgstr "-s\t\t\t¦wÀR (batch) ¼Ò¦¡ (¥u¯à»P \"ex\" ¤@°_¨Ï¥Î)"
+
+msgid "-d\t\t\tDiff mode (like \"vimdiff\")"
+msgstr "-d\t\t\tDiff ¼Ò¦¡ (¦P \"vimdiff\", ¥i¨³³t¤ñ¸û¨âÀɮפ£¦P³B)"
+
+msgid "-y\t\t\tEasy mode (like \"evim\", modeless)"
+msgstr "-y\t\t\t²©ö¼Ò¦¡ (¦P \"evim\", modeless)"
+
+msgid "-R\t\t\tReadonly mode (like \"view\")"
+msgstr "-R\t\t\t°ßŪ¼Ò¦¡ (¦P \"view\")"
+
+msgid "-Z\t\t\tRestricted mode (like \"rvim\")"
+msgstr "-Z\t\t\t­­¨î¼Ò¦¡ (¦P \"rvim\")"
+
+msgid "-m\t\t\tModifications (writing files) not allowed"
+msgstr "-m\t\t\t¤£¥i­×§ï (¼g¤JÀÉ®×)"
+
+msgid "-M\t\t\tModifications in text not allowed"
+msgstr "-M\t\t\t¤£¥i­×§ï¤å¦r"
+
+msgid "-b\t\t\tBinary mode"
+msgstr "-b\t\t\t¤G¶i¦ì¼Ò¦¡"
+
+msgid "-l\t\t\tLisp mode"
+msgstr "-l\t\t\tLisp ¼Ò¦¡"
+
+msgid "-C\t\t\tCompatible with Vi: 'compatible'"
+msgstr "-C\t\t\t'compatible' ¶Ç²Î Vi ¬Û®e¼Ò¦¡"
+
+msgid "-N\t\t\tNot fully Vi compatible: 'nocompatible'"
+msgstr "-N\t\t\t'nocompatible' ¤£§¹¥þ»P¶Ç²Î Vi ¬Û®e¡A¥i¨Ï¥Î Vim ¥[±j¯à¤O"
+
+msgid "-V[N]\t\tVerbose level"
+msgstr "-V[N]\t\tVerbose µ¥¯Å"
+
+msgid "-D\t\t\tDebugging mode"
+msgstr "-D\t\t\t°£¿ù¼Ò¦¡"
+
+msgid "-n\t\t\tNo swap file, use memory only"
+msgstr "-n\t\t\t¤£¨Ï¥Î¼È¦sÀÉ, ¥u¨Ï¥Î°O¾ÐÅé"
+
+msgid "-r\t\t\tList swap files and exit"
+msgstr "-r\t\t\t¦C¥X¼È¦sÀÉ«áÂ÷¶}"
+
+msgid "-r (with file name)\tRecover crashed session"
+msgstr "-r (¥[ÀɦW) \t­×´_¤W¦¸·l·´ªº¸ê®Æ(Recover crashed session)"
+
+msgid "-L\t\t\tSame as -r"
+msgstr "-L\t\t\t¦P -r"
+
+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 "-A\t\t\tstart in Arabic mode"
+msgstr "-A\t\t\t±Ò°Ê¬° Arabic ¼Ò¦¡"
+
+msgid "-H\t\t\tStart in Hebrew mode"
+msgstr "-H\t\t\t±Ò°Ê¬° Hebrew ¼Ò¦¡"
+
+msgid "-F\t\t\tStart in Farsi mode"
+msgstr "-F\t\t\t±Ò°Ê¬° Farsi ¼Ò¦¡"
+
+msgid "-T <terminal>\tSet terminal type to <terminal>"
+msgstr "-T <terminal>\t³]©w²×ºÝ¾÷¬° <terminal>"
+
+msgid "-u <vimrc>\t\tUse <vimrc> instead of any .vimrc"
+msgstr "-u <vimrc>\t\t¨Ï¥Î <vimrc> ¨ú¥N¥ô¦ó .vimrc"
+
+msgid "-U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc"
+msgstr "-U <gvimrc>\t\t¨Ï¥Î <gvimrc> ¨ú¥N¥ô¦ó .gvimrc"
+
+msgid "--noplugin\t\tDon't load plugin scripts"
+msgstr "--noplugin\t\t¤£¸ü¤J¥ô¦ó plugin"
+
+msgid "-o[N]\t\tOpen N windows (default: one for each file)"
+msgstr "-o[N]\t\t¶}±Ò N ­Óµøµ¡ (¹w³]¬O¨C­ÓÀɮפ@­Ó)"
+
+msgid "-O[N]\t\tLike -o but split vertically"
+msgstr "-O[N]\t\t¦P -o ¦ý¨Ï¥Î««ª½¤À³Î"
+
+msgid "+\t\t\tStart at end of file"
+msgstr "+\t\t\t±Ò°Ê«á¸õ¨ìÀÉ®×µ²§À"
+
+msgid "+<lnum>\t\tStart at line <lnum>"
+msgstr "+<lnum>\t\t±Ò°Ê«á¸õ¨ì²Ä <lnum> ¦æ "
+
+msgid "--cmd <command>\tExecute <command> before loading any vimrc file"
+msgstr "--cmd <command>\t¸ü¤J¥ô¦ó vimrc «e°õ¦æ <command>"
+
+msgid "-c <command>\t\tExecute <command> after loading the first file"
+msgstr "-c <command>\t\t¸ü¤J²Ä¤@­ÓÀɮ׫á°õ¦æ <command>"
+
+msgid "-S <session>\t\tSource file <session> after loading the first file"
+msgstr "-S <session>\t\t¸ü¤J²Ä¤@­ÓÀɮ׫á¸ü¤J Session ÀÉ <session>"
+
+msgid "-s <scriptin>\tRead Normal mode commands from file <scriptin>"
+msgstr "-s <scriptin>\t±q <scriptin> Ū¤J¤@¯ë¼Ò¦¡©R¥O"
+
+msgid "-w <scriptout>\tAppend all typed commands to file <scriptout>"
+msgstr "-w <scriptout>\t¹ïÀÉ®× <scriptout> ªþ¥[(append)©Ò¦³¿é¤Jªº©R¥O"
+
+msgid "-W <scriptout>\tWrite all typed commands to file <scriptout>"
+msgstr "-W <scriptout>\t¹ïÀÉ®× <scriptout> ¼g¤J©Ò¦³¿é¤Jªº©R¥O"
+
+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 "-i <viminfo>\t\tUse <viminfo> instead of .viminfo"
+msgstr "-i <viminfo>\t\t¨Ï¥Î <viminfo> ¦Ó«D .viminfo"
+
+msgid "-h or --help\tPrint Help (this message) and exit"
+msgstr "-h ©Î --help\t¦L¥X»¡©ú(¤]´N¬O¥»°T®§)«áÂ÷¶}"
+
+msgid "--version\t\tPrint version information and exit"
+msgstr "--version\t\t¦L¥Xª©¥»¸ê°T«áÂ÷¶}"
+
+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Åã¥Ü"
+
+#. Failed to send, abort.
+msgid ": Send failed.\n"
+msgstr ": ¶Ç°e¥¢±Ñ¡C\n"
+
+#. Let vim start normally.
+msgid ": Send failed. Trying to execute locally\n"
+msgstr ": °e¥X¥¢±Ñ¡C¸Õ¹Ï¦b¥»¦a°õ¦æ\n"
+
+#, c-format
+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 "No marks set"
+msgstr "¨S¦³³]©w¼Ð°O (mark)"
+
+#, c-format
+msgid "E283: No marks matching \"%s\""
+msgstr "E283: §ä¤£¨ì²Å¦X \"%s\" ªº¼Ð°O(mark)"
+
+#. Highlight title
+msgid ""
+"\n"
+"mark line col file/text"
+msgstr ""
+"\n"
+"¼Ð°O ¦æ¸¹ Äæ ÀÉ®×/¤å¦r"
+
+#. Highlight title
+msgid ""
+"\n"
+" jump line col file/text"
+msgstr ""
+"\n"
+" jump ¦æ¸¹ Äæ ÀÉ®×/¤å¦r"
+
+#. Highlight title
+msgid ""
+"\n"
+"change line col text"
+msgstr ""
+"\n"
+"§ïÅÜ ¦æ¸¹ Äæ ¤å¦r"
+
+#, c-format
+msgid ""
+"\n"
+"# File marks:\n"
+msgstr ""
+"\n"
+"# Àɮ׼аO:\n"
+
+#. Write the jumplist with -'
+#, c-format
+msgid ""
+"\n"
+"# Jumplist (newest first):\n"
+msgstr ""
+"\n"
+"# Jumplist (¥Ñ·s¨ìÂÂ):\n"
+
+#, c-format
+msgid ""
+"\n"
+"# History of marks within files (newest to oldest):\n"
+msgstr ""
+"\n"
+"# Àɮפº Mark °O¿ý (¥Ñ·s¨ìÂÂ):\n"
+
+msgid "Missing '>'"
+msgstr "¯Ê¤Ö¹ïÀ³ªº '>'"
+
+msgid "E543: Not a valid codepage"
+msgstr "E543: ¤£¥¿½Tªº codepage"
+
+msgid "E284: Cannot set IC values"
+msgstr "E284: ¤£¯à³]©w IC ¼Æ­È"
+
+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 "E293: block was not locked"
+msgstr "E293: °Ï¶ô¥¼³QÂê©w"
+
+msgid "E294: Seek error in swap file read"
+msgstr "E294: ¼È¦sÀÉŪ¨ú¿ù»~"
+
+msgid "E295: Read error in swap file"
+msgstr "E295: ¼È¦sÀÉŪ¨ú¿ù»~"
+
+msgid "E296: Seek error in swap file write"
+msgstr "E296: ¼È¦sÀɼg¤J¿ù»~"
+
+msgid "E297: Write error in swap file"
+msgstr "E297: ¼È¦sÀɼg¤J¿ù»~"
+
+msgid "E300: Swap file already exists (symlink attack?)"
+msgstr "E300: ¼È¦sÀɤw¸g¦s¦b! (¤p¤ß²Å¸¹³sµ²ªº¦w¥þº|¬}!?)"
+
+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?"
+
+#. could not (re)open the swap file, what can we do????
+msgid "E301: Oops, lost the swap file!!!"
+msgstr "E301: ¾¾¾¾, ¼È¦sÀɤ£¨£¤F!!!"
+
+msgid "E302: Could not rename swap file"
+msgstr "E302: µLªk§ïÅܼȦsÀɪº¦WºÙ"
+
+#, c-format
+msgid "E303: Unable to open swap file for \"%s\", recovery impossible"
+msgstr "E303: µLªk¶}±Ò¼È¦sÀÉ \"%s\", ¤£¥i¯à­×´_¤F"
+
+msgid "E304: ml_timestamp: Didn't get block 0??"
+msgstr "E304: ml_timestamp: §ä¤£¨ì°Ï¶ô 0??"
+
+#, c-format
+msgid "E305: No swap file found for %s"
+msgstr "E305: §ä¤£¨ì %s ªº¼È¦sÀÉ"
+
+msgid "Enter number of swap file to use (0 to quit): "
+msgstr "½Ð¿ï¾Ü§A­n¨Ï¥Îªº¼È¦sÀÉ («ö0 Â÷¶}): "
+
+#, c-format
+msgid "E306: Cannot open %s"
+msgstr "E306: µLªk¶}±Ò %s"
+
+msgid "Unable to read block 0 from "
+msgstr "µLªkŪ¨ú°Ï¶ô 0:"
+
+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ÀÉ."
+
+msgid " cannot be used with this version of Vim.\n"
+msgstr " µLªk¦b¥»ª©¥»ªº Vim ¤¤¨Ï¥Î.\n"
+
+msgid "Use Vim version 3.0.\n"
+msgstr "¨Ï¥Î Vim 3.0¡C\n"
+
+#, c-format
+msgid "E307: %s does not look like a Vim swap file"
+msgstr "E307: %s ¬Ý°_¨Ó¤£¹³¬O Vim ¼È¦sÀÉ"
+
+msgid " cannot be used on this computer.\n"
+msgstr " µLªk¦b³o»O¹q¸£¤W¨Ï¥Î.\n"
+
+msgid "The file was created on "
+msgstr "¥»Àɮ׫إߩó "
+
+msgid ""
+",\n"
+"or the file has been damaged."
+msgstr ""
+",\n"
+"©Î¬O³oÀɮפw¸g·l·´¡C"
+
+#, c-format
+msgid "Using swap file \"%s\""
+msgstr "¨Ï¥Î¼È¦sÀÉ \"%s\""
+
+#, c-format
+msgid "Original file \"%s\""
+msgstr "­ì©lÀÉ \"%s\""
+
+msgid "E308: Warning: Original file may have been changed"
+msgstr "E308: ĵ§i: ­ì©lÀÉ®×¥i¯à¤w¸g­×§ï¹L¤F"
+
+#, c-format
+msgid "E309: Unable to read block 1 from %s"
+msgstr "E309: µLªk±q %s Ū¨ú°Ï¶ô 1"
+
+msgid "???MANY LINES MISSING"
+msgstr "???¯Ê¤Ö¤Ó¦h¦æ "
+
+msgid "???LINE COUNT WRONG"
+msgstr "???¦æ¸¹¿ù»~"
+
+msgid "???EMPTY BLOCK"
+msgstr "???ªÅªº BLOCK"
+
+msgid "???LINES MISSING"
+msgstr "???§ä¤£¨ì¤@¨Ç¦æ "
+
+#, c-format
+msgid "E310: Block 1 ID wrong (%s not a .swp file?)"
+msgstr "E310: °Ï¶ô 1 ID ¿ù»~ (%s ¤£¬O¼È¦sÀÉ?)"
+
+msgid "???BLOCK MISSING"
+msgstr "???§ä¤£¨ìBLOCK"
+
+msgid "??? from here until ???END lines may be messed up"
+msgstr "??? ±q³o¸Ì¨ì ???END ªº¤º®e¥i¯à¦³°ÝÃD"
+
+msgid "??? from here until ???END lines may have been inserted/deleted"
+msgstr "??? ±q³o¸Ì¨ì ???END ªº¤º®e¥i¯à³Q§R°£/´¡¤J¹L"
+
+# do not translate
+msgid "???END"
+msgstr "???END"
+
+msgid "E311: Recovery Interrupted"
+msgstr "E311: ­×´_¤w¤¤Â_"
+
+msgid ""
+"E312: Errors detected while recovering; look for lines starting with ???"
+msgstr "E312: ­×´_®Éµo¥Í¿ù»~; ½Ðª`·N¶}ÀY¬° ??? ªº¦æ "
+
+msgid "See \":help E312\" for more information."
+msgstr "¸Ô²Ó»¡©ú½Ð¨£ \":help E312\""
+
+msgid "Recovery completed. You should check if everything is OK."
+msgstr "´_­ì§¹¦¨. ½Ð½T©w¤@¤Á¥¿±`."
+
+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"
+
+msgid "and run diff with the original file to check for changes)\n"
+msgstr "¦A°õ¦æ diff »P­ìÀɮפñ¸û¥HÀˬd¬O§_¦³§ïÅÜ)\n"
+
+msgid ""
+"Delete the .swp file afterwards.\n"
+"\n"
+msgstr ""
+"(D)ª½±µ§R°£ .swp ¼È¦sÀÉ\n"
+"\n"
+
+#. use msg() to start the scrolling properly
+msgid "Swap files found:"
+msgstr "§ä¨ì¥H¤Uªº¼È¦sÀÉ:"
+
+msgid " In current directory:\n"
+msgstr " ¦b¥Ø«eªº¥Ø¿ý:\n"
+
+msgid " Using specified name:\n"
+msgstr " Using specified name:\n"
+
+msgid " In directory "
+msgstr " ¦b¥Ø¿ý "
+
+msgid " -- none --\n"
+msgstr " -- µL --\n"
+
+msgid " owned by: "
+msgstr " ¾Ö¦³ªÌ: "
+
+msgid " dated: "
+msgstr " ¤é´Á: "
+
+msgid " dated: "
+msgstr " ¤é´Á: "
+
+msgid " [from Vim version 3.0]"
+msgstr " [±q Vim ª©¥» 3.0]"
+
+msgid " [does not look like a Vim swap file]"
+msgstr " [¤£¹³ Vim ªº¼È¦sÀÉ]"
+
+msgid " file name: "
+msgstr " ÀɦW: "
+
+msgid ""
+"\n"
+" modified: "
+msgstr ""
+"\n"
+" ­×§ï¹L: "
+
+msgid "YES"
+msgstr "¬O"
+
+msgid "no"
+msgstr "§_"
+
+msgid ""
+"\n"
+" user name: "
+msgstr ""
+"\n"
+" ¨Ï¥ÎªÌ: "
+
+msgid " host name: "
+msgstr " ¥D¾÷¦WºÙ: "
+
+msgid ""
+"\n"
+" host name: "
+msgstr ""
+"\n"
+" ¥D¾÷¦WºÙ: "
+
+msgid ""
+"\n"
+" process ID: "
+msgstr ""
+"\n"
+" process ID: "
+
+msgid " (still running)"
+msgstr " (°õ¦æ¤¤)"
+
+msgid ""
+"\n"
+" [not usable with this version of Vim]"
+msgstr ""
+"\n"
+" [µLªk¦b¥»ª©¥»ªº Vim ¤W¨Ï¥Î]"
+
+msgid ""
+"\n"
+" [not usable on this computer]"
+msgstr ""
+"\n"
+" [µLªk¦b¥»¹q¸£¤W¨Ï¥Î]"
+
+msgid " [cannot be read]"
+msgstr " [µLªkŪ¨ú]"
+
+msgid " [cannot be opened]"
+msgstr " [µLªk¶}±Ò]"
+
+msgid "E313: Cannot preserve, there is no swap file"
+msgstr "E313: µLªk«O¯d, ¤£¨Ï¥Î¼È¦sÀÉ"
+
+msgid "File preserved"
+msgstr "Àɮפw«O¯d"
+
+msgid "E314: Preserve failed"
+msgstr "E314: «O¯d¥¢±Ñ"
+
+#, 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: «ü¼Ð°Ï¶ô id ¿ù»~ 3"
+
+msgid "stack_idx should be 0"
+msgstr "stack_idx À³¸Ó¬O 0"
+
+msgid "E318: Updated too many blocks?"
+msgstr "E318: §ó·s¤Ó¦h°Ï¶ô?"
+
+msgid "E317: pointer block id wrong 4"
+msgstr "E317: «ü¼Ð°Ï¶ô id ¿ù»~ 4"
+
+msgid "deleted block 1?"
+msgstr "§R°£°Ï¶ô 1?"
+
+#, c-format
+msgid "E320: Cannot find line %ld"
+msgstr "E320: §ä¤£¨ì²Ä %ld ¦æ "
+
+msgid "E317: pointer block id wrong"
+msgstr "E317: «ü¼Ð°Ï¶ô id ¿ù»~"
+
+msgid "pe_line_count is zero"
+msgstr "pe_line_count ¬°¹s"
+
+#, c-format
+msgid "E322: line number out of range: %ld past the end"
+msgstr "E322: ¦æ¸¹¶W¥X½d³ò: %ld ¶W¹Lµ²§À"
+
+#, c-format
+msgid "E323: line count wrong in block %ld"
+msgstr "E323: °Ï¶ô %ld ¦æ¼Æ¿ù»~"
+
+msgid "Stack size increases"
+msgstr "°ïÅ|¤j¤p¼W¥["
+
+msgid "E317: pointer block id wrong 2"
+msgstr "E317: «ü¼Ð°Ï¶ô id ¿ù 2"
+
+msgid "E325: ATTENTION"
+msgstr "E325: ª`·N"
+
+msgid ""
+"\n"
+"Found a swap file by the name \""
+msgstr ""
+"\n"
+"§ä¨ì¼È¦sÀÉ \""
+
+msgid "While opening file \""
+msgstr "¦b¶}±ÒÀÉ®× \""
+
+msgid " NEWER than swap file!\n"
+msgstr " ¤ñ¼È¦sÀɧó·s!\n"
+
+#. Some of these messages are long to allow translation to
+#. * other languages.
+msgid ""
+"\n"
+"(1) Another program may be editing the same file.\n"
+" If this is the case, be careful not to end up with two\n"
+" different instances of the same file when making changes.\n"
+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"
+
+msgid " Quit, or continue with caution.\n"
+msgstr " Â÷¶}¡A©Î¬OÄ~Äò½s¿è¡C\n"
+
+msgid ""
+"\n"
+"(2) An edit session for this file crashed.\n"
+msgstr ""
+"\n"
+"(2) «e¦¸½s¿è¦¹Àɮɷí¾÷\n"
+
+msgid " If this is the case, use \":recover\" or \"vim -r "
+msgstr " ¦pªG¬O³o¼Ë, ½Ð¥Î \":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 " ¦pªG¸Ó±Ïªº³£¤w¸g±Ï¤F, ½Ðª½±µ§R°£¦¹¼È¦sÀÉ \""
+
+msgid ""
+"\"\n"
+" to avoid this message.\n"
+msgstr ""
+"\"\n"
+" ¥HÁ×§K¦A¬Ý¨ì¦¹°T®§.\n"
+
+msgid "Swap file \""
+msgstr "¼È¦sÀÉ \""
+
+msgid "\" already exists!"
+msgstr "\" ¤w¸g¦s¦b¤F!"
+
+msgid "VIM - ATTENTION"
+msgstr "VIM - ª`·N"
+
+msgid "Swap file already exists!"
+msgstr "¼È¦sÀɤw¸g¦s¦b!"
+
+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)"
+
+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 "E326: Too many swap files found"
+msgstr "E326: §ä¨ì¤Ó¦h¼È¦sÀÉ"
+
+msgid "E327: Part of menu-item path is not sub-menu"
+msgstr "E327: ³¡¥÷¿ï¶µ¸ô®|¤£¬O¤l¿ï³æ"
+
+msgid "E328: Menu only exists in another mode"
+msgstr "E328: ¿ï³æ¥u¯à¦b¨ä¥¦¼Ò¦¡¤¤¨Ï¥Î"
+
+msgid "E329: No menu of that name"
+msgstr "E329: ¨S¦³¨º¼Ëªº¿ï³æ"
+
+msgid "E330: Menu path must not lead to a sub-menu"
+msgstr "E330: ¿ï³æ¸ô®|¤£¯à«ü¦V¤l¿ï³æ"
+
+msgid "E331: Must not add menu items directly to menu bar"
+msgstr "E331: ¤£¯àª½±µ§â¿ï¶µ¥[¨ì¿ï³æ¦C¤¤"
+
+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
+msgid ""
+"\n"
+"--- Menus ---"
+msgstr ""
+"\n"
+"--- ¿ï³æ ---"
+
+msgid "Tear off this menu"
+msgstr "¤Á¤U¦¹¿ï³æ"
+
+msgid "E333: Menu path must lead to a menu item"
+msgstr "E333: ¿ï³æ¸ô®|¥²»Ý«ü¦V¤@­Ó¿ï¶µ"
+
+#, c-format
+msgid "E334: Menu not found: %s"
+msgstr "E334: [¿ï³æ] §ä¤£¨ì %s"
+
+#, c-format
+msgid "E335: Menu not defined for %s mode"
+msgstr "E335: %s ¼Ò¦¡¥¼©w¸q¿ï³æ"
+
+msgid "E336: Menu path must lead to a sub-menu"
+msgstr "E336: ¿ï³æ¸ô®|¥²»Ý«ü¦V¤l¿ï³æ"
+
+msgid "E337: Menu not found - check menu names"
+msgstr "E337: §ä¤£¨ì¿ï³æ - ½ÐÀˬd¿ï³æ¦WºÙ"
+
+#, c-format
+msgid "Error detected while processing %s:"
+msgstr "³B²z %s ®Éµo¥Í¿ù»~:"
+
+#, c-format
+msgid "line %4ld:"
+msgstr "¦æ %4ld:"
+
+msgid "[string too long]"
+msgstr "[¦¹¦æ¹Lªø]"
+
+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>"
+
+msgid "Interrupt: "
+msgstr "¤w¤¤Â_: "
+
+msgid "Hit ENTER to continue"
+msgstr "½Ð«ö ENTER Ä~Äò"
+
+msgid "Hit ENTER or type command to continue"
+msgstr "½Ð«ö ENTER ©Î¨ä¥¦©R¥O¥HÄ~Äò"
+
+msgid "-- More --"
+msgstr "-- ©|¦³ --"
+
+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 "Question"
+msgstr "°ÝÃD"
+
+msgid ""
+"&Yes\n"
+"&No"
+msgstr ""
+"&Y¬O\n"
+"&N§_"
+
+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¨ú®ø"
+
+msgid "Save File dialog"
+msgstr "¦sÀÉ"
+
+msgid "Open File dialog"
+msgstr "¶}ÀÉ"
+
+#. TODO: non-GUI file selector here
+msgid "E338: Sorry, no file browser in console mode"
+msgstr "E338: ¥D±±¥x(Console)¼Ò¦¡®É¨S¦³ÀÉ®×ÂsÄý¾¹(file browser)"
+
+msgid "W10: Warning: Changing a readonly file"
+msgstr "W10: ª`·N: §A¥¿¦b­×§ï¤@­Ó°ßŪÀÉ"
+
+msgid "1 more line"
+msgstr "ÁÙ¦³¤@¦æ "
+
+msgid "1 line less"
+msgstr "¤Ö©ó¤@¦æ "
+
+#, c-format
+msgid "%ld more lines"
+msgstr "ÁÙ¦³ %ld ¦æ "
+
+#, c-format
+msgid "%ld fewer lines"
+msgstr "¥u³Ñ %ld ¦æ "
+
+msgid " (Interrupted)"
+msgstr " (¤w¤¤Â_)"
+
+msgid "Vim: preserving files...\n"
+msgstr "Vim: «O¯dÀɮפ¤...\n"
+
+#. close all memfiles, without deleting
+msgid "Vim: Finished.\n"
+msgstr "Vim: µ²§ô.\n"
+
+#, c-format
+msgid "ERROR: "
+msgstr "¿ù»~: "
+
+#, c-format
+msgid ""
+"\n"
+"[bytes] total alloc-freed %lu-%lu, in use %lu, peak use %lu\n"
+msgstr ""
+"\n"
+"[bytes] ¥þ³¡ alloc-freed %lu-%lu, ¨Ï¥Î¤¤ %lu, peak ¨Ï¥Î %lu\n"
+
+#, c-format
+msgid ""
+"[calls] total re/malloc()'s %lu, total free()'s %lu\n"
+"\n"
+msgstr ""
+"[©I¥s] ¥þ³¡ re/malloc(): %lu, ¥þ³¡ free()': %lu\n"
+"\n"
+
+msgid "E340: Line is becoming too long"
+msgstr "E340: ¦¹¦æ¹Lªø"
+
+#, c-format
+msgid "E341: Internal error: lalloc(%ld, )"
+msgstr "E341: ¤º³¡¿ù»~: lalloc(%ld, )"
+
+#, c-format
+msgid "E342: Out of memory! (allocating %lu bytes)"
+msgstr "E342: °O¾ÐÅ餣¨¬! (¹Á¸Õ°t¸m %lu ¦ì¤¸²Õ)"
+
+#, c-format
+msgid "Calling shell to execute: \"%s\""
+msgstr "©I¥s shell °õ¦æ: \"%s\""
+
+msgid "E545: Missing colon"
+msgstr "E545: ¯Ê¤Ö colon"
+
+msgid "E546: Illegal mode"
+msgstr "E546: ¤£¥¿½Tªº¼Ò¦¡"
+
+msgid "E547: Illegal mouseshape"
+msgstr "E547: ¤£¥¿½Tªº·Æ¹«§Îª¬"
+
+msgid "E548: digit expected"
+msgstr "E548: À³¸Ó­n¦³¼Æ¦r"
+
+msgid "E549: Illegal percentage"
+msgstr "E549: ¤£¥¿½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!"
+
+#, 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'"
+
+#, c-format
+msgid "E344: Can't find directory \"%s\" in cdpath"
+msgstr "E344: cdpath ¤¤¨S¦³¥Ø¿ý \"%s\""
+
+#, c-format
+msgid "E345: Can't find file \"%s\" in path"
+msgstr "E345: ¦b¸ô®|¤¤§ä¤£¨ìÀÉ®× \"%s\""
+
+#, c-format
+msgid "E346: No more directory \"%s\" found in cdpath"
+msgstr "E346: ¦b¸ô®|¤¤§ä¤£¨ì§ó¦hªºÀÉ®× \"%s\""
+
+#, c-format
+msgid "E347: No more file \"%s\" found in path"
+msgstr "E347: ¦b¸ô®|¤¤§ä¤£¨ì§ó¦hªºÀÉ®× \"%s\""
+
+msgid "E550: Missing colon"
+msgstr "E550: ¯Ê¤Ö colon"
+
+msgid "E551: Illegal component"
+msgstr "E551: ¤£¥¿½Tªº¼Ò¦¡"
+
+msgid "E552: digit expected"
+msgstr "E552: À³¸Ó­n¦³¼Æ¦r"
+
+#. Get here when the server can't be found.
+msgid "Cannot connect to Netbeans #2"
+msgstr "µLªk³s±µ¨ì Netbeans #2"
+
+msgid "Cannot connect to Netbeans"
+msgstr "µLªk³s±µ¨ì Netbeans"
+
+#, c-format
+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 Ū¨ú"
+
+#, c-format
+msgid "E658: NetBeans connection lost for buffer %ld"
+msgstr "E658: ½w½Ä°Ï %ld »P NetBeans ªº³s½u¤w¤¤Â_"
+
+msgid "Warning: terminal cannot highlight"
+msgstr "ª`·N: §Aªº²×ºÝ¾÷µLªkÅã¥Ü°ª«G«×"
+
+msgid "E348: No string under cursor"
+msgstr "E348: ´å¼Ð³B¨S¦³¦r¦ê"
+
+msgid "E349: No identifier under cursor"
+msgstr "E349: ´å¼Ð³B¨S¦³ÃѧO¦r"
+
+msgid "E352: Cannot erase folds with current 'foldmethod'"
+msgstr "E352: µLªk¦b¥Ø«eªº 'foldmethod' ¤U§R°£ fold"
+
+msgid "E664: changelist is empty"
+msgstr "E664: Åܧó¦Cªí¬OªÅªº"
+
+msgid "E662: At start of changelist"
+msgstr "E662: ¤w¦bÅܧó¦Cªíªº¶}ÀY"
+
+msgid "E663: At end of changelist"
+msgstr "E663: ¤w¦bÅܧó¦Cªíªºµ²§À"
+
+msgid "Type :quit<Enter> to exit Vim"
+msgstr "­nÂ÷¶} Vim ½Ð¿é¤J :quit<Enter> "
+
+#, c-format
+msgid "1 line %sed 1 time"
+msgstr "¤@¦æ %s ¹L ¤@¦¸"
+
+#, c-format
+msgid "1 line %sed %d times"
+msgstr "¤@¦æ %s ¹L %d ¦¸"
+
+#, c-format
+msgid "%ld lines %sed 1 time"
+msgstr "%ld ¦æ %s ¹L ¤@¦¸"
+
+#, c-format
+msgid "%ld lines %sed %d times"
+msgstr "%ld ¦æ %s ¹L %d ¦¸"
+
+#, c-format
+msgid "%ld lines to indent... "
+msgstr "ÁY±Æ %ld ¦æ... "
+
+msgid "1 line indented "
+msgstr "¤@¦æ¤wÁY±Æ"
+
+#, c-format
+msgid "%ld lines indented "
+msgstr "¤wÁY±Æ %ld ¦æ "
+
+#. must display the prompt
+msgid "cannot yank; delete anyway"
+msgstr "µLªk°Å¤U; ª½±µ§R°£"
+
+msgid "1 line changed"
+msgstr " 1 ¦æ ~ed"
+
+#, c-format
+msgid "%ld lines changed"
+msgstr "¤w§ïÅÜ %ld ¦æ "
+
+#, c-format
+msgid "freeing %ld lines"
+msgstr "ÄÀ©ñ %ld ¦æ¤¤ "
+
+msgid "1 line yanked"
+msgstr "¤w½Æ»s 1 ¦æ "
+
+#, c-format
+msgid "%ld lines yanked"
+msgstr "¤w½Æ»s %ld ¦æ "
+
+#, c-format
+msgid "E353: Nothing in register %s"
+msgstr "E353: ¼È¦s¾¹ %s ¸Ì¨S¦³ªF¦è"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Registers ---"
+msgstr ""
+"\n"
+"--- ¼È¦s¾¹ ---"
+
+msgid "Illegal register name"
+msgstr "¤£¥¿½Tªº¼È¦s¾¹¦WºÙ"
+
+#, c-format
+msgid ""
+"\n"
+"# Registers:\n"
+msgstr ""
+"\n"
+"# ¼È¦s¾¹:\n"
+
+#, c-format
+msgid "E574: Unknown register type %d"
+msgstr "E574: ¥¼ª¾ªºµù¥U«¬ºA: %d"
+
+#, c-format
+msgid "E354: Invalid register name: '%s'"
+msgstr "E354: ¼È¦s¾¹¦WºÙ¿ù»~: '%s'"
+
+#, c-format
+msgid "%ld Cols; "
+msgstr "%ld Äæ; "
+
+#, c-format
+msgid "Selected %s%ld of %ld Lines; %ld of %ld Words; %ld of %ld Bytes"
+msgstr "¿ï¾Ü¤F %s%ld/%ld ¦æ; %ld/%ld ¦r(Word); %ld/%ld ¦r¤¸(Bytes)"
+
+#, c-format
+msgid "Col %s of %s; Line %ld of %ld; Word %ld of %ld; Byte %ld of %ld"
+msgstr "Äæ %s/%s; ¦æ %ld/%ld; ¦r(Word) %ld/%ld; ¦r¤¸(Byte) %ld/%ld"
+
+#, c-format
+msgid "(+%ld for BOM)"
+msgstr "(+%ld for BOM)"
+
+msgid "%<%f%h%m%=Page %N"
+msgstr "%<%f%h%m%=²Ä %N ­¶"
+
+# ? what's this for?
+msgid "Thanks for flying Vim"
+msgstr "·PÁ±z·R¥Î Vim"
+
+msgid "E518: Unknown option"
+msgstr "E518: ¤£¥¿½Tªº¿ï¶µ"
+
+msgid "E519: Option not supported"
+msgstr "E519: ¤£¤ä´©¸Ó¿ï¶µ"
+
+msgid "E520: Not allowed in a modeline"
+msgstr "E520: ¤£¯à¦b Modeline ¸Ì¥X²{"
+
+msgid ""
+"\n"
+"\tLast set from "
+msgstr ""
+"\n"
+"\t¤W¦¸³]©w: "
+
+msgid "E521: Number required after ="
+msgstr "E521: = «á»Ý­n¦³¼Æ¦r"
+
+msgid "E522: Not found in termcap"
+msgstr "E522: Termcap ¸Ì­±§ä¤£¨ì"
+
+#, c-format
+msgid "E539: Illegal character <%s>"
+msgstr "E539: ¤£¥¿½Tªº¦r¤¸ <%s>"
+
+msgid "E529: Cannot set 'term' to empty string"
+msgstr "E529: µLªk³]©w 'term' ¬°ªÅ¦r¦ê"
+
+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 "E589: 'backupext' and 'patchmode' are equal"
+msgstr "E589: 'backupext' ¸ò 'patchmode' ¬O¤@¼Ëªº"
+
+msgid "E617: Cannot be changed in the GTK+ 2 GUI"
+msgstr "E617: ¦b¹Ï«¬¬É­±¤¤µLªk¤Á´« term"
+
+msgid "E524: Missing colon"
+msgstr "E524: ¯Ê¤Ö colon"
+
+msgid "E525: Zero length string"
+msgstr "E525: ¹sªø«×¦r¦ê"
+
+#, c-format
+msgid "E526: Missing number after <%s>"
+msgstr "E526: <%s> «á¯Ê¤Ö¼Æ¦r"
+
+msgid "E527: Missing comma"
+msgstr "E527: ¯Ê¤Ö³r¸¹"
+
+msgid "E528: Must specify a ' value"
+msgstr "E528: ¥²»Ý«ü©w¤@­Ó ' ­È"
+
+msgid "E595: contains unprintable or wide character"
+msgstr "E595: ¤º§tµLªkÅã¥Üªº¦r¤¸"
+
+msgid "E596: Invalid font(s)"
+msgstr "E596: ¤£¥¿½Tªº¦r«¬"
+
+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)"
+
+#, c-format
+msgid "E535: Illegal character after <%c>"
+msgstr "E535: <%c> «á¦³¤£¥¿½Tªº¦r¤¸"
+
+msgid "E536: comma required"
+msgstr "E536: »Ý­n³r¸¹"
+
+#, c-format
+msgid "E537: 'commentstring' must be empty or contain %s"
+msgstr "E537: 'commentstring' ¥²»Ý¬OªÅ¥Õ©Î¥]§t %s"
+
+msgid "E538: No mouse support"
+msgstr "E538: ¤£¤ä´©·Æ¹«"
+
+msgid "E540: Unclosed expression sequence"
+msgstr "E540: ¨S¦³µ²§ôªº¹Bºâ¦¡: "
+
+msgid "E541: too many items"
+msgstr "E541: ¤Ó¦h¶µ¥Ø"
+
+msgid "E542: unbalanced groups"
+msgstr "E542: ¤£¹ïºÙªº group"
+
+msgid "E590: A preview window already exists"
+msgstr "E590: ¹wµøªºµøµ¡¤w¸g¦s¦b¤F"
+
+msgid "W17: Arabic requires UTF-8, do ':set encoding=utf-8'"
+msgstr "W17: Arabic »Ý­n UTF-8, ½Ð°õ¦æ ':set encoding=utf-8'"
+
+#, c-format
+msgid "E593: Need at least %d lines"
+msgstr "E593: ¦Ü¤Ö»Ý­n %d ¦æ "
+
+#, c-format
+msgid "E594: Need at least %d columns"
+msgstr "E594: ¦Ü¤Ö»Ý­n %d Äæ"
+
+#, c-format
+msgid "E355: Unknown option: %s"
+msgstr "E355: ¤£¥¿½Tªº¿ï¶µ: %s"
+
+msgid ""
+"\n"
+"--- Terminal codes ---"
+msgstr ""
+"\n"
+"--- ²×ºÝ¾÷½X ---"
+
+msgid ""
+"\n"
+"--- Global option values ---"
+msgstr ""
+"\n"
+"--- Global ¿ï¶µ­È ---"
+
+msgid ""
+"\n"
+"--- Local option values ---"
+msgstr ""
+"\n"
+"--- Local ¿ï¶µ­È ---"
+
+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 ¹ïÀ³ªº¦r¤¸"
+
+#, c-format
+msgid "E358: 'langmap': Extra characters after semicolon: %s"
+msgstr "E358: 'langmap': ¤À¸¹«á¦³¦h¾lªº¦r¤¸: %s"
+
+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"
+
+#, c-format
+msgid "Need %s version %ld\n"
+msgstr "»Ý­n %s ª©¥» %ld\n"
+
+msgid "Cannot open NIL:\n"
+msgstr "µLªk¶}±Ò 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 "µLªk¤Á´«¥D±±¥x(console)¼Ò¦¡ !?\n"
+
+msgid "mch_get_shellsize: not a console??\n"
+msgstr "mch_get_shellsize: ¤£¬O¥D±±¥x(console)??\n"
+
+#. if Vim opened a window: Executing a shell may cause crashes
+msgid "E360: Cannot execute shell with -f option"
+msgstr "E360: ¤£¯à¥Î -f ¿ï¶µ°õ¦æ shell"
+
+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 "E237: Printer selection failed"
+msgstr "E237: µLªk¿ï¾Ü¦¹¦Lªí¾÷"
+
+#, c-format
+msgid "to %s on %s"
+msgstr "¨ì %s on %s"
+
+#, c-format
+msgid "E613: Unknown printer font: %s"
+msgstr "E613: ¤£¥¿½Tªº¦Lªí¾÷¦r«¬: %s"
+
+#, c-format
+msgid "E238: Print error: %s"
+msgstr "E238: ¦C¦L¿ù»~: %s"
+
+msgid "Unknown"
+msgstr "¥¼ª¾"
+
+#, c-format
+msgid "Printing '%s'"
+msgstr "¦C¦L¤¤: '%s'"
+
+#, c-format
+msgid "E244: Illegal charset name \"%s\" in font name \"%s\""
+msgstr "E244: ¦r¤¸¶° \"%s\" µLªk¹ïÀ³¦r«¬\"%s\""
+
+#, c-format
+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"
+
+#, c-format
+msgid "Vim: Caught deadly signal %s\n"
+msgstr "Vim: CVim: ÄdºI¨ì«H¸¹(signal) %s\n"
+
+#, c-format
+msgid "Vim: Caught deadly signal\n"
+msgstr "Vim: ÄdºI¨ì­P©Rªº«H¸¹(deadly signale)\n"
+
+#, c-format
+msgid "Opening the X display took %ld msec"
+msgstr "¶}±Ò X Window ¯Ó®É %ld 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 "
+msgstr ""
+"\n"
+"¤£¯à°õ¦æ shell"
+
+msgid ""
+"\n"
+"Cannot execute shell sh\n"
+msgstr ""
+"\n"
+"¤£¯à°õ¦æ shell sh\n"
+
+msgid ""
+"\n"
+"shell returned "
+msgstr ""
+"\n"
+"Shell ¤wªð¦^"
+
+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ºÊ¬Ý¥¢±Ñ"
+
+#, c-format
+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!"
+
+#, c-format
+msgid "shell returned %d"
+msgstr "Shell ¶Ç¦^­È %d"
+
+#, c-format
+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"
+
+#, c-format
+msgid "E372: Too many %%%c in format string"
+msgstr "E372: ®æ¦¡¤Æ¦r¦ê¸Ì¦³¤Ó¦h %%%c "
+
+#, c-format
+msgid "E373: Unexpected %%%c in format string"
+msgstr "E373: ®æ¦¡¤Æ¦r¦ê¤£À³¸Ó¥X²{ %%%c "
+
+msgid "E374: Missing ] in format string"
+msgstr "E374: ®æ¦¡¤Æ¦r¦ê¸Ì¤Ö¤F ]"
+
+#, c-format
+msgid "E375: Unsupported %%%c in format string"
+msgstr "E375: ®æ¦¡¤Æ¦r¦ê¸Ì¦³¤£¤ä´©ªº %%%c "
+
+#, c-format
+msgid "E376: Invalid %%%c in format string prefix"
+msgstr "E376: ®æ¦¡¤Æ¦r¦ê¶}ÀY¸Ì¦³¤£¥¿½Tªº %%%c "
+
+#, c-format
+msgid "E377: Invalid %%%c in format string"
+msgstr "E377: ®æ¦¡¤Æ¦r¦ê¸Ì¦³¤£¥¿½Tªº %%%c "
+
+msgid "E378: 'errorformat' contains no pattern"
+msgstr "E378: 'errorformat' ¥¼³]©w"
+
+msgid "E379: Missing or empty directory name"
+msgstr "E379: §ä¤£¨ì¥Ø¿ý¦WºÙ©Î¬OªÅªº¥Ø¿ý¦WºÙ"
+
+msgid "E553: No more items"
+msgstr "E553: ¨S¦³¨ä¥¦¶µ¥Ø"
+
+#, c-format
+msgid "(%d of %d)%s%s: "
+msgstr "(%d / %d)%s%s: "
+
+msgid " (line deleted)"
+msgstr " (¦æ¤w§R°£)"
+
+msgid "E380: At bottom of quickfix stack"
+msgstr "E380: Quickfix °ïÅ|µ²§À"
+
+msgid "E381: At top of quickfix stack"
+msgstr "E381: Quickfix °ïÅ|³»ºÝ"
+
+#, c-format
+msgid "error list %d of %d; %d errors"
+msgstr "¿ù»~¦Cªí %d/%d; ¦@¦³ %d ¶µ¿ù»~"
+
+msgid "E382: Cannot write, 'buftype' option is set"
+msgstr "E382: µLªk¼g¤J¡A'buftype' ¿ï¶µ¤w³]©w"
+
+#, c-format
+msgid "E369: invalid item in %s%%[]"
+msgstr "E369: ¤£¥¿½Tªº¶µ¥Ø¡G %s%%[]"
+
+msgid "E339: Pattern too long"
+msgstr "E339: ¦W¦r¤Óªø"
+
+msgid "E50: Too many \\z("
+msgstr "E50: ¤Ó¦h \\z("
+
+#, c-format
+msgid "E51: Too many %s("
+msgstr "E51: ¤Ó¦h %s("
+
+msgid "E52: Unmatched \\z("
+msgstr "E52: µL¹ïÀ³ªº \\z("
+
+#, c-format
+msgid "E53: Unmatched %s%%("
+msgstr "E53: µL¹ïÀ³ªº %s%%("
+
+#, c-format
+msgid "E54: Unmatched %s("
+msgstr "E54: µL¹ïÀ³ªº %s("
+
+#, c-format
+msgid "E55: Unmatched %s)"
+msgstr "E55: µL¹ïÀ³ªº %s)"
+
+#, c-format
+msgid "E56: %s* operand could be empty"
+msgstr "E56: %s* ¹Bºâ¤¸¥i¥H¬OªÅªº"
+
+#, c-format
+msgid "E57: %s+ operand could be empty"
+msgstr "E57: %s+ ¹Bºâ¤¸¥i¥H¬OªÅªº"
+
+#, c-format
+msgid "E59: invalid character after %s@"
+msgstr "E59: «á­±¦³¤£¥¿½Tªº¦r¤¸: %s@"
+
+#, c-format
+msgid "E58: %s{ operand could be empty"
+msgstr "E58: %s{ ¹Bºâ¤¸¥i¥H¬OªÅªº"
+
+#, c-format
+msgid "E60: Too many complex %s{...}s"
+msgstr "E60: ¤Ó¦h½ÆÂøªº %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: ¤£¥¿½Tªº¨Ï¥Î \\_"
+
+#, c-format
+msgid "E64: %s%c follows nothing"
+msgstr "E64: %s%c ¨S¦³±µªF¦è"
+
+msgid "E65: Illegal back reference"
+msgstr "E65: ¤£¥¿½Tªº¤Ï¦V°Ñ¦Ò"
+
+msgid "E66: \\z( not allowed here"
+msgstr "E66: \\z( ¤£¯à¦b¦¹¥X²{"
+
+msgid "E67: \\z1 et al. not allowed here"
+msgstr "E67: \\z1 et al. ¤£¯à¦b¦¹¥X²{"
+
+msgid "E68: Invalid character after \\z"
+msgstr "E68: «á­±¦³¤£¥¿½Tªº¦r¤¸: \\z"
+
+#, c-format
+msgid "E69: Missing ] after %s%%["
+msgstr "E69: %s%%[ «á¯Ê¤Ö ]"
+
+#, c-format
+msgid "E70: Empty %s%%[]"
+msgstr "E70: ªÅªº %s%%[]"
+
+#, c-format
+msgid "E71: Invalid character after %s%%"
+msgstr "E71: «á­±¦³¤£¥¿½Tªº¦r¤¸: %s%%"
+
+#, c-format
+msgid "E554: Syntax error in %s{...}"
+msgstr "E554: »yªk¿ù»~: %s{...}"
+
+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 "External submatches:\n"
+msgstr "¥~³¡²Å¦X:\n"
+
+#, c-format
+msgid "+--%3ld lines folded "
+msgstr "+--¤w fold %3ld ¦æ "
+
+msgid " VREPLACE"
+msgstr " V-¨ú¥N"
+
+msgid " REPLACE"
+msgstr " ¨ú¥N"
+
+msgid " REVERSE"
+msgstr " ¤ÏÂà"
+
+msgid " INSERT"
+msgstr " ´¡¤J"
+
+msgid " (insert)"
+msgstr " (´¡¤J)"
+
+msgid " (replace)"
+msgstr " (¨ú¥N)"
+
+msgid " (vreplace)"
+msgstr " (v-¨ú¥N)"
+
+msgid " Hebrew"
+msgstr " Hebrew"
+
+msgid " Arabic"
+msgstr " Arabic"
+
+msgid " (lang)"
+msgstr " (»y¨¥)"
+
+msgid " (paste)"
+msgstr " (¶K¤W)"
+
+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 "°O¿ý¤¤"
+
+msgid "search hit TOP, continuing at BOTTOM"
+msgstr "¤w·j´M¨ìÀÉ®×¶}ÀY¡F¦A±qµ²§ÀÄ~Äò·j´M"
+
+msgid "search hit BOTTOM, continuing at TOP"
+msgstr "¤w·j´M¨ìÀÉ®×µ²§À¡F¦A±q¶}ÀYÄ~Äò·j´M"
+
+#, c-format
+msgid "E383: Invalid search string: %s"
+msgstr "E383: ¿ù»~ªº·j´M¦r¦ê: %s"
+
+#, c-format
+msgid "E384: search hit TOP without match for: %s"
+msgstr "E384: ¤w·j´M¨ìÀÉ®×¶}ÀY¤´§ä¤£¨ì %s"
+
+#, c-format
+msgid "E385: search hit BOTTOM without match for: %s"
+msgstr "E385: ¤w·j´M¨ìÀÉ®×µ²§À¤´§ä¤£¨ì %s"
+
+msgid "E386: Expected '?' or '/' after ';'"
+msgstr "E386: ¦b ';' «á­±À³¸Ó¦³ '?' ©Î '/'"
+
+msgid " (includes previously listed match)"
+msgstr " (¥]¬A«e¦¸¦C¥X²Å¦X¶µ)"
+
+#. cursor at status line
+msgid "--- Included files "
+msgstr "--- ¤Þ¤JÀÉ®× "
+
+msgid "not found "
+msgstr "§ä¤£¨ì "
+
+msgid "in path ---\n"
+msgstr "---\n"
+
+msgid " (Already listed)"
+msgstr " (¤w¦C¥X)"
+
+msgid " NOT FOUND"
+msgstr " §ä¤£¨ì"
+
+#, c-format
+msgid "Scanning included file: %s"
+msgstr "·j´M¤Þ¤JÀÉ®×: %s"
+
+msgid "E387: Match is on current line"
+msgstr "E387: ¥Ø«e©Ò¦b¦æ¤¤¦³¤@¤Ç°t"
+
+msgid "All included files were found"
+msgstr "©Ò¦³¤Þ¤JÀɮ׳£¤w§ä¨ì"
+
+msgid "No included files"
+msgstr "¨S¦³¤Þ¤JÀÉ®×"
+
+msgid "E388: Couldn't find definition"
+msgstr "E388: §ä¤£¨ì©w¸q"
+
+msgid "E389: Couldn't find pattern"
+msgstr "E389: §ä¤£¨ì pattern"
+
+#, c-format
+msgid "E390: Illegal argument: %s"
+msgstr "E390: °Ñ¼Æ¤£¥¿½T: %s"
+
+#, c-format
+msgid "E391: No such syntax cluster: %s"
+msgstr "E391: µL¦¹ syntax cluster: \"%s\""
+
+msgid "No Syntax items defined for this buffer"
+msgstr "³o­Ó½w½Ä°Ï¨S¦³©w¸q¥ô¦ó»yªk"
+
+msgid "syncing on C-style comments"
+msgstr "C»y¨¥¦¡µù¸Ñ¦P¨B¤Æ¤¤"
+
+msgid "no syncing"
+msgstr "¨S¦³¦P¨B¤Æ"
+
+msgid "syncing starts "
+msgstr "¦P¨B¤Æ¶}©l"
+
+msgid " lines before top line"
+msgstr "¦æ¸¹¶W¥X½d³ò"
+
+msgid ""
+"\n"
+"--- Syntax sync items ---"
+msgstr ""
+"\n"
+"--- »yªk¦P¨Bª«¥ó (Syntax sync items) ---"
+
+msgid ""
+"\n"
+"syncing on items"
+msgstr ""
+"\n"
+"¦P¨B¤Æ¤¤:"
+
+msgid ""
+"\n"
+"--- Syntax items ---"
+msgstr ""
+"\n"
+"--- »yªk¶µ¥Ø ---"
+
+#, c-format
+msgid "E392: No such syntax cluster: %s"
+msgstr "E392: µL¦¹ syntax cluster: \"%s\""
+
+msgid "minimal "
+msgstr "³Ì¤p"
+
+msgid "maximal "
+msgstr "³Ì¤j"
+
+msgid "; match "
+msgstr "; ²Å¦X "
+
+msgid " line breaks"
+msgstr "Â_¦æ "
+
+msgid "E393: group[t]here not accepted here"
+msgstr "E393: ¨Ï¥Î¤F¤£¥¿½Tªº°Ñ¼Æ"
+
+#, c-format
+msgid "E394: Didn't find region item for %s"
+msgstr "E394: §ä¤£¨ì %s ªº region item"
+
+msgid "E395: contains argument not accepted here"
+msgstr "E395: ¨Ï¥Î¤F¤£¥¿½Tªº°Ñ¼Æ"
+
+msgid "E396: containedin argument not accepted here"
+msgstr "E396: ¨Ï¥Î¤F¤£¥¿½Tªº°Ñ¼Æ"
+
+msgid "E397: Filename required"
+msgstr "E397: »Ý­nÀɮצWºÙ"
+
+#, c-format
+msgid "E398: Missing '=': %s"
+msgstr "E398: ¯Ê¤Ö \"=\": %s"
+
+#, c-format
+msgid "E399: Not enough arguments: syntax region %s"
+msgstr "E399: syntax region %s ªº¤Þ¼Æ¤Ó¤Ö"
+
+msgid "E400: No cluster specified"
+msgstr "E400: ¨S¦³«ü©wªºÄÝ©Ê"
+
+#, c-format
+msgid "E401: Pattern delimiter not found: %s"
+msgstr "E401: §ä¤£¨ì¤À¹j²Å¸¹: %s"
+
+#, c-format
+msgid "E402: Garbage after pattern: %s"
+msgstr "E402: '%s' «á­±ªºªF¦èµLªk¿ëÃÑ"
+
+msgid "E403: syntax sync: line continuations pattern specified twice"
+msgstr "E403: »yªk¦P¨B: ³s±µ¦æ²Å¸¹³Q«ü©w¤F¨â¦¸"
+
+#, c-format
+msgid "E404: Illegal arguments: %s"
+msgstr "E404: °Ñ¼Æ¤£¥¿½T: %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 ¤£¯à¦b¦¹¥X²{"
+
+#, c-format
+msgid "E408: %s must be first in contains list"
+msgstr "E408: %s ¥²¶·¬O¦Cªí¸Ìªº²Ä¤@­Ó"
+
+#, c-format
+msgid "E409: Unknown group name: %s"
+msgstr "E409: ¤£¥¿½Tªº¸s²Õ¦WºÙ: %s"
+
+#, c-format
+msgid "E410: Invalid :syntax subcommand: %s"
+msgstr "E410: ¤£¥¿½Tªº :syntax ¤l©R¥O: %s"
+
+#, c-format
+msgid "E411: highlight group not found: %s"
+msgstr "E411: §ä¤£¨ì highlight group: %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: °Ñ¼Æ¹L¦h: \":highlight link %s\""
+
+msgid "E414: group has settings, highlight link ignored"
+msgstr "E414: ¤w³]©w¸s²Õ, ©¿²¤ 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: ¤£¦Xªkªº­È: %s"
+
+msgid "E419: FG color unknown"
+msgstr "E419: ¿ù»~ªº«e´ºÃC¦â"
+
+msgid "E420: BG color unknown"
+msgstr "E420: ¿ù»~ªº­I´ºÃC¦â"
+
+#, c-format
+msgid "E421: Color name or number not recognized: %s"
+msgstr "E421: ¿ù»~ªºÃC¦â¦WºÙ©Î¼Æ­È: %s"
+
+#, c-format
+msgid "E422: terminal code too long: %s"
+msgstr "E422: ²×ºÝ¾÷½X¤Óªø: %s"
+
+#, c-format
+msgid "E423: Illegal argument: %s"
+msgstr "E423: °Ñ¼Æ¤£¥¿½T: %s"
+
+msgid "E424: Too many different highlighting attributes in use"
+msgstr "E424: ¨Ï¥Î¤F¹L¦h¬Û²§ªº°ª«G«×ÄÝ©Ê"
+
+msgid "E669: Unprintable character in group name"
+msgstr "E669: ¸s²Õ¦WºÙ¤¤¦³µLªk¦C¦Lªº¦r¤¸"
+
+#. This is an error, but since there previously was no check only
+#. * give a warning.
+msgid "W18: Invalid character in group name"
+msgstr "W18: ¸s²Õ¦WºÙ¤¤¦³¤£¥¿½Tªº¦r¤¸"
+
+msgid "E555: at bottom of tag stack"
+msgstr "E555: ¼ÐÅÒ(tag)°ïÅ|µ²§À"
+
+msgid "E556: at top of tag stack"
+msgstr "E556: ¼ÐÅÒ(tag)°ïÅ|¶}ÀY"
+
+msgid "E425: Cannot go before first matching tag"
+msgstr "E425: ¤w¸g¦b³Ì«e­±ªº¼ÐÅÒ(tag)¤F"
+
+#, c-format
+msgid "E426: tag not found: %s"
+msgstr "E426: §ä¤£¨ì¼ÐÅÒ(tag): %s"
+
+msgid " # pri kind tag"
+msgstr " # pri kind tag"
+
+msgid "file\n"
+msgstr "ÀÉ®×\n"
+
+#.
+#. * Ask to select a tag from the list.
+#. * When using ":silent" assume that <CR> was entered.
+#.
+msgid "Enter nr of choice (<CR> to abort): "
+msgstr "¿é¤J nr ©Î¿ï¾Ü (<CR> Â÷¶}): "
+
+msgid "E427: There is only one matching tag"
+msgstr "E427: ¥u¦³¦¹¶µ²Å¦X"
+
+msgid "E428: Cannot go beyond last matching tag"
+msgstr "E428: ¤v¸g¦b³Ì«á¤@­Ó²Å¦Xªº tag ¤F"
+
+#, c-format
+msgid "File \"%s\" does not exist"
+msgstr "ÀÉ®× \"%s\" ¤£¦s¦b"
+
+#. Give an indication of the number of matching tags
+#, c-format
+msgid "tag %d of %d%s"
+msgstr "§ä¨ì tag: %d/%d%s"
+
+msgid " or more"
+msgstr " ©Î§ó¦h"
+
+msgid " Using tag with different case!"
+msgstr " ¥H¤£¦P¤j¤p¼g¨Ó¨Ï¥Î tag!"
+
+#, c-format
+msgid "E429: File \"%s\" does not exist"
+msgstr "E429: ÀÉ®× \"%s\" ¤£¦s¦b"
+
+#. Highlight title
+msgid ""
+"\n"
+" # TO tag FROM line in file/text"
+msgstr ""
+"\n"
+" # ¨ì tag ±q ¦æ ¦b ÀÉ®×/¤å¦r"
+
+#, c-format
+msgid "Searching tags file %s"
+msgstr "·j´M tag ÀÉ®× \"%s\""
+
+#, c-format
+msgid "E430: Tag file path truncated for %s\n"
+msgstr "E430: Tag Àɮ׸ô®|³QºIÂ_¬° %s\n"
+
+#, c-format
+msgid "E431: Format error in tags file \"%s\""
+msgstr "E431: Tag ÀÉ \"%s\" ®æ¦¡¿ù»~"
+
+#, c-format
+msgid "Before byte %ld"
+msgstr "¦b %ld ¦ì¤¸¤§«e"
+
+#, c-format
+msgid "E432: Tags file not sorted: %s"
+msgstr "E432: Tag ÀÉ®×¥¼±Æ§Ç: %s"
+
+#. never opened any tags file
+msgid "E433: No tags file"
+msgstr "E433: ¨S¦³ tag ÀÉ"
+
+msgid "E434: Can't find tag pattern"
+msgstr "E434: §ä¤£¨ì tag"
+
+msgid "E435: Couldn't find tag, just guessing!"
+msgstr "E435: §ä¤£¨ì tag, ¥Î²qªº!"
+
+msgid "' not known. Available builtin terminals are:"
+msgstr "' µLªk¸ü¤J¡C¥i¥Îªº¤º«Ø²×ºÝ¾÷§Î¦¡¦³:"
+
+msgid "defaulting to '"
+msgstr "¹w³]: '"
+
+msgid "E557: Cannot open termcap file"
+msgstr "E557: µLªk¶}±Ò termcap ÀÉ®×"
+
+msgid "E558: Terminal entry not found in terminfo"
+msgstr "E558: terminfo ¤¤¨S¦³²×ºÝ¾÷¸ê®Æ¶µ"
+
+msgid "E559: Terminal entry not found in termcap"
+msgstr "E559: termcap ¤¤¨S¦³²×ºÝ¾÷¸ê®Æ¶µ"
+
+#, c-format
+msgid "E436: No \"%s\" entry in termcap"
+msgstr "E436: termcap ¨S¦³ \"%s\" entry"
+
+msgid "E437: terminal capability \"cm\" required"
+msgstr "E437: ²×ºÝ¾÷»Ý­n \"cm\" ªº¯à¤O"
+
+#. Highlight title
+msgid ""
+"\n"
+"--- Terminal keys ---"
+msgstr ""
+"\n"
+"--- ²×ºÝ¾÷«öÁä ---"
+
+msgid "new shell started\n"
+msgstr "°_°Ê·s shell\n"
+
+msgid "Vim: Error reading input, exiting...\n"
+msgstr "Vim: Ū¨ú¿é¤J¿ù»~¡AÂ÷¶}¤¤...\n"
+
+#. must display the prompt
+msgid "No undo possible; continue anyway"
+msgstr "µLªkÁÙ­ì¡F½ÐÄ~Äò§V¤O"
+
+msgid "E438: u_undo: line numbers wrong"
+msgstr "E438: u_undo: ¦æ¸¹¿ù»~"
+
+msgid "1 change"
+msgstr "¤@¶µ§ïÅÜ"
+
+#, c-format
+msgid "%ld changes"
+msgstr "%ld ¶µ§ïÅÜ"
+
+msgid "E439: undo list corrupt"
+msgstr "E439: ´_­ì¦Cªí·lÃa"
+
+msgid "E440: undo line missing"
+msgstr "E440: §ä¤£¨ì­n undo ªº¦æ "
+
+#. Only MS VC 4.1 and earlier can do Win32s
+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"
+"Included patches: "
+msgstr ""
+"\n"
+"¤Þ¤J­×¥¿: "
+
+msgid "Modified by "
+msgstr "­×§ïªÌ¬°"
+
+msgid ""
+"\n"
+"Compiled "
+msgstr ""
+"\n"
+"½sĶ"
+
+msgid "by "
+msgstr "ªÌ:"
+
+msgid ""
+"\n"
+"Huge version "
+msgstr ""
+"\n"
+"¶W±jª©¥» "
+
+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 "without GUI."
+msgstr "¤£¨Ï¥Î¹Ï«¬¬É­±¡C"
+
+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 " Features included (+) or not (-):\n"
+msgstr " ¥Ø«e¥i¨Ï¥Î(+)»P¤£¥i¨Ï¥Î(-)ªº¼Ò²Õ¦Cªí:\n"
+
+msgid " system vimrc file: \""
+msgstr " ¨t²Î vimrc ³]©wÀÉ: \""
+
+msgid " user vimrc file: \""
+msgstr " ¨Ï¥ÎªÌ­Ó¤H vimrc ³]©wÀÉ: \""
+
+msgid " 2nd user vimrc file: \""
+msgstr " ²Ä¤G²Õ­Ó¤H vimrc ÀÉ®×: \""
+
+msgid " 3rd user vimrc file: \""
+msgstr " ²Ä¤T²Õ­Ó¤H vimrc ÀÉ®×: \""
+
+msgid " user exrc file: \""
+msgstr " ¨Ï¥ÎªÌ­Ó¤H exrc ³]©wÀÉ: \""
+
+msgid " 2nd user exrc file: \""
+msgstr " ²Ä¤G²Õ¨Ï¥ÎªÌ exrc ÀÉ®×: \""
+
+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 " fall-back for $VIM: \""
+msgstr " $VIM ¹w³]­È: \""
+
+msgid " f-b for $VIMRUNTIME: \""
+msgstr " $VIMRUNTIME ¹w³]­È: \""
+
+msgid "Compilation: "
+msgstr "½sĶ¤è¦¡: "
+
+msgid "Compiler: "
+msgstr "½s;¹: "
+
+msgid "Linking: "
+msgstr "Ãìµ²¤è¦¡: "
+
+msgid " DEBUG BUILD"
+msgstr " °£¿ùª©¥»"
+
+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 ¬°¥i¦Û¥Ñ´²§Gªº¶}©ñ­ì©l½X³nÅé"
+
+msgid "Help poor children in Uganda!"
+msgstr "½ÐÀ°§U¯Q¤z¹Fªº¥i¼¦«Äµ£!"
+
+msgid "type :help iccf<Enter> for information "
+msgstr "¶i¤@¨B»¡©ú½Ð¿é¤J :help iccf<Enter>"
+
+msgid "type :q<Enter> to exit "
+msgstr "­nÂ÷¶}½Ð¿é¤J :q<Enter> "
+
+msgid "type :help<Enter> or <F1> for on-line help"
+msgstr "½u¤W»¡©ú½Ð¿é¤J :help<Enter> "
+
+msgid "type :help version7<Enter> for version info"
+msgstr "·sª©¥»¸ê°T½Ð¿é¤J :help version7<Enter>"
+
+msgid "Running in Vi compatible mode"
+msgstr "Vi ¬Û®e¼Ò¦¡"
+
+msgid "type :set nocp<Enter> for Vim defaults"
+msgstr "¦pªG­n§¹¥þ¼ÒÀÀ¶Ç²Î Vi ½Ð¿é¤J :set nocp<Enter>"
+
+msgid "type :help cp-default<Enter> for info on this"
+msgstr "¦pªG»Ý­n¹ï Vi ¬Û®e¼Ò¦¡ªº¶i¤@¨B»¡©ú½Ð¿é¤J :help cp-default<Enter>"
+
+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 "Sponsor Vim development!"
+msgstr "ÃÙ§U Vim ªº¶}µo»P¦¨ªø¡I"
+
+msgid "Become a registered Vim user!"
+msgstr "¦¨¬° Vim ªºµù¥U¨Ï¥ÎªÌ¡I"
+
+msgid "type :help sponsor<Enter> for information "
+msgstr "¸Ô²Ó»¡©ú½Ð¿é¤J :help sponsor<Enter>"
+
+msgid "type :help register<Enter> for information "
+msgstr "¸Ô²Ó»¡©ú½Ð¿é¤J :help register<Enter> "
+
+msgid "menu Help->Sponsor/Register for information "
+msgstr "¸Ô²Ó»¡©ú½Ð¿ï¨ú¿ï³æªº »²§U»¡©ú->ÃÙ§U/µù¥U "
+
+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 "E441: There is no preview window"
+msgstr "E441: ¨S¦³¹wÄýµøµ¡"
+
+msgid "E442: Can't split topleft and botright at the same time"
+msgstr "E442: ¤£¯à¦P®É¤À³Îµøµ¡¬°¥ª¤W©M¥k¤U¨¤"
+
+msgid "E443: Cannot rotate when another window is split"
+msgstr "E443: ¦³¨ä¥¦¤À³Îµøµ¡®ÉµLªk±ÛÂà"
+
+msgid "E444: Cannot close last window"
+msgstr "E444: ¤£¯àÃö³¬³Ì«á¤@­Óµøµ¡"
+
+msgid "Already only one window"
+msgstr "¤w¸g¥u³Ñ¤@­Óµøµ¡¤F"
+
+msgid "E445: Other window contains changes"
+msgstr "E445: ¨ä¥¦µøµ¡¦³§ó°Ê¸ê®Æ"
+
+msgid "E446: No file name under cursor"
+msgstr "E446: ´å¼Ð³B¨S¦³ÀɦW"
+
+#, c-format
+msgid "E447: Can't find file \"%s\" in path"
+msgstr "E447: ¦b¸ô®|¤¤§ä¤£¨ìÀÉ®× \"%s\""
+
+#, c-format
+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)"
+
+#. Now concatenate
+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 "--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.
+#.
+msgid "E470: Command aborted"
+msgstr "E470: ©R¥O³Q±j¨î¤¤Â_°õ¦æ "
+
+msgid "E471: Argument required"
+msgstr "E471: »Ý­n«ü¥O°Ñ¼Æ"
+
+msgid "E10: \\ should be followed by /, ? or &"
+msgstr "E10: \\ «á­±À³¸Ó¦³ / ? ©Î &"
+
+msgid "E11: Invalid in command-line window; <CR> executes, CTRL-C quits"
+msgstr "E11: ¤£¯à¦b©R¥O¦Cµøµ¡¤¤¨Ï¥Î¡C<CR>°õ¦æ¡ACTRL-C Â÷¶}"
+
+msgid "E12: Command not allowed from exrc/vimrc in current dir or tag search"
+msgstr "E12: exrc/vimrc ¸Ìªº«ü¥OµLªk°õ¦æ "
+
+msgid "E171: Missing :endif"
+msgstr "E171: ¯Ê¤Ö :endif"
+
+msgid "E600: Missing :endtry"
+msgstr "E600: ¯Ê¤Ö :endtry"
+
+msgid "E170: Missing :endwhile"
+msgstr "E170: ¯Ê¤Ö :endwhile"
+
+msgid "E588: :endwhile without :while"
+msgstr "E588: :endwhile ¯Ê¤Ö¹ïÀ³ªº :while"
+
+msgid "E13: File exists (add ! to override)"
+msgstr "E13: Àɮפw¸g¦s¦b (¥i¥Î ! ±j¨î¨ú¥N)"
+
+msgid "E472: Command failed"
+msgstr "E472: ©R¥O°õ¦æ¥¢±Ñ"
+
+#, c-format
+msgid "E234: Unknown fontset: %s"
+msgstr "E234: ¤£¥¿½Tªº¦r¤¸¶° (Fontset): %s"
+
+#, c-format
+msgid "E235: Unknown font: %s"
+msgstr "E235: ¤£¥¿½Tªº¦r«¬¦WºÙ: %s"
+
+#, c-format
+msgid "E236: Font \"%s\" is not fixed-width"
+msgstr "E236: \"%s\" ¤£¬O©T©w¼e«×¦r«¬"
+
+msgid "E473: Internal error"
+msgstr "E473: ¤º³¡¿ù»~"
+
+msgid "Interrupted"
+msgstr "¤w¤¤Â_"
+
+msgid "E14: Invalid address"
+msgstr "E14: ¤£¥¿½Tªº¦ì§}"
+
+msgid "E474: Invalid argument"
+msgstr "E474: ¤£¥¿½Tªº°Ñ¼Æ"
+
+#, c-format
+msgid "E475: Invalid argument: %s"
+msgstr "E475: ¤£¥¿½Tªº°Ñ¼Æ: %s"
+
+#, c-format
+msgid "E15: Invalid expression: %s"
+msgstr "E15: ¤£¥¿½Tªº¹Bºâ¦¡: %s"
+
+msgid "E16: Invalid range"
+msgstr "E16: ¤£¥¿½Tªº½d³ò"
+
+msgid "E476: Invalid command"
+msgstr "E476: ¤£¥¿½Tªº©R¥O"
+
+#, c-format
+msgid "E17: \"%s\" is a directory"
+msgstr "E17: \"%s\" ¬O¥Ø¿ý"
+
+msgid "E18: Unexpected characters before '='"
+msgstr "E18: '=' «e­±¥X²{¤F¿ù»~ªº¦r¤¸"
+
+#, c-format
+msgid "E364: Library call failed for \"%s()\""
+msgstr "E364: ©I¥s¨ç¦¡®w \"%s\"() ¥¢±Ñ"
+
+#, c-format
+msgid "E448: Could not load library function %s"
+msgstr "E448: µLªk¸ü¤Jµ{¦¡®wªº¨ç¦¡ %s"
+
+msgid "E19: Mark has invalid line number"
+msgstr "E19: ¼Ð°Oªº¦æ¸¹¿ù»~"
+
+msgid "E20: Mark not set"
+msgstr "E20: ¨S¦³³]©w¼Ð°O"
+
+msgid "E21: Cannot make changes, 'modifiable' is off"
+msgstr "E21: ¦]¬° 'modifiable' ¿ï¶µ¬OÃö³¬ªº¡A©Ò¥H¤£¯à­×§ï"
+
+msgid "E22: Scripts nested too deep"
+msgstr "E22: ±_ª¬»¼°j©I¥s¤Ó¦h¼h"
+
+msgid "E23: No alternate file"
+msgstr "E23: ¨S¦³´À¥NªºÀÉ®×"
+
+msgid "E24: No such abbreviation"
+msgstr "E24: ¨S¦³³o­Ó abbreviation ¹ïÀ³"
+
+msgid "E477: No ! allowed"
+msgstr "E477: ¤£¥i¨Ï¥Î '!'"
+
+msgid "E25: GUI cannot be used: Not enabled at compile time"
+msgstr "E25: ¦]¬°½sͮɍS¦³¥[¤J¹Ï«¬¬É­±ªºµ{¦¡½X¡A©Ò¥HµLªk¨Ï¥Î¹Ï«¬¬É­±"
+
+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"
+
+#, c-format
+msgid "E28: No such highlight group name: %s"
+msgstr "E28: ¨S¦³¦W¬° '%s' ªº highlight group"
+
+msgid "E29: No inserted text yet"
+msgstr "E29: ÁÙ¨S¦³´¡¤J¤å¦r¹L"
+
+msgid "E30: No previous command line"
+msgstr "E30: ¨S¦³«e¤@¶µ©R¥O"
+
+msgid "E31: No such mapping"
+msgstr "E31: ¨S¦³³o­Ó mapping ¹ïÀ³"
+
+msgid "E479: No match"
+msgstr "E479: §ä¤£¨ì"
+
+#, c-format
+msgid "E480: No match: %s"
+msgstr "E480: §ä¤£¨ì: %s"
+
+msgid "E32: No file name"
+msgstr "E32: ¨S¦³ÀɦW"
+
+msgid "E33: No previous substitute regular expression"
+msgstr "E33: ¨S¦³«e¤@­Ó·j´M/¨ú¥Nªº©R¥O"
+
+msgid "E34: No previous command"
+msgstr "E34: ¨S¦³«e¤@­Ó©R¥O"
+
+msgid "E35: No previous regular expression"
+msgstr "E35: ¨S¦³«e¤@­Ó·j´M«ü¥O"
+
+msgid "E481: No range allowed"
+msgstr "E481: ¤£¥i¨Ï¥Î½d³ò«ü¥O"
+
+msgid "E36: Not enough room"
+msgstr "E36: ¨S¦³¨¬°÷ªºªÅ¶¡"
+
+#, c-format
+msgid "E247: no registered server named \"%s\""
+msgstr "E247: ¨S¦³µù¥U¬° \"%s\" ªº¦øªA¾¹"
+
+#, c-format
+msgid "E482: Can't create file %s"
+msgstr "E482: ¤£¯à«Ø¥ßÀÉ®× %s"
+
+msgid "E483: Can't get temp file name"
+msgstr "E483: µLªk±oª¾¼È¦sÀɦW"
+
+#, c-format
+msgid "E484: Can't open file %s"
+msgstr "E484: µLªk¶}±ÒÀÉ®× %s"
+
+#, c-format
+msgid "E485: Can't read file %s"
+msgstr "E485: µLªkŪ¨úÀÉ®× %s"
+
+msgid "E37: No write since last change (add ! to override)"
+msgstr "E37: ¤w§ó§ï¹LÀɮצý©|¥¼¦sÀÉ (¥i¥Î ! ±j¨î°õ¦æ)"
+
+msgid "E38: Null argument"
+msgstr "E38: ªÅªº (Null) °Ñ¼Æ"
+
+msgid "E39: Number expected"
+msgstr "E39: À³¸Ó­n¦³¼Æ¦r"
+
+#, c-format
+msgid "E40: Can't open errorfile %s"
+msgstr "E40: µLªk¶}±Ò¿ù»~ÀÉ®× %s"
+
+msgid "E233: cannot open display"
+msgstr "E233: <¤£¯à¶}±Ò X Server DISPLAY>"
+
+msgid "E41: Out of memory!"
+msgstr "E41: °O¾ÐÅ餣¨¬!"
+
+msgid "Pattern not found"
+msgstr "§ä¤£¨ì"
+
+#, c-format
+msgid "E486: Pattern not found: %s"
+msgstr "E486: §ä¤£¨ì %s"
+
+msgid "E487: Argument must be positive"
+msgstr "E487: °Ñ¼ÆÀ³¸Ó¬O¥¿¼Æ"
+
+msgid "E459: Cannot go back to previous directory"
+msgstr "E459: µLªk¦^¨ì«e¤@­Ó¥Ø¿ý"
+
+msgid "E42: No Errors"
+msgstr "E42: ¨S¦³¿ù»~"
+
+msgid "E43: Damaged match string"
+msgstr "E43: ²Å¦X¦r¦ê¦³°ÝÃD"
+
+msgid "E44: Corrupted regexp program"
+msgstr "E44: regexp ¦³°ÝÃD"
+
+msgid "E45: 'readonly' option is set (add ! to override)"
+msgstr "E45: ¦³³]©w 'readonly' ¿ï¶µ(°ßŪ) (¥i¥Î ! ±j¨î°õ¦æ)"
+
+#, c-format
+msgid "E46: Cannot set read-only variable \"%s\""
+msgstr "E46: µLªk³]©w°ßŪÅÜ¼Æ \"%s\""
+
+msgid "E47: Error while reading errorfile"
+msgstr "E47: Ū¨ú¿ù»~ÀÉ®×¥¢±Ñ"
+
+msgid "E48: Not allowed in sandbox"
+msgstr "E48: ¤£¯à¦b sandbox ¸Ì¥X²{"
+
+msgid "E523: Not allowed here"
+msgstr "E523: ³o¸Ì¤£¥i¨Ï¥Î"
+
+msgid "E359: Screen mode setting not supported"
+msgstr "E359: ¤£¤ä´©³]©w¿Ã¹õ¼Ò¦¡"
+
+msgid "E49: Invalid scroll size"
+msgstr "E49: ¿ù»~ªº±²°Ê¤j¤p"
+
+msgid "E91: 'shell' option is empty"
+msgstr "E91: 'E71: ¿ï¶µ 'shell' ¥¼³]©w"
+
+msgid "E255: Couldn't read in sign data!"
+msgstr "E255: µLªkŪ¨ú sign data!"
+
+msgid "E72: Close error on swap file"
+msgstr "E72: ¼È¦sÀÉÃö³¬¿ù»~"
+
+msgid "E73: tag stack empty"
+msgstr "E73: ¼ÐÅÒ°ïÅ|¤wªÅ"
+
+msgid "E74: Command too complex"
+msgstr "E74: ©R¥O¤Ó½ÆÂø"
+
+msgid "E75: Name too long"
+msgstr "E75: ¦W¦r¤Óªø"
+
+msgid "E76: Too many ["
+msgstr "E76: ¤Ó¦h ["
+
+msgid "E77: Too many file names"
+msgstr "E77: ¤Ó¦hÀɦW"
+
+msgid "E488: Trailing characters"
+msgstr "E488: §A¿é¤J¤F¦h¾lªº¦r¤¸"
+
+msgid "E78: Unknown mark"
+msgstr "E78: µLªk¿ìÃѪº¼Ð°O"
+
+msgid "E79: Cannot expand wildcards"
+msgstr "E79: µLªk®i¶}¸U¥Î¦r¤¸"
+
+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: ¼g¤J¿ù»~"
+
+msgid "Zero count"
+msgstr "¼Æ¨ì¹s (?)"
+
+msgid "E81: Using <SID> not in a script context"
+msgstr "E81: <SID> ¤£¯à¦b script ¥»¤å¥~¨Ï¥Î."
+
+msgid "E449: Invalid expression received"
+msgstr "E449: ¦¬¨ì¤£¥¿½Tªº¹Bºâ¦¡"
+
+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 "E221: 'commentstring' is empty"
+#~ msgstr "E221: ¿ï¶µ 'commentstring' ¥¼³]©w"
+
+#~ msgid "E242: Color name not recognized: %s"
+#~ msgstr "E242: %s ¬°µLªkÃѧOªºÃC¦â¦WºÙ"
+
+#~ msgid "E242: Missing color: %s"
+#~ msgstr "E242: §ä¤£¨ìÃC¦â: %s"
+
+#~ 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 "Can't open file %s"
+#~ msgstr "µLªk¶}±ÒÀÉ®× %s"
+
+#~ msgid "Unable to send reply"
+#~ msgstr "µLªk¶Ç°e¦^À³°T®§"
+
+#~ 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/popupmnu.c b/src/popupmnu.c
new file mode 100644
index 0000000000..ff28fc2676
--- /dev/null
+++ b/src/popupmnu.c
@@ -0,0 +1,617 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * 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.
+ */
+
+/*
+ * popupmnu.c: Popup menu (PUM)
+ */
+#include "vim.h"
+
+
+static pumitem_T *pum_array = NULL; /* items of displayed pum */
+static int pum_size; /* nr of items in "pum_array" */
+static int pum_selected; /* index of selected item or -1 */
+static int pum_first = 0; /* index of top item */
+
+static int pum_height; /* nr of displayed pum items */
+static int pum_width; /* width of displayed pum items */
+static int pum_base_width; /* width of pum items base */
+static int pum_kind_width; /* width of pum items kind column */
+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 int pum_set_selected __ARGS((int n, int repeat));
+
+#define PUM_DEF_HEIGHT 10
+#define PUM_DEF_WIDTH 15
+
+/*
+ * Show the popup menu with items "array[size]".
+ * "array" must remain valid until pum_undisplay() is called!
+ * When possible the leftmost character is aligned with screen column "col".
+ * The menu appears above the screen line "row" or at "row" + "height" - 1.
+ */
+void pum_display(array, size, selected)
+pumitem_T *array;
+int size;
+int selected; /* index of initially selected item, none if
+ out of range */
+{
+ int w;
+ int def_width;
+ int max_width;
+ int kind_width;
+ int extra_width;
+ int i;
+ int top_clear;
+ int row;
+ int context_lines;
+ int col;
+ int above_row = cmdline_row;
+ int redo_count = 0;
+
+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 + W_WINROW(curwin);
+
+ 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 = p_ph;
+
+ /* 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" */
+
+ /* 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;
+
+ if (row >= size + context_lines) {
+ pum_row = row - size - context_lines;
+ pum_height = size;
+ } else {
+ pum_row = 0;
+ pum_height = row - context_lines;
+ }
+ if (p_ph > 0 && pum_height > p_ph) {
+ pum_row += pum_height - p_ph;
+ pum_height = 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;
+
+ pum_row = row + context_lines;
+ if (size > above_row - pum_row)
+ pum_height = above_row - pum_row;
+ else
+ pum_height = size;
+ if (p_ph > 0 && pum_height > p_ph)
+ pum_height = p_ph;
+ }
+
+ /* don't display when we only have room for one line */
+ if (pum_height < 1 || (pum_height == 1 && size > 1))
+ return;
+
+ /* 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;
+ }
+
+ /* 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 (max_width < w)
+ max_width = w;
+ if (array[i].pum_kind != NULL) {
+ w = vim_strsize(array[i].pum_kind) + 1;
+ if (kind_width < w)
+ kind_width = w;
+ }
+ if (array[i].pum_extra != NULL) {
+ w = vim_strsize(array[i].pum_extra) + 1;
+ if (extra_width < w)
+ extra_width = w;
+ }
+ }
+ pum_base_width = max_width;
+ pum_kind_width = kind_width;
+
+ /* Calculate column */
+ if (curwin->w_p_rl)
+ col = W_WINCOL(curwin) + W_WIDTH(curwin) - curwin->w_wcol - 1;
+ else
+ col = W_WINCOL(curwin) + curwin->w_wcol;
+
+ /* 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 (def_width < max_width)
+ def_width = max_width;
+
+ 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
+ pum_width = 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)
+ pum_col = Columns - 1;
+ else
+ pum_col = 0;
+ pum_width = Columns - 1;
+ } else {
+ if (max_width > PUM_DEF_WIDTH)
+ max_width = PUM_DEF_WIDTH; /* truncate */
+ if (curwin->w_p_rl)
+ pum_col = max_width - 1;
+ else
+ pum_col = Columns - max_width;
+ pum_width = max_width - pum_scrollbar;
+ }
+
+ 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;
+}
+
+/*
+ * Redraw the popup menu, using "pum_first" and "pum_selected".
+ */
+void pum_redraw() {
+ 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;
+ int i;
+ int idx;
+ char_u *s;
+ char_u *p = NULL;
+ int totwidth, width, w;
+ int thumb_pos = 0;
+ int thumb_heigth = 1;
+ int round;
+ int n;
+
+ /* Never display more than we have */
+ if (pum_first > pum_size - pum_height)
+ pum_first = pum_size - pum_height;
+
+ if (pum_scrollbar) {
+ thumb_heigth = pum_height * pum_height / pum_size;
+ if (thumb_heigth == 0)
+ thumb_heigth = 1;
+ thumb_pos = (pum_first * (pum_height - thumb_heigth)
+ + (pum_size - pum_height) / 2)
+ / (pum_size - pum_height);
+ }
+
+ for (i = 0; i < pum_height; ++i) {
+ idx = i + pum_first;
+ attr = (idx == pum_selected) ? attr_select : attr_norm;
+
+ /* prepend a space if there is room */
+ if (curwin->w_p_rl) {
+ if (pum_col < W_WINCOL(curwin) + W_WIDTH(curwin) - 1)
+ screen_putchar(' ', row, pum_col + 1, attr);
+ } else if (pum_col > 0)
+ screen_putchar(' ', row, pum_col - 1, attr);
+
+ /* Display each entry, use two spaces for a Tab.
+ * Do this 3 times: For the main text, kind and extra info */
+ col = pum_col;
+ totwidth = 0;
+ for (round = 1; round <= 3; ++round) {
+ width = 0;
+ s = NULL;
+ switch (round) {
+ case 1: p = pum_array[idx].pum_text; break;
+ case 2: p = pum_array[idx].pum_kind; break;
+ case 3: p = pum_array[idx].pum_extra; break;
+ }
+ if (p != NULL)
+ for (;; mb_ptr_adv(p)) {
+ if (s == NULL)
+ s = p;
+ w = ptr2cells(p);
+ if (*p == NUL || *p == TAB || totwidth + w > pum_width) {
+ /* Display the text that fits or comes before a Tab.
+ * First convert it to printable characters. */
+ char_u *st;
+ int saved = *p;
+
+ *p = NUL;
+ st = transstr(s);
+ *p = saved;
+ if (curwin->w_p_rl) {
+ if (st != NULL) {
+ char_u *rt = reverse_text(st);
+
+ if (rt != NULL) {
+ char_u *rt_start = rt;
+ int size;
+
+ size = vim_strsize(rt);
+ if (size > pum_width) {
+ do {
+ size -= has_mbyte
+ ? (*mb_ptr2cells)(rt) : 1;
+ mb_ptr_adv(rt);
+ } while (size > pum_width);
+
+ if (size < pum_width) {
+ /* Most left character requires
+ * 2-cells but only 1 cell is
+ * available on screen. Put a
+ * '<' on the left of the pum
+ * item */
+ *(--rt) = '<';
+ size++;
+ }
+ }
+ screen_puts_len(rt, (int)STRLEN(rt),
+ row, col - size + 1, attr);
+ vim_free(rt_start);
+ }
+ vim_free(st);
+ }
+ col -= width;
+ } else {
+ if (st != NULL) {
+ screen_puts_len(st, (int)STRLEN(st), row, col,
+ attr);
+ vim_free(st);
+ }
+ col += width;
+ }
+
+ if (*p != TAB)
+ break;
+
+ /* Display two spaces for a Tab. */
+ if (curwin->w_p_rl) {
+ screen_puts_len((char_u *)" ", 2, row, col - 1,
+ attr);
+ col -= 2;
+ } else {
+ screen_puts_len((char_u *)" ", 2, row, col, attr);
+ col += 2;
+ }
+ totwidth += 2;
+ s = NULL; /* start text at next char */
+ width = 0;
+ } else
+ width += w;
+ }
+
+ if (round > 1)
+ n = pum_kind_width + 1;
+ else
+ n = 1;
+
+ /* Stop when there is nothing more to display. */
+ if (round == 3
+ || (round == 2 && pum_array[idx].pum_extra == NULL)
+ || (round == 1 && pum_array[idx].pum_kind == NULL
+ && pum_array[idx].pum_extra == NULL)
+ || pum_base_width + n >= pum_width)
+ break;
+ if (curwin->w_p_rl) {
+ screen_fill(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);
+ 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);
+ else
+ screen_fill(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);
+ else
+ screen_putchar(' ', row, pum_col + pum_width,
+ i >= thumb_pos && i < thumb_pos + thumb_heigth
+ ? attr_thumb : attr_scroll);
+ }
+
+ ++row;
+ }
+}
+
+/*
+ * Set the index of the currently selected item. The menu will scroll when
+ * necessary. When "n" is out of range don't scroll.
+ * This may be repeated when the preview window is used:
+ * "repeat" == 0: open preview window normally
+ * "repeat" == 1: open preview window but don't set the size
+ * "repeat" == 2: don't open preview window
+ * Returns TRUE when the window was resized and the location of the popup menu
+ * must be recomputed.
+ */
+static int pum_set_selected(n, repeat)
+int n;
+int repeat;
+{
+ int resized = FALSE;
+ int context = pum_height / 2;
+
+ pum_selected = n;
+
+ if (pum_selected >= 0 && pum_selected < pum_size) {
+ if (pum_first > pum_selected - 4) {
+ /* scroll down; when we did a jump it's probably a PageUp then
+ * scroll a whole page */
+ if (pum_first > pum_selected - 2) {
+ pum_first -= pum_height - 2;
+ if (pum_first < 0)
+ pum_first = 0;
+ else if (pum_first > pum_selected)
+ pum_first = pum_selected;
+ } else
+ pum_first = pum_selected;
+ } else if (pum_first < pum_selected - pum_height + 5) {
+ /* scroll up; when we did a jump it's probably a PageDown then
+ * scroll a whole page */
+ if (pum_first < pum_selected - pum_height + 1 + 2) {
+ pum_first += pum_height - 2;
+ if (pum_first < pum_selected - pum_height + 1)
+ pum_first = pum_selected - pum_height + 1;
+ } else
+ pum_first = pum_selected - pum_height + 1;
+ }
+
+ /* Give a few lines of context when possible. */
+ if (context > 3)
+ context = 3;
+ if (pum_height > 2) {
+ if (pum_first > pum_selected - context) {
+ /* scroll down */
+ pum_first = pum_selected - context;
+ if (pum_first < 0)
+ pum_first = 0;
+ } else if (pum_first < pum_selected + context - pum_height + 1) {
+ /* scroll up */
+ pum_first = pum_selected + context - pum_height + 1;
+ }
+ }
+
+ /*
+ * Show extra info in the preview window if there is something and
+ * 'completeopt' contains "preview".
+ * Skip this when tried twice already.
+ * Skip this also when there is not much room.
+ * NOTE: Be very careful not to sync undo!
+ */
+ if (pum_array[pum_selected].pum_info != NULL
+ && Rows > 10
+ && repeat <= 1
+ && vim_strchr(p_cot, 'p') != NULL) {
+ win_T *curwin_save = curwin;
+ int res = OK;
+
+ /* Open a preview window. 3 lines by default. Prefer
+ * 'previewheight' if set and smaller. */
+ g_do_tagpreview = 3;
+ if (p_pvh > 0 && p_pvh < g_do_tagpreview)
+ g_do_tagpreview = p_pvh;
+ resized = prepare_tagpreview(FALSE);
+ g_do_tagpreview = 0;
+
+ if (curwin->w_p_pvw) {
+ if (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())
+ ml_delete((linenr_T)1, FALSE);
+ } else {
+ /* Don't want to sync undo in the current buffer. */
+ ++no_u_sync;
+ res = do_ecmd(0, NULL, NULL, NULL, ECMD_ONE, 0, NULL);
+ --no_u_sync;
+ 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);
+ }
+ }
+ if (res == OK) {
+ char_u *p, *e;
+ linenr_T lnum = 0;
+
+ for (p = pum_array[pum_selected].pum_info; *p != NUL; ) {
+ e = vim_strchr(p, '\n');
+ if (e == NULL) {
+ ml_append(lnum++, p, 0, FALSE);
+ break;
+ } else {
+ *e = NUL;
+ ml_append(lnum++, p, (int)(e - p + 1), FALSE);
+ *e = '\n';
+ p = e + 1;
+ }
+ }
+
+ /* Increase the height of the preview window to show the
+ * text, but no more than 'previewheight' lines. */
+ if (repeat == 0) {
+ if (lnum > p_pvh)
+ lnum = p_pvh;
+ if (curwin->w_height < lnum) {
+ win_setheight((int)lnum);
+ resized = TRUE;
+ }
+ }
+
+ curbuf->b_changed = 0;
+ curbuf->b_p_ma = FALSE;
+ curwin->w_cursor.lnum = 1;
+ curwin->w_cursor.col = 0;
+
+ if (curwin != curwin_save && win_valid(curwin_save)) {
+ /* Return cursor to where we were */
+ validate_cursor();
+ redraw_later(SOME_VALID);
+
+ /* When the preview window was resized we need to
+ * update the view on the buffer. Only go back to
+ * the window when needed, otherwise it will always be
+ * redraw. */
+ if (resized) {
+ win_enter(curwin_save, TRUE);
+ update_topline();
+ }
+
+ /* Update the screen before drawing the popup menu.
+ * Enable updating the status lines. */
+ pum_do_redraw = TRUE;
+ update_screen(0);
+ pum_do_redraw = FALSE;
+
+ if (!resized && win_valid(curwin_save))
+ win_enter(curwin_save, TRUE);
+
+ /* May need to update the screen again when there are
+ * autocommands involved. */
+ pum_do_redraw = TRUE;
+ update_screen(0);
+ pum_do_redraw = FALSE;
+ }
+ }
+ }
+ }
+ }
+
+ if (!resized)
+ pum_redraw();
+
+ return resized;
+}
+
+/*
+ * Undisplay the popup menu (later).
+ */
+void pum_undisplay() {
+ pum_array = NULL;
+ redraw_all_later(SOME_VALID);
+ redraw_tabline = TRUE;
+ status_redraw_all();
+}
+
+/*
+ * Clear the popup menu. Currently only resets the offset to the first
+ * displayed item.
+ */
+void pum_clear() {
+ pum_first = 0;
+}
+
+/*
+ * Return TRUE if the popup menu is displayed.
+ * Overruled when "pum_do_redraw" is set, used to redraw the status lines.
+ */
+int pum_visible() {
+ return !pum_do_redraw && pum_array != NULL;
+}
+
+/*
+ * Return the height of the popup menu, the number of entries visible.
+ * Only valid when pum_visible() returns TRUE!
+ */
+int pum_get_height() {
+ return pum_height;
+}
+
diff --git a/src/proto.h b/src/proto.h
new file mode 100644
index 0000000000..b040ff70cc
--- /dev/null
+++ b/src/proto.h
@@ -0,0 +1,137 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * 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.
+ */
+
+/*
+ * proto.h: include the (automatically generated) function prototypes
+ */
+
+/*
+ * Don't include these while generating prototypes. Prevents problems when
+ * files are missing.
+ */
+#if !defined(PROTO) && !defined(NOPROTO)
+
+/*
+ * Machine-dependent routines.
+ */
+/* avoid errors in function prototypes */
+# define Display int
+# define Widget int
+# define GdkEvent int
+# define GdkEventKey int
+# define XImage int
+
+# if defined(UNIX) || defined(__EMX__) || defined(VMS)
+# include "os_unix.pro"
+# endif
+
+# include "blowfish.pro"
+# include "buffer.pro"
+# include "charset.pro"
+# include "if_cscope.pro"
+# include "diff.pro"
+# include "digraph.pro"
+# include "edit.pro"
+# include "eval.pro"
+# include "ex_cmds.pro"
+# include "ex_cmds2.pro"
+# include "ex_docmd.pro"
+# include "ex_eval.pro"
+# include "ex_getln.pro"
+# include "fileio.pro"
+# include "fold.pro"
+# include "getchar.pro"
+# include "hangulin.pro"
+# include "hardcopy.pro"
+# include "hashtab.pro"
+# include "main.pro"
+# include "mark.pro"
+# include "memfile.pro"
+# include "memline.pro"
+# include "menu.pro"
+
+# if !defined MESSAGE_FILE || defined(HAVE_STDARG_H)
+/* These prototypes cannot be produced automatically and conflict with
+ * the old-style prototypes in message.c. */
+int
+smsg __ARGS((char_u *, ...));
+
+int
+smsg_attr __ARGS((int, char_u *, ...));
+
+int
+vim_snprintf_add __ARGS((char *, size_t, char *, ...));
+
+int
+vim_snprintf __ARGS((char *, size_t, char *, ...));
+
+# if defined(HAVE_STDARG_H)
+int vim_vsnprintf(char *str, size_t str_m, char *fmt, va_list ap, typval_T *tvs);
+# endif
+# endif
+
+# include "message.pro"
+# include "misc1.pro"
+# include "misc2.pro"
+#ifndef HAVE_STRPBRK /* not generated automatically from misc2.c */
+char_u *vim_strpbrk __ARGS((char_u *s, char_u *charset));
+#endif
+#ifndef HAVE_QSORT
+/* Use our own qsort(), don't define the prototype when not used. */
+void qsort __ARGS((void *base, size_t elm_count, size_t elm_size, int (*cmp)(
+ const void *, const void *)));
+#endif
+# include "move.pro"
+# if defined(FEAT_MBYTE) || defined(FEAT_XIM) || defined(FEAT_KEYMAP) \
+ || defined(FEAT_POSTSCRIPT)
+# include "mbyte.pro"
+# endif
+# include "normal.pro"
+# include "ops.pro"
+# include "option.pro"
+# include "popupmnu.pro"
+# include "quickfix.pro"
+# include "regexp.pro"
+# include "screen.pro"
+# include "sha256.pro"
+# include "search.pro"
+# include "spell.pro"
+# include "syntax.pro"
+# include "tag.pro"
+# include "term.pro"
+# include "ui.pro"
+# include "undo.pro"
+# include "version.pro"
+# include "window.pro"
+
+
+
+
+
+
+
+/* Ugly solution for "BalloonEval" not being defined while it's used in some
+ * .pro files. */
+# define BalloonEval int
+
+
+
+# ifdef FEAT_OLE
+# endif
+
+/*
+ * The perl include files pollute the namespace, therefore proto.h must be
+ * included before the perl include files. But then CV is not defined, which
+ * not included here for the perl files. Use a dummy define for CV for the
+ * other files.
+ */
+
+#ifdef MACOS_CONVERT
+#endif
+
+#endif /* !PROTO && !NOPROTO */
diff --git a/src/proto/blowfish.pro b/src/proto/blowfish.pro
new file mode 100644
index 0000000000..51e4fa9ec5
--- /dev/null
+++ b/src/proto/blowfish.pro
@@ -0,0 +1,10 @@
+/* blowfish.c */
+void bf_key_init __ARGS((char_u *password, char_u *salt, int salt_len));
+void bf_ofb_init __ARGS((char_u *iv, int iv_len));
+void bf_crypt_encode __ARGS((char_u *from, size_t len, char_u *to));
+void bf_crypt_decode __ARGS((char_u *ptr, long len));
+void bf_crypt_init_keys __ARGS((char_u *passwd));
+void bf_crypt_save __ARGS((void));
+void bf_crypt_restore __ARGS((void));
+int blowfish_self_test __ARGS((void));
+/* vim: set ft=c : */
diff --git a/src/proto/buffer.pro b/src/proto/buffer.pro
new file mode 100644
index 0000000000..060008db77
--- /dev/null
+++ b/src/proto/buffer.pro
@@ -0,0 +1,81 @@
+/* buffer.c */
+int open_buffer __ARGS((int read_stdin, exarg_T *eap, int flags));
+int buf_valid __ARGS((buf_T *buf));
+void close_buffer __ARGS((win_T *win, buf_T *buf, int action, int abort_if_last));
+void buf_clear_file __ARGS((buf_T *buf));
+void buf_freeall __ARGS((buf_T *buf, int flags));
+void goto_buffer __ARGS((exarg_T *eap, int start, int dir, int count));
+void handle_swap_exists __ARGS((buf_T *old_curbuf));
+char_u *do_bufdel __ARGS((int command, char_u *arg, int addr_count,
+ int start_bnr, int end_bnr,
+ int forceit));
+int do_buffer __ARGS((int action, int start, int dir, int count, int forceit));
+void set_curbuf __ARGS((buf_T *buf, int action));
+void enter_buffer __ARGS((buf_T *buf));
+void do_autochdir __ARGS((void));
+buf_T *buflist_new __ARGS((char_u *ffname, char_u *sfname, linenr_T lnum,
+ int flags));
+void free_buf_options __ARGS((buf_T *buf, int free_p_ff));
+int buflist_getfile __ARGS((int n, linenr_T lnum, int options, int forceit));
+void buflist_getfpos __ARGS((void));
+buf_T *buflist_findname_exp __ARGS((char_u *fname));
+buf_T *buflist_findname __ARGS((char_u *ffname));
+int buflist_findpat __ARGS((char_u *pattern, char_u *pattern_end, int unlisted,
+ int diffmode,
+ int curtab_only));
+int ExpandBufnames __ARGS((char_u *pat, int *num_file, char_u ***file,
+ int options));
+buf_T *buflist_findnr __ARGS((int nr));
+char_u *buflist_nr2name __ARGS((int n, int fullname, int helptail));
+void get_winopts __ARGS((buf_T *buf));
+pos_T *buflist_findfpos __ARGS((buf_T *buf));
+linenr_T buflist_findlnum __ARGS((buf_T *buf));
+void buflist_list __ARGS((exarg_T *eap));
+int buflist_name_nr __ARGS((int fnum, char_u **fname, linenr_T *lnum));
+int setfname __ARGS((buf_T *buf, char_u *ffname, char_u *sfname, int message));
+void buf_set_name __ARGS((int fnum, char_u *name));
+void buf_name_changed __ARGS((buf_T *buf));
+buf_T *setaltfname __ARGS((char_u *ffname, char_u *sfname, linenr_T lnum));
+char_u *getaltfname __ARGS((int errmsg));
+int buflist_add __ARGS((char_u *fname, int flags));
+void buflist_slash_adjust __ARGS((void));
+void buflist_altfpos __ARGS((win_T *win));
+int otherfile __ARGS((char_u *ffname));
+void buf_setino __ARGS((buf_T *buf));
+void fileinfo __ARGS((int fullname, int shorthelp, int dont_truncate));
+void col_print __ARGS((char_u *buf, size_t buflen, int col, int vcol));
+void maketitle __ARGS((void));
+void resettitle __ARGS((void));
+void free_titles __ARGS((void));
+int build_stl_str_hl __ARGS((win_T *wp, char_u *out, size_t outlen, char_u *fmt,
+ int use_sandbox, int fillchar, int maxwidth,
+ struct stl_hlrec *hltab,
+ struct stl_hlrec *tabtab));
+void get_rel_pos __ARGS((win_T *wp, char_u *buf, int buflen));
+char_u *fix_fname __ARGS((char_u *fname));
+void fname_expand __ARGS((buf_T *buf, char_u **ffname, char_u **sfname));
+char_u *alist_name __ARGS((aentry_T *aep));
+void do_arg_all __ARGS((int count, int forceit, int keep_tabs));
+void ex_buffer_all __ARGS((exarg_T *eap));
+void do_modelines __ARGS((int flags));
+int read_viminfo_bufferlist __ARGS((vir_T *virp, int writing));
+void write_viminfo_bufferlist __ARGS((FILE *fp));
+char_u *buf_spname __ARGS((buf_T *buf));
+int find_win_for_buf __ARGS((buf_T *buf, win_T **wp, tabpage_T **tp));
+void buf_addsign __ARGS((buf_T *buf, int id, linenr_T lnum, int typenr));
+linenr_T buf_change_sign_type __ARGS((buf_T *buf, int markId, int typenr));
+int buf_getsigntype __ARGS((buf_T *buf, linenr_T lnum, int type));
+linenr_T buf_delsign __ARGS((buf_T *buf, int id));
+int buf_findsign __ARGS((buf_T *buf, int id));
+int buf_findsign_id __ARGS((buf_T *buf, linenr_T lnum));
+int buf_findsigntype_id __ARGS((buf_T *buf, linenr_T lnum, int typenr));
+int buf_signcount __ARGS((buf_T *buf, linenr_T lnum));
+void buf_delete_signs __ARGS((buf_T *buf));
+void buf_delete_all_signs __ARGS((void));
+void sign_list_placed __ARGS((buf_T *rbuf));
+void sign_mark_adjust __ARGS((linenr_T line1, linenr_T line2, long amount,
+ long amount_after));
+void set_buflisted __ARGS((int on));
+int buf_contents_changed __ARGS((buf_T *buf));
+void wipe_buffer __ARGS((buf_T *buf, int aucmd));
+/* vim: set ft=c : */
diff --git a/src/proto/charset.pro b/src/proto/charset.pro
new file mode 100644
index 0000000000..d0223f1e9c
--- /dev/null
+++ b/src/proto/charset.pro
@@ -0,0 +1,64 @@
+/* charset.c */
+int init_chartab __ARGS((void));
+int buf_init_chartab __ARGS((buf_T *buf, int global));
+void trans_characters __ARGS((char_u *buf, int bufsize));
+char_u *transstr __ARGS((char_u *s));
+char_u *str_foldcase __ARGS((char_u *str, int orglen, char_u *buf, int buflen));
+char_u *transchar __ARGS((int c));
+char_u *transchar_byte __ARGS((int c));
+void transchar_nonprint __ARGS((char_u *buf, int c));
+void transchar_hex __ARGS((char_u *buf, int c));
+int byte2cells __ARGS((int b));
+int char2cells __ARGS((int c));
+int ptr2cells __ARGS((char_u *p));
+int vim_strsize __ARGS((char_u *s));
+int vim_strnsize __ARGS((char_u *s, int len));
+int chartabsize __ARGS((char_u *p, colnr_T col));
+int linetabsize __ARGS((char_u *s));
+int linetabsize_col __ARGS((int startcol, char_u *s));
+int win_linetabsize __ARGS((win_T *wp, char_u *p, colnr_T len));
+int vim_isIDc __ARGS((int c));
+int vim_iswordc __ARGS((int c));
+int vim_iswordc_buf __ARGS((int c, buf_T *buf));
+int vim_iswordp __ARGS((char_u *p));
+int vim_iswordp_buf __ARGS((char_u *p, buf_T *buf));
+int vim_isfilec __ARGS((int c));
+int vim_isfilec_or_wc __ARGS((int c));
+int vim_isprintc __ARGS((int c));
+int vim_isprintc_strict __ARGS((int c));
+int lbr_chartabsize __ARGS((unsigned char *s, colnr_T col));
+int lbr_chartabsize_adv __ARGS((char_u **s, colnr_T col));
+int win_lbr_chartabsize __ARGS((win_T *wp, char_u *s, colnr_T col, int *headp));
+int in_win_border __ARGS((win_T *wp, colnr_T vcol));
+void getvcol __ARGS((win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor,
+ colnr_T *end));
+colnr_T getvcol_nolist __ARGS((pos_T *posp));
+void getvvcol __ARGS((win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor,
+ colnr_T *end));
+void getvcols __ARGS((win_T *wp, pos_T *pos1, pos_T *pos2, colnr_T *left,
+ colnr_T *right));
+char_u *skipwhite __ARGS((char_u *q));
+char_u *skipdigits __ARGS((char_u *q));
+char_u *skiphex __ARGS((char_u *q));
+char_u *skiptodigit __ARGS((char_u *q));
+char_u *skiptohex __ARGS((char_u *q));
+int vim_isdigit __ARGS((int c));
+int vim_isxdigit __ARGS((int c));
+int vim_islower __ARGS((int c));
+int vim_isupper __ARGS((int c));
+int vim_toupper __ARGS((int c));
+int vim_tolower __ARGS((int c));
+char_u *skiptowhite __ARGS((char_u *p));
+char_u *skiptowhite_esc __ARGS((char_u *p));
+long getdigits __ARGS((char_u **pp));
+int vim_isblankline __ARGS((char_u *lbuf));
+void vim_str2nr __ARGS((char_u *start, int *hexp, int *len, int dooct,
+ int dohex, long *nptr,
+ unsigned long *unptr));
+int hex2nr __ARGS((int c));
+int hexhex2nr __ARGS((char_u *p));
+int rem_backslash __ARGS((char_u *str));
+void backslash_halve __ARGS((char_u *p));
+char_u *backslash_halve_save __ARGS((char_u *p));
+void ebcdic2ascii __ARGS((char_u *buffer, int len));
+/* vim: set ft=c : */
diff --git a/src/proto/diff.pro b/src/proto/diff.pro
new file mode 100644
index 0000000000..0093629033
--- /dev/null
+++ b/src/proto/diff.pro
@@ -0,0 +1,30 @@
+/* diff.c */
+void diff_buf_delete __ARGS((buf_T *buf));
+void diff_buf_adjust __ARGS((win_T *win));
+void diff_buf_add __ARGS((buf_T *buf));
+void diff_invalidate __ARGS((buf_T *buf));
+void diff_mark_adjust __ARGS((linenr_T line1, linenr_T line2, long amount,
+ long amount_after));
+void ex_diffupdate __ARGS((exarg_T *eap));
+void ex_diffpatch __ARGS((exarg_T *eap));
+void ex_diffsplit __ARGS((exarg_T *eap));
+void ex_diffthis __ARGS((exarg_T *eap));
+void diff_win_options __ARGS((win_T *wp, int addbuf));
+void ex_diffoff __ARGS((exarg_T *eap));
+void diff_clear __ARGS((tabpage_T *tp));
+int diff_check __ARGS((win_T *wp, linenr_T lnum));
+int diff_check_fill __ARGS((win_T *wp, linenr_T lnum));
+void diff_set_topline __ARGS((win_T *fromwin, win_T *towin));
+int diffopt_changed __ARGS((void));
+int diffopt_horizontal __ARGS((void));
+int diff_find_change __ARGS((win_T *wp, linenr_T lnum, int *startp, int *endp));
+int diff_infold __ARGS((win_T *wp, linenr_T lnum));
+void nv_diffgetput __ARGS((int put));
+void ex_diffgetput __ARGS((exarg_T *eap));
+int diff_mode_buf __ARGS((buf_T *buf));
+int diff_move_to __ARGS((int dir, long count));
+linenr_T diff_get_corresponding_line __ARGS((buf_T *buf1, linenr_T lnum1,
+ buf_T *buf2,
+ linenr_T lnum3));
+linenr_T diff_lnum_win __ARGS((linenr_T lnum, win_T *wp));
+/* vim: set ft=c : */
diff --git a/src/proto/digraph.pro b/src/proto/digraph.pro
new file mode 100644
index 0000000000..5573b8c36d
--- /dev/null
+++ b/src/proto/digraph.pro
@@ -0,0 +1,9 @@
+/* digraph.c */
+int do_digraph __ARGS((int c));
+int get_digraph __ARGS((int cmdline));
+int getdigraph __ARGS((int char1, int char2, int meta_char));
+void putdigraph __ARGS((char_u *str));
+void listdigraphs __ARGS((void));
+char_u *keymap_init __ARGS((void));
+void ex_loadkeymap __ARGS((exarg_T *eap));
+/* vim: set ft=c : */
diff --git a/src/proto/edit.pro b/src/proto/edit.pro
new file mode 100644
index 0000000000..0284101df4
--- /dev/null
+++ b/src/proto/edit.pro
@@ -0,0 +1,46 @@
+/* edit.c */
+int edit __ARGS((int cmdchar, int startln, long count));
+void edit_putchar __ARGS((int c, int highlight));
+void edit_unputchar __ARGS((void));
+void display_dollar __ARGS((colnr_T col));
+void change_indent __ARGS((int type, int amount, int round, int replaced,
+ int call_changed_bytes));
+void truncate_spaces __ARGS((char_u *line));
+void backspace_until_column __ARGS((int col));
+int vim_is_ctrl_x_key __ARGS((int c));
+int ins_compl_add_infercase __ARGS((char_u *str, int len, int icase, char_u *
+ fname, int dir,
+ int flags));
+void set_completion __ARGS((colnr_T startcol, list_T *list));
+void ins_compl_show_pum __ARGS((void));
+char_u *find_word_start __ARGS((char_u *ptr));
+char_u *find_word_end __ARGS((char_u *ptr));
+int ins_compl_active __ARGS((void));
+int ins_compl_add_tv __ARGS((typval_T *tv, int dir));
+void ins_compl_check_keys __ARGS((int frequency));
+int get_literal __ARGS((void));
+void insertchar __ARGS((int c, int flags, int second_indent));
+void auto_format __ARGS((int trailblank, int prev_line));
+int comp_textwidth __ARGS((int ff));
+int stop_arrow __ARGS((void));
+void set_last_insert __ARGS((int c));
+void free_last_insert __ARGS((void));
+char_u *add_char2buf __ARGS((int c, char_u *s));
+void beginline __ARGS((int flags));
+int oneright __ARGS((void));
+int oneleft __ARGS((void));
+int cursor_up __ARGS((long n, int upd_topline));
+int cursor_down __ARGS((long n, int upd_topline));
+int stuff_inserted __ARGS((int c, long count, int no_esc));
+char_u *get_last_insert __ARGS((void));
+char_u *get_last_insert_save __ARGS((void));
+void replace_push __ARGS((int c));
+int replace_push_mb __ARGS((char_u *p));
+void fixthisline __ARGS((int (*get_the_indent)(void)));
+void fix_indent __ARGS((void));
+int in_cinkeys __ARGS((int keytyped, int when, int line_is_empty));
+int hkmap __ARGS((int c));
+void ins_scroll __ARGS((void));
+void ins_horscroll __ARGS((void));
+int ins_copychar __ARGS((linenr_T lnum));
+/* vim: set ft=c : */
diff --git a/src/proto/eval.pro b/src/proto/eval.pro
new file mode 100644
index 0000000000..c0f707cab2
--- /dev/null
+++ b/src/proto/eval.pro
@@ -0,0 +1,150 @@
+/* eval.c */
+void eval_init __ARGS((void));
+void eval_clear __ARGS((void));
+char_u *func_name __ARGS((void *cookie));
+linenr_T *func_breakpoint __ARGS((void *cookie));
+int *func_dbg_tick __ARGS((void *cookie));
+int func_level __ARGS((void *cookie));
+int current_func_returned __ARGS((void));
+void set_internal_string_var __ARGS((char_u *name, char_u *value));
+int var_redir_start __ARGS((char_u *name, int append));
+void var_redir_str __ARGS((char_u *value, int value_len));
+void var_redir_stop __ARGS((void));
+int eval_charconvert __ARGS((char_u *enc_from, char_u *enc_to, char_u *
+ fname_from,
+ char_u *fname_to));
+int eval_printexpr __ARGS((char_u *fname, char_u *args));
+void eval_diff __ARGS((char_u *origfile, char_u *newfile, char_u *outfile));
+void eval_patch __ARGS((char_u *origfile, char_u *difffile, char_u *outfile));
+int eval_to_bool __ARGS((char_u *arg, int *error, char_u **nextcmd, int skip));
+char_u *eval_to_string_skip __ARGS((char_u *arg, char_u **nextcmd, int skip));
+int skip_expr __ARGS((char_u **pp));
+char_u *eval_to_string __ARGS((char_u *arg, char_u **nextcmd, int convert));
+char_u *eval_to_string_safe __ARGS((char_u *arg, char_u **nextcmd,
+ int use_sandbox));
+int eval_to_number __ARGS((char_u *expr));
+list_T *eval_spell_expr __ARGS((char_u *badword, char_u *expr));
+int get_spellword __ARGS((list_T *list, char_u **pp));
+typval_T *eval_expr __ARGS((char_u *arg, char_u **nextcmd));
+int call_vim_function __ARGS((char_u *func, int argc, char_u **argv, int safe,
+ int str_arg_only,
+ typval_T *rettv));
+long call_func_retnr __ARGS((char_u *func, int argc, char_u **argv, int safe));
+void *call_func_retstr __ARGS((char_u *func, int argc, char_u **argv, int safe));
+void *call_func_retlist __ARGS((char_u *func, int argc, char_u **argv, int safe));
+void *save_funccal __ARGS((void));
+void restore_funccal __ARGS((void *vfc));
+void prof_child_enter __ARGS((proftime_T *tm));
+void prof_child_exit __ARGS((proftime_T *tm));
+int eval_foldexpr __ARGS((char_u *arg, int *cp));
+void ex_let __ARGS((exarg_T *eap));
+void list_add_watch __ARGS((list_T *l, listwatch_T *lw));
+void list_rem_watch __ARGS((list_T *l, listwatch_T *lwrem));
+void *eval_for_line __ARGS((char_u *arg, int *errp, char_u **nextcmdp, int skip));
+int next_for_item __ARGS((void *fi_void, char_u *arg));
+void free_for_info __ARGS((void *fi_void));
+void set_context_for_expression __ARGS((expand_T *xp, char_u *arg,
+ cmdidx_T cmdidx));
+void ex_call __ARGS((exarg_T *eap));
+void ex_unlet __ARGS((exarg_T *eap));
+void ex_lockvar __ARGS((exarg_T *eap));
+int do_unlet __ARGS((char_u *name, int forceit));
+void del_menutrans_vars __ARGS((void));
+char_u *get_user_var_name __ARGS((expand_T *xp, int idx));
+list_T *list_alloc __ARGS((void));
+void list_unref __ARGS((list_T *l));
+void list_free __ARGS((list_T *l, int recurse));
+listitem_T *listitem_alloc __ARGS((void));
+void listitem_free __ARGS((listitem_T *item));
+void listitem_remove __ARGS((list_T *l, listitem_T *item));
+dictitem_T *dict_lookup __ARGS((hashitem_T *hi));
+listitem_T *list_find __ARGS((list_T *l, long n));
+char_u *list_find_str __ARGS((list_T *l, long idx));
+void list_append __ARGS((list_T *l, listitem_T *item));
+int list_append_tv __ARGS((list_T *l, typval_T *tv));
+int list_append_dict __ARGS((list_T *list, dict_T *dict));
+int list_append_string __ARGS((list_T *l, char_u *str, int len));
+int list_insert_tv __ARGS((list_T *l, typval_T *tv, listitem_T *item));
+void list_remove __ARGS((list_T *l, listitem_T *item, listitem_T *item2));
+void list_insert __ARGS((list_T *l, listitem_T *ni, listitem_T *item));
+int garbage_collect __ARGS((void));
+void set_ref_in_ht __ARGS((hashtab_T *ht, int copyID));
+void set_ref_in_list __ARGS((list_T *l, int copyID));
+void set_ref_in_item __ARGS((typval_T *tv, int copyID));
+dict_T *dict_alloc __ARGS((void));
+void dict_unref __ARGS((dict_T *d));
+void dict_free __ARGS((dict_T *d, int recurse));
+dictitem_T *dictitem_alloc __ARGS((char_u *key));
+void dictitem_free __ARGS((dictitem_T *item));
+int dict_add __ARGS((dict_T *d, dictitem_T *item));
+int dict_add_nr_str __ARGS((dict_T *d, char *key, long nr, char_u *str));
+int dict_add_list __ARGS((dict_T *d, char *key, list_T *list));
+dictitem_T *dict_find __ARGS((dict_T *d, char_u *key, int len));
+char_u *get_dict_string __ARGS((dict_T *d, char_u *key, int save));
+long get_dict_number __ARGS((dict_T *d, char_u *key));
+char_u *get_function_name __ARGS((expand_T *xp, int idx));
+char_u *get_expr_name __ARGS((expand_T *xp, int idx));
+int func_call __ARGS((char_u *name, typval_T *args, dict_T *selfdict,
+ typval_T *rettv));
+void dict_extend __ARGS((dict_T *d1, dict_T *d2, char_u *action));
+void mzscheme_call_vim __ARGS((char_u *name, typval_T *args, typval_T *rettv));
+float_T vim_round __ARGS((float_T f));
+long do_searchpair __ARGS((char_u *spat, char_u *mpat, char_u *epat, int dir,
+ char_u *skip, int flags, pos_T *match_pos,
+ linenr_T lnum_stop,
+ long time_limit));
+void set_vim_var_nr __ARGS((int idx, long val));
+long get_vim_var_nr __ARGS((int idx));
+char_u *get_vim_var_str __ARGS((int idx));
+list_T *get_vim_var_list __ARGS((int idx));
+void set_vim_var_char __ARGS((int c));
+void set_vcount __ARGS((long count, long count1, int set_prevcount));
+void set_vim_var_string __ARGS((int idx, char_u *val, int len));
+void set_vim_var_list __ARGS((int idx, list_T *val));
+void set_reg_var __ARGS((int c));
+char_u *v_exception __ARGS((char_u *oldval));
+char_u *v_throwpoint __ARGS((char_u *oldval));
+char_u *set_cmdarg __ARGS((exarg_T *eap, char_u *oldarg));
+void free_tv __ARGS((typval_T *varp));
+void clear_tv __ARGS((typval_T *varp));
+long get_tv_number_chk __ARGS((typval_T *varp, int *denote));
+char_u *get_tv_string_chk __ARGS((typval_T *varp));
+char_u *get_var_value __ARGS((char_u *name));
+void new_script_vars __ARGS((scid_T id));
+void init_var_dict __ARGS((dict_T *dict, dictitem_T *dict_var, int scope));
+void unref_var_dict __ARGS((dict_T *dict));
+void vars_clear __ARGS((hashtab_T *ht));
+void copy_tv __ARGS((typval_T *from, typval_T *to));
+void ex_echo __ARGS((exarg_T *eap));
+void ex_echohl __ARGS((exarg_T *eap));
+void ex_execute __ARGS((exarg_T *eap));
+void ex_function __ARGS((exarg_T *eap));
+void free_all_functions __ARGS((void));
+int translated_function_exists __ARGS((char_u *name));
+char_u *get_expanded_name __ARGS((char_u *name, int check));
+void func_dump_profile __ARGS((FILE *fd));
+char_u *get_user_func_name __ARGS((expand_T *xp, int idx));
+void ex_delfunction __ARGS((exarg_T *eap));
+void func_unref __ARGS((char_u *name));
+void func_ref __ARGS((char_u *name));
+void ex_return __ARGS((exarg_T *eap));
+int do_return __ARGS((exarg_T *eap, int reanimate, int is_cmd, void *rettv));
+void discard_pending_return __ARGS((void *rettv));
+char_u *get_return_cmd __ARGS((void *rettv));
+char_u *get_func_line __ARGS((int c, void *cookie, int indent));
+void func_line_start __ARGS((void *cookie));
+void func_line_exec __ARGS((void *cookie));
+void func_line_end __ARGS((void *cookie));
+int func_has_ended __ARGS((void *cookie));
+int func_has_abort __ARGS((void *cookie));
+int read_viminfo_varlist __ARGS((vir_T *virp, int writing));
+void write_viminfo_varlist __ARGS((FILE *fp));
+int store_session_globals __ARGS((FILE *fd));
+void last_set_msg __ARGS((scid_T scriptID));
+void ex_oldfiles __ARGS((exarg_T *eap));
+int modify_fname __ARGS((char_u *src, int *usedlen, char_u **fnamep, char_u *
+ *bufp,
+ int *fnamelen));
+char_u *do_string_sub __ARGS((char_u *str, char_u *pat, char_u *sub,
+ char_u *flags));
+/* vim: set ft=c : */
diff --git a/src/proto/ex_cmds.pro b/src/proto/ex_cmds.pro
new file mode 100644
index 0000000000..6d566e7f05
--- /dev/null
+++ b/src/proto/ex_cmds.pro
@@ -0,0 +1,72 @@
+/* ex_cmds.c */
+void do_ascii __ARGS((exarg_T *eap));
+void ex_align __ARGS((exarg_T *eap));
+void ex_sort __ARGS((exarg_T *eap));
+void ex_retab __ARGS((exarg_T *eap));
+int do_move __ARGS((linenr_T line1, linenr_T line2, linenr_T dest));
+void ex_copy __ARGS((linenr_T line1, linenr_T line2, linenr_T n));
+void free_prev_shellcmd __ARGS((void));
+void do_bang __ARGS((int addr_count, exarg_T *eap, int forceit, int do_in,
+ int do_out));
+void do_shell __ARGS((char_u *cmd, int flags));
+char_u *make_filter_cmd __ARGS((char_u *cmd, char_u *itmp, char_u *otmp));
+void append_redir __ARGS((char_u *buf, int buflen, char_u *opt, char_u *fname));
+int viminfo_error __ARGS((char *errnum, char *message, char_u *line));
+int read_viminfo __ARGS((char_u *file, int flags));
+void write_viminfo __ARGS((char_u *file, int forceit));
+int viminfo_readline __ARGS((vir_T *virp));
+char_u *viminfo_readstring __ARGS((vir_T *virp, int off, int convert));
+void viminfo_writestring __ARGS((FILE *fd, char_u *p));
+void do_fixdel __ARGS((exarg_T *eap));
+void print_line_no_prefix __ARGS((linenr_T lnum, int use_number, int list));
+void print_line __ARGS((linenr_T lnum, int use_number, int list));
+int rename_buffer __ARGS((char_u *new_fname));
+void ex_file __ARGS((exarg_T *eap));
+void ex_update __ARGS((exarg_T *eap));
+void ex_write __ARGS((exarg_T *eap));
+int do_write __ARGS((exarg_T *eap));
+int check_overwrite __ARGS((exarg_T *eap, buf_T *buf, char_u *fname, char_u *
+ ffname,
+ int other));
+void ex_wnext __ARGS((exarg_T *eap));
+void do_wqall __ARGS((exarg_T *eap));
+int not_writing __ARGS((void));
+int getfile __ARGS((int fnum, char_u *ffname, char_u *sfname, int setpm,
+ linenr_T lnum,
+ int forceit));
+int do_ecmd __ARGS((int fnum, char_u *ffname, char_u *sfname, exarg_T *eap,
+ linenr_T newlnum, int flags,
+ win_T *oldwin));
+void ex_append __ARGS((exarg_T *eap));
+void ex_change __ARGS((exarg_T *eap));
+void ex_z __ARGS((exarg_T *eap));
+int check_restricted __ARGS((void));
+int check_secure __ARGS((void));
+void do_sub __ARGS((exarg_T *eap));
+int do_sub_msg __ARGS((int count_only));
+void ex_global __ARGS((exarg_T *eap));
+void global_exe __ARGS((char_u *cmd));
+int read_viminfo_sub_string __ARGS((vir_T *virp, int force));
+void write_viminfo_sub_string __ARGS((FILE *fp));
+void free_old_sub __ARGS((void));
+int prepare_tagpreview __ARGS((int undo_sync));
+void ex_help __ARGS((exarg_T *eap));
+char_u *check_help_lang __ARGS((char_u *arg));
+int help_heuristic __ARGS((char_u *matched_string, int offset, int wrong_case));
+int find_help_tags __ARGS((char_u *arg, int *num_matches, char_u ***matches,
+ int keep_lang));
+void fix_help_buffer __ARGS((void));
+void ex_exusage __ARGS((exarg_T *eap));
+void ex_viusage __ARGS((exarg_T *eap));
+void ex_helptags __ARGS((exarg_T *eap));
+void ex_sign __ARGS((exarg_T *eap));
+void sign_gui_started __ARGS((void));
+int sign_get_attr __ARGS((int typenr, int line));
+char_u *sign_get_text __ARGS((int typenr));
+void *sign_get_image __ARGS((int typenr));
+char_u *sign_typenr2name __ARGS((int typenr));
+void free_signs __ARGS((void));
+char_u *get_sign_name __ARGS((expand_T *xp, int idx));
+void set_context_in_sign_cmd __ARGS((expand_T *xp, char_u *arg));
+void ex_drop __ARGS((exarg_T *eap));
+/* vim: set ft=c : */
diff --git a/src/proto/ex_cmds2.pro b/src/proto/ex_cmds2.pro
new file mode 100644
index 0000000000..51efb73455
--- /dev/null
+++ b/src/proto/ex_cmds2.pro
@@ -0,0 +1,93 @@
+/* ex_cmds2.c */
+void do_debug __ARGS((char_u *cmd));
+void ex_debug __ARGS((exarg_T *eap));
+void dbg_check_breakpoint __ARGS((exarg_T *eap));
+int dbg_check_skipped __ARGS((exarg_T *eap));
+void ex_breakadd __ARGS((exarg_T *eap));
+void ex_debuggreedy __ARGS((exarg_T *eap));
+void ex_breakdel __ARGS((exarg_T *eap));
+void ex_breaklist __ARGS((exarg_T *eap));
+linenr_T dbg_find_breakpoint __ARGS((int file, char_u *fname, linenr_T after));
+int has_profiling __ARGS((int file, char_u *fname, int *fp));
+void dbg_breakpoint __ARGS((char_u *name, linenr_T lnum));
+void profile_start __ARGS((proftime_T *tm));
+void profile_end __ARGS((proftime_T *tm));
+void profile_sub __ARGS((proftime_T *tm, proftime_T *tm2));
+char *profile_msg __ARGS((proftime_T *tm));
+void profile_setlimit __ARGS((long msec, proftime_T *tm));
+int profile_passed_limit __ARGS((proftime_T *tm));
+void profile_zero __ARGS((proftime_T *tm));
+void profile_divide __ARGS((proftime_T *tm, int count, proftime_T *tm2));
+void profile_add __ARGS((proftime_T *tm, proftime_T *tm2));
+void profile_self __ARGS((proftime_T *self, proftime_T *total,
+ proftime_T *children));
+void profile_get_wait __ARGS((proftime_T *tm));
+void profile_sub_wait __ARGS((proftime_T *tm, proftime_T *tma));
+int profile_equal __ARGS((proftime_T *tm1, proftime_T *tm2));
+int profile_cmp __ARGS((const proftime_T *tm1, const proftime_T *tm2));
+void ex_profile __ARGS((exarg_T *eap));
+char_u *get_profile_name __ARGS((expand_T *xp, int idx));
+void set_context_in_profile_cmd __ARGS((expand_T *xp, char_u *arg));
+void profile_dump __ARGS((void));
+void script_prof_save __ARGS((proftime_T *tm));
+void script_prof_restore __ARGS((proftime_T *tm));
+void prof_inchar_enter __ARGS((void));
+void prof_inchar_exit __ARGS((void));
+int prof_def_func __ARGS((void));
+int autowrite __ARGS((buf_T *buf, int forceit));
+void autowrite_all __ARGS((void));
+int check_changed __ARGS((buf_T *buf, int flags));
+void browse_save_fname __ARGS((buf_T *buf));
+void dialog_changed __ARGS((buf_T *buf, int checkall));
+int can_abandon __ARGS((buf_T *buf, int forceit));
+int check_changed_any __ARGS((int hidden));
+int check_fname __ARGS((void));
+int buf_write_all __ARGS((buf_T *buf, int forceit));
+int get_arglist __ARGS((garray_T *gap, char_u *str));
+int get_arglist_exp __ARGS((char_u *str, int *fcountp, char_u ***fnamesp,
+ int wig));
+void set_arglist __ARGS((char_u *str));
+void check_arg_idx __ARGS((win_T *win));
+void ex_args __ARGS((exarg_T *eap));
+void ex_previous __ARGS((exarg_T *eap));
+void ex_rewind __ARGS((exarg_T *eap));
+void ex_last __ARGS((exarg_T *eap));
+void ex_argument __ARGS((exarg_T *eap));
+void do_argfile __ARGS((exarg_T *eap, int argn));
+void ex_next __ARGS((exarg_T *eap));
+void ex_argedit __ARGS((exarg_T *eap));
+void ex_argadd __ARGS((exarg_T *eap));
+void ex_argdelete __ARGS((exarg_T *eap));
+void ex_listdo __ARGS((exarg_T *eap));
+void ex_compiler __ARGS((exarg_T *eap));
+void ex_runtime __ARGS((exarg_T *eap));
+int source_runtime __ARGS((char_u *name, int all));
+int do_in_runtimepath __ARGS((char_u *name, int all, void (*callback)(
+ char_u *fname, void *ck), void *cookie));
+void ex_options __ARGS((exarg_T *eap));
+void ex_source __ARGS((exarg_T *eap));
+linenr_T *source_breakpoint __ARGS((void *cookie));
+int *source_dbg_tick __ARGS((void *cookie));
+int source_level __ARGS((void *cookie));
+int do_source __ARGS((char_u *fname, int check_other, int is_vimrc));
+void ex_scriptnames __ARGS((exarg_T *eap));
+void scriptnames_slash_adjust __ARGS((void));
+char_u *get_scriptname __ARGS((scid_T id));
+void free_scriptnames __ARGS((void));
+char *fgets_cr __ARGS((char *s, int n, FILE *stream));
+char_u *getsourceline __ARGS((int c, void *cookie, int indent));
+void script_line_start __ARGS((void));
+void script_line_exec __ARGS((void));
+void script_line_end __ARGS((void));
+void ex_scriptencoding __ARGS((exarg_T *eap));
+void ex_finish __ARGS((exarg_T *eap));
+void do_finish __ARGS((exarg_T *eap, int reanimate));
+int source_finished __ARGS((char_u *(*fgetline)(int, void *, int), void *cookie));
+void ex_checktime __ARGS((exarg_T *eap));
+char_u *get_mess_lang __ARGS((void));
+void set_lang_var __ARGS((void));
+void ex_language __ARGS((exarg_T *eap));
+void free_locales __ARGS((void));
+char_u *get_lang_arg __ARGS((expand_T *xp, int idx));
+char_u *get_locales __ARGS((expand_T *xp, int idx));
+/* vim: set ft=c : */
diff --git a/src/proto/ex_docmd.pro b/src/proto/ex_docmd.pro
new file mode 100644
index 0000000000..ff83cad83f
--- /dev/null
+++ b/src/proto/ex_docmd.pro
@@ -0,0 +1,69 @@
+/* ex_docmd.c */
+void do_exmode __ARGS((int improved));
+int do_cmdline_cmd __ARGS((char_u *cmd));
+int do_cmdline __ARGS((char_u *cmdline, char_u *
+ (*fgetline)(int, void *, int), void *cookie,
+ int flags));
+int getline_equal __ARGS((char_u *
+ (*fgetline)(int, void *,
+ int), void *cookie, char_u *
+ (*func)(int, void *,
+ int)));
+void *getline_cookie __ARGS((char_u *(*fgetline)(int, void *, int),
+ void *cookie));
+int checkforcmd __ARGS((char_u **pp, char *cmd, int len));
+int modifier_len __ARGS((char_u *cmd));
+int cmd_exists __ARGS((char_u *name));
+char_u *set_one_cmd_context __ARGS((expand_T *xp, char_u *buff));
+char_u *skip_range __ARGS((char_u *cmd, int *ctx));
+void ex_ni __ARGS((exarg_T *eap));
+int expand_filename __ARGS((exarg_T *eap, char_u **cmdlinep, char_u **errormsgp));
+void separate_nextcmd __ARGS((exarg_T *eap));
+int ends_excmd __ARGS((int c));
+char_u *find_nextcmd __ARGS((char_u *p));
+char_u *check_nextcmd __ARGS((char_u *p));
+char_u *get_command_name __ARGS((expand_T *xp, int idx));
+void ex_comclear __ARGS((exarg_T *eap));
+void uc_clear __ARGS((garray_T *gap));
+char_u *get_user_commands __ARGS((expand_T *xp, int idx));
+char_u *get_user_cmd_flags __ARGS((expand_T *xp, int idx));
+char_u *get_user_cmd_nargs __ARGS((expand_T *xp, int idx));
+char_u *get_user_cmd_complete __ARGS((expand_T *xp, int idx));
+int parse_compl_arg __ARGS((char_u *value, int vallen, int *complp, long *argt,
+ char_u **compl_arg));
+void not_exiting __ARGS((void));
+void tabpage_close __ARGS((int forceit));
+void tabpage_close_other __ARGS((tabpage_T *tp, int forceit));
+void ex_all __ARGS((exarg_T *eap));
+void handle_drop __ARGS((int filec, char_u **filev, int split));
+void alist_clear __ARGS((alist_T *al));
+void alist_init __ARGS((alist_T *al));
+void alist_unlink __ARGS((alist_T *al));
+void alist_new __ARGS((void));
+void alist_expand __ARGS((int *fnum_list, int fnum_len));
+void alist_set __ARGS((alist_T *al, int count, char_u **files, int use_curbuf,
+ int *fnum_list,
+ int fnum_len));
+void alist_add __ARGS((alist_T *al, char_u *fname, int set_fnum));
+void alist_slash_adjust __ARGS((void));
+void ex_splitview __ARGS((exarg_T *eap));
+void tabpage_new __ARGS((void));
+void do_exedit __ARGS((exarg_T *eap, win_T *old_curwin));
+void free_cd_dir __ARGS((void));
+void post_chdir __ARGS((int local));
+void ex_cd __ARGS((exarg_T *eap));
+void do_sleep __ARGS((long msec));
+int vim_mkdir_emsg __ARGS((char_u *name, int prot));
+FILE *open_exfile __ARGS((char_u *fname, int forceit, char *mode));
+void update_topline_cursor __ARGS((void));
+void exec_normal_cmd __ARGS((char_u *cmd, int remap, int silent));
+int find_cmdline_var __ARGS((char_u *src, int *usedlen));
+char_u *eval_vars __ARGS((char_u *src, char_u *srcstart, int *usedlen,
+ linenr_T *lnump, char_u **errormsg,
+ int *escaped));
+char_u *expand_sfile __ARGS((char_u *arg));
+int put_eol __ARGS((FILE *fd));
+int put_line __ARGS((FILE *fd, char *s));
+void dialog_msg __ARGS((char_u *buff, char *format, char_u *fname));
+char_u *get_behave_arg __ARGS((expand_T *xp, int idx));
+/* vim: set ft=c : */
diff --git a/src/proto/ex_eval.pro b/src/proto/ex_eval.pro
new file mode 100644
index 0000000000..7fc87410e0
--- /dev/null
+++ b/src/proto/ex_eval.pro
@@ -0,0 +1,38 @@
+/* ex_eval.c */
+int aborting __ARGS((void));
+void update_force_abort __ARGS((void));
+int should_abort __ARGS((int retcode));
+int aborted_in_try __ARGS((void));
+int cause_errthrow __ARGS((char_u *mesg, int severe, int *ignore));
+void free_global_msglist __ARGS((void));
+void do_errthrow __ARGS((struct condstack *cstack, char_u *cmdname));
+int do_intthrow __ARGS((struct condstack *cstack));
+char_u *get_exception_string __ARGS((void *value, int type, char_u *cmdname,
+ int *should_free));
+void discard_current_exception __ARGS((void));
+void report_make_pending __ARGS((int pending, void *value));
+void report_resume_pending __ARGS((int pending, void *value));
+void report_discard_pending __ARGS((int pending, void *value));
+void ex_if __ARGS((exarg_T *eap));
+void ex_endif __ARGS((exarg_T *eap));
+void ex_else __ARGS((exarg_T *eap));
+void ex_while __ARGS((exarg_T *eap));
+void ex_continue __ARGS((exarg_T *eap));
+void ex_break __ARGS((exarg_T *eap));
+void ex_endwhile __ARGS((exarg_T *eap));
+void ex_throw __ARGS((exarg_T *eap));
+void do_throw __ARGS((struct condstack *cstack));
+void ex_try __ARGS((exarg_T *eap));
+void ex_catch __ARGS((exarg_T *eap));
+void ex_finally __ARGS((exarg_T *eap));
+void ex_endtry __ARGS((exarg_T *eap));
+void enter_cleanup __ARGS((cleanup_T *csp));
+void leave_cleanup __ARGS((cleanup_T *csp));
+int cleanup_conditionals __ARGS((struct condstack *cstack, int searched_cond,
+ int inclusive));
+void rewind_conditionals __ARGS((struct condstack *cstack, int idx,
+ int cond_type,
+ int *cond_level));
+void ex_endfunction __ARGS((exarg_T *eap));
+int has_loop_cmd __ARGS((char_u *p));
+/* vim: set ft=c : */
diff --git a/src/proto/ex_getln.pro b/src/proto/ex_getln.pro
new file mode 100644
index 0000000000..e3a642283f
--- /dev/null
+++ b/src/proto/ex_getln.pro
@@ -0,0 +1,66 @@
+/* ex_getln.c */
+char_u *getcmdline __ARGS((int firstc, long count, int indent));
+char_u *getcmdline_prompt __ARGS((int firstc, char_u *prompt, int attr,
+ int xp_context,
+ char_u *xp_arg));
+int text_locked __ARGS((void));
+void text_locked_msg __ARGS((void));
+int curbuf_locked __ARGS((void));
+int allbuf_locked __ARGS((void));
+char_u *getexline __ARGS((int c, void *cookie, int indent));
+char_u *getexmodeline __ARGS((int promptc, void *cookie, int indent));
+int cmdline_overstrike __ARGS((void));
+int cmdline_at_end __ARGS((void));
+colnr_T cmdline_getvcol_cursor __ARGS((void));
+void free_cmdline_buf __ARGS((void));
+void putcmdline __ARGS((int c, int shift));
+void unputcmdline __ARGS((void));
+int put_on_cmdline __ARGS((char_u *str, int len, int redraw));
+char_u *save_cmdline_alloc __ARGS((void));
+void restore_cmdline_alloc __ARGS((char_u *p));
+void cmdline_paste_str __ARGS((char_u *s, int literally));
+void redrawcmdline __ARGS((void));
+void redrawcmd __ARGS((void));
+void compute_cmdrow __ARGS((void));
+void gotocmdline __ARGS((int clr));
+char_u *ExpandOne __ARGS((expand_T *xp, char_u *str, char_u *orig, int options,
+ int mode));
+void ExpandInit __ARGS((expand_T *xp));
+void ExpandCleanup __ARGS((expand_T *xp));
+void ExpandEscape __ARGS((expand_T *xp, char_u *str, int numfiles, char_u *
+ *files,
+ int options));
+char_u *vim_strsave_fnameescape __ARGS((char_u *fname, int shell));
+void tilde_replace __ARGS((char_u *orig_pat, int num_files, char_u **files));
+char_u *sm_gettail __ARGS((char_u *s));
+char_u *addstar __ARGS((char_u *fname, int len, int context));
+void set_cmd_context __ARGS((expand_T *xp, char_u *str, int len, int col));
+int expand_cmdline __ARGS((expand_T *xp, char_u *str, int col, int *matchcount,
+ char_u ***matches));
+int ExpandGeneric __ARGS((expand_T *xp, regmatch_T *regmatch, int *num_file,
+ char_u ***file, char_u *((*func)(expand_T *, int)),
+ int escaped));
+char_u *globpath __ARGS((char_u *path, char_u *file, int expand_options));
+void init_history __ARGS((void));
+int get_histtype __ARGS((char_u *name));
+void add_to_history __ARGS((int histype, char_u *new_entry, int in_map, int sep));
+int get_history_idx __ARGS((int histype));
+char_u *get_cmdline_str __ARGS((void));
+int get_cmdline_pos __ARGS((void));
+int set_cmdline_pos __ARGS((int pos));
+int get_cmdline_type __ARGS((void));
+char_u *get_history_entry __ARGS((int histype, int idx));
+int clr_history __ARGS((int histype));
+int del_history_entry __ARGS((int histype, char_u *str));
+int del_history_idx __ARGS((int histype, int idx));
+void remove_key_from_history __ARGS((void));
+int get_list_range __ARGS((char_u **str, int *num1, int *num2));
+void ex_history __ARGS((exarg_T *eap));
+void prepare_viminfo_history __ARGS((int asklen, int writing));
+int read_viminfo_history __ARGS((vir_T *virp, int writing));
+void finish_viminfo_history __ARGS((void));
+void write_viminfo_history __ARGS((FILE *fp, int merge));
+void cmd_pchar __ARGS((int c, int offset));
+int cmd_gchar __ARGS((int offset));
+char_u *script_get __ARGS((exarg_T *eap, char_u *cmd));
+/* vim: set ft=c : */
diff --git a/src/proto/fileio.pro b/src/proto/fileio.pro
new file mode 100644
index 0000000000..ec83342e4d
--- /dev/null
+++ b/src/proto/fileio.pro
@@ -0,0 +1,82 @@
+/* fileio.c */
+void filemess __ARGS((buf_T *buf, char_u *name, char_u *s, int attr));
+int readfile __ARGS((char_u *fname, char_u *sfname, linenr_T from,
+ linenr_T lines_to_skip, linenr_T lines_to_read, exarg_T *
+ eap,
+ int flags));
+int prep_exarg __ARGS((exarg_T *eap, buf_T *buf));
+void set_file_options __ARGS((int set_options, exarg_T *eap));
+void set_forced_fenc __ARGS((exarg_T *eap));
+int prepare_crypt_read __ARGS((FILE *fp));
+char_u *prepare_crypt_write __ARGS((buf_T *buf, int *lenp));
+int check_file_readonly __ARGS((char_u *fname, int perm));
+int buf_write __ARGS((buf_T *buf, char_u *fname, char_u *sfname, linenr_T start,
+ linenr_T end, exarg_T *eap, int append, int forceit,
+ int reset_changed,
+ int filtering));
+void msg_add_fname __ARGS((buf_T *buf, char_u *fname));
+void msg_add_lines __ARGS((int insert_space, long lnum, off_t nchars));
+char_u *shorten_fname1 __ARGS((char_u *full_path));
+char_u *shorten_fname __ARGS((char_u *full_path, char_u *dir_name));
+void shorten_fnames __ARGS((int force));
+void shorten_filenames __ARGS((char_u **fnames, int count));
+char_u *modname __ARGS((char_u *fname, char_u *ext, int prepend_dot));
+char_u *buf_modname __ARGS((int shortname, char_u *fname, char_u *ext,
+ int prepend_dot));
+int vim_fgets __ARGS((char_u *buf, int size, FILE *fp));
+int tag_fgets __ARGS((char_u *buf, int size, FILE *fp));
+int vim_rename __ARGS((char_u *from, char_u *to));
+int check_timestamps __ARGS((int focus));
+int buf_check_timestamp __ARGS((buf_T *buf, int focus));
+void buf_reload __ARGS((buf_T *buf, int orig_mode));
+void buf_store_time __ARGS((buf_T *buf, struct stat *st, char_u *fname));
+void write_lnum_adjust __ARGS((linenr_T offset));
+void vim_deltempdir __ARGS((void));
+char_u *vim_tempname __ARGS((int extra_char));
+void forward_slash __ARGS((char_u *fname));
+void aubuflocal_remove __ARGS((buf_T *buf));
+int au_has_group __ARGS((char_u *name));
+void do_augroup __ARGS((char_u *arg, int del_group));
+void free_all_autocmds __ARGS((void));
+int check_ei __ARGS((void));
+char_u *au_event_disable __ARGS((char *what));
+void au_event_restore __ARGS((char_u *old_ei));
+void do_autocmd __ARGS((char_u *arg, int forceit));
+int do_doautocmd __ARGS((char_u *arg, int do_msg));
+void ex_doautoall __ARGS((exarg_T *eap));
+int check_nomodeline __ARGS((char_u **argp));
+void aucmd_prepbuf __ARGS((aco_save_T *aco, buf_T *buf));
+void aucmd_restbuf __ARGS((aco_save_T *aco));
+int apply_autocmds __ARGS((event_T event, char_u *fname, char_u *fname_io,
+ int force,
+ buf_T *buf));
+int apply_autocmds_retval __ARGS((event_T event, char_u *fname, char_u *
+ fname_io, int force, buf_T *buf,
+ int *retval));
+int has_cursorhold __ARGS((void));
+int trigger_cursorhold __ARGS((void));
+int has_cursormoved __ARGS((void));
+int has_cursormovedI __ARGS((void));
+int has_textchanged __ARGS((void));
+int has_textchangedI __ARGS((void));
+int has_insertcharpre __ARGS((void));
+void block_autocmds __ARGS((void));
+void unblock_autocmds __ARGS((void));
+int is_autocmd_blocked __ARGS((void));
+char_u *getnextac __ARGS((int c, void *cookie, int indent));
+int has_autocmd __ARGS((event_T event, char_u *sfname, buf_T *buf));
+char_u *get_augroup_name __ARGS((expand_T *xp, int idx));
+char_u *set_context_in_autocmd __ARGS((expand_T *xp, char_u *arg, int doautocmd));
+char_u *get_event_name __ARGS((expand_T *xp, int idx));
+int autocmd_supported __ARGS((char_u *name));
+int au_exists __ARGS((char_u *arg));
+int match_file_pat __ARGS((char_u *pattern, regprog_T *prog, char_u *fname,
+ char_u *sfname, char_u *tail,
+ int allow_dirs));
+int match_file_list __ARGS((char_u *list, char_u *sfname, char_u *ffname));
+char_u *file_pat_to_reg_pat __ARGS((char_u *pat, char_u *pat_end,
+ char *allow_dirs,
+ int no_bslash));
+long read_eintr __ARGS((int fd, void *buf, size_t bufsize));
+long write_eintr __ARGS((int fd, void *buf, size_t bufsize));
+/* vim: set ft=c : */
diff --git a/src/proto/fold.pro b/src/proto/fold.pro
new file mode 100644
index 0000000000..6f498872e7
--- /dev/null
+++ b/src/proto/fold.pro
@@ -0,0 +1,50 @@
+/* fold.c */
+void copyFoldingState __ARGS((win_T *wp_from, win_T *wp_to));
+int hasAnyFolding __ARGS((win_T *win));
+int hasFolding __ARGS((linenr_T lnum, linenr_T *firstp, linenr_T *lastp));
+int hasFoldingWin __ARGS((win_T *win, linenr_T lnum, linenr_T *firstp,
+ linenr_T *lastp, int cache,
+ foldinfo_T *infop));
+int foldLevel __ARGS((linenr_T lnum));
+int lineFolded __ARGS((win_T *win, linenr_T lnum));
+long foldedCount __ARGS((win_T *win, linenr_T lnum, foldinfo_T *infop));
+int foldmethodIsManual __ARGS((win_T *wp));
+int foldmethodIsIndent __ARGS((win_T *wp));
+int foldmethodIsExpr __ARGS((win_T *wp));
+int foldmethodIsMarker __ARGS((win_T *wp));
+int foldmethodIsSyntax __ARGS((win_T *wp));
+int foldmethodIsDiff __ARGS((win_T *wp));
+void closeFold __ARGS((linenr_T lnum, long count));
+void closeFoldRecurse __ARGS((linenr_T lnum));
+void opFoldRange __ARGS((linenr_T first, linenr_T last, int opening,
+ int recurse,
+ int had_visual));
+void openFold __ARGS((linenr_T lnum, long count));
+void openFoldRecurse __ARGS((linenr_T lnum));
+void foldOpenCursor __ARGS((void));
+void newFoldLevel __ARGS((void));
+void foldCheckClose __ARGS((void));
+int foldManualAllowed __ARGS((int create));
+void foldCreate __ARGS((linenr_T start, linenr_T end));
+void deleteFold __ARGS((linenr_T start, linenr_T end, int recursive,
+ int had_visual));
+void clearFolding __ARGS((win_T *win));
+void foldUpdate __ARGS((win_T *wp, linenr_T top, linenr_T bot));
+void foldUpdateAll __ARGS((win_T *win));
+int foldMoveTo __ARGS((int updown, int dir, long count));
+void foldInitWin __ARGS((win_T *new_win));
+int find_wl_entry __ARGS((win_T *win, linenr_T lnum));
+void foldAdjustVisual __ARGS((void));
+void foldAdjustCursor __ARGS((void));
+void cloneFoldGrowArray __ARGS((garray_T *from, garray_T *to));
+void deleteFoldRecurse __ARGS((garray_T *gap));
+void foldMarkAdjust __ARGS((win_T *wp, linenr_T line1, linenr_T line2,
+ long amount,
+ long amount_after));
+int getDeepestNesting __ARGS((void));
+char_u *get_foldtext __ARGS((win_T *wp, linenr_T lnum, linenr_T lnume,
+ foldinfo_T *foldinfo,
+ char_u *buf));
+void foldtext_cleanup __ARGS((char_u *str));
+int put_folds __ARGS((FILE *fd, win_T *wp));
+/* vim: set ft=c : */
diff --git a/src/proto/getchar.pro b/src/proto/getchar.pro
new file mode 100644
index 0000000000..df3c9836cd
--- /dev/null
+++ b/src/proto/getchar.pro
@@ -0,0 +1,74 @@
+/* getchar.c */
+void free_buff __ARGS((struct buffheader *buf));
+char_u *get_recorded __ARGS((void));
+char_u *get_inserted __ARGS((void));
+int stuff_empty __ARGS((void));
+void typeahead_noflush __ARGS((int c));
+void flush_buffers __ARGS((int flush_typeahead));
+void ResetRedobuff __ARGS((void));
+void CancelRedo __ARGS((void));
+void saveRedobuff __ARGS((void));
+void restoreRedobuff __ARGS((void));
+void AppendToRedobuff __ARGS((char_u *s));
+void AppendToRedobuffLit __ARGS((char_u *str, int len));
+void AppendCharToRedobuff __ARGS((int c));
+void AppendNumberToRedobuff __ARGS((long n));
+void stuffReadbuff __ARGS((char_u *s));
+void stuffReadbuffLen __ARGS((char_u *s, long len));
+void stuffReadbuffSpec __ARGS((char_u *s));
+void stuffcharReadbuff __ARGS((int c));
+void stuffnumReadbuff __ARGS((long n));
+int start_redo __ARGS((long count, int old_redo));
+int start_redo_ins __ARGS((void));
+void stop_redo_ins __ARGS((void));
+int ins_typebuf __ARGS((char_u *str, int noremap, int offset, int nottyped,
+ int silent));
+void ins_char_typebuf __ARGS((int c));
+int typebuf_changed __ARGS((int tb_change_cnt));
+int typebuf_typed __ARGS((void));
+int typebuf_maplen __ARGS((void));
+void del_typebuf __ARGS((int len, int offset));
+int alloc_typebuf __ARGS((void));
+void free_typebuf __ARGS((void));
+int save_typebuf __ARGS((void));
+void save_typeahead __ARGS((tasave_T *tp));
+void restore_typeahead __ARGS((tasave_T *tp));
+void openscript __ARGS((char_u *name, int directly));
+void close_all_scripts __ARGS((void));
+int using_script __ARGS((void));
+void before_blocking __ARGS((void));
+void updatescript __ARGS((int c));
+int vgetc __ARGS((void));
+int safe_vgetc __ARGS((void));
+int plain_vgetc __ARGS((void));
+int vpeekc __ARGS((void));
+int vpeekc_nomap __ARGS((void));
+int vpeekc_any __ARGS((void));
+int char_avail __ARGS((void));
+void vungetc __ARGS((int c));
+int inchar __ARGS((char_u *buf, int maxlen, long wait_time, int tb_change_cnt));
+int fix_input_buffer __ARGS((char_u *buf, int len, int script));
+int input_available __ARGS((void));
+int do_map __ARGS((int maptype, char_u *arg, int mode, int abbrev));
+int get_map_mode __ARGS((char_u **cmdp, int forceit));
+void map_clear __ARGS((char_u *cmdp, char_u *arg, int forceit, int abbr));
+void map_clear_int __ARGS((buf_T *buf, int mode, int local, int abbr));
+char_u *map_mode_to_chars __ARGS((int mode));
+int map_to_exists __ARGS((char_u *str, char_u *modechars, int abbr));
+int map_to_exists_mode __ARGS((char_u *rhs, int mode, int abbr));
+char_u *set_context_in_map_cmd __ARGS((expand_T *xp, char_u *cmd, char_u *arg,
+ int forceit, int isabbrev, int isunmap,
+ cmdidx_T cmdidx));
+int ExpandMappings __ARGS((regmatch_T *regmatch, int *num_file, char_u ***file));
+int check_abbr __ARGS((int c, char_u *ptr, int col, int mincol));
+char_u *vim_strsave_escape_csi __ARGS((char_u *p));
+void vim_unescape_csi __ARGS((char_u *p));
+int makemap __ARGS((FILE *fd, buf_T *buf));
+int put_escstr __ARGS((FILE *fd, char_u *strstart, int what));
+void check_map_keycodes __ARGS((void));
+char_u *check_map __ARGS((char_u *keys, int mode, int exact, int ign_mod,
+ int abbr, mapblock_T **mp_ptr,
+ int *local_ptr));
+void init_mappings __ARGS((void));
+void add_map __ARGS((char_u *map, int mode));
+/* vim: set ft=c : */
diff --git a/src/proto/hangulin.pro b/src/proto/hangulin.pro
new file mode 100644
index 0000000000..adfde142ff
--- /dev/null
+++ b/src/proto/hangulin.pro
@@ -0,0 +1,9 @@
+/* hangulin.c */
+int hangul_input_state_get __ARGS((void));
+void hangul_input_state_set __ARGS((int state));
+int im_get_status __ARGS((void));
+void hangul_input_state_toggle __ARGS((void));
+void hangul_keyboard_set __ARGS((void));
+int hangul_input_process __ARGS((char_u *s, int len));
+void hangul_input_clear __ARGS((void));
+/* vim: set ft=c : */
diff --git a/src/proto/hardcopy.pro b/src/proto/hardcopy.pro
new file mode 100644
index 0000000000..3744181371
--- /dev/null
+++ b/src/proto/hardcopy.pro
@@ -0,0 +1,21 @@
+/* hardcopy.c */
+char_u *parse_printoptions __ARGS((void));
+char_u *parse_printmbfont __ARGS((void));
+int prt_header_height __ARGS((void));
+int prt_use_number __ARGS((void));
+int prt_get_unit __ARGS((int idx));
+void ex_hardcopy __ARGS((exarg_T *eap));
+void mch_print_cleanup __ARGS((void));
+int mch_print_init __ARGS((prt_settings_T *psettings, char_u *jobname,
+ int forceit));
+int mch_print_begin __ARGS((prt_settings_T *psettings));
+void mch_print_end __ARGS((prt_settings_T *psettings));
+int mch_print_end_page __ARGS((void));
+int mch_print_begin_page __ARGS((char_u *str));
+int mch_print_blank_page __ARGS((void));
+void mch_print_start_line __ARGS((int margin, int page_line));
+int mch_print_text_out __ARGS((char_u *p, int len));
+void mch_print_set_font __ARGS((int iBold, int iItalic, int iUnderline));
+void mch_print_set_bg __ARGS((long_u bgcol));
+void mch_print_set_fg __ARGS((long_u fgcol));
+/* vim: set ft=c : */
diff --git a/src/proto/hashtab.pro b/src/proto/hashtab.pro
new file mode 100644
index 0000000000..c90f44898e
--- /dev/null
+++ b/src/proto/hashtab.pro
@@ -0,0 +1,15 @@
+/* hashtab.c */
+void hash_init __ARGS((hashtab_T *ht));
+void hash_clear __ARGS((hashtab_T *ht));
+void hash_clear_all __ARGS((hashtab_T *ht, int off));
+hashitem_T *hash_find __ARGS((hashtab_T *ht, char_u *key));
+hashitem_T *hash_lookup __ARGS((hashtab_T *ht, char_u *key, hash_T hash));
+void hash_debug_results __ARGS((void));
+int hash_add __ARGS((hashtab_T *ht, char_u *key));
+int hash_add_item __ARGS((hashtab_T *ht, hashitem_T *hi, char_u *key,
+ hash_T hash));
+void hash_remove __ARGS((hashtab_T *ht, hashitem_T *hi));
+void hash_lock __ARGS((hashtab_T *ht));
+void hash_unlock __ARGS((hashtab_T *ht));
+hash_T hash_hash __ARGS((char_u *key));
+/* vim: set ft=c : */
diff --git a/src/proto/if_cscope.pro b/src/proto/if_cscope.pro
new file mode 100644
index 0000000000..1239835d79
--- /dev/null
+++ b/src/proto/if_cscope.pro
@@ -0,0 +1,13 @@
+/* if_cscope.c */
+char_u *get_cscope_name __ARGS((expand_T *xp, int idx));
+void set_context_in_cscope_cmd __ARGS((expand_T *xp, char_u *arg,
+ cmdidx_T cmdidx));
+void do_cscope __ARGS((exarg_T *eap));
+void do_scscope __ARGS((exarg_T *eap));
+void do_cstag __ARGS((exarg_T *eap));
+int cs_fgets __ARGS((char_u *buf, int size));
+void cs_free_tags __ARGS((void));
+void cs_print_tags __ARGS((void));
+int cs_connection __ARGS((int num, char_u *dbpath, char_u *ppath));
+void cs_end __ARGS((void));
+/* vim: set ft=c : */
diff --git a/src/proto/main.pro b/src/proto/main.pro
new file mode 100644
index 0000000000..a93b8de2ae
--- /dev/null
+++ b/src/proto/main.pro
@@ -0,0 +1,27 @@
+/* main.c */
+void main_loop __ARGS((int cmdwin, int noexmode));
+void getout_preserve_modified __ARGS((int exitval));
+void getout __ARGS((int exitval));
+int process_env __ARGS((char_u *env, int is_viminit));
+void mainerr_arg_missing __ARGS((char_u *str));
+void time_push __ARGS((void *tv_rel, void *tv_start));
+void time_pop __ARGS((void *tp));
+void time_msg __ARGS((char *mesg, void *tv_start));
+void server_to_input_buf __ARGS((char_u *str));
+char_u *eval_client_expr_to_string __ARGS((char_u *expr));
+char_u *serverConvert __ARGS((char_u *client_enc, char_u *data, char_u **tofree));
+int toF_TyA __ARGS((int c));
+int fkmap __ARGS((int c));
+void conv_to_pvim __ARGS((void));
+void conv_to_pstd __ARGS((void));
+char_u *lrswap __ARGS((char_u *ibuf));
+char_u *lrFswap __ARGS((char_u *cmdbuf, int len));
+char_u *lrF_sub __ARGS((char_u *ibuf));
+int cmdl_fkmap __ARGS((int c));
+int F_isalpha __ARGS((int c));
+int F_isdigit __ARGS((int c));
+int F_ischar __ARGS((int c));
+void farsi_fkey __ARGS((cmdarg_T *cap));
+int arabic_shape __ARGS((int c, int *ccp, int *c1p, int prev_c, int prev_c1,
+ int next_c));
+/* vim: set ft=c : */
diff --git a/src/proto/mark.pro b/src/proto/mark.pro
new file mode 100644
index 0000000000..47623f4847
--- /dev/null
+++ b/src/proto/mark.pro
@@ -0,0 +1,34 @@
+/* mark.c */
+int setmark __ARGS((int c));
+int setmark_pos __ARGS((int c, pos_T *pos, int fnum));
+void setpcmark __ARGS((void));
+void checkpcmark __ARGS((void));
+pos_T *movemark __ARGS((int count));
+pos_T *movechangelist __ARGS((int count));
+pos_T *getmark_buf __ARGS((buf_T *buf, int c, int changefile));
+pos_T *getmark __ARGS((int c, int changefile));
+pos_T *getmark_buf_fnum __ARGS((buf_T *buf, int c, int changefile, int *fnum));
+pos_T *getnextmark __ARGS((pos_T *startpos, int dir, int begin_line));
+void fmarks_check_names __ARGS((buf_T *buf));
+int check_mark __ARGS((pos_T *pos));
+void clrallmarks __ARGS((buf_T *buf));
+char_u *fm_getname __ARGS((fmark_T *fmark, int lead_len));
+void do_marks __ARGS((exarg_T *eap));
+void ex_delmarks __ARGS((exarg_T *eap));
+void ex_jumps __ARGS((exarg_T *eap));
+void ex_changes __ARGS((exarg_T *eap));
+void mark_adjust __ARGS((linenr_T line1, linenr_T line2, long amount,
+ long amount_after));
+void mark_col_adjust __ARGS((linenr_T lnum, colnr_T mincol, long lnum_amount,
+ long col_amount));
+void copy_jumplist __ARGS((win_T *from, win_T *to));
+void free_jumplist __ARGS((win_T *wp));
+void set_last_cursor __ARGS((win_T *win));
+void free_all_marks __ARGS((void));
+int read_viminfo_filemark __ARGS((vir_T *virp, int force));
+void write_viminfo_filemarks __ARGS((FILE *fp));
+int removable __ARGS((char_u *name));
+int write_viminfo_marks __ARGS((FILE *fp_out));
+void copy_viminfo_marks __ARGS((vir_T *virp, FILE *fp_out, int count, int eof,
+ int flags));
+/* vim: set ft=c : */
diff --git a/src/proto/mbyte.pro b/src/proto/mbyte.pro
new file mode 100644
index 0000000000..c440d62a4e
--- /dev/null
+++ b/src/proto/mbyte.pro
@@ -0,0 +1,100 @@
+/* mbyte.c */
+int enc_canon_props __ARGS((char_u *name));
+char_u *mb_init __ARGS((void));
+int bomb_size __ARGS((void));
+void remove_bom __ARGS((char_u *s));
+int mb_get_class __ARGS((char_u *p));
+int mb_get_class_buf __ARGS((char_u *p, buf_T *buf));
+int dbcs_class __ARGS((unsigned lead, unsigned trail));
+int latin_char2len __ARGS((int c));
+int latin_char2bytes __ARGS((int c, char_u *buf));
+int latin_ptr2len __ARGS((char_u *p));
+int latin_ptr2len_len __ARGS((char_u *p, int size));
+int utf_char2cells __ARGS((int c));
+int latin_ptr2cells __ARGS((char_u *p));
+int utf_ptr2cells __ARGS((char_u *p));
+int dbcs_ptr2cells __ARGS((char_u *p));
+int latin_ptr2cells_len __ARGS((char_u *p, int size));
+int latin_char2cells __ARGS((int c));
+int mb_string2cells __ARGS((char_u *p, int len));
+int latin_off2cells __ARGS((unsigned off, unsigned max_off));
+int dbcs_off2cells __ARGS((unsigned off, unsigned max_off));
+int utf_off2cells __ARGS((unsigned off, unsigned max_off));
+int latin_ptr2char __ARGS((char_u *p));
+int utf_ptr2char __ARGS((char_u *p));
+int mb_ptr2char_adv __ARGS((char_u **pp));
+int mb_cptr2char_adv __ARGS((char_u **pp));
+int arabic_combine __ARGS((int one, int two));
+int arabic_maycombine __ARGS((int two));
+int utf_composinglike __ARGS((char_u *p1, char_u *p2));
+int utfc_ptr2char __ARGS((char_u *p, int *pcc));
+int utfc_ptr2char_len __ARGS((char_u *p, int *pcc, int maxlen));
+int utfc_char2bytes __ARGS((int off, char_u *buf));
+int utf_ptr2len __ARGS((char_u *p));
+int utf_byte2len __ARGS((int b));
+int utf_ptr2len_len __ARGS((char_u *p, int size));
+int utfc_ptr2len __ARGS((char_u *p));
+int utfc_ptr2len_len __ARGS((char_u *p, int size));
+int utf_char2len __ARGS((int c));
+int utf_char2bytes __ARGS((int c, char_u *buf));
+int utf_iscomposing __ARGS((int c));
+int utf_printable __ARGS((int c));
+int utf_class __ARGS((int c));
+int utf_fold __ARGS((int a));
+int utf_toupper __ARGS((int a));
+int utf_islower __ARGS((int a));
+int utf_tolower __ARGS((int a));
+int utf_isupper __ARGS((int a));
+int mb_strnicmp __ARGS((char_u *s1, char_u *s2, size_t nn));
+void show_utf8 __ARGS((void));
+int latin_head_off __ARGS((char_u *base, char_u *p));
+int dbcs_head_off __ARGS((char_u *base, char_u *p));
+int dbcs_screen_head_off __ARGS((char_u *base, char_u *p));
+int utf_head_off __ARGS((char_u *base, char_u *p));
+void mb_copy_char __ARGS((char_u **fp, char_u **tp));
+int mb_off_next __ARGS((char_u *base, char_u *p));
+int mb_tail_off __ARGS((char_u *base, char_u *p));
+void utf_find_illegal __ARGS((void));
+int utf_valid_string __ARGS((char_u *s, char_u *end));
+int dbcs_screen_tail_off __ARGS((char_u *base, char_u *p));
+void mb_adjust_cursor __ARGS((void));
+void mb_adjustpos __ARGS((buf_T *buf, pos_T *lp));
+char_u *mb_prevptr __ARGS((char_u *line, char_u *p));
+int mb_charlen __ARGS((char_u *str));
+int mb_charlen_len __ARGS((char_u *str, int len));
+char_u *mb_unescape __ARGS((char_u **pp));
+int mb_lefthalve __ARGS((int row, int col));
+int mb_fix_col __ARGS((int col, int row));
+char_u *enc_skip __ARGS((char_u *p));
+char_u *enc_canonize __ARGS((char_u *enc));
+char_u *enc_locale __ARGS((void));
+int encname2codepage __ARGS((char_u *name));
+void *my_iconv_open __ARGS((char_u *to, char_u *from));
+int iconv_enabled __ARGS((int verbose));
+void iconv_end __ARGS((void));
+void im_set_active __ARGS((int active));
+void xim_set_focus __ARGS((int focus));
+void im_set_position __ARGS((int row, int col));
+void xim_set_preedit __ARGS((void));
+int im_get_feedback_attr __ARGS((int col));
+void xim_init __ARGS((void));
+void im_shutdown __ARGS((void));
+int im_xim_isvalid_imactivate __ARGS((void));
+void xim_reset __ARGS((void));
+int xim_queue_key_press_event __ARGS((GdkEventKey *event, int down));
+int im_get_status __ARGS((void));
+int preedit_get_status __ARGS((void));
+int im_is_preediting __ARGS((void));
+void xim_set_status_area __ARGS((void));
+int xim_get_status_area_height __ARGS((void));
+int convert_setup __ARGS((vimconv_T *vcp, char_u *from, char_u *to));
+int convert_setup_ext __ARGS((vimconv_T *vcp, char_u *from,
+ int from_unicode_is_utf8, char_u *to,
+ int to_unicode_is_utf8));
+int convert_input __ARGS((char_u *ptr, int len, int maxlen));
+int convert_input_safe __ARGS((char_u *ptr, int len, int maxlen, char_u **restp,
+ int *restlenp));
+char_u *string_convert __ARGS((vimconv_T *vcp, char_u *ptr, int *lenp));
+char_u *string_convert_ext __ARGS((vimconv_T *vcp, char_u *ptr, int *lenp,
+ int *unconvlenp));
+/* vim: set ft=c : */
diff --git a/src/proto/memfile.pro b/src/proto/memfile.pro
new file mode 100644
index 0000000000..3983b4799c
--- /dev/null
+++ b/src/proto/memfile.pro
@@ -0,0 +1,18 @@
+/* memfile.c */
+memfile_T *mf_open __ARGS((char_u *fname, int flags));
+int mf_open_file __ARGS((memfile_T *mfp, char_u *fname));
+void mf_close __ARGS((memfile_T *mfp, int del_file));
+void mf_close_file __ARGS((buf_T *buf, int getlines));
+void mf_new_page_size __ARGS((memfile_T *mfp, unsigned new_size));
+bhdr_T *mf_new __ARGS((memfile_T *mfp, int negative, int page_count));
+bhdr_T *mf_get __ARGS((memfile_T *mfp, blocknr_T nr, int page_count));
+void mf_put __ARGS((memfile_T *mfp, bhdr_T *hp, int dirty, int infile));
+void mf_free __ARGS((memfile_T *mfp, bhdr_T *hp));
+int mf_sync __ARGS((memfile_T *mfp, int flags));
+void mf_set_dirty __ARGS((memfile_T *mfp));
+int mf_release_all __ARGS((void));
+blocknr_T mf_trans_del __ARGS((memfile_T *mfp, blocknr_T old_nr));
+void mf_set_ffname __ARGS((memfile_T *mfp));
+void mf_fullname __ARGS((memfile_T *mfp));
+int mf_need_trans __ARGS((memfile_T *mfp));
+/* vim: set ft=c : */
diff --git a/src/proto/memline.pro b/src/proto/memline.pro
new file mode 100644
index 0000000000..97806d38a2
--- /dev/null
+++ b/src/proto/memline.pro
@@ -0,0 +1,41 @@
+/* memline.c */
+int ml_open __ARGS((buf_T *buf));
+void ml_set_crypt_key __ARGS((buf_T *buf, char_u *old_key, int old_cm));
+void ml_setname __ARGS((buf_T *buf));
+void ml_open_files __ARGS((void));
+void ml_open_file __ARGS((buf_T *buf));
+void check_need_swap __ARGS((int newfile));
+void ml_close __ARGS((buf_T *buf, int del_file));
+void ml_close_all __ARGS((int del_file));
+void ml_close_notmod __ARGS((void));
+void ml_timestamp __ARGS((buf_T *buf));
+void ml_recover __ARGS((void));
+int recover_names __ARGS((char_u *fname, int list, int nr, char_u **fname_out));
+void ml_sync_all __ARGS((int check_file, int check_char));
+void ml_preserve __ARGS((buf_T *buf, int message));
+char_u *ml_get __ARGS((linenr_T lnum));
+char_u *ml_get_pos __ARGS((pos_T *pos));
+char_u *ml_get_curline __ARGS((void));
+char_u *ml_get_cursor __ARGS((void));
+char_u *ml_get_buf __ARGS((buf_T *buf, linenr_T lnum, int will_change));
+int ml_line_alloced __ARGS((void));
+int ml_append __ARGS((linenr_T lnum, char_u *line, colnr_T len, int newfile));
+int ml_append_buf __ARGS((buf_T *buf, linenr_T lnum, char_u *line, colnr_T len,
+ int newfile));
+int ml_replace __ARGS((linenr_T lnum, char_u *line, int copy));
+int ml_delete __ARGS((linenr_T lnum, int message));
+void ml_setmarked __ARGS((linenr_T lnum));
+linenr_T ml_firstmarked __ARGS((void));
+void ml_clearmarked __ARGS((void));
+int resolve_symlink __ARGS((char_u *fname, char_u *buf));
+char_u *makeswapname __ARGS((char_u *fname, char_u *ffname, buf_T *buf,
+ char_u *dir_name));
+char_u *get_file_in_dir __ARGS((char_u *fname, char_u *dname));
+void ml_setflags __ARGS((buf_T *buf));
+char_u *ml_encrypt_data __ARGS((memfile_T *mfp, char_u *data, off_t offset,
+ unsigned size));
+void ml_decrypt_data __ARGS((memfile_T *mfp, char_u *data, off_t offset,
+ unsigned size));
+long ml_find_line_or_offset __ARGS((buf_T *buf, linenr_T lnum, long *offp));
+void goto_byte __ARGS((long cnt));
+/* vim: set ft=c : */
diff --git a/src/proto/menu.pro b/src/proto/menu.pro
new file mode 100644
index 0000000000..80460d2de2
--- /dev/null
+++ b/src/proto/menu.pro
@@ -0,0 +1,23 @@
+/* menu.c */
+void ex_menu __ARGS((exarg_T *eap));
+char_u *set_context_in_menu_cmd __ARGS((expand_T *xp, char_u *cmd, char_u *arg,
+ int forceit));
+char_u *get_menu_name __ARGS((expand_T *xp, int idx));
+char_u *get_menu_names __ARGS((expand_T *xp, int idx));
+char_u *menu_name_skip __ARGS((char_u *name));
+int get_menu_index __ARGS((vimmenu_T *menu, int state));
+int menu_is_menubar __ARGS((char_u *name));
+int menu_is_popup __ARGS((char_u *name));
+int menu_is_child_of_popup __ARGS((vimmenu_T *menu));
+int menu_is_toolbar __ARGS((char_u *name));
+int menu_is_separator __ARGS((char_u *name));
+int check_menu_pointer __ARGS((vimmenu_T *root, vimmenu_T *menu_to_check));
+void gui_create_initial_menus __ARGS((vimmenu_T *menu));
+void gui_update_menus __ARGS((int modes));
+int gui_is_menu_shortcut __ARGS((int key));
+void gui_show_popupmenu __ARGS((void));
+void gui_mch_toggle_tearoffs __ARGS((int enable));
+void ex_emenu __ARGS((exarg_T *eap));
+vimmenu_T *gui_find_menu __ARGS((char_u *path_name));
+void ex_menutranslate __ARGS((exarg_T *eap));
+/* vim: set ft=c : */
diff --git a/src/proto/message.pro b/src/proto/message.pro
new file mode 100644
index 0000000000..ece1985213
--- /dev/null
+++ b/src/proto/message.pro
@@ -0,0 +1,80 @@
+/* message.c */
+int msg __ARGS((char_u *s));
+int verb_msg __ARGS((char_u *s));
+int msg_attr __ARGS((char_u *s, int attr));
+int msg_attr_keep __ARGS((char_u *s, int attr, int keep));
+char_u *msg_strtrunc __ARGS((char_u *s, int force));
+void trunc_string __ARGS((char_u *s, char_u *buf, int room, int buflen));
+void reset_last_sourcing __ARGS((void));
+void msg_source __ARGS((int attr));
+int emsg_not_now __ARGS((void));
+int emsg __ARGS((char_u *s));
+int emsg2 __ARGS((char_u *s, char_u *a1));
+void emsg_invreg __ARGS((int name));
+char_u *msg_trunc_attr __ARGS((char_u *s, int force, int attr));
+char_u *msg_may_trunc __ARGS((int force, char_u *s));
+int delete_first_msg __ARGS((void));
+void ex_messages __ARGS((exarg_T *eap));
+void msg_end_prompt __ARGS((void));
+void wait_return __ARGS((int redraw));
+void set_keep_msg __ARGS((char_u *s, int attr));
+void set_keep_msg_from_hist __ARGS((void));
+void msg_start __ARGS((void));
+void msg_starthere __ARGS((void));
+void msg_putchar __ARGS((int c));
+void msg_putchar_attr __ARGS((int c, int attr));
+void msg_outnum __ARGS((long n));
+void msg_home_replace __ARGS((char_u *fname));
+void msg_home_replace_hl __ARGS((char_u *fname));
+int msg_outtrans __ARGS((char_u *str));
+int msg_outtrans_attr __ARGS((char_u *str, int attr));
+int msg_outtrans_len __ARGS((char_u *str, int len));
+char_u *msg_outtrans_one __ARGS((char_u *p, int attr));
+int msg_outtrans_len_attr __ARGS((char_u *msgstr, int len, int attr));
+void msg_make __ARGS((char_u *arg));
+int msg_outtrans_special __ARGS((char_u *strstart, int from));
+char_u *str2special_save __ARGS((char_u *str, int is_lhs));
+char_u *str2special __ARGS((char_u **sp, int from));
+void str2specialbuf __ARGS((char_u *sp, char_u *buf, int len));
+void msg_prt_line __ARGS((char_u *s, int list));
+void msg_puts __ARGS((char_u *s));
+void msg_puts_title __ARGS((char_u *s));
+void msg_puts_long_attr __ARGS((char_u *longstr, int attr));
+void msg_puts_long_len_attr __ARGS((char_u *longstr, int len, int attr));
+void msg_puts_attr __ARGS((char_u *s, int attr));
+void may_clear_sb_text __ARGS((void));
+void clear_sb_text __ARGS((void));
+void show_sb_text __ARGS((void));
+void msg_sb_eol __ARGS((void));
+int msg_use_printf __ARGS((void));
+void mch_errmsg __ARGS((char *str));
+void mch_msg __ARGS((char *str));
+void msg_moremsg __ARGS((int full));
+void repeat_message __ARGS((void));
+void msg_clr_eos __ARGS((void));
+void msg_clr_eos_force __ARGS((void));
+void msg_clr_cmdline __ARGS((void));
+int msg_end __ARGS((void));
+void msg_check __ARGS((void));
+int redirecting __ARGS((void));
+void verbose_enter __ARGS((void));
+void verbose_leave __ARGS((void));
+void verbose_enter_scroll __ARGS((void));
+void verbose_leave_scroll __ARGS((void));
+void verbose_stop __ARGS((void));
+int verbose_open __ARGS((void));
+void give_warning __ARGS((char_u *message, int hl));
+void msg_advance __ARGS((int col));
+int do_dialog __ARGS((int type, char_u *title, char_u *message, char_u *buttons,
+ int dfltbutton, char_u *textfield,
+ int ex_cmd));
+void display_confirm_msg __ARGS((void));
+int vim_dialog_yesno __ARGS((int type, char_u *title, char_u *message, int dflt));
+int vim_dialog_yesnocancel __ARGS((int type, char_u *title, char_u *message,
+ int dflt));
+int vim_dialog_yesnoallcancel __ARGS((int type, char_u *title, char_u *message,
+ int dflt));
+char_u *do_browse __ARGS((int flags, char_u *title, char_u *dflt, char_u *ext,
+ char_u *initdir, char_u *filter,
+ buf_T *buf));
+/* vim: set ft=c : */
diff --git a/src/proto/misc1.pro b/src/proto/misc1.pro
new file mode 100644
index 0000000000..0497096791
--- /dev/null
+++ b/src/proto/misc1.pro
@@ -0,0 +1,117 @@
+/* misc1.c */
+int get_indent __ARGS((void));
+int get_indent_lnum __ARGS((linenr_T lnum));
+int get_indent_buf __ARGS((buf_T *buf, linenr_T lnum));
+int get_indent_str __ARGS((char_u *ptr, int ts));
+int set_indent __ARGS((int size, int flags));
+int get_number_indent __ARGS((linenr_T lnum));
+int open_line __ARGS((int dir, int flags, int second_line_indent));
+int get_leader_len __ARGS((char_u *line, char_u **flags, int backward,
+ int include_space));
+int get_last_leader_offset __ARGS((char_u *line, char_u **flags));
+int plines __ARGS((linenr_T lnum));
+int plines_win __ARGS((win_T *wp, linenr_T lnum, int winheight));
+int plines_nofill __ARGS((linenr_T lnum));
+int plines_win_nofill __ARGS((win_T *wp, linenr_T lnum, int winheight));
+int plines_win_nofold __ARGS((win_T *wp, linenr_T lnum));
+int plines_win_col __ARGS((win_T *wp, linenr_T lnum, long column));
+int plines_m_win __ARGS((win_T *wp, linenr_T first, linenr_T last));
+void ins_bytes __ARGS((char_u *p));
+void ins_bytes_len __ARGS((char_u *p, int len));
+void ins_char __ARGS((int c));
+void ins_char_bytes __ARGS((char_u *buf, int charlen));
+void ins_str __ARGS((char_u *s));
+int del_char __ARGS((int fixpos));
+int del_chars __ARGS((long count, int fixpos));
+int del_bytes __ARGS((long count, int fixpos_arg, int use_delcombine));
+int truncate_line __ARGS((int fixpos));
+void del_lines __ARGS((long nlines, int undo));
+int gchar_pos __ARGS((pos_T *pos));
+int gchar_cursor __ARGS((void));
+void pchar_cursor __ARGS((int c));
+int inindent __ARGS((int extra));
+char_u *skip_to_option_part __ARGS((char_u *p));
+void changed __ARGS((void));
+void changed_int __ARGS((void));
+void changed_bytes __ARGS((linenr_T lnum, colnr_T col));
+void appended_lines __ARGS((linenr_T lnum, long count));
+void appended_lines_mark __ARGS((linenr_T lnum, long count));
+void deleted_lines __ARGS((linenr_T lnum, long count));
+void deleted_lines_mark __ARGS((linenr_T lnum, long count));
+void changed_lines __ARGS((linenr_T lnum, colnr_T col, linenr_T lnume,
+ long xtra));
+void unchanged __ARGS((buf_T *buf, int ff));
+void check_status __ARGS((buf_T *buf));
+void change_warning __ARGS((int col));
+int ask_yesno __ARGS((char_u *str, int direct));
+int is_mouse_key __ARGS((int c));
+int get_keystroke __ARGS((void));
+int get_number __ARGS((int colon, int *mouse_used));
+int prompt_for_number __ARGS((int *mouse_used));
+void msgmore __ARGS((long n));
+void beep_flush __ARGS((void));
+void vim_beep __ARGS((void));
+void init_homedir __ARGS((void));
+void free_homedir __ARGS((void));
+void free_users __ARGS((void));
+char_u *expand_env_save __ARGS((char_u *src));
+char_u *expand_env_save_opt __ARGS((char_u *src, int one));
+void expand_env __ARGS((char_u *src, char_u *dst, int dstlen));
+void expand_env_esc __ARGS((char_u *srcp, char_u *dst, int dstlen, int esc,
+ int one,
+ char_u *startstr));
+char_u *vim_getenv __ARGS((char_u *name, int *mustfree));
+void vim_setenv __ARGS((char_u *name, char_u *val));
+char_u *get_env_name __ARGS((expand_T *xp, int idx));
+char_u *get_users __ARGS((expand_T *xp, int idx));
+int match_user __ARGS((char_u *name));
+void home_replace __ARGS((buf_T *buf, char_u *src, char_u *dst, int dstlen,
+ int one));
+char_u *home_replace_save __ARGS((buf_T *buf, char_u *src));
+int fullpathcmp __ARGS((char_u *s1, char_u *s2, int checkname));
+char_u *gettail __ARGS((char_u *fname));
+char_u *gettail_sep __ARGS((char_u *fname));
+char_u *getnextcomp __ARGS((char_u *fname));
+char_u *get_past_head __ARGS((char_u *path));
+int vim_ispathsep __ARGS((int c));
+int vim_ispathsep_nocolon __ARGS((int c));
+int vim_ispathlistsep __ARGS((int c));
+void shorten_dir __ARGS((char_u *str));
+int dir_of_file_exists __ARGS((char_u *fname));
+int vim_fnamecmp __ARGS((char_u *x, char_u *y));
+int vim_fnamencmp __ARGS((char_u *x, char_u *y, size_t len));
+char_u *concat_fnames __ARGS((char_u *fname1, char_u *fname2, int sep));
+char_u *concat_str __ARGS((char_u *str1, char_u *str2));
+void add_pathsep __ARGS((char_u *p));
+char_u *FullName_save __ARGS((char_u *fname, int force));
+pos_T *find_start_comment __ARGS((int ind_maxcomment));
+void do_c_expr_indent __ARGS((void));
+int cin_islabel __ARGS((void));
+int cin_iscase __ARGS((char_u *s, int strict));
+int cin_isscopedecl __ARGS((char_u *s));
+void parse_cino __ARGS((buf_T *buf));
+int get_c_indent __ARGS((void));
+int get_expr_indent __ARGS((void));
+int get_lisp_indent __ARGS((void));
+void prepare_to_exit __ARGS((void));
+void preserve_exit __ARGS((void));
+int vim_fexists __ARGS((char_u *fname));
+void line_breakcheck __ARGS((void));
+void fast_breakcheck __ARGS((void));
+int expand_wildcards_eval __ARGS((char_u **pat, int *num_file, char_u ***file,
+ int flags));
+int expand_wildcards __ARGS((int num_pat, char_u **pat, int *num_file, char_u *
+ **file,
+ int flags));
+int match_suffix __ARGS((char_u *fname));
+int unix_expandpath __ARGS((garray_T *gap, char_u *path, int wildoff, int flags,
+ int didstar));
+void remove_duplicates __ARGS((garray_T *gap));
+int gen_expand_wildcards __ARGS((int num_pat, char_u **pat, int *num_file,
+ char_u ***file,
+ int flags));
+void addfile __ARGS((garray_T *gap, char_u *f, int flags));
+char_u *get_cmd_output __ARGS((char_u *cmd, char_u *infile, int flags));
+void FreeWild __ARGS((int count, char_u **files));
+int goto_im __ARGS((void));
+/* vim: set ft=c : */
diff --git a/src/proto/misc2.pro b/src/proto/misc2.pro
new file mode 100644
index 0000000000..c0fd06ff77
--- /dev/null
+++ b/src/proto/misc2.pro
@@ -0,0 +1,133 @@
+/* misc2.c */
+int virtual_active __ARGS((void));
+int getviscol __ARGS((void));
+int getviscol2 __ARGS((colnr_T col, colnr_T coladd));
+int coladvance_force __ARGS((colnr_T wcol));
+int coladvance __ARGS((colnr_T wcol));
+int getvpos __ARGS((pos_T *pos, colnr_T wcol));
+int inc_cursor __ARGS((void));
+int inc __ARGS((pos_T *lp));
+int incl __ARGS((pos_T *lp));
+int dec_cursor __ARGS((void));
+int dec __ARGS((pos_T *lp));
+int decl __ARGS((pos_T *lp));
+linenr_T get_cursor_rel_lnum __ARGS((win_T *wp, linenr_T lnum));
+void check_cursor_lnum __ARGS((void));
+void check_cursor_col __ARGS((void));
+void check_cursor_col_win __ARGS((win_T *win));
+void check_cursor __ARGS((void));
+void adjust_cursor_col __ARGS((void));
+int leftcol_changed __ARGS((void));
+void vim_mem_profile_dump __ARGS((void));
+char_u *alloc __ARGS((unsigned size));
+char_u *alloc_clear __ARGS((unsigned size));
+char_u *alloc_check __ARGS((unsigned size));
+char_u *lalloc_clear __ARGS((long_u size, int message));
+char_u *lalloc __ARGS((long_u size, int message));
+void *mem_realloc __ARGS((void *ptr, size_t size));
+void do_outofmem_msg __ARGS((long_u size));
+void free_all_mem __ARGS((void));
+char_u *vim_strsave __ARGS((char_u *string));
+char_u *vim_strnsave __ARGS((char_u *string, int len));
+char_u *vim_strsave_escaped __ARGS((char_u *string, char_u *esc_chars));
+char_u *vim_strsave_escaped_ext __ARGS((char_u *string, char_u *esc_chars,
+ int cc,
+ int bsl));
+int csh_like_shell __ARGS((void));
+char_u *vim_strsave_shellescape __ARGS((char_u *string, int do_special));
+char_u *vim_strsave_up __ARGS((char_u *string));
+char_u *vim_strnsave_up __ARGS((char_u *string, int len));
+void vim_strup __ARGS((char_u *p));
+char_u *strup_save __ARGS((char_u *orig));
+void copy_spaces __ARGS((char_u *ptr, size_t count));
+void copy_chars __ARGS((char_u *ptr, size_t count, int c));
+void del_trailing_spaces __ARGS((char_u *ptr));
+void vim_strncpy __ARGS((char_u *to, char_u *from, size_t len));
+void vim_strcat __ARGS((char_u *to, char_u *from, size_t tosize));
+int copy_option_part __ARGS((char_u **option, char_u *buf, int maxlen,
+ char *sep_chars));
+void vim_free __ARGS((void *x));
+int vim_stricmp __ARGS((char *s1, char *s2));
+int vim_strnicmp __ARGS((char *s1, char *s2, size_t len));
+char_u *vim_strchr __ARGS((char_u *string, int c));
+char_u *vim_strbyte __ARGS((char_u *string, int c));
+char_u *vim_strrchr __ARGS((char_u *string, int c));
+int vim_isspace __ARGS((int x));
+void ga_clear __ARGS((garray_T *gap));
+void ga_clear_strings __ARGS((garray_T *gap));
+void ga_init __ARGS((garray_T *gap));
+void ga_init2 __ARGS((garray_T *gap, int itemsize, int growsize));
+int ga_grow __ARGS((garray_T *gap, int n));
+char_u *ga_concat_strings __ARGS((garray_T *gap));
+void ga_concat __ARGS((garray_T *gap, char_u *s));
+void ga_append __ARGS((garray_T *gap, int c));
+void append_ga_line __ARGS((garray_T *gap));
+int name_to_mod_mask __ARGS((int c));
+int simplify_key __ARGS((int key, int *modifiers));
+int handle_x_keys __ARGS((int key));
+char_u *get_special_key_name __ARGS((int c, int modifiers));
+int trans_special __ARGS((char_u **srcp, char_u *dst, int keycode));
+int find_special_key __ARGS((char_u **srcp, int *modp, int keycode,
+ int keep_x_key));
+int extract_modifiers __ARGS((int key, int *modp));
+int find_special_key_in_table __ARGS((int c));
+int get_special_key_code __ARGS((char_u *name));
+char_u *get_key_name __ARGS((int i));
+int get_mouse_button __ARGS((int code, int *is_click, int *is_drag));
+int get_pseudo_mouse_code __ARGS((int button, int is_click, int is_drag));
+int get_fileformat __ARGS((buf_T *buf));
+int get_fileformat_force __ARGS((buf_T *buf, exarg_T *eap));
+void set_fileformat __ARGS((int t, int opt_flags));
+int default_fileformat __ARGS((void));
+int call_shell __ARGS((char_u *cmd, int opt));
+int get_real_state __ARGS((void));
+int after_pathsep __ARGS((char_u *b, char_u *p));
+int same_directory __ARGS((char_u *f1, char_u *f2));
+int vim_chdirfile __ARGS((char_u *fname));
+int illegal_slash __ARGS((char *name));
+char_u *parse_shape_opt __ARGS((int what));
+int get_shape_idx __ARGS((int mouse));
+void update_mouseshape __ARGS((int shape_idx));
+int crypt_method_from_string __ARGS((char_u *s));
+int get_crypt_method __ARGS((buf_T *buf));
+void set_crypt_method __ARGS((buf_T *buf, int method));
+void crypt_push_state __ARGS((void));
+void crypt_pop_state __ARGS((void));
+void crypt_encode __ARGS((char_u *from, size_t len, char_u *to));
+void crypt_decode __ARGS((char_u *ptr, long len));
+void crypt_init_keys __ARGS((char_u *passwd));
+void free_crypt_key __ARGS((char_u *key));
+char_u *get_crypt_key __ARGS((int store, int twice));
+void *vim_findfile_init __ARGS((char_u *path, char_u *filename, char_u *
+ stopdirs, int level, int free_visited,
+ int find_what, void *search_ctx_arg,
+ int tagfile,
+ char_u *rel_fname));
+char_u *vim_findfile_stopdir __ARGS((char_u *buf));
+void vim_findfile_cleanup __ARGS((void *ctx));
+char_u *vim_findfile __ARGS((void *search_ctx_arg));
+void vim_findfile_free_visited __ARGS((void *search_ctx_arg));
+char_u *find_file_in_path __ARGS((char_u *ptr, int len, int options, int first,
+ char_u *rel_fname));
+char_u *find_directory_in_path __ARGS((char_u *ptr, int len, int options,
+ char_u *rel_fname));
+char_u *find_file_in_path_option __ARGS((char_u *ptr, int len, int options,
+ int first, char_u *path_option,
+ int find_what, char_u *rel_fname,
+ char_u *suffixes));
+int vim_chdir __ARGS((char_u *new_dir));
+int get_user_name __ARGS((char_u *buf, int len));
+void sort_strings __ARGS((char_u **files, int count));
+int pathcmp __ARGS((const char *p, const char *q, int maxlen));
+int filewritable __ARGS((char_u *fname));
+int emsg3 __ARGS((char_u *s, char_u *a1, char_u *a2));
+int emsgn __ARGS((char_u *s, long n));
+int get2c __ARGS((FILE *fd));
+int get3c __ARGS((FILE *fd));
+int get4c __ARGS((FILE *fd));
+time_t get8ctime __ARGS((FILE *fd));
+char_u *read_string __ARGS((FILE *fd, int cnt));
+int put_bytes __ARGS((FILE *fd, long_u nr, int len));
+void put_time __ARGS((FILE *fd, time_t the_time));
+int has_non_ascii __ARGS((char_u *s));
+/* vim: set ft=c : */
diff --git a/src/proto/move.pro b/src/proto/move.pro
new file mode 100644
index 0000000000..595e3b8dd7
--- /dev/null
+++ b/src/proto/move.pro
@@ -0,0 +1,41 @@
+/* move.c */
+void update_topline_redraw __ARGS((void));
+void update_topline __ARGS((void));
+void update_curswant __ARGS((void));
+void check_cursor_moved __ARGS((win_T *wp));
+void changed_window_setting __ARGS((void));
+void changed_window_setting_win __ARGS((win_T *wp));
+void set_topline __ARGS((win_T *wp, linenr_T lnum));
+void changed_cline_bef_curs __ARGS((void));
+void changed_cline_bef_curs_win __ARGS((win_T *wp));
+void changed_line_abv_curs __ARGS((void));
+void changed_line_abv_curs_win __ARGS((win_T *wp));
+void validate_botline __ARGS((void));
+void invalidate_botline __ARGS((void));
+void invalidate_botline_win __ARGS((win_T *wp));
+void approximate_botline_win __ARGS((win_T *wp));
+int cursor_valid __ARGS((void));
+void validate_cursor __ARGS((void));
+void validate_cline_row __ARGS((void));
+void validate_virtcol __ARGS((void));
+void validate_virtcol_win __ARGS((win_T *wp));
+void validate_cursor_col __ARGS((void));
+int win_col_off __ARGS((win_T *wp));
+int curwin_col_off __ARGS((void));
+int win_col_off2 __ARGS((win_T *wp));
+int curwin_col_off2 __ARGS((void));
+void curs_columns __ARGS((int may_scroll));
+void scrolldown __ARGS((long line_count, int byfold));
+void scrollup __ARGS((long line_count, int byfold));
+void check_topfill __ARGS((win_T *wp, int down));
+void scrolldown_clamp __ARGS((void));
+void scrollup_clamp __ARGS((void));
+void scroll_cursor_top __ARGS((int min_scroll, int always));
+void set_empty_rows __ARGS((win_T *wp, int used));
+void scroll_cursor_bot __ARGS((int min_scroll, int set_topbot));
+void scroll_cursor_halfway __ARGS((int atend));
+void cursor_correct __ARGS((void));
+int onepage __ARGS((int dir, long count));
+void halfpage __ARGS((int flag, linenr_T Prenum));
+void do_check_cursorbind __ARGS((void));
+/* vim: set ft=c : */
diff --git a/src/proto/normal.pro b/src/proto/normal.pro
new file mode 100644
index 0000000000..a178751474
--- /dev/null
+++ b/src/proto/normal.pro
@@ -0,0 +1,29 @@
+/* normal.c */
+void init_normal_cmds __ARGS((void));
+void normal_cmd __ARGS((oparg_T *oap, int toplevel));
+void do_pending_operator __ARGS((cmdarg_T *cap, int old_col, int gui_yank));
+int do_mouse __ARGS((oparg_T *oap, int c, int dir, long count, int fixindent));
+void check_visual_highlight __ARGS((void));
+void end_visual_mode __ARGS((void));
+void reset_VIsual_and_resel __ARGS((void));
+void reset_VIsual __ARGS((void));
+int find_ident_under_cursor __ARGS((char_u **string, int find_type));
+int find_ident_at_pos __ARGS((win_T *wp, linenr_T lnum, colnr_T startcol,
+ char_u **string,
+ int find_type));
+void clear_showcmd __ARGS((void));
+int add_to_showcmd __ARGS((int c));
+void add_to_showcmd_c __ARGS((int c));
+void push_showcmd __ARGS((void));
+void pop_showcmd __ARGS((void));
+void do_check_scrollbind __ARGS((int check));
+void check_scrollbind __ARGS((linenr_T topline_diff, long leftcol_diff));
+int find_decl __ARGS((char_u *ptr, int len, int locally, int thisblock,
+ int searchflags));
+void scroll_redraw __ARGS((int up, long count));
+void handle_tabmenu __ARGS((void));
+void do_nv_ident __ARGS((int c1, int c2));
+int get_visual_text __ARGS((cmdarg_T *cap, char_u **pp, int *lenp));
+void start_selection __ARGS((void));
+void may_start_select __ARGS((int c));
+/* vim: set ft=c : */
diff --git a/src/proto/ops.pro b/src/proto/ops.pro
new file mode 100644
index 0000000000..f69f71ae25
--- /dev/null
+++ b/src/proto/ops.pro
@@ -0,0 +1,66 @@
+/* ops.c */
+int get_op_type __ARGS((int char1, int char2));
+int op_on_lines __ARGS((int op));
+int get_op_char __ARGS((int optype));
+int get_extra_op_char __ARGS((int optype));
+void op_shift __ARGS((oparg_T *oap, int curs_top, int amount));
+void shift_line __ARGS((int left, int round, int amount, int call_changed_bytes));
+void op_reindent __ARGS((oparg_T *oap, int (*how)(void)));
+int get_expr_register __ARGS((void));
+void set_expr_line __ARGS((char_u *new_line));
+char_u *get_expr_line __ARGS((void));
+char_u *get_expr_line_src __ARGS((void));
+int valid_yank_reg __ARGS((int regname, int writing));
+void get_yank_register __ARGS((int regname, int writing));
+int may_get_selection __ARGS((int regname));
+void *get_register __ARGS((int name, int copy));
+void put_register __ARGS((int name, void *reg));
+void free_register __ARGS((void *reg));
+int yank_register_mline __ARGS((int regname));
+int do_record __ARGS((int c));
+int do_execreg __ARGS((int regname, int colon, int addcr, int silent));
+int insert_reg __ARGS((int regname, int literally));
+int get_spec_reg __ARGS((int regname, char_u **argp, int *allocated, int errmsg));
+int cmdline_paste_reg __ARGS((int regname, int literally, int remcr));
+void adjust_clip_reg __ARGS((int *rp));
+int op_delete __ARGS((oparg_T *oap));
+int op_replace __ARGS((oparg_T *oap, int c));
+void op_tilde __ARGS((oparg_T *oap));
+int swapchar __ARGS((int op_type, pos_T *pos));
+void op_insert __ARGS((oparg_T *oap, long count1));
+int op_change __ARGS((oparg_T *oap));
+void init_yank __ARGS((void));
+void clear_registers __ARGS((void));
+int op_yank __ARGS((oparg_T *oap, int deleting, int mess));
+void do_put __ARGS((int regname, int dir, long count, int flags));
+void adjust_cursor_eol __ARGS((void));
+int preprocs_left __ARGS((void));
+int get_register_name __ARGS((int num));
+void ex_display __ARGS((exarg_T *eap));
+int do_join __ARGS((long count, int insert_space, int save_undo,
+ int use_formatoptions));
+void op_format __ARGS((oparg_T *oap, int keep_cursor));
+void op_formatexpr __ARGS((oparg_T *oap));
+int fex_format __ARGS((linenr_T lnum, long count, int c));
+void format_lines __ARGS((linenr_T line_count, int avoid_fex));
+int paragraph_start __ARGS((linenr_T lnum));
+int do_addsub __ARGS((int command, linenr_T Prenum1));
+int read_viminfo_register __ARGS((vir_T *virp, int force));
+void write_viminfo_registers __ARGS((FILE *fp));
+void x11_export_final_selection __ARGS((void));
+void clip_free_selection __ARGS((VimClipboard *cbd));
+void clip_get_selection __ARGS((VimClipboard *cbd));
+void clip_yank_selection __ARGS((int type, char_u *str, long len,
+ VimClipboard *cbd));
+int clip_convert_selection __ARGS((char_u **str, long_u *len, VimClipboard *cbd));
+void dnd_yank_drag_data __ARGS((char_u *str, long len));
+char_u get_reg_type __ARGS((int regname, long *reglen));
+char_u *get_reg_contents __ARGS((int regname, int allowexpr, int expr_src));
+void write_reg_contents __ARGS((int name, char_u *str, int maxlen,
+ int must_append));
+void write_reg_contents_ex __ARGS((int name, char_u *str, int maxlen,
+ int must_append, int yank_type,
+ long block_len));
+void clear_oparg __ARGS((oparg_T *oap));
+void cursor_pos_info __ARGS((void));
+/* vim: set ft=c : */
diff --git a/src/proto/option.pro b/src/proto/option.pro
new file mode 100644
index 0000000000..00aa74d34a
--- /dev/null
+++ b/src/proto/option.pro
@@ -0,0 +1,74 @@
+/* option.c */
+void set_init_1 __ARGS((void));
+void set_string_default __ARGS((char *name, char_u *val));
+void set_number_default __ARGS((char *name, long val));
+void free_all_options __ARGS((void));
+void set_init_2 __ARGS((void));
+void set_init_3 __ARGS((void));
+void set_helplang_default __ARGS((char_u *lang));
+void init_gui_options __ARGS((void));
+void set_title_defaults __ARGS((void));
+int do_set __ARGS((char_u *arg, int opt_flags));
+void set_options_bin __ARGS((int oldval, int newval, int opt_flags));
+int get_viminfo_parameter __ARGS((int type));
+char_u *find_viminfo_parameter __ARGS((int type));
+void check_options __ARGS((void));
+void check_buf_options __ARGS((buf_T *buf));
+void free_string_option __ARGS((char_u *p));
+void clear_string_option __ARGS((char_u **pp));
+void set_term_option_alloced __ARGS((char_u **p));
+int was_set_insecurely __ARGS((char_u *opt, int opt_flags));
+void set_string_option_direct __ARGS((char_u *name, int opt_idx, char_u *val,
+ int opt_flags,
+ int set_sid));
+char_u *check_colorcolumn __ARGS((win_T *wp));
+char_u *check_stl_option __ARGS((char_u *s));
+int get_option_value __ARGS((char_u *name, long *numval, char_u **stringval,
+ int opt_flags));
+int get_option_value_strict __ARGS((char_u *name, long *numval, char_u *
+ *stringval, int opt_type,
+ void *from));
+char_u *option_iter_next __ARGS((void **option, int opt_type));
+char_u *set_option_value __ARGS((char_u *name, long number, char_u *string,
+ int opt_flags));
+char_u *get_term_code __ARGS((char_u *tname));
+char_u *get_highlight_default __ARGS((void));
+char_u *get_encoding_default __ARGS((void));
+int makeset __ARGS((FILE *fd, int opt_flags, int local_only));
+int makefoldset __ARGS((FILE *fd));
+void clear_termoptions __ARGS((void));
+void free_termoptions __ARGS((void));
+void free_one_termoption __ARGS((char_u *var));
+void set_term_defaults __ARGS((void));
+void comp_col __ARGS((void));
+void unset_global_local_option __ARGS((char_u *name, void *from));
+char_u *get_equalprg __ARGS((void));
+void win_copy_options __ARGS((win_T *wp_from, win_T *wp_to));
+void copy_winopt __ARGS((winopt_T *from, winopt_T *to));
+void check_win_options __ARGS((win_T *win));
+void check_winopt __ARGS((winopt_T *wop));
+void clear_winopt __ARGS((winopt_T *wop));
+void buf_copy_options __ARGS((buf_T *buf, int flags));
+void reset_modifiable __ARGS((void));
+void set_iminsert_global __ARGS((void));
+void set_imsearch_global __ARGS((void));
+void set_context_in_set_cmd __ARGS((expand_T *xp, char_u *arg, int opt_flags));
+int ExpandSettings __ARGS((expand_T *xp, regmatch_T *regmatch, int *num_file,
+ char_u ***file));
+int ExpandOldSetting __ARGS((int *num_file, char_u ***file));
+int langmap_adjust_mb __ARGS((int c));
+int has_format_option __ARGS((int x));
+int shortmess __ARGS((int x));
+void vimrc_found __ARGS((char_u *fname, char_u *envname));
+void change_compatible __ARGS((int on));
+int option_was_set __ARGS((char_u *name));
+void reset_option_was_set __ARGS((char_u *name));
+int can_bs __ARGS((int what));
+void save_file_ff __ARGS((buf_T *buf));
+int file_ff_differs __ARGS((buf_T *buf, int ignore_empty));
+int check_ff_value __ARGS((char_u *p));
+long get_sw_value __ARGS((buf_T *buf));
+long get_sts_value __ARGS((void));
+void find_mps_values __ARGS((int *initc, int *findc, int *backwards,
+ int switchit));
+/* vim: set ft=c : */
diff --git a/src/proto/os_unix.pro b/src/proto/os_unix.pro
new file mode 100644
index 0000000000..3c97345d00
--- /dev/null
+++ b/src/proto/os_unix.pro
@@ -0,0 +1,80 @@
+/* os_unix.c */
+int mch_chdir __ARGS((char *path));
+void mch_write __ARGS((char_u *s, int len));
+int mch_inchar __ARGS((char_u *buf, int maxlen, long wtime, int tb_change_cnt));
+int mch_char_avail __ARGS((void));
+long_u mch_total_mem __ARGS((int special));
+void mch_delay __ARGS((long msec, int ignoreinput));
+int mch_stackcheck __ARGS((char *p));
+void mch_startjmp __ARGS((void));
+void mch_endjmp __ARGS((void));
+void mch_didjmp __ARGS((void));
+void mch_suspend __ARGS((void));
+void mch_init __ARGS((void));
+void reset_signals __ARGS((void));
+int vim_handle_signal __ARGS((int sig));
+int mch_check_win __ARGS((int argc, char **argv));
+int mch_input_isatty __ARGS((void));
+int mch_can_restore_title __ARGS((void));
+int mch_can_restore_icon __ARGS((void));
+void mch_settitle __ARGS((char_u *title, char_u *icon));
+void mch_restore_title __ARGS((int which));
+int vim_is_xterm __ARGS((char_u *name));
+int use_xterm_like_mouse __ARGS((char_u *name));
+int use_xterm_mouse __ARGS((void));
+int vim_is_iris __ARGS((char_u *name));
+int vim_is_vt300 __ARGS((char_u *name));
+int vim_is_fastterm __ARGS((char_u *name));
+int mch_get_user_name __ARGS((char_u *s, int len));
+int mch_get_uname __ARGS((uid_t uid, char_u *s, int len));
+void mch_get_host_name __ARGS((char_u *s, int len));
+long mch_get_pid __ARGS((void));
+int mch_dirname __ARGS((char_u *buf, int len));
+void slash_adjust __ARGS((char_u *p));
+int mch_FullName __ARGS((char_u *fname, char_u *buf, int len, int force));
+int mch_isFullName __ARGS((char_u *fname));
+void fname_case __ARGS((char_u *name, int len));
+long mch_getperm __ARGS((char_u *name));
+int mch_setperm __ARGS((char_u *name, long perm));
+void mch_copy_sec __ARGS((char_u *from_file, char_u *to_file));
+vim_acl_T mch_get_acl __ARGS((char_u *fname));
+void mch_set_acl __ARGS((char_u *fname, vim_acl_T aclent));
+void mch_free_acl __ARGS((vim_acl_T aclent));
+void mch_hide __ARGS((char_u *name));
+int mch_isdir __ARGS((char_u *name));
+int mch_can_exe __ARGS((char_u *name));
+int mch_nodetype __ARGS((char_u *name));
+void mch_early_init __ARGS((void));
+void mch_free_mem __ARGS((void));
+void mch_exit __ARGS((int r));
+void mch_settmode __ARGS((int tmode));
+void get_stty __ARGS((void));
+void mch_setmouse __ARGS((int on));
+void check_mouse_termcode __ARGS((void));
+int mch_screenmode __ARGS((char_u *arg));
+int mch_get_shellsize __ARGS((void));
+void mch_set_shellsize __ARGS((void));
+void mch_new_shellsize __ARGS((void));
+int mch_call_shell __ARGS((char_u *cmd, int options));
+void mch_breakcheck __ARGS((void));
+int mch_expandpath __ARGS((garray_T *gap, char_u *path, int flags));
+int mch_expand_wildcards __ARGS((int num_pat, char_u **pat, int *num_file,
+ char_u ***file,
+ int flags));
+int mch_has_exp_wildcard __ARGS((char_u *p));
+int mch_has_wildcard __ARGS((char_u *p));
+int mch_libcall __ARGS((char_u *libname, char_u *funcname, char_u *argstring,
+ int argint, char_u **string_result,
+ int *number_result));
+void setup_term_clip __ARGS((void));
+void start_xterm_trace __ARGS((int button));
+void stop_xterm_trace __ARGS((void));
+void clear_xterm_clip __ARGS((void));
+int clip_xterm_own_selection __ARGS((VimClipboard *cbd));
+void clip_xterm_lose_selection __ARGS((VimClipboard *cbd));
+void clip_xterm_request_selection __ARGS((VimClipboard *cbd));
+void clip_xterm_set_selection __ARGS((VimClipboard *cbd));
+int xsmp_handle_requests __ARGS((void));
+void xsmp_init __ARGS((void));
+void xsmp_close __ARGS((void));
+/* vim: set ft=c : */
diff --git a/src/proto/popupmnu.pro b/src/proto/popupmnu.pro
new file mode 100644
index 0000000000..74a53e2f0e
--- /dev/null
+++ b/src/proto/popupmnu.pro
@@ -0,0 +1,8 @@
+/* popupmnu.c */
+void pum_display __ARGS((pumitem_T *array, int size, int selected));
+void pum_redraw __ARGS((void));
+void pum_undisplay __ARGS((void));
+void pum_clear __ARGS((void));
+int pum_visible __ARGS((void));
+int pum_get_height __ARGS((void));
+/* vim: set ft=c : */
diff --git a/src/proto/quickfix.pro b/src/proto/quickfix.pro
new file mode 100644
index 0000000000..98d64a7a3f
--- /dev/null
+++ b/src/proto/quickfix.pro
@@ -0,0 +1,33 @@
+/* quickfix.c */
+int qf_init __ARGS((win_T *wp, char_u *efile, char_u *errorformat, int newlist,
+ char_u *qf_title));
+void qf_free_all __ARGS((win_T *wp));
+void copy_loclist __ARGS((win_T *from, win_T *to));
+void qf_jump __ARGS((qf_info_T *qi, int dir, int errornr, int forceit));
+void qf_list __ARGS((exarg_T *eap));
+void qf_age __ARGS((exarg_T *eap));
+void qf_mark_adjust __ARGS((win_T *wp, linenr_T line1, linenr_T line2,
+ long amount,
+ long amount_after));
+void ex_cwindow __ARGS((exarg_T *eap));
+void ex_cclose __ARGS((exarg_T *eap));
+void ex_copen __ARGS((exarg_T *eap));
+linenr_T qf_current_entry __ARGS((win_T *wp));
+int bt_quickfix __ARGS((buf_T *buf));
+int bt_nofile __ARGS((buf_T *buf));
+int bt_dontwrite __ARGS((buf_T *buf));
+int bt_dontwrite_msg __ARGS((buf_T *buf));
+int buf_hide __ARGS((buf_T *buf));
+int grep_internal __ARGS((cmdidx_T cmdidx));
+void ex_make __ARGS((exarg_T *eap));
+void ex_cc __ARGS((exarg_T *eap));
+void ex_cnext __ARGS((exarg_T *eap));
+void ex_cfile __ARGS((exarg_T *eap));
+void ex_vimgrep __ARGS((exarg_T *eap));
+char_u *skip_vimgrep_pat __ARGS((char_u *p, char_u **s, int *flags));
+int get_errorlist __ARGS((win_T *wp, list_T *list));
+int set_errorlist __ARGS((win_T *wp, list_T *list, int action, char_u *title));
+void ex_cbuffer __ARGS((exarg_T *eap));
+void ex_cexpr __ARGS((exarg_T *eap));
+void ex_helpgrep __ARGS((exarg_T *eap));
+/* vim: set ft=c : */
diff --git a/src/proto/regexp.pro b/src/proto/regexp.pro
new file mode 100644
index 0000000000..b77a8e8ea9
--- /dev/null
+++ b/src/proto/regexp.pro
@@ -0,0 +1,24 @@
+/* regexp.c */
+int re_multiline __ARGS((regprog_T *prog));
+int re_lookbehind __ARGS((regprog_T *prog));
+char_u *skip_regexp __ARGS((char_u *startp, int dirc, int magic, char_u **newp));
+int vim_regcomp_had_eol __ARGS((void));
+void free_regexp_stuff __ARGS((void));
+reg_extmatch_T *ref_extmatch __ARGS((reg_extmatch_T *em));
+void unref_extmatch __ARGS((reg_extmatch_T *em));
+char_u *regtilde __ARGS((char_u *source, int magic));
+int vim_regsub __ARGS((regmatch_T *rmp, char_u *source, char_u *dest, int copy,
+ int magic,
+ int backslash));
+int vim_regsub_multi __ARGS((regmmatch_T *rmp, linenr_T lnum, char_u *source,
+ char_u *dest, int copy, int magic,
+ int backslash));
+char_u *reg_submatch __ARGS((int no));
+regprog_T *vim_regcomp __ARGS((char_u *expr_arg, int re_flags));
+void vim_regfree __ARGS((regprog_T *prog));
+int vim_regexec __ARGS((regmatch_T *rmp, char_u *line, colnr_T col));
+int vim_regexec_nl __ARGS((regmatch_T *rmp, char_u *line, colnr_T col));
+long vim_regexec_multi __ARGS((regmmatch_T *rmp, win_T *win, buf_T *buf,
+ linenr_T lnum, colnr_T col,
+ proftime_T *tm));
+/* vim: set ft=c : */
diff --git a/src/proto/screen.pro b/src/proto/screen.pro
new file mode 100644
index 0000000000..53a909e242
--- /dev/null
+++ b/src/proto/screen.pro
@@ -0,0 +1,66 @@
+/* screen.c */
+void redraw_later __ARGS((int type));
+void redraw_win_later __ARGS((win_T *wp, int type));
+void redraw_later_clear __ARGS((void));
+void redraw_all_later __ARGS((int type));
+void redraw_curbuf_later __ARGS((int type));
+void redraw_buf_later __ARGS((buf_T *buf, int type));
+int redraw_asap __ARGS((int type));
+void redrawWinline __ARGS((linenr_T lnum, int invalid));
+void update_curbuf __ARGS((int type));
+void update_screen __ARGS((int type));
+int conceal_cursor_line __ARGS((win_T *wp));
+void conceal_check_cursur_line __ARGS((void));
+void update_single_line __ARGS((win_T *wp, linenr_T lnum));
+void update_debug_sign __ARGS((buf_T *buf, linenr_T lnum));
+void updateWindow __ARGS((win_T *wp));
+void rl_mirror __ARGS((char_u *str));
+void status_redraw_all __ARGS((void));
+void status_redraw_curbuf __ARGS((void));
+void redraw_statuslines __ARGS((void));
+void win_redraw_last_status __ARGS((frame_T *frp));
+void win_redr_status_matches __ARGS((expand_T *xp, int num_matches, char_u *
+ *matches, int match,
+ int showtail));
+void win_redr_status __ARGS((win_T *wp));
+int stl_connected __ARGS((win_T *wp));
+int get_keymap_str __ARGS((win_T *wp, char_u *buf, int len));
+void screen_putchar __ARGS((int c, int row, int col, int attr));
+void screen_getbytes __ARGS((int row, int col, char_u *bytes, int *attrp));
+void screen_puts __ARGS((char_u *text, int row, int col, int attr));
+void screen_puts_len __ARGS((char_u *text, int len, int row, int col, int attr));
+void screen_stop_highlight __ARGS((void));
+void reset_cterm_colors __ARGS((void));
+void screen_draw_rectangle __ARGS((int row, int col, int height, int width,
+ int invert));
+void screen_fill __ARGS((int start_row, int end_row, int start_col, int end_col,
+ int c1, int c2,
+ int attr));
+void check_for_delay __ARGS((int check_msg_scroll));
+int screen_valid __ARGS((int doclear));
+void screenalloc __ARGS((int doclear));
+void free_screenlines __ARGS((void));
+void screenclear __ARGS((void));
+int can_clear __ARGS((char_u *p));
+void screen_start __ARGS((void));
+void windgoto __ARGS((int row, int col));
+void setcursor __ARGS((void));
+int win_ins_lines __ARGS((win_T *wp, int row, int line_count, int invalid,
+ int mayclear));
+int win_del_lines __ARGS((win_T *wp, int row, int line_count, int invalid,
+ int mayclear));
+int screen_ins_lines __ARGS((int off, int row, int line_count, int end,
+ win_T *wp));
+int screen_del_lines __ARGS((int off, int row, int line_count, int end,
+ int force,
+ win_T *wp));
+int showmode __ARGS((void));
+void unshowmode __ARGS((int force));
+void get_trans_bufname __ARGS((buf_T *buf));
+int redrawing __ARGS((void));
+int messaging __ARGS((void));
+void showruler __ARGS((int always));
+int number_width __ARGS((win_T *wp));
+int screen_screencol __ARGS((void));
+int screen_screenrow __ARGS((void));
+/* vim: set ft=c : */
diff --git a/src/proto/search.pro b/src/proto/search.pro
new file mode 100644
index 0000000000..9c3c520c9f
--- /dev/null
+++ b/src/proto/search.pro
@@ -0,0 +1,49 @@
+/* search.c */
+int search_regcomp __ARGS((char_u *pat, int pat_save, int pat_use, int options,
+ regmmatch_T *regmatch));
+char_u *get_search_pat __ARGS((void));
+char_u *reverse_text __ARGS((char_u *s));
+void save_search_patterns __ARGS((void));
+void restore_search_patterns __ARGS((void));
+void free_search_patterns __ARGS((void));
+int ignorecase __ARGS((char_u *pat));
+int pat_has_uppercase __ARGS((char_u *pat));
+char_u *last_search_pat __ARGS((void));
+void reset_search_dir __ARGS((void));
+void set_last_search_pat __ARGS((char_u *s, int idx, int magic, int setlast));
+void last_pat_prog __ARGS((regmmatch_T *regmatch));
+int searchit __ARGS((win_T *win, buf_T *buf, pos_T *pos, int dir, char_u *pat,
+ long count, int options, int pat_use, linenr_T stop_lnum,
+ proftime_T *tm));
+void set_search_direction __ARGS((int cdir));
+int do_search __ARGS((oparg_T *oap, int dirc, char_u *pat, long count,
+ int options,
+ proftime_T *tm));
+int search_for_exact_line __ARGS((buf_T *buf, pos_T *pos, int dir, char_u *pat));
+int searchc __ARGS((cmdarg_T *cap, int t_cmd));
+pos_T *findmatch __ARGS((oparg_T *oap, int initc));
+pos_T *findmatchlimit __ARGS((oparg_T *oap, int initc, int flags, int maxtravel));
+void showmatch __ARGS((int c));
+int findsent __ARGS((int dir, long count));
+int findpar __ARGS((int *pincl, int dir, long count, int what, int both));
+int startPS __ARGS((linenr_T lnum, int para, int both));
+int fwd_word __ARGS((long count, int bigword, int eol));
+int bck_word __ARGS((long count, int bigword, int stop));
+int end_word __ARGS((long count, int bigword, int stop, int empty));
+int bckend_word __ARGS((long count, int bigword, int eol));
+int current_word __ARGS((oparg_T *oap, long count, int include, int bigword));
+int current_sent __ARGS((oparg_T *oap, long count, int include));
+int current_block __ARGS((oparg_T *oap, long count, int include, int what,
+ int other));
+int current_tagblock __ARGS((oparg_T *oap, long count_arg, int include));
+int current_par __ARGS((oparg_T *oap, long count, int include, int type));
+int current_quote __ARGS((oparg_T *oap, long count, int include, int quotechar));
+int current_search __ARGS((long count, int forward));
+int linewhite __ARGS((linenr_T lnum));
+void find_pattern_in_path __ARGS((char_u *ptr, int dir, int len, int whole,
+ int skip_comments, int type, long count,
+ int action, linenr_T start_lnum,
+ linenr_T end_lnum));
+int read_viminfo_search_pattern __ARGS((vir_T *virp, int force));
+void write_viminfo_search_pattern __ARGS((FILE *fp));
+/* vim: set ft=c : */
diff --git a/src/proto/sha256.pro b/src/proto/sha256.pro
new file mode 100644
index 0000000000..dca9e37998
--- /dev/null
+++ b/src/proto/sha256.pro
@@ -0,0 +1,12 @@
+/* sha256.c */
+void sha256_start __ARGS((context_sha256_T *ctx));
+void sha256_update __ARGS((context_sha256_T *ctx, char_u *input,
+ UINT32_T length));
+void sha256_finish __ARGS((context_sha256_T *ctx, char_u digest[32]));
+char_u *sha256_bytes __ARGS((char_u *buf, int buf_len, char_u *salt,
+ int salt_len));
+char_u *sha256_key __ARGS((char_u *buf, char_u *salt, int salt_len));
+int sha256_self_test __ARGS((void));
+void sha2_seed __ARGS((char_u *header, int header_len, char_u *salt,
+ int salt_len));
+/* vim: set ft=c : */
diff --git a/src/proto/spell.pro b/src/proto/spell.pro
new file mode 100644
index 0000000000..cba277509e
--- /dev/null
+++ b/src/proto/spell.pro
@@ -0,0 +1,30 @@
+/* spell.c */
+int spell_check __ARGS((win_T *wp, char_u *ptr, hlf_T *attrp, int *capcol,
+ int docount));
+int spell_move_to __ARGS((win_T *wp, int dir, int allwords, int curline,
+ hlf_T *attrp));
+void spell_cat_line __ARGS((char_u *buf, char_u *line, int maxlen));
+char_u *did_set_spelllang __ARGS((win_T *wp));
+void spell_delete_wordlist __ARGS((void));
+void spell_free_all __ARGS((void));
+void spell_reload __ARGS((void));
+int spell_check_msm __ARGS((void));
+void ex_mkspell __ARGS((exarg_T *eap));
+void ex_spell __ARGS((exarg_T *eap));
+void spell_add_word __ARGS((char_u *word, int len, int bad, int idx, int undo));
+void init_spell_chartab __ARGS((void));
+int spell_check_sps __ARGS((void));
+void spell_suggest __ARGS((int count));
+void ex_spellrepall __ARGS((exarg_T *eap));
+void spell_suggest_list __ARGS((garray_T *gap, char_u *word, int maxcount,
+ int need_cap,
+ int interactive));
+char_u *eval_soundfold __ARGS((char_u *word));
+void ex_spellinfo __ARGS((exarg_T *eap));
+void ex_spelldump __ARGS((exarg_T *eap));
+void spell_dump_compl __ARGS((char_u *pat, int ic, int *dir, int dumpflags_arg));
+char_u *spell_to_word_end __ARGS((char_u *start, win_T *win));
+int spell_word_start __ARGS((int startcol));
+void spell_expand_check_cap __ARGS((colnr_T col));
+int expand_spelling __ARGS((linenr_T lnum, char_u *pat, char_u ***matchp));
+/* vim: set ft=c : */
diff --git a/src/proto/syntax.pro b/src/proto/syntax.pro
new file mode 100644
index 0000000000..0d5f23910f
--- /dev/null
+++ b/src/proto/syntax.pro
@@ -0,0 +1,58 @@
+/* syntax.c */
+void syntax_start __ARGS((win_T *wp, linenr_T lnum));
+void syn_stack_free_all __ARGS((synblock_T *block));
+void syn_stack_apply_changes __ARGS((buf_T *buf));
+void syntax_end_parsing __ARGS((linenr_T lnum));
+int syntax_check_changed __ARGS((linenr_T lnum));
+int get_syntax_attr __ARGS((colnr_T col, int *can_spell, int keep_state));
+void syntax_clear __ARGS((synblock_T *block));
+void reset_synblock __ARGS((win_T *wp));
+void ex_syntax __ARGS((exarg_T *eap));
+void ex_ownsyntax __ARGS((exarg_T *eap));
+int syntax_present __ARGS((win_T *win));
+void reset_expand_highlight __ARGS((void));
+void set_context_in_echohl_cmd __ARGS((expand_T *xp, char_u *arg));
+void set_context_in_syntax_cmd __ARGS((expand_T *xp, char_u *arg));
+char_u *get_syntax_name __ARGS((expand_T *xp, int idx));
+int syn_get_id __ARGS((win_T *wp, long lnum, colnr_T col, int trans,
+ int *spellp,
+ int keep_state));
+int get_syntax_info __ARGS((int *seqnrp));
+int syn_get_sub_char __ARGS((void));
+int syn_get_stack_item __ARGS((int i));
+int syn_get_foldlevel __ARGS((win_T *wp, long lnum));
+void ex_syntime __ARGS((exarg_T *eap));
+char_u *get_syntime_arg __ARGS((expand_T *xp, int idx));
+void init_highlight __ARGS((int both, int reset));
+int load_colors __ARGS((char_u *name));
+void do_highlight __ARGS((char_u *line, int forceit, int init));
+void free_highlight __ARGS((void));
+void restore_cterm_colors __ARGS((void));
+void set_normal_colors __ARGS((void));
+char_u *hl_get_font_name __ARGS((void));
+void hl_set_font_name __ARGS((char_u *font_name));
+void hl_set_bg_color_name __ARGS((char_u *name));
+void hl_set_fg_color_name __ARGS((char_u *name));
+void clear_hl_tables __ARGS((void));
+int hl_combine_attr __ARGS((int char_attr, int prim_attr));
+attrentry_T *syn_gui_attr2entry __ARGS((int attr));
+int syn_attr2attr __ARGS((int attr));
+attrentry_T *syn_term_attr2entry __ARGS((int attr));
+attrentry_T *syn_cterm_attr2entry __ARGS((int attr));
+char_u *highlight_has_attr __ARGS((int id, int flag, int modec));
+char_u *highlight_color __ARGS((int id, char_u *what, int modec));
+long_u highlight_gui_color_rgb __ARGS((int id, int fg));
+int syn_name2id __ARGS((char_u *name));
+int highlight_exists __ARGS((char_u *name));
+char_u *syn_id2name __ARGS((int id));
+int syn_namen2id __ARGS((char_u *linep, int len));
+int syn_check_group __ARGS((char_u *pp, int len));
+int syn_id2attr __ARGS((int hl_id));
+int syn_id2colors __ARGS((int hl_id, guicolor_T *fgp, guicolor_T *bgp));
+int syn_get_final_id __ARGS((int hl_id));
+void highlight_gui_started __ARGS((void));
+int highlight_changed __ARGS((void));
+void set_context_in_highlight_cmd __ARGS((expand_T *xp, char_u *arg));
+char_u *get_highlight_name __ARGS((expand_T *xp, int idx));
+void free_highlight_fonts __ARGS((void));
+/* vim: set ft=c : */
diff --git a/src/proto/tag.pro b/src/proto/tag.pro
new file mode 100644
index 0000000000..fedbc93745
--- /dev/null
+++ b/src/proto/tag.pro
@@ -0,0 +1,15 @@
+/* tag.c */
+int do_tag __ARGS((char_u *tag, int type, int count, int forceit, int verbose));
+void tag_freematch __ARGS((void));
+void do_tags __ARGS((exarg_T *eap));
+int find_tags __ARGS((char_u *pat, int *num_matches, char_u ***matchesp,
+ int flags, int mincount,
+ char_u *buf_ffname));
+void free_tag_stuff __ARGS((void));
+int get_tagfname __ARGS((tagname_T *tnp, int first, char_u *buf));
+void tagname_free __ARGS((tagname_T *tnp));
+void simplify_filename __ARGS((char_u *filename));
+int expand_tags __ARGS((int tagnames, char_u *pat, int *num_file,
+ char_u ***file));
+int get_tags __ARGS((list_T *list, char_u *pat));
+/* vim: set ft=c : */
diff --git a/src/proto/term.pro b/src/proto/term.pro
new file mode 100644
index 0000000000..9a348c0a72
--- /dev/null
+++ b/src/proto/term.pro
@@ -0,0 +1,65 @@
+/* term.c */
+int set_termname __ARGS((char_u *term));
+void set_mouse_termcode __ARGS((int n, char_u *s));
+void del_mouse_termcode __ARGS((int n));
+void getlinecol __ARGS((long *cp, long *rp));
+int add_termcap_entry __ARGS((char_u *name, int force));
+int term_is_8bit __ARGS((char_u *name));
+int term_is_gui __ARGS((char_u *name));
+char_u *tltoa __ARGS((unsigned long i));
+void termcapinit __ARGS((char_u *name));
+void out_flush __ARGS((void));
+void out_flush_check __ARGS((void));
+void out_trash __ARGS((void));
+void out_char __ARGS((unsigned c));
+void out_str_nf __ARGS((char_u *s));
+void out_str __ARGS((char_u *s));
+void term_windgoto __ARGS((int row, int col));
+void term_cursor_right __ARGS((int i));
+void term_append_lines __ARGS((int line_count));
+void term_delete_lines __ARGS((int line_count));
+void term_set_winpos __ARGS((int x, int y));
+void term_set_winsize __ARGS((int width, int height));
+void term_fg_color __ARGS((int n));
+void term_bg_color __ARGS((int n));
+void term_settitle __ARGS((char_u *title));
+void ttest __ARGS((int pairs));
+void add_long_to_buf __ARGS((long_u val, char_u *dst));
+void check_shellsize __ARGS((void));
+void limit_screen_size __ARGS((void));
+void win_new_shellsize __ARGS((void));
+void shell_resized __ARGS((void));
+void shell_resized_check __ARGS((void));
+void set_shellsize __ARGS((int width, int height, int mustset));
+void settmode __ARGS((int tmode));
+void starttermcap __ARGS((void));
+void stoptermcap __ARGS((void));
+void may_req_termresponse __ARGS((void));
+void may_req_ambiguous_char_width __ARGS((void));
+int swapping_screen __ARGS((void));
+void setmouse __ARGS((void));
+int mouse_has __ARGS((int c));
+int mouse_model_popup __ARGS((void));
+void scroll_start __ARGS((void));
+void cursor_on __ARGS((void));
+void cursor_off __ARGS((void));
+void term_cursor_shape __ARGS((void));
+void scroll_region_set __ARGS((win_T *wp, int off));
+void scroll_region_reset __ARGS((void));
+void clear_termcodes __ARGS((void));
+void add_termcode __ARGS((char_u *name, char_u *string, int flags));
+char_u *find_termcode __ARGS((char_u *name));
+char_u *get_termcode __ARGS((int i));
+void del_termcode __ARGS((char_u *name));
+void set_mouse_topline __ARGS((win_T *wp));
+int check_termcode __ARGS((int max_offset, char_u *buf, int bufsize,
+ int *buflen));
+char_u *replace_termcodes __ARGS((char_u *from, char_u **bufp, int from_part,
+ int do_lt,
+ int special));
+int find_term_bykeys __ARGS((char_u *src));
+void show_termcodes __ARGS((void));
+int show_one_termcode __ARGS((char_u *name, char_u *code, int printit));
+char_u *translate_mapping __ARGS((char_u *str, int expmap));
+void update_tcap __ARGS((int attr));
+/* vim: set ft=c : */
diff --git a/src/proto/ui.pro b/src/proto/ui.pro
new file mode 100644
index 0000000000..2f37fb9dfe
--- /dev/null
+++ b/src/proto/ui.pro
@@ -0,0 +1,67 @@
+/* ui.c */
+void ui_write __ARGS((char_u *s, int len));
+void ui_inchar_undo __ARGS((char_u *s, int len));
+int ui_inchar __ARGS((char_u *buf, int maxlen, long wtime, int tb_change_cnt));
+int ui_char_avail __ARGS((void));
+void ui_delay __ARGS((long msec, int ignoreinput));
+void ui_suspend __ARGS((void));
+void suspend_shell __ARGS((void));
+int ui_get_shellsize __ARGS((void));
+void ui_set_shellsize __ARGS((int mustset));
+void ui_new_shellsize __ARGS((void));
+void ui_breakcheck __ARGS((void));
+void clip_init __ARGS((int can_use));
+void clip_update_selection __ARGS((VimClipboard *clip));
+void clip_own_selection __ARGS((VimClipboard *cbd));
+void clip_lose_selection __ARGS((VimClipboard *cbd));
+void clip_auto_select __ARGS((void));
+int clip_isautosel_star __ARGS((void));
+int clip_isautosel_plus __ARGS((void));
+void clip_modeless __ARGS((int button, int is_click, int is_drag));
+void clip_start_selection __ARGS((int col, int row, int repeated_click));
+void clip_process_selection __ARGS((int button, int col, int row,
+ int_u repeated_click));
+void clip_may_redraw_selection __ARGS((int row, int col, int len));
+void clip_clear_selection __ARGS((VimClipboard *cbd));
+void clip_may_clear_selection __ARGS((int row1, int row2));
+void clip_scroll_selection __ARGS((int rows));
+void clip_copy_modeless_selection __ARGS((int both));
+int clip_gen_own_selection __ARGS((VimClipboard *cbd));
+void clip_gen_lose_selection __ARGS((VimClipboard *cbd));
+void clip_gen_set_selection __ARGS((VimClipboard *cbd));
+void clip_gen_request_selection __ARGS((VimClipboard *cbd));
+int clip_gen_owner_exists __ARGS((VimClipboard *cbd));
+int vim_is_input_buf_full __ARGS((void));
+int vim_is_input_buf_empty __ARGS((void));
+int vim_free_in_input_buf __ARGS((void));
+int vim_used_in_input_buf __ARGS((void));
+char_u *get_input_buf __ARGS((void));
+void set_input_buf __ARGS((char_u *p));
+void add_to_input_buf __ARGS((char_u *s, int len));
+void add_to_input_buf_csi __ARGS((char_u *str, int len));
+void push_raw_key __ARGS((char_u *s, int len));
+void trash_input_buf __ARGS((void));
+int read_from_input_buf __ARGS((char_u *buf, long maxlen));
+void fill_input_buf __ARGS((int exit_on_error));
+void read_error_exit __ARGS((void));
+void ui_cursor_shape __ARGS((void));
+int check_col __ARGS((int col));
+int check_row __ARGS((int row));
+void open_app_context __ARGS((void));
+void x11_setup_atoms __ARGS((Display *dpy));
+void x11_setup_selection __ARGS((Widget w));
+void clip_x11_request_selection __ARGS((Widget myShell, Display *dpy,
+ VimClipboard *cbd));
+void clip_x11_lose_selection __ARGS((Widget myShell, VimClipboard *cbd));
+int clip_x11_own_selection __ARGS((Widget myShell, VimClipboard *cbd));
+void clip_x11_set_selection __ARGS((VimClipboard *cbd));
+int clip_x11_owner_exists __ARGS((VimClipboard *cbd));
+void yank_cut_buffer0 __ARGS((Display *dpy, VimClipboard *cbd));
+int jump_to_mouse __ARGS((int flags, int *inclusive, int which_button));
+int mouse_comp_pos __ARGS((win_T *win, int *rowp, int *colp, linenr_T *lnump));
+win_T *mouse_find_win __ARGS((int *rowp, int *colp));
+int get_fpos_of_mouse __ARGS((pos_T *mpos));
+int vcol2col __ARGS((win_T *wp, linenr_T lnum, int vcol));
+void ui_focus_change __ARGS((int in_focus));
+void im_save_status __ARGS((long *psave));
+/* vim: set ft=c : */
diff --git a/src/proto/undo.pro b/src/proto/undo.pro
new file mode 100644
index 0000000000..dfbb07ac26
--- /dev/null
+++ b/src/proto/undo.pro
@@ -0,0 +1,31 @@
+/* undo.c */
+int u_save_cursor __ARGS((void));
+int u_save __ARGS((linenr_T top, linenr_T bot));
+int u_savesub __ARGS((linenr_T lnum));
+int u_inssub __ARGS((linenr_T lnum));
+int u_savedel __ARGS((linenr_T lnum, long nlines));
+int undo_allowed __ARGS((void));
+int u_savecommon __ARGS((linenr_T top, linenr_T bot, linenr_T newbot,
+ int reload));
+void u_compute_hash __ARGS((char_u *hash));
+char_u *u_get_undo_file_name __ARGS((char_u *buf_ffname, int reading));
+void u_write_undo __ARGS((char_u *name, int forceit, buf_T *buf, char_u *hash));
+void u_read_undo __ARGS((char_u *name, char_u *hash, char_u *orig_name));
+void u_undo __ARGS((int count));
+void u_redo __ARGS((int count));
+void undo_time __ARGS((long step, int sec, int file, int absolute));
+void u_sync __ARGS((int force));
+void ex_undolist __ARGS((exarg_T *eap));
+void ex_undojoin __ARGS((exarg_T *eap));
+void u_unchanged __ARGS((buf_T *buf));
+void u_find_first_changed __ARGS((void));
+void u_update_save_nr __ARGS((buf_T *buf));
+void u_clearall __ARGS((buf_T *buf));
+void u_saveline __ARGS((linenr_T lnum));
+void u_clearline __ARGS((void));
+void u_undoline __ARGS((void));
+void u_blockfree __ARGS((buf_T *buf));
+int bufIsChanged __ARGS((buf_T *buf));
+int curbufIsChanged __ARGS((void));
+void u_eval_tree __ARGS((u_header_T *first_uhp, list_T *list));
+/* vim: set ft=c : */
diff --git a/src/proto/version.pro b/src/proto/version.pro
new file mode 100644
index 0000000000..e6fb78f069
--- /dev/null
+++ b/src/proto/version.pro
@@ -0,0 +1,10 @@
+/* version.c */
+void make_version __ARGS((void));
+int highest_patch __ARGS((void));
+int has_patch __ARGS((int n));
+void ex_version __ARGS((exarg_T *eap));
+void list_version __ARGS((void));
+void maybe_intro_message __ARGS((void));
+void intro_message __ARGS((int colon));
+void ex_intro __ARGS((exarg_T *eap));
+/* vim: set ft=c : */
diff --git a/src/proto/window.pro b/src/proto/window.pro
new file mode 100644
index 0000000000..bf82ca1982
--- /dev/null
+++ b/src/proto/window.pro
@@ -0,0 +1,93 @@
+/* window.c */
+void do_window __ARGS((int nchar, long Prenum, int xchar));
+int win_split __ARGS((int size, int flags));
+int win_split_ins __ARGS((int size, int flags, win_T *new_wp, int dir));
+int win_valid __ARGS((win_T *win));
+int win_count __ARGS((void));
+int make_windows __ARGS((int count, int vertical));
+void win_move_after __ARGS((win_T *win1, win_T *win2));
+void win_equal __ARGS((win_T *next_curwin, int current, int dir));
+void close_windows __ARGS((buf_T *buf, int keep_curwin));
+int one_window __ARGS((void));
+int win_close __ARGS((win_T *win, int free_buf));
+void win_close_othertab __ARGS((win_T *win, int free_buf, tabpage_T *tp));
+void win_free_all __ARGS((void));
+win_T *winframe_remove __ARGS((win_T *win, int *dirp, tabpage_T *tp));
+void close_others __ARGS((int message, int forceit));
+void curwin_init __ARGS((void));
+void win_init_empty __ARGS((win_T *wp));
+int win_alloc_first __ARGS((void));
+void win_alloc_aucmd_win __ARGS((void));
+void win_init_size __ARGS((void));
+void free_tabpage __ARGS((tabpage_T *tp));
+int win_new_tabpage __ARGS((int after));
+int may_open_tabpage __ARGS((void));
+int make_tabpages __ARGS((int maxcount));
+int valid_tabpage __ARGS((tabpage_T *tpc));
+tabpage_T *find_tabpage __ARGS((int n));
+int tabpage_index __ARGS((tabpage_T *ftp));
+void goto_tabpage __ARGS((int n));
+void goto_tabpage_tp __ARGS((tabpage_T *tp, int trigger_enter_autocmds,
+ int trigger_leave_autocmds));
+void goto_tabpage_win __ARGS((tabpage_T *tp, win_T *wp));
+void tabpage_move __ARGS((int nr));
+void win_goto __ARGS((win_T *wp));
+win_T *win_find_nr __ARGS((int winnr));
+tabpage_T *win_find_tabpage __ARGS((win_T *win));
+void win_enter __ARGS((win_T *wp, int undo_sync));
+win_T *buf_jump_open_win __ARGS((buf_T *buf));
+win_T *buf_jump_open_tab __ARGS((buf_T *buf));
+void win_append __ARGS((win_T *after, win_T *wp));
+void win_remove __ARGS((win_T *wp, tabpage_T *tp));
+int win_alloc_lines __ARGS((win_T *wp));
+void win_free_lsize __ARGS((win_T *wp));
+void shell_new_rows __ARGS((void));
+void shell_new_columns __ARGS((void));
+void win_size_save __ARGS((garray_T *gap));
+void win_size_restore __ARGS((garray_T *gap));
+int win_comp_pos __ARGS((void));
+void win_setheight __ARGS((int height));
+void win_setheight_win __ARGS((int height, win_T *win));
+void win_setwidth __ARGS((int width));
+void win_setwidth_win __ARGS((int width, win_T *wp));
+void win_setminheight __ARGS((void));
+void win_drag_status_line __ARGS((win_T *dragwin, int offset));
+void win_drag_vsep_line __ARGS((win_T *dragwin, int offset));
+void win_new_height __ARGS((win_T *wp, int height));
+void win_new_width __ARGS((win_T *wp, int width));
+void win_comp_scroll __ARGS((win_T *wp));
+void command_height __ARGS((void));
+void last_status __ARGS((int morewin));
+int tabline_height __ARGS((void));
+char_u *grab_file_name __ARGS((long count, linenr_T *file_lnum));
+char_u *file_name_at_cursor __ARGS((int options, long count,
+ linenr_T *file_lnum));
+char_u *file_name_in_line __ARGS((char_u *line, int col, int options,
+ long count, char_u *rel_fname,
+ linenr_T *file_lnum));
+char_u *find_file_name_in_path __ARGS((char_u *ptr, int len, int options,
+ long count,
+ char_u *rel_fname));
+int path_with_url __ARGS((char_u *fname));
+int vim_isAbsName __ARGS((char_u *name));
+int vim_FullName __ARGS((char_u *fname, char_u *buf, int len, int force));
+int min_rows __ARGS((void));
+int only_one_window __ARGS((void));
+void check_lnums __ARGS((int do_curwin));
+void make_snapshot __ARGS((int idx));
+void restore_snapshot __ARGS((int idx, int close_curwin));
+int switch_win __ARGS((win_T **save_curwin, tabpage_T **save_curtab, win_T *win,
+ tabpage_T *tp,
+ int no_display));
+void restore_win __ARGS((win_T *save_curwin, tabpage_T *save_curtab,
+ int no_display));
+void switch_buffer __ARGS((buf_T **save_curbuf, buf_T *buf));
+void restore_buffer __ARGS((buf_T *save_curbuf));
+int win_hasvertsplit __ARGS((void));
+int match_add __ARGS((win_T *wp, char_u *grp, char_u *pat, int prio, int id));
+int match_delete __ARGS((win_T *wp, int id, int perr));
+void clear_matches __ARGS((win_T *wp));
+matchitem_T *get_match __ARGS((win_T *wp, int id));
+int get_win_number __ARGS((win_T *wp, win_T *first_win));
+int get_tab_number __ARGS((tabpage_T *tp));
+/* vim: set ft=c : */
diff --git a/src/quickfix.c b/src/quickfix.c
new file mode 100644
index 0000000000..28f3a469f6
--- /dev/null
+++ b/src/quickfix.c
@@ -0,0 +1,3750 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * 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.
+ */
+
+/*
+ * quickfix.c: functions for quickfix mode, using a file with error messages
+ */
+
+#include "vim.h"
+
+
+struct dir_stack_T {
+ struct dir_stack_T *next;
+ char_u *dirname;
+};
+
+static struct dir_stack_T *dir_stack = NULL;
+
+/*
+ * For each error the next struct is allocated and linked in a list.
+ */
+typedef struct qfline_S qfline_T;
+struct qfline_S {
+ qfline_T *qf_next; /* pointer to next error in the list */
+ qfline_T *qf_prev; /* pointer to previous error in the list */
+ linenr_T qf_lnum; /* line number where the error occurred */
+ int qf_fnum; /* file number for the line */
+ int qf_col; /* column where the error occurred */
+ int qf_nr; /* error number */
+ char_u *qf_pattern; /* search pattern for the error */
+ char_u *qf_text; /* description of the error */
+ char_u qf_viscol; /* set to TRUE if qf_col is screen column */
+ char_u qf_cleared; /* set to TRUE if line has been deleted */
+ char_u qf_type; /* type of the error (mostly 'E'); 1 for
+ :helpgrep */
+ char_u qf_valid; /* valid error message detected */
+};
+
+/*
+ * There is a stack of error lists.
+ */
+#define LISTCOUNT 10
+
+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 */
+} qf_list_T;
+
+struct qf_info_S {
+ /*
+ * Count of references to this list. Used only for location lists.
+ * When a location list window reference this list, qf_refcount
+ * will be 2. Otherwise, qf_refcount will be 1. When qf_refcount
+ * reaches 0, the list is freed.
+ */
+ int qf_refcount;
+ int qf_listcount; /* current number of lists */
+ int qf_curlist; /* current error list */
+ qf_list_T qf_lists[LISTCOUNT];
+};
+
+static qf_info_T ql_info; /* global quickfix list */
+
+#define FMT_PATTERNS 10 /* maximum number of % recognized */
+
+/*
+ * Structure used to hold the info of one part of 'errorformat'
+ */
+typedef struct efm_S efm_T;
+struct efm_S {
+ regprog_T *prog; /* pre-formatted part of 'errorformat' */
+ efm_T *next; /* pointer to next (NULL if last) */
+ char_u addr[FMT_PATTERNS]; /* indices of used % patterns */
+ char_u prefix; /* prefix of this format line: */
+ /* 'D' enter directory */
+ /* 'X' leave directory */
+ /* 'A' start of multi-line message */
+ /* 'E' error message */
+ /* 'W' warning message */
+ /* 'I' informational message */
+ /* 'C' continuation line */
+ /* 'Z' end of multi-line message */
+ /* 'G' general, unspecific message */
+ /* 'P' push file (partial) message */
+ /* 'Q' pop/quit file (partial) message */
+ /* 'O' overread (partial) message */
+ char_u flags; /* additional flags given in prefix */
+ /* '-' do not include this line */
+ /* '+' include whole line in message */
+ int conthere; /* %> used */
+};
+
+static int qf_init_ext __ARGS((qf_info_T *qi, char_u *efile, buf_T *buf,
+ typval_T *tv, char_u *errorformat, int newlist,
+ linenr_T lnumfirst,
+ linenr_T lnumlast,
+ char_u *qf_title));
+static void qf_new_list __ARGS((qf_info_T *qi, char_u *qf_title));
+static void ll_free_all __ARGS((qf_info_T **pqi));
+static int qf_add_entry __ARGS((qf_info_T *qi, qfline_T **prevp, char_u *dir,
+ char_u *fname, int bufnum, char_u *mesg,
+ long lnum, int col, int vis_col,
+ char_u *pattern, int nr, int type,
+ int valid));
+static qf_info_T *ll_new_list __ARGS((void));
+static void qf_msg __ARGS((qf_info_T *qi));
+static void qf_free __ARGS((qf_info_T *qi, int idx));
+static char_u *qf_types __ARGS((int, int));
+static int qf_get_fnum __ARGS((char_u *, char_u *));
+static char_u *qf_push_dir __ARGS((char_u *, struct dir_stack_T **));
+static char_u *qf_pop_dir __ARGS((struct dir_stack_T **));
+static char_u *qf_guess_filepath __ARGS((char_u *));
+static void qf_fmt_text __ARGS((char_u *text, char_u *buf, int bufsize));
+static void qf_clean_dir_stack __ARGS((struct dir_stack_T **));
+static int qf_win_pos_update __ARGS((qf_info_T *qi, int old_qf_index));
+static int is_qf_win __ARGS((win_T *win, qf_info_T *qi));
+static win_T *qf_find_win __ARGS((qf_info_T *qi));
+static buf_T *qf_find_buf __ARGS((qf_info_T *qi));
+static void qf_update_buffer __ARGS((qf_info_T *qi));
+static void qf_set_title __ARGS((qf_info_T *qi));
+static void qf_fill_buffer __ARGS((qf_info_T *qi));
+static char_u *get_mef_name __ARGS((void));
+static void restore_start_dir __ARGS((char_u *dirname_start));
+static buf_T *load_dummy_buffer __ARGS((char_u *fname, char_u *dirname_start,
+ char_u *resulting_dir));
+static void wipe_dummy_buffer __ARGS((buf_T *buf, char_u *dirname_start));
+static void unload_dummy_buffer __ARGS((buf_T *buf, char_u *dirname_start));
+static qf_info_T *ll_get_or_alloc_list __ARGS((win_T *));
+
+/* Quickfix window check helper macro */
+#define IS_QF_WINDOW(wp) (bt_quickfix(wp->w_buffer) && wp->w_llist_ref == NULL)
+/* Location list window check helper macro */
+#define IS_LL_WINDOW(wp) (bt_quickfix(wp->w_buffer) && wp->w_llist_ref != NULL)
+/*
+ * Return location list for window 'wp'
+ * For location list window, return the referenced location list
+ */
+#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(wp, efile, errorformat, newlist, qf_title)
+win_T *wp;
+char_u *efile;
+char_u *errorformat;
+int newlist; /* TRUE: start a new error list */
+char_u *qf_title;
+{
+ qf_info_T *qi = &ql_info;
+
+ if (efile == NULL)
+ return FAIL;
+
+ if (wp != NULL) {
+ qi = ll_get_or_alloc_list(wp);
+ if (qi == NULL)
+ return FAIL;
+ }
+
+ return qf_init_ext(qi, efile, curbuf, NULL, errorformat, newlist,
+ (linenr_T)0, (linenr_T)0,
+ qf_title);
+}
+
+/*
+ * 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(qi, efile, buf, tv, errorformat, newlist, lnumfirst,
+ lnumlast,
+ qf_title)
+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;
+ char_u use_viscol = FALSE;
+ int type = 0;
+ int valid;
+ 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;
+ int multiline = FALSE;
+ int multiignore = FALSE;
+ int 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 = alloc(CMDBUFFSIZE + 1);
+ errmsg = alloc(CMDBUFFSIZE + 1);
+ pattern = alloc(CMDBUFFSIZE + 1);
+ if (namebuf == NULL || errmsg == NULL || pattern == NULL)
+ goto qf_init_end;
+
+ 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.
+ */
+ i = (FMT_PATTERNS * 3) + ((int)STRLEN(efm) << 2);
+ for (round = FMT_PATTERNS; round > 0; )
+ i += (int)STRLEN(fmt_pat[--round].pattern);
+#ifdef COLON_IN_FILENAME
+ i += 12; /* "%f" can become twelve chars longer */
+#else
+ i += 2; /* "%f" can become two chars longer */
+#endif
+ if ((fmtstr = alloc(i)) == NULL)
+ goto error2;
+
+ while (efm[0] != NUL) {
+ /*
+ * Allocate a new eformat structure and put it at the end of the list
+ */
+ fmt_ptr = (efm_T *)alloc_clear((unsigned)sizeof(efm_T));
+ if (fmt_ptr == NULL)
+ goto error2;
+ 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;
+
+ /*
+ * 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++ = '(';
+#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;
+ }
+#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;
+ }
+ } else {
+ 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) {
+ *ptr++ = *++efmp; /* could be ']' */
+ while (efmp < efm + len
+ && (*ptr++ = *++efmp) != ']')
+ /* skip */;
+ if (efmp == efm + len) {
+ EMSG(_("E374: Missing ] in format string"));
+ goto error2;
+ }
+ }
+ } 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;
+ }
+ } else {
+ sprintf((char *)errmsg,
+ _("E377: Invalid %%%c in format string"), *efmp);
+ EMSG(errmsg);
+ goto error2;
+ }
+ } 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 */
+ 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;
+
+ /* Always ignore case when looking for a matching error. */
+ regmatch.rm_ic = TRUE;
+
+ 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;
+ }
+
+ /*
+ * 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;
+
+ p = vim_strchr(p_str, '\n');
+ if (p)
+ len = (int)(p - p_str + 1);
+ else
+ len = (int)STRLEN(p_str);
+
+ if (len > CMDBUFFSIZE - 2)
+ vim_strncpy(IObuff, p_str, CMDBUFFSIZE - 2);
+ else
+ vim_strncpy(IObuff, p_str, len);
+
+ 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 */
+
+ if (!p_li) /* End of the list */
+ break;
+
+ len = (int)STRLEN(p_li->li_tv.vval.v_string);
+ if (len > CMDBUFFSIZE - 2)
+ len = CMDBUFFSIZE - 2;
+
+ vim_strncpy(IObuff, p_li->li_tv.vval.v_string, len);
+
+ p_li = p_li->li_next; /* next item */
+ }
+ } else {
+ /* Get the next line from the supplied buffer */
+ if (buflnum > lnumlast)
+ break;
+ vim_strncpy(IObuff, ml_get_buf(buf, buflnum++, FALSE),
+ CMDBUFFSIZE - 2);
+ }
+ } else if (fgets((char *)IObuff, CMDBUFFSIZE - 2, fd) == NULL)
+ break;
+
+ IObuff[CMDBUFFSIZE - 2] = NUL; /* for very long lines */
+ remove_bom(IObuff);
+
+ if ((efmp = vim_strrchr(IObuff, '\n')) != NULL)
+ *efmp = NUL;
+#ifdef USE_CRNL
+ if ((efmp = vim_strrchr(IObuff, '\r')) != NULL)
+ *efmp = 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;
+ }
+
+ /*
+ * Try to match each part of 'errorformat' until we find a complete
+ * match or no match.
+ */
+ 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)
+ 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;
+ if (vim_regexec(&regmatch, IObuff, (colnr_T)0)) {
+ if ((idx == 'C' || idx == 'Z') && !multiline)
+ continue;
+ if (vim_strchr((char_u *)"EWI", idx) != NULL)
+ type = idx;
+ else
+ 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 */
+ int c;
+
+ if (regmatch.startp[i] == NULL || regmatch.endp[i] == NULL)
+ continue;
+
+ /* Expand ~/file and $HOME/file to full path. */
+ 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
+ && mch_getperm(namebuf) == -1)
+ continue;
+ }
+ if ((i = (int)fmt_ptr->addr[1]) > 0) { /* %n */
+ if (regmatch.startp[i] == NULL)
+ continue;
+ enr = (int)atol((char *)regmatch.startp[i]);
+ }
+ if ((i = (int)fmt_ptr->addr[2]) > 0) { /* %l */
+ if (regmatch.startp[i] == NULL)
+ continue;
+ lnum = atol((char *)regmatch.startp[i]);
+ }
+ if ((i = (int)fmt_ptr->addr[3]) > 0) { /* %c */
+ if (regmatch.startp[i] == NULL)
+ continue;
+ col = (int)atol((char *)regmatch.startp[i]);
+ }
+ if ((i = (int)fmt_ptr->addr[4]) > 0) { /* %t */
+ if (regmatch.startp[i] == NULL)
+ continue;
+ type = *regmatch.startp[i];
+ }
+ 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]);
+ vim_strncpy(errmsg, regmatch.startp[i], len);
+ }
+ 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;
+ }
+ }
+ ++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;
+ }
+ 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;
+ }
+ 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);
+ }
+ 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 */
+ else if (vim_strchr((char_u *)"CZ", idx) != NULL) { /* continuation of multi-line msg */
+ if (qfprev == NULL)
+ goto error2;
+ if (*errmsg && !multiignore) {
+ len = (int)STRLEN(qfprev->qf_text);
+ if ((ptr = alloc((unsigned)(len + STRLEN(errmsg) + 2)))
+ == NULL)
+ goto error2;
+ STRCPY(ptr, qfprev->qf_text);
+ vim_free(qfprev->qf_text);
+ qfprev->qf_text = ptr;
+ *(ptr += len) = '\n';
+ STRCPY(++ptr, 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;
+ line_breakcheck();
+ continue;
+ } else if (vim_strchr((char_u *)"OPQ", idx) != NULL) {
+ /* global file names */
+ valid = FALSE;
+ if (*namebuf == NUL || mch_getperm(namebuf) >= 0) {
+ 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 (fmt_ptr->flags == '-') { /* generally exclude this line */
+ if (multiline)
+ multiignore = TRUE; /* also exclude continuation lines */
+ 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)
+ 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;
+ } 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;
+ }
+ /* return number of matches */
+ retval = qi->qf_lists[qi->qf_curlist].qf_count;
+ goto qf_init_ok;
+ }
+ 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);
+ vim_free(fmt_ptr);
+ }
+ qf_clean_dir_stack(&dir_stack);
+ qf_clean_dir_stack(&file_stack);
+qf_init_end:
+ vim_free(namebuf);
+ vim_free(errmsg);
+ vim_free(pattern);
+ vim_free(fmtstr);
+
+ qf_update_buffer(qi);
+
+ return retval;
+}
+
+/*
+ * Prepare for adding a new quickfix list.
+ */
+static void qf_new_list(qi, qf_title)
+qf_info_T *qi;
+char_u *qf_title;
+{
+ int i;
+
+ /*
+ * If the current entry is not the last entry, delete entries below
+ * the current entry. This makes it possible to browse in a tree-like
+ * way with ":grep'.
+ */
+ while (qi->qf_listcount > qi->qf_curlist + 1)
+ qf_free(qi, --qi->qf_listcount);
+
+ /*
+ * When the stack is full, remove to oldest entry
+ * Otherwise, add a new entry.
+ */
+ if (qi->qf_listcount == LISTCOUNT) {
+ qf_free(qi, 0);
+ for (i = 1; i < LISTCOUNT; ++i)
+ qi->qf_lists[i - 1] = qi->qf_lists[i];
+ qi->qf_curlist = LISTCOUNT - 1;
+ } else
+ qi->qf_curlist = qi->qf_listcount++;
+ vim_memset(&qi->qf_lists[qi->qf_curlist], 0, (size_t)(sizeof(qf_list_T)));
+ if (qf_title != NULL) {
+ char_u *p = alloc((int)STRLEN(qf_title) + 2);
+
+ qi->qf_lists[qi->qf_curlist].qf_title = p;
+ if (p != NULL)
+ sprintf((char *)p, ":%s", (char *)qf_title);
+ }
+}
+
+/*
+ * Free a location list
+ */
+static void ll_free_all(pqi)
+qf_info_T **pqi;
+{
+ int i;
+ qf_info_T *qi;
+
+ qi = *pqi;
+ if (qi == NULL)
+ return;
+ *pqi = NULL; /* Remove reference to this list */
+
+ qi->qf_refcount--;
+ if (qi->qf_refcount < 1) {
+ /* No references to this location list */
+ for (i = 0; i < qi->qf_listcount; ++i)
+ qf_free(qi, i);
+ vim_free(qi);
+ }
+}
+
+void qf_free_all(wp)
+win_T *wp;
+{
+ int i;
+ qf_info_T *qi = &ql_info;
+
+ if (wp != NULL) {
+ /* location list */
+ ll_free_all(&wp->w_llist);
+ ll_free_all(&wp->w_llist_ref);
+ } else
+ /* quickfix list */
+ for (i = 0; i < qi->qf_listcount; ++i)
+ qf_free(qi, i);
+}
+
+/*
+ * Add an entry to the end of the list of errors.
+ * Returns OK or FAIL.
+ */
+static int qf_add_entry(qi, prevp, dir, fname, bufnum, mesg, lnum, col, vis_col,
+ pattern,
+ nr, type,
+ valid)
+qf_info_T *qi; /* quickfix list */
+qfline_T **prevp; /* pointer to previously added entry or NULL */
+char_u *dir; /* optional directory name */
+char_u *fname; /* file name or NULL */
+int bufnum; /* buffer number or zero */
+char_u *mesg; /* message */
+long lnum; /* line number */
+int col; /* column */
+int vis_col; /* using visual column */
+char_u *pattern; /* search pattern */
+int nr; /* error number */
+int type; /* type character */
+int valid; /* valid entry */
+{
+ qfline_T *qfp;
+
+ if ((qfp = (qfline_T *)alloc((unsigned)sizeof(qfline_T))) == NULL)
+ return FAIL;
+ if (bufnum != 0)
+ qfp->qf_fnum = bufnum;
+ else
+ qfp->qf_fnum = qf_get_fnum(dir, fname);
+ if ((qfp->qf_text = vim_strsave(mesg)) == NULL) {
+ vim_free(qfp);
+ return FAIL;
+ }
+ qfp->qf_lnum = lnum;
+ qfp->qf_col = col;
+ qfp->qf_viscol = vis_col;
+ if (pattern == NULL || *pattern == NUL)
+ qfp->qf_pattern = NULL;
+ else if ((qfp->qf_pattern = vim_strsave(pattern)) == NULL) {
+ vim_free(qfp->qf_text);
+ vim_free(qfp);
+ return FAIL;
+ }
+ qfp->qf_nr = nr;
+ if (type != 1 && !vim_isprintc(type)) /* only printable chars allowed */
+ type = 0;
+ qfp->qf_type = 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 */
+ } else {
+ qfp->qf_prev = *prevp;
+ (*prevp)->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;
+ }
+
+ return OK;
+}
+
+/*
+ * Allocate a new location list
+ */
+static qf_info_T * ll_new_list() {
+ qf_info_T *qi;
+
+ qi = (qf_info_T *)alloc((unsigned)sizeof(qf_info_T));
+ if (qi != NULL) {
+ vim_memset(qi, 0, (size_t)(sizeof(qf_info_T)));
+ qi->qf_refcount++;
+ }
+
+ return qi;
+}
+
+/*
+ * Return the location list for window 'wp'.
+ * If not present, allocate a location list
+ */
+static qf_info_T * ll_get_or_alloc_list(wp)
+win_T *wp;
+{
+ if (IS_LL_WINDOW(wp))
+ /* For a location list window, use the referenced location list */
+ return wp->w_llist_ref;
+
+ /*
+ * For a non-location list window, w_llist_ref should not point to a
+ * location list.
+ */
+ ll_free_all(&wp->w_llist_ref);
+
+ if (wp->w_llist == NULL)
+ wp->w_llist = ll_new_list(); /* new location list */
+ return wp->w_llist;
+}
+
+/*
+ * Copy the location list from window "from" to window "to".
+ */
+void copy_loclist(from, to)
+win_T *from;
+win_T *to;
+{
+ qf_info_T *qi;
+ int idx;
+ int i;
+
+ /*
+ * When copying from a location list window, copy the referenced
+ * location list. For other windows, copy the location list for
+ * that window.
+ */
+ if (IS_LL_WINDOW(from))
+ qi = from->w_llist_ref;
+ else
+ qi = from->w_llist;
+
+ if (qi == NULL) /* no location list to copy */
+ return;
+
+ /* allocate a new location list */
+ if ((to->w_llist = ll_new_list()) == NULL)
+ return;
+
+ to->w_llist->qf_listcount = qi->qf_listcount;
+
+ /* Copy the location lists one at a time */
+ for (idx = 0; idx < qi->qf_listcount; idx++) {
+ qf_list_T *from_qfl;
+ qf_list_T *to_qfl;
+
+ to->w_llist->qf_curlist = idx;
+
+ from_qfl = &qi->qf_lists[idx];
+ to_qfl = &to->w_llist->qf_lists[idx];
+
+ /* Some of the fields are populated by qf_add_entry() */
+ to_qfl->qf_nonevalid = from_qfl->qf_nonevalid;
+ to_qfl->qf_count = 0;
+ to_qfl->qf_index = 0;
+ to_qfl->qf_start = 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_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) {
+ qf_free_all(to);
+ return;
+ }
+ /*
+ * qf_add_entry() will not set the qf_num field, as the
+ * 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 */
+ }
+ }
+
+ to_qfl->qf_index = from_qfl->qf_index; /* current index in the list */
+
+ /* When no valid entries are present in the list, qf_ptr points to
+ * the first item in the list */
+ if (to_qfl->qf_nonevalid) {
+ to_qfl->qf_ptr = to_qfl->qf_start;
+ to_qfl->qf_index = 1;
+ }
+ }
+
+ to->w_llist->qf_curlist = qi->qf_curlist; /* current list */
+}
+
+/*
+ * get buffer number for file "dir.name"
+ */
+static int qf_get_fnum(directory, fname)
+char_u *directory;
+char_u *fname;
+{
+ 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);
+#endif
+ if (directory != NULL && !vim_isAbsName(fname)
+ && (ptr = concat_fnames(directory, fname, TRUE)) != NULL) {
+ /*
+ * 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 (mch_getperm(ptr) < 0) {
+ vim_free(ptr);
+ directory = qf_guess_filepath(fname);
+ if (directory)
+ ptr = concat_fnames(directory, fname, TRUE);
+ else
+ ptr = vim_strsave(fname);
+ }
+ /* Use concatenated directory name and file name */
+ fnum = buflist_add(ptr, 0);
+ vim_free(ptr);
+ return fnum;
+ }
+ return buflist_add(fname, 0);
+ }
+}
+
+/*
+ * push dirbuf onto the directory stack and return pointer to actual dir or
+ * NULL on error
+ */
+static char_u * qf_push_dir(dirbuf, stackptr)
+char_u *dirbuf;
+struct dir_stack_T **stackptr;
+{
+ struct dir_stack_T *ds_new;
+ struct dir_stack_T *ds_ptr;
+
+ /* allocate new stack element and hook it in */
+ ds_new = (struct dir_stack_T *)alloc((unsigned)sizeof(struct dir_stack_T));
+ if (ds_new == NULL)
+ return NULL;
+
+ ds_new->next = *stackptr;
+ *stackptr = ds_new;
+
+ /* store directory on the stack */
+ if (vim_isAbsName(dirbuf)
+ || (*stackptr)->next == NULL
+ || (*stackptr && dir_stack != *stackptr))
+ (*stackptr)->dirname = vim_strsave(dirbuf);
+ else {
+ /* Okay we don't have an absolute path.
+ * dirbuf must be a subdir of one of the directories on the stack.
+ * Let's search...
+ */
+ ds_new = (*stackptr)->next;
+ (*stackptr)->dirname = NULL;
+ while (ds_new) {
+ vim_free((*stackptr)->dirname);
+ (*stackptr)->dirname = concat_fnames(ds_new->dirname, dirbuf,
+ TRUE);
+ if (mch_isdir((*stackptr)->dirname) == TRUE)
+ break;
+
+ ds_new = ds_new->next;
+ }
+
+ /* clean up all dirs we already left */
+ while ((*stackptr)->next != ds_new) {
+ ds_ptr = (*stackptr)->next;
+ (*stackptr)->next = (*stackptr)->next->next;
+ vim_free(ds_ptr->dirname);
+ vim_free(ds_ptr);
+ }
+
+ /* Nothing found -> it must be on top level */
+ if (ds_new == NULL) {
+ vim_free((*stackptr)->dirname);
+ (*stackptr)->dirname = vim_strsave(dirbuf);
+ }
+ }
+
+ if ((*stackptr)->dirname != NULL)
+ return (*stackptr)->dirname;
+ else {
+ ds_ptr = *stackptr;
+ *stackptr = (*stackptr)->next;
+ vim_free(ds_ptr);
+ return NULL;
+ }
+}
+
+
+/*
+ * pop dirbuf from the directory stack and return previous directory or NULL if
+ * stack is empty
+ */
+static char_u * qf_pop_dir(stackptr)
+struct dir_stack_T **stackptr;
+{
+ struct dir_stack_T *ds_ptr;
+
+ /* TODO: Should we check if dirbuf is the directory on top of the stack?
+ * What to do if it isn't? */
+
+ /* pop top element and free it */
+ if (*stackptr != NULL) {
+ ds_ptr = *stackptr;
+ *stackptr = (*stackptr)->next;
+ vim_free(ds_ptr->dirname);
+ vim_free(ds_ptr);
+ }
+
+ /* return NEW top element as current dir or NULL if stack is empty*/
+ return *stackptr ? (*stackptr)->dirname : NULL;
+}
+
+/*
+ * clean up directory stack
+ */
+static void qf_clean_dir_stack(stackptr)
+struct dir_stack_T **stackptr;
+{
+ struct dir_stack_T *ds_ptr;
+
+ while ((ds_ptr = *stackptr) != NULL) {
+ *stackptr = (*stackptr)->next;
+ vim_free(ds_ptr->dirname);
+ vim_free(ds_ptr);
+ }
+}
+
+/*
+ * Check in which directory of the directory stack the given file can be
+ * found.
+ * Returns a pointer to the directory name or NULL if not found
+ * Cleans up intermediate directory entries.
+ *
+ * TODO: How to solve the following problem?
+ * If we have the this directory tree:
+ * ./
+ * ./aa
+ * ./aa/bb
+ * ./bb
+ * ./bb/x.c
+ * and make says:
+ * making all in aa
+ * making all in bb
+ * x.c:9: Error
+ * 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(filename)
+char_u *filename;
+{
+ struct dir_stack_T *ds_ptr;
+ struct dir_stack_T *ds_tmp;
+ char_u *fullname;
+
+ /* no dirs on the stack - there's nothing we can do */
+ if (dir_stack == NULL)
+ return NULL;
+
+ ds_ptr = dir_stack->next;
+ fullname = NULL;
+ while (ds_ptr) {
+ vim_free(fullname);
+ fullname = concat_fnames(ds_ptr->dirname, filename, TRUE);
+
+ /* If concat_fnames failed, just go on. The worst thing that can happen
+ * is that we delete the entire stack.
+ */
+ if ((fullname != NULL) && (mch_getperm(fullname) >= 0))
+ break;
+
+ ds_ptr = ds_ptr->next;
+ }
+
+ vim_free(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;
+ vim_free(ds_tmp->dirname);
+ vim_free(ds_tmp);
+ }
+
+ return ds_ptr==NULL ? NULL : ds_ptr->dirname;
+
+}
+
+/*
+ * jump to a quickfix line
+ * if dir == FORWARD go "errornr" valid entries forward
+ * if dir == BACKWARD go "errornr" valid entries backward
+ * if dir == FORWARD_FILE go "errornr" valid entries files backward
+ * if dir == BACKWARD_FILE go "errornr" valid entries files backward
+ * else if "errornr" is zero, redisplay the same line
+ * else go to entry "errornr"
+ */
+void qf_jump(qi, dir, errornr, forceit)
+qf_info_T *qi;
+int dir;
+int errornr;
+int forceit;
+{
+ qf_info_T *ll_ref;
+ qfline_T *qf_ptr;
+ qfline_T *old_qf_ptr;
+ int qf_index;
+ int old_qf_fnum;
+ int old_qf_index;
+ int prev_index;
+ static char_u *e_no_more_items = (char_u *)N_("E553: No more items");
+ char_u *err = e_no_more_items;
+ linenr_T i;
+ buf_T *old_curbuf;
+ linenr_T old_lnum;
+ colnr_T screen_col;
+ colnr_T char_col;
+ char_u *line;
+ char_u *old_swb = p_swb;
+ unsigned old_swb_flags = swb_flags;
+ int opened_window = FALSE;
+ win_T *win;
+ win_T *altwin;
+ int flags;
+ win_T *oldwin = curwin;
+ int print_message = TRUE;
+ int len;
+ int old_KeyTyped = KeyTyped; /* getting file may reset it */
+ int ok = OK;
+ int usable_win;
+
+ if (qi == NULL)
+ qi = &ql_info;
+
+ if (qi->qf_curlist >= qi->qf_listcount
+ || qi->qf_lists[qi->qf_curlist].qf_count == 0) {
+ EMSG(_(e_quickfix));
+ return;
+ }
+
+ qf_ptr = qi->qf_lists[qi->qf_curlist].qf_ptr;
+ old_qf_ptr = qf_ptr;
+ qf_index = qi->qf_lists[qi->qf_curlist].qf_index;
+ old_qf_index = qf_index;
+ if (dir == FORWARD || dir == FORWARD_FILE) { /* next valid entry */
+ while (errornr--) {
+ old_qf_ptr = qf_ptr;
+ prev_index = qf_index;
+ old_qf_fnum = qf_ptr->qf_fnum;
+ do {
+ if (qf_index == qi->qf_lists[qi->qf_curlist].qf_count
+ || qf_ptr->qf_next == NULL) {
+ qf_ptr = old_qf_ptr;
+ qf_index = prev_index;
+ if (err != NULL) {
+ EMSG(_(err));
+ goto theend;
+ }
+ errornr = 0;
+ break;
+ }
+ ++qf_index;
+ qf_ptr = qf_ptr->qf_next;
+ } while ((!qi->qf_lists[qi->qf_curlist].qf_nonevalid
+ && !qf_ptr->qf_valid)
+ || (dir == FORWARD_FILE && qf_ptr->qf_fnum == old_qf_fnum));
+ err = NULL;
+ }
+ } else if (dir == BACKWARD || dir == BACKWARD_FILE) { /* prev. valid entry */
+ while (errornr--) {
+ old_qf_ptr = qf_ptr;
+ prev_index = qf_index;
+ old_qf_fnum = qf_ptr->qf_fnum;
+ do {
+ if (qf_index == 1 || qf_ptr->qf_prev == NULL) {
+ qf_ptr = old_qf_ptr;
+ qf_index = prev_index;
+ if (err != NULL) {
+ EMSG(_(err));
+ goto theend;
+ }
+ errornr = 0;
+ break;
+ }
+ --qf_index;
+ qf_ptr = qf_ptr->qf_prev;
+ } while ((!qi->qf_lists[qi->qf_curlist].qf_nonevalid
+ && !qf_ptr->qf_valid)
+ || (dir == BACKWARD_FILE && qf_ptr->qf_fnum == old_qf_fnum));
+ err = NULL;
+ }
+ } else if (errornr != 0) { /* go to specified number */
+ while (errornr < qf_index && qf_index > 1 && qf_ptr->qf_prev != NULL) {
+ --qf_index;
+ qf_ptr = qf_ptr->qf_prev;
+ }
+ while (errornr > qf_index && qf_index <
+ qi->qf_lists[qi->qf_curlist].qf_count
+ && qf_ptr->qf_next != NULL) {
+ ++qf_index;
+ qf_ptr = qf_ptr->qf_next;
+ }
+ }
+
+ qi->qf_lists[qi->qf_curlist].qf_index = qf_index;
+ if (qf_win_pos_update(qi, old_qf_index))
+ /* No need to print the error message if it's visible in the error
+ * window */
+ print_message = FALSE;
+
+ /*
+ * For ":helpgrep" find a help window or open one.
+ */
+ if (qf_ptr->qf_type == 1 && (!curwin->w_buffer->b_help || cmdmod.tab != 0)) {
+ win_T *wp;
+
+ 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)
+ break;
+ if (wp != NULL && wp->w_buffer->b_nwindows > 0)
+ win_enter(wp, TRUE);
+ else {
+ /*
+ * Split off help window; put it at far top if no position
+ * specified, the current window is vertically split and narrow.
+ */
+ flags = WSP_HELP;
+ if (cmdmod.split == 0 && curwin->w_width != Columns
+ && curwin->w_width < 80)
+ flags |= WSP_TOP;
+ if (qi != &ql_info)
+ flags |= WSP_NEWLOC; /* don't copy the location list */
+
+ if (win_split(0, flags) == FAIL)
+ goto theend;
+ opened_window = TRUE; /* close it when fail */
+
+ if (curwin->w_height < p_hh)
+ win_setheight((int)p_hh);
+
+ if (qi != &ql_info) { /* not a quickfix list */
+ /* The new window should use the supplied location list */
+ curwin->w_llist = qi;
+ qi->qf_refcount++;
+ }
+ }
+
+ if (!p_im)
+ restart_edit = 0; /* don't want insert mode in help file */
+ }
+
+ /*
+ * If currently in the quickfix window, find another window to show the
+ * file in.
+ */
+ if (bt_quickfix(curbuf) && !opened_window) {
+ win_T *usable_win_ptr = NULL;
+
+ /*
+ * If there is no file specified, we don't know where to go.
+ * But do advance, otherwise ":cn" gets stuck.
+ */
+ if (qf_ptr->qf_fnum == 0)
+ goto theend;
+
+ usable_win = 0;
+
+ ll_ref = curwin->w_llist_ref;
+ if (ll_ref != NULL) {
+ /* Find a window using the same location list that is not a
+ * quickfix window. */
+ FOR_ALL_WINDOWS(usable_win_ptr)
+ if (usable_win_ptr->w_llist == ll_ref
+ && usable_win_ptr->w_buffer->b_p_bt[0] != 'q') {
+ usable_win = 1;
+ break;
+ }
+ }
+
+ if (!usable_win) {
+ /* Locate a window showing a normal buffer */
+ FOR_ALL_WINDOWS(win)
+ if (win->w_buffer->b_p_bt[0] == NUL) {
+ usable_win = 1;
+ break;
+ }
+ }
+
+ /*
+ * If no usable window is found and 'switchbuf' contains "usetab"
+ * then search in other tabs.
+ */
+ if (!usable_win && (swb_flags & SWB_USETAB)) {
+ tabpage_T *tp;
+ win_T *wp;
+
+ FOR_ALL_TAB_WINDOWS(tp, wp)
+ {
+ if (wp->w_buffer->b_fnum == qf_ptr->qf_fnum) {
+ goto_tabpage_win(tp, wp);
+ usable_win = 1;
+ goto win_found;
+ }
+ }
+ }
+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) {
+ flags = WSP_ABOVE;
+ if (ll_ref != NULL)
+ flags |= WSP_NEWLOC;
+ if (win_split(0, flags) == FAIL)
+ goto failed; /* not enough room for window */
+ opened_window = TRUE; /* close it when fail */
+ p_swb = empty_option; /* don't split again */
+ swb_flags = 0;
+ RESET_BINDING(curwin);
+ if (ll_ref != NULL) {
+ /* The new window should use the location list from the
+ * location list window */
+ curwin->w_llist = ll_ref;
+ ll_ref->qf_refcount++;
+ }
+ } else {
+ if (curwin->w_llist_ref != NULL) {
+ /* In a location window */
+ win = usable_win_ptr;
+ if (win == NULL) {
+ /* Find the window showing the selected file */
+ FOR_ALL_WINDOWS(win)
+ if (win->w_buffer->b_fnum == qf_ptr->qf_fnum)
+ break;
+ if (win == NULL) {
+ /* Find a previous usable window */
+ win = curwin;
+ do {
+ if (win->w_buffer->b_p_bt[0] == NUL)
+ break;
+ if (win->w_prev == NULL)
+ win = lastwin; /* wrap around the top */
+ else
+ win = win->w_prev; /* go to previous window */
+ } while (win != curwin);
+ }
+ }
+ win_goto(win);
+
+ /* If the location list for the window is not set, then set it
+ * to the location list from the location window */
+ if (win->w_llist == NULL) {
+ win->w_llist = ll_ref;
+ ll_ref->qf_refcount++;
+ }
+ } else {
+
+ /*
+ * Try to find a window that shows the right buffer.
+ * Default to the window just above the quickfix buffer.
+ */
+ win = curwin;
+ altwin = NULL;
+ for (;; ) {
+ if (win->w_buffer->b_fnum == qf_ptr->qf_fnum)
+ break;
+ if (win->w_prev == NULL)
+ win = lastwin; /* wrap around the top */
+ else
+ win = win->w_prev; /* go to previous window */
+
+ if (IS_QF_WINDOW(win)) {
+ /* Didn't find it, go to the window before the quickfix
+ * window. */
+ if (altwin != NULL)
+ win = altwin;
+ else if (curwin->w_prev != NULL)
+ win = curwin->w_prev;
+ else
+ win = curwin->w_next;
+ break;
+ }
+
+ /* Remember a usable window. */
+ if (altwin == NULL && !win->w_p_pvw
+ && win->w_buffer->b_p_bt[0] == NUL)
+ altwin = win;
+ }
+
+ win_goto(win);
+ }
+ }
+ }
+
+ /*
+ * If there is a file name,
+ * read the wanted file if needed, and check autowrite etc.
+ */
+ old_curbuf = curbuf;
+ old_lnum = curwin->w_cursor.lnum;
+
+ if (qf_ptr->qf_fnum != 0) {
+ if (qf_ptr->qf_type == 1) {
+ /* Open help file (do_ecmd() will set b_help flag, readfile() will
+ * set b_p_ro flag). */
+ if (!can_abandon(curbuf, forceit)) {
+ EMSG(_(e_nowrtmsg));
+ ok = FALSE;
+ } else
+ ok = do_ecmd(qf_ptr->qf_fnum, NULL, NULL, NULL, (linenr_T)1,
+ ECMD_HIDE + ECMD_SET_HELP,
+ oldwin == curwin ? curwin : NULL);
+ } else
+ ok = buflist_getfile(qf_ptr->qf_fnum,
+ (linenr_T)1, GETF_SETMARK | GETF_SWITCH, forceit);
+ }
+
+ if (ok == OK) {
+ /* When not switched to another buffer, still need to set pc mark */
+ if (curbuf == old_curbuf)
+ setpcmark();
+
+ if (qf_ptr->qf_pattern == NULL) {
+ /*
+ * Go to line with error, unless qf_lnum is 0.
+ */
+ i = qf_ptr->qf_lnum;
+ if (i > 0) {
+ if (i > curbuf->b_ml.ml_line_count)
+ i = curbuf->b_ml.ml_line_count;
+ curwin->w_cursor.lnum = i;
+ }
+ if (qf_ptr->qf_col > 0) {
+ curwin->w_cursor.col = qf_ptr->qf_col - 1;
+ if (qf_ptr->qf_viscol == TRUE) {
+ /*
+ * Check each character from the beginning of the error
+ * line up to the error column. For each tab character
+ * found, reduce the error column value by the length of
+ * a tab character.
+ */
+ line = ml_get_curline();
+ screen_col = 0;
+ for (char_col = 0; char_col < curwin->w_cursor.col; ++char_col) {
+ if (*line == NUL)
+ break;
+ if (*line++ == '\t') {
+ curwin->w_cursor.col -= 7 - (screen_col % 8);
+ screen_col += 8 - (screen_col % 8);
+ } else
+ ++screen_col;
+ }
+ }
+ check_cursor();
+ } else
+ beginline(BL_WHITE | BL_FIX);
+ } else {
+ pos_T save_cursor;
+
+ /* Move the cursor to the first line in the buffer */
+ save_cursor = curwin->w_cursor;
+ curwin->w_cursor.lnum = 0;
+ if (!do_search(NULL, '/', qf_ptr->qf_pattern, (long)1,
+ SEARCH_KEEP, NULL))
+ curwin->w_cursor = save_cursor;
+ }
+
+ if ((fdo_flags & FDO_QUICKFIX) && old_KeyTyped)
+ foldOpenCursor();
+ if (print_message) {
+ /* Update the screen before showing the message, unless the screen
+ * scrolled up. */
+ if (!msg_scrolled)
+ update_topline_redraw();
+ sprintf((char *)IObuff, _("(%d of %d)%s%s: "), qf_index,
+ qi->qf_lists[qi->qf_curlist].qf_count,
+ qf_ptr->qf_cleared ? _(" (line deleted)") : "",
+ (char *)qf_types(qf_ptr->qf_type, qf_ptr->qf_nr));
+ /* Add the message, skipping leading whitespace and newlines. */
+ len = (int)STRLEN(IObuff);
+ qf_fmt_text(skipwhite(qf_ptr->qf_text), IObuff + len, IOSIZE - len);
+
+ /* Output the message. Overwrite to avoid scrolling when the 'O'
+ * flag is present in 'shortmess'; But when not jumping, print the
+ * whole message. */
+ i = msg_scroll;
+ if (curbuf == old_curbuf && curwin->w_cursor.lnum == old_lnum)
+ msg_scroll = TRUE;
+ else if (!msg_scrolled && shortmess(SHM_OVERALL))
+ msg_scroll = FALSE;
+ msg_attr_keep(IObuff, 0, TRUE);
+ msg_scroll = i;
+ }
+ } else {
+ if (opened_window)
+ win_close(curwin, TRUE); /* Close opened window */
+ if (qf_ptr->qf_fnum != 0) {
+ /*
+ * Couldn't open file, so put index back where it was. This could
+ * happen if the file was readonly and we changed something.
+ */
+failed:
+ qf_ptr = old_qf_ptr;
+ qf_index = old_qf_index;
+ }
+ }
+theend:
+ qi->qf_lists[qi->qf_curlist].qf_ptr = qf_ptr;
+ qi->qf_lists[qi->qf_curlist].qf_index = qf_index;
+ if (p_swb != old_swb && opened_window) {
+ /* Restore old 'switchbuf' value, but not when an autocommand or
+ * modeline has changed the value. */
+ if (p_swb == empty_option) {
+ p_swb = old_swb;
+ swb_flags = old_swb_flags;
+ } else
+ free_string_option(old_swb);
+ }
+}
+
+/*
+ * ":clist": list all errors
+ * ":llist": list all locations
+ */
+void qf_list(eap)
+exarg_T *eap;
+{
+ buf_T *buf;
+ char_u *fname;
+ qfline_T *qfp;
+ int i;
+ int idx1 = 1;
+ int idx2 = -1;
+ char_u *arg = eap->arg;
+ int all = eap->forceit; /* if not :cl!, only show
+ recognised errors */
+ qf_info_T *qi = &ql_info;
+
+ if (eap->cmdidx == CMD_llist) {
+ qi = GET_LOC_LIST(curwin);
+ if (qi == NULL) {
+ EMSG(_(e_loclist));
+ return;
+ }
+ }
+
+ if (qi->qf_curlist >= qi->qf_listcount
+ || qi->qf_lists[qi->qf_curlist].qf_count == 0) {
+ EMSG(_(e_quickfix));
+ return;
+ }
+ 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 (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) {
+ msg_putchar('\n');
+ if (got_int)
+ break;
+
+ fname = NULL;
+ if (qfp->qf_fnum != 0
+ && (buf = buflist_findnr(qfp->qf_fnum)) != NULL) {
+ fname = buf->b_fname;
+ if (qfp->qf_type == 1) /* :helpgrep */
+ fname = gettail(fname);
+ }
+ if (fname == NULL)
+ sprintf((char *)IObuff, "%2d", i);
+ else
+ 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)
+ IObuff[0] = NUL;
+ else if (qfp->qf_col == 0)
+ sprintf((char *)IObuff, ":%ld", qfp->qf_lnum);
+ else
+ sprintf((char *)IObuff, ":%ld col %d",
+ 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));
+ if (qfp->qf_pattern != NULL) {
+ qf_fmt_text(qfp->qf_pattern, IObuff, IOSIZE);
+ STRCAT(IObuff, ":");
+ msg_puts(IObuff);
+ }
+ msg_puts((char_u *)" ");
+
+ /* Remove newlines and leading whitespace from the text. For an
+ * unrecognized line keep the indent, the compiler may mark a word
+ * with ^^^^. */
+ qf_fmt_text((fname != NULL || qfp->qf_lnum != 0)
+ ? skipwhite(qfp->qf_text) : qfp->qf_text,
+ IObuff, IOSIZE);
+ msg_prt_line(IObuff, FALSE);
+ out_flush(); /* show one line at a time */
+ }
+
+ qfp = qfp->qf_next;
+ ++i;
+ ui_breakcheck();
+ }
+}
+
+/*
+ * Remove newlines and leading whitespace from an error message.
+ * Put the result in "buf[bufsize]".
+ */
+static void qf_fmt_text(text, buf, bufsize)
+char_u *text;
+char_u *buf;
+int bufsize;
+{
+ int i;
+ char_u *p = text;
+
+ for (i = 0; *p != NUL && i < bufsize - 1; ++i) {
+ if (*p == '\n') {
+ buf[i] = ' ';
+ while (*++p != NUL)
+ if (!vim_iswhite(*p) && *p != '\n')
+ break;
+ } else
+ buf[i] = *p++;
+ }
+ buf[i] = NUL;
+}
+
+/*
+ * ":colder [count]": Up in the quickfix stack.
+ * ":cnewer [count]": Down in the quickfix stack.
+ * ":lolder [count]": Up in the location list stack.
+ * ":lnewer [count]": Down in the location list stack.
+ */
+void qf_age(eap)
+exarg_T *eap;
+{
+ qf_info_T *qi = &ql_info;
+ int count;
+
+ if (eap->cmdidx == CMD_lolder || eap->cmdidx == CMD_lnewer) {
+ qi = GET_LOC_LIST(curwin);
+ if (qi == NULL) {
+ EMSG(_(e_loclist));
+ return;
+ }
+ }
+
+ if (eap->addr_count != 0)
+ count = eap->line2;
+ else
+ count = 1;
+ while (count--) {
+ if (eap->cmdidx == CMD_colder || eap->cmdidx == CMD_lolder) {
+ if (qi->qf_curlist == 0) {
+ EMSG(_("E380: At bottom of quickfix stack"));
+ break;
+ }
+ --qi->qf_curlist;
+ } else {
+ if (qi->qf_curlist >= qi->qf_listcount - 1) {
+ EMSG(_("E381: At top of quickfix stack"));
+ break;
+ }
+ ++qi->qf_curlist;
+ }
+ }
+ qf_msg(qi);
+}
+
+static void qf_msg(qi)
+qf_info_T *qi;
+{
+ smsg((char_u *)_("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);
+}
+
+/*
+ * Free error list "idx".
+ */
+static void qf_free(qi, idx)
+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) {
+ vim_free(qi->qf_lists[idx].qf_start->qf_text);
+ stop = (qi->qf_lists[idx].qf_start == qfp);
+ vim_free(qi->qf_lists[idx].qf_start->qf_pattern);
+ vim_free(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;
+ }
+ vim_free(qi->qf_lists[idx].qf_title);
+ qi->qf_lists[idx].qf_title = NULL;
+}
+
+/*
+ * qf_mark_adjust: adjust marks
+ */
+void qf_mark_adjust(wp, line1, line2, amount, amount_after)
+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;
+
+ if (wp != NULL) {
+ if (wp->w_llist == NULL)
+ return;
+ 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)
+ if (qfp->qf_fnum == curbuf->b_fnum) {
+ if (qfp->qf_lnum >= line1 && qfp->qf_lnum <= line2) {
+ if (amount == MAXLNUM)
+ qfp->qf_cleared = TRUE;
+ else
+ qfp->qf_lnum += amount;
+ } else if (amount_after && qfp->qf_lnum > line2)
+ qfp->qf_lnum += amount_after;
+ }
+}
+
+/*
+ * Make a nice message out of the error character and the error number:
+ * char number message
+ * e or E 0 " error"
+ * w or W 0 " warning"
+ * i or I 0 " info"
+ * 0 0 ""
+ * other 0 " c"
+ * e or E n " error n"
+ * w or W n " warning n"
+ * i or I n " info n"
+ * 0 n " error n"
+ * other n " c n"
+ * 1 x "" :helpgrep
+ */
+static char_u * qf_types(c, nr)
+int c, nr;
+{
+ static char_u buf[20];
+ static char_u cc[3];
+ char_u *p;
+
+ if (c == 'W' || c == 'w')
+ p = (char_u *)" warning";
+ else if (c == 'I' || c == 'i')
+ p = (char_u *)" info";
+ else if (c == 'E' || c == 'e' || (c == 0 && nr > 0))
+ p = (char_u *)" error";
+ else if (c == 0 || c == 1)
+ p = (char_u *)"";
+ else {
+ cc[0] = ' ';
+ cc[1] = c;
+ cc[2] = NUL;
+ p = cc;
+ }
+
+ if (nr <= 0)
+ return p;
+
+ sprintf((char *)buf, "%s %3d", (char *)p, nr);
+ return buf;
+}
+
+/*
+ * ":cwindow": open the quickfix window if we have errors to display,
+ * close it if not.
+ * ":lwindow": open the location list window if we have locations to display,
+ * close it if not.
+ */
+void ex_cwindow(eap)
+exarg_T *eap;
+{
+ qf_info_T *qi = &ql_info;
+ win_T *win;
+
+ if (eap->cmdidx == CMD_lwindow) {
+ qi = GET_LOC_LIST(curwin);
+ if (qi == NULL)
+ return;
+ }
+
+ /* Look for an existing quickfix window. */
+ win = qf_find_win(qi);
+
+ /*
+ * If a quickfix window is open but we have no errors to display,
+ * close the window. If a quickfix window is not open, then open
+ * it if we have errors; otherwise, leave it closed.
+ */
+ if (qi->qf_lists[qi->qf_curlist].qf_nonevalid
+ || qi->qf_lists[qi->qf_curlist].qf_count == 0
+ || qi->qf_curlist >= qi->qf_listcount) {
+ if (win != NULL)
+ ex_cclose(eap);
+ } else if (win == NULL)
+ ex_copen(eap);
+}
+
+/*
+ * ":cclose": close the window showing the list of errors.
+ * ":lclose": close the window showing the location list
+ */
+void ex_cclose(eap)
+exarg_T *eap;
+{
+ win_T *win = NULL;
+ qf_info_T *qi = &ql_info;
+
+ if (eap->cmdidx == CMD_lclose || eap->cmdidx == CMD_lwindow) {
+ qi = GET_LOC_LIST(curwin);
+ if (qi == NULL)
+ return;
+ }
+
+ /* Find existing quickfix window and close it. */
+ win = qf_find_win(qi);
+ if (win != NULL)
+ win_close(win, FALSE);
+}
+
+/*
+ * ":copen": open a window that shows the list of errors.
+ * ":lopen": open a window that shows the location list.
+ */
+void ex_copen(eap)
+exarg_T *eap;
+{
+ qf_info_T *qi = &ql_info;
+ int height;
+ win_T *win;
+ tabpage_T *prevtab = curtab;
+ buf_T *qf_buf;
+ win_T *oldwin = curwin;
+
+ if (eap->cmdidx == CMD_lopen || eap->cmdidx == CMD_lwindow) {
+ qi = GET_LOC_LIST(curwin);
+ if (qi == NULL) {
+ EMSG(_(e_loclist));
+ return;
+ }
+ }
+
+ if (eap->addr_count != 0)
+ height = eap->line2;
+ else
+ height = QF_WINHEIGHT;
+
+ reset_VIsual_and_resel(); /* stop Visual mode */
+
+ /*
+ * Find existing quickfix window, or open a new one.
+ */
+ win = qf_find_win(qi);
+
+ if (win != NULL && cmdmod.tab == 0)
+ win_goto(win);
+ else {
+ qf_buf = qf_find_buf(qi);
+
+ /* The current window becomes the previous window afterwards. */
+ win = curwin;
+
+ 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. */
+ win_goto(lastwin);
+ if (win_split(height, WSP_BELOW | WSP_NEWLOC) == FAIL)
+ return; /* not enough room for window */
+ RESET_BINDING(curwin);
+
+ if (eap->cmdidx == CMD_lopen || eap->cmdidx == CMD_lwindow) {
+ /*
+ * For the location list window, create a reference to the
+ * location list from the window 'win'.
+ */
+ curwin->w_llist_ref = win->w_llist;
+ win->w_llist->qf_refcount++;
+ }
+
+ if (oldwin != curwin)
+ oldwin = NULL; /* don't store info when in another window */
+ if (qf_buf != NULL)
+ /* Use the existing quickfix buffer */
+ (void)do_ecmd(qf_buf->b_fnum, NULL, NULL, NULL, ECMD_ONE,
+ ECMD_HIDE + ECMD_OLDBUF, oldwin);
+ 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);
+ RESET_BINDING(curwin);
+ curwin->w_p_diff = FALSE;
+ set_option_value((char_u *)"fdm", 0L, (char_u *)"manual",
+ OPT_LOCAL);
+ }
+
+ /* Only set the height when still in the same tab page and there is no
+ * window to the side. */
+ if (curtab == prevtab
+ && curwin->w_width == Columns
+ )
+ win_setheight(height);
+ curwin->w_p_wfh = TRUE; /* set 'winfixheight' */
+ if (win_valid(win))
+ prevwin = win;
+ }
+
+ /*
+ * Fill the buffer with the quickfix list.
+ */
+ qf_fill_buffer(qi);
+
+ if (qi->qf_lists[qi->qf_curlist].qf_title != NULL)
+ qf_set_title(qi);
+
+ curwin->w_cursor.lnum = qi->qf_lists[qi->qf_curlist].qf_index;
+ curwin->w_cursor.col = 0;
+ check_cursor();
+ update_topline(); /* scroll to show the line */
+}
+
+/*
+ * Return the number of the current entry (line number in the quickfix
+ * window).
+ */
+linenr_T qf_current_entry(wp)
+win_T *wp;
+{
+ qf_info_T *qi = &ql_info;
+
+ if (IS_LL_WINDOW(wp))
+ /* In the location list window, use the referenced location list */
+ qi = wp->w_llist_ref;
+
+ return qi->qf_lists[qi->qf_curlist].qf_index;
+}
+
+/*
+ * Update the cursor position in the quickfix window to the current error.
+ * Return TRUE if there is a quickfix window.
+ */
+static int qf_win_pos_update(qi, old_qf_index)
+qf_info_T *qi;
+int old_qf_index; /* previous qf_index or zero */
+{
+ win_T *win;
+ int qf_index = qi->qf_lists[qi->qf_curlist].qf_index;
+
+ /*
+ * Put the cursor on the current error in the quickfix window, so that
+ * it's viewable.
+ */
+ win = qf_find_win(qi);
+ 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;
+ } else {
+ curwin->w_redraw_top = qf_index;
+ curwin->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;
+ }
+ return win != NULL;
+}
+
+/*
+ * Check whether the given window is displaying the specified quickfix/location
+ * list buffer
+ */
+static int is_qf_win(win, qi)
+win_T *win;
+qf_info_T *qi;
+{
+ /*
+ * A window displaying the quickfix buffer will have the w_llist_ref field
+ * set to NULL.
+ * A window displaying a location list buffer will have the w_llist_ref
+ * pointing to the location list.
+ */
+ if (bt_quickfix(win->w_buffer))
+ if ((qi == &ql_info && win->w_llist_ref == NULL)
+ || (qi != &ql_info && win->w_llist_ref == qi))
+ return TRUE;
+
+ return FALSE;
+}
+
+/*
+ * Find a window displaying the quickfix/location list 'qi'
+ * Searches in only the windows opened in the current tab.
+ */
+static win_T * qf_find_win(qi)
+qf_info_T *qi;
+{
+ win_T *win;
+
+ FOR_ALL_WINDOWS(win)
+ if (is_qf_win(win, qi))
+ break;
+
+ return win;
+}
+
+/*
+ * Find a quickfix buffer.
+ * Searches in windows opened in all the tabs.
+ */
+static buf_T * qf_find_buf(qi)
+qf_info_T *qi;
+{
+ tabpage_T *tp;
+ win_T *win;
+
+ FOR_ALL_TAB_WINDOWS(tp, win)
+ if (is_qf_win(win, qi))
+ return win->w_buffer;
+
+ return NULL;
+}
+
+/*
+ * Find the quickfix buffer. If it exists, update the contents.
+ */
+static void qf_update_buffer(qi)
+qf_info_T *qi;
+{
+ 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);
+
+ qf_fill_buffer(qi);
+
+ if (qi->qf_lists[qi->qf_curlist].qf_title != NULL
+ && (win = qf_find_win(qi)) != NULL) {
+ curwin_save = curwin;
+ curwin = win;
+ qf_set_title(qi);
+ curwin = curwin_save;
+
+ }
+
+ /* restore curwin/curbuf and a few other things */
+ aucmd_restbuf(&aco);
+
+ (void)qf_win_pos_update(qi, 0);
+ }
+}
+
+static void qf_set_title(qi)
+qf_info_T *qi;
+{
+ set_internal_string_var((char_u *)"w:quickfix_title",
+ qi->qf_lists[qi->qf_curlist].qf_title);
+}
+
+/*
+ * Fill current buffer with quickfix errors, replacing any previous contents.
+ * curbuf must be the quickfix buffer!
+ */
+static void qf_fill_buffer(qi)
+qf_info_T *qi;
+{
+ linenr_T lnum;
+ qfline_T *qfp;
+ buf_T *errbuf;
+ int len;
+ int old_KeyTyped = KeyTyped;
+
+ /* 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) {
+ if (qfp->qf_fnum != 0
+ && (errbuf = buflist_findnr(qfp->qf_fnum)) != NULL
+ && errbuf->b_fname != NULL) {
+ if (qfp->qf_type == 1) /* :helpgrep */
+ STRCPY(IObuff, gettail(errbuf->b_fname));
+ else
+ STRCPY(IObuff, errbuf->b_fname);
+ len = (int)STRLEN(IObuff);
+ } else
+ len = 0;
+ IObuff[len++] = '|';
+
+ if (qfp->qf_lnum > 0) {
+ sprintf((char *)IObuff + len, "%ld", qfp->qf_lnum);
+ len += (int)STRLEN(IObuff + len);
+
+ if (qfp->qf_col > 0) {
+ sprintf((char *)IObuff + len, " col %d", qfp->qf_col);
+ len += (int)STRLEN(IObuff + len);
+ }
+
+ sprintf((char *)IObuff + len, "%s",
+ (char *)qf_types(qfp->qf_type, qfp->qf_nr));
+ len += (int)STRLEN(IObuff + len);
+ } else if (qfp->qf_pattern != NULL) {
+ qf_fmt_text(qfp->qf_pattern, IObuff + len, IOSIZE - len);
+ len += (int)STRLEN(IObuff + len);
+ }
+ IObuff[len++] = '|';
+ IObuff[len++] = ' ';
+
+ /* Remove newlines and leading whitespace from the text.
+ * For an unrecognized line keep the indent, the compiler may
+ * mark a word with ^^^^. */
+ 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)
+ break;
+ qfp = qfp->qf_next;
+ }
+ /* 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);
+
+ /* Restore KeyTyped, setting 'filetype' may reset it. */
+ KeyTyped = old_KeyTyped;
+}
+
+
+/*
+ * Return TRUE if "buf" is the quickfix buffer.
+ */
+int bt_quickfix(buf)
+buf_T *buf;
+{
+ return buf != NULL && buf->b_p_bt[0] == 'q';
+}
+
+/*
+ * Return TRUE if "buf" is a "nofile" or "acwrite" buffer.
+ * This means the buffer name is not a file name.
+ */
+int bt_nofile(buf)
+buf_T *buf;
+{
+ return buf != NULL && ((buf->b_p_bt[0] == 'n' && buf->b_p_bt[2] == 'f')
+ || buf->b_p_bt[0] == 'a');
+}
+
+/*
+ * Return TRUE if "buf" is a "nowrite" or "nofile" buffer.
+ */
+int bt_dontwrite(buf)
+buf_T *buf;
+{
+ return buf != NULL && buf->b_p_bt[0] == 'n';
+}
+
+int bt_dontwrite_msg(buf)
+buf_T *buf;
+{
+ if (bt_dontwrite(buf)) {
+ EMSG(_("E382: Cannot write, 'buftype' option is set"));
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*
+ * Return TRUE if the buffer should be hidden, according to 'hidden', ":hide"
+ * and 'bufhidden'.
+ */
+int buf_hide(buf)
+buf_T *buf;
+{
+ /* 'bufhidden' overrules 'hidden' and ":hide", check it first */
+ switch (buf->b_p_bh[0]) {
+ case 'u': /* "unload" */
+ case 'w': /* "wipe" */
+ case 'd': return FALSE; /* "delete" */
+ case 'h': return TRUE; /* "hide" */
+ }
+ return p_hid || cmdmod.hide;
+}
+
+/*
+ * Return TRUE when using ":vimgrep" for ":grep".
+ */
+int grep_internal(cmdidx)
+cmdidx_T cmdidx;
+{
+ return (cmdidx == CMD_grep
+ || cmdidx == CMD_lgrep
+ || cmdidx == CMD_grepadd
+ || cmdidx == CMD_lgrepadd)
+ && STRCMP("internal",
+ *curbuf->b_p_gp == NUL ? p_gp : curbuf->b_p_gp) == 0;
+}
+
+/*
+ * Used for ":make", ":lmake", ":grep", ":lgrep", ":grepadd", and ":lgrepadd"
+ */
+void ex_make(eap)
+exarg_T *eap;
+{
+ char_u *fname;
+ char_u *cmd;
+ unsigned len;
+ win_T *wp = NULL;
+ qf_info_T *qi = &ql_info;
+ int res;
+ char_u *au_name = NULL;
+
+ /* Redirect ":grep" to ":vimgrep" if 'grepprg' is "internal". */
+ if (grep_internal(eap->cmdidx)) {
+ ex_vimgrep(eap);
+ return;
+ }
+
+ switch (eap->cmdidx) {
+ case CMD_make: au_name = (char_u *)"make"; break;
+ case CMD_lmake: au_name = (char_u *)"lmake"; break;
+ case CMD_grep: au_name = (char_u *)"grep"; break;
+ case CMD_lgrep: au_name = (char_u *)"lgrep"; break;
+ case CMD_grepadd: au_name = (char_u *)"grepadd"; break;
+ 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)
+ return;
+ }
+
+ if (eap->cmdidx == CMD_lmake || eap->cmdidx == CMD_lgrep
+ || eap->cmdidx == CMD_lgrepadd)
+ wp = curwin;
+
+ autowrite_all();
+ fname = get_mef_name();
+ if (fname == NULL)
+ return;
+ mch_remove(fname); /* in case it's not unique */
+
+ /*
+ * If 'shellpipe' empty: don't redirect to 'errorfile'.
+ */
+ len = (unsigned)STRLEN(p_shq) * 2 + (unsigned)STRLEN(eap->arg) + 1;
+ if (*p_sp != NUL)
+ len += (unsigned)STRLEN(p_sp) + (unsigned)STRLEN(fname) + 3;
+ cmd = alloc(len);
+ if (cmd == NULL)
+ return;
+ sprintf((char *)cmd, "%s%s%s", (char *)p_shq, (char *)eap->arg,
+ (char *)p_shq);
+ if (*p_sp != NUL)
+ append_redir(cmd, len, p_sp, fname);
+ /*
+ * Output a newline if there's something else than the :make command that
+ * was typed (in which case the cursor is in column 0).
+ */
+ if (msg_col == 0)
+ msg_didout = FALSE;
+ msg_start();
+ MSG_PUTS(":!");
+ msg_outtrans(cmd); /* show what we are doing */
+
+ /* let the shell know if we are redirecting output or not */
+ do_shell(cmd, *p_sp != NUL ? SHELL_DOOUT : 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)
+ qi = GET_LOC_LIST(wp);
+ if (au_name != NULL) {
+ apply_autocmds(EVENT_QUICKFIXCMDPOST, au_name,
+ curbuf->b_fname, TRUE, curbuf);
+ if (qi->qf_curlist < qi->qf_listcount)
+ res = qi->qf_lists[qi->qf_curlist].qf_count;
+ else
+ res = 0;
+ }
+ if (res > 0 && !eap->forceit)
+ qf_jump(qi, 0, 0, FALSE); /* display first error */
+
+ mch_remove(fname);
+ vim_free(fname);
+ vim_free(cmd);
+}
+
+/*
+ * Return the name for the errorfile, in allocated memory.
+ * Find a new unique name when 'makeef' contains "##".
+ * Returns NULL for error.
+ */
+static char_u * get_mef_name() {
+ char_u *p;
+ char_u *name;
+ static int start = -1;
+ static int off = 0;
+#ifdef HAVE_LSTAT
+ struct stat sb;
+#endif
+
+ if (*p_mef == NUL) {
+ name = vim_tempname('e');
+ if (name == NULL)
+ EMSG(_(e_notmp));
+ return name;
+ }
+
+ for (p = p_mef; *p; ++p)
+ if (p[0] == '#' && p[1] == '#')
+ break;
+
+ if (*p == NUL)
+ return vim_strsave(p_mef);
+
+ /* Keep trying until the name doesn't exist yet. */
+ for (;; ) {
+ if (start == -1)
+ start = mch_get_pid();
+ else
+ off += 19;
+
+ name = alloc((unsigned)STRLEN(p_mef) + 30);
+ if (name == NULL)
+ break;
+ STRCPY(name, p_mef);
+ sprintf((char *)name + (p - p_mef), "%d%d", start, off);
+ STRCAT(name, p + 2);
+ if (mch_getperm(name) < 0
+#ifdef HAVE_LSTAT
+ /* Don't accept a symbolic link, its a security risk. */
+ && mch_lstat((char *)name, &sb) < 0
+#endif
+ )
+ break;
+ vim_free(name);
+ }
+ return name;
+}
+
+/*
+ * ":cc", ":crewind", ":cfirst" and ":clast".
+ * ":ll", ":lrewind", ":lfirst" and ":llast".
+ */
+void ex_cc(eap)
+exarg_T *eap;
+{
+ qf_info_T *qi = &ql_info;
+
+ if (eap->cmdidx == CMD_ll
+ || eap->cmdidx == CMD_lrewind
+ || eap->cmdidx == CMD_lfirst
+ || eap->cmdidx == CMD_llast) {
+ qi = GET_LOC_LIST(curwin);
+ if (qi == NULL) {
+ EMSG(_(e_loclist));
+ return;
+ }
+ }
+
+ qf_jump(qi, 0,
+ eap->addr_count > 0
+ ? (int)eap->line2
+ : (eap->cmdidx == CMD_cc || eap->cmdidx == CMD_ll)
+ ? 0
+ : (eap->cmdidx == CMD_crewind || eap->cmdidx == CMD_lrewind
+ || eap->cmdidx == CMD_cfirst || eap->cmdidx == CMD_lfirst)
+ ? 1
+ : 32767,
+ eap->forceit);
+}
+
+/*
+ * ":cnext", ":cnfile", ":cNext" and ":cprevious".
+ * ":lnext", ":lNext", ":lprevious", ":lnfile", ":lNfile" and ":lpfile".
+ */
+void ex_cnext(eap)
+exarg_T *eap;
+{
+ qf_info_T *qi = &ql_info;
+
+ if (eap->cmdidx == CMD_lnext
+ || eap->cmdidx == CMD_lNext
+ || eap->cmdidx == CMD_lprevious
+ || eap->cmdidx == CMD_lnfile
+ || eap->cmdidx == CMD_lNfile
+ || eap->cmdidx == CMD_lpfile) {
+ qi = GET_LOC_LIST(curwin);
+ if (qi == NULL) {
+ EMSG(_(e_loclist));
+ return;
+ }
+ }
+
+ qf_jump(qi, (eap->cmdidx == CMD_cnext || eap->cmdidx == CMD_lnext)
+ ? FORWARD
+ : (eap->cmdidx == CMD_cnfile || eap->cmdidx == CMD_lnfile)
+ ? FORWARD_FILE
+ : (eap->cmdidx == CMD_cpfile || eap->cmdidx == CMD_lpfile
+ || eap->cmdidx == CMD_cNfile || eap->cmdidx == CMD_lNfile)
+ ? BACKWARD_FILE
+ : BACKWARD,
+ eap->addr_count > 0 ? (int)eap->line2 : 1, eap->forceit);
+}
+
+/*
+ * ":cfile"/":cgetfile"/":caddfile" commands.
+ * ":lfile"/":lgetfile"/":laddfile" commands.
+ */
+void ex_cfile(eap)
+exarg_T *eap;
+{
+ win_T *wp = NULL;
+ qf_info_T *qi = &ql_info;
+ char_u *au_name = NULL;
+
+ if (eap->cmdidx == CMD_lfile || eap->cmdidx == CMD_lgetfile
+ || eap->cmdidx == CMD_laddfile)
+ wp = curwin;
+
+ switch (eap->cmdidx) {
+ case CMD_cfile: au_name = (char_u *)"cfile"; break;
+ case CMD_cgetfile: au_name = (char_u *)"cgetfile"; break;
+ case CMD_caddfile: au_name = (char_u *)"caddfile"; break;
+ case CMD_lfile: au_name = (char_u *)"lfile"; break;
+ case CMD_lgetfile: au_name = (char_u *)"lgetfile"; break;
+ case CMD_laddfile: au_name = (char_u *)"laddfile"; break;
+ default: break;
+ }
+ if (au_name != NULL)
+ apply_autocmds(EVENT_QUICKFIXCMDPRE, au_name, NULL, FALSE, curbuf);
+ 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.
+ */
+ if (qf_init(wp, p_ef, p_efm, (eap->cmdidx != CMD_caddfile
+ && eap->cmdidx != CMD_laddfile),
+ *eap->cmdlinep) > 0
+ && (eap->cmdidx == CMD_cfile
+ || eap->cmdidx == CMD_lfile)) {
+ if (au_name != NULL)
+ apply_autocmds(EVENT_QUICKFIXCMDPOST, au_name, NULL, FALSE, curbuf);
+ if (wp != NULL)
+ qi = GET_LOC_LIST(wp);
+ qf_jump(qi, 0, 0, eap->forceit); /* display first error */
+ } else {
+ if (au_name != NULL)
+ apply_autocmds(EVENT_QUICKFIXCMDPOST, au_name, NULL, FALSE, curbuf);
+ }
+}
+
+/*
+ * ":vimgrep {pattern} file(s)"
+ * ":vimgrepadd {pattern} file(s)"
+ * ":lvimgrep {pattern} file(s)"
+ * ":lvimgrepadd {pattern} file(s)"
+ */
+void ex_vimgrep(eap)
+exarg_T *eap;
+{
+ regmmatch_T regmatch;
+ int fcount;
+ char_u **fnames;
+ char_u *fname;
+ char_u *s;
+ char_u *p;
+ 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;
+ int using_dummy;
+ int redraw_for_dummy = FALSE;
+ int found_match;
+ buf_T *first_match_buf = NULL;
+ time_t seconds = 0;
+ int save_mls;
+ char_u *save_ei = NULL;
+ aco_save_T aco;
+ int flags = 0;
+ colnr_T col;
+ long tomatch;
+ char_u *dirname_start = NULL;
+ char_u *dirname_now = NULL;
+ char_u *target_dir = NULL;
+ char_u *au_name = NULL;
+
+ switch (eap->cmdidx) {
+ case CMD_vimgrep: au_name = (char_u *)"vimgrep"; break;
+ case CMD_lvimgrep: au_name = (char_u *)"lvimgrep"; break;
+ case CMD_vimgrepadd: au_name = (char_u *)"vimgrepadd"; break;
+ case CMD_lvimgrepadd: au_name = (char_u *)"lvimgrepadd"; break;
+ case CMD_grep: au_name = (char_u *)"grep"; break;
+ case CMD_lgrep: au_name = (char_u *)"lgrep"; break;
+ case CMD_grepadd: au_name = (char_u *)"grepadd"; break;
+ 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)
+ return;
+ }
+
+ if (eap->cmdidx == CMD_lgrep
+ || eap->cmdidx == CMD_lvimgrep
+ || eap->cmdidx == CMD_lgrepadd
+ || eap->cmdidx == CMD_lvimgrepadd) {
+ qi = ll_get_or_alloc_list(curwin);
+ if (qi == NULL)
+ return;
+ }
+
+ if (eap->addr_count > 0)
+ tomatch = eap->line2;
+ else
+ tomatch = MAXLNUM;
+
+ /* Get the search pattern: either white-separated or enclosed in // */
+ regmatch.regprog = NULL;
+ 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 (last_search_pat() == NULL) {
+ EMSG(_(e_noprevre));
+ goto theend;
+ }
+ regmatch.regprog = vim_regcomp(last_search_pat(), RE_MAGIC);
+ } else
+ regmatch.regprog = vim_regcomp(s, RE_MAGIC);
+
+ if (regmatch.regprog == NULL)
+ goto theend;
+ regmatch.rmm_ic = p_ic;
+ regmatch.rmm_maxcol = 0;
+
+ p = skipwhite(p);
+ if (*p == NUL) {
+ EMSG(_("E683: File name missing or invalid pattern"));
+ goto theend;
+ }
+
+ if ((eap->cmdidx != CMD_grepadd && eap->cmdidx != CMD_lgrepadd &&
+ 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)
+ ;
+
+ /* parse the list of arguments */
+ if (get_arglist_exp(p, &fcount, &fnames, TRUE) == FAIL)
+ goto theend;
+ if (fcount == 0) {
+ EMSG(_(e_nomatch));
+ goto theend;
+ }
+
+ dirname_start = alloc(MAXPATHL);
+ dirname_now = alloc(MAXPATHL);
+ if (dirname_start == NULL || dirname_now == NULL)
+ goto theend;
+
+ /* Remember the current directory, because a BufRead autocommand that does
+ * ":lcd %:p:h" changes the meaning of short path names. */
+ mch_dirname(dirname_start, MAXPATHL);
+
+ /* Remember the value of qf_start, so that we can check for autocommands
+ * changing the current quickfix list. */
+ 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 = shorten_fname1(fnames[fi]);
+ if (time(NULL) > seconds) {
+ /* Display the file name every second or so, show the user we are
+ * working on it. */
+ seconds = time(NULL);
+ msg_start();
+ p = msg_strtrunc(fname, TRUE);
+ if (p == NULL)
+ msg_outtrans(fname);
+ else {
+ msg_outtrans(p);
+ vim_free(p);
+ }
+ msg_clr_eos();
+ msg_didout = FALSE; /* overwrite this message */
+ msg_nowait = TRUE; /* don't wait for this message */
+ msg_col = 0;
+ out_flush();
+ }
+
+ buf = buflist_findname_exp(fnames[fi]);
+ if (buf == NULL || buf->b_ml.ml_mfp == NULL) {
+ /* Remember that a buffer with this name already exists. */
+ duplicate_name = (buf != NULL);
+ using_dummy = TRUE;
+ redraw_for_dummy = TRUE;
+
+ /* Don't do Filetype autocommands to avoid loading syntax and
+ * indent scripts, a great speed improvement. */
+ save_ei = au_event_disable(",Filetype");
+ /* Don't use modelines here, it's useless. */
+ save_mls = p_mls;
+ p_mls = 0;
+
+ /* Load file into a buffer, so that 'fileencoding' is detected,
+ * autocommands applied, etc. */
+ buf = load_dummy_buffer(fname, dirname_start, dirname_now);
+
+ p_mls = save_mls;
+ au_event_restore(save_ei);
+ } else
+ /* Use existing, loaded buffer. */
+ using_dummy = FALSE;
+
+ if (cur_qf_start != qi->qf_lists[qi->qf_curlist].qf_start) {
+ int idx;
+
+ /* Autocommands changed the quickfix list. Find the one we were
+ * using and restore it. */
+ for (idx = 0; idx < LISTCOUNT; ++idx)
+ if (cur_qf_start == qi->qf_lists[idx].qf_start) {
+ qi->qf_curlist = idx;
+ break;
+ }
+ if (idx == LISTCOUNT) {
+ /* List cannot be found, create a new one. */
+ qf_new_list(qi, *eap->cmdlinep);
+ cur_qf_start = qi->qf_lists[qi->qf_curlist].qf_start;
+ }
+ }
+
+ if (buf == NULL) {
+ if (!got_int)
+ smsg((char_u *)_("Cannot open file \"%s\""), fname);
+ } else {
+ /* Try for a match in all lines of the buffer.
+ * For ":1vimgrep" look for first match only. */
+ found_match = FALSE;
+ for (lnum = 1; lnum <= buf->b_ml.ml_line_count && tomatch > 0;
+ ++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;
+ break;
+ }
+ found_match = TRUE;
+ if (--tomatch == 0)
+ break;
+ if ((flags & VGR_GLOBAL) == 0
+ || regmatch.endpos[0].lnum > 0)
+ break;
+ col = regmatch.endpos[0].col
+ + (col == regmatch.endpos[0].col);
+ if (col > (colnr_T)STRLEN(ml_get_buf(buf, lnum, FALSE)))
+ break;
+ }
+ line_breakcheck();
+ if (got_int)
+ break;
+ }
+ cur_qf_start = qi->qf_lists[qi->qf_curlist].qf_start;
+
+ if (using_dummy) {
+ if (found_match && first_match_buf == NULL)
+ first_match_buf = buf;
+ if (duplicate_name) {
+ /* Never keep a dummy buffer if there is another buffer
+ * with the same name. */
+ wipe_dummy_buffer(buf, dirname_start);
+ buf = NULL;
+ } else if (!cmdmod.hide
+ || buf->b_p_bh[0] == 'u' /* "unload" */
+ || buf->b_p_bh[0] == 'w' /* "wipe" */
+ || buf->b_p_bh[0] == 'd') { /* "delete" */
+ /* When no match was found we don't need to remember the
+ * buffer, wipe it out. If there was a match and it
+ * wasn't the first one or we won't jump there: only
+ * unload the buffer.
+ * Ignore 'hidden' here, because it may lead to having too
+ * many swap files. */
+ if (!found_match) {
+ wipe_dummy_buffer(buf, dirname_start);
+ buf = NULL;
+ } else if (buf != first_match_buf || (flags & VGR_NOJUMP)) {
+ unload_dummy_buffer(buf, dirname_start);
+ buf = NULL;
+ }
+ }
+
+ if (buf != NULL) {
+ /* 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)
+ 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
+ * need to be done (again). But not the window-local
+ * options! */
+ aucmd_prepbuf(&aco, buf);
+ apply_autocmds(EVENT_FILETYPE, buf->b_p_ft,
+ buf->b_fname, TRUE, buf);
+ do_modelines(OPT_NOWIN);
+ aucmd_restbuf(&aco);
+ }
+ }
+ }
+ }
+
+ FreeWild(fcount, fnames);
+
+ 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;
+
+ qf_update_buffer(qi);
+
+ if (au_name != NULL)
+ apply_autocmds(EVENT_QUICKFIXCMDPOST, au_name,
+ curbuf->b_fname, TRUE, curbuf);
+
+ /* Jump to first match. */
+ if (qi->qf_lists[qi->qf_curlist].qf_count > 0) {
+ if ((flags & VGR_NOJUMP) == 0) {
+ buf = curbuf;
+ qf_jump(qi, 0, 0, eap->forceit);
+ if (buf != curbuf)
+ /* If we jumped to another buffer redrawing will already be
+ * taken care of. */
+ redraw_for_dummy = FALSE;
+
+ /* Jump to the directory used after loading the buffer. */
+ if (curbuf == first_match_buf && target_dir != NULL) {
+ exarg_T ea;
+
+ ea.arg = target_dir;
+ ea.cmdidx = CMD_lcd;
+ ex_cd(&ea);
+ }
+ }
+ } else
+ EMSG2(_(e_nomatch2), s);
+
+ /* If we loaded a dummy buffer into the current window, the autocommands
+ * may have messed up things, need to redraw and recompute folds. */
+ if (redraw_for_dummy) {
+ foldUpdateAll(curwin);
+ }
+
+theend:
+ vim_free(dirname_now);
+ vim_free(dirname_start);
+ vim_free(target_dir);
+ vim_regfree(regmatch.regprog);
+}
+
+/*
+ * 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(p, s, flags)
+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.
+ */
+static void restore_start_dir(dirname_start)
+char_u *dirname_start;
+{
+ char_u *dirname_now = alloc(MAXPATHL);
+
+ if (NULL != dirname_now) {
+ mch_dirname(dirname_now, MAXPATHL);
+ if (STRCMP(dirname_start, dirname_now) != 0) {
+ /* If the directory has changed, change it back by building up an
+ * appropriate ex command and executing it. */
+ exarg_T ea;
+
+ ea.arg = dirname_start;
+ ea.cmdidx = (curwin->w_localdir == NULL) ? CMD_cd : CMD_lcd;
+ ex_cd(&ea);
+ }
+ vim_free(dirname_now);
+ }
+}
+
+/*
+ * Load file "fname" into a dummy buffer and return the buffer pointer,
+ * placing the directory resulting from the buffer load into the
+ * "resulting_dir" pointer. "resulting_dir" must be allocated by the caller
+ * prior to calling this function. Restores directory to "dirname_start" prior
+ * to returning, if autocmds or the 'autochdir' option have changed it.
+ *
+ * If creating the dummy buffer does not fail, must call unload_dummy_buffer()
+ * or wipe_dummy_buffer() later!
+ *
+ * Returns NULL if it fails.
+ */
+static buf_T * load_dummy_buffer(fname, dirname_start, resulting_dir)
+char_u *fname;
+char_u *dirname_start; /* in: old directory */
+char_u *resulting_dir; /* out: new directory */
+{
+ buf_T *newbuf;
+ buf_T *newbuf_to_wipe = NULL;
+ int failed = TRUE;
+ aco_save_T aco;
+
+ /* Allocate a buffer without putting it in the buffer list. */
+ newbuf = buflist_new(NULL, NULL, (linenr_T)1, BLN_DUMMY);
+ if (newbuf == NULL)
+ return NULL;
+
+ /* 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 */
+ aucmd_prepbuf(&aco, newbuf);
+
+ /* Need to set the filename for autocommands. */
+ (void)setfname(curbuf, fname, NULL, FALSE);
+
+ /* Create swap file now to avoid the ATTENTION message. */
+ check_need_swap(TRUE);
+
+ /* Remove the "dummy" flag, otherwise autocommands may not
+ * 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
+ && !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;
+ newbuf = curbuf;
+ }
+ }
+
+ /* 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);
+ }
+
+ /*
+ * When autocommands/'autochdir' option changed directory: go back.
+ * Let the caller know what the resulting dir was first, in case it is
+ * important.
+ */
+ mch_dirname(resulting_dir, MAXPATHL);
+ restore_start_dir(dirname_start);
+
+ if (!buf_valid(newbuf))
+ return NULL;
+ if (failed) {
+ wipe_dummy_buffer(newbuf, dirname_start);
+ return NULL;
+ }
+ return newbuf;
+}
+
+/*
+ * Wipe out the dummy buffer that load_dummy_buffer() created. Restores
+ * directory to "dirname_start" prior to returning, if autocmds or the
+ * 'autochdir' option have changed it.
+ */
+static void wipe_dummy_buffer(buf, dirname_start)
+buf_T *buf;
+char_u *dirname_start;
+{
+ if (curbuf != buf) { /* safety check */
+ cleanup_T cs;
+
+ /* Reset the error/interrupt/exception state here so that aborting()
+ * returns FALSE when wiping out the buffer. Otherwise it doesn't
+ * work when got_int is set. */
+ enter_cleanup(&cs);
+
+ wipe_buffer(buf, FALSE);
+
+ /* Restore the error/interrupt/exception state if not discarded by a
+ * new aborting error, interrupt, or uncaught exception. */
+ leave_cleanup(&cs);
+ /* When autocommands/'autochdir' option changed directory: go back. */
+ restore_start_dir(dirname_start);
+ }
+}
+
+/*
+ * Unload the dummy buffer that load_dummy_buffer() created. Restores
+ * directory to "dirname_start" prior to returning, if autocmds or the
+ * 'autochdir' option have changed it.
+ */
+static void unload_dummy_buffer(buf, dirname_start)
+buf_T *buf;
+char_u *dirname_start;
+{
+ if (curbuf != buf) { /* safety check */
+ close_buffer(NULL, buf, DOBUF_UNLOAD, FALSE);
+
+ /* When autocommands/'autochdir' option changed directory: go back. */
+ restore_start_dir(dirname_start);
+ }
+}
+
+/*
+ * Add each quickfix error to list "list" as a dictionary.
+ */
+int get_errorlist(wp, list)
+win_T *wp;
+list_T *list;
+{
+ qf_info_T *qi = &ql_info;
+ dict_T *dict;
+ 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->qf_curlist >= qi->qf_listcount
+ || qi->qf_lists[qi->qf_curlist].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. */
+ bufnum = qfp->qf_fnum;
+ if (bufnum != 0 && (buflist_findnr(bufnum) == NULL))
+ bufnum = 0;
+
+ if ((dict = dict_alloc()) == NULL)
+ return FAIL;
+ if (list_append_dict(list, dict) == FAIL)
+ return FAIL;
+
+ 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;
+
+ qfp = qfp->qf_next;
+ }
+ 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(wp, list, action, title)
+win_T *wp;
+list_T *list;
+int action;
+char_u *title;
+{
+ listitem_T *li;
+ dict_T *d;
+ char_u *filename, *pattern, *text, *type;
+ int bufnum;
+ long lnum;
+ int col, nr;
+ int vcol;
+ qfline_T *prevp = NULL;
+ int valid, status;
+ int retval = OK;
+ qf_info_T *qi = &ql_info;
+ int did_bufnr_emsg = FALSE;
+
+ if (wp != NULL) {
+ qi = ll_get_or_alloc_list(wp);
+ if (qi == NULL)
+ return FAIL;
+ }
+
+ if (action == ' ' || qi->qf_curlist == 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);
+
+ for (li = list->lv_first; li != NULL; li = li->li_next) {
+ if (li->li_tv.v_type != VAR_DICT)
+ continue; /* Skip non-dict items */
+
+ d = li->li_tv.vval.v_dict;
+ if (d == NULL)
+ continue;
+
+ filename = get_dict_string(d, (char_u *)"filename", TRUE);
+ bufnum = get_dict_number(d, (char_u *)"bufnr");
+ lnum = get_dict_number(d, (char_u *)"lnum");
+ col = get_dict_number(d, (char_u *)"col");
+ vcol = get_dict_number(d, (char_u *)"vcol");
+ nr = get_dict_number(d, (char_u *)"nr");
+ type = get_dict_string(d, (char_u *)"type", TRUE);
+ pattern = get_dict_string(d, (char_u *)"pattern", TRUE);
+ text = get_dict_string(d, (char_u *)"text", TRUE);
+ if (text == NULL)
+ text = vim_strsave((char_u *)"");
+
+ valid = TRUE;
+ if ((filename == NULL && bufnum == 0) || (lnum == 0 && pattern == NULL))
+ valid = FALSE;
+
+ /* Mark entries with non-existing buffer number as not valid. Give the
+ * error message only once. */
+ if (bufnum != 0 && (buflist_findnr(bufnum) == NULL)) {
+ if (!did_bufnr_emsg) {
+ did_bufnr_emsg = TRUE;
+ EMSGN(_("E92: Buffer %ld not found"), bufnum);
+ }
+ valid = FALSE;
+ bufnum = 0;
+ }
+
+ status = qf_add_entry(qi, &prevp,
+ NULL, /* dir */
+ filename,
+ bufnum,
+ text,
+ lnum,
+ col,
+ vcol, /* vis_col */
+ pattern, /* search pattern */
+ nr,
+ type == NULL ? NUL : *type,
+ valid);
+
+ vim_free(filename);
+ vim_free(pattern);
+ vim_free(text);
+ vim_free(type);
+
+ if (status == FAIL) {
+ retval = FAIL;
+ break;
+ }
+ }
+
+ 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;
+
+ qf_update_buffer(qi);
+
+ return retval;
+}
+
+/*
+ * ":[range]cbuffer [bufnr]" command.
+ * ":[range]caddbuffer [bufnr]" command.
+ * ":[range]cgetbuffer [bufnr]" command.
+ * ":[range]lbuffer [bufnr]" command.
+ * ":[range]laddbuffer [bufnr]" command.
+ * ":[range]lgetbuffer [bufnr]" command.
+ */
+void ex_cbuffer(eap)
+exarg_T *eap;
+{
+ buf_T *buf = NULL;
+ qf_info_T *qi = &ql_info;
+
+ if (eap->cmdidx == CMD_lbuffer || eap->cmdidx == CMD_lgetbuffer
+ || eap->cmdidx == CMD_laddbuffer) {
+ qi = ll_get_or_alloc_list(curwin);
+ if (qi == NULL)
+ return;
+ }
+
+ if (*eap->arg == NUL)
+ buf = curbuf;
+ else if (*skipwhite(skipdigits(eap->arg)) == NUL)
+ buf = buflist_findnr(atoi((char *)eap->arg));
+ if (buf == NULL)
+ EMSG(_(e_invarg));
+ else if (buf->b_ml.ml_mfp == NULL)
+ EMSG(_("E681: Buffer is not loaded"));
+ else {
+ if (eap->addr_count == 0) {
+ eap->line1 = 1;
+ eap->line2 = buf->b_ml.ml_line_count;
+ }
+ if (eap->line1 < 1 || eap->line1 > buf->b_ml.ml_line_count
+ || eap->line2 < 1 || eap->line2 > buf->b_ml.ml_line_count)
+ EMSG(_(e_invrange));
+ else {
+ char_u *qf_title = *eap->cmdlinep;
+
+ if (buf->b_sfname) {
+ vim_snprintf((char *)IObuff, IOSIZE, "%s (%s)",
+ (char *)qf_title, (char *)buf->b_sfname);
+ 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 */
+ }
+ }
+}
+
+/*
+ * ":cexpr {expr}", ":cgetexpr {expr}", ":caddexpr {expr}" command.
+ * ":lexpr {expr}", ":lgetexpr {expr}", ":laddexpr {expr}" command.
+ */
+void ex_cexpr(eap)
+exarg_T *eap;
+{
+ typval_T *tv;
+ qf_info_T *qi = &ql_info;
+
+ if (eap->cmdidx == CMD_lexpr || eap->cmdidx == CMD_lgetexpr
+ || eap->cmdidx == CMD_laddexpr) {
+ qi = ll_get_or_alloc_list(curwin);
+ if (qi == NULL)
+ 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
+ EMSG(_("E777: String or List expected"));
+ free_tv(tv);
+ }
+}
+
+/*
+ * ":helpgrep {pattern}"
+ */
+void ex_helpgrep(eap)
+exarg_T *eap;
+{
+ regmatch_T regmatch;
+ char_u *save_cpo;
+ char_u *p;
+ int fcount;
+ char_u **fnames;
+ FILE *fd;
+ int fi;
+ qfline_T *prevp = NULL;
+ long lnum;
+ char_u *lang;
+ qf_info_T *qi = &ql_info;
+ int new_qi = FALSE;
+ win_T *wp;
+ char_u *au_name = NULL;
+
+ /* Check for a specified language */
+ lang = check_help_lang(eap->arg);
+
+ switch (eap->cmdidx) {
+ case CMD_helpgrep: au_name = (char_u *)"helpgrep"; break;
+ 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)
+ return;
+ }
+
+ /* Make 'cpoptions' empty, the 'l' flag should not be used here. */
+ save_cpo = p_cpo;
+ p_cpo = empty_option;
+
+ if (eap->cmdidx == CMD_lhelpgrep) {
+ /* Find an existing help window */
+ FOR_ALL_WINDOWS(wp)
+ if (wp->w_buffer != NULL && wp->w_buffer->b_help)
+ break;
+
+ 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 */
+ if ((qi = ll_new_list()) == NULL)
+ return;
+ new_qi = TRUE;
+ }
+ }
+
+ 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 */
+ qf_new_list(qi, *eap->cmdlinep);
+
+ /* Go through all directories in 'runtimepath' */
+ p = p_rtp;
+ while (*p != NUL && !got_int) {
+ copy_option_part(&p, NameBuff, MAXPATHL, ",");
+
+ /* Find all "*.txt" and "*.??x" files in the "doc" directory. */
+ add_pathsep(NameBuff);
+ STRCAT(NameBuff, "doc/*.\\(txt\\|??x\\)");
+ if (gen_expand_wildcards(1, &NameBuff, &fcount,
+ &fnames, EW_FILE|EW_SILENT) == OK
+ && fcount > 0) {
+ for (fi = 0; fi < fcount && !got_int; ++fi) {
+ /* Skip files for a different language. */
+ if (lang != NULL
+ && STRNICMP(lang, fnames[fi]
+ + STRLEN(fnames[fi]) - 3, 2) != 0
+ && !(STRNICMP(lang, "en", 2) == 0
+ && STRNICMP("txt", fnames[fi]
+ + STRLEN(fnames[fi]) - 3, 3) == 0))
+ continue;
+ fd = mch_fopen((char *)fnames[fi], "r");
+ if (fd != NULL) {
+ 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);
+
+ /* remove trailing CR, LF, spaces, etc. */
+ 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)
+ vim_free(line);
+ break;
+ }
+ }
+ if (line != IObuff)
+ vim_free(line);
+ ++lnum;
+ line_breakcheck();
+ }
+ fclose(fd);
+ }
+ }
+ FreeWild(fcount, fnames);
+ }
+ }
+
+ 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 =
+ qi->qf_lists[qi->qf_curlist].qf_start;
+ qi->qf_lists[qi->qf_curlist].qf_index = 1;
+ }
+
+ if (p_cpo == empty_option)
+ p_cpo = save_cpo;
+ else
+ /* Darn, some plugin changed the value. */
+ free_string_option(save_cpo);
+
+ qf_update_buffer(qi);
+
+ 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 */
+ return;
+ }
+
+ /* Jump to first match. */
+ if (qi->qf_lists[qi->qf_curlist].qf_count > 0)
+ qf_jump(qi, 0, 0, FALSE);
+ else
+ EMSG2(_(e_nomatch2), eap->arg);
+
+ 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)
+ ll_free_all(&qi);
+ } else if (curwin->w_llist == NULL)
+ curwin->w_llist = qi;
+ }
+}
+
diff --git a/src/regexp.c b/src/regexp.c
new file mode 100644
index 0000000000..d1852f7ba9
--- /dev/null
+++ b/src/regexp.c
@@ -0,0 +1,7178 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * Handling of regular expressions: vim_regcomp(), vim_regexec(), vim_regsub()
+ *
+ * NOTICE:
+ *
+ * This is NOT the original regular expression code as written by Henry
+ * Spencer. This code has been modified specifically for use with the VIM
+ * editor, and should not be used separately from Vim. If you want a good
+ * regular expression library, get the original code. The copyright notice
+ * that follows is from the original.
+ *
+ * END NOTICE
+ *
+ * Copyright (c) 1986 by University of Toronto.
+ * Written by Henry Spencer. Not derived from licensed software.
+ *
+ * Permission is granted to anyone to use this software for any
+ * purpose on any computer system, and to redistribute it freely,
+ * subject to the following restrictions:
+ *
+ * 1. The author is not responsible for the consequences of use of
+ * this software, no matter how awful, even if they arise
+ * from defects in it.
+ *
+ * 2. The origin of this software must not be misrepresented, either
+ * by explicit claim or by omission.
+ *
+ * 3. Altered versions must be plainly marked as such, and must not
+ * be misrepresented as being the original software.
+ *
+ * Beware that some of this code is subtly aware of the way operator
+ * precedence is structured in regular expressions. Serious changes in
+ * regular-expression syntax might require a total rethink.
+ *
+ * Changes have been made by Tony Andrews, Olaf 'Rhialto' Seibert, Robert
+ * Webb, Ciaran McCreesh and Bram Moolenaar.
+ * Named character class support added by Walter Briscoe (1998 Jul 01)
+ */
+
+/* Uncomment the first if you do not want to see debugging logs or files
+ * related to regular expressions, even when compiling with -DDEBUG.
+ * Uncomment the second to get the regexp debugging. */
+/* #undef REGEXP_DEBUG */
+/* #define REGEXP_DEBUG */
+
+#include "vim.h"
+
+#ifdef REGEXP_DEBUG
+/* show/save debugging data when BT engine is used */
+# define BT_REGEXP_DUMP
+/* save the debugging data to a file instead of displaying it */
+# define BT_REGEXP_LOG
+# define BT_REGEXP_DEBUG_LOG
+# define BT_REGEXP_DEBUG_LOG_NAME "bt_regexp_debug.log"
+#endif
+
+/*
+ * The "internal use only" fields in regexp.h are present to pass info from
+ * compile to execute that permits the execute phase to run lots faster on
+ * simple cases. They are:
+ *
+ * regstart char that must begin a match; NUL if none obvious; Can be a
+ * multi-byte character.
+ * reganch is the match anchored (at beginning-of-line only)?
+ * regmust string (pointer into program) that match must include, or NULL
+ * regmlen length of regmust string
+ * regflags RF_ values or'ed together
+ *
+ * Regstart and reganch permit very fast decisions on suitable starting points
+ * for a match, cutting down the work a lot. Regmust permits fast rejection
+ * of lines that cannot possibly match. The regmust tests are costly enough
+ * that vim_regcomp() supplies a regmust only if the r.e. contains something
+ * potentially expensive (at present, the only such thing detected is * or +
+ * at the start of the r.e., which can involve a lot of backup). Regmlen is
+ * supplied because the test in vim_regexec() needs it and vim_regcomp() is
+ * computing it anyway.
+ */
+
+/*
+ * Structure for regexp "program". This is essentially a linear encoding
+ * of a nondeterministic finite-state machine (aka syntax charts or
+ * "railroad normal form" in parsing technology). Each node is an opcode
+ * plus a "next" pointer, possibly plus an operand. "Next" pointers of
+ * all nodes except BRANCH and BRACES_COMPLEX implement concatenation; a "next"
+ * pointer with a BRANCH on both ends of it is connecting two alternatives.
+ * (Here we have one of the subtle syntax dependencies: an individual BRANCH
+ * (as opposed to a collection of them) is never concatenated with anything
+ * because of operator precedence). The "next" pointer of a BRACES_COMPLEX
+ * node points to the node after the stuff to be repeated.
+ * The operand of some types of node is a literal string; for others, it is a
+ * node leading into a sub-FSM. In particular, the operand of a BRANCH node
+ * is the first node of the branch.
+ * (NB this is *not* a tree structure: the tail of the branch connects to the
+ * thing following the set of BRANCHes.)
+ *
+ * pattern is coded like:
+ *
+ * +-----------------+
+ * | V
+ * <aa>\|<bb> BRANCH <aa> BRANCH <bb> --> END
+ * | ^ | ^
+ * +------+ +----------+
+ *
+ *
+ * +------------------+
+ * V |
+ * <aa>* BRANCH BRANCH <aa> --> BACK BRANCH --> NOTHING --> END
+ * | | ^ ^
+ * | +---------------+ |
+ * +---------------------------------------------+
+ *
+ *
+ * +----------------------+
+ * V |
+ * <aa>\+ BRANCH <aa> --> BRANCH --> BACK BRANCH --> NOTHING --> END
+ * | | ^ ^
+ * | +-----------+ |
+ * +--------------------------------------------------+
+ *
+ *
+ * +-------------------------+
+ * V |
+ * <aa>\{} BRANCH BRACE_LIMITS --> BRACE_COMPLEX <aa> --> BACK END
+ * | | ^
+ * | +----------------+
+ * +-----------------------------------------------+
+ *
+ *
+ * <aa>\@!<bb> BRANCH NOMATCH <aa> --> END <bb> --> END
+ * | | ^ ^
+ * | +----------------+ |
+ * +--------------------------------+
+ *
+ * +---------+
+ * | V
+ * \z[abc] BRANCH BRANCH a BRANCH b BRANCH c BRANCH NOTHING --> END
+ * | | | | ^ ^
+ * | | | +-----+ |
+ * | | +----------------+ |
+ * | +---------------------------+ |
+ * +------------------------------------------------------+
+ *
+ * They all start with a BRANCH for "\|" alternatives, even when there is only
+ * one alternative.
+ */
+
+/*
+ * The opcodes are:
+ */
+
+/* definition number opnd? meaning */
+#define END 0 /* End of program or NOMATCH operand. */
+#define BOL 1 /* Match "" at beginning of line. */
+#define EOL 2 /* Match "" at end of line. */
+#define BRANCH 3 /* node Match this alternative, or the
+ * next... */
+#define BACK 4 /* Match "", "next" ptr points backward. */
+#define EXACTLY 5 /* str Match this string. */
+#define NOTHING 6 /* Match empty string. */
+#define STAR 7 /* node Match this (simple) thing 0 or more
+ * times. */
+#define PLUS 8 /* node Match this (simple) thing 1 or more
+ * times. */
+#define MATCH 9 /* node match the operand zero-width */
+#define NOMATCH 10 /* node check for no match with operand */
+#define BEHIND 11 /* node look behind for a match with operand */
+#define NOBEHIND 12 /* node look behind for no match with operand */
+#define SUBPAT 13 /* node match the operand here */
+#define BRACE_SIMPLE 14 /* node Match this (simple) thing between m and
+ * n times (\{m,n\}). */
+#define BOW 15 /* Match "" after [^a-zA-Z0-9_] */
+#define EOW 16 /* Match "" at [^a-zA-Z0-9_] */
+#define BRACE_LIMITS 17 /* nr nr define the min & max for BRACE_SIMPLE
+ * and BRACE_COMPLEX. */
+#define NEWL 18 /* Match line-break */
+#define BHPOS 19 /* End position for BEHIND or NOBEHIND */
+
+
+/* character classes: 20-48 normal, 50-78 include a line-break */
+#define ADD_NL 30
+#define FIRST_NL ANY + ADD_NL
+#define ANY 20 /* Match any one character. */
+#define ANYOF 21 /* str Match any character in this string. */
+#define ANYBUT 22 /* str Match any character not in this
+ * string. */
+#define IDENT 23 /* Match identifier char */
+#define SIDENT 24 /* Match identifier char but no digit */
+#define KWORD 25 /* Match keyword char */
+#define SKWORD 26 /* Match word char but no digit */
+#define FNAME 27 /* Match file name char */
+#define SFNAME 28 /* Match file name char but no digit */
+#define PRINT 29 /* Match printable char */
+#define SPRINT 30 /* Match printable char but no digit */
+#define WHITE 31 /* Match whitespace char */
+#define NWHITE 32 /* Match non-whitespace char */
+#define DIGIT 33 /* Match digit char */
+#define NDIGIT 34 /* Match non-digit char */
+#define HEX 35 /* Match hex char */
+#define NHEX 36 /* Match non-hex char */
+#define OCTAL 37 /* Match octal char */
+#define NOCTAL 38 /* Match non-octal char */
+#define WORD 39 /* Match word char */
+#define NWORD 40 /* Match non-word char */
+#define HEAD 41 /* Match head char */
+#define NHEAD 42 /* Match non-head char */
+#define ALPHA 43 /* Match alpha char */
+#define NALPHA 44 /* Match non-alpha char */
+#define LOWER 45 /* Match lowercase char */
+#define NLOWER 46 /* Match non-lowercase char */
+#define UPPER 47 /* Match uppercase char */
+#define NUPPER 48 /* Match non-uppercase char */
+#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 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 */
+
+#define NOPEN 150 /* Mark this point in input as start of
+ \%( subexpr. */
+#define NCLOSE 151 /* Analogous to NOPEN. */
+
+#define MULTIBYTECODE 200 /* mbc Match one multi-byte character */
+#define RE_BOF 201 /* Match "" at beginning of file. */
+#define RE_EOF 202 /* Match "" at end of file. */
+#define CURSOR 203 /* Match location of cursor. */
+
+#define RE_LNUM 204 /* nr cmp Match line number */
+#define RE_COL 205 /* nr cmp Match column number */
+#define RE_VCOL 206 /* nr cmp Match virtual column number */
+
+#define RE_MARK 207 /* mark cmp Match mark position */
+#define RE_VISUAL 208 /* Match Visual area */
+
+/*
+ * Magic characters have a special meaning, they don't match literally.
+ * Magic characters are negative. This separates them from literal characters
+ * (possibly multi-byte). Only ASCII characters can be Magic.
+ */
+#define Magic(x) ((int)(x) - 256)
+#define un_Magic(x) ((x) + 256)
+#define is_Magic(x) ((x) < 0)
+
+static int no_Magic __ARGS((int x));
+static int toggle_Magic __ARGS((int x));
+
+static int no_Magic(x)
+int x;
+{
+ if (is_Magic(x))
+ return un_Magic(x);
+ return x;
+}
+
+static int toggle_Magic(x)
+int x;
+{
+ if (is_Magic(x))
+ return un_Magic(x);
+ return Magic(x);
+}
+
+/*
+ * The first byte of the regexp internal "program" is actually this magic
+ * number; the start node begins in the second byte. It's used to catch the
+ * most severe mutilation of the program by the caller.
+ */
+
+#define REGMAGIC 0234
+
+/*
+ * Opcode notes:
+ *
+ * BRANCH The set of branches constituting a single choice are hooked
+ * together with their "next" pointers, since precedence prevents
+ * anything being concatenated to any individual branch. The
+ * "next" pointer of the last BRANCH in a choice points to the
+ * thing following the whole choice. This is also where the
+ * final "next" pointer of each individual branch points; each
+ * branch starts with the operand node of a BRANCH node.
+ *
+ * BACK Normal "next" pointers all implicitly point forward; BACK
+ * exists to make loop structures possible.
+ *
+ * STAR,PLUS '=', and complex '*' and '+', are implemented as circular
+ * BRANCH structures using BACK. Simple cases (one character
+ * per match) are implemented with STAR and PLUS for speed
+ * and to minimize recursive plunges.
+ *
+ * BRACE_LIMITS This is always followed by a BRACE_SIMPLE or BRACE_COMPLEX
+ * node, and defines the min and max limits to be used for that
+ * node.
+ *
+ * MOPEN,MCLOSE ...are numbered at compile time.
+ * ZOPEN,ZCLOSE ...ditto
+ */
+
+/*
+ * A node is one char of opcode followed by two chars of "next" pointer.
+ * "Next" pointers are stored as two 8-bit bytes, high order first. The
+ * value is a positive offset from the opcode of the node containing it.
+ * An operand, if any, simply follows the node. (Note that much of the
+ * code generation knows about this implicit relationship.)
+ *
+ * Using two bytes for the "next" pointer is vast overkill for most things,
+ * but allows patterns to get big without disasters.
+ */
+#define OP(p) ((int)*(p))
+#define NEXT(p) (((*((p) + 1) & 0377) << 8) + (*((p) + 2) & 0377))
+#define OPERAND(p) ((p) + 3)
+/* Obtain an operand that was stored as four bytes, MSB first. */
+#define OPERAND_MIN(p) (((long)(p)[3] << 24) + ((long)(p)[4] << 16) \
+ + ((long)(p)[5] << 8) + (long)(p)[6])
+/* Obtain a second operand stored as four bytes. */
+#define OPERAND_MAX(p) OPERAND_MIN((p) + 4)
+/* Obtain a second single-byte operand stored after a four bytes operand. */
+#define OPERAND_CMP(p) (p)[7]
+
+/*
+ * Utility definitions.
+ */
+#define UCHARAT(p) ((int)*(char_u *)(p))
+
+/* 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_ONE_RET_NULL EMSG2_RET_NULL(_( \
+ "E369: invalid item in %s%%[]"), reg_magic == MAGIC_ALL)
+
+#define MAX_LIMIT (32767L << 16L)
+
+static int re_multi_type __ARGS((int));
+static int cstrncmp __ARGS((char_u *s1, char_u *s2, int *n));
+static char_u *cstrchr __ARGS((char_u *, int));
+
+#ifdef BT_REGEXP_DUMP
+static void regdump __ARGS((char_u *, bt_regprog_T *));
+#endif
+#ifdef REGEXP_DEBUG
+static char_u *regprop __ARGS((char_u *));
+#endif
+
+static char_u e_missingbracket[] = N_("E769: Missing ] after %s[");
+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_missing_sb[] = N_("E69: Missing ] after %s%%[");
+static char_u e_empty_sb[] = N_("E70: Empty %s%%[]");
+#define NOT_MULTI 0
+#define MULTI_ONE 1
+#define MULTI_MULT 2
+/*
+ * Return NOT_MULTI if c is not a "multi" operator.
+ * Return MULTI_ONE if c is a single "multi" operator.
+ * Return MULTI_MULT if c is a multi "multi" operator.
+ */
+static int re_multi_type(c)
+int c;
+{
+ if (c == Magic('@') || c == Magic('=') || c == Magic('?'))
+ return MULTI_ONE;
+ if (c == Magic('*') || c == Magic('+') || c == Magic('{'))
+ return MULTI_MULT;
+ return NOT_MULTI;
+}
+
+/*
+ * Flags to be passed up and down.
+ */
+#define HASWIDTH 0x1 /* Known never to match null string. */
+#define SIMPLE 0x2 /* Simple enough to be STAR/PLUS operand. */
+#define SPSTART 0x4 /* Starts with * or +. */
+#define HASNL 0x8 /* Contains some \n. */
+#define HASLOOKBH 0x10 /* Contains "\@<=" or "\@<!". */
+#define WORST 0 /* Worst case. */
+
+/*
+ * When regcode is set to this value, code is not emitted and size is computed
+ * instead.
+ */
+#define JUST_CALC_SIZE ((char_u *) -1)
+
+static char_u *reg_prev_sub = NULL;
+
+/*
+ * REGEXP_INRANGE contains all characters which are always special in a []
+ * range after '\'.
+ * REGEXP_ABBR contains all characters which act as abbreviations after '\'.
+ * These are:
+ * \n - New line (NL).
+ * \r - Carriage Return (CR).
+ * \t - Tab (TAB).
+ * \e - Escape (ESC).
+ * \b - Backspace (Ctrl_H).
+ * \d - Character code in decimal, eg \d123
+ * \o - Character code in octal, eg \o80
+ * \x - Character code in hex, eg \x4a
+ * \u - Multibyte character code, eg \u20ac
+ * \U - Long multibyte character code, eg \U12345678
+ */
+static char_u REGEXP_INRANGE[] = "]^-n\\";
+static char_u REGEXP_ABBR[] = "nrtebdoxuU";
+
+static int backslash_trans __ARGS((int c));
+static int get_char_class __ARGS((char_u **pp));
+static int get_equi_class __ARGS((char_u **pp));
+static void reg_equi_class __ARGS((int c));
+static int get_coll_element __ARGS((char_u **pp));
+static char_u *skip_anyof __ARGS((char_u *p));
+static void init_class_tab __ARGS((void));
+
+/*
+ * Translate '\x' to its control character, except "\n", which is Magic.
+ */
+static int backslash_trans(c)
+int c;
+{
+ switch (c) {
+ case 'r': return CAR;
+ case 't': return TAB;
+ case 'e': return ESC;
+ case 'b': return BS;
+ }
+ return c;
+}
+
+/*
+ * Check for a character class name "[:name:]". "pp" points to the '['.
+ * Returns one of the CLASS_ items. CLASS_NONE means that no item was
+ * recognized. Otherwise "pp" is advanced to after the item.
+ */
+static int get_char_class(pp)
+char_u **pp;
+{
+ static const char *(class_names[]) =
+ {
+ "alnum:]",
+#define CLASS_ALNUM 0
+ "alpha:]",
+#define CLASS_ALPHA 1
+ "blank:]",
+#define CLASS_BLANK 2
+ "cntrl:]",
+#define CLASS_CNTRL 3
+ "digit:]",
+#define CLASS_DIGIT 4
+ "graph:]",
+#define CLASS_GRAPH 5
+ "lower:]",
+#define CLASS_LOWER 6
+ "print:]",
+#define CLASS_PRINT 7
+ "punct:]",
+#define CLASS_PUNCT 8
+ "space:]",
+#define CLASS_SPACE 9
+ "upper:]",
+#define CLASS_UPPER 10
+ "xdigit:]",
+#define CLASS_XDIGIT 11
+ "tab:]",
+#define CLASS_TAB 12
+ "return:]",
+#define CLASS_RETURN 13
+ "backspace:]",
+#define CLASS_BACKSPACE 14
+ "escape:]",
+#define CLASS_ESCAPE 15
+ };
+#define CLASS_NONE 99
+ int i;
+
+ if ((*pp)[1] == ':') {
+ for (i = 0; i < (int)(sizeof(class_names) / sizeof(*class_names)); ++i)
+ if (STRNCMP(*pp + 2, class_names[i], STRLEN(class_names[i])) == 0) {
+ *pp += STRLEN(class_names[i]) + 2;
+ return i;
+ }
+ }
+ return CLASS_NONE;
+}
+
+/*
+ * Specific version of character class functions.
+ * Using a table to keep this fast.
+ */
+static short class_tab[256];
+
+#define RI_DIGIT 0x01
+#define RI_HEX 0x02
+#define RI_OCTAL 0x04
+#define RI_WORD 0x08
+#define RI_HEAD 0x10
+#define RI_ALPHA 0x20
+#define RI_LOWER 0x40
+#define RI_UPPER 0x80
+#define RI_WHITE 0x100
+
+static void init_class_tab() {
+ int i;
+ static int done = FALSE;
+
+ if (done)
+ return;
+
+ for (i = 0; i < 256; ++i) {
+ if (i >= '0' && i <= '7')
+ class_tab[i] = RI_DIGIT + RI_HEX + RI_OCTAL + RI_WORD;
+ else if (i >= '8' && i <= '9')
+ class_tab[i] = RI_DIGIT + RI_HEX + RI_WORD;
+ else if (i >= 'a' && i <= 'f')
+ class_tab[i] = RI_HEX + RI_WORD + RI_HEAD + RI_ALPHA + RI_LOWER;
+ else if (i >= 'g' && i <= 'z')
+ class_tab[i] = RI_WORD + RI_HEAD + RI_ALPHA + RI_LOWER;
+ else if (i >= 'A' && i <= 'F')
+ class_tab[i] = RI_HEX + RI_WORD + RI_HEAD + RI_ALPHA + RI_UPPER;
+ else if (i >= 'G' && i <= 'Z')
+ class_tab[i] = RI_WORD + RI_HEAD + RI_ALPHA + RI_UPPER;
+ else if (i == '_')
+ class_tab[i] = RI_WORD + RI_HEAD;
+ else
+ class_tab[i] = 0;
+ }
+ class_tab[' '] |= RI_WHITE;
+ class_tab['\t'] |= RI_WHITE;
+ done = TRUE;
+}
+
+# define ri_digit(c) (c < 0x100 && (class_tab[c] & RI_DIGIT))
+# define ri_hex(c) (c < 0x100 && (class_tab[c] & RI_HEX))
+# define ri_octal(c) (c < 0x100 && (class_tab[c] & RI_OCTAL))
+# define ri_word(c) (c < 0x100 && (class_tab[c] & RI_WORD))
+# define ri_head(c) (c < 0x100 && (class_tab[c] & RI_HEAD))
+# define ri_alpha(c) (c < 0x100 && (class_tab[c] & RI_ALPHA))
+# define ri_lower(c) (c < 0x100 && (class_tab[c] & RI_LOWER))
+# define ri_upper(c) (c < 0x100 && (class_tab[c] & RI_UPPER))
+# define ri_white(c) (c < 0x100 && (class_tab[c] & RI_WHITE))
+
+/* flags for regflags */
+#define RF_ICASE 1 /* ignore case */
+#define RF_NOICASE 2 /* don't ignore case */
+#define RF_HASNL 4 /* can match a NL */
+#define RF_ICOMBINE 8 /* ignore combining characters */
+#define RF_LOOKBH 16 /* uses "\@<=" or "\@<!" */
+
+/*
+ * Global work variables for vim_regcomp().
+ */
+
+static char_u *regparse; /* Input-scan pointer. */
+static int prevchr_len; /* byte length of previous char */
+static int num_complex_braces; /* Complex \{...} count */
+static int regnpar; /* () count. */
+static int regnzpar; /* \z() count. */
+static int re_has_z; /* \z item detected */
+static char_u *regcode; /* Code-emit pointer, or JUST_CALC_SIZE */
+static long regsize; /* Code size. */
+static int reg_toolong; /* TRUE when offset out of range */
+static char_u had_endbrace[NSUBEXP]; /* flags, TRUE if end of () found */
+static unsigned regflags; /* RF_ flags for prog */
+static long brace_min[10]; /* Minimums for complex brace repeats */
+static long brace_max[10]; /* Maximums for complex brace repeats */
+static int brace_count[10]; /* Current counts for complex brace repeats */
+static int had_eol; /* TRUE when EOL found by vim_regcomp() */
+static int one_exactly = FALSE; /* only do one char for EXACTLY */
+
+static int reg_magic; /* magicness of the pattern: */
+#define MAGIC_NONE 1 /* "\V" very unmagic */
+#define MAGIC_OFF 2 /* "\M" or 'magic' off */
+#define MAGIC_ON 3 /* "\m" or 'magic' */
+#define MAGIC_ALL 4 /* "\v" very magic */
+
+static int reg_string; /* matching with a string instead of a buffer
+ line */
+static int reg_strict; /* "[abc" is illegal */
+
+/*
+ * META contains all characters that may be magic, except '^' and '$'.
+ */
+
+/* META[] is used often enough to justify turning it into a table. */
+static char_u META_flags[] = {
+ 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, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0,
+ /* 1 2 3 4 5 6 7 8 9 < = > ? */
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1,
+ /* @ A C D F H I K L M O */
+ 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1,
+ /* P S U V W X Z [ _ */
+ 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1,
+ /* a c d f h i k l m n o */
+ 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1,
+ /* p s u v w x z { | ~ */
+ 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1
+};
+
+static int curchr; /* currently parsed character */
+/* Previous character. Note: prevchr is sometimes -1 when we are not at the
+ * start, eg in /[ ^I]^ the pattern was never found even if it existed,
+ * because ^ was taken to be magic -- webb */
+static int prevchr;
+static int prevprevchr; /* previous-previous character */
+static int nextchr; /* used for ungetchr() */
+
+/* arguments for reg() */
+#define REG_NOPAREN 0 /* toplevel reg() */
+#define REG_PAREN 1 /* \(\) */
+#define REG_ZPAREN 2 /* \z(\) */
+#define REG_NPAREN 3 /* \%(\) */
+
+typedef struct {
+ char_u *regparse;
+ int prevchr_len;
+ int curchr;
+ int prevchr;
+ int prevprevchr;
+ int nextchr;
+ int at_start;
+ int prev_at_start;
+ int regnpar;
+} parse_state_T;
+
+/*
+ * Forward declarations for vim_regcomp()'s friends.
+ */
+static void initchr __ARGS((char_u *));
+static void save_parse_state __ARGS((parse_state_T *ps));
+static void restore_parse_state __ARGS((parse_state_T *ps));
+static int getchr __ARGS((void));
+static void skipchr_keepstart __ARGS((void));
+static int peekchr __ARGS((void));
+static void skipchr __ARGS((void));
+static void ungetchr __ARGS((void));
+static int gethexchrs __ARGS((int maxinputlen));
+static int getoctchrs __ARGS((void));
+static int getdecchrs __ARGS((void));
+static int coll_get_char __ARGS((void));
+static void regcomp_start __ARGS((char_u *expr, int flags));
+static char_u *reg __ARGS((int, int *));
+static char_u *regbranch __ARGS((int *flagp));
+static char_u *regconcat __ARGS((int *flagp));
+static char_u *regpiece __ARGS((int *));
+static char_u *regatom __ARGS((int *));
+static char_u *regnode __ARGS((int));
+static int use_multibytecode __ARGS((int c));
+static int prog_magic_wrong __ARGS((void));
+static char_u *regnext __ARGS((char_u *));
+static void regc __ARGS((int b));
+static void regmbc __ARGS((int c));
+# define REGMBC(x) regmbc(x);
+# define CASEMBC(x) case x:
+static void reginsert __ARGS((int, char_u *));
+static void reginsert_nr __ARGS((int op, long val, char_u *opnd));
+static void reginsert_limits __ARGS((int, long, long, char_u *));
+static char_u *re_put_long __ARGS((char_u *pr, long_u val));
+static int read_limits __ARGS((long *, long *));
+static void regtail __ARGS((char_u *, char_u *));
+static void regoptail __ARGS((char_u *, char_u *));
+
+static regengine_T bt_regengine;
+static regengine_T nfa_regengine;
+
+/*
+ * Return TRUE if compiled regular expression "prog" can match a line break.
+ */
+int re_multiline(prog)
+regprog_T *prog;
+{
+ return prog->regflags & RF_HASNL;
+}
+
+/*
+ * Return TRUE if compiled regular expression "prog" looks before the start
+ * position (pattern contains "\@<=" or "\@<!").
+ */
+int re_lookbehind(prog)
+regprog_T *prog;
+{
+ return prog->regflags & RF_LOOKBH;
+}
+
+/*
+ * Check for an equivalence class name "[=a=]". "pp" points to the '['.
+ * Returns a character representing the class. Zero means that no item was
+ * recognized. Otherwise "pp" is advanced to after the item.
+ */
+static int get_equi_class(pp)
+char_u **pp;
+{
+ int c;
+ int l = 1;
+ char_u *p = *pp;
+
+ if (p[1] == '=') {
+ if (has_mbyte)
+ l = (*mb_ptr2len)(p + 2);
+ if (p[l + 2] == '=' && p[l + 3] == ']') {
+ if (has_mbyte)
+ c = mb_ptr2char(p + 2);
+ else
+ c = p[2];
+ *pp += l + 4;
+ return c;
+ }
+ }
+ return 0;
+}
+
+
+/*
+ * Produce the bytes for equivalence class "c".
+ * Currently only handles latin1, latin9 and utf-8.
+ * NOTE: When changing this function, also change nfa_emit_equi_class()
+ */
+static void reg_equi_class(c)
+int c;
+{
+ if (enc_utf8 || STRCMP(p_enc, "latin1") == 0
+ || STRCMP(p_enc, "iso-8859-15") == 0) {
+ switch (c) {
+ case 'A': case '\300': case '\301': case '\302':
+ CASEMBC(0x100) CASEMBC(0x102) CASEMBC(0x104) CASEMBC(0x1cd)
+ CASEMBC(0x1de) CASEMBC(0x1e0) CASEMBC(0x1ea2)
+ case '\303': case '\304': case '\305':
+ regmbc('A'); regmbc('\300'); regmbc('\301');
+ regmbc('\302'); regmbc('\303'); regmbc('\304');
+ regmbc('\305');
+ REGMBC(0x100) REGMBC(0x102) REGMBC(0x104)
+ REGMBC(0x1cd) REGMBC(0x1de) REGMBC(0x1e0)
+ REGMBC(0x1ea2)
+ return;
+ case 'B': CASEMBC(0x1e02) CASEMBC(0x1e06)
+ regmbc('B'); REGMBC(0x1e02) REGMBC(0x1e06)
+ return;
+ case 'C': case '\307':
+ CASEMBC(0x106) CASEMBC(0x108) CASEMBC(0x10a) CASEMBC(0x10c)
+ regmbc('C'); regmbc('\307');
+ REGMBC(0x106) REGMBC(0x108) REGMBC(0x10a)
+ REGMBC(0x10c)
+ return;
+ case 'D': CASEMBC(0x10e) CASEMBC(0x110) CASEMBC(0x1e0a)
+ CASEMBC(0x1e0e) CASEMBC(0x1e10)
+ regmbc('D'); REGMBC(0x10e) REGMBC(0x110)
+ REGMBC(0x1e0a) REGMBC(0x1e0e) REGMBC(0x1e10)
+ return;
+ case 'E': case '\310': case '\311': case '\312': case '\313':
+ CASEMBC(0x112) CASEMBC(0x114) CASEMBC(0x116) CASEMBC(0x118)
+ CASEMBC(0x11a) CASEMBC(0x1eba) CASEMBC(0x1ebc)
+ regmbc('E'); regmbc('\310'); regmbc('\311');
+ regmbc('\312'); regmbc('\313');
+ REGMBC(0x112) REGMBC(0x114) REGMBC(0x116)
+ REGMBC(0x118) REGMBC(0x11a) REGMBC(0x1eba)
+ REGMBC(0x1ebc)
+ return;
+ case 'F': CASEMBC(0x1e1e)
+ regmbc('F'); REGMBC(0x1e1e)
+ return;
+ case 'G': CASEMBC(0x11c) CASEMBC(0x11e) CASEMBC(0x120)
+ CASEMBC(0x122) CASEMBC(0x1e4) CASEMBC(0x1e6) CASEMBC(0x1f4)
+ CASEMBC(0x1e20)
+ regmbc('G'); REGMBC(0x11c) REGMBC(0x11e)
+ REGMBC(0x120) REGMBC(0x122) REGMBC(0x1e4)
+ REGMBC(0x1e6) REGMBC(0x1f4) REGMBC(0x1e20)
+ return;
+ case 'H': CASEMBC(0x124) CASEMBC(0x126) CASEMBC(0x1e22)
+ CASEMBC(0x1e26) CASEMBC(0x1e28)
+ regmbc('H'); REGMBC(0x124) REGMBC(0x126)
+ REGMBC(0x1e22) REGMBC(0x1e26) REGMBC(0x1e28)
+ return;
+ case 'I': case '\314': case '\315': case '\316': case '\317':
+ CASEMBC(0x128) CASEMBC(0x12a) CASEMBC(0x12c) CASEMBC(0x12e)
+ CASEMBC(0x130) CASEMBC(0x1cf) CASEMBC(0x1ec8)
+ regmbc('I'); regmbc('\314'); regmbc('\315');
+ regmbc('\316'); regmbc('\317');
+ REGMBC(0x128) REGMBC(0x12a) REGMBC(0x12c)
+ REGMBC(0x12e) REGMBC(0x130) REGMBC(0x1cf)
+ REGMBC(0x1ec8)
+ return;
+ case 'J': CASEMBC(0x134)
+ regmbc('J'); REGMBC(0x134)
+ return;
+ case 'K': CASEMBC(0x136) CASEMBC(0x1e8) CASEMBC(0x1e30)
+ CASEMBC(0x1e34)
+ regmbc('K'); REGMBC(0x136) REGMBC(0x1e8)
+ REGMBC(0x1e30) REGMBC(0x1e34)
+ return;
+ case 'L': CASEMBC(0x139) CASEMBC(0x13b) CASEMBC(0x13d)
+ CASEMBC(0x13f) CASEMBC(0x141) CASEMBC(0x1e3a)
+ regmbc('L'); REGMBC(0x139) REGMBC(0x13b)
+ REGMBC(0x13d) REGMBC(0x13f) REGMBC(0x141)
+ REGMBC(0x1e3a)
+ return;
+ case 'M': CASEMBC(0x1e3e) CASEMBC(0x1e40)
+ regmbc('M'); REGMBC(0x1e3e) REGMBC(0x1e40)
+ return;
+ case 'N': case '\321':
+ CASEMBC(0x143) CASEMBC(0x145) CASEMBC(0x147) CASEMBC(0x1e44)
+ CASEMBC(0x1e48)
+ regmbc('N'); regmbc('\321');
+ REGMBC(0x143) REGMBC(0x145) REGMBC(0x147)
+ REGMBC(0x1e44) REGMBC(0x1e48)
+ return;
+ case 'O': case '\322': case '\323': case '\324': case '\325':
+ case '\326': case '\330':
+ CASEMBC(0x14c) CASEMBC(0x14e) CASEMBC(0x150) CASEMBC(0x1a0)
+ CASEMBC(0x1d1) CASEMBC(0x1ea) CASEMBC(0x1ec) CASEMBC(0x1ece)
+ regmbc('O'); regmbc('\322'); regmbc('\323');
+ regmbc('\324'); regmbc('\325'); regmbc('\326');
+ regmbc('\330');
+ REGMBC(0x14c) REGMBC(0x14e) REGMBC(0x150)
+ REGMBC(0x1a0) REGMBC(0x1d1) REGMBC(0x1ea)
+ REGMBC(0x1ec) REGMBC(0x1ece)
+ return;
+ case 'P': case 0x1e54: case 0x1e56:
+ regmbc('P'); REGMBC(0x1e54) REGMBC(0x1e56)
+ return;
+ case 'R': CASEMBC(0x154) CASEMBC(0x156) CASEMBC(0x158)
+ CASEMBC(0x1e58) CASEMBC(0x1e5e)
+ regmbc('R'); REGMBC(0x154) REGMBC(0x156) REGMBC(0x158)
+ REGMBC(0x1e58) REGMBC(0x1e5e)
+ return;
+ case 'S': CASEMBC(0x15a) CASEMBC(0x15c) CASEMBC(0x15e)
+ CASEMBC(0x160) CASEMBC(0x1e60)
+ regmbc('S'); REGMBC(0x15a) REGMBC(0x15c)
+ REGMBC(0x15e) REGMBC(0x160) REGMBC(0x1e60)
+ return;
+ case 'T': CASEMBC(0x162) CASEMBC(0x164) CASEMBC(0x166)
+ CASEMBC(0x1e6a) CASEMBC(0x1e6e)
+ regmbc('T'); REGMBC(0x162) REGMBC(0x164)
+ REGMBC(0x166) REGMBC(0x1e6a) REGMBC(0x1e6e)
+ return;
+ case 'U': case '\331': case '\332': case '\333': case '\334':
+ CASEMBC(0x168) CASEMBC(0x16a) CASEMBC(0x16c) CASEMBC(0x16e)
+ CASEMBC(0x170) CASEMBC(0x172) CASEMBC(0x1af) CASEMBC(0x1d3)
+ CASEMBC(0x1ee6)
+ regmbc('U'); regmbc('\331'); regmbc('\332');
+ regmbc('\333'); regmbc('\334');
+ REGMBC(0x168) REGMBC(0x16a) REGMBC(0x16c)
+ REGMBC(0x16e) REGMBC(0x170) REGMBC(0x172)
+ REGMBC(0x1af) REGMBC(0x1d3) REGMBC(0x1ee6)
+ return;
+ case 'V': CASEMBC(0x1e7c)
+ regmbc('V'); REGMBC(0x1e7c)
+ return;
+ case 'W': CASEMBC(0x174) CASEMBC(0x1e80) CASEMBC(0x1e82)
+ CASEMBC(0x1e84) CASEMBC(0x1e86)
+ regmbc('W'); REGMBC(0x174) REGMBC(0x1e80)
+ REGMBC(0x1e82) REGMBC(0x1e84) REGMBC(0x1e86)
+ return;
+ case 'X': CASEMBC(0x1e8a) CASEMBC(0x1e8c)
+ regmbc('X'); REGMBC(0x1e8a) REGMBC(0x1e8c)
+ return;
+ case 'Y': case '\335':
+ CASEMBC(0x176) CASEMBC(0x178) CASEMBC(0x1e8e) CASEMBC(0x1ef2)
+ CASEMBC(0x1ef6) CASEMBC(0x1ef8)
+ regmbc('Y'); regmbc('\335');
+ REGMBC(0x176) REGMBC(0x178) REGMBC(0x1e8e)
+ REGMBC(0x1ef2) REGMBC(0x1ef6) REGMBC(0x1ef8)
+ return;
+ case 'Z': CASEMBC(0x179) CASEMBC(0x17b) CASEMBC(0x17d)
+ CASEMBC(0x1b5) CASEMBC(0x1e90) CASEMBC(0x1e94)
+ regmbc('Z'); REGMBC(0x179) REGMBC(0x17b)
+ REGMBC(0x17d) REGMBC(0x1b5) REGMBC(0x1e90)
+ REGMBC(0x1e94)
+ return;
+ case 'a': case '\340': case '\341': case '\342':
+ case '\343': case '\344': case '\345':
+ CASEMBC(0x101) CASEMBC(0x103) CASEMBC(0x105) CASEMBC(0x1ce)
+ CASEMBC(0x1df) CASEMBC(0x1e1) CASEMBC(0x1ea3)
+ regmbc('a'); regmbc('\340'); regmbc('\341');
+ regmbc('\342'); regmbc('\343'); regmbc('\344');
+ regmbc('\345');
+ REGMBC(0x101) REGMBC(0x103) REGMBC(0x105)
+ REGMBC(0x1ce) REGMBC(0x1df) REGMBC(0x1e1)
+ REGMBC(0x1ea3)
+ return;
+ case 'b': CASEMBC(0x1e03) CASEMBC(0x1e07)
+ regmbc('b'); REGMBC(0x1e03) REGMBC(0x1e07)
+ return;
+ case 'c': case '\347':
+ CASEMBC(0x107) CASEMBC(0x109) CASEMBC(0x10b) CASEMBC(0x10d)
+ regmbc('c'); regmbc('\347');
+ REGMBC(0x107) REGMBC(0x109) REGMBC(0x10b)
+ REGMBC(0x10d)
+ return;
+ case 'd': CASEMBC(0x10f) CASEMBC(0x111) CASEMBC(0x1d0b)
+ CASEMBC(0x1e11)
+ regmbc('d'); REGMBC(0x10f) REGMBC(0x111)
+ REGMBC(0x1e0b) REGMBC(0x01e0f) REGMBC(0x1e11)
+ return;
+ case 'e': case '\350': case '\351': case '\352': case '\353':
+ CASEMBC(0x113) CASEMBC(0x115) CASEMBC(0x117) CASEMBC(0x119)
+ CASEMBC(0x11b) CASEMBC(0x1ebb) CASEMBC(0x1ebd)
+ regmbc('e'); regmbc('\350'); regmbc('\351');
+ regmbc('\352'); regmbc('\353');
+ REGMBC(0x113) REGMBC(0x115) REGMBC(0x117)
+ REGMBC(0x119) REGMBC(0x11b) REGMBC(0x1ebb)
+ REGMBC(0x1ebd)
+ return;
+ case 'f': CASEMBC(0x1e1f)
+ regmbc('f'); REGMBC(0x1e1f)
+ return;
+ case 'g': CASEMBC(0x11d) CASEMBC(0x11f) CASEMBC(0x121)
+ CASEMBC(0x123) CASEMBC(0x1e5) CASEMBC(0x1e7) CASEMBC(0x1f5)
+ CASEMBC(0x1e21)
+ regmbc('g'); REGMBC(0x11d) REGMBC(0x11f)
+ REGMBC(0x121) REGMBC(0x123) REGMBC(0x1e5)
+ REGMBC(0x1e7) REGMBC(0x1f5) REGMBC(0x1e21)
+ return;
+ case 'h': CASEMBC(0x125) CASEMBC(0x127) CASEMBC(0x1e23)
+ CASEMBC(0x1e27) CASEMBC(0x1e29) CASEMBC(0x1e96)
+ regmbc('h'); REGMBC(0x125) REGMBC(0x127)
+ REGMBC(0x1e23) REGMBC(0x1e27) REGMBC(0x1e29)
+ REGMBC(0x1e96)
+ return;
+ case 'i': case '\354': case '\355': case '\356': case '\357':
+ CASEMBC(0x129) CASEMBC(0x12b) CASEMBC(0x12d) CASEMBC(0x12f)
+ CASEMBC(0x1d0) CASEMBC(0x1ec9)
+ regmbc('i'); regmbc('\354'); regmbc('\355');
+ regmbc('\356'); regmbc('\357');
+ REGMBC(0x129) REGMBC(0x12b) REGMBC(0x12d)
+ REGMBC(0x12f) REGMBC(0x1d0) REGMBC(0x1ec9)
+ return;
+ case 'j': CASEMBC(0x135) CASEMBC(0x1f0)
+ regmbc('j'); REGMBC(0x135) REGMBC(0x1f0)
+ return;
+ case 'k': CASEMBC(0x137) CASEMBC(0x1e9) CASEMBC(0x1e31)
+ CASEMBC(0x1e35)
+ regmbc('k'); REGMBC(0x137) REGMBC(0x1e9)
+ REGMBC(0x1e31) REGMBC(0x1e35)
+ return;
+ case 'l': CASEMBC(0x13a) CASEMBC(0x13c) CASEMBC(0x13e)
+ CASEMBC(0x140) CASEMBC(0x142) CASEMBC(0x1e3b)
+ regmbc('l'); REGMBC(0x13a) REGMBC(0x13c)
+ REGMBC(0x13e) REGMBC(0x140) REGMBC(0x142)
+ REGMBC(0x1e3b)
+ return;
+ case 'm': CASEMBC(0x1e3f) CASEMBC(0x1e41)
+ regmbc('m'); REGMBC(0x1e3f) REGMBC(0x1e41)
+ return;
+ case 'n': case '\361':
+ CASEMBC(0x144) CASEMBC(0x146) CASEMBC(0x148) CASEMBC(0x149)
+ CASEMBC(0x1e45) CASEMBC(0x1e49)
+ regmbc('n'); regmbc('\361');
+ REGMBC(0x144) REGMBC(0x146) REGMBC(0x148)
+ REGMBC(0x149) REGMBC(0x1e45) REGMBC(0x1e49)
+ return;
+ case 'o': case '\362': case '\363': case '\364': case '\365':
+ case '\366': case '\370':
+ CASEMBC(0x14d) CASEMBC(0x14f) CASEMBC(0x151) CASEMBC(0x1a1)
+ CASEMBC(0x1d2) CASEMBC(0x1eb) CASEMBC(0x1ed) CASEMBC(0x1ecf)
+ regmbc('o'); regmbc('\362'); regmbc('\363');
+ regmbc('\364'); regmbc('\365'); regmbc('\366');
+ regmbc('\370');
+ REGMBC(0x14d) REGMBC(0x14f) REGMBC(0x151)
+ REGMBC(0x1a1) REGMBC(0x1d2) REGMBC(0x1eb)
+ REGMBC(0x1ed) REGMBC(0x1ecf)
+ return;
+ case 'p': CASEMBC(0x1e55) CASEMBC(0x1e57)
+ regmbc('p'); REGMBC(0x1e55) REGMBC(0x1e57)
+ return;
+ case 'r': CASEMBC(0x155) CASEMBC(0x157) CASEMBC(0x159)
+ CASEMBC(0x1e59) CASEMBC(0x1e5f)
+ regmbc('r'); REGMBC(0x155) REGMBC(0x157) REGMBC(0x159)
+ REGMBC(0x1e59) REGMBC(0x1e5f)
+ return;
+ case 's': CASEMBC(0x15b) CASEMBC(0x15d) CASEMBC(0x15f)
+ CASEMBC(0x161) CASEMBC(0x1e61)
+ regmbc('s'); REGMBC(0x15b) REGMBC(0x15d)
+ REGMBC(0x15f) REGMBC(0x161) REGMBC(0x1e61)
+ return;
+ case 't': CASEMBC(0x163) CASEMBC(0x165) CASEMBC(0x167)
+ CASEMBC(0x1e6b) CASEMBC(0x1e6f) CASEMBC(0x1e97)
+ regmbc('t'); REGMBC(0x163) REGMBC(0x165) REGMBC(0x167)
+ REGMBC(0x1e6b) REGMBC(0x1e6f) REGMBC(0x1e97)
+ return;
+ case 'u': case '\371': case '\372': case '\373': case '\374':
+ CASEMBC(0x169) CASEMBC(0x16b) CASEMBC(0x16d) CASEMBC(0x16f)
+ CASEMBC(0x171) CASEMBC(0x173) CASEMBC(0x1b0) CASEMBC(0x1d4)
+ CASEMBC(0x1ee7)
+ regmbc('u'); regmbc('\371'); regmbc('\372');
+ regmbc('\373'); regmbc('\374');
+ REGMBC(0x169) REGMBC(0x16b) REGMBC(0x16d)
+ REGMBC(0x16f) REGMBC(0x171) REGMBC(0x173)
+ REGMBC(0x1b0) REGMBC(0x1d4) REGMBC(0x1ee7)
+ return;
+ case 'v': CASEMBC(0x1e7d)
+ regmbc('v'); REGMBC(0x1e7d)
+ return;
+ case 'w': CASEMBC(0x175) CASEMBC(0x1e81) CASEMBC(0x1e83)
+ CASEMBC(0x1e85) CASEMBC(0x1e87) CASEMBC(0x1e98)
+ regmbc('w'); REGMBC(0x175) REGMBC(0x1e81)
+ REGMBC(0x1e83) REGMBC(0x1e85) REGMBC(0x1e87)
+ REGMBC(0x1e98)
+ return;
+ case 'x': CASEMBC(0x1e8b) CASEMBC(0x1e8d)
+ regmbc('x'); REGMBC(0x1e8b) REGMBC(0x1e8d)
+ return;
+ case 'y': case '\375': case '\377':
+ CASEMBC(0x177) CASEMBC(0x1e8f) CASEMBC(0x1e99)
+ CASEMBC(0x1ef3) CASEMBC(0x1ef7) CASEMBC(0x1ef9)
+ regmbc('y'); regmbc('\375'); regmbc('\377');
+ REGMBC(0x177) REGMBC(0x1e8f) REGMBC(0x1e99)
+ REGMBC(0x1ef3) REGMBC(0x1ef7) REGMBC(0x1ef9)
+ return;
+ case 'z': CASEMBC(0x17a) CASEMBC(0x17c) CASEMBC(0x17e)
+ CASEMBC(0x1b6) CASEMBC(0x1e91) CASEMBC(0x1e95)
+ regmbc('z'); REGMBC(0x17a) REGMBC(0x17c)
+ REGMBC(0x17e) REGMBC(0x1b6) REGMBC(0x1e91)
+ REGMBC(0x1e95)
+ return;
+ }
+ }
+ regmbc(c);
+}
+
+/*
+ * Check for a collating element "[.a.]". "pp" points to the '['.
+ * Returns a character. Zero means that no item was recognized. Otherwise
+ * "pp" is advanced to after the item.
+ * Currently only single characters are recognized!
+ */
+static int get_coll_element(pp)
+char_u **pp;
+{
+ int c;
+ int l = 1;
+ char_u *p = *pp;
+
+ if (p[1] == '.') {
+ if (has_mbyte)
+ l = (*mb_ptr2len)(p + 2);
+ if (p[l + 2] == '.' && p[l + 3] == ']') {
+ if (has_mbyte)
+ c = mb_ptr2char(p + 2);
+ else
+ c = p[2];
+ *pp += l + 4;
+ return c;
+ }
+ }
+ return 0;
+}
+
+static void get_cpo_flags __ARGS((void));
+static int reg_cpo_lit; /* 'cpoptions' contains 'l' flag */
+static int reg_cpo_bsl; /* 'cpoptions' contains '\' flag */
+
+static void get_cpo_flags() {
+ reg_cpo_lit = vim_strchr(p_cpo, CPO_LITERAL) != NULL;
+ reg_cpo_bsl = vim_strchr(p_cpo, CPO_BACKSL) != NULL;
+}
+
+/*
+ * Skip over a "[]" range.
+ * "p" must point to the character after the '['.
+ * The returned pointer is on the matching ']', or the terminating NUL.
+ */
+static char_u * skip_anyof(p)
+char_u *p;
+{
+ int l;
+
+ if (*p == '^') /* Complement of range. */
+ ++p;
+ if (*p == ']' || *p == '-')
+ ++p;
+ while (*p != NUL && *p != ']') {
+ 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 == '\\'
+ && !reg_cpo_bsl
+ && (vim_strchr(REGEXP_INRANGE, p[1]) != NULL
+ || (!reg_cpo_lit && vim_strchr(REGEXP_ABBR, p[1]) != NULL)))
+ p += 2;
+ else if (*p == '[') {
+ if (get_char_class(&p) == CLASS_NONE
+ && get_equi_class(&p) == 0
+ && get_coll_element(&p) == 0)
+ ++p; /* It was not a class name */
+ } else
+ ++p;
+ }
+
+ return p;
+}
+
+/*
+ * Skip past regular expression.
+ * Stop at end of "startp" or where "dirc" is found ('/', '?', etc).
+ * Take care of characters with a backslash in front of it.
+ * Skip strings inside [ and ].
+ * When "newp" is not NULL and "dirc" is '?', make an allocated copy of the
+ * expression and change "\?" to "?". If "*newp" is not NULL the expression
+ * is changed in-place.
+ */
+char_u * skip_regexp(startp, dirc, magic, newp)
+char_u *startp;
+int dirc;
+int magic;
+char_u **newp;
+{
+ int mymagic;
+ char_u *p = startp;
+
+ if (magic)
+ mymagic = MAGIC_ON;
+ else
+ mymagic = MAGIC_OFF;
+ get_cpo_flags();
+
+ 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);
+ if (p[0] == NUL)
+ break;
+ } else if (p[0] == '\\' && p[1] != NUL) {
+ if (dirc == '?' && newp != NULL && p[1] == '?') {
+ /* change "\?" to "?", make a copy first. */
+ if (*newp == NULL) {
+ *newp = vim_strsave(startp);
+ if (*newp != NULL)
+ p = *newp + (p - startp);
+ }
+ if (*newp != NULL)
+ STRMOVE(p, p + 1);
+ else
+ ++p;
+ } else
+ ++p; /* skip next character */
+ if (*p == 'v')
+ mymagic = MAGIC_ALL;
+ else if (*p == 'V')
+ mymagic = MAGIC_NONE;
+ }
+ }
+ return p;
+}
+
+static regprog_T *bt_regcomp __ARGS((char_u *expr, int re_flags));
+static void bt_regfree __ARGS((regprog_T *prog));
+
+/*
+ * bt_regcomp() - compile a regular expression into internal code for the
+ * traditional back track matcher.
+ * Returns the program in allocated space. Returns NULL for an error.
+ *
+ * We can't allocate space until we know how big the compiled form will be,
+ * but we can't compile it (and thus know how big it is) until we've got a
+ * place to put the code. So we cheat: we compile it twice, once with code
+ * generation turned off and size counting turned on, and once "for real".
+ * This also means that we don't allocate space until we are sure that the
+ * thing really will compile successfully, and we never have to move the
+ * code and thus invalidate pointers into it. (Note that it has to be in
+ * one piece because vim_free() must be able to free it all.)
+ *
+ * Whether upper/lower case is to be ignored is decided when executing the
+ * program, it does not matter here.
+ *
+ * Beware that the optimization-preparation code in here knows about some
+ * of the structure of the compiled regexp.
+ * "re_flags": RE_MAGIC and/or RE_STRING.
+ */
+static regprog_T * bt_regcomp(expr, re_flags)
+char_u *expr;
+int re_flags;
+{
+ bt_regprog_T *r;
+ char_u *scan;
+ char_u *longest;
+ int len;
+ int flags;
+
+ if (expr == NULL)
+ EMSG_RET_NULL(_(e_null));
+
+ init_class_tab();
+
+ /*
+ * First pass: determine size, legality.
+ */
+ regcomp_start(expr, re_flags);
+ regcode = JUST_CALC_SIZE;
+ regc(REGMAGIC);
+ if (reg(REG_NOPAREN, &flags) == NULL)
+ return NULL;
+
+ /* Small enough for pointer-storage convention? */
+#ifdef SMALL_MALLOC /* 16 bit storage allocation */
+ if (regsize >= 65536L - 256L)
+ EMSG_RET_NULL(_("E339: Pattern too long"));
+#endif
+
+ /* Allocate space. */
+ r = (bt_regprog_T *)lalloc(sizeof(bt_regprog_T) + regsize, TRUE);
+ if (r == NULL)
+ return NULL;
+
+ /*
+ * Second pass: emit code.
+ */
+ regcomp_start(expr, re_flags);
+ regcode = r->program;
+ regc(REGMAGIC);
+ if (reg(REG_NOPAREN, &flags) == NULL || reg_toolong) {
+ vim_free(r);
+ if (reg_toolong)
+ EMSG_RET_NULL(_("E339: Pattern too long"));
+ return NULL;
+ }
+
+ /* Dig out information for optimizations. */
+ r->regstart = NUL; /* Worst-case defaults. */
+ r->reganch = 0;
+ r->regmust = NULL;
+ r->regmlen = 0;
+ r->regflags = regflags;
+ if (flags & HASNL)
+ r->regflags |= RF_HASNL;
+ if (flags & HASLOOKBH)
+ r->regflags |= RF_LOOKBH;
+ /* Remember whether this pattern has any \z specials in it. */
+ r->reghasz = re_has_z;
+ scan = r->program + 1; /* First BRANCH. */
+ if (OP(regnext(scan)) == END) { /* Only one top-level choice. */
+ scan = OPERAND(scan);
+
+ /* Starting-point info. */
+ if (OP(scan) == BOL || OP(scan) == RE_BOF) {
+ r->reganch++;
+ scan = regnext(scan);
+ }
+
+ if (OP(scan) == EXACTLY) {
+ if (has_mbyte)
+ r->regstart = (*mb_ptr2char)(OPERAND(scan));
+ else
+ r->regstart = *OPERAND(scan);
+ } else if ((OP(scan) == BOW
+ || OP(scan) == EOW
+ || OP(scan) == NOTHING
+ || OP(scan) == MOPEN + 0 || OP(scan) == NOPEN
+ || OP(scan) == MCLOSE + 0 || OP(scan) == NCLOSE)
+ && OP(regnext(scan)) == EXACTLY) {
+ if (has_mbyte)
+ r->regstart = (*mb_ptr2char)(OPERAND(regnext(scan)));
+ else
+ r->regstart = *OPERAND(regnext(scan));
+ }
+
+ /*
+ * If there's something expensive in the r.e., find the longest
+ * literal string that must appear and make it the regmust. Resolve
+ * ties in favor of later strings, since the regstart check works
+ * with the beginning of the r.e. and avoiding duplication
+ * strengthens checking. Not a strong reason, but sufficient in the
+ * absence of others.
+ */
+ /*
+ * When the r.e. starts with BOW, it is faster to look for a regmust
+ * first. Used a lot for "#" and "*" commands. (Added by mool).
+ */
+ if ((flags & SPSTART || OP(scan) == BOW || OP(scan) == EOW)
+ && !(flags & HASNL)) {
+ longest = NULL;
+ len = 0;
+ for (; scan != NULL; scan = regnext(scan))
+ if (OP(scan) == EXACTLY && STRLEN(OPERAND(scan)) >= (size_t)len) {
+ longest = OPERAND(scan);
+ len = (int)STRLEN(OPERAND(scan));
+ }
+ r->regmust = longest;
+ r->regmlen = len;
+ }
+ }
+#ifdef BT_REGEXP_DUMP
+ regdump(expr, r);
+#endif
+ r->engine = &bt_regengine;
+ return (regprog_T *)r;
+}
+
+/*
+ * Free a compiled regexp program, returned by bt_regcomp().
+ */
+static void bt_regfree(prog)
+regprog_T *prog;
+{
+ vim_free(prog);
+}
+
+/*
+ * Setup to parse the regexp. Used once to get the length and once to do it.
+ */
+static void regcomp_start(expr, re_flags)
+char_u *expr;
+int re_flags; /* see vim_regcomp() */
+{
+ initchr(expr);
+ if (re_flags & RE_MAGIC)
+ reg_magic = MAGIC_ON;
+ else
+ reg_magic = MAGIC_OFF;
+ reg_string = (re_flags & RE_STRING);
+ reg_strict = (re_flags & RE_STRICT);
+ get_cpo_flags();
+
+ num_complex_braces = 0;
+ regnpar = 1;
+ vim_memset(had_endbrace, 0, sizeof(had_endbrace));
+ regnzpar = 1;
+ re_has_z = 0;
+ regsize = 0L;
+ reg_toolong = FALSE;
+ regflags = 0;
+ had_eol = FALSE;
+}
+
+/*
+ * Check if during the previous call to vim_regcomp the EOL item "$" has been
+ * found. This is messy, but it works fine.
+ */
+int vim_regcomp_had_eol() {
+ return had_eol;
+}
+
+/*
+ * Parse regular expression, i.e. main body or parenthesized thing.
+ *
+ * Caller must absorb opening parenthesis.
+ *
+ * Combining parenthesis handling with the base level of regular expression
+ * is a trifle forced, but the need to tie the tails of the branches to what
+ * follows makes it hard to avoid.
+ */
+static char_u * reg(paren, flagp)
+int paren; /* REG_NOPAREN, REG_PAREN, REG_NPAREN or REG_ZPAREN */
+int *flagp;
+{
+ char_u *ret;
+ char_u *br;
+ char_u *ender;
+ int parno = 0;
+ int flags;
+
+ *flagp = HASWIDTH; /* Tentatively. */
+
+ if (paren == REG_ZPAREN) {
+ /* Make a ZOPEN node. */
+ if (regnzpar >= NSUBEXP)
+ EMSG_RET_NULL(_("E50: Too many \\z("));
+ parno = regnzpar;
+ regnzpar++;
+ ret = regnode(ZOPEN + parno);
+ } else if (paren == REG_PAREN) {
+ /* Make a MOPEN node. */
+ if (regnpar >= NSUBEXP)
+ EMSG2_RET_NULL(_("E51: Too many %s("), reg_magic == MAGIC_ALL);
+ parno = regnpar;
+ ++regnpar;
+ ret = regnode(MOPEN + parno);
+ } else if (paren == REG_NPAREN) {
+ /* Make a NOPEN node. */
+ ret = regnode(NOPEN);
+ } else
+ ret = NULL;
+
+ /* Pick up the branches, linking them together. */
+ br = regbranch(&flags);
+ if (br == NULL)
+ return NULL;
+ if (ret != NULL)
+ regtail(ret, br); /* [MZ]OPEN -> first. */
+ else
+ ret = br;
+ /* If one of the branches can be zero-width, the whole thing can.
+ * If one of the branches has * at start or matches a line-break, the
+ * whole thing can. */
+ if (!(flags & HASWIDTH))
+ *flagp &= ~HASWIDTH;
+ *flagp |= flags & (SPSTART | HASNL | HASLOOKBH);
+ while (peekchr() == Magic('|')) {
+ skipchr();
+ br = regbranch(&flags);
+ if (br == NULL || reg_toolong)
+ return NULL;
+ regtail(ret, br); /* BRANCH -> BRANCH. */
+ if (!(flags & HASWIDTH))
+ *flagp &= ~HASWIDTH;
+ *flagp |= flags & (SPSTART | HASNL | HASLOOKBH);
+ }
+
+ /* Make a closing node, and hook it on the end. */
+ ender = regnode(
+ paren == REG_ZPAREN ? ZCLOSE + parno :
+ paren == REG_PAREN ? MCLOSE + parno :
+ paren == REG_NPAREN ? NCLOSE : END);
+ regtail(ret, ender);
+
+ /* Hook the tails of the branches to the closing node. */
+ for (br = ret; br != NULL; br = regnext(br))
+ regoptail(br, ender);
+
+ /* Check for proper termination. */
+ if (paren != REG_NOPAREN && getchr() != Magic(')')) {
+ if (paren == REG_ZPAREN)
+ EMSG_RET_NULL(_("E52: Unmatched \\z("));
+ else if (paren == REG_NPAREN)
+ EMSG2_RET_NULL(_(e_unmatchedpp), reg_magic == MAGIC_ALL);
+ else
+ EMSG2_RET_NULL(_(e_unmatchedp), reg_magic == MAGIC_ALL);
+ } else if (paren == REG_NOPAREN && peekchr() != NUL) {
+ if (curchr == Magic(')'))
+ EMSG2_RET_NULL(_(e_unmatchedpar), reg_magic == MAGIC_ALL);
+ else
+ EMSG_RET_NULL(_(e_trailing)); /* "Can't happen". */
+ /* NOTREACHED */
+ }
+ /*
+ * Here we set the flag allowing back references to this set of
+ * parentheses.
+ */
+ if (paren == REG_PAREN)
+ had_endbrace[parno] = TRUE; /* have seen the close paren */
+ return ret;
+}
+
+/*
+ * Parse one alternative of an | operator.
+ * Implements the & operator.
+ */
+static char_u * regbranch(flagp)
+int *flagp;
+{
+ char_u *ret;
+ char_u *chain = NULL;
+ char_u *latest;
+ int flags;
+
+ *flagp = WORST | HASNL; /* Tentatively. */
+
+ ret = regnode(BRANCH);
+ for (;; ) {
+ latest = regconcat(&flags);
+ if (latest == NULL)
+ return NULL;
+ /* If one of the branches has width, the whole thing has. If one of
+ * the branches anchors at start-of-line, the whole thing does.
+ * If one of the branches uses look-behind, the whole thing does. */
+ *flagp |= flags & (HASWIDTH | SPSTART | HASLOOKBH);
+ /* If one of the branches doesn't match a line-break, the whole thing
+ * doesn't. */
+ *flagp &= ~HASNL | (flags & HASNL);
+ if (chain != NULL)
+ regtail(chain, latest);
+ if (peekchr() != Magic('&'))
+ break;
+ skipchr();
+ regtail(latest, regnode(END)); /* operand ends */
+ if (reg_toolong)
+ break;
+ reginsert(MATCH, latest);
+ chain = latest;
+ }
+
+ return ret;
+}
+
+/*
+ * Parse one alternative of an | or & operator.
+ * Implements the concatenation operator.
+ */
+static char_u * regconcat(flagp)
+int *flagp;
+{
+ char_u *first = NULL;
+ char_u *chain = NULL;
+ char_u *latest;
+ int flags;
+ int cont = TRUE;
+
+ *flagp = WORST; /* Tentatively. */
+
+ while (cont) {
+ switch (peekchr()) {
+ case NUL:
+ case Magic('|'):
+ case Magic('&'):
+ case Magic(')'):
+ cont = FALSE;
+ break;
+ case Magic('Z'):
+ regflags |= RF_ICOMBINE;
+ skipchr_keepstart();
+ break;
+ case Magic('c'):
+ regflags |= RF_ICASE;
+ skipchr_keepstart();
+ break;
+ case Magic('C'):
+ regflags |= RF_NOICASE;
+ skipchr_keepstart();
+ break;
+ case Magic('v'):
+ reg_magic = MAGIC_ALL;
+ skipchr_keepstart();
+ curchr = -1;
+ break;
+ case Magic('m'):
+ reg_magic = MAGIC_ON;
+ skipchr_keepstart();
+ curchr = -1;
+ break;
+ case Magic('M'):
+ reg_magic = MAGIC_OFF;
+ skipchr_keepstart();
+ curchr = -1;
+ break;
+ case Magic('V'):
+ reg_magic = MAGIC_NONE;
+ skipchr_keepstart();
+ curchr = -1;
+ break;
+ default:
+ latest = regpiece(&flags);
+ if (latest == NULL || reg_toolong)
+ return NULL;
+ *flagp |= flags & (HASWIDTH | HASNL | HASLOOKBH);
+ if (chain == NULL) /* First piece. */
+ *flagp |= flags & SPSTART;
+ else
+ regtail(chain, latest);
+ chain = latest;
+ if (first == NULL)
+ first = latest;
+ break;
+ }
+ }
+ if (first == NULL) /* Loop ran zero times. */
+ first = regnode(NOTHING);
+ return first;
+}
+
+/*
+ * Parse something followed by possible [*+=].
+ *
+ * Note that the branching code sequences used for = and the general cases
+ * of * and + are somewhat optimized: they use the same NOTHING node as
+ * both the endmarker for their branch list and the body of the last branch.
+ * It might seem that this node could be dispensed with entirely, but the
+ * endmarker role is not redundant.
+ */
+static char_u * regpiece(flagp)
+int *flagp;
+{
+ char_u *ret;
+ int op;
+ char_u *next;
+ int flags;
+ long minval;
+ long maxval;
+
+ ret = regatom(&flags);
+ if (ret == NULL)
+ return NULL;
+
+ op = peekchr();
+ if (re_multi_type(op) == NOT_MULTI) {
+ *flagp = flags;
+ return ret;
+ }
+ /* default flags */
+ *flagp = (WORST | SPSTART | (flags & (HASNL | HASLOOKBH)));
+
+ skipchr();
+ switch (op) {
+ case Magic('*'):
+ if (flags & SIMPLE)
+ reginsert(STAR, ret);
+ else {
+ /* Emit x* as (x&|), where & means "self". */
+ reginsert(BRANCH, ret); /* Either x */
+ regoptail(ret, regnode(BACK)); /* and loop */
+ regoptail(ret, ret); /* back */
+ regtail(ret, regnode(BRANCH)); /* or */
+ regtail(ret, regnode(NOTHING)); /* null. */
+ }
+ break;
+
+ case Magic('+'):
+ if (flags & SIMPLE)
+ reginsert(PLUS, ret);
+ else {
+ /* Emit x+ as x(&|), where & means "self". */
+ next = regnode(BRANCH); /* Either */
+ regtail(ret, next);
+ regtail(regnode(BACK), ret); /* loop back */
+ regtail(next, regnode(BRANCH)); /* or */
+ regtail(ret, regnode(NOTHING)); /* null. */
+ }
+ *flagp = (WORST | HASWIDTH | (flags & (HASNL | HASLOOKBH)));
+ break;
+
+ case Magic('@'):
+ {
+ int lop = END;
+ int nr;
+
+ nr = getdecchrs();
+ switch (no_Magic(getchr())) {
+ case '=': lop = MATCH; break; /* \@= */
+ case '!': lop = NOMATCH; break; /* \@! */
+ case '>': lop = SUBPAT; break; /* \@> */
+ case '<': switch (no_Magic(getchr())) {
+ case '=': lop = BEHIND; break; /* \@<= */
+ case '!': lop = NOBEHIND; break; /* \@<! */
+ }
+ }
+ if (lop == END)
+ EMSG2_RET_NULL(_("E59: invalid character after %s@"),
+ reg_magic == MAGIC_ALL);
+ /* Look behind must match with behind_pos. */
+ if (lop == BEHIND || lop == NOBEHIND) {
+ regtail(ret, regnode(BHPOS));
+ *flagp |= HASLOOKBH;
+ }
+ regtail(ret, regnode(END)); /* operand ends */
+ if (lop == BEHIND || lop == NOBEHIND) {
+ if (nr < 0)
+ nr = 0; /* no limit is same as zero limit */
+ reginsert_nr(lop, nr, ret);
+ } else
+ reginsert(lop, ret);
+ break;
+ }
+
+ case Magic('?'):
+ case Magic('='):
+ /* Emit x= as (x|) */
+ reginsert(BRANCH, ret); /* Either x */
+ regtail(ret, regnode(BRANCH)); /* or */
+ next = regnode(NOTHING); /* null. */
+ regtail(ret, next);
+ regoptail(ret, next);
+ break;
+
+ case Magic('{'):
+ if (!read_limits(&minval, &maxval))
+ return NULL;
+ if (flags & SIMPLE) {
+ reginsert(BRACE_SIMPLE, ret);
+ reginsert_limits(BRACE_LIMITS, minval, maxval, ret);
+ } else {
+ if (num_complex_braces >= 10)
+ EMSG2_RET_NULL(_("E60: Too many complex %s{...}s"),
+ reg_magic == MAGIC_ALL);
+ reginsert(BRACE_COMPLEX + num_complex_braces, ret);
+ regoptail(ret, regnode(BACK));
+ regoptail(ret, ret);
+ reginsert_limits(BRACE_LIMITS, minval, maxval, ret);
+ ++num_complex_braces;
+ }
+ if (minval > 0 && maxval > 0)
+ *flagp = (HASWIDTH | (flags & (HASNL | HASLOOKBH)));
+ break;
+ }
+ if (re_multi_type(peekchr()) != NOT_MULTI) {
+ /* Can't have a multi follow a multi. */
+ if (peekchr() == Magic('*'))
+ sprintf((char *)IObuff, _("E61: Nested %s*"),
+ reg_magic >= MAGIC_ON ? "" : "\\");
+ else
+ sprintf((char *)IObuff, _("E62: Nested %s%c"),
+ reg_magic == MAGIC_ALL ? "" : "\\", no_Magic(peekchr()));
+ EMSG_RET_NULL(IObuff);
+ }
+
+ return ret;
+}
+
+/* When making changes to classchars also change nfa_classcodes. */
+static char_u *classchars = (char_u *)".iIkKfFpPsSdDxXoOwWhHaAlLuU";
+static int classcodes[] = {
+ ANY, IDENT, SIDENT, KWORD, SKWORD,
+ FNAME, SFNAME, PRINT, SPRINT,
+ WHITE, NWHITE, DIGIT, NDIGIT,
+ HEX, NHEX, OCTAL, NOCTAL,
+ WORD, NWORD, HEAD, NHEAD,
+ ALPHA, NALPHA, LOWER, NLOWER,
+ UPPER, NUPPER
+};
+
+/*
+ * Parse the lowest level.
+ *
+ * Optimization: gobbles an entire sequence of ordinary characters so that
+ * it can turn them into a single node, which is smaller to store and
+ * faster to run. Don't do this when one_exactly is set.
+ */
+static char_u * regatom(flagp)
+int *flagp;
+{
+ char_u *ret;
+ int flags;
+ int c;
+ char_u *p;
+ int extra = 0;
+
+ *flagp = WORST; /* Tentatively. */
+
+ c = getchr();
+ switch (c) {
+ case Magic('^'):
+ ret = regnode(BOL);
+ break;
+
+ case Magic('$'):
+ ret = regnode(EOL);
+ had_eol = TRUE;
+ break;
+
+ case Magic('<'):
+ ret = regnode(BOW);
+ break;
+
+ case Magic('>'):
+ ret = regnode(EOW);
+ break;
+
+ case Magic('_'):
+ c = no_Magic(getchr());
+ if (c == '^') { /* "\_^" is start-of-line */
+ ret = regnode(BOL);
+ break;
+ }
+ if (c == '$') { /* "\_$" is end-of-line */
+ ret = regnode(EOL);
+ had_eol = TRUE;
+ break;
+ }
+
+ extra = ADD_NL;
+ *flagp |= HASNL;
+
+ /* "\_[" is character range plus newline */
+ if (c == '[')
+ goto collection;
+
+ /* "\_x" is character class plus newline */
+ /*FALLTHROUGH*/
+
+ /*
+ * Character classes.
+ */
+ case Magic('.'):
+ case Magic('i'):
+ case Magic('I'):
+ case Magic('k'):
+ case Magic('K'):
+ case Magic('f'):
+ case Magic('F'):
+ case Magic('p'):
+ case Magic('P'):
+ case Magic('s'):
+ case Magic('S'):
+ case Magic('d'):
+ case Magic('D'):
+ case Magic('x'):
+ case Magic('X'):
+ case Magic('o'):
+ case Magic('O'):
+ case Magic('w'):
+ case Magic('W'):
+ case Magic('h'):
+ case Magic('H'):
+ case Magic('a'):
+ case Magic('A'):
+ case Magic('l'):
+ case Magic('L'):
+ case Magic('u'):
+ case Magic('U'):
+ p = vim_strchr(classchars, no_Magic(c));
+ if (p == NULL)
+ EMSG_RET_NULL(_("E63: invalid use of \\_"));
+ /* When '.' is followed by a composing char ignore the dot, so that
+ * the composing char is matched here. */
+ if (enc_utf8 && c == Magic('.') && utf_iscomposing(peekchr())) {
+ c = getchr();
+ goto do_multibyte;
+ }
+ ret = regnode(classcodes[p - classchars] + extra);
+ *flagp |= HASWIDTH | SIMPLE;
+ break;
+
+ case Magic('n'):
+ if (reg_string) {
+ /* In a string "\n" matches a newline character. */
+ ret = regnode(EXACTLY);
+ regc(NL);
+ regc(NUL);
+ *flagp |= HASWIDTH | SIMPLE;
+ } else {
+ /* In buffer text "\n" matches the end of a line. */
+ ret = regnode(NEWL);
+ *flagp |= HASWIDTH | HASNL;
+ }
+ break;
+
+ case Magic('('):
+ if (one_exactly)
+ EMSG_ONE_RET_NULL;
+ ret = reg(REG_PAREN, &flags);
+ if (ret == NULL)
+ return NULL;
+ *flagp |= flags & (HASWIDTH | SPSTART | HASNL | HASLOOKBH);
+ break;
+
+ case NUL:
+ case Magic('|'):
+ case Magic('&'):
+ case Magic(')'):
+ if (one_exactly)
+ EMSG_ONE_RET_NULL;
+ EMSG_RET_NULL(_(e_internal)); /* Supposed to be caught earlier. */
+ /* NOTREACHED */
+
+ case Magic('='):
+ case Magic('?'):
+ case Magic('+'):
+ case Magic('@'):
+ case Magic('{'):
+ case Magic('*'):
+ c = no_Magic(c);
+ sprintf((char *)IObuff, _("E64: %s%c follows nothing"),
+ (c == '*' ? reg_magic >= MAGIC_ON : reg_magic == MAGIC_ALL)
+ ? "" : "\\", c);
+ EMSG_RET_NULL(IObuff);
+ /* NOTREACHED */
+
+ case Magic('~'): /* previous substitute pattern */
+ if (reg_prev_sub != NULL) {
+ char_u *lp;
+
+ ret = regnode(EXACTLY);
+ lp = reg_prev_sub;
+ while (*lp != NUL)
+ regc(*lp++);
+ regc(NUL);
+ if (*reg_prev_sub != NUL) {
+ *flagp |= HASWIDTH;
+ if ((lp - reg_prev_sub) == 1)
+ *flagp |= SIMPLE;
+ }
+ } else
+ EMSG_RET_NULL(_(e_nopresub));
+ break;
+
+ case Magic('1'):
+ case Magic('2'):
+ case Magic('3'):
+ case Magic('4'):
+ case Magic('5'):
+ case Magic('6'):
+ case Magic('7'):
+ case Magic('8'):
+ case Magic('9'):
+ {
+ int refnum;
+
+ refnum = c - Magic('0');
+ /*
+ * Check if the back reference is legal. We must have seen the
+ * close brace.
+ * TODO: Should also check that we don't refer to something
+ * that is repeated (+*=): what instance of the repetition
+ * should we match?
+ */
+ if (!had_endbrace[refnum]) {
+ /* Trick: check if "@<=" or "@<!" follows, in which case
+ * the \1 can appear before the referenced match. */
+ for (p = regparse; *p != NUL; ++p)
+ if (p[0] == '@' && p[1] == '<'
+ && (p[2] == '!' || p[2] == '='))
+ break;
+ if (*p == NUL)
+ EMSG_RET_NULL(_("E65: Illegal back reference"));
+ }
+ ret = regnode(BACKREF + refnum);
+ }
+ break;
+
+ case Magic('z'):
+ {
+ c = no_Magic(getchr());
+ switch (c) {
+ case '(': if (reg_do_extmatch != REX_SET)
+ EMSG_RET_NULL(_(e_z_not_allowed));
+ if (one_exactly)
+ EMSG_ONE_RET_NULL;
+ ret = reg(REG_ZPAREN, &flags);
+ if (ret == NULL)
+ return NULL;
+ *flagp |= flags & (HASWIDTH|SPSTART|HASNL|HASLOOKBH);
+ re_has_z = REX_SET;
+ break;
+
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9': if (reg_do_extmatch != REX_USE)
+ EMSG_RET_NULL(_(e_z1_not_allowed));
+ ret = regnode(ZREF + c - '0');
+ re_has_z = REX_USE;
+ break;
+
+ case 's': ret = regnode(MOPEN + 0);
+ break;
+
+ case 'e': ret = regnode(MCLOSE + 0);
+ break;
+
+ default: EMSG_RET_NULL(_("E68: Invalid character after \\z"));
+ }
+ }
+ break;
+
+ case Magic('%'):
+ {
+ c = no_Magic(getchr());
+ switch (c) {
+ /* () without a back reference */
+ case '(':
+ if (one_exactly)
+ EMSG_ONE_RET_NULL;
+ ret = reg(REG_NPAREN, &flags);
+ if (ret == NULL)
+ return NULL;
+ *flagp |= flags & (HASWIDTH | SPSTART | HASNL | HASLOOKBH);
+ break;
+
+ /* Catch \%^ and \%$ regardless of where they appear in the
+ * pattern -- regardless of whether or not it makes sense. */
+ case '^':
+ ret = regnode(RE_BOF);
+ break;
+
+ case '$':
+ ret = regnode(RE_EOF);
+ break;
+
+ case '#':
+ ret = regnode(CURSOR);
+ break;
+
+ case 'V':
+ ret = regnode(RE_VISUAL);
+ break;
+
+ /* \%[abc]: Emit as a list of branches, all ending at the last
+ * branch which matches nothing. */
+ case '[':
+ if (one_exactly) /* doesn't nest */
+ EMSG_ONE_RET_NULL;
+ {
+ char_u *lastbranch;
+ char_u *lastnode = NULL;
+ char_u *br;
+
+ ret = NULL;
+ while ((c = getchr()) != ']') {
+ if (c == NUL)
+ EMSG2_RET_NULL(_(e_missing_sb),
+ reg_magic == MAGIC_ALL);
+ br = regnode(BRANCH);
+ if (ret == NULL)
+ ret = br;
+ else
+ regtail(lastnode, br);
+
+ ungetchr();
+ one_exactly = TRUE;
+ lastnode = regatom(flagp);
+ one_exactly = FALSE;
+ if (lastnode == NULL)
+ return NULL;
+ }
+ if (ret == NULL)
+ EMSG2_RET_NULL(_(e_empty_sb),
+ reg_magic == MAGIC_ALL);
+ lastbranch = regnode(BRANCH);
+ br = regnode(NOTHING);
+ if (ret != JUST_CALC_SIZE) {
+ regtail(lastnode, br);
+ regtail(lastbranch, br);
+ /* connect all branches to the NOTHING
+ * branch at the end */
+ for (br = ret; br != lastnode; ) {
+ if (OP(br) == BRANCH) {
+ regtail(br, lastbranch);
+ br = OPERAND(br);
+ } else
+ br = regnext(br);
+ }
+ }
+ *flagp &= ~(HASWIDTH | SIMPLE);
+ break;
+ }
+
+ case 'd': /* %d123 decimal */
+ case 'o': /* %o123 octal */
+ case 'x': /* %xab hex 2 */
+ case 'u': /* %uabcd hex 4 */
+ case 'U': /* %U1234abcd hex 8 */
+ {
+ int i;
+
+ switch (c) {
+ case 'd': i = getdecchrs(); break;
+ case 'o': i = getoctchrs(); break;
+ case 'x': i = gethexchrs(2); break;
+ case 'u': i = gethexchrs(4); break;
+ case 'U': i = gethexchrs(8); break;
+ default: i = -1; break;
+ }
+
+ if (i < 0)
+ EMSG2_RET_NULL(
+ _("E678: Invalid character after %s%%[dxouU]"),
+ reg_magic == MAGIC_ALL);
+ if (use_multibytecode(i))
+ ret = regnode(MULTIBYTECODE);
+ else
+ ret = regnode(EXACTLY);
+ if (i == 0)
+ regc(0x0a);
+ else
+ regmbc(i);
+ regc(NUL);
+ *flagp |= HASWIDTH;
+ break;
+ }
+
+ default:
+ if (VIM_ISDIGIT(c) || c == '<' || c == '>'
+ || c == '\'') {
+ long_u n = 0;
+ int cmp;
+
+ cmp = c;
+ if (cmp == '<' || cmp == '>')
+ c = getchr();
+ while (VIM_ISDIGIT(c)) {
+ n = n * 10 + (c - '0');
+ c = getchr();
+ }
+ if (c == '\'' && n == 0) {
+ /* "\%'m", "\%<'m" and "\%>'m": Mark */
+ c = getchr();
+ ret = regnode(RE_MARK);
+ if (ret == JUST_CALC_SIZE)
+ regsize += 2;
+ else {
+ *regcode++ = c;
+ *regcode++ = cmp;
+ }
+ break;
+ } else if (c == 'l' || c == 'c' || c == 'v') {
+ if (c == 'l')
+ ret = regnode(RE_LNUM);
+ else if (c == 'c')
+ ret = regnode(RE_COL);
+ else
+ ret = regnode(RE_VCOL);
+ if (ret == JUST_CALC_SIZE)
+ regsize += 5;
+ else {
+ /* put the number and the optional
+ * comparator after the opcode */
+ regcode = re_put_long(regcode, n);
+ *regcode++ = cmp;
+ }
+ break;
+ }
+ }
+
+ EMSG2_RET_NULL(_("E71: Invalid character after %s%%"),
+ reg_magic == MAGIC_ALL);
+ }
+ }
+ break;
+
+ case Magic('['):
+collection:
+ {
+ char_u *lp;
+
+ /*
+ * If there is no matching ']', we assume the '[' is a normal
+ * character. This makes 'incsearch' and ":help [" work.
+ */
+ lp = skip_anyof(regparse);
+ if (*lp == ']') { /* there is a matching ']' */
+ int startc = -1; /* > 0 when next '-' is a range */
+ int endc;
+
+ /*
+ * In a character class, different parsing rules apply.
+ * Not even \ is special anymore, nothing is.
+ */
+ if (*regparse == '^') { /* Complement of range. */
+ ret = regnode(ANYBUT + extra);
+ regparse++;
+ } else
+ ret = regnode(ANYOF + extra);
+
+ /* At the start ']' and '-' mean the literal character. */
+ if (*regparse == ']' || *regparse == '-') {
+ startc = *regparse;
+ regc(*regparse++);
+ }
+
+ while (*regparse != NUL && *regparse != ']') {
+ if (*regparse == '-') {
+ ++regparse;
+ /* The '-' is not used for a range at the end and
+ * after or before a '\n'. */
+ if (*regparse == ']' || *regparse == NUL
+ || startc == -1
+ || (regparse[0] == '\\' && regparse[1] == 'n')) {
+ regc('-');
+ startc = '-'; /* [--x] is a range */
+ } else {
+ /* Also accept "a-[.z.]" */
+ endc = 0;
+ if (*regparse == '[')
+ endc = get_coll_element(&regparse);
+ if (endc == 0) {
+ if (has_mbyte)
+ endc = mb_ptr2char_adv(&regparse);
+ else
+ endc = *regparse++;
+ }
+
+ /* Handle \o40, \x20 and \u20AC style sequences */
+ if (endc == '\\' && !reg_cpo_lit && !reg_cpo_bsl)
+ endc = coll_get_char();
+
+ if (startc > endc)
+ EMSG_RET_NULL(_(e_invrange));
+ 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)
+ regmbc(startc);
+ } else {
+ while (++startc <= endc)
+ regc(startc);
+ }
+ startc = -1;
+ }
+ }
+ /*
+ * Only "\]", "\^", "\]" and "\\" are special in Vi. Vim
+ * accepts "\t", "\e", etc., but only when the 'l' flag in
+ * 'cpoptions' is not included.
+ * Posix doesn't recognize backslash at all.
+ */
+ else if (*regparse == '\\'
+ && !reg_cpo_bsl
+ && (vim_strchr(REGEXP_INRANGE, regparse[1]) != NULL
+ || (!reg_cpo_lit
+ && vim_strchr(REGEXP_ABBR,
+ regparse[1]) != NULL))) {
+ regparse++;
+ if (*regparse == 'n') {
+ /* '\n' in range: also match NL */
+ if (ret != JUST_CALC_SIZE) {
+ /* Using \n inside [^] does not change what
+ * matches. "[^\n]" is the same as ".". */
+ if (*ret == ANYOF) {
+ *ret = ANYOF + ADD_NL;
+ *flagp |= HASNL;
+ }
+ /* else: must have had a \n already */
+ }
+ regparse++;
+ startc = -1;
+ } else if (*regparse == 'd'
+ || *regparse == 'o'
+ || *regparse == 'x'
+ || *regparse == 'u'
+ || *regparse == 'U') {
+ startc = coll_get_char();
+ if (startc == 0)
+ regc(0x0a);
+ else
+ regmbc(startc);
+ } else {
+ startc = backslash_trans(*regparse++);
+ regc(startc);
+ }
+ } else if (*regparse == '[') {
+ int c_class;
+ int cu;
+
+ c_class = get_char_class(&regparse);
+ startc = -1;
+ /* Characters assumed to be 8 bits! */
+ switch (c_class) {
+ case CLASS_NONE:
+ c_class = get_equi_class(&regparse);
+ if (c_class != 0) {
+ /* produce equivalence class */
+ reg_equi_class(c_class);
+ } else if ((c_class =
+ get_coll_element(&regparse)) != 0) {
+ /* produce a collating element */
+ regmbc(c_class);
+ } else {
+ /* literal '[', allow [[-x] as a range */
+ startc = *regparse++;
+ regc(startc);
+ }
+ break;
+ case CLASS_ALNUM:
+ for (cu = 1; cu <= 255; cu++)
+ if (isalnum(cu))
+ regc(cu);
+ break;
+ case CLASS_ALPHA:
+ for (cu = 1; cu <= 255; cu++)
+ if (isalpha(cu))
+ regc(cu);
+ break;
+ case CLASS_BLANK:
+ regc(' ');
+ regc('\t');
+ break;
+ case CLASS_CNTRL:
+ for (cu = 1; cu <= 255; cu++)
+ if (iscntrl(cu))
+ regc(cu);
+ break;
+ case CLASS_DIGIT:
+ for (cu = 1; cu <= 255; cu++)
+ if (VIM_ISDIGIT(cu))
+ regc(cu);
+ break;
+ case CLASS_GRAPH:
+ for (cu = 1; cu <= 255; cu++)
+ if (isgraph(cu))
+ regc(cu);
+ break;
+ case CLASS_LOWER:
+ for (cu = 1; cu <= 255; cu++)
+ if (MB_ISLOWER(cu))
+ regc(cu);
+ break;
+ case CLASS_PRINT:
+ for (cu = 1; cu <= 255; cu++)
+ if (vim_isprintc(cu))
+ regc(cu);
+ break;
+ case CLASS_PUNCT:
+ for (cu = 1; cu <= 255; cu++)
+ if (ispunct(cu))
+ regc(cu);
+ break;
+ case CLASS_SPACE:
+ for (cu = 9; cu <= 13; cu++)
+ regc(cu);
+ regc(' ');
+ break;
+ case CLASS_UPPER:
+ for (cu = 1; cu <= 255; cu++)
+ if (MB_ISUPPER(cu))
+ regc(cu);
+ break;
+ case CLASS_XDIGIT:
+ for (cu = 1; cu <= 255; cu++)
+ if (vim_isxdigit(cu))
+ regc(cu);
+ break;
+ case CLASS_TAB:
+ regc('\t');
+ break;
+ case CLASS_RETURN:
+ regc('\r');
+ break;
+ case CLASS_BACKSPACE:
+ regc('\b');
+ break;
+ case CLASS_ESCAPE:
+ regc('\033');
+ 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);
+ }
+ }
+ }
+ regc(NUL);
+ prevchr_len = 1; /* last char was the ']' */
+ if (*regparse != ']')
+ EMSG_RET_NULL(_(e_toomsbra)); /* Cannot happen? */
+ skipchr(); /* let's be friends with the lexer again */
+ *flagp |= HASWIDTH | SIMPLE;
+ break;
+ } else if (reg_strict)
+ EMSG2_RET_NULL(_(e_missingbracket), reg_magic > MAGIC_OFF);
+ }
+ /* FALLTHROUGH */
+
+ default:
+ {
+ int len;
+
+ /* A multi-byte character is handled as a separate atom if it's
+ * before a multi and when it's a composing char. */
+ if (use_multibytecode(c)) {
+do_multibyte:
+ ret = regnode(MULTIBYTECODE);
+ regmbc(c);
+ *flagp |= HASWIDTH | SIMPLE;
+ break;
+ }
+
+ ret = regnode(EXACTLY);
+
+ /*
+ * Append characters as long as:
+ * - there is no following multi, we then need the character in
+ * front of it as a single character operand
+ * - not running into a Magic character
+ * - "one_exactly" is not set
+ * But always emit at least one character. Might be a Multi,
+ * e.g., a "[" without matching "]".
+ */
+ for (len = 0; c != NUL && (len == 0
+ || (re_multi_type(peekchr()) == NOT_MULTI
+ && !one_exactly
+ && !is_Magic(c))); ++len) {
+ c = no_Magic(c);
+ if (has_mbyte) {
+ regmbc(c);
+ if (enc_utf8) {
+ int l;
+
+ /* Need to get composing character too. */
+ for (;; ) {
+ l = utf_ptr2len(regparse);
+ if (!UTF_COMPOSINGLIKE(regparse, regparse + l))
+ break;
+ regmbc(utf_ptr2char(regparse));
+ skipchr();
+ }
+ }
+ } else
+ regc(c);
+ c = getchr();
+ }
+ ungetchr();
+
+ regc(NUL);
+ *flagp |= HASWIDTH;
+ if (len == 1)
+ *flagp |= SIMPLE;
+ }
+ break;
+ }
+
+ return ret;
+}
+
+/*
+ * Return TRUE if MULTIBYTECODE should be used instead of EXACTLY for
+ * character "c".
+ */
+static int use_multibytecode(c)
+int c;
+{
+ return has_mbyte && (*mb_char2len)(c) > 1
+ && (re_multi_type(peekchr()) != NOT_MULTI
+ || (enc_utf8 && utf_iscomposing(c)));
+}
+
+/*
+ * Emit a node.
+ * Return pointer to generated code.
+ */
+static char_u * regnode(op)
+int op;
+{
+ char_u *ret;
+
+ ret = regcode;
+ if (ret == JUST_CALC_SIZE)
+ regsize += 3;
+ else {
+ *regcode++ = op;
+ *regcode++ = NUL; /* Null "next" pointer. */
+ *regcode++ = NUL;
+ }
+ return ret;
+}
+
+/*
+ * Emit (if appropriate) a byte of code
+ */
+static void regc(b)
+int b;
+{
+ if (regcode == JUST_CALC_SIZE)
+ regsize++;
+ else
+ *regcode++ = b;
+}
+
+/*
+ * Emit (if appropriate) a multi-byte character of code
+ */
+static void regmbc(c)
+int c;
+{
+ if (!has_mbyte && c > 0xff)
+ return;
+ if (regcode == JUST_CALC_SIZE)
+ regsize += (*mb_char2len)(c);
+ else
+ regcode += (*mb_char2bytes)(c, regcode);
+}
+
+/*
+ * Insert an operator in front of already-emitted operand
+ *
+ * Means relocating the operand.
+ */
+static void reginsert(op, opnd)
+int op;
+char_u *opnd;
+{
+ char_u *src;
+ char_u *dst;
+ char_u *place;
+
+ if (regcode == JUST_CALC_SIZE) {
+ regsize += 3;
+ return;
+ }
+ src = regcode;
+ regcode += 3;
+ dst = regcode;
+ while (src > opnd)
+ *--dst = *--src;
+
+ place = opnd; /* Op node, where operand used to be. */
+ *place++ = op;
+ *place++ = NUL;
+ *place = NUL;
+}
+
+/*
+ * Insert an operator in front of already-emitted operand.
+ * Add a number to the operator.
+ */
+static void reginsert_nr(op, val, opnd)
+int op;
+long val;
+char_u *opnd;
+{
+ char_u *src;
+ char_u *dst;
+ char_u *place;
+
+ if (regcode == JUST_CALC_SIZE) {
+ regsize += 7;
+ return;
+ }
+ src = regcode;
+ regcode += 7;
+ dst = regcode;
+ while (src > opnd)
+ *--dst = *--src;
+
+ place = opnd; /* Op node, where operand used to be. */
+ *place++ = op;
+ *place++ = NUL;
+ *place++ = NUL;
+ place = re_put_long(place, (long_u)val);
+}
+
+/*
+ * Insert an operator in front of already-emitted operand.
+ * The operator has the given limit values as operands. Also set next pointer.
+ *
+ * Means relocating the operand.
+ */
+static void reginsert_limits(op, minval, maxval, opnd)
+int op;
+long minval;
+long maxval;
+char_u *opnd;
+{
+ char_u *src;
+ char_u *dst;
+ char_u *place;
+
+ if (regcode == JUST_CALC_SIZE) {
+ regsize += 11;
+ return;
+ }
+ src = regcode;
+ regcode += 11;
+ dst = regcode;
+ while (src > opnd)
+ *--dst = *--src;
+
+ place = opnd; /* Op node, where operand used to be. */
+ *place++ = op;
+ *place++ = NUL;
+ *place++ = NUL;
+ place = re_put_long(place, (long_u)minval);
+ place = re_put_long(place, (long_u)maxval);
+ regtail(opnd, place);
+}
+
+/*
+ * Write a long as four bytes at "p" and return pointer to the next char.
+ */
+static char_u * re_put_long(p, val)
+char_u *p;
+long_u val;
+{
+ *p++ = (char_u) ((val >> 24) & 0377);
+ *p++ = (char_u) ((val >> 16) & 0377);
+ *p++ = (char_u) ((val >> 8) & 0377);
+ *p++ = (char_u) (val & 0377);
+ return p;
+}
+
+/*
+ * Set the next-pointer at the end of a node chain.
+ */
+static void regtail(p, val)
+char_u *p;
+char_u *val;
+{
+ char_u *scan;
+ char_u *temp;
+ int offset;
+
+ if (p == JUST_CALC_SIZE)
+ return;
+
+ /* Find last node. */
+ scan = p;
+ for (;; ) {
+ temp = regnext(scan);
+ if (temp == NULL)
+ break;
+ scan = temp;
+ }
+
+ if (OP(scan) == BACK)
+ offset = (int)(scan - val);
+ else
+ offset = (int)(val - scan);
+ /* When the offset uses more than 16 bits it can no longer fit in the two
+ * bytes available. Use a global flag to avoid having to check return
+ * values in too many places. */
+ if (offset > 0xffff)
+ reg_toolong = TRUE;
+ else {
+ *(scan + 1) = (char_u) (((unsigned)offset >> 8) & 0377);
+ *(scan + 2) = (char_u) (offset & 0377);
+ }
+}
+
+/*
+ * Like regtail, on item after a BRANCH; nop if none.
+ */
+static void regoptail(p, val)
+char_u *p;
+char_u *val;
+{
+ /* When op is neither BRANCH nor BRACE_COMPLEX0-9, it is "operandless" */
+ if (p == NULL || p == JUST_CALC_SIZE
+ || (OP(p) != BRANCH
+ && (OP(p) < BRACE_COMPLEX || OP(p) > BRACE_COMPLEX + 9)))
+ return;
+ regtail(OPERAND(p), 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".
+ */
+static void initchr(str)
+char_u *str;
+{
+ regparse = str;
+ prevchr_len = 0;
+ curchr = prevprevchr = prevchr = nextchr = -1;
+ at_start = TRUE;
+ prev_at_start = FALSE;
+}
+
+/*
+ * Save the current parse state, so that it can be restored and parsing
+ * starts in the same state again.
+ */
+static void save_parse_state(ps)
+parse_state_T *ps;
+{
+ ps->regparse = regparse;
+ ps->prevchr_len = prevchr_len;
+ ps->curchr = curchr;
+ ps->prevchr = prevchr;
+ ps->prevprevchr = prevprevchr;
+ ps->nextchr = nextchr;
+ ps->at_start = at_start;
+ ps->prev_at_start = prev_at_start;
+ ps->regnpar = regnpar;
+}
+
+/*
+ * Restore a previously saved parse state.
+ */
+static void restore_parse_state(ps)
+parse_state_T *ps;
+{
+ regparse = ps->regparse;
+ prevchr_len = ps->prevchr_len;
+ curchr = ps->curchr;
+ prevchr = ps->prevchr;
+ prevprevchr = ps->prevprevchr;
+ nextchr = ps->nextchr;
+ at_start = ps->at_start;
+ prev_at_start = ps->prev_at_start;
+ regnpar = ps->regnpar;
+}
+
+
+/*
+ * Get the next character without advancing.
+ */
+static int peekchr() {
+ static int after_slash = FALSE;
+
+ if (curchr == -1) {
+ switch (curchr = regparse[0]) {
+ case '.':
+ case '[':
+ case '~':
+ /* magic when 'magic' is on */
+ if (reg_magic >= MAGIC_ON)
+ curchr = Magic(curchr);
+ break;
+ case '(':
+ case ')':
+ case '{':
+ case '%':
+ case '+':
+ case '=':
+ case '?':
+ case '@':
+ case '!':
+ case '&':
+ case '|':
+ case '<':
+ case '>':
+ case '#': /* future ext. */
+ case '"': /* future ext. */
+ case '\'': /* future ext. */
+ case ',': /* future ext. */
+ case '-': /* future ext. */
+ case ':': /* future ext. */
+ case ';': /* future ext. */
+ case '`': /* future ext. */
+ case '/': /* Can't be used in / command */
+ /* magic only after "\v" */
+ if (reg_magic == MAGIC_ALL)
+ curchr = Magic(curchr);
+ break;
+ case '*':
+ /* * is not magic as the very first character, eg "?*ptr", when
+ * after '^', eg "/^*ptr" and when after "\(", "\|", "\&". But
+ * "\(\*" is not magic, thus must be magic if "after_slash" */
+ if (reg_magic >= MAGIC_ON
+ && !at_start
+ && !(prev_at_start && prevchr == Magic('^'))
+ && (after_slash
+ || (prevchr != Magic('(')
+ && prevchr != Magic('&')
+ && prevchr != Magic('|'))))
+ curchr = Magic('*');
+ break;
+ case '^':
+ /* '^' is only magic as the very first character and if it's after
+ * "\(", "\|", "\&' or "\n" */
+ if (reg_magic >= MAGIC_OFF
+ && (at_start
+ || reg_magic == MAGIC_ALL
+ || prevchr == Magic('(')
+ || prevchr == Magic('|')
+ || prevchr == Magic('&')
+ || prevchr == Magic('n')
+ || (no_Magic(prevchr) == '('
+ && prevprevchr == Magic('%')))) {
+ curchr = Magic('^');
+ at_start = TRUE;
+ prev_at_start = FALSE;
+ }
+ break;
+ case '$':
+ /* '$' is only magic as the very last char and if it's in front of
+ * either "\|", "\)", "\&", or "\n" */
+ if (reg_magic >= MAGIC_OFF) {
+ char_u *p = regparse + 1;
+
+ /* ignore \c \C \m and \M after '$' */
+ while (p[0] == '\\' && (p[1] == 'c' || p[1] == 'C'
+ || p[1] == 'm' || p[1] == 'M' || p[1] == 'Z'))
+ p += 2;
+ if (p[0] == NUL
+ || (p[0] == '\\'
+ && (p[1] == '|' || p[1] == '&' || p[1] == ')'
+ || p[1] == 'n'))
+ || reg_magic == MAGIC_ALL)
+ curchr = Magic('$');
+ }
+ break;
+ case '\\':
+ {
+ int c = regparse[1];
+
+ if (c == NUL)
+ curchr = '\\'; /* trailing '\' */
+ else if (
+ c <= '~' && META_flags[c]
+ ) {
+ /*
+ * META contains everything that may be magic sometimes,
+ * except ^ and $ ("\^" and "\$" are only magic after
+ * "\v"). We now fetch the next character and toggle its
+ * magicness. Therefore, \ is so meta-magic that it is
+ * not in META.
+ */
+ curchr = -1;
+ prev_at_start = at_start;
+ at_start = FALSE; /* be able to say "/\*ptr" */
+ ++regparse;
+ ++after_slash;
+ peekchr();
+ --regparse;
+ --after_slash;
+ curchr = toggle_Magic(curchr);
+ } else if (vim_strchr(REGEXP_ABBR, c)) {
+ /*
+ * Handle abbreviations, like "\t" for TAB -- webb
+ */
+ curchr = backslash_trans(c);
+ } else if (reg_magic == MAGIC_NONE && (c == '$' || c == '^'))
+ curchr = toggle_Magic(c);
+ else {
+ /*
+ * 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;
+ }
+ break;
+ }
+
+ default:
+ if (has_mbyte)
+ curchr = (*mb_ptr2char)(regparse);
+ }
+ }
+
+ return curchr;
+}
+
+/*
+ * Eat one lexed character. Do this in a way that we can undo it.
+ */
+static void skipchr() {
+ /* peekchr() eats a backslash, do the same here */
+ if (*regparse == '\\')
+ prevchr_len = 1;
+ 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;
+ }
+ regparse += prevchr_len;
+ prev_at_start = at_start;
+ at_start = FALSE;
+ prevprevchr = prevchr;
+ prevchr = curchr;
+ curchr = nextchr; /* use previously unget char, or -1 */
+ nextchr = -1;
+}
+
+/*
+ * Skip a character while keeping the value of prev_at_start for at_start.
+ * prevchr and prevprevchr are also kept.
+ */
+static void skipchr_keepstart() {
+ int as = prev_at_start;
+ int pr = prevchr;
+ int prpr = prevprevchr;
+
+ skipchr();
+ at_start = as;
+ prevchr = pr;
+ prevprevchr = prpr;
+}
+
+/*
+ * Get the next character from the pattern. We know about magic and such, so
+ * therefore we need a lexical analyzer.
+ */
+static int getchr() {
+ int chr = peekchr();
+
+ skipchr();
+ return chr;
+}
+
+/*
+ * put character back. Works only once!
+ */
+static void ungetchr() {
+ nextchr = curchr;
+ curchr = prevchr;
+ prevchr = prevprevchr;
+ at_start = prev_at_start;
+ prev_at_start = FALSE;
+
+ /* Backup regparse, so that it's at the same position as before the
+ * getchr(). */
+ regparse -= prevchr_len;
+}
+
+/*
+ * Get and return the value of the hex string at the current position.
+ * Return -1 if there is no valid hex number.
+ * The position is updated:
+ * blahblah\%x20asdf
+ * before-^ ^-after
+ * 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(maxinputlen)
+int maxinputlen;
+{
+ int nr = 0;
+ int c;
+ int i;
+
+ for (i = 0; i < maxinputlen; ++i) {
+ c = regparse[0];
+ if (!vim_isxdigit(c))
+ break;
+ nr <<= 4;
+ nr |= hex2nr(c);
+ ++regparse;
+ }
+
+ if (i == 0)
+ return -1;
+ return nr;
+}
+
+/*
+ * Get and return the value of the decimal string immediately after the
+ * current position. Return -1 for invalid. Consumes all digits.
+ */
+static int getdecchrs() {
+ int nr = 0;
+ int c;
+ int i;
+
+ for (i = 0;; ++i) {
+ c = regparse[0];
+ if (c < '0' || c > '9')
+ break;
+ nr *= 10;
+ nr += c - '0';
+ ++regparse;
+ curchr = -1; /* no longer valid */
+ }
+
+ if (i == 0)
+ return -1;
+ return nr;
+}
+
+/*
+ * get and return the value of the octal string immediately after the current
+ * position. Return -1 for invalid, or 0-255 for valid. Smart enough to handle
+ * numbers > 377 correctly (for example, 400 is treated as 40) and doesn't
+ * treat 8 or 9 as recognised characters. Position is updated:
+ * blahblah\%o210asdf
+ * before-^ ^-after
+ */
+static int getoctchrs() {
+ int nr = 0;
+ int c;
+ int i;
+
+ for (i = 0; i < 3 && nr < 040; ++i) {
+ c = regparse[0];
+ if (c < '0' || c > '7')
+ break;
+ nr <<= 3;
+ nr |= hex2nr(c);
+ ++regparse;
+ }
+
+ if (i == 0)
+ return -1;
+ return nr;
+}
+
+/*
+ * Get a number after a backslash that is inside [].
+ * When nothing is recognized return a backslash.
+ */
+static int coll_get_char() {
+ int nr = -1;
+
+ switch (*regparse++) {
+ case 'd': nr = getdecchrs(); break;
+ case 'o': nr = getoctchrs(); break;
+ case 'x': nr = gethexchrs(2); break;
+ case 'u': nr = gethexchrs(4); break;
+ case 'U': nr = gethexchrs(8); break;
+ }
+ if (nr < 0) {
+ /* If getting the number fails be backwards compatible: the character
+ * is a backslash. */
+ --regparse;
+ nr = '\\';
+ }
+ return nr;
+}
+
+/*
+ * read_limits - Read two integers to be taken as a minimum and maximum.
+ * If the first character is '-', then the range is reversed.
+ * Should end with 'end'. If minval is missing, zero is default, if maxval is
+ * missing, a very big number is the default.
+ */
+static int read_limits(minval, maxval)
+long *minval;
+long *maxval;
+{
+ int reverse = FALSE;
+ char_u *first_char;
+ long tmp;
+
+ if (*regparse == '-') {
+ /* Starts with '-', so reverse the range later */
+ regparse++;
+ reverse = TRUE;
+ }
+ first_char = regparse;
+ *minval = getdigits(&regparse);
+ if (*regparse == ',') { /* There is a comma */
+ if (vim_isdigit(*++regparse))
+ *maxval = getdigits(&regparse);
+ else
+ *maxval = MAX_LIMIT;
+ } else if (VIM_ISDIGIT(*first_char))
+ *maxval = *minval; /* It was \{n} or \{-n} */
+ else
+ *maxval = MAX_LIMIT; /* It was \{} or \{-} */
+ if (*regparse == '\\')
+ regparse++; /* Allow either \{...} or \{...\} */
+ if (*regparse != '}') {
+ sprintf((char *)IObuff, _("E554: Syntax error in %s{...}"),
+ reg_magic == MAGIC_ALL ? "" : "\\");
+ EMSG_RET_FAIL(IObuff);
+ }
+
+ /*
+ * Reverse the range if there was a '-', or make sure it is in the right
+ * order otherwise.
+ */
+ if ((!reverse && *minval > *maxval) || (reverse && *minval < *maxval)) {
+ tmp = *minval;
+ *minval = *maxval;
+ *maxval = tmp;
+ }
+ skipchr(); /* let's be friends with the lexer again */
+ return OK;
+}
+
+/*
+ * vim_regexec and friends
+ */
+
+/*
+ * Global work variables for vim_regexec().
+ */
+
+/* The current match-position is remembered with these variables: */
+static linenr_T reglnum; /* line number, relative to first line */
+static char_u *regline; /* start of current line */
+static char_u *reginput; /* current input, points into "regline" */
+
+static int need_clear_subexpr; /* subexpressions still need to be
+ * cleared */
+static int need_clear_zsubexpr = FALSE; /* extmatch subexpressions
+ * still need to be cleared */
+
+/*
+ * Structure used to save the current input state, when it needs to be
+ * restored after trying a match. Used by reg_save() and reg_restore().
+ * Also stores the length of "backpos".
+ */
+typedef struct {
+ union {
+ char_u *ptr; /* reginput pointer, for single-line regexp */
+ lpos_T pos; /* reginput pos, for multi-line regexp */
+ } rs_u;
+ int rs_len;
+} regsave_T;
+
+/* struct to save start/end pointer/position in for \(\) */
+typedef struct {
+ union {
+ char_u *ptr;
+ lpos_T pos;
+ } se_u;
+} save_se_T;
+
+/* used for BEHIND and NOBEHIND matching */
+typedef struct regbehind_S {
+ regsave_T save_after;
+ regsave_T save_behind;
+ int save_need_clear_subexpr;
+ save_se_T save_start[NSUBEXP];
+ save_se_T save_end[NSUBEXP];
+} regbehind_T;
+
+static char_u *reg_getline __ARGS((linenr_T lnum));
+static long bt_regexec_both __ARGS((char_u *line, colnr_T col, proftime_T *tm));
+static long regtry __ARGS((bt_regprog_T *prog, colnr_T col));
+static void cleanup_subexpr __ARGS((void));
+static void cleanup_zsubexpr __ARGS((void));
+static void save_subexpr __ARGS((regbehind_T *bp));
+static void restore_subexpr __ARGS((regbehind_T *bp));
+static void reg_nextline __ARGS((void));
+static void reg_save __ARGS((regsave_T *save, garray_T *gap));
+static void reg_restore __ARGS((regsave_T *save, garray_T *gap));
+static int reg_save_equal __ARGS((regsave_T *save));
+static void save_se_multi __ARGS((save_se_T *savep, lpos_T *posp));
+static void save_se_one __ARGS((save_se_T *savep, char_u **pp));
+
+/* Save the sub-expressions before attempting a match. */
+#define save_se(savep, posp, pp) \
+ REG_MULTI ? save_se_multi((savep), (posp)) : save_se_one((savep), (pp))
+
+/* After a failed match restore the sub-expressions. */
+#define restore_se(savep, posp, pp) { \
+ if (REG_MULTI) \
+ *(posp) = (savep)->se_u.pos; \
+ else \
+ *(pp) = (savep)->se_u.ptr; }
+
+static int re_num_cmp __ARGS((long_u val, char_u *scan));
+static int match_with_backref __ARGS((linenr_T start_lnum, colnr_T start_col,
+ linenr_T end_lnum, colnr_T end_col,
+ int *bytelen));
+static int regmatch __ARGS((char_u *prog));
+static int regrepeat __ARGS((char_u *p, long maxcount));
+
+#ifdef REGEXP_DEBUG
+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.
+ */
+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 */
+
+/* Values for rs_state in regitem_T. */
+typedef enum regstate_E {
+ RS_NOPEN = 0 /* NOPEN and NCLOSE */
+ , RS_MOPEN /* MOPEN + [0-9] */
+ , RS_MCLOSE /* MCLOSE + [0-9] */
+ , RS_ZOPEN /* ZOPEN + [0-9] */
+ , RS_ZCLOSE /* ZCLOSE + [0-9] */
+ , RS_BRANCH /* BRANCH */
+ , RS_BRCPLX_MORE /* BRACE_COMPLEX and trying one more match */
+ , RS_BRCPLX_LONG /* BRACE_COMPLEX and trying longest match */
+ , RS_BRCPLX_SHORT /* BRACE_COMPLEX and trying shortest match */
+ , RS_NOMATCH /* NOMATCH */
+ , RS_BEHIND1 /* BEHIND / NOBEHIND matching rest */
+ , RS_BEHIND2 /* BEHIND / NOBEHIND matching behind part */
+ , RS_STAR_LONG /* STAR/PLUS/BRACE_SIMPLE longest match */
+ , RS_STAR_SHORT /* STAR/PLUS/BRACE_SIMPLE shortest match */
+} regstate_T;
+
+/*
+ * When there are alternatives a regstate_T is put on the regstack to remember
+ * what we are doing.
+ * Before it may be another type of item, depending on rs_state, to remember
+ * more things.
+ */
+typedef struct regitem_S {
+ regstate_T rs_state; /* what we are doing, one of RS_ above */
+ char_u *rs_scan; /* current node in program */
+ union {
+ save_se_T sesave;
+ regsave_T regsave;
+ } rs_un; /* room for saving reginput */
+ short rs_no; /* submatch nr or BEHIND/NOBEHIND */
+} regitem_T;
+
+static regitem_T *regstack_push __ARGS((regstate_T state, char_u *scan));
+static void regstack_pop __ARGS((char_u **scan));
+
+/* used for STAR, PLUS and BRACE_SIMPLE matching */
+typedef struct regstar_S {
+ int nextb; /* next byte */
+ int nextb_ic; /* next byte reverse case */
+ long count;
+ long minval;
+ long maxval;
+} regstar_T;
+
+/* used to store input position when a BACK was encountered, so that we now if
+ * we made any progress since the last time. */
+typedef struct backpos_S {
+ char_u *bp_scan; /* "scan" where BACK was encountered */
+ regsave_T bp_pos; /* last input position */
+} backpos_T;
+
+/*
+ * "regstack" and "backpos" are used by regmatch(). They are kept over calls
+ * to avoid invoking malloc() and free() often.
+ * "regstack" is a stack with regitem_T items, sometimes preceded by regstar_T
+ * or regbehind_T.
+ * "backpos_T" is a table with backpos_T for BACK
+ */
+static garray_T regstack = {0, 0, 0, 0, NULL};
+static garray_T backpos = {0, 0, 0, 0, NULL};
+
+/*
+ * Both for regstack and backpos tables we use the following strategy of
+ * allocation (to reduce malloc/free calls):
+ * - Initial size is fairly small.
+ * - When needed, the tables are grown bigger (8 times at first, double after
+ * that).
+ * - After executing the match we free the memory only if the array has grown.
+ * Thus the memory is kept allocated when it's at the initial size.
+ * This makes it fast while not keeping a lot of memory allocated.
+ * A three times speed increase was observed when using many simple patterns.
+ */
+#define REGSTACK_INITIAL 2048
+#define BACKPOS_INITIAL 64
+
+#if defined(EXITFREE) || defined(PROTO)
+void free_regexp_stuff() {
+ ga_clear(&regstack);
+ ga_clear(&backpos);
+ vim_free(reg_tofree);
+ vim_free(reg_prev_sub);
+}
+
+#endif
+
+/*
+ * Get pointer to the line "lnum", which is relative to "reg_firstlnum".
+ */
+static char_u * reg_getline(lnum)
+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)
+ return NULL;
+ if (lnum > reg_maxline)
+ /* Must have matched the "\n" in the last line. */
+ return (char_u *)"";
+ return ml_get_buf(reg_buf, reg_firstlnum + lnum, FALSE);
+}
+
+static regsave_T behind_pos;
+
+static char_u *reg_startzp[NSUBEXP]; /* Workspace to mark beginning */
+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)
+
+static int bt_regexec __ARGS((regmatch_T *rmp, char_u *line, colnr_T col));
+
+/*
+ * Match a regexp against a string.
+ * "rmp->regprog" is a compiled regexp as returned by vim_regcomp().
+ * Uses curbuf for line count and 'iskeyword'.
+ *
+ * Return TRUE if there is a match, FALSE if not.
+ */
+static int bt_regexec(rmp, line, col)
+regmatch_T *rmp;
+char_u *line; /* string to match against */
+colnr_T col; /* column to start looking for match */
+{
+ reg_match = rmp;
+ reg_mmatch = NULL;
+ reg_maxline = 0;
+ reg_line_lbr = FALSE;
+ reg_buf = curbuf;
+ reg_win = NULL;
+ ireg_ic = rmp->rm_ic;
+ ireg_icombine = FALSE;
+ ireg_maxcol = 0;
+ return bt_regexec_both(line, col, NULL) != 0;
+}
+
+#if defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) \
+ || defined(FIND_REPLACE_DIALOG) || defined(PROTO)
+
+static int bt_regexec_nl __ARGS((regmatch_T *rmp, char_u *line, colnr_T col));
+
+/*
+ * Like vim_regexec(), but consider a "\n" in "line" to be a line break.
+ */
+static int bt_regexec_nl(rmp, line, col)
+regmatch_T *rmp;
+char_u *line; /* string to match against */
+colnr_T col; /* column to start looking for match */
+{
+ reg_match = rmp;
+ reg_mmatch = NULL;
+ reg_maxline = 0;
+ reg_line_lbr = TRUE;
+ reg_buf = curbuf;
+ reg_win = NULL;
+ ireg_ic = rmp->rm_ic;
+ ireg_icombine = FALSE;
+ ireg_maxcol = 0;
+ return bt_regexec_both(line, col, NULL) != 0;
+}
+#endif
+
+static long bt_regexec_multi __ARGS((regmmatch_T *rmp, win_T *win, buf_T *buf,
+ linenr_T lnum, colnr_T col,
+ proftime_T *tm));
+
+/*
+ * Match a regexp against multiple lines.
+ * "rmp->regprog" is a compiled regexp as returned by vim_regcomp().
+ * Uses curbuf for line count and 'iskeyword'.
+ *
+ * Return zero if there is no match. Return number of lines contained in the
+ * match otherwise.
+ */
+static long bt_regexec_multi(rmp, win, buf, lnum, col, tm)
+regmmatch_T *rmp;
+win_T *win; /* window in which to search or NULL */
+buf_T *buf; /* buffer in which to search */
+linenr_T lnum; /* nr of line to start looking for match */
+colnr_T col; /* column to start looking for match */
+proftime_T *tm; /* timeout limit or NULL */
+{
+ long r;
+
+ 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;
+
+ r = bt_regexec_both(NULL, col, tm);
+
+ return r;
+}
+
+/*
+ * Match a regexp against a string ("line" points to the string) or multiple
+ * lines ("line" is NULL, use reg_getline()).
+ */
+static long bt_regexec_both(line, col, tm)
+char_u *line;
+colnr_T col; /* column to start looking for match */
+proftime_T *tm UNUSED; /* timeout limit or NULL */
+{
+ bt_regprog_T *prog;
+ char_u *s;
+ long retval = 0L;
+
+ /* Create "regstack" and "backpos" if they are not allocated yet.
+ * We allocate *_INITIAL amount of bytes first and then set the grow size
+ * to much bigger value to avoid many malloc calls in case of deep regular
+ * expressions. */
+ if (regstack.ga_data == NULL) {
+ /* Use an item size of 1 byte, since we push different things
+ * onto the regstack. */
+ ga_init2(&regstack, 1, REGSTACK_INITIAL);
+ ga_grow(&regstack, REGSTACK_INITIAL);
+ regstack.ga_growsize = REGSTACK_INITIAL * 8;
+ }
+
+ if (backpos.ga_data == NULL) {
+ ga_init2(&backpos, sizeof(backpos_T), BACKPOS_INITIAL);
+ ga_grow(&backpos, BACKPOS_INITIAL);
+ backpos.ga_growsize = BACKPOS_INITIAL * 8;
+ }
+
+ if (REG_MULTI) {
+ prog = (bt_regprog_T *)reg_mmatch->regprog;
+ line = reg_getline((linenr_T)0);
+ reg_startpos = reg_mmatch->startpos;
+ reg_endpos = reg_mmatch->endpos;
+ } else {
+ prog = (bt_regprog_T *)reg_match->regprog;
+ reg_startp = reg_match->startp;
+ reg_endp = reg_match->endp;
+ }
+
+ /* Be paranoid... */
+ if (prog == NULL || line == NULL) {
+ EMSG(_(e_null));
+ goto theend;
+ }
+
+ /* Check validity of program. */
+ 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)
+ 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 "\Z" overrule value of ireg_icombine */
+ if (prog->regflags & RF_ICOMBINE)
+ ireg_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;
+ 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))
+ while ((s = vim_strchr(s, c)) != NULL) {
+ if (cstrncmp(s, prog->regmust, &prog->regmlen) == 0)
+ break; /* Found it. */
+ mb_ptr_adv(s);
+ }
+ else
+ while ((s = cstrchr(s, c)) != NULL) {
+ if (cstrncmp(s, prog->regmust, &prog->regmlen) == 0)
+ break; /* Found it. */
+ mb_ptr_adv(s);
+ }
+ if (s == NULL) /* Not present. */
+ goto theend;
+ }
+
+ regline = line;
+ reglnum = 0;
+ reg_toolong = FALSE;
+
+ /* 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];
+ if (prog->regstart == NUL
+ || prog->regstart == c
+ || (ireg_ic && ((
+ (enc_utf8 && utf_fold(prog->regstart) == utf_fold(c)))
+ || (c < 255 && prog->regstart < 255 &&
+ MB_TOLOWER(prog->regstart) == MB_TOLOWER(c)))))
+ retval = regtry(prog, col);
+ else
+ retval = 0;
+ } else {
+ int tm_count = 0;
+ /* 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);
+ if (s == NULL) {
+ retval = 0;
+ break;
+ }
+ col = (int)(s - regline);
+ }
+
+ /* Check for maximum column to try. */
+ if (ireg_maxcol > 0 && col >= ireg_maxcol) {
+ retval = 0;
+ break;
+ }
+
+ retval = regtry(prog, col);
+ if (retval > 0)
+ break;
+
+ /* if not currently on the first line, get it again */
+ if (reglnum != 0) {
+ reglnum = 0;
+ regline = reg_getline((linenr_T)0);
+ }
+ if (regline[col] == NUL)
+ break;
+ if (has_mbyte)
+ col += (*mb_ptr2len)(regline + col);
+ else
+ ++col;
+ /* Check for timeout once in a twenty times to avoid overhead. */
+ if (tm != NULL && ++tm_count == 20) {
+ tm_count = 0;
+ if (profile_passed_limit(tm))
+ break;
+ }
+ }
+ }
+
+theend:
+ /* Free "reg_tofree" when it's a bit big.
+ * Free regstack and backpos if they are bigger than their initial size. */
+ if (reg_tofreelen > 400) {
+ vim_free(reg_tofree);
+ reg_tofree = NULL;
+ }
+ if (regstack.ga_maxlen > REGSTACK_INITIAL)
+ ga_clear(&regstack);
+ if (backpos.ga_maxlen > BACKPOS_INITIAL)
+ ga_clear(&backpos);
+
+ return retval;
+}
+
+static reg_extmatch_T *make_extmatch __ARGS((void));
+
+/*
+ * Create a new extmatch and mark it as referenced once.
+ */
+static reg_extmatch_T * make_extmatch() {
+ reg_extmatch_T *em;
+
+ em = (reg_extmatch_T *)alloc_clear((unsigned)sizeof(reg_extmatch_T));
+ if (em != NULL)
+ em->refcnt = 1;
+ return em;
+}
+
+/*
+ * Add a reference to an extmatch.
+ */
+reg_extmatch_T * ref_extmatch(em)
+reg_extmatch_T *em;
+{
+ if (em != NULL)
+ em->refcnt++;
+ return em;
+}
+
+/*
+ * Remove a reference to an extmatch. If there are no references left, free
+ * the info.
+ */
+void unref_extmatch(em)
+reg_extmatch_T *em;
+{
+ int i;
+
+ if (em != NULL && --em->refcnt <= 0) {
+ for (i = 0; i < NSUBEXP; ++i)
+ vim_free(em->matches[i]);
+ vim_free(em);
+ }
+}
+
+/*
+ * regtry - try match of "prog" with at regline["col"].
+ * Returns 0 for failure, number of lines contained in the match otherwise.
+ */
+static long regtry(prog, col)
+bt_regprog_T *prog;
+colnr_T col;
+{
+ reginput = regline + col;
+ need_clear_subexpr = TRUE;
+ /* Clear the external match subpointers if necessary. */
+ if (prog->reghasz == REX_SET)
+ need_clear_zsubexpr = TRUE;
+
+ if (regmatch(prog->program + 1) == 0)
+ return 0;
+
+ cleanup_subexpr();
+ if (REG_MULTI) {
+ if (reg_startpos[0].lnum < 0) {
+ reg_startpos[0].lnum = 0;
+ reg_startpos[0].col = col;
+ }
+ 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;
+ }
+ /* Package any found \z(...\) matches for export. Default is none. */
+ unref_extmatch(re_extmatch_out);
+ re_extmatch_out = NULL;
+
+ if (prog->reghasz == REX_SET) {
+ int i;
+
+ cleanup_zsubexpr();
+ re_extmatch_out = make_extmatch();
+ for (i = 0; i < NSUBEXP; i++) {
+ if (REG_MULTI) {
+ /* Only accept single line matches. */
+ if (reg_startzpos[i].lnum >= 0
+ && reg_endzpos[i].lnum == reg_startzpos[i].lnum)
+ re_extmatch_out->matches[i] =
+ vim_strnsave(reg_getline(reg_startzpos[i].lnum)
+ + reg_startzpos[i].col,
+ reg_endzpos[i].col - reg_startzpos[i].col);
+ } else {
+ if (reg_startzp[i] != NULL && reg_endzp[i] != NULL)
+ re_extmatch_out->matches[i] =
+ vim_strnsave(reg_startzp[i],
+ (int)(reg_endzp[i] - reg_startzp[i]));
+ }
+ }
+ }
+ return 1 + reglnum;
+}
+
+static int reg_prev_class __ARGS((void));
+
+/*
+ * Get class of previous character.
+ */
+static int reg_prev_class() {
+ if (reginput > regline)
+ return mb_get_class_buf(reginput - 1
+ - (*mb_head_off)(regline, reginput - 1), reg_buf);
+ return -1;
+}
+
+static int reg_match_visual __ARGS((void));
+
+/*
+ * Return TRUE if the current reginput position matches the Visual area.
+ */
+static int reg_match_visual() {
+ pos_T top, bot;
+ linenr_T lnum;
+ colnr_T col;
+ win_T *wp = reg_win == NULL ? curwin : reg_win;
+ int mode;
+ colnr_T start, end;
+ colnr_T start2, end2;
+ colnr_T cols;
+
+ /* Check if the buffer is the current buffer. */
+ if (reg_buf != curbuf || VIsual.lnum == 0)
+ return FALSE;
+
+ if (VIsual_active) {
+ if (lt(VIsual, wp->w_cursor)) {
+ top = VIsual;
+ bot = wp->w_cursor;
+ } else {
+ top = wp->w_cursor;
+ bot = VIsual;
+ }
+ mode = VIsual_mode;
+ } else {
+ if (lt(curbuf->b_visual.vi_start, curbuf->b_visual.vi_end)) {
+ top = curbuf->b_visual.vi_start;
+ bot = curbuf->b_visual.vi_end;
+ } else {
+ top = curbuf->b_visual.vi_end;
+ bot = curbuf->b_visual.vi_start;
+ }
+ mode = curbuf->b_visual.vi_mode;
+ }
+ lnum = reglnum + reg_firstlnum;
+ if (lnum < top.lnum || lnum > bot.lnum)
+ return FALSE;
+
+ if (mode == 'v') {
+ col = (colnr_T)(reginput - regline);
+ if ((lnum == top.lnum && col < top.col)
+ || (lnum == bot.lnum && col >= bot.col + (*p_sel != 'e')))
+ return FALSE;
+ } else if (mode == Ctrl_V) {
+ getvvcol(wp, &top, &start, NULL, &end);
+ getvvcol(wp, &bot, &start2, NULL, &end2);
+ if (start2 < start)
+ start = start2;
+ if (end2 > end)
+ end = end2;
+ if (top.col == MAXCOL || bot.col == MAXCOL)
+ end = MAXCOL;
+ cols = win_linetabsize(wp, regline, (colnr_T)(reginput - regline));
+ if (cols < start || cols > end - (*p_sel == 'e'))
+ return FALSE;
+ }
+ return TRUE;
+}
+
+#define ADVANCE_REGINPUT() mb_ptr_adv(reginput)
+
+/*
+ * The arguments from BRACE_LIMITS are stored here. They are actually local
+ * to regmatch(), but they are here to reduce the amount of stack space used
+ * (it can be called recursively many times).
+ */
+static long bl_minval;
+static long bl_maxval;
+
+/*
+ * regmatch - main matching routine
+ *
+ * Conceptually the strategy is simple: Check to see whether the current node
+ * matches, push an item onto the regstack and loop to see whether the rest
+ * matches, and then act accordingly. In practice we make some effort to
+ * avoid using the regstack, in particular by going through "ordinary" nodes
+ * (that don't need to know whether the rest of the match failed) by a nested
+ * loop.
+ *
+ * Returns TRUE when there is a match. Leaves reginput and reglnum just after
+ * the last matched character.
+ * Returns FALSE when there is no match. Leaves reginput and reglnum in an
+ * undefined state!
+ */
+static int regmatch(scan)
+char_u *scan; /* Current node. */
+{
+ char_u *next; /* Next node. */
+ int op;
+ int c;
+ regitem_T *rp;
+ int no;
+ int status; /* one of the RA_ values: */
+#define RA_FAIL 1 /* something failed, abort */
+#define RA_CONT 2 /* continue in inner loop */
+#define RA_BREAK 3 /* break inner loop */
+#define RA_MATCH 4 /* successful match */
+#define RA_NOMATCH 5 /* didn't match */
+
+ /* Make "regstack" and "backpos" empty. They are allocated and freed in
+ * bt_regexec_both() to reduce malloc()/free() calls. */
+ regstack.ga_len = 0;
+ backpos.ga_len = 0;
+
+ /*
+ * Repeat until "regstack" is empty.
+ */
+ for (;; ) {
+ /* Some patterns may take a long time to match, e.g., "\([a-z]\+\)\+Q".
+ * Allow interrupting them with CTRL-C. */
+ fast_breakcheck();
+
+#ifdef REGEXP_DEBUG
+ if (scan != NULL && regnarrate) {
+ mch_errmsg((char *)regprop(scan));
+ mch_errmsg("(\n");
+ }
+#endif
+
+ /*
+ * Repeat for items that can be matched sequentially, without using the
+ * regstack.
+ */
+ for (;; ) {
+ if (got_int || scan == NULL) {
+ status = RA_FAIL;
+ break;
+ }
+ status = RA_CONT;
+
+#ifdef REGEXP_DEBUG
+ if (regnarrate) {
+ mch_errmsg((char *)regprop(scan));
+ mch_errmsg("...\n");
+ if (re_extmatch_in != NULL) {
+ int i;
+
+ mch_errmsg(_("External submatches:\n"));
+ for (i = 0; i < NSUBEXP; i++) {
+ mch_errmsg(" \"");
+ if (re_extmatch_in->matches[i] != NULL)
+ mch_errmsg((char *)re_extmatch_in->matches[i]);
+ mch_errmsg("\"\n");
+ }
+ }
+ }
+#endif
+ 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) {
+ reg_nextline();
+ } else if (reg_line_lbr && WITH_NL(op) && *reginput == '\n') {
+ ADVANCE_REGINPUT();
+ } else {
+ if (WITH_NL(op))
+ op -= ADD_NL;
+ if (has_mbyte)
+ c = (*mb_ptr2char)(reginput);
+ else
+ c = *reginput;
+ switch (op) {
+ case BOL:
+ if (reginput != regline)
+ status = RA_NOMATCH;
+ break;
+
+ case EOL:
+ if (c != NUL)
+ status = RA_NOMATCH;
+ 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. */
+ if (reglnum != 0 || reginput != regline
+ || (REG_MULTI && reg_firstlnum > 1))
+ status = RA_NOMATCH;
+ break;
+
+ case RE_EOF:
+ if (reglnum != 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))
+ status = RA_NOMATCH;
+ break;
+
+ case RE_MARK:
+ /* Compare the mark position to the match position. */
+ {
+ int mark = OPERAND(scan)[0];
+ 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->col == (colnr_T)(reginput - regline)
+ ? (cmp == '<' || cmp == '>')
+ : (pos->col < (colnr_T)(reginput - regline)
+ ? cmp != '>'
+ : cmp != '<'))
+ : (pos->lnum < reglnum + reg_firstlnum
+ ? cmp != '>'
+ : cmp != '<')))
+ status = RA_NOMATCH;
+ }
+ break;
+
+ case RE_VISUAL:
+ if (!reg_match_visual())
+ status = RA_NOMATCH;
+ break;
+
+ case RE_LNUM:
+ if (!REG_MULTI || !re_num_cmp((long_u)(reglnum + reg_firstlnum),
+ scan))
+ status = RA_NOMATCH;
+ break;
+
+ case RE_COL:
+ if (!re_num_cmp((long_u)(reginput - regline) + 1, scan))
+ status = RA_NOMATCH;
+ break;
+
+ case RE_VCOL:
+ if (!re_num_cmp((long_u)win_linetabsize(
+ reg_win == NULL ? curwin : reg_win,
+ regline, (colnr_T)(reginput - regline)) + 1, scan))
+ status = RA_NOMATCH;
+ break;
+
+ case BOW: /* \<word; reginput points to w */
+ if (c == NUL) /* Can't match at end of line */
+ status = RA_NOMATCH;
+ 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 */
+ } else {
+ if (!vim_iswordc_buf(c, reg_buf) || (reginput > regline
+ && vim_iswordc_buf(reginput[-1
+ ], reg_buf)))
+ status = RA_NOMATCH;
+ }
+ break;
+
+ case EOW: /* word\>; reginput points after d */
+ if (reginput == regline) /* Can't match at start of line */
+ status = RA_NOMATCH;
+ 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);
+ 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)))
+ status = RA_NOMATCH;
+ }
+ break; /* Matched with EOW */
+
+ case ANY:
+ /* ANY does not match new lines. */
+ if (c == NUL)
+ status = RA_NOMATCH;
+ else
+ ADVANCE_REGINPUT();
+ break;
+
+ case IDENT:
+ if (!vim_isIDc(c))
+ status = RA_NOMATCH;
+ else
+ ADVANCE_REGINPUT();
+ break;
+
+ case SIDENT:
+ if (VIM_ISDIGIT(*reginput) || !vim_isIDc(c))
+ status = RA_NOMATCH;
+ else
+ ADVANCE_REGINPUT();
+ break;
+
+ case KWORD:
+ if (!vim_iswordp_buf(reginput, reg_buf))
+ status = RA_NOMATCH;
+ else
+ ADVANCE_REGINPUT();
+ break;
+
+ case SKWORD:
+ if (VIM_ISDIGIT(*reginput) || !vim_iswordp_buf(reginput, reg_buf))
+ status = RA_NOMATCH;
+ else
+ ADVANCE_REGINPUT();
+ break;
+
+ case FNAME:
+ if (!vim_isfilec(c))
+ status = RA_NOMATCH;
+ else
+ ADVANCE_REGINPUT();
+ break;
+
+ case SFNAME:
+ if (VIM_ISDIGIT(*reginput) || !vim_isfilec(c))
+ status = RA_NOMATCH;
+ else
+ ADVANCE_REGINPUT();
+ break;
+
+ case PRINT:
+ if (!vim_isprintc(PTR2CHAR(reginput)))
+ status = RA_NOMATCH;
+ else
+ ADVANCE_REGINPUT();
+ break;
+
+ case SPRINT:
+ if (VIM_ISDIGIT(*reginput) || !vim_isprintc(PTR2CHAR(reginput)))
+ status = RA_NOMATCH;
+ else
+ ADVANCE_REGINPUT();
+ break;
+
+ case WHITE:
+ if (!vim_iswhite(c))
+ status = RA_NOMATCH;
+ else
+ ADVANCE_REGINPUT();
+ break;
+
+ case NWHITE:
+ if (c == NUL || vim_iswhite(c))
+ status = RA_NOMATCH;
+ else
+ ADVANCE_REGINPUT();
+ break;
+
+ case DIGIT:
+ if (!ri_digit(c))
+ status = RA_NOMATCH;
+ else
+ ADVANCE_REGINPUT();
+ break;
+
+ case NDIGIT:
+ if (c == NUL || ri_digit(c))
+ status = RA_NOMATCH;
+ else
+ ADVANCE_REGINPUT();
+ break;
+
+ case HEX:
+ if (!ri_hex(c))
+ status = RA_NOMATCH;
+ else
+ ADVANCE_REGINPUT();
+ break;
+
+ case NHEX:
+ if (c == NUL || ri_hex(c))
+ status = RA_NOMATCH;
+ else
+ ADVANCE_REGINPUT();
+ break;
+
+ case OCTAL:
+ if (!ri_octal(c))
+ status = RA_NOMATCH;
+ else
+ ADVANCE_REGINPUT();
+ break;
+
+ case NOCTAL:
+ if (c == NUL || ri_octal(c))
+ status = RA_NOMATCH;
+ else
+ ADVANCE_REGINPUT();
+ break;
+
+ case WORD:
+ if (!ri_word(c))
+ status = RA_NOMATCH;
+ else
+ ADVANCE_REGINPUT();
+ break;
+
+ case NWORD:
+ if (c == NUL || ri_word(c))
+ status = RA_NOMATCH;
+ else
+ ADVANCE_REGINPUT();
+ break;
+
+ case HEAD:
+ if (!ri_head(c))
+ status = RA_NOMATCH;
+ else
+ ADVANCE_REGINPUT();
+ break;
+
+ case NHEAD:
+ if (c == NUL || ri_head(c))
+ status = RA_NOMATCH;
+ else
+ ADVANCE_REGINPUT();
+ break;
+
+ case ALPHA:
+ if (!ri_alpha(c))
+ status = RA_NOMATCH;
+ else
+ ADVANCE_REGINPUT();
+ break;
+
+ case NALPHA:
+ if (c == NUL || ri_alpha(c))
+ status = RA_NOMATCH;
+ else
+ ADVANCE_REGINPUT();
+ break;
+
+ case LOWER:
+ if (!ri_lower(c))
+ status = RA_NOMATCH;
+ else
+ ADVANCE_REGINPUT();
+ break;
+
+ case NLOWER:
+ if (c == NUL || ri_lower(c))
+ status = RA_NOMATCH;
+ else
+ ADVANCE_REGINPUT();
+ break;
+
+ case UPPER:
+ if (!ri_upper(c))
+ status = RA_NOMATCH;
+ else
+ ADVANCE_REGINPUT();
+ break;
+
+ case NUPPER:
+ if (c == NUL || ri_upper(c))
+ status = RA_NOMATCH;
+ else
+ ADVANCE_REGINPUT();
+ break;
+
+ case EXACTLY:
+ {
+ int len;
+ char_u *opnd;
+
+ opnd = OPERAND(scan);
+ /* Inline the first byte, for speed. */
+ if (*opnd != *reginput
+ && (!ireg_ic || (
+ !enc_utf8 &&
+ 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)
+ )
+ ++reginput; /* matched a single char */
+ else {
+ len = (int)STRLEN(opnd);
+ /* Need to match first byte again for multi-byte. */
+ if (cstrncmp(opnd, reginput, &len) != 0)
+ status = RA_NOMATCH;
+ /* Check for following composing character. */
+ else if (enc_utf8
+ && UTF_COMPOSINGLIKE(reginput, reginput + len)) {
+ /* raaron: This code makes a composing character get
+ * ignored, which is the correct behavior (sometimes)
+ * for voweled Hebrew texts. */
+ if (!ireg_icombine)
+ status = RA_NOMATCH;
+ } else
+ reginput += len;
+ }
+ }
+ break;
+
+ case ANYOF:
+ case ANYBUT:
+ if (c == NUL)
+ status = RA_NOMATCH;
+ else if ((cstrchr(OPERAND(scan), c) == NULL) == (op == ANYOF))
+ status = RA_NOMATCH;
+ else
+ ADVANCE_REGINPUT();
+ break;
+
+ case MULTIBYTECODE:
+ if (has_mbyte) {
+ int i, len;
+ char_u *opnd;
+ int opndc = 0, inpc;
+
+ opnd = OPERAND(scan);
+ /* 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 && 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_char2len(inpc)) {
+ inpc = mb_ptr2char(reginput + i);
+ if (!utf_iscomposing(inpc)) {
+ if (i > 0)
+ break;
+ } else if (opndc == inpc) {
+ /* Include all following composing chars. */
+ len = i + mb_ptr2len(reginput + i);
+ status = RA_MATCH;
+ break;
+ }
+ }
+ } else
+ for (i = 0; i < len; ++i)
+ if (opnd[i] != reginput[i]) {
+ status = RA_NOMATCH;
+ break;
+ }
+ reginput += len;
+ } else
+ status = RA_NOMATCH;
+ break;
+
+ case NOTHING:
+ break;
+
+ case BACK:
+ {
+ int i;
+ backpos_T *bp;
+
+ /*
+ * When we run into BACK we need to check if we don't keep
+ * looping without matching any input. The second and later
+ * times a BACK is encountered it fails if the input is still
+ * at the same position as the previous time.
+ * The positions are stored in "backpos" and found by the
+ * current value of "scan", the position in the RE program.
+ */
+ bp = (backpos_T *)backpos.ga_data;
+ for (i = 0; i < backpos.ga_len; ++i)
+ if (bp[i].bp_scan == scan)
+ break;
+ if (i == backpos.ga_len) {
+ /* First time at this BACK, make room to store the pos. */
+ if (ga_grow(&backpos, 1) == FAIL)
+ status = RA_FAIL;
+ else {
+ /* get "ga_data" again, it may have changed */
+ bp = (backpos_T *)backpos.ga_data;
+ bp[i].bp_scan = scan;
+ ++backpos.ga_len;
+ }
+ } else if (reg_save_equal(&bp[i].bp_pos))
+ /* Still at same position as last time, fail. */
+ status = RA_NOMATCH;
+
+ if (status != RA_FAIL && status != RA_NOMATCH)
+ reg_save(&bp[i].bp_pos, &backpos);
+ }
+ break;
+
+ case MOPEN + 0: /* Match start: \zs */
+ case MOPEN + 1: /* \( */
+ case MOPEN + 2:
+ case MOPEN + 3:
+ case MOPEN + 4:
+ case MOPEN + 5:
+ case MOPEN + 6:
+ case MOPEN + 7:
+ case MOPEN + 8:
+ case MOPEN + 9:
+ {
+ no = op - MOPEN;
+ cleanup_subexpr();
+ rp = regstack_push(RS_MOPEN, scan);
+ if (rp == NULL)
+ 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. */
+ }
+ }
+ break;
+
+ case NOPEN: /* \%( */
+ case NCLOSE: /* \) after \%( */
+ if (regstack_push(RS_NOPEN, scan) == NULL)
+ status = RA_FAIL;
+ /* We simply continue and handle the result when done. */
+ break;
+
+ case ZOPEN + 1:
+ case ZOPEN + 2:
+ case ZOPEN + 3:
+ case ZOPEN + 4:
+ case ZOPEN + 5:
+ case ZOPEN + 6:
+ case ZOPEN + 7:
+ case ZOPEN + 8:
+ case ZOPEN + 9:
+ {
+ no = op - ZOPEN;
+ cleanup_zsubexpr();
+ rp = regstack_push(RS_ZOPEN, scan);
+ if (rp == NULL)
+ status = RA_FAIL;
+ else {
+ rp->rs_no = no;
+ save_se(&rp->rs_un.sesave, &reg_startzpos[no],
+ &reg_startzp[no]);
+ /* We simply continue and handle the result when done. */
+ }
+ }
+ break;
+
+ case MCLOSE + 0: /* Match end: \ze */
+ case MCLOSE + 1: /* \) */
+ case MCLOSE + 2:
+ case MCLOSE + 3:
+ case MCLOSE + 4:
+ case MCLOSE + 5:
+ case MCLOSE + 6:
+ case MCLOSE + 7:
+ case MCLOSE + 8:
+ case MCLOSE + 9:
+ {
+ no = op - MCLOSE;
+ cleanup_subexpr();
+ rp = regstack_push(RS_MCLOSE, scan);
+ if (rp == NULL)
+ status = RA_FAIL;
+ 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. */
+ }
+ }
+ break;
+
+ case ZCLOSE + 1: /* \) after \z( */
+ case ZCLOSE + 2:
+ case ZCLOSE + 3:
+ case ZCLOSE + 4:
+ case ZCLOSE + 5:
+ case ZCLOSE + 6:
+ case ZCLOSE + 7:
+ case ZCLOSE + 8:
+ case ZCLOSE + 9:
+ {
+ no = op - ZCLOSE;
+ cleanup_zsubexpr();
+ rp = regstack_push(RS_ZCLOSE, scan);
+ if (rp == NULL)
+ status = RA_FAIL;
+ else {
+ rp->rs_no = no;
+ save_se(&rp->rs_un.sesave, &reg_endzpos[no],
+ &reg_endzp[no]);
+ /* We simply continue and handle the result when done. */
+ }
+ }
+ break;
+
+ case BACKREF + 1:
+ case BACKREF + 2:
+ case BACKREF + 3:
+ case BACKREF + 4:
+ case BACKREF + 5:
+ case BACKREF + 6:
+ case BACKREF + 7:
+ case BACKREF + 8:
+ case BACKREF + 9:
+ {
+ int len;
+
+ 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. */
+ 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)
+ 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. */
+ 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)
+ 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)
+ status = r;
+ }
+ }
+ }
+
+ /* Matched the backref, skip over it. */
+ reginput += len;
+ }
+ break;
+
+ case ZREF + 1:
+ case ZREF + 2:
+ case ZREF + 3:
+ case ZREF + 4:
+ case ZREF + 5:
+ case ZREF + 6:
+ case ZREF + 7:
+ case ZREF + 8:
+ case ZREF + 9:
+ {
+ int len;
+
+ cleanup_zsubexpr();
+ no = op - ZREF;
+ if (re_extmatch_in != NULL
+ && re_extmatch_in->matches[no] != NULL) {
+ len = (int)STRLEN(re_extmatch_in->matches[no]);
+ if (cstrncmp(re_extmatch_in->matches[no],
+ reginput, &len) != 0)
+ status = RA_NOMATCH;
+ else
+ reginput += len;
+ } else {
+ /* Backref was not set: Match an empty string. */
+ }
+ }
+ break;
+
+ case BRANCH:
+ {
+ if (OP(next) != BRANCH) /* No choice. */
+ next = OPERAND(scan); /* Avoid recursion. */
+ else {
+ rp = regstack_push(RS_BRANCH, scan);
+ if (rp == NULL)
+ status = RA_FAIL;
+ else
+ status = RA_BREAK; /* rest is below */
+ }
+ }
+ break;
+
+ case BRACE_LIMITS:
+ {
+ if (OP(next) == BRACE_SIMPLE) {
+ bl_minval = OPERAND_MIN(scan);
+ bl_maxval = OPERAND_MAX(scan);
+ } else if (OP(next) >= BRACE_COMPLEX
+ && OP(next) < BRACE_COMPLEX + 10) {
+ no = OP(next) - BRACE_COMPLEX;
+ brace_min[no] = OPERAND_MIN(scan);
+ brace_max[no] = OPERAND_MAX(scan);
+ brace_count[no] = 0;
+ } else {
+ EMSG(_(e_internal)); /* Shouldn't happen */
+ status = RA_FAIL;
+ }
+ }
+ break;
+
+ case BRACE_COMPLEX + 0:
+ case BRACE_COMPLEX + 1:
+ case BRACE_COMPLEX + 2:
+ case BRACE_COMPLEX + 3:
+ case BRACE_COMPLEX + 4:
+ case BRACE_COMPLEX + 5:
+ case BRACE_COMPLEX + 6:
+ case BRACE_COMPLEX + 7:
+ case BRACE_COMPLEX + 8:
+ case BRACE_COMPLEX + 9:
+ {
+ no = op - BRACE_COMPLEX;
+ ++brace_count[no];
+
+ /* If not matched enough times yet, try one more */
+ if (brace_count[no] <= (brace_min[no] <= brace_max[no]
+ ? brace_min[no] : brace_max[no])) {
+ rp = regstack_push(RS_BRCPLX_MORE, scan);
+ if (rp == NULL)
+ status = RA_FAIL;
+ else {
+ rp->rs_no = no;
+ reg_save(&rp->rs_un.regsave, &backpos);
+ next = OPERAND(scan);
+ /* We continue and handle the result when done. */
+ }
+ break;
+ }
+
+ /* If matched enough times, may try matching some more */
+ if (brace_min[no] <= brace_max[no]) {
+ /* Range is the normal way around, use longest match */
+ if (brace_count[no] <= brace_max[no]) {
+ rp = regstack_push(RS_BRCPLX_LONG, scan);
+ if (rp == NULL)
+ status = RA_FAIL;
+ else {
+ rp->rs_no = no;
+ reg_save(&rp->rs_un.regsave, &backpos);
+ next = OPERAND(scan);
+ /* We continue and handle the result when done. */
+ }
+ }
+ } else {
+ /* Range is backwards, use shortest match first */
+ if (brace_count[no] <= brace_min[no]) {
+ rp = regstack_push(RS_BRCPLX_SHORT, scan);
+ if (rp == NULL)
+ status = RA_FAIL;
+ else {
+ reg_save(&rp->rs_un.regsave, &backpos);
+ /* We continue and handle the result when done. */
+ }
+ }
+ }
+ }
+ break;
+
+ case BRACE_SIMPLE:
+ case STAR:
+ case PLUS:
+ {
+ regstar_T rst;
+
+ /*
+ * Lookahead to avoid useless match attempts when we know
+ * what character comes next.
+ */
+ if (OP(next) == EXACTLY) {
+ rst.nextb = *OPERAND(next);
+ if (ireg_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;
+ }
+ if (op != BRACE_SIMPLE) {
+ rst.minval = (op == STAR) ? 0 : 1;
+ rst.maxval = MAX_LIMIT;
+ } else {
+ rst.minval = bl_minval;
+ rst.maxval = bl_maxval;
+ }
+
+ /*
+ * When maxval > minval, try matching as much as possible, up
+ * to maxval. When maxval < minval, try matching at least the
+ * minimal number (since the range is backwards, that's also
+ * maxval!).
+ */
+ rst.count = regrepeat(OPERAND(scan), rst.maxval);
+ if (got_int) {
+ status = RA_FAIL;
+ break;
+ }
+ if (rst.minval <= rst.maxval
+ ? rst.count >= rst.minval : rst.count >= rst.maxval) {
+ /* It could match. Prepare for trying to match what
+ * follows. The code is below. Parameters are stored in
+ * a regstar_T on the regstack. */
+ if ((long)((unsigned)regstack.ga_len >> 10) >= p_mmp) {
+ EMSG(_(e_maxmempat));
+ status = RA_FAIL;
+ } else if (ga_grow(&regstack, sizeof(regstar_T)) == FAIL)
+ status = RA_FAIL;
+ else {
+ regstack.ga_len += sizeof(regstar_T);
+ rp = regstack_push(rst.minval <= rst.maxval
+ ? RS_STAR_LONG : RS_STAR_SHORT, scan);
+ if (rp == NULL)
+ status = RA_FAIL;
+ else {
+ *(((regstar_T *)rp) - 1) = rst;
+ status = RA_BREAK; /* skip the restore bits */
+ }
+ }
+ } else
+ status = RA_NOMATCH;
+
+ }
+ break;
+
+ case NOMATCH:
+ case MATCH:
+ case SUBPAT:
+ rp = regstack_push(RS_NOMATCH, scan);
+ if (rp == NULL)
+ status = RA_FAIL;
+ else {
+ rp->rs_no = op;
+ reg_save(&rp->rs_un.regsave, &backpos);
+ next = OPERAND(scan);
+ /* We continue and handle the result when done. */
+ }
+ break;
+
+ case BEHIND:
+ case NOBEHIND:
+ /* Need a bit of room to store extra positions. */
+ if ((long)((unsigned)regstack.ga_len >> 10) >= p_mmp) {
+ EMSG(_(e_maxmempat));
+ status = RA_FAIL;
+ } else if (ga_grow(&regstack, sizeof(regbehind_T)) == FAIL)
+ status = RA_FAIL;
+ else {
+ regstack.ga_len += sizeof(regbehind_T);
+ rp = regstack_push(RS_BEHIND1, scan);
+ if (rp == NULL)
+ status = RA_FAIL;
+ else {
+ /* Need to save the subexpr to be able to restore them
+ * when there is a match but we don't use it. */
+ save_subexpr(((regbehind_T *)rp) - 1);
+
+ rp->rs_no = op;
+ reg_save(&rp->rs_un.regsave, &backpos);
+ /* First try if what follows matches. If it does then we
+ * check the behind match by looping. */
+ }
+ }
+ break;
+
+ case BHPOS:
+ if (REG_MULTI) {
+ if (behind_pos.rs_u.pos.col != (colnr_T)(reginput - regline)
+ || behind_pos.rs_u.pos.lnum != reglnum)
+ status = RA_NOMATCH;
+ } else if (behind_pos.rs_u.ptr != reginput)
+ status = RA_NOMATCH;
+ break;
+
+ case NEWL:
+ if ((c != NUL || !REG_MULTI || reglnum > reg_maxline
+ || reg_line_lbr) && (c != '\n' || !reg_line_lbr))
+ status = RA_NOMATCH;
+ else if (reg_line_lbr)
+ ADVANCE_REGINPUT();
+ else
+ reg_nextline();
+ break;
+
+ case END:
+ status = RA_MATCH; /* Success! */
+ break;
+
+ default:
+ EMSG(_(e_re_corr));
+#ifdef REGEXP_DEBUG
+ printf("Illegal op code %d\n", op);
+#endif
+ status = RA_FAIL;
+ break;
+ }
+ }
+
+ /* If we can't continue sequentially, break the inner loop. */
+ if (status != RA_CONT)
+ break;
+
+ /* Continue in inner loop, advance to next item. */
+ scan = next;
+
+ } /* end of inner loop */
+
+ /*
+ * If there is something on the regstack execute the code for the state.
+ * If the state is popped then loop and use the older state.
+ */
+ while (regstack.ga_len > 0 && status != RA_FAIL) {
+ rp = (regitem_T *)((char *)regstack.ga_data + regstack.ga_len) - 1;
+ switch (rp->rs_state) {
+ case RS_NOPEN:
+ /* Result is passed on as-is, simply pop the state. */
+ regstack_pop(&scan);
+ 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]);
+ regstack_pop(&scan);
+ break;
+
+ case RS_ZOPEN:
+ /* Pop the state. Restore pointers when there is no match. */
+ if (status == RA_NOMATCH)
+ restore_se(&rp->rs_un.sesave, &reg_startzpos[rp->rs_no],
+ &reg_startzp[rp->rs_no]);
+ regstack_pop(&scan);
+ 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]);
+ regstack_pop(&scan);
+ break;
+
+ case RS_ZCLOSE:
+ /* Pop the state. Restore pointers when there is no match. */
+ if (status == RA_NOMATCH)
+ restore_se(&rp->rs_un.sesave, &reg_endzpos[rp->rs_no],
+ &reg_endzp[rp->rs_no]);
+ regstack_pop(&scan);
+ break;
+
+ case RS_BRANCH:
+ if (status == RA_MATCH)
+ /* this branch matched, use it */
+ regstack_pop(&scan);
+ else {
+ if (status != RA_BREAK) {
+ /* After a non-matching branch: try next one. */
+ reg_restore(&rp->rs_un.regsave, &backpos);
+ scan = rp->rs_scan;
+ }
+ if (scan == NULL || OP(scan) != BRANCH) {
+ /* no more branches, didn't find a match */
+ status = RA_NOMATCH;
+ regstack_pop(&scan);
+ } else {
+ /* Prepare to try a branch. */
+ rp->rs_scan = regnext(scan);
+ reg_save(&rp->rs_un.regsave, &backpos);
+ scan = OPERAND(scan);
+ }
+ }
+ break;
+
+ case RS_BRCPLX_MORE:
+ /* Pop the state. Restore pointers when there is no match. */
+ if (status == RA_NOMATCH) {
+ reg_restore(&rp->rs_un.regsave, &backpos);
+ --brace_count[rp->rs_no]; /* decrement match count */
+ }
+ regstack_pop(&scan);
+ break;
+
+ case RS_BRCPLX_LONG:
+ /* Pop the state. Restore pointers when there is no match. */
+ if (status == RA_NOMATCH) {
+ /* There was no match, but we did find enough matches. */
+ reg_restore(&rp->rs_un.regsave, &backpos);
+ --brace_count[rp->rs_no];
+ /* continue with the items after "\{}" */
+ status = RA_CONT;
+ }
+ regstack_pop(&scan);
+ if (status == RA_CONT)
+ scan = regnext(scan);
+ break;
+
+ case RS_BRCPLX_SHORT:
+ /* Pop the state. Restore pointers when there is no match. */
+ if (status == RA_NOMATCH)
+ /* There was no match, try to match one more item. */
+ reg_restore(&rp->rs_un.regsave, &backpos);
+ regstack_pop(&scan);
+ if (status == RA_NOMATCH) {
+ scan = OPERAND(scan);
+ status = RA_CONT;
+ }
+ break;
+
+ case RS_NOMATCH:
+ /* Pop the state. If the operand matches for NOMATCH or
+ * doesn't match for MATCH/SUBPAT, we fail. Otherwise backup,
+ * except for SUBPAT, and continue with the next item. */
+ if (status == (rp->rs_no == NOMATCH ? RA_MATCH : RA_NOMATCH))
+ status = RA_NOMATCH;
+ else {
+ status = RA_CONT;
+ if (rp->rs_no != SUBPAT) /* zero-width */
+ reg_restore(&rp->rs_un.regsave, &backpos);
+ }
+ regstack_pop(&scan);
+ if (status == RA_CONT)
+ scan = regnext(scan);
+ break;
+
+ case RS_BEHIND1:
+ if (status == RA_NOMATCH) {
+ regstack_pop(&scan);
+ regstack.ga_len -= sizeof(regbehind_T);
+ } else {
+ /* The stuff after BEHIND/NOBEHIND matches. Now try if
+ * the behind part does (not) match before the current
+ * position in the input. This must be done at every
+ * position in the input and checking if the match ends at
+ * the current position. */
+
+ /* save the position after the found match for next */
+ reg_save(&(((regbehind_T *)rp) - 1)->save_after, &backpos);
+
+ /* Start looking for a match with operand at the current
+ * position. Go back one character until we find the
+ * result, hitting the start of the line or the previous
+ * line (for multi-line matching).
+ * Set behind_pos to where the match should end, BHPOS
+ * will match it. Save the current value. */
+ (((regbehind_T *)rp) - 1)->save_behind = behind_pos;
+ behind_pos = rp->rs_un.regsave;
+
+ rp->rs_state = RS_BEHIND2;
+
+ reg_restore(&rp->rs_un.regsave, &backpos);
+ scan = OPERAND(rp->rs_scan) + 4;
+ }
+ break;
+
+ case RS_BEHIND2:
+ /*
+ * Looping for BEHIND / NOBEHIND match.
+ */
+ if (status == RA_MATCH && reg_save_equal(&behind_pos)) {
+ /* found a match that ends where "next" started */
+ behind_pos = (((regbehind_T *)rp) - 1)->save_behind;
+ if (rp->rs_no == BEHIND)
+ reg_restore(&(((regbehind_T *)rp) - 1)->save_after,
+ &backpos);
+ else {
+ /* But we didn't want a match. Need to restore the
+ * subexpr, because what follows matched, so they have
+ * been set. */
+ status = RA_NOMATCH;
+ restore_subexpr(((regbehind_T *)rp) - 1);
+ }
+ regstack_pop(&scan);
+ regstack.ga_len -= sizeof(regbehind_T);
+ } else {
+ long limit;
+
+ /* No match or a match that doesn't end where we want it: Go
+ * back one character. May go to previous line once. */
+ no = OK;
+ limit = OPERAND_MIN(rp->rs_scan);
+ if (REG_MULTI) {
+ if (limit > 0
+ && ((rp->rs_un.regsave.rs_u.pos.lnum
+ < behind_pos.rs_u.pos.lnum
+ ? (colnr_T)STRLEN(regline)
+ : behind_pos.rs_u.pos.col)
+ - rp->rs_un.regsave.rs_u.pos.col >= limit))
+ no = FAIL;
+ else if (rp->rs_un.regsave.rs_u.pos.col == 0) {
+ if (rp->rs_un.regsave.rs_u.pos.lnum
+ < behind_pos.rs_u.pos.lnum
+ || reg_getline(
+ --rp->rs_un.regsave.rs_u.pos.lnum)
+ == NULL)
+ no = FAIL;
+ else {
+ reg_restore(&rp->rs_un.regsave, &backpos);
+ rp->rs_un.regsave.rs_u.pos.col =
+ (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;
+ }
+ } else {
+ 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)
+ no = FAIL;
+ }
+ }
+ if (no == OK) {
+ /* Advanced, prepare for finding match again. */
+ reg_restore(&rp->rs_un.regsave, &backpos);
+ scan = OPERAND(rp->rs_scan) + 4;
+ if (status == RA_MATCH) {
+ /* We did match, so subexpr may have been changed,
+ * need to restore them for the next try. */
+ status = RA_NOMATCH;
+ restore_subexpr(((regbehind_T *)rp) - 1);
+ }
+ } else {
+ /* Can't advance. For NOBEHIND that's a match. */
+ behind_pos = (((regbehind_T *)rp) - 1)->save_behind;
+ if (rp->rs_no == NOBEHIND) {
+ reg_restore(&(((regbehind_T *)rp) - 1)->save_after,
+ &backpos);
+ status = RA_MATCH;
+ } else {
+ /* We do want a proper match. Need to restore the
+ * subexpr if we had a match, because they may have
+ * been set. */
+ if (status == RA_MATCH) {
+ status = RA_NOMATCH;
+ restore_subexpr(((regbehind_T *)rp) - 1);
+ }
+ }
+ regstack_pop(&scan);
+ regstack.ga_len -= sizeof(regbehind_T);
+ }
+ }
+ break;
+
+ case RS_STAR_LONG:
+ case RS_STAR_SHORT:
+ {
+ regstar_T *rst = ((regstar_T *)rp) - 1;
+
+ if (status == RA_MATCH) {
+ regstack_pop(&scan);
+ regstack.ga_len -= sizeof(regstar_T);
+ break;
+ }
+
+ /* Tried once already, restore input pointers. */
+ if (status != RA_BREAK)
+ reg_restore(&rp->rs_un.regsave, &backpos);
+
+ /* Repeat until we found a position where it could match. */
+ for (;; ) {
+ if (status != RA_BREAK) {
+ /* Tried first position already, advance. */
+ if (rp->rs_state == RS_STAR_LONG) {
+ /* Trying for longest match, but couldn't or
+ * didn't match -- back up one char. */
+ if (--rst->count < rst->minval)
+ break;
+ if (reginput == regline) {
+ /* backup to last char of previous line */
+ --reglnum;
+ regline = reg_getline(reglnum);
+ /* 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 {
+ /* Range is backwards, use shortest match first.
+ * Careful: maxval and minval are exchanged!
+ * Couldn't or didn't match: try advancing one
+ * char. */
+ if (rst->count == rst->minval
+ || regrepeat(OPERAND(rp->rs_scan), 1L) == 0)
+ break;
+ ++rst->count;
+ }
+ if (got_int)
+ break;
+ } else
+ status = RA_NOMATCH;
+
+ /* If it could match, try it. */
+ if (rst->nextb == NUL || *reginput == rst->nextb
+ || *reginput == rst->nextb_ic) {
+ reg_save(&rp->rs_un.regsave, &backpos);
+ scan = regnext(rp->rs_scan);
+ status = RA_CONT;
+ break;
+ }
+ }
+ if (status != RA_CONT) {
+ /* Failed. */
+ regstack_pop(&scan);
+ regstack.ga_len -= sizeof(regstar_T);
+ status = RA_NOMATCH;
+ }
+ }
+ break;
+ }
+
+ /* If we want to continue the inner loop or didn't pop a state
+ * continue matching loop */
+ if (status == RA_CONT || rp == (regitem_T *)
+ ((char *)regstack.ga_data + regstack.ga_len) - 1)
+ break;
+ }
+
+ /* May need to continue with the inner loop, starting at "scan". */
+ if (status == RA_CONT)
+ continue;
+
+ /*
+ * If the regstack is empty or something failed we are done.
+ */
+ if (regstack.ga_len == 0 || status == RA_FAIL) {
+ if (scan == NULL) {
+ /*
+ * We get here only if there's trouble -- normally "case END" is
+ * the terminating point.
+ */
+ EMSG(_(e_re_corr));
+#ifdef REGEXP_DEBUG
+ printf("Premature EOL\n");
+#endif
+ }
+ if (status == RA_FAIL)
+ got_int = TRUE;
+ return status == RA_MATCH;
+ }
+
+ } /* End of loop until the regstack is empty. */
+
+ /* NOTREACHED */
+}
+
+/*
+ * Push an item onto the regstack.
+ * Returns pointer to new item. Returns NULL when out of memory.
+ */
+static regitem_T * regstack_push(state, scan)
+regstate_T state;
+char_u *scan;
+{
+ regitem_T *rp;
+
+ if ((long)((unsigned)regstack.ga_len >> 10) >= p_mmp) {
+ EMSG(_(e_maxmempat));
+ return NULL;
+ }
+ if (ga_grow(&regstack, sizeof(regitem_T)) == FAIL)
+ return NULL;
+
+ rp = (regitem_T *)((char *)regstack.ga_data + regstack.ga_len);
+ rp->rs_state = state;
+ rp->rs_scan = scan;
+
+ regstack.ga_len += sizeof(regitem_T);
+ return rp;
+}
+
+/*
+ * Pop an item from the regstack.
+ */
+static void regstack_pop(scan)
+char_u **scan;
+{
+ regitem_T *rp;
+
+ rp = (regitem_T *)((char *)regstack.ga_data + regstack.ga_len) - 1;
+ *scan = rp->rs_scan;
+
+ regstack.ga_len -= sizeof(regitem_T);
+}
+
+/*
+ * regrepeat - repeatedly match something simple, return how many.
+ * Advances reginput (and reglnum) to just after the matched chars.
+ */
+static int regrepeat(p, maxcount)
+char_u *p;
+long maxcount; /* maximum number of matches allowed */
+{
+ long count = 0;
+ char_u *scan;
+ char_u *opnd;
+ int mask;
+ int testval = 0;
+
+ scan = reginput; /* Make local copy of reginput for speed. */
+ opnd = OPERAND(p);
+ switch (OP(p)) {
+ case ANY:
+ case ANY + ADD_NL:
+ while (count < maxcount) {
+ /* 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);
+ }
+ if (!REG_MULTI || !WITH_NL(OP(p)) || reglnum > reg_maxline
+ || reg_line_lbr || count == maxcount)
+ break;
+ ++count; /* count the line-break */
+ reg_nextline();
+ scan = reginput;
+ if (got_int)
+ break;
+ }
+ break;
+
+ case IDENT:
+ case IDENT + ADD_NL:
+ testval = TRUE;
+ /*FALLTHROUGH*/
+ case SIDENT:
+ case SIDENT + ADD_NL:
+ while (count < maxcount) {
+ if (vim_isIDc(PTR2CHAR(scan)) && (testval || !VIM_ISDIGIT(*scan))) {
+ mb_ptr_adv(scan);
+ } else if (*scan == NUL) {
+ if (!REG_MULTI || !WITH_NL(OP(p)) || reglnum > reg_maxline
+ || 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
+ break;
+ ++count;
+ }
+ break;
+
+ case KWORD:
+ case KWORD + ADD_NL:
+ testval = TRUE;
+ /*FALLTHROUGH*/
+ case SKWORD:
+ case SKWORD + ADD_NL:
+ while (count < maxcount) {
+ if (vim_iswordp_buf(scan, reg_buf)
+ && (testval || !VIM_ISDIGIT(*scan))) {
+ mb_ptr_adv(scan);
+ } else if (*scan == NUL) {
+ if (!REG_MULTI || !WITH_NL(OP(p)) || reglnum > reg_maxline
+ || 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
+ break;
+ ++count;
+ }
+ break;
+
+ case FNAME:
+ case FNAME + ADD_NL:
+ testval = TRUE;
+ /*FALLTHROUGH*/
+ case SFNAME:
+ case SFNAME + ADD_NL:
+ while (count < maxcount) {
+ if (vim_isfilec(PTR2CHAR(scan)) && (testval || !VIM_ISDIGIT(*scan))) {
+ mb_ptr_adv(scan);
+ } else if (*scan == NUL) {
+ if (!REG_MULTI || !WITH_NL(OP(p)) || reglnum > reg_maxline
+ || 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
+ break;
+ ++count;
+ }
+ break;
+
+ case PRINT:
+ case PRINT + ADD_NL:
+ testval = TRUE;
+ /*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)
+ break;
+ reg_nextline();
+ scan = reginput;
+ if (got_int)
+ break;
+ } else if (vim_isprintc(PTR2CHAR(scan)) == 1
+ && (testval || !VIM_ISDIGIT(*scan))) {
+ mb_ptr_adv(scan);
+ } else if (reg_line_lbr && *scan == '\n' && WITH_NL(OP(p)))
+ ++scan;
+ else
+ break;
+ ++count;
+ }
+ break;
+
+ case WHITE:
+ case WHITE + ADD_NL:
+ testval = mask = RI_WHITE;
+do_class:
+ while (count < maxcount) {
+ int l;
+ if (*scan == NUL) {
+ if (!REG_MULTI || !WITH_NL(OP(p)) || reglnum > reg_maxline
+ || reg_line_lbr)
+ break;
+ reg_nextline();
+ scan = reginput;
+ if (got_int)
+ break;
+ } else if (has_mbyte && (l = (*mb_ptr2len)(scan)) > 1) {
+ 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
+ break;
+ ++count;
+ }
+ break;
+
+ case NWHITE:
+ case NWHITE + ADD_NL:
+ mask = RI_WHITE;
+ goto do_class;
+ case DIGIT:
+ case DIGIT + ADD_NL:
+ testval = mask = RI_DIGIT;
+ goto do_class;
+ case NDIGIT:
+ case NDIGIT + ADD_NL:
+ mask = RI_DIGIT;
+ goto do_class;
+ case HEX:
+ case HEX + ADD_NL:
+ testval = mask = RI_HEX;
+ goto do_class;
+ case NHEX:
+ case NHEX + ADD_NL:
+ mask = RI_HEX;
+ goto do_class;
+ case OCTAL:
+ case OCTAL + ADD_NL:
+ testval = mask = RI_OCTAL;
+ goto do_class;
+ case NOCTAL:
+ case NOCTAL + ADD_NL:
+ mask = RI_OCTAL;
+ goto do_class;
+ case WORD:
+ case WORD + ADD_NL:
+ testval = mask = RI_WORD;
+ goto do_class;
+ case NWORD:
+ case NWORD + ADD_NL:
+ mask = RI_WORD;
+ goto do_class;
+ case HEAD:
+ case HEAD + ADD_NL:
+ testval = mask = RI_HEAD;
+ goto do_class;
+ case NHEAD:
+ case NHEAD + ADD_NL:
+ mask = RI_HEAD;
+ goto do_class;
+ case ALPHA:
+ case ALPHA + ADD_NL:
+ testval = mask = RI_ALPHA;
+ goto do_class;
+ case NALPHA:
+ case NALPHA + ADD_NL:
+ mask = RI_ALPHA;
+ goto do_class;
+ case LOWER:
+ case LOWER + ADD_NL:
+ testval = mask = RI_LOWER;
+ goto do_class;
+ case NLOWER:
+ case NLOWER + ADD_NL:
+ mask = RI_LOWER;
+ goto do_class;
+ case UPPER:
+ case UPPER + ADD_NL:
+ testval = mask = RI_UPPER;
+ goto do_class;
+ case NUPPER:
+ case NUPPER + ADD_NL:
+ mask = RI_UPPER;
+ goto do_class;
+
+ case EXACTLY:
+ {
+ 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 = MB_TOUPPER(*opnd);
+ cl = MB_TOLOWER(*opnd);
+ while (count < maxcount && (*scan == cu || *scan == cl)) {
+ count++;
+ scan++;
+ }
+ } else {
+ cu = *opnd;
+ while (count < maxcount && *scan == cu) {
+ count++;
+ scan++;
+ }
+ }
+ break;
+ }
+
+ case MULTIBYTECODE:
+ {
+ int i, len, cf = 0;
+
+ /* Safety check (just in case 'encoding' was changed since
+ * compiling the program). */
+ if ((len = (*mb_ptr2len)(opnd)) > 1) {
+ if (ireg_ic && enc_utf8)
+ cf = utf_fold(utf_ptr2char(opnd));
+ while (count < maxcount) {
+ 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))
+ break;
+ scan += len;
+ ++count;
+ }
+ }
+ }
+ break;
+
+ case ANYOF:
+ case ANYOF + ADD_NL:
+ testval = TRUE;
+ /*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)
+ break;
+ reg_nextline();
+ scan = reginput;
+ 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)
+ break;
+ scan += len;
+ } else {
+ if ((cstrchr(opnd, *scan) == NULL) == testval)
+ break;
+ ++scan;
+ }
+ ++count;
+ }
+ break;
+
+ case NEWL:
+ while (count < maxcount
+ && ((*scan == NUL && reglnum <= reg_maxline && !reg_line_lbr
+ && REG_MULTI) || (*scan == '\n' && reg_line_lbr))) {
+ count++;
+ if (reg_line_lbr)
+ ADVANCE_REGINPUT();
+ else
+ reg_nextline();
+ scan = reginput;
+ if (got_int)
+ break;
+ }
+ break;
+
+ default: /* Oh dear. Called inappropriately. */
+ EMSG(_(e_re_corr));
+#ifdef REGEXP_DEBUG
+ printf("Called regrepeat with op code %d\n", OP(p));
+#endif
+ break;
+ }
+
+ reginput = scan;
+
+ return (int)count;
+}
+
+/*
+ * regnext - dig the "next" pointer out of a node
+ * Returns NULL when calculating size, when there is no next item and when
+ * there is an error.
+ */
+static char_u * regnext(p)
+char_u *p;
+{
+ int offset;
+
+ if (p == JUST_CALC_SIZE || reg_toolong)
+ return NULL;
+
+ offset = NEXT(p);
+ if (offset == 0)
+ return NULL;
+
+ if (OP(p) == BACK)
+ return p - offset;
+ else
+ return p + offset;
+}
+
+/*
+ * Check the regexp program for its magic number.
+ * Return TRUE if it's wrong.
+ */
+static int prog_magic_wrong() {
+ 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;
+
+ if (UCHARAT(((bt_regprog_T *)prog)->program) != REGMAGIC) {
+ EMSG(_(e_re_corr));
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*
+ * Cleanup the subexpressions, if this wasn't done yet.
+ * This construction is used to clear the subexpressions only when they are
+ * used (to increase speed).
+ */
+static void cleanup_subexpr() {
+ if (need_clear_subexpr) {
+ if (REG_MULTI) {
+ /* Use 0xff to set lnum to -1 */
+ vim_memset(reg_startpos, 0xff, sizeof(lpos_T) * NSUBEXP);
+ vim_memset(reg_endpos, 0xff, sizeof(lpos_T) * NSUBEXP);
+ } else {
+ vim_memset(reg_startp, 0, sizeof(char_u *) * NSUBEXP);
+ vim_memset(reg_endp, 0, sizeof(char_u *) * NSUBEXP);
+ }
+ need_clear_subexpr = FALSE;
+ }
+}
+
+static void cleanup_zsubexpr() {
+ if (need_clear_zsubexpr) {
+ if (REG_MULTI) {
+ /* Use 0xff to set lnum to -1 */
+ vim_memset(reg_startzpos, 0xff, sizeof(lpos_T) * NSUBEXP);
+ vim_memset(reg_endzpos, 0xff, sizeof(lpos_T) * NSUBEXP);
+ } else {
+ vim_memset(reg_startzp, 0, sizeof(char_u *) * NSUBEXP);
+ vim_memset(reg_endzp, 0, sizeof(char_u *) * NSUBEXP);
+ }
+ need_clear_zsubexpr = FALSE;
+ }
+}
+
+/*
+ * Save the current subexpr to "bp", so that they can be restored
+ * later by restore_subexpr().
+ */
+static void save_subexpr(bp)
+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. */
+ 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];
+ } else {
+ bp->save_start[i].se_u.ptr = reg_startp[i];
+ bp->save_end[i].se_u.ptr = reg_endp[i];
+ }
+ }
+ }
+}
+
+/*
+ * Restore the subexpr from "bp".
+ */
+static void restore_subexpr(bp)
+regbehind_T *bp;
+{
+ int i;
+
+ /* Only need to restore saved values when they are not to be cleared. */
+ need_clear_subexpr = bp->save_need_clear_subexpr;
+ 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;
+ } else {
+ reg_startp[i] = bp->save_start[i].se_u.ptr;
+ reg_endp[i] = bp->save_end[i].se_u.ptr;
+ }
+ }
+ }
+}
+
+/*
+ * Advance reglnum, regline and reginput to the next line.
+ */
+static void reg_nextline() {
+ regline = reg_getline(++reglnum);
+ reginput = regline;
+ fast_breakcheck();
+}
+
+/*
+ * Save the input line and position in a regsave_T.
+ */
+static void reg_save(save, gap)
+regsave_T *save;
+garray_T *gap;
+{
+ if (REG_MULTI) {
+ save->rs_u.pos.col = (colnr_T)(reginput - regline);
+ save->rs_u.pos.lnum = reglnum;
+ } else
+ save->rs_u.ptr = reginput;
+ save->rs_len = gap->ga_len;
+}
+
+/*
+ * Restore the input line and position from a regsave_T.
+ */
+static void reg_restore(save, gap)
+regsave_T *save;
+garray_T *gap;
+{
+ if (REG_MULTI) {
+ if (reglnum != save->rs_u.pos.lnum) {
+ /* only call reg_getline() when the line number changed to save
+ * a bit of time */
+ reglnum = save->rs_u.pos.lnum;
+ regline = reg_getline(reglnum);
+ }
+ reginput = regline + save->rs_u.pos.col;
+ } else
+ reginput = save->rs_u.ptr;
+ gap->ga_len = save->rs_len;
+}
+
+/*
+ * Return TRUE if current position is equal to saved position.
+ */
+static int reg_save_equal(save)
+regsave_T *save;
+{
+ if (REG_MULTI)
+ return reglnum == save->rs_u.pos.lnum
+ && reginput == regline + save->rs_u.pos.col;
+ return reginput == save->rs_u.ptr;
+}
+
+/*
+ * Tentatively set the sub-expression start to the current position (after
+ * calling regmatch() they will have changed). Need to save the existing
+ * values for when there is no match.
+ * Use se_save() to use pointer (save_se_multi()) or position (save_se_one()),
+ * depending on REG_MULTI.
+ */
+static void save_se_multi(savep, posp)
+save_se_T *savep;
+lpos_T *posp;
+{
+ savep->se_u.pos = *posp;
+ posp->lnum = reglnum;
+ posp->col = (colnr_T)(reginput - regline);
+}
+
+static void save_se_one(savep, pp)
+save_se_T *savep;
+char_u **pp;
+{
+ savep->se_u.ptr = *pp;
+ *pp = reginput;
+}
+
+/*
+ * Compare a number with the operand of RE_LNUM, RE_COL or RE_VCOL.
+ */
+static int re_num_cmp(val, scan)
+long_u val;
+char_u *scan;
+{
+ long_u n = OPERAND_MIN(scan);
+
+ if (OPERAND_CMP(scan) == '>')
+ return val > n;
+ if (OPERAND_CMP(scan) == '<')
+ return val < n;
+ return val == n;
+}
+
+/*
+ * Check whether a backreference matches.
+ * Returns RA_FAIL, RA_NOMATCH or RA_MATCH.
+ * If "bytelen" is not NULL, it is set to the byte length of the match in the
+ * last line.
+ */
+static int match_with_backref(start_lnum, start_col, end_lnum, end_col, bytelen)
+linenr_T start_lnum;
+colnr_T start_col;
+linenr_T end_lnum;
+colnr_T end_col;
+int *bytelen;
+{
+ linenr_T clnum = start_lnum;
+ colnr_T ccol = start_col;
+ int len;
+ char_u *p;
+
+ if (bytelen != NULL)
+ *bytelen = 0;
+ for (;; ) {
+ /* Since getting one line may invalidate the other, need to make copy.
+ * Slow! */
+ if (regline != reg_tofree) {
+ len = (int)STRLEN(regline);
+ if (reg_tofree == NULL || len >= (int)reg_tofreelen) {
+ len += 50; /* get some extra */
+ vim_free(reg_tofree);
+ reg_tofree = alloc(len);
+ if (reg_tofree == NULL)
+ return RA_FAIL; /* out of memory!*/
+ reg_tofreelen = len;
+ }
+ STRCPY(reg_tofree, regline);
+ reginput = reg_tofree + (reginput - regline);
+ regline = reg_tofree;
+ }
+
+ /* Get the line to compare with. */
+ p = reg_getline(clnum);
+ if (clnum == end_lnum)
+ len = end_col - ccol;
+ else
+ len = (int)STRLEN(p + ccol);
+
+ if (cstrncmp(p + ccol, reginput, &len) != 0)
+ 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 */
+
+ /* Advance to next line. */
+ reg_nextline();
+ if (bytelen != NULL)
+ *bytelen = 0;
+ ++clnum;
+ ccol = 0;
+ if (got_int)
+ return RA_FAIL;
+ }
+
+ /* found a match! Note that regline may now point to a copy of the line,
+ * that should not matter. */
+ return RA_MATCH;
+}
+
+#ifdef BT_REGEXP_DUMP
+
+/*
+ * regdump - dump a regexp onto stdout in vaguely comprehensible form
+ */
+static void regdump(pattern, r)
+char_u *pattern;
+bt_regprog_T *r;
+{
+ char_u *s;
+ int op = EXACTLY; /* Arbitrary non-END op. */
+ char_u *next;
+ char_u *end = NULL;
+ FILE *f;
+
+#ifdef BT_REGEXP_LOG
+ f = fopen("bt_regexp_log.log", "a");
+#else
+ f = stdout;
+#endif
+ if (f == NULL)
+ return;
+ fprintf(f, "-------------------------------------\n\r\nregcomp(%s):\r\n",
+ pattern);
+
+ s = r->program + 1;
+ /*
+ * Loop until we find the END that isn't before a referred next (an END
+ * can also appear in a NOMATCH operand).
+ */
+ while (op != END || s <= end) {
+ op = OP(s);
+ fprintf(f, "%2d%s", (int)(s - r->program), regprop(s)); /* Where, what. */
+ next = regnext(s);
+ if (next == NULL) /* Next ptr. */
+ fprintf(f, "(0)");
+ else
+ fprintf(f, "(%d)", (int)((s - r->program) + (next - s)));
+ if (end < next)
+ end = next;
+ if (op == BRACE_LIMITS) {
+ /* Two ints */
+ fprintf(f, " minval %ld, maxval %ld", OPERAND_MIN(s), OPERAND_MAX(s));
+ s += 8;
+ } else if (op == BEHIND || op == NOBEHIND) {
+ /* one int */
+ fprintf(f, " count %ld", OPERAND_MIN(s));
+ s += 4;
+ } else if (op == RE_LNUM || op == RE_COL || op == RE_VCOL) {
+ /* one int plus comperator */
+ fprintf(f, " count %ld", OPERAND_MIN(s));
+ s += 5;
+ }
+ s += 3;
+ if (op == ANYOF || op == ANYOF + ADD_NL
+ || op == ANYBUT || op == ANYBUT + ADD_NL
+ || op == EXACTLY) {
+ /* Literal string, where present. */
+ fprintf(f, "\nxxxxxxxxx\n");
+ while (*s != NUL)
+ fprintf(f, "%c", *s++);
+ fprintf(f, "\nxxxxxxxxx\n");
+ s++;
+ }
+ fprintf(f, "\r\n");
+ }
+
+ /* Header fields of interest. */
+ if (r->regstart != NUL)
+ fprintf(f, "start `%s' 0x%x; ", r->regstart < 256
+ ? (char *)transchar(r->regstart)
+ : "multibyte", r->regstart);
+ if (r->reganch)
+ fprintf(f, "anchored; ");
+ if (r->regmust != NULL)
+ fprintf(f, "must have \"%s\"", r->regmust);
+ fprintf(f, "\r\n");
+
+#ifdef BT_REGEXP_LOG
+ fclose(f);
+#endif
+}
+#endif /* BT_REGEXP_DUMP */
+
+#ifdef REGEXP_DEBUG
+/*
+ * regprop - printable representation of opcode
+ */
+static char_u * regprop(op)
+char_u *op;
+{
+ char *p;
+ static char buf[50];
+
+ STRCPY(buf, ":");
+
+ switch ((int) OP(op)) {
+ case BOL:
+ p = "BOL";
+ break;
+ case EOL:
+ p = "EOL";
+ break;
+ case RE_BOF:
+ p = "BOF";
+ break;
+ case RE_EOF:
+ p = "EOF";
+ break;
+ case CURSOR:
+ p = "CURSOR";
+ break;
+ case RE_VISUAL:
+ p = "RE_VISUAL";
+ break;
+ case RE_LNUM:
+ p = "RE_LNUM";
+ break;
+ case RE_MARK:
+ p = "RE_MARK";
+ break;
+ case RE_COL:
+ p = "RE_COL";
+ break;
+ case RE_VCOL:
+ p = "RE_VCOL";
+ break;
+ case BOW:
+ p = "BOW";
+ break;
+ case EOW:
+ p = "EOW";
+ break;
+ case ANY:
+ p = "ANY";
+ break;
+ case ANY + ADD_NL:
+ p = "ANY+NL";
+ break;
+ case ANYOF:
+ p = "ANYOF";
+ break;
+ case ANYOF + ADD_NL:
+ p = "ANYOF+NL";
+ break;
+ case ANYBUT:
+ p = "ANYBUT";
+ break;
+ case ANYBUT + ADD_NL:
+ p = "ANYBUT+NL";
+ break;
+ case IDENT:
+ p = "IDENT";
+ break;
+ case IDENT + ADD_NL:
+ p = "IDENT+NL";
+ break;
+ case SIDENT:
+ p = "SIDENT";
+ break;
+ case SIDENT + ADD_NL:
+ p = "SIDENT+NL";
+ break;
+ case KWORD:
+ p = "KWORD";
+ break;
+ case KWORD + ADD_NL:
+ p = "KWORD+NL";
+ break;
+ case SKWORD:
+ p = "SKWORD";
+ break;
+ case SKWORD + ADD_NL:
+ p = "SKWORD+NL";
+ break;
+ case FNAME:
+ p = "FNAME";
+ break;
+ case FNAME + ADD_NL:
+ p = "FNAME+NL";
+ break;
+ case SFNAME:
+ p = "SFNAME";
+ break;
+ case SFNAME + ADD_NL:
+ p = "SFNAME+NL";
+ break;
+ case PRINT:
+ p = "PRINT";
+ break;
+ case PRINT + ADD_NL:
+ p = "PRINT+NL";
+ break;
+ case SPRINT:
+ p = "SPRINT";
+ break;
+ case SPRINT + ADD_NL:
+ p = "SPRINT+NL";
+ break;
+ case WHITE:
+ p = "WHITE";
+ break;
+ case WHITE + ADD_NL:
+ p = "WHITE+NL";
+ break;
+ case NWHITE:
+ p = "NWHITE";
+ break;
+ case NWHITE + ADD_NL:
+ p = "NWHITE+NL";
+ break;
+ case DIGIT:
+ p = "DIGIT";
+ break;
+ case DIGIT + ADD_NL:
+ p = "DIGIT+NL";
+ break;
+ case NDIGIT:
+ p = "NDIGIT";
+ break;
+ case NDIGIT + ADD_NL:
+ p = "NDIGIT+NL";
+ break;
+ case HEX:
+ p = "HEX";
+ break;
+ case HEX + ADD_NL:
+ p = "HEX+NL";
+ break;
+ case NHEX:
+ p = "NHEX";
+ break;
+ case NHEX + ADD_NL:
+ p = "NHEX+NL";
+ break;
+ case OCTAL:
+ p = "OCTAL";
+ break;
+ case OCTAL + ADD_NL:
+ p = "OCTAL+NL";
+ break;
+ case NOCTAL:
+ p = "NOCTAL";
+ break;
+ case NOCTAL + ADD_NL:
+ p = "NOCTAL+NL";
+ break;
+ case WORD:
+ p = "WORD";
+ break;
+ case WORD + ADD_NL:
+ p = "WORD+NL";
+ break;
+ case NWORD:
+ p = "NWORD";
+ break;
+ case NWORD + ADD_NL:
+ p = "NWORD+NL";
+ break;
+ case HEAD:
+ p = "HEAD";
+ break;
+ case HEAD + ADD_NL:
+ p = "HEAD+NL";
+ break;
+ case NHEAD:
+ p = "NHEAD";
+ break;
+ case NHEAD + ADD_NL:
+ p = "NHEAD+NL";
+ break;
+ case ALPHA:
+ p = "ALPHA";
+ break;
+ case ALPHA + ADD_NL:
+ p = "ALPHA+NL";
+ break;
+ case NALPHA:
+ p = "NALPHA";
+ break;
+ case NALPHA + ADD_NL:
+ p = "NALPHA+NL";
+ break;
+ case LOWER:
+ p = "LOWER";
+ break;
+ case LOWER + ADD_NL:
+ p = "LOWER+NL";
+ break;
+ case NLOWER:
+ p = "NLOWER";
+ break;
+ case NLOWER + ADD_NL:
+ p = "NLOWER+NL";
+ break;
+ case UPPER:
+ p = "UPPER";
+ break;
+ case UPPER + ADD_NL:
+ p = "UPPER+NL";
+ break;
+ case NUPPER:
+ p = "NUPPER";
+ break;
+ case NUPPER + ADD_NL:
+ p = "NUPPER+NL";
+ break;
+ case BRANCH:
+ p = "BRANCH";
+ break;
+ case EXACTLY:
+ p = "EXACTLY";
+ break;
+ case NOTHING:
+ p = "NOTHING";
+ break;
+ case BACK:
+ p = "BACK";
+ break;
+ case END:
+ p = "END";
+ break;
+ case MOPEN + 0:
+ p = "MATCH START";
+ break;
+ case MOPEN + 1:
+ case MOPEN + 2:
+ case MOPEN + 3:
+ case MOPEN + 4:
+ case MOPEN + 5:
+ case MOPEN + 6:
+ case MOPEN + 7:
+ case MOPEN + 8:
+ case MOPEN + 9:
+ sprintf(buf + STRLEN(buf), "MOPEN%d", OP(op) - MOPEN);
+ p = NULL;
+ break;
+ case MCLOSE + 0:
+ p = "MATCH END";
+ break;
+ case MCLOSE + 1:
+ case MCLOSE + 2:
+ case MCLOSE + 3:
+ case MCLOSE + 4:
+ case MCLOSE + 5:
+ case MCLOSE + 6:
+ case MCLOSE + 7:
+ case MCLOSE + 8:
+ case MCLOSE + 9:
+ sprintf(buf + STRLEN(buf), "MCLOSE%d", OP(op) - MCLOSE);
+ p = NULL;
+ break;
+ case BACKREF + 1:
+ case BACKREF + 2:
+ case BACKREF + 3:
+ case BACKREF + 4:
+ case BACKREF + 5:
+ case BACKREF + 6:
+ case BACKREF + 7:
+ case BACKREF + 8:
+ case BACKREF + 9:
+ sprintf(buf + STRLEN(buf), "BACKREF%d", OP(op) - BACKREF);
+ p = NULL;
+ break;
+ case NOPEN:
+ p = "NOPEN";
+ break;
+ case NCLOSE:
+ p = "NCLOSE";
+ break;
+ case ZOPEN + 1:
+ case ZOPEN + 2:
+ case ZOPEN + 3:
+ case ZOPEN + 4:
+ case ZOPEN + 5:
+ case ZOPEN + 6:
+ case ZOPEN + 7:
+ case ZOPEN + 8:
+ case ZOPEN + 9:
+ sprintf(buf + STRLEN(buf), "ZOPEN%d", OP(op) - ZOPEN);
+ p = NULL;
+ break;
+ case ZCLOSE + 1:
+ case ZCLOSE + 2:
+ case ZCLOSE + 3:
+ case ZCLOSE + 4:
+ case ZCLOSE + 5:
+ case ZCLOSE + 6:
+ case ZCLOSE + 7:
+ case ZCLOSE + 8:
+ case ZCLOSE + 9:
+ sprintf(buf + STRLEN(buf), "ZCLOSE%d", OP(op) - ZCLOSE);
+ p = NULL;
+ break;
+ case ZREF + 1:
+ case ZREF + 2:
+ case ZREF + 3:
+ case ZREF + 4:
+ case ZREF + 5:
+ case ZREF + 6:
+ case ZREF + 7:
+ case ZREF + 8:
+ case ZREF + 9:
+ sprintf(buf + STRLEN(buf), "ZREF%d", OP(op) - ZREF);
+ p = NULL;
+ break;
+ case STAR:
+ p = "STAR";
+ break;
+ case PLUS:
+ p = "PLUS";
+ break;
+ case NOMATCH:
+ p = "NOMATCH";
+ break;
+ case MATCH:
+ p = "MATCH";
+ break;
+ case BEHIND:
+ p = "BEHIND";
+ break;
+ case NOBEHIND:
+ p = "NOBEHIND";
+ break;
+ case SUBPAT:
+ p = "SUBPAT";
+ break;
+ case BRACE_LIMITS:
+ p = "BRACE_LIMITS";
+ break;
+ case BRACE_SIMPLE:
+ p = "BRACE_SIMPLE";
+ break;
+ case BRACE_COMPLEX + 0:
+ case BRACE_COMPLEX + 1:
+ case BRACE_COMPLEX + 2:
+ case BRACE_COMPLEX + 3:
+ case BRACE_COMPLEX + 4:
+ case BRACE_COMPLEX + 5:
+ case BRACE_COMPLEX + 6:
+ case BRACE_COMPLEX + 7:
+ case BRACE_COMPLEX + 8:
+ case BRACE_COMPLEX + 9:
+ sprintf(buf + STRLEN(buf), "BRACE_COMPLEX%d", OP(op) - BRACE_COMPLEX);
+ p = NULL;
+ break;
+ case MULTIBYTECODE:
+ p = "MULTIBYTECODE";
+ break;
+ case NEWL:
+ p = "NEWL";
+ break;
+ default:
+ sprintf(buf + STRLEN(buf), "corrupt %d", OP(op));
+ p = NULL;
+ break;
+ }
+ if (p != NULL)
+ STRCAT(buf, p);
+ return (char_u *)buf;
+}
+#endif /* REGEXP_DEBUG */
+
+static void mb_decompose __ARGS((int c, int *c1, int *c2, int *c3));
+
+typedef struct {
+ int a, b, c;
+} decomp_T;
+
+
+/* 0xfb20 - 0xfb4f */
+static decomp_T decomp_table[0xfb4f-0xfb20+1] =
+{
+ {0x5e2,0,0}, /* 0xfb20 alt ayin */
+ {0x5d0,0,0}, /* 0xfb21 alt alef */
+ {0x5d3,0,0}, /* 0xfb22 alt dalet */
+ {0x5d4,0,0}, /* 0xfb23 alt he */
+ {0x5db,0,0}, /* 0xfb24 alt kaf */
+ {0x5dc,0,0}, /* 0xfb25 alt lamed */
+ {0x5dd,0,0}, /* 0xfb26 alt mem-sofit */
+ {0x5e8,0,0}, /* 0xfb27 alt resh */
+ {0x5ea,0,0}, /* 0xfb28 alt tav */
+ {'+', 0, 0}, /* 0xfb29 alt plus */
+ {0x5e9, 0x5c1, 0}, /* 0xfb2a shin+shin-dot */
+ {0x5e9, 0x5c2, 0}, /* 0xfb2b shin+sin-dot */
+ {0x5e9, 0x5c1, 0x5bc}, /* 0xfb2c shin+shin-dot+dagesh */
+ {0x5e9, 0x5c2, 0x5bc}, /* 0xfb2d shin+sin-dot+dagesh */
+ {0x5d0, 0x5b7, 0}, /* 0xfb2e alef+patah */
+ {0x5d0, 0x5b8, 0}, /* 0xfb2f alef+qamats */
+ {0x5d0, 0x5b4, 0}, /* 0xfb30 alef+hiriq */
+ {0x5d1, 0x5bc, 0}, /* 0xfb31 bet+dagesh */
+ {0x5d2, 0x5bc, 0}, /* 0xfb32 gimel+dagesh */
+ {0x5d3, 0x5bc, 0}, /* 0xfb33 dalet+dagesh */
+ {0x5d4, 0x5bc, 0}, /* 0xfb34 he+dagesh */
+ {0x5d5, 0x5bc, 0}, /* 0xfb35 vav+dagesh */
+ {0x5d6, 0x5bc, 0}, /* 0xfb36 zayin+dagesh */
+ {0xfb37, 0, 0}, /* 0xfb37 -- UNUSED */
+ {0x5d8, 0x5bc, 0}, /* 0xfb38 tet+dagesh */
+ {0x5d9, 0x5bc, 0}, /* 0xfb39 yud+dagesh */
+ {0x5da, 0x5bc, 0}, /* 0xfb3a kaf sofit+dagesh */
+ {0x5db, 0x5bc, 0}, /* 0xfb3b kaf+dagesh */
+ {0x5dc, 0x5bc, 0}, /* 0xfb3c lamed+dagesh */
+ {0xfb3d, 0, 0}, /* 0xfb3d -- UNUSED */
+ {0x5de, 0x5bc, 0}, /* 0xfb3e mem+dagesh */
+ {0xfb3f, 0, 0}, /* 0xfb3f -- UNUSED */
+ {0x5e0, 0x5bc, 0}, /* 0xfb40 nun+dagesh */
+ {0x5e1, 0x5bc, 0}, /* 0xfb41 samech+dagesh */
+ {0xfb42, 0, 0}, /* 0xfb42 -- UNUSED */
+ {0x5e3, 0x5bc, 0}, /* 0xfb43 pe sofit+dagesh */
+ {0x5e4, 0x5bc,0}, /* 0xfb44 pe+dagesh */
+ {0xfb45, 0, 0}, /* 0xfb45 -- UNUSED */
+ {0x5e6, 0x5bc, 0}, /* 0xfb46 tsadi+dagesh */
+ {0x5e7, 0x5bc, 0}, /* 0xfb47 qof+dagesh */
+ {0x5e8, 0x5bc, 0}, /* 0xfb48 resh+dagesh */
+ {0x5e9, 0x5bc, 0}, /* 0xfb49 shin+dagesh */
+ {0x5ea, 0x5bc, 0}, /* 0xfb4a tav+dagesh */
+ {0x5d5, 0x5b9, 0}, /* 0xfb4b vav+holam */
+ {0x5d1, 0x5bf, 0}, /* 0xfb4c bet+rafe */
+ {0x5db, 0x5bf, 0}, /* 0xfb4d kaf+rafe */
+ {0x5e4, 0x5bf, 0}, /* 0xfb4e pe+rafe */
+ {0x5d0, 0x5dc, 0} /* 0xfb4f alef-lamed */
+};
+
+static void mb_decompose(c, c1, c2, c3)
+int c, *c1, *c2, *c3;
+{
+ decomp_T d;
+
+ if (c >= 0xfb20 && c <= 0xfb4f) {
+ d = decomp_table[c - 0xfb20];
+ *c1 = d.a;
+ *c2 = d.b;
+ *c3 = d.c;
+ } else {
+ *c1 = c;
+ *c2 = *c3 = 0;
+ }
+}
+
+/*
+ * 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.
+ */
+static int cstrncmp(s1, s2, n)
+char_u *s1, *s2;
+int *n;
+{
+ int result;
+
+ if (!ireg_ic)
+ result = STRNCMP(s1, s2, *n);
+ else
+ result = MB_STRNICMP(s1, s2, *n);
+
+ /* if it failed and it's utf8 and we want to combineignore: */
+ if (result != 0 && enc_utf8 && ireg_icombine) {
+ char_u *str1, *str2;
+ int c1, c2, c11, c12;
+ int junk;
+
+ /* we have to handle the strcmp ourselves, since it is necessary to
+ * deal with the composing characters by ignoring them: */
+ str1 = s1;
+ str2 = s2;
+ c1 = c2 = 0;
+ while ((int)(str1 - s1) < *n) {
+ c1 = mb_ptr2char_adv(&str1);
+ c2 = mb_ptr2char_adv(&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? */
+ 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)))
+ break;
+ }
+ }
+ result = c2 - c1;
+ if (result == 0)
+ *n = (int)(str2 - s2);
+ }
+
+ return result;
+}
+
+/*
+ * cstrchr: This function is used a lot for simple searches, keep it fast!
+ */
+static char_u * cstrchr(s, c)
+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 (MB_ISUPPER(c))
+ cc = MB_TOLOWER(c);
+ else if (MB_ISLOWER(c))
+ cc = MB_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 *
+***************************************************************/
+
+/* This stuff below really confuses cc on an SGI -- webb */
+
+/*
+ * We should define ftpr as a pointer to a function returning a pointer to
+ * a function returning a pointer to a function ...
+ * This is impossible, so we declare a pointer to a function returning a
+ * pointer to a function returning void. This should work for all compilers.
+ */
+typedef void (*(*fptr_T)__ARGS((int *, int)))();
+
+static fptr_T do_upper __ARGS((int *, int));
+static fptr_T do_Upper __ARGS((int *, int));
+static fptr_T do_lower __ARGS((int *, int));
+static fptr_T do_Lower __ARGS((int *, int));
+
+static int vim_regsub_both __ARGS((char_u *source, char_u *dest, int copy,
+ int magic,
+ int backslash));
+
+static fptr_T do_upper(d, c)
+int *d;
+int c;
+{
+ *d = MB_TOUPPER(c);
+
+ return (fptr_T)NULL;
+}
+
+static fptr_T do_Upper(d, c)
+int *d;
+int c;
+{
+ *d = MB_TOUPPER(c);
+
+ return (fptr_T)do_Upper;
+}
+
+static fptr_T do_lower(d, c)
+int *d;
+int c;
+{
+ *d = MB_TOLOWER(c);
+
+ return (fptr_T)NULL;
+}
+
+static fptr_T do_Lower(d, c)
+int *d;
+int c;
+{
+ *d = MB_TOLOWER(c);
+
+ return (fptr_T)do_Lower;
+}
+
+/*
+ * regtilde(): Replace tildes in the pattern by the old pattern.
+ *
+ * Short explanation of the tilde: It stands for the previous replacement
+ * pattern. If that previous pattern also contains a ~ we should go back a
+ * step further... But we insert the previous pattern into the current one
+ * and remember that.
+ * This still does not handle the case where "magic" changes. So require the
+ * user to keep his hands off of "magic".
+ *
+ * The tildes are parsed once before the first call to vim_regsub().
+ */
+char_u * regtilde(source, magic)
+char_u *source;
+int magic;
+{
+ char_u *newsub = source;
+ char_u *tmpsub;
+ char_u *p;
+ int len;
+ int prevlen;
+
+ for (p = newsub; *p; ++p) {
+ if ((*p == '~' && magic) || (*p == '\\' && *(p + 1) == '~' && !magic)) {
+ if (reg_prev_sub != NULL) {
+ /* length = len(newsub) - 1 + len(prev_sub) + 1 */
+ prevlen = (int)STRLEN(reg_prev_sub);
+ tmpsub = alloc((unsigned)(STRLEN(newsub) + prevlen));
+ if (tmpsub != NULL) {
+ /* copy prefix */
+ len = (int)(p - newsub); /* not including ~ */
+ mch_memmove(tmpsub, newsub, (size_t)len);
+ /* interpret tilde */
+ mch_memmove(tmpsub + len, reg_prev_sub, (size_t)prevlen);
+ /* copy postfix */
+ if (!magic)
+ ++p; /* back off \ */
+ STRCPY(tmpsub + len + prevlen, p + 1);
+
+ if (newsub != source) /* already allocated newsub */
+ vim_free(newsub);
+ newsub = tmpsub;
+ p = newsub + len + prevlen;
+ }
+ } else if (magic)
+ STRMOVE(p, p + 1); /* remove '~' */
+ else
+ STRMOVE(p, p + 2); /* remove '\~' */
+ --p;
+ } else {
+ if (*p == '\\' && p[1]) /* skip escaped characters */
+ ++p;
+ if (has_mbyte)
+ p += (*mb_ptr2len)(p) - 1;
+ }
+ }
+
+ vim_free(reg_prev_sub);
+ if (newsub != source) /* newsub was allocated, just keep it */
+ reg_prev_sub = newsub;
+ else /* no ~ found, need to save newsub */
+ reg_prev_sub = vim_strsave(newsub);
+ return newsub;
+}
+
+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;
+
+/*
+ * 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(rmp, source, dest, copy, magic, backslash)
+regmatch_T *rmp;
+char_u *source;
+char_u *dest;
+int copy;
+int magic;
+int backslash;
+{
+ reg_match = rmp;
+ reg_mmatch = NULL;
+ reg_maxline = 0;
+ reg_buf = curbuf;
+ return vim_regsub_both(source, dest, copy, magic, backslash);
+}
+
+int vim_regsub_multi(rmp, lnum, source, dest, copy, magic, backslash)
+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;
+ return vim_regsub_both(source, dest, copy, magic, backslash);
+}
+
+static int vim_regsub_both(source, dest, copy, magic, backslash)
+char_u *source;
+char_u *dest;
+int copy;
+int magic;
+int backslash;
+{
+ char_u *src;
+ char_u *dst;
+ char_u *s;
+ int c;
+ int cc;
+ int no = -1;
+ fptr_T func_all = (fptr_T)NULL;
+ fptr_T func_one = (fptr_T)NULL;
+ linenr_T clnum = 0; /* init for GCC */
+ int len = 0; /* init for GCC */
+ static char_u *eval_result = NULL;
+
+ /* Be paranoid... */
+ if (source == NULL || dest == NULL) {
+ EMSG(_(e_null));
+ return 0;
+ }
+ if (prog_magic_wrong())
+ return 0;
+ 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. */
+ if (copy) {
+ if (eval_result != NULL) {
+ STRCPY(dest, eval_result);
+ dst += STRLEN(eval_result);
+ vim_free(eval_result);
+ eval_result = NULL;
+ }
+ } else {
+ win_T *save_reg_win;
+ int save_ireg_ic;
+
+ vim_free(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);
+ 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)
+ *s = CAR;
+ 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)
+ *s = CAR;
+ had_backslash = TRUE;
+ }
+ }
+ if (had_backslash && backslash) {
+ /* Backslashes will be consumed, need to double them. */
+ s = vim_strsave_escaped(eval_result, (char_u *)"\\");
+ if (s != NULL) {
+ vim_free(eval_result);
+ eval_result = s;
+ }
+ }
+
+ 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;
+ }
+ } else
+ while ((c = *src++) != NUL) {
+ if (c == '&' && magic)
+ no = 0;
+ else if (c == '\\' && *src != NUL) {
+ if (*src == '&' && !magic) {
+ ++src;
+ no = 0;
+ } else if ('0' <= *src && *src <= '9') {
+ no = *src++ - '0';
+ } else if (vim_strchr((char_u *)"uUlLeE", *src)) {
+ switch (*src++) {
+ case 'u': func_one = (fptr_T)do_upper;
+ continue;
+ case 'U': func_all = (fptr_T)do_Upper;
+ continue;
+ case 'l': func_one = (fptr_T)do_lower;
+ continue;
+ case 'L': func_all = (fptr_T)do_Lower;
+ continue;
+ case 'e':
+ case 'E': func_one = func_all = (fptr_T)NULL;
+ continue;
+ }
+ }
+ }
+ if (no < 0) { /* Ordinary character. */
+ if (c == K_SPECIAL && src[0] != NUL && src[1] != NUL) {
+ /* Copy a special key as-is. */
+ if (copy) {
+ *dst++ = c;
+ *dst++ = *src++;
+ *dst++ = *src++;
+ } else {
+ dst += 3;
+ src += 2;
+ }
+ continue;
+ }
+
+ if (c == '\\' && *src != NUL) {
+ /* Check for abbreviations -- webb */
+ switch (*src) {
+ case 'r': c = CAR; ++src; break;
+ case 'n': c = NL; ++src; break;
+ case 't': c = TAB; ++src; break;
+ /* Oh no! \e already has meaning in subst pat :-( */
+ /* case 'e': c = ESC; ++src; break; */
+ case 'b': c = Ctrl_H; ++src; break;
+
+ /* If "backslash" is TRUE the backslash will be removed
+ * later. Used to insert a literal CR. */
+ default: if (backslash) {
+ if (copy)
+ *dst = '\\';
+ ++dst;
+ }
+ 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 */
+ func_one = (fptr_T)(func_one(&cc, c));
+ else if (func_all != (fptr_T)NULL)
+ /* Turbo C complains without the typecast */
+ func_all = (fptr_T)(func_all(&cc, c));
+ else /* just copy */
+ cc = c;
+
+ if (has_mbyte) {
+ int totlen = mb_ptr2len(src - 1);
+
+ if (copy)
+ mb_char2bytes(cc, dst);
+ dst += mb_char2len(cc) - 1;
+ if (enc_utf8) {
+ 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)
+ mch_memmove(dst + 1, src - 1 + clen,
+ (size_t)(totlen - clen));
+ dst += totlen - clen;
+ }
+ }
+ src += totlen - 1;
+ } else if (copy)
+ *dst = cc;
+ dst++;
+ } else {
+ if (REG_MULTI) {
+ clnum = reg_mmatch->startpos[no].lnum;
+ if (clnum < 0 || 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
+ len = (int)STRLEN(s);
+ }
+ } else {
+ s = reg_match->startp[no];
+ if (reg_match->endp[no] == NULL)
+ s = NULL;
+ else
+ len = (int)(reg_match->endp[no] - s);
+ }
+ if (s != NULL) {
+ for (;; ) {
+ if (len == 0) {
+ if (REG_MULTI) {
+ if (reg_mmatch->endpos[no].lnum == clnum)
+ break;
+ if (copy)
+ *dst = CAR;
+ ++dst;
+ s = reg_getline(++clnum);
+ if (reg_mmatch->endpos[no].lnum == clnum)
+ len = reg_mmatch->endpos[no].col;
+ else
+ len = (int)STRLEN(s);
+ } else
+ break;
+ } else if (*s == NUL) { /* we hit NUL. */
+ if (copy)
+ EMSG(_(e_re_damg));
+ goto exit;
+ } else {
+ if (backslash && (*s == CAR || *s == '\\')) {
+ /*
+ * Insert a backslash in front of a CR, otherwise
+ * it will be replaced by a line break.
+ * Number of backslashes will be halved later,
+ * double them here.
+ */
+ if (copy) {
+ dst[0] = '\\';
+ dst[1] = *s;
+ }
+ dst += 2;
+ } else {
+ if (has_mbyte)
+ c = mb_ptr2char(s);
+ else
+ c = *s;
+
+ if (func_one != (fptr_T)NULL)
+ /* Turbo C complains without the typecast */
+ func_one = (fptr_T)(func_one(&cc, c));
+ else if (func_all != (fptr_T)NULL)
+ /* Turbo C complains without the typecast */
+ func_all = (fptr_T)(func_all(&cc, c));
+ else /* just copy */
+ cc = c;
+
+ 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;
+
+ s += l;
+ len -= l;
+ if (copy)
+ mb_char2bytes(cc, dst);
+ dst += mb_char2len(cc) - 1;
+ } else if (copy)
+ *dst = cc;
+ dst++;
+ }
+
+ ++s;
+ --len;
+ }
+ }
+ }
+ no = -1;
+ }
+ }
+ if (copy)
+ *dst = NUL;
+
+exit:
+ return (int)((dst - dest) + 1);
+}
+
+static char_u *reg_getline_submatch __ARGS((linenr_T lnum));
+
+/*
+ * Call reg_getline() with the line numbers from the submatch. If a
+ * substitute() was used the reg_maxline and other values have been
+ * overwritten.
+ */
+static char_u * reg_getline_submatch(lnum)
+linenr_T lnum;
+{
+ char_u *s;
+ linenr_T save_first = reg_firstlnum;
+ linenr_T save_max = reg_maxline;
+
+ reg_firstlnum = submatch_firstlnum;
+ reg_maxline = submatch_maxline;
+
+ s = reg_getline(lnum);
+
+ reg_firstlnum = save_first;
+ reg_maxline = save_max;
+ return s;
+}
+
+/*
+ * Used for the submatch() function: get the string from the n'th submatch in
+ * allocated memory.
+ * Returns NULL when not in a ":s" command and for a non-existing submatch.
+ */
+char_u * reg_submatch(no)
+int no;
+{
+ char_u *retval = NULL;
+ char_u *s;
+ int len;
+ int round;
+ linenr_T lnum;
+
+ if (!can_f_submatch || no < 0)
+ return NULL;
+
+ if (submatch_match == NULL) {
+ /*
+ * 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)
+ return NULL;
+
+ s = reg_getline_submatch(lnum) + submatch_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)
+ vim_strncpy(retval, s, len);
+ ++len;
+ } else {
+ /* Multiple lines: take start line from start col, middle
+ * lines completely and end line up to end col. */
+ len = (int)STRLEN(s);
+ if (round == 2) {
+ STRCPY(retval, s);
+ retval[len] = '\n';
+ }
+ ++len;
+ ++lnum;
+ while (lnum < submatch_mmatch->endpos[no].lnum) {
+ s = reg_getline_submatch(lnum++);
+ if (round == 2)
+ STRCPY(retval + len, s);
+ len += (int)STRLEN(s);
+ if (round == 2)
+ retval[len] = '\n';
+ ++len;
+ }
+ 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;
+ }
+
+ if (retval == NULL) {
+ retval = lalloc((long_u)len, TRUE);
+ if (retval == NULL)
+ return NULL;
+ }
+ }
+ } else {
+ s = submatch_match->startp[no];
+ if (s == NULL || submatch_match->endp[no] == NULL)
+ retval = NULL;
+ else
+ retval = vim_strnsave(s, (int)(submatch_match->endp[no] - s));
+ }
+
+ return retval;
+}
+
+static regengine_T bt_regengine =
+{
+ bt_regcomp,
+ bt_regfree,
+ bt_regexec,
+#if defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) \
+ || defined(FIND_REPLACE_DIALOG) || defined(PROTO)
+ bt_regexec_nl,
+#endif
+ bt_regexec_multi
+#ifdef REGEXP_DEBUG
+ ,(char_u *)""
+#endif
+};
+
+
+#include "regexp_nfa.c"
+
+static regengine_T nfa_regengine =
+{
+ nfa_regcomp,
+ nfa_regfree,
+ nfa_regexec,
+#if defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) \
+ || defined(FIND_REPLACE_DIALOG) || defined(PROTO)
+ nfa_regexec_nl,
+#endif
+ nfa_regexec_multi
+#ifdef REGEXP_DEBUG
+ ,(char_u *)""
+#endif
+};
+
+/* Which regexp engine to use? Needed for vim_regcomp().
+ * Must match with 'regexpengine'. */
+static int regexp_engine = 0;
+#define AUTOMATIC_ENGINE 0
+#define BACKTRACKING_ENGINE 1
+#define NFA_ENGINE 2
+#ifdef REGEXP_DEBUG
+static char_u regname[][30] = {
+ "AUTOMATIC Regexp Engine",
+ "BACKTRACKING Regexp Engine",
+ "NFA Regexp Engine"
+};
+#endif
+
+/*
+ * Compile a regular expression into internal code.
+ * Returns the program in allocated memory.
+ * Use vim_regfree() to free the memory.
+ * Returns NULL for an error.
+ */
+regprog_T * vim_regcomp(expr_arg, re_flags)
+char_u *expr_arg;
+int re_flags;
+{
+ regprog_T *prog = NULL;
+ char_u *expr = expr_arg;
+
+ regexp_engine = p_re;
+
+ /* Check for prefix "\%#=", that sets the regexp engine */
+ if (STRNCMP(expr, "\\%#=", 4) == 0) {
+ int newengine = expr[4] - '0';
+
+ if (newengine == AUTOMATIC_ENGINE
+ || newengine == BACKTRACKING_ENGINE
+ || newengine == NFA_ENGINE) {
+ regexp_engine = expr[4] - '0';
+ expr += 5;
+#ifdef REGEXP_DEBUG
+ EMSG3("New regexp mode selected (%d): %s", regexp_engine,
+ regname[newengine]);
+#endif
+ } else {
+ EMSG(_(
+ "E864: \\%#= can only be followed by 0, 1, or 2. The automatic engine will be used "));
+ regexp_engine = AUTOMATIC_ENGINE;
+ }
+ }
+#ifdef REGEXP_DEBUG
+ bt_regengine.expr = expr;
+ nfa_regengine.expr = expr;
+#endif
+
+ /*
+ * First try the NFA engine, unless backtracking was requested.
+ */
+ if (regexp_engine != BACKTRACKING_ENGINE)
+ prog = nfa_regengine.regcomp(expr, re_flags);
+ else
+ prog = bt_regengine.regcomp(expr, re_flags);
+
+ if (prog == NULL) { /* error compiling regexp with initial engine */
+#ifdef BT_REGEXP_DEBUG_LOG
+ if (regexp_engine != BACKTRACKING_ENGINE) { /* debugging log for NFA */
+ FILE *f;
+ f = fopen(BT_REGEXP_DEBUG_LOG_NAME, "a");
+ if (f) {
+ fprintf(f, "Syntax error in \"%s\"\n", expr);
+ fclose(f);
+ } else
+ EMSG2("(NFA) Could not open \"%s\" to write !!!",
+ BT_REGEXP_DEBUG_LOG_NAME);
+ }
+#endif
+ /*
+ * If the NFA engine failed, the backtracking engine won't work either.
+ *
+ if (regexp_engine == AUTOMATIC_ENGINE)
+ prog = bt_regengine.regcomp(expr, re_flags);
+ */
+ }
+
+ return prog;
+}
+
+/*
+ * Free a compiled regexp program, returned by vim_regcomp().
+ */
+void vim_regfree(prog)
+regprog_T *prog;
+{
+ if (prog != NULL)
+ prog->engine->regfree(prog);
+}
+
+/*
+ * Match a regexp against a string.
+ * "rmp->regprog" is a compiled regexp as returned by vim_regcomp().
+ * Uses curbuf for line count and 'iskeyword'.
+ *
+ * Return TRUE if there is a match, FALSE if not.
+ */
+int vim_regexec(rmp, line, col)
+regmatch_T *rmp;
+char_u *line; /* string to match against */
+colnr_T col; /* column to start looking for match */
+{
+ return rmp->regprog->engine->regexec(rmp, line, col);
+}
+
+#if defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) \
+ || defined(FIND_REPLACE_DIALOG) || defined(PROTO)
+/*
+ * Like vim_regexec(), but consider a "\n" in "line" to be a line break.
+ */
+int vim_regexec_nl(rmp, line, col)
+regmatch_T *rmp;
+char_u *line;
+colnr_T col;
+{
+ return rmp->regprog->engine->regexec_nl(rmp, line, col);
+}
+#endif
+
+/*
+ * Match a regexp against multiple lines.
+ * "rmp->regprog" is a compiled regexp as returned by vim_regcomp().
+ * 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(rmp, win, buf, lnum, col, tm)
+regmmatch_T *rmp;
+win_T *win; /* window in which to search or NULL */
+buf_T *buf; /* buffer in which to search */
+linenr_T lnum; /* nr of line to start looking for match */
+colnr_T col; /* column to start looking for match */
+proftime_T *tm; /* timeout limit or NULL */
+{
+ return rmp->regprog->engine->regexec_multi(rmp, win, buf, lnum, col, tm);
+}
diff --git a/src/regexp.h b/src/regexp.h
new file mode 100644
index 0000000000..0426f242a4
--- /dev/null
+++ b/src/regexp.h
@@ -0,0 +1,152 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
+ *
+ * This is NOT the original regular expression code as written by Henry
+ * Spencer. This code has been modified specifically for use with Vim, and
+ * should not be used apart from compiling Vim. If you want a good regular
+ * expression library, get the original code.
+ *
+ * NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
+ */
+
+#ifndef _REGEXP_H
+#define _REGEXP_H
+
+/*
+ * The number of sub-matches is limited to 10.
+ * The first one (index 0) is the whole match, referenced with "\0".
+ * The second one (index 1) is the first sub-match, referenced with "\1".
+ * This goes up to the tenth (index 9), referenced with "\9".
+ */
+#define NSUBEXP 10
+
+/*
+ * In the NFA engine: how many braces are allowed.
+ * TODO(RE): Use dynamic memory allocation instead of static, like here
+ */
+#define NFA_MAX_BRACES 20
+
+typedef struct regengine regengine_T;
+
+/*
+ * 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 {
+ regengine_T *engine;
+ unsigned regflags;
+} regprog_T;
+
+/*
+ * Structure used by the back track matcher.
+ * These fields are only to be used in regexp.c!
+ * See regexp.c for an explanation.
+ */
+typedef struct {
+ /* These two members implement regprog_T */
+ regengine_T *engine;
+ unsigned regflags;
+
+ int regstart;
+ char_u reganch;
+ char_u *regmust;
+ int regmlen;
+ char_u reghasz;
+ char_u program[1]; /* actually longer.. */
+} bt_regprog_T;
+
+/*
+ * Structure representing a NFA state.
+ * A NFA state may have no outgoing edge, when it is a NFA_MATCH state.
+ */
+typedef struct nfa_state nfa_state_T;
+struct nfa_state {
+ int c;
+ nfa_state_T *out;
+ nfa_state_T *out1;
+ int id;
+ int lastlist[2]; /* 0: normal, 1: recursive */
+ int val;
+};
+
+/*
+ * Structure used by the NFA matcher.
+ */
+typedef struct {
+ /* These two members implement regprog_T */
+ regengine_T *engine;
+ unsigned regflags;
+
+ nfa_state_T *start; /* points into state[] */
+
+ int reganch; /* pattern starts with ^ */
+ int regstart; /* char at start of pattern */
+ char_u *match_text; /* plain text to match with */
+
+ int has_zend; /* pattern contains \ze */
+ int has_backref; /* pattern contains \1 .. \9 */
+ int reghasz;
+#ifdef DEBUG
+ char_u *pattern;
+#endif
+ int nsubexp; /* number of () */
+ int nstate;
+ nfa_state_T state[1]; /* actually longer.. */
+} nfa_regprog_T;
+
+/*
+ * Structure to be used for single-line matching.
+ * Sub-match "no" starts at "startp[no]" and ends just before "endp[no]".
+ * When there is no match, the pointer is NULL.
+ */
+typedef struct {
+ regprog_T *regprog;
+ char_u *startp[NSUBEXP];
+ char_u *endp[NSUBEXP];
+ int rm_ic;
+} 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;
+ char_u *matches[NSUBEXP];
+} reg_extmatch_T;
+
+struct regengine {
+ regprog_T *(*regcomp)(char_u*, int);
+ void (*regfree)(regprog_T *);
+ int (*regexec)(regmatch_T*, char_u*, colnr_T);
+#if defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) \
+ || defined(FIND_REPLACE_DIALOG) || defined(PROTO)
+ int (*regexec_nl)(regmatch_T*, char_u*, colnr_T);
+#endif
+ long (*regexec_multi)(regmmatch_T*, win_T*, buf_T*, linenr_T, colnr_T,
+ proftime_T*);
+#ifdef DEBUG
+ char_u *expr;
+#endif
+};
+
+#endif /* _REGEXP_H */
diff --git a/src/regexp_nfa.c b/src/regexp_nfa.c
new file mode 100644
index 0000000000..96d6a01a90
--- /dev/null
+++ b/src/regexp_nfa.c
@@ -0,0 +1,6550 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * NFA regular expression implementation.
+ *
+ * This file is included in "regexp.c".
+ */
+
+/*
+ * Logging of NFA engine.
+ *
+ * The NFA engine can write four log files:
+ * - Error log: Contains NFA engine's fatal errors.
+ * - Dump log: Contains compiled NFA state machine's information.
+ * - Run log: Contains information of matching procedure.
+ * - Debug log: Contains detailed information of matching procedure. Can be
+ * disabled by undefining NFA_REGEXP_DEBUG_LOG.
+ * The first one can also be used without debug mode.
+ * The last three are enabled when compiled as debug mode and individually
+ * disabled by commenting them out.
+ * The log files can get quite big!
+ * Do disable all of this when compiling Vim for debugging, undefine REGEXP_DEBUG in
+ * regexp.c
+ */
+#ifdef REGEXP_DEBUG
+# define NFA_REGEXP_ERROR_LOG "nfa_regexp_error.log"
+# define ENABLE_LOG
+# define NFA_REGEXP_DUMP_LOG "nfa_regexp_dump.log"
+# define NFA_REGEXP_RUN_LOG "nfa_regexp_run.log"
+# define NFA_REGEXP_DEBUG_LOG "nfa_regexp_debug.log"
+#endif
+
+/* Added to NFA_ANY - NFA_NUPPER_IC to include a NL. */
+#define NFA_ADD_NL 31
+
+enum {
+ NFA_SPLIT = -1024,
+ NFA_MATCH,
+ NFA_EMPTY, /* matches 0-length */
+
+ NFA_START_COLL, /* [abc] start */
+ NFA_END_COLL, /* [abc] end */
+ NFA_START_NEG_COLL, /* [^abc] start */
+ NFA_END_NEG_COLL, /* [^abc] end (postfix only) */
+ NFA_RANGE, /* range of the two previous items
+ * (postfix only) */
+ 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_BOL, /* ^ Begin line */
+ NFA_EOL, /* $ End line */
+ NFA_BOW, /* \< Begin word */
+ NFA_EOW, /* \> End word */
+ NFA_BOF, /* \%^ Begin file */
+ NFA_EOF, /* \%$ End file */
+ NFA_NEWL,
+ NFA_ZSTART, /* Used for \zs */
+ NFA_ZEND, /* Used for \ze */
+ NFA_NOPEN, /* Start of subexpression marked with \%( */
+ NFA_NCLOSE, /* End of subexpr. marked with \%( ... \) */
+ NFA_START_INVISIBLE,
+ NFA_START_INVISIBLE_FIRST,
+ NFA_START_INVISIBLE_NEG,
+ NFA_START_INVISIBLE_NEG_FIRST,
+ NFA_START_INVISIBLE_BEFORE,
+ NFA_START_INVISIBLE_BEFORE_FIRST,
+ NFA_START_INVISIBLE_BEFORE_NEG,
+ NFA_START_INVISIBLE_BEFORE_NEG_FIRST,
+ NFA_START_PATTERN,
+ NFA_END_INVISIBLE,
+ NFA_END_INVISIBLE_NEG,
+ NFA_END_PATTERN,
+ NFA_COMPOSING, /* Next nodes in NFA are part of the
+ composing multibyte char */
+ NFA_END_COMPOSING, /* End of a composing char in the NFA */
+ NFA_OPT_CHARS, /* \%[abc] */
+
+ /* The following are used only in the postfix form, not in the NFA */
+ NFA_PREV_ATOM_NO_WIDTH, /* Used for \@= */
+ NFA_PREV_ATOM_NO_WIDTH_NEG, /* Used for \@! */
+ NFA_PREV_ATOM_JUST_BEFORE, /* Used for \@<= */
+ NFA_PREV_ATOM_JUST_BEFORE_NEG, /* Used for \@<! */
+ NFA_PREV_ATOM_LIKE_PATTERN, /* Used for \@> */
+
+ NFA_BACKREF1, /* \1 */
+ NFA_BACKREF2, /* \2 */
+ NFA_BACKREF3, /* \3 */
+ NFA_BACKREF4, /* \4 */
+ NFA_BACKREF5, /* \5 */
+ NFA_BACKREF6, /* \6 */
+ NFA_BACKREF7, /* \7 */
+ NFA_BACKREF8, /* \8 */
+ NFA_BACKREF9, /* \9 */
+ NFA_ZREF1, /* \z1 */
+ NFA_ZREF2, /* \z2 */
+ NFA_ZREF3, /* \z3 */
+ NFA_ZREF4, /* \z4 */
+ NFA_ZREF5, /* \z5 */
+ NFA_ZREF6, /* \z6 */
+ NFA_ZREF7, /* \z7 */
+ NFA_ZREF8, /* \z8 */
+ NFA_ZREF9, /* \z9 */
+ NFA_SKIP, /* Skip characters */
+
+ NFA_MOPEN,
+ NFA_MOPEN1,
+ NFA_MOPEN2,
+ NFA_MOPEN3,
+ NFA_MOPEN4,
+ NFA_MOPEN5,
+ NFA_MOPEN6,
+ NFA_MOPEN7,
+ NFA_MOPEN8,
+ NFA_MOPEN9,
+
+ NFA_MCLOSE,
+ NFA_MCLOSE1,
+ NFA_MCLOSE2,
+ NFA_MCLOSE3,
+ NFA_MCLOSE4,
+ NFA_MCLOSE5,
+ NFA_MCLOSE6,
+ NFA_MCLOSE7,
+ NFA_MCLOSE8,
+ NFA_MCLOSE9,
+
+ NFA_ZOPEN,
+ NFA_ZOPEN1,
+ NFA_ZOPEN2,
+ NFA_ZOPEN3,
+ NFA_ZOPEN4,
+ NFA_ZOPEN5,
+ NFA_ZOPEN6,
+ NFA_ZOPEN7,
+ NFA_ZOPEN8,
+ NFA_ZOPEN9,
+
+ NFA_ZCLOSE,
+ NFA_ZCLOSE1,
+ NFA_ZCLOSE2,
+ NFA_ZCLOSE3,
+ NFA_ZCLOSE4,
+ NFA_ZCLOSE5,
+ NFA_ZCLOSE6,
+ NFA_ZCLOSE7,
+ NFA_ZCLOSE8,
+ NFA_ZCLOSE9,
+
+ /* NFA_FIRST_NL */
+ NFA_ANY, /* Match any one character. */
+ NFA_IDENT, /* Match identifier char */
+ NFA_SIDENT, /* Match identifier char but no digit */
+ NFA_KWORD, /* Match keyword char */
+ NFA_SKWORD, /* Match word char but no digit */
+ NFA_FNAME, /* Match file name char */
+ NFA_SFNAME, /* Match file name char but no digit */
+ NFA_PRINT, /* Match printable char */
+ NFA_SPRINT, /* Match printable char but no digit */
+ NFA_WHITE, /* Match whitespace char */
+ NFA_NWHITE, /* Match non-whitespace char */
+ NFA_DIGIT, /* Match digit char */
+ NFA_NDIGIT, /* Match non-digit char */
+ NFA_HEX, /* Match hex char */
+ NFA_NHEX, /* Match non-hex char */
+ NFA_OCTAL, /* Match octal char */
+ NFA_NOCTAL, /* Match non-octal char */
+ NFA_WORD, /* Match word char */
+ NFA_NWORD, /* Match non-word char */
+ NFA_HEAD, /* Match head char */
+ NFA_NHEAD, /* Match non-head char */
+ NFA_ALPHA, /* Match alpha char */
+ NFA_NALPHA, /* Match non-alpha char */
+ NFA_LOWER, /* Match lowercase char */
+ NFA_NLOWER, /* Match non-lowercase char */
+ NFA_UPPER, /* Match uppercase char */
+ NFA_NUPPER, /* Match non-uppercase char */
+ NFA_LOWER_IC, /* Match [a-z] */
+ NFA_NLOWER_IC, /* Match [^a-z] */
+ NFA_UPPER_IC, /* Match [A-Z] */
+ NFA_NUPPER_IC, /* Match [^A-Z] */
+
+ NFA_FIRST_NL = NFA_ANY + NFA_ADD_NL,
+ NFA_LAST_NL = NFA_NUPPER_IC + NFA_ADD_NL,
+
+ NFA_CURSOR, /* Match cursor pos */
+ NFA_LNUM, /* Match line number */
+ NFA_LNUM_GT, /* Match > line number */
+ NFA_LNUM_LT, /* Match < line number */
+ NFA_COL, /* Match cursor column */
+ NFA_COL_GT, /* Match > cursor column */
+ NFA_COL_LT, /* Match < cursor column */
+ NFA_VCOL, /* Match cursor virtual column */
+ NFA_VCOL_GT, /* Match > cursor virtual column */
+ NFA_VCOL_LT, /* Match < cursor virtual column */
+ NFA_MARK, /* Match mark */
+ NFA_MARK_GT, /* Match > mark */
+ NFA_MARK_LT, /* Match < mark */
+ NFA_VISUAL, /* Match Visual area */
+
+ /* Character classes [:alnum:] etc */
+ NFA_CLASS_ALNUM,
+ NFA_CLASS_ALPHA,
+ NFA_CLASS_BLANK,
+ NFA_CLASS_CNTRL,
+ NFA_CLASS_DIGIT,
+ NFA_CLASS_GRAPH,
+ NFA_CLASS_LOWER,
+ NFA_CLASS_PRINT,
+ NFA_CLASS_PUNCT,
+ NFA_CLASS_SPACE,
+ NFA_CLASS_UPPER,
+ NFA_CLASS_XDIGIT,
+ NFA_CLASS_TAB,
+ NFA_CLASS_RETURN,
+ NFA_CLASS_BACKSPACE,
+ NFA_CLASS_ESCAPE
+};
+
+/* Keep in sync with classchars. */
+static int nfa_classcodes[] = {
+ NFA_ANY, NFA_IDENT, NFA_SIDENT, NFA_KWORD,NFA_SKWORD,
+ NFA_FNAME, NFA_SFNAME, NFA_PRINT, NFA_SPRINT,
+ NFA_WHITE, NFA_NWHITE, NFA_DIGIT, NFA_NDIGIT,
+ NFA_HEX, NFA_NHEX, NFA_OCTAL, NFA_NOCTAL,
+ NFA_WORD, NFA_NWORD, NFA_HEAD, NFA_NHEAD,
+ NFA_ALPHA, NFA_NALPHA, NFA_LOWER, NFA_NLOWER,
+ NFA_UPPER, NFA_NUPPER
+};
+
+static char_u e_nul_found[] = N_(
+ "E865: (NFA) Regexp end encountered prematurely");
+static char_u e_misplaced[] = N_("E866: (NFA regexp) Misplaced %c");
+static char_u e_ill_char_class[] = N_(
+ "E877: (NFA regexp) Invalid character class: %ld");
+
+/* NFA regexp \ze operator encountered. */
+static int nfa_has_zend;
+
+/* NFA regexp \1 .. \9 encountered. */
+static int nfa_has_backref;
+
+/* NFA regexp has \z( ), set zsubexpr. */
+static int nfa_has_zsubexpr;
+
+/* Number of sub expressions actually being used during execution. 1 if only
+ * the whole match (subexpr 0) is used. */
+static int nfa_nsubexpr;
+
+static int *post_start; /* holds the postfix form of r.e. */
+static int *post_end;
+static int *post_ptr;
+
+static int nstate; /* Number of states in the NFA. Also used when
+ * executing. */
+static int istate; /* Index in the state vector, used in alloc_state() */
+
+/* If not NULL match must end at this position */
+static save_se_T *nfa_endp = NULL;
+
+/* listid is global, so that it increases on recursive calls to
+ * nfa_regmatch(), which means we don't have to clear the lastlist field of
+ * all the states. */
+static int nfa_listid;
+static int nfa_alt_listid;
+
+/* 0 for first call to nfa_regmatch(), 1 for recursive call. */
+static int nfa_ll_index = 0;
+
+static int nfa_regcomp_start __ARGS((char_u *expr, int re_flags));
+static int nfa_get_reganch __ARGS((nfa_state_T *start, int depth));
+static int nfa_get_regstart __ARGS((nfa_state_T *start, int depth));
+static char_u *nfa_get_match_text __ARGS((nfa_state_T *start));
+static int realloc_post_list __ARGS((void));
+static int nfa_recognize_char_class __ARGS((char_u *start, char_u *end,
+ int extra_newl));
+static int nfa_emit_equi_class __ARGS((int c));
+static int nfa_regatom __ARGS((void));
+static int nfa_regpiece __ARGS((void));
+static int nfa_regconcat __ARGS((void));
+static int nfa_regbranch __ARGS((void));
+static int nfa_reg __ARGS((int paren));
+#ifdef REGEXP_DEBUG
+static void nfa_set_code __ARGS((int c));
+static void nfa_postfix_dump __ARGS((char_u *expr, int retval));
+static void nfa_print_state __ARGS((FILE *debugf, nfa_state_T *state));
+static void nfa_print_state2 __ARGS((FILE *debugf, nfa_state_T *state,
+ garray_T *indent));
+static void nfa_dump __ARGS((nfa_regprog_T *prog));
+#endif
+static int *re2post __ARGS((void));
+static nfa_state_T *alloc_state __ARGS((int c, nfa_state_T *out,
+ nfa_state_T *out1));
+static void st_error __ARGS((int *postfix, int *end, int *p));
+static int nfa_max_width __ARGS((nfa_state_T *startstate, int depth));
+static nfa_state_T *post2nfa __ARGS((int *postfix, int *end, int nfa_calc_size));
+static void nfa_postprocess __ARGS((nfa_regprog_T *prog));
+static int check_char_class __ARGS((int class, int c));
+static void nfa_save_listids __ARGS((nfa_regprog_T *prog, int *list));
+static void nfa_restore_listids __ARGS((nfa_regprog_T *prog, int *list));
+static int nfa_re_num_cmp __ARGS((long_u val, int op, long_u pos));
+static long nfa_regtry __ARGS((nfa_regprog_T *prog, colnr_T col));
+static long nfa_regexec_both __ARGS((char_u *line, colnr_T col));
+static regprog_T *nfa_regcomp __ARGS((char_u *expr, int re_flags));
+static void nfa_regfree __ARGS((regprog_T *prog));
+static int nfa_regexec __ARGS((regmatch_T *rmp, char_u *line, colnr_T col));
+static long nfa_regexec_multi __ARGS((regmmatch_T *rmp, win_T *win, buf_T *buf,
+ linenr_T lnum, colnr_T col,
+ proftime_T *tm));
+static int match_follows __ARGS((nfa_state_T *startstate, int depth));
+static int failure_chance __ARGS((nfa_state_T *state, int depth));
+
+/* helper functions used when doing re2post() ... regatom() parsing */
+#define EMIT(c) do { \
+ if (post_ptr >= post_end && realloc_post_list() == FAIL) \
+ return FAIL; \
+ *post_ptr++ = c; \
+} while (0)
+
+/*
+ * Initialize internal variables before NFA compilation.
+ * Return OK on success, FAIL otherwise.
+ */
+static int nfa_regcomp_start(expr, re_flags)
+char_u *expr;
+int re_flags; /* see vim_regcomp() */
+{
+ size_t postfix_size;
+ int nstate_max;
+
+ nstate = 0;
+ istate = 0;
+ /* A reasonable estimation for maximum size */
+ nstate_max = (int)(STRLEN(expr) + 1) * 25;
+
+ /* Some items blow up in size, such as [A-z]. Add more space for that.
+ * When it is still not enough realloc_post_list() will be used. */
+ nstate_max += 1000;
+
+ /* Size for postfix representation of expr. */
+ postfix_size = sizeof(int) * nstate_max;
+
+ post_start = (int *)lalloc(postfix_size, TRUE);
+ if (post_start == NULL)
+ return FAIL;
+ post_ptr = post_start;
+ post_end = post_start + nstate_max;
+ nfa_has_zend = FALSE;
+ nfa_has_backref = FALSE;
+
+ /* shared with BT engine */
+ regcomp_start(expr, re_flags);
+
+ return OK;
+}
+
+/*
+ * Figure out if the NFA state list starts with an anchor, must match at start
+ * of the line.
+ */
+static int nfa_get_reganch(start, depth)
+nfa_state_T *start;
+int depth;
+{
+ nfa_state_T *p = start;
+
+ if (depth > 4)
+ return 0;
+
+ while (p != NULL) {
+ switch (p->c) {
+ case NFA_BOL:
+ case NFA_BOF:
+ return 1; /* yes! */
+
+ case NFA_ZSTART:
+ case NFA_ZEND:
+ case NFA_CURSOR:
+ case NFA_VISUAL:
+
+ case NFA_MOPEN:
+ case NFA_MOPEN1:
+ case NFA_MOPEN2:
+ case NFA_MOPEN3:
+ case NFA_MOPEN4:
+ case NFA_MOPEN5:
+ case NFA_MOPEN6:
+ case NFA_MOPEN7:
+ case NFA_MOPEN8:
+ case NFA_MOPEN9:
+ case NFA_NOPEN:
+ case NFA_ZOPEN:
+ case NFA_ZOPEN1:
+ case NFA_ZOPEN2:
+ case NFA_ZOPEN3:
+ case NFA_ZOPEN4:
+ case NFA_ZOPEN5:
+ case NFA_ZOPEN6:
+ case NFA_ZOPEN7:
+ case NFA_ZOPEN8:
+ case NFA_ZOPEN9:
+ p = p->out;
+ break;
+
+ case NFA_SPLIT:
+ return nfa_get_reganch(p->out, depth + 1)
+ && nfa_get_reganch(p->out1, depth + 1);
+
+ default:
+ return 0; /* noooo */
+ }
+ }
+ return 0;
+}
+
+/*
+ * Figure out if the NFA state list starts with a character which must match
+ * at start of the match.
+ */
+static int nfa_get_regstart(start, depth)
+nfa_state_T *start;
+int depth;
+{
+ nfa_state_T *p = start;
+
+ if (depth > 4)
+ return 0;
+
+ while (p != NULL) {
+ switch (p->c) {
+ /* all kinds of zero-width matches */
+ case NFA_BOL:
+ case NFA_BOF:
+ case NFA_BOW:
+ case NFA_EOW:
+ case NFA_ZSTART:
+ case NFA_ZEND:
+ case NFA_CURSOR:
+ case NFA_VISUAL:
+ case NFA_LNUM:
+ case NFA_LNUM_GT:
+ case NFA_LNUM_LT:
+ case NFA_COL:
+ case NFA_COL_GT:
+ case NFA_COL_LT:
+ case NFA_VCOL:
+ case NFA_VCOL_GT:
+ case NFA_VCOL_LT:
+ case NFA_MARK:
+ case NFA_MARK_GT:
+ case NFA_MARK_LT:
+
+ case NFA_MOPEN:
+ case NFA_MOPEN1:
+ case NFA_MOPEN2:
+ case NFA_MOPEN3:
+ case NFA_MOPEN4:
+ case NFA_MOPEN5:
+ case NFA_MOPEN6:
+ case NFA_MOPEN7:
+ case NFA_MOPEN8:
+ case NFA_MOPEN9:
+ case NFA_NOPEN:
+ case NFA_ZOPEN:
+ case NFA_ZOPEN1:
+ case NFA_ZOPEN2:
+ case NFA_ZOPEN3:
+ case NFA_ZOPEN4:
+ case NFA_ZOPEN5:
+ case NFA_ZOPEN6:
+ case NFA_ZOPEN7:
+ case NFA_ZOPEN8:
+ case NFA_ZOPEN9:
+ p = p->out;
+ break;
+
+ case NFA_SPLIT:
+ {
+ int c1 = nfa_get_regstart(p->out, depth + 1);
+ int c2 = nfa_get_regstart(p->out1, depth + 1);
+
+ if (c1 == c2)
+ return c1; /* yes! */
+ return 0;
+ }
+
+ default:
+ if (p->c > 0)
+ return p->c; /* yes! */
+ return 0;
+ }
+ }
+ return 0;
+}
+
+/*
+ * Figure out if the NFA state list contains just literal text and nothing
+ * else. If so return a string in allocated memory with what must match after
+ * regstart. Otherwise return NULL.
+ */
+static char_u * nfa_get_match_text(start)
+nfa_state_T *start;
+{
+ nfa_state_T *p = start;
+ int len = 0;
+ char_u *ret;
+ char_u *s;
+
+ if (p->c != NFA_MOPEN)
+ return NULL; /* just in case */
+ p = p->out;
+ while (p->c > 0) {
+ len += MB_CHAR2LEN(p->c);
+ p = p->out;
+ }
+ if (p->c != NFA_MCLOSE || p->out->c != NFA_MATCH)
+ return NULL;
+
+ ret = alloc(len);
+ if (ret != NULL) {
+ len = 0;
+ 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;
+ p = p->out;
+ }
+ *s = NUL;
+ }
+ return ret;
+}
+
+/*
+ * Allocate more space for post_start. Called when
+ * running above the estimated number of states.
+ */
+static int realloc_post_list() {
+ int nstate_max = (int)(post_end - post_start);
+ int new_max = nstate_max + 1000;
+ int *new_start;
+ int *old_start;
+
+ new_start = (int *)lalloc(new_max * sizeof(int), TRUE);
+ if (new_start == NULL)
+ return FAIL;
+ mch_memmove(new_start, post_start, nstate_max * sizeof(int));
+ old_start = post_start;
+ post_start = new_start;
+ post_ptr = new_start + (post_ptr - old_start);
+ post_end = post_start + new_max;
+ vim_free(old_start);
+ return OK;
+}
+
+/*
+ * Search between "start" and "end" and try to recognize a
+ * character class in expanded form. For example [0-9].
+ * On success, return the id the character class to be emitted.
+ * On failure, return 0 (=FAIL)
+ * Start points to the first char of the range, while end should point
+ * to the closing brace.
+ * Keep in mind that 'ignorecase' applies at execution time, thus [a-z] may
+ * need to be interpreted as [a-zA-Z].
+ */
+static int nfa_recognize_char_class(start, end, extra_newl)
+char_u *start;
+char_u *end;
+int extra_newl;
+{
+# define CLASS_not 0x80
+# define CLASS_af 0x40
+# define CLASS_AF 0x20
+# define CLASS_az 0x10
+# define CLASS_AZ 0x08
+# define CLASS_o7 0x04
+# define CLASS_o9 0x02
+# define CLASS_underscore 0x01
+
+ int newl = FALSE;
+ char_u *p;
+ int config = 0;
+
+ if (extra_newl == TRUE)
+ newl = TRUE;
+
+ if (*end != ']')
+ return FAIL;
+ p = start;
+ if (*p == '^') {
+ config |= CLASS_not;
+ p++;
+ }
+
+ while (p < end) {
+ if (p + 2 < end && *(p + 1) == '-') {
+ switch (*p) {
+ case '0':
+ if (*(p + 2) == '9') {
+ config |= CLASS_o9;
+ break;
+ } else if (*(p + 2) == '7') {
+ config |= CLASS_o7;
+ break;
+ }
+ case 'a':
+ if (*(p + 2) == 'z') {
+ config |= CLASS_az;
+ break;
+ } else if (*(p + 2) == 'f') {
+ config |= CLASS_af;
+ break;
+ }
+ case 'A':
+ if (*(p + 2) == 'Z') {
+ config |= CLASS_AZ;
+ break;
+ } else if (*(p + 2) == 'F') {
+ config |= CLASS_AF;
+ break;
+ }
+ /* FALLTHROUGH */
+ default:
+ return FAIL;
+ }
+ p += 3;
+ } else if (p + 1 < end && *p == '\\' && *(p + 1) == 'n') {
+ newl = TRUE;
+ p += 2;
+ } else if (*p == '_') {
+ config |= CLASS_underscore;
+ p++;
+ } else if (*p == '\n') {
+ newl = TRUE;
+ p++;
+ } else
+ return FAIL;
+ } /* while (p < end) */
+
+ if (p != end)
+ return FAIL;
+
+ if (newl == TRUE)
+ extra_newl = NFA_ADD_NL;
+
+ switch (config) {
+ case CLASS_o9:
+ return extra_newl + NFA_DIGIT;
+ case CLASS_not | CLASS_o9:
+ return extra_newl + NFA_NDIGIT;
+ case CLASS_af | CLASS_AF | CLASS_o9:
+ return extra_newl + NFA_HEX;
+ case CLASS_not | CLASS_af | CLASS_AF | CLASS_o9:
+ return extra_newl + NFA_NHEX;
+ case CLASS_o7:
+ return extra_newl + NFA_OCTAL;
+ case CLASS_not | CLASS_o7:
+ return extra_newl + NFA_NOCTAL;
+ case CLASS_az | CLASS_AZ | CLASS_o9 | CLASS_underscore:
+ return extra_newl + NFA_WORD;
+ case CLASS_not | CLASS_az | CLASS_AZ | CLASS_o9 | CLASS_underscore:
+ return extra_newl + NFA_NWORD;
+ case CLASS_az | CLASS_AZ | CLASS_underscore:
+ return extra_newl + NFA_HEAD;
+ case CLASS_not | CLASS_az | CLASS_AZ | CLASS_underscore:
+ return extra_newl + NFA_NHEAD;
+ case CLASS_az | CLASS_AZ:
+ return extra_newl + NFA_ALPHA;
+ case CLASS_not | CLASS_az | CLASS_AZ:
+ return extra_newl + NFA_NALPHA;
+ case CLASS_az:
+ return extra_newl + NFA_LOWER_IC;
+ case CLASS_not | CLASS_az:
+ return extra_newl + NFA_NLOWER_IC;
+ case CLASS_AZ:
+ return extra_newl + NFA_UPPER_IC;
+ case CLASS_not | CLASS_AZ:
+ return extra_newl + NFA_NUPPER_IC;
+ }
+ return FAIL;
+}
+
+/*
+ * Produce the bytes for equivalence class "c".
+ * Currently only handles latin1, latin9 and utf-8.
+ * Emits bytes in postfix notation: 'a,b,NFA_OR,c,NFA_OR' is
+ * equivalent to 'a OR b OR c'
+ *
+ * NOTE! When changing this function, also update reg_equi_class()
+ */
+static int nfa_emit_equi_class(c)
+int c;
+{
+#define EMIT2(c) EMIT(c); EMIT(NFA_CONCAT);
+# define EMITMBC(c) EMIT(c); EMIT(NFA_CONCAT);
+
+ if (enc_utf8 || STRCMP(p_enc, "latin1") == 0
+ || STRCMP(p_enc, "iso-8859-15") == 0) {
+ 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);
+ EMITMBC(0x100) EMITMBC(0x102) EMITMBC(0x104)
+ EMITMBC(0x1cd) EMITMBC(0x1de) EMITMBC(0x1e0)
+ EMITMBC(0x1ea2)
+ return OK;
+
+ case 'B': CASEMBC(0x1e02) CASEMBC(0x1e06)
+ EMIT2('B'); EMITMBC(0x1e02) EMITMBC(0x1e06)
+ return OK;
+
+ case 'C': case 0307:
+ CASEMBC(0x106) CASEMBC(0x108) CASEMBC(0x10a) CASEMBC(0x10c)
+ EMIT2('C'); EMIT2(0307); EMITMBC(0x106) EMITMBC(0x108)
+ EMITMBC(0x10a) EMITMBC(0x10c)
+ return OK;
+
+ case 'D': CASEMBC(0x10e) CASEMBC(0x110) CASEMBC(0x1e0a)
+ CASEMBC(0x1e0e) CASEMBC(0x1e10)
+ EMIT2('D'); EMITMBC(0x10e) EMITMBC(0x110) EMITMBC(0x1e0a)
+ EMITMBC(0x1e0e) EMITMBC(0x1e10)
+ return OK;
+
+ 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);
+ EMITMBC(0x112) EMITMBC(0x114) EMITMBC(0x116)
+ EMITMBC(0x118) EMITMBC(0x11a) EMITMBC(0x1eba)
+ EMITMBC(0x1ebc)
+ return OK;
+
+ case 'F': CASEMBC(0x1e1e)
+ EMIT2('F'); EMITMBC(0x1e1e)
+ return OK;
+
+ case 'G': CASEMBC(0x11c) CASEMBC(0x11e) CASEMBC(0x120)
+ 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 OK;
+
+ case 'H': CASEMBC(0x124) CASEMBC(0x126) CASEMBC(0x1e22)
+ CASEMBC(0x1e26) CASEMBC(0x1e28)
+ EMIT2('H'); EMITMBC(0x124) EMITMBC(0x126) EMITMBC(0x1e22)
+ EMITMBC(0x1e26) EMITMBC(0x1e28)
+ return OK;
+
+ 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)
+ EMITMBC(0x12c) EMITMBC(0x12e) EMITMBC(0x130)
+ EMITMBC(0x1cf) EMITMBC(0x1ec8)
+ return OK;
+
+ case 'J': CASEMBC(0x134)
+ EMIT2('J'); EMITMBC(0x134)
+ return OK;
+
+ case 'K': CASEMBC(0x136) CASEMBC(0x1e8) CASEMBC(0x1e30)
+ CASEMBC(0x1e34)
+ EMIT2('K'); EMITMBC(0x136) EMITMBC(0x1e8) EMITMBC(0x1e30)
+ EMITMBC(0x1e34)
+ return OK;
+
+ case 'L': CASEMBC(0x139) CASEMBC(0x13b) CASEMBC(0x13d)
+ CASEMBC(0x13f) CASEMBC(0x141) CASEMBC(0x1e3a)
+ EMIT2('L'); EMITMBC(0x139) EMITMBC(0x13b) EMITMBC(0x13d)
+ EMITMBC(0x13f) EMITMBC(0x141) EMITMBC(0x1e3a)
+ return OK;
+
+ case 'M': CASEMBC(0x1e3e) CASEMBC(0x1e40)
+ EMIT2('M'); EMITMBC(0x1e3e) EMITMBC(0x1e40)
+ return OK;
+
+ case 'N': case 0321:
+ CASEMBC(0x143) CASEMBC(0x145) CASEMBC(0x147) CASEMBC(0x1e44)
+ CASEMBC(0x1e48)
+ EMIT2('N'); EMIT2(0321); EMITMBC(0x143) EMITMBC(0x145)
+ EMITMBC(0x147) EMITMBC(0x1e44) EMITMBC(0x1e48)
+ return OK;
+
+ 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);
+ EMITMBC(0x14c) EMITMBC(0x14e) EMITMBC(0x150)
+ EMITMBC(0x1a0) EMITMBC(0x1d1) EMITMBC(0x1ea)
+ EMITMBC(0x1ec) EMITMBC(0x1ece)
+ return OK;
+
+ case 'P': case 0x1e54: case 0x1e56:
+ EMIT2('P'); EMITMBC(0x1e54) EMITMBC(0x1e56)
+ return OK;
+
+ case 'R': CASEMBC(0x154) CASEMBC(0x156) CASEMBC(0x158)
+ CASEMBC(0x1e58) CASEMBC(0x1e5e)
+ EMIT2('R'); EMITMBC(0x154) EMITMBC(0x156) EMITMBC(0x158)
+ EMITMBC(0x1e58) EMITMBC(0x1e5e)
+ return OK;
+
+ case 'S': CASEMBC(0x15a) CASEMBC(0x15c) CASEMBC(0x15e)
+ CASEMBC(0x160) CASEMBC(0x1e60)
+ EMIT2('S'); EMITMBC(0x15a) EMITMBC(0x15c) EMITMBC(0x15e)
+ EMITMBC(0x160) EMITMBC(0x1e60)
+ return OK;
+
+ case 'T': CASEMBC(0x162) CASEMBC(0x164) CASEMBC(0x166)
+ CASEMBC(0x1e6a) CASEMBC(0x1e6e)
+ EMIT2('T'); EMITMBC(0x162) EMITMBC(0x164) EMITMBC(0x166)
+ EMITMBC(0x1e6a) EMITMBC(0x1e6e)
+ return OK;
+
+ 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)
+ EMITMBC(0x16c) EMITMBC(0x16e) EMITMBC(0x170)
+ EMITMBC(0x172) EMITMBC(0x1af) EMITMBC(0x1d3)
+ EMITMBC(0x1ee6)
+ return OK;
+
+ case 'V': CASEMBC(0x1e7c)
+ EMIT2('V'); EMITMBC(0x1e7c)
+ return OK;
+
+ case 'W': CASEMBC(0x174) CASEMBC(0x1e80) CASEMBC(0x1e82)
+ CASEMBC(0x1e84) CASEMBC(0x1e86)
+ EMIT2('W'); EMITMBC(0x174) EMITMBC(0x1e80) EMITMBC(0x1e82)
+ EMITMBC(0x1e84) EMITMBC(0x1e86)
+ return OK;
+
+ case 'X': CASEMBC(0x1e8a) CASEMBC(0x1e8c)
+ EMIT2('X'); EMITMBC(0x1e8a) EMITMBC(0x1e8c)
+ return OK;
+
+ case 'Y': case 0335:
+ CASEMBC(0x176) CASEMBC(0x178) CASEMBC(0x1e8e) CASEMBC(0x1ef2)
+ CASEMBC(0x1ef6) CASEMBC(0x1ef8)
+ EMIT2('Y'); EMIT2(0335); EMITMBC(0x176) EMITMBC(0x178)
+ EMITMBC(0x1e8e) EMITMBC(0x1ef2) EMITMBC(0x1ef6)
+ EMITMBC(0x1ef8)
+ return OK;
+
+ case 'Z': CASEMBC(0x179) CASEMBC(0x17b) CASEMBC(0x17d)
+ CASEMBC(0x1b5) CASEMBC(0x1e90) CASEMBC(0x1e94)
+ EMIT2('Z'); EMITMBC(0x179) EMITMBC(0x17b) EMITMBC(0x17d)
+ EMITMBC(0x1b5) EMITMBC(0x1e90) EMITMBC(0x1e94)
+ return OK;
+
+ 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);
+ EMITMBC(0x101) EMITMBC(0x103) EMITMBC(0x105)
+ EMITMBC(0x1ce) EMITMBC(0x1df) EMITMBC(0x1e1)
+ EMITMBC(0x1ea3)
+ return OK;
+
+ case 'b': CASEMBC(0x1e03) CASEMBC(0x1e07)
+ EMIT2('b'); EMITMBC(0x1e03) EMITMBC(0x1e07)
+ return OK;
+
+ case 'c': case 0347:
+ CASEMBC(0x107) CASEMBC(0x109) CASEMBC(0x10b) CASEMBC(0x10d)
+ EMIT2('c'); EMIT2(0347); EMITMBC(0x107) EMITMBC(0x109)
+ EMITMBC(0x10b) EMITMBC(0x10d)
+ return OK;
+
+ case 'd': CASEMBC(0x10f) CASEMBC(0x111) CASEMBC(0x1d0b)
+ CASEMBC(0x1e11)
+ EMIT2('d'); EMITMBC(0x10f) EMITMBC(0x111) EMITMBC(0x1e0b)
+ EMITMBC(0x01e0f) EMITMBC(0x1e11)
+ return OK;
+
+ 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)
+ EMITMBC(0x117) EMITMBC(0x119) EMITMBC(0x11b)
+ EMITMBC(0x1ebb) EMITMBC(0x1ebd)
+ return OK;
+
+ case 'f': CASEMBC(0x1e1f)
+ EMIT2('f'); EMITMBC(0x1e1f)
+ return OK;
+
+ case 'g': CASEMBC(0x11d) CASEMBC(0x11f) CASEMBC(0x121)
+ 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 OK;
+
+ case 'h': CASEMBC(0x125) CASEMBC(0x127) CASEMBC(0x1e23)
+ CASEMBC(0x1e27) CASEMBC(0x1e29) CASEMBC(0x1e96)
+ EMIT2('h'); EMITMBC(0x125) EMITMBC(0x127) EMITMBC(0x1e23)
+ EMITMBC(0x1e27) EMITMBC(0x1e29) EMITMBC(0x1e96)
+ return OK;
+
+ 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)
+ EMITMBC(0x12d) EMITMBC(0x12f) EMITMBC(0x1d0)
+ EMITMBC(0x1ec9)
+ return OK;
+
+ case 'j': CASEMBC(0x135) CASEMBC(0x1f0)
+ EMIT2('j'); EMITMBC(0x135) EMITMBC(0x1f0)
+ return OK;
+
+ case 'k': CASEMBC(0x137) CASEMBC(0x1e9) CASEMBC(0x1e31)
+ CASEMBC(0x1e35)
+ EMIT2('k'); EMITMBC(0x137) EMITMBC(0x1e9) EMITMBC(0x1e31)
+ EMITMBC(0x1e35)
+ return OK;
+
+ case 'l': CASEMBC(0x13a) CASEMBC(0x13c) CASEMBC(0x13e)
+ CASEMBC(0x140) CASEMBC(0x142) CASEMBC(0x1e3b)
+ EMIT2('l'); EMITMBC(0x13a) EMITMBC(0x13c) EMITMBC(0x13e)
+ EMITMBC(0x140) EMITMBC(0x142) EMITMBC(0x1e3b)
+ return OK;
+
+ case 'm': CASEMBC(0x1e3f) CASEMBC(0x1e41)
+ EMIT2('m'); EMITMBC(0x1e3f) EMITMBC(0x1e41)
+ return OK;
+
+ case 'n': case 0361:
+ CASEMBC(0x144) CASEMBC(0x146) CASEMBC(0x148) CASEMBC(0x149)
+ CASEMBC(0x1e45) CASEMBC(0x1e49)
+ EMIT2('n'); EMIT2(0361); EMITMBC(0x144) EMITMBC(0x146)
+ EMITMBC(0x148) EMITMBC(0x149) EMITMBC(0x1e45)
+ EMITMBC(0x1e49)
+ return OK;
+
+ 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);
+ EMITMBC(0x14d) EMITMBC(0x14f) EMITMBC(0x151)
+ EMITMBC(0x1a1) EMITMBC(0x1d2) EMITMBC(0x1eb)
+ EMITMBC(0x1ed) EMITMBC(0x1ecf)
+ return OK;
+
+ case 'p': CASEMBC(0x1e55) CASEMBC(0x1e57)
+ EMIT2('p'); EMITMBC(0x1e55) EMITMBC(0x1e57)
+ return OK;
+
+ case 'r': CASEMBC(0x155) CASEMBC(0x157) CASEMBC(0x159)
+ CASEMBC(0x1e59) CASEMBC(0x1e5f)
+ EMIT2('r'); EMITMBC(0x155) EMITMBC(0x157) EMITMBC(0x159)
+ EMITMBC(0x1e59) EMITMBC(0x1e5f)
+ return OK;
+
+ case 's': CASEMBC(0x15b) CASEMBC(0x15d) CASEMBC(0x15f)
+ CASEMBC(0x161) CASEMBC(0x1e61)
+ EMIT2('s'); EMITMBC(0x15b) EMITMBC(0x15d) EMITMBC(0x15f)
+ EMITMBC(0x161) EMITMBC(0x1e61)
+ return OK;
+
+ case 't': CASEMBC(0x163) CASEMBC(0x165) CASEMBC(0x167)
+ CASEMBC(0x1e6b) CASEMBC(0x1e6f) CASEMBC(0x1e97)
+ EMIT2('t'); EMITMBC(0x163) EMITMBC(0x165) EMITMBC(0x167)
+ EMITMBC(0x1e6b) EMITMBC(0x1e6f) EMITMBC(0x1e97)
+ return OK;
+
+ 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)
+ EMITMBC(0x16d) EMITMBC(0x16f) EMITMBC(0x171)
+ EMITMBC(0x173) EMITMBC(0x1b0) EMITMBC(0x1d4)
+ EMITMBC(0x1ee7)
+ return OK;
+
+ case 'v': CASEMBC(0x1e7d)
+ EMIT2('v'); EMITMBC(0x1e7d)
+ return OK;
+
+ case 'w': CASEMBC(0x175) CASEMBC(0x1e81) CASEMBC(0x1e83)
+ CASEMBC(0x1e85) CASEMBC(0x1e87) CASEMBC(0x1e98)
+ EMIT2('w'); EMITMBC(0x175) EMITMBC(0x1e81) EMITMBC(0x1e83)
+ EMITMBC(0x1e85) EMITMBC(0x1e87) EMITMBC(0x1e98)
+ return OK;
+
+ case 'x': CASEMBC(0x1e8b) CASEMBC(0x1e8d)
+ EMIT2('x'); EMITMBC(0x1e8b) EMITMBC(0x1e8d)
+ return OK;
+
+ 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)
+ EMITMBC(0x1e8f) EMITMBC(0x1e99) EMITMBC(0x1ef3)
+ EMITMBC(0x1ef7) EMITMBC(0x1ef9)
+ return OK;
+
+ case 'z': CASEMBC(0x17a) CASEMBC(0x17c) CASEMBC(0x17e)
+ CASEMBC(0x1b6) CASEMBC(0x1e91) CASEMBC(0x1e95)
+ EMIT2('z'); EMITMBC(0x17a) EMITMBC(0x17c) EMITMBC(0x17e)
+ EMITMBC(0x1b6) EMITMBC(0x1e91) EMITMBC(0x1e95)
+ return OK;
+
+ /* default: character itself */
+ }
+ }
+
+ EMIT2(c);
+ return OK;
+#undef EMIT2
+#undef EMITMBC
+}
+
+/*
+ * Code to parse regular expression.
+ *
+ * We try to reuse parsing functions in regexp.c to
+ * minimize surprise and keep the syntax consistent.
+ */
+
+/*
+ * Parse the lowest level.
+ *
+ * An atom can be one of a long list of items. Many atoms match one character
+ * in the text. It is often an ordinary character or a character class.
+ * Braces can be used to make a pattern into an atom. The "\z(\)" construct
+ * is only for syntax highlighting.
+ *
+ * atom ::= ordinary-atom
+ * or \( pattern \)
+ * or \%( pattern \)
+ * or \z( pattern \)
+ */
+static int nfa_regatom() {
+ int c;
+ int charclass;
+ int equiclass;
+ int collclass;
+ int got_coll_char;
+ char_u *p;
+ char_u *endp;
+ char_u *old_regparse = regparse;
+ int extra = 0;
+ int emit_range;
+ int negated;
+ int result;
+ int startc = -1;
+ int endc = -1;
+ int oldstartc = -1;
+
+ c = getchr();
+ switch (c) {
+ case NUL:
+ EMSG_RET_FAIL(_(e_nul_found));
+
+ case Magic('^'):
+ EMIT(NFA_BOL);
+ break;
+
+ case Magic('$'):
+ EMIT(NFA_EOL);
+ had_eol = TRUE;
+ break;
+
+ case Magic('<'):
+ EMIT(NFA_BOW);
+ break;
+
+ case Magic('>'):
+ EMIT(NFA_EOW);
+ break;
+
+ case Magic('_'):
+ c = no_Magic(getchr());
+ if (c == NUL)
+ EMSG_RET_FAIL(_(e_nul_found));
+
+ if (c == '^') { /* "\_^" is start-of-line */
+ EMIT(NFA_BOL);
+ break;
+ }
+ if (c == '$') { /* "\_$" is end-of-line */
+ EMIT(NFA_EOL);
+ had_eol = TRUE;
+ break;
+ }
+
+ extra = NFA_ADD_NL;
+
+ /* "\_[" is collection plus newline */
+ if (c == '[')
+ goto collection;
+
+ /* "\_x" is character class plus newline */
+ /*FALLTHROUGH*/
+
+ /*
+ * Character classes.
+ */
+ case Magic('.'):
+ case Magic('i'):
+ case Magic('I'):
+ case Magic('k'):
+ case Magic('K'):
+ case Magic('f'):
+ case Magic('F'):
+ case Magic('p'):
+ case Magic('P'):
+ case Magic('s'):
+ case Magic('S'):
+ case Magic('d'):
+ case Magic('D'):
+ case Magic('x'):
+ case Magic('X'):
+ case Magic('o'):
+ case Magic('O'):
+ case Magic('w'):
+ case Magic('W'):
+ case Magic('h'):
+ case Magic('H'):
+ case Magic('a'):
+ case Magic('A'):
+ case Magic('l'):
+ case Magic('L'):
+ case Magic('u'):
+ case Magic('U'):
+ p = vim_strchr(classchars, no_Magic(c));
+ if (p == NULL) {
+ if (extra == NFA_ADD_NL) {
+ EMSGN(_(e_ill_char_class), c);
+ rc_did_emsg = TRUE;
+ return FAIL;
+ }
+ EMSGN("INTERNAL: Unknown character class char: %ld", c);
+ return FAIL;
+ }
+ /* When '.' is followed by a composing char ignore the dot, so that
+ * the composing char is matched here. */
+ if (enc_utf8 && c == Magic('.') && utf_iscomposing(peekchr())) {
+ old_regparse = regparse;
+ c = getchr();
+ goto nfa_do_multibyte;
+ }
+ EMIT(nfa_classcodes[p - classchars]);
+ if (extra == NFA_ADD_NL) {
+ EMIT(NFA_NEWL);
+ EMIT(NFA_OR);
+ regflags |= RF_HASNL;
+ }
+ break;
+
+ case Magic('n'):
+ if (reg_string)
+ /* In a string "\n" matches a newline character. */
+ EMIT(NL);
+ else {
+ /* In buffer text "\n" matches the end of a line. */
+ EMIT(NFA_NEWL);
+ regflags |= RF_HASNL;
+ }
+ break;
+
+ case Magic('('):
+ if (nfa_reg(REG_PAREN) == FAIL)
+ return FAIL; /* cascaded error */
+ break;
+
+ case Magic('|'):
+ case Magic('&'):
+ case Magic(')'):
+ EMSGN(_(e_misplaced), no_Magic(c));
+ return FAIL;
+
+ case Magic('='):
+ case Magic('?'):
+ case Magic('+'):
+ case Magic('@'):
+ case Magic('*'):
+ case Magic('{'):
+ /* these should follow an atom, not form an atom */
+ EMSGN(_(e_misplaced), no_Magic(c));
+ return FAIL;
+
+ case Magic('~'):
+ {
+ char_u *lp;
+
+ /* Previous substitute pattern.
+ * Generated as "\%(pattern\)". */
+ if (reg_prev_sub == NULL) {
+ EMSG(_(e_nopresub));
+ return FAIL;
+ }
+ for (lp = reg_prev_sub; *lp != NUL; mb_cptr_adv(lp)) {
+ EMIT(PTR2CHAR(lp));
+ if (lp != reg_prev_sub)
+ EMIT(NFA_CONCAT);
+ }
+ EMIT(NFA_NOPEN);
+ break;
+ }
+
+ case Magic('1'):
+ case Magic('2'):
+ case Magic('3'):
+ case Magic('4'):
+ case Magic('5'):
+ case Magic('6'):
+ case Magic('7'):
+ case Magic('8'):
+ case Magic('9'):
+ EMIT(NFA_BACKREF1 + (no_Magic(c) - '1'));
+ nfa_has_backref = TRUE;
+ break;
+
+ case Magic('z'):
+ c = no_Magic(getchr());
+ switch (c) {
+ case 's':
+ EMIT(NFA_ZSTART);
+ break;
+ case 'e':
+ EMIT(NFA_ZEND);
+ nfa_has_zend = TRUE;
+ break;
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ /* \z1...\z9 */
+ if (reg_do_extmatch != REX_USE)
+ 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)
+ EMSG_RET_FAIL(_(e_z_not_allowed));
+ 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));
+ return FAIL;
+ }
+ break;
+
+ case Magic('%'):
+ c = no_Magic(getchr());
+ switch (c) {
+ /* () without a back reference */
+ case '(':
+ if (nfa_reg(REG_NPAREN) == FAIL)
+ return FAIL;
+ EMIT(NFA_NOPEN);
+ break;
+
+ case 'd': /* %d123 decimal */
+ case 'o': /* %o123 octal */
+ case 'x': /* %xab hex 2 */
+ case 'u': /* %uabcd hex 4 */
+ case 'U': /* %U1234abcd hex 8 */
+ {
+ int nr;
+
+ switch (c) {
+ case 'd': nr = getdecchrs(); break;
+ case 'o': nr = getoctchrs(); break;
+ case 'x': nr = gethexchrs(2); break;
+ case 'u': nr = gethexchrs(4); break;
+ case 'U': nr = gethexchrs(8); break;
+ default: nr = -1; break;
+ }
+
+ if (nr < 0)
+ EMSG2_RET_FAIL(
+ _("E678: Invalid character after %s%%[dxouU]"),
+ reg_magic == MAGIC_ALL);
+ /* A NUL is stored in the text as NL */
+ /* TODO: what if a composing character follows? */
+ EMIT(nr == 0 ? 0x0a : nr);
+ }
+ break;
+
+ /* Catch \%^ and \%$ regardless of where they appear in the
+ * pattern -- regardless of whether or not it makes sense. */
+ case '^':
+ EMIT(NFA_BOF);
+ break;
+
+ case '$':
+ EMIT(NFA_EOF);
+ break;
+
+ case '#':
+ EMIT(NFA_CURSOR);
+ break;
+
+ case 'V':
+ EMIT(NFA_VISUAL);
+ break;
+
+ case '[':
+ {
+ int n;
+
+ /* \%[abc] */
+ for (n = 0; (c = peekchr()) != ']'; ++n) {
+ if (c == NUL)
+ EMSG2_RET_FAIL(_(e_missing_sb),
+ reg_magic == MAGIC_ALL);
+ /* recursive call! */
+ if (nfa_regatom() == FAIL)
+ return FAIL;
+ }
+ getchr(); /* get the ] */
+ if (n == 0)
+ EMSG2_RET_FAIL(_(e_empty_sb),
+ reg_magic == MAGIC_ALL);
+ EMIT(NFA_OPT_CHARS);
+ EMIT(n);
+
+ /* Emit as "\%(\%[abc]\)" to be able to handle
+ * "\%[abc]*" which would cause the empty string to be
+ * matched an unlimited number of times. NFA_NOPEN is
+ * added only once at a position, while NFA_SPLIT is
+ * added multiple times. This is more efficient than
+ * not allowsing NFA_SPLIT multiple times, it is used
+ * a lot. */
+ EMIT(NFA_NOPEN);
+ break;
+ }
+
+ default:
+ {
+ int n = 0;
+ int cmp = c;
+
+ if (c == '<' || c == '>')
+ c = getchr();
+ while (VIM_ISDIGIT(c)) {
+ n = n * 10 + (c - '0');
+ c = getchr();
+ }
+ if (c == 'l' || c == 'c' || c == 'v') {
+ 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 */
+ EMIT(cmp == '<' ? NFA_COL_LT :
+ 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);
+ break;
+ } else if (c == '\'' && n == 0) {
+ /* \%'m \%<'m \%>'m */
+ EMIT(cmp == '<' ? NFA_MARK_LT :
+ cmp == '>' ? NFA_MARK_GT : NFA_MARK);
+ EMIT(getchr());
+ break;
+ }
+ }
+ EMSGN(_("E867: (NFA) Unknown operator '\\%%%c'"),
+ no_Magic(c));
+ return FAIL;
+ }
+ break;
+
+ case Magic('['):
+collection:
+ /*
+ * [abc] uses NFA_START_COLL - NFA_END_COLL
+ * [^abc] uses NFA_START_NEG_COLL - NFA_END_NEG_COLL
+ * Each character is produced as a regular state, using
+ * NFA_CONCAT to bind them together.
+ * Besides normal characters there can be:
+ * - character classes NFA_CLASS_*
+ * - ranges, two characters followed by NFA_RANGE.
+ */
+
+ p = regparse;
+ endp = skip_anyof(p);
+ if (*endp == ']') {
+ /*
+ * Try to reverse engineer character classes. For example,
+ * recognize that [0-9] stands for \d and [A-Za-z_] for \h,
+ * and perform the necessary substitutions in the NFA.
+ */
+ result = nfa_recognize_char_class(regparse, endp,
+ extra == NFA_ADD_NL);
+ if (result != FAIL) {
+ if (result >= NFA_FIRST_NL && result <= NFA_LAST_NL) {
+ EMIT(result - NFA_ADD_NL);
+ EMIT(NFA_NEWL);
+ EMIT(NFA_OR);
+ } else
+ EMIT(result);
+ regparse = endp;
+ mb_ptr_adv(regparse);
+ return OK;
+ }
+ /*
+ * Failed to recognize a character class. Use the simple
+ * 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);
+ EMIT(NFA_START_NEG_COLL);
+ } else
+ EMIT(NFA_START_COLL);
+ if (*regparse == '-') {
+ startc = '-';
+ EMIT(startc);
+ EMIT(NFA_CONCAT);
+ mb_ptr_adv(regparse);
+ }
+ /* Emit the OR branches for each character in the [] */
+ emit_range = FALSE;
+ while (regparse < endp) {
+ oldstartc = startc;
+ startc = -1;
+ got_coll_char = FALSE;
+ if (*regparse == '[') {
+ /* Check for [: :], [= =], [. .] */
+ equiclass = collclass = 0;
+ charclass = get_char_class(&regparse);
+ if (charclass == CLASS_NONE) {
+ equiclass = get_equi_class(&regparse);
+ if (equiclass == 0)
+ collclass = get_coll_element(&regparse);
+ }
+
+ /* Character class like [:alpha:] */
+ if (charclass != CLASS_NONE) {
+ switch (charclass) {
+ case CLASS_ALNUM:
+ EMIT(NFA_CLASS_ALNUM);
+ break;
+ case CLASS_ALPHA:
+ EMIT(NFA_CLASS_ALPHA);
+ break;
+ case CLASS_BLANK:
+ EMIT(NFA_CLASS_BLANK);
+ break;
+ case CLASS_CNTRL:
+ EMIT(NFA_CLASS_CNTRL);
+ break;
+ case CLASS_DIGIT:
+ EMIT(NFA_CLASS_DIGIT);
+ break;
+ case CLASS_GRAPH:
+ EMIT(NFA_CLASS_GRAPH);
+ break;
+ case CLASS_LOWER:
+ EMIT(NFA_CLASS_LOWER);
+ break;
+ case CLASS_PRINT:
+ EMIT(NFA_CLASS_PRINT);
+ break;
+ case CLASS_PUNCT:
+ EMIT(NFA_CLASS_PUNCT);
+ break;
+ case CLASS_SPACE:
+ EMIT(NFA_CLASS_SPACE);
+ break;
+ case CLASS_UPPER:
+ EMIT(NFA_CLASS_UPPER);
+ break;
+ case CLASS_XDIGIT:
+ EMIT(NFA_CLASS_XDIGIT);
+ break;
+ case CLASS_TAB:
+ EMIT(NFA_CLASS_TAB);
+ break;
+ case CLASS_RETURN:
+ EMIT(NFA_CLASS_RETURN);
+ break;
+ case CLASS_BACKSPACE:
+ EMIT(NFA_CLASS_BACKSPACE);
+ break;
+ case CLASS_ESCAPE:
+ EMIT(NFA_CLASS_ESCAPE);
+ break;
+ }
+ EMIT(NFA_CONCAT);
+ continue;
+ }
+ /* Try equivalence class [=a=] and the like */
+ if (equiclass != 0) {
+ result = nfa_emit_equi_class(equiclass);
+ if (result == FAIL) {
+ /* should never happen */
+ EMSG_RET_FAIL(_(
+ "E868: Error building NFA with equivalence class!"));
+ }
+ continue;
+ }
+ /* Try collating class like [. .] */
+ if (collclass != 0) {
+ startc = collclass; /* allow [.a.]-x as a range */
+ /* Will emit the proper atom at the end of the
+ * while loop. */
+ }
+ }
+ /* Try a range like 'a-x' or '\t-z'. Also allows '-' as a
+ * start character. */
+ if (*regparse == '-' && oldstartc != -1) {
+ emit_range = TRUE;
+ startc = oldstartc;
+ mb_ptr_adv(regparse);
+ continue; /* reading the end of the range */
+ }
+
+ /* Now handle simple and escaped characters.
+ * Only "\]", "\^", "\]" and "\\" are special in Vi. Vim
+ * accepts "\t", "\e", etc., but only when the 'l' flag in
+ * 'cpoptions' is not included.
+ * Posix doesn't recognize backslash at all.
+ */
+ if (*regparse == '\\'
+ && !reg_cpo_bsl
+ && regparse + 1 <= endp
+ && (vim_strchr(REGEXP_INRANGE, regparse[1]) != NULL
+ || (!reg_cpo_lit
+ && vim_strchr(REGEXP_ABBR, regparse[1])
+ != NULL)
+ )
+ ) {
+ mb_ptr_adv(regparse);
+
+ if (*regparse == 'n')
+ startc = reg_string ? NL : NFA_NEWL;
+ else if (*regparse == 'd'
+ || *regparse == 'o'
+ || *regparse == 'x'
+ || *regparse == 'u'
+ || *regparse == 'U'
+ ) {
+ /* TODO(RE) This needs more testing */
+ startc = coll_get_char();
+ got_coll_char = TRUE;
+ mb_ptr_back(old_regparse, regparse);
+ } else {
+ /* \r,\t,\e,\b */
+ startc = backslash_trans(*regparse);
+ }
+ }
+
+ /* Normal printable char */
+ if (startc == -1)
+ startc = PTR2CHAR(regparse);
+
+ /* Previous char was '-', so this char is end of range. */
+ if (emit_range) {
+ endc = startc;
+ startc = oldstartc;
+ if (startc > endc)
+ EMSG_RET_FAIL(_(e_invrange));
+
+ if (endc > startc + 2) {
+ /* Emit a range instead of the sequence of
+ * individual characters. */
+ if (startc == 0)
+ /* \x00 is translated to \x0a, start at \x01. */
+ EMIT(1);
+ else
+ --post_ptr; /* remove NFA_CONCAT */
+ EMIT(endc);
+ EMIT(NFA_RANGE);
+ EMIT(NFA_CONCAT);
+ } else if (has_mbyte && ((*mb_char2len)(startc) > 1
+ || (*mb_char2len)(endc) > 1)) {
+ /* Emit the characters in the range.
+ * "startc" was already emitted, so skip it.
+ * */
+ for (c = startc + 1; c <= endc; c++) {
+ EMIT(c);
+ EMIT(NFA_CONCAT);
+ }
+ } else {
+ /* Emit the range. "startc" was already emitted, so
+ * skip it. */
+ for (c = startc + 1; c <= endc; c++) {
+ EMIT(c);
+ EMIT(NFA_CONCAT);
+ }
+ }
+ emit_range = FALSE;
+ startc = -1;
+ } else {
+ /* This char (startc) is not part of a range. Just
+ * emit it.
+ * Normally, simply emit startc. But if we get char
+ * code=0 from a collating char, then replace it with
+ * 0x0a.
+ * This is needed to completely mimic the behaviour of
+ * the backtracking engine. */
+ if (startc == NFA_NEWL) {
+ /* Line break can't be matched as part of the
+ * collection, add an OR below. But not for negated
+ * range. */
+ if (!negated)
+ extra = NFA_ADD_NL;
+ } else {
+ if (got_coll_char == TRUE && startc == 0)
+ EMIT(0x0a);
+ else
+ EMIT(startc);
+ EMIT(NFA_CONCAT);
+ }
+ }
+
+ mb_ptr_adv(regparse);
+ } /* while (p < endp) */
+
+ 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);
+
+ /* Mark end of the collection. */
+ if (negated == TRUE)
+ EMIT(NFA_END_NEG_COLL);
+ else
+ EMIT(NFA_END_COLL);
+
+ /* \_[] also matches \n but it's not negated */
+ if (extra == NFA_ADD_NL) {
+ EMIT(reg_string ? NL : NFA_NEWL);
+ EMIT(NFA_OR);
+ }
+
+ return OK;
+ } /* if exists closing ] */
+
+ if (reg_strict)
+ EMSG_RET_FAIL(_(e_missingbracket));
+ /* FALLTHROUGH */
+
+ default:
+ {
+ int plen;
+
+nfa_do_multibyte:
+ /* plen is length of current char with composing chars */
+ if (enc_utf8 && ((*mb_char2len)(c)
+ != (plen = (*mb_ptr2len)(old_regparse))
+ || utf_iscomposing(c))) {
+ int i = 0;
+
+ /* A base character plus composing characters, or just one
+ * or more composing characters.
+ * This requires creating a separate atom as if enclosing
+ * the characters in (), where NFA_COMPOSING is the ( and
+ * NFA_END_COMPOSING is the ). Note that right now we are
+ * building the postfix form, not the NFA itself;
+ * a composing char could be: a, b, c, NFA_COMPOSING
+ * where 'b' and 'c' are chars with codes > 256. */
+ for (;; ) {
+ EMIT(c);
+ if (i > 0)
+ EMIT(NFA_CONCAT);
+ if ((i += utf_char2len(c)) >= plen)
+ break;
+ c = utf_ptr2char(old_regparse + i);
+ }
+ EMIT(NFA_COMPOSING);
+ regparse = old_regparse + plen;
+ } else {
+ c = no_Magic(c);
+ EMIT(c);
+ }
+ return OK;
+ }
+ }
+
+ return OK;
+}
+
+/*
+ * Parse something followed by possible [*+=].
+ *
+ * A piece is an atom, possibly followed by a multi, an indication of how many
+ * times the atom can be matched. Example: "a*" matches any sequence of "a"
+ * characters: "", "a", "aa", etc.
+ *
+ * piece ::= atom
+ * or atom multi
+ */
+static int nfa_regpiece() {
+ int i;
+ int op;
+ int ret;
+ long minval, maxval;
+ int greedy = TRUE; /* Braces are prefixed with '-' ? */
+ parse_state_T old_state;
+ parse_state_T new_state;
+ int c2;
+ int old_post_pos;
+ int my_post_start;
+ int quest;
+
+ /* Save the current parse state, so that we can use it if <atom>{m,n} is
+ * next. */
+ save_parse_state(&old_state);
+
+ /* store current pos in the postfix form, for \{m,n} involving 0s */
+ my_post_start = (int)(post_ptr - post_start);
+
+ ret = nfa_regatom();
+ if (ret == FAIL)
+ return FAIL; /* cascaded error */
+
+ op = peekchr();
+ if (re_multi_type(op) == NOT_MULTI)
+ return OK;
+
+ skipchr();
+ switch (op) {
+ case Magic('*'):
+ EMIT(NFA_STAR);
+ break;
+
+ case Magic('+'):
+ /*
+ * Trick: Normally, (a*)\+ would match the whole input "aaa". The
+ * first and only submatch would be "aaa". But the backtracking
+ * engine interprets the plus as "try matching one more time", and
+ * a* matches a second time at the end of the input, the empty
+ * string.
+ * The submatch will be the empty string.
+ *
+ * In order to be consistent with the old engine, we replace
+ * <atom>+ with <atom><atom>*
+ */
+ restore_parse_state(&old_state);
+ curchr = -1;
+ if (nfa_regatom() == FAIL)
+ return FAIL;
+ EMIT(NFA_STAR);
+ EMIT(NFA_CONCAT);
+ skipchr(); /* skip the \+ */
+ break;
+
+ case Magic('@'):
+ c2 = getdecchrs();
+ op = no_Magic(getchr());
+ i = 0;
+ switch(op) {
+ case '=':
+ /* \@= */
+ i = NFA_PREV_ATOM_NO_WIDTH;
+ break;
+ case '!':
+ /* \@! */
+ i = NFA_PREV_ATOM_NO_WIDTH_NEG;
+ break;
+ case '<':
+ op = no_Magic(getchr());
+ if (op == '=')
+ /* \@<= */
+ i = NFA_PREV_ATOM_JUST_BEFORE;
+ else if (op == '!')
+ /* \@<! */
+ i = NFA_PREV_ATOM_JUST_BEFORE_NEG;
+ break;
+ case '>':
+ /* \@> */
+ i = NFA_PREV_ATOM_LIKE_PATTERN;
+ break;
+ }
+ if (i == 0) {
+ EMSGN(_("E869: (NFA) Unknown operator '\\@%c'"), op);
+ return FAIL;
+ }
+ EMIT(i);
+ if (i == NFA_PREV_ATOM_JUST_BEFORE
+ || i == NFA_PREV_ATOM_JUST_BEFORE_NEG)
+ EMIT(c2);
+ break;
+
+ case Magic('?'):
+ case Magic('='):
+ EMIT(NFA_QUEST);
+ break;
+
+ case Magic('{'):
+ /* a{2,5} will expand to 'aaa?a?a?'
+ * a{-1,3} will expand to 'aa??a??', where ?? is the nongreedy
+ * version of '?'
+ * \v(ab){2,3} will expand to '(ab)(ab)(ab)?', where all the
+ * parenthesis have the same id
+ */
+
+ greedy = TRUE;
+ c2 = peekchr();
+ if (c2 == '-' || c2 == Magic('-')) {
+ skipchr();
+ greedy = FALSE;
+ }
+ if (!read_limits(&minval, &maxval))
+ EMSG_RET_FAIL(_("E870: (NFA regexp) Error reading repetition limits"));
+
+ /* <atom>{0,inf}, <atom>{0,} and <atom>{} are equivalent to
+ * <atom>* */
+ if (minval == 0 && maxval == MAX_LIMIT) {
+ if (greedy)
+ /* \{}, \{0,} */
+ EMIT(NFA_STAR);
+ else
+ /* \{-}, \{-0,} */
+ EMIT(NFA_STAR_NONGREEDY);
+ break;
+ }
+
+ /* Special case: x{0} or x{-0} */
+ if (maxval == 0) {
+ /* Ignore result of previous call to nfa_regatom() */
+ post_ptr = post_start + my_post_start;
+ /* NFA_EMPTY is 0-length and works everywhere */
+ EMIT(NFA_EMPTY);
+ return OK;
+ }
+
+ /* Ignore previous call to nfa_regatom() */
+ post_ptr = post_start + my_post_start;
+ /* Save parse state after the repeated atom and the \{} */
+ save_parse_state(&new_state);
+
+ quest = (greedy == TRUE ? NFA_QUEST : NFA_QUEST_NONGREEDY);
+ for (i = 0; i < maxval; i++) {
+ /* Goto beginning of the repeated atom */
+ restore_parse_state(&old_state);
+ old_post_pos = (int)(post_ptr - post_start);
+ if (nfa_regatom() == FAIL)
+ return FAIL;
+ /* after "minval" times, atoms are optional */
+ if (i + 1 > minval) {
+ if (maxval == MAX_LIMIT) {
+ if (greedy)
+ EMIT(NFA_STAR);
+ else
+ EMIT(NFA_STAR_NONGREEDY);
+ } else
+ EMIT(quest);
+ }
+ if (old_post_pos != my_post_start)
+ EMIT(NFA_CONCAT);
+ if (i + 1 > minval && maxval == MAX_LIMIT)
+ break;
+ }
+
+ /* Go to just after the repeated atom and the \{} */
+ restore_parse_state(&new_state);
+ curchr = -1;
+
+ break;
+
+
+ default:
+ 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 !"));
+
+ return OK;
+}
+
+/*
+ * Parse one or more pieces, concatenated. It matches a match for the
+ * first piece, followed by a match for the second piece, etc. Example:
+ * "f[0-9]b", first matches "f", then a digit and then "b".
+ *
+ * concat ::= piece
+ * or piece piece
+ * or piece piece piece
+ * etc.
+ */
+static int nfa_regconcat() {
+ int cont = TRUE;
+ int first = TRUE;
+
+ while (cont) {
+ switch (peekchr()) {
+ case NUL:
+ case Magic('|'):
+ case Magic('&'):
+ case Magic(')'):
+ cont = FALSE;
+ break;
+
+ case Magic('Z'):
+ regflags |= RF_ICOMBINE;
+ skipchr_keepstart();
+ break;
+ case Magic('c'):
+ regflags |= RF_ICASE;
+ skipchr_keepstart();
+ break;
+ case Magic('C'):
+ regflags |= RF_NOICASE;
+ skipchr_keepstart();
+ break;
+ case Magic('v'):
+ reg_magic = MAGIC_ALL;
+ skipchr_keepstart();
+ curchr = -1;
+ break;
+ case Magic('m'):
+ reg_magic = MAGIC_ON;
+ skipchr_keepstart();
+ curchr = -1;
+ break;
+ case Magic('M'):
+ reg_magic = MAGIC_OFF;
+ skipchr_keepstart();
+ curchr = -1;
+ break;
+ case Magic('V'):
+ reg_magic = MAGIC_NONE;
+ skipchr_keepstart();
+ curchr = -1;
+ break;
+
+ default:
+ if (nfa_regpiece() == FAIL)
+ return FAIL;
+ if (first == FALSE)
+ EMIT(NFA_CONCAT);
+ else
+ first = FALSE;
+ break;
+ }
+ }
+
+ return OK;
+}
+
+/*
+ * Parse a branch, one or more concats, separated by "\&". It matches the
+ * last concat, but only if all the preceding concats also match at the same
+ * position. Examples:
+ * "foobeep\&..." matches "foo" in "foobeep".
+ * ".*Peter\&.*Bob" matches in a line containing both "Peter" and "Bob"
+ *
+ * branch ::= concat
+ * or concat \& concat
+ * or concat \& concat \& concat
+ * etc.
+ */
+static int nfa_regbranch() {
+ int ch;
+ int old_post_pos;
+
+ old_post_pos = (int)(post_ptr - post_start);
+
+ /* First branch, possibly the only one */
+ if (nfa_regconcat() == FAIL)
+ return FAIL;
+
+ ch = peekchr();
+ /* Try next concats */
+ while (ch == Magic('&')) {
+ skipchr();
+ EMIT(NFA_NOPEN);
+ EMIT(NFA_PREV_ATOM_NO_WIDTH);
+ old_post_pos = (int)(post_ptr - post_start);
+ if (nfa_regconcat() == FAIL)
+ return FAIL;
+ /* if concat is empty do emit a node */
+ 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 */
+ if (old_post_pos == (int)(post_ptr - post_start))
+ EMIT(NFA_EMPTY);
+
+ return OK;
+}
+
+/*
+ * Parse a pattern, one or more branches, separated by "\|". It matches
+ * anything that matches one of the branches. Example: "foo\|beep" matches
+ * "foo" and matches "beep". If more than one branch matches, the first one
+ * is used.
+ *
+ * pattern ::= branch
+ * or branch \| branch
+ * or branch \| branch \| branch
+ * etc.
+ */
+static int nfa_reg(paren)
+int paren; /* REG_NOPAREN, REG_PAREN, REG_NPAREN or REG_ZPAREN */
+{
+ int parno = 0;
+
+ if (paren == REG_PAREN) {
+ if (regnpar >= NSUBEXP) /* Too many `(' */
+ EMSG_RET_FAIL(_("E872: (NFA regexp) Too many '('"));
+ parno = regnpar++;
+ } else if (paren == REG_ZPAREN) {
+ /* Make a ZOPEN node. */
+ if (regnzpar >= NSUBEXP)
+ EMSG_RET_FAIL(_("E879: (NFA regexp) Too many \\z("));
+ parno = regnzpar++;
+ }
+
+ if (nfa_regbranch() == FAIL)
+ return FAIL; /* cascaded error */
+
+ while (peekchr() == Magic('|')) {
+ skipchr();
+ if (nfa_regbranch() == FAIL)
+ return FAIL; /* cascaded error */
+ EMIT(NFA_OR);
+ }
+
+ /* Check for proper termination. */
+ if (paren != REG_NOPAREN && getchr() != Magic(')')) {
+ if (paren == REG_NPAREN)
+ EMSG2_RET_FAIL(_(e_unmatchedpp), reg_magic == MAGIC_ALL);
+ else
+ EMSG2_RET_FAIL(_(e_unmatchedp), reg_magic == MAGIC_ALL);
+ } else if (paren == REG_NOPAREN && peekchr() != NUL) {
+ if (peekchr() == Magic(')'))
+ EMSG2_RET_FAIL(_(e_unmatchedpar), reg_magic == MAGIC_ALL);
+ else
+ EMSG_RET_FAIL(_("E873: (NFA regexp) proper termination error"));
+ }
+ /*
+ * Here we set the flag allowing back references to this set of
+ * parentheses.
+ */
+ if (paren == REG_PAREN) {
+ had_endbrace[parno] = TRUE; /* have seen the close paren */
+ EMIT(NFA_MOPEN + parno);
+ } else if (paren == REG_ZPAREN)
+ EMIT(NFA_ZOPEN + parno);
+
+ return OK;
+}
+
+#ifdef REGEXP_DEBUG
+static char_u code[50];
+
+static void nfa_set_code(c)
+int c;
+{
+ int addnl = FALSE;
+
+ if (c >= NFA_FIRST_NL && c <= NFA_LAST_NL) {
+ addnl = TRUE;
+ c -= NFA_ADD_NL;
+ }
+
+ STRCPY(code, "");
+ switch (c) {
+ case NFA_MATCH: STRCPY(code, "NFA_MATCH "); break;
+ case NFA_SPLIT: STRCPY(code, "NFA_SPLIT "); break;
+ case NFA_CONCAT: STRCPY(code, "NFA_CONCAT "); break;
+ case NFA_NEWL: STRCPY(code, "NFA_NEWL "); break;
+ case NFA_ZSTART: STRCPY(code, "NFA_ZSTART"); break;
+ case NFA_ZEND: STRCPY(code, "NFA_ZEND"); break;
+
+ case NFA_BACKREF1: STRCPY(code, "NFA_BACKREF1"); break;
+ case NFA_BACKREF2: STRCPY(code, "NFA_BACKREF2"); break;
+ case NFA_BACKREF3: STRCPY(code, "NFA_BACKREF3"); break;
+ case NFA_BACKREF4: STRCPY(code, "NFA_BACKREF4"); break;
+ case NFA_BACKREF5: STRCPY(code, "NFA_BACKREF5"); break;
+ case NFA_BACKREF6: STRCPY(code, "NFA_BACKREF6"); break;
+ case NFA_BACKREF7: STRCPY(code, "NFA_BACKREF7"); break;
+ case NFA_BACKREF8: STRCPY(code, "NFA_BACKREF8"); break;
+ case NFA_BACKREF9: STRCPY(code, "NFA_BACKREF9"); break;
+ case NFA_ZREF1: STRCPY(code, "NFA_ZREF1"); break;
+ case NFA_ZREF2: STRCPY(code, "NFA_ZREF2"); break;
+ case NFA_ZREF3: STRCPY(code, "NFA_ZREF3"); break;
+ case NFA_ZREF4: STRCPY(code, "NFA_ZREF4"); break;
+ case NFA_ZREF5: STRCPY(code, "NFA_ZREF5"); break;
+ case NFA_ZREF6: STRCPY(code, "NFA_ZREF6"); break;
+ case NFA_ZREF7: STRCPY(code, "NFA_ZREF7"); break;
+ case NFA_ZREF8: STRCPY(code, "NFA_ZREF8"); break;
+ case NFA_ZREF9: STRCPY(code, "NFA_ZREF9"); break;
+ case NFA_SKIP: STRCPY(code, "NFA_SKIP"); break;
+
+ case NFA_PREV_ATOM_NO_WIDTH:
+ STRCPY(code, "NFA_PREV_ATOM_NO_WIDTH"); break;
+ case NFA_PREV_ATOM_NO_WIDTH_NEG:
+ STRCPY(code, "NFA_PREV_ATOM_NO_WIDTH_NEG"); break;
+ case NFA_PREV_ATOM_JUST_BEFORE:
+ STRCPY(code, "NFA_PREV_ATOM_JUST_BEFORE"); break;
+ case NFA_PREV_ATOM_JUST_BEFORE_NEG:
+ STRCPY(code, "NFA_PREV_ATOM_JUST_BEFORE_NEG"); break;
+ case NFA_PREV_ATOM_LIKE_PATTERN:
+ STRCPY(code, "NFA_PREV_ATOM_LIKE_PATTERN"); break;
+
+ case NFA_NOPEN: STRCPY(code, "NFA_NOPEN"); break;
+ case NFA_NCLOSE: STRCPY(code, "NFA_NCLOSE"); break;
+ case NFA_START_INVISIBLE: STRCPY(code, "NFA_START_INVISIBLE"); break;
+ case NFA_START_INVISIBLE_FIRST:
+ STRCPY(code, "NFA_START_INVISIBLE_FIRST"); break;
+ case NFA_START_INVISIBLE_NEG:
+ STRCPY(code, "NFA_START_INVISIBLE_NEG"); break;
+ case NFA_START_INVISIBLE_NEG_FIRST:
+ STRCPY(code, "NFA_START_INVISIBLE_NEG_FIRST"); break;
+ case NFA_START_INVISIBLE_BEFORE:
+ STRCPY(code, "NFA_START_INVISIBLE_BEFORE"); break;
+ case NFA_START_INVISIBLE_BEFORE_FIRST:
+ STRCPY(code, "NFA_START_INVISIBLE_BEFORE_FIRST"); break;
+ case NFA_START_INVISIBLE_BEFORE_NEG:
+ STRCPY(code, "NFA_START_INVISIBLE_BEFORE_NEG"); break;
+ case NFA_START_INVISIBLE_BEFORE_NEG_FIRST:
+ STRCPY(code, "NFA_START_INVISIBLE_BEFORE_NEG_FIRST"); break;
+ case NFA_START_PATTERN: STRCPY(code, "NFA_START_PATTERN"); break;
+ case NFA_END_INVISIBLE: STRCPY(code, "NFA_END_INVISIBLE"); break;
+ case NFA_END_INVISIBLE_NEG: STRCPY(code, "NFA_END_INVISIBLE_NEG"); break;
+ case NFA_END_PATTERN: STRCPY(code, "NFA_END_PATTERN"); break;
+
+ case NFA_COMPOSING: STRCPY(code, "NFA_COMPOSING"); break;
+ case NFA_END_COMPOSING: STRCPY(code, "NFA_END_COMPOSING"); break;
+ case NFA_OPT_CHARS: STRCPY(code, "NFA_OPT_CHARS"); break;
+
+ case NFA_MOPEN:
+ case NFA_MOPEN1:
+ case NFA_MOPEN2:
+ case NFA_MOPEN3:
+ case NFA_MOPEN4:
+ case NFA_MOPEN5:
+ case NFA_MOPEN6:
+ case NFA_MOPEN7:
+ case NFA_MOPEN8:
+ case NFA_MOPEN9:
+ STRCPY(code, "NFA_MOPEN(x)");
+ code[10] = c - NFA_MOPEN + '0';
+ break;
+ case NFA_MCLOSE:
+ case NFA_MCLOSE1:
+ case NFA_MCLOSE2:
+ case NFA_MCLOSE3:
+ case NFA_MCLOSE4:
+ case NFA_MCLOSE5:
+ case NFA_MCLOSE6:
+ case NFA_MCLOSE7:
+ case NFA_MCLOSE8:
+ case NFA_MCLOSE9:
+ STRCPY(code, "NFA_MCLOSE(x)");
+ code[11] = c - NFA_MCLOSE + '0';
+ break;
+ case NFA_ZOPEN:
+ case NFA_ZOPEN1:
+ case NFA_ZOPEN2:
+ case NFA_ZOPEN3:
+ case NFA_ZOPEN4:
+ case NFA_ZOPEN5:
+ case NFA_ZOPEN6:
+ case NFA_ZOPEN7:
+ case NFA_ZOPEN8:
+ case NFA_ZOPEN9:
+ STRCPY(code, "NFA_ZOPEN(x)");
+ code[10] = c - NFA_ZOPEN + '0';
+ break;
+ case NFA_ZCLOSE:
+ case NFA_ZCLOSE1:
+ case NFA_ZCLOSE2:
+ case NFA_ZCLOSE3:
+ case NFA_ZCLOSE4:
+ case NFA_ZCLOSE5:
+ case NFA_ZCLOSE6:
+ case NFA_ZCLOSE7:
+ case NFA_ZCLOSE8:
+ case NFA_ZCLOSE9:
+ STRCPY(code, "NFA_ZCLOSE(x)");
+ code[11] = c - NFA_ZCLOSE + '0';
+ break;
+ case NFA_EOL: STRCPY(code, "NFA_EOL "); break;
+ case NFA_BOL: STRCPY(code, "NFA_BOL "); break;
+ case NFA_EOW: STRCPY(code, "NFA_EOW "); break;
+ case NFA_BOW: STRCPY(code, "NFA_BOW "); break;
+ case NFA_EOF: STRCPY(code, "NFA_EOF "); break;
+ case NFA_BOF: STRCPY(code, "NFA_BOF "); break;
+ case NFA_LNUM: STRCPY(code, "NFA_LNUM "); break;
+ case NFA_LNUM_GT: STRCPY(code, "NFA_LNUM_GT "); break;
+ case NFA_LNUM_LT: STRCPY(code, "NFA_LNUM_LT "); break;
+ case NFA_COL: STRCPY(code, "NFA_COL "); break;
+ case NFA_COL_GT: STRCPY(code, "NFA_COL_GT "); break;
+ case NFA_COL_LT: STRCPY(code, "NFA_COL_LT "); break;
+ case NFA_VCOL: STRCPY(code, "NFA_VCOL "); break;
+ case NFA_VCOL_GT: STRCPY(code, "NFA_VCOL_GT "); break;
+ case NFA_VCOL_LT: STRCPY(code, "NFA_VCOL_LT "); break;
+ case NFA_MARK: STRCPY(code, "NFA_MARK "); break;
+ case NFA_MARK_GT: STRCPY(code, "NFA_MARK_GT "); break;
+ case NFA_MARK_LT: STRCPY(code, "NFA_MARK_LT "); break;
+ case NFA_CURSOR: STRCPY(code, "NFA_CURSOR "); break;
+ case NFA_VISUAL: STRCPY(code, "NFA_VISUAL "); break;
+
+ case NFA_STAR: STRCPY(code, "NFA_STAR "); break;
+ case NFA_STAR_NONGREEDY: STRCPY(code, "NFA_STAR_NONGREEDY "); break;
+ case NFA_QUEST: STRCPY(code, "NFA_QUEST"); break;
+ case NFA_QUEST_NONGREEDY: STRCPY(code, "NFA_QUEST_NON_GREEDY"); break;
+ case NFA_EMPTY: STRCPY(code, "NFA_EMPTY"); break;
+ case NFA_OR: STRCPY(code, "NFA_OR"); break;
+
+ case NFA_START_COLL: STRCPY(code, "NFA_START_COLL"); break;
+ case NFA_END_COLL: STRCPY(code, "NFA_END_COLL"); break;
+ case NFA_START_NEG_COLL: STRCPY(code, "NFA_START_NEG_COLL"); break;
+ case NFA_END_NEG_COLL: STRCPY(code, "NFA_END_NEG_COLL"); break;
+ case NFA_RANGE: STRCPY(code, "NFA_RANGE"); break;
+ case NFA_RANGE_MIN: STRCPY(code, "NFA_RANGE_MIN"); break;
+ case NFA_RANGE_MAX: STRCPY(code, "NFA_RANGE_MAX"); break;
+
+ case NFA_CLASS_ALNUM: STRCPY(code, "NFA_CLASS_ALNUM"); break;
+ case NFA_CLASS_ALPHA: STRCPY(code, "NFA_CLASS_ALPHA"); break;
+ case NFA_CLASS_BLANK: STRCPY(code, "NFA_CLASS_BLANK"); break;
+ case NFA_CLASS_CNTRL: STRCPY(code, "NFA_CLASS_CNTRL"); break;
+ case NFA_CLASS_DIGIT: STRCPY(code, "NFA_CLASS_DIGIT"); break;
+ case NFA_CLASS_GRAPH: STRCPY(code, "NFA_CLASS_GRAPH"); break;
+ case NFA_CLASS_LOWER: STRCPY(code, "NFA_CLASS_LOWER"); break;
+ case NFA_CLASS_PRINT: STRCPY(code, "NFA_CLASS_PRINT"); break;
+ case NFA_CLASS_PUNCT: STRCPY(code, "NFA_CLASS_PUNCT"); break;
+ case NFA_CLASS_SPACE: STRCPY(code, "NFA_CLASS_SPACE"); break;
+ case NFA_CLASS_UPPER: STRCPY(code, "NFA_CLASS_UPPER"); break;
+ case NFA_CLASS_XDIGIT: STRCPY(code, "NFA_CLASS_XDIGIT"); break;
+ case NFA_CLASS_TAB: STRCPY(code, "NFA_CLASS_TAB"); break;
+ case NFA_CLASS_RETURN: STRCPY(code, "NFA_CLASS_RETURN"); break;
+ case NFA_CLASS_BACKSPACE: STRCPY(code, "NFA_CLASS_BACKSPACE"); break;
+ case NFA_CLASS_ESCAPE: STRCPY(code, "NFA_CLASS_ESCAPE"); break;
+
+ case NFA_ANY: STRCPY(code, "NFA_ANY"); break;
+ case NFA_IDENT: STRCPY(code, "NFA_IDENT"); break;
+ case NFA_SIDENT: STRCPY(code, "NFA_SIDENT"); break;
+ case NFA_KWORD: STRCPY(code, "NFA_KWORD"); break;
+ case NFA_SKWORD: STRCPY(code, "NFA_SKWORD"); break;
+ case NFA_FNAME: STRCPY(code, "NFA_FNAME"); break;
+ case NFA_SFNAME: STRCPY(code, "NFA_SFNAME"); break;
+ case NFA_PRINT: STRCPY(code, "NFA_PRINT"); break;
+ case NFA_SPRINT: STRCPY(code, "NFA_SPRINT"); break;
+ case NFA_WHITE: STRCPY(code, "NFA_WHITE"); break;
+ case NFA_NWHITE: STRCPY(code, "NFA_NWHITE"); break;
+ case NFA_DIGIT: STRCPY(code, "NFA_DIGIT"); break;
+ case NFA_NDIGIT: STRCPY(code, "NFA_NDIGIT"); break;
+ case NFA_HEX: STRCPY(code, "NFA_HEX"); break;
+ case NFA_NHEX: STRCPY(code, "NFA_NHEX"); break;
+ case NFA_OCTAL: STRCPY(code, "NFA_OCTAL"); break;
+ case NFA_NOCTAL: STRCPY(code, "NFA_NOCTAL"); break;
+ case NFA_WORD: STRCPY(code, "NFA_WORD"); break;
+ case NFA_NWORD: STRCPY(code, "NFA_NWORD"); break;
+ case NFA_HEAD: STRCPY(code, "NFA_HEAD"); break;
+ case NFA_NHEAD: STRCPY(code, "NFA_NHEAD"); break;
+ case NFA_ALPHA: STRCPY(code, "NFA_ALPHA"); break;
+ case NFA_NALPHA: STRCPY(code, "NFA_NALPHA"); break;
+ case NFA_LOWER: STRCPY(code, "NFA_LOWER"); break;
+ case NFA_NLOWER: STRCPY(code, "NFA_NLOWER"); break;
+ case NFA_UPPER: STRCPY(code, "NFA_UPPER"); break;
+ case NFA_NUPPER: STRCPY(code, "NFA_NUPPER"); break;
+ case NFA_LOWER_IC: STRCPY(code, "NFA_LOWER_IC"); break;
+ case NFA_NLOWER_IC: STRCPY(code, "NFA_NLOWER_IC"); break;
+ case NFA_UPPER_IC: STRCPY(code, "NFA_UPPER_IC"); break;
+ case NFA_NUPPER_IC: STRCPY(code, "NFA_NUPPER_IC"); break;
+
+ default:
+ STRCPY(code, "CHAR(x)");
+ code[5] = c;
+ }
+
+ if (addnl == TRUE)
+ STRCAT(code, " + NEWLINE ");
+
+}
+
+#ifdef ENABLE_LOG
+static FILE *log_fd;
+
+/*
+ * Print the postfix notation of the current regexp.
+ */
+static void nfa_postfix_dump(expr, retval)
+char_u *expr;
+int retval;
+{
+ int *p;
+ FILE *f;
+
+ 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)
+ 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);
+ fprintf(f, "%s, ", code);
+ }
+ fprintf(f, "\"\nPostfix notation (int): ");
+ for (p = post_start; *p && p < post_ptr; p++)
+ fprintf(f, "%d ", *p);
+ fprintf(f, "\n\n");
+ fclose(f);
+ }
+}
+
+/*
+ * Print the NFA starting with a root node "state".
+ */
+static void nfa_print_state(debugf, state)
+FILE *debugf;
+nfa_state_T *state;
+{
+ garray_T indent;
+
+ ga_init2(&indent, 1, 64);
+ ga_append(&indent, '\0');
+ nfa_print_state2(debugf, state, &indent);
+ ga_clear(&indent);
+}
+
+static void nfa_print_state2(debugf, state, indent)
+FILE *debugf;
+nfa_state_T *state;
+garray_T *indent;
+{
+ char_u *p;
+
+ if (state == NULL)
+ return;
+
+ fprintf(debugf, "(%2d)", abs(state->id));
+
+ /* Output indent */
+ p = (char_u *)indent->ga_data;
+ if (indent->ga_len >= 3) {
+ int last = indent->ga_len - 3;
+ char_u save[2];
+
+ STRNCPY(save, &p[last], 2);
+ STRNCPY(&p[last], "+-", 2);
+ fprintf(debugf, " %s", p);
+ STRNCPY(&p[last], save, 2);
+ } else
+ fprintf(debugf, " %s", p);
+
+ nfa_set_code(state->c);
+ fprintf(debugf, "%s (%d) (id=%d) val=%d\n",
+ code,
+ state->c,
+ abs(state->id),
+ state->val);
+ if (state->id < 0)
+ return;
+
+ state->id = abs(state->id) * -1;
+
+ /* grow indent for state->out */
+ indent->ga_len -= 1;
+ if (state->out1)
+ ga_concat(indent, (char_u *)"| ");
+ else
+ ga_concat(indent, (char_u *)" ");
+ ga_append(indent, '\0');
+
+ nfa_print_state2(debugf, state->out, indent);
+
+ /* replace last part of indent for state->out1 */
+ indent->ga_len -= 3;
+ ga_concat(indent, (char_u *)" ");
+ ga_append(indent, '\0');
+
+ nfa_print_state2(debugf, state->out1, indent);
+
+ /* shrink indent */
+ indent->ga_len -= 3;
+ ga_append(indent, '\0');
+}
+
+/*
+ * Print the NFA state machine.
+ */
+static void nfa_dump(prog)
+nfa_regprog_T *prog;
+{
+ FILE *debugf = fopen(NFA_REGEXP_DUMP_LOG, "a");
+
+ if (debugf != NULL) {
+ nfa_print_state(debugf, prog->start);
+
+ if (prog->reganch)
+ fprintf(debugf, "reganch: %d\n", prog->reganch);
+ if (prog->regstart != NUL)
+ fprintf(debugf, "regstart: %c (decimal: %d)\n",
+ prog->regstart, prog->regstart);
+ if (prog->match_text != NULL)
+ fprintf(debugf, "match_text: \"%s\"\n", prog->match_text);
+
+ fclose(debugf);
+ }
+}
+#endif /* ENABLE_LOG */
+#endif /* REGEXP_DEBUG */
+
+/*
+ * Parse r.e. @expr and convert it into postfix form.
+ * Return the postfix string on success, NULL otherwise.
+ */
+static int * re2post() {
+ if (nfa_reg(REG_NOPAREN) == FAIL)
+ return NULL;
+ EMIT(NFA_MOPEN);
+ return post_start;
+}
+
+/* NB. Some of the code below is inspired by Russ's. */
+
+/*
+ * Represents an NFA state plus zero or one or two arrows exiting.
+ * if c == MATCH, no arrows out; matching state.
+ * If c == SPLIT, unlabeled arrows to out and out1 (if != NULL).
+ * If c < 256, labeled arrow with character c to out.
+ */
+
+static nfa_state_T *state_ptr; /* points to nfa_prog->state */
+
+/*
+ * Allocate and initialize nfa_state_T.
+ */
+static nfa_state_T * alloc_state(c, out, out1)
+int c;
+nfa_state_T *out;
+nfa_state_T *out1;
+{
+ nfa_state_T *s;
+
+ if (istate >= nstate)
+ return NULL;
+
+ s = &state_ptr[istate++];
+
+ s->c = c;
+ s->out = out;
+ s->out1 = out1;
+ s->val = 0;
+
+ s->id = istate;
+ s->lastlist[0] = 0;
+ s->lastlist[1] = 0;
+
+ return s;
+}
+
+/*
+ * A partially built NFA without the matching state filled in.
+ * Frag_T.start points at the start state.
+ * Frag_T.out is a list of places that need to be set to the
+ * next state for this fragment.
+ */
+
+/* Since the out pointers in the list are always
+ * uninitialized, we use the pointers themselves
+ * as storage for the Ptrlists. */
+typedef union Ptrlist Ptrlist;
+union Ptrlist {
+ Ptrlist *next;
+ nfa_state_T *s;
+};
+
+struct Frag {
+ nfa_state_T *start;
+ Ptrlist *out;
+};
+typedef struct Frag Frag_T;
+
+static Frag_T frag __ARGS((nfa_state_T *start, Ptrlist *out));
+static Ptrlist *list1 __ARGS((nfa_state_T **outp));
+static void patch __ARGS((Ptrlist *l, nfa_state_T *s));
+static Ptrlist *append __ARGS((Ptrlist *l1, Ptrlist *l2));
+static void st_push __ARGS((Frag_T s, Frag_T **p, Frag_T *stack_end));
+static Frag_T st_pop __ARGS((Frag_T **p, Frag_T *stack));
+
+/*
+ * Initialize a Frag_T struct and return it.
+ */
+static Frag_T frag(start, out)
+nfa_state_T *start;
+Ptrlist *out;
+{
+ Frag_T n;
+
+ n.start = start;
+ n.out = out;
+ return n;
+}
+
+/*
+ * Create singleton list containing just outp.
+ */
+static Ptrlist * list1(outp)
+nfa_state_T **outp;
+{
+ Ptrlist *l;
+
+ l = (Ptrlist *)outp;
+ l->next = NULL;
+ return l;
+}
+
+/*
+ * Patch the list of states at out to point to start.
+ */
+static void patch(l, s)
+Ptrlist *l;
+nfa_state_T *s;
+{
+ Ptrlist *next;
+
+ for (; l; l = next) {
+ next = l->next;
+ l->s = s;
+ }
+}
+
+
+/*
+ * Join the two lists l1 and l2, returning the combination.
+ */
+static Ptrlist * append(l1, l2)
+Ptrlist *l1;
+Ptrlist *l2;
+{
+ Ptrlist *oldl1;
+
+ oldl1 = l1;
+ while (l1->next)
+ l1 = l1->next;
+ l1->next = l2;
+ return oldl1;
+}
+
+/*
+ * Stack used for transforming postfix form into NFA.
+ */
+static Frag_T empty;
+
+static void st_error(postfix, end, p)
+int *postfix UNUSED;
+int *end UNUSED;
+int *p UNUSED;
+{
+#ifdef NFA_REGEXP_ERROR_LOG
+ FILE *df;
+ int *p2;
+
+ df = fopen(NFA_REGEXP_ERROR_LOG, "a");
+ if (df) {
+ fprintf(df, "Error popping the stack!\n");
+#ifdef REGEXP_DEBUG
+ fprintf(df, "Current regexp is \"%s\"\n", nfa_regengine.expr);
+#endif
+ fprintf(df, "Postfix form is: ");
+#ifdef REGEXP_DEBUG
+ for (p2 = postfix; p2 < end; p2++) {
+ nfa_set_code(*p2);
+ fprintf(df, "%s, ", code);
+ }
+ nfa_set_code(*p);
+ fprintf(df, "\nCurrent position is: ");
+ for (p2 = postfix; p2 <= p; p2++) {
+ nfa_set_code(*p2);
+ fprintf(df, "%s, ", code);
+ }
+#else
+ for (p2 = postfix; p2 < end; p2++) {
+ fprintf(df, "%d, ", *p2);
+ }
+ fprintf(df, "\nCurrent position is: ");
+ for (p2 = postfix; p2 <= p; p2++) {
+ fprintf(df, "%d, ", *p2);
+ }
+#endif
+ fprintf(df, "\n--------------------------\n");
+ fclose(df);
+ }
+#endif
+ EMSG(_("E874: (NFA) Could not pop the stack !"));
+}
+
+/*
+ * Push an item onto the stack.
+ */
+static void st_push(s, p, stack_end)
+Frag_T s;
+Frag_T **p;
+Frag_T *stack_end;
+{
+ Frag_T *stackp = *p;
+
+ if (stackp >= stack_end)
+ return;
+ *stackp = s;
+ *p = *p + 1;
+}
+
+/*
+ * Pop an item from the stack.
+ */
+static Frag_T st_pop(p, stack)
+Frag_T **p;
+Frag_T *stack;
+{
+ Frag_T *stackp;
+
+ *p = *p - 1;
+ stackp = *p;
+ if (stackp < stack)
+ return empty;
+ return **p;
+}
+
+/*
+ * Estimate the maximum byte length of anything matching "state".
+ * When unknown or unlimited return -1.
+ */
+static int nfa_max_width(startstate, depth)
+nfa_state_T *startstate;
+int depth;
+{
+ int l, r;
+ nfa_state_T *state = startstate;
+ int len = 0;
+
+ /* detect looping in a NFA_SPLIT */
+ if (depth > 4)
+ return -1;
+
+ while (state != NULL) {
+ switch (state->c) {
+ case NFA_END_INVISIBLE:
+ case NFA_END_INVISIBLE_NEG:
+ /* the end, return what we have */
+ return len;
+
+ case NFA_SPLIT:
+ /* two alternatives, use the maximum */
+ l = nfa_max_width(state->out, depth + 1);
+ r = nfa_max_width(state->out1, depth + 1);
+ if (l < 0 || r < 0)
+ return -1;
+ return len + (l > r ? l : r);
+
+ 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;
+ if (state->c != NFA_ANY) {
+ /* skip over the characters */
+ state = state->out1->out;
+ continue;
+ }
+ break;
+
+ case NFA_DIGIT:
+ case NFA_WHITE:
+ case NFA_HEX:
+ case NFA_OCTAL:
+ /* ascii */
+ ++len;
+ break;
+
+ case NFA_IDENT:
+ case NFA_SIDENT:
+ case NFA_KWORD:
+ case NFA_SKWORD:
+ case NFA_FNAME:
+ case NFA_SFNAME:
+ case NFA_PRINT:
+ case NFA_SPRINT:
+ case NFA_NWHITE:
+ case NFA_NDIGIT:
+ case NFA_NHEX:
+ case NFA_NOCTAL:
+ case NFA_WORD:
+ case NFA_NWORD:
+ case NFA_HEAD:
+ case NFA_NHEAD:
+ case NFA_ALPHA:
+ case NFA_NALPHA:
+ case NFA_LOWER:
+ case NFA_NLOWER:
+ case NFA_UPPER:
+ case NFA_NUPPER:
+ case NFA_LOWER_IC:
+ case NFA_NLOWER_IC:
+ case NFA_UPPER_IC:
+ case NFA_NUPPER_IC:
+ /* possibly non-ascii */
+ if (has_mbyte)
+ len += 3;
+ else
+ ++len;
+ break;
+
+ case NFA_START_INVISIBLE:
+ case NFA_START_INVISIBLE_NEG:
+ case NFA_START_INVISIBLE_BEFORE:
+ case NFA_START_INVISIBLE_BEFORE_NEG:
+ /* zero-width, out1 points to the END state */
+ state = state->out1->out;
+ continue;
+
+ case NFA_BACKREF1:
+ case NFA_BACKREF2:
+ case NFA_BACKREF3:
+ case NFA_BACKREF4:
+ case NFA_BACKREF5:
+ case NFA_BACKREF6:
+ case NFA_BACKREF7:
+ case NFA_BACKREF8:
+ case NFA_BACKREF9:
+ case NFA_ZREF1:
+ case NFA_ZREF2:
+ case NFA_ZREF3:
+ case NFA_ZREF4:
+ case NFA_ZREF5:
+ case NFA_ZREF6:
+ case NFA_ZREF7:
+ case NFA_ZREF8:
+ case NFA_ZREF9:
+ case NFA_NEWL:
+ case NFA_SKIP:
+ /* unknown width */
+ return -1;
+
+ case NFA_BOL:
+ case NFA_EOL:
+ case NFA_BOF:
+ case NFA_EOF:
+ case NFA_BOW:
+ case NFA_EOW:
+ case NFA_MOPEN:
+ case NFA_MOPEN1:
+ case NFA_MOPEN2:
+ case NFA_MOPEN3:
+ case NFA_MOPEN4:
+ case NFA_MOPEN5:
+ case NFA_MOPEN6:
+ case NFA_MOPEN7:
+ case NFA_MOPEN8:
+ case NFA_MOPEN9:
+ case NFA_ZOPEN:
+ case NFA_ZOPEN1:
+ case NFA_ZOPEN2:
+ case NFA_ZOPEN3:
+ case NFA_ZOPEN4:
+ case NFA_ZOPEN5:
+ case NFA_ZOPEN6:
+ case NFA_ZOPEN7:
+ case NFA_ZOPEN8:
+ case NFA_ZOPEN9:
+ case NFA_ZCLOSE:
+ case NFA_ZCLOSE1:
+ case NFA_ZCLOSE2:
+ case NFA_ZCLOSE3:
+ case NFA_ZCLOSE4:
+ case NFA_ZCLOSE5:
+ case NFA_ZCLOSE6:
+ case NFA_ZCLOSE7:
+ case NFA_ZCLOSE8:
+ case NFA_ZCLOSE9:
+ case NFA_MCLOSE:
+ case NFA_MCLOSE1:
+ case NFA_MCLOSE2:
+ case NFA_MCLOSE3:
+ case NFA_MCLOSE4:
+ case NFA_MCLOSE5:
+ case NFA_MCLOSE6:
+ case NFA_MCLOSE7:
+ case NFA_MCLOSE8:
+ case NFA_MCLOSE9:
+ case NFA_NOPEN:
+ case NFA_NCLOSE:
+
+ case NFA_LNUM_GT:
+ case NFA_LNUM_LT:
+ case NFA_COL_GT:
+ case NFA_COL_LT:
+ case NFA_VCOL_GT:
+ case NFA_VCOL_LT:
+ case NFA_MARK_GT:
+ case NFA_MARK_LT:
+ case NFA_VISUAL:
+ case NFA_LNUM:
+ case NFA_CURSOR:
+ case NFA_COL:
+ case NFA_VCOL:
+ case NFA_MARK:
+
+ case NFA_ZSTART:
+ case NFA_ZEND:
+ case NFA_OPT_CHARS:
+ case NFA_EMPTY:
+ case NFA_START_PATTERN:
+ case NFA_END_PATTERN:
+ case NFA_COMPOSING:
+ case NFA_END_COMPOSING:
+ /* zero-width */
+ break;
+
+ default:
+ if (state->c < 0)
+ /* don't know what this is */
+ return -1;
+ /* normal character */
+ len += MB_CHAR2LEN(state->c);
+ break;
+ }
+
+ /* normal way to continue */
+ state = state->out;
+ }
+
+ /* unrecognized, "cannot happen" */
+ return -1;
+}
+
+/*
+ * Convert a postfix form into its equivalent NFA.
+ * Return the NFA start state on success, NULL otherwise.
+ */
+static nfa_state_T * post2nfa(postfix, end, nfa_calc_size)
+int *postfix;
+int *end;
+int nfa_calc_size;
+{
+ int *p;
+ int mopen;
+ int mclose;
+ Frag_T *stack = NULL;
+ Frag_T *stackp = NULL;
+ Frag_T *stack_end = NULL;
+ Frag_T e1;
+ Frag_T e2;
+ Frag_T e;
+ nfa_state_T *s;
+ nfa_state_T *s1;
+ nfa_state_T *matchstate;
+ nfa_state_T *ret = NULL;
+
+ if (postfix == NULL)
+ return NULL;
+
+#define PUSH(s) st_push((s), &stackp, stack_end)
+#define POP() st_pop(&stackp, stack); \
+ if (stackp < stack) \
+ { \
+ st_error(postfix, end, p); \
+ return NULL; \
+ }
+
+ if (nfa_calc_size == FALSE) {
+ /* Allocate space for the stack. Max states on the stack : nstate */
+ stack = (Frag_T *)lalloc((nstate + 1) * sizeof(Frag_T), TRUE);
+ stackp = stack;
+ stack_end = stack + (nstate + 1);
+ }
+
+ for (p = postfix; p < end; ++p) {
+ switch (*p) {
+ case NFA_CONCAT:
+ /* Concatenation.
+ * Pay attention: this operator does not exist in the r.e. itself
+ * (it is implicit, really). It is added when r.e. is translated
+ * to postfix form in re2post(). */
+ if (nfa_calc_size == TRUE) {
+ /* nstate += 0; */
+ break;
+ }
+ e2 = POP();
+ e1 = POP();
+ patch(e1.out, e2.start);
+ PUSH(frag(e1.start, e2.out));
+ break;
+
+ case NFA_OR:
+ /* Alternation */
+ if (nfa_calc_size == TRUE) {
+ nstate++;
+ break;
+ }
+ e2 = POP();
+ e1 = POP();
+ s = alloc_state(NFA_SPLIT, e1.start, e2.start);
+ if (s == NULL)
+ goto theend;
+ PUSH(frag(s, append(e1.out, e2.out)));
+ break;
+
+ case NFA_STAR:
+ /* Zero or more, prefer more */
+ if (nfa_calc_size == TRUE) {
+ nstate++;
+ break;
+ }
+ e = POP();
+ s = alloc_state(NFA_SPLIT, e.start, NULL);
+ if (s == NULL)
+ goto theend;
+ patch(e.out, s);
+ PUSH(frag(s, list1(&s->out1)));
+ break;
+
+ case NFA_STAR_NONGREEDY:
+ /* Zero or more, prefer zero */
+ if (nfa_calc_size == TRUE) {
+ nstate++;
+ break;
+ }
+ e = POP();
+ s = alloc_state(NFA_SPLIT, NULL, e.start);
+ if (s == NULL)
+ goto theend;
+ patch(e.out, s);
+ PUSH(frag(s, list1(&s->out)));
+ break;
+
+ case NFA_QUEST:
+ /* one or zero atoms=> greedy match */
+ if (nfa_calc_size == TRUE) {
+ nstate++;
+ break;
+ }
+ e = POP();
+ s = alloc_state(NFA_SPLIT, e.start, NULL);
+ if (s == NULL)
+ goto theend;
+ PUSH(frag(s, append(e.out, list1(&s->out1))));
+ break;
+
+ case NFA_QUEST_NONGREEDY:
+ /* zero or one atoms => non-greedy match */
+ if (nfa_calc_size == TRUE) {
+ nstate++;
+ break;
+ }
+ e = POP();
+ s = alloc_state(NFA_SPLIT, NULL, e.start);
+ if (s == NULL)
+ goto theend;
+ PUSH(frag(s, append(e.out, list1(&s->out))));
+ break;
+
+ case NFA_END_COLL:
+ case NFA_END_NEG_COLL:
+ /* On the stack is the sequence starting with NFA_START_COLL or
+ * NFA_START_NEG_COLL and all possible characters. Patch it to
+ * add the output to the start. */
+ if (nfa_calc_size == TRUE) {
+ nstate++;
+ break;
+ }
+ e = POP();
+ s = alloc_state(NFA_END_COLL, NULL, NULL);
+ if (s == NULL)
+ goto theend;
+ patch(e.out, s);
+ e.start->out1 = s;
+ PUSH(frag(e.start, list1(&s->out)));
+ break;
+
+ case NFA_RANGE:
+ /* Before this are two characters, the low and high end of a
+ * range. Turn them into two states with MIN and MAX. */
+ if (nfa_calc_size == TRUE) {
+ /* nstate += 0; */
+ break;
+ }
+ e2 = POP();
+ e1 = POP();
+ e2.start->val = e2.start->c;
+ e2.start->c = NFA_RANGE_MAX;
+ e1.start->val = e1.start->c;
+ e1.start->c = NFA_RANGE_MIN;
+ patch(e1.out, e2.start);
+ PUSH(frag(e1.start, e2.out));
+ break;
+
+ case NFA_EMPTY:
+ /* 0-length, used in a repetition with max/min count of 0 */
+ if (nfa_calc_size == TRUE) {
+ nstate++;
+ break;
+ }
+ s = alloc_state(NFA_EMPTY, NULL, NULL);
+ if (s == NULL)
+ goto theend;
+ PUSH(frag(s, list1(&s->out)));
+ break;
+
+ case NFA_OPT_CHARS:
+ {
+ int n;
+
+ /* \%[abc] implemented as:
+ * NFA_SPLIT
+ * +-CHAR(a)
+ * | +-NFA_SPLIT
+ * | +-CHAR(b)
+ * | | +-NFA_SPLIT
+ * | | +-CHAR(c)
+ * | | | +-next
+ * | | +- next
+ * | +- next
+ * +- next
+ */
+ n = *++p; /* get number of characters */
+ if (nfa_calc_size == TRUE) {
+ nstate += n;
+ break;
+ }
+ s = NULL; /* avoid compiler warning */
+ e1.out = NULL; /* stores list with out1's */
+ s1 = NULL; /* previous NFA_SPLIT to connect to */
+ while (n-- > 0) {
+ e = POP(); /* get character */
+ s = alloc_state(NFA_SPLIT, e.start, NULL);
+ if (s == NULL)
+ goto theend;
+ if (e1.out == NULL)
+ e1 = e;
+ patch(e.out, s1);
+ append(e1.out, list1(&s->out1));
+ s1 = s;
+ }
+ PUSH(frag(s, e1.out));
+ break;
+ }
+
+ case NFA_PREV_ATOM_NO_WIDTH:
+ case NFA_PREV_ATOM_NO_WIDTH_NEG:
+ case NFA_PREV_ATOM_JUST_BEFORE:
+ case NFA_PREV_ATOM_JUST_BEFORE_NEG:
+ case NFA_PREV_ATOM_LIKE_PATTERN:
+ {
+ int before = (*p == NFA_PREV_ATOM_JUST_BEFORE
+ || *p == NFA_PREV_ATOM_JUST_BEFORE_NEG);
+ int pattern = (*p == NFA_PREV_ATOM_LIKE_PATTERN);
+ int start_state;
+ int end_state;
+ int n = 0;
+ nfa_state_T *zend;
+ nfa_state_T *skip;
+
+ switch (*p) {
+ case NFA_PREV_ATOM_NO_WIDTH:
+ start_state = NFA_START_INVISIBLE;
+ end_state = NFA_END_INVISIBLE;
+ break;
+ case NFA_PREV_ATOM_NO_WIDTH_NEG:
+ start_state = NFA_START_INVISIBLE_NEG;
+ end_state = NFA_END_INVISIBLE_NEG;
+ break;
+ case NFA_PREV_ATOM_JUST_BEFORE:
+ start_state = NFA_START_INVISIBLE_BEFORE;
+ end_state = NFA_END_INVISIBLE;
+ break;
+ case NFA_PREV_ATOM_JUST_BEFORE_NEG:
+ start_state = NFA_START_INVISIBLE_BEFORE_NEG;
+ end_state = NFA_END_INVISIBLE_NEG;
+ break;
+ default: /* NFA_PREV_ATOM_LIKE_PATTERN: */
+ start_state = NFA_START_PATTERN;
+ end_state = NFA_END_PATTERN;
+ break;
+ }
+
+ if (before)
+ n = *++p; /* get the count */
+
+ /* The \@= operator: match the preceding atom with zero width.
+ * The \@! operator: no match for the preceding atom.
+ * The \@<= operator: match for the preceding atom.
+ * The \@<! operator: no match for the preceding atom.
+ * Surrounds the preceding atom with START_INVISIBLE and
+ * END_INVISIBLE, similarly to MOPEN. */
+
+ if (nfa_calc_size == TRUE) {
+ nstate += pattern ? 4 : 2;
+ break;
+ }
+ e = POP();
+ s1 = alloc_state(end_state, NULL, NULL);
+ if (s1 == NULL)
+ goto theend;
+
+ s = alloc_state(start_state, e.start, s1);
+ if (s == NULL)
+ goto theend;
+ if (pattern) {
+ /* NFA_ZEND -> NFA_END_PATTERN -> NFA_SKIP -> what follows. */
+ skip = alloc_state(NFA_SKIP, NULL, NULL);
+ zend = alloc_state(NFA_ZEND, s1, NULL);
+ s1->out= skip;
+ patch(e.out, zend);
+ PUSH(frag(s, list1(&skip->out)));
+ } else {
+ patch(e.out, s1);
+ PUSH(frag(s, list1(&s1->out)));
+ if (before) {
+ if (n <= 0)
+ /* See if we can guess the maximum width, it avoids a
+ * lot of pointless tries. */
+ n = nfa_max_width(e.start, 0);
+ s->val = n; /* store the count */
+ }
+ }
+ break;
+ }
+
+ case NFA_COMPOSING: /* char with composing char */
+ /* FALLTHROUGH */
+
+ case NFA_MOPEN: /* \( \) Submatch */
+ case NFA_MOPEN1:
+ case NFA_MOPEN2:
+ case NFA_MOPEN3:
+ case NFA_MOPEN4:
+ case NFA_MOPEN5:
+ case NFA_MOPEN6:
+ case NFA_MOPEN7:
+ case NFA_MOPEN8:
+ case NFA_MOPEN9:
+ case NFA_ZOPEN: /* \z( \) Submatch */
+ case NFA_ZOPEN1:
+ case NFA_ZOPEN2:
+ case NFA_ZOPEN3:
+ case NFA_ZOPEN4:
+ case NFA_ZOPEN5:
+ case NFA_ZOPEN6:
+ case NFA_ZOPEN7:
+ case NFA_ZOPEN8:
+ case NFA_ZOPEN9:
+ case NFA_NOPEN: /* \%( \) "Invisible Submatch" */
+ if (nfa_calc_size == TRUE) {
+ nstate += 2;
+ break;
+ }
+
+ mopen = *p;
+ switch (*p) {
+ case NFA_NOPEN: mclose = NFA_NCLOSE; break;
+ case NFA_ZOPEN: mclose = NFA_ZCLOSE; break;
+ case NFA_ZOPEN1: mclose = NFA_ZCLOSE1; break;
+ case NFA_ZOPEN2: mclose = NFA_ZCLOSE2; break;
+ case NFA_ZOPEN3: mclose = NFA_ZCLOSE3; break;
+ case NFA_ZOPEN4: mclose = NFA_ZCLOSE4; break;
+ case NFA_ZOPEN5: mclose = NFA_ZCLOSE5; break;
+ case NFA_ZOPEN6: mclose = NFA_ZCLOSE6; break;
+ case NFA_ZOPEN7: mclose = NFA_ZCLOSE7; break;
+ case NFA_ZOPEN8: mclose = NFA_ZCLOSE8; break;
+ case NFA_ZOPEN9: mclose = NFA_ZCLOSE9; break;
+ case NFA_COMPOSING: mclose = NFA_END_COMPOSING; break;
+ default:
+ /* NFA_MOPEN, NFA_MOPEN1 .. NFA_MOPEN9 */
+ mclose = *p + NSUBEXP;
+ break;
+ }
+
+ /* Allow "NFA_MOPEN" as a valid postfix representation for
+ * the empty regexp "". In this case, the NFA will be
+ * NFA_MOPEN -> NFA_MCLOSE. Note that this also allows
+ * empty groups of parenthesis, and empty mbyte chars */
+ if (stackp == stack) {
+ s = alloc_state(mopen, NULL, NULL);
+ if (s == NULL)
+ goto theend;
+ s1 = alloc_state(mclose, NULL, NULL);
+ if (s1 == NULL)
+ goto theend;
+ patch(list1(&s->out), s1);
+ PUSH(frag(s, list1(&s1->out)));
+ break;
+ }
+
+ /* At least one node was emitted before NFA_MOPEN, so
+ * at least one node will be between NFA_MOPEN and NFA_MCLOSE */
+ e = POP();
+ s = alloc_state(mopen, e.start, NULL); /* `(' */
+ if (s == NULL)
+ goto theend;
+
+ s1 = alloc_state(mclose, NULL, NULL); /* `)' */
+ if (s1 == NULL)
+ goto theend;
+ patch(e.out, s1);
+
+ if (mopen == NFA_COMPOSING)
+ /* COMPOSING->out1 = END_COMPOSING */
+ patch(list1(&s->out1), s1);
+
+ PUSH(frag(s, list1(&s1->out)));
+ break;
+
+ case NFA_BACKREF1:
+ case NFA_BACKREF2:
+ case NFA_BACKREF3:
+ case NFA_BACKREF4:
+ case NFA_BACKREF5:
+ case NFA_BACKREF6:
+ case NFA_BACKREF7:
+ case NFA_BACKREF8:
+ case NFA_BACKREF9:
+ case NFA_ZREF1:
+ case NFA_ZREF2:
+ case NFA_ZREF3:
+ case NFA_ZREF4:
+ case NFA_ZREF5:
+ case NFA_ZREF6:
+ case NFA_ZREF7:
+ case NFA_ZREF8:
+ case NFA_ZREF9:
+ if (nfa_calc_size == TRUE) {
+ nstate += 2;
+ break;
+ }
+ s = alloc_state(*p, NULL, NULL);
+ if (s == NULL)
+ goto theend;
+ s1 = alloc_state(NFA_SKIP, NULL, NULL);
+ if (s1 == NULL)
+ goto theend;
+ patch(list1(&s->out), s1);
+ PUSH(frag(s, list1(&s1->out)));
+ break;
+
+ case NFA_LNUM:
+ case NFA_LNUM_GT:
+ case NFA_LNUM_LT:
+ case NFA_VCOL:
+ case NFA_VCOL_GT:
+ case NFA_VCOL_LT:
+ case NFA_COL:
+ case NFA_COL_GT:
+ case NFA_COL_LT:
+ case NFA_MARK:
+ case NFA_MARK_GT:
+ case NFA_MARK_LT:
+ {
+ int n = *++p; /* lnum, col or mark name */
+
+ if (nfa_calc_size == TRUE) {
+ nstate += 1;
+ break;
+ }
+ s = alloc_state(p[-1], NULL, NULL);
+ if (s == NULL)
+ goto theend;
+ s->val = n;
+ PUSH(frag(s, list1(&s->out)));
+ break;
+ }
+
+ case NFA_ZSTART:
+ case NFA_ZEND:
+ default:
+ /* Operands */
+ if (nfa_calc_size == TRUE) {
+ nstate++;
+ break;
+ }
+ s = alloc_state(*p, NULL, NULL);
+ if (s == NULL)
+ goto theend;
+ PUSH(frag(s, list1(&s->out)));
+ break;
+
+ } /* switch(*p) */
+
+ } /* for(p = postfix; *p; ++p) */
+
+ if (nfa_calc_size == TRUE) {
+ nstate++;
+ goto theend; /* Return value when counting size is ignored anyway */
+ }
+
+ e = POP();
+ if (stackp != stack)
+ EMSG_RET_NULL(_(
+ "E875: (NFA regexp) (While converting from postfix to NFA), too many states left on stack"));
+
+ if (istate >= nstate)
+ EMSG_RET_NULL(_(
+ "E876: (NFA regexp) Not enough space to store the whole NFA "));
+
+ matchstate = &state_ptr[istate++]; /* the match state */
+ matchstate->c = NFA_MATCH;
+ matchstate->out = matchstate->out1 = NULL;
+ matchstate->id = 0;
+
+ patch(e.out, matchstate);
+ ret = e.start;
+
+theend:
+ vim_free(stack);
+ return ret;
+
+#undef POP1
+#undef PUSH1
+#undef POP2
+#undef PUSH2
+#undef POP
+#undef PUSH
+}
+
+/*
+ * After building the NFA program, inspect it to add optimization hints.
+ */
+static void nfa_postprocess(prog)
+nfa_regprog_T *prog;
+{
+ int i;
+ int c;
+
+ for (i = 0; i < prog->nstate; ++i) {
+ c = prog->state[i].c;
+ if (c == NFA_START_INVISIBLE
+ || c == NFA_START_INVISIBLE_NEG
+ || c == NFA_START_INVISIBLE_BEFORE
+ || c == NFA_START_INVISIBLE_BEFORE_NEG) {
+ int directly;
+
+ /* Do it directly when what follows is possibly the end of the
+ * match. */
+ if (match_follows(prog->state[i].out1->out, 0))
+ directly = TRUE;
+ else {
+ int ch_invisible = failure_chance(prog->state[i].out, 0);
+ int ch_follows = failure_chance(prog->state[i].out1->out, 0);
+
+ /* Postpone when the invisible match is expensive or has a
+ * lower chance of failing. */
+ if (c == NFA_START_INVISIBLE_BEFORE
+ || c == NFA_START_INVISIBLE_BEFORE_NEG) {
+ /* "before" matches are very expensive when
+ * unbounded, always prefer what follows then,
+ * unless what follows will always match.
+ * Otherwise strongly prefer what follows. */
+ if (prog->state[i].val <= 0 && ch_follows > 0)
+ directly = FALSE;
+ else
+ directly = ch_follows * 10 < ch_invisible;
+ } else {
+ /* normal invisible, first do the one with the
+ * highest failure chance */
+ directly = ch_follows < ch_invisible;
+ }
+ }
+ if (directly)
+ /* switch to the _FIRST state */
+ ++prog->state[i].c;
+ }
+ }
+}
+
+/****************************************************************
+* NFA execution code.
+****************************************************************/
+
+typedef struct {
+ int in_use; /* number of subexpr with useful info */
+
+ /* When REG_MULTI is TRUE list.multi is used, otherwise list.line. */
+ union {
+ struct multipos {
+ lpos_T start;
+ lpos_T end;
+ } multi[NSUBEXP];
+ struct linepos {
+ char_u *start;
+ char_u *end;
+ } line[NSUBEXP];
+ } list;
+} regsub_T;
+
+typedef struct {
+ regsub_T norm; /* \( .. \) matches */
+ regsub_T synt; /* \z( .. \) matches */
+} regsubs_T;
+
+/* nfa_pim_T stores a Postponed Invisible Match. */
+typedef struct nfa_pim_S nfa_pim_T;
+struct nfa_pim_S {
+ int result; /* NFA_PIM_*, see below */
+ nfa_state_T *state; /* the invisible match start state */
+ regsubs_T subs; /* submatch info, only party used */
+ union {
+ lpos_T pos;
+ char_u *ptr;
+ } end; /* where the match must end */
+};
+
+/* Values for done in nfa_pim_T. */
+#define NFA_PIM_UNUSED 0 /* pim not used */
+#define NFA_PIM_TODO 1 /* pim not done yet */
+#define NFA_PIM_MATCH 2 /* pim executed, matches */
+#define NFA_PIM_NOMATCH 3 /* pim executed, no match */
+
+
+/* nfa_thread_T contains execution information of a NFA state */
+typedef struct {
+ nfa_state_T *state;
+ int count;
+ nfa_pim_T pim; /* if pim.result != NFA_PIM_UNUSED: postponed
+ * invisible match */
+ regsubs_T subs; /* submatch info, only party used */
+} nfa_thread_T;
+
+/* nfa_list_T contains the alternative NFA execution states. */
+typedef struct {
+ nfa_thread_T *t; /* allocated array of states */
+ int n; /* nr of states currently in "t" */
+ int len; /* max nr of states in "t" */
+ int id; /* ID of the list */
+ int has_pim; /* TRUE when any state has a PIM */
+} nfa_list_T;
+
+#ifdef ENABLE_LOG
+static void log_subsexpr __ARGS((regsubs_T *subs));
+static void log_subexpr __ARGS((regsub_T *sub));
+static char *pim_info __ARGS((nfa_pim_T *pim));
+
+static void log_subsexpr(subs)
+regsubs_T *subs;
+{
+ log_subexpr(&subs->norm);
+ if (nfa_has_zsubexpr)
+ log_subexpr(&subs->synt);
+}
+
+static void log_subexpr(sub)
+regsub_T *sub;
+{
+ int j;
+
+ for (j = 0; j < sub->in_use; j++)
+ if (REG_MULTI)
+ fprintf(log_fd, "*** group %d, start: c=%d, l=%d, end: c=%d, l=%d\n",
+ j,
+ sub->list.multi[j].start.col,
+ (int)sub->list.multi[j].start.lnum,
+ sub->list.multi[j].end.col,
+ (int)sub->list.multi[j].end.lnum);
+ else {
+ char *s = (char *)sub->list.line[j].start;
+ char *e = (char *)sub->list.line[j].end;
+
+ fprintf(log_fd, "*** group %d, start: \"%s\", end: \"%s\"\n",
+ j,
+ s == NULL ? "NULL" : s,
+ e == NULL ? "NULL" : e);
+ }
+}
+
+static char * pim_info(pim)
+nfa_pim_T *pim;
+{
+ static char buf[30];
+
+ if (pim == NULL || pim->result == NFA_PIM_UNUSED)
+ buf[0] = NUL;
+ else {
+ sprintf(buf, " PIM col %d", REG_MULTI ? (int)pim->end.pos.col
+ : (int)(pim->end.ptr - reginput));
+ }
+ return buf;
+}
+
+#endif
+
+/* Used during execution: whether a match has been found. */
+static int nfa_match;
+
+static void copy_pim __ARGS((nfa_pim_T *to, nfa_pim_T *from));
+static void clear_sub __ARGS((regsub_T *sub));
+static void copy_sub __ARGS((regsub_T *to, regsub_T *from));
+static void copy_sub_off __ARGS((regsub_T *to, regsub_T *from));
+static void copy_ze_off __ARGS((regsub_T *to, regsub_T *from));
+static int sub_equal __ARGS((regsub_T *sub1, regsub_T *sub2));
+static int match_backref __ARGS((regsub_T *sub, int subidx, int *bytelen));
+static int has_state_with_pos __ARGS((nfa_list_T *l, nfa_state_T *state,
+ regsubs_T *subs,
+ nfa_pim_T *pim));
+static int pim_equal __ARGS((nfa_pim_T *one, nfa_pim_T *two));
+static int state_in_list __ARGS((nfa_list_T *l, nfa_state_T *state,
+ regsubs_T *subs));
+static regsubs_T *addstate __ARGS((nfa_list_T *l, nfa_state_T *state,
+ regsubs_T *subs_arg, nfa_pim_T *pim,
+ int off));
+static void addstate_here __ARGS((nfa_list_T *l, nfa_state_T *state,
+ regsubs_T *subs, nfa_pim_T *pim,
+ int *ip));
+
+/*
+ * Copy postponed invisible match info from "from" to "to".
+ */
+static void copy_pim(to, from)
+nfa_pim_T *to;
+nfa_pim_T *from;
+{
+ to->result = from->result;
+ to->state = from->state;
+ copy_sub(&to->subs.norm, &from->subs.norm);
+ if (nfa_has_zsubexpr)
+ copy_sub(&to->subs.synt, &from->subs.synt);
+ to->end = from->end;
+}
+
+static void clear_sub(sub)
+regsub_T *sub;
+{
+ if (REG_MULTI)
+ /* Use 0xff to set lnum to -1 */
+ vim_memset(sub->list.multi, 0xff,
+ sizeof(struct multipos) * nfa_nsubexpr);
+ else
+ vim_memset(sub->list.line, 0, sizeof(struct linepos) * nfa_nsubexpr);
+ sub->in_use = 0;
+}
+
+/*
+ * Copy the submatches from "from" to "to".
+ */
+static void copy_sub(to, from)
+regsub_T *to;
+regsub_T *from;
+{
+ to->in_use = from->in_use;
+ if (from->in_use > 0) {
+ /* Copy the match start and end positions. */
+ if (REG_MULTI)
+ mch_memmove(&to->list.multi[0],
+ &from->list.multi[0],
+ sizeof(struct multipos) * from->in_use);
+ else
+ mch_memmove(&to->list.line[0],
+ &from->list.line[0],
+ sizeof(struct linepos) * from->in_use);
+ }
+}
+
+/*
+ * Like copy_sub() but exclude the main match.
+ */
+static void copy_sub_off(to, from)
+regsub_T *to;
+regsub_T *from;
+{
+ if (to->in_use < from->in_use)
+ to->in_use = from->in_use;
+ if (from->in_use > 1) {
+ /* Copy the match start and end positions. */
+ if (REG_MULTI)
+ mch_memmove(&to->list.multi[1],
+ &from->list.multi[1],
+ sizeof(struct multipos) * (from->in_use - 1));
+ else
+ mch_memmove(&to->list.line[1],
+ &from->list.line[1],
+ sizeof(struct linepos) * (from->in_use - 1));
+ }
+}
+
+/*
+ * Like copy_sub() but only do the end of the main match if \ze is present.
+ */
+static void copy_ze_off(to, from)
+regsub_T *to;
+regsub_T *from;
+{
+ if (nfa_has_zend) {
+ if (REG_MULTI) {
+ if (from->list.multi[0].end.lnum >= 0)
+ to->list.multi[0].end = from->list.multi[0].end;
+ } else {
+ if (from->list.line[0].end != NULL)
+ to->list.line[0].end = from->list.line[0].end;
+ }
+ }
+}
+
+/*
+ * Return TRUE if "sub1" and "sub2" have the same start positions.
+ */
+static int sub_equal(sub1, sub2)
+regsub_T *sub1;
+regsub_T *sub2;
+{
+ int i;
+ int todo;
+ linenr_T s1;
+ linenr_T s2;
+ char_u *sp1;
+ char_u *sp2;
+
+ todo = sub1->in_use > sub2->in_use ? sub1->in_use : sub2->in_use;
+ if (REG_MULTI) {
+ for (i = 0; i < todo; ++i) {
+ if (i < sub1->in_use)
+ s1 = sub1->list.multi[i].start.lnum;
+ else
+ s1 = -1;
+ if (i < sub2->in_use)
+ s2 = sub2->list.multi[i].start.lnum;
+ else
+ s2 = -1;
+ if (s1 != s2)
+ return FALSE;
+ if (s1 != -1 && sub1->list.multi[i].start.col
+ != sub2->list.multi[i].start.col)
+ return FALSE;
+ }
+ } else {
+ for (i = 0; i < todo; ++i) {
+ if (i < sub1->in_use)
+ sp1 = sub1->list.line[i].start;
+ else
+ sp1 = NULL;
+ if (i < sub2->in_use)
+ sp2 = sub2->list.line[i].start;
+ else
+ sp2 = NULL;
+ if (sp1 != sp2)
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+#ifdef ENABLE_LOG
+static void report_state(char *action,
+ regsub_T *sub,
+ nfa_state_T *state,
+ int lid,
+ nfa_pim_T *pim) {
+ int col;
+
+ if (sub->in_use <= 0)
+ col = -1;
+ else if (REG_MULTI)
+ col = sub->list.multi[0].start.col;
+ else
+ col = (int)(sub->list.line[0].start - regline);
+ nfa_set_code(state->c);
+ fprintf(log_fd, "> %s state %d to list %d. char %d: %s (start col %d)%s\n",
+ action, abs(state->id), lid, state->c, code, col,
+ pim_info(pim));
+}
+
+#endif
+
+/*
+ * Return TRUE if the same state is already in list "l" with the same
+ * positions as "subs".
+ */
+static int has_state_with_pos(l, state, subs, pim)
+nfa_list_T *l; /* runtime state list */
+nfa_state_T *state; /* state to update */
+regsubs_T *subs; /* pointers to subexpressions */
+nfa_pim_T *pim; /* postponed match or NULL */
+{
+ nfa_thread_T *thread;
+ int i;
+
+ for (i = 0; i < l->n; ++i) {
+ thread = &l->t[i];
+ if (thread->state->id == state->id
+ && sub_equal(&thread->subs.norm, &subs->norm)
+ && (!nfa_has_zsubexpr
+ || sub_equal(&thread->subs.synt, &subs->synt))
+ && pim_equal(&thread->pim, pim))
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*
+ * Return TRUE if "one" and "two" are equal. That includes when both are not
+ * set.
+ */
+static int pim_equal(one, two)
+nfa_pim_T *one;
+nfa_pim_T *two;
+{
+ int one_unused = (one == NULL || one->result == NFA_PIM_UNUSED);
+ int two_unused = (two == NULL || two->result == NFA_PIM_UNUSED);
+
+ if (one_unused)
+ /* one is unused: equal when two is also unused */
+ return two_unused;
+ if (two_unused)
+ /* one is used and two is not: not equal */
+ return FALSE;
+ /* compare the state id */
+ if (one->state->id != two->state->id)
+ return FALSE;
+ /* compare the position */
+ if (REG_MULTI)
+ return one->end.pos.lnum == two->end.pos.lnum
+ && one->end.pos.col == two->end.pos.col;
+ return one->end.ptr == two->end.ptr;
+}
+
+/*
+ * Return TRUE if "state" leads to a NFA_MATCH without advancing the input.
+ */
+static int match_follows(startstate, depth)
+nfa_state_T *startstate;
+int depth;
+{
+ nfa_state_T *state = startstate;
+
+ /* avoid too much recursion */
+ if (depth > 10)
+ return FALSE;
+
+ while (state != NULL) {
+ switch (state->c) {
+ case NFA_MATCH:
+ case NFA_MCLOSE:
+ case NFA_END_INVISIBLE:
+ case NFA_END_INVISIBLE_NEG:
+ case NFA_END_PATTERN:
+ return TRUE;
+
+ case NFA_SPLIT:
+ return match_follows(state->out, depth + 1)
+ || match_follows(state->out1, depth + 1);
+
+ case NFA_START_INVISIBLE:
+ case NFA_START_INVISIBLE_FIRST:
+ case NFA_START_INVISIBLE_BEFORE:
+ case NFA_START_INVISIBLE_BEFORE_FIRST:
+ case NFA_START_INVISIBLE_NEG:
+ case NFA_START_INVISIBLE_NEG_FIRST:
+ case NFA_START_INVISIBLE_BEFORE_NEG:
+ case NFA_START_INVISIBLE_BEFORE_NEG_FIRST:
+ case NFA_COMPOSING:
+ /* skip ahead to next state */
+ state = state->out1->out;
+ continue;
+
+ case NFA_ANY:
+ case NFA_IDENT:
+ case NFA_SIDENT:
+ case NFA_KWORD:
+ case NFA_SKWORD:
+ case NFA_FNAME:
+ case NFA_SFNAME:
+ case NFA_PRINT:
+ case NFA_SPRINT:
+ case NFA_WHITE:
+ case NFA_NWHITE:
+ case NFA_DIGIT:
+ case NFA_NDIGIT:
+ case NFA_HEX:
+ case NFA_NHEX:
+ case NFA_OCTAL:
+ case NFA_NOCTAL:
+ case NFA_WORD:
+ case NFA_NWORD:
+ case NFA_HEAD:
+ case NFA_NHEAD:
+ case NFA_ALPHA:
+ case NFA_NALPHA:
+ case NFA_LOWER:
+ case NFA_NLOWER:
+ case NFA_UPPER:
+ case NFA_NUPPER:
+ case NFA_LOWER_IC:
+ case NFA_NLOWER_IC:
+ case NFA_UPPER_IC:
+ case NFA_NUPPER_IC:
+ case NFA_START_COLL:
+ case NFA_START_NEG_COLL:
+ case NFA_NEWL:
+ /* state will advance input */
+ return FALSE;
+
+ default:
+ if (state->c > 0)
+ /* state will advance input */
+ return FALSE;
+
+ /* Others: zero-width or possibly zero-width, might still find
+ * a match at the same position, keep looking. */
+ break;
+ }
+ state = state->out;
+ }
+ return FALSE;
+}
+
+
+/*
+ * Return TRUE if "state" is already in list "l".
+ */
+static int state_in_list(l, state, subs)
+nfa_list_T *l; /* runtime state list */
+nfa_state_T *state; /* state to update */
+regsubs_T *subs; /* pointers to subexpressions */
+{
+ if (state->lastlist[nfa_ll_index] == l->id) {
+ if (!nfa_has_backref || has_state_with_pos(l, state, subs, NULL))
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*
+ * Add "state" and possibly what follows to state list ".".
+ * Returns "subs_arg", possibly copied into temp_subs.
+ */
+
+static regsubs_T * addstate(l, state, subs_arg, pim, off)
+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 subidx;
+ nfa_thread_T *thread;
+ lpos_T save_lpos;
+ int save_in_use;
+ char_u *save_ptr;
+ int i;
+ regsub_T *sub;
+ regsubs_T *subs = subs_arg;
+ static regsubs_T temp_subs;
+#ifdef ENABLE_LOG
+ int did_print = FALSE;
+#endif
+
+ switch (state->c) {
+ case NFA_NCLOSE:
+ case NFA_MCLOSE:
+ case NFA_MCLOSE1:
+ case NFA_MCLOSE2:
+ case NFA_MCLOSE3:
+ case NFA_MCLOSE4:
+ case NFA_MCLOSE5:
+ case NFA_MCLOSE6:
+ case NFA_MCLOSE7:
+ case NFA_MCLOSE8:
+ case NFA_MCLOSE9:
+ case NFA_ZCLOSE:
+ case NFA_ZCLOSE1:
+ case NFA_ZCLOSE2:
+ case NFA_ZCLOSE3:
+ case NFA_ZCLOSE4:
+ case NFA_ZCLOSE5:
+ case NFA_ZCLOSE6:
+ case NFA_ZCLOSE7:
+ case NFA_ZCLOSE8:
+ case NFA_ZCLOSE9:
+ case NFA_MOPEN:
+ case NFA_ZEND:
+ case NFA_SPLIT:
+ case NFA_EMPTY:
+ /* These nodes are not added themselves but their "out" and/or
+ * "out1" may be added below. */
+ break;
+
+ case NFA_BOL:
+ case NFA_BOF:
+ /* "^" won't match past end-of-line, don't bother trying.
+ * Except when at the end of the line, or when we are going to the
+ * next line for a look-behind match. */
+ if (reginput > regline
+ && *reginput != NUL
+ && (nfa_endp == NULL
+ || !REG_MULTI
+ || reglnum == nfa_endp->se_u.pos.lnum))
+ goto skip_add;
+ /* FALLTHROUGH */
+
+ case NFA_MOPEN1:
+ case NFA_MOPEN2:
+ case NFA_MOPEN3:
+ case NFA_MOPEN4:
+ case NFA_MOPEN5:
+ case NFA_MOPEN6:
+ case NFA_MOPEN7:
+ case NFA_MOPEN8:
+ case NFA_MOPEN9:
+ case NFA_ZOPEN:
+ case NFA_ZOPEN1:
+ case NFA_ZOPEN2:
+ case NFA_ZOPEN3:
+ case NFA_ZOPEN4:
+ case NFA_ZOPEN5:
+ case NFA_ZOPEN6:
+ case NFA_ZOPEN7:
+ case NFA_ZOPEN8:
+ case NFA_ZOPEN9:
+ case NFA_NOPEN:
+ case NFA_ZSTART:
+ /* These nodes need to be added so that we can bail out when it
+ * was added to this list before at the same position to avoid an
+ * endless loop for "\(\)*" */
+
+ default:
+ if (state->lastlist[nfa_ll_index] == l->id && state->c != NFA_SKIP) {
+ /* This state is already in the list, don't add it again,
+ * unless it is an MOPEN that is used for a backreference or
+ * when there is a PIM. */
+ if (!nfa_has_backref && pim == NULL && !l->has_pim) {
+skip_add:
+#ifdef ENABLE_LOG
+ 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);
+#endif
+ return subs;
+ }
+
+ /* Do not add the state again when it exists with the same
+ * positions. */
+ if (has_state_with_pos(l, state, subs, pim))
+ goto skip_add;
+ }
+
+ /* When there are backreferences or PIMs the number of states may
+ * be (a lot) bigger than anticipated. */
+ if (l->n == l->len) {
+ int newlen = l->len * 3 / 2 + 50;
+
+ if (subs != &temp_subs) {
+ /* "subs" may point into the current array, need to make a
+ * copy before it becomes invalid. */
+ copy_sub(&temp_subs.norm, &subs->norm);
+ if (nfa_has_zsubexpr)
+ copy_sub(&temp_subs.synt, &subs->synt);
+ subs = &temp_subs;
+ }
+
+ l->t = vim_realloc(l->t, newlen * sizeof(nfa_thread_T));
+ l->len = newlen;
+ }
+
+ /* add the state to the list */
+ state->lastlist[nfa_ll_index] = l->id;
+ thread = &l->t[l->n++];
+ thread->state = state;
+ if (pim == NULL)
+ thread->pim.result = NFA_PIM_UNUSED;
+ else {
+ copy_pim(&thread->pim, pim);
+ l->has_pim = TRUE;
+ }
+ copy_sub(&thread->subs.norm, &subs->norm);
+ if (nfa_has_zsubexpr)
+ copy_sub(&thread->subs.synt, &subs->synt);
+#ifdef ENABLE_LOG
+ report_state("Adding", &thread->subs.norm, state, l->id, pim);
+ did_print = TRUE;
+#endif
+ }
+
+#ifdef ENABLE_LOG
+ if (!did_print)
+ report_state("Processing", &subs->norm, state, l->id, pim);
+#endif
+ switch (state->c) {
+ case NFA_MATCH:
+ nfa_match = TRUE;
+ break;
+
+ case NFA_SPLIT:
+ /* order matters here */
+ subs = addstate(l, state->out, subs, pim, off);
+ subs = addstate(l, state->out1, subs, pim, off);
+ break;
+
+ case NFA_EMPTY:
+ case NFA_NOPEN:
+ case NFA_NCLOSE:
+ subs = addstate(l, state->out, subs, pim, off);
+ break;
+
+ case NFA_MOPEN:
+ case NFA_MOPEN1:
+ case NFA_MOPEN2:
+ case NFA_MOPEN3:
+ case NFA_MOPEN4:
+ case NFA_MOPEN5:
+ case NFA_MOPEN6:
+ case NFA_MOPEN7:
+ case NFA_MOPEN8:
+ case NFA_MOPEN9:
+ case NFA_ZOPEN:
+ case NFA_ZOPEN1:
+ case NFA_ZOPEN2:
+ case NFA_ZOPEN3:
+ case NFA_ZOPEN4:
+ case NFA_ZOPEN5:
+ case NFA_ZOPEN6:
+ case NFA_ZOPEN7:
+ case NFA_ZOPEN8:
+ case NFA_ZOPEN9:
+ case NFA_ZSTART:
+ if (state->c == NFA_ZSTART) {
+ subidx = 0;
+ sub = &subs->norm;
+ } else if (state->c >= NFA_ZOPEN && state->c <= NFA_ZOPEN9) {
+ subidx = state->c - NFA_ZOPEN;
+ sub = &subs->synt;
+ } else {
+ subidx = state->c - NFA_MOPEN;
+ sub = &subs->norm;
+ }
+
+ /* avoid compiler warnings */
+ save_ptr = NULL;
+ save_lpos.lnum = 0;
+ save_lpos.col = 0;
+
+ /* 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 = sub->list.multi[subidx].start;
+ save_in_use = -1;
+ } else {
+ save_in_use = sub->in_use;
+ for (i = sub->in_use; i < subidx; ++i) {
+ sub->list.multi[i].start.lnum = -1;
+ sub->list.multi[i].end.lnum = -1;
+ }
+ sub->in_use = subidx + 1;
+ }
+ if (off == -1) {
+ sub->list.multi[subidx].start.lnum = reglnum + 1;
+ sub->list.multi[subidx].start.col = 0;
+ } else {
+ sub->list.multi[subidx].start.lnum = reglnum;
+ sub->list.multi[subidx].start.col =
+ (colnr_T)(reginput - regline + off);
+ }
+ } else {
+ if (subidx < sub->in_use) {
+ save_ptr = sub->list.line[subidx].start;
+ save_in_use = -1;
+ } else {
+ save_in_use = sub->in_use;
+ for (i = sub->in_use; i < subidx; ++i) {
+ sub->list.line[i].start = NULL;
+ sub->list.line[i].end = NULL;
+ }
+ sub->in_use = subidx + 1;
+ }
+ 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)
+ sub = &subs->synt;
+ else
+ sub = &subs->norm;
+
+ if (save_in_use == -1) {
+ if (REG_MULTI)
+ sub->list.multi[subidx].start = save_lpos;
+ else
+ sub->list.line[subidx].start = save_ptr;
+ } else
+ sub->in_use = save_in_use;
+ break;
+
+ case NFA_MCLOSE:
+ if (nfa_has_zend && (REG_MULTI
+ ? 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);
+ break;
+ }
+ case NFA_MCLOSE1:
+ case NFA_MCLOSE2:
+ case NFA_MCLOSE3:
+ case NFA_MCLOSE4:
+ case NFA_MCLOSE5:
+ case NFA_MCLOSE6:
+ case NFA_MCLOSE7:
+ case NFA_MCLOSE8:
+ case NFA_MCLOSE9:
+ case NFA_ZCLOSE:
+ case NFA_ZCLOSE1:
+ case NFA_ZCLOSE2:
+ case NFA_ZCLOSE3:
+ case NFA_ZCLOSE4:
+ case NFA_ZCLOSE5:
+ case NFA_ZCLOSE6:
+ case NFA_ZCLOSE7:
+ case NFA_ZCLOSE8:
+ case NFA_ZCLOSE9:
+ case NFA_ZEND:
+ if (state->c == NFA_ZEND) {
+ subidx = 0;
+ sub = &subs->norm;
+ } else if (state->c >= NFA_ZCLOSE && state->c <= NFA_ZCLOSE9) {
+ subidx = state->c - NFA_ZCLOSE;
+ sub = &subs->synt;
+ } else {
+ subidx = state->c - NFA_MCLOSE;
+ sub = &subs->norm;
+ }
+
+ /* We don't fill in gaps here, there must have been an MOPEN that
+ * has done that. */
+ save_in_use = sub->in_use;
+ if (sub->in_use <= subidx)
+ sub->in_use = subidx + 1;
+ if (REG_MULTI) {
+ save_lpos = sub->list.multi[subidx].end;
+ if (off == -1) {
+ sub->list.multi[subidx].end.lnum = reglnum + 1;
+ sub->list.multi[subidx].end.col = 0;
+ } else {
+ sub->list.multi[subidx].end.lnum = reglnum;
+ sub->list.multi[subidx].end.col =
+ (colnr_T)(reginput - regline + off);
+ }
+ /* avoid compiler warnings */
+ save_ptr = NULL;
+ } 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;
+ }
+
+ 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)
+ sub = &subs->synt;
+ else
+ sub = &subs->norm;
+
+ if (REG_MULTI)
+ sub->list.multi[subidx].end = save_lpos;
+ else
+ sub->list.line[subidx].end = save_ptr;
+ sub->in_use = save_in_use;
+ break;
+ }
+ return subs;
+}
+
+/*
+ * Like addstate(), but the new state(s) are put at position "*ip".
+ * Used for zero-width matches, next state to use is the added one.
+ * This makes sure the order of states to be tried does not change, which
+ * matters for alternatives.
+ */
+static void addstate_here(l, state, subs, pim, ip)
+nfa_list_T *l; /* runtime state list */
+nfa_state_T *state; /* state to update */
+regsubs_T *subs; /* pointers to subexpressions */
+nfa_pim_T *pim; /* postponed look-behind match */
+int *ip;
+{
+ int tlen = l->n;
+ 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);
+
+ /* when "*ip" was at the end of the list, nothing to do */
+ if (listidx + 1 == tlen)
+ return;
+
+ /* re-order to put the new state at the current position */
+ count = l->n - tlen;
+ if (count == 0)
+ return; /* no state got added */
+ if (count == 1) {
+ /* overwrite the current state */
+ l->t[listidx] = l->t[l->n - 1];
+ } else if (count > 1) {
+ if (l->n + count - 1 >= l->len) {
+ /* not enough space to move the new states, reallocate the list
+ * and move the states to the right position */
+ nfa_thread_T *newl;
+
+ l->len = l->len * 3 / 2 + 50;
+ newl = (nfa_thread_T *)alloc(l->len * sizeof(nfa_thread_T));
+ if (newl == NULL)
+ return;
+ mch_memmove(&(newl[0]),
+ &(l->t[0]),
+ sizeof(nfa_thread_T) * listidx);
+ mch_memmove(&(newl[listidx]),
+ &(l->t[l->n - count]),
+ sizeof(nfa_thread_T) * count);
+ mch_memmove(&(newl[listidx + count]),
+ &(l->t[listidx + 1]),
+ sizeof(nfa_thread_T) * (l->n - count - listidx - 1));
+ vim_free(l->t);
+ l->t = newl;
+ } else {
+ /* make space for new states, then move them from the
+ * end to the current position */
+ mch_memmove(&(l->t[listidx + count]),
+ &(l->t[listidx + 1]),
+ sizeof(nfa_thread_T) * (l->n - listidx - 1));
+ mch_memmove(&(l->t[listidx]),
+ &(l->t[l->n - 1]),
+ sizeof(nfa_thread_T) * count);
+ }
+ }
+ --l->n;
+ *ip = listidx - 1;
+}
+
+/*
+ * Check character class "class" against current character c.
+ */
+static int check_char_class(class, c)
+int class;
+int c;
+{
+ switch (class) {
+ case NFA_CLASS_ALNUM:
+ if (c >= 1 && c <= 255 && isalnum(c))
+ return OK;
+ break;
+ case NFA_CLASS_ALPHA:
+ if (c >= 1 && c <= 255 && 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))
+ return OK;
+ break;
+ case NFA_CLASS_DIGIT:
+ if (VIM_ISDIGIT(c))
+ return OK;
+ break;
+ case NFA_CLASS_GRAPH:
+ if (c >= 1 && c <= 255 && isgraph(c))
+ return OK;
+ break;
+ case NFA_CLASS_LOWER:
+ if (MB_ISLOWER(c))
+ 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))
+ return OK;
+ break;
+ case NFA_CLASS_SPACE:
+ if ((c >= 9 && c <= 13) || (c == ' '))
+ return OK;
+ break;
+ case NFA_CLASS_UPPER:
+ if (MB_ISUPPER(c))
+ return OK;
+ break;
+ case NFA_CLASS_XDIGIT:
+ if (vim_isxdigit(c))
+ return OK;
+ break;
+ case NFA_CLASS_TAB:
+ if (c == '\t')
+ return OK;
+ break;
+ case NFA_CLASS_RETURN:
+ if (c == '\r')
+ return OK;
+ break;
+ case NFA_CLASS_BACKSPACE:
+ if (c == '\b')
+ return OK;
+ break;
+ case NFA_CLASS_ESCAPE:
+ if (c == '\033')
+ return OK;
+ break;
+
+ default:
+ /* should not be here :P */
+ EMSGN(_(e_ill_char_class), class);
+ return FAIL;
+ }
+ return FAIL;
+}
+
+/*
+ * Check for a match with subexpression "subidx".
+ * Return TRUE if it matches.
+ */
+static int match_backref(sub, subidx, bytelen)
+regsub_T *sub; /* pointers to subexpressions */
+int subidx;
+int *bytelen; /* out: length of match in bytes */
+{
+ int len;
+
+ if (sub->in_use <= subidx) {
+retempty:
+ /* backref was not set, match an empty string */
+ *bytelen = 0;
+ return TRUE;
+ }
+
+ if (REG_MULTI) {
+ if (sub->list.multi[subidx].start.lnum < 0
+ || sub->list.multi[subidx].end.lnum < 0)
+ goto retempty;
+ if (sub->list.multi[subidx].start.lnum == reglnum
+ && sub->list.multi[subidx].end.lnum == reglnum) {
+ len = sub->list.multi[subidx].end.col
+ - sub->list.multi[subidx].start.col;
+ if (cstrncmp(regline + sub->list.multi[subidx].start.col,
+ reginput, &len) == 0) {
+ *bytelen = len;
+ return TRUE;
+ }
+ } else {
+ if (match_with_backref(
+ sub->list.multi[subidx].start.lnum,
+ sub->list.multi[subidx].start.col,
+ sub->list.multi[subidx].end.lnum,
+ sub->list.multi[subidx].end.col,
+ bytelen) == RA_MATCH)
+ return TRUE;
+ }
+ } else {
+ if (sub->list.line[subidx].start == NULL
+ || sub->list.line[subidx].end == NULL)
+ goto retempty;
+ len = (int)(sub->list.line[subidx].end - sub->list.line[subidx].start);
+ if (cstrncmp(sub->list.line[subidx].start, reginput, &len) == 0) {
+ *bytelen = len;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+
+static int match_zref __ARGS((int subidx, int *bytelen));
+
+/*
+ * Check for a match with \z subexpression "subidx".
+ * Return TRUE if it matches.
+ */
+static int match_zref(subidx, bytelen)
+int subidx;
+int *bytelen; /* out: length of match in bytes */
+{
+ int len;
+
+ cleanup_zsubexpr();
+ if (re_extmatch_in == NULL || re_extmatch_in->matches[subidx] == NULL) {
+ /* backref was not set, match an empty string */
+ *bytelen = 0;
+ return TRUE;
+ }
+
+ len = (int)STRLEN(re_extmatch_in->matches[subidx]);
+ if (cstrncmp(re_extmatch_in->matches[subidx], reginput, &len) == 0) {
+ *bytelen = len;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*
+ * Save list IDs for all NFA states of "prog" into "list".
+ * Also reset the IDs to zero.
+ * Only used for the recursive value lastlist[1].
+ */
+static void nfa_save_listids(prog, list)
+nfa_regprog_T *prog;
+int *list;
+{
+ int i;
+ nfa_state_T *p;
+
+ /* Order in the list is reverse, it's a bit faster that way. */
+ p = &prog->state[0];
+ for (i = prog->nstate; --i >= 0; ) {
+ list[i] = p->lastlist[1];
+ p->lastlist[1] = 0;
+ ++p;
+ }
+}
+
+/*
+ * Restore list IDs from "list" to all NFA states.
+ */
+static void nfa_restore_listids(prog, list)
+nfa_regprog_T *prog;
+int *list;
+{
+ int i;
+ nfa_state_T *p;
+
+ p = &prog->state[0];
+ for (i = prog->nstate; --i >= 0; ) {
+ p->lastlist[1] = list[i];
+ ++p;
+ }
+}
+
+static int nfa_re_num_cmp(val, op, pos)
+long_u val;
+int op;
+long_u pos;
+{
+ if (op == 1) return pos > val;
+ if (op == 2) return pos < val;
+ return val == pos;
+}
+
+static int recursive_regmatch __ARGS((nfa_state_T *state, nfa_pim_T *pim,
+ nfa_regprog_T *prog, regsubs_T *submatch,
+ regsubs_T *m,
+ int **listids));
+static int nfa_regmatch __ARGS((nfa_regprog_T *prog, nfa_state_T *start,
+ regsubs_T *submatch,
+ regsubs_T *m));
+
+/*
+ * Recursively call nfa_regmatch()
+ * "pim" is NULL or contains info about a Postponed Invisible Match (start
+ * position).
+ */
+static int recursive_regmatch(state, pim, prog, submatch, m, listids)
+nfa_state_T *state;
+nfa_pim_T *pim;
+nfa_regprog_T *prog;
+regsubs_T *submatch;
+regsubs_T *m;
+int **listids;
+{
+ int save_reginput_col = (int)(reginput - regline);
+ int save_reglnum = reglnum;
+ int save_nfa_match = nfa_match;
+ int save_nfa_listid = nfa_listid;
+ save_se_T *save_nfa_endp = nfa_endp;
+ save_se_T endpos;
+ save_se_T *endposp = NULL;
+ int result;
+ int need_restore = FALSE;
+
+ if (pim != NULL) {
+ /* start at the position where the postponed match was */
+ if (REG_MULTI)
+ reginput = regline + pim->end.pos.col;
+ else
+ reginput = pim->end.ptr;
+ }
+
+ if (state->c == NFA_START_INVISIBLE_BEFORE
+ || state->c == NFA_START_INVISIBLE_BEFORE_FIRST
+ || state->c == NFA_START_INVISIBLE_BEFORE_NEG
+ || state->c == NFA_START_INVISIBLE_BEFORE_NEG_FIRST) {
+ /* The recursive match must end at the current position. When "pim" is
+ * not NULL it specifies the current position. */
+ endposp = &endpos;
+ if (REG_MULTI) {
+ if (pim == NULL) {
+ endpos.se_u.pos.col = (int)(reginput - regline);
+ endpos.se_u.pos.lnum = reglnum;
+ } else
+ endpos.se_u.pos = pim->end.pos;
+ } else {
+ if (pim == NULL)
+ endpos.se_u.ptr = reginput;
+ else
+ endpos.se_u.ptr = pim->end.ptr;
+ }
+
+ /* Go back the specified number of bytes, or as far as the
+ * start of the previous line, to try matching "\@<=" or
+ * not matching "\@<!". This is very inefficient, limit the number of
+ * bytes if possible. */
+ if (state->val <= 0) {
+ if (REG_MULTI) {
+ regline = reg_getline(--reglnum);
+ if (regline == NULL)
+ /* can't go before the first line */
+ regline = reg_getline(++reglnum);
+ }
+ reginput = regline;
+ } else {
+ if (REG_MULTI && (int)(reginput - regline) < state->val) {
+ /* Not enough bytes in this line, go to end of
+ * previous line. */
+ regline = reg_getline(--reglnum);
+ if (regline == NULL) {
+ /* can't go before the first line */
+ regline = reg_getline(++reglnum);
+ reginput = regline;
+ } else
+ reginput = regline + STRLEN(regline);
+ }
+ if ((int)(reginput - regline) >= state->val) {
+ reginput -= state->val;
+ if (has_mbyte)
+ reginput -= mb_head_off(regline, reginput);
+ } else
+ reginput = regline;
+ }
+ }
+
+#ifdef ENABLE_LOG
+ if (log_fd != stderr)
+ fclose(log_fd);
+ log_fd = NULL;
+#endif
+ /* Have to clear the lastlist field of the NFA nodes, so that
+ * nfa_regmatch() and addstate() can run properly after recursion. */
+ if (nfa_ll_index == 1) {
+ /* Already calling nfa_regmatch() recursively. Save the lastlist[1]
+ * values and clear them. */
+ if (*listids == NULL) {
+ *listids = (int *)lalloc(sizeof(int) * nstate, TRUE);
+ if (*listids == NULL) {
+ EMSG(_("E878: (NFA) Could not allocate memory for branch traversal!"));
+ return 0;
+ }
+ }
+ nfa_save_listids(prog, *listids);
+ need_restore = TRUE;
+ /* any value of nfa_listid will do */
+ } else {
+ /* First recursive nfa_regmatch() call, switch to the second lastlist
+ * entry. Make sure nfa_listid is different from a previous recursive
+ * call, because some states may still have this ID. */
+ ++nfa_ll_index;
+ if (nfa_listid <= nfa_alt_listid)
+ nfa_listid = nfa_alt_listid;
+ }
+
+ /* Call nfa_regmatch() to check if the current concat matches at this
+ * position. The concat ends with the node NFA_END_INVISIBLE */
+ nfa_endp = endposp;
+ result = nfa_regmatch(prog, state->out, submatch, m);
+
+ if (need_restore)
+ nfa_restore_listids(prog, *listids);
+ else {
+ --nfa_ll_index;
+ nfa_alt_listid = nfa_listid;
+ }
+
+ /* restore position in input text */
+ reglnum = save_reglnum;
+ if (REG_MULTI)
+ regline = reg_getline(reglnum);
+ reginput = regline + save_reginput_col;
+ nfa_match = save_nfa_match;
+ nfa_endp = save_nfa_endp;
+ nfa_listid = save_nfa_listid;
+
+#ifdef ENABLE_LOG
+ log_fd = fopen(NFA_REGEXP_RUN_LOG, "a");
+ if (log_fd != NULL) {
+ fprintf(log_fd, "****************************\n");
+ fprintf(log_fd, "FINISHED RUNNING nfa_regmatch() recursively\n");
+ fprintf(log_fd, "MATCH = %s\n", result == TRUE ? "OK" : "FALSE");
+ fprintf(log_fd, "****************************\n");
+ } else {
+ EMSG(_(
+ "Could not open temporary log file for writing, displaying on stderr ... "));
+ log_fd = stderr;
+ }
+#endif
+
+ return result;
+}
+
+static int skip_to_start __ARGS((int c, colnr_T *colp));
+static long find_match_text __ARGS((colnr_T startcol, int regstart,
+ char_u *match_text));
+
+/*
+ * Estimate the chance of a match with "state" failing.
+ * empty match: 0
+ * NFA_ANY: 1
+ * specific character: 99
+ */
+static int failure_chance(state, depth)
+nfa_state_T *state;
+int depth;
+{
+ int c = state->c;
+ int l, r;
+
+ /* detect looping */
+ if (depth > 4)
+ return 1;
+
+ switch (c) {
+ case NFA_SPLIT:
+ if (state->out->c == NFA_SPLIT || state->out1->c == NFA_SPLIT)
+ /* avoid recursive stuff */
+ return 1;
+ /* two alternatives, use the lowest failure chance */
+ l = failure_chance(state->out, depth + 1);
+ r = failure_chance(state->out1, depth + 1);
+ return l < r ? l : r;
+
+ case NFA_ANY:
+ /* matches anything, unlikely to fail */
+ return 1;
+
+ case NFA_MATCH:
+ case NFA_MCLOSE:
+ /* empty match works always */
+ return 0;
+
+ case NFA_START_INVISIBLE:
+ case NFA_START_INVISIBLE_FIRST:
+ case NFA_START_INVISIBLE_NEG:
+ case NFA_START_INVISIBLE_NEG_FIRST:
+ case NFA_START_INVISIBLE_BEFORE:
+ case NFA_START_INVISIBLE_BEFORE_FIRST:
+ case NFA_START_INVISIBLE_BEFORE_NEG:
+ case NFA_START_INVISIBLE_BEFORE_NEG_FIRST:
+ case NFA_START_PATTERN:
+ /* recursive regmatch is expensive, use low failure chance */
+ return 5;
+
+ case NFA_BOL:
+ case NFA_EOL:
+ case NFA_BOF:
+ case NFA_EOF:
+ case NFA_NEWL:
+ return 99;
+
+ case NFA_BOW:
+ case NFA_EOW:
+ return 90;
+
+ case NFA_MOPEN:
+ case NFA_MOPEN1:
+ case NFA_MOPEN2:
+ case NFA_MOPEN3:
+ case NFA_MOPEN4:
+ case NFA_MOPEN5:
+ case NFA_MOPEN6:
+ case NFA_MOPEN7:
+ case NFA_MOPEN8:
+ case NFA_MOPEN9:
+ case NFA_ZOPEN:
+ case NFA_ZOPEN1:
+ case NFA_ZOPEN2:
+ case NFA_ZOPEN3:
+ case NFA_ZOPEN4:
+ case NFA_ZOPEN5:
+ case NFA_ZOPEN6:
+ case NFA_ZOPEN7:
+ case NFA_ZOPEN8:
+ case NFA_ZOPEN9:
+ case NFA_ZCLOSE:
+ case NFA_ZCLOSE1:
+ case NFA_ZCLOSE2:
+ case NFA_ZCLOSE3:
+ case NFA_ZCLOSE4:
+ case NFA_ZCLOSE5:
+ case NFA_ZCLOSE6:
+ case NFA_ZCLOSE7:
+ case NFA_ZCLOSE8:
+ case NFA_ZCLOSE9:
+ case NFA_NOPEN:
+ case NFA_MCLOSE1:
+ case NFA_MCLOSE2:
+ case NFA_MCLOSE3:
+ case NFA_MCLOSE4:
+ case NFA_MCLOSE5:
+ case NFA_MCLOSE6:
+ case NFA_MCLOSE7:
+ case NFA_MCLOSE8:
+ case NFA_MCLOSE9:
+ case NFA_NCLOSE:
+ return failure_chance(state->out, depth + 1);
+
+ case NFA_BACKREF1:
+ case NFA_BACKREF2:
+ case NFA_BACKREF3:
+ case NFA_BACKREF4:
+ case NFA_BACKREF5:
+ case NFA_BACKREF6:
+ case NFA_BACKREF7:
+ case NFA_BACKREF8:
+ case NFA_BACKREF9:
+ case NFA_ZREF1:
+ case NFA_ZREF2:
+ case NFA_ZREF3:
+ case NFA_ZREF4:
+ case NFA_ZREF5:
+ case NFA_ZREF6:
+ case NFA_ZREF7:
+ case NFA_ZREF8:
+ case NFA_ZREF9:
+ /* backreferences don't match in many places */
+ return 94;
+
+ case NFA_LNUM_GT:
+ case NFA_LNUM_LT:
+ case NFA_COL_GT:
+ case NFA_COL_LT:
+ case NFA_VCOL_GT:
+ case NFA_VCOL_LT:
+ case NFA_MARK_GT:
+ case NFA_MARK_LT:
+ case NFA_VISUAL:
+ /* before/after positions don't match very often */
+ return 85;
+
+ case NFA_LNUM:
+ return 90;
+
+ case NFA_CURSOR:
+ case NFA_COL:
+ case NFA_VCOL:
+ case NFA_MARK:
+ /* specific positions rarely match */
+ return 98;
+
+ case NFA_COMPOSING:
+ return 95;
+
+ default:
+ if (c > 0)
+ /* character match fails often */
+ return 95;
+ }
+
+ /* something else, includes character classes */
+ return 50;
+}
+
+/*
+ * Skip until the char "c" we know a match must start with.
+ */
+static int skip_to_start(c, colp)
+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)
+ return FAIL;
+ *colp = (int)(s - regline);
+ return OK;
+}
+
+/*
+ * Check for a match with match_text.
+ * Called after skip_to_start() has found regstart.
+ * Returns zero for no match, 1 for a match.
+ */
+static long find_match_text(startcol, regstart, match_text)
+colnr_T startcol;
+int regstart;
+char_u *match_text;
+{
+ colnr_T col = startcol;
+ int c1, c2;
+ int len1, len2;
+ int match;
+
+ for (;; ) {
+ match = TRUE;
+ len2 = MB_CHAR2LEN(regstart); /* skip regstart */
+ for (len1 = 0; match_text[len1] != NUL; len1 += MB_CHAR2LEN(c1)) {
+ c1 = PTR2CHAR(match_text + len1);
+ c2 = PTR2CHAR(regline + col + len2);
+ if (c1 != c2 && (!ireg_ic || MB_TOLOWER(c1) != MB_TOLOWER(c2))) {
+ match = FALSE;
+ break;
+ }
+ len2 += MB_CHAR2LEN(c2);
+ }
+ if (match
+ /* check that no composing char follows */
+ && !(enc_utf8
+ && utf_iscomposing(PTR2CHAR(regline + col + len2)))
+ ) {
+ cleanup_subexpr();
+ if (REG_MULTI) {
+ reg_startpos[0].lnum = reglnum;
+ reg_startpos[0].col = col;
+ reg_endpos[0].lnum = reglnum;
+ reg_endpos[0].col = col + len2;
+ } else {
+ reg_startp[0] = regline + col;
+ reg_endp[0] = regline + col + len2;
+ }
+ return 1L;
+ }
+
+ /* Try finding regstart after the current match. */
+ col += MB_CHAR2LEN(regstart); /* skip regstart */
+ if (skip_to_start(regstart, &col) == FAIL)
+ break;
+ }
+ return 0L;
+}
+
+/*
+ * Main matching routine.
+ *
+ * Run NFA to determine whether it matches reginput.
+ *
+ * When "nfa_endp" is not NULL it is a required end-of-match position.
+ *
+ * Return TRUE if there is a match, FALSE otherwise.
+ * When there is a match "submatch" contains the positions.
+ * Note: Caller must ensure that: start != NULL.
+ */
+static int nfa_regmatch(prog, start, submatch, m)
+nfa_regprog_T *prog;
+nfa_state_T *start;
+regsubs_T *submatch;
+regsubs_T *m;
+{
+ int result;
+ int size = 0;
+ int flag = 0;
+ int go_to_nextline = FALSE;
+ nfa_thread_T *t;
+ nfa_list_T list[2];
+ int listidx;
+ nfa_list_T *thislist;
+ nfa_list_T *nextlist;
+ int *listids = NULL;
+ nfa_state_T *add_state;
+ int add_here;
+ int add_count;
+ int add_off = 0;
+ int toplevel = start->c == NFA_MOPEN;
+#ifdef NFA_REGEXP_DEBUG_LOG
+ FILE *debug = fopen(NFA_REGEXP_DEBUG_LOG, "a");
+
+ if (debug == NULL) {
+ EMSG2(_("(NFA) COULD NOT OPEN %s !"), NFA_REGEXP_DEBUG_LOG);
+ return FALSE;
+ }
+#endif
+ /* Some patterns may take a long time to match, especially when using
+ * recursive_regmatch(). Allow interrupting them with CTRL-C. */
+ fast_breakcheck();
+ if (got_int)
+ return FALSE;
+
+ nfa_match = FALSE;
+
+ /* Allocate memory for the lists of nodes. */
+ size = (nstate + 1) * sizeof(nfa_thread_T);
+ list[0].t = (nfa_thread_T *)lalloc(size, TRUE);
+ list[0].len = nstate + 1;
+ list[1].t = (nfa_thread_T *)lalloc(size, TRUE);
+ list[1].len = nstate + 1;
+ if (list[0].t == NULL || list[1].t == NULL)
+ goto theend;
+
+#ifdef ENABLE_LOG
+ log_fd = fopen(NFA_REGEXP_RUN_LOG, "a");
+ if (log_fd != NULL) {
+ fprintf(log_fd, "**********************************\n");
+ nfa_set_code(start->c);
+ fprintf(log_fd, " RUNNING nfa_regmatch() starting with state %d, code %s\n",
+ abs(start->id), code);
+ fprintf(log_fd, "**********************************\n");
+ } else {
+ EMSG(_(
+ "Could not open temporary log file for writing, displaying on stderr ... "));
+ log_fd = stderr;
+ }
+#endif
+
+ thislist = &list[0];
+ thislist->n = 0;
+ thislist->has_pim = FALSE;
+ nextlist = &list[1];
+ nextlist->n = 0;
+ nextlist->has_pim = FALSE;
+#ifdef ENABLE_LOG
+ fprintf(log_fd, "(---) STARTSTATE first\n");
+#endif
+ thislist->id = nfa_listid + 1;
+
+ /* Inline optimized code for addstate(thislist, start, m, 0) if we know
+ * it's the first MOPEN. */
+ if (toplevel) {
+ if (REG_MULTI) {
+ m->norm.list.multi[0].start.lnum = reglnum;
+ m->norm.list.multi[0].start.col = (colnr_T)(reginput - regline);
+ } else
+ m->norm.list.line[0].start = reginput;
+ m->norm.in_use = 1;
+ addstate(thislist, start->out, m, NULL, 0);
+ } else
+ addstate(thislist, start, m, NULL, 0);
+
+#define ADD_STATE_IF_MATCH(state) \
+ if (result) { \
+ add_state = state->out; \
+ add_off = clen; \
+ }
+
+ /*
+ * 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;
+ }
+ if (curc == NUL) {
+ clen = 0;
+ go_to_nextline = FALSE;
+ }
+
+ /* swap lists */
+ thislist = &list[flag];
+ nextlist = &list[flag ^= 1];
+ nextlist->n = 0; /* clear nextlist */
+ nextlist->has_pim = FALSE;
+ ++nfa_listid;
+ thislist->id = nfa_listid;
+ nextlist->id = nfa_listid + 1;
+
+#ifdef ENABLE_LOG
+ 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);
+ fprintf(log_fd, ">>> Thislist has %d states available: ", thislist->n);
+ {
+ int i;
+
+ for (i = 0; i < thislist->n; i++)
+ fprintf(log_fd, "%d ", abs(thislist->t[i].state->id));
+ }
+ fprintf(log_fd, "\n");
+#endif
+
+#ifdef NFA_REGEXP_DEBUG_LOG
+ fprintf(debug, "\n-------------------\n");
+#endif
+ /*
+ * If the state lists are empty we can stop.
+ */
+ if (thislist->n == 0)
+ break;
+
+ /* compute nextlist */
+ for (listidx = 0; listidx < thislist->n; ++listidx) {
+ t = &thislist->t[listidx];
+
+#ifdef NFA_REGEXP_DEBUG_LOG
+ nfa_set_code(t->state->c);
+ fprintf(debug, "%s, ", code);
+#endif
+#ifdef ENABLE_LOG
+ {
+ int col;
+
+ if (t->subs.norm.in_use <= 0)
+ col = -1;
+ else if (REG_MULTI)
+ col = t->subs.norm.list.multi[0].start.col;
+ 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));
+ }
+#endif
+
+ /*
+ * Handle the possible codes of the current state.
+ * The most important is NFA_MATCH.
+ */
+ add_state = NULL;
+ add_here = FALSE;
+ add_count = 0;
+ switch (t->state->c) {
+ case NFA_MATCH:
+ {
+ nfa_match = TRUE;
+ copy_sub(&submatch->norm, &t->subs.norm);
+ if (nfa_has_zsubexpr)
+ copy_sub(&submatch->synt, &t->subs.synt);
+#ifdef ENABLE_LOG
+ log_subsexpr(&t->subs);
+#endif
+ /* Found the left-most longest match, do not look at any other
+ * states at this position. When the list of states is going
+ * to be empty quit without advancing, so that "reginput" is
+ * correct. */
+ if (nextlist->n == 0)
+ clen = 0;
+ goto nextchar;
+ }
+
+ case NFA_END_INVISIBLE:
+ case NFA_END_INVISIBLE_NEG:
+ case NFA_END_PATTERN:
+ /*
+ * This is only encountered after a NFA_START_INVISIBLE or
+ * NFA_START_INVISIBLE_BEFORE node.
+ * They surround a zero-width group, used with "\@=", "\&",
+ * "\@!", "\@<=" and "\@<!".
+ * If we got here, it means that the current "invisible" group
+ * finished successfully, so return control to the parent
+ * nfa_regmatch(). For a look-behind match only when it ends
+ * in the position in "nfa_endp".
+ * Submatches are stored in *m, and used in the parent call.
+ */
+#ifdef ENABLE_LOG
+ if (nfa_endp != NULL) {
+ if (REG_MULTI)
+ fprintf(
+ log_fd,
+ "Current lnum: %d, endp lnum: %d; current col: %d, endp col: %d\n",
+ (int)reglnum,
+ (int)nfa_endp->se_u.pos.lnum,
+ (int)(reginput - regline),
+ nfa_endp->se_u.pos.col);
+ else
+ fprintf(log_fd, "Current col: %d, endp col: %d\n",
+ (int)(reginput - regline),
+ (int)(nfa_endp->se_u.ptr - reginput));
+ }
+#endif
+ /* If "nfa_endp" is set it's only a match if it ends at
+ * "nfa_endp" */
+ if (nfa_endp != NULL && (REG_MULTI
+ ? (reglnum != nfa_endp->se_u.pos.lnum
+ || (int)(reginput - regline)
+ != nfa_endp->se_u.pos.col)
+ : reginput != nfa_endp->se_u.ptr))
+ break;
+
+ /* do not set submatches for \@! */
+ if (t->state->c != NFA_END_INVISIBLE_NEG) {
+ copy_sub(&m->norm, &t->subs.norm);
+ if (nfa_has_zsubexpr)
+ copy_sub(&m->synt, &t->subs.synt);
+ }
+#ifdef ENABLE_LOG
+ fprintf(log_fd, "Match found:\n");
+ log_subsexpr(m);
+#endif
+ nfa_match = TRUE;
+ /* See comment above at "goto nextchar". */
+ if (nextlist->n == 0)
+ clen = 0;
+ goto nextchar;
+
+ case NFA_START_INVISIBLE:
+ case NFA_START_INVISIBLE_FIRST:
+ case NFA_START_INVISIBLE_NEG:
+ case NFA_START_INVISIBLE_NEG_FIRST:
+ case NFA_START_INVISIBLE_BEFORE:
+ case NFA_START_INVISIBLE_BEFORE_FIRST:
+ case NFA_START_INVISIBLE_BEFORE_NEG:
+ case NFA_START_INVISIBLE_BEFORE_NEG_FIRST:
+ {
+#ifdef ENABLE_LOG
+ fprintf(log_fd, "Failure chance invisible: %d, what follows: %d\n",
+ failure_chance(t->state->out, 0),
+ failure_chance(t->state->out1->out, 0));
+#endif
+ /* Do it directly if there already is a PIM or when
+ * nfa_postprocess() detected it will work better. */
+ if (t->pim.result != NFA_PIM_UNUSED
+ || t->state->c == NFA_START_INVISIBLE_FIRST
+ || t->state->c == NFA_START_INVISIBLE_NEG_FIRST
+ || t->state->c == NFA_START_INVISIBLE_BEFORE_FIRST
+ || t->state->c == NFA_START_INVISIBLE_BEFORE_NEG_FIRST) {
+ int in_use = m->norm.in_use;
+
+ /* Copy submatch info for the recursive call, opposite
+ * of what happens on success below. */
+ copy_sub_off(&m->norm, &t->subs.norm);
+ if (nfa_has_zsubexpr)
+ copy_sub_off(&m->synt, &t->subs.synt);
+
+ /*
+ * First try matching the invisible match, then what
+ * follows.
+ */
+ result = recursive_regmatch(t->state, NULL, prog,
+ submatch, m, &listids);
+
+ /* for \@! and \@<! it is a match when the result is
+ * FALSE */
+ if (result != (t->state->c == NFA_START_INVISIBLE_NEG
+ || t->state->c == NFA_START_INVISIBLE_NEG_FIRST
+ || t->state->c
+ == NFA_START_INVISIBLE_BEFORE_NEG
+ || t->state->c
+ == NFA_START_INVISIBLE_BEFORE_NEG_FIRST)) {
+ /* Copy submatch info from the recursive call */
+ copy_sub_off(&t->subs.norm, &m->norm);
+ if (nfa_has_zsubexpr)
+ copy_sub_off(&t->subs.synt, &m->synt);
+ /* If the pattern has \ze and it matched in the
+ * sub pattern, use it. */
+ copy_ze_off(&t->subs.norm, &m->norm);
+
+ /* t->state->out1 is the corresponding
+ * END_INVISIBLE node; Add its out to the current
+ * list (zero-width match). */
+ add_here = TRUE;
+ add_state = t->state->out1->out;
+ }
+ m->norm.in_use = in_use;
+ } else {
+ nfa_pim_T pim;
+
+ /*
+ * First try matching what follows. Only if a match
+ * is found verify the invisible match matches. Add a
+ * nfa_pim_T to the following states, it contains info
+ * about the invisible match.
+ */
+ pim.state = t->state;
+ pim.result = NFA_PIM_TODO;
+ pim.subs.norm.in_use = 0;
+ pim.subs.synt.in_use = 0;
+ if (REG_MULTI) {
+ pim.end.pos.col = (int)(reginput - regline);
+ pim.end.pos.lnum = reglnum;
+ } else
+ pim.end.ptr = reginput;
+
+ /* t->state->out1 is the corresponding END_INVISIBLE
+ * node; Add its out to the current list (zero-width
+ * match). */
+ addstate_here(thislist, t->state->out1->out, &t->subs,
+ &pim, &listidx);
+ }
+ }
+ break;
+
+ case NFA_START_PATTERN:
+ {
+ nfa_state_T *skip = NULL;
+#ifdef ENABLE_LOG
+ int skip_lid = 0;
+#endif
+
+ /* There is no point in trying to match the pattern if the
+ * output state is not going to be added to the list. */
+ if (state_in_list(nextlist, t->state->out1->out, &t->subs)) {
+ skip = t->state->out1->out;
+#ifdef ENABLE_LOG
+ skip_lid = nextlist->id;
+#endif
+ } else if (state_in_list(nextlist,
+ t->state->out1->out->out, &t->subs)) {
+ skip = t->state->out1->out->out;
+#ifdef ENABLE_LOG
+ skip_lid = nextlist->id;
+#endif
+ } else if (state_in_list(thislist,
+ t->state->out1->out->out, &t->subs)) {
+ skip = t->state->out1->out->out;
+#ifdef ENABLE_LOG
+ skip_lid = thislist->id;
+#endif
+ }
+ if (skip != NULL) {
+#ifdef ENABLE_LOG
+ nfa_set_code(skip->c);
+ fprintf(
+ log_fd,
+ "> Not trying to match pattern, output state %d is already in list %d. char %d: %s\n",
+ abs(skip->id), skip_lid, skip->c, code);
+#endif
+ break;
+ }
+ /* Copy submatch info to the recursive call, opposite of what
+ * happens afterwards. */
+ copy_sub_off(&m->norm, &t->subs.norm);
+ if (nfa_has_zsubexpr)
+ copy_sub_off(&m->synt, &t->subs.synt);
+
+ /* First try matching the pattern. */
+ result = recursive_regmatch(t->state, NULL, prog,
+ submatch, m, &listids);
+ if (result) {
+ int bytelen;
+
+#ifdef ENABLE_LOG
+ fprintf(log_fd, "NFA_START_PATTERN matches:\n");
+ log_subsexpr(m);
+#endif
+ /* Copy submatch info from the recursive call */
+ copy_sub_off(&t->subs.norm, &m->norm);
+ if (nfa_has_zsubexpr)
+ copy_sub_off(&t->subs.synt, &m->synt);
+ /* Now we need to skip over the matched text and then
+ * continue with what follows. */
+ if (REG_MULTI)
+ /* TODO: multi-line match */
+ bytelen = m->norm.list.multi[0].end.col
+ - (int)(reginput - regline);
+ else
+ bytelen = (int)(m->norm.list.line[0].end - reginput);
+
+#ifdef ENABLE_LOG
+ fprintf(log_fd, "NFA_START_PATTERN length: %d\n", bytelen);
+#endif
+ if (bytelen == 0) {
+ /* empty match, output of corresponding
+ * NFA_END_PATTERN/NFA_SKIP to be used at current
+ * position */
+ add_here = TRUE;
+ add_state = t->state->out1->out->out;
+ } else if (bytelen <= clen) {
+ /* match current character, output of corresponding
+ * NFA_END_PATTERN to be used at next position. */
+ add_state = t->state->out1->out->out;
+ add_off = clen;
+ } else {
+ /* skip over the matched characters, set character
+ * count in NFA_SKIP */
+ add_state = t->state->out1->out;
+ add_off = bytelen;
+ add_count = bytelen - clen;
+ }
+ }
+ break;
+ }
+
+ case NFA_BOL:
+ if (reginput == regline) {
+ add_here = TRUE;
+ add_state = t->state->out;
+ }
+ break;
+
+ case NFA_EOL:
+ if (curc == NUL) {
+ add_here = TRUE;
+ add_state = t->state->out;
+ }
+ break;
+
+ case NFA_BOW:
+ result = TRUE;
+
+ if (curc == NUL)
+ result = FALSE;
+ 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)
+ result = FALSE;
+ else if (reg_prev_class() == this_class)
+ result = FALSE;
+ } else if (!vim_iswordc_buf(curc, reg_buf)
+ || (reginput > regline
+ && vim_iswordc_buf(reginput[-1], reg_buf)))
+ result = FALSE;
+ if (result) {
+ add_here = TRUE;
+ add_state = t->state->out;
+ }
+ break;
+
+ case NFA_EOW:
+ result = TRUE;
+ if (reginput == regline)
+ result = FALSE;
+ 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);
+ 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)
+ || (reginput[0] != NUL
+ && vim_iswordc_buf(curc, reg_buf)))
+ result = FALSE;
+ if (result) {
+ add_here = TRUE;
+ add_state = t->state->out;
+ }
+ break;
+
+ case NFA_BOF:
+ if (reglnum == 0 && reginput == regline
+ && (!REG_MULTI || reg_firstlnum == 1)) {
+ add_here = TRUE;
+ add_state = t->state->out;
+ }
+ break;
+
+ case NFA_EOF:
+ if (reglnum == reg_maxline && curc == NUL) {
+ add_here = TRUE;
+ add_state = t->state->out;
+ }
+ break;
+
+ case NFA_COMPOSING:
+ {
+ int mc = curc;
+ int len = 0;
+ nfa_state_T *end;
+ nfa_state_T *sta;
+ int cchars[MAX_MCO];
+ int ccount = 0;
+ int j;
+
+ sta = t->state->out;
+ len = 0;
+ if (utf_iscomposing(sta->c)) {
+ /* Only match composing character(s), ignore base
+ * character. Used for ".{composing}" and "{composing}"
+ * (no preceding character). */
+ len += mb_char2len(mc);
+ }
+ if (ireg_icombine && len == 0) {
+ /* If \Z was present, then ignore composing characters.
+ * When ignoring the base character this always matches. */
+ if (len == 0 && sta->c != curc)
+ result = FAIL;
+ else
+ result = OK;
+ while (sta->c != NFA_END_COMPOSING)
+ sta = sta->out;
+ }
+ /* Check base character matches first, unless ignored. */
+ else if (len > 0 || mc == sta->c) {
+ if (len == 0) {
+ len += mb_char2len(mc);
+ sta = sta->out;
+ }
+
+ /* We don't care about the order of composing characters.
+ * Get them into cchars[] first. */
+ while (len < clen) {
+ mc = mb_ptr2char(reginput + len);
+ cchars[ccount++] = mc;
+ len += mb_char2len(mc);
+ if (ccount == MAX_MCO)
+ break;
+ }
+
+ /* Check that each composing char in the pattern matches a
+ * composing char in the text. We do not check if all
+ * composing chars are matched. */
+ result = OK;
+ while (sta->c != NFA_END_COMPOSING) {
+ for (j = 0; j < ccount; ++j)
+ if (cchars[j] == sta->c)
+ break;
+ if (j == ccount) {
+ result = FAIL;
+ break;
+ }
+ sta = sta->out;
+ }
+ } else
+ result = FAIL;
+
+ end = t->state->out1; /* NFA_END_COMPOSING */
+ ADD_STATE_IF_MATCH(end);
+ break;
+ }
+
+ case NFA_NEWL:
+ if (curc == NUL && !reg_line_lbr && REG_MULTI
+ && reglnum <= 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) {
+ /* match \n as if it is an ordinary character */
+ add_state = t->state->out;
+ add_off = 1;
+ }
+ break;
+
+ case NFA_START_COLL:
+ case NFA_START_NEG_COLL:
+ {
+ /* What follows is a list of characters, until NFA_END_COLL.
+ * One of them must match or none of them must match. */
+ nfa_state_T *state;
+ int result_if_matched;
+ int c1, c2;
+
+ /* Never match EOL. If it's part of the collection it is added
+ * as a separate state with an OR. */
+ if (curc == NUL)
+ break;
+
+ state = t->state->out;
+ result_if_matched = (t->state->c == NFA_START_COLL);
+ for (;; ) {
+ if (state->c == NFA_END_COLL) {
+ result = !result_if_matched;
+ break;
+ }
+ if (state->c == NFA_RANGE_MIN) {
+ c1 = state->val;
+ state = state->out; /* advance to NFA_RANGE_MAX */
+ c2 = state->val;
+#ifdef ENABLE_LOG
+ fprintf(log_fd, "NFA_RANGE_MIN curc=%d c1=%d c2=%d\n",
+ curc, c1, c2);
+#endif
+ if (curc >= c1 && curc <= c2) {
+ result = result_if_matched;
+ break;
+ }
+ if (ireg_ic) {
+ int curc_low = MB_TOLOWER(curc);
+ int done = FALSE;
+
+ for (; c1 <= c2; ++c1)
+ if (MB_TOLOWER(c1) == curc_low) {
+ result = result_if_matched;
+ done = TRUE;
+ break;
+ }
+ if (done)
+ break;
+ }
+ } else if (state->c < 0 ? check_char_class(state->c, curc)
+ : (curc == state->c
+ || (ireg_ic && MB_TOLOWER(curc)
+ == MB_TOLOWER(state->c)))) {
+ result = result_if_matched;
+ break;
+ }
+ state = state->out;
+ }
+ if (result) {
+ /* next state is in out of the NFA_END_COLL, out1 of
+ * START points to the END state */
+ add_state = t->state->out1->out;
+ add_off = clen;
+ }
+ break;
+ }
+
+ case NFA_ANY:
+ /* Any char except '\0', (end of input) does not match. */
+ if (curc > 0) {
+ add_state = t->state->out;
+ add_off = clen;
+ }
+ break;
+
+ /*
+ * Character classes like \a for alpha, \d for digit etc.
+ */
+ case NFA_IDENT: /* \i */
+ result = vim_isIDc(curc);
+ ADD_STATE_IF_MATCH(t->state);
+ break;
+
+ case NFA_SIDENT: /* \I */
+ result = !VIM_ISDIGIT(curc) && vim_isIDc(curc);
+ ADD_STATE_IF_MATCH(t->state);
+ break;
+
+ case NFA_KWORD: /* \k */
+ result = vim_iswordp_buf(reginput, reg_buf);
+ ADD_STATE_IF_MATCH(t->state);
+ break;
+
+ case NFA_SKWORD: /* \K */
+ result = !VIM_ISDIGIT(curc)
+ && vim_iswordp_buf(reginput, reg_buf);
+ ADD_STATE_IF_MATCH(t->state);
+ break;
+
+ case NFA_FNAME: /* \f */
+ result = vim_isfilec(curc);
+ ADD_STATE_IF_MATCH(t->state);
+ break;
+
+ case NFA_SFNAME: /* \F */
+ result = !VIM_ISDIGIT(curc) && vim_isfilec(curc);
+ ADD_STATE_IF_MATCH(t->state);
+ break;
+
+ case NFA_PRINT: /* \p */
+ result = vim_isprintc(PTR2CHAR(reginput));
+ ADD_STATE_IF_MATCH(t->state);
+ break;
+
+ case NFA_SPRINT: /* \P */
+ result = !VIM_ISDIGIT(curc) && vim_isprintc(PTR2CHAR(reginput));
+ ADD_STATE_IF_MATCH(t->state);
+ break;
+
+ case NFA_WHITE: /* \s */
+ result = vim_iswhite(curc);
+ ADD_STATE_IF_MATCH(t->state);
+ break;
+
+ case NFA_NWHITE: /* \S */
+ result = curc != NUL && !vim_iswhite(curc);
+ ADD_STATE_IF_MATCH(t->state);
+ break;
+
+ case NFA_DIGIT: /* \d */
+ result = ri_digit(curc);
+ ADD_STATE_IF_MATCH(t->state);
+ break;
+
+ case NFA_NDIGIT: /* \D */
+ result = curc != NUL && !ri_digit(curc);
+ ADD_STATE_IF_MATCH(t->state);
+ break;
+
+ case NFA_HEX: /* \x */
+ result = ri_hex(curc);
+ ADD_STATE_IF_MATCH(t->state);
+ break;
+
+ case NFA_NHEX: /* \X */
+ result = curc != NUL && !ri_hex(curc);
+ ADD_STATE_IF_MATCH(t->state);
+ break;
+
+ case NFA_OCTAL: /* \o */
+ result = ri_octal(curc);
+ ADD_STATE_IF_MATCH(t->state);
+ break;
+
+ case NFA_NOCTAL: /* \O */
+ result = curc != NUL && !ri_octal(curc);
+ ADD_STATE_IF_MATCH(t->state);
+ break;
+
+ case NFA_WORD: /* \w */
+ result = ri_word(curc);
+ ADD_STATE_IF_MATCH(t->state);
+ break;
+
+ case NFA_NWORD: /* \W */
+ result = curc != NUL && !ri_word(curc);
+ ADD_STATE_IF_MATCH(t->state);
+ break;
+
+ case NFA_HEAD: /* \h */
+ result = ri_head(curc);
+ ADD_STATE_IF_MATCH(t->state);
+ break;
+
+ case NFA_NHEAD: /* \H */
+ result = curc != NUL && !ri_head(curc);
+ ADD_STATE_IF_MATCH(t->state);
+ break;
+
+ case NFA_ALPHA: /* \a */
+ result = ri_alpha(curc);
+ ADD_STATE_IF_MATCH(t->state);
+ break;
+
+ case NFA_NALPHA: /* \A */
+ result = curc != NUL && !ri_alpha(curc);
+ ADD_STATE_IF_MATCH(t->state);
+ break;
+
+ case NFA_LOWER: /* \l */
+ result = ri_lower(curc);
+ ADD_STATE_IF_MATCH(t->state);
+ break;
+
+ case NFA_NLOWER: /* \L */
+ result = curc != NUL && !ri_lower(curc);
+ ADD_STATE_IF_MATCH(t->state);
+ break;
+
+ case NFA_UPPER: /* \u */
+ result = ri_upper(curc);
+ ADD_STATE_IF_MATCH(t->state);
+ break;
+
+ case NFA_NUPPER: /* \U */
+ result = curc != NUL && !ri_upper(curc);
+ ADD_STATE_IF_MATCH(t->state);
+ break;
+
+ case NFA_LOWER_IC: /* [a-z] */
+ result = ri_lower(curc) || (ireg_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)));
+ ADD_STATE_IF_MATCH(t->state);
+ break;
+
+ case NFA_UPPER_IC: /* [A-Z] */
+ result = ri_upper(curc) || (ireg_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)));
+ ADD_STATE_IF_MATCH(t->state);
+ break;
+
+ case NFA_BACKREF1:
+ case NFA_BACKREF2:
+ case NFA_BACKREF3:
+ case NFA_BACKREF4:
+ case NFA_BACKREF5:
+ case NFA_BACKREF6:
+ case NFA_BACKREF7:
+ case NFA_BACKREF8:
+ case NFA_BACKREF9:
+ case NFA_ZREF1:
+ case NFA_ZREF2:
+ case NFA_ZREF3:
+ case NFA_ZREF4:
+ case NFA_ZREF5:
+ case NFA_ZREF6:
+ case NFA_ZREF7:
+ case NFA_ZREF8:
+ case NFA_ZREF9:
+ /* \1 .. \9 \z1 .. \z9 */
+ {
+ int subidx;
+ int bytelen;
+
+ if (t->state->c <= NFA_BACKREF9) {
+ subidx = t->state->c - NFA_BACKREF1 + 1;
+ result = match_backref(&t->subs.norm, subidx, &bytelen);
+ } else {
+ subidx = t->state->c - NFA_ZREF1 + 1;
+ result = match_zref(subidx, &bytelen);
+ }
+
+ if (result) {
+ if (bytelen == 0) {
+ /* empty match always works, output of NFA_SKIP to be
+ * used next */
+ add_here = TRUE;
+ add_state = t->state->out->out;
+ } else if (bytelen <= clen) {
+ /* match current character, jump ahead to out of
+ * NFA_SKIP */
+ add_state = t->state->out->out;
+ add_off = clen;
+ } else {
+ /* skip over the matched characters, set character
+ * count in NFA_SKIP */
+ add_state = t->state->out;
+ add_off = bytelen;
+ add_count = bytelen - clen;
+ }
+ }
+ break;
+ }
+ case NFA_SKIP:
+ /* character of previous matching \1 .. \9 or \@> */
+ if (t->count - clen <= 0) {
+ /* end of match, go to what follows */
+ add_state = t->state->out;
+ add_off = clen;
+ } else {
+ /* add state again with decremented count */
+ add_state = t->state;
+ add_off = 0;
+ add_count = t->count - clen;
+ }
+ break;
+
+ case NFA_LNUM:
+ case NFA_LNUM_GT:
+ case NFA_LNUM_LT:
+ result = (REG_MULTI &&
+ nfa_re_num_cmp(t->state->val, t->state->c - NFA_LNUM,
+ (long_u)(reglnum + reg_firstlnum)));
+ if (result) {
+ add_here = TRUE;
+ add_state = t->state->out;
+ }
+ break;
+
+ case NFA_COL:
+ case NFA_COL_GT:
+ case NFA_COL_LT:
+ result = nfa_re_num_cmp(t->state->val, t->state->c - NFA_COL,
+ (long_u)(reginput - regline) + 1);
+ if (result) {
+ add_here = TRUE;
+ add_state = t->state->out;
+ }
+ break;
+
+ case NFA_VCOL:
+ case NFA_VCOL_GT:
+ case NFA_VCOL_LT:
+ result = nfa_re_num_cmp(t->state->val, t->state->c - NFA_VCOL,
+ (long_u)win_linetabsize(
+ reg_win == NULL ? curwin : reg_win,
+ regline, (colnr_T)(reginput - regline)) + 1);
+ if (result) {
+ add_here = TRUE;
+ add_state = t->state->out;
+ }
+ break;
+
+ case NFA_MARK:
+ case NFA_MARK_GT:
+ case NFA_MARK_LT:
+ {
+ pos_T *pos = getmark_buf(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->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
+ ? t->state->c == NFA_MARK_GT
+ : t->state->c == NFA_MARK_LT)));
+ if (result) {
+ add_here = TRUE;
+ add_state = t->state->out;
+ }
+ break;
+ }
+
+ case NFA_CURSOR:
+ result = (reg_win != NULL
+ && (reglnum + reg_firstlnum == reg_win->w_cursor.lnum)
+ && ((colnr_T)(reginput - regline)
+ == reg_win->w_cursor.col));
+ if (result) {
+ add_here = TRUE;
+ add_state = t->state->out;
+ }
+ break;
+
+ case NFA_VISUAL:
+ result = reg_match_visual();
+ if (result) {
+ add_here = TRUE;
+ add_state = t->state->out;
+ }
+ break;
+
+ case NFA_MOPEN1:
+ case NFA_MOPEN2:
+ case NFA_MOPEN3:
+ case NFA_MOPEN4:
+ case NFA_MOPEN5:
+ case NFA_MOPEN6:
+ case NFA_MOPEN7:
+ case NFA_MOPEN8:
+ case NFA_MOPEN9:
+ case NFA_ZOPEN:
+ case NFA_ZOPEN1:
+ case NFA_ZOPEN2:
+ case NFA_ZOPEN3:
+ case NFA_ZOPEN4:
+ case NFA_ZOPEN5:
+ case NFA_ZOPEN6:
+ case NFA_ZOPEN7:
+ case NFA_ZOPEN8:
+ case NFA_ZOPEN9:
+ case NFA_NOPEN:
+ case NFA_ZSTART:
+ /* These states are only added to be able to bail out when
+ * they are added again, nothing is to be done. */
+ break;
+
+ default: /* regular character */
+ {
+ int c = t->state->c;
+
+#ifdef REGEXP_DEBUG
+ if (c < 0)
+ EMSGN("INTERNAL: Negative state char: %ld", c);
+#endif
+ result = (c == curc);
+
+ if (!result && ireg_ic)
+ result = MB_TOLOWER(c) == MB_TOLOWER(curc);
+ /* If there is a composing character which is not being
+ * ignored there can be no match. Match with composing
+ * character uses NFA_COMPOSING above. */
+ if (result && enc_utf8 && !ireg_icombine
+ && clen != utf_char2len(curc))
+ result = FALSE;
+ ADD_STATE_IF_MATCH(t->state);
+ break;
+ }
+
+ } /* switch (t->state->c) */
+
+ if (add_state != NULL) {
+ nfa_pim_T *pim;
+ nfa_pim_T pim_copy;
+
+ if (t->pim.result == NFA_PIM_UNUSED)
+ pim = NULL;
+ else
+ pim = &t->pim;
+
+ /* Handle the postponed invisible match if the match might end
+ * without advancing and before the end of the line. */
+ if (pim != NULL && (clen == 0 || match_follows(add_state, 0))) {
+ if (pim->result == NFA_PIM_TODO) {
+#ifdef ENABLE_LOG
+ fprintf(log_fd, "\n");
+ fprintf(log_fd, "==================================\n");
+ fprintf(log_fd, "Postponed recursive nfa_regmatch()\n");
+ fprintf(log_fd, "\n");
+#endif
+ result = recursive_regmatch(pim->state, pim,
+ prog, submatch, m, &listids);
+ pim->result = result ? NFA_PIM_MATCH : NFA_PIM_NOMATCH;
+ /* for \@! and \@<! it is a match when the result is
+ * FALSE */
+ if (result != (pim->state->c == NFA_START_INVISIBLE_NEG
+ || pim->state->c == NFA_START_INVISIBLE_NEG_FIRST
+ || pim->state->c
+ == NFA_START_INVISIBLE_BEFORE_NEG
+ || pim->state->c
+ == NFA_START_INVISIBLE_BEFORE_NEG_FIRST)) {
+ /* Copy submatch info from the recursive call */
+ copy_sub_off(&pim->subs.norm, &m->norm);
+ if (nfa_has_zsubexpr)
+ copy_sub_off(&pim->subs.synt, &m->synt);
+ }
+ } else {
+ result = (pim->result == NFA_PIM_MATCH);
+#ifdef ENABLE_LOG
+ fprintf(log_fd, "\n");
+ fprintf(
+ log_fd,
+ "Using previous recursive nfa_regmatch() result, result == %d\n",
+ pim->result);
+ fprintf(log_fd, "MATCH = %s\n", result == TRUE ? "OK" : "FALSE");
+ fprintf(log_fd, "\n");
+#endif
+ }
+
+ /* for \@! and \@<! it is a match when result is FALSE */
+ if (result != (pim->state->c == NFA_START_INVISIBLE_NEG
+ || pim->state->c == NFA_START_INVISIBLE_NEG_FIRST
+ || pim->state->c
+ == NFA_START_INVISIBLE_BEFORE_NEG
+ || pim->state->c
+ == NFA_START_INVISIBLE_BEFORE_NEG_FIRST)) {
+ /* Copy submatch info from the recursive call */
+ copy_sub_off(&t->subs.norm, &pim->subs.norm);
+ if (nfa_has_zsubexpr)
+ copy_sub_off(&t->subs.synt, &pim->subs.synt);
+ } else
+ /* look-behind match failed, don't add the state */
+ continue;
+
+ /* Postponed invisible match was handled, don't add it to
+ * following states. */
+ pim = NULL;
+ }
+
+ /* If "pim" points into l->t it will become invalid when
+ * adding the state causes the list to be reallocated. Make a
+ * local copy to avoid that. */
+ if (pim == &t->pim) {
+ copy_pim(&pim_copy, pim);
+ pim = &pim_copy;
+ }
+
+ if (add_here)
+ addstate_here(thislist, add_state, &t->subs, pim, &listidx);
+ else {
+ addstate(nextlist, add_state, &t->subs, pim, add_off);
+ if (add_count > 0)
+ nextlist->t[nextlist->n - 1].count = add_count;
+ }
+ }
+
+ } /* for (thislist = thislist; thislist->state; thislist++) */
+
+ /* Look for the start of a match in the current position by adding the
+ * start state to the list of states.
+ * The first found match is the leftmost one, thus the order of states
+ * matters!
+ * Do not add the start state in recursive calls of nfa_regmatch(),
+ * because recursive calls should only start in the first position.
+ * Unless "nfa_endp" is not NULL, then we match the end position.
+ * Also don't start a match past the first line. */
+ if (nfa_match == FALSE
+ && ((toplevel
+ && reglnum == 0
+ && clen != 0
+ && (ireg_maxcol == 0
+ || (colnr_T)(reginput - regline) < ireg_maxcol))
+ || (nfa_endp != NULL
+ && (REG_MULTI
+ ? (reglnum < nfa_endp->se_u.pos.lnum
+ || (reglnum == nfa_endp->se_u.pos.lnum
+ && (int)(reginput - regline)
+ < nfa_endp->se_u.pos.col))
+ : reginput < nfa_endp->se_u.ptr)))) {
+#ifdef ENABLE_LOG
+ fprintf(log_fd, "(---) STARTSTATE\n");
+#endif
+ /* Inline optimized code for addstate() if we know the state is
+ * the first MOPEN. */
+ if (toplevel) {
+ int add = TRUE;
+ int c;
+
+ if (prog->regstart != NUL && clen != 0) {
+ if (nextlist->n == 0) {
+ colnr_T col = (colnr_T)(reginput - regline) + clen;
+
+ /* Nextlist is empty, we can skip ahead to the
+ * character that must appear at the start. */
+ if (skip_to_start(prog->regstart, &col) == FAIL)
+ break;
+#ifdef ENABLE_LOG
+ fprintf(log_fd, " Skipping ahead %d bytes to regstart\n",
+ col - ((colnr_T)(reginput - regline) + clen));
+#endif
+ reginput = regline + col - clen;
+ } else {
+ /* 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 || MB_TOLOWER(c)
+ != MB_TOLOWER(prog->regstart))) {
+#ifdef ENABLE_LOG
+ fprintf(log_fd,
+ " Skipping start state, regstart does not match\n");
+#endif
+ add = FALSE;
+ }
+ }
+ }
+
+ if (add) {
+ if (REG_MULTI)
+ m->norm.list.multi[0].start.col =
+ (colnr_T)(reginput - regline) + clen;
+ else
+ m->norm.list.line[0].start = reginput + clen;
+ addstate(nextlist, start->out, m, NULL, clen);
+ }
+ } else
+ addstate(nextlist, start, m, NULL, clen);
+ }
+
+#ifdef ENABLE_LOG
+ fprintf(log_fd, ">>> Thislist had %d states available: ", thislist->n);
+ {
+ int i;
+
+ for (i = 0; i < thislist->n; i++)
+ fprintf(log_fd, "%d ", abs(thislist->t[i].state->id));
+ }
+ fprintf(log_fd, "\n");
+#endif
+
+nextchar:
+ /* Advance to the next character, or advance to the next line, or
+ * finish. */
+ if (clen != 0)
+ reginput += clen;
+ else if (go_to_nextline || (nfa_endp != NULL && REG_MULTI
+ && reglnum < nfa_endp->se_u.pos.lnum))
+ reg_nextline();
+ else
+ break;
+ }
+
+#ifdef ENABLE_LOG
+ if (log_fd != stderr)
+ fclose(log_fd);
+ log_fd = NULL;
+#endif
+
+theend:
+ /* Free memory */
+ vim_free(list[0].t);
+ vim_free(list[1].t);
+ vim_free(listids);
+#undef ADD_STATE_IF_MATCH
+#ifdef NFA_REGEXP_DEBUG_LOG
+ fclose(debug);
+#endif
+
+ return nfa_match;
+}
+
+/*
+ * Try match of "prog" with at regline["col"].
+ * Returns 0 for failure, number of lines contained in the match otherwise.
+ */
+static long nfa_regtry(prog, col)
+nfa_regprog_T *prog;
+colnr_T col;
+{
+ int i;
+ regsubs_T subs, m;
+ nfa_state_T *start = prog->start;
+#ifdef ENABLE_LOG
+ FILE *f;
+#endif
+
+ reginput = regline + col;
+
+#ifdef ENABLE_LOG
+ f = fopen(NFA_REGEXP_RUN_LOG, "a");
+ if (f != NULL) {
+ fprintf(f,
+ "\n\n\t=======================================================\n");
+#ifdef REGEXP_DEBUG
+ fprintf(f, "\tRegexp is \"%s\"\n", nfa_regengine.expr);
+#endif
+ fprintf(f, "\tInput text is \"%s\" \n", reginput);
+ fprintf(f, "\t=======================================================\n\n");
+ nfa_print_state(f, start);
+ fprintf(f, "\n\n");
+ fclose(f);
+ } else
+ EMSG(_("Could not open temporary log file for writing "));
+#endif
+
+ clear_sub(&subs.norm);
+ clear_sub(&m.norm);
+ clear_sub(&subs.synt);
+ clear_sub(&m.synt);
+
+ if (nfa_regmatch(prog, start, &subs, &m) == FALSE)
+ return 0;
+
+ cleanup_subexpr();
+ if (REG_MULTI) {
+ for (i = 0; i < subs.norm.in_use; i++) {
+ reg_startpos[i] = subs.norm.list.multi[i].start;
+ reg_endpos[i] = subs.norm.list.multi[i].end;
+ }
+
+ if (reg_startpos[0].lnum < 0) {
+ reg_startpos[0].lnum = 0;
+ reg_startpos[0].col = col;
+ }
+ 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;
+ }
+
+ if (reg_startp[0] == NULL)
+ reg_startp[0] = regline + col;
+ if (reg_endp[0] == NULL)
+ reg_endp[0] = reginput;
+ }
+
+ /* Package any found \z(...\) matches for export. Default is none. */
+ unref_extmatch(re_extmatch_out);
+ re_extmatch_out = NULL;
+
+ if (prog->reghasz == REX_SET) {
+ cleanup_zsubexpr();
+ re_extmatch_out = make_extmatch();
+ for (i = 0; i < subs.synt.in_use; i++) {
+ if (REG_MULTI) {
+ struct multipos *mpos = &subs.synt.list.multi[i];
+
+ /* Only accept single line matches. */
+ if (mpos->start.lnum >= 0 && mpos->start.lnum == mpos->end.lnum)
+ re_extmatch_out->matches[i] =
+ vim_strnsave(reg_getline(mpos->start.lnum)
+ + mpos->start.col,
+ mpos->end.col - mpos->start.col);
+ } else {
+ struct linepos *lpos = &subs.synt.list.line[i];
+
+ if (lpos->start != NULL && lpos->end != NULL)
+ re_extmatch_out->matches[i] =
+ vim_strnsave(lpos->start,
+ (int)(lpos->end - lpos->start));
+ }
+ }
+ }
+
+ return 1 + reglnum;
+}
+
+/*
+ * Match a regexp against a string ("line" points to the string) or multiple
+ * lines ("line" is NULL, use reg_getline()).
+ *
+ * Returns 0 for failure, number of lines contained in the match otherwise.
+ */
+static long nfa_regexec_both(line, startcol)
+char_u *line;
+colnr_T startcol; /* column to start looking for match */
+{
+ nfa_regprog_T *prog;
+ long retval = 0L;
+ int i;
+ 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;
+ } else {
+ prog = (nfa_regprog_T *)reg_match->regprog;
+ reg_startp = reg_match->startp;
+ reg_endp = reg_match->endp;
+ }
+
+ /* Be paranoid... */
+ if (prog == NULL || line == NULL) {
+ EMSG(_(e_null));
+ 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 "\Z" overrule value of ireg_icombine */
+ if (prog->regflags & RF_ICOMBINE)
+ ireg_icombine = TRUE;
+
+ regline = line;
+ reglnum = 0; /* relative to line */
+
+ nfa_has_zend = prog->has_zend;
+ nfa_has_backref = prog->has_backref;
+ nfa_nsubexpr = prog->nsubexp;
+ nfa_listid = 1;
+ nfa_alt_listid = 2;
+#ifdef REGEXP_DEBUG
+ nfa_regengine.expr = prog->pattern;
+#endif
+
+ if (prog->reganch && col > 0)
+ return 0L;
+
+ need_clear_subexpr = TRUE;
+ /* Clear the external match subpointers if necessary. */
+ if (prog->reghasz == REX_SET) {
+ nfa_has_zsubexpr = TRUE;
+ need_clear_zsubexpr = TRUE;
+ } else
+ nfa_has_zsubexpr = FALSE;
+
+ if (prog->regstart != NUL) {
+ /* Skip ahead until a character we know the match must start with.
+ * When there is none there is no match. */
+ 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
+ )
+ 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)
+ goto theend;
+
+ nstate = prog->nstate;
+ for (i = 0; i < nstate; ++i) {
+ prog->state[i].id = i;
+ prog->state[i].lastlist[0] = 0;
+ prog->state[i].lastlist[1] = 0;
+ }
+
+ retval = nfa_regtry(prog, col);
+
+#ifdef REGEXP_DEBUG
+ nfa_regengine.expr = NULL;
+#endif
+
+theend:
+ return retval;
+}
+
+/*
+ * Compile a regular expression into internal code for the NFA matcher.
+ * Returns the program in allocated space. Returns NULL for an error.
+ */
+static regprog_T * nfa_regcomp(expr, re_flags)
+char_u *expr;
+int re_flags;
+{
+ nfa_regprog_T *prog = NULL;
+ size_t prog_size;
+ int *postfix;
+
+ if (expr == NULL)
+ return NULL;
+
+#ifdef REGEXP_DEBUG
+ nfa_regengine.expr = expr;
+#endif
+
+ init_class_tab();
+
+ if (nfa_regcomp_start(expr, re_flags) == FAIL)
+ return NULL;
+
+ /* Build postfix form of the regexp. Needed to build the NFA
+ * (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: %ld",
+ post_end - post_start);
+ goto fail; /* Cascaded (syntax?) error */
+ }
+
+ /*
+ * In order to build the NFA, we parse the input regexp twice:
+ * 1. first pass to count size (so we can allocate space)
+ * 2. second to emit code
+ */
+#ifdef ENABLE_LOG
+ {
+ 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);
+ fclose(f);
+ }
+ }
+#endif
+
+ /*
+ * PASS 1
+ * Count number of NFA states in "nstate". Do not build the NFA.
+ */
+ post2nfa(postfix, post_ptr, TRUE);
+
+ /* allocate the regprog with space for the compiled regexp */
+ prog_size = sizeof(nfa_regprog_T) + sizeof(nfa_state_T) * (nstate - 1);
+ prog = (nfa_regprog_T *)lalloc(prog_size, TRUE);
+ if (prog == NULL)
+ goto fail;
+ state_ptr = prog->state;
+
+ /*
+ * PASS 2
+ * Build the NFA
+ */
+ prog->start = post2nfa(postfix, post_ptr, FALSE);
+ if (prog->start == NULL)
+ goto fail;
+
+ prog->regflags = regflags;
+ prog->engine = &nfa_regengine;
+ prog->nstate = nstate;
+ prog->has_zend = nfa_has_zend;
+ prog->has_backref = nfa_has_backref;
+ prog->nsubexp = regnpar;
+
+ nfa_postprocess(prog);
+
+ prog->reganch = nfa_get_reganch(prog->start, 0);
+ prog->regstart = nfa_get_regstart(prog->start, 0);
+ prog->match_text = nfa_get_match_text(prog->start);
+
+#ifdef ENABLE_LOG
+ nfa_postfix_dump(expr, OK);
+ nfa_dump(prog);
+#endif
+ /* Remember whether this pattern has any \z specials in it. */
+ prog->reghasz = re_has_z;
+#ifdef REGEXP_DEBUG
+ prog->pattern = vim_strsave(expr);
+ nfa_regengine.expr = NULL;
+#endif
+
+out:
+ vim_free(post_start);
+ post_start = post_ptr = post_end = NULL;
+ state_ptr = NULL;
+ return (regprog_T *)prog;
+
+fail:
+ vim_free(prog);
+ prog = NULL;
+#ifdef ENABLE_LOG
+ nfa_postfix_dump(expr, FAIL);
+#endif
+#ifdef REGEXP_DEBUG
+ nfa_regengine.expr = NULL;
+#endif
+ goto out;
+}
+
+/*
+ * Free a compiled regexp program, returned by nfa_regcomp().
+ */
+static void nfa_regfree(prog)
+regprog_T *prog;
+{
+ if (prog != NULL) {
+ vim_free(((nfa_regprog_T *)prog)->match_text);
+#ifdef REGEXP_DEBUG
+ vim_free(((nfa_regprog_T *)prog)->pattern);
+#endif
+ vim_free(prog);
+ }
+}
+
+/*
+ * Match a regexp against a string.
+ * "rmp->regprog" is a compiled regexp as returned by nfa_regcomp().
+ * Uses curbuf for line count and 'iskeyword'.
+ *
+ * Return TRUE if there is a match, FALSE if not.
+ */
+static int nfa_regexec(rmp, line, col)
+regmatch_T *rmp;
+char_u *line; /* string to match against */
+colnr_T col; /* column to start looking for match */
+{
+ reg_match = rmp;
+ reg_mmatch = NULL;
+ reg_maxline = 0;
+ reg_line_lbr = FALSE;
+ reg_buf = curbuf;
+ reg_win = NULL;
+ ireg_ic = rmp->rm_ic;
+ ireg_icombine = FALSE;
+ ireg_maxcol = 0;
+ return nfa_regexec_both(line, col) != 0;
+}
+
+#if defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) \
+ || defined(FIND_REPLACE_DIALOG) || defined(PROTO)
+
+static int nfa_regexec_nl __ARGS((regmatch_T *rmp, char_u *line, colnr_T col));
+
+/*
+ * Like nfa_regexec(), but consider a "\n" in "line" to be a line break.
+ */
+static int nfa_regexec_nl(rmp, line, col)
+regmatch_T *rmp;
+char_u *line; /* string to match against */
+colnr_T col; /* column to start looking for match */
+{
+ reg_match = rmp;
+ reg_mmatch = NULL;
+ reg_maxline = 0;
+ reg_line_lbr = TRUE;
+ reg_buf = curbuf;
+ reg_win = NULL;
+ ireg_ic = rmp->rm_ic;
+ ireg_icombine = FALSE;
+ ireg_maxcol = 0;
+ return nfa_regexec_both(line, col) != 0;
+}
+#endif
+
+
+/*
+ * Match a regexp against multiple lines.
+ * "rmp->regprog" is a compiled regexp as returned by vim_regcomp().
+ * Uses curbuf for line count and 'iskeyword'.
+ *
+ * Return zero if there is no match. Return number of lines contained in the
+ * match otherwise.
+ *
+ * Note: the body is the same as bt_regexec() except for nfa_regexec_both()
+ *
+ * ! Also NOTE : match may actually be in another line. e.g.:
+ * when r.e. is \nc, cursor is at 'a' and the text buffer looks like
+ *
+ * +-------------------------+
+ * |a |
+ * |b |
+ * |c |
+ * | |
+ * +-------------------------+
+ *
+ * then nfa_regexec_multi() returns 3. while the original
+ * vim_regexec_multi() returns 0 and a second call at line 2 will return 2.
+ *
+ * FIXME if this behavior is not compatible.
+ */
+static long nfa_regexec_multi(rmp, win, buf, lnum, col, tm)
+regmmatch_T *rmp;
+win_T *win; /* window in which to search or NULL */
+buf_T *buf; /* buffer in which to search */
+linenr_T lnum; /* nr of line to start looking for match */
+colnr_T col; /* column to start looking for match */
+proftime_T *tm UNUSED; /* timeout limit or NULL */
+{
+ 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;
+
+ return nfa_regexec_both(NULL, col);
+}
+
+#ifdef REGEXP_DEBUG
+# undef ENABLE_LOG
+#endif
diff --git a/src/screen.c b/src/screen.c
new file mode 100644
index 0000000000..cb04ab6964
--- /dev/null
+++ b/src/screen.c
@@ -0,0 +1,7936 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * 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.
+ */
+
+/*
+ * 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 line 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.
+ */
+
+#include "vim.h"
+
+#define MB_FILLER_CHAR '<' /* character used when a double-width character
+ * doesn't fit. */
+
+/*
+ * The attributes that are actually active for writing to the screen.
+ */
+static int screen_attr = 0;
+
+/*
+ * Positioning the cursor is reduced by remembering the last position.
+ * Mostly used by windgoto() and screen_char().
+ */
+static int screen_cur_row, screen_cur_col; /* last known cursor position */
+
+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;
+
+static void win_update __ARGS((win_T *wp));
+static void win_draw_end __ARGS((win_T *wp, int c1, int c2, int row, int endrow,
+ hlf_T hl));
+static void fold_line __ARGS((win_T *wp, long fold_count, foldinfo_T *foldinfo,
+ linenr_T lnum,
+ int row));
+static void fill_foldcolumn __ARGS((char_u *p, win_T *wp, int closed,
+ linenr_T lnum));
+static void copy_text_attr __ARGS((int off, char_u *buf, int len, int attr));
+static int win_line __ARGS((win_T *, linenr_T, int, int, int nochange));
+static int char_needs_redraw __ARGS((int off_from, int off_to, int cols));
+static void screen_line __ARGS((int row, int coloff, int endcol,
+ int clear_width,
+ int rlflag));
+# define SCREEN_LINE(r, o, e, c, rl) screen_line((r), (o), (e), (c), (rl))
+static void draw_vsep_win __ARGS((win_T *wp, int row));
+static void redraw_custom_statusline __ARGS((win_T *wp));
+#define SEARCH_HL_PRIORITY 0
+static void start_search_hl __ARGS((void));
+static void end_search_hl __ARGS((void));
+static void init_search_hl __ARGS((win_T *wp));
+static void prepare_search_hl __ARGS((win_T *wp, linenr_T lnum));
+static void next_search_hl __ARGS((win_T *win, match_T *shl, linenr_T lnum,
+ colnr_T mincol));
+static void screen_start_highlight __ARGS((int attr));
+static void screen_char __ARGS((unsigned off, int row, int col));
+static void screen_char_2 __ARGS((unsigned off, int row, int col));
+static void screenclear2 __ARGS((void));
+static void lineclear __ARGS((unsigned off, int width));
+static void lineinvalid __ARGS((unsigned off, int width));
+static void linecopy __ARGS((int to, int from, win_T *wp));
+static void redraw_block __ARGS((int row, int end, win_T *wp));
+static int win_do_lines __ARGS((win_T *wp, int row, int line_count,
+ int mayclear,
+ int del));
+static void win_rest_invalid __ARGS((win_T *wp));
+static void msg_pos_mode __ARGS((void));
+static void draw_tabline __ARGS((void));
+static int fillchar_status __ARGS((int *attr, int is_curwin));
+static int fillchar_vsep __ARGS((int *attr));
+static void win_redr_custom __ARGS((win_T *wp, int draw_ruler));
+static void win_redr_ruler __ARGS((win_T *wp, int always));
+
+/* Ugly global: overrule attribute used by screen_char() */
+static int screen_char_attr = 0;
+
+/*
+ * Redraw the current window later, with update_screen(type).
+ * Set must_redraw only if not already set to a higher value.
+ * e.g. if must_redraw is CLEAR, type NOT_VALID will do nothing.
+ */
+void redraw_later(type)
+int type;
+{
+ redraw_win_later(curwin, type);
+}
+
+void redraw_win_later(wp, type)
+win_T *wp;
+int type;
+{
+ if (wp->w_redr_type < type) {
+ wp->w_redr_type = type;
+ if (type >= NOT_VALID)
+ wp->w_lines_valid = 0;
+ if (must_redraw < type) /* must_redraw is the maximum of all windows */
+ must_redraw = 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() {
+ 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(type)
+int type;
+{
+ win_T *wp;
+
+ FOR_ALL_WINDOWS(wp)
+ {
+ redraw_win_later(wp, type);
+ }
+}
+
+/*
+ * Mark all windows that are editing the current buffer to be updated later.
+ */
+void redraw_curbuf_later(type)
+int type;
+{
+ redraw_buf_later(curbuf, type);
+}
+
+void redraw_buf_later(buf, type)
+buf_T *buf;
+int type;
+{
+ win_T *wp;
+
+ FOR_ALL_WINDOWS(wp)
+ {
+ if (wp->w_buffer == buf)
+ redraw_win_later(wp, type);
+ }
+}
+
+/*
+ * Redraw as soon as possible. When the command line is not scrolled redraw
+ * right away and restore what was on the command line.
+ * Return a code indicating what happened.
+ */
+int redraw_asap(type)
+int type;
+{
+ int rows;
+ int r;
+ int ret = 0;
+ schar_T *screenline; /* copy from ScreenLines[] */
+ sattr_T *screenattr; /* copy from ScreenAttrs[] */
+ int i;
+ u8char_T *screenlineUC = NULL; /* copy from ScreenLinesUC[] */
+ u8char_T *screenlineC[MAX_MCO]; /* copy from ScreenLinesC[][] */
+ schar_T *screenline2 = NULL; /* copy from ScreenLines2[] */
+
+ redraw_later(type);
+ if (msg_scrolled || (State != NORMAL && State != NORMAL_BUSY))
+ return ret;
+
+ /* Allocate space to save the text displayed in the command line area. */
+ rows = Rows - cmdline_row;
+ screenline = (schar_T *)lalloc(
+ (long_u)(rows * Columns * sizeof(schar_T)), FALSE);
+ screenattr = (sattr_T *)lalloc(
+ (long_u)(rows * Columns * sizeof(sattr_T)), FALSE);
+ if (screenline == NULL || screenattr == NULL)
+ ret = 2;
+ if (enc_utf8) {
+ screenlineUC = (u8char_T *)lalloc(
+ (long_u)(rows * Columns * sizeof(u8char_T)), FALSE);
+ if (screenlineUC == NULL)
+ ret = 2;
+ for (i = 0; i < p_mco; ++i) {
+ screenlineC[i] = (u8char_T *)lalloc(
+ (long_u)(rows * Columns * sizeof(u8char_T)), FALSE);
+ if (screenlineC[i] == NULL)
+ ret = 2;
+ }
+ }
+ if (enc_dbcs == DBCS_JPNU) {
+ screenline2 = (schar_T *)lalloc(
+ (long_u)(rows * Columns * sizeof(schar_T)), FALSE);
+ if (screenline2 == NULL)
+ ret = 2;
+ }
+
+ if (ret != 2) {
+ /* Save the text displayed in the command line area. */
+ for (r = 0; r < rows; ++r) {
+ mch_memmove(screenline + r * Columns,
+ ScreenLines + LineOffset[cmdline_row + r],
+ (size_t)Columns * sizeof(schar_T));
+ mch_memmove(screenattr + r * Columns,
+ ScreenAttrs + LineOffset[cmdline_row + r],
+ (size_t)Columns * sizeof(sattr_T));
+ if (enc_utf8) {
+ mch_memmove(screenlineUC + r * Columns,
+ ScreenLinesUC + LineOffset[cmdline_row + r],
+ (size_t)Columns * sizeof(u8char_T));
+ for (i = 0; i < p_mco; ++i)
+ mch_memmove(screenlineC[i] + r * Columns,
+ ScreenLinesC[r] + LineOffset[cmdline_row + r],
+ (size_t)Columns * sizeof(u8char_T));
+ }
+ if (enc_dbcs == DBCS_JPNU)
+ mch_memmove(screenline2 + r * Columns,
+ ScreenLines2 + LineOffset[cmdline_row + r],
+ (size_t)Columns * sizeof(schar_T));
+ }
+
+ update_screen(0);
+ ret = 3;
+
+ if (must_redraw == 0) {
+ int off = (int)(current_ScreenLine - ScreenLines);
+
+ /* Restore the text displayed in the command line area. */
+ for (r = 0; r < rows; ++r) {
+ mch_memmove(current_ScreenLine,
+ screenline + r * Columns,
+ (size_t)Columns * sizeof(schar_T));
+ mch_memmove(ScreenAttrs + off,
+ screenattr + r * Columns,
+ (size_t)Columns * sizeof(sattr_T));
+ if (enc_utf8) {
+ mch_memmove(ScreenLinesUC + off,
+ screenlineUC + r * Columns,
+ (size_t)Columns * sizeof(u8char_T));
+ for (i = 0; i < p_mco; ++i)
+ mch_memmove(ScreenLinesC[i] + off,
+ screenlineC[i] + r * Columns,
+ (size_t)Columns * sizeof(u8char_T));
+ }
+ if (enc_dbcs == DBCS_JPNU)
+ mch_memmove(ScreenLines2 + off,
+ screenline2 + r * Columns,
+ (size_t)Columns * sizeof(schar_T));
+ SCREEN_LINE(cmdline_row + r, 0, Columns, Columns, FALSE);
+ }
+ ret = 4;
+ }
+ }
+
+ vim_free(screenline);
+ vim_free(screenattr);
+ if (enc_utf8) {
+ vim_free(screenlineUC);
+ for (i = 0; i < p_mco; ++i)
+ vim_free(screenlineC[i]);
+ }
+ if (enc_dbcs == DBCS_JPNU)
+ vim_free(screenline2);
+
+ /* Show the intro message when appropriate. */
+ maybe_intro_message();
+
+ setcursor();
+
+ return ret;
+}
+
+/*
+ * Changed something in the current window, at buffer line "lnum", that
+ * requires that line and possibly other lines to be redrawn.
+ * Used when entering/leaving Insert mode with the cursor on a folded line.
+ * Used to remove the "$" from a change command.
+ * Note that when also inserting/deleting lines w_redraw_top and w_redraw_bot
+ * may become invalid and the whole window will have to be redrawn.
+ */
+void redrawWinline(lnum, invalid)
+linenr_T lnum;
+int invalid UNUSED; /* window line height is invalid now */
+{
+ 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 defined(FEAT_RUBY) || defined(FEAT_PERL) || defined(FEAT_VISUAL) || \
+ (defined(FEAT_CLIPBOARD) && defined(FEAT_X11)) || defined(PROTO)
+/*
+ * update all windows that are editing the current buffer
+ */
+void update_curbuf(type)
+int type;
+{
+ redraw_curbuf_later(type);
+ update_screen(type);
+}
+#endif
+
+/*
+ * 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.
+ */
+void update_screen(type)
+int type;
+{
+ win_T *wp;
+ static int did_intro = FALSE;
+ int did_one;
+
+ /* Don't do anything if the screen structures are (not yet) valid. */
+ if (!screen_valid(TRUE))
+ return;
+
+ if (must_redraw) {
+ if (type < must_redraw) /* use maximal type */
+ type = must_redraw;
+
+ /* must_redraw is reset here, so that when we run into some weird
+ * reason to redraw while busy redrawing (e.g., asynchronous
+ * scrolling), or update_topline() in win_update() will cause a
+ * scroll, the screen will be redrawn later or in win_update(). */
+ must_redraw = 0;
+ }
+
+ /* Need to update w_lines[]. */
+ if (curwin->w_lines_valid == 0 && type < NOT_VALID)
+ type = NOT_VALID;
+
+ /* Postpone the redrawing when it's not needed and when being called
+ * recursively. */
+ if (!redrawing() || updating_screen) {
+ redraw_later(type); /* remember type for next time */
+ must_redraw = type;
+ if (type > INVERTED_ALL)
+ curwin->w_lines_valid = 0; /* don't use w_lines[].wl_size now */
+ return;
+ }
+
+ updating_screen = TRUE;
+ ++display_tick; /* let syntax code know we're in a next round of
+ * display updating */
+
+ /*
+ * 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 */
+ type = CLEAR;
+ else if (type != CLEAR) {
+ check_for_delay(FALSE);
+ if (screen_ins_lines(0, 0, msg_scrolled, (int)Rows, NULL) == FAIL)
+ type = CLEAR;
+ FOR_ALL_WINDOWS(wp)
+ {
+ if (W_WINROW(wp) < msg_scrolled) {
+ if (W_WINROW(wp) + wp->w_height > msg_scrolled
+ && wp->w_redr_type < REDRAW_TOP
+ && wp->w_lines_valid > 0
+ && wp->w_topline == wp->w_lines[0].wl_lnum) {
+ wp->w_upd_rows = msg_scrolled - W_WINROW(wp);
+ wp->w_redr_type = REDRAW_TOP;
+ } else {
+ wp->w_redr_type = NOT_VALID;
+ if (W_WINROW(wp) + wp->w_height + W_STATUS_HEIGHT(wp)
+ <= msg_scrolled)
+ wp->w_redr_status = TRUE;
+ }
+ }
+ }
+ redraw_cmdline = TRUE;
+ redraw_tabline = TRUE;
+ }
+ msg_scrolled = 0;
+ need_wait_return = FALSE;
+ }
+
+ /* reset cmdline_row now (may have been changed temporarily) */
+ compute_cmdrow();
+
+ /* Check for changed highlighting */
+ if (need_highlight_changed)
+ highlight_changed();
+
+ if (type == CLEAR) { /* first clear screen */
+ screenclear(); /* will reset clear_cmdline */
+ type = NOT_VALID;
+ }
+
+ if (clear_cmdline) /* going to clear cmdline (done below) */
+ check_for_delay(FALSE);
+
+ /* Force redraw when width of 'number' or 'relativenumber' column
+ * changes. */
+ if (curwin->w_redr_type < NOT_VALID
+ && curwin->w_nrwidth != ((curwin->w_p_nu || curwin->w_p_rnu)
+ ? number_width(curwin) : 0))
+ curwin->w_redr_type = NOT_VALID;
+
+ /*
+ * Only start redrawing if there is really something to do.
+ */
+ if (type == INVERTED)
+ update_curswant();
+ if (curwin->w_redr_type < type
+ && !((type == VALID
+ && curwin->w_lines[0].wl_valid
+ && curwin->w_topfill == curwin->w_old_topfill
+ && curwin->w_botfill == curwin->w_old_botfill
+ && curwin->w_topline == curwin->w_lines[0].wl_lnum)
+ || (type == INVERTED
+ && VIsual_active
+ && curwin->w_old_cursor_lnum == curwin->w_cursor.lnum
+ && curwin->w_old_visual_mode == VIsual_mode
+ && (curwin->w_valid & VALID_VIRTCOL)
+ && curwin->w_old_curswant == curwin->w_curswant)
+ ))
+ curwin->w_redr_type = type;
+
+ /* Redraw the tab pages line if needed. */
+ if (redraw_tabline || 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(wp)
+ {
+ if (wp->w_buffer->b_mod_set) {
+ win_T *wwp;
+
+ /* Check if we already did this buffer. */
+ for (wwp = firstwin; wwp != wp; wwp = wwp->w_next)
+ if (wwp->w_buffer == wp->w_buffer)
+ break;
+ if (
+ wwp == wp &&
+ syntax_present(wp))
+ syn_stack_apply_changes(wp->w_buffer);
+ }
+ }
+
+ /*
+ * Go from top to bottom through the windows, redrawing the ones that need
+ * it.
+ */
+ did_one = FALSE;
+ search_hl.rm.regprog = NULL;
+ FOR_ALL_WINDOWS(wp)
+ {
+ if (wp->w_redr_type != 0) {
+ cursor_off();
+ if (!did_one) {
+ did_one = TRUE;
+ start_search_hl();
+ }
+ win_update(wp);
+ }
+
+ /* redraw status line after the window to minimize cursor movement */
+ if (wp->w_redr_status) {
+ cursor_off();
+ win_redr_status(wp);
+ }
+ }
+ end_search_hl();
+ /* May need to redraw the popup menu. */
+ if (pum_visible())
+ pum_redraw();
+
+ /* Reset b_mod_set flags. Going through all windows is probably faster
+ * than going through all buffers (there could be many buffers). */
+ for (wp = firstwin; wp != NULL; wp = wp->w_next)
+ wp->w_buffer->b_mod_set = FALSE;
+
+ updating_screen = FALSE;
+
+ /* Clear or redraw the command line. Done last, because scrolling may
+ * mess up the command line. */
+ if (clear_cmdline || redraw_cmdline)
+ showmode();
+
+ /* May put up an introductory message when not editing a file */
+ if (!did_intro)
+ maybe_intro_message();
+ did_intro = TRUE;
+
+}
+
+/*
+ * Return TRUE if the cursor line in window "wp" may be concealed, according
+ * to the 'concealcursor' option.
+ */
+int conceal_cursor_line(wp)
+win_T *wp;
+{
+ int c;
+
+ if (*wp->w_p_cocu == NUL)
+ return FALSE;
+ if (get_real_state() & VISUAL)
+ c = 'v';
+ else if (State & INSERT)
+ c = 'i';
+ else if (State & NORMAL)
+ c = 'n';
+ else if (State & CMDLINE)
+ c = 'c';
+ else
+ return FALSE;
+ 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() {
+ 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);
+ }
+}
+
+void update_single_line(wp, lnum)
+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) {
+ screen_start(); /* not sure of screen cursor */
+ 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;
+}
+
+
+
+
+
+/*
+ * Update a single window.
+ *
+ * This may cause the windows below it also to be redrawn (when clearing the
+ * screen or scrolling lines).
+ *
+ * How the window is redrawn depends on wp->w_redr_type. Each type also
+ * implies the one below it.
+ * NOT_VALID redraw the whole window
+ * SOME_VALID redraw the whole window but do scroll when possible
+ * REDRAW_TOP redraw the top w_upd_rows window lines, otherwise like VALID
+ * INVERTED redraw the changed part of the Visual area
+ * INVERTED_ALL redraw the whole Visual area
+ * VALID 1. scroll up/down to adjust for a changed w_topline
+ * 2. update lines at the top when scrolled down
+ * 3. redraw changed text:
+ * - if wp->w_buffer->b_mod_set set, update lines between
+ * b_mod_top and b_mod_bot.
+ * - if wp->w_redraw_top non-zero, redraw lines between
+ * wp->w_redraw_top and wp->w_redr_bot.
+ * - continue redrawing when syntax status is invalid.
+ * 4. if scrolled up, update lines at the bottom.
+ * This results in three areas that may need updating:
+ * top: from first row to top_end (when scrolled down)
+ * mid: from mid_start to mid_end (update inversion or changed text)
+ * bot: from bot_start to last row (when scrolled up)
+ */
+static void win_update(wp)
+win_T *wp;
+{
+ buf_T *buf = wp->w_buffer;
+ int type;
+ int top_end = 0; /* Below last row of the top area that needs
+ updating. 0 when no top area updating. */
+ int mid_start = 999; /* first row of the mid area that needs
+ updating. 999 when no mid area updating. */
+ int mid_end = 0; /* Below last row of the mid area that needs
+ updating. 0 when no mid area updating. */
+ int bot_start = 999; /* first row of the bot area that needs
+ updating. 999 when no bot area updating */
+ int scrolled_down = FALSE; /* TRUE when scrolled down when
+ w_topline got smaller a bit */
+ matchitem_T *cur; /* points to the match list */
+ int top_to_mod = FALSE; /* redraw above mod_top */
+
+ int row; /* current window row to display */
+ linenr_T lnum; /* current buffer lnum to display */
+ int idx; /* current index in w_lines[] */
+ int srow; /* starting row of the current line */
+
+ int eof = FALSE; /* if TRUE, we hit the end of the file */
+ int didline = FALSE; /* if TRUE, we finished the last line */
+ int i;
+ long j;
+ 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 */
+ int did_update = DID_NONE;
+ linenr_T syntax_last_parsed = 0; /* last parsed text line */
+ linenr_T mod_top = 0;
+ linenr_T mod_bot = 0;
+ int save_got_int;
+
+ type = wp->w_redr_type;
+
+ 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) {
+ 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 */
+ draw_vsep_win(wp, 0);
+ wp->w_redr_type = 0;
+ return;
+ }
+
+ init_search_hl(wp);
+
+ /* Force redraw when width of 'number' or 'relativenumber' column
+ * changes. */
+ i = (wp->w_p_nu || wp->w_p_rnu) ? number_width(wp) : 0;
+ 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).
+ */
+ type = NOT_VALID;
+ } else {
+ /*
+ * Set mod_top to the first line that needs displaying because of
+ * changes. Set mod_bot to the first line after the changes.
+ */
+ mod_top = wp->w_redraw_top;
+ if (wp->w_redraw_bot != 0)
+ mod_bot = wp->w_redraw_bot + 1;
+ else
+ mod_bot = 0;
+ wp->w_redraw_top = 0; /* reset for next time */
+ wp->w_redraw_bot = 0;
+ if (buf->b_mod_set) {
+ if (mod_top == 0 || mod_top > buf->b_mod_top) {
+ mod_top = buf->b_mod_top;
+ /* Need to redraw lines above the change that may be included
+ * in a pattern match. */
+ if (syntax_present(wp)) {
+ mod_top -= buf->b_s.b_syn_sync_linebreaks;
+ if (mod_top < 1)
+ mod_top = 1;
+ }
+ }
+ if (mod_bot == 0 || mod_bot < buf->b_mod_bot)
+ mod_bot = buf->b_mod_bot;
+
+ /* When 'hlsearch' is on and using a multi-line search pattern, a
+ * change in one line may make the Search highlighting in a
+ * previous line invalid. Simple solution: redraw all visible
+ * lines above the change.
+ * Same for a match pattern.
+ */
+ if (search_hl.rm.regprog != NULL
+ && re_multiline(search_hl.rm.regprog))
+ top_to_mod = TRUE;
+ else {
+ cur = wp->w_match_head;
+ while (cur != NULL) {
+ if (cur->match.regprog != NULL
+ && re_multiline(cur->match.regprog)) {
+ top_to_mod = TRUE;
+ break;
+ }
+ cur = cur->next;
+ }
+ }
+ }
+ if (mod_top != 0 && hasAnyFolding(wp)) {
+ linenr_T lnumt, lnumb;
+
+ /*
+ * A change in a line can cause lines above it to become folded or
+ * unfolded. Find the top most buffer line that may be affected.
+ * If the line was previously folded and displayed, get the first
+ * line of that fold. If the line is folded now, get the first
+ * folded line. Use the minimum of these two.
+ */
+
+ /* Find last valid w_lines[] entry above mod_top. Set lnumt to
+ * the line below it. If there is no valid entry, use w_topline.
+ * Find the first valid w_lines[] entry below mod_bot. Set lnumb
+ * to this line. If there is no valid entry, use MAXLNUM. */
+ lnumt = wp->w_topline;
+ lnumb = MAXLNUM;
+ for (i = 0; i < wp->w_lines_valid; ++i)
+ if (wp->w_lines[i].wl_valid) {
+ if (wp->w_lines[i].wl_lastlnum < mod_top)
+ lnumt = wp->w_lines[i].wl_lastlnum + 1;
+ if (lnumb == MAXLNUM && wp->w_lines[i].wl_lnum >= mod_bot) {
+ lnumb = wp->w_lines[i].wl_lnum;
+ /* When there is a fold column it might need updating
+ * in the next line ("J" just above an open fold). */
+ if (wp->w_p_fdc > 0)
+ ++lnumb;
+ }
+ }
+
+ (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)
+ mod_bot = lnumb;
+ }
+
+ /* When a change starts above w_topline and the end is below
+ * w_topline, start redrawing at w_topline.
+ * If the end of the change is above w_topline: do like no change was
+ * made, but redraw the first line to find changes in syntax. */
+ if (mod_top != 0 && mod_top < wp->w_topline) {
+ if (mod_bot > wp->w_topline)
+ mod_top = wp->w_topline;
+ else if (syntax_present(wp))
+ top_end = 1;
+ }
+
+ /* When line numbers are displayed need to redraw all lines below
+ * inserted/deleted lines. */
+ if (mod_top != 0 && buf->b_mod_xlines != 0 && wp->w_p_nu)
+ mod_bot = MAXLNUM;
+ }
+
+ /*
+ * When only displaying the lines at the top, set top_end. Used when
+ * window has scrolled down for msg_scrolled.
+ */
+ if (type == REDRAW_TOP) {
+ j = 0;
+ for (i = 0; i < wp->w_lines_valid; ++i) {
+ j += wp->w_lines[i].wl_size;
+ if (j >= wp->w_upd_rows) {
+ top_end = j;
+ break;
+ }
+ }
+ if (top_end == 0)
+ /* not found (cannot happen?): redraw everything */
+ type = NOT_VALID;
+ else
+ /* top area defined, the rest is VALID */
+ 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:
+ * 1: we are off the top of the screen by a few lines: scroll down
+ * 2: wp->w_topline is below wp->w_lines[0].wl_lnum: may scroll up
+ * 3: wp->w_topline is wp->w_lines[0].wl_lnum: find first entry in
+ * w_lines[] that needs updating.
+ */
+ if ((type == VALID || type == SOME_VALID
+ || type == INVERTED || type == INVERTED_ALL)
+ && !wp->w_botfill && !wp->w_old_botfill
+ ) {
+ if (mod_top != 0 && wp->w_topline == mod_top) {
+ /*
+ * w_topline is the first changed line, the scrolling will be done
+ * further down.
+ */
+ } else if (wp->w_lines[0].wl_valid
+ && (wp->w_topline < wp->w_lines[0].wl_lnum
+ || (wp->w_topline == wp->w_lines[0].wl_lnum
+ && wp->w_topfill > wp->w_old_topfill)
+ )) {
+ /*
+ * New topline is above old topline: May scroll down.
+ */
+ if (hasAnyFolding(wp)) {
+ linenr_T ln;
+
+ /* 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)
+ break;
+ (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 */
+ 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 (wp->w_lines_valid != 0) {
+ /* Need to update rows that are new, stop at the
+ * first one that scrolled down. */
+ top_end = i;
+ scrolled_down = TRUE;
+
+ /* 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--)
+ wp->w_lines[idx] = wp->w_lines[idx - j];
+ while (idx >= 0)
+ wp->w_lines[idx--].wl_valid = FALSE;
+ }
+ } else
+ mid_start = 0; /* redraw all lines */
+ } else
+ mid_start = 0; /* redraw all lines */
+ } else
+ mid_start = 0; /* redraw all lines */
+ } else {
+ /*
+ * New topline is at or below old topline: May scroll up.
+ * When topline didn't change, find first entry in w_lines[] that
+ * needs updating.
+ */
+
+ /* try to find wp->w_topline in wp->w_lines[].wl_lnum */
+ j = -1;
+ row = 0;
+ for (i = 0; i < wp->w_lines_valid; i++) {
+ if (wp->w_lines[i].wl_valid
+ && wp->w_lines[i].wl_lnum == wp->w_topline) {
+ j = i;
+ break;
+ }
+ row += wp->w_lines[i].wl_size;
+ }
+ if (j == -1) {
+ /* if wp->w_topline is not in wp->w_lines[].wl_lnum redraw all
+ * lines */
+ mid_start = 0;
+ } else {
+ /*
+ * Try to delete the correct number of lines.
+ * wp->w_topline is at wp->w_lines[i].wl_lnum.
+ */
+ /* If the topline didn't change, delete old filler lines,
+ * otherwise delete filler lines of the new topline... */
+ if (wp->w_lines[0].wl_lnum == wp->w_topline)
+ row += wp->w_old_topfill;
+ else
+ row += diff_check_fill(wp, wp->w_topline);
+ /* ... 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 ((row == 0 || bot_start < 999) && wp->w_lines_valid != 0) {
+ /*
+ * Skip the lines (below the deleted lines) that are still
+ * valid and don't need redrawing. Copy their info
+ * upwards, to compensate for the deleted lines. Set
+ * bot_start to the first row that needs redrawing.
+ */
+ bot_start = 0;
+ idx = 0;
+ for (;; ) {
+ wp->w_lines[idx] = wp->w_lines[j];
+ /* 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) {
+ wp->w_lines_valid = idx + 1;
+ break;
+ }
+ bot_start += wp->w_lines[idx++].wl_size;
+
+ /* stop at the last valid entry in w_lines[].wl_size */
+ if (++j >= wp->w_lines_valid) {
+ wp->w_lines_valid = idx;
+ break;
+ }
+ }
+ /* Correct the first entry for filler lines at the top
+ * 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)
+ + 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. */
+ 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;
+ } else {
+ /* Not VALID or INVERTED: redraw all lines. */
+ mid_start = 0;
+ mid_end = wp->w_height;
+ }
+
+ if (type == SOME_VALID) {
+ /* SOME_VALID: redraw all lines. */
+ mid_start = 0;
+ mid_end = wp->w_height;
+ type = NOT_VALID;
+ }
+
+ /* check if we are updating or removing the inverted part */
+ if ((VIsual_active && buf == curwin->w_buffer)
+ || (wp->w_old_cursor_lnum != 0 && type != NOT_VALID)) {
+ 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 (curwin->w_cursor.lnum < VIsual.lnum) {
+ from = curwin->w_cursor.lnum;
+ to = VIsual.lnum;
+ } else {
+ from = VIsual.lnum;
+ to = curwin->w_cursor.lnum;
+ }
+ /* redraw more when the cursor moved as well */
+ if (wp->w_old_cursor_lnum < from)
+ from = wp->w_old_cursor_lnum;
+ if (wp->w_old_cursor_lnum > to)
+ to = wp->w_old_cursor_lnum;
+ if (wp->w_old_visual_lnum < from)
+ from = wp->w_old_visual_lnum;
+ if (wp->w_old_visual_lnum > to)
+ to = wp->w_old_visual_lnum;
+ } else {
+ /*
+ * Find the line numbers that need to be updated: The lines
+ * between the old cursor position and the current cursor
+ * position. Also check if the Visual position changed.
+ */
+ if (curwin->w_cursor.lnum < wp->w_old_cursor_lnum) {
+ from = curwin->w_cursor.lnum;
+ to = wp->w_old_cursor_lnum;
+ } else {
+ from = wp->w_old_cursor_lnum;
+ to = curwin->w_cursor.lnum;
+ if (from == 0) /* Visual mode just started */
+ from = to;
+ }
+
+ if (VIsual.lnum != wp->w_old_visual_lnum
+ || VIsual.col != wp->w_old_visual_col) {
+ if (wp->w_old_visual_lnum < from
+ && wp->w_old_visual_lnum != 0)
+ from = wp->w_old_visual_lnum;
+ if (wp->w_old_visual_lnum > to)
+ to = wp->w_old_visual_lnum;
+ if (VIsual.lnum < from)
+ from = VIsual.lnum;
+ if (VIsual.lnum > to)
+ to = VIsual.lnum;
+ }
+ }
+
+ /*
+ * If in block mode and changed column or curwin->w_curswant:
+ * update all lines.
+ * First compute the actual start and end column.
+ */
+ if (VIsual_mode == Ctrl_V) {
+ colnr_T fromc, toc;
+
+ getvcols(wp, &VIsual, &curwin->w_cursor, &fromc, &toc);
+ ++toc;
+ if (curwin->w_curswant == MAXCOL)
+ toc = MAXCOL;
+
+ if (fromc != wp->w_old_cursor_fcol
+ || toc != wp->w_old_cursor_lcol) {
+ if (from > VIsual.lnum)
+ from = VIsual.lnum;
+ if (to < VIsual.lnum)
+ to = VIsual.lnum;
+ }
+ wp->w_old_cursor_fcol = fromc;
+ wp->w_old_cursor_lcol = toc;
+ }
+ } else {
+ /* Use the line numbers of the old Visual area. */
+ if (wp->w_old_cursor_lnum < wp->w_old_visual_lnum) {
+ from = wp->w_old_cursor_lnum;
+ to = wp->w_old_visual_lnum;
+ } else {
+ from = wp->w_old_visual_lnum;
+ to = wp->w_old_cursor_lnum;
+ }
+ }
+
+ /*
+ * There is no need to update lines above the top of the window.
+ */
+ if (from < wp->w_topline)
+ from = wp->w_topline;
+
+ /*
+ * If we know the value of w_botline, use it to restrict the update to
+ * the lines that are visible in the window.
+ */
+ if (wp->w_valid & VALID_BOTLINE) {
+ if (from >= wp->w_botline)
+ from = wp->w_botline - 1;
+ if (to >= wp->w_botline)
+ to = wp->w_botline - 1;
+ }
+
+ /*
+ * Find the minimal part to be updated.
+ * Watch out for scrolling that made entries in w_lines[] invalid.
+ * E.g., CTRL-U makes the first half of w_lines[] invalid and sets
+ * top_end; need to redraw from top_end to the "to" line.
+ * A middle mouse click with a Visual selection may change the text
+ * above the Visual area and reset wl_valid, do count these for
+ * mid_end (in srow).
+ */
+ if (mid_start > 0) {
+ lnum = wp->w_topline;
+ idx = 0;
+ srow = 0;
+ if (scrolled_down)
+ mid_start = top_end;
+ else
+ mid_start = 0;
+ while (lnum < from && idx < wp->w_lines_valid) { /* find start */
+ if (wp->w_lines[idx].wl_valid)
+ mid_start += wp->w_lines[idx].wl_size;
+ else if (!scrolled_down)
+ srow += wp->w_lines[idx].wl_size;
+ ++idx;
+ if (idx < wp->w_lines_valid && wp->w_lines[idx].wl_valid)
+ lnum = wp->w_lines[idx].wl_lnum;
+ else
+ ++lnum;
+ }
+ srow += mid_start;
+ mid_end = wp->w_height;
+ 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 */
+ mid_end = srow;
+ break;
+ }
+ srow += wp->w_lines[idx].wl_size;
+ }
+ }
+ }
+
+ if (VIsual_active && buf == curwin->w_buffer) {
+ wp->w_old_visual_mode = VIsual_mode;
+ wp->w_old_cursor_lnum = curwin->w_cursor.lnum;
+ wp->w_old_visual_lnum = VIsual.lnum;
+ wp->w_old_visual_col = VIsual.col;
+ wp->w_old_curswant = curwin->w_curswant;
+ } else {
+ wp->w_old_visual_mode = 0;
+ wp->w_old_cursor_lnum = 0;
+ wp->w_old_visual_lnum = 0;
+ wp->w_old_visual_col = 0;
+ }
+
+ /* reset got_int, otherwise regexp won't work */
+ save_got_int = got_int;
+ got_int = 0;
+ win_foldinfo.fi_level = 0;
+
+ /*
+ * Update all the window rows.
+ */
+ idx = 0; /* first entry in w_lines[].wl_size */
+ row = 0;
+ srow = 0;
+ lnum = wp->w_topline; /* first line shown in window */
+ 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;
+ break;
+ }
+
+ /* stop updating when hit the end of the file */
+ if (lnum > buf->b_ml.ml_line_count) {
+ eof = TRUE;
+ break;
+ }
+
+ /* Remember the starting row of the line that is going to be dealt
+ * 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 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
+ || idx >= wp->w_lines_valid
+ || (row + wp->w_lines[idx].wl_size > bot_start)
+ || (mod_top != 0
+ && (lnum == mod_top
+ || (lnum >= mod_top
+ && (lnum < mod_bot
+ || did_update == DID_FOLD
+ || (did_update == DID_LINE
+ && syntax_present(wp)
+ && (
+ (foldmethodIsSyntax(wp)
+ && hasAnyFolding(wp)) ||
+ syntax_check_changed(lnum)))
+ /* match in fixed position might need redraw */
+ || wp->w_match_head != NULL
+ ))))) {
+ if (lnum == mod_top)
+ top_to_mod = FALSE;
+
+ /*
+ * When at start of changed lines: May scroll following lines
+ * up or down to minimize redrawing.
+ * Don't do this when the change continues until the end.
+ * Don't scroll when dollar_vcol >= 0, keep the "$".
+ */
+ if (lnum == mod_top
+ && mod_bot != MAXLNUM
+ && !(dollar_vcol >= 0 && mod_bot == mod_top + 1)) {
+ int old_rows = 0;
+ int new_rows = 0;
+ int xtra_rows;
+ linenr_T l;
+
+ /* Count the old number of window rows, using w_lines[], which
+ * should still contain the sizes for the lines as they are
+ * currently displayed. */
+ for (i = idx; i < wp->w_lines_valid; ++i) {
+ /* Only valid lines have a meaningful wl_lnum. Invalid
+ * lines are part of the changed area. */
+ if (wp->w_lines[i].wl_valid
+ && wp->w_lines[i].wl_lnum == mod_bot)
+ break;
+ old_rows += wp->w_lines[i].wl_size;
+ if (wp->w_lines[i].wl_valid
+ && wp->w_lines[i].wl_lastlnum + 1 == mod_bot) {
+ /* Must have found the last valid entry above mod_bot.
+ * Add following invalid entries. */
+ ++i;
+ while (i < wp->w_lines_valid
+ && !wp->w_lines[i].wl_valid)
+ old_rows += wp->w_lines[i++].wl_size;
+ break;
+ }
+ }
+
+ if (i >= wp->w_lines_valid) {
+ /* We can't find a valid line below the changed lines,
+ * need to redraw until the end of the window.
+ * Inserting/deleting lines has no use. */
+ bot_start = 0;
+ } else {
+ /* 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 */
+ new_rows = 9999;
+ break;
+ }
+ }
+ xtra_rows = new_rows - old_rows;
+ if (xtra_rows < 0) {
+ /* May scroll text up. If there is not enough
+ * 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)
+ mod_bot = MAXLNUM;
+ else {
+ check_for_delay(FALSE);
+ if (win_del_lines(wp, row,
+ -xtra_rows, FALSE, FALSE) == FAIL)
+ mod_bot = MAXLNUM;
+ else
+ bot_start = wp->w_height + 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)
+ mod_bot = MAXLNUM;
+ else {
+ check_for_delay(FALSE);
+ if (win_ins_lines(wp, row + old_rows,
+ xtra_rows, FALSE, FALSE) == FAIL)
+ mod_bot = MAXLNUM;
+ else if (top_end > row + old_rows)
+ /* Scrolled the part at the top that requires
+ * updating down. */
+ top_end += xtra_rows;
+ }
+ }
+
+ /* When not updating the rest, may need to move w_lines[]
+ * entries. */
+ if (mod_bot != MAXLNUM && i != j) {
+ if (j < i) {
+ int x = row + new_rows;
+
+ /* move entries in w_lines[] upwards */
+ for (;; ) {
+ /* stop at last valid entry in w_lines[] */
+ if (i >= wp->w_lines_valid) {
+ wp->w_lines_valid = j;
+ break;
+ }
+ 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_lines_valid = j + 1;
+ break;
+ }
+ x += wp->w_lines[j++].wl_size;
+ ++i;
+ }
+ if (bot_start > x)
+ bot_start = x;
+ } else { /* j > i */
+ /* 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)
+ 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.
+ * Reset to zero. */
+ while (i >= idx) {
+ wp->w_lines[i].wl_size = 0;
+ wp->w_lines[i--].wl_valid = FALSE;
+ }
+ }
+ }
+ }
+ }
+
+ /*
+ * When lines are folded, display one line for all of them.
+ * Otherwise, display normally (can be several display lines when
+ * 'wrap' is on).
+ */
+ fold_count = foldedCount(wp, lnum, &win_foldinfo);
+ if (fold_count != 0) {
+ fold_line(wp, fold_count, &win_foldinfo, lnum, row);
+ ++row;
+ --fold_count;
+ wp->w_lines[idx].wl_folded = TRUE;
+ wp->w_lines[idx].wl_lastlnum = lnum + fold_count;
+ did_update = DID_FOLD;
+ } else if (idx < wp->w_lines_valid
+ && 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
+ && 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;
+ } else {
+ prepare_search_hl(wp, lnum);
+ /* Let the syntax stuff know we skipped a few lines. */
+ if (syntax_last_parsed != 0 && syntax_last_parsed + 1 < lnum
+ && syntax_present(wp))
+ syntax_end_parsing(syntax_last_parsed + 1);
+
+ /*
+ * Display one line.
+ */
+ row = win_line(wp, lnum, srow, wp->w_height, mod_top == 0);
+
+ wp->w_lines[idx].wl_folded = FALSE;
+ wp->w_lines[idx].wl_lastlnum = lnum;
+ did_update = DID_LINE;
+ syntax_last_parsed = lnum;
+ }
+
+ 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;
+ break;
+ }
+ if (dollar_vcol == -1)
+ wp->w_lines[idx].wl_size = row - srow;
+ ++idx;
+ lnum += fold_count + 1;
+ } else {
+ /* This line does not need updating, advance to the next one */
+ row += wp->w_lines[idx++].wl_size;
+ if (row > wp->w_height) /* past end of screen */
+ break;
+ lnum = wp->w_lines[idx - 1].wl_lastlnum + 1;
+ did_update = DID_NONE;
+ }
+
+ if (lnum > buf->b_ml.ml_line_count) {
+ eof = TRUE;
+ break;
+ }
+ }
+ /*
+ * End of loop over all window lines.
+ */
+
+
+ if (idx > wp->w_lines_valid)
+ wp->w_lines_valid = idx;
+
+ /*
+ * Let the syntax stuff know we stop parsing here.
+ */
+ if (syntax_last_parsed != 0 && syntax_present(wp))
+ syntax_end_parsing(syntax_last_parsed + 1);
+
+ /*
+ * If we didn't hit the end of the file, and we didn't finish the last
+ * line we were working on, then the line didn't fit.
+ */
+ wp->w_empty_rows = 0;
+ wp->w_filler_rows = 0;
+ if (!eof && !didline) {
+ 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. */
+ 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(W_WINROW(wp) + wp->w_height - 1,
+ W_WINROW(wp) + wp->w_height,
+ (int)W_ENDCOL(wp) - 3, (int)W_ENDCOL(wp),
+ '@', '@', hl_attr(HLF_AT));
+ set_empty_rows(wp, srow);
+ wp->w_botline = lnum;
+ } else {
+ win_draw_end(wp, '@', ' ', srow, wp->w_height, HLF_AT);
+ wp->w_botline = lnum;
+ }
+ } else {
+ draw_vsep_win(wp, row);
+ 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) {
+ /*
+ * Display filler lines at the end of the file
+ */
+ if (char2cells(fill_diff) > 1)
+ i = '-';
+ else
+ i = fill_diff;
+ if (row + j > wp->w_height)
+ j = wp->w_height - 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_AT);
+ }
+
+ /* Reset the type of redrawing required, the window has been updated. */
+ wp->w_redr_type = 0;
+ wp->w_old_topfill = wp->w_topfill;
+ wp->w_old_botfill = wp->w_botfill;
+
+ if (dollar_vcol == -1) {
+ /*
+ * There is a trick with w_botline. If we invalidate it on each
+ * change that might modify it, this will cause a lot of expensive
+ * calls to plines() in update_topline() each time. Therefore the
+ * value of w_botline is often approximated, and this value is used to
+ * compute the value of w_topline. If the value of w_botline was
+ * wrong, check that the value of w_topline is correct (cursor is on
+ * the visible part of the text). If it's not, we need to redraw
+ * again. Mostly this just means scrolling up a few lines, so it
+ * doesn't look too bad. Only do this for the current window (where
+ * changes are relevant).
+ */
+ wp->w_valid |= VALID_BOTLINE;
+ if (wp == curwin && wp->w_botline != old_botline && !recursive) {
+ recursive = TRUE;
+ curwin->w_valid &= ~VALID_TOPLINE;
+ update_topline(); /* may invalidate w_botline again */
+ if (must_redraw != 0) {
+ /* Don't update for changes in buffer again. */
+ i = curbuf->b_mod_set;
+ curbuf->b_mod_set = FALSE;
+ win_update(curwin);
+ must_redraw = 0;
+ curbuf->b_mod_set = i;
+ }
+ recursive = FALSE;
+ }
+ }
+
+ /* restore got_int, unless CTRL-C was hit while redrawing */
+ if (!got_int)
+ got_int = save_got_int;
+}
+
+
+/*
+ * Clear the rest of the window and mark the unused lines with "c1". use "c2"
+ * as the filler character.
+ */
+static void win_draw_end(wp, c1, c2, row, endrow, hl)
+win_T *wp;
+int c1;
+int c2;
+int row;
+int endrow;
+hlf_T hl;
+{
+ int n = 0;
+# define FDC_OFF n
+
+ if (wp->w_p_rl) {
+ /* No check for cmdline window: should never be right-left. */
+ n = wp->w_p_fdc;
+
+ if (n > 0) {
+ /* draw the fold column at the right */
+ if (n > W_WIDTH(wp))
+ n = W_WIDTH(wp);
+ screen_fill(W_WINROW(wp) + row, W_WINROW(wp) + endrow,
+ W_ENDCOL(wp) - n, (int)W_ENDCOL(wp),
+ ' ', ' ', hl_attr(HLF_FC));
+ }
+ screen_fill(W_WINROW(wp) + row, W_WINROW(wp) + endrow,
+ W_WINCOL(wp), W_ENDCOL(wp) - 1 - FDC_OFF,
+ c2, c2, hl_attr(hl));
+ screen_fill(W_WINROW(wp) + row, W_WINROW(wp) + endrow,
+ W_ENDCOL(wp) - 1 - FDC_OFF, W_ENDCOL(wp) - FDC_OFF,
+ c1, c2, hl_attr(hl));
+ } 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(W_WINROW(wp) + row, W_WINROW(wp) + endrow,
+ W_WINCOL(wp), (int)W_WINCOL(wp) + n,
+ cmdwin_type, ' ', hl_attr(HLF_AT));
+ }
+ if (wp->w_p_fdc > 0) {
+ int nn = n + wp->w_p_fdc;
+
+ /* draw the fold column at the left */
+ if (nn > W_WIDTH(wp))
+ nn = W_WIDTH(wp);
+ screen_fill(W_WINROW(wp) + row, W_WINROW(wp) + endrow,
+ W_WINCOL(wp) + n, (int)W_WINCOL(wp) + nn,
+ ' ', ' ', hl_attr(HLF_FC));
+ n = nn;
+ }
+ screen_fill(W_WINROW(wp) + row, W_WINROW(wp) + endrow,
+ W_WINCOL(wp) + FDC_OFF, (int)W_ENDCOL(wp),
+ c1, c2, hl_attr(hl));
+ }
+ set_empty_rows(wp, row);
+}
+
+static int advance_color_col __ARGS((int vcol, int **color_cols));
+
+/*
+ * Advance **color_cols and return TRUE when there are columns to draw.
+ */
+static int advance_color_col(vcol, color_cols)
+int vcol;
+int **color_cols;
+{
+ while (**color_cols >= 0 && vcol > **color_cols)
+ ++*color_cols;
+ return **color_cols >= 0;
+}
+
+/*
+ * Display one folded line.
+ */
+static void fold_line(wp, fold_count, foldinfo, lnum, row)
+win_T *wp;
+long fold_count;
+foldinfo_T *foldinfo;
+linenr_T lnum;
+int row;
+{
+ char_u buf[51];
+ pos_T *top, *bot;
+ linenr_T lnume = lnum + fold_count - 1;
+ int len;
+ char_u *text;
+ int fdc;
+ int col;
+ int txtcol;
+ int off = (int)(current_ScreenLine - ScreenLines);
+ int ri;
+
+ /* Build the fold line:
+ * 1. Add the cmdwin_type for the command-line window
+ * 2. Add the 'foldcolumn'
+ * 3. Add the 'number' or 'relativenumber' column
+ * 4. Compose the text
+ * 5. Add the text
+ * 6. set highlighting for the Visual area an other text
+ */
+ col = 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;
+ }
+
+ /*
+ * 2. Add the 'foldcolumn'
+ */
+ fdc = wp->w_p_fdc;
+ if (fdc > W_WIDTH(wp) - col)
+ fdc = W_WIDTH(wp) - col;
+ if (fdc > 0) {
+ fill_foldcolumn(buf, wp, TRUE, lnum);
+ if (wp->w_p_rl) {
+ int i;
+
+ copy_text_attr(off + W_WIDTH(wp) - fdc - col, buf, fdc,
+ hl_attr(HLF_FC));
+ /* reverse the fold column */
+ for (i = 0; i < fdc; ++i)
+ ScreenLines[off + W_WIDTH(wp) - i - 1 - col] = buf[i];
+ } else
+ copy_text_attr(off + col, buf, fdc, hl_attr(HLF_FC));
+ col += fdc;
+ }
+
+# define RL_MEMSET(p, v, l) if (wp->w_p_rl) \
+ for (ri = 0; ri < l; ++ri) \
+ ScreenAttrs[off + (W_WIDTH(wp) - (p) - (l)) + ri] = v; \
+ else \
+ for (ri = 0; ri < l; ++ri) \
+ ScreenAttrs[off + (p) + ri] = v
+
+ /* Set all attributes of the 'number' or 'relativenumber' column and the
+ * text */
+ RL_MEMSET(col, hl_attr(HLF_FL), W_WIDTH(wp) - col);
+
+
+ /*
+ * 3. Add the 'number' or 'relativenumber' column
+ */
+ if (wp->w_p_nu || wp->w_p_rnu) {
+ len = W_WIDTH(wp) - col;
+ if (len > 0) {
+ int w = number_width(wp);
+ long num;
+ char *fmt = "%*ld ";
+
+ if (len > w + 1)
+ len = w + 1;
+
+ if (wp->w_p_nu && !wp->w_p_rnu)
+ /* 'number' + 'norelativenumber' */
+ num = (long)lnum;
+ else {
+ /* 'relativenumber', don't use negative numbers */
+ num = labs((long)get_cursor_rel_lnum(wp, lnum));
+ if (num == 0 && wp->w_p_nu && wp->w_p_rnu) {
+ /* 'number' + 'relativenumber': cursor line shows absolute
+ * line number */
+ num = lnum;
+ fmt = "%-*ld ";
+ }
+ }
+
+ sprintf((char *)buf, fmt, w, num);
+ if (wp->w_p_rl)
+ /* the line number isn't reversed */
+ copy_text_attr(off + W_WIDTH(wp) - len - col, buf, len,
+ hl_attr(HLF_FL));
+ else
+ copy_text_attr(off + col, buf, len, hl_attr(HLF_FL));
+ col += len;
+ }
+ }
+
+ /*
+ * 4. Compose the folded-line string with 'foldtext', if set.
+ */
+ text = get_foldtext(wp, lnum, lnume, foldinfo, buf);
+
+ 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 > W_WIDTH(wp)
+ - (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;
+
+ u8c = arabic_shape(u8c, &firstbyte, &u8cc[0],
+ pc, pc1, nc);
+ ScreenLines[idx] = firstbyte;
+ } else
+ prev_c = u8c;
+ /* Non-BMP character: display as ? or fullwidth ?. */
+#ifdef UNICODE16
+ if (u8c >= 0x10000)
+ ScreenLinesUC[idx] = (cells == 2) ? 0xff1f : (int)'?';
+ else
+#endif
+ 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;
+ }
+ } else {
+ len = (int)STRLEN(text);
+ if (len > W_WIDTH(wp) - col)
+ len = W_WIDTH(wp) - col;
+ if (len > 0) {
+ if (wp->w_p_rl)
+ STRNCPY(current_ScreenLine, text, len);
+ else
+ STRNCPY(current_ScreenLine + col, text, len);
+ col += len;
+ }
+ }
+
+ /* Fill the rest of the line with the fold filler */
+ if (wp->w_p_rl)
+ col -= txtcol;
+ while (col < W_WIDTH(wp)
+ - (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;
+ }
+
+ if (text != buf)
+ vim_free(text);
+
+ /*
+ * 6. set highlighting for the Visual area an other text.
+ * If all folded lines are in the Visual area, highlight the line.
+ */
+ if (VIsual_active && wp->w_buffer == curwin->w_buffer) {
+ if (ltoreq(curwin->w_cursor, VIsual)) {
+ /* Visual is after curwin->w_cursor */
+ top = &curwin->w_cursor;
+ bot = &VIsual;
+ } else {
+ /* Visual is before curwin->w_cursor */
+ top = &VIsual;
+ bot = &curwin->w_cursor;
+ }
+ if (lnum >= top->lnum
+ && lnume <= bot->lnum
+ && (VIsual_mode != 'v'
+ || ((lnum > top->lnum
+ || (lnum == top->lnum
+ && top->col == 0))
+ && (lnume < bot->lnum
+ || (lnume == bot->lnum
+ && (bot->col - (*p_sel == 'e'))
+ >= (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)W_WIDTH(wp)) {
+ if (wp->w_old_cursor_lcol != MAXCOL
+ && wp->w_old_cursor_lcol + txtcol
+ < (colnr_T)W_WIDTH(wp))
+ len = wp->w_old_cursor_lcol;
+ else
+ len = W_WIDTH(wp) - txtcol;
+ RL_MEMSET(wp->w_old_cursor_fcol + txtcol, hl_attr(HLF_V),
+ len - (int)wp->w_old_cursor_fcol);
+ }
+ } else {
+ /* Set all attributes of the text */
+ RL_MEMSET(txtcol, hl_attr(HLF_V), W_WIDTH(wp) - txtcol);
+ }
+ }
+ }
+
+ /* Show 'cursorcolumn' in the fold line. */
+ if (wp->w_p_cuc) {
+ txtcol += wp->w_virtcol;
+ if (wp->w_p_wrap)
+ txtcol -= wp->w_skipcol;
+ else
+ txtcol -= wp->w_leftcol;
+ if (txtcol >= 0 && txtcol < W_WIDTH(wp))
+ ScreenAttrs[off + txtcol] = hl_combine_attr(
+ ScreenAttrs[off + txtcol], hl_attr(HLF_CUC));
+ }
+
+ SCREEN_LINE(row + W_WINROW(wp), W_WINCOL(wp), (int)W_WIDTH(wp),
+ (int)W_WIDTH(wp), FALSE);
+
+ /*
+ * Update w_cline_height and w_cline_folded if the cursor line was
+ * updated (saves a call to plines() later).
+ */
+ if (wp == curwin
+ && lnum <= curwin->w_cursor.lnum
+ && lnume >= curwin->w_cursor.lnum) {
+ curwin->w_cline_row = row;
+ curwin->w_cline_height = 1;
+ curwin->w_cline_folded = TRUE;
+ curwin->w_valid |= (VALID_CHEIGHT|VALID_CROW);
+ }
+}
+
+/*
+ * Copy "buf[len]" to ScreenLines["off"] and set attributes to "attr".
+ */
+static void copy_text_attr(off, buf, len, attr)
+int off;
+char_u *buf;
+int len;
+int attr;
+{
+ int i;
+
+ mch_memmove(ScreenLines + off, buf, (size_t)len);
+ if (enc_utf8)
+ vim_memset(ScreenLinesUC + off, 0, sizeof(u8char_T) * (size_t)len);
+ for (i = 0; i < len; ++i)
+ ScreenAttrs[off + i] = attr;
+}
+
+/*
+ * Fill the foldcolumn at "p" for window "wp".
+ * Only to be called when 'foldcolumn' > 0.
+ */
+static void fill_foldcolumn(p, wp, closed, lnum)
+char_u *p;
+win_T *wp;
+int closed; /* TRUE of FALSE */
+linenr_T lnum; /* current line number */
+{
+ int i = 0;
+ int level;
+ int first_level;
+ int empty;
+
+ /* Init to all spaces. */
+ copy_spaces(p, (size_t)wp->w_p_fdc);
+
+ level = win_foldinfo.fi_level;
+ if (level > 0) {
+ /* If there is only one column put more info in it. */
+ empty = (wp->w_p_fdc == 1) ? 0 : 1;
+
+ /* If the column is too narrow, we start at the lowest level that
+ * fits and use numbers to indicated the depth. */
+ first_level = level - wp->w_p_fdc - closed + 1 + empty;
+ if (first_level < 1)
+ first_level = 1;
+
+ for (i = 0; i + empty < wp->w_p_fdc; ++i) {
+ if (win_foldinfo.fi_lnum == lnum
+ && first_level + i >= win_foldinfo.fi_low_level)
+ p[i] = '-';
+ else if (first_level == 1)
+ p[i] = '|';
+ else if (first_level + i <= 9)
+ p[i] = '0' + first_level + i;
+ else
+ p[i] = '>';
+ if (first_level + i == level)
+ break;
+ }
+ }
+ if (closed)
+ p[i >= wp->w_p_fdc ? i - 1 : i] = '+';
+}
+
+/*
+ * Display line "lnum" of window 'wp' on the screen.
+ * Start at row "startrow", stop when "endrow" is reached.
+ * wp->w_virtcol needs to be valid.
+ *
+ * Return the number of last row the line occupies.
+ */
+static int win_line(wp, lnum, startrow, endrow, nochange)
+win_T *wp;
+linenr_T lnum;
+int startrow;
+int endrow;
+int nochange UNUSED; /* not updating for changed text */
+{
+ 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) */
+ 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 */
+
+ char_u extra[18]; /* "%ld" and 'fdc' must fit in here */
+ int n_extra = 0; /* number of extra chars */
+ char_u *p_extra = NULL; /* string of extra chars, plus NUL */
+ int c_extra = NUL; /* extra chars, all the same */
+ int extra_attr = 0; /* attributes when n_extra != 0 */
+ static char_u *at_end_str = (char_u *)""; /* used for p_extra when
+ displaying lcs_eol at end-of-line */
+ int lcs_eol_one = lcs_eol; /* lcs_eol until it's been used */
+ int lcs_prec_todo = lcs_prec; /* lcs_prec until it's been used */
+
+ /* saved "extra" items for when draw_state becomes WL_LINE (again) */
+ int saved_n_extra = 0;
+ char_u *saved_p_extra = NULL;
+ int saved_c_extra = 0;
+ int saved_char_attr = 0;
+
+ int n_attr = 0; /* chars with special attr */
+ int saved_attr2 = 0; /* char_attr saved for n_attr */
+ int n_attr3 = 0; /* chars with overruling special attr */
+ int saved_attr3 = 0; /* char_attr saved for n_attr3 */
+
+ 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;
+ pos_T pos;
+ long v;
+
+ int char_attr = 0; /* attributes for next character */
+ int attr_pri = FALSE; /* char_attr has priority */
+ int area_highlighting = FALSE; /* Visual or incsearch highlighting
+ in this line */
+ int attr = 0; /* attributes for area highlighting */
+ int area_attr = 0; /* attributes desired by highlighting */
+ int search_attr = 0; /* attributes desired by 'hlsearch' */
+ int vcol_save_attr = 0; /* saved attr for 'cursorcolumn' */
+ 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 */
+ int 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 */
+ int nextline_idx = 0; /* index in nextline[] where next line
+ starts */
+ int spell_attr = 0; /* attributes desired by spelling */
+ int word_end = 0; /* last byte with same spell_attr */
+ 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;
+#if defined(FEAT_SIGNS) || (defined(FEAT_QUICKFIX) && defined(FEAT_WINDOWS)) \
+ || defined(FEAT_SYN_HL) || defined(FEAT_DIFF)
+# define LINE_ATTR
+ int line_attr = 0; /* attribute for the whole line */
+#endif
+ 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 */
+#if defined(LINE_ATTR)
+ int did_line_attr = 0;
+#endif
+
+ /* draw_state: items that are drawn in sequence: */
+#define WL_START 0 /* nothing done yet */
+# define WL_CMDLINE WL_START + 1 /* cmdline window column */
+# define WL_FOLD WL_CMDLINE + 1 /* 'foldcolumn' */
+# define WL_SIGN WL_FOLD /* column for signs */
+#define WL_NR WL_SIGN + 1 /* line number */
+# define WL_SBR WL_NR + 1 /* 'showbreak' or 'diff' */
+#define WL_LINE WL_SBR + 1 /* text in the line */
+ int draw_state = WL_START; /* what to draw next */
+
+ int syntax_flags = 0;
+ int syntax_seqnr = 0;
+ int prev_syntax_id = 0;
+ int conceal_attr = hl_attr(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;
+# define VCOL_HLC (vcol - vcol_off)
+# define FIX_FOR_BOGUSCOLS \
+ { \
+ n_extra += vcol_off; \
+ vcol -= vcol_off; \
+ vcol_off = 0; \
+ col -= boguscols; \
+ boguscols = 0; \
+ }
+
+ if (startrow > endrow) /* past the end already! */
+ return startrow;
+
+ row = startrow;
+ screen_row = row + W_WINROW(wp);
+
+ /*
+ * 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_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
+ && wp->w_s->b_langp.ga_len > 0
+ && *(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;
+ }
+
+ /*
+ * 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 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;
+ }
+ }
+ }
+ }
+
+ /* Check if the character under the cursor should not be inverted */
+ if (!highlight_match && lnum == curwin->w_cursor.lnum && wp == curwin
+ )
+ noinvcur = TRUE;
+
+ /* if inverting in this line set area_highlighting */
+ if (fromcol >= 0) {
+ area_highlighting = TRUE;
+ attr = hl_attr(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 = hl_attr(HLF_I);
+ }
+
+ filler_lines = diff_check(wp, lnum);
+ if (filler_lines < 0) {
+ if (filler_lines == -1) {
+ if (diff_find_change(wp, lnum, &change_start, &change_end))
+ diff_hlf = HLF_ADD; /* added line */
+ else if (change_start == 0)
+ diff_hlf = HLF_TXD; /* changed text */
+ else
+ diff_hlf = HLF_CHD; /* changed line */
+ } else
+ diff_hlf = HLF_ADD; /* added line */
+ filler_lines = 0;
+ area_highlighting = TRUE;
+ }
+ if (lnum == wp->w_topline)
+ filler_lines = wp->w_topfill;
+ filler_todo = filler_lines;
+
+#ifdef LINE_ATTR
+ /* 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;
+#endif
+
+ 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);
+
+ /* 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
+ * copied to nextline[SPWORDLEN]. */
+ if (nextline[SPWORDLEN] == NUL) {
+ /* No next line or it is empty. */
+ nextlinecol = MAXCOL;
+ nextline_idx = 0;
+ } else {
+ v = (long)STRLEN(line);
+ if (v < SPWORDLEN) {
+ /* Short line, use it completely and append the start of the
+ * next line. */
+ nextlinecol = 0;
+ mch_memmove(nextline, line, (size_t)v);
+ STRMOVE(nextline + v, nextline + SPWORDLEN);
+ nextline_idx = v + 1;
+ } else {
+ /* Long line, use only the last SPWORDLEN bytes. */
+ nextlinecol = v - SPWORDLEN;
+ mch_memmove(nextline, line + nextlinecol, SPWORDLEN);
+ nextline_idx = SPWORDLEN + 1;
+ }
+ }
+ }
+
+ /* find start of trailing whitespace */
+ if (wp->w_p_list && lcs_trail) {
+ trailcol = (colnr_T)STRLEN(ptr);
+ while (trailcol > (colnr_T)0 && vim_iswhite(ptr[trailcol - 1]))
+ --trailcol;
+ trailcol += (colnr_T) (ptr - line);
+ extra_check = TRUE;
+ }
+
+ /*
+ * 'nowrap' or 'wrap' and a single line that doesn't fit: Advance to the
+ * first character to be displayed.
+ */
+ if (wp->w_p_wrap)
+ v = wp->w_skipcol;
+ else
+ v = wp->w_leftcol;
+ if (v > 0) {
+ char_u *prev_ptr = ptr;
+ while (vcol < v && *ptr != NUL) {
+ c = win_lbr_chartabsize(wp, ptr, (colnr_T)vcol, NULL);
+ vcol += c;
+ prev_ptr = ptr;
+ mb_ptr_adv(ptr);
+ }
+
+ /* When:
+ * - 'cuc' is set, or
+ * - 'colorcolumn' is set, or
+ * - 'virtualedit' is set, or
+ * - the visual mode is active,
+ * the end of the line may be before the start of the displayed part.
+ */
+ if (vcol < v && (
+ wp->w_p_cuc
+ || draw_color_col
+ ||
+ virtual_active()
+ ||
+ (VIsual_active && wp->w_buffer == curwin->w_buffer)
+ )) {
+ vcol = v;
+ }
+
+ /* Handle a character that's not completely on the screen: Put ptr at
+ * that character but skip the first few screen characters. */
+ if (vcol > v) {
+ vcol -= c;
+ ptr = prev_ptr;
+ n_skip = v - vcol;
+ }
+
+ /*
+ * Adjust for when the inverted text is before the screen,
+ * and when the start of the inverted text is before the screen.
+ */
+ if (tocol <= vcol)
+ fromcol = 0;
+ else if (fromcol >= 0 && fromcol < vcol)
+ fromcol = vcol;
+
+ /* When w_skipcol is non-zero, first line needs 'showbreak' */
+ if (wp->w_p_wrap)
+ need_showbreak = TRUE;
+ /* When spell checking a word we need to figure out the start of the
+ * word and if it's badly spelled or not. */
+ if (has_spell) {
+ int len;
+ colnr_T linecol = (colnr_T)(ptr - line);
+ hlf_T spell_hlf = HLF_COUNT;
+
+ pos = wp->w_cursor;
+ wp->w_cursor.lnum = lnum;
+ wp->w_cursor.col = linecol;
+ len = spell_move_to(wp, FORWARD, TRUE, TRUE, &spell_hlf);
+
+ /* spell_move_to() may call ml_get() and make "line" invalid */
+ line = ml_get_buf(wp->w_buffer, lnum, FALSE);
+ ptr = line + linecol;
+
+ if (len == 0 || (int)wp->w_cursor.col > ptr - line) {
+ /* no bad word found at line start, don't check until end of a
+ * word */
+ spell_hlf = HLF_COUNT;
+ word_end = (int)(spell_to_word_end(ptr, wp) - line + 1);
+ } else {
+ /* bad word found, use attributes until end of word */
+ word_end = wp->w_cursor.col + len + 1;
+
+ /* Turn index into actual attributes. */
+ if (spell_hlf != HLF_COUNT)
+ spell_attr = highlight_attr[spell_hlf];
+ }
+ wp->w_cursor = pos;
+
+ /* Need to restart syntax highlighting for this line. */
+ if (has_syntax)
+ syntax_start(wp, lnum);
+ }
+ }
+
+ /*
+ * Correct highlighting for cursor that can't be disabled.
+ * Avoids having to check this for each character.
+ */
+ if (fromcol >= 0) {
+ if (noinvcur) {
+ if ((colnr_T)fromcol == wp->w_virtcol) {
+ /* highlighting starts at cursor, let it start just after the
+ * cursor */
+ fromcol_prev = fromcol;
+ fromcol = -1;
+ } else if ((colnr_T)fromcol < wp->w_virtcol)
+ /* restart highlighting after the cursor */
+ fromcol_prev = wp->w_virtcol;
+ }
+ if (fromcol >= tocol)
+ fromcol = -1;
+ }
+
+ /*
+ * Handle highlighting the last used search pattern and matches.
+ * 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 = &search_hl;
+ shl_flag = TRUE;
+ } else
+ shl = &cur->hl;
+ shl->startcol = MAXCOL;
+ shl->endcol = MAXCOL;
+ shl->attr_cur = 0;
+ if (shl->rm.regprog != NULL) {
+ v = (long)(ptr - line);
+ next_search_hl(wp, shl, lnum, (colnr_T)v);
+
+ /* Need to get the line again, a multi-line regexp may have made it
+ * invalid. */
+ line = ml_get_buf(wp->w_buffer, lnum, FALSE);
+ ptr = line + v;
+
+ if (shl->lnum != 0 && shl->lnum <= lnum) {
+ if (shl->lnum == lnum)
+ shl->startcol = shl->rm.startpos[0].col;
+ else
+ shl->startcol = 0;
+ if (lnum == shl->lnum + shl->rm.endpos[0].lnum
+ - shl->rm.startpos[0].lnum)
+ shl->endcol = shl->rm.endpos[0].col;
+ else
+ shl->endcol = MAXCOL;
+ /* Highlight one character for an empty match. */
+ if (shl->startcol == shl->endcol) {
+ if (has_mbyte && line[shl->endcol] != NUL)
+ shl->endcol += (*mb_ptr2len)(line + shl->endcol);
+ else
+ ++shl->endcol;
+ }
+ if ((long)shl->startcol < v) { /* match at leftcol */
+ shl->attr_cur = shl->attr;
+ search_attr = shl->attr;
+ }
+ area_highlighting = TRUE;
+ }
+ }
+ if (shl != &search_hl && cur != NULL)
+ 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;
+ 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 = W_WIDTH(wp) - 1;
+ off += col;
+ }
+
+ /*
+ * Repeat for the whole displayed line.
+ */
+ for (;; ) {
+ /* Skip this quickly when working on the text. */
+ if (draw_state != WL_LINE) {
+ if (draw_state == WL_CMDLINE - 1 && n_extra == 0) {
+ draw_state = WL_CMDLINE;
+ if (cmdwin_type != 0 && wp == curwin) {
+ /* Draw the cmdline character. */
+ n_extra = 1;
+ c_extra = cmdwin_type;
+ char_attr = hl_attr(HLF_AT);
+ }
+ }
+
+ if (draw_state == WL_FOLD - 1 && n_extra == 0) {
+ draw_state = WL_FOLD;
+ if (wp->w_p_fdc > 0) {
+ /* Draw the 'foldcolumn'. */
+ fill_foldcolumn(extra, wp, FALSE, lnum);
+ n_extra = wp->w_p_fdc;
+ p_extra = extra;
+ p_extra[n_extra] = NUL;
+ c_extra = NUL;
+ char_attr = hl_attr(HLF_FC);
+ }
+ }
+
+
+ if (draw_state == WL_NR - 1 && n_extra == 0) {
+ draw_state = WL_NR;
+ /* Display the absolute or relative line number. After the
+ * first fill with blanks when the 'n' flag isn't in 'cpo' */
+ if ((wp->w_p_nu || wp->w_p_rnu)
+ && (row == startrow
+ + filler_lines
+ || vim_strchr(p_cpo, CPO_NUMCOL) == NULL)) {
+ /* Draw the line number (empty space after wrapping). */
+ if (row == startrow
+ + filler_lines
+ ) {
+ long num;
+ char *fmt = "%*ld ";
+
+ if (wp->w_p_nu && !wp->w_p_rnu)
+ /* 'number' + 'norelativenumber' */
+ num = (long)lnum;
+ else {
+ /* 'relativenumber', don't use negative numbers */
+ num = labs((long)get_cursor_rel_lnum(wp, lnum));
+ if (num == 0 && wp->w_p_nu && wp->w_p_rnu) {
+ /* 'number' + 'relativenumber' */
+ num = lnum;
+ fmt = "%-*ld ";
+ }
+ }
+
+ sprintf((char *)extra, fmt,
+ number_width(wp), num);
+ if (wp->w_skipcol > 0)
+ for (p_extra = extra; *p_extra == ' '; ++p_extra)
+ *p_extra = '-';
+ if (wp->w_p_rl) /* reverse line numbers */
+ rl_mirror(extra);
+ p_extra = extra;
+ c_extra = NUL;
+ } 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);
+ }
+ }
+
+ if (draw_state == WL_SBR - 1 && n_extra == 0) {
+ draw_state = WL_SBR;
+ if (filler_todo > 0) {
+ /* Draw "deleted" diff line(s). */
+ if (char2cells(fill_diff) > 1)
+ c_extra = '-';
+ else
+ c_extra = fill_diff;
+ if (wp->w_p_rl)
+ n_extra = col + 1;
+ else
+ n_extra = W_WIDTH(wp) - col;
+ char_attr = hl_attr(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;
+ /* Correct end of highlighted area for 'showbreak',
+ * required when 'linebreak' is also set. */
+ if (tocol == vcol)
+ tocol += n_extra;
+ /* combine 'showbreak' with 'cursorline' */
+ if (wp->w_p_cul && lnum == wp->w_cursor.lnum)
+ char_attr = hl_combine_attr(char_attr, HLF_CLN);
+ }
+ }
+
+ if (draw_state == WL_LINE - 1 && n_extra == 0) {
+ draw_state = WL_LINE;
+ if (saved_n_extra) {
+ /* Continue item from end of wrapped line. */
+ n_extra = saved_n_extra;
+ c_extra = saved_c_extra;
+ p_extra = saved_p_extra;
+ char_attr = saved_char_attr;
+ } 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, W_WINCOL(wp), col, -(int)W_WIDTH(wp),
+ wp->w_p_rl);
+ /* 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;
+ break;
+ }
+
+ if (draw_state == WL_LINE && area_highlighting) {
+ /* handle Visual or match highlighting in this line */
+ if (vcol == fromcol
+ || (has_mbyte && vcol + 1 == fromcol && n_extra == 0
+ && (*mb_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 */
+
+ if (!n_extra) {
+ /*
+ * Check for start/end of search pattern match.
+ * After end, check for start/end of next match.
+ * When another match, have to check for start again.
+ * Watch out for matching an empty string!
+ * Do this for 'search_hl' and the match list (ordered by
+ * priority).
+ */
+ v = (long)(ptr - line);
+ cur = wp->w_match_head;
+ shl_flag = FALSE;
+ while (cur != NULL || shl_flag == FALSE) {
+ if (shl_flag == FALSE
+ && ((cur != NULL
+ && cur->priority > SEARCH_HL_PRIORITY)
+ || cur == NULL)) {
+ shl = &search_hl;
+ shl_flag = TRUE;
+ } else
+ shl = &cur->hl;
+ while (shl->rm.regprog != NULL) {
+ if (shl->startcol != MAXCOL
+ && v >= (long)shl->startcol
+ && v < (long)shl->endcol) {
+ shl->attr_cur = shl->attr;
+ } else if (v == (long)shl->endcol) {
+ shl->attr_cur = 0;
+
+ next_search_hl(wp, shl, lnum, (colnr_T)v);
+
+ /* Need to get the line again, a multi-line regexp
+ * may have made it invalid. */
+ line = ml_get_buf(wp->w_buffer, lnum, FALSE);
+ ptr = line + v;
+
+ if (shl->lnum == lnum) {
+ shl->startcol = shl->rm.startpos[0].col;
+ if (shl->rm.endpos[0].lnum == 0)
+ shl->endcol = shl->rm.endpos[0].col;
+ else
+ shl->endcol = MAXCOL;
+
+ if (shl->startcol == shl->endcol) {
+ /* highlight empty match, try again after
+ * it */
+ if (has_mbyte)
+ shl->endcol += (*mb_ptr2len)(line
+ + shl->endcol);
+ else
+ ++shl->endcol;
+ }
+
+ /* Loop to check if the match starts at the
+ * current position */
+ continue;
+ }
+ }
+ break;
+ }
+ if (shl != &search_hl && cur != NULL)
+ cur = cur->next;
+ }
+
+ /* Use attributes from match with highest priority among
+ * 'search_hl' and the match list. */
+ search_attr = search_hl.attr_cur;
+ cur = wp->w_match_head;
+ shl_flag = FALSE;
+ while (cur != NULL || shl_flag == FALSE) {
+ if (shl_flag == FALSE
+ && ((cur != NULL
+ && cur->priority > SEARCH_HL_PRIORITY)
+ || cur == NULL)) {
+ shl = &search_hl;
+ shl_flag = TRUE;
+ } else
+ shl = &cur->hl;
+ if (shl->attr_cur != 0)
+ search_attr = shl->attr_cur;
+ if (shl != &search_hl && cur != NULL)
+ cur = cur->next;
+ }
+ }
+
+ if (diff_hlf != (hlf_T)0) {
+ if (diff_hlf == HLF_CHD && ptr - line >= change_start
+ && 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);
+ }
+
+ /* Decide which of the highlight attributes to use. */
+ attr_pri = TRUE;
+ if (area_attr != 0)
+ char_attr = area_attr;
+ else if (search_attr != 0)
+ char_attr = search_attr;
+#ifdef LINE_ATTR
+ /* Use line_attr when not in the Visual or 'incsearch' area
+ * (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))
+ char_attr = line_attr;
+#endif
+ else {
+ attr_pri = FALSE;
+ if (has_syntax)
+ char_attr = syntax_attr;
+ else
+ char_attr = 0;
+ }
+ }
+
+ /*
+ * Get the next character to put on the screen.
+ */
+ /*
+ * The "p_extra" points to the extra stuff that is inserted to
+ * represent special characters (non-printable stuff) and other
+ * things. When all characters are the same, c_extra is used.
+ * "p_extra" must end in a NUL to avoid mb_ptr2len() reads past
+ * "p_extra[n_extra]".
+ * For the '$' of the 'list' option, n_extra == 1, p_extra == "".
+ */
+ 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;
+ u8cc[0] = 0;
+ c = 0xc0;
+ } 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)
+ mb_l = 1;
+ else if (mb_l > 1) {
+ mb_c = utfc_ptr2char(p_extra, u8cc);
+ 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 >= W_WIDTH(wp) - 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;
+ } else {
+ n_extra -= mb_l - 1;
+ p_extra += mb_l - 1;
+ }
+ }
+ ++p_extra;
+ }
+ --n_extra;
+ } else {
+ /*
+ * Get a character from the line itself.
+ */
+ 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 (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;
+
+ /* 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)
+ u8cc[i] = u8cc[i - 1];
+ u8cc[0] = mb_c;
+ mb_c = ' ';
+ }
+ }
+
+ if ((mb_l == 1 && c >= 0x80)
+ || (mb_l >= 1 && mb_c == 0)
+ || (mb_l > 1 && (!vim_isprintc(mb_c)
+# ifdef UNICODE16
+ || mb_c >= 0x10000
+# endif
+ ))) {
+ /*
+ * Illegal UTF-8 byte: display as <xx>.
+ * Non-BMP character : display as ? or fullwidth ?.
+ */
+# ifdef UNICODE16
+ if (mb_c < 0x10000)
+# endif
+ {
+ transchar_hex(extra, mb_c);
+ if (wp->w_p_rl) /* reverse */
+ rl_mirror(extra);
+ }
+# ifdef UNICODE16
+ else if (utf_char2cells(mb_c) != 2)
+ STRCPY(extra, "?");
+ else
+ /* 0xff1f in UTF-8: full-width '?' */
+ STRCPY(extra, "\357\274\237");
+# endif
+
+ p_extra = extra;
+ c = *p_extra;
+ mb_c = mb_ptr2char_adv(&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 */
+ }
+ } else if (mb_l == 0) /* at the NUL at end-of-line */
+ mb_l = 1;
+ else if (p_arshape && !p_tbidi && ARABIC_CHAR(mb_c)) {
+ /* Do Arabic shaping. */
+ int pc, pc1, nc;
+ int pcc[MAX_MCO];
+
+ /* 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(ptr + mb_l);
+ prev_c1 = u8cc[0];
+ } else {
+ pc = utfc_ptr2char(ptr + mb_l, pcc);
+ nc = prev_c;
+ pc1 = pcc[0];
+ }
+ prev_c = mb_c;
+
+ mb_c = arabic_shape(mb_c, &c, &u8cc[0], pc, pc1, nc);
+ } else
+ prev_c = mb_c;
+ } else { /* enc_dbcs */
+ mb_l = MB_BYTE2LEN(c);
+ if (mb_l == 0) /* at the NUL at end-of-line */
+ mb_l = 1;
+ else if (mb_l > 1) {
+ /* We assume a second byte below 32 is illegal.
+ * Hopefully this is OK for all double-byte encodings!
+ */
+ if (ptr[1] >= 32)
+ mb_c = (c << 8) + ptr[1];
+ else {
+ if (ptr[1] == NUL) {
+ /* head byte at end of line */
+ mb_l = 1;
+ transchar_nonprint(extra, c);
+ } else {
+ /* illegal tail byte */
+ mb_l = 2;
+ STRCPY(extra, "XX");
+ }
+ p_extra = extra;
+ n_extra = (int)STRLEN(extra) - 1;
+ c_extra = NUL;
+ 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 */
+ }
+ mb_c = c;
+ }
+ }
+ }
+ /* 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 >= W_WIDTH(wp) - 1))
+ && (*mb_char2cells)(mb_c) == 2) {
+ c = '>';
+ mb_c = c;
+ 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)
+ 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
+ * characters. */
+ if (n_skip > 0 && mb_l > 1 && n_extra == 0) {
+ n_extra = 1;
+ c_extra = MB_FILLER_CHAR;
+ 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 */
+ }
+ mb_c = c;
+ mb_utf8 = FALSE;
+ mb_l = 1;
+ }
+
+ }
+ ++ptr;
+
+ /* 'list' : change char 160 to lcs_nbsp. */
+ if (wp->w_p_list && (c == 160
+ || (mb_utf8 && mb_c == 160)
+ ) && lcs_nbsp) {
+ c = lcs_nbsp;
+ if (area_attr == 0 && search_attr == 0) {
+ n_attr = 1;
+ extra_attr = hl_attr(HLF_8);
+ saved_attr2 = char_attr; /* save current attr */
+ }
+ mb_c = c;
+ if (enc_utf8 && (*mb_char2len)(c) > 1) {
+ mb_utf8 = TRUE;
+ u8cc[0] = 0;
+ c = 0xc0;
+ } else
+ mb_utf8 = FALSE;
+ }
+
+ if (extra_check) {
+ int can_spell = TRUE;
+
+ /* Get syntax attribute, unless still at the start of the line
+ * (double-wide char that doesn't fit). */
+ v = (long)(ptr - line);
+ if (has_syntax && v > 0) {
+ /* Get the syntax attribute for the character. If there
+ * is an error, disable syntax highlighting. */
+ save_did_emsg = did_emsg;
+ did_emsg = FALSE;
+
+ syntax_attr = get_syntax_attr((colnr_T)v - 1,
+ has_spell ? &can_spell :
+ NULL, FALSE);
+
+ if (did_emsg) {
+ wp->w_s->b_syn_error = TRUE;
+ has_syntax = FALSE;
+ } else
+ did_emsg = save_did_emsg;
+
+ /* Need to get the line again, a multi-line regexp may
+ * have made it invalid. */
+ line = ml_get_buf(wp->w_buffer, lnum, FALSE);
+ ptr = line + v;
+
+ if (!attr_pri)
+ char_attr = syntax_attr;
+ else
+ char_attr = hl_combine_attr(syntax_attr, char_attr);
+ /* no concealing past the end of the line, it interferes
+ * with line highlighting */
+ if (c == NUL)
+ syntax_flags = 0;
+ else
+ syntax_flags = get_syntax_info(&syntax_seqnr);
+ }
+
+ /* Check spelling (unless at the end of the line).
+ * Only do this when there is no syntax highlighting, the
+ * @Spell cluster is not used or the current syntax item
+ * contains the @Spell cluster. */
+ if (has_spell && v >= word_end && v > cur_checked_col) {
+ spell_attr = 0;
+ if (!attr_pri)
+ char_attr = syntax_attr;
+ if (c != 0 && (
+ !has_syntax ||
+ can_spell)) {
+ char_u *prev_ptr, *p;
+ int len;
+ hlf_T spell_hlf = HLF_COUNT;
+ if (has_mbyte) {
+ prev_ptr = ptr - mb_l;
+ v -= mb_l - 1;
+ } else
+ prev_ptr = ptr - 1;
+
+ /* 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
+ p = prev_ptr;
+ cap_col -= (int)(prev_ptr - line);
+ len = spell_check(wp, p, &spell_hlf, &cap_col,
+ nochange);
+ word_end = v + len;
+
+ /* In Insert mode only highlight a word that
+ * doesn't touch the cursor. */
+ if (spell_hlf != HLF_COUNT
+ && (State & INSERT) != 0
+ && wp->w_cursor.lnum == lnum
+ && wp->w_cursor.col >=
+ (colnr_T)(prev_ptr - line)
+ && wp->w_cursor.col < (colnr_T)word_end) {
+ spell_hlf = HLF_COUNT;
+ spell_redraw_lnum = lnum;
+ }
+
+ if (spell_hlf == HLF_COUNT && p != prev_ptr
+ && (p - nextline) + len > nextline_idx) {
+ /* Remember that the good word continues at the
+ * start of the next line. */
+ checked_lnum = lnum + 1;
+ checked_col = (int)((p - nextline) + len - nextline_idx);
+ }
+
+ /* Turn index into actual attributes. */
+ if (spell_hlf != HLF_COUNT)
+ spell_attr = highlight_attr[spell_hlf];
+
+ if (cap_col > 0) {
+ if (p != prev_ptr
+ && (p - nextline) + cap_col >= nextline_idx) {
+ /* Remember that the word in the next line
+ * must start with a capital. */
+ capcol_lnum = lnum + 1;
+ cap_col = (int)((p - nextline) + cap_col
+ - nextline_idx);
+ } else
+ /* Compute the actual column. */
+ cap_col += (int)(prev_ptr - line);
+ }
+ }
+ }
+ if (spell_attr != 0) {
+ if (!attr_pri)
+ char_attr = hl_combine_attr(char_attr, spell_attr);
+ else
+ char_attr = hl_combine_attr(spell_attr, char_attr);
+ }
+ /*
+ * Found last space before word: check for line break.
+ */
+ if (wp->w_p_lbr && vim_isbreak(c) && !vim_isbreak(*ptr)
+ && !wp->w_p_list) {
+ n_extra = win_lbr_chartabsize(wp, ptr - (
+ has_mbyte ? mb_l :
+ 1), (colnr_T)vcol, NULL) - 1;
+ c_extra = ' ';
+ if (vim_iswhite(c)) {
+ if (c == TAB)
+ /* See "Tab alignment" below. */
+ FIX_FOR_BOGUSCOLS;
+ c = ' ';
+ }
+ }
+
+ if (trailcol != MAXCOL && ptr > line + trailcol && c == ' ') {
+ c = lcs_trail;
+ if (!attr_pri) {
+ n_attr = 1;
+ extra_attr = hl_attr(HLF_8);
+ saved_attr2 = char_attr; /* save current attr */
+ }
+ mb_c = c;
+ if (enc_utf8 && (*mb_char2len)(c) > 1) {
+ mb_utf8 = TRUE;
+ u8cc[0] = 0;
+ c = 0xc0;
+ } 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 (c == TAB && (!wp->w_p_list || lcs_tab1)) {
+ /* tab amount depends on current column */
+ n_extra = (int)wp->w_buffer->b_p_ts
+ - vcol % (int)wp->w_buffer->b_p_ts - 1;
+ /* Tab alignment should be identical regardless of
+ * 'conceallevel' value. So tab compensates of all
+ * previous concealed characters, and thus resets vcol_off
+ * and boguscols accumulated so far in the line. Note that
+ * the tab can be longer than 'tabstop' when there
+ * are concealed characters. */
+ FIX_FOR_BOGUSCOLS;
+ mb_utf8 = FALSE; /* don't draw as UTF-8 */
+ if (wp->w_p_list) {
+ c = lcs_tab1;
+ c_extra = lcs_tab2;
+ n_attr = n_extra + 1;
+ extra_attr = hl_attr(HLF_8);
+ saved_attr2 = char_attr; /* save current attr */
+ mb_c = c;
+ if (enc_utf8 && (*mb_char2len)(c) > 1) {
+ mb_utf8 = TRUE;
+ u8cc[0] = 0;
+ c = 0xc0;
+ }
+ } else {
+ c_extra = ' ';
+ c = ' ';
+ }
+ } else if (c == NUL
+ && ((wp->w_p_list && lcs_eol > 0)
+ || ((fromcol >= 0 || fromcol_prev >= 0)
+ && tocol > vcol
+ && VIsual_mode != Ctrl_V
+ && (
+ wp->w_p_rl ? (col >= 0) :
+ (col < W_WIDTH(wp)))
+ && !(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
+# ifdef LINE_ATTR
+ &&
+# endif
+# ifdef LINE_ATTR
+ line_attr == 0
+# endif
+ ) {
+ /* In virtualedit, visual selections may extend
+ * beyond end of line. */
+ if (area_highlighting && virtual_active()
+ && tocol != MAXCOL && vcol < tocol)
+ n_extra = 0;
+ else {
+ p_extra = at_end_str;
+ n_extra = 1;
+ c_extra = NUL;
+ }
+ }
+ if (wp->w_p_list)
+ c = lcs_eol;
+ else
+ c = ' ';
+ lcs_eol_one = -1;
+ --ptr; /* put it back at the NUL */
+ if (!attr_pri) {
+ extra_attr = hl_attr(HLF_AT);
+ n_attr = 1;
+ }
+ mb_c = c;
+ if (enc_utf8 && (*mb_char2len)(c) > 1) {
+ mb_utf8 = TRUE;
+ u8cc[0] = 0;
+ c = 0xc0;
+ } else
+ mb_utf8 = FALSE; /* don't draw as UTF-8 */
+ } else if (c != NUL) {
+ p_extra = transchar(c);
+ if ((dy_flags & DY_UHEX) && wp->w_p_rl)
+ rl_mirror(p_extra); /* reverse "<12>" */
+ n_extra = byte2cells(c) - 1;
+ c_extra = NUL;
+ c = *p_extra++;
+ if (!attr_pri) {
+ n_attr = n_extra + 1;
+ extra_attr = hl_attr(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')
+ && virtual_active()
+ && tocol != MAXCOL
+ && vcol < tocol
+ && (
+ wp->w_p_rl ? (col >= 0) :
+ (col < W_WIDTH(wp)))) {
+ c = ' ';
+ --ptr; /* put it back at the NUL */
+ }
+#if defined(LINE_ATTR)
+ else if ((
+ diff_hlf != (hlf_T)0 ||
+ line_attr != 0
+ ) && (
+ wp->w_p_rl ? (col >= 0) :
+ (col
+ - boguscols
+ < W_WIDTH(wp)))) {
+ /* 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);
+ }
+ }
+#endif
+ }
+
+ if ( wp->w_p_cole > 0
+ && (wp != curwin || lnum != wp->w_cursor.lnum ||
+ conceal_cursor_line(wp))
+ && (syntax_flags & HL_CONCEAL) != 0
+ && !(lnum_in_visual_area
+ && vim_strchr(wp->w_p_cocu, 'v') == NULL)) {
+ char_attr = conceal_attr;
+ if (prev_syntax_id != syntax_seqnr
+ && (syn_get_sub_char() != NUL || wp->w_p_cole == 1)
+ && wp->w_p_cole != 3) {
+ /* First time at this concealed item: display one
+ * character. */
+ if (syn_get_sub_char() != NUL)
+ c = syn_get_sub_char();
+ else if (lcs_conceal != NUL)
+ c = lcs_conceal;
+ else
+ c = ' ';
+
+ prev_syntax_id = syntax_seqnr;
+
+ if (n_extra > 0)
+ vcol_off += n_extra;
+ vcol += n_extra;
+ if (wp->w_p_wrap && n_extra > 0) {
+ if (wp->w_p_rl) {
+ col -= n_extra;
+ boguscols -= n_extra;
+ } else {
+ boguscols += n_extra;
+ col += n_extra;
+ }
+ }
+ n_extra = 0;
+ n_attr = 0;
+ } else if (n_skip == 0) {
+ is_concealing = TRUE;
+ n_skip = 1;
+ }
+ mb_c = c;
+ if (enc_utf8 && (*mb_char2len)(c) > 1) {
+ mb_utf8 = TRUE;
+ u8cc[0] = 0;
+ c = 0xc0;
+ } else
+ mb_utf8 = FALSE; /* don't draw as UTF-8 */
+ } else {
+ prev_syntax_id = 0;
+ is_concealing = FALSE;
+ }
+ }
+
+ /* In the cursor line and we may be concealing characters: correct
+ * the cursor column when we reach its position. */
+ if (!did_wcol && draw_state == WL_LINE
+ && wp == curwin && lnum == wp->w_cursor.lnum
+ && conceal_cursor_line(wp)
+ && (int)wp->w_virtcol <= vcol + n_skip) {
+ wp->w_wcol = col - boguscols;
+ wp->w_wrow = row;
+ did_wcol = TRUE;
+ }
+
+ /* Don't override visual selection highlighting. */
+ if (n_attr > 0
+ && draw_state == WL_LINE
+ && !attr_pri)
+ char_attr = extra_attr;
+
+ /*
+ * Handle the case where we are in column 0 but not on the first
+ * character of the line and the user wants us to show us a
+ * special character (via 'listchars' option "precedes:<char>".
+ */
+ if (lcs_prec_todo != NUL
+ && (wp->w_p_wrap ? wp->w_skipcol > 0 : wp->w_leftcol > 0)
+ && filler_todo <= 0
+ && draw_state > WL_NR
+ && c != NUL) {
+ c = lcs_prec;
+ lcs_prec_todo = NUL;
+ if (has_mbyte && (*mb_char2cells)(mb_c) > 1) {
+ /* Double-width character being overwritten by the "precedes"
+ * character, need to fill up half the character. */
+ c_extra = MB_FILLER_CHAR;
+ n_extra = 1;
+ n_attr = 2;
+ extra_attr = hl_attr(HLF_AT);
+ }
+ mb_c = c;
+ if (enc_utf8 && (*mb_char2len)(c) > 1) {
+ mb_utf8 = TRUE;
+ u8cc[0] = 0;
+ c = 0xc0;
+ } else
+ mb_utf8 = FALSE; /* don't draw as UTF-8 */
+ if (!attr_pri) {
+ saved_attr3 = char_attr; /* save current attr */
+ char_attr = hl_attr(HLF_AT); /* later copied to char_attr */
+ n_attr3 = 1;
+ }
+ }
+
+ /*
+ * At end of the text line or just after the last character.
+ */
+ if (c == NUL
+#if defined(LINE_ATTR)
+ || did_line_attr == 1
+#endif
+ ) {
+ 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 {
+ cur = wp->w_match_head;
+ while (cur != NULL) {
+ if (prevcol == (long)cur->hl.startcol) {
+ prevcol_hl_flag = TRUE;
+ break;
+ }
+ cur = cur->next;
+ }
+ }
+ if (lcs_eol == lcs_eol_one
+ && ((area_attr != 0 && vcol == fromcol
+ && (VIsual_mode != Ctrl_V
+ || lnum == VIsual.lnum
+ || lnum == curwin->w_cursor.lnum)
+ && c == NUL)
+ /* highlight 'hlsearch' match at end of line */
+ || (prevcol_hl_flag == TRUE
+# if defined(LINE_ATTR)
+ && did_line_attr <= 1
+# endif
+ )
+ )) {
+ int n = 0;
+
+ if (wp->w_p_rl) {
+ if (col < 0)
+ n = 1;
+ } else {
+ if (col >= W_WIDTH(wp))
+ n = -1;
+ }
+ if (n != 0) {
+ /* At the window boundary, highlight the last character
+ * instead (better than nothing). */
+ off += n;
+ col += n;
+ } else {
+ /* Add a blank character to highlight. */
+ ScreenLines[off] = ' ';
+ if (enc_utf8)
+ ScreenLinesUC[off] = 0;
+ }
+ if (area_attr == 0) {
+ /* Use attributes from match with highest priority among
+ * 'search_hl' and the match list. */
+ char_attr = search_hl.attr;
+ cur = wp->w_match_head;
+ shl_flag = FALSE;
+ while (cur != NULL || shl_flag == FALSE) {
+ if (shl_flag == FALSE
+ && ((cur != NULL
+ && cur->priority > SEARCH_HL_PRIORITY)
+ || cur == NULL)) {
+ shl = &search_hl;
+ shl_flag = TRUE;
+ } else
+ shl = &cur->hl;
+ if ((ptr - line) - 1 == (long)shl->startcol)
+ char_attr = shl->attr;
+ if (shl != &search_hl && cur != NULL)
+ cur = cur->next;
+ }
+ }
+ ScreenAttrs[off] = char_attr;
+ if (wp->w_p_rl) {
+ --col;
+ --off;
+ } else {
+ ++col;
+ ++off;
+ }
+ ++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)
+ v = wp->w_skipcol;
+ else
+ v = wp->w_leftcol;
+
+ /* check if line ends before left margin */
+ if (vcol < v + col - win_col_off(wp))
+ vcol = v + col - win_col_off(wp);
+ /* Get rid of the boguscols now, we want to draw until the right
+ * edge for 'cursorcolumn'. */
+ col -= boguscols;
+ boguscols = 0;
+
+ if (draw_color_col)
+ draw_color_col = advance_color_col(VCOL_HLC, &color_cols);
+
+ if (((wp->w_p_cuc
+ && (int)wp->w_virtcol >= VCOL_HLC - eol_hl_off
+ && (int)wp->w_virtcol <
+ W_WIDTH(wp) * (row - startrow + 1) + v
+ && lnum != wp->w_cursor.lnum)
+ || draw_color_col)
+ && !wp->w_p_rl
+ ) {
+ int rightmost_vcol = 0;
+ int i;
+
+ 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])
+ rightmost_vcol = color_cols[i];
+
+ while (col < W_WIDTH(wp)) {
+ 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;
+
+ if (VCOL_HLC >= rightmost_vcol)
+ break;
+
+ ++vcol;
+ }
+ }
+
+ SCREEN_LINE(screen_row, W_WINCOL(wp), col,
+ (int)W_WIDTH(wp), wp->w_p_rl);
+ row++;
+
+ /*
+ * Update w_cline_height and w_cline_folded if the cursor line was
+ * updated (saves a call to plines() later).
+ */
+ if (wp == curwin && lnum == curwin->w_cursor.lnum) {
+ curwin->w_cline_row = startrow;
+ curwin->w_cline_height = row - startrow;
+ curwin->w_cline_folded = FALSE;
+ curwin->w_valid |= (VALID_CHEIGHT|VALID_CROW);
+ }
+
+ break;
+ }
+
+ /* line continues beyond line end */
+ if (lcs_ext
+ && !wp->w_p_wrap
+ && filler_todo <= 0
+ && (
+ wp->w_p_rl ? col == 0 :
+ col == W_WIDTH(wp) - 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);
+ mb_c = c;
+ if (enc_utf8 && (*mb_char2len)(c) > 1) {
+ mb_utf8 = TRUE;
+ u8cc[0] = 0;
+ c = 0xc0;
+ } else
+ mb_utf8 = FALSE;
+ }
+
+ /* advance to the next 'colorcolumn' */
+ if (draw_color_col)
+ draw_color_col = advance_color_col(VCOL_HLC, &color_cols);
+
+ /* Highlight the cursor column if 'cursorcolumn' is set. But don't
+ * highlight the cursor position itself.
+ * Also highlight the 'colorcolumn' if it is different than
+ * 'cursorcolumn' */
+ vcol_save_attr = -1;
+ if (draw_state == WL_LINE && !lnum_in_visual_area) {
+ 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));
+ } 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));
+ }
+ }
+
+ /*
+ * Store character to be displayed.
+ * Skip characters that are left of the screen for 'nowrap'.
+ */
+ vcol_prev = vcol;
+ if (draw_state < WL_LINE || n_skip <= 0) {
+ /*
+ * Store the character.
+ */
+ if (has_mbyte && wp->w_p_rl && (*mb_char2cells)(mb_c) > 1) {
+ /* A double-wide character is: put first halve in left cell. */
+ --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 (multi_attr) {
+ ScreenAttrs[off] = multi_attr;
+ multi_attr = 0;
+ } else
+ ScreenAttrs[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;
+ ++vcol;
+ /* When "tocol" is halfway a character, set it to the end of
+ * the character, otherwise highlighting won't stop. */
+ if (tocol == vcol)
+ ++tocol;
+ if (wp->w_p_rl) {
+ /* now it's time to backup one cell */
+ --off;
+ --col;
+ }
+ }
+ if (wp->w_p_rl) {
+ --off;
+ --col;
+ } else {
+ ++off;
+ ++col;
+ }
+ } else if (wp->w_p_cole > 0 && is_concealing) {
+ --n_skip;
+ ++vcol_off;
+ if (n_extra > 0)
+ vcol_off += n_extra;
+ if (wp->w_p_wrap) {
+ /*
+ * Special voodoo required if 'wrap' is on.
+ *
+ * Advance the column indicator to force the line
+ * drawing to wrap early. This will make the line
+ * take up the same screen space when parts are concealed,
+ * so that cursor line computations aren't messed up.
+ *
+ * To avoid the fictitious advance of 'col' causing
+ * trailing junk to be written out of the screen line
+ * we are building, 'boguscols' keeps track of the number
+ * of bad columns we have advanced.
+ */
+ if (n_extra > 0) {
+ vcol += n_extra;
+ if (wp->w_p_rl) {
+ col -= n_extra;
+ boguscols -= n_extra;
+ } else {
+ col += n_extra;
+ boguscols += n_extra;
+ }
+ n_extra = 0;
+ n_attr = 0;
+ }
+
+
+ if (has_mbyte && (*mb_char2cells)(mb_c) > 1) {
+ /* Need to fill two screen columns. */
+ if (wp->w_p_rl) {
+ --boguscols;
+ --col;
+ } else {
+ ++boguscols;
+ ++col;
+ }
+ }
+
+ if (wp->w_p_rl) {
+ --boguscols;
+ --col;
+ } else {
+ ++boguscols;
+ ++col;
+ }
+ } else {
+ if (n_extra > 0) {
+ vcol += n_extra;
+ n_extra = 0;
+ n_attr = 0;
+ }
+ }
+
+ } else
+ --n_skip;
+
+ /* Only advance the "vcol" when after the 'number' or 'relativenumber'
+ * column. */
+ if (draw_state > WL_NR
+ && filler_todo <= 0
+ )
+ ++vcol;
+
+ if (vcol_save_attr >= 0)
+ char_attr = vcol_save_attr;
+
+ /* restore attributes after "predeces" in 'listchars' */
+ if (draw_state > WL_NR && n_attr3 > 0 && --n_attr3 == 0)
+ char_attr = saved_attr3;
+
+ /* restore attributes after last 'listchars' or 'number' char */
+ if (n_attr > 0 && draw_state == WL_LINE && --n_attr == 0)
+ char_attr = saved_attr2;
+
+ /*
+ * 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 >= W_WIDTH(wp)))
+ && (*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, W_WINCOL(wp), col - boguscols,
+ (int)W_WIDTH(wp), wp->w_p_rl);
+ boguscols = 0;
+ ++row;
+ ++screen_row;
+
+ /* When not wrapping and finished diff lines, or when displayed
+ * '$' and highlighting until last column, break here. */
+ if ((!wp->w_p_wrap
+ && filler_todo <= 0
+ ) || lcs_eol_one == -1)
+ break;
+
+ /* When the window is too narrow draw all "@" lines. */
+ if (draw_state != WL_LINE
+ && filler_todo <= 0
+ ) {
+ win_draw_end(wp, '@', ' ', row, wp->w_height, HLF_AT);
+ draw_vsep_win(wp, row);
+ row = endrow;
+ }
+
+ /* When line got too long for screen break here. */
+ if (row == endrow) {
+ ++row;
+ break;
+ }
+
+ if (screen_cur_row == screen_row - 1
+ && filler_todo <= 0
+ && W_WIDTH(wp) == 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 on a fast tty.
+ * 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 (p_tf
+ && !(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 (screen_cur_col != W_WIDTH(wp))
+ 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)
+ out_char(' ');
+ else
+ out_char(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;
+ screen_start(); /* don't know where cursor is now */
+ }
+ }
+
+ col = 0;
+ off = (unsigned)(current_ScreenLine - ScreenLines);
+ if (wp->w_p_rl) {
+ col = W_WIDTH(wp) - 1; /* col is not used if breaking! */
+ off += col;
+ }
+
+ /* reset the drawing state for the start of a wrapped line */
+ draw_state = WL_START;
+ saved_n_extra = n_extra;
+ saved_p_extra = p_extra;
+ saved_c_extra = c_extra;
+ saved_char_attr = char_attr;
+ n_extra = 0;
+ lcs_prec_todo = lcs_prec;
+ if (filler_todo <= 0)
+ need_showbreak = TRUE;
+ --filler_todo;
+ /* When the filler lines are actually below the last line of the
+ * file, don't draw the line itself, break here. */
+ if (filler_todo == 0 && wp->w_botfill)
+ break;
+ }
+
+ } /* for every character in the line */
+
+ /* After an empty line check first word for capital. */
+ if (*skipwhite(line) == NUL) {
+ capcol_lnum = lnum + 1;
+ cap_col = 0;
+ }
+
+ return row;
+}
+
+static int comp_char_differs __ARGS((int, int));
+
+/*
+ * 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(off_from, off_to)
+int off_from;
+int off_to;
+{
+ 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;
+ }
+ return FALSE;
+}
+
+/*
+ * Check whether the given character needs redrawing:
+ * - the (first byte of the) character is different
+ * - the attributes are different
+ * - 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(off_from, off_to, cols)
+int off_from;
+int off_to;
+int cols;
+{
+ if (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])))
+ ))
+ return TRUE;
+ return FALSE;
+}
+
+/*
+ * 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(row, coloff, endcol, clear_width
+ , rlflag )
+int row;
+int coloff;
+int endcol;
+int clear_width;
+int rlflag;
+{
+ 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;
+
+ 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)
+ ) {
+ ++off_to;
+ ++col;
+ }
+ if (col <= endcol)
+ screen_fill(row, row + 1, col + coloff,
+ endcol + coloff + 1, ' ', ' ', 0);
+ }
+ col = endcol + 1;
+ off_to = LineOffset[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);
+
+ while (col < endcol) {
+ if (has_mbyte && (col + 1 < endcol))
+ char_cells = (*mb_off2cells)(off_from, max_off_from);
+ else
+ char_cells = 1;
+
+ redraw_this = redraw_next;
+ redraw_next = force || char_needs_redraw(off_from + CHAR_CELLS,
+ off_to + CHAR_CELLS, endcol - col - CHAR_CELLS);
+
+
+ if (redraw_this) {
+ /*
+ * Special handling when 'xs' termcap flag set (hpterm):
+ * Attributes for characters are stored at the position where the
+ * cursor is when writing the highlighting code. The
+ * start-highlighting code must be written with the cursor on the
+ * first highlighted character. The stop-highlighting code must
+ * be written with the cursor just after the last highlighted
+ * character.
+ * Overwriting a character doesn't remove it's highlighting. Need
+ * to clear the rest of the line, and force redrawing it
+ * completely.
+ */
+ if ( p_wiv
+ && !force
+ && ScreenAttrs[off_to] != 0
+ && ScreenAttrs[off_from] != ScreenAttrs[off_to]) {
+ /*
+ * Need to remove highlighting attributes here.
+ */
+ windgoto(row, col + coloff);
+ out_str(T_CE); /* clear rest of this screen line */
+ screen_start(); /* don't know where cursor is now */
+ force = TRUE; /* force redraw of rest of the line */
+ redraw_next = TRUE; /* or else next char would miss out */
+
+ /*
+ * If the previous character was highlighted, need to stop
+ * highlighting at this character.
+ */
+ if (col + coloff > 0 && ScreenAttrs[off_to - 1] != 0) {
+ screen_attr = ScreenAttrs[off_to - 1];
+ term_windgoto(row, col + coloff);
+ screen_stop_highlight();
+ } else
+ screen_attr = 0; /* highlighting has stopped */
+ }
+ 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];
+ }
+ /* 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
+ && ((char_cells == 1
+ && (*mb_off2cells)(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];
+ }
+ }
+ if (char_cells == 2)
+ ScreenLines[off_to + 1] = ScreenLines[off_from + 1];
+
+#if defined(FEAT_GUI) || defined(UNIX)
+ /* The bold trick makes a single column of pixels appear in the
+ * next character. When a bold character is removed, the next
+ * character should be redrawn too. This happens for our own GUI
+ * and for some xterms. */
+ if (
+# ifdef UNIX
+ term_is_xterm
+# endif
+ ) {
+ hl = ScreenAttrs[off_to];
+ if (hl > HL_ALL)
+ hl = syn_attr2attr(hl);
+ if (hl & HL_BOLD)
+ redraw_next = TRUE;
+ }
+#endif
+ 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];
+
+ if (enc_dbcs != 0 && char_cells == 2)
+ screen_char_2(off_to, row, col + coloff);
+ else
+ screen_char(off_to, row, col + coloff);
+ } else if ( p_wiv
+ && col + coloff > 0) {
+ if (ScreenAttrs[off_to] == ScreenAttrs[off_to - 1]) {
+ /*
+ * Don't output stop-highlight when moving the cursor, it will
+ * stop the highlighting when it should continue.
+ */
+ screen_attr = 0;
+ } else if (screen_attr != 0)
+ screen_stop_highlight();
+ }
+
+ 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);
+ }
+
+ if (clear_width > 0
+ && !rlflag
+ ) {
+
+ /* 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] != 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;
+ }
+}
+
+/*
+ * Mirror text "str" for right-left displaying.
+ * Only works for single-byte characters (e.g., numbers).
+ */
+void rl_mirror(str)
+char_u *str;
+{
+ char_u *p1, *p2;
+ int t;
+
+ for (p1 = str, p2 = str + STRLEN(str) - 1; p1 < p2; ++p1, --p2) {
+ t = *p1;
+ *p1 = *p2;
+ *p2 = t;
+ }
+}
+
+/*
+ * mark all status lines for redraw; used after first :cd
+ */
+void status_redraw_all() {
+ win_T *wp;
+
+ for (wp = firstwin; wp; wp = wp->w_next)
+ if (wp->w_status_height) {
+ wp->w_redr_status = TRUE;
+ redraw_later(VALID);
+ }
+}
+
+/*
+ * mark all status lines of the current buffer for redraw
+ */
+void status_redraw_curbuf() {
+ win_T *wp;
+
+ for (wp = firstwin; wp; wp = wp->w_next)
+ if (wp->w_status_height != 0 && wp->w_buffer == curbuf) {
+ wp->w_redr_status = TRUE;
+ redraw_later(VALID);
+ }
+}
+
+/*
+ * Redraw all status lines that need to be redrawn.
+ */
+void redraw_statuslines() {
+ win_T *wp;
+
+ for (wp = firstwin; wp; wp = wp->w_next)
+ if (wp->w_redr_status)
+ win_redr_status(wp);
+ if (redraw_tabline)
+ draw_tabline();
+}
+
+/*
+ * Redraw all status lines at the bottom of frame "frp".
+ */
+void win_redraw_last_status(frp)
+frame_T *frp;
+{
+ if (frp->fr_layout == FR_LEAF)
+ frp->fr_win->w_redr_status = TRUE;
+ else if (frp->fr_layout == FR_ROW) {
+ for (frp = frp->fr_child; frp != NULL; frp = frp->fr_next)
+ win_redraw_last_status(frp);
+ } else { /* frp->fr_layout == FR_COL */
+ frp = frp->fr_child;
+ while (frp->fr_next != NULL)
+ frp = frp->fr_next;
+ win_redraw_last_status(frp);
+ }
+}
+
+/*
+ * Draw the verticap separator right of window "wp" starting with line "row".
+ */
+static void draw_vsep_win(wp, row)
+win_T *wp;
+int row;
+{
+ int hl;
+ int c;
+
+ if (wp->w_vsep_width) {
+ /* draw the vertical separator right of this window */
+ c = fillchar_vsep(&hl);
+ screen_fill(W_WINROW(wp) + row, W_WINROW(wp) + wp->w_height,
+ W_ENDCOL(wp), W_ENDCOL(wp) + 1,
+ c, ' ', hl);
+ }
+}
+
+static int status_match_len __ARGS((expand_T *xp, char_u *s));
+static int skip_status_match_char __ARGS((expand_T *xp, char_u *s));
+
+/*
+ * Get the length of an item as it will be shown in the status line.
+ */
+static int status_match_len(xp, s)
+expand_T *xp;
+char_u *s;
+{
+ int len = 0;
+
+ int emenu = (xp->xp_context == EXPAND_MENUS
+ || xp->xp_context == EXPAND_MENUNAMES);
+
+ /* Check for menu separators - replace with '|'. */
+ if (emenu && menu_is_separator(s))
+ return 1;
+
+ while (*s != NUL) {
+ s += skip_status_match_char(xp, s);
+ len += ptr2cells(s);
+ mb_ptr_adv(s);
+ }
+
+ return len;
+}
+
+/*
+ * Return the number of characters that should be skipped in a status match.
+ * These are backslashes used for escaping. Do show backslashes in help tags.
+ */
+static int skip_status_match_char(xp, s)
+expand_T *xp;
+char_u *s;
+{
+ if ((rem_backslash(s) && xp->xp_context != EXPAND_HELP)
+ || ((xp->xp_context == EXPAND_MENUS
+ || xp->xp_context == EXPAND_MENUNAMES)
+ && (s[0] == '\t' || (s[0] == '\\' && s[1] != NUL)))
+ ) {
+#ifndef BACKSLASH_IN_FILENAME
+ if (xp->xp_shell && csh_like_shell() && s[1] == '\\' && s[2] == '!')
+ return 2;
+#endif
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ * Show wildchar matches in the status line.
+ * Show at least the "match" item.
+ * We start at item 'first_match' in the list and show all matches that fit.
+ *
+ * If inversion is possible we use it. Else '=' characters are used.
+ */
+void win_redr_status_matches(xp, num_matches, matches, match, showtail)
+expand_T *xp;
+int num_matches;
+char_u **matches; /* list of matches */
+int match;
+int showtail;
+{
+#define L_MATCH(m) (showtail ? sm_gettail(matches[m]) : matches[m])
+ int row;
+ char_u *buf;
+ int len;
+ int clen; /* length in screen cells */
+ int fillchar;
+ int attr;
+ int i;
+ int highlight = TRUE;
+ char_u *selstart = NULL;
+ int selstart_col = 0;
+ char_u *selend = NULL;
+ static int first_match = 0;
+ int add_left = FALSE;
+ char_u *s;
+ int emenu;
+ int l;
+
+ if (matches == NULL) /* interrupted completion? */
+ return;
+
+ if (has_mbyte)
+ buf = alloc((unsigned)Columns * MB_MAXBYTES + 1);
+ else
+ buf = alloc((unsigned)Columns + 1);
+ if (buf == NULL)
+ return;
+
+ if (match == -1) { /* don't show match but original text */
+ match = 0;
+ highlight = FALSE;
+ }
+ /* count 1 for the ending ">" */
+ clen = status_match_len(xp, L_MATCH(match)) + 3;
+ if (match == 0)
+ first_match = 0;
+ else if (match < first_match) {
+ /* jumping left, as far as we can go */
+ first_match = match;
+ add_left = TRUE;
+ } else {
+ /* check if match fits on the screen */
+ for (i = first_match; i < match; ++i)
+ 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) {
+ 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)
+ break;
+ }
+ if (i == num_matches)
+ add_left = TRUE;
+ }
+ }
+ if (add_left)
+ while (first_match > 0) {
+ clen += status_match_len(xp, L_MATCH(first_match - 1)) + 2;
+ if ((long)clen >= Columns)
+ break;
+ --first_match;
+ }
+
+ fillchar = fillchar_status(&attr, TRUE);
+
+ if (first_match == 0) {
+ *buf = NUL;
+ len = 0;
+ } else {
+ STRCPY(buf, "< ");
+ len = 2;
+ }
+ clen = len;
+
+ i = first_match;
+ while ((long)(clen + status_match_len(xp, L_MATCH(i)) + 2) < Columns) {
+ if (i == match) {
+ selstart = buf + len;
+ selstart_col = clen;
+ }
+
+ s = L_MATCH(i);
+ /* Check for menu separators - replace with '|' */
+ emenu = (xp->xp_context == EXPAND_MENUS
+ || xp->xp_context == EXPAND_MENUNAMES);
+ if (emenu && menu_is_separator(s)) {
+ STRCPY(buf + len, transchar('|'));
+ l = (int)STRLEN(buf + len);
+ len += l;
+ clen += l;
+ } else
+ for (; *s != NUL; ++s) {
+ s += skip_status_match_char(xp, s);
+ clen += ptr2cells(s);
+ if (has_mbyte && (l = (*mb_ptr2len)(s)) > 1) {
+ STRNCPY(buf + len, s, l);
+ s += l - 1;
+ len += l;
+ } else {
+ STRCPY(buf + len, transchar_byte(*s));
+ len += (int)STRLEN(buf + len);
+ }
+ }
+ if (i == match)
+ selend = buf + len;
+
+ *(buf + len++) = ' ';
+ *(buf + len++) = ' ';
+ clen += 2;
+ if (++i == num_matches)
+ break;
+ }
+
+ if (i != num_matches) {
+ *(buf + len++) = '>';
+ ++clen;
+ }
+
+ buf[len] = NUL;
+
+ row = cmdline_row - 1;
+ if (row >= 0) {
+ if (wild_menu_showing == 0) {
+ 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, TRUE, NULL);
+ ++msg_scrolled;
+ } else {
+ ++cmdline_row;
+ ++row;
+ }
+ wild_menu_showing = WM_SCROLLED;
+ } else {
+ /* Create status line if needed by setting 'laststatus' to 2.
+ * Set 'winminheight' to zero to avoid that the window is
+ * resized. */
+ if (lastwin->w_status_height == 0) {
+ save_p_ls = p_ls;
+ save_p_wmh = p_wmh;
+ p_ls = 2;
+ p_wmh = 0;
+ last_status(FALSE);
+ }
+ wild_menu_showing = WM_SHOWN;
+ }
+ }
+
+ screen_puts(buf, row, 0, attr);
+ if (selstart != NULL && highlight) {
+ *selend = NUL;
+ screen_puts(selstart, row, selstart_col, hl_attr(HLF_WM));
+ }
+
+ screen_fill(row, row + 1, clen, (int)Columns, fillchar, fillchar, attr);
+ }
+
+ win_redraw_last_status(topframe);
+ vim_free(buf);
+}
+
+/*
+ * Redraw the status line of window wp.
+ *
+ * If inversion is possible we use it. Else '=' characters are used.
+ */
+void win_redr_status(wp)
+win_T *wp;
+{
+ int row;
+ char_u *p;
+ int len;
+ int fillchar;
+ int attr;
+ 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)
+ return;
+ 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;
+ } 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);
+
+ get_trans_bufname(wp->w_buffer);
+ p = NameBuff;
+ len = (int)STRLEN(p);
+
+ if (wp->w_buffer->b_help
+ || wp->w_p_pvw
+ || bufIsChanged(wp->w_buffer)
+ || wp->w_buffer->b_p_ro)
+ *(p + len++) = ' ';
+ if (wp->w_buffer->b_help) {
+ STRCPY(p + len, _("[Help]"));
+ len += (int)STRLEN(p + len);
+ }
+ if (wp->w_p_pvw) {
+ STRCPY(p + len, _("[Preview]"));
+ len += (int)STRLEN(p + len);
+ }
+ if (bufIsChanged(wp->w_buffer)) {
+ STRCPY(p + len, "[+]");
+ len += 3;
+ }
+ if (wp->w_buffer->b_p_ro) {
+ STRCPY(p + len, _("[RO]"));
+ len += 4;
+ }
+
+ this_ru_col = ru_col - (Columns - W_WIDTH(wp));
+ if (this_ru_col < (W_WIDTH(wp) + 1) / 2)
+ this_ru_col = (W_WIDTH(wp) + 1) / 2;
+ if (this_ru_col <= 1) {
+ p = (char_u *)"<"; /* No room for file name! */
+ len = 1;
+ } else if (has_mbyte) {
+ int clen = 0, i;
+
+ /* Count total number of display cells. */
+ clen = mb_string2cells(p, -1);
+
+ /* 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);
+ 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 = W_WINROW(wp) + wp->w_height;
+ screen_puts(p, row, W_WINCOL(wp), attr);
+ screen_fill(row, row + 1, len + W_WINCOL(wp),
+ this_ru_col + W_WINCOL(wp), fillchar, fillchar, attr);
+
+ if (get_keymap_str(wp, NameBuff, MAXPATHL)
+ && (int)(this_ru_col - len) > (int)(STRLEN(NameBuff) + 1))
+ screen_puts(NameBuff, row, (int)(this_ru_col - STRLEN(NameBuff)
+ - 1 + W_WINCOL(wp)), attr);
+
+ win_redr_ruler(wp, TRUE);
+ }
+
+ /*
+ * 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, W_WINROW(wp) + wp->w_height, W_ENDCOL(wp),
+ attr);
+ }
+ busy = FALSE;
+}
+
+/*
+ * Redraw the status line according to 'statusline' and take care of any
+ * errors encountered.
+ */
+static void redraw_custom_statusline(wp)
+win_T *wp;
+{
+ static int entered = FALSE;
+ int save_called_emsg = called_emsg;
+
+ /* When called recursively return. This can happen when the statusline
+ * contains an expression that triggers a redraw. */
+ if (entered)
+ 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. */
+ 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;
+}
+
+/*
+ * Return TRUE if the status line of window "wp" is connected to the status
+ * line of the window right of it. If not, then it's a vertical separator.
+ * Only call if (wp->w_vsep_width != 0).
+ */
+int stl_connected(wp)
+win_T *wp;
+{
+ frame_T *fr;
+
+ fr = wp->w_frame;
+ while (fr->fr_parent != NULL) {
+ if (fr->fr_parent->fr_layout == FR_COL) {
+ if (fr->fr_next != NULL)
+ break;
+ } else {
+ if (fr->fr_next != NULL)
+ return TRUE;
+ }
+ fr = fr->fr_parent;
+ }
+ return FALSE;
+}
+
+
+/*
+ * Get the value to show for the language mappings, active 'keymap'.
+ */
+int get_keymap_str(wp, buf, len)
+win_T *wp;
+char_u *buf; /* buffer for the result */
+int len; /* length of buffer */
+{
+ char_u *p;
+
+ if (wp->w_buffer->b_p_iminsert != B_IMODE_LMAP)
+ return FALSE;
+
+ {
+ buf_T *old_curbuf = curbuf;
+ win_T *old_curwin = curwin;
+ char_u *s;
+
+ curbuf = wp->w_buffer;
+ curwin = wp;
+ STRCPY(buf, "b:keymap_name"); /* must be writable */
+ ++emsg_skip;
+ s = p = eval_to_string(buf, NULL, FALSE);
+ --emsg_skip;
+ curbuf = old_curbuf;
+ curwin = old_curwin;
+ if (p == NULL || *p == NUL) {
+ if (wp->w_buffer->b_kmap_state & KEYMAP_LOADED)
+ p = wp->w_buffer->b_p_keymap;
+ else
+ p = (char_u *)"lang";
+ }
+ if ((int)(STRLEN(p) + 3) < len)
+ sprintf((char *)buf, "<%s>", p);
+ else
+ buf[0] = NUL;
+ vim_free(s);
+ }
+ return buf[0] != NUL;
+}
+
+/*
+ * Redraw the status line or ruler of window "wp".
+ * When "wp" is NULL redraw the tab pages line from 'tabline'.
+ */
+static void win_redr_custom(wp, draw_ruler)
+win_T *wp;
+int draw_ruler; /* TRUE or FALSE */
+{
+ static int entered = FALSE;
+ int attr;
+ int curattr;
+ int row;
+ int col = 0;
+ int maxwidth;
+ int width;
+ int n;
+ int len;
+ int fillchar;
+ char_u buf[MAXPATHL];
+ char_u *stl;
+ char_u *p;
+ struct stl_hlrec hltab[STL_MAX_ITEM];
+ struct stl_hlrec tabtab[STL_MAX_ITEM];
+ int use_sandbox = FALSE;
+ win_T *ewp;
+ int p_crb_save;
+
+ /* There is a tiny chance that this gets called recursively: When
+ * redrawing a status line triggers redrawing the ruler or tabline.
+ * Avoid trouble by not allowing recursion. */
+ if (entered)
+ return;
+ entered = TRUE;
+
+ /* setup environment for the task at hand */
+ if (wp == NULL) {
+ /* Use 'tabline'. Always at the first line of the screen. */
+ stl = p_tal;
+ row = 0;
+ fillchar = ' ';
+ attr = hl_attr(HLF_TPF);
+ maxwidth = Columns;
+ use_sandbox = was_set_insecurely((char_u *)"tabline", 0);
+ } else {
+ row = W_WINROW(wp) + wp->w_height;
+ fillchar = fillchar_status(&attr, wp == curwin);
+ maxwidth = W_WIDTH(wp);
+
+ if (draw_ruler) {
+ stl = p_ruf;
+ /* advance past any leading group spec - implicit in ru_col */
+ if (*stl == '%') {
+ if (*++stl == '-')
+ stl++;
+ if (atoi((char *)stl))
+ while (VIM_ISDIGIT(*stl))
+ stl++;
+ if (*stl++ != '(')
+ stl = p_ruf;
+ }
+ col = ru_col - (Columns - W_WIDTH(wp));
+ if (col < (W_WIDTH(wp) + 1) / 2)
+ col = (W_WIDTH(wp) + 1) / 2;
+ maxwidth = W_WIDTH(wp) - col;
+ if (!wp->w_status_height) {
+ row = Rows - 1;
+ --maxwidth; /* writing in last column may cause scrolling */
+ fillchar = ' ';
+ attr = 0;
+ }
+
+ use_sandbox = was_set_insecurely((char_u *)"rulerformat", 0);
+ } else {
+ if (*wp->w_p_stl != NUL)
+ stl = wp->w_p_stl;
+ else
+ stl = p_stl;
+ use_sandbox = was_set_insecurely((char_u *)"statusline",
+ *wp->w_p_stl == NUL ? 0 : OPT_LOCAL);
+ }
+
+ col += W_WINCOL(wp);
+ }
+
+ if (maxwidth <= 0)
+ goto theend;
+
+ /* Temporarily reset 'cursorbind', we don't want a side effect from moving
+ * the cursor away and back. */
+ ewp = wp == NULL ? curwin : wp;
+ p_crb_save = ewp->w_p_crb;
+ ewp->w_p_crb = FALSE;
+
+ /* Make a copy, because the statusline may include a function call that
+ * might change the option value and free the memory. */
+ stl = vim_strsave(stl);
+ width = build_stl_str_hl(ewp, buf, sizeof(buf),
+ stl, use_sandbox,
+ fillchar, maxwidth, hltab, tabtab);
+ vim_free(stl);
+ ewp->w_p_crb = p_crb_save;
+
+ /* Make all characters printable. */
+ p = transstr(buf);
+ if (p != NULL) {
+ vim_strncpy(buf, p, sizeof(buf) - 1);
+ vim_free(p);
+ }
+
+ /* fill up with "fillchar" */
+ len = (int)STRLEN(buf);
+ while (width < maxwidth && len < (int)sizeof(buf) - 1) {
+ len += (*mb_char2bytes)(fillchar, buf + len);
+ ++width;
+ }
+ buf[len] = NUL;
+
+ /*
+ * Draw each snippet with the specified highlighting.
+ */
+ curattr = attr;
+ p = buf;
+ for (n = 0; hltab[n].start != NULL; n++) {
+ len = (int)(hltab[n].start - p);
+ screen_puts_len(p, len, row, col, curattr);
+ col += vim_strnsize(p, len);
+ p = hltab[n].start;
+
+ if (hltab[n].userhl == 0)
+ curattr = attr;
+ else if (hltab[n].userhl < 0)
+ curattr = syn_id2attr(-hltab[n].userhl);
+ else if (wp != NULL && wp != curwin && wp->w_status_height != 0)
+ curattr = highlight_stlnc[hltab[n].userhl - 1];
+ else
+ curattr = highlight_user[hltab[n].userhl - 1];
+ }
+ screen_puts(p, row, col, curattr);
+
+ if (wp == NULL) {
+ /* Fill the TabPageIdxs[] array for clicking in the tab pagesline. */
+ col = 0;
+ len = 0;
+ p = buf;
+ fillchar = 0;
+ for (n = 0; tabtab[n].start != NULL; n++) {
+ len += vim_strnsize(p, (int)(tabtab[n].start - p));
+ while (col < len)
+ TabPageIdxs[col++] = fillchar;
+ p = tabtab[n].start;
+ fillchar = tabtab[n].userhl;
+ }
+ while (col < Columns)
+ TabPageIdxs[col++] = fillchar;
+ }
+
+theend:
+ entered = FALSE;
+}
+
+
+/*
+ * Output a single character directly to the screen and update ScreenLines.
+ */
+void screen_putchar(c, row, col, attr)
+int c;
+int row, col;
+int attr;
+{
+ char_u buf[MB_MAXBYTES + 1];
+
+ if (has_mbyte)
+ buf[(*mb_char2bytes)(c, buf)] = NUL;
+ else {
+ buf[0] = c;
+ buf[1] = NUL;
+ }
+ screen_puts(buf, row, col, attr);
+}
+
+/*
+ * Get a single character directly from ScreenLines into "bytes[]".
+ * Also return its attribute in *attrp;
+ */
+void screen_getbytes(row, col, bytes, attrp)
+int row, col;
+char_u *bytes;
+int *attrp;
+{
+ unsigned off;
+
+ /* 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;
+
+ 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 screen_comp_differs __ARGS((int, int*));
+
+/*
+ * 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(off, u8cc)
+int off;
+int *u8cc;
+{
+ int i;
+
+ for (i = 0; i < Screen_mco; ++i) {
+ if (ScreenLinesC[i][off] != (u8char_T)u8cc[i])
+ return TRUE;
+ if (u8cc[i] == 0)
+ break;
+ }
+ 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(text, row, col, attr)
+char_u *text;
+int row;
+int col;
+int attr;
+{
+ screen_puts_len(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(text, len, row, col, attr)
+char_u *text;
+int len;
+int row;
+int col;
+int attr;
+{
+ unsigned off;
+ char_u *ptr = text;
+ int c;
+ unsigned max_off;
+ int mbyte_blen = 1;
+ int mbyte_cells = 1;
+ int u8c = 0;
+ int u8cc[MAX_MCO];
+ int clear_next_cell = FALSE;
+ int prev_c = 0; /* previous Arabic character */
+ int pc, nc, nc1;
+ int pcc[MAX_MCO];
+ int force_redraw_this;
+ int force_redraw_next = FALSE;
+ int need_redraw;
+
+ if (ScreenLines == NULL || row >= screen_Rows) /* safety check */
+ return;
+ off = LineOffset[row] + col;
+
+ /* When drawing over the right halve of a double-wide char clear out the
+ * left halve. Only needed in a terminal. */
+ if (has_mbyte && col > 0 && col < screen_Columns
+ && mb_fix_col(col, row) != col) {
+ ScreenLines[off - 1] = ' ';
+ ScreenAttrs[off - 1] = 0;
+ if (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
+ && (len < 0 || (int)(ptr - text) < len)
+ && *ptr != NUL) {
+ c = *ptr;
+ /* check if this is the first byte of a multibyte */
+ if (has_mbyte) {
+ if (enc_utf8 && len > 0)
+ mbyte_blen = utfc_ptr2len_len(ptr, (int)((text + len) - ptr));
+ else
+ mbyte_blen = (*mb_ptr2len)(ptr);
+ if (enc_dbcs == DBCS_JPNU && c == 0x8e)
+ mbyte_cells = 1;
+ else if (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);
+# ifdef UNICODE16
+ /* Non-BMP character: display as ? or fullwidth ?. */
+ if (u8c >= 0x10000) {
+ u8c = (mbyte_cells == 2) ? 0xff1f : (int)'?';
+ if (attr == 0)
+ attr = hl_attr(HLF_8);
+ }
+# endif
+ 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;
+ }
+ }
+ }
+
+ force_redraw_this = force_redraw_next;
+ force_redraw_next = FALSE;
+
+ need_redraw = ScreenLines[off] != c
+ || (mbyte_cells == 2
+ && ScreenLines[off + 1] != (enc_dbcs ? ptr[1] : 0))
+ || (enc_dbcs == DBCS_JPNU
+ && c == 0x8e
+ && ScreenLines2[off] != ptr[1])
+ || (enc_utf8
+ && (ScreenLinesUC[off] !=
+ (u8char_T)(c < 0x80 && u8cc[0] == 0 ? 0 : u8c)
+ || (ScreenLinesUC[off] != 0
+ && screen_comp_differs(off, u8cc))))
+ || ScreenAttrs[off] != attr
+ || exmode_active;
+
+ if (need_redraw
+ || force_redraw_this
+ ) {
+#if defined(FEAT_GUI) || defined(UNIX)
+ /* The bold trick makes a single row of pixels appear in the next
+ * character. When a bold character is removed, the next
+ * character should be redrawn too. This happens for our own GUI
+ * and for some xterms. */
+ if (need_redraw && ScreenLines[off] != ' ' && (
+# ifdef UNIX
+ term_is_xterm
+# endif
+ )) {
+ int n = ScreenAttrs[off];
+
+ if (n > HL_ALL)
+ n = syn_attr2attr(n);
+ if (n & HL_BOLD)
+ force_redraw_next = TRUE;
+ }
+#endif
+ /* 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 (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 (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 (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 (enc_dbcs == DBCS_JPNU && c == 0x8e) {
+ ScreenLines2[off] = ptr[1];
+ screen_char(off, row, col);
+ } else
+ screen_char(off, row, col);
+ }
+ if (has_mbyte) {
+ off += mbyte_cells;
+ col += mbyte_cells;
+ ptr += mbyte_blen;
+ if (clear_next_cell)
+ ptr = (char_u *)" ";
+ } else {
+ ++off;
+ ++col;
+ ++ptr;
+ }
+ }
+
+ /* 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 (enc_dbcs != 0 && dbcs_off2cells(off, max_off) > 1)
+ screen_char_2(off, row, col);
+ else
+ screen_char(off, row, col);
+ }
+}
+
+/*
+ * Prepare for 'hlsearch' highlighting.
+ */
+static void start_search_hl() {
+ if (p_hls && !no_hlsearch) {
+ last_pat_prog(&search_hl.rm);
+ search_hl.attr = hl_attr(HLF_L);
+ /* Set the time limit to 'redrawtime'. */
+ profile_setlimit(p_rdt, &search_hl.tm);
+ }
+}
+
+/*
+ * Clean up for 'hlsearch' highlighting.
+ */
+static void end_search_hl() {
+ if (search_hl.rm.regprog != NULL) {
+ vim_regfree(search_hl.rm.regprog);
+ search_hl.rm.regprog = NULL;
+ }
+}
+
+/*
+ * Init for calling prepare_search_hl().
+ */
+static void init_search_hl(wp)
+win_T *wp;
+{
+ matchitem_T *cur;
+
+ /* Setup for match and 'hlsearch' highlighting. Disable any previous
+ * match */
+ cur = wp->w_match_head;
+ while (cur != NULL) {
+ cur->hl.rm = cur->match;
+ if (cur->hlg_id == 0)
+ cur->hl.attr = 0;
+ else
+ cur->hl.attr = syn_id2attr(cur->hlg_id);
+ cur->hl.buf = wp->w_buffer;
+ cur->hl.lnum = 0;
+ cur->hl.first_lnum = 0;
+ /* Set the time limit to 'redrawtime'. */
+ profile_setlimit(p_rdt, &(cur->hl.tm));
+ cur = cur->next;
+ }
+ 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 */
+}
+
+/*
+ * Advance to the match in window "wp" line "lnum" or past it.
+ */
+static void prepare_search_hl(wp, lnum)
+win_T *wp;
+linenr_T lnum;
+{
+ 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 n;
+
+ /*
+ * When using a multi-line pattern, start searching at the top
+ * of the window or just after a closed fold.
+ * 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 = &search_hl;
+ shl_flag = TRUE;
+ } else
+ shl = &cur->hl;
+ 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))
+ break;
+ }
+ n = 0;
+ while (shl->first_lnum < lnum && shl->rm.regprog != NULL) {
+ next_search_hl(wp, shl, shl->first_lnum, (colnr_T)n);
+ if (shl->lnum != 0) {
+ shl->first_lnum = shl->lnum
+ + shl->rm.endpos[0].lnum
+ - shl->rm.startpos[0].lnum;
+ n = shl->rm.endpos[0].col;
+ } else {
+ ++shl->first_lnum;
+ n = 0;
+ }
+ }
+ }
+ if (shl != &search_hl && cur != NULL)
+ cur = cur->next;
+ }
+}
+
+/*
+ * Search for a next 'hlsearch' or match.
+ * Uses shl->buf.
+ * Sets shl->lnum and shl->rm contents.
+ * Note: Assumes a previous match is always before "lnum", unless
+ * shl->lnum is zero.
+ * Careful: Any pointers for buffer lines will become invalid.
+ */
+static void next_search_hl(win, shl, lnum, mincol)
+win_T *win;
+match_T *shl; /* points to search_hl or a match */
+linenr_T lnum;
+colnr_T mincol; /* minimal column for a match */
+{
+ linenr_T l;
+ colnr_T matchcol;
+ long nmatched;
+
+ if (shl->lnum != 0) {
+ /* Check for three situations:
+ * 1. If the "lnum" is below a previous match, start a new search.
+ * 2. If the previous match includes "mincol", use it.
+ * 3. Continue after the previous match.
+ */
+ l = shl->lnum + shl->rm.endpos[0].lnum - shl->rm.startpos[0].lnum;
+ if (lnum > l)
+ shl->lnum = 0;
+ else if (lnum < l || shl->rm.endpos[0].col > mincol)
+ return;
+ }
+
+ /*
+ * Repeat searching for a match until one is found that includes "mincol"
+ * or none is found in this line.
+ */
+ called_emsg = FALSE;
+ for (;; ) {
+ /* Stop searching after passing the time limit. */
+ if (profile_passed_limit(&(shl->tm))) {
+ shl->lnum = 0; /* no match found in time */
+ break;
+ }
+ /* Three situations:
+ * 1. No useful previous match: search from start of line.
+ * 2. Not Vi compatible or empty match: continue at next character.
+ * Break the loop if this is beyond the end of the line.
+ * 3. Vi compatible searching: continue at end of previous match.
+ */
+ if (shl->lnum == 0)
+ matchcol = 0;
+ else if (vim_strchr(p_cpo, CPO_SEARCH) == NULL
+ || (shl->rm.endpos[0].lnum == 0
+ && shl->rm.endpos[0].col <= shl->rm.startpos[0].col)) {
+ char_u *ml;
+
+ matchcol = shl->rm.startpos[0].col;
+ ml = ml_get_buf(shl->buf, lnum, FALSE) + matchcol;
+ if (*ml == NUL) {
+ ++matchcol;
+ shl->lnum = 0;
+ break;
+ }
+ if (has_mbyte)
+ matchcol += mb_ptr2len(ml);
+ else
+ ++matchcol;
+ } else
+ matchcol = shl->rm.endpos[0].col;
+
+ shl->lnum = lnum;
+ nmatched = vim_regexec_multi(&shl->rm, win, shl->buf, lnum, matchcol,
+ &(shl->tm)
+ );
+ if (called_emsg || got_int) {
+ /* Error while handling regexp: stop using this regexp. */
+ if (shl == &search_hl) {
+ /* don't free regprog in the match list, it's a copy */
+ vim_regfree(shl->rm.regprog);
+ SET_NO_HLSEARCH(TRUE);
+ }
+ shl->rm.regprog = NULL;
+ shl->lnum = 0;
+ got_int = FALSE; /* avoid the "Type :quit to exit Vim" message */
+ break;
+ }
+ if (nmatched == 0) {
+ shl->lnum = 0; /* no match found */
+ break;
+ }
+ if (shl->rm.startpos[0].lnum > 0
+ || shl->rm.startpos[0].col >= mincol
+ || nmatched > 1
+ || shl->rm.endpos[0].col > mincol) {
+ shl->lnum += shl->rm.startpos[0].lnum;
+ break; /* useful match found */
+ }
+ }
+}
+
+static void screen_start_highlight(attr)
+int attr;
+{
+ attrentry_T *aep = NULL;
+
+ screen_attr = attr;
+ if (full_screen
+ ) {
+ {
+ if (attr > HL_ALL) { /* special HL attr. */
+ if (t_colors > 1)
+ aep = syn_cterm_attr2entry(attr);
+ else
+ aep = syn_term_attr2entry(attr);
+ if (aep == NULL) /* did ":syntax clear" */
+ attr = 0;
+ else
+ attr = aep->ae_attr;
+ }
+ if ((attr & HL_BOLD) && T_MD != NULL) /* bold */
+ out_str(T_MD);
+ else if (aep != NULL && t_colors > 1 && aep->ae_u.cterm.fg_color
+ && cterm_normal_fg_bold)
+ /* If the Normal FG color has BOLD attribute and the new HL
+ * has a FG color defined, clear BOLD. */
+ out_str(T_ME);
+ if ((attr & HL_STANDOUT) && T_SO != NULL) /* standout */
+ out_str(T_SO);
+ if ((attr & (HL_UNDERLINE | HL_UNDERCURL)) && T_US != NULL)
+ /* underline or undercurl */
+ out_str(T_US);
+ if ((attr & HL_ITALIC) && T_CZH != NULL) /* italic */
+ out_str(T_CZH);
+ if ((attr & HL_INVERSE) && T_MR != NULL) /* inverse (reverse) */
+ out_str(T_MR);
+
+ /*
+ * Output the color or start string after bold etc., in case the
+ * bold etc. override the color setting.
+ */
+ if (aep != NULL) {
+ if (t_colors > 1) {
+ if (aep->ae_u.cterm.fg_color)
+ term_fg_color(aep->ae_u.cterm.fg_color - 1);
+ if (aep->ae_u.cterm.bg_color)
+ term_bg_color(aep->ae_u.cterm.bg_color - 1);
+ } else {
+ if (aep->ae_u.term.start != NULL)
+ out_str(aep->ae_u.term.start);
+ }
+ }
+ }
+ }
+}
+
+void screen_stop_highlight() {
+ int do_ME = FALSE; /* output T_ME code */
+
+ if (screen_attr != 0
+ ) {
+ {
+ if (screen_attr > HL_ALL) { /* special HL attr. */
+ attrentry_T *aep;
+
+ if (t_colors > 1) {
+ /*
+ * Assume that t_me restores the original colors!
+ */
+ aep = syn_cterm_attr2entry(screen_attr);
+ if (aep != NULL && (aep->ae_u.cterm.fg_color
+ || aep->ae_u.cterm.bg_color))
+ do_ME = TRUE;
+ } else {
+ aep = syn_term_attr2entry(screen_attr);
+ if (aep != NULL && aep->ae_u.term.stop != NULL) {
+ if (STRCMP(aep->ae_u.term.stop, T_ME) == 0)
+ do_ME = TRUE;
+ else
+ out_str(aep->ae_u.term.stop);
+ }
+ }
+ if (aep == NULL) /* did ":syntax clear" */
+ screen_attr = 0;
+ else
+ screen_attr = aep->ae_attr;
+ }
+
+ /*
+ * Often all ending-codes are equal to T_ME. Avoid outputting the
+ * same sequence several times.
+ */
+ if (screen_attr & HL_STANDOUT) {
+ if (STRCMP(T_SE, T_ME) == 0)
+ do_ME = TRUE;
+ else
+ out_str(T_SE);
+ }
+ if (screen_attr & (HL_UNDERLINE | HL_UNDERCURL)) {
+ if (STRCMP(T_UE, T_ME) == 0)
+ do_ME = TRUE;
+ else
+ out_str(T_UE);
+ }
+ if (screen_attr & HL_ITALIC) {
+ if (STRCMP(T_CZR, T_ME) == 0)
+ do_ME = TRUE;
+ else
+ out_str(T_CZR);
+ }
+ if (do_ME || (screen_attr & (HL_BOLD | HL_INVERSE)))
+ out_str(T_ME);
+
+ if (t_colors > 1) {
+ /* set Normal cterm colors */
+ if (cterm_normal_fg_color != 0)
+ term_fg_color(cterm_normal_fg_color - 1);
+ if (cterm_normal_bg_color != 0)
+ term_bg_color(cterm_normal_bg_color - 1);
+ if (cterm_normal_fg_bold)
+ out_str(T_MD);
+ }
+ }
+ }
+ screen_attr = 0;
+}
+
+/*
+ * Reset the colors for a cterm. Used when leaving Vim.
+ * The machine specific code may override this again.
+ */
+void reset_cterm_colors() {
+ if (t_colors > 1) {
+ /* set Normal cterm colors */
+ if (cterm_normal_fg_color > 0 || cterm_normal_bg_color > 0) {
+ out_str(T_OP);
+ screen_attr = -1;
+ }
+ if (cterm_normal_fg_bold) {
+ out_str(T_ME);
+ screen_attr = -1;
+ }
+ }
+}
+
+/*
+ * Put character ScreenLines["off"] on the screen at position "row" and "col",
+ * using the attributes from ScreenAttrs["off"].
+ */
+static void screen_char(off, row, col)
+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;
+
+ /* 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;
+ }
+
+ /*
+ * Stop highlighting first, so it's easier to move the cursor.
+ */
+ if (screen_char_attr != 0)
+ attr = screen_char_attr;
+ else
+ attr = ScreenAttrs[off];
+ if (screen_attr != attr)
+ screen_stop_highlight();
+
+ windgoto(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;
+
+ out_str(buf);
+ if (utf_char2cells(ScreenLinesUC[off]) > 1)
+ ++screen_cur_col;
+ } else {
+ out_flush_check();
+ out_char(ScreenLines[off]);
+ /* double-byte character in single-width cell */
+ if (enc_dbcs == DBCS_JPNU && ScreenLines[off] == 0x8e)
+ out_char(ScreenLines2[off]);
+ }
+
+ screen_cur_col++;
+}
+
+
+/*
+ * 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(off, row, col)
+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;
+ return;
+ }
+
+ /* Output the first byte normally (positions the cursor), then write the
+ * second byte directly. */
+ screen_char(off, row, col);
+ out_char(ScreenLines[off + 1]);
+ ++screen_cur_col;
+}
+
+/*
+ * Draw a rectangle of the screen, inverted when "invert" is TRUE.
+ * This uses the contents of ScreenLines[] and doesn't change it.
+ */
+void screen_draw_rectangle(row, col, height, width, invert)
+int row;
+int col;
+int height;
+int width;
+int invert;
+{
+ int r, c;
+ int off;
+ int max_off;
+
+ /* Can't use ScreenLines unless initialized */
+ if (ScreenLines == NULL)
+ return;
+
+ if (invert)
+ screen_char_attr = HL_INVERSE;
+ for (r = row; r < row + height; ++r) {
+ off = LineOffset[r];
+ max_off = off + screen_Columns;
+ for (c = col; c < col + width; ++c) {
+ if (enc_dbcs != 0 && dbcs_off2cells(off + c, max_off) > 1) {
+ screen_char_2(off + c, r, c);
+ ++c;
+ } else {
+ screen_char(off + c, r, c);
+ if (utf_off2cells(off + c, max_off) > 1)
+ ++c;
+ }
+ }
+ }
+ screen_char_attr = 0;
+}
+
+/*
+ * Redraw the characters for a vertically split window.
+ */
+static void redraw_block(row, end, wp)
+int row;
+int end;
+win_T *wp;
+{
+ int col;
+ int width;
+
+
+ if (wp == NULL) {
+ col = 0;
+ width = Columns;
+ } else {
+ col = wp->w_wincol;
+ width = wp->w_width;
+ }
+ screen_draw_rectangle(row, col, end - row, width, FALSE);
+}
+
+/*
+ * 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(start_row, end_row, start_col, end_col, c1, c2, attr)
+int start_row, end_row;
+int start_col, end_col;
+int c1, c2;
+int attr;
+{
+ int row;
+ int col;
+ int off;
+ int end_off;
+ int did_delete;
+ int c;
+ int norm_term;
+#if defined(FEAT_GUI) || defined(UNIX)
+ int force_next = FALSE;
+#endif
+
+ 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 */
+ norm_term = (
+ t_colors <= 1);
+ for (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 (end_col < screen_Columns && mb_fix_col(end_col, row) != end_col)
+ screen_puts_len((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
+ && can_clear(T_CE)
+ && (attr == 0
+ || (norm_term
+ && attr <= HL_ALL
+ && ((attr & ~(HL_BOLD | HL_ITALIC)) == 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();
+ term_windgoto(row, col); /* clear rest of this screen line */
+ out_str(T_CE);
+ screen_start(); /* don't know where cursor is now */
+ col = end_col - col;
+ while (col--) { /* clear chars in ScreenLines */
+ ScreenLines[off] = ' ';
+ if (enc_utf8)
+ ScreenLinesUC[off] = 0;
+ ScreenAttrs[off] = 0;
+ ++off;
+ }
+ }
+ 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
+#if defined(FEAT_GUI) || defined(UNIX)
+ || force_next
+#endif
+ ) {
+#if defined(FEAT_GUI) || defined(UNIX)
+ /* The bold trick may make a single row of pixels appear in
+ * the next character. When a bold character is removed, the
+ * next character should be redrawn too. This happens for our
+ * own GUI and for some xterms. */
+ if (
+# ifdef UNIX
+ term_is_xterm
+# endif
+ ) {
+ if (ScreenLines[off] != ' '
+ && (ScreenAttrs[off] > HL_ALL
+ || ScreenAttrs[off] & HL_BOLD))
+ force_next = TRUE;
+ else
+ force_next = FALSE;
+ }
+#endif
+ 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);
+ }
+ ++off;
+ if (col == start_col) {
+ if (did_delete)
+ break;
+ c = c2;
+ }
+ }
+ 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 */
+ }
+ }
+}
+
+/*
+ * Check if there should be a delay. Used before clearing or redrawing the
+ * screen or the command line.
+ */
+void check_for_delay(check_msg_scroll)
+int check_msg_scroll;
+{
+ if ((emsg_on_display || (check_msg_scroll && msg_scroll))
+ && !did_wait_return
+ && emsg_silent == 0) {
+ out_flush();
+ ui_delay(1000L, TRUE);
+ emsg_on_display = FALSE;
+ if (check_msg_scroll)
+ msg_scroll = FALSE;
+ }
+}
+
+/*
+ * screen_valid - allocate screen buffers if size changed
+ * If "doclear" is TRUE: clear screen if it has been resized.
+ * Returns TRUE if there is a valid screen to write to.
+ * Returns FALSE when starting up and screen not initialized yet.
+ */
+int screen_valid(doclear)
+int doclear;
+{
+ screenalloc(doclear); /* allocate screen buffers if size changed */
+ return ScreenLines != 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.
+ */
+void screenalloc(doclear)
+int doclear;
+{
+ int new_row, old_row;
+ win_T *wp;
+ 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;
+ short *new_TabPageIdxs;
+ tabpage_T *tp;
+ static int entered = FALSE; /* avoid recursiveness */
+ static int done_outofmem_msg = FALSE; /* did outofmem message */
+ int retry_count = 0;
+
+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
+ && enc_utf8 == (ScreenLinesUC != NULL)
+ && (enc_dbcs == DBCS_JPNU) == (ScreenLines2 != NULL)
+ && p_mco == Screen_mco
+ )
+ || Rows == 0
+ || Columns == 0
+ || (!full_screen && ScreenLines == NULL))
+ return;
+
+ /*
+ * It's possible that we produce an out-of-memory message below, which
+ * will cause this function to be called again. To break the loop, just
+ * return here.
+ */
+ if (entered)
+ return;
+ entered = TRUE;
+
+ /*
+ * Note that the window sizes are updated before reallocating the arrays,
+ * thus we must not redraw here!
+ */
+ ++RedrawingDisabled;
+
+ win_new_shellsize(); /* fit the windows in the new sized shell */
+
+ 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.
+ */
+ FOR_ALL_TAB_WINDOWS(tp, wp)
+ win_free_lsize(wp);
+ if (aucmd_win != NULL)
+ win_free_lsize(aucmd_win);
+
+ new_ScreenLines = (schar_T *)lalloc((long_u)(
+ (Rows + 1) * Columns * sizeof(schar_T)), FALSE);
+ vim_memset(new_ScreenLinesC, 0, sizeof(u8char_T *) * MAX_MCO);
+ if (enc_utf8) {
+ new_ScreenLinesUC = (u8char_T *)lalloc((long_u)(
+ (Rows + 1) * Columns * sizeof(u8char_T)), FALSE);
+ for (i = 0; i < p_mco; ++i)
+ new_ScreenLinesC[i] = (u8char_T *)lalloc_clear((long_u)(
+ (Rows + 1) * Columns * sizeof(u8char_T)), FALSE);
+ }
+ if (enc_dbcs == DBCS_JPNU)
+ new_ScreenLines2 = (schar_T *)lalloc((long_u)(
+ (Rows + 1) * Columns * sizeof(schar_T)), FALSE);
+ new_ScreenAttrs = (sattr_T *)lalloc((long_u)(
+ (Rows + 1) * Columns * sizeof(sattr_T)), FALSE);
+ new_LineOffset = (unsigned *)lalloc((long_u)(
+ Rows * sizeof(unsigned)), FALSE);
+ new_LineWraps = (char_u *)lalloc((long_u)(Rows * sizeof(char_u)), FALSE);
+ new_TabPageIdxs = (short *)lalloc((long_u)(Columns * sizeof(short)), FALSE);
+
+ FOR_ALL_TAB_WINDOWS(tp, wp)
+ {
+ if (win_alloc_lines(wp) == FAIL) {
+ outofmem = TRUE;
+ goto give_up;
+ }
+ }
+ if (aucmd_win != NULL && aucmd_win->w_lines == NULL
+ && win_alloc_lines(aucmd_win) == FAIL)
+ outofmem = TRUE;
+give_up:
+
+ for (i = 0; i < p_mco; ++i)
+ if (new_ScreenLinesC[i] == NULL)
+ break;
+ if (new_ScreenLines == NULL
+ || (enc_utf8 && (new_ScreenLinesUC == NULL || i != p_mco))
+ || (enc_dbcs == DBCS_JPNU && new_ScreenLines2 == NULL)
+ || new_ScreenAttrs == NULL
+ || new_LineOffset == NULL
+ || new_LineWraps == NULL
+ || new_TabPageIdxs == NULL
+ || outofmem) {
+ if (ScreenLines != NULL || !done_outofmem_msg) {
+ /* guess the size */
+ do_outofmem_msg((long_u)((Rows + 1) * Columns));
+
+ /* Remember we did this to avoid getting outofmem messages over
+ * and over again. */
+ done_outofmem_msg = TRUE;
+ }
+ vim_free(new_ScreenLines);
+ new_ScreenLines = NULL;
+ vim_free(new_ScreenLinesUC);
+ new_ScreenLinesUC = NULL;
+ for (i = 0; i < p_mco; ++i) {
+ vim_free(new_ScreenLinesC[i]);
+ new_ScreenLinesC[i] = NULL;
+ }
+ vim_free(new_ScreenLines2);
+ new_ScreenLines2 = NULL;
+ vim_free(new_ScreenAttrs);
+ new_ScreenAttrs = NULL;
+ vim_free(new_LineOffset);
+ new_LineOffset = NULL;
+ vim_free(new_LineWraps);
+ new_LineWraps = NULL;
+ vim_free(new_TabPageIdxs);
+ new_TabPageIdxs = 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)vim_memset(new_ScreenLines + new_row * Columns,
+ ' ', (size_t)Columns * sizeof(schar_T));
+ if (enc_utf8) {
+ (void)vim_memset(new_ScreenLinesUC + new_row * Columns,
+ 0, (size_t)Columns * sizeof(u8char_T));
+ for (i = 0; i < p_mco; ++i)
+ (void)vim_memset(new_ScreenLinesC[i]
+ + new_row * Columns,
+ 0, (size_t)Columns * sizeof(u8char_T));
+ }
+ if (enc_dbcs == DBCS_JPNU)
+ (void)vim_memset(new_ScreenLines2 + new_row * Columns,
+ 0, (size_t)Columns * sizeof(schar_T));
+ (void)vim_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 (!(enc_utf8 && ScreenLinesUC == NULL)
+ && p_mco == Screen_mco)
+ mch_memmove(new_ScreenLines + new_LineOffset[new_row],
+ ScreenLines + LineOffset[old_row],
+ (size_t)len * sizeof(schar_T));
+ if (enc_utf8 && ScreenLinesUC != NULL
+ && p_mco == Screen_mco) {
+ mch_memmove(new_ScreenLinesUC + new_LineOffset[new_row],
+ ScreenLinesUC + LineOffset[old_row],
+ (size_t)len * sizeof(u8char_T));
+ for (i = 0; i < p_mco; ++i)
+ mch_memmove(new_ScreenLinesC[i]
+ + new_LineOffset[new_row],
+ ScreenLinesC[i] + LineOffset[old_row],
+ (size_t)len * sizeof(u8char_T));
+ }
+ if (enc_dbcs == DBCS_JPNU && ScreenLines2 != NULL)
+ mch_memmove(new_ScreenLines2 + new_LineOffset[new_row],
+ ScreenLines2 + LineOffset[old_row],
+ (size_t)len * sizeof(schar_T));
+ mch_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();
+
+ 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;
+ TabPageIdxs = new_TabPageIdxs;
+
+ /* 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;
+
+ must_redraw = CLEAR; /* need to clear the screen later */
+ if (doclear)
+ screenclear2();
+
+
+ entered = FALSE;
+ --RedrawingDisabled;
+
+ /*
+ * Do not apply autocommands more than 3 times to avoid an endless loop
+ * in case applying autocommands always changes Rows or Columns.
+ */
+ if (starting == 0 && ++retry_count <= 3) {
+ apply_autocmds(EVENT_VIMRESIZED, NULL, NULL, FALSE, curbuf);
+ /* In rare cases, autocommands may have altered Rows or Columns,
+ * jump back to check if we need to allocate the screen again. */
+ goto retry;
+ }
+}
+
+void free_screenlines() {
+ int i;
+
+ vim_free(ScreenLinesUC);
+ for (i = 0; i < Screen_mco; ++i)
+ vim_free(ScreenLinesC[i]);
+ vim_free(ScreenLines2);
+ vim_free(ScreenLines);
+ vim_free(ScreenAttrs);
+ vim_free(LineOffset);
+ vim_free(LineWraps);
+ vim_free(TabPageIdxs);
+}
+
+void screenclear() {
+ check_for_delay(FALSE);
+ screenalloc(FALSE); /* allocate screen buffers if size changed */
+ screenclear2(); /* clear the screen */
+}
+
+static void screenclear2() {
+ int i;
+
+ if (starting == NO_SCREEN || ScreenLines == NULL
+ )
+ return;
+
+ screen_attr = -1; /* force setting the Normal colors */
+ screen_stop_highlight(); /* don't want highlighting here */
+
+
+ /* blank out ScreenLines */
+ for (i = 0; i < Rows; ++i) {
+ lineclear(LineOffset[i], (int)Columns);
+ LineWraps[i] = FALSE;
+ }
+
+ if (can_clear(T_CL)) {
+ out_str(T_CL); /* clear the display */
+ clear_cmdline = FALSE;
+ mode_displayed = FALSE;
+ } else {
+ /* can't clear the screen, mark all chars with invalid attributes */
+ for (i = 0; i < Rows; ++i)
+ lineinvalid(LineOffset[i], (int)Columns);
+ clear_cmdline = TRUE;
+ }
+
+ 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_col = 0;
+ screen_start(); /* don't know where cursor is now */
+ msg_scrolled = 0; /* can't scroll back */
+ msg_didany = FALSE;
+ msg_didout = FALSE;
+}
+
+/*
+ * Clear one line in ScreenLines.
+ */
+static void lineclear(off, width)
+unsigned off;
+int width;
+{
+ (void)vim_memset(ScreenLines + off, ' ', (size_t)width * sizeof(schar_T));
+ if (enc_utf8)
+ (void)vim_memset(ScreenLinesUC + off, 0,
+ (size_t)width * sizeof(u8char_T));
+ (void)vim_memset(ScreenAttrs + off, 0, (size_t)width * sizeof(sattr_T));
+}
+
+/*
+ * Mark one line in ScreenLines invalid by setting the attributes to an
+ * invalid value.
+ */
+static void lineinvalid(off, width)
+unsigned off;
+int width;
+{
+ (void)vim_memset(ScreenAttrs + off, -1, (size_t)width * sizeof(sattr_T));
+}
+
+/*
+ * Copy part of a Screenline for vertically split window "wp".
+ */
+static void linecopy(to, from, wp)
+int to;
+int from;
+win_T *wp;
+{
+ unsigned off_to = LineOffset[to] + wp->w_wincol;
+ unsigned off_from = LineOffset[from] + wp->w_wincol;
+
+ mch_memmove(ScreenLines + off_to, ScreenLines + off_from,
+ wp->w_width * sizeof(schar_T));
+ if (enc_utf8) {
+ int i;
+
+ mch_memmove(ScreenLinesUC + off_to, ScreenLinesUC + off_from,
+ wp->w_width * sizeof(u8char_T));
+ for (i = 0; i < p_mco; ++i)
+ mch_memmove(ScreenLinesC[i] + off_to, ScreenLinesC[i] + off_from,
+ wp->w_width * sizeof(u8char_T));
+ }
+ if (enc_dbcs == DBCS_JPNU)
+ mch_memmove(ScreenLines2 + off_to, ScreenLines2 + off_from,
+ wp->w_width * sizeof(schar_T));
+ mch_memmove(ScreenAttrs + off_to, ScreenAttrs + off_from,
+ wp->w_width * sizeof(sattr_T));
+}
+
+/*
+ * Return TRUE if clearing with term string "p" would work.
+ * It can't work when the string is empty or it won't set the right background.
+ */
+int can_clear(p)
+char_u *p;
+{
+ return *p != NUL && (t_colors <= 1
+ || cterm_normal_bg_color == 0 || *T_UT != NUL);
+}
+
+/*
+ * Reset cursor position. Use whenever cursor was moved because of outputting
+ * something directly to the screen (shell commands) or a terminal control
+ * code.
+ */
+void screen_start() {
+ screen_cur_row = screen_cur_col = 9999;
+}
+
+/*
+ * Move the cursor to position "row","col" in the screen.
+ * This tries to find the most efficient way to move, minimizing the number of
+ * characters sent to the terminal.
+ */
+void windgoto(row, col)
+int row;
+int col;
+{
+ sattr_T *p;
+ int i;
+ int plan;
+ int cost;
+ int wouldbe_col;
+ int noinvcurs;
+ char_u *bs;
+ int goto_cost;
+ int attr;
+
+#define GOTO_COST 7 /* assume a term_windgoto() takes about 7 chars */
+#define HIGHL_COST 5 /* assume unhighlight takes 5 chars */
+
+#define PLAN_LE 1
+#define PLAN_CR 2
+#define PLAN_NL 3
+#define PLAN_WRITE 4
+ /* Can't use ScreenLines unless initialized */
+ if (ScreenLines == NULL)
+ return;
+
+ if (col != screen_cur_col || row != screen_cur_row) {
+ /* Check for valid position. */
+ if (row < 0) /* window without text lines? */
+ row = 0;
+ if (row >= screen_Rows)
+ row = screen_Rows - 1;
+ if (col >= screen_Columns)
+ col = screen_Columns - 1;
+
+ /* check if no cursor movement is allowed in highlight mode */
+ if (screen_attr && *T_MS == NUL)
+ noinvcurs = HIGHL_COST;
+ else
+ noinvcurs = 0;
+ goto_cost = GOTO_COST + noinvcurs;
+
+ /*
+ * Plan how to do the positioning:
+ * 1. Use CR to move it to column 0, same row.
+ * 2. Use T_LE to move it a few columns to the left.
+ * 3. Use NL to move a few lines down, column 0.
+ * 4. Move a few columns to the right with T_ND or by writing chars.
+ *
+ * Don't do this if the cursor went beyond the last column, the cursor
+ * position is unknown then (some terminals wrap, some don't )
+ *
+ * First check if the highlighting attributes allow us to write
+ * characters to move the cursor to the right.
+ */
+ if (row >= screen_cur_row && screen_cur_col < Columns) {
+ /*
+ * If the cursor is in the same row, bigger col, we can use CR
+ * or T_LE.
+ */
+ bs = NULL; /* init for GCC */
+ attr = screen_attr;
+ if (row == screen_cur_row && col < screen_cur_col) {
+ /* "le" is preferred over "bc", because "bc" is obsolete */
+ if (*T_LE)
+ bs = T_LE; /* "cursor left" */
+ else
+ bs = T_BC; /* "backspace character (old) */
+ if (*bs)
+ cost = (screen_cur_col - col) * (int)STRLEN(bs);
+ else
+ cost = 999;
+ if (col + 1 < cost) { /* using CR is less characters */
+ plan = PLAN_CR;
+ wouldbe_col = 0;
+ cost = 1; /* CR is just one character */
+ } else {
+ plan = PLAN_LE;
+ wouldbe_col = col;
+ }
+ if (noinvcurs) { /* will stop highlighting */
+ cost += noinvcurs;
+ attr = 0;
+ }
+ }
+ /*
+ * If the cursor is above where we want to be, we can use CR LF.
+ */
+ else if (row > screen_cur_row) {
+ plan = PLAN_NL;
+ wouldbe_col = 0;
+ cost = (row - screen_cur_row) * 2; /* CR LF */
+ if (noinvcurs) { /* will stop highlighting */
+ cost += noinvcurs;
+ attr = 0;
+ }
+ }
+ /*
+ * If the cursor is in the same row, smaller col, just use write.
+ */
+ else {
+ plan = PLAN_WRITE;
+ wouldbe_col = screen_cur_col;
+ cost = 0;
+ }
+
+ /*
+ * Check if any characters that need to be written have the
+ * correct attributes. Also avoid UTF-8 characters.
+ */
+ i = col - wouldbe_col;
+ if (i > 0)
+ cost += i;
+ if (cost < goto_cost && i > 0) {
+ /*
+ * Check if the attributes are correct without additionally
+ * stopping highlighting.
+ */
+ p = ScreenAttrs + LineOffset[row] + wouldbe_col;
+ while (i && *p++ == attr)
+ --i;
+ if (i != 0) {
+ /*
+ * Try if it works when highlighting is stopped here.
+ */
+ if (*--p == 0) {
+ cost += noinvcurs;
+ while (i && *p++ == 0)
+ --i;
+ }
+ if (i != 0)
+ cost = 999; /* different attributes, don't do it */
+ }
+ if (enc_utf8) {
+ /* Don't use an UTF-8 char for positioning, it's slow. */
+ for (i = wouldbe_col; i < col; ++i)
+ if (ScreenLinesUC[LineOffset[row] + i] != 0) {
+ cost = 999;
+ break;
+ }
+ }
+ }
+
+ /*
+ * We can do it without term_windgoto()!
+ */
+ if (cost < goto_cost) {
+ if (plan == PLAN_LE) {
+ if (noinvcurs)
+ screen_stop_highlight();
+ while (screen_cur_col > col) {
+ out_str(bs);
+ --screen_cur_col;
+ }
+ } else if (plan == PLAN_CR) {
+ if (noinvcurs)
+ screen_stop_highlight();
+ out_char('\r');
+ screen_cur_col = 0;
+ } else if (plan == PLAN_NL) {
+ if (noinvcurs)
+ screen_stop_highlight();
+ while (screen_cur_row < row) {
+ out_char('\n');
+ ++screen_cur_row;
+ }
+ screen_cur_col = 0;
+ }
+
+ i = col - screen_cur_col;
+ if (i > 0) {
+ /*
+ * Use cursor-right if it's one character only. Avoids
+ * removing a line of pixels from the last bold char, when
+ * using the bold trick in the GUI.
+ */
+ if (T_ND[0] != NUL && T_ND[1] == NUL) {
+ while (i-- > 0)
+ out_char(*T_ND);
+ } else {
+ int off;
+
+ off = LineOffset[row] + screen_cur_col;
+ while (i-- > 0) {
+ if (ScreenAttrs[off] != screen_attr)
+ screen_stop_highlight();
+ out_flush_check();
+ out_char(ScreenLines[off]);
+ if (enc_dbcs == DBCS_JPNU
+ && ScreenLines[off] == 0x8e)
+ out_char(ScreenLines2[off]);
+ ++off;
+ }
+ }
+ }
+ }
+ } else
+ cost = 999;
+
+ if (cost >= goto_cost) {
+ if (noinvcurs)
+ screen_stop_highlight();
+ if (row == screen_cur_row && (col > screen_cur_col) &&
+ *T_CRI != NUL)
+ term_cursor_right(col - screen_cur_col);
+ else
+ term_windgoto(row, col);
+ }
+ screen_cur_row = row;
+ screen_cur_col = col;
+ }
+}
+
+/*
+ * Set cursor to its position in the current window.
+ */
+void setcursor() {
+ if (redrawing()) {
+ validate_cursor();
+ windgoto(W_WINROW(curwin) + curwin->w_wrow,
+ W_WINCOL(curwin) + (
+ /* With 'rightleft' set and the cursor on a double-wide
+ * character, position it on the leftmost column. */
+ curwin->w_p_rl ? ((int)W_WIDTH(curwin) - curwin->w_wcol - (
+ (has_mbyte
+ && (*mb_ptr2cells)(ml_get_cursor()) == 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(wp, row, line_count, invalid, mayclear)
+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, W_WINROW(wp) + wp->w_height - line_count,
+ line_count, (int)Rows, FALSE, 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 = W_WINROW(wp) + wp->w_height + W_STATUS_HEIGHT(wp);
+ lastrow = nextrow + line_count;
+ if (lastrow > Rows)
+ lastrow = Rows;
+ screen_fill(nextrow - line_count, lastrow - line_count,
+ W_WINCOL(wp), (int)W_ENDCOL(wp),
+ ' ', ' ', 0);
+ }
+
+ if (screen_ins_lines(0, W_WINROW(wp) + 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(W_NEXT(wp));
+ }
+ return FAIL;
+ }
+
+ return OK;
+}
+
+/*
+ * 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(wp, row, line_count, invalid, mayclear)
+win_T *wp;
+int row;
+int line_count;
+int invalid;
+int mayclear;
+{
+ 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, W_WINROW(wp) + row, line_count,
+ (int)Rows, FALSE, NULL) == FAIL)
+ return FAIL;
+
+ /*
+ * 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, W_WINROW(wp) + 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;
+}
+
+/*
+ * Common code for win_ins_lines() and win_del_lines().
+ * Returns OK or FAIL when the work has been done.
+ * Returns MAYBE when not finished yet.
+ */
+static int win_do_lines(wp, row, line_count, mayclear, del)
+win_T *wp;
+int row;
+int line_count;
+int mayclear;
+int del;
+{
+ int retval;
+
+ 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(W_WINROW(wp) + row, W_WINROW(wp) + wp->w_height,
+ W_WINCOL(wp), (int)W_ENDCOL(wp),
+ ' ', ' ', 0);
+ return OK;
+ }
+
+ /*
+ * when scrolling, the message on the command line should be cleared,
+ * otherwise it will stay there forever.
+ */
+ clear_cmdline = TRUE;
+
+ /*
+ * If the terminal can set a scroll region, use that.
+ * Always do this in a vertically split window. This will redraw from
+ * ScreenLines[] when t_CV isn't defined. That's faster than using
+ * win_line().
+ * Don't use a scroll region when we are going to redraw the text, writing
+ * a character in the lower right corner of the scroll region causes a
+ * scroll-up in the DJGPP version.
+ */
+ if (scroll_region
+ || W_WIDTH(wp) != Columns
+ ) {
+ if (scroll_region && (wp->w_width == Columns || *T_CSV != NUL))
+ scroll_region_set(wp, row);
+ if (del)
+ retval = screen_del_lines(W_WINROW(wp) + row, 0, line_count,
+ wp->w_height - row, FALSE, wp);
+ else
+ retval = screen_ins_lines(W_WINROW(wp) + row, 0, line_count,
+ wp->w_height - row, wp);
+ if (scroll_region && (wp->w_width == Columns || *T_CSV != NUL))
+ scroll_region_reset();
+ return retval;
+ }
+
+ if (wp->w_next != NULL && p_tf) /* don't delete/insert on fast terminal */
+ return FAIL;
+
+ return MAYBE;
+}
+
+/*
+ * window 'wp' and everything after it is messed up, mark it for redraw
+ */
+static void win_rest_invalid(wp)
+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
+ * anticipates the effect of editing changes on the appearance of the screen.
+ * That way, when we call screenupdate a complete redraw isn't usually
+ * necessary. Another advantage is that we can keep adding code to anticipate
+ * screen changes, and in the meantime, everything still works.
+ */
+
+/*
+ * types for inserting or deleting lines
+ */
+#define USE_T_CAL 1
+#define USE_T_CDL 2
+#define USE_T_AL 3
+#define USE_T_CE 4
+#define USE_T_DL 5
+#define USE_T_SR 6
+#define USE_NL 7
+#define USE_T_CD 8
+#define USE_REDRAW 9
+
+/*
+ * 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.
+ *
+ * return FAIL for failure, OK for success.
+ */
+int screen_ins_lines(off, row, line_count, end, wp)
+int off;
+int row;
+int line_count;
+int end;
+win_T *wp; /* NULL or window to use width from */
+{
+ int i;
+ int j;
+ unsigned temp;
+ int cursor_row;
+ int type;
+ int result_empty;
+ int can_ce = can_clear(T_CE);
+
+ /*
+ * FAIL if
+ * - there is no valid screen
+ * - the screen has to be redrawn completely
+ * - the line count is less than one
+ * - the line count is more than 'ttyscroll'
+ */
+ if (!screen_valid(TRUE) || line_count <= 0 || line_count > p_ttyscroll)
+ return FAIL;
+
+ /*
+ * There are seven ways to insert lines:
+ * 0. When in a vertically split window and t_CV isn't set, redraw the
+ * characters from ScreenLines[].
+ * 1. Use T_CD (clear to end of display) if it exists and the result of
+ * the insert is just empty lines
+ * 2. Use T_CAL (insert multiple lines) if it exists and T_AL is not
+ * present or line_count > 1. It looks better if we do all the inserts
+ * at once.
+ * 3. Use T_CDL (delete multiple lines) if it exists and the result of the
+ * insert is just empty lines and T_CE is not present or line_count >
+ * 1.
+ * 4. Use T_AL (insert line) if it exists.
+ * 5. Use T_CE (erase line) if it exists and the result of the insert is
+ * just empty lines.
+ * 6. Use T_DL (delete line) if it exists and the result of the insert is
+ * just empty lines.
+ * 7. Use T_SR (scroll reverse) if it exists and inserting at row 0 and
+ * the 'da' flag is not set or we have clear line capability.
+ * 8. redraw the characters from ScreenLines[].
+ *
+ * Careful: In a hpterm scroll reverse doesn't work as expected, it moves
+ * the scrollbar for the window. It does have insert line, use that if it
+ * exists.
+ */
+ result_empty = (row + line_count >= end);
+ if (wp != NULL && wp->w_width != Columns && *T_CSV == NUL)
+ type = USE_REDRAW;
+ else if (can_clear(T_CD) && result_empty)
+ type = USE_T_CD;
+ else if (*T_CAL != NUL && (line_count > 1 || *T_AL == NUL))
+ type = USE_T_CAL;
+ else if (*T_CDL != NUL && result_empty && (line_count > 1 || !can_ce))
+ type = USE_T_CDL;
+ else if (*T_AL != NUL)
+ type = USE_T_AL;
+ else if (can_ce && result_empty)
+ type = USE_T_CE;
+ else if (*T_DL != NUL && result_empty)
+ type = USE_T_DL;
+ else if (*T_SR != NUL && row == 0 && (*T_DA == NUL || can_ce))
+ type = USE_T_SR;
+ else
+ return FAIL;
+
+ /*
+ * For clearing the lines screen_del_lines() is used. This will also take
+ * care of t_db if necessary.
+ */
+ if (type == USE_T_CD || type == USE_T_CDL ||
+ type == USE_T_CE || type == USE_T_DL)
+ return screen_del_lines(off, row, line_count, end, FALSE, wp);
+
+ /*
+ * If text is retained below the screen, first clear or delete as many
+ * lines at the bottom of the window as are about to be inserted so that
+ * the deleted lines won't later surface during a screen_del_lines.
+ */
+ if (*T_DB)
+ screen_del_lines(off, end - line_count, line_count, end, FALSE, wp);
+
+
+
+ if (*T_CCS != NUL) /* cursor relative to region */
+ cursor_row = row;
+ else
+ cursor_row = row + off;
+
+ /*
+ * 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) {
+ /* need to copy part of a line */
+ j = end - 1 - i;
+ while ((j -= line_count) >= row)
+ linecopy(j + line_count, j, wp);
+ j += line_count;
+ if (can_clear((char_u *)" "))
+ lineclear(LineOffset[j] + wp->w_wincol, wp->w_width);
+ else
+ lineinvalid(LineOffset[j] + wp->w_wincol, wp->w_width);
+ LineWraps[j] = FALSE;
+ } else {
+ j = end - 1 - i;
+ temp = LineOffset[j];
+ while ((j -= line_count) >= row) {
+ LineOffset[j + line_count] = LineOffset[j];
+ LineWraps[j + line_count] = LineWraps[j];
+ }
+ LineOffset[j + line_count] = temp;
+ LineWraps[j + line_count] = FALSE;
+ if (can_clear((char_u *)" "))
+ lineclear(temp, (int)Columns);
+ else
+ lineinvalid(temp, (int)Columns);
+ }
+ }
+
+ screen_stop_highlight();
+ windgoto(cursor_row, 0);
+
+ /* redraw the characters */
+ if (type == USE_REDRAW)
+ redraw_block(row, end, wp);
+ else if (type == USE_T_CAL) {
+ term_append_lines(line_count);
+ screen_start(); /* don't know where cursor is now */
+ } else {
+ for (i = 0; i < line_count; i++) {
+ if (type == USE_T_AL) {
+ if (i && cursor_row != 0)
+ windgoto(cursor_row, 0);
+ out_str(T_AL);
+ } else /* type == USE_T_SR */
+ out_str(T_SR);
+ screen_start(); /* don't know where cursor is now */
+ }
+ }
+
+ /*
+ * With scroll-reverse and 'da' flag set we need to clear the lines that
+ * have been scrolled down into the region.
+ */
+ if (type == USE_T_SR && *T_DA) {
+ for (i = 0; i < line_count; ++i) {
+ windgoto(off + i, 0);
+ out_str(T_CE);
+ screen_start(); /* don't know where cursor is now */
+ }
+ }
+
+ 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(off, row, line_count, end, force, wp)
+int off;
+int row;
+int line_count;
+int end;
+int force; /* even when line_count > p_ttyscroll */
+win_T *wp UNUSED; /* NULL or window to use width from */
+{
+ int j;
+ int i;
+ unsigned temp;
+ int cursor_row;
+ int cursor_end;
+ int result_empty; /* result is empty until end of region */
+ int can_delete; /* deleting line codes can be used */
+ int type;
+
+ /*
+ * FAIL if
+ * - there is no valid screen
+ * - the screen has to be redrawn completely
+ * - the line count is less than one
+ * - the line count is more than 'ttyscroll'
+ */
+ if (!screen_valid(TRUE) || line_count <= 0 ||
+ (!force && line_count > p_ttyscroll))
+ return FAIL;
+
+ /*
+ * Check if the rest of the current region will become empty.
+ */
+ result_empty = row + line_count >= end;
+
+ /*
+ * We can delete lines only when 'db' flag not set or when 'ce' option
+ * available.
+ */
+ can_delete = (*T_DB == NUL || can_clear(T_CE));
+
+ /*
+ * There are six ways to delete lines:
+ * 0. When in a vertically split window and t_CV isn't set, redraw the
+ * characters from ScreenLines[].
+ * 1. Use T_CD if it exists and the result is empty.
+ * 2. Use newlines if row == 0 and count == 1 or T_CDL does not exist.
+ * 3. Use T_CDL (delete multiple lines) if it exists and line_count > 1 or
+ * none of the other ways work.
+ * 4. Use T_CE (erase line) if the result is empty.
+ * 5. Use T_DL (delete line) if it exists.
+ * 6. redraw the characters from ScreenLines[].
+ */
+ if (wp != NULL && wp->w_width != Columns && *T_CSV == NUL)
+ type = USE_REDRAW;
+ else if (can_clear(T_CD) && result_empty)
+ type = USE_T_CD;
+ else if (row == 0 && (
+ /* On the Amiga, somehow '\n' on the last line doesn't always scroll
+ * up, so use delete-line command */
+ line_count == 1 ||
+ *T_CDL == NUL))
+ type = USE_NL;
+ else if (*T_CDL != NUL && line_count > 1 && can_delete)
+ type = USE_T_CDL;
+ else if (can_clear(T_CE) && result_empty
+ && (wp == NULL || wp->w_width == Columns)
+ )
+ type = USE_T_CE;
+ else if (*T_DL != NUL && can_delete)
+ type = USE_T_DL;
+ else if (*T_CDL != NUL && can_delete)
+ type = USE_T_CDL;
+ else
+ return FAIL;
+
+
+
+ if (*T_CCS != NUL) { /* cursor relative to region */
+ cursor_row = row;
+ cursor_end = end;
+ } else {
+ cursor_row = row + off;
+ cursor_end = end + off;
+ }
+
+ /*
+ * 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) {
+ /* need to copy part of a line */
+ j = row + i;
+ while ((j += line_count) <= end - 1)
+ linecopy(j - line_count, j, wp);
+ j -= line_count;
+ if (can_clear((char_u *)" "))
+ lineclear(LineOffset[j] + wp->w_wincol, wp->w_width);
+ else
+ lineinvalid(LineOffset[j] + wp->w_wincol, wp->w_width);
+ LineWraps[j] = FALSE;
+ } else {
+ /* whole width, moving the line pointers is faster */
+ j = row + i;
+ temp = LineOffset[j];
+ while ((j += line_count) <= end - 1) {
+ LineOffset[j - line_count] = LineOffset[j];
+ LineWraps[j - line_count] = LineWraps[j];
+ }
+ LineOffset[j - line_count] = temp;
+ LineWraps[j - line_count] = FALSE;
+ if (can_clear((char_u *)" "))
+ lineclear(temp, (int)Columns);
+ else
+ lineinvalid(temp, (int)Columns);
+ }
+ }
+
+ screen_stop_highlight();
+
+ /* redraw the characters */
+ if (type == USE_REDRAW)
+ redraw_block(row, end, wp);
+ else if (type == USE_T_CD) { /* delete the lines */
+ windgoto(cursor_row, 0);
+ out_str(T_CD);
+ screen_start(); /* don't know where cursor is now */
+ } else if (type == USE_T_CDL) {
+ windgoto(cursor_row, 0);
+ term_delete_lines(line_count);
+ screen_start(); /* don't know where cursor is now */
+ }
+ /*
+ * Deleting lines at top of the screen or scroll region: Just scroll
+ * the whole screen (scroll region) up by outputting newlines on the
+ * last line.
+ */
+ else if (type == USE_NL) {
+ windgoto(cursor_end - 1, 0);
+ for (i = line_count; --i >= 0; )
+ out_char('\n'); /* cursor will remain on same line */
+ } else {
+ for (i = line_count; --i >= 0; ) {
+ if (type == USE_T_DL) {
+ windgoto(cursor_row, 0);
+ out_str(T_DL); /* delete a line */
+ } else { /* type == USE_T_CE */
+ windgoto(cursor_row + i, 0);
+ out_str(T_CE); /* erase a line */
+ }
+ screen_start(); /* don't know where cursor is now */
+ }
+ }
+
+ /*
+ * If the 'db' flag is set, we need to clear the lines that have been
+ * scrolled up at the bottom of the region.
+ */
+ if (*T_DB && (type == USE_T_DL || type == USE_T_CDL)) {
+ for (i = line_count; i > 0; --i) {
+ windgoto(cursor_end - i, 0);
+ out_str(T_CE); /* erase a line */
+ screen_start(); /* don't know where cursor is now */
+ }
+ }
+
+
+ return OK;
+}
+
+/*
+ * show the current mode and ruler
+ *
+ * If clear_cmdline is TRUE, clear the rest of the cmdline.
+ * If clear_cmdline is FALSE there may be a message there that needs to be
+ * cleared only if a mode is shown.
+ * Return the length of the message (0 if no message).
+ */
+int showmode() {
+ int need_clear;
+ int length = 0;
+ int do_mode;
+ int attr;
+ int nwr_save;
+ int sub_attr;
+
+ do_mode = ((p_smd && msg_silent == 0)
+ && ((State & INSERT)
+ || restart_edit
+ || VIsual_active
+ ));
+ if (do_mode || Recording) {
+ /*
+ * Don't show mode right now, when not redrawing or inside a mapping.
+ * Call char_avail() only when we are going to show something, because
+ * it takes a bit of time.
+ */
+ if (!redrawing() || (char_avail() && !KeyTyped) || msg_silent != 0) {
+ redraw_cmdline = TRUE; /* show mode later */
+ return 0;
+ }
+
+ nwr_save = need_wait_return;
+
+ /* wait a bit before overwriting an important message */
+ check_for_delay(FALSE);
+
+ /* 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 */
+
+ /* Position on the last line in the window, column 0 */
+ msg_pos_mode();
+ cursor_off();
+ attr = hl_attr(HLF_CM); /* Highlight mode */
+ if (do_mode) {
+ MSG_PUTS_ATTR("--", attr);
+ if (edit_submode != NULL) { /* CTRL-X in Insert mode */
+ /* 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 -= 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_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
+ sub_attr = attr;
+ msg_puts_attr(edit_submode_extra, sub_attr);
+ }
+ }
+ length = 0;
+ } else {
+ if (State & VREPLACE_FLAG)
+ MSG_PUTS_ATTR(_(" VREPLACE"), attr);
+ else if (State & REPLACE_FLAG)
+ MSG_PUTS_ATTR(_(" REPLACE"), attr);
+ else if (State & INSERT) {
+ if (p_ri)
+ MSG_PUTS_ATTR(_(" REVERSE"), attr);
+ MSG_PUTS_ATTR(_(" INSERT"), attr);
+ } else if (restart_edit == 'I')
+ MSG_PUTS_ATTR(_(" (insert)"), attr);
+ else if (restart_edit == 'R')
+ MSG_PUTS_ATTR(_(" (replace)"), attr);
+ else if (restart_edit == 'V')
+ MSG_PUTS_ATTR(_(" (vreplace)"), attr);
+ if (p_hkmap)
+ MSG_PUTS_ATTR(_(" Hebrew"), attr);
+ if (p_fkmap)
+ MSG_PUTS_ATTR(farsi_text_5, attr);
+ if (State & LANGMAP) {
+ if (curwin->w_p_arab)
+ MSG_PUTS_ATTR(_(" Arabic"), attr);
+ else
+ MSG_PUTS_ATTR(_(" (lang)"), attr);
+ }
+ if ((State & INSERT) && p_paste)
+ MSG_PUTS_ATTR(_(" (paste)"), attr);
+
+ if (VIsual_active) {
+ char *p;
+
+ /* Don't concatenate separate words to avoid translation
+ * problems. */
+ switch ((VIsual_select ? 4 : 0)
+ + (VIsual_mode == Ctrl_V) * 2
+ + (VIsual_mode == 'V')) {
+ case 0: p = N_(" VISUAL"); break;
+ case 1: p = N_(" VISUAL LINE"); break;
+ case 2: p = N_(" VISUAL BLOCK"); break;
+ case 4: p = N_(" SELECT"); break;
+ case 5: p = N_(" SELECT LINE"); break;
+ default: p = N_(" SELECT BLOCK"); break;
+ }
+ MSG_PUTS_ATTR(_(p), attr);
+ }
+ MSG_PUTS_ATTR(" --", attr);
+ }
+
+ need_clear = TRUE;
+ }
+ if (Recording
+ && edit_submode == NULL /* otherwise it gets too long */
+ ) {
+ MSG_PUTS_ATTR(_("recording"), attr);
+ need_clear = TRUE;
+ }
+
+ mode_displayed = TRUE;
+ if (need_clear || clear_cmdline)
+ msg_clr_eos();
+ 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_clr_cmdline();
+
+ /* In Visual mode the size of the selected area must be redrawn. */
+ if (VIsual_active)
+ clear_showcmd();
+
+ /* If the last window has no status line, the ruler is after the mode
+ * message and must be redrawn */
+ if (redrawing()
+ && lastwin->w_status_height == 0
+ )
+ win_redr_ruler(lastwin, TRUE);
+ redraw_cmdline = FALSE;
+ clear_cmdline = FALSE;
+
+ return length;
+}
+
+/*
+ * Position for a mode message.
+ */
+static void msg_pos_mode() {
+ msg_col = 0;
+ msg_row = Rows - 1;
+}
+
+/*
+ * Delete mode message. Used when ESC is typed which is expected to end
+ * Insert mode (but Insert mode didn't end yet!).
+ * Caller should check "mode_displayed".
+ */
+void unshowmode(force)
+int force;
+{
+ /*
+ * Don't delete it right now, when not redrawing or inside a mapping.
+ */
+ if (!redrawing() || (!force && char_avail() && !KeyTyped))
+ redraw_cmdline = TRUE; /* delete mode later */
+ else {
+ msg_pos_mode();
+ if (Recording)
+ MSG_PUTS_ATTR(_("recording"), hl_attr(HLF_CM));
+ msg_clr_eos();
+ }
+}
+
+/*
+ * Draw the tab pages line at the top of the Vim window.
+ */
+static void draw_tabline() {
+ int tabcount = 0;
+ tabpage_T *tp;
+ int tabwidth;
+ int col = 0;
+ int scol = 0;
+ int attr;
+ win_T *wp;
+ win_T *cwp;
+ int wincount;
+ 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);
+ char_u *p;
+ int room;
+ int use_sep_chars = (t_colors < 8
+ );
+
+ redraw_tabline = FALSE;
+
+
+ if (tabline_height() < 1)
+ return;
+
+
+ /* Init TabPageIdxs[] to zero: Clicking outside of tabs has no effect. */
+ for (scol = 0; scol < Columns; ++scol)
+ TabPageIdxs[scol] = 0;
+
+ /* Use the 'tabline' option if it's set. */
+ if (*p_tal != NUL) {
+ int save_called_emsg = called_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)
+ set_string_option_direct((char_u *)"tabline", -1,
+ (char_u *)"", OPT_FREE, SID_ERROR);
+ called_emsg |= save_called_emsg;
+ } else {
+ for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
+ ++tabcount;
+
+ tabwidth = (Columns - 1 + tabcount / 2) / tabcount;
+ if (tabwidth < 6)
+ tabwidth = 6;
+
+ attr = attr_nosel;
+ tabcount = 0;
+ scol = 0;
+ for (tp = first_tabpage; tp != NULL && col < Columns - 4;
+ tp = tp->tp_next) {
+ 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;
+ } else {
+ cwp = tp->tp_curwin;
+ wp = tp->tp_firstwin;
+ }
+
+ 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)
+ break;
+ screen_puts_len(NameBuff, len, 0, col,
+ hl_combine_attr(attr, hl_attr(HLF_T))
+ );
+ col += len;
+ }
+ if (modified)
+ screen_puts_len((char_u *)"+", 1, 0, col++, attr);
+ screen_putchar(' ', 0, col++, attr);
+ }
+
+ room = scol - col + tabwidth - 1;
+ if (room > 0) {
+ /* Get buffer name in NameBuff[] */
+ get_trans_bufname(cwp->w_buffer);
+ shorten_dir(NameBuff);
+ len = vim_strsize(NameBuff);
+ p = NameBuff;
+ if (has_mbyte)
+ while (len > room) {
+ len -= ptr2cells(p);
+ mb_ptr_adv(p);
+ }
+ else if (len > room) {
+ p += len - room;
+ len = room;
+ }
+ if (len > Columns - col - 1)
+ len = Columns - col - 1;
+
+ screen_puts_len(p, (int)STRLEN(p), 0, col, attr);
+ col += len;
+ }
+ screen_putchar(' ', 0, col++, attr);
+
+ /* Store the tab page number in TabPageIdxs[], so that
+ * jump_to_mouse() knows where each one is. */
+ ++tabcount;
+ while (scol < col)
+ TabPageIdxs[scol++] = tabcount;
+ }
+
+ if (use_sep_chars)
+ c = '_';
+ else
+ c = ' ';
+ screen_fill(0, 1, col, (int)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);
+ TabPageIdxs[Columns - 1] = -999;
+ }
+ }
+
+ /* Reset the flag here again, in case evaluating 'tabline' causes it to be
+ * set. */
+ redraw_tabline = FALSE;
+}
+
+/*
+ * Get buffer name for "buf" into NameBuff[].
+ * Takes care of special buffer names and translates special characters.
+ */
+void get_trans_bufname(buf)
+buf_T *buf;
+{
+ if (buf_spname(buf) != NULL)
+ vim_strncpy(NameBuff, buf_spname(buf), MAXPATHL - 1);
+ else
+ home_replace(buf, buf->b_fname, NameBuff, MAXPATHL, TRUE);
+ trans_characters(NameBuff, MAXPATHL);
+}
+
+/*
+ * Get the character to use in a status line. Get its attributes in "*attr".
+ */
+static int fillchar_status(attr, is_curwin)
+int *attr;
+int is_curwin;
+{
+ int fill;
+ if (is_curwin) {
+ *attr = hl_attr(HLF_S);
+ fill = fill_stl;
+ } else {
+ *attr = hl_attr(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)))
+ return fill;
+ if (is_curwin)
+ return '^';
+ return '=';
+}
+
+/*
+ * Get the character to use in a separator between vertically split windows.
+ * Get its attributes in "*attr".
+ */
+static int fillchar_vsep(attr)
+int *attr;
+{
+ *attr = hl_attr(HLF_C);
+ if (*attr == 0 && fill_vert == ' ')
+ return '|';
+ else
+ return fill_vert;
+}
+
+/*
+ * Return TRUE if redrawing should currently be done.
+ */
+int redrawing() {
+ return !RedrawingDisabled
+ && !(p_lz && char_avail() && !KeyTyped && !do_redraw);
+}
+
+/*
+ * Return TRUE if printing messages should currently be done.
+ */
+int messaging() {
+ return !(p_lz && char_avail() && !KeyTyped);
+}
+
+/*
+ * Show current status info in ruler and various other places
+ * If always is FALSE, only show ruler if position has changed.
+ */
+void showruler(always)
+int always;
+{
+ if (!always && !redrawing())
+ return;
+ if (pum_visible()) {
+ /* 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
+ win_redr_ruler(curwin, always);
+
+ if (need_maketitle
+ || (p_icon && (stl_syntax & STL_IN_ICON))
+ || (p_title && (stl_syntax & STL_IN_TITLE))
+ )
+ maketitle();
+ /* Redraw the tab pages line if needed. */
+ if (redraw_tabline)
+ draw_tabline();
+}
+
+static void win_redr_ruler(wp, always)
+win_T *wp;
+int always;
+{
+#define RULER_BUF_LEN 70
+ char_u buffer[RULER_BUF_LEN];
+ int row;
+ int fillchar;
+ int attr;
+ int empty_line = FALSE;
+ colnr_T virtcol;
+ int i;
+ size_t len;
+ int o;
+ int this_ru_col;
+ int off = 0;
+ int width = Columns;
+# define WITH_OFF(x) x
+# define WITH_WIDTH(x) x
+
+ /* If 'ruler' off or redrawing disabled, don't do anything */
+ if (!p_ru)
+ return;
+
+ /*
+ * Check if cursor.lnum is valid, since win_redr_ruler() may be called
+ * after deleting lines, before cursor.lnum is corrected.
+ */
+ if (wp->w_cursor.lnum > wp->w_buffer->b_ml.ml_line_count)
+ return;
+
+ /* Don't draw the ruler while doing insert-completion, it might overwrite
+ * the (long) mode message. */
+ 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())
+ return;
+
+ if (*p_ruf) {
+ int save_called_emsg = called_emsg;
+
+ called_emsg = FALSE;
+ win_redr_custom(wp, TRUE);
+ if (called_emsg)
+ set_string_option_direct((char_u *)"rulerformat", -1,
+ (char_u *)"", OPT_FREE, SID_ERROR);
+ called_emsg |= save_called_emsg;
+ return;
+ }
+
+ /*
+ * Check if not in Insert mode and the line is empty (will show "0-1").
+ */
+ if (!(State & INSERT)
+ && *ml_get_buf(wp->w_buffer, wp->w_cursor.lnum, FALSE) == NUL)
+ empty_line = TRUE;
+
+ /*
+ * Only draw the ruler when something changed.
+ */
+ validate_virtcol_win(wp);
+ if ( redraw_cmdline
+ || always
+ || wp->w_cursor.lnum != wp->w_ru_cursor.lnum
+ || wp->w_cursor.col != wp->w_ru_cursor.col
+ || wp->w_virtcol != wp->w_ru_virtcol
+ || wp->w_cursor.coladd != wp->w_ru_cursor.coladd
+ || wp->w_topline != wp->w_ru_topline
+ || wp->w_buffer->b_ml.ml_line_count != wp->w_ru_line_count
+ || wp->w_topfill != wp->w_ru_topfill
+ || empty_line != wp->w_ru_empty) {
+ cursor_off();
+ if (wp->w_status_height) {
+ row = W_WINROW(wp) + wp->w_height;
+ fillchar = fillchar_status(&attr, wp == curwin);
+ off = W_WINCOL(wp);
+ width = W_WIDTH(wp);
+ } else {
+ row = Rows - 1;
+ fillchar = ' ';
+ attr = 0;
+ width = Columns;
+ off = 0;
+ }
+
+ /* In list mode virtcol needs to be recomputed */
+ virtcol = wp->w_virtcol;
+ if (wp->w_p_list && lcs_tab1 == NUL) {
+ wp->w_p_list = FALSE;
+ getvvcol(wp, &wp->w_cursor, NULL, &virtcol, NULL);
+ wp->w_p_list = TRUE;
+ }
+
+ /*
+ * Some sprintfs return the length, some return a pointer.
+ * To avoid portability problems we use strlen() here.
+ */
+ vim_snprintf((char *)buffer, RULER_BUF_LEN, "%ld,",
+ (wp->w_buffer->b_ml.ml_flags & ML_EMPTY)
+ ? 0L
+ : (long)(wp->w_cursor.lnum));
+ len = STRLEN(buffer);
+ col_print(buffer + len, RULER_BUF_LEN - len,
+ empty_line ? 0 : (int)wp->w_cursor.col + 1,
+ (int)virtcol + 1);
+
+ /*
+ * Add a "50%" if there is room for it.
+ * On the last line, don't print in the last column (scrolls the
+ * screen up on some terminals).
+ */
+ i = (int)STRLEN(buffer);
+ get_rel_pos(wp, buffer + i + 1, RULER_BUF_LEN - i - 1);
+ o = i + vim_strsize(buffer + i + 1);
+ if (wp->w_status_height == 0) /* can't use last char of screen */
+ ++o;
+ this_ru_col = ru_col - (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 < (WITH_WIDTH(width) + 1) / 2)
+ this_ru_col = (WITH_WIDTH(width) + 1) / 2;
+ if (this_ru_col + o < WITH_WIDTH(width)) {
+ while (this_ru_col + o < WITH_WIDTH(width)) {
+ if (has_mbyte)
+ i += (*mb_char2bytes)(fillchar, buffer + i);
+ else
+ buffer[i++] = fillchar;
+ ++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 > WITH_WIDTH(width)) {
+ buffer[i] = NUL;
+ break;
+ }
+ }
+ } else if (this_ru_col + (int)STRLEN(buffer) > WITH_WIDTH(width))
+ buffer[WITH_WIDTH(width) - this_ru_col] = NUL;
+
+ screen_puts(buffer, row, this_ru_col + WITH_OFF(off), attr);
+ i = redraw_cmdline;
+ screen_fill(row, row + 1,
+ this_ru_col + WITH_OFF(off) + (int)STRLEN(buffer),
+ (int)(WITH_OFF(off) + WITH_WIDTH(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;
+ wp->w_ru_empty = empty_line;
+ wp->w_ru_topline = wp->w_topline;
+ wp->w_ru_line_count = wp->w_buffer->b_ml.ml_line_count;
+ wp->w_ru_topfill = wp->w_topfill;
+ }
+}
+
+/*
+ * Return the width of the 'number' and 'relativenumber' column.
+ * Caller may need to check if 'number' or 'relativenumber' is set.
+ * Otherwise it depends on 'numberwidth' and the line count.
+ */
+int number_width(wp)
+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 */
+ lnum = wp->w_buffer->b_ml.ml_line_count;
+
+ if (lnum == wp->w_nrwidth_line_count)
+ return wp->w_nrwidth_width;
+ wp->w_nrwidth_line_count = lnum;
+
+ n = 0;
+ do {
+ lnum /= 10;
+ ++n;
+ } while (lnum > 0);
+
+ /* 'numberwidth' gives the minimal width plus one */
+ if (n < wp->w_p_nuw - 1)
+ n = wp->w_p_nuw - 1;
+
+ wp->w_nrwidth_width = n;
+ return n;
+}
+
+/*
+ * Return the current cursor column. This is the actual position on the
+ * screen. First column is 0.
+ */
+int screen_screencol() {
+ return screen_cur_col;
+}
+
+/*
+ * Return the current cursor row. This is the actual position on the screen.
+ * First row is 0.
+ */
+int screen_screenrow() {
+ return screen_cur_row;
+}
+
diff --git a/src/search.c b/src/search.c
new file mode 100644
index 0000000000..6007b53375
--- /dev/null
+++ b/src/search.c
@@ -0,0 +1,4717 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * 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.
+ */
+/*
+ * search.c: code for normal mode searching commands
+ */
+
+#include "vim.h"
+
+static void save_re_pat __ARGS((int idx, char_u *pat, int magic));
+static void set_vv_searchforward __ARGS((void));
+static int first_submatch __ARGS((regmmatch_T *rp));
+static int check_prevcol __ARGS((char_u *linep, int col, int ch, int *prevcol));
+static int inmacro __ARGS((char_u *, char_u *));
+static int check_linecomment __ARGS((char_u *line));
+static int cls __ARGS((void));
+static int skip_chars __ARGS((int, int));
+static void back_in_line __ARGS((void));
+static void find_first_blank __ARGS((pos_T *));
+static void findsent_forward __ARGS((long count, int at_start_sent));
+static void show_pat_in_path __ARGS((char_u *, int,
+ int, int, FILE *, linenr_T *, long));
+static void wvsp_one __ARGS((FILE *fp, int idx, char *s, int sc));
+
+/*
+ * This file contains various searching-related routines. These fall into
+ * three groups:
+ * 1. string searches (for /, ?, n, and N)
+ * 2. character searches within a single line (for f, F, t, T, etc)
+ * 3. "other" kinds of searches like the '%' command, and 'word' searches.
+ */
+
+/*
+ * String searches
+ *
+ * The string search functions are divided into two levels:
+ * lowest: searchit(); uses an pos_T for starting position and found match.
+ * Highest: do_search(); uses curwin->w_cursor; calls searchit().
+ *
+ * The last search pattern is remembered for repeating the same search.
+ * This pattern is shared between the :g, :s, ? and / commands.
+ * This is in search_regcomp().
+ *
+ * The actual string matching is done using a heavily modified version of
+ * Henry Spencer's regular expression library. See regexp.c.
+ */
+
+/* The offset for a search command is store in a soff struct */
+/* Note: only spats[0].off is really used */
+struct soffset {
+ int dir; /* search direction, '/' or '?' */
+ int line; /* search has line offset */
+ int end; /* search set cursor at end */
+ long off; /* line or char offset */
+};
+
+/* A search pattern and its attributes are stored in a spat struct */
+struct spat {
+ char_u *pat; /* the pattern (in allocated memory) or NULL */
+ int magic; /* magicness of the pattern */
+ int no_scs; /* no smartcase for this pattern */
+ struct soffset off;
+};
+
+/*
+ * Two search patterns are remembered: One for the :substitute command and
+ * one for other searches. last_idx points to the one that was used the last
+ * time.
+ */
+static struct spat spats[2] =
+{
+ {NULL, TRUE, FALSE, {'/', 0, 0, 0L}}, /* last used search pat */
+ {NULL, TRUE, FALSE, {'/', 0, 0, 0L}} /* last used substitute pat */
+};
+
+static int last_idx = 0; /* index in spats[] for RE_LAST */
+
+/* copy of spats[], for keeping the search patterns while executing autocmds */
+static struct spat saved_spats[2];
+static int saved_last_idx = 0;
+static int saved_no_hlsearch = 0;
+
+static char_u *mr_pattern = NULL; /* pattern used by search_regcomp() */
+static int mr_pattern_alloced = FALSE; /* mr_pattern was allocated */
+
+/*
+ * Type used by find_pattern_in_path() to remember which included files have
+ * been searched already.
+ */
+typedef struct SearchedFile {
+ FILE *fp; /* File pointer */
+ char_u *name; /* Full name of file */
+ linenr_T lnum; /* Line we were up to in file */
+ int matched; /* Found a match in this file */
+} SearchedFile;
+
+/*
+ * translate search pattern for vim_regcomp()
+ *
+ * pat_save == RE_SEARCH: save pat in spats[RE_SEARCH].pat (normal search cmd)
+ * pat_save == RE_SUBST: save pat in spats[RE_SUBST].pat (:substitute command)
+ * pat_save == RE_BOTH: save pat in both patterns (:global command)
+ * pat_use == RE_SEARCH: use previous search pattern if "pat" is NULL
+ * pat_use == RE_SUBST: use previous substitute pattern if "pat" is NULL
+ * pat_use == RE_LAST: use last used pattern if "pat" is NULL
+ * options & SEARCH_HIS: put search string in history
+ * options & SEARCH_KEEP: keep previous search pattern
+ *
+ * returns FAIL if failed, OK otherwise.
+ */
+int search_regcomp(pat, pat_save, pat_use, options, regmatch)
+char_u *pat;
+int pat_save;
+int pat_use;
+int options;
+regmmatch_T *regmatch; /* return: pattern and ignore-case flag */
+{
+ int magic;
+ int i;
+
+ rc_did_emsg = FALSE;
+ magic = p_magic;
+
+ /*
+ * If no pattern given, use a previously defined pattern.
+ */
+ if (pat == NULL || *pat == NUL) {
+ if (pat_use == RE_LAST)
+ i = last_idx;
+ else
+ i = pat_use;
+ if (spats[i].pat == NULL) { /* pattern was never defined */
+ if (pat_use == RE_SUBST)
+ EMSG(_(e_nopresub));
+ else
+ EMSG(_(e_noprevre));
+ rc_did_emsg = TRUE;
+ return FAIL;
+ }
+ pat = spats[i].pat;
+ magic = spats[i].magic;
+ no_smartcase = spats[i].no_scs;
+ } else if (options & SEARCH_HIS) /* put new pattern in history */
+ add_to_history(HIST_SEARCH, pat, TRUE, NUL);
+
+ if (mr_pattern_alloced) {
+ vim_free(mr_pattern);
+ mr_pattern_alloced = FALSE;
+ }
+
+ if (curwin->w_p_rl && *curwin->w_p_rlc == 's') {
+ char_u *rev_pattern;
+
+ rev_pattern = reverse_text(pat);
+ if (rev_pattern == NULL)
+ mr_pattern = pat; /* out of memory, keep normal pattern. */
+ else {
+ mr_pattern = rev_pattern;
+ mr_pattern_alloced = TRUE;
+ }
+ } else
+ mr_pattern = pat;
+
+ /*
+ * Save the currently used pattern in the appropriate place,
+ * unless the pattern should not be remembered.
+ */
+ if (!(options & SEARCH_KEEP) && !cmdmod.keeppatterns) {
+ /* search or global command */
+ if (pat_save == RE_SEARCH || pat_save == RE_BOTH)
+ save_re_pat(RE_SEARCH, pat, magic);
+ /* substitute or global command */
+ if (pat_save == RE_SUBST || pat_save == RE_BOTH)
+ save_re_pat(RE_SUBST, pat, magic);
+ }
+
+ regmatch->rmm_ic = ignorecase(pat);
+ regmatch->rmm_maxcol = 0;
+ regmatch->regprog = vim_regcomp(pat, magic ? RE_MAGIC : 0);
+ if (regmatch->regprog == NULL)
+ return FAIL;
+ return OK;
+}
+
+/*
+ * Get search pattern used by search_regcomp().
+ */
+char_u * get_search_pat() {
+ return mr_pattern;
+}
+
+/*
+ * Reverse text into allocated memory.
+ * Returns the allocated string, NULL when out of memory.
+ */
+char_u * reverse_text(s)
+char_u *s;
+{
+ unsigned len;
+ unsigned s_i, rev_i;
+ char_u *rev;
+
+ /*
+ * Reverse the pattern.
+ */
+ len = (unsigned)STRLEN(s);
+ rev = alloc(len + 1);
+ if (rev != NULL) {
+ rev_i = len;
+ for (s_i = 0; s_i < len; ++s_i) {
+ if (has_mbyte) {
+ int mb_len;
+
+ mb_len = (*mb_ptr2len)(s + s_i);
+ rev_i -= mb_len;
+ mch_memmove(rev + rev_i, s + s_i, mb_len);
+ s_i += mb_len - 1;
+ } else
+ rev[--rev_i] = s[s_i];
+
+ }
+ rev[len] = NUL;
+ }
+ return rev;
+}
+
+static void save_re_pat(idx, pat, magic)
+int idx;
+char_u *pat;
+int magic;
+{
+ if (spats[idx].pat != pat) {
+ vim_free(spats[idx].pat);
+ spats[idx].pat = vim_strsave(pat);
+ spats[idx].magic = magic;
+ spats[idx].no_scs = no_smartcase;
+ last_idx = idx;
+ /* If 'hlsearch' set and search pat changed: need redraw. */
+ if (p_hls)
+ redraw_all_later(SOME_VALID);
+ SET_NO_HLSEARCH(FALSE);
+ }
+}
+
+/*
+ * Save the search patterns, so they can be restored later.
+ * Used before/after executing autocommands and user functions.
+ */
+static int save_level = 0;
+
+void save_search_patterns() {
+ if (save_level++ == 0) {
+ saved_spats[0] = spats[0];
+ if (spats[0].pat != NULL)
+ saved_spats[0].pat = vim_strsave(spats[0].pat);
+ saved_spats[1] = spats[1];
+ if (spats[1].pat != NULL)
+ saved_spats[1].pat = vim_strsave(spats[1].pat);
+ saved_last_idx = last_idx;
+ saved_no_hlsearch = no_hlsearch;
+ }
+}
+
+void restore_search_patterns() {
+ if (--save_level == 0) {
+ vim_free(spats[0].pat);
+ spats[0] = saved_spats[0];
+ set_vv_searchforward();
+ vim_free(spats[1].pat);
+ spats[1] = saved_spats[1];
+ last_idx = saved_last_idx;
+ SET_NO_HLSEARCH(saved_no_hlsearch);
+ }
+}
+
+#if defined(EXITFREE) || defined(PROTO)
+void free_search_patterns() {
+ vim_free(spats[0].pat);
+ vim_free(spats[1].pat);
+
+ if (mr_pattern_alloced) {
+ vim_free(mr_pattern);
+ mr_pattern_alloced = FALSE;
+ mr_pattern = NULL;
+ }
+}
+
+#endif
+
+/*
+ * Return TRUE when case should be ignored for search pattern "pat".
+ * Uses the 'ignorecase' and 'smartcase' options.
+ */
+int ignorecase(pat)
+char_u *pat;
+{
+ int ic = p_ic;
+
+ if (ic && !no_smartcase && p_scs
+ && !(ctrl_x_mode && curbuf->b_p_inf)
+ )
+ ic = !pat_has_uppercase(pat);
+ no_smartcase = FALSE;
+
+ return ic;
+}
+
+/*
+ * Return TRUE if patter "pat" has an uppercase character.
+ */
+int pat_has_uppercase(pat)
+char_u *pat;
+{
+ char_u *p = pat;
+
+ while (*p != NUL) {
+ int l;
+
+ if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1) {
+ if (enc_utf8 && utf_isupper(utf_ptr2char(p)))
+ return TRUE;
+ p += l;
+ } else if (*p == '\\') {
+ if (p[1] == '_' && p[2] != NUL) /* skip "\_X" */
+ p += 3;
+ else if (p[1] == '%' && p[2] != NUL) /* skip "\%X" */
+ p += 3;
+ else if (p[1] != NUL) /* skip "\X" */
+ p += 2;
+ else
+ p += 1;
+ } else if (MB_ISUPPER(*p))
+ return TRUE;
+ else
+ ++p;
+ }
+ return FALSE;
+}
+
+char_u * last_search_pat() {
+ return spats[last_idx].pat;
+}
+
+/*
+ * Reset search direction to forward. For "gd" and "gD" commands.
+ */
+void reset_search_dir() {
+ spats[0].off.dir = '/';
+ set_vv_searchforward();
+}
+
+/*
+ * Set the last search pattern. For ":let @/ =" and viminfo.
+ * Also set the saved search pattern, so that this works in an autocommand.
+ */
+void set_last_search_pat(s, idx, magic, setlast)
+char_u *s;
+int idx;
+int magic;
+int setlast;
+{
+ vim_free(spats[idx].pat);
+ /* An empty string means that nothing should be matched. */
+ if (*s == NUL)
+ spats[idx].pat = NULL;
+ else
+ spats[idx].pat = vim_strsave(s);
+ spats[idx].magic = magic;
+ spats[idx].no_scs = FALSE;
+ spats[idx].off.dir = '/';
+ set_vv_searchforward();
+ spats[idx].off.line = FALSE;
+ spats[idx].off.end = FALSE;
+ spats[idx].off.off = 0;
+ if (setlast)
+ last_idx = idx;
+ if (save_level) {
+ vim_free(saved_spats[idx].pat);
+ saved_spats[idx] = spats[0];
+ if (spats[idx].pat == NULL)
+ saved_spats[idx].pat = NULL;
+ else
+ saved_spats[idx].pat = vim_strsave(spats[idx].pat);
+ saved_last_idx = last_idx;
+ }
+ /* If 'hlsearch' set and search pat changed: need redraw. */
+ if (p_hls && idx == last_idx && !no_hlsearch)
+ redraw_all_later(SOME_VALID);
+}
+
+/*
+ * Get a regexp program for the last used search pattern.
+ * This is used for highlighting all matches in a window.
+ * Values returned in regmatch->regprog and regmatch->rmm_ic.
+ */
+void last_pat_prog(regmatch)
+regmmatch_T *regmatch;
+{
+ if (spats[last_idx].pat == NULL) {
+ regmatch->regprog = NULL;
+ return;
+ }
+ ++emsg_off; /* So it doesn't beep if bad expr */
+ (void)search_regcomp((char_u *)"", 0, last_idx, SEARCH_KEEP, regmatch);
+ --emsg_off;
+}
+
+/*
+ * lowest level search function.
+ * Search for 'count'th occurrence of pattern 'pat' in direction 'dir'.
+ * Start at position 'pos' and return the found position in 'pos'.
+ *
+ * if (options & SEARCH_MSG) == 0 don't give any messages
+ * if (options & SEARCH_MSG) == SEARCH_NFMSG don't give 'notfound' messages
+ * if (options & SEARCH_MSG) == SEARCH_MSG give all messages
+ * if (options & SEARCH_HIS) put search pattern in history
+ * if (options & SEARCH_END) return position at end of match
+ * if (options & SEARCH_START) accept match at pos itself
+ * if (options & SEARCH_KEEP) keep previous search pattern
+ * if (options & SEARCH_FOLD) match only once in a closed fold
+ * if (options & SEARCH_PEEK) check for typed char, cancel search
+ *
+ * Return FAIL (zero) for failure, non-zero for success.
+ * When FEAT_EVAL is defined, returns the index of the first matching
+ * subpattern plus one; one if there was none.
+ */
+int searchit(win, buf, pos, dir, pat, count, options, pat_use, stop_lnum, tm)
+win_T *win; /* window to search in; can be NULL for a
+ buffer without a window! */
+buf_T *buf;
+pos_T *pos;
+int dir;
+char_u *pat;
+long count;
+int options;
+int pat_use; /* which pattern to use when "pat" is empty */
+linenr_T stop_lnum; /* stop after this line number when != 0 */
+proftime_T *tm UNUSED; /* timeout limit or NULL */
+{
+ int found;
+ linenr_T lnum; /* no init to shut up Apollo cc */
+ regmmatch_T regmatch;
+ char_u *ptr;
+ colnr_T matchcol;
+ lpos_T endpos;
+ lpos_T matchpos;
+ int loop;
+ pos_T start_pos;
+ int at_first_line;
+ int extra_col;
+ int match_ok;
+ long nmatched;
+ int submatch = 0;
+ int save_called_emsg = called_emsg;
+ int break_loop = FALSE;
+
+ if (search_regcomp(pat, RE_SEARCH, pat_use,
+ (options & (SEARCH_HIS + SEARCH_KEEP)), &regmatch) == FAIL) {
+ if ((options & SEARCH_MSG) && !rc_did_emsg)
+ EMSG2(_("E383: Invalid search string: %s"), mr_pattern);
+ return FAIL;
+ }
+
+ /* When not accepting a match at the start position set "extra_col" to a
+ * non-zero value. Don't do that when starting at MAXCOL, since MAXCOL +
+ * 1 is zero. */
+ if ((options & SEARCH_START) || pos->col == MAXCOL)
+ extra_col = 0;
+ /* Watch out for the "col" being MAXCOL - 2, used in a closed fold. */
+ else if (dir != BACKWARD && has_mbyte
+ && pos->lnum >= 1 && pos->lnum <= buf->b_ml.ml_line_count
+ && pos->col < MAXCOL - 2) {
+ ptr = ml_get_buf(buf, pos->lnum, FALSE) + pos->col;
+ if (*ptr == NUL)
+ extra_col = 1;
+ else
+ extra_col = (*mb_ptr2len)(ptr);
+ } else
+ extra_col = 1;
+
+ /*
+ * find the string
+ */
+ called_emsg = FALSE;
+ do { /* loop for count */
+ start_pos = *pos; /* remember start pos for detecting no match */
+ found = 0; /* default: not found */
+ at_first_line = TRUE; /* default: start in first line */
+ if (pos->lnum == 0) { /* correct lnum for when starting in line 0 */
+ pos->lnum = 1;
+ pos->col = 0;
+ at_first_line = FALSE; /* not in first line now */
+ }
+
+ /*
+ * Start searching in current line, unless searching backwards and
+ * we're in column 0.
+ * If we are searching backwards, in column 0, and not including the
+ * current position, gain some efficiency by skipping back a line.
+ * Otherwise begin the search in the current line.
+ */
+ if (dir == BACKWARD && start_pos.col == 0
+ && (options & SEARCH_START) == 0) {
+ lnum = pos->lnum - 1;
+ at_first_line = FALSE;
+ } else
+ lnum = pos->lnum;
+
+ for (loop = 0; loop <= 1; ++loop) { /* loop twice if 'wrapscan' set */
+ for (; lnum > 0 && lnum <= buf->b_ml.ml_line_count;
+ lnum += dir, at_first_line = FALSE) {
+ /* Stop after checking "stop_lnum", if it's set. */
+ if (stop_lnum != 0 && (dir == FORWARD
+ ? lnum > stop_lnum : lnum < stop_lnum))
+ break;
+ /* Stop after passing the "tm" time limit. */
+ if (tm != NULL && profile_passed_limit(tm))
+ break;
+
+ /*
+ * Look for a match somewhere in line "lnum".
+ */
+ nmatched = vim_regexec_multi(&regmatch, win, buf,
+ lnum, (colnr_T)0,
+ tm
+ );
+ /* Abort searching on an error (e.g., out of stack). */
+ if (called_emsg)
+ break;
+ if (nmatched > 0) {
+ /* match may actually be in another line when using \zs */
+ matchpos = regmatch.startpos[0];
+ endpos = regmatch.endpos[0];
+ submatch = first_submatch(&regmatch);
+ /* "lnum" may be past end of buffer for "\n\zs". */
+ if (lnum + matchpos.lnum > buf->b_ml.ml_line_count)
+ ptr = (char_u *)"";
+ else
+ ptr = ml_get_buf(buf, lnum + matchpos.lnum, FALSE);
+
+ /*
+ * Forward search in the first line: match should be after
+ * the start position. If not, continue at the end of the
+ * match (this is vi compatible) or on the next char.
+ */
+ if (dir == FORWARD && at_first_line) {
+ match_ok = TRUE;
+ /*
+ * When the match starts in a next line it's certainly
+ * past the start position.
+ * When match lands on a NUL the cursor will be put
+ * one back afterwards, compare with that position,
+ * otherwise "/$" will get stuck on end of line.
+ */
+ while (matchpos.lnum == 0
+ && ((options & SEARCH_END)
+ ? (nmatched == 1
+ && (int)endpos.col - 1
+ < (int)start_pos.col + extra_col)
+ : ((int)matchpos.col
+ - (ptr[matchpos.col] == NUL)
+ < (int)start_pos.col + extra_col))) {
+ /*
+ * If vi-compatible searching, continue at the end
+ * of the match, otherwise continue one position
+ * forward.
+ */
+ if (vim_strchr(p_cpo, CPO_SEARCH) != NULL) {
+ if (nmatched > 1) {
+ /* end is in next line, thus no match in
+ * this line */
+ match_ok = FALSE;
+ break;
+ }
+ matchcol = endpos.col;
+ /* for empty match: advance one char */
+ if (matchcol == matchpos.col
+ && ptr[matchcol] != NUL) {
+ if (has_mbyte)
+ matchcol +=
+ (*mb_ptr2len)(ptr + matchcol);
+ else
+ ++matchcol;
+ }
+ } else {
+ matchcol = matchpos.col;
+ if (ptr[matchcol] != NUL) {
+ if (has_mbyte)
+ matchcol += (*mb_ptr2len)(ptr
+ + matchcol);
+ else
+ ++matchcol;
+ }
+ }
+ if (matchcol == 0 && (options & SEARCH_START))
+ break;
+ if (ptr[matchcol] == NUL
+ || (nmatched = vim_regexec_multi(&regmatch,
+ win, buf, lnum + matchpos.lnum,
+ matchcol,
+ tm
+ )) == 0) {
+ match_ok = FALSE;
+ break;
+ }
+ matchpos = regmatch.startpos[0];
+ endpos = regmatch.endpos[0];
+ submatch = first_submatch(&regmatch);
+
+ /* Need to get the line pointer again, a
+ * multi-line search may have made it invalid. */
+ ptr = ml_get_buf(buf, lnum + matchpos.lnum, FALSE);
+ }
+ if (!match_ok)
+ continue;
+ }
+ if (dir == BACKWARD) {
+ /*
+ * Now, if there are multiple matches on this line,
+ * we have to get the last one. Or the last one before
+ * the cursor, if we're on that line.
+ * When putting the new cursor at the end, compare
+ * relative to the end of the match.
+ */
+ match_ok = FALSE;
+ for (;; ) {
+ /* Remember a position that is before the start
+ * position, we use it if it's the last match in
+ * the line. Always accept a position after
+ * wrapping around. */
+ if (loop
+ || ((options & SEARCH_END)
+ ? (lnum + regmatch.endpos[0].lnum
+ < start_pos.lnum
+ || (lnum + regmatch.endpos[0].lnum
+ == start_pos.lnum
+ && (int)regmatch.endpos[0].col - 1
+ + extra_col
+ <= (int)start_pos.col))
+ : (lnum + regmatch.startpos[0].lnum
+ < start_pos.lnum
+ || (lnum + regmatch.startpos[0].lnum
+ == start_pos.lnum
+ && (int)regmatch.startpos[0].col
+ + extra_col
+ <= (int)start_pos.col)))) {
+ match_ok = TRUE;
+ matchpos = regmatch.startpos[0];
+ endpos = regmatch.endpos[0];
+ submatch = first_submatch(&regmatch);
+ } else
+ break;
+
+ /*
+ * We found a valid match, now check if there is
+ * another one after it.
+ * If vi-compatible searching, continue at the end
+ * of the match, otherwise continue one position
+ * forward.
+ */
+ if (vim_strchr(p_cpo, CPO_SEARCH) != NULL) {
+ if (nmatched > 1)
+ break;
+ matchcol = endpos.col;
+ /* for empty match: advance one char */
+ if (matchcol == matchpos.col
+ && ptr[matchcol] != NUL) {
+ if (has_mbyte)
+ matchcol +=
+ (*mb_ptr2len)(ptr + matchcol);
+ else
+ ++matchcol;
+ }
+ } else {
+ /* Stop when the match is in a next line. */
+ if (matchpos.lnum > 0)
+ break;
+ matchcol = matchpos.col;
+ if (ptr[matchcol] != NUL) {
+ if (has_mbyte)
+ matchcol +=
+ (*mb_ptr2len)(ptr + matchcol);
+ else
+ ++matchcol;
+ }
+ }
+ if (ptr[matchcol] == NUL
+ || (nmatched = vim_regexec_multi(&regmatch,
+ win, buf, lnum + matchpos.lnum,
+ matchcol,
+ tm
+ )) == 0)
+ break;
+
+ /* Need to get the line pointer again, a
+ * multi-line search may have made it invalid. */
+ ptr = ml_get_buf(buf, lnum + matchpos.lnum, FALSE);
+ }
+
+ /*
+ * If there is only a match after the cursor, skip
+ * this match.
+ */
+ if (!match_ok)
+ continue;
+ }
+
+ /* With the SEARCH_END option move to the last character
+ * of the match. Don't do it for an empty match, end
+ * should be same as start then. */
+ if ((options & SEARCH_END) && !(options & SEARCH_NOOF)
+ && !(matchpos.lnum == endpos.lnum
+ && matchpos.col == endpos.col)) {
+ /* For a match in the first column, set the position
+ * on the NUL in the previous line. */
+ pos->lnum = lnum + endpos.lnum;
+ pos->col = endpos.col;
+ if (endpos.col == 0) {
+ if (pos->lnum > 1) { /* just in case */
+ --pos->lnum;
+ pos->col = (colnr_T)STRLEN(ml_get_buf(buf,
+ 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);
+ }
+ }
+ } else {
+ pos->lnum = lnum + matchpos.lnum;
+ pos->col = matchpos.col;
+ }
+ pos->coladd = 0;
+ found = 1;
+
+ /* Set variables used for 'incsearch' highlighting. */
+ search_match_lines = endpos.lnum - matchpos.lnum;
+ search_match_endcol = endpos.col;
+ break;
+ }
+ line_breakcheck(); /* stop if ctrl-C typed */
+ if (got_int)
+ break;
+
+ /* Cancel searching if a character was typed. Used for
+ * 'incsearch'. Don't check too often, that would slowdown
+ * searching too much. */
+ if ((options & SEARCH_PEEK)
+ && ((lnum - pos->lnum) & 0x3f) == 0
+ && char_avail()) {
+ break_loop = TRUE;
+ break;
+ }
+
+ if (loop && lnum == start_pos.lnum)
+ break; /* if second loop, stop where started */
+ }
+ at_first_line = FALSE;
+
+ /*
+ * Stop the search if wrapscan isn't set, "stop_lnum" is
+ * specified, after an interrupt, after a match and after looping
+ * twice.
+ */
+ if (!p_ws || stop_lnum != 0 || got_int || called_emsg
+ || break_loop
+ || found || loop)
+ break;
+
+ /*
+ * If 'wrapscan' is set we continue at the other end of the file.
+ * If 'shortmess' does not contain 's', we give a message.
+ * This message is also remembered in keep_msg for when the screen
+ * is redrawn. The keep_msg is cleared whenever another message is
+ * written.
+ */
+ if (dir == BACKWARD) /* start second loop at the other end */
+ lnum = buf->b_ml.ml_line_count;
+ else
+ lnum = 1;
+ if (!shortmess(SHM_SEARCH) && (options & SEARCH_MSG))
+ give_warning((char_u *)_(dir == BACKWARD
+ ? top_bot_msg : bot_top_msg), TRUE);
+ }
+ if (got_int || called_emsg
+ || break_loop
+ )
+ break;
+ } while (--count > 0 && found); /* stop after count matches or no match */
+
+ vim_regfree(regmatch.regprog);
+
+ called_emsg |= save_called_emsg;
+
+ if (!found) { /* did not find it */
+ if (got_int)
+ EMSG(_(e_interr));
+ else if ((options & SEARCH_MSG) == SEARCH_MSG) {
+ if (p_ws)
+ EMSG2(_(e_patnotf2), mr_pattern);
+ else if (lnum == 0)
+ EMSG2(_("E384: search hit TOP without match for: %s"),
+ mr_pattern);
+ else
+ EMSG2(_("E385: search hit BOTTOM without match for: %s"),
+ mr_pattern);
+ }
+ return FAIL;
+ }
+
+ /* A pattern like "\n\zs" may go past the last line. */
+ if (pos->lnum > buf->b_ml.ml_line_count) {
+ pos->lnum = buf->b_ml.ml_line_count;
+ pos->col = (int)STRLEN(ml_get_buf(buf, pos->lnum, FALSE));
+ if (pos->col > 0)
+ --pos->col;
+ }
+
+ return submatch + 1;
+}
+
+void set_search_direction(cdir)
+int cdir;
+{
+ spats[0].off.dir = cdir;
+}
+
+static void set_vv_searchforward() {
+ set_vim_var_nr(VV_SEARCHFORWARD, (long)(spats[0].off.dir == '/'));
+}
+
+/*
+ * Return the number of the first subpat that matched.
+ */
+static int first_submatch(rp)
+regmmatch_T *rp;
+{
+ int submatch;
+
+ for (submatch = 1;; ++submatch) {
+ if (rp->startpos[submatch].lnum >= 0)
+ break;
+ if (submatch == 9) {
+ submatch = 0;
+ break;
+ }
+ }
+ return submatch;
+}
+
+/*
+ * Highest level string search function.
+ * Search for the 'count'th occurrence of pattern 'pat' in direction 'dirc'
+ * If 'dirc' is 0: use previous dir.
+ * If 'pat' is NULL or empty : use previous string.
+ * If 'options & SEARCH_REV' : go in reverse of previous dir.
+ * If 'options & SEARCH_ECHO': echo the search command and handle options
+ * If 'options & SEARCH_MSG' : may give error message
+ * If 'options & SEARCH_OPT' : interpret optional flags
+ * If 'options & SEARCH_HIS' : put search pattern in history
+ * If 'options & SEARCH_NOOF': don't add offset to position
+ * If 'options & SEARCH_MARK': set previous context mark
+ * If 'options & SEARCH_KEEP': keep previous search pattern
+ * If 'options & SEARCH_START': accept match at curpos itself
+ * If 'options & SEARCH_PEEK': check for typed char, cancel search
+ *
+ * Careful: If spats[0].off.line == TRUE and spats[0].off.off == 0 this
+ * makes the movement linewise without moving the match position.
+ *
+ * return 0 for failure, 1 for found, 2 for found and line offset added
+ */
+int do_search(oap, dirc, pat, count, options, tm)
+oparg_T *oap; /* can be NULL */
+int dirc; /* '/' or '?' */
+char_u *pat;
+long count;
+int options;
+proftime_T *tm; /* timeout limit or NULL */
+{
+ pos_T pos; /* position of the last match */
+ char_u *searchstr;
+ struct soffset old_off;
+ int retval; /* Return value */
+ char_u *p;
+ long c;
+ char_u *dircp;
+ char_u *strcopy = NULL;
+ char_u *ps;
+
+ /*
+ * A line offset is not remembered, this is vi compatible.
+ */
+ if (spats[0].off.line && vim_strchr(p_cpo, CPO_LINEOFF) != NULL) {
+ spats[0].off.line = FALSE;
+ spats[0].off.off = 0;
+ }
+
+ /*
+ * Save the values for when (options & SEARCH_KEEP) is used.
+ * (there is no "if ()" around this because gcc wants them initialized)
+ */
+ old_off = spats[0].off;
+
+ pos = curwin->w_cursor; /* start searching at the cursor position */
+
+ /*
+ * Find out the direction of the search.
+ */
+ if (dirc == 0)
+ dirc = spats[0].off.dir;
+ else {
+ spats[0].off.dir = dirc;
+ set_vv_searchforward();
+ }
+ if (options & SEARCH_REV) {
+ if (dirc == '/')
+ dirc = '?';
+ else
+ dirc = '/';
+ }
+
+ /* If the cursor is in a closed fold, don't find another match in the same
+ * fold. */
+ if (dirc == '/') {
+ if (hasFolding(pos.lnum, NULL, &pos.lnum))
+ pos.col = MAXCOL - 2; /* avoid overflow when adding 1 */
+ } else {
+ if (hasFolding(pos.lnum, &pos.lnum, NULL))
+ pos.col = 0;
+ }
+
+ /*
+ * Turn 'hlsearch' highlighting back on.
+ */
+ if (no_hlsearch && !(options & SEARCH_KEEP)) {
+ redraw_all_later(SOME_VALID);
+ SET_NO_HLSEARCH(FALSE);
+ }
+
+ /*
+ * Repeat the search when pattern followed by ';', e.g. "/foo/;?bar".
+ */
+ for (;; ) {
+ searchstr = pat;
+ 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) {
+ EMSG(_(e_noprevre));
+ retval = 0;
+ goto end_do_search;
+ }
+ searchstr = pat;
+ } else {
+ /* make search_regcomp() use spats[RE_SEARCH].pat */
+ searchstr = (char_u *)"";
+ }
+ }
+
+ if (pat != NULL && *pat != NUL) { /* look for (new) offset */
+ /*
+ * Find end of regular expression.
+ * If there is a matching '/' or '?', toss it.
+ */
+ ps = strcopy;
+ p = skip_regexp(pat, dirc, (int)p_magic, &strcopy);
+ if (strcopy != ps) {
+ /* made a copy of "pat" to change "\?" to "?" */
+ searchcmdlen += (int)(STRLEN(pat) - STRLEN(strcopy));
+ pat = strcopy;
+ searchstr = strcopy;
+ }
+ if (*p == dirc) {
+ dircp = p; /* remember where we put the NUL */
+ *p++ = NUL;
+ }
+ spats[0].off.line = FALSE;
+ spats[0].off.end = FALSE;
+ spats[0].off.off = 0;
+ /*
+ * Check for a line offset or a character offset.
+ * For get_address (echo off) we don't check for a character
+ * offset, because it is meaningless and the 's' could be a
+ * substitute command.
+ */
+ if (*p == '+' || *p == '-' || VIM_ISDIGIT(*p))
+ spats[0].off.line = TRUE;
+ else if ((options & SEARCH_OPT) &&
+ (*p == 'e' || *p == 's' || *p == 'b')) {
+ if (*p == 'e') /* end */
+ spats[0].off.end = SEARCH_END;
+ ++p;
+ }
+ if (VIM_ISDIGIT(*p) || *p == '+' || *p == '-') { /* got an offset */
+ /* 'nr' or '+nr' or '-nr' */
+ if (VIM_ISDIGIT(*p) || VIM_ISDIGIT(*(p + 1)))
+ spats[0].off.off = atol((char *)p);
+ else if (*p == '-') /* single '-' */
+ spats[0].off.off = -1;
+ else /* single '+' */
+ spats[0].off.off = 1;
+ ++p;
+ while (VIM_ISDIGIT(*p)) /* skip number */
+ ++p;
+ }
+
+ /* compute length of search command for get_address() */
+ searchcmdlen += (int)(p - pat);
+
+ pat = p; /* put pat after search command */
+ }
+
+ if ((options & SEARCH_ECHO) && messaging()
+ && !cmd_silent && msg_silent == 0) {
+ char_u *msgbuf;
+ char_u *trunc;
+
+ if (*searchstr == NUL)
+ p = spats[last_idx].pat;
+ else
+ p = searchstr;
+ msgbuf = alloc((unsigned)(STRLEN(p) + 40));
+ if (msgbuf != NULL) {
+ msgbuf[0] = dirc;
+ if (enc_utf8 && utf_iscomposing(utf_ptr2char(p))) {
+ /* Use a space to draw the composing char on. */
+ msgbuf[1] = ' ';
+ STRCPY(msgbuf + 2, p);
+ } else
+ STRCPY(msgbuf + 1, p);
+ if (spats[0].off.line || spats[0].off.end || spats[0].off.off) {
+ p = msgbuf + STRLEN(msgbuf);
+ *p++ = dirc;
+ if (spats[0].off.end)
+ *p++ = 'e';
+ else if (!spats[0].off.line)
+ *p++ = 's';
+ if (spats[0].off.off > 0 || spats[0].off.line)
+ *p++ = '+';
+ if (spats[0].off.off != 0 || spats[0].off.line)
+ sprintf((char *)p, "%ld", spats[0].off.off);
+ else
+ *p = NUL;
+ }
+
+ msg_start();
+ trunc = msg_strtrunc(msgbuf, FALSE);
+
+ /* The search pattern could be shown on the right in rightleft
+ * mode, but the 'ruler' and 'showcmd' area use it too, thus
+ * it would be blanked out again very soon. Show it on the
+ * left, but do reverse the text. */
+ if (curwin->w_p_rl && *curwin->w_p_rlc == 's') {
+ char_u *r;
+
+ r = reverse_text(trunc != NULL ? trunc : msgbuf);
+ if (r != NULL) {
+ vim_free(trunc);
+ trunc = r;
+ }
+ }
+ if (trunc != NULL) {
+ msg_outtrans(trunc);
+ vim_free(trunc);
+ } else
+ msg_outtrans(msgbuf);
+ msg_clr_eos();
+ msg_check();
+ vim_free(msgbuf);
+
+ gotocmdline(FALSE);
+ out_flush();
+ msg_nowait = TRUE; /* don't wait for this message */
+ }
+ }
+
+ /*
+ * If there is a character offset, subtract it from the current
+ * position, so we don't get stuck at "?pat?e+2" or "/pat/s-2".
+ * Skip this if pos.col is near MAXCOL (closed fold).
+ * This is not done for a line offset, because then we would not be vi
+ * compatible.
+ */
+ if (!spats[0].off.line && spats[0].off.off && pos.col < MAXCOL - 2) {
+ if (spats[0].off.off > 0) {
+ for (c = spats[0].off.off; c; --c)
+ if (decl(&pos) == -1)
+ break;
+ if (c) { /* at start of buffer */
+ pos.lnum = 0; /* allow lnum == 0 here */
+ pos.col = MAXCOL;
+ }
+ } else {
+ for (c = spats[0].off.off; c; ++c)
+ if (incl(&pos) == -1)
+ break;
+ if (c) { /* at end of buffer */
+ pos.lnum = curbuf->b_ml.ml_line_count + 1;
+ pos.col = 0;
+ }
+ }
+ }
+
+ if (p_altkeymap && curwin->w_p_rl)
+ lrFswap(searchstr,0);
+
+ c = searchit(curwin, curbuf, &pos, dirc == '/' ? FORWARD : BACKWARD,
+ searchstr, count, spats[0].off.end + (options &
+ (SEARCH_KEEP + SEARCH_PEEK +
+ SEARCH_HIS
+ + SEARCH_MSG + SEARCH_START
+ + ((pat != NULL && *pat ==
+ ';') ? 0 : SEARCH_NOOF))),
+ RE_LAST, (linenr_T)0, tm);
+
+ if (dircp != NULL)
+ *dircp = dirc; /* restore second '/' or '?' for normal_cmd() */
+ if (c == FAIL) {
+ retval = 0;
+ goto end_do_search;
+ }
+ if (spats[0].off.end && oap != NULL)
+ oap->inclusive = TRUE; /* 'e' includes last character */
+
+ retval = 1; /* pattern found */
+
+ /*
+ * Add character and/or line offset
+ */
+ if (!(options & SEARCH_NOOF) || (pat != NULL && *pat == ';')) {
+ if (spats[0].off.line) { /* Add the offset to the line number. */
+ c = pos.lnum + spats[0].off.off;
+ if (c < 1)
+ pos.lnum = 1;
+ else if (c > curbuf->b_ml.ml_line_count)
+ pos.lnum = curbuf->b_ml.ml_line_count;
+ else
+ pos.lnum = c;
+ pos.col = 0;
+
+ retval = 2; /* pattern found, line offset added */
+ } else if (pos.col < MAXCOL - 2) { /* just in case */
+ /* to the right, check for end of file */
+ c = spats[0].off.off;
+ if (c > 0) {
+ while (c-- > 0)
+ if (incl(&pos) == -1)
+ break;
+ }
+ /* to the left, check for start of file */
+ else {
+ while (c++ < 0)
+ if (decl(&pos) == -1)
+ break;
+ }
+ }
+ }
+
+ /*
+ * The search command can be followed by a ';' to do another search.
+ * For example: "/pat/;/foo/+3;?bar"
+ * This is like doing another search command, except:
+ * - The remembered direction '/' or '?' is from the first search.
+ * - When an error happens the cursor isn't moved at all.
+ * Don't do this when called by get_address() (it handles ';' itself).
+ */
+ if (!(options & SEARCH_OPT) || pat == NULL || *pat != ';')
+ break;
+
+ dirc = *++pat;
+ if (dirc != '?' && dirc != '/') {
+ retval = 0;
+ EMSG(_("E386: Expected '?' or '/' after ';'"));
+ goto end_do_search;
+ }
+ ++pat;
+ }
+
+ if (options & SEARCH_MARK)
+ setpcmark();
+ curwin->w_cursor = pos;
+ curwin->w_set_curswant = TRUE;
+
+end_do_search:
+ if ((options & SEARCH_KEEP) || cmdmod.keeppatterns)
+ spats[0].off = old_off;
+ vim_free(strcopy);
+
+ return retval;
+}
+
+/*
+ * 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
+ * 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.
+ * Return OK for success, or FAIL if no line found.
+ */
+int search_for_exact_line(buf, pos, dir, pat)
+buf_T *buf;
+pos_T *pos;
+int dir;
+char_u *pat;
+{
+ linenr_T start = 0;
+ char_u *ptr;
+ char_u *p;
+
+ if (buf->b_ml.ml_line_count == 0)
+ return FAIL;
+ for (;; ) {
+ pos->lnum += dir;
+ if (pos->lnum < 1) {
+ if (p_ws) {
+ pos->lnum = buf->b_ml.ml_line_count;
+ if (!shortmess(SHM_SEARCH))
+ give_warning((char_u *)_(top_bot_msg), TRUE);
+ } else {
+ pos->lnum = 1;
+ break;
+ }
+ } else if (pos->lnum > buf->b_ml.ml_line_count) {
+ if (p_ws) {
+ pos->lnum = 1;
+ if (!shortmess(SHM_SEARCH))
+ give_warning((char_u *)_(bot_top_msg), TRUE);
+ } else {
+ pos->lnum = 1;
+ break;
+ }
+ }
+ if (pos->lnum == start)
+ break;
+ if (start == 0)
+ start = pos->lnum;
+ ptr = ml_get_buf(buf, pos->lnum, FALSE);
+ p = skipwhite(ptr);
+ pos->col = (colnr_T) (p - ptr);
+
+ /* when adding lines the matching line may be empty but it is not
+ * 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)
+ return OK;
+ } else if (*p != NUL) { /* ignore empty lines */
+ /* expanding lines or words */
+ if ((p_ic ? MB_STRNICMP(p, pat, compl_length)
+ : STRNCMP(p, pat, compl_length)) == 0)
+ return OK;
+ }
+ }
+ return FAIL;
+}
+
+/*
+ * Character Searches
+ */
+
+/*
+ * Search for a character in a line. If "t_cmd" is FALSE, move to the
+ * position of the character, otherwise move to just before the char.
+ * Do this "cap->count1" times.
+ * Return FAIL or OK.
+ */
+int searchc(cap, t_cmd)
+cmdarg_T *cap;
+int t_cmd;
+{
+ int c = cap->nchar; /* char to search for */
+ int dir = cap->arg; /* TRUE for searching forward */
+ long count = cap->count1; /* repeat count */
+ static int lastc = NUL; /* last character searched for */
+ static int lastcdir; /* last direction of character search */
+ static int last_t_cmd; /* last search t_cmd */
+ int col;
+ char_u *p;
+ int len;
+ int stop = TRUE;
+ static char_u bytes[MB_MAXBYTES + 1];
+ static int bytelen = 1; /* >1 for multi-byte char */
+
+ if (c != NUL) { /* normal search: remember args for repeat */
+ if (!KeyStuffed) { /* don't remember when redoing */
+ lastc = c;
+ lastcdir = dir;
+ last_t_cmd = t_cmd;
+ bytelen = (*mb_char2bytes)(c, bytes);
+ if (cap->ncharC1 != 0) {
+ bytelen += (*mb_char2bytes)(cap->ncharC1, bytes + bytelen);
+ if (cap->ncharC2 != 0)
+ bytelen += (*mb_char2bytes)(cap->ncharC2, bytes + bytelen);
+ }
+ }
+ } else { /* repeat previous search */
+ if (lastc == NUL)
+ return FAIL;
+ if (dir) /* repeat in opposite direction */
+ dir = -lastcdir;
+ else
+ dir = lastcdir;
+ t_cmd = last_t_cmd;
+ c = lastc;
+ /* For multi-byte re-use last bytes[] and bytelen. */
+
+ /* Force a move of at least one char, so ";" and "," will move the
+ * cursor, even if the cursor is right in front of char we are looking
+ * at. */
+ if (vim_strchr(p_cpo, CPO_SCOLON) == NULL && count == 1 && t_cmd)
+ stop = FALSE;
+ }
+
+ if (dir == BACKWARD)
+ cap->oap->inclusive = FALSE;
+ else
+ cap->oap->inclusive = TRUE;
+
+ p = ml_get_curline();
+ col = curwin->w_cursor.col;
+ len = (int)STRLEN(p);
+
+ while (count--) {
+ if (has_mbyte) {
+ for (;; ) {
+ if (dir > 0) {
+ col += (*mb_ptr2len)(p + col);
+ if (col >= len)
+ return FAIL;
+ } else {
+ if (col == 0)
+ return FAIL;
+ col -= (*mb_head_off)(p, p + col - 1) + 1;
+ }
+ if (bytelen == 1) {
+ if (p[col] == c && stop)
+ break;
+ } else {
+ if (vim_memcmp(p + col, bytes, bytelen) == 0 && stop)
+ break;
+ }
+ stop = TRUE;
+ }
+ } else {
+ for (;; ) {
+ if ((col += dir) < 0 || col >= len)
+ return FAIL;
+ if (p[col] == c && stop)
+ break;
+ stop = TRUE;
+ }
+ }
+ }
+
+ if (t_cmd) {
+ /* backup to before the character (possibly double-byte) */
+ col -= dir;
+ if (has_mbyte) {
+ if (dir < 0)
+ /* Landed on the search char which is bytelen long */
+ col += bytelen - 1;
+ else
+ /* To previous char, which may be multi-byte. */
+ col -= (*mb_head_off)(p, p + col);
+ }
+ }
+ curwin->w_cursor.col = col;
+
+ return OK;
+}
+
+/*
+ * "Other" Searches
+ */
+
+/*
+ * findmatch - find the matching paren or brace
+ *
+ * Improvement over vi: Braces inside quotes are ignored.
+ */
+pos_T * findmatch(oap, initc)
+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(linep, col, ch, 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)
+ *prevcol = col;
+ return (col >= 0 && linep[col] == ch) ? TRUE : FALSE;
+}
+
+/*
+ * findmatchlimit -- find the matching paren or brace, if it exists within
+ * maxtravel lines of here. A maxtravel of 0 means search until falling off
+ * the edge of the file.
+ *
+ * "initc" is the character to find a match for. NUL means to find the
+ * character at or after the cursor.
+ *
+ * flags: FM_BACKWARD search backwards (when initc is '/', '*' or '#')
+ * FM_FORWARD search forwards (when initc is '/', '*' or '#')
+ * FM_BLOCKSTOP stop at start/end of block ({ or } in column 0)
+ * FM_SKIPCOMM skip comments (not implemented yet!)
+ *
+ * "oap" is only used to set oap->motion_type for a linewise motion, it be
+ * NULL
+ */
+
+pos_T * findmatchlimit(oap, initc, flags, maxtravel)
+oparg_T *oap;
+int initc;
+int flags;
+int 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 inquote = FALSE; /* TRUE when inside quotes */
+ char_u *linep; /* pointer to current line */
+ 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 ;) */
+
+ pos = curwin->w_cursor;
+ pos.coladd = 0;
+ linep = ml_get(pos.lnum);
+
+ cpo_match = (vim_strchr(p_cpo, CPO_MATCH) != NULL);
+ cpo_bsl = (vim_strchr(p_cpo, CPO_MATCHBSL) != NULL);
+
+ /* Direction to search when initc is '/', '*' or '#' */
+ if (flags & FM_BACKWARD)
+ dir = BACKWARD;
+ else if (flags & FM_FORWARD)
+ dir = FORWARD;
+ else
+ dir = 0;
+
+ /*
+ * if initc given, look in the table for the matching character
+ * '/' and '*' are special cases: look for start or end of comment.
+ * When '/' is used, we ignore running backwards into an star-slash, for
+ * "[*" command, we just want to find any comment.
+ */
+ if (initc == '/' || initc == '*') {
+ comment_dir = dir;
+ if (initc == '/')
+ ignore_cend = TRUE;
+ backwards = (dir == FORWARD) ? FALSE : TRUE;
+ initc = NUL;
+ } else if (initc != '#' && initc != NUL) {
+ find_mps_values(&initc, &findc, &backwards, TRUE);
+ if (findc == NUL)
+ return NULL;
+ }
+ /*
+ * Either initc is '#', or no initc was given and we need to look under the
+ * cursor.
+ */
+ else {
+ if (initc == '#') {
+ hash_dir = dir;
+ } else {
+ /*
+ * initc was not given, must look for something to match under
+ * or near the cursor.
+ * Only check for special things when 'cpo' doesn't have '%'.
+ */
+ if (!cpo_match) {
+ /* Are we before or at #if, #else etc.? */
+ ptr = skipwhite(linep);
+ if (*ptr == '#' && pos.col <= (colnr_T)(ptr - linep)) {
+ ptr = skipwhite(ptr + 1);
+ if ( STRNCMP(ptr, "if", 2) == 0
+ || STRNCMP(ptr, "endif", 5) == 0
+ || STRNCMP(ptr, "el", 2) == 0)
+ hash_dir = 1;
+ }
+ /* Are we on a comment? */
+ else if (linep[pos.col] == '/') {
+ if (linep[pos.col + 1] == '*') {
+ comment_dir = FORWARD;
+ backwards = FALSE;
+ pos.col++;
+ } else if (pos.col > 0 && linep[pos.col - 1] == '*') {
+ comment_dir = BACKWARD;
+ backwards = TRUE;
+ pos.col--;
+ }
+ } else if (linep[pos.col] == '*') {
+ if (linep[pos.col + 1] == '/') {
+ comment_dir = BACKWARD;
+ backwards = TRUE;
+ } else if (pos.col > 0 && linep[pos.col - 1] == '/') {
+ comment_dir = FORWARD;
+ backwards = FALSE;
+ }
+ }
+ }
+
+ /*
+ * If we are not on a comment or the # at the start of a line, then
+ * look for brace anywhere on this line after the cursor.
+ */
+ if (!hash_dir && !comment_dir) {
+ /*
+ * Find the brace under or after the cursor.
+ * If beyond the end of the line, use the last character in
+ * the line.
+ */
+ if (linep[pos.col] == NUL && pos.col)
+ --pos.col;
+ for (;; ) {
+ initc = PTR2CHAR(linep + pos.col);
+ if (initc == NUL)
+ break;
+
+ find_mps_values(&initc, &findc, &backwards, FALSE);
+ if (findc)
+ break;
+ pos.col += MB_PTR2LEN(linep + pos.col);
+ }
+ if (!findc) {
+ /* no brace in the line, maybe use " #if" then */
+ if (!cpo_match && *skipwhite(linep) == '#')
+ hash_dir = 1;
+ else
+ return NULL;
+ } else if (!cpo_bsl) {
+ int col, bslcnt = 0;
+
+ /* Set "match_escaped" if there are an odd number of
+ * backslashes. */
+ for (col = pos.col; check_prevcol(linep, col, '\\', &col); )
+ bslcnt++;
+ match_escaped = (bslcnt & 1);
+ }
+ }
+ }
+ if (hash_dir) {
+ /*
+ * Look for matching #if, #else, #elif, or #endif
+ */
+ if (oap != NULL)
+ oap->motion_type = MLINE; /* Linewise for this case only */
+ if (initc != '#') {
+ ptr = skipwhite(skipwhite(linep) + 1);
+ if (STRNCMP(ptr, "if", 2) == 0 || STRNCMP(ptr, "el", 2) == 0)
+ hash_dir = 1;
+ else if (STRNCMP(ptr, "endif", 5) == 0)
+ hash_dir = -1;
+ else
+ return NULL;
+ }
+ pos.col = 0;
+ while (!got_int) {
+ if (hash_dir > 0) {
+ if (pos.lnum == curbuf->b_ml.ml_line_count)
+ break;
+ } else if (pos.lnum == 1)
+ break;
+ pos.lnum += hash_dir;
+ linep = ml_get(pos.lnum);
+ line_breakcheck(); /* check for CTRL-C typed */
+ ptr = skipwhite(linep);
+ if (*ptr != '#')
+ continue;
+ pos.col = (colnr_T) (ptr - linep);
+ ptr = skipwhite(ptr + 1);
+ if (hash_dir > 0) {
+ if (STRNCMP(ptr, "if", 2) == 0)
+ count++;
+ else if (STRNCMP(ptr, "el", 2) == 0) {
+ if (count == 0)
+ return &pos;
+ } else if (STRNCMP(ptr, "endif", 5) == 0) {
+ if (count == 0)
+ return &pos;
+ count--;
+ }
+ } else {
+ if (STRNCMP(ptr, "if", 2) == 0) {
+ if (count == 0)
+ return &pos;
+ count--;
+ } else if (initc == '#' && STRNCMP(ptr, "el", 2) == 0) {
+ if (count == 0)
+ return &pos;
+ } else if (STRNCMP(ptr, "endif", 5) == 0)
+ count++;
+ }
+ }
+ return 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;
+ clearpos(&match_pos);
+
+ /* backward search: Check if this line contains a single-line comment */
+ if ((backwards && comment_dir)
+ || lisp
+ )
+ comment_col = check_linecomment(linep);
+ 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
+ * inc() and dec() here, but that is much slower
+ */
+ if (backwards) {
+ /* char to match is inside of comment, don't search outside */
+ if (lispcomm && pos.col < (colnr_T)comment_col)
+ break;
+ if (pos.col == 0) { /* at start of line, go to prev. one */
+ if (pos.lnum == 1) /* start of file */
+ break;
+ --pos.lnum;
+
+ if (maxtravel > 0 && ++traveled > maxtravel)
+ break;
+
+ linep = ml_get(pos.lnum);
+ pos.col = (colnr_T)STRLEN(linep); /* pos.col on trailing NUL */
+ do_quotes = -1;
+ line_breakcheck();
+
+ /* Check if this line contains a single-line comment */
+ if (comment_dir
+ || lisp
+ )
+ comment_col = check_linecomment(linep);
+ /* skip comment */
+ if (lisp && comment_col != MAXCOL)
+ pos.col = comment_col;
+ } else {
+ --pos.col;
+ if (has_mbyte)
+ pos.col -= (*mb_head_off)(linep, linep + pos.col);
+ }
+ } else { /* forward search */
+ if (linep[pos.col] == NUL
+ /* at end of line, go to next one */
+ /* don't search for match in comment */
+ || (lisp && comment_col != MAXCOL
+ && pos.col == (colnr_T)comment_col)
+ ) {
+ if (pos.lnum == curbuf->b_ml.ml_line_count /* end of file */
+ /* line is exhausted and comment with it,
+ * don't search for match in code */
+ || lispcomm
+ )
+ break;
+ ++pos.lnum;
+
+ if (maxtravel && traveled++ > maxtravel)
+ break;
+
+ linep = ml_get(pos.lnum);
+ pos.col = 0;
+ do_quotes = -1;
+ line_breakcheck();
+ if (lisp) /* find comment pos in new line */
+ comment_col = check_linecomment(linep);
+ } else {
+ if (has_mbyte)
+ pos.col += (*mb_ptr2len)(linep + pos.col);
+ else
+ ++pos.col;
+ }
+ }
+
+ /*
+ * If FM_BLOCKSTOP given, stop at a '{' or '}' in column 0.
+ */
+ if (pos.col == 0 && (flags & FM_BLOCKSTOP) &&
+ (linep[0] == '{' || linep[0] == '}')) {
+ if (linep[0] == findc && count == 0) /* match! */
+ return &pos;
+ break; /* out of scope */
+ }
+
+ if (comment_dir) {
+ /* Note: comments do not nest, and we ignore quotes in them */
+ /* TODO: ignore comment brackets inside strings */
+ if (comment_dir == FORWARD) {
+ if (linep[pos.col] == '*' && linep[pos.col + 1] == '/') {
+ pos.col++;
+ return &pos;
+ }
+ } else { /* Searching backwards */
+ /*
+ * A comment may contain / * or / /, it may also start or end
+ * with / * /. Ignore a / * after / /.
+ */
+ if (pos.col == 0)
+ continue;
+ else if ( linep[pos.col - 1] == '/'
+ && linep[pos.col] == '*'
+ && (int)pos.col < comment_col) {
+ count++;
+ match_pos = pos;
+ match_pos.col--;
+ } else if (linep[pos.col - 1] == '*' && linep[pos.col] == '/') {
+ if (count > 0)
+ pos = match_pos;
+ else if (pos.col > 1 && linep[pos.col - 2] == '/'
+ && (int)pos.col <= comment_col)
+ pos.col -= 2;
+ else if (ignore_cend)
+ continue;
+ else
+ return NULL;
+ return &pos;
+ }
+ }
+ continue;
+ }
+
+ /*
+ * If smart matching ('cpoptions' does not contain '%'), braces inside
+ * of quotes are ignored, but only if there is an even number of
+ * quotes in the line.
+ */
+ if (cpo_match)
+ do_quotes = 0;
+ else if (do_quotes == -1) {
+ /*
+ * Count the number of quotes in the line, skipping \" and '"'.
+ * Watch out for "\\".
+ */
+ at_start = do_quotes;
+ for (ptr = linep; *ptr; ++ptr) {
+ if (ptr == linep + pos.col + backwards)
+ at_start = (do_quotes & 1);
+ if (*ptr == '"'
+ && (ptr == linep || ptr[-1] != '\'' || ptr[1] != '\''))
+ ++do_quotes;
+ if (*ptr == '\\' && ptr[1] != NUL)
+ ++ptr;
+ }
+ do_quotes &= 1; /* result is 1 with even number of quotes */
+
+ /*
+ * If we find an uneven count, check current line and previous
+ * one for a '\' at the end.
+ */
+ if (!do_quotes) {
+ 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 (pos.lnum > 1) {
+ ptr = ml_get(pos.lnum - 1);
+ if (*ptr && *(ptr + STRLEN(ptr) - 1) == '\\') {
+ do_quotes = 1;
+ if (start_in_quotes == MAYBE) {
+ inquote = at_start;
+ if (inquote)
+ start_in_quotes = TRUE;
+ } else if (!backwards)
+ inquote = TRUE;
+ }
+
+ /* ml_get() only keeps one line, need to get linep again */
+ linep = ml_get(pos.lnum);
+ }
+ }
+ }
+ if (start_in_quotes == MAYBE)
+ start_in_quotes = FALSE;
+
+ /*
+ * If 'smartmatch' is set:
+ * Things inside quotes are ignored by setting 'inquote'. If we
+ * find a quote without a preceding '\' invert 'inquote'. At the
+ * end of a line not ending in '\' we reset 'inquote'.
+ *
+ * In lines with an uneven number of quotes (without preceding '\')
+ * we do not know which part to ignore. Therefore we only set
+ * inquote if the number of quotes in a line is even, unless this
+ * line or the previous one ends in a '\'. Complicated, isn't it?
+ */
+ 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;
+ }
+ break;
+
+ case '"':
+ /* a quote that is preceded with an odd number of backslashes is
+ * ignored */
+ if (do_quotes) {
+ int col;
+
+ for (col = pos.col - 1; col >= 0; --col)
+ if (linep[col] != '\\')
+ break;
+ if ((((int)pos.col - 1 - col) & 1) == 0) {
+ inquote = !inquote;
+ start_in_quotes = FALSE;
+ }
+ }
+ break;
+
+ /*
+ * If smart matching ('cpoptions' does not contain '%'):
+ * Skip things in single quotes: 'x' or '\x'. Be careful for single
+ * single quotes, eg jon's. Things like '\233' or '\x3f' are not
+ * skipped, there is never a brace in them.
+ * Ignore this when finding matches for `'.
+ */
+ case '\'':
+ if (!cpo_match && initc != '\'' && findc != '\'') {
+ if (backwards) {
+ if (pos.col > 1) {
+ if (linep[pos.col - 2] == '\'') {
+ pos.col -= 2;
+ break;
+ } else if (linep[pos.col - 2] == '\\' &&
+ pos.col > 2 && linep[pos.col - 3] == '\'') {
+ pos.col -= 3;
+ break;
+ }
+ }
+ } else if (linep[pos.col + 1]) { /* forward search */
+ if (linep[pos.col + 1] == '\\' &&
+ linep[pos.col + 2] && linep[pos.col + 3] == '\'') {
+ pos.col += 3;
+ break;
+ } else if (linep[pos.col + 2] == '\'') {
+ pos.col += 2;
+ break;
+ }
+ }
+ }
+ /* FALLTHROUGH */
+
+ default:
+ /*
+ * For Lisp skip over backslashed (), {} and [].
+ * (actually, we skip #\( et al)
+ */
+ if (curbuf->b_p_lisp
+ && vim_strchr((char_u *)"(){}[]", c) != NULL
+ && pos.col > 1
+ && check_prevcol(linep, pos.col, '\\', NULL)
+ && check_prevcol(linep, pos.col - 1, '#', NULL))
+ break;
+
+ /* Check for match outside of quotes, and inside of
+ * quotes when the start is also inside of quotes. */
+ if ((!inquote || start_in_quotes == TRUE)
+ && (c == initc || c == findc)) {
+ int col, bslcnt = 0;
+
+ if (!cpo_bsl) {
+ for (col = pos.col; check_prevcol(linep, col, '\\', &col); )
+ bslcnt++;
+ }
+ /* Only accept a match when 'M' is in 'cpo' or when escaping
+ * is what we expect. */
+ if (cpo_bsl || (bslcnt & 1) == match_escaped) {
+ if (c == initc)
+ count++;
+ else {
+ if (count == 0)
+ return &pos;
+ count--;
+ }
+ }
+ }
+ }
+ }
+
+ if (comment_dir == BACKWARD && count > 0) {
+ pos = match_pos;
+ return &pos;
+ }
+ return (pos_T *)NULL; /* never found it */
+}
+
+/*
+ * Check if line[] contains a / / comment.
+ * Return MAXCOL if not, otherwise return the column.
+ * TODO: skip strings.
+ */
+static int check_linecomment(line)
+char_u *line;
+{
+ char_u *p;
+
+ p = line;
+ /* skip Lispish one-line comments */
+ if (curbuf->b_p_lisp) {
+ if (vim_strchr(p, ';') != NULL) { /* there may be comments */
+ int in_str = FALSE; /* inside of string */
+
+ p = line; /* scan from start */
+ while ((p = vim_strpbrk(p, (char_u *)"\";")) != NULL) {
+ if (*p == '"') {
+ if (in_str) {
+ if (*(p - 1) != '\\') /* skip escaped quote */
+ in_str = FALSE;
+ } else if (p == line || ((p - line) >= 2
+ /* skip #\" form */
+ && *(p - 1) != '\\' && *(p - 2) != '#'))
+ in_str = TRUE;
+ } else if (!in_str && ((p - line) < 2
+ || (*(p - 1) != '\\' && *(p - 2) != '#')))
+ break; /* found! */
+ ++p;
+ }
+ } else
+ p = NULL;
+ } else
+ while ((p = vim_strchr(p, '/')) != NULL) {
+ /* accept a double /, unless it's preceded with * and followed by *,
+ * because * / / * is an end and start of a C comment */
+ if (p[1] == '/' && (p == line || p[-1] != '*' || p[2] != '*'))
+ break;
+ ++p;
+ }
+
+ if (p == NULL)
+ return MAXCOL;
+ return (int)(p - line);
+}
+
+/*
+ * Move cursor briefly to character matching the one under the cursor.
+ * Used for Insert mode and "r" command.
+ * Show the match only if it is visible on the screen.
+ * If there isn't a match, then beep.
+ */
+void showmatch(c)
+int c; /* char to show match for */
+{
+ pos_T *lpos, save_cursor;
+ pos_T mpos;
+ colnr_T vcol;
+ long save_so;
+ long save_siso;
+#ifdef CURSOR_SHAPE
+ int save_state;
+#endif
+ colnr_T save_dollar_vcol;
+ char_u *p;
+
+ /*
+ * Only show match for chars in the 'matchpairs' option.
+ */
+ /* 'matchpairs' is "x:y,x:y" */
+ for (p = curbuf->b_p_mps; *p != NUL; ++p) {
+ if (PTR2CHAR(p) == c && (curwin->w_p_rl ^ p_ri))
+ break;
+ p += MB_PTR2LEN(p) + 1;
+ if (PTR2CHAR(p) == c
+ && !(curwin->w_p_rl ^ p_ri)
+ )
+ break;
+ p += MB_PTR2LEN(p);
+ if (*p == NUL)
+ return;
+ }
+
+ if ((lpos = findmatch(NULL, NUL)) == NULL) /* no match, so beep */
+ vim_beep();
+ else if (lpos->lnum >= curwin->w_topline && lpos->lnum < curwin->w_botline) {
+ if (!curwin->w_p_wrap)
+ getvcol(curwin, lpos, NULL, &vcol, NULL);
+ if (curwin->w_p_wrap || (vcol >= curwin->w_leftcol
+ && vcol < curwin->w_leftcol + W_WIDTH(curwin))) {
+ mpos = *lpos; /* save the pos, update_screen() may change it */
+ save_cursor = curwin->w_cursor;
+ save_so = p_so;
+ save_siso = p_siso;
+ /* Handle "$" in 'cpo': If the ')' is typed on top of the "$",
+ * stop displaying the "$". */
+ if (dollar_vcol >= 0 && dollar_vcol == curwin->w_virtcol)
+ dollar_vcol = -1;
+ ++curwin->w_virtcol; /* do display ')' just before "$" */
+ update_screen(VALID); /* show the new char first */
+
+ save_dollar_vcol = dollar_vcol;
+#ifdef CURSOR_SHAPE
+ save_state = State;
+ State = SHOWMATCH;
+ ui_cursor_shape(); /* may show different cursor shape */
+#endif
+ curwin->w_cursor = mpos; /* move to matching char */
+ p_so = 0; /* don't use 'scrolloff' here */
+ p_siso = 0; /* don't use 'sidescrolloff' here */
+ showruler(FALSE);
+ setcursor();
+ cursor_on(); /* make sure that the cursor is shown */
+ out_flush();
+ /* Restore dollar_vcol(), because setcursor() may call curs_rows()
+ * which resets it if the matching position is in a previous line
+ * and has a higher column number. */
+ dollar_vcol = save_dollar_vcol;
+
+ /*
+ * brief pause, unless 'm' is present in 'cpo' and a character is
+ * available.
+ */
+ if (vim_strchr(p_cpo, CPO_SHOWMATCH) != NULL)
+ ui_delay(p_mat * 100L, TRUE);
+ else if (!char_avail())
+ ui_delay(p_mat * 100L, FALSE);
+ curwin->w_cursor = save_cursor; /* restore cursor position */
+ p_so = save_so;
+ p_siso = save_siso;
+#ifdef CURSOR_SHAPE
+ State = save_state;
+ ui_cursor_shape(); /* may show different cursor shape */
+#endif
+ }
+ }
+}
+
+/*
+ * 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(dir, count)
+int dir;
+long count;
+{
+ pos_T pos, tpos;
+ int c;
+ int (*func)__ARGS((pos_T *));
+ int startlnum;
+ int noskip = FALSE; /* do not skip blanks */
+ int cpo_J;
+ int found_dot;
+
+ pos = curwin->w_cursor;
+ if (dir == FORWARD)
+ func = incl;
+ else
+ func = decl;
+
+ while (count--) {
+ /*
+ * if on an empty line, skip upto a non-empty line
+ */
+ if (gchar_pos(&pos) == NUL) {
+ do
+ if ((*func)(&pos) == -1)
+ break;
+ while (gchar_pos(&pos) == NUL);
+ if (dir == FORWARD)
+ goto found;
+ }
+ /*
+ * if on the start of a paragraph or a section and searching forward,
+ * go to the next line
+ */
+ else if (dir == FORWARD && pos.col == 0 &&
+ startPS(pos.lnum, NUL, FALSE)) {
+ if (pos.lnum == curbuf->b_ml.ml_line_count)
+ return FAIL;
+ ++pos.lnum;
+ goto found;
+ } else if (dir == BACKWARD)
+ 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;
+ }
+ if (decl(&pos) == -1)
+ break;
+ /* when going forward: Stop in front of empty line */
+ if (lineempty(pos.lnum) && dir == FORWARD) {
+ incl(&pos);
+ goto found;
+ }
+ }
+
+ /* remember the line where the search started */
+ startlnum = pos.lnum;
+ cpo_J = vim_strchr(p_cpo, CPO_ENDOFSENT) != NULL;
+
+ for (;; ) { /* find end of sentence */
+ c = gchar_pos(&pos);
+ if (c == NUL || (pos.col == 0 && startPS(pos.lnum, NUL, FALSE))) {
+ if (dir == BACKWARD && pos.lnum != startlnum)
+ ++pos.lnum;
+ break;
+ }
+ if (c == '.' || c == '!' || c == '?') {
+ tpos = pos;
+ do
+ if ((c = inc(&tpos)) == -1)
+ break;
+ while (vim_strchr((char_u *)")]\"'", c = gchar_pos(&tpos))
+ != NULL);
+ if (c == -1 || (!cpo_J && (c == ' ' || c == '\t')) || c == NUL
+ || (cpo_J && (c == ' ' && inc(&tpos) >= 0
+ && gchar_pos(&tpos) == ' '))) {
+ pos = tpos;
+ if (gchar_pos(&pos) == NUL) /* skip NUL at EOL */
+ inc(&pos);
+ break;
+ }
+ }
+ if ((*func)(&pos) == -1) {
+ if (count)
+ return FAIL;
+ noskip = TRUE;
+ break;
+ }
+ }
+found:
+ /* skip white space */
+ while (!noskip && ((c = gchar_pos(&pos)) == ' ' || c == '\t'))
+ if (incl(&pos) == -1)
+ break;
+ }
+
+ setpcmark();
+ curwin->w_cursor = pos;
+ return OK;
+}
+
+/*
+ * Find the next paragraph or section in direction 'dir'.
+ * Paragraphs are currently supposed to be separated by empty lines.
+ * If 'what' is NUL we go to the next paragraph.
+ * If 'what' is '{' or '}' we go to the next section.
+ * If 'both' is TRUE also stop at '}'.
+ * Return TRUE if the next paragraph or section was found.
+ */
+int findpar(pincl, dir, count, what, both)
+int *pincl; /* Return: TRUE if last char is to be included */
+int dir;
+long count;
+int what;
+int both;
+{
+ linenr_T curr;
+ int did_skip; /* TRUE after separating lines have been skipped */
+ int first; /* TRUE on first line */
+ int posix = (vim_strchr(p_cpo, CPO_PARA) != NULL);
+ linenr_T fold_first; /* first line of a closed fold */
+ linenr_T fold_last; /* last line of a closed fold */
+ int fold_skipped; /* TRUE if a closed fold was skipped this
+ iteration */
+
+ curr = curwin->w_cursor.lnum;
+
+ while (count--) {
+ did_skip = FALSE;
+ for (first = TRUE;; first = FALSE) {
+ if (*ml_get(curr) != NUL)
+ did_skip = TRUE;
+
+ /* skip folded lines */
+ fold_skipped = FALSE;
+ if (first && hasFolding(curr, &fold_first, &fold_last)) {
+ curr = ((dir > 0) ? fold_last : fold_first) + dir;
+ fold_skipped = TRUE;
+ }
+
+ /* POSIX has it's own ideas of what a paragraph boundary is and it
+ * doesn't match historical Vi: It also stops at a "{" in the
+ * first column and at an empty line. */
+ if (!first && did_skip && (startPS(curr, what, both)
+ || (posix && what == NUL && *ml_get(curr) ==
+ '{')))
+ break;
+
+ if (fold_skipped)
+ curr -= dir;
+ if ((curr += dir) < 1 || curr > curbuf->b_ml.ml_line_count) {
+ if (count)
+ return FALSE;
+ curr -= dir;
+ break;
+ }
+ }
+ }
+ setpcmark();
+ if (both && *ml_get(curr) == '}') /* include line with '}' */
+ ++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;
+ *pincl = TRUE;
+ }
+ } else
+ curwin->w_cursor.col = 0;
+ return TRUE;
+}
+
+/*
+ * check if the string 's' is a nroff macro that is in option 'opt'
+ */
+static int inmacro(opt, s)
+char_u *opt;
+char_u *s;
+{
+ char_u *macro;
+
+ for (macro = opt; macro[0]; ++macro) {
+ /* Accept two characters in the option being equal to two characters
+ * in the line. A space in the option matches with a space in the
+ * line or the line having ended. */
+ if ( (macro[0] == s[0]
+ || (macro[0] == ' '
+ && (s[0] == NUL || s[0] == ' ')))
+ && (macro[1] == s[1]
+ || ((macro[1] == NUL || macro[1] == ' ')
+ && (s[0] == NUL || s[1] == NUL || s[1] == ' '))))
+ break;
+ ++macro;
+ if (macro[0] == NUL)
+ break;
+ }
+ return macro[0] != NUL;
+}
+
+/*
+ * startPS: return TRUE if line 'lnum' is the start of a section or paragraph.
+ * If 'para' is '{' or '}' only check for sections.
+ * If 'both' is TRUE also stop at '}'
+ */
+int startPS(lnum, para, both)
+linenr_T lnum;
+int para;
+int both;
+{
+ char_u *s;
+
+ s = ml_get(lnum);
+ if (*s == para || *s == '\f' || (both && *s == '}'))
+ return TRUE;
+ if (*s == '.' && (inmacro(p_sections, s + 1) ||
+ (!para && inmacro(p_para, s + 1))))
+ return TRUE;
+ return FALSE;
+}
+
+/*
+ * The following routines do the word searches performed by the 'w', 'W',
+ * 'b', 'B', 'e', and 'E' commands.
+ */
+
+/*
+ * To perform these searches, characters are placed into one of three
+ * classes, and transitions between classes determine word boundaries.
+ *
+ * The classes are:
+ *
+ * 0 - white space
+ * 1 - punctuation
+ * 2 or higher - keyword characters (letters, digits and underscore)
+ */
+
+static int cls_bigword; /* TRUE for "W", "B" or "E" */
+
+/*
+ * cls() - returns the class of character at curwin->w_cursor
+ *
+ * If a 'W', 'B', or 'E' motion is being done (cls_bigword == TRUE), chars
+ * from class 2 and higher are reported as class 1 since only white space
+ * boundaries are of interest.
+ */
+static int cls() {
+ int c;
+
+ c = gchar_cursor();
+ 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 cls_bigword is TRUE, report all non-blanks as class 1. */
+ if (cls_bigword)
+ return 1;
+
+ if (vim_iswordc(c))
+ return 2;
+ return 1;
+}
+
+/*
+ * fwd_word(count, type, eol) - move forward one word
+ *
+ * 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(count, bigword, eol)
+long count;
+int bigword; /* "W", "E" or "B" */
+int eol;
+{
+ int sclass; /* starting class */
+ int i;
+ int last_line;
+
+ curwin->w_cursor.coladd = 0;
+ cls_bigword = bigword;
+ while (--count >= 0) {
+ /* When inside a range of folded lines, move to the last char of the
+ * last line. */
+ if (hasFolding(curwin->w_cursor.lnum, NULL, &curwin->w_cursor.lnum))
+ coladvance((colnr_T)MAXCOL);
+ sclass = cls();
+
+ /*
+ * We always move at least one character, unless on the last
+ * character in the buffer.
+ */
+ last_line = (curwin->w_cursor.lnum == curbuf->b_ml.ml_line_count);
+ i = inc_cursor();
+ if (i == -1 || (i >= 1 && last_line)) /* started at last char in file */
+ return FAIL;
+ if (i >= 1 && eol && count == 0) /* started at last char in line */
+ return OK;
+
+ /*
+ * Go one char past end of current word (if any)
+ */
+ if (sclass != 0)
+ while (cls() == sclass) {
+ i = inc_cursor();
+ if (i == -1 || (i >= 1 && eol && count == 0))
+ return OK;
+ }
+
+ /*
+ * go to next non-white
+ */
+ while (cls() == 0) {
+ /*
+ * We'll stop if we land on a blank line
+ */
+ if (curwin->w_cursor.col == 0 && *ml_get_curline() == NUL)
+ break;
+
+ i = inc_cursor();
+ if (i == -1 || (i >= 1 && eol && count == 0))
+ return OK;
+ }
+ }
+ return OK;
+}
+
+/*
+ * bck_word() - move backward 'count' words
+ *
+ * If stop is TRUE and we are already on the start of a word, move one less.
+ *
+ * Returns FAIL if top of the file was reached.
+ */
+int bck_word(count, bigword, stop)
+long count;
+int bigword;
+int stop;
+{
+ int sclass; /* starting class */
+
+ curwin->w_cursor.coladd = 0;
+ cls_bigword = bigword;
+ while (--count >= 0) {
+ /* When inside a range of folded lines, move to the first char of the
+ * first line. */
+ if (hasFolding(curwin->w_cursor.lnum, &curwin->w_cursor.lnum, NULL))
+ curwin->w_cursor.col = 0;
+ sclass = cls();
+ if (dec_cursor() == -1) /* started at start of file */
+ return FAIL;
+
+ if (!stop || sclass == cls() || sclass == 0) {
+ /*
+ * Skip white space before the word.
+ * Stop on an empty line.
+ */
+ while (cls() == 0) {
+ if (curwin->w_cursor.col == 0
+ && lineempty(curwin->w_cursor.lnum))
+ goto finished;
+ if (dec_cursor() == -1) /* hit start of file, stop here */
+ return OK;
+ }
+
+ /*
+ * Move backward to start of this word.
+ */
+ if (skip_chars(cls(), BACKWARD))
+ return OK;
+ }
+
+ inc_cursor(); /* overshot - forward one */
+finished:
+ stop = FALSE;
+ }
+ return OK;
+}
+
+/*
+ * end_word() - move to the end of the word
+ *
+ * There is an apparent bug in the 'e' motion of the real vi. At least on the
+ * System V Release 3 version for the 80386. Unlike 'b' and 'w', the 'e'
+ * motion crosses blank lines. When the real vi crosses a blank line in an
+ * 'e' motion, the cursor is placed on the FIRST character of the next
+ * non-blank line. The 'E' command, however, works correctly. Since this
+ * appears to be a bug, I have not duplicated it here.
+ *
+ * Returns FAIL if end of the file was reached.
+ *
+ * If stop is TRUE and we are already on the end of a word, move one less.
+ * If empty is TRUE stop on an empty line.
+ */
+int end_word(count, bigword, stop, empty)
+long count;
+int bigword;
+int stop;
+int empty;
+{
+ int sclass; /* starting class */
+
+ curwin->w_cursor.coladd = 0;
+ cls_bigword = bigword;
+ while (--count >= 0) {
+ /* When inside a range of folded lines, move to the last char of the
+ * last line. */
+ if (hasFolding(curwin->w_cursor.lnum, NULL, &curwin->w_cursor.lnum))
+ coladvance((colnr_T)MAXCOL);
+ sclass = cls();
+ if (inc_cursor() == -1)
+ return FAIL;
+
+ /*
+ * If we're in the middle of a word, we just have to move to the end
+ * of it.
+ */
+ if (cls() == sclass && sclass != 0) {
+ /*
+ * Move forward to end of the current word
+ */
+ if (skip_chars(sclass, FORWARD))
+ return FAIL;
+ } else if (!stop || sclass == 0) {
+ /*
+ * We were at the end of a word. Go to the end of the next word.
+ * First skip white space, if 'empty' is TRUE, stop at empty line.
+ */
+ while (cls() == 0) {
+ if (empty && curwin->w_cursor.col == 0
+ && lineempty(curwin->w_cursor.lnum))
+ goto finished;
+ if (inc_cursor() == -1) /* hit end of file, stop here */
+ return FAIL;
+ }
+
+ /*
+ * Move forward to the end of this word.
+ */
+ if (skip_chars(cls(), FORWARD))
+ return FAIL;
+ }
+ dec_cursor(); /* overshot - one char backward */
+finished:
+ stop = FALSE; /* we move only one word less */
+ }
+ return OK;
+}
+
+/*
+ * Move back to the end of the word.
+ *
+ * Returns FAIL if start of the file was reached.
+ */
+int bckend_word(count, bigword, eol)
+long count;
+int bigword; /* TRUE for "B" */
+int eol; /* TRUE: stop at end of line. */
+{
+ int sclass; /* starting class */
+ int i;
+
+ curwin->w_cursor.coladd = 0;
+ cls_bigword = bigword;
+ while (--count >= 0) {
+ sclass = cls();
+ if ((i = dec_cursor()) == -1)
+ return FAIL;
+ if (eol && i == 1)
+ return OK;
+
+ /*
+ * Move backward to before the start of this word.
+ */
+ if (sclass != 0) {
+ while (cls() == sclass)
+ if ((i = dec_cursor()) == -1 || (eol && i == 1))
+ return OK;
+ }
+
+ /*
+ * Move backward to end of the previous word
+ */
+ while (cls() == 0) {
+ if (curwin->w_cursor.col == 0 && lineempty(curwin->w_cursor.lnum))
+ break;
+ if ((i = dec_cursor()) == -1 || (eol && i == 1))
+ return OK;
+ }
+ }
+ return OK;
+}
+
+/*
+ * Skip a row of characters of the same class.
+ * Return TRUE when end-of-file reached, FALSE otherwise.
+ */
+static int skip_chars(cclass, dir)
+int cclass;
+int dir;
+{
+ while (cls() == cclass)
+ if ((dir == FORWARD ? inc_cursor() : dec_cursor()) == -1)
+ return TRUE;
+ return FALSE;
+}
+
+/*
+ * Go back to the start of the word or the start of white space
+ */
+static void back_in_line() {
+ int sclass; /* starting class */
+
+ sclass = cls();
+ for (;; ) {
+ if (curwin->w_cursor.col == 0) /* stop at start of line */
+ break;
+ dec_cursor();
+ if (cls() != sclass) { /* stop at start of word */
+ inc_cursor();
+ break;
+ }
+ }
+}
+
+static void find_first_blank(posp)
+pos_T *posp;
+{
+ int c;
+
+ while (decl(posp) != -1) {
+ c = gchar_pos(posp);
+ if (!vim_iswhite(c)) {
+ incl(posp);
+ break;
+ }
+ }
+}
+
+/*
+ * Skip count/2 sentences and count/2 separating white spaces.
+ */
+static void findsent_forward(count, at_start_sent)
+long count;
+int at_start_sent; /* cursor is at start of sentence */
+{
+ while (count--) {
+ findsent(FORWARD, 1L);
+ if (at_start_sent)
+ find_first_blank(&curwin->w_cursor);
+ if (count == 0 || at_start_sent)
+ decl(&curwin->w_cursor);
+ at_start_sent = !at_start_sent;
+ }
+}
+
+/*
+ * Find word under cursor, cursor at end.
+ * Used while an operator is pending, and in Visual mode.
+ */
+int current_word(oap, count, include, bigword)
+oparg_T *oap;
+long count;
+int include; /* TRUE: include word and white space */
+int bigword; /* FALSE == word, TRUE == WORD */
+{
+ pos_T start_pos;
+ pos_T pos;
+ int inclusive = TRUE;
+ int include_white = FALSE;
+
+ cls_bigword = bigword;
+ clearpos(&start_pos);
+
+ /* Correct cursor when 'selection' is exclusive */
+ if (VIsual_active && *p_sel == 'e' && lt(VIsual, curwin->w_cursor))
+ dec_cursor();
+
+ /*
+ * When Visual mode is not active, or when the VIsual area is only one
+ * character, select the word and/or white space under the cursor.
+ */
+ if (!VIsual_active || equalpos(curwin->w_cursor, VIsual)) {
+ /*
+ * Go to start of current word or white space.
+ */
+ back_in_line();
+ start_pos = curwin->w_cursor;
+
+ /*
+ * If the start is on white space, and white space should be included
+ * (" word"), or start is not on white space, and white space should
+ * not be included ("word"), find end of word.
+ */
+ if ((cls() == 0) == include) {
+ if (end_word(1L, bigword, TRUE, TRUE) == FAIL)
+ return FAIL;
+ } else {
+ /*
+ * If the start is not on white space, and white space should be
+ * included ("word "), or start is on white space and white
+ * space should not be included (" "), find start of word.
+ * If we end up in the first column of the next line (single char
+ * word) back up to end of the line.
+ */
+ fwd_word(1L, bigword, TRUE);
+ if (curwin->w_cursor.col == 0)
+ decl(&curwin->w_cursor);
+ else
+ oneleft();
+
+ if (include)
+ include_white = TRUE;
+ }
+
+ if (VIsual_active) {
+ /* should do something when inclusive == FALSE ! */
+ VIsual = start_pos;
+ redraw_curbuf_later(INVERTED); /* update the inversion */
+ } else {
+ oap->start = start_pos;
+ oap->motion_type = MCHAR;
+ }
+ --count;
+ }
+
+ /*
+ * When count is still > 0, extend with more objects.
+ */
+ while (count > 0) {
+ inclusive = TRUE;
+ if (VIsual_active && lt(curwin->w_cursor, VIsual)) {
+ /*
+ * In Visual mode, with cursor at start: move cursor back.
+ */
+ if (decl(&curwin->w_cursor) == -1)
+ return FAIL;
+ if (include != (cls() != 0)) {
+ if (bck_word(1L, bigword, TRUE) == FAIL)
+ return FAIL;
+ } else {
+ if (bckend_word(1L, bigword, TRUE) == FAIL)
+ return FAIL;
+ (void)incl(&curwin->w_cursor);
+ }
+ } else {
+ /*
+ * Move cursor forward one word and/or white area.
+ */
+ if (incl(&curwin->w_cursor) == -1)
+ return FAIL;
+ if (include != (cls() == 0)) {
+ if (fwd_word(1L, bigword, TRUE) == FAIL && count > 1)
+ return FAIL;
+ /*
+ * If end is just past a new-line, we don't want to include
+ * the first character on the line.
+ * Put cursor on last char of white.
+ */
+ if (oneleft() == FAIL)
+ inclusive = FALSE;
+ } else {
+ if (end_word(1L, bigword, TRUE, TRUE) == FAIL)
+ return FAIL;
+ }
+ }
+ --count;
+ }
+
+ if (include_white && (cls() != 0
+ || (curwin->w_cursor.col == 0 && !inclusive))) {
+ /*
+ * If we don't include white space at the end, move the start
+ * to include some white space there. This makes "daw" work
+ * better on the last word in a sentence (and "2daw" on last-but-one
+ * word). Also when "2daw" deletes "word." at the end of the line
+ * (cursor is at start of next line).
+ * But don't delete white space at start of line (indent).
+ */
+ pos = curwin->w_cursor; /* save cursor position */
+ curwin->w_cursor = start_pos;
+ if (oneleft() == OK) {
+ back_in_line();
+ if (cls() == 0 && curwin->w_cursor.col > 0) {
+ if (VIsual_active)
+ VIsual = curwin->w_cursor;
+ else
+ oap->start = curwin->w_cursor;
+ }
+ }
+ curwin->w_cursor = pos; /* put cursor back at end */
+ }
+
+ if (VIsual_active) {
+ if (*p_sel == 'e' && inclusive && ltoreq(VIsual, curwin->w_cursor))
+ inc_cursor();
+ if (VIsual_mode == 'V') {
+ VIsual_mode = 'v';
+ redraw_cmdline = TRUE; /* show mode later */
+ }
+ } else
+ oap->inclusive = inclusive;
+
+ return OK;
+}
+
+/*
+ * Find sentence(s) under the cursor, cursor at end.
+ * When Visual active, extend it by one or more sentences.
+ */
+int current_sent(oap, count, include)
+oparg_T *oap;
+long count;
+int include;
+{
+ pos_T start_pos;
+ pos_T pos;
+ int start_blank;
+ int c;
+ int at_start_sent;
+ long ncount;
+
+ start_pos = curwin->w_cursor;
+ pos = start_pos;
+ findsent(FORWARD, 1L); /* Find start of next sentence. */
+
+ /*
+ * When the Visual area is bigger than one character: Extend it.
+ */
+ if (VIsual_active && !equalpos(start_pos, VIsual)) {
+extend:
+ if (lt(start_pos, VIsual)) {
+ /*
+ * Cursor at start of Visual area.
+ * Find out where we are:
+ * - in the white space before a sentence
+ * - in a sentence or just after it
+ * - at the start of a sentence
+ */
+ at_start_sent = TRUE;
+ decl(&pos);
+ while (lt(pos, curwin->w_cursor)) {
+ c = gchar_pos(&pos);
+ if (!vim_iswhite(c)) {
+ at_start_sent = FALSE;
+ break;
+ }
+ incl(&pos);
+ }
+ if (!at_start_sent) {
+ findsent(BACKWARD, 1L);
+ if (equalpos(curwin->w_cursor, start_pos))
+ at_start_sent = TRUE; /* exactly at start of sentence */
+ else
+ /* inside a sentence, go to its end (start of next) */
+ findsent(FORWARD, 1L);
+ }
+ if (include) /* "as" gets twice as much as "is" */
+ count *= 2;
+ while (count--) {
+ if (at_start_sent)
+ find_first_blank(&curwin->w_cursor);
+ c = gchar_cursor();
+ if (!at_start_sent || (!include && !vim_iswhite(c)))
+ findsent(BACKWARD, 1L);
+ at_start_sent = !at_start_sent;
+ }
+ } else {
+ /*
+ * Cursor at end of Visual area.
+ * Find out where we are:
+ * - just before a sentence
+ * - just before or in the white space before a sentence
+ * - in a sentence
+ */
+ incl(&pos);
+ at_start_sent = TRUE;
+ if (!equalpos(pos, curwin->w_cursor)) { /* not just before a sentence */
+ at_start_sent = FALSE;
+ while (lt(pos, curwin->w_cursor)) {
+ c = gchar_pos(&pos);
+ if (!vim_iswhite(c)) {
+ at_start_sent = TRUE;
+ break;
+ }
+ incl(&pos);
+ }
+ if (at_start_sent) /* in the sentence */
+ findsent(BACKWARD, 1L);
+ else /* in/before white before a sentence */
+ curwin->w_cursor = start_pos;
+ }
+
+ if (include) /* "as" gets twice as much as "is" */
+ count *= 2;
+ findsent_forward(count, at_start_sent);
+ if (*p_sel == 'e')
+ ++curwin->w_cursor.col;
+ }
+ return OK;
+ }
+
+ /*
+ * If the cursor started on a blank, check if it is just before the start
+ * of the next sentence.
+ */
+ while (c = gchar_pos(&pos), vim_iswhite(c)) /* vim_iswhite() is a macro */
+ incl(&pos);
+ if (equalpos(pos, curwin->w_cursor)) {
+ start_blank = TRUE;
+ find_first_blank(&start_pos); /* go back to first blank */
+ } else {
+ start_blank = FALSE;
+ findsent(BACKWARD, 1L);
+ start_pos = curwin->w_cursor;
+ }
+ if (include)
+ ncount = count * 2;
+ else {
+ ncount = count;
+ if (start_blank)
+ --ncount;
+ }
+ if (ncount > 0)
+ findsent_forward(ncount, TRUE);
+ else
+ decl(&curwin->w_cursor);
+
+ if (include) {
+ /*
+ * If the blank in front of the sentence is included, exclude the
+ * blanks at the end of the sentence, go back to the first blank.
+ * If there are no trailing blanks, try to include leading blanks.
+ */
+ if (start_blank) {
+ find_first_blank(&curwin->w_cursor);
+ c = gchar_pos(&curwin->w_cursor); /* vim_iswhite() is a macro */
+ if (vim_iswhite(c))
+ decl(&curwin->w_cursor);
+ } else if (c = gchar_cursor(), !vim_iswhite(c))
+ find_first_blank(&start_pos);
+ }
+
+ if (VIsual_active) {
+ /* Avoid getting stuck with "is" on a single space before a sentence. */
+ if (equalpos(start_pos, curwin->w_cursor))
+ goto extend;
+ if (*p_sel == 'e')
+ ++curwin->w_cursor.col;
+ VIsual = start_pos;
+ VIsual_mode = 'v';
+ redraw_curbuf_later(INVERTED); /* update the inversion */
+ } else {
+ /* include a newline after the sentence, if there is one */
+ if (incl(&curwin->w_cursor) == -1)
+ oap->inclusive = TRUE;
+ else
+ oap->inclusive = FALSE;
+ oap->start = start_pos;
+ oap->motion_type = MCHAR;
+ }
+ return OK;
+}
+
+/*
+ * Find block under the cursor, cursor at end.
+ * "what" and "other" are two matching parenthesis/brace/etc.
+ */
+int current_block(oap, count, include, what, other)
+oparg_T *oap;
+long count;
+int include; /* TRUE == include white space */
+int what; /* '(', '{', etc. */
+int other; /* ')', '}', etc. */
+{
+ pos_T old_pos;
+ pos_T *pos = NULL;
+ pos_T start_pos;
+ pos_T *end_pos;
+ pos_T old_start, old_end;
+ char_u *save_cpo;
+ int sol = FALSE; /* '{' at start of line */
+
+ old_pos = curwin->w_cursor;
+ old_end = curwin->w_cursor; /* remember where we started */
+ old_start = old_end;
+
+ /*
+ * If we start on '(', '{', ')', '}', etc., use the whole block inclusive.
+ */
+ if (!VIsual_active || equalpos(VIsual, curwin->w_cursor)) {
+ setpcmark();
+ if (what == '{') /* ignore indent */
+ while (inindent(1))
+ if (inc_cursor() != 0)
+ break;
+ if (gchar_cursor() == what)
+ /* cursor on '(' or '{', move cursor just after it */
+ ++curwin->w_cursor.col;
+ } else if (lt(VIsual, curwin->w_cursor)) {
+ old_start = VIsual;
+ curwin->w_cursor = VIsual; /* cursor at low end of Visual */
+ } else
+ old_end = VIsual;
+
+ /*
+ * Search backwards for unclosed '(', '{', etc..
+ * Put this position in start_pos.
+ * Ignore quotes here.
+ */
+ save_cpo = p_cpo;
+ p_cpo = (char_u *)"%";
+ while (count-- > 0) {
+ if ((pos = findmatch(NULL, what)) == NULL)
+ break;
+ curwin->w_cursor = *pos;
+ start_pos = *pos; /* the findmatch for end_pos will overwrite *pos */
+ }
+ p_cpo = save_cpo;
+
+ /*
+ * Search for matching ')', '}', etc.
+ * Put this position in curwin->w_cursor.
+ */
+ if (pos == NULL || (end_pos = findmatch(NULL, other)) == NULL) {
+ curwin->w_cursor = old_pos;
+ return FAIL;
+ }
+ curwin->w_cursor = *end_pos;
+
+ /*
+ * Try to exclude the '(', '{', ')', '}', etc. when "include" is FALSE.
+ * If the ending '}' is only preceded by indent, skip that indent.
+ * But only if the resulting area is not smaller than what we started with.
+ */
+ while (!include) {
+ incl(&start_pos);
+ sol = (curwin->w_cursor.col == 0);
+ decl(&curwin->w_cursor);
+ if (what == '{')
+ while (inindent(1)) {
+ sol = TRUE;
+ if (decl(&curwin->w_cursor) != 0)
+ break;
+ }
+ /*
+ * In Visual mode, when the resulting area is not bigger than what we
+ * started with, extend it to the next block, and then exclude again.
+ */
+ if (!lt(start_pos, old_start) && !lt(old_end, curwin->w_cursor)
+ && VIsual_active) {
+ curwin->w_cursor = old_start;
+ decl(&curwin->w_cursor);
+ if ((pos = findmatch(NULL, what)) == NULL) {
+ curwin->w_cursor = old_pos;
+ return FAIL;
+ }
+ start_pos = *pos;
+ curwin->w_cursor = *pos;
+ if ((end_pos = findmatch(NULL, other)) == NULL) {
+ curwin->w_cursor = old_pos;
+ return FAIL;
+ }
+ curwin->w_cursor = *end_pos;
+ } else
+ break;
+ }
+
+ if (VIsual_active) {
+ if (*p_sel == 'e')
+ ++curwin->w_cursor.col;
+ if (sol && gchar_cursor() != NUL)
+ inc(&curwin->w_cursor); /* include the line break */
+ VIsual = start_pos;
+ VIsual_mode = 'v';
+ redraw_curbuf_later(INVERTED); /* update the inversion */
+ showmode();
+ } else {
+ oap->start = start_pos;
+ oap->motion_type = MCHAR;
+ oap->inclusive = FALSE;
+ if (sol)
+ incl(&curwin->w_cursor);
+ else if (ltoreq(start_pos, curwin->w_cursor))
+ /* Include the character under the cursor. */
+ oap->inclusive = TRUE;
+ else
+ /* End is before the start (no text in between <>, [], etc.): don't
+ * operate on any text. */
+ curwin->w_cursor = start_pos;
+ }
+
+ return OK;
+}
+
+static int in_html_tag __ARGS((int));
+
+/*
+ * Return TRUE if the cursor is on a "<aaa>" tag. Ignore "<aaa/>".
+ * When "end_tag" is TRUE return TRUE if the cursor is on "</aaa>".
+ */
+static int in_html_tag(end_tag)
+int end_tag;
+{
+ char_u *line = ml_get_curline();
+ char_u *p;
+ int c;
+ int lc = NUL;
+ pos_T pos;
+
+ if (enc_dbcs) {
+ char_u *lp = NULL;
+
+ /* 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))
+ if (*p == '>' || *p == '<') {
+ lc = *p;
+ lp = p;
+ }
+ 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 */
+ break;
+ mb_ptr_back(line, p);
+ if (*p == '>') /* find '>' before cursor */
+ break;
+ }
+ 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 '<' */
+ return *p == '/';
+
+ /* check that there is no '/' after the '<' */
+ if (*p == '/')
+ return FALSE;
+
+ /* check that the matching '>' is not preceded by '/' */
+ for (;; ) {
+ if (inc(&pos) < 0)
+ return FALSE;
+ c = *ml_get_pos(&pos);
+ if (c == '>')
+ break;
+ lc = c;
+ }
+ return lc != '/';
+}
+
+/*
+ * Find tag block under the cursor, cursor at end.
+ */
+int current_tagblock(oap, count_arg, include)
+oparg_T *oap;
+long count_arg;
+int include; /* TRUE == include white space */
+{
+ long count = count_arg;
+ long n;
+ pos_T old_pos;
+ pos_T start_pos;
+ pos_T end_pos;
+ pos_T old_start, old_end;
+ char_u *spat, *epat;
+ char_u *p;
+ char_u *cp;
+ int len;
+ int r;
+ int do_include = include;
+ int save_p_ws = p_ws;
+ int retval = FAIL;
+
+ p_ws = FALSE;
+
+ old_pos = curwin->w_cursor;
+ old_end = curwin->w_cursor; /* remember where we started */
+ old_start = old_end;
+ if (!VIsual_active || *p_sel == 'e')
+ decl(&old_end); /* old_end is inclusive */
+
+ /*
+ * If we start on "<aaa>" select that block.
+ */
+ if (!VIsual_active || equalpos(VIsual, curwin->w_cursor)) {
+ setpcmark();
+
+ /* ignore indent */
+ while (inindent(1))
+ if (inc_cursor() != 0)
+ break;
+
+ if (in_html_tag(FALSE)) {
+ /* cursor on start tag, move to its '>' */
+ while (*ml_get_cursor() != '>')
+ if (inc_cursor() < 0)
+ break;
+ } else if (in_html_tag(TRUE)) {
+ /* cursor on end tag, move to just before it */
+ while (*ml_get_cursor() != '<')
+ if (dec_cursor() < 0)
+ break;
+ dec_cursor();
+ old_end = curwin->w_cursor;
+ }
+ } else if (lt(VIsual, curwin->w_cursor)) {
+ old_start = VIsual;
+ curwin->w_cursor = VIsual; /* cursor at low end of Visual */
+ } else
+ old_end = VIsual;
+
+again:
+ /*
+ * Search backwards for unclosed "<aaa>".
+ * Put this position in start_pos.
+ */
+ for (n = 0; n < count; ++n) {
+ if (do_searchpair((char_u *)
+ "<[^ \t>/!]\\+\\%(\\_s\\_[^>]\\{-}[^/]>\\|$\\|\\_s\\=>\\)",
+ (char_u *)"",
+ (char_u *)"</[^>]*>", BACKWARD, (char_u *)"", 0,
+ NULL, (linenr_T)0, 0L) <= 0) {
+ curwin->w_cursor = old_pos;
+ goto theend;
+ }
+ }
+ start_pos = curwin->w_cursor;
+
+ /*
+ * Search for matching "</aaa>". First isolate the "aaa".
+ */
+ inc_cursor();
+ p = ml_get_cursor();
+ for (cp = p; *cp != NUL && *cp != '>' && !vim_iswhite(*cp); mb_ptr_adv(cp))
+ ;
+ len = (int)(cp - p);
+ if (len == 0) {
+ curwin->w_cursor = old_pos;
+ goto theend;
+ }
+ spat = alloc(len + 31);
+ epat = alloc(len + 9);
+ if (spat == NULL || epat == NULL) {
+ vim_free(spat);
+ vim_free(epat);
+ curwin->w_cursor = old_pos;
+ goto theend;
+ }
+ sprintf((char *)spat, "<%.*s\\>\\%%(\\s\\_[^>]\\{-}[^/]>\\|>\\)\\c", len, p);
+ sprintf((char *)epat, "</%.*s>\\c", len, p);
+
+ r = do_searchpair(spat, (char_u *)"", epat, FORWARD, (char_u *)"",
+ 0, NULL, (linenr_T)0, 0L);
+
+ vim_free(spat);
+ vim_free(epat);
+
+ if (r < 1 || lt(curwin->w_cursor, old_end)) {
+ /* Can't find other end or it's before the previous end. Could be a
+ * HTML tag that doesn't have a matching end. Search backwards for
+ * another starting tag. */
+ count = 1;
+ curwin->w_cursor = start_pos;
+ goto again;
+ }
+
+ if (do_include || r < 1) {
+ /* Include up to the '>'. */
+ while (*ml_get_cursor() != '>')
+ if (inc_cursor() < 0)
+ break;
+ } else {
+ /* Exclude the '<' of the end tag. */
+ if (*ml_get_cursor() == '<')
+ dec_cursor();
+ }
+ end_pos = curwin->w_cursor;
+
+ if (!do_include) {
+ /* Exclude the start tag. */
+ curwin->w_cursor = start_pos;
+ while (inc_cursor() >= 0)
+ if (*ml_get_cursor() == '>') {
+ inc_cursor();
+ start_pos = curwin->w_cursor;
+ break;
+ }
+ 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;
+ curwin->w_cursor = old_start;
+ count = count_arg;
+ goto again;
+ }
+ }
+
+ if (VIsual_active) {
+ /* If the end is before the start there is no text between tags, select
+ * the char under the cursor. */
+ if (lt(end_pos, start_pos))
+ curwin->w_cursor = start_pos;
+ else if (*p_sel == 'e')
+ ++curwin->w_cursor.col;
+ VIsual = start_pos;
+ VIsual_mode = 'v';
+ redraw_curbuf_later(INVERTED); /* update the inversion */
+ showmode();
+ } else {
+ oap->start = start_pos;
+ oap->motion_type = MCHAR;
+ if (lt(end_pos, start_pos)) {
+ /* End is before the start: there is no text between tags; operate
+ * on an empty area. */
+ curwin->w_cursor = start_pos;
+ oap->inclusive = FALSE;
+ } else
+ oap->inclusive = TRUE;
+ }
+ retval = OK;
+
+theend:
+ p_ws = save_p_ws;
+ return retval;
+}
+
+int current_par(oap, count, include, type)
+oparg_T *oap;
+long count;
+int include; /* TRUE == include white space */
+int type; /* 'p' for paragraph, 'S' for section */
+{
+ linenr_T start_lnum;
+ linenr_T end_lnum;
+ int white_in_front;
+ int dir;
+ int start_is_white;
+ int prev_start_is_white;
+ int retval = OK;
+ int do_white = FALSE;
+ int t;
+ int i;
+
+ if (type == 'S') /* not implemented yet */
+ return FAIL;
+
+ start_lnum = curwin->w_cursor.lnum;
+
+ /*
+ * When visual area is more than one line: extend it.
+ */
+ if (VIsual_active && start_lnum != VIsual.lnum) {
+extend:
+ if (start_lnum < VIsual.lnum)
+ dir = BACKWARD;
+ else
+ dir = FORWARD;
+ for (i = count; --i >= 0; ) {
+ if (start_lnum ==
+ (dir == BACKWARD ? 1 : curbuf->b_ml.ml_line_count)) {
+ retval = FAIL;
+ break;
+ }
+
+ prev_start_is_white = -1;
+ for (t = 0; t < 2; ++t) {
+ start_lnum += dir;
+ start_is_white = linewhite(start_lnum);
+ if (prev_start_is_white == start_is_white) {
+ start_lnum -= dir;
+ break;
+ }
+ for (;; ) {
+ if (start_lnum == (dir == BACKWARD
+ ? 1 : curbuf->b_ml.ml_line_count))
+ break;
+ if (start_is_white != linewhite(start_lnum + dir)
+ || (!start_is_white
+ && startPS(start_lnum + (dir > 0
+ ? 1 : 0), 0, 0)))
+ break;
+ start_lnum += dir;
+ }
+ if (!include)
+ break;
+ if (start_lnum == (dir == BACKWARD
+ ? 1 : curbuf->b_ml.ml_line_count))
+ break;
+ prev_start_is_white = start_is_white;
+ }
+ }
+ curwin->w_cursor.lnum = start_lnum;
+ curwin->w_cursor.col = 0;
+ return retval;
+ }
+
+ /*
+ * First move back to the start_lnum of the paragraph or white lines
+ */
+ white_in_front = linewhite(start_lnum);
+ while (start_lnum > 1) {
+ if (white_in_front) { /* stop at first white line */
+ if (!linewhite(start_lnum - 1))
+ break;
+ } else { /* stop at first non-white line of start of paragraph */
+ if (linewhite(start_lnum - 1) || startPS(start_lnum, 0, 0))
+ break;
+ }
+ --start_lnum;
+ }
+
+ /*
+ * Move past the end of any white lines.
+ */
+ end_lnum = start_lnum;
+ while (end_lnum <= curbuf->b_ml.ml_line_count && linewhite(end_lnum))
+ ++end_lnum;
+
+ --end_lnum;
+ i = count;
+ if (!include && white_in_front)
+ --i;
+ while (i--) {
+ if (end_lnum == curbuf->b_ml.ml_line_count)
+ return FAIL;
+
+ if (!include)
+ do_white = linewhite(end_lnum + 1);
+
+ if (include || !do_white) {
+ ++end_lnum;
+ /*
+ * skip to end of paragraph
+ */
+ while (end_lnum < curbuf->b_ml.ml_line_count
+ && !linewhite(end_lnum + 1)
+ && !startPS(end_lnum + 1, 0, 0))
+ ++end_lnum;
+ }
+
+ if (i == 0 && white_in_front && include)
+ break;
+
+ /*
+ * skip to end of white lines after paragraph
+ */
+ if (include || do_white)
+ while (end_lnum < curbuf->b_ml.ml_line_count
+ && linewhite(end_lnum + 1))
+ ++end_lnum;
+ }
+
+ /*
+ * If there are no empty lines at the end, try to find some empty lines at
+ * the start (unless that has been done already).
+ */
+ if (!white_in_front && !linewhite(end_lnum) && include)
+ while (start_lnum > 1 && linewhite(start_lnum - 1))
+ --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)
+ goto extend;
+ VIsual.lnum = start_lnum;
+ VIsual_mode = 'V';
+ redraw_curbuf_later(INVERTED); /* update the inversion */
+ showmode();
+ } else {
+ oap->start.lnum = start_lnum;
+ oap->start.col = 0;
+ oap->motion_type = MLINE;
+ }
+ curwin->w_cursor.lnum = end_lnum;
+ curwin->w_cursor.col = 0;
+
+ return OK;
+}
+
+static int find_next_quote __ARGS((char_u *top_ptr, int col, int quotechar,
+ char_u *escape));
+static int find_prev_quote __ARGS((char_u *line, int col_start, int quotechar,
+ char_u *escape));
+
+/*
+ * Search quote char from string line[col].
+ * Quote character escaped by one of the characters in "escape" is not counted
+ * as a quote.
+ * Returns column number of "quotechar" or -1 when not found.
+ */
+static int find_next_quote(line, col, quotechar, escape)
+char_u *line;
+int col;
+int quotechar;
+char_u *escape; /* escape characters, can be NULL */
+{
+ int c;
+
+ for (;; ) {
+ c = line[col];
+ if (c == NUL)
+ return -1;
+ else if (escape != NULL && vim_strchr(escape, c))
+ ++col;
+ else if (c == quotechar)
+ break;
+ if (has_mbyte)
+ col += (*mb_ptr2len)(line + col);
+ else
+ ++col;
+ }
+ return col;
+}
+
+/*
+ * Search backwards in "line" from column "col_start" to find "quotechar".
+ * Quote character escaped by one of the characters in "escape" is not counted
+ * as a quote.
+ * Return the found column or zero.
+ */
+static int find_prev_quote(line, col_start, quotechar, escape)
+char_u *line;
+int col_start;
+int quotechar;
+char_u *escape; /* escape characters, can be NULL */
+{
+ int n;
+
+ while (col_start > 0) {
+ --col_start;
+ col_start -= (*mb_head_off)(line, line + col_start);
+ n = 0;
+ if (escape != NULL)
+ while (col_start - n > 0 && vim_strchr(escape,
+ line[col_start - n - 1]) != NULL)
+ ++n;
+ if (n & 1)
+ col_start -= n; /* uneven number of escape chars, skip it */
+ else if (line[col_start] == quotechar)
+ break;
+ }
+ return col_start;
+}
+
+/*
+ * Find quote under the cursor, cursor at end.
+ * Returns TRUE if found, else FALSE.
+ */
+int current_quote(oap, count, include, quotechar)
+oparg_T *oap;
+long count;
+int include; /* TRUE == include quote char */
+int quotechar; /* Quote character */
+{
+ char_u *line = ml_get_curline();
+ int col_end;
+ int col_start = curwin->w_cursor.col;
+ int inclusive = FALSE;
+ int vis_empty = TRUE; /* Visual selection <= 1 char */
+ int vis_bef_curs = FALSE; /* Visual starts before cursor */
+ int inside_quotes = FALSE; /* Looks like "i'" done before */
+ int selected_quote = FALSE; /* Has quote inside selection */
+ int i;
+
+ /* Correct cursor when 'selection' is exclusive */
+ if (VIsual_active) {
+ vis_bef_curs = lt(VIsual, curwin->w_cursor);
+ if (*p_sel == 'e' && vis_bef_curs)
+ dec_cursor();
+ vis_empty = equalpos(VIsual, curwin->w_cursor);
+ }
+
+ if (!vis_empty) {
+ /* Check if the existing selection exactly spans the text inside
+ * quotes. */
+ if (vis_bef_curs) {
+ inside_quotes = VIsual.col > 0
+ && line[VIsual.col - 1] == quotechar
+ && line[curwin->w_cursor.col] != NUL
+ && line[curwin->w_cursor.col + 1] == quotechar;
+ i = VIsual.col;
+ col_end = curwin->w_cursor.col;
+ } else {
+ inside_quotes = curwin->w_cursor.col > 0
+ && line[curwin->w_cursor.col - 1] == quotechar
+ && line[VIsual.col] != NUL
+ && line[VIsual.col + 1] == quotechar;
+ i = curwin->w_cursor.col;
+ col_end = VIsual.col;
+ }
+
+ /* Find out if we have a quote in the selection. */
+ while (i <= col_end)
+ if (line[i++] == quotechar) {
+ selected_quote = TRUE;
+ break;
+ }
+ }
+
+ if (!vis_empty && line[col_start] == quotechar) {
+ /* Already selecting something and on a quote character. Find the
+ * next quoted string. */
+ if (vis_bef_curs) {
+ /* Assume we are on a closing quote: move to after the next
+ * opening quote. */
+ col_start = find_next_quote(line, col_start + 1, quotechar, NULL);
+ if (col_start < 0)
+ return FALSE;
+ col_end = find_next_quote(line, col_start + 1, quotechar,
+ curbuf->b_p_qe);
+ if (col_end < 0) {
+ /* We were on a starting quote perhaps? */
+ col_end = col_start;
+ col_start = curwin->w_cursor.col;
+ }
+ } else {
+ col_end = find_prev_quote(line, col_start, quotechar, NULL);
+ if (line[col_end] != quotechar)
+ return FALSE;
+ col_start = find_prev_quote(line, col_end, quotechar,
+ curbuf->b_p_qe);
+ if (line[col_start] != quotechar) {
+ /* We were on an ending quote perhaps? */
+ col_start = col_end;
+ col_end = curwin->w_cursor.col;
+ }
+ }
+ } else if (line[col_start] == quotechar
+ || !vis_empty
+ ) {
+ int first_col = col_start;
+
+ if (!vis_empty) {
+ if (vis_bef_curs)
+ first_col = find_next_quote(line, col_start, quotechar, NULL);
+ else
+ first_col = find_prev_quote(line, col_start, quotechar, NULL);
+ }
+ /* The cursor is on a quote, we don't know if it's the opening or
+ * closing quote. Search from the start of the line to find out.
+ * Also do this when there is a Visual area, a' may leave the cursor
+ * in between two strings. */
+ col_start = 0;
+ for (;; ) {
+ /* Find open quote character. */
+ col_start = find_next_quote(line, col_start, quotechar, NULL);
+ if (col_start < 0 || col_start > first_col)
+ return FALSE;
+ /* Find close quote character. */
+ col_end = find_next_quote(line, col_start + 1, quotechar,
+ curbuf->b_p_qe);
+ if (col_end < 0)
+ return FALSE;
+ /* If is cursor between start and end quote character, it is
+ * target text object. */
+ if (col_start <= first_col && first_col <= col_end)
+ break;
+ col_start = col_end + 1;
+ }
+ } else {
+ /* Search backward for a starting quote. */
+ col_start = find_prev_quote(line, col_start, quotechar, curbuf->b_p_qe);
+ if (line[col_start] != quotechar) {
+ /* No quote before the cursor, look after the cursor. */
+ col_start = find_next_quote(line, col_start, quotechar, NULL);
+ if (col_start < 0)
+ return FALSE;
+ }
+
+ /* Find close quote character. */
+ col_end = find_next_quote(line, col_start + 1, quotechar,
+ curbuf->b_p_qe);
+ if (col_end < 0)
+ return FALSE;
+ }
+
+ /* When "include" is TRUE, include spaces after closing quote or before
+ * the starting quote. */
+ if (include) {
+ if (vim_iswhite(line[col_end + 1]))
+ while (vim_iswhite(line[col_end + 1]))
+ ++col_end;
+ else
+ while (col_start > 0 && vim_iswhite(line[col_start - 1]))
+ --col_start;
+ }
+
+ /* Set start position. After vi" another i" must include the ".
+ * For v2i" include the quotes. */
+ if (!include && count < 2
+ && (vis_empty || !inside_quotes)
+ )
+ ++col_start;
+ curwin->w_cursor.col = col_start;
+ if (VIsual_active) {
+ /* Set the start of the Visual area when the Visual area was empty, we
+ * were just inside quotes or the Visual area didn't start at a quote
+ * and didn't include a quote.
+ */
+ if (vis_empty
+ || (vis_bef_curs
+ && !selected_quote
+ && (inside_quotes
+ || (line[VIsual.col] != quotechar
+ && (VIsual.col == 0
+ || line[VIsual.col - 1] != quotechar))))) {
+ VIsual = curwin->w_cursor;
+ redraw_curbuf_later(INVERTED);
+ }
+ } else {
+ oap->start = curwin->w_cursor;
+ oap->motion_type = MCHAR;
+ }
+
+ /* Set end position. */
+ curwin->w_cursor.col = col_end;
+ if ((include || count > 1
+ /* After vi" another i" must include the ". */
+ || (!vis_empty && inside_quotes)
+ ) && inc_cursor() == 2)
+ inclusive = TRUE;
+ if (VIsual_active) {
+ if (vis_empty || vis_bef_curs) {
+ /* decrement cursor when 'selection' is not exclusive */
+ if (*p_sel != 'e')
+ dec_cursor();
+ } else {
+ /* Cursor is at start of Visual area. Set the end of the Visual
+ * area when it was just inside quotes or it didn't end at a
+ * quote. */
+ if (inside_quotes
+ || (!selected_quote
+ && line[VIsual.col] != quotechar
+ && (line[VIsual.col] == NUL
+ || line[VIsual.col + 1] != quotechar))) {
+ dec_cursor();
+ VIsual = curwin->w_cursor;
+ }
+ curwin->w_cursor.col = col_start;
+ }
+ if (VIsual_mode == 'V') {
+ VIsual_mode = 'v';
+ redraw_cmdline = TRUE; /* show mode later */
+ }
+ } else {
+ /* Set inclusive and other oap's flags. */
+ oap->inclusive = inclusive;
+ }
+
+ return OK;
+}
+
+
+static int is_one_char __ARGS((char_u *pattern));
+
+/*
+ * Find next search match under cursor, cursor at end.
+ * Used while an operator is pending, and in Visual mode.
+ * TODO: redo only works when used in operator pending mode
+ */
+int current_search(count, forward)
+long count;
+int forward; /* move forward or backwards */
+{
+ pos_T start_pos; /* position before the pattern */
+ pos_T orig_pos; /* position of the cursor at beginning */
+ pos_T pos; /* position after the pattern */
+ int i;
+ int dir;
+ int result; /* result of various function calls */
+ char_u old_p_ws = p_ws;
+ int flags = 0;
+ pos_T save_VIsual = VIsual;
+ int one_char;
+
+ /* wrapping should not occur */
+ p_ws = FALSE;
+
+ /* Correct cursor when 'selection' is exclusive */
+ if (VIsual_active && *p_sel == 'e' && lt(VIsual, curwin->w_cursor))
+ dec_cursor();
+
+ if (VIsual_active) {
+ orig_pos = curwin->w_cursor;
+
+ pos = curwin->w_cursor;
+ start_pos = VIsual;
+
+ /* make sure, searching further will extend the match */
+ if (VIsual_active) {
+ if (forward)
+ incl(&pos);
+ else
+ decl(&pos);
+ }
+ } else
+ orig_pos = pos = start_pos = curwin->w_cursor;
+
+ /* Is the pattern is zero-width? */
+ one_char = is_one_char(spats[last_idx].pat);
+ if (one_char == -1) {
+ p_ws = old_p_ws;
+ return FAIL; /* pattern not found */
+ }
+
+ /*
+ * The trick is to first search backwards and then search forward again,
+ * so that a match at the current cursor position will be correctly
+ * captured.
+ */
+ for (i = 0; i < 2; i++) {
+ if (forward)
+ dir = i;
+ else
+ dir = !i;
+
+ flags = 0;
+ if (!dir && !one_char)
+ flags = SEARCH_END;
+
+ result = searchit(curwin, curbuf, &pos, (dir ? FORWARD : BACKWARD),
+ spats[last_idx].pat, (long) (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)
+ * except when Visual mode is active, so that extending the visual
+ * selection works. */
+ if (!result && i) { /* not found, abort */
+ curwin->w_cursor = orig_pos;
+ if (VIsual_active)
+ VIsual = save_VIsual;
+ p_ws = old_p_ws;
+ return FAIL;
+ } else if (!i && !result) {
+ if (forward) { /* try again from start of buffer */
+ clearpos(&pos);
+ } else { /* try again from end of buffer */
+ /* searching backwards, so set pos to last line and col */
+ pos.lnum = curwin->w_buffer->b_ml.ml_line_count;
+ pos.col = (colnr_T)STRLEN(
+ ml_get(curwin->w_buffer->b_ml.ml_line_count));
+ }
+ }
+ p_ws = old_p_ws;
+ }
+
+ start_pos = pos;
+ flags = forward ? SEARCH_END : 0;
+
+ /* move to match, except for zero-width matches, in which case, we are
+ * already on the next match */
+ if (!one_char)
+ result = searchit(curwin, curbuf, &pos, (forward ? FORWARD : BACKWARD),
+ spats[last_idx].pat, 0L, flags | SEARCH_KEEP, RE_SEARCH, 0, NULL);
+
+ if (!VIsual_active)
+ VIsual = start_pos;
+
+ curwin->w_cursor = pos;
+ 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);
+ }
+
+ }
+
+ if (fdo_flags & FDO_SEARCH && KeyTyped)
+ foldOpenCursor();
+
+ may_start_select('c');
+ setmouse();
+ redraw_curbuf_later(INVERTED);
+ showmode();
+
+ return OK;
+}
+
+/*
+ * Check if the pattern is one character or zero-width.
+ * Returns TRUE, FALSE or -1 for failure.
+ */
+static int is_one_char(pattern)
+char_u *pattern;
+{
+ regmmatch_T regmatch;
+ int nmatched = 0;
+ int result = -1;
+ pos_T pos;
+ int save_called_emsg = called_emsg;
+
+ if (search_regcomp(pattern, RE_SEARCH, RE_SEARCH,
+ SEARCH_KEEP, &regmatch) == FAIL)
+ return -1;
+
+ /* move to match */
+ clearpos(&pos);
+ if (searchit(curwin, curbuf, &pos, FORWARD, spats[last_idx].pat, 1,
+ SEARCH_KEEP, 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)
+ 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;
+ }
+
+ called_emsg |= save_called_emsg;
+ vim_regfree(regmatch.regprog);
+ return result;
+}
+
+#if defined(FEAT_LISP) || defined(FEAT_CINDENT) || defined(FEAT_TEXTOBJ) \
+ || defined(PROTO)
+/*
+ * return TRUE if line 'lnum' is empty or has white chars only.
+ */
+int linewhite(lnum)
+linenr_T lnum;
+{
+ char_u *p;
+
+ p = skipwhite(ml_get(lnum));
+ return *p == NUL;
+}
+#endif
+
+/*
+ * 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(ptr, dir, len, whole, skip_comments,
+ type, count, action, start_lnum, end_lnum)
+char_u *ptr; /* pointer to search pattern */
+int dir UNUSED; /* direction of expansion */
+int 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 */
+{
+ SearchedFile *files; /* Stack of included files */
+ SearchedFile *bigger; /* When we need more space */
+ int max_path_depth = 50;
+ long match_count = 1;
+
+ char_u *pat;
+ char_u *new_fname;
+ char_u *curr_fname = curbuf->b_fname;
+ char_u *prev_fname = NULL;
+ linenr_T lnum;
+ int depth;
+ int depth_displayed; /* For type==CHECK_PATH */
+ int old_files;
+ int already_searched;
+ char_u *file_line;
+ char_u *line;
+ char_u *p;
+ char_u save_char;
+ int define_matched;
+ regmatch_T regmatch;
+ regmatch_T incl_regmatch;
+ regmatch_T def_regmatch;
+ int matched = FALSE;
+ int did_show = FALSE;
+ int found = FALSE;
+ int i;
+ char_u *already = NULL;
+ char_u *startp = NULL;
+ char_u *inc_opt = NULL;
+ win_T *curwin_save = NULL;
+
+ regmatch.regprog = NULL;
+ incl_regmatch.regprog = NULL;
+ def_regmatch.regprog = NULL;
+
+ file_line = alloc(LSIZE);
+ if (file_line == NULL)
+ return;
+
+ if (type != CHECK_PATH && type != FIND_DEFINE
+ /* when CONT_SOL is set compare "ptr" with the beginning of the line
+ * is faster than quote_meta/regcomp/regexec "ptr" -- Acevedo */
+ && !(compl_cont_status & CONT_SOL)
+ ) {
+ pat = alloc(len + 5);
+ if (pat == NULL)
+ goto fpip_end;
+ sprintf((char *)pat, whole ? "\\<%.*s\\>" : "%.*s", len, ptr);
+ /* ignore case according to p_ic, p_scs and pat */
+ regmatch.rm_ic = ignorecase(pat);
+ regmatch.regprog = vim_regcomp(pat, p_magic ? RE_MAGIC : 0);
+ vim_free(pat);
+ if (regmatch.regprog == NULL)
+ goto fpip_end;
+ }
+ inc_opt = (*curbuf->b_p_inc == NUL) ? p_inc : curbuf->b_p_inc;
+ if (*inc_opt != NUL) {
+ incl_regmatch.regprog = vim_regcomp(inc_opt, p_magic ? RE_MAGIC : 0);
+ if (incl_regmatch.regprog == NULL)
+ goto fpip_end;
+ incl_regmatch.rm_ic = FALSE; /* don't ignore case in incl. pat. */
+ }
+ if (type == FIND_DEFINE && (*curbuf->b_p_def != NUL || *p_def != NUL)) {
+ def_regmatch.regprog = vim_regcomp(*curbuf->b_p_def == NUL
+ ? p_def : curbuf->b_p_def, p_magic ? RE_MAGIC : 0);
+ if (def_regmatch.regprog == NULL)
+ goto fpip_end;
+ def_regmatch.rm_ic = FALSE; /* don't ignore case in define pat. */
+ }
+ files = (SearchedFile *)lalloc_clear((long_u)
+ (max_path_depth * sizeof(SearchedFile)), TRUE);
+ if (files == NULL)
+ goto fpip_end;
+ old_files = max_path_depth;
+ depth = depth_displayed = -1;
+
+ lnum = start_lnum;
+ if (end_lnum > curbuf->b_ml.ml_line_count)
+ end_lnum = curbuf->b_ml.ml_line_count;
+ if (lnum > end_lnum) /* do at least one line */
+ lnum = end_lnum;
+ line = ml_get(lnum);
+
+ for (;; ) {
+ if (incl_regmatch.regprog != NULL
+ && vim_regexec(&incl_regmatch, line, (colnr_T)0)) {
+ char_u *p_fname = (curr_fname == curbuf->b_fname)
+ ? curbuf->b_ffname : curr_fname;
+
+ if (inc_opt != NULL && strstr((char *)inc_opt, "\\zs") != NULL)
+ /* Use text from '\zs' to '\ze' (or end) of 'include'. */
+ new_fname = find_file_name_in_path(incl_regmatch.startp[0],
+ (int)(incl_regmatch.endp[0] - incl_regmatch.startp[0]),
+ FNAME_EXP|FNAME_INCL|FNAME_REL, 1L, p_fname);
+ else
+ /* Use text after match with 'include'. */
+ new_fname = file_name_in_line(incl_regmatch.endp[0], 0,
+ FNAME_EXP|FNAME_INCL|FNAME_REL, 1L, p_fname, NULL);
+ already_searched = FALSE;
+ if (new_fname != NULL) {
+ /* Check whether we have already searched in this file */
+ for (i = 0;; i++) {
+ if (i == depth + 1)
+ i = old_files;
+ if (i == max_path_depth)
+ break;
+ if (fullpathcmp(new_fname, files[i].name, TRUE) & FPC_SAME) {
+ if (type != CHECK_PATH &&
+ action == ACTION_SHOW_ALL && files[i].matched) {
+ msg_putchar('\n'); /* cursor below last one */
+ if (!got_int) { /* don't display if 'q'
+ typed at "--more--"
+ message */
+ msg_home_replace_hl(new_fname);
+ MSG_PUTS(_(" (includes previously listed match)"));
+ prev_fname = NULL;
+ }
+ }
+ vim_free(new_fname);
+ new_fname = NULL;
+ already_searched = TRUE;
+ break;
+ }
+ }
+ }
+
+ if (type == CHECK_PATH && (action == ACTION_SHOW_ALL
+ || (new_fname == NULL &&
+ !already_searched))) {
+ if (did_show)
+ msg_putchar('\n'); /* cursor below last one */
+ else {
+ gotocmdline(TRUE); /* cursor at status line */
+ MSG_PUTS_TITLE(_("--- Included files "));
+ if (action != ACTION_SHOW_ALL)
+ MSG_PUTS_TITLE(_("not found "));
+ MSG_PUTS_TITLE(_("in path ---\n"));
+ }
+ did_show = TRUE;
+ while (depth_displayed < depth && !got_int) {
+ ++depth_displayed;
+ for (i = 0; i < depth_displayed; i++)
+ MSG_PUTS(" ");
+ msg_home_replace(files[depth_displayed].name);
+ MSG_PUTS(" -->\n");
+ }
+ if (!got_int) { /* don't display if 'q' typed
+ for "--more--" message */
+ for (i = 0; i <= depth_displayed; i++)
+ MSG_PUTS(" ");
+ 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));
+ } else {
+ /*
+ * Isolate the file name.
+ * Include the surrounding "" or <> if present.
+ */
+ if (inc_opt != NULL
+ && strstr((char *)inc_opt, "\\zs") != NULL) {
+ /* pattern contains \zs, use the match */
+ p = incl_regmatch.startp[0];
+ i = (int)(incl_regmatch.endp[0]
+ - incl_regmatch.startp[0]);
+ } else {
+ /* find the file name after the end of the match */
+ for (p = incl_regmatch.endp[0];
+ *p && !vim_isfilec(*p); p++)
+ ;
+ for (i = 0; vim_isfilec(p[i]); i++)
+ ;
+ }
+
+ if (i == 0) {
+ /* Nothing found, use the rest of the line. */
+ p = incl_regmatch.endp[0];
+ i = (int)STRLEN(p);
+ }
+ /* Avoid checking before the start of the line, can
+ * happen if \zs appears in the regexp. */
+ else if (p > line) {
+ if (p[-1] == '"' || p[-1] == '<') {
+ --p;
+ ++i;
+ }
+ if (p[i] == '"' || p[i] == '>')
+ ++i;
+ }
+ save_char = p[i];
+ p[i] = NUL;
+ msg_outtrans_attr(p, hl_attr(HLF_D));
+ p[i] = save_char;
+ }
+
+ if (new_fname == NULL && action == ACTION_SHOW_ALL) {
+ if (already_searched)
+ MSG_PUTS(_(" (Already listed)"));
+ else
+ MSG_PUTS(_(" NOT FOUND"));
+ }
+ }
+ out_flush(); /* output each line directly */
+ }
+
+ if (new_fname != NULL) {
+ /* Push the new file onto the file stack */
+ if (depth + 1 == old_files) {
+ bigger = (SearchedFile *)lalloc((long_u)(
+ max_path_depth * 2 * sizeof(SearchedFile)), TRUE);
+ if (bigger != NULL) {
+ for (i = 0; i <= depth; i++)
+ bigger[i] = files[i];
+ for (i = depth + 1; i < old_files + max_path_depth; i++) {
+ bigger[i].fp = NULL;
+ bigger[i].name = NULL;
+ bigger[i].lnum = 0;
+ bigger[i].matched = FALSE;
+ }
+ for (i = old_files; i < max_path_depth; i++)
+ bigger[i + max_path_depth] = files[i];
+ old_files += max_path_depth;
+ max_path_depth *= 2;
+ vim_free(files);
+ files = bigger;
+ }
+ }
+ if ((files[depth + 1].fp = mch_fopen((char *)new_fname, "r"))
+ == NULL)
+ vim_free(new_fname);
+ else {
+ if (++depth == old_files) {
+ /*
+ * lalloc() for 'bigger' must have failed above. We
+ * will forget one of our already visited files now.
+ */
+ vim_free(files[old_files].name);
+ ++old_files;
+ }
+ files[depth].name = curr_fname = new_fname;
+ 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));
+ } else if (p_verbose >= 5) {
+ verbose_enter();
+ smsg((char_u *)_("Searching included file %s"),
+ (char *)new_fname);
+ verbose_leave();
+ }
+
+ }
+ }
+ } else {
+ /*
+ * Check if the line is a define (type == FIND_DEFINE)
+ */
+ p = line;
+search_line:
+ define_matched = FALSE;
+ if (def_regmatch.regprog != NULL
+ && vim_regexec(&def_regmatch, line, (colnr_T)0)) {
+ /*
+ * Pattern must be first identifier after 'define', so skip
+ * to that position before checking for match of pattern. Also
+ * don't let it match beyond the end of this identifier.
+ */
+ p = def_regmatch.endp[0];
+ while (*p && !vim_iswordc(*p))
+ p++;
+ define_matched = TRUE;
+ }
+
+ /*
+ * Look for a match. Don't do this if we are looking for a
+ * define and this line didn't match define_prog above.
+ */
+ if (def_regmatch.regprog == NULL || define_matched) {
+ if (define_matched
+ || (compl_cont_status & CONT_SOL)
+ ) {
+ /* compare the first "len" chars from "ptr" */
+ startp = skipwhite(p);
+ if (p_ic)
+ matched = !MB_STRNICMP(startp, ptr, len);
+ else
+ matched = !STRNCMP(startp, ptr, len);
+ if (matched && define_matched && whole
+ && vim_iswordc(startp[len]))
+ matched = FALSE;
+ } else if (regmatch.regprog != NULL
+ && vim_regexec(&regmatch, line, (colnr_T)(p - line))) {
+ matched = TRUE;
+ startp = regmatch.startp[0];
+ /*
+ * Check if the line is not a comment line (unless we are
+ * looking for a define). A line starting with "# define"
+ * is not considered to be a comment line.
+ */
+ if (!define_matched && skip_comments) {
+ if ((*line != '#' ||
+ STRNCMP(skipwhite(line + 1), "define", 6) != 0)
+ && get_leader_len(line, NULL, FALSE, TRUE))
+ matched = FALSE;
+
+ /*
+ * Also check for a "/ *" or "/ /" before the match.
+ * Skips lines like "int backwards; / * normal index
+ * * /" when looking for "normal".
+ * Note: Doesn't skip "/ *" in comments.
+ */
+ p = skipwhite(line);
+ if (matched
+ || (p[0] == '/' && p[1] == '*') || p[0] == '*')
+ for (p = line; *p && p < startp; ++p) {
+ if (matched
+ && p[0] == '/'
+ && (p[1] == '*' || p[1] == '/')) {
+ matched = FALSE;
+ /* After "//" all text is comment */
+ if (p[1] == '/')
+ break;
+ ++p;
+ } else if (!matched && p[0] == '*' && p[1] == '/') {
+ /* Can find match after "* /". */
+ matched = TRUE;
+ ++p;
+ }
+ }
+ }
+ }
+ }
+ }
+ if (matched) {
+ if (action == ACTION_EXPAND) {
+ int reuse = 0;
+ int add_r;
+ char_u *aux;
+
+ if (depth == -1 && lnum == curwin->w_cursor.lnum)
+ break;
+ found = TRUE;
+ aux = p = startp;
+ if (compl_cont_status & CONT_ADDING) {
+ p += compl_length;
+ if (vim_iswordp(p))
+ goto exit_matched;
+ p = find_word_start(p);
+ }
+ p = find_word_end(p);
+ i = (int)(p - aux);
+
+ if ((compl_cont_status & CONT_ADDING) && i == compl_length) {
+ /* IOSIZE > compl_length, so the STRNCPY works */
+ STRNCPY(IObuff, aux, i);
+
+ /* Get the next line: when "depth" < 0 from the current
+ * buffer, otherwise from the included file. Jump to
+ * exit_matched when past the last line. */
+ if (depth < 0) {
+ if (lnum >= end_lnum)
+ goto exit_matched;
+ line = ml_get(++lnum);
+ } else if (vim_fgets(line = file_line,
+ LSIZE, files[depth].fp))
+ goto exit_matched;
+
+ /* we read a line, set "already" to check this "line" later
+ * if depth >= 0 we'll increase files[depth].lnum far
+ * bellow -- Acevedo */
+ already = aux = p = skipwhite(line);
+ p = find_word_start(p);
+ p = find_word_end(p);
+ if (p > aux) {
+ if (*aux != ')' && IObuff[i-1] != TAB) {
+ if (IObuff[i-1] != ' ')
+ IObuff[i++] = ' ';
+ /* IObuf =~ "\(\k\|\i\).* ", thus i >= 2*/
+ if (p_js
+ && (IObuff[i-2] == '.'
+ || (vim_strchr(p_cpo, CPO_JOINSP) == NULL
+ && (IObuff[i-2] == '?'
+ || IObuff[i-2] == '!'))))
+ IObuff[i++] = ' ';
+ }
+ /* copy as much as possible of the new word */
+ if (p - aux >= IOSIZE - i)
+ p = aux + IOSIZE - i - 1;
+ STRNCPY(IObuff + i, aux, p - aux);
+ i += (int)(p - aux);
+ reuse |= CONT_S_IPOS;
+ }
+ IObuff[i] = NUL;
+ aux = IObuff;
+
+ if (i == compl_length)
+ goto exit_matched;
+ }
+
+ add_r = ins_compl_add_infercase(aux, i, p_ic,
+ curr_fname == curbuf->b_fname ? NULL : curr_fname,
+ dir, reuse);
+ if (add_r == OK)
+ /* if dir was BACKWARD then honor it just once */
+ dir = FORWARD;
+ else if (add_r == FAIL)
+ break;
+ } else if (action == ACTION_SHOW_ALL) {
+ found = TRUE;
+ if (!did_show)
+ gotocmdline(TRUE); /* cursor at status line */
+ if (curr_fname != prev_fname) {
+ if (did_show)
+ msg_putchar('\n'); /* cursor below last one */
+ if (!got_int) /* don't display if 'q' typed
+ at "--more--" message */
+ msg_home_replace_hl(curr_fname);
+ prev_fname = curr_fname;
+ }
+ did_show = TRUE;
+ if (!got_int)
+ show_pat_in_path(line, type, TRUE, action,
+ (depth == -1) ? NULL : files[depth].fp,
+ (depth == -1) ? &lnum : &files[depth].lnum,
+ match_count++);
+
+ /* Set matched flag for this file and all the ones that
+ * include it */
+ for (i = 0; i <= depth; ++i)
+ files[i].matched = TRUE;
+ } else if (--count <= 0) {
+ found = TRUE;
+ if (depth == -1 && lnum == curwin->w_cursor.lnum
+ && g_do_tagpreview == 0
+ )
+ EMSG(_("E387: Match is on current line"));
+ else if (action == ACTION_SHOW) {
+ show_pat_in_path(line, type, did_show, action,
+ (depth == -1) ? NULL : files[depth].fp,
+ (depth == -1) ? &lnum : &files[depth].lnum, 1L);
+ did_show = TRUE;
+ } else {
+ /* ":psearch" uses the preview window */
+ if (g_do_tagpreview != 0) {
+ curwin_save = curwin;
+ prepare_tagpreview(TRUE);
+ }
+ if (action == ACTION_SPLIT) {
+ if (win_split(0, 0) == FAIL)
+ break;
+ RESET_BINDING(curwin);
+ }
+ if (depth == -1) {
+ /* match in current file */
+ if (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
+ setpcmark();
+ curwin->w_cursor.lnum = lnum;
+ } 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 */
+ curwin->w_cursor.lnum = files[depth].lnum;
+ }
+ }
+ if (action != ACTION_SHOW) {
+ curwin->w_cursor.col = (colnr_T)(startp - line);
+ curwin->w_set_curswant = TRUE;
+ }
+
+ if (g_do_tagpreview != 0
+ && curwin != curwin_save && win_valid(curwin_save)) {
+ /* Return cursor to where we were */
+ validate_cursor();
+ redraw_later(VALID);
+ win_enter(curwin_save, TRUE);
+ }
+ break;
+ }
+exit_matched:
+ matched = FALSE;
+ /* look for other matches in the rest of the line if we
+ * are not at the end of it already */
+ if (def_regmatch.regprog == NULL
+ && action == ACTION_EXPAND
+ && !(compl_cont_status & CONT_SOL)
+ && *startp != NUL
+ && *(p = startp + MB_PTR2LEN(startp)) != NUL)
+ goto search_line;
+ }
+ line_breakcheck();
+ if (action == ACTION_EXPAND)
+ ins_compl_check_keys(30);
+ if (got_int || compl_interrupted)
+ break;
+
+ /*
+ * Read the next line. When reading an included file and encountering
+ * end-of-file, close the file and continue in the file that included
+ * it.
+ */
+ while (depth >= 0 && !already
+ && vim_fgets(line = file_line, LSIZE, files[depth].fp)) {
+ fclose(files[depth].fp);
+ --old_files;
+ files[old_files].name = files[depth].name;
+ files[old_files].matched = files[depth].matched;
+ --depth;
+ curr_fname = (depth == -1) ? curbuf->b_fname
+ : files[depth].name;
+ if (depth < depth_displayed)
+ depth_displayed = depth;
+ }
+ if (depth >= 0) { /* we could read the line */
+ files[depth].lnum++;
+ /* Remove any CR and LF from the line. */
+ i = (int)STRLEN(line);
+ if (i > 0 && line[i - 1] == '\n')
+ line[--i] = NUL;
+ if (i > 0 && line[i - 1] == '\r')
+ line[--i] = NUL;
+ } else if (!already) {
+ if (++lnum > end_lnum)
+ break;
+ line = ml_get(lnum);
+ }
+ already = NULL;
+ }
+ /* End of big for (;;) loop. */
+
+ /* Close any files that are still open. */
+ for (i = 0; i <= depth; i++) {
+ fclose(files[i].fp);
+ vim_free(files[i].name);
+ }
+ for (i = old_files; i < max_path_depth; i++)
+ vim_free(files[i].name);
+ vim_free(files);
+
+ if (type == CHECK_PATH) {
+ if (!did_show) {
+ if (action != ACTION_SHOW_ALL)
+ MSG(_("All included files were found"));
+ else
+ MSG(_("No included files"));
+ }
+ } else if (!found
+ && action != ACTION_EXPAND
+ ) {
+ if (got_int || compl_interrupted)
+ EMSG(_(e_interr));
+ else if (type == FIND_DEFINE)
+ EMSG(_("E388: Couldn't find definition"));
+ else
+ EMSG(_("E389: Couldn't find pattern"));
+ }
+ if (action == ACTION_SHOW || action == ACTION_SHOW_ALL)
+ msg_end();
+
+fpip_end:
+ vim_free(file_line);
+ vim_regfree(regmatch.regprog);
+ vim_regfree(incl_regmatch.regprog);
+ vim_regfree(def_regmatch.regprog);
+}
+
+static void show_pat_in_path(line, type, did_show, action, fp, lnum, count)
+char_u *line;
+int type;
+int did_show;
+int action;
+FILE *fp;
+linenr_T *lnum;
+long count;
+{
+ char_u *p;
+
+ if (did_show)
+ msg_putchar('\n'); /* cursor below last one */
+ else if (!msg_silent)
+ gotocmdline(TRUE); /* cursor at status line */
+ if (got_int) /* 'q' typed at "--more--" message */
+ return;
+ for (;; ) {
+ p = line + STRLEN(line) - 1;
+ if (fp != NULL) {
+ /* We used fgets(), so get rid of newline at end */
+ if (p >= line && *p == '\n')
+ --p;
+ if (p >= line && *p == '\r')
+ --p;
+ *(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(" ");
+ }
+ msg_prt_line(line, FALSE);
+ out_flush(); /* show one line at a time */
+
+ /* Definition continues until line that doesn't end with '\' */
+ if (got_int || type != FIND_DEFINE || p < line || *p != '\\')
+ break;
+
+ if (fp != NULL) {
+ if (vim_fgets(line, LSIZE, fp)) /* end of file */
+ break;
+ ++*lnum;
+ } else {
+ if (++*lnum > curbuf->b_ml.ml_line_count)
+ break;
+ line = ml_get(*lnum);
+ }
+ msg_putchar('\n');
+ }
+}
+
+int read_viminfo_search_pattern(virp, force)
+vir_T *virp;
+int force;
+{
+ char_u *lp;
+ int idx = -1;
+ int magic = FALSE;
+ int no_scs = FALSE;
+ int off_line = FALSE;
+ int off_end = 0;
+ long off = 0;
+ int setlast = FALSE;
+ static int hlsearch_on = FALSE;
+ char_u *val;
+
+ /*
+ * Old line types:
+ * "/pat", "&pat": search/subst. pat
+ * "~/pat", "~&pat": last used search/subst. pat
+ * New line types:
+ * "~h", "~H": hlsearch highlighting off/on
+ * "~<magic><smartcase><line><end><off><last><which>pat"
+ * <magic>: 'm' off, 'M' on
+ * <smartcase>: 's' off, 'S' on
+ * <line>: 'L' line offset, 'l' char offset
+ * <end>: 'E' from end, 'e' from start
+ * <off>: decimal, offset
+ * <last>: '~' last used pattern
+ * <which>: '/' search pat, '&' subst. pat
+ */
+ lp = virp->vir_line;
+ if (lp[0] == '~' && (lp[1] == 'm' || lp[1] == 'M')) { /* new line type */
+ if (lp[1] == 'M') /* magic on */
+ magic = TRUE;
+ if (lp[2] == 's')
+ no_scs = TRUE;
+ if (lp[3] == 'L')
+ off_line = TRUE;
+ if (lp[4] == 'E')
+ off_end = SEARCH_END;
+ lp += 5;
+ off = getdigits(&lp);
+ }
+ if (lp[0] == '~') { /* use this pattern for last-used pattern */
+ setlast = TRUE;
+ lp++;
+ }
+ if (lp[0] == '/')
+ idx = RE_SEARCH;
+ else if (lp[0] == '&')
+ idx = RE_SUBST;
+ else if (lp[0] == 'h') /* ~h: 'hlsearch' highlighting off */
+ hlsearch_on = FALSE;
+ else if (lp[0] == 'H') /* ~H: 'hlsearch' highlighting on */
+ hlsearch_on = TRUE;
+ if (idx >= 0) {
+ if (force || spats[idx].pat == NULL) {
+ val = viminfo_readstring(virp, (int)(lp - virp->vir_line + 1),
+ TRUE);
+ if (val != NULL) {
+ set_last_search_pat(val, idx, magic, setlast);
+ vim_free(val);
+ spats[idx].no_scs = no_scs;
+ spats[idx].off.line = off_line;
+ spats[idx].off.end = off_end;
+ spats[idx].off.off = off;
+ if (setlast) {
+ SET_NO_HLSEARCH(!hlsearch_on);
+ }
+ }
+ }
+ }
+ return viminfo_readline(virp);
+}
+
+void write_viminfo_search_pattern(fp)
+FILE *fp;
+{
+ if (get_viminfo_parameter('/') != 0) {
+ fprintf(fp, "\n# hlsearch on (H) or off (h):\n~%c",
+ (no_hlsearch || find_viminfo_parameter('h') != NULL) ? 'h' : 'H');
+ wvsp_one(fp, RE_SEARCH, "", '/');
+ wvsp_one(fp, RE_SUBST, _("Substitute "), '&');
+ }
+}
+
+static void wvsp_one(fp, idx, s, sc)
+FILE *fp; /* file to write to */
+int idx; /* spats[] index */
+char *s; /* search pat */
+int sc; /* dir char */
+{
+ if (spats[idx].pat != NULL) {
+ fprintf(fp, _("\n# Last %sSearch Pattern:\n~"), s);
+ /* off.dir is not stored, it's reset to forward */
+ fprintf(fp, "%c%c%c%c%ld%s%c",
+ spats[idx].magic ? 'M' : 'm', /* magic */
+ spats[idx].no_scs ? 's' : 'S', /* smartcase */
+ spats[idx].off.line ? 'L' : 'l', /* line offset */
+ spats[idx].off.end ? 'E' : 'e', /* offset from end */
+ spats[idx].off.off, /* offset */
+ last_idx == idx ? "~" : "", /* last used pat */
+ sc);
+ viminfo_writestring(fp, spats[idx].pat);
+ }
+}
diff --git a/src/sha256.c b/src/sha256.c
new file mode 100644
index 0000000000..0761987ebe
--- /dev/null
+++ b/src/sha256.c
@@ -0,0 +1,417 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * 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.
+ *
+ * FIPS-180-2 compliant SHA-256 implementation
+ * GPL by Christophe Devine, applies to older version.
+ * Modified for md5deep, in public domain.
+ * Modified For Vim, Mohsin Ahmed, http://www.cs.albany.edu/~mosh
+ * Mohsin Ahmed states this work is distributed under the VIM License or GPL,
+ * at your choice.
+ *
+ * Vim specific notes:
+ * Functions exported by this file:
+ * 1. sha256_key() hashes the password to 64 bytes char string.
+ * 2. sha2_seed() generates a random header.
+ * sha256_self_test() is implicitly called once.
+ */
+
+#include "vim.h"
+
+
+static void sha256_process __ARGS((context_sha256_T *ctx, char_u data[64]));
+
+#define GET_UINT32(n, b, i) \
+ { \
+ (n) = ( (UINT32_T)(b)[(i) ] << 24) \
+ | ( (UINT32_T)(b)[(i) + 1] << 16) \
+ | ( (UINT32_T)(b)[(i) + 2] << 8) \
+ | ( (UINT32_T)(b)[(i) + 3] ); \
+ }
+
+#define PUT_UINT32(n,b,i) \
+ { \
+ (b)[(i) ] = (char_u)((n) >> 24); \
+ (b)[(i) + 1] = (char_u)((n) >> 16); \
+ (b)[(i) + 2] = (char_u)((n) >> 8); \
+ (b)[(i) + 3] = (char_u)((n) ); \
+ }
+
+void sha256_start(ctx)
+context_sha256_T *ctx;
+{
+ ctx->total[0] = 0;
+ ctx->total[1] = 0;
+
+ ctx->state[0] = 0x6A09E667;
+ ctx->state[1] = 0xBB67AE85;
+ ctx->state[2] = 0x3C6EF372;
+ ctx->state[3] = 0xA54FF53A;
+ ctx->state[4] = 0x510E527F;
+ ctx->state[5] = 0x9B05688C;
+ ctx->state[6] = 0x1F83D9AB;
+ ctx->state[7] = 0x5BE0CD19;
+}
+
+static void sha256_process(ctx, data)
+context_sha256_T *ctx;
+char_u data[64];
+{
+ UINT32_T temp1, temp2, W[64];
+ UINT32_T A, B, C, D, E, F, G, H;
+
+ GET_UINT32(W[0], data, 0);
+ GET_UINT32(W[1], data, 4);
+ GET_UINT32(W[2], data, 8);
+ GET_UINT32(W[3], data, 12);
+ GET_UINT32(W[4], data, 16);
+ GET_UINT32(W[5], data, 20);
+ GET_UINT32(W[6], data, 24);
+ GET_UINT32(W[7], data, 28);
+ GET_UINT32(W[8], data, 32);
+ GET_UINT32(W[9], data, 36);
+ GET_UINT32(W[10], data, 40);
+ GET_UINT32(W[11], data, 44);
+ GET_UINT32(W[12], data, 48);
+ GET_UINT32(W[13], data, 52);
+ GET_UINT32(W[14], data, 56);
+ GET_UINT32(W[15], data, 60);
+
+#define SHR(x, n) ((x & 0xFFFFFFFF) >> n)
+#define ROTR(x, n) (SHR(x, n) | (x << (32 - n)))
+
+#define S0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3))
+#define S1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10))
+
+#define S2(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
+#define S3(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
+
+#define F0(x, y, z) ((x & y) | (z & (x | y)))
+#define F1(x, y, z) (z ^ (x & (y ^ z)))
+
+#define R(t) \
+ ( \
+ W[t] = S1(W[t - 2]) + W[t - 7] + \
+ S0(W[t - 15]) + W[t - 16] \
+ )
+
+#define P(a,b,c,d,e,f,g,h,x,K) \
+ { \
+ temp1 = h + S3(e) + F1(e, f, g) + K + x; \
+ temp2 = S2(a) + F0(a, b, c); \
+ d += temp1; h = temp1 + temp2; \
+ }
+
+ A = ctx->state[0];
+ B = ctx->state[1];
+ C = ctx->state[2];
+ D = ctx->state[3];
+ E = ctx->state[4];
+ F = ctx->state[5];
+ G = ctx->state[6];
+ H = ctx->state[7];
+
+ P( A, B, C, D, E, F, G, H, W[ 0], 0x428A2F98);
+ P( H, A, B, C, D, E, F, G, W[ 1], 0x71374491);
+ P( G, H, A, B, C, D, E, F, W[ 2], 0xB5C0FBCF);
+ P( F, G, H, A, B, C, D, E, W[ 3], 0xE9B5DBA5);
+ P( E, F, G, H, A, B, C, D, W[ 4], 0x3956C25B);
+ P( D, E, F, G, H, A, B, C, W[ 5], 0x59F111F1);
+ P( C, D, E, F, G, H, A, B, W[ 6], 0x923F82A4);
+ P( B, C, D, E, F, G, H, A, W[ 7], 0xAB1C5ED5);
+ P( A, B, C, D, E, F, G, H, W[ 8], 0xD807AA98);
+ P( H, A, B, C, D, E, F, G, W[ 9], 0x12835B01);
+ P( G, H, A, B, C, D, E, F, W[10], 0x243185BE);
+ P( F, G, H, A, B, C, D, E, W[11], 0x550C7DC3);
+ P( E, F, G, H, A, B, C, D, W[12], 0x72BE5D74);
+ P( D, E, F, G, H, A, B, C, W[13], 0x80DEB1FE);
+ P( C, D, E, F, G, H, A, B, W[14], 0x9BDC06A7);
+ P( B, C, D, E, F, G, H, A, W[15], 0xC19BF174);
+ P( A, B, C, D, E, F, G, H, R(16), 0xE49B69C1);
+ P( H, A, B, C, D, E, F, G, R(17), 0xEFBE4786);
+ P( G, H, A, B, C, D, E, F, R(18), 0x0FC19DC6);
+ P( F, G, H, A, B, C, D, E, R(19), 0x240CA1CC);
+ P( E, F, G, H, A, B, C, D, R(20), 0x2DE92C6F);
+ P( D, E, F, G, H, A, B, C, R(21), 0x4A7484AA);
+ P( C, D, E, F, G, H, A, B, R(22), 0x5CB0A9DC);
+ P( B, C, D, E, F, G, H, A, R(23), 0x76F988DA);
+ P( A, B, C, D, E, F, G, H, R(24), 0x983E5152);
+ P( H, A, B, C, D, E, F, G, R(25), 0xA831C66D);
+ P( G, H, A, B, C, D, E, F, R(26), 0xB00327C8);
+ P( F, G, H, A, B, C, D, E, R(27), 0xBF597FC7);
+ P( E, F, G, H, A, B, C, D, R(28), 0xC6E00BF3);
+ P( D, E, F, G, H, A, B, C, R(29), 0xD5A79147);
+ P( C, D, E, F, G, H, A, B, R(30), 0x06CA6351);
+ P( B, C, D, E, F, G, H, A, R(31), 0x14292967);
+ P( A, B, C, D, E, F, G, H, R(32), 0x27B70A85);
+ P( H, A, B, C, D, E, F, G, R(33), 0x2E1B2138);
+ P( G, H, A, B, C, D, E, F, R(34), 0x4D2C6DFC);
+ P( F, G, H, A, B, C, D, E, R(35), 0x53380D13);
+ P( E, F, G, H, A, B, C, D, R(36), 0x650A7354);
+ P( D, E, F, G, H, A, B, C, R(37), 0x766A0ABB);
+ P( C, D, E, F, G, H, A, B, R(38), 0x81C2C92E);
+ P( B, C, D, E, F, G, H, A, R(39), 0x92722C85);
+ P( A, B, C, D, E, F, G, H, R(40), 0xA2BFE8A1);
+ P( H, A, B, C, D, E, F, G, R(41), 0xA81A664B);
+ P( G, H, A, B, C, D, E, F, R(42), 0xC24B8B70);
+ P( F, G, H, A, B, C, D, E, R(43), 0xC76C51A3);
+ P( E, F, G, H, A, B, C, D, R(44), 0xD192E819);
+ P( D, E, F, G, H, A, B, C, R(45), 0xD6990624);
+ P( C, D, E, F, G, H, A, B, R(46), 0xF40E3585);
+ P( B, C, D, E, F, G, H, A, R(47), 0x106AA070);
+ P( A, B, C, D, E, F, G, H, R(48), 0x19A4C116);
+ P( H, A, B, C, D, E, F, G, R(49), 0x1E376C08);
+ P( G, H, A, B, C, D, E, F, R(50), 0x2748774C);
+ P( F, G, H, A, B, C, D, E, R(51), 0x34B0BCB5);
+ P( E, F, G, H, A, B, C, D, R(52), 0x391C0CB3);
+ P( D, E, F, G, H, A, B, C, R(53), 0x4ED8AA4A);
+ P( C, D, E, F, G, H, A, B, R(54), 0x5B9CCA4F);
+ P( B, C, D, E, F, G, H, A, R(55), 0x682E6FF3);
+ P( A, B, C, D, E, F, G, H, R(56), 0x748F82EE);
+ P( H, A, B, C, D, E, F, G, R(57), 0x78A5636F);
+ P( G, H, A, B, C, D, E, F, R(58), 0x84C87814);
+ P( F, G, H, A, B, C, D, E, R(59), 0x8CC70208);
+ P( E, F, G, H, A, B, C, D, R(60), 0x90BEFFFA);
+ P( D, E, F, G, H, A, B, C, R(61), 0xA4506CEB);
+ P( C, D, E, F, G, H, A, B, R(62), 0xBEF9A3F7);
+ P( B, C, D, E, F, G, H, A, R(63), 0xC67178F2);
+
+ ctx->state[0] += A;
+ ctx->state[1] += B;
+ ctx->state[2] += C;
+ ctx->state[3] += D;
+ ctx->state[4] += E;
+ ctx->state[5] += F;
+ ctx->state[6] += G;
+ ctx->state[7] += H;
+}
+
+void sha256_update(ctx, input, length)
+context_sha256_T *ctx;
+char_u *input;
+UINT32_T length;
+{
+ UINT32_T left, fill;
+
+ if (length == 0)
+ return;
+
+ left = ctx->total[0] & 0x3F;
+ fill = 64 - left;
+
+ ctx->total[0] += length;
+ ctx->total[0] &= 0xFFFFFFFF;
+
+ if (ctx->total[0] < length)
+ ctx->total[1]++;
+
+ if (left && length >= fill) {
+ memcpy((void *)(ctx->buffer + left), (void *)input, fill);
+ sha256_process(ctx, ctx->buffer);
+ length -= fill;
+ input += fill;
+ left = 0;
+ }
+
+ while (length >= 64) {
+ sha256_process(ctx, input);
+ length -= 64;
+ input += 64;
+ }
+
+ if (length)
+ memcpy((void *)(ctx->buffer + left), (void *)input, length);
+}
+
+static char_u sha256_padding[64] = {
+ 0x80, 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
+};
+
+void sha256_finish(ctx, digest)
+context_sha256_T *ctx;
+char_u digest[32];
+{
+ UINT32_T last, padn;
+ UINT32_T high, low;
+ char_u msglen[8];
+
+ high = (ctx->total[0] >> 29) | (ctx->total[1] << 3);
+ low = (ctx->total[0] << 3);
+
+ PUT_UINT32(high, msglen, 0);
+ PUT_UINT32(low, msglen, 4);
+
+ last = ctx->total[0] & 0x3F;
+ padn = (last < 56) ? (56 - last) : (120 - last);
+
+ sha256_update(ctx, sha256_padding, padn);
+ sha256_update(ctx, msglen, 8);
+
+ PUT_UINT32(ctx->state[0], digest, 0);
+ PUT_UINT32(ctx->state[1], digest, 4);
+ PUT_UINT32(ctx->state[2], digest, 8);
+ PUT_UINT32(ctx->state[3], digest, 12);
+ PUT_UINT32(ctx->state[4], digest, 16);
+ PUT_UINT32(ctx->state[5], digest, 20);
+ PUT_UINT32(ctx->state[6], digest, 24);
+ PUT_UINT32(ctx->state[7], digest, 28);
+}
+
+static unsigned int get_some_time __ARGS((void));
+
+/*
+ * 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(buf, buf_len, salt, salt_len)
+char_u *buf;
+int buf_len;
+char_u *salt;
+int salt_len;
+{
+ char_u sha256sum[32];
+ static char_u hexit[65];
+ int j;
+ context_sha256_T ctx;
+
+ sha256_self_test();
+
+ sha256_start(&ctx);
+ sha256_update(&ctx, buf, buf_len);
+ if (salt != NULL)
+ sha256_update(&ctx, salt, salt_len);
+ sha256_finish(&ctx, sha256sum);
+ for (j = 0; j < 32; j++)
+ sprintf((char *)hexit + j * 2, "%02x", sha256sum[j]);
+ hexit[sizeof(hexit) - 1] = '\0';
+ return hexit;
+}
+
+/*
+ * Returns sha256(buf) as 64 hex chars in static array.
+ */
+char_u * sha256_key(buf, salt, salt_len)
+char_u *buf;
+char_u *salt;
+int salt_len;
+{
+ /* No passwd means don't encrypt */
+ if (buf == NULL || *buf == NUL)
+ return (char_u *)"";
+
+ return sha256_bytes(buf, (int)STRLEN(buf), salt, salt_len);
+}
+
+/*
+ * These are the standard FIPS-180-2 test vectors
+ */
+
+static char *sha_self_test_msg[] = {
+ "abc",
+ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+ NULL
+};
+
+static char *sha_self_test_vector[] = {
+ "ba7816bf8f01cfea414140de5dae2223" \
+ "b00361a396177a9cb410ff61f20015ad",
+ "248d6a61d20638b8e5c026930c3e6039" \
+ "a33ce45964ff2167f6ecedd419db06c1",
+ "cdc76e5c9914fb9281a1c7e284d73e67" \
+ "f1809a48a497200e046d39ccc7112cd0"
+};
+
+/*
+ * Perform a test on the SHA256 algorithm.
+ * Return FAIL or OK.
+ */
+int sha256_self_test() {
+ int i, j;
+ char output[65];
+ context_sha256_T ctx;
+ char_u buf[1000];
+ char_u sha256sum[32];
+ static int failures = 0;
+ char_u *hexit;
+ static int sha256_self_tested = 0;
+
+ if (sha256_self_tested > 0)
+ return failures > 0 ? FAIL : OK;
+ sha256_self_tested = 1;
+
+ for (i = 0; i < 3; i++) {
+ if (i < 2) {
+ hexit = sha256_bytes((char_u *)sha_self_test_msg[i],
+ (int)STRLEN(sha_self_test_msg[i]),
+ NULL, 0);
+ STRCPY(output, hexit);
+ } else {
+ sha256_start(&ctx);
+ vim_memset(buf, 'a', 1000);
+ for (j = 0; j < 1000; j++)
+ sha256_update(&ctx, (char_u *)buf, 1000);
+ sha256_finish(&ctx, sha256sum);
+ for (j = 0; j < 32; j++)
+ sprintf(output + j * 2, "%02x", sha256sum[j]);
+ }
+ if (memcmp(output, sha_self_test_vector[i], 64)) {
+ failures++;
+ output[sizeof(output) - 1] = '\0';
+ /* printf("sha256_self_test %d failed %s\n", i, output); */
+ }
+ }
+ return failures > 0 ? FAIL : OK;
+}
+
+static unsigned int get_some_time() {
+# ifdef HAVE_GETTIMEOFDAY
+ struct timeval tv;
+
+ /* Using usec makes it less predictable. */
+ gettimeofday(&tv, NULL);
+ return (unsigned int)(tv.tv_sec + tv.tv_usec);
+# else
+ return (unsigned int)time(NULL);
+# endif
+}
+
+/*
+ * Fill "header[header_len]" with random_data.
+ * Also "salt[salt_len]" when "salt" is not NULL.
+ */
+void sha2_seed(header, header_len, salt, salt_len)
+char_u *header;
+int header_len;
+char_u *salt;
+int salt_len;
+{
+ int i;
+ static char_u random_data[1000];
+ char_u sha256sum[32];
+ context_sha256_T ctx;
+
+ srand(get_some_time());
+
+ for (i = 0; i < (int)sizeof(random_data) - 1; i++)
+ random_data[i] = (char_u)((get_some_time() ^ rand()) & 0xff);
+ sha256_start(&ctx);
+ sha256_update(&ctx, (char_u *)random_data, sizeof(random_data));
+ sha256_finish(&ctx, sha256sum);
+
+ /* put first block into header. */
+ for (i = 0; i < header_len; i++)
+ header[i] = sha256sum[i % sizeof(sha256sum)];
+
+ /* put remaining block into salt. */
+ if (salt != NULL)
+ for (i = 0; i < salt_len; i++)
+ salt[i] = sha256sum[(i + header_len) % sizeof(sha256sum)];
+}
+
diff --git a/src/spell.c b/src/spell.c
new file mode 100644
index 0000000000..05c6543ef6
--- /dev/null
+++ b/src/spell.c
@@ -0,0 +1,14426 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * 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.
+ */
+
+/*
+ * spell.c: code for spell checking
+ *
+ * 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).
+ *
+ * A NUL byte is used where the word may end. The bytes are sorted, so that
+ * binary searching can be used and the NUL bytes are at the start. The
+ * number of possible bytes is stored before the list of bytes.
+ *
+ * The tree uses two arrays: "byts" stores the characters, "idxs" stores
+ * either the next index or flags. The tree starts at index 0. For example,
+ * to lookup "vi" this sequence is followed:
+ * i = 0
+ * len = byts[i]
+ * n = where "v" appears in byts[i + 1] to byts[i + len]
+ * i = idxs[n]
+ * len = byts[i]
+ * n = where "i" appears in byts[i + 1] to byts[i + len]
+ * i = idxs[n]
+ * len = byts[i]
+ * find that byts[i + 1] is 0, idxs[i + 1] has flags for "vi".
+ *
+ * There are two word trees: one with case-folded words and one with words in
+ * original case. The second one is only used for keep-case words and is
+ * usually small.
+ *
+ * There is one additional tree for when not all prefixes are applied when
+ * generating the .spl file. This tree stores all the possible prefixes, as
+ * if they were words. At each word (prefix) end the prefix nr is stored, the
+ * following word must support this prefix nr. And the condition nr is
+ * stored, used to lookup the condition that the word must match with.
+ *
+ * Thanks to Olaf Seibert for providing an example implementation of this tree
+ * and the compression mechanism.
+ * LZ trie ideas:
+ * http://www.irb.hr/hr/home/ristov/papers/RistovLZtrieRevision1.pdf
+ * More papers: http://www-igm.univ-mlv.fr/~laporte/publi_en.html
+ *
+ * Matching involves checking the caps type: Onecap ALLCAP KeepCap.
+ *
+ * Why doesn't Vim use aspell/ispell/myspell/etc.?
+ * See ":help develop-spell".
+ */
+
+/* Use SPELL_PRINTTREE for debugging: dump the word tree after adding a word.
+ * Only use it for small word lists! */
+
+/* Use DEBUG_TRIEWALK to print the changes made in suggest_trie_walk() for a
+ * specific word. */
+
+/*
+ * Use this to adjust the score after finding suggestions, based on the
+ * suggested word sounding like the bad word. This is much faster than doing
+ * it for every possible suggestion.
+ * Disadvantage: When "the" is typed as "hte" it sounds quite different ("@"
+ * vs "ht") and goes down in the list.
+ * Used when 'spellsuggest' is set to "best".
+ */
+#define RESCORE(word_score, sound_score) ((3 * word_score + sound_score) / 4)
+
+/*
+ * Do the opposite: based on a maximum end score and a known sound score,
+ * 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_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 "vim.h"
+
+
+#ifndef UNIX /* it's in os_unix.h for Unix */
+# include <time.h> /* for time_t */
+#endif
+
+#define MAXWLEN 250 /* 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? */
+#if SIZEOF_INT > 3
+typedef int idx_T;
+#else
+typedef long idx_T;
+#endif
+
+# 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 */
+ int 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 */
+ char_u 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 */
+ short 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 */
+ int sl_followup; /* SAL followup */
+ int sl_collapse; /* SAL collapse_result */
+ int sl_rem_accents; /* SAL remove_accents */
+ int 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 */
+ short sl_repsal_first[256]; /* sl_rep_first for REPSAL lines */
+ int sl_nosplitsugs; /* don't suggest splitting a word */
+
+ /* 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 */
+ int sl_sugloaded; /* TRUE when .sug file was loaded or failed to
+ load */
+
+ int 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_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_OK 0
+#define SP_RARE 1
+#define SP_LOCAL 2
+#define SP_BAD 3
+
+/* file used for "zG" and "zW" */
+static char_u *int_wordlist = NULL;
+
+typedef struct wordcount_S {
+ short_u 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 MAXWORDCOUNT 0xffff
+
+/*
+ * Information used when looking for suggestions.
+ */
+typedef struct suginfo_S {
+ garray_T su_ga; /* suggestions, contains "suggest_T" */
+ int su_maxcount; /* max. number of suggestions displayed */
+ int su_maxscore; /* maximum score for adding to su_ga */
+ int su_sfmaxscore; /* idem, for when doing soundfold words */
+ garray_T su_sga; /* like su_ga, sound-folded scoring */
+ char_u *su_badptr; /* start of bad word in line */
+ int su_badlen; /* length of detected bad word in line */
+ int su_badflags; /* caps flags for bad word */
+ char_u su_badword[MAXWLEN]; /* bad word truncated at su_badlen */
+ char_u su_fbadword[MAXWLEN]; /* su_badword case-folded */
+ char_u su_sal_badword[MAXWLEN]; /* su_badword soundfolded */
+ hashtab_T su_banned; /* table with banned words */
+ slang_T *su_sallang; /* default language for sound folding */
+} suginfo_T;
+
+/* One word suggestion. Used in "si_ga". */
+typedef struct suggest_S {
+ char_u *st_word; /* suggested word, allocated string */
+ int st_wordlen; /* STRLEN(st_word) */
+ int st_orglen; /* length of replaced text */
+ int st_score; /* lower is better */
+ int st_altscore; /* used when st_score compares equal */
+ int st_salscore; /* st_score is for soundalike */
+ int st_had_bonus; /* bonus already included in score */
+ slang_T *st_slang; /* language used for sound folding */
+} suggest_T;
+
+#define SUG(ga, i) (((suggest_T *)(ga).ga_data)[i])
+
+/* TRUE if a word appears in the list of banned words. */
+#define WAS_BANNED(su, word) (!HASHITEM_EMPTY(hash_find(&su->su_banned, word)))
+
+/* Number of suggestions kept when cleaning up. We need to keep more than
+ * what is displayed, because when rescore_suggestions() is called the score
+ * may change and wrong suggestions may be removed later. */
+#define SUG_CLEAN_COUNT(su) ((su)->su_maxcount < \
+ 130 ? 150 : (su)->su_maxcount + 20)
+
+/* Threshold for sorting and cleaning up suggestions. Don't want to keep lots
+ * of suggestions that are not going to be displayed. */
+#define SUG_MAX_COUNT(su) (SUG_CLEAN_COUNT(su) + 50)
+
+/* score for various changes */
+#define SCORE_SPLIT 149 /* split bad word */
+#define SCORE_SPLIT_NO 249 /* split bad word with NOSPLITSUGS */
+#define SCORE_ICASE 52 /* slightly different case */
+#define SCORE_REGION 200 /* word is for different region */
+#define SCORE_RARE 180 /* rare word */
+#define SCORE_SWAP 75 /* swap two characters */
+#define SCORE_SWAP3 110 /* swap two characters in three */
+#define SCORE_REP 65 /* REP replacement */
+#define SCORE_SUBST 93 /* substitute a character */
+#define SCORE_SIMILAR 33 /* substitute a similar character */
+#define SCORE_SUBCOMP 33 /* substitute a composing character */
+#define SCORE_DEL 94 /* delete a character */
+#define SCORE_DELDUP 66 /* delete a duplicated character */
+#define SCORE_DELCOMP 28 /* delete a composing character */
+#define SCORE_INS 96 /* insert a character */
+#define SCORE_INSDUP 67 /* insert a duplicate character */
+#define SCORE_INSCOMP 30 /* insert a composing character */
+#define SCORE_NONWORD 103 /* change non-word to word char */
+
+#define SCORE_FILE 30 /* suggestion from a file */
+#define SCORE_MAXINIT 350 /* Initial maximum score: higher == slower.
+ * 350 allows for about three changes. */
+
+#define SCORE_COMMON1 30 /* subtracted for words seen before */
+#define SCORE_COMMON2 40 /* subtracted for words often seen */
+#define SCORE_COMMON3 50 /* subtracted for words very often seen */
+#define SCORE_THRES2 10 /* word count threshold for COMMON2 */
+#define SCORE_THRES3 100 /* word count threshold for COMMON3 */
+
+/* When trying changed soundfold words it becomes slow when trying more than
+ * two changes. With less then two changes it's slightly faster but we miss a
+ * few good suggestions. In rare cases we need to try three of four changes.
+ */
+#define SCORE_SFMAX1 200 /* maximum score for first try */
+#define SCORE_SFMAX2 300 /* maximum score for second try */
+#define SCORE_SFMAX3 400 /* maximum score for third try */
+
+#define SCORE_BIG SCORE_INS * 3 /* big difference */
+#define SCORE_MAXMAX 999999 /* accept any score */
+#define SCORE_LIMITMAX 350 /* for spell_edit_score_limit() */
+
+/* for spell_edit_score_limit() we need to know the minimum value of
+* SCORE_ICASE, SCORE_SWAP, SCORE_DEL, SCORE_SIMILAR and SCORE_INS */
+#define SCORE_EDIT_MIN SCORE_SIMILAR
+
+/*
+ * Structure to store info for word matching.
+ */
+typedef struct matchinf_S {
+ langp_T *mi_lp; /* info for language and region */
+
+ /* pointers to original text to be checked */
+ char_u *mi_word; /* start of word being checked */
+ char_u *mi_end; /* end of matching word so far */
+ char_u *mi_fend; /* next char to be added to mi_fword */
+ char_u *mi_cend; /* char after what was used for
+ mi_capflags */
+
+ /* case-folded text */
+ char_u mi_fword[MAXWLEN + 1]; /* mi_word case-folded */
+ int mi_fwordlen; /* nr of valid bytes in mi_fword */
+
+ /* for when checking word after a prefix */
+ int mi_prefarridx; /* index in sl_pidxs with list of
+ affixID/condition */
+ int mi_prefcnt; /* number of entries at mi_prefarridx */
+ int mi_prefixlen; /* byte length of prefix */
+ int mi_cprefixlen; /* byte length of prefix in original
+ case */
+
+ /* for when checking a compound word */
+ int mi_compoff; /* start of following word offset */
+ char_u mi_compflags[MAXWLEN]; /* flags for compound words used */
+ int mi_complen; /* nr of compound words used */
+ int mi_compextra; /* nr of COMPOUNDROOT words */
+
+ /* others */
+ int mi_result; /* result so far: SP_BAD, SP_OK, etc. */
+ int mi_capflags; /* WF_ONECAP WF_ALLCAP WF_KEEPCAP */
+ win_T *mi_win; /* buffer being checked */
+
+ /* for NOBREAK */
+ int mi_result2; /* "mi_resul" without following word */
+ 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 spelltab_S {
+ char_u st_isw[256]; /* flags: is word char */
+ char_u 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;
+
+static spelltab_T spelltab;
+static int did_set_spelltab;
+
+#define CF_WORD 0x01
+#define CF_UPPER 0x02
+
+static void clear_spell_chartab __ARGS((spelltab_T *sp));
+static int set_spell_finish __ARGS((spelltab_T *new_st));
+static int spell_iswordp __ARGS((char_u *p, win_T *wp));
+static int spell_iswordp_nmw __ARGS((char_u *p, win_T *wp));
+static int spell_mb_isword_class __ARGS((int cl, win_T *wp));
+static int spell_iswordp_w __ARGS((int *p, win_T *wp));
+static int write_spell_prefcond __ARGS((FILE *fd, garray_T *gap));
+
+/*
+ * 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;
+
+/* values for ts_isdiff */
+#define DIFF_NONE 0 /* no different byte (yet) */
+#define DIFF_YES 1 /* different byte found */
+#define DIFF_INSERT 2 /* inserting character */
+
+/* values for ts_flags */
+#define TSF_PREFIXOK 1 /* already checked that prefix is OK */
+#define TSF_DIDSPLIT 2 /* tried split at this point */
+#define TSF_DIDDEL 4 /* did a delete, "ts_delidx" has index */
+
+/* special values ts_prefixdepth */
+#define PFD_NOPREFIX 0xff /* not using prefixes */
+#define PFD_PREFIXTREE 0xfe /* walking through the prefix tree */
+#define PFD_NOTSPECIAL 0xfd /* highest value that's not special */
+
+/* mode values for find_word */
+#define FIND_FOLDWORD 0 /* find word case-folded */
+#define FIND_KEEPWORD 1 /* find keep-case word */
+#define FIND_PREFIX 2 /* find word after prefix */
+#define FIND_COMPOUND 3 /* find case-folded compound word */
+#define FIND_KEEPCOMPOUND 4 /* find keep-case compound word */
+
+static slang_T *slang_alloc __ARGS((char_u *lang));
+static void slang_free __ARGS((slang_T *lp));
+static void slang_clear __ARGS((slang_T *lp));
+static void slang_clear_sug __ARGS((slang_T *lp));
+static void find_word __ARGS((matchinf_T *mip, int mode));
+static int match_checkcompoundpattern __ARGS((char_u *ptr, int wlen,
+ garray_T *gap));
+static int can_compound __ARGS((slang_T *slang, char_u *word, char_u *flags));
+static int can_be_compound __ARGS((trystate_T *sp, slang_T *slang, char_u *
+ compflags,
+ int flag));
+static int match_compoundrule __ARGS((slang_T *slang, char_u *compflags));
+static int valid_word_prefix __ARGS((int totprefcnt, int arridx, int flags,
+ char_u *word, slang_T *slang,
+ int cond_req));
+static void find_prefix __ARGS((matchinf_T *mip, int mode));
+static int fold_more __ARGS((matchinf_T *mip));
+static int spell_valid_case __ARGS((int wordflags, int treeflags));
+static int no_spell_checking __ARGS((win_T *wp));
+static void spell_load_lang __ARGS((char_u *lang));
+static char_u *spell_enc __ARGS((void));
+static void int_wordlist_spl __ARGS((char_u *fname));
+static void spell_load_cb __ARGS((char_u *fname, void *cookie));
+static slang_T *spell_load_file __ARGS((char_u *fname, char_u *lang, slang_T *
+ old_lp,
+ int silent));
+static char_u *read_cnt_string __ARGS((FILE *fd, int cnt_bytes, int *lenp));
+static int read_region_section __ARGS((FILE *fd, slang_T *slang, int len));
+static int read_charflags_section __ARGS((FILE *fd));
+static int read_prefcond_section __ARGS((FILE *fd, slang_T *lp));
+static int read_rep_section __ARGS((FILE *fd, garray_T *gap, short *first));
+static int read_sal_section __ARGS((FILE *fd, slang_T *slang));
+static int read_words_section __ARGS((FILE *fd, slang_T *lp, int len));
+static void count_common_word __ARGS((slang_T *lp, char_u *word, int len,
+ int count));
+static int score_wordcount_adj __ARGS((slang_T *slang, int score, char_u *word,
+ int split));
+static int read_sofo_section __ARGS((FILE *fd, slang_T *slang));
+static int read_compound __ARGS((FILE *fd, slang_T *slang, int len));
+static int byte_in_str __ARGS((char_u *str, int byte));
+static int init_syl_tab __ARGS((slang_T *slang));
+static int count_syllables __ARGS((slang_T *slang, char_u *word));
+static int set_sofo __ARGS((slang_T *lp, char_u *from, char_u *to));
+static void set_sal_first __ARGS((slang_T *lp));
+static int *mb_str2wide __ARGS((char_u *s));
+static int spell_read_tree __ARGS((FILE *fd, char_u **bytsp, idx_T **idxsp,
+ int prefixtree,
+ int prefixcnt));
+static idx_T read_tree_node __ARGS((FILE *fd, char_u *byts, idx_T *idxs,
+ int maxidx, idx_T startidx, int prefixtree,
+ int maxprefcondnr));
+static void clear_midword __ARGS((win_T *buf));
+static void use_midword __ARGS((slang_T *lp, win_T *buf));
+static int find_region __ARGS((char_u *rp, char_u *region));
+static int captype __ARGS((char_u *word, char_u *end));
+static int badword_captype __ARGS((char_u *word, char_u *end));
+static void spell_reload_one __ARGS((char_u *fname, int added_word));
+static void set_spell_charflags __ARGS((char_u *flags, int cnt, char_u *upp));
+static int set_spell_chartab __ARGS((char_u *fol, char_u *low, char_u *upp));
+static int spell_casefold __ARGS((char_u *p, int len, char_u *buf, int buflen));
+static int check_need_cap __ARGS((linenr_T lnum, colnr_T col));
+static void spell_find_suggest __ARGS((char_u *badptr, int badlen, suginfo_T *
+ su, int maxcount, int banbadword,
+ int need_cap,
+ int interactive));
+static void spell_suggest_expr __ARGS((suginfo_T *su, char_u *expr));
+static void spell_suggest_file __ARGS((suginfo_T *su, char_u *fname));
+static void spell_suggest_intern __ARGS((suginfo_T *su, int interactive));
+static void suggest_load_files __ARGS((void));
+static void tree_count_words __ARGS((char_u *byts, idx_T *idxs));
+static void spell_find_cleanup __ARGS((suginfo_T *su));
+static void onecap_copy __ARGS((char_u *word, char_u *wcopy, int upper));
+static void allcap_copy __ARGS((char_u *word, char_u *wcopy));
+static void suggest_try_special __ARGS((suginfo_T *su));
+static void suggest_try_change __ARGS((suginfo_T *su));
+static void suggest_trie_walk __ARGS((suginfo_T *su, langp_T *lp, char_u *fword,
+ int soundfold));
+static void go_deeper __ARGS((trystate_T *stack, int depth, int score_add));
+static int nofold_len __ARGS((char_u *fword, int flen, char_u *word));
+static void find_keepcap_word __ARGS((slang_T *slang, char_u *fword,
+ char_u *kword));
+static void score_comp_sal __ARGS((suginfo_T *su));
+static void score_combine __ARGS((suginfo_T *su));
+static int stp_sal_score __ARGS((suggest_T *stp, suginfo_T *su, slang_T *slang,
+ char_u *badsound));
+static void suggest_try_soundalike_prep __ARGS((void));
+static void suggest_try_soundalike __ARGS((suginfo_T *su));
+static void suggest_try_soundalike_finish __ARGS((void));
+static void add_sound_suggest __ARGS((suginfo_T *su, char_u *goodword,
+ int score,
+ langp_T *lp));
+static int soundfold_find __ARGS((slang_T *slang, char_u *word));
+static void make_case_word __ARGS((char_u *fword, char_u *cword, int flags));
+static void set_map_str __ARGS((slang_T *lp, char_u *map));
+static int similar_chars __ARGS((slang_T *slang, int c1, int c2));
+static void add_suggestion __ARGS((suginfo_T *su, garray_T *gap, char_u *
+ goodword, int badlen, int score,
+ int altscore, int had_bonus, slang_T *slang,
+ int maxsf));
+static void check_suggestions __ARGS((suginfo_T *su, garray_T *gap));
+static void add_banned __ARGS((suginfo_T *su, char_u *word));
+static void rescore_suggestions __ARGS((suginfo_T *su));
+static void rescore_one __ARGS((suginfo_T *su, suggest_T *stp));
+static int cleanup_suggestions __ARGS((garray_T *gap, int maxscore, int keep));
+static void spell_soundfold __ARGS((slang_T *slang, char_u *inword, int folded,
+ char_u *res));
+static void spell_soundfold_sofo __ARGS((slang_T *slang, char_u *inword,
+ char_u *res));
+static void spell_soundfold_sal __ARGS((slang_T *slang, char_u *inword,
+ char_u *res));
+static void spell_soundfold_wsal __ARGS((slang_T *slang, char_u *inword,
+ char_u *res));
+static int soundalike_score __ARGS((char_u *goodsound, char_u *badsound));
+static int spell_edit_score __ARGS((slang_T *slang, char_u *badword,
+ char_u *goodword));
+static int spell_edit_score_limit __ARGS((slang_T *slang, char_u *badword,
+ char_u *goodword,
+ int limit));
+static int spell_edit_score_limit_w __ARGS((slang_T *slang, char_u *badword,
+ char_u *goodword,
+ int limit));
+static void dump_word __ARGS((slang_T *slang, char_u *word, char_u *pat,
+ int *dir, int round, int flags,
+ linenr_T lnum));
+static linenr_T dump_prefixes __ARGS((slang_T *slang, char_u *word, char_u *pat,
+ int *dir, int round, int flags,
+ linenr_T startlnum));
+static buf_T *open_spellbuf __ARGS((void));
+static void close_spellbuf __ARGS((buf_T *buf));
+
+/*
+ * 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!
+ */
+# if defined(HAVE_WCHAR_H)
+# include <wchar.h> /* for towupper() and towlower() */
+# endif
+/* 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 if available. */
+# ifdef HAVE_TOWLOWER
+# define SPELL_TOFOLD(c) (enc_utf8 && (c) >= 128 ? utf_fold(c) \
+ : (c) < \
+ 256 ? (int)spelltab.st_fold[c] : (int)towlower(c))
+# else
+# define SPELL_TOFOLD(c) (enc_utf8 && (c) >= 128 ? utf_fold(c) \
+ : (c) < 256 ? (int)spelltab.st_fold[c] : (c))
+# endif
+
+# ifdef HAVE_TOWUPPER
+# define SPELL_TOUPPER(c) (enc_utf8 && (c) >= 128 ? utf_toupper(c) \
+ : (c) < \
+ 256 ? (int)spelltab.st_upper[c] : (int)towupper(c))
+# else
+# define SPELL_TOUPPER(c) (enc_utf8 && (c) >= 128 ? utf_toupper(c) \
+ : (c) < 256 ? (int)spelltab.st_upper[c] : (c))
+# endif
+
+# ifdef HAVE_ISWUPPER
+# define SPELL_ISUPPER(c) (enc_utf8 && (c) >= 128 ? utf_isupper(c) \
+ : (c) < 256 ? spelltab.st_isu[c] : iswupper(c))
+# else
+# define SPELL_ISUPPER(c) (enc_utf8 && (c) >= 128 ? utf_isupper(c) \
+ : (c) < 256 ? spelltab.st_isu[c] : (FALSE))
+# endif
+
+
+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...");
+
+/* Remember what "z?" replaced. */
+static char_u *repl_from = NULL;
+static char_u *repl_to = NULL;
+
+/*
+ * Main spell-checking function.
+ * "ptr" points to a character that could be the start of a word.
+ * "*attrp" is set to the highlight index for a badly spelled word. For a
+ * non-word or when it's OK it remains unchanged.
+ * This must only be called when 'spelllang' is not empty.
+ *
+ * "capcol" is used to check for a Capitalised word after the end of a
+ * sentence. If it's zero then perform the check. Return the column where to
+ * check next, or -1 when no sentence end was found. If it's NULL then don't
+ * worry.
+ *
+ * Returns the length of the word in bytes, also when it's OK, so that the
+ * caller can skip over the word.
+ */
+int spell_check(wp, ptr, attrp, capcol, docount)
+win_T *wp; /* current window */
+char_u *ptr;
+hlf_T *attrp;
+int *capcol; /* column to check for Capital */
+int docount; /* count good words */
+{
+ matchinf_T mi; /* Most things are put in "mi" so that it can
+ be passed to functions quickly. */
+ int nrlen = 0; /* found a number first */
+ int c;
+ int wrongcaplen = 0;
+ int lpi;
+ int count_word = docount;
+
+ /* A word never starts at a space or a control character. Return quickly
+ * then, skipping over the character. */
+ if (*ptr <= ' ')
+ return 1;
+
+ /* Return here when loading language files failed. */
+ if (wp->w_s->b_langp.ga_len == 0)
+ return 1;
+
+ vim_memset(&mi, 0, sizeof(matchinf_T));
+
+ /* A number is always OK. Also skip hexadecimal numbers 0xFF99 and
+ * 0X99FF. But always do check spelling to find "3GPP" and "11
+ * julifeest". */
+ if (*ptr >= '0' && *ptr <= '9') {
+ if (*ptr == '0' && (ptr[1] == 'x' || ptr[1] == 'X'))
+ mi.mi_end = skiphex(ptr + 2);
+ else
+ mi.mi_end = skipdigits(ptr);
+ nrlen = (int)(mi.mi_end - ptr);
+ }
+
+ /* Find the normal end of the word (until the next non-word character). */
+ mi.mi_word = ptr;
+ mi.mi_fend = ptr;
+ if (spell_iswordp(mi.mi_fend, wp)) {
+ do {
+ 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) {
+ /* Check word starting with capital letter. */
+ c = PTR2CHAR(ptr);
+ if (!SPELL_ISUPPER(c))
+ wrongcaplen = (int)(mi.mi_fend - ptr);
+ }
+ }
+ if (capcol != NULL)
+ *capcol = -1;
+
+ /* We always use the characters up to the next non-word character,
+ * also for bad words. */
+ mi.mi_end = mi.mi_fend;
+
+ /* Check caps type later. */
+ mi.mi_capflags = 0;
+ mi.mi_cend = NULL;
+ mi.mi_win = wp;
+
+ /* 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);
+
+ (void)spell_casefold(ptr, (int)(mi.mi_fend - ptr), mi.mi_fword,
+ MAXWLEN + 1);
+ mi.mi_fwordlen = (int)STRLEN(mi.mi_fword);
+
+ /* The word is bad unless we recognize it. */
+ mi.mi_result = SP_BAD;
+ mi.mi_result2 = SP_BAD;
+
+ /*
+ * Loop over the languages specified in 'spelllang'.
+ * We check them all, because a word may be matched longer in another
+ * language.
+ */
+ for (lpi = 0; lpi < wp->w_s->b_langp.ga_len; ++lpi) {
+ mi.mi_lp = LANGP_ENTRY(wp->w_s->b_langp, lpi);
+
+ /* If reloading fails the language is still in the list but everything
+ * has been cleared. */
+ if (mi.mi_lp->lp_slang->sl_fidxs == NULL)
+ continue;
+
+ /* Check for a matching word in case-folded words. */
+ find_word(&mi, FIND_FOLDWORD);
+
+ /* Check for a matching word in keep-case words. */
+ find_word(&mi, FIND_KEEPWORD);
+
+ /* Check for matching prefixes. */
+ find_prefix(&mi, FIND_FOLDWORD);
+
+ /* For a NOBREAK language, may want to use a word without a following
+ * word as a backup. */
+ if (mi.mi_lp->lp_slang->sl_nobreak && mi.mi_result == SP_BAD
+ && mi.mi_result2 != SP_BAD) {
+ mi.mi_result = mi.mi_result2;
+ mi.mi_end = mi.mi_end2;
+ }
+
+ /* Count the word in the first language where it's found to be OK. */
+ if (count_word && mi.mi_result == SP_OK) {
+ count_common_word(mi.mi_lp->lp_slang, ptr,
+ (int)(mi.mi_end - ptr), 1);
+ count_word = FALSE;
+ }
+ }
+
+ if (mi.mi_result != SP_OK) {
+ /* If we found a number skip over it. Allows for "42nd". Do flag
+ * rare and local words, e.g., "3GPP". */
+ if (nrlen > 0) {
+ if (mi.mi_result == SP_BAD || mi.mi_result == SP_BANNED)
+ return nrlen;
+ }
+ /* When we are at a non-word character there is no error, just
+ * skip over the character (try looking for a word after it). */
+ else if (!spell_iswordp_nmw(ptr, wp)) {
+ if (capcol != NULL && wp->w_s->b_cap_prog != NULL) {
+ regmatch_T regmatch;
+
+ /* Check for end of sentence. */
+ regmatch.regprog = wp->w_s->b_cap_prog;
+ regmatch.rm_ic = FALSE;
+ if (vim_regexec(&regmatch, ptr, 0))
+ *capcol = (int)(regmatch.endp[0] - ptr);
+ }
+
+ if (has_mbyte)
+ return (*mb_ptr2len)(ptr);
+ return 1;
+ } 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);
+ else if (mi.mi_result == SP_BAD
+ && LANGP_ENTRY(wp->w_s->b_langp, 0)->lp_slang->sl_nobreak) {
+ char_u *p, *fp;
+ int save_result = mi.mi_result;
+
+ /* First language in 'spelllang' is NOBREAK. Find first position
+ * at which any word would be valid. */
+ mi.mi_lp = LANGP_ENTRY(wp->w_s->b_langp, 0);
+ if (mi.mi_lp->lp_slang->sl_fidxs != NULL) {
+ p = mi.mi_word;
+ fp = mi.mi_fword;
+ for (;; ) {
+ mb_ptr_adv(p);
+ mb_ptr_adv(fp);
+ if (p >= mi.mi_end)
+ break;
+ mi.mi_compoff = (int)(fp - mi.mi_fword);
+ find_word(&mi, FIND_COMPOUND);
+ if (mi.mi_result != SP_BAD) {
+ mi.mi_end = p;
+ break;
+ }
+ }
+ mi.mi_result = save_result;
+ }
+ }
+
+ if (mi.mi_result == SP_BAD || mi.mi_result == SP_BANNED)
+ *attrp = HLF_SPB;
+ else if (mi.mi_result == SP_RARE)
+ *attrp = HLF_SPR;
+ else
+ *attrp = HLF_SPL;
+ }
+
+ if (wrongcaplen > 0 && (mi.mi_result == SP_OK || mi.mi_result == SP_RARE)) {
+ /* Report SpellCap only when the word isn't badly spelled. */
+ *attrp = HLF_SPC;
+ return wrongcaplen;
+ }
+
+ return (int)(mi.mi_end - ptr);
+}
+
+/*
+ * Check if the word at "mip->mi_word" is in the tree.
+ * When "mode" is FIND_FOLDWORD check in fold-case word tree.
+ * When "mode" is FIND_KEEPWORD check in keep-case word tree.
+ * When "mode" is FIND_PREFIX check for word after prefix in fold-case word
+ * tree.
+ *
+ * For a match mip->mi_result is updated.
+ */
+static void find_word(mip, mode)
+matchinf_T *mip;
+int mode;
+{
+ idx_T arridx = 0;
+ int endlen[MAXWLEN]; /* length at possible word endings */
+ idx_T endidx[MAXWLEN]; /* possible word endings */
+ int endidxcnt = 0;
+ int len;
+ int wlen = 0;
+ int flen;
+ int c;
+ char_u *ptr;
+ idx_T lo, hi, m;
+ char_u *s;
+ char_u *p;
+ int res = SP_BAD;
+ slang_T *slang = mip->mi_lp->lp_slang;
+ unsigned flags;
+ char_u *byts;
+ idx_T *idxs;
+ int word_ends;
+ int prefix_found;
+ int nobreak_result;
+
+ if (mode == FIND_KEEPWORD || mode == FIND_KEEPCOMPOUND) {
+ /* Check for word with matching case in keep-case tree. */
+ ptr = mip->mi_word;
+ flen = 9999; /* no case folding, always enough bytes */
+ byts = slang->sl_kbyts;
+ idxs = slang->sl_kidxs;
+
+ if (mode == FIND_KEEPCOMPOUND)
+ /* Skip over the previously found word(s). */
+ wlen += mip->mi_compoff;
+ } else {
+ /* Check for case-folded in case-folded tree. */
+ ptr = mip->mi_fword;
+ flen = mip->mi_fwordlen; /* available case-folded bytes */
+ byts = slang->sl_fbyts;
+ idxs = slang->sl_fidxs;
+
+ if (mode == FIND_PREFIX) {
+ /* Skip over the prefix. */
+ wlen = mip->mi_prefixlen;
+ flen -= mip->mi_prefixlen;
+ } else if (mode == FIND_COMPOUND) {
+ /* Skip over the previously found word(s). */
+ wlen = mip->mi_compoff;
+ flen -= mip->mi_compoff;
+ }
+
+ }
+
+ if (byts == NULL)
+ return; /* array is empty */
+
+ /*
+ * Repeat advancing in the tree until:
+ * - there is a byte that doesn't match,
+ * - we reach the end of the tree,
+ * - or we reach the end of the line.
+ */
+ for (;; ) {
+ if (flen <= 0 && *mip->mi_fend != NUL)
+ flen = fold_more(mip);
+
+ len = byts[arridx++];
+
+ /* If the first possible byte is a zero the word could end here.
+ * Remember this index, we first check for the longest word. */
+ if (byts[arridx] == 0) {
+ if (endidxcnt == MAXWLEN) {
+ /* Must be a corrupted spell file. */
+ EMSG(_(e_format));
+ return;
+ }
+ endlen[endidxcnt] = wlen;
+ endidx[endidxcnt++] = arridx++;
+ --len;
+
+ /* Skip over the zeros, there can be several flag/region
+ * combinations. */
+ while (len > 0 && byts[arridx] == 0) {
+ ++arridx;
+ --len;
+ }
+ if (len == 0)
+ break; /* no children, word must end here */
+ }
+
+ /* Stop looking at end of the line. */
+ if (ptr[wlen] == NUL)
+ break;
+
+ /* Perform a binary search in the list of accepted bytes. */
+ c = ptr[wlen];
+ if (c == TAB) /* <Tab> is handled like <Space> */
+ c = ' ';
+ lo = arridx;
+ hi = arridx + len - 1;
+ while (lo < hi) {
+ m = (lo + hi) / 2;
+ if (byts[m] > c)
+ hi = m - 1;
+ else if (byts[m] < c)
+ lo = m + 1;
+ else {
+ lo = hi = m;
+ break;
+ }
+ }
+
+ /* Stop if there is no matching byte. */
+ if (hi < lo || byts[lo] != c)
+ break;
+
+ /* Continue at the child (if there is one). */
+ arridx = idxs[lo];
+ ++wlen;
+ --flen;
+
+ /* One space in the good word may stand for several spaces in the
+ * checked word. */
+ if (c == ' ') {
+ for (;; ) {
+ if (flen <= 0 && *mip->mi_fend != NUL)
+ flen = fold_more(mip);
+ if (ptr[wlen] != ' ' && ptr[wlen] != TAB)
+ break;
+ ++wlen;
+ --flen;
+ }
+ }
+ }
+
+ /*
+ * Verify that one of the possible endings is valid. Try the longest
+ * first.
+ */
+ while (endidxcnt > 0) {
+ --endidxcnt;
+ arridx = endidx[endidxcnt];
+ wlen = endlen[endidxcnt];
+
+ if ((*mb_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 */
+ word_ends = FALSE;
+ } else
+ word_ends = TRUE;
+ /* The prefix flag is before compound flags. Once a valid prefix flag
+ * has been found we try compound flags. */
+ prefix_found = FALSE;
+
+ if (mode != FIND_KEEPWORD && has_mbyte) {
+ /* Compute byte length in original word, length may change
+ * when folding case. This can be slow, take a shortcut when the
+ * case-folded word is equal to the keep-case word. */
+ p = mip->mi_word;
+ if (STRNCMP(ptr, p, wlen) != 0) {
+ for (s = ptr; s < ptr + wlen; mb_ptr_adv(s))
+ mb_ptr_adv(p);
+ wlen = (int)(p - mip->mi_word);
+ }
+ }
+
+ /* Check flags and region. For FIND_PREFIX check the condition and
+ * prefix ID.
+ * Repeat this if there are more flags/region alternatives until there
+ * is a match. */
+ res = SP_BAD;
+ for (len = byts[arridx - 1]; len > 0 && byts[arridx] == 0;
+ --len, ++arridx) {
+ flags = idxs[arridx];
+
+ /* For the fold-case tree check that the case of the checked word
+ * matches with what the word in the tree requires.
+ * For keep-case tree the case is always right. For prefixes we
+ * don't bother to check. */
+ if (mode == FIND_FOLDWORD) {
+ if (mip->mi_cend != mip->mi_word + wlen) {
+ /* mi_capflags was set for a different word length, need
+ * to do it again. */
+ mip->mi_cend = mip->mi_word + wlen;
+ mip->mi_capflags = captype(mip->mi_word, mip->mi_cend);
+ }
+
+ if (mip->mi_capflags == WF_KEEPCAP
+ || !spell_valid_case(mip->mi_capflags, flags))
+ continue;
+ }
+ /* When mode is FIND_PREFIX the word must support the prefix:
+ * check the prefix ID and the condition. Do that for the list at
+ * mip->mi_prefarridx that find_prefix() filled. */
+ else if (mode == FIND_PREFIX && !prefix_found) {
+ c = valid_word_prefix(mip->mi_prefcnt, mip->mi_prefarridx,
+ flags,
+ mip->mi_word + mip->mi_cprefixlen, slang,
+ FALSE);
+ if (c == 0)
+ continue;
+
+ /* Use the WF_RARE flag for a rare prefix. */
+ if (c & WF_RAREPFX)
+ flags |= WF_RARE;
+ prefix_found = TRUE;
+ }
+
+ if (slang->sl_nobreak) {
+ if ((mode == FIND_COMPOUND || mode == FIND_KEEPCOMPOUND)
+ && (flags & WF_BANNED) == 0) {
+ /* NOBREAK: found a valid following word. That's all we
+ * need to know, so return. */
+ mip->mi_result = SP_OK;
+ break;
+ }
+ } else if ((mode == FIND_COMPOUND || mode == FIND_KEEPCOMPOUND
+ || !word_ends)) {
+ /* If there is no compound flag or the word is shorter than
+ * COMPOUNDMIN reject it quickly.
+ * Makes you wonder why someone puts a compound flag on a word
+ * that's too short... Myspell compatibility requires this
+ * anyway. */
+ if (((unsigned)flags >> 24) == 0
+ || wlen - mip->mi_compoff < slang->sl_compminlen)
+ continue;
+ /* For multi-byte chars check character length against
+ * COMPOUNDMIN. */
+ if (has_mbyte
+ && slang->sl_compminlen > 0
+ && mb_charlen_len(mip->mi_word + mip->mi_compoff,
+ wlen - mip->mi_compoff) < slang->sl_compminlen)
+ continue;
+
+ /* Limit the number of compound words to COMPOUNDWORDMAX if no
+ * maximum for syllables is specified. */
+ if (!word_ends && mip->mi_complen + mip->mi_compextra + 2
+ > slang->sl_compmax
+ && slang->sl_compsylmax == MAXWLEN)
+ continue;
+
+ /* Don't allow compounding on a side where an affix was added,
+ * unless COMPOUNDPERMITFLAG was used. */
+ if (mip->mi_complen > 0 && (flags & WF_NOCOMPBEF))
+ continue;
+ if (!word_ends && (flags & WF_NOCOMPAFT))
+ continue;
+
+ /* Quickly check if compounding is possible with this flag. */
+ if (!byte_in_str(mip->mi_complen == 0
+ ? slang->sl_compstartflags
+ : slang->sl_compallflags,
+ ((unsigned)flags >> 24)))
+ continue;
+
+ /* If there is a match with a CHECKCOMPOUNDPATTERN rule
+ * discard the compound word. */
+ if (match_checkcompoundpattern(ptr, wlen, &slang->sl_comppat))
+ continue;
+
+ if (mode == FIND_COMPOUND) {
+ int capflags;
+
+ /* Need to check the caps type of the appended compound
+ * word. */
+ if (has_mbyte && STRNCMP(ptr, mip->mi_word,
+ mip->mi_compoff) != 0) {
+ /* case folding may have changed the length */
+ p = mip->mi_word;
+ for (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))
+ continue;
+
+ if (capflags != WF_ALLCAP) {
+ /* When the character before the word is a word
+ * 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);
+ if (spell_iswordp_nmw(p, mip->mi_win)
+ ? capflags == WF_ONECAP
+ : (flags & WF_ONECAP) != 0
+ && capflags != WF_ONECAP)
+ continue;
+ }
+ }
+
+ /* If the word ends the sequence of compound flags of the
+ * words must match with one of the COMPOUNDRULE items and
+ * the number of syllables must not be too large. */
+ mip->mi_compflags[mip->mi_complen] = ((unsigned)flags >> 24);
+ mip->mi_compflags[mip->mi_complen + 1] = NUL;
+ if (word_ends) {
+ char_u fword[MAXWLEN];
+
+ if (slang->sl_compsylmax < MAXWLEN) {
+ /* "fword" is only needed for checking syllables. */
+ if (ptr == mip->mi_word)
+ (void)spell_casefold(ptr, wlen, fword, MAXWLEN);
+ else
+ vim_strncpy(fword, ptr, endlen[endidxcnt]);
+ }
+ if (!can_compound(slang, fword, mip->mi_compflags))
+ continue;
+ } else if (slang->sl_comprules != NULL
+ && !match_compoundrule(slang, mip->mi_compflags))
+ /* The compound flags collected so far do not match any
+ * COMPOUNDRULE, discard the compounded word. */
+ continue;
+ }
+ /* Check NEEDCOMPOUND: can't use word without compounding. */
+ else if (flags & WF_NEEDCOMP)
+ continue;
+
+ nobreak_result = SP_OK;
+
+ if (!word_ends) {
+ int save_result = mip->mi_result;
+ char_u *save_end = mip->mi_end;
+ langp_T *save_lp = mip->mi_lp;
+ int lpi;
+
+ /* Check that a valid word follows. If there is one and we
+ * are compounding, it will set "mi_result", thus we are
+ * always finished here. For NOBREAK we only check that a
+ * valid word follows.
+ * Recursive! */
+ if (slang->sl_nobreak)
+ mip->mi_result = SP_BAD;
+
+ /* Find following word in case-folded tree. */
+ mip->mi_compoff = endlen[endidxcnt];
+ if (has_mbyte && mode == FIND_KEEPWORD) {
+ /* Compute byte length in case-folded word from "wlen":
+ * byte length in keep-case word. Length may change when
+ * folding case. This can be slow, take a shortcut when
+ * the case-folded word is equal to the keep-case word. */
+ p = mip->mi_fword;
+ if (STRNCMP(ptr, p, wlen) != 0) {
+ for (s = ptr; s < ptr + wlen; mb_ptr_adv(s))
+ mb_ptr_adv(p);
+ mip->mi_compoff = (int)(p - mip->mi_fword);
+ }
+ }
+ c = mip->mi_compoff;
+ ++mip->mi_complen;
+ if (flags & WF_COMPROOT)
+ ++mip->mi_compextra;
+
+ /* For NOBREAK we need to try all NOBREAK languages, at least
+ * to find the ".add" file(s). */
+ for (lpi = 0; lpi < mip->mi_win->w_s->b_langp.ga_len; ++lpi) {
+ if (slang->sl_nobreak) {
+ mip->mi_lp = LANGP_ENTRY(mip->mi_win->w_s->b_langp, lpi);
+ if (mip->mi_lp->lp_slang->sl_fidxs == NULL
+ || !mip->mi_lp->lp_slang->sl_nobreak)
+ continue;
+ }
+
+ find_word(mip, FIND_COMPOUND);
+
+ /* When NOBREAK any word that matches is OK. Otherwise we
+ * need to find the longest match, thus try with keep-case
+ * and prefix too. */
+ if (!slang->sl_nobreak || mip->mi_result == SP_BAD) {
+ /* Find following word in keep-case tree. */
+ mip->mi_compoff = wlen;
+ find_word(mip, FIND_KEEPCOMPOUND);
+
+#if 0 /* Disabled, a prefix must not appear halfway a compound word,
+ unless the COMPOUNDPERMITFLAG is used and then it can't be a
+ postponed prefix. */
+ if (!slang->sl_nobreak || mip->mi_result == SP_BAD) {
+ /* Check for following word with prefix. */
+ mip->mi_compoff = c;
+ find_prefix(mip, FIND_COMPOUND);
+ }
+#endif
+ }
+
+ if (!slang->sl_nobreak)
+ break;
+ }
+ --mip->mi_complen;
+ if (flags & WF_COMPROOT)
+ --mip->mi_compextra;
+ mip->mi_lp = save_lp;
+
+ if (slang->sl_nobreak) {
+ nobreak_result = mip->mi_result;
+ mip->mi_result = save_result;
+ mip->mi_end = save_end;
+ } else {
+ if (mip->mi_result == SP_OK)
+ break;
+ continue;
+ }
+ }
+
+ if (flags & WF_BANNED)
+ res = SP_BANNED;
+ else if (flags & WF_REGION) {
+ /* Check region. */
+ if ((mip->mi_lp->lp_region & (flags >> 16)) != 0)
+ res = SP_OK;
+ else
+ res = SP_LOCAL;
+ } else if (flags & WF_RARE)
+ res = SP_RARE;
+ else
+ res = SP_OK;
+
+ /* Always use the longest match and the best result. For NOBREAK
+ * we separately keep the longest match without a following good
+ * word as a fall-back. */
+ if (nobreak_result == SP_BAD) {
+ if (mip->mi_result2 > res) {
+ mip->mi_result2 = res;
+ mip->mi_end2 = mip->mi_word + wlen;
+ } else if (mip->mi_result2 == res
+ && mip->mi_end2 < mip->mi_word + wlen)
+ mip->mi_end2 = mip->mi_word + wlen;
+ } else if (mip->mi_result > res) {
+ mip->mi_result = res;
+ mip->mi_end = mip->mi_word + wlen;
+ } else if (mip->mi_result == res && mip->mi_end < mip->mi_word + wlen)
+ mip->mi_end = mip->mi_word + wlen;
+
+ if (mip->mi_result == SP_OK)
+ break;
+ }
+
+ if (mip->mi_result == SP_OK)
+ break;
+ }
+}
+
+/*
+ * Return TRUE if there is a match between the word ptr[wlen] and
+ * CHECKCOMPOUNDPATTERN rules, assuming that we will concatenate with another
+ * word.
+ * A match means that the first part of CHECKCOMPOUNDPATTERN matches at the
+ * end of ptr[wlen] and the second part matches after it.
+ */
+static int match_checkcompoundpattern(ptr, wlen, gap)
+char_u *ptr;
+int wlen;
+garray_T *gap; /* &sl_comppat */
+{
+ int i;
+ char_u *p;
+ int len;
+
+ for (i = 0; i + 1 < gap->ga_len; i += 2) {
+ p = ((char_u **)gap->ga_data)[i + 1];
+ if (STRNCMP(ptr + wlen, p, STRLEN(p)) == 0) {
+ /* Second part matches at start of following compound word, now
+ * check if first part matches at end of previous word. */
+ p = ((char_u **)gap->ga_data)[i];
+ len = (int)STRLEN(p);
+ if (len <= wlen && STRNCMP(ptr + wlen - len, p, len) == 0)
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/*
+ * Return TRUE if "flags" is a valid sequence of compound flags and "word"
+ * does not have too many syllables.
+ */
+static int can_compound(slang, word, flags)
+slang_T *slang;
+char_u *word;
+char_u *flags;
+{
+ regmatch_T regmatch;
+ char_u uflags[MAXWLEN * 2];
+ int i;
+ char_u *p;
+
+ if (slang->sl_compprog == NULL)
+ return FALSE;
+ 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);
+ *p = NUL;
+ p = uflags;
+ } else
+ p = flags;
+ regmatch.regprog = slang->sl_compprog;
+ regmatch.rm_ic = FALSE;
+ if (!vim_regexec(&regmatch, p, 0))
+ return FALSE;
+
+ /* Count the number of syllables. This may be slow, do it last. If there
+ * are too many syllables AND the number of compound words is above
+ * COMPOUNDWORDMAX then compounding is not allowed. */
+ if (slang->sl_compsylmax < MAXWLEN
+ && count_syllables(slang, word) > slang->sl_compsylmax)
+ return (int)STRLEN(flags) < slang->sl_compmax;
+ return TRUE;
+}
+
+/*
+ * Return TRUE when the sequence of flags in "compflags" plus "flag" can
+ * possibly form a valid compounded word. This also checks the COMPOUNDRULE
+ * lines if they don't contain wildcards.
+ */
+static int can_be_compound(sp, slang, compflags, flag)
+trystate_T *sp;
+slang_T *slang;
+char_u *compflags;
+int flag;
+{
+ /* If the flag doesn't appear in sl_compstartflags or sl_compallflags
+ * then it can't possibly compound. */
+ if (!byte_in_str(sp->ts_complen == sp->ts_compsplit
+ ? slang->sl_compstartflags : slang->sl_compallflags, flag))
+ return FALSE;
+
+ /* If there are no wildcards, we can check if the flags collected so far
+ * possibly can form a match with COMPOUNDRULE patterns. This only
+ * makes sense when we have two or more words. */
+ if (slang->sl_comprules != NULL && sp->ts_complen > sp->ts_compsplit) {
+ int v;
+
+ compflags[sp->ts_complen] = flag;
+ compflags[sp->ts_complen + 1] = NUL;
+ v = match_compoundrule(slang, compflags + sp->ts_compsplit);
+ compflags[sp->ts_complen] = NUL;
+ return v;
+ }
+
+ return TRUE;
+}
+
+
+/*
+ * Return TRUE if the compound flags in compflags[] match the start of any
+ * compound rule. This is used to stop trying a compound if the flags
+ * collected so far can't possibly match any compound rule.
+ * Caller must check that slang->sl_comprules is not NULL.
+ */
+static int match_compoundrule(slang, compflags)
+slang_T *slang;
+char_u *compflags;
+{
+ char_u *p;
+ int i;
+ int c;
+
+ /* loop over all the COMPOUNDRULE entries */
+ for (p = slang->sl_comprules; *p != NUL; ++p) {
+ /* loop over the flags in the compound word we have made, match
+ * them against the current rule entry */
+ for (i = 0;; ++i) {
+ c = compflags[i];
+ if (c == NUL)
+ /* found a rule that matches for the flags we have so far */
+ return TRUE;
+ if (*p == '/' || *p == NUL)
+ break; /* end of rule, it's too short */
+ if (*p == '[') {
+ int match = FALSE;
+
+ /* compare against all the flags in [] */
+ ++p;
+ while (*p != ']' && *p != NUL)
+ if (*p++ == c)
+ match = TRUE;
+ if (!match)
+ break; /* none matches */
+ } else if (*p != c)
+ break; /* flag of word doesn't match flag in pattern */
+ ++p;
+ }
+
+ /* Skip to the next "/", where the next pattern starts. */
+ p = vim_strchr(p, '/');
+ if (p == NULL)
+ break;
+ }
+
+ /* Checked all the rules and none of them match the flags, so there
+ * can't possibly be a compound starting with these flags. */
+ return FALSE;
+}
+
+/*
+ * Return non-zero if the prefix indicated by "arridx" matches with the prefix
+ * ID in "flags" for the word "word".
+ * The WF_RAREPFX flag is included in the return value for a rare prefix.
+ */
+static int valid_word_prefix(totprefcnt, arridx, flags, word, slang, cond_req)
+int totprefcnt; /* nr of prefix IDs */
+int arridx; /* idx in sl_pidxs[] */
+int flags;
+char_u *word;
+slang_T *slang;
+int cond_req; /* only use prefixes with a condition */
+{
+ int prefcnt;
+ int pidx;
+ regprog_T *rp;
+ regmatch_T regmatch;
+ int prefid;
+
+ prefid = (unsigned)flags >> 24;
+ for (prefcnt = totprefcnt - 1; prefcnt >= 0; --prefcnt) {
+ pidx = slang->sl_pidxs[arridx + prefcnt];
+
+ /* Check the prefix ID. */
+ if (prefid != (pidx & 0xff))
+ continue;
+
+ /* Check if the prefix doesn't combine and the word already has a
+ * suffix. */
+ if ((flags & WF_HAS_AFF) && (pidx & WF_PFX_NC))
+ continue;
+
+ /* Check the condition, if there is one. The condition index is
+ * stored in the two bytes above the prefix ID byte. */
+ rp = slang->sl_prefprog[((unsigned)pidx >> 8) & 0xffff];
+ if (rp != NULL) {
+ regmatch.regprog = rp;
+ regmatch.rm_ic = FALSE;
+ if (!vim_regexec(&regmatch, word, 0))
+ continue;
+ } else if (cond_req)
+ continue;
+
+ /* It's a match! Return the WF_ flags. */
+ return pidx;
+ }
+ return 0;
+}
+
+/*
+ * Check if the word at "mip->mi_word" has a matching prefix.
+ * If it does, then check the following word.
+ *
+ * If "mode" is "FIND_COMPOUND" then do the same after another word, find a
+ * prefix in a compound word.
+ *
+ * For a match mip->mi_result is updated.
+ */
+static void find_prefix(mip, mode)
+matchinf_T *mip;
+int mode;
+{
+ idx_T arridx = 0;
+ int len;
+ int wlen = 0;
+ int flen;
+ int c;
+ char_u *ptr;
+ idx_T lo, hi, m;
+ slang_T *slang = mip->mi_lp->lp_slang;
+ char_u *byts;
+ idx_T *idxs;
+
+ byts = slang->sl_pbyts;
+ if (byts == NULL)
+ return; /* array is empty */
+
+ /* We use the case-folded word here, since prefixes are always
+ * case-folded. */
+ ptr = mip->mi_fword;
+ flen = mip->mi_fwordlen; /* available case-folded bytes */
+ if (mode == FIND_COMPOUND) {
+ /* Skip over the previously found word(s). */
+ ptr += mip->mi_compoff;
+ flen -= mip->mi_compoff;
+ }
+ idxs = slang->sl_pidxs;
+
+ /*
+ * Repeat advancing in the tree until:
+ * - there is a byte that doesn't match,
+ * - we reach the end of the tree,
+ * - or we reach the end of the line.
+ */
+ for (;; ) {
+ if (flen == 0 && *mip->mi_fend != NUL)
+ flen = fold_more(mip);
+
+ len = byts[arridx++];
+
+ /* If the first possible byte is a zero the prefix could end here.
+ * Check if the following word matches and supports the prefix. */
+ if (byts[arridx] == 0) {
+ /* There can be several prefixes with different conditions. We
+ * try them all, since we don't know which one will give the
+ * longest match. The word is the same each time, pass the list
+ * of possible prefixes to find_word(). */
+ mip->mi_prefarridx = arridx;
+ mip->mi_prefcnt = len;
+ while (len > 0 && byts[arridx] == 0) {
+ ++arridx;
+ --len;
+ }
+ mip->mi_prefcnt -= len;
+
+ /* Find the word that comes after the prefix. */
+ mip->mi_prefixlen = wlen;
+ if (mode == FIND_COMPOUND)
+ /* Skip over the previously found word(s). */
+ mip->mi_prefixlen += mip->mi_compoff;
+
+ if (has_mbyte) {
+ /* Case-folded length may differ from original length. */
+ mip->mi_cprefixlen = nofold_len(mip->mi_fword,
+ mip->mi_prefixlen, mip->mi_word);
+ } else
+ mip->mi_cprefixlen = mip->mi_prefixlen;
+ find_word(mip, FIND_PREFIX);
+
+
+ if (len == 0)
+ break; /* no children, word must end here */
+ }
+
+ /* Stop looking at end of the line. */
+ if (ptr[wlen] == NUL)
+ break;
+
+ /* Perform a binary search in the list of accepted bytes. */
+ c = ptr[wlen];
+ lo = arridx;
+ hi = arridx + len - 1;
+ while (lo < hi) {
+ m = (lo + hi) / 2;
+ if (byts[m] > c)
+ hi = m - 1;
+ else if (byts[m] < c)
+ lo = m + 1;
+ else {
+ lo = hi = m;
+ break;
+ }
+ }
+
+ /* Stop if there is no matching byte. */
+ if (hi < lo || byts[lo] != c)
+ break;
+
+ /* Continue at the child (if there is one). */
+ arridx = idxs[lo];
+ ++wlen;
+ --flen;
+ }
+}
+
+/*
+ * Need to fold at least one more character. Do until next non-word character
+ * for efficiency. Include the non-word character too.
+ * Return the length of the folded chars in bytes.
+ */
+static int fold_more(mip)
+matchinf_T *mip;
+{
+ int flen;
+ char_u *p;
+
+ p = mip->mi_fend;
+ do {
+ 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);
+
+ (void)spell_casefold(p, (int)(mip->mi_fend - p),
+ mip->mi_fword + mip->mi_fwordlen,
+ MAXWLEN - mip->mi_fwordlen);
+ flen = (int)STRLEN(mip->mi_fword + mip->mi_fwordlen);
+ mip->mi_fwordlen += flen;
+ return flen;
+}
+
+/*
+ * Check case flags for a word. Return TRUE if the word has the requested
+ * case.
+ */
+static int spell_valid_case(wordflags, treeflags)
+int wordflags; /* flags for the checked word. */
+int treeflags; /* flags for the word in the spell tree */
+{
+ return (wordflags == WF_ALLCAP && (treeflags & WF_FIXCAP) == 0)
+ || ((treeflags & (WF_ALLCAP | WF_KEEPCAP)) == 0
+ && ((treeflags & WF_ONECAP) == 0
+ || (wordflags & WF_ONECAP) != 0));
+}
+
+/*
+ * Return TRUE if spell checking is not enabled.
+ */
+static int no_spell_checking(wp)
+win_T *wp;
+{
+ if (!wp->w_p_spell || *wp->w_s->b_p_spl == NUL
+ || wp->w_s->b_langp.ga_len == 0) {
+ EMSG(_("E756: Spell checking is not enabled"));
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*
+ * Move to next spell error.
+ * "curline" is FALSE for "[s", "]s", "[S" and "]S".
+ * "curline" is TRUE to find word under/after cursor in the same line.
+ * For Insert mode completion "dir" is BACKWARD and "curline" is TRUE: move
+ * to after badly spelled word before the cursor.
+ * Return 0 if not found, length of the badly spelled word otherwise.
+ */
+int spell_move_to(wp, dir, allwords, curline, attrp)
+win_T *wp;
+int dir; /* FORWARD or BACKWARD */
+int allwords; /* TRUE for "[s"/"]s", FALSE for "[S"/"]S" */
+int curline;
+hlf_T *attrp; /* return: attributes of bad word or NULL
+ (only when "dir" is FORWARD) */
+{
+ linenr_T lnum;
+ pos_T found_pos;
+ int found_len = 0;
+ char_u *line;
+ char_u *p;
+ char_u *endp;
+ hlf_T attr;
+ int len;
+ int has_syntax = syntax_present(wp);
+ int col;
+ int can_spell;
+ char_u *buf = NULL;
+ int buflen = 0;
+ int skip = 0;
+ int capcol = -1;
+ int found_one = FALSE;
+ int wrapped = FALSE;
+
+ if (no_spell_checking(wp))
+ return 0;
+
+ /*
+ * Start looking for bad word at the start of the line, because we can't
+ * start halfway a word, we don't know where it starts or ends.
+ *
+ * When searching backwards, we continue in the line to find the last
+ * bad word (in the cursor line: before the cursor).
+ *
+ * We concatenate the start of the next line, so that wrapped words work
+ * (e.g. "et<line-break>cetera"). Doesn't work when searching backwards
+ * though...
+ */
+ lnum = wp->w_cursor.lnum;
+ clearpos(&found_pos);
+
+ while (!got_int) {
+ line = ml_get_buf(wp->w_buffer, lnum, FALSE);
+
+ len = (int)STRLEN(line);
+ if (buflen < len + MAXWLEN + 2) {
+ vim_free(buf);
+ buflen = len + MAXWLEN + 2;
+ buf = alloc(buflen);
+ if (buf == NULL)
+ break;
+ }
+
+ /* In first line check first word for Capital. */
+ if (lnum == 1)
+ 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) {
+ /* For spellbadword(): check if first word needs a capital. */
+ col = (int)(skipwhite(line) - line);
+ if (check_need_cap(lnum, col))
+ capcol = col;
+
+ /* Need to get the line again, may have looked at the previous
+ * one. */
+ line = ml_get_buf(wp->w_buffer, lnum, FALSE);
+ }
+
+ /* Copy the line into "buf" and append the start of the next line if
+ * possible. */
+ STRCPY(buf, line);
+ if (lnum < wp->w_buffer->b_ml.ml_line_count)
+ spell_cat_line(buf + STRLEN(buf),
+ ml_get_buf(wp->w_buffer, lnum + 1, FALSE), MAXWLEN);
+
+ p = buf + skip;
+ endp = buf + len;
+ while (p < endp) {
+ /* When searching backward don't search after the cursor. Unless
+ * we wrapped around the end of the buffer. */
+ if (dir == BACKWARD
+ && lnum == wp->w_cursor.lnum
+ && !wrapped
+ && (colnr_T)(p - buf) >= wp->w_cursor.col)
+ break;
+
+ /* start of word */
+ attr = HLF_COUNT;
+ len = spell_check(wp, p, &attr, &capcol, FALSE);
+
+ if (attr != HLF_COUNT) {
+ /* We found a bad word. Check the attribute. */
+ if (allwords || attr == HLF_SPB) {
+ /* When searching forward only accept a bad word after
+ * the cursor. */
+ if (dir == BACKWARD
+ || lnum != wp->w_cursor.lnum
+ || (lnum == wp->w_cursor.lnum
+ && (wrapped
+ || (colnr_T)(curline ? p - buf + len
+ : p - buf)
+ > wp->w_cursor.col))) {
+ if (has_syntax) {
+ col = (int)(p - buf);
+ (void)syn_get_id(wp, lnum, (colnr_T)col,
+ FALSE, &can_spell, FALSE);
+ if (!can_spell)
+ attr = HLF_COUNT;
+ } else
+ can_spell = TRUE;
+
+ if (can_spell) {
+ found_one = TRUE;
+ found_pos.lnum = lnum;
+ found_pos.col = (int)(p - buf);
+ found_pos.coladd = 0;
+ if (dir == FORWARD) {
+ /* No need to search further. */
+ wp->w_cursor = found_pos;
+ vim_free(buf);
+ if (attrp != NULL)
+ *attrp = attr;
+ return len;
+ } else if (curline)
+ /* Insert mode completion: put cursor after
+ * the bad word. */
+ found_pos.col += len;
+ found_len = len;
+ }
+ } else
+ found_one = TRUE;
+ }
+ }
+
+ /* advance to character after the word */
+ p += len;
+ capcol -= len;
+ }
+
+ if (dir == BACKWARD && found_pos.lnum != 0) {
+ /* Use the last match in the line (before the cursor). */
+ wp->w_cursor = found_pos;
+ vim_free(buf);
+ return found_len;
+ }
+
+ if (curline)
+ break; /* only check cursor line */
+
+ /* 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)
+ break; /* at first line and 'nowrapscan' */
+ 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;
+ wrapped = TRUE;
+ if (!shortmess(SHM_SEARCH))
+ give_warning((char_u *)_(top_bot_msg), TRUE);
+ }
+ capcol = -1;
+ } else {
+ if (lnum < wp->w_buffer->b_ml.ml_line_count)
+ ++lnum;
+ else if (!p_ws)
+ break; /* at first line and 'nowrapscan' */
+ else {
+ /* Wrap around to the start of the buffer. May search the
+ * starting line again and accept the first match. */
+ lnum = 1;
+ wrapped = TRUE;
+ if (!shortmess(SHM_SEARCH))
+ give_warning((char_u *)_(bot_top_msg), TRUE);
+ }
+
+ /* 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))
+ break;
+
+ /* Skip the characters at the start of the next line that were
+ * included in a match crossing line boundaries. */
+ if (attr == HLF_COUNT)
+ skip = (int)(p - endp);
+ else
+ skip = 0;
+
+ /* Capcol skips over the inserted space. */
+ --capcol;
+
+ /* But after empty line check first word in next line */
+ if (*skipwhite(line) == NUL)
+ capcol = 0;
+ }
+
+ line_breakcheck();
+ }
+
+ vim_free(buf);
+ return 0;
+}
+
+/*
+ * For spell checking: concatenate the start of the following line "line" into
+ * "buf", blanking-out special characters. Copy less then "maxlen" bytes.
+ * Keep the blanks at the start of the next line, this is used in win_line()
+ * to skip those bytes if the word was OK.
+ */
+void spell_cat_line(buf, line, maxlen)
+char_u *buf;
+char_u *line;
+int maxlen;
+{
+ char_u *p;
+ int n;
+
+ p = skipwhite(line);
+ while (vim_strchr((char_u *)"*#/\"\t", *p) != NULL)
+ p = skipwhite(p + 1);
+
+ if (*p != NUL) {
+ /* Only worth concatenating if there is something else than spaces to
+ * concatenate. */
+ n = (int)(p - line) + 1;
+ if (n < maxlen - 1) {
+ vim_memset(buf, ' ', n);
+ vim_strncpy(buf + n, p, maxlen - 1 - n);
+ }
+ }
+}
+
+/*
+ * Structure used for the cookie argument of do_in_runtimepath().
+ */
+typedef struct spelload_S {
+ char_u sl_lang[MAXWLEN + 1]; /* language name */
+ slang_T *sl_slang; /* resulting slang_T struct */
+ int sl_nobreak; /* NOBREAK language found */
+} spelload_T;
+
+/*
+ * Load word list(s) for "lang" from Vim spell file(s).
+ * "lang" must be the language without the region: e.g., "en".
+ */
+static void spell_load_lang(lang)
+char_u *lang;
+{
+ char_u fname_enc[85];
+ int r;
+ spelload_T sl;
+ int round;
+
+ /* Copy the language name to pass it to spell_load_cb() as a cookie.
+ * It's truncated when an error is detected. */
+ STRCPY(sl.sl_lang, lang);
+ sl.sl_slang = NULL;
+ sl.sl_nobreak = FALSE;
+
+ /* We may retry when no spell file is found for the language, an
+ * autocommand may load it then. */
+ for (round = 1; round <= 2; ++round) {
+ /*
+ * Find the first spell file for "lang" in 'runtimepath' and load it.
+ */
+ vim_snprintf((char *)fname_enc, sizeof(fname_enc) - 5,
+ "spell/%s.%s.spl",
+ lang, spell_enc());
+ r = do_in_runtimepath(fname_enc, FALSE, spell_load_cb, &sl);
+
+ if (r == FAIL && *sl.sl_lang != NUL) {
+ /* Try loading the ASCII version. */
+ vim_snprintf((char *)fname_enc, sizeof(fname_enc) - 5,
+ "spell/%s.ascii.spl",
+ lang);
+ r = do_in_runtimepath(fname_enc, FALSE, spell_load_cb, &sl);
+
+ if (r == FAIL && *sl.sl_lang != NUL && round == 1
+ && apply_autocmds(EVENT_SPELLFILEMISSING, lang,
+ curbuf->b_fname, FALSE, curbuf))
+ continue;
+ break;
+ }
+ break;
+ }
+
+ if (r == FAIL) {
+ smsg((char_u *)
+ _("Warning: Cannot find word list \"%s.%s.spl\" or \"%s.ascii.spl\""),
+ lang, spell_enc(), lang);
+ } else if (sl.sl_slang != NULL) {
+ /* At least one file was loaded, now load ALL the additions. */
+ STRCPY(fname_enc + STRLEN(fname_enc) - 3, "add.spl");
+ do_in_runtimepath(fname_enc, TRUE, spell_load_cb, &sl);
+ }
+}
+
+/*
+ * 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() {
+
+ if (STRLEN(p_enc) < 60 && STRCMP(p_enc, "iso-8859-15") != 0)
+ return p_enc;
+ return (char_u *)"latin1";
+}
+
+/*
+ * Get the name of the .spl file for the internal wordlist into
+ * "fname[MAXPATHL]".
+ */
+static void int_wordlist_spl(fname)
+char_u *fname;
+{
+ vim_snprintf((char *)fname, MAXPATHL, SPL_FNAME_TMPL,
+ int_wordlist, spell_enc());
+}
+
+/*
+ * Allocate a new slang_T for language "lang". "lang" can be NULL.
+ * Caller must fill "sl_next".
+ */
+static slang_T * slang_alloc(lang)
+char_u *lang;
+{
+ slang_T *lp;
+
+ lp = (slang_T *)alloc_clear(sizeof(slang_T));
+ if (lp != NULL) {
+ if (lang != NULL)
+ lp->sl_name = vim_strsave(lang);
+ ga_init2(&lp->sl_rep, sizeof(fromto_T), 10);
+ ga_init2(&lp->sl_repsal, sizeof(fromto_T), 10);
+ lp->sl_compmax = MAXWLEN;
+ lp->sl_compsylmax = MAXWLEN;
+ hash_init(&lp->sl_wordcount);
+ }
+
+ return lp;
+}
+
+/*
+ * Free the contents of an slang_T and the structure itself.
+ */
+static void slang_free(lp)
+slang_T *lp;
+{
+ vim_free(lp->sl_name);
+ vim_free(lp->sl_fname);
+ slang_clear(lp);
+ vim_free(lp);
+}
+
+/*
+ * Clear an slang_T so that the file can be reloaded.
+ */
+static void slang_clear(lp)
+slang_T *lp;
+{
+ garray_T *gap;
+ fromto_T *ftp;
+ salitem_T *smp;
+ int i;
+ int round;
+
+ vim_free(lp->sl_fbyts);
+ lp->sl_fbyts = NULL;
+ vim_free(lp->sl_kbyts);
+ lp->sl_kbyts = NULL;
+ vim_free(lp->sl_pbyts);
+ lp->sl_pbyts = NULL;
+
+ vim_free(lp->sl_fidxs);
+ lp->sl_fidxs = NULL;
+ vim_free(lp->sl_kidxs);
+ lp->sl_kidxs = NULL;
+ vim_free(lp->sl_pidxs);
+ lp->sl_pidxs = NULL;
+
+ for (round = 1; round <= 2; ++round) {
+ gap = round == 1 ? &lp->sl_rep : &lp->sl_repsal;
+ while (gap->ga_len > 0) {
+ ftp = &((fromto_T *)gap->ga_data)[--gap->ga_len];
+ vim_free(ftp->ft_from);
+ vim_free(ftp->ft_to);
+ }
+ ga_clear(gap);
+ }
+
+ gap = &lp->sl_sal;
+ if (lp->sl_sofo) {
+ /* "ga_len" is set to 1 without adding an item for latin1 */
+ if (gap->ga_data != NULL)
+ /* SOFOFROM and SOFOTO items: free lists of wide characters. */
+ for (i = 0; i < gap->ga_len; ++i)
+ vim_free(((int **)gap->ga_data)[i]);
+ } else
+ /* SAL items: free salitem_T items */
+ while (gap->ga_len > 0) {
+ smp = &((salitem_T *)gap->ga_data)[--gap->ga_len];
+ vim_free(smp->sm_lead);
+ /* Don't free sm_oneof and sm_rules, they point into sm_lead. */
+ vim_free(smp->sm_to);
+ vim_free(smp->sm_lead_w);
+ vim_free(smp->sm_oneof_w);
+ vim_free(smp->sm_to_w);
+ }
+ ga_clear(gap);
+
+ for (i = 0; i < lp->sl_prefixcnt; ++i)
+ vim_regfree(lp->sl_prefprog[i]);
+ lp->sl_prefixcnt = 0;
+ vim_free(lp->sl_prefprog);
+ lp->sl_prefprog = NULL;
+
+ vim_free(lp->sl_info);
+ lp->sl_info = NULL;
+
+ vim_free(lp->sl_midword);
+ lp->sl_midword = NULL;
+
+ vim_regfree(lp->sl_compprog);
+ vim_free(lp->sl_comprules);
+ vim_free(lp->sl_compstartflags);
+ vim_free(lp->sl_compallflags);
+ lp->sl_compprog = NULL;
+ lp->sl_comprules = NULL;
+ lp->sl_compstartflags = NULL;
+ lp->sl_compallflags = NULL;
+
+ vim_free(lp->sl_syllable);
+ lp->sl_syllable = NULL;
+ ga_clear(&lp->sl_syl_items);
+
+ ga_clear_strings(&lp->sl_comppat);
+
+ hash_clear_all(&lp->sl_wordcount, WC_KEY_OFF);
+ hash_init(&lp->sl_wordcount);
+
+ hash_clear_all(&lp->sl_map_hash, 0);
+
+ /* Clear info from .sug file. */
+ slang_clear_sug(lp);
+
+ lp->sl_compmax = MAXWLEN;
+ lp->sl_compminlen = 0;
+ lp->sl_compsylmax = MAXWLEN;
+ lp->sl_regions[0] = NUL;
+}
+
+/*
+ * Clear the info from the .sug file in "lp".
+ */
+static void slang_clear_sug(lp)
+slang_T *lp;
+{
+ vim_free(lp->sl_sbyts);
+ lp->sl_sbyts = NULL;
+ vim_free(lp->sl_sidxs);
+ lp->sl_sidxs = NULL;
+ close_spellbuf(lp->sl_sugbuf);
+ lp->sl_sugbuf = NULL;
+ lp->sl_sugloaded = FALSE;
+ lp->sl_sugtime = 0;
+}
+
+/*
+ * Load one spell file and store the info into a slang_T.
+ * Invoked through do_in_runtimepath().
+ */
+static void spell_load_cb(fname, cookie)
+char_u *fname;
+void *cookie;
+{
+ spelload_T *slp = (spelload_T *)cookie;
+ slang_T *slang;
+
+ slang = spell_load_file(fname, slp->sl_lang, NULL, FALSE);
+ if (slang != NULL) {
+ /* When a previously loaded file has NOBREAK also use it for the
+ * ".add" files. */
+ if (slp->sl_nobreak && slang->sl_add)
+ slang->sl_nobreak = TRUE;
+ else if (slang->sl_nobreak)
+ slp->sl_nobreak = TRUE;
+
+ slp->sl_slang = slang;
+ }
+}
+
+/*
+ * 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(fname, lang, old_lp, silent)
+char_u *fname;
+char_u *lang;
+slang_T *old_lp;
+int 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_u *)e_notopen, fname);
+ verbose_leave();
+ }
+ goto endFAIL;
+ }
+ if (p_verbose > 2) {
+ verbose_enter();
+ smsg((char_u *)_("Reading spell file \"%s\""), fname);
+ verbose_leave();
+ }
+
+ if (old_lp == NULL) {
+ lp = slang_alloc(lang);
+ if (lp == NULL)
+ goto endFAIL;
+
+ /* Remember the file name, used to reload the file when it's updated. */
+ lp->sl_fname = vim_strsave(fname);
+ if (lp->sl_fname == NULL)
+ goto endFAIL;
+
+ /* Check for .add.spl (_add.spl for VMS). */
+ lp->sl_add = strstr((char *)gettail(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);
+ vim_free(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; /* <timestamp> */
+ 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(fd, cnt_bytes, cntp)
+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(fd, lp, len)
+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(fd)
+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) {
+ vim_free(flags);
+ return follen;
+ }
+
+ /* Set the word-char flags and fill SPELL_ISUPPER() table. */
+ if (flags != NULL && fol != NULL)
+ set_spell_charflags(flags, flagslen, fol);
+
+ vim_free(flags);
+ vim_free(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(fd, lp)
+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 = (regprog_T **)alloc_clear(
+ (unsigned)sizeof(regprog_T *) * cnt);
+ if (lp->sl_prefprog == NULL)
+ return SP_OTHERERROR;
+ 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(fd, gap, first)
+FILE *fd;
+garray_T *gap;
+short *first;
+{
+ int cnt;
+ fromto_T *ftp;
+ int i;
+
+ cnt = get2c(fd); /* <repcount> */
+ if (cnt < 0)
+ return SP_TRUNCERROR;
+
+ if (ga_grow(gap, cnt) == FAIL)
+ return SP_OTHERERROR;
+
+ /* <rep> : <repfromlen> <repfrom> <reptolen> <repto> */
+ for (; gap->ga_len < cnt; ++gap->ga_len) {
+ ftp = &((fromto_T *)gap->ga_data)[gap->ga_len];
+ ftp->ft_from = read_cnt_string(fd, 1, &i);
+ if (i < 0)
+ return i;
+ if (i == 0)
+ return SP_FORMERROR;
+ ftp->ft_to = read_cnt_string(fd, 1, &i);
+ if (i <= 0) {
+ vim_free(ftp->ft_from);
+ if (i < 0)
+ return i;
+ return SP_FORMERROR;
+ }
+ }
+
+ /* Fill the first-index table. */
+ for (i = 0; i < 256; ++i)
+ first[i] = -1;
+ for (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(fd, slang)
+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_init2(gap, sizeof(salitem_T), 10);
+ if (ga_grow(gap, cnt + 1) == FAIL)
+ return SP_OTHERERROR;
+
+ /* <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;
+ if ((p = alloc(ccnt + 2)) == NULL)
+ return SP_OTHERERROR;
+ 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) {
+ vim_free(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 (smp->sm_lead_w == NULL
+ || (smp->sm_oneof_w == NULL && smp->sm_oneof != NULL)
+ || (smp->sm_to_w == NULL && smp->sm_to != NULL)) {
+ vim_free(smp->sm_lead);
+ vim_free(smp->sm_to);
+ vim_free(smp->sm_lead_w);
+ vim_free(smp->sm_oneof_w);
+ vim_free(smp->sm_to_w);
+ return SP_OTHERERROR;
+ }
+ }
+ }
+
+ if (gap->ga_len > 0) {
+ /* 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];
+ if ((p = alloc(1)) == NULL)
+ return SP_OTHERERROR;
+ 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(fd, lp, len)
+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(lp, word, len, count)
+slang_T *lp;
+char_u *word;
+int len; /* word length, -1 for upto NUL */
+int count; /* 1 to count once, 10 to init */
+{
+ hash_T hash;
+ hashitem_T *hi;
+ wordcount_T *wc;
+ char_u buf[MAXWLEN];
+ char_u *p;
+
+ if (len == -1)
+ p = word;
+ else {
+ vim_strncpy(buf, word, len);
+ p = buf;
+ }
+
+ hash = hash_hash(p);
+ hi = hash_lookup(&lp->sl_wordcount, p, hash);
+ if (HASHITEM_EMPTY(hi)) {
+ wc = (wordcount_T *)alloc((unsigned)(sizeof(wordcount_T) + STRLEN(p)));
+ if (wc == NULL)
+ return;
+ STRCPY(wc->wc_word, p);
+ wc->wc_count = count;
+ hash_add_item(&lp->sl_wordcount, hi, wc->wc_word, hash);
+ } else {
+ wc = HI2WC(hi);
+ if ((wc->wc_count += count) < (unsigned)count) /* check for overflow */
+ wc->wc_count = MAXWORDCOUNT;
+ }
+}
+
+/*
+ * Adjust the score of common words.
+ */
+static int score_wordcount_adj(slang, score, word, split)
+slang_T *slang;
+int score;
+char_u *word;
+int split; /* word was split, less bonus */
+{
+ hashitem_T *hi;
+ wordcount_T *wc;
+ int bonus;
+ int newscore;
+
+ hi = hash_find(&slang->sl_wordcount, word);
+ if (!HASHITEM_EMPTY(hi)) {
+ wc = HI2WC(hi);
+ if (wc->wc_count < SCORE_THRES2)
+ bonus = SCORE_COMMON1;
+ else if (wc->wc_count < SCORE_THRES3)
+ bonus = SCORE_COMMON2;
+ else
+ bonus = SCORE_COMMON3;
+ if (split)
+ newscore = score - bonus / 2;
+ else
+ newscore = score - bonus;
+ if (newscore < 0)
+ return 0;
+ return newscore;
+ }
+ return score;
+}
+
+/*
+ * SN_SOFO: <sofofromlen> <sofofrom> <sofotolen> <sofoto>
+ * Return SP_*ERROR flags.
+ */
+static int read_sofo_section(fd, slang)
+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) {
+ vim_free(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;
+
+ vim_free(from);
+ vim_free(to);
+ return res;
+}
+
+/*
+ * Read the compound section from the .spl file:
+ * <compmax> <compminlen> <compsylmax> <compoptions> <compflags>
+ * Returns SP_*ERROR flags.
+ */
+static int read_compound(fd, slang, len)
+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_init2(gap, sizeof(char_u *), c);
+ if (ga_grow(gap, c) == OK)
+ 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 = alloc((unsigned)c);
+ if (pat == NULL)
+ return SP_OTHERERROR;
+
+ /* We also need a list of all flags that can appear at the start and one
+ * for all flags. */
+ cp = alloc(todo + 1);
+ if (cp == NULL) {
+ vim_free(pat);
+ return SP_OTHERERROR;
+ }
+ slang->sl_compstartflags = cp;
+ *cp = NUL;
+
+ ap = alloc(todo + 1);
+ if (ap == NULL) {
+ vim_free(pat);
+ return SP_OTHERERROR;
+ }
+ 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 = alloc(todo + 1);
+ slang->sl_comprules = crp;
+
+ pp = pat;
+ *pp++ = '^';
+ *pp++ = '\\';
+ *pp++ = '(';
+
+ atstart = 1;
+ while (todo-- > 0) {
+ c = getc(fd); /* <compflags> */
+ if (c == EOF) {
+ vim_free(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 == '*') {
+ vim_free(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);
+ vim_free(pat);
+ if (slang->sl_compprog == NULL)
+ return SP_FORMERROR;
+
+ return 0;
+}
+
+/*
+ * Return TRUE if byte "n" appears in "str".
+ * Like strchr() but independent of locale.
+ */
+static int byte_in_str(str, n)
+char_u *str;
+int n;
+{
+ char_u *p;
+
+ for (p = str; *p != NUL; ++p)
+ if (*p == n)
+ return TRUE;
+ return FALSE;
+}
+
+#define SY_MAXLEN 30
+typedef struct syl_item_S {
+ char_u sy_chars[SY_MAXLEN]; /* the sequence of chars */
+ int sy_len;
+} syl_item_T;
+
+/*
+ * Truncate "slang->sl_syllable" at the first slash and put the following items
+ * in "slang->sl_syl_items".
+ */
+static int init_syl_tab(slang)
+slang_T *slang;
+{
+ char_u *p;
+ char_u *s;
+ int l;
+ syl_item_T *syl;
+
+ ga_init2(&slang->sl_syl_items, sizeof(syl_item_T), 4);
+ p = vim_strchr(slang->sl_syllable, '/');
+ while (p != NULL) {
+ *p++ = NUL;
+ if (*p == NUL) /* trailing slash */
+ break;
+ s = p;
+ p = vim_strchr(p, '/');
+ if (p == NULL)
+ l = (int)STRLEN(s);
+ else
+ l = (int)(p - s);
+ if (l >= SY_MAXLEN)
+ return SP_FORMERROR;
+ if (ga_grow(&slang->sl_syl_items, 1) == FAIL)
+ return SP_OTHERERROR;
+ syl = ((syl_item_T *)slang->sl_syl_items.ga_data)
+ + slang->sl_syl_items.ga_len++;
+ vim_strncpy(syl->sy_chars, s, l);
+ syl->sy_len = l;
+ }
+ return OK;
+}
+
+/*
+ * Count the number of syllables in "word".
+ * When "word" contains spaces the syllables after the last space are counted.
+ * Returns zero if syllables are not defines.
+ */
+static int count_syllables(slang, word)
+slang_T *slang;
+char_u *word;
+{
+ int cnt = 0;
+ int skip = FALSE;
+ char_u *p;
+ int len;
+ int i;
+ syl_item_T *syl;
+ int c;
+
+ if (slang->sl_syllable == NULL)
+ return 0;
+
+ for (p = word; *p != NUL; p += len) {
+ /* When running into a space reset counter. */
+ if (*p == ' ') {
+ len = 1;
+ cnt = 0;
+ continue;
+ }
+
+ /* Find longest match of syllable items. */
+ len = 0;
+ for (i = 0; i < slang->sl_syl_items.ga_len; ++i) {
+ syl = ((syl_item_T *)slang->sl_syl_items.ga_data) + i;
+ if (syl->sy_len > len
+ && STRNCMP(p, syl->sy_chars, syl->sy_len) == 0)
+ len = syl->sy_len;
+ }
+ if (len != 0) { /* found a match, count syllable */
+ ++cnt;
+ skip = FALSE;
+ } else {
+ /* No recognized syllable item, at least a syllable char then? */
+ c = mb_ptr2char(p);
+ len = (*mb_ptr2len)(p);
+ if (vim_strchr(slang->sl_syllable, c) == NULL)
+ skip = FALSE; /* No, search for next syllable */
+ else if (!skip) {
+ ++cnt; /* Yes, count it */
+ skip = TRUE; /* don't count following syllable chars */
+ }
+ }
+ }
+ return cnt;
+}
+
+/*
+ * Set the SOFOFROM and SOFOTO items in language "lp".
+ * Returns SP_*ERROR flags when there is something wrong.
+ */
+static int set_sofo(lp, from, to)
+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_init2(gap, sizeof(int *), 1);
+ if (ga_grow(gap, 256) == FAIL)
+ return SP_OTHERERROR;
+ vim_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 = alloc(sizeof(int) * (lp->sl_sal_first[i] * 2 + 1));
+ if (p == NULL)
+ return SP_OTHERERROR;
+ ((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. */
+ vim_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(lp)
+slang_T *lp;
+{
+ salfirst_T *sfirst;
+ int i;
+ salitem_T *smp;
+ int c;
+ garray_T *gap = &lp->sl_sal;
+
+ sfirst = lp->sl_sal_first;
+ for (i = 0; i < 256; ++i)
+ sfirst[i] = -1;
+ smp = (salitem_T *)gap->ga_data;
+ for (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];
+ mch_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 (NULL for out-of-memory)
+ */
+static int * mb_str2wide(s)
+char_u *s;
+{
+ int *res;
+ char_u *p;
+ int i = 0;
+
+ res = (int *)alloc(sizeof(int) * (mb_charlen(s) + 1));
+ if (res != NULL) {
+ for (p = s; *p != NUL; )
+ res[i++] = mb_ptr2char_adv(&p);
+ res[i] = NUL;
+ }
+ return res;
+}
+
+/*
+ * Read 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(fd, bytsp, idxsp, prefixtree, prefixcnt)
+FILE *fd;
+char_u **bytsp;
+idx_T **idxsp;
+int prefixtree; /* TRUE for the prefix tree */
+int prefixcnt; /* when "prefixtree" is TRUE: prefix count */
+{
+ int len;
+ 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> */
+ len = get4c(fd);
+ if (len < 0)
+ return SP_TRUNCERROR;
+ if (len > 0) {
+ /* Allocate the byte array. */
+ bp = lalloc((long_u)len, TRUE);
+ if (bp == NULL)
+ return SP_OTHERERROR;
+ *bytsp = bp;
+
+ /* Allocate the index array. */
+ ip = (idx_T *)lalloc_clear((long_u)(len * sizeof(int)), TRUE);
+ if (ip == NULL)
+ return SP_OTHERERROR;
+ *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(fd, byts, idxs, maxidx, startidx, prefixtree,
+ maxprefcondnr)
+FILE *fd;
+char_u *byts;
+idx_T *idxs;
+int maxidx; /* size of arrays */
+idx_T startidx; /* current index in "byts" and "idxs" */
+int 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(wp)
+win_T *wp;
+{
+ garray_T ga;
+ char_u *splp;
+ char_u *region;
+ char_u region_cp[3];
+ int filename;
+ int region_mask;
+ slang_T *slang;
+ int c;
+ char_u lang[MAXWLEN + 1];
+ char_u spf_name[MAXPATHL];
+ int len;
+ char_u *p;
+ int round;
+ char_u *spf;
+ char_u *use_region = NULL;
+ int dont_use_region = FALSE;
+ int nobreak = FALSE;
+ int i, j;
+ langp_T *lp, *lp2;
+ static int recursive = FALSE;
+ char_u *ret_msg = NULL;
+ char_u *spl_copy;
+
+ /* 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. */
+ if (recursive)
+ return NULL;
+ recursive = TRUE;
+
+ ga_init2(&ga, sizeof(langp_T), 2);
+ clear_midword(wp);
+
+ /* Make a copy of 'spelllang', the SpellFileMissing autocommands may change
+ * it under our fingers. */
+ spl_copy = vim_strsave(wp->w_s->b_p_spl);
+ if (spl_copy == NULL)
+ goto theend;
+
+ wp->w_s->b_cjk = 0;
+
+ /* Loop over comma separated language names. */
+ for (splp = spl_copy; *splp != NUL; ) {
+ /* Get one language name. */
+ copy_option_part(&splp, lang, MAXWLEN, ",");
+ region = NULL;
+ len = (int)STRLEN(lang);
+
+ if (STRCMP(lang, "cjk") == 0) {
+ wp->w_s->b_cjk = 1;
+ continue;
+ }
+
+ /* If the name ends in ".spl" use it as the name of the spell file.
+ * If there is a region name let "region" point to it and remove it
+ * from the name. */
+ if (len > 4 && fnamecmp(lang + len - 4, ".spl") == 0) {
+ filename = TRUE;
+
+ /* Locate a region and remove it from the file name. */
+ p = vim_strchr(gettail(lang), '_');
+ if (p != NULL && ASCII_ISALPHA(p[1]) && ASCII_ISALPHA(p[2])
+ && !ASCII_ISALPHA(p[3])) {
+ vim_strncpy(region_cp, p + 1, 2);
+ mch_memmove(p, p + 3, len - (p - lang) - 2);
+ len -= 3;
+ region = region_cp;
+ } else
+ dont_use_region = TRUE;
+
+ /* Check if we loaded this language before. */
+ for (slang = first_lang; slang != NULL; slang = slang->sl_next)
+ if (fullpathcmp(lang, slang->sl_fname, FALSE) == FPC_SAME)
+ break;
+ } else {
+ filename = FALSE;
+ if (len > 3 && lang[len - 3] == '_') {
+ region = lang + len - 2;
+ len -= 3;
+ lang[len] = NUL;
+ } else
+ dont_use_region = TRUE;
+
+ /* Check if we loaded this language before. */
+ for (slang = first_lang; slang != NULL; slang = slang->sl_next)
+ if (STRICMP(lang, slang->sl_name) == 0)
+ break;
+ }
+
+ if (region != NULL) {
+ /* If the region differs from what was used before then don't
+ * use it for 'spellfile'. */
+ if (use_region != NULL && STRCMP(region, use_region) != 0)
+ dont_use_region = TRUE;
+ use_region = region;
+ }
+
+ /* If not found try loading the language now. */
+ if (slang == NULL) {
+ if (filename)
+ (void)spell_load_file(lang, lang, NULL, FALSE);
+ else {
+ spell_load_lang(lang);
+ /* SpellFileMissing autocommands may do anything, including
+ * destroying the buffer we are using... */
+ if (!buf_valid(wp->w_buffer)) {
+ ret_msg =
+ (char_u *)"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 ? fullpathcmp(lang, slang->sl_fname, FALSE) == FPC_SAME
+ : STRICMP(lang, slang->sl_name) == 0) {
+ region_mask = REGION_ALL;
+ if (!filename && region != NULL) {
+ /* find region in sl_regions */
+ c = find_region(slang->sl_regions, region);
+ if (c == REGION_ALL) {
+ if (slang->sl_add) {
+ if (*slang->sl_regions != NUL)
+ /* This addition file is for other regions. */
+ region_mask = 0;
+ } else
+ /* This is probably an error. Give a warning and
+ * accept the words anyway. */
+ smsg((char_u *)
+ _("Warning: region %s not supported"),
+ region);
+ } else
+ region_mask = 1 << c;
+ }
+
+ if (region_mask != 0) {
+ if (ga_grow(&ga, 1) == FAIL) {
+ ga_clear(&ga);
+ ret_msg = e_outofmem;
+ goto theend;
+ }
+ LANGP_ENTRY(ga, ga.ga_len)->lp_slang = slang;
+ LANGP_ENTRY(ga, ga.ga_len)->lp_region = region_mask;
+ ++ga.ga_len;
+ use_midword(slang, wp);
+ if (slang->sl_nobreak)
+ nobreak = TRUE;
+ }
+ }
+ }
+
+ /* round 0: load int_wordlist, if possible.
+ * round 1: load first name in 'spellfile'.
+ * round 2: load second name in 'spellfile.
+ * etc. */
+ spf = curwin->w_s->b_p_spf;
+ for (round = 0; round == 0 || *spf != NUL; ++round) {
+ if (round == 0) {
+ /* Internal wordlist, if there is one. */
+ if (int_wordlist == NULL)
+ continue;
+ int_wordlist_spl(spf_name);
+ } else {
+ /* One entry in 'spellfile'. */
+ copy_option_part(&spf, spf_name, MAXPATHL - 5, ",");
+ STRCAT(spf_name, ".spl");
+
+ /* 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 && fullpathcmp(spf_name, p, FALSE) == FPC_SAME)
+ break;
+ }
+ if (c < ga.ga_len)
+ continue;
+ }
+
+ /* Check if it was loaded already. */
+ for (slang = first_lang; slang != NULL; slang = slang->sl_next)
+ if (fullpathcmp(spf_name, slang->sl_fname, FALSE) == FPC_SAME)
+ 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
+ * use an arbitrary name. */
+ if (round == 0)
+ STRCPY(lang, "internal wordlist");
+ else {
+ vim_strncpy(lang, gettail(spf_name), MAXWLEN);
+ p = vim_strchr(lang, '.');
+ if (p != NULL)
+ *p = NUL; /* truncate at ".encoding.add" */
+ }
+ slang = spell_load_file(spf_name, lang, NULL, TRUE);
+
+ /* If one of the languages has NOBREAK we assume the addition
+ * files also have this. */
+ if (slang != NULL && nobreak)
+ slang->sl_nobreak = TRUE;
+ }
+ if (slang != NULL && ga_grow(&ga, 1) == OK) {
+ region_mask = REGION_ALL;
+ if (use_region != NULL && !dont_use_region) {
+ /* find region in sl_regions */
+ c = find_region(slang->sl_regions, use_region);
+ if (c != REGION_ALL)
+ region_mask = 1 << c;
+ else if (*slang->sl_regions != NUL)
+ /* This spell file is for other regions. */
+ region_mask = 0;
+ }
+
+ if (region_mask != 0) {
+ LANGP_ENTRY(ga, ga.ga_len)->lp_slang = slang;
+ LANGP_ENTRY(ga, ga.ga_len)->lp_sallang = NULL;
+ LANGP_ENTRY(ga, ga.ga_len)->lp_replang = NULL;
+ LANGP_ENTRY(ga, ga.ga_len)->lp_region = region_mask;
+ ++ga.ga_len;
+ use_midword(slang, wp);
+ }
+ }
+ }
+
+ /* Everything is fine, store the new b_langp value. */
+ ga_clear(&wp->w_s->b_langp);
+ wp->w_s->b_langp = ga;
+
+ /* For each language figure out what language to use for sound folding and
+ * REP items. If the language doesn't support it itself use another one
+ * with the same name. E.g. for "en-math" use "en". */
+ for (i = 0; i < ga.ga_len; ++i) {
+ lp = LANGP_ENTRY(ga, i);
+
+ /* sound folding */
+ if (lp->lp_slang->sl_sal.ga_len > 0)
+ /* language does sound folding itself */
+ lp->lp_sallang = lp->lp_slang;
+ else
+ /* find first similar language that does sound folding */
+ for (j = 0; j < ga.ga_len; ++j) {
+ lp2 = LANGP_ENTRY(ga, j);
+ if (lp2->lp_slang->sl_sal.ga_len > 0
+ && STRNCMP(lp->lp_slang->sl_name,
+ lp2->lp_slang->sl_name, 2) == 0) {
+ lp->lp_sallang = lp2->lp_slang;
+ break;
+ }
+ }
+
+ /* REP items */
+ if (lp->lp_slang->sl_rep.ga_len > 0)
+ /* language has REP items itself */
+ lp->lp_replang = lp->lp_slang;
+ else
+ /* find first similar language that has REP items */
+ for (j = 0; j < ga.ga_len; ++j) {
+ lp2 = LANGP_ENTRY(ga, j);
+ if (lp2->lp_slang->sl_rep.ga_len > 0
+ && STRNCMP(lp->lp_slang->sl_name,
+ lp2->lp_slang->sl_name, 2) == 0) {
+ lp->lp_replang = lp2->lp_slang;
+ break;
+ }
+ }
+ }
+
+theend:
+ vim_free(spl_copy);
+ recursive = FALSE;
+ return ret_msg;
+}
+
+/*
+ * Clear the midword characters for buffer "buf".
+ */
+static void clear_midword(wp)
+win_T *wp;
+{
+ vim_memset(wp->w_s->b_spell_ismw, 0, 256);
+ vim_free(wp->w_s->b_spell_ismw_mb);
+ wp->w_s->b_spell_ismw_mb = NULL;
+}
+
+/*
+ * Use the "sl_midword" field of language "lp" for buffer "buf".
+ * They add up to any currently used midword characters.
+ */
+static void use_midword(lp, wp)
+slang_T *lp;
+win_T *wp;
+{
+ char_u *p;
+
+ if (lp->sl_midword == NULL) /* there aren't any */
+ return;
+
+ for (p = lp->sl_midword; *p != NUL; )
+ if (has_mbyte) {
+ int c, l, n;
+ char_u *bp;
+
+ c = mb_ptr2char(p);
+ l = (*mb_ptr2len)(p);
+ if (c < 256 && l <= 2)
+ wp->w_s->b_spell_ismw[c] = TRUE;
+ else if (wp->w_s->b_spell_ismw_mb == NULL)
+ /* First multi-byte char in "b_spell_ismw_mb". */
+ wp->w_s->b_spell_ismw_mb = vim_strnsave(p, l);
+ else {
+ /* Append multi-byte chars to "b_spell_ismw_mb". */
+ n = (int)STRLEN(wp->w_s->b_spell_ismw_mb);
+ bp = vim_strnsave(wp->w_s->b_spell_ismw_mb, n + l);
+ if (bp != NULL) {
+ vim_free(wp->w_s->b_spell_ismw_mb);
+ wp->w_s->b_spell_ismw_mb = bp;
+ vim_strncpy(bp + n, p, l);
+ }
+ }
+ p += l;
+ } else
+ wp->w_s->b_spell_ismw[*p++] = TRUE;
+}
+
+/*
+ * Find the region "region[2]" in "rp" (points to "sl_regions").
+ * Each region is simply stored as the two characters of it's name.
+ * Returns the index if found (first is 0), REGION_ALL if not found.
+ */
+static int find_region(rp, region)
+char_u *rp;
+char_u *region;
+{
+ int i;
+
+ for (i = 0;; i += 2) {
+ if (rp[i] == NUL)
+ return REGION_ALL;
+ if (rp[i] == region[0] && rp[i + 1] == region[1])
+ break;
+ }
+ 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(word, end)
+char_u *word;
+char_u *end; /* When NULL use up to NUL byte. */
+{
+ char_u *p;
+ int c;
+ int firstcap;
+ int allcap;
+ int 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)
+ return 0; /* only non-word characters, illegal word */
+ if (has_mbyte)
+ c = mb_ptr2char_adv(&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))
+ if (spell_iswordp_nmw(p, curwin)) {
+ c = PTR2CHAR(p);
+ if (!SPELL_ISUPPER(c)) {
+ /* UUl -> KEEPCAP */
+ if (past_second && allcap)
+ return WF_KEEPCAP;
+ allcap = FALSE;
+ } else if (!allcap)
+ /* UlU -> KEEPCAP */
+ return WF_KEEPCAP;
+ past_second = TRUE;
+ }
+
+ if (allcap)
+ return WF_ALLCAP;
+ if (firstcap)
+ return WF_ONECAP;
+ return 0;
+}
+
+/*
+ * Like captype() but for a KEEPCAP word add ONECAP if the word starts with a
+ * capital. So that make_case_word() can turn WOrd into Word.
+ * Add ALLCAP for "WOrD".
+ */
+static int badword_captype(word, end)
+char_u *word;
+char_u *end;
+{
+ int flags = captype(word, end);
+ int c;
+ int l, u;
+ int first;
+ char_u *p;
+
+ if (flags & WF_KEEPCAP) {
+ /* Count the number of UPPER and lower case letters. */
+ l = u = 0;
+ first = FALSE;
+ for (p = word; p < end; mb_ptr_adv(p)) {
+ c = PTR2CHAR(p);
+ if (SPELL_ISUPPER(c)) {
+ ++u;
+ if (p == word)
+ first = TRUE;
+ } else
+ ++l;
+ }
+
+ /* If there are more UPPER than lower case letters suggest an
+ * ALLCAP word. Otherwise, if the first letter is UPPER then
+ * suggest ONECAP. Exception: "ALl" most likely should be "All",
+ * require three upper case letters. */
+ if (u > l && u > 2)
+ flags |= WF_ALLCAP;
+ else if (first)
+ flags |= WF_ONECAP;
+
+ if (u >= 2 && l >= 2) /* maCARONI maCAroni */
+ flags |= WF_MIXCAP;
+ }
+ return flags;
+}
+
+/*
+ * Delete the internal wordlist and its .spl file.
+ */
+void spell_delete_wordlist() {
+ char_u fname[MAXPATHL];
+
+ if (int_wordlist != NULL) {
+ mch_remove(int_wordlist);
+ int_wordlist_spl(fname);
+ mch_remove(fname);
+ vim_free(int_wordlist);
+ int_wordlist = NULL;
+ }
+}
+
+/*
+ * Free all languages.
+ */
+void spell_free_all() {
+ slang_T *slang;
+ buf_T *buf;
+
+ /* Go through all buffers and handle 'spelllang'. <VN> */
+ for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+ ga_clear(&buf->b_s.b_langp);
+
+ while (first_lang != NULL) {
+ slang = first_lang;
+ first_lang = slang->sl_next;
+ slang_free(slang);
+ }
+
+ spell_delete_wordlist();
+
+ vim_free(repl_to);
+ repl_to = NULL;
+ vim_free(repl_from);
+ repl_from = NULL;
+}
+
+/*
+ * Clear all spelling tables and reload them.
+ * Used after 'encoding' is set and when ":mkspell" was used.
+ */
+void spell_reload() {
+ win_T *wp;
+
+ /* Initialize the table for spell_iswordp(). */
+ init_spell_chartab();
+
+ /* Unload all allocated memory. */
+ spell_free_all();
+
+ /* Go through all buffers and handle 'spelllang'. */
+ for (wp = firstwin; wp != NULL; wp = wp->w_next) {
+ /* Only load the wordlists when 'spelllang' is set and there is a
+ * window for this buffer in which 'spell' is set. */
+ if (*wp->w_s->b_p_spl != NUL) {
+ if (wp->w_p_spell) {
+ (void)did_set_spelllang(wp);
+ break;
+ }
+ }
+ }
+}
+
+/*
+ * Reload the spell file "fname" if it's loaded.
+ */
+static void spell_reload_one(fname, added_word)
+char_u *fname;
+int added_word; /* invoked through "zg" */
+{
+ slang_T *slang;
+ int didit = FALSE;
+
+ for (slang = first_lang; slang != NULL; slang = slang->sl_next) {
+ if (fullpathcmp(fname, slang->sl_fname, FALSE) == FPC_SAME) {
+ 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".
+ */
+
+#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 */
+ 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 */
+ short_u 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_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 afffile_T *spell_read_aff __ARGS((spellinfo_T *spin, char_u *fname));
+static int is_aff_rule __ARGS((char_u **items, int itemcnt, char *rulename,
+ int mincount));
+static void aff_process_flags __ARGS((afffile_T *affile, affentry_T *entry));
+static int spell_info_item __ARGS((char_u *s));
+static unsigned affitem2flag __ARGS((int flagtype, char_u *item, char_u *fname,
+ int lnum));
+static unsigned get_affitem __ARGS((int flagtype, char_u **pp));
+static void process_compflags __ARGS((spellinfo_T *spin, afffile_T *aff,
+ char_u *compflags));
+static void check_renumber __ARGS((spellinfo_T *spin));
+static int flag_in_afflist __ARGS((int flagtype, char_u *afflist, unsigned flag));
+static void aff_check_number __ARGS((int spinval, int affval, char *name));
+static void aff_check_string __ARGS((char_u *spinval, char_u *affval,
+ char *name));
+static int str_equal __ARGS((char_u *s1, char_u *s2));
+static void add_fromto __ARGS((spellinfo_T *spin, garray_T *gap, char_u *from,
+ char_u *to));
+static int sal_to_bool __ARGS((char_u *s));
+static void spell_free_aff __ARGS((afffile_T *aff));
+static int spell_read_dic __ARGS((spellinfo_T *spin, char_u *fname,
+ afffile_T *affile));
+static int get_affix_flags __ARGS((afffile_T *affile, char_u *afflist));
+static int get_pfxlist __ARGS((afffile_T *affile, char_u *afflist,
+ char_u *store_afflist));
+static void get_compflags __ARGS((afffile_T *affile, char_u *afflist,
+ char_u *store_afflist));
+static int store_aff_word __ARGS((spellinfo_T *spin, char_u *word, char_u *
+ afflist, afffile_T *affile, hashtab_T *ht,
+ hashtab_T *xht, int condit, int flags,
+ char_u *pfxlist,
+ int pfxlen));
+static int spell_read_wordfile __ARGS((spellinfo_T *spin, char_u *fname));
+static void *getroom __ARGS((spellinfo_T *spin, size_t len, int align));
+static char_u *getroom_save __ARGS((spellinfo_T *spin, char_u *s));
+static void free_blocks __ARGS((sblock_T *bl));
+static wordnode_T *wordtree_alloc __ARGS((spellinfo_T *spin));
+static int store_word __ARGS((spellinfo_T *spin, char_u *word, int flags,
+ int region, char_u *pfxlist,
+ int need_affix));
+static int tree_add_word __ARGS((spellinfo_T *spin, char_u *word, wordnode_T *
+ tree, int flags, int region,
+ int affixID));
+static wordnode_T *get_wordnode __ARGS((spellinfo_T *spin));
+static int deref_wordnode __ARGS((spellinfo_T *spin, wordnode_T *node));
+static void free_wordnode __ARGS((spellinfo_T *spin, wordnode_T *n));
+static void wordtree_compress __ARGS((spellinfo_T *spin, wordnode_T *root));
+static int node_compress __ARGS((spellinfo_T *spin, wordnode_T *node,
+ hashtab_T *ht,
+ int *tot));
+static int node_equal __ARGS((wordnode_T *n1, wordnode_T *n2));
+static int write_vim_spell __ARGS((spellinfo_T *spin, char_u *fname));
+static void clear_node __ARGS((wordnode_T *node));
+static int put_node __ARGS((FILE *fd, wordnode_T *node, int idx, int regionmask,
+ int prefixtree));
+static void spell_make_sugfile __ARGS((spellinfo_T *spin, char_u *wfname));
+static int sug_filltree __ARGS((spellinfo_T *spin, slang_T *slang));
+static int sug_maketable __ARGS((spellinfo_T *spin));
+static int sug_filltable __ARGS((spellinfo_T *spin, wordnode_T *node,
+ int startwordnr,
+ garray_T *gap));
+static int offset2bytes __ARGS((int nr, char_u *buf));
+static int bytes2offset __ARGS((char_u **pp));
+static void sug_write __ARGS((spellinfo_T *spin, char_u *fname));
+static void mkspell __ARGS((int fcount, char_u **fnames, int ascii,
+ int over_write,
+ int added_word));
+static void spell_message __ARGS((spellinfo_T *spin, char_u *str));
+static void init_spellfile __ARGS((void));
+
+/* 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(line1);
+ msg(line2);
+ msg(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(line1);
+ msg(line2);
+ msg(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 */
+
+/*
+ * Read the affix file "fname".
+ * Returns an afffile_T, NULL for complete failure.
+ */
+static afffile_T * spell_read_aff(spin, fname)
+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;
+ int 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;
+ int 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 = spin->si_rep.ga_len == 0;
+
+ /* Only do REPSAL lines when not done in another .aff file already. */
+ do_repsal = spin->si_repsal.ga_len == 0;
+
+ /* Only do SAL lines when not done in another .aff file already. */
+ do_sal = spin->si_sal.ga_len == 0;
+
+ /* Only do MAP lines when not done in another .aff file already. */
+ do_mapline = spin->si_map.ga_len == 0;
+
+ /*
+ * 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. */
+ vim_free(pc);
+ if (spin->si_conv.vc_type != CONV_NONE) {
+ pc = string_convert(&spin->si_conv, rline, NULL);
+ if (pc == NULL) {
+ smsg((char_u *)_("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 (aff->af_enc != NULL && !spin->si_ascii
+ && convert_setup(&spin->si_conv, aff->af_enc,
+ p_enc) == FAIL)
+ smsg((char_u *)_("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((char_u *)_("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((char_u *)_("FLAG after using flags in %s line %d: %s"),
+ fname, lnum, items[1]);
+ } else if (spell_info_item(items[0])) {
+ 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((char_u *)_(
+ "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((char_u *)_(
+ "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);
+ if (p != NULL) {
+ 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((char_u *)_("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 (p != NULL) {
+ 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((char_u *)_("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((char_u *)_("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((char_u *)_("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((char_u *)_("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) == OK) {
+ ((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, "NOSUGFILE", 1)) {
+ spin->si_nosugfile = TRUE;
+ } else if (is_aff_rule(items, itemcnt, "PFXPOSTPONE", 1)) {
+ aff->af_pfxpostpone = 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. */
+ vim_strncpy(key, items[1], AH_KEY_LEN - 1);
+ hi = hash_find(tp, key);
+ if (!HASHITEM_EMPTY(hi)) {
+ cur_aff = HI2AH(hi);
+ if (cur_aff->ah_combine != (*items[2] == 'Y'))
+ smsg((char_u *)_(
+ "Different combining flag in continued affix block in %s line %d: %s"),
+ fname, lnum, items[1]);
+ if (!cur_aff->ah_follows)
+ smsg((char_u *)_("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((char_u *)_(
+ "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. */
+ if (itemcnt > lasti && *items[lasti] != '#')
+ smsg((char_u *)_(e_afftrailing), fname, lnum, items[lasti]);
+
+ if (STRCMP(items[2], "Y") != 0 && STRCMP(items[2], "N") != 0)
+ smsg((char_u *)_("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;
+ int 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((char_u *)_(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((char_u *)_("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 && ga_grow(&spin->si_prefcond, 1) == OK) {
+ /* Not found, add a new condition. */
+ idx = spin->si_prefcond.ga_len++;
+ pp = ((char_u **)spin->si_prefcond.ga_data)
+ + idx;
+ if (aff_entry->ae_cond == NULL)
+ *pp = NULL;
+ else
+ *pp = 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((char_u *)_("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((char_u *)_(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((char_u *)_("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 ((spin->si_map.ga_len > 0
+ && vim_strchr(spin->si_map.ga_data, c)
+ != NULL)
+ || vim_strchr(p, c) != NULL)
+ smsg((char_u *)_("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]);
+ if (p == NULL)
+ break;
+ hash_add(&spin->si_commonwords, p);
+ }
+ }
+ } else
+ smsg((char_u *)_("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((char_u *)_("Missing FOL/LOW/UPP line in %s"), fname);
+ else
+ (void)set_spell_chartab(fol, low, upp);
+ }
+
+ vim_free(fol);
+ vim_free(low);
+ vim_free(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((char_u *)_("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((char_u *)_("Missing SOFO%s line in %s"),
+ sofofrom == NULL ? "FROM" : "TO", fname);
+ else if (spin->si_sal.ga_len > 0)
+ smsg((char_u *)_("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;
+ }
+
+ vim_free(pc);
+ fclose(fd);
+ return aff;
+}
+
+/*
+ * Return TRUE when items[0] equals "rulename", there are "mincount" items or
+ * a comment is following after item "mincount".
+ */
+static int is_aff_rule(items, itemcnt, rulename, mincount)
+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(affile, entry)
+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 */
+ }
+}
+
+/*
+ * Return TRUE if "s" is the name of an info item in the affix file.
+ */
+static int spell_info_item(s)
+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(flagtype, item, fname, lnum)
+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((char_u *)_("Flag is not a number in %s line %d: %s"),
+ fname, lnum, item);
+ else
+ smsg((char_u *)_("Illegal flag in %s line %d: %s"),
+ fname, lnum, item);
+ }
+ if (*p != NUL) {
+ smsg((char_u *)_(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(flagtype, pp)
+int flagtype;
+char_u **pp;
+{
+ int res;
+
+ if (flagtype == AFT_NUM) {
+ if (!VIM_ISDIGIT(**pp)) {
+ ++*pp; /* always advance, avoid getting stuck */
+ return 0;
+ }
+ res = getdigits(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(spin, aff, 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 (p == NULL)
+ return;
+ 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. */
+ vim_strncpy(key, prevp, p - prevp);
+ 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(spin)
+spellinfo_T *spin;
+{
+ if (spin->si_newprefID == spin->si_newcompID && spin->si_newcompID < 128) {
+ spin->si_newprefID = 127;
+ spin->si_newcompID = 255;
+ }
+}
+
+/*
+ * Return TRUE if flag "flag" appears in affix list "afflist".
+ */
+static int flag_in_afflist(flagtype, afflist, flag)
+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; ) {
+ n = getdigits(&p);
+ 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(spinval, affval, name)
+int spinval;
+int affval;
+char *name;
+{
+ if (spinval != 0 && spinval != affval)
+ smsg((char_u *)_(
+ "%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(spinval, affval, name)
+char_u *spinval;
+char_u *affval;
+char *name;
+{
+ if (spinval != NULL && STRCMP(spinval, affval) != 0)
+ smsg((char_u *)_(
+ "%s value differs from what is used in another .aff file"), name);
+}
+
+/*
+ * Return TRUE if strings "s1" and "s2" are equal. Also consider both being
+ * NULL as equal.
+ */
+static int str_equal(s1, s2)
+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(spin, gap, from, to)
+spellinfo_T *spin;
+garray_T *gap;
+char_u *from;
+char_u *to;
+{
+ fromto_T *ftp;
+ char_u word[MAXWLEN];
+
+ if (ga_grow(gap, 1) == OK) {
+ ftp = ((fromto_T *)gap->ga_data) + gap->ga_len;
+ (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);
+ ++gap->ga_len;
+ }
+}
+
+/*
+ * Convert a boolean argument in a SAL line to TRUE or FALSE;
+ */
+static int sal_to_bool(s)
+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(aff)
+afffile_T *aff;
+{
+ hashtab_T *ht;
+ hashitem_T *hi;
+ int todo;
+ affheader_T *ah;
+ affentry_T *ae;
+
+ vim_free(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(spin, fname, affile)
+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;
+ int 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 (!vim_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
+ * the word is kept to allow e.g., "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((char_u *)_("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;
+ vim_free(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;
+ out_flush();
+ }
+
+ /* Store the word in the hashtable to be able to find duplicates. */
+ dw = (char_u *)getroom_save(spin, w);
+ if (dw == NULL) {
+ retval = FAIL;
+ vim_free(pc);
+ break;
+ }
+
+ hash = hash_hash(dw);
+ hi = hash_lookup(&ht, dw, hash);
+ if (!HASHITEM_EMPTY(hi)) {
+ if (p_verbose > 0)
+ smsg((char_u *)_("Duplicate word in %s line %d: %s"),
+ fname, lnum, dw);
+ else if (duplicate == 0)
+ smsg((char_u *)_("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;
+ }
+
+ vim_free(pc);
+ }
+
+ if (duplicate > 0)
+ smsg((char_u *)_("%d duplicate word(s) in %s"), duplicate, fname);
+ if (spin->si_ascii && non_ascii > 0)
+ smsg((char_u *)_("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(affile, afflist)
+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(affile, afflist, store_afflist)
+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. */
+ vim_strncpy(key, prevp, p - prevp);
+ 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(affile, afflist, store_afflist)
+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". */
+ vim_strncpy(key, prevp, p - prevp);
+ 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(spin, word, afflist, affile, ht, xht, condit, flags,
+ pfxlist, pfxlen)
+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;
+ regmatch_T regmatch;
+ char_u newword[MAXWLEN];
+ int retval = OK;
+ int i, j;
+ char_u *p;
+ int use_flags;
+ char_u *use_pfxlist;
+ int use_pfxlen;
+ int 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. */
+ regmatch.regprog = ae->ae_prog;
+ regmatch.rm_ic = FALSE;
+ 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(&regmatch, 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
+ vim_strncpy(newword, ae->ae_add, MAXWLEN - 1);
+ 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 */
+ vim_strncpy(newword, word, MAXWLEN - 1);
+ 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);
+
+ /* 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) {
+ vim_strncpy(pfx_pfxlist, use_pfxlist, use_pfxlen);
+ 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(spin, fname)
+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;
+ int 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. */
+ vim_free(pc);
+ if (spin->si_conv.vc_type != CONV_NONE) {
+ pc = string_convert(&spin->si_conv, rline, NULL);
+ if (pc == NULL) {
+ smsg((char_u *)_("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((char_u *)_(
+ "Duplicate /encoding= line ignored in %s line %d: %s"),
+ fname, lnum, line - 1);
+ else if (did_word)
+ smsg((char_u *)_(
+ "/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 (enc != NULL && !spin->si_ascii
+ && convert_setup(&spin->si_conv, enc,
+ p_enc) == FAIL)
+ smsg((char_u *)_("Conversion in %s not supported: from %s to %s"),
+ fname, line, p_enc);
+ vim_free(enc);
+ spin->si_conv.vc_fail = TRUE;
+ }
+ continue;
+ }
+
+ if (STRNCMP(line, "regions=", 8) == 0) {
+ if (spin->si_region_count > 1)
+ smsg((char_u *)_("Duplicate /regions= line ignored in %s line %d: %s"),
+ fname, lnum, line);
+ else {
+ line += 8;
+ if (STRLEN(line) > 16)
+ smsg((char_u *)_("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((char_u *)_("/ 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 (VIM_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((char_u *)_("Invalid region nr in %s line %d: %s"),
+ fname, lnum, p);
+ break;
+ }
+ regionmask |= 1 << (l - 1);
+ } else {
+ smsg((char_u *)_("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;
+ }
+
+ vim_free(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.
+ * Returns NULL when out of memory.
+ */
+static void * getroom(spin, len, align)
+spellinfo_T *spin;
+size_t len; /* length needed */
+int align; /* align for pointer */
+{
+ char_u *p;
+ sblock_T *bl = spin->si_blocks;
+
+ 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) {
+ if (len >= SBLOCKSIZE)
+ bl = NULL;
+ else
+ /* Allocate a block of memory. It is not freed until much later. */
+ bl = (sblock_T *)alloc_clear(
+ (unsigned)(sizeof(sblock_T) + SBLOCKSIZE));
+ if (bl == NULL) {
+ if (!spin->si_did_emsg) {
+ EMSG(_("E845: Insufficient memory, word list will be incomplete"));
+ spin->si_did_emsg = TRUE;
+ }
+ return NULL;
+ }
+ 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(spin, s)
+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(bl)
+sblock_T *bl;
+{
+ sblock_T *next;
+
+ while (bl != NULL) {
+ next = bl->sb_next;
+ vim_free(bl);
+ bl = next;
+ }
+}
+
+/*
+ * Allocate the root of a word tree.
+ * Returns NULL when out of memory.
+ */
+static wordnode_T * wordtree_alloc(spin)
+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(spin, word, flags, region, pfxlist, need_affix)
+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 */
+int 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(spin, word, root, flags, region, affixID)
+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("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_PRINTTREE
+ if (spin->si_compress_cnt == 1
+ ? 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;
+ out_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() {
+ char_u *p = p_msm;
+ long start = 0;
+ long incr = 0;
+ long added = 0;
+
+ if (!VIM_ISDIGIT(*p))
+ return FAIL;
+ /* block count = (value * 1024) / SBLOCKSIZE (but avoid overflow)*/
+ start = (getdigits(&p) * 10) / (SBLOCKSIZE / 102);
+ if (*p != ',')
+ return FAIL;
+ ++p;
+ if (!VIM_ISDIGIT(*p))
+ return FAIL;
+ incr = (getdigits(&p) * 102) / (SBLOCKSIZE / 10);
+ if (*p != ',')
+ return FAIL;
+ ++p;
+ if (!VIM_ISDIGIT(*p))
+ return FAIL;
+ added = getdigits(&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(spin)
+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;
+ vim_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(spin, node)
+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(spin, n)
+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(spin, root)
+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(spin, node, ht, tot)
+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 + ((long_u)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;
+}
+
+/*
+ * Return TRUE when two nodes have identical siblings and children.
+ */
+static int node_equal(n1, n2)
+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;
+}
+
+static int
+rep_compare __ARGS((const void *s1, const void *s2));
+
+/*
+ * Function given to qsort() to sort the REP items on "from" string.
+ */
+static int rep_compare(s1, s2)
+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 FAIL or OK;
+ */
+static int write_vim_spell(spin, fname)
+spellinfo_T *spin;
+char_u *fname;
+{
+ FILE *fd;
+ int regionmask;
+ int round;
+ wordnode_T *tree;
+ int nodecount;
+ int i;
+ int l;
+ garray_T *gap;
+ fromto_T *ftp;
+ char_u *p;
+ int rr;
+ int retval = OK;
+ size_t fwv = 1; /* collect return value of fwrite() to avoid
+ warnings from picky compiler */
+
+ fd = mch_fopen((char *)fname, "w");
+ if (fd == NULL) {
+ EMSG2(_(e_notopen), fname);
+ return FAIL;
+ }
+
+ /* <HEADER>: <fileID> <versionnr> */
+ /* <fileID> */
+ fwv &= fwrite(VIMSPELLMAGIC, VIMSPELLMAGICL, (size_t)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> */
+
+ i = (int)STRLEN(spin->si_info);
+ put_bytes(fd, (long_u)i, 4); /* <sectionlen> */
+ fwv &= fwrite(spin->si_info, (size_t)i, (size_t)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> */
+ l = spin->si_region_count * 2;
+ put_bytes(fd, (long_u)l, 4); /* <sectionlen> */
+ fwv &= fwrite(spin->si_region_name, (size_t)l, (size_t)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. */
+ l = 0;
+ for (i = 128; i < 256; ++i) {
+ if (has_mbyte)
+ l += mb_char2bytes(spelltab.st_fold[i], folchars + l);
+ else
+ folchars[l++] = spelltab.st_fold[i];
+ }
+ put_bytes(fd, (long_u)(1 + 128 + 2 + l), 4); /* <sectionlen> */
+
+ fputc(128, fd); /* <charflagslen> */
+ for (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, (long_u)l, 2); /* <folcharslen> */
+ fwv &= fwrite(folchars, (size_t)l, (size_t)1, fd); /* <folchars> */
+ }
+
+ /* SN_MIDWORD: <midword> */
+ if (spin->si_midword != NULL) {
+ putc(SN_MIDWORD, fd); /* <sectionID> */
+ putc(SNF_REQUIRED, fd); /* <sectionflags> */
+
+ i = (int)STRLEN(spin->si_midword);
+ put_bytes(fd, (long_u)i, 4); /* <sectionlen> */
+ fwv &= fwrite(spin->si_midword, (size_t)i, (size_t)1, fd);
+ /* <midword> */
+ }
+
+ /* SN_PREFCOND: <prefcondcnt> <prefcond> ... */
+ if (spin->si_prefcond.ga_len > 0) {
+ putc(SN_PREFCOND, fd); /* <sectionID> */
+ putc(SNF_REQUIRED, fd); /* <sectionflags> */
+
+ l = write_spell_prefcond(NULL, &spin->si_prefcond);
+ put_bytes(fd, (long_u)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 (round = 1; round <= 3; ++round) {
+ 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 (gap->ga_len == 0)
+ continue;
+
+ /* Sort the REP/REPSAL items. */
+ if (round != 2)
+ qsort(gap->ga_data, (size_t)gap->ga_len,
+ sizeof(fromto_T), rep_compare);
+
+ 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. */
+ l = 2; /* count <repcount> or <salcount> */
+ for (i = 0; i < gap->ga_len; ++i) {
+ ftp = &((fromto_T *)gap->ga_data)[i];
+ l += 1 + (int)STRLEN(ftp->ft_from); /* count <*fromlen> and <*from> */
+ l += 1 + (int)STRLEN(ftp->ft_to); /* count <*tolen> and <*to> */
+ }
+ if (round == 2)
+ ++l; /* count <salflags> */
+ put_bytes(fd, (long_u)l, 4); /* <sectionlen> */
+
+ if (round == 2) {
+ 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, (long_u)gap->ga_len, 2); /* <repcount> or <salcount> */
+ for (i = 0; i < gap->ga_len; ++i) {
+ /* <rep> : <repfromlen> <repfrom> <reptolen> <repto> */
+ /* <sal> : <salfromlen> <salfrom> <saltolen> <salto> */
+ ftp = &((fromto_T *)gap->ga_data)[i];
+ for (rr = 1; rr <= 2; ++rr) {
+ p = rr == 1 ? ftp->ft_from : ftp->ft_to;
+ l = (int)STRLEN(p);
+ putc(l, fd);
+ if (l > 0)
+ fwv &= fwrite(p, l, (size_t)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> */
+
+ l = (int)STRLEN(spin->si_sofofr);
+ put_bytes(fd, (long_u)(l + STRLEN(spin->si_sofoto) + 4), 4);
+ /* <sectionlen> */
+
+ put_bytes(fd, (long_u)l, 2); /* <sofofromlen> */
+ fwv &= fwrite(spin->si_sofofr, l, (size_t)1, fd); /* <sofofrom> */
+
+ l = (int)STRLEN(spin->si_sofoto);
+ put_bytes(fd, (long_u)l, 2); /* <sofotolen> */
+ fwv &= fwrite(spin->si_sofoto, l, (size_t)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 (round = 1; round <= 2; ++round) {
+ int todo;
+ int len = 0;
+ hashitem_T *hi;
+
+ todo = (int)spin->si_commonwords.ht_used;
+ for (hi = spin->si_commonwords.ht_array; todo > 0; ++hi)
+ if (!HASHITEM_EMPTY(hi)) {
+ l = (int)STRLEN(hi->hi_key) + 1;
+ len += l;
+ if (round == 2) /* <word> */
+ fwv &= fwrite(hi->hi_key, (size_t)l, (size_t)1, fd);
+ --todo;
+ }
+ if (round == 1)
+ put_bytes(fd, (long_u)len, 4); /* <sectionlen> */
+ }
+ }
+
+ /* SN_MAP: <mapstr>
+ * This is for making suggestions, section is not required. */
+ if (spin->si_map.ga_len > 0) {
+ putc(SN_MAP, fd); /* <sectionID> */
+ putc(0, fd); /* <sectionflags> */
+ l = spin->si_map.ga_len;
+ put_bytes(fd, (long_u)l, 4); /* <sectionlen> */
+ fwv &= fwrite(spin->si_map.ga_data, (size_t)l, (size_t)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
+ && (spin->si_sal.ga_len > 0
+ || (spin->si_sofofr != NULL && spin->si_sofoto != NULL))) {
+ putc(SN_SUGFILE, fd); /* <sectionID> */
+ putc(0, fd); /* <sectionflags> */
+ put_bytes(fd, (long_u)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, (long_u)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> */
+
+ l = (int)STRLEN(spin->si_compflags);
+ for (i = 0; i < spin->si_comppat.ga_len; ++i)
+ l += (int)STRLEN(((char_u **)(spin->si_comppat.ga_data))[i]) + 1;
+ put_bytes(fd, (long_u)(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, (long_u)spin->si_comppat.ga_len, 2);
+ /* <comppatcount> */
+ for (i = 0; i < spin->si_comppat.ga_len; ++i) {
+ p = ((char_u **)(spin->si_comppat.ga_data))[i];
+ putc((int)STRLEN(p), fd); /* <comppatlen> */
+ fwv &= fwrite(p, (size_t)STRLEN(p), (size_t)1, fd);
+ /* <comppattext> */
+ }
+ /* <compflags> */
+ fwv &= fwrite(spin->si_compflags, (size_t)STRLEN(spin->si_compflags),
+ (size_t)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, (long_u)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> */
+
+ l = (int)STRLEN(spin->si_syllable);
+ put_bytes(fd, (long_u)l, 4); /* <sectionlen> */
+ fwv &= fwrite(spin->si_syllable, (size_t)l, (size_t)1, fd);
+ /* <syllable> */
+ }
+
+ /* end of <SECTIONS> */
+ putc(SN_END, fd); /* <sectionend> */
+
+
+ /*
+ * <LWORDTREE> <KWORDTREE> <PREFIXTREE>
+ */
+ spin->si_memtot = 0;
+ for (round = 1; round <= 3; ++round) {
+ 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. */
+ nodecount = put_node(NULL, tree, 0, regionmask, round == 3);
+
+ /* number of nodes in 4 bytes */
+ put_bytes(fd, (long_u)nodecount, 4); /* <nodecount> */
+ spin->si_memtot += 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(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(fd, node, idx, regionmask, prefixtree)
+FILE *fd; /* NULL when only counting */
+wordnode_T *node;
+int idx;
+int regionmask;
+int prefixtree; /* TRUE for PREFIXTREE */
+{
+ int newindex = idx;
+ int siblingcount = 0;
+ wordnode_T *np;
+ int flags;
+
+ /* 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. */
+ for (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 (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 == (short_u)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, (long_u)np->wn_region, 2); /* <prefcondnr> */
+ } else {
+ /* For word trees we write the flag/region items. */
+ 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((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> */
+ /* <nodeidx> */
+ put_bytes(fd, (long_u)np->wn_child->wn_u1.index, 3);
+ }
+ } 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. */
+ newindex += siblingcount + 1;
+
+ /* Recursively dump the children of each sibling. */
+ for (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(eap)
+exarg_T *eap;
+{
+ int fcount;
+ char_u **fnames;
+ char_u *arg = eap->arg;
+ int 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(spin, wfname)
+spellinfo_T *spin;
+char_u *wfname;
+{
+ char_u *fname = NULL;
+ int len;
+ slang_T *slang;
+ int 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 (fullpathcmp(wfname, slang->sl_fname, FALSE) == FPC_SAME)
+ 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((char_u *)_("Number of words after soundfolding: %ld"),
+ (long)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 = alloc(MAXPATHL);
+ if (fname == NULL)
+ goto theend;
+ vim_strncpy(fname, wfname, MAXPATHL - 1);
+ len = (int)STRLEN(fname);
+ fname[len - 2] = 'u';
+ fname[len - 1] = 'g';
+ sug_write(spin, fname);
+
+theend:
+ vim_free(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(spin, slang)
+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((char_u *)_("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(spin)
+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();
+ if (spin->si_spellbuf == NULL)
+ return FAIL;
+
+ /* Use a buffer to store the line info, avoids allocating many small
+ * pieces of memory. */
+ ga_init2(&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(spin, node, startwordnr, gap)
+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) {
+ if (ga_grow(gap, 10) == FAIL)
+ return -1;
+
+ 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(nr, buf)
+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.
+ * Returns the offset.
+ */
+static int bytes2offset(pp)
+char_u **pp;
+{
+ char_u *p = *pp;
+ int nr;
+ int c;
+
+ c = *p++;
+ if ((c & 0x80) == 0x00) { /* 1 byte */
+ nr = c - 1;
+ } else if ((c & 0xc0) == 0x80) { /* 2 bytes */
+ nr = (c & 0x3f) - 1;
+ nr = nr * 255 + (*p++ - 1);
+ } else if ((c & 0xe0) == 0xc0) { /* 3 bytes */
+ nr = (c & 0x1f) - 1;
+ nr = nr * 255 + (*p++ - 1);
+ nr = nr * 255 + (*p++ - 1);
+ } else { /* 4 bytes */
+ nr = (c & 0x0f) - 1;
+ nr = nr * 255 + (*p++ - 1);
+ nr = nr * 255 + (*p++ - 1);
+ nr = nr * 255 + (*p++ - 1);
+ }
+
+ *pp = p;
+ return nr;
+}
+
+/*
+ * Write the .sug file in "fname".
+ */
+static void sug_write(spin, fname)
+spellinfo_T *spin;
+char_u *fname;
+{
+ FILE *fd;
+ wordnode_T *tree;
+ int nodecount;
+ int wcount;
+ char_u *line;
+ linenr_T lnum;
+ int len;
+
+ /* Create the file. Note that an existing file is silently overwritten! */
+ 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;
+ 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. */
+ nodecount = put_node(NULL, tree, 0, 0, FALSE);
+
+ /* number of nodes in 4 bytes */
+ put_bytes(fd, (long_u)nodecount, 4); /* <nodecount> */
+ spin->si_memtot += nodecount + nodecount * sizeof(int);
+
+ /* Write the nodes. */
+ (void)put_node(fd, tree, 0, 0, FALSE);
+
+ /*
+ * <SUGTABLE>: <sugwcount> <sugline> ...
+ */
+ wcount = spin->si_spellbuf->b_ml.ml_line_count;
+ put_bytes(fd, (long_u)wcount, 4); /* <sugwcount> */
+
+ for (lnum = 1; lnum <= (linenr_T)wcount; ++lnum) {
+ /* <sugline>: <sugnr> ... NUL */
+ line = ml_get_buf(spin->si_spellbuf, lnum, FALSE);
+ len = (int)STRLEN(line) + 1;
+ if (fwrite(line, (size_t)len, (size_t)1, fd) == 0) {
+ EMSG(_(e_write));
+ goto theend;
+ }
+ spin->si_memtot += 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.
+ * Returns NULL when out of memory.
+ */
+static buf_T * open_spellbuf() {
+ buf_T *buf;
+
+ buf = (buf_T *)alloc_clear(sizeof(buf_T));
+ if (buf != NULL) {
+ buf->b_spell = TRUE;
+ buf->b_p_swf = TRUE; /* may create a swap file */
+ buf->b_p_key = empty_option;
+ ml_open(buf);
+ ml_open_file(buf); /* create swap file now */
+ }
+ return buf;
+}
+
+/*
+ * Close the buffer used for spell info.
+ */
+static void close_spellbuf(buf)
+buf_T *buf;
+{
+ if (buf != NULL) {
+ ml_close(buf, TRUE);
+ vim_free(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(fcount, fnames, ascii, over_write, added_word)
+int fcount;
+char_u **fnames;
+int ascii; /* -ascii argument given */
+int over_write; /* overwrite existing output file */
+int 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;
+ struct stat st;
+ int error = FALSE;
+ spellinfo_T spin;
+
+ vim_memset(&spin, 0, sizeof(spin));
+ spin.si_verbose = !added_word;
+ spin.si_ascii = ascii;
+ spin.si_followup = TRUE;
+ spin.si_rem_accents = TRUE;
+ ga_init2(&spin.si_rep, (int)sizeof(fromto_T), 20);
+ ga_init2(&spin.si_repsal, (int)sizeof(fromto_T), 20);
+ ga_init2(&spin.si_sal, (int)sizeof(fromto_T), 20);
+ ga_init2(&spin.si_map, (int)sizeof(char_u), 100);
+ ga_init2(&spin.si_comppat, (int)sizeof(char_u *), 20);
+ ga_init2(&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 = alloc(MAXPATHL);
+ if (wfname == NULL)
+ return;
+
+ 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. */
+ vim_strncpy(wfname, fnames[0], MAXPATHL - 1);
+ } 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 *)gettail(wfname), SPL_FNAME_ASCII) != NULL)
+ spin.si_ascii = TRUE;
+
+ /* Check for .add.spl. */
+ if (strstr((char *)gettail(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(gettail(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 && mch_stat((char *)wfname, &st) >= 0) {
+ EMSG(_(e_exists));
+ goto theend;
+ }
+ if (mch_isdir(wfname)) {
+ EMSG2(_(e_isadir2), wfname);
+ goto theend;
+ }
+
+ fname = alloc(MAXPATHL);
+ if (fname == NULL)
+ goto theend;
+
+ /*
+ * 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(gettail(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 (mch_stat((char *)fname, &st) >= 0) {
+ /* 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:
+ vim_free(fname);
+ vim_free(wfname);
+}
+
+/*
+ * Display a message for spell file processing when 'verbose' is set or using
+ * ":mkspell". "str" can be IObuff.
+ */
+static void spell_message(spin, str)
+spellinfo_T *spin;
+char_u *str;
+{
+ if (spin->si_verbose || p_verbose > 2) {
+ if (!spin->si_verbose)
+ verbose_enter();
+ MSG(str);
+ out_flush();
+ if (!spin->si_verbose)
+ verbose_leave();
+ }
+}
+
+/*
+ * ":[count]spellgood {word}"
+ * ":[count]spellwrong {word}"
+ * ":[count]spellundo {word}"
+ */
+void ex_spell(eap)
+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(word, len, bad, idx, undo)
+char_u *word;
+int len;
+int bad;
+int idx; /* "zG" and "zW": zero, otherwise index in
+ 'spellfile' */
+int undo; /* TRUE for "zug", "zuG", "zuw" and "zuW" */
+{
+ FILE *fd = NULL;
+ buf_T *buf = NULL;
+ int 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('s');
+ 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 = alloc(MAXPATHL);
+ if (fnamebuf == NULL)
+ return;
+
+ 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 %ld entries"), idx);
+ vim_free(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));
+ vim_free(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((char_u *)_("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 = gettail_sep(fname)) != fname) {
+ int c = *p;
+
+ /* The directory doesn't exist. Try creating it and opening
+ * the file again. */
+ *p = NUL;
+ vim_mkdir(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((char_u *)_("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);
+ }
+ vim_free(fnamebuf);
+}
+
+/*
+ * Initialize 'spellfile' for the current buffer.
+ */
+static void init_spellfile() {
+ char_u *buf;
+ int l;
+ char_u *fname;
+ char_u *rtp;
+ char_u *lend;
+ int aspath = FALSE;
+ char_u *lstart = curbuf->b_s.b_p_spl;
+
+ if (*curwin->w_s->b_p_spl != NUL && curwin->w_s->b_langp.ga_len > 0) {
+ buf = alloc(MAXPATHL);
+ if (buf == NULL)
+ return;
+
+ /* 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". */
+ vim_strncpy(buf, curbuf->b_s.b_p_spl,
+ lstart - curbuf->b_s.b_p_spl - 1);
+ else
+ /* Copy the path from 'runtimepath' to buf[]. */
+ copy_option_part(&rtp, buf, MAXPATHL, ",");
+ if (filewritable(buf) == 2) {
+ /* Use the first language name from 'spelllang' and the
+ * encoding used in the first loaded .spl file. */
+ if (aspath)
+ vim_strncpy(buf, curbuf->b_s.b_p_spl,
+ lend - curbuf->b_s.b_p_spl);
+ else {
+ /* Create the "spell" directory if it doesn't exist yet. */
+ l = (int)STRLEN(buf);
+ vim_snprintf((char *)buf + l, MAXPATHL - l, "/spell");
+ if (filewritable(buf) != 2)
+ vim_mkdir(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 *)gettail(fname), ".ascii.") != NULL
+ ? (char_u *)"ascii" : spell_enc());
+ set_option_value((char_u *)"spellfile", 0L, buf, OPT_LOCAL);
+ break;
+ }
+ aspath = FALSE;
+ }
+
+ vim_free(buf);
+ }
+}
+
+/*
+ * Init the chartab used for spelling for ASCII.
+ * EBCDIC is not supported!
+ */
+static void clear_spell_chartab(sp)
+spelltab_T *sp;
+{
+ int i;
+
+ /* Init everything to FALSE. */
+ vim_memset(sp->st_isw, FALSE, sizeof(sp->st_isw));
+ vim_memset(sp->st_isu, FALSE, sizeof(sp->st_isu));
+ for (i = 0; i < 256; ++i) {
+ sp->st_fold[i] = i;
+ sp->st_upper[i] = i;
+ }
+
+ /* We include digits. A word shouldn't start with a digit, but handling
+ * that is done separately. */
+ for (i = '0'; i <= '9'; ++i)
+ sp->st_isw[i] = TRUE;
+ for (i = 'A'; i <= 'Z'; ++i) {
+ sp->st_isw[i] = TRUE;
+ sp->st_isu[i] = TRUE;
+ sp->st_fold[i] = i + 0x20;
+ }
+ for (i = 'a'; i <= 'z'; ++i) {
+ sp->st_isw[i] = TRUE;
+ sp->st_upper[i] = i - 0x20;
+ }
+}
+
+/*
+ * Init the chartab used for spelling. Only depends on 'encoding'.
+ * Called once while starting up and when 'encoding' changes.
+ * 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.
+ */
+void init_spell_chartab() {
+ int i;
+
+ 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 (MB_ISUPPER(i)) {
+ spelltab.st_isw[i] = TRUE;
+ spelltab.st_isu[i] = TRUE;
+ spelltab.st_fold[i] = MB_TOLOWER(i);
+ } else if (MB_ISLOWER(i)) {
+ spelltab.st_isw[i] = TRUE;
+ spelltab.st_upper[i] = MB_TOUPPER(i);
+ }
+ }
+ }
+}
+
+/*
+ * Set the spell character tables from strings in the affix file.
+ */
+static int set_spell_chartab(fol, low, upp)
+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(flags, cnt, fol)
+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(new_st)
+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;
+}
+
+/*
+ * Return TRUE if "p" points to a word character.
+ * As a special case we see "midword" characters as word character when it is
+ * followed by a word character. This finds they'there but not 'they there'.
+ * Thus this only works properly when past the first character of the word.
+ */
+static int spell_iswordp(p, wp)
+char_u *p;
+win_T *wp; /* buffer used */
+{
+ char_u *s;
+ int l;
+ int c;
+
+ if (has_mbyte) {
+ l = MB_BYTE2LEN(*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);
+ 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))
+ s = p + l;
+ }
+
+ c = mb_ptr2char(s);
+ if (c > 255)
+ return spell_mb_isword_class(mb_get_class(s), wp);
+ return spelltab.st_isw[c];
+ }
+
+ return spelltab.st_isw[wp->w_s->b_spell_ismw[*p] ? p[1] : p[0]];
+}
+
+/*
+ * Return TRUE if "p" points to a word character.
+ * Unlike spell_iswordp() this doesn't check for "midword" characters.
+ */
+static int spell_iswordp_nmw(p, wp)
+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];
+ }
+ return spelltab.st_isw[*p];
+}
+
+/*
+ * Return 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.
+ */
+static int spell_mb_isword_class(cl, wp)
+int cl;
+win_T *wp;
+{
+ if (wp->w_s->b_cjk)
+ /* East Asian characters are not considered word characters. */
+ return cl == 2 || cl == 0x2800;
+ return cl >= 2 && cl != 0x2070 && cl != 0x2080;
+}
+
+/*
+ * Return TRUE if "p" points to a word character.
+ * Wide version of spell_iswordp().
+ */
+static int spell_iswordp_w(p, wp)
+int *p;
+win_T *wp;
+{
+ int *s;
+
+ if (*p < 256 ? wp->w_s->b_spell_ismw[*p]
+ : (wp->w_s->b_spell_ismw_mb != NULL
+ && vim_strchr(wp->w_s->b_spell_ismw_mb, *p) != NULL))
+ s = p + 1;
+ else
+ 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 0;
+ }
+ 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(fd, gap)
+FILE *fd;
+garray_T *gap;
+{
+ int i;
+ char_u *p;
+ int len;
+ int totlen;
+ size_t x = 1; /* collect return value of fwrite() */
+
+ if (fd != NULL)
+ put_bytes(fd, (long_u)gap->ga_len, 2); /* <prefcondcnt> */
+
+ totlen = 2 + gap->ga_len; /* length of <prefcondcnt> and <condlen> bytes */
+
+ for (i = 0; i < gap->ga_len; ++i) {
+ /* <prefcond> : <condlen> <condstr> */
+ p = ((char_u **)gap->ga_data)[i];
+ if (p != NULL) {
+ len = (int)STRLEN(p);
+ if (fd != NULL) {
+ fputc(len, fd);
+ x &= fwrite(p, (size_t)len, (size_t)1, fd);
+ }
+ totlen += len;
+ } else if (fd != NULL)
+ fputc(0, fd);
+ }
+
+ return 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(str, len, buf, buflen)
+char_u *str;
+int len;
+char_u *buf;
+int buflen;
+{
+ int i;
+
+ if (len >= buflen) {
+ buf[0] = NUL;
+ return FAIL; /* result will not fit */
+ }
+
+ if (has_mbyte) {
+ int outi = 0;
+ char_u *p;
+ int c;
+
+ /* Fold one character at a time. */
+ for (p = str; p < str + len; ) {
+ if (outi + MB_MAXBYTES > buflen) {
+ buf[outi] = NUL;
+ return FAIL;
+ }
+ c = mb_cptr2char_adv(&p);
+ outi += mb_char2bytes(SPELL_TOFOLD(c), buf + outi);
+ }
+ buf[outi] = NUL;
+ } else {
+ /* Be quick for non-multibyte encodings. */
+ for (i = 0; i < len; ++i)
+ buf[i] = spelltab.st_fold[str[i]];
+ buf[i] = NUL;
+ }
+
+ return OK;
+}
+
+/* values for sps_flags */
+#define SPS_BEST 1
+#define SPS_FAST 2
+#define SPS_DOUBLE 4
+
+static int sps_flags = SPS_BEST; /* flags from 'spellsuggest' */
+static int sps_limit = 9999; /* max nr of suggestions given */
+
+/*
+ * Check the 'spellsuggest' option. Return FAIL if it's wrong.
+ * Sets "sps_flags" and "sps_limit".
+ */
+int spell_check_sps() {
+ char_u *p;
+ char_u *s;
+ char_u buf[MAXPATHL];
+ int f;
+
+ sps_flags = 0;
+ sps_limit = 9999;
+
+ for (p = p_sps; *p != NUL; ) {
+ copy_option_part(&p, buf, MAXPATHL, ",");
+
+ f = 0;
+ if (VIM_ISDIGIT(*buf)) {
+ s = buf;
+ sps_limit = getdigits(&s);
+ if (*s != NUL && !VIM_ISDIGIT(*s))
+ f = -1;
+ } else if (STRCMP(buf, "best") == 0)
+ f = SPS_BEST;
+ else if (STRCMP(buf, "fast") == 0)
+ f = SPS_FAST;
+ else if (STRCMP(buf, "double") == 0)
+ f = SPS_DOUBLE;
+ else if (STRNCMP(buf, "expr:", 5) != 0
+ && STRNCMP(buf, "file:", 5) != 0)
+ f = -1;
+
+ if (f == -1 || (sps_flags != 0 && f != 0)) {
+ sps_flags = SPS_BEST;
+ sps_limit = 9999;
+ return FAIL;
+ }
+ if (f != 0)
+ sps_flags = f;
+ }
+
+ if (sps_flags == 0)
+ sps_flags = SPS_BEST;
+
+ return OK;
+}
+
+/*
+ * "z=": Find badly spelled word under or after the cursor.
+ * Give suggestions for the properly spelled word.
+ * In Visual mode use the highlighted word as the bad word.
+ * When "count" is non-zero use that suggestion.
+ */
+void spell_suggest(count)
+int count;
+{
+ char_u *line;
+ pos_T prev_cursor = curwin->w_cursor;
+ char_u wcopy[MAXWLEN + 2];
+ char_u *p;
+ int i;
+ int c;
+ suginfo_T sug;
+ suggest_T *stp;
+ int mouse_used;
+ int need_cap;
+ int limit;
+ int selected = count;
+ int badlen = 0;
+ int msg_scroll_save = msg_scroll;
+
+ if (no_spell_checking(curwin))
+ return;
+
+ if (VIsual_active) {
+ /* Use the Visually selected text as the bad word. But reject
+ * a multi-line selection. */
+ if (curwin->w_cursor.lnum != VIsual.lnum) {
+ vim_beep();
+ return;
+ }
+ badlen = (int)curwin->w_cursor.col - (int)VIsual.col;
+ if (badlen < 0)
+ badlen = -badlen;
+ else
+ curwin->w_cursor.col = VIsual.col;
+ ++badlen;
+ end_visual_mode();
+ } else
+ /* Find the start of the badly spelled word. */
+ if (spell_move_to(curwin, FORWARD, TRUE, TRUE, NULL) == 0
+ || curwin->w_cursor.col > prev_cursor.col) {
+ /* No bad word or it starts after the cursor: use the word under the
+ * cursor. */
+ curwin->w_cursor = prev_cursor;
+ line = ml_get_curline();
+ 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);
+ /* Forward to start of word. */
+ while (*p != NUL && !spell_iswordp_nmw(p, curwin))
+ mb_ptr_adv(p);
+
+ if (!spell_iswordp_nmw(p, curwin)) { /* No word found. */
+ beep_flush();
+ return;
+ }
+ curwin->w_cursor.col = (colnr_T)(p - line);
+ }
+
+ /* Get the word and its length. */
+
+ /* Figure out if the word should be capitalised. */
+ need_cap = check_need_cap(curwin->w_cursor.lnum, curwin->w_cursor.col);
+
+ /* Make a copy of current line since autocommands may free the line. */
+ line = vim_strsave(ml_get_curline());
+ if (line == NULL)
+ goto skip;
+
+ /* Get the list of suggestions. Limit to 'lines' - 2 or the number in
+ * 'spellsuggest', whatever is smaller. */
+ if (sps_limit > (int)Rows - 2)
+ limit = (int)Rows - 2;
+ else
+ limit = sps_limit;
+ spell_find_suggest(line + curwin->w_cursor.col, badlen, &sug, limit,
+ TRUE, need_cap, TRUE);
+
+ if (sug.su_ga.ga_len == 0)
+ MSG(_("Sorry, no suggestions"));
+ else if (count > 0) {
+ if (count > sug.su_ga.ga_len)
+ smsg((char_u *)_("Sorry, only %ld suggestions"),
+ (long)sug.su_ga.ga_len);
+ } else {
+ vim_free(repl_from);
+ repl_from = NULL;
+ vim_free(repl_to);
+ repl_to = NULL;
+
+ /* When 'rightleft' is set the list is drawn right-left. */
+ cmdmsg_rl = curwin->w_p_rl;
+ if (cmdmsg_rl)
+ msg_col = Columns - 1;
+
+ /* List the suggestions. */
+ msg_start();
+ msg_row = Rows - 1; /* for when 'cmdheight' > 1 */
+ lines_left = Rows; /* avoid more prompt */
+ vim_snprintf((char *)IObuff, IOSIZE, _("Change \"%.*s\" to:"),
+ sug.su_badlen, sug.su_badptr);
+ if (cmdmsg_rl && STRNCMP(IObuff, "Change", 6) == 0) {
+ /* And now the rabbit from the high hat: Avoid showing the
+ * untranslated message rightleft. */
+ vim_snprintf((char *)IObuff, IOSIZE, ":ot \"%.*s\" egnahC",
+ sug.su_badlen, sug.su_badptr);
+ }
+ msg_puts(IObuff);
+ msg_clr_eos();
+ msg_putchar('\n');
+
+ msg_scroll = TRUE;
+ for (i = 0; i < sug.su_ga.ga_len; ++i) {
+ stp = &SUG(sug.su_ga, i);
+
+ /* The suggested word may replace only part of the bad word, add
+ * the not replaced part. */
+ vim_strncpy(wcopy, stp->st_word, MAXWLEN);
+ if (sug.su_badlen > stp->st_orglen)
+ vim_strncpy(wcopy + stp->st_wordlen,
+ sug.su_badptr + stp->st_orglen,
+ sug.su_badlen - stp->st_orglen);
+ vim_snprintf((char *)IObuff, IOSIZE, "%2d", i + 1);
+ if (cmdmsg_rl)
+ rl_mirror(IObuff);
+ msg_puts(IObuff);
+
+ vim_snprintf((char *)IObuff, IOSIZE, " \"%s\"", wcopy);
+ msg_puts(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);
+ }
+
+ if (p_verbose > 0) {
+ /* Add the score. */
+ if (sps_flags & (SPS_DOUBLE | SPS_BEST))
+ vim_snprintf((char *)IObuff, IOSIZE, " (%s%d - %d)",
+ stp->st_salscore ? "s " : "",
+ stp->st_score, stp->st_altscore);
+ else
+ vim_snprintf((char *)IObuff, IOSIZE, " (%d)",
+ stp->st_score);
+ if (cmdmsg_rl)
+ /* Mirror the numbers, but keep the leading space. */
+ rl_mirror(IObuff + 1);
+ msg_advance(30);
+ msg_puts(IObuff);
+ }
+ msg_putchar('\n');
+ }
+
+ cmdmsg_rl = FALSE;
+ msg_col = 0;
+ /* Ask for choice. */
+ selected = prompt_for_number(&mouse_used);
+ if (mouse_used)
+ selected -= lines_left;
+ lines_left = Rows; /* avoid more prompt */
+ /* don't delay for 'smd' in normal_cmd() */
+ msg_scroll = msg_scroll_save;
+ }
+
+ if (selected > 0 && selected <= sug.su_ga.ga_len && u_save_cursor() == OK) {
+ /* Save the from and to text for :spellrepall. */
+ stp = &SUG(sug.su_ga, selected - 1);
+ if (sug.su_badlen > stp->st_orglen) {
+ /* Replacing less than "su_badlen", append the remainder to
+ * repl_to. */
+ repl_from = vim_strnsave(sug.su_badptr, sug.su_badlen);
+ vim_snprintf((char *)IObuff, IOSIZE, "%s%.*s", stp->st_word,
+ sug.su_badlen - stp->st_orglen,
+ sug.su_badptr + stp->st_orglen);
+ repl_to = vim_strsave(IObuff);
+ } else {
+ /* Replacing su_badlen or more, use the whole word. */
+ repl_from = vim_strnsave(sug.su_badptr, stp->st_orglen);
+ repl_to = vim_strsave(stp->st_word);
+ }
+
+ /* Replace the word. */
+ p = alloc((unsigned)STRLEN(line) - stp->st_orglen
+ + stp->st_wordlen + 1);
+ if (p != NULL) {
+ c = (int)(sug.su_badptr - line);
+ mch_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);
+ curwin->w_cursor.col = c;
+
+ /* For redo we use a change-word command. */
+ ResetRedobuff();
+ AppendToRedobuff((char_u *)"ciw");
+ AppendToRedobuffLit(p + c,
+ stp->st_wordlen + sug.su_badlen - stp->st_orglen);
+ AppendCharToRedobuff(ESC);
+
+ /* After this "p" may be invalid. */
+ changed_bytes(curwin->w_cursor.lnum, c);
+ }
+ } else
+ curwin->w_cursor = prev_cursor;
+
+ spell_find_cleanup(&sug);
+skip:
+ vim_free(line);
+}
+
+/*
+ * Check if the word at line "lnum" column "col" is required to start with a
+ * capital. This uses 'spellcapcheck' of the current buffer.
+ */
+static int check_need_cap(lnum, col)
+linenr_T lnum;
+colnr_T col;
+{
+ int need_cap = FALSE;
+ char_u *line;
+ char_u *line_copy = NULL;
+ char_u *p;
+ colnr_T endcol;
+ regmatch_T regmatch;
+
+ if (curwin->w_s->b_cap_prog == NULL)
+ return FALSE;
+
+ line = ml_get_curline();
+ endcol = 0;
+ if ((int)(skipwhite(line) - line) >= (int)col) {
+ /* At start of line, check if previous line is empty or sentence
+ * ends there. */
+ if (lnum == 1)
+ need_cap = TRUE;
+ else {
+ line = ml_get(lnum - 1);
+ if (*skipwhite(line) == NUL)
+ need_cap = TRUE;
+ else {
+ /* Append a space in place of the line break. */
+ line_copy = concat_str(line, (char_u *)" ");
+ line = line_copy;
+ endcol = (colnr_T)STRLEN(line);
+ }
+ }
+ } else
+ endcol = col;
+
+ if (endcol > 0) {
+ /* Check if sentence ends before the bad word. */
+ regmatch.regprog = curwin->w_s->b_cap_prog;
+ regmatch.rm_ic = FALSE;
+ p = line + endcol;
+ for (;; ) {
+ 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;
+ break;
+ }
+ }
+ }
+
+ vim_free(line_copy);
+
+ return need_cap;
+}
+
+
+/*
+ * ":spellrepall"
+ */
+void ex_spellrepall(eap)
+exarg_T *eap UNUSED;
+{
+ pos_T pos = curwin->w_cursor;
+ char_u *frompat;
+ int addlen;
+ char_u *line;
+ char_u *p;
+ int save_ws = p_ws;
+ linenr_T prev_lnum = 0;
+
+ if (repl_from == NULL || repl_to == NULL) {
+ EMSG(_("E752: No previous spell replacement"));
+ return;
+ }
+ addlen = (int)(STRLEN(repl_to) - STRLEN(repl_from));
+
+ frompat = alloc((unsigned)STRLEN(repl_from) + 7);
+ if (frompat == NULL)
+ return;
+ sprintf((char *)frompat, "\\V\\<%s\\>", repl_from);
+ p_ws = FALSE;
+
+ sub_nsubs = 0;
+ sub_nlines = 0;
+ curwin->w_cursor.lnum = 0;
+ while (!got_int) {
+ if (do_search(NULL, '/', frompat, 1L, SEARCH_KEEP, NULL) == 0
+ || u_save_cursor() == FAIL)
+ break;
+
+ /* Only replace when the right word isn't there yet. This happens
+ * when changing "etc" to "etc.". */
+ line = ml_get_curline();
+ if (addlen <= 0 || STRNCMP(line + curwin->w_cursor.col,
+ repl_to, STRLEN(repl_to)) != 0) {
+ p = alloc((unsigned)STRLEN(line) + addlen + 1);
+ if (p == NULL)
+ break;
+ mch_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);
+ changed_bytes(curwin->w_cursor.lnum, curwin->w_cursor.col);
+
+ if (curwin->w_cursor.lnum != prev_lnum) {
+ ++sub_nlines;
+ prev_lnum = curwin->w_cursor.lnum;
+ }
+ ++sub_nsubs;
+ }
+ curwin->w_cursor.col += (colnr_T)STRLEN(repl_to);
+ }
+
+ p_ws = save_ws;
+ curwin->w_cursor = pos;
+ vim_free(frompat);
+
+ if (sub_nsubs == 0)
+ EMSG2(_("E753: Not found: %s"), repl_from);
+ else
+ do_sub_msg(FALSE);
+}
+
+/*
+ * Find spell suggestions for "word". Return them in the growarray "*gap" as
+ * a list of allocated strings.
+ */
+void spell_suggest_list(gap, word, maxcount, need_cap, interactive)
+garray_T *gap;
+char_u *word;
+int maxcount; /* maximum nr of suggestions */
+int need_cap; /* 'spellcapcheck' matched */
+int interactive;
+{
+ suginfo_T sug;
+ int i;
+ suggest_T *stp;
+ char_u *wcopy;
+
+ spell_find_suggest(word, 0, &sug, maxcount, FALSE, need_cap, interactive);
+
+ /* Make room in "gap". */
+ ga_init2(gap, sizeof(char_u *), sug.su_ga.ga_len + 1);
+ if (ga_grow(gap, sug.su_ga.ga_len) == OK) {
+ for (i = 0; i < sug.su_ga.ga_len; ++i) {
+ stp = &SUG(sug.su_ga, i);
+
+ /* The suggested word may replace only part of "word", add the not
+ * replaced part. */
+ wcopy = alloc(stp->st_wordlen
+ + (unsigned)STRLEN(sug.su_badptr + stp->st_orglen) + 1);
+ if (wcopy == NULL)
+ break;
+ STRCPY(wcopy, stp->st_word);
+ STRCPY(wcopy + stp->st_wordlen, sug.su_badptr + stp->st_orglen);
+ ((char_u **)gap->ga_data)[gap->ga_len++] = wcopy;
+ }
+ }
+
+ spell_find_cleanup(&sug);
+}
+
+/*
+ * Find spell suggestions for the word at the start of "badptr".
+ * Return the suggestions in "su->su_ga".
+ * The maximum number of suggestions is "maxcount".
+ * Note: does use info for the current window.
+ * This is based on the mechanisms of Aspell, but completely reimplemented.
+ */
+static void spell_find_suggest(badptr, badlen, su, maxcount, banbadword,
+ need_cap,
+ interactive)
+char_u *badptr;
+int badlen; /* length of bad word or 0 if unknown */
+suginfo_T *su;
+int maxcount;
+int banbadword; /* don't include badword in suggestions */
+int need_cap; /* word should start with capital */
+int interactive;
+{
+ hlf_T attr = HLF_COUNT;
+ char_u buf[MAXPATHL];
+ char_u *p;
+ int do_combine = FALSE;
+ char_u *sps_copy;
+ static int expr_busy = FALSE;
+ int c;
+ int i;
+ langp_T *lp;
+
+ /*
+ * Set the info in "*su".
+ */
+ vim_memset(su, 0, sizeof(suginfo_T));
+ ga_init2(&su->su_ga, (int)sizeof(suggest_T), 10);
+ ga_init2(&su->su_sga, (int)sizeof(suggest_T), 10);
+ if (*badptr == NUL)
+ return;
+ hash_init(&su->su_banned);
+
+ su->su_badptr = badptr;
+ if (badlen != 0)
+ su->su_badlen = badlen;
+ else
+ su->su_badlen = spell_check(curwin, su->su_badptr, &attr, NULL, FALSE);
+ su->su_maxcount = maxcount;
+ su->su_maxscore = SCORE_MAXINIT;
+
+ if (su->su_badlen >= MAXWLEN)
+ su->su_badlen = MAXWLEN - 1; /* just in case */
+ vim_strncpy(su->su_badword, su->su_badptr, su->su_badlen);
+ (void)spell_casefold(su->su_badptr, su->su_badlen,
+ su->su_fbadword, MAXWLEN);
+ /* get caps flags for bad word */
+ su->su_badflags = badword_captype(su->su_badptr,
+ su->su_badptr + su->su_badlen);
+ if (need_cap)
+ su->su_badflags |= WF_ONECAP;
+
+ /* Find the default language for sound folding. We simply use the first
+ * one in 'spelllang' that supports sound folding. That's good for when
+ * using multiple files for one language, it's not that bad when mixing
+ * languages (e.g., "pl,en"). */
+ for (i = 0; i < curbuf->b_s.b_langp.ga_len; ++i) {
+ lp = LANGP_ENTRY(curbuf->b_s.b_langp, i);
+ if (lp->lp_sallang != NULL) {
+ su->su_sallang = lp->lp_sallang;
+ break;
+ }
+ }
+
+ /* Soundfold the bad word with the default sound folding, so that we don't
+ * have to do this many times. */
+ if (su->su_sallang != NULL)
+ spell_soundfold(su->su_sallang, su->su_fbadword, TRUE,
+ su->su_sal_badword);
+
+ /* If the word is not capitalised and spell_check() doesn't consider the
+ * word to be bad then it might need to be capitalised. Add a suggestion
+ * for that. */
+ c = PTR2CHAR(su->su_badptr);
+ if (!SPELL_ISUPPER(c) && attr == HLF_COUNT) {
+ make_case_word(su->su_badword, buf, WF_ONECAP);
+ add_suggestion(su, &su->su_ga, buf, su->su_badlen, SCORE_ICASE,
+ 0, TRUE, su->su_sallang, FALSE);
+ }
+
+ /* Ban the bad word itself. It may appear in another region. */
+ if (banbadword)
+ add_banned(su, su->su_badword);
+
+ /* Make a copy of 'spellsuggest', because the expression may change it. */
+ sps_copy = vim_strsave(p_sps);
+ if (sps_copy == NULL)
+ return;
+
+ /* Loop over the items in 'spellsuggest'. */
+ for (p = sps_copy; *p != NUL; ) {
+ copy_option_part(&p, buf, MAXPATHL, ",");
+
+ if (STRNCMP(buf, "expr:", 5) == 0) {
+ /* Evaluate an expression. Skip this when called recursively,
+ * when using spellsuggest() in the expression. */
+ if (!expr_busy) {
+ expr_busy = TRUE;
+ spell_suggest_expr(su, buf + 5);
+ expr_busy = FALSE;
+ }
+ } else if (STRNCMP(buf, "file:", 5) == 0)
+ /* Use list of suggestions in a file. */
+ spell_suggest_file(su, buf + 5);
+ else {
+ /* Use internal method. */
+ spell_suggest_intern(su, interactive);
+ if (sps_flags & SPS_DOUBLE)
+ do_combine = TRUE;
+ }
+ }
+
+ vim_free(sps_copy);
+
+ if (do_combine)
+ /* Combine the two list of suggestions. This must be done last,
+ * because sorting changes the order again. */
+ score_combine(su);
+}
+
+/*
+ * Find suggestions by evaluating expression "expr".
+ */
+static void spell_suggest_expr(su, expr)
+suginfo_T *su;
+char_u *expr;
+{
+ list_T *list;
+ listitem_T *li;
+ int score;
+ char_u *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);
+ 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) {
+ /* 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);
+ }
+ list_unref(list);
+ }
+
+ /* Remove bogus suggestions, sort and truncate at "maxcount". */
+ check_suggestions(su, &su->su_ga);
+ (void)cleanup_suggestions(&su->su_ga, su->su_maxscore, su->su_maxcount);
+}
+
+/*
+ * Find suggestions in file "fname". Used for "file:" in 'spellsuggest'.
+ */
+static void spell_suggest_file(su, fname)
+suginfo_T *su;
+char_u *fname;
+{
+ FILE *fd;
+ char_u line[MAXWLEN * 2];
+ char_u *p;
+ int len;
+ char_u cword[MAXWLEN];
+
+ /* Open the file. */
+ fd = mch_fopen((char *)fname, "r");
+ if (fd == NULL) {
+ EMSG2(_(e_notopen), fname);
+ return;
+ }
+
+ /* Read it line by line. */
+ while (!vim_fgets(line, MAXWLEN * 2, fd) && !got_int) {
+ line_breakcheck();
+
+ p = vim_strchr(line, '/');
+ if (p == NULL)
+ continue; /* No Tab found, just skip the line. */
+ *p++ = NUL;
+ if (STRICMP(su->su_badword, line) == 0) {
+ /* Match! Isolate the good word, until CR or NL. */
+ for (len = 0; p[len] >= ' '; ++len)
+ ;
+ p[len] = NUL;
+
+ /* If the suggestion doesn't have specific case duplicate the case
+ * of the bad word. */
+ if (captype(p, NULL) == 0) {
+ make_case_word(p, cword, su->su_badflags);
+ p = cword;
+ }
+
+ add_suggestion(su, &su->su_ga, p, su->su_badlen,
+ SCORE_FILE, 0, TRUE, su->su_sallang, FALSE);
+ }
+ }
+
+ fclose(fd);
+
+ /* Remove bogus suggestions, sort and truncate at "maxcount". */
+ check_suggestions(su, &su->su_ga);
+ (void)cleanup_suggestions(&su->su_ga, su->su_maxscore, su->su_maxcount);
+}
+
+/*
+ * Find suggestions for the internal method indicated by "sps_flags".
+ */
+static void spell_suggest_intern(su, interactive)
+suginfo_T *su;
+int interactive;
+{
+ /*
+ * Load the .sug file(s) that are available and not done yet.
+ */
+ suggest_load_files();
+
+ /*
+ * 1. Try special cases, such as repeating a word: "the the" -> "the".
+ *
+ * Set a maximum score to limit the combination of operations that is
+ * tried.
+ */
+ suggest_try_special(su);
+
+ /*
+ * 2. Try inserting/deleting/swapping/changing a letter, use REP entries
+ * from the .aff file and inserting a space (split the word).
+ */
+ suggest_try_change(su);
+
+ /* For the resulting top-scorers compute the sound-a-like score. */
+ if (sps_flags & SPS_DOUBLE)
+ score_comp_sal(su);
+
+ /*
+ * 3. Try finding sound-a-like words.
+ */
+ if ((sps_flags & SPS_FAST) == 0) {
+ if (sps_flags & SPS_BEST)
+ /* Adjust the word score for the suggestions found so far for how
+ * they sounds like. */
+ rescore_suggestions(su);
+
+ /*
+ * While going through the soundfold tree "su_maxscore" is the score
+ * for the soundfold word, limits the changes that are being tried,
+ * and "su_sfmaxscore" the rescored score, which is set by
+ * cleanup_suggestions().
+ * First find words with a small edit distance, because this is much
+ * faster and often already finds the top-N suggestions. If we didn't
+ * find many suggestions try again with a higher edit distance.
+ * "sl_sounddone" is used to avoid doing the same word twice.
+ */
+ suggest_try_soundalike_prep();
+ su->su_maxscore = SCORE_SFMAX1;
+ su->su_sfmaxscore = SCORE_MAXINIT * 3;
+ suggest_try_soundalike(su);
+ if (su->su_ga.ga_len < SUG_CLEAN_COUNT(su)) {
+ /* We didn't find enough matches, try again, allowing more
+ * changes to the soundfold word. */
+ su->su_maxscore = SCORE_SFMAX2;
+ suggest_try_soundalike(su);
+ if (su->su_ga.ga_len < SUG_CLEAN_COUNT(su)) {
+ /* Still didn't find enough matches, try again, allowing even
+ * more changes to the soundfold word. */
+ su->su_maxscore = SCORE_SFMAX3;
+ suggest_try_soundalike(su);
+ }
+ }
+ su->su_maxscore = su->su_sfmaxscore;
+ suggest_try_soundalike_finish();
+ }
+
+ /* When CTRL-C was hit while searching do show the results. Only clear
+ * got_int when using a command, not for spellsuggest(). */
+ ui_breakcheck();
+ if (interactive && got_int) {
+ (void)vgetc();
+ got_int = FALSE;
+ }
+
+ if ((sps_flags & SPS_DOUBLE) == 0 && su->su_ga.ga_len != 0) {
+ if (sps_flags & SPS_BEST)
+ /* Adjust the word score for how it sounds like. */
+ rescore_suggestions(su);
+
+ /* Remove bogus suggestions, sort and truncate at "maxcount". */
+ check_suggestions(su, &su->su_ga);
+ (void)cleanup_suggestions(&su->su_ga, su->su_maxscore, su->su_maxcount);
+ }
+}
+
+/*
+ * Load the .sug files for languages that have one and weren't loaded yet.
+ */
+static void suggest_load_files() {
+ langp_T *lp;
+ int lpi;
+ 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 (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();
+ if (slang->sl_sugbuf == NULL)
+ goto someerror;
+ /* <sugwcount> */
+ wcount = get4c(fd);
+ if (wcount < 0)
+ goto someerror;
+
+ /* Read all the wordnr lists into the buffer, one NUL terminated
+ * list per line. */
+ ga_init2(&ga, 1, 100);
+ for (wordnr = 0; wordnr < wcount; ++wordnr) {
+ ga.ga_len = 0;
+ for (;; ) {
+ c = getc(fd); /* <sugline> */
+ if (c < 0 || ga_grow(&ga, 1) == FAIL)
+ goto someerror;
+ ((char_u *)ga.ga_data)[ga.ga_len++] = 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(byts, idxs)
+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(su)
+suginfo_T *su;
+{
+ int i;
+
+ /* Free the suggestions. */
+ for (i = 0; i < su->su_ga.ga_len; ++i)
+ vim_free(SUG(su->su_ga, i).st_word);
+ ga_clear(&su->su_ga);
+ for (i = 0; i < su->su_sga.ga_len; ++i)
+ vim_free(SUG(su->su_sga, i).st_word);
+ ga_clear(&su->su_sga);
+
+ /* Free the banned words. */
+ 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(word, wcopy, upper)
+char_u *word;
+char_u *wcopy;
+int upper; /* TRUE: first letter made upper case */
+{
+ char_u *p;
+ int c;
+ int l;
+
+ p = word;
+ if (has_mbyte)
+ c = mb_cptr2char_adv(&p);
+ else
+ c = *p++;
+ if (upper)
+ c = SPELL_TOUPPER(c);
+ else
+ c = SPELL_TOFOLD(c);
+ if (has_mbyte)
+ l = mb_char2bytes(c, wcopy);
+ else {
+ l = 1;
+ wcopy[0] = c;
+ }
+ vim_strncpy(wcopy + l, p, MAXWLEN - l - 1);
+}
+
+/*
+ * Make a copy of "word" with all the letters upper cased into
+ * "wcopy[MAXWLEN]". The result is NUL terminated.
+ */
+static void allcap_copy(word, wcopy)
+char_u *word;
+char_u *wcopy;
+{
+ char_u *s;
+ char_u *d;
+ int c;
+
+ d = wcopy;
+ for (s = word; *s != NUL; ) {
+ if (has_mbyte)
+ c = mb_cptr2char_adv(&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) {
+ c = 'S';
+ if (d - wcopy >= MAXWLEN - 1)
+ break;
+ *d++ = c;
+ } 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;
+ }
+ }
+ *d = NUL;
+}
+
+/*
+ * Try finding suggestions by recognizing specific situations.
+ */
+static void suggest_try_special(su)
+suginfo_T *su;
+{
+ char_u *p;
+ size_t len;
+ int c;
+ char_u word[MAXWLEN];
+
+ /*
+ * Recognize a word that is repeated: "the the".
+ */
+ p = skiptowhite(su->su_fbadword);
+ len = p - su->su_fbadword;
+ p = skipwhite(p);
+ if (STRLEN(p) == len && STRNCMP(su->su_fbadword, p, len) == 0) {
+ /* Include badflags: if the badword is onecap or allcap
+ * use that for the goodword too: "The the" -> "The". */
+ c = su->su_fbadword[len];
+ su->su_fbadword[len] = NUL;
+ make_case_word(su->su_fbadword, word, su->su_badflags);
+ su->su_fbadword[len] = c;
+
+ /* Give a soundalike score of 0, compute the score as if deleting one
+ * character. */
+ add_suggestion(su, &su->su_ga, word, su->su_badlen,
+ RESCORE(SCORE_REP, 0), 0, TRUE, su->su_sallang, FALSE);
+ }
+}
+
+/*
+ * Try finding suggestions by adding/removing/swapping letters.
+ */
+static void suggest_try_change(su)
+suginfo_T *su;
+{
+ char_u fword[MAXWLEN]; /* copy of the bad word, case-folded */
+ int n;
+ char_u *p;
+ int lpi;
+ langp_T *lp;
+
+ /* We make a copy of the case-folded bad word, so that we can modify it
+ * to find matches (esp. REP items). Append some more text, changing
+ * chars after the bad word may help. */
+ STRCPY(fword, su->su_fbadword);
+ n = (int)STRLEN(fword);
+ p = su->su_badptr + su->su_badlen;
+ (void)spell_casefold(p, (int)STRLEN(p), fword + n, MAXWLEN - n);
+
+ for (lpi = 0; lpi < curwin->w_s->b_langp.ga_len; ++lpi) {
+ lp = LANGP_ENTRY(curwin->w_s->b_langp, lpi);
+
+ /* If reloading a spell file fails it's still in the list but
+ * everything has been cleared. */
+ if (lp->lp_slang->sl_fbyts == NULL)
+ continue;
+
+ /* Try it for this language. Will add possible suggestions. */
+ suggest_trie_walk(su, lp, fword, FALSE);
+ }
+}
+
+/* Check the maximum score, if we go over it we won't try this change. */
+#define TRY_DEEPER(su, stack, depth, add) \
+ (stack[depth].ts_score + (add) < su->su_maxscore)
+
+/*
+ * Try finding suggestions by adding/removing/swapping letters.
+ *
+ * This uses a state machine. At each node in the tree we try various
+ * operations. When trying if an operation works "depth" is increased and the
+ * stack[] is used to store info. This allows combinations, thus insert one
+ * character, replace one and delete another. The number of changes is
+ * limited by su->su_maxscore.
+ *
+ * After implementing this I noticed an article by Kemal Oflazer that
+ * describes something similar: "Error-tolerant Finite State Recognition with
+ * Applications to Morphological Analysis and Spelling Correction" (1996).
+ * The implementation in the article is simplified and requires a stack of
+ * unknown depth. The implementation here only needs a stack depth equal to
+ * the length of the word.
+ *
+ * This is also used for the sound-folded word, "soundfold" is TRUE then.
+ * The mechanism is the same, but we find a match with a sound-folded word
+ * that comes from one or more original words. Each of these words may be
+ * added, this is done by add_sound_suggest().
+ * Don't use:
+ * the prefix tree or the keep-case tree
+ * "su->su_badlen"
+ * anything to do with upper and lower case
+ * anything to do with word or non-word characters ("spell_iswordp()")
+ * banned words
+ * word flags (rare, region, compounding)
+ * word splitting for now
+ * "similar_chars()"
+ * use "slang->sl_repsal" instead of "lp->lp_replang->sl_rep"
+ */
+static void suggest_trie_walk(su, lp, fword, soundfold)
+suginfo_T *su;
+langp_T *lp;
+char_u *fword;
+int soundfold;
+{
+ char_u tword[MAXWLEN]; /* good word collected so far */
+ trystate_T stack[MAXWLEN];
+ char_u preword[MAXWLEN * 3]; /* word found with proper case;
+ * concatenation of prefix compound
+ * words and split word. NUL terminated
+ * when going deeper but not when coming
+ * back. */
+ char_u compflags[MAXWLEN]; /* compound flags, one for each word */
+ trystate_T *sp;
+ int newscore;
+ int score;
+ char_u *byts, *fbyts, *pbyts;
+ idx_T *idxs, *fidxs, *pidxs;
+ int depth;
+ int c, c2, c3;
+ int n = 0;
+ int flags;
+ garray_T *gap;
+ idx_T arridx;
+ int len;
+ char_u *p;
+ fromto_T *ftp;
+ int fl = 0, tl;
+ int repextra = 0; /* extra bytes in fword[] from REP item */
+ slang_T *slang = lp->lp_slang;
+ int fword_ends;
+ int goodword_ends;
+#ifdef DEBUG_TRIEWALK
+ /* Stores the name of the change made at each level. */
+ char_u changename[MAXWLEN][80];
+#endif
+ int breakcheckcount = 1000;
+ int compound_ok;
+
+ /*
+ * Go through the whole case-fold tree, try changes at each node.
+ * "tword[]" contains the word collected from nodes in the tree.
+ * "fword[]" the word we are trying to match with (initially the bad
+ * word).
+ */
+ depth = 0;
+ sp = &stack[0];
+ vim_memset(sp, 0, sizeof(trystate_T));
+ sp->ts_curi = 1;
+
+ if (soundfold) {
+ /* Going through the soundfold tree. */
+ byts = fbyts = slang->sl_sbyts;
+ idxs = fidxs = slang->sl_sidxs;
+ pbyts = NULL;
+ pidxs = NULL;
+ sp->ts_prefixdepth = PFD_NOPREFIX;
+ sp->ts_state = STATE_START;
+ } else {
+ /*
+ * When there are postponed prefixes we need to use these first. At
+ * the end of the prefix we continue in the case-fold tree.
+ */
+ fbyts = slang->sl_fbyts;
+ fidxs = slang->sl_fidxs;
+ pbyts = slang->sl_pbyts;
+ pidxs = slang->sl_pidxs;
+ if (pbyts != NULL) {
+ byts = pbyts;
+ idxs = pidxs;
+ sp->ts_prefixdepth = PFD_PREFIXTREE;
+ sp->ts_state = STATE_NOPREFIX; /* try without prefix first */
+ } else {
+ byts = fbyts;
+ idxs = fidxs;
+ sp->ts_prefixdepth = PFD_NOPREFIX;
+ sp->ts_state = STATE_START;
+ }
+ }
+
+ /*
+ * Loop to find all suggestions. At each round we either:
+ * - For the current state try one operation, advance "ts_curi",
+ * increase "depth".
+ * - When a state is done go to the next, set "ts_state".
+ * - When all states are tried decrease "depth".
+ */
+ while (depth >= 0 && !got_int) {
+ sp = &stack[depth];
+ switch (sp->ts_state) {
+ case STATE_START:
+ case STATE_NOPREFIX:
+ /*
+ * Start of node: Deal with NUL bytes, which means
+ * tword[] may end here.
+ */
+ arridx = sp->ts_arridx; /* current node in the tree */
+ len = byts[arridx]; /* bytes in this node */
+ arridx += sp->ts_curi; /* index of current byte */
+
+ if (sp->ts_prefixdepth == PFD_PREFIXTREE) {
+ /* Skip over the NUL bytes, we use them later. */
+ for (n = 0; n < len && byts[arridx + n] == 0; ++n)
+ ;
+ sp->ts_curi += n;
+
+ /* Always past NUL bytes now. */
+ n = (int)sp->ts_state;
+ sp->ts_state = STATE_ENDNUL;
+ sp->ts_save_badflags = su->su_badflags;
+
+ /* At end of a prefix or at start of prefixtree: check for
+ * following word. */
+ if (byts[arridx] == 0 || n == (int)STATE_NOPREFIX) {
+ /* Set su->su_badflags to the caps type at this position.
+ * Use the caps type until here for the prefix itself. */
+ if (has_mbyte)
+ n = nofold_len(fword, sp->ts_fidx, su->su_badptr);
+ else
+ n = sp->ts_fidx;
+ flags = badword_captype(su->su_badptr, su->su_badptr + n);
+ su->su_badflags = badword_captype(su->su_badptr + n,
+ su->su_badptr + su->su_badlen);
+#ifdef DEBUG_TRIEWALK
+ sprintf(changename[depth], "prefix");
+#endif
+ go_deeper(stack, depth, 0);
+ ++depth;
+ sp = &stack[depth];
+ sp->ts_prefixdepth = depth - 1;
+ byts = fbyts;
+ idxs = fidxs;
+ sp->ts_arridx = 0;
+
+ /* Move the prefix to preword[] with the right case
+ * and make find_keepcap_word() works. */
+ tword[sp->ts_twordlen] = NUL;
+ make_case_word(tword + sp->ts_splitoff,
+ preword + sp->ts_prewordlen, flags);
+ sp->ts_prewordlen = (char_u)STRLEN(preword);
+ sp->ts_splitoff = sp->ts_twordlen;
+ }
+ break;
+ }
+
+ if (sp->ts_curi > len || byts[arridx] != 0) {
+ /* Past bytes in node and/or past NUL bytes. */
+ sp->ts_state = STATE_ENDNUL;
+ sp->ts_save_badflags = su->su_badflags;
+ break;
+ }
+
+ /*
+ * End of word in tree.
+ */
+ ++sp->ts_curi; /* eat one NUL byte */
+
+ flags = (int)idxs[arridx];
+
+ /* Skip words with the NOSUGGEST flag. */
+ if (flags & WF_NOSUGGEST)
+ break;
+
+ fword_ends = (fword[sp->ts_fidx] == NUL
+ || (soundfold
+ ? vim_iswhite(fword[sp->ts_fidx])
+ : !spell_iswordp(fword + sp->ts_fidx, curwin)));
+ tword[sp->ts_twordlen] = NUL;
+
+ if (sp->ts_prefixdepth <= PFD_NOTSPECIAL
+ && (sp->ts_flags & TSF_PREFIXOK) == 0) {
+ /* There was a prefix before the word. Check that the prefix
+ * can be used with this word. */
+ /* Count the length of the NULs in the prefix. If there are
+ * none this must be the first try without a prefix. */
+ n = stack[sp->ts_prefixdepth].ts_arridx;
+ len = pbyts[n++];
+ for (c = 0; c < len && pbyts[n + c] == 0; ++c)
+ ;
+ if (c > 0) {
+ c = valid_word_prefix(c, n, flags,
+ tword + sp->ts_splitoff, slang, FALSE);
+ if (c == 0)
+ break;
+
+ /* Use the WF_RARE flag for a rare prefix. */
+ if (c & WF_RAREPFX)
+ flags |= WF_RARE;
+
+ /* Tricky: when checking for both prefix and compounding
+ * we run into the prefix flag first.
+ * Remember that it's OK, so that we accept the prefix
+ * when arriving at a compound flag. */
+ sp->ts_flags |= TSF_PREFIXOK;
+ }
+ }
+
+ /* Check NEEDCOMPOUND: can't use word without compounding. Do try
+ * appending another compound word below. */
+ if (sp->ts_complen == sp->ts_compsplit && fword_ends
+ && (flags & WF_NEEDCOMP))
+ goodword_ends = FALSE;
+ else
+ goodword_ends = TRUE;
+
+ p = NULL;
+ compound_ok = TRUE;
+ if (sp->ts_complen > sp->ts_compsplit) {
+ if (slang->sl_nobreak) {
+ /* There was a word before this word. When there was no
+ * change in this word (it was correct) add the first word
+ * as a suggestion. If this word was corrected too, we
+ * need to check if a correct word follows. */
+ if (sp->ts_fidx - sp->ts_splitfidx
+ == sp->ts_twordlen - sp->ts_splitoff
+ && STRNCMP(fword + sp->ts_splitfidx,
+ tword + sp->ts_splitoff,
+ sp->ts_fidx - sp->ts_splitfidx) == 0) {
+ preword[sp->ts_prewordlen] = NUL;
+ newscore = score_wordcount_adj(slang, sp->ts_score,
+ preword + sp->ts_prewordlen,
+ sp->ts_prewordlen > 0);
+ /* Add the suggestion if the score isn't too bad. */
+ if (newscore <= su->su_maxscore)
+ add_suggestion(su, &su->su_ga, preword,
+ sp->ts_splitfidx - repextra,
+ newscore, 0, FALSE,
+ lp->lp_sallang, FALSE);
+ break;
+ }
+ } else {
+ /* There was a compound word before this word. If this
+ * word does not support compounding then give up
+ * (splitting is tried for the word without compound
+ * flag). */
+ if (((unsigned)flags >> 24) == 0
+ || sp->ts_twordlen - sp->ts_splitoff
+ < slang->sl_compminlen)
+ break;
+ /* For multi-byte chars check character length against
+ * COMPOUNDMIN. */
+ if (has_mbyte
+ && slang->sl_compminlen > 0
+ && mb_charlen(tword + sp->ts_splitoff)
+ < slang->sl_compminlen)
+ break;
+
+ compflags[sp->ts_complen] = ((unsigned)flags >> 24);
+ compflags[sp->ts_complen + 1] = NUL;
+ vim_strncpy(preword + sp->ts_prewordlen,
+ tword + sp->ts_splitoff,
+ sp->ts_twordlen - sp->ts_splitoff);
+
+ /* Verify CHECKCOMPOUNDPATTERN rules. */
+ if (match_checkcompoundpattern(preword, sp->ts_prewordlen,
+ &slang->sl_comppat))
+ compound_ok = FALSE;
+
+ if (compound_ok) {
+ p = preword;
+ while (*skiptowhite(p) != NUL)
+ p = skipwhite(skiptowhite(p));
+ if (fword_ends && !can_compound(slang, p,
+ compflags + sp->ts_compsplit))
+ /* Compound is not allowed. But it may still be
+ * possible if we add another (short) word. */
+ compound_ok = FALSE;
+ }
+
+ /* Get pointer to last char of previous word. */
+ p = preword + sp->ts_prewordlen;
+ mb_ptr_back(preword, p);
+ }
+ }
+
+ /*
+ * Form the word with proper case in preword.
+ * If there is a word from a previous split, append.
+ * For the soundfold tree don't change the case, simply append.
+ */
+ if (soundfold)
+ STRCPY(preword + sp->ts_prewordlen, tword + sp->ts_splitoff);
+ else if (flags & WF_KEEPCAP)
+ /* Must find the word in the keep-case tree. */
+ find_keepcap_word(slang, tword + sp->ts_splitoff,
+ preword + sp->ts_prewordlen);
+ else {
+ /* Include badflags: If the badword is onecap or allcap
+ * use that for the goodword too. But if the badword is
+ * allcap and it's only one char long use onecap. */
+ c = su->su_badflags;
+ if ((c & WF_ALLCAP)
+ && su->su_badlen == (*mb_ptr2len)(su->su_badptr)
+ )
+ c = WF_ONECAP;
+ c |= flags;
+
+ /* When appending a compound word after a word character don't
+ * use Onecap. */
+ if (p != NULL && spell_iswordp_nmw(p, curwin))
+ c &= ~WF_ONECAP;
+ make_case_word(tword + sp->ts_splitoff,
+ preword + sp->ts_prewordlen, c);
+ }
+
+ if (!soundfold) {
+ /* Don't use a banned word. It may appear again as a good
+ * word, thus remember it. */
+ if (flags & WF_BANNED) {
+ add_banned(su, preword + sp->ts_prewordlen);
+ break;
+ }
+ if ((sp->ts_complen == sp->ts_compsplit
+ && WAS_BANNED(su, preword + sp->ts_prewordlen))
+ || WAS_BANNED(su, preword)) {
+ if (slang->sl_compprog == NULL)
+ break;
+ /* the word so far was banned but we may try compounding */
+ goodword_ends = FALSE;
+ }
+ }
+
+ newscore = 0;
+ if (!soundfold) { /* soundfold words don't have flags */
+ if ((flags & WF_REGION)
+ && (((unsigned)flags >> 16) & lp->lp_region) == 0)
+ newscore += SCORE_REGION;
+ if (flags & WF_RARE)
+ newscore += SCORE_RARE;
+
+ if (!spell_valid_case(su->su_badflags,
+ captype(preword + sp->ts_prewordlen, NULL)))
+ newscore += SCORE_ICASE;
+ }
+
+ /* TODO: how about splitting in the soundfold tree? */
+ if (fword_ends
+ && goodword_ends
+ && sp->ts_fidx >= sp->ts_fidxtry
+ && compound_ok) {
+ /* The badword also ends: add suggestions. */
+#ifdef DEBUG_TRIEWALK
+ if (soundfold && STRCMP(preword, "smwrd") == 0) {
+ int j;
+
+ /* print the stack of changes that brought us here */
+ smsg("------ %s -------", fword);
+ for (j = 0; j < depth; ++j)
+ smsg("%s", changename[j]);
+ }
+#endif
+ if (soundfold) {
+ /* For soundfolded words we need to find the original
+ * words, the edit distance and then add them. */
+ add_sound_suggest(su, preword, sp->ts_score, lp);
+ } else if (sp->ts_fidx > 0) {
+ /* 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);
+ if (!spell_iswordp(p, curwin)) {
+ p = preword + STRLEN(preword);
+ mb_ptr_back(preword, p);
+ if (spell_iswordp(p, curwin))
+ newscore += SCORE_NONWORD;
+ }
+
+ /* Give a bonus to words seen before. */
+ score = score_wordcount_adj(slang,
+ sp->ts_score + newscore,
+ preword + sp->ts_prewordlen,
+ sp->ts_prewordlen > 0);
+
+ /* Add the suggestion if the score isn't too bad. */
+ if (score <= su->su_maxscore) {
+ add_suggestion(su, &su->su_ga, preword,
+ sp->ts_fidx - repextra,
+ score, 0, FALSE, lp->lp_sallang, FALSE);
+
+ if (su->su_badflags & WF_MIXCAP) {
+ /* We really don't know if the word should be
+ * upper or lower case, add both. */
+ c = captype(preword, NULL);
+ if (c == 0 || c == WF_ALLCAP) {
+ make_case_word(tword + sp->ts_splitoff,
+ preword + sp->ts_prewordlen,
+ c == 0 ? WF_ALLCAP : 0);
+
+ add_suggestion(su, &su->su_ga, preword,
+ sp->ts_fidx - repextra,
+ score + SCORE_ICASE, 0, FALSE,
+ lp->lp_sallang, FALSE);
+ }
+ }
+ }
+ }
+ }
+
+ /*
+ * Try word split and/or compounding.
+ */
+ if ((sp->ts_fidx >= sp->ts_fidxtry || fword_ends)
+ /* Don't split halfway a character. */
+ && (!has_mbyte || sp->ts_tcharlen == 0)
+ ) {
+ int try_compound;
+ int try_split;
+
+ /* If past the end of the bad word don't try a split.
+ * Otherwise try changing the next word. E.g., find
+ * suggestions for "the the" where the second "the" is
+ * different. It's done like a split.
+ * TODO: word split for soundfold words */
+ try_split = (sp->ts_fidx - repextra < su->su_badlen)
+ && !soundfold;
+
+ /* Get here in several situations:
+ * 1. The word in the tree ends:
+ * If the word allows compounding try that. Otherwise try
+ * a split by inserting a space. For both check that a
+ * valid words starts at fword[sp->ts_fidx].
+ * For NOBREAK do like compounding to be able to check if
+ * the next word is valid.
+ * 2. The badword does end, but it was due to a change (e.g.,
+ * a swap). No need to split, but do check that the
+ * following word is valid.
+ * 3. The badword and the word in the tree end. It may still
+ * be possible to compound another (short) word.
+ */
+ try_compound = FALSE;
+ if (!soundfold
+ && slang->sl_compprog != NULL
+ && ((unsigned)flags >> 24) != 0
+ && sp->ts_twordlen - sp->ts_splitoff
+ >= slang->sl_compminlen
+ && (!has_mbyte
+ || slang->sl_compminlen == 0
+ || mb_charlen(tword + sp->ts_splitoff)
+ >= slang->sl_compminlen)
+ && (slang->sl_compsylmax < MAXWLEN
+ || sp->ts_complen + 1 - sp->ts_compsplit
+ < slang->sl_compmax)
+ && (can_be_compound(sp, slang,
+ compflags, ((unsigned)flags >> 24)))) {
+ try_compound = TRUE;
+ compflags[sp->ts_complen] = ((unsigned)flags >> 24);
+ compflags[sp->ts_complen + 1] = NUL;
+ }
+
+ /* For NOBREAK we never try splitting, it won't make any word
+ * valid. */
+ if (slang->sl_nobreak)
+ try_compound = TRUE;
+
+ /* If we could add a compound word, and it's also possible to
+ * split at this point, do the split first and set
+ * TSF_DIDSPLIT to avoid doing it again. */
+ else if (!fword_ends
+ && try_compound
+ && (sp->ts_flags & TSF_DIDSPLIT) == 0) {
+ try_compound = FALSE;
+ sp->ts_flags |= TSF_DIDSPLIT;
+ --sp->ts_curi; /* do the same NUL again */
+ compflags[sp->ts_complen] = NUL;
+ } else
+ sp->ts_flags &= ~TSF_DIDSPLIT;
+
+ if (try_split || try_compound) {
+ if (!try_compound && (!fword_ends || !goodword_ends)) {
+ /* If we're going to split need to check that the
+ * words so far are valid for compounding. If there
+ * is only one word it must not have the NEEDCOMPOUND
+ * flag. */
+ if (sp->ts_complen == sp->ts_compsplit
+ && (flags & WF_NEEDCOMP))
+ break;
+ p = preword;
+ while (*skiptowhite(p) != NUL)
+ p = skipwhite(skiptowhite(p));
+ if (sp->ts_complen > sp->ts_compsplit
+ && !can_compound(slang, p,
+ compflags + sp->ts_compsplit))
+ break;
+
+ if (slang->sl_nosplitsugs)
+ newscore += SCORE_SPLIT_NO;
+ else
+ newscore += SCORE_SPLIT;
+
+ /* Give a bonus to words seen before. */
+ newscore = score_wordcount_adj(slang, newscore,
+ preword + sp->ts_prewordlen, TRUE);
+ }
+
+ if (TRY_DEEPER(su, stack, depth, newscore)) {
+ go_deeper(stack, depth, newscore);
+#ifdef DEBUG_TRIEWALK
+ if (!try_compound && !fword_ends)
+ sprintf(changename[depth], "%.*s-%s: split",
+ sp->ts_twordlen, tword, fword + sp->ts_fidx);
+ else
+ sprintf(changename[depth], "%.*s-%s: compound",
+ sp->ts_twordlen, tword, fword + sp->ts_fidx);
+#endif
+ /* Save things to be restored at STATE_SPLITUNDO. */
+ sp->ts_save_badflags = su->su_badflags;
+ sp->ts_state = STATE_SPLITUNDO;
+
+ ++depth;
+ sp = &stack[depth];
+
+ /* Append a space to preword when splitting. */
+ if (!try_compound && !fword_ends)
+ STRCAT(preword, " ");
+ sp->ts_prewordlen = (char_u)STRLEN(preword);
+ sp->ts_splitoff = sp->ts_twordlen;
+ sp->ts_splitfidx = sp->ts_fidx;
+
+ /* If the badword has a non-word character at this
+ * position skip it. That means replacing the
+ * non-word character with a space. Always skip a
+ * character when the word ends. But only when the
+ * good word can end. */
+ if (((!try_compound && !spell_iswordp_nmw(fword
+ + sp->ts_fidx,
+ curwin))
+ || fword_ends)
+ && fword[sp->ts_fidx] != NUL
+ && goodword_ends) {
+ int l;
+
+ if (has_mbyte)
+ l = MB_BYTE2LEN(fword[sp->ts_fidx]);
+ else
+ l = 1;
+ if (fword_ends) {
+ /* Copy the skipped character to preword. */
+ mch_memmove(preword + sp->ts_prewordlen,
+ fword + sp->ts_fidx, l);
+ sp->ts_prewordlen += l;
+ preword[sp->ts_prewordlen] = NUL;
+ } else
+ sp->ts_score -= SCORE_SPLIT - SCORE_SUBST;
+ sp->ts_fidx += l;
+ }
+
+ /* When compounding include compound flag in
+ * compflags[] (already set above). When splitting we
+ * may start compounding over again. */
+ if (try_compound)
+ ++sp->ts_complen;
+ else
+ sp->ts_compsplit = sp->ts_complen;
+ sp->ts_prefixdepth = PFD_NOPREFIX;
+
+ /* set su->su_badflags to the caps type at this
+ * position */
+ if (has_mbyte)
+ n = nofold_len(fword, sp->ts_fidx, su->su_badptr);
+ else
+ n = sp->ts_fidx;
+ su->su_badflags = badword_captype(su->su_badptr + n,
+ su->su_badptr + su->su_badlen);
+
+ /* Restart at top of the tree. */
+ sp->ts_arridx = 0;
+
+ /* If there are postponed prefixes, try these too. */
+ if (pbyts != NULL) {
+ byts = pbyts;
+ idxs = pidxs;
+ sp->ts_prefixdepth = PFD_PREFIXTREE;
+ sp->ts_state = STATE_NOPREFIX;
+ }
+ }
+ }
+ }
+ break;
+
+ case STATE_SPLITUNDO:
+ /* Undo the changes done for word split or compound word. */
+ su->su_badflags = sp->ts_save_badflags;
+
+ /* Continue looking for NUL bytes. */
+ sp->ts_state = STATE_START;
+
+ /* In case we went into the prefix tree. */
+ byts = fbyts;
+ idxs = fidxs;
+ break;
+
+ case STATE_ENDNUL:
+ /* Past the NUL bytes in the node. */
+ su->su_badflags = sp->ts_save_badflags;
+ if (fword[sp->ts_fidx] == NUL
+ && sp->ts_tcharlen == 0
+ ) {
+ /* The badword ends, can't use STATE_PLAIN. */
+ sp->ts_state = STATE_DEL;
+ break;
+ }
+ sp->ts_state = STATE_PLAIN;
+ /*FALLTHROUGH*/
+
+ case STATE_PLAIN:
+ /*
+ * Go over all possible bytes at this node, add each to tword[]
+ * and use child node. "ts_curi" is the index.
+ */
+ arridx = sp->ts_arridx;
+ if (sp->ts_curi > byts[arridx]) {
+ /* Done all bytes at this node, do next state. When still at
+ * already changed bytes skip the other tricks. */
+ if (sp->ts_fidx >= sp->ts_fidxtry)
+ sp->ts_state = STATE_DEL;
+ else
+ sp->ts_state = STATE_FINAL;
+ } else {
+ arridx += sp->ts_curi++;
+ c = byts[arridx];
+
+ /* Normal byte, go one level deeper. If it's not equal to the
+ * byte in the bad word adjust the score. But don't even try
+ * when the byte was already changed. And don't try when we
+ * just deleted this byte, accepting it is always cheaper then
+ * delete + substitute. */
+ if (c == fword[sp->ts_fidx]
+ || (sp->ts_tcharlen > 0 && sp->ts_isdiff != DIFF_NONE)
+ )
+ newscore = 0;
+ else
+ newscore = SCORE_SUBST;
+ if ((newscore == 0
+ || (sp->ts_fidx >= sp->ts_fidxtry
+ && ((sp->ts_flags & TSF_DIDDEL) == 0
+ || c != fword[sp->ts_delidx])))
+ && TRY_DEEPER(su, stack, depth, newscore)) {
+ go_deeper(stack, depth, newscore);
+#ifdef DEBUG_TRIEWALK
+ if (newscore > 0)
+ sprintf(changename[depth], "%.*s-%s: subst %c to %c",
+ sp->ts_twordlen, tword, fword + sp->ts_fidx,
+ fword[sp->ts_fidx], c);
+ else
+ sprintf(changename[depth], "%.*s-%s: accept %c",
+ sp->ts_twordlen, tword, fword + sp->ts_fidx,
+ fword[sp->ts_fidx]);
+#endif
+ ++depth;
+ sp = &stack[depth];
+ ++sp->ts_fidx;
+ tword[sp->ts_twordlen++] = c;
+ sp->ts_arridx = idxs[arridx];
+ if (newscore == SCORE_SUBST)
+ sp->ts_isdiff = DIFF_YES;
+ if (has_mbyte) {
+ /* Multi-byte characters are a bit complicated to
+ * handle: They differ when any of the bytes differ
+ * and then their length may also differ. */
+ if (sp->ts_tcharlen == 0) {
+ /* First byte. */
+ sp->ts_tcharidx = 0;
+ sp->ts_tcharlen = MB_BYTE2LEN(c);
+ sp->ts_fcharstart = sp->ts_fidx - 1;
+ sp->ts_isdiff = (newscore != 0)
+ ? DIFF_YES : DIFF_NONE;
+ } else if (sp->ts_isdiff == DIFF_INSERT)
+ /* When inserting trail bytes don't advance in the
+ * bad word. */
+ --sp->ts_fidx;
+ if (++sp->ts_tcharidx == sp->ts_tcharlen) {
+ /* Last byte of character. */
+ if (sp->ts_isdiff == DIFF_YES) {
+ /* 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]);
+
+ /* 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;
+ } 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)) {
+ /* Inserting a composing char doesn't
+ * count that much. */
+ sp->ts_score -= SCORE_INS - SCORE_INSCOMP;
+ } else {
+ /* If the previous character was the same,
+ * thus doubling a character, give a bonus
+ * 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;
+ }
+ }
+
+ /* Starting a new char, reset the length. */
+ sp->ts_tcharlen = 0;
+ }
+ } else {
+ /* If we found a similar char adjust the score.
+ * We do this after calling go_deeper() because
+ * it's slow. */
+ if (newscore != 0
+ && !soundfold
+ && slang->sl_has_map
+ && similar_chars(slang,
+ c, fword[sp->ts_fidx - 1]))
+ sp->ts_score -= SCORE_SUBST - SCORE_SIMILAR;
+ }
+ }
+ }
+ break;
+
+ case STATE_DEL:
+ /* When past the first byte of a multi-byte char don't try
+ * delete/insert/swap a character. */
+ if (has_mbyte && sp->ts_tcharlen > 0) {
+ sp->ts_state = STATE_FINAL;
+ break;
+ }
+ /*
+ * Try skipping one character in the bad word (delete it).
+ */
+ sp->ts_state = STATE_INS_PREP;
+ sp->ts_curi = 1;
+ if (soundfold && sp->ts_fidx == 0 && fword[sp->ts_fidx] == '*')
+ /* Deleting a vowel at the start of a word counts less, see
+ * soundalike_score(). */
+ newscore = 2 * SCORE_DEL / 3;
+ else
+ newscore = SCORE_DEL;
+ if (fword[sp->ts_fidx] != NUL
+ && TRY_DEEPER(su, stack, depth, newscore)) {
+ go_deeper(stack, depth, newscore);
+#ifdef DEBUG_TRIEWALK
+ sprintf(changename[depth], "%.*s-%s: delete %c",
+ sp->ts_twordlen, tword, fword + sp->ts_fidx,
+ fword[sp->ts_fidx]);
+#endif
+ ++depth;
+
+ /* Remember what character we deleted, so that we can avoid
+ * inserting it again. */
+ stack[depth].ts_flags |= TSF_DIDDEL;
+ stack[depth].ts_delidx = sp->ts_fidx;
+
+ /* Advance over the character in fword[]. Give a bonus to the
+ * 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;
+ }
+ break;
+ }
+ /*FALLTHROUGH*/
+
+ case STATE_INS_PREP:
+ if (sp->ts_flags & TSF_DIDDEL) {
+ /* If we just deleted a byte then inserting won't make sense,
+ * a substitute is always cheaper. */
+ sp->ts_state = STATE_SWAP;
+ break;
+ }
+
+ /* skip over NUL bytes */
+ n = sp->ts_arridx;
+ for (;; ) {
+ if (sp->ts_curi > byts[n]) {
+ /* Only NUL bytes at this node, go to next state. */
+ sp->ts_state = STATE_SWAP;
+ break;
+ }
+ if (byts[n + sp->ts_curi] != NUL) {
+ /* Found a byte to insert. */
+ sp->ts_state = STATE_INS;
+ break;
+ }
+ ++sp->ts_curi;
+ }
+ break;
+
+ /*FALLTHROUGH*/
+
+ case STATE_INS:
+ /* Insert one byte. Repeat this for each possible byte at this
+ * node. */
+ n = sp->ts_arridx;
+ if (sp->ts_curi > byts[n]) {
+ /* Done all bytes at this node, go to next state. */
+ sp->ts_state = STATE_SWAP;
+ break;
+ }
+
+ /* Do one more byte at this node, but:
+ * - Skip NUL bytes.
+ * - Skip the byte if it's equal to the byte in the word,
+ * accepting that byte is always better.
+ */
+ n += sp->ts_curi++;
+ c = byts[n];
+ if (soundfold && sp->ts_twordlen == 0 && c == '*')
+ /* Inserting a vowel at the start of a word counts less,
+ * see soundalike_score(). */
+ newscore = 2 * SCORE_INS / 3;
+ else
+ newscore = SCORE_INS;
+ if (c != fword[sp->ts_fidx]
+ && TRY_DEEPER(su, stack, depth, newscore)) {
+ go_deeper(stack, depth, newscore);
+#ifdef DEBUG_TRIEWALK
+ sprintf(changename[depth], "%.*s-%s: insert %c",
+ sp->ts_twordlen, tword, fword + sp->ts_fidx,
+ c);
+#endif
+ ++depth;
+ sp = &stack[depth];
+ tword[sp->ts_twordlen++] = c;
+ sp->ts_arridx = idxs[n];
+ if (has_mbyte) {
+ fl = MB_BYTE2LEN(c);
+ if (fl > 1) {
+ /* There are following bytes for the same character.
+ * We must find all bytes before trying
+ * delete/insert/swap/etc. */
+ sp->ts_tcharlen = fl;
+ sp->ts_tcharidx = 1;
+ sp->ts_isdiff = DIFF_INSERT;
+ }
+ } else
+ fl = 1;
+ if (fl == 1) {
+ /* If the previous character was the same, thus doubling a
+ * character, give a bonus to the score. Also for
+ * soundfold words (illogical but does give a better
+ * score). */
+ if (sp->ts_twordlen >= 2
+ && tword[sp->ts_twordlen - 2] == c)
+ sp->ts_score -= SCORE_INS - SCORE_INSDUP;
+ }
+ }
+ break;
+
+ case STATE_SWAP:
+ /*
+ * Swap two bytes in the bad word: "12" -> "21".
+ * We change "fword" here, it's changed back afterwards at
+ * STATE_UNSWAP.
+ */
+ p = fword + sp->ts_fidx;
+ c = *p;
+ if (c == NUL) {
+ /* End of word, can't swap or replace. */
+ sp->ts_state = STATE_FINAL;
+ break;
+ }
+
+ /* Don't swap if the first character is not a word character.
+ * SWAP3 etc. also don't make sense then. */
+ if (!soundfold && !spell_iswordp(p, curwin)) {
+ sp->ts_state = STATE_REP_INI;
+ 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);
+ } 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];
+ }
+
+ /* When the second character is NUL we can't swap. */
+ if (c2 == NUL) {
+ sp->ts_state = STATE_REP_INI;
+ break;
+ }
+
+ /* When characters are identical, swap won't do anything.
+ * Also get here if the second char is not a word character. */
+ if (c == c2) {
+ sp->ts_state = STATE_SWAP3;
+ break;
+ }
+ 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);
+#endif
+ sp->ts_state = STATE_UNSWAP;
+ ++depth;
+ if (has_mbyte) {
+ fl = mb_char2len(c2);
+ mch_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
+ /* If this swap doesn't work then SWAP3 won't either. */
+ 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);
+ mch_memmove(p + MB_BYTE2LEN(p[n]), p, n);
+ mb_char2bytes(c, p);
+ } else {
+ c = *p;
+ *p = p[1];
+ p[1] = c;
+ }
+ /*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);
+ } 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];
+ }
+
+ /* When characters are identical: "121" then SWAP3 result is
+ * identical, ROT3L result is same as SWAP: "211", ROT3L result is
+ * same as SWAP on next char: "112". Thus skip all swapping.
+ * Also skip when c3 is NUL.
+ * Also get here when the third character is not a word character.
+ * Second character may any char: "a.b" -> "b.a" */
+ if (c == c3 || c3 == NUL) {
+ sp->ts_state = STATE_REP_INI;
+ break;
+ }
+ if (TRY_DEEPER(su, stack, depth, SCORE_SWAP3)) {
+ go_deeper(stack, depth, SCORE_SWAP3);
+#ifdef DEBUG_TRIEWALK
+ sprintf(changename[depth], "%.*s-%s: swap3 %c and %c",
+ sp->ts_twordlen, tword, fword + sp->ts_fidx,
+ c, c3);
+#endif
+ sp->ts_state = STATE_UNSWAP3;
+ ++depth;
+ if (has_mbyte) {
+ tl = mb_char2len(c3);
+ mch_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;
+ }
+ } else
+ sp->ts_state = STATE_REP_INI;
+ break;
+
+ 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]);
+ mch_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;
+ }
+
+ if (!soundfold && !spell_iswordp(p, curwin)) {
+ /* Middle char is not a word char, skip the rotate. First and
+ * third char were already checked at swap and swap3. */
+ sp->ts_state = STATE_REP_INI;
+ break;
+ }
+
+ /* Rotate three characters left: "123" -> "231". We change
+ * "fword" here, it's changed back afterwards at STATE_UNROT3L. */
+ if (TRY_DEEPER(su, stack, depth, SCORE_SWAP3)) {
+ go_deeper(stack, depth, SCORE_SWAP3);
+#ifdef DEBUG_TRIEWALK
+ p = fword + sp->ts_fidx;
+ sprintf(changename[depth], "%.*s-%s: rotate left %c%c%c",
+ sp->ts_twordlen, tword, fword + sp->ts_fidx,
+ p[0], p[1], p[2]);
+#endif
+ 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);
+ mch_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;
+ }
+ } else
+ sp->ts_state = STATE_REP_INI;
+ break;
+
+ 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]);
+ mch_memmove(p + tl, p, n);
+ mb_char2bytes(c, p);
+ } else {
+ c = p[2];
+ p[2] = p[1];
+ p[1] = *p;
+ *p = c;
+ }
+
+ /* Rotate three bytes right: "123" -> "312". We change "fword"
+ * here, it's changed back afterwards at STATE_UNROT3R. */
+ if (TRY_DEEPER(su, stack, depth, SCORE_SWAP3)) {
+ go_deeper(stack, depth, SCORE_SWAP3);
+#ifdef DEBUG_TRIEWALK
+ p = fword + sp->ts_fidx;
+ sprintf(changename[depth], "%.*s-%s: rotate right %c%c%c",
+ sp->ts_twordlen, tword, fword + sp->ts_fidx,
+ p[0], p[1], p[2]);
+#endif
+ 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);
+ mch_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;
+ }
+ } else
+ sp->ts_state = STATE_REP_INI;
+ break;
+
+ 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]);
+ mch_memmove(p, p + tl, n);
+ mb_char2bytes(c, p + n);
+ } else {
+ c = *p;
+ *p = p[1];
+ p[1] = p[2];
+ p[2] = c;
+ }
+ /*FALLTHROUGH*/
+
+ case STATE_REP_INI:
+ /* Check if matching with REP items from the .aff file would work.
+ * Quickly skip if:
+ * - there are no REP items and we are not in the soundfold trie
+ * - the score is going to be too high anyway
+ * - already applied a REP item or swapped here */
+ if ((lp->lp_replang == NULL && !soundfold)
+ || sp->ts_score + SCORE_REP >= su->su_maxscore
+ || sp->ts_fidx < sp->ts_fidxtry) {
+ sp->ts_state = STATE_FINAL;
+ break;
+ }
+
+ /* Use the first byte to quickly find the first entry that may
+ * match. If the index is -1 there is none. */
+ if (soundfold)
+ sp->ts_curi = slang->sl_repsal_first[fword[sp->ts_fidx]];
+ else
+ sp->ts_curi = lp->lp_replang->sl_rep_first[fword[sp->ts_fidx]];
+
+ if (sp->ts_curi < 0) {
+ sp->ts_state = STATE_FINAL;
+ break;
+ }
+
+ sp->ts_state = STATE_REP;
+ /*FALLTHROUGH*/
+
+ case STATE_REP:
+ /* Try matching with REP items from the .aff file. For each match
+ * replace the characters and check if the resulting word is
+ * valid. */
+ p = fword + sp->ts_fidx;
+
+ if (soundfold)
+ gap = &slang->sl_repsal;
+ else
+ gap = &lp->lp_replang->sl_rep;
+ while (sp->ts_curi < gap->ga_len) {
+ ftp = (fromto_T *)gap->ga_data + sp->ts_curi++;
+ if (*ftp->ft_from != *p) {
+ /* past possible matching entries */
+ sp->ts_curi = gap->ga_len;
+ break;
+ }
+ if (STRNCMP(ftp->ft_from, p, STRLEN(ftp->ft_from)) == 0
+ && TRY_DEEPER(su, stack, depth, SCORE_REP)) {
+ go_deeper(stack, depth, SCORE_REP);
+#ifdef DEBUG_TRIEWALK
+ sprintf(changename[depth], "%.*s-%s: replace %s with %s",
+ sp->ts_twordlen, tword, fword + sp->ts_fidx,
+ ftp->ft_from, ftp->ft_to);
+#endif
+ /* Need to undo this afterwards. */
+ sp->ts_state = STATE_REP_UNDO;
+
+ /* Change the "from" to the "to" string. */
+ ++depth;
+ fl = (int)STRLEN(ftp->ft_from);
+ tl = (int)STRLEN(ftp->ft_to);
+ if (fl != tl) {
+ STRMOVE(p + tl, p + fl);
+ repextra += tl - fl;
+ }
+ mch_memmove(p, ftp->ft_to, tl);
+ stack[depth].ts_fidxtry = sp->ts_fidx + tl;
+ stack[depth].ts_tcharlen = 0;
+ break;
+ }
+ }
+
+ if (sp->ts_curi >= gap->ga_len && sp->ts_state == STATE_REP)
+ /* No (more) matches. */
+ sp->ts_state = STATE_FINAL;
+
+ break;
+
+ case STATE_REP_UNDO:
+ /* Undo a REP replacement and continue with the next one. */
+ if (soundfold)
+ gap = &slang->sl_repsal;
+ else
+ gap = &lp->lp_replang->sl_rep;
+ ftp = (fromto_T *)gap->ga_data + sp->ts_curi - 1;
+ fl = (int)STRLEN(ftp->ft_from);
+ tl = (int)STRLEN(ftp->ft_to);
+ p = fword + sp->ts_fidx;
+ if (fl != tl) {
+ STRMOVE(p + fl, p + tl);
+ repextra -= tl - fl;
+ }
+ mch_memmove(p, ftp->ft_from, fl);
+ sp->ts_state = STATE_REP;
+ break;
+
+ default:
+ /* Did all possible states at this level, go up one level. */
+ --depth;
+
+ if (depth >= 0 && stack[depth].ts_prefixdepth == PFD_PREFIXTREE) {
+ /* Continue in or go back to the prefix tree. */
+ byts = pbyts;
+ idxs = pidxs;
+ }
+
+ /* Don't check for CTRL-C too often, it takes time. */
+ if (--breakcheckcount == 0) {
+ ui_breakcheck();
+ breakcheckcount = 1000;
+ }
+ }
+ }
+}
+
+
+/*
+ * Go one level deeper in the tree.
+ */
+static void go_deeper(stack, depth, score_add)
+trystate_T *stack;
+int depth;
+int score_add;
+{
+ stack[depth + 1] = stack[depth];
+ stack[depth + 1].ts_state = STATE_START;
+ stack[depth + 1].ts_score = stack[depth].ts_score + score_add;
+ stack[depth + 1].ts_curi = 1; /* start just after length byte */
+ stack[depth + 1].ts_flags = 0;
+}
+
+/*
+ * Case-folding may change the number of bytes: Count nr of chars in
+ * fword[flen] and return the byte length of that many chars in "word".
+ */
+static int nofold_len(fword, flen, word)
+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;
+ return (int)(p - word);
+}
+
+/*
+ * "fword" is a good word with case folded. Find the matching keep-case
+ * words and put it in "kword".
+ * Theoretically there could be several keep-case words that result in the
+ * same case-folded word, but we only find one...
+ */
+static void find_keepcap_word(slang, fword, kword)
+slang_T *slang;
+char_u *fword;
+char_u *kword;
+{
+ char_u uword[MAXWLEN]; /* "fword" in upper-case */
+ int depth;
+ idx_T tryidx;
+
+ /* The following arrays are used at each depth in the tree. */
+ idx_T arridx[MAXWLEN];
+ int round[MAXWLEN];
+ int fwordidx[MAXWLEN];
+ int uwordidx[MAXWLEN];
+ int kwordlen[MAXWLEN];
+
+ int flen, ulen;
+ int l;
+ int len;
+ int c;
+ idx_T lo, hi, m;
+ char_u *p;
+ char_u *byts = slang->sl_kbyts; /* array with bytes of the words */
+ idx_T *idxs = slang->sl_kidxs; /* array with indexes */
+
+ if (byts == NULL) {
+ /* array is empty: "cannot happen" */
+ *kword = NUL;
+ return;
+ }
+
+ /* Make an all-cap version of "fword". */
+ allcap_copy(fword, uword);
+
+ /*
+ * Each character needs to be tried both case-folded and upper-case.
+ * All this gets very complicated if we keep in mind that changing case
+ * may change the byte length of a multi-byte character...
+ */
+ depth = 0;
+ arridx[0] = 0;
+ round[0] = 0;
+ fwordidx[0] = 0;
+ uwordidx[0] = 0;
+ kwordlen[0] = 0;
+ while (depth >= 0) {
+ if (fword[fwordidx[depth]] == NUL) {
+ /* We are at the end of "fword". If the tree allows a word to end
+ * here we have found a match. */
+ if (byts[arridx[depth] + 1] == 0) {
+ kword[kwordlen[depth]] = NUL;
+ return;
+ }
+
+ /* kword is getting too long, continue one level up */
+ --depth;
+ } else if (++round[depth] > 2) {
+ /* tried both fold-case and upper-case character, continue one
+ * level up */
+ --depth;
+ } else {
+ /*
+ * 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
+ ulen = flen = 1;
+ if (round[depth] == 1) {
+ p = fword + fwordidx[depth];
+ l = flen;
+ } else {
+ p = uword + uwordidx[depth];
+ l = ulen;
+ }
+
+ for (tryidx = arridx[depth]; l > 0; --l) {
+ /* Perform a binary search in the list of accepted bytes. */
+ len = byts[tryidx++];
+ c = *p++;
+ lo = tryidx;
+ hi = tryidx + len - 1;
+ while (lo < hi) {
+ m = (lo + hi) / 2;
+ if (byts[m] > c)
+ hi = m - 1;
+ else if (byts[m] < c)
+ lo = m + 1;
+ else {
+ lo = hi = m;
+ break;
+ }
+ }
+
+ /* Stop if there is no matching byte. */
+ if (hi < lo || byts[lo] != c)
+ break;
+
+ /* Continue at the child (if there is one). */
+ tryidx = idxs[lo];
+ }
+
+ if (l == 0) {
+ /*
+ * Found the matching char. Copy it to "kword" and go a
+ * level deeper.
+ */
+ if (round[depth] == 1) {
+ STRNCPY(kword + kwordlen[depth], fword + fwordidx[depth],
+ flen);
+ kwordlen[depth + 1] = kwordlen[depth] + flen;
+ } else {
+ STRNCPY(kword + kwordlen[depth], uword + uwordidx[depth],
+ ulen);
+ kwordlen[depth + 1] = kwordlen[depth] + ulen;
+ }
+ fwordidx[depth + 1] = fwordidx[depth] + flen;
+ uwordidx[depth + 1] = uwordidx[depth] + ulen;
+
+ ++depth;
+ arridx[depth] = tryidx;
+ round[depth] = 0;
+ }
+ }
+ }
+
+ /* Didn't find it: "cannot happen". */
+ *kword = NUL;
+}
+
+/*
+ * Compute the sound-a-like score for suggestions in su->su_ga and add them to
+ * su->su_sga.
+ */
+static void score_comp_sal(su)
+suginfo_T *su;
+{
+ langp_T *lp;
+ char_u badsound[MAXWLEN];
+ int i;
+ suggest_T *stp;
+ suggest_T *sstp;
+ int score;
+ int lpi;
+
+ if (ga_grow(&su->su_sga, su->su_ga.ga_len) == FAIL)
+ return;
+
+ /* Use the sound-folding of the first language that supports it. */
+ for (lpi = 0; lpi < curwin->w_s->b_langp.ga_len; ++lpi) {
+ lp = LANGP_ENTRY(curwin->w_s->b_langp, lpi);
+ if (lp->lp_slang->sl_sal.ga_len > 0) {
+ /* soundfold the bad word */
+ spell_soundfold(lp->lp_slang, su->su_fbadword, TRUE, badsound);
+
+ for (i = 0; i < su->su_ga.ga_len; ++i) {
+ stp = &SUG(su->su_ga, i);
+
+ /* Case-fold the suggested word, sound-fold it and compute the
+ * sound-a-like score. */
+ score = stp_sal_score(stp, su, lp->lp_slang, badsound);
+ if (score < SCORE_MAXMAX) {
+ /* Add the suggestion. */
+ sstp = &SUG(su->su_sga, su->su_sga.ga_len);
+ sstp->st_word = vim_strsave(stp->st_word);
+ if (sstp->st_word != NULL) {
+ sstp->st_wordlen = stp->st_wordlen;
+ sstp->st_score = score;
+ sstp->st_altscore = 0;
+ sstp->st_orglen = stp->st_orglen;
+ ++su->su_sga.ga_len;
+ }
+ }
+ }
+ break;
+ }
+ }
+}
+
+/*
+ * Combine the list of suggestions in su->su_ga and su->su_sga.
+ * They are entwined.
+ */
+static void score_combine(su)
+suginfo_T *su;
+{
+ int i;
+ int j;
+ garray_T ga;
+ garray_T *gap;
+ langp_T *lp;
+ suggest_T *stp;
+ char_u *p;
+ char_u badsound[MAXWLEN];
+ int round;
+ int lpi;
+ slang_T *slang = NULL;
+
+ /* Add the alternate score to su_ga. */
+ for (lpi = 0; lpi < curwin->w_s->b_langp.ga_len; ++lpi) {
+ lp = LANGP_ENTRY(curwin->w_s->b_langp, lpi);
+ if (lp->lp_slang->sl_sal.ga_len > 0) {
+ /* soundfold the bad word */
+ slang = lp->lp_slang;
+ spell_soundfold(slang, su->su_fbadword, TRUE, badsound);
+
+ for (i = 0; i < su->su_ga.ga_len; ++i) {
+ stp = &SUG(su->su_ga, i);
+ stp->st_altscore = stp_sal_score(stp, su, slang, badsound);
+ if (stp->st_altscore == SCORE_MAXMAX)
+ stp->st_score = (stp->st_score * 3 + SCORE_BIG) / 4;
+ else
+ stp->st_score = (stp->st_score * 3
+ + stp->st_altscore) / 4;
+ stp->st_salscore = FALSE;
+ }
+ break;
+ }
+ }
+
+ if (slang == NULL) { /* Using "double" without sound folding. */
+ (void)cleanup_suggestions(&su->su_ga, su->su_maxscore,
+ su->su_maxcount);
+ return;
+ }
+
+ /* Add the alternate score to su_sga. */
+ for (i = 0; i < su->su_sga.ga_len; ++i) {
+ stp = &SUG(su->su_sga, i);
+ stp->st_altscore = spell_edit_score(slang,
+ su->su_badword, stp->st_word);
+ if (stp->st_score == SCORE_MAXMAX)
+ stp->st_score = (SCORE_BIG * 7 + stp->st_altscore) / 8;
+ else
+ stp->st_score = (stp->st_score * 7 + stp->st_altscore) / 8;
+ stp->st_salscore = TRUE;
+ }
+
+ /* Remove bad suggestions, sort the suggestions and truncate at "maxcount"
+ * for both lists. */
+ check_suggestions(su, &su->su_ga);
+ (void)cleanup_suggestions(&su->su_ga, su->su_maxscore, su->su_maxcount);
+ check_suggestions(su, &su->su_sga);
+ (void)cleanup_suggestions(&su->su_sga, su->su_maxscore, su->su_maxcount);
+
+ ga_init2(&ga, (int)sizeof(suginfo_T), 1);
+ if (ga_grow(&ga, su->su_ga.ga_len + su->su_sga.ga_len) == FAIL)
+ return;
+
+ stp = &SUG(ga, 0);
+ for (i = 0; i < su->su_ga.ga_len || i < su->su_sga.ga_len; ++i) {
+ /* round 1: get a suggestion from su_ga
+ * round 2: get a suggestion from su_sga */
+ for (round = 1; round <= 2; ++round) {
+ gap = round == 1 ? &su->su_ga : &su->su_sga;
+ if (i < gap->ga_len) {
+ /* Don't add a word if it's already there. */
+ p = SUG(*gap, i).st_word;
+ for (j = 0; j < ga.ga_len; ++j)
+ if (STRCMP(stp[j].st_word, p) == 0)
+ break;
+ if (j == ga.ga_len)
+ stp[ga.ga_len++] = SUG(*gap, i);
+ else
+ vim_free(p);
+ }
+ }
+ }
+
+ ga_clear(&su->su_ga);
+ ga_clear(&su->su_sga);
+
+ /* Truncate the list to the number of suggestions that will be displayed. */
+ if (ga.ga_len > su->su_maxcount) {
+ for (i = su->su_maxcount; i < ga.ga_len; ++i)
+ vim_free(stp[i].st_word);
+ ga.ga_len = su->su_maxcount;
+ }
+
+ su->su_ga = ga;
+}
+
+/*
+ * For the goodword in "stp" compute the soundalike score compared to the
+ * badword.
+ */
+static int stp_sal_score(stp, su, slang, badsound)
+suggest_T *stp;
+suginfo_T *su;
+slang_T *slang;
+char_u *badsound; /* sound-folded badword */
+{
+ char_u *p;
+ char_u *pbad;
+ char_u *pgood;
+ char_u badsound2[MAXWLEN];
+ char_u fword[MAXWLEN];
+ char_u goodsound[MAXWLEN];
+ char_u goodword[MAXWLEN];
+ int lendiff;
+
+ lendiff = (int)(su->su_badlen - stp->st_orglen);
+ if (lendiff >= 0)
+ pbad = badsound;
+ else {
+ /* soundfold the bad word with more characters following */
+ (void)spell_casefold(su->su_badptr, stp->st_orglen, fword, MAXWLEN);
+
+ /* When joining two words the sound often changes a lot. E.g., "t he"
+ * sounds like "t h" while "the" sounds like "@". Avoid that by
+ * removing the space. Don't do it when the good word also contains a
+ * space. */
+ if (vim_iswhite(su->su_badptr[su->su_badlen])
+ && *skiptowhite(stp->st_word) == NUL)
+ for (p = fword; *(p = skiptowhite(p)) != NUL; )
+ STRMOVE(p, p + 1);
+
+ spell_soundfold(slang, fword, TRUE, badsound2);
+ pbad = badsound2;
+ }
+
+ if (lendiff > 0 && stp->st_wordlen + lendiff < MAXWLEN) {
+ /* Add part of the bad word to the good word, so that we soundfold
+ * what replaces the bad word. */
+ STRCPY(goodword, stp->st_word);
+ vim_strncpy(goodword + stp->st_wordlen,
+ su->su_badptr + su->su_badlen - lendiff, lendiff);
+ pgood = goodword;
+ } else
+ pgood = stp->st_word;
+
+ /* Sound-fold the word and compute the score for the difference. */
+ spell_soundfold(slang, pgood, FALSE, goodsound);
+
+ return soundalike_score(goodsound, pbad);
+}
+
+/* structure used to store soundfolded words that add_sound_suggest() has
+ * handled already. */
+typedef struct {
+ short sft_score; /* lowest score used */
+ char_u sft_word[1]; /* soundfolded word, actually longer */
+} sftword_T;
+
+static sftword_T dumsft;
+#define HIKEY2SFT(p) ((sftword_T *)(p - (dumsft.sft_word - (char_u *)&dumsft)))
+#define HI2SFT(hi) HIKEY2SFT((hi)->hi_key)
+
+/*
+ * Prepare for calling suggest_try_soundalike().
+ */
+static void suggest_try_soundalike_prep() {
+ langp_T *lp;
+ int lpi;
+ slang_T *slang;
+
+ /* Do this for all languages that support sound folding and for which a
+ * .sug file has been loaded. */
+ for (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_sal.ga_len > 0 && slang->sl_sbyts != NULL)
+ /* prepare the hashtable used by add_sound_suggest() */
+ hash_init(&slang->sl_sounddone);
+ }
+}
+
+/*
+ * Find suggestions by comparing the word in a sound-a-like form.
+ * Note: This doesn't support postponed prefixes.
+ */
+static void suggest_try_soundalike(su)
+suginfo_T *su;
+{
+ char_u salword[MAXWLEN];
+ langp_T *lp;
+ int lpi;
+ slang_T *slang;
+
+ /* Do this for all languages that support sound folding and for which a
+ * .sug file has been loaded. */
+ for (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_sal.ga_len > 0 && slang->sl_sbyts != NULL) {
+ /* soundfold the bad word */
+ spell_soundfold(slang, su->su_fbadword, TRUE, salword);
+
+ /* try all kinds of inserts/deletes/swaps/etc. */
+ /* TODO: also soundfold the next words, so that we can try joining
+ * and splitting */
+ suggest_trie_walk(su, lp, salword, TRUE);
+ }
+ }
+}
+
+/*
+ * Finish up after calling suggest_try_soundalike().
+ */
+static void suggest_try_soundalike_finish() {
+ langp_T *lp;
+ int lpi;
+ slang_T *slang;
+ int todo;
+ hashitem_T *hi;
+
+ /* Do this for all languages that support sound folding and for which a
+ * .sug file has been loaded. */
+ for (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_sal.ga_len > 0 && slang->sl_sbyts != NULL) {
+ /* Free the info about handled words. */
+ todo = (int)slang->sl_sounddone.ht_used;
+ for (hi = slang->sl_sounddone.ht_array; todo > 0; ++hi)
+ if (!HASHITEM_EMPTY(hi)) {
+ vim_free(HI2SFT(hi));
+ --todo;
+ }
+
+ /* Clear the hashtable, it may also be used by another region. */
+ hash_clear(&slang->sl_sounddone);
+ hash_init(&slang->sl_sounddone);
+ }
+ }
+}
+
+/*
+ * A match with a soundfolded word is found. Add the good word(s) that
+ * produce this soundfolded word.
+ */
+static void add_sound_suggest(su, goodword, score, lp)
+suginfo_T *su;
+char_u *goodword;
+int score; /* soundfold score */
+langp_T *lp;
+{
+ slang_T *slang = lp->lp_slang; /* language for sound folding */
+ int sfwordnr;
+ char_u *nrline;
+ int orgnr;
+ char_u theword[MAXWLEN];
+ int i;
+ int wlen;
+ char_u *byts;
+ idx_T *idxs;
+ int n;
+ int wordcount;
+ int wc;
+ int goodscore;
+ hash_T hash;
+ hashitem_T *hi;
+ sftword_T *sft;
+ int bc, gc;
+ int limit;
+
+ /*
+ * It's very well possible that the same soundfold word is found several
+ * times with different scores. Since the following is quite slow only do
+ * 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);
+ if (HASHITEM_EMPTY(hi)) {
+ sft = (sftword_T *)alloc((unsigned)(sizeof(sftword_T)
+ + STRLEN(goodword)));
+ if (sft != NULL) {
+ sft->sft_score = score;
+ STRCPY(sft->sft_word, goodword);
+ hash_add_item(&slang->sl_sounddone, hi, sft->sft_word, hash);
+ }
+ } else {
+ sft = HI2SFT(hi);
+ if (score >= sft->sft_score)
+ return;
+ sft->sft_score = score;
+ }
+
+ /*
+ * Find the word nr in the soundfold tree.
+ */
+ sfwordnr = soundfold_find(slang, goodword);
+ if (sfwordnr < 0) {
+ EMSG2(_(e_intern2), "add_sound_suggest()");
+ return;
+ }
+
+ /*
+ * go over the list of good words that produce this soundfold word
+ */
+ nrline = ml_get_buf(slang->sl_sugbuf, (linenr_T)(sfwordnr + 1), FALSE);
+ orgnr = 0;
+ while (*nrline != NUL) {
+ /* The wordnr was stored in a minimal nr of bytes as an offset to the
+ * previous wordnr. */
+ orgnr += bytes2offset(&nrline);
+
+ byts = slang->sl_fbyts;
+ idxs = slang->sl_fidxs;
+
+ /* Lookup the word "orgnr" one of the two tries. */
+ n = 0;
+ wordcount = 0;
+ for (wlen = 0; wlen < MAXWLEN - 3; ++wlen) {
+ i = 1;
+ if (wordcount == orgnr && byts[n + 1] == NUL)
+ break; /* found end of word */
+
+ if (byts[n + 1] == NUL)
+ ++wordcount;
+
+ /* skip over the NUL bytes */
+ for (; byts[n + i] == NUL; ++i)
+ if (i > byts[n]) { /* safety check */
+ STRCPY(theword + wlen, "BAD");
+ wlen += 3;
+ goto badword;
+ }
+
+ /* One of the siblings must have the word. */
+ for (; i < byts[n]; ++i) {
+ wc = idxs[idxs[n + i]]; /* nr of words under this byte */
+ if (wordcount + wc > orgnr)
+ break;
+ wordcount += wc;
+ }
+
+ theword[wlen] = byts[n + i];
+ n = idxs[n + i];
+ }
+badword:
+ theword[wlen] = NUL;
+
+ /* Go over the possible flags and regions. */
+ for (; i <= byts[n] && byts[n + i] == NUL; ++i) {
+ char_u cword[MAXWLEN];
+ char_u *p;
+ int flags = (int)idxs[n + i];
+
+ /* Skip words with the NOSUGGEST flag */
+ if (flags & WF_NOSUGGEST)
+ continue;
+
+ if (flags & WF_KEEPCAP) {
+ /* Must find the word in the keep-case tree. */
+ find_keepcap_word(slang, theword, cword);
+ p = cword;
+ } else {
+ flags |= su->su_badflags;
+ if ((flags & WF_CAPMASK) != 0) {
+ /* Need to fix case according to "flags". */
+ make_case_word(theword, cword, flags);
+ p = cword;
+ } else
+ p = theword;
+ }
+
+ /* Add the suggestion. */
+ if (sps_flags & SPS_DOUBLE) {
+ /* Add the suggestion if the score isn't too bad. */
+ if (score <= su->su_maxscore)
+ add_suggestion(su, &su->su_sga, p, su->su_badlen,
+ score, 0, FALSE, slang, FALSE);
+ } else {
+ /* Add a penalty for words in another region. */
+ if ((flags & WF_REGION)
+ && (((unsigned)flags >> 16) & lp->lp_region) == 0)
+ goodscore = SCORE_REGION;
+ else
+ goodscore = 0;
+
+ /* Add a small penalty for changing the first letter from
+ * lower to upper case. Helps for "tath" -> "Kath", which is
+ * less common than "tath" -> "path". Don't do it when the
+ * letter is the same, that has already been counted. */
+ gc = PTR2CHAR(p);
+ if (SPELL_ISUPPER(gc)) {
+ bc = PTR2CHAR(su->su_badword);
+ if (!SPELL_ISUPPER(bc)
+ && SPELL_TOFOLD(bc) != SPELL_TOFOLD(gc))
+ goodscore += SCORE_ICASE / 2;
+ }
+
+ /* Compute the score for the good word. This only does letter
+ * insert/delete/swap/replace. REP items are not considered,
+ * which may make the score a bit higher.
+ * Use a limit for the score to make it work faster. Use
+ * MAXSCORE(), because RESCORE() will change the score.
+ * If the limit is very high then the iterative method is
+ * inefficient, using an array is quicker. */
+ limit = MAXSCORE(su->su_sfmaxscore - goodscore, score);
+ if (limit > SCORE_LIMITMAX)
+ goodscore += spell_edit_score(slang, su->su_badword, p);
+ else
+ goodscore += spell_edit_score_limit(slang, su->su_badword,
+ p, limit);
+
+ /* When going over the limit don't bother to do the rest. */
+ if (goodscore < SCORE_MAXMAX) {
+ /* Give a bonus to words seen before. */
+ goodscore = score_wordcount_adj(slang, goodscore, p, FALSE);
+
+ /* Add the suggestion if the score isn't too bad. */
+ goodscore = RESCORE(goodscore, score);
+ if (goodscore <= su->su_sfmaxscore)
+ add_suggestion(su, &su->su_ga, p, su->su_badlen,
+ goodscore, score, TRUE, slang, TRUE);
+ }
+ }
+ }
+ /* smsg("word %s (%d): %s (%d)", sftword, sftnr, theword, orgnr); */
+ }
+}
+
+/*
+ * Find word "word" in fold-case tree for "slang" and return the word number.
+ */
+static int soundfold_find(slang, word)
+slang_T *slang;
+char_u *word;
+{
+ idx_T arridx = 0;
+ int len;
+ int wlen = 0;
+ int c;
+ char_u *ptr = word;
+ char_u *byts;
+ idx_T *idxs;
+ int wordnr = 0;
+
+ byts = slang->sl_sbyts;
+ idxs = slang->sl_sidxs;
+
+ for (;; ) {
+ /* First byte is the number of possible bytes. */
+ len = byts[arridx++];
+
+ /* If the first possible byte is a zero the word could end here.
+ * If the word ends we found the word. If not skip the NUL bytes. */
+ c = ptr[wlen];
+ if (byts[arridx] == NUL) {
+ if (c == NUL)
+ break;
+
+ /* Skip over the zeros, there can be several. */
+ while (len > 0 && byts[arridx] == NUL) {
+ ++arridx;
+ --len;
+ }
+ if (len == 0)
+ return -1; /* no children, word should have ended here */
+ ++wordnr;
+ }
+
+ /* If the word ends we didn't find it. */
+ if (c == NUL)
+ return -1;
+
+ /* Perform a binary search in the list of accepted bytes. */
+ if (c == TAB) /* <Tab> is handled like <Space> */
+ c = ' ';
+ while (byts[arridx] < c) {
+ /* The word count is in the first idxs[] entry of the child. */
+ wordnr += idxs[idxs[arridx]];
+ ++arridx;
+ if (--len == 0) /* end of the bytes, didn't find it */
+ return -1;
+ }
+ if (byts[arridx] != c) /* didn't find the byte */
+ return -1;
+
+ /* Continue at the child (if there is one). */
+ arridx = idxs[arridx];
+ ++wlen;
+
+ /* One space in the good word may stand for several spaces in the
+ * checked word. */
+ if (c == ' ')
+ while (ptr[wlen] == ' ' || ptr[wlen] == TAB)
+ ++wlen;
+ }
+
+ return wordnr;
+}
+
+/*
+ * Copy "fword" to "cword", fixing case according to "flags".
+ */
+static void make_case_word(fword, cword, flags)
+char_u *fword;
+char_u *cword;
+int flags;
+{
+ if (flags & WF_ALLCAP)
+ /* Make it all upper-case */
+ allcap_copy(fword, cword);
+ else if (flags & WF_ONECAP)
+ /* Make the first letter upper-case */
+ onecap_copy(fword, cword, TRUE);
+ else
+ /* Use goodword as-is. */
+ STRCPY(cword, fword);
+}
+
+/*
+ * Use map string "map" for languages "lp".
+ */
+static void set_map_str(lp, map)
+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 = alloc((unsigned)(cl + headcl + 2));
+ if (b == NULL)
+ return;
+ 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"));
+ vim_free(b);
+ }
+ } else
+ lp->sl_map_array[c] = headc;
+ }
+ }
+}
+
+/*
+ * Return TRUE if "c1" and "c2" are similar characters according to the MAP
+ * lines in the .aff file.
+ */
+static int similar_chars(slang, c1, c2)
+slang_T *slang;
+int c1;
+int c2;
+{
+ int m1, m2;
+ char_u buf[MB_MAXBYTES + 1];
+ hashitem_T *hi;
+
+ if (c1 >= 256) {
+ buf[mb_char2bytes(c1, buf)] = 0;
+ hi = hash_find(&slang->sl_map_hash, buf);
+ if (HASHITEM_EMPTY(hi))
+ m1 = 0;
+ else
+ m1 = mb_ptr2char(hi->hi_key + STRLEN(hi->hi_key) + 1);
+ } else
+ m1 = slang->sl_map_array[c1];
+ if (m1 == 0)
+ return FALSE;
+
+
+ if (c2 >= 256) {
+ buf[mb_char2bytes(c2, buf)] = 0;
+ hi = hash_find(&slang->sl_map_hash, buf);
+ if (HASHITEM_EMPTY(hi))
+ m2 = 0;
+ else
+ m2 = mb_ptr2char(hi->hi_key + STRLEN(hi->hi_key) + 1);
+ } else
+ m2 = slang->sl_map_array[c2];
+
+ return m1 == m2;
+}
+
+/*
+ * Add a suggestion to the list of suggestions.
+ * For a suggestion that is already in the list the lowest score is remembered.
+ */
+static void add_suggestion(su, gap, goodword, badlenarg, score, altscore,
+ had_bonus,
+ slang,
+ maxsf)
+suginfo_T *su;
+garray_T *gap; /* either su_ga or su_sga */
+char_u *goodword;
+int badlenarg; /* len of bad word replaced with "goodword" */
+int score;
+int altscore;
+int had_bonus; /* value for st_had_bonus */
+slang_T *slang; /* language for sound folding */
+int maxsf; /* su_maxscore applies to soundfold score,
+ su_sfmaxscore to the total score. */
+{
+ int goodlen; /* len of goodword changed */
+ 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;
+ 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)
+ break;
+ }
+
+ if (badlen == 0 && goodlen == 0)
+ /* goodword doesn't change anything; may happen for "the the" changing
+ * the first "the" to itself. */
+ return;
+
+ if (gap->ga_len == 0)
+ i = -1;
+ 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". */
+ stp = &SUG(*gap, 0);
+ for (i = gap->ga_len; --i >= 0; ++stp)
+ if (stp->st_wordlen == goodlen
+ && stp->st_orglen == badlen
+ && STRNCMP(stp->st_word, goodword, goodlen) == 0) {
+ /*
+ * Found it. Remember the word with the lowest score.
+ */
+ if (stp->st_slang == NULL)
+ stp->st_slang = slang;
+
+ new_sug.st_score = score;
+ new_sug.st_altscore = altscore;
+ new_sug.st_had_bonus = had_bonus;
+
+ if (stp->st_had_bonus != had_bonus) {
+ /* Only one of the two had the soundalike score computed.
+ * Need to do that for the other one now, otherwise the
+ * scores can't be compared. This happens because
+ * suggest_try_change() doesn't compute the soundalike
+ * word to keep it fast, while some special methods set
+ * the soundalike score to zero. */
+ if (had_bonus)
+ rescore_one(su, stp);
+ else {
+ new_sug.st_word = stp->st_word;
+ new_sug.st_wordlen = stp->st_wordlen;
+ new_sug.st_slang = stp->st_slang;
+ new_sug.st_orglen = badlen;
+ rescore_one(su, &new_sug);
+ }
+ }
+
+ if (stp->st_score > new_sug.st_score) {
+ stp->st_score = new_sug.st_score;
+ stp->st_altscore = new_sug.st_altscore;
+ stp->st_had_bonus = new_sug.st_had_bonus;
+ }
+ break;
+ }
+ }
+
+ if (i < 0 && ga_grow(gap, 1) == OK) {
+ /* Add a suggestion. */
+ stp = &SUG(*gap, gap->ga_len);
+ stp->st_word = vim_strnsave(goodword, goodlen);
+ if (stp->st_word != NULL) {
+ stp->st_wordlen = goodlen;
+ stp->st_score = score;
+ stp->st_altscore = altscore;
+ stp->st_had_bonus = had_bonus;
+ stp->st_orglen = badlen;
+ stp->st_slang = slang;
+ ++gap->ga_len;
+
+ /* If we have too many suggestions now, sort the list and keep
+ * the best suggestions. */
+ if (gap->ga_len > SUG_MAX_COUNT(su)) {
+ if (maxsf)
+ su->su_sfmaxscore = cleanup_suggestions(gap,
+ su->su_sfmaxscore, SUG_CLEAN_COUNT(su));
+ else
+ su->su_maxscore = cleanup_suggestions(gap,
+ su->su_maxscore, SUG_CLEAN_COUNT(su));
+ }
+ }
+ }
+}
+
+/*
+ * Suggestions may in fact be flagged as errors. Esp. for banned words and
+ * for split words, such as "the the". Remove these from the list here.
+ */
+static void check_suggestions(su, gap)
+suginfo_T *su;
+garray_T *gap; /* either su_ga or su_sga */
+{
+ suggest_T *stp;
+ int i;
+ char_u longword[MAXWLEN + 1];
+ int len;
+ hlf_T attr;
+
+ stp = &SUG(*gap, 0);
+ for (i = gap->ga_len - 1; i >= 0; --i) {
+ /* Need to append what follows to check for "the the". */
+ vim_strncpy(longword, stp[i].st_word, MAXWLEN);
+ len = stp[i].st_wordlen;
+ vim_strncpy(longword + len, su->su_badptr + stp[i].st_orglen,
+ MAXWLEN - len);
+ attr = HLF_COUNT;
+ (void)spell_check(curwin, longword, &attr, NULL, FALSE);
+ if (attr != HLF_COUNT) {
+ /* Remove this entry. */
+ vim_free(stp[i].st_word);
+ --gap->ga_len;
+ if (i < gap->ga_len)
+ mch_memmove(stp + i, stp + i + 1,
+ sizeof(suggest_T) * (gap->ga_len - i));
+ }
+ }
+}
+
+
+/*
+ * Add a word to be banned.
+ */
+static void add_banned(su, word)
+suginfo_T *su;
+char_u *word;
+{
+ char_u *s;
+ hash_T hash;
+ hashitem_T *hi;
+
+ hash = hash_hash(word);
+ hi = hash_lookup(&su->su_banned, word, hash);
+ if (HASHITEM_EMPTY(hi)) {
+ s = vim_strsave(word);
+ if (s != NULL)
+ hash_add_item(&su->su_banned, hi, s, hash);
+ }
+}
+
+/*
+ * Recompute the score for all suggestions if sound-folding is possible. This
+ * is slow, thus only done for the final results.
+ */
+static void rescore_suggestions(su)
+suginfo_T *su;
+{
+ int i;
+
+ if (su->su_sallang != NULL)
+ for (i = 0; i < su->su_ga.ga_len; ++i)
+ rescore_one(su, &SUG(su->su_ga, i));
+}
+
+/*
+ * Recompute the score for one suggestion if sound-folding is possible.
+ */
+static void rescore_one(su, stp)
+suginfo_T *su;
+suggest_T *stp;
+{
+ slang_T *slang = stp->st_slang;
+ char_u sal_badword[MAXWLEN];
+ char_u *p;
+
+ /* Only rescore suggestions that have no sal score yet and do have a
+ * language. */
+ if (slang != NULL && slang->sl_sal.ga_len > 0 && !stp->st_had_bonus) {
+ if (slang == su->su_sallang)
+ p = su->su_sal_badword;
+ else {
+ spell_soundfold(slang, su->su_fbadword, TRUE, sal_badword);
+ p = sal_badword;
+ }
+
+ stp->st_altscore = stp_sal_score(stp, su, slang, p);
+ if (stp->st_altscore == SCORE_MAXMAX)
+ stp->st_altscore = SCORE_BIG;
+ stp->st_score = RESCORE(stp->st_score, stp->st_altscore);
+ stp->st_had_bonus = TRUE;
+ }
+}
+
+static int
+sug_compare __ARGS((const void *s1, const void *s2));
+
+/*
+ * Function given to qsort() to sort the suggestions on st_score.
+ * First on "st_score", then "st_altscore" then alphabetically.
+ */
+static int sug_compare(s1, s2)
+const void *s1;
+const void *s2;
+{
+ suggest_T *p1 = (suggest_T *)s1;
+ suggest_T *p2 = (suggest_T *)s2;
+ int n = p1->st_score - p2->st_score;
+
+ if (n == 0) {
+ n = p1->st_altscore - p2->st_altscore;
+ if (n == 0)
+ n = STRICMP(p1->st_word, p2->st_word);
+ }
+ return n;
+}
+
+/*
+ * Cleanup the suggestions:
+ * - Sort on score.
+ * - Remove words that won't be displayed.
+ * Returns the maximum score in the list or "maxscore" unmodified.
+ */
+static int cleanup_suggestions(gap, maxscore, keep)
+garray_T *gap;
+int maxscore;
+int keep; /* nr of suggestions to keep */
+{
+ suggest_T *stp = &SUG(*gap, 0);
+ int i;
+
+ /* Sort the list. */
+ qsort(gap->ga_data, (size_t)gap->ga_len, sizeof(suggest_T), sug_compare);
+
+ /* Truncate the list to the number of suggestions that will be displayed. */
+ if (gap->ga_len > keep) {
+ for (i = keep; i < gap->ga_len; ++i)
+ vim_free(stp[i].st_word);
+ gap->ga_len = keep;
+ return stp[keep - 1].st_score;
+ }
+ return maxscore;
+}
+
+/*
+ * Soundfold a string, for soundfold().
+ * Result is in allocated memory, NULL for an error.
+ */
+char_u * eval_soundfold(word)
+char_u *word;
+{
+ langp_T *lp;
+ char_u sound[MAXWLEN];
+ int lpi;
+
+ if (curwin->w_p_spell && *curwin->w_s->b_p_spl != NUL)
+ /* Use the sound-folding of the first language that supports it. */
+ for (lpi = 0; lpi < curwin->w_s->b_langp.ga_len; ++lpi) {
+ lp = LANGP_ENTRY(curwin->w_s->b_langp, lpi);
+ if (lp->lp_slang->sl_sal.ga_len > 0) {
+ /* soundfold the word */
+ spell_soundfold(lp->lp_slang, word, FALSE, sound);
+ return vim_strsave(sound);
+ }
+ }
+
+ /* No language with sound folding, return word as-is. */
+ return vim_strsave(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, inword, folded, res)
+slang_T *slang;
+char_u *inword;
+int folded; /* "inword" is already case-folded */
+char_u *res;
+{
+ char_u fword[MAXWLEN];
+ char_u *word;
+
+ if (slang->sl_sofo)
+ /* SOFOFROM and SOFOTO used */
+ spell_soundfold_sofo(slang, inword, res);
+ else {
+ /* SAL items used. Requires the word to be case-folded. */
+ if (folded)
+ word = inword;
+ else {
+ (void)spell_casefold(inword, (int)STRLEN(inword), fword, MAXWLEN);
+ word = fword;
+ }
+
+ if (has_mbyte)
+ spell_soundfold_wsal(slang, word, res);
+ else
+ spell_soundfold_sal(slang, word, res);
+ }
+}
+
+/*
+ * Perform sound folding of "inword" into "res" according to SOFOFROM and
+ * SOFOTO lines.
+ */
+static void spell_soundfold_sofo(slang, inword, res)
+slang_T *slang;
+char_u *inword;
+char_u *res;
+{
+ char_u *s;
+ int ri = 0;
+ int c;
+
+ if (has_mbyte) {
+ int prevc = 0;
+ int *ip;
+
+ /* 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 : vim_iswhite(c))
+ c = ' ';
+ else if (c < 256)
+ c = slang->sl_sal_first[c];
+ else {
+ ip = ((int **)slang->sl_sal.ga_data)[c & 0xff];
+ if (ip == NULL) /* empty list, can't match */
+ c = NUL;
+ else
+ for (;; ) { /* find "c" in the list */
+ if (*ip == 0) { /* not found */
+ c = NUL;
+ break;
+ }
+ if (*ip == c) { /* match! */
+ c = ip[1];
+ break;
+ }
+ ip += 2;
+ }
+ }
+
+ if (c != NUL && c != prevc) {
+ ri += mb_char2bytes(c, res + ri);
+ if (ri + MB_MAXBYTES > MAXWLEN)
+ break;
+ prevc = c;
+ }
+ }
+ } else {
+ /* The sl_sal_first[] table contains the translation. */
+ for (s = inword; (c = *s) != NUL; ++s) {
+ if (vim_iswhite(c))
+ c = ' ';
+ else
+ c = slang->sl_sal_first[c];
+ if (c != NUL && (ri == 0 || res[ri - 1] != c))
+ res[ri++] = c;
+ }
+ }
+
+ res[ri] = NUL;
+}
+
+static void spell_soundfold_sal(slang, inword, res)
+slang_T *slang;
+char_u *inword;
+char_u *res;
+{
+ salitem_T *smp;
+ char_u word[MAXWLEN];
+ char_u *s = inword;
+ char_u *t;
+ char_u *pf;
+ int i, j, z;
+ int reslen;
+ int n, k = 0;
+ int z0;
+ int k0;
+ int n0;
+ int c;
+ int pri;
+ int p0 = -333;
+ int c0;
+
+ /* Remove accents, if wanted. We actually remove all non-word characters.
+ * But keep white space. We need a copy, the word may be changed here. */
+ if (slang->sl_rem_accents) {
+ t = word;
+ while (*s != NUL) {
+ if (vim_iswhite(*s)) {
+ *t++ = ' ';
+ s = skipwhite(s);
+ } else {
+ if (spell_iswordp_nmw(s, curwin))
+ *t++ = *s;
+ ++s;
+ }
+ }
+ *t = NUL;
+ } else
+ vim_strncpy(word, s, MAXWLEN - 1);
+
+ smp = (salitem_T *)slang->sl_sal.ga_data;
+
+ /*
+ * This comes from Aspell phonet.cpp. Converted from C++ to C.
+ * Changed to keep spaces.
+ */
+ i = reslen = z = 0;
+ while ((c = word[i]) != NUL) {
+ /* Start with the first rule that has the character in the word. */
+ n = slang->sl_sal_first[c];
+ z0 = 0;
+
+ if (n >= 0) {
+ /* check all rules for the same letter */
+ for (; (s = smp[n].sm_lead)[0] == c; ++n) {
+ /* Quickly skip entries that don't match the word. Most
+ * entries are less then three chars, optimize for that. */
+ k = smp[n].sm_leadlen;
+ if (k > 1) {
+ if (word[i + 1] != s[1])
+ continue;
+ if (k > 2) {
+ for (j = 2; j < k; ++j)
+ if (word[i + j] != s[j])
+ break;
+ if (j < k)
+ continue;
+ }
+ }
+
+ if ((pf = smp[n].sm_oneof) != NULL) {
+ /* Check for match with one of the chars in "sm_oneof". */
+ while (*pf != NUL && *pf != word[i + k])
+ ++pf;
+ if (*pf == NUL)
+ continue;
+ ++k;
+ }
+ s = smp[n].sm_rules;
+ pri = 5; /* default priority */
+
+ p0 = *s;
+ k0 = k;
+ while (*s == '-' && k > 1) {
+ k--;
+ s++;
+ }
+ if (*s == '<')
+ s++;
+ if (VIM_ISDIGIT(*s)) {
+ /* determine priority */
+ pri = *s - '0';
+ s++;
+ }
+ if (*s == '^' && *(s + 1) == '^')
+ s++;
+
+ if (*s == NUL
+ || (*s == '^'
+ && (i == 0 || !(word[i - 1] == ' '
+ || spell_iswordp(word + i - 1, curwin)))
+ && (*(s + 1) != '$'
+ || (!spell_iswordp(word + i + k0, curwin))))
+ || (*s == '$' && i > 0
+ && spell_iswordp(word + i - 1, curwin)
+ && (!spell_iswordp(word + i + k0, curwin)))) {
+ /* search for followup rules, if: */
+ /* followup and k > 1 and NO '-' in searchstring */
+ c0 = word[i + k - 1];
+ n0 = slang->sl_sal_first[c0];
+
+ if (slang->sl_followup && k > 1 && n0 >= 0
+ && p0 != '-' && word[i + k] != NUL) {
+ /* test follow-up rule for "word[i + k]" */
+ for (; (s = smp[n0].sm_lead)[0] == c0; ++n0) {
+ /* Quickly skip entries that don't match the word.
+ * */
+ k0 = smp[n0].sm_leadlen;
+ if (k0 > 1) {
+ if (word[i + k] != s[1])
+ continue;
+ if (k0 > 2) {
+ pf = word + i + k + 1;
+ for (j = 2; j < k0; ++j)
+ if (*pf++ != s[j])
+ break;
+ if (j < k0)
+ continue;
+ }
+ }
+ k0 += k - 1;
+
+ if ((pf = smp[n0].sm_oneof) != NULL) {
+ /* Check for match with one of the chars in
+ * "sm_oneof". */
+ while (*pf != NUL && *pf != word[i + k0])
+ ++pf;
+ if (*pf == NUL)
+ continue;
+ ++k0;
+ }
+
+ p0 = 5;
+ s = smp[n0].sm_rules;
+ while (*s == '-') {
+ /* "k0" gets NOT reduced because
+ * "if (k0 == k)" */
+ s++;
+ }
+ if (*s == '<')
+ s++;
+ if (VIM_ISDIGIT(*s)) {
+ p0 = *s - '0';
+ s++;
+ }
+
+ if (*s == NUL
+ /* *s == '^' cuts */
+ || (*s == '$'
+ && !spell_iswordp(word + i + k0,
+ curwin))) {
+ if (k0 == k)
+ /* this is just a piece of the string */
+ continue;
+
+ if (p0 < pri)
+ /* priority too low */
+ continue;
+ /* rule fits; stop search */
+ break;
+ }
+ }
+
+ if (p0 >= pri && smp[n0].sm_lead[0] == c0)
+ continue;
+ }
+
+ /* replace string */
+ s = smp[n].sm_to;
+ if (s == NULL)
+ s = (char_u *)"";
+ pf = smp[n].sm_rules;
+ p0 = (vim_strchr(pf, '<') != NULL) ? 1 : 0;
+ if (p0 == 1 && z == 0) {
+ /* rule with '<' is used */
+ if (reslen > 0 && *s != NUL && (res[reslen - 1] == c
+ || res[reslen - 1] == *s))
+ reslen--;
+ z0 = 1;
+ z = 1;
+ k0 = 0;
+ while (*s != NUL && word[i + k0] != NUL) {
+ word[i + k0] = *s;
+ k0++;
+ s++;
+ }
+ if (k > k0)
+ STRMOVE(word + i + k0, word + i + k);
+
+ /* new "actual letter" */
+ c = word[i];
+ } else {
+ /* no '<' rule used */
+ i += k - 1;
+ z = 0;
+ while (*s != NUL && s[1] != NUL && reslen < MAXWLEN) {
+ if (reslen == 0 || res[reslen - 1] != *s)
+ res[reslen++] = *s;
+ s++;
+ }
+ /* new "actual letter" */
+ c = *s;
+ if (strstr((char *)pf, "^^") != NULL) {
+ if (c != NUL)
+ res[reslen++] = c;
+ STRMOVE(word, word + i + 1);
+ i = 0;
+ z0 = 1;
+ }
+ }
+ break;
+ }
+ }
+ } else if (vim_iswhite(c)) {
+ c = ' ';
+ k = 1;
+ }
+
+ if (z0 == 0) {
+ if (k && !p0 && reslen < MAXWLEN && c != NUL
+ && (!slang->sl_collapse || reslen == 0
+ || res[reslen - 1] != c))
+ /* condense only double letters */
+ res[reslen++] = c;
+
+ i++;
+ z = 0;
+ k = 0;
+ }
+ }
+
+ res[reslen] = NUL;
+}
+
+/*
+ * Turn "inword" into its sound-a-like equivalent in "res[MAXWLEN]".
+ * Multi-byte version of spell_soundfold().
+ */
+static void spell_soundfold_wsal(slang, inword, res)
+slang_T *slang;
+char_u *inword;
+char_u *res;
+{
+ salitem_T *smp = (salitem_T *)slang->sl_sal.ga_data;
+ int word[MAXWLEN];
+ int wres[MAXWLEN];
+ int l;
+ char_u *s;
+ int *ws;
+ char_u *t;
+ int *pf;
+ int i, j, z;
+ int reslen;
+ int n, k = 0;
+ int z0;
+ int k0;
+ int n0;
+ int c;
+ int pri;
+ int p0 = -333;
+ int c0;
+ int did_white = FALSE;
+ int wordlen;
+
+
+ /*
+ * Convert the multi-byte string to a wide-character string.
+ * 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);
+ if (slang->sl_rem_accents) {
+ if (enc_utf8 ? utf_class(c) == 0 : vim_iswhite(c)) {
+ if (did_white)
+ continue;
+ c = ' ';
+ did_white = TRUE;
+ } else {
+ did_white = FALSE;
+ if (!spell_iswordp_nmw(t, curwin))
+ continue;
+ }
+ }
+ word[wordlen++] = c;
+ }
+ word[wordlen] = NUL;
+
+ /*
+ * This algorithm comes from Aspell phonet.cpp.
+ * Converted from C++ to C. Added support for multi-byte chars.
+ * Changed to keep spaces.
+ */
+ i = reslen = z = 0;
+ while ((c = word[i]) != NUL) {
+ /* Start with the first rule that has the character in the word. */
+ n = slang->sl_sal_first[c & 0xff];
+ z0 = 0;
+
+ if (n >= 0) {
+ /* Check all rules for the same index byte.
+ * If c is 0x300 need extra check for the end of the array, as
+ * (c & 0xff) is NUL. */
+ for (; ((ws = smp[n].sm_lead_w)[0] & 0xff) == (c & 0xff)
+ && ws[0] != NUL; ++n) {
+ /* Quickly skip entries that don't match the word. Most
+ * entries are less then three chars, optimize for that. */
+ if (c != ws[0])
+ continue;
+ k = smp[n].sm_leadlen;
+ if (k > 1) {
+ if (word[i + 1] != ws[1])
+ continue;
+ if (k > 2) {
+ for (j = 2; j < k; ++j)
+ if (word[i + j] != ws[j])
+ break;
+ if (j < k)
+ continue;
+ }
+ }
+
+ if ((pf = smp[n].sm_oneof_w) != NULL) {
+ /* Check for match with one of the chars in "sm_oneof". */
+ while (*pf != NUL && *pf != word[i + k])
+ ++pf;
+ if (*pf == NUL)
+ continue;
+ ++k;
+ }
+ s = smp[n].sm_rules;
+ pri = 5; /* default priority */
+
+ p0 = *s;
+ k0 = k;
+ while (*s == '-' && k > 1) {
+ k--;
+ s++;
+ }
+ if (*s == '<')
+ s++;
+ if (VIM_ISDIGIT(*s)) {
+ /* determine priority */
+ pri = *s - '0';
+ s++;
+ }
+ if (*s == '^' && *(s + 1) == '^')
+ s++;
+
+ if (*s == NUL
+ || (*s == '^'
+ && (i == 0 || !(word[i - 1] == ' '
+ || spell_iswordp_w(word + i - 1, curwin)))
+ && (*(s + 1) != '$'
+ || (!spell_iswordp_w(word + i + k0, curwin))))
+ || (*s == '$' && i > 0
+ && spell_iswordp_w(word + i - 1, curwin)
+ && (!spell_iswordp_w(word + i + k0, curwin)))) {
+ /* search for followup rules, if: */
+ /* followup and k > 1 and NO '-' in searchstring */
+ c0 = word[i + k - 1];
+ n0 = slang->sl_sal_first[c0 & 0xff];
+
+ if (slang->sl_followup && k > 1 && n0 >= 0
+ && p0 != '-' && word[i + k] != NUL) {
+ /* Test follow-up rule for "word[i + k]"; loop over
+ * all entries with the same index byte. */
+ for (; ((ws = smp[n0].sm_lead_w)[0] & 0xff)
+ == (c0 & 0xff); ++n0) {
+ /* Quickly skip entries that don't match the word.
+ */
+ if (c0 != ws[0])
+ continue;
+ k0 = smp[n0].sm_leadlen;
+ if (k0 > 1) {
+ if (word[i + k] != ws[1])
+ continue;
+ if (k0 > 2) {
+ pf = word + i + k + 1;
+ for (j = 2; j < k0; ++j)
+ if (*pf++ != ws[j])
+ break;
+ if (j < k0)
+ continue;
+ }
+ }
+ k0 += k - 1;
+
+ if ((pf = smp[n0].sm_oneof_w) != NULL) {
+ /* Check for match with one of the chars in
+ * "sm_oneof". */
+ while (*pf != NUL && *pf != word[i + k0])
+ ++pf;
+ if (*pf == NUL)
+ continue;
+ ++k0;
+ }
+
+ p0 = 5;
+ s = smp[n0].sm_rules;
+ while (*s == '-') {
+ /* "k0" gets NOT reduced because
+ * "if (k0 == k)" */
+ s++;
+ }
+ if (*s == '<')
+ s++;
+ if (VIM_ISDIGIT(*s)) {
+ p0 = *s - '0';
+ s++;
+ }
+
+ if (*s == NUL
+ /* *s == '^' cuts */
+ || (*s == '$'
+ && !spell_iswordp_w(word + i + k0,
+ curwin))) {
+ if (k0 == k)
+ /* this is just a piece of the string */
+ continue;
+
+ if (p0 < pri)
+ /* priority too low */
+ continue;
+ /* rule fits; stop search */
+ break;
+ }
+ }
+
+ if (p0 >= pri && (smp[n0].sm_lead_w[0] & 0xff)
+ == (c0 & 0xff))
+ continue;
+ }
+
+ /* replace string */
+ ws = smp[n].sm_to_w;
+ s = smp[n].sm_rules;
+ p0 = (vim_strchr(s, '<') != NULL) ? 1 : 0;
+ if (p0 == 1 && z == 0) {
+ /* rule with '<' is used */
+ if (reslen > 0 && ws != NULL && *ws != NUL
+ && (wres[reslen - 1] == c
+ || wres[reslen - 1] == *ws))
+ reslen--;
+ z0 = 1;
+ z = 1;
+ k0 = 0;
+ if (ws != NULL)
+ while (*ws != NUL && word[i + k0] != NUL) {
+ word[i + k0] = *ws;
+ k0++;
+ ws++;
+ }
+ if (k > k0)
+ mch_memmove(word + i + k0, word + i + k,
+ sizeof(int) * (wordlen - (i + k) + 1));
+
+ /* new "actual letter" */
+ c = word[i];
+ } else {
+ /* no '<' rule used */
+ i += k - 1;
+ z = 0;
+ if (ws != NULL)
+ while (*ws != NUL && ws[1] != NUL
+ && reslen < MAXWLEN) {
+ if (reslen == 0 || wres[reslen - 1] != *ws)
+ wres[reslen++] = *ws;
+ ws++;
+ }
+ /* new "actual letter" */
+ if (ws == NULL)
+ c = NUL;
+ else
+ c = *ws;
+ if (strstr((char *)s, "^^") != NULL) {
+ if (c != NUL)
+ wres[reslen++] = c;
+ mch_memmove(word, word + i + 1,
+ sizeof(int) * (wordlen - (i + 1) + 1));
+ i = 0;
+ z0 = 1;
+ }
+ }
+ break;
+ }
+ }
+ } else if (vim_iswhite(c)) {
+ c = ' ';
+ k = 1;
+ }
+
+ if (z0 == 0) {
+ if (k && !p0 && reslen < MAXWLEN && c != NUL
+ && (!slang->sl_collapse || reslen == 0
+ || wres[reslen - 1] != c))
+ /* condense only double letters */
+ wres[reslen++] = c;
+
+ i++;
+ z = 0;
+ k = 0;
+ }
+ }
+
+ /* 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)
+ break;
+ }
+ res[l] = NUL;
+}
+
+/*
+ * Compute a score for two sound-a-like words.
+ * This permits up to two inserts/deletes/swaps/etc. to keep things fast.
+ * Instead of a generic loop we write out the code. That keeps it fast by
+ * avoiding checks that will not be possible.
+ */
+static int soundalike_score(goodstart, badstart)
+char_u *goodstart; /* sound-folded good word */
+char_u *badstart; /* sound-folded bad word */
+{
+ char_u *goodsound = goodstart;
+ char_u *badsound = badstart;
+ int goodlen;
+ int badlen;
+ int n;
+ char_u *pl, *ps;
+ char_u *pl2, *ps2;
+ int score = 0;
+
+ /* Adding/inserting "*" at the start (word starts with vowel) shouldn't be
+ * counted so much, vowels halfway the word aren't counted at all. */
+ if ((*badsound == '*' || *goodsound == '*') && *badsound != *goodsound) {
+ if ((badsound[0] == NUL && goodsound[1] == NUL)
+ || (goodsound[0] == NUL && badsound[1] == NUL))
+ /* changing word with vowel to word without a sound */
+ return SCORE_DEL;
+ if (badsound[0] == NUL || goodsound[0] == NUL)
+ /* more than two changes */
+ return SCORE_MAXMAX;
+
+ if (badsound[1] == goodsound[1]
+ || (badsound[1] != NUL
+ && goodsound[1] != NUL
+ && badsound[2] == goodsound[2])) {
+ /* handle like a substitute */
+ } else {
+ score = 2 * SCORE_DEL / 3;
+ if (*badsound == '*')
+ ++badsound;
+ else
+ ++goodsound;
+ }
+ }
+
+ goodlen = (int)STRLEN(goodsound);
+ badlen = (int)STRLEN(badsound);
+
+ /* Return quickly if the lengths are too different to be fixed by two
+ * changes. */
+ n = goodlen - badlen;
+ if (n < -2 || n > 2)
+ return SCORE_MAXMAX;
+
+ if (n > 0) {
+ pl = goodsound; /* goodsound is longest */
+ ps = badsound;
+ } else {
+ pl = badsound; /* badsound is longest */
+ ps = goodsound;
+ }
+
+ /* Skip over the identical part. */
+ while (*pl == *ps && *pl != NUL) {
+ ++pl;
+ ++ps;
+ }
+
+ switch (n) {
+ case -2:
+ case 2:
+ /*
+ * Must delete two characters from "pl".
+ */
+ ++pl; /* first delete */
+ while (*pl == *ps) {
+ ++pl;
+ ++ps;
+ }
+ /* strings must be equal after second delete */
+ if (STRCMP(pl + 1, ps) == 0)
+ return score + SCORE_DEL * 2;
+
+ /* Failed to compare. */
+ break;
+
+ case -1:
+ case 1:
+ /*
+ * Minimal one delete from "pl" required.
+ */
+
+ /* 1: delete */
+ pl2 = pl + 1;
+ ps2 = ps;
+ while (*pl2 == *ps2) {
+ if (*pl2 == NUL) /* reached the end */
+ return score + SCORE_DEL;
+ ++pl2;
+ ++ps2;
+ }
+
+ /* 2: delete then swap, then rest must be equal */
+ if (pl2[0] == ps2[1] && pl2[1] == ps2[0]
+ && STRCMP(pl2 + 2, ps2 + 2) == 0)
+ return score + SCORE_DEL + SCORE_SWAP;
+
+ /* 3: delete then substitute, then the rest must be equal */
+ if (STRCMP(pl2 + 1, ps2 + 1) == 0)
+ return score + SCORE_DEL + SCORE_SUBST;
+
+ /* 4: first swap then delete */
+ if (pl[0] == ps[1] && pl[1] == ps[0]) {
+ pl2 = pl + 2; /* swap, skip two chars */
+ ps2 = ps + 2;
+ while (*pl2 == *ps2) {
+ ++pl2;
+ ++ps2;
+ }
+ /* delete a char and then strings must be equal */
+ if (STRCMP(pl2 + 1, ps2) == 0)
+ return score + SCORE_SWAP + SCORE_DEL;
+ }
+
+ /* 5: first substitute then delete */
+ pl2 = pl + 1; /* substitute, skip one char */
+ ps2 = ps + 1;
+ while (*pl2 == *ps2) {
+ ++pl2;
+ ++ps2;
+ }
+ /* delete a char and then strings must be equal */
+ if (STRCMP(pl2 + 1, ps2) == 0)
+ return score + SCORE_SUBST + SCORE_DEL;
+
+ /* Failed to compare. */
+ break;
+
+ case 0:
+ /*
+ * Lengths are equal, thus changes must result in same length: An
+ * insert is only possible in combination with a delete.
+ * 1: check if for identical strings
+ */
+ if (*pl == NUL)
+ return score;
+
+ /* 2: swap */
+ if (pl[0] == ps[1] && pl[1] == ps[0]) {
+ pl2 = pl + 2; /* swap, skip two chars */
+ ps2 = ps + 2;
+ while (*pl2 == *ps2) {
+ if (*pl2 == NUL) /* reached the end */
+ return score + SCORE_SWAP;
+ ++pl2;
+ ++ps2;
+ }
+ /* 3: swap and swap again */
+ if (pl2[0] == ps2[1] && pl2[1] == ps2[0]
+ && STRCMP(pl2 + 2, ps2 + 2) == 0)
+ return score + SCORE_SWAP + SCORE_SWAP;
+
+ /* 4: swap and substitute */
+ if (STRCMP(pl2 + 1, ps2 + 1) == 0)
+ return score + SCORE_SWAP + SCORE_SUBST;
+ }
+
+ /* 5: substitute */
+ pl2 = pl + 1;
+ ps2 = ps + 1;
+ while (*pl2 == *ps2) {
+ if (*pl2 == NUL) /* reached the end */
+ return score + SCORE_SUBST;
+ ++pl2;
+ ++ps2;
+ }
+
+ /* 6: substitute and swap */
+ if (pl2[0] == ps2[1] && pl2[1] == ps2[0]
+ && STRCMP(pl2 + 2, ps2 + 2) == 0)
+ return score + SCORE_SUBST + SCORE_SWAP;
+
+ /* 7: substitute and substitute */
+ if (STRCMP(pl2 + 1, ps2 + 1) == 0)
+ return score + SCORE_SUBST + SCORE_SUBST;
+
+ /* 8: insert then delete */
+ pl2 = pl;
+ ps2 = ps + 1;
+ while (*pl2 == *ps2) {
+ ++pl2;
+ ++ps2;
+ }
+ if (STRCMP(pl2 + 1, ps2) == 0)
+ return score + SCORE_INS + SCORE_DEL;
+
+ /* 9: delete then insert */
+ pl2 = pl + 1;
+ ps2 = ps;
+ while (*pl2 == *ps2) {
+ ++pl2;
+ ++ps2;
+ }
+ if (STRCMP(pl2, ps2 + 1) == 0)
+ return score + SCORE_INS + SCORE_DEL;
+
+ /* Failed to compare. */
+ break;
+ }
+
+ return SCORE_MAXMAX;
+}
+
+/*
+ * Compute the "edit distance" to turn "badword" into "goodword". The less
+ * deletes/inserts/substitutes/swaps are required the lower the score.
+ *
+ * The algorithm is described by Du and Chang, 1992.
+ * The implementation of the algorithm comes from Aspell editdist.cpp,
+ * edit_distance(). It has been converted from C++ to C and modified to
+ * support multi-byte characters.
+ */
+static int spell_edit_score(slang, badword, goodword)
+slang_T *slang;
+char_u *badword;
+char_u *goodword;
+{
+ int *cnt;
+ int badlen, goodlen; /* lengths including NUL */
+ int j, i;
+ int t;
+ int bc, gc;
+ int pbc, pgc;
+ char_u *p;
+ int wbadword[MAXWLEN];
+ int wgoodword[MAXWLEN];
+
+ if (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; )
+ wbadword[badlen++] = mb_cptr2char_adv(&p);
+ wbadword[badlen++] = 0;
+ for (p = goodword, goodlen = 0; *p != NUL; )
+ wgoodword[goodlen++] = mb_cptr2char_adv(&p);
+ wgoodword[goodlen++] = 0;
+ } else {
+ badlen = (int)STRLEN(badword) + 1;
+ goodlen = (int)STRLEN(goodword) + 1;
+ }
+
+ /* We use "cnt" as an array: CNT(badword_idx, goodword_idx). */
+#define CNT(a, b) cnt[(a) + (b) * (badlen + 1)]
+ cnt = (int *)lalloc((long_u)(sizeof(int) * (badlen + 1) * (goodlen + 1)),
+ TRUE);
+ if (cnt == NULL)
+ return 0; /* out of memory */
+
+ CNT(0, 0) = 0;
+ for (j = 1; j <= goodlen; ++j)
+ CNT(0, j) = CNT(0, j - 1) + SCORE_INS;
+
+ for (i = 1; i <= badlen; ++i) {
+ CNT(i, 0) = CNT(i - 1, 0) + SCORE_DEL;
+ for (j = 1; j <= goodlen; ++j) {
+ if (has_mbyte) {
+ bc = wbadword[i - 1];
+ gc = wgoodword[j - 1];
+ } else {
+ bc = badword[i - 1];
+ gc = goodword[j - 1];
+ }
+ if (bc == gc)
+ CNT(i, j) = CNT(i - 1, j - 1);
+ else {
+ /* Use a better score when there is only a case difference. */
+ if (SPELL_TOFOLD(bc) == SPELL_TOFOLD(gc))
+ CNT(i, j) = SCORE_ICASE + CNT(i - 1, j - 1);
+ else {
+ /* For a similar character use SCORE_SIMILAR. */
+ if (slang != NULL
+ && slang->sl_has_map
+ && similar_chars(slang, gc, bc))
+ CNT(i, j) = SCORE_SIMILAR + CNT(i - 1, j - 1);
+ else
+ CNT(i, j) = SCORE_SUBST + CNT(i - 1, j - 1);
+ }
+
+ if (i > 1 && j > 1) {
+ if (has_mbyte) {
+ pbc = wbadword[i - 2];
+ pgc = wgoodword[j - 2];
+ } else {
+ pbc = badword[i - 2];
+ pgc = goodword[j - 2];
+ }
+ if (bc == pgc && pbc == gc) {
+ t = SCORE_SWAP + CNT(i - 2, j - 2);
+ if (t < CNT(i, j))
+ CNT(i, j) = t;
+ }
+ }
+ t = SCORE_DEL + CNT(i - 1, j);
+ if (t < CNT(i, j))
+ CNT(i, j) = t;
+ t = SCORE_INS + CNT(i, j - 1);
+ if (t < CNT(i, j))
+ CNT(i, j) = t;
+ }
+ }
+ }
+
+ i = CNT(badlen - 1, goodlen - 1);
+ vim_free(cnt);
+ return i;
+}
+
+typedef struct {
+ int badi;
+ int goodi;
+ int score;
+} limitscore_T;
+
+/*
+ * Like spell_edit_score(), but with a limit on the score to make it faster.
+ * May return SCORE_MAXMAX when the score is higher than "limit".
+ *
+ * This uses a stack for the edits still to be tried.
+ * The idea comes from Aspell leditdist.cpp. Rewritten in C and added support
+ * for multi-byte characters.
+ */
+static int spell_edit_score_limit(slang, badword, goodword, limit)
+slang_T *slang;
+char_u *badword;
+char_u *goodword;
+int limit;
+{
+ limitscore_T stack[10]; /* allow for over 3 * 2 edits */
+ int stackidx;
+ int bi, gi;
+ int bi2, gi2;
+ int bc, gc;
+ int score;
+ int score_off;
+ int minscore;
+ int round;
+
+ /* Multi-byte characters require a bit more work, use a different function
+ * to avoid testing "has_mbyte" quite often. */
+ if (has_mbyte)
+ return spell_edit_score_limit_w(slang, badword, goodword, limit);
+
+ /*
+ * The idea is to go from start to end over the words. So long as
+ * characters are equal just continue, this always gives the lowest score.
+ * When there is a difference try several alternatives. Each alternative
+ * increases "score" for the edit distance. Some of the alternatives are
+ * pushed unto a stack and tried later, some are tried right away. At the
+ * end of the word the score for one alternative is known. The lowest
+ * possible score is stored in "minscore".
+ */
+ stackidx = 0;
+ bi = 0;
+ gi = 0;
+ score = 0;
+ minscore = limit + 1;
+
+ for (;; ) {
+ /* Skip over an equal part, score remains the same. */
+ for (;; ) {
+ bc = badword[bi];
+ gc = goodword[gi];
+ if (bc != gc) /* stop at a char that's different */
+ break;
+ if (bc == NUL) { /* both words end */
+ if (score < minscore)
+ minscore = score;
+ goto pop; /* do next alternative */
+ }
+ ++bi;
+ ++gi;
+ }
+
+ if (gc == NUL) { /* goodword ends, delete badword chars */
+ do {
+ if ((score += SCORE_DEL) >= minscore)
+ goto pop; /* do next alternative */
+ } while (badword[++bi] != NUL);
+ minscore = score;
+ } else if (bc == NUL) { /* badword ends, insert badword chars */
+ do {
+ if ((score += SCORE_INS) >= minscore)
+ goto pop; /* do next alternative */
+ } while (goodword[++gi] != NUL);
+ minscore = score;
+ } else { /* both words continue */
+ /* If not close to the limit, perform a change. Only try changes
+ * that may lead to a lower score than "minscore".
+ * round 0: try deleting a char from badword
+ * round 1: try inserting a char in badword */
+ for (round = 0; round <= 1; ++round) {
+ score_off = score + (round == 0 ? SCORE_DEL : SCORE_INS);
+ if (score_off < minscore) {
+ if (score_off + SCORE_EDIT_MIN >= minscore) {
+ /* Near the limit, rest of the words must match. We
+ * can check that right now, no need to push an item
+ * onto the stack. */
+ bi2 = bi + 1 - round;
+ gi2 = gi + round;
+ while (goodword[gi2] == badword[bi2]) {
+ if (goodword[gi2] == NUL) {
+ minscore = score_off;
+ break;
+ }
+ ++bi2;
+ ++gi2;
+ }
+ } else {
+ /* try deleting/inserting a character later */
+ stack[stackidx].badi = bi + 1 - round;
+ stack[stackidx].goodi = gi + round;
+ stack[stackidx].score = score_off;
+ ++stackidx;
+ }
+ }
+ }
+
+ if (score + SCORE_SWAP < minscore) {
+ /* If swapping two characters makes a match then the
+ * substitution is more expensive, thus there is no need to
+ * try both. */
+ if (gc == badword[bi + 1] && bc == goodword[gi + 1]) {
+ /* Swap two characters, that is: skip them. */
+ gi += 2;
+ bi += 2;
+ score += SCORE_SWAP;
+ continue;
+ }
+ }
+
+ /* Substitute one character for another which is the same
+ * thing as deleting a character from both goodword and badword.
+ * Use a better score when there is only a case difference. */
+ if (SPELL_TOFOLD(bc) == SPELL_TOFOLD(gc))
+ score += SCORE_ICASE;
+ else {
+ /* For a similar character use SCORE_SIMILAR. */
+ if (slang != NULL
+ && slang->sl_has_map
+ && similar_chars(slang, gc, bc))
+ score += SCORE_SIMILAR;
+ else
+ score += SCORE_SUBST;
+ }
+
+ if (score < minscore) {
+ /* Do the substitution. */
+ ++gi;
+ ++bi;
+ continue;
+ }
+ }
+pop:
+ /*
+ * Get here to try the next alternative, pop it from the stack.
+ */
+ if (stackidx == 0) /* stack is empty, finished */
+ break;
+
+ /* pop an item from the stack */
+ --stackidx;
+ gi = stack[stackidx].goodi;
+ bi = stack[stackidx].badi;
+ score = stack[stackidx].score;
+ }
+
+ /* When the score goes over "limit" it may actually be much higher.
+ * Return a very large number to avoid going below the limit when giving a
+ * bonus. */
+ if (minscore > limit)
+ return SCORE_MAXMAX;
+ return minscore;
+}
+
+/*
+ * Multi-byte version of spell_edit_score_limit().
+ * Keep it in sync with the above!
+ */
+static int spell_edit_score_limit_w(slang, badword, goodword, limit)
+slang_T *slang;
+char_u *badword;
+char_u *goodword;
+int limit;
+{
+ limitscore_T stack[10]; /* allow for over 3 * 2 edits */
+ int stackidx;
+ int bi, gi;
+ int bi2, gi2;
+ int bc, gc;
+ int score;
+ 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; )
+ wbadword[bi++] = mb_cptr2char_adv(&p);
+ wbadword[bi++] = 0;
+ gi = 0;
+ for (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
+ * characters are equal just continue, this always gives the lowest score.
+ * When there is a difference try several alternatives. Each alternative
+ * increases "score" for the edit distance. Some of the alternatives are
+ * pushed unto a stack and tried later, some are tried right away. At the
+ * end of the word the score for one alternative is known. The lowest
+ * possible score is stored in "minscore".
+ */
+ stackidx = 0;
+ bi = 0;
+ gi = 0;
+ score = 0;
+ minscore = limit + 1;
+
+ for (;; ) {
+ /* Skip over an equal part, score remains the same. */
+ for (;; ) {
+ bc = wbadword[bi];
+ gc = wgoodword[gi];
+
+ if (bc != gc) /* stop at a char that's different */
+ break;
+ if (bc == NUL) { /* both words end */
+ if (score < minscore)
+ minscore = score;
+ goto pop; /* do next alternative */
+ }
+ ++bi;
+ ++gi;
+ }
+
+ if (gc == NUL) { /* goodword ends, delete badword chars */
+ do {
+ if ((score += SCORE_DEL) >= minscore)
+ goto pop; /* do next alternative */
+ } while (wbadword[++bi] != NUL);
+ minscore = score;
+ } else if (bc == NUL) { /* badword ends, insert badword chars */
+ do {
+ if ((score += SCORE_INS) >= minscore)
+ goto pop; /* do next alternative */
+ } while (wgoodword[++gi] != NUL);
+ minscore = score;
+ } else { /* both words continue */
+ /* If not close to the limit, perform a change. Only try changes
+ * that may lead to a lower score than "minscore".
+ * round 0: try deleting a char from badword
+ * round 1: try inserting a char in badword */
+ for (round = 0; round <= 1; ++round) {
+ score_off = score + (round == 0 ? SCORE_DEL : SCORE_INS);
+ if (score_off < minscore) {
+ if (score_off + SCORE_EDIT_MIN >= minscore) {
+ /* Near the limit, rest of the words must match. We
+ * can check that right now, no need to push an item
+ * onto the stack. */
+ bi2 = bi + 1 - round;
+ gi2 = gi + round;
+ while (wgoodword[gi2] == wbadword[bi2]) {
+ if (wgoodword[gi2] == NUL) {
+ minscore = score_off;
+ break;
+ }
+ ++bi2;
+ ++gi2;
+ }
+ } else {
+ /* try deleting a character from badword later */
+ stack[stackidx].badi = bi + 1 - round;
+ stack[stackidx].goodi = gi + round;
+ stack[stackidx].score = score_off;
+ ++stackidx;
+ }
+ }
+ }
+
+ if (score + SCORE_SWAP < minscore) {
+ /* If swapping two characters makes a match then the
+ * substitution is more expensive, thus there is no need to
+ * try both. */
+ if (gc == wbadword[bi + 1] && bc == wgoodword[gi + 1]) {
+ /* Swap two characters, that is: skip them. */
+ gi += 2;
+ bi += 2;
+ score += SCORE_SWAP;
+ continue;
+ }
+ }
+
+ /* Substitute one character for another which is the same
+ * thing as deleting a character from both goodword and badword.
+ * Use a better score when there is only a case difference. */
+ if (SPELL_TOFOLD(bc) == SPELL_TOFOLD(gc))
+ score += SCORE_ICASE;
+ else {
+ /* For a similar character use SCORE_SIMILAR. */
+ if (slang != NULL
+ && slang->sl_has_map
+ && similar_chars(slang, gc, bc))
+ score += SCORE_SIMILAR;
+ else
+ score += SCORE_SUBST;
+ }
+
+ if (score < minscore) {
+ /* Do the substitution. */
+ ++gi;
+ ++bi;
+ continue;
+ }
+ }
+pop:
+ /*
+ * Get here to try the next alternative, pop it from the stack.
+ */
+ if (stackidx == 0) /* stack is empty, finished */
+ break;
+
+ /* pop an item from the stack */
+ --stackidx;
+ gi = stack[stackidx].goodi;
+ bi = stack[stackidx].badi;
+ score = stack[stackidx].score;
+ }
+
+ /* When the score goes over "limit" it may actually be much higher.
+ * Return a very large number to avoid going below the limit when giving a
+ * bonus. */
+ if (minscore > limit)
+ return SCORE_MAXMAX;
+ return minscore;
+}
+
+/*
+ * ":spellinfo"
+ */
+void ex_spellinfo(eap)
+exarg_T *eap UNUSED;
+{
+ int lpi;
+ langp_T *lp;
+ char_u *p;
+
+ if (no_spell_checking(curwin))
+ return;
+
+ msg_start();
+ for (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);
+ msg_putchar('\n');
+ p = lp->lp_slang->sl_info;
+ if (p != NULL) {
+ msg_puts(p);
+ msg_putchar('\n');
+ }
+ }
+ msg_end();
+}
+
+#define DUMPFLAG_KEEPCASE 1 /* round 2: keep-case tree */
+#define DUMPFLAG_COUNT 2 /* include word count */
+#define DUMPFLAG_ICASE 4 /* ignore case when finding matches */
+#define DUMPFLAG_ONECAP 8 /* pattern starts with capital */
+#define DUMPFLAG_ALLCAP 16 /* pattern is all capitals */
+
+/*
+ * ":spelldump"
+ */
+void ex_spelldump(eap)
+exarg_T *eap;
+{
+ char_u *spl;
+ long dummy;
+
+ if (no_spell_checking(curwin))
+ return;
+ get_option_value((char_u*)"spl", &dummy, &spl, OPT_LOCAL);
+
+ /* Create a new empty buffer in a new window. */
+ do_cmdline_cmd((char_u *)"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);
+ vim_free(spl);
+
+ if (!bufempty() || !buf_valid(curbuf))
+ return;
+
+ spell_dump_compl(NULL, 0, NULL, eap->forceit ? DUMPFLAG_COUNT : 0);
+
+ /* Delete the empty line that we started with. */
+ if (curbuf->b_ml.ml_line_count > 1)
+ ml_delete(curbuf->b_ml.ml_line_count, FALSE);
+
+ redraw_later(NOT_VALID);
+}
+
+/*
+ * Go through all possible words and:
+ * 1. When "pat" is NULL: dump a list of all words in the current buffer.
+ * "ic" and "dir" are not used.
+ * 2. When "pat" is not NULL: add matching words to insert mode completion.
+ */
+void spell_dump_compl(pat, ic, dir, dumpflags_arg)
+char_u *pat; /* leading part of the word */
+int ic; /* ignore case */
+int *dir; /* direction for adding matches */
+int dumpflags_arg; /* DUMPFLAG_* */
+{
+ langp_T *lp;
+ slang_T *slang;
+ idx_T arridx[MAXWLEN];
+ int curi[MAXWLEN];
+ char_u word[MAXWLEN];
+ int c;
+ char_u *byts;
+ idx_T *idxs;
+ linenr_T lnum = 0;
+ int round;
+ int depth;
+ int n;
+ int flags;
+ char_u *region_names = NULL; /* region names being used */
+ int do_region = TRUE; /* dump region names and numbers */
+ char_u *p;
+ int lpi;
+ int dumpflags = dumpflags_arg;
+ int patlen;
+
+ /* When ignoring case or when the pattern starts with capital pass this on
+ * to dump_word(). */
+ if (pat != NULL) {
+ if (ic)
+ dumpflags |= DUMPFLAG_ICASE;
+ else {
+ n = captype(pat, NULL);
+ if (n == WF_ONECAP)
+ dumpflags |= DUMPFLAG_ONECAP;
+ else if (n == WF_ALLCAP
+ && (int)STRLEN(pat) > mb_ptr2len(pat)
+ )
+ dumpflags |= DUMPFLAG_ALLCAP;
+ }
+ }
+
+ /* Find out if we can support regions: All languages must support the same
+ * regions or none at all. */
+ for (lpi = 0; lpi < curwin->w_s->b_langp.ga_len; ++lpi) {
+ lp = LANGP_ENTRY(curwin->w_s->b_langp, lpi);
+ p = lp->lp_slang->sl_regions;
+ if (p[0] != 0) {
+ if (region_names == NULL) /* first language with regions */
+ region_names = p;
+ else if (STRCMP(region_names, p) != 0) {
+ do_region = FALSE; /* region names are different */
+ break;
+ }
+ }
+ }
+
+ if (do_region && region_names != NULL) {
+ if (pat == NULL) {
+ vim_snprintf((char *)IObuff, IOSIZE, "/regions=%s", region_names);
+ ml_append(lnum++, IObuff, (colnr_T)0, FALSE);
+ }
+ } else
+ do_region = FALSE;
+
+ /*
+ * Loop over all files loaded for the entries in 'spelllang'.
+ */
+ for (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_fbyts == NULL) /* reloading failed */
+ continue;
+
+ if (pat == NULL) {
+ vim_snprintf((char *)IObuff, IOSIZE, "# file: %s", slang->sl_fname);
+ ml_append(lnum++, IObuff, (colnr_T)0, FALSE);
+ }
+
+ /* When matching with a pattern and there are no prefixes only use
+ * parts of the tree that match "pat". */
+ if (pat != NULL && slang->sl_pbyts == NULL)
+ patlen = (int)STRLEN(pat);
+ else
+ patlen = -1;
+
+ /* round 1: case-folded tree
+ * round 2: keep-case tree */
+ for (round = 1; round <= 2; ++round) {
+ if (round == 1) {
+ dumpflags &= ~DUMPFLAG_KEEPCASE;
+ byts = slang->sl_fbyts;
+ idxs = slang->sl_fidxs;
+ } else {
+ dumpflags |= DUMPFLAG_KEEPCASE;
+ byts = slang->sl_kbyts;
+ idxs = slang->sl_kidxs;
+ }
+ if (byts == NULL)
+ continue; /* array is empty */
+
+ depth = 0;
+ arridx[0] = 0;
+ curi[0] = 1;
+ while (depth >= 0 && !got_int
+ && (pat == NULL || !compl_interrupted)) {
+ if (curi[depth] > byts[arridx[depth]]) {
+ /* Done all bytes at this node, go up one level. */
+ --depth;
+ line_breakcheck();
+ ins_compl_check_keys(50);
+ } else {
+ /* Do one more byte at this node. */
+ n = arridx[depth] + curi[depth];
+ ++curi[depth];
+ c = byts[n];
+ if (c == 0) {
+ /* End of word, deal with the word.
+ * Don't use keep-case words in the fold-case tree,
+ * they will appear in the keep-case tree.
+ * Only use the word when the region matches. */
+ flags = (int)idxs[n];
+ if ((round == 2 || (flags & WF_KEEPCAP) == 0)
+ && (flags & WF_NEEDCOMP) == 0
+ && (do_region
+ || (flags & WF_REGION) == 0
+ || (((unsigned)flags >> 16)
+ & lp->lp_region) != 0)) {
+ word[depth] = NUL;
+ if (!do_region)
+ flags &= ~WF_REGION;
+
+ /* Dump the basic word if there is no prefix or
+ * when it's the first one. */
+ c = (unsigned)flags >> 24;
+ if (c == 0 || curi[depth] == 2) {
+ dump_word(slang, word, pat, dir,
+ dumpflags, flags, lnum);
+ if (pat == NULL)
+ ++lnum;
+ }
+
+ /* Apply the prefix, if there is one. */
+ if (c != 0)
+ lnum = dump_prefixes(slang, word, pat, dir,
+ dumpflags, flags, lnum);
+ }
+ } else {
+ /* Normal char, go one level deeper. */
+ word[depth++] = c;
+ arridx[depth] = idxs[n];
+ curi[depth] = 1;
+
+ /* Check if this characters matches with the pattern.
+ * If not skip the whole tree below it.
+ * Always ignore case here, dump_word() will check
+ * proper case later. This isn't exactly right when
+ * length changes for multi-byte characters with
+ * ignore case... */
+ if (depth <= patlen
+ && MB_STRNICMP(word, pat, depth) != 0)
+ --depth;
+ }
+ }
+ }
+ }
+ }
+}
+
+/*
+ * Dump one word: apply case modifications and append a line to the buffer.
+ * When "lnum" is zero add insert mode completion.
+ */
+static void dump_word(slang, word, pat, dir, dumpflags, wordflags, lnum)
+slang_T *slang;
+char_u *word;
+char_u *pat;
+int *dir;
+int dumpflags;
+int wordflags;
+linenr_T lnum;
+{
+ int keepcap = FALSE;
+ char_u *p;
+ char_u *tw;
+ char_u cword[MAXWLEN];
+ char_u badword[MAXWLEN + 10];
+ int i;
+ int flags = wordflags;
+
+ if (dumpflags & DUMPFLAG_ONECAP)
+ flags |= WF_ONECAP;
+ if (dumpflags & DUMPFLAG_ALLCAP)
+ flags |= WF_ALLCAP;
+
+ if ((dumpflags & DUMPFLAG_KEEPCASE) == 0 && (flags & WF_CAPMASK) != 0) {
+ /* Need to fix case according to "flags". */
+ make_case_word(word, cword, flags);
+ p = cword;
+ } else {
+ p = word;
+ if ((dumpflags & DUMPFLAG_KEEPCASE)
+ && ((captype(word, NULL) & WF_KEEPCAP) == 0
+ || (flags & WF_FIXCAP) != 0))
+ keepcap = TRUE;
+ }
+ tw = p;
+
+ if (pat == NULL) {
+ /* Add flags and regions after a slash. */
+ if ((flags & (WF_BANNED | WF_RARE | WF_REGION)) || keepcap) {
+ STRCPY(badword, p);
+ STRCAT(badword, "/");
+ if (keepcap)
+ STRCAT(badword, "=");
+ if (flags & WF_BANNED)
+ STRCAT(badword, "!");
+ 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);
+ p = badword;
+ }
+
+ if (dumpflags & DUMPFLAG_COUNT) {
+ hashitem_T *hi;
+
+ /* Include the word count for ":spelldump!". */
+ hi = hash_find(&slang->sl_wordcount, tw);
+ if (!HASHITEM_EMPTY(hi)) {
+ vim_snprintf((char *)IObuff, IOSIZE, "%s\t%d",
+ tw, HI2WC(hi)->wc_count);
+ p = IObuff;
+ }
+ }
+
+ ml_append(lnum, p, (colnr_T)0, FALSE);
+ } else if (((dumpflags & DUMPFLAG_ICASE)
+ ? MB_STRNICMP(p, pat, STRLEN(pat)) == 0
+ : STRNCMP(p, pat, STRLEN(pat)) == 0)
+ && ins_compl_add_infercase(p, (int)STRLEN(p),
+ p_ic, NULL, *dir, 0) == OK)
+ /* if dir was BACKWARD then honor it just once */
+ *dir = FORWARD;
+}
+
+/*
+ * For ":spelldump": Find matching prefixes for "word". Prepend each to
+ * "word" and append a line to the buffer.
+ * When "lnum" is zero add insert mode completion.
+ * Return the updated line number.
+ */
+static linenr_T dump_prefixes(slang, word, pat, dir, dumpflags, flags,
+ startlnum)
+slang_T *slang;
+char_u *word; /* case-folded word */
+char_u *pat;
+int *dir;
+int dumpflags;
+int flags; /* flags with prefix ID */
+linenr_T startlnum;
+{
+ idx_T arridx[MAXWLEN];
+ int curi[MAXWLEN];
+ char_u prefix[MAXWLEN];
+ char_u word_up[MAXWLEN];
+ int has_word_up = FALSE;
+ int c;
+ char_u *byts;
+ idx_T *idxs;
+ linenr_T lnum = startlnum;
+ int depth;
+ int n;
+ int len;
+ int i;
+
+ /* If the word starts with a lower-case letter make the word with an
+ * upper-case letter in word_up[]. */
+ c = PTR2CHAR(word);
+ if (SPELL_TOUPPER(c) != c) {
+ onecap_copy(word, word_up, TRUE);
+ has_word_up = TRUE;
+ }
+
+ byts = slang->sl_pbyts;
+ idxs = slang->sl_pidxs;
+ if (byts != NULL) { /* array not is empty */
+ /*
+ * Loop over all prefixes, building them byte-by-byte in prefix[].
+ * When at the end of a prefix check that it supports "flags".
+ */
+ depth = 0;
+ arridx[0] = 0;
+ curi[0] = 1;
+ while (depth >= 0 && !got_int) {
+ n = arridx[depth];
+ len = byts[n];
+ if (curi[depth] > len) {
+ /* Done all bytes at this node, go up one level. */
+ --depth;
+ line_breakcheck();
+ } else {
+ /* Do one more byte at this node. */
+ n += curi[depth];
+ ++curi[depth];
+ c = byts[n];
+ if (c == 0) {
+ /* End of prefix, find out how many IDs there are. */
+ for (i = 1; i < len; ++i)
+ if (byts[n + i] != 0)
+ break;
+ curi[depth] += i - 1;
+
+ c = valid_word_prefix(i, n, flags, word, slang, FALSE);
+ if (c != 0) {
+ vim_strncpy(prefix + depth, word, MAXWLEN - depth - 1);
+ dump_word(slang, prefix, pat, dir, dumpflags,
+ (c & WF_RAREPFX) ? (flags | WF_RARE)
+ : flags, lnum);
+ if (lnum != 0)
+ ++lnum;
+ }
+
+ /* Check for prefix that matches the word when the
+ * first letter is upper-case, but only if the prefix has
+ * a condition. */
+ if (has_word_up) {
+ c = valid_word_prefix(i, n, flags, word_up, slang,
+ TRUE);
+ if (c != 0) {
+ vim_strncpy(prefix + depth, word_up,
+ MAXWLEN - depth - 1);
+ dump_word(slang, prefix, pat, dir, dumpflags,
+ (c & WF_RAREPFX) ? (flags | WF_RARE)
+ : flags, lnum);
+ if (lnum != 0)
+ ++lnum;
+ }
+ }
+ } else {
+ /* Normal char, go one level deeper. */
+ prefix[depth++] = c;
+ arridx[depth] = idxs[n];
+ curi[depth] = 1;
+ }
+ }
+ }
+ }
+
+ return lnum;
+}
+
+/*
+ * Move "p" to the end of word "start".
+ * Uses the spell-checking word characters.
+ */
+char_u * spell_to_word_end(start, win)
+char_u *start;
+win_T *win;
+{
+ char_u *p = start;
+
+ while (*p != NUL && spell_iswordp(p, win))
+ mb_ptr_adv(p);
+ return p;
+}
+
+/*
+ * For Insert mode completion CTRL-X s:
+ * Find start of the word in front of column "startcol".
+ * We don't check if it is badly spelled, with completion we can only change
+ * the word in front of the cursor.
+ * Returns the column number of the word.
+ */
+int spell_word_start(startcol)
+int startcol;
+{
+ char_u *line;
+ char_u *p;
+ int col = 0;
+
+ if (no_spell_checking(curwin))
+ return startcol;
+
+ /* Find a word character before "startcol". */
+ line = ml_get_curline();
+ for (p = line + startcol; p > line; ) {
+ 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))
+ break;
+ col = 0;
+ }
+
+ return col;
+}
+
+/*
+ * Need to check for 'spellcapcheck' now, the word is removed before
+ * expand_spelling() is called. Therefore the ugly global variable.
+ */
+static int spell_expand_need_cap;
+
+void spell_expand_check_cap(col)
+colnr_T col;
+{
+ spell_expand_need_cap = check_need_cap(curwin->w_cursor.lnum, col);
+}
+
+/*
+ * Get list of spelling suggestions.
+ * Used for Insert mode completion CTRL-X ?.
+ * Returns the number of matches. The matches are in "matchp[]", array of
+ * allocated strings.
+ */
+int expand_spelling(lnum, pat, matchp)
+linenr_T lnum UNUSED;
+char_u *pat;
+char_u ***matchp;
+{
+ garray_T ga;
+
+ spell_suggest_list(&ga, pat, 100, spell_expand_need_cap, TRUE);
+ *matchp = ga.ga_data;
+ return ga.ga_len;
+}
+
diff --git a/src/structs.h b/src/structs.h
new file mode 100644
index 0000000000..c29848a9af
--- /dev/null
+++ b/src/structs.h
@@ -0,0 +1,2047 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * 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.
+ */
+
+/*
+ * This file contains various definitions of structures that are used by Vim
+ */
+
+/*
+ * There is something wrong in the SAS compiler that makes typedefs not
+ * valid in include files. Has been fixed in version 6.58.
+ */
+
+/*
+ * position in file or buffer
+ */
+typedef struct {
+ linenr_T lnum; /* line number */
+ colnr_T col; /* column number */
+ colnr_T coladd;
+} pos_T;
+
+# define INIT_POS_T(l, c, ca) {l, c, ca}
+
+/*
+ * Same, but without coladd.
+ */
+typedef struct {
+ linenr_T lnum; /* line number */
+ colnr_T col; /* column number */
+} lpos_T;
+
+/*
+ * Structure used for growing arrays.
+ * This is used to store information that only grows, is deleted all at
+ * once, and needs to be accessed by index. See ga_clear() and ga_grow().
+ */
+typedef struct growarray {
+ int ga_len; /* current number of items used */
+ int ga_maxlen; /* maximum number of items possible */
+ int ga_itemsize; /* sizeof(item) */
+ int ga_growsize; /* number of items to grow each time */
+ void *ga_data; /* pointer to the first item */
+} garray_T;
+
+#define GA_EMPTY {0, 0, 0, 0, NULL}
+
+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 struct file_buffer buf_T; /* forward declaration */
+
+/*
+ * This is here because regexp.h needs pos_T and below regprog_T is used.
+ */
+#include "regexp.h"
+
+/*
+ * This is here because gui.h needs the pos_T and win_T, and win_T needs gui.h
+ * for scrollbar_T.
+ */
+# define guicolor_T int /* avoid error in prototypes */
+
+/*
+ * marks: positions in a file
+ * (a normal mark is a lnum/col pair, the same as a file position)
+ */
+
+/* (Note: for EBCDIC there are more than 26, because there are gaps in the
+ * alphabet coding. To minimize changes to the code, I decided to just
+ * increase the number of possible marks. */
+#define NMARKS ('z' - 'a' + 1) /* max. # of named marks */
+#define JUMPLISTSIZE 100 /* max. # of marks in jump list */
+#define TAGSTACKSIZE 20 /* max. # of tags in tag stack */
+
+typedef struct filemark {
+ pos_T mark; /* cursor position */
+ int fnum; /* file number */
+} fmark_T;
+
+/* Xtended file mark: also has a file name */
+typedef struct xfilemark {
+ fmark_T fmark;
+ char_u *fname; /* file name, used when fnum == 0 */
+} xfmark_T;
+
+/*
+ * The taggy struct is used to store the information about a :tag command.
+ */
+typedef struct taggy {
+ char_u *tagname; /* tag name */
+ fmark_T fmark; /* cursor position BEFORE ":tag" */
+ int cur_match; /* match number */
+ int cur_fnum; /* buffer number used for cur_match */
+} taggy_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.
+ * Also used in wininfo_T.
+ */
+typedef struct {
+ int wo_arab;
+# define w_p_arab w_onebuf_opt.wo_arab /* 'arabic' */
+ int wo_diff;
+# define w_p_diff w_onebuf_opt.wo_diff /* 'diff' */
+ long wo_fdc;
+# define w_p_fdc w_onebuf_opt.wo_fdc /* 'foldcolumn' */
+ int wo_fdc_save;
+# define w_p_fdc_save w_onebuf_opt.wo_fdc_save /* 'foldenable' saved for diff mode */
+ int wo_fen;
+# define w_p_fen w_onebuf_opt.wo_fen /* 'foldenable' */
+ int wo_fen_save;
+# define w_p_fen_save w_onebuf_opt.wo_fen_save /* 'foldenable' saved for diff mode */
+ char_u *wo_fdi;
+# define w_p_fdi w_onebuf_opt.wo_fdi /* 'foldignore' */
+ long wo_fdl;
+# define w_p_fdl w_onebuf_opt.wo_fdl /* 'foldlevel' */
+ int wo_fdl_save;
+# define w_p_fdl_save w_onebuf_opt.wo_fdl_save /* 'foldlevel' state saved for diff mode */
+ char_u *wo_fdm;
+# define w_p_fdm w_onebuf_opt.wo_fdm /* 'foldmethod' */
+ char_u *wo_fdm_save;
+# define w_p_fdm_save w_onebuf_opt.wo_fdm_save /* 'fdm' saved for diff mode */
+ long wo_fml;
+# define w_p_fml w_onebuf_opt.wo_fml /* 'foldminlines' */
+ long wo_fdn;
+# define w_p_fdn w_onebuf_opt.wo_fdn /* 'foldnestmax' */
+ char_u *wo_fde;
+# define w_p_fde w_onebuf_opt.wo_fde /* 'foldexpr' */
+ char_u *wo_fdt;
+# define w_p_fdt w_onebuf_opt.wo_fdt /* 'foldtext' */
+ char_u *wo_fmr;
+# define w_p_fmr w_onebuf_opt.wo_fmr /* 'foldmarker' */
+ int wo_lbr;
+# define w_p_lbr w_onebuf_opt.wo_lbr /* 'linebreak' */
+ int wo_list;
+#define w_p_list w_onebuf_opt.wo_list /* 'list' */
+ int wo_nu;
+#define w_p_nu w_onebuf_opt.wo_nu /* 'number' */
+ int wo_rnu;
+#define w_p_rnu w_onebuf_opt.wo_rnu /* 'relativenumber' */
+ long wo_nuw;
+# define w_p_nuw w_onebuf_opt.wo_nuw /* 'numberwidth' */
+ int wo_wfh;
+# define w_p_wfh w_onebuf_opt.wo_wfh /* 'winfixheight' */
+ int wo_wfw;
+# define w_p_wfw w_onebuf_opt.wo_wfw /* 'winfixwidth' */
+ int wo_pvw;
+# define w_p_pvw w_onebuf_opt.wo_pvw /* 'previewwindow' */
+ int wo_rl;
+# define w_p_rl w_onebuf_opt.wo_rl /* 'rightleft' */
+ char_u *wo_rlc;
+# define w_p_rlc w_onebuf_opt.wo_rlc /* 'rightleftcmd' */
+ long wo_scr;
+#define w_p_scr w_onebuf_opt.wo_scr /* 'scroll' */
+ int wo_spell;
+# define w_p_spell w_onebuf_opt.wo_spell /* 'spell' */
+ int wo_cuc;
+# define w_p_cuc w_onebuf_opt.wo_cuc /* 'cursorcolumn' */
+ int wo_cul;
+# define w_p_cul w_onebuf_opt.wo_cul /* 'cursorline' */
+ char_u *wo_cc;
+# define w_p_cc w_onebuf_opt.wo_cc /* 'colorcolumn' */
+ char_u *wo_stl;
+#define w_p_stl w_onebuf_opt.wo_stl /* 'statusline' */
+ int wo_scb;
+# define w_p_scb w_onebuf_opt.wo_scb /* 'scrollbind' */
+ int wo_diff_saved; /* options were saved for starting diff mode */
+# define w_p_diff_saved w_onebuf_opt.wo_diff_saved
+ int wo_scb_save; /* 'scrollbind' saved for diff mode*/
+# define w_p_scb_save w_onebuf_opt.wo_scb_save
+ int wo_wrap;
+#define w_p_wrap w_onebuf_opt.wo_wrap /* 'wrap' */
+ int wo_wrap_save; /* 'wrap' state saved for diff mode*/
+# define w_p_wrap_save w_onebuf_opt.wo_wrap_save
+ char_u *wo_cocu; /* 'concealcursor' */
+# define w_p_cocu w_onebuf_opt.wo_cocu
+ long wo_cole; /* 'conceallevel' */
+# define w_p_cole w_onebuf_opt.wo_cole
+ int wo_crb;
+# 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
+
+ int wo_scriptID[WV_COUNT]; /* SIDs for window-local options */
+# define w_p_scriptID w_onebuf_opt.wo_scriptID
+} winopt_T;
+
+/*
+ * Window info stored with a buffer.
+ *
+ * Two types of info are kept for a buffer which are associated with a
+ * specific window:
+ * 1. Each window can have a different line number associated with a buffer.
+ * 2. The window-local options for a buffer work in a similar way.
+ * The window-info is kept in a list at b_wininfo. It is kept in
+ * most-recently-used order.
+ */
+struct wininfo_S {
+ wininfo_T *wi_next; /* next entry or NULL for last entry */
+ wininfo_T *wi_prev; /* previous entry or NULL for first entry */
+ win_T *wi_win; /* pointer to window that did set wi_fpos */
+ pos_T wi_fpos; /* last cursor position in the file */
+ int wi_optset; /* TRUE when wi_opt has useful values */
+ winopt_T wi_opt; /* local window options */
+ int wi_fold_manual; /* copy of w_fold_manual */
+ garray_T wi_folds; /* clone of w_folds */
+};
+
+/*
+ * Info used to pass info about a fold from the fold-detection code to the
+ * code that displays the foldcolumn.
+ */
+typedef struct foldinfo {
+ int fi_level; /* level of the fold; when this is zero the
+ other fields are invalid */
+ int fi_lnum; /* line number where fold starts */
+ int fi_low_level; /* lowest fold level that starts in the same
+ line */
+} foldinfo_T;
+
+/* Structure to store info about the Visual area. */
+typedef struct {
+ pos_T vi_start; /* start pos of last VIsual */
+ pos_T vi_end; /* end position of last VIsual */
+ int vi_mode; /* VIsual_mode of last VIsual */
+ colnr_T vi_curswant; /* MAXCOL from w_curswant */
+} visualinfo_T;
+
+/*
+ * structures used for undo
+ */
+
+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 */
+ linenr_T ue_bot; /* number of line below undo block */
+ linenr_T ue_lcount; /* linecount when u_save called */
+ char_u **ue_array; /* array of lines in undo block */
+ long ue_size; /* number of lines in ue_array */
+#ifdef U_DEBUG
+ int ue_magic; /* magic number to check allocation */
+#endif
+};
+
+struct u_header {
+ /* The following have a pointer and a number. The number is used when
+ * reading the undo file in u_read_undo() */
+ union {
+ u_header_T *ptr; /* pointer to next undo header in list */
+ long seq;
+ } uh_next;
+ union {
+ u_header_T *ptr; /* pointer to previous header in list */
+ long seq;
+ } uh_prev;
+ union {
+ u_header_T *ptr; /* pointer to next header for alt. redo */
+ long seq;
+ } uh_alt_next;
+ union {
+ u_header_T *ptr; /* pointer to previous header for alt. redo */
+ long seq;
+ } uh_alt_prev;
+ long uh_seq; /* sequence number, higher == newer undo */
+ int uh_walk; /* used by undo_time() */
+ u_entry_T *uh_entry; /* pointer to first entry */
+ u_entry_T *uh_getbot_entry; /* pointer to where ue_bot must be set */
+ pos_T uh_cursor; /* cursor position before saving */
+ long uh_cursor_vcol;
+ int uh_flags; /* see below */
+ pos_T uh_namedm[NMARKS]; /* marks before undo/after redo */
+ visualinfo_T uh_visual; /* Visual areas before undo/after redo */
+ time_t uh_time; /* timestamp when the change was made */
+ long uh_save_nr; /* set when the file was saved after the
+ changes in this block */
+#ifdef U_DEBUG
+ int uh_magic; /* magic number to check allocation */
+#endif
+};
+
+/* values for uh_flags */
+#define UH_CHANGED 0x01 /* b_changed flag before undo/after redo */
+#define UH_EMPTYBUF 0x02 /* buffer was empty */
+
+/*
+ * structures used in undo.c
+ */
+#if SIZEOF_INT > 2
+# define ALIGN_LONG /* longword alignment and use filler byte */
+# define ALIGN_SIZE (sizeof(long))
+#else
+# define ALIGN_SIZE (sizeof(short))
+#endif
+
+#define ALIGN_MASK (ALIGN_SIZE - 1)
+
+typedef struct m_info minfo_T;
+
+/*
+ * structure used to link chunks in one of the free chunk lists.
+ */
+struct m_info {
+#ifdef ALIGN_LONG
+ long_u m_size; /* size of the chunk (including m_info) */
+#else
+ short_u m_size; /* size of the chunk (including m_info) */
+#endif
+ minfo_T *m_next; /* pointer to next free chunk in the list */
+};
+
+/*
+ * things used in memfile.c
+ */
+
+typedef struct block_hdr bhdr_T;
+typedef struct memfile memfile_T;
+typedef long blocknr_T;
+
+/*
+ * mf_hashtab_T is a chained hashtable with blocknr_T key and arbitrary
+ * structures as items. This is an intrusive data structure: we require
+ * that items begin with mf_hashitem_T which contains the key and linked
+ * list pointers. List of items in each bucket is doubly-linked.
+ */
+
+typedef struct mf_hashitem_S mf_hashitem_T;
+
+struct mf_hashitem_S {
+ mf_hashitem_T *mhi_next;
+ mf_hashitem_T *mhi_prev;
+ blocknr_T mhi_key;
+};
+
+#define MHT_INIT_SIZE 64
+
+typedef struct mf_hashtab_S {
+ long_u mht_mask; /* mask used for hash value (nr of items
+ * in array is "mht_mask" + 1) */
+ long_u mht_count; /* nr of items inserted into hashtable */
+ mf_hashitem_T **mht_buckets; /* points to mht_small_buckets or
+ *dynamically allocated array */
+ mf_hashitem_T *mht_small_buckets[MHT_INIT_SIZE]; /* initial buckets */
+ char mht_fixed; /* non-zero value forbids growth */
+} mf_hashtab_T;
+
+/*
+ * for each (previously) used block in the memfile there is one block header.
+ *
+ * The block may be linked in the used list OR in the free list.
+ * The used blocks are also kept in hash lists.
+ *
+ * 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
+ * the contents of the block in the file (if any) is irrelevant.
+ */
+
+struct block_hdr {
+ mf_hashitem_T bh_hashitem; /* header for hash table and key */
+#define bh_bnum bh_hashitem.mhi_key /* block number, part of bh_hashitem */
+
+ bhdr_T *bh_next; /* next block_hdr in free or used list */
+ bhdr_T *bh_prev; /* previous block_hdr in used list */
+ char_u *bh_data; /* pointer to memory (for used block) */
+ int bh_page_count; /* number of pages in this block */
+
+#define BH_DIRTY 1
+#define BH_LOCKED 2
+ char bh_flags; /* BH_DIRTY or BH_LOCKED */
+};
+
+/*
+ * when a block with a negative number is flushed to the file, it gets
+ * a positive number. Because the reference to the block is still the negative
+ * number, we remember the translation to the new positive number in the
+ * double linked trans lists. The structure is the same as the hash lists.
+ */
+typedef struct nr_trans NR_TRANS;
+
+struct nr_trans {
+ mf_hashitem_T nt_hashitem; /* header for hash table and key */
+#define nt_old_bnum nt_hashitem.mhi_key /* old, negative, number */
+
+ blocknr_T nt_new_bnum; /* new, positive, number */
+};
+
+/*
+ * structure used to store one block of the stuff/redo/recording buffers
+ */
+struct buffblock {
+ struct buffblock *b_next; /* pointer to next buffblock */
+ char_u b_str[1]; /* contents (actually longer) */
+};
+
+/*
+ * header used for the stuff buffer and the redo buffer
+ */
+struct buffheader {
+ struct buffblock bh_first; /* first (dummy) block of list */
+ struct buffblock *bh_curr; /* buffblock for appending */
+ int bh_index; /* index for reading */
+ int bh_space; /* space in bh_curr for appending */
+};
+
+/*
+ * 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 */
+#ifndef BACKSLASH_IN_FILENAME
+ 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 */
+
+/*
+ * 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.
+ */
+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 */
+ char_u *save_ei; /* saved value of 'eventignore' */
+} cmdmod_T;
+
+#define MF_SEED_LEN 8
+
+struct memfile {
+ char_u *mf_fname; /* name of the file */
+ char_u *mf_ffname; /* idem, full path */
+ int mf_fd; /* file descriptor */
+ bhdr_T *mf_free_first; /* first block_hdr in free list */
+ bhdr_T *mf_used_first; /* mru block_hdr in used list */
+ bhdr_T *mf_used_last; /* lru block_hdr 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*/
+ blocknr_T mf_blocknr_min; /* lowest negative block number - 1 */
+ blocknr_T mf_neg_count; /* number of negative blocks numbers */
+ blocknr_T mf_infile_count; /* number of pages in the file */
+ unsigned mf_page_size; /* number of bytes in a page */
+ int mf_dirty; /* TRUE if there are dirty blocks */
+ buf_T *mf_buffer; /* bufer this memfile is for */
+ char_u mf_seed[MF_SEED_LEN]; /* seed for encryption */
+
+ /* Values for key, method and seed used for reading data blocks when
+ * updating for a newly set key or method. Only when mf_old_key != NULL. */
+ char_u *mf_old_key;
+ int mf_old_cm;
+ char_u mf_old_seed[MF_SEED_LEN];
+};
+
+/*
+ * things used in memline.c
+ */
+/*
+ * When searching for a specific line, we remember what blocks in the tree
+ * are the branches leading to that block. This is stored in ml_stack. Each
+ * entry is a pointer to info in a block (may be data block or pointer block)
+ */
+typedef struct info_pointer {
+ blocknr_T ip_bnum; /* block number */
+ linenr_T ip_low; /* lowest lnum in this block */
+ linenr_T ip_high; /* highest lnum in this block */
+ int ip_index; /* index for block with current lnum */
+} infoptr_T; /* block/index pair */
+
+typedef struct ml_chunksize {
+ int mlcs_numlines;
+ long mlcs_totalsize;
+} chunksize_T;
+
+/* Flags when calling ml_updatechunk() */
+
+#define ML_CHNK_ADDLINE 1
+#define ML_CHNK_DELLINE 2
+#define ML_CHNK_UPDLINE 3
+
+/*
+ * the memline structure holds all the information about a memline
+ */
+typedef struct memline {
+ linenr_T ml_line_count; /* number of lines in the buffer */
+
+ memfile_T *ml_mfp; /* pointer to associated memfile */
+
+#define ML_EMPTY 1 /* empty buffer */
+#define ML_LINE_DIRTY 2 /* cached line was changed and allocated */
+#define ML_LOCKED_DIRTY 4 /* ml_locked was changed */
+#define ML_LOCKED_POS 8 /* ml_locked needs positive block number */
+ int ml_flags;
+
+ infoptr_T *ml_stack; /* stack of pointer blocks (array of IPTRs) */
+ int ml_stack_top; /* current top if ml_stack */
+ int ml_stack_size; /* total number of entries in ml_stack */
+
+ linenr_T ml_line_lnum; /* line number of cached line, 0 if not valid */
+ char_u *ml_line_ptr; /* pointer to cached line */
+
+ bhdr_T *ml_locked; /* block used by last ml_get */
+ linenr_T ml_locked_low; /* first line in ml_locked */
+ linenr_T ml_locked_high; /* last line in ml_locked */
+ int ml_locked_lineadd; /* number of lines inserted in ml_locked */
+ chunksize_T *ml_chunksize;
+ int ml_numchunks;
+ int ml_usedchunks;
+} memline_T;
+
+
+/*
+ * Argument list: Array of file names.
+ * Used for the global argument list and the argument lists local to a window.
+ */
+typedef struct arglist {
+ garray_T al_ga; /* growarray with the array of file names */
+ int al_refcount; /* number of windows using this arglist */
+} alist_T;
+
+/*
+ * For each argument remember the file name as it was given, and the buffer
+ * number that contains the expanded file name (required for when ":cd" is
+ * used.
+ */
+typedef struct argentry {
+ char_u *ae_fname; /* file name as specified */
+ int ae_fnum; /* buffer number with expanded file name */
+} aentry_T;
+
+# define ALIST(win) (win)->w_alist
+#define GARGLIST ((aentry_T *)global_alist.al_ga.ga_data)
+#define ARGLIST ((aentry_T *)ALIST(curwin)->al_ga.ga_data)
+#define WARGLIST(wp) ((aentry_T *)ALIST(wp)->al_ga.ga_data)
+#define AARGLIST(al) ((aentry_T *)((al)->al_ga.ga_data))
+#define GARGCOUNT (global_alist.al_ga.ga_len)
+#define ARGCOUNT (ALIST(curwin)->al_ga.ga_len)
+#define WARGCOUNT(wp) (ALIST(wp)->al_ga.ga_len)
+
+/*
+ * A list used for saving values of "emsg_silent". Used by ex_try() to save the
+ * value of "emsg_silent" if it was non-zero. When this is done, the CSF_SILENT
+ * flag below is set.
+ */
+
+typedef struct eslist_elem eslist_T;
+struct eslist_elem {
+ int saved_emsg_silent; /* saved value of "emsg_silent" */
+ eslist_T *next; /* next element on the list */
+};
+
+/*
+ * For conditional commands a stack is kept of nested conditionals.
+ * When cs_idx < 0, there is no conditional command.
+ */
+#define CSTACK_LEN 50
+
+struct condstack {
+ short 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 */
+ } 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 */
+};
+# define cs_rettv cs_pend.csp_rv
+# define cs_exception cs_pend.csp_ex
+
+/* There is no CSF_IF, the lack of CSF_WHILE, CSF_FOR and CSF_TRY means ":if"
+ * was used. */
+# define CSF_TRUE 0x0001 /* condition was TRUE */
+# define CSF_ACTIVE 0x0002 /* current state is active */
+# define CSF_ELSE 0x0004 /* ":else" has been passed */
+# define CSF_WHILE 0x0008 /* is a ":while" */
+# define CSF_FOR 0x0010 /* is a ":for" */
+
+# define CSF_TRY 0x0100 /* is a ":try" */
+# define CSF_FINALLY 0x0200 /* ":finally" has been passed */
+# define CSF_THROWN 0x0400 /* exception thrown to this try conditional */
+# define CSF_CAUGHT 0x0800 /* exception caught by this try conditional */
+# define CSF_SILENT 0x1000 /* "emsg_silent" reset by ":try" */
+/* Note that CSF_ELSE is only used when CSF_TRY and CSF_WHILE are unset
+ * (an ":if"), and CSF_SILENT is only used when CSF_TRY is set. */
+
+/*
+ * What's pending for being reactivated at the ":endtry" of this try
+ * conditional:
+ */
+# define CSTP_NONE 0 /* nothing pending in ":finally" clause */
+# define CSTP_ERROR 1 /* an error is pending */
+# define CSTP_INTERRUPT 2 /* an interrupt is pending */
+# define CSTP_THROW 4 /* a throw is pending */
+# define CSTP_BREAK 8 /* ":break" is pending */
+# define CSTP_CONTINUE 16 /* ":continue" is pending */
+# define CSTP_RETURN 24 /* ":return" is pending */
+# define CSTP_FINISH 32 /* ":finish" is pending */
+
+/*
+ * Flags for the cs_lflags item in struct condstack.
+ */
+# define CSL_HAD_LOOP 1 /* just found ":while" or ":for" */
+# define CSL_HAD_ENDLOOP 2 /* just found ":endwhile" or ":endfor" */
+# define CSL_HAD_CONT 4 /* just found ":continue" */
+# define CSL_HAD_FINA 8 /* just found ":finally" */
+
+/*
+ * A list of error messages that can be converted to an exception. "throw_msg"
+ * is only set in the first element of the list. Usually, it points to the
+ * original message stored in that element, but sometimes it points to a later
+ * message in the list. See cause_errthrow() below.
+ */
+struct msglist {
+ char_u *msg; /* original message */
+ char_u *throw_msg; /* msg to throw: usually original one */
+ struct msglist *next; /* next of several messages in a row */
+};
+
+/*
+ * 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 */
+};
+
+/*
+ * 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.
+ */
+typedef struct cleanup_stuff cleanup_T;
+struct cleanup_stuff {
+ int pending; /* error/interrupt/exception state */
+ except_T *exception; /* exception value */
+};
+
+/* 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 */
+};
+
+/*
+ * Each keyword has one keyentry, which is linked in a hash list.
+ */
+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) */
+ int flags;
+ int k_char; /* conceal substitute character */
+ char_u keyword[1]; /* actually longer */
+};
+
+/*
+ * Struct used to store one state of the state stack.
+ */
+typedef struct buf_state {
+ int bs_idx; /* index of pattern */
+ int bs_flags; /* flags for pattern */
+ int bs_seqnr; /* stores si_seqnr */
+ int bs_cchar; /* stores si_cchar */
+ reg_extmatch_T *bs_extmatch; /* external matches from start pattern */
+} bufstate_T;
+
+/*
+ * 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 */
+ union {
+ 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 */
+};
+
+/*
+ * Structure shared between syntax.c, screen.c and gui_x11.c.
+ */
+typedef struct attr_entry {
+ short ae_attr; /* HL_BOLD, etc. */
+ union {
+ struct {
+ char_u *start; /* start escape sequence */
+ char_u *stop; /* stop escape sequence */
+ } term;
+ struct {
+ /* These colors need to be > 8 bits to hold 256. */
+ short_u fg_color; /* foreground color number */
+ short_u bg_color; /* background color number */
+ } cterm;
+ } ae_u;
+} attrentry_T;
+
+#ifdef USE_ICONV
+# ifdef HAVE_ICONV_H
+# include <iconv.h>
+# else
+# include <errno.h>
+typedef void *iconv_t;
+# endif
+#endif
+
+/*
+ * Used for the typeahead buffer: typebuf.
+ */
+typedef struct {
+ char_u *tb_buf; /* buffer for typed characters */
+ char_u *tb_noremap; /* mapping flags for characters in tb_buf[] */
+ int tb_buflen; /* size of tb_buf[] */
+ int tb_off; /* current position in tb_buf[] */
+ int tb_len; /* number of valid bytes in tb_buf[] */
+ int tb_maplen; /* nr of mapped bytes in tb_buf[] */
+ int tb_silent; /* nr of silently mapped bytes in tb_buf[] */
+ int tb_no_abbr_cnt; /* nr of bytes without abbrev. in tb_buf[] */
+ int tb_change_cnt; /* nr of time tb_buf was changed; never zero */
+} typebuf_T;
+
+/* Struct to hold the saved typeahead for save_typeahead(). */
+typedef struct {
+ typebuf_T save_typebuf;
+ int typebuf_valid; /* TRUE when save_typebuf valid */
+ int old_char;
+ int old_mod_mask;
+ struct buffheader save_stuffbuff;
+#ifdef USE_INPUT_BUF
+ char_u *save_inputbuf;
+#endif
+} 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
+ int vc_fail; /* fail for invalid char, don't use '?' */
+} vimconv_T;
+
+/*
+ * Structure used for reading from the viminfo file.
+ */
+typedef struct {
+ char_u *vir_line; /* text of the current line */
+ FILE *vir_fd; /* file descriptor */
+ vimconv_T vir_conv; /* encoding conversion */
+} vir_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;
+struct mapblock {
+ mapblock_T *m_next; /* next mapblock in list */
+ char_u *m_keys; /* mapped from, lhs */
+ char_u *m_str; /* mapped to, rhs */
+ char_u *m_orig_str; /* rhs as entered by the user */
+ int m_keylen; /* strlen(m_keys) */
+ int m_mode; /* valid mode */
+ int m_noremap; /* if non-zero no re-mapping for m_str */
+ char m_silent; /* <silent> used, don't echo commands */
+ char m_nowait; /* <nowait> used */
+ char m_expr; /* <expr> used, m_str is an expression */
+ scid_T m_script_ID; /* ID of script where map was defined */
+};
+
+/*
+ * Used for highlighting in the status line.
+ */
+struct stl_hlrec {
+ char_u *start;
+ int userhl; /* 0: no HL, 1-9: User HL, < 0 for syn ID */
+};
+
+
+/*
+ * Syntax items - usually buffer-specific.
+ */
+
+/* Item for a hashtable. "hi_key" can be one of three values:
+ * NULL: Never been used
+ * HI_KEY_REMOVED: Entry was removed
+ * Otherwise: Used item, pointer to the actual key; this usually is
+ * inside the item, subtract an offset to locate the item.
+ * This reduces the size of hashitem by 1/3.
+ */
+typedef struct hashitem_S {
+ long_u hi_hash; /* cached hash number of hi_key */
+ char_u *hi_key;
+} hashitem_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 HASHITEM_EMPTY(hi) ((hi)->hi_key == NULL || (hi)->hi_key == \
+ &hash_removed)
+
+/* Initial size for a hashtable. Our items are relatively small and growing
+ * is expensive, thus use 16 as a start. Must be a power of 2. */
+#define HT_INIT_SIZE 16
+
+typedef struct hashtable_S {
+ long_u ht_mask; /* mask used for hash value (nr of items in
+ * array is "ht_mask" + 1) */
+ long_u ht_used; /* number of items used */
+ long_u ht_filled; /* number of items used + removed */
+ int ht_locked; /* counter for hash_lock() */
+ int ht_error; /* when set growing failed, can't add more
+ items before growing works */
+ hashitem_T *ht_array; /* points to the array, allocated when it's
+ not "ht_smallarray" */
+ hashitem_T ht_smallarray[HT_INIT_SIZE]; /* initial array */
+} hashtab_T;
+
+typedef long_u hash_T; /* Type for hi_hash */
+
+
+#if SIZEOF_INT <= 3 /* use long if int is smaller than 32 bits */
+typedef long varnumber_T;
+#else
+typedef int varnumber_T;
+#endif
+typedef double float_T;
+
+typedef struct listvar_S list_T;
+typedef struct dictvar_S dict_T;
+
+/*
+ * Structure to hold an internal variable without a name.
+ */
+typedef struct {
+ char v_type; /* see below: VAR_NUMBER, VAR_STRING, etc. */
+ char v_lock; /* see below: VAR_LOCKED, VAR_FIXED */
+ union {
+ varnumber_T v_number; /* number value */
+ float_T v_float; /* floating number value */
+ char_u *v_string; /* string value (can be NULL!) */
+ list_T *v_list; /* list value (can be NULL!) */
+ dict_T *v_dict; /* dict value (can be NULL!) */
+ } vval;
+} typval_T;
+
+/* Values for "v_type". */
+#define VAR_UNKNOWN 0
+#define VAR_NUMBER 1 /* "v_number" is used */
+#define VAR_STRING 2 /* "v_string" is used */
+#define VAR_FUNC 3 /* "v_string" is function name */
+#define VAR_LIST 4 /* "v_list" is used */
+#define VAR_DICT 5 /* "v_dict" is used */
+#define VAR_FLOAT 6 /* "v_float" is used */
+
+/* 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 */
+
+/* Values for "v_lock". */
+#define VAR_LOCKED 1 /* locked with lock(), can use unlock() */
+#define VAR_FIXED 2 /* locked forever */
+
+/*
+ * 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 variable, not allocated */
+#define DI_FLAGS_LOCK 8 /* "di_flags" value: locked variable */
+
+/*
+ * Structure to hold info about a Dictionary.
+ */
+struct dictvar_S {
+ char dv_lock; /* zero, VAR_LOCKED, VAR_FIXED */
+ char dv_scope; /* zero, VAR_SCOPE, VAR_DEF_SCOPE */
+ int dv_refcount; /* reference count */
+ int dv_copyID; /* ID used by deepcopy() */
+ hashtab_T dv_hashtab; /* hashtab that refers to the items */
+ dict_T *dv_copydict; /* copied dict used by deepcopy() */
+ dict_T *dv_used_next; /* next dict in used dicts list */
+ dict_T *dv_used_prev; /* previous dict in used dicts list */
+};
+
+/* values for b_syn_spell: what to do with toplevel text */
+#define SYNSPL_DEFAULT 0 /* spell check if @Spell not defined */
+#define SYNSPL_TOP 1 /* spell check toplevel text */
+#define SYNSPL_NOTOP 2 /* don't spell check toplevel text */
+
+/* avoid #ifdefs for when b_spell is not available */
+# define B_SPELL(buf) ((buf)->b_spell)
+
+typedef struct qf_info_S qf_info_T;
+
+/*
+ * Used for :syntime: timing of executing a syntax pattern.
+ */
+typedef struct {
+ proftime_T total; /* total time used */
+ proftime_T slowest; /* time of slowest call */
+ long count; /* nr of times used */
+ long match; /* nr of times matched */
+} syn_time_T;
+
+/*
+ * These are items normally related to a buffer. But when using ":ownsyntax"
+ * a window may have its own instance.
+ */
+typedef struct {
+ hashtab_T b_keywtab; /* syntax keywords hash table */
+ hashtab_T b_keywtab_ic; /* idem, ignore case */
+ int b_syn_error; /* TRUE when error occurred in HL */
+ int b_syn_ic; /* ignore case for :syn cmds */
+ int b_syn_spell; /* SYNSPL_ values */
+ garray_T b_syn_patterns; /* table for syntax patterns */
+ garray_T b_syn_clusters; /* table for syntax clusters */
+ int b_spell_cluster_id; /* @Spell cluster ID or 0 */
+ int b_nospell_cluster_id; /* @NoSpell cluster ID or 0 */
+ int b_syn_containedin; /* TRUE when there is an item with a
+ "containedin" argument */
+ int b_syn_sync_flags; /* flags about how to sync */
+ short b_syn_sync_id; /* group to sync on */
+ long b_syn_sync_minlines; /* minimal sync lines offset */
+ long b_syn_sync_maxlines; /* maximal sync lines offset */
+ long b_syn_sync_linebreaks; /* offset for multi-line pattern */
+ char_u *b_syn_linecont_pat; /* line continuation pattern */
+ regprog_T *b_syn_linecont_prog; /* line continuation program */
+ syn_time_T b_syn_linecont_time;
+ int b_syn_linecont_ic; /* ignore-case flag for above */
+ int b_syn_topgrp; /* for ":syntax include" */
+ int b_syn_conceal; /* auto-conceal for :syn cmds */
+ int b_syn_folditems; /* number of patterns with the HL_FOLD
+ flag set */
+ /*
+ * b_sst_array[] contains the state stack for a number of lines, for the
+ * start of that line (col == 0). This avoids having to recompute the
+ * 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)
+ */
+ synstate_T *b_sst_array;
+ int b_sst_len;
+ synstate_T *b_sst_first;
+ synstate_T *b_sst_firstfree;
+ int b_sst_freecount;
+ linenr_T b_sst_check_lnum;
+ short_u b_sst_lasttick; /* last display tick */
+
+ /* for spell checking */
+ garray_T b_langp; /* list of pointers to slang_T, see spell.c */
+ char_u b_spell_ismw[256]; /* flags: is midword char */
+ char_u *b_spell_ismw_mb; /* multi-byte midword chars */
+ char_u *b_p_spc; /* 'spellcapcheck' */
+ regprog_T *b_cap_prog; /* program for 'spellcapcheck' */
+ char_u *b_p_spf; /* 'spellfile' */
+ char_u *b_p_spl; /* 'spelllang' */
+ int b_cjk; /* all CJK letters as OK */
+} synblock_T;
+
+
+/*
+ * buffer: structure that holds information about one file
+ *
+ * Several windows can share a single Buffer
+ * A buffer is unallocated if there is no memfile for it.
+ * A buffer is new if the associated file has never been loaded yet.
+ */
+
+struct file_buffer {
+ 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 */
+ int b_closing; /* buffer is being closed, don't let
+ autocommands close it too. */
+
+ /*
+ * 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 */
+
+#ifdef UNIX
+ int b_dev_valid; /* TRUE when b_dev has a valid number */
+ dev_t b_dev; /* device number */
+ ino_t b_ino; /* inode number */
+#endif
+
+ 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. */
+ int b_changedtick; /* incremented for each change, also for undo */
+
+ int b_saving; /* Set to TRUE if we are in the middle of
+ saving the buffer. */
+
+ /*
+ * Changes to a buffer require updating of the display. To minimize the
+ * work, remember changes made and update everything at once.
+ */
+ int b_mod_set; /* TRUE when there are changes since the last
+ time the display was updated */
+ linenr_T b_mod_top; /* topmost lnum that was changed */
+ linenr_T b_mod_bot; /* lnum below last changed line, AFTER the
+ change */
+ long b_mod_xlines; /* number of extra buffer lines inserted;
+ negative when lines were deleted */
+
+ wininfo_T *b_wininfo; /* list of last used info for each window */
+
+ long b_mtime; /* last change time of original file */
+ long b_mtime_read; /* last change time when reading */
+ off_t b_orig_size; /* size of original file in bytes */
+ int b_orig_mode; /* mode of original file */
+
+ pos_T b_namedm[NMARKS]; /* current named marks (mark.c) */
+
+ /* These variables are set when VIsual_active becomes FALSE */
+ visualinfo_T b_visual;
+ int b_visual_mode_eval; /* b_visual.vi_mode for visualmode() */
+
+ pos_T b_last_cursor; /* cursor position when last unloading this
+ buffer */
+ pos_T b_last_insert; /* where Insert mode was left */
+ pos_T b_last_change; /* position of last change: '. mark */
+
+ /*
+ * the changelist contains old change positions
+ */
+ pos_T b_changelist[JUMPLISTSIZE];
+ int b_changelistlen; /* number of active entries */
+ int b_new_change; /* set by u_savecommon() */
+
+ /*
+ * Character table, only used in charset.c for 'iskeyword'
+ * 32 bytes of 8 bits: 1 bit per character 0-255.
+ */
+ char_u b_chartab[32];
+
+ /* Table used for mappings local to a buffer. */
+ mapblock_T *(b_maphash[256]);
+
+ /* First abbreviation local to a buffer. */
+ mapblock_T *b_first_abbr;
+ /* User commands local to the buffer. */
+ garray_T b_ucmds;
+ /*
+ * start and end of an operator, also used for '[ and ']
+ */
+ pos_T b_op_start;
+ pos_T b_op_end;
+
+ int b_marks_read; /* Have we read viminfo marks yet? */
+
+ /*
+ * The following only used in undo.c.
+ */
+ u_header_T *b_u_oldhead; /* pointer to oldest header */
+ u_header_T *b_u_newhead; /* pointer to newest header; may not be valid
+ if b_u_curhead is not NULL */
+ u_header_T *b_u_curhead; /* pointer to current header */
+ int b_u_numhead; /* current number of headers */
+ int b_u_synced; /* entry lists are synced */
+ long b_u_seq_last; /* last used undo sequence number */
+ long b_u_save_nr_last; /* counter for last file write */
+ long b_u_seq_cur; /* hu_seq of header below which we are now */
+ time_t b_u_time_cur; /* uh_time of header below which we are now */
+ long b_u_save_nr_cur; /* file write nr after which we are now */
+
+ /*
+ * variables for "U" command in undo.c
+ */
+ char_u *b_u_line_ptr; /* saved line for "U" command */
+ linenr_T b_u_line_lnum; /* line number of line in u_line */
+ colnr_T b_u_line_colnr; /* optional column number */
+
+ int 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 */
+#ifndef USE_IM_CONTROL
+# define B_IMODE_LAST 1
+#else
+# define B_IMODE_IM 2 /* Input via input method */
+# define B_IMODE_LAST 2
+#endif
+
+ short b_kmap_state; /* using "lmap" mappings */
+# define KEYMAP_INIT 1 /* 'keymap' was set, call keymap_init() */
+# define KEYMAP_LOADED 2 /* 'keymap' mappings have been loaded */
+ garray_T b_kmap_ga; /* the keymap table */
+
+ /*
+ * Options local to a buffer.
+ * They are here because their value depends on the type of file
+ * or contents of the file being edited.
+ */
+ int b_p_initialized; /* set when options initialized */
+
+ int 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 */
+ int b_p_ci; /* 'copyindent' */
+ int b_p_bin; /* 'binary' */
+ int b_p_bomb; /* 'bomb' */
+ char_u *b_p_bh; /* 'bufhidden' */
+ char_u *b_p_bt; /* 'buftype' */
+ int b_p_bl; /* 'buflisted' */
+ int b_p_cin; /* 'cindent' */
+ char_u *b_p_cino; /* 'cinoptions' */
+ char_u *b_p_cink; /* 'cinkeys' */
+ char_u *b_p_cinw; /* 'cinwords' */
+ char_u *b_p_com; /* 'comments' */
+ char_u *b_p_cms; /* 'commentstring' */
+ char_u *b_p_cpt; /* 'complete' */
+ char_u *b_p_cfu; /* 'completefunc' */
+ char_u *b_p_ofu; /* 'omnifunc' */
+ int b_p_eol; /* 'endofline' */
+ int b_p_et; /* 'expandtab' */
+ int b_p_et_nobin; /* b_p_et saved for binary mode */
+ char_u *b_p_fenc; /* 'fileencoding' */
+ char_u *b_p_ff; /* 'fileformat' */
+ char_u *b_p_ft; /* 'filetype' */
+ char_u *b_p_fo; /* 'formatoptions' */
+ char_u *b_p_flp; /* 'formatlistpat' */
+ int b_p_inf; /* 'infercase' */
+ char_u *b_p_isk; /* 'iskeyword' */
+ char_u *b_p_def; /* 'define' local value */
+ char_u *b_p_inc; /* 'include' */
+ char_u *b_p_inex; /* 'includeexpr' */
+ long_u b_p_inex_flags; /* flags for 'includeexpr' */
+ char_u *b_p_inde; /* 'indentexpr' */
+ long_u b_p_inde_flags; /* flags for 'indentexpr' */
+ char_u *b_p_indk; /* 'indentkeys' */
+ char_u *b_p_fex; /* 'formatexpr' */
+ long_u b_p_fex_flags; /* flags for 'formatexpr' */
+ char_u *b_p_key; /* 'key' */
+ char_u *b_p_kp; /* 'keywordprg' */
+ int b_p_lisp; /* 'lisp' */
+ char_u *b_p_mps; /* 'matchpairs' */
+ int b_p_ml; /* 'modeline' */
+ int b_p_ml_nobin; /* b_p_ml saved for binary mode */
+ int b_p_ma; /* 'modifiable' */
+ char_u *b_p_nf; /* 'nrformats' */
+ int b_p_pi; /* 'preserveindent' */
+ char_u *b_p_qe; /* 'quoteescape' */
+ int b_p_ro; /* 'readonly' */
+ long b_p_sw; /* 'shiftwidth' */
+#ifndef SHORT_FNAME
+ int b_p_sn; /* 'shortname' */
+#endif
+ 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' */
+ int b_p_swf; /* 'swapfile' */
+ long b_p_smc; /* 'synmaxcol' */
+ char_u *b_p_syn; /* 'syntax' */
+ long b_p_ts; /* 'tabstop' */
+ int b_p_tx; /* 'textmode' */
+ long b_p_tw; /* 'textwidth' */
+ long b_p_tw_nobin; /* b_p_tw saved for binary mode */
+ long b_p_tw_nopaste; /* b_p_tw saved for paste mode */
+ long b_p_wm; /* 'wrapmargin' */
+ long b_p_wm_nobin; /* b_p_wm saved for binary mode */
+ long b_p_wm_nopaste; /* b_p_wm saved for paste mode */
+ char_u *b_p_keymap; /* 'keymap' */
+
+ /* local values for options which are normally global */
+ char_u *b_p_gp; /* 'grepprg' local value */
+ char_u *b_p_mp; /* 'makeprg' local value */
+ char_u *b_p_efm; /* 'errorformat' local value */
+ char_u *b_p_ep; /* 'equalprg' local value */
+ char_u *b_p_path; /* 'path' local value */
+ int b_p_ar; /* 'autoread' local value */
+ char_u *b_p_tags; /* 'tags' local value */
+ char_u *b_p_dict; /* 'dictionary' local value */
+ char_u *b_p_tsr; /* 'thesaurus' local value */
+ long b_p_ul; /* 'undolevels' local value */
+ int b_p_udf; /* 'undofile' */
+
+ /* end of buffer options */
+
+ /* values set from b_p_cino */
+ int b_ind_level;
+ int b_ind_open_imag;
+ int b_ind_no_brace;
+ int b_ind_first_open;
+ int b_ind_open_extra;
+ int b_ind_close_extra;
+ int b_ind_open_left_imag;
+ int b_ind_jump_label;
+ int b_ind_case;
+ int b_ind_case_code;
+ int b_ind_case_break;
+ int b_ind_param;
+ int b_ind_func_type;
+ int b_ind_comment;
+ int b_ind_in_comment;
+ int b_ind_in_comment2;
+ int b_ind_cpp_baseclass;
+ int b_ind_continuation;
+ int b_ind_unclosed;
+ int b_ind_unclosed2;
+ int b_ind_unclosed_noignore;
+ int b_ind_unclosed_wrapped;
+ int b_ind_unclosed_whiteok;
+ int b_ind_matching_paren;
+ int b_ind_paren_prev;
+ int b_ind_maxparen;
+ int b_ind_maxcomment;
+ int b_ind_scopedecl;
+ int b_ind_scopedecl_code;
+ int b_ind_java;
+ int b_ind_js;
+ int b_ind_keep_case_label;
+ int b_ind_hash_comment;
+ int b_ind_cpp_namespace;
+ int b_ind_if_for_while;
+
+ linenr_T b_no_eol_lnum; /* non-zero lnum when last line of next binary
+ * write should not have an end-of-line */
+
+ int b_start_eol; /* last line had eol when it was read */
+ int b_start_ffc; /* first char of 'ff' when edit started */
+ char_u *b_start_fenc; /* 'fileencoding' when edit started or NULL */
+ 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 */
+
+ char_u *b_p_cm; /* 'cryptmethod' */
+
+ /* 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
+ * if a swap file could not be opened.
+ */
+ int b_may_swap;
+ int b_did_warn; /* Set to 1 if user has been warned on first
+ change of a read-only file */
+
+ /* 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.
+ */
+ int b_help; /* TRUE for help file buffer (when set b_p_bt
+ is "help") */
+ int b_spell; /* TRUE for a spell file buffer, most fields
+ are not used! Use the B_SPELL macro to
+ access b_spell without #ifdef. */
+
+#ifndef SHORT_FNAME
+ int b_shortname; /* this file has an 8.3 file name */
+#endif
+
+
+
+
+
+
+
+ synblock_T b_s; /* Info related to syntax highlighting. w_s
+ * normally points to this, but some windows
+ * may use a different synblock_T. */
+
+
+
+};
+
+
+/*
+ * Stuff for diff mode.
+ */
+# define DB_COUNT 4 /* up to four buffers can be diff'ed */
+
+/*
+ * Each diffblock defines where a block of lines starts in each of the buffers
+ * and how many lines it occupies in that buffer. When the lines are missing
+ * in the buffer the df_count[] is zero. This is all counted in
+ * buffer lines.
+ * There is always at least one unchanged line in between the diffs.
+ * Otherwise it would have been included in the diff above or below it.
+ * df_lnum[] + df_count[] is the lnum below the change. When in one buffer
+ * lines have been inserted, in the other buffer df_lnum[] is the line below
+ * the insertion and df_count[] is zero. When appending lines at the end of
+ * the buffer, df_lnum[] is one beyond the end!
+ * This is using a linked list, because the number of differences is expected
+ * to be reasonable small. The list is sorted on lnum.
+ */
+typedef struct diffblock_S diff_T;
+struct diffblock_S {
+ diff_T *df_next;
+ linenr_T df_lnum[DB_COUNT]; /* line number in buffer */
+ linenr_T df_count[DB_COUNT]; /* nr of inserted/changed lines */
+};
+
+#define SNAP_HELP_IDX 0
+# 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.
+ */
+typedef struct tabpage_S tabpage_T;
+struct tabpage_S {
+ 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 */
+ 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 */
+
+
+};
+
+/*
+ * Structure to cache info for displayed lines in w_lines[].
+ * Each logical line has one entry.
+ * The entry tells how the logical line is currently displayed in the window.
+ * This is updated when displaying the window.
+ * When the display is changed (e.g., when clearing the screen) w_lines_valid
+ * is changed to exclude invalid entries.
+ * When making changes to the buffer, wl_valid is reset to indicate wl_size
+ * may not reflect what is actually in the buffer. When wl_valid is FALSE,
+ * the entries can only be used to count the number of displayed lines used.
+ * wl_lnum and wl_lastlnum are invalid too.
+ */
+typedef struct w_line {
+ linenr_T wl_lnum; /* buffer line number for logical line */
+ short_u wl_size; /* height in screen lines */
+ char wl_valid; /* TRUE values are valid for text in buffer */
+ char wl_folded; /* TRUE when this is a range of folded lines */
+ linenr_T wl_lastlnum; /* last buffer line number for logical line */
+} wline_T;
+
+/*
+ * Windows are kept in a tree of frames. Each frame has a column (FR_COL)
+ * or row (FR_ROW) layout or is a leaf, which has a window.
+ */
+struct frame_S {
+ char fr_layout; /* FR_LEAF, FR_COL or FR_ROW */
+ int fr_width;
+ int fr_newwidth; /* new width used in win_equal_rec() */
+ int fr_height;
+ int fr_newheight; /* new height used in win_equal_rec() */
+ frame_T *fr_parent; /* containing frame or NULL */
+ frame_T *fr_next; /* frame right or below in same parent, NULL
+ for first */
+ frame_T *fr_prev; /* frame left or above in same parent, NULL
+ for last */
+ /* fr_child and fr_win are mutually exclusive */
+ frame_T *fr_child; /* first contained frame */
+ win_T *fr_win; /* window that fills this frame */
+};
+
+#define FR_LEAF 0 /* frame is a leaf */
+#define FR_ROW 1 /* frame with a row of windows */
+#define FR_COL 2 /* frame with a column of windows */
+
+/*
+ * Struct used for highlighting 'hlsearch' matches, matches defined by
+ * ":match" and matches defined by match functions.
+ * For 'hlsearch' there is one pattern for all windows. For ":match" and the
+ * 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 */
+} match_T;
+
+/*
+ * matchitem_T provides a linked list for storing match items for ":match" and
+ * the match functions.
+ */
+typedef struct matchitem matchitem_T;
+struct matchitem {
+ matchitem_T *next;
+ int id; /* match ID */
+ int priority; /* match priority */
+ char_u *pattern; /* pattern to highlight */
+ int hlg_id; /* highlight group ID */
+ regmmatch_T match; /* regexp program for pattern */
+ match_T hl; /* struct for doing the actual highlighting */
+};
+
+/*
+ * Structure which contains all information that belongs to a window
+ *
+ * All row numbers are relative to the start of the window, except w_winrow.
+ */
+struct window_S {
+ buf_T *w_buffer; /* buffer we are a window into (used
+ often, keep it the first item!) */
+
+ synblock_T *w_s; /* for :ownsyntax */
+
+ win_T *w_prev; /* link to previous window */
+ win_T *w_next; /* link to next window */
+ int w_closing; /* window is being closed, don't let
+ autocommands close it too. */
+
+ frame_T *w_frame; /* frame containing this window */
+
+ pos_T w_cursor; /* cursor position in buffer */
+
+ colnr_T w_curswant; /* The column we'd like to be at. This is
+ 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 */
+
+ /*
+ * the next six are used to update the visual part
+ */
+ char w_old_visual_mode; /* last known VIsual_mode */
+ linenr_T w_old_cursor_lnum; /* last known end of visual part */
+ colnr_T w_old_cursor_fcol; /* first column for block visual part */
+ colnr_T w_old_cursor_lcol; /* last column for block visual part */
+ linenr_T w_old_visual_lnum; /* last known start of visual part */
+ colnr_T w_old_visual_col; /* last known start of visual part */
+ colnr_T w_old_curswant; /* last known value of Curswant */
+
+ /*
+ * "w_topline", "w_leftcol" and "w_skipcol" specify the offsets for
+ * displaying the buffer.
+ */
+ linenr_T w_topline; /* buffer line number of the line at the
+ top of the window */
+ char w_topline_was_set; /* flag set to TRUE when topline is set,
+ e.g. by winrestview() */
+ int w_topfill; /* number of filler lines above w_topline */
+ int w_old_topfill; /* w_topfill at last redraw */
+ int w_botfill; /* TRUE when filler lines are actually
+ below w_topline (at end of file) */
+ int w_old_botfill; /* w_botfill at last redraw */
+ colnr_T w_leftcol; /* window column number of the left most
+ character in the window; used when
+ 'wrap' is off */
+ colnr_T w_skipcol; /* starting column when a single line
+ doesn't fit in the window */
+
+ /*
+ * Layout of the window in the screen.
+ * May need to add "msg_scrolled" to "w_winrow" in rare situations.
+ */
+ int w_winrow; /* first row of window in screen */
+ int w_height; /* number of rows in window, excluding
+ status/command line(s) */
+ int w_status_height; /* number of status lines (0 or 1) */
+ int w_wincol; /* Leftmost column of window in screen.
+ use W_WINCOL() */
+ int w_width; /* Width of window, excluding separation.
+ use W_WIDTH() */
+ int w_vsep_width; /* Number of separator columns (0 or 1).
+ use W_VSEP_WIDTH() */
+
+ /*
+ * === start of cached values ====
+ */
+ /*
+ * 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. See screen.c for values.
+ */
+ int w_valid;
+ pos_T w_valid_cursor; /* last known position of w_cursor, used
+ to adjust w_valid */
+ colnr_T w_valid_leftcol; /* last known w_leftcol */
+
+ /*
+ * w_cline_height is the number of physical lines taken by the buffer line
+ * that the cursor is on. We use this to avoid extra calls to plines().
+ */
+ int w_cline_height; /* current size of cursor line */
+ int w_cline_folded; /* cursor line is folded */
+
+ int w_cline_row; /* starting row of the cursor line */
+
+ colnr_T w_virtcol; /* column number of the cursor in the
+ buffer line, as opposed to the column
+ number we're at on the screen. This
+ makes a difference on lines which span
+ more than one screen line or when
+ w_leftcol is non-zero */
+
+ /*
+ * w_wrow and w_wcol specify the cursor position in the window.
+ * This is related to positions in the window, not in the display or
+ * buffer, thus w_wrow is relative to w_winrow.
+ */
+ 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 */
+
+ /*
+ * Info about the lines currently in the window is remembered to avoid
+ * recomputing it every time. The allocated size of w_lines[] is Rows.
+ * Only the w_lines_valid entries are actually valid.
+ * When the display is up-to-date w_lines[0].wl_lnum is equal to w_topline
+ * and w_lines[w_lines_valid - 1].wl_lnum is equal to w_botline.
+ * Between changing text and updating the display w_lines[] represents
+ * what is currently displayed. wl_valid is reset to indicated this.
+ * This is used for efficient redrawing.
+ */
+ int w_lines_valid; /* number of valid entries */
+ wline_T *w_lines;
+
+ garray_T w_folds; /* array of nested folds */
+ char w_fold_manual; /* when TRUE: some folds are opened/closed
+ manually */
+ char w_foldinvalid; /* when TRUE: folding needs to be
+ recomputed */
+ int w_nrwidth; /* width of 'number' and 'relativenumber'
+ column being used */
+
+ /*
+ * === end of cached values ===
+ */
+
+ int w_redr_type; /* type of redraw to be performed on win */
+ int w_upd_rows; /* number of window lines to update when
+ w_redr_type is REDRAW_TOP */
+ linenr_T w_redraw_top; /* when != 0: first line needing redraw */
+ linenr_T w_redraw_bot; /* when != 0: last line needing redraw */
+ int w_redr_status; /* if TRUE status line must be redrawn */
+
+ /* remember what is shown in the ruler for this window (if 'ruler' set) */
+ pos_T w_ru_cursor; /* cursor position shown in ruler */
+ colnr_T w_ru_virtcol; /* virtcol shown in ruler */
+ linenr_T w_ru_topline; /* topline shown in ruler */
+ linenr_T w_ru_line_count; /* line count used for ruler */
+ int w_ru_topfill; /* topfill shown in ruler */
+ char w_ru_empty; /* TRUE if ruler shows 0-1 (empty line) */
+
+ int w_alt_fnum; /* alternate file (for # and CTRL-^) */
+
+ alist_T *w_alist; /* pointer to arglist for this window */
+ int w_arg_idx; /* current index in argument list (can be
+ out of range!) */
+ int w_arg_idx_invalid; /* editing another file than w_arg_idx */
+
+ char_u *w_localdir; /* absolute path of local directory or
+ NULL */
+ /*
+ * Options local to a window.
+ * They are local because they influence the layout of the window or
+ * depend on the window layout.
+ * There are two values: w_onebuf_opt is local to the buffer currently in
+ * this window, w_allbuf_opt is for all buffers in this window.
+ */
+ winopt_T w_onebuf_opt;
+ winopt_T w_allbuf_opt;
+
+ /* A few options have local flags for P_INSECURE. */
+ long_u w_p_stl_flags; /* flags for 'statusline' */
+ long_u w_p_fde_flags; /* flags for 'foldexpr' */
+ long_u w_p_fdt_flags; /* flags for 'foldtext' */
+ int *w_p_cc_cols; /* array of columns to highlight or NULL */
+
+ /* transform a pointer to a "onebuf" option into a "allbuf" option */
+#define GLOBAL_WO(p) ((char *)p + sizeof(winopt_T))
+
+ long w_scbind_pos;
+
+ dictitem_T w_winvar; /* variable for "w:" Dictionary */
+ dict_T *w_vars; /* internal variables, local to window */
+
+ int w_farsi; /* for the window dependent Farsi functions */
+
+ /*
+ * The w_prev_pcmark field is used to check whether we really did jump to
+ * a new line after setting the w_pcmark. If not, then we revert to
+ * using the previous w_pcmark.
+ */
+ pos_T w_pcmark; /* previous context mark */
+ pos_T w_prev_pcmark; /* previous w_pcmark */
+
+ /*
+ * the jumplist contains old cursor positions
+ */
+ xfmark_T w_jumplist[JUMPLISTSIZE];
+ int w_jumplistlen; /* number of active entries */
+ int w_jumplistidx; /* current position */
+
+ int w_changelistidx; /* current position in b_changelist */
+
+ matchitem_T *w_match_head; /* head of match list */
+ int w_next_match_id; /* next match ID */
+
+ /*
+ * the tagstack grows from 0 upwards:
+ * entry 0: older
+ * entry 1: newer
+ * entry 2: newest
+ */
+ taggy_T w_tagstack[TAGSTACKSIZE]; /* the tag stack */
+ int w_tagstackidx; /* idx just below active entry */
+ int w_tagstacklen; /* number of tags on stack */
+
+ /*
+ * 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.
+ * w_prev_fraction_row was the actual cursor row when w_fraction was last
+ * calculated.
+ */
+ int w_fraction;
+ int w_prev_fraction_row;
+
+ linenr_T w_nrwidth_line_count; /* line count when ml_nrwidth_width
+ * was computed. */
+ int w_nrwidth_width; /* nr of chars to print line count. */
+
+ qf_info_T *w_llist; /* Location list for this window */
+ /*
+ * Location list reference used in the location list window.
+ * In a non-location list window, w_llist_ref is NULL.
+ */
+ qf_info_T *w_llist_ref;
+
+
+
+
+
+
+
+};
+
+/*
+ * Arguments for operators.
+ */
+typedef struct oparg_S {
+ int op_type; /* current pending operator type */
+ int regname; /* register to use for the operator */
+ int motion_type; /* type of the current cursor motion */
+ int motion_force; /* force motion type: 'v', 'V' or CTRL-V */
+ int use_reg_one; /* TRUE if delete uses reg 1 even when not
+ linewise */
+ int inclusive; /* TRUE if char motion is inclusive (only
+ valid when motion_type is MCHAR */
+ int end_adjusted; /* backuped b_op_end one char (only used by
+ do_format()) */
+ pos_T start; /* start of the operator */
+ pos_T end; /* end of the operator */
+ pos_T cursor_start; /* cursor position before motion for "gw" */
+
+ long line_count; /* number of lines from op_start to op_end
+ (inclusive) */
+ int empty; /* op_start and op_end the same (only used by
+ do_change()) */
+ int is_VIsual; /* operator on Visual area */
+ int block_mode; /* current operator is Visual block mode */
+ colnr_T start_vcol; /* start col for block mode operator */
+ colnr_T end_vcol; /* end col for block mode operator */
+ long prev_opcount; /* ca.opcount saved for K_CURSORHOLD */
+ long prev_count0; /* ca.count0 saved for K_CURSORHOLD */
+} oparg_T;
+
+/*
+ * Arguments for Normal mode commands.
+ */
+typedef struct cmdarg_S {
+ oparg_T *oap; /* Operator arguments */
+ int prechar; /* prefix character (optional, always 'g') */
+ int cmdchar; /* command character */
+ int nchar; /* next command character (optional) */
+ int ncharC1; /* first composing character (optional) */
+ int ncharC2; /* second composing character (optional) */
+ int extra_char; /* yet another character (optional) */
+ long opcount; /* count before an operator */
+ long count0; /* count before command, default 0 */
+ long count1; /* count before command, default 1 */
+ int arg; /* extra argument from nv_cmds[] */
+ int retval; /* return: CA_* values */
+ char_u *searchbuf; /* return: pointer to search pattern or NULL */
+} cmdarg_T;
+
+/* values for retval: */
+#define CA_COMMAND_BUSY 1 /* skip restarting edit() once */
+#define CA_NO_ADJ_OP_END 2 /* don't adjust operator end */
+
+#ifdef CURSOR_SHAPE
+/*
+ * 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 */
+
+#define MSHAPE_NUMBERED 1000 /* offset for shapes identified by number */
+#define MSHAPE_HIDE 1 /* hide mouse pointer */
+
+#define SHAPE_MOUSE 1 /* used for mouse pointer shape */
+#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 */
+} cursorentry_T;
+#endif /* CURSOR_SHAPE */
+
+
+/* Indices into vimmenu_T->strings[] and vimmenu_T->noremap[] for each mode */
+#define MENU_INDEX_INVALID -1
+#define MENU_INDEX_NORMAL 0
+#define MENU_INDEX_VISUAL 1
+#define MENU_INDEX_SELECT 2
+#define MENU_INDEX_OP_PENDING 3
+#define MENU_INDEX_INSERT 4
+#define MENU_INDEX_CMDLINE 5
+#define MENU_INDEX_TIP 6
+#define MENU_MODES 7
+
+/* 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)
+#define MENU_OP_PENDING_MODE (1 << MENU_INDEX_OP_PENDING)
+#define MENU_INSERT_MODE (1 << MENU_INDEX_INSERT)
+#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 */
+#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) */
+ int priority; /* Menu order priority */
+ char_u *strings[MENU_MODES]; /* Mapped string for each mode */
+ int noremap[MENU_MODES]; /* A REMAP_ flag for each mode */
+ char 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 */
+};
+
+/*
+ * Struct to save values in before executing autocommands for a buffer that is
+ * not the current buffer. Without FEAT_AUTOCMD only "curbuf" is remembered.
+ */
+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 */
+} aco_save_T;
+
+/*
+ * Generic option table item, only used for printer at the moment.
+ */
+typedef struct {
+ const char *name;
+ int hasnum;
+ long number;
+ char_u *string; /* points into option string */
+ int strlen;
+ int present;
+} option_table_T;
+
+/*
+ * Structure to hold printing color and font attributes.
+ */
+typedef struct {
+ long_u fg_color;
+ long_u bg_color;
+ int bold;
+ int italic;
+ int underline;
+ int undercurl;
+} prt_text_attr_T;
+
+/*
+ * Structure passed back to the generic printer code.
+ */
+typedef struct {
+ int n_collated_copies;
+ int n_uncollated_copies;
+ int duplex;
+ int chars_per_line;
+ int lines_per_page;
+ int has_color;
+ prt_text_attr_T number;
+ int modec;
+ int do_syntax;
+ int user_abort;
+ char_u *jobname;
+ char_u *outfile;
+ char_u *arguments;
+} prt_settings_T;
+
+#define PRINT_NUMBER_WIDTH 8
+
+/*
+ * Used for popup menu items.
+ */
+typedef struct {
+ char_u *pum_text; /* main menu text */
+ char_u *pum_kind; /* extra kind text (may be truncated) */
+ char_u *pum_extra; /* extra menu text (may be truncated) */
+ char_u *pum_info; /* extra info */
+} pumitem_T;
+
+/*
+ * Structure used for get_tagfname().
+ */
+typedef struct {
+ char_u *tn_tags; /* value of 'tags' when starting */
+ char_u *tn_np; /* current position in tn_tags */
+ int tn_did_filefind_init;
+ int tn_hf_idx;
+ void *tn_search_ctx;
+} tagname_T;
+
+/*
+ * 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 */
+
+typedef struct {
+ UINT32_T total[2];
+ UINT32_T state[8];
+ char_u buffer[64];
+} context_sha256_T;
diff --git a/src/syntax.c b/src/syntax.c
new file mode 100644
index 0000000000..375f16cd0d
--- /dev/null
+++ b/src/syntax.c
@@ -0,0 +1,7924 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * 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.
+ */
+
+/*
+ * syntax.c: code for syntax highlighting
+ */
+
+#include "vim.h"
+
+/*
+ * 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 */
+ /* for normal terminals */
+ int sg_term; /* "term=" highlighting attributes */
+ char_u *sg_start; /* terminal string for start highl */
+ char_u *sg_stop; /* terminal string for stop highl */
+ int sg_term_attr; /* Screen attr for term mode */
+ /* for color terminals */
+ int sg_cterm; /* "cterm=" highlighting attr */
+ int sg_cterm_bold; /* bold attr was set for light color */
+ int sg_cterm_fg; /* terminal fg color number + 1 */
+ int sg_cterm_bg; /* terminal bg color number + 1 */
+ int sg_cterm_attr; /* Screen attr for color term mode */
+ /* Store the sp color name for the GUI or synIDattr() */
+ int sg_gui; /* "gui=" highlighting attributes */
+ char_u *sg_gui_fg_name; /* GUI foreground color name */
+ char_u *sg_gui_bg_name; /* GUI background color name */
+ char_u *sg_gui_sp_name; /* GUI special color name */
+ 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 */
+};
+
+#define SG_TERM 1 /* term has been 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 */
+
+static garray_T highlight_ga; /* highlight groups for 'highlight' option */
+
+#define HL_TABLE() ((struct hl_group *)((highlight_ga.ga_data)))
+
+#define MAX_HL_ID 20000 /* maximum value for a highlight ID. */
+
+/* Flags to indicate an additional string for highlight name completion. */
+static int include_none = 0; /* when 1 include "None" */
+static int include_default = 0; /* when 1 include "default" */
+static int include_link = 0; /* when 2 include "link" and "clear" */
+
+/*
+ * 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"};
+static int hl_attr_table[] =
+{HL_BOLD, HL_STANDOUT, HL_UNDERLINE, HL_UNDERCURL, HL_ITALIC, HL_INVERSE,
+ HL_INVERSE, 0};
+
+static int get_attr_entry __ARGS((garray_T *table, attrentry_T *aep));
+static void syn_unadd_group __ARGS((void));
+static void set_hl_attr __ARGS((int idx));
+static void highlight_list_one __ARGS((int id));
+static int highlight_list_arg __ARGS((int id, int didh, int type, int iarg,
+ char_u *sarg,
+ char *name));
+static int syn_add_group __ARGS((char_u *name));
+static int syn_list_header __ARGS((int did_header, int outlen, int id));
+static int hl_has_settings __ARGS((int idx, int check_link));
+static void highlight_clear __ARGS((int idx));
+
+
+/*
+ * An attribute number is the index in attr_table plus ATTR_OFF.
+ */
+#define ATTR_OFF (HL_ALL + 1)
+
+
+#define SYN_NAMELEN 50 /* maximum length of a syntax name */
+
+/* different types of offsets that are possible */
+#define SPO_MS_OFF 0 /* match start offset */
+#define SPO_ME_OFF 1 /* match end offset */
+#define SPO_HS_OFF 2 /* highl. start offset */
+#define SPO_HE_OFF 3 /* highl. end offset */
+#define SPO_RS_OFF 4 /* region start offset */
+#define SPO_RE_OFF 5 /* region end offset */
+#define SPO_LC_OFF 6 /* leading context offset */
+#define SPO_COUNT 7
+
+static char *(spo_name_tab[SPO_COUNT]) =
+{"ms=", "me=", "hs=", "he=", "rs=", "re=", "lc="};
+
+/*
+ * 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).
+ */
+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 */
+ 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;
+
+/* The sp_off_flags are computed like this:
+ * offset from the start of the matched text: (1 << SPO_XX_OFF)
+ * offset from the end of the matched text: (1 << (SPO_XX_OFF + SPO_COUNT))
+ * When both are present, only one is used.
+ */
+
+#define SPTYPE_MATCH 1 /* match keyword with this group ID */
+#define SPTYPE_START 2 /* match a regexp, start of item */
+#define SPTYPE_END 3 /* match a regexp, end of item */
+#define SPTYPE_SKIP 4 /* match a regexp, skip within item */
+
+
+#define SYN_ITEMS(buf) ((synpat_T *)((buf)->b_syn_patterns.ga_data))
+
+#define NONE_IDX -2 /* value of sp_sync_idx for "NONE" */
+
+/*
+ * Flags for b_syn_sync_flags:
+ */
+#define SF_CCOMMENT 0x01 /* sync on a C-style comment */
+#define SF_MATCH 0x02 /* sync by matching a pattern */
+
+#define SYN_STATE_P(ssp) ((bufstate_T *)((ssp)->ga_data))
+
+#define MAXKEYWLEN 80 /* maximum length of a keyword */
+
+/*
+ * The attributes of the syntax item that has been recognized.
+ */
+static int current_attr = 0; /* attr of current syntax word */
+static int current_id = 0; /* ID of current char for syn_get_id() */
+static int current_trans_id = 0; /* idem, transparency removed */
+static int current_flags = 0;
+static int current_seqnr = 0;
+static int current_sub_char = 0;
+
+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 */
+} syn_cluster_T;
+
+/*
+ * Methods of combining two clusters
+ */
+#define CLUSTER_REPLACE 1 /* replace first list with second */
+#define CLUSTER_ADD 2 /* add second list to first */
+#define CLUSTER_SUBTRACT 3 /* subtract second list from first */
+
+#define SYN_CLSTR(buf) ((syn_cluster_T *)((buf)->b_syn_clusters.ga_data))
+
+/*
+ * Syntax group IDs have different types:
+ * 0 - 19999 normal syntax groups
+ * 20000 - 20999 ALLBUT indicator (current_syn_inc_tag added)
+ * 21000 - 21999 TOP indicator (current_syn_inc_tag added)
+ * 22000 - 22999 CONTAINED indicator (current_syn_inc_tag added)
+ * 23000 - 32767 cluster IDs (subtract SYNID_CLUSTER for the cluster ID)
+ */
+#define SYNID_ALLBUT MAX_HL_ID /* syntax group ID for contains=ALLBUT */
+#define SYNID_TOP 21000 /* syntax group ID for contains=TOP */
+#define SYNID_CONTAINED 22000 /* syntax group ID for contains=CONTAINED */
+#define SYNID_CLUSTER 23000 /* first syntax group ID for clusters */
+
+#define MAX_SYN_INC_TAG 999 /* maximum before the above overflow */
+#define MAX_CLUSTER_ID (32767 - SYNID_CLUSTER)
+
+/*
+ * Annoying Hack(TM): ":syn include" needs this pointer to pass to
+ * expand_filename(). Most of the other syntax commands don't need it, so
+ * instead of passing it to them, we stow it here.
+ */
+static char_u **syn_cmdlinep;
+
+/*
+ * Another Annoying Hack(TM): To prevent rules from other ":syn include"'d
+ * files from leaking into ALLBUT lists, we assign a unique ID to the
+ * rules in each ":syn include"'d file.
+ */
+static int current_syn_inc_tag = 0;
+static int running_syn_inc_tag = 0;
+
+/*
+ * In a hashtable item "hi_key" points to "keyword" in a keyentry.
+ * This avoids adding a pointer to the hashtable item.
+ * KE2HIKEY() converts a var pointer to a hashitem key pointer.
+ * HIKEY2KE() converts a hashitem key pointer to a var pointer.
+ * HI2KE() converts a hashitem pointer to a var pointer.
+ */
+static keyentry_T dumkey;
+#define KE2HIKEY(kp) ((kp)->keyword)
+#define HIKEY2KE(p) ((keyentry_T *)((p) - (dumkey.keyword - (char_u *)&dumkey)))
+#define HI2KE(hi) HIKEY2KE((hi)->hi_key)
+
+/*
+ * 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
+ * "keepend" on the stack.
+ */
+static int keepend_level = -1;
+
+static char msg_no_items[] = N_("No Syntax items defined for this buffer");
+
+/*
+ * For the current state we need to remember more than just the idx.
+ * When si_m_endpos.lnum is 0, the items other than si_idx are unknown.
+ * (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 */
+} stateitem_T;
+
+#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 */
+
+static int next_seqnr = 0; /* value to use for si_seqnr */
+
+/*
+ * Struct to reduce the number of arguments to get_syn_options(), it's used
+ * 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 */
+} syn_opt_arg_T;
+
+/*
+ * The next possible match in the current line for any pattern is remembered,
+ * to avoid having to try for a match in each column.
+ * If next_match_idx == -1, not tried (in this line) yet.
+ * If next_match_col == MAXCOL, no match found in this line.
+ * (All end positions have the column of the char after the end)
+ */
+static int next_match_col; /* column for start of next match */
+static lpos_T next_match_m_endpos; /* position for end of next match */
+static lpos_T next_match_h_startpos; /* pos. for highl. start of next match */
+static lpos_T next_match_h_endpos; /* pos. for highl. end of next match */
+static int next_match_idx; /* index of matched item */
+static long next_match_flags; /* flags for next match */
+static lpos_T next_match_eos_pos; /* end of start pattn (start region) */
+static lpos_T next_match_eoe_pos; /* pos. for end of end pattern */
+static int next_match_end_idx; /* ID of group for end pattn or zero */
+static reg_extmatch_T *next_match_extmatch = NULL;
+
+/*
+ * A state stack is an array of integers or stateitem_T, stored in a
+ * garray_T. A state stack is invalid if it's itemsize entry is zero.
+ */
+#define INVALID_STATE(ssp) ((ssp)->ga_itemsize == 0)
+#define VALID_STATE(ssp) ((ssp)->ga_itemsize != 0)
+
+/*
+ * The current state (within the line) of the recognition engine.
+ * When current_state.ga_itemsize is 0 the current state is invalid.
+ */
+static win_T *syn_win; /* current window for highlighting */
+static buf_T *syn_buf; /* current buffer for highlighting */
+static synblock_T *syn_block; /* current buffer for highlighting */
+static linenr_T current_lnum = 0; /* lnum of current state */
+static colnr_T current_col = 0; /* column of current state */
+static int current_state_stored = 0; /* TRUE if stored current state
+ * after setting current_finished */
+static int current_finished = 0; /* current line has been finished */
+static garray_T current_state /* current stack of state_items */
+ = {0, 0, 0, 0, NULL};
+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 */
+
+#define CUR_STATE(idx) ((stateitem_T *)(current_state.ga_data))[idx]
+
+static void syn_sync __ARGS((win_T *wp, linenr_T lnum, synstate_T *last_valid));
+static int syn_match_linecont __ARGS((linenr_T lnum));
+static void syn_start_line __ARGS((void));
+static void syn_update_ends __ARGS((int startofline));
+static void syn_stack_alloc __ARGS((void));
+static int syn_stack_cleanup __ARGS((void));
+static void syn_stack_free_entry __ARGS((synblock_T *block, synstate_T *p));
+static synstate_T *syn_stack_find_entry __ARGS((linenr_T lnum));
+static synstate_T *store_current_state __ARGS((void));
+static void load_current_state __ARGS((synstate_T *from));
+static void invalidate_current_state __ARGS((void));
+static int syn_stack_equal __ARGS((synstate_T *sp));
+static void validate_current_state __ARGS((void));
+static int syn_finish_line __ARGS((int syncing));
+static int syn_current_attr __ARGS((int syncing, int displaying, int *can_spell,
+ int keep_state));
+static int did_match_already __ARGS((int idx, garray_T *gap));
+static stateitem_T *push_next_match __ARGS((stateitem_T *cur_si));
+static void check_state_ends __ARGS((void));
+static void update_si_attr __ARGS((int idx));
+static void check_keepend __ARGS((void));
+static void update_si_end __ARGS((stateitem_T *sip, int startcol, int force));
+static short *copy_id_list __ARGS((short *list));
+static int in_id_list __ARGS((stateitem_T *item, short *cont_list,
+ struct sp_syn *ssp,
+ int contained));
+static int push_current_state __ARGS((int idx));
+static void pop_current_state __ARGS((void));
+static void syn_clear_time __ARGS((syn_time_T *tt));
+static void syntime_clear __ARGS((void));
+static int syn_compare_syntime __ARGS((const void *v1, const void *v2));
+static void syntime_report __ARGS((void));
+static int syn_time_on = FALSE;
+# define IF_SYN_TIME(p) (p)
+
+static void syn_stack_apply_changes_block __ARGS((synblock_T *block, buf_T *buf));
+static void find_endpos __ARGS((int idx, lpos_T *startpos, lpos_T *m_endpos,
+ lpos_T *hl_endpos, long *flagsp, lpos_T *
+ end_endpos, int *end_idx,
+ reg_extmatch_T *start_ext));
+static void clear_syn_state __ARGS((synstate_T *p));
+static void clear_current_state __ARGS((void));
+
+static void limit_pos __ARGS((lpos_T *pos, lpos_T *limit));
+static void limit_pos_zero __ARGS((lpos_T *pos, lpos_T *limit));
+static void syn_add_end_off __ARGS((lpos_T *result, regmmatch_T *regmatch,
+ synpat_T *spp, int idx,
+ int extra));
+static void syn_add_start_off __ARGS((lpos_T *result, regmmatch_T *regmatch,
+ synpat_T *spp, int idx,
+ int extra));
+static char_u *syn_getcurline __ARGS((void));
+static int syn_regexec __ARGS((regmmatch_T *rmp, linenr_T lnum, colnr_T col,
+ syn_time_T *st));
+static int check_keyword_id __ARGS((char_u *line, int startcol, int *endcol,
+ long *flags, short **next_list,
+ stateitem_T *cur_si,
+ int *ccharp));
+static void syn_cmd_case __ARGS((exarg_T *eap, int syncing));
+static void syn_cmd_spell __ARGS((exarg_T *eap, int syncing));
+static void syntax_sync_clear __ARGS((void));
+static void syn_remove_pattern __ARGS((synblock_T *block, int idx));
+static void syn_clear_pattern __ARGS((synblock_T *block, int i));
+static void syn_clear_cluster __ARGS((synblock_T *block, int i));
+static void syn_cmd_clear __ARGS((exarg_T *eap, int syncing));
+static void syn_cmd_conceal __ARGS((exarg_T *eap, int syncing));
+static void syn_clear_one __ARGS((int id, int syncing));
+static void syn_cmd_on __ARGS((exarg_T *eap, int syncing));
+static void syn_cmd_enable __ARGS((exarg_T *eap, int syncing));
+static void syn_cmd_reset __ARGS((exarg_T *eap, int syncing));
+static void syn_cmd_manual __ARGS((exarg_T *eap, int syncing));
+static void syn_cmd_off __ARGS((exarg_T *eap, int syncing));
+static void syn_cmd_onoff __ARGS((exarg_T *eap, char *name));
+static void syn_cmd_list __ARGS((exarg_T *eap, int syncing));
+static void syn_lines_msg __ARGS((void));
+static void syn_match_msg __ARGS((void));
+static void syn_stack_free_block __ARGS((synblock_T *block));
+static void syn_list_one __ARGS((int id, int syncing, int link_only));
+static void syn_list_cluster __ARGS((int id));
+static void put_id_list __ARGS((char_u *name, short *list, int attr));
+static void put_pattern __ARGS((char *s, int c, synpat_T *spp, int attr));
+static int syn_list_keywords __ARGS((int id, hashtab_T *ht, int did_header,
+ int attr));
+static void syn_clear_keyword __ARGS((int id, hashtab_T *ht));
+static void clear_keywtab __ARGS((hashtab_T *ht));
+static void add_keyword __ARGS((char_u *name, int id, int flags,
+ short *cont_in_list, short *next_list,
+ int conceal_char));
+static char_u *get_group_name __ARGS((char_u *arg, char_u **name_end));
+static char_u *get_syn_options __ARGS((char_u *arg, syn_opt_arg_T *opt,
+ int *conceal_char));
+static void syn_cmd_include __ARGS((exarg_T *eap, int syncing));
+static void syn_cmd_keyword __ARGS((exarg_T *eap, int syncing));
+static void syn_cmd_match __ARGS((exarg_T *eap, int syncing));
+static void syn_cmd_region __ARGS((exarg_T *eap, int syncing));
+static int syn_compare_stub __ARGS((const void *v1, const void *v2));
+static void syn_cmd_cluster __ARGS((exarg_T *eap, int syncing));
+static int syn_scl_name2id __ARGS((char_u *name));
+static int syn_scl_namen2id __ARGS((char_u *linep, int len));
+static int syn_check_cluster __ARGS((char_u *pp, int len));
+static int syn_add_cluster __ARGS((char_u *name));
+static void init_syn_patterns __ARGS((void));
+static char_u *get_syn_pattern __ARGS((char_u *arg, synpat_T *ci));
+static void syn_cmd_sync __ARGS((exarg_T *eap, int syncing));
+static int get_id_list __ARGS((char_u **arg, int keylen, short **list));
+static void syn_combine_list __ARGS((short **clstr1, short **clstr2,
+ int list_op));
+static void syn_incl_toplevel __ARGS((int id, int *flagsp));
+
+/*
+ * Start the syntax recognition for a line. This function is normally called
+ * from the screen updating, once for each displayed line.
+ * The buffer is remembered in syn_buf, because get_syntax_attr() doesn't get
+ * it. Careful: curbuf and curwin are likely to point to another buffer and
+ * window.
+ */
+void syntax_start(wp, lnum)
+win_T *wp;
+linenr_T lnum;
+{
+ synstate_T *p;
+ synstate_T *last_valid = NULL;
+ synstate_T *last_min_valid = NULL;
+ synstate_T *sp, *prev = NULL;
+ linenr_T parsed_lnum;
+ linenr_T first_stored;
+ int dist;
+ static int changedtick = 0; /* remember the last change ID */
+
+ current_sub_char = NUL;
+
+ /*
+ * After switching buffers, invalidate current_state.
+ * 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) {
+ invalidate_current_state();
+ syn_buf = wp->w_buffer;
+ syn_block = wp->w_s;
+ }
+ changedtick = syn_buf->b_changedtick;
+ syn_win = wp;
+
+ /*
+ * Allocate syntax stack when needed.
+ */
+ syn_stack_alloc();
+ if (syn_block->b_sst_array == NULL)
+ return; /* out of memory */
+ syn_block->b_sst_lasttick = display_tick;
+
+ /*
+ * If the state of the end of the previous line is useful, store it.
+ */
+ if (VALID_STATE(&current_state)
+ && current_lnum < lnum
+ && current_lnum < syn_buf->b_ml.ml_line_count) {
+ (void)syn_finish_line(FALSE);
+ if (!current_state_stored) {
+ ++current_lnum;
+ (void)store_current_state();
+ }
+
+ /*
+ * If the current_lnum is now the same as "lnum", keep the current
+ * state (this happens very often!). Otherwise invalidate
+ * current_state and figure it out below.
+ */
+ if (current_lnum != lnum)
+ invalidate_current_state();
+ } else
+ invalidate_current_state();
+
+ /*
+ * Try to synchronize from a saved state in b_sst_array[].
+ * Only do this if lnum is not before and not to far beyond a saved state.
+ */
+ 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)
+ break;
+ if (p->sst_lnum <= lnum && p->sst_change_lnum == 0) {
+ last_valid = p;
+ if (p->sst_lnum >= lnum - syn_block->b_syn_sync_minlines)
+ last_min_valid = p;
+ }
+ }
+ if (last_min_valid != NULL)
+ load_current_state(last_min_valid);
+ }
+
+ /*
+ * If "lnum" is before or far beyond a line with a saved state, need to
+ * re-synchronize.
+ */
+ if (INVALID_STATE(&current_state)) {
+ syn_sync(wp, lnum, last_valid);
+ if (current_lnum == 1)
+ /* First line is always valid, no matter "minlines". */
+ first_stored = 1;
+ else
+ /* Need to parse "minlines" lines before state can be considered
+ * valid to store. */
+ first_stored = current_lnum + syn_block->b_syn_sync_minlines;
+ } else
+ first_stored = current_lnum;
+
+ /*
+ * Advance from the sync point or saved state until the current line.
+ * Save some entries for syncing with later on.
+ */
+ if (syn_block->b_sst_len <= Rows)
+ dist = 999999;
+ else
+ 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;
+
+ /* If we parsed at least "minlines" lines or started at a valid
+ * state, the current state is considered valid. */
+ if (current_lnum >= first_stored) {
+ /* Check if the saved state entry is for the current line and is
+ * equal to the current state. If so, then validate all saved
+ * states that depended on a change before the parsed line. */
+ if (prev == NULL)
+ prev = syn_stack_find_entry(current_lnum - 1);
+ if (prev == NULL)
+ sp = syn_block->b_sst_first;
+ else
+ sp = prev;
+ while (sp != NULL && sp->sst_lnum < current_lnum)
+ sp = sp->sst_next;
+ if (sp != NULL
+ && sp->sst_lnum == current_lnum
+ && syn_stack_equal(sp)) {
+ parsed_lnum = current_lnum;
+ prev = sp;
+ while (sp != NULL && sp->sst_change_lnum <= parsed_lnum) {
+ if (sp->sst_lnum <= lnum)
+ /* valid state before desired line, use this one */
+ prev = sp;
+ else if (sp->sst_change_lnum == 0)
+ /* past saved states depending on change, break here. */
+ break;
+ sp->sst_change_lnum = 0;
+ sp = sp->sst_next;
+ }
+ load_current_state(prev);
+ }
+ /* Store the state at this line when it's the first one, the line
+ * where we start parsing, or some distance from the previously
+ * saved state. But only when parsed at least 'minlines'. */
+ else if (prev == NULL
+ || current_lnum == lnum
+ || current_lnum >= prev->sst_lnum + dist)
+ prev = store_current_state();
+ }
+
+ /* This can take a long time: break when CTRL-C pressed. The current
+ * state will be wrong then. */
+ line_breakcheck();
+ if (got_int) {
+ current_lnum = lnum;
+ break;
+ }
+ }
+
+ syn_start_line();
+}
+
+/*
+ * We cannot simply discard growarrays full of state_items or buf_states; we
+ * have to manually release their extmatch pointers first.
+ */
+static void clear_syn_state(p)
+synstate_T *p;
+{
+ int i;
+ garray_T *gap;
+
+ if (p->sst_stacksize > SST_FIX_STATES) {
+ gap = &(p->sst_union.sst_ga);
+ for (i = 0; i < gap->ga_len; i++)
+ unref_extmatch(SYN_STATE_P(gap)[i].bs_extmatch);
+ ga_clear(gap);
+ } else {
+ for (i = 0; i < p->sst_stacksize; i++)
+ unref_extmatch(p->sst_union.sst_stack[i].bs_extmatch);
+ }
+}
+
+/*
+ * Cleanup the current_state stack.
+ */
+static void clear_current_state() {
+ int i;
+ stateitem_T *sip;
+
+ sip = (stateitem_T *)(current_state.ga_data);
+ for (i = 0; i < current_state.ga_len; i++)
+ unref_extmatch(sip[i].si_extmatch);
+ ga_clear(&current_state);
+}
+
+/*
+ * Try to find a synchronisation point for line "lnum".
+ *
+ * This sets current_lnum and the current state. One of three methods is
+ * used:
+ * 1. Search backwards for the end of a C-comment.
+ * 2. Search backwards for given sync patterns.
+ * 3. Simply start on a given number of lines above "lnum".
+ */
+static void syn_sync(wp, start_lnum, last_valid)
+win_T *wp;
+linenr_T start_lnum;
+synstate_T *last_valid;
+{
+ buf_T *curbuf_save;
+ win_T *curwin_save;
+ pos_T cursor_save;
+ int idx;
+ linenr_T lnum;
+ linenr_T end_lnum;
+ linenr_T break_lnum;
+ int had_sync_point;
+ stateitem_T *cur_si;
+ synpat_T *spp;
+ char_u *line;
+ int found_flags = 0;
+ int found_match_idx = 0;
+ linenr_T found_current_lnum = 0;
+ int found_current_col= 0;
+ lpos_T found_m_endpos;
+ colnr_T prev_current_col;
+
+ /*
+ * Clear any current state that might be hanging around.
+ */
+ invalidate_current_state();
+
+ /*
+ * Start at least "minlines" back. Default starting point for parsing is
+ * there.
+ * Start further back, to avoid that scrolling backwards will result in
+ * resyncing for every line. Now it resyncs only one out of N lines,
+ * where N is minlines * 1.5, or minlines * 2 if minlines is small.
+ * Watch out for overflow when minlines is MAXLNUM.
+ */
+ if (syn_block->b_syn_sync_minlines > start_lnum)
+ start_lnum = 1;
+ else {
+ if (syn_block->b_syn_sync_minlines == 1)
+ lnum = 1;
+ else if (syn_block->b_syn_sync_minlines < 10)
+ lnum = syn_block->b_syn_sync_minlines * 2;
+ else
+ lnum = syn_block->b_syn_sync_minlines * 3 / 2;
+ if (syn_block->b_syn_sync_maxlines != 0
+ && lnum > syn_block->b_syn_sync_maxlines)
+ lnum = syn_block->b_syn_sync_maxlines;
+ if (lnum >= start_lnum)
+ start_lnum = 1;
+ else
+ start_lnum -= lnum;
+ }
+ current_lnum = start_lnum;
+
+ /*
+ * 1. Search backwards for the end of a C-style comment.
+ */
+ if (syn_block->b_syn_sync_flags & SF_CCOMMENT) {
+ /* Need to make syn_buf the current buffer for a moment, to be able to
+ * use find_start_comment(). */
+ curwin_save = curwin;
+ curwin = wp;
+ curbuf_save = curbuf;
+ curbuf = syn_buf;
+
+ /*
+ * Skip lines that end in a backslash.
+ */
+ for (; start_lnum > 1; --start_lnum) {
+ line = ml_get(start_lnum - 1);
+ if (*line == NUL || *(line + STRLEN(line) - 1) != '\\')
+ break;
+ }
+ current_lnum = start_lnum;
+
+ /* set cursor to start of search */
+ cursor_save = wp->w_cursor;
+ wp->w_cursor.lnum = start_lnum;
+ wp->w_cursor.col = 0;
+
+ /*
+ * If the line is inside a comment, need to find the syntax item that
+ * defines the comment.
+ * Restrict the search for the end of a comment to b_syn_sync_maxlines.
+ */
+ if (find_start_comment((int)syn_block->b_syn_sync_maxlines) != NULL) {
+ for (idx = syn_block->b_syn_patterns.ga_len; --idx >= 0; )
+ if (SYN_ITEMS(syn_block)[idx].sp_syn.id
+ == syn_block->b_syn_sync_id
+ && SYN_ITEMS(syn_block)[idx].sp_type == SPTYPE_START) {
+ validate_current_state();
+ if (push_current_state(idx) == OK)
+ update_si_attr(current_state.ga_len - 1);
+ break;
+ }
+ }
+
+ /* restore cursor and buffer */
+ wp->w_cursor = cursor_save;
+ curwin = curwin_save;
+ curbuf = curbuf_save;
+ }
+ /*
+ * 2. Search backwards for given sync patterns.
+ */
+ else if (syn_block->b_syn_sync_flags & SF_MATCH) {
+ if (syn_block->b_syn_sync_maxlines != 0
+ && start_lnum > syn_block->b_syn_sync_maxlines)
+ break_lnum = start_lnum - syn_block->b_syn_sync_maxlines;
+ else
+ break_lnum = 0;
+
+ found_m_endpos.lnum = 0;
+ found_m_endpos.col = 0;
+ end_lnum = start_lnum;
+ lnum = start_lnum;
+ while (--lnum > break_lnum) {
+ /* This can take a long time: break when CTRL-C pressed. */
+ line_breakcheck();
+ if (got_int) {
+ invalidate_current_state();
+ current_lnum = start_lnum;
+ break;
+ }
+
+ /* Check if we have run into a valid saved state stack now. */
+ if (last_valid != NULL && lnum == last_valid->sst_lnum) {
+ load_current_state(last_valid);
+ break;
+ }
+
+ /*
+ * Check if the previous line has the line-continuation pattern.
+ */
+ if (lnum > 1 && syn_match_linecont(lnum - 1))
+ continue;
+
+ /*
+ * Start with nothing on the state stack
+ */
+ validate_current_state();
+
+ 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.
+ */
+ 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) {
+ /* ignore match that goes to after where started */
+ current_lnum = end_lnum;
+ break;
+ }
+ if (cur_si->si_idx < 0) {
+ /* Cannot happen? */
+ found_flags = 0;
+ found_match_idx = KEYWORD_IDX;
+ } else {
+ spp = &(SYN_ITEMS(syn_block)[cur_si->si_idx]);
+ found_flags = spp->sp_flags;
+ found_match_idx = spp->sp_sync_idx;
+ }
+ found_current_lnum = current_lnum;
+ found_current_col = current_col;
+ found_m_endpos = cur_si->si_m_endpos;
+ /*
+ * Continue after the match (be aware of a zero-length
+ * match).
+ */
+ if (found_m_endpos.lnum > current_lnum) {
+ current_lnum = found_m_endpos.lnum;
+ current_col = found_m_endpos.col;
+ if (current_lnum >= end_lnum)
+ break;
+ } else if (found_m_endpos.col > current_col)
+ current_col = found_m_endpos.col;
+ else
+ ++current_col;
+
+ /* 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;
+ check_state_ends();
+ current_col = prev_current_col;
+ } else
+ break;
+ }
+ }
+
+ /*
+ * If a sync point was encountered, break here.
+ */
+ if (found_flags) {
+ /*
+ * Put the item that was specified by the sync point on the
+ * state stack. If there was no item specified, make the
+ * state stack empty.
+ */
+ clear_current_state();
+ if (found_match_idx >= 0
+ && push_current_state(found_match_idx) == OK)
+ update_si_attr(current_state.ga_len - 1);
+
+ /*
+ * When using "grouphere", continue from the sync point
+ * match, until the end of the line. Parsing starts at
+ * the next line.
+ * For "groupthere" the parsing starts at start_lnum.
+ */
+ if (found_flags & HL_SYNC_HERE) {
+ if (current_state.ga_len) {
+ cur_si = &CUR_STATE(current_state.ga_len - 1);
+ cur_si->si_h_startpos.lnum = found_current_lnum;
+ cur_si->si_h_startpos.col = found_current_col;
+ update_si_end(cur_si, (int)current_col, TRUE);
+ check_keepend();
+ }
+ current_col = found_m_endpos.col;
+ current_lnum = found_m_endpos.lnum;
+ (void)syn_finish_line(FALSE);
+ ++current_lnum;
+ } else
+ current_lnum = start_lnum;
+
+ break;
+ }
+
+ end_lnum = lnum;
+ invalidate_current_state();
+ }
+
+ /* Ran into start of the file or exceeded maximum number of lines */
+ if (lnum <= break_lnum) {
+ invalidate_current_state();
+ current_lnum = break_lnum + 1;
+ }
+ }
+
+ validate_current_state();
+}
+
+/*
+ * Return TRUE if the line-continuation pattern matches in line "lnum".
+ */
+static int syn_match_linecont(lnum)
+linenr_T lnum;
+{
+ regmmatch_T regmatch;
+
+ if (syn_block->b_syn_linecont_prog != NULL) {
+ regmatch.rmm_ic = syn_block->b_syn_linecont_ic;
+ regmatch.regprog = syn_block->b_syn_linecont_prog;
+ return syn_regexec(&regmatch, lnum, (colnr_T)0,
+ IF_SYN_TIME(&syn_block->b_syn_linecont_time));
+ }
+ return FALSE;
+}
+
+/*
+ * Prepare the current state for the start of a line.
+ */
+static void syn_start_line() {
+ current_finished = FALSE;
+ current_col = 0;
+
+ /*
+ * Need to update the end of a start/skip/end that continues from the
+ * previous line and regions that have "keepend".
+ */
+ if (current_state.ga_len > 0) {
+ syn_update_ends(TRUE);
+ check_state_ends();
+ }
+
+ next_match_idx = -1;
+ ++current_line_id;
+}
+
+/*
+ * Check for items in the stack that need their end updated.
+ * When "startofline" is TRUE the last item is always updated.
+ * When "startofline" is FALSE the item with "keepend" is forcefully updated.
+ */
+static void syn_update_ends(startofline)
+int startofline;
+{
+ stateitem_T *cur_si;
+ int i;
+ int seen_keepend;
+
+ if (startofline) {
+ /* Check for a match carried over from a previous line with a
+ * contained region. The match ends as soon as the region ends. */
+ for (i = 0; i < current_state.ga_len; ++i) {
+ cur_si = &CUR_STATE(i);
+ if (cur_si->si_idx >= 0
+ && (SYN_ITEMS(syn_block)[cur_si->si_idx]).sp_type
+ == SPTYPE_MATCH
+ && cur_si->si_m_endpos.lnum < current_lnum) {
+ cur_si->si_flags |= HL_MATCHCONT;
+ cur_si->si_m_endpos.lnum = 0;
+ cur_si->si_m_endpos.col = 0;
+ cur_si->si_h_endpos = cur_si->si_m_endpos;
+ cur_si->si_ends = TRUE;
+ }
+ }
+ }
+
+ /*
+ * Need to update the end of a start/skip/end that continues from the
+ * previous line. And regions that have "keepend", because they may
+ * influence contained items. If we've just removed "extend"
+ * (startofline == 0) then we should update ends of normal regions
+ * contained inside "keepend" because "extend" could have extended
+ * these "keepend" regions as well as contained normal regions.
+ * Then check for items ending in column 0.
+ */
+ i = current_state.ga_len - 1;
+ if (keepend_level >= 0)
+ for (; i > keepend_level; --i)
+ if (CUR_STATE(i).si_flags & HL_EXTEND)
+ break;
+
+ seen_keepend = FALSE;
+ for (; i < current_state.ga_len; ++i) {
+ cur_si = &CUR_STATE(i);
+ if ((cur_si->si_flags & HL_KEEPEND)
+ || (seen_keepend && !startofline)
+ || (i == current_state.ga_len - 1 && startofline)) {
+ cur_si->si_h_startpos.col = 0; /* start highl. in col 0 */
+ cur_si->si_h_startpos.lnum = current_lnum;
+
+ if (!(cur_si->si_flags & HL_MATCHCONT))
+ update_si_end(cur_si, (int)current_col, !startofline);
+
+ if (!startofline && (cur_si->si_flags & HL_KEEPEND))
+ seen_keepend = TRUE;
+ }
+ }
+ check_keepend();
+}
+
+/****************************************
+ * Handling of the state stack cache.
+ */
+
+/*
+ * EXPLANATION OF THE SYNTAX STATE STACK CACHE
+ *
+ * To speed up syntax highlighting, the state stack for the start of some
+ * lines is cached. These entries can be used to start parsing at that point.
+ *
+ * The stack is kept in b_sst_array[] for each buffer. There is a list of
+ * valid entries. b_sst_first points to the first one, then follow sst_next.
+ * The entries are sorted on line number. The first entry is often for line 2
+ * (line 1 always starts with an empty stack).
+ * There is also a list for free entries. This construction is used to avoid
+ * having to allocate and free memory blocks too often.
+ *
+ * When making changes to the buffer, this is logged in b_mod_*. When calling
+ * update_screen() to update the display, it will call
+ * syn_stack_apply_changes() for each displayed buffer to adjust the cached
+ * entries. The entries which are inside the changed area are removed,
+ * because they must be recomputed. Entries below the changed have their line
+ * number adjusted for deleted/inserted lines, and have their sst_change_lnum
+ * set to indicate that a check must be made if the changed lines would change
+ * the cached entry.
+ *
+ * When later displaying lines, an entry is stored for each line. Displayed
+ * lines are likely to be displayed again, in which case the state at the
+ * start of the line is needed.
+ * For not displayed lines, an entry is stored for every so many lines. These
+ * entries will be used e.g., when scrolling backwards. The distance between
+ * entries depends on the number of lines in the buffer. For small buffers
+ * the distance is fixed at SST_DIST, for large buffers there is a fixed
+ * number of entries SST_MAX_ENTRIES, and the distance is computed.
+ */
+
+static void syn_stack_free_block(block)
+synblock_T *block;
+{
+ synstate_T *p;
+
+ if (block->b_sst_array != NULL) {
+ for (p = block->b_sst_first; p != NULL; p = p->sst_next)
+ clear_syn_state(p);
+ vim_free(block->b_sst_array);
+ block->b_sst_array = NULL;
+ block->b_sst_len = 0;
+ }
+}
+/*
+ * Free b_sst_array[] for buffer "buf".
+ * Used when syntax items changed to force resyncing everywhere.
+ */
+void syn_stack_free_all(block)
+synblock_T *block;
+{
+ win_T *wp;
+
+ syn_stack_free_block(block);
+
+
+ /* When using "syntax" fold method, must update all folds. */
+ FOR_ALL_WINDOWS(wp)
+ {
+ if (wp->w_s == block && foldmethodIsSyntax(wp))
+ foldUpdateAll(wp);
+ }
+}
+
+/*
+ * Allocate the syntax state stack for syn_buf when needed.
+ * If the number of entries in b_sst_array[] is much too big or a bit too
+ * small, reallocate it.
+ * Also used to allocate b_sst_array[] for the first time.
+ */
+static void syn_stack_alloc() {
+ long len;
+ synstate_T *to, *from;
+ synstate_T *sstp;
+
+ len = syn_buf->b_ml.ml_line_count / SST_DIST + Rows * 2;
+ if (len < SST_MIN_ENTRIES)
+ len = SST_MIN_ENTRIES;
+ else if (len > SST_MAX_ENTRIES)
+ len = SST_MAX_ENTRIES;
+ if (syn_block->b_sst_len > len * 2 || syn_block->b_sst_len < len) {
+ /* Allocate 50% too much, to avoid reallocating too often. */
+ len = syn_buf->b_ml.ml_line_count;
+ len = (len + len / 2) / SST_DIST + Rows * 2;
+ if (len < SST_MIN_ENTRIES)
+ len = SST_MIN_ENTRIES;
+ else if (len > SST_MAX_ENTRIES)
+ len = SST_MAX_ENTRIES;
+
+ if (syn_block->b_sst_array != NULL) {
+ /* When shrinking the array, cleanup the existing stack.
+ * Make sure that all valid entries fit in the new array. */
+ while (syn_block->b_sst_len - syn_block->b_sst_freecount + 2 > len
+ && syn_stack_cleanup())
+ ;
+ if (len < syn_block->b_sst_len - syn_block->b_sst_freecount + 2)
+ len = syn_block->b_sst_len - syn_block->b_sst_freecount + 2;
+ }
+
+ sstp = (synstate_T *)alloc_clear((unsigned)(len * sizeof(synstate_T)));
+ if (sstp == NULL) /* out of memory! */
+ return;
+
+ to = sstp - 1;
+ if (syn_block->b_sst_array != NULL) {
+ /* Move the states from the old array to the new one. */
+ for (from = syn_block->b_sst_first; from != NULL;
+ from = from->sst_next) {
+ ++to;
+ *to = *from;
+ to->sst_next = to + 1;
+ }
+ }
+ if (to != sstp - 1) {
+ to->sst_next = NULL;
+ syn_block->b_sst_first = sstp;
+ syn_block->b_sst_freecount = len - (int)(to - sstp) - 1;
+ } else {
+ syn_block->b_sst_first = NULL;
+ syn_block->b_sst_freecount = len;
+ }
+
+ /* Create the list of free entries. */
+ syn_block->b_sst_firstfree = to + 1;
+ while (++to < sstp + len)
+ to->sst_next = to + 1;
+ (sstp + len - 1)->sst_next = NULL;
+
+ vim_free(syn_block->b_sst_array);
+ syn_block->b_sst_array = sstp;
+ syn_block->b_sst_len = len;
+ }
+}
+
+/*
+ * Check for changes in a buffer to affect stored syntax states. Uses the
+ * b_mod_* fields.
+ * Called from update_screen(), before screen is being updated, once for each
+ * displayed buffer.
+ */
+void syn_stack_apply_changes(buf)
+buf_T *buf;
+{
+ win_T *wp;
+
+ syn_stack_apply_changes_block(&buf->b_s, buf);
+
+ FOR_ALL_WINDOWS(wp)
+ {
+ if ((wp->w_buffer == buf) && (wp->w_s != &buf->b_s))
+ syn_stack_apply_changes_block(wp->w_s, buf);
+ }
+}
+
+static void syn_stack_apply_changes_block(block, buf)
+synblock_T *block;
+buf_T *buf;
+{
+ synstate_T *p, *prev, *np;
+ linenr_T n;
+
+ if (block->b_sst_array == NULL) /* nothing to do */
+ return;
+
+ prev = NULL;
+ for (p = block->b_sst_first; p != NULL; ) {
+ if (p->sst_lnum + block->b_syn_sync_linebreaks > buf->b_mod_top) {
+ n = p->sst_lnum + buf->b_mod_xlines;
+ if (n <= buf->b_mod_bot) {
+ /* this state is inside the changed area, remove it */
+ np = p->sst_next;
+ if (prev == NULL)
+ block->b_sst_first = np;
+ else
+ prev->sst_next = np;
+ syn_stack_free_entry(block, p);
+ p = np;
+ continue;
+ }
+ /* This state is below the changed area. Remember the line
+ * that needs to be parsed before this entry can be made valid
+ * again. */
+ if (p->sst_change_lnum != 0 && p->sst_change_lnum > buf->b_mod_top) {
+ if (p->sst_change_lnum + buf->b_mod_xlines > buf->b_mod_top)
+ p->sst_change_lnum += buf->b_mod_xlines;
+ else
+ p->sst_change_lnum = buf->b_mod_top;
+ }
+ if (p->sst_change_lnum == 0
+ || p->sst_change_lnum < buf->b_mod_bot)
+ p->sst_change_lnum = buf->b_mod_bot;
+
+ p->sst_lnum = n;
+ }
+ prev = p;
+ p = p->sst_next;
+ }
+}
+
+/*
+ * Reduce the number of entries in the state stack for syn_buf.
+ * Returns TRUE if at least one entry was freed.
+ */
+static int syn_stack_cleanup() {
+ synstate_T *p, *prev;
+ disptick_T tick;
+ int above;
+ int dist;
+ int retval = FALSE;
+
+ if (syn_block->b_sst_array == NULL || syn_block->b_sst_first == NULL)
+ return retval;
+
+ /* Compute normal distance between non-displayed entries. */
+ if (syn_block->b_sst_len <= Rows)
+ dist = 999999;
+ else
+ dist = syn_buf->b_ml.ml_line_count / (syn_block->b_sst_len - Rows) + 1;
+
+ /*
+ * Go through the list to find the "tick" for the oldest entry that can
+ * be removed. Set "above" when the "tick" for the oldest entry is above
+ * "b_sst_lasttick" (the display tick wraps around).
+ */
+ tick = syn_block->b_sst_lasttick;
+ above = FALSE;
+ prev = syn_block->b_sst_first;
+ for (p = prev->sst_next; p != NULL; prev = p, p = p->sst_next) {
+ if (prev->sst_lnum + dist > p->sst_lnum) {
+ if (p->sst_tick > syn_block->b_sst_lasttick) {
+ if (!above || p->sst_tick < tick)
+ tick = p->sst_tick;
+ above = TRUE;
+ } else if (!above && p->sst_tick < tick)
+ tick = p->sst_tick;
+ }
+ }
+
+ /*
+ * Go through the list to make the entries for the oldest tick at an
+ * interval of several lines.
+ */
+ prev = syn_block->b_sst_first;
+ for (p = prev->sst_next; p != NULL; prev = p, p = p->sst_next) {
+ if (p->sst_tick == tick && prev->sst_lnum + dist > p->sst_lnum) {
+ /* Move this entry from used list to free list */
+ prev->sst_next = p->sst_next;
+ syn_stack_free_entry(syn_block, p);
+ p = prev;
+ retval = TRUE;
+ }
+ }
+ return retval;
+}
+
+/*
+ * Free the allocated memory for a syn_state item.
+ * Move the entry into the free list.
+ */
+static void syn_stack_free_entry(block, p)
+synblock_T *block;
+synstate_T *p;
+{
+ clear_syn_state(p);
+ p->sst_next = block->b_sst_firstfree;
+ block->b_sst_firstfree = p;
+ ++block->b_sst_freecount;
+}
+
+/*
+ * Find an entry in the list of state stacks at or before "lnum".
+ * Returns NULL when there is no entry or the first entry is after "lnum".
+ */
+static synstate_T * syn_stack_find_entry(lnum)
+linenr_T lnum;
+{
+ synstate_T *p, *prev;
+
+ prev = NULL;
+ for (p = syn_block->b_sst_first; p != NULL; prev = p, p = p->sst_next) {
+ if (p->sst_lnum == lnum)
+ return p;
+ if (p->sst_lnum > lnum)
+ break;
+ }
+ return prev;
+}
+
+/*
+ * Try saving the current state in b_sst_array[].
+ * The current state must be valid for the start of the current_lnum line!
+ */
+static synstate_T * store_current_state() {
+ int i;
+ synstate_T *p;
+ bufstate_T *bp;
+ stateitem_T *cur_si;
+ synstate_T *sp = syn_stack_find_entry(current_lnum);
+
+ /*
+ * If the current state contains a start or end pattern that continues
+ * from the previous line, we can't use it. Don't store it then.
+ */
+ for (i = current_state.ga_len - 1; i >= 0; --i) {
+ cur_si = &CUR_STATE(i);
+ if (cur_si->si_h_startpos.lnum >= current_lnum
+ || cur_si->si_m_endpos.lnum >= current_lnum
+ || cur_si->si_h_endpos.lnum >= current_lnum
+ || (cur_si->si_end_idx
+ && cur_si->si_eoe_pos.lnum >= current_lnum))
+ break;
+ }
+ if (i >= 0) {
+ if (sp != NULL) {
+ /* find "sp" in the list and remove it */
+ if (syn_block->b_sst_first == sp)
+ /* it's the first entry */
+ syn_block->b_sst_first = sp->sst_next;
+ else {
+ /* find the entry just before this one to adjust sst_next */
+ for (p = syn_block->b_sst_first; p != NULL; p = p->sst_next)
+ if (p->sst_next == sp)
+ break;
+ if (p != NULL) /* just in case */
+ p->sst_next = sp->sst_next;
+ }
+ syn_stack_free_entry(syn_block, sp);
+ sp = NULL;
+ }
+ } else if (sp == NULL || sp->sst_lnum != current_lnum) {
+ /*
+ * Add a new entry
+ */
+ /* If no free items, cleanup the array first. */
+ if (syn_block->b_sst_freecount == 0) {
+ (void)syn_stack_cleanup();
+ /* "sp" may have been moved to the freelist now */
+ sp = syn_stack_find_entry(current_lnum);
+ }
+ /* Still no free items? Must be a strange problem... */
+ if (syn_block->b_sst_freecount == 0)
+ sp = NULL;
+ else {
+ /* Take the first item from the free list and put it in the used
+ * list, after *sp */
+ p = syn_block->b_sst_firstfree;
+ syn_block->b_sst_firstfree = p->sst_next;
+ --syn_block->b_sst_freecount;
+ if (sp == NULL) {
+ /* Insert in front of the list */
+ p->sst_next = syn_block->b_sst_first;
+ syn_block->b_sst_first = p;
+ } else {
+ /* insert in list after *sp */
+ p->sst_next = sp->sst_next;
+ sp->sst_next = p;
+ }
+ sp = p;
+ sp->sst_stacksize = 0;
+ sp->sst_lnum = current_lnum;
+ }
+ }
+ if (sp != NULL) {
+ /* When overwriting an existing state stack, clear it first */
+ clear_syn_state(sp);
+ sp->sst_stacksize = current_state.ga_len;
+ if (current_state.ga_len > SST_FIX_STATES) {
+ /* Need to clear it, might be something remaining from when the
+ * length was less than SST_FIX_STATES. */
+ ga_init2(&sp->sst_union.sst_ga, (int)sizeof(bufstate_T), 1);
+ if (ga_grow(&sp->sst_union.sst_ga, current_state.ga_len) == FAIL)
+ sp->sst_stacksize = 0;
+ else
+ sp->sst_union.sst_ga.ga_len = current_state.ga_len;
+ bp = SYN_STATE_P(&(sp->sst_union.sst_ga));
+ } else
+ bp = sp->sst_union.sst_stack;
+ for (i = 0; i < sp->sst_stacksize; ++i) {
+ bp[i].bs_idx = CUR_STATE(i).si_idx;
+ bp[i].bs_flags = CUR_STATE(i).si_flags;
+ bp[i].bs_seqnr = CUR_STATE(i).si_seqnr;
+ bp[i].bs_cchar = CUR_STATE(i).si_cchar;
+ bp[i].bs_extmatch = ref_extmatch(CUR_STATE(i).si_extmatch);
+ }
+ sp->sst_next_flags = current_next_flags;
+ sp->sst_next_list = current_next_list;
+ sp->sst_tick = display_tick;
+ sp->sst_change_lnum = 0;
+ }
+ current_state_stored = TRUE;
+ return sp;
+}
+
+/*
+ * Copy a state stack from "from" in b_sst_array[] to current_state;
+ */
+static void load_current_state(from)
+synstate_T *from;
+{
+ int i;
+ bufstate_T *bp;
+
+ clear_current_state();
+ validate_current_state();
+ keepend_level = -1;
+ if (from->sst_stacksize
+ && ga_grow(&current_state, from->sst_stacksize) != FAIL) {
+ if (from->sst_stacksize > SST_FIX_STATES)
+ bp = SYN_STATE_P(&(from->sst_union.sst_ga));
+ else
+ bp = from->sst_union.sst_stack;
+ for (i = 0; i < from->sst_stacksize; ++i) {
+ CUR_STATE(i).si_idx = bp[i].bs_idx;
+ CUR_STATE(i).si_flags = bp[i].bs_flags;
+ CUR_STATE(i).si_seqnr = bp[i].bs_seqnr;
+ CUR_STATE(i).si_cchar = bp[i].bs_cchar;
+ CUR_STATE(i).si_extmatch = ref_extmatch(bp[i].bs_extmatch);
+ if (keepend_level < 0 && (CUR_STATE(i).si_flags & HL_KEEPEND))
+ keepend_level = i;
+ CUR_STATE(i).si_ends = FALSE;
+ CUR_STATE(i).si_m_lnum = 0;
+ if (CUR_STATE(i).si_idx >= 0)
+ CUR_STATE(i).si_next_list =
+ (SYN_ITEMS(syn_block)[CUR_STATE(i).si_idx]).sp_next_list;
+ else
+ CUR_STATE(i).si_next_list = NULL;
+ update_si_attr(i);
+ }
+ current_state.ga_len = from->sst_stacksize;
+ }
+ current_next_list = from->sst_next_list;
+ current_next_flags = from->sst_next_flags;
+ current_lnum = from->sst_lnum;
+}
+
+/*
+ * Compare saved state stack "*sp" with the current state.
+ * Return TRUE when they are equal.
+ */
+static int syn_stack_equal(sp)
+synstate_T *sp;
+{
+ int i, j;
+ bufstate_T *bp;
+ reg_extmatch_T *six, *bsx;
+
+ /* First a quick check if the stacks have the same size end nextlist. */
+ if (sp->sst_stacksize == current_state.ga_len
+ && sp->sst_next_list == current_next_list) {
+ /* Need to compare all states on both stacks. */
+ if (sp->sst_stacksize > SST_FIX_STATES)
+ bp = SYN_STATE_P(&(sp->sst_union.sst_ga));
+ else
+ bp = sp->sst_union.sst_stack;
+
+ for (i = current_state.ga_len; --i >= 0; ) {
+ /* If the item has another index the state is different. */
+ if (bp[i].bs_idx != CUR_STATE(i).si_idx)
+ break;
+ if (bp[i].bs_extmatch != CUR_STATE(i).si_extmatch) {
+ /* When the extmatch pointers are different, the strings in
+ * them can still be the same. Check if the extmatch
+ * references are equal. */
+ bsx = bp[i].bs_extmatch;
+ six = CUR_STATE(i).si_extmatch;
+ /* If one of the extmatch pointers is NULL the states are
+ * different. */
+ if (bsx == NULL || six == NULL)
+ break;
+ for (j = 0; j < NSUBEXP; ++j) {
+ /* Check each referenced match string. They must all be
+ * equal. */
+ if (bsx->matches[j] != six->matches[j]) {
+ /* 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)
+ 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)
+ break;
+ }
+ }
+ if (j != NSUBEXP)
+ break;
+ }
+ }
+ if (i < 0)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*
+ * We stop parsing syntax above line "lnum". If the stored state at or below
+ * this line depended on a change before it, it now depends on the line below
+ * the last parsed line.
+ * The window looks like this:
+ * line which changed
+ * displayed line
+ * displayed line
+ * lnum -> line below window
+ */
+void syntax_end_parsing(lnum)
+linenr_T lnum;
+{
+ synstate_T *sp;
+
+ sp = syn_stack_find_entry(lnum);
+ if (sp != NULL && sp->sst_lnum < lnum)
+ sp = sp->sst_next;
+
+ if (sp != NULL && sp->sst_change_lnum != 0)
+ sp->sst_change_lnum = lnum;
+}
+
+/*
+ * End of handling of the state stack.
+ ****************************************/
+
+static void invalidate_current_state() {
+ clear_current_state();
+ current_state.ga_itemsize = 0; /* mark current_state invalid */
+ current_next_list = NULL;
+ keepend_level = -1;
+}
+
+static void validate_current_state() {
+ current_state.ga_itemsize = sizeof(stateitem_T);
+ current_state.ga_growsize = 3;
+}
+
+/*
+ * Return TRUE if the syntax at start of lnum changed since last time.
+ * This will only be called just after get_syntax_attr() for the previous
+ * line, to check if the next line needs to be redrawn too.
+ */
+int syntax_check_changed(lnum)
+linenr_T lnum;
+{
+ int retval = TRUE;
+ synstate_T *sp;
+
+ /*
+ * Check the state stack when:
+ * - lnum is just below the previously syntaxed line.
+ * - lnum is not before the lines with saved states.
+ * - lnum is not past the lines with saved states.
+ * - lnum is at or before the last changed line.
+ */
+ if (VALID_STATE(&current_state) && lnum == current_lnum + 1) {
+ sp = syn_stack_find_entry(lnum);
+ if (sp != NULL && sp->sst_lnum == lnum) {
+ /*
+ * finish the previous line (needed when not all of the line was
+ * drawn)
+ */
+ (void)syn_finish_line(FALSE);
+
+ /*
+ * Compare the current state with the previously saved state of
+ * the line.
+ */
+ if (syn_stack_equal(sp))
+ retval = FALSE;
+
+ /*
+ * Store the current state in b_sst_array[] for later use.
+ */
+ ++current_lnum;
+ (void)store_current_state();
+ }
+ }
+
+ return retval;
+}
+
+/*
+ * Finish the current line.
+ * This doesn't return any attributes, it only gets the state at the end of
+ * the line. It can start anywhere in the line, as long as the current state
+ * is valid.
+ */
+static int syn_finish_line(syncing)
+int syncing; /* called for syncing */
+{
+ stateitem_T *cur_si;
+ colnr_T prev_current_col;
+
+ if (!current_finished) {
+ while (!current_finished) {
+ (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);
+ 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;
+ check_state_ends();
+ current_col = prev_current_col;
+ }
+ ++current_col;
+ }
+ }
+ return FALSE;
+}
+
+/*
+ * Return highlight attributes for next character.
+ * Must first call syntax_start() once for the line.
+ * "col" is normally 0 for the first use in a line, and increments by one each
+ * time. It's allowed to skip characters and to stop before the end of the
+ * line. But only a "col" after a previously used column is allowed.
+ * When "can_spell" is not NULL set it to TRUE when spell-checking should be
+ * done.
+ */
+int get_syntax_attr(col, can_spell, keep_state)
+colnr_T col;
+int *can_spell;
+int keep_state; /* keep state of char at "col" */
+{
+ int attr = 0;
+
+ if (can_spell != NULL)
+ /* Default: Only do spelling when there is no @Spell cluster or when
+ * ":syn spell toplevel" was used. */
+ *can_spell = syn_block->b_syn_spell == SYNSPL_DEFAULT
+ ? (syn_block->b_spell_cluster_id == 0)
+ : (syn_block->b_syn_spell == SYNSPL_TOP);
+
+ /* check for out of memory situation */
+ if (syn_block->b_sst_array == NULL)
+ return 0;
+
+ /* After 'synmaxcol' the attribute is always zero. */
+ if (syn_buf->b_p_smc > 0 && col >= (colnr_T)syn_buf->b_p_smc) {
+ clear_current_state();
+ current_id = 0;
+ current_trans_id = 0;
+ current_flags = 0;
+ return 0;
+ }
+
+ /* Make sure current_state is valid */
+ if (INVALID_STATE(&current_state))
+ validate_current_state();
+
+ /*
+ * 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;
+ }
+
+ return attr;
+}
+
+/*
+ * Get syntax attributes for current_lnum, current_col.
+ */
+static int syn_current_attr(syncing, displaying, can_spell, keep_state)
+int syncing; /* When 1: called for syncing */
+int displaying; /* result will be displayed */
+int *can_spell; /* return: do spell checking */
+int 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 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 */
+ int idx;
+ synpat_T *spp;
+ 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;
+ regmmatch_T regmatch;
+ lpos_T pos;
+ int lc_col;
+ reg_extmatch_T *cur_extmatch = NULL;
+ 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;
+ garray_T zero_width_next_ga;
+
+ /*
+ * No character, no attributes! Past end of line?
+ * Do try matching with an empty line (could be the start of a region).
+ */
+ line = syn_getcurline();
+ if (line[current_col] == NUL && current_col != 0) {
+ /*
+ * 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);
+
+ current_finished = TRUE;
+ current_state_stored = FALSE;
+ return 0;
+ }
+
+ /* if the current or next character is NUL, we will finish the line now */
+ if (line[current_col] == NUL || line[current_col + 1] == NUL) {
+ current_finished = TRUE;
+ current_state_stored = FALSE;
+ }
+
+ /*
+ * When in the previous column there was a match but it could not be used
+ * (empty match or already matched in this column) need to try again in
+ * the next column.
+ */
+ if (try_next_column) {
+ next_match_idx = -1;
+ 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);
+
+ /* Init the list of zero-width matches with a nextlist. This is used to
+ * avoid matching the same item in the same position twice. */
+ ga_init2(&zero_width_next_ga, (int)sizeof(int), 10);
+
+ /*
+ * Repeat matching keywords and patterns, to find contained items at the
+ * same column. This stops when there are no extra matches at the current
+ * column.
+ */
+ do {
+ found_match = FALSE;
+ keep_next_list = FALSE;
+ syn_id = 0;
+
+ /*
+ * 1. Check for a current state.
+ * Only when there is no current state, or if the current state may
+ * contain other things, we need to check for keywords and patterns.
+ * Always need to check for contained items if some item has the
+ * "containedin" argument (takes extra time!).
+ */
+ if (current_state.ga_len)
+ cur_si = &CUR_STATE(current_state.ga_len - 1);
+ else
+ cur_si = NULL;
+
+ if (syn_block->b_syn_containedin || cur_si == NULL
+ || cur_si->si_cont_list != NULL) {
+ /*
+ * 2. Check for keywords, if on a keyword char after a non-keyword
+ * char. Don't do this when syncing.
+ */
+ 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);
+ if (syn_id != 0) {
+ if (push_current_state(KEYWORD_IDX) == OK) {
+ cur_si = &CUR_STATE(current_state.ga_len - 1);
+ cur_si->si_m_startcol = current_col;
+ cur_si->si_h_startpos.lnum = current_lnum;
+ cur_si->si_h_startpos.col = 0; /* starts right away */
+ cur_si->si_m_endpos.lnum = current_lnum;
+ cur_si->si_m_endpos.col = endcol;
+ cur_si->si_h_endpos.lnum = current_lnum;
+ cur_si->si_h_endpos.col = endcol;
+ cur_si->si_ends = TRUE;
+ cur_si->si_end_idx = 0;
+ cur_si->si_flags = flags;
+ cur_si->si_seqnr = next_seqnr++;
+ cur_si->si_cchar = cchar;
+ if (current_state.ga_len > 1)
+ cur_si->si_flags |=
+ CUR_STATE(current_state.ga_len - 2).si_flags
+ & HL_CONCEAL;
+ cur_si->si_id = syn_id;
+ cur_si->si_trans_id = syn_id;
+ if (flags & HL_TRANSP) {
+ if (current_state.ga_len < 2) {
+ cur_si->si_attr = 0;
+ cur_si->si_trans_id = 0;
+ } else {
+ cur_si->si_attr = CUR_STATE(
+ current_state.ga_len - 2).si_attr;
+ cur_si->si_trans_id = CUR_STATE(
+ current_state.ga_len - 2).si_trans_id;
+ }
+ } else
+ cur_si->si_attr = syn_id2attr(syn_id);
+ cur_si->si_cont_list = NULL;
+ cur_si->si_next_list = next_list;
+ check_keepend();
+ } else
+ vim_free(next_list);
+ }
+ }
+ }
+
+ /*
+ * 3. Check for patterns (only if no keyword found).
+ */
+ if (syn_id == 0 && syn_block->b_syn_patterns.ga_len) {
+ /*
+ * If we didn't check for a match yet, or we are past it, check
+ * for any match with a pattern.
+ */
+ if (next_match_idx < 0 || next_match_col < (int)current_col) {
+ /*
+ * Check all relevant patterns for a match at this
+ * position. This is complicated, because matching with a
+ * pattern takes quite a bit of time, thus we want to
+ * avoid doing it when it's not needed.
+ */
+ next_match_idx = 0; /* no match in this line yet */
+ next_match_col = MAXCOL;
+ for (idx = syn_block->b_syn_patterns.ga_len; --idx >= 0; ) {
+ spp = &(SYN_ITEMS(syn_block)[idx]);
+ if ( spp->sp_syncing == syncing
+ && (displaying || !(spp->sp_flags & HL_DISPLAY))
+ && (spp->sp_type == SPTYPE_MATCH
+ || spp->sp_type == SPTYPE_START)
+ && (current_next_list != NULL
+ ? in_id_list(NULL, current_next_list,
+ &spp->sp_syn, 0)
+ : (cur_si == NULL
+ ? !(spp->sp_flags & HL_CONTAINED)
+ : in_id_list(cur_si,
+ cur_si->si_cont_list, &spp->sp_syn,
+ spp->sp_flags & HL_CONTAINED)))) {
+ /* If we already tried matching in this line, and
+ * there isn't a match before next_match_col, skip
+ * this item. */
+ if (spp->sp_line_id == current_line_id
+ && spp->sp_startcol >= next_match_col)
+ continue;
+ spp->sp_line_id = current_line_id;
+
+ 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;
+ if (!syn_regexec(&regmatch,
+ current_lnum,
+ (colnr_T)lc_col,
+ IF_SYN_TIME(&spp->sp_time))) {
+ /* no match in this line, try another one */
+ spp->sp_startcol = MAXCOL;
+ continue;
+ }
+
+ /*
+ * Compute the first column of the match.
+ */
+ syn_add_start_off(&pos, &regmatch,
+ spp, SPO_MS_OFF, -1);
+ if (pos.lnum > current_lnum) {
+ /* must have used end of match in a next line,
+ * we can't handle that */
+ spp->sp_startcol = MAXCOL;
+ continue;
+ }
+ startcol = pos.col;
+
+ /* remember the next column where this pattern
+ * matches in the current line */
+ spp->sp_startcol = startcol;
+
+ /*
+ * If a previously found match starts at a lower
+ * column number, don't use this one.
+ */
+ if (startcol >= next_match_col)
+ continue;
+
+ /*
+ * If we matched this pattern at this position
+ * before, skip it. Must retry in the next
+ * column, because it may match from there.
+ */
+ if (did_match_already(idx, &zero_width_next_ga)) {
+ try_next_column = TRUE;
+ continue;
+ }
+
+ endpos.lnum = regmatch.endpos[0].lnum;
+ endpos.col = regmatch.endpos[0].col;
+
+ /* Compute the highlight start. */
+ syn_add_start_off(&hl_startpos, &regmatch,
+ spp, SPO_HS_OFF, -1);
+
+ /* Compute the region start. */
+ /* Default is to use the end of the match. */
+ syn_add_end_off(&eos_pos, &regmatch,
+ spp, SPO_RS_OFF, 0);
+
+ /*
+ * Grab the external submatches before they get
+ * overwritten. Reference count doesn't change.
+ */
+ unref_extmatch(cur_extmatch);
+ cur_extmatch = re_extmatch_out;
+ re_extmatch_out = NULL;
+
+ flags = 0;
+ eoe_pos.lnum = 0; /* avoid warning */
+ eoe_pos.col = 0;
+ end_idx = 0;
+ hl_endpos.lnum = 0;
+
+ /*
+ * For a "oneline" the end must be found in the
+ * same line too. Search for it after the end of
+ * the match with the start pattern. Set the
+ * resulting end positions at the same time.
+ */
+ if (spp->sp_type == SPTYPE_START
+ && (spp->sp_flags & HL_ONELINE)) {
+ lpos_T startpos;
+
+ startpos = endpos;
+ find_endpos(idx, &startpos, &endpos, &hl_endpos,
+ &flags, &eoe_pos, &end_idx, cur_extmatch);
+ if (endpos.lnum == 0)
+ continue; /* not found */
+ }
+ /*
+ * For a "match" the size must be > 0 after the
+ * end offset needs has been added. Except when
+ * syncing.
+ */
+ else if (spp->sp_type == SPTYPE_MATCH) {
+ syn_add_end_off(&hl_endpos, &regmatch, spp,
+ SPO_HE_OFF, 0);
+ syn_add_end_off(&endpos, &regmatch, spp,
+ SPO_ME_OFF, 0);
+ if (endpos.lnum == current_lnum
+ && (int)endpos.col + syncing < startcol) {
+ /*
+ * 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;
+ continue;
+ }
+ }
+
+ /*
+ * keep the best match so far in next_match_*
+ */
+ /* Highlighting must start after startpos and end
+ * before endpos. */
+ if (hl_startpos.lnum == current_lnum
+ && (int)hl_startpos.col < startcol)
+ hl_startpos.col = startcol;
+ limit_pos_zero(&hl_endpos, &endpos);
+
+ next_match_idx = idx;
+ next_match_col = startcol;
+ next_match_m_endpos = endpos;
+ next_match_h_endpos = hl_endpos;
+ next_match_h_startpos = hl_startpos;
+ next_match_flags = flags;
+ next_match_eos_pos = eos_pos;
+ next_match_eoe_pos = eoe_pos;
+ next_match_end_idx = end_idx;
+ unref_extmatch(next_match_extmatch);
+ next_match_extmatch = cur_extmatch;
+ cur_extmatch = NULL;
+ }
+ }
+ }
+
+ /*
+ * If we found a match at the current column, use it.
+ */
+ if (next_match_idx >= 0 && next_match_col == (int)current_col) {
+ synpat_T *lspp;
+
+ /* When a zero-width item matched which has a nextgroup,
+ * don't push the item but set nextgroup. */
+ lspp = &(SYN_ITEMS(syn_block)[next_match_idx]);
+ if (next_match_m_endpos.lnum == current_lnum
+ && next_match_m_endpos.col == current_col
+ && 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;
+
+ /* Add the index to a list, so that we can check
+ * later that we don't match it again (and cause an
+ * endless loop). */
+ if (ga_grow(&zero_width_next_ga, 1) == OK) {
+ ((int *)(zero_width_next_ga.ga_data))
+ [zero_width_next_ga.ga_len++] = next_match_idx;
+ }
+ next_match_idx = -1;
+ } else
+ cur_si = push_next_match(cur_si);
+ found_match = TRUE;
+ }
+ }
+ }
+
+ /*
+ * Handle searching for nextgroup match.
+ */
+ if (current_next_list != NULL && !keep_next_list) {
+ /*
+ * If a nextgroup was not found, continue looking for one if:
+ * - this is an empty line and the "skipempty" option was given
+ * - we are on white space and the "skipwhite" option was given
+ */
+ if (!found_match) {
+ line = syn_getcurline();
+ if (((current_next_flags & HL_SKIPWHITE)
+ && vim_iswhite(line[current_col]))
+ || ((current_next_flags & HL_SKIPEMPTY)
+ && *line == NUL))
+ break;
+ }
+
+ /*
+ * If a nextgroup was found: Use it, and continue looking for
+ * contained matches.
+ * If a nextgroup was not found: Continue looking for a normal
+ * match.
+ * When did set current_next_list for a zero-width item and no
+ * match was found don't loop (would get stuck).
+ */
+ current_next_list = NULL;
+ next_match_idx = -1;
+ if (!zero_width_next_list)
+ found_match = TRUE;
+ }
+
+ } while (found_match);
+
+ /*
+ * Use attributes from the current state, if within its highlighting.
+ * If not, use attributes from the current-but-one state, etc.
+ */
+ current_attr = 0;
+ current_id = 0;
+ current_trans_id = 0;
+ current_flags = 0;
+ if (cur_si != NULL) {
+ for (idx = current_state.ga_len - 1; idx >= 0; --idx) {
+ sip = &CUR_STATE(idx);
+ if ((current_lnum > sip->si_h_startpos.lnum
+ || (current_lnum == sip->si_h_startpos.lnum
+ && current_col >= sip->si_h_startpos.col))
+ && (sip->si_h_endpos.lnum == 0
+ || current_lnum < sip->si_h_endpos.lnum
+ || (current_lnum == sip->si_h_endpos.lnum
+ && current_col < sip->si_h_endpos.col))) {
+ current_attr = sip->si_attr;
+ current_id = sip->si_id;
+ current_trans_id = sip->si_trans_id;
+ current_flags = sip->si_flags;
+ current_seqnr = sip->si_seqnr;
+ current_sub_char = sip->si_cchar;
+ break;
+ }
+ }
+
+ if (can_spell != NULL) {
+ struct sp_syn sps;
+
+ /*
+ * set "can_spell" to TRUE if spell checking is supposed to be
+ * done in the current item.
+ */
+ if (syn_block->b_spell_cluster_id == 0) {
+ /* There is no @Spell cluster: Do spelling for items without
+ * @NoSpell cluster. */
+ if (syn_block->b_nospell_cluster_id == 0
+ || current_trans_id == 0)
+ *can_spell = (syn_block->b_syn_spell != SYNSPL_NOTOP);
+ else {
+ sps.inc_tag = 0;
+ sps.id = syn_block->b_nospell_cluster_id;
+ sps.cont_in_list = NULL;
+ *can_spell = !in_id_list(sip, sip->si_cont_list, &sps, 0);
+ }
+ } else {
+ /* The @Spell cluster is defined: Do spelling in items with
+ * the @Spell cluster. But not when @NoSpell is also there.
+ * At the toplevel only spell check when ":syn spell toplevel"
+ * was used. */
+ if (current_trans_id == 0)
+ *can_spell = (syn_block->b_syn_spell == SYNSPL_TOP);
+ else {
+ sps.inc_tag = 0;
+ sps.id = syn_block->b_spell_cluster_id;
+ sps.cont_in_list = NULL;
+ *can_spell = in_id_list(sip, sip->si_cont_list, &sps, 0);
+
+ if (syn_block->b_nospell_cluster_id != 0) {
+ sps.id = syn_block->b_nospell_cluster_id;
+ if (in_id_list(sip, sip->si_cont_list, &sps, 0))
+ *can_spell = FALSE;
+ }
+ }
+ }
+ }
+
+
+ /*
+ * Check for end of current state (and the states before it) at the
+ * next column. Don't do this for syncing, because we would miss a
+ * single character match.
+ * First check if the current state ends at the current column. It
+ * may be for an empty match and a containing item might end in the
+ * current column.
+ */
+ if (!syncing && !keep_state) {
+ check_state_ends();
+ if (current_state.ga_len > 0
+ && syn_getcurline()[current_col] != NUL) {
+ ++current_col;
+ check_state_ends();
+ --current_col;
+ }
+ }
+ } else if (can_spell != NULL)
+ /* Default: Only do spelling when there is no @Spell cluster or when
+ * ":syn spell toplevel" was used. */
+ *can_spell = syn_block->b_syn_spell == SYNSPL_DEFAULT
+ ? (syn_block->b_spell_cluster_id == 0)
+ : (syn_block->b_syn_spell == SYNSPL_TOP);
+
+ /* 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)))
+ current_next_list = NULL;
+
+ if (zero_width_next_ga.ga_len > 0)
+ ga_clear(&zero_width_next_ga);
+
+ /* No longer need external matches. But keep next_match_extmatch. */
+ unref_extmatch(re_extmatch_out);
+ re_extmatch_out = NULL;
+ unref_extmatch(cur_extmatch);
+
+ return current_attr;
+}
+
+
+/*
+ * Check if we already matched pattern "idx" at the current column.
+ */
+static int did_match_already(idx, gap)
+int idx;
+garray_T *gap;
+{
+ int i;
+
+ for (i = current_state.ga_len; --i >= 0; )
+ if (CUR_STATE(i).si_m_startcol == (int)current_col
+ && CUR_STATE(i).si_m_lnum == (int)current_lnum
+ && CUR_STATE(i).si_idx == idx)
+ return TRUE;
+
+ /* Zero-width matches with a nextgroup argument are not put on the syntax
+ * stack, and can only be matched once anyway. */
+ for (i = gap->ga_len; --i >= 0; )
+ if (((int *)(gap->ga_data))[i] == idx)
+ return TRUE;
+
+ return FALSE;
+}
+
+/*
+ * Push the next match onto the stack.
+ */
+static stateitem_T * push_next_match(cur_si)
+stateitem_T *cur_si;
+{
+ synpat_T *spp;
+ int save_flags;
+
+ spp = &(SYN_ITEMS(syn_block)[next_match_idx]);
+
+ /*
+ * Push the item in current_state stack;
+ */
+ if (push_current_state(next_match_idx) == OK) {
+ /*
+ * If it's a start-skip-end type that crosses lines, figure out how
+ * much it continues in this line. Otherwise just fill in the length.
+ */
+ cur_si = &CUR_STATE(current_state.ga_len - 1);
+ cur_si->si_h_startpos = next_match_h_startpos;
+ cur_si->si_m_startcol = current_col;
+ cur_si->si_m_lnum = current_lnum;
+ cur_si->si_flags = spp->sp_flags;
+ cur_si->si_seqnr = next_seqnr++;
+ cur_si->si_cchar = spp->sp_cchar;
+ if (current_state.ga_len > 1)
+ cur_si->si_flags |=
+ CUR_STATE(current_state.ga_len - 2).si_flags & HL_CONCEAL;
+ cur_si->si_next_list = spp->sp_next_list;
+ cur_si->si_extmatch = ref_extmatch(next_match_extmatch);
+ if (spp->sp_type == SPTYPE_START && !(spp->sp_flags & HL_ONELINE)) {
+ /* Try to find the end pattern in the current line */
+ update_si_end(cur_si, (int)(next_match_m_endpos.col), TRUE);
+ check_keepend();
+ } else {
+ cur_si->si_m_endpos = next_match_m_endpos;
+ cur_si->si_h_endpos = next_match_h_endpos;
+ cur_si->si_ends = TRUE;
+ cur_si->si_flags |= next_match_flags;
+ cur_si->si_eoe_pos = next_match_eoe_pos;
+ cur_si->si_end_idx = next_match_end_idx;
+ }
+ if (keepend_level < 0 && (cur_si->si_flags & HL_KEEPEND))
+ keepend_level = current_state.ga_len - 1;
+ check_keepend();
+ update_si_attr(current_state.ga_len - 1);
+
+ save_flags = cur_si->si_flags & (HL_CONCEAL | HL_CONCEALENDS);
+ /*
+ * If the start pattern has another highlight group, push another item
+ * on the stack for the start pattern.
+ */
+ if ( spp->sp_type == SPTYPE_START
+ && spp->sp_syn_match_id != 0
+ && push_current_state(next_match_idx) == OK) {
+ cur_si = &CUR_STATE(current_state.ga_len - 1);
+ cur_si->si_h_startpos = next_match_h_startpos;
+ cur_si->si_m_startcol = current_col;
+ cur_si->si_m_lnum = current_lnum;
+ cur_si->si_m_endpos = next_match_eos_pos;
+ cur_si->si_h_endpos = next_match_eos_pos;
+ cur_si->si_ends = TRUE;
+ cur_si->si_end_idx = 0;
+ cur_si->si_flags = HL_MATCH;
+ cur_si->si_seqnr = next_seqnr++;
+ cur_si->si_flags |= save_flags;
+ if (cur_si->si_flags & HL_CONCEALENDS)
+ cur_si->si_flags |= HL_CONCEAL;
+ cur_si->si_next_list = NULL;
+ check_keepend();
+ update_si_attr(current_state.ga_len - 1);
+ }
+ }
+
+ next_match_idx = -1; /* try other match next time */
+
+ return cur_si;
+}
+
+/*
+ * Check for end of current state (and the states before it).
+ */
+static void check_state_ends() {
+ stateitem_T *cur_si;
+ int had_extend;
+
+ cur_si = &CUR_STATE(current_state.ga_len - 1);
+ for (;; ) {
+ if (cur_si->si_ends
+ && (cur_si->si_m_endpos.lnum < current_lnum
+ || (cur_si->si_m_endpos.lnum == current_lnum
+ && cur_si->si_m_endpos.col <= current_col))) {
+ /*
+ * If there is an end pattern group ID, highlight the end pattern
+ * now. No need to pop the current item from the stack.
+ * Only do this if the end pattern continues beyond the current
+ * position.
+ */
+ if (cur_si->si_end_idx
+ && (cur_si->si_eoe_pos.lnum > current_lnum
+ || (cur_si->si_eoe_pos.lnum == current_lnum
+ && cur_si->si_eoe_pos.col > current_col))) {
+ cur_si->si_idx = cur_si->si_end_idx;
+ cur_si->si_end_idx = 0;
+ cur_si->si_m_endpos = cur_si->si_eoe_pos;
+ cur_si->si_h_endpos = cur_si->si_eoe_pos;
+ cur_si->si_flags |= HL_MATCH;
+ cur_si->si_seqnr = next_seqnr++;
+ if (cur_si->si_flags & HL_CONCEALENDS)
+ cur_si->si_flags |= HL_CONCEAL;
+ update_si_attr(current_state.ga_len - 1);
+
+ /* nextgroup= should not match in the end pattern */
+ current_next_list = NULL;
+
+ /* what matches next may be different now, clear it */
+ next_match_idx = 0;
+ next_match_col = MAXCOL;
+ break;
+ } else {
+ /* handle next_list, unless at end of line and no "skipnl" or
+ * "skipempty" */
+ current_next_list = cur_si->si_next_list;
+ current_next_flags = cur_si->si_flags;
+ if (!(current_next_flags & (HL_SKIPNL | HL_SKIPEMPTY))
+ && syn_getcurline()[current_col] == NUL)
+ current_next_list = NULL;
+
+ /* When the ended item has "extend", another item with
+ * "keepend" now needs to check for its end. */
+ had_extend = (cur_si->si_flags & HL_EXTEND);
+
+ pop_current_state();
+
+ if (current_state.ga_len == 0)
+ break;
+
+ if (had_extend && keepend_level >= 0) {
+ syn_update_ends(FALSE);
+ if (current_state.ga_len == 0)
+ break;
+ }
+
+ cur_si = &CUR_STATE(current_state.ga_len - 1);
+
+ /*
+ * Only for a region the search for the end continues after
+ * the end of the contained item. If the contained match
+ * included the end-of-line, break here, the region continues.
+ * Don't do this when:
+ * - "keepend" is used for the contained item
+ * - not at the end of the line (could be end="x$"me=e-1).
+ * - "excludenl" is used (HL_HAS_EOL won't be set)
+ */
+ if (cur_si->si_idx >= 0
+ && SYN_ITEMS(syn_block)[cur_si->si_idx].sp_type
+ == SPTYPE_START
+ && !(cur_si->si_flags & (HL_MATCH | HL_KEEPEND))) {
+ update_si_end(cur_si, (int)current_col, TRUE);
+ check_keepend();
+ if ((current_next_flags & HL_HAS_EOL)
+ && keepend_level < 0
+ && syn_getcurline()[current_col] == NUL)
+ break;
+ }
+ }
+ } else
+ break;
+ }
+}
+
+/*
+ * Update an entry in the current_state stack for a match or region. This
+ * fills in si_attr, si_next_list and si_cont_list.
+ */
+static void update_si_attr(idx)
+int idx;
+{
+ stateitem_T *sip = &CUR_STATE(idx);
+ synpat_T *spp;
+
+ /* This should not happen... */
+ if (sip->si_idx < 0)
+ return;
+
+ spp = &(SYN_ITEMS(syn_block)[sip->si_idx]);
+ if (sip->si_flags & HL_MATCH)
+ sip->si_id = spp->sp_syn_match_id;
+ else
+ sip->si_id = spp->sp_syn.id;
+ sip->si_attr = syn_id2attr(sip->si_id);
+ sip->si_trans_id = sip->si_id;
+ if (sip->si_flags & HL_MATCH)
+ sip->si_cont_list = NULL;
+ else
+ sip->si_cont_list = spp->sp_cont_list;
+
+ /*
+ * For transparent items, take attr from outer item.
+ * Also take cont_list, if there is none.
+ * Don't do this for the matchgroup of a start or end pattern.
+ */
+ if ((spp->sp_flags & HL_TRANSP) && !(sip->si_flags & HL_MATCH)) {
+ if (idx == 0) {
+ sip->si_attr = 0;
+ sip->si_trans_id = 0;
+ if (sip->si_cont_list == NULL)
+ sip->si_cont_list = ID_LIST_ALL;
+ } else {
+ sip->si_attr = CUR_STATE(idx - 1).si_attr;
+ sip->si_trans_id = CUR_STATE(idx - 1).si_trans_id;
+ sip->si_h_startpos = CUR_STATE(idx - 1).si_h_startpos;
+ sip->si_h_endpos = CUR_STATE(idx - 1).si_h_endpos;
+ if (sip->si_cont_list == NULL) {
+ sip->si_flags |= HL_TRANS_CONT;
+ sip->si_cont_list = CUR_STATE(idx - 1).si_cont_list;
+ }
+ }
+ }
+}
+
+/*
+ * Check the current stack for patterns with "keepend" flag.
+ * Propagate the match-end to contained items, until a "skipend" item is found.
+ */
+static void check_keepend() {
+ int i;
+ lpos_T maxpos;
+ lpos_T maxpos_h;
+ stateitem_T *sip;
+
+ /*
+ * This check can consume a lot of time; only do it from the level where
+ * there really is a keepend.
+ */
+ if (keepend_level < 0)
+ return;
+
+ /*
+ * Find the last index of an "extend" item. "keepend" items before that
+ * won't do anything. If there is no "extend" item "i" will be
+ * "keepend_level" and all "keepend" items will work normally.
+ */
+ for (i = current_state.ga_len - 1; i > keepend_level; --i)
+ if (CUR_STATE(i).si_flags & HL_EXTEND)
+ break;
+
+ maxpos.lnum = 0;
+ maxpos.col = 0;
+ maxpos_h.lnum = 0;
+ maxpos_h.col = 0;
+ for (; i < current_state.ga_len; ++i) {
+ sip = &CUR_STATE(i);
+ if (maxpos.lnum != 0) {
+ limit_pos_zero(&sip->si_m_endpos, &maxpos);
+ limit_pos_zero(&sip->si_h_endpos, &maxpos_h);
+ limit_pos_zero(&sip->si_eoe_pos, &maxpos);
+ sip->si_ends = TRUE;
+ }
+ if (sip->si_ends && (sip->si_flags & HL_KEEPEND)) {
+ if (maxpos.lnum == 0
+ || maxpos.lnum > sip->si_m_endpos.lnum
+ || (maxpos.lnum == sip->si_m_endpos.lnum
+ && maxpos.col > sip->si_m_endpos.col))
+ maxpos = sip->si_m_endpos;
+ if (maxpos_h.lnum == 0
+ || maxpos_h.lnum > sip->si_h_endpos.lnum
+ || (maxpos_h.lnum == sip->si_h_endpos.lnum
+ && maxpos_h.col > sip->si_h_endpos.col))
+ maxpos_h = sip->si_h_endpos;
+ }
+ }
+}
+
+/*
+ * Update an entry in the current_state stack for a start-skip-end pattern.
+ * This finds the end of the current item, if it's in the current line.
+ *
+ * Return the flags for the matched END.
+ */
+static void update_si_end(sip, startcol, force)
+stateitem_T *sip;
+int startcol; /* where to start searching for the end */
+int force; /* when TRUE overrule a previous end */
+{
+ lpos_T startpos;
+ lpos_T endpos;
+ lpos_T hl_endpos;
+ lpos_T end_endpos;
+ int end_idx;
+
+ /* return quickly for a keyword */
+ if (sip->si_idx < 0)
+ return;
+
+ /* Don't update when it's already done. Can be a match of an end pattern
+ * that started in a previous line. Watch out: can also be a "keepend"
+ * from a containing item. */
+ if (!force && sip->si_m_endpos.lnum >= current_lnum)
+ return;
+
+ /*
+ * We need to find the end of the region. It may continue in the next
+ * line.
+ */
+ end_idx = 0;
+ startpos.lnum = current_lnum;
+ startpos.col = startcol;
+ find_endpos(sip->si_idx, &startpos, &endpos, &hl_endpos,
+ &(sip->si_flags), &end_endpos, &end_idx, sip->si_extmatch);
+
+ if (endpos.lnum == 0) {
+ /* No end pattern matched. */
+ if (SYN_ITEMS(syn_block)[sip->si_idx].sp_flags & HL_ONELINE) {
+ /* a "oneline" never continues in the next line */
+ sip->si_ends = TRUE;
+ sip->si_m_endpos.lnum = current_lnum;
+ sip->si_m_endpos.col = (colnr_T)STRLEN(syn_getcurline());
+ } else {
+ /* continues in the next line */
+ sip->si_ends = FALSE;
+ sip->si_m_endpos.lnum = 0;
+ }
+ sip->si_h_endpos = sip->si_m_endpos;
+ } else {
+ /* match within this line */
+ sip->si_m_endpos = endpos;
+ sip->si_h_endpos = hl_endpos;
+ sip->si_eoe_pos = end_endpos;
+ sip->si_ends = TRUE;
+ sip->si_end_idx = end_idx;
+ }
+}
+
+/*
+ * Add a new state to the current state stack.
+ * It is cleared and the index set to "idx".
+ * Return FAIL if it's not possible (out of memory).
+ */
+static int push_current_state(idx)
+int idx;
+{
+ if (ga_grow(&current_state, 1) == FAIL)
+ return FAIL;
+ vim_memset(&CUR_STATE(current_state.ga_len), 0, sizeof(stateitem_T));
+ CUR_STATE(current_state.ga_len).si_idx = idx;
+ ++current_state.ga_len;
+ return OK;
+}
+
+/*
+ * Remove a state from the current_state stack.
+ */
+static void pop_current_state() {
+ if (current_state.ga_len) {
+ unref_extmatch(CUR_STATE(current_state.ga_len - 1).si_extmatch);
+ --current_state.ga_len;
+ }
+ /* after the end of a pattern, try matching a keyword or pattern */
+ next_match_idx = -1;
+
+ /* if first state with "keepend" is popped, reset keepend_level */
+ if (keepend_level >= current_state.ga_len)
+ keepend_level = -1;
+}
+
+/*
+ * Find the end of a start/skip/end syntax region after "startpos".
+ * Only checks one line.
+ * Also handles a match item that continued from a previous line.
+ * If not found, the syntax item continues in the next line. m_endpos->lnum
+ * will be 0.
+ * If found, the end of the region and the end of the highlighting is
+ * computed.
+ */
+static void find_endpos(idx, startpos, m_endpos, hl_endpos, flagsp, end_endpos,
+ end_idx, start_ext)
+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;
+ synpat_T *spp, *spp_skip;
+ int start_idx;
+ int best_idx;
+ regmmatch_T regmatch;
+ regmmatch_T best_regmatch; /* startpos/endpos of best match */
+ lpos_T pos;
+ char_u *line;
+ int had_match = FALSE;
+
+ /* just in case we are invoked for a keyword */
+ if (idx < 0)
+ return;
+
+ /*
+ * Check for being called with a START pattern.
+ * Can happen with a match that continues to the next line, because it
+ * contained a region.
+ */
+ spp = &(SYN_ITEMS(syn_block)[idx]);
+ if (spp->sp_type != SPTYPE_START) {
+ *hl_endpos = *startpos;
+ return;
+ }
+
+ /*
+ * Find the SKIP or first END pattern after the last START pattern.
+ */
+ for (;; ) {
+ spp = &(SYN_ITEMS(syn_block)[idx]);
+ if (spp->sp_type != SPTYPE_START)
+ break;
+ ++idx;
+ }
+
+ /*
+ * Lookup the SKIP pattern (if present)
+ */
+ if (spp->sp_type == SPTYPE_SKIP) {
+ spp_skip = spp;
+ ++idx;
+ } else
+ spp_skip = NULL;
+
+ /* Setup external matches for syn_regexec(). */
+ unref_extmatch(re_extmatch_in);
+ re_extmatch_in = ref_extmatch(start_ext);
+
+ matchcol = startpos->col; /* start looking for a match at sstart */
+ start_idx = idx; /* remember the first END pattern. */
+ best_regmatch.startpos[0].col = 0; /* avoid compiler warning */
+ for (;; ) {
+ /*
+ * Find end pattern that matches first after "matchcol".
+ */
+ best_idx = -1;
+ for (idx = start_idx; idx < syn_block->b_syn_patterns.ga_len; ++idx) {
+ int lc_col = matchcol;
+
+ spp = &(SYN_ITEMS(syn_block)[idx]);
+ if (spp->sp_type != SPTYPE_END) /* past last END pattern */
+ break;
+ lc_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;
+ if (syn_regexec(&regmatch, startpos->lnum, lc_col,
+ IF_SYN_TIME(&spp->sp_time))) {
+ if (best_idx == -1 || regmatch.startpos[0].col
+ < best_regmatch.startpos[0].col) {
+ best_idx = idx;
+ best_regmatch.startpos[0] = regmatch.startpos[0];
+ best_regmatch.endpos[0] = regmatch.endpos[0];
+ }
+ }
+ }
+
+ /*
+ * If all end patterns have been tried, and there is no match, the
+ * item continues until end-of-line.
+ */
+ if (best_idx == -1)
+ break;
+
+ /*
+ * If the skip pattern matches before the end pattern,
+ * continue searching after the skip pattern.
+ */
+ if (spp_skip != NULL) {
+ int lc_col = matchcol - spp_skip->sp_offsets[SPO_LC_OFF];
+
+ if (lc_col < 0)
+ lc_col = 0;
+ regmatch.rmm_ic = spp_skip->sp_ic;
+ regmatch.regprog = spp_skip->sp_prog;
+ if (syn_regexec(&regmatch, startpos->lnum, lc_col,
+ IF_SYN_TIME(&spp_skip->sp_time))
+ && regmatch.startpos[0].col
+ <= best_regmatch.startpos[0].col) {
+ /* Add offset to skip pattern match */
+ syn_add_end_off(&pos, &regmatch, spp_skip, SPO_ME_OFF, 1);
+
+ /* If the skip pattern goes on to the next line, there is no
+ * match with an end pattern in this line. */
+ if (pos.lnum > startpos->lnum)
+ break;
+
+ line = ml_get_buf(syn_buf, startpos->lnum, FALSE);
+
+ /* take care of an empty match or negative offset */
+ if (pos.col <= matchcol)
+ ++matchcol;
+ else if (pos.col <= regmatch.endpos[0].col)
+ matchcol = pos.col;
+ else
+ /* Be careful not to jump over the NUL at the end-of-line */
+ for (matchcol = regmatch.endpos[0].col;
+ line[matchcol] != NUL && matchcol < pos.col;
+ ++matchcol)
+ ;
+
+ /* if the skip pattern includes end-of-line, break here */
+ if (line[matchcol] == NUL)
+ break;
+
+ continue; /* start with first end pattern again */
+ }
+ }
+
+ /*
+ * Match from start pattern to end pattern.
+ * Correct for match and highlight offset of end pattern.
+ */
+ spp = &(SYN_ITEMS(syn_block)[best_idx]);
+ syn_add_end_off(m_endpos, &best_regmatch, spp, SPO_ME_OFF, 1);
+ /* can't end before the start */
+ if (m_endpos->lnum == startpos->lnum && m_endpos->col < startpos->col)
+ m_endpos->col = startpos->col;
+
+ syn_add_end_off(end_endpos, &best_regmatch, spp, SPO_HE_OFF, 1);
+ /* can't end before the start */
+ if (end_endpos->lnum == startpos->lnum
+ && end_endpos->col < startpos->col)
+ end_endpos->col = startpos->col;
+ /* can't end after the match */
+ limit_pos(end_endpos, m_endpos);
+
+ /*
+ * If the end group is highlighted differently, adjust the pointers.
+ */
+ if (spp->sp_syn_match_id != spp->sp_syn.id && spp->sp_syn_match_id != 0) {
+ *end_idx = best_idx;
+ if (spp->sp_off_flags & (1 << (SPO_RE_OFF + SPO_COUNT))) {
+ hl_endpos->lnum = best_regmatch.endpos[0].lnum;
+ hl_endpos->col = best_regmatch.endpos[0].col;
+ } else {
+ hl_endpos->lnum = best_regmatch.startpos[0].lnum;
+ hl_endpos->col = best_regmatch.startpos[0].col;
+ }
+ hl_endpos->col += spp->sp_offsets[SPO_RE_OFF];
+
+ /* can't end before the start */
+ if (hl_endpos->lnum == startpos->lnum
+ && hl_endpos->col < startpos->col)
+ hl_endpos->col = startpos->col;
+ limit_pos(hl_endpos, m_endpos);
+
+ /* now the match ends where the highlighting ends, it is turned
+ * into the matchgroup for the end */
+ *m_endpos = *hl_endpos;
+ } else {
+ *end_idx = 0;
+ *hl_endpos = *end_endpos;
+ }
+
+ *flagsp = spp->sp_flags;
+
+ had_match = TRUE;
+ break;
+ }
+
+ /* no match for an END pattern in this line */
+ if (!had_match)
+ m_endpos->lnum = 0;
+
+ /* Remove external matches. */
+ unref_extmatch(re_extmatch_in);
+ re_extmatch_in = NULL;
+}
+
+/*
+ * Limit "pos" not to be after "limit".
+ */
+static void limit_pos(pos, limit)
+lpos_T *pos;
+lpos_T *limit;
+{
+ if (pos->lnum > limit->lnum)
+ *pos = *limit;
+ else if (pos->lnum == limit->lnum && pos->col > limit->col)
+ pos->col = limit->col;
+}
+
+/*
+ * Limit "pos" not to be after "limit", unless pos->lnum is zero.
+ */
+static void limit_pos_zero(pos, limit)
+lpos_T *pos;
+lpos_T *limit;
+{
+ if (pos->lnum == 0)
+ *pos = *limit;
+ else
+ limit_pos(pos, limit);
+}
+
+/*
+ * Add offset to matched text for end of match or highlight.
+ */
+static void syn_add_end_off(result, regmatch, spp, idx, extra)
+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;
+ int off;
+ char_u *base;
+ char_u *p;
+
+ if (spp->sp_off_flags & (1 << idx)) {
+ result->lnum = regmatch->startpos[0].lnum;
+ col = regmatch->startpos[0].col;
+ off = spp->sp_offsets[idx] + extra;
+ } else {
+ result->lnum = regmatch->endpos[0].lnum;
+ col = regmatch->endpos[0].col;
+ off = spp->sp_offsets[idx];
+ }
+ /* Don't go past the end of the line. Matters for "rs=e+2" when there
+ * is a matchgroup. Watch out for match with last NL in the buffer. */
+ if (result->lnum > syn_buf->b_ml.ml_line_count)
+ col = 0;
+ else if (off != 0) {
+ 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);
+ }
+ col = (int)(p - base);
+ }
+ result->col = col;
+}
+
+/*
+ * Add offset to matched text for start of match or highlight.
+ * Avoid resulting column to become negative.
+ */
+static void syn_add_start_off(result, regmatch, spp, idx, extra)
+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 col;
+ int off;
+ char_u *base;
+ char_u *p;
+
+ if (spp->sp_off_flags & (1 << (idx + SPO_COUNT))) {
+ result->lnum = regmatch->endpos[0].lnum;
+ col = regmatch->endpos[0].col;
+ off = spp->sp_offsets[idx] + extra;
+ } else {
+ result->lnum = regmatch->startpos[0].lnum;
+ col = regmatch->startpos[0].col;
+ off = spp->sp_offsets[idx];
+ }
+ if (result->lnum > syn_buf->b_ml.ml_line_count) {
+ /* a "\n" at the end of the pattern may take us below the last line */
+ result->lnum = syn_buf->b_ml.ml_line_count;
+ col = (int)STRLEN(ml_get_buf(syn_buf, result->lnum, FALSE));
+ }
+ if (off != 0) {
+ 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);
+ }
+ col = (int)(p - base);
+ }
+ result->col = col;
+}
+
+/*
+ * Get current line in syntax buffer.
+ */
+static char_u * syn_getcurline() {
+ return ml_get_buf(syn_buf, current_lnum, FALSE);
+}
+
+/*
+ * Call vim_regexec() to find a match with "rmp" in "syn_buf".
+ * Returns TRUE when there is a match.
+ */
+static int syn_regexec(rmp, lnum, col, st)
+regmmatch_T *rmp;
+linenr_T lnum;
+colnr_T col;
+syn_time_T *st UNUSED;
+{
+ int r;
+ proftime_T pt;
+
+ if (syn_time_on)
+ profile_start(&pt);
+
+ rmp->rmm_maxcol = syn_buf->b_p_smc;
+ r = vim_regexec_multi(rmp, syn_win, syn_buf, lnum, col, NULL);
+
+ if (syn_time_on) {
+ profile_end(&pt);
+ profile_add(&st->total, &pt);
+ if (profile_cmp(&pt, &st->slowest) < 0)
+ st->slowest = pt;
+ ++st->count;
+ if (r > 0)
+ ++st->match;
+ }
+
+ if (r > 0) {
+ rmp->startpos[0].lnum += lnum;
+ rmp->endpos[0].lnum += lnum;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*
+ * 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(line, startcol, endcolp, flagsp, next_listp, cur_si,
+ ccharp)
+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 UNUSED; /* conceal substitution char */
+{
+ keyentry_T *kp;
+ char_u *kwp;
+ int round;
+ int kwlen;
+ char_u keyword[MAXKEYWLEN + 1]; /* assume max. keyword len is 80 */
+ hashtab_T *ht;
+ hashitem_T *hi;
+
+ /* Find first character after the keyword. First character was already
+ * checked. */
+ kwp = line + startcol;
+ kwlen = 0;
+ do {
+ if (has_mbyte)
+ kwlen += (*mb_ptr2len)(kwp + kwlen);
+ else
+ ++kwlen;
+ } while (vim_iswordp_buf(kwp + kwlen, syn_buf));
+
+ if (kwlen > MAXKEYWLEN)
+ return 0;
+
+ /*
+ * Must make a copy of the keyword, so we can add a NUL and make it
+ * lowercase.
+ */
+ vim_strncpy(keyword, kwp, kwlen);
+
+ /*
+ * Try twice:
+ * 1. matching case
+ * 2. ignoring case
+ */
+ for (round = 1; round <= 2; ++round) {
+ ht = round == 1 ? &syn_block->b_keywtab : &syn_block->b_keywtab_ic;
+ if (ht->ht_used == 0)
+ continue;
+ if (round == 2) /* ignore case */
+ (void)str_foldcase(kwp, kwlen, keyword, MAXKEYWLEN + 1);
+
+ /*
+ * Find keywords that match. There can be several with different
+ * attributes.
+ * When current_next_list is non-zero accept only that group, otherwise:
+ * Accept a not-contained keyword at toplevel.
+ * Accept a keyword at other levels only if it is in the contains list.
+ */
+ hi = hash_find(ht, keyword);
+ if (!HASHITEM_EMPTY(hi))
+ for (kp = HI2KE(hi); kp != NULL; kp = kp->ke_next) {
+ if (current_next_list != 0
+ ? in_id_list(NULL, current_next_list, &kp->k_syn, 0)
+ : (cur_si == NULL
+ ? !(kp->flags & HL_CONTAINED)
+ : in_id_list(cur_si, cur_si->si_cont_list,
+ &kp->k_syn, kp->flags & HL_CONTAINED))) {
+ *endcolp = startcol + kwlen;
+ *flagsp = kp->flags;
+ *next_listp = kp->next_list;
+ *ccharp = kp->k_char;
+ return kp->k_syn.id;
+ }
+ }
+ }
+ return 0;
+}
+
+/*
+ * Handle ":syntax conceal" command.
+ */
+static void syn_cmd_conceal(eap, syncing)
+exarg_T *eap UNUSED;
+int syncing UNUSED;
+{
+ char_u *arg = eap->arg;
+ char_u *next;
+
+ eap->nextcmd = find_nextcmd(arg);
+ if (eap->skip)
+ 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
+ EMSG2(_("E390: Illegal argument: %s"), arg);
+}
+
+/*
+ * Handle ":syntax case" command.
+ */
+static void syn_cmd_case(eap, syncing)
+exarg_T *eap;
+int syncing UNUSED;
+{
+ char_u *arg = eap->arg;
+ char_u *next;
+
+ eap->nextcmd = find_nextcmd(arg);
+ if (eap->skip)
+ 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
+ EMSG2(_("E390: Illegal argument: %s"), arg);
+}
+
+/*
+ * Handle ":syntax spell" command.
+ */
+static void syn_cmd_spell(eap, syncing)
+exarg_T *eap;
+int syncing UNUSED;
+{
+ char_u *arg = eap->arg;
+ char_u *next;
+
+ eap->nextcmd = find_nextcmd(arg);
+ if (eap->skip)
+ return;
+
+ next = skiptowhite(arg);
+ 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;
+ else if (STRNICMP(arg, "default", 7) == 0 && next - arg == 7)
+ curwin->w_s->b_syn_spell = SYNSPL_DEFAULT;
+ else
+ EMSG2(_("E390: Illegal argument: %s"), arg);
+}
+
+/*
+ * Clear all syntax info for one buffer.
+ */
+void syntax_clear(block)
+synblock_T *block;
+{
+ int i;
+
+ 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;
+
+ /* free the keywords */
+ clear_keywtab(&block->b_keywtab);
+ clear_keywtab(&block->b_keywtab_ic);
+
+ /* free the syntax patterns */
+ for (i = block->b_syn_patterns.ga_len; --i >= 0; )
+ syn_clear_pattern(block, i);
+ ga_clear(&block->b_syn_patterns);
+
+ /* free the syntax clusters */
+ for (i = block->b_syn_clusters.ga_len; --i >= 0; )
+ syn_clear_cluster(block, i);
+ ga_clear(&block->b_syn_clusters);
+ block->b_spell_cluster_id = 0;
+ block->b_nospell_cluster_id = 0;
+
+ block->b_syn_sync_flags = 0;
+ block->b_syn_sync_minlines = 0;
+ block->b_syn_sync_maxlines = 0;
+ block->b_syn_sync_linebreaks = 0;
+
+ vim_regfree(block->b_syn_linecont_prog);
+ block->b_syn_linecont_prog = NULL;
+ vim_free(block->b_syn_linecont_pat);
+ block->b_syn_linecont_pat = NULL;
+ block->b_syn_folditems = 0;
+
+ /* free the stored states */
+ syn_stack_free_all(block);
+ invalidate_current_state();
+
+ /* Reset the counter for ":syn include" */
+ running_syn_inc_tag = 0;
+}
+
+/*
+ * Get rid of ownsyntax for window "wp".
+ */
+void reset_synblock(wp)
+win_T *wp;
+{
+ if (wp->w_s != &wp->w_buffer->b_s) {
+ syntax_clear(wp->w_s);
+ vim_free(wp->w_s);
+ wp->w_s = &wp->w_buffer->b_s;
+ }
+}
+
+/*
+ * Clear syncing info for one buffer.
+ */
+static void syntax_sync_clear() {
+ int i;
+
+ /* free the syntax patterns */
+ for (i = curwin->w_s->b_syn_patterns.ga_len; --i >= 0; )
+ if (SYN_ITEMS(curwin->w_s)[i].sp_syncing)
+ syn_remove_pattern(curwin->w_s, i);
+
+ curwin->w_s->b_syn_sync_flags = 0;
+ curwin->w_s->b_syn_sync_minlines = 0;
+ curwin->w_s->b_syn_sync_maxlines = 0;
+ curwin->w_s->b_syn_sync_linebreaks = 0;
+
+ vim_regfree(curwin->w_s->b_syn_linecont_prog);
+ curwin->w_s->b_syn_linecont_prog = NULL;
+ vim_free(curwin->w_s->b_syn_linecont_pat);
+ curwin->w_s->b_syn_linecont_pat = NULL;
+
+ syn_stack_free_all(curwin->w_s); /* Need to recompute all syntax. */
+}
+
+/*
+ * Remove one pattern from the buffer's pattern list.
+ */
+static void syn_remove_pattern(block, idx)
+synblock_T *block;
+int idx;
+{
+ synpat_T *spp;
+
+ spp = &(SYN_ITEMS(block)[idx]);
+ if (spp->sp_flags & HL_FOLD)
+ --block->b_syn_folditems;
+ syn_clear_pattern(block, idx);
+ mch_memmove(spp, spp + 1,
+ sizeof(synpat_T) * (block->b_syn_patterns.ga_len - idx - 1));
+ --block->b_syn_patterns.ga_len;
+}
+
+/*
+ * Clear and free one syntax pattern. When clearing all, must be called from
+ * last to first!
+ */
+static void syn_clear_pattern(block, i)
+synblock_T *block;
+int i;
+{
+ vim_free(SYN_ITEMS(block)[i].sp_pattern);
+ vim_regfree(SYN_ITEMS(block)[i].sp_prog);
+ /* Only free sp_cont_list and sp_next_list of first start pattern */
+ if (i == 0 || SYN_ITEMS(block)[i - 1].sp_type != SPTYPE_START) {
+ vim_free(SYN_ITEMS(block)[i].sp_cont_list);
+ vim_free(SYN_ITEMS(block)[i].sp_next_list);
+ vim_free(SYN_ITEMS(block)[i].sp_syn.cont_in_list);
+ }
+}
+
+/*
+ * Clear and free one syntax cluster.
+ */
+static void syn_clear_cluster(block, i)
+synblock_T *block;
+int i;
+{
+ vim_free(SYN_CLSTR(block)[i].scl_name);
+ vim_free(SYN_CLSTR(block)[i].scl_name_u);
+ vim_free(SYN_CLSTR(block)[i].scl_list);
+}
+
+/*
+ * Handle ":syntax clear" command.
+ */
+static void syn_cmd_clear(eap, syncing)
+exarg_T *eap;
+int syncing;
+{
+ char_u *arg = eap->arg;
+ char_u *arg_end;
+ int id;
+
+ eap->nextcmd = find_nextcmd(arg);
+ if (eap->skip)
+ return;
+
+ /*
+ * We have to disable this within ":syn include @group filename",
+ * because otherwise @group would get deleted.
+ * Only required for Vim 5.x syntax files, 6.0 ones don't contain ":syn
+ * clear".
+ */
+ if (curwin->w_s->b_syn_topgrp != 0)
+ return;
+
+ if (ends_excmd(*arg)) {
+ /*
+ * No argument: Clear all syntax items.
+ */
+ if (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);
+ }
+ } else {
+ /*
+ * Clear the group IDs that are in the argument.
+ */
+ while (!ends_excmd(*arg)) {
+ arg_end = skiptowhite(arg);
+ if (*arg == '@') {
+ id = syn_scl_namen2id(arg + 1, (int)(arg_end - arg - 1));
+ if (id == 0) {
+ 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;
+
+ vim_free(SYN_CLSTR(curwin->w_s)[scl_id].scl_list);
+ SYN_CLSTR(curwin->w_s)[scl_id].scl_list = NULL;
+ }
+ } else {
+ id = syn_namen2id(arg, (int)(arg_end - arg));
+ if (id == 0) {
+ EMSG2(_(e_nogroup), arg);
+ break;
+ } else
+ syn_clear_one(id, syncing);
+ }
+ arg = skipwhite(arg_end);
+ }
+ }
+ redraw_curbuf_later(SOME_VALID);
+ syn_stack_free_all(curwin->w_s); /* Need to recompute all syntax. */
+}
+
+/*
+ * Clear one syntax group for the current buffer.
+ */
+static void syn_clear_one(id, syncing)
+int id;
+int syncing;
+{
+ synpat_T *spp;
+ int idx;
+
+ /* Clear keywords only when not ":syn sync clear group-name" */
+ if (!syncing) {
+ (void)syn_clear_keyword(id, &curwin->w_s->b_keywtab);
+ (void)syn_clear_keyword(id, &curwin->w_s->b_keywtab_ic);
+ }
+
+ /* clear the patterns for "id" */
+ for (idx = curwin->w_s->b_syn_patterns.ga_len; --idx >= 0; ) {
+ spp = &(SYN_ITEMS(curwin->w_s)[idx]);
+ if (spp->sp_syn.id != id || spp->sp_syncing != syncing)
+ continue;
+ syn_remove_pattern(curwin->w_s, idx);
+ }
+}
+
+/*
+ * Handle ":syntax on" command.
+ */
+static void syn_cmd_on(eap, syncing)
+exarg_T *eap;
+int syncing UNUSED;
+{
+ syn_cmd_onoff(eap, "syntax");
+}
+
+/*
+ * Handle ":syntax enable" command.
+ */
+static void syn_cmd_enable(eap, syncing)
+exarg_T *eap;
+int syncing UNUSED;
+{
+ set_internal_string_var((char_u *)"syntax_cmd", (char_u *)"enable");
+ syn_cmd_onoff(eap, "syntax");
+ do_unlet((char_u *)"g:syntax_cmd", TRUE);
+}
+
+/*
+ * Handle ":syntax reset" command.
+ */
+static void syn_cmd_reset(eap, syncing)
+exarg_T *eap;
+int syncing UNUSED;
+{
+ eap->nextcmd = check_nextcmd(eap->arg);
+ if (!eap->skip) {
+ set_internal_string_var((char_u *)"syntax_cmd", (char_u *)"reset");
+ do_cmdline_cmd((char_u *)"runtime! syntax/syncolor.vim");
+ do_unlet((char_u *)"g:syntax_cmd", TRUE);
+ }
+}
+
+/*
+ * Handle ":syntax manual" command.
+ */
+static void syn_cmd_manual(eap, syncing)
+exarg_T *eap;
+int syncing UNUSED;
+{
+ syn_cmd_onoff(eap, "manual");
+}
+
+/*
+ * Handle ":syntax off" command.
+ */
+static void syn_cmd_off(eap, syncing)
+exarg_T *eap;
+int syncing UNUSED;
+{
+ syn_cmd_onoff(eap, "nosyntax");
+}
+
+static void syn_cmd_onoff(eap, name)
+exarg_T *eap;
+char *name;
+{
+ char_u buf[100];
+
+ eap->nextcmd = check_nextcmd(eap->arg);
+ if (!eap->skip) {
+ STRCPY(buf, "so ");
+ vim_snprintf((char *)buf + 3, sizeof(buf) - 3, SYNTAX_FNAME, name);
+ do_cmdline_cmd(buf);
+ }
+}
+
+/*
+ * Handle ":syntax [list]" command: list current syntax words.
+ */
+static void syn_cmd_list(eap, syncing)
+exarg_T *eap;
+int syncing; /* when TRUE: list syncing items */
+{
+ char_u *arg = eap->arg;
+ int id;
+ char_u *arg_end;
+
+ eap->nextcmd = find_nextcmd(arg);
+ if (eap->skip)
+ return;
+
+ if (!syntax_present(curwin)) {
+ MSG(_(msg_no_items));
+ return;
+ }
+
+ if (syncing) {
+ if (curwin->w_s->b_syn_sync_flags & SF_CCOMMENT) {
+ MSG_PUTS(_("syncing on C-style comments"));
+ syn_lines_msg();
+ syn_match_msg();
+ return;
+ } else if (!(curwin->w_s->b_syn_sync_flags & SF_MATCH)) {
+ if (curwin->w_s->b_syn_sync_minlines == 0)
+ MSG_PUTS(_("no syncing"));
+ else {
+ MSG_PUTS(_("syncing starts "));
+ msg_outnum(curwin->w_s->b_syn_sync_minlines);
+ MSG_PUTS(_(" lines before top line"));
+ syn_match_msg();
+ }
+ return;
+ }
+ MSG_PUTS_TITLE(_("\n--- Syntax sync items ---"));
+ if (curwin->w_s->b_syn_sync_minlines > 0
+ || curwin->w_s->b_syn_sync_maxlines > 0
+ || curwin->w_s->b_syn_sync_linebreaks > 0) {
+ MSG_PUTS(_("\nsyncing on items"));
+ syn_lines_msg();
+ syn_match_msg();
+ }
+ } else
+ MSG_PUTS_TITLE(_("\n--- Syntax items ---"));
+ if (ends_excmd(*arg)) {
+ /*
+ * No argument: List all group IDs and all syntax clusters.
+ */
+ for (id = 1; id <= highlight_ga.ga_len && !got_int; ++id)
+ syn_list_one(id, syncing, FALSE);
+ for (id = 0; id < curwin->w_s->b_syn_clusters.ga_len && !got_int; ++id)
+ syn_list_cluster(id);
+ } else {
+ /*
+ * List the group IDs and syntax clusters that are in the argument.
+ */
+ while (!ends_excmd(*arg) && !got_int) {
+ arg_end = skiptowhite(arg);
+ if (*arg == '@') {
+ id = syn_scl_namen2id(arg + 1, (int)(arg_end - arg - 1));
+ if (id == 0)
+ EMSG2(_("E392: No such syntax cluster: %s"), arg);
+ else
+ syn_list_cluster(id - SYNID_CLUSTER);
+ } else {
+ id = syn_namen2id(arg, (int)(arg_end - arg));
+ if (id == 0)
+ EMSG2(_(e_nogroup), arg);
+ else
+ syn_list_one(id, syncing, TRUE);
+ }
+ arg = skipwhite(arg_end);
+ }
+ }
+ eap->nextcmd = check_nextcmd(arg);
+}
+
+static void syn_lines_msg() {
+ if (curwin->w_s->b_syn_sync_maxlines > 0
+ || curwin->w_s->b_syn_sync_minlines > 0) {
+ MSG_PUTS("; ");
+ if (curwin->w_s->b_syn_sync_minlines > 0) {
+ MSG_PUTS(_("minimal "));
+ msg_outnum(curwin->w_s->b_syn_sync_minlines);
+ if (curwin->w_s->b_syn_sync_maxlines)
+ MSG_PUTS(", ");
+ }
+ if (curwin->w_s->b_syn_sync_maxlines > 0) {
+ MSG_PUTS(_("maximal "));
+ msg_outnum(curwin->w_s->b_syn_sync_maxlines);
+ }
+ MSG_PUTS(_(" lines before top line"));
+ }
+}
+
+static void syn_match_msg() {
+ if (curwin->w_s->b_syn_sync_linebreaks > 0) {
+ MSG_PUTS(_("; match "));
+ msg_outnum(curwin->w_s->b_syn_sync_linebreaks);
+ MSG_PUTS(_(" line breaks"));
+ }
+}
+
+static int last_matchgroup;
+
+struct name_list {
+ int flag;
+ char *name;
+};
+
+static void syn_list_flags __ARGS((struct name_list *nl, int flags, int attr));
+
+/*
+ * List one syntax item, for ":syntax" or "syntax list syntax_name".
+ */
+static void syn_list_one(id, syncing, link_only)
+int id;
+int syncing; /* when TRUE: list syncing items */
+int link_only; /* when TRUE; list link-only too */
+{
+ int attr;
+ int idx;
+ int did_header = FALSE;
+ synpat_T *spp;
+ static struct name_list namelist1[] =
+ {
+ {HL_DISPLAY, "display"},
+ {HL_CONTAINED, "contained"},
+ {HL_ONELINE, "oneline"},
+ {HL_KEEPEND, "keepend"},
+ {HL_EXTEND, "extend"},
+ {HL_EXCLUDENL, "excludenl"},
+ {HL_TRANSP, "transparent"},
+ {HL_FOLD, "fold"},
+ {HL_CONCEAL, "conceal"},
+ {HL_CONCEALENDS, "concealends"},
+ {0, NULL}
+ };
+ static struct name_list namelist2[] =
+ {
+ {HL_SKIPWHITE, "skipwhite"},
+ {HL_SKIPNL, "skipnl"},
+ {HL_SKIPEMPTY, "skipempty"},
+ {0, NULL}
+ };
+
+ attr = hl_attr(HLF_D); /* highlight like directories */
+
+ /* 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_ic,
+ did_header, attr);
+ }
+
+ /* list the patterns for "id" */
+ for (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)
+ continue;
+
+ (void)syn_list_header(did_header, 999, id);
+ did_header = TRUE;
+ last_matchgroup = 0;
+ if (spp->sp_type == SPTYPE_MATCH) {
+ put_pattern("match", ' ', spp, attr);
+ msg_putchar(' ');
+ } else if (spp->sp_type == SPTYPE_START) {
+ while (SYN_ITEMS(curwin->w_s)[idx].sp_type == SPTYPE_START)
+ put_pattern("start", '=', &SYN_ITEMS(curwin->w_s)[idx++], attr);
+ if (SYN_ITEMS(curwin->w_s)[idx].sp_type == SPTYPE_SKIP)
+ put_pattern("skip", '=', &SYN_ITEMS(curwin->w_s)[idx++], attr);
+ while (idx < curwin->w_s->b_syn_patterns.ga_len
+ && SYN_ITEMS(curwin->w_s)[idx].sp_type == SPTYPE_END)
+ put_pattern("end", '=', &SYN_ITEMS(curwin->w_s)[idx++], attr);
+ --idx;
+ msg_putchar(' ');
+ }
+ 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_syn.cont_in_list != NULL)
+ put_id_list((char_u *)"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);
+ 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);
+ msg_putchar(' ');
+ if (spp->sp_sync_idx >= 0)
+ msg_outtrans(HL_TABLE()[SYN_ITEMS(curwin->w_s)
+ [spp->sp_sync_idx].sp_syn.id - 1].sg_name);
+ else
+ MSG_PUTS("NONE");
+ msg_putchar(' ');
+ }
+ }
+
+ /* 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_putchar(' ');
+ msg_outtrans(HL_TABLE()[HL_TABLE()[id - 1].sg_link - 1].sg_name);
+ }
+}
+
+static void syn_list_flags(nlist, flags, attr)
+struct name_list *nlist;
+int flags;
+int attr;
+{
+ int i;
+
+ for (i = 0; nlist[i].flag != 0; ++i)
+ if (flags & nlist[i].flag) {
+ msg_puts_attr((char_u *)nlist[i].name, attr);
+ msg_putchar(' ');
+ }
+}
+
+/*
+ * List one syntax cluster, for ":syntax" or "syntax list syntax_name".
+ */
+static void syn_list_cluster(id)
+int id;
+{
+ int endcol = 15;
+
+ /* slight hack: roughly duplicate the guts of syn_list_header() */
+ msg_putchar('\n');
+ msg_outtrans(SYN_CLSTR(curwin->w_s)[id].scl_name);
+
+ if (msg_col >= endcol) /* output at least one space */
+ endcol = msg_col + 1;
+ if (Columns <= endcol) /* avoid hang for tiny window */
+ endcol = Columns - 1;
+
+ 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));
+ } else {
+ msg_puts_attr((char_u *)"cluster", hl_attr(HLF_D));
+ msg_puts((char_u *)"=NONE");
+ }
+}
+
+static void put_id_list(name, list, attr)
+char_u *name;
+short *list;
+int attr;
+{
+ short *p;
+
+ msg_puts_attr(name, attr);
+ msg_putchar('=');
+ for (p = list; *p; ++p) {
+ if (*p >= SYNID_ALLBUT && *p < SYNID_TOP) {
+ if (p[1])
+ MSG_PUTS("ALLBUT");
+ else
+ MSG_PUTS("ALL");
+ } else if (*p >= SYNID_TOP && *p < SYNID_CONTAINED) {
+ MSG_PUTS("TOP");
+ } else if (*p >= SYNID_CONTAINED && *p < SYNID_CLUSTER) {
+ MSG_PUTS("CONTAINED");
+ } else if (*p >= SYNID_CLUSTER) {
+ short scl_id = *p - SYNID_CLUSTER;
+
+ msg_putchar('@');
+ msg_outtrans(SYN_CLSTR(curwin->w_s)[scl_id].scl_name);
+ } else
+ msg_outtrans(HL_TABLE()[*p - 1].sg_name);
+ if (p[1])
+ msg_putchar(',');
+ }
+ msg_putchar(' ');
+}
+
+static void put_pattern(s, c, spp, attr)
+char *s;
+int c;
+synpat_T *spp;
+int attr;
+{
+ long n;
+ int mask;
+ int first;
+ static char *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_putchar('=');
+ if (last_matchgroup == 0)
+ msg_outtrans((char_u *)"NONE");
+ else
+ msg_outtrans(HL_TABLE()[last_matchgroup - 1].sg_name);
+ msg_putchar(' ');
+ }
+
+ /* output the name of the pattern and an '=' or ' ' */
+ msg_puts_attr((char_u *)s, attr);
+ msg_putchar(c);
+
+ /* output the pattern, in between a char that is not in the pattern */
+ for (i = 0; vim_strchr(spp->sp_pattern, sepchars[i]) != NULL; )
+ if (sepchars[++i] == NUL) {
+ i = 0; /* no good char found, just use the first one */
+ break;
+ }
+ msg_putchar(sepchars[i]);
+ 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);
+ if (spp->sp_off_flags & (mask + (mask << SPO_COUNT))) {
+ if (!first)
+ msg_putchar(','); /* separate with commas */
+ msg_puts((char_u *)spo_name_tab[i]);
+ n = spp->sp_offsets[i];
+ if (i != SPO_LC_OFF) {
+ if (spp->sp_off_flags & mask)
+ msg_putchar('s');
+ else
+ msg_putchar('e');
+ if (n > 0)
+ msg_putchar('+');
+ }
+ if (n || i == SPO_LC_OFF)
+ msg_outnum(n);
+ 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(id, ht, did_header, attr)
+int id;
+hashtab_T *ht;
+int did_header; /* header has already been printed */
+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;
+ 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) {
+ if (!HASHITEM_EMPTY(hi)) {
+ --todo;
+ for (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)
+ || prev_skipwhite != (kp->flags & HL_SKIPWHITE)
+ || prev_skipempty != (kp->flags & HL_SKIPEMPTY)
+ || prev_cont_in_list != kp->k_syn.cont_in_list
+ || prev_next_list != kp->next_list)
+ outlen = 9999;
+ else
+ outlen = (int)STRLEN(kp->keyword);
+ /* output "contained" and "nextgroup" on each line */
+ if (syn_list_header(did_header, outlen, id)) {
+ prev_contained = 0;
+ prev_next_list = NULL;
+ prev_cont_in_list = NULL;
+ prev_skipnl = 0;
+ prev_skipwhite = 0;
+ prev_skipempty = 0;
+ }
+ did_header = TRUE;
+ if (prev_contained != (kp->flags & HL_CONTAINED)) {
+ msg_puts_attr((char_u *)"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);
+ 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);
+ msg_putchar(' ');
+ prev_next_list = kp->next_list;
+ if (kp->flags & HL_SKIPNL) {
+ msg_puts_attr((char_u *)"skipnl", attr);
+ msg_putchar(' ');
+ prev_skipnl = (kp->flags & HL_SKIPNL);
+ }
+ if (kp->flags & HL_SKIPWHITE) {
+ msg_puts_attr((char_u *)"skipwhite", attr);
+ msg_putchar(' ');
+ prev_skipwhite = (kp->flags & HL_SKIPWHITE);
+ }
+ if (kp->flags & HL_SKIPEMPTY) {
+ msg_puts_attr((char_u *)"skipempty", attr);
+ msg_putchar(' ');
+ prev_skipempty = (kp->flags & HL_SKIPEMPTY);
+ }
+ }
+ msg_outtrans(kp->keyword);
+ }
+ }
+ }
+ }
+
+ return did_header;
+}
+
+static void syn_clear_keyword(id, ht)
+int id;
+hashtab_T *ht;
+{
+ hashitem_T *hi;
+ keyentry_T *kp;
+ keyentry_T *kp_prev;
+ keyentry_T *kp_next;
+ int todo;
+
+ hash_lock(ht);
+ todo = (int)ht->ht_used;
+ for (hi = ht->ht_array; todo > 0; ++hi) {
+ if (!HASHITEM_EMPTY(hi)) {
+ --todo;
+ kp_prev = NULL;
+ for (kp = HI2KE(hi); kp != NULL; ) {
+ if (kp->k_syn.id == id) {
+ kp_next = kp->ke_next;
+ if (kp_prev == NULL) {
+ if (kp_next == NULL)
+ hash_remove(ht, hi);
+ else
+ hi->hi_key = KE2HIKEY(kp_next);
+ } else
+ kp_prev->ke_next = kp_next;
+ vim_free(kp->next_list);
+ vim_free(kp->k_syn.cont_in_list);
+ vim_free(kp);
+ kp = kp_next;
+ } else {
+ kp_prev = kp;
+ kp = kp->ke_next;
+ }
+ }
+ }
+ }
+ hash_unlock(ht);
+}
+
+/*
+ * Clear a whole keyword table.
+ */
+static void clear_keywtab(ht)
+hashtab_T *ht;
+{
+ hashitem_T *hi;
+ int todo;
+ keyentry_T *kp;
+ keyentry_T *kp_next;
+
+ todo = (int)ht->ht_used;
+ for (hi = ht->ht_array; todo > 0; ++hi) {
+ if (!HASHITEM_EMPTY(hi)) {
+ --todo;
+ for (kp = HI2KE(hi); kp != NULL; kp = kp_next) {
+ kp_next = kp->ke_next;
+ vim_free(kp->next_list);
+ vim_free(kp->k_syn.cont_in_list);
+ vim_free(kp);
+ }
+ }
+ }
+ hash_clear(ht);
+ hash_init(ht);
+}
+
+/*
+ * Add a keyword to the list of keywords.
+ */
+static void add_keyword(name, id, flags, cont_in_list, next_list, conceal_char)
+char_u *name; /* name of keyword */
+int id; /* group ID for this keyword */
+int flags; /* flags for this keyword */
+short *cont_in_list; /* containedin for this keyword */
+short *next_list; /* nextgroup for this keyword */
+int conceal_char;
+{
+ keyentry_T *kp;
+ hashtab_T *ht;
+ hashitem_T *hi;
+ char_u *name_ic;
+ long_u hash;
+ char_u name_folded[MAXKEYWLEN + 1];
+
+ if (curwin->w_s->b_syn_ic)
+ name_ic = str_foldcase(name, (int)STRLEN(name),
+ name_folded, MAXKEYWLEN + 1);
+ else
+ name_ic = name;
+ kp = (keyentry_T *)alloc((int)(sizeof(keyentry_T) + STRLEN(name_ic)));
+ if (kp == NULL)
+ return;
+ STRCPY(kp->keyword, name_ic);
+ kp->k_syn.id = id;
+ kp->k_syn.inc_tag = current_syn_inc_tag;
+ kp->flags = flags;
+ kp->k_char = conceal_char;
+ kp->k_syn.cont_in_list = copy_id_list(cont_in_list);
+ if (cont_in_list != NULL)
+ curwin->w_s->b_syn_containedin = TRUE;
+ kp->next_list = copy_id_list(next_list);
+
+ if (curwin->w_s->b_syn_ic)
+ ht = &curwin->w_s->b_keywtab_ic;
+ else
+ ht = &curwin->w_s->b_keywtab;
+
+ hash = hash_hash(kp->keyword);
+ hi = hash_lookup(ht, kp->keyword, hash);
+ if (HASHITEM_EMPTY(hi)) {
+ /* new keyword, add to hashtable */
+ kp->ke_next = NULL;
+ hash_add_item(ht, hi, kp->keyword, hash);
+ } else {
+ /* keyword already exists, prepend to list */
+ kp->ke_next = HI2KE(hi);
+ hi->hi_key = KE2HIKEY(kp);
+ }
+}
+
+/*
+ * Get the start and end of the group name argument.
+ * Return a pointer to the first argument.
+ * Return NULL if the end of the command was found instead of further args.
+ */
+static char_u * get_group_name(arg, name_end)
+char_u *arg; /* start of the argument */
+char_u **name_end; /* pointer to end of the name */
+{
+ char_u *rest;
+
+ *name_end = skiptowhite(arg);
+ rest = skipwhite(*name_end);
+
+ /*
+ * Check if there are enough arguments. The first argument may be a
+ * pattern, where '|' is allowed, so only check for NUL.
+ */
+ if (ends_excmd(*arg) || *rest == NUL)
+ return NULL;
+ return rest;
+}
+
+/*
+ * Check for syntax command option arguments.
+ * This can be called at any place in the list of arguments, and just picks
+ * out the arguments that are known. Can be called several times in a row to
+ * collect all options in between other arguments.
+ * Return a pointer to the next argument (which isn't an option).
+ * Return NULL for any error;
+ */
+static char_u * get_syn_options(arg, opt, conceal_char)
+char_u *arg; /* next argument to be checked */
+syn_opt_arg_T *opt; /* various things */
+int *conceal_char UNUSED;
+{
+ char_u *gname_start, *gname;
+ int syn_id;
+ int len;
+ char *p;
+ int i;
+ int fidx;
+ static struct flag {
+ char *name;
+ int argtype;
+ int flags;
+ } flagtab[] = { {"cCoOnNtTaAiInNeEdD", 0, HL_CONTAINED},
+ {"oOnNeElLiInNeE", 0, HL_ONELINE},
+ {"kKeEeEpPeEnNdD", 0, HL_KEEPEND},
+ {"eExXtTeEnNdD", 0, HL_EXTEND},
+ {"eExXcClLuUdDeEnNlL", 0, HL_EXCLUDENL},
+ {"tTrRaAnNsSpPaArReEnNtT", 0, HL_TRANSP},
+ {"sSkKiIpPnNlL", 0, HL_SKIPNL},
+ {"sSkKiIpPwWhHiItTeE", 0, HL_SKIPWHITE},
+ {"sSkKiIpPeEmMpPtTyY", 0, HL_SKIPEMPTY},
+ {"gGrRoOuUpPhHeErReE", 0, HL_SYNC_HERE},
+ {"gGrRoOuUpPtThHeErReE", 0, HL_SYNC_THERE},
+ {"dDiIsSpPlLaAyY", 0, HL_DISPLAY},
+ {"fFoOlLdD", 0, HL_FOLD},
+ {"cCoOnNcCeEaAlL", 0, HL_CONCEAL},
+ {"cCoOnNcCeEaAlLeEnNdDsS", 0, HL_CONCEALENDS},
+ {"cCcChHaArR", 11, 0},
+ {"cCoOnNtTaAiInNsS", 1, 0},
+ {"cCoOnNtTaAiInNeEdDiInN", 2, 0},
+ {"nNeExXtTgGrRoOuUpP", 3, 0},};
+ static char *first_letters = "cCoOkKeEtTsSgGdDfFnN";
+
+ if (arg == NULL) /* already detected error */
+ return NULL;
+
+ if (curwin->w_s->b_syn_conceal)
+ opt->flags |= HL_CONCEAL;
+
+ for (;; ) {
+ /*
+ * This is used very often when a large number of keywords is defined.
+ * Need to skip quickly when no option name is found.
+ * Also avoid tolower(), it's slow.
+ */
+ if (strchr(first_letters, *arg) == NULL)
+ break;
+
+ for (fidx = sizeof(flagtab) / sizeof(struct flag); --fidx >= 0; ) {
+ p = flagtab[fidx].name;
+ 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 && (vim_iswhite(arg[len])
+ || (flagtab[fidx].argtype > 0
+ ? arg[len] == '='
+ : ends_excmd(arg[len])))) {
+ if (opt->keyword
+ && (flagtab[fidx].flags == HL_DISPLAY
+ || flagtab[fidx].flags == HL_FOLD
+ || flagtab[fidx].flags == HL_EXTEND))
+ /* treat "display", "fold" and "extend" as a keyword */
+ fidx = -1;
+ break;
+ }
+ }
+ if (fidx < 0) /* no match found */
+ break;
+
+ if (flagtab[fidx].argtype == 1) {
+ if (!opt->has_cont_list) {
+ EMSG(_("E395: contains argument not accepted here"));
+ return NULL;
+ }
+ if (get_id_list(&arg, 8, &opt->cont_list) == FAIL)
+ return NULL;
+ } else if (flagtab[fidx].argtype == 2) {
+ if (get_id_list(&arg, 11, &opt->cont_in_list) == FAIL)
+ return NULL;
+ } else if (flagtab[fidx].argtype == 3) {
+ if (get_id_list(&arg, 9, &opt->next_list) == 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];
+ }
+ if (!vim_isprintc_strict(*conceal_char)) {
+ EMSG(_("E844: invalid cchar value"));
+ return NULL;
+ }
+ arg = skipwhite(arg + 7);
+ } else {
+ opt->flags |= flagtab[fidx].flags;
+ arg = skipwhite(arg + len);
+
+ if (flagtab[fidx].flags == HL_SYNC_HERE
+ || flagtab[fidx].flags == HL_SYNC_THERE) {
+ if (opt->sync_idx == NULL) {
+ EMSG(_("E393: group[t]here not accepted here"));
+ return NULL;
+ }
+ gname_start = arg;
+ arg = skiptowhite(arg);
+ if (gname_start == arg)
+ return NULL;
+ gname = vim_strnsave(gname_start, (int)(arg - gname_start));
+ if (gname == NULL)
+ return NULL;
+ if (STRCMP(gname, "NONE") == 0)
+ *opt->sync_idx = NONE_IDX;
+ else {
+ syn_id = syn_name2id(gname);
+ for (i = curwin->w_s->b_syn_patterns.ga_len; --i >= 0; )
+ if (SYN_ITEMS(curwin->w_s)[i].sp_syn.id == syn_id
+ && SYN_ITEMS(curwin->w_s)[i].sp_type == SPTYPE_START) {
+ *opt->sync_idx = i;
+ break;
+ }
+ if (i < 0) {
+ EMSG2(_("E394: Didn't find region item for %s"), gname);
+ vim_free(gname);
+ return NULL;
+ }
+ }
+
+ vim_free(gname);
+ arg = skipwhite(arg);
+ } else if (flagtab[fidx].flags == HL_FOLD
+ && foldmethodIsSyntax(curwin))
+ /* Need to update folds later. */
+ foldUpdateAll(curwin);
+ }
+ }
+
+ return arg;
+}
+
+/*
+ * Adjustments to syntax item when declared in a ":syn include"'d file.
+ * Set the contained flag, and if the item is not already contained, add it
+ * to the specified top-level group, if any.
+ */
+static void syn_incl_toplevel(id, flagsp)
+int id;
+int *flagsp;
+{
+ if ((*flagsp & HL_CONTAINED) || curwin->w_s->b_syn_topgrp == 0)
+ 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 = (short *)alloc((unsigned)(2 * sizeof(short)));
+ int tlg_id = curwin->w_s->b_syn_topgrp - SYNID_CLUSTER;
+
+ if (grp_list != NULL) {
+ grp_list[0] = id;
+ grp_list[1] = 0;
+ syn_combine_list(&SYN_CLSTR(curwin->w_s)[tlg_id].scl_list, &grp_list,
+ CLUSTER_ADD);
+ }
+ }
+}
+
+/*
+ * Handle ":syntax include [@{group-name}] filename" command.
+ */
+static void syn_cmd_include(eap, syncing)
+exarg_T *eap;
+int syncing UNUSED;
+{
+ char_u *arg = eap->arg;
+ int sgl_id = 1;
+ char_u *group_name_end;
+ char_u *rest;
+ char_u *errormsg = NULL;
+ int prev_toplvl_grp;
+ int prev_syn_inc_tag;
+ int source = FALSE;
+
+ eap->nextcmd = find_nextcmd(arg);
+ if (eap->skip)
+ return;
+
+ if (arg[0] == '@') {
+ ++arg;
+ rest = get_group_name(arg, &group_name_end);
+ if (rest == NULL) {
+ EMSG((char_u *)_("E397: Filename required"));
+ return;
+ }
+ sgl_id = syn_check_cluster(arg, (int)(group_name_end - arg));
+ if (sgl_id == 0)
+ return;
+ /* separate_nextcmd() and expand_filename() depend on this */
+ eap->arg = rest;
+ }
+
+ /*
+ * Everything that's left, up to the next command, should be the
+ * filename to include.
+ */
+ eap->argt |= (XFILE | NOSPC);
+ separate_nextcmd(eap);
+ if (*eap->arg == '<' || *eap->arg == '$' || mch_isFullName(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);
+ return;
+ }
+ }
+
+ /*
+ * Save and restore the existing top-level grouplist id and ":syn
+ * include" tag around the actual inclusion.
+ */
+ if (running_syn_inc_tag >= MAX_SYN_INC_TAG) {
+ EMSG((char_u *)_("E847: Too many syntax includes"));
+ return;
+ }
+ prev_syn_inc_tag = current_syn_inc_tag;
+ current_syn_inc_tag = ++running_syn_inc_tag;
+ prev_toplvl_grp = curwin->w_s->b_syn_topgrp;
+ curwin->w_s->b_syn_topgrp = sgl_id;
+ if (source ? do_source(eap->arg, FALSE, DOSO_NONE) == FAIL
+ : source_runtime(eap->arg, TRUE) == FAIL)
+ EMSG2(_(e_notopen), eap->arg);
+ curwin->w_s->b_syn_topgrp = prev_toplvl_grp;
+ current_syn_inc_tag = prev_syn_inc_tag;
+}
+
+/*
+ * Handle ":syntax keyword {group-name} [{option}] keyword .." command.
+ */
+static void syn_cmd_keyword(eap, syncing)
+exarg_T *eap;
+int syncing UNUSED;
+{
+ char_u *arg = eap->arg;
+ char_u *group_name_end;
+ int syn_id;
+ char_u *rest;
+ char_u *keyword_copy = NULL;
+ char_u *p;
+ char_u *kw;
+ syn_opt_arg_T syn_opt_arg;
+ int cnt;
+ int conceal_char = NUL;
+
+ 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 */
+ keyword_copy = alloc((unsigned)STRLEN(rest) + 1);
+ 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);
+ if (rest == NULL || ends_excmd(*rest))
+ break;
+ /* Copy the keyword, removing backslashes, and add a NUL. */
+ while (*rest != NUL && !vim_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);
+
+ /*
+ * 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);
+ kw = p + 2; /* skip over the NUL */
+ break;
+ }
+ if (p[1] == ']') {
+ kw = p + 1; /* skip over the "]" */
+ break;
+ }
+ if (has_mbyte) {
+ int l = (*mb_ptr2len)(p + 1);
+
+ mch_memmove(p, p + 1, l);
+ p += l;
+ } else {
+ p[0] = p[1];
+ ++p;
+ }
+ }
+ }
+ }
+
+ vim_free(keyword_copy);
+ vim_free(syn_opt_arg.cont_in_list);
+ vim_free(syn_opt_arg.next_list);
+ }
+ }
+
+ if (rest != NULL)
+ eap->nextcmd = check_nextcmd(rest);
+ else
+ EMSG2(_(e_invarg2), arg);
+
+ redraw_curbuf_later(SOME_VALID);
+ syn_stack_free_all(curwin->w_s); /* Need to recompute all syntax. */
+}
+
+/*
+ * Handle ":syntax match {name} [{options}] {pattern} [{options}]".
+ *
+ * Also ":syntax sync match {name} [[grouphere | groupthere] {group-name}] .."
+ */
+static void syn_cmd_match(eap, syncing)
+exarg_T *eap;
+int syncing; /* TRUE for ":syntax sync match .. " */
+{
+ char_u *arg = eap->arg;
+ char_u *group_name_end;
+ char_u *rest;
+ synpat_T item; /* the item found in the line */
+ int syn_id;
+ int idx;
+ syn_opt_arg_T syn_opt_arg;
+ int sync_idx = 0;
+ int conceal_char = NUL;
+
+ /* Isolate the group name, check for validity */
+ rest = get_group_name(arg, &group_name_end);
+
+ /* Get options before the pattern */
+ syn_opt_arg.flags = 0;
+ syn_opt_arg.keyword = FALSE;
+ syn_opt_arg.sync_idx = syncing ? &sync_idx : NULL;
+ 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);
+
+ /* get the pattern. */
+ init_syn_patterns();
+ vim_memset(&item, 0, sizeof(item));
+ rest = get_syn_pattern(rest, &item);
+ 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);
+
+ if (rest != NULL) { /* all arguments are valid */
+ /*
+ * Check for trailing command and illegal trailing arguments.
+ */
+ eap->nextcmd = check_nextcmd(rest);
+ if (!ends_excmd(*rest) || eap->skip)
+ rest = NULL;
+ else if (ga_grow(&curwin->w_s->b_syn_patterns, 1) != FAIL
+ && (syn_id = syn_check_group(arg,
+ (int)(group_name_end - arg))) != 0) {
+ syn_incl_toplevel(syn_id, &syn_opt_arg.flags);
+ /*
+ * Store the pattern in the syn_items list
+ */
+ idx = curwin->w_s->b_syn_patterns.ga_len;
+ SYN_ITEMS(curwin->w_s)[idx] = item;
+ SYN_ITEMS(curwin->w_s)[idx].sp_syncing = syncing;
+ SYN_ITEMS(curwin->w_s)[idx].sp_type = SPTYPE_MATCH;
+ SYN_ITEMS(curwin->w_s)[idx].sp_syn.id = syn_id;
+ SYN_ITEMS(curwin->w_s)[idx].sp_syn.inc_tag = current_syn_inc_tag;
+ SYN_ITEMS(curwin->w_s)[idx].sp_flags = syn_opt_arg.flags;
+ SYN_ITEMS(curwin->w_s)[idx].sp_sync_idx = sync_idx;
+ SYN_ITEMS(curwin->w_s)[idx].sp_cont_list = syn_opt_arg.cont_list;
+ SYN_ITEMS(curwin->w_s)[idx].sp_syn.cont_in_list =
+ syn_opt_arg.cont_in_list;
+ SYN_ITEMS(curwin->w_s)[idx].sp_cchar = conceal_char;
+ if (syn_opt_arg.cont_in_list != NULL)
+ curwin->w_s->b_syn_containedin = TRUE;
+ SYN_ITEMS(curwin->w_s)[idx].sp_next_list = syn_opt_arg.next_list;
+ ++curwin->w_s->b_syn_patterns.ga_len;
+
+ /* remember that we found a match for syncing on */
+ if (syn_opt_arg.flags & (HL_SYNC_HERE|HL_SYNC_THERE))
+ curwin->w_s->b_syn_sync_flags |= SF_MATCH;
+ if (syn_opt_arg.flags & HL_FOLD)
+ ++curwin->w_s->b_syn_folditems;
+
+ redraw_curbuf_later(SOME_VALID);
+ syn_stack_free_all(curwin->w_s); /* Need to recompute all syntax. */
+ return; /* don't free the progs and patterns now */
+ }
+ }
+
+ /*
+ * Something failed, free the allocated memory.
+ */
+ vim_regfree(item.sp_prog);
+ vim_free(item.sp_pattern);
+ vim_free(syn_opt_arg.cont_list);
+ vim_free(syn_opt_arg.cont_in_list);
+ vim_free(syn_opt_arg.next_list);
+
+ if (rest == NULL)
+ EMSG2(_(e_invarg2), arg);
+}
+
+/*
+ * Handle ":syntax region {group-name} [matchgroup={group-name}]
+ * start {start} .. [skip {skip}] end {end} .. [{options}]".
+ */
+static void syn_cmd_region(eap, syncing)
+exarg_T *eap;
+int syncing; /* TRUE for ":syntax sync region .." */
+{
+ char_u *arg = eap->arg;
+ char_u *group_name_end;
+ char_u *rest; /* next arg, NULL on error */
+ char_u *key_end;
+ char_u *key = NULL;
+ char_u *p;
+ int item;
+#define ITEM_START 0
+#define ITEM_SKIP 1
+#define ITEM_END 2
+#define ITEM_MATCHGROUP 3
+ struct pat_ptr {
+ synpat_T *pp_synp; /* pointer to syn_pattern */
+ int pp_matchgroup_id; /* matchgroup ID */
+ struct pat_ptr *pp_next; /* pointer to next pat_ptr */
+ } *(pat_ptrs[3]);
+ /* patterns found in the line */
+ struct pat_ptr *ppp;
+ struct pat_ptr *ppp_next;
+ int pat_count = 0; /* nr of syn_patterns found */
+ int syn_id;
+ int matchgroup_id = 0;
+ int not_enough = FALSE; /* not enough arguments */
+ int illegal = FALSE; /* illegal arguments */
+ int success = FALSE;
+ int idx;
+ syn_opt_arg_T syn_opt_arg;
+ int conceal_char = NUL;
+
+ /* Isolate the group name, check for validity */
+ rest = get_group_name(arg, &group_name_end);
+
+ pat_ptrs[0] = NULL;
+ pat_ptrs[1] = NULL;
+ pat_ptrs[2] = NULL;
+
+ init_syn_patterns();
+
+ syn_opt_arg.flags = 0;
+ syn_opt_arg.keyword = FALSE;
+ syn_opt_arg.sync_idx = NULL;
+ 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.
+ */
+ 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))
+ break;
+
+ /* must be a pattern or matchgroup then */
+ key_end = rest;
+ while (*key_end && !vim_iswhite(*key_end) && *key_end != '=')
+ ++key_end;
+ vim_free(key);
+ key = vim_strnsave_up(rest, (int)(key_end - rest));
+ if (key == NULL) { /* out of memory */
+ rest = NULL;
+ break;
+ }
+ if (STRCMP(key, "MATCHGROUP") == 0)
+ item = ITEM_MATCHGROUP;
+ else if (STRCMP(key, "START") == 0)
+ item = ITEM_START;
+ 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;
+ break;
+ }
+ item = ITEM_SKIP;
+ } else
+ break;
+ rest = skipwhite(key_end);
+ if (*rest != '=') {
+ rest = NULL;
+ EMSG2(_("E398: Missing '=': %s"), arg);
+ break;
+ }
+ rest = skipwhite(rest + 1);
+ if (*rest == NUL) {
+ not_enough = TRUE;
+ break;
+ }
+
+ if (item == ITEM_MATCHGROUP) {
+ p = skiptowhite(rest);
+ if ((p - rest == 4 && STRNCMP(rest, "NONE", 4) == 0) || eap->skip)
+ matchgroup_id = 0;
+ else {
+ matchgroup_id = syn_check_group(rest, (int)(p - rest));
+ if (matchgroup_id == 0) {
+ illegal = TRUE;
+ break;
+ }
+ }
+ rest = skipwhite(p);
+ } else {
+ /*
+ * Allocate room for a syn_pattern, and link it in the list of
+ * syn_patterns for this item, at the start (because the list is
+ * used from end to start).
+ */
+ ppp = (struct pat_ptr *)alloc((unsigned)sizeof(struct pat_ptr));
+ if (ppp == NULL) {
+ rest = NULL;
+ break;
+ }
+ ppp->pp_next = pat_ptrs[item];
+ pat_ptrs[item] = ppp;
+ ppp->pp_synp = (synpat_T *)alloc_clear((unsigned)sizeof(synpat_T));
+ if (ppp->pp_synp == NULL) {
+ rest = NULL;
+ break;
+ }
+
+ /*
+ * 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)
+ 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))
+ ppp->pp_synp->sp_flags |= HL_HAS_EOL;
+ ppp->pp_matchgroup_id = matchgroup_id;
+ ++pat_count;
+ }
+ }
+ vim_free(key);
+ if (illegal || not_enough)
+ rest = NULL;
+
+ /*
+ * Must have a "start" and "end" pattern.
+ */
+ if (rest != NULL && (pat_ptrs[ITEM_START] == NULL ||
+ pat_ptrs[ITEM_END] == NULL)) {
+ not_enough = TRUE;
+ rest = NULL;
+ }
+
+ if (rest != NULL) {
+ /*
+ * Check for trailing garbage or command.
+ * If OK, add the item.
+ */
+ eap->nextcmd = check_nextcmd(rest);
+ if (!ends_excmd(*rest) || eap->skip)
+ rest = NULL;
+ else if (ga_grow(&(curwin->w_s->b_syn_patterns), pat_count) != FAIL
+ && (syn_id = syn_check_group(arg,
+ (int)(group_name_end - arg))) != 0) {
+ syn_incl_toplevel(syn_id, &syn_opt_arg.flags);
+ /*
+ * Store the start/skip/end in the syn_items list
+ */
+ idx = curwin->w_s->b_syn_patterns.ga_len;
+ for (item = ITEM_START; item <= ITEM_END; ++item) {
+ for (ppp = pat_ptrs[item]; ppp != NULL; ppp = ppp->pp_next) {
+ SYN_ITEMS(curwin->w_s)[idx] = *(ppp->pp_synp);
+ SYN_ITEMS(curwin->w_s)[idx].sp_syncing = syncing;
+ SYN_ITEMS(curwin->w_s)[idx].sp_type =
+ (item == ITEM_START) ? SPTYPE_START :
+ (item == ITEM_SKIP) ? SPTYPE_SKIP : SPTYPE_END;
+ SYN_ITEMS(curwin->w_s)[idx].sp_flags |= syn_opt_arg.flags;
+ SYN_ITEMS(curwin->w_s)[idx].sp_syn.id = syn_id;
+ SYN_ITEMS(curwin->w_s)[idx].sp_syn.inc_tag =
+ current_syn_inc_tag;
+ SYN_ITEMS(curwin->w_s)[idx].sp_syn_match_id =
+ ppp->pp_matchgroup_id;
+ SYN_ITEMS(curwin->w_s)[idx].sp_cchar = conceal_char;
+ if (item == ITEM_START) {
+ SYN_ITEMS(curwin->w_s)[idx].sp_cont_list =
+ syn_opt_arg.cont_list;
+ SYN_ITEMS(curwin->w_s)[idx].sp_syn.cont_in_list =
+ syn_opt_arg.cont_in_list;
+ if (syn_opt_arg.cont_in_list != NULL)
+ curwin->w_s->b_syn_containedin = TRUE;
+ SYN_ITEMS(curwin->w_s)[idx].sp_next_list =
+ syn_opt_arg.next_list;
+ }
+ ++curwin->w_s->b_syn_patterns.ga_len;
+ ++idx;
+ if (syn_opt_arg.flags & HL_FOLD)
+ ++curwin->w_s->b_syn_folditems;
+ }
+ }
+
+ redraw_curbuf_later(SOME_VALID);
+ syn_stack_free_all(curwin->w_s); /* Need to recompute all syntax. */
+ success = TRUE; /* don't free the progs and patterns now */
+ }
+ }
+
+ /*
+ * Free the allocated memory.
+ */
+ for (item = ITEM_START; item <= ITEM_END; ++item)
+ for (ppp = pat_ptrs[item]; ppp != NULL; ppp = ppp_next) {
+ if (!success) {
+ vim_regfree(ppp->pp_synp->sp_prog);
+ vim_free(ppp->pp_synp->sp_pattern);
+ }
+ vim_free(ppp->pp_synp);
+ ppp_next = ppp->pp_next;
+ vim_free(ppp);
+ }
+
+ if (!success) {
+ vim_free(syn_opt_arg.cont_list);
+ vim_free(syn_opt_arg.cont_in_list);
+ vim_free(syn_opt_arg.next_list);
+ if (not_enough)
+ EMSG2(_("E399: Not enough arguments: syntax region %s"), arg);
+ else if (illegal || rest == NULL)
+ EMSG2(_(e_invarg2), arg);
+ }
+}
+
+/*
+ * A simple syntax group ID comparison function suitable for use in qsort()
+ */
+static int syn_compare_stub(v1, v2)
+const void *v1;
+const void *v2;
+{
+ const short *s1 = v1;
+ const short *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(clstr1, clstr2, list_op)
+short **clstr1;
+short **clstr2;
+int list_op;
+{
+ int count1 = 0;
+ int count2 = 0;
+ short *g1;
+ short *g2;
+ short *clstr = NULL;
+ int count;
+ int round;
+
+ /*
+ * Handle degenerate cases.
+ */
+ if (*clstr2 == NULL)
+ return;
+ if (*clstr1 == NULL || list_op == CLUSTER_REPLACE) {
+ if (list_op == CLUSTER_REPLACE)
+ vim_free(*clstr1);
+ if (list_op == CLUSTER_REPLACE || list_op == CLUSTER_ADD)
+ *clstr1 = *clstr2;
+ else
+ vim_free(*clstr2);
+ return;
+ }
+
+ 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);
+
+ /*
+ * 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++) {
+ g1 = *clstr1;
+ g2 = *clstr2;
+ count = 0;
+
+ /*
+ * First, loop through the lists until one of them is empty.
+ */
+ while (*g1 && *g2) {
+ /*
+ * We always want to add from the first list.
+ */
+ if (*g1 < *g2) {
+ if (round == 2)
+ clstr[count] = *g1;
+ count++;
+ g1++;
+ continue;
+ }
+ /*
+ * We only want to add from the second list if we're adding the
+ * lists.
+ */
+ if (list_op == CLUSTER_ADD) {
+ if (round == 2)
+ clstr[count] = *g2;
+ count++;
+ }
+ if (*g1 == *g2)
+ g1++;
+ g2++;
+ }
+
+ /*
+ * Now add the leftovers from whichever list didn't get finished
+ * first. As before, we only want to add from the second list if
+ * we're adding the lists.
+ */
+ for (; *g1; g1++, count++)
+ if (round == 2)
+ clstr[count] = *g1;
+ if (list_op == CLUSTER_ADD)
+ for (; *g2; g2++, count++)
+ if (round == 2)
+ clstr[count] = *g2;
+
+ if (round == 1) {
+ /*
+ * If the group ended up empty, we don't need to allocate any
+ * space for it.
+ */
+ if (count == 0) {
+ clstr = NULL;
+ break;
+ }
+ clstr = (short *)alloc((unsigned)((count + 1) * sizeof(short)));
+ if (clstr == NULL)
+ break;
+ clstr[count] = 0;
+ }
+ }
+
+ /*
+ * Finally, put the new list in place.
+ */
+ vim_free(*clstr1);
+ vim_free(*clstr2);
+ *clstr1 = clstr;
+}
+
+/*
+ * Lookup a syntax cluster name and return it's ID.
+ * If it is not found, 0 is returned.
+ */
+static int syn_scl_name2id(name)
+char_u *name;
+{
+ int i;
+ char_u *name_u;
+
+ /* Avoid using stricmp() too much, it's slow on some systems */
+ name_u = vim_strsave_up(name);
+ if (name_u == NULL)
+ return 0;
+ for (i = curwin->w_s->b_syn_clusters.ga_len; --i >= 0; )
+ if (SYN_CLSTR(curwin->w_s)[i].scl_name_u != NULL
+ && STRCMP(name_u, SYN_CLSTR(curwin->w_s)[i].scl_name_u) == 0)
+ break;
+ vim_free(name_u);
+ return i < 0 ? 0 : i + SYNID_CLUSTER;
+}
+
+/*
+ * Like syn_scl_name2id(), but take a pointer + length argument.
+ */
+static int syn_scl_namen2id(linep, len)
+char_u *linep;
+int len;
+{
+ char_u *name;
+ int id = 0;
+
+ name = vim_strnsave(linep, len);
+ if (name != NULL) {
+ id = syn_scl_name2id(name);
+ vim_free(name);
+ }
+ 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.
+ */
+static int syn_check_cluster(pp, len)
+char_u *pp;
+int len;
+{
+ int id;
+ char_u *name;
+
+ name = vim_strnsave(pp, len);
+ if (name == NULL)
+ return 0;
+
+ id = syn_scl_name2id(name);
+ if (id == 0) /* doesn't exist yet */
+ id = syn_add_cluster(name);
+ else
+ vim_free(name);
+ 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.
+ */
+static int syn_add_cluster(name)
+char_u *name;
+{
+ int len;
+
+ /*
+ * First call for this growarray: init growing array.
+ */
+ if (curwin->w_s->b_syn_clusters.ga_data == NULL) {
+ curwin->w_s->b_syn_clusters.ga_itemsize = sizeof(syn_cluster_T);
+ curwin->w_s->b_syn_clusters.ga_growsize = 10;
+ }
+
+ len = curwin->w_s->b_syn_clusters.ga_len;
+ if (len >= MAX_CLUSTER_ID) {
+ EMSG((char_u *)_("E848: Too many syntax clusters"));
+ vim_free(name);
+ return 0;
+ }
+
+ /*
+ * Make room for at least one other cluster entry.
+ */
+ if (ga_grow(&curwin->w_s->b_syn_clusters, 1) == FAIL) {
+ vim_free(name);
+ return 0;
+ }
+
+ vim_memset(&(SYN_CLSTR(curwin->w_s)[len]), 0, sizeof(syn_cluster_T));
+ SYN_CLSTR(curwin->w_s)[len].scl_name = name;
+ SYN_CLSTR(curwin->w_s)[len].scl_name_u = vim_strsave_up(name);
+ SYN_CLSTR(curwin->w_s)[len].scl_list = NULL;
+ ++curwin->w_s->b_syn_clusters.ga_len;
+
+ if (STRICMP(name, "Spell") == 0)
+ curwin->w_s->b_spell_cluster_id = len + SYNID_CLUSTER;
+ if (STRICMP(name, "NoSpell") == 0)
+ curwin->w_s->b_nospell_cluster_id = len + SYNID_CLUSTER;
+
+ return len + SYNID_CLUSTER;
+}
+
+/*
+ * Handle ":syntax cluster {cluster-name} [contains={groupname},..]
+ * [add={groupname},..] [remove={groupname},..]".
+ */
+static void syn_cmd_cluster(eap, syncing)
+exarg_T *eap;
+int syncing UNUSED;
+{
+ char_u *arg = eap->arg;
+ char_u *group_name_end;
+ char_u *rest;
+ int scl_id;
+ short *clstr_list;
+ int got_clstr = FALSE;
+ int opt_len;
+ int list_op;
+
+ eap->nextcmd = find_nextcmd(arg);
+ if (eap->skip)
+ return;
+
+ 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)
+ return;
+ scl_id -= SYNID_CLUSTER;
+
+ for (;; ) {
+ if (STRNICMP(rest, "add", 3) == 0
+ && (vim_iswhite(rest[3]) || rest[3] == '=')) {
+ opt_len = 3;
+ list_op = CLUSTER_ADD;
+ } else if (STRNICMP(rest, "remove", 6) == 0
+ && (vim_iswhite(rest[6]) || rest[6] == '=')) {
+ opt_len = 6;
+ list_op = CLUSTER_SUBTRACT;
+ } else if (STRNICMP(rest, "contains", 8) == 0
+ && (vim_iswhite(rest[8]) || rest[8] == '=')) {
+ opt_len = 8;
+ list_op = CLUSTER_REPLACE;
+ } else
+ break;
+
+ clstr_list = NULL;
+ if (get_id_list(&rest, opt_len, &clstr_list) == 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 (got_clstr) {
+ redraw_curbuf_later(SOME_VALID);
+ syn_stack_free_all(curwin->w_s); /* Need to recompute all. */
+ }
+ }
+
+ if (!got_clstr)
+ EMSG(_("E400: No cluster specified"));
+ if (rest == NULL || !ends_excmd(*rest))
+ EMSG2(_(e_invarg2), arg);
+}
+
+/*
+ * On first call for current buffer: Init growing array.
+ */
+static void init_syn_patterns() {
+ curwin->w_s->b_syn_patterns.ga_itemsize = sizeof(synpat_T);
+ curwin->w_s->b_syn_patterns.ga_growsize = 10;
+}
+
+/*
+ * Get one pattern for a ":syntax match" or ":syntax region" command.
+ * Stores the pattern and program in a synpat_T.
+ * Returns a pointer to the next argument, or NULL in case of an error.
+ */
+static char_u * get_syn_pattern(arg, ci)
+char_u *arg;
+synpat_T *ci;
+{
+ char_u *end;
+ int *p;
+ int idx;
+ char_u *cpo_save;
+
+ /* need at least three chars */
+ if (arg == NULL || arg[1] == NUL || arg[2] == NUL)
+ return NULL;
+
+ end = skip_regexp(arg + 1, *arg, TRUE, NULL);
+ if (*end != *arg) { /* end delimiter not found */
+ EMSG2(_("E401: Pattern delimiter not found: %s"), arg);
+ return NULL;
+ }
+ /* store the pattern and compiled regexp program */
+ if ((ci->sp_pattern = vim_strnsave(arg + 1, (int)(end - arg - 1))) == NULL)
+ return NULL;
+
+ /* Make 'cpoptions' empty, to avoid the 'l' flag */
+ cpo_save = p_cpo;
+ p_cpo = (char_u *)"";
+ ci->sp_prog = vim_regcomp(ci->sp_pattern, RE_MAGIC);
+ p_cpo = cpo_save;
+
+ if (ci->sp_prog == NULL)
+ return NULL;
+ ci->sp_ic = curwin->w_s->b_syn_ic;
+ syn_clear_time(&ci->sp_time);
+
+ /*
+ * Check for a match, highlight or region offset.
+ */
+ ++end;
+ do {
+ for (idx = SPO_COUNT; --idx >= 0; )
+ if (STRNCMP(end, spo_name_tab[idx], 3) == 0)
+ break;
+ if (idx >= 0) {
+ p = &(ci->sp_offsets[idx]);
+ if (idx != SPO_LC_OFF)
+ switch (end[3]) {
+ case 's': break;
+ case 'b': break;
+ case 'e': idx += SPO_COUNT; break;
+ default: idx = -1; break;
+ }
+ if (idx >= 0) {
+ ci->sp_off_flags |= (1 << idx);
+ if (idx == SPO_LC_OFF) { /* lc=99 */
+ end += 3;
+ *p = getdigits(&end);
+
+ /* "lc=" offset automatically sets "ms=" offset */
+ if (!(ci->sp_off_flags & (1 << SPO_MS_OFF))) {
+ ci->sp_off_flags |= (1 << SPO_MS_OFF);
+ ci->sp_offsets[SPO_MS_OFF] = *p;
+ }
+ } else { /* yy=x+99 */
+ end += 4;
+ if (*end == '+') {
+ ++end;
+ *p = getdigits(&end); /* positive offset */
+ } else if (*end == '-') {
+ ++end;
+ *p = -getdigits(&end); /* negative offset */
+ }
+ }
+ if (*end != ',')
+ break;
+ ++end;
+ }
+ }
+ } while (idx >= 0);
+
+ if (!ends_excmd(*end) && !vim_iswhite(*end)) {
+ EMSG2(_("E402: Garbage after pattern: %s"), arg);
+ return NULL;
+ }
+ return skipwhite(end);
+}
+
+/*
+ * Handle ":syntax sync .." command.
+ */
+static void syn_cmd_sync(eap, syncing)
+exarg_T *eap;
+int syncing UNUSED;
+{
+ char_u *arg_start = eap->arg;
+ char_u *arg_end;
+ char_u *key = NULL;
+ char_u *next_arg;
+ int illegal = FALSE;
+ int finished = FALSE;
+ long n;
+ char_u *cpo_save;
+
+ if (ends_excmd(*arg_start)) {
+ syn_cmd_list(eap, TRUE);
+ return;
+ }
+
+ while (!ends_excmd(*arg_start)) {
+ arg_end = skiptowhite(arg_start);
+ next_arg = skipwhite(arg_end);
+ vim_free(key);
+ key = vim_strnsave_up(arg_start, (int)(arg_end - arg_start));
+ if (STRCMP(key, "CCOMMENT") == 0) {
+ if (!eap->skip)
+ curwin->w_s->b_syn_sync_flags |= SF_CCOMMENT;
+ if (!ends_excmd(*next_arg)) {
+ arg_end = skiptowhite(next_arg);
+ if (!eap->skip)
+ curwin->w_s->b_syn_sync_id = syn_check_group(next_arg,
+ (int)(arg_end - next_arg));
+ next_arg = skipwhite(arg_end);
+ } else if (!eap->skip)
+ curwin->w_s->b_syn_sync_id = syn_name2id((char_u *)"Comment");
+ } else if ( STRNCMP(key, "LINES", 5) == 0
+ || STRNCMP(key, "MINLINES", 8) == 0
+ || STRNCMP(key, "MAXLINES", 8) == 0
+ || STRNCMP(key, "LINEBREAKS", 10) == 0) {
+ if (key[4] == 'S')
+ arg_end = key + 6;
+ else if (key[0] == 'L')
+ arg_end = key + 11;
+ else
+ arg_end = key + 9;
+ if (arg_end[-1] != '=' || !VIM_ISDIGIT(*arg_end)) {
+ illegal = TRUE;
+ break;
+ }
+ n = getdigits(&arg_end);
+ if (!eap->skip) {
+ if (key[4] == 'B')
+ curwin->w_s->b_syn_sync_linebreaks = n;
+ else if (key[1] == 'A')
+ curwin->w_s->b_syn_sync_maxlines = n;
+ else
+ curwin->w_s->b_syn_sync_minlines = n;
+ }
+ } else if (STRCMP(key, "FROMSTART") == 0) {
+ if (!eap->skip) {
+ curwin->w_s->b_syn_sync_minlines = MAXLNUM;
+ curwin->w_s->b_syn_sync_maxlines = 0;
+ }
+ } else if (STRCMP(key, "LINECONT") == 0) {
+ if (curwin->w_s->b_syn_linecont_pat != NULL) {
+ EMSG(_("E403: syntax sync: line continuations pattern specified twice"));
+ finished = TRUE;
+ break;
+ }
+ arg_end = skip_regexp(next_arg + 1, *next_arg, TRUE, NULL);
+ if (*arg_end != *next_arg) { /* end delimiter not found */
+ illegal = TRUE;
+ break;
+ }
+
+ if (!eap->skip) {
+ /* store the pattern and compiled regexp program */
+ if ((curwin->w_s->b_syn_linecont_pat = vim_strnsave(next_arg + 1,
+ (int)(arg_end - next_arg - 1))) == NULL) {
+ finished = TRUE;
+ break;
+ }
+ curwin->w_s->b_syn_linecont_ic = curwin->w_s->b_syn_ic;
+
+ /* Make 'cpoptions' empty, to avoid the 'l' flag */
+ cpo_save = p_cpo;
+ p_cpo = (char_u *)"";
+ curwin->w_s->b_syn_linecont_prog =
+ vim_regcomp(curwin->w_s->b_syn_linecont_pat, RE_MAGIC);
+ p_cpo = cpo_save;
+ syn_clear_time(&curwin->w_s->b_syn_linecont_time);
+
+ if (curwin->w_s->b_syn_linecont_prog == NULL) {
+ vim_free(curwin->w_s->b_syn_linecont_pat);
+ curwin->w_s->b_syn_linecont_pat = NULL;
+ finished = TRUE;
+ break;
+ }
+ }
+ next_arg = skipwhite(arg_end + 1);
+ } else {
+ eap->arg = next_arg;
+ if (STRCMP(key, "MATCH") == 0)
+ syn_cmd_match(eap, TRUE);
+ else if (STRCMP(key, "REGION") == 0)
+ syn_cmd_region(eap, TRUE);
+ else if (STRCMP(key, "CLEAR") == 0)
+ syn_cmd_clear(eap, TRUE);
+ else
+ illegal = TRUE;
+ finished = TRUE;
+ break;
+ }
+ arg_start = next_arg;
+ }
+ vim_free(key);
+ if (illegal)
+ EMSG2(_("E404: Illegal arguments: %s"), arg_start);
+ else if (!finished) {
+ eap->nextcmd = check_nextcmd(arg_start);
+ redraw_curbuf_later(SOME_VALID);
+ syn_stack_free_all(curwin->w_s); /* Need to recompute all syntax. */
+ }
+}
+
+/*
+ * Convert a line of highlight group names into a list of group ID numbers.
+ * "arg" should point to the "contains" or "nextgroup" keyword.
+ * "arg" is advanced to after the last group name.
+ * Careful: the argument is modified (NULs added).
+ * returns FAIL for some error, OK for success.
+ */
+static int get_id_list(arg, keylen, 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! */
+{
+ char_u *p = NULL;
+ char_u *end;
+ int round;
+ int count;
+ int total_count = 0;
+ short *retval = NULL;
+ char_u *name;
+ regmatch_T regmatch;
+ int id;
+ int i;
+ 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"
+ */
+ p = skipwhite(*arg + keylen);
+ if (*p != '=') {
+ EMSG2(_("E405: Missing equal sign: %s"), *arg);
+ break;
+ }
+ p = skipwhite(p + 1);
+ if (ends_excmd(*p)) {
+ EMSG2(_("E406: Empty argument: %s"), *arg);
+ break;
+ }
+
+ /*
+ * parse the arguments after "contains"
+ */
+ count = 0;
+ while (!ends_excmd(*p)) {
+ for (end = p; *end && !vim_iswhite(*end) && *end != ','; ++end)
+ ;
+ name = alloc((int)(end - p + 3)); /* leave room for "^$" */
+ if (name == NULL) {
+ failed = TRUE;
+ break;
+ }
+ vim_strncpy(name + 1, p, end - p);
+ if ( STRCMP(name + 1, "ALLBUT") == 0
+ || STRCMP(name + 1, "ALL") == 0
+ || STRCMP(name + 1, "TOP") == 0
+ || STRCMP(name + 1, "CONTAINED") == 0) {
+ if (TOUPPER_ASC(**arg) != 'C') {
+ EMSG2(_("E407: %s not allowed here"), name + 1);
+ failed = TRUE;
+ vim_free(name);
+ break;
+ }
+ if (count != 0) {
+ EMSG2(_("E408: %s must be first in contains list"), name + 1);
+ failed = TRUE;
+ vim_free(name);
+ break;
+ }
+ if (name[1] == 'A')
+ id = SYNID_ALLBUT;
+ else if (name[1] == 'T')
+ id = SYNID_TOP;
+ else
+ id = SYNID_CONTAINED;
+ id += current_syn_inc_tag;
+ } else if (name[1] == '@') {
+ id = syn_check_cluster(name + 2, (int)(end - p - 1));
+ } else {
+ /*
+ * Handle full group name.
+ */
+ 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.
+ */
+ *name = '^';
+ STRCAT(name, "$");
+ regmatch.regprog = vim_regcomp(name, RE_MAGIC);
+ if (regmatch.regprog == NULL) {
+ failed = TRUE;
+ vim_free(name);
+ break;
+ }
+
+ regmatch.rm_ic = TRUE;
+ id = 0;
+ for (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 */
+ if (count >= total_count) {
+ vim_free(retval);
+ round = 1;
+ } else
+ retval[count] = i + 1;
+ }
+ ++count;
+ id = -1; /* remember that we found one */
+ }
+ }
+ vim_regfree(regmatch.regprog);
+ }
+ }
+ vim_free(name);
+ if (id == 0) {
+ EMSG2(_("E409: Unknown group name: %s"), p);
+ failed = TRUE;
+ break;
+ }
+ if (id > 0) {
+ if (round == 2) {
+ /* Got more items than expected, go back to first round */
+ if (count >= total_count) {
+ vim_free(retval);
+ round = 1;
+ } else
+ retval[count] = id;
+ }
+ ++count;
+ }
+ p = skipwhite(end);
+ if (*p != ',')
+ break;
+ p = skipwhite(p + 1); /* skip comma in between arguments */
+ }
+ if (failed)
+ break;
+ if (round == 1) {
+ retval = (short *)alloc((unsigned)((count + 1) * sizeof(short)));
+ if (retval == NULL)
+ break;
+ retval[count] = 0; /* zero means end of the list */
+ total_count = count;
+ }
+ }
+
+ *arg = p;
+ if (failed || retval == NULL) {
+ vim_free(retval);
+ return FAIL;
+ }
+
+ if (*list == NULL)
+ *list = retval;
+ else
+ vim_free(retval); /* list already found, don't overwrite it */
+
+ return OK;
+}
+
+/*
+ * Make a copy of an ID list.
+ */
+static short * copy_id_list(list)
+short *list;
+{
+ int len;
+ int count;
+ short *retval;
+
+ if (list == NULL)
+ return NULL;
+
+ for (count = 0; list[count]; ++count)
+ ;
+ len = (count + 1) * sizeof(short);
+ retval = (short *)alloc((unsigned)len);
+ if (retval != NULL)
+ mch_memmove(retval, list, (size_t)len);
+
+ return retval;
+}
+
+/*
+ * Check if syntax group "ssp" is in the ID list "list" of "cur_si".
+ * "cur_si" can be NULL if not checking the "containedin" list.
+ * Used to check if a syntax item is in the "contains" or "nextgroup" list of
+ * the current item.
+ * This function is called very often, keep it fast!!
+ */
+static int in_id_list(cur_si, list, ssp, contained)
+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 */
+{
+ int retval;
+ short *scl_list;
+ short item;
+ short id = ssp->id;
+ static int depth = 0;
+ int r;
+
+ /* If ssp has a "containedin" list and "cur_si" is in it, return TRUE. */
+ if (cur_si != NULL && ssp->cont_in_list != NULL
+ && !(cur_si->si_flags & HL_MATCH)) {
+ /* Ignore transparent items without a contains argument. Double check
+ * that we don't go back past the first one. */
+ while ((cur_si->si_flags & HL_TRANS_CONT)
+ && cur_si > (stateitem_T *)(current_state.ga_data))
+ --cur_si;
+ /* cur_si->si_idx is -1 for keywords, these never contain anything. */
+ if (cur_si->si_idx >= 0 && in_id_list(NULL, ssp->cont_in_list,
+ &(SYN_ITEMS(syn_block)[cur_si->si_idx].sp_syn),
+ SYN_ITEMS(syn_block)[cur_si->si_idx].sp_flags & HL_CONTAINED))
+ return TRUE;
+ }
+
+ if (list == NULL)
+ return FALSE;
+
+ /*
+ * If list is ID_LIST_ALL, we are in a transparent item that isn't
+ * inside anything. Only allow not-contained groups.
+ */
+ if (list == ID_LIST_ALL)
+ return !contained;
+
+ /*
+ * If the first item is "ALLBUT", return TRUE if "id" is NOT in the
+ * contains list. We also require that "id" is at the same ":syn include"
+ * level as the list.
+ */
+ item = *list;
+ if (item >= SYNID_ALLBUT && item < SYNID_CLUSTER) {
+ if (item < SYNID_TOP) {
+ /* ALL or ALLBUT: accept all groups in the same file */
+ if (item - SYNID_ALLBUT != ssp->inc_tag)
+ return FALSE;
+ } else if (item < SYNID_CONTAINED) {
+ /* TOP: accept all not-contained groups in the same file */
+ if (item - SYNID_TOP != ssp->inc_tag || contained)
+ return FALSE;
+ } else {
+ /* CONTAINED: accept all contained groups in the same file */
+ if (item - SYNID_CONTAINED != ssp->inc_tag || !contained)
+ return FALSE;
+ }
+ item = *++list;
+ retval = FALSE;
+ } else
+ retval = TRUE;
+
+ /*
+ * Return "retval" if id is in the contains list.
+ */
+ while (item != 0) {
+ if (item == id)
+ return retval;
+ if (item >= SYNID_CLUSTER) {
+ scl_list = SYN_CLSTR(syn_block)[item - SYNID_CLUSTER].scl_list;
+ /* restrict recursiveness to 30 to avoid an endless loop for a
+ * cluster that includes itself (indirectly) */
+ if (scl_list != NULL && depth < 30) {
+ ++depth;
+ r = in_id_list(NULL, scl_list, ssp, contained);
+ --depth;
+ if (r)
+ return retval;
+ }
+ }
+ item = *++list;
+ }
+ return !retval;
+}
+
+struct subcommand {
+ char *name; /* subcommand name */
+ void (*func)__ARGS((exarg_T *, int)); /* function to call */
+};
+
+static struct subcommand subcommands[] =
+{
+ {"case", syn_cmd_case},
+ {"clear", syn_cmd_clear},
+ {"cluster", syn_cmd_cluster},
+ {"conceal", syn_cmd_conceal},
+ {"enable", syn_cmd_enable},
+ {"include", syn_cmd_include},
+ {"keyword", syn_cmd_keyword},
+ {"list", syn_cmd_list},
+ {"manual", syn_cmd_manual},
+ {"match", syn_cmd_match},
+ {"on", syn_cmd_on},
+ {"off", syn_cmd_off},
+ {"region", syn_cmd_region},
+ {"reset", syn_cmd_reset},
+ {"spell", syn_cmd_spell},
+ {"sync", syn_cmd_sync},
+ {"", syn_cmd_list},
+ {NULL, NULL}
+};
+
+/*
+ * ":syntax".
+ * This searches the subcommands[] table for the subcommand name, and calls a
+ * syntax_subcommand() function to do the rest.
+ */
+void ex_syntax(eap)
+exarg_T *eap;
+{
+ char_u *arg = eap->arg;
+ char_u *subcmd_end;
+ char_u *subcmd_name;
+ int i;
+
+ syn_cmdlinep = eap->cmdlinep;
+
+ /* isolate subcommand name */
+ for (subcmd_end = arg; ASCII_ISALPHA(*subcmd_end); ++subcmd_end)
+ ;
+ subcmd_name = vim_strnsave(arg, (int)(subcmd_end - arg));
+ if (subcmd_name != NULL) {
+ if (eap->skip) /* skip error messages for all subcommands */
+ ++emsg_skip;
+ for (i = 0;; ++i) {
+ if (subcommands[i].name == NULL) {
+ EMSG2(_("E410: Invalid :syntax subcommand: %s"), subcmd_name);
+ break;
+ }
+ if (STRCMP(subcmd_name, (char_u *)subcommands[i].name) == 0) {
+ eap->arg = skipwhite(subcmd_end);
+ (subcommands[i].func)(eap, FALSE);
+ break;
+ }
+ }
+ vim_free(subcmd_name);
+ if (eap->skip)
+ --emsg_skip;
+ }
+}
+
+void ex_ownsyntax(eap)
+exarg_T *eap;
+{
+ char_u *old_value;
+ char_u *new_value;
+
+ if (curwin->w_s == &curwin->w_buffer->b_s) {
+ curwin->w_s = (synblock_T *)alloc(sizeof(synblock_T));
+ memset(curwin->w_s, 0, sizeof(synblock_T));
+ curwin->w_p_spell = FALSE; /* No spell checking */
+ clear_string_option(&curwin->w_s->b_p_spc);
+ clear_string_option(&curwin->w_s->b_p_spf);
+ vim_regfree(curwin->w_s->b_cap_prog);
+ curwin->w_s->b_cap_prog = NULL;
+ clear_string_option(&curwin->w_s->b_p_spl);
+ }
+
+ /* save value of b:current_syntax */
+ old_value = get_var_value((char_u *)"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)
+ 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 {
+ set_internal_string_var((char_u *)"b:current_syntax", old_value);
+ vim_free(old_value);
+ }
+}
+
+int syntax_present(win)
+win_T *win;
+{
+ return win->w_s->b_syn_patterns.ga_len != 0
+ || win->w_s->b_syn_clusters.ga_len != 0
+ || win->w_s->b_keywtab.ht_used > 0
+ || win->w_s->b_keywtab_ic.ht_used > 0;
+}
+
+
+static enum {
+ EXP_SUBCMD, /* expand ":syn" sub-commands */
+ EXP_CASE /* expand ":syn case" arguments */
+} expand_what;
+
+/*
+ * Reset include_link, include_default, include_none to 0.
+ * Called when we are done expanding.
+ */
+void reset_expand_highlight() {
+ include_link = include_default = include_none = 0;
+}
+
+/*
+ * Handle command line completion for :match and :echohl command: Add "None"
+ * as highlight group.
+ */
+void set_context_in_echohl_cmd(xp, arg)
+expand_T *xp;
+char_u *arg;
+{
+ xp->xp_context = EXPAND_HIGHLIGHT;
+ xp->xp_pattern = arg;
+ include_none = 1;
+}
+
+/*
+ * Handle command line completion for :syntax command.
+ */
+void set_context_in_syntax_cmd(xp, arg)
+expand_T *xp;
+char_u *arg;
+{
+ char_u *p;
+
+ /* Default: expand subcommands */
+ xp->xp_context = EXPAND_SYNTAX;
+ expand_what = EXP_SUBCMD;
+ xp->xp_pattern = 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)
+ xp->xp_context = EXPAND_NOTHING;
+ else if (STRNICMP(arg, "case", p - arg) == 0)
+ expand_what = EXP_CASE;
+ 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)
+ xp->xp_context = EXPAND_HIGHLIGHT;
+ 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(xp, idx)
+expand_T *xp UNUSED;
+int idx;
+{
+ if (expand_what == EXP_SUBCMD)
+ return (char_u *)subcommands[idx].name;
+ return (char_u *)case_args[idx];
+}
+
+
+/*
+ * Function called for expression evaluation: get syntax ID at file position.
+ */
+int syn_get_id(wp, lnum, col, trans, spellp, keep_state)
+win_T *wp;
+long lnum;
+colnr_T col;
+int trans; /* remove transparency */
+int *spellp; /* return: can do spell checking */
+int keep_state; /* keep state of char at "col" */
+{
+ /* 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)
+ syntax_start(wp, lnum);
+
+ (void)get_syntax_attr(col, spellp, keep_state);
+
+ return trans ? current_trans_id : current_id;
+}
+
+/*
+ * Get extra information about the syntax item. Must be called right after
+ * get_syntax_attr().
+ * Stores the current item sequence nr in "*seqnrp".
+ * Returns the current flags.
+ */
+int get_syntax_info(seqnrp)
+int *seqnrp;
+{
+ *seqnrp = current_seqnr;
+ return current_flags;
+}
+
+/*
+ * Return conceal substitution character
+ */
+int syn_get_sub_char() {
+ return current_sub_char;
+}
+
+/*
+ * Return the syntax ID at position "i" in the current stack.
+ * The caller must have called syn_get_id() before to fill the stack.
+ * Returns -1 when "i" is out of range.
+ */
+int syn_get_stack_item(i)
+int i;
+{
+ if (i >= current_state.ga_len) {
+ /* Need to invalidate the state, because we didn't properly finish it
+ * for the last character, "keep_state" was TRUE. */
+ invalidate_current_state();
+ current_col = MAXCOL;
+ return -1;
+ }
+ return CUR_STATE(i).si_id;
+}
+
+/*
+ * Function called to get folding level for line "lnum" in window "wp".
+ */
+int syn_get_foldlevel(wp, lnum)
+win_T *wp;
+long lnum;
+{
+ int level = 0;
+ int i;
+
+ /* Return quickly when there are no fold items at all. */
+ if (wp->w_s->b_syn_folditems != 0) {
+ syntax_start(wp, lnum);
+
+ for (i = 0; i < current_state.ga_len; ++i)
+ if (CUR_STATE(i).si_flags & HL_FOLD)
+ ++level;
+ }
+ if (level > wp->w_p_fdn) {
+ level = wp->w_p_fdn;
+ if (level < 0)
+ level = 0;
+ }
+ return level;
+}
+
+/*
+ * ":syntime".
+ */
+void ex_syntime(eap)
+exarg_T *eap;
+{
+ if (STRCMP(eap->arg, "on") == 0)
+ syn_time_on = TRUE;
+ else if (STRCMP(eap->arg, "off") == 0)
+ syn_time_on = FALSE;
+ else if (STRCMP(eap->arg, "clear") == 0)
+ syntime_clear();
+ else if (STRCMP(eap->arg, "report") == 0)
+ syntime_report();
+ else
+ EMSG2(_(e_invarg2), eap->arg);
+}
+
+static void syn_clear_time(st)
+syn_time_T *st;
+{
+ profile_zero(&st->total);
+ profile_zero(&st->slowest);
+ st->count = 0;
+ st->match = 0;
+}
+
+/*
+ * Clear the syntax timing for the current buffer.
+ */
+static void syntime_clear() {
+ int idx;
+ synpat_T *spp;
+
+ if (!syntax_present(curwin)) {
+ MSG(_(msg_no_items));
+ return;
+ }
+ for (idx = 0; idx < curwin->w_s->b_syn_patterns.ga_len; ++idx) {
+ spp = &(SYN_ITEMS(curwin->w_s)[idx]);
+ syn_clear_time(&spp->sp_time);
+ }
+}
+
+/*
+ * Function given to ExpandGeneric() to obtain the possible arguments of the
+ * ":syntime {on,off,clear,report}" command.
+ */
+char_u * get_syntime_arg(xp, idx)
+expand_T *xp UNUSED;
+int idx;
+{
+ switch (idx) {
+ case 0: return (char_u *)"on";
+ case 1: return (char_u *)"off";
+ case 2: return (char_u *)"clear";
+ case 3: return (char_u *)"report";
+ }
+ return NULL;
+}
+
+typedef struct {
+ proftime_T total;
+ int count;
+ int match;
+ proftime_T slowest;
+ proftime_T average;
+ int id;
+ char_u *pattern;
+} time_entry_T;
+
+static int syn_compare_syntime(v1, v2)
+const void *v1;
+const void *v2;
+{
+ const time_entry_T *s1 = v1;
+ const time_entry_T *s2 = v2;
+
+ return profile_cmp(&s1->total, &s2->total);
+}
+
+/*
+ * Clear the syntax timing for the current buffer.
+ */
+static void syntime_report() {
+ int idx;
+ synpat_T *spp;
+ proftime_T tm;
+ int len;
+ proftime_T total_total;
+ int total_count = 0;
+ garray_T ga;
+ time_entry_T *p;
+
+ if (!syntax_present(curwin)) {
+ MSG(_(msg_no_items));
+ return;
+ }
+
+ ga_init2(&ga, sizeof(time_entry_T), 50);
+ profile_zero(&total_total);
+ for (idx = 0; idx < curwin->w_s->b_syn_patterns.ga_len; ++idx) {
+ spp = &(SYN_ITEMS(curwin->w_s)[idx]);
+ if (spp->sp_time.count > 0) {
+ ga_grow(&ga, 1);
+ p = ((time_entry_T *)ga.ga_data) + ga.ga_len;
+ p->total = spp->sp_time.total;
+ profile_add(&total_total, &spp->sp_time.total);
+ p->count = spp->sp_time.count;
+ p->match = spp->sp_time.match;
+ total_count += spp->sp_time.count;
+ p->slowest = spp->sp_time.slowest;
+ profile_divide(&spp->sp_time.total, spp->sp_time.count, &tm);
+ p->average = tm;
+ p->id = spp->sp_syn.id;
+ p->pattern = spp->sp_pattern;
+ ++ga.ga_len;
+ }
+ }
+
+ /* sort on total time */
+ 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"));
+ MSG_PUTS("\n");
+ for (idx = 0; idx < ga.ga_len && !got_int; ++idx) {
+ spp = &(SYN_ITEMS(curwin->w_s)[idx]);
+ p = ((time_entry_T *)ga.ga_data) + idx;
+
+ MSG_PUTS(profile_msg(&p->total));
+ MSG_PUTS(" "); /* make sure there is always a separating space */
+ msg_advance(13);
+ msg_outnum(p->count);
+ MSG_PUTS(" ");
+ msg_advance(20);
+ msg_outnum(p->match);
+ MSG_PUTS(" ");
+ msg_advance(26);
+ MSG_PUTS(profile_msg(&p->slowest));
+ MSG_PUTS(" ");
+ msg_advance(38);
+ MSG_PUTS(profile_msg(&p->average));
+ MSG_PUTS(" ");
+ msg_advance(50);
+ msg_outtrans(HL_TABLE()[p->id - 1].sg_name);
+ MSG_PUTS(" ");
+
+ msg_advance(69);
+ if (Columns < 80)
+ len = 20; /* will wrap anyway */
+ else
+ len = Columns - 70;
+ if (len > (int)STRLEN(p->pattern))
+ len = (int)STRLEN(p->pattern);
+ msg_outtrans_len(p->pattern, len);
+ MSG_PUTS("\n");
+ }
+ ga_clear(&ga);
+ if (!got_int) {
+ MSG_PUTS("\n");
+ MSG_PUTS(profile_msg(&total_total));
+ msg_advance(13);
+ msg_outnum(total_count);
+ MSG_PUTS("\n");
+ }
+}
+
+/**************************************
+* Highlighting stuff *
+**************************************/
+
+/*
+ * The default highlight groups. These are compiled-in for fast startup and
+ * they still work when the runtime files can't be found.
+ * When making changes here, also change runtime/colors/default.vim!
+ * The #ifdefs are needed to reduce the amount of static data. Helps to make
+ * the 16 bit DOS (museum) version compile.
+ */
+# define CENT(a, b) b
+static char *(highlight_init_both[]) =
+{
+ CENT(
+ "ErrorMsg term=standout ctermbg=DarkRed ctermfg=White",
+ "ErrorMsg term=standout ctermbg=DarkRed ctermfg=White guibg=Red guifg=White"),
+ CENT("IncSearch term=reverse cterm=reverse",
+ "IncSearch term=reverse cterm=reverse gui=reverse"),
+ CENT("ModeMsg term=bold cterm=bold",
+ "ModeMsg term=bold cterm=bold gui=bold"),
+ CENT("NonText term=bold ctermfg=Blue",
+ "NonText term=bold ctermfg=Blue gui=bold guifg=Blue"),
+ CENT("StatusLine term=reverse,bold cterm=reverse,bold",
+ "StatusLine term=reverse,bold cterm=reverse,bold gui=reverse,bold"),
+ CENT("StatusLineNC term=reverse cterm=reverse",
+ "StatusLineNC term=reverse cterm=reverse gui=reverse"),
+ CENT("VertSplit term=reverse cterm=reverse",
+ "VertSplit term=reverse cterm=reverse gui=reverse"),
+ CENT("DiffText term=reverse cterm=bold ctermbg=Red",
+ "DiffText term=reverse cterm=bold ctermbg=Red gui=bold guibg=Red"),
+ CENT("PmenuSbar ctermbg=Grey",
+ "PmenuSbar ctermbg=Grey guibg=Grey"),
+ CENT("TabLineSel term=bold cterm=bold",
+ "TabLineSel term=bold cterm=bold gui=bold"),
+ CENT("TabLineFill term=reverse cterm=reverse",
+ "TabLineFill term=reverse cterm=reverse gui=reverse"),
+ NULL
+};
+
+static char *(highlight_init_light[]) =
+{
+ CENT("Directory term=bold ctermfg=DarkBlue",
+ "Directory term=bold ctermfg=DarkBlue guifg=Blue"),
+ CENT("LineNr term=underline ctermfg=Brown",
+ "LineNr term=underline ctermfg=Brown guifg=Brown"),
+ CENT("CursorLineNr term=bold ctermfg=Brown",
+ "CursorLineNr term=bold ctermfg=Brown gui=bold guifg=Brown"),
+ CENT("MoreMsg term=bold ctermfg=DarkGreen",
+ "MoreMsg term=bold ctermfg=DarkGreen gui=bold guifg=SeaGreen"),
+ CENT("Question term=standout ctermfg=DarkGreen",
+ "Question term=standout ctermfg=DarkGreen gui=bold guifg=SeaGreen"),
+ CENT("Search term=reverse ctermbg=Yellow ctermfg=NONE",
+ "Search term=reverse ctermbg=Yellow ctermfg=NONE guibg=Yellow guifg=NONE"),
+ CENT("SpellBad term=reverse ctermbg=LightRed",
+ "SpellBad term=reverse ctermbg=LightRed guisp=Red gui=undercurl"),
+ CENT("SpellCap term=reverse ctermbg=LightBlue",
+ "SpellCap term=reverse ctermbg=LightBlue guisp=Blue gui=undercurl"),
+ CENT("SpellRare term=reverse ctermbg=LightMagenta",
+ "SpellRare term=reverse ctermbg=LightMagenta guisp=Magenta gui=undercurl"),
+ CENT("SpellLocal term=underline ctermbg=Cyan",
+ "SpellLocal term=underline ctermbg=Cyan guisp=DarkCyan gui=undercurl"),
+ CENT("PmenuThumb ctermbg=Black",
+ "PmenuThumb ctermbg=Black guibg=Black"),
+ CENT("Pmenu ctermbg=LightMagenta ctermfg=Black",
+ "Pmenu ctermbg=LightMagenta ctermfg=Black guibg=LightMagenta"),
+ CENT("PmenuSel ctermbg=LightGrey ctermfg=Black",
+ "PmenuSel ctermbg=LightGrey ctermfg=Black guibg=Grey"),
+ CENT("SpecialKey term=bold ctermfg=DarkBlue",
+ "SpecialKey term=bold ctermfg=DarkBlue guifg=Blue"),
+ CENT("Title term=bold ctermfg=DarkMagenta",
+ "Title term=bold ctermfg=DarkMagenta gui=bold guifg=Magenta"),
+ CENT("WarningMsg term=standout ctermfg=DarkRed",
+ "WarningMsg term=standout ctermfg=DarkRed guifg=Red"),
+ CENT(
+ "WildMenu term=standout ctermbg=Yellow ctermfg=Black",
+ "WildMenu term=standout ctermbg=Yellow ctermfg=Black guibg=Yellow guifg=Black"),
+ CENT(
+ "Folded term=standout ctermbg=Grey ctermfg=DarkBlue",
+ "Folded term=standout ctermbg=Grey ctermfg=DarkBlue guibg=LightGrey guifg=DarkBlue"),
+ CENT(
+ "FoldColumn term=standout ctermbg=Grey ctermfg=DarkBlue",
+ "FoldColumn term=standout ctermbg=Grey ctermfg=DarkBlue guibg=Grey guifg=DarkBlue"),
+ CENT("Visual term=reverse",
+ "Visual term=reverse guibg=LightGrey"),
+ CENT("DiffAdd term=bold ctermbg=LightBlue",
+ "DiffAdd term=bold ctermbg=LightBlue guibg=LightBlue"),
+ CENT("DiffChange term=bold ctermbg=LightMagenta",
+ "DiffChange term=bold ctermbg=LightMagenta guibg=LightMagenta"),
+ CENT(
+ "DiffDelete term=bold ctermfg=Blue ctermbg=LightCyan",
+ "DiffDelete term=bold ctermfg=Blue ctermbg=LightCyan gui=bold guifg=Blue guibg=LightCyan"),
+ CENT(
+ "TabLine term=underline cterm=underline ctermfg=black ctermbg=LightGrey",
+ "TabLine term=underline cterm=underline ctermfg=black ctermbg=LightGrey gui=underline guibg=LightGrey"),
+ CENT("CursorColumn term=reverse ctermbg=LightGrey",
+ "CursorColumn term=reverse ctermbg=LightGrey guibg=Grey90"),
+ CENT("CursorLine term=underline cterm=underline",
+ "CursorLine term=underline cterm=underline guibg=Grey90"),
+ CENT("ColorColumn term=reverse ctermbg=LightRed",
+ "ColorColumn term=reverse ctermbg=LightRed guibg=LightRed"),
+ CENT(
+ "Conceal ctermbg=DarkGrey ctermfg=LightGrey",
+ "Conceal ctermbg=DarkGrey ctermfg=LightGrey guibg=DarkGrey guifg=LightGrey"),
+ CENT("MatchParen term=reverse ctermbg=Cyan",
+ "MatchParen term=reverse ctermbg=Cyan guibg=Cyan"),
+ NULL
+};
+
+static char *(highlight_init_dark[]) =
+{
+ CENT("Directory term=bold ctermfg=LightCyan",
+ "Directory term=bold ctermfg=LightCyan guifg=Cyan"),
+ CENT("LineNr term=underline ctermfg=Yellow",
+ "LineNr term=underline ctermfg=Yellow guifg=Yellow"),
+ CENT("CursorLineNr term=bold ctermfg=Yellow",
+ "CursorLineNr term=bold ctermfg=Yellow gui=bold guifg=Yellow"),
+ CENT("MoreMsg term=bold ctermfg=LightGreen",
+ "MoreMsg term=bold ctermfg=LightGreen gui=bold guifg=SeaGreen"),
+ CENT("Question term=standout ctermfg=LightGreen",
+ "Question term=standout ctermfg=LightGreen gui=bold guifg=Green"),
+ CENT(
+ "Search term=reverse ctermbg=Yellow ctermfg=Black",
+ "Search term=reverse ctermbg=Yellow ctermfg=Black guibg=Yellow guifg=Black"),
+ CENT("SpecialKey term=bold ctermfg=LightBlue",
+ "SpecialKey term=bold ctermfg=LightBlue guifg=Cyan"),
+ CENT("SpellBad term=reverse ctermbg=Red",
+ "SpellBad term=reverse ctermbg=Red guisp=Red gui=undercurl"),
+ CENT("SpellCap term=reverse ctermbg=Blue",
+ "SpellCap term=reverse ctermbg=Blue guisp=Blue gui=undercurl"),
+ CENT("SpellRare term=reverse ctermbg=Magenta",
+ "SpellRare term=reverse ctermbg=Magenta guisp=Magenta gui=undercurl"),
+ CENT("SpellLocal term=underline ctermbg=Cyan",
+ "SpellLocal term=underline ctermbg=Cyan guisp=Cyan gui=undercurl"),
+ CENT("PmenuThumb ctermbg=White",
+ "PmenuThumb ctermbg=White guibg=White"),
+ CENT("Pmenu ctermbg=Magenta ctermfg=Black",
+ "Pmenu ctermbg=Magenta ctermfg=Black guibg=Magenta"),
+ CENT("PmenuSel ctermbg=Black ctermfg=DarkGrey",
+ "PmenuSel ctermbg=Black ctermfg=DarkGrey guibg=DarkGrey"),
+ CENT("Title term=bold ctermfg=LightMagenta",
+ "Title term=bold ctermfg=LightMagenta gui=bold guifg=Magenta"),
+ CENT("WarningMsg term=standout ctermfg=LightRed",
+ "WarningMsg term=standout ctermfg=LightRed guifg=Red"),
+ CENT(
+ "WildMenu term=standout ctermbg=Yellow ctermfg=Black",
+ "WildMenu term=standout ctermbg=Yellow ctermfg=Black guibg=Yellow guifg=Black"),
+ CENT(
+ "Folded term=standout ctermbg=DarkGrey ctermfg=Cyan",
+ "Folded term=standout ctermbg=DarkGrey ctermfg=Cyan guibg=DarkGrey guifg=Cyan"),
+ CENT(
+ "FoldColumn term=standout ctermbg=DarkGrey ctermfg=Cyan",
+ "FoldColumn term=standout ctermbg=DarkGrey ctermfg=Cyan guibg=Grey guifg=Cyan"),
+ CENT("Visual term=reverse",
+ "Visual term=reverse guibg=DarkGrey"),
+ CENT("DiffAdd term=bold ctermbg=DarkBlue",
+ "DiffAdd term=bold ctermbg=DarkBlue guibg=DarkBlue"),
+ CENT("DiffChange term=bold ctermbg=DarkMagenta",
+ "DiffChange term=bold ctermbg=DarkMagenta guibg=DarkMagenta"),
+ CENT(
+ "DiffDelete term=bold ctermfg=Blue ctermbg=DarkCyan",
+ "DiffDelete term=bold ctermfg=Blue ctermbg=DarkCyan gui=bold guifg=Blue guibg=DarkCyan"),
+ CENT(
+ "TabLine term=underline cterm=underline ctermfg=white ctermbg=DarkGrey",
+ "TabLine term=underline cterm=underline ctermfg=white ctermbg=DarkGrey gui=underline guibg=DarkGrey"),
+ CENT("CursorColumn term=reverse ctermbg=DarkGrey",
+ "CursorColumn term=reverse ctermbg=DarkGrey guibg=Grey40"),
+ CENT("CursorLine term=underline cterm=underline",
+ "CursorLine term=underline cterm=underline guibg=Grey40"),
+ CENT("ColorColumn term=reverse ctermbg=DarkRed",
+ "ColorColumn term=reverse ctermbg=DarkRed guibg=DarkRed"),
+ CENT("MatchParen term=reverse ctermbg=DarkCyan",
+ "MatchParen term=reverse ctermbg=DarkCyan guibg=DarkCyan"),
+ CENT(
+ "Conceal ctermbg=DarkGrey ctermfg=LightGrey",
+ "Conceal ctermbg=DarkGrey ctermfg=LightGrey guibg=DarkGrey guifg=LightGrey"),
+ NULL
+};
+
+void init_highlight(both, reset)
+int both; /* include groups where 'bg' doesn't matter */
+int reset; /* clear group first */
+{
+ int i;
+ char **pp;
+ static int had_both = FALSE;
+ char_u *p;
+
+ /*
+ * Try finding the color scheme file. Used when a color file was loaded
+ * and 'background' or 't_Co' is changed.
+ */
+ p = get_var_value((char_u *)"g:colors_name");
+ if (p != NULL && load_colors(p) == OK)
+ return;
+
+ /*
+ * 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. */
+ 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);
+
+ /* 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)
+ 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);
+ }
+
+ /*
+ * If syntax highlighting is enabled load the highlighting for it.
+ */
+ if (get_var_value((char_u *)"g:syntax_on") != NULL) {
+ static int recursive = 0;
+
+ if (recursive >= 5)
+ EMSG(_("E679: recursive loop loading syncolor.vim"));
+ else {
+ ++recursive;
+ (void)source_runtime((char_u *)"syntax/syncolor.vim", TRUE);
+ --recursive;
+ }
+ }
+}
+
+/*
+ * Load color file "name".
+ * Return OK for success, FAIL for failure.
+ */
+int load_colors(name)
+char_u *name;
+{
+ char_u *buf;
+ int retval = FAIL;
+ static int recursive = FALSE;
+
+ /* When being called recursively, this is probably because setting
+ * 'background' caused the highlighting to be reloaded. This means it is
+ * working, thus we should return OK. */
+ if (recursive)
+ return OK;
+
+ recursive = TRUE;
+ buf = alloc((unsigned)(STRLEN(name) + 12));
+ if (buf != NULL) {
+ sprintf((char *)buf, "colors/%s.vim", name);
+ retval = source_runtime(buf, FALSE);
+ vim_free(buf);
+ apply_autocmds(EVENT_COLORSCHEME, name, curbuf->b_fname, FALSE, curbuf);
+ }
+ recursive = FALSE;
+
+ 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(line, forceit, init)
+char_u *line;
+int forceit;
+int init; /* TRUE when called for initializing */
+{
+ char_u *name_end;
+ char_u *p;
+ char_u *linep;
+ char_u *key_start;
+ char_u *arg_start;
+ char_u *key = NULL, *arg = NULL;
+ long i;
+ int off;
+ int len;
+ int attr;
+ int id;
+ int idx;
+ int dodefault = FALSE;
+ int doclear = FALSE;
+ int dolink = FALSE;
+ int error = FALSE;
+ int color;
+ int is_normal_group = FALSE; /* "Normal" group */
+# define is_menu_group 0
+# define is_tooltip_group 0
+
+ /*
+ * If no argument, list current highlighting.
+ */
+ if (ends_excmd(*line)) {
+ for (i = 1; i <= highlight_ga.ga_len && !got_int; ++i)
+ /* TODO: only call when the group has attributes set */
+ highlight_list_one((int)i);
+ return;
+ }
+
+ /*
+ * Isolate the name.
+ */
+ name_end = skiptowhite(line);
+ linep = skipwhite(name_end);
+
+ /*
+ * Check for "default" argument.
+ */
+ if (STRNCMP(line, "default", name_end - line) == 0) {
+ dodefault = TRUE;
+ line = linep;
+ name_end = skiptowhite(line);
+ linep = skipwhite(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;
+
+ /*
+ * ":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_list_one(id);
+ return;
+ }
+
+ /*
+ * 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;
+ int from_id;
+ int to_id;
+
+ from_end = skiptowhite(from_start);
+ to_start = skipwhite(from_end);
+ to_end = skiptowhite(to_start);
+
+ if (ends_excmd(*from_start) || ends_excmd(*to_start)) {
+ EMSG2(_("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);
+ return;
+ }
+
+ from_id = syn_check_group(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));
+
+ 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
+ */
+ if (to_id > 0 && !forceit && !init
+ && hl_has_settings(from_id - 1, dodefault)) {
+ if (sourcing_name == NULL && !dodefault)
+ EMSG(_("E414: group has settings, highlight link ignored"));
+ } else {
+ 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;
+ redraw_all_later(SOME_VALID);
+ }
+ }
+
+ /* Only call highlight_changed() once, after sourcing a syntax file */
+ need_highlight_changed = TRUE;
+
+ return;
+ }
+
+ if (doclear) {
+ /*
+ * ":highlight clear [group]" command.
+ */
+ line = linep;
+ if (ends_excmd(*line)) {
+ do_unlet((char_u *)"colors_name", TRUE);
+ restore_cterm_colors();
+
+ /*
+ * Clear all default highlight groups and load the defaults.
+ */
+ for (idx = 0; idx < highlight_ga.ga_len; ++idx)
+ highlight_clear(idx);
+ init_highlight(TRUE, TRUE);
+ highlight_changed();
+ redraw_later_clear();
+ return;
+ }
+ name_end = skiptowhite(line);
+ linep = skipwhite(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) */
+ return;
+ 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 (STRCMP(HL_TABLE()[idx].sg_name_u, "NORMAL") == 0)
+ is_normal_group = TRUE;
+
+ /* Clear the highlighting for ":hi clear {group}" and ":hi clear". */
+ if (doclear || (forceit && init)) {
+ highlight_clear(idx);
+ if (!doclear)
+ HL_TABLE()[idx].sg_set = 0;
+ }
+
+ if (!doclear)
+ while (!ends_excmd(*linep)) {
+ key_start = linep;
+ if (*linep == '=') {
+ EMSG2(_("E415: unexpected equal sign: %s"), key_start);
+ error = TRUE;
+ break;
+ }
+
+ /*
+ * Isolate the key ("term", "ctermfg", "ctermbg", "font", "guifg" or
+ * "guibg").
+ */
+ while (*linep && !vim_iswhite(*linep) && *linep != '=')
+ ++linep;
+ vim_free(key);
+ key = vim_strnsave_up(key_start, (int)(linep - key_start));
+ if (key == NULL) {
+ error = TRUE;
+ break;
+ }
+ linep = skipwhite(linep);
+
+ if (STRCMP(key, "NONE") == 0) {
+ if (!init || HL_TABLE()[idx].sg_set == 0) {
+ if (!init)
+ HL_TABLE()[idx].sg_set |= SG_TERM+SG_CTERM+SG_GUI;
+ highlight_clear(idx);
+ }
+ continue;
+ }
+
+ /*
+ * Check for the equal sign.
+ */
+ if (*linep != '=') {
+ EMSG2(_("E416: missing equal sign: %s"), key_start);
+ error = TRUE;
+ break;
+ }
+ ++linep;
+
+ /*
+ * Isolate the argument.
+ */
+ linep = skipwhite(linep);
+ if (*linep == '\'') { /* guifg='color name' */
+ arg_start = ++linep;
+ linep = vim_strchr(linep, '\'');
+ if (linep == NULL) {
+ EMSG2(_(e_invarg2), key_start);
+ error = TRUE;
+ break;
+ }
+ } else {
+ arg_start = linep;
+ linep = skiptowhite(linep);
+ }
+ if (linep == arg_start) {
+ EMSG2(_("E417: missing argument: %s"), key_start);
+ error = TRUE;
+ break;
+ }
+ vim_free(arg);
+ arg = vim_strnsave(arg_start, (int)(linep - arg_start));
+ if (arg == NULL) {
+ error = TRUE;
+ break;
+ }
+ if (*linep == '\'')
+ ++linep;
+
+ /*
+ * Store the argument.
+ */
+ if ( STRCMP(key, "TERM") == 0
+ || STRCMP(key, "CTERM") == 0
+ || STRCMP(key, "GUI") == 0) {
+ attr = 0;
+ off = 0;
+ while (arg[off] != NUL) {
+ for (i = sizeof(hl_attr_table) / sizeof(int); --i >= 0; ) {
+ len = (int)STRLEN(hl_name_table[i]);
+ if (STRNICMP(arg + off, hl_name_table[i], len) == 0) {
+ attr |= hl_attr_table[i];
+ off += len;
+ break;
+ }
+ }
+ if (i < 0) {
+ EMSG2(_("E418: Illegal value: %s"), arg);
+ error = TRUE;
+ break;
+ }
+ if (arg[off] == ',') /* another one follows */
+ ++off;
+ }
+ if (error)
+ break;
+ if (*key == 'T') {
+ if (!init || !(HL_TABLE()[idx].sg_set & SG_TERM)) {
+ if (!init)
+ HL_TABLE()[idx].sg_set |= SG_TERM;
+ HL_TABLE()[idx].sg_term = attr;
+ }
+ } else if (*key == 'C') {
+ if (!init || !(HL_TABLE()[idx].sg_set & SG_CTERM)) {
+ if (!init)
+ HL_TABLE()[idx].sg_set |= SG_CTERM;
+ HL_TABLE()[idx].sg_cterm = attr;
+ HL_TABLE()[idx].sg_cterm_bold = FALSE;
+ }
+ } else {
+ if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI)) {
+ 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) {
+ if (!init || !(HL_TABLE()[idx].sg_set & SG_CTERM)) {
+ 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;
+ }
+
+ if (VIM_ISDIGIT(*arg))
+ color = atoi((char *)arg);
+ else if (STRICMP(arg, "fg") == 0) {
+ if (cterm_normal_fg_color)
+ color = cterm_normal_fg_color - 1;
+ else {
+ EMSG(_("E419: FG color unknown"));
+ error = TRUE;
+ break;
+ }
+ } else if (STRICMP(arg, "bg") == 0) {
+ if (cterm_normal_bg_color > 0)
+ color = cterm_normal_bg_color - 1;
+ else {
+ EMSG(_("E420: BG color unknown"));
+ 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};
+#if defined(__QNXNTO__)
+ static int *color_numbers_8_qansi = color_numbers_8;
+ /* On qnx, the 8 & 16 color arrays are the same */
+ if (STRNCMP(T_NAME, "qansi", 5) == 0)
+ color_numbers_8_qansi = color_numbers_16;
+#endif
+
+ /* reduce calls to STRICMP a bit, it can be slow */
+ off = TOUPPER_ASC(*arg);
+ for (i = (sizeof(color_names) / sizeof(char *)); --i >= 0; )
+ if (off == color_names[i][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;
+ 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 */
+#if defined(__QNXNTO__)
+ color = color_numbers_8_qansi[i];
+#else
+ color = color_numbers_8[i];
+#endif
+ 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) {
+ /*
+ * Guess: if the termcap entry ends in 'm', it is
+ * probably an xterm-like terminal. Use the changed
+ * order for colors.
+ */
+ if (*T_CAF != NUL)
+ p = T_CAF;
+ else
+ p = T_CSF;
+ if (*p != NUL && *(p + STRLEN(p) - 1) == 'm')
+ switch (t_colors) {
+ case 16:
+ color = color_numbers_8[i];
+ break;
+ case 88:
+ color = color_numbers_88[i];
+ break;
+ case 256:
+ color = color_numbers_256[i];
+ break;
+ }
+ }
+ }
+ }
+ /* 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;
+ if (termcap_active && color >= 0)
+ term_fg_color(color);
+ }
+ }
+ } else {
+ HL_TABLE()[idx].sg_cterm_bg = color + 1;
+ if (is_normal_group) {
+ cterm_normal_bg_color = color + 1;
+ {
+ must_redraw = CLEAR;
+ if (color >= 0) {
+ if (termcap_active)
+ term_bg_color(color);
+ 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);
+ }
+ }
+ }
+ }
+ }
+ } else if (STRCMP(key, "GUIFG") == 0) {
+ if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI)) {
+ if (!init)
+ HL_TABLE()[idx].sg_set |= SG_GUI;
+
+ vim_free(HL_TABLE()[idx].sg_gui_fg_name);
+ if (STRCMP(arg, "NONE"))
+ HL_TABLE()[idx].sg_gui_fg_name = vim_strsave(arg);
+ else
+ HL_TABLE()[idx].sg_gui_fg_name = NULL;
+ }
+ } else if (STRCMP(key, "GUIBG") == 0) {
+ if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI)) {
+ if (!init)
+ HL_TABLE()[idx].sg_set |= SG_GUI;
+
+ vim_free(HL_TABLE()[idx].sg_gui_bg_name);
+ if (STRCMP(arg, "NONE") != 0)
+ HL_TABLE()[idx].sg_gui_bg_name = vim_strsave(arg);
+ else
+ HL_TABLE()[idx].sg_gui_bg_name = NULL;
+ }
+ } else if (STRCMP(key, "GUISP") == 0) {
+ if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI)) {
+ if (!init)
+ HL_TABLE()[idx].sg_set |= SG_GUI;
+
+ vim_free(HL_TABLE()[idx].sg_gui_sp_name);
+ if (STRCMP(arg, "NONE") != 0)
+ HL_TABLE()[idx].sg_gui_sp_name = vim_strsave(arg);
+ else
+ HL_TABLE()[idx].sg_gui_sp_name = NULL;
+ }
+ } else if (STRCMP(key, "START") == 0 || STRCMP(key, "STOP") == 0) {
+ char_u buf[100];
+ char_u *tname;
+
+ if (!init)
+ HL_TABLE()[idx].sg_set |= SG_TERM;
+
+ /*
+ * The "start" and "stop" arguments can be a literal escape
+ * sequence, or a comma separated list of terminal codes.
+ */
+ if (STRNCMP(arg, "t_", 2) == 0) {
+ off = 0;
+ buf[0] = 0;
+ while (arg[off] != NUL) {
+ /* Isolate one termcap name */
+ for (len = 0; arg[off + len] &&
+ arg[off + len] != ','; ++len)
+ ;
+ tname = vim_strnsave(arg + off, len);
+ if (tname == NULL) { /* out of memory */
+ error = TRUE;
+ break;
+ }
+ /* lookup the escape sequence for the item */
+ p = get_term_code(tname);
+ vim_free(tname);
+ if (p == NULL) /* ignore non-existing things */
+ p = (char_u *)"";
+
+ /* Append it to the already found stuff */
+ if ((int)(STRLEN(buf) + STRLEN(p)) >= 99) {
+ EMSG2(_("E422: terminal code too long: %s"), arg);
+ error = TRUE;
+ break;
+ }
+ STRCAT(buf, p);
+
+ /* Advance to the next item */
+ off += len;
+ if (arg[off] == ',') /* another one follows */
+ ++off;
+ }
+ } else {
+ /*
+ * Copy characters from arg[] to buf[], translating <> codes.
+ */
+ for (p = arg, off = 0; off < 100 - 6 && *p; ) {
+ len = trans_special(&p, buf + off, FALSE);
+ if (len > 0) /* recognized special char */
+ off += len;
+ else /* copy as normal char */
+ buf[off++] = *p++;
+ }
+ buf[off] = NUL;
+ }
+ if (error)
+ break;
+
+ if (STRCMP(buf, "NONE") == 0) /* resetting the value */
+ p = NULL;
+ else
+ p = vim_strsave(buf);
+ if (key[2] == 'A') {
+ vim_free(HL_TABLE()[idx].sg_start);
+ HL_TABLE()[idx].sg_start = p;
+ } else {
+ vim_free(HL_TABLE()[idx].sg_stop);
+ HL_TABLE()[idx].sg_stop = p;
+ }
+ } else {
+ EMSG2(_("E423: Illegal argument: %s"), key_start);
+ error = TRUE;
+ break;
+ }
+
+ /*
+ * 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);
+ }
+
+ /*
+ * 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_term_attr = 0;
+ HL_TABLE()[idx].sg_cterm_attr = 0;
+ } else
+ set_hl_attr(idx);
+ HL_TABLE()[idx].sg_scriptID = current_SID;
+ redraw_all_later(NOT_VALID);
+ }
+ vim_free(key);
+ vim_free(arg);
+
+ /* Only call highlight_changed() once, after sourcing a syntax file */
+ need_highlight_changed = TRUE;
+}
+
+#if defined(EXITFREE) || defined(PROTO)
+void free_highlight() {
+ int i;
+
+ for (i = 0; i < highlight_ga.ga_len; ++i) {
+ highlight_clear(i);
+ vim_free(HL_TABLE()[i].sg_name);
+ vim_free(HL_TABLE()[i].sg_name_u);
+ }
+ ga_clear(&highlight_ga);
+}
+
+#endif
+
+/*
+ * Reset the cterm colors to what they were before Vim was started, if
+ * possible. Otherwise reset them to zero.
+ */
+void restore_cterm_colors() {
+ cterm_normal_fg_color = 0;
+ cterm_normal_fg_bold = 0;
+ cterm_normal_bg_color = 0;
+}
+
+/*
+ * Return TRUE if highlight group "idx" has any settings.
+ * When "check_link" is TRUE also check for an existing link.
+ */
+static int hl_has_settings(idx, check_link)
+int idx;
+int check_link;
+{
+ return HL_TABLE()[idx].sg_term_attr != 0
+ || HL_TABLE()[idx].sg_cterm_attr != 0
+ || (check_link && (HL_TABLE()[idx].sg_set & SG_LINK));
+}
+
+/*
+ * Clear highlighting for one group.
+ */
+static void highlight_clear(idx)
+int idx;
+{
+ HL_TABLE()[idx].sg_term = 0;
+ vim_free(HL_TABLE()[idx].sg_start);
+ HL_TABLE()[idx].sg_start = NULL;
+ vim_free(HL_TABLE()[idx].sg_stop);
+ HL_TABLE()[idx].sg_stop = NULL;
+ HL_TABLE()[idx].sg_term_attr = 0;
+ HL_TABLE()[idx].sg_cterm = 0;
+ 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_cterm_attr = 0;
+ HL_TABLE()[idx].sg_gui = 0;
+ vim_free(HL_TABLE()[idx].sg_gui_fg_name);
+ HL_TABLE()[idx].sg_gui_fg_name = NULL;
+ vim_free(HL_TABLE()[idx].sg_gui_bg_name);
+ HL_TABLE()[idx].sg_gui_bg_name = NULL;
+ vim_free(HL_TABLE()[idx].sg_gui_sp_name);
+ HL_TABLE()[idx].sg_gui_sp_name = NULL;
+ /* Clear the script ID only when there is no link, since that is not
+ * cleared. */
+ if (HL_TABLE()[idx].sg_link == 0)
+ HL_TABLE()[idx].sg_scriptID = 0;
+}
+
+
+/*
+ * 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 term_attr_table = {0, 0, 0, 0, NULL};
+
+#define TERM_ATTR_ENTRY(idx) ((attrentry_T *)term_attr_table.ga_data)[idx]
+
+static garray_T cterm_attr_table = {0, 0, 0, 0, NULL};
+
+#define CTERM_ATTR_ENTRY(idx) ((attrentry_T *)cterm_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, cterm_attr_table or gui_attr_table
+ * if the combination is new.
+ * Return 0 for error (no more room).
+ */
+static int get_attr_entry(table, aep)
+garray_T *table;
+attrentry_T *aep;
+{
+ int i;
+ attrentry_T *taep;
+ static int recursive = FALSE;
+
+ /*
+ * Init the table, in case it wasn't done yet.
+ */
+ table->ga_itemsize = sizeof(attrentry_T);
+ table->ga_growsize = 7;
+
+ /*
+ * Try to find an entry with the same specifications.
+ */
+ for (i = 0; i < table->ga_len; ++i) {
+ taep = &(((attrentry_T *)table->ga_data)[i]);
+ if ( aep->ae_attr == taep->ae_attr
+ && (
+ (table == &term_attr_table
+ && (aep->ae_u.term.start == NULL)
+ == (taep->ae_u.term.start == NULL)
+ && (aep->ae_u.term.start == NULL
+ || STRCMP(aep->ae_u.term.start,
+ taep->ae_u.term.start) == 0)
+ && (aep->ae_u.term.stop == NULL)
+ == (taep->ae_u.term.stop == NULL)
+ && (aep->ae_u.term.stop == NULL
+ || STRCMP(aep->ae_u.term.stop,
+ taep->ae_u.term.stop) == 0))
+ || (table == &cterm_attr_table
+ && aep->ae_u.cterm.fg_color
+ == taep->ae_u.cterm.fg_color
+ && aep->ae_u.cterm.bg_color
+ == taep->ae_u.cterm.bg_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 (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.
+ */
+ if (ga_grow(table, 1) == FAIL)
+ return 0;
+
+ taep = &(((attrentry_T *)table->ga_data)[table->ga_len]);
+ vim_memset(taep, 0, sizeof(attrentry_T));
+ taep->ae_attr = aep->ae_attr;
+ if (table == &term_attr_table) {
+ if (aep->ae_u.term.start == NULL)
+ taep->ae_u.term.start = NULL;
+ else
+ taep->ae_u.term.start = vim_strsave(aep->ae_u.term.start);
+ if (aep->ae_u.term.stop == NULL)
+ taep->ae_u.term.stop = NULL;
+ else
+ taep->ae_u.term.stop = vim_strsave(aep->ae_u.term.stop);
+ } else if (table == &cterm_attr_table) {
+ taep->ae_u.cterm.fg_color = aep->ae_u.cterm.fg_color;
+ taep->ae_u.cterm.bg_color = aep->ae_u.cterm.bg_color;
+ }
+ ++table->ga_len;
+ return table->ga_len - 1 + ATTR_OFF;
+}
+
+/*
+ * Clear all highlight tables.
+ */
+void clear_hl_tables() {
+ int i;
+ attrentry_T *taep;
+
+ for (i = 0; i < term_attr_table.ga_len; ++i) {
+ taep = &(((attrentry_T *)term_attr_table.ga_data)[i]);
+ vim_free(taep->ae_u.term.start);
+ vim_free(taep->ae_u.term.stop);
+ }
+ ga_clear(&term_attr_table);
+ ga_clear(&cterm_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(char_attr, prim_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 (char_attr <= HL_ALL && prim_attr <= HL_ALL)
+ return char_attr | prim_attr;
+
+ if (t_colors > 1) {
+ if (char_attr > HL_ALL)
+ char_aep = syn_cterm_attr2entry(char_attr);
+ if (char_aep != NULL)
+ new_en = *char_aep;
+ else {
+ vim_memset(&new_en, 0, sizeof(new_en));
+ if (char_attr <= HL_ALL)
+ new_en.ae_attr = char_attr;
+ }
+
+ if (prim_attr <= HL_ALL)
+ new_en.ae_attr |= prim_attr;
+ else {
+ spell_aep = syn_cterm_attr2entry(prim_attr);
+ if (spell_aep != NULL) {
+ new_en.ae_attr |= spell_aep->ae_attr;
+ if (spell_aep->ae_u.cterm.fg_color > 0)
+ new_en.ae_u.cterm.fg_color = spell_aep->ae_u.cterm.fg_color;
+ if (spell_aep->ae_u.cterm.bg_color > 0)
+ new_en.ae_u.cterm.bg_color = spell_aep->ae_u.cterm.bg_color;
+ }
+ }
+ return get_attr_entry(&cterm_attr_table, &new_en);
+ }
+
+ if (char_attr > HL_ALL)
+ char_aep = syn_term_attr2entry(char_attr);
+ if (char_aep != NULL)
+ new_en = *char_aep;
+ else {
+ vim_memset(&new_en, 0, sizeof(new_en));
+ if (char_attr <= HL_ALL)
+ new_en.ae_attr = char_attr;
+ }
+
+ if (prim_attr <= HL_ALL)
+ new_en.ae_attr |= prim_attr;
+ else {
+ spell_aep = syn_term_attr2entry(prim_attr);
+ if (spell_aep != NULL) {
+ new_en.ae_attr |= spell_aep->ae_attr;
+ if (spell_aep->ae_u.term.start != NULL) {
+ new_en.ae_u.term.start = spell_aep->ae_u.term.start;
+ new_en.ae_u.term.stop = spell_aep->ae_u.term.stop;
+ }
+ }
+ }
+ return get_attr_entry(&term_attr_table, &new_en);
+}
+
+
+/*
+ * Get the highlight attributes (HL_BOLD etc.) from an attribute nr.
+ * Only to be used when "attr" > HL_ALL.
+ */
+int syn_attr2attr(attr)
+int attr;
+{
+ attrentry_T *aep;
+
+ if (t_colors > 1)
+ aep = syn_cterm_attr2entry(attr);
+ else
+ aep = syn_term_attr2entry(attr);
+
+ if (aep == NULL) /* highlighting not set */
+ return 0;
+ return aep->ae_attr;
+}
+
+
+attrentry_T * syn_term_attr2entry(attr)
+int attr;
+{
+ attr -= ATTR_OFF;
+ if (attr >= term_attr_table.ga_len) /* did ":syntax clear" */
+ return NULL;
+ return &(TERM_ATTR_ENTRY(attr));
+}
+
+attrentry_T * syn_cterm_attr2entry(attr)
+int attr;
+{
+ attr -= ATTR_OFF;
+ if (attr >= cterm_attr_table.ga_len) /* did ":syntax clear" */
+ return NULL;
+ return &(CTERM_ATTR_ENTRY(attr));
+}
+
+#define LIST_ATTR 1
+#define LIST_STRING 2
+#define LIST_INT 3
+
+static void highlight_list_one(id)
+int id;
+{
+ struct hl_group *sgp;
+ int didh = FALSE;
+
+ sgp = &HL_TABLE()[id - 1]; /* index is ID minus one */
+
+ didh = highlight_list_arg(id, didh, LIST_ATTR,
+ sgp->sg_term, NULL, "term");
+ didh = highlight_list_arg(id, didh, LIST_STRING,
+ 0, sgp->sg_start, "start");
+ didh = highlight_list_arg(id, didh, LIST_STRING,
+ 0, sgp->sg_stop, "stop");
+
+ didh = highlight_list_arg(id, didh, LIST_ATTR,
+ sgp->sg_cterm, NULL, "cterm");
+ didh = highlight_list_arg(id, didh, LIST_INT,
+ sgp->sg_cterm_fg, NULL, "ctermfg");
+ didh = highlight_list_arg(id, didh, LIST_INT,
+ sgp->sg_cterm_bg, NULL, "ctermbg");
+
+ didh = highlight_list_arg(id, didh, LIST_ATTR,
+ sgp->sg_gui, NULL, "gui");
+ didh = highlight_list_arg(id, didh, LIST_STRING,
+ 0, sgp->sg_gui_fg_name, "guifg");
+ didh = highlight_list_arg(id, didh, LIST_STRING,
+ 0, sgp->sg_gui_bg_name, "guibg");
+ didh = highlight_list_arg(id, didh, LIST_STRING,
+ 0, sgp->sg_gui_sp_name, "guisp");
+
+ 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));
+ msg_putchar(' ');
+ msg_outtrans(HL_TABLE()[HL_TABLE()[id - 1].sg_link - 1].sg_name);
+ }
+
+ if (!didh)
+ highlight_list_arg(id, didh, LIST_STRING, 0, (char_u *)"cleared", "");
+ if (p_verbose > 0)
+ last_set_msg(sgp->sg_scriptID);
+}
+
+static int highlight_list_arg(id, didh, type, iarg, sarg, name)
+int id;
+int didh;
+int type;
+int iarg;
+char_u *sarg;
+char *name;
+{
+ char_u buf[100];
+ char_u *ts;
+ int i;
+
+ 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)
+ ts = sarg;
+ else { /* type == LIST_ATTR */
+ buf[0] = NUL;
+ for (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);
+ iarg &= ~hl_attr_table[i]; /* don't want "inverse" */
+ }
+ }
+ }
+
+ (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_outtrans(ts);
+ }
+ }
+ return didh;
+}
+
+/*
+ * Return "1" if highlight group "id" has attribute "flag".
+ * Return NULL otherwise.
+ */
+char_u * highlight_has_attr(id, flag, modec)
+int id;
+int flag;
+int modec; /* 'g' for GUI, 'c' for cterm, 't' for term */
+{
+ int attr;
+
+ if (id <= 0 || id > highlight_ga.ga_len)
+ return NULL;
+
+ if (modec == 'g')
+ attr = HL_TABLE()[id - 1].sg_gui;
+ else if (modec == 'c')
+ attr = HL_TABLE()[id - 1].sg_cterm;
+ else
+ attr = HL_TABLE()[id - 1].sg_term;
+
+ if (attr & flag)
+ return (char_u *)"1";
+ return NULL;
+}
+
+/*
+ * Return color name of highlight group "id".
+ */
+char_u * highlight_color(id, what, modec)
+int id;
+char_u *what; /* "font", "fg", "bg", "sp", "fg#", "bg#" or "sp#" */
+int modec; /* 'g' for GUI, 'c' for cterm, 't' for term */
+{
+ static char_u name[20];
+ int n;
+ int fg = FALSE;
+ int sp = FALSE;
+ int font = FALSE;
+
+ 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'))
+ return NULL;
+ if (modec == 'g') {
+ if (fg)
+ return HL_TABLE()[id - 1].sg_gui_fg_name;
+ if (sp)
+ return HL_TABLE()[id - 1].sg_gui_sp_name;
+ return HL_TABLE()[id - 1].sg_gui_bg_name;
+ }
+ if (font || sp)
+ return NULL;
+ if (modec == 'c') {
+ if (fg)
+ n = HL_TABLE()[id - 1].sg_cterm_fg - 1;
+ else
+ n = HL_TABLE()[id - 1].sg_cterm_bg - 1;
+ sprintf((char *)name, "%d", n);
+ return name;
+ }
+ /* term doesn't have color */
+ return NULL;
+}
+
+#if (defined(FEAT_SYN_HL) && defined(FEAT_GUI) && defined(FEAT_PRINTER)) \
+ || defined(PROTO)
+/*
+ * Return color name of highlight group "id" as RGB value.
+ */
+long_u highlight_gui_color_rgb(id, fg)
+int id;
+int fg; /* TRUE = fg, FALSE = bg */
+{
+ guicolor_T color;
+
+ if (id <= 0 || id > highlight_ga.ga_len)
+ return 0L;
+
+ if (fg)
+ color = HL_TABLE()[id - 1].sg_gui_fg;
+ else
+ color = HL_TABLE()[id - 1].sg_gui_bg;
+
+ if (color == INVALCOLOR)
+ return 0L;
+
+ return gui_mch_get_rgb(color);
+}
+#endif
+
+/*
+ * Output the syntax list header.
+ * Return TRUE when started a new line.
+ */
+static int syn_list_header(did_header, outlen, id)
+int did_header; /* did header already */
+int outlen; /* length of string that comes */
+int id; /* highlight group id */
+{
+ int endcol = 19;
+ int newline = TRUE;
+
+ if (!did_header) {
+ msg_putchar('\n');
+ 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;
+ } else {
+ if (msg_col >= endcol) /* wrap around is like starting a new line */
+ newline = FALSE;
+ }
+
+ if (msg_col >= endcol) /* output at least one space */
+ endcol = msg_col + 1;
+ if (Columns <= endcol) /* avoid hang for tiny window */
+ endcol = Columns - 1;
+
+ msg_advance(endcol);
+
+ /* Show "xxx" with the attributes. */
+ if (!did_header) {
+ msg_puts_attr((char_u *)"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(idx)
+int idx; /* index in array */
+{
+ attrentry_T at_en;
+ 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;
+
+ /*
+ * For the term mode: If there are other than "normal" highlighting
+ * attributes, need to allocate an attr number.
+ */
+ if (sgp->sg_start == NULL && sgp->sg_stop == NULL)
+ sgp->sg_term_attr = sgp->sg_term;
+ else {
+ at_en.ae_attr = sgp->sg_term;
+ at_en.ae_u.term.start = sgp->sg_start;
+ at_en.ae_u.term.stop = sgp->sg_stop;
+ sgp->sg_term_attr = get_attr_entry(&term_attr_table, &at_en);
+ }
+
+ /*
+ * For the color term mode: If there are other than "normal"
+ * highlighting attributes, need to allocate an attr number.
+ */
+ if (sgp->sg_cterm_fg == 0 && sgp->sg_cterm_bg == 0)
+ sgp->sg_cterm_attr = sgp->sg_cterm;
+ else {
+ at_en.ae_attr = sgp->sg_cterm;
+ at_en.ae_u.cterm.fg_color = sgp->sg_cterm_fg;
+ at_en.ae_u.cterm.bg_color = sgp->sg_cterm_bg;
+ sgp->sg_cterm_attr = get_attr_entry(&cterm_attr_table, &at_en);
+ }
+}
+
+/*
+ * Lookup a highlight group name and return it's ID.
+ * If it is not found, 0 is returned.
+ */
+int syn_name2id(name)
+char_u *name;
+{
+ int i;
+ char_u name_u[200];
+
+ /* Avoid using stricmp() too much, it's slow on some systems */
+ /* Avoid alloc()/free(), these are slow too. ID names over 200 chars
+ * don't deserve to be found! */
+ vim_strncpy(name_u, name, 199);
+ vim_strup(name_u);
+ for (i = highlight_ga.ga_len; --i >= 0; )
+ if (HL_TABLE()[i].sg_name_u != NULL
+ && STRCMP(name_u, HL_TABLE()[i].sg_name_u) == 0)
+ break;
+ return i + 1;
+}
+
+/*
+ * Return TRUE if highlight group "name" exists.
+ */
+int highlight_exists(name)
+char_u *name;
+{
+ return syn_name2id(name) > 0;
+}
+
+/*
+ * Return the name of highlight group "id".
+ * When not a valid ID return an empty string.
+ */
+char_u * syn_id2name(id)
+int id;
+{
+ if (id <= 0 || id > highlight_ga.ga_len)
+ return (char_u *)"";
+ return HL_TABLE()[id - 1].sg_name;
+}
+
+/*
+ * Like syn_name2id(), but take a pointer + length argument.
+ */
+int syn_namen2id(linep, len)
+char_u *linep;
+int len;
+{
+ char_u *name;
+ int id = 0;
+
+ name = vim_strnsave(linep, len);
+ if (name != NULL) {
+ id = syn_name2id(name);
+ vim_free(name);
+ }
+ 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(pp, len)
+char_u *pp;
+int len;
+{
+ int id;
+ char_u *name;
+
+ name = vim_strnsave(pp, len);
+ if (name == NULL)
+ return 0;
+
+ id = syn_name2id(name);
+ if (id == 0) /* doesn't exist yet */
+ id = syn_add_group(name);
+ else
+ vim_free(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.
+ */
+static int syn_add_group(name)
+char_u *name;
+{
+ char_u *p;
+
+ /* Check that the name is ASCII letters, digits and underscore. */
+ for (p = name; *p != NUL; ++p) {
+ if (!vim_isprintc(*p)) {
+ EMSG(_("E669: Unprintable character in group name"));
+ vim_free(name);
+ return 0;
+ } 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(_("W18: Invalid character in group name"));
+ break;
+ }
+ }
+
+ /*
+ * First call for this growarray: init growing array.
+ */
+ if (highlight_ga.ga_data == NULL) {
+ highlight_ga.ga_itemsize = sizeof(struct hl_group);
+ highlight_ga.ga_growsize = 10;
+ }
+
+ if (highlight_ga.ga_len >= MAX_HL_ID) {
+ EMSG(_("E849: Too many highlight and syntax groups"));
+ vim_free(name);
+ return 0;
+ }
+
+ /*
+ * Make room for at least one other syntax_highlight entry.
+ */
+ if (ga_grow(&highlight_ga, 1) == FAIL) {
+ vim_free(name);
+ return 0;
+ }
+
+ vim_memset(&(HL_TABLE()[highlight_ga.ga_len]), 0, sizeof(struct hl_group));
+ HL_TABLE()[highlight_ga.ga_len].sg_name = name;
+ HL_TABLE()[highlight_ga.ga_len].sg_name_u = vim_strsave_up(name);
+ ++highlight_ga.ga_len;
+
+ 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.
+ */
+static void syn_unadd_group() {
+ --highlight_ga.ga_len;
+ vim_free(HL_TABLE()[highlight_ga.ga_len].sg_name);
+ vim_free(HL_TABLE()[highlight_ga.ga_len].sg_name_u);
+}
+
+/*
+ * Translate a group ID to highlight attributes.
+ */
+int syn_id2attr(hl_id)
+int hl_id;
+{
+ int attr;
+ struct hl_group *sgp;
+
+ hl_id = syn_get_final_id(hl_id);
+ sgp = &HL_TABLE()[hl_id - 1]; /* index is ID minus one */
+
+ if (t_colors > 1)
+ attr = sgp->sg_cterm_attr;
+ else
+ attr = sgp->sg_term_attr;
+
+ return attr;
+}
+
+
+/*
+ * Translate a group ID to the final group ID (following links).
+ */
+int syn_get_final_id(hl_id)
+int hl_id;
+{
+ int count;
+ struct hl_group *sgp;
+
+ if (hl_id > highlight_ga.ga_len || hl_id < 1)
+ return 0; /* Can be called from eval!! */
+
+ /*
+ * Follow links until there is no more.
+ * Look out for loops! Break after 100 links.
+ */
+ for (count = 100; --count >= 0; ) {
+ sgp = &HL_TABLE()[hl_id - 1]; /* index is ID minus one */
+ if (sgp->sg_link == 0 || sgp->sg_link > highlight_ga.ga_len)
+ break;
+ hl_id = sgp->sg_link;
+ }
+
+ return hl_id;
+}
+
+
+/*
+ * Translate the 'highlight' option into attributes in highlight_attr[] and
+ * set up the user highlights User1..9. If FEAT_STL_OPT is in use, 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() {
+ int hlf;
+ int i;
+ char_u *p;
+ int attr;
+ char_u *end;
+ int id;
+#ifdef USER_HIGHLIGHT
+ char_u userhl[10];
+ int id_SNC = -1;
+ int id_S = -1;
+ int hlcnt;
+#endif
+ 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;
+ for (; *p && *p != ','; ++p) { /* parse upto comma */
+ if (vim_iswhite(*p)) /* ignore white space */
+ continue;
+
+ if (attr > HL_ALL) /* 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;
+ 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 defined(FEAT_STL_OPT) && defined(USER_HIGHLIGHT)
+ 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);
+#endif
+ break;
+ default: return FAIL;
+ }
+ }
+ highlight_attr[hlf] = attr;
+
+ p = skip_to_option_part(p); /* skip comma and spaces */
+ }
+ }
+
+#ifdef USER_HIGHLIGHT
+ /* Setup the user highlights
+ *
+ * Temporarily utilize 10 more hl entries. Have to be in there
+ * simultaneously in case of table overflows in get_attr_entry()
+ */
+ if (ga_grow(&highlight_ga, 10) == FAIL)
+ return FAIL;
+ hlcnt = highlight_ga.ga_len;
+ if (id_S == 0) { /* Make sure id_S is always valid to simplify code below */
+ vim_memset(&HL_TABLE()[hlcnt + 9], 0, sizeof(struct hl_group));
+ HL_TABLE()[hlcnt + 9].sg_term = highlight_attr[HLF_S];
+ id_S = hlcnt + 10;
+ }
+ for (i = 0; i < 9; i++) {
+ sprintf((char *)userhl, "User%d", i + 1);
+ id = syn_name2id(userhl);
+ if (id == 0) {
+ highlight_user[i] = 0;
+ highlight_stlnc[i] = 0;
+ } else {
+ struct hl_group *hlt = HL_TABLE();
+
+ highlight_user[i] = syn_id2attr(id);
+ if (id_SNC == 0) {
+ vim_memset(&hlt[hlcnt + i], 0, sizeof(struct hl_group));
+ hlt[hlcnt + i].sg_term = highlight_attr[HLF_SNC];
+ hlt[hlcnt + i].sg_cterm = highlight_attr[HLF_SNC];
+ hlt[hlcnt + i].sg_gui = highlight_attr[HLF_SNC];
+ } else
+ mch_memmove(&hlt[hlcnt + i],
+ &hlt[id_SNC - 1],
+ sizeof(struct hl_group));
+ hlt[hlcnt + i].sg_link = 0;
+
+ /* Apply difference between UserX and HLF_S to HLF_SNC */
+ hlt[hlcnt + i].sg_term ^=
+ hlt[id - 1].sg_term ^ hlt[id_S - 1].sg_term;
+ if (hlt[id - 1].sg_start != hlt[id_S - 1].sg_start)
+ hlt[hlcnt + i].sg_start = hlt[id - 1].sg_start;
+ if (hlt[id - 1].sg_stop != hlt[id_S - 1].sg_stop)
+ hlt[hlcnt + i].sg_stop = hlt[id - 1].sg_stop;
+ hlt[hlcnt + i].sg_cterm ^=
+ hlt[id - 1].sg_cterm ^ hlt[id_S - 1].sg_cterm;
+ if (hlt[id - 1].sg_cterm_fg != hlt[id_S - 1].sg_cterm_fg)
+ hlt[hlcnt + i].sg_cterm_fg = hlt[id - 1].sg_cterm_fg;
+ if (hlt[id - 1].sg_cterm_bg != hlt[id_S - 1].sg_cterm_bg)
+ hlt[hlcnt + i].sg_cterm_bg = hlt[id - 1].sg_cterm_bg;
+ hlt[hlcnt + i].sg_gui ^=
+ hlt[id - 1].sg_gui ^ hlt[id_S - 1].sg_gui;
+ highlight_ga.ga_len = hlcnt + i + 1;
+ set_hl_attr(hlcnt + i); /* At long last we can apply */
+ highlight_stlnc[i] = syn_id2attr(hlcnt + i + 1);
+ }
+ }
+ highlight_ga.ga_len = hlcnt;
+
+#endif /* USER_HIGHLIGHT */
+
+ return OK;
+}
+
+static void highlight_list __ARGS((void));
+static void highlight_list_two __ARGS((int cnt, int attr));
+
+/*
+ * Handle command line completion for :highlight command.
+ */
+void set_context_in_highlight_cmd(xp, arg)
+expand_T *xp;
+char_u *arg;
+{
+ char_u *p;
+
+ /* Default: expand group names */
+ xp->xp_context = EXPAND_HIGHLIGHT;
+ xp->xp_pattern = 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 */
+ include_default = 0;
+ if (STRNCMP("default", arg, p - arg) == 0) {
+ arg = skipwhite(p);
+ xp->xp_pattern = arg;
+ p = skiptowhite(arg);
+ }
+ if (*p != NUL) { /* past group name */
+ include_link = 0;
+ 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 (*p != NUL) /* past group name(s) */
+ xp->xp_context = EXPAND_NOTHING;
+ }
+ }
+ }
+}
+
+/*
+ * List highlighting matches in a nice way.
+ */
+static void highlight_list() {
+ int i;
+
+ 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(cnt, attr)
+int cnt;
+int attr;
+{
+ msg_puts_attr((char_u *)&("N \bI \b! \b"[cnt / 11]), attr);
+ msg_clr_eos();
+ out_flush();
+ ui_delay(cnt == 99 ? 40L : (long)cnt * 50L, FALSE);
+}
+
+
+#if defined(FEAT_CMDL_COMPL) || (defined(FEAT_SYN_HL) && defined(FEAT_EVAL)) \
+ || defined(FEAT_SIGNS) || defined(PROTO)
+/*
+ * Function given to ExpandGeneric() to obtain the list of group names.
+ * Also used for synIDattr() function.
+ */
+char_u * get_highlight_name(xp, idx)
+expand_T *xp UNUSED;
+int idx;
+{
+ 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)
+ return NULL;
+ return HL_TABLE()[idx].sg_name;
+}
+#endif
+
+
+/**************************************
+* End of Highlighting stuff *
+**************************************/
diff --git a/src/tag.c b/src/tag.c
new file mode 100644
index 0000000000..3f144936c7
--- /dev/null
+++ b/src/tag.c
@@ -0,0 +1,3107 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * 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.
+ */
+
+/*
+ * Code to handle tags and the tag stack
+ */
+
+#include "vim.h"
+
+/*
+ * Structure to hold pointers to various items in a tag line.
+ */
+typedef struct tag_pointers {
+ /* filled in by parse_tag_line(): */
+ char_u *tagname; /* start of tag name (skip "file:") */
+ char_u *tagname_end; /* char after tag name */
+ char_u *fname; /* first char of file name */
+ char_u *fname_end; /* char after file name */
+ char_u *command; /* first char of command */
+ /* filled in by parse_match(): */
+ char_u *command_end; /* first char after command */
+ char_u *tag_fname; /* file name of the tags file */
+ char_u *tagkind; /* "kind:" value */
+ char_u *tagkind_end; /* end of tagkind */
+} tagptrs_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 */
+#define MT_COUNT 16
+
+static char *mt_names[MT_COUNT/2] =
+{"FSC", "F C", "F ", "FS ", " SC", " C", " ", " S "};
+
+#define NOTAGFILE 99 /* return value for jumpto_tag */
+static char_u *nofile_fname = NULL; /* fname for NOTAGFILE error */
+
+static void taglen_advance __ARGS((int l));
+
+static int jumpto_tag __ARGS((char_u *lbuf, int forceit, int keep_help));
+static int parse_tag_line __ARGS((char_u *lbuf, tagptrs_T *tagp));
+static int test_for_static __ARGS((tagptrs_T *));
+static int parse_match __ARGS((char_u *lbuf, tagptrs_T *tagp));
+static char_u *tag_full_fname __ARGS((tagptrs_T *tagp));
+static char_u *expand_tag_fname __ARGS((char_u *fname, char_u *tag_fname,
+ int expand));
+static int test_for_current __ARGS((char_u *, char_u *, char_u *, char_u *));
+static int find_extra __ARGS((char_u **pp));
+
+static char_u *bottommsg = (char_u *)N_("E555: at bottom of tag stack");
+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.
+ */
+static taggy_T ptag_entry = {NULL, {INIT_POS_T(0, 0, 0), 0}, 0, 0};
+
+/*
+ * Jump to tag; handling of tag commands and tag stack
+ *
+ * *tag != NUL: ":tag {tag}", jump to new tag, add to tag stack
+ *
+ * type == DT_TAG: ":tag [tag]", jump to newer position or same tag again
+ * type == DT_HELP: like DT_TAG, but don't use regexp.
+ * type == DT_POP: ":pop" or CTRL-T, jump to old position
+ * type == DT_NEXT: jump to next match of same tag
+ * type == DT_PREV: jump to previous match of same tag
+ * type == DT_FIRST: jump to first match of same tag
+ * type == DT_LAST: jump to last match of same tag
+ * type == DT_SELECT: ":tselect [tag]", select tag from a list of all matches
+ * type == DT_JUMP: ":tjump [tag]", jump to tag or select tag from a list
+ * type == DT_CSCOPE: use cscope to find the tag
+ * type == DT_LTAG: use location list for displaying tag matches
+ * type == DT_FREE: free cached matches
+ *
+ * for cscope, returns TRUE if we jumped to tag or aborted, FALSE otherwise
+ */
+int do_tag(tag, type, count, forceit, verbose)
+char_u *tag; /* tag (pattern) to jump to */
+int type;
+int count;
+int forceit; /* :ta with ! */
+int verbose; /* print "tag not found" message */
+{
+ taggy_T *tagstack = curwin->w_tagstack;
+ int tagstackidx = curwin->w_tagstackidx;
+ int tagstacklen = curwin->w_tagstacklen;
+ int cur_match = 0;
+ int cur_fnum = curbuf->b_fnum;
+ int oldtagstackidx = tagstackidx;
+ int prevtagstackidx = tagstackidx;
+ int prev_num_matches;
+ int new_tag = FALSE;
+ int other_name;
+ int i, j, k;
+ int idx;
+ int ic;
+ char_u *p;
+ char_u *name;
+ int no_regexp = FALSE;
+ int error_cur_match = 0;
+ char_u *command_end;
+ int save_pos = FALSE;
+ fmark_T saved_fmark;
+ int taglen;
+ int jumped_to_tag = FALSE;
+ tagptrs_T tagp, tagp2;
+ int new_num_matches;
+ char_u **new_matches;
+ int attr;
+ int use_tagstack;
+ int skip_msg = FALSE;
+ char_u *buf_ffname = curbuf->b_ffname; /* name to use for
+ priority computation */
+
+ /* remember the matches for the last used tag */
+ static int num_matches = 0;
+ static int max_num_matches = 0; /* limit used for match search */
+ static char_u **matches = NULL;
+ static int flags;
+
+#ifdef EXITFREE
+ if (type == DT_FREE) {
+ /* remove the list of matches */
+ FreeWild(num_matches, matches);
+ cs_free_tags();
+ num_matches = 0;
+ return FALSE;
+ }
+#endif
+
+ if (type == DT_HELP) {
+ type = DT_TAG;
+ no_regexp = TRUE;
+ }
+
+ prev_num_matches = num_matches;
+ free_string_option(nofile_fname);
+ nofile_fname = NULL;
+
+ 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;
+ } else {
+ if (g_do_tagpreview != 0)
+ use_tagstack = FALSE;
+ else
+ use_tagstack = TRUE;
+
+ /* new pattern, add to the tag stack */
+ if (*tag != NUL
+ && (type == DT_TAG || type == DT_SELECT || type == DT_JUMP
+ || type == DT_LTAG
+ || type == DT_CSCOPE
+ )) {
+ if (g_do_tagpreview != 0) {
+ if (ptag_entry.tagname != NULL
+ && STRCMP(ptag_entry.tagname, tag) == 0) {
+ /* Jumping to same tag: keep the current match, so that
+ * the CursorHold autocommand example works. */
+ cur_match = ptag_entry.cur_match;
+ cur_fnum = ptag_entry.cur_fnum;
+ } else {
+ vim_free(ptag_entry.tagname);
+ if ((ptag_entry.tagname = vim_strsave(tag)) == NULL)
+ goto end_do_tag;
+ }
+ } else {
+ /*
+ * If the last used entry is not at the top, delete all tag
+ * stack entries above it.
+ */
+ while (tagstackidx < tagstacklen)
+ vim_free(tagstack[--tagstacklen].tagname);
+
+ /* if the tagstack is full: remove oldest entry */
+ if (++tagstacklen > TAGSTACKSIZE) {
+ tagstacklen = TAGSTACKSIZE;
+ vim_free(tagstack[0].tagname);
+ for (i = 1; i < tagstacklen; ++i)
+ tagstack[i - 1] = tagstack[i];
+ --tagstackidx;
+ }
+
+ /*
+ * put the tag name in the tag stack
+ */
+ if ((tagstack[tagstackidx].tagname = vim_strsave(tag)) == NULL) {
+ curwin->w_tagstacklen = tagstacklen - 1;
+ goto end_do_tag;
+ }
+ curwin->w_tagstacklen = tagstacklen;
+
+ save_pos = TRUE; /* save the cursor position below */
+ }
+
+ new_tag = TRUE;
+ } else {
+ if (
+ g_do_tagpreview != 0 ? ptag_entry.tagname == NULL :
+ tagstacklen == 0) {
+ /* empty stack */
+ EMSG(_(e_tagstack));
+ goto end_do_tag;
+ }
+
+ if (type == DT_POP) { /* go to older position */
+ int old_KeyTyped = KeyTyped;
+ if ((tagstackidx -= count) < 0) {
+ EMSG(_(bottommsg));
+ if (tagstackidx + count == 0) {
+ /* We did [num]^T from the bottom of the stack */
+ tagstackidx = 0;
+ goto end_do_tag;
+ }
+ /* We weren't at the bottom of the stack, so jump all the
+ * way to the bottom now.
+ */
+ tagstackidx = 0;
+ } else if (tagstackidx >= tagstacklen) { /* count == 0? */
+ EMSG(_(topmsg));
+ goto end_do_tag;
+ }
+
+ /* Make a copy of the fmark, autocommands may invalidate the
+ * tagstack before it's used. */
+ saved_fmark = tagstack[tagstackidx].fmark;
+ if (saved_fmark.fnum != curbuf->b_fnum) {
+ /*
+ * Jump to other file. If this fails (e.g. because the
+ * file was changed) keep original position in tag stack.
+ */
+ if (buflist_getfile(saved_fmark.fnum, saved_fmark.mark.lnum,
+ GETF_SETMARK, forceit) == FAIL) {
+ tagstackidx = oldtagstackidx; /* back to old posn */
+ goto end_do_tag;
+ }
+ /* An BufReadPost autocommand may jump to the '" mark, but
+ * we don't what that here. */
+ curwin->w_cursor.lnum = saved_fmark.mark.lnum;
+ } else {
+ setpcmark();
+ curwin->w_cursor.lnum = saved_fmark.mark.lnum;
+ }
+ curwin->w_cursor.col = saved_fmark.mark.col;
+ curwin->w_set_curswant = TRUE;
+ check_cursor();
+ if ((fdo_flags & FDO_TAG) && old_KeyTyped)
+ foldOpenCursor();
+
+ /* remove the old list of matches */
+ FreeWild(num_matches, matches);
+ cs_free_tags();
+ num_matches = 0;
+ tag_freematch();
+ goto end_do_tag;
+ }
+
+ if (type == DT_TAG
+ || type == DT_LTAG
+ ) {
+ if (g_do_tagpreview != 0) {
+ cur_match = ptag_entry.cur_match;
+ cur_fnum = ptag_entry.cur_fnum;
+ } else {
+ /* ":tag" (no argument): go to newer pattern */
+ save_pos = TRUE; /* save the cursor position below */
+ if ((tagstackidx += count - 1) >= tagstacklen) {
+ /*
+ * Beyond the last one, just give an error message and
+ * go to the last one. Don't store the cursor
+ * position.
+ */
+ tagstackidx = tagstacklen - 1;
+ EMSG(_(topmsg));
+ save_pos = FALSE;
+ } else if (tagstackidx < 0) { /* must have been count == 0 */
+ EMSG(_(bottommsg));
+ tagstackidx = 0;
+ goto end_do_tag;
+ }
+ cur_match = tagstack[tagstackidx].cur_match;
+ cur_fnum = tagstack[tagstackidx].cur_fnum;
+ }
+ new_tag = TRUE;
+ } else { /* go to other matching tag */
+ /* Save index for when selection is cancelled. */
+ prevtagstackidx = tagstackidx;
+
+ if (g_do_tagpreview != 0) {
+ cur_match = ptag_entry.cur_match;
+ cur_fnum = ptag_entry.cur_fnum;
+ } else {
+ if (--tagstackidx < 0)
+ tagstackidx = 0;
+ cur_match = tagstack[tagstackidx].cur_match;
+ cur_fnum = tagstack[tagstackidx].cur_fnum;
+ }
+ switch (type) {
+ case DT_FIRST: cur_match = count - 1; break;
+ case DT_SELECT:
+ case DT_JUMP:
+ case DT_CSCOPE:
+ case DT_LAST: cur_match = MAXCOL - 1; break;
+ case DT_NEXT: cur_match += count; break;
+ case DT_PREV: cur_match -= count; break;
+ }
+ if (cur_match >= MAXCOL)
+ cur_match = MAXCOL - 1;
+ else if (cur_match < 0) {
+ EMSG(_("E425: Cannot go before first matching tag"));
+ skip_msg = TRUE;
+ cur_match = 0;
+ cur_fnum = curbuf->b_fnum;
+ }
+ }
+ }
+
+ if (g_do_tagpreview != 0) {
+ if (type != DT_SELECT && type != DT_JUMP) {
+ ptag_entry.cur_match = cur_match;
+ ptag_entry.cur_fnum = cur_fnum;
+ }
+ } else {
+ /*
+ * For ":tag [arg]" or ":tselect" remember position before the jump.
+ */
+ saved_fmark = tagstack[tagstackidx].fmark;
+ if (save_pos) {
+ tagstack[tagstackidx].fmark.mark = curwin->w_cursor;
+ tagstack[tagstackidx].fmark.fnum = curbuf->b_fnum;
+ }
+
+ /* Curwin will change in the call to jumpto_tag() if ":stag" was
+ * used or an autocommand jumps to another window; store value of
+ * tagstackidx now. */
+ curwin->w_tagstackidx = tagstackidx;
+ if (type != DT_SELECT && type != DT_JUMP) {
+ curwin->w_tagstack[tagstackidx].cur_match = cur_match;
+ curwin->w_tagstack[tagstackidx].cur_fnum = cur_fnum;
+ }
+ }
+ }
+
+ /* When not using the current buffer get the name of buffer "cur_fnum".
+ * Makes sure that the tag order doesn't change when using a remembered
+ * position for "cur_match". */
+ if (cur_fnum != curbuf->b_fnum) {
+ buf_T *buf = buflist_findnr(cur_fnum);
+
+ if (buf != NULL)
+ buf_ffname = buf->b_ffname;
+ }
+
+ /*
+ * Repeat searching for tags, when a file has not been found.
+ */
+ for (;; ) {
+ /*
+ * When desired match not found yet, try to find it (and others).
+ */
+ if (use_tagstack)
+ name = tagstack[tagstackidx].tagname;
+ else if (g_do_tagpreview != 0)
+ name = ptag_entry.tagname;
+ else
+ name = tag;
+ other_name = (tagmatchname == NULL || STRCMP(tagmatchname, name) != 0);
+ if (new_tag
+ || (cur_match >= num_matches && max_num_matches != MAXCOL)
+ || other_name) {
+ if (other_name) {
+ vim_free(tagmatchname);
+ tagmatchname = vim_strsave(name);
+ }
+
+ /*
+ * If a count is supplied to the ":tag <name>" command, then
+ * jump to count'th matching tag.
+ */
+ if (type == DT_TAG && *tag != NUL && count > 0)
+ cur_match = count - 1;
+
+ if (type == DT_SELECT || type == DT_JUMP
+ || type == DT_LTAG
+ )
+ cur_match = MAXCOL - 1;
+ max_num_matches = cur_match + 1;
+
+ /* when the argument starts with '/', use it as a regexp */
+ if (!no_regexp && *name == '/') {
+ flags = TAG_REGEXP;
+ ++name;
+ } else
+ flags = TAG_NOIC;
+
+ if (type == DT_CSCOPE)
+ flags = TAG_CSCOPE;
+ if (verbose)
+ flags |= TAG_VERBOSE;
+ if (find_tags(name, &new_num_matches, &new_matches, flags,
+ max_num_matches, buf_ffname) == OK
+ && new_num_matches < max_num_matches)
+ max_num_matches = MAXCOL; /* If less than max_num_matches
+ found: all matches found. */
+
+ /* If there already were some matches for the same name, move them
+ * to the start. Avoids that the order changes when using
+ * ":tnext" and jumping to another file. */
+ if (!new_tag && !other_name) {
+ /* Find the position of each old match in the new list. Need
+ * to use parse_match() to find the tag line. */
+ idx = 0;
+ for (j = 0; j < num_matches; ++j) {
+ parse_match(matches[j], &tagp);
+ for (i = idx; i < new_num_matches; ++i) {
+ parse_match(new_matches[i], &tagp2);
+ if (STRCMP(tagp.tagname, tagp2.tagname) == 0) {
+ p = new_matches[i];
+ for (k = i; k > idx; --k)
+ new_matches[k] = new_matches[k - 1];
+ new_matches[idx++] = p;
+ break;
+ }
+ }
+ }
+ }
+ FreeWild(num_matches, matches);
+ num_matches = new_num_matches;
+ matches = new_matches;
+ }
+
+ if (num_matches <= 0) {
+ if (verbose)
+ EMSG2(_("E426: tag not found: %s"), name);
+ g_do_tagpreview = 0;
+ } else {
+ int ask_for_selection = FALSE;
+
+ if (type == DT_CSCOPE && num_matches > 1) {
+ cs_print_tags();
+ ask_for_selection = TRUE;
+ } else if (type == DT_SELECT ||
+ (type == DT_JUMP && num_matches > 1)) {
+ /*
+ * List all the matching tags.
+ * Assume that the first match indicates how long the tags can
+ * be, and align the file names to that.
+ */
+ parse_match(matches[0], &tagp);
+ taglen = (int)(tagp.tagname_end - tagp.tagname + 2);
+ if (taglen < 18)
+ taglen = 18;
+ if (taglen > Columns - 25)
+ taglen = MAXCOL;
+ if (msg_col == 0)
+ msg_didout = FALSE; /* overwrite previous message */
+ msg_start();
+ 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));
+
+ for (i = 0; i < num_matches && !got_int; ++i) {
+ parse_match(matches[i], &tagp);
+ if (!new_tag && (
+ (g_do_tagpreview != 0
+ && i == ptag_entry.cur_match) ||
+ (use_tagstack
+ && i == tagstack[tagstackidx].cur_match)))
+ *IObuff = '>';
+ else
+ *IObuff = ' ';
+ 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_outtrans_len(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));
+ 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);
+ if (p != NULL) {
+ msg_puts_long_attr(p, hl_attr(HLF_D));
+ vim_free(p);
+ }
+ if (msg_col > 0)
+ msg_putchar('\n');
+ if (got_int)
+ break;
+ msg_advance(15);
+
+ /* print any extra fields */
+ command_end = tagp.command_end;
+ if (command_end != NULL) {
+ p = command_end + 3;
+ while (*p && *p != '\r' && *p != '\n') {
+ while (*p == TAB)
+ ++p;
+
+ /* skip "file:" without a value (static tag) */
+ if (STRNCMP(p, "file:", 5) == 0
+ && vim_isspace(p[5])) {
+ p += 5;
+ continue;
+ }
+ /* skip "kind:<kind>" and "<kind>" */
+ if (p == tagp.tagkind
+ || (p + 5 == tagp.tagkind
+ && STRNCMP(p, "kind:", 5) == 0)) {
+ p = tagp.tagkind_end;
+ continue;
+ }
+ /* 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');
+ if (got_int)
+ break;
+ msg_advance(15);
+ }
+ p = msg_outtrans_one(p, attr);
+ if (*p == TAB) {
+ msg_puts_attr((char_u *)" ", attr);
+ break;
+ }
+ if (*p == ':')
+ attr = 0;
+ }
+ }
+ if (msg_col > 15) {
+ msg_putchar('\n');
+ if (got_int)
+ break;
+ msg_advance(15);
+ }
+ } else {
+ for (p = tagp.command;
+ *p && *p != '\r' && *p != '\n'; ++p)
+ ;
+ command_end = p;
+ }
+
+ /*
+ * Put the info (in several lines) at column 15.
+ * Don't display "/^" and "?^".
+ */
+ p = tagp.command;
+ if (*p == '/' || *p == '?') {
+ ++p;
+ if (*p == '^')
+ ++p;
+ }
+ /* Remove leading whitespace from pattern */
+ while (p != command_end && vim_isspace(*p))
+ ++p;
+
+ while (p != command_end) {
+ if (msg_col + (*p == TAB ? 1 : ptr2cells(p)) > Columns)
+ msg_putchar('\n');
+ if (got_int)
+ break;
+ msg_advance(15);
+
+ /* skip backslash used for escaping command char */
+ if (*p == '\\' && *(p + 1) == *tagp.command)
+ ++p;
+
+ if (*p == TAB) {
+ msg_putchar(' ');
+ ++p;
+ } else
+ p = msg_outtrans_one(p, 0);
+
+ /* don't display the "$/;\"" and "$?;\"" */
+ if (p == command_end - 2 && *p == '$'
+ && *(p + 1) == *tagp.command)
+ break;
+ /* don't display matching '/' or '?' */
+ if (p == command_end - 1 && *p == *tagp.command
+ && (*p == '/' || *p == '?'))
+ break;
+ }
+ if (msg_col)
+ msg_putchar('\n');
+ ui_breakcheck();
+ }
+ if (got_int)
+ got_int = FALSE; /* only stop the listing */
+ ask_for_selection = TRUE;
+ } else if (type == DT_LTAG) {
+ list_T *list;
+ char_u tag_name[128 + 1];
+ char_u *fname;
+ char_u *cmd;
+
+ /*
+ * Add the matching tags to the location list for the current
+ * window.
+ */
+
+ fname = alloc(MAXPATHL + 1);
+ cmd = alloc(CMDBUFFSIZE + 1);
+ list = list_alloc();
+ if (list == NULL || fname == NULL || cmd == NULL) {
+ vim_free(cmd);
+ vim_free(fname);
+ if (list != NULL)
+ list_free(list, TRUE);
+ goto end_do_tag;
+ }
+
+ for (i = 0; i < num_matches; ++i) {
+ int len, cmd_len;
+ long lnum;
+ dict_T *dict;
+
+ parse_match(matches[i], &tagp);
+
+ /* Save the tag name */
+ len = (int)(tagp.tagname_end - tagp.tagname);
+ if (len > 128)
+ len = 128;
+ vim_strncpy(tag_name, tagp.tagname, len);
+ tag_name[len] = NUL;
+
+ /* Save the tag file name */
+ p = tag_full_fname(&tagp);
+ if (p == NULL)
+ continue;
+ vim_strncpy(fname, p, MAXPATHL);
+ vim_free(p);
+
+ /*
+ * Get the line number or the search pattern used to locate
+ * the tag.
+ */
+ lnum = 0;
+ if (isdigit(*tagp.command))
+ /* Line number is used to locate the tag */
+ lnum = atol((char *)tagp.command);
+ else {
+ char_u *cmd_start, *cmd_end;
+
+ /* Search pattern is used to locate the tag */
+
+ /* Locate the end of the command */
+ cmd_start = tagp.command;
+ cmd_end = tagp.command_end;
+ if (cmd_end == NULL) {
+ for (p = tagp.command;
+ *p && *p != '\r' && *p != '\n'; ++p)
+ ;
+ cmd_end = p;
+ }
+
+ /*
+ * Now, cmd_end points to the character after the
+ * command. Adjust it to point to the last
+ * character of the command.
+ */
+ cmd_end--;
+
+ /*
+ * Skip the '/' and '?' characters at the
+ * beginning and end of the search pattern.
+ */
+ if (*cmd_start == '/' || *cmd_start == '?')
+ cmd_start++;
+
+ if (*cmd_end == '/' || *cmd_end == '?')
+ cmd_end--;
+
+ len = 0;
+ cmd[0] = NUL;
+
+ /*
+ * If "^" is present in the tag search pattern, then
+ * copy it first.
+ */
+ if (*cmd_start == '^') {
+ STRCPY(cmd, "^");
+ cmd_start++;
+ len++;
+ }
+
+ /*
+ * Precede the tag pattern with \V to make it very
+ * nomagic.
+ */
+ STRCAT(cmd, "\\V");
+ len += 2;
+
+ cmd_len = (int)(cmd_end - cmd_start + 1);
+ if (cmd_len > (CMDBUFFSIZE - 5))
+ cmd_len = CMDBUFFSIZE - 5;
+ STRNCAT(cmd, cmd_start, cmd_len);
+ len += cmd_len;
+
+ if (cmd[len - 1] == '$') {
+ /*
+ * Replace '$' at the end of the search pattern
+ * with '\$'
+ */
+ cmd[len - 1] = '\\';
+ cmd[len] = '$';
+ len++;
+ }
+
+ cmd[len] = NUL;
+ }
+
+ if ((dict = dict_alloc()) == NULL)
+ continue;
+ if (list_append_dict(list, dict) == FAIL) {
+ vim_free(dict);
+ continue;
+ }
+
+ 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);
+ }
+
+ vim_snprintf((char *)IObuff, IOSIZE, "ltag %s", tag);
+ set_errorlist(curwin, list, ' ', IObuff);
+
+ list_free(list, TRUE);
+ vim_free(fname);
+ vim_free(cmd);
+
+ cur_match = 0; /* Jump to the first tag */
+ }
+
+ if (ask_for_selection == TRUE) {
+ /*
+ * Ask to select a tag from the list.
+ */
+ i = prompt_for_number(NULL);
+ if (i <= 0 || i > num_matches || got_int) {
+ /* no valid choice: don't change anything */
+ if (use_tagstack) {
+ tagstack[tagstackidx].fmark = saved_fmark;
+ tagstackidx = prevtagstackidx;
+ }
+ cs_free_tags();
+ jumped_to_tag = TRUE;
+ break;
+ }
+ cur_match = i - 1;
+ }
+
+ if (cur_match >= num_matches) {
+ /* Avoid giving this error when a file wasn't found and we're
+ * looking for a match in another file, which wasn't found.
+ * There will be an EMSG("file doesn't exist") below then. */
+ if ((type == DT_NEXT || type == DT_FIRST)
+ && nofile_fname == NULL) {
+ if (num_matches == 1)
+ EMSG(_("E427: There is only one matching tag"));
+ else
+ EMSG(_("E428: Cannot go beyond last matching tag"));
+ skip_msg = TRUE;
+ }
+ cur_match = num_matches - 1;
+ }
+ if (use_tagstack) {
+ tagstack[tagstackidx].cur_match = cur_match;
+ tagstack[tagstackidx].cur_fnum = cur_fnum;
+ ++tagstackidx;
+ } else if (g_do_tagpreview != 0) {
+ ptag_entry.cur_match = cur_match;
+ ptag_entry.cur_fnum = cur_fnum;
+ }
+
+ /*
+ * Only when going to try the next match, report that the previous
+ * file didn't exist. Otherwise an EMSG() is given below.
+ */
+ if (nofile_fname != NULL && error_cur_match != cur_match)
+ smsg((char_u *)_("File \"%s\" does not exist"), nofile_fname);
+
+
+ ic = (matches[cur_match][0] & MT_IC_OFF);
+ if (type != DT_SELECT && type != DT_JUMP
+ && type != DT_CSCOPE
+ && (num_matches > 1 || ic)
+ && !skip_msg) {
+ /* Give an indication of the number of matching tags */
+ sprintf((char *)IObuff, _("tag %d of %d%s"),
+ cur_match + 1,
+ num_matches,
+ max_num_matches != MAXCOL ? _(" or more") : "");
+ if (ic)
+ 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
+ msg(IObuff);
+ msg_scroll = TRUE; /* don't overwrite this message */
+ } else
+ give_warning(IObuff, ic);
+ if (ic && !msg_scrolled && msg_silent == 0) {
+ out_flush();
+ ui_delay(1000L, TRUE);
+ }
+ }
+
+ /* Let the SwapExists event know what tag we are jumping to. */
+ vim_snprintf((char *)IObuff, IOSIZE, ":ta %s\r", name);
+ set_vim_var_string(VV_SWAPCOMMAND, IObuff, -1);
+
+ /*
+ * Jump to the desired match.
+ */
+ i = jumpto_tag(matches[cur_match], forceit, type != DT_CSCOPE);
+
+ set_vim_var_string(VV_SWAPCOMMAND, NULL, -1);
+
+ if (i == NOTAGFILE) {
+ /* File not found: try again with another matching tag */
+ if ((type == DT_PREV && cur_match > 0)
+ || ((type == DT_TAG || type == DT_NEXT
+ || type == DT_FIRST)
+ && (max_num_matches != MAXCOL
+ || cur_match < num_matches - 1))) {
+ error_cur_match = cur_match;
+ if (use_tagstack)
+ --tagstackidx;
+ if (type == DT_PREV)
+ --cur_match;
+ else {
+ type = DT_NEXT;
+ ++cur_match;
+ }
+ continue;
+ }
+ EMSG2(_("E429: File \"%s\" does not exist"), nofile_fname);
+ } else {
+ /* We may have jumped to another window, check that
+ * tagstackidx is still valid. */
+ if (use_tagstack && tagstackidx > curwin->w_tagstacklen)
+ tagstackidx = curwin->w_tagstackidx;
+ jumped_to_tag = TRUE;
+ }
+ }
+ break;
+ }
+
+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 */
+
+ return jumped_to_tag;
+}
+
+/*
+ * Free cached tags.
+ */
+void tag_freematch() {
+ vim_free(tagmatchname);
+ tagmatchname = NULL;
+}
+
+static void taglen_advance(l)
+int l;
+{
+ if (l == MAXCOL) {
+ msg_putchar('\n');
+ msg_advance(24);
+ } else
+ msg_advance(13 + l);
+}
+
+/*
+ * Print the tag stack
+ */
+void do_tags(eap)
+exarg_T *eap UNUSED;
+{
+ int i;
+ char_u *name;
+ taggy_T *tagstack = curwin->w_tagstack;
+ int tagstackidx = curwin->w_tagstackidx;
+ int tagstacklen = curwin->w_tagstacklen;
+
+ /* Highlight title */
+ MSG_PUTS_TITLE(_("\n # TO tag FROM line in file/text"));
+ for (i = 0; i < tagstacklen; ++i) {
+ if (tagstack[i].tagname != NULL) {
+ name = fm_getname(&(tagstack[i].fmark), 30);
+ if (name == NULL) /* file name not available */
+ 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);
+ msg_outtrans(IObuff);
+ msg_outtrans_attr(name, tagstack[i].fmark.fnum == curbuf->b_fnum
+ ? hl_attr(HLF_D) : 0);
+ vim_free(name);
+ }
+ out_flush(); /* show one line at a time */
+ }
+ if (tagstackidx == tagstacklen) /* idx at top of stack */
+ MSG_PUTS("\n>");
+}
+
+/* When not using a CR for line separator, use vim_fgets() to read tag lines.
+ * For the Mac use tag_fgets(). It can handle any line separator, but is much
+ * slower than vim_fgets().
+ */
+#ifndef USE_CR
+# define tag_fgets vim_fgets
+#endif
+
+static int tag_strnicmp __ARGS((char_u *s1, char_u *s2, size_t len));
+
+/*
+ * Compare two strings, for length "len", ignoring case the ASCII way.
+ * return 0 for match, < 0 for smaller, > 0 for bigger
+ * Make sure case is folded to uppercase in comparison (like for 'sort -f')
+ */
+static int tag_strnicmp(s1, s2, len)
+char_u *s1;
+char_u *s2;
+size_t len;
+{
+ int i;
+
+ while (len > 0) {
+ i = (int)TOUPPER_ASC(*s1) - (int)TOUPPER_ASC(*s2);
+ if (i != 0)
+ return i; /* this character different */
+ if (*s1 == NUL)
+ break; /* strings match until NUL */
+ ++s1;
+ ++s2;
+ --len;
+ }
+ return 0; /* strings match */
+}
+
+/*
+ * Structure to hold info about the tag pattern being used.
+ */
+typedef struct {
+ char_u *pat; /* the pattern */
+ int len; /* length of pat[] */
+ char_u *head; /* start of pattern head */
+ int headlen; /* length of head[] */
+ regmatch_T regmatch; /* regexp program, may be NULL */
+} pat_T;
+
+static void prepare_pats __ARGS((pat_T *pats, int has_re));
+
+/*
+ * Extract info from the tag search pattern "pats->pat".
+ */
+static void prepare_pats(pats, has_re)
+pat_T *pats;
+int has_re;
+{
+ pats->head = pats->pat;
+ pats->headlen = pats->len;
+ if (has_re) {
+ /* When the pattern starts with '^' or "\\<", binary searching can be
+ * used (much faster). */
+ if (pats->pat[0] == '^')
+ pats->head = pats->pat + 1;
+ else if (pats->pat[0] == '\\' && pats->pat[1] == '<')
+ pats->head = pats->pat + 2;
+ if (pats->head == pats->pat)
+ pats->headlen = 0;
+ else
+ for (pats->headlen = 0; pats->head[pats->headlen] != NUL;
+ ++pats->headlen)
+ if (vim_strchr((char_u *)(p_magic ? ".[~*\\$" : "\\$"),
+ pats->head[pats->headlen]) != NULL)
+ break;
+ if (p_tl != 0 && pats->headlen > p_tl) /* adjust for 'taglength' */
+ pats->headlen = p_tl;
+ }
+
+ if (has_re)
+ pats->regmatch.regprog = vim_regcomp(pats->pat, p_magic ? RE_MAGIC : 0);
+ else
+ pats->regmatch.regprog = NULL;
+}
+
+/*
+ * find_tags() - search for tags in tags files
+ *
+ * Return FAIL if search completely failed (*num_matches will be 0, *matchesp
+ * will be NULL), OK otherwise.
+ *
+ * There is a priority in which type of tag is recognized.
+ *
+ * 6. A static or global tag with a full matching tag for the current file.
+ * 5. A global tag with a full matching tag for another file.
+ * 4. A static tag with a full matching tag for another file.
+ * 3. A static or global tag with an ignore-case matching tag for the
+ * current file.
+ * 2. A global tag with an ignore-case matching tag for another file.
+ * 1. A static tag with an ignore-case matching tag for another file.
+ *
+ * Tags in an emacs-style tags file are always global.
+ *
+ * flags:
+ * TAG_HELP only search for help tags
+ * TAG_NAMES only return name of tag
+ * TAG_REGEXP use "pat" as a regexp
+ * TAG_NOIC don't always ignore case
+ * TAG_KEEP_LANG keep language
+ */
+int find_tags(pat, num_matches, matchesp, flags, mincount, buf_ffname)
+char_u *pat; /* pattern to search for */
+int *num_matches; /* return: number of matches found */
+char_u ***matchesp; /* return: array of matches found */
+int flags;
+int mincount; /* MAXCOL: find all matches
+ other: minimal number of matches */
+char_u *buf_ffname; /* name of buffer for priority */
+{
+ FILE *fp;
+ char_u *lbuf; /* line buffer */
+ int lbuf_size = LSIZE; /* length of lbuf */
+ char_u *tag_fname; /* name of tag file */
+ tagname_T tn; /* info for get_tagfname() */
+ int first_file; /* trying first tag file */
+ tagptrs_T tagp;
+ int did_open = FALSE; /* did open a tag file */
+ int stop_searching = FALSE; /* stop when match found or error */
+ int retval = FAIL; /* return value */
+ int is_static; /* current tag line is static */
+ int is_current; /* file name matches */
+ int eof = FALSE; /* found end-of-file */
+ 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 */
+ } search_info;
+ off_t filesize;
+ int tagcmp;
+ off_t offset;
+ int round;
+ enum {
+ TS_START, /* at start of file */
+ TS_LINEAR /* linear searching forward, till EOF */
+ , TS_BINARY, /* binary searching */
+ TS_SKIP_BACK, /* skipping backwards */
+ TS_STEP_FORWARD /* stepping forwards */
+ } state; /* Current search state */
+
+ int cmplen;
+ int match; /* matches */
+ int match_no_ic = 0; /* matches with rm_ic == FALSE */
+ int match_re; /* match with regexp */
+ int matchoff = 0;
+ int save_emsg_off;
+
+
+ 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 **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[] */
+
+ pat_T orgpat; /* holds unconverted pattern info */
+ vimconv_T vimconv;
+
+ int findall = (mincount == MAXCOL || mincount == TAG_MANY);
+ /* find all matching tags */
+ int sort_error = FALSE; /* tags file not sorted */
+ int linear; /* do a linear search */
+ int sortic = FALSE; /* tag file sorted in nocase */
+ int line_error = FALSE; /* syntax error */
+ int has_re = (flags & TAG_REGEXP); /* regexp used */
+ int help_only = (flags & TAG_HELP);
+ int name_only = (flags & TAG_NAMES);
+ int noic = (flags & TAG_NOIC);
+ int get_it_again = FALSE;
+ int use_cscope = (flags & TAG_CSCOPE);
+ int verbose = (flags & TAG_VERBOSE);
+
+ help_save = curbuf->b_help;
+ orgpat.pat = pat;
+ vimconv.vc_type = CONV_NONE;
+
+ /*
+ * Allocate memory for the buffers that are used
+ */
+ lbuf = alloc(lbuf_size);
+ tag_fname = alloc(MAXPATHL + 1);
+ for (mtt = 0; mtt < MT_COUNT; ++mtt)
+ ga_init2(&ga_match[mtt], (int)sizeof(struct match_found *), 100);
+
+ /* check for out of memory situation */
+ if (lbuf == NULL || tag_fname == NULL
+ )
+ goto findtag_end;
+
+ 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 */
+
+ orgpat.len = (int)STRLEN(pat);
+ if (curbuf->b_help) {
+ /* When "@ab" is specified use only the "ab" language, otherwise
+ * search all languages. */
+ if (orgpat.len > 3 && pat[orgpat.len - 3] == '@'
+ && ASCII_ISALPHA(pat[orgpat.len - 2])
+ && ASCII_ISALPHA(pat[orgpat.len - 1])) {
+ saved_pat = vim_strnsave(pat, orgpat.len - 3);
+ if (saved_pat != NULL) {
+ help_lang_find = &pat[orgpat.len - 2];
+ orgpat.pat = saved_pat;
+ orgpat.len -= 3;
+ }
+ }
+ }
+ if (p_tl != 0 && orgpat.len > p_tl) /* adjust for 'taglength' */
+ orgpat.len = p_tl;
+
+ save_emsg_off = emsg_off;
+ emsg_off = TRUE; /* don't want error for invalid RE here */
+ prepare_pats(&orgpat, has_re);
+ emsg_off = save_emsg_off;
+ if (has_re && orgpat.regmatch.regprog == NULL)
+ goto findtag_end;
+
+ /* This is only to avoid a compiler warning for using search_info
+ * uninitialised. */
+ vim_memset(&search_info, 0, (size_t)1);
+
+ /*
+ * When finding a specified number of matches, first try with matching
+ * case, so binary search can be used, and try ignore-case matches in a
+ * second loop.
+ * When finding all matches, 'tagbsearch' is off, or there is no fixed
+ * string to look for, ignore case right away to avoid going though the
+ * tags files twice.
+ * When the tag file is case-fold sorted, it is either one or the other.
+ * Only ignore case when TAG_NOIC not used or 'ignorecase' set.
+ */
+ orgpat.regmatch.rm_ic = ((p_ic || !noic)
+ && (findall || orgpat.headlen == 0 || !p_tbs));
+ for (round = 1; round <= 2; ++round) {
+ linear = (orgpat.headlen == 0 || !p_tbs || round == 2);
+
+ /*
+ * Try tag file names from tags option one by one.
+ */
+ for (first_file = TRUE;
+ use_cscope ||
+ get_tagfname(&tn, first_file, tag_fname) == OK;
+ first_file = FALSE) {
+ /*
+ * A file that doesn't exist is silently ignored. Only when not a
+ * single file is found, an error message is given (further on).
+ */
+ if (use_cscope)
+ 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
+ STRCPY(help_lang, "en");
+
+ /* When searching for a specific language skip tags files
+ * for other languages. */
+ if (help_lang_find != NULL
+ && STRICMP(help_lang, help_lang_find) != 0)
+ continue;
+
+ /* For CTRL-] in a help file prefer a match with the same
+ * language. */
+ if ((flags & TAG_KEEP_LANG)
+ && help_lang_find == NULL
+ && curbuf->b_fname != NULL
+ && (i = (int)STRLEN(curbuf->b_fname)) > 4
+ && curbuf->b_fname[i - 1] == 'x'
+ && curbuf->b_fname[i - 4] == '.'
+ && STRNICMP(curbuf->b_fname + i - 3, help_lang, 2) == 0)
+ help_pri = 0;
+ else {
+ help_pri = 1;
+ for (s = p_hlg; *s != NUL; ++s) {
+ if (STRNICMP(s, help_lang, 2) == 0)
+ break;
+ ++help_pri;
+ if ((s = vim_strchr(s, ',')) == NULL)
+ break;
+ }
+ if (s == NULL || *s == NUL) {
+ /* Language not in 'helplang': use last, prefer English,
+ * unless found already. */
+ ++help_pri;
+ if (STRICMP(help_lang, "en") != 0)
+ ++help_pri;
+ }
+ }
+ }
+
+ if ((fp = mch_fopen((char *)tag_fname, "r")) == NULL)
+ continue;
+
+ if (p_verbose >= 5) {
+ verbose_enter();
+ smsg((char_u *)_("Searching tags file %s"), tag_fname);
+ verbose_leave();
+ }
+ }
+ did_open = TRUE; /* remember that we found at least one file */
+
+ state = TS_START; /* we're at the start of the file */
+
+ /*
+ * Read and parse the lines in the file one by one
+ */
+ for (;; ) {
+ line_breakcheck(); /* check for CTRL-C typed */
+ if ((flags & TAG_INS_COMP)) /* Double brackets for gcc */
+ ins_compl_check_keys(30);
+ if (got_int || compl_interrupted) {
+ stop_searching = TRUE;
+ break;
+ }
+ /* When mincount is TAG_MANY, stop when enough matches have been
+ * found (for completion). */
+ if (mincount == TAG_MANY && match_count >= TAG_MANY) {
+ stop_searching = TRUE;
+ retval = OK;
+ break;
+ }
+ if (get_it_again)
+ goto line_read_in;
+ /*
+ * For binary search: compute the next offset to use.
+ */
+ if (state == TS_BINARY) {
+ offset = search_info.low_offset + ((search_info.high_offset
+ - search_info.low_offset) / 2);
+ if (offset == search_info.curr_offset)
+ break; /* End the binary search without a match. */
+ else
+ search_info.curr_offset = offset;
+ }
+ /*
+ * Skipping back (after a match during binary search).
+ */
+ else if (state == TS_SKIP_BACK) {
+ search_info.curr_offset -= LSIZE * 2;
+ if (search_info.curr_offset < 0) {
+ search_info.curr_offset = 0;
+ rewind(fp);
+ state = TS_STEP_FORWARD;
+ }
+ }
+
+ /*
+ * When jumping around in the file, first read a line to find the
+ * start of the next line.
+ */
+ if (state == TS_BINARY || state == TS_SKIP_BACK) {
+ /* Adjust the search file offset to the correct position */
+ search_info.curr_offset_used = search_info.curr_offset;
+#ifdef HAVE_FSEEKO
+ fseeko(fp, search_info.curr_offset, SEEK_SET);
+#else
+ fseek(fp, (long)search_info.curr_offset, SEEK_SET);
+#endif
+ eof = tag_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);
+ 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
+ search_info.curr_offset = search_info.low_offset;
+ }
+ eof = tag_fgets(lbuf, LSIZE, fp);
+ }
+ /* skip empty and blank lines */
+ while (!eof && vim_isblankline(lbuf)) {
+ search_info.curr_offset = ftell(fp);
+ eof = tag_fgets(lbuf, LSIZE, fp);
+ }
+ if (eof) {
+ /* Hit end of file. Skip backwards. */
+ state = TS_SKIP_BACK;
+ search_info.match_offset = ftell(fp);
+ search_info.curr_offset = search_info.curr_offset_used;
+ continue;
+ }
+ }
+ /*
+ * Not jumping around in the file: Read the next line.
+ */
+ else {
+ /* skip empty and blank lines */
+ do {
+ if (use_cscope)
+ eof = cs_fgets(lbuf, LSIZE);
+ else
+ eof = tag_fgets(lbuf, LSIZE, fp);
+ } while (!eof && vim_isblankline(lbuf));
+
+ if (eof) {
+ break; /* end of file */
+ }
+ }
+line_read_in:
+
+ if (vimconv.vc_type != CONV_NONE) {
+ char_u *conv_line;
+ int len;
+
+ /* Convert every line. Converting the pattern from 'enc' to
+ * the tags file encoding doesn't work, because characters are
+ * not recognized. */
+ conv_line = string_convert(&vimconv, lbuf, NULL);
+ if (conv_line != NULL) {
+ /* Copy or swap lbuf and conv_line. */
+ len = (int)STRLEN(conv_line) + 1;
+ if (len > lbuf_size) {
+ vim_free(lbuf);
+ lbuf = conv_line;
+ lbuf_size = len;
+ } else {
+ STRCPY(lbuf, conv_line);
+ vim_free(conv_line);
+ }
+ }
+ }
+
+
+
+ /*
+ * When still at the start of the file, check for Emacs tags file
+ * format, and for "not sorted" flag.
+ */
+ if (state == TS_START) {
+ /* The header ends when the line sorts below "!_TAG_". When
+ * case is folded lower case letters sort before "_". */
+ if (STRNCMP(lbuf, "!_TAG_", 6) <= 0
+ || (lbuf[0] == '!' && ASCII_ISLOWER(lbuf[1]))) {
+ if (STRNCMP(lbuf, "!_TAG_", 6) != 0)
+ /* Non-header item before the header, e.g. "!" itself.
+ */
+ goto parse_line;
+
+ /*
+ * Read header line.
+ */
+ if (STRNCMP(lbuf, "!_TAG_FILE_SORTED\t", 18) == 0)
+ tag_file_sorted = lbuf[18];
+ if (STRNCMP(lbuf, "!_TAG_FILE_ENCODING\t", 20) == 0) {
+ /* Prepare to convert every line from the specified
+ * encoding to 'encoding'. */
+ for (p = lbuf + 20; *p > ' ' && *p < 127; ++p)
+ ;
+ *p = NUL;
+ convert_setup(&vimconv, lbuf + 20, p_enc);
+ }
+
+ /* Read the next line. Unrecognized flags are ignored. */
+ continue;
+ }
+
+ /* Headers ends. */
+
+ /*
+ * When there is no tag head, or ignoring case, need to do a
+ * linear search.
+ * When no "!_TAG_" is found, default to binary search. If
+ * the tag file isn't sorted, the second loop will find it.
+ * When "!_TAG_FILE_SORTED" found: start binary search if
+ * flag set.
+ * For cscope, it's always linear.
+ */
+ if (linear || use_cscope)
+ state = TS_LINEAR;
+ else if (tag_file_sorted == NUL)
+ state = TS_BINARY;
+ else if (tag_file_sorted == '1')
+ state = TS_BINARY;
+ else if (tag_file_sorted == '2') {
+ state = TS_BINARY;
+ sortic = TRUE;
+ orgpat.regmatch.rm_ic = (p_ic || !noic);
+ } else
+ state = TS_LINEAR;
+
+ if (state == TS_BINARY && orgpat.regmatch.rm_ic && !sortic) {
+ /* Binary search won't work for ignoring case, use linear
+ * search. */
+ linear = TRUE;
+ state = TS_LINEAR;
+ }
+
+ /*
+ * When starting a binary search, get the size of the file and
+ * compute the first offset.
+ */
+ if (state == TS_BINARY) {
+ /* Get the tag file size (don't use mch_fstat(), it's not
+ * portable). */
+ if ((filesize = lseek(fileno(fp),
+ (off_t)0L, SEEK_END)) <= 0)
+ state = TS_LINEAR;
+ else {
+ 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. */
+ search_info.low_offset = 0;
+ search_info.low_char = 0;
+ search_info.high_offset = filesize;
+ search_info.curr_offset = 0;
+ search_info.high_char = 0xff;
+ }
+ continue;
+ }
+ }
+
+parse_line:
+ /*
+ * Figure out where the different strings are in this line.
+ * For "normal" tags: Do a quick check if the tag matches.
+ * This speeds up tag searching a lot!
+ */
+ if (orgpat.headlen
+ ) {
+ tagp.tagname = lbuf;
+#ifdef FEAT_TAG_ANYWHITE
+ tagp.tagname_end = skiptowhite(lbuf);
+ if (*tagp.tagname_end == NUL)
+#else
+ tagp.tagname_end = vim_strchr(lbuf, TAB);
+ if (tagp.tagname_end == NULL)
+#endif
+ {
+ if (vim_strchr(lbuf, NL) == NULL) {
+ /* Truncated line, ignore it. Has been reported for
+ * Mozilla JS with extremely long names. */
+ if (p_verbose >= 5) {
+ verbose_enter();
+ MSG(_("Ignoring long line in tags file"));
+ verbose_leave();
+ }
+ if (state != TS_LINEAR) {
+ /* 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
+ }
+ continue;
+ }
+
+ /* Corrupted tag line. */
+ line_error = TRUE;
+ break;
+ }
+
+ /*
+ * Check for old style static tag: "file:tag file .."
+ */
+ tagp.fname = NULL;
+ for (p = lbuf; p < tagp.tagname_end; ++p) {
+ if (*p == ':') {
+ if (tagp.fname == NULL)
+#ifdef FEAT_TAG_ANYWHITE
+ tagp.fname = skipwhite(tagp.tagname_end);
+#else
+ tagp.fname = tagp.tagname_end + 1;
+#endif
+ if ( fnamencmp(lbuf, tagp.fname, p - lbuf) == 0
+#ifdef FEAT_TAG_ANYWHITE
+ && vim_iswhite(tagp.fname[p - lbuf])
+#else
+ && tagp.fname[p - lbuf] == TAB
+#endif
+ ) {
+ /* found one */
+ tagp.tagname = p + 1;
+ break;
+ }
+ }
+ }
+
+ /*
+ * Skip this line if the length of the tag is different and
+ * there is no regexp, or the tag is too short.
+ */
+ cmplen = (int)(tagp.tagname_end - tagp.tagname);
+ if (p_tl != 0 && cmplen > p_tl) /* adjust for 'taglength' */
+ cmplen = p_tl;
+ if (has_re && orgpat.headlen < cmplen)
+ cmplen = orgpat.headlen;
+ else if (state == TS_LINEAR && orgpat.headlen != cmplen)
+ continue;
+
+ if (state == TS_BINARY) {
+ /*
+ * Simplistic check for unsorted tags file.
+ */
+ i = (int)tagp.tagname[0];
+ if (sortic)
+ i = (int)TOUPPER_ASC(tagp.tagname[0]);
+ if (i < search_info.low_char || i > search_info.high_char)
+ sort_error = TRUE;
+
+ /*
+ * Compare the current tag with the searched tag.
+ */
+ if (sortic)
+ tagcmp = tag_strnicmp(tagp.tagname, orgpat.head,
+ (size_t)cmplen);
+ else
+ tagcmp = STRNCMP(tagp.tagname, orgpat.head, cmplen);
+
+ /*
+ * A match with a shorter tag means to search forward.
+ * A match with a longer tag means to search backward.
+ */
+ if (tagcmp == 0) {
+ if (cmplen < orgpat.headlen)
+ tagcmp = -1;
+ else if (cmplen > orgpat.headlen)
+ tagcmp = 1;
+ }
+
+ if (tagcmp == 0) {
+ /* We've located the tag, now skip back and search
+ * forward until the first matching tag is found.
+ */
+ state = TS_SKIP_BACK;
+ search_info.match_offset = search_info.curr_offset;
+ continue;
+ }
+ if (tagcmp < 0) {
+ search_info.curr_offset = ftell(fp);
+ if (search_info.curr_offset < search_info.high_offset) {
+ search_info.low_offset = search_info.curr_offset;
+ if (sortic)
+ search_info.low_char =
+ TOUPPER_ASC(tagp.tagname[0]);
+ else
+ search_info.low_char = tagp.tagname[0];
+ continue;
+ }
+ }
+ if (tagcmp > 0
+ && search_info.curr_offset != search_info.high_offset) {
+ search_info.high_offset = search_info.curr_offset;
+ if (sortic)
+ search_info.high_char =
+ TOUPPER_ASC(tagp.tagname[0]);
+ else
+ search_info.high_char = tagp.tagname[0];
+ continue;
+ }
+
+ /* No match yet and are at the end of the binary search. */
+ break;
+ } else if (state == TS_SKIP_BACK) {
+ if (MB_STRNICMP(tagp.tagname, orgpat.head, cmplen) != 0)
+ state = TS_STEP_FORWARD;
+ else
+ /* Have to skip back more. Restore the curr_offset
+ * used, otherwise we get stuck at a long line. */
+ search_info.curr_offset = search_info.curr_offset_used;
+ continue;
+ } else if (state == TS_STEP_FORWARD) {
+ if (MB_STRNICMP(tagp.tagname, orgpat.head, cmplen) != 0) {
+ if ((off_t)ftell(fp) > search_info.match_offset)
+ break; /* past last match */
+ else
+ continue; /* before first match */
+ }
+ } else
+ /* skip this match if it can't match */
+ if (MB_STRNICMP(tagp.tagname, orgpat.head, cmplen) != 0)
+ continue;
+
+ /*
+ * Can be a matching tag, isolate the file name and command.
+ */
+ if (tagp.fname == NULL)
+#ifdef FEAT_TAG_ANYWHITE
+ tagp.fname = skipwhite(tagp.tagname_end);
+#else
+ tagp.fname = tagp.tagname_end + 1;
+#endif
+#ifdef FEAT_TAG_ANYWHITE
+ tagp.fname_end = skiptowhite(tagp.fname);
+ tagp.command = skipwhite(tagp.fname_end);
+ if (*tagp.command == NUL)
+#else
+ tagp.fname_end = vim_strchr(tagp.fname, TAB);
+ tagp.command = tagp.fname_end + 1;
+ if (tagp.fname_end == NULL)
+#endif
+ i = FAIL;
+ else
+ i = OK;
+ } else
+ i = parse_tag_line(lbuf,
+ &tagp);
+ if (i == FAIL) {
+ line_error = TRUE;
+ break;
+ }
+
+ /*
+ * First try matching with the pattern literally (also when it is
+ * a regexp).
+ */
+ cmplen = (int)(tagp.tagname_end - tagp.tagname);
+ if (p_tl != 0 && cmplen > p_tl) /* adjust for 'taglength' */
+ cmplen = p_tl;
+ /* if tag length does not match, don't try comparing */
+ if (orgpat.len != cmplen)
+ match = FALSE;
+ else {
+ if (orgpat.regmatch.rm_ic) {
+ match = (MB_STRNICMP(tagp.tagname, orgpat.pat, cmplen) == 0);
+ if (match)
+ match_no_ic = (STRNCMP(tagp.tagname, orgpat.pat,
+ cmplen) == 0);
+ } else
+ match = (STRNCMP(tagp.tagname, orgpat.pat, cmplen) == 0);
+ }
+
+ /*
+ * Has a regexp: Also find tags matching regexp.
+ */
+ match_re = FALSE;
+ if (!match && orgpat.regmatch.regprog != NULL) {
+ int cc;
+
+ cc = *tagp.tagname_end;
+ *tagp.tagname_end = NUL;
+ match = vim_regexec(&orgpat.regmatch, tagp.tagname, (colnr_T)0);
+ if (match) {
+ matchoff = (int)(orgpat.regmatch.startp[0] - tagp.tagname);
+ if (orgpat.regmatch.rm_ic) {
+ orgpat.regmatch.rm_ic = FALSE;
+ match_no_ic = vim_regexec(&orgpat.regmatch, tagp.tagname,
+ (colnr_T)0);
+ orgpat.regmatch.rm_ic = TRUE;
+ }
+ }
+ *tagp.tagname_end = cc;
+ match_re = TRUE;
+ }
+
+ /*
+ * If a match is found, add it to ga_match[].
+ */
+ if (match) {
+ if (use_cscope) {
+ /* Don't change the ordering, always use the same table. */
+ mtt = MT_GL_OTH;
+ } else {
+ /* Decide in which array to store this match. */
+ is_current = test_for_current(
+ tagp.fname, tagp.fname_end, tag_fname,
+ buf_ffname);
+ {
+ if (tagp.tagname != lbuf)
+ is_static = TRUE; /* detected static tag before */
+ else
+ is_static = test_for_static(&tagp);
+ }
+
+ /* decide in which of the sixteen tables to store this
+ * match */
+ if (is_static) {
+ if (is_current)
+ mtt = MT_ST_CUR;
+ else
+ mtt = MT_ST_OTH;
+ } else {
+ if (is_current)
+ mtt = MT_GL_CUR;
+ else
+ mtt = MT_GL_OTH;
+ }
+ if (orgpat.regmatch.rm_ic && !match_no_ic)
+ mtt += MT_IC_OFF;
+ if (match_re)
+ mtt += MT_RE_OFF;
+ }
+
+ /*
+ * Add the found match in ga_match[mtt], avoiding duplicates.
+ * Store the info we need later, which depends on the kind of
+ * tags we are dealing with.
+ */
+ if (ga_grow(&ga_match[mtt], 1) == OK) {
+ int len;
+
+ 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 = (struct match_found *)
+ alloc((int)sizeof(struct match_found) + len
+ + 10 + ML_EXTRA);
+ if (mfp != NULL) {
+ /* "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 = (struct match_found *)alloc(
+ (int)sizeof(struct match_found) + len);
+ if (mfp != NULL) {
+ mfp->len = len + 1; /* include the NUL */
+ p = mfp->match;
+ vim_strncpy(p, tagp.command + 2, len);
+ }
+ } else
+ mfp = NULL;
+ get_it_again = FALSE;
+ } else {
+ len = (int)(tagp.tagname_end - tagp.tagname);
+ mfp = (struct match_found *)alloc(
+ (int)sizeof(struct match_found) + len);
+ if (mfp != NULL) {
+ mfp->len = len + 1; /* include the NUL */
+ p = mfp->match;
+ vim_strncpy(p, tagp.tagname, len);
+ }
+
+ /* if wanted, re-read line to get long form too */
+ if (State & INSERT)
+ get_it_again = p_sft;
+ }
+ } 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 = (struct match_found *)alloc(
+ (int)sizeof(struct match_found) + len);
+ if (mfp != NULL) {
+ mfp->len = len;
+ p = mfp->match;
+ p[0] = mtt;
+ STRCPY(p + 1, tag_fname);
+#ifdef BACKSLASH_IN_FILENAME
+ /* Ignore differences in slashes, avoid adding
+ * both path/file and path\file. */
+ slash_adjust(p + 1);
+#endif
+ s = p + 1 + STRLEN(tag_fname) + 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
+ && vim_memcmp(mfp2->match, mfp->match,
+ (size_t)mfp->len) == 0)
+ break;
+ line_breakcheck();
+ }
+ if (i < 0) {
+ ((struct match_found **)(ga_match[mtt].ga_data))
+ [ga_match[mtt].ga_len++] = mfp;
+ ++match_count;
+ } else
+ vim_free(mfp);
+ }
+ } else { /* Out of memory! Just forget about the rest. */
+ retval = OK;
+ stop_searching = TRUE;
+ break;
+ }
+ }
+ if (use_cscope && eof)
+ break;
+ } /* forever */
+
+ if (line_error) {
+ EMSG2(_("E431: Format error in tags file \"%s\""), tag_fname);
+ if (!use_cscope)
+ EMSGN(_("Before byte %ld"), (long)ftell(fp));
+ stop_searching = TRUE;
+ line_error = FALSE;
+ }
+
+ if (!use_cscope)
+ fclose(fp);
+ if (vimconv.vc_type != CONV_NONE)
+ convert_setup(&vimconv, NULL, NULL);
+
+ tag_file_sorted = NUL;
+ if (sort_error) {
+ EMSG2(_("E432: Tags file not sorted: %s"), tag_fname);
+ sort_error = FALSE;
+ }
+
+ /*
+ * Stop searching if sufficient tags have been found.
+ */
+ if (match_count >= mincount) {
+ retval = OK;
+ stop_searching = TRUE;
+ }
+
+ if (stop_searching || use_cscope)
+ break;
+
+ } /* end of for-each-file loop */
+
+ if (!use_cscope)
+ tagname_free(&tn);
+
+ /* stop searching when already did a linear search, or when TAG_NOIC
+ * used, and 'ignorecase' not set or already did case-ignore search */
+ if (stop_searching || linear || (!p_ic && noic) || orgpat.regmatch.rm_ic)
+ break;
+ if (use_cscope)
+ break;
+ orgpat.regmatch.rm_ic = TRUE; /* try another time while ignoring case */
+ }
+
+ if (!stop_searching) {
+ if (!did_open && verbose) /* never opened any tags file */
+ EMSG(_("E433: No tags file"));
+ retval = OK; /* It's OK even when no tag found */
+ }
+
+findtag_end:
+ vim_free(lbuf);
+ vim_regfree(orgpat.regmatch.regprog);
+ vim_free(tag_fname);
+
+ /*
+ * Move the matches from the ga_match[] arrays into one list of
+ * matches. When retval == FAIL, free the matches.
+ */
+ if (retval == FAIL)
+ match_count = 0;
+
+ if (match_count > 0)
+ matches = (char_u **)lalloc((long_u)(match_count * sizeof(char_u *)),
+ TRUE);
+ else
+ matches = NULL;
+ match_count = 0;
+ for (mtt = 0; mtt < MT_COUNT; ++mtt) {
+ for (i = 0; i < ga_match[mtt].ga_len; ++i) {
+ mfp = ((struct match_found **)(ga_match[mtt].ga_data))[i];
+ if (matches == NULL)
+ vim_free(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. */
+ mch_memmove(mfp, mfp->match,
+ (size_t)(mfp->len + (help_only ? ML_HELP_LEN : 0)));
+ matches[match_count++] = (char_u *)mfp;
+ }
+ }
+ ga_clear(&ga_match[mtt]);
+ }
+
+ *matchesp = matches;
+ *num_matches = match_count;
+
+ curbuf->b_help = help_save;
+ vim_free(saved_pat);
+
+ return retval;
+}
+
+static garray_T tag_fnames = GA_EMPTY;
+static void found_tagfile_cb __ARGS((char_u *fname, void *cookie));
+
+/*
+ * Callback function for finding all "tags" and "tags-??" files in
+ * 'runtimepath' doc directories.
+ */
+static void found_tagfile_cb(fname, cookie)
+char_u *fname;
+void *cookie UNUSED;
+{
+ if (ga_grow(&tag_fnames, 1) == OK)
+ ((char_u **)(tag_fnames.ga_data))[tag_fnames.ga_len++] =
+ vim_strsave(fname);
+}
+
+#if defined(EXITFREE) || defined(PROTO)
+void free_tag_stuff() {
+ ga_clear_strings(&tag_fnames);
+ do_tag(NULL, DT_FREE, 0, 0, 0);
+ tag_freematch();
+
+ if (ptag_entry.tagname) {
+ vim_free(ptag_entry.tagname);
+ ptag_entry.tagname = NULL;
+ }
+}
+
+#endif
+
+/*
+ * Get the next name of a tag file from the tag file list.
+ * For help files, use "tags" file only.
+ *
+ * Return FAIL if no more tag file names, OK otherwise.
+ */
+int get_tagfname(tnp, first, buf)
+tagname_T *tnp; /* holds status info */
+int first; /* TRUE when first file name is wanted */
+char_u *buf; /* pointer to buffer of MAXPATHL chars */
+{
+ char_u *fname = NULL;
+ char_u *r_ptr;
+
+ if (first)
+ vim_memset(tnp, 0, sizeof(tagname_T));
+
+ if (curbuf->b_help) {
+ /*
+ * For help files it's done in a completely different way:
+ * Find "doc/tags" and "doc/tags-??" in all directories in
+ * 'runtimepath'.
+ */
+ if (first) {
+ ga_clear_strings(&tag_fnames);
+ ga_init2(&tag_fnames, (int)sizeof(char_u *), 10);
+ do_in_runtimepath((char_u *)
+ "doc/tags doc/tags-??"
+ , TRUE, found_tagfile_cb, NULL);
+ }
+
+ if (tnp->tn_hf_idx >= tag_fnames.ga_len) {
+ /* Not found in 'runtimepath', use 'helpfile', if it exists and
+ * wasn't used yet, replacing "help.txt" with "tags". */
+ if (tnp->tn_hf_idx > tag_fnames.ga_len || *p_hf == NUL)
+ return FAIL;
+ ++tnp->tn_hf_idx;
+ STRCPY(buf, p_hf);
+ STRCPY(gettail(buf), "tags");
+ } else
+ vim_strncpy(buf, ((char_u **)(tag_fnames.ga_data))[
+ tnp->tn_hf_idx++], MAXPATHL - 1);
+ return OK;
+ }
+
+ if (first) {
+ /* Init. We make a copy of 'tags', because autocommands may change
+ * the value without notifying us. */
+ tnp->tn_tags = vim_strsave((*curbuf->b_p_tags != NUL)
+ ? curbuf->b_p_tags : p_tags);
+ if (tnp->tn_tags == NULL)
+ return FAIL;
+ tnp->tn_np = tnp->tn_tags;
+ }
+
+ /*
+ * Loop until we have found a file name that can be used.
+ * There are two states:
+ * tnp->tn_did_filefind_init == FALSE: setup for next part in 'tags'.
+ * tnp->tn_did_filefind_init == TRUE: find next file in this part.
+ */
+ for (;; ) {
+ if (tnp->tn_did_filefind_init) {
+ fname = vim_findfile(tnp->tn_search_ctx);
+ if (fname != NULL)
+ break;
+
+ tnp->tn_did_filefind_init = FALSE;
+ } else {
+ char_u *filename = NULL;
+
+ /* Stop when used all parts of 'tags'. */
+ if (*tnp->tn_np == NUL) {
+ vim_findfile_cleanup(tnp->tn_search_ctx);
+ tnp->tn_search_ctx = NULL;
+ return FAIL;
+ }
+
+ /*
+ * Copy next file name into buf.
+ */
+ buf[0] = NUL;
+ (void)copy_option_part(&tnp->tn_np, buf, MAXPATHL - 1, " ,");
+
+ r_ptr = vim_findfile_stopdir(buf);
+ /* move the filename one char forward and truncate the
+ * filepath with a NUL */
+ filename = gettail(buf);
+ STRMOVE(filename + 1, filename);
+ *filename++ = NUL;
+
+ tnp->tn_search_ctx = vim_findfile_init(buf, filename,
+ r_ptr, 100,
+ FALSE, /* don't free visited list */
+ FINDFILE_FILE, /* we search for a file */
+ tnp->tn_search_ctx, TRUE, curbuf->b_ffname);
+ if (tnp->tn_search_ctx != NULL)
+ tnp->tn_did_filefind_init = TRUE;
+ }
+ }
+
+ STRCPY(buf, fname);
+ vim_free(fname);
+ return OK;
+}
+
+/*
+ * Free the contents of a tagname_T that was filled by get_tagfname().
+ */
+void tagname_free(tnp)
+tagname_T *tnp;
+{
+ vim_free(tnp->tn_tags);
+ vim_findfile_cleanup(tnp->tn_search_ctx);
+ tnp->tn_search_ctx = NULL;
+ ga_clear_strings(&tag_fnames);
+}
+
+/*
+ * Parse one line from the tags file. Find start/end of tag name, start/end of
+ * file name and start of search pattern.
+ *
+ * If is_etag is TRUE, tagp->fname and tagp->fname_end are not set.
+ *
+ * Return FAIL if there is a format error in this line, OK otherwise.
+ */
+static int parse_tag_line(lbuf,
+ tagp)
+char_u *lbuf; /* line to be parsed */
+tagptrs_T *tagp;
+{
+ char_u *p;
+
+ /* Isolate the tagname, from lbuf up to the first white */
+ tagp->tagname = lbuf;
+#ifdef FEAT_TAG_ANYWHITE
+ p = skiptowhite(lbuf);
+#else
+ p = vim_strchr(lbuf, TAB);
+ if (p == NULL)
+ return FAIL;
+#endif
+ tagp->tagname_end = p;
+
+ /* Isolate file name, from first to second white space */
+#ifdef FEAT_TAG_ANYWHITE
+ p = skipwhite(p);
+#else
+ if (*p != NUL)
+ ++p;
+#endif
+ tagp->fname = p;
+#ifdef FEAT_TAG_ANYWHITE
+ p = skiptowhite(p);
+#else
+ p = vim_strchr(p, TAB);
+ if (p == NULL)
+ return FAIL;
+#endif
+ tagp->fname_end = p;
+
+ /* find start of search command, after second white space */
+#ifdef FEAT_TAG_ANYWHITE
+ p = skipwhite(p);
+#else
+ if (*p != NUL)
+ ++p;
+#endif
+ if (*p == NUL)
+ return FAIL;
+ tagp->command = p;
+
+ return OK;
+}
+
+/*
+ * Check if tagname is a static tag
+ *
+ * Static tags produced by the older ctags program have the format:
+ * 'file:tag file /pattern'.
+ * This is only recognized when both occurrence of 'file' are the same, to
+ * avoid recognizing "string::string" or ":exit".
+ *
+ * Static tags produced by the new ctags program have the format:
+ * 'tag file /pattern/;"<Tab>file:' "
+ *
+ * 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(tagp)
+tagptrs_T *tagp;
+{
+ char_u *p;
+
+ int len;
+
+ /*
+ * Check for old style static tag: "file:tag file .."
+ */
+ len = (int)(tagp->fname_end - tagp->fname);
+ p = tagp->tagname + len;
+ if ( p < tagp->tagname_end
+ && *p == ':'
+ && fnamencmp(tagp->tagname, tagp->fname, len) == 0) {
+ tagp->tagname = p + 1;
+ return TRUE;
+ }
+
+ /*
+ * Check for new style static tag ":...<Tab>file:[<Tab>...]"
+ */
+ p = tagp->command;
+ while ((p = vim_strchr(p, '\t')) != NULL) {
+ ++p;
+ if (STRNCMP(p, "file:", 5) == 0)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/*
+ * Parse a line from a matching tag. Does not change the line itself.
+ *
+ * The line that we get looks like this:
+ * 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>
+ *
+ * Return OK or FAIL.
+ */
+static int parse_match(lbuf, tagp)
+char_u *lbuf; /* input: matching line */
+tagptrs_T *tagp; /* output: pointers into the line */
+{
+ int retval;
+ char_u *p;
+ char_u *pc, *pt;
+
+ tagp->tag_fname = lbuf + 1;
+ lbuf += STRLEN(tagp->tag_fname) + 2;
+
+ /* Find search pattern and the file name for non-etags. */
+ retval = parse_tag_line(lbuf,
+ tagp);
+
+ tagp->tagkind = NULL;
+ tagp->command_end = NULL;
+
+ if (retval == OK) {
+ /* Try to find a kind field: "kind:<kind>" or just "<kind>"*/
+ p = tagp->command;
+ if (find_extra(&p) == OK) {
+ tagp->command_end = p;
+ p += 2; /* skip ";\"" */
+ if (*p++ == TAB)
+ while (ASCII_ISALPHA(*p)) {
+ if (STRNCMP(p, "kind:", 5) == 0) {
+ tagp->tagkind = p + 5;
+ break;
+ }
+ pc = vim_strchr(p, ':');
+ pt = vim_strchr(p, '\t');
+ if (pc == NULL || (pt != NULL && pc > pt)) {
+ tagp->tagkind = p;
+ break;
+ }
+ if (pt == NULL)
+ break;
+ p = pt + 1;
+ }
+ }
+ if (tagp->tagkind != NULL) {
+ for (p = tagp->tagkind;
+ *p && *p != '\t' && *p != '\r' && *p != '\n'; ++p)
+ ;
+ tagp->tagkind_end = p;
+ }
+ }
+ return retval;
+}
+
+/*
+ * Find out the actual file name of a tag. Concatenate the tags file name
+ * with the matching tag file name.
+ * Returns an allocated string or NULL (out of memory).
+ */
+static char_u * tag_full_fname(tagp)
+tagptrs_T *tagp;
+{
+ char_u *fullname;
+ int c;
+
+ {
+ c = *tagp->fname_end;
+ *tagp->fname_end = NUL;
+ }
+ fullname = expand_tag_fname(tagp->fname, tagp->tag_fname, FALSE);
+
+ *tagp->fname_end = c;
+
+ return fullname;
+}
+
+/*
+ * Jump to a tag that has been found in one of the tag files
+ *
+ * returns OK for success, NOTAGFILE when file not found, FAIL otherwise.
+ */
+static int jumpto_tag(lbuf, forceit, keep_help)
+char_u *lbuf; /* line from the tags file for this tag */
+int forceit; /* :ta with ! */
+int keep_help; /* keep help flag (FALSE for cscope) */
+{
+ int save_secure;
+ int save_magic;
+ int save_p_ws, 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;
+ char_u *tofree_fname = NULL;
+ char_u *fname;
+ tagptrs_T tagp;
+ int retval = FAIL;
+ int getfile_result;
+ 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 */
+
+ pbuf = alloc(LSIZE);
+
+ /* parse the match line into the tagp structure */
+ if (pbuf == NULL || parse_match(lbuf, &tagp) == FAIL) {
+ tagp.fname_end = NULL;
+ goto erret;
+ }
+
+ /* truncate the file name, so it can be used as a string */
+ csave = *tagp.fname_end;
+ *tagp.fname_end = NUL;
+ fname = tagp.fname;
+
+ /* copy the command to pbuf[], remove trailing CR/NL */
+ str = tagp.command;
+ for (pbuf_end = pbuf; *str && *str != '\n' && *str != '\r'; ) {
+ *pbuf_end++ = *str++;
+ }
+ *pbuf_end = NUL;
+
+ {
+ /*
+ * Remove the "<Tab>fieldname:value" stuff; we don't need it here.
+ */
+ str = pbuf;
+ if (find_extra(&str) == OK) {
+ pbuf_end = str;
+ *pbuf_end = NUL;
+ }
+ }
+
+ /*
+ * 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);
+ if (fname == NULL)
+ goto erret;
+ tofree_fname = fname; /* free() it later */
+
+ /*
+ * Check if the file with the tag exists before abandoning the current
+ * file. Also accept a file name for which there is a matching BufReadCmd
+ * autocommand event (e.g., http://sys/file).
+ */
+ if (mch_getperm(fname) < 0
+ && !has_autocmd(EVENT_BUFREADCMD, fname, NULL)
+ ) {
+ retval = NOTAGFILE;
+ vim_free(nofile_fname);
+ nofile_fname = vim_strsave(fname);
+ if (nofile_fname == NULL)
+ nofile_fname = empty_option;
+ goto erret;
+ }
+
+ ++RedrawingDisabled;
+
+
+ if (g_do_tagpreview != 0) {
+ postponed_split = 0; /* don't split again below */
+ curwin_save = curwin; /* Save current window */
+
+ /*
+ * If we are reusing a window, we may change dir when
+ * entering it (autocommands) so turn the tag filename
+ * into a fullpath
+ */
+ if (!curwin->w_p_pvw) {
+ full_fname = FullName_save(fname, FALSE);
+ fname = full_fname;
+
+ /*
+ * Make the preview window the current window.
+ * Open a preview window when needed.
+ */
+ prepare_tagpreview(TRUE);
+ }
+ }
+
+ /* 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);
+ RESET_BINDING(curwin);
+ }
+
+ if (keep_help) {
+ /* A :ta from a help file will keep the b_help flag set. For ":ptag"
+ * we need to use the flag from the window where we came from. */
+ if (g_do_tagpreview != 0)
+ keep_help_flag = curwin_save->w_buffer->b_help;
+ 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;
+ postponed_split = 0;
+
+ save_secure = secure;
+ secure = 1;
+#ifdef HAVE_SANDBOX
+ ++sandbox;
+#endif
+ save_magic = p_magic;
+ p_magic = FALSE; /* always execute with 'nomagic' */
+ /* Save value of no_hlsearch, jumping to a tag is not a real search */
+ save_no_hlsearch = no_hlsearch;
+
+ /*
+ * If 'cpoptions' contains 't', store the search pattern for the "n"
+ * command. If 'cpoptions' does not contain 't', the search pattern
+ * is not stored.
+ */
+ if (vim_strchr(p_cpo, CPO_TAGPAT) != NULL)
+ search_options = 0;
+ else
+ search_options = SEARCH_KEEP;
+
+ /*
+ * If the command is a search, try here.
+ *
+ * Reset 'smartcase' for the search, since the search pattern was not
+ * typed by the user.
+ * Only use do_search() when there is a full search command, without
+ * anything following.
+ */
+ str = pbuf;
+ if (pbuf[0] == '/' || pbuf[0] == '?')
+ str = skip_regexp(pbuf + 1, pbuf[0], FALSE, NULL) + 1;
+ if (str > pbuf_end - 1) { /* search command with nothing following */
+ save_p_ws = p_ws;
+ save_p_ic = p_ic;
+ save_p_scs = p_scs;
+ p_ws = TRUE; /* need 'wrapscan' for backward searches */
+ p_ic = FALSE; /* don't ignore case now */
+ p_scs = FALSE;
+ save_lnum = curwin->w_cursor.lnum;
+ curwin->w_cursor.lnum = 0; /* start search before first line */
+ if (do_search(NULL, pbuf[0], pbuf + 1, (long)1,
+ search_options, NULL))
+ retval = OK;
+ else {
+ int found = 1;
+ int cc;
+
+ /*
+ * try again, ignore case now
+ */
+ p_ic = TRUE;
+ if (!do_search(NULL, pbuf[0], pbuf + 1, (long)1,
+ search_options, NULL)) {
+ /*
+ * Failed to find pattern, take a guess: "^func ("
+ */
+ found = 2;
+ (void)test_for_static(&tagp);
+ cc = *tagp.tagname_end;
+ *tagp.tagname_end = NUL;
+ sprintf((char *)pbuf, "^%s\\s\\*(", tagp.tagname);
+ if (!do_search(NULL, '/', pbuf, (long)1,
+ search_options, NULL)) {
+ /* Guess again: "^char * \<func (" */
+ sprintf((char *)pbuf, "^\\[#a-zA-Z_]\\.\\*\\<%s\\s\\*(",
+ tagp.tagname);
+ if (!do_search(NULL, '/', pbuf, (long)1,
+ search_options, NULL))
+ found = 0;
+ }
+ *tagp.tagname_end = cc;
+ }
+ if (found == 0) {
+ EMSG(_("E434: Can't find tag pattern"));
+ curwin->w_cursor.lnum = save_lnum;
+ } else {
+ /*
+ * Only give a message when really guessed, not when 'ic'
+ * is set and match found while ignoring case.
+ */
+ if (found == 2 || !save_p_ic) {
+ MSG(_("E435: Couldn't find tag, just guessing!"));
+ if (!msg_scrolled && msg_silent == 0) {
+ out_flush();
+ ui_delay(1000L, TRUE);
+ }
+ }
+ retval = OK;
+ }
+ }
+ p_ws = save_p_ws;
+ p_ic = save_p_ic;
+ p_scs = save_p_scs;
+
+ /* A search command may have positioned the cursor beyond the end
+ * of the line. May need to correct that here. */
+ check_cursor();
+ } else {
+ curwin->w_cursor.lnum = 1; /* start command in line 1 */
+ do_cmdline_cmd(pbuf);
+ retval = OK;
+ }
+
+ /*
+ * When the command has done something that is not allowed make sure
+ * the error message can be seen.
+ */
+ if (secure == 2)
+ wait_return(TRUE);
+ secure = save_secure;
+ p_magic = save_magic;
+#ifdef HAVE_SANDBOX
+ --sandbox;
+#endif
+ /* restore no_hlsearch when keeping the old search pattern */
+ if (search_options) {
+ SET_NO_HLSEARCH(save_no_hlsearch);
+ }
+
+ /* Return OK if jumped to another file (at least we found the file!). */
+ if (getfile_result == -1)
+ retval = OK;
+
+ if (retval == OK) {
+ /*
+ * For a help buffer: Put the cursor line at the top of the window,
+ * the help subject will be below it.
+ */
+ if (curbuf->b_help)
+ set_topline(curwin, curwin->w_cursor.lnum);
+ if ((fdo_flags & FDO_TAG) && old_KeyTyped)
+ foldOpenCursor();
+ }
+
+ if (g_do_tagpreview != 0
+ && curwin != curwin_save && win_valid(curwin_save)) {
+ /* Return cursor to where we were */
+ validate_cursor();
+ redraw_later(VALID);
+ win_enter(curwin_save, TRUE);
+ }
+
+ --RedrawingDisabled;
+ } else {
+ --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;
+ vim_free(pbuf);
+ vim_free(tofree_fname);
+ vim_free(full_fname);
+
+ 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 (or NULL when out of memory).
+ */
+static char_u * expand_tag_fname(fname, tag_fname, expand)
+char_u *fname;
+char_u *tag_fname;
+int expand;
+{
+ char_u *p;
+ char_u *retval;
+ char_u *expanded_fname = NULL;
+ expand_T xpc;
+
+ /*
+ * Expand file name (for environment variables) when needed.
+ */
+ if (expand && mch_has_wildcard(fname)) {
+ ExpandInit(&xpc);
+ xpc.xp_context = EXPAND_FILES;
+ expanded_fname = ExpandOne(&xpc, (char_u *)fname, NULL,
+ WILD_LIST_NOTFOUND|WILD_SILENT, WILD_EXPAND_FREE);
+ if (expanded_fname != NULL)
+ fname = expanded_fname;
+ }
+
+ if ((p_tr || curbuf->b_help)
+ && !vim_isAbsName(fname)
+ && (p = gettail(tag_fname)) != tag_fname) {
+ retval = alloc(MAXPATHL);
+ if (retval != NULL) {
+ STRCPY(retval, tag_fname);
+ vim_strncpy(retval + (p - tag_fname), fname,
+ MAXPATHL - (p - tag_fname) - 1);
+ /*
+ * Translate names like "src/a/../b/file.c" into "src/b/file.c".
+ */
+ simplify_filename(retval);
+ }
+ } else
+ retval = vim_strsave(fname);
+
+ vim_free(expanded_fname);
+
+ return retval;
+}
+
+/*
+ * Converts a file name into a canonical form. It simplifies a file name into
+ * its simplest form by stripping out unneeded components, if any. The
+ * resulting file name is simplified in place and will either be the same
+ * length as that supplied, or shorter.
+ */
+void simplify_filename(filename)
+char_u *filename;
+{
+ int components = 0;
+ char_u *p, *tail, *start;
+ int stripping_disabled = FALSE;
+ int relative = TRUE;
+
+ p = filename;
+#ifdef BACKSLASH_IN_FILENAME
+ if (p[1] == ':') /* skip "x:" */
+ p += 2;
+#endif
+
+ if (vim_ispathsep(*p)) {
+ relative = FALSE;
+ do
+ ++p;
+ while (vim_ispathsep(*p));
+ }
+ start = p; /* remember start after "c:/" or "/" or "///" */
+
+ do {
+ /* At this point "p" is pointing to the char following a single "/"
+ * or "p" is at the "start" of the (absolute or relative) path name. */
+ if (vim_ispathsep(*p))
+ STRMOVE(p, p + 1); /* remove duplicate "/" */
+ else if (p[0] == '.' && (vim_ispathsep(p[1]) || p[1] == NUL)) {
+ if (p == start && relative)
+ p += 1 + (p[1] != NUL); /* keep single "." or leading "./" */
+ else {
+ /* Strip "./" or ".///". If we are at the end of the file name
+ * and there is no trailing path separator, either strip "/." if
+ * 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 */
+ 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);
+
+ if (components > 0) { /* strip one preceding component */
+ int do_strip = FALSE;
+ char_u saved_char;
+ struct stat st;
+
+ /* Don't strip for an erroneous file name. */
+ if (!stripping_disabled) {
+ /* If the preceding component does not exist in the file
+ * system, we strip it. On Unix, we don't accept a symbolic
+ * link that refers to a non-existent file. */
+ saved_char = p[-1];
+ p[-1] = NUL;
+#ifdef UNIX
+ if (mch_lstat((char *)filename, &st) < 0)
+#else
+ if (mch_stat((char *)filename, &st) < 0)
+#endif
+ do_strip = TRUE;
+ p[-1] = saved_char;
+
+ --p;
+ /* Skip back to after previous '/'. */
+ while (p > start && !after_pathsep(start, p))
+ mb_ptr_back(start, p);
+
+ if (!do_strip) {
+ /* If the component exists in the file system, check
+ * that stripping it won't change the meaning of the
+ * file name. First get information about the
+ * unstripped file name. This may fail if the component
+ * to strip is not a searchable directory (but a regular
+ * file, for instance), since the trailing "/.." cannot
+ * be applied then. We don't strip it then since we
+ * don't want to replace an erroneous file name by
+ * a valid one, and we disable stripping of later
+ * components. */
+ saved_char = *tail;
+ *tail = NUL;
+ if (mch_stat((char *)filename, &st) >= 0)
+ do_strip = TRUE;
+ else
+ stripping_disabled = TRUE;
+ *tail = saved_char;
+#ifdef UNIX
+ if (do_strip) {
+ struct stat new_st;
+
+ /* On Unix, the check for the unstripped file name
+ * above works also for a symbolic link pointing to
+ * a searchable directory. But then the parent of
+ * the directory pointed to by the link must be the
+ * same as the stripped file name. (The latter
+ * exists in the file system since it is the
+ * component's parent directory.) */
+ if (p == start && relative)
+ (void)mch_stat(".", &new_st);
+ else {
+ saved_char = *p;
+ *p = NUL;
+ (void)mch_stat((char *)filename, &new_st);
+ *p = saved_char;
+ }
+
+ if (new_st.st_ino != st.st_ino ||
+ new_st.st_dev != st.st_dev) {
+ do_strip = FALSE;
+ /* We don't disable stripping of later
+ * components since the unstripped path name is
+ * still valid. */
+ }
+ }
+#endif
+ }
+ }
+
+ if (!do_strip) {
+ /* Skip the ".." or "../" and reset the counter for the
+ * components that might be stripped later on. */
+ p = tail;
+ components = 0;
+ } else {
+ /* Strip previous component. If the result would get empty
+ * and there is no trailing path separator, leave a single
+ * "." instead. If we are at the end of the file name and
+ * there is no trailing path separator and a preceding
+ * component is left after stripping, strip its trailing
+ * path separator as well. */
+ if (p == start && relative && tail[-1] == '.') {
+ *p++ = '.';
+ *p = NUL;
+ } else {
+ if (p > start && tail[-1] == '.')
+ --p;
+ STRMOVE(p, tail); /* strip previous component */
+ }
+
+ --components;
+ }
+ } else if (p == start && !relative) /* leading "/.." or "/../" */
+ STRMOVE(p, tail); /* strip ".." or "../" */
+ else {
+ if (p == start + 2 && p[-2] == '.') { /* leading "./../" */
+ STRMOVE(p - 2, p); /* strip leading "./" */
+ tail -= 2;
+ }
+ p = tail; /* skip to char after ".." or "../" */
+ }
+ } else {
+ ++components; /* simple path component */
+ p = getnextcomp(p);
+ }
+ } while (*p != NUL);
+}
+
+/*
+ * Check if we have a tag for the buffer with name "buf_ffname".
+ * This is a bit slow, because of the full path compare in fullpathcmp().
+ * Return TRUE if tag for file "fname" if tag file "tag_fname" is for current
+ * file.
+ */
+static int test_for_current(fname, fname_end, tag_fname, buf_ffname)
+char_u *fname;
+char_u *fname_end;
+char_u *tag_fname;
+char_u *buf_ffname;
+{
+ int c;
+ int retval = FALSE;
+ char_u *fullname;
+
+ if (buf_ffname != NULL) { /* if the buffer has a name */
+ {
+ c = *fname_end;
+ *fname_end = NUL;
+ }
+ fullname = expand_tag_fname(fname, tag_fname, TRUE);
+ if (fullname != NULL) {
+ retval = (fullpathcmp(fullname, buf_ffname, TRUE) & FPC_SAME);
+ vim_free(fullname);
+ }
+ *fname_end = c;
+ }
+
+ return retval;
+}
+
+/*
+ * Find the end of the tagaddress.
+ * Return OK if ";\"" is following, FAIL otherwise.
+ */
+static int find_extra(pp)
+char_u **pp;
+{
+ char_u *str = *pp;
+
+ /* Repeat for addresses separated with ';' */
+ for (;; ) {
+ if (VIM_ISDIGIT(*str))
+ str = skipdigits(str);
+ else if (*str == '/' || *str == '?') {
+ str = skip_regexp(str + 1, *str, FALSE, NULL);
+ if (*str != **pp)
+ str = NULL;
+ else
+ ++str;
+ } else
+ str = NULL;
+ if (str == NULL || *str != ';'
+ || !(VIM_ISDIGIT(str[1]) || str[1] == '/' || str[1] == '?'))
+ break;
+ ++str; /* skip ';' */
+ }
+
+ if (str != NULL && STRNCMP(str, ";\"", 2) == 0) {
+ *pp = str;
+ return OK;
+ }
+ return FAIL;
+}
+
+int expand_tags(tagnames, pat, num_file, file)
+int tagnames; /* expand tag names */
+char_u *pat;
+int *num_file;
+char_u ***file;
+{
+ int i;
+ int c;
+ int tagnmflag;
+ char_u tagnm[100];
+ tagptrs_T t_p;
+ int ret;
+
+ if (tagnames)
+ tagnmflag = TAG_NAMES;
+ else
+ tagnmflag = 0;
+ if (pat[0] == '/')
+ ret = find_tags(pat + 1, num_file, file,
+ TAG_REGEXP | tagnmflag | TAG_VERBOSE,
+ TAG_MANY, curbuf->b_ffname);
+ else
+ ret = find_tags(pat, num_file, file,
+ TAG_REGEXP | tagnmflag | TAG_VERBOSE | TAG_NOIC,
+ TAG_MANY, curbuf->b_ffname);
+ if (ret == OK && !tagnames) {
+ /* Reorganize the tags for display and matching as strings of:
+ * "<tagname>\0<kind>\0<filename>\0"
+ */
+ for (i = 0; i < *num_file; i++) {
+ parse_match((*file)[i], &t_p);
+ c = (int)(t_p.tagname_end - t_p.tagname);
+ mch_memmove(tagnm, t_p.tagname, (size_t)c);
+ tagnm[c++] = 0;
+ tagnm[c++] = (t_p.tagkind != NULL && *t_p.tagkind)
+ ? *t_p.tagkind : 'f';
+ tagnm[c++] = 0;
+ mch_memmove((*file)[i] + c, t_p.fname, t_p.fname_end - t_p.fname);
+ (*file)[i][c + (t_p.fname_end - t_p.fname)] = 0;
+ mch_memmove((*file)[i], tagnm, (size_t)c);
+ }
+ }
+ return ret;
+}
+
+static int add_tag_field __ARGS((dict_T *dict, char *field_name, char_u *start,
+ char_u *end));
+
+/*
+ * Add a tag field to the dictionary "dict".
+ * Return OK or FAIL.
+ */
+static int add_tag_field(dict, field_name, start, end)
+dict_T *dict;
+char *field_name;
+char_u *start; /* start of the value */
+char_u *end; /* after the value; can be NULL */
+{
+ char_u *buf;
+ int len = 0;
+ int retval;
+
+ /* check that the field name doesn't exist yet */
+ if (dict_find(dict, (char_u *)field_name, -1) != NULL) {
+ if (p_verbose > 0) {
+ verbose_enter();
+ smsg((char_u *)_("Duplicate field name: %s"), field_name);
+ verbose_leave();
+ }
+ return FAIL;
+ }
+ buf = alloc(MAXPATHL);
+ if (buf == NULL)
+ return FAIL;
+ if (start != NULL) {
+ if (end == NULL) {
+ end = start + STRLEN(start);
+ while (end > start && (end[-1] == '\r' || end[-1] == '\n'))
+ --end;
+ }
+ len = (int)(end - start);
+ if (len > MAXPATHL - 1)
+ len = MAXPATHL - 1;
+ vim_strncpy(buf, start, len);
+ }
+ buf[len] = NUL;
+ retval = dict_add_nr_str(dict, field_name, 0L, buf);
+ vim_free(buf);
+ return retval;
+}
+
+/*
+ * Add the tags matching the specified pattern to the list "list"
+ * as a dictionary
+ */
+int get_tags(list, pat)
+list_T *list;
+char_u *pat;
+{
+ int num_matches, i, ret;
+ char_u **matches, *p;
+ char_u *full_fname;
+ dict_T *dict;
+ tagptrs_T tp;
+ long is_static;
+
+ ret = find_tags(pat, &num_matches, &matches,
+ TAG_REGEXP | TAG_NOIC, (int)MAXCOL, NULL);
+ if (ret == OK && num_matches > 0) {
+ for (i = 0; i < num_matches; ++i) {
+ parse_match(matches[i], &tp);
+ is_static = test_for_static(&tp);
+
+ /* Skip pseudo-tag lines. */
+ if (STRNCMP(tp.tagname, "!_TAG_", 6) == 0)
+ continue;
+
+ if ((dict = dict_alloc()) == NULL)
+ ret = FAIL;
+ if (list_append_dict(list, dict) == FAIL)
+ ret = FAIL;
+
+ 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, "kind", tp.tagkind,
+ tp.tagkind_end) == FAIL
+ || dict_add_nr_str(dict, "static", is_static, NULL) == FAIL)
+ ret = FAIL;
+
+ vim_free(full_fname);
+
+ if (tp.command_end != NULL) {
+ for (p = tp.command_end + 3;
+ *p != NUL && *p != '\n' && *p != '\r'; ++p) {
+ if (p == tp.tagkind || (p + 5 == tp.tagkind
+ && STRNCMP(p, "kind:", 5) == 0))
+ /* skip "kind:<kind>" and "<kind>" */
+ p = tp.tagkind_end - 1;
+ else if (STRNCMP(p, "file:", 5) == 0)
+ /* skip "file:" (static tag) */
+ p += 4;
+ else if (!vim_iswhite(*p)) {
+ char_u *s, *n;
+ int len;
+
+ /* Add extra field as a dict entry. Fields are
+ * separated by Tabs. */
+ n = p;
+ while (*p != NUL && *p >= ' ' && *p < 127 && *p != ':')
+ ++p;
+ len = (int)(p - n);
+ if (*p == ':' && len > 0) {
+ s = ++p;
+ while (*p != NUL && *p >= ' ')
+ ++p;
+ n[len] = NUL;
+ if (add_tag_field(dict, (char *)n, s, p) == FAIL)
+ ret = FAIL;
+ n[len] = ':';
+ } else
+ /* Skip field without colon. */
+ while (*p != NUL && *p >= ' ')
+ ++p;
+ if (*p == NUL)
+ break;
+ }
+ }
+ }
+
+ vim_free(matches[i]);
+ }
+ vim_free(matches);
+ }
+ return ret;
+}
diff --git a/src/term.c b/src/term.c
new file mode 100644
index 0000000000..7525244ca1
--- /dev/null
+++ b/src/term.c
@@ -0,0 +1,4787 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * 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.
+ */
+/*
+ *
+ * term.c: functions for controlling the terminal
+ *
+ * primitive termcap support for Amiga, MSDOS, and Win32 included
+ *
+ * NOTE: padding and variable substitution is not performed,
+ * when compiling without HAVE_TGETENT, we use tputs() and tgoto() dummies.
+ */
+
+/*
+ * Some systems have a prototype for tgetstr() with (char *) instead of
+ * (char **). This define removes that prototype. We include our own prototype
+ * below.
+ */
+
+#define tgetstr tgetstr_defined_wrong
+#include "vim.h"
+
+#ifdef HAVE_TGETENT
+# ifdef HAVE_TERMIOS_H
+# include <termios.h> /* seems to be required for some Linux */
+# endif
+# ifdef HAVE_TERMCAP_H
+# include <termcap.h>
+# endif
+
+/*
+ * A few linux systems define outfuntype in termcap.h to be used as the third
+ * argument for tputs().
+ */
+# define TPUTSFUNCAST (int (*)())
+#endif
+
+#undef tgetstr
+
+/*
+ * Here are the builtin termcap entries. They are not stored as complete
+ * structures with all entries, as such a structure is too big.
+ *
+ * The entries are compact, therefore they normally are included even when
+ * HAVE_TGETENT is defined. When HAVE_TGETENT is defined, the builtin entries
+ * can be accessed with "builtin_amiga", "builtin_ansi", "builtin_debug", etc.
+ *
+ * Each termcap is a list of builtin_term structures. It always starts with
+ * KS_NAME, which separates the entries. See parse_builtin_tcap() for all
+ * details.
+ * bt_entry is either a KS_xxx code (>= 0), or a K_xxx code.
+ *
+ * Entries marked with "guessed" may be wrong.
+ */
+struct builtin_term {
+ int bt_entry;
+ char *bt_string;
+};
+
+/* start of keys that are not directly used by Vim but can be mapped */
+#define BT_EXTRA_KEYS 0x101
+
+static struct builtin_term *find_builtin_term __ARGS((char_u *name));
+static void parse_builtin_tcap __ARGS((char_u *s));
+static void term_color __ARGS((char_u *s, int n));
+static void gather_termleader __ARGS((void));
+static void req_codes_from_term __ARGS((void));
+static void req_more_codes_from_term __ARGS((void));
+static void got_code_from_term __ARGS((char_u *code, int len));
+static void check_for_codes_from_term __ARGS((void));
+#if defined(FEAT_GUI) \
+ || (defined(FEAT_MOUSE) && (!defined(UNIX) || defined(FEAT_MOUSE_XTERM) \
+ || defined(FEAT_MOUSE_GPM) || defined(FEAT_SYSMOUSE)))
+static int get_bytes_from_buf __ARGS((char_u *, char_u *, int));
+#endif
+static void del_termcode_idx __ARGS((int idx));
+static int term_is_builtin __ARGS((char_u *name));
+static int term_7to8bit __ARGS((char_u *p));
+static void switch_to_8bit __ARGS((void));
+
+#ifdef HAVE_TGETENT
+static char_u *tgetent_error __ARGS((char_u *, char_u *));
+
+/*
+ * Here is our own prototype for tgetstr(), any prototypes from the include
+ * files have been disabled by the define at the start of this file.
+ */
+char *tgetstr __ARGS((char *, char **));
+
+/* Change this to "if 1" to debug what happens with termresponse. */
+# define LOG_TR(msg)
+/* Request Terminal Version status: */
+# define CRV_GET 1 /* send T_CRV when switched to RAW mode */
+# define CRV_SENT 2 /* did send T_CRV, waiting for answer */
+# define CRV_GOT 3 /* received T_CRV response */
+static int crv_status = CRV_GET;
+/* Request Cursor position report: */
+# define U7_GET 1 /* send T_U7 when switched to RAW mode */
+# define U7_SENT 2 /* did send T_U7, waiting for answer */
+# define U7_GOT 3 /* received T_U7 response */
+static int u7_status = U7_GET;
+
+/*
+ * Don't declare these variables if termcap.h contains them.
+ * Autoconf checks if these variables should be declared extern (not all
+ * systems have them).
+ * Some versions define ospeed to be speed_t, but that is incompatible with
+ * BSD, where ospeed is short and speed_t is long.
+ */
+# ifndef HAVE_OSPEED
+# ifdef OSPEED_EXTERN
+extern short ospeed;
+# else
+short ospeed;
+# endif
+# endif
+# ifndef HAVE_UP_BC_PC
+# ifdef UP_BC_PC_EXTERN
+extern char *UP, *BC, PC;
+# else
+char *UP, *BC, PC;
+# endif
+# endif
+
+# define TGETSTR(s, p) vim_tgetstr((s), (p))
+# define TGETENT(b, t) tgetent((char *)(b), (char *)(t))
+static char_u *vim_tgetstr __ARGS((char *s, char_u **pp));
+#endif /* HAVE_TGETENT */
+
+static int detected_8bit = FALSE; /* detected 8-bit terminal */
+
+static struct builtin_term builtin_termcaps[] =
+{
+
+
+#ifndef NO_BUILTIN_TCAPS
+
+# if defined(AMIGA) || defined(ALL_BUILTIN_TCAPS)
+ /*
+ * Amiga console window, default for Amiga
+ */
+ {(int)KS_NAME, "amiga"},
+ {(int)KS_CE, "\033[K"},
+ {(int)KS_CD, "\033[J"},
+ {(int)KS_AL, "\033[L"},
+# ifdef TERMINFO
+ {(int)KS_CAL, "\033[%p1%dL"},
+# else
+ {(int)KS_CAL, "\033[%dL"},
+# endif
+ {(int)KS_DL, "\033[M"},
+# ifdef TERMINFO
+ {(int)KS_CDL, "\033[%p1%dM"},
+# else
+ {(int)KS_CDL, "\033[%dM"},
+# endif
+ {(int)KS_CL, "\014"},
+ {(int)KS_VI, "\033[0 p"},
+ {(int)KS_VE, "\033[1 p"},
+ {(int)KS_ME, "\033[0m"},
+ {(int)KS_MR, "\033[7m"},
+ {(int)KS_MD, "\033[1m"},
+ {(int)KS_SE, "\033[0m"},
+ {(int)KS_SO, "\033[33m"},
+ {(int)KS_US, "\033[4m"},
+ {(int)KS_UE, "\033[0m"},
+ {(int)KS_CZH, "\033[3m"},
+ {(int)KS_CZR, "\033[0m"},
+#if defined(__MORPHOS__) || defined(__AROS__)
+ {(int)KS_CCO, "8"}, /* allow 8 colors */
+# ifdef TERMINFO
+ {(int)KS_CAB, "\033[4%p1%dm"}, /* set background color */
+ {(int)KS_CAF, "\033[3%p1%dm"}, /* set foreground color */
+# else
+ {(int)KS_CAB, "\033[4%dm"}, /* set background color */
+ {(int)KS_CAF, "\033[3%dm"}, /* set foreground color */
+# endif
+ {(int)KS_OP, "\033[m"}, /* reset colors */
+#endif
+ {(int)KS_MS, "y"},
+ {(int)KS_UT, "y"}, /* guessed */
+ {(int)KS_LE, "\b"},
+# ifdef TERMINFO
+ {(int)KS_CM, "\033[%i%p1%d;%p2%dH"},
+# else
+ {(int)KS_CM, "\033[%i%d;%dH"},
+# endif
+#if defined(__MORPHOS__)
+ {(int)KS_SR, "\033M"},
+#endif
+# ifdef TERMINFO
+ {(int)KS_CRI, "\033[%p1%dC"},
+# else
+ {(int)KS_CRI, "\033[%dC"},
+# endif
+ {K_UP, "\233A"},
+ {K_DOWN, "\233B"},
+ {K_LEFT, "\233D"},
+ {K_RIGHT, "\233C"},
+ {K_S_UP, "\233T"},
+ {K_S_DOWN, "\233S"},
+ {K_S_LEFT, "\233 A"},
+ {K_S_RIGHT, "\233 @"},
+ {K_S_TAB, "\233Z"},
+ {K_F1, "\233\060~"}, /* some compilers don't dig "\2330" */
+ {K_F2, "\233\061~"},
+ {K_F3, "\233\062~"},
+ {K_F4, "\233\063~"},
+ {K_F5, "\233\064~"},
+ {K_F6, "\233\065~"},
+ {K_F7, "\233\066~"},
+ {K_F8, "\233\067~"},
+ {K_F9, "\233\070~"},
+ {K_F10, "\233\071~"},
+ {K_S_F1, "\233\061\060~"},
+ {K_S_F2, "\233\061\061~"},
+ {K_S_F3, "\233\061\062~"},
+ {K_S_F4, "\233\061\063~"},
+ {K_S_F5, "\233\061\064~"},
+ {K_S_F6, "\233\061\065~"},
+ {K_S_F7, "\233\061\066~"},
+ {K_S_F8, "\233\061\067~"},
+ {K_S_F9, "\233\061\070~"},
+ {K_S_F10, "\233\061\071~"},
+ {K_HELP, "\233?~"},
+ {K_INS, "\233\064\060~"}, /* 101 key keyboard */
+ {K_PAGEUP, "\233\064\061~"}, /* 101 key keyboard */
+ {K_PAGEDOWN, "\233\064\062~"}, /* 101 key keyboard */
+ {K_HOME, "\233\064\064~"}, /* 101 key keyboard */
+ {K_END, "\233\064\065~"}, /* 101 key keyboard */
+
+ {BT_EXTRA_KEYS, ""},
+ {TERMCAP2KEY('#', '2'), "\233\065\064~"}, /* shifted home key */
+ {TERMCAP2KEY('#', '3'), "\233\065\060~"}, /* shifted insert key */
+ {TERMCAP2KEY('*', '7'), "\233\065\065~"}, /* shifted end key */
+# endif
+
+# if defined(__BEOS__) || defined(ALL_BUILTIN_TCAPS)
+ /*
+ * almost standard ANSI terminal, default for bebox
+ */
+ {(int)KS_NAME, "beos-ansi"},
+ {(int)KS_CE, "\033[K"},
+ {(int)KS_CD, "\033[J"},
+ {(int)KS_AL, "\033[L"},
+# ifdef TERMINFO
+ {(int)KS_CAL, "\033[%p1%dL"},
+# else
+ {(int)KS_CAL, "\033[%dL"},
+# endif
+ {(int)KS_DL, "\033[M"},
+# ifdef TERMINFO
+ {(int)KS_CDL, "\033[%p1%dM"},
+# else
+ {(int)KS_CDL, "\033[%dM"},
+# endif
+#ifdef BEOS_PR_OR_BETTER
+# ifdef TERMINFO
+ {(int)KS_CS, "\033[%i%p1%d;%p2%dr"},
+# else
+ {(int)KS_CS, "\033[%i%d;%dr"}, /* scroll region */
+# endif
+#endif
+ {(int)KS_CL, "\033[H\033[2J"},
+#ifdef notyet
+ {(int)KS_VI, "[VI]"}, /* cursor invisible, VT320: CSI ? 25 l */
+ {(int)KS_VE, "[VE]"}, /* cursor visible, VT320: CSI ? 25 h */
+#endif
+ {(int)KS_ME, "\033[m"}, /* normal mode */
+ {(int)KS_MR, "\033[7m"}, /* reverse */
+ {(int)KS_MD, "\033[1m"}, /* bold */
+ {(int)KS_SO, "\033[31m"}, /* standout mode: red */
+ {(int)KS_SE, "\033[m"}, /* standout end */
+ {(int)KS_CZH, "\033[35m"}, /* italic: purple */
+ {(int)KS_CZR, "\033[m"}, /* italic end */
+ {(int)KS_US, "\033[4m"}, /* underscore mode */
+ {(int)KS_UE, "\033[m"}, /* underscore end */
+ {(int)KS_CCO, "8"}, /* allow 8 colors */
+# ifdef TERMINFO
+ {(int)KS_CAB, "\033[4%p1%dm"}, /* set background color */
+ {(int)KS_CAF, "\033[3%p1%dm"}, /* set foreground color */
+# else
+ {(int)KS_CAB, "\033[4%dm"}, /* set background color */
+ {(int)KS_CAF, "\033[3%dm"}, /* set foreground color */
+# endif
+ {(int)KS_OP, "\033[m"}, /* reset colors */
+ {(int)KS_MS, "y"}, /* safe to move cur in reverse mode */
+ {(int)KS_UT, "y"}, /* guessed */
+ {(int)KS_LE, "\b"},
+# ifdef TERMINFO
+ {(int)KS_CM, "\033[%i%p1%d;%p2%dH"},
+# else
+ {(int)KS_CM, "\033[%i%d;%dH"},
+# endif
+ {(int)KS_SR, "\033M"},
+# ifdef TERMINFO
+ {(int)KS_CRI, "\033[%p1%dC"},
+# else
+ {(int)KS_CRI, "\033[%dC"},
+# endif
+#if defined(BEOS_DR8)
+ {(int)KS_DB, ""}, /* hack! see screen.c */
+#endif
+
+ {K_UP, "\033[A"},
+ {K_DOWN, "\033[B"},
+ {K_LEFT, "\033[D"},
+ {K_RIGHT, "\033[C"},
+# endif
+
+# if defined(UNIX) || defined(ALL_BUILTIN_TCAPS) || \
+ defined(SOME_BUILTIN_TCAPS) || defined(__EMX__)
+ /*
+ * standard ANSI terminal, default for unix
+ */
+ {(int)KS_NAME, "ansi"},
+ {(int)KS_CE, IF_EB("\033[K", ESC_STR "[K")},
+ {(int)KS_AL, IF_EB("\033[L", ESC_STR "[L")},
+# ifdef TERMINFO
+ {(int)KS_CAL, IF_EB("\033[%p1%dL", ESC_STR "[%p1%dL")},
+# else
+ {(int)KS_CAL, IF_EB("\033[%dL", ESC_STR "[%dL")},
+# endif
+ {(int)KS_DL, IF_EB("\033[M", ESC_STR "[M")},
+# ifdef TERMINFO
+ {(int)KS_CDL, IF_EB("\033[%p1%dM", ESC_STR "[%p1%dM")},
+# else
+ {(int)KS_CDL, IF_EB("\033[%dM", ESC_STR "[%dM")},
+# endif
+ {(int)KS_CL, IF_EB("\033[H\033[2J", ESC_STR "[H" ESC_STR_nc "[2J")},
+ {(int)KS_ME, IF_EB("\033[0m", ESC_STR "[0m")},
+ {(int)KS_MR, IF_EB("\033[7m", ESC_STR "[7m")},
+ {(int)KS_MS, "y"},
+ {(int)KS_UT, "y"}, /* guessed */
+ {(int)KS_LE, "\b"},
+# ifdef TERMINFO
+ {(int)KS_CM, IF_EB("\033[%i%p1%d;%p2%dH", ESC_STR "[%i%p1%d;%p2%dH")},
+# else
+ {(int)KS_CM, IF_EB("\033[%i%d;%dH", ESC_STR "[%i%d;%dH")},
+# endif
+# ifdef TERMINFO
+ {(int)KS_CRI, IF_EB("\033[%p1%dC", ESC_STR "[%p1%dC")},
+# else
+ {(int)KS_CRI, IF_EB("\033[%dC", ESC_STR "[%dC")},
+# endif
+# endif
+
+# if defined(MSDOS) || defined(ALL_BUILTIN_TCAPS) || defined(__EMX__)
+ /*
+ * These codes are valid when nansi.sys or equivalent has been installed.
+ * Function keys on a PC are preceded with a NUL. These are converted into
+ * K_NUL '\316' in mch_inchar(), because we cannot handle NULs in key codes.
+ * CTRL-arrow is used instead of SHIFT-arrow.
+ */
+ {(int)KS_NAME, "pcansi"},
+ {(int)KS_DL, "\033[M"},
+ {(int)KS_AL, "\033[L"},
+ {(int)KS_CE, "\033[K"},
+ {(int)KS_CL, "\033[2J"},
+ {(int)KS_ME, "\033[0m"},
+ {(int)KS_MR, "\033[5m"}, /* reverse: black on lightgrey */
+ {(int)KS_MD, "\033[1m"}, /* bold: white text */
+ {(int)KS_SE, "\033[0m"}, /* standout end */
+ {(int)KS_SO, "\033[31m"}, /* standout: white on blue */
+ {(int)KS_CZH, "\033[34;43m"}, /* italic mode: blue text on yellow */
+ {(int)KS_CZR, "\033[0m"}, /* italic mode end */
+ {(int)KS_US, "\033[36;41m"}, /* underscore mode: cyan text on red */
+ {(int)KS_UE, "\033[0m"}, /* underscore mode end */
+ {(int)KS_CCO, "8"}, /* allow 8 colors */
+# ifdef TERMINFO
+ {(int)KS_CAB, "\033[4%p1%dm"}, /* set background color */
+ {(int)KS_CAF, "\033[3%p1%dm"}, /* set foreground color */
+# else
+ {(int)KS_CAB, "\033[4%dm"}, /* set background color */
+ {(int)KS_CAF, "\033[3%dm"}, /* set foreground color */
+# endif
+ {(int)KS_OP, "\033[0m"}, /* reset colors */
+ {(int)KS_MS, "y"},
+ {(int)KS_UT, "y"}, /* guessed */
+ {(int)KS_LE, "\b"},
+# ifdef TERMINFO
+ {(int)KS_CM, "\033[%i%p1%d;%p2%dH"},
+# else
+ {(int)KS_CM, "\033[%i%d;%dH"},
+# endif
+# ifdef TERMINFO
+ {(int)KS_CRI, "\033[%p1%dC"},
+# else
+ {(int)KS_CRI, "\033[%dC"},
+# endif
+ {K_UP, "\316H"},
+ {K_DOWN, "\316P"},
+ {K_LEFT, "\316K"},
+ {K_RIGHT, "\316M"},
+ {K_S_LEFT, "\316s"},
+ {K_S_RIGHT, "\316t"},
+ {K_F1, "\316;"},
+ {K_F2, "\316<"},
+ {K_F3, "\316="},
+ {K_F4, "\316>"},
+ {K_F5, "\316?"},
+ {K_F6, "\316@"},
+ {K_F7, "\316A"},
+ {K_F8, "\316B"},
+ {K_F9, "\316C"},
+ {K_F10, "\316D"},
+ {K_F11, "\316\205"}, /* guessed */
+ {K_F12, "\316\206"}, /* guessed */
+ {K_S_F1, "\316T"},
+ {K_S_F2, "\316U"},
+ {K_S_F3, "\316V"},
+ {K_S_F4, "\316W"},
+ {K_S_F5, "\316X"},
+ {K_S_F6, "\316Y"},
+ {K_S_F7, "\316Z"},
+ {K_S_F8, "\316["},
+ {K_S_F9, "\316\\"},
+ {K_S_F10, "\316]"},
+ {K_S_F11, "\316\207"}, /* guessed */
+ {K_S_F12, "\316\210"}, /* guessed */
+ {K_INS, "\316R"},
+ {K_DEL, "\316S"},
+ {K_HOME, "\316G"},
+ {K_END, "\316O"},
+ {K_PAGEDOWN, "\316Q"},
+ {K_PAGEUP, "\316I"},
+# endif
+
+
+# if defined(WIN3264) || defined(ALL_BUILTIN_TCAPS) || defined(__EMX__)
+ /*
+ * These codes are valid for the Win32 Console . The entries that start with
+ * ESC | are translated into console calls in os_win32.c. The function keys
+ * are also translated in os_win32.c.
+ */
+ {(int)KS_NAME, "win32"},
+ {(int)KS_CE, "\033|K"}, /* clear to end of line */
+ {(int)KS_AL, "\033|L"}, /* add new blank line */
+# ifdef TERMINFO
+ {(int)KS_CAL, "\033|%p1%dL"}, /* add number of new blank lines */
+# else
+ {(int)KS_CAL, "\033|%dL"}, /* add number of new blank lines */
+# endif
+ {(int)KS_DL, "\033|M"}, /* delete line */
+# ifdef TERMINFO
+ {(int)KS_CDL, "\033|%p1%dM"}, /* delete number of lines */
+# else
+ {(int)KS_CDL, "\033|%dM"}, /* delete number of lines */
+# endif
+ {(int)KS_CL, "\033|J"}, /* clear screen */
+ {(int)KS_CD, "\033|j"}, /* clear to end of display */
+ {(int)KS_VI, "\033|v"}, /* cursor invisible */
+ {(int)KS_VE, "\033|V"}, /* cursor visible */
+
+ {(int)KS_ME, "\033|0m"}, /* normal */
+ {(int)KS_MR, "\033|112m"}, /* reverse: black on lightgray */
+ {(int)KS_MD, "\033|15m"}, /* bold: white on black */
+ {(int)KS_SO, "\033|31m"}, /* standout: white on blue */
+ {(int)KS_SE, "\033|0m"}, /* standout end */
+ {(int)KS_CZH, "\033|225m"}, /* italic: blue text on yellow */
+ {(int)KS_CZR, "\033|0m"}, /* italic end */
+ {(int)KS_US, "\033|67m"}, /* underscore: cyan text on red */
+ {(int)KS_UE, "\033|0m"}, /* underscore end */
+ {(int)KS_CCO, "16"}, /* allow 16 colors */
+# ifdef TERMINFO
+ {(int)KS_CAB, "\033|%p1%db"}, /* set background color */
+ {(int)KS_CAF, "\033|%p1%df"}, /* set foreground color */
+# else
+ {(int)KS_CAB, "\033|%db"}, /* set background color */
+ {(int)KS_CAF, "\033|%df"}, /* set foreground color */
+# endif
+
+ {(int)KS_MS, "y"}, /* save to move cur in reverse mode */
+ {(int)KS_UT, "y"},
+ {(int)KS_LE, "\b"},
+# ifdef TERMINFO
+ {(int)KS_CM, "\033|%i%p1%d;%p2%dH"}, /* cursor motion */
+# else
+ {(int)KS_CM, "\033|%i%d;%dH"}, /* cursor motion */
+# endif
+ {(int)KS_VB, "\033|B"}, /* visual bell */
+ {(int)KS_TI, "\033|S"}, /* put terminal in termcap mode */
+ {(int)KS_TE, "\033|E"}, /* out of termcap mode */
+# ifdef TERMINFO
+ {(int)KS_CS, "\033|%i%p1%d;%p2%dr"}, /* scroll region */
+# else
+ {(int)KS_CS, "\033|%i%d;%dr"}, /* scroll region */
+# endif
+
+ {K_UP, "\316H"},
+ {K_DOWN, "\316P"},
+ {K_LEFT, "\316K"},
+ {K_RIGHT, "\316M"},
+ {K_S_UP, "\316\304"},
+ {K_S_DOWN, "\316\317"},
+ {K_S_LEFT, "\316\311"},
+ {K_C_LEFT, "\316s"},
+ {K_S_RIGHT, "\316\313"},
+ {K_C_RIGHT, "\316t"},
+ {K_S_TAB, "\316\017"},
+ {K_F1, "\316;"},
+ {K_F2, "\316<"},
+ {K_F3, "\316="},
+ {K_F4, "\316>"},
+ {K_F5, "\316?"},
+ {K_F6, "\316@"},
+ {K_F7, "\316A"},
+ {K_F8, "\316B"},
+ {K_F9, "\316C"},
+ {K_F10, "\316D"},
+ {K_F11, "\316\205"},
+ {K_F12, "\316\206"},
+ {K_S_F1, "\316T"},
+ {K_S_F2, "\316U"},
+ {K_S_F3, "\316V"},
+ {K_S_F4, "\316W"},
+ {K_S_F5, "\316X"},
+ {K_S_F6, "\316Y"},
+ {K_S_F7, "\316Z"},
+ {K_S_F8, "\316["},
+ {K_S_F9, "\316\\"},
+ {K_S_F10, "\316]"},
+ {K_S_F11, "\316\207"},
+ {K_S_F12, "\316\210"},
+ {K_INS, "\316R"},
+ {K_DEL, "\316S"},
+ {K_HOME, "\316G"},
+ {K_S_HOME, "\316\302"},
+ {K_C_HOME, "\316w"},
+ {K_END, "\316O"},
+ {K_S_END, "\316\315"},
+ {K_C_END, "\316u"},
+ {K_PAGEDOWN, "\316Q"},
+ {K_PAGEUP, "\316I"},
+ {K_KPLUS, "\316N"},
+ {K_KMINUS, "\316J"},
+ {K_KMULTIPLY, "\316\067"},
+ {K_K0, "\316\332"},
+ {K_K1, "\316\336"},
+ {K_K2, "\316\342"},
+ {K_K3, "\316\346"},
+ {K_K4, "\316\352"},
+ {K_K5, "\316\356"},
+ {K_K6, "\316\362"},
+ {K_K7, "\316\366"},
+ {K_K8, "\316\372"},
+ {K_K9, "\316\376"},
+# endif
+
+# if defined(VMS) || defined(ALL_BUILTIN_TCAPS)
+ /*
+ * VT320 is working as an ANSI terminal compatible DEC terminal.
+ * (it covers VT1x0, VT2x0 and VT3x0 up to VT320 on VMS as well)
+ * Note: K_F1...K_F5 are for internal use, should not be defined.
+ * TODO:- rewrite ESC[ codes to CSI
+ * - keyboard languages (CSI ? 26 n)
+ */
+ {(int)KS_NAME, "vt320"},
+ {(int)KS_CE, IF_EB("\033[K", ESC_STR "[K")},
+ {(int)KS_AL, IF_EB("\033[L", ESC_STR "[L")},
+# ifdef TERMINFO
+ {(int)KS_CAL, IF_EB("\033[%p1%dL", ESC_STR "[%p1%dL")},
+# else
+ {(int)KS_CAL, IF_EB("\033[%dL", ESC_STR "[%dL")},
+# endif
+ {(int)KS_DL, IF_EB("\033[M", ESC_STR "[M")},
+# ifdef TERMINFO
+ {(int)KS_CDL, IF_EB("\033[%p1%dM", ESC_STR "[%p1%dM")},
+# else
+ {(int)KS_CDL, IF_EB("\033[%dM", ESC_STR "[%dM")},
+# endif
+ {(int)KS_CL, IF_EB("\033[H\033[2J", ESC_STR "[H" ESC_STR_nc "[2J")},
+ {(int)KS_CD, IF_EB("\033[J", ESC_STR "[J")},
+ {(int)KS_CCO, "8"}, /* allow 8 colors */
+ {(int)KS_ME, IF_EB("\033[0m", ESC_STR "[0m")},
+ {(int)KS_MR, IF_EB("\033[7m", ESC_STR "[7m")},
+ {(int)KS_MD, IF_EB("\033[1m", ESC_STR "[1m")}, /* bold mode */
+ {(int)KS_SE, IF_EB("\033[22m", ESC_STR "[22m")}, /* normal mode */
+ {(int)KS_UE, IF_EB("\033[24m", ESC_STR "[24m")}, /* exit underscore mode */
+ {(int)KS_US, IF_EB("\033[4m", ESC_STR "[4m")}, /* underscore mode */
+ {(int)KS_CZH, IF_EB("\033[34;43m", ESC_STR "[34;43m")}, /* italic mode: blue text on yellow */
+ {(int)KS_CZR, IF_EB("\033[0m", ESC_STR "[0m")}, /* italic mode end */
+ {(int)KS_CAB, IF_EB("\033[4%dm", ESC_STR "[4%dm")}, /* set background color (ANSI) */
+ {(int)KS_CAF, IF_EB("\033[3%dm", ESC_STR "[3%dm")}, /* set foreground color (ANSI) */
+ {(int)KS_CSB, IF_EB("\033[102;%dm", ESC_STR "[102;%dm")}, /* set screen background color */
+ {(int)KS_CSF, IF_EB("\033[101;%dm", ESC_STR "[101;%dm")}, /* set screen foreground color */
+ {(int)KS_MS, "y"},
+ {(int)KS_UT, "y"},
+ {(int)KS_LE, "\b"},
+# ifdef TERMINFO
+ {(int)KS_CM, IF_EB("\033[%i%p1%d;%p2%dH",
+ ESC_STR "[%i%p1%d;%p2%dH")},
+# else
+ {(int)KS_CM, IF_EB("\033[%i%d;%dH", ESC_STR "[%i%d;%dH")},
+# endif
+# ifdef TERMINFO
+ {(int)KS_CRI, IF_EB("\033[%p1%dC", ESC_STR "[%p1%dC")},
+# else
+ {(int)KS_CRI, IF_EB("\033[%dC", ESC_STR "[%dC")},
+# endif
+ {K_UP, IF_EB("\033[A", ESC_STR "[A")},
+ {K_DOWN, IF_EB("\033[B", ESC_STR "[B")},
+ {K_RIGHT, IF_EB("\033[C", ESC_STR "[C")},
+ {K_LEFT, IF_EB("\033[D", ESC_STR "[D")},
+ {K_F1, IF_EB("\033[11~", ESC_STR "[11~")},
+ {K_F2, IF_EB("\033[12~", ESC_STR "[12~")},
+ {K_F3, IF_EB("\033[13~", ESC_STR "[13~")},
+ {K_F4, IF_EB("\033[14~", ESC_STR "[14~")},
+ {K_F5, IF_EB("\033[15~", ESC_STR "[15~")},
+ {K_F6, IF_EB("\033[17~", ESC_STR "[17~")},
+ {K_F7, IF_EB("\033[18~", ESC_STR "[18~")},
+ {K_F8, IF_EB("\033[19~", ESC_STR "[19~")},
+ {K_F9, IF_EB("\033[20~", ESC_STR "[20~")},
+ {K_F10, IF_EB("\033[21~", ESC_STR "[21~")},
+ {K_F11, IF_EB("\033[23~", ESC_STR "[23~")},
+ {K_F12, IF_EB("\033[24~", ESC_STR "[24~")},
+ {K_F13, IF_EB("\033[25~", ESC_STR "[25~")},
+ {K_F14, IF_EB("\033[26~", ESC_STR "[26~")},
+ {K_F15, IF_EB("\033[28~", ESC_STR "[28~")}, /* Help */
+ {K_F16, IF_EB("\033[29~", ESC_STR "[29~")}, /* Select */
+ {K_F17, IF_EB("\033[31~", ESC_STR "[31~")},
+ {K_F18, IF_EB("\033[32~", ESC_STR "[32~")},
+ {K_F19, IF_EB("\033[33~", ESC_STR "[33~")},
+ {K_F20, IF_EB("\033[34~", ESC_STR "[34~")},
+ {K_INS, IF_EB("\033[2~", ESC_STR "[2~")},
+ {K_DEL, IF_EB("\033[3~", ESC_STR "[3~")},
+ {K_HOME, IF_EB("\033[1~", ESC_STR "[1~")},
+ {K_END, IF_EB("\033[4~", ESC_STR "[4~")},
+ {K_PAGEUP, IF_EB("\033[5~", ESC_STR "[5~")},
+ {K_PAGEDOWN, IF_EB("\033[6~", ESC_STR "[6~")},
+ {K_KPLUS, IF_EB("\033Ok", ESC_STR "Ok")}, /* keypad plus */
+ {K_KMINUS, IF_EB("\033Om", ESC_STR "Om")}, /* keypad minus */
+ {K_KDIVIDE, IF_EB("\033Oo", ESC_STR "Oo")}, /* keypad / */
+ {K_KMULTIPLY, IF_EB("\033Oj", ESC_STR "Oj")}, /* keypad * */
+ {K_KENTER, IF_EB("\033OM", ESC_STR "OM")}, /* keypad Enter */
+ {K_BS, "\x7f"}, /* for some reason 0177 doesn't work */
+# endif
+
+# if defined(ALL_BUILTIN_TCAPS) || defined(__MINT__)
+ /*
+ * Ordinary vt52
+ */
+ {(int)KS_NAME, "vt52"},
+ {(int)KS_CE, IF_EB("\033K", ESC_STR "K")},
+ {(int)KS_CD, IF_EB("\033J", ESC_STR "J")},
+ {(int)KS_CM, IF_EB("\033Y%+ %+ ", ESC_STR "Y%+ %+ ")},
+ {(int)KS_LE, "\b"},
+ {(int)KS_AL, IF_EB("\033T", ESC_STR "T")},
+ {(int)KS_DL, IF_EB("\033U", ESC_STR "U")},
+ {(int)KS_CL, IF_EB("\033H\033J", ESC_STR "H" ESC_STR_nc "J")},
+ {(int)KS_ME, IF_EB("\033SO", ESC_STR "SO")},
+ {(int)KS_MR, IF_EB("\033S2", ESC_STR "S2")},
+ {(int)KS_MS, "y"},
+# endif
+
+# if defined(UNIX) || defined(ALL_BUILTIN_TCAPS) || \
+ defined(SOME_BUILTIN_TCAPS) || defined(__EMX__)
+ {(int)KS_NAME, "xterm"},
+ {(int)KS_CE, IF_EB("\033[K", ESC_STR "[K")},
+ {(int)KS_AL, IF_EB("\033[L", ESC_STR "[L")},
+# ifdef TERMINFO
+ {(int)KS_CAL, IF_EB("\033[%p1%dL", ESC_STR "[%p1%dL")},
+# else
+ {(int)KS_CAL, IF_EB("\033[%dL", ESC_STR "[%dL")},
+# endif
+ {(int)KS_DL, IF_EB("\033[M", ESC_STR "[M")},
+# ifdef TERMINFO
+ {(int)KS_CDL, IF_EB("\033[%p1%dM", ESC_STR "[%p1%dM")},
+# else
+ {(int)KS_CDL, IF_EB("\033[%dM", ESC_STR "[%dM")},
+# endif
+# ifdef TERMINFO
+ {(int)KS_CS, IF_EB("\033[%i%p1%d;%p2%dr",
+ ESC_STR "[%i%p1%d;%p2%dr")},
+# else
+ {(int)KS_CS, IF_EB("\033[%i%d;%dr", ESC_STR "[%i%d;%dr")},
+# endif
+ {(int)KS_CL, IF_EB("\033[H\033[2J", ESC_STR "[H" ESC_STR_nc "[2J")},
+ {(int)KS_CD, IF_EB("\033[J", ESC_STR "[J")},
+ {(int)KS_ME, IF_EB("\033[m", ESC_STR "[m")},
+ {(int)KS_MR, IF_EB("\033[7m", ESC_STR "[7m")},
+ {(int)KS_MD, IF_EB("\033[1m", ESC_STR "[1m")},
+ {(int)KS_UE, IF_EB("\033[m", ESC_STR "[m")},
+ {(int)KS_US, IF_EB("\033[4m", ESC_STR "[4m")},
+ {(int)KS_MS, "y"},
+ {(int)KS_UT, "y"},
+ {(int)KS_LE, "\b"},
+# ifdef TERMINFO
+ {(int)KS_CM, IF_EB("\033[%i%p1%d;%p2%dH",
+ ESC_STR "[%i%p1%d;%p2%dH")},
+# else
+ {(int)KS_CM, IF_EB("\033[%i%d;%dH", ESC_STR "[%i%d;%dH")},
+# endif
+ {(int)KS_SR, IF_EB("\033M", ESC_STR "M")},
+# ifdef TERMINFO
+ {(int)KS_CRI, IF_EB("\033[%p1%dC", ESC_STR "[%p1%dC")},
+# else
+ {(int)KS_CRI, IF_EB("\033[%dC", ESC_STR "[%dC")},
+# endif
+ {(int)KS_KS, IF_EB("\033[?1h\033=", ESC_STR "[?1h" ESC_STR_nc "=")},
+ {(int)KS_KE, IF_EB("\033[?1l\033>", ESC_STR "[?1l" ESC_STR_nc ">")},
+# ifdef FEAT_XTERM_SAVE
+ {(int)KS_TI, IF_EB("\0337\033[?47h", ESC_STR "7" ESC_STR_nc "[?47h")},
+ {(int)KS_TE, IF_EB("\033[2J\033[?47l\0338",
+ ESC_STR "[2J" ESC_STR_nc "[?47l" ESC_STR_nc "8")},
+# endif
+ {(int)KS_CIS, IF_EB("\033]1;", ESC_STR "]1;")},
+ {(int)KS_CIE, "\007"},
+ {(int)KS_TS, IF_EB("\033]2;", ESC_STR "]2;")},
+ {(int)KS_FS, "\007"},
+# ifdef TERMINFO
+ {(int)KS_CWS, IF_EB("\033[8;%p1%d;%p2%dt",
+ ESC_STR "[8;%p1%d;%p2%dt")},
+ {(int)KS_CWP, IF_EB("\033[3;%p1%d;%p2%dt",
+ ESC_STR "[3;%p1%d;%p2%dt")},
+# else
+ {(int)KS_CWS, IF_EB("\033[8;%d;%dt", ESC_STR "[8;%d;%dt")},
+ {(int)KS_CWP, IF_EB("\033[3;%d;%dt", ESC_STR "[3;%d;%dt")},
+# endif
+ {(int)KS_CRV, IF_EB("\033[>c", ESC_STR "[>c")},
+ {(int)KS_U7, IF_EB("\033[6n", ESC_STR "[6n")},
+
+ {K_UP, IF_EB("\033O*A", ESC_STR "O*A")},
+ {K_DOWN, IF_EB("\033O*B", ESC_STR "O*B")},
+ {K_RIGHT, IF_EB("\033O*C", ESC_STR "O*C")},
+ {K_LEFT, IF_EB("\033O*D", ESC_STR "O*D")},
+ /* An extra set of cursor keys for vt100 mode */
+ {K_XUP, IF_EB("\033[1;*A", ESC_STR "[1;*A")},
+ {K_XDOWN, IF_EB("\033[1;*B", ESC_STR "[1;*B")},
+ {K_XRIGHT, IF_EB("\033[1;*C", ESC_STR "[1;*C")},
+ {K_XLEFT, IF_EB("\033[1;*D", ESC_STR "[1;*D")},
+ /* An extra set of function keys for vt100 mode */
+ {K_XF1, IF_EB("\033O*P", ESC_STR "O*P")},
+ {K_XF2, IF_EB("\033O*Q", ESC_STR "O*Q")},
+ {K_XF3, IF_EB("\033O*R", ESC_STR "O*R")},
+ {K_XF4, IF_EB("\033O*S", ESC_STR "O*S")},
+ {K_F1, IF_EB("\033[11;*~", ESC_STR "[11;*~")},
+ {K_F2, IF_EB("\033[12;*~", ESC_STR "[12;*~")},
+ {K_F3, IF_EB("\033[13;*~", ESC_STR "[13;*~")},
+ {K_F4, IF_EB("\033[14;*~", ESC_STR "[14;*~")},
+ {K_F5, IF_EB("\033[15;*~", ESC_STR "[15;*~")},
+ {K_F6, IF_EB("\033[17;*~", ESC_STR "[17;*~")},
+ {K_F7, IF_EB("\033[18;*~", ESC_STR "[18;*~")},
+ {K_F8, IF_EB("\033[19;*~", ESC_STR "[19;*~")},
+ {K_F9, IF_EB("\033[20;*~", ESC_STR "[20;*~")},
+ {K_F10, IF_EB("\033[21;*~", ESC_STR "[21;*~")},
+ {K_F11, IF_EB("\033[23;*~", ESC_STR "[23;*~")},
+ {K_F12, IF_EB("\033[24;*~", ESC_STR "[24;*~")},
+ {K_S_TAB, IF_EB("\033[Z", ESC_STR "[Z")},
+ {K_HELP, IF_EB("\033[28;*~", ESC_STR "[28;*~")},
+ {K_UNDO, IF_EB("\033[26;*~", ESC_STR "[26;*~")},
+ {K_INS, IF_EB("\033[2;*~", ESC_STR "[2;*~")},
+ {K_HOME, IF_EB("\033[1;*H", ESC_STR "[1;*H")},
+ /* {K_S_HOME, IF_EB("\033O2H", ESC_STR "O2H")}, */
+ /* {K_C_HOME, IF_EB("\033O5H", ESC_STR "O5H")}, */
+ {K_KHOME, IF_EB("\033[1;*~", ESC_STR "[1;*~")},
+ {K_XHOME, IF_EB("\033O*H", ESC_STR "O*H")}, /* other Home */
+ {K_ZHOME, IF_EB("\033[7;*~", ESC_STR "[7;*~")}, /* other Home */
+ {K_END, IF_EB("\033[1;*F", ESC_STR "[1;*F")},
+ /* {K_S_END, IF_EB("\033O2F", ESC_STR "O2F")}, */
+ /* {K_C_END, IF_EB("\033O5F", ESC_STR "O5F")}, */
+ {K_KEND, IF_EB("\033[4;*~", ESC_STR "[4;*~")},
+ {K_XEND, IF_EB("\033O*F", ESC_STR "O*F")}, /* other End */
+ {K_ZEND, IF_EB("\033[8;*~", ESC_STR "[8;*~")},
+ {K_PAGEUP, IF_EB("\033[5;*~", ESC_STR "[5;*~")},
+ {K_PAGEDOWN, IF_EB("\033[6;*~", ESC_STR "[6;*~")},
+ {K_KPLUS, IF_EB("\033O*k", ESC_STR "O*k")}, /* keypad plus */
+ {K_KMINUS, IF_EB("\033O*m", ESC_STR "O*m")}, /* keypad minus */
+ {K_KDIVIDE, IF_EB("\033O*o", ESC_STR "O*o")}, /* keypad / */
+ {K_KMULTIPLY, IF_EB("\033O*j", ESC_STR "O*j")}, /* keypad * */
+ {K_KENTER, IF_EB("\033O*M", ESC_STR "O*M")}, /* keypad Enter */
+ {K_KPOINT, IF_EB("\033O*n", ESC_STR "O*n")}, /* keypad . */
+ {K_KDEL, IF_EB("\033[3;*~", ESC_STR "[3;*~")}, /* keypad Del */
+
+ {BT_EXTRA_KEYS, ""},
+ {TERMCAP2KEY('k', '0'), IF_EB("\033[10;*~", ESC_STR "[10;*~")}, /* F0 */
+ {TERMCAP2KEY('F', '3'), IF_EB("\033[25;*~", ESC_STR "[25;*~")}, /* F13 */
+ /* F14 and F15 are missing, because they send the same codes as the undo
+ * and help key, although they don't work on all keyboards. */
+ {TERMCAP2KEY('F', '6'), IF_EB("\033[29;*~", ESC_STR "[29;*~")}, /* F16 */
+ {TERMCAP2KEY('F', '7'), IF_EB("\033[31;*~", ESC_STR "[31;*~")}, /* F17 */
+ {TERMCAP2KEY('F', '8'), IF_EB("\033[32;*~", ESC_STR "[32;*~")}, /* F18 */
+ {TERMCAP2KEY('F', '9'), IF_EB("\033[33;*~", ESC_STR "[33;*~")}, /* F19 */
+ {TERMCAP2KEY('F', 'A'), IF_EB("\033[34;*~", ESC_STR "[34;*~")}, /* F20 */
+
+ {TERMCAP2KEY('F', 'B'), IF_EB("\033[42;*~", ESC_STR "[42;*~")}, /* F21 */
+ {TERMCAP2KEY('F', 'C'), IF_EB("\033[43;*~", ESC_STR "[43;*~")}, /* F22 */
+ {TERMCAP2KEY('F', 'D'), IF_EB("\033[44;*~", ESC_STR "[44;*~")}, /* F23 */
+ {TERMCAP2KEY('F', 'E'), IF_EB("\033[45;*~", ESC_STR "[45;*~")}, /* F24 */
+ {TERMCAP2KEY('F', 'F'), IF_EB("\033[46;*~", ESC_STR "[46;*~")}, /* F25 */
+ {TERMCAP2KEY('F', 'G'), IF_EB("\033[47;*~", ESC_STR "[47;*~")}, /* F26 */
+ {TERMCAP2KEY('F', 'H'), IF_EB("\033[48;*~", ESC_STR "[48;*~")}, /* F27 */
+ {TERMCAP2KEY('F', 'I'), IF_EB("\033[49;*~", ESC_STR "[49;*~")}, /* F28 */
+ {TERMCAP2KEY('F', 'J'), IF_EB("\033[50;*~", ESC_STR "[50;*~")}, /* F29 */
+ {TERMCAP2KEY('F', 'K'), IF_EB("\033[51;*~", ESC_STR "[51;*~")}, /* F30 */
+
+ {TERMCAP2KEY('F', 'L'), IF_EB("\033[52;*~", ESC_STR "[52;*~")}, /* F31 */
+ {TERMCAP2KEY('F', 'M'), IF_EB("\033[53;*~", ESC_STR "[53;*~")}, /* F32 */
+ {TERMCAP2KEY('F', 'N'), IF_EB("\033[54;*~", ESC_STR "[54;*~")}, /* F33 */
+ {TERMCAP2KEY('F', 'O'), IF_EB("\033[55;*~", ESC_STR "[55;*~")}, /* F34 */
+ {TERMCAP2KEY('F', 'P'), IF_EB("\033[56;*~", ESC_STR "[56;*~")}, /* F35 */
+ {TERMCAP2KEY('F', 'Q'), IF_EB("\033[57;*~", ESC_STR "[57;*~")}, /* F36 */
+ {TERMCAP2KEY('F', 'R'), IF_EB("\033[58;*~", ESC_STR "[58;*~")}, /* F37 */
+# endif
+
+# if defined(UNIX) || defined(ALL_BUILTIN_TCAPS)
+ /*
+ * iris-ansi for Silicon Graphics machines.
+ */
+ {(int)KS_NAME, "iris-ansi"},
+ {(int)KS_CE, "\033[K"},
+ {(int)KS_CD, "\033[J"},
+ {(int)KS_AL, "\033[L"},
+# ifdef TERMINFO
+ {(int)KS_CAL, "\033[%p1%dL"},
+# else
+ {(int)KS_CAL, "\033[%dL"},
+# endif
+ {(int)KS_DL, "\033[M"},
+# ifdef TERMINFO
+ {(int)KS_CDL, "\033[%p1%dM"},
+# else
+ {(int)KS_CDL, "\033[%dM"},
+# endif
+ {(int)KS_CL, "\033[H\033[2J"},
+ {(int)KS_VE, "\033[9/y\033[12/y"}, /* These aren't documented */
+ {(int)KS_VS, "\033[10/y\033[=1h\033[=2l"}, /* These aren't documented */
+ {(int)KS_TI, "\033[=6h"},
+ {(int)KS_TE, "\033[=6l"},
+ {(int)KS_SE, "\033[21;27m"},
+ {(int)KS_SO, "\033[1;7m"},
+ {(int)KS_ME, "\033[m"},
+ {(int)KS_MR, "\033[7m"},
+ {(int)KS_MD, "\033[1m"},
+ {(int)KS_CCO, "8"}, /* allow 8 colors */
+ {(int)KS_CZH, "\033[3m"}, /* italic mode on */
+ {(int)KS_CZR, "\033[23m"}, /* italic mode off */
+ {(int)KS_US, "\033[4m"}, /* underline on */
+ {(int)KS_UE, "\033[24m"}, /* underline off */
+# ifdef TERMINFO
+ {(int)KS_CAB, "\033[4%p1%dm"}, /* set background color (ANSI) */
+ {(int)KS_CAF, "\033[3%p1%dm"}, /* set foreground color (ANSI) */
+ {(int)KS_CSB, "\033[102;%p1%dm"}, /* set screen background color */
+ {(int)KS_CSF, "\033[101;%p1%dm"}, /* set screen foreground color */
+# else
+ {(int)KS_CAB, "\033[4%dm"}, /* set background color (ANSI) */
+ {(int)KS_CAF, "\033[3%dm"}, /* set foreground color (ANSI) */
+ {(int)KS_CSB, "\033[102;%dm"}, /* set screen background color */
+ {(int)KS_CSF, "\033[101;%dm"}, /* set screen foreground color */
+# endif
+ {(int)KS_MS, "y"}, /* guessed */
+ {(int)KS_UT, "y"}, /* guessed */
+ {(int)KS_LE, "\b"},
+# ifdef TERMINFO
+ {(int)KS_CM, "\033[%i%p1%d;%p2%dH"},
+# else
+ {(int)KS_CM, "\033[%i%d;%dH"},
+# endif
+ {(int)KS_SR, "\033M"},
+# ifdef TERMINFO
+ {(int)KS_CRI, "\033[%p1%dC"},
+# else
+ {(int)KS_CRI, "\033[%dC"},
+# endif
+ {(int)KS_CIS, "\033P3.y"},
+ {(int)KS_CIE, "\234"}, /* ST "String Terminator" */
+ {(int)KS_TS, "\033P1.y"},
+ {(int)KS_FS, "\234"}, /* ST "String Terminator" */
+# ifdef TERMINFO
+ {(int)KS_CWS, "\033[203;%p1%d;%p2%d/y"},
+ {(int)KS_CWP, "\033[205;%p1%d;%p2%d/y"},
+# else
+ {(int)KS_CWS, "\033[203;%d;%d/y"},
+ {(int)KS_CWP, "\033[205;%d;%d/y"},
+# endif
+ {K_UP, "\033[A"},
+ {K_DOWN, "\033[B"},
+ {K_LEFT, "\033[D"},
+ {K_RIGHT, "\033[C"},
+ {K_S_UP, "\033[161q"},
+ {K_S_DOWN, "\033[164q"},
+ {K_S_LEFT, "\033[158q"},
+ {K_S_RIGHT, "\033[167q"},
+ {K_F1, "\033[001q"},
+ {K_F2, "\033[002q"},
+ {K_F3, "\033[003q"},
+ {K_F4, "\033[004q"},
+ {K_F5, "\033[005q"},
+ {K_F6, "\033[006q"},
+ {K_F7, "\033[007q"},
+ {K_F8, "\033[008q"},
+ {K_F9, "\033[009q"},
+ {K_F10, "\033[010q"},
+ {K_F11, "\033[011q"},
+ {K_F12, "\033[012q"},
+ {K_S_F1, "\033[013q"},
+ {K_S_F2, "\033[014q"},
+ {K_S_F3, "\033[015q"},
+ {K_S_F4, "\033[016q"},
+ {K_S_F5, "\033[017q"},
+ {K_S_F6, "\033[018q"},
+ {K_S_F7, "\033[019q"},
+ {K_S_F8, "\033[020q"},
+ {K_S_F9, "\033[021q"},
+ {K_S_F10, "\033[022q"},
+ {K_S_F11, "\033[023q"},
+ {K_S_F12, "\033[024q"},
+ {K_INS, "\033[139q"},
+ {K_HOME, "\033[H"},
+ {K_END, "\033[146q"},
+ {K_PAGEUP, "\033[150q"},
+ {K_PAGEDOWN, "\033[154q"},
+# endif
+
+# if defined(DEBUG) || defined(ALL_BUILTIN_TCAPS)
+ /*
+ * for debugging
+ */
+ {(int)KS_NAME, "debug"},
+ {(int)KS_CE, "[CE]"},
+ {(int)KS_CD, "[CD]"},
+ {(int)KS_AL, "[AL]"},
+# ifdef TERMINFO
+ {(int)KS_CAL, "[CAL%p1%d]"},
+# else
+ {(int)KS_CAL, "[CAL%d]"},
+# endif
+ {(int)KS_DL, "[DL]"},
+# ifdef TERMINFO
+ {(int)KS_CDL, "[CDL%p1%d]"},
+# else
+ {(int)KS_CDL, "[CDL%d]"},
+# endif
+# ifdef TERMINFO
+ {(int)KS_CS, "[%p1%dCS%p2%d]"},
+# else
+ {(int)KS_CS, "[%dCS%d]"},
+# endif
+# ifdef TERMINFO
+ {(int)KS_CSV, "[%p1%dCSV%p2%d]"},
+# else
+ {(int)KS_CSV, "[%dCSV%d]"},
+# endif
+# ifdef TERMINFO
+ {(int)KS_CAB, "[CAB%p1%d]"},
+ {(int)KS_CAF, "[CAF%p1%d]"},
+ {(int)KS_CSB, "[CSB%p1%d]"},
+ {(int)KS_CSF, "[CSF%p1%d]"},
+# else
+ {(int)KS_CAB, "[CAB%d]"},
+ {(int)KS_CAF, "[CAF%d]"},
+ {(int)KS_CSB, "[CSB%d]"},
+ {(int)KS_CSF, "[CSF%d]"},
+# endif
+ {(int)KS_OP, "[OP]"},
+ {(int)KS_LE, "[LE]"},
+ {(int)KS_CL, "[CL]"},
+ {(int)KS_VI, "[VI]"},
+ {(int)KS_VE, "[VE]"},
+ {(int)KS_VS, "[VS]"},
+ {(int)KS_ME, "[ME]"},
+ {(int)KS_MR, "[MR]"},
+ {(int)KS_MB, "[MB]"},
+ {(int)KS_MD, "[MD]"},
+ {(int)KS_SE, "[SE]"},
+ {(int)KS_SO, "[SO]"},
+ {(int)KS_UE, "[UE]"},
+ {(int)KS_US, "[US]"},
+ {(int)KS_UCE, "[UCE]"},
+ {(int)KS_UCS, "[UCS]"},
+ {(int)KS_MS, "[MS]"},
+ {(int)KS_UT, "[UT]"},
+# ifdef TERMINFO
+ {(int)KS_CM, "[%p1%dCM%p2%d]"},
+# else
+ {(int)KS_CM, "[%dCM%d]"},
+# endif
+ {(int)KS_SR, "[SR]"},
+# ifdef TERMINFO
+ {(int)KS_CRI, "[CRI%p1%d]"},
+# else
+ {(int)KS_CRI, "[CRI%d]"},
+# endif
+ {(int)KS_VB, "[VB]"},
+ {(int)KS_KS, "[KS]"},
+ {(int)KS_KE, "[KE]"},
+ {(int)KS_TI, "[TI]"},
+ {(int)KS_TE, "[TE]"},
+ {(int)KS_CIS, "[CIS]"},
+ {(int)KS_CIE, "[CIE]"},
+ {(int)KS_TS, "[TS]"},
+ {(int)KS_FS, "[FS]"},
+# ifdef TERMINFO
+ {(int)KS_CWS, "[%p1%dCWS%p2%d]"},
+ {(int)KS_CWP, "[%p1%dCWP%p2%d]"},
+# else
+ {(int)KS_CWS, "[%dCWS%d]"},
+ {(int)KS_CWP, "[%dCWP%d]"},
+# endif
+ {(int)KS_CRV, "[CRV]"},
+ {(int)KS_U7, "[U7]"},
+ {K_UP, "[KU]"},
+ {K_DOWN, "[KD]"},
+ {K_LEFT, "[KL]"},
+ {K_RIGHT, "[KR]"},
+ {K_XUP, "[xKU]"},
+ {K_XDOWN, "[xKD]"},
+ {K_XLEFT, "[xKL]"},
+ {K_XRIGHT, "[xKR]"},
+ {K_S_UP, "[S-KU]"},
+ {K_S_DOWN, "[S-KD]"},
+ {K_S_LEFT, "[S-KL]"},
+ {K_C_LEFT, "[C-KL]"},
+ {K_S_RIGHT, "[S-KR]"},
+ {K_C_RIGHT, "[C-KR]"},
+ {K_F1, "[F1]"},
+ {K_XF1, "[xF1]"},
+ {K_F2, "[F2]"},
+ {K_XF2, "[xF2]"},
+ {K_F3, "[F3]"},
+ {K_XF3, "[xF3]"},
+ {K_F4, "[F4]"},
+ {K_XF4, "[xF4]"},
+ {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_S_F1, "[S-F1]"},
+ {K_S_XF1, "[S-xF1]"},
+ {K_S_F2, "[S-F2]"},
+ {K_S_XF2, "[S-xF2]"},
+ {K_S_F3, "[S-F3]"},
+ {K_S_XF3, "[S-xF3]"},
+ {K_S_F4, "[S-F4]"},
+ {K_S_XF4, "[S-xF4]"},
+ {K_S_F5, "[S-F5]"},
+ {K_S_F6, "[S-F6]"},
+ {K_S_F7, "[S-F7]"},
+ {K_S_F8, "[S-F8]"},
+ {K_S_F9, "[S-F9]"},
+ {K_S_F10, "[S-F10]"},
+ {K_S_F11, "[S-F11]"},
+ {K_S_F12, "[S-F12]"},
+ {K_HELP, "[HELP]"},
+ {K_UNDO, "[UNDO]"},
+ {K_BS, "[BS]"},
+ {K_INS, "[INS]"},
+ {K_KINS, "[KINS]"},
+ {K_DEL, "[DEL]"},
+ {K_KDEL, "[KDEL]"},
+ {K_HOME, "[HOME]"},
+ {K_S_HOME, "[C-HOME]"},
+ {K_C_HOME, "[C-HOME]"},
+ {K_KHOME, "[KHOME]"},
+ {K_XHOME, "[XHOME]"},
+ {K_ZHOME, "[ZHOME]"},
+ {K_END, "[END]"},
+ {K_S_END, "[C-END]"},
+ {K_C_END, "[C-END]"},
+ {K_KEND, "[KEND]"},
+ {K_XEND, "[XEND]"},
+ {K_ZEND, "[ZEND]"},
+ {K_PAGEUP, "[PAGEUP]"},
+ {K_PAGEDOWN, "[PAGEDOWN]"},
+ {K_KPAGEUP, "[KPAGEUP]"},
+ {K_KPAGEDOWN, "[KPAGEDOWN]"},
+ {K_MOUSE, "[MOUSE]"},
+ {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]"},
+# endif
+
+#endif /* NO_BUILTIN_TCAPS */
+
+ /*
+ * The most minimal terminal: only clear screen and cursor positioning
+ * Always included.
+ */
+ {(int)KS_NAME, "dumb"},
+ {(int)KS_CL, "\014"},
+#ifdef TERMINFO
+ {(int)KS_CM, IF_EB("\033[%i%p1%d;%p2%dH",
+ ESC_STR "[%i%p1%d;%p2%dH")},
+#else
+ {(int)KS_CM, IF_EB("\033[%i%d;%dH", ESC_STR "[%i%d;%dH")},
+#endif
+
+ /*
+ * end marker
+ */
+ {(int)KS_NAME, NULL}
+
+}; /* end of builtin_termcaps */
+
+/*
+ * DEFAULT_TERM is used, when no terminal is specified with -T option or $TERM.
+ */
+
+
+
+#if defined(UNIX) && !defined(__MINT__)
+# define DEFAULT_TERM (char_u *)"ansi"
+#endif
+
+
+
+
+
+#ifndef DEFAULT_TERM
+# define DEFAULT_TERM (char_u *)"dumb"
+#endif
+
+/*
+ * Term_strings contains currently used terminal output strings.
+ * It is initialized with the default values by parse_builtin_tcap().
+ * The values can be changed by setting the option with the same name.
+ */
+char_u *(term_strings[(int)KS_LAST + 1]);
+
+static int need_gather = FALSE; /* need to fill termleader[] */
+static char_u termleader[256 + 1]; /* for check_termcode() */
+static int check_for_codes = FALSE; /* check for key code response */
+
+static struct builtin_term * find_builtin_term(term)
+char_u *term;
+{
+ struct builtin_term *p;
+
+ p = builtin_termcaps;
+ while (p->bt_string != NULL) {
+ if (p->bt_entry == (int)KS_NAME) {
+#ifdef UNIX
+ if (STRCMP(p->bt_string, "iris-ansi") == 0 && vim_is_iris(term))
+ return p;
+ else if (STRCMP(p->bt_string, "xterm") == 0 && vim_is_xterm(term))
+ return p;
+ else
+#endif
+ if (STRCMP(term, p->bt_string) == 0)
+ return p;
+ }
+ ++p;
+ }
+ return p;
+}
+
+/*
+ * Parsing of the builtin termcap entries.
+ * Caller should check if 'name' is a valid builtin term.
+ * The terminal's name is not set, as this is already done in termcapinit().
+ */
+static void parse_builtin_tcap(term)
+char_u *term;
+{
+ struct builtin_term *p;
+ char_u name[2];
+ int term_8bit;
+
+ p = find_builtin_term(term);
+ term_8bit = term_is_8bit(term);
+
+ /* Do not parse if builtin term not found */
+ if (p->bt_string == NULL)
+ return;
+
+ for (++p; p->bt_entry != (int)KS_NAME && p->bt_entry != BT_EXTRA_KEYS; ++p) {
+ if ((int)p->bt_entry >= 0) { /* KS_xx entry */
+ /* Only set the value if it wasn't set yet. */
+ if (term_strings[p->bt_entry] == NULL
+ || term_strings[p->bt_entry] == empty_option) {
+ /* 8bit terminal: use CSI instead of <Esc>[ */
+ if (term_8bit && term_7to8bit((char_u *)p->bt_string) != 0) {
+ char_u *s, *t;
+
+ s = vim_strsave((char_u *)p->bt_string);
+ if (s != NULL) {
+ for (t = s; *t; ++t)
+ if (term_7to8bit(t)) {
+ *t = term_7to8bit(t);
+ STRCPY(t + 1, t + 2);
+ }
+ term_strings[p->bt_entry] = s;
+ set_term_option_alloced(&term_strings[p->bt_entry]);
+ }
+ } else
+ term_strings[p->bt_entry] = (char_u *)p->bt_string;
+ }
+ } else {
+ name[0] = KEY2TERMCAP0((int)p->bt_entry);
+ name[1] = KEY2TERMCAP1((int)p->bt_entry);
+ if (find_termcode(name) == NULL)
+ add_termcode(name, (char_u *)p->bt_string, term_8bit);
+ }
+ }
+}
+static void set_color_count __ARGS((int nr));
+
+/*
+ * Set number of colors.
+ * Store it as a number in t_colors.
+ * Store it as a string in T_CCO (using nr_colors[]).
+ */
+static void set_color_count(nr)
+int nr;
+{
+ char_u nr_colors[20]; /* string for number of colors */
+
+ t_colors = nr;
+ if (t_colors > 1)
+ sprintf((char *)nr_colors, "%d", t_colors);
+ else
+ *nr_colors = NUL;
+ set_string_option_direct((char_u *)"t_Co", -1, nr_colors, OPT_FREE, 0);
+}
+
+#ifdef HAVE_TGETENT
+static char *(key_names[]) =
+{
+ /* Do this one first, it may cause a screen redraw. */
+ "Co",
+ "ku", "kd", "kr", "kl",
+# ifdef ARCHIE
+ "su", "sd", /* Termcap code made up! */
+# endif
+ "#2", "#4", "%i", "*7",
+ "k1", "k2", "k3", "k4", "k5", "k6",
+ "k7", "k8", "k9", "k;", "F1", "F2",
+ "%1", "&8", "kb", "kI", "kD", "kh",
+ "@7", "kP", "kN", "K1", "K3", "K4", "K5", "kB",
+ NULL
+};
+#endif
+
+/*
+ * Set terminal options for terminal "term".
+ * Return OK if terminal 'term' was found in a termcap, FAIL otherwise.
+ *
+ * While doing this, until ttest(), some options may be NULL, be careful.
+ */
+int set_termname(term)
+char_u *term;
+{
+ struct builtin_term *termp;
+#ifdef HAVE_TGETENT
+ int builtin_first = p_tbi;
+ int try;
+ int termcap_cleared = FALSE;
+#endif
+ int width = 0, height = 0;
+ char_u *error_msg = NULL;
+ char_u *bs_p, *del_p;
+
+ /* In silect mode (ex -s) we don't use the 'term' option. */
+ if (silent_mode)
+ return OK;
+
+ detected_8bit = FALSE; /* reset 8-bit detection */
+
+ if (term_is_builtin(term)) {
+ term += 8;
+#ifdef HAVE_TGETENT
+ builtin_first = 1;
+#endif
+ }
+
+ /*
+ * If HAVE_TGETENT is not defined, only the builtin termcap is used, otherwise:
+ * If builtin_first is TRUE:
+ * 0. try builtin termcap
+ * 1. try external termcap
+ * 2. if both fail default to a builtin terminal
+ * If builtin_first is FALSE:
+ * 1. try external termcap
+ * 2. try builtin termcap, if both fail default to a builtin terminal
+ */
+#ifdef HAVE_TGETENT
+ for (try = builtin_first ? 0 : 1; try < 3; ++try) {
+ /*
+ * Use external termcap
+ */
+ if (try == 1) {
+ char_u *p;
+ static char_u tstrbuf[TBUFSZ];
+ int i;
+ char_u tbuf[TBUFSZ];
+ char_u *tp;
+ static struct {
+ enum SpecialKey dest; /* index in term_strings[] */
+ char *name; /* termcap name for string */
+ } string_names[] =
+ { {KS_CE, "ce"}, {KS_AL, "al"}, {KS_CAL,"AL"},
+ {KS_DL, "dl"}, {KS_CDL,"DL"}, {KS_CS, "cs"},
+ {KS_CL, "cl"}, {KS_CD, "cd"},
+ {KS_VI, "vi"}, {KS_VE, "ve"}, {KS_MB, "mb"},
+ {KS_VS, "vs"}, {KS_ME, "me"}, {KS_MR, "mr"},
+ {KS_MD, "md"}, {KS_SE, "se"}, {KS_SO, "so"},
+ {KS_CZH,"ZH"}, {KS_CZR,"ZR"}, {KS_UE, "ue"},
+ {KS_US, "us"}, {KS_UCE, "Ce"}, {KS_UCS, "Cs"},
+ {KS_CM, "cm"}, {KS_SR, "sr"},
+ {KS_CRI,"RI"}, {KS_VB, "vb"}, {KS_KS, "ks"},
+ {KS_KE, "ke"}, {KS_TI, "ti"}, {KS_TE, "te"},
+ {KS_BC, "bc"}, {KS_CSB,"Sb"}, {KS_CSF,"Sf"},
+ {KS_CAB,"AB"}, {KS_CAF,"AF"}, {KS_LE, "le"},
+ {KS_ND, "nd"}, {KS_OP, "op"}, {KS_CRV, "RV"},
+ {KS_CIS, "IS"}, {KS_CIE, "IE"},
+ {KS_TS, "ts"}, {KS_FS, "fs"},
+ {KS_CWP, "WP"}, {KS_CWS, "WS"},
+ {KS_CSI, "SI"}, {KS_CEI, "EI"},
+ {KS_U7, "u7"},
+ {(enum SpecialKey)0, NULL}};
+
+ /*
+ * If the external termcap does not have a matching entry, try the
+ * builtin ones.
+ */
+ if ((error_msg = tgetent_error(tbuf, term)) == NULL) {
+ tp = tstrbuf;
+ if (!termcap_cleared) {
+ clear_termoptions(); /* clear old options */
+ termcap_cleared = TRUE;
+ }
+
+ /* get output strings */
+ for (i = 0; string_names[i].name != NULL; ++i) {
+ if (term_str(string_names[i].dest) == NULL
+ || term_str(string_names[i].dest) == empty_option)
+ term_str(string_names[i].dest) =
+ TGETSTR(string_names[i].name, &tp);
+ }
+
+ /* tgetflag() returns 1 if the flag is present, 0 if not and
+ * possibly -1 if the flag doesn't exist. */
+ if ((T_MS == NULL || T_MS == empty_option)
+ && tgetflag("ms") > 0)
+ T_MS = (char_u *)"y";
+ if ((T_XS == NULL || T_XS == empty_option)
+ && tgetflag("xs") > 0)
+ T_XS = (char_u *)"y";
+ if ((T_DB == NULL || T_DB == empty_option)
+ && tgetflag("db") > 0)
+ T_DB = (char_u *)"y";
+ if ((T_DA == NULL || T_DA == empty_option)
+ && tgetflag("da") > 0)
+ T_DA = (char_u *)"y";
+ if ((T_UT == NULL || T_UT == empty_option)
+ && tgetflag("ut") > 0)
+ T_UT = (char_u *)"y";
+
+
+ /*
+ * get key codes
+ */
+ for (i = 0; key_names[i] != NULL; ++i) {
+ if (find_termcode((char_u *)key_names[i]) == NULL) {
+ p = TGETSTR(key_names[i], &tp);
+ /* if cursor-left == backspace, ignore it (televideo
+ * 925) */
+ if (p != NULL
+ && (*p != Ctrl_H
+ || key_names[i][0] != 'k'
+ || key_names[i][1] != 'l'))
+ add_termcode((char_u *)key_names[i], p, FALSE);
+ }
+ }
+
+ if (height == 0)
+ height = tgetnum("li");
+ if (width == 0)
+ width = tgetnum("co");
+
+ /*
+ * Get number of colors (if not done already).
+ */
+ if (term_str(KS_CCO) == NULL
+ || term_str(KS_CCO) == empty_option)
+ set_color_count(tgetnum("Co"));
+
+# ifndef hpux
+ BC = (char *)TGETSTR("bc", &tp);
+ UP = (char *)TGETSTR("up", &tp);
+ p = TGETSTR("pc", &tp);
+ if (p)
+ PC = *p;
+# endif /* hpux */
+ }
+ } else /* try == 0 || try == 2 */
+#endif /* HAVE_TGETENT */
+ /*
+ * Use builtin termcap
+ */
+ {
+#ifdef HAVE_TGETENT
+ /*
+ * If builtin termcap was already used, there is no need to search
+ * for the builtin termcap again, quit now.
+ */
+ if (try == 2 && builtin_first && termcap_cleared)
+ break;
+#endif
+ /*
+ * search for 'term' in builtin_termcaps[]
+ */
+ termp = find_builtin_term(term);
+ if (termp->bt_string == NULL) { /* did not find it */
+#ifdef HAVE_TGETENT
+ /*
+ * If try == 0, first try the external termcap. If that is not
+ * found we'll get back here with try == 2.
+ * If termcap_cleared is set we used the external termcap,
+ * don't complain about not finding the term in the builtin
+ * termcap.
+ */
+ if (try == 0) /* try external one */
+ continue;
+ if (termcap_cleared) /* found in external termcap */
+ break;
+#endif
+
+ mch_errmsg("\r\n");
+ if (error_msg != NULL) {
+ mch_errmsg((char *)error_msg);
+ mch_errmsg("\r\n");
+ }
+ mch_errmsg("'");
+ mch_errmsg((char *)term);
+ mch_errmsg(_("' not known. Available builtin terminals are:"));
+ mch_errmsg("\r\n");
+ for (termp = &(builtin_termcaps[0]); termp->bt_string != NULL;
+ ++termp) {
+ if (termp->bt_entry == (int)KS_NAME) {
+#ifdef HAVE_TGETENT
+ mch_errmsg(" builtin_");
+#else
+ mch_errmsg(" ");
+#endif
+ mch_errmsg(termp->bt_string);
+ mch_errmsg("\r\n");
+ }
+ }
+ /* when user typed :set term=xxx, quit here */
+ if (starting != NO_SCREEN) {
+ screen_start(); /* don't know where cursor is now */
+ wait_return(TRUE);
+ return FAIL;
+ }
+ term = DEFAULT_TERM;
+ mch_errmsg(_("defaulting to '"));
+ mch_errmsg((char *)term);
+ mch_errmsg("'\r\n");
+ if (emsg_silent == 0) {
+ screen_start(); /* don't know where cursor is now */
+ out_flush();
+ ui_delay(2000L, TRUE);
+ }
+ set_string_option_direct((char_u *)"term", -1, term,
+ OPT_FREE, 0);
+ display_errors();
+ }
+ out_flush();
+#ifdef HAVE_TGETENT
+ if (!termcap_cleared) {
+#endif
+ clear_termoptions(); /* clear old options */
+#ifdef HAVE_TGETENT
+ termcap_cleared = TRUE;
+ }
+#endif
+ parse_builtin_tcap(term);
+ }
+#ifdef HAVE_TGETENT
+}
+#endif
+
+ /*
+ * special: There is no info in the termcap about whether the cursor
+ * positioning is relative to the start of the screen or to the start of the
+ * scrolling region. We just guess here. Only msdos pcterm is known to do it
+ * relative.
+ */
+ if (STRCMP(term, "pcterm") == 0)
+ T_CCS = (char_u *)"yes";
+ else
+ T_CCS = empty_option;
+
+#ifdef UNIX
+ /*
+ * Any "stty" settings override the default for t_kb from the termcap.
+ * This is in os_unix.c, because it depends a lot on the version of unix that
+ * is being used.
+ * Don't do this when the GUI is active, it uses "t_kb" and "t_kD" directly.
+ */
+ get_stty();
+#endif
+
+ /*
+ * If the termcap has no entry for 'bs' and/or 'del' and the ioctl() also
+ * didn't work, use the default CTRL-H
+ * The default for t_kD is DEL, unless t_kb is DEL.
+ * The vim_strsave'd strings are probably lost forever, well it's only two
+ * bytes. Don't do this when the GUI is active, it uses "t_kb" and "t_kD"
+ * directly.
+ */
+ {
+ bs_p = find_termcode((char_u *)"kb");
+ del_p = find_termcode((char_u *)"kD");
+ if (bs_p == NULL || *bs_p == NUL)
+ add_termcode((char_u *)"kb", (bs_p = (char_u *)CTRL_H_STR), FALSE);
+ if ((del_p == NULL || *del_p == NUL) &&
+ (bs_p == NULL || *bs_p != DEL))
+ add_termcode((char_u *)"kD", (char_u *)DEL_STR, FALSE);
+ }
+
+#if defined(UNIX) || defined(VMS)
+ term_is_xterm = vim_is_xterm(term);
+#endif
+
+# if defined(UNIX) || defined(VMS)
+ /*
+ * For Unix, set the 'ttymouse' option to the type of mouse to be used.
+ * The termcode for the mouse is added as a side effect in option.c.
+ */
+ {
+ char_u *p;
+
+ p = (char_u *)"";
+ if (use_xterm_like_mouse(term)) {
+ if (use_xterm_mouse())
+ p = NULL; /* keep existing value, might be "xterm2" */
+ else
+ p = (char_u *)"xterm";
+ }
+ if (p != NULL) {
+ set_option_value((char_u *)"ttym", 0L, p, 0);
+ /* Reset the WAS_SET flag, 'ttymouse' can be set to "sgr" or
+ * "xterm2" in check_termcode(). */
+ reset_option_was_set((char_u *)"ttym");
+ }
+ if (p == NULL
+ )
+ check_mouse_termcode(); /* set mouse termcode anyway */
+ }
+# else
+ set_mouse_termcode(KS_MOUSE, (char_u *)"\233M");
+# endif
+
+
+#ifdef USE_TERM_CONSOLE
+ /* DEFAULT_TERM indicates that it is the machine console. */
+ if (STRCMP(term, DEFAULT_TERM) != 0)
+ term_console = FALSE;
+ else {
+ term_console = TRUE;
+ }
+#endif
+
+#if defined(UNIX) || defined(VMS)
+ /*
+ * 'ttyfast' is default on for xterm, iris-ansi and a few others.
+ */
+ if (vim_is_fastterm(term))
+ p_tf = TRUE;
+#endif
+#ifdef USE_TERM_CONSOLE
+ /*
+ * 'ttyfast' is default on consoles
+ */
+ if (term_console)
+ p_tf = TRUE;
+#endif
+
+ ttest(TRUE); /* make sure we have a valid set of terminal codes */
+
+ full_screen = TRUE; /* we can use termcap codes from now on */
+ set_term_defaults(); /* use current values as defaults */
+ LOG_TR("setting crv_status to CRV_GET");
+ crv_status = CRV_GET; /* Get terminal version later */
+
+ /*
+ * Initialize the terminal with the appropriate termcap codes.
+ * Set the mouse and window title if possible.
+ * Don't do this when starting, need to parse the .vimrc first, because it
+ * may redefine t_TI etc.
+ */
+ if (starting != NO_SCREEN) {
+ starttermcap(); /* may change terminal mode */
+ setmouse(); /* may start using the mouse */
+ maketitle(); /* may display window title */
+ }
+
+ /* display initial screen after ttest() checking. jw. */
+ if (width <= 0 || height <= 0) {
+ /* termcap failed to report size */
+ /* set defaults, in case ui_get_shellsize() also fails */
+ width = 80;
+ height = 24; /* most terminals are 24 lines */
+ }
+ set_shellsize(width, height, FALSE); /* may change Rows */
+ if (starting != NO_SCREEN) {
+ if (scroll_region)
+ scroll_region_reset(); /* In case Rows changed */
+ check_map_keycodes(); /* check mappings for terminal codes used */
+
+ {
+ buf_T *old_curbuf;
+
+ /*
+ * Execute the TermChanged autocommands for each buffer that is
+ * loaded.
+ */
+ old_curbuf = curbuf;
+ for (curbuf = firstbuf; curbuf != NULL; curbuf = curbuf->b_next) {
+ if (curbuf->b_ml.ml_mfp != NULL)
+ apply_autocmds(EVENT_TERMCHANGED, NULL, NULL, FALSE,
+ curbuf);
+ }
+ if (buf_valid(old_curbuf))
+ curbuf = old_curbuf;
+ }
+ }
+
+ may_req_termresponse();
+
+ return OK;
+}
+
+
+# define HMT_NORMAL 1
+# define HMT_NETTERM 2
+# define HMT_DEC 4
+# define HMT_JSBTERM 8
+# define HMT_PTERM 16
+# define HMT_URXVT 32
+# define HMT_SGR 64
+static int has_mouse_termcode = 0;
+
+void set_mouse_termcode(n, s)
+int n; /* KS_MOUSE, KS_NETTERM_MOUSE or KS_DEC_MOUSE */
+char_u *s;
+{
+ char_u name[2];
+
+ name[0] = n;
+ name[1] = KE_FILLER;
+ add_termcode(name, s, FALSE);
+# ifdef FEAT_MOUSE_JSB
+ if (n == KS_JSBTERM_MOUSE)
+ has_mouse_termcode |= HMT_JSBTERM;
+ else
+# endif
+ if (n == KS_NETTERM_MOUSE)
+ has_mouse_termcode |= HMT_NETTERM;
+ else if (n == KS_DEC_MOUSE)
+ has_mouse_termcode |= HMT_DEC;
+ else if (n == KS_URXVT_MOUSE)
+ has_mouse_termcode |= HMT_URXVT;
+ else if (n == KS_SGR_MOUSE)
+ has_mouse_termcode |= HMT_SGR;
+ else
+ has_mouse_termcode |= HMT_NORMAL;
+}
+
+# if ((defined(UNIX) || defined(VMS) || defined(OS2)) \
+ && defined(FEAT_MOUSE_TTY)) || defined(PROTO)
+void del_mouse_termcode(n)
+int n; /* KS_MOUSE, KS_NETTERM_MOUSE or KS_DEC_MOUSE */
+{
+ char_u name[2];
+
+ name[0] = n;
+ name[1] = KE_FILLER;
+ del_termcode(name);
+# ifdef FEAT_MOUSE_JSB
+ if (n == KS_JSBTERM_MOUSE)
+ has_mouse_termcode &= ~HMT_JSBTERM;
+ else
+# endif
+ if (n == KS_NETTERM_MOUSE)
+ has_mouse_termcode &= ~HMT_NETTERM;
+ else if (n == KS_DEC_MOUSE)
+ has_mouse_termcode &= ~HMT_DEC;
+ else if (n == KS_URXVT_MOUSE)
+ has_mouse_termcode &= ~HMT_URXVT;
+ else if (n == KS_SGR_MOUSE)
+ has_mouse_termcode &= ~HMT_SGR;
+ else
+ has_mouse_termcode &= ~HMT_NORMAL;
+}
+# endif
+
+#ifdef HAVE_TGETENT
+/*
+ * Call tgetent()
+ * Return error message if it fails, NULL if it's OK.
+ */
+static char_u * tgetent_error(tbuf, term)
+char_u *tbuf;
+char_u *term;
+{
+ int i;
+
+ i = TGETENT(tbuf, term);
+ if (i < 0 /* -1 is always an error */
+# ifdef TGETENT_ZERO_ERR
+ || i == 0 /* sometimes zero is also an error */
+# endif
+ ) {
+ /* On FreeBSD tputs() gets a SEGV after a tgetent() which fails. Call
+ * tgetent() with the always existing "dumb" entry to avoid a crash or
+ * hang. */
+ (void)TGETENT(tbuf, "dumb");
+
+ if (i < 0)
+# ifdef TGETENT_ZERO_ERR
+ return (char_u *)_("E557: Cannot open termcap file");
+ if (i == 0)
+# endif
+#ifdef TERMINFO
+ return (char_u *)_("E558: Terminal entry not found in terminfo");
+#else
+ return (char_u *)_("E559: Terminal entry not found in termcap");
+#endif
+ }
+ return NULL;
+}
+
+/*
+ * Some versions of tgetstr() have been reported to return -1 instead of NULL.
+ * Fix that here.
+ */
+static char_u * vim_tgetstr(s, pp)
+char *s;
+char_u **pp;
+{
+ char *p;
+
+ p = tgetstr(s, (char **)pp);
+ if (p == (char *)-1)
+ p = NULL;
+ return (char_u *)p;
+}
+#endif /* HAVE_TGETENT */
+
+#if defined(HAVE_TGETENT) && (defined(UNIX) || defined(__EMX__) || \
+ defined(VMS) || defined(MACOS_X))
+/*
+ * Get Columns and Rows from the termcap. Used after a window signal if the
+ * ioctl() fails. It doesn't make sense to call tgetent each time if the "co"
+ * and "li" entries never change. But on some systems this works.
+ * Errors while getting the entries are ignored.
+ */
+void getlinecol(cp, rp)
+long *cp; /* pointer to columns */
+long *rp; /* pointer to rows */
+{
+ char_u tbuf[TBUFSZ];
+
+ if (T_NAME != NULL && *T_NAME != NUL &&
+ tgetent_error(tbuf, T_NAME) == NULL) {
+ if (*cp == 0)
+ *cp = tgetnum("co");
+ if (*rp == 0)
+ *rp = tgetnum("li");
+ }
+}
+#endif /* defined(HAVE_TGETENT) && defined(UNIX) */
+
+/*
+ * Get a string entry from the termcap and add it to the list of termcodes.
+ * Used for <t_xx> special keys.
+ * Give an error message for failure when not sourcing.
+ * If force given, replace an existing entry.
+ * Return FAIL if the entry was not found, OK if the entry was added.
+ */
+int add_termcap_entry(name, force)
+char_u *name;
+int force;
+{
+ char_u *term;
+ int key;
+ struct builtin_term *termp;
+#ifdef HAVE_TGETENT
+ char_u *string;
+ int i;
+ int builtin_first;
+ char_u tbuf[TBUFSZ];
+ char_u tstrbuf[TBUFSZ];
+ char_u *tp = tstrbuf;
+ char_u *error_msg = NULL;
+#endif
+
+ /*
+ * If the GUI is running or will start in a moment, we only support the keys
+ * that the GUI can produce.
+ */
+
+ if (!force && find_termcode(name) != NULL) /* it's already there */
+ return OK;
+
+ term = T_NAME;
+ if (term == NULL || *term == NUL) /* 'term' not defined yet */
+ return FAIL;
+
+ if (term_is_builtin(term)) { /* name starts with "builtin_" */
+ term += 8;
+#ifdef HAVE_TGETENT
+ builtin_first = TRUE;
+#endif
+ }
+#ifdef HAVE_TGETENT
+ else
+ builtin_first = p_tbi;
+#endif
+
+#ifdef HAVE_TGETENT
+ /*
+ * We can get the entry from the builtin termcap and from the external one.
+ * If 'ttybuiltin' is on or the terminal name starts with "builtin_", try
+ * builtin termcap first.
+ * If 'ttybuiltin' is off, try external termcap first.
+ */
+ for (i = 0; i < 2; ++i) {
+ if (!builtin_first == i)
+#endif
+ /*
+ * Search in builtin termcap
+ */
+ {
+ termp = find_builtin_term(term);
+ if (termp->bt_string != NULL) { /* found it */
+ key = TERMCAP2KEY(name[0], name[1]);
+ while (termp->bt_entry != (int)KS_NAME) {
+ if ((int)termp->bt_entry == key) {
+ add_termcode(name, (char_u *)termp->bt_string,
+ term_is_8bit(term));
+ return OK;
+ }
+ ++termp;
+ }
+ }
+ }
+#ifdef HAVE_TGETENT
+ else {
+ /*
+ * Search in external termcap
+ */
+ error_msg = tgetent_error(tbuf, term);
+ if (error_msg == NULL) {
+ string = TGETSTR((char *)name, &tp);
+ if (string != NULL && *string != NUL) {
+ add_termcode(name, string, FALSE);
+ return OK;
+ }
+ }
+ }
+}
+#endif
+
+ if (sourcing_name == NULL) {
+#ifdef HAVE_TGETENT
+ if (error_msg != NULL)
+ EMSG(error_msg);
+ else
+#endif
+ EMSG2(_("E436: No \"%s\" entry in termcap"), name);
+ }
+ return FAIL;
+}
+
+static int term_is_builtin(name)
+char_u *name;
+{
+ return STRNCMP(name, "builtin_", (size_t)8) == 0;
+}
+
+/*
+ * Return TRUE if terminal "name" uses CSI instead of <Esc>[.
+ * Assume that the terminal is using 8-bit controls when the name contains
+ * "8bit", like in "xterm-8bit".
+ */
+int term_is_8bit(name)
+char_u *name;
+{
+ return detected_8bit || strstr((char *)name, "8bit") != NULL;
+}
+
+/*
+ * Translate terminal control chars from 7-bit to 8-bit:
+ * <Esc>[ -> CSI
+ * <Esc>] -> <M-C-]>
+ * <Esc>O -> <M-C-O>
+ */
+static int term_7to8bit(p)
+char_u *p;
+{
+ if (*p == ESC) {
+ if (p[1] == '[')
+ return CSI;
+ if (p[1] == ']')
+ return 0x9d;
+ if (p[1] == 'O')
+ return 0x8f;
+ }
+ return 0;
+}
+
+
+#if !defined(HAVE_TGETENT) || defined(AMIGA) || defined(PROTO)
+
+char_u * tltoa(i)
+unsigned long i;
+{
+ static char_u buf[16];
+ char_u *p;
+
+ p = buf + 15;
+ *p = '\0';
+ do {
+ --p;
+ *p = (char_u) (i % 10 + '0');
+ i /= 10;
+ } while (i > 0 && p > buf);
+ return p;
+}
+#endif
+
+#ifndef HAVE_TGETENT
+
+/*
+ * minimal tgoto() implementation.
+ * no padding and we only parse for %i %d and %+char
+ */
+static char *tgoto __ARGS((char *, int, int));
+
+static char * tgoto(cm, x, y)
+char *cm;
+int x, y;
+{
+ static char buf[30];
+ char *p, *s, *e;
+
+ if (!cm)
+ return "OOPS";
+ e = buf + 29;
+ for (s = buf; s < e && *cm; cm++) {
+ if (*cm != '%') {
+ *s++ = *cm;
+ continue;
+ }
+ switch (*++cm) {
+ case 'd':
+ p = (char *)tltoa((unsigned long)y);
+ y = x;
+ while (*p)
+ *s++ = *p++;
+ break;
+ case 'i':
+ x++;
+ y++;
+ break;
+ case '+':
+ *s++ = (char)(*++cm + y);
+ y = x;
+ break;
+ case '%':
+ *s++ = *cm;
+ break;
+ default:
+ return "OOPS";
+ }
+ }
+ *s = '\0';
+ return buf;
+}
+
+#endif /* HAVE_TGETENT */
+
+/*
+ * Set the terminal name and initialize the terminal options.
+ * If "name" is NULL or empty, get the terminal name from the environment.
+ * If that fails, use the default terminal name.
+ */
+void termcapinit(name)
+char_u *name;
+{
+ char_u *term;
+
+ if (name != NULL && *name == NUL)
+ name = NULL; /* empty name is equal to no name */
+ term = name;
+
+ if (term == NULL)
+ term = mch_getenv((char_u *)"TERM");
+ if (term == NULL || *term == NUL)
+ term = DEFAULT_TERM;
+ set_string_option_direct((char_u *)"term", -1, term, OPT_FREE, 0);
+
+ /* Set the default terminal name. */
+ set_string_default("term", term);
+ set_string_default("ttytype", term);
+
+ /*
+ * Avoid using "term" here, because the next mch_getenv() may overwrite it.
+ */
+ set_termname(T_NAME != NULL ? T_NAME : term);
+}
+
+/*
+ * the number of calls to ui_write is reduced by using the buffer "out_buf"
+ */
+# define OUT_SIZE 2047
+/* Add one to allow mch_write() in os_win32.c to append a NUL */
+static char_u out_buf[OUT_SIZE + 1];
+static int out_pos = 0; /* number of chars in out_buf */
+
+/*
+ * out_flush(): flush the output buffer
+ */
+void out_flush() {
+ int len;
+
+ if (out_pos != 0) {
+ /* set out_pos to 0 before ui_write, to avoid recursiveness */
+ len = out_pos;
+ out_pos = 0;
+ ui_write(out_buf, len);
+ }
+}
+
+/*
+ * Sometimes a byte out of a multi-byte character is written with out_char().
+ * To avoid flushing half of the character, call this function first.
+ */
+void out_flush_check() {
+ if (enc_dbcs != 0 && out_pos >= OUT_SIZE - MB_MAXBYTES)
+ out_flush();
+}
+
+/*
+ * out_char(c): put a byte into the output buffer.
+ * Flush it if it becomes full.
+ * This should not be used for outputting text on the screen (use functions
+ * like msg_puts() and screen_putchar() for that).
+ */
+void out_char(c)
+unsigned c;
+{
+#if defined(UNIX) || defined(VMS) || defined(AMIGA) || defined(MACOS_X_UNIX)
+ if (c == '\n') /* turn LF into CR-LF (CRMOD doesn't seem to do this) */
+ out_char('\r');
+#endif
+
+ out_buf[out_pos++] = c;
+
+ /* For testing we flush each time. */
+ if (out_pos >= OUT_SIZE || p_wd)
+ out_flush();
+}
+
+static void out_char_nf __ARGS((unsigned));
+
+/*
+ * out_char_nf(c): like out_char(), but don't flush when p_wd is set
+ */
+static void out_char_nf(c)
+unsigned c;
+{
+#if defined(UNIX) || defined(VMS) || defined(AMIGA) || defined(MACOS_X_UNIX)
+ if (c == '\n') /* turn LF into CR-LF (CRMOD doesn't seem to do this) */
+ out_char_nf('\r');
+#endif
+
+ out_buf[out_pos++] = c;
+
+ if (out_pos >= OUT_SIZE)
+ out_flush();
+}
+
+#if defined(FEAT_TITLE) || defined(FEAT_MOUSE_TTY) || defined(FEAT_GUI) \
+ || defined(FEAT_TERMRESPONSE) || defined(PROTO)
+/*
+ * A never-padding out_str.
+ * use this whenever you don't want to run the string through tputs.
+ * tputs above is harmless, but tputs from the termcap library
+ * is likely to strip off leading digits, that it mistakes for padding
+ * information, and "%i", "%d", etc.
+ * This should only be used for writing terminal codes, not for outputting
+ * normal text (use functions like msg_puts() and screen_putchar() for that).
+ */
+void out_str_nf(s)
+char_u *s;
+{
+ if (out_pos > OUT_SIZE - 20) /* avoid terminal strings being split up */
+ out_flush();
+ while (*s)
+ out_char_nf(*s++);
+
+ /* For testing we write one string at a time. */
+ if (p_wd)
+ out_flush();
+}
+#endif
+
+/*
+ * out_str(s): Put a character string a byte at a time into the output buffer.
+ * If HAVE_TGETENT is defined use the termcap parser. (jw)
+ * This should only be used for writing terminal codes, not for outputting
+ * normal text (use functions like msg_puts() and screen_putchar() for that).
+ */
+void out_str(s)
+char_u *s;
+{
+ if (s != NULL && *s) {
+ /* avoid terminal strings being split up */
+ if (out_pos > OUT_SIZE - 20)
+ out_flush();
+#ifdef HAVE_TGETENT
+ tputs((char *)s, 1, TPUTSFUNCAST out_char_nf);
+#else
+ while (*s)
+ out_char_nf(*s++);
+#endif
+
+ /* For testing we write one string at a time. */
+ if (p_wd)
+ out_flush();
+ }
+}
+
+/*
+ * cursor positioning using termcap parser. (jw)
+ */
+void term_windgoto(row, col)
+int row;
+int col;
+{
+ OUT_STR(tgoto((char *)T_CM, col, row));
+}
+
+void term_cursor_right(i)
+int i;
+{
+ OUT_STR(tgoto((char *)T_CRI, 0, i));
+}
+
+void term_append_lines(line_count)
+int line_count;
+{
+ OUT_STR(tgoto((char *)T_CAL, 0, line_count));
+}
+
+void term_delete_lines(line_count)
+int line_count;
+{
+ OUT_STR(tgoto((char *)T_CDL, 0, line_count));
+}
+
+#if defined(HAVE_TGETENT) || defined(PROTO)
+void term_set_winpos(x, y)
+int x;
+int y;
+{
+ /* Can't handle a negative value here */
+ if (x < 0)
+ x = 0;
+ if (y < 0)
+ y = 0;
+ OUT_STR(tgoto((char *)T_CWP, y, x));
+}
+
+void term_set_winsize(width, height)
+int width;
+int height;
+{
+ OUT_STR(tgoto((char *)T_CWS, height, width));
+}
+#endif
+
+void term_fg_color(n)
+int n;
+{
+ /* Use "AF" termcap entry if present, "Sf" entry otherwise */
+ if (*T_CAF)
+ term_color(T_CAF, n);
+ else if (*T_CSF)
+ term_color(T_CSF, n);
+}
+
+void term_bg_color(n)
+int n;
+{
+ /* Use "AB" termcap entry if present, "Sb" entry otherwise */
+ if (*T_CAB)
+ term_color(T_CAB, n);
+ else if (*T_CSB)
+ term_color(T_CSB, n);
+}
+
+static void term_color(s, n)
+char_u *s;
+int n;
+{
+ char buf[20];
+ int i = 2; /* index in s[] just after <Esc>[ or CSI */
+
+ /* Special handling of 16 colors, because termcap can't handle it */
+ /* Also accept "\e[3%dm" for TERMINFO, it is sometimes used */
+ /* Also accept CSI instead of <Esc>[ */
+ if (n >= 8 && t_colors >= 16
+ && ((s[0] == ESC && s[1] == '[') || (s[0] == CSI && (i = 1) == 1))
+ && s[i] != NUL
+ && (STRCMP(s + i + 1, "%p1%dm") == 0
+ || STRCMP(s + i + 1, "%dm") == 0)
+ && (s[i] == '3' || s[i] == '4')) {
+ sprintf(buf,
+#ifdef TERMINFO
+ "%s%s%%p1%%dm",
+#else
+ "%s%s%%dm",
+#endif
+ i == 2 ? IF_EB("\033[", ESC_STR "[") : "\233",
+ s[i] == '3' ? (n >= 16 ? "38;5;" : "9")
+ : (n >= 16 ? "48;5;" : "10"));
+ OUT_STR(tgoto(buf, 0, n >= 16 ? n : n - 8));
+ } else
+ OUT_STR(tgoto((char *)s, 0, n));
+}
+
+#if (defined(FEAT_TITLE) && (defined(UNIX) || defined(OS2) || defined(VMS) || \
+ defined(MACOS_X))) || defined(PROTO)
+/*
+ * Generic function to set window title, using t_ts and t_fs.
+ */
+void term_settitle(title)
+char_u *title;
+{
+ /* t_ts takes one argument: column in status line */
+ OUT_STR(tgoto((char *)T_TS, 0, 0)); /* set title start */
+ out_str_nf(title);
+ out_str(T_FS); /* set title end */
+ out_flush();
+}
+#endif
+
+/*
+ * Make sure we have a valid set or terminal options.
+ * Replace all entries that are NULL by empty_option
+ */
+void ttest(pairs)
+int pairs;
+{
+ check_options(); /* make sure no options are NULL */
+
+ /*
+ * MUST have "cm": cursor motion.
+ */
+ if (*T_CM == NUL)
+ EMSG(_("E437: terminal capability \"cm\" required"));
+
+ /*
+ * if "cs" defined, use a scroll region, it's faster.
+ */
+ if (*T_CS != NUL)
+ scroll_region = TRUE;
+ else
+ scroll_region = FALSE;
+
+ if (pairs) {
+ /*
+ * optional pairs
+ */
+ /* TP goes to normal mode for TI (invert) and TB (bold) */
+ if (*T_ME == NUL)
+ T_ME = T_MR = T_MD = T_MB = empty_option;
+ if (*T_SO == NUL || *T_SE == NUL)
+ T_SO = T_SE = empty_option;
+ if (*T_US == NUL || *T_UE == NUL)
+ T_US = T_UE = empty_option;
+ if (*T_CZH == NUL || *T_CZR == NUL)
+ T_CZH = T_CZR = empty_option;
+
+ /* T_VE is needed even though T_VI is not defined */
+ if (*T_VE == NUL)
+ T_VI = empty_option;
+
+ /* if 'mr' or 'me' is not defined use 'so' and 'se' */
+ if (*T_ME == NUL) {
+ T_ME = T_SE;
+ T_MR = T_SO;
+ T_MD = T_SO;
+ }
+
+ /* if 'so' or 'se' is not defined use 'mr' and 'me' */
+ if (*T_SO == NUL) {
+ T_SE = T_ME;
+ if (*T_MR == NUL)
+ T_SO = T_MD;
+ else
+ T_SO = T_MR;
+ }
+
+ /* if 'ZH' or 'ZR' is not defined use 'mr' and 'me' */
+ if (*T_CZH == NUL) {
+ T_CZR = T_ME;
+ if (*T_MR == NUL)
+ T_CZH = T_MD;
+ else
+ T_CZH = T_MR;
+ }
+
+ /* "Sb" and "Sf" come in pairs */
+ if (*T_CSB == NUL || *T_CSF == NUL) {
+ T_CSB = empty_option;
+ T_CSF = empty_option;
+ }
+
+ /* "AB" and "AF" come in pairs */
+ if (*T_CAB == NUL || *T_CAF == NUL) {
+ T_CAB = empty_option;
+ T_CAF = empty_option;
+ }
+
+ /* if 'Sb' and 'AB' are not defined, reset "Co" */
+ if (*T_CSB == NUL && *T_CAB == NUL)
+ free_one_termoption(T_CCO);
+
+ /* Set 'weirdinvert' according to value of 't_xs' */
+ p_wiv = (*T_XS != NUL);
+ }
+ need_gather = TRUE;
+
+ /* Set t_colors to the value of t_Co. */
+ t_colors = atoi((char *)T_CCO);
+}
+
+#if (defined(FEAT_GUI) && (defined(FEAT_MENU) || !defined(USE_ON_FLY_SCROLL))) \
+ || defined(PROTO)
+/*
+ * Represent the given long_u as individual bytes, with the most significant
+ * byte first, and store them in dst.
+ */
+void add_long_to_buf(val, dst)
+long_u val;
+char_u *dst;
+{
+ int i;
+ int shift;
+
+ for (i = 1; i <= (int)sizeof(long_u); i++) {
+ shift = 8 * (sizeof(long_u) - i);
+ dst[i - 1] = (char_u) ((val >> shift) & 0xff);
+ }
+}
+
+static int get_long_from_buf __ARGS((char_u *buf, long_u *val));
+
+/*
+ * Interpret the next string of bytes in buf as a long integer, with the most
+ * significant byte first. Note that it is assumed that buf has been through
+ * inchar(), so that NUL and K_SPECIAL will be represented as three bytes each.
+ * Puts result in val, and returns the number of bytes read from buf
+ * (between sizeof(long_u) and 2 * sizeof(long_u)), or -1 if not enough bytes
+ * were present.
+ */
+static int get_long_from_buf(buf, val)
+char_u *buf;
+long_u *val;
+{
+ int len;
+ char_u bytes[sizeof(long_u)];
+ int i;
+ int shift;
+
+ *val = 0;
+ len = get_bytes_from_buf(buf, bytes, (int)sizeof(long_u));
+ if (len != -1) {
+ for (i = 0; i < (int)sizeof(long_u); i++) {
+ shift = 8 * (sizeof(long_u) - 1 - i);
+ *val += (long_u)bytes[i] << shift;
+ }
+ }
+ return len;
+}
+#endif
+
+#if defined(FEAT_GUI) \
+ || (defined(FEAT_MOUSE) && (!defined(UNIX) || defined(FEAT_MOUSE_XTERM) \
+ || defined(FEAT_MOUSE_GPM) || defined(FEAT_SYSMOUSE)))
+/*
+ * Read the next num_bytes bytes from buf, and store them in bytes. Assume
+ * that buf has been through inchar(). Returns the actual number of bytes used
+ * from buf (between num_bytes and num_bytes*2), or -1 if not enough bytes were
+ * available.
+ */
+static int get_bytes_from_buf(buf, bytes, num_bytes)
+char_u *buf;
+char_u *bytes;
+int num_bytes;
+{
+ int len = 0;
+ int i;
+ char_u c;
+
+ for (i = 0; i < num_bytes; i++) {
+ if ((c = buf[len++]) == NUL)
+ return -1;
+ if (c == K_SPECIAL) {
+ if (buf[len] == NUL || buf[len + 1] == NUL) /* cannot happen? */
+ return -1;
+ if (buf[len++] == (int)KS_ZERO)
+ c = NUL;
+ /* else it should be KS_SPECIAL; when followed by KE_FILLER c is
+ * K_SPECIAL, or followed by KE_CSI and c must be CSI. */
+ if (buf[len++] == (int)KE_CSI)
+ c = CSI;
+ } else if (c == CSI && buf[len] == KS_EXTRA
+ && buf[len + 1] == (int)KE_CSI)
+ /* CSI is stored as CSI KS_SPECIAL KE_CSI to avoid confusion with
+ * the start of a special key, see add_to_input_buf_csi(). */
+ len += 2;
+ bytes[i] = c;
+ }
+ return len;
+}
+#endif
+
+/*
+ * Check if the new shell size is valid, correct it if it's too small or way
+ * too big.
+ */
+void check_shellsize() {
+ if (Rows < min_rows()) /* need room for one window and command line */
+ Rows = min_rows();
+ limit_screen_size();
+}
+
+/*
+ * Limit Rows and Columns to avoid an overflow in Rows * Columns.
+ */
+void limit_screen_size() {
+ if (Columns < MIN_COLUMNS)
+ Columns = MIN_COLUMNS;
+ else if (Columns > 10000)
+ Columns = 10000;
+ if (Rows > 1000)
+ Rows = 1000;
+}
+
+/*
+ * Invoked just before the screen structures are going to be (re)allocated.
+ */
+void win_new_shellsize() {
+ static int old_Rows = 0;
+ static int old_Columns = 0;
+
+ if (old_Rows != Rows || old_Columns != Columns)
+ ui_new_shellsize();
+ if (old_Rows != Rows) {
+ /* if 'window' uses the whole screen, keep it using that */
+ if (p_window == old_Rows - 1 || old_Rows == 0)
+ p_window = Rows - 1;
+ old_Rows = Rows;
+ shell_new_rows(); /* update window sizes */
+ }
+ if (old_Columns != Columns) {
+ old_Columns = Columns;
+ shell_new_columns(); /* update window sizes */
+ }
+}
+
+/*
+ * Call this function when the Vim shell has been resized in any way.
+ * Will obtain the current size and redraw (also when size didn't change).
+ */
+void shell_resized() {
+ set_shellsize(0, 0, FALSE);
+}
+
+/*
+ * Check if the shell size changed. Handle a resize.
+ * When the size didn't change, nothing happens.
+ */
+void shell_resized_check() {
+ int old_Rows = Rows;
+ int old_Columns = Columns;
+
+ if (!exiting
+ ) {
+ (void)ui_get_shellsize();
+ check_shellsize();
+ if (old_Rows != Rows || old_Columns != Columns)
+ shell_resized();
+ }
+}
+
+/*
+ * 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'.
+ */
+void set_shellsize(width, height, mustset)
+int width, height;
+int mustset;
+{
+ static int busy = FALSE;
+
+ /*
+ * Avoid recursiveness, can happen when setting the window size causes
+ * another window-changed signal.
+ */
+ if (busy)
+ return;
+
+ if (width < 0 || height < 0) /* just checking... */
+ return;
+
+ if (State == HITRETURN || State == SETWSIZE) {
+ /* postpone the resizing */
+ State = SETWSIZE;
+ return;
+ }
+
+ /* curwin->w_buffer can be NULL when we are closing a window and the
+ * buffer has already been closed and removing a scrollbar causes a resize
+ * event. Don't resize then, it will happen after entering another buffer.
+ */
+ if (curwin->w_buffer == NULL)
+ return;
+
+ ++busy;
+
+
+ if (mustset || (ui_get_shellsize() == FAIL && height != 0)) {
+ Rows = height;
+ Columns = width;
+ check_shellsize();
+ ui_set_shellsize(mustset);
+ } else
+ check_shellsize();
+
+ /* 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(). */
+
+ if (State != ASKMORE && State != EXTERNCMD && State != CONFIRM)
+ screenclear();
+ else
+ screen_start(); /* don't know where cursor is now */
+
+ if (starting != NO_SCREEN) {
+ maketitle();
+ changed_line_abv_curs();
+ invalidate_botline();
+
+ /*
+ * We only redraw when it's needed:
+ * - While at the more prompt or executing an external command, don't
+ * redraw, but position the cursor.
+ * - While editing the command line, only redraw that.
+ * - 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!
+ */
+ if (State == ASKMORE || State == EXTERNCMD || State == CONFIRM
+ || exmode_active) {
+ screenalloc(FALSE);
+ repeat_message();
+ } else {
+ if (curwin->w_p_scb)
+ do_check_scrollbind(TRUE);
+ if (State & CMDLINE) {
+ update_screen(NOT_VALID);
+ redrawcmdline();
+ } else {
+ update_topline();
+ if (pum_visible()) {
+ redraw_later(NOT_VALID);
+ ins_compl_show_pum(); /* This includes the redraw. */
+ } else
+ update_screen(NOT_VALID);
+ if (redrawing())
+ setcursor();
+ }
+ }
+ cursor_on(); /* redrawing may have switched it off */
+ }
+ out_flush();
+ --busy;
+}
+
+/*
+ * Set the terminal to TMODE_RAW (for Normal mode) or TMODE_COOK (for external
+ * commands and Ex mode).
+ */
+void settmode(tmode)
+int tmode;
+{
+
+ if (full_screen) {
+ /*
+ * When returning after calling a shell we want to really set the
+ * terminal to raw mode, even though we think it already is, because
+ * the shell program may have reset the terminal mode.
+ * When we think the terminal is normal, don't try to set it to
+ * normal again, because that causes problems (logout!) on some
+ * machines.
+ */
+ if (tmode != TMODE_COOK || cur_tmode != TMODE_COOK) {
+ {
+ /* May need to check for T_CRV response and termcodes, it
+ * doesn't work in Cooked mode, an external program may get
+ * them. */
+ if (tmode != TMODE_RAW && (crv_status == CRV_SENT
+ || u7_status == U7_SENT))
+ (void)vpeekc_nomap();
+ check_for_codes_from_term();
+ }
+ if (tmode != TMODE_RAW)
+ mch_setmouse(FALSE); /* switch mouse off */
+ out_flush();
+ mch_settmode(tmode); /* machine specific function */
+ cur_tmode = tmode;
+ if (tmode == TMODE_RAW)
+ setmouse(); /* may switch mouse on */
+ out_flush();
+ }
+ may_req_termresponse();
+ }
+}
+
+void starttermcap() {
+ if (full_screen && !termcap_active) {
+ out_str(T_TI); /* start termcap mode */
+ out_str(T_KS); /* start "keypad transmit" mode */
+ out_flush();
+ termcap_active = TRUE;
+ screen_start(); /* don't know where cursor is now */
+ {
+ may_req_termresponse();
+ /* Immediately check for a response. If t_Co changes, we don't
+ * want to redraw with wrong colors first. */
+ if (crv_status != CRV_GET)
+ check_for_codes_from_term();
+ }
+ }
+}
+
+void stoptermcap() {
+ screen_stop_highlight();
+ reset_cterm_colors();
+ if (termcap_active) {
+ {
+ /* May need to discard T_CRV or T_U7 response. */
+ if (crv_status == CRV_SENT || u7_status == U7_SENT) {
+# ifdef UNIX
+ /* Give the terminal a chance to respond. */
+ mch_delay(100L, FALSE);
+# endif
+# ifdef TCIFLUSH
+ /* Discard data received but not read. */
+ if (exiting)
+ tcflush(fileno(stdin), TCIFLUSH);
+# endif
+ }
+ /* Check for termcodes first, otherwise an external program may
+ * get them. */
+ check_for_codes_from_term();
+ }
+ out_str(T_KE); /* stop "keypad transmit" mode */
+ out_flush();
+ termcap_active = FALSE;
+ cursor_on(); /* just in case it is still off */
+ out_str(T_TE); /* stop termcap mode */
+ screen_start(); /* don't know where cursor is now */
+ out_flush();
+ }
+}
+
+/*
+ * Request version string (for xterm) when needed.
+ * Only do this after switching to raw mode, otherwise the result will be
+ * echoed.
+ * Only do this after startup has finished, to avoid that the response comes
+ * while executing "-c !cmd" or even after "-c quit".
+ * Only do this after termcap mode has been started, otherwise the codes for
+ * the cursor keys may be wrong.
+ * Only do this when 'esckeys' is on, otherwise the response causes trouble in
+ * Insert mode.
+ * On Unix only do it when both output and input are a tty (avoid writing
+ * request to terminal while reading from a file).
+ * The result is caught in check_termcode().
+ */
+void may_req_termresponse() {
+ if (crv_status == CRV_GET
+ && cur_tmode == TMODE_RAW
+ && starting == 0
+ && termcap_active
+ && p_ek
+# ifdef UNIX
+ && isatty(1)
+ && isatty(read_cmd_fd)
+# endif
+ && *T_CRV != NUL) {
+ LOG_TR("Sending CRV");
+ out_str(T_CRV);
+ crv_status = CRV_SENT;
+ /* check for the characters now, otherwise they might be eaten by
+ * get_keystroke() */
+ out_flush();
+ (void)vpeekc_nomap();
+ }
+}
+
+/*
+ * Check how the terminal treats ambiguous character width (UAX #11).
+ * First, we move the cursor to (1, 0) and print a test ambiguous character
+ * \u25bd (WHITE DOWN-POINTING TRIANGLE) and query current cursor position.
+ * If the terminal treats \u25bd as single width, the position is (1, 1),
+ * or if it is treated as double width, that will be (1, 2).
+ * This function has the side effect that changes cursor position, so
+ * it must be called immediately after entering termcap mode.
+ */
+void may_req_ambiguous_char_width() {
+ if (u7_status == U7_GET
+ && cur_tmode == TMODE_RAW
+ && termcap_active
+ && p_ek
+# ifdef UNIX
+ && isatty(1)
+ && isatty(read_cmd_fd)
+# endif
+ && *T_U7 != NUL
+ && !option_was_set((char_u *)"ambiwidth")) {
+ char_u buf[16];
+
+ LOG_TR("Sending U7 request");
+ /* Do this in the second row. In the first row the returned sequence
+ * may be CSI 1;2R, which is the same as <S-F3>. */
+ term_windgoto(1, 0);
+ buf[mb_char2bytes(0x25bd, buf)] = 0;
+ out_str(buf);
+ out_str(T_U7);
+ u7_status = U7_SENT;
+ term_windgoto(0, 0);
+ out_str((char_u *)" ");
+ term_windgoto(0, 0);
+ /* check for the characters now, otherwise they might be eaten by
+ * get_keystroke() */
+ out_flush();
+ (void)vpeekc_nomap();
+ }
+}
+
+# ifdef DEBUG_TERMRESPONSE
+static void log_tr(char *msg) {
+ static FILE *fd_tr = NULL;
+ static proftime_T start;
+ proftime_T now;
+
+ if (fd_tr == NULL) {
+ fd_tr = fopen("termresponse.log", "w");
+ profile_start(&start);
+ }
+ now = start;
+ profile_end(&now);
+ fprintf(fd_tr, "%s: %s %s\n",
+ profile_msg(&now),
+ must_redraw == NOT_VALID ? "NV"
+ : must_redraw == CLEAR ? "CL" : " ",
+ msg);
+}
+
+# endif
+
+/*
+ * Return TRUE when saving and restoring the screen.
+ */
+int swapping_screen() {
+ return full_screen && *T_TI != NUL;
+}
+
+/*
+ * setmouse() - switch mouse on/off depending on current mode and 'mouse'
+ */
+void setmouse() {
+ int checkfor;
+
+
+ /* be quick when mouse is off */
+ if (*p_mouse == NUL || has_mouse_termcode == 0)
+ return;
+
+ /* don't switch mouse on when not in raw mode (Ex mode) */
+ if (cur_tmode != TMODE_RAW) {
+ mch_setmouse(FALSE);
+ return;
+ }
+
+ if (VIsual_active)
+ checkfor = MOUSE_VISUAL;
+ else if (State == HITRETURN || State == ASKMORE || State == SETWSIZE)
+ checkfor = MOUSE_RETURN;
+ else if (State & INSERT)
+ checkfor = MOUSE_INSERT;
+ else if (State & CMDLINE)
+ checkfor = MOUSE_COMMAND;
+ else if (State == CONFIRM || State == EXTERNCMD)
+ checkfor = ' '; /* don't use mouse for ":confirm" or ":!cmd" */
+ else
+ checkfor = MOUSE_NORMAL; /* assume normal mode */
+
+ if (mouse_has(checkfor))
+ mch_setmouse(TRUE);
+ else
+ mch_setmouse(FALSE);
+}
+
+/*
+ * Return TRUE if
+ * - "c" is in 'mouse', or
+ * - 'a' is in 'mouse' and "c" is in MOUSE_A, or
+ * - the current buffer is a help file and 'h' is in 'mouse' and we are in a
+ * normal editing mode (not at hit-return message).
+ */
+int mouse_has(c)
+int c;
+{
+ char_u *p;
+
+ for (p = p_mouse; *p; ++p)
+ switch (*p) {
+ case 'a': if (vim_strchr((char_u *)MOUSE_A, c) != NULL)
+ return TRUE;
+ break;
+ case MOUSE_HELP: if (c != MOUSE_RETURN && curbuf->b_help)
+ return TRUE;
+ break;
+ default: if (c == *p) return TRUE; break;
+ }
+ return FALSE;
+}
+
+/*
+ * Return TRUE when 'mousemodel' is set to "popup" or "popup_setpos".
+ */
+int mouse_model_popup() {
+ return p_mousem[0] == 'p';
+}
+
+/*
+ * By outputting the 'cursor very visible' termcap code, for some windowed
+ * terminals this makes the screen scrolled to the correct position.
+ * Used when starting Vim or returning from a shell.
+ */
+void scroll_start() {
+ if (*T_VS != NUL) {
+ out_str(T_VS);
+ out_str(T_VE);
+ screen_start(); /* don't know where cursor is now */
+ }
+}
+
+static int cursor_is_off = FALSE;
+
+/*
+ * Enable the cursor.
+ */
+void cursor_on() {
+ if (cursor_is_off) {
+ out_str(T_VE);
+ cursor_is_off = FALSE;
+ }
+}
+
+/*
+ * Disable the cursor.
+ */
+void cursor_off() {
+ if (full_screen) {
+ if (!cursor_is_off)
+ out_str(T_VI); /* disable cursor */
+ cursor_is_off = TRUE;
+ }
+}
+
+#if defined(CURSOR_SHAPE) || defined(PROTO)
+/*
+ * Set cursor shape to match Insert mode.
+ */
+void term_cursor_shape() {
+ static int showing_insert_mode = MAYBE;
+
+ if (!full_screen || *T_CSI == NUL || *T_CEI == NUL)
+ return;
+
+ if (State & INSERT) {
+ if (showing_insert_mode != TRUE)
+ out_str(T_CSI); /* Insert mode cursor */
+ showing_insert_mode = TRUE;
+ } else {
+ if (showing_insert_mode != FALSE)
+ out_str(T_CEI); /* non-Insert mode cursor */
+ showing_insert_mode = FALSE;
+ }
+}
+
+#endif
+
+/*
+ * 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 scroll_region_set(wp, off)
+win_T *wp;
+int off;
+{
+ OUT_STR(tgoto((char *)T_CS, W_WINROW(wp) + wp->w_height - 1,
+ W_WINROW(wp) + off));
+ if (*T_CSV != NUL && wp->w_width != Columns)
+ OUT_STR(tgoto((char *)T_CSV, W_WINCOL(wp) + wp->w_width - 1,
+ W_WINCOL(wp)));
+ screen_start(); /* don't know where cursor is now */
+}
+
+/*
+ * Reset scrolling region to the whole screen.
+ */
+void scroll_region_reset() {
+ OUT_STR(tgoto((char *)T_CS, (int)Rows - 1, 0));
+ if (*T_CSV != NUL)
+ OUT_STR(tgoto((char *)T_CSV, (int)Columns - 1, 0));
+ screen_start(); /* don't know where cursor is now */
+}
+
+/*
+ * List of terminal codes that are currently recognized.
+ */
+
+static struct termcode {
+ char_u name[2]; /* termcap name of entry */
+ char_u *code; /* terminal code (in allocated memory) */
+ int len; /* STRLEN(code) */
+ int modlen; /* length of part before ";*~". */
+} *termcodes = NULL;
+
+static int tc_max_len = 0; /* number of entries that termcodes[] can hold */
+static int tc_len = 0; /* current number of entries in termcodes[] */
+
+static int termcode_star __ARGS((char_u *code, int len));
+
+void clear_termcodes() {
+ while (tc_len > 0)
+ vim_free(termcodes[--tc_len].code);
+ vim_free(termcodes);
+ termcodes = NULL;
+ tc_max_len = 0;
+
+#ifdef HAVE_TGETENT
+ BC = (char *)empty_option;
+ UP = (char *)empty_option;
+ PC = NUL; /* set pad character to NUL */
+ ospeed = 0;
+#endif
+
+ need_gather = TRUE; /* need to fill termleader[] */
+}
+
+#define ATC_FROM_TERM 55
+
+/*
+ * Add a new entry to the list of terminal codes.
+ * The list is kept alphabetical for ":set termcap"
+ * "flags" is TRUE when replacing 7-bit by 8-bit controls is desired.
+ * "flags" can also be ATC_FROM_TERM for got_code_from_term().
+ */
+void add_termcode(name, string, flags)
+char_u *name;
+char_u *string;
+int flags;
+{
+ struct termcode *new_tc;
+ int i, j;
+ char_u *s;
+ int len;
+
+ if (string == NULL || *string == NUL) {
+ del_termcode(name);
+ return;
+ }
+
+ s = vim_strsave(string);
+ if (s == NULL)
+ return;
+
+ /* Change leading <Esc>[ to CSI, change <Esc>O to <M-O>. */
+ if (flags != 0 && flags != ATC_FROM_TERM && term_7to8bit(string) != 0) {
+ STRMOVE(s, s + 1);
+ s[0] = term_7to8bit(string);
+ }
+ len = (int)STRLEN(s);
+
+ need_gather = TRUE; /* need to fill termleader[] */
+
+ /*
+ * need to make space for more entries
+ */
+ if (tc_len == tc_max_len) {
+ tc_max_len += 20;
+ new_tc = (struct termcode *)alloc(
+ (unsigned)(tc_max_len * sizeof(struct termcode)));
+ if (new_tc == NULL) {
+ tc_max_len -= 20;
+ return;
+ }
+ for (i = 0; i < tc_len; ++i)
+ new_tc[i] = termcodes[i];
+ vim_free(termcodes);
+ termcodes = new_tc;
+ }
+
+ /*
+ * Look for existing entry with the same name, it is replaced.
+ * Look for an existing entry that is alphabetical higher, the new entry
+ * is inserted in front of it.
+ */
+ for (i = 0; i < tc_len; ++i) {
+ if (termcodes[i].name[0] < name[0])
+ continue;
+ if (termcodes[i].name[0] == name[0]) {
+ if (termcodes[i].name[1] < name[1])
+ continue;
+ /*
+ * Exact match: May replace old code.
+ */
+ if (termcodes[i].name[1] == name[1]) {
+ if (flags == ATC_FROM_TERM && (j = termcode_star(
+ termcodes[i].code,
+ termcodes[i].len)) > 0) {
+ /* Don't replace ESC[123;*X or ESC O*X with another when
+ * invoked from got_code_from_term(). */
+ if (len == termcodes[i].len - j
+ && STRNCMP(s, termcodes[i].code, len - 1) == 0
+ && s[len - 1]
+ == termcodes[i].code[termcodes[i].len - 1]) {
+ /* They are equal but for the ";*": don't add it. */
+ vim_free(s);
+ return;
+ }
+ } else {
+ /* Replace old code. */
+ vim_free(termcodes[i].code);
+ --tc_len;
+ break;
+ }
+ }
+ }
+ /*
+ * Found alphabetical larger entry, move rest to insert new entry
+ */
+ for (j = tc_len; j > i; --j)
+ termcodes[j] = termcodes[j - 1];
+ break;
+ }
+
+ termcodes[i].name[0] = name[0];
+ termcodes[i].name[1] = name[1];
+ termcodes[i].code = s;
+ termcodes[i].len = len;
+
+ /* For xterm we recognize special codes like "ESC[42;*X" and "ESC O*X" that
+ * accept modifiers. */
+ termcodes[i].modlen = 0;
+ j = termcode_star(s, len);
+ if (j > 0)
+ termcodes[i].modlen = len - 1 - j;
+ ++tc_len;
+}
+
+/*
+ * Check termcode "code[len]" for ending in ;*X, <Esc>O*X or <M-O>*X.
+ * The "X" can be any character.
+ * Return 0 if not found, 2 for ;*X and 1 for O*X and <M-O>*X.
+ */
+static int termcode_star(code, len)
+char_u *code;
+int len;
+{
+ /* Shortest is <M-O>*X. With ; shortest is <CSI>1;*X */
+ if (len >= 3 && code[len - 2] == '*') {
+ if (len >= 5 && code[len - 3] == ';')
+ return 2;
+ if ((len >= 4 && code[len - 3] == 'O') || code[len - 3] == 'O' + 128)
+ return 1;
+ }
+ return 0;
+}
+
+char_u * find_termcode(name)
+char_u *name;
+{
+ int i;
+
+ for (i = 0; i < tc_len; ++i)
+ if (termcodes[i].name[0] == name[0] && termcodes[i].name[1] == name[1])
+ return termcodes[i].code;
+ return NULL;
+}
+
+char_u * get_termcode(i)
+int i;
+{
+ if (i >= tc_len)
+ return NULL;
+ return &termcodes[i].name[0];
+}
+
+void del_termcode(name)
+char_u *name;
+{
+ int i;
+
+ if (termcodes == NULL) /* nothing there yet */
+ return;
+
+ need_gather = TRUE; /* need to fill termleader[] */
+
+ for (i = 0; i < tc_len; ++i)
+ if (termcodes[i].name[0] == name[0] && termcodes[i].name[1] == name[1]) {
+ del_termcode_idx(i);
+ return;
+ }
+ /* not found. Give error message? */
+}
+
+static void del_termcode_idx(idx)
+int idx;
+{
+ int i;
+
+ vim_free(termcodes[idx].code);
+ --tc_len;
+ for (i = idx; i < tc_len; ++i)
+ termcodes[i] = termcodes[i + 1];
+}
+
+/*
+ * Called when detected that the terminal sends 8-bit codes.
+ * Convert all 7-bit codes to their 8-bit equivalent.
+ */
+static void switch_to_8bit() {
+ int i;
+ int c;
+
+ /* Only need to do something when not already using 8-bit codes. */
+ if (!term_is_8bit(T_NAME)) {
+ for (i = 0; i < tc_len; ++i) {
+ c = term_7to8bit(termcodes[i].code);
+ if (c != 0) {
+ STRMOVE(termcodes[i].code + 1, termcodes[i].code + 2);
+ termcodes[i].code[0] = c;
+ }
+ }
+ need_gather = TRUE; /* need to fill termleader[] */
+ }
+ detected_8bit = TRUE;
+ LOG_TR("Switching to 8 bit");
+}
+
+#ifdef CHECK_DOUBLE_CLICK
+static linenr_T orig_topline = 0;
+static int orig_topfill = 0;
+#endif
+#if (defined(FEAT_WINDOWS) && defined(CHECK_DOUBLE_CLICK)) || defined(PROTO)
+/*
+ * Checking for double clicks ourselves.
+ * "orig_topline" is used to avoid detecting a double-click when the window
+ * contents scrolled (e.g., when 'scrolloff' is non-zero).
+ */
+/*
+ * Set orig_topline. Used when jumping to another window, so that a double
+ * click still works.
+ */
+void set_mouse_topline(wp)
+win_T *wp;
+{
+ orig_topline = wp->w_topline;
+ orig_topfill = wp->w_topfill;
+}
+#endif
+
+/*
+ * Check if typebuf.tb_buf[] contains a terminal key code.
+ * Check from typebuf.tb_buf[typebuf.tb_off] to typebuf.tb_buf[typebuf.tb_off
+ * + max_offset].
+ * Return 0 for no match, -1 for partial match, > 0 for full match.
+ * Return KEYLEN_REMOVED when a key code was deleted.
+ * With a match, the match is removed, the replacement code is inserted in
+ * typebuf.tb_buf[] and the number of characters in typebuf.tb_buf[] is
+ * returned.
+ * When "buf" is not NULL, buf[bufsize] is used instead of typebuf.tb_buf[].
+ * "buflen" is then the length of the string in buf[] and is updated for
+ * inserts and deletes.
+ */
+int check_termcode(max_offset, buf, bufsize, buflen)
+int max_offset;
+char_u *buf;
+int bufsize;
+int *buflen;
+{
+ char_u *tp;
+ char_u *p;
+ int slen = 0; /* init for GCC */
+ int modslen;
+ int len;
+ int retval = 0;
+ int offset;
+ char_u key_name[2];
+ int modifiers;
+ int key;
+ int new_slen;
+ int extra;
+ char_u string[MAX_KEY_CODE_LEN + 1];
+ int i, j;
+ int idx = 0;
+# if !defined(UNIX) || defined(FEAT_MOUSE_XTERM) || defined(FEAT_GUI) \
+ || defined(FEAT_MOUSE_GPM) || defined(FEAT_SYSMOUSE)
+ char_u bytes[6];
+ int num_bytes;
+# endif
+ int mouse_code = 0; /* init for GCC */
+ int is_click, is_drag;
+ int wheel_code = 0;
+ int current_button;
+ static int held_button = MOUSE_RELEASE;
+ static int orig_num_clicks = 1;
+ static int orig_mouse_code = 0x0;
+# ifdef CHECK_DOUBLE_CLICK
+ static int orig_mouse_col = 0;
+ static int orig_mouse_row = 0;
+ static struct timeval orig_mouse_time = {0, 0};
+ /* time of previous mouse click */
+ struct timeval mouse_time; /* time of current mouse click */
+ long timediff; /* elapsed time in msec */
+# endif
+ int cpo_koffset;
+
+ cpo_koffset = (vim_strchr(p_cpo, CPO_KOFFSET) != NULL);
+
+ /*
+ * Speed up the checks for terminal codes by gathering all first bytes
+ * used in termleader[]. Often this is just a single <Esc>.
+ */
+ if (need_gather)
+ gather_termleader();
+
+ /*
+ * Check at several positions in typebuf.tb_buf[], to catch something like
+ * "x<Up>" that can be mapped. Stop at max_offset, because characters
+ * after that cannot be used for mapping, and with @r commands
+ * typebuf.tb_buf[] can become very long.
+ * This is used often, KEEP IT FAST!
+ */
+ for (offset = 0; offset < max_offset; ++offset) {
+ if (buf == NULL) {
+ if (offset >= typebuf.tb_len)
+ break;
+ tp = typebuf.tb_buf + typebuf.tb_off + offset;
+ len = typebuf.tb_len - offset; /* length of the input */
+ } else {
+ if (offset >= *buflen)
+ break;
+ tp = buf + offset;
+ len = *buflen - offset;
+ }
+
+ /*
+ * Don't check characters after K_SPECIAL, those are already
+ * translated terminal chars (avoid translating ~@^Hx).
+ */
+ if (*tp == K_SPECIAL) {
+ offset += 2; /* there are always 2 extra characters */
+ continue;
+ }
+
+ /*
+ * Skip this position if the character does not appear as the first
+ * character in term_strings. This speeds up a lot, since most
+ * termcodes start with the same character (ESC or CSI).
+ */
+ i = *tp;
+ for (p = termleader; *p && *p != i; ++p)
+ ;
+ if (*p == NUL)
+ continue;
+
+ /*
+ * Skip this position if p_ek is not set and tp[0] is an ESC and we
+ * are in Insert mode.
+ */
+ if (*tp == ESC && !p_ek && (State & INSERT))
+ continue;
+
+ key_name[0] = NUL; /* no key name found yet */
+ key_name[1] = NUL; /* no key name found yet */
+ modifiers = 0; /* no modifiers yet */
+
+ {
+ for (idx = 0; idx < tc_len; ++idx) {
+ /*
+ * Ignore the entry if we are not at the start of
+ * typebuf.tb_buf[]
+ * and there are not enough characters to make a match.
+ * But only when the 'K' flag is in 'cpoptions'.
+ */
+ slen = termcodes[idx].len;
+ if (cpo_koffset && offset && len < slen)
+ continue;
+ if (STRNCMP(termcodes[idx].code, tp,
+ (size_t)(slen > len ? len : slen)) == 0) {
+ if (len < slen) /* got a partial sequence */
+ return -1; /* need to get more chars */
+
+ /*
+ * When found a keypad key, check if there is another key
+ * that matches and use that one. This makes <Home> to be
+ * found instead of <kHome> when they produce the same
+ * key code.
+ */
+ if (termcodes[idx].name[0] == 'K'
+ && VIM_ISDIGIT(termcodes[idx].name[1])) {
+ for (j = idx + 1; j < tc_len; ++j)
+ if (termcodes[j].len == slen &&
+ STRNCMP(termcodes[idx].code,
+ termcodes[j].code, slen) == 0) {
+ idx = j;
+ break;
+ }
+ }
+
+ key_name[0] = termcodes[idx].name[0];
+ key_name[1] = termcodes[idx].name[1];
+ break;
+ }
+
+ /*
+ * Check for code with modifier, like xterm uses:
+ * <Esc>[123;*X (modslen == slen - 3)
+ * Also <Esc>O*X and <M-O>*X (modslen == slen - 2).
+ * When there is a modifier the * matches a number.
+ * When there is no modifier the ;* or * is omitted.
+ */
+ if (termcodes[idx].modlen > 0) {
+ modslen = termcodes[idx].modlen;
+ if (cpo_koffset && offset && len < modslen)
+ continue;
+ if (STRNCMP(termcodes[idx].code, tp,
+ (size_t)(modslen > len ? len : modslen)) == 0) {
+ int n;
+
+ if (len <= modslen) /* got a partial sequence */
+ return -1; /* need to get more chars */
+
+ if (tp[modslen] == termcodes[idx].code[slen - 1])
+ slen = modslen + 1; /* no modifiers */
+ else if (tp[modslen] != ';' && modslen == slen - 3)
+ continue; /* no match */
+ else {
+ /* Skip over the digits, the final char must
+ * follow. */
+ for (j = slen - 2; j < len && isdigit(tp[j]); ++j)
+ ;
+ ++j;
+ if (len < j) /* got a partial sequence */
+ return -1; /* need to get more chars */
+ if (tp[j - 1] != termcodes[idx].code[slen - 1])
+ continue; /* no match */
+
+ /* Match! Convert modifier bits. */
+ n = atoi((char *)tp + slen - 2) - 1;
+ if (n & 1)
+ modifiers |= MOD_MASK_SHIFT;
+ if (n & 2)
+ modifiers |= MOD_MASK_ALT;
+ if (n & 4)
+ modifiers |= MOD_MASK_CTRL;
+ if (n & 8)
+ modifiers |= MOD_MASK_META;
+
+ slen = j;
+ }
+ key_name[0] = termcodes[idx].name[0];
+ key_name[1] = termcodes[idx].name[1];
+ break;
+ }
+ }
+ }
+ }
+
+ if (key_name[0] == NUL
+ /* URXVT mouse uses <ESC>[#;#;#M, but we are matching <ESC>[ */
+ || key_name[0] == KS_URXVT_MOUSE
+ || u7_status == U7_SENT
+ ) {
+ /* Check for some responses from terminal start with "<Esc>[" or
+ * CSI.
+ *
+ * - xterm version string: <Esc>[>{x};{vers};{y}c
+ * Also eat other possible responses to t_RV, rxvt returns
+ * "<Esc>[?1;2c". Also accept CSI instead of <Esc>[.
+ * mrxvt has been reported to have "+" in the version. Assume
+ * the escape sequence ends with a letter or one of "{|}~".
+ *
+ * - cursor position report: <Esc>[{row};{col}R
+ * The final byte is 'R'. now it is only used for checking for
+ * ambiguous-width character state.
+ */
+ p = tp[0] == CSI ? tp + 1 : tp + 2;
+ if ((*T_CRV != NUL || *T_U7 != NUL)
+ && ((tp[0] == ESC && tp[1] == '[' && len >= 3)
+ || (tp[0] == CSI && len >= 2))
+ && (VIM_ISDIGIT(*p) || *p == '>' || *p == '?')) {
+ j = 0;
+ extra = 0;
+ for (i = 2 + (tp[0] != CSI); i < len
+ && !(tp[i] >= '{' && tp[i] <= '~')
+ && !ASCII_ISALPHA(tp[i]); ++i)
+ if (tp[i] == ';' && ++j == 1)
+ extra = i + 1;
+ if (i == len) {
+ LOG_TR("Not enough characters for CRV");
+ return -1;
+ }
+
+ /* Eat it when it has 2 arguments and ends in 'R'. Ignore it
+ * when u7_status is not "sent", <S-F3> sends something
+ * similar. */
+ if (j == 1 && tp[i] == 'R' && u7_status == U7_SENT) {
+ char *aw = NULL;
+
+ LOG_TR("Received U7 status");
+ u7_status = U7_GOT;
+ did_cursorhold = TRUE;
+ if (extra > 0)
+ extra = atoi((char *)tp + extra);
+ if (extra == 2)
+ aw = "single";
+ else if (extra == 3)
+ aw = "double";
+ if (aw != NULL && STRCMP(aw, p_ambw) != 0) {
+ /* Setting the option causes a screen redraw. Do that
+ * right away if possible, keeping any messages. */
+ set_option_value((char_u *)"ambw", 0L, (char_u *)aw, 0);
+#ifdef DEBUG_TERMRESPONSE
+ {
+ char buf[100];
+ int r = redraw_asap(CLEAR);
+
+ sprintf(buf, "set 'ambiwidth', redraw_asap(): %d",
+ r);
+ log_tr(buf);
+ }
+#else
+ redraw_asap(CLEAR);
+#endif
+ }
+ key_name[0] = (int)KS_EXTRA;
+ key_name[1] = (int)KE_IGNORE;
+ slen = i + 1;
+ } else
+ /* eat it when at least one digit and ending in 'c' */
+ if (*T_CRV != NUL && i > 2 + (tp[0] != CSI) && tp[i] == 'c') {
+ LOG_TR("Received CRV");
+ crv_status = CRV_GOT;
+ did_cursorhold = TRUE;
+
+ /* If this code starts with CSI, you can bet that the
+ * terminal uses 8-bit codes. */
+ if (tp[0] == CSI)
+ switch_to_8bit();
+
+ /* rxvt sends its version number: "20703" is 2.7.3.
+ * Ignore it for when the user has set 'term' to xterm,
+ * even though it's an rxvt. */
+ if (extra > 0)
+ extra = atoi((char *)tp + extra);
+ if (extra > 20000)
+ extra = 0;
+
+ if (tp[1 + (tp[0] != CSI)] == '>' && j == 2) {
+ /* Only set 'ttymouse' automatically if it was not set
+ * by the user already. */
+ if (!option_was_set((char_u *)"ttym")) {
+# ifdef TTYM_SGR
+ if (extra >= 277)
+ set_option_value((char_u *)"ttym", 0L,
+ (char_u *)"sgr", 0);
+ else
+# endif
+ /* if xterm version >= 95 use mouse dragging */
+ if (extra >= 95)
+ set_option_value((char_u *)"ttym", 0L,
+ (char_u *)"xterm2", 0);
+ }
+
+ /* if xterm version >= 141 try to get termcap codes */
+ if (extra >= 141) {
+ LOG_TR("Enable checking for XT codes");
+ check_for_codes = TRUE;
+ need_gather = TRUE;
+ req_codes_from_term();
+ }
+ }
+ set_vim_var_string(VV_TERMRESPONSE, tp, i + 1);
+ apply_autocmds(EVENT_TERMRESPONSE,
+ NULL, NULL, FALSE, curbuf);
+ key_name[0] = (int)KS_EXTRA;
+ key_name[1] = (int)KE_IGNORE;
+ slen = i + 1;
+ }
+ }
+ /* Check for '<Esc>P1+r<hex bytes><Esc>\'. A "0" instead of the
+ * "1" means an invalid request. */
+ else if (check_for_codes
+ && ((tp[0] == ESC && tp[1] == 'P' && len >= 2)
+ || tp[0] == DCS)) {
+ j = 1 + (tp[0] != DCS);
+ for (i = j; i < len; ++i)
+ if ((tp[i] == ESC && tp[i + 1] == '\\' && i + 1 < len)
+ || tp[i] == STERM) {
+ if (i - j >= 3 && tp[j + 1] == '+' && tp[j + 2] == 'r')
+ got_code_from_term(tp + j, i);
+ key_name[0] = (int)KS_EXTRA;
+ key_name[1] = (int)KE_IGNORE;
+ slen = i + 1 + (tp[i] == ESC);
+ break;
+ }
+
+ if (i == len) {
+ LOG_TR("not enough characters for XT");
+ return -1; /* not enough characters */
+ }
+ }
+ }
+
+ if (key_name[0] == NUL)
+ continue; /* No match at this position, try next one */
+
+ /* We only get here when we have a complete termcode match */
+
+ /*
+ * If it is a mouse click, get the coordinates.
+ */
+ if (key_name[0] == KS_MOUSE
+# ifdef FEAT_MOUSE_JSB
+ || key_name[0] == KS_JSBTERM_MOUSE
+# endif
+ || key_name[0] == KS_NETTERM_MOUSE
+ || key_name[0] == KS_DEC_MOUSE
+ || key_name[0] == KS_URXVT_MOUSE
+ || key_name[0] == KS_SGR_MOUSE
+ ) {
+ is_click = is_drag = FALSE;
+
+# if !defined(UNIX) || defined(FEAT_MOUSE_XTERM) || defined(FEAT_GUI) \
+ || defined(FEAT_MOUSE_GPM) || defined(FEAT_SYSMOUSE)
+ if (key_name[0] == (int)KS_MOUSE) {
+ /*
+ * For xterm and MSDOS we get "<t_mouse>scr", where
+ * s == encoded button state:
+ * 0x20 = left button down
+ * 0x21 = middle button down
+ * 0x22 = right button down
+ * 0x23 = any button release
+ * 0x60 = button 4 down (scroll wheel down)
+ * 0x61 = button 5 down (scroll wheel up)
+ * add 0x04 for SHIFT
+ * add 0x08 for ALT
+ * add 0x10 for CTRL
+ * add 0x20 for mouse drag (0x40 is drag with left button)
+ * c == column + ' ' + 1 == column + 33
+ * r == row + ' ' + 1 == row + 33
+ *
+ * The coordinates are passed on through global variables.
+ * Ugly, but this avoids trouble with mouse clicks at an
+ * unexpected moment and allows for mapping them.
+ */
+ for (;; ) {
+ {
+ num_bytes = get_bytes_from_buf(tp + slen, bytes, 3);
+ if (num_bytes == -1) /* not enough coordinates */
+ return -1;
+ mouse_code = bytes[0];
+ mouse_col = bytes[1] - ' ' - 1;
+ mouse_row = bytes[2] - ' ' - 1;
+ }
+ slen += num_bytes;
+
+ /* If the following bytes is also a mouse code and it has
+ * the same code, dump this one and get the next. This
+ * makes dragging a whole lot faster. */
+ j = termcodes[idx].len;
+ if (STRNCMP(tp, tp + slen, (size_t)j) == 0
+ && tp[slen + j] == mouse_code
+ && tp[slen + j + 1] != NUL
+ && tp[slen + j + 2] != NUL
+ )
+ slen += j;
+ else
+ break;
+ }
+ }
+
+ if (key_name[0] == KS_URXVT_MOUSE
+ || key_name[0] == KS_SGR_MOUSE) {
+ for (;; ) {
+ /* URXVT 1015 mouse reporting mode:
+ * Almost identical to xterm mouse mode, except the values
+ * are decimal instead of bytes.
+ *
+ * \033[%d;%d;%dM
+ * ^-- row
+ * ^----- column
+ * ^-------- code
+ *
+ * SGR 1006 mouse reporting mode:
+ * Almost identical to xterm mouse mode, except the values
+ * are decimal instead of bytes.
+ *
+ * \033[<%d;%d;%dM
+ * ^-- row
+ * ^----- column
+ * ^-------- code
+ *
+ * \033[<%d;%d;%dm : mouse release event
+ * ^-- row
+ * ^----- column
+ * ^-------- code
+ */
+ p = tp + slen;
+
+ mouse_code = getdigits(&p);
+ if (*p++ != ';')
+ return -1;
+
+ /* when mouse reporting is SGR, add 32 to mouse code */
+ if (key_name[0] == KS_SGR_MOUSE)
+ mouse_code += 32;
+
+ mouse_col = getdigits(&p) - 1;
+ if (*p++ != ';')
+ return -1;
+
+ mouse_row = getdigits(&p) - 1;
+ if (key_name[0] == KS_SGR_MOUSE && *p == 'm')
+ mouse_code |= MOUSE_RELEASE;
+ else if (*p != 'M')
+ return -1;
+ p++;
+
+ slen += (int)(p - (tp + slen));
+
+ /* skip this one if next one has same code (like xterm
+ * case) */
+ j = termcodes[idx].len;
+ if (STRNCMP(tp, tp + slen, (size_t)j) == 0) {
+ int slen2;
+ int cmd_complete = 0;
+
+ /* check if the command is complete by looking for the
+ * 'M' */
+ for (slen2 = slen; slen2 < len; slen2++) {
+ if (tp[slen2] == 'M'
+ || (key_name[0] == KS_SGR_MOUSE
+ && tp[slen2] == 'm')) {
+ cmd_complete = 1;
+ break;
+ }
+ }
+ p += j;
+ if (cmd_complete && getdigits(&p) == mouse_code) {
+ slen += j; /* skip the \033[ */
+ continue;
+ }
+ }
+ break;
+ }
+ }
+
+ if (key_name[0] == (int)KS_MOUSE
+ || key_name[0] == (int)KS_URXVT_MOUSE
+ || key_name[0] == KS_SGR_MOUSE
+ ) {
+ /*
+ * Handle mouse events.
+ * Recognize the xterm mouse wheel, but not in the GUI, the
+ * Linux console with GPM and the MS-DOS or Win32 console
+ * (multi-clicks use >= 0x60).
+ */
+ if (mouse_code >= MOUSEWHEEL_LOW
+ ) {
+ /* Keep the mouse_code before it's changed, so that we
+ * remember that it was a mouse wheel click. */
+ wheel_code = mouse_code;
+ } else if (held_button == MOUSE_RELEASE
+ && (mouse_code == 0x23 || mouse_code == 0x24)) {
+ /* Apparently used by rxvt scroll wheel. */
+ wheel_code = mouse_code - 0x23 + MOUSEWHEEL_LOW;
+ }
+
+# if defined(UNIX) && defined(FEAT_MOUSE_TTY)
+ else if (use_xterm_mouse() > 1) {
+ if (mouse_code & MOUSE_DRAG_XTERM)
+ mouse_code |= MOUSE_DRAG;
+ }
+# endif
+ }
+# endif /* !UNIX || FEAT_MOUSE_XTERM */
+ if (key_name[0] == (int)KS_NETTERM_MOUSE) {
+ int mc, mr;
+
+ /* expect a rather limited sequence like: balancing {
+ * \033}6,45\r
+ * '6' is the row, 45 is the column
+ */
+ p = tp + slen;
+ mr = getdigits(&p);
+ if (*p++ != ',')
+ return -1;
+ mc = getdigits(&p);
+ if (*p++ != '\r')
+ return -1;
+
+ mouse_col = mc - 1;
+ mouse_row = mr - 1;
+ mouse_code = MOUSE_LEFT;
+ slen += (int)(p - (tp + slen));
+ }
+# ifdef FEAT_MOUSE_JSB
+ if (key_name[0] == (int)KS_JSBTERM_MOUSE) {
+ int mult, val, iter, button, status;
+
+ /* JSBTERM Input Model
+ * \033[0~zw uniq escape sequence
+ * (L-x) Left button pressed - not pressed x not reporting
+ * (M-x) Middle button pressed - not pressed x not reporting
+ * (R-x) Right button pressed - not pressed x not reporting
+ * (SDmdu) Single , Double click, m mouse move d button down
+ * u button up
+ * ### X cursor position padded to 3 digits
+ * ### Y cursor position padded to 3 digits
+ * (s-x) SHIFT key pressed - not pressed x not reporting
+ * (c-x) CTRL key pressed - not pressed x not reporting
+ * \033\\ terminating sequence
+ */
+
+ p = tp + slen;
+ button = mouse_code = 0;
+ switch (*p++) {
+ case 'L': button = 1; break;
+ case '-': break;
+ case 'x': break; /* ignore sequence */
+ default: return -1; /* Unknown Result */
+ }
+ switch (*p++) {
+ case 'M': button |= 2; break;
+ case '-': break;
+ case 'x': break; /* ignore sequence */
+ default: return -1; /* Unknown Result */
+ }
+ switch (*p++) {
+ case 'R': button |= 4; break;
+ case '-': break;
+ case 'x': break; /* ignore sequence */
+ default: return -1; /* Unknown Result */
+ }
+ status = *p++;
+ for (val = 0, mult = 100, iter = 0; iter < 3; iter++,
+ mult /= 10, p++)
+ if (*p >= '0' && *p <= '9')
+ val += (*p - '0') * mult;
+ else
+ return -1;
+ mouse_col = val;
+ for (val = 0, mult = 100, iter = 0; iter < 3; iter++,
+ mult /= 10, p++)
+ if (*p >= '0' && *p <= '9')
+ val += (*p - '0') * mult;
+ else
+ return -1;
+ mouse_row = val;
+ switch (*p++) {
+ case 's': button |= 8; break; /* SHIFT key Pressed */
+ case '-': break; /* Not Pressed */
+ case 'x': break; /* Not Reporting */
+ default: return -1; /* Unknown Result */
+ }
+ switch (*p++) {
+ case 'c': button |= 16; break; /* CTRL key Pressed */
+ case '-': break; /* Not Pressed */
+ case 'x': break; /* Not Reporting */
+ default: return -1; /* Unknown Result */
+ }
+ if (*p++ != '\033')
+ return -1;
+ if (*p++ != '\\')
+ return -1;
+ switch (status) {
+ case 'D': /* Double Click */
+ case 'S': /* Single Click */
+ if (button & 1) mouse_code |= MOUSE_LEFT;
+ if (button & 2) mouse_code |= MOUSE_MIDDLE;
+ if (button & 4) mouse_code |= MOUSE_RIGHT;
+ if (button & 8) mouse_code |= MOUSE_SHIFT;
+ if (button & 16) mouse_code |= MOUSE_CTRL;
+ break;
+ case 'm': /* Mouse move */
+ if (button & 1) mouse_code |= MOUSE_LEFT;
+ if (button & 2) mouse_code |= MOUSE_MIDDLE;
+ if (button & 4) mouse_code |= MOUSE_RIGHT;
+ if (button & 8) mouse_code |= MOUSE_SHIFT;
+ if (button & 16) mouse_code |= MOUSE_CTRL;
+ if ((button & 7) != 0) {
+ held_button = mouse_code;
+ mouse_code |= MOUSE_DRAG;
+ }
+ is_drag = TRUE;
+ showmode();
+ break;
+ case 'd': /* Button Down */
+ if (button & 1) mouse_code |= MOUSE_LEFT;
+ if (button & 2) mouse_code |= MOUSE_MIDDLE;
+ if (button & 4) mouse_code |= MOUSE_RIGHT;
+ if (button & 8) mouse_code |= MOUSE_SHIFT;
+ if (button & 16) mouse_code |= MOUSE_CTRL;
+ break;
+ case 'u': /* Button Up */
+ if (button & 1)
+ mouse_code |= MOUSE_LEFT | MOUSE_RELEASE;
+ if (button & 2)
+ mouse_code |= MOUSE_MIDDLE | MOUSE_RELEASE;
+ if (button & 4)
+ mouse_code |= MOUSE_RIGHT | MOUSE_RELEASE;
+ if (button & 8)
+ mouse_code |= MOUSE_SHIFT;
+ if (button & 16)
+ mouse_code |= MOUSE_CTRL;
+ break;
+ default: return -1; /* Unknown Result */
+ }
+
+ slen += (p - (tp + slen));
+ }
+# endif /* FEAT_MOUSE_JSB */
+ if (key_name[0] == (int)KS_DEC_MOUSE) {
+ /* The DEC Locator Input Model
+ * Netterm delivers the code sequence:
+ * \033[2;4;24;80&w (left button down)
+ * \033[3;0;24;80&w (left button up)
+ * \033[6;1;24;80&w (right button down)
+ * \033[7;0;24;80&w (right button up)
+ * CSI Pe ; Pb ; Pr ; Pc ; Pp & w
+ * Pe is the event code
+ * Pb is the button code
+ * Pr is the row coordinate
+ * Pc is the column coordinate
+ * Pp is the third coordinate (page number)
+ * Pe, the event code indicates what event caused this report
+ * The following event codes are defined:
+ * 0 - request, the terminal received an explicit request
+ * for a locator report, but the locator is unavailable
+ * 1 - request, the terminal received an explicit request
+ * for a locator report
+ * 2 - left button down
+ * 3 - left button up
+ * 4 - middle button down
+ * 5 - middle button up
+ * 6 - right button down
+ * 7 - right button up
+ * 8 - fourth button down
+ * 9 - fourth button up
+ * 10 - locator outside filter rectangle
+ * Pb, the button code, ASCII decimal 0-15 indicating which
+ * buttons are down if any. The state of the four buttons
+ * on the locator correspond to the low four bits of the
+ * decimal value,
+ * "1" means button depressed
+ * 0 - no buttons down,
+ * 1 - right,
+ * 2 - middle,
+ * 4 - left,
+ * 8 - fourth
+ * Pr is the row coordinate of the locator position in the page,
+ * encoded as an ASCII decimal value.
+ * If Pr is omitted, the locator position is undefined
+ * (outside the terminal window for example).
+ * Pc is the column coordinate of the locator position in the
+ * page, encoded as an ASCII decimal value.
+ * If Pc is omitted, the locator position is undefined
+ * (outside the terminal window for example).
+ * Pp is the page coordinate of the locator position
+ * encoded as an ASCII decimal value.
+ * The page coordinate may be omitted if the locator is on
+ * page one (the default). We ignore it anyway.
+ */
+ int Pe, Pb, Pr, Pc;
+
+ p = tp + slen;
+
+ /* get event status */
+ Pe = getdigits(&p);
+ if (*p++ != ';')
+ return -1;
+
+ /* get button status */
+ Pb = getdigits(&p);
+ if (*p++ != ';')
+ return -1;
+
+ /* get row status */
+ Pr = getdigits(&p);
+ if (*p++ != ';')
+ return -1;
+
+ /* get column status */
+ Pc = getdigits(&p);
+
+ /* the page parameter is optional */
+ if (*p == ';') {
+ p++;
+ (void)getdigits(&p);
+ }
+ if (*p++ != '&')
+ return -1;
+ if (*p++ != 'w')
+ return -1;
+
+ mouse_code = 0;
+ switch (Pe) {
+ case 0: return -1; /* position request while unavailable */
+ case 1: /* a response to a locator position request includes
+ the status of all buttons */
+ Pb &= 7; /* mask off and ignore fourth button */
+ if (Pb & 4)
+ mouse_code = MOUSE_LEFT;
+ if (Pb & 2)
+ mouse_code = MOUSE_MIDDLE;
+ if (Pb & 1)
+ mouse_code = MOUSE_RIGHT;
+ if (Pb) {
+ held_button = mouse_code;
+ mouse_code |= MOUSE_DRAG;
+ WantQueryMouse = TRUE;
+ }
+ is_drag = TRUE;
+ showmode();
+ break;
+ case 2: mouse_code = MOUSE_LEFT;
+ WantQueryMouse = TRUE;
+ break;
+ case 3: mouse_code = MOUSE_RELEASE | MOUSE_LEFT;
+ break;
+ case 4: mouse_code = MOUSE_MIDDLE;
+ WantQueryMouse = TRUE;
+ break;
+ case 5: mouse_code = MOUSE_RELEASE | MOUSE_MIDDLE;
+ break;
+ case 6: mouse_code = MOUSE_RIGHT;
+ WantQueryMouse = TRUE;
+ break;
+ case 7: mouse_code = MOUSE_RELEASE | MOUSE_RIGHT;
+ break;
+ case 8: return -1; /* fourth button down */
+ case 9: return -1; /* fourth button up */
+ case 10: return -1; /* mouse outside of filter rectangle */
+ default: return -1; /* should never occur */
+ }
+
+ mouse_col = Pc - 1;
+ mouse_row = Pr - 1;
+
+ slen += (int)(p - (tp + slen));
+ }
+
+ /* Interpret the mouse code */
+ current_button = (mouse_code & MOUSE_CLICK_MASK);
+ if (current_button == MOUSE_RELEASE
+ && wheel_code == 0
+ ) {
+ /*
+ * If we get a mouse drag or release event when
+ * there is no mouse button held down (held_button ==
+ * MOUSE_RELEASE), produce a K_IGNORE below.
+ * (can happen when you hold down two buttons
+ * and then let them go, or click in the menu bar, but not
+ * on a menu, and drag into the text).
+ */
+ if ((mouse_code & MOUSE_DRAG) == MOUSE_DRAG)
+ is_drag = TRUE;
+ current_button = held_button;
+ } else if (wheel_code == 0) {
+# ifdef CHECK_DOUBLE_CLICK
+ {
+ /*
+ * Compute the time elapsed since the previous mouse click.
+ */
+ gettimeofday(&mouse_time, NULL);
+ timediff = (mouse_time.tv_usec
+ - orig_mouse_time.tv_usec) / 1000;
+ if (timediff < 0)
+ --orig_mouse_time.tv_sec;
+ timediff += (mouse_time.tv_sec
+ - orig_mouse_time.tv_sec) * 1000;
+ orig_mouse_time = mouse_time;
+ if (mouse_code == orig_mouse_code
+ && timediff < p_mouset
+ && orig_num_clicks != 4
+ && orig_mouse_col == mouse_col
+ && orig_mouse_row == mouse_row
+ && ((orig_topline == curwin->w_topline
+ && orig_topfill == curwin->w_topfill
+ )
+ /* Double click in tab pages line also works
+ * when window contents changes. */
+ || (mouse_row == 0 && firstwin->w_winrow > 0)
+ )
+ )
+ ++orig_num_clicks;
+ else
+ orig_num_clicks = 1;
+ orig_mouse_col = mouse_col;
+ orig_mouse_row = mouse_row;
+ orig_topline = curwin->w_topline;
+ orig_topfill = curwin->w_topfill;
+ }
+# else
+ orig_num_clicks = NUM_MOUSE_CLICKS(mouse_code);
+# endif
+ is_click = TRUE;
+ orig_mouse_code = mouse_code;
+ }
+ if (!is_drag)
+ held_button = mouse_code & MOUSE_CLICK_MASK;
+
+ /*
+ * Translate the actual mouse event into a pseudo mouse event.
+ * First work out what modifiers are to be used.
+ */
+ if (orig_mouse_code & MOUSE_SHIFT)
+ modifiers |= MOD_MASK_SHIFT;
+ if (orig_mouse_code & MOUSE_CTRL)
+ modifiers |= MOD_MASK_CTRL;
+ if (orig_mouse_code & MOUSE_ALT)
+ modifiers |= MOD_MASK_ALT;
+ if (orig_num_clicks == 2)
+ modifiers |= MOD_MASK_2CLICK;
+ else if (orig_num_clicks == 3)
+ modifiers |= MOD_MASK_3CLICK;
+ else if (orig_num_clicks == 4)
+ modifiers |= MOD_MASK_4CLICK;
+
+ /* Work out our pseudo mouse event */
+ key_name[0] = (int)KS_EXTRA;
+ if (wheel_code != 0) {
+ if (wheel_code & MOUSE_CTRL)
+ modifiers |= MOD_MASK_CTRL;
+ if (wheel_code & MOUSE_ALT)
+ modifiers |= MOD_MASK_ALT;
+ key_name[1] = (wheel_code & 1)
+ ? (int)KE_MOUSEUP : (int)KE_MOUSEDOWN;
+ } else
+ key_name[1] = get_pseudo_mouse_code(current_button,
+ is_click, is_drag);
+ }
+
+
+ /*
+ * Change <xHome> to <Home>, <xUp> to <Up>, etc.
+ */
+ key = handle_x_keys(TERMCAP2KEY(key_name[0], key_name[1]));
+
+ /*
+ * Add any modifier codes to our string.
+ */
+ new_slen = 0; /* Length of what will replace the termcode */
+ if (modifiers != 0) {
+ /* Some keys have the modifier included. Need to handle that here
+ * to make mappings work. */
+ key = simplify_key(key, &modifiers);
+ if (modifiers != 0) {
+ string[new_slen++] = K_SPECIAL;
+ string[new_slen++] = (int)KS_MODIFIER;
+ string[new_slen++] = modifiers;
+ }
+ }
+
+ /* Finally, add the special key code to our string */
+ key_name[0] = KEY2TERMCAP0(key);
+ key_name[1] = KEY2TERMCAP1(key);
+ if (key_name[0] == KS_KEY) {
+ /* from ":set <M-b>=xx" */
+ if (has_mbyte)
+ new_slen += (*mb_char2bytes)(key_name[1], string + new_slen);
+ else
+ string[new_slen++] = key_name[1];
+ } else if (new_slen == 0 && key_name[0] == KS_EXTRA
+ && key_name[1] == KE_IGNORE) {
+ /* Do not put K_IGNORE into the buffer, do return KEYLEN_REMOVED
+ * to indicate what happened. */
+ retval = KEYLEN_REMOVED;
+ } else {
+ string[new_slen++] = K_SPECIAL;
+ string[new_slen++] = key_name[0];
+ string[new_slen++] = key_name[1];
+ }
+ string[new_slen] = NUL;
+ extra = new_slen - slen;
+ if (buf == NULL) {
+ if (extra < 0)
+ /* remove matched chars, taking care of noremap */
+ del_typebuf(-extra, offset);
+ else if (extra > 0)
+ /* insert the extra space we need */
+ ins_typebuf(string + slen, REMAP_YES, offset, FALSE, FALSE);
+
+ /*
+ * Careful: del_typebuf() and ins_typebuf() may have reallocated
+ * typebuf.tb_buf[]!
+ */
+ mch_memmove(typebuf.tb_buf + typebuf.tb_off + offset, string,
+ (size_t)new_slen);
+ } else {
+ if (extra < 0)
+ /* remove matched characters */
+ mch_memmove(buf + offset, buf + offset - extra,
+ (size_t)(*buflen + offset + extra));
+ else if (extra > 0) {
+ /* Insert the extra space we need. If there is insufficient
+ * space return -1. */
+ if (*buflen + extra + new_slen >= bufsize)
+ return -1;
+ mch_memmove(buf + offset + extra, buf + offset,
+ (size_t)(*buflen - offset));
+ }
+ mch_memmove(buf + offset, string, (size_t)new_slen);
+ *buflen = *buflen + extra + new_slen;
+ }
+ return retval == 0 ? (len + extra + offset) : retval;
+ }
+
+ LOG_TR("normal character");
+
+ return 0; /* no match found */
+}
+
+/*
+ * Replace any terminal code strings in from[] with the equivalent internal
+ * vim representation. This is 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 KS_SPECIAL KE_FILLER.
+ *
+ * The replacement is done in result[] and finally copied into allocated
+ * memory. If this all works well *bufp is set to the allocated memory and a
+ * pointer to it is returned. If something fails *bufp is set to NULL and from
+ * is returned.
+ *
+ * CTRL-V characters are removed. When "from_part" is TRUE, a trailing CTRL-V
+ * is included, otherwise it is removed (for ":map xx ^V", maps xx to
+ * nothing). When 'cpoptions' does not contain 'B', a backslash can be used
+ * instead of a CTRL-V.
+ */
+char_u * replace_termcodes(from, bufp, from_part, do_lt, special)
+char_u *from;
+char_u **bufp;
+int from_part;
+int do_lt; /* also translate <lt> */
+int special; /* always accept <key> notation */
+{
+ int i;
+ int slen;
+ int key;
+ int dlen = 0;
+ char_u *src;
+ int do_backslash; /* backslash is a special character */
+ int do_special; /* recognize <> key codes */
+ int do_key_code; /* recognize raw key codes */
+ char_u *result; /* buffer for resulting string */
+
+ do_backslash = (vim_strchr(p_cpo, CPO_BSLASH) == NULL);
+ do_special = (vim_strchr(p_cpo, CPO_SPECI) == NULL) || special;
+ do_key_code = (vim_strchr(p_cpo, CPO_KEYCODE) == NULL);
+
+ /*
+ * Allocate space for the translation. Worst case a single character is
+ * replaced by 6 bytes (shifted special key), plus a NUL at the end.
+ */
+ result = alloc((unsigned)STRLEN(from) * 6 + 1);
+ if (result == NULL) { /* out of memory */
+ *bufp = NULL;
+ return from;
+ }
+
+ src = from;
+
+ /*
+ * Check for #n at start only: function key n
+ */
+ if (from_part && src[0] == '#' && VIM_ISDIGIT(src[1])) { /* function key */
+ result[dlen++] = K_SPECIAL;
+ result[dlen++] = 'k';
+ if (src[1] == '0')
+ result[dlen++] = ';'; /* #0 is F10 is "k;" */
+ else
+ result[dlen++] = src[1]; /* #3 is F3 is "k3" */
+ src += 2;
+ }
+
+ /*
+ * Copy each byte from *from to result[dlen]
+ */
+ while (*src != NUL) {
+ /*
+ * If 'cpoptions' does not contain '<', check for special key codes,
+ * like "<C-S-LeftMouse>"
+ */
+ if (do_special && (do_lt || STRNCMP(src, "<lt>", 4) != 0)) {
+ /*
+ * Replace <SID> by K_SNR <script-nr> _.
+ * (room: 5 * 6 = 30 bytes; needed: 3 + <nr> + 1 <= 14)
+ */
+ if (STRNICMP(src, "<SID>", 5) == 0) {
+ if (current_SID <= 0)
+ EMSG(_(e_usingsid));
+ else {
+ src += 5;
+ result[dlen++] = K_SPECIAL;
+ result[dlen++] = (int)KS_EXTRA;
+ result[dlen++] = (int)KE_SNR;
+ sprintf((char *)result + dlen, "%ld", (long)current_SID);
+ dlen += (int)STRLEN(result + dlen);
+ result[dlen++] = '_';
+ continue;
+ }
+ }
+
+ slen = trans_special(&src, result + dlen, TRUE);
+ if (slen) {
+ dlen += slen;
+ continue;
+ }
+ }
+
+ /*
+ * If 'cpoptions' does not contain 'k', see if it's an actual key-code.
+ * Note that this is also checked after replacing the <> form.
+ * Single character codes are NOT replaced (e.g. ^H or DEL), because
+ * it could be a character in the file.
+ */
+ if (do_key_code) {
+ i = find_term_bykeys(src);
+ if (i >= 0) {
+ result[dlen++] = K_SPECIAL;
+ result[dlen++] = termcodes[i].name[0];
+ result[dlen++] = termcodes[i].name[1];
+ src += termcodes[i].len;
+ /* If terminal code matched, continue after it. */
+ continue;
+ }
+ }
+
+ if (do_special) {
+ char_u *p, *s, len;
+
+ /*
+ * Replace <Leader> by the value of "mapleader".
+ * Replace <LocalLeader> by the value of "maplocalleader".
+ * If "mapleader" or "maplocalleader" isn't set use a backslash.
+ */
+ if (STRNICMP(src, "<Leader>", 8) == 0) {
+ len = 8;
+ p = get_var_value((char_u *)"g:mapleader");
+ } else if (STRNICMP(src, "<LocalLeader>", 13) == 0) {
+ len = 13;
+ p = get_var_value((char_u *)"g:maplocalleader");
+ } else {
+ len = 0;
+ p = NULL;
+ }
+ if (len != 0) {
+ /* Allow up to 8 * 6 characters for "mapleader". */
+ if (p == NULL || *p == NUL || STRLEN(p) > 8 * 6)
+ s = (char_u *)"\\";
+ else
+ s = p;
+ while (*s != NUL)
+ result[dlen++] = *s++;
+ src += len;
+ continue;
+ }
+ }
+
+ /*
+ * Remove CTRL-V and ignore the next character.
+ * For "from" side the CTRL-V at the end is included, for the "to"
+ * part it is removed.
+ * If 'cpoptions' does not contain 'B', also accept a backslash.
+ */
+ key = *src;
+ if (key == Ctrl_V || (do_backslash && key == '\\')) {
+ ++src; /* skip CTRL-V or backslash */
+ if (*src == NUL) {
+ if (from_part)
+ result[dlen++] = key;
+ break;
+ }
+ }
+
+ /* skip multibyte char correctly */
+ for (i = (*mb_ptr2len)(src); 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.
+ */
+ if (*src == K_SPECIAL) {
+ result[dlen++] = K_SPECIAL;
+ result[dlen++] = KS_SPECIAL;
+ result[dlen++] = KE_FILLER;
+ } else
+ result[dlen++] = *src;
+ ++src;
+ }
+ }
+ result[dlen] = NUL;
+
+ /*
+ * Copy the new string to allocated memory.
+ * If this fails, just return from.
+ */
+ if ((*bufp = vim_strsave(result)) != NULL)
+ from = *bufp;
+ vim_free(result);
+ return from;
+}
+
+/*
+ * Find a termcode with keys 'src' (must be NUL terminated).
+ * Return the index in termcodes[], or -1 if not found.
+ */
+int find_term_bykeys(src)
+char_u *src;
+{
+ int i;
+ int slen = (int)STRLEN(src);
+
+ for (i = 0; i < tc_len; ++i) {
+ if (slen == termcodes[i].len
+ && STRNCMP(termcodes[i].code, src, (size_t)slen) == 0)
+ return i;
+ }
+ return -1;
+}
+
+/*
+ * Gather the first characters in the terminal key codes into a string.
+ * Used to speed up check_termcode().
+ */
+static void gather_termleader() {
+ int i;
+ int len = 0;
+
+ if (check_for_codes)
+ termleader[len++] = DCS; /* the termcode response starts with DCS
+ in 8-bit mode */
+ termleader[len] = NUL;
+
+ for (i = 0; i < tc_len; ++i)
+ if (vim_strchr(termleader, termcodes[i].code[0]) == NULL) {
+ termleader[len++] = termcodes[i].code[0];
+ termleader[len] = NUL;
+ }
+
+ need_gather = FALSE;
+}
+
+/*
+ * Show all termcodes (for ":set termcap")
+ * This code looks a lot like showoptions(), but is different.
+ */
+void show_termcodes() {
+ int col;
+ int *items;
+ int item_count;
+ int run;
+ int row, rows;
+ int cols;
+ int i;
+ int len;
+
+#define INC3 27 /* try to make three columns */
+#define INC2 40 /* try to make two columns */
+#define GAP 2 /* spaces between columns */
+
+ if (tc_len == 0) /* no terminal codes (must be GUI) */
+ return;
+ items = (int *)alloc((unsigned)(sizeof(int) * tc_len));
+ if (items == NULL)
+ return;
+
+ /* Highlight title */
+ MSG_PUTS_TITLE(_("\n--- Terminal keys ---"));
+
+ /*
+ * do the loop two times:
+ * 1. display the short items (non-strings and short strings)
+ * 2. display the medium items (medium length strings)
+ * 3. display the long items (remaining strings)
+ */
+ for (run = 1; run <= 3 && !got_int; ++run) {
+ /*
+ * collect the items in items[]
+ */
+ item_count = 0;
+ for (i = 0; i < tc_len; i++) {
+ len = show_one_termcode(termcodes[i].name,
+ termcodes[i].code, FALSE);
+ if (len <= INC3 - GAP ? run == 1
+ : len <= INC2 - GAP ? run == 2
+ : run == 3)
+ items[item_count++] = i;
+ }
+
+ /*
+ * display the items
+ */
+ if (run <= 2) {
+ cols = (Columns + GAP) / (run == 1 ? INC3 : INC2);
+ if (cols == 0)
+ cols = 1;
+ rows = (item_count + cols - 1) / cols;
+ } else /* run == 3 */
+ rows = item_count;
+ for (row = 0; row < rows && !got_int; ++row) {
+ msg_putchar('\n'); /* go to next line */
+ if (got_int) /* 'q' typed in more */
+ break;
+ col = 0;
+ for (i = row; i < item_count; i += rows) {
+ msg_col = col; /* make columns */
+ show_one_termcode(termcodes[items[i]].name,
+ termcodes[items[i]].code, TRUE);
+ if (run == 2)
+ col += INC2;
+ else
+ col += INC3;
+ }
+ out_flush();
+ ui_breakcheck();
+ }
+ }
+ vim_free(items);
+}
+
+/*
+ * Show one termcode entry.
+ * Output goes into IObuff[]
+ */
+int show_one_termcode(name, code, printit)
+char_u *name;
+char_u *code;
+int printit;
+{
+ char_u *p;
+ int len;
+
+ if (name[0] > '~') {
+ IObuff[0] = ' ';
+ IObuff[1] = ' ';
+ IObuff[2] = ' ';
+ IObuff[3] = ' ';
+ } else {
+ IObuff[0] = 't';
+ IObuff[1] = '_';
+ IObuff[2] = name[0];
+ IObuff[3] = name[1];
+ }
+ IObuff[4] = ' ';
+
+ p = get_special_key_name(TERMCAP2KEY(name[0], name[1]), 0);
+ if (p[1] != 't')
+ STRCPY(IObuff + 5, p);
+ else
+ IObuff[5] = NUL;
+ len = (int)STRLEN(IObuff);
+ do
+ IObuff[len++] = ' ';
+ while (len < 17);
+ IObuff[len] = NUL;
+ if (code == NULL)
+ len += 4;
+ else
+ len += vim_strsize(code);
+
+ if (printit) {
+ msg_puts(IObuff);
+ if (code == NULL)
+ msg_puts((char_u *)"NULL");
+ else
+ msg_outtrans(code);
+ }
+ return len;
+}
+
+/*
+ * For Xterm >= 140 compiled with OPT_TCAP_QUERY: Obtain the actually used
+ * termcap codes from the terminal itself.
+ * We get them one by one to avoid a very long response string.
+ */
+static int xt_index_in = 0;
+static int xt_index_out = 0;
+
+static void req_codes_from_term() {
+ xt_index_out = 0;
+ xt_index_in = 0;
+ req_more_codes_from_term();
+}
+
+static void req_more_codes_from_term() {
+ char buf[11];
+ int old_idx = xt_index_out;
+
+ /* Don't do anything when going to exit. */
+ if (exiting)
+ return;
+
+ /* Send up to 10 more requests out than we received. Avoid sending too
+ * many, there can be a buffer overflow somewhere. */
+ while (xt_index_out < xt_index_in + 10 && key_names[xt_index_out] != NULL) {
+# ifdef DEBUG_TERMRESPONSE
+ char dbuf[100];
+
+ sprintf(dbuf, "Requesting XT %d: %s",
+ xt_index_out, key_names[xt_index_out]);
+ log_tr(dbuf);
+# endif
+ sprintf(buf, "\033P+q%02x%02x\033\\",
+ key_names[xt_index_out][0], key_names[xt_index_out][1]);
+ out_str_nf((char_u *)buf);
+ ++xt_index_out;
+ }
+
+ /* Send the codes out right away. */
+ if (xt_index_out != old_idx)
+ out_flush();
+}
+
+/*
+ * Decode key code response from xterm: '<Esc>P1+r<name>=<string><Esc>\'.
+ * A "0" instead of the "1" indicates a code that isn't supported.
+ * Both <name> and <string> are encoded in hex.
+ * "code" points to the "0" or "1".
+ */
+static void got_code_from_term(code, len)
+char_u *code;
+int len;
+{
+#define XT_LEN 100
+ char_u name[3];
+ char_u str[XT_LEN];
+ int i;
+ int j = 0;
+ int c;
+
+ /* A '1' means the code is supported, a '0' means it isn't.
+ * When half the length is > XT_LEN we can't use it.
+ * Our names are currently all 2 characters. */
+ if (code[0] == '1' && code[7] == '=' && len / 2 < XT_LEN) {
+ /* Get the name from the response and find it in the table. */
+ name[0] = hexhex2nr(code + 3);
+ name[1] = hexhex2nr(code + 5);
+ name[2] = NUL;
+ for (i = 0; key_names[i] != NULL; ++i) {
+ if (STRCMP(key_names[i], name) == 0) {
+ xt_index_in = i;
+ break;
+ }
+ }
+# ifdef DEBUG_TERMRESPONSE
+ {
+ char buf[100];
+
+ sprintf(buf, "Received XT %d: %s", xt_index_in, (char *)name);
+ log_tr(buf);
+ }
+# endif
+ if (key_names[i] != NULL) {
+ for (i = 8; (c = hexhex2nr(code + i)) >= 0; i += 2)
+ str[j++] = c;
+ str[j] = NUL;
+ if (name[0] == 'C' && name[1] == 'o') {
+ /* Color count is not a key code. */
+ i = atoi((char *)str);
+ if (i != t_colors) {
+ /* Nr of colors changed, initialize highlighting and
+ * redraw everything. This causes a redraw, which usually
+ * clears the message. Try keeping the message if it
+ * might work. */
+ set_keep_msg_from_hist();
+ set_color_count(i);
+ init_highlight(TRUE, FALSE);
+#ifdef DEBUG_TERMRESPONSE
+ {
+ char buf[100];
+ int r = redraw_asap(CLEAR);
+
+ sprintf(buf, "Received t_Co, redraw_asap(): %d", r);
+ log_tr(buf);
+ }
+#else
+ redraw_asap(CLEAR);
+#endif
+ }
+ } else {
+ /* First delete any existing entry with the same code. */
+ i = find_term_bykeys(str);
+ if (i >= 0)
+ del_termcode_idx(i);
+ add_termcode(name, str, ATC_FROM_TERM);
+ }
+ }
+ }
+
+ /* May request more codes now that we received one. */
+ ++xt_index_in;
+ req_more_codes_from_term();
+}
+
+/*
+ * Check if there are any unanswered requests and deal with them.
+ * This is called before starting an external program or getting direct
+ * keyboard input. We don't want responses to be send to that program or
+ * handled as typed text.
+ */
+static void check_for_codes_from_term() {
+ int c;
+
+ /* If no codes requested or all are answered, no need to wait. */
+ if (xt_index_out == 0 || xt_index_out == xt_index_in)
+ return;
+
+ /* Vgetc() will check for and handle any response.
+ * Keep calling vpeekc() until we don't get any responses. */
+ ++no_mapping;
+ ++allow_keys;
+ for (;; ) {
+ c = vpeekc();
+ if (c == NUL) /* nothing available */
+ break;
+
+ /* If a response is recognized it's replaced with K_IGNORE, must read
+ * it from the input stream. If there is no K_IGNORE we can't do
+ * anything, break here (there might be some responses further on, but
+ * we don't want to throw away any typed chars). */
+ if (c != K_SPECIAL && c != K_IGNORE)
+ break;
+ c = vgetc();
+ if (c != K_IGNORE) {
+ vungetc(c);
+ break;
+ }
+ }
+ --no_mapping;
+ --allow_keys;
+}
+
+/*
+ * Translate an internal mapping/abbreviation representation into the
+ * corresponding external one recognized by :map/:abbrev commands;
+ * respects the current B/k/< settings of 'cpoption'.
+ *
+ * This function is called when expanding mappings/abbreviations on the
+ * command-line, and for building the "Ambiguous mapping..." error message.
+ *
+ * It uses a growarray to build the translation string since the
+ * latter can be wider than the original description. The caller has to
+ * free the string afterwards.
+ *
+ * Returns NULL when there is a problem.
+ */
+char_u * translate_mapping(str, expmap)
+char_u *str;
+int expmap; /* TRUE when expanding mappings on command-line */
+{
+ garray_T ga;
+ int c;
+ int modifiers;
+ int cpo_bslash;
+ int cpo_special;
+ int cpo_keycode;
+
+ ga_init(&ga);
+ ga.ga_itemsize = 1;
+ ga.ga_growsize = 40;
+
+ cpo_bslash = (vim_strchr(p_cpo, CPO_BSLASH) != NULL);
+ cpo_special = (vim_strchr(p_cpo, CPO_SPECI) != NULL);
+ cpo_keycode = (vim_strchr(p_cpo, CPO_KEYCODE) == NULL);
+
+ for (; *str; ++str) {
+ c = *str;
+ if (c == K_SPECIAL && str[1] != NUL && str[2] != NUL) {
+ modifiers = 0;
+ if (str[1] == KS_MODIFIER) {
+ str++;
+ modifiers = *++str;
+ c = *++str;
+ }
+ if (cpo_special && cpo_keycode && c == K_SPECIAL && !modifiers) {
+ int i;
+
+ /* try to find special key in termcodes */
+ for (i = 0; i < tc_len; ++i)
+ if (termcodes[i].name[0] == str[1]
+ && termcodes[i].name[1] == str[2])
+ break;
+ if (i < tc_len) {
+ ga_concat(&ga, termcodes[i].code);
+ str += 2;
+ continue; /* for (str) */
+ }
+ }
+ if (c == K_SPECIAL && str[1] != NUL && str[2] != NUL) {
+ if (expmap && cpo_special) {
+ ga_clear(&ga);
+ return NULL;
+ }
+ c = TO_SPECIAL(str[1], str[2]);
+ if (c == K_ZERO) /* display <Nul> as ^@ */
+ c = NUL;
+ str += 2;
+ }
+ if (IS_SPECIAL(c) || modifiers) { /* special key */
+ if (expmap && cpo_special) {
+ ga_clear(&ga);
+ return NULL;
+ }
+ ga_concat(&ga, get_special_key_name(c, modifiers));
+ continue; /* for (str) */
+ }
+ }
+ if (c == ' ' || c == '\t' || c == Ctrl_J || c == Ctrl_V
+ || (c == '<' && !cpo_special) || (c == '\\' && !cpo_bslash))
+ ga_append(&ga, cpo_bslash ? Ctrl_V : '\\');
+ if (c)
+ ga_append(&ga, c);
+ }
+ ga_append(&ga, NUL);
+ return (char_u *)(ga.ga_data);
+}
+
diff --git a/src/term.h b/src/term.h
new file mode 100644
index 0000000000..0ba5a19c13
--- /dev/null
+++ b/src/term.h
@@ -0,0 +1,156 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * 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.
+ */
+
+/*
+ * This file contains the defines for the machine dependent escape sequences
+ * that the editor needs to perform various operations. All of the sequences
+ * here are optional, except "cm" (cursor motion).
+ */
+
+
+/*
+ * Index of the termcap codes in the term_strings array.
+ */
+enum SpecialKey {
+ KS_NAME = 0, /* name of this terminal entry */
+ KS_CE, /* clear to end of line */
+ KS_AL, /* add new blank line */
+ KS_CAL, /* add number of blank lines */
+ KS_DL, /* delete line */
+ KS_CDL, /* delete number of lines */
+ KS_CS, /* scroll region */
+ KS_CL, /* clear screen */
+ KS_CD, /* clear to end of display */
+ KS_UT, /* clearing uses current background color */
+ KS_DA, /* text may be scrolled down from up */
+ KS_DB, /* text may be scrolled up from down */
+ KS_VI, /* cursor invisible */
+ KS_VE, /* cursor visible */
+ KS_VS, /* cursor very visible */
+ KS_ME, /* normal mode */
+ KS_MR, /* reverse mode */
+ KS_MD, /* bold mode */
+ KS_SE, /* normal mode */
+ KS_SO, /* standout mode */
+ KS_CZH, /* italic mode start */
+ KS_CZR, /* italic mode end */
+ KS_UE, /* exit underscore (underline) mode */
+ KS_US, /* underscore (underline) mode */
+ KS_UCE, /* exit undercurl mode */
+ KS_UCS, /* undercurl mode */
+ KS_MS, /* save to move cur in reverse mode */
+ KS_CM, /* cursor motion */
+ KS_SR, /* scroll reverse (backward) */
+ KS_CRI, /* cursor number of chars right */
+ KS_VB, /* visual bell */
+ KS_KS, /* put term in "keypad transmit" mode */
+ KS_KE, /* out of "keypad transmit" mode */
+ KS_TI, /* put terminal in termcap mode */
+ KS_TE, /* out of termcap mode */
+ KS_BC, /* backspace character (cursor left) */
+ KS_CCS, /* cur is relative to scroll region */
+ KS_CCO, /* number of colors */
+ KS_CSF, /* set foreground color */
+ KS_CSB, /* set background color */
+ KS_XS, /* standout not erased by overwriting (hpterm) */
+ KS_MB, /* blink mode */
+ KS_CAF, /* set foreground color (ANSI) */
+ KS_CAB, /* set background color (ANSI) */
+ KS_LE, /* cursor left (mostly backspace) */
+ KS_ND, /* cursor right */
+ KS_CIS, /* set icon text start */
+ KS_CIE, /* set icon text end */
+ KS_TS, /* set window title start (to status line)*/
+ KS_FS, /* set window title end (from status line) */
+ KS_CWP, /* set window position in pixels */
+ KS_CWS, /* set window size in characters */
+ KS_CRV, /* request version string */
+ KS_CSI, /* start insert mode (bar cursor) */
+ KS_CEI, /* end insert mode (block cursor) */
+ KS_CSV, /* scroll region vertical */
+ KS_OP, /* original color pair */
+ KS_U7 /* request cursor position */
+};
+
+#define KS_LAST KS_U7
+
+/*
+ * the terminal capabilities are stored in this array
+ * IMPORTANT: When making changes, note the following:
+ * - there should be an entry for each code in the builtin termcaps
+ * - there should be an option for each code in option.c
+ * - there should be code in term.c to obtain the value from the termcap
+ */
+
+extern char_u *(term_strings[]); /* current terminal strings */
+
+/*
+ * strings used for terminal
+ */
+#define T_NAME (term_str(KS_NAME)) /* terminal name */
+#define T_CE (term_str(KS_CE)) /* clear to end of line */
+#define T_AL (term_str(KS_AL)) /* add new blank line */
+#define T_CAL (term_str(KS_CAL)) /* add number of blank lines */
+#define T_DL (term_str(KS_DL)) /* delete line */
+#define T_CDL (term_str(KS_CDL)) /* delete number of lines */
+#define T_CS (term_str(KS_CS)) /* scroll region */
+#define T_CSV (term_str(KS_CSV)) /* scroll region vertical */
+#define T_CL (term_str(KS_CL)) /* clear screen */
+#define T_CD (term_str(KS_CD)) /* clear to end of display */
+#define T_UT (term_str(KS_UT)) /* clearing uses background color */
+#define T_DA (term_str(KS_DA)) /* text may be scrolled down from up */
+#define T_DB (term_str(KS_DB)) /* text may be scrolled up from down */
+#define T_VI (term_str(KS_VI)) /* cursor invisible */
+#define T_VE (term_str(KS_VE)) /* cursor visible */
+#define T_VS (term_str(KS_VS)) /* cursor very visible */
+#define T_ME (term_str(KS_ME)) /* normal mode */
+#define T_MR (term_str(KS_MR)) /* reverse mode */
+#define T_MD (term_str(KS_MD)) /* bold mode */
+#define T_SE (term_str(KS_SE)) /* normal mode */
+#define T_SO (term_str(KS_SO)) /* standout mode */
+#define T_CZH (term_str(KS_CZH)) /* italic mode start */
+#define T_CZR (term_str(KS_CZR)) /* italic mode end */
+#define T_UE (term_str(KS_UE)) /* exit underscore (underline) mode */
+#define T_US (term_str(KS_US)) /* underscore (underline) mode */
+#define T_UCE (term_str(KS_UCE)) /* exit undercurl mode */
+#define T_UCS (term_str(KS_UCS)) /* undercurl mode */
+#define T_MS (term_str(KS_MS)) /* save to move cur in reverse mode */
+#define T_CM (term_str(KS_CM)) /* cursor motion */
+#define T_SR (term_str(KS_SR)) /* scroll reverse (backward) */
+#define T_CRI (term_str(KS_CRI)) /* cursor number of chars right */
+#define T_VB (term_str(KS_VB)) /* visual bell */
+#define T_KS (term_str(KS_KS)) /* put term in "keypad transmit" mode */
+#define T_KE (term_str(KS_KE)) /* out of "keypad transmit" mode */
+#define T_TI (term_str(KS_TI)) /* put terminal in termcap mode */
+#define T_TE (term_str(KS_TE)) /* out of termcap mode */
+#define T_BC (term_str(KS_BC)) /* backspace character */
+#define T_CCS (term_str(KS_CCS)) /* cur is relative to scroll region */
+#define T_CCO (term_str(KS_CCO)) /* number of colors */
+#define T_CSF (term_str(KS_CSF)) /* set foreground color */
+#define T_CSB (term_str(KS_CSB)) /* set background color */
+#define T_XS (term_str(KS_XS)) /* standout not erased by overwriting */
+#define T_MB (term_str(KS_MB)) /* blink mode */
+#define T_CAF (term_str(KS_CAF)) /* set foreground color (ANSI) */
+#define T_CAB (term_str(KS_CAB)) /* set background color (ANSI) */
+#define T_LE (term_str(KS_LE)) /* cursor left */
+#define T_ND (term_str(KS_ND)) /* cursor right */
+#define T_CIS (term_str(KS_CIS)) /* set icon text start */
+#define T_CIE (term_str(KS_CIE)) /* set icon text end */
+#define T_TS (term_str(KS_TS)) /* set window title start */
+#define T_FS (term_str(KS_FS)) /* set window title end */
+#define T_CWP (term_str(KS_CWP)) /* window position */
+#define T_CWS (term_str(KS_CWS)) /* window size */
+#define T_CSI (term_str(KS_CSI)) /* start insert mode */
+#define T_CEI (term_str(KS_CEI)) /* end insert mode */
+#define T_CRV (term_str(KS_CRV)) /* request version string */
+#define T_OP (term_str(KS_OP)) /* original color pair */
+#define T_U7 (term_str(KS_U7)) /* request cursor position */
+
+#define TMODE_COOK 0 /* terminal mode for external cmds and Ex mode */
+#define TMODE_SLEEP 1 /* terminal mode for sleeping (cooked but no echo) */
+#define TMODE_RAW 2 /* terminal mode for Normal and Insert mode */
diff --git a/src/testdir/Makefile b/src/testdir/Makefile
new file mode 100644
index 0000000000..5238fda86a
--- /dev/null
+++ b/src/testdir/Makefile
@@ -0,0 +1,110 @@
+#
+# Makefile to run all tests for Vim
+#
+
+VIMPROG = ../../build/src/vim
+
+# Uncomment this line to use valgrind for memory leaks and extra warnings.
+# The output goes into a file "valgrind.testN"
+# Vim should be compiled with EXITFREE to avoid false warnings.
+# This will make testing about 10 times as slow.
+# VALGRIND = valgrind --tool=memcheck --leak-check=yes --num-callers=15 --log-file=valgrind.$*
+
+
+SCRIPTS = test1.out test2.out test3.out test4.out test5.out test6.out \
+ test7.out test8.out test9.out test10.out test11.out \
+ test12.out test13.out test14.out test15.out test17.out \
+ test18.out test19.out test20.out test21.out test22.out \
+ test23.out test24.out test25.out test26.out test27.out \
+ test28.out test29.out test30.out test31.out test32.out \
+ test33.out test34.out test35.out test36.out test37.out \
+ test38.out test39.out test40.out test41.out test42.out \
+ test43.out test44.out test45.out test46.out test47.out \
+ test48.out test49.out test51.out test52.out test53.out \
+ test54.out test55.out test56.out test57.out test58.out \
+ test59.out test60.out test61.out test62.out test63.out \
+ test64.out test65.out test66.out test67.out test68.out \
+ test69.out test70.out test71.out test72.out test73.out \
+ test74.out test75.out test76.out test77.out test78.out \
+ test79.out test80.out test81.out test82.out test83.out \
+ test84.out test85.out test86.out test87.out test88.out \
+ test89.out test90.out test91.out test92.out test93.out \
+ test94.out test95.out test96.out test97.out test98.out \
+ test99.out test100.out test101.out test102.out test103.out
+
+SCRIPTS_GUI = test16.out
+
+.SUFFIXES: .in .out
+
+nongui: nolog $(SCRIPTS) report
+
+gui: nolog $(SCRIPTS) $(SCRIPTS_GUI) report
+
+report:
+ @echo
+ @echo 'Test results:'
+ @/bin/sh -c "if test -f test.log; \
+ then cat test.log; echo TEST FAILURE; exit 1; \
+ else echo ALL DONE; \
+ fi"
+
+$(SCRIPTS) $(SCRIPTS_GUI): $(VIMPROG)
+
+RM_ON_RUN = test.out X* viminfo
+RM_ON_START = tiny.vim small.vim mbyte.vim mzscheme.vim lua.vim test.ok
+RUN_VIM = $(VALGRIND) $(VIMPROG) -u unix.vim -U NONE --noplugin -s dotest.in
+
+clean:
+ -rm -rf *.out *.failed *.rej *.orig test.log $(RM_ON_RUN) $(RM_ON_START) valgrind.*
+
+test1.out: 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
+
+.in.out:
+ -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
+
+ # For flaky tests retry one time.
+ @/bin/sh -c "if test -f test.out -a $* = test61; then \
+ if diff test.out $*.ok; \
+ then echo flaky test ok first time; \
+ else rm -rf $*.failed $(RM_ON_RUN); \
+ $(RUN_VIM) $*.in; \
+ fi \
+ fi"
+
+ # Check if the test.out file matches test.ok.
+ @/bin/sh -c "if test -f test.out; then \
+ if diff 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
+
+test49.out: test49.vim
+
+test60.out: test60.vim
+
+nolog:
+ -rm -f test.log
diff --git a/src/testdir/dotest.in b/src/testdir/dotest.in
new file mode 100644
index 0000000000..b2a0e1a68e
--- /dev/null
+++ b/src/testdir/dotest.in
@@ -0,0 +1,3 @@
+:set cp
+:map dotest /^STARTTEST j:set ff=unix cpo-=A :.,/ENDTEST/-1w! Xdotest :set ff& cpo+=A nj0:so! Xdotest dotest
+dotest
diff --git a/src/testdir/sautest/autoload/footest.vim b/src/testdir/sautest/autoload/footest.vim
new file mode 100644
index 0000000000..f467bc376d
--- /dev/null
+++ b/src/testdir/sautest/autoload/footest.vim
@@ -0,0 +1,5 @@
+" Autoload script used by test55 and test60
+let footest#x = 1
+func footest#F()
+ return 0
+endfunc
diff --git a/src/testdir/test1.in b/src/testdir/test1.in
new file mode 100644
index 0000000000..735d539673
--- /dev/null
+++ b/src/testdir/test1.in
@@ -0,0 +1,57 @@
+
+First a simple test to check if the test script works.
+
+If Vim was not compiled with the +eval feature, the small.vim script will be
+set to copy the test.ok file to test.out, so that it looks like the test
+succeeded. Otherwise an empty small.vim is written. small.vim is sourced by
+tests that require the +eval feature or other features that are missing in the
+small version.
+
+If Vim was not compiled with the +windows feature, the tiny.vim script will be
+set like small.vim above. tiny.vim is sourced by tests that require the
++windows feature or other features that are missing in the tiny version.
+
+If Vim was not compiled with the +multi_byte feature, the mbyte.vim script will
+be set like small.vim above. mbyte.vim is sourced by tests that require the
++multi_byte feature.
+Similar logic is applied to the +mzscheme feature, using mzscheme.vim.
+Similar logic is applied to the +lua feature, using lua.vim.
+
+STARTTEST
+:" If columns or lines are too small, create wrongtermsize.
+:" (Some tests will fail. When columns and/or lines are small)
+:if &lines < 24 || &columns < 80 | sp another | w! wrongtermsize | qa! | endif
+:"
+:" Write a single line to test.out to check if testing works at all.
+:%d
+athis is a test:w! test.out
+:" Create small.vim and tiny.vim empty, create mbyte.vim to skip the test.
+0D:w! small.vim
+:w! tiny.vim
+ae! test.ok
+w! test.out
+qa!
+:w! mbyte.vim
+:w! mzscheme.vim
+:w! lua.vim
+:"
+:" If +multi_byte feature supported, make mbyte.vim empty.
+:if has("multi_byte") | sp another | w! mbyte.vim | q | endif
+:"
+:" If +mzscheme feature supported, make mzscheme.vim empty.
+:if has("mzscheme") | sp another | w! mzscheme.vim | q | endif
+:"
+:" If +lua feature supported, make lua.vim empty.
+:if has("lua") | sp another | w! lua.vim | q | endif
+:"
+:" If +eval feature supported quit here, leaving tiny.vim and small.vim empty.
+:" Otherwise write small.vim to skip the test.
+:if 1 | q! | endif
+:w! small.vim
+:" If +windows feature not supported :sp will fail and tiny.vim will be
+:" written to skip the test.
+:sp another
+:wq! tiny.vim
+:qa!
+ENDTEST
+
diff --git a/src/testdir/test1.ok b/src/testdir/test1.ok
new file mode 100644
index 0000000000..90bfcb5106
--- /dev/null
+++ b/src/testdir/test1.ok
@@ -0,0 +1 @@
+this is a test
diff --git a/src/testdir/test10.in b/src/testdir/test10.in
new file mode 100644
index 0000000000..2d0d546606
--- /dev/null
+++ b/src/testdir/test10.in
@@ -0,0 +1,114 @@
+Test for 'errorformat'. This will fail if the quickfix feature was disabled.
+
+STARTTEST
+:so small.vim
+:" Also test a BOM is ignored.
+:so mbyte.vim
+:set encoding=utf-8
+:7/start of errorfile/,/end of errorfile/w! Xerrorfile1
+:7/start of errorfile/,/end of errorfile/-1w! Xerrorfile2
+:/start of testfile/,/end of testfile/w! Xtestfile
+:set efm+==%f=\\,\ line\ %l%*\\D%v%*[^\ ]\ %m
+:set efm^=%AError\ in\ \"%f\"\ at\ line\ %l:,%Z%p^,%C%m
+:cf Xerrorfile2
+:clast
+:copen
+:let a=w:quickfix_title
+:wincmd p
+lgR=a 
+:cf Xerrorfile1
+grA
+:cn
+gRLINE 6, COL 19
+:cn
+gRNO COLUMN SPECIFIED
+:cn
+gRAGAIN NO COLUMN
+:cn
+gRCOL 1
+:cn
+gRCOL 2
+:cn
+gRCOL 10
+:cn
+gRVCOL 10
+:cn
+grI
+:cn
+gR. SPACE POINTER
+:cn
+gR. DOT POINTER
+:cn
+gR. DASH POINTER
+:cn
+gR. TAB-SPACE POINTER
+:clast
+:cprev
+:cprev
+:wincmd w
+:let a=w:quickfix_title
+:wincmd p
+lgR=a 
+:w! test.out " Write contents of this file
+:qa!
+ENDTEST
+
+start of errorfile
+"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?
+end of errorfile
+
+start of testfile
+ 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
+end of testfile
diff --git a/src/testdir/test10.ok b/src/testdir/test10.ok
new file mode 100644
index 0000000000..76a02f40b4
--- /dev/null
+++ b/src/testdir/test10.ok
@@ -0,0 +1,23 @@
+start of testfile
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 2
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 3
+ xxxxxxxxxxAxxxxxxxxxxxxxxxxxxx line 4
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 5
+ xxxxxxxxxxxxxxxxxLINE 6, COL 19 line 6
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 7
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 8
+ NO COLUMN SPECIFIEDxxxxxxxxxxx line 9
+ AGAIN NO COLUMNxxxxxxxxxxxxxxx line 10
+COL 1 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 11
+ COL 2xxxxxxxxxxxxxxxxxxxxxxxxx line 12
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 13
+ xxxxxxxxCOL 10xxxxxxxxxxxxxxxx line 14
+ xVCOL 10xxxxxxxxxxxxxxxxxxxxxx line 15
+ Ixxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 16
+ xxxx. SPACE POINTERxxxxxxxxxxx line 17
+ xxxxx. DOT POINTERxxxxxxxxxxxx line 18
+ xxxxxx. DASH POINTERxxxxxxxxxx line 19
+ xxxxxxx. TAB-SPACE POINTERxxxx line 20
+ xxxxxxxx:cf Xerrorfile1xxxxxxx line 21
+ xxxxxxxx:cf Xerrorfile2xxxxxxx line 22
+end of testfile
diff --git a/src/testdir/test100.in b/src/testdir/test100.in
new file mode 100644
index 0000000000..e42331946c
--- /dev/null
+++ b/src/testdir/test100.in
@@ -0,0 +1,42 @@
+Tests for 'undolevel' setting being global-local
+
+STARTTEST
+:so small.vim
+:set nocompatible viminfo+=nviminfo ul=5
+:fu! FillBuffer()
+ :for i in range(1,13)
+ :put=i
+ :exe "setg ul=" . &g:ul
+ :endfor
+:endfu
+:fu! UndoLevel()
+ :redir @a | setglobal undolevels? | echon ' global' | setlocal undolevels? | echon ' local' |redir end
+ :$put a
+:endfu
+:new one
+:0put ='ONE: expecting global undolevels: 5, local undolevels: -123456 (default)'
+:call FillBuffer()
+:call feedkeys(":earlier 10\n", 't')
+:call UndoLevel()
+:%w! test.out
+:new two
+:0put ='TWO: expecting global undolevels: 5, local undolevels: 2 (first) then 10 (afterwards)'
+:setlocal ul=2
+:call FillBuffer()
+:call feedkeys(":earlier 10\n", 't')
+:call UndoLevel()
+:setlocal ul=10
+:call UndoLevel()
+:%w >> test.out
+:wincmd p
+:redir >>test.out | echo "global value shouldn't be changed and still be 5!" | echo 'ONE: expecting global undolevels: 5, local undolevels: -123456 (default)'|:setglobal undolevels? | echon ' global' | setlocal undolevels? | echon ' local' |echo "" |redir end
+:new three
+:setglobal ul=50
+:1put ='global value should be changed to 50'
+:2put ='THREE: expecting global undolevels: 50, local undolevels: -123456 (default)'
+:call UndoLevel()
+:%w >> test.out
+:"sleep 10
+:qa!
+ENDTEST
+
diff --git a/src/testdir/test100.ok b/src/testdir/test100.ok
new file mode 100644
index 0000000000..95b318461c
--- /dev/null
+++ b/src/testdir/test100.ok
@@ -0,0 +1,41 @@
+ONE: expecting global undolevels: 5, local undolevels: -123456 (default)
+1
+2
+3
+4
+5
+6
+7
+
+
+ undolevels=5 global
+ undolevels=-123456 local
+TWO: expecting global undolevels: 5, local undolevels: 2 (first) then 10 (afterwards)
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+
+
+ undolevels=5 global
+ undolevels=2 local
+
+ undolevels=5 global
+ undolevels=10 local
+
+global value shouldn't be changed and still be 5!
+ONE: expecting global undolevels: 5, local undolevels: -123456 (default)
+ undolevels=5 global
+ undolevels=-123456 local
+
+global value should be changed to 50
+THREE: expecting global undolevels: 50, local undolevels: -123456 (default)
+
+ undolevels=50 global
+ undolevels=-123456 local
diff --git a/src/testdir/test101.in b/src/testdir/test101.in
new file mode 100644
index 0000000000..04c934f2c5
--- /dev/null
+++ b/src/testdir/test101.in
@@ -0,0 +1,45 @@
+Test for v:hlsearch vim: set ft=vim :
+
+STARTTEST
+:" Last abc: Q
+:so small.vim
+:new
+:call setline(1, repeat(['aaa'], 10))
+:set hlsearch nolazyredraw
+:let r=[]
+:command -nargs=0 -bar AddR :call add(r, [screenattr(1, 1), v:hlsearch])
+/aaa
+:AddR
+:nohlsearch
+:AddR
+:let v:hlsearch=1
+:AddR
+:let v:hlsearch=0
+:AddR
+:set hlsearch
+:AddR
+:let v:hlsearch=0
+:AddR
+n:AddR
+:let v:hlsearch=0
+:AddR
+/
+:AddR
+:let r1=r[0][0]
+:" I guess it is not guaranteed that screenattr outputs always the same character
+:call map(r, 'v:val[1].":".(v:val[0]==r1?"highlighted":"not highlighted")')
+:try
+: let v:hlsearch=[]
+:catch
+: call add(r, matchstr(v:exception,'^Vim(let):E\d\+:'))
+:endtry
+:bwipeout!
+:$put=r
+:call garbagecollect(1)
+:"
+:/^start:/,$wq! test.out
+:" vim: et ts=4 isk-=\:
+:call getchar()
+ENDTEST
+
+start:
diff --git a/src/testdir/test101.ok b/src/testdir/test101.ok
new file mode 100644
index 0000000000..3ed7436cf7
--- /dev/null
+++ b/src/testdir/test101.ok
@@ -0,0 +1,11 @@
+start:
+1:highlighted
+0:not highlighted
+1:highlighted
+0:not highlighted
+1:highlighted
+0:not highlighted
+1:highlighted
+0:not highlighted
+1:highlighted
+Vim(let):E706:
diff --git a/src/testdir/test102.in b/src/testdir/test102.in
new file mode 100644
index 0000000000..35e9f6c2cf
--- /dev/null
+++ b/src/testdir/test102.in
@@ -0,0 +1,12 @@
+Test if fnameescape is correct for special chars like !
+
+STARTTEST
+:%d
+:let fname = 'Xspa ce'
+:try | exe "w! " . fnameescape(fname) | put='Space' | endtry
+:let fname = 'Xemark!'
+:try | exe "w! " . fnameescape(fname) | put='ExclamationMark' | endtry
+:w! test.out
+:qa!
+ENDTEST
+
diff --git a/src/testdir/test102.ok b/src/testdir/test102.ok
new file mode 100644
index 0000000000..a25fea192c
--- /dev/null
+++ b/src/testdir/test102.ok
@@ -0,0 +1,3 @@
+
+Space
+ExclamationMark
diff --git a/src/testdir/test103.in b/src/testdir/test103.in
new file mode 100644
index 0000000000..7c7591e3b9
--- /dev/null
+++ b/src/testdir/test103.in
@@ -0,0 +1,37 @@
+Test for visual mode not being reset causing E315 error.
+STARTTEST
+:so small.vim
+:enew
+:let g:msg="Everything's fine."
+:function! 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
+:endfunction
+: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:
+:"
+GV:call TriggerTheProblem()
+:%del _
+:call append(line('$'), g:msg)
+:w! test.out
+:brewind
+ENDTEST
+
+STARTTEST
+:qa!
+ENDTEST
+
diff --git a/src/testdir/test103.ok b/src/testdir/test103.ok
new file mode 100644
index 0000000000..9ea6dd6eea
--- /dev/null
+++ b/src/testdir/test103.ok
@@ -0,0 +1,2 @@
+
+Everything's fine.
diff --git a/src/testdir/test10a.in b/src/testdir/test10a.in
new file mode 100644
index 0000000000..19e8652fe5
--- /dev/null
+++ b/src/testdir/test10a.in
@@ -0,0 +1,73 @@
+Test for 'errorformat'.
+
+STARTTEST
+:so small.vim
+:/start of errorfile/,/end of errorfile/w! Xerrorfile
+:/start of testfile/,/end of testfile/w! Xtestfile
+:cf Xerrorfile
+rA
+:cn
+rB
+:cn
+rC
+:cn
+rD
+:cn
+rE
+:w! test.out " Write contents of this file
+:qa!
+ENDTEST
+
+start of errorfile
+
+ printf(" %d \n", (number/other)%10 );
+..................^
+%CC-E-NOSEMI, Missing ";".
+at line number 4 in file SYS$DISK:XTESTFILE
+
+ other=10000000;
+.............^
+%CC-E-UNDECLARED, In this statement, "oszt" is not declared.
+at line number 7 in file SYS$DISK:XTESTFILE
+
+ for (i = 0; i<7 ; i++ ){
+..................^
+%CC-E-UNDECLARED, In this statement, "i" is not declared.
+at line number 16 in file SYS$DISK:XTESTFILE
+
+some other error somewhere here.
+...........................^
+%CC-W-WARRING, Sorry, but no expalnation for such an warring.
+at line number 19 in file SYS$DISK:XTESTFILE
+
+and finally some other error exactly here.
+.....................................^
+%CC-I-INFORMATIONAL, It should be some informational message.
+at line number 20 in file SYS$DISK:XTESTFILE
+
+Does anyone know what is the problem and how to correct ?? :)
+end of errorfile
+
+start of testfile
+01234567890123456789012345678901234567
+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 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+end of testfile
diff --git a/src/testdir/test10a.ok b/src/testdir/test10a.ok
new file mode 100644
index 0000000000..10e78c9239
--- /dev/null
+++ b/src/testdir/test10a.ok
@@ -0,0 +1,23 @@
+start of testfile
+01234567890123456789012345678901234567
+line 3 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 4 xxxxxxxxxxAxxxxxxxxxxxxxxxxxxx
+line 5 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 6 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 7 xxxxxBxxxxxxxxxxxxxxxxxxxxxxxx
+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 xxxxxxxxxxCxxxxxxxxxxxxxxxxxxx
+line 17 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 18 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 19 xxxxxxxxxxxxxxxxxxxDxxxxxxxxxx
+line 20 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxE
+line 21 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 22 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+end of testfile
diff --git a/src/testdir/test11.in b/src/testdir/test11.in
new file mode 100644
index 0000000000..47de470a2d
--- /dev/null
+++ b/src/testdir/test11.in
@@ -0,0 +1,84 @@
+Tests for autocommands:
+- FileWritePre writing a compressed file
+- FileReadPost reading a compressed file
+- BufNewFile reading a file template
+- BufReadPre decompressing the file to be read
+- FilterReadPre substituting characters in the temp file
+- FilterReadPost substituting characters after filtering
+- FileReadPre set options for decompression
+- FileReadPost decompress the file
+
+Note: This test is skipped if "gzip" is not available.
+$GZIP is made empty, "-v" would cause trouble.
+Use a FileChangedShell autocommand to avoid a prompt for "Xtestfile.gz" being
+modified outside of Vim (noticed on Solaris).
+
+STARTTEST
+:so small.vim
+:" drop out when there is no gzip program
+:if !executable("gzip")
+: e! test.ok
+: w! test.out
+: qa!
+:endif
+:let $GZIP = ""
+:au FileChangedShell * echo "caught FileChangedShell"
+:set bin
+:au FileWritePre *.gz '[,']!gzip
+:au FileWritePost *.gz undo
+:/^start of testfile/,/^end of testfile/w! Xtestfile.gz
+:au FileReadPost *.gz '[,']!gzip -d
+:$r Xtestfile.gz " Read and decompress the testfile
+:?startstart?,$w! test.out " Write contents of this file
+:au BufNewFile *.c read Xtest.c
+:/^start of test.c/+1,/^end of test.c/-1w! Xtest.c
+:e! foo.c " Will load Xtest.c
+:au FileAppendPre *.out '[,']s/new/NEW/
+:au FileAppendPost *.out !cat Xtest.c >>test.out
+:w>>test.out " Append it to the output file
+:au! FileAppendPre
+:" setup autocommands to decompress before reading and re-compress afterwards
+:au BufReadPre *.gz exe '!gzip -d ' . shellescape(expand("<afile>"))
+:au BufReadPre *.gz call rename(expand("<afile>:r"), expand("<afile>"))
+:au BufReadPost *.gz call rename(expand("<afile>"), expand("<afile>:r"))
+:au BufReadPost *.gz exe '!gzip ' . shellescape(expand("<afile>:r"))
+:e! Xtestfile.gz " Edit compressed file
+:w>>test.out " Append it to the output file
+:set shelltemp " need temp files here
+:au FilterReadPre *.out call rename(expand("<afile>"), expand("<afile>") . ".t")
+:au FilterReadPre *.out exe '!sed s/e/E/ ' . shellescape(expand("<afile>")) . ".t >" . shellescape(expand("<afile>"))
+:au FilterReadPre *.out exe '!rm ' . shellescape(expand("<afile>")) . '.t'
+:au FilterReadPost *.out '[,']s/x/X/g
+:e! test.out " Edit the output file
+:23,$!cat
+:23,$s/\r$// " remove CR for when sed adds them
+:au! FileReadPre *.gz exe '!gzip -d ' . shellescape(expand("<afile>"))
+:au FileReadPre *.gz call rename(expand("<afile>:r"), expand("<afile>"))
+:au! FileReadPost *.gz '[,']s/l/L/
+:$r Xtestfile.gz " Read compressed file
+:w " write it, after filtering
+:au! " remove all autocommands
+:e " Edit test.out again
+:set nobin ff& " use the default fileformat for writing
+:w
+:qa!
+ENDTEST
+
+startstart
+start of testfile
+line 2 Abcdefghijklmnopqrstuvwxyz
+line 3 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 4 Abcdefghijklmnopqrstuvwxyz
+line 5 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 6 Abcdefghijklmnopqrstuvwxyz
+line 7 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 8 Abcdefghijklmnopqrstuvwxyz
+line 9 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 10 Abcdefghijklmnopqrstuvwxyz
+end of testfile
+
+start of test.c
+/*
+ * Here is a new .c file
+ */
+end of test.c
diff --git a/src/testdir/test11.ok b/src/testdir/test11.ok
new file mode 100644
index 0000000000..af8c5ce261
--- /dev/null
+++ b/src/testdir/test11.ok
@@ -0,0 +1,61 @@
+startstart
+start of testfile
+line 2 Abcdefghijklmnopqrstuvwxyz
+line 3 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 4 Abcdefghijklmnopqrstuvwxyz
+line 5 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 6 Abcdefghijklmnopqrstuvwxyz
+line 7 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 8 Abcdefghijklmnopqrstuvwxyz
+line 9 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 10 Abcdefghijklmnopqrstuvwxyz
+end of testfile
+
+start of test.c
+/*
+ * Here is a new .c file
+ */
+end of test.c
+start of testfile
+line 2 Abcdefghijklmnopqrstuvwxyz
+line 3 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+line 4 Abcdefghijklmnopqrstuvwxyz
+linE 5 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+linE 6 AbcdefghijklmnopqrstuvwXyz
+linE 7 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+linE 8 AbcdefghijklmnopqrstuvwXyz
+linE 9 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+linE 10 AbcdefghijklmnopqrstuvwXyz
+End of testfile
+
+/*
+ * HEre is a NEW .c file
+ */
+/*
+ * HEre is a new .c file
+ */
+start of tEstfile
+linE 2 AbcdefghijklmnopqrstuvwXyz
+linE 3 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+linE 4 AbcdefghijklmnopqrstuvwXyz
+linE 5 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+linE 6 AbcdefghijklmnopqrstuvwXyz
+linE 7 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+linE 8 AbcdefghijklmnopqrstuvwXyz
+linE 9 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+linE 10 AbcdefghijklmnopqrstuvwXyz
+End of testfile
+/*
+ * HEre is a new .c file
+ */
+start of testfiLe
+Line 2 Abcdefghijklmnopqrstuvwxyz
+Line 3 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+Line 4 Abcdefghijklmnopqrstuvwxyz
+Line 5 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+Line 6 Abcdefghijklmnopqrstuvwxyz
+Line 7 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+Line 8 Abcdefghijklmnopqrstuvwxyz
+Line 9 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+Line 10 Abcdefghijklmnopqrstuvwxyz
+end of testfiLe
diff --git a/src/testdir/test12.in b/src/testdir/test12.in
new file mode 100644
index 0000000000..46e9c45b80
--- /dev/null
+++ b/src/testdir/test12.in
@@ -0,0 +1,52 @@
+Tests for 'directory' option.
+- ".", in same dir as file
+- "./dir", in directory relative to file
+- "dir", in directory relative to current dir
+
+STARTTEST
+:so small.vim
+:set nocompatible viminfo+=nviminfo
+: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/testdir/test12.ok b/src/testdir/test12.ok
new file mode 100644
index 0000000000..605623b117
--- /dev/null
+++ b/src/testdir/test12.ok
@@ -0,0 +1,10 @@
+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/testdir/test13.in b/src/testdir/test13.in
new file mode 100644
index 0000000000..cb8a6fff89
--- /dev/null
+++ b/src/testdir/test13.in
@@ -0,0 +1,58 @@
+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
+:so small.vim
+:/^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
+:qa!
+ENDTEST
+
+start of testfile
+ contents
+ contents
+ contents
+end of testfile
diff --git a/src/testdir/test13.ok b/src/testdir/test13.ok
new file mode 100644
index 0000000000..0f1fc347a4
--- /dev/null
+++ b/src/testdir/test13.ok
@@ -0,0 +1,30 @@
+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
diff --git a/src/testdir/test14.in b/src/testdir/test14.in
new file mode 100644
index 0000000000..fb987ebc88
--- /dev/null
+++ b/src/testdir/test14.in
@@ -0,0 +1,99 @@
+Tests for "vaBiB", end could be wrong.
+Also test ":s/pat/sub/" with different ~s in sub.
+Also test for ^Vxff and ^Vo123 in Insert mode.
+Also test "[m", "]m", "[M" and "]M"
+Also test search()
+
+STARTTEST
+:so small.vim
+/Start cursor here
+vaBiBD:?Bug?,/Piece/-2w! test.out
+/^- Bug
+:s/u/~u~/
+:s/i/~u~/
+:s/o/~~~/
+:.w >>test.out
+:if has("ebcdic")
+: let tt = "o\<C-V>193\<C-V>xc2\<C-V>o303 \<C-V>90a\<C-V>xfg\<C-V>o578\<Esc>"
+:else
+: let tt = "o\<C-V>65\<C-V>x42\<C-V>o103 \<C-V>33a\<C-V>xfg\<C-V>o78\<Esc>"
+:endif
+:exe "normal " . tt
+:unlet tt
+:.w >>test.out
+:set vb
+/^Piece
+2]maA:.w >>test.out
+j]maB:.w >>test.out
+]maC:.w >>test.out
+[maD:.w >>test.out
+k2[maE:.w >>test.out
+3[maF:.w >>test.out
+]MaG:.w >>test.out
+j2]MaH:.w >>test.out
+]M]MaI:.w >>test.out
+2[MaJ:.w >>test.out
+k[MaK:.w >>test.out
+3[MaL:.w >>test.out
+:"
+/^foobar
+:let startline = line('.')
+:call search('foobar', 'c')
+:call append(line('$'), line('.') - startline)
+j:call search('^$', 'c')
+:call append(line('$'), line('.') - startline)
+:call search('^$', 'bc')
+:call append(line('$'), line('.') - startline)
+/two
+:call search('.', 'c')
+:call append(line('$'), getline('.')[col('.') - 1:])
+:"
+/^substitute
+:s/foo/bar/
+:$put =@/
+/^substitute
+:keeppatterns s/asdf/xyz/
+:$put =@/
+/^substitute
+Y:$put =@0
+/bar /e
+:$put =@0
+-:keeppatterns /xyz
+0dn:/^search()/,$w >>test.out
+:qa!
+ENDTEST
+
+- Bug in "vPPPP" on this text (Webb):
+ {
+ cmd;
+ {
+ cmd; /* <-- Start cursor here */
+ {
+ }
+ }
+ }
+
+Piece of Java
+{
+ tt m1 {
+ t1;
+ } e1
+
+ tt m2 {
+ t2;
+ } e2
+
+ tt m3 {
+ if (x)
+ {
+ t3;
+ }
+ } e3
+}
+
+foobar
+
+substitute foo asdf
+
+one two
+search()
diff --git a/src/testdir/test14.ok b/src/testdir/test14.ok
new file mode 100644
index 0000000000..0aa2db3f97
--- /dev/null
+++ b/src/testdir/test14.ok
@@ -0,0 +1,26 @@
+- Bug in "vPPPP" on this text (Webb):
+ {
+ }
+- Bug uuun "vPPPP" uuuuuuuuun this text (Webb):
+ABC !ag8
+ tt m1 {A
+ tt m2 {B
+ tt m3 {C
+ tt m3 {DC
+ tt m1 {EA
+{F
+ }G e1
+ }H e3
+}I
+ }JH e3
+ }K e2
+{LF
+search()
+0
+1
+1
+two
+foo
+^substitute
+substitute bar xyz
+xyz
diff --git a/src/testdir/test15.in b/src/testdir/test15.in
new file mode 100644
index 0000000000..366529a550
--- /dev/null
+++ b/src/testdir/test15.in
@@ -0,0 +1,136 @@
+Tests for :right on text with embedded TAB.
+Also test formatting a paragraph.
+Also test undo after ":%s" and formatting.
+
+STARTTEST
+:so small.vim
+:set tw=65
+
+:/^\s*test for :left/,/^\s*test for :center/ left
+:/^\s*test for :center/,/^\s*test for :right/ center
+:/^\s*test for :right/,/^xxx/-1 right
+:set fo+=tcroql tw=72
+/xxxxxxxx$
+0gq6kk
+:set nocp viminfo+=nviminfo
+:" undo/redo here to make the next undo only work on the following changes
+u
+:map gg :.,.+2s/^/x/<CR>kk:set tw=3<CR>gqq
+/^aa
+ggu
+:?test for :left?,$w! test.out
+:qa!
+ENDTEST
+
+ test for :left
+ a a
+ fa a
+ dfa a
+ sdfa a
+ asdfa a
+ xasdfa a
+asxxdfa a
+
+ test for :center
+ a a
+ fa afd asdf
+ dfa a
+ sdfa afd asdf
+ asdfa a
+ xasdfa asdfasdfasdfasdfasdf
+asxxdfa a
+
+ test for :right
+ a a
+ fa a
+ dfa a
+ sdfa a
+ asdfa a
+ xasdfa a
+ asxxdfa a
+ asxa;ofa a
+ asdfaqwer a
+ a ax
+ fa ax
+ dfa ax
+ sdfa ax
+ asdfa ax
+ xasdfa ax
+ asxxdfa ax
+ asxa;ofa ax
+ asdfaqwer ax
+ a axx
+ fa axx
+ dfa axx
+ sdfa axx
+ asdfa axx
+ xasdfa axx
+ asxxdfa axx
+ asxa;ofa axx
+ asdfaqwer axx
+ a axxx
+ fa axxx
+ dfa axxx
+ sdfa axxx
+ asdfa axxx
+ xasdfa axxx
+ asxxdfa axxx
+ asxa;ofa axxx
+ asdfaqwer axxx
+ a axxxo
+ fa axxxo
+ dfa axxxo
+ sdfa axxxo
+ asdfa axxxo
+ xasdfa axxxo
+ asxxdfa axxxo
+ asxa;ofa axxxo
+ asdfaqwer axxxo
+ a axxxoi
+ fa axxxoi
+ dfa axxxoi
+ sdfa axxxoi
+ asdfa axxxoi
+ xasdfa axxxoi
+ asxxdfa axxxoi
+ asxa;ofa axxxoi
+ asdfaqwer axxxoi
+ a axxxoik
+ fa axxxoik
+ dfa axxxoik
+ sdfa axxxoik
+ asdfa axxxoik
+ xasdfa axxxoik
+ asxxdfa axxxoik
+ asxa;ofa axxxoik
+ asdfaqwer axxxoik
+ a axxxoike
+ fa axxxoike
+ dfa axxxoike
+ sdfa axxxoike
+ asdfa axxxoike
+ xasdfa axxxoike
+ asxxdfa axxxoike
+ asxa;ofa axxxoike
+ asdfaqwer axxxoike
+ a axxxoikey
+ fa axxxoikey
+ dfa axxxoikey
+ sdfa axxxoikey
+ asdfa axxxoikey
+ xasdfa axxxoikey
+ asxxdfa axxxoikey
+ asxa;ofa axxxoikey
+ asdfaqwer axxxoikey
+
+xxxxx xx xxxxxx
+xxxxxxx xxxxxxxxx xxx xxxx xxxxx xxxxx xxx xx
+xxxxxxxxxxxxxxxxxx xxxxx xxxx, xxxx xxxx xxxx xxxx xxx xx xx
+xx xxxxxxx. xxxx xxxx.
+
+> xx xx, xxxx xxxx xxx xxxx xxx xxxxx xxx xxx xxxxxxx xxx xxxxx
+> xxxxxx xxxxxxx: xxxx xxxxxxx, xx xxxxxx xxxx xxxxxxxxxx
+
+aa aa aa aa
+bb bb bb bb
+cc cc cc cc
diff --git a/src/testdir/test15.ok b/src/testdir/test15.ok
new file mode 100644
index 0000000000..bc09f5e7db
--- /dev/null
+++ b/src/testdir/test15.ok
@@ -0,0 +1,111 @@
+test for :left
+a a
+fa a
+dfa a
+sdfa a
+asdfa a
+xasdfa a
+asxxdfa a
+
+ test for :center
+ a a
+ fa afd asdf
+ dfa a
+ sdfa afd asdf
+ asdfa a
+ xasdfa asdfasdfasdfasdfasdf
+ asxxdfa a
+
+ test for :right
+ a a
+ fa a
+ dfa a
+ sdfa a
+ asdfa a
+ xasdfa a
+ asxxdfa a
+ asxa;ofa a
+ asdfaqwer a
+ a ax
+ fa ax
+ dfa ax
+ sdfa ax
+ asdfa ax
+ xasdfa ax
+ asxxdfa ax
+ asxa;ofa ax
+ asdfaqwer ax
+ a axx
+ fa axx
+ dfa axx
+ sdfa axx
+ asdfa axx
+ xasdfa axx
+ asxxdfa axx
+ asxa;ofa axx
+ asdfaqwer axx
+ a axxx
+ fa axxx
+ dfa axxx
+ sdfa axxx
+ asdfa axxx
+ xasdfa axxx
+ asxxdfa axxx
+ asxa;ofa axxx
+ asdfaqwer axxx
+ a axxxo
+ fa axxxo
+ dfa axxxo
+ sdfa axxxo
+ asdfa axxxo
+ xasdfa axxxo
+ asxxdfa axxxo
+ asxa;ofa axxxo
+ asdfaqwer axxxo
+ a axxxoi
+ fa axxxoi
+ dfa axxxoi
+ sdfa axxxoi
+ asdfa axxxoi
+ xasdfa axxxoi
+ asxxdfa axxxoi
+ asxa;ofa axxxoi
+ asdfaqwer axxxoi
+ a axxxoik
+ fa axxxoik
+ dfa axxxoik
+ sdfa axxxoik
+ asdfa axxxoik
+ xasdfa axxxoik
+ asxxdfa axxxoik
+ asxa;ofa axxxoik
+ asdfaqwer axxxoik
+ a axxxoike
+ fa axxxoike
+ dfa axxxoike
+ sdfa axxxoike
+ asdfa axxxoike
+ xasdfa axxxoike
+ asxxdfa axxxoike
+ asxa;ofa axxxoike
+ asdfaqwer axxxoike
+ a axxxoikey
+ fa axxxoikey
+ dfa axxxoikey
+ sdfa axxxoikey
+ asdfa axxxoikey
+ xasdfa axxxoikey
+ asxxdfa axxxoikey
+ asxa;ofa axxxoikey
+ asdfaqwer axxxoikey
+
+xxxxx xx xxxxxx xxxxxxx xxxxxxxxx xxx xxxx xxxxx xxxxx xxx xx
+xxxxxxxxxxxxxxxxxx xxxxx xxxx, xxxx xxxx xxxx xxxx xxx xx xx xx xxxxxxx.
+xxxx xxxx.
+
+> xx xx, xxxx xxxx xxx xxxx xxx xxxxx xxx xxx xxxxxxx xxx xxxxx xxxxxx
+> xxxxxxx: xxxx xxxxxxx, xx xxxxxx xxxx xxxxxxxxxx
+
+aa aa aa aa
+bb bb bb bb
+cc cc cc cc
diff --git a/src/testdir/test16.in b/src/testdir/test16.in
new file mode 100644
index 0000000000..b2cd159a8c
--- /dev/null
+++ b/src/testdir/test16.in
@@ -0,0 +1,15 @@
+Tests for resetting "secure" flag after GUI has started.
+For KDE set a font, empty 'guifont' may cause a hang.
+
+STARTTEST
+:if $DISPLAY == "" | e! test.ok | wq! test.out | endif
+:set exrc secure
+:if has("gui_kde")
+: set guifont=Courier\ 10\ Pitch/8/-1/5/50/0/0/0/0/0
+:endif
+:gui -f
+:.,$w! test.out
+:qa!
+ENDTEST
+
+ just some text
diff --git a/src/testdir/test16.ok b/src/testdir/test16.ok
new file mode 100644
index 0000000000..25e2eea5c0
--- /dev/null
+++ b/src/testdir/test16.ok
@@ -0,0 +1,2 @@
+
+ just some text
diff --git a/src/testdir/test17.in b/src/testdir/test17.in
new file mode 100644
index 0000000000..bc542c7625
--- /dev/null
+++ b/src/testdir/test17.in
@@ -0,0 +1,141 @@
+Tests for:
+- "gf" on ${VAR},
+- ":checkpath!" with various 'include' settings.
+
+STARTTEST
+:so small.vim
+:if has("ebcdic")
+: set isfname=@,240-249,/,.,-,_,+,,,$,:,~,{,}
+:else
+: set isfname=@,48-57,/,.,-,_,+,,,$,:,~,{,}
+:endif
+: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
+:else
+:if has("amiga")
+:let $TDIR = "/testdir"
+:else
+:let $TDIR = "."
+:endif
+/TDIR
+:endif
+:" Dummy writing for making that sure gf doesn't fail even if the current
+:" file is modified. It can be occurred when executing the following command
+:" directly on Windows without fixing the 'fileformat':
+:" > nmake -f Make_dos.mak test17.out
+:w! test.out
+gf
+:set ff=unix
+:w! test.out
+:brewind
+ENDTEST
+
+ ${CDIR}/test17a.in
+ $TDIR/test17a.in
+
+STARTTEST
+:" check for 'include' without \zs or \ze
+:lang C
+:call delete("./Xbase.a")
+:call DeleteDirectory("Xdir1")
+:!mkdir Xdir1
+:!mkdir "Xdir1/dir2"
+:e! Xdir1/dir2/foo.a
+i#include "bar.a"
+:w
+:e Xdir1/dir2/bar.a
+i#include "baz.a"
+:w
+:e Xdir1/dir2/baz.a
+i#include "foo.a"
+:w
+:e Xbase.a
+:set path=Xdir1/dir2
+i#include <foo.a>
+:w
+:redir! >>test.out
+:checkpath!
+:redir END
+:brewind
+ENDTEST
+
+STARTTEST
+:" check for 'include' with \zs and \ze
+:call delete("./Xbase.b")
+:call DeleteDirectory("Xdir1")
+:!mkdir Xdir1
+:!mkdir "Xdir1/dir2"
+:let &include='^\s*%inc\s*/\zs[^/]\+\ze'
+:function! DotsToSlashes()
+: return substitute(v:fname, '\.', '/', 'g') . '.b'
+:endfunction
+:let &includeexpr='DotsToSlashes()'
+:e! Xdir1/dir2/foo.b
+i%inc /bar/
+:w
+:e Xdir1/dir2/bar.b
+i%inc /baz/
+:w
+:e Xdir1/dir2/baz.b
+i%inc /foo/
+:w
+:e Xbase.b
+:set path=Xdir1/dir2
+i%inc /foo/
+:w
+:redir! >>test.out
+:checkpath!
+:redir END
+:brewind
+ENDTEST
+
+STARTTEST
+:" check for 'include' with \zs and no \ze
+:call delete("./Xbase.c")
+:call DeleteDirectory("Xdir1")
+:!mkdir Xdir1
+:!mkdir "Xdir1/dir2"
+:let &include='^\s*%inc\s*\%([[:upper:]][^[:space:]]*\s\+\)\?\zs\S\+\ze'
+:function! StripNewlineChar()
+: if v:fname =~ '\n$'
+: return v:fname[:-2]
+: endif
+: return v:fname
+:endfunction
+:let &includeexpr='StripNewlineChar()'
+:e! Xdir1/dir2/foo.c
+i%inc bar.c
+:w
+:e Xdir1/dir2/bar.c
+i%inc baz.c
+:w
+:e Xdir1/dir2/baz.c
+i%inc foo.c
+:w
+:e Xdir1/dir2/FALSE.c
+i%inc foo.c
+:w
+:e Xbase.c
+:set path=Xdir1/dir2
+i%inc FALSE.c foo.c
+:w
+:redir! >>test.out
+:checkpath!
+:redir END
+:brewind
+:" change "\" to "/" for Windows and fix 'fileformat'
+:e test.out
+:%s#\\#/#g
+:set ff&
+:w
+:q
+ENDTEST
+
diff --git a/src/testdir/test17.ok b/src/testdir/test17.ok
new file mode 100644
index 0000000000..b2a66d5f85
--- /dev/null
+++ b/src/testdir/test17.ok
@@ -0,0 +1,33 @@
+This file is just to test "gf" in test 17.
+The contents is not important.
+Just testing!
+
+
+--- Included files in path ---
+Xdir1/dir2/foo.a
+Xdir1/dir2/foo.a -->
+ Xdir1/dir2/bar.a
+ Xdir1/dir2/bar.a -->
+ Xdir1/dir2/baz.a
+ Xdir1/dir2/baz.a -->
+ "foo.a" (Already listed)
+
+
+--- Included files in path ---
+Xdir1/dir2/foo.b
+Xdir1/dir2/foo.b -->
+ Xdir1/dir2/bar.b
+ Xdir1/dir2/bar.b -->
+ Xdir1/dir2/baz.b
+ Xdir1/dir2/baz.b -->
+ foo (Already listed)
+
+
+--- Included files in path ---
+Xdir1/dir2/foo.c
+Xdir1/dir2/foo.c -->
+ Xdir1/dir2/bar.c
+ Xdir1/dir2/bar.c -->
+ Xdir1/dir2/baz.c
+ Xdir1/dir2/baz.c -->
+ foo.c (Already listed)
diff --git a/src/testdir/test17a.in b/src/testdir/test17a.in
new file mode 100644
index 0000000000..7e89364797
--- /dev/null
+++ b/src/testdir/test17a.in
@@ -0,0 +1,3 @@
+This file is just to test "gf" in test 17.
+The contents is not important.
+Just testing!
diff --git a/src/testdir/test18.in b/src/testdir/test18.in
new file mode 100644
index 0000000000..9bfd922344
--- /dev/null
+++ b/src/testdir/test18.in
@@ -0,0 +1,16 @@
+Tests for not doing smart indenting when it isn't set.
+
+STARTTEST
+:so small.vim
+:set nocin nosi ai
+/some
+2cc#test
+:?start?,$w! test.out
+:qa!
+ENDTEST
+
+start text
+ some test text
+ test text
+test text
+ test text
diff --git a/src/testdir/test18.ok b/src/testdir/test18.ok
new file mode 100644
index 0000000000..e719713785
--- /dev/null
+++ b/src/testdir/test18.ok
@@ -0,0 +1,4 @@
+start text
+ #test
+test text
+ test text
diff --git a/src/testdir/test19.in b/src/testdir/test19.in
new file mode 100644
index 0000000000..aafa34e521
--- /dev/null
+++ b/src/testdir/test19.in
@@ -0,0 +1,33 @@
+Tests for "r<Tab>" with 'smarttab' and 'expandtab' set/not set.
+Also test that dv_ works correctly
+
+STARTTEST
+:so small.vim
+:set smarttab expandtab ts=8 sw=4
+:" make sure that backspace works, no matter what termcap is used
+:set t_kD=x7f t_kb=x08
+/some
+r :set noexpandtab
+/other
+r
+:" Test replacing with Tabs and then backspacing to undo it
+0wR 
+:" Test replacing with Tabs
+0wR 
+:" Test that copyindent works with expandtab set
+:set expandtab smartindent copyindent ts=8 sw=8 sts=8
+o{
+x:set nosol
+/Second line/
+fwdv_:?^start?,$w! test.out
+:qa!
+ENDTEST
+
+start text
+ some test text
+test text
+ other test text
+ a cde
+ f ghi
+test text
+ Second line beginning with whitespace
diff --git a/src/testdir/test19.ok b/src/testdir/test19.ok
new file mode 100644
index 0000000000..4146214919
--- /dev/null
+++ b/src/testdir/test19.ok
@@ -0,0 +1,10 @@
+start text
+ ome test text
+test text
+ ther test text
+ a cde
+ hi
+test text
+{
+ x
+ with whitespace
diff --git a/src/testdir/test2.in b/src/testdir/test2.in
new file mode 100644
index 0000000000..b7b5a51066
--- /dev/null
+++ b/src/testdir/test2.in
@@ -0,0 +1,29 @@
+
+This is a test if a URL is recognized by "gf", with the cursor before and
+after the "://". Also test ":\\".
+
+STARTTEST
+:so small.vim
+/^first
+/tmp
+:call append(0, expand("<cfile>"))
+/^second
+/URL
+:call append(1, expand("<cfile>"))
+:if has("ebcdic")
+: set isf=@,240-249,/,.,-,_,+,,,$,:,~,\
+:else
+: set isf=@,48-57,/,.,-,_,+,,,$,:,~,\
+:endif
+/^third
+/name
+:call append(2, expand("<cfile>"))
+/^fourth
+/URL
+:call append(3, expand("<cfile>"))
+5GdG:wq! test.out
+ENDTEST
+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
diff --git a/src/testdir/test2.ok b/src/testdir/test2.ok
new file mode 100644
index 0000000000..32978825f8
--- /dev/null
+++ b/src/testdir/test2.ok
@@ -0,0 +1,4 @@
+URL://machine.name/tmp/vimtest2a
+URL://machine.name/tmp/vimtest2b
+URL:\\machine.name\vimtest2c
+URL:\\machine.name\tmp\vimtest2d
diff --git a/src/testdir/test20.in b/src/testdir/test20.in
new file mode 100644
index 0000000000..662a1439f2
--- /dev/null
+++ b/src/testdir/test20.in
@@ -0,0 +1,28 @@
+Tests Blockwise Visual when there are TABs before the text.
+First test for undo working properly when executing commands from a register.
+Also test this in an empty buffer.
+
+STARTTEST
+:so tiny.vim
+G0"ay$k@au
+:new
+@auY:quit!
+GP
+/start here$
+"by$jjlld
+/456$
+jj"bP
+:/56$/,$-1w! test.out
+:qa!
+ENDTEST
+
+123456
+234567
+345678
+
+test text test tex start here
+ some text
+ test text
+test text
+
+OxjAykdd
diff --git a/src/testdir/test20.ok b/src/testdir/test20.ok
new file mode 100644
index 0000000000..7c50ea8db8
--- /dev/null
+++ b/src/testdir/test20.ok
@@ -0,0 +1,10 @@
+123start here56
+234start here67
+345start here78
+
+test text test tex rt here
+ somext
+ tesext
+test text
+
+
diff --git a/src/testdir/test21.in b/src/testdir/test21.in
new file mode 100644
index 0000000000..491b9f7404
--- /dev/null
+++ b/src/testdir/test21.in
@@ -0,0 +1,19 @@
+Tests for [ CTRL-I with a count and CTRL-W CTRL-I with a count
+
+STARTTEST
+:so small.vim
+/start
+6[ :.w! test.out
+?start here
+6 :.w >>test.out
+:qa!
+ENDTEST
+
+#include test21.in
+
+/* test text test tex start here
+ some text
+ test text
+ start OK if found this line
+ start found wrong line
+test text
diff --git a/src/testdir/test21.ok b/src/testdir/test21.ok
new file mode 100644
index 0000000000..d9f1b759ce
--- /dev/null
+++ b/src/testdir/test21.ok
@@ -0,0 +1,2 @@
+ start OK if found this line
+ start OK if found this line
diff --git a/src/testdir/test22.in b/src/testdir/test22.in
new file mode 100644
index 0000000000..f5cc046c6a
--- /dev/null
+++ b/src/testdir/test22.in
@@ -0,0 +1,13 @@
+Tests for file with some lines ending in CTRL-M, some not
+
+STARTTEST
+:set ta tx
+:e!
+:$-3,$w! test.out
+:qa!
+ENDTEST
+
+this lines ends in a
+this one doesn't
+this one does
+and the last one doesn't
diff --git a/src/testdir/test22.ok b/src/testdir/test22.ok
new file mode 100644
index 0000000000..38ff89eaf3
--- /dev/null
+++ b/src/testdir/test22.ok
@@ -0,0 +1,4 @@
+this lines ends in a
+this one doesn't
+this one does
+and the last one doesn't
diff --git a/src/testdir/test23.in b/src/testdir/test23.in
new file mode 100644
index 0000000000..0e0e605531
--- /dev/null
+++ b/src/testdir/test23.in
@@ -0,0 +1,15 @@
+Tests for complicated + argument to :edit command
+
+STARTTEST
+:$-1w! Xfile1
+:$w! Xfile2
+:edit +1|s/|/PIPE/|w Xfile1| e Xfile2|1 | s/\//SLASH/|w
+:w! test.out
+:e Xfile1
+:w >> test.out
+:qa!
+ENDTEST
+
+The result should be in Xfile1: "fooPIPEbar", in Xfile2: "fooSLASHbar"
+foo|bar
+foo/bar
diff --git a/src/testdir/test23.ok b/src/testdir/test23.ok
new file mode 100644
index 0000000000..f1930abad6
--- /dev/null
+++ b/src/testdir/test23.ok
@@ -0,0 +1,2 @@
+fooSLASHbar
+fooPIPEbar
diff --git a/src/testdir/test24.in b/src/testdir/test24.in
new file mode 100644
index 0000000000..7dfc1afdc6
--- /dev/null
+++ b/src/testdir/test24.in
Binary files differ
diff --git a/src/testdir/test24.ok b/src/testdir/test24.ok
new file mode 100644
index 0000000000..cd61210968
--- /dev/null
+++ b/src/testdir/test24.ok
@@ -0,0 +1,32 @@
+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/testdir/test25.in b/src/testdir/test25.in
new file mode 100644
index 0000000000..4139865daf
--- /dev/null
+++ b/src/testdir/test25.in
@@ -0,0 +1,31 @@
+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.
+
+STARTTEST
+:so small.vim
+:set hidden
+:" Create a link from test25.dir to the current directory.
+:!rm -f test25.dir
+:!ln -s . test25.dir
+:" Create tags.text, with the current directory name inserted.
+/tags line
+:r !pwd
+d$/test
+hP:.w! tags.test
+:" Try jumping to a tag in the current file, 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=tags.test
+G x:.w! test.out
+:!rm -f test25.dir tags.test
+:qa!
+ENDTEST
+
+tags line:
+SECTION_OFF /test25.dir/test25.in /^#define SECTION_OFF 3$/
+
+/*tx.c*/
+#define SECTION_OFF 3
+#define NUM_SECTIONS 3
+
+SECTION_OFF
diff --git a/src/testdir/test25.ok b/src/testdir/test25.ok
new file mode 100644
index 0000000000..08fc070b7b
--- /dev/null
+++ b/src/testdir/test25.ok
@@ -0,0 +1 @@
+#efine SECTION_OFF 3
diff --git a/src/testdir/test26.in b/src/testdir/test26.in
new file mode 100644
index 0000000000..e7cd757661
--- /dev/null
+++ b/src/testdir/test26.in
@@ -0,0 +1,44 @@
+Test for :execute, :while and :if
+
+STARTTEST
+:so small.vim
+mt: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
+:'t,$w! test.out
+:qa!
+ENDTEST
+
diff --git a/src/testdir/test26.ok b/src/testdir/test26.ok
new file mode 100644
index 0000000000..bc44761187
--- /dev/null
+++ b/src/testdir/test26.ok
@@ -0,0 +1,10 @@
+
+1x999999999888888887777777666666555554444333221
+2
+3x999999999888888887777777666666555554444333221
+4
+5x
+6
+7x999999999888888887777777666666555554444333221
+8
+9x
diff --git a/src/testdir/test27.in b/src/testdir/test27.in
new file mode 100644
index 0000000000..2df16d9eff
--- /dev/null
+++ b/src/testdir/test27.in
@@ -0,0 +1,20 @@
+Test for expanding file names
+
+STARTTEST
+:!mkdir Xdir1
+:!mkdir Xdir2
+:!mkdir Xdir3
+:cd Xdir3
+:!mkdir Xdir4
+:cd ..
+:w Xdir1/file
+:w Xdir3/Xdir4/file
+:n Xdir?/*/file
+Go%:.w! test.out
+:n! Xdir?/*/nofile
+Go%:.w >>test.out
+:e! xx
+:!rm -rf Xdir1 Xdir2 Xdir3
+:qa!
+ENDTEST
+
diff --git a/src/testdir/test27.ok b/src/testdir/test27.ok
new file mode 100644
index 0000000000..c35f2438a9
--- /dev/null
+++ b/src/testdir/test27.ok
@@ -0,0 +1,2 @@
+Xdir3/Xdir4/file
+Xdir?/*/nofile
diff --git a/src/testdir/test28.in b/src/testdir/test28.in
new file mode 100644
index 0000000000..5542c92666
--- /dev/null
+++ b/src/testdir/test28.in
Binary files differ
diff --git a/src/testdir/test28.ok b/src/testdir/test28.ok
new file mode 100644
index 0000000000..911d854655
--- /dev/null
+++ b/src/testdir/test28.ok
@@ -0,0 +1,2 @@
+sd
+map __2 asdsecondsdsd0map __5 asd0fifth
diff --git a/src/testdir/test29.in b/src/testdir/test29.in
new file mode 100644
index 0000000000..2df2f7077e
--- /dev/null
+++ b/src/testdir/test29.in
@@ -0,0 +1,202 @@
+Test for joining lines and marks in them
+ in compatible and nocompatible modes
+ and with 'joinspaces' set or not
+ and with 'cpoptions' flag 'j' set or not
+
+STARTTEST
+:so small.vim
+:set nocompatible viminfo+=nviminfo
+:set nojoinspaces
+:set cpoptions-=j
+/firstline/
+j"td/^STARTTEST/-1
+PJjJjJjJjJjJjJjJjJjJjJjJjJjJj05lmx2j06lmy2k4Jy3l$p`xyl$p`yy2l$p:set cpoptions+=j
+j05lmx2j06lmy2k4Jy3l$p`xyl$p`yy2l$p:set cpoptions-=j joinspaces
+j"tpJjJjJjJjJjJjJjJjJjJjJjJjJjJj05lmx2j06lmy2k4Jy3l$p`xyl$p`yy2l$p:set cpoptions+=j
+j05lmx2j06lmy2k4Jy3l$p`xyl$p`yy2l$p:set cpoptions-=j nojoinspaces compatible
+j"tpJjJjJjJjJjJjJjJjJjJjJjJjJjJj4Jy3l$pjd/STARTTEST/-2
+ENDTEST
+
+firstline
+asdfasdf.
+asdf
+asdfasdf.
+asdf
+asdfasdf.
+asdf
+asdfasdf.
+asdf
+asdfasdf.
+asdf
+asdfasdf.
+asdf
+asdfasdf.
+asdf
+asdfasdf
+asdf
+asdfasdf
+asdf
+asdfasdf
+asdf
+asdfasdf
+asdf
+asdfasdf
+asdf
+asdfasdf
+asdf
+asdfasdf
+asdf
+zx cvn.
+as dfg?
+hjkl iop!
+ert
+zx cvn.
+as dfg?
+hjkl iop!
+ert
+
+STARTTEST
+/^{/+1
+:set comments=s1:/*,mb:*,ex:*/,://
+:set nojoinspaces fo=j
+:set backspace=eol,start
+:.,+3join
+j4J
+:.,+2join
+j3J
+:.,+2join
+j3J
+:.,+2join
+jj3J
+ENDTEST
+
+{
+
+/*
+ * Make sure the previous comment leader is not removed.
+ */
+
+/*
+ * Make sure the previous comment leader is not removed.
+ */
+
+// Should the next comment leader be left alone?
+// Yes.
+
+// Should the next comment leader be left alone?
+// Yes.
+
+/* Here the comment leader should be left intact. */
+// And so should this one.
+
+/* Here the comment leader should be left intact. */
+// And so should this one.
+
+if (condition) // Remove the next comment leader!
+ // OK, I will.
+ action();
+
+if (condition) // Remove the next comment leader!
+ // OK, I will.
+ action();
+}
+
+STARTTEST
+/^{/+1
+:set comments=sO:*\ -,mO:*\ \ ,exO:*/
+:set comments+=s1:/*,mb:*,ex:*/,://
+:set comments+=s1:>#,mb:#,ex:#<,:<
+:set cpoptions-=j joinspaces fo=j
+:set backspace=eol,start
+:.,+3join
+j4J
+:.,+8join
+j9J
+:.,+2join
+j3J
+:.,+2join
+j3J
+:.,+2join
+jj3J
+j:.,+2join
+jj3J
+j:.,+5join
+j6J
+oSome code! // Make sure backspacing does not remove this comment leader.0i
+ENDTEST
+
+{
+
+/*
+ * Make sure the previous comment leader is not removed.
+ */
+
+/*
+ * Make sure the previous comment leader is not removed.
+ */
+
+/* List:
+ * - item1
+ * foo bar baz
+ * foo bar baz
+ * - item2
+ * foo bar baz
+ * foo bar baz
+ */
+
+/* List:
+ * - item1
+ * foo bar baz
+ * foo bar baz
+ * - item2
+ * foo bar baz
+ * foo bar baz
+ */
+
+// Should the next comment leader be left alone?
+// Yes.
+
+// Should the next comment leader be left alone?
+// Yes.
+
+/* Here the comment leader should be left intact. */
+// And so should this one.
+
+/* Here the comment leader should be left intact. */
+// And so should this one.
+
+if (condition) // Remove the next comment leader!
+ // OK, I will.
+ action();
+
+if (condition) // Remove the next comment leader!
+ // OK, I will.
+ action();
+
+int i = 7 /* foo *// 3
+ // comment
+ ;
+
+int i = 7 /* foo *// 3
+ // comment
+ ;
+
+># Note that the last character of the ending comment leader (left angle
+ # bracket) is a comment leader itself. Make sure that this comment leader is
+ # not removed from the next line #<
+< On this line a new comment is opened which spans 2 lines. This comment should
+< retain its comment leader.
+
+># Note that the last character of the ending comment leader (left angle
+ # bracket) is a comment leader itself. Make sure that this comment leader is
+ # not removed from the next line #<
+< On this line a new comment is opened which spans 2 lines. This comment should
+< retain its comment leader.
+
+}
+
+STARTTEST
+:g/^STARTTEST/.,/^ENDTEST/d
+:?firstline?+1,$w! test.out
+:qa!
+ENDTEST
diff --git a/src/testdir/test29.ok b/src/testdir/test29.ok
new file mode 100644
index 0000000000..902d52f49b
--- /dev/null
+++ b/src/testdir/test29.ok
@@ -0,0 +1,88 @@
+asdfasdf. asdf
+asdfasdf. asdf
+asdfasdf. asdf
+asdfasdf. asdf
+asdfasdf. asdf
+asdfasdf. asdf
+asdfasdf. asdf
+asdfasdf asdf
+asdfasdf asdf
+asdfasdf asdf
+asdfasdf asdf
+asdfasdf asdf
+asdfasdf asdf
+asdfasdf asdf
+zx cvn. as dfg? hjkl iop! ert ernop
+zx cvn. as dfg? hjkl iop! ert ernop
+
+asdfasdf. asdf
+asdfasdf. asdf
+asdfasdf. asdf
+asdfasdf. asdf
+asdfasdf. asdf
+asdfasdf. asdf
+asdfasdf. asdf
+asdfasdf asdf
+asdfasdf asdf
+asdfasdf asdf
+asdfasdf asdf
+asdfasdf asdf
+asdfasdf asdf
+asdfasdf asdf
+zx cvn. as dfg? hjkl iop! ert enop
+zx cvn. as dfg? hjkl iop! ert ernop
+
+asdfasdf. asdf
+asdfasdf. asdf
+asdfasdf. asdf
+asdfasdf. asdf
+asdfasdf. asdf
+asdfasdf. asdf
+asdfasdf. asdf
+asdfasdf asdf
+asdfasdf asdf
+asdfasdf asdf
+asdfasdf asdf
+asdfasdf asdf
+asdfasdf asdf
+asdfasdf asdf
+zx cvn. as dfg? hjkl iop! ert a
+
+
+{
+/* Make sure the previous comment leader is not removed. */
+/* Make sure the previous comment leader is not removed. */
+// Should the next comment leader be left alone? Yes.
+// Should the next comment leader be left alone? Yes.
+/* Here the comment leader should be left intact. */ // And so should this one.
+/* Here the comment leader should be left intact. */ // And so should this one.
+if (condition) // Remove the next comment leader! OK, I will.
+ action();
+if (condition) // Remove the next comment leader! OK, I will.
+ action();
+}
+
+
+{
+/* Make sure the previous comment leader is not removed. */
+/* Make sure the previous comment leader is not removed. */
+/* List: item1 foo bar baz foo bar baz item2 foo bar baz foo bar baz */
+/* List: item1 foo bar baz foo bar baz item2 foo bar baz foo bar baz */
+// Should the next comment leader be left alone? Yes.
+// Should the next comment leader be left alone? Yes.
+/* Here the comment leader should be left intact. */ // And so should this one.
+/* Here the comment leader should be left intact. */ // And so should this one.
+if (condition) // Remove the next comment leader! OK, I will.
+ action();
+if (condition) // Remove the next comment leader! OK, I will.
+ action();
+int i = 7 /* foo *// 3 // comment
+ ;
+int i = 7 /* foo *// 3 // comment
+ ;
+># Note that the last character of the ending comment leader (left angle bracket) is a comment leader itself. Make sure that this comment leader is not removed from the next line #< < On this line a new comment is opened which spans 2 lines. This comment should retain its comment leader.
+># Note that the last character of the ending comment leader (left angle bracket) is a comment leader itself. Make sure that this comment leader is not removed from the next line #< < On this line a new comment is opened which spans 2 lines. This comment should retain its comment leader.
+
+Some code!// Make sure backspacing does not remove this comment leader.
+}
+
diff --git a/src/testdir/test3.in b/src/testdir/test3.in
new file mode 100644
index 0000000000..a7543945c4
--- /dev/null
+++ b/src/testdir/test3.in
@@ -0,0 +1,2056 @@
+/* vim: set cin ts=4 sw=4 : */
+
+Test for 'cindent'
+
+STARTTEST
+:so small.vim
+:set nocompatible viminfo+=nviminfo modeline
+:edit " read modeline
+/start of AUTO
+=/end of AUTO
+ENDTEST
+
+/* start of AUTO matically checked vim: set ts=4 : */
+{
+ if (test)
+ cmd1;
+ cmd2;
+}
+
+{
+ if (test)
+ cmd1;
+ else
+ cmd2;
+}
+
+{
+ if (test)
+ {
+ cmd1;
+ cmd2;
+ }
+}
+
+{
+ if (test)
+ {
+ cmd1;
+ else
+ }
+}
+
+{
+ while (this)
+ if (test)
+ cmd1;
+ cmd2;
+}
+
+{
+ while (this)
+ if (test)
+ cmd1;
+ else
+ cmd2;
+}
+
+{
+ if (test)
+ {
+ cmd;
+ }
+
+ if (test)
+ cmd;
+}
+
+{
+ if (test) {
+ cmd;
+ }
+
+ if (test) cmd;
+}
+
+{
+ cmd1;
+ for (blah)
+ while (this)
+ if (test)
+ cmd2;
+ cmd3;
+}
+
+{
+ cmd1;
+ for (blah)
+ while (this)
+ if (test)
+ cmd2;
+ cmd3;
+
+ if (test)
+ {
+ cmd1;
+ cmd2;
+ cmd3;
+ }
+}
+
+
+/* Test for 'cindent' do/while mixed with if/else: */
+
+{
+ do
+ if (asdf)
+ asdfasd;
+ while (cond);
+
+ do
+ if (asdf)
+ while (asdf)
+ asdf;
+ while (asdf);
+}
+
+/* Test for 'cindent' with two ) on a continuation line */
+{
+ if (asdfasdf;asldkfj asdlkfj as;ldkfj sal;d
+ aal;sdkjf ( ;asldfkja;sldfk
+ al;sdjfka ;slkdf ) sa;ldkjfsa dlk;)
+ line up here;
+}
+
+
+/* C++ tests: */
+
+// foo() these three lines should remain in column 0
+// {
+// }
+
+/* Test for continuation and unterminated lines: */
+{
+ i = 99 + 14325 +
+ 21345 +
+ 21345 +
+ 21345 + ( 21345 +
+ 21345) +
+ 2345 +
+ 1234;
+ c = 1;
+}
+
+/*
+ testje for indent with empty line
+
+ here */
+
+{
+ if (testing &&
+ not a joke ||
+ line up here)
+ hay;
+ if (testing &&
+ (not a joke || testing
+ )line up here)
+ hay;
+ if (testing &&
+ (not a joke || testing
+ line up here))
+ hay;
+}
+
+
+{
+ switch (c)
+ {
+ case xx:
+ do
+ if (asdf)
+ do
+ asdfasdf;
+ while (asdf);
+ else
+ asdfasdf;
+ while (cond);
+ case yy:
+ case xx:
+ case zz:
+ testing;
+ }
+}
+
+{
+ if (cond) {
+ foo;
+ }
+ else
+ {
+ bar;
+ }
+}
+
+{
+ if (alskdfj ;alsdkfjal;skdjf (;sadlkfsa ;dlkf j;alksdfj ;alskdjf
+ alsdkfj (asldk;fj
+ awith cino=(0 ;lf this one goes to below the paren with ==
+ ;laksjfd ;lsakdjf ;alskdf asd)
+ asdfasdf;)))
+ asdfasdf;
+}
+
+ int
+func(a, b)
+ int a;
+ int c;
+{
+ if (c1 && (c2 ||
+ c3))
+ foo;
+ if (c1 &&
+ (c2 || c3)
+ )
+}
+
+{
+ while (asd)
+ {
+ if (asdf)
+ if (test)
+ if (that)
+ {
+ if (asdf)
+ do
+ cdasd;
+ while (as
+ df);
+ }
+ else
+ if (asdf)
+ asdf;
+ else
+ asdf;
+ asdf;
+ }
+}
+
+{
+ s = "/*"; b = ';'
+ s = "/*"; b = ';';
+ a = b;
+}
+
+{
+ switch (a)
+ {
+ case a:
+ switch (t)
+ {
+ case 1:
+ cmd;
+ break;
+ case 2:
+ cmd;
+ break;
+ }
+ cmd;
+ break;
+ case b:
+ {
+ int i;
+ cmd;
+ }
+ break;
+ case c: {
+ int i;
+ cmd;
+ }
+ case d: if (cond &&
+ test) { /* this line doesn't work right */
+ int i;
+ cmd;
+ }
+ break;
+ }
+}
+
+{
+ if (!(vim_strchr(p_cpo, CPO_BUFOPTGLOB) != NULL && entering) &&
+ (bp_to->b_p_initialized ||
+ (!entering && vim_strchr(p_cpo, CPO_BUFOPT) != NULL)))
+ return;
+label :
+ asdf = asdf ?
+ asdf : asdf;
+ asdf = asdf ?
+ asdf: asdf;
+}
+
+/* Special Comments : This function has the added complexity (compared */
+/* : to addtolist) of having to check for a detail */
+/* : texture and add that to the list first. */
+
+char *(array[100]) = {
+ "testje",
+ "foo",
+ "bar",
+}
+
+enum soppie
+{
+yes = 0,
+no,
+maybe
+};
+
+typedef enum soppie
+{
+yes = 0,
+no,
+maybe
+};
+
+static enum
+{
+yes = 0,
+no,
+maybe
+} soppie;
+
+public static enum
+{
+yes = 0,
+no,
+maybe
+} soppie;
+
+static private enum
+{
+yes = 0,
+no,
+maybe
+} soppie;
+
+{
+ int a,
+ b;
+}
+
+{
+ struct Type
+ {
+ int i;
+ char *str;
+ } var[] =
+ {
+ 0, "zero",
+ 1, "one",
+ 2, "two",
+ 3, "three"
+ };
+
+ float matrix[3][3] =
+ {
+ {
+ 0,
+ 1,
+ 2
+ },
+ {
+ 3,
+ 4,
+ 5
+ },
+ {
+ 6,
+ 7,
+ 8
+ }
+ };
+}
+
+{
+ /* blah ( blah */
+ /* where does this go? */
+
+ /* blah ( blah */
+ cmd;
+
+ func(arg1,
+ /* comment */
+ arg2);
+ a;
+ {
+ b;
+ {
+ c; /* Hey, NOW it indents?! */
+ }
+ }
+
+ {
+ func(arg1,
+ arg2,
+ arg3);
+ /* Hey, what am I doing here? Is this coz of the ","? */
+ }
+}
+
+main ()
+{
+ if (cond)
+ {
+ a = b;
+ }
+ if (cond) {
+ a = c;
+ }
+ if (cond)
+ a = d;
+ return;
+}
+
+{
+ case 2: if (asdf &&
+ asdfasdf)
+ aasdf;
+ a = 9;
+ case 3: if (asdf)
+ aasdf;
+ a = 9;
+ case 4: x = 1;
+ y = 2;
+
+label: if (asdf)
+ here;
+
+label: if (asdf &&
+ asdfasdf)
+ {
+ }
+
+label: if (asdf &&
+ asdfasdf) {
+ there;
+ }
+
+label: if (asdf &&
+ asdfasdf)
+ there;
+}
+
+{
+ /*
+ hello with ":set comments= cino=c5"
+ */
+
+ /*
+ hello with ":set comments= cino="
+ */
+}
+
+
+{
+ if (a < b) {
+ a = a + 1;
+ } else
+ a = a + 2;
+
+ if (a)
+ do {
+ testing;
+ } while (asdfasdf);
+ a = b + 1;
+ asdfasdf
+}
+
+class bob
+{
+ int foo() {return 1;}
+ int bar;
+}
+
+main()
+{
+while(1)
+if (foo)
+{
+bar;
+}
+else {
+asdf;
+}
+misplacedline;
+}
+
+{
+ if (clipboard.state == SELECT_DONE
+ && ((row == clipboard.start.lnum
+ && col >= clipboard.start.col)
+ || row > clipboard.start.lnum))
+}
+
+{
+if (1) {i += 4;}
+where_am_i;
+return 0;
+}
+
+{
+{
+} // sdf(asdf
+if (asdf)
+asd;
+}
+
+{
+label1:
+label2:
+}
+
+{
+int fooRet = foo(pBar1, false /*fKB*/,
+ true /*fPTB*/, 3 /*nT*/, false /*fDF*/);
+f() {
+for ( i = 0;
+ i < m;
+ /* c */ i++ ) {
+a = b;
+}
+}
+}
+
+{
+ f1(/*comment*/);
+ f2();
+}
+
+{
+do {
+if (foo) {
+} else
+;
+} while (foo);
+foo(); // was wrong
+}
+
+int x; // no extra indent because of the ;
+void func()
+{
+}
+
+char *tab[] = {"aaa",
+ "};", /* }; */ NULL}
+ int indented;
+{}
+
+char *a[] = {"aaa", "bbb",
+ "ccc", NULL};
+// here
+
+char *tab[] = {"aaa",
+ "xx", /* xx */}; /* asdf */
+int not_indented;
+
+{
+ do {
+ switch (bla)
+ {
+ case 1: if (foo)
+ bar;
+ }
+ } while (boo);
+ wrong;
+}
+
+int foo,
+ bar;
+int foo;
+
+#if defined(foo) \
+ && defined(bar)
+char * xx = "asdf\
+ foo\
+ bor";
+int x;
+
+char *foo = "asdf\
+ asdf\
+ asdf",
+ *bar;
+
+void f()
+{
+#if defined(foo) \
+ && defined(bar)
+char *foo = "asdf\
+ asdf\
+ asdf",
+ *bar;
+ {
+ int i;
+char *foo = "asdf\
+ asdf\
+ asdf",
+ *bar;
+ }
+#endif
+}
+#endif
+
+int y; // comment
+ // comment
+
+ // comment
+
+{
+ Constructor(int a,
+ int b ) : BaseClass(a)
+ {
+ }
+}
+
+void foo()
+{
+ char one,
+ two;
+ struct bla piet,
+ jan;
+ enum foo kees,
+ jannie;
+ static unsigned sdf,
+ krap;
+ unsigned int piet,
+ jan;
+ int
+ kees,
+ jan;
+}
+
+{
+ t(int f,
+ int d); // )
+ d();
+}
+
+Constructor::Constructor(int a,
+ int b
+ ) :
+ BaseClass(a,
+ b,
+ c),
+ mMember(b),
+{
+}
+
+Constructor::Constructor(int a,
+ int b ) :
+ BaseClass(a)
+{
+}
+
+Constructor::Constructor(int a,
+ int b ) /*x*/ : /*x*/ BaseClass(a),
+ member(b)
+{
+}
+
+class CAbc :
+ public BaseClass1,
+ protected BaseClass2
+{
+ int Test() { return FALSE; }
+ int Test1() { return TRUE; }
+
+ CAbc(int a, int b ) :
+ BaseClass(a)
+ {
+ switch(xxx)
+ {
+ case abc:
+ asdf();
+ break;
+
+ case 999:
+ baer();
+ break;
+ }
+ }
+
+public: // <-- this was incoreectly indented before!!
+ void testfall();
+protected:
+ void testfall();
+};
+
+class CAbc : public BaseClass1,
+ protected BaseClass2
+{
+};
+
+static struct
+{
+ int a;
+ int b;
+} variable[COUNT] =
+{
+ {
+ 123,
+ 456
+ },
+ {
+ 123,
+ 456
+ }
+};
+
+static struct
+{
+ int a;
+ int b;
+} variable[COUNT] =
+{
+ { 123, 456 },
+ { 123, 456 }
+};
+
+void asdf() /* ind_maxparen may cause trouble here */
+{
+ if ((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)) break;
+}
+
+foo()
+{
+ a = cond ? foo() : asdf
+ + asdf;
+
+ a = cond ?
+ foo() : asdf
+ + asdf;
+}
+
+int main(void)
+{
+ if (a)
+ if (b)
+ 2;
+ else 3;
+ next_line_of_code();
+}
+
+barry()
+{
+ Foo::Foo (int one,
+ int two)
+ : something(4)
+ {}
+}
+
+barry()
+{
+ Foo::Foo (int one, int two)
+ : something(4)
+ {}
+}
+
+Constructor::Constructor(int a,
+ int b
+ ) :
+ BaseClass(a,
+ b,
+ c),
+ mMember(b)
+{
+}
+ int main ()
+ {
+ if (lala)
+ do
+ ++(*lolo);
+ while (lili
+ && lele);
+ lulu;
+ }
+
+int main ()
+{
+switch (c)
+{
+case 'c': if (cond)
+{
+}
+}
+}
+
+main()
+{
+ (void) MyFancyFuasdfadsfnction(
+ argument);
+}
+
+main()
+{
+ char foo[] = "/*";
+ /* as
+ df */
+ hello
+}
+
+/* valid namespaces with normal indent */
+namespace
+{
+{
+ 111111111111;
+}
+}
+namespace /* test */
+{
+ 11111111111111111;
+}
+namespace // test
+{
+ 111111111111111111;
+}
+namespace
+{
+ 111111111111111111;
+}
+namespace test
+{
+ 111111111111111111;
+}
+namespace{
+ 111111111111111111;
+}
+namespace test{
+ 111111111111111111;
+}
+namespace {
+ 111111111111111111;
+}
+namespace test {
+ 111111111111111111;
+namespace test2 {
+ 22222222222222222;
+}
+}
+
+/* invalid namespaces use block indent */
+namespace test test2 {
+ 111111111111111111111;
+}
+namespace11111111111 {
+ 111111111111;
+}
+namespace() {
+ 1111111111111;
+}
+namespace()
+{
+ 111111111111111111;
+}
+namespace test test2
+{
+ 1111111111111111111;
+}
+namespace111111111
+{
+ 111111111111111111;
+}
+
+/* end of AUTO */
+
+STARTTEST
+:set tw=0 wm=60 columns=80 noai fo=croq
+/serious/e
+a about life, the universe, and the rest
+ENDTEST
+
+{
+
+/* this is
+ * a real serious important big
+ * comment
+ */
+ /* insert " about life, the universe, and the rest" after "serious" */
+}
+
+STARTTEST
+:set nocin
+/comments
+joabout life/happens
+jothere/below
+oline/this
+Ohello
+ENDTEST
+
+{
+ /*
+ * Testing for comments, without 'cin' set
+ */
+
+/*
+* what happens here?
+*/
+
+ /*
+ the end of the comment, try inserting a line below */
+
+ /* how about
+ this one */
+}
+
+STARTTEST
+:set cin
+/vec2
+==
+ENDTEST
+
+{
+ var = this + that + vec[0] * vec[0]
+ + vec[1] * vec[1]
+ + vec2[2] * vec[2];
+}
+
+STARTTEST
+:set cin
+:set cino=}4
+/testing1
+k2==/testing2
+k2==
+ENDTEST
+
+{
+ asdf asdflkajds f;
+ if (tes & ting) {
+ asdf asdf asdf ;
+ asdfa sdf asdf;
+ }
+ testing1;
+ if (tes & ting)
+ {
+ asdf asdf asdf ;
+ asdfa sdf asdf;
+ }
+ testing2;
+}
+
+STARTTEST
+:set cin
+:set cino=(0,)20
+/main
+=][
+ENDTEST
+
+main ( int first_par, /*
+ * Comment for
+ * first par
+ */
+ int second_par /*
+ * Comment for
+ * second par
+ */
+ )
+{
+ func( first_par, /*
+ * Comment for
+ * first par
+ */
+ second_par /*
+ * Comment for
+ * second par
+ */
+ );
+
+}
+
+STARTTEST
+:set cin
+:set cino=es,n0s
+/main
+=][
+ENDTEST
+
+main(void)
+{
+ /* Make sure that cino=X0s is not parsed like cino=Xs. */
+ if (cond)
+ foo();
+ else
+ {
+ bar();
+ }
+}
+
+STARTTEST
+:set cin
+:set cino=
+]]=][
+ENDTEST
+
+{
+ do
+ {
+ if ()
+ {
+ if ()
+ asdf;
+ else
+ asdf;
+ }
+ } while ();
+ cmd; /* this should go under the } */
+}
+
+STARTTEST
+]]=][
+ENDTEST
+
+void f()
+{
+ if ( k() ) {
+ l();
+
+ } else { /* Start (two words) end */
+ m();
+ }
+
+ n();
+}
+
+STARTTEST
+:set cino={s,e-s
+]]=][
+ENDTEST
+
+void f()
+{
+ if ( k() )
+ {
+ l();
+ } else { /* Start (two words) end */
+ m();
+ }
+ n(); /* should be under the if () */
+}
+
+STARTTEST
+:set cino={s,fs
+]]=/ foo
+ENDTEST
+
+void bar(void)
+{
+ static array[2][2] =
+ {
+ { 1, 2 },
+ { 3, 4 },
+ }
+
+ while (a)
+ {
+ foo(&a);
+ }
+
+ {
+ int a;
+ {
+ a = a + 1;
+ }
+ }
+ b = a;
+ }
+
+void func(void)
+ {
+ a = 1;
+ {
+ b = 2;
+ }
+ c = 3;
+ d = 4;
+ }
+/* foo */
+
+STARTTEST
+:set cino=
+/while
+ohere
+ENDTEST
+
+a()
+{
+ do {
+ a = a +
+ a;
+ } while ( a ); /* add text under this line */
+ if ( a )
+ a;
+}
+
+STARTTEST
+:set cino= com=
+/comment
+olabel2: b(); label3 /* post */: /* pre */ label4: f(/*com*/); if (/*com*/) cmd();
+ENDTEST
+
+a()
+{
+label1:
+ /* hmm */
+ // comment
+}
+
+STARTTEST
+:set comments& comments^=s:/*,m:**,ex:*/
+/simple
+=5j
+ENDTEST
+
+/*
+ * A simple comment
+ */
+
+/*
+ ** A different comment
+ */
+
+STARTTEST
+:set cino=c0
+:set comments& comments-=s1:/* comments^=s0:/*
+2kdd]]=][
+ENDTEST
+
+void f()
+{
+
+ /*********
+ A comment.
+*********/
+}
+
+STARTTEST
+:set cino=c0,C1
+:set comments& comments-=s1:/* comments^=s0:/*
+2kdd]]=][
+ENDTEST
+
+void f()
+{
+
+ /*********
+ A comment.
+*********/
+}
+
+STARTTEST
+:set cino=
+]]=][
+ENDTEST
+
+void f()
+{
+ c = c1 &&
+ (
+ c2 ||
+ c3
+ ) && c4;
+}
+
+STARTTEST
+:set cino=(s
+2kdd]]=][
+ENDTEST
+
+void f()
+{
+ c = c1 &&
+ (
+ c2 ||
+ c3
+ ) && c4;
+}
+
+STARTTEST
+:set cino=(s,U1
+2kdd]]=][
+ENDTEST
+
+void f()
+{
+ c = c1 &&
+ (
+ c2 ||
+ c3
+ ) && c4;
+}
+
+STARTTEST
+:set cino=(0
+2kdd]]=][
+ENDTEST
+
+void f()
+{
+ if ( c1
+ && ( c2
+ || c3))
+ foo;
+}
+
+STARTTEST
+:set cino=(0,w1
+2kdd]]=][
+ENDTEST
+
+void f()
+{
+ if ( c1
+ && ( c2
+ || c3))
+ foo;
+}
+
+STARTTEST
+:set cino=(s
+2kdd]]=][
+ENDTEST
+
+void f()
+{
+ c = c1 && (
+ c2 ||
+ c3
+ ) && c4;
+ if (
+ c1 && c2
+ )
+ foo;
+}
+
+STARTTEST
+:set cino=(s,m1
+2kdd]]=][
+ENDTEST
+
+void f()
+{
+ c = c1 && (
+ c2 ||
+ c3
+ ) && c4;
+ if (
+ c1 && c2
+ )
+ foo;
+}
+
+STARTTEST
+:set cino=b1
+2kdd]]=][
+ENDTEST
+
+void f()
+{
+ switch (x)
+ {
+ case 1:
+ a = b;
+ break;
+ default:
+ a = 0;
+ break;
+ }
+}
+
+STARTTEST
+:set cino=(0,W5
+2kdd]]=][
+ENDTEST
+
+void f()
+{
+ invokeme(
+ argu,
+ ment);
+ invokeme(
+ argu,
+ ment
+ );
+ invokeme(argu,
+ ment
+ );
+}
+
+STARTTEST
+:set cino=/6
+2kdd]]=][
+ENDTEST
+
+void f()
+{
+ statement;
+ // comment 1
+ // comment 2
+}
+
+STARTTEST
+:set cino=
+2kdd]]/comment 1/+1
+==
+ENDTEST
+
+void f()
+{
+ statement;
+ // comment 1
+ // comment 2
+}
+
+STARTTEST
+:set cino=g0
+2kdd]]=][
+ENDTEST
+
+class CAbc
+{
+ int Test() { return FALSE; }
+
+public: // comment
+ void testfall();
+protected:
+ void testfall();
+};
+
+STARTTEST
+:set cino=(0,gs,hs
+2kdd]]=][
+ENDTEST
+
+class Foo : public Bar
+{
+public:
+virtual void method1(void) = 0;
+virtual void method2(int arg1,
+int arg2,
+int arg3) = 0;
+};
+
+STARTTEST
+:set cino=+20
+2kdd]]=][
+ENDTEST
+
+ void
+foo()
+{
+ if (a)
+ {
+ } else
+ asdf;
+}
+
+STARTTEST
+:set cino=(0,W2s
+2kdd]]=][
+ENDTEST
+
+{
+ averylongfunctionnamelongfunctionnameaverylongfunctionname()->asd(
+ asdasdf,
+ func(asdf,
+ asdfadsf),
+ asdfasdf
+ );
+
+ /* those are ugly, but consequent */
+
+ func()->asd(asdasdf,
+ averylongfunctionname(
+ abc,
+ dec)->averylongfunctionname(
+ asdfadsf,
+ asdfasdf,
+ asdfasdf,
+ ),
+ func(asdfadf,
+ asdfasdf
+ ),
+ asdasdf
+ );
+
+ averylongfunctionnameaverylongfunctionnameavery()->asd(fasdf(
+ abc,
+ dec)->asdfasdfasdf(
+ asdfadsf,
+ asdfasdf,
+ asdfasdf,
+ ),
+ func(asdfadf,
+ asdfasdf),
+ asdasdf
+ );
+}
+
+STARTTEST
+:set cino=M1
+2kdd]]=][
+ENDTEST
+
+int main ()
+{
+ if (cond1 &&
+ cond2
+ )
+ foo;
+}
+
+STARTTEST
+:set cino=(0,ts
+2kdd=][
+ENDTEST
+
+void func(int a
+#if defined(FOO)
+ , int b
+ , int c
+#endif
+ )
+{
+}
+
+STARTTEST
+:set cino=(0
+2kdd=][
+ENDTEST
+
+void
+func(int a
+#if defined(FOO)
+ , int b
+ , int c
+#endif
+ )
+{
+}
+
+STARTTEST
+:set cino&
+2kdd=7][
+ENDTEST
+
+void func(void)
+{
+ if(x==y)
+ if(y==z)
+ foo=1;
+ else { bar=1;
+ baz=2;
+ }
+ printf("Foo!\n");
+}
+
+void func1(void)
+{
+ char* tab[] = {"foo", "bar",
+ "baz", "quux",
+ "this line used", "to be indented incorrectly"};
+ foo();
+}
+
+void func2(void)
+{
+ int tab[] =
+ {1, 2,
+ 3, 4,
+ 5, 6};
+
+ printf("This line used to be indented incorrectly.\n");
+}
+
+int foo[]
+#ifdef BAR
+
+= { 1, 2, 3,
+ 4, 5, 6 }
+
+#endif
+;
+ int baz;
+
+void func3(void)
+{
+ int tab[] = {
+ 1, 2,
+ 3, 4,
+ 5, 6};
+
+printf("Don't you dare indent this line incorrectly!\n");
+}
+
+void
+func4(a, b,
+ c)
+int a;
+int b;
+int c;
+{
+}
+
+void
+func5(
+ int a,
+ int b)
+{
+}
+
+void
+func6(
+ int a)
+{
+}
+
+STARTTEST
+:set cino&
+:set cino+=l1
+2kdd=][
+ENDTEST
+
+void func(void)
+{
+ int tab[] =
+ {
+ 1, 2, 3,
+ 4, 5, 6};
+
+ printf("Indent this line correctly!\n");
+
+ switch (foo)
+ {
+ case bar:
+ printf("bar");
+ break;
+ case baz: {
+ printf("baz");
+ break;
+ }
+ case quux:
+printf("But don't break the indentation of this instruction\n");
+break;
+ }
+}
+
+STARTTEST
+:set cino&
+2kdd=][
+ENDTEST
+
+void func(void)
+{
+ cout << "a"
+ << "b"
+ << ") :"
+ << "c";
+}
+
+STARTTEST
+:set com=s1:/*,m:*,ex:*/
+]]3jofoo();
+ENDTEST
+
+void func(void)
+{
+ /*
+ * This is a comment.
+ */
+}
+
+STARTTEST
+:set cino&
+2kdd=][
+ENDTEST
+
+void func(void)
+{
+ for (int i = 0; i < 10; ++i)
+ if (i & 1) {
+ foo(1);
+ } else
+ foo(0);
+baz();
+}
+
+STARTTEST
+:set cino=k2s,(0
+2kdd3j=][
+ENDTEST
+
+void func(void)
+{
+ if (condition1
+ && condition2)
+ action();
+ function(argument1
+ && argument2);
+
+ if (c1 && (c2 ||
+ c3))
+ foo;
+ if (c1 &&
+ (c2 || c3))
+ {
+ }
+
+ if ( c1
+ && ( c2
+ || c3))
+ foo;
+ func( c1
+ && ( c2
+ || c3))
+ foo;
+}
+
+STARTTEST
+:set cino=k2s,(s
+2kdd3j=][
+ENDTEST
+
+void func(void)
+{
+ if (condition1
+ && condition2)
+ action();
+ function(argument1
+ && argument2);
+
+ if (c1 && (c2 ||
+ c3))
+ foo;
+ if (c1 &&
+ (c2 || c3))
+ {
+ }
+
+ if ( c1
+ && ( c2
+ || c3))
+ foo;
+ func( c1
+ && ( c2
+ || c3))
+ foo;
+}
+
+STARTTEST
+:set cino=k2s,(s,U1
+2kdd3j=][
+ENDTEST
+
+void func(void)
+{
+ if (condition1
+ && condition2)
+ action();
+ function(argument1
+ && argument2);
+
+ if (c1 && (c2 ||
+ c3))
+ foo;
+ if (c1 &&
+ (c2 || c3))
+ {
+ }
+ if (c123456789
+ && (c22345
+ || c3))
+ printf("foo\n");
+
+ c = c1 &&
+ (
+ c2 ||
+ c3
+ ) && c4;
+}
+
+STARTTEST
+:set cino=k2s,(0,W4
+2kdd3j=][
+ENDTEST
+
+void func(void)
+{
+ if (condition1
+ && condition2)
+ action();
+ function(argument1
+ && argument2);
+
+ if (c1 && (c2 ||
+ c3))
+ foo;
+ if (c1 &&
+ (c2 || c3))
+ {
+ }
+ if (c123456789
+ && (c22345
+ || c3))
+ printf("foo\n");
+
+ if ( c1
+ && ( c2
+ || c3))
+ foo;
+
+ a_long_line(
+ argument,
+ argument);
+ a_short_line(argument,
+ argument);
+}
+
+STARTTEST
+:set cino=k2s,u2
+2kdd3j=][
+ENDTEST
+
+void func(void)
+{
+ if (condition1
+ && condition2)
+ action();
+ function(argument1
+ && argument2);
+
+ if (c1 && (c2 ||
+ c3))
+ foo;
+ if (c1 &&
+ (c2 || c3))
+ {
+ }
+ if (c123456789
+ && (c22345
+ || c3))
+ printf("foo\n");
+}
+
+STARTTEST
+:set cino=k2s,(0,w1
+2kdd3j=][
+ENDTEST
+
+void func(void)
+{
+ if (condition1
+ && condition2)
+ action();
+ function(argument1
+ && argument2);
+
+ if (c1 && (c2 ||
+ c3))
+ foo;
+ if (c1 &&
+ (c2 || c3))
+ {
+ }
+ if (c123456789
+ && (c22345
+ || c3))
+ printf("foo\n");
+
+ if ( c1
+ && ( c2
+ || c3))
+ foo;
+ func( c1
+ && ( c2
+ || c3))
+ foo;
+}
+
+STARTTEST
+:set cino=k2,(s
+2kdd3j=][
+ENDTEST
+
+void func(void)
+{
+ if (condition1
+ && condition2)
+ action();
+ function(argument1
+ && argument2);
+
+ if (c1 && (c2 ||
+ c3))
+ foo;
+ if (c1 &&
+ (c2 || c3))
+ {
+ }
+}
+
+STARTTEST
+:set cino=N-s
+/^NAMESPACESTART
+=/^NAMESPACEEND
+ENDTEST
+
+NAMESPACESTART
+/* valid namespaces with normal indent */
+namespace
+{
+ {
+ 111111111111;
+}
+}
+namespace /* test */
+{
+ 11111111111111111;
+}
+namespace // test
+{
+ 111111111111111111;
+}
+namespace
+{
+ 111111111111111111;
+}
+namespace test
+{
+ 111111111111111111;
+}
+namespace{
+ 111111111111111111;
+}
+namespace test{
+ 111111111111111111;
+}
+namespace {
+ 111111111111111111;
+}
+namespace test {
+ 111111111111111111;
+namespace test2 {
+ 22222222222222222;
+}
+}
+
+/* invalid namespaces use block indent */
+namespace test test2 {
+ 111111111111111111111;
+}
+namespace11111111111 {
+ 111111111111;
+}
+namespace() {
+ 1111111111111;
+}
+namespace()
+{
+ 111111111111111111;
+}
+namespace test test2
+{
+ 1111111111111111111;
+}
+namespace111111111
+{
+ 111111111111111111;
+}
+NAMESPACEEND
+
+
+STARTTEST
+:set cino=j1,J1
+/^JSSTART
+=/^JSEND
+ENDTEST
+
+JSSTART
+var bar = {
+foo: {
+that: this,
+some: ok,
+},
+"bar":{
+a : 2,
+b: "123abc",
+x: 4,
+"y": 5
+}
+}
+JSEND
+
+STARTTEST
+:set cino=j1,J1
+/^JSSTART
+=/^JSEND
+ENDTEST
+
+JSSTART
+var foo = [
+1, // indent 8 more
+2,
+3
+]; // indent 8 less
+JSEND
+
+STARTTEST
+:set cino=j1,J1
+/^JSSTART
+=/^JSEND
+ENDTEST
+
+JSSTART
+function bar() {
+var foo = [
+1,
+2,
+3
+]; // indent 16 less
+}
+JSEND
+
+STARTTEST
+:set cino=j1,J1
+/^JSSTART
+=/^JSEND
+ENDTEST
+
+JSSTART
+(function($){
+
+var class_name='myclass';
+
+function private_method() {
+}
+
+var public_method={
+method: function(options,args){
+private_method();
+}
+}
+
+function init(options) {
+
+$(this).data(class_name+'_public',$.extend({},{
+foo: 'bar',
+bar: 2, // indent 8 more
+foobar: [ // indent 8 more
+1, // indent 8 more
+2, // indent 16 more
+3 // indent 16 more
+],
+callback: function(){ // indent 8 more
+return true; // indent 8 more
+} // indent 8 more
+}, options||{}));
+}
+
+$.fn[class_name]=function() {
+
+var _arguments=arguments;
+return this.each(function(){
+
+var options=$(this).data(class_name+'_public');
+if (!options) {
+init.apply(this,_arguments);
+
+} else {
+var method=public_method[_arguments[0]];
+
+if (typeof(method)!='function') {
+console.log(class_name+' has no method "'+_arguments[0]+'"');
+return false;
+}
+_arguments[0]=options;
+method.apply(this,_arguments);
+}
+});
+}
+
+})(jQuery);
+JSEND
+
+STARTTEST
+:set cino=j1,J1
+/^JSSTART
+=/^JSEND
+ENDTEST
+
+JSSTART
+function init(options) {
+$(this).data(class_name+'_public',$.extend({},{
+foo: 'bar',
+bar: 2,
+foobar: [
+1, // indent 8 more
+2, // indent 8 more
+3 // indent 8 more
+],
+callback: function(){
+return true;
+}
+}, options||{}));
+}
+JSEND
+
+STARTTEST
+:set cino=j1,J1
+/^JSSTART
+=/^JSEND
+ENDTEST
+
+JSSTART
+(function($){
+function init(options) {
+$(this).data(class_name+'_public',$.extend({},{
+foo: 'bar',
+bar: 2, // indent 8 more
+foobar: [ // indent 8 more
+1, // indent 8 more
+2, // indent 16 more
+3 // indent 16 more
+],
+callback: function(){ // indent 8 more
+return true; // indent 8 more
+} // indent 8 more
+}, options||{}));
+}
+})(jQuery);
+JSEND
+
+STARTTEST
+:g/^STARTTEST/.,/^ENDTEST/d
+:1;/start of AUTO/,$wq! test.out
+ENDTEST
diff --git a/src/testdir/test3.ok b/src/testdir/test3.ok
new file mode 100644
index 0000000000..d73a5e1230
--- /dev/null
+++ b/src/testdir/test3.ok
@@ -0,0 +1,1820 @@
+/* start of AUTO matically checked vim: set ts=4 : */
+{
+ if (test)
+ cmd1;
+ cmd2;
+}
+
+{
+ if (test)
+ cmd1;
+ else
+ cmd2;
+}
+
+{
+ if (test)
+ {
+ cmd1;
+ cmd2;
+ }
+}
+
+{
+ if (test)
+ {
+ cmd1;
+ else
+ }
+}
+
+{
+ while (this)
+ if (test)
+ cmd1;
+ cmd2;
+}
+
+{
+ while (this)
+ if (test)
+ cmd1;
+ else
+ cmd2;
+}
+
+{
+ if (test)
+ {
+ cmd;
+ }
+
+ if (test)
+ cmd;
+}
+
+{
+ if (test) {
+ cmd;
+ }
+
+ if (test) cmd;
+}
+
+{
+ cmd1;
+ for (blah)
+ while (this)
+ if (test)
+ cmd2;
+ cmd3;
+}
+
+{
+ cmd1;
+ for (blah)
+ while (this)
+ if (test)
+ cmd2;
+ cmd3;
+
+ if (test)
+ {
+ cmd1;
+ cmd2;
+ cmd3;
+ }
+}
+
+
+/* Test for 'cindent' do/while mixed with if/else: */
+
+{
+ do
+ if (asdf)
+ asdfasd;
+ while (cond);
+
+ do
+ if (asdf)
+ while (asdf)
+ asdf;
+ while (asdf);
+}
+
+/* Test for 'cindent' with two ) on a continuation line */
+{
+ if (asdfasdf;asldkfj asdlkfj as;ldkfj sal;d
+ aal;sdkjf ( ;asldfkja;sldfk
+ al;sdjfka ;slkdf ) sa;ldkjfsa dlk;)
+ line up here;
+}
+
+
+/* C++ tests: */
+
+// foo() these three lines should remain in column 0
+// {
+// }
+
+/* Test for continuation and unterminated lines: */
+{
+ i = 99 + 14325 +
+ 21345 +
+ 21345 +
+ 21345 + ( 21345 +
+ 21345) +
+ 2345 +
+ 1234;
+ c = 1;
+}
+
+/*
+ testje for indent with empty line
+
+ here */
+
+{
+ if (testing &&
+ not a joke ||
+ line up here)
+ hay;
+ if (testing &&
+ (not a joke || testing
+ )line up here)
+ hay;
+ if (testing &&
+ (not a joke || testing
+ line up here))
+ hay;
+}
+
+
+{
+ switch (c)
+ {
+ case xx:
+ do
+ if (asdf)
+ do
+ asdfasdf;
+ while (asdf);
+ else
+ asdfasdf;
+ while (cond);
+ case yy:
+ case xx:
+ case zz:
+ testing;
+ }
+}
+
+{
+ if (cond) {
+ foo;
+ }
+ else
+ {
+ bar;
+ }
+}
+
+{
+ if (alskdfj ;alsdkfjal;skdjf (;sadlkfsa ;dlkf j;alksdfj ;alskdjf
+ alsdkfj (asldk;fj
+ awith cino=(0 ;lf this one goes to below the paren with ==
+ ;laksjfd ;lsakdjf ;alskdf asd)
+ asdfasdf;)))
+ asdfasdf;
+}
+
+ int
+func(a, b)
+ int a;
+ int c;
+{
+ if (c1 && (c2 ||
+ c3))
+ foo;
+ if (c1 &&
+ (c2 || c3)
+ )
+}
+
+{
+ while (asd)
+ {
+ if (asdf)
+ if (test)
+ if (that)
+ {
+ if (asdf)
+ do
+ cdasd;
+ while (as
+ df);
+ }
+ else
+ if (asdf)
+ asdf;
+ else
+ asdf;
+ asdf;
+ }
+}
+
+{
+ s = "/*"; b = ';'
+ s = "/*"; b = ';';
+ a = b;
+}
+
+{
+ switch (a)
+ {
+ case a:
+ switch (t)
+ {
+ case 1:
+ cmd;
+ break;
+ case 2:
+ cmd;
+ break;
+ }
+ cmd;
+ break;
+ case b:
+ {
+ int i;
+ cmd;
+ }
+ break;
+ case c: {
+ int i;
+ cmd;
+ }
+ case d: if (cond &&
+ test) { /* this line doesn't work right */
+ int i;
+ cmd;
+ }
+ break;
+ }
+}
+
+{
+ if (!(vim_strchr(p_cpo, CPO_BUFOPTGLOB) != NULL && entering) &&
+ (bp_to->b_p_initialized ||
+ (!entering && vim_strchr(p_cpo, CPO_BUFOPT) != NULL)))
+ return;
+label :
+ asdf = asdf ?
+ asdf : asdf;
+ asdf = asdf ?
+ asdf: asdf;
+}
+
+/* Special Comments : This function has the added complexity (compared */
+/* : to addtolist) of having to check for a detail */
+/* : texture and add that to the list first. */
+
+char *(array[100]) = {
+ "testje",
+ "foo",
+ "bar",
+}
+
+enum soppie
+{
+ yes = 0,
+ no,
+ maybe
+};
+
+typedef enum soppie
+{
+ yes = 0,
+ no,
+ maybe
+};
+
+static enum
+{
+ yes = 0,
+ no,
+ maybe
+} soppie;
+
+public static enum
+{
+ yes = 0,
+ no,
+ maybe
+} soppie;
+
+static private enum
+{
+ yes = 0,
+ no,
+ maybe
+} soppie;
+
+{
+ int a,
+ b;
+}
+
+{
+ struct Type
+ {
+ int i;
+ char *str;
+ } var[] =
+ {
+ 0, "zero",
+ 1, "one",
+ 2, "two",
+ 3, "three"
+ };
+
+ float matrix[3][3] =
+ {
+ {
+ 0,
+ 1,
+ 2
+ },
+ {
+ 3,
+ 4,
+ 5
+ },
+ {
+ 6,
+ 7,
+ 8
+ }
+ };
+}
+
+{
+ /* blah ( blah */
+ /* where does this go? */
+
+ /* blah ( blah */
+ cmd;
+
+ func(arg1,
+ /* comment */
+ arg2);
+ a;
+ {
+ b;
+ {
+ c; /* Hey, NOW it indents?! */
+ }
+ }
+
+ {
+ func(arg1,
+ arg2,
+ arg3);
+ /* Hey, what am I doing here? Is this coz of the ","? */
+ }
+}
+
+main ()
+{
+ if (cond)
+ {
+ a = b;
+ }
+ if (cond) {
+ a = c;
+ }
+ if (cond)
+ a = d;
+ return;
+}
+
+{
+ case 2: if (asdf &&
+ asdfasdf)
+ aasdf;
+ a = 9;
+ case 3: if (asdf)
+ aasdf;
+ a = 9;
+ case 4: x = 1;
+ y = 2;
+
+label: if (asdf)
+ here;
+
+label: if (asdf &&
+ asdfasdf)
+ {
+ }
+
+label: if (asdf &&
+ asdfasdf) {
+ there;
+ }
+
+label: if (asdf &&
+ asdfasdf)
+ there;
+}
+
+{
+ /*
+ hello with ":set comments= cino=c5"
+ */
+
+ /*
+ hello with ":set comments= cino="
+ */
+}
+
+
+{
+ if (a < b) {
+ a = a + 1;
+ } else
+ a = a + 2;
+
+ if (a)
+ do {
+ testing;
+ } while (asdfasdf);
+ a = b + 1;
+ asdfasdf
+}
+
+class bob
+{
+ int foo() {return 1;}
+ int bar;
+}
+
+main()
+{
+ while(1)
+ if (foo)
+ {
+ bar;
+ }
+ else {
+ asdf;
+ }
+ misplacedline;
+}
+
+{
+ if (clipboard.state == SELECT_DONE
+ && ((row == clipboard.start.lnum
+ && col >= clipboard.start.col)
+ || row > clipboard.start.lnum))
+}
+
+{
+ if (1) {i += 4;}
+ where_am_i;
+ return 0;
+}
+
+{
+ {
+ } // sdf(asdf
+ if (asdf)
+ asd;
+}
+
+{
+label1:
+label2:
+}
+
+{
+ int fooRet = foo(pBar1, false /*fKB*/,
+ true /*fPTB*/, 3 /*nT*/, false /*fDF*/);
+ f() {
+ for ( i = 0;
+ i < m;
+ /* c */ i++ ) {
+ a = b;
+ }
+ }
+}
+
+{
+ f1(/*comment*/);
+ f2();
+}
+
+{
+ do {
+ if (foo) {
+ } else
+ ;
+ } while (foo);
+ foo(); // was wrong
+}
+
+int x; // no extra indent because of the ;
+void func()
+{
+}
+
+char *tab[] = {"aaa",
+ "};", /* }; */ NULL}
+ int indented;
+{}
+
+char *a[] = {"aaa", "bbb",
+ "ccc", NULL};
+// here
+
+char *tab[] = {"aaa",
+ "xx", /* xx */}; /* asdf */
+int not_indented;
+
+{
+ do {
+ switch (bla)
+ {
+ case 1: if (foo)
+ bar;
+ }
+ } while (boo);
+ wrong;
+}
+
+int foo,
+ bar;
+int foo;
+
+#if defined(foo) \
+ && defined(bar)
+char * xx = "asdf\
+ foo\
+ bor";
+int x;
+
+char *foo = "asdf\
+ asdf\
+ asdf",
+ *bar;
+
+void f()
+{
+#if defined(foo) \
+ && defined(bar)
+ char *foo = "asdf\
+ asdf\
+ asdf",
+ *bar;
+ {
+ int i;
+ char *foo = "asdf\
+ asdf\
+ asdf",
+ *bar;
+ }
+#endif
+}
+#endif
+
+int y; // comment
+// comment
+
+// comment
+
+{
+ Constructor(int a,
+ int b ) : BaseClass(a)
+ {
+ }
+}
+
+void foo()
+{
+ char one,
+ two;
+ struct bla piet,
+ jan;
+ enum foo kees,
+ jannie;
+ static unsigned sdf,
+ krap;
+ unsigned int piet,
+ jan;
+ int
+ kees,
+ jan;
+}
+
+{
+ t(int f,
+ int d); // )
+ d();
+}
+
+Constructor::Constructor(int a,
+ int b
+ ) :
+ BaseClass(a,
+ b,
+ c),
+ mMember(b),
+{
+}
+
+Constructor::Constructor(int a,
+ int b ) :
+ BaseClass(a)
+{
+}
+
+Constructor::Constructor(int a,
+ int b ) /*x*/ : /*x*/ BaseClass(a),
+ member(b)
+{
+}
+
+class CAbc :
+ public BaseClass1,
+ protected BaseClass2
+{
+ int Test() { return FALSE; }
+ int Test1() { return TRUE; }
+
+ CAbc(int a, int b ) :
+ BaseClass(a)
+ {
+ switch(xxx)
+ {
+ case abc:
+ asdf();
+ break;
+
+ case 999:
+ baer();
+ break;
+ }
+ }
+
+ public: // <-- this was incoreectly indented before!!
+ void testfall();
+ protected:
+ void testfall();
+};
+
+class CAbc : public BaseClass1,
+ protected BaseClass2
+{
+};
+
+static struct
+{
+ int a;
+ int b;
+} variable[COUNT] =
+{
+ {
+ 123,
+ 456
+ },
+ {
+ 123,
+ 456
+ }
+};
+
+static struct
+{
+ int a;
+ int b;
+} variable[COUNT] =
+{
+ { 123, 456 },
+ { 123, 456 }
+};
+
+void asdf() /* ind_maxparen may cause trouble here */
+{
+ if ((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)) break;
+}
+
+foo()
+{
+ a = cond ? foo() : asdf
+ + asdf;
+
+ a = cond ?
+ foo() : asdf
+ + asdf;
+}
+
+int main(void)
+{
+ if (a)
+ if (b)
+ 2;
+ else 3;
+ next_line_of_code();
+}
+
+barry()
+{
+ Foo::Foo (int one,
+ int two)
+ : something(4)
+ {}
+}
+
+barry()
+{
+ Foo::Foo (int one, int two)
+ : something(4)
+ {}
+}
+
+Constructor::Constructor(int a,
+ int b
+ ) :
+ BaseClass(a,
+ b,
+ c),
+ mMember(b)
+{
+}
+int main ()
+{
+ if (lala)
+ do
+ ++(*lolo);
+ while (lili
+ && lele);
+ lulu;
+}
+
+int main ()
+{
+ switch (c)
+ {
+ case 'c': if (cond)
+ {
+ }
+ }
+}
+
+main()
+{
+ (void) MyFancyFuasdfadsfnction(
+ argument);
+}
+
+main()
+{
+ char foo[] = "/*";
+ /* as
+ df */
+ hello
+}
+
+/* valid namespaces with normal indent */
+namespace
+{
+ {
+ 111111111111;
+ }
+}
+namespace /* test */
+{
+ 11111111111111111;
+}
+namespace // test
+{
+ 111111111111111111;
+}
+namespace
+{
+ 111111111111111111;
+}
+namespace test
+{
+ 111111111111111111;
+}
+namespace{
+ 111111111111111111;
+}
+namespace test{
+ 111111111111111111;
+}
+namespace {
+ 111111111111111111;
+}
+namespace test {
+ 111111111111111111;
+ namespace test2 {
+ 22222222222222222;
+ }
+}
+
+/* invalid namespaces use block indent */
+namespace test test2 {
+ 111111111111111111111;
+}
+namespace11111111111 {
+ 111111111111;
+}
+namespace() {
+ 1111111111111;
+}
+namespace()
+{
+ 111111111111111111;
+}
+namespace test test2
+{
+ 1111111111111111111;
+}
+namespace111111111
+{
+ 111111111111111111;
+}
+
+/* end of AUTO */
+
+
+{
+
+/* this is
+ * a real serious
+ * about life, the
+ * universe, and the
+ * rest important big
+ * comment
+ */
+ /* insert " about life, the universe, and the rest" after "serious" */
+}
+
+
+{
+ /*
+ * Testing for comments, without 'cin' set
+ */
+about life
+
+/*
+* what happens here?
+*/
+there
+
+ /*
+ the end of the comment, try inserting a line below */
+line
+
+ /* how about
+hello
+ this one */
+}
+
+
+{
+ var = this + that + vec[0] * vec[0]
+ + vec[1] * vec[1]
+ + vec2[2] * vec[2];
+}
+
+
+{
+ asdf asdflkajds f;
+ if (tes & ting) {
+ asdf asdf asdf ;
+ asdfa sdf asdf;
+ }
+ testing1;
+ if (tes & ting)
+ {
+ asdf asdf asdf ;
+ asdfa sdf asdf;
+ }
+ testing2;
+}
+
+
+main ( int first_par, /*
+ * Comment for
+ * first par
+ */
+ int second_par /*
+ * Comment for
+ * second par
+ */
+ )
+{
+ func( first_par, /*
+ * Comment for
+ * first par
+ */
+ second_par /*
+ * Comment for
+ * second par
+ */
+ );
+
+}
+
+
+main(void)
+{
+ /* Make sure that cino=X0s is not parsed like cino=Xs. */
+ if (cond)
+ foo();
+ else
+ {
+ bar();
+ }
+}
+
+
+{
+ do
+ {
+ if ()
+ {
+ if ()
+ asdf;
+ else
+ asdf;
+ }
+ } while ();
+ cmd; /* this should go under the } */
+}
+
+
+void f()
+{
+ if ( k() ) {
+ l();
+
+ } else { /* Start (two words) end */
+ m();
+ }
+
+ n();
+}
+
+
+void f()
+ {
+ if ( k() )
+ {
+ l();
+ } else { /* Start (two words) end */
+ m();
+ }
+ n(); /* should be under the if () */
+}
+
+
+void bar(void)
+ {
+ static array[2][2] =
+ {
+ { 1, 2 },
+ { 3, 4 },
+ }
+
+ while (a)
+ {
+ foo(&a);
+ }
+
+ {
+ int a;
+ {
+ a = a + 1;
+ }
+ }
+ b = a;
+ }
+
+void func(void)
+ {
+ a = 1;
+ {
+ b = 2;
+ }
+ c = 3;
+ d = 4;
+ }
+/* foo */
+
+
+a()
+{
+ do {
+ a = a +
+ a;
+ } while ( a ); /* add text under this line */
+ here
+ if ( a )
+ a;
+}
+
+
+a()
+{
+label1:
+ /* hmm */
+ // comment
+label2: b();
+label3 /* post */:
+/* pre */ label4:
+ f(/*com*/);
+ if (/*com*/)
+ cmd();
+}
+
+
+/*
+ * A simple comment
+ */
+
+/*
+** A different comment
+*/
+
+
+void f()
+{
+
+ /*********
+ A comment.
+ *********/
+}
+
+
+void f()
+{
+
+ /*********
+ A comment.
+ *********/
+}
+
+
+void f()
+{
+ c = c1 &&
+ (
+ c2 ||
+ c3
+ ) && c4;
+}
+
+
+void f()
+{
+ c = c1 &&
+ (
+ c2 ||
+ c3
+ ) && c4;
+}
+
+
+void f()
+{
+ c = c1 &&
+ (
+ c2 ||
+ c3
+ ) && c4;
+}
+
+
+void f()
+{
+ if ( c1
+ && ( c2
+ || c3))
+ foo;
+}
+
+
+void f()
+{
+ if ( c1
+ && ( c2
+ || c3))
+ foo;
+}
+
+
+void f()
+{
+ c = c1 && (
+ c2 ||
+ c3
+ ) && c4;
+ if (
+ c1 && c2
+ )
+ foo;
+}
+
+
+void f()
+{
+ c = c1 && (
+ c2 ||
+ c3
+ ) && c4;
+ if (
+ c1 && c2
+ )
+ foo;
+}
+
+
+void f()
+{
+ switch (x)
+ {
+ case 1:
+ a = b;
+ break;
+ default:
+ a = 0;
+ break;
+ }
+}
+
+
+void f()
+{
+ invokeme(
+ argu,
+ ment);
+ invokeme(
+ argu,
+ ment
+ );
+ invokeme(argu,
+ ment
+ );
+}
+
+
+void f()
+{
+ statement;
+ // comment 1
+ // comment 2
+}
+
+
+void f()
+{
+ statement;
+ // comment 1
+ // comment 2
+}
+
+
+class CAbc
+{
+ int Test() { return FALSE; }
+
+public: // comment
+ void testfall();
+protected:
+ void testfall();
+};
+
+
+class Foo : public Bar
+{
+ public:
+ virtual void method1(void) = 0;
+ virtual void method2(int arg1,
+ int arg2,
+ int arg3) = 0;
+};
+
+
+ void
+foo()
+{
+ if (a)
+ {
+ } else
+ asdf;
+}
+
+
+{
+ averylongfunctionnamelongfunctionnameaverylongfunctionname()->asd(
+ asdasdf,
+ func(asdf,
+ asdfadsf),
+ asdfasdf
+ );
+
+ /* those are ugly, but consequent */
+
+ func()->asd(asdasdf,
+ averylongfunctionname(
+ abc,
+ dec)->averylongfunctionname(
+ asdfadsf,
+ asdfasdf,
+ asdfasdf,
+ ),
+ func(asdfadf,
+ asdfasdf
+ ),
+ asdasdf
+ );
+
+ averylongfunctionnameaverylongfunctionnameavery()->asd(fasdf(
+ abc,
+ dec)->asdfasdfasdf(
+ asdfadsf,
+ asdfasdf,
+ asdfasdf,
+ ),
+ func(asdfadf,
+ asdfasdf),
+ asdasdf
+ );
+}
+
+
+int main ()
+{
+ if (cond1 &&
+ cond2
+ )
+ foo;
+}
+
+
+void func(int a
+#if defined(FOO)
+ , int b
+ , int c
+#endif
+ )
+{
+}
+
+
+ void
+func(int a
+#if defined(FOO)
+ , int b
+ , int c
+#endif
+ )
+{
+}
+
+
+void func(void)
+{
+ if(x==y)
+ if(y==z)
+ foo=1;
+ else { bar=1;
+ baz=2;
+ }
+ printf("Foo!\n");
+}
+
+void func1(void)
+{
+ char* tab[] = {"foo", "bar",
+ "baz", "quux",
+ "this line used", "to be indented incorrectly"};
+ foo();
+}
+
+void func2(void)
+{
+ int tab[] =
+ {1, 2,
+ 3, 4,
+ 5, 6};
+
+ printf("This line used to be indented incorrectly.\n");
+}
+
+int foo[]
+#ifdef BAR
+
+= { 1, 2, 3,
+ 4, 5, 6 }
+
+#endif
+ ;
+int baz;
+
+void func3(void)
+{
+ int tab[] = {
+ 1, 2,
+ 3, 4,
+ 5, 6};
+
+ printf("Don't you dare indent this line incorrectly!\n");
+}
+
+ void
+func4(a, b,
+ c)
+ int a;
+ int b;
+ int c;
+{
+}
+
+ void
+func5(
+ int a,
+ int b)
+{
+}
+
+ void
+func6(
+ int a)
+{
+}
+
+
+void func(void)
+{
+ int tab[] =
+ {
+ 1, 2, 3,
+ 4, 5, 6};
+
+ printf("Indent this line correctly!\n");
+
+ switch (foo)
+ {
+ case bar:
+ printf("bar");
+ break;
+ case baz: {
+ printf("baz");
+ break;
+ }
+ case quux:
+ printf("But don't break the indentation of this instruction\n");
+ break;
+ }
+}
+
+
+void func(void)
+{
+ cout << "a"
+ << "b"
+ << ") :"
+ << "c";
+}
+
+
+void func(void)
+{
+ /*
+ * This is a comment.
+ */
+ foo();
+}
+
+
+void func(void)
+{
+ for (int i = 0; i < 10; ++i)
+ if (i & 1) {
+ foo(1);
+ } else
+ foo(0);
+ baz();
+}
+
+
+void func(void)
+{
+ if (condition1
+ && condition2)
+ action();
+ function(argument1
+ && argument2);
+
+ if (c1 && (c2 ||
+ c3))
+ foo;
+ if (c1 &&
+ (c2 || c3))
+ {
+ }
+
+ if ( c1
+ && ( c2
+ || c3))
+ foo;
+ func( c1
+ && ( c2
+ || c3))
+ foo;
+}
+
+
+void func(void)
+{
+ if (condition1
+ && condition2)
+ action();
+ function(argument1
+ && argument2);
+
+ if (c1 && (c2 ||
+ c3))
+ foo;
+ if (c1 &&
+ (c2 || c3))
+ {
+ }
+
+ if ( c1
+ && ( c2
+ || c3))
+ foo;
+ func( c1
+ && ( c2
+ || c3))
+ foo;
+}
+
+
+void func(void)
+{
+ if (condition1
+ && condition2)
+ action();
+ function(argument1
+ && argument2);
+
+ if (c1 && (c2 ||
+ c3))
+ foo;
+ if (c1 &&
+ (c2 || c3))
+ {
+ }
+ if (c123456789
+ && (c22345
+ || c3))
+ printf("foo\n");
+
+ c = c1 &&
+ (
+ c2 ||
+ c3
+ ) && c4;
+}
+
+
+void func(void)
+{
+ if (condition1
+ && condition2)
+ action();
+ function(argument1
+ && argument2);
+
+ if (c1 && (c2 ||
+ c3))
+ foo;
+ if (c1 &&
+ (c2 || c3))
+ {
+ }
+ if (c123456789
+ && (c22345
+ || c3))
+ printf("foo\n");
+
+ if ( c1
+ && ( c2
+ || c3))
+ foo;
+
+ a_long_line(
+ argument,
+ argument);
+ a_short_line(argument,
+ argument);
+}
+
+
+void func(void)
+{
+ if (condition1
+ && condition2)
+ action();
+ function(argument1
+ && argument2);
+
+ if (c1 && (c2 ||
+ c3))
+ foo;
+ if (c1 &&
+ (c2 || c3))
+ {
+ }
+ if (c123456789
+ && (c22345
+ || c3))
+ printf("foo\n");
+}
+
+
+void func(void)
+{
+ if (condition1
+ && condition2)
+ action();
+ function(argument1
+ && argument2);
+
+ if (c1 && (c2 ||
+ c3))
+ foo;
+ if (c1 &&
+ (c2 || c3))
+ {
+ }
+ if (c123456789
+ && (c22345
+ || c3))
+ printf("foo\n");
+
+ if ( c1
+ && ( c2
+ || c3))
+ foo;
+ func( c1
+ && ( c2
+ || c3))
+ foo;
+}
+
+
+void func(void)
+{
+ if (condition1
+ && condition2)
+ action();
+ function(argument1
+ && argument2);
+
+ if (c1 && (c2 ||
+ c3))
+ foo;
+ if (c1 &&
+ (c2 || c3))
+ {
+ }
+}
+
+
+NAMESPACESTART
+/* valid namespaces with normal indent */
+namespace
+{
+{
+ 111111111111;
+}
+}
+namespace /* test */
+{
+11111111111111111;
+}
+namespace // test
+{
+111111111111111111;
+}
+namespace
+{
+111111111111111111;
+}
+namespace test
+{
+111111111111111111;
+}
+namespace{
+111111111111111111;
+}
+namespace test{
+111111111111111111;
+}
+namespace {
+111111111111111111;
+}
+namespace test {
+111111111111111111;
+namespace test2 {
+22222222222222222;
+}
+}
+
+/* invalid namespaces use block indent */
+namespace test test2 {
+ 111111111111111111111;
+}
+namespace11111111111 {
+ 111111111111;
+}
+namespace() {
+ 1111111111111;
+}
+namespace()
+{
+ 111111111111111111;
+}
+namespace test test2
+{
+ 1111111111111111111;
+}
+namespace111111111
+{
+ 111111111111111111;
+}
+NAMESPACEEND
+
+
+
+JSSTART
+var bar = {
+ foo: {
+ that: this,
+ some: ok,
+ },
+ "bar":{
+ a : 2,
+ b: "123abc",
+ x: 4,
+ "y": 5
+ }
+}
+JSEND
+
+
+JSSTART
+var foo = [
+1, // indent 8 more
+ 2,
+ 3
+ ]; // indent 8 less
+JSEND
+
+
+JSSTART
+function bar() {
+ var foo = [
+ 1,
+ 2,
+ 3
+ ]; // indent 16 less
+}
+JSEND
+
+
+JSSTART
+(function($){
+
+ var class_name='myclass';
+
+ function private_method() {
+ }
+
+ var public_method={
+ method: function(options,args){
+ private_method();
+ }
+ }
+
+ function init(options) {
+
+ $(this).data(class_name+'_public',$.extend({},{
+ foo: 'bar',
+ bar: 2, // indent 8 more
+ foobar: [ // indent 8 more
+ 1, // indent 8 more
+ 2, // indent 16 more
+ 3 // indent 16 more
+ ],
+ callback: function(){ // indent 8 more
+ return true; // indent 8 more
+ } // indent 8 more
+ }, options||{}));
+ }
+
+ $.fn[class_name]=function() {
+
+ var _arguments=arguments;
+ return this.each(function(){
+
+ var options=$(this).data(class_name+'_public');
+ if (!options) {
+ init.apply(this,_arguments);
+
+ } else {
+ var method=public_method[_arguments[0]];
+
+ if (typeof(method)!='function') {
+ console.log(class_name+' has no method "'+_arguments[0]+'"');
+ return false;
+ }
+ _arguments[0]=options;
+ method.apply(this,_arguments);
+ }
+ });
+ }
+
+})(jQuery);
+JSEND
+
+
+JSSTART
+function init(options) {
+ $(this).data(class_name+'_public',$.extend({},{
+ foo: 'bar',
+ bar: 2,
+ foobar: [
+ 1, // indent 8 more
+ 2, // indent 8 more
+ 3 // indent 8 more
+ ],
+ callback: function(){
+ return true;
+ }
+ }, options||{}));
+}
+JSEND
+
+
+JSSTART
+(function($){
+ function init(options) {
+ $(this).data(class_name+'_public',$.extend({},{
+ foo: 'bar',
+ bar: 2, // indent 8 more
+ foobar: [ // indent 8 more
+ 1, // indent 8 more
+ 2, // indent 16 more
+ 3 // indent 16 more
+ ],
+ callback: function(){ // indent 8 more
+ return true; // indent 8 more
+ } // indent 8 more
+ }, options||{}));
+ }
+})(jQuery);
+JSEND
+
diff --git a/src/testdir/test30.in b/src/testdir/test30.in
new file mode 100644
index 0000000000..4a8778d2de
--- /dev/null
+++ b/src/testdir/test30.in
@@ -0,0 +1,222 @@
+Test for a lot of variations of the 'fileformats' option
+
+Note: This test will fail if "cat" is not available.
+
+STARTTEST
+:so small.vim
+:" first write three test files, one in each format
+:set fileformat=unix
+:set fileformats=
+:/^1/w! XX1
+:/^2/w! XX2
+:/^3/w! XX3
+:/^4/w! XX4
+:/^5/w! XX5
+:/^6/w! XX6
+:/^7/w! XX7
+:/^8/w! XX8
+:/^9/w! XX9
+:/^10/w! XX10
+:/^unix/;/eof/-1w! XXUnix
+:/^dos/;/eof/-1w! XXDos
+:set bin noeol
+:$w! XXMac
+:set nobin eol
+:bwipe XXUnix XXDos XXMac
+:" create mixed format files
+:if has("vms")
+: !copy XXUnix,XXDos XXUxDs.
+: !copy XXUnix,XXMac XXUxMac.
+: !copy XXDos,XXMac XXDosMac.
+: !copy XXUnix,XXDos,XXMac XXUxDsMc.
+:elseif has("win32")
+: !copy /b XXUnix+XXDos XXUxDs
+: !copy /b XXUnix+XXMac XXUxMac
+: !copy /b XXDos+XXMac XXDosMac
+: !copy /b XXUnix+XXDos+XXMac XXUxDsMc
+:else
+: !cat XXUnix XXDos >XXUxDs
+: !cat XXUnix XXMac >XXUxMac
+: !cat XXDos XXMac >XXDosMac
+: !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
+:set fileformats=dos,mac
+:e! XXUxDs
+:w! XXtt61
+:bwipe XXUxDs
+:e! XXUxMac
+:w! XXtt62
+:bwipe XXUxMac
+:e! XXUxDsMc
+:w! XXtt63
+:bwipe XXUxDsMc
+:"
+:" try reading and writing with 'fileformats' set to three formats
+:set fileformats=unix,dos,mac
+:e! XXUxDsMc
+:w! XXtt71
+:bwipe XXUxDsMc
+:set fileformats=mac,dos,unix
+:e! XXUxDsMc
+:w! XXtt81
+:bwipe XXUxDsMc
+:" 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 >>XXtt61
+:w >>XXtt62
+:w >>XXtt63
+:w >>XXtt71
+:w >>XXtt81
+: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
+Go6:$r XXtt61
+:$r XXtt62
+:$r XXtt63
+Go7:$r XXtt71
+Go8:$r XXtt81
+Go9:$r XXtt91
+:$r XXtt92
+:$r XXtt93
+Go10:$r XXUnix
+:set nobinary ff&
+:w
+:qa!
+ENDTEST
+
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+
+unix
+unix
+eof
+
+dos
+dos
+eof
+
+mac mac
diff --git a/src/testdir/test30.ok b/src/testdir/test30.ok
new file mode 100644
index 0000000000..380ce67061
--- /dev/null
+++ b/src/testdir/test30.ok
@@ -0,0 +1,121 @@
+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
+6
+unix
+unix
+dos
+dos
+END
+unix
+unix
+mac mac
+END
+unix
+unix
+dos
+dos
+mac mac
+END
+7
+unix
+unix
+dos
+dos
+mac mac
+END
+8
+unix
+unix
+dos
+dos
+mac mac
+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/testdir/test31.in b/src/testdir/test31.in
new file mode 100644
index 0000000000..7dc2334781
--- /dev/null
+++ b/src/testdir/test31.in
@@ -0,0 +1,75 @@
+Test for commands that close windows and/or buffers:
+:quit
+:close
+:hide
+:only
+:sall
+:all
+:ball
+:buf
+:edit
+
+STARTTEST
+:so tiny.vim
+GA 1:$w! Xtest1
+$r2:$w! Xtest2
+$r3:$w! Xtest3
+:n! Xtest1 Xtest2
+A 1:set hidden
+:" test for working :n when hidden set; write "testtext 2"
+:n
+:w! test.out
+:" test for failing :rew when hidden not set; write "testtext 2 2"
+:set nohidden
+A 2:rew
+:w >>test.out
+:" test for working :rew when hidden set; write "testtext 1 1"
+:set hidden
+:rew
+:w >>test.out
+:" test for :all keeping a buffer when it's modified; write "testtext 1 1 1"
+:set nohidden
+A 1:sp
+:n Xtest2 Xtest3
+:all
+:1wincmd w
+:w >>test.out
+:" test abandoning changed buffer, should be unloaded even when 'hidden' set
+:" write "testtext 2 2" twice
+:set hidden
+A 1:q!
+:w >>test.out
+:unhide
+:w >>test.out
+:" test ":hide" hides anyway when 'hidden' not set; write "testtext 3"
+:set nohidden
+A 2:hide
+:w >>test.out
+:" test ":edit" failing in modified buffer when 'hidden' not set
+:" write "testtext 3 3"
+A 3:e Xtest1
+:w >>test.out
+:" test ":edit" working in modified buffer when 'hidden' set; write "testtext 1"
+:set hidden
+:e Xtest1
+:w >>test.out
+:" test ":close" not hiding when 'hidden' not set in modified buffer;
+:" write "testtext 3 3 3"
+:sp Xtest3
+:set nohidden
+A 3:close
+:w >>test.out
+:" test ":close!" does hide when 'hidden' not set in modified buffer;
+:" write "testtext 1"
+A 3:close!
+:w >>test.out
+:set nohidden
+:" test ":all!" hides changed buffer; write "testtext 2 2 2"
+:sp Xtest4
+GA 4:all!
+:1wincmd w
+:w >>test.out
+:qa!
+ENDTEST
+
+testtext
diff --git a/src/testdir/test31.ok b/src/testdir/test31.ok
new file mode 100644
index 0000000000..185bdc768e
--- /dev/null
+++ b/src/testdir/test31.ok
@@ -0,0 +1,12 @@
+testtext 2
+testtext 2 2
+testtext 1 1
+testtext 1 1 1
+testtext 2 2
+testtext 2 2
+testtext 3
+testtext 3 3
+testtext 1
+testtext 3 3 3
+testtext 1
+testtext 2 2 2
diff --git a/src/testdir/test32.in b/src/testdir/test32.in
new file mode 100644
index 0000000000..6b399fa6c6
--- /dev/null
+++ b/src/testdir/test32.in
@@ -0,0 +1,60 @@
+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
+:so small.vim
+:se nocp viminfo+=nviminfo 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/testdir/test32.ok b/src/testdir/test32.ok
new file mode 100644
index 0000000000..afc4463fac
--- /dev/null
+++ b/src/testdir/test32.ok
@@ -0,0 +1,15 @@
+#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/testdir/test33.in b/src/testdir/test33.in
new file mode 100644
index 0000000000..5644760402
--- /dev/null
+++ b/src/testdir/test33.in
@@ -0,0 +1,34 @@
+Test for 'lisp'
+If the lisp feature is not enabled, this will fail!
+
+STARTTEST
+:so small.vim
+:set lisp
+/^(defun
+=G:/^(defun/,$w! test.out
+:q!
+ENDTEST
+
+(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>")))
diff --git a/src/testdir/test33.ok b/src/testdir/test33.ok
new file mode 100644
index 0000000000..cd1d87a14b
--- /dev/null
+++ b/src/testdir/test33.ok
@@ -0,0 +1,23 @@
+(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>")))
diff --git a/src/testdir/test34.in b/src/testdir/test34.in
new file mode 100644
index 0000000000..71ee5f63b2
--- /dev/null
+++ b/src/testdir/test34.in
@@ -0,0 +1,87 @@
+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.
+
+STARTTEST
+:so small.vim
+:function 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
+:endfunction
+:function Compute(n1, n2, divname)
+: if a:n2 == 0
+: return "fail"
+: endif
+: exe "let g:" . a:divname . " = ". a:n1 / a:n2
+: return "ok"
+:endfunction
+:func Expr1()
+: 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
+:let g:FuncRef=function("FuncWithRef")
+:let counter = 0
+:inoremap <expr> ( ListItem()
+:inoremap <expr> [ ListReset()
+:imap <expr> + Expr1()
+:imap <expr> * Expr2()
+:let retval = "nop"
+/^here
+C=Table("xxx", 4, "asdf")
+ =Compute(45, 0, "retval")
+ =retval
+ =Compute(45, 5, "retval")
+ =retval
+ =g:FuncRef(333)
+
+XX+-XX
+---*---
+(one
+(two
+[(one again:call append(line('$'), max([1, 2, 3]))
+:call extend(g:, {'max': function('min')})
+:call append(line('$'), max([1, 2, 3]))
+:try
+: " 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 &&.
+: $put =(0&&(function('tr'))(1, 2, 3))
+: $put =(1&&(function('tr'))(1, 2, 3))
+:catch
+: $put ='!!! Unexpected exception:'
+: $put =v:exception
+:endtry
+:$-9,$w! test.out
+:delfunc Table
+:delfunc Compute
+:delfunc Expr1
+:delfunc Expr2
+:delfunc ListItem
+:delfunc ListReset
+:unlet retval counter
+:q!
+ENDTEST
+
+here
diff --git a/src/testdir/test34.ok b/src/testdir/test34.ok
new file mode 100644
index 0000000000..97995de80e
--- /dev/null
+++ b/src/testdir/test34.ok
@@ -0,0 +1,10 @@
+xxx4asdf fail nop ok 9 333
+XX111-XX
+---222---
+1. one
+2. two
+1. one again
+3
+3
+0
+1
diff --git a/src/testdir/test35.in b/src/testdir/test35.in
new file mode 100644
index 0000000000..ba97911a1d
--- /dev/null
+++ b/src/testdir/test35.in
@@ -0,0 +1,21 @@
+Test Ctrl-A and Ctrl-X, which increment and decrement decimal, hexadecimal,
+and octal numbers.
+
+STARTTEST
+/^start-here
+:set nrformats=octal,hex
+j102ll64128$
+:set nrformats=octal
+0102l2w65129blx6lD
+:set nrformats=hex
+0101l257Txldt   
+:set nrformats=
+0200l100w78k
+:$-3,$wq! test.out
+ENDTEST
+
+start-here
+100 0x100 077 0
+100 0x100 077
+100 0x100 077 0xfF 0xFf
+100 0x100 077
diff --git a/src/testdir/test35.ok b/src/testdir/test35.ok
new file mode 100644
index 0000000000..093ad958ac
--- /dev/null
+++ b/src/testdir/test35.ok
@@ -0,0 +1,4 @@
+0 0x0ff 0000 -1
+0 1x100 0777777
+-1 0x0 078 0xFE 0xfe
+-100 -100x100 000
diff --git a/src/testdir/test36.in b/src/testdir/test36.in
new file mode 100644
index 0000000000..8cdb5262bd
--- /dev/null
+++ b/src/testdir/test36.in
@@ -0,0 +1,105 @@
+Test character classes in regexp using regexpengine 0, 1, 2.
+
+STARTTEST
+/^start-here/+1
+Y:s/\%#=0\d//g
+p:s/\%#=1\d//g
+p:s/\%#=2\d//g
+p:s/\%#=0[0-9]//g
+p:s/\%#=1[0-9]//g
+p:s/\%#=2[0-9]//g
+p:s/\%#=0\D//g
+p:s/\%#=1\D//g
+p:s/\%#=2\D//g
+p:s/\%#=0[^0-9]//g
+p:s/\%#=1[^0-9]//g
+p:s/\%#=2[^0-9]//g
+p:s/\%#=0\o//g
+p:s/\%#=1\o//g
+p:s/\%#=2\o//g
+p:s/\%#=0[0-7]//g
+p:s/\%#=1[0-7]//g
+p:s/\%#=2[0-7]//g
+p:s/\%#=0\O//g
+p:s/\%#=1\O//g
+p:s/\%#=2\O//g
+p:s/\%#=0[^0-7]//g
+p:s/\%#=1[^0-7]//g
+p:s/\%#=2[^0-7]//g
+p:s/\%#=0\x//g
+p:s/\%#=1\x//g
+p:s/\%#=2\x//g
+p:s/\%#=0[0-9A-Fa-f]//g
+p:s/\%#=1[0-9A-Fa-f]//g
+p:s/\%#=2[0-9A-Fa-f]//g
+p:s/\%#=0\X//g
+p:s/\%#=1\X//g
+p:s/\%#=2\X//g
+p:s/\%#=0[^0-9A-Fa-f]//g
+p:s/\%#=1[^0-9A-Fa-f]//g
+p:s/\%#=2[^0-9A-Fa-f]//g
+p:s/\%#=0\w//g
+p:s/\%#=1\w//g
+p:s/\%#=2\w//g
+p:s/\%#=0[0-9A-Za-z_]//g
+p:s/\%#=1[0-9A-Za-z_]//g
+p:s/\%#=2[0-9A-Za-z_]//g
+p:s/\%#=0\W//g
+p:s/\%#=1\W//g
+p:s/\%#=2\W//g
+p:s/\%#=0[^0-9A-Za-z_]//g
+p:s/\%#=1[^0-9A-Za-z_]//g
+p:s/\%#=2[^0-9A-Za-z_]//g
+p:s/\%#=0\h//g
+p:s/\%#=1\h//g
+p:s/\%#=2\h//g
+p:s/\%#=0[A-Za-z_]//g
+p:s/\%#=1[A-Za-z_]//g
+p:s/\%#=2[A-Za-z_]//g
+p:s/\%#=0\H//g
+p:s/\%#=1\H//g
+p:s/\%#=2\H//g
+p:s/\%#=0[^A-Za-z_]//g
+p:s/\%#=1[^A-Za-z_]//g
+p:s/\%#=2[^A-Za-z_]//g
+p:s/\%#=0\a//g
+p:s/\%#=1\a//g
+p:s/\%#=2\a//g
+p:s/\%#=0[A-Za-z]//g
+p:s/\%#=1[A-Za-z]//g
+p:s/\%#=2[A-Za-z]//g
+p:s/\%#=0\A//g
+p:s/\%#=1\A//g
+p:s/\%#=2\A//g
+p:s/\%#=0[^A-Za-z]//g
+p:s/\%#=1[^A-Za-z]//g
+p:s/\%#=2[^A-Za-z]//g
+p:s/\%#=0\l//g
+p:s/\%#=1\l//g
+p:s/\%#=2\l//g
+p:s/\%#=0[a-z]//g
+p:s/\%#=1[a-z]//g
+p:s/\%#=2[a-z]//g
+p:s/\%#=0\L//g
+p:s/\%#=1\L//g
+p:s/\%#=2\L//g
+p:s/\%#=0[^a-z]//g
+p:s/\%#=1[^a-z]//g
+p:s/\%#=2[^a-z]//g
+p:s/\%#=0\u//g
+p:s/\%#=1\u//g
+p:s/\%#=2\u//g
+p:s/\%#=0[A-Z]//g
+p:s/\%#=1[A-Z]//g
+p:s/\%#=2[A-Z]//g
+p:s/\%#=0\U//g
+p:s/\%#=1\U//g
+p:s/\%#=2\U//g
+p:s/\%#=0[^A-Z]//g
+p:s/\%#=1[^A-Z]//g
+p:s/\%#=2[^A-Z]//g
+:/^start-here/+1,$wq! test.out
+ENDTEST
+
+start-here
+ !"#$%&'()#+'-./0123456789:;<=>?@ABCDEFGHIXYZ[\]^_`abcdefghiwxyz{|}~€‚›¦±¼ÇÓé
diff --git a/src/testdir/test36.ok b/src/testdir/test36.ok
new file mode 100644
index 0000000000..f72a74b2b7
--- /dev/null
+++ b/src/testdir/test36.ok
@@ -0,0 +1,96 @@
+ !"#$%&'()#+'-./:;<=>?@ABCDEFGHIXYZ[\]^_`abcdefghiwxyz{|}~€‚›¦±¼ÇÓé
+ !"#$%&'()#+'-./:;<=>?@ABCDEFGHIXYZ[\]^_`abcdefghiwxyz{|}~€‚›¦±¼ÇÓé
+ !"#$%&'()#+'-./:;<=>?@ABCDEFGHIXYZ[\]^_`abcdefghiwxyz{|}~€‚›¦±¼ÇÓé
+ !"#$%&'()#+'-./:;<=>?@ABCDEFGHIXYZ[\]^_`abcdefghiwxyz{|}~€‚›¦±¼ÇÓé
+ !"#$%&'()#+'-./:;<=>?@ABCDEFGHIXYZ[\]^_`abcdefghiwxyz{|}~€‚›¦±¼ÇÓé
+ !"#$%&'()#+'-./:;<=>?@ABCDEFGHIXYZ[\]^_`abcdefghiwxyz{|}~€‚›¦±¼ÇÓé
+0123456789
+0123456789
+0123456789
+0123456789
+0123456789
+0123456789
+ !"#$%&'()#+'-./89:;<=>?@ABCDEFGHIXYZ[\]^_`abcdefghiwxyz{|}~€‚›¦±¼ÇÓé
+ !"#$%&'()#+'-./89:;<=>?@ABCDEFGHIXYZ[\]^_`abcdefghiwxyz{|}~€‚›¦±¼ÇÓé
+ !"#$%&'()#+'-./89:;<=>?@ABCDEFGHIXYZ[\]^_`abcdefghiwxyz{|}~€‚›¦±¼ÇÓé
+ !"#$%&'()#+'-./89:;<=>?@ABCDEFGHIXYZ[\]^_`abcdefghiwxyz{|}~€‚›¦±¼ÇÓé
+ !"#$%&'()#+'-./89:;<=>?@ABCDEFGHIXYZ[\]^_`abcdefghiwxyz{|}~€‚›¦±¼ÇÓé
+ !"#$%&'()#+'-./89:;<=>?@ABCDEFGHIXYZ[\]^_`abcdefghiwxyz{|}~€‚›¦±¼ÇÓé
+01234567
+01234567
+01234567
+01234567
+01234567
+01234567
+ !"#$%&'()#+'-./:;<=>?@GHIXYZ[\]^_`ghiwxyz{|}~€‚›¦±¼ÇÓé
+ !"#$%&'()#+'-./:;<=>?@GHIXYZ[\]^_`ghiwxyz{|}~€‚›¦±¼ÇÓé
+ !"#$%&'()#+'-./:;<=>?@GHIXYZ[\]^_`ghiwxyz{|}~€‚›¦±¼ÇÓé
+ !"#$%&'()#+'-./:;<=>?@GHIXYZ[\]^_`ghiwxyz{|}~€‚›¦±¼ÇÓé
+ !"#$%&'()#+'-./:;<=>?@GHIXYZ[\]^_`ghiwxyz{|}~€‚›¦±¼ÇÓé
+ !"#$%&'()#+'-./:;<=>?@GHIXYZ[\]^_`ghiwxyz{|}~€‚›¦±¼ÇÓé
+0123456789ABCDEFabcdef
+0123456789ABCDEFabcdef
+0123456789ABCDEFabcdef
+0123456789ABCDEFabcdef
+0123456789ABCDEFabcdef
+0123456789ABCDEFabcdef
+ !"#$%&'()#+'-./:;<=>?@[\]^`{|}~€‚›¦±¼ÇÓé
+ !"#$%&'()#+'-./:;<=>?@[\]^`{|}~€‚›¦±¼ÇÓé
+ !"#$%&'()#+'-./:;<=>?@[\]^`{|}~€‚›¦±¼ÇÓé
+ !"#$%&'()#+'-./:;<=>?@[\]^`{|}~€‚›¦±¼ÇÓé
+ !"#$%&'()#+'-./:;<=>?@[\]^`{|}~€‚›¦±¼ÇÓé
+ !"#$%&'()#+'-./:;<=>?@[\]^`{|}~€‚›¦±¼ÇÓé
+0123456789ABCDEFGHIXYZ_abcdefghiwxyz
+0123456789ABCDEFGHIXYZ_abcdefghiwxyz
+0123456789ABCDEFGHIXYZ_abcdefghiwxyz
+0123456789ABCDEFGHIXYZ_abcdefghiwxyz
+0123456789ABCDEFGHIXYZ_abcdefghiwxyz
+0123456789ABCDEFGHIXYZ_abcdefghiwxyz
+ !"#$%&'()#+'-./0123456789:;<=>?@[\]^`{|}~€‚›¦±¼ÇÓé
+ !"#$%&'()#+'-./0123456789:;<=>?@[\]^`{|}~€‚›¦±¼ÇÓé
+ !"#$%&'()#+'-./0123456789:;<=>?@[\]^`{|}~€‚›¦±¼ÇÓé
+ !"#$%&'()#+'-./0123456789:;<=>?@[\]^`{|}~€‚›¦±¼ÇÓé
+ !"#$%&'()#+'-./0123456789:;<=>?@[\]^`{|}~€‚›¦±¼ÇÓé
+ !"#$%&'()#+'-./0123456789:;<=>?@[\]^`{|}~€‚›¦±¼ÇÓé
+ABCDEFGHIXYZ_abcdefghiwxyz
+ABCDEFGHIXYZ_abcdefghiwxyz
+ABCDEFGHIXYZ_abcdefghiwxyz
+ABCDEFGHIXYZ_abcdefghiwxyz
+ABCDEFGHIXYZ_abcdefghiwxyz
+ABCDEFGHIXYZ_abcdefghiwxyz
+ !"#$%&'()#+'-./0123456789:;<=>?@[\]^_`{|}~€‚›¦±¼ÇÓé
+ !"#$%&'()#+'-./0123456789:;<=>?@[\]^_`{|}~€‚›¦±¼ÇÓé
+ !"#$%&'()#+'-./0123456789:;<=>?@[\]^_`{|}~€‚›¦±¼ÇÓé
+ !"#$%&'()#+'-./0123456789:;<=>?@[\]^_`{|}~€‚›¦±¼ÇÓé
+ !"#$%&'()#+'-./0123456789:;<=>?@[\]^_`{|}~€‚›¦±¼ÇÓé
+ !"#$%&'()#+'-./0123456789:;<=>?@[\]^_`{|}~€‚›¦±¼ÇÓé
+ABCDEFGHIXYZabcdefghiwxyz
+ABCDEFGHIXYZabcdefghiwxyz
+ABCDEFGHIXYZabcdefghiwxyz
+ABCDEFGHIXYZabcdefghiwxyz
+ABCDEFGHIXYZabcdefghiwxyz
+ABCDEFGHIXYZabcdefghiwxyz
+ !"#$%&'()#+'-./0123456789:;<=>?@ABCDEFGHIXYZ[\]^_`{|}~€‚›¦±¼ÇÓé
+ !"#$%&'()#+'-./0123456789:;<=>?@ABCDEFGHIXYZ[\]^_`{|}~€‚›¦±¼ÇÓé
+ !"#$%&'()#+'-./0123456789:;<=>?@ABCDEFGHIXYZ[\]^_`{|}~€‚›¦±¼ÇÓé
+ !"#$%&'()#+'-./0123456789:;<=>?@ABCDEFGHIXYZ[\]^_`{|}~€‚›¦±¼ÇÓé
+ !"#$%&'()#+'-./0123456789:;<=>?@ABCDEFGHIXYZ[\]^_`{|}~€‚›¦±¼ÇÓé
+ !"#$%&'()#+'-./0123456789:;<=>?@ABCDEFGHIXYZ[\]^_`{|}~€‚›¦±¼ÇÓé
+abcdefghiwxyz
+abcdefghiwxyz
+abcdefghiwxyz
+abcdefghiwxyz
+abcdefghiwxyz
+abcdefghiwxyz
+ !"#$%&'()#+'-./0123456789:;<=>?@[\]^_`abcdefghiwxyz{|}~€‚›¦±¼ÇÓé
+ !"#$%&'()#+'-./0123456789:;<=>?@[\]^_`abcdefghiwxyz{|}~€‚›¦±¼ÇÓé
+ !"#$%&'()#+'-./0123456789:;<=>?@[\]^_`abcdefghiwxyz{|}~€‚›¦±¼ÇÓé
+ !"#$%&'()#+'-./0123456789:;<=>?@[\]^_`abcdefghiwxyz{|}~€‚›¦±¼ÇÓé
+ !"#$%&'()#+'-./0123456789:;<=>?@[\]^_`abcdefghiwxyz{|}~€‚›¦±¼ÇÓé
+ !"#$%&'()#+'-./0123456789:;<=>?@[\]^_`abcdefghiwxyz{|}~€‚›¦±¼ÇÓé
+ABCDEFGHIXYZ
+ABCDEFGHIXYZ
+ABCDEFGHIXYZ
+ABCDEFGHIXYZ
+ABCDEFGHIXYZ
+ABCDEFGHIXYZ
diff --git a/src/testdir/test37.in b/src/testdir/test37.in
new file mode 100644
index 0000000000..8ca1125793
--- /dev/null
+++ b/src/testdir/test37.in
@@ -0,0 +1,116 @@
+Test for 'scrollbind'. <eralston@computer.org> Do not add a line below!
+STARTTEST
+:so small.vim
+:set noscrollbind
+:set scrollopt=ver,jump
+:set scrolloff=2
+:set nowrap
+:set noequalalways
+:set splitbelow
+:" TEST using two windows open to one buffer, one extra empty window
+:split
+:new
+t:
+:resize 8
+/^start of window 1$/
+zt:
+:set scrollbind
+j:
+:resize 7
+/^start of window 2$/
+zt:
+:set scrollbind
+:" -- start of tests --
+:" TEST scrolling down
+L5jHyybpr0tHyybpr1tL6jHyybpr2kHyybpr3:
+:" TEST scrolling up
+tH4kjHtHyybpr4kHyybpr5k3ktHjHyybpr6tHyybpr7:
+:" TEST horizontal scrolling
+:set scrollopt+=hor
+gg"zyyG"zpGt015zly$bp"zpGky$bp"zpG:
+k10jH7zhg0y$bp"zpGtHg0y$bp"zpG:
+:set scrollopt-=hor
+:" ****** tests using two different buffers *****
+tj:
+:close
+t:
+:set noscrollbind
+:/^start of window 2$/,/^end of window 2$/y
+:new
+tj4"zpGp:
+t/^start of window 1$/
+zt:
+:set scrollbind
+j:
+/^start of window 2$/
+zt:
+:set scrollbind
+:" -- start of tests --
+:" TEST scrolling down
+L5jHyybpr0tHyybpr1tL6jHyybpr2kHyybpr3:
+:" TEST scrolling up
+tH4kjHtHyybpr4kHyybpr5k3ktHjHyybpr6tHyybpr7:
+:" TEST horizontal scrolling
+:set scrollopt+=hor
+gg"zyyG"zpGt015zly$bp"zpGky$bp"zpG:
+k10jH7zhg0y$bp"zpGtHg0y$bp"zpG:
+:set scrollopt-=hor
+:" TEST syncbind
+t:set noscb
+ggLj:set noscb
+ggL:set scb
+t:set scb
+GjG:syncbind
+HktHjHyybptyybp:
+t:set noscb
+ggLj:set noscb
+ggL:set scb
+t:set scb
+tGjGt:syncbind
+HkjHtHyybptjyybp:
+tH3kjHtHyybptjyybp:
+:" ***** done with tests *****
+:w! test.out " Write contents of this file
+:qa!
+ENDTEST
+
+
+start of window 1
+. line 01 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 01
+. line 02 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 02
+. line 03 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 03
+. line 04 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 04
+. line 05 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 05
+. line 06 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 06
+. line 07 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 07
+. line 08 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 08
+. line 09 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 09
+. line 10 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 10
+. line 11 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 11
+. line 12 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 12
+. line 13 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 13
+. line 14 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 14
+. line 15 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 15
+end of window 1
+
+
+start of window 2
+. line 01 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 01
+. line 02 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 02
+. line 03 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 03
+. line 04 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 04
+. line 05 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 05
+. line 06 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 06
+. line 07 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 07
+. line 08 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 08
+. line 09 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 09
+. line 10 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 10
+. line 11 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 11
+. line 12 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 12
+. line 13 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 13
+. line 14 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 14
+. line 15 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 15
+. line 16 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 16
+end of window 2
+
+end of test37.in (please don't delete this line)
diff --git a/src/testdir/test37.ok b/src/testdir/test37.ok
new file mode 100644
index 0000000000..d0b74853b3
--- /dev/null
+++ b/src/testdir/test37.ok
@@ -0,0 +1,33 @@
+
+0 line 05 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 05
+1 line 05 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 05
+2 line 11 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 11
+3 line 11 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 11
+4 line 06 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 06
+5 line 06 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 06
+6 line 02 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 02
+7 line 02 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 02
+56789ABCDEFGHIJKLMNOPQRSTUVWXYZ 02
+UTSRQPONMLKJIHGREDCBA9876543210 02
+. line 11 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 11
+. line 11 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 11
+
+0 line 05 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 05
+1 line 05 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 05
+2 line 11 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 11
+3 line 11 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 11
+4 line 06 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 06
+5 line 06 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 06
+6 line 02 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 02
+7 line 02 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 02
+56789ABCDEFGHIJKLMNOPQRSTUVWXYZ 02
+UTSRQPONMLKJIHGREDCBA9876543210 02
+. line 11 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 11
+. line 11 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 11
+
+. line 16 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 16
+:set scrollbind
+:set scrollbind
+. line 16 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 16
+j:
+. line 12 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 12
diff --git a/src/testdir/test38.in b/src/testdir/test38.in
new file mode 100644
index 0000000000..3e0236251b
--- /dev/null
+++ b/src/testdir/test38.in
@@ -0,0 +1,35 @@
+
+Test Virtual replace mode.
+
+STARTTEST
+:so small.vim
+:" make sure that backspace works, no matter what termcap is used
+:set t_kD=x7f t_kb=x08
+ggdGa
+abcdefghi
+jk lmn
+ opq rst
+uvwxyz
+gg:set ai
+:set bs=2
+gR0 1
+A
+BCDEFGHIJ
+ KL
+MNO
+PQRG:ka
+o0
+abcdefghi
+jk lmn
+ opq rst
+uvwxyz
+'ajgR0 1
+A
+BCDEFGHIJ
+ KL
+MNO
+PQR:$
+iab cdefghi jkl0gRAB......CDEFGHI.Jo:
+iabcdefghijklmnopqrst0gRAB IJKLMNO QR:wq! test.out
+ENDTEST
+
diff --git a/src/testdir/test38.ok b/src/testdir/test38.ok
new file mode 100644
index 0000000000..e10209667b
--- /dev/null
+++ b/src/testdir/test38.ok
@@ -0,0 +1,13 @@
+ 1
+ A
+ BCDEFGHIJ
+ KL
+ MNO
+ PQR
+ 1
+abcdefghi
+jk lmn
+ opq rst
+uvwxyz
+AB......CDEFGHI.Jkl
+AB IJKLMNO QRst
diff --git a/src/testdir/test39.in b/src/testdir/test39.in
new file mode 100644
index 0000000000..8f45f47dc3
--- /dev/null
+++ b/src/testdir/test39.in
@@ -0,0 +1,83 @@
+
+Test Visual block mode commands
+And test "U" in Visual mode, also on German sharp S.
+
+STARTTEST
+:so small.vim
+:so mbyte.vim
+:" This only works when 'encoding' is "latin1", don't depend on the environment
+:set enc=latin1
+/^abcde
+:" Test shift-right of a block
+jlllljj>wlljlll>
+:" Test shift-left of a block
+G$hhhhkk<
+:" Test block-insert
+GklkkkIxyz
+:" Test block-replace
+Gllllkkklllrq
+:" Test block-change
+G$khhhhhkkcmno
+:$-4,$w! test.out
+:" Test block-insert using cursor keys for movement
+/^aaaa/
+:exe ":norm! l\<C-V>jjjlllI\<Right>\<Right> \<Esc>"
+:/^aa/,/^$/w >> test.out
+:" Test for Visual block was created with the last <C-v>$
+/^A23$/
+:exe ":norm! l\<C-V>j$Aab\<Esc>"
+:.,/^$/w >> test.out
+:" Test for Visual block was created with the middle <C-v>$ (1)
+/^B23$/
+:exe ":norm! l\<C-V>j$hAab\<Esc>"
+:.,/^$/w >> test.out
+:" Test for Visual block was created with the middle <C-v>$ (2)
+/^C23$/
+:exe ":norm! l\<C-V>j$hhAab\<Esc>"
+:.,/^$/w >> test.out
+:" gUe must uppercase a whole word, also when ß changes to SS
+Gothe youtußeuu endYpk0wgUe
+:" gUfx must uppercase until x, inclusive.
+O- youßtußexu -0fogUfx
+:" VU must uppercase a whole line
+YpkVU
+:" same, when it's the last line in the buffer
+YPGi111VUddP
+:" Uppercase two lines
+Oblah di
+doh dutVkUj
+:" Uppercase part of two lines
+ddppi333k0i222fyllvjfuUk
+:" visual replace using Enter or NL
+G3o1234567892k05l2jr G3o987652k02l2jr
+G3o1234567892k05l2jr
+G3o987652k02l2jr
+:"
+:" Test cursor position. When ve=block and Visual block mode and $gj
+:set ve=block
+:exe ":norm! 2k\<C-V>$gj\<Esc>"
+:let cpos=getpos("'>")
+:$put ='col:'.cpos[2].' off:'.cpos[3]
+:/^the/,$w >> test.out
+:qa!
+ENDTEST
+
+aaaaaa
+bbbbbb
+cccccc
+dddddd
+
+A23
+4567
+
+B23
+4567
+
+C23
+4567
+
+abcdefghijklm
+abcdefghijklm
+abcdefghijklm
+abcdefghijklm
+abcdefghijklm
diff --git a/src/testdir/test39.ok b/src/testdir/test39.ok
new file mode 100644
index 0000000000..b459355c6a
--- /dev/null
+++ b/src/testdir/test39.ok
Binary files differ
diff --git a/src/testdir/test4.in b/src/testdir/test4.in
new file mode 100644
index 0000000000..4aa2fe5a86
--- /dev/null
+++ b/src/testdir/test4.in
@@ -0,0 +1,31 @@
+Test for autocommand that changes current buffer on BufEnter event.
+Check if modelines are interpreted for the correct buffer.
+
+STARTTEST
+:so small.vim
+:set nocompatible viminfo+=nviminfo
+:au BufEnter Xxx brew
+/start of
+:.,/end of/w! Xxx " write test file Xxx
+:set ai modeline modelines=3
+:sp Xxx " split to Xxx, autocmd will do :brew
+G?this is a
+othis should be auto-indented
+: " Append text with autoindent to this file
+:au! BufEnter Xxx
+:buf Xxx " go to Xxx, no autocmd anymore
+G?this is a
+othis should be in column 1:wq " append text without autoindent to Xxx
+G:r Xxx " include Xxx in the current file
+:?startstart?,$w! test.out
+:qa!
+ENDTEST
+
+startstart
+start of test file Xxx
+vim: set noai :
+ this is a test
+ this is a test
+ this is a test
+ this is a test
+end of test file Xxx
diff --git a/src/testdir/test4.ok b/src/testdir/test4.ok
new file mode 100644
index 0000000000..dffecda4d2
--- /dev/null
+++ b/src/testdir/test4.ok
@@ -0,0 +1,17 @@
+startstart
+start of test file Xxx
+vim: set noai :
+ this is a test
+ this is a test
+ this is a test
+ this is a test
+ this should be auto-indented
+end of test file Xxx
+start of test file Xxx
+vim: set noai :
+ this is a test
+ this is a test
+ this is a test
+ this is a test
+this should be in column 1
+end of test file Xxx
diff --git a/src/testdir/test40.in b/src/testdir/test40.in
new file mode 100644
index 0000000000..d92a18f3d0
--- /dev/null
+++ b/src/testdir/test40.in
@@ -0,0 +1,63 @@
+Test for "*Cmd" autocommands
+
+STARTTEST
+:so small.vim
+:/^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/testdir/test40.ok b/src/testdir/test40.ok
new file mode 100644
index 0000000000..b6501394f9
--- /dev/null
+++ b/src/testdir/test40.ok
@@ -0,0 +1,11 @@
+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/testdir/test41.in b/src/testdir/test41.in
new file mode 100644
index 0000000000..2d294cae09
--- /dev/null
+++ b/src/testdir/test41.in
@@ -0,0 +1,24 @@
+Test for writing and reading a file of over 100 Kbyte
+
+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"
+
+STARTTEST
+:%d
+aThis is the start
+This is the leader
+This is the middle
+This is the trailer
+This is the endkY3000p2GY3000p
+:w! Xtest
+:%d
+:e! Xtest
+:.w! test.out
+3003G:.w >>test.out
+6005G:.w >>test.out
+:qa!
+ENDTEST
+
diff --git a/src/testdir/test41.ok b/src/testdir/test41.ok
new file mode 100644
index 0000000000..988e5f24b4
--- /dev/null
+++ b/src/testdir/test41.ok
@@ -0,0 +1,3 @@
+This is the start
+This is the middle
+This is the end
diff --git a/src/testdir/test42.in b/src/testdir/test42.in
new file mode 100644
index 0000000000..c35569a76c
--- /dev/null
+++ b/src/testdir/test42.in
Binary files differ
diff --git a/src/testdir/test42.ok b/src/testdir/test42.ok
new file mode 100644
index 0000000000..183430d71c
--- /dev/null
+++ b/src/testdir/test42.ok
Binary files differ
diff --git a/src/testdir/test43.in b/src/testdir/test43.in
new file mode 100644
index 0000000000..7c545073da
--- /dev/null
+++ b/src/testdir/test43.in
@@ -0,0 +1,34 @@
+Tests for regexp with various magic settings.
+
+STARTTEST
+:so small.vim
+:set nocompatible viminfo+=nviminfo
+/^1
+/a*b\{2}c\+/e
+x/\Md\*e\{2}f\+/e
+x:set nomagic
+/g\*h\{2}i\+/e
+x/\mj*k\{2}l\+/e
+x/\vm*n{2}o+/e
+x/\V^aa$
+x:set magic
+/\v(a)(b)\2\1\1/e
+x/\V[ab]\(\[xy]\)\1
+x:$
+:set undolevels=100
+dv?bar?
+Yup:"
+:?^1?,$w! test.out
+:qa!
+ENDTEST
+
+1 a aa abb abbccc
+2 d dd dee deefff
+3 g gg ghh ghhiii
+4 j jj jkk jkklll
+5 m mm mnn mnnooo
+6 x ^aa$ x
+7 (a)(b) abbaa
+8 axx [ab]xx
+9 foobar
+
diff --git a/src/testdir/test43.ok b/src/testdir/test43.ok
new file mode 100644
index 0000000000..0b37a6a61e
--- /dev/null
+++ b/src/testdir/test43.ok
@@ -0,0 +1,11 @@
+1 a aa abb abbcc
+2 d dd dee deeff
+3 g gg ghh ghhii
+4 j jj jkk jkkll
+5 m mm mnn mnnoo
+6 x aa$ x
+7 (a)(b) abba
+8 axx ab]xx
+9 foobar
+9 foo
+
diff --git a/src/testdir/test44.in b/src/testdir/test44.in
new file mode 100644
index 0000000000..87de1b95a4
--- /dev/null
+++ b/src/testdir/test44.in
@@ -0,0 +1,68 @@
+Tests for regexp with multi-byte encoding and various magic settings.
+Test matchstr() with a count and multi-byte chars.
+See test99 for exactly the same test with re=2.
+
+STARTTEST
+:so mbyte.vim
+:set nocompatible encoding=utf-8 termencoding=latin1 viminfo+=nviminfo
+:set re=1
+/^1
+/a*b\{2}c\+/e
+x/\Md\*e\{2}f\+/e
+x:set nomagic
+/g\*h\{2}i\+/e
+x/\mj*k\{2}l\+/e
+x/\vm*n{2}o+/e
+x/\V^aa$
+x:set magic
+/\v(a)(b)\2\1\1/e
+x/\V[ab]\(\[xy]\)\1
+x:" Now search for multi-byte without composing char
+/ม
+x:" Now search for multi-byte with composing char
+/ม่
+x:" find word by change of word class
+/ã¡\<カヨ\>ã¯
+x:" Test \%u, [\u] and friends
+/\%u20ac
+x/[\u4f7f\u5929]\+
+x/\%U12345678
+x/[\U1234abcd\u1234\uabcd]
+x/\%d21879b
+x/ [[=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=]]*/e
+x/ [[=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=]]*/e
+x:" Test backwards search from a multi-byte char
+/x
+x?.
+x:let @w=':%s#comb[i]nations#œ̄ṣÌm̥̄ᾱ̆Ì#g'
+:@w
+:?^1?,$w! test.out
+:e! test.out
+G:put =matchstr(\"×בגד\", \".\", 0, 2) " ב
+:put =matchstr(\"×בגד\", \"..\", 0, 2) " בג
+:put =matchstr(\"×בגד\", \".\", 0, 0) " ×
+:put =matchstr(\"×בגד\", \".\", 4, -1) " ×’
+:w!
+:qa!
+ENDTEST
+
+1 a aa abb abbccc
+2 d dd dee deefff
+3 g gg ghh ghhiii
+4 j jj jkk jkklll
+5 m mm mnn mnnooo
+6 x ^aa$ x
+7 (a)(b) abbaa
+8 axx [ab]xx
+9 หม่x อมx
+a อมx หม่x
+b ã¡ã‚«ãƒ¨ã¯
+c x ¬€x
+d 天使x
+e ü’…™¸y
+f ü’Нz
+g aå•·bb
+h 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ŹŻŽƵáºáº”
+i 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źżžƶẑẕ
+j 0123â¤x
+k combinations
diff --git a/src/testdir/test44.ok b/src/testdir/test44.ok
new file mode 100644
index 0000000000..0bd0b8ab73
--- /dev/null
+++ b/src/testdir/test44.ok
@@ -0,0 +1,24 @@
+1 a aa abb abbcc
+2 d dd dee deeff
+3 g gg ghh ghhii
+4 j jj jkk jkkll
+5 m mm mnn mnnoo
+6 x aa$ x
+7 (a)(b) abba
+8 axx ab]xx
+9 หม่x อx
+a อมx หx
+b カヨã¯
+c x ¬x
+d 使x
+e y
+f z
+g abb
+h 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ŹŻŽƵáº
+i 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źżžƶẑ
+j 012â¤
+k œ̄ṣÌm̥̄ᾱ̆Ì
+ב
+בג
+×’
diff --git a/src/testdir/test45.in b/src/testdir/test45.in
new file mode 100644
index 0000000000..e5af5073d9
--- /dev/null
+++ b/src/testdir/test45.in
@@ -0,0 +1,80 @@
+Tests for folding. vim: set ft=vim :
+
+STARTTEST
+:so small.vim
+:" We also need the +syntax feature here.
+:if !has("syntax")
+ e! test.ok
+ w! test.out
+ qa!
+:endif
+:" basic test if a fold can be created, opened, moving to the end and closed
+/^1
+zf2j:call append("$", "manual " . getline(foldclosed(".")))
+zo:call append("$", foldclosed("."))
+]z:call append("$", getline("."))
+zc:call append("$", getline(foldclosed(".")))
+:" test folding with markers.
+:set fdm=marker fdl=1 fdc=3
+/^5
+:call append("$", "marker " . foldlevel("."))
+[z:call append("$", foldlevel("."))
+jo{{ r{jj:call append("$", foldlevel("."))
+kYpj:call append("$", foldlevel("."))
+:" test folding with indent
+:set fdm=indent sw=2
+/^2 b
+i jI :call append("$", "indent " . foldlevel("."))
+k:call append("$", foldlevel("."))
+:" test syntax folding
+: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
+Gzk:call append("$", "folding " . getline("."))
+k:call append("$", getline("."))
+jAcommentstart Acommentend:set fdl=1
+3j:call append("$", getline("."))
+:set fdl=0
+zO j:call append("$", getline("."))
+:" test expression folding
+:fun 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
+:set fdm=expr fde=Flvl()
+/bb$
+:call append("$", "expr " . foldlevel("."))
+/hh$
+:call append("$", foldlevel("."))
+/ii$
+:call append("$", foldlevel("."))
+/kk$
+:call append("$", foldlevel("."))
+:/^last/+1,$w! test.out
+:delfun Flvl
+:qa!
+ENDTEST
+
+1 aa
+2 bb
+3 cc
+4 dd {{{
+5 ee {{{ }}}
+6 ff }}}
+7 gg
+8 hh
+9 ii
+a jj
+b kk
+last
diff --git a/src/testdir/test45.ok b/src/testdir/test45.ok
new file mode 100644
index 0000000000..f04996e337
--- /dev/null
+++ b/src/testdir/test45.ok
@@ -0,0 +1,18 @@
+manual 1 aa
+-1
+3 cc
+1 aa
+marker 2
+1
+1
+0
+indent 2
+1
+folding 9 ii
+ 3 cc
+7 gg
+8 hh
+expr 2
+1
+2
+0
diff --git a/src/testdir/test46.in b/src/testdir/test46.in
new file mode 100644
index 0000000000..9a9db74d62
--- /dev/null
+++ b/src/testdir/test46.in
@@ -0,0 +1,27 @@
+Tests for multi-line regexps with ":s". vim: set ft=vim :
+
+STARTTEST
+:" 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/
+:/^1/,$w! test.out
+:qa!
+ENDTEST
+
+1 aa
+bb
+cc
+2 dd
+ee
+3 ef
+gh
+4 ij
+5 a8
+8b c9
+9d
+6 e7
+77f
+xxxxx
diff --git a/src/testdir/test46.ok b/src/testdir/test46.ok
new file mode 100644
index 0000000000..71b353df1d
--- /dev/null
+++ b/src/testdir/test46.ok
@@ -0,0 +1,13 @@
+1 aa bb cc 2 dd ee
+3 e
+f
+g
+h
+4 i
+j
+5 ax8
+8xb cx9
+9xd
+6 ex7
+7x7f
+xxxxx
diff --git a/src/testdir/test47.in b/src/testdir/test47.in
new file mode 100644
index 0000000000..13ad82462f
--- /dev/null
+++ b/src/testdir/test47.in
@@ -0,0 +1,62 @@
+Tests for vertical splits and filler lines in diff mode
+
+STARTTEST
+:so small.vim
+:" 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
+:vert diffsplit Xtest
+:vert diffsplit Xtest2
+:" 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 that diffing shows correct filler lines
+:diffoff!
+: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 w0
+:qa!
+ENDTEST
+
+1 aa
+2 bb
+3 cc
+4 dd
+5 ee
diff --git a/src/testdir/test47.ok b/src/testdir/test47.ok
new file mode 100644
index 0000000000..b1cba92b1c
--- /dev/null
+++ b/src/testdir/test47.ok
@@ -0,0 +1,4 @@
+2-4-5-6-8-9
+1-2-4-5-8
+2-3-4-5-6-7-8
+1
diff --git a/src/testdir/test48.in b/src/testdir/test48.in
new file mode 100644
index 0000000000..48f4abbf75
--- /dev/null
+++ b/src/testdir/test48.in
@@ -0,0 +1,78 @@
+This is a test of 'virtualedit'.
+
+STARTTEST
+:so small.vim
+:set noswf
+:set ve=all
+-dgg
+:"
+:" Insert "keyword keyw", ESC, C CTRL-N, shows "keyword ykeyword".
+:" Repeating CTRL-N fixes it. (Mary Ellen Foster)
+2/w
+C
+:"
+:" Using "C" then then <CR> moves the last remaining character to the next
+:" line. (Mary Ellen Foster)
+j^/are
+C are belong to vim
+:"
+:" When past the end of a line that ends in a single character "b" skips
+:" that word.
+^$15lbC7
+:"
+:" Make sure 'i' works
+$4li<-- should be 3 ' '
+:"
+:" Make sure 'C' works
+$4lC<-- should be 3 ' '
+:"
+:" Make sure 'a' works
+$4la<-- should be 4 ' '
+:"
+:" Make sure 'A' works
+$4lA<-- should be 0 ' '
+:"
+:" Make sure 'D' works
+$4lDi<-- 'D' should be intact
+:"
+:" Test for yank bug reported by Mark Waggoner.
+:set ve=block
+^2w3jyGp
+:"
+:" Test "r" beyond the end of the line
+:set ve=all
+/^"r"
+$5lrxa<-- should be 'x'
+:"
+:" Test to make sure 'x' can delete control characters
+:set display=uhex
+^xxxxxxi[This line should contain only the text between the brackets.]
+:set display=
+:"
+:" Test for ^Y/^E due to bad w_virtcol value, reported by
+:" Roy <royl@netropolis.net>.
+^O3li4li4li <-- should show the name of a noted text editor
+^o4li4li4li <-- and its version number-dd
+:"
+:" Test for yanking and pasting using the small delete register
+gg/^foo
+dewve"-p
+:wq! test.out
+ENDTEST
+foo, bar
+keyword keyw
+all your base are belong to us
+1 2 3 4 5 6
+'i'
+'C'
+'a'
+'A'
+'D'
+this is a test
+this is a test
+this is a test
+"r"
+ab sd
+abcv6efi.him0kl
+
+
diff --git a/src/testdir/test48.ok b/src/testdir/test48.ok
new file mode 100644
index 0000000000..334cb5a29c
--- /dev/null
+++ b/src/testdir/test48.ok
@@ -0,0 +1,22 @@
+, foo
+keyword keyword
+all your base
+are belong to vim
+1 2 3 4 5 7
+'i' <-- should be 3 ' '
+'C' <-- should be 3 ' '
+'a' <-- should be 4 ' '
+'A'<-- should be 0 ' '
+'D' <-- 'D' should be intact
+this is a test
+this is a test
+this is a test
+"r" x<-- should be 'x'
+[This line should contain only the text between the brackets.]
+ v i m <-- should show the name of a noted text editor
+ 6 . 0 <-- and its version number
+
+a
+a
+a
+
diff --git a/src/testdir/test49.in b/src/testdir/test49.in
new file mode 100644
index 0000000000..bd6cb4cad7
--- /dev/null
+++ b/src/testdir/test49.in
@@ -0,0 +1,30 @@
+This is a test of the script language.
+
+If after adding a new test, the test output doesn't appear properly in
+test49.failed, try to add one ore more "G"s at the line ending in "test.out"
+
+STARTTEST
+:so small.vim
+:se nocp nomore viminfo+=nviminfo
+:lang mess C
+:so test49.vim
+GGGGGGGGGGGGGG"rp:.-,$w! test.out
+:"
+:" make valgrind happy
+:redir => funclist
+:silent func
+:redir END
+:for line in split(funclist, "\n")
+: let name = matchstr(line, 'function \zs[A-Z]\w*\ze(')
+: if name != ''
+: exe "delfunc " . name
+: endif
+:endfor
+:for v in keys(g:)
+: silent! exe "unlet " . v
+:endfor
+:unlet v
+:qa!
+ENDTEST
+
+Results of test49.vim:
diff --git a/src/testdir/test49.ok b/src/testdir/test49.ok
new file mode 100644
index 0000000000..bf1ceed9af
--- /dev/null
+++ b/src/testdir/test49.ok
@@ -0,0 +1,99 @@
+Results of test49.vim:
+*** Test 1: OK (34695)
+*** Test 2: OK (34695)
+*** Test 3: OK (1384648195)
+*** Test 4: OK (32883)
+*** Test 5: OK (32883)
+*** Test 6: OK (603978947)
+*** Test 7: OK (90563)
+*** Test 8: OK (562493431)
+*** Test 9: OK (363)
+*** Test 10: OK (559615)
+*** Test 11: OK (2049)
+*** Test 12: OK (352256)
+*** Test 13: OK (145)
+*** Test 14: OK (42413)
+*** Test 15: OK (42413)
+*** Test 16: OK (8722)
+*** Test 17: OK (285127993)
+*** Test 18: OK (67224583)
+*** Test 19: OK (69275973)
+*** Test 20: OK (1874575085)
+*** Test 21: OK (147932225)
+*** Test 22: OK (4161)
+*** Test 23: OK (49)
+*** Test 24: OK (41)
+*** Test 25: OK (260177811)
+*** Test 26: OK (1681500476)
+*** Test 27: OK (1996459)
+*** Test 28: OK (1996459)
+*** Test 29: OK (170428555)
+*** Test 30: OK (190905173)
+*** Test 31: OK (190905173)
+*** Test 32: OK (354833067)
+--- Test 33: sum = 178275600 (ok)
+*** Test 33: OK (1216907538)
+*** Test 34: OK (2146584868)
+*** Test 35: OK (2146584868)
+*** Test 36: OK (1071644672)
+*** Test 37: OK (1071644672)
+*** Test 38: OK (357908480)
+*** Test 39: OK (357908480)
+*** Test 40: OK (357908480)
+*** Test 41: OK (3076095)
+*** Test 42: OK (1505155949)
+*** Test 43: OK (1157763329)
+*** Test 44: OK (1031761407)
+*** Test 45: OK (1157763329)
+*** Test 46: OK (739407)
+*** Test 47: OK (371213935)
+*** Test 48: OK (756255461)
+*** Test 49: OK (179000669)
+*** Test 50: OK (363550045)
+*** Test 51: OK (40744667)
+*** Test 52: OK (1247112011)
+*** Test 53: OK (131071)
+*** Test 54: OK (2047)
+*** Test 55: OK (1023)
+*** Test 56: OK (511)
+*** Test 57: OK (2147450880)
+*** Test 58: OK (624945)
+*** Test 59: OK (2038431743)
+*** Test 60: OK (311511339)
+*** Test 61: OK (374889517)
+*** Test 62: OK (286331153)
+*** Test 63: OK (236978127)
+*** Test 64: OK (1499645335)
+*** Test 65: OK (70187)
+*** Test 66: OK (5464)
+*** Test 67: OK (212514423)
+*** Test 68: OK (212514423)
+*** Test 69: OK (8995471)
+*** Test 70: OK (69544277)
+*** Test 71: OK (34886997)
+*** Test 72: OK (1789569365)
+*** Test 73: OK (9032615)
+*** Test 74: OK (224907669)
+*** Test 75: OK (2000403408)
+*** Test 76: OK (1610087935)
+*** Test 77: OK (1388671)
+*** Test 78: OK (134217728)
+*** Test 79: OK (70288929)
+*** Test 80: OK (17895765)
+*** Test 81: OK (387)
+*** Test 82: OK (8454401)
+*** Test 83: OK (2835)
+*** Test 84: OK (934782101)
+*** Test 85: OK (198689)
+--- Test 86: No Crash for vimgrep on BufUnload
+*** Test 86: OK (0)
+--- Test 87: 3
+--- Test 87: 5
+--- Test 87: abcdefghijk
+--- Test 87: Successfully executed funcref Add2
+*** Test 87: OK (0)
+--- Test 88: All tests were run with throwing exceptions on error.
+ The $VIMNOERRTHROW control is not configured.
+--- Test 88: All tests were run with throwing exceptions on interrupt.
+ The $VIMNOINTTHROW control is not configured.
+*** Test 88: OK (50443995)
diff --git a/src/testdir/test49.vim b/src/testdir/test49.vim
new file mode 100644
index 0000000000..eaf0cba00b
--- /dev/null
+++ b/src/testdir/test49.vim
@@ -0,0 +1,9852 @@
+" Vim script language tests
+" Author: Servatius Brandt <Servatius.Brandt@fujitsu-siemens.com>
+" Last Change: 2013 Jun 06
+
+"-------------------------------------------------------------------------------
+" Test environment {{{1
+"-------------------------------------------------------------------------------
+
+
+" Adding new tests easily. {{{2
+"
+" Writing new tests is eased considerably with the following functions and
+" abbreviations (see "Commands for recording the execution path", "Automatic
+" argument generation").
+"
+" To get the abbreviations, execute the command
+"
+" :let test49_set_env = 1 | source test49.vim
+"
+" To get them always (from src/testdir), put a line
+"
+" au! BufRead test49.vim let test49_set_env = 1 | source test49.vim
+"
+" into the local .vimrc file in the src/testdir directory.
+"
+if exists("test49_set_env") && test49_set_env
+
+ " Automatic argument generation for the test environment commands.
+
+ function! Xsum()
+ let addend = substitute(getline("."), '^.*"\s*X:\s*\|^.*', '', "")
+ " Evaluate arithmetic expression.
+ if addend != ""
+ exec "let g:Xsum = g:Xsum + " . addend
+ endif
+ endfunction
+
+ function! Xcheck()
+ let g:Xsum=0
+ ?XpathINIT?,.call Xsum()
+ exec "norm A "
+ return g:Xsum
+ endfunction
+
+ iab Xcheck Xcheck<Space><C-R>=Xcheck()<CR><C-O>x
+
+ function! Xcomment(num)
+ let str = ""
+ let tabwidth = &sts ? &sts : &ts
+ let tabs = (48+tabwidth - a:num - virtcol(".")) / tabwidth
+ while tabs > 0
+ let str = str . "\t"
+ let tabs = tabs - 1
+ endwhile
+ let str = str . '" X:'
+ return str
+ endfunction
+
+ function! Xloop()
+ let back = line(".") . "|norm" . virtcol(".") . "|"
+ norm 0
+ let last = search('X\(loop\|path\)INIT\|Xloop\>', "bW")
+ exec back
+ let theline = getline(last)
+ if theline =~ 'X\(loop\|path\)INIT'
+ let num = 1
+ else
+ let num = 2 * substitute(theline, '.*Xloop\s*\(\d\+\).*', '\1', "")
+ endif
+ ?X\(loop\|path\)INIT?
+ \s/\(XloopINIT!\=\s*\d\+\s\+\)\@<=\(\d\+\)/\=2*submatch(2)/
+ exec back
+ exec "norm a "
+ return num . Xcomment(strlen(num))
+ endfunction
+
+ iab Xloop Xloop<Space><C-R>=Xloop()<CR><C-O>x
+
+ function! Xpath(loopinit)
+ let back = line(".") . "|norm" . virtcol(".") . "|"
+ norm 0
+ let last = search('XpathINIT\|Xpath\>\|XloopINIT', "bW")
+ exec back
+ let theline = getline(last)
+ if theline =~ 'XpathINIT'
+ let num = 1
+ elseif theline =~ 'Xpath\>'
+ let num = 2 * substitute(theline, '.*Xpath\s*\(\d\+\).*', '\1', "")
+ else
+ let pattern = '.*XloopINIT!\=\s*\(\d\+\)\s*\(\d\+\).*'
+ let num = substitute(theline, pattern, '\1', "")
+ let factor = substitute(theline, pattern, '\2', "")
+ " The "<C-O>x" from the "Xpath" iab and the character triggering its
+ " expansion are in the input buffer. Save and clear typeahead so
+ " that it is not read away by the call to "input()" below. Restore
+ " afterwards.
+ call inputsave()
+ let loops = input("Number of iterations in previous loop? ")
+ call inputrestore()
+ while (loops > 0)
+ let num = num * factor
+ let loops = loops - 1
+ endwhile
+ endif
+ exec "norm a "
+ if a:loopinit
+ return num . " 1"
+ endif
+ return num . Xcomment(strlen(num))
+ endfunction
+
+ iab Xpath Xpath<Space><C-R>=Xpath(0)<CR><C-O>x
+ iab XloopINIT XloopINIT<Space><C-R>=Xpath(1)<CR><C-O>x
+
+ " Also useful (see ExtraVim below):
+ aug ExtraVim
+ au!
+ au BufEnter <sfile> syn region ExtraVim
+ \ start=+^if\s\+ExtraVim(.*)+ end=+^endif+
+ \ transparent keepend
+ au BufEnter <sfile> syn match ExtraComment /^"/
+ \ contained containedin=ExtraVim
+ au BufEnter <sfile> hi link ExtraComment vimComment
+ aug END
+
+ aug Xpath
+ au BufEnter <sfile> syn keyword Xpath
+ \ XpathINIT Xpath XloopINIT Xloop XloopNEXT Xcheck Xout
+ au BufEnter <sfile> hi link Xpath Special
+ aug END
+
+ do BufEnter <sfile>
+
+ " Do not execute the tests when sourcing this file for getting the functions
+ " and abbreviations above, which are intended for easily adding new test
+ " cases; they are not needed for test execution. Unlet the variable
+ " controlling this so that an explicit ":source" command for this file will
+ " execute the tests.
+ unlet test49_set_env
+ finish
+
+endif
+
+
+" Commands for recording the execution path. {{{2
+"
+" The Xpath/Xloop commands can be used for computing the eXecution path by
+" adding (different) powers of 2 from those script lines, for which the
+" execution should be checked. Xloop provides different addends for each
+" execution of a loop. Permitted values are 2^0 to 2^30, so that 31 execution
+" points (multiply counted inside loops) can be tested.
+"
+" Note that the arguments of the following commands can be generated
+" automatically, see below.
+"
+" Usage: {{{3
+"
+" - Use XpathINIT at the beginning of the test.
+"
+" - Use Xpath to check if a line is executed.
+" Argument: power of 2 (decimal).
+"
+" - To check multiple execution of loops use Xloop for automatically
+" computing Xpath values:
+"
+" - Use XloopINIT before the loop.
+" Two arguments:
+" - the first Xpath value (power of 2) to be used (Xnext),
+" - factor for computing a new Xnext value when reexecuting a loop
+" (by a ":continue" or ":endwhile"); this should be 2^n where
+" n is the number of Xloop commands inside the loop.
+" If XloopINIT! is used, the first execution of XloopNEXT is
+" a no-operation.
+"
+" - Use Xloop inside the loop:
+" One argument:
+" The argument and the Xnext value are multiplied to build the
+" next Xpath value. No new Xnext value is prepared. The argument
+" should be 2^(n-1) for the nth Xloop command inside the loop.
+" If the loop has only one Xloop command, the argument can be
+" ommitted (default: 1).
+"
+" - Use XloopNEXT before ":continue" and ":endwhile". This computes a new
+" Xnext value for the next execution of the loop by multiplying the old
+" one with the factor specified in the XloopINIT command. No Argument.
+" Alternatively, when XloopINIT! is used, a single XloopNEXT at the
+" beginning of the loop can be used.
+"
+" Nested loops are not supported.
+"
+" - Use Xcheck at end of each test. It prints the test number, the expected
+" execution path value, the test result ("OK" or "FAIL"), and, if the tests
+" fails, the actual execution path.
+" One argument:
+" Expected Xpath/Xloop sum for the correct execution path.
+" In order that this value can be computed automatically, do the
+" following: For each line in the test with an Xpath and Xloop
+" command, add a comment starting with "X:" and specifying an
+" expression that evaluates to the value contributed by this line to
+" the correct execution path. (For copying an Xpath argument of at
+" least two digits into the comment, press <C-P>.) At the end of the
+" test, just type "Xcheck" and press <Esc>.
+"
+" - In order to add additional information to the test output file, use the
+" Xout command. Argument(s) like ":echo".
+"
+" Automatic argument generation: {{{3
+"
+" The arguments of the Xpath, XloopINIT, Xloop, and Xcheck commands can be
+" generated automatically, so that new tests can easily be written without
+" mental arithmetic. The Xcheck argument is computed from the "X:" comments
+" of the preceding Xpath and Xloop commands. See the commands and
+" abbreviations at the beginning of this file.
+"
+" Implementation: {{{3
+" XpathINIT, Xpath, XloopINIT, Xloop, XloopNEXT, Xcheck, Xout.
+"
+" The variants for existing g:ExtraVimResult are needed when executing a script
+" in an extra Vim process, see ExtraVim below.
+
+" EXTRA_VIM_START - do not change or remove this line.
+
+com! XpathINIT let g:Xpath = 0
+
+if exists("g:ExtraVimResult")
+ com! -count -bar Xpath exec "!echo <count> >>" . g:ExtraVimResult
+else
+ com! -count -bar Xpath let g:Xpath = g:Xpath + <count>
+endif
+
+com! -count -nargs=1 -bang
+ \ XloopINIT let g:Xnext = <count> |
+ \ let g:Xfactor = <args> |
+ \ let g:Xskip = strlen("<bang>")
+
+if exists("g:ExtraVimResult")
+ com! -count=1 -bar Xloop exec "!echo " . (g:Xnext * <count>) . " >>" .
+ \ g:ExtraVimResult
+else
+ com! -count=1 -bar Xloop let g:Xpath = g:Xpath + g:Xnext * <count>
+endif
+
+com! XloopNEXT let g:Xnext = g:Xnext *
+ \ (g:Xskip ? 1 : g:Xfactor) |
+ \ let g:Xskip = 0
+
+let @r = ""
+let Xtest = 1
+com! -count Xcheck let Xresult = "*** Test " .
+ \ (Xtest<10?" ":Xtest<100?" ":"") .
+ \ Xtest . ": " . (
+ \ (Xpath==<count>) ? "OK (".Xpath.")" :
+ \ "FAIL (".Xpath." instead of <count>)"
+ \ ) |
+ \ let @R = Xresult . "\n" |
+ \ echo Xresult |
+ \ let Xtest = Xtest + 1
+
+if exists("g:ExtraVimResult")
+ com! -nargs=+ Xoutq exec "!echo @R:'" .
+ \ substitute(substitute(<q-args>,
+ \ "'", '&\\&&', "g"), "\n", "@NL@", "g")
+ \ . "' >>" . g:ExtraVimResult
+else
+ com! -nargs=+ Xoutq let @R = "--- Test " .
+ \ (g:Xtest<10?" ":g:Xtest<100?" ":"") .
+ \ g:Xtest . ": " . substitute(<q-args>,
+ \ "\n", "&\t ", "g") . "\n"
+endif
+com! -nargs=+ Xout exec 'Xoutq' <args>
+
+" Switch off storing of lines for undoing changes. Speeds things up a little.
+set undolevels=-1
+
+" EXTRA_VIM_STOP - do not change or remove this line.
+
+
+" ExtraVim() - Run a script file in an extra Vim process. {{{2
+"
+" This is useful for testing immediate abortion of the script processing due to
+" an error in a command dynamically enclosed by a :try/:tryend region or when an
+" exception is thrown but not caught or when an interrupt occurs. It can also
+" be used for testing :finish.
+"
+" An interrupt location can be specified by an "INTERRUPT" comment. A number
+" telling how often this location is reached (in a loop or in several function
+" calls) should be specified as argument. When missing, once per script
+" invocation or function call is assumed. INTERRUPT locations are tested by
+" setting a breakpoint in that line and using the ">quit" debug command when
+" the breakpoint is reached. A function for which an INTERRUPT location is
+" specified must be defined before calling it (or executing it as a script by
+" using ExecAsScript below).
+"
+" This function is only called in normal modus ("g:ExtraVimResult" undefined).
+"
+" Tests to be executed as an extra script should be written as follows:
+"
+" column 1 column 1
+" | |
+" v v
+"
+" XpathINIT XpathINIT
+" if ExtraVim() if ExtraVim()
+" ... " ...
+" ... " ...
+" endif endif
+" Xcheck <number> Xcheck <number>
+"
+" Double quotes in column 1 are removed before the script is executed.
+" They should be used if the test has unbalanced conditionals (:if/:endif,
+" :while:/endwhile, :try/:endtry) or for a line with a syntax error. The
+" extra script may use Xpath, XloopINIT, Xloop, XloopNEXT, and Xout as usual.
+"
+" A file name may be specified as argument. All messages of the extra Vim
+" process are then redirected to the file. An existing file is overwritten.
+"
+let ExtraVimCount = 0
+let ExtraVimBase = expand("<sfile>")
+let ExtraVimTestEnv = ""
+"
+function! ExtraVim(...)
+ " Count how often this function is called.
+ let g:ExtraVimCount = g:ExtraVimCount + 1
+
+ " Disable folds to prevent that the ranges in the ":write" commands below
+ " are extended up to the end of a closed fold. This also speeds things up
+ " considerably.
+ set nofoldenable
+
+ " Open a buffer for this test script and copy the test environment to
+ " a temporary file. Take account of parts relevant for the extra script
+ " execution only.
+ let current_buffnr = bufnr("%")
+ execute "view +1" g:ExtraVimBase
+ if g:ExtraVimCount == 1
+ let g:ExtraVimTestEnv = tempname()
+ execute "/E" . "XTRA_VIM_START/+,/E" . "XTRA_VIM_STOP/-w"
+ \ g:ExtraVimTestEnv "|']+"
+ execute "/E" . "XTRA_VIM_START/+,/E" . "XTRA_VIM_STOP/-w >>"
+ \ g:ExtraVimTestEnv "|']+"
+ execute "/E" . "XTRA_VIM_START/+,/E" . "XTRA_VIM_STOP/-w >>"
+ \ g:ExtraVimTestEnv "|']+"
+ execute "/E" . "XTRA_VIM_START/+,/E" . "XTRA_VIM_STOP/-w >>"
+ \ g:ExtraVimTestEnv "|']+"
+ endif
+
+ " Start the extra Vim script with a ":source" command for the test
+ " environment. The source line number where the extra script will be
+ " appended, needs to be passed as variable "ExtraVimBegin" to the script.
+ let extra_script = tempname()
+ exec "!echo 'source " . g:ExtraVimTestEnv . "' >" . extra_script
+ let extra_begin = 1
+
+ " Starting behind the test environment, skip over the first g:ExtraVimCount
+ " occurrences of "if ExtraVim()" and copy the following lines up to the
+ " matching "endif" to the extra Vim script.
+ execute "/E" . "ND_OF_TEST_ENVIRONMENT/"
+ exec 'norm ' . g:ExtraVimCount . '/^\s*if\s\+ExtraVim(.*)/+' . "\n"
+ execute ".,/^endif/-write >>" . extra_script
+
+ " Open a buffer for the extra Vim script, delete all ^", and write the
+ " script if was actually modified.
+ execute "edit +" . (extra_begin + 1) extra_script
+ ,$s/^"//e
+ update
+
+ " Count the INTERRUPTs and build the breakpoint and quit commands.
+ let breakpoints = ""
+ let debug_quits = ""
+ let in_func = 0
+ exec extra_begin
+ while search(
+ \ '"\s*INTERRUPT\h\@!\|^\s*fu\%[nction]\>!\=\s*\%(\u\|s:\)\w*\s*(\|'
+ \ . '^\s*\\\|^\s*endf\%[unction]\>\|'
+ \ . '\%(^\s*fu\%[nction]!\=\s*\)\@<!\%(\u\|s:\)\w*\s*(\|'
+ \ . 'ExecAsScript\s\+\%(\u\|s:\)\w*',
+ \ "W") > 0
+ let theline = getline(".")
+ if theline =~ '^\s*fu'
+ " Function definition.
+ let in_func = 1
+ let func_start = line(".")
+ let func_name = substitute(theline,
+ \ '^\s*fu\%[nction]!\=\s*\(\%(\u\|s:\)\w*\).*', '\1', "")
+ elseif theline =~ '^\s*endf'
+ " End of function definition.
+ let in_func = 0
+ else
+ let finding = substitute(theline, '.*\(\%' . col(".") . 'c.*\)',
+ \ '\1', "")
+ if finding =~ '^"\s*INTERRUPT\h\@!'
+ " Interrupt comment. Compose as many quit commands as
+ " specified.
+ let cnt = substitute(finding,
+ \ '^"\s*INTERRUPT\s*\(\d*\).*$', '\1', "")
+ let quits = ""
+ while cnt > 0
+ " Use "\r" rather than "\n" to separate the quit commands.
+ " "\r" is not interpreted as command separator by the ":!"
+ " command below but works to separate commands in the
+ " external vim.
+ let quits = quits . "q\r"
+ let cnt = cnt - 1
+ endwhile
+ if in_func
+ " Add the function breakpoint and note the number of quits
+ " to be used, if specified, or one for every call else.
+ let breakpoints = breakpoints . " -c 'breakadd func " .
+ \ (line(".") - func_start) . " " .
+ \ func_name . "'"
+ if quits != ""
+ let debug_quits = debug_quits . quits
+ elseif !exists("quits{func_name}")
+ let quits{func_name} = "q\r"
+ else
+ let quits{func_name} = quits{func_name} . "q\r"
+ endif
+ else
+ " Add the file breakpoint and the quits to be used for it.
+ let breakpoints = breakpoints . " -c 'breakadd file " .
+ \ line(".") . " " . extra_script . "'"
+ if quits == ""
+ let quits = "q\r"
+ endif
+ let debug_quits = debug_quits . quits
+ endif
+ else
+ " Add the quits to be used for calling the function or executing
+ " it as script file.
+ if finding =~ '^ExecAsScript'
+ " Sourcing function as script.
+ let finding = substitute(finding,
+ \ '^ExecAsScript\s\+\(\%(\u\|s:\)\w*\).*', '\1', "")
+ else
+ " Function call.
+ let finding = substitute(finding,
+ \ '^\(\%(\u\|s:\)\w*\).*', '\1', "")
+ endif
+ if exists("quits{finding}")
+ let debug_quits = debug_quits . quits{finding}
+ endif
+ endif
+ endif
+ endwhile
+
+ " Close the buffer for the script and create an (empty) resultfile.
+ bwipeout
+ let resultfile = tempname()
+ exec "!>" . resultfile
+
+ " Run the script in an extra vim. Switch to extra modus by passing the
+ " resultfile in ExtraVimResult. Redirect messages to the file specified as
+ " argument if any. Use ":debuggreedy" so that the commands provided on the
+ " pipe are consumed at the debug prompt. Use "-N" to enable command-line
+ " continuation ("C" in 'cpo'). Add "nviminfo" to 'viminfo' to avoid
+ " 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/src/vim -u NONE -N -Xes" . redirect .
+ \ " -c 'debuggreedy|set viminfo+=nviminfo'" .
+ \ " -c 'let ExtraVimBegin = " . extra_begin . "'" .
+ \ " -c 'let ExtraVimResult = \"" . resultfile . "\"'" . breakpoints .
+ \ " -S " . extra_script
+
+ " Build the resulting sum for resultfile and add it to g:Xpath. Add Xout
+ " information provided by the extra Vim process to the test output.
+ let sum = 0
+ exec "edit" resultfile
+ let line = 1
+ while line <= line("$")
+ let theline = getline(line)
+ if theline =~ '^@R:'
+ exec 'Xout "' . substitute(substitute(
+ \ escape(escape(theline, '"'), '\"'),
+ \ '^@R:', '', ""), '@NL@', "\n", "g") . '"'
+ else
+ let sum = sum + getline(line)
+ endif
+ let line = line + 1
+ endwhile
+ bwipeout
+ let g:Xpath = g:Xpath + sum
+
+ " Delete the extra script and the resultfile.
+ call delete(extra_script)
+ call delete(resultfile)
+
+ " Switch back to the buffer that was active when this function was entered.
+ exec "buffer" current_buffnr
+
+ " Return 0. This protects extra scripts from being run in the main Vim
+ " process.
+ return 0
+endfunction
+
+
+" ExtraVimThrowpoint() - Relative throwpoint in ExtraVim script {{{2
+"
+" Evaluates v:throwpoint and returns the throwpoint relative to the beginning of
+" an ExtraVim script as passed by ExtraVim() in ExtraVimBegin.
+"
+" EXTRA_VIM_START - do not change or remove this line.
+function! ExtraVimThrowpoint()
+ if !exists("g:ExtraVimBegin")
+ Xout "ExtraVimThrowpoint() used outside ExtraVim() script."
+ return v:throwpoint
+ endif
+
+ if v:throwpoint =~ '^function\>'
+ return v:throwpoint
+ endif
+
+ return "line " .
+ \ (substitute(v:throwpoint, '.*, line ', '', "") - g:ExtraVimBegin) .
+ \ " of ExtraVim() script"
+endfunction
+" EXTRA_VIM_STOP - do not change or remove this line.
+
+
+" MakeScript() - Make a script file from a function. {{{2
+"
+" Create a script that consists of the body of the function a:funcname.
+" Replace any ":return" by a ":finish", any argument variable by a global
+" variable, and and every ":call" by a ":source" for the next following argument
+" in the variable argument list. This function is useful if similar tests are
+" to be made for a ":return" from a function call or a ":finish" in a script
+" file.
+"
+" In order to execute a function specifying an INTERRUPT location (see ExtraVim)
+" as a script file, use ExecAsScript below.
+"
+" EXTRA_VIM_START - do not change or remove this line.
+function! MakeScript(funcname, ...)
+ let script = tempname()
+ execute "redir! >" . script
+ execute "function" a:funcname
+ redir END
+ execute "edit" script
+ " Delete the "function" and the "endfunction" lines. Do not include the
+ " word "function" in the pattern since it might be translated if LANG is
+ " set. When MakeScript() is being debugged, this deletes also the debugging
+ " output of its line 3 and 4.
+ exec '1,/.*' . a:funcname . '(.*)/d'
+ /^\d*\s*endfunction\>/,$d
+ %s/^\d*//e
+ %s/return/finish/e
+ %s/\<a:\(\h\w*\)/g:\1/ge
+ normal gg0
+ let cnt = 0
+ while search('\<call\s*\%(\u\|s:\)\w*\s*(.*)', 'W') > 0
+ let cnt = cnt + 1
+ s/\<call\s*\%(\u\|s:\)\w*\s*(.*)/\='source ' . a:{cnt}/
+ endwhile
+ g/^\s*$/d
+ write
+ bwipeout
+ return script
+endfunction
+" EXTRA_VIM_STOP - do not change or remove this line.
+
+
+" 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.
+"
+" When inside ":if ExtraVim()", add a file breakpoint for each INTERRUPT
+" location specified in the function.
+"
+" EXTRA_VIM_START - do not change or remove this line.
+function! ExecAsScript(funcname)
+ " Make a script from the function passed as argument.
+ let script = MakeScript(a:funcname)
+
+ " When running in an extra Vim process, add a file breakpoint for each
+ " function breakpoint set when the extra Vim process was invoked by
+ " ExtraVim().
+ if exists("g:ExtraVimResult")
+ let bplist = tempname()
+ execute "redir! >" . bplist
+ breaklist
+ redir END
+ execute "edit" bplist
+ " Get the line number from the function breakpoint. Works also when
+ " LANG is set.
+ execute 'v/^\s*\d\+\s\+func\s\+' . a:funcname . '\s.*/d'
+ %s/^\s*\d\+\s\+func\s\+\%(\u\|s:\)\w*\s\D*\(\d*\).*/\1/e
+ let cnt = 0
+ while cnt < line("$")
+ let cnt = cnt + 1
+ if getline(cnt) != ""
+ execute "breakadd file" getline(cnt) script
+ endif
+ endwhile
+ bwipeout!
+ call delete(bplist)
+ endif
+
+ " Source and delete the script.
+ exec "source" script
+ call delete(script)
+endfunction
+
+com! -nargs=1 -bar ExecAsScript call ExecAsScript(<f-args>)
+" EXTRA_VIM_STOP - do not change or remove this line.
+
+
+" END_OF_TEST_ENVIRONMENT - do not change or remove this line.
+
+
+"-------------------------------------------------------------------------------
+" Test 1: :endwhile in function {{{1
+"
+" Detect if a broken loop is (incorrectly) reactivated by the
+" :endwhile. Use a :return to prevent an endless loop, and make
+" this test first to get a meaningful result on an error before other
+" tests will hang.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+function! F()
+ Xpath 1 " X: 1
+ let first = 1
+ XloopINIT 2 8
+ while 1
+ Xloop 1 " X: 2 + 0 * 16
+ if first
+ Xloop 2 " X: 4 + 0 * 32
+ let first = 0
+ XloopNEXT
+ break
+ else
+ Xloop 4 " X: 0 + 0 * 64
+ return
+ endif
+ endwhile
+endfunction
+
+call F()
+Xpath 128 " X: 128
+
+function! G()
+ Xpath 256 " X: 256 + 0 * 2048
+ let first = 1
+ XloopINIT 512 8
+ while 1
+ Xloop 1 " X: 512 + 0 * 4096
+ if first
+ Xloop 2 " X: 1024 + 0 * 8192
+ let first = 0
+ XloopNEXT
+ break
+ else
+ Xloop 4 " X: 0 + 0 * 16384
+ return
+ endif
+ if 1 " unmatched :if
+ endwhile
+endfunction
+
+call G()
+Xpath 32768 " X: 32768
+
+Xcheck 34695
+
+" Leave F and G for execution as scripts in the next test.
+
+
+"-------------------------------------------------------------------------------
+" Test 2: :endwhile in script {{{1
+"
+" Detect if a broken loop is (incorrectly) reactivated by the
+" :endwhile. Use a :finish to prevent an endless loop, and place
+" this test before others that might hang to get a meaningful result
+" on an error.
+"
+" This test executes the bodies of the functions F and G from the
+" previous test as script files (:return replaced by :finish).
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+ExecAsScript F " X: 1 + 2 + 4
+Xpath 128 " X: 128
+
+ExecAsScript G " X: 256 + 512 + 1024
+Xpath 32768 " X: 32768
+
+unlet first
+delfunction F
+delfunction G
+
+Xcheck 34695
+
+
+"-------------------------------------------------------------------------------
+" Test 3: :if, :elseif, :while, :continue, :break {{{1
+"-------------------------------------------------------------------------------
+
+XpathINIT
+if 1
+ Xpath 1 " X: 1
+ let loops = 3
+ XloopINIT 2 512
+ while loops > -1 " main loop: loops == 3, 2, 1 (which breaks)
+ if loops <= 0
+ let break_err = 1
+ let loops = -1
+ else " 3: 2: 1:
+ Xloop 1 " X: 2 + 2*512 + 2*512*512
+ endif
+ if (loops == 2)
+ while loops == 2 " dummy loop
+ Xloop 2 " X: 4*512
+ let loops = loops - 1
+ continue " stop dummy loop
+ Xloop 4 " X: 0
+ endwhile
+ XloopNEXT
+ continue " continue main loop
+ Xloop 8 " X: 0
+ elseif (loops == 1)
+ let p = 1
+ while p " dummy loop
+ Xloop 16 " X: 32*512*512
+ let p = 0
+ break " break dummy loop
+ Xloop 32 " X: 0
+ endwhile
+ Xloop 64 " X: 128*512*512
+ unlet p
+ break " break main loop
+ Xloop 128 " X: 0
+ endif
+ if (loops > 0)
+ Xloop 256 " X: 512
+ endif
+ while loops == 3 " dummy loop
+ let loops = loops - 1
+ endwhile " end dummy loop
+ XloopNEXT
+ endwhile " end main loop
+ Xpath 268435456 " X: 1024*512*512
+else
+ Xpath 536870912 " X: 0
+endif
+Xpath 1073741824 " X: 4096*512*512
+if exists("break_err")
+ " The Xpath command does not accept 2^31 (negative); add explicitly:
+ let Xpath = Xpath + 2147483648 " X: 0
+ unlet break_err
+endif
+
+unlet loops
+
+Xcheck 1384648195
+
+
+"-------------------------------------------------------------------------------
+" Test 4: :return {{{1
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+function! F()
+ if 1
+ Xpath 1 " X: 1
+ let loops = 3
+ XloopINIT 2 16
+ while loops > 0 " 3: 2: 1:
+ Xloop 1 " X: 2 + 2*16 + 0*16*16
+ if (loops == 2)
+ Xloop 2 " X: 4*16
+ return
+ Xloop 4 " X: 0
+ endif
+ Xloop 8 " X: 16
+ let loops = loops - 1
+ XloopNEXT
+ endwhile
+ Xpath 8192 " X: 0
+ else
+ Xpath 16384 " X: 0
+ endif
+endfunction
+
+call F()
+Xpath 32768 " X: 8*16*16*16
+
+Xcheck 32883
+
+" Leave F for execution as a script in the next test.
+
+
+"-------------------------------------------------------------------------------
+" Test 5: :finish {{{1
+"
+" This test executes the body of the function F from the previous test
+" as a script file (:return replaced by :finish).
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+ExecAsScript F " X: 1 + 2 + 2*16 + 4*16 + 16
+Xpath 32768 " X: 32768
+
+unlet loops
+delfunction F
+
+Xcheck 32883
+
+
+"-------------------------------------------------------------------------------
+" Test 6: Defining functions in :while loops {{{1
+"
+" Functions can be defined inside other functions. An inner function
+" gets defined when the outer function is executed. Functions may
+" also be defined inside while loops. Expressions in braces for
+" defining the function name are allowed.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+if ExtraVim()
+
+ " The command CALL collects the argument of all its invocations in "calls"
+ " when used from a function (that is, when the global variable "calls" needs
+ " the "g:" prefix). This is to check that the function code is skipped when
+ " the function is defined. For inner functions, do so only if the outer
+ " function is not being executed.
+ "
+ let calls = ""
+ com! -nargs=1 CALL
+ \ if !exists("calls") && !exists("outer") |
+ \ let g:calls = g:calls . <args> |
+ \ endif
+
+
+ XloopINIT! 1 16
+
+ let i = 0
+ while i < 3
+
+ XloopNEXT
+ let i = i + 1
+
+ if i == 1
+ Xloop 1 " X: 1
+ function! F1(arg)
+ CALL a:arg
+ let outer = 1
+
+ XloopINIT! 4096 4
+ let j = 0
+ while j < 1
+ XloopNEXT
+ Xloop 1 " X: 4096
+ let j = j + 1
+ function! G1(arg)
+ CALL a:arg
+ endfunction
+ Xloop 2 " X: 8192
+ endwhile
+ endfunction
+ Xloop 2 " X: 2
+
+ continue
+ endif
+
+ Xloop 4 " X: 4 * (16 + 256)
+ function! F{i}(i, arg)
+ CALL a:arg
+ let outer = 1
+
+ XloopINIT! 16384 4
+ if a:i == 3
+ XloopNEXT
+ XloopNEXT
+ XloopNEXT
+ endif
+ let k = 0
+ while k < 3
+ XloopNEXT
+ Xloop 1 " X: 16384*(1+4+16+64+256+1024)
+ let k = k + 1
+ function! G{a:i}{k}(arg)
+ CALL a:arg
+ endfunction
+ Xloop 2 " X: 32768*(1+4+16+64+256+1024)
+ endwhile
+ endfunction
+ Xloop 8 " X: 8 * (16 + 256)
+
+ endwhile
+
+ if exists("*G1")
+ Xpath 67108864 " X: 0
+ endif
+ if exists("*F1")
+ call F1("F1")
+ if exists("*G1")
+ call G1("G1")
+ endif
+ endif
+
+ if exists("G21") || exists("G21") || exists("G21")
+ Xpath 134217728 " X: 0
+ endif
+ if exists("*F2")
+ call F2(2, "F2")
+ if exists("*G21")
+ call G21("G21")
+ endif
+ if exists("*G22")
+ call G22("G22")
+ endif
+ if exists("*G23")
+ call G23("G23")
+ endif
+ endif
+
+ if exists("G31") || exists("G31") || exists("G31")
+ Xpath 268435456 " X: 0
+ endif
+ if exists("*F3")
+ call F3(3, "F3")
+ if exists("*G31")
+ call G31("G31")
+ endif
+ if exists("*G32")
+ call G32("G32")
+ endif
+ if exists("*G33")
+ call G33("G33")
+ endif
+ endif
+
+ Xpath 536870912 " X: 536870912
+
+ if calls != "F1G1F2G21G22G23F3G31G32G33"
+ Xpath 1073741824 " X: 0
+ Xout "calls is" calls
+ endif
+
+ delfunction F1
+ delfunction G1
+ delfunction F2
+ delfunction G21
+ delfunction G22
+ delfunction G23
+ delfunction G31
+ delfunction G32
+ delfunction G33
+
+endif
+
+Xcheck 603978947
+
+
+"-------------------------------------------------------------------------------
+" Test 7: Continuing on errors outside functions {{{1
+"
+" On an error outside a function, the script processing continues
+" at the line following the outermost :endif or :endwhile. When not
+" inside an :if or :while, the script processing continues at the next
+" line.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+if 1
+ Xpath 1 " X: 1
+ while 1
+ Xpath 2 " X: 2
+ asdf
+ Xpath 4 " X: 0
+ break
+ endwhile | Xpath 8 " X: 0
+ Xpath 16 " X: 0
+endif | Xpath 32 " X: 0
+Xpath 64 " X: 64
+
+while 1
+ Xpath 128 " X: 128
+ if 1
+ Xpath 256 " X: 256
+ asdf
+ Xpath 512 " X: 0
+ endif | Xpath 1024 " X: 0
+ Xpath 2048 " X: 0
+ break
+endwhile | Xpath 4096 " X: 0
+Xpath 8192 " X: 8192
+
+asdf
+Xpath 16384 " X: 16384
+
+asdf | Xpath 32768 " X: 0
+Xpath 65536 " X: 65536
+
+Xcheck 90563
+
+
+"-------------------------------------------------------------------------------
+" Test 8: Aborting and continuing on errors inside functions {{{1
+"
+" On an error inside a function without the "abort" attribute, the
+" script processing continues at the next line (unless the error was
+" in a :return command). On an error inside a function with the
+" "abort" attribute, the function is aborted and the script processing
+" continues after the function call; the value -1 is returned then.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+function! F()
+ if 1
+ Xpath 1 " X: 1
+ while 1
+ Xpath 2 " X: 2
+ asdf
+ Xpath 4 " X: 4
+ asdf | Xpath 8 " X: 0
+ Xpath 16 " X: 16
+ break
+ endwhile
+ Xpath 32 " X: 32
+ endif | Xpath 64 " X: 64
+ Xpath 128 " X: 128
+
+ while 1
+ Xpath 256 " X: 256
+ if 1
+ Xpath 512 " X: 512
+ asdf
+ Xpath 1024 " X: 1024
+ asdf | Xpath 2048 " X: 0
+ Xpath 4096 " X: 4096
+ endif
+ Xpath 8192 " X: 8192
+ break
+ endwhile | Xpath 16384 " X: 16384
+ Xpath 32768 " X: 32768
+
+ return novar " returns (default return value 0)
+ Xpath 65536 " X: 0
+ return 1 " not reached
+endfunction
+
+function! G() abort
+ if 1
+ Xpath 131072 " X: 131072
+ while 1
+ Xpath 262144 " X: 262144
+ asdf " returns -1
+ Xpath 524288 " X: 0
+ break
+ endwhile
+ Xpath 1048576 " X: 0
+ endif | Xpath 2097152 " X: 0
+ Xpath Xpath 4194304 " X: 0
+
+ return -4 " not reached
+endfunction
+
+function! H() abort
+ while 1
+ Xpath 8388608 " X: 8388608
+ if 1
+ Xpath 16777216 " X: 16777216
+ asdf " returns -1
+ Xpath 33554432 " X: 0
+ endif
+ Xpath 67108864 " X: 0
+ break
+ endwhile | Xpath 134217728 " X: 0
+ Xpath 268435456 " X: 0
+
+ return -4 " not reached
+endfunction
+
+" Aborted functions (G and H) return -1.
+let sum = (F() + 1) - 4*G() - 8*H()
+Xpath 536870912 " X: 536870912
+if sum != 13
+ Xpath 1073741824 " X: 0
+ Xout "sum is" sum
+endif
+
+unlet sum
+delfunction F
+delfunction G
+delfunction H
+
+Xcheck 562493431
+
+
+"-------------------------------------------------------------------------------
+" Test 9: Continuing after aborted functions {{{1
+"
+" When a function with the "abort" attribute is aborted due to an
+" error, the next function back in the call hierarchy without an
+" "abort" attribute continues; the value -1 is returned then.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+function! F() abort
+ Xpath 1 " X: 1
+ let result = G() " not aborted
+ Xpath 2 " X: 2
+ if result != 2
+ Xpath 4 " X: 0
+ endif
+ return 1
+endfunction
+
+function! G() " no abort attribute
+ Xpath 8 " X: 8
+ if H() != -1 " aborted
+ Xpath 16 " X: 0
+ endif
+ Xpath 32 " X: 32
+ return 2
+endfunction
+
+function! H() abort
+ Xpath 64 " X: 64
+ call I() " aborted
+ Xpath 128 " X: 0
+ return 4
+endfunction
+
+function! I() abort
+ Xpath 256 " X: 256
+ asdf " error
+ Xpath 512 " X: 0
+ return 8
+endfunction
+
+if F() != 1
+ Xpath 1024 " X: 0
+endif
+
+delfunction F
+delfunction G
+delfunction H
+delfunction I
+
+Xcheck 363
+
+
+"-------------------------------------------------------------------------------
+" Test 10: :if, :elseif, :while argument parsing {{{1
+"
+" A '"' or '|' in an argument expression must not be mixed up with
+" a comment or a next command after a bar. Parsing errors should
+" be recognized.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+function! MSG(enr, emsg)
+ let english = v:lang == "C" || v:lang =~ '^[Ee]n'
+ if a:enr == ""
+ Xout "TODO: Add message number for:" a:emsg
+ let v:errmsg = ":" . v:errmsg
+ endif
+ let match = 1
+ if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg)
+ let match = 0
+ if v:errmsg == ""
+ Xout "Message missing."
+ else
+ let v:errmsg = escape(v:errmsg, '"')
+ Xout "Unexpected message:" v:errmsg
+ endif
+ endif
+ return match
+endfunction
+
+if 1 || strlen("\"") | Xpath 1 " X: 1
+ Xpath 2 " X: 2
+endif
+Xpath 4 " X: 4
+
+if 0
+elseif 1 || strlen("\"") | Xpath 8 " X: 8
+ Xpath 16 " X: 16
+endif
+Xpath 32 " X: 32
+
+while 1 || strlen("\"") | Xpath 64 " X: 64
+ Xpath 128 " X: 128
+ break
+endwhile
+Xpath 256 " X: 256
+
+let v:errmsg = ""
+if 1 ||| strlen("\"") | Xpath 512 " X: 0
+ Xpath 1024 " X: 0
+endif
+Xpath 2048 " X: 2048
+if !MSG('E15', "Invalid expression")
+ Xpath 4096 " X: 0
+endif
+
+let v:errmsg = ""
+if 0
+elseif 1 ||| strlen("\"") | Xpath 8192 " X: 0
+ Xpath 16384 " X: 0
+endif
+Xpath 32768 " X: 32768
+if !MSG('E15', "Invalid expression")
+ Xpath 65536 " X: 0
+endif
+
+let v:errmsg = ""
+while 1 ||| strlen("\"") | Xpath 131072 " X: 0
+ Xpath 262144 " X: 0
+ break
+endwhile
+Xpath 524288 " X: 524288
+if !MSG('E15', "Invalid expression")
+ Xpath 1048576 " X: 0
+endif
+
+delfunction MSG
+
+Xcheck 559615
+
+
+"-------------------------------------------------------------------------------
+" Test 11: :if, :elseif, :while argument evaluation after abort {{{1
+"
+" When code is skipped over due to an error, the boolean argument to
+" an :if, :elseif, or :while must not be evaluated.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+let calls = 0
+
+function! P(num)
+ let g:calls = g:calls + a:num " side effect on call
+ return 0
+endfunction
+
+if 1
+ Xpath 1 " X: 1
+ asdf " error
+ Xpath 2 " X: 0
+ if P(1) " should not be called
+ Xpath 4 " X: 0
+ elseif !P(2) " should not be called
+ Xpath 8 " X: 0
+ else
+ Xpath 16 " X: 0
+ endif
+ Xpath 32 " X: 0
+ while P(4) " should not be called
+ Xpath 64 " X: 0
+ endwhile
+ Xpath 128 " X: 0
+endif
+
+if calls % 2
+ Xpath 256 " X: 0
+endif
+if (calls/2) % 2
+ Xpath 512 " X: 0
+endif
+if (calls/4) % 2
+ Xpath 1024 " X: 0
+endif
+Xpath 2048 " X: 2048
+
+unlet calls
+delfunction P
+
+Xcheck 2049
+
+
+"-------------------------------------------------------------------------------
+" Test 12: Expressions in braces in skipped code {{{1
+"
+" In code skipped over due to an error or inactive conditional,
+" an expression in braces as part of a variable or function name
+" should not be evaluated.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+XloopINIT 1 8
+
+function! NULL()
+ Xloop 1 " X: 0
+ return 0
+endfunction
+
+function! ZERO()
+ Xloop 2 " X: 0
+ return 0
+endfunction
+
+function! F0()
+ Xloop 4 " X: 0
+endfunction
+
+function! F1(arg)
+ Xpath 4096 " X: 0
+endfunction
+
+let V0 = 1
+
+Xpath 8192 " X: 8192
+echo 0 ? F{NULL() + V{ZERO()}}() : 1
+XloopNEXT
+
+Xpath 16384 " X: 16384
+if 0
+ Xpath 32768 " X: 0
+ call F{NULL() + V{ZERO()}}()
+endif
+XloopNEXT
+
+Xpath 65536 " X: 65536
+if 1
+ asdf " error
+ Xpath 131072 " X: 0
+ call F1(F{NULL() + V{ZERO()}}())
+endif
+XloopNEXT
+
+Xpath 262144 " X: 262144
+if 1
+ asdf " error
+ Xpath 524288 " X: 0
+ call F{NULL() + V{ZERO()}}()
+endif
+
+Xcheck 352256
+
+
+"-------------------------------------------------------------------------------
+" Test 13: Failure in argument evaluation for :while {{{1
+"
+" A failure in the expression evaluation for the condition of a :while
+" causes the whole :while loop until the matching :endwhile being
+" ignored. Continuation is at the next following line.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+Xpath 1 " X: 1
+while asdf
+ Xpath 2 " X: 0
+ while 1
+ Xpath 4 " X: 0
+ break
+ endwhile
+ Xpath 8 " X: 0
+ break
+endwhile
+Xpath 16 " X: 16
+
+while asdf | Xpath 32 | endwhile | Xpath 64 " X: 0
+Xpath 128 " X: 128
+
+Xcheck 145
+
+
+"-------------------------------------------------------------------------------
+" Test 14: Failure in argument evaluation for :if {{{1
+"
+" A failure in the expression evaluation for the condition of an :if
+" does not cause the corresponding :else or :endif being matched to
+" a previous :if/:elseif. Neither of both branches of the failed :if
+" are executed.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+XloopINIT 1 256
+
+function! F()
+ Xloop 1 " X: 1 + 256 * 1
+ let x = 0
+ if x " false
+ Xloop 2 " X: 0 + 256 * 0
+ elseif !x " always true
+ Xloop 4 " X: 4 + 256 * 4
+ let x = 1
+ if g:boolvar " possibly undefined
+ Xloop 8 " X: 8 + 256 * 0
+ else
+ Xloop 16 " X: 0 + 256 * 0
+ endif
+ Xloop 32 " X: 32 + 256 * 32
+ elseif x " never executed
+ Xloop 64 " X: 0 + 256 * 0
+ endif
+ Xloop 128 " X: 128 + 256 * 128
+endfunction
+
+let boolvar = 1
+call F()
+
+XloopNEXT
+unlet boolvar
+call F()
+
+delfunction F
+
+Xcheck 42413
+
+
+"-------------------------------------------------------------------------------
+" Test 15: Failure in argument evaluation for :if (bar) {{{1
+"
+" Like previous test, except that the failing :if ... | ... | :endif
+" is in a single line.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+XloopINIT 1 256
+
+function! F()
+ Xloop 1 " X: 1 + 256 * 1
+ let x = 0
+ if x " false
+ Xloop 2 " X: 0 + 256 * 0
+ elseif !x " always true
+ Xloop 4 " X: 4 + 256 * 4
+ let x = 1
+ if g:boolvar | Xloop 8 | else | Xloop 16 | endif " X: 8
+ Xloop 32 " X: 32 + 256 * 32
+ elseif x " never executed
+ Xloop 64 " X: 0 + 256 * 0
+ endif
+ Xloop 128 " X: 128 + 256 * 128
+endfunction
+
+let boolvar = 1
+call F()
+
+XloopNEXT
+unlet boolvar
+call F()
+
+delfunction F
+
+Xcheck 42413
+
+
+"-------------------------------------------------------------------------------
+" Test 16: Double :else or :elseif after :else {{{1
+"
+" Multiple :elses or an :elseif after an :else are forbidden.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+function! F() abort
+ if 0
+ Xpath 1 " X: 0
+ else
+ Xpath 2 " X: 2
+ else " aborts function
+ Xpath 4 " X: 0
+ endif
+endfunction
+
+function! G() abort
+ if 0
+ Xpath 8 " X: 0
+ else
+ Xpath 16 " X: 16
+ elseif 1 " aborts function
+ Xpath 32 " X: 0
+ else
+ Xpath 64 " X: 0
+ endif
+endfunction
+
+function! H() abort
+ if 0
+ Xpath 128 " X: 0
+ elseif 0
+ Xpath 256 " X: 0
+ else
+ Xpath 512 " X: 512
+ else " aborts function
+ Xpath 1024 " X: 0
+ endif
+endfunction
+
+function! I() abort
+ if 0
+ Xpath 2048 " X: 0
+ elseif 0
+ Xpath 4096 " X: 0
+ else
+ Xpath 8192 " X: 8192
+ elseif 1 " aborts function
+ Xpath 16384 " X: 0
+ else
+ Xpath 32768 " X: 0
+ endif
+endfunction
+
+call F()
+call G()
+call H()
+call I()
+
+delfunction F
+delfunction G
+delfunction H
+delfunction I
+
+Xcheck 8722
+
+
+"-------------------------------------------------------------------------------
+" Test 17: Nesting of unmatched :if or :endif inside a :while {{{1
+"
+" The :while/:endwhile takes precedence in nesting over an unclosed
+" :if or an unopened :endif.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+function! MSG(enr, emsg)
+ let english = v:lang == "C" || v:lang =~ '^[Ee]n'
+ if a:enr == ""
+ Xout "TODO: Add message number for:" a:emsg
+ let v:errmsg = ":" . v:errmsg
+ endif
+ let match = 1
+ if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg)
+ let match = 0
+ if v:errmsg == ""
+ Xout "Message missing."
+ else
+ let v:errmsg = escape(v:errmsg, '"')
+ Xout "Unexpected message:" v:errmsg
+ endif
+ endif
+ return match
+endfunction
+
+let messages = ""
+
+" While loops inside a function are continued on error.
+function! F()
+ let v:errmsg = ""
+ XloopINIT 1 16
+ let loops = 3
+ while loops > 0
+ let loops = loops - 1 " 2: 1: 0:
+ Xloop 1 " X: 1 + 1*16 + 1*16*16
+ if (loops == 1)
+ Xloop 2 " X: 2*16
+ XloopNEXT
+ continue
+ elseif (loops == 0)
+ Xloop 4 " X: 4*16*16
+ break
+ elseif 1
+ Xloop 8 " X: 8
+ XloopNEXT
+ " endif missing!
+ endwhile " :endwhile after :if 1
+ Xpath 4096 " X: 16*16*16
+ if MSG('E171', "Missing :endif")
+ let g:messages = g:messages . "A"
+ endif
+
+ let v:errmsg = ""
+ XloopINIT! 8192 4
+ let loops = 2
+ while loops > 0 " 2: 1:
+ XloopNEXT
+ let loops = loops - 1
+ Xloop 1 " X: 8192 + 8192*4
+ if 0
+ Xloop 2 " X: 0
+ " endif missing
+ endwhile " :endwhile after :if 0
+ Xpath 131072 " X: 8192*4*4
+ if MSG('E171', "Missing :endif")
+ let g:messages = g:messages . "B"
+ endif
+
+ let v:errmsg = ""
+ XloopINIT 262144 4
+ let loops = 2
+ while loops > 0 " 2: 1:
+ let loops = loops - 1
+ Xloop 1 " X: 262144 + 262144 * 4
+ " if missing!
+ endif " :endif without :if in while
+ Xloop 2 " X: 524288 + 524288 * 4
+ XloopNEXT
+ endwhile
+ Xpath 4194304 " X: 262144*4*4
+ if MSG('E580', ":endif without :if")
+ let g:messages = g:messages . "C"
+ endif
+endfunction
+
+call F()
+
+" Error continuation outside a function is at the outermost :endwhile or :endif.
+let v:errmsg = ""
+XloopINIT! 8388608 4
+let loops = 2
+while loops > 0 " 2: 1:
+ XloopNEXT
+ let loops = loops - 1
+ Xloop 1 " X: 8388608 + 0 * 4
+ if 0
+ Xloop 2 " X: 0
+ " endif missing! Following :endwhile fails.
+endwhile | Xpath 134217728 " X: 0
+Xpath 268435456 " X: 2*8388608*4*4
+if MSG('E171', "Missing :endif")
+ let messages = g:messages . "D"
+endif
+
+if messages != "ABCD"
+ Xpath 536870912 " X: 0
+ Xout "messages is" messages "instead of ABCD"
+endif
+
+unlet loops messages
+delfunction F
+delfunction MSG
+
+Xcheck 285127993
+
+
+"-------------------------------------------------------------------------------
+" Test 18: Interrupt (Ctrl-C pressed) {{{1
+"
+" On an interrupt, the script processing is terminated immediately.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+if ExtraVim()
+ if 1
+ Xpath 1 " X: 1
+ while 1
+ Xpath 2 " X: 2
+ if 1
+ Xpath 4 " X: 4
+ "INTERRUPT
+ Xpath 8 " X: 0
+ break
+ finish
+ endif | Xpath 16 " X: 0
+ Xpath 32 " X: 0
+ endwhile | Xpath 64 " X: 0
+ Xpath 128 " X: 0
+ endif | Xpath 256 " X: 0
+ Xpath 512 " X: 0
+endif
+
+if ExtraVim()
+ try
+ Xpath 1024 " X: 1024
+ "INTERRUPT
+ Xpath 2048 " X: 0
+ endtry | Xpath 4096 " X: 0
+ Xpath 8192 " X: 0
+endif
+
+if ExtraVim()
+ function! F()
+ if 1
+ Xpath 16384 " X: 16384
+ while 1
+ Xpath 32768 " X: 32768
+ if 1
+ Xpath 65536 " X: 65536
+ "INTERRUPT
+ Xpath 131072 " X: 0
+ break
+ return
+ endif | Xpath 262144 " X: 0
+ Xpath Xpath 524288 " X: 0
+ endwhile | Xpath 1048576 " X: 0
+ Xpath Xpath 2097152 " X: 0
+ endif | Xpath Xpath 4194304 " X: 0
+ Xpath Xpath 8388608 " X: 0
+ endfunction
+
+ call F() | Xpath 16777216 " X: 0
+ Xpath 33554432 " X: 0
+endif
+
+if ExtraVim()
+ function! G()
+ try
+ Xpath 67108864 " X: 67108864
+ "INTERRUPT
+ Xpath 134217728 " X: 0
+ endtry | Xpath 268435456 " X: 0
+ Xpath 536870912 " X: 0
+ endfunction
+
+ call G() | Xpath 1073741824 " X: 0
+ " The Xpath command does not accept 2^31 (negative); display explicitly:
+ exec "!echo 2147483648 >>" . g:ExtraVimResult
+ " X: 0
+endif
+
+Xcheck 67224583
+
+
+"-------------------------------------------------------------------------------
+" Test 19: Aborting on errors inside :try/:endtry {{{1
+"
+" An error in a command dynamically enclosed in a :try/:endtry region
+" aborts script processing immediately. It does not matter whether
+" the failing command is outside or inside a function and whether a
+" function has an "abort" attribute.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+if ExtraVim()
+ function! F() abort
+ Xpath 1 " X: 1
+ asdf
+ Xpath 2 " X: 0
+ endfunction
+
+ try
+ Xpath 4 " X: 4
+ call F()
+ Xpath 8 " X: 0
+ endtry | Xpath 16 " X: 0
+ Xpath 32 " X: 0
+endif
+
+if ExtraVim()
+ function! G()
+ Xpath 64 " X: 64
+ asdf
+ Xpath 128 " X: 0
+ endfunction
+
+ try
+ Xpath 256 " X: 256
+ call G()
+ Xpath 512 " X: 0
+ endtry | Xpath 1024 " X: 0
+ Xpath 2048 " X: 0
+endif
+
+if ExtraVim()
+ try
+ Xpath 4096 " X: 4096
+ asdf
+ Xpath 8192 " X: 0
+ endtry | Xpath 16384 " X: 0
+ Xpath 32768 " X: 0
+endif
+
+if ExtraVim()
+ if 1
+ try
+ Xpath 65536 " X: 65536
+ asdf
+ Xpath 131072 " X: 0
+ endtry | Xpath 262144 " X: 0
+ endif | Xpath 524288 " X: 0
+ Xpath 1048576 " X: 0
+endif
+
+if ExtraVim()
+ let p = 1
+ while p
+ let p = 0
+ try
+ Xpath 2097152 " X: 2097152
+ asdf
+ Xpath 4194304 " X: 0
+ endtry | Xpath 8388608 " X: 0
+ endwhile | Xpath 16777216 " X: 0
+ Xpath 33554432 " X: 0
+endif
+
+if ExtraVim()
+ let p = 1
+ while p
+ let p = 0
+" try
+ Xpath 67108864 " X: 67108864
+ endwhile | Xpath 134217728 " X: 0
+ Xpath 268435456 " X: 0
+endif
+
+Xcheck 69275973
+"-------------------------------------------------------------------------------
+" Test 20: Aborting on errors after :try/:endtry {{{1
+"
+" When an error occurs after the last active :try/:endtry region has
+" been left, termination behavior is as if no :try/:endtry has been
+" seen.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+if ExtraVim()
+ let p = 1
+ while p
+ let p = 0
+ try
+ Xpath 1 " X: 1
+ endtry
+ asdf
+ endwhile | Xpath 2 " X: 0
+ Xpath 4 " X: 4
+endif
+
+if ExtraVim()
+ while 1
+ try
+ Xpath 8 " X: 8
+ break
+ Xpath 16 " X: 0
+ endtry
+ endwhile
+ Xpath 32 " X: 32
+ asdf
+ Xpath 64 " X: 64
+endif
+
+if ExtraVim()
+ while 1
+ try
+ Xpath 128 " X: 128
+ break
+ Xpath 256 " X: 0
+ finally
+ Xpath 512 " X: 512
+ endtry
+ endwhile
+ Xpath 1024 " X: 1024
+ asdf
+ Xpath 2048 " X: 2048
+endif
+
+if ExtraVim()
+ while 1
+ try
+ Xpath 4096 " X: 4096
+ finally
+ Xpath 8192 " X: 8192
+ break
+ Xpath 16384 " X: 0
+ endtry
+ endwhile
+ Xpath 32768 " X: 32768
+ asdf
+ Xpath 65536 " X: 65536
+endif
+
+if ExtraVim()
+ let p = 1
+ while p
+ let p = 0
+ try
+ Xpath 131072 " X: 131072
+ continue
+ Xpath 262144 " X: 0
+ endtry
+ endwhile
+ Xpath 524288 " X: 524288
+ asdf
+ Xpath 1048576 " X: 1048576
+endif
+
+if ExtraVim()
+ let p = 1
+ while p
+ let p = 0
+ try
+ Xpath 2097152 " X: 2097152
+ continue
+ Xpath 4194304 " X: 0
+ finally
+ Xpath 8388608 " X: 8388608
+ endtry
+ endwhile
+ Xpath 16777216 " X: 16777216
+ asdf
+ Xpath 33554432 " X: 33554432
+endif
+
+if ExtraVim()
+ let p = 1
+ while p
+ let p = 0
+ try
+ Xpath 67108864 " X: 67108864
+ finally
+ Xpath 134217728 " X: 134217728
+ continue
+ Xpath 268435456 " X: 0
+ endtry
+ endwhile
+ Xpath 536870912 " X: 536870912
+ asdf
+ Xpath 1073741824 " X: 1073741824
+endif
+
+Xcheck 1874575085
+
+
+"-------------------------------------------------------------------------------
+" Test 21: :finally for :try after :continue/:break/:return/:finish {{{1
+"
+" If a :try conditional stays inactive due to a preceding :continue,
+" :break, :return, or :finish, its :finally clause should not be
+" executed.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+if ExtraVim()
+ function F()
+ let loops = 2
+ XloopINIT! 1 256
+ while loops > 0
+ XloopNEXT
+ let loops = loops - 1
+ try
+ if loops == 1
+ Xloop 1 " X: 1
+ continue
+ Xloop 2 " X: 0
+ elseif loops == 0
+ Xloop 4 " X: 4*256
+ break
+ Xloop 8 " X: 0
+ endif
+
+ try " inactive
+ Xloop 16 " X: 0
+ finally
+ Xloop 32 " X: 0
+ endtry
+ finally
+ Xloop 64 " X: 64 + 64*256
+ endtry
+ Xloop 128 " X: 0
+ endwhile
+
+ try
+ Xpath 65536 " X: 65536
+ return
+ Xpath 131072 " X: 0
+ try " inactive
+ Xpath 262144 " X: 0
+ finally
+ Xpath 524288 " X: 0
+ endtry
+ finally
+ Xpath 1048576 " X: 1048576
+ endtry
+ Xpath 2097152 " X: 0
+ endfunction
+
+ try
+ Xpath 4194304 " X: 4194304
+ call F()
+ Xpath 8388608 " X: 8388608
+ finish
+ Xpath 16777216 " X: 0
+ try " inactive
+ Xpath 33554432 " X: 0
+ finally
+ Xpath 67108864 " X: 0
+ endtry
+ finally
+ Xpath 134217728 " X: 134217728
+ endtry
+ Xpath 268435456 " X: 0
+endif
+
+Xcheck 147932225
+
+
+"-------------------------------------------------------------------------------
+" Test 22: :finally for a :try after an error/interrupt/:throw {{{1
+"
+" If a :try conditional stays inactive due to a preceding error or
+" interrupt or :throw, its :finally clause should not be executed.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+if ExtraVim()
+ function! Error()
+ try
+ asdf " aborting error, triggering error exception
+ endtry
+ endfunction
+
+ Xpath 1 " X: 1
+ call Error()
+ Xpath 2 " X: 0
+
+ if 1 " not active due to error
+ try " not active since :if inactive
+ Xpath 4 " X: 0
+ finally
+ Xpath 8 " X: 0
+ endtry
+ endif
+
+ try " not active due to error
+ Xpath 16 " X: 0
+ finally
+ Xpath 32 " X: 0
+ endtry
+endif
+
+if ExtraVim()
+ function! Interrupt()
+ try
+ "INTERRUPT " triggering interrupt exception
+ endtry
+ endfunction
+
+ Xpath 64 " X: 64
+ call Interrupt()
+ Xpath 128 " X: 0
+
+ if 1 " not active due to interrupt
+ try " not active since :if inactive
+ Xpath 256 " X: 0
+ finally
+ Xpath 512 " X: 0
+ endtry
+ endif
+
+ try " not active due to interrupt
+ Xpath 1024 " X: 0
+ finally
+ Xpath 2048 " X: 0
+ endtry
+endif
+
+if ExtraVim()
+ function! Throw()
+ throw "xyz"
+ endfunction
+
+ Xpath 4096 " X: 4096
+ call Throw()
+ Xpath 8192 " X: 0
+
+ if 1 " not active due to :throw
+ try " not active since :if inactive
+ Xpath 16384 " X: 0
+ finally
+ Xpath 32768 " X: 0
+ endtry
+ endif
+
+ try " not active due to :throw
+ Xpath 65536 " X: 0
+ finally
+ Xpath 131072 " X: 0
+ endtry
+endif
+
+Xcheck 4161
+
+
+"-------------------------------------------------------------------------------
+" Test 23: :catch clauses for a :try after a :throw {{{1
+"
+" If a :try conditional stays inactive due to a preceding :throw,
+" none of its :catch clauses should be executed.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+if ExtraVim()
+ try
+ Xpath 1 " X: 1
+ throw "xyz"
+ Xpath 2 " X: 0
+
+ if 1 " not active due to :throw
+ try " not active since :if inactive
+ Xpath 4 " X: 0
+ catch /xyz/
+ Xpath 8 " X: 0
+ endtry
+ endif
+ catch /xyz/
+ Xpath 16 " X: 16
+ endtry
+
+ Xpath 32 " X: 32
+ throw "abc"
+ Xpath 64 " X: 0
+
+ try " not active due to :throw
+ Xpath 128 " X: 0
+ catch /abc/
+ Xpath 256 " X: 0
+ endtry
+endif
+
+Xcheck 49
+
+
+"-------------------------------------------------------------------------------
+" Test 24: :endtry for a :try after a :throw {{{1
+"
+" If a :try conditional stays inactive due to a preceding :throw,
+" its :endtry should not rethrow the exception to the next surrounding
+" active :try conditional.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+if ExtraVim()
+ try " try 1
+ try " try 2
+ Xpath 1 " X: 1
+ throw "xyz" " makes try 2 inactive
+ Xpath 2 " X: 0
+
+ try " try 3
+ Xpath 4 " X: 0
+ endtry " no rethrow to try 1
+ catch /xyz/ " should catch although try 2 inactive
+ Xpath 8 " X: 8
+ endtry
+ catch /xyz/ " try 1 active, but exception already caught
+ Xpath 16 " X: 0
+ endtry
+ Xpath 32 " X: 32
+endif
+
+Xcheck 41
+
+
+"-------------------------------------------------------------------------------
+" Test 25: Executing :finally clauses on normal control flow {{{1
+"
+" Control flow in a :try conditional should always fall through to its
+" :finally clause. A :finally clause of a :try conditional inside an
+" inactive conditional should never be executed.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+function! F()
+ let loops = 3
+ XloopINIT 1 256
+ while loops > 0 " 3: 2: 1:
+ Xloop 1 " X: 1 + 1*256 + 1*256*256
+ if loops >= 2
+ try
+ Xloop 2 " X: 2 + 2*256
+ if loops == 2
+ try
+ Xloop 4 " X: 4*256
+ finally
+ Xloop 8 " X: 8*256
+ endtry
+ endif
+ finally
+ Xloop 16 " X: 16 + 16*256
+ if loops == 2
+ try
+ Xloop 32 " X: 32*256
+ finally
+ Xloop 64 " X: 64*256
+ endtry
+ endif
+ endtry
+ endif
+ Xloop 128 " X: 128 + 128*256 + 128*256*256
+ let loops = loops - 1
+ XloopNEXT
+ endwhile
+ Xpath 16777216 " X: 16777216
+endfunction
+
+if 1
+ try
+ Xpath 33554432 " X: 33554432
+ call F()
+ Xpath 67108864 " X: 67108864
+ finally
+ Xpath 134217728 " X: 134217728
+ endtry
+else
+ try
+ Xpath 268435456 " X: 0
+ finally
+ Xpath 536870912 " X: 0
+ endtry
+endif
+
+delfunction F
+
+Xcheck 260177811
+
+
+"-------------------------------------------------------------------------------
+" Test 26: Executing :finally clauses after :continue or :break {{{1
+"
+" For a :continue or :break dynamically enclosed in a :try/:endtry
+" region inside the next surrounding :while/:endwhile, if the
+" :continue/:break is before the :finally, the :finally clause is
+" executed first. If the :continue/:break is after the :finally, the
+" :finally clause is broken (like an :if/:endif region).
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+try
+ let loops = 3
+ XloopINIT! 1 32
+ while loops > 0
+ XloopNEXT
+ try
+ try
+ if loops == 2 " 3: 2: 1:
+ Xloop 1 " X: 1*32
+ let loops = loops - 1
+ continue
+ elseif loops == 1
+ Xloop 2 " X: 2*32*32
+ break
+ finish
+ endif
+ Xloop 4 " X: 4
+ endtry
+ finally
+ Xloop 8 " X: 8 + 8*32 + 8*32*32
+ endtry
+ Xloop 16 " X: 16
+ let loops = loops - 1
+ endwhile
+ Xpath 32768 " X: 32768
+finally
+ Xpath 65536 " X: 65536
+ let loops = 3
+ XloopINIT 131072 16
+ while loops > 0
+ try
+ finally
+ try
+ if loops == 2
+ Xloop 1 " X: 131072*16
+ let loops = loops - 1
+ XloopNEXT
+ continue
+ elseif loops == 1
+ Xloop 2 " X: 131072*2*16*16
+ break
+ finish
+ endif
+ endtry
+ Xloop 4 " X: 131072*4
+ endtry
+ Xloop 8 " X: 131072*8
+ let loops = loops - 1
+ XloopNEXT
+ endwhile
+ Xpath 536870912 " X: 536870912
+endtry
+Xpath 1073741824 " X: 1073741824
+
+unlet loops
+
+Xcheck 1681500476
+
+
+"-------------------------------------------------------------------------------
+" Test 27: Executing :finally clauses after :return {{{1
+"
+" For a :return command dynamically enclosed in a :try/:endtry region,
+" :finally clauses are executed and the called function is ended.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+function! F()
+ try
+ Xpath 1 " X: 1
+ try
+ Xpath 2 " X: 2
+ return
+ Xpath 4 " X: 0
+ finally
+ Xpath 8 " X: 8
+ endtry
+ Xpath 16 " X: 0
+ finally
+ Xpath 32 " X: 32
+ endtry
+ Xpath 64 " X: 0
+endfunction
+
+function! G()
+ try
+ Xpath 128 " X: 128
+ return
+ Xpath 256 " X: 0
+ finally
+ Xpath 512 " X: 512
+ call F()
+ Xpath 1024 " X: 1024
+ endtry
+ Xpath 2048 " X: 0
+endfunction
+
+function! H()
+ try
+ Xpath 4096 " X: 4096
+ call G()
+ Xpath 8192 " X: 8192
+ finally
+ Xpath 16384 " X: 16384
+ return
+ Xpath 32768 " X: 0
+ endtry
+ Xpath 65536 " X: 0
+endfunction
+
+try
+ Xpath 131072 " X: 131072
+ call H()
+ Xpath 262144 " X: 262144
+finally
+ Xpath 524288 " X: 524288
+endtry
+Xpath 1048576 " X: 1048576
+
+Xcheck 1996459
+
+" Leave F, G, and H for execution as scripts in the next test.
+
+
+"-------------------------------------------------------------------------------
+" Test 28: Executing :finally clauses after :finish {{{1
+"
+" For a :finish command dynamically enclosed in a :try/:endtry region,
+" :finally clauses are executed and the sourced file is finished.
+"
+" This test executes the bodies of the functions F, G, and H from the
+" previous test as script files (:return replaced by :finish).
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+let scriptF = MakeScript("F") " X: 1 + 2 + 8 + 32
+let scriptG = MakeScript("G", scriptF) " X: 128 + 512 + 1024
+let scriptH = MakeScript("H", scriptG) " X: 4096 + 8192 + 16384
+
+try
+ Xpath 131072 " X: 131072
+ exec "source" scriptH
+ Xpath 262144 " X: 262144
+finally
+ Xpath 524288 " X: 524288
+endtry
+Xpath 1048576 " X: 1048576
+
+call delete(scriptF)
+call delete(scriptG)
+call delete(scriptH)
+unlet scriptF scriptG scriptH
+delfunction F
+delfunction G
+delfunction H
+
+Xcheck 1996459
+
+
+"-------------------------------------------------------------------------------
+" Test 29: Executing :finally clauses on errors {{{1
+"
+" After an error in a command dynamically enclosed in a :try/:endtry
+" region, :finally clauses are executed and the script processing is
+" terminated.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+if ExtraVim()
+ function! F()
+ while 1
+ try
+ Xpath 1 " X: 1
+ while 1
+ try
+ Xpath 2 " X: 2
+ asdf " error
+ Xpath 4 " X: 0
+ finally
+ Xpath 8 " X: 8
+ endtry | Xpath 16 " X: 0
+ Xpath 32 " X: 0
+ break
+ endwhile
+ Xpath 64 " X: 0
+ finally
+ Xpath 128 " X: 128
+ endtry | Xpath 256 " X: 0
+ Xpath 512 " X: 0
+ break
+ endwhile
+ Xpath 1024 " X: 0
+ endfunction
+
+ while 1
+ try
+ Xpath 2048 " X: 2048
+ while 1
+ call F()
+ Xpath 4096 " X: 0
+ break
+ endwhile | Xpath 8192 " X: 0
+ Xpath 16384 " X: 0
+ finally
+ Xpath 32768 " X: 32768
+ endtry | Xpath 65536 " X: 0
+ endwhile | Xpath 131072 " X: 0
+ Xpath 262144 " X: 0
+endif
+
+if ExtraVim()
+ function! G() abort
+ if 1
+ try
+ Xpath 524288 " X: 524288
+ asdf " error
+ Xpath 1048576 " X: 0
+ finally
+ Xpath 2097152 " X: 2097152
+ endtry | Xpath 4194304 " X: 0
+ endif | Xpath 8388608 " X: 0
+ Xpath 16777216 " X: 0
+ endfunction
+
+ if 1
+ try
+ Xpath 33554432 " X: 33554432
+ call G()
+ Xpath 67108864 " X: 0
+ finally
+ Xpath 134217728 " X: 134217728
+ endtry | Xpath 268435456 " X: 0
+ endif | Xpath 536870912 " X: 0
+ Xpath 1073741824 " X: 0
+endif
+
+Xcheck 170428555
+
+
+"-------------------------------------------------------------------------------
+" Test 30: Executing :finally clauses on interrupt {{{1
+"
+" After an interrupt in a command dynamically enclosed in
+" a :try/:endtry region, :finally clauses are executed and the
+" script processing is terminated.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+if ExtraVim()
+ XloopINIT 1 16
+
+ function! F()
+ try
+ Xloop 1 " X: 1 + 1*16
+ "INTERRUPT
+ Xloop 2 " X: 0
+ finally
+ Xloop 4 " X: 4 + 4*16
+ endtry
+ Xloop 8 " X: 0
+ endfunction
+
+ try
+ Xpath 256 " X: 256
+ try
+ Xpath 512 " X: 512
+ "INTERRUPT
+ Xpath 1024 " X: 0
+ finally
+ Xpath 2048 " X: 2048
+ try
+ Xpath 4096 " X: 4096
+ try
+ Xpath 8192 " X: 8192
+ finally
+ Xpath 16384 " X: 16384
+ try
+ Xpath 32768 " X: 32768
+ "INTERRUPT
+ Xpath 65536 " X: 0
+ endtry
+ Xpath 131072 " X: 0
+ endtry
+ Xpath 262144 " X: 0
+ endtry
+ Xpath 524288 " X: 0
+ endtry
+ Xpath 1048576 " X: 0
+ finally
+ Xpath 2097152 " X: 2097152
+ try
+ Xpath 4194304 " X: 4194304
+ call F()
+ Xpath 8388608 " X: 0
+ finally
+ Xpath 16777216 " X: 16777216
+ try
+ Xpath 33554432 " X: 33554432
+ XloopNEXT
+ ExecAsScript F
+ Xpath 67108864 " X: 0
+ finally
+ Xpath 134217728 " X: 134217728
+ endtry
+ Xpath 268435456 " X: 0
+ endtry
+ Xpath 536870912 " X: 0
+ endtry
+ Xpath 1073741824 " X: 0
+endif
+
+Xcheck 190905173
+
+
+"-------------------------------------------------------------------------------
+" Test 31: Executing :finally clauses after :throw {{{1
+"
+" After a :throw dynamically enclosed in a :try/:endtry region,
+" :finally clauses are executed and the script processing is
+" terminated.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+if ExtraVim()
+ XloopINIT 1 16
+
+ function! F()
+ try
+ Xloop 1 " X: 1 + 1*16
+ throw "exception"
+ Xloop 2 " X: 0
+ finally
+ Xloop 4 " X: 4 + 4*16
+ endtry
+ Xloop 8 " X: 0
+ endfunction
+
+ try
+ Xpath 256 " X: 256
+ try
+ Xpath 512 " X: 512
+ throw "exception"
+ Xpath 1024 " X: 0
+ finally
+ Xpath 2048 " X: 2048
+ try
+ Xpath 4096 " X: 4096
+ try
+ Xpath 8192 " X: 8192
+ finally
+ Xpath 16384 " X: 16384
+ try
+ Xpath 32768 " X: 32768
+ throw "exception"
+ Xpath 65536 " X: 0
+ endtry
+ Xpath 131072 " X: 0
+ endtry
+ Xpath 262144 " X: 0
+ endtry
+ Xpath 524288 " X: 0
+ endtry
+ Xpath 1048576 " X: 0
+ finally
+ Xpath 2097152 " X: 2097152
+ try
+ Xpath 4194304 " X: 4194304
+ call F()
+ Xpath 8388608 " X: 0
+ finally
+ Xpath 16777216 " X: 16777216
+ try
+ Xpath 33554432 " X: 33554432
+ XloopNEXT
+ ExecAsScript F
+ Xpath 67108864 " X: 0
+ finally
+ Xpath 134217728 " X: 134217728
+ endtry
+ Xpath 268435456 " X: 0
+ endtry
+ Xpath 536870912 " X: 0
+ endtry
+ Xpath 1073741824 " X: 0
+endif
+
+Xcheck 190905173
+
+
+"-------------------------------------------------------------------------------
+" Test 32: Remembering the :return value on :finally {{{1
+"
+" If a :finally clause is executed due to a :return specifying
+" a value, this is the value visible to the caller if not overwritten
+" by a new :return in the :finally clause. A :return without a value
+" in the :finally clause overwrites with value 0.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+function! F()
+ try
+ Xpath 1 " X: 1
+ try
+ Xpath 2 " X: 2
+ return "ABCD"
+ Xpath 4 " X: 0
+ finally
+ Xpath 8 " X: 8
+ endtry
+ Xpath 16 " X: 0
+ finally
+ Xpath 32 " X: 32
+ endtry
+ Xpath 64 " X: 0
+endfunction
+
+function! G()
+ try
+ Xpath 128 " X: 128
+ return 8
+ Xpath 256 " X: 0
+ finally
+ Xpath 512 " X: 512
+ return 16 + strlen(F())
+ Xpath 1024 " X: 0
+ endtry
+ Xpath 2048 " X: 0
+endfunction
+
+function! H()
+ try
+ Xpath 4096 " X: 4096
+ return 32
+ Xpath 8192 " X: 0
+ finally
+ Xpath 16384 " X: 16384
+ return
+ Xpath 32768 " X: 0
+ endtry
+ Xpath 65536 " X: 0
+endfunction
+
+function! I()
+ try
+ Xpath 131072 " X: 131072
+ finally
+ Xpath 262144 " X: 262144
+ return G() + H() + 64
+ Xpath 524288 " X: 0
+ endtry
+ Xpath 1048576 " X: 0
+endfunction
+
+let retcode = I()
+Xpath 2097152 " X: 2097152
+
+if retcode < 0
+ Xpath 4194304 " X: 0
+endif
+if retcode % 4
+ Xpath 8388608 " X: 0
+endif
+if (retcode/4) % 2
+ Xpath 16777216 " X: 16777216
+endif
+if (retcode/8) % 2
+ Xpath 33554432 " X: 0
+endif
+if (retcode/16) % 2
+ Xpath 67108864 " X: 67108864
+endif
+if (retcode/32) % 2
+ Xpath 134217728 " X: 0
+endif
+if (retcode/64) % 2
+ Xpath 268435456 " X: 268435456
+endif
+if retcode/128
+ Xpath 536870912 " X: 0
+endif
+
+unlet retcode
+delfunction F
+delfunction G
+delfunction H
+delfunction I
+
+Xcheck 354833067
+
+
+"-------------------------------------------------------------------------------
+" Test 33: :return under :execute or user command and :finally {{{1
+"
+" A :return command may be executed under an ":execute" or from
+" a user command. Executing of :finally clauses and passing through
+" the return code works also then.
+"-------------------------------------------------------------------------------
+XpathINIT
+
+command! -nargs=? RETURN
+ \ try | return <args> | finally | return <args> * 2 | endtry
+
+function! F()
+ try
+ RETURN 8
+ Xpath 1 " X: 0
+ finally
+ Xpath 2 " X: 2
+ endtry
+ Xpath 4 " X: 0
+endfunction
+
+function! G()
+ try
+ RETURN 32
+ Xpath 8 " X: 0
+ finally
+ Xpath 16 " X: 16
+ RETURN 128
+ Xpath 32 " X: 0
+ endtry
+ Xpath 64 " X: 0
+endfunction
+
+function! H()
+ try
+ execute "try | return 512 | finally | return 1024 | endtry"
+ Xpath 128 " X: 0
+ finally
+ Xpath 256 " X: 256
+ endtry
+ Xpath 512 " X: 0
+endfunction
+
+function! I()
+ try
+ execute "try | return 2048 | finally | return 4096 | endtry"
+ Xpath 1024 " X: 0
+ finally
+ Xpath 2048 " X: 2048
+ execute "try | return 8192 | finally | return 16384 | endtry"
+ Xpath 4096 " X: 0
+ endtry
+ Xpath 8192 " X: 0
+endfunction
+
+function! J()
+ try
+ RETURN 32768
+ Xpath 16384 " X: 0
+ finally
+ Xpath 32768 " X: 32768
+ return
+ Xpath 65536 " X: 0
+ endtry
+ Xpath 131072 " X: 0
+endfunction
+
+function! K()
+ try
+ execute "try | return 131072 | finally | return 262144 | endtry"
+ Xpath 262144 " X: 0
+ finally
+ Xpath 524288 " X: 524288
+ execute "try | return 524288 | finally | return | endtry"
+ Xpath 1048576 " X: 0
+ endtry
+ Xpath 2097152 " X: 0
+endfunction
+
+function! L()
+ try
+ return
+ Xpath 4194304 " X: 0
+ finally
+ Xpath 8388608 " X: 8388608
+ RETURN 1048576
+ Xpath 16777216 " X: 0
+ endtry
+ Xpath 33554432 " X: 0
+endfunction
+
+function! M()
+ try
+ return
+ Xpath 67108864 " X: 0
+ finally
+ Xpath 134217728 " X: 134217728
+ execute "try | return 4194304 | finally | return 8388608 | endtry"
+ Xpath 268435456 " X: 0
+ endtry
+ Xpath 536870912 " X: 0
+endfunction
+
+function! N()
+ RETURN 16777216
+endfunction
+
+function! O()
+ execute "try | return 67108864 | finally | return 134217728 | endtry"
+endfunction
+
+let sum = F() + G() + H() + I() + J() + K() + L() + M()
+let expected = 16 + 256 + 1024 + 16384 + 0 + 0 + 2097152 + 8388608
+let sum = sum + N() + O()
+let expected = expected + 33554432 + 134217728
+
+if sum == expected
+ Xout "sum = " . sum . " (ok)"
+else
+ Xout "sum = " . sum . ", expected: " . expected
+endif
+
+Xpath 1073741824 " X: 1073741824
+
+if sum != expected
+ " The Xpath command does not accept 2^31 (negative); add explicitly:
+ let Xpath = Xpath + 2147483648 " X: 0
+endif
+
+unlet sum expected
+delfunction F
+delfunction G
+delfunction H
+delfunction I
+delfunction J
+delfunction K
+delfunction L
+delfunction M
+delfunction N
+delfunction O
+
+Xcheck 1216907538
+
+
+"-------------------------------------------------------------------------------
+" Test 34: :finally reason discarded by :continue {{{1
+"
+" When a :finally clause is executed due to a :continue, :break,
+" :return, :finish, error, interrupt or :throw, the jump reason is
+" discarded by a :continue in the finally clause.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+if ExtraVim()
+
+ XloopINIT! 1 8
+
+ function! C(jump)
+ XloopNEXT
+ let loop = 0
+ while loop < 2
+ let loop = loop + 1
+ if loop == 1
+ try
+ if a:jump == "continue"
+ continue
+ elseif a:jump == "break"
+ break
+ elseif a:jump == "return" || a:jump == "finish"
+ return
+ elseif a:jump == "error"
+ asdf
+ elseif a:jump == "interrupt"
+ "INTERRUPT
+ let dummy = 0
+ elseif a:jump == "throw"
+ throw "abc"
+ endif
+ finally
+ continue " discards jump that caused the :finally
+ Xloop 1 " X: 0
+ endtry
+ Xloop 2 " X: 0
+ elseif loop == 2
+ Xloop 4 " X: 4*(1+8+64+512+4096+32768+262144)
+ endif
+ endwhile
+ endfunction
+
+ call C("continue")
+ Xpath 2097152 " X: 2097152
+ call C("break")
+ Xpath 4194304 " X: 4194304
+ call C("return")
+ Xpath 8388608 " X: 8388608
+ let g:jump = "finish"
+ ExecAsScript C
+ unlet g:jump
+ Xpath 16777216 " X: 16777216
+ try
+ call C("error")
+ Xpath 33554432 " X: 33554432
+ finally
+ Xpath 67108864 " X: 67108864
+ try
+ call C("interrupt")
+ Xpath 134217728 " X: 134217728
+ finally
+ Xpath 268435456 " X: 268435456
+ call C("throw")
+ Xpath 536870912 " X: 536870912
+ endtry
+ endtry
+ Xpath 1073741824 " X: 1073741824
+
+ delfunction C
+
+endif
+
+Xcheck 2146584868
+
+
+"-------------------------------------------------------------------------------
+" Test 35: :finally reason discarded by :break {{{1
+"
+" When a :finally clause is executed due to a :continue, :break,
+" :return, :finish, error, interrupt or :throw, the jump reason is
+" discarded by a :break in the finally clause.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+if ExtraVim()
+
+ XloopINIT! 1 8
+
+ function! B(jump)
+ XloopNEXT
+ let loop = 0
+ while loop < 2
+ let loop = loop + 1
+ if loop == 1
+ try
+ if a:jump == "continue"
+ continue
+ elseif a:jump == "break"
+ break
+ elseif a:jump == "return" || a:jump == "finish"
+ return
+ elseif a:jump == "error"
+ asdf
+ elseif a:jump == "interrupt"
+ "INTERRUPT
+ let dummy = 0
+ elseif a:jump == "throw"
+ throw "abc"
+ endif
+ finally
+ break " discards jump that caused the :finally
+ Xloop 1 " X: 0
+ endtry
+ elseif loop == 2
+ Xloop 2 " X: 0
+ endif
+ endwhile
+ Xloop 4 " X: 4*(1+8+64+512+4096+32768+262144)
+ endfunction
+
+ call B("continue")
+ Xpath 2097152 " X: 2097152
+ call B("break")
+ Xpath 4194304 " X: 4194304
+ call B("return")
+ Xpath 8388608 " X: 8388608
+ let g:jump = "finish"
+ ExecAsScript B
+ unlet g:jump
+ Xpath 16777216 " X: 16777216
+ try
+ call B("error")
+ Xpath 33554432 " X: 33554432
+ finally
+ Xpath 67108864 " X: 67108864
+ try
+ call B("interrupt")
+ Xpath 134217728 " X: 134217728
+ finally
+ Xpath 268435456 " X: 268435456
+ call B("throw")
+ Xpath 536870912 " X: 536870912
+ endtry
+ endtry
+ Xpath 1073741824 " X: 1073741824
+
+ delfunction B
+
+endif
+
+Xcheck 2146584868
+
+
+"-------------------------------------------------------------------------------
+" Test 36: :finally reason discarded by :return {{{1
+"
+" When a :finally clause is executed due to a :continue, :break,
+" :return, :finish, error, interrupt or :throw, the jump reason is
+" discarded by a :return in the finally clause.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+if ExtraVim()
+
+ XloopINIT! 1 8
+
+ function! R(jump, retval) abort
+ XloopNEXT
+ let loop = 0
+ while loop < 2
+ let loop = loop + 1
+ if loop == 1
+ try
+ if a:jump == "continue"
+ continue
+ elseif a:jump == "break"
+ break
+ elseif a:jump == "return"
+ return
+ elseif a:jump == "error"
+ asdf
+ elseif a:jump == "interrupt"
+ "INTERRUPT
+ let dummy = 0
+ elseif a:jump == "throw"
+ throw "abc"
+ endif
+ finally
+ return a:retval " discards jump that caused the :finally
+ Xloop 1 " X: 0
+ endtry
+ elseif loop == 2
+ Xloop 2 " X: 0
+ endif
+ endwhile
+ Xloop 4 " X: 0
+ endfunction
+
+ let sum = -R("continue", -8)
+ Xpath 2097152 " X: 2097152
+ let sum = sum - R("break", -16)
+ Xpath 4194304 " X: 4194304
+ let sum = sum - R("return", -32)
+ Xpath 8388608 " X: 8388608
+ try
+ let sum = sum - R("error", -64)
+ Xpath 16777216 " X: 16777216
+ finally
+ Xpath 33554432 " X: 33554432
+ try
+ let sum = sum - R("interrupt", -128)
+ Xpath 67108864 " X: 67108864
+ finally
+ Xpath 134217728 " X: 134217728
+ let sum = sum - R("throw", -256)
+ Xpath 268435456 " X: 268435456
+ endtry
+ endtry
+ Xpath 536870912 " X: 536870912
+
+ let expected = 8 + 16 + 32 + 64 + 128 + 256
+ if sum != expected
+ Xpath 1073741824 " X: 0
+ Xout "sum =" . sum . ", expected: " . expected
+ endif
+
+ unlet sum expected
+ delfunction R
+
+endif
+
+Xcheck 1071644672
+
+
+"-------------------------------------------------------------------------------
+" Test 37: :finally reason discarded by :finish {{{1
+"
+" When a :finally clause is executed due to a :continue, :break,
+" :return, :finish, error, interrupt or :throw, the jump reason is
+" discarded by a :finish in the finally clause.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+if ExtraVim()
+
+ XloopINIT! 1 8
+
+ function! F(jump) " not executed as function, transformed to a script
+ XloopNEXT
+ let loop = 0
+ while loop < 2
+ let loop = loop + 1
+ if loop == 1
+ try
+ if a:jump == "continue"
+ continue
+ elseif a:jump == "break"
+ break
+ elseif a:jump == "finish"
+ finish
+ elseif a:jump == "error"
+ asdf
+ elseif a:jump == "interrupt"
+ "INTERRUPT
+ let dummy = 0
+ elseif a:jump == "throw"
+ throw "abc"
+ endif
+ finally
+ finish " discards jump that caused the :finally
+ Xloop 1 " X: 0
+ endtry
+ elseif loop == 2
+ Xloop 2 " X: 0
+ endif
+ endwhile
+ Xloop 4 " X: 0
+ endfunction
+
+ let scriptF = MakeScript("F")
+ delfunction F
+
+ let g:jump = "continue"
+ exec "source" scriptF
+ Xpath 2097152 " X: 2097152
+ let g:jump = "break"
+ exec "source" scriptF
+ Xpath 4194304 " X: 4194304
+ let g:jump = "finish"
+ exec "source" scriptF
+ Xpath 8388608 " X: 8388608
+ try
+ let g:jump = "error"
+ exec "source" scriptF
+ Xpath 16777216 " X: 16777216
+ finally
+ Xpath 33554432 " X: 33554432
+ try
+ let g:jump = "interrupt"
+ exec "source" scriptF
+ Xpath 67108864 " X: 67108864
+ finally
+ Xpath 134217728 " X: 134217728
+ try
+ let g:jump = "throw"
+ exec "source" scriptF
+ Xpath 268435456 " X: 268435456
+ finally
+ Xpath 536870912 " X: 536870912
+ endtry
+ endtry
+ endtry
+ unlet g:jump
+
+ call delete(scriptF)
+ unlet scriptF
+
+endif
+
+Xcheck 1071644672
+
+
+"-------------------------------------------------------------------------------
+" Test 38: :finally reason discarded by an error {{{1
+"
+" When a :finally clause is executed due to a :continue, :break,
+" :return, :finish, error, interrupt or :throw, the jump reason is
+" discarded by an error in the finally clause.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+if ExtraVim()
+
+ XloopINIT! 1 4
+
+ function! E(jump)
+ XloopNEXT
+ let loop = 0
+ while loop < 2
+ let loop = loop + 1
+ if loop == 1
+ try
+ if a:jump == "continue"
+ continue
+ elseif a:jump == "break"
+ break
+ elseif a:jump == "return" || a:jump == "finish"
+ return
+ elseif a:jump == "error"
+ asdf
+ elseif a:jump == "interrupt"
+ "INTERRUPT
+ let dummy = 0
+ elseif a:jump == "throw"
+ throw "abc"
+ endif
+ finally
+ asdf " error; discards jump that caused the :finally
+ endtry
+ elseif loop == 2
+ Xloop 1 " X: 0
+ endif
+ endwhile
+ Xloop 2 " X: 0
+ endfunction
+
+ try
+ Xpath 16384 " X: 16384
+ call E("continue")
+ Xpath 32768 " X: 0
+ finally
+ try
+ Xpath 65536 " X: 65536
+ call E("break")
+ Xpath 131072 " X: 0
+ finally
+ try
+ Xpath 262144 " X: 262144
+ call E("return")
+ Xpath 524288 " X: 0
+ finally
+ try
+ Xpath 1048576 " X: 1048576
+ let g:jump = "finish"
+ ExecAsScript E
+ Xpath 2097152 " X: 0
+ finally
+ unlet g:jump
+ try
+ Xpath 4194304 " X: 4194304
+ call E("error")
+ Xpath 8388608 " X: 0
+ finally
+ try
+ Xpath 16777216 " X: 16777216
+ call E("interrupt")
+ Xpath 33554432 " X: 0
+ finally
+ try
+ Xpath 67108864 " X: 67108864
+ call E("throw")
+ Xpath 134217728 " X: 0
+ finally
+ Xpath 268435456 " X: 268435456
+ delfunction E
+ endtry
+ endtry
+ endtry
+ endtry
+ endtry
+ endtry
+ endtry
+ Xpath 536870912 " X: 0
+
+endif
+
+Xcheck 357908480
+
+
+"-------------------------------------------------------------------------------
+" Test 39: :finally reason discarded by an interrupt {{{1
+"
+" When a :finally clause is executed due to a :continue, :break,
+" :return, :finish, error, interrupt or :throw, the jump reason is
+" discarded by an interrupt in the finally clause.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+if ExtraVim()
+
+ XloopINIT! 1 4
+
+ function! I(jump)
+ XloopNEXT
+ let loop = 0
+ while loop < 2
+ let loop = loop + 1
+ if loop == 1
+ try
+ if a:jump == "continue"
+ continue
+ elseif a:jump == "break"
+ break
+ elseif a:jump == "return" || a:jump == "finish"
+ return
+ elseif a:jump == "error"
+ asdf
+ elseif a:jump == "interrupt"
+ "INTERRUPT
+ let dummy = 0
+ elseif a:jump == "throw"
+ throw "abc"
+ endif
+ finally
+ "INTERRUPT - discards jump that caused the :finally
+ let dummy = 0
+ endtry
+ elseif loop == 2
+ Xloop 1 " X: 0
+ endif
+ endwhile
+ Xloop 2 " X: 0
+ endfunction
+
+ try
+ Xpath 16384 " X: 16384
+ call I("continue")
+ Xpath 32768 " X: 0
+ finally
+ try
+ Xpath 65536 " X: 65536
+ call I("break")
+ Xpath 131072 " X: 0
+ finally
+ try
+ Xpath 262144 " X: 262144
+ call I("return")
+ Xpath 524288 " X: 0
+ finally
+ try
+ Xpath 1048576 " X: 1048576
+ let g:jump = "finish"
+ ExecAsScript I
+ Xpath 2097152 " X: 0
+ finally
+ unlet g:jump
+ try
+ Xpath 4194304 " X: 4194304
+ call I("error")
+ Xpath 8388608 " X: 0
+ finally
+ try
+ Xpath 16777216 " X: 16777216
+ call I("interrupt")
+ Xpath 33554432 " X: 0
+ finally
+ try
+ Xpath 67108864 " X: 67108864
+ call I("throw")
+ Xpath 134217728 " X: 0
+ finally
+ Xpath 268435456 " X: 268435456
+ delfunction I
+ endtry
+ endtry
+ endtry
+ endtry
+ endtry
+ endtry
+ endtry
+ Xpath 536870912 " X: 0
+
+endif
+
+Xcheck 357908480
+
+
+"-------------------------------------------------------------------------------
+" Test 40: :finally reason discarded by :throw {{{1
+"
+" When a :finally clause is executed due to a :continue, :break,
+" :return, :finish, error, interrupt or :throw, the jump reason is
+" discarded by a :throw in the finally clause.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+if ExtraVim()
+
+ XloopINIT! 1 4
+
+ function! T(jump)
+ XloopNEXT
+ let loop = 0
+ while loop < 2
+ let loop = loop + 1
+ if loop == 1
+ try
+ if a:jump == "continue"
+ continue
+ elseif a:jump == "break"
+ break
+ elseif a:jump == "return" || a:jump == "finish"
+ return
+ elseif a:jump == "error"
+ asdf
+ elseif a:jump == "interrupt"
+ "INTERRUPT
+ let dummy = 0
+ elseif a:jump == "throw"
+ throw "abc"
+ endif
+ finally
+ throw "xyz" " discards jump that caused the :finally
+ endtry
+ elseif loop == 2
+ Xloop 1 " X: 0
+ endif
+ endwhile
+ Xloop 2 " X: 0
+ endfunction
+
+ try
+ Xpath 16384 " X: 16384
+ call T("continue")
+ Xpath 32768 " X: 0
+ finally
+ try
+ Xpath 65536 " X: 65536
+ call T("break")
+ Xpath 131072 " X: 0
+ finally
+ try
+ Xpath 262144 " X: 262144
+ call T("return")
+ Xpath 524288 " X: 0
+ finally
+ try
+ Xpath 1048576 " X: 1048576
+ let g:jump = "finish"
+ ExecAsScript T
+ Xpath 2097152 " X: 0
+ finally
+ unlet g:jump
+ try
+ Xpath 4194304 " X: 4194304
+ call T("error")
+ Xpath 8388608 " X: 0
+ finally
+ try
+ Xpath 16777216 " X: 16777216
+ call T("interrupt")
+ Xpath 33554432 " X: 0
+ finally
+ try
+ Xpath 67108864 " X: 67108864
+ call T("throw")
+ Xpath 134217728 " X: 0
+ finally
+ Xpath 268435456 " X: 268435456
+ delfunction T
+ endtry
+ endtry
+ endtry
+ endtry
+ endtry
+ endtry
+ endtry
+ Xpath 536870912 " X: 0
+
+endif
+
+Xcheck 357908480
+
+
+"-------------------------------------------------------------------------------
+" Test 41: Skipped :throw finding next command {{{1
+"
+" A :throw in an inactive conditional must not hide a following
+" command.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+function! F()
+ Xpath 1 " X: 1
+ if 0 | throw "never" | endif | Xpath 2 " X: 2
+ Xpath 4 " X: 4
+endfunction
+
+function! G()
+ Xpath 8 " X: 8
+ while 0 | throw "never" | endwhile | Xpath 16 " X: 16
+ Xpath 32 " X: 32
+endfunction
+
+function H()
+ Xpath 64 " X: 64
+ if 0 | try | throw "never" | endtry | endif | Xpath 128 " X: 128
+ Xpath 256 " X: 256
+endfunction
+
+Xpath 512 " X: 512
+
+try
+ Xpath 1024 " X: 1024
+ call F()
+ Xpath 2048 " X: 2048
+catch /.*/
+ Xpath 4096 " X: 0
+ Xout v:exception "in" v:throwpoint
+endtry
+
+Xpath 8192 " X: 8192
+
+try
+ Xpath 16384 " X: 16384
+ call G()
+ Xpath 32768 " X: 32768
+catch /.*/
+ Xpath 65536 " X: 0
+ Xout v:exception "in" v:throwpoint
+endtry
+
+Xpath 131072 " X: 131072
+
+try
+ Xpath 262144 " X: 262144
+ call H()
+ Xpath 524288 " X: 524288
+catch /.*/
+ Xpath 1048576 " X: 0
+ Xout v:exception "in" v:throwpoint
+endtry
+
+Xpath 2097152 " X: 2097152
+
+delfunction F
+delfunction G
+delfunction H
+
+Xcheck 3076095
+
+
+"-------------------------------------------------------------------------------
+" Test 42: Catching number and string exceptions {{{1
+"
+" When a number is thrown, it is converted to a string exception.
+" Numbers and strings may be caught by specifying a regular exception
+" as argument to the :catch command.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+try
+
+ try
+ Xpath 1 " X: 1
+ throw 4711
+ Xpath 2 " X: 0
+ catch /4711/
+ Xpath 4 " X: 4
+ endtry
+
+ try
+ Xpath 8 " X: 8
+ throw 4711
+ Xpath 16 " X: 0
+ catch /^4711$/
+ Xpath 32 " X: 32
+ endtry
+
+ try
+ Xpath 64 " X: 64
+ throw 4711
+ Xpath 128 " X: 0
+ catch /\d/
+ Xpath 256 " X: 256
+ endtry
+
+ try
+ Xpath 512 " X: 512
+ throw 4711
+ Xpath 1024 " X: 0
+ catch /^\d\+$/
+ Xpath 2048 " X: 2048
+ endtry
+
+ try
+ Xpath 4096 " X: 4096
+ throw "arrgh"
+ Xpath 8192 " X: 0
+ catch /arrgh/
+ Xpath 16384 " X: 16384
+ endtry
+
+ try
+ Xpath 32768 " X: 32768
+ throw "arrgh"
+ Xpath 65536 " X: 0
+ catch /^arrgh$/
+ Xpath 131072 " X: 131072
+ endtry
+
+ try
+ Xpath 262144 " X: 262144
+ throw "arrgh"
+ Xpath 524288 " X: 0
+ catch /\l/
+ Xpath 1048576 " X: 1048576
+ endtry
+
+ try
+ Xpath 2097152 " X: 2097152
+ throw "arrgh"
+ Xpath 4194304 " X: 0
+ catch /^\l\+$/
+ Xpath 8388608 " X: 8388608
+ endtry
+
+ try
+ try
+ Xpath 16777216 " X: 16777216
+ throw "ARRGH"
+ Xpath 33554432 " X: 0
+ catch /^arrgh$/
+ Xpath 67108864 " X: 0
+ endtry
+ catch /^\carrgh$/
+ Xpath 134217728 " X: 134217728
+ endtry
+
+ try
+ Xpath 268435456 " X: 268435456
+ throw ""
+ Xpath 536870912 " X: 0
+ catch /^$/
+ Xpath 1073741824 " X: 1073741824
+ endtry
+
+catch /.*/
+ " The Xpath command does not accept 2^31 (negative); add explicitly:
+ let Xpath = Xpath + 2147483648 " X: 0
+ Xout v:exception "in" v:throwpoint
+endtry
+
+Xcheck 1505155949
+
+
+"-------------------------------------------------------------------------------
+" Test 43: Selecting the correct :catch clause {{{1
+"
+" When an exception is thrown and there are multiple :catch clauses,
+" the first matching one is taken.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+XloopINIT 1 1024
+let loops = 3
+while loops > 0
+ try
+ if loops == 3
+ Xloop 1 " X: 1
+ throw "a"
+ Xloop 2 " X: 0
+ elseif loops == 2
+ Xloop 4 " X: 4*1024
+ throw "ab"
+ Xloop 8 " X: 0
+ elseif loops == 1
+ Xloop 16 " X: 16*1024*1024
+ throw "abc"
+ Xloop 32 " X: 0
+ endif
+ catch /abc/
+ Xloop 64 " X: 64*1024*1024
+ catch /ab/
+ Xloop 128 " X: 128*1024
+ catch /.*/
+ Xloop 256 " X: 256
+ catch /a/
+ Xloop 512 " X: 0
+ endtry
+
+ let loops = loops - 1
+ XloopNEXT
+endwhile
+Xpath 1073741824 " X: 1073741824
+
+unlet loops
+
+Xcheck 1157763329
+
+
+"-------------------------------------------------------------------------------
+" Test 44: Missing or empty :catch patterns {{{1
+"
+" A missing or empty :catch pattern means the same as /.*/, that is,
+" catches everything. To catch only empty exceptions, /^$/ must be
+" used. A :catch with missing, empty, or /.*/ argument also works
+" when followed by another command separated by a bar on the same
+" line. :catch patterns cannot be specified between ||. But other
+" pattern separators can be used instead of //.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+try
+ try
+ Xpath 1 " X: 1
+ throw ""
+ catch /^$/
+ Xpath 2 " X: 2
+ endtry
+
+ try
+ Xpath 4 " X: 4
+ throw ""
+ catch /.*/
+ Xpath 8 " X: 8
+ endtry
+
+ try
+ Xpath 16 " X: 16
+ throw ""
+ catch //
+ Xpath 32 " X: 32
+ endtry
+
+ try
+ Xpath 64 " X: 64
+ throw ""
+ catch
+ Xpath 128 " X: 128
+ endtry
+
+ try
+ Xpath 256 " X: 256
+ throw "oops"
+ catch /^$/
+ Xpath 512 " X: 0
+ catch /.*/
+ Xpath 1024 " X: 1024
+ endtry
+
+ try
+ Xpath 2048 " X: 2048
+ throw "arrgh"
+ catch /^$/
+ Xpath 4096 " X: 0
+ catch //
+ Xpath 8192 " X: 8192
+ endtry
+
+ try
+ Xpath 16384 " X: 16384
+ throw "brrr"
+ catch /^$/
+ Xpath 32768 " X: 0
+ catch
+ Xpath 65536 " X: 65536
+ endtry
+
+ try | Xpath 131072 | throw "x" | catch /.*/ | Xpath 262144 | endtry
+ " X: 131072 + 262144
+
+ try | Xpath 524288 | throw "y" | catch // | Xpath 1048576 | endtry
+ " X: 524288 + 1048576
+
+ while 1
+ try
+ let caught = 0
+ let v:errmsg = ""
+ " Extra try level: if ":catch" without arguments below raises
+ " a syntax error because it misinterprets the "Xpath" as a pattern,
+ " let it be caught by the ":catch /.*/" below.
+ try
+ try | Xpath 2097152 | throw "z" | catch | Xpath 4194304 | :
+ endtry " X: 2097152 + 4194304
+ endtry
+ catch /.*/
+ let caught = 1
+ Xout v:exception "in" v:throwpoint
+ finally
+ if $VIMNOERRTHROW && v:errmsg != ""
+ Xout v:errmsg
+ endif
+ if caught || $VIMNOERRTHROW && v:errmsg != ""
+ Xpath 8388608 " X: 0
+ endif
+ break " discard error for $VIMNOERRTHROW
+ endtry
+ endwhile
+
+ let cologne = 4711
+ try
+ try
+ Xpath 16777216 " X: 16777216
+ throw "throw cologne"
+ " Next lines catches all and throws 4711:
+ catch |throw cologne|
+ Xpath 33554432 " X: 0
+ endtry
+ catch /4711/
+ Xpath 67108864 " X: 67108864
+ endtry
+
+ try
+ Xpath 134217728 " X: 134217728
+ throw "plus"
+ catch +plus+
+ Xpath 268435456 " X: 268435456
+ endtry
+
+ Xpath 536870912 " X: 536870912
+catch /.*/
+ Xpath 1073741824 " X: 0
+ Xout v:exception "in" v:throwpoint
+endtry
+
+unlet! caught cologne
+
+Xcheck 1031761407
+
+
+"-------------------------------------------------------------------------------
+" Test 45: Catching exceptions from nested :try blocks {{{1
+"
+" When :try blocks are nested, an exception is caught by the innermost
+" try conditional that has a matching :catch clause.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+XloopINIT 1 1024
+let loops = 3
+while loops > 0
+ try
+ try
+ try
+ try
+ if loops == 3
+ Xloop 1 " X: 1
+ throw "a"
+ Xloop 2 " X: 0
+ elseif loops == 2
+ Xloop 4 " X: 4*1024
+ throw "ab"
+ Xloop 8 " X: 0
+ elseif loops == 1
+ Xloop 16 " X: 16*1024*1024
+ throw "abc"
+ Xloop 32 " X: 0
+ endif
+ catch /abc/
+ Xloop 64 " X: 64*1024*1024
+ endtry
+ catch /ab/
+ Xloop 128 " X: 128*1024
+ endtry
+ catch /.*/
+ Xloop 256 " X: 256
+ endtry
+ catch /a/
+ Xloop 512 " X: 0
+ endtry
+
+ let loops = loops - 1
+ XloopNEXT
+endwhile
+Xpath 1073741824 " X: 1073741824
+
+unlet loops
+
+Xcheck 1157763329
+
+
+"-------------------------------------------------------------------------------
+" Test 46: Executing :finally after a :throw in nested :try {{{1
+"
+" When an exception is thrown from within nested :try blocks, the
+" :finally clauses of the non-catching try conditionals should be
+" executed before the matching :catch of the next surrounding :try
+" gets the control. If this also has a :finally clause, it is
+" executed afterwards.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+let sum = 0
+
+try
+ Xpath 1 " X: 1
+ try
+ Xpath 2 " X: 2
+ try
+ Xpath 4 " X: 4
+ try
+ Xpath 8 " X: 8
+ throw "ABC"
+ Xpath 16 " X: 0
+ catch /xyz/
+ Xpath 32 " X: 0
+ finally
+ Xpath 64 " X: 64
+ if sum != 0
+ Xpath 128 " X: 0
+ endif
+ let sum = sum + 1
+ endtry
+ Xpath 256 " X: 0
+ catch /123/
+ Xpath 512 " X: 0
+ catch /321/
+ Xpath 1024 " X: 0
+ finally
+ Xpath 2048 " X: 2048
+ if sum != 1
+ Xpath 4096 " X: 0
+ endif
+ let sum = sum + 2
+ endtry
+ Xpath 8192 " X: 0
+ finally
+ Xpath 16384 " X: 16384
+ if sum != 3
+ Xpath 32768 " X: 0
+ endif
+ let sum = sum + 4
+ endtry
+ Xpath 65536 " X: 0
+catch /ABC/
+ Xpath 131072 " X: 131072
+ if sum != 7
+ Xpath 262144 " X: 0
+ endif
+ let sum = sum + 8
+finally
+ Xpath 524288 " X: 524288
+ if sum != 15
+ Xpath 1048576 " X: 0
+ endif
+ let sum = sum + 16
+endtry
+Xpath 65536 " X: 65536
+if sum != 31
+ Xpath 131072 " X: 0
+endif
+
+unlet sum
+
+Xcheck 739407
+
+
+"-------------------------------------------------------------------------------
+" Test 47: Throwing exceptions from a :catch clause {{{1
+"
+" When an exception is thrown from a :catch clause, it should not be
+" caught by a :catch of the same :try conditional. After executing
+" the :finally clause (if present), surrounding try conditionals
+" should be checked for a matching :catch.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+Xpath 1 " X: 1
+try
+ Xpath 2 " X: 2
+ try
+ Xpath 4 " X: 4
+ try
+ Xpath 8 " X: 8
+ throw "x1"
+ Xpath 16 " X: 0
+ catch /x1/
+ Xpath 32 " X: 32
+ try
+ Xpath 64 " X: 64
+ throw "x2"
+ Xpath 128 " X: 0
+ catch /x1/
+ Xpath 256 " X: 0
+ catch /x2/
+ Xpath 512 " X: 512
+ try
+ Xpath 1024 " X: 1024
+ throw "x3"
+ Xpath 2048 " X: 0
+ catch /x1/
+ Xpath 4096 " X: 0
+ catch /x2/
+ Xpath 8192 " X: 0
+ finally
+ Xpath 16384 " X: 16384
+ endtry
+ Xpath 32768 " X: 0
+ catch /x3/
+ Xpath 65536 " X: 0
+ endtry
+ Xpath 131072 " X: 0
+ catch /x1/
+ Xpath 262144 " X: 0
+ catch /x2/
+ Xpath 524288 " X: 0
+ catch /x3/
+ Xpath 1048576 " X: 0
+ finally
+ Xpath 2097152 " X: 2097152
+ endtry
+ Xpath 4194304 " X: 0
+ catch /x1/
+ Xpath 8388608 " X: 0
+ catch /x2/
+ Xpath 16777216 " X: 0
+ catch /x3/
+ Xpath 33554432 " X: 33554432
+ endtry
+ Xpath 67108864 " X: 67108864
+catch /.*/
+ Xpath 134217728 " X: 0
+ Xout v:exception "in" v:throwpoint
+endtry
+Xpath 268435456 " X: 268435456
+
+Xcheck 371213935
+
+
+"-------------------------------------------------------------------------------
+" Test 48: Throwing exceptions from a :finally clause {{{1
+"
+" When an exception is thrown from a :finally clause, it should not be
+" caught by a :catch of the same :try conditional. Surrounding try
+" conditionals should be checked for a matching :catch. A previously
+" thrown exception is discarded.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+try
+
+ try
+ try
+ Xpath 1 " X: 1
+ catch /x1/
+ Xpath 2 " X: 0
+ finally
+ Xpath 4 " X: 4
+ throw "x1"
+ Xpath 8 " X: 0
+ endtry
+ Xpath 16 " X: 0
+ catch /x1/
+ Xpath 32 " X: 32
+ endtry
+ Xpath 64 " X: 64
+
+ try
+ try
+ Xpath 128 " X: 128
+ throw "x2"
+ Xpath 256 " X: 0
+ catch /x2/
+ Xpath 512 " X: 512
+ catch /x3/
+ Xpath 1024 " X: 0
+ finally
+ Xpath 2048 " X: 2048
+ throw "x3"
+ Xpath 4096 " X: 0
+ endtry
+ Xpath 8192 " X: 0
+ catch /x2/
+ Xpath 16384 " X: 0
+ catch /x3/
+ Xpath 32768 " X: 32768
+ endtry
+ Xpath 65536 " X: 65536
+
+ try
+ try
+ try
+ Xpath 131072 " X: 131072
+ throw "x4"
+ Xpath 262144 " X: 0
+ catch /x5/
+ Xpath 524288 " X: 0
+ finally
+ Xpath 1048576 " X: 1048576
+ throw "x5" " discards "x4"
+ Xpath 2097152 " X: 0
+ endtry
+ Xpath 4194304 " X: 0
+ catch /x4/
+ Xpath 8388608 " X: 0
+ finally
+ Xpath 16777216 " X: 16777216
+ endtry
+ Xpath 33554432 " X: 0
+ catch /x5/
+ Xpath 67108864 " X: 67108864
+ endtry
+ Xpath 134217728 " X: 134217728
+
+catch /.*/
+ Xpath 268435456 " X: 0
+ Xout v:exception "in" v:throwpoint
+endtry
+Xpath 536870912 " X: 536870912
+
+Xcheck 756255461
+
+
+"-------------------------------------------------------------------------------
+" Test 49: Throwing exceptions across functions {{{1
+"
+" When an exception is thrown but not caught inside a function, the
+" caller is checked for a matching :catch clause.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+function! C()
+ try
+ Xpath 1 " X: 1
+ throw "arrgh"
+ Xpath 2 " X: 0
+ catch /arrgh/
+ Xpath 4 " X: 4
+ endtry
+ Xpath 8 " X: 8
+endfunction
+
+XloopINIT! 16 16
+
+function! T1()
+ XloopNEXT
+ try
+ Xloop 1 " X: 16 + 16*16
+ throw "arrgh"
+ Xloop 2 " X: 0
+ finally
+ Xloop 4 " X: 64 + 64*16
+ endtry
+ Xloop 8 " X: 0
+endfunction
+
+function! T2()
+ try
+ Xpath 4096 " X: 4096
+ call T1()
+ Xpath 8192 " X: 0
+ finally
+ Xpath 16384 " X: 16384
+ endtry
+ Xpath 32768 " X: 0
+endfunction
+
+try
+ Xpath 65536 " X: 65536
+ call C() " throw and catch
+ Xpath 131072 " X: 131072
+catch /.*/
+ Xpath 262144 " X: 0
+ Xout v:exception "in" v:throwpoint
+endtry
+
+try
+ Xpath 524288 " X: 524288
+ call T1() " throw, one level
+ Xpath 1048576 " X: 0
+catch /arrgh/
+ Xpath 2097152 " X: 2097152
+catch /.*/
+ Xpath 4194304 " X: 0
+ Xout v:exception "in" v:throwpoint
+endtry
+
+try
+ Xpath 8388608 " X: 8388608
+ call T2() " throw, two levels
+ Xpath 16777216 " X: 0
+catch /arrgh/
+ Xpath 33554432 " X: 33554432
+catch /.*/
+ Xpath 67108864 " X: 0
+ Xout v:exception "in" v:throwpoint
+endtry
+Xpath 134217728 " X: 134217728
+
+Xcheck 179000669
+
+" Leave C, T1, and T2 for execution as scripts in the next test.
+
+
+"-------------------------------------------------------------------------------
+" Test 50: Throwing exceptions across script files {{{1
+"
+" When an exception is thrown but not caught inside a script file,
+" the sourcing script or function is checked for a matching :catch
+" clause.
+"
+" This test executes the bodies of the functions C, T1, and T2 from
+" the previous test as script files (:return replaced by :finish).
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+let scriptC = MakeScript("C") " X: 1 + 4 + 8
+delfunction C
+
+XloopINIT! 16 16
+
+let scriptT1 = MakeScript("T1") " X: 16 + 64 + 16*16 + 64*16
+delfunction T1
+
+let scriptT2 = MakeScript("T2", scriptT1) " X: 4096 + 16384
+delfunction T2
+
+function! F()
+ try
+ Xpath 65536 " X: 65536
+ exec "source" g:scriptC
+ Xpath 131072 " X: 131072
+ catch /.*/
+ Xpath 262144 " X: 0
+ Xout v:exception "in" v:throwpoint
+ endtry
+
+ try
+ Xpath 524288 " X: 524288
+ exec "source" g:scriptT1
+ Xpath 1048576 " X: 0
+ catch /arrgh/
+ Xpath 2097152 " X: 2097152
+ catch /.*/
+ Xpath 4194304 " X: 0
+ Xout v:exception "in" v:throwpoint
+ endtry
+endfunction
+
+try
+ Xpath 8388608 " X: 8388608
+ call F()
+ Xpath 16777216 " X: 16777216
+ exec "source" scriptT2
+ Xpath 33554432 " X: 0
+catch /arrgh/
+ Xpath 67108864 " X: 67108864
+catch /.*/
+ Xpath 134217728 " X: 0
+ Xout v:exception "in" v:throwpoint
+endtry
+Xpath 268435456 " X: 268435456
+
+call delete(scriptC)
+call delete(scriptT1)
+call delete(scriptT2)
+unlet scriptC scriptT1 scriptT2
+delfunction F
+
+Xcheck 363550045
+
+
+"-------------------------------------------------------------------------------
+" Test 51: Throwing exceptions across :execute and user commands {{{1
+"
+" A :throw command may be executed under an ":execute" or from
+" a user command.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+command! -nargs=? THROW1 throw <args> | throw 1
+command! -nargs=? THROW2 try | throw <args> | endtry | throw 2
+command! -nargs=? THROW3 try | throw 3 | catch /3/ | throw <args> | endtry
+command! -nargs=? THROW4 try | throw 4 | finally | throw <args> | endtry
+
+try
+
+ try
+ try
+ Xpath 1 " X: 1
+ THROW1 "A"
+ catch /A/
+ Xpath 2 " X: 2
+ endtry
+ catch /1/
+ Xpath 4 " X: 0
+ endtry
+
+ try
+ try
+ Xpath 8 " X: 8
+ THROW2 "B"
+ catch /B/
+ Xpath 16 " X: 16
+ endtry
+ catch /2/
+ Xpath 32 " X: 0
+ endtry
+
+ try
+ try
+ Xpath 64 " X: 64
+ THROW3 "C"
+ catch /C/
+ Xpath 128 " X: 128
+ endtry
+ catch /3/
+ Xpath 256 " X: 0
+ endtry
+
+ try
+ try
+ Xpath 512 " X: 512
+ THROW4 "D"
+ catch /D/
+ Xpath 1024 " X: 1024
+ endtry
+ catch /4/
+ Xpath 2048 " X: 0
+ endtry
+
+ try
+ try
+ Xpath 4096 " X: 4096
+ execute 'throw "E" | throw 5'
+ catch /E/
+ Xpath 8192 " X: 8192
+ endtry
+ catch /5/
+ Xpath 16384 " X: 0
+ endtry
+
+ try
+ try
+ Xpath 32768 " X: 32768
+ execute 'try | throw "F" | endtry | throw 6'
+ catch /F/
+ Xpath 65536 " X: 65536
+ endtry
+ catch /6/
+ Xpath 131072 " X: 0
+ endtry
+
+ try
+ try
+ Xpath 262144 " X: 262144
+ execute'try | throw 7 | catch /7/ | throw "G" | endtry'
+ catch /G/
+ Xpath 524288 " X: 524288
+ endtry
+ catch /7/
+ Xpath 1048576 " X: 0
+ endtry
+
+ try
+ try
+ Xpath 2097152 " X: 2097152
+ execute 'try | throw 8 | finally | throw "H" | endtry'
+ catch /H/
+ Xpath 4194304 " X: 4194304
+ endtry
+ catch /8/
+ Xpath 8388608 " X: 0
+ endtry
+
+catch /.*/
+ Xpath 16777216 " X: 0
+ Xout v:exception "in" v:throwpoint
+endtry
+
+Xpath 33554432 " X: 33554432
+
+delcommand THROW1
+delcommand THROW2
+delcommand THROW3
+delcommand THROW4
+
+Xcheck 40744667
+
+
+"-------------------------------------------------------------------------------
+" Test 52: Uncaught exceptions {{{1
+"
+" When an exception is thrown but not caught, an error message is
+" displayed when the script is terminated. In case of an interrupt
+" or error exception, the normal interrupt or error message(s) are
+" displayed.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+let msgfile = tempname()
+
+function! MESSAGES(...)
+ try
+ exec "edit" g:msgfile
+ catch /^Vim(edit):/
+ return 0
+ endtry
+
+ let english = v:lang == "C" || v:lang =~ '^[Ee]n'
+ let match = 1
+ norm gg
+
+ let num = a:0 / 2
+ let cnt = 1
+ while cnt <= num
+ let enr = a:{2*cnt - 1}
+ let emsg= a:{2*cnt}
+ let cnt = cnt + 1
+
+ if enr == ""
+ Xout "TODO: Add message number for:" emsg
+ elseif enr == "INT"
+ let enr = ""
+ endif
+ if enr == "" && !english
+ continue
+ endif
+ let pattern = (enr != "") ? enr . ':.*' : ''
+ if english
+ let pattern = pattern . emsg
+ endif
+ if !search(pattern, "W")
+ let match = 0
+ Xout "No match for:" pattern
+ endif
+ norm $
+ endwhile
+
+ bwipeout!
+ return match
+endfunction
+
+if ExtraVim(msgfile)
+ Xpath 1 " X: 1
+ throw "arrgh"
+endif
+
+Xpath 2 " X: 2
+if !MESSAGES('E605', "Exception not caught")
+ Xpath 4 " X: 0
+endif
+
+if ExtraVim(msgfile)
+ try
+ Xpath 8 " X: 8
+ throw "oops"
+ catch /arrgh/
+ Xpath 16 " X: 0
+ endtry
+ Xpath 32 " X: 0
+endif
+
+Xpath 64 " X: 64
+if !MESSAGES('E605', "Exception not caught")
+ Xpath 128 " X: 0
+endif
+
+if ExtraVim(msgfile)
+ function! T()
+ throw "brrr"
+ endfunction
+
+ try
+ Xpath 256 " X: 256
+ throw "arrgh"
+ catch /.*/
+ Xpath 512 " X: 512
+ call T()
+ endtry
+ Xpath 1024 " X: 0
+endif
+
+Xpath 2048 " X: 2048
+if !MESSAGES('E605', "Exception not caught")
+ Xpath 4096 " X: 0
+endif
+
+if ExtraVim(msgfile)
+ try
+ Xpath 8192 " X: 8192
+ throw "arrgh"
+ finally
+ Xpath 16384 " X: 16384
+ throw "brrr"
+ endtry
+ Xpath 32768 " X: 0
+endif
+
+Xpath 65536 " X: 65536
+if !MESSAGES('E605', "Exception not caught")
+ Xpath 131072 " X: 0
+endif
+
+if ExtraVim(msgfile)
+ try
+ Xpath 262144 " X: 262144
+ "INTERRUPT
+ endtry
+ Xpath 524288 " X: 0
+endif
+
+Xpath 1048576 " X: 1048576
+if !MESSAGES('INT', "Interrupted")
+ Xpath 2097152 " X: 0
+endif
+
+if ExtraVim(msgfile)
+ try
+ Xpath 4194304 " X: 4194304
+ let x = novar " error E121/E15; exception: E121
+ catch /E15:/ " should not catch
+ Xpath 8388608 " X: 0
+ endtry
+ Xpath 16777216 " X: 0
+endif
+
+Xpath 33554432 " X: 33554432
+if !MESSAGES('E121', "Undefined variable", 'E15', "Invalid expression")
+ Xpath 67108864 " X: 0
+endif
+
+if ExtraVim(msgfile)
+ try
+ Xpath 134217728 " X: 134217728
+" unlet novar # " error E108/E488; exception: E488
+ catch /E108:/ " should not catch
+ Xpath 268435456 " X: 0
+ endtry
+ Xpath 536870912 " X: 0
+endif
+
+Xpath 1073741824 " X: 1073741824
+if !MESSAGES('E108', "No such variable", 'E488', "Trailing characters")
+ " The Xpath command does not accept 2^31 (negative); add explicitly:
+ let Xpath = Xpath + 2147483648 " X: 0
+endif
+
+call delete(msgfile)
+unlet msgfile
+
+Xcheck 1247112011
+
+" Leave MESSAGES() for the next tests.
+
+
+"-------------------------------------------------------------------------------
+" Test 53: Nesting errors: :endif/:else/:elseif {{{1
+"
+" For nesting errors of :if conditionals the correct error messages
+" should be given.
+"
+" This test reuses the function MESSAGES() from the previous test.
+" This functions checks the messages in g:msgfile.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+let msgfile = tempname()
+
+if ExtraVim(msgfile)
+" endif
+endif
+if MESSAGES('E580', ":endif without :if")
+ Xpath 1 " X: 1
+endif
+
+if ExtraVim(msgfile)
+" while 1
+" endif
+" endwhile
+endif
+if MESSAGES('E580', ":endif without :if")
+ Xpath 2 " X: 2
+endif
+
+if ExtraVim(msgfile)
+" try
+" finally
+" endif
+" endtry
+endif
+if MESSAGES('E580', ":endif without :if")
+ Xpath 4 " X: 4
+endif
+
+if ExtraVim(msgfile)
+" try
+" endif
+" endtry
+endif
+if MESSAGES('E580', ":endif without :if")
+ Xpath 8 " X: 8
+endif
+
+if ExtraVim(msgfile)
+" try
+" throw "a"
+" catch /a/
+" endif
+" endtry
+endif
+if MESSAGES('E580', ":endif without :if")
+ Xpath 16 " X: 16
+endif
+
+if ExtraVim(msgfile)
+" else
+endif
+if MESSAGES('E581', ":else without :if")
+ Xpath 32 " X: 32
+endif
+
+if ExtraVim(msgfile)
+" while 1
+" else
+" endwhile
+endif
+if MESSAGES('E581', ":else without :if")
+ Xpath 64 " X: 64
+endif
+
+if ExtraVim(msgfile)
+" try
+" finally
+" else
+" endtry
+endif
+if MESSAGES('E581', ":else without :if")
+ Xpath 128 " X: 128
+endif
+
+if ExtraVim(msgfile)
+" try
+" else
+" endtry
+endif
+if MESSAGES('E581', ":else without :if")
+ Xpath 256 " X: 256
+endif
+
+if ExtraVim(msgfile)
+" try
+" throw "a"
+" catch /a/
+" else
+" endtry
+endif
+if MESSAGES('E581', ":else without :if")
+ Xpath 512 " X: 512
+endif
+
+if ExtraVim(msgfile)
+" elseif
+endif
+if MESSAGES('E582', ":elseif without :if")
+ Xpath 1024 " X: 1024
+endif
+
+if ExtraVim(msgfile)
+" while 1
+" elseif
+" endwhile
+endif
+if MESSAGES('E582', ":elseif without :if")
+ Xpath 2048 " X: 2048
+endif
+
+if ExtraVim(msgfile)
+" try
+" finally
+" elseif
+" endtry
+endif
+if MESSAGES('E582', ":elseif without :if")
+ Xpath 4096 " X: 4096
+endif
+
+if ExtraVim(msgfile)
+" try
+" elseif
+" endtry
+endif
+if MESSAGES('E582', ":elseif without :if")
+ Xpath 8192 " X: 8192
+endif
+
+if ExtraVim(msgfile)
+" try
+" throw "a"
+" catch /a/
+" elseif
+" endtry
+endif
+if MESSAGES('E582', ":elseif without :if")
+ Xpath 16384 " X: 16384
+endif
+
+if ExtraVim(msgfile)
+" if 1
+" else
+" else
+" endif
+endif
+if MESSAGES('E583', "multiple :else")
+ Xpath 32768 " X: 32768
+endif
+
+if ExtraVim(msgfile)
+" if 1
+" else
+" elseif 1
+" endif
+endif
+if MESSAGES('E584', ":elseif after :else")
+ Xpath 65536 " X: 65536
+endif
+
+call delete(msgfile)
+unlet msgfile
+
+Xcheck 131071
+
+" Leave MESSAGES() for the next test.
+
+
+"-------------------------------------------------------------------------------
+" Test 54: Nesting errors: :while/:endwhile {{{1
+"
+" For nesting errors of :while conditionals the correct error messages
+" should be given.
+"
+" This test reuses the function MESSAGES() from the previous test.
+" This functions checks the messages in g:msgfile.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+let msgfile = tempname()
+
+if ExtraVim(msgfile)
+" endwhile
+endif
+if MESSAGES('E588', ":endwhile without :while")
+ Xpath 1 " X: 1
+endif
+
+if ExtraVim(msgfile)
+" if 1
+" endwhile
+" endif
+endif
+if MESSAGES('E588', ":endwhile without :while")
+ Xpath 2 " X: 2
+endif
+
+if ExtraVim(msgfile)
+" while 1
+" if 1
+" endwhile
+endif
+if MESSAGES('E171', "Missing :endif")
+ Xpath 4 " X: 4
+endif
+
+if ExtraVim(msgfile)
+" try
+" finally
+" endwhile
+" endtry
+endif
+if MESSAGES('E588', ":endwhile without :while")
+ Xpath 8 " X: 8
+endif
+
+if ExtraVim(msgfile)
+" while 1
+" try
+" finally
+" endwhile
+endif
+if MESSAGES('E600', "Missing :endtry")
+ Xpath 16 " X: 16
+endif
+
+if ExtraVim(msgfile)
+" while 1
+" if 1
+" try
+" finally
+" endwhile
+endif
+if MESSAGES('E600', "Missing :endtry")
+ Xpath 32 " X: 32
+endif
+
+if ExtraVim(msgfile)
+" while 1
+" try
+" finally
+" if 1
+" endwhile
+endif
+if MESSAGES('E171', "Missing :endif")
+ Xpath 64 " X: 64
+endif
+
+if ExtraVim(msgfile)
+" try
+" endwhile
+" endtry
+endif
+if MESSAGES('E588', ":endwhile without :while")
+ Xpath 128 " X: 128
+endif
+
+if ExtraVim(msgfile)
+" while 1
+" try
+" endwhile
+" endtry
+" endwhile
+endif
+if MESSAGES('E588', ":endwhile without :while")
+ Xpath 256 " X: 256
+endif
+
+if ExtraVim(msgfile)
+" try
+" throw "a"
+" catch /a/
+" endwhile
+" endtry
+endif
+if MESSAGES('E588', ":endwhile without :while")
+ Xpath 512 " X: 512
+endif
+
+if ExtraVim(msgfile)
+" while 1
+" try
+" throw "a"
+" catch /a/
+" endwhile
+" endtry
+" endwhile
+endif
+if MESSAGES('E588', ":endwhile without :while")
+ Xpath 1024 " X: 1024
+endif
+
+
+call delete(msgfile)
+unlet msgfile
+
+Xcheck 2047
+
+" Leave MESSAGES() for the next test.
+
+
+"-------------------------------------------------------------------------------
+" Test 55: Nesting errors: :continue/:break {{{1
+"
+" For nesting errors of :continue and :break commands the correct
+" error messages should be given.
+"
+" This test reuses the function MESSAGES() from the previous test.
+" This functions checks the messages in g:msgfile.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+let msgfile = tempname()
+
+if ExtraVim(msgfile)
+" continue
+endif
+if MESSAGES('E586', ":continue without :while")
+ Xpath 1 " X: 1
+endif
+
+if ExtraVim(msgfile)
+" if 1
+" continue
+" endif
+endif
+if MESSAGES('E586', ":continue without :while")
+ Xpath 2 " X: 2
+endif
+
+if ExtraVim(msgfile)
+" try
+" finally
+" continue
+" endtry
+endif
+if MESSAGES('E586', ":continue without :while")
+ Xpath 4 " X: 4
+endif
+
+if ExtraVim(msgfile)
+" try
+" continue
+" endtry
+endif
+if MESSAGES('E586', ":continue without :while")
+ Xpath 8 " X: 8
+endif
+
+if ExtraVim(msgfile)
+" try
+" throw "a"
+" catch /a/
+" continue
+" endtry
+endif
+if MESSAGES('E586', ":continue without :while")
+ Xpath 16 " X: 16
+endif
+
+if ExtraVim(msgfile)
+" break
+endif
+if MESSAGES('E587', ":break without :while")
+ Xpath 32 " X: 32
+endif
+
+if ExtraVim(msgfile)
+" if 1
+" break
+" endif
+endif
+if MESSAGES('E587', ":break without :while")
+ Xpath 64 " X: 64
+endif
+
+if ExtraVim(msgfile)
+" try
+" finally
+" break
+" endtry
+endif
+if MESSAGES('E587', ":break without :while")
+ Xpath 128 " X: 128
+endif
+
+if ExtraVim(msgfile)
+" try
+" break
+" endtry
+endif
+if MESSAGES('E587', ":break without :while")
+ Xpath 256 " X: 256
+endif
+
+if ExtraVim(msgfile)
+" try
+" throw "a"
+" catch /a/
+" break
+" endtry
+endif
+if MESSAGES('E587', ":break without :while")
+ Xpath 512 " X: 512
+endif
+
+call delete(msgfile)
+unlet msgfile
+
+Xcheck 1023
+
+" Leave MESSAGES() for the next test.
+
+
+"-------------------------------------------------------------------------------
+" Test 56: Nesting errors: :endtry {{{1
+"
+" For nesting errors of :try conditionals the correct error messages
+" should be given.
+"
+" This test reuses the function MESSAGES() from the previous test.
+" This functions checks the messages in g:msgfile.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+let msgfile = tempname()
+
+if ExtraVim(msgfile)
+" endtry
+endif
+if MESSAGES('E602', ":endtry without :try")
+ Xpath 1 " X: 1
+endif
+
+if ExtraVim(msgfile)
+" if 1
+" endtry
+" endif
+endif
+if MESSAGES('E602', ":endtry without :try")
+ Xpath 2 " X: 2
+endif
+
+if ExtraVim(msgfile)
+" while 1
+" endtry
+" endwhile
+endif
+if MESSAGES('E602', ":endtry without :try")
+ Xpath 4 " X: 4
+endif
+
+if ExtraVim(msgfile)
+" try
+" if 1
+" endtry
+endif
+if MESSAGES('E171', "Missing :endif")
+ Xpath 8 " X: 8
+endif
+
+if ExtraVim(msgfile)
+" try
+" while 1
+" endtry
+endif
+if MESSAGES('E170', "Missing :endwhile")
+ Xpath 16 " X: 16
+endif
+
+if ExtraVim(msgfile)
+" try
+" finally
+" if 1
+" endtry
+endif
+if MESSAGES('E171', "Missing :endif")
+ Xpath 32 " X: 32
+endif
+
+if ExtraVim(msgfile)
+" try
+" finally
+" while 1
+" endtry
+endif
+if MESSAGES('E170', "Missing :endwhile")
+ Xpath 64 " X: 64
+endif
+
+if ExtraVim(msgfile)
+" try
+" throw "a"
+" catch /a/
+" if 1
+" endtry
+endif
+if MESSAGES('E171', "Missing :endif")
+ Xpath 128 " X: 128
+endif
+
+if ExtraVim(msgfile)
+" try
+" throw "a"
+" catch /a/
+" while 1
+" endtry
+endif
+if MESSAGES('E170', "Missing :endwhile")
+ Xpath 256 " X: 256
+endif
+
+call delete(msgfile)
+unlet msgfile
+
+delfunction MESSAGES
+
+Xcheck 511
+
+
+"-------------------------------------------------------------------------------
+" Test 57: v:exception and v:throwpoint for user exceptions {{{1
+"
+" v:exception evaluates to the value of the exception that was caught
+" most recently and is not finished. (A caught exception is finished
+" when the next ":catch", ":finally", or ":endtry" is reached.)
+" v:throwpoint evaluates to the script/function name and line number
+" where that exception has been thrown.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+function! FuncException()
+ let g:exception = v:exception
+endfunction
+
+function! FuncThrowpoint()
+ let g:throwpoint = v:throwpoint
+endfunction
+
+let scriptException = MakeScript("FuncException")
+let scriptThrowPoint = MakeScript("FuncThrowpoint")
+
+command! CmdException let g:exception = v:exception
+command! CmdThrowpoint let g:throwpoint = v:throwpoint
+
+XloopINIT! 1 2
+
+function! CHECK(n, exception, throwname, throwline)
+ XloopNEXT
+ let error = 0
+ if v:exception != a:exception
+ Xout a:n.": v:exception is" v:exception "instead of" a:exception
+ let error = 1
+ endif
+ if v:throwpoint !~ a:throwname
+ let name = escape(a:throwname, '\')
+ Xout a:n.": v:throwpoint (".v:throwpoint.") does not match" name
+ let error = 1
+ endif
+ if v:throwpoint !~ a:throwline
+ let line = escape(a:throwline, '\')
+ Xout a:n.": v:throwpoint (".v:throwpoint.") does not match" line
+ let error = 1
+ endif
+ if error
+ Xloop 1 " X: 0
+ endif
+endfunction
+
+function! T(arg, line)
+ if a:line == 2
+ throw a:arg " in line 2
+ elseif a:line == 4
+ throw a:arg " in line 4
+ elseif a:line == 6
+ throw a:arg " in line 6
+ elseif a:line == 8
+ throw a:arg " in line 8
+ endif
+endfunction
+
+function! G(arg, line)
+ call T(a:arg, a:line)
+endfunction
+
+function! F(arg, line)
+ call G(a:arg, a:line)
+endfunction
+
+let scriptT = MakeScript("T")
+let scriptG = MakeScript("G", scriptT)
+let scriptF = MakeScript("F", scriptG)
+
+try
+ Xpath 32768 " X: 32768
+ call F("oops", 2)
+catch /.*/
+ Xpath 65536 " X: 65536
+ let exception = v:exception
+ let throwpoint = v:throwpoint
+ call CHECK(1, "oops", '\<F\.\.G\.\.T\>', '\<2\>')
+ exec "let exception = v:exception"
+ exec "let throwpoint = v:throwpoint"
+ call CHECK(2, "oops", '\<F\.\.G\.\.T\>', '\<2\>')
+ CmdException
+ CmdThrowpoint
+ call CHECK(3, "oops", '\<F\.\.G\.\.T\>', '\<2\>')
+ call FuncException()
+ call FuncThrowpoint()
+ call CHECK(4, "oops", '\<F\.\.G\.\.T\>', '\<2\>')
+ exec "source" scriptException
+ exec "source" scriptThrowPoint
+ call CHECK(5, "oops", '\<F\.\.G\.\.T\>', '\<2\>')
+ try
+ Xpath 131072 " X: 131072
+ call G("arrgh", 4)
+ catch /.*/
+ Xpath 262144 " X: 262144
+ let exception = v:exception
+ let throwpoint = v:throwpoint
+ call CHECK(6, "arrgh", '\<G\.\.T\>', '\<4\>')
+ try
+ Xpath 524288 " X: 524288
+ let g:arg = "autsch"
+ let g:line = 6
+ exec "source" scriptF
+ catch /.*/
+ Xpath 1048576 " X: 1048576
+ let exception = v:exception
+ let throwpoint = v:throwpoint
+ " Symbolic links in tempname()s are not resolved, whereas resolving
+ " is done for v:throwpoint. Resolve the temporary file name for
+ " scriptT, so that it can be matched against v:throwpoint.
+ call CHECK(7, "autsch", resolve(scriptT), '\<6\>')
+ finally
+ Xpath 2097152 " X: 2097152
+ let exception = v:exception
+ let throwpoint = v:throwpoint
+ call CHECK(8, "arrgh", '\<G\.\.T\>', '\<4\>')
+ try
+ Xpath 4194304 " X: 4194304
+ let g:arg = "brrrr"
+ let g:line = 8
+ exec "source" scriptG
+ catch /.*/
+ Xpath 8388608 " X: 8388608
+ let exception = v:exception
+ let throwpoint = v:throwpoint
+ " Resolve scriptT for matching it against v:throwpoint.
+ call CHECK(9, "brrrr", resolve(scriptT), '\<8\>')
+ finally
+ Xpath 16777216 " X: 16777216
+ let exception = v:exception
+ let throwpoint = v:throwpoint
+ call CHECK(10, "arrgh", '\<G\.\.T\>', '\<4\>')
+ endtry
+ Xpath 33554432 " X: 33554432
+ let exception = v:exception
+ let throwpoint = v:throwpoint
+ call CHECK(11, "arrgh", '\<G\.\.T\>', '\<4\>')
+ endtry
+ Xpath 67108864 " X: 67108864
+ let exception = v:exception
+ let throwpoint = v:throwpoint
+ call CHECK(12, "arrgh", '\<G\.\.T\>', '\<4\>')
+ finally
+ Xpath 134217728 " X: 134217728
+ let exception = v:exception
+ let throwpoint = v:throwpoint
+ call CHECK(13, "oops", '\<F\.\.G\.\.T\>', '\<2\>')
+ endtry
+ Xpath 268435456 " X: 268435456
+ let exception = v:exception
+ let throwpoint = v:throwpoint
+ call CHECK(14, "oops", '\<F\.\.G\.\.T\>', '\<2\>')
+finally
+ Xpath 536870912 " X: 536870912
+ let exception = v:exception
+ let throwpoint = v:throwpoint
+ call CHECK(15, "", '^$', '^$')
+endtry
+
+Xpath 1073741824 " X: 1073741824
+
+unlet exception throwpoint
+delfunction FuncException
+delfunction FuncThrowpoint
+call delete(scriptException)
+call delete(scriptThrowPoint)
+unlet scriptException scriptThrowPoint
+delcommand CmdException
+delcommand CmdThrowpoint
+delfunction T
+delfunction G
+delfunction F
+call delete(scriptT)
+call delete(scriptG)
+call delete(scriptF)
+unlet scriptT scriptG scriptF
+
+Xcheck 2147450880
+
+
+"-------------------------------------------------------------------------------
+"
+" Test 58: v:exception and v:throwpoint for error/interrupt exceptions {{{1
+"
+" v:exception and v:throwpoint work also for error and interrupt
+" exceptions.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+if ExtraVim()
+
+ function! T(line)
+ if a:line == 2
+ delfunction T " error (function in use) in line 2
+ elseif a:line == 4
+ let dummy = 0 " INTERRUPT1 - interrupt in line 4
+ endif
+ endfunction
+
+ while 1
+ try
+ Xpath 1 " X: 1
+ let caught = 0
+ call T(2)
+ catch /.*/
+ let caught = 1
+ if v:exception !~ 'Vim(delfunction):'
+ Xpath 2 " X: 0
+ endif
+ if v:throwpoint !~ '\<T\>'
+ Xpath 4 " X: 0
+ endif
+ if v:throwpoint !~ '\<2\>'
+ Xpath 8 " X: 0
+ endif
+ finally
+ Xpath 16 " X: 16
+ if caught || $VIMNOERRTHROW
+ Xpath 32 " X: 32
+ endif
+ if v:exception != ""
+ Xpath 64 " X: 0
+ endif
+ if v:throwpoint != ""
+ Xpath 128 " X: 0
+ endif
+ break " discard error for $VIMNOERRTHROW
+ endtry
+ endwhile
+
+ Xpath 256 " X: 256
+ if v:exception != ""
+ Xpath 512 " X: 0
+ endif
+ if v:throwpoint != ""
+ Xpath 1024 " X: 0
+ endif
+
+ while 1
+ try
+ Xpath 2048 " X: 2048
+ let caught = 0
+ call T(4)
+ catch /.*/
+ let caught = 1
+ if v:exception != 'Vim:Interrupt'
+ Xpath 4096 " X: 0
+ endif
+ if v:throwpoint !~ '\<T\>'
+ Xpath 8192 " X: 0
+ endif
+ if v:throwpoint !~ '\<4\>'
+ Xpath 16384 " X: 0
+ endif
+ finally
+ Xpath 32768 " X: 32768
+ if caught || $VIMNOINTTHROW
+ Xpath 65536 " X: 65536
+ endif
+ if v:exception != ""
+ Xpath 131072 " X: 0
+ endif
+ if v:throwpoint != ""
+ Xpath 262144 " X: 0
+ endif
+ break " discard error for $VIMNOERRTHROW
+ endtry
+ endwhile
+
+ Xpath 524288 " X: 524288
+ if v:exception != ""
+ Xpath 1048576 " X: 0
+ endif
+ if v:throwpoint != ""
+ Xpath 2097152 " X: 0
+ endif
+
+endif
+
+Xcheck 624945
+
+
+"-------------------------------------------------------------------------------
+"
+" Test 59: v:exception and v:throwpoint when discarding exceptions {{{1
+"
+" When a :catch clause is left by a ":break" etc or an error or
+" interrupt exception, v:exception and v:throwpoint are reset. They
+" are not affected by an exception that is discarded before being
+" caught.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+if ExtraVim()
+
+ XloopINIT! 1 2
+
+ let sfile = expand("<sfile>")
+
+ function! LineNumber()
+ return substitute(substitute(v:throwpoint, g:sfile, '', ""),
+ \ '\D*\(\d*\).*', '\1', "")
+ endfunction
+
+ command! -nargs=1 SetLineNumber
+ \ try | throw "line" | catch /.*/ | let <args> = LineNumber() | endtry
+
+ " Check v:exception/v:throwpoint against second/fourth parameter if
+ " specified, check for being empty else.
+ function! CHECK(n, ...)
+ XloopNEXT
+ let exception = a:0 != 0 ? a:1 : "" " second parameter (optional)
+ let emsg = a:0 != 0 ? a:2 : "" " third parameter (optional)
+ let line = a:0 != 0 ? a:3 : 0 " fourth parameter (optional)
+ let error = 0
+ if emsg != ""
+ " exception is the error number, emsg the English error message text
+ if exception !~ '^E\d\+$'
+ Xout "TODO: Add message number for:" emsg
+ elseif v:lang == "C" || v:lang =~ '^[Ee]n'
+ if exception == "E492" && emsg == "Not an editor command"
+ let exception = '^Vim:' . exception . ': ' . emsg
+ else
+ let exception = '^Vim(\a\+):' . exception . ': ' . emsg
+ endif
+ else
+ if exception == "E492"
+ let exception = '^Vim:' . exception
+ else
+ let exception = '^Vim(\a\+):' . exception
+ endif
+ endif
+ endif
+ if exception == "" && v:exception != ""
+ Xout a:n.": v:exception is set:" v:exception
+ let error = 1
+ elseif exception != "" && v:exception !~ exception
+ Xout a:n.": v:exception (".v:exception.") does not match" exception
+ let error = 1
+ endif
+ if line == 0 && v:throwpoint != ""
+ Xout a:n.": v:throwpoint is set:" v:throwpoint
+ let error = 1
+ elseif line != 0 && v:throwpoint !~ '\<' . line . '\>'
+ Xout a:n.": v:throwpoint (".v:throwpoint.") does not match" line
+ let error = 1
+ endif
+ if !error
+ Xloop 1 " X: 2097151
+ endif
+ endfunction
+
+ while 1
+ try
+ throw "x1"
+ catch /.*/
+ break
+ endtry
+ endwhile
+ call CHECK(1)
+
+ while 1
+ try
+ throw "x2"
+ catch /.*/
+ break
+ finally
+ call CHECK(2)
+ endtry
+ break
+ endwhile
+ call CHECK(3)
+
+ while 1
+ try
+ let errcaught = 0
+ try
+ try
+ throw "x3"
+ catch /.*/
+ SetLineNumber line_before_error
+ asdf
+ endtry
+ catch /.*/
+ let errcaught = 1
+ call CHECK(4, 'E492', "Not an editor command",
+ \ line_before_error + 1)
+ endtry
+ finally
+ if !errcaught && $VIMNOERRTHROW
+ call CHECK(4)
+ endif
+ break " discard error for $VIMNOERRTHROW
+ endtry
+ endwhile
+ call CHECK(5)
+
+ Xpath 2097152 " X: 2097152
+
+ while 1
+ try
+ let intcaught = 0
+ try
+ try
+ throw "x4"
+ catch /.*/
+ SetLineNumber two_lines_before_interrupt
+ "INTERRUPT
+ let dummy = 0
+ endtry
+ catch /.*/
+ let intcaught = 1
+ call CHECK(6, "Vim:Interrupt", '',
+ \ two_lines_before_interrupt + 2)
+ endtry
+ finally
+ if !intcaught && $VIMNOINTTHROW
+ call CHECK(6)
+ endif
+ break " discard interrupt for $VIMNOINTTHROW
+ endtry
+ endwhile
+ call CHECK(7)
+
+ Xpath 4194304 " X: 4194304
+
+ while 1
+ try
+ let errcaught = 0
+ try
+ try
+" if 1
+ SetLineNumber line_before_throw
+ throw "x5"
+ " missing endif
+ catch /.*/
+ Xpath 8388608 " X: 0
+ endtry
+ catch /.*/
+ let errcaught = 1
+ call CHECK(8, 'E171', "Missing :endif", line_before_throw + 3)
+ endtry
+ finally
+ if !errcaught && $VIMNOERRTHROW
+ call CHECK(8)
+ endif
+ break " discard error for $VIMNOERRTHROW
+ endtry
+ endwhile
+ call CHECK(9)
+
+ Xpath 16777216 " X: 16777216
+
+ try
+ while 1
+ try
+ throw "x6"
+ finally
+ break
+ endtry
+ break
+ endwhile
+ catch /.*/
+ Xpath 33554432 " X: 0
+ endtry
+ call CHECK(10)
+
+ try
+ while 1
+ try
+ throw "x7"
+ finally
+ break
+ endtry
+ break
+ endwhile
+ catch /.*/
+ Xpath 67108864 " X: 0
+ finally
+ call CHECK(11)
+ endtry
+ call CHECK(12)
+
+ while 1
+ try
+ let errcaught = 0
+ try
+ try
+ throw "x8"
+ finally
+ SetLineNumber line_before_error
+ asdf
+ endtry
+ catch /.*/
+ let errcaught = 1
+ call CHECK(13, 'E492', "Not an editor command",
+ \ line_before_error + 1)
+ endtry
+ finally
+ if !errcaught && $VIMNOERRTHROW
+ call CHECK(13)
+ endif
+ break " discard error for $VIMNOERRTHROW
+ endtry
+ endwhile
+ call CHECK(14)
+
+ Xpath 134217728 " X: 134217728
+
+ while 1
+ try
+ let intcaught = 0
+ try
+ try
+ throw "x9"
+ finally
+ SetLineNumber two_lines_before_interrupt
+ "INTERRUPT
+ endtry
+ catch /.*/
+ let intcaught = 1
+ call CHECK(15, "Vim:Interrupt", '',
+ \ two_lines_before_interrupt + 2)
+ endtry
+ finally
+ if !intcaught && $VIMNOINTTHROW
+ call CHECK(15)
+ endif
+ break " discard interrupt for $VIMNOINTTHROW
+ endtry
+ endwhile
+ call CHECK(16)
+
+ Xpath 268435456 " X: 268435456
+
+ while 1
+ try
+ let errcaught = 0
+ try
+ try
+" if 1
+ SetLineNumber line_before_throw
+ throw "x10"
+ " missing endif
+ finally
+ call CHECK(17)
+ endtry
+ catch /.*/
+ let errcaught = 1
+ call CHECK(18, 'E171', "Missing :endif", line_before_throw + 3)
+ endtry
+ finally
+ if !errcaught && $VIMNOERRTHROW
+ call CHECK(18)
+ endif
+ break " discard error for $VIMNOERRTHROW
+ endtry
+ endwhile
+ call CHECK(19)
+
+ Xpath 536870912 " X: 536870912
+
+ while 1
+ try
+ let errcaught = 0
+ try
+ try
+" if 1
+ SetLineNumber line_before_throw
+ throw "x11"
+ " missing endif
+ endtry
+ catch /.*/
+ let errcaught = 1
+ call CHECK(20, 'E171', "Missing :endif", line_before_throw + 3)
+ endtry
+ finally
+ if !errcaught && $VIMNOERRTHROW
+ call CHECK(20)
+ endif
+ break " discard error for $VIMNOERRTHROW
+ endtry
+ endwhile
+ call CHECK(21)
+
+ Xpath 1073741824 " X: 1073741824
+
+endif
+
+Xcheck 2038431743
+
+
+"-------------------------------------------------------------------------------
+"
+" Test 60: (Re)throwing v:exception; :echoerr. {{{1
+"
+" A user exception can be rethrown after catching by throwing
+" v:exception. An error or interrupt exception cannot be rethrown
+" because Vim exceptions cannot be faked. A Vim exception using the
+" value of v:exception can, however, be triggered by the :echoerr
+" command.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+try
+ try
+ Xpath 1 " X: 1
+ throw "oops"
+ catch /oops/
+ Xpath 2 " X: 2
+ throw v:exception " rethrow user exception
+ catch /.*/
+ Xpath 4 " X: 0
+ endtry
+catch /^oops$/ " catches rethrown user exception
+ Xpath 8 " X: 8
+catch /.*/
+ Xpath 16 " X: 0
+endtry
+
+function! F()
+ try
+ let caught = 0
+ try
+ Xpath 32 " X: 32
+ write /n/o/n/w/r/i/t/a/b/l/e/_/f/i/l/e
+ Xpath 64 " X: 0
+ Xout "did_emsg was reset before executing " .
+ \ "BufWritePost autocommands."
+ catch /^Vim(write):/
+ let caught = 1
+ throw v:exception " throw error: cannot fake Vim exception
+ catch /.*/
+ Xpath 128 " X: 0
+ finally
+ Xpath 256 " X: 256
+ if !caught && !$VIMNOERRTHROW
+ Xpath 512 " X: 0
+ endif
+ endtry
+ catch /^Vim(throw):/ " catches throw error
+ let caught = caught + 1
+ catch /.*/
+ Xpath 1024 " X: 0
+ finally
+ Xpath 2048 " X: 2048
+ if caught != 2
+ if !caught && !$VIMNOERRTHROW
+ Xpath 4096 " X: 0
+ elseif caught
+ Xpath 8192 " X: 0
+ endif
+ return | " discard error for $VIMNOERRTHROW
+ endif
+ endtry
+endfunction
+
+call F()
+delfunction F
+
+function! G()
+ try
+ let caught = 0
+ try
+ Xpath 16384 " X: 16384
+ asdf
+ catch /^Vim/ " catch error exception
+ let caught = 1
+ " Trigger Vim error exception with value specified after :echoerr
+ let value = substitute(v:exception, '^Vim\((.*)\)\=:', '', "")
+ echoerr value
+ catch /.*/
+ Xpath 32768 " X: 0
+ finally
+ Xpath 65536 " X: 65536
+ if !caught
+ if !$VIMNOERRTHROW
+ Xpath 131072 " X: 0
+ else
+ let value = "Error"
+ echoerr value
+ endif
+ endif
+ endtry
+ catch /^Vim(echoerr):/
+ let caught = caught + 1
+ if v:exception !~ value
+ Xpath 262144 " X: 0
+ endif
+ catch /.*/
+ Xpath 524288 " X: 0
+ finally
+ Xpath 1048576 " X: 1048576
+ if caught != 2
+ if !caught && !$VIMNOERRTHROW
+ Xpath 2097152 " X: 0
+ elseif caught
+ Xpath 4194304 " X: 0
+ endif
+ return | " discard error for $VIMNOERRTHROW
+ endif
+ endtry
+endfunction
+
+call G()
+delfunction G
+
+unlet! value caught
+
+if ExtraVim()
+ try
+ let errcaught = 0
+ try
+ Xpath 8388608 " X: 8388608
+ let intcaught = 0
+ "INTERRUPT
+ catch /^Vim:/ " catch interrupt exception
+ let intcaught = 1
+ " Trigger Vim error exception with value specified after :echoerr
+ echoerr substitute(v:exception, '^Vim\((.*)\)\=:', '', "")
+ catch /.*/
+ Xpath 16777216 " X: 0
+ finally
+ Xpath 33554432 " X: 33554432
+ if !intcaught
+ if !$VIMNOINTTHROW
+ Xpath 67108864 " X: 0
+ else
+ echoerr "Interrupt"
+ endif
+ endif
+ endtry
+ catch /^Vim(echoerr):/
+ let errcaught = 1
+ if v:exception !~ "Interrupt"
+ Xpath 134217728 " X: 0
+ endif
+ finally
+ Xpath 268435456 " X: 268435456
+ if !errcaught && !$VIMNOERRTHROW
+ Xpath 536870912 " X: 0
+ endif
+ endtry
+endif
+
+Xcheck 311511339
+
+
+"-------------------------------------------------------------------------------
+" Test 61: Catching interrupt exceptions {{{1
+"
+" When an interrupt occurs inside a :try/:endtry region, an
+" interrupt exception is thrown and can be caught. Its value is
+" "Vim:Interrupt". If the interrupt occurs after an error or a :throw
+" but before a matching :catch is reached, all following :catches of
+" that try block are ignored, but the interrupt exception can be
+" caught by the next surrounding try conditional. An interrupt is
+" ignored when there is a previous interrupt that has not been caught
+" or causes a :finally clause to be executed.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+if ExtraVim()
+
+ while 1
+ try
+ try
+ Xpath 1 " X: 1
+ let caught = 0
+ "INTERRUPT
+ Xpath 2 " X: 0
+ catch /^Vim:Interrupt$/
+ let caught = 1
+ finally
+ Xpath 4 " X: 4
+ if caught || $VIMNOINTTHROW
+ Xpath 8 " X: 8
+ endif
+ endtry
+ catch /.*/
+ Xpath 16 " X: 0
+ Xout v:exception "in" v:throwpoint
+ finally
+ break " discard interrupt for $VIMNOINTTHROW
+ endtry
+ endwhile
+
+ while 1
+ try
+ try
+ let caught = 0
+ try
+ Xpath 32 " X: 32
+ asdf
+ Xpath 64 " X: 0
+ catch /do_not_catch/
+ Xpath 128 " X: 0
+ catch /.*/ "INTERRUPT - throw interrupt if !$VIMNOERRTHROW
+ Xpath 256 " X: 0
+ catch /.*/
+ Xpath 512 " X: 0
+ finally "INTERRUPT - throw interrupt if $VIMNOERRTHROW
+ Xpath 1024 " X: 1024
+ endtry
+ catch /^Vim:Interrupt$/
+ let caught = 1
+ finally
+ Xpath 2048 " X: 2048
+ if caught || $VIMNOINTTHROW
+ Xpath 4096 " X: 4096
+ endif
+ endtry
+ catch /.*/
+ Xpath 8192 " X: 0
+ Xout v:exception "in" v:throwpoint
+ finally
+ break " discard interrupt for $VIMNOINTTHROW
+ endtry
+ endwhile
+
+ while 1
+ try
+ try
+ let caught = 0
+ try
+ Xpath 16384 " X: 16384
+ throw "x"
+ Xpath 32768 " X: 0
+ catch /do_not_catch/
+ Xpath 65536 " X: 0
+ catch /x/ "INTERRUPT
+ Xpath 131072 " X: 0
+ catch /.*/
+ Xpath 262144 " X: 0
+ endtry
+ catch /^Vim:Interrupt$/
+ let caught = 1
+ finally
+ Xpath 524288 " X: 524288
+ if caught || $VIMNOINTTHROW
+ Xpath 1048576 " X: 1048576
+ endif
+ endtry
+ catch /.*/
+ Xpath 2097152 " X: 0
+ Xout v:exception "in" v:throwpoint
+ finally
+ break " discard interrupt for $VIMNOINTTHROW
+ endtry
+ endwhile
+
+ while 1
+ try
+ let caught = 0
+ try
+ Xpath 4194304 " X: 4194304
+ "INTERRUPT
+ Xpath 8388608 " X: 0
+ catch /do_not_catch/ "INTERRUPT
+ Xpath 16777216 " X: 0
+ catch /^Vim:Interrupt$/
+ let caught = 1
+ finally
+ Xpath 33554432 " X: 33554432
+ if caught || $VIMNOINTTHROW
+ Xpath 67108864 " X: 67108864
+ endif
+ endtry
+ catch /.*/
+ Xpath 134217728 " X: 0
+ Xout v:exception "in" v:throwpoint
+ finally
+ break " discard interrupt for $VIMNOINTTHROW
+ endtry
+ endwhile
+
+ Xpath 268435456 " X: 268435456
+
+endif
+
+Xcheck 374889517
+
+
+"-------------------------------------------------------------------------------
+" Test 62: Catching error exceptions {{{1
+"
+" An error inside a :try/:endtry region is converted to an exception
+" and can be caught. The error exception has a "Vim(cmdname):" prefix
+" where cmdname is the name of the failing command, or a "Vim:" prefix
+" if no command name is known. The "Vim" prefixes cannot be faked.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+function! MSG(enr, emsg)
+ let english = v:lang == "C" || v:lang =~ '^[Ee]n'
+ if a:enr == ""
+ Xout "TODO: Add message number for:" a:emsg
+ let v:errmsg = ":" . v:errmsg
+ endif
+ let match = 1
+ if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg)
+ let match = 0
+ if v:errmsg == ""
+ Xout "Message missing."
+ else
+ let v:errmsg = escape(v:errmsg, '"')
+ Xout "Unexpected message:" v:errmsg
+ endif
+ endif
+ return match
+endfunction
+
+while 1
+ try
+ try
+ let caught = 0
+ unlet novar
+ catch /^Vim(unlet):/
+ let caught = 1
+ let v:errmsg = substitute(v:exception, '^Vim(unlet):', '', "")
+ finally
+ Xpath 1 " X: 1
+ if !caught && !$VIMNOERRTHROW
+ Xpath 2 " X: 0
+ endif
+ if !MSG('E108', "No such variable")
+ Xpath 4 " X: 0
+ endif
+ endtry
+ catch /.*/
+ Xpath 8 " X: 0
+ Xout v:exception "in" v:throwpoint
+ finally
+ break " discard error for $VIMNOERRTHROW
+ endtry
+endwhile
+
+while 1
+ try
+ try
+ let caught = 0
+ throw novar " error in :throw
+ catch /^Vim(throw):/
+ let caught = 1
+ let v:errmsg = substitute(v:exception, '^Vim(throw):', '', "")
+ finally
+ Xpath 16 " X: 16
+ if !caught && !$VIMNOERRTHROW
+ Xpath 32 " X: 0
+ endif
+ if caught ? !MSG('E121', "Undefined variable")
+ \ : !MSG('E15', "Invalid expression")
+ Xpath 64 " X: 0
+ endif
+ endtry
+ catch /.*/
+ Xpath 128 " X: 0
+ Xout v:exception "in" v:throwpoint
+ finally
+ break " discard error for $VIMNOERRTHROW
+ endtry
+endwhile
+
+while 1
+ try
+ try
+ let caught = 0
+ throw "Vim:faked" " error: cannot fake Vim exception
+ catch /^Vim(throw):/
+ let caught = 1
+ let v:errmsg = substitute(v:exception, '^Vim(throw):', '', "")
+ finally
+ Xpath 256 " X: 256
+ if !caught && !$VIMNOERRTHROW
+ Xpath 512 " X: 0
+ endif
+ if !MSG('E608', "Cannot :throw exceptions with 'Vim' prefix")
+ Xpath 1024 " X: 0
+ endif
+ endtry
+ catch /.*/
+ Xpath 2048 " X: 0
+ Xout v:exception "in" v:throwpoint
+ finally
+ break " discard error for $VIMNOERRTHROW
+ endtry
+endwhile
+
+function! F()
+ while 1
+ " Missing :endwhile
+endfunction
+
+while 1
+ try
+ try
+ let caught = 0
+ call F()
+ catch /^Vim(endfunction):/
+ let caught = 1
+ let v:errmsg = substitute(v:exception, '^Vim(endfunction):', '', "")
+ finally
+ Xpath 4096 " X: 4096
+ if !caught && !$VIMNOERRTHROW
+ Xpath 8192 " X: 0
+ endif
+ if !MSG('E170', "Missing :endwhile")
+ Xpath 16384 " X: 0
+ endif
+ endtry
+ catch /.*/
+ Xpath 32768 " X: 0
+ Xout v:exception "in" v:throwpoint
+ finally
+ break " discard error for $VIMNOERRTHROW
+ endtry
+endwhile
+
+while 1
+ try
+ try
+ let caught = 0
+ ExecAsScript F
+ catch /^Vim:/
+ let caught = 1
+ let v:errmsg = substitute(v:exception, '^Vim:', '', "")
+ finally
+ Xpath 65536 " X: 65536
+ if !caught && !$VIMNOERRTHROW
+ Xpath 131072 " X: 0
+ endif
+ if !MSG('E170', "Missing :endwhile")
+ Xpath 262144 " X: 0
+ endif
+ endtry
+ catch /.*/
+ Xpath 524288 " X: 0
+ Xout v:exception "in" v:throwpoint
+ finally
+ break " discard error for $VIMNOERRTHROW
+ endtry
+endwhile
+
+function! G()
+ call G()
+endfunction
+
+while 1
+ try
+ let mfd_save = &mfd
+ set mfd=3
+ try
+ let caught = 0
+ call G()
+ catch /^Vim(call):/
+ let caught = 1
+ let v:errmsg = substitute(v:exception, '^Vim(call):', '', "")
+ finally
+ Xpath 1048576 " X: 1048576
+ if !caught && !$VIMNOERRTHROW
+ Xpath 2097152 " X: 0
+ endif
+ if !MSG('E132', "Function call depth is higher than 'maxfuncdepth'")
+ Xpath 4194304 " X: 0
+ endif
+ endtry
+ catch /.*/
+ Xpath 8388608 " X: 0
+ Xout v:exception "in" v:throwpoint
+ finally
+ let &mfd = mfd_save
+ break " discard error for $VIMNOERRTHROW
+ endtry
+endwhile
+
+function! H()
+ return H()
+endfunction
+
+while 1
+ try
+ let mfd_save = &mfd
+ set mfd=3
+ try
+ let caught = 0
+ call H()
+ catch /^Vim(return):/
+ let caught = 1
+ let v:errmsg = substitute(v:exception, '^Vim(return):', '', "")
+ finally
+ Xpath 16777216 " X: 16777216
+ if !caught && !$VIMNOERRTHROW
+ Xpath 33554432 " X: 0
+ endif
+ if !MSG('E132', "Function call depth is higher than 'maxfuncdepth'")
+ Xpath 67108864 " X: 0
+ endif
+ endtry
+ catch /.*/
+ Xpath 134217728 " X: 0
+ Xout v:exception "in" v:throwpoint
+ finally
+ let &mfd = mfd_save
+ break " discard error for $VIMNOERRTHROW
+ endtry
+endwhile
+
+unlet! caught mfd_save
+delfunction F
+delfunction G
+delfunction H
+Xpath 268435456 " X: 268435456
+
+Xcheck 286331153
+
+" Leave MSG() for the next test.
+
+
+"-------------------------------------------------------------------------------
+" Test 63: Suppressing error exceptions by :silent!. {{{1
+"
+" A :silent! command inside a :try/:endtry region suppresses the
+" conversion of errors to an exception and the immediate abortion on
+" error. When the commands executed by the :silent! themselves open
+" a new :try/:endtry region, conversion of errors to exception and
+" immediate abortion is switched on again - until the next :silent!
+" etc. The :silent! has the effect of setting v:errmsg to the error
+" message text (without displaying it) and continuing with the next
+" script line.
+"
+" When a command triggering autocommands is executed by :silent!
+" inside a :try/:endtry, the autocommand execution is not suppressed
+" on error.
+"
+" This test reuses the function MSG() from the previous test.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+XloopINIT! 1 4
+
+let taken = ""
+
+function! S(n) abort
+ XloopNEXT
+ let g:taken = g:taken . "E" . a:n
+ let v:errmsg = ""
+ exec "asdf" . a:n
+
+ " Check that ":silent!" continues:
+ Xloop 1
+
+ " Check that ":silent!" sets "v:errmsg":
+ if MSG('E492', "Not an editor command")
+ Xloop 2
+ endif
+endfunction
+
+function! Foo()
+ while 1
+ try
+ try
+ let caught = 0
+ " This is not silent:
+ call S(3) " X: 0 * 16
+ catch /^Vim:/
+ let caught = 1
+ let errmsg3 = substitute(v:exception, '^Vim:', '', "")
+ silent! call S(4) " X: 3 * 64
+ finally
+ if !caught
+ let errmsg3 = v:errmsg
+ " Do call S(4) here if not executed in :catch.
+ silent! call S(4)
+ endif
+ Xpath 1048576 " X: 1048576
+ if !caught && !$VIMNOERRTHROW
+ Xpath 2097152 " X: 0
+ endif
+ let v:errmsg = errmsg3
+ if !MSG('E492', "Not an editor command")
+ Xpath 4194304 " X: 0
+ endif
+ silent! call S(5) " X: 3 * 256
+ " Break out of try conditionals that cover ":silent!". This also
+ " discards the aborting error when $VIMNOERRTHROW is non-zero.
+ break
+ endtry
+ catch /.*/
+ Xpath 8388608 " X: 0
+ Xout v:exception "in" v:throwpoint
+ endtry
+ endwhile
+ " This is a double ":silent!" (see caller).
+ silent! call S(6) " X: 3 * 1024
+endfunction
+
+function! Bar()
+ try
+ silent! call S(2) " X: 3 * 4
+ " X: 3 * 4096
+ silent! execute "call Foo() | call S(7)"
+ silent! call S(8) " X: 3 * 16384
+ endtry " normal end of try cond that covers ":silent!"
+ " This has a ":silent!" from the caller:
+ call S(9) " X: 3 * 65536
+endfunction
+
+silent! call S(1) " X: 3 * 1
+silent! call Bar()
+silent! call S(10) " X: 3 * 262144
+
+let expected = "E1E2E3E4E5E6E7E8E9E10"
+if taken != expected
+ Xpath 16777216 " X: 0
+ Xout "'taken' is" taken "instead of" expected
+endif
+
+augroup TMP
+ autocmd BufWritePost * Xpath 33554432 " X: 33554432
+augroup END
+
+Xpath 67108864 " X: 67108864
+write /i/m/p/o/s/s/i/b/l/e
+Xpath 134217728 " X: 134217728
+
+autocmd! TMP
+unlet! caught errmsg3 taken expected
+delfunction S
+delfunction Foo
+delfunction Bar
+delfunction MSG
+
+Xcheck 236978127
+
+
+"-------------------------------------------------------------------------------
+" Test 64: Error exceptions after error, interrupt or :throw {{{1
+"
+" When an error occurs after an interrupt or a :throw but before
+" a matching :catch is reached, all following :catches of that try
+" block are ignored, but the error exception can be caught by the next
+" surrounding try conditional. Any previous error exception is
+" discarded. An error is ignored when there is a previous error that
+" has not been caught.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+if ExtraVim()
+
+ while 1
+ try
+ try
+ Xpath 1 " X: 1
+ let caught = 0
+ while 1
+" if 1
+ " Missing :endif
+ endwhile " throw error exception
+ catch /^Vim(/
+ let caught = 1
+ finally
+ Xpath 2 " X: 2
+ if caught || $VIMNOERRTHROW
+ Xpath 4 " X: 4
+ endif
+ endtry
+ catch /.*/
+ Xpath 8 " X: 0
+ Xout v:exception "in" v:throwpoint
+ finally
+ break " discard error for $VIMNOERRTHROW
+ endtry
+ endwhile
+
+ while 1
+ try
+ try
+ Xpath 16 " X: 16
+ let caught = 0
+ try
+" if 1
+ " Missing :endif
+ catch /.*/ " throw error exception
+ Xpath 32 " X: 0
+ catch /.*/
+ Xpath 64 " X: 0
+ endtry
+ catch /^Vim(/
+ let caught = 1
+ finally
+ Xpath 128 " X: 128
+ if caught || $VIMNOERRTHROW
+ Xpath 256 " X: 256
+ endif
+ endtry
+ catch /.*/
+ Xpath 512 " X: 0
+ Xout v:exception "in" v:throwpoint
+ finally
+ break " discard error for $VIMNOERRTHROW
+ endtry
+ endwhile
+
+ while 1
+ try
+ try
+ let caught = 0
+ try
+ Xpath 1024 " X: 1024
+ "INTERRUPT
+ catch /do_not_catch/
+ Xpath 2048 " X: 0
+" if 1
+ " Missing :endif
+ catch /.*/ " throw error exception
+ Xpath 4096 " X: 0
+ catch /.*/
+ Xpath 8192 " X: 0
+ endtry
+ catch /^Vim(/
+ let caught = 1
+ finally
+ Xpath 16384 " X: 16384
+ if caught || $VIMNOERRTHROW
+ Xpath 32768 " X: 32768
+ endif
+ endtry
+ catch /.*/
+ Xpath 65536 " X: 0
+ Xout v:exception "in" v:throwpoint
+ finally
+ break " discard error for $VIMNOERRTHROW
+ endtry
+ endwhile
+
+ while 1
+ try
+ try
+ let caught = 0
+ try
+ Xpath 131072 " X: 131072
+ throw "x"
+ catch /do_not_catch/
+ Xpath 262144 " X: 0
+" if 1
+ " Missing :endif
+ catch /x/ " throw error exception
+ Xpath 524288 " X: 0
+ catch /.*/
+ Xpath 1048576 " X: 0
+ endtry
+ catch /^Vim(/
+ let caught = 1
+ finally
+ Xpath 2097152 " X: 2097152
+ if caught || $VIMNOERRTHROW
+ Xpath 4194304 " X: 4194304
+ endif
+ endtry
+ catch /.*/
+ Xpath 8388608 " X: 0
+ Xout v:exception "in" v:throwpoint
+ finally
+ break " discard error for $VIMNOERRTHROW
+ endtry
+ endwhile
+
+ while 1
+ try
+ try
+ let caught = 0
+ Xpath 16777216 " X: 16777216
+" endif " :endif without :if; throw error exception
+" if 1
+ " Missing :endif
+ catch /do_not_catch/ " ignore new error
+ Xpath 33554432 " X: 0
+ catch /^Vim(endif):/
+ let caught = 1
+ catch /^Vim(/
+ Xpath 67108864 " X: 0
+ finally
+ Xpath 134217728 " X: 134217728
+ if caught || $VIMNOERRTHROW
+ Xpath 268435456 " X: 268435456
+ endif
+ endtry
+ catch /.*/
+ Xpath 536870912 " X: 0
+ Xout v:exception "in" v:throwpoint
+ finally
+ break " discard error for $VIMNOERRTHROW
+ endtry
+ endwhile
+
+ Xpath 1073741824 " X: 1073741824
+
+endif
+
+Xcheck 1499645335
+
+
+"-------------------------------------------------------------------------------
+" Test 65: Errors in the /pattern/ argument of a :catch {{{1
+"
+" On an error in the /pattern/ argument of a :catch, the :catch does
+" not match. Any following :catches of the same :try/:endtry don't
+" match either. Finally clauses are executed.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+function! MSG(enr, emsg)
+ let english = v:lang == "C" || v:lang =~ '^[Ee]n'
+ if a:enr == ""
+ Xout "TODO: Add message number for:" a:emsg
+ let v:errmsg = ":" . v:errmsg
+ endif
+ let match = 1
+ if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg)
+ let match = 0
+ if v:errmsg == ""
+ Xout "Message missing."
+ else
+ let v:errmsg = escape(v:errmsg, '"')
+ Xout "Unexpected message:" v:errmsg
+ endif
+ endif
+ return match
+endfunction
+
+try
+ try
+ Xpath 1 " X: 1
+ throw "oops"
+ catch /^oops$/
+ Xpath 2 " X: 2
+ catch /\)/ " not checked; exception has already been caught
+ Xpath 4 " X: 0
+ endtry
+ Xpath 8 " X: 8
+catch /.*/
+ Xpath 16 " X: 0
+ Xout v:exception "in" v:throwpoint
+endtry
+
+function! F()
+ try
+ let caught = 0
+ try
+ try
+ Xpath 32 " X: 32
+ throw "ab"
+ catch /abc/ " does not catch
+ Xpath 64 " X: 0
+ catch /\)/ " error; discards exception
+ Xpath 128 " X: 0
+ catch /.*/ " not checked
+ Xpath 256 " X: 0
+ finally
+ Xpath 512 " X: 512
+ endtry
+ Xpath 1024 " X: 0
+ catch /^ab$/ " checked, but original exception is discarded
+ Xpath 2048 " X: 0
+ catch /^Vim(catch):/
+ let caught = 1
+ let v:errmsg = substitute(v:exception, '^Vim(catch):', '', "")
+ finally
+ Xpath 4096 " X: 4096
+ if !caught && !$VIMNOERRTHROW
+ Xpath 8192 " X: 0
+ endif
+ if caught ? !MSG('E55', 'Unmatched \\)')
+ \ : !MSG('E475', "Invalid argument")
+ Xpath 16384 " X: 0
+ endif
+ if !caught
+ return | " discard error
+ endif
+ endtry
+ catch /.*/
+ Xpath 32768 " X: 0
+ Xout v:exception "in" v:throwpoint
+ endtry
+endfunction
+
+call F()
+Xpath 65536 " X: 65536
+
+delfunction MSG
+delfunction F
+unlet! caught
+
+Xcheck 70187
+
+
+"-------------------------------------------------------------------------------
+" Test 66: Stop range :call on error, interrupt, or :throw {{{1
+"
+" When a function which is multiply called for a range since it
+" doesn't handle the range itself has an error in a command
+" dynamically enclosed by :try/:endtry or gets an interrupt or
+" executes a :throw, no more calls for the remaining lines in the
+" range are made. On an error in a command not dynamically enclosed
+" by :try/:endtry, the function is executed again for the remaining
+" lines in the range.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+if ExtraVim()
+
+ let file = tempname()
+ exec "edit" file
+
+ insert
+line 1
+line 2
+line 3
+.
+
+ XloopINIT! 1 2
+
+ let taken = ""
+ let expected = "G1EF1E(1)F1E(2)F1E(3)G2EF2E(1)G3IF3I(1)G4TF4T(1)G5AF5A(1)"
+
+ function! F(reason, n) abort
+ let g:taken = g:taken . "F" . a:n .
+ \ substitute(a:reason, '\(\l\).*', '\u\1', "") .
+ \ "(" . line(".") . ")"
+
+ if a:reason == "error"
+ asdf
+ elseif a:reason == "interrupt"
+ "INTERRUPT
+ let dummy = 0
+ elseif a:reason == "throw"
+ throw "xyz"
+ elseif a:reason == "aborting error"
+ XloopNEXT
+ if g:taken != g:expected
+ Xloop 1 " X: 0
+ Xout "'taken' is" g:taken "instead of" g:expected
+ endif
+ try
+ bwipeout!
+ call delete(file)
+ asdf
+ endtry
+ endif
+ endfunction
+
+ function! G(reason, n)
+ let g:taken = g:taken . "G" . a:n .
+ \ substitute(a:reason, '\(\l\).*', '\u\1', "")
+ 1,3call F(a:reason, a:n)
+ endfunction
+
+ Xpath 8 " X: 8
+ call G("error", 1)
+ try
+ Xpath 16 " X: 16
+ try
+ call G("error", 2)
+ Xpath 32 " X: 0
+ finally
+ Xpath 64 " X: 64
+ try
+ call G("interrupt", 3)
+ Xpath 128 " X: 0
+ finally
+ Xpath 256 " X: 256
+ try
+ call G("throw", 4)
+ Xpath 512 " X: 0
+ endtry
+ endtry
+ endtry
+ catch /xyz/
+ Xpath 1024 " X: 1024
+ catch /.*/
+ Xpath 2048 " X: 0
+ Xout v:exception "in" ExtraVimThrowpoint()
+ endtry
+ Xpath 4096 " X: 4096
+ call G("aborting error", 5)
+ Xpath 8192 " X: 0
+ Xout "'taken' is" taken "instead of" expected
+
+endif
+
+Xcheck 5464
+
+
+"-------------------------------------------------------------------------------
+" Test 67: :throw across :call command {{{1
+"
+" On a call command, an exception might be thrown when evaluating the
+" function name, during evaluation of the arguments, or when the
+" function is being executed. The exception can be caught by the
+" caller.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+function! THROW(x, n)
+ if a:n == 1
+ Xpath 1 " X: 1
+ elseif a:n == 2
+ Xpath 2 " X: 2
+ elseif a:n == 3
+ Xpath 4 " X: 4
+ endif
+ throw a:x
+endfunction
+
+function! NAME(x, n)
+ if a:n == 1
+ Xpath 8 " X: 0
+ elseif a:n == 2
+ Xpath 16 " X: 16
+ elseif a:n == 3
+ Xpath 32 " X: 32
+ elseif a:n == 4
+ Xpath 64 " X: 64
+ endif
+ return a:x
+endfunction
+
+function! ARG(x, n)
+ if a:n == 1
+ Xpath 128 " X: 0
+ elseif a:n == 2
+ Xpath 256 " X: 0
+ elseif a:n == 3
+ Xpath 512 " X: 512
+ elseif a:n == 4
+ Xpath 1024 " X: 1024
+ endif
+ return a:x
+endfunction
+
+function! F(x, n)
+ if a:n == 2
+ Xpath 2048 " X: 0
+ elseif a:n == 4
+ Xpath 4096 " X: 4096
+ endif
+endfunction
+
+while 1
+ try
+ let error = 0
+ let v:errmsg = ""
+
+ while 1
+ try
+ Xpath 8192 " X: 8192
+ call {NAME(THROW("name", 1), 1)}(ARG(4711, 1), 1)
+ Xpath 16384 " X: 0
+ catch /^name$/
+ Xpath 32768 " X: 32768
+ catch /.*/
+ let error = 1
+ Xout "1:" v:exception "in" v:throwpoint
+ finally
+ if !error && $VIMNOERRTHROW && v:errmsg != ""
+ let error = 1
+ Xout "1:" v:errmsg
+ endif
+ if error
+ Xpath 65536 " X: 0
+ endif
+ let error = 0
+ let v:errmsg = ""
+ break " discard error for $VIMNOERRTHROW
+ endtry
+ endwhile
+
+ while 1
+ try
+ Xpath 131072 " X: 131072
+ call {NAME("F", 2)}(ARG(THROW("arg", 2), 2), 2)
+ Xpath 262144 " X: 0
+ catch /^arg$/
+ Xpath 524288 " X: 524288
+ catch /.*/
+ let error = 1
+ Xout "2:" v:exception "in" v:throwpoint
+ finally
+ if !error && $VIMNOERRTHROW && v:errmsg != ""
+ let error = 1
+ Xout "2:" v:errmsg
+ endif
+ if error
+ Xpath 1048576 " X: 0
+ endif
+ let error = 0
+ let v:errmsg = ""
+ break " discard error for $VIMNOERRTHROW
+ endtry
+ endwhile
+
+ while 1
+ try
+ Xpath 2097152 " X: 2097152
+ call {NAME("THROW", 3)}(ARG("call", 3), 3)
+ Xpath 4194304 " X: 0
+ catch /^call$/
+ Xpath 8388608 " X: 8388608
+ catch /^0$/ " default return value
+ Xpath 16777216 " X: 0
+ Xout "3:" v:throwpoint
+ catch /.*/
+ let error = 1
+ Xout "3:" v:exception "in" v:throwpoint
+ finally
+ if !error && $VIMNOERRTHROW && v:errmsg != ""
+ let error = 1
+ Xout "3:" v:errmsg
+ endif
+ if error
+ Xpath 33554432 " X: 0
+ endif
+ let error = 0
+ let v:errmsg = ""
+ break " discard error for $VIMNOERRTHROW
+ endtry
+ endwhile
+
+ while 1
+ try
+ Xpath 67108864 " X: 67108864
+ call {NAME("F", 4)}(ARG(4711, 4), 4)
+ Xpath 134217728 " X: 134217728
+ catch /.*/
+ let error = 1
+ Xout "4:" v:exception "in" v:throwpoint
+ finally
+ if !error && $VIMNOERRTHROW && v:errmsg != ""
+ let error = 1
+ Xout "4:" v:errmsg
+ endif
+ if error
+ Xpath 268435456 " X: 0
+ endif
+ let error = 0
+ let v:errmsg = ""
+ break " discard error for $VIMNOERRTHROW
+ endtry
+ endwhile
+
+ catch /^0$/ " default return value
+ Xpath 536870912 " X: 0
+ Xout v:throwpoint
+ catch /.*/
+ let error = 1
+ Xout v:exception "in" v:throwpoint
+ finally
+ if !error && $VIMNOERRTHROW && v:errmsg != ""
+ let error = 1
+ Xout v:errmsg
+ endif
+ if error
+ Xpath 1073741824 " X: 0
+ endif
+ break " discard error for $VIMNOERRTHROW
+ endtry
+endwhile
+
+unlet error
+delfunction F
+
+Xcheck 212514423
+
+" Leave THROW(), NAME(), and ARG() for the next test.
+
+
+"-------------------------------------------------------------------------------
+" Test 68: :throw across function calls in expressions {{{1
+"
+" On a function call within an expression, an exception might be
+" thrown when evaluating the function name, during evaluation of the
+" arguments, or when the function is being executed. The exception
+" can be caught by the caller.
+"
+" This test reuses the functions THROW(), NAME(), and ARG() from the
+" previous test.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+function! F(x, n)
+ if a:n == 2
+ Xpath 2048 " X: 0
+ elseif a:n == 4
+ Xpath 4096 " X: 4096
+ endif
+ return a:x
+endfunction
+
+unlet! var1 var2 var3 var4
+
+while 1
+ try
+ let error = 0
+ let v:errmsg = ""
+
+ while 1
+ try
+ Xpath 8192 " X: 8192
+ let var1 = {NAME(THROW("name", 1), 1)}(ARG(4711, 1), 1)
+ Xpath 16384 " X: 0
+ catch /^name$/
+ Xpath 32768 " X: 32768
+ catch /.*/
+ let error = 1
+ Xout "1:" v:exception "in" v:throwpoint
+ finally
+ if !error && $VIMNOERRTHROW && v:errmsg != ""
+ let error = 1
+ Xout "1:" v:errmsg
+ endif
+ if error
+ Xpath 65536 " X: 0
+ endif
+ let error = 0
+ let v:errmsg = ""
+ break " discard error for $VIMNOERRTHROW
+ endtry
+ endwhile
+
+ while 1
+ try
+ Xpath 131072 " X: 131072
+ let var2 = {NAME("F", 2)}(ARG(THROW("arg", 2), 2), 2)
+ Xpath 262144 " X: 0
+ catch /^arg$/
+ Xpath 524288 " X: 524288
+ catch /.*/
+ let error = 1
+ Xout "2:" v:exception "in" v:throwpoint
+ finally
+ if !error && $VIMNOERRTHROW && v:errmsg != ""
+ let error = 1
+ Xout "2:" v:errmsg
+ endif
+ if error
+ Xpath 1048576 " X: 0
+ endif
+ let error = 0
+ let v:errmsg = ""
+ break " discard error for $VIMNOERRTHROW
+ endtry
+ endwhile
+
+ while 1
+ try
+ Xpath 2097152 " X: 2097152
+ let var3 = {NAME("THROW", 3)}(ARG("call", 3), 3)
+ Xpath 4194304 " X: 0
+ catch /^call$/
+ Xpath 8388608 " X: 8388608
+ catch /^0$/ " default return value
+ Xpath 16777216 " X: 0
+ Xout "3:" v:throwpoint
+ catch /.*/
+ let error = 1
+ Xout "3:" v:exception "in" v:throwpoint
+ finally
+ if !error && $VIMNOERRTHROW && v:errmsg != ""
+ let error = 1
+ Xout "3:" v:errmsg
+ endif
+ if error
+ Xpath 33554432 " X: 0
+ endif
+ let error = 0
+ let v:errmsg = ""
+ break " discard error for $VIMNOERRTHROW
+ endtry
+ endwhile
+
+ while 1
+ try
+ Xpath 67108864 " X: 67108864
+ let var4 = {NAME("F", 4)}(ARG(4711, 4), 4)
+ Xpath 134217728 " X: 134217728
+ catch /.*/
+ let error = 1
+ Xout "4:" v:exception "in" v:throwpoint
+ finally
+ if !error && $VIMNOERRTHROW && v:errmsg != ""
+ let error = 1
+ Xout "4:" v:errmsg
+ endif
+ if error
+ Xpath 268435456 " X: 0
+ endif
+ let error = 0
+ let v:errmsg = ""
+ break " discard error for $VIMNOERRTHROW
+ endtry
+ endwhile
+
+ catch /^0$/ " default return value
+ Xpath 536870912 " X: 0
+ Xout v:throwpoint
+ catch /.*/
+ let error = 1
+ Xout v:exception "in" v:throwpoint
+ finally
+ if !error && $VIMNOERRTHROW && v:errmsg != ""
+ let error = 1
+ Xout v:errmsg
+ endif
+ if error
+ Xpath 1073741824 " X: 0
+ endif
+ break " discard error for $VIMNOERRTHROW
+ endtry
+endwhile
+
+if exists("var1") || exists("var2") || exists("var3") ||
+ \ !exists("var4") || var4 != 4711
+ " The Xpath command does not accept 2^31 (negative); add explicitly:
+ let Xpath = Xpath + 2147483648 " X: 0
+ if exists("var1")
+ Xout "var1 =" var1
+ endif
+ if exists("var2")
+ Xout "var2 =" var2
+ endif
+ if exists("var3")
+ Xout "var3 =" var3
+ endif
+ if !exists("var4")
+ Xout "var4 unset"
+ elseif var4 != 4711
+ Xout "var4 =" var4
+ endif
+endif
+
+unlet! error var1 var2 var3 var4
+delfunction THROW
+delfunction NAME
+delfunction ARG
+delfunction F
+
+Xcheck 212514423
+
+
+"-------------------------------------------------------------------------------
+" Test 69: :throw across :if, :elseif, :while {{{1
+"
+" On an :if, :elseif, or :while command, an exception might be thrown
+" during evaluation of the expression to test. The exception can be
+" caught by the script.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+XloopINIT! 1 2
+
+function! THROW(x)
+ XloopNEXT
+ Xloop 1 " X: 1 + 2 + 4
+ throw a:x
+endfunction
+
+try
+
+ try
+ Xpath 8 " X: 8
+ if 4711 == THROW("if") + 111
+ Xpath 16 " X: 0
+ else
+ Xpath 32 " X: 0
+ endif
+ Xpath 64 " X: 0
+ catch /^if$/
+ Xpath 128 " X: 128
+ catch /.*/
+ Xpath 256 " X: 0
+ Xout "if:" v:exception "in" v:throwpoint
+ endtry
+
+ try
+ Xpath 512 " X: 512
+ if 4711 == 4 + 7 + 1 + 1
+ Xpath 1024 " X: 0
+ elseif 4711 == THROW("elseif") + 222
+ Xpath 2048 " X: 0
+ else
+ Xpath 4096 " X: 0
+ endif
+ Xpath 8192 " X: 0
+ catch /^elseif$/
+ Xpath 16384 " X: 16384
+ catch /.*/
+ Xpath 32768 " X: 0
+ Xout "elseif:" v:exception "in" v:throwpoint
+ endtry
+
+ try
+ Xpath 65536 " X: 65536
+ while 4711 == THROW("while") + 4711
+ Xpath 131072 " X: 0
+ break
+ endwhile
+ Xpath 262144 " X: 0
+ catch /^while$/
+ Xpath 524288 " X: 524288
+ catch /.*/
+ Xpath 1048576 " X: 0
+ Xout "while:" v:exception "in" v:throwpoint
+ endtry
+
+catch /^0$/ " default return value
+ Xpath 2097152 " X: 0
+ Xout v:throwpoint
+catch /.*/
+ Xout v:exception "in" v:throwpoint
+ Xpath 4194304 " X: 0
+endtry
+
+Xpath 8388608 " X: 8388608
+
+delfunction THROW
+
+Xcheck 8995471
+
+
+"-------------------------------------------------------------------------------
+" Test 70: :throw across :return or :throw {{{1
+"
+" On a :return or :throw command, an exception might be thrown during
+" evaluation of the expression to return or throw, respectively. The
+" exception can be caught by the script.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+let taken = ""
+
+function! THROW(x, n)
+ let g:taken = g:taken . "T" . a:n
+ throw a:x
+endfunction
+
+function! F(x, y, n)
+ let g:taken = g:taken . "F" . a:n
+ return a:x + THROW(a:y, a:n)
+endfunction
+
+function! G(x, y, n)
+ let g:taken = g:taken . "G" . a:n
+ throw a:x . THROW(a:y, a:n)
+ return a:x
+endfunction
+
+try
+ try
+ Xpath 1 " X: 1
+ call F(4711, "return", 1)
+ Xpath 2 " X: 0
+ catch /^return$/
+ Xpath 4 " X: 4
+ catch /.*/
+ Xpath 8 " X: 0
+ Xout "return:" v:exception "in" v:throwpoint
+ endtry
+
+ try
+ Xpath 16 " X: 16
+ let var = F(4712, "return-var", 2)
+ Xpath 32 " X: 0
+ catch /^return-var$/
+ Xpath 64 " X: 64
+ catch /.*/
+ Xpath 128 " X: 0
+ Xout "return-var:" v:exception "in" v:throwpoint
+ finally
+ unlet! var
+ endtry
+
+ try
+ Xpath 256 " X: 256
+ throw "except1" . THROW("throw1", 3)
+ Xpath 512 " X: 0
+ catch /^except1/
+ Xpath 1024 " X: 0
+ catch /^throw1$/
+ Xpath 2048 " X: 2048
+ catch /.*/
+ Xpath 4096 " X: 0
+ Xout "throw1:" v:exception "in" v:throwpoint
+ endtry
+
+ try
+ Xpath 8192 " X: 8192
+ call G("except2", "throw2", 4)
+ Xpath 16384 " X: 0
+ catch /^except2/
+ Xpath 32768 " X: 0
+ catch /^throw2$/
+ Xpath 65536 " X: 65536
+ catch /.*/
+ Xpath 131072 " X: 0
+ Xout "throw2:" v:exception "in" v:throwpoint
+ endtry
+
+ try
+ Xpath 262144 " X: 262144
+ let var = G("except3", "throw3", 5)
+ Xpath 524288 " X: 0
+ catch /^except3/
+ Xpath 1048576 " X: 0
+ catch /^throw3$/
+ Xpath 2097152 " X: 2097152
+ catch /.*/
+ Xpath 4194304 " X: 0
+ Xout "throw3:" v:exception "in" v:throwpoint
+ finally
+ unlet! var
+ endtry
+
+ let expected = "F1T1F2T2T3G4T4G5T5"
+ if taken != expected
+ Xpath 8388608 " X: 0
+ Xout "'taken' is" taken "instead of" expected
+ endif
+
+catch /^0$/ " default return value
+ Xpath 16777216 " X: 0
+ Xout v:throwpoint
+catch /.*/
+ Xpath 33554432 " X: 0
+ Xout v:exception "in" v:throwpoint
+endtry
+
+Xpath 67108864 " X: 67108864
+
+unlet taken expected
+delfunction THROW
+delfunction F
+delfunction G
+
+Xcheck 69544277
+
+
+"-------------------------------------------------------------------------------
+" Test 71: :throw across :echo variants and :execute {{{1
+"
+" On an :echo, :echon, :echomsg, :echoerr, or :execute command, an
+" exception might be thrown during evaluation of the arguments to
+" be displayed or executed as a command, respectively. Any following
+" arguments are not evaluated, then. The exception can be caught by
+" the script.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+let taken = ""
+
+function! THROW(x, n)
+ let g:taken = g:taken . "T" . a:n
+ throw a:x
+endfunction
+
+function! F(n)
+ let g:taken = g:taken . "F" . a:n
+ return "F" . a:n
+endfunction
+
+try
+ try
+ Xpath 1 " X: 1
+ echo "echo" . THROW("echo-except", 1) F(1)
+ Xpath 2 " X: 0
+ catch /^echo-except$/
+ Xpath 4 " X: 4
+ catch /.*/
+ Xpath 8 " X: 0
+ Xout "echo:" v:exception "in" v:throwpoint
+ endtry
+
+ try
+ Xpath 16 " X: 16
+ echon "echon" . THROW("echon-except", 2) F(2)
+ Xpath 32 " X: 0
+ catch /^echon-except$/
+ Xpath 64 " X: 64
+ catch /.*/
+ Xpath 128 " X: 0
+ Xout "echon:" v:exception "in" v:throwpoint
+ endtry
+
+ try
+ Xpath 256 " X: 256
+ echomsg "echomsg" . THROW("echomsg-except", 3) F(3)
+ Xpath 512 " X: 0
+ catch /^echomsg-except$/
+ Xpath 1024 " X: 1024
+ catch /.*/
+ Xpath 2048 " X: 0
+ Xout "echomsg:" v:exception "in" v:throwpoint
+ endtry
+
+ try
+ Xpath 4096 " X: 4096
+ echoerr "echoerr" . THROW("echoerr-except", 4) F(4)
+ Xpath 8192 " X: 0
+ catch /^echoerr-except$/
+ Xpath 16384 " X: 16384
+ catch /Vim/
+ Xpath 32768 " X: 0
+ catch /echoerr/
+ Xpath 65536 " X: 0
+ catch /.*/
+ Xpath 131072 " X: 0
+ Xout "echoerr:" v:exception "in" v:throwpoint
+ endtry
+
+ try
+ Xpath 262144 " X: 262144
+ execute "echo 'execute" . THROW("execute-except", 5) F(5) "'"
+ Xpath 524288 " X: 0
+ catch /^execute-except$/
+ Xpath 1048576 " X: 1048576
+ catch /.*/
+ Xpath 2097152 " X: 0
+ Xout "execute:" v:exception "in" v:throwpoint
+ endtry
+
+ let expected = "T1T2T3T4T5"
+ if taken != expected
+ Xpath 4194304 " X: 0
+ Xout "'taken' is" taken "instead of" expected
+ endif
+
+catch /^0$/ " default return value
+ Xpath 8388608 " X: 0
+ Xout v:throwpoint
+catch /.*/
+ Xpath 16777216 " X: 0
+ Xout v:exception "in" v:throwpoint
+endtry
+
+Xpath 33554432 " X: 33554432
+
+unlet taken expected
+delfunction THROW
+delfunction F
+
+Xcheck 34886997
+
+
+"-------------------------------------------------------------------------------
+" Test 72: :throw across :let or :unlet {{{1
+"
+" On a :let command, an exception might be thrown during evaluation
+" of the expression to assign. On an :let or :unlet command, the
+" evaluation of the name of the variable to be assigned or list or
+" deleted, respectively, may throw an exception. Any following
+" arguments are not evaluated, then. The exception can be caught by
+" the script.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+let throwcount = 0
+
+function! THROW(x)
+ let g:throwcount = g:throwcount + 1
+ throw a:x
+endfunction
+
+try
+ try
+ let $VAR = "old_value"
+ Xpath 1 " X: 1
+ let $VAR = "let(" . THROW("var") . ")"
+ Xpath 2 " X: 0
+ catch /^var$/
+ Xpath 4 " X: 4
+ finally
+ if $VAR != "old_value"
+ Xpath 8 " X: 0
+ endif
+ endtry
+
+ try
+ let @a = "old_value"
+ Xpath 16 " X: 16
+ let @a = "let(" . THROW("reg") . ")"
+ Xpath 32 " X: 0
+ catch /^reg$/
+ try
+ Xpath 64 " X: 64
+ let @A = "let(" . THROW("REG") . ")"
+ Xpath 128 " X: 0
+ catch /^REG$/
+ Xpath 256 " X: 256
+ endtry
+ finally
+ if @a != "old_value"
+ Xpath 512 " X: 0
+ endif
+ if @A != "old_value"
+ Xpath 1024 " X: 0
+ endif
+ endtry
+
+ try
+ let saved_gpath = &g:path
+ let saved_lpath = &l:path
+ Xpath 2048 " X: 2048
+ let &path = "let(" . THROW("opt") . ")"
+ Xpath 4096 " X: 0
+ catch /^opt$/
+ try
+ Xpath 8192 " X: 8192
+ let &g:path = "let(" . THROW("gopt") . ")"
+ Xpath 16384 " X: 0
+ catch /^gopt$/
+ try
+ Xpath 32768 " X: 32768
+ let &l:path = "let(" . THROW("lopt") . ")"
+ Xpath 65536 " X: 0
+ catch /^lopt$/
+ Xpath 131072 " X: 131072
+ endtry
+ endtry
+ finally
+ if &g:path != saved_gpath || &l:path != saved_lpath
+ Xpath 262144 " X: 0
+ endif
+ let &g:path = saved_gpath
+ let &l:path = saved_lpath
+ endtry
+
+ unlet! var1 var2 var3
+
+ try
+ Xpath 524288 " X: 524288
+ let var1 = "let(" . THROW("var1") . ")"
+ Xpath 1048576 " X: 0
+ catch /^var1$/
+ Xpath 2097152 " X: 2097152
+ finally
+ if exists("var1")
+ Xpath 4194304 " X: 0
+ endif
+ endtry
+
+ try
+ let var2 = "old_value"
+ Xpath 8388608 " X: 8388608
+ let var2 = "let(" . THROW("var2"). ")"
+ Xpath 16777216 " X: 0
+ catch /^var2$/
+ Xpath 33554432 " X: 33554432
+ finally
+ if var2 != "old_value"
+ Xpath 67108864 " X: 0
+ endif
+ endtry
+
+ try
+ Xpath 134217728 " X: 134217728
+ let var{THROW("var3")} = 4711
+ Xpath 268435456 " X: 0
+ catch /^var3$/
+ Xpath 536870912 " X: 536870912
+ endtry
+
+ let addpath = ""
+
+ function ADDPATH(p)
+ let g:addpath = g:addpath . a:p
+ endfunction
+
+ try
+ call ADDPATH("T1")
+ let var{THROW("var4")} var{ADDPATH("T2")} | call ADDPATH("T3")
+ call ADDPATH("T4")
+ catch /^var4$/
+ call ADDPATH("T5")
+ endtry
+
+ try
+ call ADDPATH("T6")
+ unlet var{THROW("var5")} var{ADDPATH("T7")} | call ADDPATH("T8")
+ call ADDPATH("T9")
+ catch /^var5$/
+ call ADDPATH("T10")
+ endtry
+
+ if addpath != "T1T5T6T10" || throwcount != 11
+ throw "addpath: " . addpath . ", throwcount: " . throwcount
+ endif
+
+ Xpath 1073741824 " X: 1073741824
+
+catch /.*/
+ " The Xpath command does not accept 2^31 (negative); add explicitly:
+ let Xpath = Xpath + 2147483648 " X: 0
+ Xout v:exception "in" v:throwpoint
+endtry
+
+unlet! var1 var2 var3 addpath throwcount
+delfunction THROW
+
+Xcheck 1789569365
+
+
+"-------------------------------------------------------------------------------
+" Test 73: :throw across :function, :delfunction {{{1
+"
+" The :function and :delfunction commands may cause an expression
+" specified in braces to be evaluated. During evaluation, an
+" exception might be thrown. The exception can be caught by the
+" script.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+let taken = ""
+
+function! THROW(x, n)
+ let g:taken = g:taken . "T" . a:n
+ throw a:x
+endfunction
+
+function! EXPR(x, n)
+ let g:taken = g:taken . "E" . a:n
+ if a:n % 2 == 0
+ call THROW(a:x, a:n)
+ endif
+ return 2 - a:n % 2
+endfunction
+
+try
+ try
+ " Define function.
+ Xpath 1 " X: 1
+ function! F0()
+ endfunction
+ Xpath 2 " X: 2
+ function! F{EXPR("function-def-ok", 1)}()
+ endfunction
+ Xpath 4 " X: 4
+ function! F{EXPR("function-def", 2)}()
+ endfunction
+ Xpath 8 " X: 0
+ catch /^function-def-ok$/
+ Xpath 16 " X: 0
+ catch /^function-def$/
+ Xpath 32 " X: 32
+ catch /.*/
+ Xpath 64 " X: 0
+ Xout "def:" v:exception "in" v:throwpoint
+ endtry
+
+ try
+ " List function.
+ Xpath 128 " X: 128
+ function F0
+ Xpath 256 " X: 256
+ function F{EXPR("function-lst-ok", 3)}
+ Xpath 512 " X: 512
+ function F{EXPR("function-lst", 4)}
+ Xpath 1024 " X: 0
+ catch /^function-lst-ok$/
+ Xpath 2048 " X: 0
+ catch /^function-lst$/
+ Xpath 4096 " X: 4096
+ catch /.*/
+ Xpath 8192 " X: 0
+ Xout "lst:" v:exception "in" v:throwpoint
+ endtry
+
+ try
+ " Delete function
+ Xpath 16384 " X: 16384
+ delfunction F0
+ Xpath 32768 " X: 32768
+ delfunction F{EXPR("function-del-ok", 5)}
+ Xpath 65536 " X: 65536
+ delfunction F{EXPR("function-del", 6)}
+ Xpath 131072 " X: 0
+ catch /^function-del-ok$/
+ Xpath 262144 " X: 0
+ catch /^function-del$/
+ Xpath 524288 " X: 524288
+ catch /.*/
+ Xpath 1048576 " X: 0
+ Xout "del:" v:exception "in" v:throwpoint
+ endtry
+
+ let expected = "E1E2T2E3E4T4E5E6T6"
+ if taken != expected
+ Xpath 2097152 " X: 0
+ Xout "'taken' is" taken "instead of" expected
+ endif
+
+catch /.*/
+ Xpath 4194304 " X: 0
+ Xout v:exception "in" v:throwpoint
+endtry
+
+Xpath 8388608 " X: 8388608
+
+unlet taken expected
+delfunction THROW
+delfunction EXPR
+
+Xcheck 9032615
+
+
+"-------------------------------------------------------------------------------
+" Test 74: :throw across builtin functions and commands {{{1
+"
+" Some functions like exists(), searchpair() take expression
+" arguments, other functions or commands like substitute() or
+" :substitute cause an expression (specified in the regular
+" expression) to be evaluated. During evaluation an exception
+" might be thrown. The exception can be caught by the script.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+let taken = ""
+
+function! THROW(x, n)
+ let g:taken = g:taken . "T" . a:n
+ throw a:x
+endfunction
+
+function! EXPR(x, n)
+ let g:taken = g:taken . "E" . a:n
+ call THROW(a:x . a:n, a:n)
+ return "EXPR"
+endfunction
+
+function! SKIP(x, n)
+ let g:taken = g:taken . "S" . a:n . "(" . line(".")
+ let theline = getline(".")
+ if theline =~ "skip"
+ let g:taken = g:taken . "s)"
+ return 1
+ elseif theline =~ "throw"
+ let g:taken = g:taken . "t)"
+ call THROW(a:x . a:n, a:n)
+ else
+ let g:taken = g:taken . ")"
+ return 0
+ endif
+endfunction
+
+function! SUBST(x, n)
+ let g:taken = g:taken . "U" . a:n . "(" . line(".")
+ let theline = getline(".")
+ if theline =~ "not" " SUBST() should not be called for this line
+ let g:taken = g:taken . "n)"
+ call THROW(a:x . a:n, a:n)
+ elseif theline =~ "throw"
+ let g:taken = g:taken . "t)"
+ call THROW(a:x . a:n, a:n)
+ else
+ let g:taken = g:taken . ")"
+ return "replaced"
+ endif
+endfunction
+
+try
+ try
+ Xpath 1 " X: 1
+ let result = exists('*{EXPR("exists", 1)}')
+ Xpath 2 " X: 0
+ catch /^exists1$/
+ Xpath 4 " X: 4
+ try
+ let result = exists('{EXPR("exists", 2)}')
+ Xpath 8 " X: 0
+ catch /^exists2$/
+ Xpath 16 " X: 16
+ catch /.*/
+ Xpath 32 " X: 0
+ Xout "exists2:" v:exception "in" v:throwpoint
+ endtry
+ catch /.*/
+ Xpath 64 " X: 0
+ Xout "exists1:" v:exception "in" v:throwpoint
+ endtry
+
+ try
+ let file = tempname()
+ exec "edit" file
+ insert
+begin
+ xx
+middle 3
+ xx
+middle 5 skip
+ xx
+middle 7 throw
+ xx
+end
+.
+ normal! gg
+ Xpath 128 " X: 128
+ let result =
+ \ searchpair("begin", "middle", "end", '', 'SKIP("searchpair", 3)')
+ Xpath 256 " X: 256
+ let result =
+ \ searchpair("begin", "middle", "end", '', 'SKIP("searchpair", 4)')
+ Xpath 512 " X: 0
+ let result =
+ \ searchpair("begin", "middle", "end", '', 'SKIP("searchpair", 5)')
+ Xpath 1024 " X: 0
+ catch /^searchpair[35]$/
+ Xpath 2048 " X: 0
+ catch /^searchpair4$/
+ Xpath 4096 " X: 4096
+ catch /.*/
+ Xpath 8192 " X: 0
+ Xout "searchpair:" v:exception "in" v:throwpoint
+ finally
+ bwipeout!
+ call delete(file)
+ endtry
+
+ try
+ let file = tempname()
+ exec "edit" file
+ insert
+subst 1
+subst 2
+not
+subst 4
+subst throw
+subst 6
+.
+ normal! gg
+ Xpath 16384 " X: 16384
+ 1,2substitute/subst/\=SUBST("substitute", 6)/
+ try
+ Xpath 32768 " X: 32768
+ try
+ let v:errmsg = ""
+ 3substitute/subst/\=SUBST("substitute", 7)/
+ finally
+ if v:errmsg != ""
+ " If exceptions are not thrown on errors, fake the error
+ " exception in order to get the same execution path.
+ throw "faked Vim(substitute)"
+ endif
+ endtry
+ catch /Vim(substitute)/ " Pattern not found ('e' flag missing)
+ Xpath 65536 " X: 65536
+ 3substitute/subst/\=SUBST("substitute", 8)/e
+ Xpath 131072 " X: 131072
+ endtry
+ Xpath 262144 " X: 262144
+ 4,6substitute/subst/\=SUBST("substitute", 9)/
+ Xpath 524288 " X: 0
+ catch /^substitute[678]/
+ Xpath 1048576 " X: 0
+ catch /^substitute9/
+ Xpath 2097152 " X: 2097152
+ finally
+ bwipeout!
+ call delete(file)
+ endtry
+
+ try
+ Xpath 4194304 " X: 4194304
+ let var = substitute("sub", "sub", '\=THROW("substitute()y", 10)', '')
+ Xpath 8388608 " X: 0
+ catch /substitute()y/
+ Xpath 16777216 " X: 16777216
+ catch /.*/
+ Xpath 33554432 " X: 0
+ Xout "substitute()y:" v:exception "in" v:throwpoint
+ endtry
+
+ try
+ Xpath 67108864 " X: 67108864
+ let var = substitute("not", "sub", '\=THROW("substitute()n", 11)', '')
+ Xpath 134217728 " X: 134217728
+ catch /substitute()n/
+ Xpath 268435456 " X: 0
+ catch /.*/
+ Xpath 536870912 " X: 0
+ Xout "substitute()n:" v:exception "in" v:throwpoint
+ endtry
+
+ let expected = "E1T1E2T2S3(3)S4(5s)S4(7t)T4U6(1)U6(2)U9(4)U9(5t)T9T10"
+ if taken != expected
+ Xpath 1073741824 " X: 0
+ Xout "'taken' is" taken "instead of" expected
+ endif
+
+catch /.*/
+ " The Xpath command does not accept 2^31 (negative); add explicitly:
+ let Xpath = Xpath + 2147483648 " X: 0
+ Xout v:exception "in" v:throwpoint
+endtry
+
+unlet result var taken expected
+delfunction THROW
+delfunction EXPR
+delfunction SKIP
+delfunction SUBST
+
+Xcheck 224907669
+
+
+"-------------------------------------------------------------------------------
+" Test 75: Errors in builtin functions. {{{1
+"
+" On an error in a builtin function called inside a :try/:endtry
+" region, the evaluation of the expression calling that function and
+" the command containing that expression are abandoned. The error can
+" be caught as an exception.
+"
+" A simple :call of the builtin function is a trivial case. If the
+" builtin function is called in the argument list of another function,
+" no further arguments are evaluated, and the other function is not
+" executed. If the builtin function is called from the argument of
+" a :return command, the :return command is not executed. If the
+" builtin function is called from the argument of a :throw command,
+" the :throw command is not executed. The evaluation of the
+" expression calling the builtin function is abandoned.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+function! F1(arg1)
+ Xpath 1 " X: 0
+endfunction
+
+function! F2(arg1, arg2)
+ Xpath 2 " X: 0
+endfunction
+
+function! G()
+ Xpath 4 " X: 0
+endfunction
+
+function! H()
+ Xpath 8 " X: 0
+endfunction
+
+function! R()
+ while 1
+ try
+ let caught = 0
+ let v:errmsg = ""
+ Xpath 16 " X: 16
+ return append(1, "s")
+ catch /E21/
+ let caught = 1
+ catch /.*/
+ Xpath 32 " X: 0
+ finally
+ Xpath 64 " X: 64
+ if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21'
+ Xpath 128 " X: 128
+ endif
+ break " discard error for $VIMNOERRTHROW
+ endtry
+ endwhile
+ Xpath 256 " X: 256
+endfunction
+
+try
+ set noma " let append() fail with "E21"
+
+ while 1
+ try
+ let caught = 0
+ let v:errmsg = ""
+ Xpath 512 " X: 512
+ call append(1, "s")
+ catch /E21/
+ let caught = 1
+ catch /.*/
+ Xpath 1024 " X: 0
+ finally
+ Xpath 2048 " X: 2048
+ if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21'
+ Xpath 4096 " X: 4096
+ endif
+ break " discard error for $VIMNOERRTHROW
+ endtry
+ endwhile
+
+ while 1
+ try
+ let caught = 0
+ let v:errmsg = ""
+ Xpath 8192 " X: 8192
+ call F1('x' . append(1, "s"))
+ catch /E21/
+ let caught = 1
+ catch /.*/
+ Xpath 16384 " X: 0
+ finally
+ Xpath 32768 " X: 32768
+ if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21'
+ Xpath 65536 " X: 65536
+ endif
+ break " discard error for $VIMNOERRTHROW
+ endtry
+ endwhile
+
+ while 1
+ try
+ let caught = 0
+ let v:errmsg = ""
+ Xpath 131072 " X: 131072
+ call F2('x' . append(1, "s"), G())
+ catch /E21/
+ let caught = 1
+ catch /.*/
+ Xpath 262144 " X: 0
+ finally
+ Xpath 524288 " X: 524288
+ if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21'
+ Xpath 1048576 " X: 1048576
+ endif
+ break " discard error for $VIMNOERRTHROW
+ endtry
+ endwhile
+
+ call R()
+
+ while 1
+ try
+ let caught = 0
+ let v:errmsg = ""
+ Xpath 2097152 " X: 2097152
+ throw "T" . append(1, "s")
+ catch /E21/
+ let caught = 1
+ catch /^T.*/
+ Xpath 4194304 " X: 0
+ catch /.*/
+ Xpath 8388608 " X: 0
+ finally
+ Xpath 16777216 " X: 16777216
+ if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21'
+ Xpath 33554432 " X: 33554432
+ endif
+ break " discard error for $VIMNOERRTHROW
+ endtry
+ endwhile
+
+ while 1
+ try
+ let caught = 0
+ let v:errmsg = ""
+ Xpath 67108864 " X: 67108864
+ let x = "a"
+ let x = x . "b" . append(1, "s") . H()
+ catch /E21/
+ let caught = 1
+ catch /.*/
+ Xpath 134217728 " X: 0
+ finally
+ Xpath 268435456 " X: 268435456
+ if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21'
+ Xpath 536870912 " X: 536870912
+ endif
+ if x == "a"
+ Xpath 1073741824 " X: 1073741824
+ endif
+ break " discard error for $VIMNOERRTHROW
+ endtry
+ endwhile
+catch /.*/
+ " The Xpath command does not accept 2^31 (negative); add explicitly:
+ let Xpath = Xpath + 2147483648 " X: 0
+ Xout v:exception "in" v:throwpoint
+finally
+ set ma&
+endtry
+
+unlet! caught x
+delfunction F1
+delfunction F2
+delfunction G
+delfunction H
+delfunction R
+
+Xcheck 2000403408
+
+
+"-------------------------------------------------------------------------------
+" Test 76: Errors, interrupts, :throw during expression evaluation {{{1
+"
+" When a function call made during expression evaluation is aborted
+" due to an error inside a :try/:endtry region or due to an interrupt
+" or a :throw, the expression evaluation is aborted as well. No
+" message is displayed for the cancelled expression evaluation. On an
+" error not inside :try/:endtry, the expression evaluation continues.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+if ExtraVim()
+
+ let taken = ""
+
+ function! ERR(n)
+ let g:taken = g:taken . "E" . a:n
+ asdf
+ endfunction
+
+ function! ERRabort(n) abort
+ let g:taken = g:taken . "A" . a:n
+ asdf
+ endfunction " returns -1; may cause follow-up msg for illegal var/func name
+
+ function! WRAP(n, arg)
+ let g:taken = g:taken . "W" . a:n
+ let g:saved_errmsg = v:errmsg
+ return arg
+ endfunction
+
+ function! INT(n)
+ let g:taken = g:taken . "I" . a:n
+ "INTERRUPT9
+ let dummy = 0
+ endfunction
+
+ function! THR(n)
+ let g:taken = g:taken . "T" . a:n
+ throw "should not be caught"
+ endfunction
+
+ function! CONT(n)
+ let g:taken = g:taken . "C" . a:n
+ endfunction
+
+ function! MSG(n)
+ let g:taken = g:taken . "M" . a:n
+ let errmsg = (a:n >= 37 && a:n <= 44) ? g:saved_errmsg : v:errmsg
+ let msgptn = (a:n >= 10 && a:n <= 27) ? "^$" : "asdf"
+ if errmsg !~ msgptn
+ let g:taken = g:taken . "x"
+ Xout "Expr" a:n.": Unexpected message:" v:errmsg
+ endif
+ let v:errmsg = ""
+ let g:saved_errmsg = ""
+ endfunction
+
+ let v:errmsg = ""
+
+ try
+ let t = 1
+ XloopINIT 1 2
+ while t <= 9
+ Xloop 1 " X: 511
+ try
+ if t == 1
+ let v{ERR(t) + CONT(t)} = 0
+ elseif t == 2
+ let v{ERR(t) + CONT(t)}
+ elseif t == 3
+ let var = exists('v{ERR(t) + CONT(t)}')
+ elseif t == 4
+ unlet v{ERR(t) + CONT(t)}
+ elseif t == 5
+ function F{ERR(t) + CONT(t)}()
+ endfunction
+ elseif t == 6
+ function F{ERR(t) + CONT(t)}
+ elseif t == 7
+ let var = exists('*F{ERR(t) + CONT(t)}')
+ elseif t == 8
+ delfunction F{ERR(t) + CONT(t)}
+ elseif t == 9
+ let var = ERR(t) + CONT(t)
+ endif
+ catch /asdf/
+ " v:errmsg is not set when the error message is converted to an
+ " exception. Set it to the original error message.
+ let v:errmsg = substitute(v:exception, '^Vim:', '', "")
+ catch /^Vim\((\a\+)\)\=:/
+ " An error exception has been thrown after the original error.
+ let v:errmsg = ""
+ finally
+ call MSG(t)
+ let t = t + 1
+ XloopNEXT
+ continue " discard an aborting error
+ endtry
+ endwhile
+ catch /.*/
+ Xpath 512 " X: 0
+ Xout v:exception "in" ExtraVimThrowpoint()
+ endtry
+
+ try
+ let t = 10
+ XloopINIT 1024 2
+ while t <= 18
+ Xloop 1 " X: 1024 * 511
+ try
+ if t == 10
+ let v{INT(t) + CONT(t)} = 0
+ elseif t == 11
+ let v{INT(t) + CONT(t)}
+ elseif t == 12
+ let var = exists('v{INT(t) + CONT(t)}')
+ elseif t == 13
+ unlet v{INT(t) + CONT(t)}
+ elseif t == 14
+ function F{INT(t) + CONT(t)}()
+ endfunction
+ elseif t == 15
+ function F{INT(t) + CONT(t)}
+ elseif t == 16
+ let var = exists('*F{INT(t) + CONT(t)}')
+ elseif t == 17
+ delfunction F{INT(t) + CONT(t)}
+ elseif t == 18
+ let var = INT(t) + CONT(t)
+ endif
+ catch /^Vim\((\a\+)\)\=:\(Interrupt\)\@!/
+ " An error exception has been triggered after the interrupt.
+ let v:errmsg = substitute(v:exception,
+ \ '^Vim\((\a\+)\)\=:', '', "")
+ finally
+ call MSG(t)
+ let t = t + 1
+ XloopNEXT
+ continue " discard interrupt
+ endtry
+ endwhile
+ catch /.*/
+ Xpath 524288 " X: 0
+ Xout v:exception "in" ExtraVimThrowpoint()
+ endtry
+
+ try
+ let t = 19
+ XloopINIT 1048576 2
+ while t <= 27
+ Xloop 1 " X: 1048576 * 511
+ try
+ if t == 19
+ let v{THR(t) + CONT(t)} = 0
+ elseif t == 20
+ let v{THR(t) + CONT(t)}
+ elseif t == 21
+ let var = exists('v{THR(t) + CONT(t)}')
+ elseif t == 22
+ unlet v{THR(t) + CONT(t)}
+ elseif t == 23
+ function F{THR(t) + CONT(t)}()
+ endfunction
+ elseif t == 24
+ function F{THR(t) + CONT(t)}
+ elseif t == 25
+ let var = exists('*F{THR(t) + CONT(t)}')
+ elseif t == 26
+ delfunction F{THR(t) + CONT(t)}
+ elseif t == 27
+ let var = THR(t) + CONT(t)
+ endif
+ catch /^Vim\((\a\+)\)\=:/
+ " An error exception has been triggered after the :throw.
+ let v:errmsg = substitute(v:exception,
+ \ '^Vim\((\a\+)\)\=:', '', "")
+ finally
+ call MSG(t)
+ let t = t + 1
+ XloopNEXT
+ continue " discard exception
+ endtry
+ endwhile
+ catch /.*/
+ Xpath 536870912 " X: 0
+ Xout v:exception "in" ExtraVimThrowpoint()
+ endtry
+
+ let v{ERR(28) + CONT(28)} = 0
+ call MSG(28)
+ let v{ERR(29) + CONT(29)}
+ call MSG(29)
+ let var = exists('v{ERR(30) + CONT(30)}')
+ call MSG(30)
+ unlet v{ERR(31) + CONT(31)}
+ call MSG(31)
+ function F{ERR(32) + CONT(32)}()
+ endfunction
+ call MSG(32)
+ function F{ERR(33) + CONT(33)}
+ call MSG(33)
+ let var = exists('*F{ERR(34) + CONT(34)}')
+ call MSG(34)
+ delfunction F{ERR(35) + CONT(35)}
+ call MSG(35)
+ let var = ERR(36) + CONT(36)
+ call MSG(36)
+
+ let saved_errmsg = ""
+
+ let v{WRAP(37, ERRabort(37)) + CONT(37)} = 0
+ call MSG(37)
+ let v{WRAP(38, ERRabort(38)) + CONT(38)}
+ call MSG(38)
+ let var = exists('v{WRAP(39, ERRabort(39)) + CONT(39)}')
+ call MSG(39)
+ unlet v{WRAP(40, ERRabort(40)) + CONT(40)}
+ call MSG(40)
+ function F{WRAP(41, ERRabort(41)) + CONT(41)}()
+ endfunction
+ call MSG(41)
+ function F{WRAP(42, ERRabort(42)) + CONT(42)}
+ call MSG(42)
+ let var = exists('*F{WRAP(43, ERRabort(43)) + CONT(43)}')
+ call MSG(43)
+ delfunction F{WRAP(44, ERRabort(44)) + CONT(44)}
+ call MSG(44)
+ let var = ERRabort(45) + CONT(45)
+ call MSG(45)
+
+ Xpath 1073741824 " X: 1073741824
+
+ let expected = ""
+ \ . "E1M1E2M2E3M3E4M4E5M5E6M6E7M7E8M8E9M9"
+ \ . "I10M10I11M11I12M12I13M13I14M14I15M15I16M16I17M17I18M18"
+ \ . "T19M19T20M20T21M21T22M22T23M23T24M24T25M25T26M26T27M27"
+ \ . "E28C28M28E29C29M29E30C30M30E31C31M31E32C32M32E33C33M33"
+ \ . "E34C34M34E35C35M35E36C36M36"
+ \ . "A37W37C37M37A38W38C38M38A39W39C39M39A40W40C40M40A41W41C41M41"
+ \ . "A42W42C42M42A43W43C43M43A44W44C44M44A45C45M45"
+
+ if taken != expected
+ " The Xpath command does not accept 2^31 (negative); display explicitly:
+ exec "!echo 2147483648 >>" . g:ExtraVimResult
+ " X: 0
+ Xout "'taken' is" taken "instead of" expected
+ if substitute(taken,
+ \ '\(.*\)E3C3M3x\(.*\)E30C30M30x\(.*\)A39C39M39x\(.*\)',
+ \ '\1E3M3\2E30C30M30\3A39C39M39\4',
+ \ "") == expected
+ Xout "Is ++emsg_skip for var with expr_start non-NULL"
+ \ "in f_exists ok?"
+ endif
+ endif
+
+ unlet! v var saved_errmsg taken expected
+ call delete(WA_t5)
+ call delete(WA_t14)
+ call delete(WA_t23)
+ unlet! WA_t5 WA_t14 WA_t23
+ delfunction WA_t5
+ delfunction WA_t14
+ delfunction WA_t23
+
+endif
+
+Xcheck 1610087935
+
+
+"-------------------------------------------------------------------------------
+" Test 77: Errors, interrupts, :throw in name{brace-expression} {{{1
+"
+" When a function call made during evaluation of an expression in
+" braces as part of a function name after ":function" is aborted due
+" to an error inside a :try/:endtry region or due to an interrupt or
+" a :throw, the expression evaluation is aborted as well, and the
+" function definition is ignored, skipping all commands to the
+" ":endfunction". On an error not inside :try/:endtry, the expression
+" evaluation continues and the function gets defined, and can be
+" called and deleted.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+XloopINIT 1 4
+
+function! ERR() abort
+ Xloop 1 " X: 1 + 4 + 16 + 64
+ asdf
+endfunction " returns -1
+
+function! OK()
+ Xloop 2 " X: 2 * (1 + 4 + 16)
+ let v:errmsg = ""
+ return 0
+endfunction
+
+let v:errmsg = ""
+
+Xpath 4096 " X: 4096
+function! F{1 + ERR() + OK()}(arg)
+ " F0 should be defined.
+ if exists("a:arg") && a:arg == "calling"
+ Xpath 8192 " X: 8192
+ else
+ Xpath 16384 " X: 0
+ endif
+endfunction
+if v:errmsg != ""
+ Xpath 32768 " X: 0
+endif
+XloopNEXT
+
+Xpath 65536 " X: 65536
+call F{1 + ERR() + OK()}("calling")
+if v:errmsg != ""
+ Xpath 131072 " X: 0
+endif
+XloopNEXT
+
+Xpath 262144 " X: 262144
+delfunction F{1 + ERR() + OK()}
+if v:errmsg != ""
+ Xpath 524288 " X: 0
+endif
+XloopNEXT
+
+try
+ while 1
+ let caught = 0
+ try
+ Xpath 1048576 " X: 1048576
+ function! G{1 + ERR() + OK()}(arg)
+ " G0 should not be defined, and the function body should be
+ " skipped.
+ if exists("a:arg") && a:arg == "calling"
+ Xpath 2097152 " X: 0
+ else
+ Xpath 4194304 " X: 0
+ endif
+ " Use an unmatched ":finally" to check whether the body is
+ " skipped when an error occurs in ERR(). This works whether or
+ " not the exception is converted to an exception.
+ finally
+ Xpath 8388608 " X: 0
+ Xout "Body of G{1 + ERR() + OK()}() not skipped"
+ " Discard the aborting error or exception, and break the
+ " while loop.
+ break
+ " End the try conditional and start a new one to avoid
+ " ":catch after :finally" errors.
+ endtry
+ try
+ Xpath 16777216 " X: 0
+ endfunction
+
+ " When the function was not defined, this won't be reached - whether
+ " the body was skipped or not. When the function was defined, it
+ " can be called and deleted here.
+ Xpath 33554432 " X: 0
+ Xout "G0() has been defined"
+ XloopNEXT
+ try
+ call G{1 + ERR() + OK()}("calling")
+ catch /.*/
+ Xpath 67108864 " X: 0
+ endtry
+ Xpath 134217728 " X: 0
+ XloopNEXT
+ try
+ delfunction G{1 + ERR() + OK()}
+ catch /.*/
+ Xpath 268435456 " X: 0
+ endtry
+ catch /asdf/
+ " Jumped to when the function is not defined and the body is
+ " skipped.
+ let caught = 1
+ catch /.*/
+ Xpath 536870912 " X: 0
+ finally
+ if !caught && !$VIMNOERRTHROW
+ Xpath 1073741824 " X: 0
+ endif
+ break " discard error for $VIMNOERRTHROW
+ endtry " jumped to when the body is not skipped
+ endwhile
+catch /.*/
+ " The Xpath command does not accept 2^31 (negative); add explicitly:
+ let Xpath = Xpath + 2147483648 " X: 0
+ Xout "Body of G{1 + ERR() + OK()}() not skipped, exception caught"
+ Xout v:exception "in" v:throwpoint
+endtry
+
+Xcheck 1388671
+
+
+"-------------------------------------------------------------------------------
+" Test 78: Messages on parsing errors in expression evaluation {{{1
+"
+" When an expression evaluation detects a parsing error, an error
+" message is given and converted to an exception, and the expression
+" evaluation is aborted.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+if ExtraVim()
+
+ let taken = ""
+
+ function! F(n)
+ let g:taken = g:taken . "F" . a:n
+ endfunction
+
+ function! MSG(n, enr, emsg)
+ let g:taken = g:taken . "M" . a:n
+ let english = v:lang == "C" || v:lang =~ '^[Ee]n'
+ if a:enr == ""
+ Xout "TODO: Add message number for:" a:emsg
+ let v:errmsg = ":" . v:errmsg
+ endif
+ if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg)
+ if v:errmsg == ""
+ Xout "Expr" a:n.": Message missing."
+ let g:taken = g:taken . "x"
+ else
+ let v:errmsg = escape(v:errmsg, '"')
+ Xout "Expr" a:n.": Unexpected message:" v:errmsg
+ Xout "Expected: " . a:enr . ': ' . a:emsg
+ let g:taken = g:taken . "X"
+ endif
+ endif
+ endfunction
+
+ function! CONT(n)
+ let g:taken = g:taken . "C" . a:n
+ endfunction
+
+ let v:errmsg = ""
+ XloopINIT 1 2
+
+ try
+ let t = 1
+ while t <= 14
+ let g:taken = g:taken . "T" . t
+ let v:errmsg = ""
+ try
+ let caught = 0
+ if t == 1
+ let v{novar + CONT(t)} = 0
+ elseif t == 2
+ let v{novar + CONT(t)}
+ elseif t == 3
+ let var = exists('v{novar + CONT(t)}')
+ elseif t == 4
+ unlet v{novar + CONT(t)}
+ elseif t == 5
+ function F{novar + CONT(t)}()
+ endfunction
+ elseif t == 6
+ function F{novar + CONT(t)}
+ elseif t == 7
+ let var = exists('*F{novar + CONT(t)}')
+ elseif t == 8
+ delfunction F{novar + CONT(t)}
+ elseif t == 9
+ echo novar + CONT(t)
+ elseif t == 10
+ echo v{novar + CONT(t)}
+ elseif t == 11
+ echo F{novar + CONT(t)}
+ elseif t == 12
+ let var = novar + CONT(t)
+ elseif t == 13
+ let var = v{novar + CONT(t)}
+ elseif t == 14
+ let var = F{novar + CONT(t)}()
+ endif
+ catch /^Vim\((\a\+)\)\=:/
+ " v:errmsg is not set when the error message is converted to an
+ " exception. Set it to the original error message.
+ let v:errmsg = substitute(v:exception,
+ \ '^Vim\((\a\+)\)\=:', '', "")
+ let caught = 1
+ finally
+ if t <= 8 && t != 3 && t != 7
+ call MSG(t, 'E475', 'Invalid argument\>')
+ else
+ if !caught " no error exceptions ($VIMNOERRTHROW set)
+ call MSG(t, 'E15', "Invalid expression")
+ else
+ call MSG(t, 'E121', "Undefined variable")
+ endif
+ endif
+ let t = t + 1
+ XloopNEXT
+ continue " discard an aborting error
+ endtry
+ endwhile
+ catch /.*/
+ Xloop 1 " X: 0
+ Xout t.":" v:exception "in" ExtraVimThrowpoint()
+ endtry
+
+ function! T(n, expr, enr, emsg)
+ try
+ let g:taken = g:taken . "T" . a:n
+ let v:errmsg = ""
+ try
+ let caught = 0
+ execute "let var = " . a:expr
+ catch /^Vim\((\a\+)\)\=:/
+ " v:errmsg is not set when the error message is converted to an
+ " exception. Set it to the original error message.
+ let v:errmsg = substitute(v:exception,
+ \ '^Vim\((\a\+)\)\=:', '', "")
+ let caught = 1
+ finally
+ if !caught " no error exceptions ($VIMNOERRTHROW set)
+ call MSG(a:n, 'E15', "Invalid expression")
+ else
+ call MSG(a:n, a:enr, a:emsg)
+ endif
+ XloopNEXT
+ " Discard an aborting error:
+ return
+ endtry
+ catch /.*/
+ Xloop 1 " X: 0
+ Xout a:n.":" v:exception "in" ExtraVimThrowpoint()
+ endtry
+ endfunction
+
+ call T(15, 'Nofunc() + CONT(15)', 'E117', "Unknown function")
+ call T(16, 'F(1 2 + CONT(16))', 'E116', "Invalid arguments")
+ call T(17, 'F(1, 2) + CONT(17)', 'E118', "Too many arguments")
+ call T(18, 'F() + CONT(18)', 'E119', "Not enough arguments")
+ call T(19, '{(1} + CONT(19)', 'E110', "Missing ')'")
+ call T(20, '("abc"[1) + CONT(20)', 'E111', "Missing ']'")
+ call T(21, '(1 +) + CONT(21)', 'E15', "Invalid expression")
+ call T(22, '1 2 + CONT(22)', 'E15', "Invalid expression")
+ call T(23, '(1 ? 2) + CONT(23)', 'E109', "Missing ':' after '?'")
+ call T(24, '("abc) + CONT(24)', 'E114', "Missing quote")
+ call T(25, "('abc) + CONT(25)", 'E115', "Missing quote")
+ call T(26, '& + CONT(26)', 'E112', "Option name missing")
+ call T(27, '&asdf + CONT(27)', 'E113', "Unknown option")
+
+ Xpath 134217728 " X: 134217728
+
+ let expected = ""
+ \ . "T1M1T2M2T3M3T4M4T5M5T6M6T7M7T8M8T9M9T10M10T11M11T12M12T13M13T14M14"
+ \ . "T15M15T16M16T17M17T18M18T19M19T20M20T21M21T22M22T23M23T24M24T25M25"
+ \ . "T26M26T27M27"
+
+ if taken != expected
+ Xpath 268435456 " X: 0
+ Xout "'taken' is" taken "instead of" expected
+ if substitute(taken, '\(.*\)T3M3x\(.*\)', '\1T3M3\2', "") == expected
+ Xout "Is ++emsg_skip for var with expr_start non-NULL"
+ \ "in f_exists ok?"
+ endif
+ endif
+
+ unlet! var caught taken expected
+ call delete(WA_t5)
+ unlet! WA_t5
+ delfunction WA_t5
+
+endif
+
+Xcheck 134217728
+
+
+"-------------------------------------------------------------------------------
+" Test 79: Throwing one of several errors for the same command {{{1
+"
+" When several errors appear in a row (for instance during expression
+" evaluation), the first as the most specific one is used when
+" throwing an error exception. If, however, a syntax error is
+" detected afterwards, this one is used for the error exception.
+" On a syntax error, the next command is not executed, on a normal
+" error, however, it is (relevant only in a function without the
+" "abort" flag). v:errmsg is not set.
+"
+" If throwing error exceptions is configured off, v:errmsg is always
+" set to the latest error message, that is, to the more general
+" message or the syntax error, respectively.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+XloopINIT 1 2
+
+function! NEXT(cmd)
+ exec a:cmd . " | Xloop 1"
+endfunction
+
+call NEXT('echo novar') " X: 1 * 1 (checks nextcmd)
+XloopNEXT
+call NEXT('let novar #') " X: 0 * 2 (skips nextcmd)
+XloopNEXT
+call NEXT('unlet novar #') " X: 0 * 4 (skips nextcmd)
+XloopNEXT
+call NEXT('let {novar}') " X: 0 * 8 (skips nextcmd)
+XloopNEXT
+call NEXT('unlet{ novar}') " X: 0 * 16 (skips nextcmd)
+
+function! EXEC(cmd)
+ exec a:cmd
+endfunction
+
+function! MATCH(expected, msg, enr, emsg)
+ let msg = a:msg
+ if a:enr == ""
+ Xout "TODO: Add message number for:" a:emsg
+ let msg = ":" . msg
+ endif
+ let english = v:lang == "C" || v:lang =~ '^[Ee]n'
+ if msg !~ '^'.a:enr.':' || (english && msg !~ a:emsg)
+ let match = 0
+ if a:expected " no match although expected
+ if a:msg == ""
+ Xout "Message missing."
+ else
+ let msg = escape(msg, '"')
+ Xout "Unexpected message:" msg
+ Xout "Expected:" a:enr . ": " . a:emsg
+ endif
+ endif
+ else
+ let match = 1
+ if !a:expected " match although not expected
+ let msg = escape(msg, '"')
+ Xout "Unexpected message:" msg
+ Xout "Expected none."
+ endif
+ endif
+ return match
+endfunction
+
+try
+
+ while 1 " dummy loop
+ try
+ let v:errmsg = ""
+ let caught = 0
+ let thrmsg = ""
+ call EXEC('echo novar') " normal error
+ catch /^Vim\((\a\+)\)\=:/
+ let caught = 1
+ let thrmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "")
+ finally
+ Xpath 32 " X: 32
+ if !caught
+ if !$VIMNOERRTHROW
+ Xpath 64 " X: 0
+ endif
+ elseif !MATCH(1, thrmsg, 'E121', "Undefined variable")
+ \ || v:errmsg != ""
+ Xpath 128 " X: 0
+ endif
+ if !caught && !MATCH(1, v:errmsg, 'E15', "Invalid expression")
+ Xpath 256 " X: 0
+ endif
+ break " discard error if $VIMNOERRTHROW == 1
+ endtry
+ endwhile
+
+ Xpath 512 " X: 512
+ let cmd = "let"
+ XloopINIT 1024 32
+ while cmd != ""
+ try
+ let v:errmsg = ""
+ let caught = 0
+ let thrmsg = ""
+ call EXEC(cmd . ' novar #') " normal plus syntax error
+ catch /^Vim\((\a\+)\)\=:/
+ let caught = 1
+ let thrmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "")
+ finally
+ Xloop 1 " X: 1024 * (1 + 32)
+ if !caught
+ if !$VIMNOERRTHROW
+ Xloop 2 " X: 0
+ endif
+ else
+ if cmd == "let"
+ let match = MATCH(0, thrmsg, 'E121', "Undefined variable")
+ elseif cmd == "unlet"
+ let match = MATCH(0, thrmsg, 'E108', "No such variable")
+ endif
+ if match " normal error
+ Xloop 4 " X: 0
+ endif
+ if !MATCH(1, thrmsg, 'E488', "Trailing characters")
+ \|| v:errmsg != ""
+ " syntax error
+ Xloop 8 " X: 0
+ endif
+ endif
+ if !caught && !MATCH(1, v:errmsg, 'E488', "Trailing characters")
+ " last error
+ Xloop 16 " X: 0
+ endif
+ if cmd == "let"
+ let cmd = "unlet"
+ else
+ let cmd = ""
+ endif
+ XloopNEXT
+ continue " discard error if $VIMNOERRTHROW == 1
+ endtry
+ endwhile
+
+ Xpath 1048576 " X: 1048576
+ let cmd = "let"
+ XloopINIT 2097152 32
+ while cmd != ""
+ try
+ let v:errmsg = ""
+ let caught = 0
+ let thrmsg = ""
+ call EXEC(cmd . ' {novar}') " normal plus syntax error
+ catch /^Vim\((\a\+)\)\=:/
+ let caught = 1
+ let thrmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "")
+ finally
+ Xloop 1 " X: 2097152 * (1 + 32)
+ if !caught
+ if !$VIMNOERRTHROW
+ Xloop 2 " X: 0
+ endif
+ else
+ if MATCH(0, thrmsg, 'E121', "Undefined variable") " normal error
+ Xloop 4 " X: 0
+ endif
+ if !MATCH(1, thrmsg, 'E475', 'Invalid argument\>')
+ \ || v:errmsg != "" " syntax error
+ Xloop 8 " X: 0
+ endif
+ endif
+ if !caught && !MATCH(1, v:errmsg, 'E475', 'Invalid argument\>')
+ " last error
+ Xloop 16 " X: 0
+ endif
+ if cmd == "let"
+ let cmd = "unlet"
+ else
+ let cmd = ""
+ endif
+ XloopNEXT
+ continue " discard error if $VIMNOERRTHROW == 1
+ endtry
+ endwhile
+
+catch /.*/
+ " The Xpath command does not accept 2^31 (negative); add explicitly:
+ let Xpath = Xpath + 2147483648 " X: 0
+ Xout v:exception "in" v:throwpoint
+endtry
+
+unlet! next_command thrmsg match
+delfunction NEXT
+delfunction EXEC
+delfunction MATCH
+
+Xcheck 70288929
+
+
+"-------------------------------------------------------------------------------
+" Test 80: Syntax error in expression for illegal :elseif {{{1
+"
+" If there is a syntax error in the expression after an illegal
+" :elseif, an error message is given (or an error exception thrown)
+" for the illegal :elseif rather than the expression error.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+function! MSG(enr, emsg)
+ let english = v:lang == "C" || v:lang =~ '^[Ee]n'
+ if a:enr == ""
+ Xout "TODO: Add message number for:" a:emsg
+ let v:errmsg = ":" . v:errmsg
+ endif
+ let match = 1
+ if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg)
+ let match = 0
+ if v:errmsg == ""
+ Xout "Message missing."
+ else
+ let v:errmsg = escape(v:errmsg, '"')
+ Xout "Unexpected message:" v:errmsg
+ endif
+ endif
+ return match
+endfunction
+
+let v:errmsg = ""
+if 0
+else
+elseif 1 ||| 2
+endif
+Xpath 1 " X: 1
+if !MSG('E584', ":elseif after :else")
+ Xpath 2 " X: 0
+endif
+
+let v:errmsg = ""
+if 1
+else
+elseif 1 ||| 2
+endif
+Xpath 4 " X: 4
+if !MSG('E584', ":elseif after :else")
+ Xpath 8 " X: 0
+endif
+
+let v:errmsg = ""
+elseif 1 ||| 2
+Xpath 16 " X: 16
+if !MSG('E582', ":elseif without :if")
+ Xpath 32 " X: 0
+endif
+
+let v:errmsg = ""
+while 1
+ elseif 1 ||| 2
+endwhile
+Xpath 64 " X: 64
+if !MSG('E582', ":elseif without :if")
+ Xpath 128 " X: 0
+endif
+
+while 1
+ try
+ try
+ let v:errmsg = ""
+ let caught = 0
+ if 0
+ else
+ elseif 1 ||| 2
+ endif
+ catch /^Vim\((\a\+)\)\=:/
+ let caught = 1
+ let v:errmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "")
+ finally
+ Xpath 256 " X: 256
+ if !caught && !$VIMNOERRTHROW
+ Xpath 512 " X: 0
+ endif
+ if !MSG('E584', ":elseif after :else")
+ Xpath 1024 " X: 0
+ endif
+ endtry
+ catch /.*/
+ Xpath 2048 " X: 0
+ Xout v:exception "in" v:throwpoint
+ finally
+ break " discard error for $VIMNOERRTHROW
+ endtry
+endwhile
+
+while 1
+ try
+ try
+ let v:errmsg = ""
+ let caught = 0
+ if 1
+ else
+ elseif 1 ||| 2
+ endif
+ catch /^Vim\((\a\+)\)\=:/
+ let caught = 1
+ let v:errmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "")
+ finally
+ Xpath 4096 " X: 4096
+ if !caught && !$VIMNOERRTHROW
+ Xpath 8192 " X: 0
+ endif
+ if !MSG('E584', ":elseif after :else")
+ Xpath 16384 " X: 0
+ endif
+ endtry
+ catch /.*/
+ Xpath 32768 " X: 0
+ Xout v:exception "in" v:throwpoint
+ finally
+ break " discard error for $VIMNOERRTHROW
+ endtry
+endwhile
+
+while 1
+ try
+ try
+ let v:errmsg = ""
+ let caught = 0
+ elseif 1 ||| 2
+ catch /^Vim\((\a\+)\)\=:/
+ let caught = 1
+ let v:errmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "")
+ finally
+ Xpath 65536 " X: 65536
+ if !caught && !$VIMNOERRTHROW
+ Xpath 131072 " X: 0
+ endif
+ if !MSG('E582', ":elseif without :if")
+ Xpath 262144 " X: 0
+ endif
+ endtry
+ catch /.*/
+ Xpath 524288 " X: 0
+ Xout v:exception "in" v:throwpoint
+ finally
+ break " discard error for $VIMNOERRTHROW
+ endtry
+endwhile
+
+while 1
+ try
+ try
+ let v:errmsg = ""
+ let caught = 0
+ while 1
+ elseif 1 ||| 2
+ endwhile
+ catch /^Vim\((\a\+)\)\=:/
+ let caught = 1
+ let v:errmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "")
+ finally
+ Xpath 1048576 " X: 1048576
+ if !caught && !$VIMNOERRTHROW
+ Xpath 2097152 " X: 0
+ endif
+ if !MSG('E582', ":elseif without :if")
+ Xpath 4194304 " X: 0
+ endif
+ endtry
+ catch /.*/
+ Xpath 8388608 " X: 0
+ Xout v:exception "in" v:throwpoint
+ finally
+ break " discard error for $VIMNOERRTHROW
+ endtry
+endwhile
+
+Xpath 16777216 " X: 16777216
+
+unlet! caught
+delfunction MSG
+
+Xcheck 17895765
+
+
+"-------------------------------------------------------------------------------
+" Test 81: Discarding exceptions after an error or interrupt {{{1
+"
+" When an exception is thrown from inside a :try conditional without
+" :catch and :finally clauses and an error or interrupt occurs before
+" the :endtry is reached, the exception is discarded.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+if ExtraVim()
+ try
+ Xpath 1 " X: 1
+ try
+ Xpath 2 " X: 2
+ throw "arrgh"
+ Xpath 4 " X: 0
+" if 1
+ Xpath 8 " X: 0
+ " error after :throw: missing :endif
+ endtry
+ Xpath 16 " X: 0
+ catch /arrgh/
+ Xpath 32 " X: 0
+ endtry
+ Xpath 64 " X: 0
+endif
+
+if ExtraVim()
+ try
+ Xpath 128 " X: 128
+ try
+ Xpath 256 " X: 256
+ throw "arrgh"
+ Xpath 512 " X: 0
+ endtry " INTERRUPT
+ Xpath 1024 " X: 0
+ catch /arrgh/
+ Xpath 2048 " X: 0
+ endtry
+ Xpath 4096 " X: 0
+endif
+
+Xcheck 387
+
+
+"-------------------------------------------------------------------------------
+" Test 82: Ignoring :catch clauses after an error or interrupt {{{1
+"
+" When an exception is thrown and an error or interrupt occurs before
+" the matching :catch clause is reached, the exception is discarded
+" and the :catch clause is ignored (also for the error or interrupt
+" exception being thrown then).
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+if ExtraVim()
+ try
+ try
+ Xpath 1 " X: 1
+ throw "arrgh"
+ Xpath 2 " X: 0
+" if 1
+ Xpath 4 " X: 0
+ " error after :throw: missing :endif
+ catch /.*/
+ Xpath 8 " X: 0
+ Xout v:exception "in" ExtraVimThrowpoint()
+ catch /.*/
+ Xpath 16 " X: 0
+ Xout v:exception "in" ExtraVimThrowpoint()
+ endtry
+ Xpath 32 " X: 0
+ catch /arrgh/
+ Xpath 64 " X: 0
+ endtry
+ Xpath 128 " X: 0
+endif
+
+if ExtraVim()
+ function! E()
+ try
+ try
+ Xpath 256 " X: 256
+ throw "arrgh"
+ Xpath 512 " X: 0
+" if 1
+ Xpath 1024 " X: 0
+ " error after :throw: missing :endif
+ catch /.*/
+ Xpath 2048 " X: 0
+ Xout v:exception "in" ExtraVimThrowpoint()
+ catch /.*/
+ Xpath 4096 " X: 0
+ Xout v:exception "in" ExtraVimThrowpoint()
+ endtry
+ Xpath 8192 " X: 0
+ catch /arrgh/
+ Xpath 16384 " X: 0
+ endtry
+ endfunction
+
+ call E()
+ Xpath 32768 " X: 0
+endif
+
+if ExtraVim()
+ try
+ try
+ Xpath 65536 " X: 65536
+ throw "arrgh"
+ Xpath 131072 " X: 0
+ catch /.*/ "INTERRUPT
+ Xpath 262144 " X: 0
+ Xout v:exception "in" ExtraVimThrowpoint()
+ catch /.*/
+ Xpath 524288 " X: 0
+ Xout v:exception "in" ExtraVimThrowpoint()
+ endtry
+ Xpath 1048576 " X: 0
+ catch /arrgh/
+ Xpath 2097152 " X: 0
+ endtry
+ Xpath 4194304 " X: 0
+endif
+
+if ExtraVim()
+ function I()
+ try
+ try
+ Xpath 8388608 " X: 8388608
+ throw "arrgh"
+ Xpath 16777216 " X: 0
+ catch /.*/ "INTERRUPT
+ Xpath 33554432 " X: 0
+ Xout v:exception "in" ExtraVimThrowpoint()
+ catch /.*/
+ Xpath 67108864 " X: 0
+ Xout v:exception "in" ExtraVimThrowpoint()
+ endtry
+ Xpath 134217728 " X: 0
+ catch /arrgh/
+ Xpath 268435456 " X: 0
+ endtry
+ endfunction
+
+ call I()
+ Xpath 536870912 " X: 0
+endif
+
+Xcheck 8454401
+
+
+"-------------------------------------------------------------------------------
+" Test 83: Executing :finally clauses after an error or interrupt {{{1
+"
+" When an exception is thrown and an error or interrupt occurs before
+" the :finally of the innermost :try is reached, the exception is
+" discarded and the :finally clause is executed.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+if ExtraVim()
+ try
+ Xpath 1 " X: 1
+ try
+ Xpath 2 " X: 2
+ throw "arrgh"
+ Xpath 4 " X: 0
+" if 1
+ Xpath 8 " X: 0
+ " error after :throw: missing :endif
+ finally
+ Xpath 16 " X: 16
+ endtry
+ Xpath 32 " X: 0
+ catch /arrgh/
+ Xpath 64 " X: 0
+ endtry
+ Xpath 128 " X: 0
+endif
+
+if ExtraVim()
+ try
+ Xpath 256 " X: 256
+ try
+ Xpath 512 " X: 512
+ throw "arrgh"
+ Xpath 1024 " X: 0
+ finally "INTERRUPT
+ Xpath 2048 " X: 2048
+ endtry
+ Xpath 4096 " X: 0
+ catch /arrgh/
+ Xpath 8192 " X: 0
+ endtry
+ Xpath 16384 " X: 0
+endif
+
+Xcheck 2835
+
+
+"-------------------------------------------------------------------------------
+" Test 84: Exceptions in autocommand sequences. {{{1
+"
+" When an exception occurs in a sequence of autocommands for
+" a specific event, the rest of the sequence is not executed. The
+" command that triggered the autocommand execution aborts, and the
+" exception is propagated to the caller.
+"
+" For the FuncUndefined event under a function call expression or
+" :call command, the function is not executed, even when it has
+" been defined by the autocommands before the exception occurred.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+if ExtraVim()
+
+ function! INT()
+ "INTERRUPT
+ let dummy = 0
+ endfunction
+
+ aug TMP
+ autocmd!
+
+ autocmd User x1 Xpath 1 " X: 1
+ autocmd User x1 throw "x1"
+ autocmd User x1 Xpath 2 " X: 0
+
+ autocmd User x2 Xpath 4 " X: 4
+ autocmd User x2 asdf
+ autocmd User x2 Xpath 8 " X: 0
+
+ autocmd User x3 Xpath 16 " X: 16
+ autocmd User x3 call INT()
+ autocmd User x3 Xpath 32 " X: 0
+
+ autocmd FuncUndefined U1 function! U1()
+ autocmd FuncUndefined U1 Xpath 64 " X: 0
+ autocmd FuncUndefined U1 endfunction
+ autocmd FuncUndefined U1 Xpath 128 " X: 128
+ autocmd FuncUndefined U1 throw "U1"
+ autocmd FuncUndefined U1 Xpath 256 " X: 0
+
+ autocmd FuncUndefined U2 function! U2()
+ autocmd FuncUndefined U2 Xpath 512 " X: 0
+ autocmd FuncUndefined U2 endfunction
+ autocmd FuncUndefined U2 Xpath 1024 " X: 1024
+ autocmd FuncUndefined U2 ASDF
+ autocmd FuncUndefined U2 Xpath 2048 " X: 0
+
+ autocmd FuncUndefined U3 function! U3()
+ autocmd FuncUndefined U3 Xpath 4096 " X: 0
+ autocmd FuncUndefined U3 endfunction
+ autocmd FuncUndefined U3 Xpath 8192 " X: 8192
+ autocmd FuncUndefined U3 call INT()
+ autocmd FuncUndefined U3 Xpath 16384 " X: 0
+ aug END
+
+ try
+ try
+ Xpath 32768 " X: 32768
+ doautocmd User x1
+ catch /x1/
+ Xpath 65536 " X: 65536
+ endtry
+
+ while 1
+ try
+ Xpath 131072 " X: 131072
+ let caught = 0
+ doautocmd User x2
+ catch /asdf/
+ let caught = 1
+ finally
+ Xpath 262144 " X: 262144
+ if !caught && !$VIMNOERRTHROW
+ Xpath 524288 " X: 0
+ " Propagate uncaught error exception,
+ else
+ " ... but break loop for caught error exception,
+ " or discard error and break loop if $VIMNOERRTHROW
+ break
+ endif
+ endtry
+ endwhile
+
+ while 1
+ try
+ Xpath 1048576 " X: 1048576
+ let caught = 0
+ doautocmd User x3
+ catch /Vim:Interrupt/
+ let caught = 1
+ finally
+ Xpath 2097152 " X: 2097152
+ if !caught && !$VIMNOINTTHROW
+ Xpath 4194304 " X: 0
+ " Propagate uncaught interrupt exception,
+ else
+ " ... but break loop for caught interrupt exception,
+ " or discard interrupt and break loop if $VIMNOINTTHROW
+ break
+ endif
+ endtry
+ endwhile
+
+ if exists("*U1") | delfunction U1 | endif
+ if exists("*U2") | delfunction U2 | endif
+ if exists("*U3") | delfunction U3 | endif
+
+ try
+ Xpath 8388608 " X: 8388608
+ call U1()
+ catch /U1/
+ Xpath 16777216 " X: 16777216
+ endtry
+
+ while 1
+ try
+ Xpath 33554432 " X: 33554432
+ let caught = 0
+ call U2()
+ catch /ASDF/
+ let caught = 1
+ finally
+ Xpath 67108864 " X: 67108864
+ if !caught && !$VIMNOERRTHROW
+ Xpath 134217728 " X: 0
+ " Propagate uncaught error exception,
+ else
+ " ... but break loop for caught error exception,
+ " or discard error and break loop if $VIMNOERRTHROW
+ break
+ endif
+ endtry
+ endwhile
+
+ while 1
+ try
+ Xpath 268435456 " X: 268435456
+ let caught = 0
+ call U3()
+ catch /Vim:Interrupt/
+ let caught = 1
+ finally
+ Xpath 536870912 " X: 536870912
+ if !caught && !$VIMNOINTTHROW
+ Xpath 1073741824 " X: 0
+ " Propagate uncaught interrupt exception,
+ else
+ " ... but break loop for caught interrupt exception,
+ " or discard interrupt and break loop if $VIMNOINTTHROW
+ break
+ endif
+ endtry
+ endwhile
+ catch /.*/
+ " The Xpath command does not accept 2^31 (negative); display explicitly:
+ exec "!echo 2147483648 >>" . g:ExtraVimResult
+ Xout "Caught" v:exception "in" v:throwpoint
+ endtry
+
+ unlet caught
+ delfunction INT
+ delfunction U1
+ delfunction U2
+ delfunction U3
+ au! TMP
+ aug! TMP
+endif
+
+Xcheck 934782101
+
+
+"-------------------------------------------------------------------------------
+" Test 85: Error exceptions in autocommands for I/O command events {{{1
+"
+" When an I/O command is inside :try/:endtry, autocommands to be
+" executed after it should be skipped on an error (exception) in the
+" command itself or in autocommands to be executed before the command.
+" In the latter case, the I/O command should not be executed either.
+" Example 1: BufWritePre, :write, BufWritePost
+" Example 2: FileReadPre, :read, FileReadPost.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+function! MSG(enr, emsg)
+ let english = v:lang == "C" || v:lang =~ '^[Ee]n'
+ if a:enr == ""
+ Xout "TODO: Add message number for:" a:emsg
+ let v:errmsg = ":" . v:errmsg
+ endif
+ let match = 1
+ if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg)
+ let match = 0
+ if v:errmsg == ""
+ Xout "Message missing."
+ else
+ let v:errmsg = escape(v:errmsg, '"')
+ Xout "Unexpected message:" v:errmsg
+ endif
+ endif
+ return match
+endfunction
+
+" Remove the autocommands for the events specified as arguments in all used
+" autogroups.
+function! Delete_autocommands(...)
+ let augfile = tempname()
+ while 1
+ try
+ exec "redir >" . augfile
+ aug
+ redir END
+ exec "edit" augfile
+ g/^$/d
+ norm G$
+ let wrap = "w"
+ while search('\%( \|^\)\@<=.\{-}\%( \)\@=', wrap) > 0
+ let wrap = "W"
+ exec "norm y/ \n"
+ let argno = 1
+ while argno <= a:0
+ exec "au!" escape(@", " ") a:{argno}
+ let argno = argno + 1
+ endwhile
+ endwhile
+ catch /.*/
+ finally
+ bwipeout!
+ call delete(augfile)
+ break " discard errors for $VIMNOERRTHROW
+ endtry
+ endwhile
+endfunction
+
+call Delete_autocommands("BufWritePre", "BufWritePost")
+
+while 1
+ try
+ try
+ let post = 0
+ aug TMP
+ au! BufWritePost * let post = 1
+ aug END
+ let caught = 0
+ write /n/o/n/e/x/i/s/t/e/n/t
+ catch /^Vim(write):/
+ let caught = 1
+ let v:errmsg = substitute(v:exception, '^Vim(write):', '', "")
+ finally
+ Xpath 1 " X: 1
+ if !caught && !$VIMNOERRTHROW
+ Xpath 2 " X: 0
+ endif
+ let v:errmsg = substitute(v:errmsg, '^"/n/o/n/e/x/i/s/t/e/n/t" ',
+ \ '', "")
+ if !MSG('E212', "Can't open file for writing")
+ Xpath 4 " X: 0
+ endif
+ if post
+ Xpath 8 " X: 0
+ Xout "BufWritePost commands executed after write error"
+ endif
+ au! TMP
+ aug! TMP
+ endtry
+ catch /.*/
+ Xpath 16 " X: 0
+ Xout v:exception "in" v:throwpoint
+ finally
+ break " discard error for $VIMNOERRTHROW
+ endtry
+endwhile
+
+while 1
+ try
+ try
+ let post = 0
+ aug TMP
+ au! BufWritePre * asdf
+ au! BufWritePost * let post = 1
+ aug END
+ let tmpfile = tempname()
+ let caught = 0
+ exec "write" tmpfile
+ catch /^Vim\((write)\)\=:/
+ let caught = 1
+ let v:errmsg = substitute(v:exception, '^Vim\((write)\)\=:', '', "")
+ finally
+ Xpath 32 " X: 32
+ if !caught && !$VIMNOERRTHROW
+ Xpath 64 " X: 0
+ endif
+ let v:errmsg = substitute(v:errmsg, '^"'.tmpfile.'" ', '', "")
+ if !MSG('E492', "Not an editor command")
+ Xpath 128 " X: 0
+ endif
+ if filereadable(tmpfile)
+ Xpath 256 " X: 0
+ Xout ":write command not suppressed after BufWritePre error"
+ endif
+ if post
+ Xpath 512 " X: 0
+ Xout "BufWritePost commands executed after BufWritePre error"
+ endif
+ au! TMP
+ aug! TMP
+ endtry
+ catch /.*/
+ Xpath 1024 " X: 0
+ Xout v:exception "in" v:throwpoint
+ finally
+ break " discard error for $VIMNOERRTHROW
+ endtry
+endwhile
+
+call delete(tmpfile)
+
+call Delete_autocommands("BufWritePre", "BufWritePost",
+ \ "BufReadPre", "BufReadPost", "FileReadPre", "FileReadPost")
+
+while 1
+ try
+ try
+ let post = 0
+ aug TMP
+ au! FileReadPost * let post = 1
+ aug END
+ let caught = 0
+ read /n/o/n/e/x/i/s/t/e/n/t
+ catch /^Vim(read):/
+ let caught = 1
+ let v:errmsg = substitute(v:exception, '^Vim(read):', '', "")
+ finally
+ Xpath 2048 " X: 2048
+ if !caught && !$VIMNOERRTHROW
+ Xpath 4096 " X: 0
+ endif
+ let v:errmsg = substitute(v:errmsg, ' /n/o/n/e/x/i/s/t/e/n/t$',
+ \ '', "")
+ if !MSG('E484', "Can't open file")
+ Xpath 8192 " X: 0
+ endif
+ if post
+ Xpath 16384 " X: 0
+ Xout "FileReadPost commands executed after write error"
+ endif
+ au! TMP
+ aug! TMP
+ endtry
+ catch /.*/
+ Xpath 32768 " X: 0
+ Xout v:exception "in" v:throwpoint
+ finally
+ break " discard error for $VIMNOERRTHROW
+ endtry
+endwhile
+
+while 1
+ try
+ let infile = tempname()
+ let tmpfile = tempname()
+ exec "!echo XYZ >" . infile
+ exec "edit" tmpfile
+ try
+ Xpath 65536 " X: 65536
+ try
+ let post = 0
+ aug TMP
+ au! FileReadPre * asdf
+ au! FileReadPost * let post = 1
+ aug END
+ let caught = 0
+ exec "0read" infile
+ catch /^Vim\((read)\)\=:/
+ let caught = 1
+ let v:errmsg = substitute(v:exception, '^Vim\((read)\)\=:', '',
+ \ "")
+ finally
+ Xpath 131072 " X: 131072
+ if !caught && !$VIMNOERRTHROW
+ Xpath 262144 " X: 0
+ endif
+ let v:errmsg = substitute(v:errmsg, ' '.infile.'$', '', "")
+ if !MSG('E492', "Not an editor command")
+ Xpath 524288 " X: 0
+ endif
+ if getline("1") == "XYZ"
+ Xpath 1048576 " X: 0
+ Xout ":read command not suppressed after FileReadPre error"
+ endif
+ if post
+ Xpath 2097152 " X: 0
+ Xout "FileReadPost commands executed after " .
+ \ "FileReadPre error"
+ endif
+ au! TMP
+ aug! TMP
+ endtry
+ finally
+ bwipeout!
+ endtry
+ catch /.*/
+ Xpath 4194304 " X: 0
+ Xout v:exception "in" v:throwpoint
+ finally
+ break " discard error for $VIMNOERRTHROW
+ endtry
+endwhile
+
+call delete(infile)
+call delete(tmpfile)
+unlet! caught post infile tmpfile
+delfunction MSG
+delfunction Delete_autocommands
+
+Xcheck 198689
+
+"-------------------------------------------------------------------------------
+" Test 86: setloclist crash {{{1
+"
+" Executing a setloclist() on BufUnload shouldn't crash Vim
+"-------------------------------------------------------------------------------
+
+func F
+ au BufUnload * :call setloclist(0, [{'bufnr':1, 'lnum':1, 'col':1, 'text': 'tango down'}])
+
+ :lvimgrep /.*/ *.mak
+endfunc
+
+XpathINIT
+
+ExecAsScript F
+
+delfunction F
+Xout "No Crash for vimgrep on BufUnload"
+Xcheck 0
+
+"-------------------------------------------------------------------------------
+" Test 87 using (expr) ? funcref : funcref {{{1
+"
+" Vim needs to correctly parse the funcref and even when it does
+" not execute the funcref, it needs to consume the trailing ()
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+func Add2(x1, x2)
+ return a:x1 + a:x2
+endfu
+
+func GetStr()
+ return "abcdefghijklmnopqrstuvwxyp"
+endfu
+
+echo function('Add2')(2,3)
+
+Xout 1 ? function('Add2')(1,2) : function('Add2')(2,3)
+Xout 0 ? function('Add2')(1,2) : function('Add2')(2,3)
+" Make sure, GetStr() still works.
+Xout GetStr()[0:10]
+
+
+delfunction GetStr
+delfunction Add2
+Xout "Successfully executed funcref Add2"
+
+Xcheck 0
+
+"-------------------------------------------------------------------------------
+" Test 88: $VIMNOERRTHROW and $VIMNOINTTHROW support {{{1
+"
+" It is possible to configure Vim for throwing exceptions on error
+" or interrupt, controlled by variables $VIMNOERRTHROW and
+" $VIMNOINTTHROW. This is just for increasing the number of tests.
+" All tests here should run for all four combinations of setting
+" these variables to 0 or 1. The variables are intended for the
+" development phase only. In the final release, Vim should be
+" configured to always use error and interrupt exceptions.
+"
+" The test result is "OK",
+"
+" - if the $VIMNOERRTHROW and the $VIMNOINTTHROW control are not
+" configured and exceptions are thrown on error and on
+" interrupt.
+"
+" - if the $VIMNOERRTHROW or the $VIMNOINTTHROW control is
+" configured and works as intended.
+"
+" What actually happens, is shown in the test output.
+"
+" Otherwise, the test result is "FAIL", and the test output describes
+" the problem.
+"
+" IMPORTANT: This must be the last test because it sets $VIMNOERRTHROW and
+" $VIMNOINTTHROW.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+if ExtraVim()
+
+ function! ThrowOnError()
+ XloopNEXT
+ let caught = 0
+ try
+ Xloop 1 " X: 1 + 8 + 64
+ asdf
+ catch /.*/
+ let caught = 1 " error exception caught
+ finally
+ Xloop 2 " X: 2 + 16 + 128
+ return caught " discard aborting error
+ endtry
+ Xloop 4 " X: 0
+ endfunction
+
+ let quits_skipped = 0
+
+ function! ThrowOnInterrupt()
+ XloopNEXT
+ let caught = 0
+ try
+ Xloop 1 " X: (1 + 8 + 64) * 512
+ "INTERRUPT3
+ let dummy = 0
+ let g:quits_skipped = g:quits_skipped + 1
+ catch /.*/
+ let caught = 1 " interrupt exception caught
+ finally
+ Xloop 2 " X: (2 + 16 + 128) * 512
+ return caught " discard interrupt
+ endtry
+ Xloop 4 " X: 0
+ endfunction
+
+ function! CheckThrow(Type)
+ execute 'return ThrowOn' . a:Type . '()'
+ endfunction
+
+ function! CheckConfiguration(type) " type is "error" or "interrupt"
+
+ let type = a:type
+ let Type = substitute(type, '.*', '\u&', "")
+ let VAR = '$VIMNO' . substitute(type, '\(...\).*', '\U\1', "") . 'THROW'
+
+ if type == "error"
+ XloopINIT! 1 8
+ elseif type == "interrupt"
+ XloopINIT! 512 8
+ endif
+
+ exec 'let requested_for_tests = exists(VAR) && ' . VAR . ' == 0'
+ exec 'let suppressed_for_tests = ' . VAR . ' != 0'
+ let used_in_tests = CheckThrow(Type)
+
+ exec 'let ' . VAR . ' = 0'
+ let request_works = CheckThrow(Type)
+
+ exec 'let ' . VAR . ' = 1'
+ let suppress_works = !CheckThrow(Type)
+
+ if type == "error"
+ XloopINIT! 262144 8
+ elseif type == "interrupt"
+ XloopINIT! 2097152 8
+
+ if g:quits_skipped != 0
+ Xloop 1 " X: 0*2097152
+ Xout "Test environment error. Interrupt breakpoints skipped: "
+ \ . g:quits_skipped . ".\n"
+ \ . "Cannot check whether interrupt exceptions are thrown."
+ return
+ endif
+ endif
+
+ let failure =
+ \ !suppressed_for_tests && !used_in_tests
+ \ || !request_works
+
+ let contradiction =
+ \ used_in_tests
+ \ ? suppressed_for_tests && !request_works
+ \ : !suppressed_for_tests
+
+ if failure
+ " Failure in configuration.
+ Xloop 2 " X: 0 * 2* (262144 + 2097152)
+ elseif contradiction
+ " Failure in test logic. Should not happen.
+ Xloop 4 " X: 0 * 4 * (262144 + 2097152)
+ endif
+
+ let var_control_configured =
+ \ request_works != used_in_tests
+ \ || suppress_works == used_in_tests
+
+ let var_control_not_configured =
+ \ requested_for_tests || suppressed_for_tests
+ \ ? request_works && !suppress_works
+ \ : request_works == used_in_tests
+ \ && suppress_works != used_in_tests
+
+ let with = used_in_tests ? "with" : "without"
+
+ let set = suppressed_for_tests ? "non-zero" :
+ \ requested_for_tests ? "0" : "unset"
+
+ let although = contradiction && !var_control_not_configured
+ \ ? ",\nalthough "
+ \ : ".\n"
+
+ let output = "All tests were run " . with . " throwing exceptions on "
+ \ . type . although
+
+ if !var_control_not_configured
+ let output = output . VAR . " was " . set . "."
+
+ if !request_works && !requested_for_tests
+ let output = output .
+ \ "\n" . Type . " exceptions are not thrown when " . VAR .
+ \ " is\nset to 0."
+ endif
+
+ if !suppress_works && (!used_in_tests ||
+ \ !request_works &&
+ \ !requested_for_tests && !suppressed_for_tests)
+ let output = output .
+ \ "\n" . Type . " exceptions are thrown when " . VAR .
+ \ " is set to 1."
+ endif
+
+ if !failure && var_control_configured
+ let output = output .
+ \ "\nRun tests also with " . substitute(VAR, '^\$', '', "")
+ \ . "=" . used_in_tests . "."
+ \ . "\nThis is for testing in the development phase only."
+ \ . " Remove the \n"
+ \ . VAR . " control in the final release."
+ endif
+ else
+ let output = output .
+ \ "The " . VAR . " control is not configured."
+ endif
+
+ Xout output
+ endfunction
+
+ call CheckConfiguration("error")
+ Xpath 16777216 " X: 16777216
+ call CheckConfiguration("interrupt")
+ Xpath 33554432 " X: 33554432
+endif
+
+Xcheck 50443995
+
+" IMPORTANT: No test should be added after this test because it changes
+" $VIMNOERRTHROW and $VIMNOINTTHROW.
+
+
+"-------------------------------------------------------------------------------
+" 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/testdir/test5.in b/src/testdir/test5.in
new file mode 100644
index 0000000000..e19e20d59b
--- /dev/null
+++ b/src/testdir/test5.in
@@ -0,0 +1,29 @@
+Test for autocommand that deletes the current buffer on BufLeave event.
+Also test deleting the last buffer, should give a new, empty buffer.
+
+STARTTEST
+:so small.vim
+:au BufLeave Xxx bwipe
+/start of
+:.,/end of/w! Xxx " write test file Xxx
+:sp Xxx " split to Xxx
+:bwipe " delete buffer Xxx, now we're back here
+G?this is a
+othis is some more text
+: " Append some text to this file
+:?start?,$w! test.out " Write current file contents
+:bwipe test.out " delete alternate buffer
+:au bufleave test5.in bwipe
+:bwipe! " delete current buffer, get an empty one
+ithis is another test line:w >>test.out
+: " append an extra line to the output file
+:qa!
+ENDTEST
+
+start of test file Xxx
+vim: set noai :
+ this is a test
+ this is a test
+ this is a test
+ this is a test
+end of test file Xxx
diff --git a/src/testdir/test5.ok b/src/testdir/test5.ok
new file mode 100644
index 0000000000..6743060794
--- /dev/null
+++ b/src/testdir/test5.ok
@@ -0,0 +1,9 @@
+start of test file Xxx
+vim: set noai :
+ this is a test
+ this is a test
+ this is a test
+ this is a test
+this is some more text
+end of test file Xxx
+this is another test line
diff --git a/src/testdir/test50.in b/src/testdir/test50.in
new file mode 100644
index 0000000000..0cbf4bf6d6
--- /dev/null
+++ b/src/testdir/test50.in
@@ -0,0 +1,90 @@
+Test for shortpathname ':8' extension.
+Only for use on Win32 systems!
+
+STARTTEST
+:so small.vim
+:fun! TestIt(file, bits, expected)
+ let res=fnamemodify(a:file,a:bits)
+ if a:expected == ''
+ echo "'".a:file."'->(".a:bits.")->'".res."'"
+ else
+ if substitute(res,'/','\\', 'g') != substitute( a:expected, '/','\\', 'g')
+ echo "FAILED: '".a:file."'->(".a:bits.")->'".res."'"
+ echo "Expected: '".a:expected."'"
+ else
+ echo "OK"
+ endif
+ endif
+endfun
+:fun! MakeDir( dirname )
+ "exe '!mkdir '.substitute(a:dirname,'/','\\','g')
+ call system('mkdir '.substitute(a:dirname,'/','\\','g'))
+endfun
+:fun! RMDir( dirname)
+ "exe '!rmdir '.substitute(a:dirname,'/','\\','g')
+ call system('rmdir '.substitute(a:dirname,'/','\\','g'))
+endfun
+:fun! MakeFile( filename)
+ "exe '!copy nul '.substitute(a:filename,'/','\\','g')
+ call system('copy nul '.substitute(a:filename,'/','\\','g'))
+endfun
+:fun! TestColonEight()
+ redir! >test.out
+ " This could change for CygWin to //cygdrive/c
+ let dir1='c:/x.x.y'
+ if filereadable(dir1) || isdirectory(dir1)
+ echo "FATAL: '".dir1."' exists, cannot run test"
+ return
+ endif
+ let file1=dir1.'/zz.y.txt'
+ let nofile1=dir1.'/z.y.txt'
+ let dir2=dir1.'/VimIsTheGreatestSinceSlicedBread'
+ let file2=dir2.'/z.txt'
+ let nofile2=dir2.'/zz.txt'
+ call MakeDir( dir1 )
+ let resdir1 = substitute(fnamemodify(dir1, ':p:8'), '\\$', '', '')
+ if resdir1 !~ '\V\^c:/XX\x\x\x\x~1.Y\$'
+ echo "FATAL: unexpected short name: " . resdir1
+ echo "INFO: please report your OS to vim-dev"
+ return
+ endif
+ let resfile1=resdir1.'/ZZY~1.TXT'
+ let resnofile1=resdir1.'/z.y.txt'
+ let resdir2=resdir1.'/VIMIST~1'
+ let resfile2=resdir2.'/z.txt'
+ let resnofile2=resdir2.'/zz.txt'
+ call MakeDir( dir2 )
+ call MakeFile( file1 )
+ call MakeFile( file2 )
+ call TestIt(file1, ':p:8', resfile1)
+ call TestIt(nofile1, ':p:8', resnofile1)
+ call TestIt(file2, ':p:8', resfile2)
+ call TestIt(nofile2, ':p:8', resnofile2)
+ call TestIt(nofile2, ':p:8:h', fnamemodify(resnofile2,':h'))
+ exe 'cd '.dir1
+ call TestIt(file1, ':.:8', strpart(resfile1,strlen(resdir1)+1))
+ call TestIt(nofile1, ':.:8', strpart(resnofile1,strlen(resdir1)+1))
+ call TestIt(file2, ':.:8', strpart(resfile2,strlen(resdir1)+1))
+ call TestIt(nofile2, ':.:8', strpart(resnofile2,strlen(resdir1)+1))
+ let $HOME=dir1
+ call TestIt(file1, ':~:8', '~'.strpart(resfile1,strlen(resdir1)))
+ call TestIt(nofile1, ':~:8', '~'.strpart(resnofile1,strlen(resdir1)))
+ call TestIt(file2, ':~:8', '~'.strpart(resfile2,strlen(resdir1)))
+ call TestIt(nofile2, ':~:8', '~'.strpart(resnofile2,strlen(resdir1)))
+ cd c:/
+ call delete( file2 )
+ call delete( file1 )
+ call RMDir( dir2 )
+ call RMDir( dir1 )
+ echo
+ redir END
+endfun
+:let dir = getcwd()
+:call TestColonEight()
+:exe "cd " . dir
+:edit! test.out
+:set ff=dos
+:w
+:qa!
+ENDTEST
+
diff --git a/src/testdir/test50.ok b/src/testdir/test50.ok
new file mode 100644
index 0000000000..91ef1d6604
--- /dev/null
+++ b/src/testdir/test50.ok
@@ -0,0 +1,14 @@
+
+OK
+OK
+OK
+OK
+OK
+OK
+OK
+OK
+OK
+OK
+OK
+OK
+OK
diff --git a/src/testdir/test51.in b/src/testdir/test51.in
new file mode 100644
index 0000000000..b4f45d1f75
--- /dev/null
+++ b/src/testdir/test51.in
@@ -0,0 +1,36 @@
+Tests for ":highlight". vim: set ft=vim :
+
+STARTTEST
+:so small.vim
+:" 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
+:hi NewGroup term=bold cterm=italic ctermfg=DarkBlue ctermbg=Grey gui= guifg=#00ff00 guibg=Cyan
+:hi Group2 term= cterm=
+:hi Group3 term=underline cterm=bold
+:redir! >test.out
+:hi NewGroup
+:hi Group2
+:hi Group3
+:hi clear NewGroup
+:hi NewGroup
+:hi Group2
+:hi Group2 NONE
+:hi Group2
+:hi clear
+:hi Group3
+:hi Crash term='asdf
+:redir END
+:" filter ctermfg and ctermbg, the numbers depend on the terminal
+:e test.out
+:%s/ctermfg=\d*/ctermfg=2/
+:%s/ctermbg=\d*/ctermbg=3/
+:" filter out possibly translated error message
+:%s/E475: [^:]*:/E475:/
+:" fix the fileformat
+:set ff&
+:wq!
+ENDTEST
+
diff --git a/src/testdir/test51.ok b/src/testdir/test51.ok
new file mode 100644
index 0000000000..be9ff7862c
--- /dev/null
+++ b/src/testdir/test51.ok
@@ -0,0 +1,20 @@
+
+
+NewGroup xxx term=bold cterm=italic ctermfg=2 ctermbg=3
+
+Group2 xxx cleared
+
+Group3 xxx term=underline cterm=bold
+
+
+NewGroup xxx cleared
+
+Group2 xxx cleared
+
+
+Group2 xxx cleared
+
+
+Group3 xxx cleared
+
+E475: term='asdf
diff --git a/src/testdir/test52.in b/src/testdir/test52.in
new file mode 100644
index 0000000000..206b65a1f9
--- /dev/null
+++ b/src/testdir/test52.in
@@ -0,0 +1,65 @@
+Tests for reading and writing files with conversion for Win32.
+
+STARTTEST
+:so mbyte.vim
+:" make this a dummy test for non-Win32 systems
+:if !has("win32") | e! test.ok | wq! test.out | endif
+:"
+:" write tests:
+:" combine three values for 'encoding' with three values for 'fileencoding'
+:" also write files for read tests
+/^1
+:set encoding=utf-8
+:.w! ++enc=utf-8 test.out
+:.w ++enc=cp1251 >>test.out
+:.w ++enc=cp866 >>test.out
+:.w! ++enc=utf-8 Xutf8
+/^2
+:set encoding=cp1251
+:.w ++enc=utf-8 >>test.out
+:.w ++enc=cp1251 >>test.out
+:.w ++enc=cp866 >>test.out
+:.w! ++enc=cp1251 Xcp1251
+/^3
+:set encoding=cp866
+:.w ++enc=utf-8 >>test.out
+:.w ++enc=cp1251 >>test.out
+:.w ++enc=cp866 >>test.out
+:.w! ++enc=cp866 Xcp866
+:"
+:" read three 'fileencoding's with utf-8 'encoding'
+:set encoding=utf-8 fencs=utf-8,cp1251
+:e Xutf8
+:.w ++enc=utf-8 >>test.out
+:e Xcp1251
+:.w ++enc=utf-8 >>test.out
+:set fencs=utf-8,cp866
+:e Xcp866
+:.w ++enc=utf-8 >>test.out
+:"
+:" read three 'fileencoding's with cp1251 'encoding'
+:set encoding=utf-8 fencs=utf-8,cp1251
+:e Xutf8
+:.w ++enc=cp1251 >>test.out
+:e Xcp1251
+:.w ++enc=cp1251 >>test.out
+:set fencs=utf-8,cp866
+:e Xcp866
+:.w ++enc=cp1251 >>test.out
+:"
+:" read three 'fileencoding's with cp866 'encoding'
+:set encoding=cp866 fencs=utf-8,cp1251
+:e Xutf8
+:.w ++enc=cp866 >>test.out
+:e Xcp1251
+:.w ++enc=cp866 >>test.out
+:set fencs=utf-8,cp866
+:e Xcp866
+:.w ++enc=cp866 >>test.out
+:"
+:qa!
+ENDTEST
+
+1 utf-8 text: Ð”Ð»Ñ Vim version 6.2. ПоÑледнее изменение: 1970 Jan 01
+2 cp1251 text: Äëÿ Vim version 6.2. Ïîñëåäíåå èçìåíåíèå: 1970 Jan 01
+3 cp866 text: „«ï Vim version 6.2. ®á«¥¤­¥¥ ¨§¬¥­¥­¨¥: 1970 Jan 01
diff --git a/src/testdir/test52.ok b/src/testdir/test52.ok
new file mode 100644
index 0000000000..90b516508d
--- /dev/null
+++ b/src/testdir/test52.ok
@@ -0,0 +1,18 @@
+1 utf-8 text: Ð”Ð»Ñ Vim version 6.2. ПоÑледнее изменение: 1970 Jan 01
+1 utf-8 text: Äëÿ Vim version 6.2. Ïîñëåäíåå èçìåíåíèå: 1970 Jan 01
+1 utf-8 text: „«ï Vim version 6.2. ®á«¥¤­¥¥ ¨§¬¥­¥­¨¥: 1970 Jan 01
+2 cp1251 text: Ð”Ð»Ñ Vim version 6.2. ПоÑледнее изменение: 1970 Jan 01
+2 cp1251 text: Äëÿ Vim version 6.2. Ïîñëåäíåå èçìåíåíèå: 1970 Jan 01
+2 cp1251 text: „«ï Vim version 6.2. ®á«¥¤­¥¥ ¨§¬¥­¥­¨¥: 1970 Jan 01
+3 cp866 text: Ð”Ð»Ñ Vim version 6.2. ПоÑледнее изменение: 1970 Jan 01
+3 cp866 text: Äëÿ Vim version 6.2. Ïîñëåäíåå èçìåíåíèå: 1970 Jan 01
+3 cp866 text: „«ï Vim version 6.2. ®á«¥¤­¥¥ ¨§¬¥­¥­¨¥: 1970 Jan 01
+1 utf-8 text: Ð”Ð»Ñ Vim version 6.2. ПоÑледнее изменение: 1970 Jan 01
+2 cp1251 text: Ð”Ð»Ñ Vim version 6.2. ПоÑледнее изменение: 1970 Jan 01
+3 cp866 text: Ð”Ð»Ñ Vim version 6.2. ПоÑледнее изменение: 1970 Jan 01
+1 utf-8 text: Äëÿ Vim version 6.2. Ïîñëåäíåå èçìåíåíèå: 1970 Jan 01
+2 cp1251 text: Äëÿ Vim version 6.2. Ïîñëåäíåå èçìåíåíèå: 1970 Jan 01
+3 cp866 text: Äëÿ Vim version 6.2. Ïîñëåäíåå èçìåíåíèå: 1970 Jan 01
+1 utf-8 text: „«ï Vim version 6.2. ®á«¥¤­¥¥ ¨§¬¥­¥­¨¥: 1970 Jan 01
+2 cp1251 text: „«ï Vim version 6.2. ®á«¥¤­¥¥ ¨§¬¥­¥­¨¥: 1970 Jan 01
+3 cp866 text: „«ï Vim version 6.2. ®á«¥¤­¥¥ ¨§¬¥­¥­¨¥: 1970 Jan 01
diff --git a/src/testdir/test53.in b/src/testdir/test53.in
new file mode 100644
index 0000000000..47cf6f562f
--- /dev/null
+++ b/src/testdir/test53.in
@@ -0,0 +1,84 @@
+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()
+
+STARTTEST
+:so small.vim
+/^start:/
+da"
+0va'a'rx
+02f`da`
+0fXdi"
+03f'vi'ry
+:set quoteescape=+*-
+di`
+$F"va"oha"i"rz
+:"
+/^<begin
+jfXdit
+0fXdit
+fXdat
+0fXdat
+:"
+: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
+/^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
+:/^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>-
+</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++)
+Y
+text
+Y
+end:
diff --git a/src/testdir/test53.ok b/src/testdir/test53.ok
new file mode 100644
index 0000000000..e469869abb
--- /dev/null
+++ b/src/testdir/test53.ok
@@ -0,0 +1,33 @@
+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>-
+--
+</begin>
+b
+bc
+c
+a
+-1
+0
+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++)
+
+text
+Y
+end:
diff --git a/src/testdir/test54.in b/src/testdir/test54.in
new file mode 100644
index 0000000000..9fc6537e08
--- /dev/null
+++ b/src/testdir/test54.in
@@ -0,0 +1,22 @@
+Some tests for buffer-local autocommands
+
+STARTTEST
+:so small.vim
+:e xx
+:if has("vms")
+: !del test.out.*
+: au BufLeave <buffer> :!write sys$output "buffer-local autommand in %" > test.out
+:else
+: !rm -f test.out
+: au BufLeave <buffer> :!echo buffer-local autommand in %>> test.out
+:endif
+:e somefile " here, autocommand for xx shall write test.out
+: " but autocommand shall not apply to buffer named <buffer>
+:bwipe xx " here, autocommand shall be auto-deleted
+:e xx " nothing shall be written
+:e somefile " nothing shall be written
+:qa!
+ENDTEST
+
+start of test file xx
+end of test file xx
diff --git a/src/testdir/test54.ok b/src/testdir/test54.ok
new file mode 100644
index 0000000000..0fd1dc915b
--- /dev/null
+++ b/src/testdir/test54.ok
@@ -0,0 +1 @@
+buffer-local autommand in xx
diff --git a/src/testdir/test55.in b/src/testdir/test55.in
new file mode 100644
index 0000000000..4b20de403f
--- /dev/null
+++ b/src/testdir/test55.in
@@ -0,0 +1,402 @@
+Tests for List and Dictionary types. vim: set ft=vim :
+
+STARTTEST
+:so small.vim
+:fun Test(...)
+:lang C
+:" Creating List directly with different types
+:let l = [1, 'as''d', [1, 2, function("strlen")], {'a': 1},]
+:$put =string(l)
+:$put =string(l[-1])
+:$put =string(l[-4])
+:try
+: $put =string(l[-5])
+:catch
+: $put =v:exception[:14]
+:endtry
+:" List slices
+:$put =string(l[:])
+:$put =string(l[1:])
+:$put =string(l[:-2])
+:$put =string(l[0:8])
+:$put =string(l[8:-1])
+:"
+:" List identity
+:let ll = l
+:let lx = copy(l)
+:try
+: $put =(l == ll) . (l isnot ll) . (l is ll) . (l == lx) . (l is lx) . (l isnot lx)
+:catch
+: $put =v:exception
+:endtry
+:"
+:" Creating Dictionary directly with different types
+:let d = {001: 'asd', 'b': [1, 2, function('strlen')], -1: {'a': 1},}
+:$put =string(d) . d.1
+:$put =string(sort(keys(d)))
+:$put =string (values(d))
+:for [key, val] in items(d)
+: $put =key . ':' . string(val)
+: unlet key val
+:endfor
+:call extend (d, {3:33, 1:99})
+:call extend(d, {'b':'bbb', 'c':'ccc'}, "keep")
+:try
+: call extend(d, {3:333,4:444}, "error")
+:catch
+: $put =v:exception[:15] . v:exception[-1:-1]
+:endtry
+:$put =string(d)
+:call filter(d, 'v:key =~ ''[ac391]''')
+:$put =string(d)
+:"
+:" Dictionary identity
+:let dd = d
+:let dx = copy(d)
+:try
+: $put =(d == dd) . (d isnot dd) . (d is dd) . (d == dx) . (d is dx) . (d isnot dx)
+:catch
+: $put =v:exception
+:endtry
+:"
+:" Changing var type should fail
+:try
+: let d = []
+:catch
+: $put =v:exception[:14] . v:exception[-1:-1]
+:endtry
+:try
+: let l = {}
+:catch
+: $put =v:exception[:14] . v:exception[-1:-1]
+:endtry
+:"
+:" removing items with :unlet
+:unlet l[2]
+:$put =string(l)
+:let l = range(8)
+:try
+:unlet l[:3]
+:unlet l[1:]
+:catch
+:$put =v:exception
+:endtry
+:$put =string(l)
+:"
+:unlet d.c
+:unlet d[-1]
+:$put =string(d)
+:"
+:" removing items out of range: silently skip items that don't exist
+let l = [0, 1, 2, 3]
+:unlet l[2:1]
+:$put =string(l)
+let l = [0, 1, 2, 3]
+:unlet l[2:2]
+:$put =string(l)
+let l = [0, 1, 2, 3]
+:unlet l[2:3]
+:$put =string(l)
+let l = [0, 1, 2, 3]
+:unlet l[2:4]
+:$put =string(l)
+let l = [0, 1, 2, 3]
+:unlet l[2:5]
+:$put =string(l)
+let l = [0, 1, 2, 3]
+:unlet l[-1:2]
+:$put =string(l)
+let l = [0, 1, 2, 3]
+:unlet l[-2:2]
+:$put =string(l)
+let l = [0, 1, 2, 3]
+:unlet l[-3:2]
+:$put =string(l)
+let l = [0, 1, 2, 3]
+:unlet l[-4:2]
+:$put =string(l)
+let l = [0, 1, 2, 3]
+:unlet l[-5:2]
+:$put =string(l)
+let l = [0, 1, 2, 3]
+:unlet l[-6:2]
+:$put =string(l)
+:"
+:" assignment to a list
+:let l = [0, 1, 2, 3]
+:let [va, vb] = l[2:3]
+:$put =va
+:$put =vb
+:try
+: let [va, vb] = l
+:catch
+: $put =v:exception[:14]
+:endtry
+:try
+: let [va, vb] = l[1:1]
+:catch
+: $put =v:exception[:14]
+:endtry
+:"
+:" manipulating a big Dictionary (hashtable.c has a border of 1000 entries)
+:let d = {}
+:for i in range(1500)
+: let d[i] = 3000 - i
+:endfor
+:$put =d[0] . ' ' . d[100] . ' ' . d[999] . ' ' . d[1400] . ' ' . d[1499]
+:try
+: let n = d[1500]
+:catch
+: $put =substitute(v:exception, '\v(.{14}).*( \d{4}).*', '\1\2', '')
+:endtry
+:" lookup each items
+:for i in range(1500)
+: if d[i] != 3000 - i
+: $put =d[i]
+: endif
+:endfor
+: let i += 1
+:" delete even items
+:while i >= 2
+: let i -= 2
+: unlet d[i]
+:endwhile
+:$put =get(d, 1500 - 100, 'NONE') . ' ' . d[1]
+:" delete odd items, checking value, one intentionally wrong
+:let d[33] = 999
+:let i = 1
+:while i < 1500
+: if d[i] != 3000 - i
+: $put =i . '=' . d[i]
+: else
+: unlet d[i]
+: endif
+: let i += 2
+:endwhile
+:$put =string(d) " must be almost empty now
+:unlet d
+:"
+:" Dictionary function
+:let dict = {}
+:func dict.func(a) dict
+: $put =a:a . len(self.data)
+:endfunc
+:let dict.data = [1,2,3]
+:call dict.func("len: ")
+:let x = dict.func("again: ")
+:try
+: let Fn = dict.func
+: call Fn('xxx')
+:catch
+: $put =v:exception[:15]
+:endtry
+:"
+:" Function in script-local List or Dict
+:let g:dict = {}
+:function g:dict.func() dict
+: $put ='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 g:dict.func()
+:"
+:" Nasty: remove func from Dict that's being called (works)
+:let d = {1:1}
+:func d.func(a)
+: return "a:". a:a
+:endfunc
+:$put =d.func(string(remove(d, 'func')))
+:"
+:" Nasty: deepcopy() dict that refers to itself (fails when noref used)
+:let d = {1:1, 2:2}
+:let l = [4, d, 6]
+:let d[3] = l
+:let dc = deepcopy(d)
+:try
+: let dc = deepcopy(d, 1)
+:catch
+: $put =v:exception[:14]
+:endtry
+:let l2 = [0, l, l, 3]
+:let l[1] = l2
+:let l3 = deepcopy(l2)
+:$put ='same list: ' . (l3[1] is l3[2])
+:"
+:" Locked variables
+:for depth in range(5)
+: $put ='depth is ' . depth
+: 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]")
+: $put =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
+: $put =ps
+: endfor
+:endfor
+:" :lockvar/islocked() triggering script autoloading
+:set rtp+=./sautest
+:lockvar g:footest#x
+:unlockvar g:footest#x
+:$put ='locked g:footest#x:'.islocked('g:footest#x')
+:$put ='exists g:footest#x:'.exists('g:footest#x')
+:$put ='g:footest#x: '.g:footest#x
+:"
+:" a:000 function argument
+:" first the tests that should fail
+:try
+: let a:000 = [1, 2]
+:catch
+: $put ='caught a:000'
+:endtry
+:try
+: let a:000[0] = 9
+:catch
+: $put ='caught a:000[0]'
+:endtry
+:try
+: let a:000[2] = [9, 10]
+:catch
+: $put ='caught a:000[2]'
+:endtry
+:try
+: let a:000[3] = {9: 10}
+:catch
+: $put ='caught a:000[3]'
+:endtry
+:" now the tests that should pass
+:try
+: 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
+: $put =string(a:000)
+:catch
+: $put ='caught ' . v:exception
+:endtry
+:"
+:" reverse() and sort()
+:let l = ['-0', 'A11', 2, 'xaaa', 4, 'foo', 'foo6', [0, 1, 2], 'x8']
+:$put =string(reverse(l))
+:$put =string(reverse(reverse(l)))
+:$put =string(sort(l))
+:$put =string(reverse(sort(l)))
+:$put =string(sort(reverse(sort(l))))
+:"
+:" splitting a string to a List
+:$put =string(split(' aa bb '))
+:$put =string(split(' aa bb ', '\W\+', 0))
+:$put =string(split(' aa bb ', '\W\+', 1))
+:$put =string(split(' aa bb ', '\W', 1))
+:$put =string(split(':aa::bb:', ':', 0))
+:$put =string(split(':aa::bb:', ':', 1))
+:$put =string(split('aa,,bb, cc,', ',\s*', 1))
+:$put =string(split('abc', '\zs'))
+:$put =string(split('abc', '\zs', 1))
+:"
+:" compare recursively linked list and dict
+:let l = [1, 2, 3, 4]
+:let d = {'1': 1, '2': l, '3': 3}
+:let l[1] = d
+:$put =(l == l)
+:$put =(d == d)
+:$put =(l != deepcopy(l))
+:$put =(d != deepcopy(d))
+:"
+:" compare complex recursively linked list and dict
+:let l = []
+:call add(l, l)
+:let dict4 = {"l": l}
+:call add(dict4.l, dict4)
+:let lcopy = deepcopy(l)
+:let dict4copy = deepcopy(dict4)
+:$put =(l == lcopy)
+:$put =(dict4 == dict4copy)
+:"
+:" Pass the same List to extend()
+:let l = [1, 2, 3, 4, 5]
+:call extend(l, l)
+:$put =string(l)
+:"
+:" Pass the same Dict to extend()
+:let d = { 'a': {'b': 'B'}}
+:call extend(d, d)
+:$put =string(d)
+:"
+:" Pass the same Dict to extend() with "error"
+:try
+: call extend(d, d, "error")
+:catch
+: $put =v:exception[:15] . v:exception[-1:-1]
+:endtry
+:$put =string(d)
+:endfun
+:"
+:call Test(1, 2, [3, 4], {5: 6}) " This may take a while
+:"
+:delfunc Test
+:unlet dict
+:call garbagecollect(1)
+:"
+:" test for patch 7.3.637
+:let a = 'No error caught'
+:try|foldopen|catch|let a = matchstr(v:exception,'^[^ ]*')|endtry
+o=a :"
+:lang C
+:redir => a
+:try|foobar|catch|let a = matchstr(v:exception,'^[^ ]*')|endtry
+:redir END
+o=a :"
+:"
+:/^start:/,$wq! test.out
+ENDTEST
+
+start:
diff --git a/src/testdir/test55.ok b/src/testdir/test55.ok
new file mode 100644
index 0000000000..396c9bed19
--- /dev/null
+++ b/src/testdir/test55.ok
@@ -0,0 +1,126 @@
+start:
+[1, 'as''d', [1, 2, function('strlen')], {'a': 1}]
+{'a': 1}
+1
+Vim(put):E684:
+[1, 'as''d', [1, 2, function('strlen')], {'a': 1}]
+['as''d', [1, 2, function('strlen')], {'a': 1}]
+[1, 'as''d', [1, 2, function('strlen')]]
+[1, 'as''d', [1, 2, function('strlen')], {'a': 1}]
+[]
+101101
+{'1': 'asd', 'b': [1, 2, function('strlen')], '-1': {'a': 1}}asd
+['-1', '1', 'b']
+['asd', [1, 2, function('strlen')], {'a': 1}]
+1:'asd'
+b:[1, 2, function('strlen')]
+-1:{'a': 1}
+Vim(call):E737: 3
+{'c': 'ccc', '1': 99, 'b': [1, 2, function('strlen')], '3': 33, '-1': {'a': 1}}
+{'c': 'ccc', '1': 99, '3': 33, '-1': {'a': 1}}
+101101
+Vim(let):E706: d
+Vim(let):E706: l
+[1, 'as''d', {'a': 1}]
+[4]
+{'1': 99, '3': 33}
+[0, 1, 2, 3]
+[0, 1, 3]
+[0, 1]
+[0, 1]
+[0, 1]
+[0, 1, 2, 3]
+[0, 1, 3]
+[0, 3]
+[3]
+[3]
+[3]
+2
+3
+Vim(let):E687:
+Vim(let):E688:
+3000 2900 2001 1600 1501
+Vim(let):E716: 1500
+NONE 2999
+33=999
+{'33': 999}
+len: 3
+again: 3
+Vim(call):E725:
+g:dict.func-4
+a:function('3')
+Vim(let):E698:
+same list: 1
+depth is 0
+0000-000
+ppppppp
+0000-000
+ppppppp
+0000-000
+ppppppp
+depth is 1
+1000-000
+ppppppF
+0000-000
+ppppppp
+0000-000
+ppppppp
+depth is 2
+1100-100
+ppFppFF
+0000-000
+ppppppp
+0000-000
+ppppppp
+depth is 3
+1110-110
+pFFpFFF
+0010-010
+pFppFpp
+0000-000
+ppppppp
+depth is 4
+1111-111
+FFFFFFF
+0011-011
+FFpFFpp
+0000-000
+ppppppp
+locked g:footest#x:-1
+exists g:footest#x:0
+g:footest#x: 1
+caught a:000
+caught a:000[0]
+caught a:000[2]
+caught a:000[3]
+[1, 2, [3, 9, 5, 6], {'a': 12, '5': 8}]
+['x8', [0, 1, 2], 'foo6', 'foo', 4, 'xaaa', 2, 'A11', '-0']
+['x8', [0, 1, 2], 'foo6', 'foo', 4, 'xaaa', 2, 'A11', '-0']
+['-0', 'A11', 'foo', 'foo6', 'x8', 'xaaa', 2, 4, [0, 1, 2]]
+[[0, 1, 2], 4, 2, 'xaaa', 'x8', 'foo6', 'foo', 'A11', '-0']
+['-0', 'A11', 'foo', 'foo6', 'x8', 'xaaa', 2, 4, [0, 1, 2]]
+['aa', 'bb']
+['aa', 'bb']
+['', 'aa', 'bb', '']
+['', '', 'aa', '', 'bb', '', '']
+['aa', '', 'bb']
+['', 'aa', '', 'bb', '']
+['aa', '', 'bb', 'cc', '']
+['a', 'b', 'c']
+['', 'a', '', 'b', '', 'c', '']
+1
+1
+0
+0
+1
+1
+[1, 2, 3, 4, 5, 1, 2, 3, 4, 5]
+{'a': {'b': 'B'}}
+Vim(call):E737: a
+{'a': {'b': 'B'}}
+Vim(foldopen):E490:
+
+
+Error detected while processing :
+E492: Not an editor command: foobar|catch|let a = matchstr(v:exception,'^[^ ]*')|endtry
+
diff --git a/src/testdir/test56.in b/src/testdir/test56.in
new file mode 100644
index 0000000000..311a6004ca
--- /dev/null
+++ b/src/testdir/test56.in
@@ -0,0 +1,21 @@
+Test for script-local function. vim: set ft=vim :
+
+STARTTEST
+:so small.vim
+:"
+:set nocp viminfo+=nviminfo
+:/^start:/+1,/^end:/-1w! Xtest.vim
+:source Xtest.vim
+_x
+:$-1,$wq! test.out
+ENDTEST
+
+start:
+fun <SID>DoLast()
+ call append(line('$'), "last line")
+endfun
+fun s:DoNothing()
+ call append(line('$'), "nothing line")
+endfun
+nnoremap <buffer> _x :call <SID>DoNothing()<bar>call <SID>DoLast()<bar>delfunc <SID>DoNothing<bar>delfunc <SID>DoLast<cr>
+end:
diff --git a/src/testdir/test56.ok b/src/testdir/test56.ok
new file mode 100644
index 0000000000..f2b0d33c8b
--- /dev/null
+++ b/src/testdir/test56.ok
@@ -0,0 +1,2 @@
+nothing line
+last line
diff --git a/src/testdir/test57.in b/src/testdir/test57.in
new file mode 100644
index 0000000000..8d972e4a68
--- /dev/null
+++ b/src/testdir/test57.in
@@ -0,0 +1,500 @@
+Tests for :sort command. vim: set ft=vim :
+
+STARTTEST
+:so small.vim
+:"
+:/^t01:/+1,/^t02/-1sort
+:/^t02:/+1,/^t03/-1sort n
+:/^t03:/+1,/^t04/-1sort x
+:/^t04:/+1,/^t05/-1sort u
+:/^t05:/+1,/^t06/-1sort!
+:/^t06:/+1,/^t07/-1sort! n
+:/^t07:/+1,/^t08/-1sort! u
+:/^t08:/+1,/^t09/-1sort o
+:/^t09:/+1,/^t10/-1sort! x
+:/^t10:/+1,/^t11/-1sort/./
+:/^t11:/+1,/^t12/-1sort/../
+:/^t12:/+1,/^t13/-1sort/../u
+:/^t13:/+1,/^t14/-1sort/./n
+:/^t14:/+1,/^t15/-1sort/./r
+:/^t15:/+1,/^t16/-1sort/../r
+:/^t16:/+1,/^t17/-1sort/./rn
+:/^t17:/+1,/^t18/-1sort/\d/
+:/^t18:/+1,/^t19/-1sort/\d/r
+:/^t19:/+1,/^t20/-1sort/\d/n
+:/^t20:/+1,/^t21/-1sort/\d/rn
+:/^t21:/+1,/^t22/-1sort/\d\d/
+:/^t22:/+1,/^t23/-1sort/\d\d/n
+:/^t23:/+1,/^t24/-1sort/\d\d/x
+:/^t24:/+1,/^t25/-1sort/\d\d/r
+:/^t25:/+1,/^t26/-1sort/\d\d/rn
+:/^t26:/+1,/^t27/-1sort/\d\d/rx
+:/^t27:/+1,/^t28/-1sort no
+:/^t01:/,$wq! test.out
+ENDTEST
+
+t01: alphebetical
+abc
+ab
+a
+a321
+a123
+a122
+b321
+b123
+c123d
+ 123b
+c321d
+b322b
+b321
+b321b
+
+
+t02: numeric
+abc
+ab
+a321
+a123
+a122
+a
+x-22
+b321
+b123
+
+c123d
+-24
+ 123b
+c321d
+0
+b322b
+b321
+b321b
+
+
+t03: hexadecimal
+abc
+ab
+a
+a321
+a123
+a122
+b321
+b123
+c123d
+ 123b
+c321d
+b322b
+b321
+b321b
+
+
+t04: alpha, unique
+abc
+ab
+a
+a321
+a123
+a122
+b321
+b123
+c123d
+ 123b
+c321d
+b322b
+b321
+b321b
+
+
+t05: alpha, reverse
+abc
+ab
+a
+a321
+a123
+a122
+b321
+b123
+c123d
+ 123b
+c321d
+b322b
+b321
+b321b
+
+
+t06: numeric, reverse
+abc
+ab
+a
+a321
+a123
+a122
+b321
+b123
+c123d
+ 123b
+c321d
+b322b
+b321
+b321b
+
+
+t07: unique, reverse
+abc
+ab
+a
+a321
+a123
+a122
+b321
+b123
+c123d
+ 123b
+c321d
+b322b
+b321
+b321b
+
+
+t08: octal
+abc
+ab
+a
+a321
+a123
+a122
+b321
+b123
+c123d
+ 123b
+c321d
+b322b
+b321
+b321b
+
+
+t09: reverse, hexadecimal
+abc
+ab
+a
+a321
+a123
+a122
+b321
+b123
+c123d
+ 123b
+c321d
+b322b
+b321
+b321b
+
+
+t10: alpha, skip first character
+abc
+ab
+a
+a321
+a123
+a122
+b321
+b123
+c123d
+ 123b
+c321d
+b322b
+b321
+b321b
+
+
+t11: alpha, skip first 2 characters
+abc
+ab
+a
+a321
+a123
+a122
+b321
+b123
+c123d
+ 123b
+c321d
+b322b
+b321
+b321b
+
+
+t12: alpha, unique, skip first 2 characters
+abc
+ab
+a
+a321
+a123
+a122
+b321
+b123
+c123d
+ 123b
+c321d
+b322b
+b321
+b321b
+
+
+t13: numeric, skip first character
+abc
+ab
+a
+a321
+a123
+a122
+b321
+b123
+c123d
+ 123b
+c321d
+b322b
+b321
+b321b
+
+
+t14: alpha, sort on first character
+abc
+ab
+a
+a321
+a123
+a122
+b321
+b123
+c123d
+ 123b
+c321d
+b322b
+b321
+b321b
+
+
+t15: alpha, sort on first 2 characters
+abc
+ab
+a
+a321
+a123
+a122
+b321
+b123
+c123d
+ 123b
+c321d
+b322b
+b321
+b321b
+
+
+t16: numeric, sort on first character
+abc
+ab
+a
+a321
+a123
+a122
+b321
+b123
+c123d
+ 123b
+c321d
+b322b
+b321
+b321b
+
+
+t17: alpha, skip past first digit
+abc
+ab
+a
+a321
+a123
+a122
+b321
+b123
+c123d
+ 123b
+c321d
+b322b
+b321
+b321b
+
+
+t18: alpha, sort on first digit
+abc
+ab
+a
+a321
+a123
+a122
+b321
+b123
+c123d
+ 123b
+c321d
+b322b
+b321
+b321b
+
+
+t19: numeric, skip past first digit
+abc
+ab
+a
+a321
+a123
+a122
+b321
+b123
+c123d
+ 123b
+c321d
+b322b
+b321
+b321b
+
+
+t20: numeric, sort on first digit
+abc
+ab
+a
+a321
+a123
+a122
+b321
+b123
+c123d
+ 123b
+c321d
+b322b
+b321
+b321b
+
+
+t21: alpha, skip past first 2 digits
+abc
+ab
+a
+a321
+a123
+a122
+b321
+b123
+c123d
+ 123b
+c321d
+b322b
+b321
+b321b
+
+
+t22: numeric, skip past first 2 digits
+abc
+ab
+a
+a321
+a123
+a122
+b321
+b123
+c123d
+ 123b
+c321d
+b322b
+b321
+b321b
+
+
+t23: hexadecimal, skip past first 2 digits
+abc
+ab
+a
+a321
+a123
+a122
+b321
+b123
+c123d
+ 123b
+c321d
+b322b
+b321
+b321b
+
+
+t24: alpha, sort on first 2 digits
+abc
+ab
+a
+a321
+a123
+a122
+b321
+b123
+c123d
+ 123b
+c321d
+b322b
+b321
+b321b
+
+
+t25: numeric, sort on first 2 digits
+abc
+ab
+a
+a321
+a123
+a122
+b321
+b123
+c123d
+ 123b
+c321d
+b322b
+b321
+b321b
+
+
+t26: hexadecimal, sort on first 2 digits
+abc
+ab
+a
+a321
+a123
+a122
+b321
+b123
+c123d
+ 123b
+c321d
+b322b
+b321
+b321b
+
+
+t27: wrong arguments
+abc
+ab
+a
+a321
+a123
+a122
+b321
+b123
+c123d
+ 123b
+c321d
+b322b
+b321
+b321b
+
+
+t28: done
+
diff --git a/src/testdir/test57.ok b/src/testdir/test57.ok
new file mode 100644
index 0000000000..aa3d373183
--- /dev/null
+++ b/src/testdir/test57.ok
@@ -0,0 +1,459 @@
+t01: alphebetical
+
+
+ 123b
+a
+a122
+a123
+a321
+ab
+abc
+b123
+b321
+b321
+b321b
+b322b
+c123d
+c321d
+t02: numeric
+abc
+ab
+a
+
+
+
+-24
+x-22
+0
+a122
+a123
+b123
+c123d
+ 123b
+a321
+b321
+c321d
+b321
+b321b
+b322b
+t03: hexadecimal
+
+
+a
+ab
+abc
+ 123b
+a122
+a123
+a321
+b123
+b321
+b321
+b321b
+b322b
+c123d
+c321d
+t04: alpha, unique
+
+ 123b
+a
+a122
+a123
+a321
+ab
+abc
+b123
+b321
+b321b
+b322b
+c123d
+c321d
+t05: alpha, reverse
+c321d
+c123d
+b322b
+b321b
+b321
+b321
+b123
+abc
+ab
+a321
+a123
+a122
+a
+ 123b
+
+
+t06: numeric, reverse
+b322b
+b321b
+b321
+c321d
+b321
+a321
+ 123b
+c123d
+b123
+a123
+a122
+
+
+a
+ab
+abc
+t07: unique, reverse
+c321d
+c123d
+b322b
+b321b
+b321
+b123
+abc
+ab
+a321
+a123
+a122
+a
+ 123b
+
+t08: octal
+abc
+ab
+a
+
+
+a122
+a123
+b123
+c123d
+ 123b
+a321
+b321
+c321d
+b321
+b321b
+b322b
+t09: reverse, hexadecimal
+c321d
+c123d
+b322b
+b321b
+b321
+b321
+b123
+a321
+a123
+a122
+ 123b
+abc
+ab
+a
+
+
+t10: alpha, skip first character
+a
+
+
+a122
+a123
+b123
+ 123b
+c123d
+a321
+b321
+b321
+b321b
+c321d
+b322b
+ab
+abc
+t11: alpha, skip first 2 characters
+ab
+a
+
+
+a321
+b321
+b321
+b321b
+c321d
+a122
+b322b
+a123
+b123
+ 123b
+c123d
+abc
+t12: alpha, unique, skip first 2 characters
+ab
+a
+
+a321
+b321
+b321b
+c321d
+a122
+b322b
+a123
+b123
+ 123b
+c123d
+abc
+t13: numeric, skip first character
+abc
+ab
+a
+
+
+a122
+a123
+b123
+c123d
+ 123b
+a321
+b321
+c321d
+b321
+b321b
+b322b
+t14: alpha, sort on first character
+
+
+ 123b
+abc
+ab
+a
+a321
+a123
+a122
+b321
+b123
+b322b
+b321
+b321b
+c123d
+c321d
+t15: alpha, sort on first 2 characters
+a
+
+
+ 123b
+a123
+a122
+a321
+abc
+ab
+b123
+b321
+b322b
+b321
+b321b
+c123d
+c321d
+t16: numeric, sort on first character
+abc
+ab
+a
+a321
+a123
+a122
+b321
+b123
+c123d
+ 123b
+c321d
+b322b
+b321
+b321b
+
+
+t17: alpha, skip past first digit
+abc
+ab
+a
+
+
+a321
+b321
+b321
+b321b
+c321d
+a122
+b322b
+a123
+b123
+ 123b
+c123d
+t18: alpha, sort on first digit
+abc
+ab
+a
+
+
+a123
+a122
+b123
+c123d
+ 123b
+a321
+b321
+c321d
+b322b
+b321
+b321b
+t19: numeric, skip past first digit
+abc
+ab
+a
+
+
+a321
+b321
+c321d
+b321
+b321b
+a122
+b322b
+a123
+b123
+c123d
+ 123b
+t20: numeric, sort on first digit
+abc
+ab
+a
+
+
+a123
+a122
+b123
+c123d
+ 123b
+a321
+b321
+c321d
+b322b
+b321
+b321b
+t21: alpha, skip past first 2 digits
+abc
+ab
+a
+
+
+a321
+b321
+b321
+b321b
+c321d
+a122
+b322b
+a123
+b123
+ 123b
+c123d
+t22: numeric, skip past first 2 digits
+abc
+ab
+a
+
+
+a321
+b321
+c321d
+b321
+b321b
+a122
+b322b
+a123
+b123
+c123d
+ 123b
+t23: hexadecimal, skip past first 2 digits
+abc
+ab
+a
+
+
+a321
+b321
+b321
+a122
+a123
+b123
+b321b
+c321d
+b322b
+ 123b
+c123d
+t24: alpha, sort on first 2 digits
+abc
+ab
+a
+
+
+a123
+a122
+b123
+c123d
+ 123b
+a321
+b321
+c321d
+b322b
+b321
+b321b
+t25: numeric, sort on first 2 digits
+abc
+ab
+a
+
+
+a123
+a122
+b123
+c123d
+ 123b
+a321
+b321
+c321d
+b322b
+b321
+b321b
+t26: hexadecimal, sort on first 2 digits
+abc
+ab
+a
+
+
+a123
+a122
+b123
+c123d
+ 123b
+a321
+b321
+c321d
+b322b
+b321
+b321b
+t27: wrong arguments
+abc
+ab
+a
+a321
+a123
+a122
+b321
+b123
+c123d
+ 123b
+c321d
+b322b
+b321
+b321b
+
+
+t28: done
+
diff --git a/src/testdir/test58.in b/src/testdir/test58.in
new file mode 100644
index 0000000000..cef1cfa1ba
--- /dev/null
+++ b/src/testdir/test58.in
@@ -0,0 +1,639 @@
+Tests for spell checking. vim: set ft=vim :
+
+STARTTEST
+:so small.vim
+:"
+:" Don't want to depend on the locale from the environment
+:set enc=latin1
+:e!
+:"
+:" Check using z= in new buffer (crash fixed by patch 7.4a.028).
+:set maxmem=512 spell
+iasdz=:"
+:"
+:" Function to test .aff/.dic with list of good and bad words.
+:func TestOne(aff, dic)
+ set spellfile=
+ $put =''
+ $put ='test '. a:aff . '-' . a:dic
+ " Generate a .spl file from a .dic and .aff file.
+ exe '1;/^' . a:aff . 'affstart/+1,/^' . a:aff . 'affend/-1w! Xtest.aff'
+ exe '1;/^' . a:dic . 'dicstart/+1,/^' . a:dic . 'dicend/-1w! Xtest.dic'
+ mkspell! Xtest Xtest
+ " use that spell file
+ set spl=Xtest.latin1.spl spell
+ " list all valid words
+ spelldump
+ %yank
+ quit
+ $put
+ $put ='-------'
+ " find all bad words and suggestions for them
+ exe '1;/^' . a:aff . 'good:'
+ normal 0f:]s
+ let prevbad = ''
+ while 1
+ let [bad, a] = spellbadword()
+ if bad == '' || bad == prevbad || bad == 'badend'
+ break
+ endif
+ let prevbad = bad
+ let lst = spellsuggest(bad, 3)
+ normal mm
+ $put =bad
+ $put =string(lst)
+ normal `m]s
+ endwhile
+endfunc
+:"
+:call TestOne('1', '1')
+:$put =soundfold('goobledygoook')
+:$put =soundfold('kóopërÿnôven')
+:$put =soundfold('oeverloos gezwets edale')
+:"
+:"
+:" and now with SAL instead of SOFO items; test automatic reloading
+gg:/^affstart_sal/+1,/^affend_sal/-1w! Xtest.aff
+:mkspell! Xtest Xtest
+:$put =soundfold('goobledygoook')
+:$put =soundfold('kóopërÿnôven')
+:$put =soundfold('oeverloos gezwets edale')
+:"
+:" also use an addition file
+gg:/^addstart/+1,/^addend/-1w! Xtest.latin1.add
+:mkspell! Xtest.latin1.add.spl Xtest.latin1.add
+:set spellfile=Xtest.latin1.add
+/^test2:
+]s:let [str, a] = spellbadword()
+:$put =str
+:set spl=Xtest_us.latin1.spl
+/^test2:
+]smm:let [str, a] = spellbadword()
+:$put =str
+`m]s:let [str, a] = spellbadword()
+:$put =str
+:set spl=Xtest_gb.latin1.spl
+/^test2:
+]smm:let [str, a] = spellbadword()
+:$put =str
+`m]s:let [str, a] = spellbadword()
+:$put =str
+:set spl=Xtest_nz.latin1.spl
+/^test2:
+]smm:let [str, a] = spellbadword()
+:$put =str
+`m]s:let [str, a] = spellbadword()
+:$put =str
+:set spl=Xtest_ca.latin1.spl
+/^test2:
+]smm:let [str, a] = spellbadword()
+:$put =str
+`m]s:let [str, a] = spellbadword()
+:$put =str
+:unlet str a
+:"
+:" Postponed prefixes
+:call TestOne('2', '1')
+:"
+:" Compound words
+:call TestOne('3', '3')
+:call TestOne('4', '4')
+:call TestOne('5', '5')
+:call TestOne('6', '6')
+:call TestOne('7', '7')
+:"
+:" NOSLITSUGS
+:call TestOne('8', '8')
+:"
+:" clean up for valgrind
+:delfunc TestOne
+:set spl= enc=latin1
+:"
+gg:/^test output:/,$wq! test.out
+ENDTEST
+
+1affstart
+SET ISO8859-1
+TRY esianrtolcdugmphbyfvkwjkqxz-ëéèêïîäàâöüû'ESIANRTOLCDUGMPHBYFVKWJKQXZ
+
+FOL àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþßÿ
+LOW àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþßÿ
+UPP ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßÿ
+
+SOFOFROM abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþßÿÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ¿
+SOFOTO ebctefghejklnnepkrstevvkesebctefghejklnnepkrstevvkeseeeeeeeceeeeeeeedneeeeeeeeeeepseeeeeeeeceeeeeeeedneeeeeeeeeeep?
+
+MIDWORD '-
+
+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àáâãäå
+MAP eèéêë
+MAP iìíîï
+MAP oòóôõö
+MAP uùúûü
+MAP nñ
+MAP cç
+MAP yÿý
+MAP sß
+1affend
+
+1good: wrong OK puts. Test the end
+bad: inputs comment ok Ok. test déôl end the
+badend
+
+1dicstart
+123456
+test/NO
+# comment
+wrong
+Comment
+OK
+uk
+put/ISO
+the end
+deol
+déôr
+1dicend
+
+affstart_sal
+SET ISO8859-1
+TRY esianrtolcdugmphbyfvkwjkqxz-ëéèêïîäàâöüû'ESIANRTOLCDUGMPHBYFVKWJKQXZ
+
+FOL àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþßÿ
+LOW àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþßÿ
+UPP ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßÿ
+
+MIDWORD '-
+
+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àáâãäå
+MAP eèéêë
+MAP iìíîï
+MAP oòóôõö
+MAP uùúûü
+MAP nñ
+MAP cç
+MAP yÿý
+MAP sß
+
+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 À^ *
+SAL Å^ *
+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 É< 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
+affend_sal
+
+2affstart
+SET ISO8859-1
+
+FOL àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþßÿ
+LOW àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþßÿ
+UPP ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßÿ
+
+PFXPOSTPONE
+
+MIDWORD '-
+
+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àáâãäå
+MAP eèéêë
+MAP iìíîï
+MAP oòóôõö
+MAP uùúûü
+MAP nñ
+MAP cç
+MAP yÿý
+MAP sß
+2affend
+
+2good: puts
+bad: inputs comment ok Ok end the. test déôl
+badend
+
+addstart
+/regions=usgbnz
+elequint/2
+elekwint/3
+addend
+
+test2:
+elequint test elekwint test elekwent asdf
+
+Test rules for compounding.
+
+3affstart
+SET ISO8859-1
+
+COMPOUNDMIN 3
+COMPOUNDRULE m*
+NEEDCOMPOUND x
+3affend
+
+3dicstart
+1234
+foo/m
+bar/mx
+mï/m
+la/mx
+3dicend
+
+3good: foo mï foobar foofoobar barfoo barbarfoo
+bad: bar la foomï barmï mïfoo mïbar mïmï lala mïla lamï foola labar
+badend
+
+
+Tests for compounding.
+
+4affstart
+SET ISO8859-1
+
+FOL àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþßÿ
+LOW àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþßÿ
+UPP ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßÿ
+
+COMPOUNDRULE m+
+COMPOUNDRULE sm*e
+COMPOUNDRULE sm+
+COMPOUNDMIN 3
+COMPOUNDWORDMAX 3
+COMPOUNDFORBIDFLAG t
+
+COMPOUNDSYLMAX 5
+SYLLABLE aáeéiíoóöõuúüûy/aa/au/ea/ee/ei/ie/oa/oe/oo/ou/uu/ui
+
+MAP 9
+MAP aàáâãäå
+MAP eèéêë
+MAP iìíîï
+MAP oòóôõö
+MAP uùúûü
+MAP nñ
+MAP cç
+MAP yÿý
+MAP sß
+
+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 .
+4affend
+
+4dicstart
+1234
+word/mP
+util/am
+pro/xq
+tomato/m
+bork/mp
+start/s
+end/e
+4dicend
+
+4good: 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
+badend
+
+Test affix flags with two characters
+
+5affstart
+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é Y 1
+SFX aé 0 aé .
+
+PFX zz Y 1
+PFX zz 0 pre/pp .
+
+PFX yy Y 1
+PFX yy 0 nou .
+5affend
+
+5dicstart
+1234
+foo/a1aé!!
+bar/zz13ee
+start/ss
+end/eeyy
+middle/mmxx
+5dicend
+
+5good: fooa1 fooaé bar prebar barbork prebarbork startprebar
+ start end startend startmiddleend nouend
+bad: foo fooa2 prabar probarbirk middle startmiddle middleend endstart
+ startprobar startnouend
+badend
+
+6affstart
+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é Y 1
+SFX Aé 0 aé .
+
+PFX Zz Y 1
+PFX Zz 0 pre/p .
+6affend
+
+6dicstart
+1234
+mee/A1AéA!
+bar/ZzN3Ee
+lead/s
+end/Ee
+middle/MmXx
+6dicend
+
+6good: meea1 meeaé bar prebar barbork prebarbork leadprebar
+ lead end leadend leadmiddleend
+bad: mee meea2 prabar probarbirk middle leadmiddle middleend endlead
+ leadprobar
+badend
+
+7affstart
+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é .
+
+PFX 17 Y 1
+PFX 17 0 pre/432 .
+7affend
+
+7dicstart
+1234
+mee/391,111,9999
+bar/17,61003,123
+lead/2
+tail/123
+middle/77,1
+7dicend
+
+7good: meea1 meeaé bar prebar barmeat prebarmeat leadprebar
+ lead tail leadtail leadmiddletail
+bad: mee meea2 prabar probarmaat middle leadmiddle middletail taillead
+ leadprobar
+badend
+
+Test NOSLITSUGS
+
+8affstart
+SET ISO8859-1
+
+NOSPLITSUGS
+8affend
+
+8dicstart
+1234
+foo
+bar
+faabar
+8dicend
+
+8good: foo bar faabar
+bad: foobar barfoo
+badend
+
+
+test output:
diff --git a/src/testdir/test58.ok b/src/testdir/test58.ok
new file mode 100644
index 0000000000..ce05c73322
--- /dev/null
+++ b/src/testdir/test58.ok
@@ -0,0 +1,283 @@
+test output:
+
+test 1-1
+# file: Xtest.latin1.spl
+Comment
+deol
+déôr
+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éôl
+['deol', 'déôr', 'test']
+end
+['put', 'uk', 'test']
+the
+['put', 'uk', 'test']
+gebletegek
+kepereneven
+everles gesvets etele
+kbltykk
+kprnfn
+*fls kswts tl
+elekwent
+elequint
+elekwint
+elekwint
+elekwent
+elequint
+elekwent
+elequint
+elekwint
+
+test 2-1
+# file: Xtest.latin1.spl
+Comment
+deol
+déôr
+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éôl
+['deol', 'déôr', 'test']
+
+test 3-3
+# file: Xtest.latin1.spl
+foo
+mï
+-------
+bad
+['foo', 'mï']
+bar
+['barfoo', 'foobar', 'foo']
+la
+['mï', 'foo']
+foomï
+['foo mï', 'foo', 'foofoo']
+barmï
+['barfoo', 'mï', 'barbar']
+mïfoo
+['mï foo', 'foo', 'foofoo']
+mïbar
+['foobar', 'barbar', 'mï']
+mïmï
+['mï mï', 'mï']
+lala
+[]
+mïla
+['mï', 'mï mï']
+lamï
+['mï', 'mï mï']
+foola
+['foo', 'foobar', 'foofoo']
+labar
+['barbar', 'foobar']
+
+test 4-4
+# file: Xtest.latin1.spl
+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']
+
+test 5-5
+# file: Xtest.latin1.spl
+bar
+barbork
+end
+fooa1
+fooaé
+nouend
+prebar
+prebarbork
+start
+-------
+bad
+['bar', 'end', 'fooa1']
+foo
+['fooa1', 'fooaé', 'bar']
+fooa2
+['fooa1', 'fooaé', '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']
+
+test 6-6
+# file: Xtest.latin1.spl
+bar
+barbork
+end
+lead
+meea1
+meeaé
+prebar
+prebarbork
+-------
+bad
+['bar', 'end', 'lead']
+mee
+['meea1', 'meeaé', 'bar']
+meea2
+['meea1', 'meeaé', 'lead']
+prabar
+['prebar', 'bar', 'leadbar']
+probarbirk
+['prebarbork']
+middle
+[]
+leadmiddle
+['leadmiddleend', 'leadmiddlebar']
+middleend
+[]
+endlead
+['end lead', 'lead', 'end end']
+leadprobar
+['leadprebar', 'lead prebar', 'leadbar']
+
+test 7-7
+# file: Xtest.latin1.spl
+bar
+barmeat
+lead
+meea1
+meeaé
+prebar
+prebarmeat
+tail
+-------
+bad
+['bar', 'lead', 'tail']
+mee
+['meea1', 'meeaé', 'bar']
+meea2
+['meea1', 'meeaé', 'lead']
+prabar
+['prebar', 'bar', 'leadbar']
+probarmaat
+['prebarmeat']
+middle
+[]
+leadmiddle
+['leadmiddlebar']
+middletail
+[]
+taillead
+['tail lead', 'tail']
+leadprobar
+['leadprebar', 'lead prebar', 'leadbar']
+
+test 8-8
+# file: Xtest.latin1.spl
+bar
+faabar
+foo
+-------
+bad
+['bar', 'foo']
+foobar
+['faabar', 'foo bar', 'bar']
+barfoo
+['bar foo', 'bar', 'foo']
diff --git a/src/testdir/test59.in b/src/testdir/test59.in
new file mode 100644
index 0000000000..dcdb62b283
--- /dev/null
+++ b/src/testdir/test59.in
@@ -0,0 +1,626 @@
+Tests for spell checking with 'encoding' set to "utf-8". vim: set ft=vim :
+
+STARTTEST
+:so small.vim
+:so mbyte.vim
+:"
+:" Don't want to depend on the locale from the environment. The .aff and .dic
+:" text is in latin1, the test text is utf-8.
+:set enc=latin1
+:e!
+:set enc=utf-8
+:set fenc=
+:"
+:" Function to test .aff/.dic with list of good and bad words.
+:func TestOne(aff, dic)
+ set spellfile=
+ $put =''
+ $put ='test '. a:aff . '-' . a:dic
+ " Generate a .spl file from a .dic and .aff file.
+ exe '1;/^' . a:aff . 'affstart/+1,/^' . a:aff . 'affend/-1w! Xtest.aff'
+ exe '1;/^' . a:dic . 'dicstart/+1,/^' . a:dic . 'dicend/-1w! Xtest.dic'
+ mkspell! Xtest Xtest
+ " use that spell file
+ set spl=Xtest.utf-8.spl spell
+ " list all valid words
+ spelldump
+ %yank
+ quit
+ $put
+ $put ='-------'
+ " find all bad words and suggestions for them
+ exe '1;/^' . a:aff . 'good:'
+ normal 0f:]s
+ let prevbad = ''
+ while 1
+ let [bad, a] = spellbadword()
+ if bad == '' || bad == prevbad || bad == 'badend'
+ break
+ endif
+ let prevbad = bad
+ let lst = spellsuggest(bad, 3)
+ normal mm
+ $put =bad
+ $put =string(lst)
+ normal `m]s
+ endwhile
+endfunc
+:"
+:call TestOne('1', '1')
+:$put =soundfold('goobledygoook')
+:$put =soundfold('kóopërÿnôven')
+:$put =soundfold('oeverloos gezwets edale')
+:"
+:"
+:" and now with SAL instead of SOFO items; test automatic reloading
+gg:/^affstart_sal/+1,/^affend_sal/-1w! Xtest.aff
+:mkspell! Xtest Xtest
+:$put =soundfold('goobledygoook')
+:$put =soundfold('kóopërÿnôven')
+:$put =soundfold('oeverloos gezwets edale')
+:"
+:" also use an addition file
+gg:/^addstart/+1,/^addend/-1w! Xtest.utf-8.add
+:mkspell! Xtest.utf-8.add.spl Xtest.utf-8.add
+:set spellfile=Xtest.utf-8.add
+/^test2:
+]s:let [str, a] = spellbadword()
+:$put =str
+:set spl=Xtest_us.utf-8.spl
+/^test2:
+]smm:let [str, a] = spellbadword()
+:$put =str
+`m]s:let [str, a] = spellbadword()
+:$put =str
+:set spl=Xtest_gb.utf-8.spl
+/^test2:
+]smm:let [str, a] = spellbadword()
+:$put =str
+`m]s:let [str, a] = spellbadword()
+:$put =str
+:set spl=Xtest_nz.utf-8.spl
+/^test2:
+]smm:let [str, a] = spellbadword()
+:$put =str
+`m]s:let [str, a] = spellbadword()
+:$put =str
+:set spl=Xtest_ca.utf-8.spl
+/^test2:
+]smm:let [str, a] = spellbadword()
+:$put =str
+`m]s:let [str, a] = spellbadword()
+:$put =str
+:unlet str a
+:"
+:" Postponed prefixes
+:call TestOne('2', '1')
+:"
+:" Compound words
+:call TestOne('3', '3')
+:call TestOne('4', '4')
+:call TestOne('5', '5')
+:call TestOne('6', '6')
+:call TestOne('7', '7')
+:"
+:" clean up for valgrind
+:delfunc TestOne
+:set spl= enc=latin1
+:"
+gg:/^test output:/,$wq! test.out
+ENDTEST
+
+1affstart
+SET ISO8859-1
+TRY esianrtolcdugmphbyfvkwjkqxz-ëéèêïîäàâöüû'ESIANRTOLCDUGMPHBYFVKWJKQXZ
+
+FOL àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþßÿ
+LOW àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþßÿ
+UPP ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßÿ
+
+SOFOFROM abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþßÿÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ¿
+SOFOTO ebctefghejklnnepkrstevvkesebctefghejklnnepkrstevvkeseeeeeeeceeeeeeeedneeeeeeeeeeepseeeeeeeeceeeeeeeedneeeeeeeeeeep?
+
+MIDWORD '-
+
+KEP =
+RAR ?
+BAD !
+
+#NOSPLITSUGS
+
+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àáâãäå
+MAP eèéêë
+MAP iìíîï
+MAP oòóôõö
+MAP uùúûü
+MAP nñ
+MAP cç
+MAP yÿý
+MAP sß
+1affend
+
+affstart_sal
+SET ISO8859-1
+TRY esianrtolcdugmphbyfvkwjkqxz-ëéèêïîäàâöüû'ESIANRTOLCDUGMPHBYFVKWJKQXZ
+
+FOL àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþßÿ
+LOW àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþßÿ
+UPP ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßÿ
+
+MIDWORD '-
+
+KEP =
+RAR ?
+BAD !
+
+#NOSPLITSUGS
+
+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àáâãäå
+MAP eèéêë
+MAP iìíîï
+MAP oòóôõö
+MAP uùúûü
+MAP nñ
+MAP cç
+MAP yÿý
+MAP sß
+
+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 À^ *
+SAL Å^ *
+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 É< 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
+affend_sal
+
+2affstart
+SET ISO8859-1
+
+FOL àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþßÿ
+LOW àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþßÿ
+UPP ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßÿ
+
+PFXPOSTPONE
+
+MIDWORD '-
+
+KEP =
+RAR ?
+BAD !
+
+#NOSPLITSUGS
+
+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àáâãäå
+MAP eèéêë
+MAP iìíîï
+MAP oòóôõö
+MAP uùúûü
+MAP nñ
+MAP cç
+MAP yÿý
+MAP sß
+2affend
+
+1dicstart
+123456
+test/NO
+# comment
+wrong
+Comment
+OK
+uk
+put/ISO
+the end
+deol
+déôr
+1dicend
+
+addstart
+/regions=usgbnz
+elequint/2
+elekwint/3
+addend
+
+1good: wrong OK puts. Test the end
+bad: inputs comment ok Ok. test déôl end the
+badend
+
+2good: puts
+bad: inputs comment ok Ok end the. test déôl
+badend
+
+Test rules for compounding.
+
+3affstart
+SET ISO8859-1
+
+COMPOUNDMIN 3
+COMPOUNDRULE m*
+NEEDCOMPOUND x
+3affend
+
+3dicstart
+1234
+foo/m
+bar/mx
+mï/m
+la/mx
+3dicend
+
+3good: foo mï foobar foofoobar barfoo barbarfoo
+bad: bar la foomï barmï mïfoo mïbar mïmï lala mïla lamï foola labar
+badend
+
+
+Tests for compounding.
+
+4affstart
+SET ISO8859-1
+
+FOL àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþßÿ
+LOW àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþßÿ
+UPP ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßÿ
+
+COMPOUNDRULE m+
+COMPOUNDRULE sm*e
+COMPOUNDRULE sm+
+COMPOUNDMIN 3
+COMPOUNDWORDMAX 3
+COMPOUNDFORBIDFLAG t
+
+COMPOUNDSYLMAX 5
+SYLLABLE aáeéiíoóöõuúüûy/aa/au/ea/ee/ei/ie/oa/oe/oo/ou/uu/ui
+
+MAP 9
+MAP aàáâãäå
+MAP eèéêë
+MAP iìíîï
+MAP oòóôõö
+MAP uùúûü
+MAP nñ
+MAP cç
+MAP yÿý
+MAP sß
+
+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 .
+4affend
+
+4dicstart
+1234
+word/mP
+util/am
+pro/xq
+tomato/m
+bork/mp
+start/s
+end/e
+4dicend
+
+4good: 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
+badend
+
+test2:
+elequint test elekwint test elekwent asdf
+
+Test affix flags with two characters
+
+5affstart
+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é Y 1
+SFX aé 0 aé .
+
+PFX zz Y 1
+PFX zz 0 pre/pp .
+
+PFX yy Y 1
+PFX yy 0 nou .
+5affend
+
+5dicstart
+1234
+foo/a1aé!!
+bar/zz13ee
+start/ss
+end/eeyy
+middle/mmxx
+5dicend
+
+5good: fooa1 fooaé bar prebar barbork prebarbork startprebar
+ start end startend startmiddleend nouend
+bad: foo fooa2 prabar probarbirk middle startmiddle middleend endstart
+ startprobar startnouend
+badend
+
+6affstart
+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é Y 1
+SFX Aé 0 aé .
+
+PFX Zz Y 1
+PFX Zz 0 pre/p .
+6affend
+
+6dicstart
+1234
+mee/A1AéA!
+bar/ZzN3Ee
+lead/s
+end/Ee
+middle/MmXx
+6dicend
+
+6good: meea1 meeaé bar prebar barbork prebarbork leadprebar
+ lead end leadend leadmiddleend
+bad: mee meea2 prabar probarbirk middle leadmiddle middleend endlead
+ leadprobar
+badend
+
+7affstart
+SET ISO8859-1
+
+FOL àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþßÿ
+LOW àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþßÿ
+UPP ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßÿ
+
+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é .
+
+PFX 17 Y 1
+PFX 17 0 pre/432 .
+7affend
+
+7dicstart
+1234
+mee/391,111,9999
+bar/17,61003,123
+lead/2
+tail/123
+middle/77,1
+7dicend
+
+7good: meea1 meeaé bar prebar barmeat prebarmeat leadprebar
+ lead tail leadtail leadmiddletail
+bad: mee meea2 prabar probarmaat middle leadmiddle middletail taillead
+ leadprobar
+badend
+
+test output:
diff --git a/src/testdir/test59.ok b/src/testdir/test59.ok
new file mode 100644
index 0000000000..931cdd9654
--- /dev/null
+++ b/src/testdir/test59.ok
@@ -0,0 +1,270 @@
+test output:
+
+test 1-1
+# file: Xtest.utf-8.spl
+Comment
+deol
+déôr
+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éôl
+['deol', 'déôr', 'test']
+end
+['put', 'uk', 'test']
+the
+['put', 'uk', 'test']
+gebletegek
+kepereneven
+everles gesvets etele
+kbltykk
+kprnfn
+*fls kswts tl
+elekwent
+elequint
+elekwint
+elekwint
+elekwent
+elequint
+elekwent
+elequint
+elekwint
+
+test 2-1
+# file: Xtest.utf-8.spl
+Comment
+deol
+déôr
+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éôl
+['deol', 'déôr', 'test']
+
+test 3-3
+# file: Xtest.utf-8.spl
+foo
+mï
+-------
+bad
+['foo', 'mï']
+bar
+['barfoo', 'foobar', 'foo']
+la
+['mï', 'foo']
+foomï
+['foo mï', 'foo', 'foofoo']
+barmï
+['barfoo', 'mï', 'barbar']
+mïfoo
+['mï foo', 'foo', 'foofoo']
+mïbar
+['foobar', 'barbar', 'mï']
+mïmï
+['mï mï', 'mï']
+lala
+[]
+mïla
+['mï', 'mï mï']
+lamï
+['mï', 'mï mï']
+foola
+['foo', 'foobar', 'foofoo']
+labar
+['barbar', 'foobar']
+
+test 4-4
+# file: Xtest.utf-8.spl
+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']
+
+test 5-5
+# file: Xtest.utf-8.spl
+bar
+barbork
+end
+fooa1
+fooaé
+nouend
+prebar
+prebarbork
+start
+-------
+bad
+['bar', 'end', 'fooa1']
+foo
+['fooa1', 'fooaé', 'bar']
+fooa2
+['fooa1', 'fooaé', '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']
+
+test 6-6
+# file: Xtest.utf-8.spl
+bar
+barbork
+end
+lead
+meea1
+meeaé
+prebar
+prebarbork
+-------
+bad
+['bar', 'end', 'lead']
+mee
+['meea1', 'meeaé', 'bar']
+meea2
+['meea1', 'meeaé', 'lead']
+prabar
+['prebar', 'bar', 'leadbar']
+probarbirk
+['prebarbork']
+middle
+[]
+leadmiddle
+['leadmiddleend', 'leadmiddlebar']
+middleend
+[]
+endlead
+['end lead', 'lead', 'end end']
+leadprobar
+['leadprebar', 'lead prebar', 'leadbar']
+
+test 7-7
+# file: Xtest.utf-8.spl
+bar
+barmeat
+lead
+meea1
+meeaé
+prebar
+prebarmeat
+tail
+-------
+bad
+['bar', 'lead', 'tail']
+mee
+['meea1', 'meeaé', 'bar']
+meea2
+['meea1', 'meeaé', 'lead']
+prabar
+['prebar', 'bar', 'leadbar']
+probarmaat
+['prebarmeat']
+middle
+[]
+leadmiddle
+['leadmiddlebar']
+middletail
+[]
+taillead
+['tail lead', 'tail']
+leadprobar
+['leadprebar', 'lead prebar', 'leadbar']
diff --git a/src/testdir/test6.in b/src/testdir/test6.in
new file mode 100644
index 0000000000..1ebbe2fa51
--- /dev/null
+++ b/src/testdir/test6.in
@@ -0,0 +1,24 @@
+Test for autocommand that redefines the argument list, when doing ":all".
+
+STARTTEST
+:so small.vim
+:au BufReadPost Xxx2 next Xxx2 Xxx1
+/^start of
+A1:.,/end of/w! Xxx1 " write test file Xxx1
+$r2:.,/end of/w! Xxx2 " write test file Xxx2
+$r3:.,/end of/w! Xxx3 " write test file Xxx3
+:next! Xxx1 Xxx2 Xxx3 " redefine arglist; go to Xxx1
+:all " open window for all args
+:w! test.out " Write contents of Xxx1
+:w >>test.out " Append contents of last window (Xxx1)
+:rew " should now be in Xxx2
+:w >>test.out " Append contents of Xxx2
+:qa!
+ENDTEST
+
+start of test file Xxx
+ this is a test
+ this is a test
+ this is a test
+ this is a test
+end of test file Xxx
diff --git a/src/testdir/test6.ok b/src/testdir/test6.ok
new file mode 100644
index 0000000000..b6b0c93e4e
--- /dev/null
+++ b/src/testdir/test6.ok
@@ -0,0 +1,18 @@
+start of test file Xxx1
+ this is a test
+ this is a test
+ this is a test
+ this is a test
+end of test file Xxx
+start of test file Xxx1
+ this is a test
+ this is a test
+ this is a test
+ this is a test
+end of test file Xxx
+start of test file Xxx2
+ this is a test
+ this is a test
+ this is a test
+ this is a test
+end of test file Xxx
diff --git a/src/testdir/test60.in b/src/testdir/test60.in
new file mode 100644
index 0000000000..0f30142dcf
--- /dev/null
+++ b/src/testdir/test60.in
@@ -0,0 +1,600 @@
+Tests for the exists() function. vim: set ft=vim ts=8 :
+
+STARTTEST
+:so small.vim
+:function! RunTest(str, result)
+ if exists(a:str) == a:result
+ echo "OK"
+ else
+ echo "FAILED: Checking for " . a:str
+ endif
+endfunction
+:function! TestExists()
+ augroup myagroup
+ autocmd! BufEnter *.my echo "myfile edited"
+ autocmd! FuncUndefined UndefFun exec "fu UndefFun()\nendfu"
+ augroup END
+ set rtp+=./sautest
+
+ let test_cases = []
+
+ " valid autocmd group
+ let test_cases += [['#myagroup', 1]]
+ " valid autocmd group with garbage
+ let test_cases += [['#myagroup+b', 0]]
+ " Valid autocmd group and event
+ let test_cases += [['#myagroup#BufEnter', 1]]
+ " Valid autocmd group, event and pattern
+ let test_cases += [['#myagroup#BufEnter#*.my', 1]]
+ " Valid autocmd event
+ let test_cases += [['#BufEnter', 1]]
+ " Valid autocmd event and pattern
+ let test_cases += [['#BufEnter#*.my', 1]]
+ " Non-existing autocmd group or event
+ let test_cases += [['#xyzagroup', 0]]
+ " Non-existing autocmd group and valid autocmd event
+ let test_cases += [['#xyzagroup#BufEnter', 0]]
+ " Valid autocmd group and event with no matching pattern
+ let test_cases += [['#myagroup#CmdwinEnter', 0]]
+ " Valid autocmd group and non-existing autocmd event
+ let test_cases += [['#myagroup#xyzacmd', 0]]
+ " Valid autocmd group and event and non-matching pattern
+ let test_cases += [['#myagroup#BufEnter#xyzpat', 0]]
+ " Valid autocmd event and non-matching pattern
+ let test_cases += [['#BufEnter#xyzpat', 0]]
+ " Empty autocmd group, event and pattern
+ let test_cases += [['###', 0]]
+ " Empty autocmd group and event or empty event and pattern
+ let test_cases += [['##', 0]]
+ " Valid autocmd event
+ let test_cases += [['##FileReadCmd', 1]]
+ " Non-existing autocmd event
+ let test_cases += [['##MySpecialCmd', 0]]
+
+ " Existing and working option (long form)
+ let test_cases += [['&textwidth', 1]]
+ " Existing and working option (short form)
+ let test_cases += [['&tw', 1]]
+ " Existing and working option with garbage
+ let test_cases += [['&tw-', 0]]
+ " Global option
+ let test_cases += [['&g:errorformat', 1]]
+ " Local option
+ let test_cases += [['&l:errorformat', 1]]
+ " Negative form of existing and working option (long form)
+ let test_cases += [['&nojoinspaces', 0]]
+ " Negative form of existing and working option (short form)
+ let test_cases += [['&nojs', 0]]
+ " Non-existing option
+ let test_cases += [['&myxyzoption', 0]]
+
+ " Existing and working option (long form)
+ let test_cases += [['+incsearch', 1]]
+ " Existing and working option with garbage
+ let test_cases += [['+incsearch!1', 0]]
+ " Existing and working option (short form)
+ let test_cases += [['+is', 1]]
+ " Existing option that is hidden.
+ let test_cases += [['+autoprint', 0]]
+
+ " Existing environment variable
+ let $EDITOR_NAME = 'Vim Editor'
+ let test_cases += [['$EDITOR_NAME', 1]]
+ " Non-existing environment variable
+ let test_cases += [['$NON_ENV_VAR', 0]]
+
+ " Valid internal function
+ let test_cases += [['*bufnr', 1]]
+ " Valid internal function with ()
+ let test_cases += [['*bufnr()', 1]]
+ " Non-existing internal function
+ let test_cases += [['*myxyzfunc', 0]]
+ " Valid internal function with garbage
+ let test_cases += [['*bufnr&6', 0]]
+
+ " Valid user defined function
+ let test_cases += [['*TestExists', 1]]
+ " Non-existing user defined function
+ let test_cases += [['*MyxyzFunc', 0]]
+
+ " Function that may be created by FuncUndefined event
+ let test_cases += [['*UndefFun', 0]]
+ " Function that may be created by script autoloading
+ let test_cases += [['*footest#F', 0]]
+
+ redir! > test.out
+
+ for [test_case, result] in test_cases
+ echo test_case . ": " . result
+ call RunTest(test_case, result)
+ endfor
+
+ " Valid internal command (full match)
+ echo ':edit: 2'
+ if exists(':edit') == 2
+ echo "OK"
+ else
+ echo "FAILED"
+ endif
+
+ " Valid internal command (full match) with garbage
+ echo ':edit/a: 0'
+ if exists(':edit/a') == 0
+ echo "OK"
+ else
+ echo "FAILED"
+ endif
+
+ " Valid internal command (partial match)
+ echo ':q: 1'
+ if exists(':q') == 1
+ echo "OK"
+ else
+ echo "FAILED"
+ endif
+
+ " Non-existing internal command
+ echo ':invalidcmd: 0'
+ if !exists(':invalidcmd')
+ echo "OK"
+ else
+ echo "FAILED"
+ endif
+
+ " User defined command (full match)
+ command! MyCmd :echo 'My command'
+ echo ':MyCmd: 2'
+ if exists(':MyCmd') == 2
+ echo "OK"
+ else
+ echo "FAILED"
+ endif
+
+ " User defined command (partial match)
+ command! MyOtherCmd :echo 'Another command'
+ echo ':My: 3'
+ if exists(':My') == 3
+ echo "OK"
+ else
+ echo "FAILED"
+ endif
+
+ " Command modifier
+ echo ':rightbelow: 2'
+ if exists(':rightbelow') == 2
+ echo "OK"
+ else
+ echo "FAILED"
+ endif
+
+ " Non-existing user defined command (full match)
+ delcommand MyCmd
+
+ echo ':MyCmd: 0'
+ if !exists(':MyCmd')
+ echo "OK"
+ else
+ echo "FAILED"
+ endif
+
+ " Non-existing user defined command (partial match)
+ delcommand MyOtherCmd
+
+ echo ':My: 0'
+ if !exists(':My')
+ echo "OK"
+ else
+ echo "FAILED"
+ endif
+
+ " Valid local variable
+ let local_var = 1
+ echo 'local_var: 1'
+ if exists('local_var')
+ echo "OK"
+ else
+ echo "FAILED"
+ endif
+
+ " Valid local variable with garbage
+ let local_var = 1
+ echo 'local_var%n: 0'
+ if !exists('local_var%n')
+ echo "OK"
+ else
+ echo "FAILED"
+ endif
+
+ " Non-existing local variable
+ unlet local_var
+ echo 'local_var: 0'
+ if !exists('local_var')
+ echo "OK"
+ else
+ echo "FAILED"
+ endif
+
+ " Non-existing autoload variable that may be autoloaded
+ echo 'footest#x: 0'
+ if !exists('footest#x')
+ echo "OK"
+ else
+ echo "FAILED"
+ endif
+
+ " Valid local list
+ let local_list = ["blue", "orange"]
+ echo 'local_list: 1'
+ if exists('local_list')
+ echo "OK"
+ else
+ echo "FAILED"
+ endif
+
+ " Valid local list item
+ echo 'local_list[1]: 1'
+ if exists('local_list[1]')
+ echo "OK"
+ else
+ echo "FAILED"
+ endif
+
+ " Valid local list item with garbage
+ echo 'local_list[1]+5: 0'
+ if !exists('local_list[1]+5')
+ echo "OK"
+ else
+ echo "FAILED"
+ endif
+
+ " Invalid local list item
+ echo 'local_list[2]: 0'
+ if !exists('local_list[2]')
+ echo "OK"
+ else
+ echo "FAILED"
+ endif
+
+ " Non-existing local list
+ unlet local_list
+ echo 'local_list: 0'
+ if !exists('local_list')
+ echo "OK"
+ else
+ echo "FAILED"
+ endif
+
+ " Valid local dictionary
+ let local_dict = {"xcord":100, "ycord":2}
+ echo 'local_dict: 1'
+ if exists('local_dict')
+ echo "OK"
+ else
+ echo "FAILED"
+ endif
+
+ " Non-existing local dictionary
+ unlet local_dict
+ echo 'local_dict: 0'
+ if !exists('local_dict')
+ echo "OK"
+ else
+ echo "FAILED"
+ endif
+
+ " Existing local curly-brace variable
+ let str = "local"
+ let curly_{str}_var = 1
+ echo 'curly_' . str . '_var: 1'
+ if exists('curly_{str}_var')
+ echo "OK"
+ else
+ echo "FAILED"
+ endif
+
+ " Non-existing local curly-brace variable
+ unlet curly_{str}_var
+ echo 'curly_' . str . '_var: 0'
+ if !exists('curly_{str}_var')
+ echo "OK"
+ else
+ echo "FAILED"
+ endif
+
+
+ " Existing global variable
+ let g:global_var = 1
+ echo 'g:global_var: 1'
+ if exists('g:global_var')
+ echo "OK"
+ else
+ echo "FAILED"
+ endif
+
+ " Existing global variable with garbage
+ echo 'g:global_var-n: 1'
+ if !exists('g:global_var-n')
+ echo "OK"
+ else
+ echo "FAILED"
+ endif
+
+ " Non-existing global variable
+ unlet g:global_var
+ echo 'g:global_var: 0'
+ if !exists('g:global_var')
+ echo "OK"
+ else
+ echo "FAILED"
+ endif
+
+ " Existing global list
+ let g:global_list = ["blue", "orange"]
+ echo 'g:global_list: 1'
+ if exists('g:global_list')
+ echo "OK"
+ else
+ echo "FAILED"
+ endif
+
+ " Non-existing global list
+ unlet g:global_list
+ echo 'g:global_list: 0'
+ if !exists('g:global_list')
+ echo "OK"
+ else
+ echo "FAILED"
+ endif
+
+ " Existing global dictionary
+ let g:global_dict = {"xcord":100, "ycord":2}
+ echo 'g:global_dict: 1'
+ if exists('g:global_dict')
+ echo "OK"
+ else
+ echo "FAILED"
+ endif
+
+ " Non-existing global dictionary
+ unlet g:global_dict
+ echo 'g:global_dict: 0'
+ if !exists('g:global_dict')
+ echo "OK"
+ else
+ echo "FAILED"
+ endif
+
+ " Existing global curly-brace variable
+ let str = "global"
+ let g:curly_{str}_var = 1
+ echo 'g:curly_' . str . '_var: 1'
+ if exists('g:curly_{str}_var')
+ echo "OK"
+ else
+ echo "FAILED"
+ endif
+
+ " Non-existing global curly-brace variable
+ unlet g:curly_{str}_var
+ echo 'g:curly_' . str . '_var: 0'
+ if !exists('g:curly_{str}_var')
+ echo "OK"
+ else
+ echo "FAILED"
+ endif
+
+ " Existing window variable
+ echo 'w:window_var: 1'
+ let w:window_var = 1
+ if exists('w:window_var')
+ echo "OK"
+ else
+ echo "FAILED"
+ endif
+
+ " Non-existing window variable
+ unlet w:window_var
+ echo 'w:window_var: 0'
+ if !exists('w:window_var')
+ echo "OK"
+ else
+ echo "FAILED"
+ endif
+
+ " Existing window list
+ let w:window_list = ["blue", "orange"]
+ echo 'w:window_list: 1'
+ if exists('w:window_list')
+ echo "OK"
+ else
+ echo "FAILED"
+ endif
+
+ " Non-existing window list
+ unlet w:window_list
+ echo 'w:window_list: 0'
+ if !exists('w:window_list')
+ echo "OK"
+ else
+ echo "FAILED"
+ endif
+
+ " Existing window dictionary
+ let w:window_dict = {"xcord":100, "ycord":2}
+ echo 'w:window_dict: 1'
+ if exists('w:window_dict')
+ echo "OK"
+ else
+ echo "FAILED"
+ endif
+
+ " Non-existing window dictionary
+ unlet w:window_dict
+ echo 'w:window_dict: 0'
+ if !exists('w:window_dict')
+ echo "OK"
+ else
+ echo "FAILED"
+ endif
+
+ " Existing window curly-brace variable
+ let str = "window"
+ let w:curly_{str}_var = 1
+ echo 'w:curly_' . str . '_var: 1'
+ if exists('w:curly_{str}_var')
+ echo "OK"
+ else
+ echo "FAILED"
+ endif
+
+ " Non-existing window curly-brace variable
+ unlet w:curly_{str}_var
+ echo 'w:curly_' . str . '_var: 0'
+ if !exists('w:curly_{str}_var')
+ echo "OK"
+ else
+ echo "FAILED"
+ endif
+
+ " Existing buffer variable
+ echo 'b:buffer_var: 1'
+ let b:buffer_var = 1
+ if exists('b:buffer_var')
+ echo "OK"
+ else
+ echo "FAILED"
+ endif
+
+ " Non-existing buffer variable
+ unlet b:buffer_var
+ echo 'b:buffer_var: 0'
+ if !exists('b:buffer_var')
+ echo "OK"
+ else
+ echo "FAILED"
+ endif
+
+ " Existing buffer list
+ let b:buffer_list = ["blue", "orange"]
+ echo 'b:buffer_list: 1'
+ if exists('b:buffer_list')
+ echo "OK"
+ else
+ echo "FAILED"
+ endif
+
+ " Non-existing buffer list
+ unlet b:buffer_list
+ echo 'b:buffer_list: 0'
+ if !exists('b:buffer_list')
+ echo "OK"
+ else
+ echo "FAILED"
+ endif
+
+ " Existing buffer dictionary
+ let b:buffer_dict = {"xcord":100, "ycord":2}
+ echo 'b:buffer_dict: 1'
+ if exists('b:buffer_dict')
+ echo "OK"
+ else
+ echo "FAILED"
+ endif
+
+ " Non-existing buffer dictionary
+ unlet b:buffer_dict
+ echo 'b:buffer_dict: 0'
+ if !exists('b:buffer_dict')
+ echo "OK"
+ else
+ echo "FAILED"
+ endif
+
+ " Existing buffer curly-brace variable
+ let str = "buffer"
+ let b:curly_{str}_var = 1
+ echo 'b:curly_' . str . '_var: 1'
+ if exists('b:curly_{str}_var')
+ echo "OK"
+ else
+ echo "FAILED"
+ endif
+
+ " Non-existing buffer curly-brace variable
+ unlet b:curly_{str}_var
+ echo 'b:curly_' . str . '_var: 0'
+ if !exists('b:curly_{str}_var')
+ echo "OK"
+ else
+ echo "FAILED"
+ endif
+
+ " Script-local tests
+ source test60.vim
+
+ " Existing Vim internal variable
+ echo 'v:version: 1'
+ if exists('v:version')
+ echo "OK"
+ else
+ echo "FAILED"
+ endif
+
+ " Non-existing Vim internal variable
+ echo 'v:non_exists_var: 0'
+ if !exists('v:non_exists_var')
+ echo "OK"
+ else
+ echo "FAILED"
+ endif
+
+ " Function arguments
+ function TestFuncArg(func_arg, ...)
+ echo 'a:func_arg: 1'
+ if exists('a:func_arg')
+ echo "OK"
+ else
+ echo "FAILED"
+ endif
+
+ echo 'a:non_exists_arg: 0'
+ if !exists('a:non_exists_arg')
+ echo "OK"
+ else
+ echo "FAILED"
+ endif
+
+ echo 'a:1: 1'
+ if exists('a:1')
+ echo "OK"
+ else
+ echo "FAILED"
+ endif
+
+ echo 'a:2: 0'
+ if !exists('a:2')
+ echo "OK"
+ else
+ echo "FAILED"
+ endif
+ endfunction
+
+ call TestFuncArg("arg1", "arg2")
+
+ echo ' g:footest#x =' g:footest#x
+ echo ' footest#F()' footest#F()
+ echo 'UndefFun()' UndefFun()
+
+ redir END
+endfunction
+:call TestExists()
+:delfunc TestExists
+:delfunc RunTest
+:delfunc TestFuncArg
+:edit! test.out
+:set ff=unix
+:w
+:qa!
+:while getchar(1) | call getchar() | endwhile
+ENDTEST
+
diff --git a/src/testdir/test60.ok b/src/testdir/test60.ok
new file mode 100644
index 0000000000..0c382ad281
--- /dev/null
+++ b/src/testdir/test60.ok
@@ -0,0 +1,206 @@
+
+#myagroup: 1
+OK
+#myagroup+b: 0
+OK
+#myagroup#BufEnter: 1
+OK
+#myagroup#BufEnter#*.my: 1
+OK
+#BufEnter: 1
+OK
+#BufEnter#*.my: 1
+OK
+#xyzagroup: 0
+OK
+#xyzagroup#BufEnter: 0
+OK
+#myagroup#CmdwinEnter: 0
+OK
+#myagroup#xyzacmd: 0
+OK
+#myagroup#BufEnter#xyzpat: 0
+OK
+#BufEnter#xyzpat: 0
+OK
+###: 0
+OK
+##: 0
+OK
+##FileReadCmd: 1
+OK
+##MySpecialCmd: 0
+OK
+&textwidth: 1
+OK
+&tw: 1
+OK
+&tw-: 0
+OK
+&g:errorformat: 1
+OK
+&l:errorformat: 1
+OK
+&nojoinspaces: 0
+OK
+&nojs: 0
+OK
+&myxyzoption: 0
+OK
++incsearch: 1
+OK
++incsearch!1: 0
+OK
++is: 1
+OK
++autoprint: 0
+OK
+$EDITOR_NAME: 1
+OK
+$NON_ENV_VAR: 0
+OK
+*bufnr: 1
+OK
+*bufnr(): 1
+OK
+*myxyzfunc: 0
+OK
+*bufnr&6: 0
+OK
+*TestExists: 1
+OK
+*MyxyzFunc: 0
+OK
+*UndefFun: 0
+OK
+*footest#F: 0
+OK
+:edit: 2
+OK
+:edit/a: 0
+OK
+:q: 1
+OK
+:invalidcmd: 0
+OK
+:MyCmd: 2
+OK
+:My: 3
+OK
+:rightbelow: 2
+OK
+:MyCmd: 0
+OK
+:My: 0
+OK
+local_var: 1
+OK
+local_var%n: 0
+OK
+local_var: 0
+OK
+footest#x: 0
+OK
+local_list: 1
+OK
+local_list[1]: 1
+OK
+local_list[1]+5: 0
+OK
+local_list[2]: 0
+OK
+local_list: 0
+OK
+local_dict: 1
+OK
+local_dict: 0
+OK
+curly_local_var: 1
+OK
+curly_local_var: 0
+OK
+g:global_var: 1
+OK
+g:global_var-n: 1
+OK
+g:global_var: 0
+OK
+g:global_list: 1
+OK
+g:global_list: 0
+OK
+g:global_dict: 1
+OK
+g:global_dict: 0
+OK
+g:curly_global_var: 1
+OK
+g:curly_global_var: 0
+OK
+w:window_var: 1
+OK
+w:window_var: 0
+OK
+w:window_list: 1
+OK
+w:window_list: 0
+OK
+w:window_dict: 1
+OK
+w:window_dict: 0
+OK
+w:curly_window_var: 1
+OK
+w:curly_window_var: 0
+OK
+b:buffer_var: 1
+OK
+b:buffer_var: 0
+OK
+b:buffer_list: 1
+OK
+b:buffer_list: 0
+OK
+b:buffer_dict: 1
+OK
+b:buffer_dict: 0
+OK
+b:curly_buffer_var: 1
+OK
+b:curly_buffer_var: 0
+OK
+s:script_var: 1
+OK
+s:script_var: 0
+OK
+s:script_list: 1
+OK
+s:script_list: 0
+OK
+s:script_dict: 1
+OK
+s:script_dict: 0
+OK
+s:curly_script_var: 1
+OK
+s:curly_script_var: 0
+OK
+*s:my_script_func: 1
+OK
+*s:my_script_func: 0
+OK
+v:version: 1
+OK
+v:non_exists_var: 0
+OK
+a:func_arg: 1
+OK
+a:non_exists_arg: 0
+OK
+a:1: 1
+OK
+a:2: 0
+OK
+ g:footest#x = 1
+ footest#F() 0
+UndefFun() 0
diff --git a/src/testdir/test60.vim b/src/testdir/test60.vim
new file mode 100644
index 0000000000..f1157f73f9
--- /dev/null
+++ b/src/testdir/test60.vim
@@ -0,0 +1,98 @@
+" Vim script for exists() function test
+" Script-local variables are checked here
+
+" Existing script-local variable
+let s:script_var = 1
+echo 's:script_var: 1'
+if exists('s:script_var')
+ echo "OK"
+else
+ echo "FAILED"
+endif
+
+" Non-existing script-local variable
+unlet s:script_var
+echo 's:script_var: 0'
+if !exists('s:script_var')
+ echo "OK"
+else
+ echo "FAILED"
+endif
+
+" Existing script-local list
+let s:script_list = ["blue", "orange"]
+echo 's:script_list: 1'
+if exists('s:script_list')
+ echo "OK"
+else
+ echo "FAILED"
+endif
+
+" Non-existing script-local list
+unlet s:script_list
+echo 's:script_list: 0'
+if !exists('s:script_list')
+ echo "OK"
+else
+ echo "FAILED"
+endif
+
+" Existing script-local dictionary
+let s:script_dict = {"xcord":100, "ycord":2}
+echo 's:script_dict: 1'
+if exists('s:script_dict')
+ echo "OK"
+else
+ echo "FAILED"
+endif
+
+" Non-existing script-local dictionary
+unlet s:script_dict
+echo 's:script_dict: 0'
+if !exists('s:script_dict')
+ echo "OK"
+else
+ echo "FAILED"
+endif
+
+" Existing script curly-brace variable
+let str = "script"
+let s:curly_{str}_var = 1
+echo 's:curly_' . str . '_var: 1'
+if exists('s:curly_{str}_var')
+ echo "OK"
+else
+ echo "FAILED"
+endif
+
+" Non-existing script-local curly-brace variable
+unlet s:curly_{str}_var
+echo 's:curly_' . str . '_var: 0'
+if !exists('s:curly_{str}_var')
+ echo "OK"
+else
+ echo "FAILED"
+endif
+
+" Existing script-local function
+function! s:my_script_func()
+endfunction
+
+echo '*s:my_script_func: 1'
+if exists('*s:my_script_func')
+ echo "OK"
+else
+ echo "FAILED"
+endif
+
+" Non-existing script-local function
+delfunction s:my_script_func
+
+echo '*s:my_script_func: 0'
+if !exists('*s:my_script_func')
+ echo "OK"
+else
+ echo "FAILED"
+endif
+unlet str
+
diff --git a/src/testdir/test61.in b/src/testdir/test61.in
new file mode 100644
index 0000000000..dc24ab9804
--- /dev/null
+++ b/src/testdir/test61.in
@@ -0,0 +1,113 @@
+Tests for 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.
+
+STARTTEST
+:echo undotree().entries
+ENDTEST
+
+STARTTEST
+:" Delete three characters and undo
+Gx:set ul=100
+x:set ul=100
+x:.w! test.out
+g-:.w >>test.out
+g-:.w >>test.out
+g-:.w >>test.out
+g-:.w >>test.out
+:"
+:/^111/w >>test.out
+:" Delete three other characters and go back in time step by step
+$x:set ul=100
+x:set ul=100
+x:.w >>test.out
+:sleep 1
+g-:.w >>test.out
+g-:.w >>test.out
+g-:.w >>test.out
+g-:.w >>test.out
+g-:.w >>test.out
+g-:.w >>test.out
+g-:.w >>test.out
+g-:.w >>test.out
+10g+:.w >>test.out
+:"
+:/^222/w >>test.out
+:" Delay for three seconds and go some seconds forward and backward
+:sleep 2
+Aa:set ul=100
+Ab:set ul=100
+Ac:set ul=100
+:.w >>test.out
+:ear 1s
+:.w >>test.out
+:ear 3s
+:.w >>test.out
+:later 1s
+:.w >>test.out
+:later 1h
+:.w >>test.out
+:"
+:" test undojoin
+Goaaaa:set ul=100
+obbbbu:.w >>test.out
+obbbb:set ul=100
+:undojoin
+occccu:.w >>test.out
+:e! Xtest
+ione one one:set ul=100
+:w!
+otwo:set ul=100
+otwo:set ul=100
+:w
+othree:earlier 1f
+:" expect "one one one\ntwo\ntwo"
+:%yank a
+:earlier 1f
+:" expect "one one one"
+:%yank b
+:earlier 1f
+:" expect empty line
+:%yank c
+:later 1f
+:" expect "one one one"
+:%yank d
+:later 1f
+:" expect "one one one\ntwo\ntwo"
+:%yank e
+:later 1f
+:" expect "one one one\ntwo\ntwo\nthree"
+ggO---:0put e
+ggO---:0put d
+ggO---:0put c
+ggO---:0put b
+ggO---:0put a
+ggO---:w >>test.out
+:so small.vim
+:set nocp viminfo+=nviminfo
+:enew!
+oa
+:set ul=100
+ob
+:set ul=100
+o1a2=setline('.','1234')
+
+uu:"
+oc
+:set ul=100
+o1a2=setline('.','1234')
+
+u:"
+od
+:set ul=100
+o1a2=string(123)
+u:"
+:%w >>test.out
+:qa!
+ENDTEST
+
+1111 -----
+2222 -----
+
+123456789
diff --git a/src/testdir/test61.ok b/src/testdir/test61.ok
new file mode 100644
index 0000000000..ea4b473ad7
--- /dev/null
+++ b/src/testdir/test61.ok
@@ -0,0 +1,49 @@
+456789
+3456789
+23456789
+123456789
+123456789
+1111 -----
+123456
+1234567
+12345678
+456789
+3456789
+23456789
+123456789
+123456789
+123456789
+123456
+2222 -----
+123456abc
+123456
+123456789
+123456
+123456abc
+aaaa
+aaaa
+---
+one one one
+two
+two
+---
+one one one
+---
+
+---
+one one one
+---
+one one one
+two
+two
+---
+one one one
+two
+two
+three
+
+a
+b
+c
+12
+d
diff --git a/src/testdir/test62.in b/src/testdir/test62.in
new file mode 100644
index 0000000000..03415d1322
--- /dev/null
+++ b/src/testdir/test62.in
@@ -0,0 +1,190 @@
+Tests for tab pages
+
+STARTTEST
+:so small.vim
+:" Simple test for opening and closing a tab page
+:tabnew
+:let nr = tabpagenr()
+:q
+:call append(line('$'), 'tab page ' . nr)
+:unlet nr
+:"
+:" Open three tab pages and use ":tabdo"
+:0tabnew
+:1tabnew
+:888tabnew
+:tabdo call append(line('$'), 'this is tab page ' . 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
+:"
+:" 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'])
+:"
+:let test_status = 'gettabvar: fail'
+:if gettabvar(2, 'val_num') == 100 && gettabvar(2, 'val_str') == 'SetTabVar test' && gettabvar(2, 'val_list') == ['red', 'blue', 'green']
+: let test_status = 'gettabvar: pass'
+:endif
+:call append(line('$'), test_status)
+:"
+:tabnext 2
+:let test_status = 'settabvar: fail'
+:if t:val_num == 100 && t:val_str == 'SetTabVar test' && t:val_list == ['red', 'blue', 'green']
+: let test_status = 'settabvar: pass'
+:endif
+:tabclose
+:call append(line('$'), test_status)
+:"
+:if has('gui') || has('clientserver')
+:" Test for ":tab drop exist-file" to keep current window.
+:sp test1
+:tab drop test1
+:let test_status = 'tab drop 1: fail'
+:if tabpagenr('$') == 1 && winnr('$') == 2 && winnr() == 1
+: let test_status = 'tab drop 1: pass'
+:endif
+:close
+:call append(line('$'), test_status)
+:"
+:"
+:" Test for ":tab drop new-file" to keep current window of tabpage 1.
+:split
+:tab drop newfile
+:let test_status = 'tab drop 2: fail'
+:if tabpagenr('$') == 2 && tabpagewinnr(1, '$') == 2 && tabpagewinnr(1) == 1
+: let test_status = 'tab drop 2: pass'
+:endif
+:tabclose
+:q
+:call append(line('$'), test_status)
+:"
+:"
+:" Test for ":tab drop multi-opend-file" to keep current tabpage and window.
+:new test1
+:tabnew
+:new test1
+:tab drop test1
+:let test_status = 'tab drop 3: fail'
+:if tabpagenr() == 2 && tabpagewinnr(2, '$') == 2 && tabpagewinnr(2) == 1
+: let test_status = 'tab drop 3: pass'
+:endif
+:tabclose
+:q
+:call append(line('$'), test_status)
+:else
+:" :drop not supported
+:call append(line('$'), 'tab drop 1: pass')
+:call append(line('$'), 'tab drop 2: pass')
+:call append(line('$'), 'tab drop 3: pass')
+:endif
+:"
+:"
+:for i in range(9) | tabnew | endfor
+1gt
+Go=tabpagenr() 
+:tabmove 5
+i=tabpagenr() 
+:tabmove -2
+i=tabpagenr() 
+:tabmove +4
+i=tabpagenr() 
+:tabmove
+i=tabpagenr() 
+:tabmove -20
+i=tabpagenr() 
+:tabmove +20
+i=tabpagenr() 
+:3tabmove
+i=tabpagenr() 
+:7tabmove 5
+i=tabpagenr() 
+:let a='No error caught.'
+:try
+:tabmove foo
+:catch E474
+:let a='E474 caught.'
+:endtry
+i=a 
+:"
+:" Test autocommands
+:tabonly!
+:let g:r=[]
+:command -nargs=1 -bar C :call add(g:r, '=== ' . <q-args> . ' ===')|<args>
+:function Test()
+ let hasau=has('autocmd')
+ if hasau
+ autocmd TabEnter * :call add(g:r, 'TabEnter')
+ autocmd WinEnter * :call add(g:r, 'WinEnter')
+ autocmd BufEnter * :call add(g:r, 'BufEnter')
+ autocmd TabLeave * :call add(g:r, 'TabLeave')
+ autocmd WinLeave * :call add(g:r, 'WinLeave')
+ autocmd BufLeave * :call add(g:r, 'BufLeave')
+ endif
+ let t:a='a'
+ C tab split
+ if !hasau
+ let g:r+=['WinLeave', 'TabLeave', 'WinEnter', 'TabEnter']
+ endif
+ let t:a='b'
+ C tabnew
+ if !hasau
+ let g:r+=['WinLeave', 'TabLeave', 'WinEnter', 'TabEnter', 'BufLeave', 'BufEnter']
+ endif
+ let t:a='c'
+ call add(g:r, join(map(range(1, tabpagenr('$')), 'gettabvar(v:val, "a")')))
+ C call map(range(1, tabpagenr('$')), 'settabvar(v:val, ''a'', v:val*2)')
+ call add(g:r, join(map(range(1, tabpagenr('$')), 'gettabvar(v:val, "a")')))
+ let w:a='a'
+ C vsplit
+ if !hasau
+ let g:r+=['WinLeave', 'WinEnter']
+ endif
+ let w:a='a'
+ let tabn=tabpagenr()
+ let winr=range(1, winnr('$'))
+ C tabnext 1
+ if !hasau
+ let g:r+=['BufLeave', 'WinLeave', 'TabLeave', 'WinEnter', 'TabEnter', 'BufEnter']
+ endif
+ call add(g:r, join(map(copy(winr), 'gettabwinvar('.tabn.', v:val, "a")')))
+ C call map(copy(winr), 'settabwinvar('.tabn.', v:val, ''a'', v:val*2)')
+ call add(g:r, join(map(copy(winr), 'gettabwinvar('.tabn.', v:val, "a")')))
+ if hasau
+ augroup TabDestructive
+ autocmd TabEnter * :C tabnext 2 | C tabclose 3
+ augroup END
+ C tabnext 3
+ let g:r+=[tabpagenr().'/'.tabpagenr('$')]
+ autocmd! TabDestructive TabEnter
+ C tabnew
+ C tabnext 1
+ autocmd TabDestructive TabEnter * nested :C tabnext 2 | C tabclose 3
+ C tabnext 3
+ let g:r+=[tabpagenr().'/'.tabpagenr('$')]
+ else
+ let g:r+=["=== tabnext 3 ===","BufLeave","WinLeave","TabLeave","WinEnter","TabEnter","=== tabnext 2 ===","=== tabclose 3 ===","2/2","=== tabnew ===","WinLeave","TabLeave","WinEnter","TabEnter","BufLeave","BufEnter","=== tabnext 1 ===","BufLeave","WinLeave","TabLeave","WinEnter","TabEnter","BufEnter","=== tabnext 3 ===","BufLeave","WinLeave","TabLeave","WinEnter","TabEnter","=== tabnext 2 ===","BufLeave","WinLeave","TabLeave","WinEnter","TabEnter","=== tabnext 2 ===","=== tabclose 3 ===","BufEnter","=== tabclose 3 ===","2/2",]
+ endif
+endfunction
+:call Test()
+:$ put =g:r
+:"
+:"
+:/^Results/,$w! test.out
+:qa!
+ENDTEST
+
+Results:
diff --git a/src/testdir/test62.ok b/src/testdir/test62.ok
new file mode 100644
index 0000000000..e35b2b1c67
--- /dev/null
+++ b/src/testdir/test62.ok
@@ -0,0 +1,88 @@
+Results:
+tab page 2
+this is tab page 3
+this is tab page 1
+this is tab page 4
+gettabvar: pass
+settabvar: pass
+tab drop 1: pass
+tab drop 2: pass
+tab drop 3: pass
+1
+6
+4
+8
+10
+1
+10
+4
+6
+E474 caught.
+=== tab split ===
+WinLeave
+TabLeave
+WinEnter
+TabEnter
+=== tabnew ===
+WinLeave
+TabLeave
+WinEnter
+TabEnter
+BufLeave
+BufEnter
+a b c
+=== call map(range(1, tabpagenr('$')), 'settabvar(v:val, ''a'', v:val*2)') ===
+2 4 6
+=== vsplit ===
+WinLeave
+WinEnter
+=== tabnext 1 ===
+BufLeave
+WinLeave
+TabLeave
+WinEnter
+TabEnter
+BufEnter
+a a
+=== call map(copy(winr), 'settabwinvar('.tabn.', v:val, ''a'', v:val*2)') ===
+2 4
+=== tabnext 3 ===
+BufLeave
+WinLeave
+TabLeave
+WinEnter
+TabEnter
+=== tabnext 2 ===
+=== tabclose 3 ===
+2/2
+=== tabnew ===
+WinLeave
+TabLeave
+WinEnter
+TabEnter
+BufLeave
+BufEnter
+=== tabnext 1 ===
+BufLeave
+WinLeave
+TabLeave
+WinEnter
+TabEnter
+BufEnter
+=== tabnext 3 ===
+BufLeave
+WinLeave
+TabLeave
+WinEnter
+TabEnter
+=== tabnext 2 ===
+BufLeave
+WinLeave
+TabLeave
+WinEnter
+TabEnter
+=== tabnext 2 ===
+=== tabclose 3 ===
+BufEnter
+=== tabclose 3 ===
+2/2
diff --git a/src/testdir/test63.in b/src/testdir/test63.in
new file mode 100644
index 0000000000..74339c3e35
--- /dev/null
+++ b/src/testdir/test63.in
@@ -0,0 +1,157 @@
+Test for ":match", ":2match", ":3match", "clearmatches()", "getmatches()",
+"matchadd()", "matcharg()", "matchdelete()", and "setmatches()".
+
+STARTTEST
+:so small.vim
+:" --- Check that "matcharg()" returns the correct group and pattern if a match
+:" --- is defined.
+:let @r = "*** Test 1: "
+:highlight MyGroup1 ctermbg=red
+:highlight MyGroup2 ctermbg=green
+:highlight MyGroup3 ctermbg=blue
+:match MyGroup1 /TODO/
+:2match MyGroup2 /FIXME/
+:3match MyGroup3 /XXX/
+:if matcharg(1) == ['MyGroup1', 'TODO'] && matcharg(2) == ['MyGroup2', 'FIXME'] && matcharg(3) == ['MyGroup3', 'XXX']
+: let @r .= "OK\n"
+:else
+: let @r .= "FAILED\n"
+:endif
+:" --- Check that "matcharg()" returns an empty list if the argument is not 1,
+:" --- 2 or 3 (only 0 and 4 are tested).
+:let @r .= "*** Test 2: "
+:if matcharg(0) == [] && matcharg(4) == []
+: let @r .= "OK\n"
+:else
+: let @r .= "FAILED\n"
+:endif
+:" --- Check that "matcharg()" returns ['', ''] if a match is not defined.
+:let @r .= "*** Test 3: "
+:match
+:2match
+:3match
+:if matcharg(1) == ['', ''] && matcharg(2) == ['', ''] && matcharg(3) == ['', '']
+: let @r .= "OK\n"
+:else
+: let @r .= "FAILED\n"
+:endif
+:" --- Check that "matchadd()" and "getmatches()" agree on added matches and
+:" --- that default values apply.
+:let @r .= "*** Test 4: "
+:let m1 = matchadd("MyGroup1", "TODO")
+:let m2 = matchadd("MyGroup2", "FIXME", 42)
+:let m3 = matchadd("MyGroup3", "XXX", 60, 17)
+:if getmatches() == [{'group': 'MyGroup1', 'pattern': 'TODO', 'priority': 10, 'id': 4}, {'group': 'MyGroup2', 'pattern': 'FIXME', 'priority': 42, 'id': 5}, {'group': 'MyGroup3', 'pattern': 'XXX', 'priority': 60, 'id': 17}]
+: let @r .= "OK\n"
+:else
+: let @r .= "FAILED\n"
+:endif
+:" --- Check that "matchdelete()" deletes the matches defined in the previous
+:" --- test correctly.
+:let @r .= "*** Test 5: "
+:call matchdelete(m1)
+:call matchdelete(m2)
+:call matchdelete(m3)
+:unlet m1
+:unlet m2
+:unlet m3
+:if getmatches() == []
+: let @r .= "OK\n"
+:else
+: let @r .= "FAILED\n"
+:endif
+:" --- Check that "matchdelete()" returns 0 if successful and otherwise -1.
+:let @r .= "*** Test 6: "
+:let m = matchadd("MyGroup1", "TODO")
+:let r1 = matchdelete(m)
+:let r2 = matchdelete(42)
+:if r1 == 0 && r2 == -1
+: let @r .= "OK\n"
+:else
+: let @r .= "FAILED\n"
+:endif
+:unlet m
+:unlet r1
+:unlet r2
+:" --- Check that "clearmatches()" clears all matches defined by ":match" and
+:" --- "matchadd()".
+:let @r .= "*** Test 7: "
+: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()
+:if getmatches() == []
+: let @r .= "OK\n"
+:else
+: let @r .= "FAILED\n"
+:endif
+:unlet m1
+:unlet m2
+:unlet m3
+:" --- 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 @r .= "*** Test 8: "
+: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)
+:if getmatches() == ml
+: let @r .= "OK\n"
+:else
+: let @r .= "FAILED\n"
+:endif
+:call clearmatches()
+:unlet m1
+:unlet m2
+:unlet m3
+:unlet ml
+:" --- 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 @r .= "*** Test 9: "
+:let r1 = setmatches([{'group': 'MyGroup1', 'pattern': 'TODO', 'priority': 10, 'id': 1}, {'group': 'MyGroup2', 'pattern': 'FIXME', 'priority': 10, 'id': 1}])
+:if getmatches() == [{'group': 'MyGroup1', 'pattern': 'TODO', 'priority': 10, 'id': 1}] && r1 == 0
+: let @r .= "OK\n"
+:else
+: let @r .= "FAILED\n"
+:endif
+:call clearmatches()
+:unlet r1
+:" --- 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.)
+:let @r .= "*** Test 10: "
+:let rs1 = setmatches([])
+:let rs2 = setmatches([{'group': 'MyGroup1', 'pattern': 'TODO', 'priority': 10, 'id': 1}])
+:call clearmatches()
+:let rf1 = setmatches(0)
+:let rf2 = setmatches([0])
+:let rf3 = setmatches([{'wrong key': 'wrong value'}])
+:if rs1 == 0 && rs2 == 0 && rf1 == -1 && rf2 == -1 && rf3 == -1
+: let @r .= "OK\n"
+:else
+: let @r .= "FAILED\n"
+:endif
+:unlet rs1
+:unlet rs2
+:unlet rf1
+:unlet rf2
+:unlet rf3
+:highlight clear MyGroup1
+:highlight clear MyGroup2
+:highlight clear MyGroup3
+G"rp
+:/^Results/,$wq! test.out
+ENDTEST
+
+Results of test63:
diff --git a/src/testdir/test63.ok b/src/testdir/test63.ok
new file mode 100644
index 0000000000..14973985eb
--- /dev/null
+++ b/src/testdir/test63.ok
@@ -0,0 +1,11 @@
+Results of test63:
+*** Test 1: OK
+*** Test 2: OK
+*** Test 3: OK
+*** Test 4: OK
+*** Test 5: OK
+*** Test 6: OK
+*** Test 7: OK
+*** Test 8: OK
+*** Test 9: OK
+*** Test 10: OK
diff --git a/src/testdir/test64.in b/src/testdir/test64.in
new file mode 100644
index 0000000000..29bf0b902b
--- /dev/null
+++ b/src/testdir/test64.in
@@ -0,0 +1,633 @@
+Test for regexp patterns without multi-byte support.
+See test95 for multi-byte tests.
+
+A pattern that gives the expected result produces OK, so that we know it was
+actually tried.
+
+STARTTEST
+:so small.vim
+:" tl is a List of Lists with:
+:" regexp pattern
+:" text to test the pattern on
+:" expected match (optional)
+:" expected submatch 1 (optional)
+:" expected submatch 2 (optional)
+:" etc.
+:" When there is no match use only the first two items.
+:let tl = []
+:"
+:""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+:"""" Previously written tests """"""""""""""""""""""""""""""""
+:""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+:"
+:call add(tl, [2, 'ab', 'aab', 'ab'])
+:call add(tl, [2, 'b', 'abcdef', 'b'])
+:call add(tl, [2, 'bc*', 'abccccdef', 'bcccc'])
+:call add(tl, [2, 'bc\{-}', 'abccccdef', 'b'])
+:call add(tl, [2, 'bc\{-}\(d\)', 'abccccdef', 'bccccd', 'd'])
+:call add(tl, [2, 'bc*', 'abbdef', 'b'])
+:call add(tl, [2, 'c*', 'ccc', 'ccc'])
+:call add(tl, [2, 'bc*', 'abdef', 'b'])
+:call add(tl, [2, 'c*', 'abdef', ''])
+:call add(tl, [2, 'bc\+', 'abccccdef', 'bcccc'])
+:call add(tl, [2, 'bc\+', 'abdef']) "no match
+:"
+:"operator \|
+:call add(tl, [2, 'a\|ab', 'cabd', 'a']) "alternation is ordered
+:"
+:call add(tl, [2, 'c\?', 'ccb', 'c'])
+:call add(tl, [2, 'bc\?', 'abd', 'b'])
+:call add(tl, [2, 'bc\?', 'abccd', 'bc'])
+:"
+:call add(tl, [2, '\va{1}', 'ab', 'a'])
+:"
+:call add(tl, [2, '\va{2}', 'aa', 'aa'])
+:call add(tl, [2, '\va{2}', 'caad', 'aa'])
+:call add(tl, [2, '\va{2}', 'aba'])
+:call add(tl, [2, '\va{2}', 'ab'])
+:call add(tl, [2, '\va{2}', 'abaa', 'aa'])
+:call add(tl, [2, '\va{2}', 'aaa', 'aa'])
+:"
+:call add(tl, [2, '\vb{1}', 'abca', 'b'])
+:call add(tl, [2, '\vba{2}', 'abaa', 'baa'])
+:call add(tl, [2, '\vba{3}', 'aabaac'])
+:"
+:call add(tl, [2, '\v(ab){1}', 'ab', 'ab', 'ab'])
+:call add(tl, [2, '\v(ab){1}', 'dabc', 'ab', 'ab'])
+:call add(tl, [2, '\v(ab){1}', 'acb'])
+:"
+:call add(tl, [2, '\v(ab){0,2}', 'acb', "", ""])
+:call add(tl, [2, '\v(ab){0,2}', 'ab', 'ab', 'ab'])
+:call add(tl, [2, '\v(ab){1,2}', 'ab', 'ab', 'ab'])
+:call add(tl, [2, '\v(ab){1,2}', 'ababc', 'abab', 'ab'])
+:call add(tl, [2, '\v(ab){2,4}', 'ababcab', 'abab', 'ab'])
+:call add(tl, [2, '\v(ab){2,4}', 'abcababa', 'abab', 'ab'])
+:"
+:call add(tl, [2, '\v(ab){2}', 'abab', 'abab', 'ab'])
+:call add(tl, [2, '\v(ab){2}', 'cdababe', 'abab', 'ab'])
+:call add(tl, [2, '\v(ab){2}', 'abac'])
+:call add(tl, [2, '\v(ab){2}', 'abacabab', 'abab', 'ab'])
+:call add(tl, [2, '\v((ab){2}){2}', 'abababab', 'abababab', 'abab', 'ab'])
+:call add(tl, [2, '\v((ab){2}){2}', 'abacabababab', 'abababab', 'abab', 'ab'])
+:"
+:call add(tl, [2, '\v(a{1}){1}', 'a', 'a', 'a'])
+:call add(tl, [2, '\v(a{2}){1}', 'aa', 'aa', 'aa'])
+:call add(tl, [2, '\v(a{2}){1}', 'aaac', 'aa', 'aa'])
+:call add(tl, [2, '\v(a{2}){1}', 'daaac', 'aa', 'aa'])
+:call add(tl, [2, '\v(a{1}){2}', 'daaac', 'aa', 'a'])
+:call add(tl, [2, '\v(a{1}){2}', 'aaa', 'aa', 'a'])
+:call add(tl, [2, '\v(a{2})+', 'adaac', 'aa', 'aa'])
+:call add(tl, [2, '\v(a{2})+', 'aa', 'aa', 'aa'])
+:call add(tl, [2, '\v(a{2}){1}', 'aa', 'aa', 'aa'])
+:call add(tl, [2, '\v(a{1}){2}', 'aa', 'aa', 'a'])
+:call add(tl, [2, '\v(a{1}){1}', 'a', 'a', 'a'])
+:call add(tl, [2, '\v(a{2}){2}', 'aaaa', 'aaaa', 'aa'])
+:call add(tl, [2, '\v(a{2}){2}', 'aaabaaaa', 'aaaa', 'aa'])
+:"
+:call add(tl, [2, '\v(a+){2}', 'dadaac', 'aa', 'a'])
+:call add(tl, [2, '\v(a{3}){2}', 'aaaaaaa', 'aaaaaa', 'aaa'])
+:"
+:call add(tl, [2, '\v(a{1,2}){2}', 'daaac', 'aaa', 'a'])
+:call add(tl, [2, '\v(a{1,3}){2}', 'daaaac', 'aaaa', 'a'])
+:call add(tl, [2, '\v(a{1,3}){2}', 'daaaaac', 'aaaaa', 'aa'])
+:call add(tl, [2, '\v(a{1,3}){3}', 'daac'])
+:call add(tl, [2, '\v(a{1,2}){2}', 'dac'])
+:call add(tl, [2, '\v(a+)+', 'daac', 'aa', 'aa'])
+:call add(tl, [2, '\v(a+)+', 'aaa', 'aaa', 'aaa'])
+:call add(tl, [2, '\v(a+){1,2}', 'aaa', 'aaa', 'aaa'])
+:call add(tl, [2, '\v(a+)(a+)', 'aaa', 'aaa', 'aa', 'a'])
+:call add(tl, [2, '\v(a{3})+', 'daaaac', 'aaa', 'aaa'])
+:call add(tl, [2, '\v(a|b|c)+', 'aacb', 'aacb', 'b'])
+:call add(tl, [2, '\v(a|b|c){2}', 'abcb', 'ab', 'b'])
+:call add(tl, [2, '\v(abc){2}', 'abcabd', ])
+:call add(tl, [2, '\v(abc){2}', 'abdabcabc','abcabc', 'abc'])
+:"
+:call add(tl, [2, 'a*', 'cc', ''])
+:call add(tl, [2, '\v(a*)+', 'cc', ''])
+:call add(tl, [2, '\v((ab)+)+', 'ab', 'ab', 'ab', 'ab'])
+:call add(tl, [2, '\v(((ab)+)+)+', 'ab', 'ab', 'ab', 'ab', 'ab'])
+:call add(tl, [2, '\v(((ab)+)+)+', 'dababc', 'abab', 'abab', 'abab', 'ab'])
+:call add(tl, [2, '\v(a{0,2})+', 'cc', ''])
+:call add(tl, [2, '\v(a*)+', '', ''])
+:call add(tl, [2, '\v((a*)+)+', '', ''])
+:call add(tl, [2, '\v((ab)*)+', '', ''])
+:call add(tl, [2, '\va{1,3}', 'aab', 'aa'])
+:call add(tl, [2, '\va{2,3}', 'abaa', 'aa'])
+:"
+:call add(tl, [2, '\v((ab)+|c*)+', 'abcccaba', 'abcccab', '', 'ab'])
+:call add(tl, [2, '\v(a{2})|(b{3})', 'bbabbbb', 'bbb', '', 'bbb'])
+:call add(tl, [2, '\va{2}|b{2}', 'abab'])
+:call add(tl, [2, '\v(a)+|(c)+', 'bbacbaacbbb', 'a', 'a'])
+:call add(tl, [2, '\vab{2,3}c', 'aabbccccccccccccc', 'abbc'])
+:call add(tl, [2, '\vab{2,3}c', 'aabbbccccccccccccc', 'abbbc'])
+:call add(tl, [2, '\vab{2,3}cd{2,3}e', 'aabbbcddee', 'abbbcdde'])
+:call add(tl, [2, '\va(bc){2}d', 'aabcbfbc' ])
+:call add(tl, [2, '\va*a{2}', 'a', ])
+:call add(tl, [2, '\va*a{2}', 'aa', 'aa' ])
+:call add(tl, [2, '\va*a{2}', 'aaa', 'aaa' ])
+:call add(tl, [2, '\va*a{2}', 'bbbabcc', ])
+:call add(tl, [2, '\va*b*|a*c*', 'a', 'a'])
+:call add(tl, [2, '\va{1}b{1}|a{1}b{1}', ''])
+:"
+:"submatches
+:call add(tl, [2, '\v(a)', 'ab', 'a', 'a'])
+:call add(tl, [2, '\v(a)(b)', 'ab', 'ab', 'a', 'b'])
+:call add(tl, [2, '\v(ab)(b)(c)', 'abbc', 'abbc', 'ab', 'b', 'c'])
+:call add(tl, [2, '\v((a)(b))', 'ab', 'ab', 'ab', 'a', 'b'])
+:call add(tl, [2, '\v(a)|(b)', 'ab', 'a', 'a'])
+:"
+:call add(tl, [2, '\v(a*)+', 'aaaa', 'aaaa', ''])
+:call add(tl, [2, 'x', 'abcdef'])
+:"
+:""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+:""""" Simple tests """""""""""""""""""""""""""""""""""""""""""
+:""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+:"
+:" Search single groups
+:call add(tl, [2, 'ab', 'aab', 'ab'])
+:call add(tl, [2, 'ab', 'baced'])
+:call add(tl, [2, 'ab', ' ab ', 'ab'])
+:"
+:" Search multi-modifiers
+:call add(tl, [2, 'x*', 'xcd', 'x'])
+:call add(tl, [2, 'x*', 'xxxxxxxxxxxxxxxxsofijiojgf', 'xxxxxxxxxxxxxxxx'])
+:" empty match is good
+:call add(tl, [2, 'x*', 'abcdoij', ''])
+:" no match here
+:call add(tl, [2, 'x\+', 'abcdoin'])
+:call add(tl, [2, 'x\+', 'abcdeoijdfxxiuhfij', 'xx'])
+:call add(tl, [2, 'x\+', 'xxxxx', 'xxxxx'])
+:call add(tl, [2, 'x\+', 'abc x siufhiush xxxxxxxxx', 'x'])
+:call add(tl, [2, 'x\=', 'x sdfoij', 'x'])
+:call add(tl, [2, 'x\=', 'abc sfoij', '']) " empty match is good
+:call add(tl, [2, 'x\=', 'xxxxxxxxx c', 'x'])
+:call add(tl, [2, 'x\?', 'x sdfoij', 'x'])
+:" empty match is good
+:call add(tl, [2, 'x\?', 'abc sfoij', ''])
+:call add(tl, [2, 'x\?', 'xxxxxxxxxx c', 'x'])
+:"
+:call add(tl, [2, 'a\{0,0}', 'abcdfdoij', ''])
+:" same thing as 'a?'
+:call add(tl, [2, 'a\{0,1}', 'asiubid axxxaaa', 'a'])
+:" same thing as 'a\{0,1}'
+:call add(tl, [2, 'a\{1,0}', 'asiubid axxxaaa', 'a'])
+:call add(tl, [2, 'a\{3,6}', 'aa siofuh'])
+:call add(tl, [2, 'a\{3,6}', 'aaaaa asfoij afaa', 'aaaaa'])
+:call add(tl, [2, 'a\{3,6}', 'aaaaaaaa', 'aaaaaa'])
+:call add(tl, [2, 'a\{0}', 'asoiuj', ''])
+:call add(tl, [2, 'a\{2}', 'aaaa', 'aa'])
+:call add(tl, [2, 'a\{2}', 'iuash fiusahfliusah fiushfilushfi uhsaifuh askfj nasfvius afg aaaa sfiuhuhiushf', 'aa'])
+:call add(tl, [2, 'a\{2}', 'abcdefghijklmnopqrestuvwxyz1234567890'])
+:" same thing as 'a*'
+:call add(tl, [2, 'a\{0,}', 'oij sdigfusnf', ''])
+:call add(tl, [2, 'a\{0,}', 'aaaaa aa', 'aaaaa'])
+:call add(tl, [2, 'a\{2,}', 'sdfiougjdsafg'])
+:call add(tl, [2, 'a\{2,}', 'aaaaasfoij ', 'aaaaa'])
+:call add(tl, [2, 'a\{5,}', 'xxaaaaxxx '])
+:call add(tl, [2, 'a\{5,}', 'xxaaaaaxxx ', 'aaaaa'])
+:call add(tl, [2, 'a\{,0}', 'oidfguih iuhi hiu aaaa', ''])
+:call add(tl, [2, 'a\{,5}', 'abcd', 'a'])
+:call add(tl, [2, 'a\{,5}', 'aaaaaaaaaa', 'aaaaa'])
+:" leading star as normal char when \{} follows
+:call add(tl, [2, '^*\{4,}$', '***'])
+:call add(tl, [2, '^*\{4,}$', '****', '****'])
+:call add(tl, [2, '^*\{4,}$', '*****', '*****'])
+:" same thing as 'a*'
+:call add(tl, [2, 'a\{}', 'bbbcddiuhfcd', ''])
+:call add(tl, [2, 'a\{}', 'aaaaioudfh coisf jda', 'aaaa'])
+:"
+:call add(tl, [2, 'a\{-0,0}', 'abcdfdoij', ''])
+:" anti-greedy version of 'a?'
+:call add(tl, [2, 'a\{-0,1}', 'asiubid axxxaaa', ''])
+:call add(tl, [2, 'a\{-3,6}', 'aa siofuh'])
+:call add(tl, [2, 'a\{-3,6}', 'aaaaa asfoij afaa', 'aaa'])
+:call add(tl, [2, 'a\{-3,6}', 'aaaaaaaa', 'aaa'])
+:call add(tl, [2, 'a\{-0}', 'asoiuj', ''])
+:call add(tl, [2, 'a\{-2}', 'aaaa', 'aa'])
+:call add(tl, [2, 'a\{-2}', 'abcdefghijklmnopqrestuvwxyz1234567890'])
+:call add(tl, [2, 'a\{-0,}', 'oij sdigfusnf', ''])
+:call add(tl, [2, 'a\{-0,}', 'aaaaa aa', ''])
+:call add(tl, [2, 'a\{-2,}', 'sdfiougjdsafg'])
+:call add(tl, [2, 'a\{-2,}', 'aaaaasfoij ', 'aa'])
+:call add(tl, [2, 'a\{-,0}', 'oidfguih iuhi hiu aaaa', ''])
+:call add(tl, [2, 'a\{-,5}', 'abcd', ''])
+:call add(tl, [2, 'a\{-,5}', 'aaaaaaaaaa', ''])
+:" anti-greedy version of 'a*'
+:call add(tl, [2, 'a\{-}', 'bbbcddiuhfcd', ''])
+:call add(tl, [2, 'a\{-}', 'aaaaioudfh coisf jda', ''])
+:"
+:" Test groups of characters and submatches
+:call add(tl, [2, '\(abc\)*', 'abcabcabc', 'abcabcabc', 'abc'])
+:call add(tl, [2, '\(ab\)\+', 'abababaaaaa', 'ababab', 'ab'])
+:call add(tl, [2, '\(abaaaaa\)*cd', 'cd', 'cd', ''])
+:call add(tl, [2, '\(test1\)\? \(test2\)\?', 'test1 test3', 'test1 ', 'test1', ''])
+:call add(tl, [2, '\(test1\)\= \(test2\) \(test4443\)\=', ' test2 test4443 yupiiiiiiiiiii', ' test2 test4443', '', 'test2', 'test4443'])
+:call add(tl, [2, '\(\(sub1\) hello \(sub 2\)\)', 'asterix sub1 hello sub 2 obelix', 'sub1 hello sub 2', 'sub1 hello sub 2', 'sub1', 'sub 2'])
+:call add(tl, [2, '\(\(\(yyxxzz\)\)\)', 'abcdddsfiusfyyzzxxyyxxzz', 'yyxxzz', 'yyxxzz', 'yyxxzz', 'yyxxzz'])
+:call add(tl, [2, '\v((ab)+|c+)+', 'abcccaba', 'abcccab', 'ab', 'ab'])
+:call add(tl, [2, '\v((ab)|c*)+', 'abcccaba', 'abcccab', '', 'ab'])
+:call add(tl, [2, '\v(a(c*)+b)+', 'acbababaaa', 'acbabab', 'ab', ''])
+:call add(tl, [2, '\v(a|b*)+', 'aaaa', 'aaaa', ''])
+:call add(tl, [2, '\p*', 'aá ', 'aá '])
+:"
+:" Test greedy-ness and lazy-ness
+:call add(tl, [2, 'a\{-2,7}','aaaaaaaaaaaaa', 'aa'])
+:call add(tl, [2, 'a\{-2,7}x','aaaaaaaaax', 'aaaaaaax'])
+:call add(tl, [2, 'a\{2,7}','aaaaaaaaaaaaaaaaaaaa', 'aaaaaaa'])
+:call add(tl, [2, 'a\{2,7}x','aaaaaaaaax', 'aaaaaaax'])
+:call add(tl, [2, '\vx(.{-,8})yz(.*)','xayxayzxayzxayz','xayxayzxayzxayz','ayxa','xayzxayz'])
+:call add(tl, [2, '\vx(.*)yz(.*)','xayxayzxayzxayz','xayxayzxayzxayz', 'ayxayzxayzxa',''])
+:call add(tl, [2, '\v(a{1,2}){-2,3}','aaaaaaa','aaaa','aa'])
+:call add(tl, [2, '\v(a{-1,3})+','aa','aa','a'])
+:"
+:" Test Character classes
+:call add(tl, [2, '\d\+e\d\d','test 10e23 fd','10e23'])
+:"
+:" Test collections and character range []
+:call add(tl, [2, '\v[a]', 'abcd', 'a'])
+:call add(tl, [2, 'a[bcd]', 'abcd', 'ab'])
+:call add(tl, [2, 'a[b-d]', 'acbd', 'ac'])
+:call add(tl, [2, '[a-d][e-f][x-x]d', 'cexdxx', 'cexd'])
+:call add(tl, [2, '\v[[:alpha:]]+', 'abcdefghijklmnopqrstuvwxyz6','abcdefghijklmnopqrstuvwxyz'])
+:call add(tl, [2, '[[:alpha:]\+]', '6x8','x'])
+:call add(tl, [2, '[^abc]\+','abcabcabc'])
+:call add(tl, [2, '[^abc]','defghiasijvoinasoiunbvb','d'])
+:call add(tl, [2, '[^abc]\+','ddddddda','ddddddd'])
+:call add(tl, [2, '[^a-d]\+','aaaAAAZIHFNCddd','AAAZIHFNC'])
+:call add(tl, [2, '[a-f]*','iiiiiiii',''])
+:call add(tl, [2, '[a-f]*','abcdefgh','abcdef'])
+:call add(tl, [2, '[^a-f]\+','abcdefgh','gh'])
+:call add(tl, [2, '[a-c]\{-3,6}','abcabc','abc'])
+:call add(tl, [2, '[^[:alpha:]]\+','abcccadfoij7787ysf287yrnccdu','7787'])
+:call add(tl, [2, '[-a]', '-', '-'])
+:call add(tl, [2, '[a-]', '-', '-'])
+:call add(tl, [2, '[a-f]*\c','ABCDEFGH','ABCDEF'])
+:call add(tl, [2, '[abc][xyz]\c','-af-AF-BY--','BY'])
+:" filename regexp
+:call add(tl, [2, '[-./[:alnum:]_~]\+', 'log13.file', 'log13.file'])
+:" special chars
+:call add(tl, [2, '[\]\^\-\\]\+', '\^\\\-\---^', '\^\\\-\---^'])
+:" collation elem
+:call add(tl, [2, '[[.a.]]\+', 'aa', 'aa'])
+:" middle of regexp
+:call add(tl, [2, 'abc[0-9]*ddd', 'siuhabc ii'])
+:call add(tl, [2, 'abc[0-9]*ddd', 'adf abc44482ddd oijs', 'abc44482ddd'])
+:call add(tl, [2, '\_[0-9]\+', 'asfi9888u', '9888'])
+:call add(tl, [2, '[0-9\n]\+', 'asfi9888u', '9888'])
+:call add(tl, [2, '\_[0-9]\+', "asfi\n9888u", "\n9888"])
+:call add(tl, [2, '\_f', " \na ", "\n"])
+:call add(tl, [2, '\_f\+', " \na ", "\na"])
+:call add(tl, [2, '[0-9A-Za-z-_.]\+', " @0_a.A-{ ", "0_a.A-"])
+:"
+:"""" Test start/end of line, start/end of file
+:call add(tl, [2, '^a.', "a_\nb ", "a_"])
+:call add(tl, [2, '^a.', "b a \na_"])
+:call add(tl, [2, '.a$', " a\n "])
+:call add(tl, [2, '.a$', " a b\n_a", "_a"])
+:call add(tl, [2, '\%^a.', "a a\na", "a "])
+:call add(tl, [2, '\%^a', " a \na "])
+:call add(tl, [2, '.a\%$', " a\n "])
+:call add(tl, [2, '.a\%$', " a\n_a", "_a"])
+:"
+:"""" Test recognition of character classes
+:call add(tl, [2, '[0-7]\+', 'x0123456789x', '01234567'])
+:call add(tl, [2, '[^0-7]\+', '0a;X+% 897', 'a;X+% 89'])
+:call add(tl, [2, '[0-9]\+', 'x0123456789x', '0123456789'])
+:call add(tl, [2, '[^0-9]\+', '0a;X+% 9', 'a;X+% '])
+:call add(tl, [2, '[0-9a-fA-F]\+', 'x0189abcdefg', '0189abcdef'])
+:call add(tl, [2, '[^0-9A-Fa-f]\+', '0189g;X+% ab', 'g;X+% '])
+:call add(tl, [2, '[a-z_A-Z0-9]\+', ';+aso_SfOij ', 'aso_SfOij'])
+:call add(tl, [2, '[^a-z_A-Z0-9]\+', 'aSo_;+% sfOij', ';+% '])
+:call add(tl, [2, '[a-z_A-Z]\+', '0abyz_ABYZ;', 'abyz_ABYZ'])
+:call add(tl, [2, '[^a-z_A-Z]\+', 'abAB_09;+% yzYZ', '09;+% '])
+:call add(tl, [2, '[a-z]\+', '0abcxyz1', 'abcxyz'])
+:call add(tl, [2, '[a-z]\+', 'AabxyzZ', 'abxyz'])
+:call add(tl, [2, '[^a-z]\+', 'a;X09+% x', ';X09+% '])
+:call add(tl, [2, '[^a-z]\+', 'abX0;%yz', 'X0;%'])
+:call add(tl, [2, '[a-zA-Z]\+', '0abABxzXZ9', 'abABxzXZ'])
+:call add(tl, [2, '[^a-zA-Z]\+', 'ab09_;+ XZ', '09_;+ '])
+:call add(tl, [2, '[A-Z]\+', 'aABXYZz', 'ABXYZ'])
+:call add(tl, [2, '[^A-Z]\+', 'ABx0;%YZ', 'x0;%'])
+:call add(tl, [2, '[a-z]\+\c', '0abxyzABXYZ;', 'abxyzABXYZ'])
+:call add(tl, [2, '[A-Z]\+\c', '0abABxzXZ9', 'abABxzXZ'])
+:call add(tl, [2, '\c[^a-z]\+', 'ab09_;+ XZ', '09_;+ '])
+:call add(tl, [2, '\c[^A-Z]\+', 'ab09_;+ XZ', '09_;+ '])
+:call add(tl, [2, '\C[^A-Z]\+', 'ABCOIJDEOIFNSD jsfoij sa', ' jsfoij sa'])
+:"
+:"""" Tests for \z features
+:" match ends at \ze
+:call add(tl, [2, 'xx \ze test', 'xx '])
+:call add(tl, [2, 'abc\zeend', 'oij abcend', 'abc'])
+:call add(tl, [2, 'aa\zebb\|aaxx', ' aabb ', 'aa'])
+:call add(tl, [2, 'aa\zebb\|aaxx', ' aaxx ', 'aaxx'])
+:call add(tl, [2, 'aabb\|aa\zebb', ' aabb ', 'aabb'])
+:call add(tl, [2, 'aa\zebb\|aaebb', ' aabb ', 'aa'])
+:" match starts at \zs
+:call add(tl, [2, 'abc\zsdd', 'ddabcddxyzt', 'dd'])
+:call add(tl, [2, 'aa \zsax', ' ax'])
+:call add(tl, [2, 'abc \zsmatch\ze abc', 'abc abc abc match abc abc', 'match'])
+:call add(tl, [2, '\v(a \zsif .*){2}', 'a if then a if last', 'if last', 'a if last'])
+:call add(tl, [2, '\>\zs.', 'aword. ', '.'])
+:call add(tl, [2, '\s\+\ze\[/\|\s\zs\s\+', 'is [a t', ' '])
+:"
+:"""" Tests for \@= and \& features
+:call add(tl, [2, 'abc\@=', 'abc', 'ab'])
+:call add(tl, [2, 'abc\@=cd', 'abcd', 'abcd'])
+:call add(tl, [2, 'abc\@=', 'ababc', 'ab'])
+:" will never match, no matter the input text
+:call add(tl, [2, 'abcd\@=e', 'abcd'])
+:" will never match
+:call add(tl, [2, 'abcd\@=e', 'any text in here ... '])
+:call add(tl, [2, '\v(abc)@=..', 'xabcd', 'ab', 'abc'])
+:call add(tl, [2, '\(.*John\)\@=.*Bob', 'here is John, and here is B'])
+:call add(tl, [2, '\(John.*\)\@=.*Bob', 'John is Bobs friend', 'John is Bob', 'John is Bobs friend'])
+:call add(tl, [2, '\<\S\+\())\)\@=', '$((i=i+1))', 'i=i+1', '))'])
+:call add(tl, [2, '.*John\&.*Bob', 'here is John, and here is B'])
+:call add(tl, [2, '.*John\&.*Bob', 'John is Bobs friend', 'John is Bob'])
+:call add(tl, [2, '\v(test1)@=.*yep', 'this is a test1, yep it is', 'test1, yep', 'test1'])
+:call add(tl, [2, 'foo\(bar\)\@!', 'foobar'])
+:call add(tl, [2, 'foo\(bar\)\@!', 'foo bar', 'foo'])
+:call add(tl, [2, 'if \(\(then\)\@!.\)*$', ' if then else'])
+:call add(tl, [2, 'if \(\(then\)\@!.\)*$', ' if else ', 'if else ', ' '])
+:call add(tl, [2, '\(foo\)\@!bar', 'foobar', 'bar'])
+:call add(tl, [2, '\(foo\)\@!...bar', 'foobar'])
+:call add(tl, [2, '^\%(.*bar\)\@!.*\zsfoo', ' bar foo '])
+:call add(tl, [2, '^\%(.*bar\)\@!.*\zsfoo', ' foo bar '])
+:call add(tl, [2, '^\%(.*bar\)\@!.*\zsfoo', ' foo xxx ', 'foo'])
+:call add(tl, [2, '[ ]\@!\p\%([ ]\@!\p\)*:', 'implicit mappings:', 'mappings:'])
+:call add(tl, [2, '[ ]\@!\p\([ ]\@!\p\)*:', 'implicit mappings:', 'mappings:', 's'])
+:call add(tl, [2, 'm\k\+_\@=\%(_\@!\k\)\@<=\k\+e', 'mx__xe', 'mx__xe'])
+:call add(tl, [2, '\%(\U\@<=S\k*\|S\l\)R', 'SuR', 'SuR'])
+:"
+:"""" Combining different tests and features
+:call add(tl, [2, '[[:alpha:]]\{-2,6}', '787abcdiuhsasiuhb4', 'ab'])
+:call add(tl, [2, '', 'abcd', ''])
+:call add(tl, [2, '\v(())', 'any possible text', ''])
+:call add(tl, [2, '\v%(ab(xyz)c)', ' abxyzc ', 'abxyzc', 'xyz'])
+:call add(tl, [2, '\v(test|)empty', 'tesempty', 'empty', ''])
+:call add(tl, [2, '\v(a|aa)(a|aa)', 'aaa', 'aa', 'a', 'a'])
+:"
+:"""" \%u and friends
+:call add(tl, [2, '\%d32', 'yes no', ' '])
+:call add(tl, [2, '\%o40', 'yes no', ' '])
+:call add(tl, [2, '\%x20', 'yes no', ' '])
+:call add(tl, [2, '\%u0020', 'yes no', ' '])
+:call add(tl, [2, '\%U00000020', 'yes no', ' '])
+:call add(tl, [2, '\%d0', "yes\x0ano", "\x0a"])
+:"
+:""""" \%[abc]
+:call add(tl, [2, 'foo\%[bar]', 'fobar'])
+:call add(tl, [2, 'foo\%[bar]', 'foobar', 'foobar'])
+:call add(tl, [2, 'foo\%[bar]', 'fooxx', 'foo'])
+:call add(tl, [2, 'foo\%[bar]', 'foobxx', 'foob'])
+:call add(tl, [2, 'foo\%[bar]', 'foobaxx', 'fooba'])
+:call add(tl, [2, 'foo\%[bar]', 'foobarxx', 'foobar'])
+:call add(tl, [2, 'foo\%[bar]x', 'foobxx', 'foobx'])
+:call add(tl, [2, 'foo\%[bar]x', 'foobarxx', 'foobarx'])
+:call add(tl, [2, '\%[bar]x', 'barxx', 'barx'])
+:call add(tl, [2, '\%[bar]x', 'bxx', 'bx'])
+:call add(tl, [2, '\%[bar]x', 'xxx', 'x'])
+:call add(tl, [2, 'b\%[[ao]r]', 'bar bor', 'bar'])
+:call add(tl, [2, 'b\%[[]]r]', 'b]r bor', 'b]r'])
+:call add(tl, [2, '@\%[\w\-]*', '<http://john.net/pandoc/>[@pandoc]', '@pandoc'])
+:"
+:"""" Alternatives, must use first longest match
+:call add(tl, [2, 'goo\|go', 'google', 'goo'])
+:call add(tl, [2, '\<goo\|\<go', 'google', 'goo'])
+:call add(tl, [2, '\<goo\|go', 'google', 'goo'])
+:"
+:"""" Back references
+:call add(tl, [2, '\(\i\+\) \1', ' abc abc', 'abc abc', 'abc'])
+:call add(tl, [2, '\(\i\+\) \1', 'xgoo goox', 'goo goo', 'goo'])
+:call add(tl, [2, '\(a\)\(b\)\(c\)\(dd\)\(e\)\(f\)\(g\)\(h\)\(i\)\1\2\3\4\5\6\7\8\9', 'xabcddefghiabcddefghix', 'abcddefghiabcddefghi', 'a', 'b', 'c', 'dd', 'e', 'f', 'g', 'h', 'i'])
+:call add(tl, [2, '\(\d*\)a \1b', ' a b ', 'a b', ''])
+:call add(tl, [2, '^.\(.\).\_..\1.', "aaa\naaa\nb", "aaa\naaa", 'a'])
+:call add(tl, [2, '^.*\.\(.*\)/.\+\(\1\)\@<!$', 'foo.bat/foo.com', 'foo.bat/foo.com', 'bat'])
+:call add(tl, [2, '^.*\.\(.*\)/.\+\(\1\)\@<!$', 'foo.bat/foo.bat'])
+:call add(tl, [2, '^.*\.\(.*\)/.\+\(\1\)\@<=$', 'foo.bat/foo.bat', 'foo.bat/foo.bat', 'bat', 'bat'])
+:call add(tl, [2, '\\\@<!\${\(\d\+\%(:.\{-}\)\?\\\@<!\)}', '2013-06-27${0}', '${0}', '0'])
+:call add(tl, [2, '^\(a*\)\1$', 'aaaaaaaa', 'aaaaaaaa', 'aaaa'])
+:"
+:"""" Look-behind with limit
+:call add(tl, [2, '<\@<=span.', 'xxspanxx<spanyyy', 'spany'])
+:call add(tl, [2, '<\@1<=span.', 'xxspanxx<spanyyy', 'spany'])
+:call add(tl, [2, '<\@2<=span.', 'xxspanxx<spanyyy', 'spany'])
+:call add(tl, [2, '\(<<\)\@<=span.', 'xxspanxxxx<spanxx<<spanyyy', 'spany', '<<'])
+:call add(tl, [2, '\(<<\)\@1<=span.', 'xxspanxxxx<spanxx<<spanyyy'])
+:call add(tl, [2, '\(<<\)\@2<=span.', 'xxspanxxxx<spanxx<<spanyyy', 'spany', '<<'])
+:call add(tl, [2, '\(foo\)\@<!bar.', 'xx foobar1 xbar2 xx', 'bar2'])
+:"
+:" look-behind match in front of a zero-width item
+:call add(tl, [2, '\v\C%(<Last Changed:\s+)@<=.*$', '" test header'])
+:call add(tl, [2, '\v\C%(<Last Changed:\s+)@<=.*$', '" Last Changed: 1970', '1970'])
+:call add(tl, [2, '\(foo\)\@<=\>', 'foobar'])
+:call add(tl, [2, '\(foo\)\@<=\>', 'barfoo', '', 'foo'])
+:call add(tl, [2, '\(foo\)\@<=.*', 'foobar', 'bar', 'foo'])
+:"
+:" complicated look-behind match
+:call add(tl, [2, '\(r\@<=\|\w\@<!\)\/', 'x = /word/;', '/'])
+:call add(tl, [2, '^[a-z]\+\ze \&\(asdf\)\@<!', 'foo bar', 'foo'])
+:"
+:""""" \@>
+:call add(tl, [2, '\(a*\)\@>a', 'aaaa'])
+:call add(tl, [2, '\(a*\)\@>b', 'aaab', 'aaab', 'aaa'])
+:call add(tl, [2, '^\(.\{-}b\)\@>.', ' abcbd', ' abc', ' ab'])
+:call add(tl, [2, '\(.\{-}\)\(\)\@>$', 'abc', 'abc', 'abc', ''])
+:" TODO: BT engine does not restore submatch after failure
+:call add(tl, [1, '\(a*\)\@>a\|a\+', 'aaaa', 'aaaa'])
+:"
+:"""" "\_" prepended negated collection matches EOL
+:call add(tl, [2, '\_[^8-9]\+', "asfi\n9888", "asfi\n"])
+:call add(tl, [2, '\_[^a]\+', "asfi\n9888", "sfi\n9888"])
+:"
+:"""" Requiring lots of states.
+:call add(tl, [2, '[0-9a-zA-Z]\{8}-\([0-9a-zA-Z]\{4}-\)\{3}[0-9a-zA-Z]\{12}', " 12345678-1234-1234-1234-123456789012 ", "12345678-1234-1234-1234-123456789012", "1234-"])
+:"
+:"""" Skip adding state twice
+:call add(tl, [2, '^\%(\%(^\s*#\s*if\>\|#\s*if\)\)\(\%>1c.*$\)\@=', "#if FOO", "#if", ' FOO'])
+:"
+:"""" Run the tests
+:"
+:for t in tl
+: let re = t[0]
+: let pat = t[1]
+: let text = t[2]
+: let matchidx = 3
+: for engine in [0, 1, 2]
+: if engine == 2 && re == 0 || engine == 1 && re ==1
+: continue
+: endif
+: let &regexpengine = engine
+: try
+: let l = matchlist(text, pat)
+: catch
+: $put ='ERROR: pat: \"' . pat . '\", text: \"' . text . '\", caused an exception: \"' . v:exception . '\"'
+: endtry
+:" check the match itself
+: if len(l) == 0 && len(t) > matchidx
+: $put ='ERROR: pat: \"' . pat . '\", text: \"' . text . '\", did not match, expected: \"' . t[matchidx] . '\"'
+: elseif len(l) > 0 && len(t) == matchidx
+: $put ='ERROR: pat: \"' . pat . '\", text: \"' . text . '\", match: \"' . l[0] . '\", expected no match'
+: elseif len(t) > matchidx && l[0] != t[matchidx]
+: $put ='ERROR: pat: \"' . pat . '\", text: \"' . text . '\", match: \"' . l[0] . '\", expected: \"' . t[matchidx] . '\"'
+: else
+: $put ='OK ' . engine . ' - ' . pat
+: endif
+: if len(l) > 0
+:" check all the nine submatches
+: for i in range(1, 9)
+: if len(t) <= matchidx + i
+: let e = ''
+: else
+: let e = t[matchidx + i]
+: endif
+: if l[i] != e
+: $put ='ERROR: pat: \"' . pat . '\", text: \"' . text . '\", submatch ' . i . ': \"' . l[i] . '\", expected: \"' . e . '\"'
+: endif
+: endfor
+: unlet i
+: endif
+: endfor
+:endfor
+:unlet t tl e l
+:"
+:"""""" multi-line tests """"""""""""""""""""
+:let tl = []
+:"
+:"""" back references
+:call add(tl, [2, '^.\(.\).\_..\1.', ['aaa', 'aaa', 'b'], ['XX', 'b']])
+:call add(tl, [2, '\v.*\/(.*)\n.*\/\1$', ['./Dir1/Dir2/zyxwvuts.txt', './Dir1/Dir2/abcdefgh.bat', '', './Dir1/Dir2/file1.txt', './OtherDir1/OtherDir2/file1.txt'], ['./Dir1/Dir2/zyxwvuts.txt', './Dir1/Dir2/abcdefgh.bat', '', 'XX']])
+:"
+:"""" line breaks
+:call add(tl, [2, '\S.*\nx', ['abc', 'def', 'ghi', 'xjk', 'lmn'], ['abc', 'def', 'XXjk', 'lmn']])
+:"
+:" Check that \_[0-9] matching EOL does not break a following \>
+:call add(tl, [2, '\<\(\(25\_[0-5]\|2\_[0-4]\_[0-9]\|\_[01]\?\_[0-9]\_[0-9]\?\)\.\)\{3\}\(25\_[0-5]\|2\_[0-4]\_[0-9]\|\_[01]\?\_[0-9]\_[0-9]\?\)\>', ['', 'localnet/192.168.0.1', ''], ['', 'localnet/XX', '']])
+:"
+:" Check a pattern with a line break and ^ and $
+:call add(tl, [2, 'a\n^b$\n^c', ['a', 'b', 'c'], ['XX']])
+:"
+:call add(tl, [2, '\(^.\+\n\)\1', [' dog', ' dog', 'asdf'], ['XXasdf']])
+:"
+:"""" Run the multi-line tests
+:"
+:$put ='multi-line tests'
+:for t in tl
+: let re = t[0]
+: let pat = t[1]
+: let before = t[2]
+: let after = t[3]
+: for engine in [0, 1, 2]
+: if engine == 2 && re == 0 || engine == 1 && re ==1
+: continue
+: endif
+: let &regexpengine = engine
+: new
+: call setline(1, before)
+: exe '%s/' . pat . '/XX/'
+: let result = getline(1, '$')
+: q!
+: if result != after
+: $put ='ERROR: pat: \"' . pat . '\", text: \"' . string(before) . '\", expected: \"' . string(after) . '\", got: \"' . string(result) . '\"'
+: else
+: $put ='OK ' . engine . ' - ' . pat
+: endif
+: endfor
+:endfor
+:unlet t tl
+:"
+:" Check that using a pattern on two lines doesn't get messed up by using
+:" matchstr() with \ze in between.
+:set re=0
+/^Substitute here
+:.+1,.+2s/""/\='"'.matchstr(getline("."), '\d\+\ze<').'"'
+/^Substitute here
+:.+1,.+2yank
+Gop:"
+:"
+:" Check a pattern with a look beind crossing a line boundary
+/^Behind:
+/\(<\_[xy]\+\)\@3<=start
+:.yank
+Gop:"
+:"
+:" Check matching Visual area
+/^Visual:
+jfxvfx:s/\%Ve/E/g
+jV:s/\%Va/A/g
+jfxfxj:s/\%Vo/O/g
+:/^Visual/+1,/^Visual/+4yank
+Gop:"
+:"
+:" Check matching marks
+/^Marks:
+jfSmsfEme:.-4,.+6s/.\%>'s.*\%<'e../here/
+jfSmsj0fEme:.-4,.+6s/.\%>'s\_.*\%<'e../again/
+:/^Marks:/+1,/^Marks:/+3yank
+Gop:"
+:"
+:" Check patterns matching cursor position.
+:func! Postest()
+ new
+ call setline(1, ['ffooooo', 'boboooo', 'zoooooo', 'koooooo', 'moooooo', "\t\t\tfoo", 'abababababababfoo', 'bababababababafoo', '********_'])
+ call setpos('.', [0, 1, 0, 0])
+ s/\%>3c.//g
+ call setpos('.', [0, 2, 4, 0])
+ s/\%#.*$//g
+ call setpos('.', [0, 3, 0, 0])
+ s/\%<3c./_/g
+ %s/\%4l\%>5c./_/g
+ %s/\%6l\%>25v./_/g
+ %s/\%>6l\%3c./!/g
+ %s/\%>7l\%12c./?/g
+ %s/\%>7l\%<9l\%>5v\%<8v./#/g
+ 1,$yank
+ quit!
+endfunc
+Go-0-:set re=0
+:call Postest()
+:put
+o-1-:set re=1
+:call Postest()
+:put
+o-2-:set re=2
+:call Postest()
+:put
+:"
+:" start and end of buffer
+/\%^
+yeGop:"
+50%/\%^..
+yeGopA END:"
+50%/\%$
+"ayb20gg/..\%$
+"bybGo"apo"bp:"
+:"
+:""""" Write the results """""""""""""
+:/\%#=1^Results/,$wq! test.out
+ENDTEST
+
+Substitute here:
+<T="">Ta 5</Title>
+<T="">Ac 7</Title>
+
+Behind:
+asdfasd<yyy
+xxstart1
+asdfasd<yy
+xxxstart2
+asdfasd<yy
+xxstart3
+
+Visual:
+thexe the thexethe
+andaxand andaxand
+oooxofor foroxooo
+oooxofor foroxooo
+
+Marks:
+asdfSasdfsadfEasdf
+asdfSas
+dfsadfEasdf
+
+Results of test64:
diff --git a/src/testdir/test64.ok b/src/testdir/test64.ok
new file mode 100644
index 0000000000..a1498ea5d6
--- /dev/null
+++ b/src/testdir/test64.ok
@@ -0,0 +1,1084 @@
+Results of test64:
+OK 0 - ab
+OK 1 - ab
+OK 2 - ab
+OK 0 - b
+OK 1 - b
+OK 2 - b
+OK 0 - bc*
+OK 1 - bc*
+OK 2 - bc*
+OK 0 - bc\{-}
+OK 1 - bc\{-}
+OK 2 - bc\{-}
+OK 0 - bc\{-}\(d\)
+OK 1 - bc\{-}\(d\)
+OK 2 - bc\{-}\(d\)
+OK 0 - bc*
+OK 1 - bc*
+OK 2 - bc*
+OK 0 - c*
+OK 1 - c*
+OK 2 - c*
+OK 0 - bc*
+OK 1 - bc*
+OK 2 - bc*
+OK 0 - c*
+OK 1 - c*
+OK 2 - c*
+OK 0 - bc\+
+OK 1 - bc\+
+OK 2 - bc\+
+OK 0 - bc\+
+OK 1 - bc\+
+OK 2 - bc\+
+OK 0 - a\|ab
+OK 1 - a\|ab
+OK 2 - a\|ab
+OK 0 - c\?
+OK 1 - c\?
+OK 2 - c\?
+OK 0 - bc\?
+OK 1 - bc\?
+OK 2 - bc\?
+OK 0 - bc\?
+OK 1 - bc\?
+OK 2 - bc\?
+OK 0 - \va{1}
+OK 1 - \va{1}
+OK 2 - \va{1}
+OK 0 - \va{2}
+OK 1 - \va{2}
+OK 2 - \va{2}
+OK 0 - \va{2}
+OK 1 - \va{2}
+OK 2 - \va{2}
+OK 0 - \va{2}
+OK 1 - \va{2}
+OK 2 - \va{2}
+OK 0 - \va{2}
+OK 1 - \va{2}
+OK 2 - \va{2}
+OK 0 - \va{2}
+OK 1 - \va{2}
+OK 2 - \va{2}
+OK 0 - \va{2}
+OK 1 - \va{2}
+OK 2 - \va{2}
+OK 0 - \vb{1}
+OK 1 - \vb{1}
+OK 2 - \vb{1}
+OK 0 - \vba{2}
+OK 1 - \vba{2}
+OK 2 - \vba{2}
+OK 0 - \vba{3}
+OK 1 - \vba{3}
+OK 2 - \vba{3}
+OK 0 - \v(ab){1}
+OK 1 - \v(ab){1}
+OK 2 - \v(ab){1}
+OK 0 - \v(ab){1}
+OK 1 - \v(ab){1}
+OK 2 - \v(ab){1}
+OK 0 - \v(ab){1}
+OK 1 - \v(ab){1}
+OK 2 - \v(ab){1}
+OK 0 - \v(ab){0,2}
+OK 1 - \v(ab){0,2}
+OK 2 - \v(ab){0,2}
+OK 0 - \v(ab){0,2}
+OK 1 - \v(ab){0,2}
+OK 2 - \v(ab){0,2}
+OK 0 - \v(ab){1,2}
+OK 1 - \v(ab){1,2}
+OK 2 - \v(ab){1,2}
+OK 0 - \v(ab){1,2}
+OK 1 - \v(ab){1,2}
+OK 2 - \v(ab){1,2}
+OK 0 - \v(ab){2,4}
+OK 1 - \v(ab){2,4}
+OK 2 - \v(ab){2,4}
+OK 0 - \v(ab){2,4}
+OK 1 - \v(ab){2,4}
+OK 2 - \v(ab){2,4}
+OK 0 - \v(ab){2}
+OK 1 - \v(ab){2}
+OK 2 - \v(ab){2}
+OK 0 - \v(ab){2}
+OK 1 - \v(ab){2}
+OK 2 - \v(ab){2}
+OK 0 - \v(ab){2}
+OK 1 - \v(ab){2}
+OK 2 - \v(ab){2}
+OK 0 - \v(ab){2}
+OK 1 - \v(ab){2}
+OK 2 - \v(ab){2}
+OK 0 - \v((ab){2}){2}
+OK 1 - \v((ab){2}){2}
+OK 2 - \v((ab){2}){2}
+OK 0 - \v((ab){2}){2}
+OK 1 - \v((ab){2}){2}
+OK 2 - \v((ab){2}){2}
+OK 0 - \v(a{1}){1}
+OK 1 - \v(a{1}){1}
+OK 2 - \v(a{1}){1}
+OK 0 - \v(a{2}){1}
+OK 1 - \v(a{2}){1}
+OK 2 - \v(a{2}){1}
+OK 0 - \v(a{2}){1}
+OK 1 - \v(a{2}){1}
+OK 2 - \v(a{2}){1}
+OK 0 - \v(a{2}){1}
+OK 1 - \v(a{2}){1}
+OK 2 - \v(a{2}){1}
+OK 0 - \v(a{1}){2}
+OK 1 - \v(a{1}){2}
+OK 2 - \v(a{1}){2}
+OK 0 - \v(a{1}){2}
+OK 1 - \v(a{1}){2}
+OK 2 - \v(a{1}){2}
+OK 0 - \v(a{2})+
+OK 1 - \v(a{2})+
+OK 2 - \v(a{2})+
+OK 0 - \v(a{2})+
+OK 1 - \v(a{2})+
+OK 2 - \v(a{2})+
+OK 0 - \v(a{2}){1}
+OK 1 - \v(a{2}){1}
+OK 2 - \v(a{2}){1}
+OK 0 - \v(a{1}){2}
+OK 1 - \v(a{1}){2}
+OK 2 - \v(a{1}){2}
+OK 0 - \v(a{1}){1}
+OK 1 - \v(a{1}){1}
+OK 2 - \v(a{1}){1}
+OK 0 - \v(a{2}){2}
+OK 1 - \v(a{2}){2}
+OK 2 - \v(a{2}){2}
+OK 0 - \v(a{2}){2}
+OK 1 - \v(a{2}){2}
+OK 2 - \v(a{2}){2}
+OK 0 - \v(a+){2}
+OK 1 - \v(a+){2}
+OK 2 - \v(a+){2}
+OK 0 - \v(a{3}){2}
+OK 1 - \v(a{3}){2}
+OK 2 - \v(a{3}){2}
+OK 0 - \v(a{1,2}){2}
+OK 1 - \v(a{1,2}){2}
+OK 2 - \v(a{1,2}){2}
+OK 0 - \v(a{1,3}){2}
+OK 1 - \v(a{1,3}){2}
+OK 2 - \v(a{1,3}){2}
+OK 0 - \v(a{1,3}){2}
+OK 1 - \v(a{1,3}){2}
+OK 2 - \v(a{1,3}){2}
+OK 0 - \v(a{1,3}){3}
+OK 1 - \v(a{1,3}){3}
+OK 2 - \v(a{1,3}){3}
+OK 0 - \v(a{1,2}){2}
+OK 1 - \v(a{1,2}){2}
+OK 2 - \v(a{1,2}){2}
+OK 0 - \v(a+)+
+OK 1 - \v(a+)+
+OK 2 - \v(a+)+
+OK 0 - \v(a+)+
+OK 1 - \v(a+)+
+OK 2 - \v(a+)+
+OK 0 - \v(a+){1,2}
+OK 1 - \v(a+){1,2}
+OK 2 - \v(a+){1,2}
+OK 0 - \v(a+)(a+)
+OK 1 - \v(a+)(a+)
+OK 2 - \v(a+)(a+)
+OK 0 - \v(a{3})+
+OK 1 - \v(a{3})+
+OK 2 - \v(a{3})+
+OK 0 - \v(a|b|c)+
+OK 1 - \v(a|b|c)+
+OK 2 - \v(a|b|c)+
+OK 0 - \v(a|b|c){2}
+OK 1 - \v(a|b|c){2}
+OK 2 - \v(a|b|c){2}
+OK 0 - \v(abc){2}
+OK 1 - \v(abc){2}
+OK 2 - \v(abc){2}
+OK 0 - \v(abc){2}
+OK 1 - \v(abc){2}
+OK 2 - \v(abc){2}
+OK 0 - a*
+OK 1 - a*
+OK 2 - a*
+OK 0 - \v(a*)+
+OK 1 - \v(a*)+
+OK 2 - \v(a*)+
+OK 0 - \v((ab)+)+
+OK 1 - \v((ab)+)+
+OK 2 - \v((ab)+)+
+OK 0 - \v(((ab)+)+)+
+OK 1 - \v(((ab)+)+)+
+OK 2 - \v(((ab)+)+)+
+OK 0 - \v(((ab)+)+)+
+OK 1 - \v(((ab)+)+)+
+OK 2 - \v(((ab)+)+)+
+OK 0 - \v(a{0,2})+
+OK 1 - \v(a{0,2})+
+OK 2 - \v(a{0,2})+
+OK 0 - \v(a*)+
+OK 1 - \v(a*)+
+OK 2 - \v(a*)+
+OK 0 - \v((a*)+)+
+OK 1 - \v((a*)+)+
+OK 2 - \v((a*)+)+
+OK 0 - \v((ab)*)+
+OK 1 - \v((ab)*)+
+OK 2 - \v((ab)*)+
+OK 0 - \va{1,3}
+OK 1 - \va{1,3}
+OK 2 - \va{1,3}
+OK 0 - \va{2,3}
+OK 1 - \va{2,3}
+OK 2 - \va{2,3}
+OK 0 - \v((ab)+|c*)+
+OK 1 - \v((ab)+|c*)+
+OK 2 - \v((ab)+|c*)+
+OK 0 - \v(a{2})|(b{3})
+OK 1 - \v(a{2})|(b{3})
+OK 2 - \v(a{2})|(b{3})
+OK 0 - \va{2}|b{2}
+OK 1 - \va{2}|b{2}
+OK 2 - \va{2}|b{2}
+OK 0 - \v(a)+|(c)+
+OK 1 - \v(a)+|(c)+
+OK 2 - \v(a)+|(c)+
+OK 0 - \vab{2,3}c
+OK 1 - \vab{2,3}c
+OK 2 - \vab{2,3}c
+OK 0 - \vab{2,3}c
+OK 1 - \vab{2,3}c
+OK 2 - \vab{2,3}c
+OK 0 - \vab{2,3}cd{2,3}e
+OK 1 - \vab{2,3}cd{2,3}e
+OK 2 - \vab{2,3}cd{2,3}e
+OK 0 - \va(bc){2}d
+OK 1 - \va(bc){2}d
+OK 2 - \va(bc){2}d
+OK 0 - \va*a{2}
+OK 1 - \va*a{2}
+OK 2 - \va*a{2}
+OK 0 - \va*a{2}
+OK 1 - \va*a{2}
+OK 2 - \va*a{2}
+OK 0 - \va*a{2}
+OK 1 - \va*a{2}
+OK 2 - \va*a{2}
+OK 0 - \va*a{2}
+OK 1 - \va*a{2}
+OK 2 - \va*a{2}
+OK 0 - \va*b*|a*c*
+OK 1 - \va*b*|a*c*
+OK 2 - \va*b*|a*c*
+OK 0 - \va{1}b{1}|a{1}b{1}
+OK 1 - \va{1}b{1}|a{1}b{1}
+OK 2 - \va{1}b{1}|a{1}b{1}
+OK 0 - \v(a)
+OK 1 - \v(a)
+OK 2 - \v(a)
+OK 0 - \v(a)(b)
+OK 1 - \v(a)(b)
+OK 2 - \v(a)(b)
+OK 0 - \v(ab)(b)(c)
+OK 1 - \v(ab)(b)(c)
+OK 2 - \v(ab)(b)(c)
+OK 0 - \v((a)(b))
+OK 1 - \v((a)(b))
+OK 2 - \v((a)(b))
+OK 0 - \v(a)|(b)
+OK 1 - \v(a)|(b)
+OK 2 - \v(a)|(b)
+OK 0 - \v(a*)+
+OK 1 - \v(a*)+
+OK 2 - \v(a*)+
+OK 0 - x
+OK 1 - x
+OK 2 - x
+OK 0 - ab
+OK 1 - ab
+OK 2 - ab
+OK 0 - ab
+OK 1 - ab
+OK 2 - ab
+OK 0 - ab
+OK 1 - ab
+OK 2 - ab
+OK 0 - x*
+OK 1 - x*
+OK 2 - x*
+OK 0 - x*
+OK 1 - x*
+OK 2 - x*
+OK 0 - x*
+OK 1 - x*
+OK 2 - x*
+OK 0 - x\+
+OK 1 - x\+
+OK 2 - x\+
+OK 0 - x\+
+OK 1 - x\+
+OK 2 - x\+
+OK 0 - x\+
+OK 1 - x\+
+OK 2 - x\+
+OK 0 - x\+
+OK 1 - x\+
+OK 2 - x\+
+OK 0 - x\=
+OK 1 - x\=
+OK 2 - x\=
+OK 0 - x\=
+OK 1 - x\=
+OK 2 - x\=
+OK 0 - x\=
+OK 1 - x\=
+OK 2 - x\=
+OK 0 - x\?
+OK 1 - x\?
+OK 2 - x\?
+OK 0 - x\?
+OK 1 - x\?
+OK 2 - x\?
+OK 0 - x\?
+OK 1 - x\?
+OK 2 - x\?
+OK 0 - a\{0,0}
+OK 1 - a\{0,0}
+OK 2 - a\{0,0}
+OK 0 - a\{0,1}
+OK 1 - a\{0,1}
+OK 2 - a\{0,1}
+OK 0 - a\{1,0}
+OK 1 - a\{1,0}
+OK 2 - a\{1,0}
+OK 0 - a\{3,6}
+OK 1 - a\{3,6}
+OK 2 - a\{3,6}
+OK 0 - a\{3,6}
+OK 1 - a\{3,6}
+OK 2 - a\{3,6}
+OK 0 - a\{3,6}
+OK 1 - a\{3,6}
+OK 2 - a\{3,6}
+OK 0 - a\{0}
+OK 1 - a\{0}
+OK 2 - a\{0}
+OK 0 - a\{2}
+OK 1 - a\{2}
+OK 2 - a\{2}
+OK 0 - a\{2}
+OK 1 - a\{2}
+OK 2 - a\{2}
+OK 0 - a\{2}
+OK 1 - a\{2}
+OK 2 - a\{2}
+OK 0 - a\{0,}
+OK 1 - a\{0,}
+OK 2 - a\{0,}
+OK 0 - a\{0,}
+OK 1 - a\{0,}
+OK 2 - a\{0,}
+OK 0 - a\{2,}
+OK 1 - a\{2,}
+OK 2 - a\{2,}
+OK 0 - a\{2,}
+OK 1 - a\{2,}
+OK 2 - a\{2,}
+OK 0 - a\{5,}
+OK 1 - a\{5,}
+OK 2 - a\{5,}
+OK 0 - a\{5,}
+OK 1 - a\{5,}
+OK 2 - a\{5,}
+OK 0 - a\{,0}
+OK 1 - a\{,0}
+OK 2 - a\{,0}
+OK 0 - a\{,5}
+OK 1 - a\{,5}
+OK 2 - a\{,5}
+OK 0 - a\{,5}
+OK 1 - a\{,5}
+OK 2 - a\{,5}
+OK 0 - ^*\{4,}$
+OK 1 - ^*\{4,}$
+OK 2 - ^*\{4,}$
+OK 0 - ^*\{4,}$
+OK 1 - ^*\{4,}$
+OK 2 - ^*\{4,}$
+OK 0 - ^*\{4,}$
+OK 1 - ^*\{4,}$
+OK 2 - ^*\{4,}$
+OK 0 - a\{}
+OK 1 - a\{}
+OK 2 - a\{}
+OK 0 - a\{}
+OK 1 - a\{}
+OK 2 - a\{}
+OK 0 - a\{-0,0}
+OK 1 - a\{-0,0}
+OK 2 - a\{-0,0}
+OK 0 - a\{-0,1}
+OK 1 - a\{-0,1}
+OK 2 - a\{-0,1}
+OK 0 - a\{-3,6}
+OK 1 - a\{-3,6}
+OK 2 - a\{-3,6}
+OK 0 - a\{-3,6}
+OK 1 - a\{-3,6}
+OK 2 - a\{-3,6}
+OK 0 - a\{-3,6}
+OK 1 - a\{-3,6}
+OK 2 - a\{-3,6}
+OK 0 - a\{-0}
+OK 1 - a\{-0}
+OK 2 - a\{-0}
+OK 0 - a\{-2}
+OK 1 - a\{-2}
+OK 2 - a\{-2}
+OK 0 - a\{-2}
+OK 1 - a\{-2}
+OK 2 - a\{-2}
+OK 0 - a\{-0,}
+OK 1 - a\{-0,}
+OK 2 - a\{-0,}
+OK 0 - a\{-0,}
+OK 1 - a\{-0,}
+OK 2 - a\{-0,}
+OK 0 - a\{-2,}
+OK 1 - a\{-2,}
+OK 2 - a\{-2,}
+OK 0 - a\{-2,}
+OK 1 - a\{-2,}
+OK 2 - a\{-2,}
+OK 0 - a\{-,0}
+OK 1 - a\{-,0}
+OK 2 - a\{-,0}
+OK 0 - a\{-,5}
+OK 1 - a\{-,5}
+OK 2 - a\{-,5}
+OK 0 - a\{-,5}
+OK 1 - a\{-,5}
+OK 2 - a\{-,5}
+OK 0 - a\{-}
+OK 1 - a\{-}
+OK 2 - a\{-}
+OK 0 - a\{-}
+OK 1 - a\{-}
+OK 2 - a\{-}
+OK 0 - \(abc\)*
+OK 1 - \(abc\)*
+OK 2 - \(abc\)*
+OK 0 - \(ab\)\+
+OK 1 - \(ab\)\+
+OK 2 - \(ab\)\+
+OK 0 - \(abaaaaa\)*cd
+OK 1 - \(abaaaaa\)*cd
+OK 2 - \(abaaaaa\)*cd
+OK 0 - \(test1\)\? \(test2\)\?
+OK 1 - \(test1\)\? \(test2\)\?
+OK 2 - \(test1\)\? \(test2\)\?
+OK 0 - \(test1\)\= \(test2\) \(test4443\)\=
+OK 1 - \(test1\)\= \(test2\) \(test4443\)\=
+OK 2 - \(test1\)\= \(test2\) \(test4443\)\=
+OK 0 - \(\(sub1\) hello \(sub 2\)\)
+OK 1 - \(\(sub1\) hello \(sub 2\)\)
+OK 2 - \(\(sub1\) hello \(sub 2\)\)
+OK 0 - \(\(\(yyxxzz\)\)\)
+OK 1 - \(\(\(yyxxzz\)\)\)
+OK 2 - \(\(\(yyxxzz\)\)\)
+OK 0 - \v((ab)+|c+)+
+OK 1 - \v((ab)+|c+)+
+OK 2 - \v((ab)+|c+)+
+OK 0 - \v((ab)|c*)+
+OK 1 - \v((ab)|c*)+
+OK 2 - \v((ab)|c*)+
+OK 0 - \v(a(c*)+b)+
+OK 1 - \v(a(c*)+b)+
+OK 2 - \v(a(c*)+b)+
+OK 0 - \v(a|b*)+
+OK 1 - \v(a|b*)+
+OK 2 - \v(a|b*)+
+OK 0 - \p*
+OK 1 - \p*
+OK 2 - \p*
+OK 0 - a\{-2,7}
+OK 1 - a\{-2,7}
+OK 2 - a\{-2,7}
+OK 0 - a\{-2,7}x
+OK 1 - a\{-2,7}x
+OK 2 - a\{-2,7}x
+OK 0 - a\{2,7}
+OK 1 - a\{2,7}
+OK 2 - a\{2,7}
+OK 0 - a\{2,7}x
+OK 1 - a\{2,7}x
+OK 2 - a\{2,7}x
+OK 0 - \vx(.{-,8})yz(.*)
+OK 1 - \vx(.{-,8})yz(.*)
+OK 2 - \vx(.{-,8})yz(.*)
+OK 0 - \vx(.*)yz(.*)
+OK 1 - \vx(.*)yz(.*)
+OK 2 - \vx(.*)yz(.*)
+OK 0 - \v(a{1,2}){-2,3}
+OK 1 - \v(a{1,2}){-2,3}
+OK 2 - \v(a{1,2}){-2,3}
+OK 0 - \v(a{-1,3})+
+OK 1 - \v(a{-1,3})+
+OK 2 - \v(a{-1,3})+
+OK 0 - \d\+e\d\d
+OK 1 - \d\+e\d\d
+OK 2 - \d\+e\d\d
+OK 0 - \v[a]
+OK 1 - \v[a]
+OK 2 - \v[a]
+OK 0 - a[bcd]
+OK 1 - a[bcd]
+OK 2 - a[bcd]
+OK 0 - a[b-d]
+OK 1 - a[b-d]
+OK 2 - a[b-d]
+OK 0 - [a-d][e-f][x-x]d
+OK 1 - [a-d][e-f][x-x]d
+OK 2 - [a-d][e-f][x-x]d
+OK 0 - \v[[:alpha:]]+
+OK 1 - \v[[:alpha:]]+
+OK 2 - \v[[:alpha:]]+
+OK 0 - [[:alpha:]\+]
+OK 1 - [[:alpha:]\+]
+OK 2 - [[:alpha:]\+]
+OK 0 - [^abc]\+
+OK 1 - [^abc]\+
+OK 2 - [^abc]\+
+OK 0 - [^abc]
+OK 1 - [^abc]
+OK 2 - [^abc]
+OK 0 - [^abc]\+
+OK 1 - [^abc]\+
+OK 2 - [^abc]\+
+OK 0 - [^a-d]\+
+OK 1 - [^a-d]\+
+OK 2 - [^a-d]\+
+OK 0 - [a-f]*
+OK 1 - [a-f]*
+OK 2 - [a-f]*
+OK 0 - [a-f]*
+OK 1 - [a-f]*
+OK 2 - [a-f]*
+OK 0 - [^a-f]\+
+OK 1 - [^a-f]\+
+OK 2 - [^a-f]\+
+OK 0 - [a-c]\{-3,6}
+OK 1 - [a-c]\{-3,6}
+OK 2 - [a-c]\{-3,6}
+OK 0 - [^[:alpha:]]\+
+OK 1 - [^[:alpha:]]\+
+OK 2 - [^[:alpha:]]\+
+OK 0 - [-a]
+OK 1 - [-a]
+OK 2 - [-a]
+OK 0 - [a-]
+OK 1 - [a-]
+OK 2 - [a-]
+OK 0 - [a-f]*\c
+OK 1 - [a-f]*\c
+OK 2 - [a-f]*\c
+OK 0 - [abc][xyz]\c
+OK 1 - [abc][xyz]\c
+OK 2 - [abc][xyz]\c
+OK 0 - [-./[:alnum:]_~]\+
+OK 1 - [-./[:alnum:]_~]\+
+OK 2 - [-./[:alnum:]_~]\+
+OK 0 - [\]\^\-\\]\+
+OK 1 - [\]\^\-\\]\+
+OK 2 - [\]\^\-\\]\+
+OK 0 - [[.a.]]\+
+OK 1 - [[.a.]]\+
+OK 2 - [[.a.]]\+
+OK 0 - abc[0-9]*ddd
+OK 1 - abc[0-9]*ddd
+OK 2 - abc[0-9]*ddd
+OK 0 - abc[0-9]*ddd
+OK 1 - abc[0-9]*ddd
+OK 2 - abc[0-9]*ddd
+OK 0 - \_[0-9]\+
+OK 1 - \_[0-9]\+
+OK 2 - \_[0-9]\+
+OK 0 - [0-9\n]\+
+OK 1 - [0-9\n]\+
+OK 2 - [0-9\n]\+
+OK 0 - \_[0-9]\+
+OK 1 - \_[0-9]\+
+OK 2 - \_[0-9]\+
+OK 0 - \_f
+OK 1 - \_f
+OK 2 - \_f
+OK 0 - \_f\+
+OK 1 - \_f\+
+OK 2 - \_f\+
+OK 0 - [0-9A-Za-z-_.]\+
+OK 1 - [0-9A-Za-z-_.]\+
+OK 2 - [0-9A-Za-z-_.]\+
+OK 0 - ^a.
+OK 1 - ^a.
+OK 2 - ^a.
+OK 0 - ^a.
+OK 1 - ^a.
+OK 2 - ^a.
+OK 0 - .a$
+OK 1 - .a$
+OK 2 - .a$
+OK 0 - .a$
+OK 1 - .a$
+OK 2 - .a$
+OK 0 - \%^a.
+OK 1 - \%^a.
+OK 2 - \%^a.
+OK 0 - \%^a
+OK 1 - \%^a
+OK 2 - \%^a
+OK 0 - .a\%$
+OK 1 - .a\%$
+OK 2 - .a\%$
+OK 0 - .a\%$
+OK 1 - .a\%$
+OK 2 - .a\%$
+OK 0 - [0-7]\+
+OK 1 - [0-7]\+
+OK 2 - [0-7]\+
+OK 0 - [^0-7]\+
+OK 1 - [^0-7]\+
+OK 2 - [^0-7]\+
+OK 0 - [0-9]\+
+OK 1 - [0-9]\+
+OK 2 - [0-9]\+
+OK 0 - [^0-9]\+
+OK 1 - [^0-9]\+
+OK 2 - [^0-9]\+
+OK 0 - [0-9a-fA-F]\+
+OK 1 - [0-9a-fA-F]\+
+OK 2 - [0-9a-fA-F]\+
+OK 0 - [^0-9A-Fa-f]\+
+OK 1 - [^0-9A-Fa-f]\+
+OK 2 - [^0-9A-Fa-f]\+
+OK 0 - [a-z_A-Z0-9]\+
+OK 1 - [a-z_A-Z0-9]\+
+OK 2 - [a-z_A-Z0-9]\+
+OK 0 - [^a-z_A-Z0-9]\+
+OK 1 - [^a-z_A-Z0-9]\+
+OK 2 - [^a-z_A-Z0-9]\+
+OK 0 - [a-z_A-Z]\+
+OK 1 - [a-z_A-Z]\+
+OK 2 - [a-z_A-Z]\+
+OK 0 - [^a-z_A-Z]\+
+OK 1 - [^a-z_A-Z]\+
+OK 2 - [^a-z_A-Z]\+
+OK 0 - [a-z]\+
+OK 1 - [a-z]\+
+OK 2 - [a-z]\+
+OK 0 - [a-z]\+
+OK 1 - [a-z]\+
+OK 2 - [a-z]\+
+OK 0 - [^a-z]\+
+OK 1 - [^a-z]\+
+OK 2 - [^a-z]\+
+OK 0 - [^a-z]\+
+OK 1 - [^a-z]\+
+OK 2 - [^a-z]\+
+OK 0 - [a-zA-Z]\+
+OK 1 - [a-zA-Z]\+
+OK 2 - [a-zA-Z]\+
+OK 0 - [^a-zA-Z]\+
+OK 1 - [^a-zA-Z]\+
+OK 2 - [^a-zA-Z]\+
+OK 0 - [A-Z]\+
+OK 1 - [A-Z]\+
+OK 2 - [A-Z]\+
+OK 0 - [^A-Z]\+
+OK 1 - [^A-Z]\+
+OK 2 - [^A-Z]\+
+OK 0 - [a-z]\+\c
+OK 1 - [a-z]\+\c
+OK 2 - [a-z]\+\c
+OK 0 - [A-Z]\+\c
+OK 1 - [A-Z]\+\c
+OK 2 - [A-Z]\+\c
+OK 0 - \c[^a-z]\+
+OK 1 - \c[^a-z]\+
+OK 2 - \c[^a-z]\+
+OK 0 - \c[^A-Z]\+
+OK 1 - \c[^A-Z]\+
+OK 2 - \c[^A-Z]\+
+OK 0 - \C[^A-Z]\+
+OK 1 - \C[^A-Z]\+
+OK 2 - \C[^A-Z]\+
+OK 0 - xx \ze test
+OK 1 - xx \ze test
+OK 2 - xx \ze test
+OK 0 - abc\zeend
+OK 1 - abc\zeend
+OK 2 - abc\zeend
+OK 0 - aa\zebb\|aaxx
+OK 1 - aa\zebb\|aaxx
+OK 2 - aa\zebb\|aaxx
+OK 0 - aa\zebb\|aaxx
+OK 1 - aa\zebb\|aaxx
+OK 2 - aa\zebb\|aaxx
+OK 0 - aabb\|aa\zebb
+OK 1 - aabb\|aa\zebb
+OK 2 - aabb\|aa\zebb
+OK 0 - aa\zebb\|aaebb
+OK 1 - aa\zebb\|aaebb
+OK 2 - aa\zebb\|aaebb
+OK 0 - abc\zsdd
+OK 1 - abc\zsdd
+OK 2 - abc\zsdd
+OK 0 - aa \zsax
+OK 1 - aa \zsax
+OK 2 - aa \zsax
+OK 0 - abc \zsmatch\ze abc
+OK 1 - abc \zsmatch\ze abc
+OK 2 - abc \zsmatch\ze abc
+OK 0 - \v(a \zsif .*){2}
+OK 1 - \v(a \zsif .*){2}
+OK 2 - \v(a \zsif .*){2}
+OK 0 - \>\zs.
+OK 1 - \>\zs.
+OK 2 - \>\zs.
+OK 0 - \s\+\ze\[/\|\s\zs\s\+
+OK 1 - \s\+\ze\[/\|\s\zs\s\+
+OK 2 - \s\+\ze\[/\|\s\zs\s\+
+OK 0 - abc\@=
+OK 1 - abc\@=
+OK 2 - abc\@=
+OK 0 - abc\@=cd
+OK 1 - abc\@=cd
+OK 2 - abc\@=cd
+OK 0 - abc\@=
+OK 1 - abc\@=
+OK 2 - abc\@=
+OK 0 - abcd\@=e
+OK 1 - abcd\@=e
+OK 2 - abcd\@=e
+OK 0 - abcd\@=e
+OK 1 - abcd\@=e
+OK 2 - abcd\@=e
+OK 0 - \v(abc)@=..
+OK 1 - \v(abc)@=..
+OK 2 - \v(abc)@=..
+OK 0 - \(.*John\)\@=.*Bob
+OK 1 - \(.*John\)\@=.*Bob
+OK 2 - \(.*John\)\@=.*Bob
+OK 0 - \(John.*\)\@=.*Bob
+OK 1 - \(John.*\)\@=.*Bob
+OK 2 - \(John.*\)\@=.*Bob
+OK 0 - \<\S\+\())\)\@=
+OK 1 - \<\S\+\())\)\@=
+OK 2 - \<\S\+\())\)\@=
+OK 0 - .*John\&.*Bob
+OK 1 - .*John\&.*Bob
+OK 2 - .*John\&.*Bob
+OK 0 - .*John\&.*Bob
+OK 1 - .*John\&.*Bob
+OK 2 - .*John\&.*Bob
+OK 0 - \v(test1)@=.*yep
+OK 1 - \v(test1)@=.*yep
+OK 2 - \v(test1)@=.*yep
+OK 0 - foo\(bar\)\@!
+OK 1 - foo\(bar\)\@!
+OK 2 - foo\(bar\)\@!
+OK 0 - foo\(bar\)\@!
+OK 1 - foo\(bar\)\@!
+OK 2 - foo\(bar\)\@!
+OK 0 - if \(\(then\)\@!.\)*$
+OK 1 - if \(\(then\)\@!.\)*$
+OK 2 - if \(\(then\)\@!.\)*$
+OK 0 - if \(\(then\)\@!.\)*$
+OK 1 - if \(\(then\)\@!.\)*$
+OK 2 - if \(\(then\)\@!.\)*$
+OK 0 - \(foo\)\@!bar
+OK 1 - \(foo\)\@!bar
+OK 2 - \(foo\)\@!bar
+OK 0 - \(foo\)\@!...bar
+OK 1 - \(foo\)\@!...bar
+OK 2 - \(foo\)\@!...bar
+OK 0 - ^\%(.*bar\)\@!.*\zsfoo
+OK 1 - ^\%(.*bar\)\@!.*\zsfoo
+OK 2 - ^\%(.*bar\)\@!.*\zsfoo
+OK 0 - ^\%(.*bar\)\@!.*\zsfoo
+OK 1 - ^\%(.*bar\)\@!.*\zsfoo
+OK 2 - ^\%(.*bar\)\@!.*\zsfoo
+OK 0 - ^\%(.*bar\)\@!.*\zsfoo
+OK 1 - ^\%(.*bar\)\@!.*\zsfoo
+OK 2 - ^\%(.*bar\)\@!.*\zsfoo
+OK 0 - [ ]\@!\p\%([ ]\@!\p\)*:
+OK 1 - [ ]\@!\p\%([ ]\@!\p\)*:
+OK 2 - [ ]\@!\p\%([ ]\@!\p\)*:
+OK 0 - [ ]\@!\p\([ ]\@!\p\)*:
+OK 1 - [ ]\@!\p\([ ]\@!\p\)*:
+OK 2 - [ ]\@!\p\([ ]\@!\p\)*:
+OK 0 - m\k\+_\@=\%(_\@!\k\)\@<=\k\+e
+OK 1 - m\k\+_\@=\%(_\@!\k\)\@<=\k\+e
+OK 2 - m\k\+_\@=\%(_\@!\k\)\@<=\k\+e
+OK 0 - \%(\U\@<=S\k*\|S\l\)R
+OK 1 - \%(\U\@<=S\k*\|S\l\)R
+OK 2 - \%(\U\@<=S\k*\|S\l\)R
+OK 0 - [[:alpha:]]\{-2,6}
+OK 1 - [[:alpha:]]\{-2,6}
+OK 2 - [[:alpha:]]\{-2,6}
+OK 0 -
+OK 1 -
+OK 2 -
+OK 0 - \v(())
+OK 1 - \v(())
+OK 2 - \v(())
+OK 0 - \v%(ab(xyz)c)
+OK 1 - \v%(ab(xyz)c)
+OK 2 - \v%(ab(xyz)c)
+OK 0 - \v(test|)empty
+OK 1 - \v(test|)empty
+OK 2 - \v(test|)empty
+OK 0 - \v(a|aa)(a|aa)
+OK 1 - \v(a|aa)(a|aa)
+OK 2 - \v(a|aa)(a|aa)
+OK 0 - \%d32
+OK 1 - \%d32
+OK 2 - \%d32
+OK 0 - \%o40
+OK 1 - \%o40
+OK 2 - \%o40
+OK 0 - \%x20
+OK 1 - \%x20
+OK 2 - \%x20
+OK 0 - \%u0020
+OK 1 - \%u0020
+OK 2 - \%u0020
+OK 0 - \%U00000020
+OK 1 - \%U00000020
+OK 2 - \%U00000020
+OK 0 - \%d0
+OK 1 - \%d0
+OK 2 - \%d0
+OK 0 - foo\%[bar]
+OK 1 - foo\%[bar]
+OK 2 - foo\%[bar]
+OK 0 - foo\%[bar]
+OK 1 - foo\%[bar]
+OK 2 - foo\%[bar]
+OK 0 - foo\%[bar]
+OK 1 - foo\%[bar]
+OK 2 - foo\%[bar]
+OK 0 - foo\%[bar]
+OK 1 - foo\%[bar]
+OK 2 - foo\%[bar]
+OK 0 - foo\%[bar]
+OK 1 - foo\%[bar]
+OK 2 - foo\%[bar]
+OK 0 - foo\%[bar]
+OK 1 - foo\%[bar]
+OK 2 - foo\%[bar]
+OK 0 - foo\%[bar]x
+OK 1 - foo\%[bar]x
+OK 2 - foo\%[bar]x
+OK 0 - foo\%[bar]x
+OK 1 - foo\%[bar]x
+OK 2 - foo\%[bar]x
+OK 0 - \%[bar]x
+OK 1 - \%[bar]x
+OK 2 - \%[bar]x
+OK 0 - \%[bar]x
+OK 1 - \%[bar]x
+OK 2 - \%[bar]x
+OK 0 - \%[bar]x
+OK 1 - \%[bar]x
+OK 2 - \%[bar]x
+OK 0 - b\%[[ao]r]
+OK 1 - b\%[[ao]r]
+OK 2 - b\%[[ao]r]
+OK 0 - b\%[[]]r]
+OK 1 - b\%[[]]r]
+OK 2 - b\%[[]]r]
+OK 0 - @\%[\w\-]*
+OK 1 - @\%[\w\-]*
+OK 2 - @\%[\w\-]*
+OK 0 - goo\|go
+OK 1 - goo\|go
+OK 2 - goo\|go
+OK 0 - \<goo\|\<go
+OK 1 - \<goo\|\<go
+OK 2 - \<goo\|\<go
+OK 0 - \<goo\|go
+OK 1 - \<goo\|go
+OK 2 - \<goo\|go
+OK 0 - \(\i\+\) \1
+OK 1 - \(\i\+\) \1
+OK 2 - \(\i\+\) \1
+OK 0 - \(\i\+\) \1
+OK 1 - \(\i\+\) \1
+OK 2 - \(\i\+\) \1
+OK 0 - \(a\)\(b\)\(c\)\(dd\)\(e\)\(f\)\(g\)\(h\)\(i\)\1\2\3\4\5\6\7\8\9
+OK 1 - \(a\)\(b\)\(c\)\(dd\)\(e\)\(f\)\(g\)\(h\)\(i\)\1\2\3\4\5\6\7\8\9
+OK 2 - \(a\)\(b\)\(c\)\(dd\)\(e\)\(f\)\(g\)\(h\)\(i\)\1\2\3\4\5\6\7\8\9
+OK 0 - \(\d*\)a \1b
+OK 1 - \(\d*\)a \1b
+OK 2 - \(\d*\)a \1b
+OK 0 - ^.\(.\).\_..\1.
+OK 1 - ^.\(.\).\_..\1.
+OK 2 - ^.\(.\).\_..\1.
+OK 0 - ^.*\.\(.*\)/.\+\(\1\)\@<!$
+OK 1 - ^.*\.\(.*\)/.\+\(\1\)\@<!$
+OK 2 - ^.*\.\(.*\)/.\+\(\1\)\@<!$
+OK 0 - ^.*\.\(.*\)/.\+\(\1\)\@<!$
+OK 1 - ^.*\.\(.*\)/.\+\(\1\)\@<!$
+OK 2 - ^.*\.\(.*\)/.\+\(\1\)\@<!$
+OK 0 - ^.*\.\(.*\)/.\+\(\1\)\@<=$
+OK 1 - ^.*\.\(.*\)/.\+\(\1\)\@<=$
+OK 2 - ^.*\.\(.*\)/.\+\(\1\)\@<=$
+OK 0 - \\\@<!\${\(\d\+\%(:.\{-}\)\?\\\@<!\)}
+OK 1 - \\\@<!\${\(\d\+\%(:.\{-}\)\?\\\@<!\)}
+OK 2 - \\\@<!\${\(\d\+\%(:.\{-}\)\?\\\@<!\)}
+OK 0 - ^\(a*\)\1$
+OK 1 - ^\(a*\)\1$
+OK 2 - ^\(a*\)\1$
+OK 0 - <\@<=span.
+OK 1 - <\@<=span.
+OK 2 - <\@<=span.
+OK 0 - <\@1<=span.
+OK 1 - <\@1<=span.
+OK 2 - <\@1<=span.
+OK 0 - <\@2<=span.
+OK 1 - <\@2<=span.
+OK 2 - <\@2<=span.
+OK 0 - \(<<\)\@<=span.
+OK 1 - \(<<\)\@<=span.
+OK 2 - \(<<\)\@<=span.
+OK 0 - \(<<\)\@1<=span.
+OK 1 - \(<<\)\@1<=span.
+OK 2 - \(<<\)\@1<=span.
+OK 0 - \(<<\)\@2<=span.
+OK 1 - \(<<\)\@2<=span.
+OK 2 - \(<<\)\@2<=span.
+OK 0 - \(foo\)\@<!bar.
+OK 1 - \(foo\)\@<!bar.
+OK 2 - \(foo\)\@<!bar.
+OK 0 - \v\C%(<Last Changed:\s+)@<=.*$
+OK 1 - \v\C%(<Last Changed:\s+)@<=.*$
+OK 2 - \v\C%(<Last Changed:\s+)@<=.*$
+OK 0 - \v\C%(<Last Changed:\s+)@<=.*$
+OK 1 - \v\C%(<Last Changed:\s+)@<=.*$
+OK 2 - \v\C%(<Last Changed:\s+)@<=.*$
+OK 0 - \(foo\)\@<=\>
+OK 1 - \(foo\)\@<=\>
+OK 2 - \(foo\)\@<=\>
+OK 0 - \(foo\)\@<=\>
+OK 1 - \(foo\)\@<=\>
+OK 2 - \(foo\)\@<=\>
+OK 0 - \(foo\)\@<=.*
+OK 1 - \(foo\)\@<=.*
+OK 2 - \(foo\)\@<=.*
+OK 0 - \(r\@<=\|\w\@<!\)\/
+OK 1 - \(r\@<=\|\w\@<!\)\/
+OK 2 - \(r\@<=\|\w\@<!\)\/
+OK 0 - ^[a-z]\+\ze \&\(asdf\)\@<!
+OK 1 - ^[a-z]\+\ze \&\(asdf\)\@<!
+OK 2 - ^[a-z]\+\ze \&\(asdf\)\@<!
+OK 0 - \(a*\)\@>a
+OK 1 - \(a*\)\@>a
+OK 2 - \(a*\)\@>a
+OK 0 - \(a*\)\@>b
+OK 1 - \(a*\)\@>b
+OK 2 - \(a*\)\@>b
+OK 0 - ^\(.\{-}b\)\@>.
+OK 1 - ^\(.\{-}b\)\@>.
+OK 2 - ^\(.\{-}b\)\@>.
+OK 0 - \(.\{-}\)\(\)\@>$
+OK 1 - \(.\{-}\)\(\)\@>$
+OK 2 - \(.\{-}\)\(\)\@>$
+OK 0 - \(a*\)\@>a\|a\+
+OK 2 - \(a*\)\@>a\|a\+
+OK 0 - \_[^8-9]\+
+OK 1 - \_[^8-9]\+
+OK 2 - \_[^8-9]\+
+OK 0 - \_[^a]\+
+OK 1 - \_[^a]\+
+OK 2 - \_[^a]\+
+OK 0 - [0-9a-zA-Z]\{8}-\([0-9a-zA-Z]\{4}-\)\{3}[0-9a-zA-Z]\{12}
+OK 1 - [0-9a-zA-Z]\{8}-\([0-9a-zA-Z]\{4}-\)\{3}[0-9a-zA-Z]\{12}
+OK 2 - [0-9a-zA-Z]\{8}-\([0-9a-zA-Z]\{4}-\)\{3}[0-9a-zA-Z]\{12}
+OK 0 - ^\%(\%(^\s*#\s*if\>\|#\s*if\)\)\(\%>1c.*$\)\@=
+OK 1 - ^\%(\%(^\s*#\s*if\>\|#\s*if\)\)\(\%>1c.*$\)\@=
+OK 2 - ^\%(\%(^\s*#\s*if\>\|#\s*if\)\)\(\%>1c.*$\)\@=
+multi-line tests
+OK 0 - ^.\(.\).\_..\1.
+OK 1 - ^.\(.\).\_..\1.
+OK 2 - ^.\(.\).\_..\1.
+OK 0 - \v.*\/(.*)\n.*\/\1$
+OK 1 - \v.*\/(.*)\n.*\/\1$
+OK 2 - \v.*\/(.*)\n.*\/\1$
+OK 0 - \S.*\nx
+OK 1 - \S.*\nx
+OK 2 - \S.*\nx
+OK 0 - \<\(\(25\_[0-5]\|2\_[0-4]\_[0-9]\|\_[01]\?\_[0-9]\_[0-9]\?\)\.\)\{3\}\(25\_[0-5]\|2\_[0-4]\_[0-9]\|\_[01]\?\_[0-9]\_[0-9]\?\)\>
+OK 1 - \<\(\(25\_[0-5]\|2\_[0-4]\_[0-9]\|\_[01]\?\_[0-9]\_[0-9]\?\)\.\)\{3\}\(25\_[0-5]\|2\_[0-4]\_[0-9]\|\_[01]\?\_[0-9]\_[0-9]\?\)\>
+OK 2 - \<\(\(25\_[0-5]\|2\_[0-4]\_[0-9]\|\_[01]\?\_[0-9]\_[0-9]\?\)\.\)\{3\}\(25\_[0-5]\|2\_[0-4]\_[0-9]\|\_[01]\?\_[0-9]\_[0-9]\?\)\>
+OK 0 - a\n^b$\n^c
+OK 1 - a\n^b$\n^c
+OK 2 - a\n^b$\n^c
+OK 0 - \(^.\+\n\)\1
+OK 1 - \(^.\+\n\)\1
+OK 2 - \(^.\+\n\)\1
+
+<T="5">Ta 5</Title>
+<T="7">Ac 7</Title>
+
+xxstart3
+
+thexE thE thExethe
+AndAxAnd AndAxAnd
+oooxOfOr fOrOxooo
+oooxOfOr fOrOxooo
+
+asdfhereasdf
+asdfagainasdf
+
+-0-
+ffo
+bob
+__ooooo
+koooo__
+moooooo
+ f__
+ab!babababababfoo
+ba!ab##abab?bafoo
+**!*****_
+-1-
+ffo
+bob
+__ooooo
+koooo__
+moooooo
+ f__
+ab!babababababfoo
+ba!ab##abab?bafoo
+**!*****_
+-2-
+ffo
+bob
+__ooooo
+koooo__
+moooooo
+ f__
+ab!babababababfoo
+ba!ab##abab?bafoo
+**!*****_
+Test
+Test END
+EN
+E
diff --git a/src/testdir/test65.in b/src/testdir/test65.in
new file mode 100644
index 0000000000..ca53f27555
--- /dev/null
+++ b/src/testdir/test65.in
@@ -0,0 +1,95 @@
+Test for floating point and logical operators.
+
+STARTTEST
+:so small.vim
+:if !has("float")
+: e! test.ok
+: wq! test.out
+:endif
+:"
+:$put =printf('%f', 123.456)
+:$put =printf('%e', 123.456)
+:$put =printf('%g', 123.456)
+:" check we don't crash on division by zero
+:echo 1.0 / 0.0
+:$put ='+='
+:let v = 1.234
+:let v += 6.543
+:$put =printf('%g', v)
+:let v = 1.234
+:let v += 5
+:$put =printf('%g', v)
+:let a = 5
+:let a += 3.333
+:$put =string(a)
+:$put ='=='
+:let v = 1.234
+:$put =v == 1.234
+:$put =v == 1.2341
+:$put ='add-subtract'
+:$put =printf('%g', 4 + 1.234)
+:$put =printf('%g', 1.234 - 8)
+:$put ='mult-div'
+:$put =printf('%g', 4 * 1.234)
+:$put =printf('%g', 4.0 / 1234)
+:$put ='dict'
+:$put =string({'x': 1.234, 'y': -2.0e20})
+:$put ='list'
+:$put =string([-123.4, 2.0e-20])
+:$put ='abs'
+:$put =printf('%d', abs(1456))
+:$put =printf('%d', abs(-4))
+:$put =printf('%d', abs([1, 2, 3]))
+:$put =printf('%g', abs(14.56))
+:$put =printf('%g', abs(-54.32))
+:$put ='ceil'
+:$put =printf('%g', ceil(1.456))
+:$put =printf('%g', ceil(-5.456))
+:$put =printf('%g', ceil(-4.000))
+:$put ='floor'
+:$put =printf('%g', floor(1.856))
+:$put =printf('%g', floor(-5.456))
+:$put =printf('%g', floor(4.0))
+:$put ='log10'
+:$put =printf('%g', log10(1000))
+:$put =printf('%g', log10(0.01000))
+:$put ='pow'
+:$put =printf('%g', pow(3, 3.0))
+:$put =printf('%g', pow(2, 16))
+:$put ='round'
+:$put =printf('%g', round(0.456))
+:$put =printf('%g', round(4.5))
+:$put =printf('%g', round(-4.50))
+:$put ='sqrt'
+:$put =printf('%g', sqrt(100))
+:echo sqrt(-4.01)
+:$put ='str2float'
+:$put =printf('%g', str2float('1e40'))
+:$put ='trunc'
+:$put =printf('%g', trunc(1.456))
+:$put =printf('%g', trunc(-5.456))
+:$put =printf('%g', trunc(4.000))
+:$put ='float2nr'
+:$put =float2nr(123.456)
+:$put =float2nr(-123.456)
+:$put ='AND'
+:$put =and(127, 127)
+:$put =and(127, 16)
+:$put =and(127, 128)
+:$put ='OR'
+:$put =or(16, 7)
+:$put =or(8, 7)
+:$put =or(0, 123)
+:$put ='XOR'
+:$put =xor(127, 127)
+:$put =xor(127, 16)
+:$put =xor(127, 128)
+:$put ='invert'
+:$put =and(invert(127), 65535)
+:$put =and(invert(16), 65535)
+:$put =and(invert(128), 65535)
+:$put =invert(1.0)
+:/^Results/,$wq! test.out
+ENDTEST
+
+Results of test65:
diff --git a/src/testdir/test65.ok b/src/testdir/test65.ok
new file mode 100644
index 0000000000..7aac326058
--- /dev/null
+++ b/src/testdir/test65.ok
@@ -0,0 +1,73 @@
+Results of test65:
+123.456000
+1.234560e+02
+123.456
++=
+7.777
+6.234
+8.333
+==
+1
+0
+add-subtract
+5.234
+-6.766
+mult-div
+4.936
+0.003241
+dict
+{'x': 1.234, 'y': -2.0e20}
+list
+[-123.4, 2.0e-20]
+abs
+1456
+4
+-1
+14.56
+54.32
+ceil
+2.0
+-5.0
+-4.0
+floor
+1.0
+-6.0
+4.0
+log10
+3.0
+-2.0
+pow
+27.0
+65536.0
+round
+0.0
+5.0
+-5.0
+sqrt
+10.0
+str2float
+1.0e40
+trunc
+1.0
+-5.0
+4.0
+float2nr
+123
+-123
+AND
+127
+16
+0
+OR
+23
+15
+123
+XOR
+0
+111
+255
+invert
+65408
+65519
+65407
+0
diff --git a/src/testdir/test66.in b/src/testdir/test66.in
new file mode 100644
index 0000000000..f1fdce3792
--- /dev/null
+++ b/src/testdir/test66.in
@@ -0,0 +1,33 @@
+
+Test for visual block shift and tab characters.
+
+STARTTEST
+:so small.vim
+/^one
+fe4jRugvr1:'<,'>w! test.out
+/^abcdefgh
+4jI j<<11|D
+7|a 
+7|a 
+7|a 4k13|4j<
+:$-5,$w >> test.out
+:$-4,$s/\s\+//g
+4kI j<<
+7|a 
+7|a 
+7|a 4k13|4j3<
+:$-4,$w >> test.out
+:qa!
+ENDTEST
+
+one two three
+one two three
+one two three
+one two three
+one two three
+
+abcdefghijklmnopqrstuvwxyz
+abcdefghijklmnopqrstuvwxyz
+abcdefghijklmnopqrstuvwxyz
+abcdefghijklmnopqrstuvwxyz
+abcdefghijklmnopqrstuvwxyz
diff --git a/src/testdir/test66.ok b/src/testdir/test66.ok
new file mode 100644
index 0000000000..4c3ab0fb56
--- /dev/null
+++ b/src/testdir/test66.ok
@@ -0,0 +1,16 @@
+on1 two three
+on1 two three
+on1 two three
+on1 two three
+on1 two three
+
+ abcdefghijklmnopqrstuvwxyz
+abcdefghij
+ abc defghijklmnopqrstuvwxyz
+ abc defghijklmnopqrstuvwxyz
+ abc defghijklmnopqrstuvwxyz
+ abcdefghijklmnopqrstuvwxyz
+abcdefghij
+ abc defghijklmnopqrstuvwxyz
+ abc defghijklmnopqrstuvwxyz
+ abc defghijklmnopqrstuvwxyz
diff --git a/src/testdir/test67.in b/src/testdir/test67.in
new file mode 100644
index 0000000000..08b4e3701f
--- /dev/null
+++ b/src/testdir/test67.in
@@ -0,0 +1,33 @@
+Test that groups and patterns are tested correctly when calling exists() for
+autocommands.
+
+STARTTEST
+:so small.vim
+:let results=[]
+:augroup auexists
+:augroup END
+:call add(results, "##BufEnter: " . exists("##BufEnter"))
+:call add(results, "#BufEnter: " . exists("#BufEnter"))
+:au BufEnter * let g:entered=1
+:call add(results, "#BufEnter: " . exists("#BufEnter"))
+:call add(results, "#auexists#BufEnter: " . exists("#auexists#BufEnter"))
+:augroup auexists
+:au BufEnter * let g:entered=1
+:augroup END
+:call add(results, "#auexists#BufEnter: " . exists("#auexists#BufEnter"))
+:call add(results, "#BufEnter#*.test: " . exists("#BufEnter#*.test"))
+:au BufEnter *.test let g:entered=1
+:call add(results, "#BufEnter#*.test: " . exists("#BufEnter#*.test"))
+:edit testfile.test
+:call add(results, "#BufEnter#<buffer>: " . exists("#BufEnter#<buffer>"))
+:au BufEnter <buffer> let g:entered=1
+:call add(results, "#BufEnter#<buffer>: " . exists("#BufEnter#<buffer>"))
+:edit testfile2.test
+:call add(results, "#BufEnter#<buffer>: " . exists("#BufEnter#<buffer>"))
+:e test.out
+:call append(0, results)
+:$d
+:w
+:qa!
+ENDTEST
+
diff --git a/src/testdir/test67.ok b/src/testdir/test67.ok
new file mode 100644
index 0000000000..51188e5afd
--- /dev/null
+++ b/src/testdir/test67.ok
@@ -0,0 +1,10 @@
+##BufEnter: 1
+#BufEnter: 0
+#BufEnter: 1
+#auexists#BufEnter: 0
+#auexists#BufEnter: 1
+#BufEnter#*.test: 0
+#BufEnter#*.test: 1
+#BufEnter#<buffer>: 0
+#BufEnter#<buffer>: 1
+#BufEnter#<buffer>: 0
diff --git a/src/testdir/test68.in b/src/testdir/test68.in
new file mode 100644
index 0000000000..ceaf9af1ab
--- /dev/null
+++ b/src/testdir/test68.in
@@ -0,0 +1,131 @@
+Test for text formatting.
+
+Results of test68:
+
+STARTTEST
+:so small.vim
+/^{/+1
+:set noai tw=2 fo=t
+gRa b
+ENDTEST
+
+{
+
+
+}
+
+STARTTEST
+/^{/+1
+:set ai tw=2 fo=tw
+gqgqjjllab
+ENDTEST
+
+{
+a b
+
+a
+}
+
+STARTTEST
+/^{/+1
+:set tw=3 fo=t
+gqgqo
+a 
+ENDTEST
+
+{
+a 
+}
+
+STARTTEST
+/^{/+1
+:set tw=2 fo=tcq1 comments=:#
+gqgqjgqgqo
+a b
+#a b
+ENDTEST
+
+{
+a b
+#a b
+}
+
+STARTTEST
+/^{/+1
+:set tw=5 fo=tcn comments=:#
+A bjA b
+ENDTEST
+
+{
+ 1 a
+# 1 a
+}
+
+STARTTEST
+/^{/+3
+:set tw=5 fo=t2a si
+i A_
+ENDTEST
+
+{
+
+ x a
+ b
+ c
+
+}
+
+STARTTEST
+/^{/+1
+:set tw=5 fo=qn comments=:#
+gwap
+ENDTEST
+
+{
+# 1 a b
+}
+
+STARTTEST
+/^{/+1
+:set tw=5 fo=q2 comments=:#
+gwap
+ENDTEST
+
+{
+# x
+# a b
+}
+
+STARTTEST
+/^{/+2
+:set tw& fo=a
+I^^
+ENDTEST
+
+{
+ 1aa
+ 2bb
+}
+
+STARTTEST
+/mno pqr/
+:setl tw=20 fo=an12wcq comments=s1:/*,mb:*,ex:*/
+A vwx yz
+ENDTEST
+
+/* abc def ghi jkl
+ * mno pqr stu
+ */
+
+STARTTEST
+/^#/
+:setl tw=12 fo=tqnc comments=:#
+A foobar
+ENDTEST
+
+# 1 xxxxx
+
+STARTTEST
+:g/^STARTTEST/.,/^ENDTEST/d
+:1;/^Results/,$wq! test.out
+ENDTEST
diff --git a/src/testdir/test68.ok b/src/testdir/test68.ok
new file mode 100644
index 0000000000..b3726a0a27
--- /dev/null
+++ b/src/testdir/test68.ok
@@ -0,0 +1,77 @@
+Results of test68:
+
+
+{
+a
+b
+}
+
+
+{
+a
+b
+
+a
+b
+}
+
+
+{
+a
+
+
+a
+
+}
+
+
+{
+a b
+#a b
+
+a b
+#a b
+}
+
+
+{
+ 1 a
+ b
+# 1 a
+# b
+}
+
+
+{
+
+ x a
+ b_
+ c
+
+}
+
+
+{
+# 1 a
+# b
+}
+
+
+{
+# x a
+# b
+}
+
+
+{ 1aa ^^2bb }
+
+
+/* abc def ghi jkl
+ * mno pqr stu
+ * vwx yz
+ */
+
+
+# 1 xxxxx
+# foobar
+
diff --git a/src/testdir/test69.in b/src/testdir/test69.in
new file mode 100644
index 0000000000..f18ee37905
--- /dev/null
+++ b/src/testdir/test69.in
@@ -0,0 +1,175 @@
+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
+:so mbyte.vim
+:set encoding=utf-8
+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
+: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
+:g/^STARTTEST/.,/^ENDTEST/d
+:1;/^Results/,$wq! test.out
+ENDTEST
diff --git a/src/testdir/test69.ok b/src/testdir/test69.ok
new file mode 100644
index 0000000000..1ff82f26bc
--- /dev/null
+++ b/src/testdir/test69.ok
@@ -0,0 +1,159 @@
+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
+
+
+byteidx
+[0, 1, 3, 4, -1]
+[0, 1, 4, 5, -1]
+byteidxcomp
+[0, 1, 3, 4, -1]
+[0, 1, 2, 4, 5, -1]
+
diff --git a/src/testdir/test7.in b/src/testdir/test7.in
new file mode 100644
index 0000000000..b9cc0585f6
--- /dev/null
+++ b/src/testdir/test7.in
@@ -0,0 +1,26 @@
+Test for autocommand that changes the buffer list, when doing ":ball".
+
+STARTTEST
+:so small.vim
+/^start of
+A1:.,/end of/w! Xxx1 " write test file Xxx1
+:sp Xxx1
+:close
+$r2:.,/end of/w! Xxx2 " write test file Xxx2
+:sp Xxx2
+:close
+$r3:.,/end of/w! Xxx3 " write test file Xxx3
+:sp Xxx3
+:close
+:au BufReadPost Xxx2 bwipe
+$r4:ball " open window for all args, close Xxx2
+:.,$w! test.out " Write contents of this file
+:w >>test.out " Append contents of second window (Xxx1)
+:/^start of/,$w >>test.out " Append contents of last window (this file)
+:qa!
+ENDTEST
+
+start of test file Xxx
+ this is a test
+ this is a test
+end of test file Xxx
diff --git a/src/testdir/test7.ok b/src/testdir/test7.ok
new file mode 100644
index 0000000000..a0d1ff94a3
--- /dev/null
+++ b/src/testdir/test7.ok
@@ -0,0 +1,12 @@
+start of test file Xxx4
+ this is a test
+ this is a test
+end of test file Xxx
+start of test file Xxx1
+ this is a test
+ this is a test
+end of test file Xxx
+start of test file Xxx4
+ this is a test
+ this is a test
+end of test file Xxx
diff --git a/src/testdir/test70.in b/src/testdir/test70.in
new file mode 100644
index 0000000000..9fbe818b3d
--- /dev/null
+++ b/src/testdir/test70.in
@@ -0,0 +1,63 @@
+Smoke test for MzScheme interface and mzeval() function
+
+STARTTEST
+:so mzscheme.vim
+:set nocompatible viminfo+=nviminfo
+:function! MzRequire()
+:redir => l:mzversion
+:mz (version)
+:redir END
+:if strpart(l:mzversion, 1, 1) < "4"
+:" MzScheme versions < 4.x:
+:mz (require (prefix vim- vimext))
+:else
+:" newer versions:
+:mz (require (prefix-in vim- 'vimext))
+:mz (require r5rs)
+:endif
+:endfunction
+:silent call MzRequire()
+:mz (define l '("item0" "dictionary with list OK" "item2"))
+:mz (define h (make-hash))
+:mz (hash-set! h "list" l)
+/^1
+:" change buffer contents
+:mz (vim-set-buff-line (vim-eval "line('.')") "1 changed line 1")
+:" scalar test
+:let tmp_string = mzeval('"string"')
+:let tmp_1000 = mzeval('1000')
+:if tmp_string . tmp_1000 == "string1000"
+:let scalar_res = "OK"
+:else
+:let scalar_res = "FAILED"
+:endif
+:call append(search("^1"), "scalar test " . scalar_res)
+:" dictionary containing a list
+:let tmp = mzeval("h")["list"][1]
+:/^2/put =tmp
+:" circular list (at the same time test lists containing lists)
+:mz (set-car! (cddr l) l)
+:let l2 = mzeval("h")["list"]
+:if l2[2] == l2
+:let res = "OK"
+:else
+:let res = "FAILED: " . l2[2]
+:endif
+:call setline(search("^3"), "circular test " . res)
+:" funcrefs
+:mz (define vim:max (vim-eval "function('max')"))
+:mz (define m (vim:max '(1 100 8)))
+:let m = mzeval('m')
+:if m == 100
+:let fref_res = "OK"
+:else
+:let fref_res = "FAILED: " . m
+:end
+:call append(line('$'), 'funcrefs '. fref_res)
+:?^1?,$w! test.out
+:qa!
+ENDTEST
+
+1 line 1
+2 line 2
+3 line 3
diff --git a/src/testdir/test70.ok b/src/testdir/test70.ok
new file mode 100644
index 0000000000..9c82a86f2d
--- /dev/null
+++ b/src/testdir/test70.ok
@@ -0,0 +1,6 @@
+1 changed line 1
+scalar test OK
+2 line 2
+dictionary with list OK
+circular test OK
+funcrefs OK
diff --git a/src/testdir/test71.in b/src/testdir/test71.in
new file mode 100644
index 0000000000..155fd413bc
--- /dev/null
+++ b/src/testdir/test71.in
@@ -0,0 +1,67 @@
+Test for encryption.
+The test data is in another file to avoid problems with 'encoding', especially
+cp932.
+
+STARTTEST
+:so small.vim
+:set enc=latin1
+:bwipe!
+:r test71a.in
+:/^start of text/+1
+:let text_lines = getline('.', line('.') + 2)
+:/^start of cm=zip bytes/+1
+:let cm0_bytes = getline('.', '.')
+:/^start of cm=blowfish bytes/+1
+:let cm1_bytes = getline('.', '.')
+:bwipe!
+:call append(0, text_lines)
+:$d
+:X
+foobar
+foobar
+:w! Xtestfile
+:bwipe!
+:e Xtestfile
+foobar
+:let cm0_read_back = getline('.', '$')
+:set key=
+:set cryptmethod=blowfish
+:" If the blowfish test fails 'cryptmethod' will be 'zip' now.
+:%s/^/\=&cryptmethod == 'blowfish' ? "OK " : "blowfish test failed "/
+:X
+barfoo
+barfoo
+:w! Xtestfile
+:bwipe!
+:e Xtestfile
+barfoo
+:let cm1_read_back = getline('.', '$')
+:bwipe!
+:set bin noeol key=
+:call append(0, cm0_bytes)
+:$d
+:set fenc=latin1
+:w! Xtestfile
+:bwipe!
+:set nobin
+:e Xtestfile
+foofoo
+:let cm0_read_bin = getline('.', '$')
+:bwipe!
+:set bin noeol key=
+:call append(0, cm1_bytes)
+:$d
+:set fenc=latin1
+:w! Xtestfile
+:bwipe!
+:set nobin
+:e Xtestfile
+barbar
+:call append(0, cm0_read_bin)
+:call append(0, cm1_read_back)
+:call append(0, cm0_read_back)
+:set key= fenc=latin1
+:w! test.out
+:qa!
+ENDTEST
+
diff --git a/src/testdir/test71.ok b/src/testdir/test71.ok
new file mode 100644
index 0000000000..24652c4380
--- /dev/null
+++ b/src/testdir/test71.ok
@@ -0,0 +1,10 @@
+01234567890123456789012345678901234567
+line 2 foo bar blah
+line 3 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+OK 01234567890123456789012345678901234567
+OK line 2 foo bar blah
+OK line 3 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+1234567890
+aábbccddeëff
+asdfasdfasdf
+0001112223333
diff --git a/src/testdir/test71a.in b/src/testdir/test71a.in
new file mode 100644
index 0000000000..85bd22cd01
--- /dev/null
+++ b/src/testdir/test71a.in
@@ -0,0 +1,14 @@
+
+start of text
+01234567890123456789012345678901234567
+line 2 foo bar blah
+line 3 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+end of text
+
+start of cm=zip bytes
+VimCrypt~01!lV'Þ}Mg ê£V©çE#3Ž2Ué—
+end of cm=zip bytes
+
+start of cm=blowfish bytes
+VimCrypt~02!k)¾—#ÝSœõ=ºàÈ#¥M´†JÃAÍ¥M´†!€›õáÒ‚˜÷ Ú
+end of cm=blowfish bytes
diff --git a/src/testdir/test72.in b/src/testdir/test72.in
new file mode 100644
index 0000000000..220adad67a
--- /dev/null
+++ b/src/testdir/test72.in
@@ -0,0 +1,115 @@
+Tests for undo file.
+Since this script is sourced we need to explicitly break changes up in
+undo-able pieces. Do that by setting 'undolevels'.
+
+STARTTEST
+:so small.vim
+:"
+:" Test 'undofile': first a simple one-line change.
+:set nocompatible viminfo+=nviminfo visualbell
+:set ul=100 undofile nomore
+:e! Xtestfile
+ggdGithis is one line:set ul=100
+:s/one/ONE/
+:set ul=100
+:w
+:bwipe!
+:e Xtestfile
+u:.w! test.out
+:"
+:" Test 'undofile', change in original file fails check
+:set noundofile
+:e! Xtestfile
+:s/line/Line/
+:w
+:set undofile
+:bwipe!
+:e Xtestfile
+:" TODO: this beeps
+u:.w >>test.out
+:"
+:" Test 'undofile', add 10 lines, delete 6 lines, undo 3
+:set undofile
+ggdGione
+two
+three
+four
+five
+six
+seven
+eight
+nine
+ten:set ul=100
+3Gdd:set ul=100
+dd:set ul=100
+dd:set ul=100
+dd:set ul=100
+dd:set ul=100
+dd:set ul=100
+:w
+:bwipe!
+:e Xtestfile
+uuu:w >>test.out
+:"
+:" Test that reading the undofiles when setting undofile works
+:set noundofile ul=0
+i
+u:e! Xtestfile
+:set undofile ul=100
+uuuuuu:w >>test.out
+:" And now with encryption, cryptmethod=zip
+:e! Xtestfile
+:set undofile cm=zip
+ggdGimonday
+tuesday
+wednesday
+thursday
+friday:set ul=100
+kkkdd:set ul=100
+dd:set ul=100
+dd:set ul=100
+:X
+foobar
+foobar
+:w!
+:bwipe!
+:e Xtestfile
+foobar
+:set key=
+uu:w >>test.out
+:"
+:"
+:" With encryption, cryptmethod=blowfish
+:e! Xtestfile
+:set undofile cm=blowfish
+ggdGijan
+feb
+mar
+apr
+jun:set ul=100
+kk0ifoo :set ul=100
+dd:set ul=100
+ibar :set ul=100
+:X
+foobar
+foobar
+:w!
+:bwipe!
+:e Xtestfile
+foobar
+:set key=
+/bar
+:.w >>test.out
+u:.w >>test.out
+u:.w >>test.out
+u:.w >>test.out
+:"
+:" Rename the undo file so that it gets cleaned up.
+:call rename(".Xtestfile.un~", "Xtestundo")
+:qa!
+ENDTEST
+
+1111 -----
+2222 -----
+
+123456789
diff --git a/src/testdir/test72.ok b/src/testdir/test72.ok
new file mode 100644
index 0000000000..bb267d0d8b
--- /dev/null
+++ b/src/testdir/test72.ok
@@ -0,0 +1,27 @@
+this is one line
+this is ONE Line
+one
+two
+six
+seven
+eight
+nine
+ten
+one
+two
+three
+four
+five
+six
+seven
+eight
+nine
+ten
+monday
+wednesday
+thursday
+friday
+bar apr
+apr
+foo mar
+mar
diff --git a/src/testdir/test73.in b/src/testdir/test73.in
new file mode 100644
index 0000000000..666e4d2e50
--- /dev/null
+++ b/src/testdir/test73.in
@@ -0,0 +1,176 @@
+Tests for find completion.
+
+STARTTEST
+:so small.vim
+:" 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
+:set nocp viminfo+=nviminfo
+:"
+: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/testdir/test73.ok b/src/testdir/test73.ok
new file mode 100644
index 0000000000..90efab756f
--- /dev/null
+++ b/src/testdir/test73.ok
@@ -0,0 +1,21 @@
+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/testdir/test74.in b/src/testdir/test74.in
new file mode 100644
index 0000000000..4fbe5e4d01
--- /dev/null
+++ b/src/testdir/test74.in
@@ -0,0 +1,36 @@
+" Tests for storing global variables in the .viminfo file vim: set ft=vim:
+
+STARTTEST
+:so small.vim
+:" 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
+:set nocp viminfo+=!,nviminfo
+:let MY_GLOBAL_DICT={'foo': 1, 'bar': 0, 'longvarible': 1000}
+:" store a really long list, so line wrapping will occur in viminfo file
+:let MY_GLOBAL_LIST=range(1,100)
+:wv! Xviminfo
+:unlet MY_GLOBAL_DICT
+:unlet MY_GLOBAL_LIST
+:rv! Xviminfo
+:call delete('Xviminfo')
+:if exists("MY_GLOBAL_DICT")
+:redir >> test.out
+:echo MY_GLOBAL_DICT
+:redir end
+:endif
+:if exists("MY_GLOBAL_LIST")
+:redir >> test.out
+:echo MY_GLOBAL_LIST
+:redir end
+:endif
+:redir >> test.out
+:echo "foobar"
+:redir end
+:endif
+:qa!
+ENDTEST
+
+eof
diff --git a/src/testdir/test74.ok b/src/testdir/test74.ok
new file mode 100644
index 0000000000..b026c33c35
--- /dev/null
+++ b/src/testdir/test74.ok
@@ -0,0 +1,5 @@
+
+{'foo': 1, 'longvarible': 1000, 'bar': 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, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100]
+
+foobar
diff --git a/src/testdir/test75.in b/src/testdir/test75.in
new file mode 100644
index 0000000000..4bd8279a36
--- /dev/null
+++ b/src/testdir/test75.in
@@ -0,0 +1,24 @@
+Tests for maparg().
+
+STARTTEST
+:so small.vim
+:set cpo-=<
+:" Test maparg() with a string result
+:map foo<C-V> is<F4>foo
+:vnoremap <script> <buffer> <expr> <silent> bar isbar
+:call append('$', maparg('foo<C-V>'))
+:call append('$', string(maparg('foo<C-V>', '', 0, 1)))
+:call append('$', string(maparg('bar', '', 0, 1)))
+:map <buffer> <nowait> foo bar
+:call append('$', string(maparg('foo', '', 0, 1)))
+:"
+:map abc x<char-114>x
+:call append('$', maparg('abc'))
+:map abc y<S-char-114>y
+:call append('$', maparg('abc'))
+:"
+:/^eof/+1,$w! test.out
+:qa!
+ENDTEST
+
+eof
diff --git a/src/testdir/test75.ok b/src/testdir/test75.ok
new file mode 100644
index 0000000000..d8f9a2aada
--- /dev/null
+++ b/src/testdir/test75.ok
@@ -0,0 +1,6 @@
+is<F4>foo
+{'silent': 0, 'noremap': 0, 'lhs': 'foo<C-V>', 'mode': ' ', 'nowait': 0, 'expr': 0, 'sid': 0, 'rhs': 'is<F4>foo', 'buffer': 0}
+{'silent': 1, 'noremap': 1, 'lhs': 'bar', 'mode': 'v', 'nowait': 0, 'expr': 1, 'sid': 0, 'rhs': 'isbar', 'buffer': 1}
+{'silent': 0, 'noremap': 0, 'lhs': 'foo', 'mode': ' ', 'nowait': 1, 'expr': 0, 'sid': 0, 'rhs': 'bar', 'buffer': 1}
+xrx
+yRy
diff --git a/src/testdir/test76.in b/src/testdir/test76.in
new file mode 100644
index 0000000000..db7ebe2169
--- /dev/null
+++ b/src/testdir/test76.in
@@ -0,0 +1,46 @@
+Tests for completefunc/omnifunc. vim: set ft=vim :
+
+STARTTEST
+:"Test that nothing happens if the 'completefunc' opens
+:"a new window (no completion, no crash)
+:so small.vim
+:function! DummyCompleteOne(findstart, base)
+: if a:findstart
+: return 0
+: else
+: wincmd n
+: return ['onedef', 'oneDEF']
+: endif
+:endfunction
+:setlocal completefunc=DummyCompleteOne
+/^one
+A:q!
+:function! DummyCompleteTwo(findstart, base)
+: if a:findstart
+: wincmd n
+: return 0
+: else
+: return ['twodef', 'twoDEF']
+: endif
+:endfunction
+:setlocal completefunc=DummyCompleteTwo
+/^two
+A:q!
+:"Test that 'completefunc' works when it's OK.
+:function! DummyCompleteThree(findstart, base)
+: if a:findstart
+: return 0
+: else
+: return ['threedef', 'threeDEF']
+: endif
+:endfunction
+:setlocal completefunc=DummyCompleteThree
+/^three
+A:/^+++/,/^three/w! test.out
+:qa!
+ENDTEST
+
++++
+one
+two
+three
diff --git a/src/testdir/test76.ok b/src/testdir/test76.ok
new file mode 100644
index 0000000000..2a70acbade
--- /dev/null
+++ b/src/testdir/test76.ok
@@ -0,0 +1,4 @@
++++
+
+two
+threeDEF
diff --git a/src/testdir/test77.in b/src/testdir/test77.in
new file mode 100644
index 0000000000..0dbc4fcbaf
--- /dev/null
+++ b/src/testdir/test77.in
@@ -0,0 +1,30 @@
+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.
+
+STARTTEST
+:so small.vim
+:if !executable("cksum")
+: e! test.ok
+: w! test.out
+: qa!
+:endif
+:set fileformat=unix undolevels=-1
+ggdG
+:let i = 1
+:while i <= 2000000 | call append(i, range(i, i + 99)) | let i += 100 | endwhile
+ggdd
+:w! Xtest
+:r !cksum Xtest
+:s/\s/ /g
+:set fileformat&
+:.w! test.out
+:qa!
+ENDTEST
+
diff --git a/src/testdir/test77.ok b/src/testdir/test77.ok
new file mode 100644
index 0000000000..11f148c73f
--- /dev/null
+++ b/src/testdir/test77.ok
@@ -0,0 +1 @@
+3678979763 14888896 Xtest
diff --git a/src/testdir/test78.in b/src/testdir/test78.in
new file mode 100644
index 0000000000..1850bd9236
--- /dev/null
+++ b/src/testdir/test78.in
@@ -0,0 +1,46 @@
+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.
+
+STARTTEST
+:so small.vim
+:set nocp fileformat=unix undolevels=-1 viminfo+=nviminfo
+:e! Xtest
+ggdG
+:let text = "\tabcdefghijklmnoparstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnoparstuvwxyz0123456789"
+:let i = 1
+:let linecount = 10000
+:while i <= linecount | call append(i - 1, i . text) | let i += 1 | endwhile
+:preserve
+:" get the name of the swap file
+:redir => swapname
+:swapname
+:redir END
+:let swapname = substitute(swapname, '[[:blank:][:cntrl:]]*\(.\{-}\)[[:blank:][:cntrl:]]*$', '\1', '')
+:" make a copy of the swap file in Xswap
+:set bin
+:exe 'sp ' . swapname
+:w! Xswap
+:echo swapname
+:set nobin
+:new
+:only!
+:bwipe! Xtest
+:call rename('Xswap', swapname)
+:recover Xtest
+:call delete(swapname)
+:new
+:call append(0, 'recovery start')
+:wincmd w
+:let linedollar = line('$')
+:if linedollar < linecount | exe 'wincmd w' | call append(line('$'), "expected " . linecount . " lines but found only " . linedollar) | exe 'wincmd w' | let linecount = linedollar | endif
+:let i = 1
+:while i <= linecount | if getline(i) != i . text | exe 'wincmd w' | call append(line('$'), i . ' differs') | exe 'wincmd w' | endif | let i += 1 | endwhile
+:q!
+:call append(line('$'), 'recovery end')
+:w! test.out
+:qa!
+ENDTEST
+
diff --git a/src/testdir/test78.ok b/src/testdir/test78.ok
new file mode 100644
index 0000000000..6c3ecefe3c
--- /dev/null
+++ b/src/testdir/test78.ok
@@ -0,0 +1,3 @@
+recovery start
+
+recovery end
diff --git a/src/testdir/test79.in b/src/testdir/test79.in
new file mode 100644
index 0000000000..f15ecc0f8d
--- /dev/null
+++ b/src/testdir/test79.in
Binary files differ
diff --git a/src/testdir/test79.ok b/src/testdir/test79.ok
new file mode 100644
index 0000000000..bb30d14052
--- /dev/null
+++ b/src/testdir/test79.ok
Binary files differ
diff --git a/src/testdir/test8.in b/src/testdir/test8.in
new file mode 100644
index 0000000000..d9d00d97ae
--- /dev/null
+++ b/src/testdir/test8.in
@@ -0,0 +1,46 @@
+Test for BufWritePre autocommand that deletes or unloads the buffer.
+Test for BufUnload autocommand that unloads all other buffers.
+
+STARTTEST
+:so small.vim
+: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 viminfo='100,nviminfo
+:au BufUnload * call CloseAll()
+:au VimLeave * call WriteToOut()
+:e small.vim
+:sp mbyte.vim
+:q
+:qa!
+ENDTEST
+
+start of Xxx
+ test
+end of Xxx
diff --git a/src/testdir/test8.ok b/src/testdir/test8.ok
new file mode 100644
index 0000000000..adecb2f4be
--- /dev/null
+++ b/src/testdir/test8.ok
@@ -0,0 +1,7 @@
+start of Xxx2
+ test
+end of Xxx
+start of Xxx1
+ test
+end of Xxx
+VimLeave done
diff --git a/src/testdir/test80.in b/src/testdir/test80.in
new file mode 100644
index 0000000000..c62fdc02b2
--- /dev/null
+++ b/src/testdir/test80.in
@@ -0,0 +1,199 @@
+Test for *sub-replace-special* and *sub-replace-expression* on substitue().
+Test for submatch() on substitue().
+Test for *:s%* on :substitute.
+
+STARTTEST
+:so small.vim
+ENDTEST
+
+TEST_1:
+
+STARTTEST
+:set magic
+:set cpo&
+:$put =\"\n\nTEST_1:\"
+:$put =substitute('A', 'A', '&&', '')
+:$put =substitute('B', 'B', '\&', '')
+:$put =substitute('C123456789', 'C\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)', '\0\9\8\7\6\5\4\3\2\1', '')
+:$put =substitute('D', 'D', 'd', '')
+:$put =substitute('E', 'E', '~', '')
+:$put =substitute('F', 'F', '\~', '')
+:$put =substitute('G', 'G', '\ugg', '')
+:$put =substitute('H', 'H', '\Uh\Eh', '')
+:$put =substitute('I', 'I', '\lII', '')
+:$put =substitute('J', 'J', '\LJ\EJ', '')
+:$put =substitute('K', 'K', '\Uk\ek', '')
+:$put =substitute('lLl', 'L', ' ', '')
+:$put =substitute('mMm', 'M', '\r', '')
+:$put =substitute('nNn', 'N', '\ ', '')
+:$put =substitute('oOo', 'O', '\n', '')
+:$put =substitute('pPp', 'P', '\b', '')
+:$put =substitute('qQq', 'Q', '\t', '')
+:$put =substitute('rRr', 'R', '\\', '')
+:$put =substitute('sSs', 'S', '\c', '')
+:$put =substitute('uUu', 'U', \"\n\", '')
+:$put =substitute('vVv', 'V', \"\b\", '')
+:$put =substitute('wWw', 'W', \"\\\", '')
+:$put =substitute('xXx', 'X', \"\r\", '')
+:$put =substitute('Y', 'Y', '\L\uyYy\l\EY', '')
+:$put =substitute('Z', 'Z', '\U\lZzZ\u\Ez', '')
+/^TEST_2
+ENDTEST
+
+TEST_2:
+
+STARTTEST
+:set nomagic
+:set cpo&
+:$put =\"\n\nTEST_2:\"
+:$put =substitute('A', 'A', '&&', '')
+:$put =substitute('B', 'B', '\&', '')
+:$put =substitute('C123456789', 'C\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)', '\0\9\8\7\6\5\4\3\2\1', '')
+:$put =substitute('D', 'D', 'd', '')
+:$put =substitute('E', 'E', '~', '')
+:$put =substitute('F', 'F', '\~', '')
+:$put =substitute('G', 'G', '\ugg', '')
+:$put =substitute('H', 'H', '\Uh\Eh', '')
+:$put =substitute('I', 'I', '\lII', '')
+:$put =substitute('J', 'J', '\LJ\EJ', '')
+:$put =substitute('K', 'K', '\Uk\ek', '')
+:$put =substitute('lLl', 'L', ' ', '')
+:$put =substitute('mMm', 'M', '\r', '')
+:$put =substitute('nNn', 'N', '\ ', '')
+:$put =substitute('oOo', 'O', '\n', '')
+:$put =substitute('pPp', 'P', '\b', '')
+:$put =substitute('qQq', 'Q', '\t', '')
+:$put =substitute('rRr', 'R', '\\', '')
+:$put =substitute('sSs', 'S', '\c', '')
+:$put =substitute('tTt', 'T', \"\r\", '')
+:$put =substitute('uUu', 'U', \"\n\", '')
+:$put =substitute('vVv', 'V', \"\b\", '')
+:$put =substitute('wWw', 'W', \"\\\", '')
+:$put =substitute('X', 'X', '\L\uxXx\l\EX', '')
+:$put =substitute('Y', 'Y', '\U\lYyY\u\Ey', '')
+/^TEST_3
+ENDTEST
+
+TEST_3:
+
+STARTTEST
+:set magic&
+:set cpo&
+:$put =\"\n\nTEST_3:\"
+:let y = substitute('aAa', 'A', '\="\\"', '') | $put =y
+:let y = substitute('bBb', 'B', '\="\\\\"', '') | $put =y
+:let y = substitute('cCc', 'C', '\=" "', '') | $put =y
+:let y = substitute('dDd', 'D', '\="\\ "', '') | $put =y
+:let y = substitute('eEe', 'E', '\="\\\\ "', '') | $put =y
+:let y = substitute('fFf', 'F', '\="\\r"', '') | $put =y
+:let y = substitute('jJj', 'J', '\="\\n"', '') | $put =y
+:let y = substitute('kKk', 'K', '\="\r"', '') | $put =y
+:let y = substitute('lLl', 'L', '\="\n"', '') | $put =y
+/^TEST_4
+ENDTEST
+
+TEST_4:
+
+STARTTEST
+:set magic&
+:set cpo&
+:$put =\"\n\nTEST_4:\"
+:let y = substitute('aAa', 'A', '\=substitute(submatch(0), ".", "\\", "")', '') | $put =y
+:let y = substitute('bBb', 'B', '\=substitute(submatch(0), ".", "\\\\", "")', '') | $put =y
+:let y = substitute('cCc', 'C', '\=substitute(submatch(0), ".", " ", "")', '') | $put =y
+:let y = substitute('dDd', 'D', '\=substitute(submatch(0), ".", "\\ ", "")', '') | $put =y
+:let y = substitute('eEe', 'E', '\=substitute(submatch(0), ".", "\\\\ ", "")', '') | $put =y
+:let y = substitute('fFf', 'F', '\=substitute(submatch(0), ".", "\\r", "")', '') | $put =y
+:let y = substitute('jJj', 'J', '\=substitute(submatch(0), ".", "\\n", "")', '') | $put =y
+:let y = substitute('kKk', 'K', '\=substitute(submatch(0), ".", "\r", "")', '') | $put =y
+:let y = substitute('lLl', 'L', '\=substitute(submatch(0), ".", "\n", "")', '') | $put =y
+/^TEST_5
+ENDTEST
+
+TEST_5:
+
+STARTTEST
+:set magic&
+:set cpo&
+:$put =\"\n\nTEST_5:\"
+:$put =substitute('A123456789', 'A\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)', '\=submatch(0) . submatch(9) . submatch(8) . submatch(7) . submatch(6) . submatch(5) . submatch(4) . submatch(3) . submatch(2) . submatch(1)', '')
+/^TEST_6
+ENDTEST
+
+TEST_6:
+
+STARTTEST
+:set magic&
+:$put =\"\n\nTEST_6:\"
+:set cpo+=/
+:$put =substitute('A', 'A', 'a', '')
+:$put =substitute('B', 'B', '%', '')
+:set cpo-=/
+:$put =substitute('C', 'C', 'c', '')
+:$put =substitute('D', 'D', '%', '')
+/^TEST_7
+ENDTEST
+
+TEST_7:
+
+STARTTEST
+:set magic&
+:set cpo&
+:$put =\"\n\nTEST_7:\"
+:$put =substitute('A A', 'A.', '\=submatch(0)', '')
+:$put =substitute(\"B\nB\", 'B.', '\=submatch(0)', '')
+:$put =substitute('-bb', '\zeb', 'a', 'g')
+:$put =substitute('-bb', '\ze', 'c', 'g')
+/^TEST_8
+ENDTEST
+
+TEST_8:
+
+STARTTEST
+:set magic&
+:set cpo&
+:$put =\"\n\nTEST_8:\"
+:$put =',,X'
+:s/\(^\|,\)\ze\(,\|X\)/\1N/g
+:$put =',,Y'
+:s/\(^\|,\)\ze\(,\|Y\)/\1N/gc
+a:$put =',,Z'
+:s/\(^\|,\)\ze\(,\|Z\)/\1N/gc
+yy/^TEST_9:
+ENDTEST
+
+TEST_9:
+
+STARTTEST
+:set magic&
+:set cpo&
+:$put =\"\n\nTEST_9:\"
+:$put ='xxx'
+:s/x/X/gc
+yyq/^TEST_10:
+ENDTEST
+
+TEST_10:
+
+STARTTEST
+:set magic&
+:set cpo&
+:$put =\"\n\nTEST_10:\"
+:let y = substitute('123', '\zs', 'a', 'g') | $put =y
+:let y = substitute('123', '\zs.', 'a', 'g') | $put =y
+:let y = substitute('123', '.\zs', 'a', 'g') | $put =y
+:let y = substitute('123', '\ze', 'a', 'g') | $put =y
+:let y = substitute('123', '\ze.', 'a', 'g') | $put =y
+:let y = substitute('123', '.\ze', 'a', 'g') | $put =y
+:let y = substitute('123', '1\|\ze', 'a', 'g') | $put =y
+:let y = substitute('123', '1\zs\|[23]', 'a', 'g') | $put =y
+/^TEST_11
+ENDTEST
+
+TEST_11:
+
+STARTTEST
+:/^Results/,$wq! test.out
+ENDTEST
+
+Results of test72:
diff --git a/src/testdir/test80.ok b/src/testdir/test80.ok
new file mode 100644
index 0000000000..2b79d377a7
--- /dev/null
+++ b/src/testdir/test80.ok
@@ -0,0 +1,128 @@
+Results of test72:
+
+
+TEST_1:
+AA
+&
+C123456789987654321
+d
+~
+~
+Gg
+Hh
+iI
+jJ
+Kk
+l l
+m m
+n n
+o
+o
+pp
+q q
+r\r
+scs
+u
+u
+vv
+w\w
+x x
+YyyY
+zZZz
+
+
+TEST_2:
+AA
+&
+C123456789987654321
+d
+~
+~
+Gg
+Hh
+iI
+jJ
+Kk
+l l
+m m
+n n
+o
+o
+pp
+q q
+r\r
+scs
+t t
+u
+u
+vv
+w\w
+XxxX
+yYYy
+
+
+TEST_3:
+a\a
+b\\b
+c c
+d\ d
+e\\ e
+f\rf
+j\nj
+k k
+l
+l
+
+
+TEST_4:
+a\a
+b\b
+c c
+d d
+e\ e
+f f
+j
+j
+k k
+l
+l
+
+
+TEST_5:
+A123456789987654321
+
+
+TEST_6:
+a
+%
+c
+%
+
+
+TEST_7:
+A A
+B
+B
+-abab
+c-cbcbc
+
+
+TEST_8:
+N,,NX
+N,,NY
+N,,NZ
+
+
+TEST_9:
+XXx
+
+
+TEST_10:
+a1a2a3a
+aaa
+1a2a3a
+a1a2a3a
+a1a2a3
+aaa
+aa2a3a
+1aaa
diff --git a/src/testdir/test81.in b/src/testdir/test81.in
new file mode 100644
index 0000000000..82a6892a1d
--- /dev/null
+++ b/src/testdir/test81.in
@@ -0,0 +1,22 @@
+Test for t movement command and 'cpo-;' setting
+
+STARTTEST
+:set nocompatible viminfo+=nviminfo
+:set cpo-=;
+/firstline/
+j0tt;D
+0fz;D
+$Fy;D
+$Ty;D:set cpo+=;
+j0tt;;D
+$Ty;;D:?firstline?+1,$w! test.out
+:qa!
+ENDTEST
+
+firstline
+aaa two three four
+ zzz
+yyy
+bbb yee yoo four
+ccc two three four
+ddd yee yoo four
diff --git a/src/testdir/test81.ok b/src/testdir/test81.ok
new file mode 100644
index 0000000000..e9f17dc4f8
--- /dev/null
+++ b/src/testdir/test81.ok
@@ -0,0 +1,6 @@
+aaa two
+ z
+y
+bbb y
+ccc
+ddd yee y
diff --git a/src/testdir/test82.in b/src/testdir/test82.in
new file mode 100644
index 0000000000..8503f5488f
--- /dev/null
+++ b/src/testdir/test82.in
@@ -0,0 +1,103 @@
+Tests for case-insensitive UTF-8 comparisons (utf_strnicmp() in mbyte.c)
+Also test "g~ap".
+
+STARTTEST
+:so small.vim
+:if !has("multi_byte")
+: e! test.ok
+: w! test.out
+: qa!
+:endif
+:set enc=utf8
+ggdG
+:
+:function! Ch(a, op, b, expected)
+: if eval(printf('"%s" %s "%s"', a:a, a:op, a:b)) != a:expected
+: call append(line('$'), printf('"%s" %s "%s" should return %d', a:a, a:op, a:b, a:expected))
+: else
+: let b:passed += 1
+: endif
+: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
+:
+:let b:passed=0
+: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
+:call append(0, printf('%d checks passed', b:passed))
+:"
+:" test that g~ap changes one paragraph only.
+:new
+iabcd
+
+defggg0g~ap:let lns = getline(1,3)
+:q!
+:call append(line('$'), lns)
+:"
+:wq! test.out
+ENDTEST
+
diff --git a/src/testdir/test82.ok b/src/testdir/test82.ok
new file mode 100644
index 0000000000..3f1866a0fb
--- /dev/null
+++ b/src/testdir/test82.ok
@@ -0,0 +1,5 @@
+3732 checks passed
+
+ABCD
+
+defg
diff --git a/src/testdir/test83-tags2 b/src/testdir/test83-tags2
new file mode 100644
index 0000000000..7f9f21b0eb
--- /dev/null
+++ b/src/testdir/test83-tags2
@@ -0,0 +1,2 @@
+!_TAG_FILE_ENCODING cp932 //
+‚`‚a‚b Xtags2.txt /‚`‚a‚b
diff --git a/src/testdir/test83-tags3 b/src/testdir/test83-tags3
new file mode 100644
index 0000000000..0cb6591562
--- /dev/null
+++ b/src/testdir/test83-tags3
@@ -0,0 +1,102 @@
+!_TAG_FILE_SORTED 1 //
+!_TAG_FILE_ENCODING cp932 //
+abc1 Xtags3.txt /‚`‚a‚b
+abc2 Xtags3.txt /‚`‚a‚b
+abc3 Xtags3.txt /‚`‚a‚b
+abc4 Xtags3.txt /‚`‚a‚b
+abc5 Xtags3.txt /‚`‚a‚b
+abc6 Xtags3.txt /‚`‚a‚b
+abc7 Xtags3.txt /‚`‚a‚b
+abc8 Xtags3.txt /‚`‚a‚b
+abc9 Xtags3.txt /‚`‚a‚b
+abc10 Xtags3.txt /‚`‚a‚b
+abc11 Xtags3.txt /‚`‚a‚b
+abc12 Xtags3.txt /‚`‚a‚b
+abc13 Xtags3.txt /‚`‚a‚b
+abc14 Xtags3.txt /‚`‚a‚b
+abc15 Xtags3.txt /‚`‚a‚b
+abc16 Xtags3.txt /‚`‚a‚b
+abc17 Xtags3.txt /‚`‚a‚b
+abc18 Xtags3.txt /‚`‚a‚b
+abc19 Xtags3.txt /‚`‚a‚b
+abc20 Xtags3.txt /‚`‚a‚b
+abc21 Xtags3.txt /‚`‚a‚b
+abc22 Xtags3.txt /‚`‚a‚b
+abc23 Xtags3.txt /‚`‚a‚b
+abc24 Xtags3.txt /‚`‚a‚b
+abc25 Xtags3.txt /‚`‚a‚b
+abc26 Xtags3.txt /‚`‚a‚b
+abc27 Xtags3.txt /‚`‚a‚b
+abc28 Xtags3.txt /‚`‚a‚b
+abc29 Xtags3.txt /‚`‚a‚b
+abc30 Xtags3.txt /‚`‚a‚b
+abc31 Xtags3.txt /‚`‚a‚b
+abc32 Xtags3.txt /‚`‚a‚b
+abc33 Xtags3.txt /‚`‚a‚b
+abc34 Xtags3.txt /‚`‚a‚b
+abc35 Xtags3.txt /‚`‚a‚b
+abc36 Xtags3.txt /‚`‚a‚b
+abc37 Xtags3.txt /‚`‚a‚b
+abc38 Xtags3.txt /‚`‚a‚b
+abc39 Xtags3.txt /‚`‚a‚b
+abc40 Xtags3.txt /‚`‚a‚b
+abc41 Xtags3.txt /‚`‚a‚b
+abc42 Xtags3.txt /‚`‚a‚b
+abc43 Xtags3.txt /‚`‚a‚b
+abc44 Xtags3.txt /‚`‚a‚b
+abc45 Xtags3.txt /‚`‚a‚b
+abc46 Xtags3.txt /‚`‚a‚b
+abc47 Xtags3.txt /‚`‚a‚b
+abc48 Xtags3.txt /‚`‚a‚b
+abc49 Xtags3.txt /‚`‚a‚b
+abc50 Xtags3.txt /‚`‚a‚b
+abc51 Xtags3.txt /‚`‚a‚b
+abc52 Xtags3.txt /‚`‚a‚b
+abc53 Xtags3.txt /‚`‚a‚b
+abc54 Xtags3.txt /‚`‚a‚b
+abc55 Xtags3.txt /‚`‚a‚b
+abc56 Xtags3.txt /‚`‚a‚b
+abc57 Xtags3.txt /‚`‚a‚b
+abc58 Xtags3.txt /‚`‚a‚b
+abc59 Xtags3.txt /‚`‚a‚b
+abc60 Xtags3.txt /‚`‚a‚b
+abc61 Xtags3.txt /‚`‚a‚b
+abc62 Xtags3.txt /‚`‚a‚b
+abc63 Xtags3.txt /‚`‚a‚b
+abc64 Xtags3.txt /‚`‚a‚b
+abc65 Xtags3.txt /‚`‚a‚b
+abc66 Xtags3.txt /‚`‚a‚b
+abc67 Xtags3.txt /‚`‚a‚b
+abc68 Xtags3.txt /‚`‚a‚b
+abc69 Xtags3.txt /‚`‚a‚b
+abc70 Xtags3.txt /‚`‚a‚b
+abc71 Xtags3.txt /‚`‚a‚b
+abc72 Xtags3.txt /‚`‚a‚b
+abc73 Xtags3.txt /‚`‚a‚b
+abc74 Xtags3.txt /‚`‚a‚b
+abc75 Xtags3.txt /‚`‚a‚b
+abc76 Xtags3.txt /‚`‚a‚b
+abc77 Xtags3.txt /‚`‚a‚b
+abc78 Xtags3.txt /‚`‚a‚b
+abc79 Xtags3.txt /‚`‚a‚b
+abc80 Xtags3.txt /‚`‚a‚b
+abc81 Xtags3.txt /‚`‚a‚b
+abc82 Xtags3.txt /‚`‚a‚b
+abc83 Xtags3.txt /‚`‚a‚b
+abc84 Xtags3.txt /‚`‚a‚b
+abc85 Xtags3.txt /‚`‚a‚b
+abc86 Xtags3.txt /‚`‚a‚b
+abc87 Xtags3.txt /‚`‚a‚b
+abc88 Xtags3.txt /‚`‚a‚b
+abc89 Xtags3.txt /‚`‚a‚b
+abc90 Xtags3.txt /‚`‚a‚b
+abc91 Xtags3.txt /‚`‚a‚b
+abc92 Xtags3.txt /‚`‚a‚b
+abc93 Xtags3.txt /‚`‚a‚b
+abc94 Xtags3.txt /‚`‚a‚b
+abc95 Xtags3.txt /‚`‚a‚b
+abc96 Xtags3.txt /‚`‚a‚b
+abc97 Xtags3.txt /‚`‚a‚b
+abc98 Xtags3.txt /‚`‚a‚b
+abc99 Xtags3.txt /‚`‚a‚b
+abc100 Xtags3.txt /‚`‚a‚b
diff --git a/src/testdir/test83.in b/src/testdir/test83.in
new file mode 100644
index 0000000000..297d560d2f
--- /dev/null
+++ b/src/testdir/test83.in
@@ -0,0 +1,76 @@
+Tests for tag search with !_TAG_FILE_ENCODING.
+
+STARTTEST
+:so mbyte.vim
+:set enc=utf8
+:if !has('iconv') || iconv("\x82\x60", "cp932", "utf-8") != "\uff21"
+: e! test.ok
+: w! test.out
+: qa!
+:endif
+
+:/^text for tags1$/,/^text for tags1$/+1w! Xtags1.txt
+:/^text for tags2$/,/^text for tags2$/+1w! Xtags2.txt
+:/^text for tags3$/,/^text for tags3$/+1w! Xtags3.txt
+:/^tags1$/+1,/^tags1-end$/-1w! Xtags1
+
+ggdG
+
+:call setline('.', 'Results of test83')
+
+:" case1:
+:new
+:set tags=Xtags1
+:let v:errmsg = ''
+:tag abcdefghijklmnopqrs
+:if v:errmsg =~ 'E426:' || getline('.') != 'abcdefghijklmnopqrs'
+: close
+: put ='case1: failed'
+:else
+: close
+: put ='case1: ok'
+:endif
+
+:" case2:
+:new
+:set tags=test83-tags2
+:let v:errmsg = ''
+:tag /.BC
+:if v:errmsg =~ 'E426:' || getline('.') != 'ABC'
+: close
+: put ='case2: failed'
+:else
+: close
+: put ='case2: ok'
+:endif
+
+:" case3:
+:new
+:set tags=test83-tags3
+:let v:errmsg = ''
+:tag abc50
+:if v:errmsg =~ 'E426:' || getline('.') != 'ABC'
+: close
+: put ='case3: failed'
+:else
+: close
+: put ='case3: ok'
+:endif
+:close
+
+:wq! test.out
+ENDTEST
+
+text for tags1
+abcdefghijklmnopqrs
+
+text for tags2
+ABC
+
+text for tags3
+ABC
+
+tags1
+!_TAG_FILE_ENCODING utf-8 //
+abcdefghijklmnopqrs Xtags1.txt /abcdefghijklmnopqrs
+tags1-end
diff --git a/src/testdir/test83.ok b/src/testdir/test83.ok
new file mode 100644
index 0000000000..61a1a04a18
--- /dev/null
+++ b/src/testdir/test83.ok
@@ -0,0 +1,4 @@
+Results of test83
+case1: ok
+case2: ok
+case3: ok
diff --git a/src/testdir/test84.in b/src/testdir/test84.in
new file mode 100644
index 0000000000..25482db54c
--- /dev/null
+++ b/src/testdir/test84.in
@@ -0,0 +1,35 @@
+Tests for curswant not changing when setting an option
+
+STARTTEST
+:so small.vim
+:/^start target options$/+1,/^end target options$/-1 yank
+:let target_option_names = split(@0)
+:function TestCurswant(option_name)
+: normal! ggf8j
+: let curswant_before = winsaveview().curswant
+: execute 'let' '&'.a:option_name '=' '&'.a:option_name
+: let curswant_after = winsaveview().curswant
+: return [a:option_name, curswant_before, curswant_after]
+:endfunction
+:
+:new
+:put =['1234567890', '12345']
+:1 delete _
+:let result = []
+:for option_name in target_option_names
+: call add(result, TestCurswant(option_name))
+:endfor
+:
+:new
+:put =map(copy(result), 'join(v:val, '' '')')
+:1 delete _
+:write test.out
+:
+:qall!
+ENDTEST
+
+start target options
+ tabstop
+ timeoutlen
+ ttimeoutlen
+end target options
diff --git a/src/testdir/test84.ok b/src/testdir/test84.ok
new file mode 100644
index 0000000000..8b8e4ee824
--- /dev/null
+++ b/src/testdir/test84.ok
@@ -0,0 +1,3 @@
+tabstop 7 4
+timeoutlen 7 7
+ttimeoutlen 7 7
diff --git a/src/testdir/test85.in b/src/testdir/test85.in
new file mode 100644
index 0000000000..c5ca873a49
--- /dev/null
+++ b/src/testdir/test85.in
@@ -0,0 +1,85 @@
+Test for Lua interface and luaeval() function
+
+STARTTEST
+:so small.vim
+:so lua.vim
+:set nocompatible viminfo+=nviminfo
+:lua l = vim.list():add"item0":add"dictionary with list OK":add"item2"
+:lua h = vim.dict(); h.list = l
+:call garbagecollect()
+/^1
+:" change buffer contents
+:lua curbuf = vim.buffer()
+:lua curline = vim.eval"line('.')"
+:lua curbuf[curline] = "1 changed line 1"
+:" scalar test
+:let tmp_string = luaeval('"string"')
+:let tmp_1000 = luaeval('1000')
+:if printf("%s%.0f", tmp_string, tmp_1000) == "string1000"
+:let scalar_res = "OK"
+:else
+:let scalar_res = "FAILED"
+:endif
+:call append(search("^1"), "scalar test " . scalar_res)
+:" dictionary containing a list
+:let tmp = luaeval("h").list[1]
+:/^2/put =tmp
+:" circular list (at the same time test lists containing lists)
+:lua l[2] = l
+:let l2 = luaeval("h").list
+:if l2[2] == l2
+:let res = "OK"
+:else
+:let res = "FAILED"
+:endif
+:call setline(search("^3"), "circular test " . res)
+
+:let l = []
+:lua l = vim.eval("l")
+:lua l:add(123)
+:lua l:add("abc")
+:lua l:add(vim.eval("[1, 2, 3]"))
+:lua l:add(vim.eval("{'a':1, 'b':2, 'c':3}"))
+:lua l:insert(123)
+:lua l:insert("abc")
+:lua l:insert(vim.eval("[1, 2, 3]"))
+:lua l:insert(vim.eval("{'a':1, 'b':2, 'c':3}"))
+:lua l[0] = l[0]
+:lua l[1] = l[1]
+:lua l[2] = l[2]
+:lua l[3] = l[3]
+:lua l[0] = 123
+:lua l[1] = "abc"
+:lua l[2] = vim.eval("[1, 2, 3]")
+:lua l[3] = vim.eval("{'a':1, 'b':2, 'c':3}")
+:lua l[3] = nil
+:lua l[2] = nil
+:lua l[1] = nil
+:lua l[0] = nil
+:lua l = nil
+:$put =string(l)
+
+:let d = {}
+:lua d = vim.eval("d")
+:lua d[0] = 123
+:lua d[1] = "abc"
+:lua d[2] = vim.eval("[1, 2, 3]")
+:lua d[3] = vim.eval("{'a':1, 'b':2, 'c':3}")
+:lua d[4] = d[0]
+:lua d[5] = d[1]
+:lua d[6] = d[2]
+:lua d[7] = d[3]
+:lua d[3] = nil
+:lua d[2] = nil
+:lua d[1] = nil
+:lua d[0] = nil
+:lua d = nil
+:$put =string(d)
+
+:?^1?,$w! test.out
+:qa!
+ENDTEST
+
+1 line 1
+2 line 2
+3 line 3
diff --git a/src/testdir/test85.ok b/src/testdir/test85.ok
new file mode 100644
index 0000000000..4753483240
--- /dev/null
+++ b/src/testdir/test85.ok
@@ -0,0 +1,7 @@
+1 changed line 1
+scalar test OK
+2 line 2
+dictionary with list OK
+circular test OK
+[123.0, 'abc', [1, 2, 3], {'a': 1, 'b': 2, 'c': 3}]
+{'4': 123.0, '5': 'abc', '6': [1, 2, 3], '7': {'a': 1, 'b': 2, 'c': 3}}
diff --git a/src/testdir/test86.in b/src/testdir/test86.in
new file mode 100644
index 0000000000..240e07e477
--- /dev/null
+++ b/src/testdir/test86.in
@@ -0,0 +1,1429 @@
+Tests for various python features. vim: set ft=vim :
+
+NOTE: This will cause errors when run under valgrind.
+This would require recompiling Python with:
+ ./configure --without-pymalloc
+See http://svn.python.org/view/python/trunk/Misc/README.valgrind?view=markup
+
+STARTTEST
+:so small.vim
+:set encoding=latin1
+:set noswapfile
+:if !has('python') | e! test.ok | wq! test.out | endif
+:lang C
+:fun Test()
+:py import vim
+:let l = []
+:py l=vim.bindeval('l')
+:py f=vim.bindeval('function("strlen")')
+:" Extending List directly with different types
+:py l.extend([1, "as'd", [1, 2, f, {'a': 1}]])
+:$put =string(l)
+:$put =string(l[-1])
+:try
+: $put =string(l[-4])
+:catch
+: $put =v:exception[:13]
+:endtry
+:" List assignment
+:py l[0]=0
+:$put =string(l)
+:py l[-2]=f
+:$put =string(l)
+:"
+:" Extending Dictionary directly with different types
+:let d = {}
+:fun d.f()
+: return 1
+:endfun
+py << EOF
+d=vim.bindeval('d')
+d['1']='asd'
+d.update(b=[1, 2, f])
+d.update((('-1', {'a': 1}),))
+d.update({'0': -1})
+dk = d.keys()
+dv = d.values()
+di = d.items()
+cmpfun = lambda a, b: cmp(repr(a), repr(b))
+dk.sort(cmpfun)
+dv.sort(cmpfun)
+di.sort(cmpfun)
+EOF
+:$put =pyeval('d[''f''](self={})')
+:$put =pyeval('repr(dk)')
+:$put =substitute(pyeval('repr(dv)'),'0x\x\+','','g')
+:$put =substitute(pyeval('repr(di)'),'0x\x\+','','g')
+:for [key, Val] in sort(items(d))
+: $put =string(key) . ' : ' . string(Val)
+: unlet key Val
+:endfor
+:py del dk
+:py del di
+:py del dv
+:"
+:" removing items with del
+:py del l[2]
+:$put =string(l)
+:let l = range(8)
+:py l=vim.bindeval('l')
+:try
+: py del l[:3]
+: py del l[1:]
+:catch
+: $put =v:exception
+:endtry
+:$put =string(l)
+:"
+:py del d['-1']
+:py del d['f']
+:$put =string(pyeval('d.get(''b'', 1)'))
+:$put =string(pyeval('d.pop(''b'')'))
+:$put =string(pyeval('d.get(''b'', 1)'))
+:$put =string(pyeval('d.pop(''1'', 2)'))
+:$put =string(pyeval('d.pop(''1'', 2)'))
+:$put =pyeval('repr(d.has_key(''0''))')
+:$put =pyeval('repr(d.has_key(''1''))')
+:$put =pyeval('repr(''0'' in d)')
+:$put =pyeval('repr(''1'' in d)')
+:$put =pyeval('repr(list(iter(d)))')
+:$put =string(d)
+:$put =pyeval('repr(d.popitem())')
+:$put =pyeval('repr(d.get(''0''))')
+:$put =pyeval('repr(list(iter(d)))')
+:"
+:" removing items out of range: silently skip items that don't exist
+:let l = [0, 1, 2, 3]
+:py l=vim.bindeval('l')
+:" The following two ranges delete nothing as they match empty list:
+:py del l[2:1]
+:$put =string(l)
+:py del l[2:2]
+:$put =string(l)
+:py del l[2:3]
+:$put =string(l)
+:let l = [0, 1, 2, 3]
+:py l=vim.bindeval('l')
+:py del l[2:4]
+:$put =string(l)
+:let l = [0, 1, 2, 3]
+:py l=vim.bindeval('l')
+:py del l[2:5]
+:$put =string(l)
+:let l = [0, 1, 2, 3]
+:py l=vim.bindeval('l')
+:py del l[2:6]
+:$put =string(l)
+:let l = [0, 1, 2, 3]
+:py l=vim.bindeval('l')
+:" The following two ranges delete nothing as they match empty list:
+:py del l[-1:2]
+:$put =string(l)
+:py del l[-2:2]
+:$put =string(l)
+:py del l[-3:2]
+:$put =string(l)
+:let l = [0, 1, 2, 3]
+:py l=vim.bindeval('l')
+:py del l[-4:2]
+:$put =string(l)
+:let l = [0, 1, 2, 3]
+:py l=vim.bindeval('l')
+:py del l[-5:2]
+:$put =string(l)
+:let l = [0, 1, 2, 3]
+:py l=vim.bindeval('l')
+:py del l[-6:2]
+:$put =string(l)
+:let l = [0, 1, 2, 3]
+:py l=vim.bindeval('l')
+:py del l[::2]
+:$put =string(l)
+:let l = [0, 1, 2, 3]
+:py l=vim.bindeval('l')
+:py del l[3:0:-2]
+:$put =string(l)
+:let l = [0, 1, 2, 3]
+:py l=vim.bindeval('l')
+:py del l[2:4:-2]
+:$put =string(l)
+:"
+:" Slice assignment to a list
+:let l = [0, 1, 2, 3]
+:py l=vim.bindeval('l')
+:py l[0:0]=['a']
+:$put =string(l)
+:let l = [0, 1, 2, 3]
+:py l=vim.bindeval('l')
+:py l[1:2]=['b']
+:$put =string(l)
+:let l = [0, 1, 2, 3]
+:py l=vim.bindeval('l')
+:py l[2:4]=['c']
+:$put =string(l)
+:let l = [0, 1, 2, 3]
+:py l=vim.bindeval('l')
+:py l[4:4]=['d']
+:$put =string(l)
+:let l = [0, 1, 2, 3]
+:py l=vim.bindeval('l')
+:py l[-1:2]=['e']
+:$put =string(l)
+:let l = [0, 1, 2, 3]
+:py l=vim.bindeval('l')
+:py l[-10:2]=['f']
+:$put =string(l)
+:let l = [0, 1, 2, 3]
+:py l=vim.bindeval('l')
+:py l[2:-10]=['g']
+:$put =string(l)
+:let l = []
+:py l=vim.bindeval('l')
+:py l[0:0]=['h']
+:$put =string(l)
+:let l = range(8)
+:py l=vim.bindeval('l')
+:py l[2:6:2] = [10, 20]
+:$put =string(l)
+:let l = range(8)
+:py l=vim.bindeval('l')
+:py l[6:2:-2] = [10, 20]
+:$put =string(l)
+:let l = range(8)
+:py l=vim.bindeval('l')
+:py l[6:2] = ()
+:$put =string(l)
+:let l = range(8)
+:py l=vim.bindeval('l')
+:py l[6:2:1] = ()
+:$put =string(l)
+:let l = range(8)
+:py l=vim.bindeval('l')
+:py l[2:2:1] = ()
+:$put =string(l)
+:"
+:" Locked variables
+:let l = [0, 1, 2, 3]
+:py l=vim.bindeval('l')
+:lockvar! l
+:py l[2]='i'
+:$put =string(l)
+:unlockvar! l
+:"
+:" Function calls
+py << EOF
+import sys
+def ee(expr, g=globals(), l=locals()):
+ try:
+ exec(expr, g, l)
+ except:
+ ei = sys.exc_info()
+ msg = sys.exc_info()[0].__name__ + ':' + repr(sys.exc_info()[1].args)
+ msg = msg.replace('TypeError:(\'argument 1 ', 'TypeError:(\'')
+ if expr.find('None') > -1:
+ msg = msg.replace('TypeError:(\'iteration over non-sequence\',)',
+ 'TypeError:("\'NoneType\' object is not iterable",)')
+ if expr.find('FailingNumber') > -1:
+ msg = msg.replace(', not \'FailingNumber\'', '').replace('"', '\'')
+ msg = msg.replace('TypeError:(\'iteration over non-sequence\',)',
+ 'TypeError:("\'FailingNumber\' object is not iterable",)')
+ if msg.find('(\'\'') > -1 or msg.find('(\'can\'t') > -1:
+ msg = msg.replace('(\'', '("').replace('\',)', '",)')
+ if expr == 'fd(self=[])':
+ # HACK: PyMapping_Check changed meaning
+ msg = msg.replace('AttributeError:(\'keys\',)',
+ 'TypeError:(\'unable to convert list to vim dictionary\',)')
+ vim.current.buffer.append(expr + ':' + msg)
+ else:
+ vim.current.buffer.append(expr + ':NOT FAILED')
+EOF
+:fun New(...)
+: return ['NewStart']+a:000+['NewEnd']
+:endfun
+:fun DictNew(...) dict
+: return ['DictNewStart']+a:000+['DictNewEnd', self]
+:endfun
+:let l=[function('New'), function('DictNew')]
+:py l=vim.bindeval('l')
+:py l.extend(list(l[0](1, 2, 3)))
+:$put =string(l)
+:py l.extend(list(l[1](1, 2, 3, self={'a': 'b'})))
+:$put =string(l)
+:py l.extend([l[0].name])
+:$put =string(l)
+:py ee('l[1](1, 2, 3)')
+:py f=l[0]
+:delfunction New
+:py ee('f(1, 2, 3)')
+:if has('float')
+: let l=[0.0]
+: py l=vim.bindeval('l')
+: py l.extend([0.0])
+: $put =string(l)
+:else
+: $put ='[0.0, 0.0]'
+:endif
+:let messages=[]
+:delfunction DictNew
+py <<EOF
+d=vim.bindeval('{}')
+m=vim.bindeval('messages')
+def em(expr, g=globals(), l=locals()):
+ try:
+ exec(expr, g, l)
+ except:
+ m.extend([sys.exc_type.__name__])
+
+em('d["abc1"]')
+em('d["abc1"]="\\0"')
+em('d["abc1"]=vim')
+em('d[""]=1')
+em('d["a\\0b"]=1')
+em('d[u"a\\0b"]=1')
+
+em('d.pop("abc1")')
+em('d.popitem()')
+del em
+del m
+EOF
+:$put =messages
+:unlet messages
+:" locked and scope attributes
+:let d={} | let dl={} | lockvar dl
+:for s in split("d dl v: g:")
+: let name=tr(s, ':', 's')
+: execute 'py '.name.'=vim.bindeval("'.s.'")'
+: let toput=s.' : '.join(map(['locked', 'scope'], 'v:val.":".pyeval(name.".".v:val)'), ';')
+: $put =toput
+:endfor
+:silent! let d.abc2=1
+:silent! let dl.abc3=1
+:py d.locked=True
+:py dl.locked=False
+:silent! let d.def=1
+:silent! let dl.def=1
+:put ='d:'.string(d)
+:put ='dl:'.string(dl)
+:unlet d dl
+:
+:let l=[] | let ll=[] | lockvar ll
+:for s in split("l ll")
+: let name=tr(s, ':', 's')
+: execute 'py '.name.'=vim.bindeval("'.s.'")'
+: let toput=s.' : locked:'.pyeval(name.'.locked')
+: $put =toput
+:endfor
+:silent! call extend(l, [0])
+:silent! call extend(ll, [0])
+:py l.locked=True
+:py ll.locked=False
+:silent! call extend(l, [1])
+:silent! call extend(ll, [1])
+:put ='l:'.string(l)
+:put ='ll:'.string(ll)
+:unlet l ll
+:"
+:" pyeval()
+:let l=pyeval('range(3)')
+:$put =string(l)
+:let d=pyeval('{"a": "b", "c": 1, "d": ["e"]}')
+:$put =sort(items(d))
+:if has('float')
+: let f=pyeval('0.0')
+: $put =string(f)
+:else
+: $put ='0.0'
+:endif
+:" Invalid values:
+:for e in ['"\0"', '{"\0": 1}', 'undefined_name', 'vim']
+: try
+: let v=pyeval(e)
+: catch
+: let toput=e.":\t".v:exception[:13]
+: $put =toput
+: endtry
+:endfor
+:"
+:" threading
+:let l = [0]
+:py l=vim.bindeval('l')
+py <<EOF
+import threading
+import time
+
+class T(threading.Thread):
+ def __init__(self):
+ threading.Thread.__init__(self)
+ self.t = 0
+ self.running = True
+
+ def run(self):
+ while self.running:
+ self.t += 1
+ time.sleep(0.1)
+
+t = T()
+del T
+t.start()
+EOF
+:sleep 1
+:py t.running = False
+:py t.join()
+:py l[0] = t.t > 8 # check if the background thread is working
+:py del time
+:py del threading
+:py del t
+:$put =string(l)
+:"
+:" settrace
+:let l = []
+:py l=vim.bindeval('l')
+py <<EOF
+import sys
+
+def traceit(frame, event, arg):
+ global l
+ if event == "line":
+ l.extend([frame.f_lineno])
+ return traceit
+
+def trace_main():
+ for i in range(5):
+ pass
+EOF
+:py sys.settrace(traceit)
+:py trace_main()
+:py sys.settrace(None)
+:py del traceit
+:py del trace_main
+:$put =string(l)
+:"
+:" Slice
+:py ll = vim.bindeval('[0, 1, 2, 3, 4, 5]')
+:py l = ll[:4]
+:$put =string(pyeval('l'))
+:py l = ll[2:]
+:$put =string(pyeval('l'))
+:py l = ll[:-4]
+:$put =string(pyeval('l'))
+:py l = ll[-2:]
+:$put =string(pyeval('l'))
+:py l = ll[2:4]
+:$put =string(pyeval('l'))
+:py l = ll[4:2]
+:$put =string(pyeval('l'))
+:py l = ll[-4:-2]
+:$put =string(pyeval('l'))
+:py l = ll[-2:-4]
+:$put =string(pyeval('l'))
+:py l = ll[:]
+:$put =string(pyeval('l'))
+:py l = ll[0:6]
+:$put =string(pyeval('l'))
+:py l = ll[-10:10]
+:$put =string(pyeval('l'))
+:py l = ll[4:2:-1]
+:$put =string(pyeval('l'))
+:py l = ll[::2]
+:$put =string(pyeval('l'))
+:py l = ll[4:2:1]
+:$put =string(pyeval('l'))
+:py del l
+:"
+:" Vars
+:let g:foo = 'bac'
+:let w:abc3 = 'def'
+:let b:baz = 'bar'
+:let t:bar = 'jkl'
+:try
+: throw "Abc"
+:catch
+: put =pyeval('vim.vvars[''exception'']')
+:endtry
+:put =pyeval('vim.vars[''foo'']')
+:put =pyeval('vim.current.window.vars[''abc3'']')
+:put =pyeval('vim.current.buffer.vars[''baz'']')
+:put =pyeval('vim.current.tabpage.vars[''bar'']')
+:"
+:" Options
+:" paste: boolean, global
+:" previewheight number, global
+:" operatorfunc: string, global
+:" number: boolean, window-local
+:" numberwidth: number, window-local
+:" colorcolumn: string, window-local
+:" statusline: string, window-local/global
+:" autoindent: boolean, buffer-local
+:" shiftwidth: number, buffer-local
+:" omnifunc: string, buffer-local
+:" preserveindent: boolean, buffer-local/global
+:" path: string, buffer-local/global
+:let g:bufs=[bufnr('%')]
+:new
+:let g:bufs+=[bufnr('%')]
+:vnew
+:let g:bufs+=[bufnr('%')]
+:wincmd j
+:vnew
+:let g:bufs+=[bufnr('%')]
+:wincmd l
+:fun RecVars(opt)
+: let gval =string(eval('&g:'.a:opt))
+: let wvals=join(map(range(1, 4), 'v:val.":".string(getwinvar(v:val, "&".a:opt))'))
+: let bvals=join(map(copy(g:bufs), 'v:val.":".string(getbufvar(v:val, "&".a:opt))'))
+: put =' G: '.gval
+: put =' W: '.wvals
+: put =' B: '.wvals
+:endfun
+py << EOF
+def e(s, g=globals(), l=locals()):
+ try:
+ exec(s, g, l)
+ except:
+ vim.command('return ' + repr(sys.exc_type.__name__))
+
+def ev(s, g=globals(), l=locals()):
+ try:
+ return eval(s, g, l)
+ except:
+ vim.command('let exc=' + repr(sys.exc_type.__name__))
+ return 0
+EOF
+:fun E(s)
+: python e(vim.eval('a:s'))
+:endfun
+:fun Ev(s)
+: let r=pyeval('ev(vim.eval("a:s"))')
+: if exists('exc')
+: throw exc
+: endif
+: return r
+:endfun
+:py gopts1=vim.options
+:py wopts1=vim.windows[2].options
+:py wopts2=vim.windows[0].options
+:py wopts3=vim.windows[1].options
+:py bopts1=vim.buffers[vim.bindeval("g:bufs")[2]].options
+:py bopts2=vim.buffers[vim.bindeval("g:bufs")[1]].options
+:py bopts3=vim.buffers[vim.bindeval("g:bufs")[0]].options
+:$put ='wopts iters equal: '.pyeval('list(wopts1) == list(wopts2)')
+:$put ='bopts iters equal: '.pyeval('list(bopts1) == list(bopts2)')
+:py gset=set(iter(gopts1))
+:py wset=set(iter(wopts1))
+:py bset=set(iter(bopts1))
+:set path=.,..,,
+:let lst=[]
+:let lst+=[['paste', 1, 0, 1, 2, 1, 1, 0 ]]
+:let lst+=[['previewheight', 5, 1, 6, 'a', 0, 1, 0 ]]
+:let lst+=[['operatorfunc', 'A', 'B', 'C', 2, 0, 1, 0 ]]
+:let lst+=[['number', 0, 1, 1, 0, 1, 0, 1 ]]
+:let lst+=[['numberwidth', 2, 3, 5, -100, 0, 0, 1 ]]
+:let lst+=[['colorcolumn', '+1', '+2', '+3', 'abc4', 0, 0, 1 ]]
+:let lst+=[['statusline', '1', '2', '4', 0, 0, 1, 1 ]]
+:let lst+=[['autoindent', 0, 1, 1, 2, 1, 0, 2 ]]
+:let lst+=[['shiftwidth', 0, 2, 1, 3, 0, 0, 2 ]]
+:let lst+=[['omnifunc', 'A', 'B', 'C', 1, 0, 0, 2 ]]
+:let lst+=[['preserveindent', 0, 1, 1, 2, 1, 1, 2 ]]
+:let lst+=[['path', '.,,', ',,', '.', 0, 0, 1, 2 ]]
+:for [oname, oval1, oval2, oval3, invval, bool, global, local] in lst
+: py oname=vim.eval('oname')
+: py oval1=vim.bindeval('oval1')
+: py oval2=vim.bindeval('oval2')
+: py oval3=vim.bindeval('oval3')
+: if invval is 0 || invval is 1
+: py invval=bool(vim.bindeval('invval'))
+: else
+: py invval=vim.bindeval('invval')
+: endif
+: if bool
+: py oval1=bool(oval1)
+: py oval2=bool(oval2)
+: py oval3=bool(oval3)
+: endif
+: put ='>>> '.oname
+: $put =' g/w/b:'.pyeval('oname in gset').'/'.pyeval('oname in wset').'/'.pyeval('oname in bset')
+: $put =' g/w/b (in):'.pyeval('oname in gopts1').'/'.pyeval('oname in wopts1').'/'.pyeval('oname in bopts1')
+: for v in ['gopts1', 'wopts1', 'bopts1']
+: try
+: put =' p/'.v.': '.Ev('repr('.v.'['''.oname.'''])')
+: catch
+: put =' p/'.v.'! '.v:exception
+: endtry
+: let r=E(v.'['''.oname.''']=invval')
+: if r isnot 0
+: put =' inv: '.string(invval).'! '.r
+: endif
+: for vv in (v is# 'gopts1' ? [v] : [v, v[:-2].'2', v[:-2].'3'])
+: let val=substitute(vv, '^.opts', 'oval', '')
+: let r=E(vv.'['''.oname.''']='.val)
+: if r isnot 0
+: put =' '.vv.'! '.r
+: endif
+: endfor
+: endfor
+: call RecVars(oname)
+: for v in ['wopts3', 'bopts3']
+: let r=E('del '.v.'["'.oname.'"]')
+: if r isnot 0
+: put =' del '.v.'! '.r
+: endif
+: endfor
+: call RecVars(oname)
+:endfor
+:delfunction RecVars
+:delfunction E
+:delfunction Ev
+:py del ev
+:py del e
+:only
+:for buf in g:bufs[1:]
+: execute 'bwipeout!' buf
+:endfor
+:py del gopts1
+:py del wopts1
+:py del wopts2
+:py del wopts3
+:py del bopts1
+:py del bopts2
+:py del bopts3
+:py del oval1
+:py del oval2
+:py del oval3
+:py del oname
+:py del invval
+:"
+:" Test buffer object
+:vnew
+:put ='First line'
+:put ='Second line'
+:put ='Third line'
+:1 delete _
+:py b=vim.current.buffer
+:wincmd w
+:mark a
+:augroup BUFS
+: autocmd BufFilePost * python cb.append(vim.eval('expand("<abuf>")') + ':BufFilePost:' + vim.eval('bufnr("%")'))
+: autocmd BufFilePre * python cb.append(vim.eval('expand("<abuf>")') + ':BufFilePre:' + vim.eval('bufnr("%")'))
+:augroup END
+py << EOF
+cb = vim.current.buffer
+# Tests BufferAppend and BufferItem
+cb.append(b[0])
+# Tests BufferSlice and BufferAssSlice
+cb.append('abc5') # Will be overwritten
+cb[-1:] = b[:-2]
+# Test BufferLength and BufferAssSlice
+cb.append('def') # Will not be overwritten
+cb[len(cb):] = b[:]
+# Test BufferAssItem and BufferMark
+cb.append('ghi') # Will be overwritten
+cb[-1] = repr((len(cb) - cb.mark('a')[0], cb.mark('a')[1]))
+# Test BufferRepr
+cb.append(repr(cb) + repr(b))
+# Modify foreign buffer
+b.append('foo')
+b[0]='bar'
+b[0:0]=['baz']
+vim.command('call append("$", getbufline(%i, 1, "$"))' % b.number)
+# Test assigning to name property
+import os
+old_name = cb.name
+cb.name = 'foo'
+cb.append(cb.name[-11:].replace(os.path.sep, '/'))
+b.name = 'bar'
+cb.append(b.name[-11:].replace(os.path.sep, '/'))
+cb.name = old_name
+cb.append(cb.name[-17:].replace(os.path.sep, '/'))
+del old_name
+# Test CheckBuffer
+for _b in vim.buffers:
+ if _b is not cb:
+ vim.command('bwipeout! ' + str(_b.number))
+del _b
+cb.append('valid: b:%s, cb:%s' % (repr(b.valid), repr(cb.valid)))
+for expr in ('b[1]','b[:] = ["A", "B"]','b[:]','b.append("abc6")', 'b.name = "!"'):
+ try:
+ exec(expr)
+ except vim.error:
+ pass
+ else:
+ # Usually a SEGV here
+ # Should not happen in any case
+ cb.append('No exception for ' + expr)
+vim.command('cd .')
+del b
+EOF
+:augroup BUFS
+: autocmd!
+:augroup END
+:augroup! BUFS
+:"
+:" Test vim.buffers object
+:set hidden
+:edit a
+:buffer #
+:edit b
+:buffer #
+:edit c
+:buffer #
+py << EOF
+try:
+ from __builtin__ import next
+except ImportError:
+ next = lambda o: o.next()
+# Check GCing iterator that was not fully exhausted
+i = iter(vim.buffers)
+cb.append('i:' + str(next(i)))
+# and also check creating more then one iterator at a time
+i2 = iter(vim.buffers)
+cb.append('i2:' + str(next(i2)))
+cb.append('i:' + str(next(i)))
+# The following should trigger GC and not cause any problems
+del i
+del i2
+i3 = iter(vim.buffers)
+cb.append('i3:' + str(next(i3)))
+del i3
+
+prevnum = 0
+for b in vim.buffers:
+ # Check buffer order
+ if prevnum >= b.number:
+ cb.append('!!! Buffer numbers not in strictly ascending order')
+ # Check indexing: vim.buffers[number].number == number
+ cb.append(str(b.number) + ':' + repr(vim.buffers[b.number]) + '=' + repr(b))
+ prevnum = b.number
+del prevnum
+
+cb.append(str(len(vim.buffers)))
+
+bnums = list(map(lambda b: b.number, vim.buffers))[1:]
+
+# Test wiping out buffer with existing iterator
+i4 = iter(vim.buffers)
+cb.append('i4:' + str(next(i4)))
+vim.command('bwipeout! ' + str(bnums.pop(0)))
+try:
+ next(i4)
+except vim.error:
+ pass
+else:
+ cb.append('!!!! No vim.error')
+i4 = iter(vim.buffers)
+vim.command('bwipeout! ' + str(bnums.pop(-1)))
+vim.command('bwipeout! ' + str(bnums.pop(-1)))
+cb.append('i4:' + str(next(i4)))
+try:
+ next(i4)
+except StopIteration:
+ cb.append('StopIteration')
+del i4
+del bnums
+EOF
+:"
+:" Test vim.{tabpage,window}list and vim.{tabpage,window} objects
+:tabnew 0
+:tabnew 1
+:vnew a.1
+:tabnew 2
+:vnew a.2
+:vnew b.2
+:vnew c.2
+py << EOF
+cb.append('Number of tabs: ' + str(len(vim.tabpages)))
+cb.append('Current tab pages:')
+def W(w):
+ if repr(w).find('(unknown)') != -1:
+ return '<window object (unknown)>'
+ else:
+ return repr(w)
+
+start = len(cb)
+
+def Cursor(w):
+ if w.buffer is cb:
+ return repr((start - w.cursor[0], w.cursor[1]))
+ else:
+ return repr(w.cursor)
+
+for t in vim.tabpages:
+ cb.append(' ' + repr(t) + '(' + str(t.number) + ')' + ': ' + str(len(t.windows)) + ' windows, current is ' + W(t.window))
+ cb.append(' Windows:')
+ for w in t.windows:
+ cb.append(' ' + W(w) + '(' + str(w.number) + ')' + ': displays buffer ' + repr(w.buffer) + '; cursor is at ' + Cursor(w))
+ # Other values depend on the size of the terminal, so they are checked partly:
+ for attr in ('height', 'row', 'width', 'col'):
+ try:
+ aval = getattr(w, attr)
+ if type(aval) is not long:
+ raise TypeError
+ if aval < 0:
+ raise ValueError
+ except Exception:
+ cb.append('!!!!!! Error while getting attribute ' + attr + ': ' + sys.exc_type.__name__)
+ del aval
+ del attr
+ w.cursor = (len(w.buffer), 0)
+del W
+del Cursor
+cb.append('Number of windows in current tab page: ' + str(len(vim.windows)))
+if list(vim.windows) != list(vim.current.tabpage.windows):
+ cb.append('!!!!!! Windows differ')
+EOF
+:"
+:" Test vim.current
+py << EOF
+def H(o):
+ return repr(o)
+cb.append('Current tab page: ' + repr(vim.current.tabpage))
+cb.append('Current window: ' + repr(vim.current.window) + ': ' + H(vim.current.window) + ' is ' + H(vim.current.tabpage.window))
+cb.append('Current buffer: ' + repr(vim.current.buffer) + ': ' + H(vim.current.buffer) + ' is ' + H(vim.current.window.buffer)+ ' is ' + H(vim.current.tabpage.window.buffer))
+del H
+# Assigning: fails
+try:
+ vim.current.window = vim.tabpages[0].window
+except ValueError:
+ cb.append('ValueError at assigning foreign tab window')
+
+for attr in ('window', 'tabpage', 'buffer'):
+ try:
+ setattr(vim.current, attr, None)
+ except TypeError:
+ cb.append('Type error at assigning None to vim.current.' + attr)
+del attr
+
+# Assigning: success
+vim.current.tabpage = vim.tabpages[-2]
+vim.current.buffer = cb
+vim.current.window = vim.windows[0]
+vim.current.window.cursor = (len(vim.current.buffer), 0)
+cb.append('Current tab page: ' + repr(vim.current.tabpage))
+cb.append('Current window: ' + repr(vim.current.window))
+cb.append('Current buffer: ' + repr(vim.current.buffer))
+cb.append('Current line: ' + repr(vim.current.line))
+ws = list(vim.windows)
+ts = list(vim.tabpages)
+for b in vim.buffers:
+ if b is not cb:
+ vim.command('bwipeout! ' + str(b.number))
+del b
+cb.append('w.valid: ' + repr([w.valid for w in ws]))
+cb.append('t.valid: ' + repr([t.valid for t in ts]))
+del w
+del t
+del ts
+del ws
+EOF
+:tabonly!
+:only!
+:"
+:" Test types
+py << EOF
+for expr, attr in (
+ ('vim.vars', 'Dictionary'),
+ ('vim.options', 'Options'),
+ ('vim.bindeval("{}")', 'Dictionary'),
+ ('vim.bindeval("[]")', 'List'),
+ ('vim.bindeval("function(\'tr\')")', 'Function'),
+ ('vim.current.buffer', 'Buffer'),
+ ('vim.current.range', 'Range'),
+ ('vim.current.window', 'Window'),
+ ('vim.current.tabpage', 'TabPage'),
+):
+ cb.append(expr + ':' + attr + ':' + repr(type(eval(expr)) is getattr(vim, attr)))
+del expr
+del attr
+EOF
+:"
+:" Test __dir__() method
+py << EOF
+for name, o in (
+ ('current', vim.current),
+ ('buffer', vim.current.buffer),
+ ('window', vim.current.window),
+ ('tabpage', vim.current.tabpage),
+ ('range', vim.current.range),
+ ('dictionary', vim.bindeval('{}')),
+ ('list', vim.bindeval('[]')),
+ ('function', vim.bindeval('function("tr")')),
+ ('output', sys.stdout),
+ ):
+ cb.append(name + ':' + ','.join(dir(o)))
+del name
+del o
+EOF
+:"
+:" Test vim.*.__new__
+:$put =string(pyeval('vim.Dictionary({})'))
+:$put =string(pyeval('vim.Dictionary(a=1)'))
+:$put =string(pyeval('vim.Dictionary(((''a'', 1),))'))
+:$put =string(pyeval('vim.List()'))
+:$put =string(pyeval('vim.List(iter(''abc7''))'))
+:$put =string(pyeval('vim.Function(''tr'')'))
+:"
+:" Test stdout/stderr
+:redir => messages
+:py sys.stdout.write('abc8') ; sys.stdout.write('def')
+:py sys.stderr.write('abc9') ; sys.stderr.write('def')
+:py sys.stdout.writelines(iter('abcA'))
+:py sys.stderr.writelines(iter('abcB'))
+:redir END
+:$put =string(substitute(messages, '\d\+', '', 'g'))
+:" Test subclassing
+:fun Put(...)
+: $put =string(a:000)
+: return a:000
+:endfun
+py << EOF
+class DupDict(vim.Dictionary):
+ def __setitem__(self, key, value):
+ super(DupDict, self).__setitem__(key, value)
+ super(DupDict, self).__setitem__('dup_' + key, value)
+dd = DupDict()
+dd['a'] = 'b'
+
+class DupList(vim.List):
+ def __getitem__(self, idx):
+ return [super(DupList, self).__getitem__(idx)] * 2
+
+dl = DupList()
+dl2 = DupList(iter('abcC'))
+dl.extend(dl2[0])
+
+class DupFun(vim.Function):
+ def __call__(self, arg):
+ return super(DupFun, self).__call__(arg, arg)
+
+df = DupFun('Put')
+EOF
+:$put =string(sort(keys(pyeval('dd'))))
+:$put =string(pyeval('dl'))
+:$put =string(pyeval('dl2'))
+:$put =string(pyeval('df(2)'))
+:$put =string(pyeval('dl') is# pyeval('dl'))
+:$put =string(pyeval('dd') is# pyeval('dd'))
+:$put =string(pyeval('df'))
+:delfunction Put
+py << EOF
+del DupDict
+del DupList
+del DupFun
+del dd
+del dl
+del dl2
+del df
+EOF
+:"
+:" Test chdir
+py << EOF
+import os
+fnamemodify = vim.Function('fnamemodify')
+cb.append(fnamemodify('.', ':p:h:t'))
+cb.append(vim.eval('@%'))
+os.chdir('..')
+path = fnamemodify('.', ':p:h:t')
+if path != 'src':
+ # Running tests from a shadow directory, so move up another level
+ # This will result in @% looking like shadow/testdir/test86.in, hence the
+ # extra fnamemodify
+ os.chdir('..')
+ cb.append(fnamemodify('.', ':p:h:t'))
+ cb.append(fnamemodify(vim.eval('@%'), ':s?^%s.??' % path).replace(os.path.sep, '/'))
+ os.chdir(path)
+ del path
+else:
+ cb.append(fnamemodify('.', ':p:h:t'))
+ cb.append(vim.eval('@%').replace(os.path.sep, '/'))
+os.chdir('testdir')
+cb.append(fnamemodify('.', ':p:h:t'))
+cb.append(vim.eval('@%'))
+del fnamemodify
+EOF
+:"
+:" Test errors
+:fun F() dict
+:endfun
+:fun D()
+:endfun
+py << EOF
+d = vim.Dictionary()
+ned = vim.Dictionary(foo='bar', baz='abcD')
+dl = vim.Dictionary(a=1)
+dl.locked = True
+l = vim.List()
+ll = vim.List('abcE')
+ll.locked = True
+nel = vim.List('abcO')
+f = vim.Function('string')
+fd = vim.Function('F')
+fdel = vim.Function('D')
+vim.command('delfunction D')
+
+def subexpr_test(expr, name, subexprs):
+ cb.append('>>> Testing %s using %s' % (name, expr))
+ for subexpr in subexprs:
+ ee(expr % subexpr)
+ cb.append('<<< Finished')
+
+def stringtochars_test(expr):
+ return subexpr_test(expr, 'StringToChars', (
+ '1', # Fail type checks
+ 'u"\\0"', # Fail PyString_AsStringAndSize(bytes, , NULL) check
+ '"\\0"', # Fail PyString_AsStringAndSize(object, , NULL) check
+ ))
+
+class Mapping(object):
+ def __init__(self, d):
+ self.d = d
+
+ def __getitem__(self, key):
+ return self.d[key]
+
+ def keys(self):
+ return self.d.keys()
+
+ def items(self):
+ return self.d.items()
+
+def convertfrompyobject_test(expr, recurse=True):
+ # pydict_to_tv
+ stringtochars_test(expr % '{%s : 1}')
+ if recurse:
+ convertfrompyobject_test(expr % '{"abcF" : %s}', False)
+ # pymap_to_tv
+ stringtochars_test(expr % 'Mapping({%s : 1})')
+ if recurse:
+ convertfrompyobject_test(expr % 'Mapping({"abcG" : %s})', False)
+ # pyseq_to_tv
+ iter_test(expr)
+ return subexpr_test(expr, 'ConvertFromPyObject', (
+ 'None', # Not conversible
+ '{"": 1}', # Empty key not allowed
+ '{u"": 1}', # Same, but with unicode object
+ 'FailingMapping()', #
+ 'FailingMappingKey()', #
+ 'FailingNumber()', #
+ ))
+
+def convertfrompymapping_test(expr):
+ convertfrompyobject_test(expr)
+ return subexpr_test(expr, 'ConvertFromPyMapping', (
+ '[]',
+ ))
+
+def iter_test(expr):
+ return subexpr_test(expr, '*Iter*', (
+ 'FailingIter()',
+ 'FailingIterNext()',
+ ))
+
+def number_test(expr, natural=False, unsigned=False):
+ if natural:
+ unsigned = True
+ return subexpr_test(expr, 'NumberToLong', (
+ '[]',
+ 'None',
+ ) + (unsigned and ('-1',) or ())
+ + (natural and ('0',) or ()))
+
+class FailingTrue(object):
+ def __nonzero__(self):
+ raise NotImplementedError('bool')
+
+class FailingIter(object):
+ def __iter__(self):
+ raise NotImplementedError('iter')
+
+class FailingIterNext(object):
+ def __iter__(self):
+ return self
+
+ def next(self):
+ raise NotImplementedError('next')
+
+class FailingIterNextN(object):
+ def __init__(self, n):
+ self.n = n
+
+ def __iter__(self):
+ return self
+
+ def next(self):
+ if self.n:
+ self.n -= 1
+ return 1
+ else:
+ raise NotImplementedError('next N')
+
+class FailingMappingKey(object):
+ def __getitem__(self, item):
+ raise NotImplementedError('getitem:mappingkey')
+
+ def keys(self):
+ return list("abcH")
+
+class FailingMapping(object):
+ def __getitem__(self):
+ raise NotImplementedError('getitem:mapping')
+
+ def keys(self):
+ raise NotImplementedError('keys')
+
+class FailingList(list):
+ def __getitem__(self, idx):
+ if i == 2:
+ raise NotImplementedError('getitem:list')
+ else:
+ return super(FailingList, self).__getitem__(idx)
+
+class NoArgsCall(object):
+ def __call__(self):
+ pass
+
+class FailingCall(object):
+ def __call__(self, path):
+ raise NotImplementedError('call')
+
+class FailingNumber(object):
+ def __int__(self):
+ raise NotImplementedError('int')
+
+cb.append("> Output")
+cb.append(">> OutputSetattr")
+ee('del sys.stdout.softspace')
+number_test('sys.stdout.softspace = %s', unsigned=True)
+number_test('sys.stderr.softspace = %s', unsigned=True)
+ee('sys.stdout.attr = None')
+cb.append(">> OutputWrite")
+ee('sys.stdout.write(None)')
+cb.append(">> OutputWriteLines")
+ee('sys.stdout.writelines(None)')
+ee('sys.stdout.writelines([1])')
+iter_test('sys.stdout.writelines(%s)')
+cb.append("> VimCommand")
+stringtochars_test('vim.command(%s)')
+ee('vim.command("", 2)')
+#! Not checked: vim->python exceptions translating: checked later
+cb.append("> VimToPython")
+#! Not checked: everything: needs errors in internal python functions
+cb.append("> VimEval")
+stringtochars_test('vim.eval(%s)')
+ee('vim.eval("", FailingTrue())')
+#! Not checked: everything: needs errors in internal python functions
+cb.append("> VimEvalPy")
+stringtochars_test('vim.bindeval(%s)')
+ee('vim.eval("", 2)')
+#! Not checked: vim->python exceptions translating: checked later
+cb.append("> VimStrwidth")
+stringtochars_test('vim.strwidth(%s)')
+cb.append("> VimForeachRTP")
+ee('vim.foreach_rtp(None)')
+ee('vim.foreach_rtp(NoArgsCall())')
+ee('vim.foreach_rtp(FailingCall())')
+ee('vim.foreach_rtp(int, 2)')
+cb.append('> import')
+old_rtp = vim.options['rtp']
+vim.options['rtp'] = os.getcwd().replace(',', '\\,').replace('\\', '\\\\')
+ee('import xxx_no_such_module_xxx')
+ee('import failing_import')
+ee('import failing')
+vim.options['rtp'] = old_rtp
+del old_rtp
+cb.append("> Options")
+cb.append(">> OptionsItem")
+ee('vim.options["abcQ"]')
+ee('vim.options[""]')
+stringtochars_test('vim.options[%s]')
+cb.append(">> OptionsContains")
+stringtochars_test('%s in vim.options')
+cb.append("> Dictionary")
+cb.append(">> DictionaryConstructor")
+ee('vim.Dictionary("abcI")')
+##! Not checked: py_dict_alloc failure
+cb.append(">> DictionarySetattr")
+ee('del d.locked')
+ee('d.locked = FailingTrue()')
+ee('vim.vvars.locked = False')
+ee('d.scope = True')
+ee('d.xxx = True')
+cb.append(">> _DictionaryItem")
+ee('d.get("a", 2, 3)')
+stringtochars_test('d.get(%s)')
+ee('d.pop("a")')
+ee('dl.pop("a")')
+cb.append(">> DictionaryContains")
+ee('"" in d')
+ee('0 in d')
+cb.append(">> DictionaryIterNext")
+ee('for i in ned: ned["a"] = 1')
+del i
+cb.append(">> DictionaryAssItem")
+ee('dl["b"] = 1')
+stringtochars_test('d[%s] = 1')
+convertfrompyobject_test('d["a"] = %s')
+cb.append(">> DictionaryUpdate")
+cb.append(">>> kwargs")
+cb.append(">>> iter")
+ee('d.update(FailingMapping())')
+ee('d.update([FailingIterNext()])')
+ee('d.update([FailingIterNextN(1)])')
+iter_test('d.update(%s)')
+convertfrompyobject_test('d.update(%s)')
+stringtochars_test('d.update(((%s, 0),))')
+convertfrompyobject_test('d.update((("a", %s),))')
+cb.append(">> DictionaryPopItem")
+ee('d.popitem(1, 2)')
+cb.append(">> DictionaryHasKey")
+ee('d.has_key()')
+cb.append("> List")
+cb.append(">> ListConstructor")
+ee('vim.List(1, 2)')
+ee('vim.List(a=1)')
+iter_test('vim.List(%s)')
+convertfrompyobject_test('vim.List([%s])')
+cb.append(">> ListItem")
+ee('l[1000]')
+cb.append(">> ListAssItem")
+ee('ll[1] = 2')
+ee('l[1000] = 3')
+cb.append(">> ListAssSlice")
+ee('ll[1:100] = "abcJ"')
+iter_test('l[:] = %s')
+ee('nel[1:10:2] = "abcK"')
+cb.append(repr(tuple(nel)))
+ee('nel[1:10:2] = "a"')
+cb.append(repr(tuple(nel)))
+ee('nel[1:1:-1] = "a"')
+cb.append(repr(tuple(nel)))
+ee('nel[:] = FailingIterNextN(2)')
+cb.append(repr(tuple(nel)))
+convertfrompyobject_test('l[:] = [%s]')
+cb.append(">> ListConcatInPlace")
+iter_test('l.extend(%s)')
+convertfrompyobject_test('l.extend([%s])')
+cb.append(">> ListSetattr")
+ee('del l.locked')
+ee('l.locked = FailingTrue()')
+ee('l.xxx = True')
+cb.append("> Function")
+cb.append(">> FunctionConstructor")
+ee('vim.Function("123")')
+ee('vim.Function("xxx_non_existent_function_xxx")')
+ee('vim.Function("xxx#non#existent#function#xxx")')
+cb.append(">> FunctionCall")
+convertfrompyobject_test('f(%s)')
+convertfrompymapping_test('fd(self=%s)')
+cb.append("> TabPage")
+cb.append(">> TabPageAttr")
+ee('vim.current.tabpage.xxx')
+cb.append("> TabList")
+cb.append(">> TabListItem")
+ee('vim.tabpages[1000]')
+cb.append("> Window")
+cb.append(">> WindowAttr")
+ee('vim.current.window.xxx')
+cb.append(">> WindowSetattr")
+ee('vim.current.window.buffer = 0')
+ee('vim.current.window.cursor = (100000000, 100000000)')
+ee('vim.current.window.cursor = True')
+number_test('vim.current.window.height = %s', unsigned=True)
+number_test('vim.current.window.width = %s', unsigned=True)
+ee('vim.current.window.xxxxxx = True')
+cb.append("> WinList")
+cb.append(">> WinListItem")
+ee('vim.windows[1000]')
+cb.append("> Buffer")
+cb.append(">> StringToLine (indirect)")
+ee('vim.current.buffer[0] = u"\\na"')
+ee('vim.current.buffer[0] = "\\na"')
+cb.append(">> SetBufferLine (indirect)")
+ee('vim.current.buffer[0] = True')
+cb.append(">> SetBufferLineList (indirect)")
+ee('vim.current.buffer[:] = True')
+ee('vim.current.buffer[:] = ["\\na", "bc"]')
+cb.append(">> InsertBufferLines (indirect)")
+ee('vim.current.buffer.append(None)')
+ee('vim.current.buffer.append(["\\na", "bc"])')
+ee('vim.current.buffer.append("\\nbc")')
+cb.append(">> RBItem")
+ee('vim.current.buffer[100000000]')
+cb.append(">> RBAsItem")
+ee('vim.current.buffer[100000000] = ""')
+cb.append(">> BufferAttr")
+ee('vim.current.buffer.xxx')
+cb.append(">> BufferSetattr")
+ee('vim.current.buffer.name = True')
+ee('vim.current.buffer.xxx = True')
+cb.append(">> BufferMark")
+ee('vim.current.buffer.mark(0)')
+ee('vim.current.buffer.mark("abcM")')
+ee('vim.current.buffer.mark("!")')
+cb.append(">> BufferRange")
+ee('vim.current.buffer.range(1, 2, 3)')
+cb.append("> BufMap")
+cb.append(">> BufMapItem")
+ee('vim.buffers[100000000]')
+number_test('vim.buffers[%s]', natural=True)
+cb.append("> Current")
+cb.append(">> CurrentGetattr")
+ee('vim.current.xxx')
+cb.append(">> CurrentSetattr")
+ee('vim.current.line = True')
+ee('vim.current.buffer = True')
+ee('vim.current.window = True')
+ee('vim.current.tabpage = True')
+ee('vim.current.xxx = True')
+del d
+del ned
+del dl
+del l
+del ll
+del nel
+del f
+del fd
+del fdel
+del subexpr_test
+del stringtochars_test
+del Mapping
+del convertfrompyobject_test
+del convertfrompymapping_test
+del iter_test
+del number_test
+del FailingTrue
+del FailingIter
+del FailingIterNext
+del FailingIterNextN
+del FailingMapping
+del FailingMappingKey
+del FailingList
+del NoArgsCall
+del FailingCall
+del FailingNumber
+EOF
+:delfunction F
+:"
+:" Test import
+py << EOF
+sys.path.insert(0, os.path.join(os.getcwd(), 'python_before'))
+sys.path.append(os.path.join(os.getcwd(), 'python_after'))
+vim.options['rtp'] = os.getcwd().replace(',', '\\,').replace('\\', '\\\\')
+l = []
+def callback(path):
+ l.append(path[-len('/testdir'):].replace(os.path.sep, '/'))
+vim.foreach_rtp(callback)
+cb.append(repr(l))
+del l
+def callback(path):
+ return path[-len('/testdir'):].replace(os.path.sep, '/')
+cb.append(repr(vim.foreach_rtp(callback)))
+del callback
+from module import dir as d
+from modulex import ddir
+cb.append(d + ',' + ddir)
+import before
+cb.append(before.dir)
+import after
+cb.append(after.dir)
+import topmodule as tm
+import topmodule.submodule as tms
+import topmodule.submodule.subsubmodule.subsubsubmodule as tmsss
+cb.append(tm.__file__.replace('.pyc', '.py').replace(os.path.sep, '/')[-len('modulex/topmodule/__init__.py'):])
+cb.append(tms.__file__.replace('.pyc', '.py').replace(os.path.sep, '/')[-len('modulex/topmodule/submodule/__init__.py'):])
+cb.append(tmsss.__file__.replace('.pyc', '.py').replace(os.path.sep, '/')[-len('modulex/topmodule/submodule/subsubmodule/subsubsubmodule.py'):])
+del before
+del after
+del d
+del ddir
+del tm
+del tms
+del tmsss
+EOF
+:"
+:" Test exceptions
+:fun Exe(e)
+: execute a:e
+:endfun
+py << EOF
+Exe = vim.bindeval('function("Exe")')
+ee('vim.command("throw \'abcN\'")')
+ee('Exe("throw \'def\'")')
+ee('vim.eval("Exe(\'throw \'\'ghi\'\'\')")')
+ee('vim.eval("Exe(\'echoerr \'\'jkl\'\'\')")')
+ee('vim.eval("Exe(\'xxx_non_existent_command_xxx\')")')
+ee('vim.eval("xxx_unknown_function_xxx()")')
+ee('vim.bindeval("Exe(\'xxx_non_existent_command_xxx\')")')
+del Exe
+EOF
+:delfunction Exe
+:"
+:" Regression: interrupting vim.command propagates to next vim.command
+py << EOF
+def test_keyboard_interrupt():
+ try:
+ vim.command('while 1 | endwhile')
+ except KeyboardInterrupt:
+ cb.append('Caught KeyboardInterrupt')
+ except Exception:
+ cb.append('!!!!!!!! Caught exception: ' + repr(sys.exc_info))
+ else:
+ cb.append('!!!!!!!! No exception')
+ try:
+ vim.command('$ put =\'Running :put\'')
+ except KeyboardInterrupt:
+ cb.append('!!!!!!!! Caught KeyboardInterrupt')
+ except Exception:
+ cb.append('!!!!!!!! Caught exception: ' + repr(sys.exc_info))
+ else:
+ cb.append('No exception')
+EOF
+:debuggreedy
+:call inputsave()
+:call feedkeys("s\ns\ns\ns\nq\n")
+:redir => output
+:debug silent! py test_keyboard_interrupt()
+:redir END
+:0 debuggreedy
+:silent $put =output
+:unlet output
+:py del test_keyboard_interrupt
+:"
+:" Cleanup
+py << EOF
+del cb
+del ee
+del sys
+del os
+del vim
+EOF
+:endfun
+:"
+:fun RunTest()
+:let checkrefs = !empty($PYTHONDUMPREFS)
+:let start = getline(1, '$')
+:for i in range(checkrefs ? 10 : 1)
+: if i != 0
+: %d _
+: call setline(1, start)
+: endif
+: call Test()
+: if i == 0
+: let result = getline(1, '$')
+: endif
+:endfor
+:if checkrefs
+: %d _
+: call setline(1, result)
+:endif
+:endfun
+:"
+:call RunTest()
+:delfunction RunTest
+:delfunction Test
+:call garbagecollect(1)
+:"
+:/^start:/,$wq! test.out
+:" vim: et ts=4 isk-=\:
+:call getchar()
+ENDTEST
+
+start:
diff --git a/src/testdir/test86.ok b/src/testdir/test86.ok
new file mode 100644
index 0000000000..257a5ee4cd
--- /dev/null
+++ b/src/testdir/test86.ok
@@ -0,0 +1,1266 @@
+start:
+[1, 'as''d', [1, 2, function('strlen'), {'a': 1}]]
+[1, 2, function('strlen'), {'a': 1}]
+Vim(put):E684:
+[0, 'as''d', [1, 2, function('strlen'), {'a': 1}]]
+[0, function('strlen'), [1, 2, function('strlen'), {'a': 1}]]
+1
+['-1', '0', '1', 'b', 'f']
+['asd', -1L, <vim.Function '1'>, <vim.dictionary object at >, <vim.list object at >]
+[('-1', <vim.dictionary object at >), ('0', -1L), ('1', 'asd'), ('b', <vim.list object at >), ('f', <vim.Function '1'>)]
+'-1' : {'a': 1}
+'0' : -1
+'1' : 'asd'
+'b' : [1, 2, function('strlen')]
+'f' : function('1')
+[0, function('strlen')]
+[3]
+[1, 2, function('strlen')]
+[1, 2, function('strlen')]
+1
+'asd'
+2
+True
+False
+True
+False
+['0']
+{'0': -1}
+('0', -1L)
+None
+[]
+[0, 1, 2, 3]
+[0, 1, 2, 3]
+[0, 1, 3]
+[0, 1]
+[0, 1]
+[0, 1]
+[0, 1, 2, 3]
+[0, 1, 2, 3]
+[0, 2, 3]
+[2, 3]
+[2, 3]
+[2, 3]
+[1, 3]
+[0, 2]
+[0, 1, 2, 3]
+['a', 0, 1, 2, 3]
+[0, 'b', 2, 3]
+[0, 1, 'c']
+[0, 1, 2, 3, 'd']
+[0, 1, 2, 'e', 3]
+['f', 2, 3]
+[0, 1, 'g', 2, 3]
+['h']
+[0, 1, 10, 3, 20, 5, 6, 7]
+[0, 1, 2, 3, 20, 5, 10, 7]
+[0, 1, 2, 3, 4, 5, 6, 7]
+[0, 1, 2, 3, 4, 5, 6, 7]
+[0, 1, 2, 3, 4, 5, 6, 7]
+[0, 1, 2, 3]
+[function('New'), function('DictNew'), 'NewStart', 1, 2, 3, 'NewEnd']
+[function('New'), function('DictNew'), 'NewStart', 1, 2, 3, 'NewEnd', 'DictNewStart', 1, 2, 3, 'DictNewEnd', {'a': 'b'}]
+[function('New'), function('DictNew'), 'NewStart', 1, 2, 3, 'NewEnd', 'DictNewStart', 1, 2, 3, 'DictNewEnd', {'a': 'b'}, 'New']
+l[1](1, 2, 3):error:('Vim:E725: Calling dict function without Dictionary: DictNew',)
+f(1, 2, 3):error:('Vim:E117: Unknown function: New',)
+[0.0, 0.0]
+KeyError
+TypeError
+TypeError
+ValueError
+TypeError
+TypeError
+KeyError
+KeyError
+d : locked:0;scope:0
+dl : locked:1;scope:0
+v: : locked:2;scope:1
+g: : locked:0;scope:2
+d:{'abc2': 1}
+dl:{'def': 1}
+l : locked:0
+ll : locked:1
+l:[0]
+ll:[1]
+[0, 1, 2]
+['a', 'b']
+['c', 1]
+['d', ['e']]
+0.0
+"\0": Vim(let):E859:
+{"\0": 1}: Vim(let):E859:
+undefined_name: Vim(let):Trace
+vim: Vim(let):E859:
+[1]
+[1, 10, 11, 10, 11, 10, 11, 10, 11, 10, 11, 10, 1]
+[0, 1, 2, 3]
+[2, 3, 4, 5]
+[0, 1]
+[4, 5]
+[2, 3]
+[]
+[2, 3]
+[]
+[0, 1, 2, 3, 4, 5]
+[0, 1, 2, 3, 4, 5]
+[0, 1, 2, 3, 4, 5]
+[4, 3]
+[0, 2, 4]
+[]
+Abc
+bac
+def
+bar
+jkl
+wopts iters equal: 1
+bopts iters equal: 1
+>>> paste
+ g/w/b:1/0/0
+ g/w/b (in):1/0/0
+ p/gopts1: False
+ p/wopts1! KeyError
+ inv: 2! KeyError
+ wopts1! KeyError
+ wopts2! KeyError
+ wopts3! KeyError
+ p/bopts1! KeyError
+ inv: 2! KeyError
+ bopts1! KeyError
+ bopts2! KeyError
+ bopts3! KeyError
+ G: 1
+ W: 1:1 2:1 3:1 4:1
+ B: 1:1 2:1 3:1 4:1
+ del wopts3! KeyError
+ del bopts3! KeyError
+ G: 1
+ W: 1:1 2:1 3:1 4:1
+ B: 1:1 2:1 3:1 4:1
+>>> previewheight
+ g/w/b:1/0/0
+ g/w/b (in):1/0/0
+ p/gopts1: 12
+ inv: 'a'! TypeError
+ p/wopts1! KeyError
+ inv: 'a'! KeyError
+ wopts1! KeyError
+ wopts2! KeyError
+ wopts3! KeyError
+ p/bopts1! KeyError
+ inv: 'a'! KeyError
+ bopts1! KeyError
+ bopts2! KeyError
+ bopts3! KeyError
+ G: 5
+ W: 1:5 2:5 3:5 4:5
+ B: 1:5 2:5 3:5 4:5
+ del wopts3! KeyError
+ del bopts3! KeyError
+ G: 5
+ W: 1:5 2:5 3:5 4:5
+ B: 1:5 2:5 3:5 4:5
+>>> operatorfunc
+ g/w/b:1/0/0
+ g/w/b (in):1/0/0
+ p/gopts1: ''
+ inv: 2! TypeError
+ p/wopts1! KeyError
+ inv: 2! KeyError
+ wopts1! KeyError
+ wopts2! KeyError
+ wopts3! KeyError
+ p/bopts1! KeyError
+ inv: 2! KeyError
+ bopts1! KeyError
+ bopts2! KeyError
+ bopts3! KeyError
+ G: 'A'
+ W: 1:'A' 2:'A' 3:'A' 4:'A'
+ B: 1:'A' 2:'A' 3:'A' 4:'A'
+ del wopts3! KeyError
+ del bopts3! KeyError
+ G: 'A'
+ W: 1:'A' 2:'A' 3:'A' 4:'A'
+ B: 1:'A' 2:'A' 3:'A' 4:'A'
+>>> number
+ g/w/b:0/1/0
+ g/w/b (in):0/1/0
+ p/gopts1! KeyError
+ inv: 0! KeyError
+ gopts1! KeyError
+ p/wopts1: False
+ p/bopts1! KeyError
+ inv: 0! KeyError
+ bopts1! KeyError
+ bopts2! KeyError
+ bopts3! KeyError
+ G: 0
+ W: 1:1 2:1 3:0 4:0
+ B: 1:1 2:1 3:0 4:0
+ del wopts3! ValueError
+ del bopts3! KeyError
+ G: 0
+ W: 1:1 2:1 3:0 4:0
+ B: 1:1 2:1 3:0 4:0
+>>> numberwidth
+ g/w/b:0/1/0
+ g/w/b (in):0/1/0
+ p/gopts1! KeyError
+ inv: -100! KeyError
+ gopts1! KeyError
+ p/wopts1: 8
+ inv: -100! error
+ p/bopts1! KeyError
+ inv: -100! KeyError
+ bopts1! KeyError
+ bopts2! KeyError
+ bopts3! KeyError
+ G: 8
+ W: 1:3 2:5 3:2 4:8
+ B: 1:3 2:5 3:2 4:8
+ del wopts3! ValueError
+ del bopts3! KeyError
+ G: 8
+ W: 1:3 2:5 3:2 4:8
+ B: 1:3 2:5 3:2 4:8
+>>> colorcolumn
+ g/w/b:0/1/0
+ g/w/b (in):0/1/0
+ p/gopts1! KeyError
+ inv: 'abc4'! KeyError
+ gopts1! KeyError
+ p/wopts1: ''
+ inv: 'abc4'! error
+ p/bopts1! KeyError
+ inv: 'abc4'! KeyError
+ bopts1! KeyError
+ bopts2! KeyError
+ bopts3! KeyError
+ G: ''
+ W: 1:'+2' 2:'+3' 3:'+1' 4:''
+ B: 1:'+2' 2:'+3' 3:'+1' 4:''
+ del wopts3! ValueError
+ del bopts3! KeyError
+ G: ''
+ W: 1:'+2' 2:'+3' 3:'+1' 4:''
+ B: 1:'+2' 2:'+3' 3:'+1' 4:''
+>>> statusline
+ g/w/b:1/1/0
+ g/w/b (in):1/1/0
+ p/gopts1: ''
+ inv: 0! TypeError
+ p/wopts1: None
+ inv: 0! TypeError
+ p/bopts1! KeyError
+ inv: 0! KeyError
+ bopts1! KeyError
+ bopts2! KeyError
+ bopts3! KeyError
+ G: '1'
+ W: 1:'2' 2:'4' 3:'1' 4:'1'
+ B: 1:'2' 2:'4' 3:'1' 4:'1'
+ del bopts3! KeyError
+ G: '1'
+ W: 1:'2' 2:'1' 3:'1' 4:'1'
+ B: 1:'2' 2:'1' 3:'1' 4:'1'
+>>> autoindent
+ g/w/b:0/0/1
+ g/w/b (in):0/0/1
+ p/gopts1! KeyError
+ inv: 2! KeyError
+ gopts1! KeyError
+ p/wopts1! KeyError
+ inv: 2! KeyError
+ wopts1! KeyError
+ wopts2! KeyError
+ wopts3! KeyError
+ p/bopts1: False
+ G: 0
+ W: 1:0 2:1 3:0 4:1
+ B: 1:0 2:1 3:0 4:1
+ del wopts3! KeyError
+ del bopts3! ValueError
+ G: 0
+ W: 1:0 2:1 3:0 4:1
+ B: 1:0 2:1 3:0 4:1
+>>> shiftwidth
+ g/w/b:0/0/1
+ g/w/b (in):0/0/1
+ p/gopts1! KeyError
+ inv: 3! KeyError
+ gopts1! KeyError
+ p/wopts1! KeyError
+ inv: 3! KeyError
+ wopts1! KeyError
+ wopts2! KeyError
+ wopts3! KeyError
+ p/bopts1: 8
+ G: 8
+ W: 1:0 2:2 3:8 4:1
+ B: 1:0 2:2 3:8 4:1
+ del wopts3! KeyError
+ del bopts3! ValueError
+ G: 8
+ W: 1:0 2:2 3:8 4:1
+ B: 1:0 2:2 3:8 4:1
+>>> omnifunc
+ g/w/b:0/0/1
+ g/w/b (in):0/0/1
+ p/gopts1! KeyError
+ inv: 1! KeyError
+ gopts1! KeyError
+ p/wopts1! KeyError
+ inv: 1! KeyError
+ wopts1! KeyError
+ wopts2! KeyError
+ wopts3! KeyError
+ p/bopts1: ''
+ inv: 1! TypeError
+ G: ''
+ W: 1:'A' 2:'B' 3:'' 4:'C'
+ B: 1:'A' 2:'B' 3:'' 4:'C'
+ del wopts3! KeyError
+ del bopts3! ValueError
+ G: ''
+ W: 1:'A' 2:'B' 3:'' 4:'C'
+ B: 1:'A' 2:'B' 3:'' 4:'C'
+>>> preserveindent
+ g/w/b:0/0/1
+ g/w/b (in):0/0/1
+ p/gopts1! KeyError
+ inv: 2! KeyError
+ gopts1! KeyError
+ p/wopts1! KeyError
+ inv: 2! KeyError
+ wopts1! KeyError
+ wopts2! KeyError
+ wopts3! KeyError
+ p/bopts1: False
+ G: 0
+ W: 1:0 2:1 3:0 4:1
+ B: 1:0 2:1 3:0 4:1
+ del wopts3! KeyError
+ del bopts3! ValueError
+ G: 0
+ W: 1:0 2:1 3:0 4:1
+ B: 1:0 2:1 3:0 4:1
+>>> path
+ g/w/b:1/0/1
+ g/w/b (in):1/0/1
+ p/gopts1: '.,..,,'
+ inv: 0! TypeError
+ p/wopts1! KeyError
+ inv: 0! KeyError
+ wopts1! KeyError
+ wopts2! KeyError
+ wopts3! KeyError
+ p/bopts1: None
+ inv: 0! TypeError
+ G: '.,,'
+ W: 1:'.,,' 2:',,' 3:'.,,' 4:'.'
+ B: 1:'.,,' 2:',,' 3:'.,,' 4:'.'
+ del wopts3! KeyError
+ G: '.,,'
+ W: 1:'.,,' 2:',,' 3:'.,,' 4:'.,,'
+ B: 1:'.,,' 2:',,' 3:'.,,' 4:'.,,'
+First line
+First line
+def
+First line
+Second line
+Third line
+(7, 2)
+<buffer test86.in><buffer >
+baz
+bar
+Second line
+Third line
+foo
+1:BufFilePre:1
+1:BufFilePost:1
+testdir/foo
+5:BufFilePre:5
+5:BufFilePost:5
+testdir/bar
+1:BufFilePre:1
+1:BufFilePost:1
+testdir/test86.in
+valid: b:False, cb:True
+i:<buffer test86.in>
+i2:<buffer test86.in>
+i:<buffer a>
+i3:<buffer test86.in>
+1:<buffer test86.in>=<buffer test86.in>
+8:<buffer a>=<buffer a>
+9:<buffer b>=<buffer b>
+10:<buffer c>=<buffer c>
+4
+i4:<buffer test86.in>
+i4:<buffer test86.in>
+StopIteration
+Number of tabs: 4
+Current tab pages:
+ <tabpage 0>(1): 1 windows, current is <window object (unknown)>
+ Windows:
+ <window object (unknown)>(1): displays buffer <buffer test86.in>; cursor is at (37, 0)
+ <tabpage 1>(2): 1 windows, current is <window object (unknown)>
+ Windows:
+ <window object (unknown)>(1): displays buffer <buffer 0>; cursor is at (1, 0)
+ <tabpage 2>(3): 2 windows, current is <window object (unknown)>
+ Windows:
+ <window object (unknown)>(1): displays buffer <buffer a.1>; cursor is at (1, 0)
+ <window object (unknown)>(2): displays buffer <buffer 1>; cursor is at (1, 0)
+ <tabpage 3>(4): 4 windows, current is <window 0>
+ Windows:
+ <window 0>(1): displays buffer <buffer c.2>; cursor is at (1, 0)
+ <window 1>(2): displays buffer <buffer b.2>; cursor is at (1, 0)
+ <window 2>(3): displays buffer <buffer a.2>; cursor is at (1, 0)
+ <window 3>(4): displays buffer <buffer 2>; cursor is at (1, 0)
+Number of windows in current tab page: 4
+Current tab page: <tabpage 3>
+Current window: <window 0>: <window 0> is <window 0>
+Current buffer: <buffer c.2>: <buffer c.2> is <buffer c.2> is <buffer c.2>
+ValueError at assigning foreign tab window
+Type error at assigning None to vim.current.window
+Type error at assigning None to vim.current.tabpage
+Type error at assigning None to vim.current.buffer
+Current tab page: <tabpage 2>
+Current window: <window 0>
+Current buffer: <buffer test86.in>
+Current line: 'Type error at assigning None to vim.current.buffer'
+w.valid: [True, False]
+t.valid: [True, False, True, False]
+vim.vars:Dictionary:True
+vim.options:Options:True
+vim.bindeval("{}"):Dictionary:True
+vim.bindeval("[]"):List:True
+vim.bindeval("function('tr')"):Function:True
+vim.current.buffer:Buffer:True
+vim.current.range:Range:True
+vim.current.window:Window:True
+vim.current.tabpage:TabPage:True
+current:__dir__,__members__,buffer,line,range,tabpage,window
+buffer:__dir__,__members__,append,mark,name,number,options,range,valid,vars
+window:__dir__,__members__,buffer,col,cursor,height,number,options,row,tabpage,valid,vars
+tabpage:__dir__,__members__,number,valid,vars,window,windows
+range:__dir__,__members__,append,end,start
+dictionary:__dir__,__members__,get,has_key,items,keys,locked,pop,popitem,scope,update,values
+list:__dir__,__members__,extend,locked
+function:__dir__,__members__,softspace
+output:__dir__,__members__,flush,softspace,write,writelines
+{}
+{'a': 1}
+{'a': 1}
+[]
+['a', 'b', 'c', '7']
+function('tr')
+'
+abcdef
+line :
+abcdef
+abcA
+line :
+abcB'
+['a', 'dup_a']
+['a', 'a']
+['a', 'b', 'c', 'C']
+[2, 2]
+[2, 2]
+1
+1
+function('Put')
+testdir
+test86.in
+src
+testdir/test86.in
+testdir
+test86.in
+> Output
+>> OutputSetattr
+del sys.stdout.softspace:AttributeError:("can't delete OutputObject attributes",)
+>>> Testing NumberToLong using sys.stdout.softspace = %s
+sys.stdout.softspace = []:TypeError:('expected int(), long() or something supporting coercing to long(), but got list',)
+sys.stdout.softspace = None:TypeError:('expected int(), long() or something supporting coercing to long(), but got NoneType',)
+sys.stdout.softspace = -1:ValueError:('number must be greater or equal to zero',)
+<<< Finished
+>>> Testing NumberToLong using sys.stderr.softspace = %s
+sys.stderr.softspace = []:TypeError:('expected int(), long() or something supporting coercing to long(), but got list',)
+sys.stderr.softspace = None:TypeError:('expected int(), long() or something supporting coercing to long(), but got NoneType',)
+sys.stderr.softspace = -1:ValueError:('number must be greater or equal to zero',)
+<<< Finished
+sys.stdout.attr = None:AttributeError:('invalid attribute: attr',)
+>> OutputWrite
+sys.stdout.write(None):TypeError:('coercing to Unicode: need string or buffer, NoneType found',)
+>> OutputWriteLines
+sys.stdout.writelines(None):TypeError:("'NoneType' object is not iterable",)
+sys.stdout.writelines([1]):TypeError:('coercing to Unicode: need string or buffer, int found',)
+>>> Testing *Iter* using sys.stdout.writelines(%s)
+sys.stdout.writelines(FailingIter()):NotImplementedError:('iter',)
+sys.stdout.writelines(FailingIterNext()):NotImplementedError:('next',)
+<<< Finished
+> VimCommand
+>>> Testing StringToChars using vim.command(%s)
+vim.command(1):TypeError:('expected str() or unicode() instance, but got int',)
+vim.command(u"\0"):TypeError:('expected string without null bytes',)
+vim.command("\0"):TypeError:('expected string without null bytes',)
+<<< Finished
+vim.command("", 2):TypeError:('command() takes exactly one argument (2 given)',)
+> VimToPython
+> VimEval
+>>> Testing StringToChars using vim.eval(%s)
+vim.eval(1):TypeError:('expected str() or unicode() instance, but got int',)
+vim.eval(u"\0"):TypeError:('expected string without null bytes',)
+vim.eval("\0"):TypeError:('expected string without null bytes',)
+<<< Finished
+vim.eval("", FailingTrue()):TypeError:('function takes exactly 1 argument (2 given)',)
+> VimEvalPy
+>>> Testing StringToChars using vim.bindeval(%s)
+vim.bindeval(1):TypeError:('expected str() or unicode() instance, but got int',)
+vim.bindeval(u"\0"):TypeError:('expected string without null bytes',)
+vim.bindeval("\0"):TypeError:('expected string without null bytes',)
+<<< Finished
+vim.eval("", 2):TypeError:('function takes exactly 1 argument (2 given)',)
+> VimStrwidth
+>>> Testing StringToChars using vim.strwidth(%s)
+vim.strwidth(1):TypeError:('expected str() or unicode() instance, but got int',)
+vim.strwidth(u"\0"):TypeError:('expected string without null bytes',)
+vim.strwidth("\0"):TypeError:('expected string without null bytes',)
+<<< Finished
+> VimForeachRTP
+vim.foreach_rtp(None):TypeError:("'NoneType' object is not callable",)
+vim.foreach_rtp(NoArgsCall()):TypeError:('__call__() takes exactly 1 argument (2 given)',)
+vim.foreach_rtp(FailingCall()):NotImplementedError:('call',)
+vim.foreach_rtp(int, 2):TypeError:('foreach_rtp() takes exactly one argument (2 given)',)
+> import
+import xxx_no_such_module_xxx:ImportError:('No module named xxx_no_such_module_xxx',)
+import failing_import:ImportError:('No module named failing_import',)
+import failing:NotImplementedError:()
+> Options
+>> OptionsItem
+vim.options["abcQ"]:KeyError:('abcQ',)
+vim.options[""]:ValueError:('empty keys are not allowed',)
+>>> Testing StringToChars using vim.options[%s]
+vim.options[1]:TypeError:('expected str() or unicode() instance, but got int',)
+vim.options[u"\0"]:TypeError:('expected string without null bytes',)
+vim.options["\0"]:TypeError:('expected string without null bytes',)
+<<< Finished
+>> OptionsContains
+>>> Testing StringToChars using %s in vim.options
+1 in vim.options:TypeError:('expected str() or unicode() instance, but got int',)
+u"\0" in vim.options:TypeError:('expected string without null bytes',)
+"\0" in vim.options:TypeError:('expected string without null bytes',)
+<<< Finished
+> Dictionary
+>> DictionaryConstructor
+vim.Dictionary("abcI"):ValueError:('expected sequence element of size 2, but got sequence of size 1',)
+>> DictionarySetattr
+del d.locked:AttributeError:('cannot delete vim.Dictionary attributes',)
+d.locked = FailingTrue():NotImplementedError:('bool',)
+vim.vvars.locked = False:TypeError:('cannot modify fixed dictionary',)
+d.scope = True:AttributeError:('cannot set attribute scope',)
+d.xxx = True:AttributeError:('cannot set attribute xxx',)
+>> _DictionaryItem
+d.get("a", 2, 3):TypeError:('function takes at most 2 arguments (3 given)',)
+>>> Testing StringToChars using d.get(%s)
+d.get(1):TypeError:('expected str() or unicode() instance, but got int',)
+d.get(u"\0"):TypeError:('expected string without null bytes',)
+d.get("\0"):TypeError:('expected string without null bytes',)
+<<< Finished
+d.pop("a"):KeyError:('a',)
+dl.pop("a"):error:('dictionary is locked',)
+>> DictionaryContains
+"" in d:ValueError:('empty keys are not allowed',)
+0 in d:TypeError:('expected str() or unicode() instance, but got int',)
+>> DictionaryIterNext
+for i in ned: ned["a"] = 1:RuntimeError:('hashtab changed during iteration',)
+>> DictionaryAssItem
+dl["b"] = 1:error:('dictionary is locked',)
+>>> Testing StringToChars using d[%s] = 1
+d[1] = 1:TypeError:('expected str() or unicode() instance, but got int',)
+d[u"\0"] = 1:TypeError:('expected string without null bytes',)
+d["\0"] = 1:TypeError:('expected string without null bytes',)
+<<< Finished
+>>> Testing StringToChars using d["a"] = {%s : 1}
+d["a"] = {1 : 1}:TypeError:('expected str() or unicode() instance, but got int',)
+d["a"] = {u"\0" : 1}:TypeError:('expected string without null bytes',)
+d["a"] = {"\0" : 1}:TypeError:('expected string without null bytes',)
+<<< Finished
+>>> Testing StringToChars using d["a"] = {"abcF" : {%s : 1}}
+d["a"] = {"abcF" : {1 : 1}}:TypeError:('expected str() or unicode() instance, but got int',)
+d["a"] = {"abcF" : {u"\0" : 1}}:TypeError:('expected string without null bytes',)
+d["a"] = {"abcF" : {"\0" : 1}}:TypeError:('expected string without null bytes',)
+<<< Finished
+>>> Testing StringToChars using d["a"] = {"abcF" : Mapping({%s : 1})}
+d["a"] = {"abcF" : Mapping({1 : 1})}:TypeError:('expected str() or unicode() instance, but got int',)
+d["a"] = {"abcF" : Mapping({u"\0" : 1})}:TypeError:('expected string without null bytes',)
+d["a"] = {"abcF" : Mapping({"\0" : 1})}:TypeError:('expected string without null bytes',)
+<<< Finished
+>>> Testing *Iter* using d["a"] = {"abcF" : %s}
+d["a"] = {"abcF" : FailingIter()}:TypeError:('unable to convert FailingIter to vim structure',)
+d["a"] = {"abcF" : FailingIterNext()}:NotImplementedError:('next',)
+<<< Finished
+>>> Testing ConvertFromPyObject using d["a"] = {"abcF" : %s}
+d["a"] = {"abcF" : None}:TypeError:('unable to convert NoneType to vim structure',)
+d["a"] = {"abcF" : {"": 1}}:ValueError:('empty keys are not allowed',)
+d["a"] = {"abcF" : {u"": 1}}:ValueError:('empty keys are not allowed',)
+d["a"] = {"abcF" : FailingMapping()}:NotImplementedError:('keys',)
+d["a"] = {"abcF" : FailingMappingKey()}:NotImplementedError:('getitem:mappingkey',)
+d["a"] = {"abcF" : FailingNumber()}:TypeError:('long() argument must be a string or a number',)
+<<< Finished
+>>> Testing StringToChars using d["a"] = Mapping({%s : 1})
+d["a"] = Mapping({1 : 1}):TypeError:('expected str() or unicode() instance, but got int',)
+d["a"] = Mapping({u"\0" : 1}):TypeError:('expected string without null bytes',)
+d["a"] = Mapping({"\0" : 1}):TypeError:('expected string without null bytes',)
+<<< Finished
+>>> Testing StringToChars using d["a"] = Mapping({"abcG" : {%s : 1}})
+d["a"] = Mapping({"abcG" : {1 : 1}}):TypeError:('expected str() or unicode() instance, but got int',)
+d["a"] = Mapping({"abcG" : {u"\0" : 1}}):TypeError:('expected string without null bytes',)
+d["a"] = Mapping({"abcG" : {"\0" : 1}}):TypeError:('expected string without null bytes',)
+<<< Finished
+>>> Testing StringToChars using d["a"] = Mapping({"abcG" : Mapping({%s : 1})})
+d["a"] = Mapping({"abcG" : Mapping({1 : 1})}):TypeError:('expected str() or unicode() instance, but got int',)
+d["a"] = Mapping({"abcG" : Mapping({u"\0" : 1})}):TypeError:('expected string without null bytes',)
+d["a"] = Mapping({"abcG" : Mapping({"\0" : 1})}):TypeError:('expected string without null bytes',)
+<<< Finished
+>>> Testing *Iter* using d["a"] = Mapping({"abcG" : %s})
+d["a"] = Mapping({"abcG" : FailingIter()}):TypeError:('unable to convert FailingIter to vim structure',)
+d["a"] = Mapping({"abcG" : FailingIterNext()}):NotImplementedError:('next',)
+<<< Finished
+>>> Testing ConvertFromPyObject using d["a"] = Mapping({"abcG" : %s})
+d["a"] = Mapping({"abcG" : None}):TypeError:('unable to convert NoneType to vim structure',)
+d["a"] = Mapping({"abcG" : {"": 1}}):ValueError:('empty keys are not allowed',)
+d["a"] = Mapping({"abcG" : {u"": 1}}):ValueError:('empty keys are not allowed',)
+d["a"] = Mapping({"abcG" : FailingMapping()}):NotImplementedError:('keys',)
+d["a"] = Mapping({"abcG" : FailingMappingKey()}):NotImplementedError:('getitem:mappingkey',)
+d["a"] = Mapping({"abcG" : FailingNumber()}):TypeError:('long() argument must be a string or a number',)
+<<< Finished
+>>> Testing *Iter* using d["a"] = %s
+d["a"] = FailingIter():TypeError:('unable to convert FailingIter to vim structure',)
+d["a"] = FailingIterNext():NotImplementedError:('next',)
+<<< Finished
+>>> Testing ConvertFromPyObject using d["a"] = %s
+d["a"] = None:TypeError:('unable to convert NoneType to vim structure',)
+d["a"] = {"": 1}:ValueError:('empty keys are not allowed',)
+d["a"] = {u"": 1}:ValueError:('empty keys are not allowed',)
+d["a"] = FailingMapping():NotImplementedError:('keys',)
+d["a"] = FailingMappingKey():NotImplementedError:('getitem:mappingkey',)
+d["a"] = FailingNumber():TypeError:('long() argument must be a string or a number',)
+<<< Finished
+>> DictionaryUpdate
+>>> kwargs
+>>> iter
+d.update(FailingMapping()):NotImplementedError:('keys',)
+d.update([FailingIterNext()]):NotImplementedError:('next',)
+d.update([FailingIterNextN(1)]):NotImplementedError:('next N',)
+>>> Testing *Iter* using d.update(%s)
+d.update(FailingIter()):NotImplementedError:('iter',)
+d.update(FailingIterNext()):NotImplementedError:('next',)
+<<< Finished
+>>> Testing StringToChars using d.update({%s : 1})
+d.update({1 : 1}):TypeError:('expected str() or unicode() instance, but got int',)
+d.update({u"\0" : 1}):TypeError:('expected string without null bytes',)
+d.update({"\0" : 1}):TypeError:('expected string without null bytes',)
+<<< Finished
+>>> Testing StringToChars using d.update({"abcF" : {%s : 1}})
+d.update({"abcF" : {1 : 1}}):TypeError:('expected str() or unicode() instance, but got int',)
+d.update({"abcF" : {u"\0" : 1}}):TypeError:('expected string without null bytes',)
+d.update({"abcF" : {"\0" : 1}}):TypeError:('expected string without null bytes',)
+<<< Finished
+>>> Testing StringToChars using d.update({"abcF" : Mapping({%s : 1})})
+d.update({"abcF" : Mapping({1 : 1})}):TypeError:('expected str() or unicode() instance, but got int',)
+d.update({"abcF" : Mapping({u"\0" : 1})}):TypeError:('expected string without null bytes',)
+d.update({"abcF" : Mapping({"\0" : 1})}):TypeError:('expected string without null bytes',)
+<<< Finished
+>>> Testing *Iter* using d.update({"abcF" : %s})
+d.update({"abcF" : FailingIter()}):TypeError:('unable to convert FailingIter to vim structure',)
+d.update({"abcF" : FailingIterNext()}):NotImplementedError:('next',)
+<<< Finished
+>>> Testing ConvertFromPyObject using d.update({"abcF" : %s})
+d.update({"abcF" : None}):TypeError:('unable to convert NoneType to vim structure',)
+d.update({"abcF" : {"": 1}}):ValueError:('empty keys are not allowed',)
+d.update({"abcF" : {u"": 1}}):ValueError:('empty keys are not allowed',)
+d.update({"abcF" : FailingMapping()}):NotImplementedError:('keys',)
+d.update({"abcF" : FailingMappingKey()}):NotImplementedError:('getitem:mappingkey',)
+d.update({"abcF" : FailingNumber()}):TypeError:('long() argument must be a string or a number',)
+<<< Finished
+>>> Testing StringToChars using d.update(Mapping({%s : 1}))
+d.update(Mapping({1 : 1})):TypeError:('expected str() or unicode() instance, but got int',)
+d.update(Mapping({u"\0" : 1})):TypeError:('expected string without null bytes',)
+d.update(Mapping({"\0" : 1})):TypeError:('expected string without null bytes',)
+<<< Finished
+>>> Testing StringToChars using d.update(Mapping({"abcG" : {%s : 1}}))
+d.update(Mapping({"abcG" : {1 : 1}})):TypeError:('expected str() or unicode() instance, but got int',)
+d.update(Mapping({"abcG" : {u"\0" : 1}})):TypeError:('expected string without null bytes',)
+d.update(Mapping({"abcG" : {"\0" : 1}})):TypeError:('expected string without null bytes',)
+<<< Finished
+>>> Testing StringToChars using d.update(Mapping({"abcG" : Mapping({%s : 1})}))
+d.update(Mapping({"abcG" : Mapping({1 : 1})})):TypeError:('expected str() or unicode() instance, but got int',)
+d.update(Mapping({"abcG" : Mapping({u"\0" : 1})})):TypeError:('expected string without null bytes',)
+d.update(Mapping({"abcG" : Mapping({"\0" : 1})})):TypeError:('expected string without null bytes',)
+<<< Finished
+>>> Testing *Iter* using d.update(Mapping({"abcG" : %s}))
+d.update(Mapping({"abcG" : FailingIter()})):TypeError:('unable to convert FailingIter to vim structure',)
+d.update(Mapping({"abcG" : FailingIterNext()})):NotImplementedError:('next',)
+<<< Finished
+>>> Testing ConvertFromPyObject using d.update(Mapping({"abcG" : %s}))
+d.update(Mapping({"abcG" : None})):TypeError:('unable to convert NoneType to vim structure',)
+d.update(Mapping({"abcG" : {"": 1}})):ValueError:('empty keys are not allowed',)
+d.update(Mapping({"abcG" : {u"": 1}})):ValueError:('empty keys are not allowed',)
+d.update(Mapping({"abcG" : FailingMapping()})):NotImplementedError:('keys',)
+d.update(Mapping({"abcG" : FailingMappingKey()})):NotImplementedError:('getitem:mappingkey',)
+d.update(Mapping({"abcG" : FailingNumber()})):TypeError:('long() argument must be a string or a number',)
+<<< Finished
+>>> Testing *Iter* using d.update(%s)
+d.update(FailingIter()):NotImplementedError:('iter',)
+d.update(FailingIterNext()):NotImplementedError:('next',)
+<<< Finished
+>>> Testing ConvertFromPyObject using d.update(%s)
+d.update(None):TypeError:("'NoneType' object is not iterable",)
+d.update({"": 1}):ValueError:('empty keys are not allowed',)
+d.update({u"": 1}):ValueError:('empty keys are not allowed',)
+d.update(FailingMapping()):NotImplementedError:('keys',)
+d.update(FailingMappingKey()):NotImplementedError:('getitem:mappingkey',)
+d.update(FailingNumber()):TypeError:("'FailingNumber' object is not iterable",)
+<<< Finished
+>>> Testing StringToChars using d.update(((%s, 0),))
+d.update(((1, 0),)):TypeError:('expected str() or unicode() instance, but got int',)
+d.update(((u"\0", 0),)):TypeError:('expected string without null bytes',)
+d.update((("\0", 0),)):TypeError:('expected string without null bytes',)
+<<< Finished
+>>> Testing StringToChars using d.update((("a", {%s : 1}),))
+d.update((("a", {1 : 1}),)):TypeError:('expected str() or unicode() instance, but got int',)
+d.update((("a", {u"\0" : 1}),)):TypeError:('expected string without null bytes',)
+d.update((("a", {"\0" : 1}),)):TypeError:('expected string without null bytes',)
+<<< Finished
+>>> Testing StringToChars using d.update((("a", {"abcF" : {%s : 1}}),))
+d.update((("a", {"abcF" : {1 : 1}}),)):TypeError:('expected str() or unicode() instance, but got int',)
+d.update((("a", {"abcF" : {u"\0" : 1}}),)):TypeError:('expected string without null bytes',)
+d.update((("a", {"abcF" : {"\0" : 1}}),)):TypeError:('expected string without null bytes',)
+<<< Finished
+>>> Testing StringToChars using d.update((("a", {"abcF" : Mapping({%s : 1})}),))
+d.update((("a", {"abcF" : Mapping({1 : 1})}),)):TypeError:('expected str() or unicode() instance, but got int',)
+d.update((("a", {"abcF" : Mapping({u"\0" : 1})}),)):TypeError:('expected string without null bytes',)
+d.update((("a", {"abcF" : Mapping({"\0" : 1})}),)):TypeError:('expected string without null bytes',)
+<<< Finished
+>>> Testing *Iter* using d.update((("a", {"abcF" : %s}),))
+d.update((("a", {"abcF" : FailingIter()}),)):TypeError:('unable to convert FailingIter to vim structure',)
+d.update((("a", {"abcF" : FailingIterNext()}),)):NotImplementedError:('next',)
+<<< Finished
+>>> Testing ConvertFromPyObject using d.update((("a", {"abcF" : %s}),))
+d.update((("a", {"abcF" : None}),)):TypeError:('unable to convert NoneType to vim structure',)
+d.update((("a", {"abcF" : {"": 1}}),)):ValueError:('empty keys are not allowed',)
+d.update((("a", {"abcF" : {u"": 1}}),)):ValueError:('empty keys are not allowed',)
+d.update((("a", {"abcF" : FailingMapping()}),)):NotImplementedError:('keys',)
+d.update((("a", {"abcF" : FailingMappingKey()}),)):NotImplementedError:('getitem:mappingkey',)
+d.update((("a", {"abcF" : FailingNumber()}),)):TypeError:('long() argument must be a string or a number',)
+<<< Finished
+>>> Testing StringToChars using d.update((("a", Mapping({%s : 1})),))
+d.update((("a", Mapping({1 : 1})),)):TypeError:('expected str() or unicode() instance, but got int',)
+d.update((("a", Mapping({u"\0" : 1})),)):TypeError:('expected string without null bytes',)
+d.update((("a", Mapping({"\0" : 1})),)):TypeError:('expected string without null bytes',)
+<<< Finished
+>>> Testing StringToChars using d.update((("a", Mapping({"abcG" : {%s : 1}})),))
+d.update((("a", Mapping({"abcG" : {1 : 1}})),)):TypeError:('expected str() or unicode() instance, but got int',)
+d.update((("a", Mapping({"abcG" : {u"\0" : 1}})),)):TypeError:('expected string without null bytes',)
+d.update((("a", Mapping({"abcG" : {"\0" : 1}})),)):TypeError:('expected string without null bytes',)
+<<< Finished
+>>> Testing StringToChars using d.update((("a", Mapping({"abcG" : Mapping({%s : 1})})),))
+d.update((("a", Mapping({"abcG" : Mapping({1 : 1})})),)):TypeError:('expected str() or unicode() instance, but got int',)
+d.update((("a", Mapping({"abcG" : Mapping({u"\0" : 1})})),)):TypeError:('expected string without null bytes',)
+d.update((("a", Mapping({"abcG" : Mapping({"\0" : 1})})),)):TypeError:('expected string without null bytes',)
+<<< Finished
+>>> Testing *Iter* using d.update((("a", Mapping({"abcG" : %s})),))
+d.update((("a", Mapping({"abcG" : FailingIter()})),)):TypeError:('unable to convert FailingIter to vim structure',)
+d.update((("a", Mapping({"abcG" : FailingIterNext()})),)):NotImplementedError:('next',)
+<<< Finished
+>>> Testing ConvertFromPyObject using d.update((("a", Mapping({"abcG" : %s})),))
+d.update((("a", Mapping({"abcG" : None})),)):TypeError:('unable to convert NoneType to vim structure',)
+d.update((("a", Mapping({"abcG" : {"": 1}})),)):ValueError:('empty keys are not allowed',)
+d.update((("a", Mapping({"abcG" : {u"": 1}})),)):ValueError:('empty keys are not allowed',)
+d.update((("a", Mapping({"abcG" : FailingMapping()})),)):NotImplementedError:('keys',)
+d.update((("a", Mapping({"abcG" : FailingMappingKey()})),)):NotImplementedError:('getitem:mappingkey',)
+d.update((("a", Mapping({"abcG" : FailingNumber()})),)):TypeError:('long() argument must be a string or a number',)
+<<< Finished
+>>> Testing *Iter* using d.update((("a", %s),))
+d.update((("a", FailingIter()),)):TypeError:('unable to convert FailingIter to vim structure',)
+d.update((("a", FailingIterNext()),)):NotImplementedError:('next',)
+<<< Finished
+>>> Testing ConvertFromPyObject using d.update((("a", %s),))
+d.update((("a", None),)):TypeError:('unable to convert NoneType to vim structure',)
+d.update((("a", {"": 1}),)):ValueError:('empty keys are not allowed',)
+d.update((("a", {u"": 1}),)):ValueError:('empty keys are not allowed',)
+d.update((("a", FailingMapping()),)):NotImplementedError:('keys',)
+d.update((("a", FailingMappingKey()),)):NotImplementedError:('getitem:mappingkey',)
+d.update((("a", FailingNumber()),)):TypeError:('long() argument must be a string or a number',)
+<<< Finished
+>> DictionaryPopItem
+d.popitem(1, 2):TypeError:('popitem() takes no arguments (2 given)',)
+>> DictionaryHasKey
+d.has_key():TypeError:('has_key() takes exactly one argument (0 given)',)
+> List
+>> ListConstructor
+vim.List(1, 2):TypeError:('function takes at most 1 argument (2 given)',)
+vim.List(a=1):TypeError:('list constructor does not accept keyword arguments',)
+>>> Testing *Iter* using vim.List(%s)
+vim.List(FailingIter()):NotImplementedError:('iter',)
+vim.List(FailingIterNext()):NotImplementedError:('next',)
+<<< Finished
+>>> Testing StringToChars using vim.List([{%s : 1}])
+vim.List([{1 : 1}]):TypeError:('expected str() or unicode() instance, but got int',)
+vim.List([{u"\0" : 1}]):TypeError:('expected string without null bytes',)
+vim.List([{"\0" : 1}]):TypeError:('expected string without null bytes',)
+<<< Finished
+>>> Testing StringToChars using vim.List([{"abcF" : {%s : 1}}])
+vim.List([{"abcF" : {1 : 1}}]):TypeError:('expected str() or unicode() instance, but got int',)
+vim.List([{"abcF" : {u"\0" : 1}}]):TypeError:('expected string without null bytes',)
+vim.List([{"abcF" : {"\0" : 1}}]):TypeError:('expected string without null bytes',)
+<<< Finished
+>>> Testing StringToChars using vim.List([{"abcF" : Mapping({%s : 1})}])
+vim.List([{"abcF" : Mapping({1 : 1})}]):TypeError:('expected str() or unicode() instance, but got int',)
+vim.List([{"abcF" : Mapping({u"\0" : 1})}]):TypeError:('expected string without null bytes',)
+vim.List([{"abcF" : Mapping({"\0" : 1})}]):TypeError:('expected string without null bytes',)
+<<< Finished
+>>> Testing *Iter* using vim.List([{"abcF" : %s}])
+vim.List([{"abcF" : FailingIter()}]):TypeError:('unable to convert FailingIter to vim structure',)
+vim.List([{"abcF" : FailingIterNext()}]):NotImplementedError:('next',)
+<<< Finished
+>>> Testing ConvertFromPyObject using vim.List([{"abcF" : %s}])
+vim.List([{"abcF" : None}]):TypeError:('unable to convert NoneType to vim structure',)
+vim.List([{"abcF" : {"": 1}}]):ValueError:('empty keys are not allowed',)
+vim.List([{"abcF" : {u"": 1}}]):ValueError:('empty keys are not allowed',)
+vim.List([{"abcF" : FailingMapping()}]):NotImplementedError:('keys',)
+vim.List([{"abcF" : FailingMappingKey()}]):NotImplementedError:('getitem:mappingkey',)
+vim.List([{"abcF" : FailingNumber()}]):TypeError:('long() argument must be a string or a number',)
+<<< Finished
+>>> Testing StringToChars using vim.List([Mapping({%s : 1})])
+vim.List([Mapping({1 : 1})]):TypeError:('expected str() or unicode() instance, but got int',)
+vim.List([Mapping({u"\0" : 1})]):TypeError:('expected string without null bytes',)
+vim.List([Mapping({"\0" : 1})]):TypeError:('expected string without null bytes',)
+<<< Finished
+>>> Testing StringToChars using vim.List([Mapping({"abcG" : {%s : 1}})])
+vim.List([Mapping({"abcG" : {1 : 1}})]):TypeError:('expected str() or unicode() instance, but got int',)
+vim.List([Mapping({"abcG" : {u"\0" : 1}})]):TypeError:('expected string without null bytes',)
+vim.List([Mapping({"abcG" : {"\0" : 1}})]):TypeError:('expected string without null bytes',)
+<<< Finished
+>>> Testing StringToChars using vim.List([Mapping({"abcG" : Mapping({%s : 1})})])
+vim.List([Mapping({"abcG" : Mapping({1 : 1})})]):TypeError:('expected str() or unicode() instance, but got int',)
+vim.List([Mapping({"abcG" : Mapping({u"\0" : 1})})]):TypeError:('expected string without null bytes',)
+vim.List([Mapping({"abcG" : Mapping({"\0" : 1})})]):TypeError:('expected string without null bytes',)
+<<< Finished
+>>> Testing *Iter* using vim.List([Mapping({"abcG" : %s})])
+vim.List([Mapping({"abcG" : FailingIter()})]):TypeError:('unable to convert FailingIter to vim structure',)
+vim.List([Mapping({"abcG" : FailingIterNext()})]):NotImplementedError:('next',)
+<<< Finished
+>>> Testing ConvertFromPyObject using vim.List([Mapping({"abcG" : %s})])
+vim.List([Mapping({"abcG" : None})]):TypeError:('unable to convert NoneType to vim structure',)
+vim.List([Mapping({"abcG" : {"": 1}})]):ValueError:('empty keys are not allowed',)
+vim.List([Mapping({"abcG" : {u"": 1}})]):ValueError:('empty keys are not allowed',)
+vim.List([Mapping({"abcG" : FailingMapping()})]):NotImplementedError:('keys',)
+vim.List([Mapping({"abcG" : FailingMappingKey()})]):NotImplementedError:('getitem:mappingkey',)
+vim.List([Mapping({"abcG" : FailingNumber()})]):TypeError:('long() argument must be a string or a number',)
+<<< Finished
+>>> Testing *Iter* using vim.List([%s])
+vim.List([FailingIter()]):TypeError:('unable to convert FailingIter to vim structure',)
+vim.List([FailingIterNext()]):NotImplementedError:('next',)
+<<< Finished
+>>> Testing ConvertFromPyObject using vim.List([%s])
+vim.List([None]):TypeError:('unable to convert NoneType to vim structure',)
+vim.List([{"": 1}]):ValueError:('empty keys are not allowed',)
+vim.List([{u"": 1}]):ValueError:('empty keys are not allowed',)
+vim.List([FailingMapping()]):NotImplementedError:('keys',)
+vim.List([FailingMappingKey()]):NotImplementedError:('getitem:mappingkey',)
+vim.List([FailingNumber()]):TypeError:('long() argument must be a string or a number',)
+<<< Finished
+>> ListItem
+l[1000]:IndexError:('list index out of range',)
+>> ListAssItem
+ll[1] = 2:error:('list is locked',)
+l[1000] = 3:IndexError:('list index out of range',)
+>> ListAssSlice
+ll[1:100] = "abcJ":error:('list is locked',)
+>>> Testing *Iter* using l[:] = %s
+l[:] = FailingIter():NotImplementedError:('iter',)
+l[:] = FailingIterNext():NotImplementedError:('next',)
+<<< Finished
+nel[1:10:2] = "abcK":ValueError:('attempt to assign sequence of size greater then 2 to extended slice',)
+('a', 'b', 'c', 'O')
+nel[1:10:2] = "a":ValueError:('attempt to assign sequence of size 1 to extended slice of size 2',)
+('a', 'b', 'c', 'O')
+nel[1:1:-1] = "a":ValueError:('attempt to assign sequence of size greater then 0 to extended slice',)
+('a', 'b', 'c', 'O')
+nel[:] = FailingIterNextN(2):NotImplementedError:('next N',)
+('a', 'b', 'c', 'O')
+>>> Testing StringToChars using l[:] = [{%s : 1}]
+l[:] = [{1 : 1}]:TypeError:('expected str() or unicode() instance, but got int',)
+l[:] = [{u"\0" : 1}]:TypeError:('expected string without null bytes',)
+l[:] = [{"\0" : 1}]:TypeError:('expected string without null bytes',)
+<<< Finished
+>>> Testing StringToChars using l[:] = [{"abcF" : {%s : 1}}]
+l[:] = [{"abcF" : {1 : 1}}]:TypeError:('expected str() or unicode() instance, but got int',)
+l[:] = [{"abcF" : {u"\0" : 1}}]:TypeError:('expected string without null bytes',)
+l[:] = [{"abcF" : {"\0" : 1}}]:TypeError:('expected string without null bytes',)
+<<< Finished
+>>> Testing StringToChars using l[:] = [{"abcF" : Mapping({%s : 1})}]
+l[:] = [{"abcF" : Mapping({1 : 1})}]:TypeError:('expected str() or unicode() instance, but got int',)
+l[:] = [{"abcF" : Mapping({u"\0" : 1})}]:TypeError:('expected string without null bytes',)
+l[:] = [{"abcF" : Mapping({"\0" : 1})}]:TypeError:('expected string without null bytes',)
+<<< Finished
+>>> Testing *Iter* using l[:] = [{"abcF" : %s}]
+l[:] = [{"abcF" : FailingIter()}]:TypeError:('unable to convert FailingIter to vim structure',)
+l[:] = [{"abcF" : FailingIterNext()}]:NotImplementedError:('next',)
+<<< Finished
+>>> Testing ConvertFromPyObject using l[:] = [{"abcF" : %s}]
+l[:] = [{"abcF" : None}]:TypeError:('unable to convert NoneType to vim structure',)
+l[:] = [{"abcF" : {"": 1}}]:ValueError:('empty keys are not allowed',)
+l[:] = [{"abcF" : {u"": 1}}]:ValueError:('empty keys are not allowed',)
+l[:] = [{"abcF" : FailingMapping()}]:NotImplementedError:('keys',)
+l[:] = [{"abcF" : FailingMappingKey()}]:NotImplementedError:('getitem:mappingkey',)
+l[:] = [{"abcF" : FailingNumber()}]:TypeError:('long() argument must be a string or a number',)
+<<< Finished
+>>> Testing StringToChars using l[:] = [Mapping({%s : 1})]
+l[:] = [Mapping({1 : 1})]:TypeError:('expected str() or unicode() instance, but got int',)
+l[:] = [Mapping({u"\0" : 1})]:TypeError:('expected string without null bytes',)
+l[:] = [Mapping({"\0" : 1})]:TypeError:('expected string without null bytes',)
+<<< Finished
+>>> Testing StringToChars using l[:] = [Mapping({"abcG" : {%s : 1}})]
+l[:] = [Mapping({"abcG" : {1 : 1}})]:TypeError:('expected str() or unicode() instance, but got int',)
+l[:] = [Mapping({"abcG" : {u"\0" : 1}})]:TypeError:('expected string without null bytes',)
+l[:] = [Mapping({"abcG" : {"\0" : 1}})]:TypeError:('expected string without null bytes',)
+<<< Finished
+>>> Testing StringToChars using l[:] = [Mapping({"abcG" : Mapping({%s : 1})})]
+l[:] = [Mapping({"abcG" : Mapping({1 : 1})})]:TypeError:('expected str() or unicode() instance, but got int',)
+l[:] = [Mapping({"abcG" : Mapping({u"\0" : 1})})]:TypeError:('expected string without null bytes',)
+l[:] = [Mapping({"abcG" : Mapping({"\0" : 1})})]:TypeError:('expected string without null bytes',)
+<<< Finished
+>>> Testing *Iter* using l[:] = [Mapping({"abcG" : %s})]
+l[:] = [Mapping({"abcG" : FailingIter()})]:TypeError:('unable to convert FailingIter to vim structure',)
+l[:] = [Mapping({"abcG" : FailingIterNext()})]:NotImplementedError:('next',)
+<<< Finished
+>>> Testing ConvertFromPyObject using l[:] = [Mapping({"abcG" : %s})]
+l[:] = [Mapping({"abcG" : None})]:TypeError:('unable to convert NoneType to vim structure',)
+l[:] = [Mapping({"abcG" : {"": 1}})]:ValueError:('empty keys are not allowed',)
+l[:] = [Mapping({"abcG" : {u"": 1}})]:ValueError:('empty keys are not allowed',)
+l[:] = [Mapping({"abcG" : FailingMapping()})]:NotImplementedError:('keys',)
+l[:] = [Mapping({"abcG" : FailingMappingKey()})]:NotImplementedError:('getitem:mappingkey',)
+l[:] = [Mapping({"abcG" : FailingNumber()})]:TypeError:('long() argument must be a string or a number',)
+<<< Finished
+>>> Testing *Iter* using l[:] = [%s]
+l[:] = [FailingIter()]:TypeError:('unable to convert FailingIter to vim structure',)
+l[:] = [FailingIterNext()]:NotImplementedError:('next',)
+<<< Finished
+>>> Testing ConvertFromPyObject using l[:] = [%s]
+l[:] = [None]:TypeError:('unable to convert NoneType to vim structure',)
+l[:] = [{"": 1}]:ValueError:('empty keys are not allowed',)
+l[:] = [{u"": 1}]:ValueError:('empty keys are not allowed',)
+l[:] = [FailingMapping()]:NotImplementedError:('keys',)
+l[:] = [FailingMappingKey()]:NotImplementedError:('getitem:mappingkey',)
+l[:] = [FailingNumber()]:TypeError:('long() argument must be a string or a number',)
+<<< Finished
+>> ListConcatInPlace
+>>> Testing *Iter* using l.extend(%s)
+l.extend(FailingIter()):NotImplementedError:('iter',)
+l.extend(FailingIterNext()):NotImplementedError:('next',)
+<<< Finished
+>>> Testing StringToChars using l.extend([{%s : 1}])
+l.extend([{1 : 1}]):TypeError:('expected str() or unicode() instance, but got int',)
+l.extend([{u"\0" : 1}]):TypeError:('expected string without null bytes',)
+l.extend([{"\0" : 1}]):TypeError:('expected string without null bytes',)
+<<< Finished
+>>> Testing StringToChars using l.extend([{"abcF" : {%s : 1}}])
+l.extend([{"abcF" : {1 : 1}}]):TypeError:('expected str() or unicode() instance, but got int',)
+l.extend([{"abcF" : {u"\0" : 1}}]):TypeError:('expected string without null bytes',)
+l.extend([{"abcF" : {"\0" : 1}}]):TypeError:('expected string without null bytes',)
+<<< Finished
+>>> Testing StringToChars using l.extend([{"abcF" : Mapping({%s : 1})}])
+l.extend([{"abcF" : Mapping({1 : 1})}]):TypeError:('expected str() or unicode() instance, but got int',)
+l.extend([{"abcF" : Mapping({u"\0" : 1})}]):TypeError:('expected string without null bytes',)
+l.extend([{"abcF" : Mapping({"\0" : 1})}]):TypeError:('expected string without null bytes',)
+<<< Finished
+>>> Testing *Iter* using l.extend([{"abcF" : %s}])
+l.extend([{"abcF" : FailingIter()}]):TypeError:('unable to convert FailingIter to vim structure',)
+l.extend([{"abcF" : FailingIterNext()}]):NotImplementedError:('next',)
+<<< Finished
+>>> Testing ConvertFromPyObject using l.extend([{"abcF" : %s}])
+l.extend([{"abcF" : None}]):TypeError:('unable to convert NoneType to vim structure',)
+l.extend([{"abcF" : {"": 1}}]):ValueError:('empty keys are not allowed',)
+l.extend([{"abcF" : {u"": 1}}]):ValueError:('empty keys are not allowed',)
+l.extend([{"abcF" : FailingMapping()}]):NotImplementedError:('keys',)
+l.extend([{"abcF" : FailingMappingKey()}]):NotImplementedError:('getitem:mappingkey',)
+l.extend([{"abcF" : FailingNumber()}]):TypeError:('long() argument must be a string or a number',)
+<<< Finished
+>>> Testing StringToChars using l.extend([Mapping({%s : 1})])
+l.extend([Mapping({1 : 1})]):TypeError:('expected str() or unicode() instance, but got int',)
+l.extend([Mapping({u"\0" : 1})]):TypeError:('expected string without null bytes',)
+l.extend([Mapping({"\0" : 1})]):TypeError:('expected string without null bytes',)
+<<< Finished
+>>> Testing StringToChars using l.extend([Mapping({"abcG" : {%s : 1}})])
+l.extend([Mapping({"abcG" : {1 : 1}})]):TypeError:('expected str() or unicode() instance, but got int',)
+l.extend([Mapping({"abcG" : {u"\0" : 1}})]):TypeError:('expected string without null bytes',)
+l.extend([Mapping({"abcG" : {"\0" : 1}})]):TypeError:('expected string without null bytes',)
+<<< Finished
+>>> Testing StringToChars using l.extend([Mapping({"abcG" : Mapping({%s : 1})})])
+l.extend([Mapping({"abcG" : Mapping({1 : 1})})]):TypeError:('expected str() or unicode() instance, but got int',)
+l.extend([Mapping({"abcG" : Mapping({u"\0" : 1})})]):TypeError:('expected string without null bytes',)
+l.extend([Mapping({"abcG" : Mapping({"\0" : 1})})]):TypeError:('expected string without null bytes',)
+<<< Finished
+>>> Testing *Iter* using l.extend([Mapping({"abcG" : %s})])
+l.extend([Mapping({"abcG" : FailingIter()})]):TypeError:('unable to convert FailingIter to vim structure',)
+l.extend([Mapping({"abcG" : FailingIterNext()})]):NotImplementedError:('next',)
+<<< Finished
+>>> Testing ConvertFromPyObject using l.extend([Mapping({"abcG" : %s})])
+l.extend([Mapping({"abcG" : None})]):TypeError:('unable to convert NoneType to vim structure',)
+l.extend([Mapping({"abcG" : {"": 1}})]):ValueError:('empty keys are not allowed',)
+l.extend([Mapping({"abcG" : {u"": 1}})]):ValueError:('empty keys are not allowed',)
+l.extend([Mapping({"abcG" : FailingMapping()})]):NotImplementedError:('keys',)
+l.extend([Mapping({"abcG" : FailingMappingKey()})]):NotImplementedError:('getitem:mappingkey',)
+l.extend([Mapping({"abcG" : FailingNumber()})]):TypeError:('long() argument must be a string or a number',)
+<<< Finished
+>>> Testing *Iter* using l.extend([%s])
+l.extend([FailingIter()]):TypeError:('unable to convert FailingIter to vim structure',)
+l.extend([FailingIterNext()]):NotImplementedError:('next',)
+<<< Finished
+>>> Testing ConvertFromPyObject using l.extend([%s])
+l.extend([None]):TypeError:('unable to convert NoneType to vim structure',)
+l.extend([{"": 1}]):ValueError:('empty keys are not allowed',)
+l.extend([{u"": 1}]):ValueError:('empty keys are not allowed',)
+l.extend([FailingMapping()]):NotImplementedError:('keys',)
+l.extend([FailingMappingKey()]):NotImplementedError:('getitem:mappingkey',)
+l.extend([FailingNumber()]):TypeError:('long() argument must be a string or a number',)
+<<< Finished
+>> ListSetattr
+del l.locked:AttributeError:('cannot delete vim.List attributes',)
+l.locked = FailingTrue():NotImplementedError:('bool',)
+l.xxx = True:AttributeError:('cannot set attribute xxx',)
+> Function
+>> FunctionConstructor
+vim.Function("123"):ValueError:('unnamed function 123 does not exist',)
+vim.Function("xxx_non_existent_function_xxx"):ValueError:('function xxx_non_existent_function_xxx does not exist',)
+vim.Function("xxx#non#existent#function#xxx"):NOT FAILED
+>> FunctionCall
+>>> Testing StringToChars using f({%s : 1})
+f({1 : 1}):TypeError:('expected str() or unicode() instance, but got int',)
+f({u"\0" : 1}):TypeError:('expected string without null bytes',)
+f({"\0" : 1}):TypeError:('expected string without null bytes',)
+<<< Finished
+>>> Testing StringToChars using f({"abcF" : {%s : 1}})
+f({"abcF" : {1 : 1}}):TypeError:('expected str() or unicode() instance, but got int',)
+f({"abcF" : {u"\0" : 1}}):TypeError:('expected string without null bytes',)
+f({"abcF" : {"\0" : 1}}):TypeError:('expected string without null bytes',)
+<<< Finished
+>>> Testing StringToChars using f({"abcF" : Mapping({%s : 1})})
+f({"abcF" : Mapping({1 : 1})}):TypeError:('expected str() or unicode() instance, but got int',)
+f({"abcF" : Mapping({u"\0" : 1})}):TypeError:('expected string without null bytes',)
+f({"abcF" : Mapping({"\0" : 1})}):TypeError:('expected string without null bytes',)
+<<< Finished
+>>> Testing *Iter* using f({"abcF" : %s})
+f({"abcF" : FailingIter()}):TypeError:('unable to convert FailingIter to vim structure',)
+f({"abcF" : FailingIterNext()}):NotImplementedError:('next',)
+<<< Finished
+>>> Testing ConvertFromPyObject using f({"abcF" : %s})
+f({"abcF" : None}):TypeError:('unable to convert NoneType to vim structure',)
+f({"abcF" : {"": 1}}):ValueError:('empty keys are not allowed',)
+f({"abcF" : {u"": 1}}):ValueError:('empty keys are not allowed',)
+f({"abcF" : FailingMapping()}):NotImplementedError:('keys',)
+f({"abcF" : FailingMappingKey()}):NotImplementedError:('getitem:mappingkey',)
+f({"abcF" : FailingNumber()}):TypeError:('long() argument must be a string or a number',)
+<<< Finished
+>>> Testing StringToChars using f(Mapping({%s : 1}))
+f(Mapping({1 : 1})):TypeError:('expected str() or unicode() instance, but got int',)
+f(Mapping({u"\0" : 1})):TypeError:('expected string without null bytes',)
+f(Mapping({"\0" : 1})):TypeError:('expected string without null bytes',)
+<<< Finished
+>>> Testing StringToChars using f(Mapping({"abcG" : {%s : 1}}))
+f(Mapping({"abcG" : {1 : 1}})):TypeError:('expected str() or unicode() instance, but got int',)
+f(Mapping({"abcG" : {u"\0" : 1}})):TypeError:('expected string without null bytes',)
+f(Mapping({"abcG" : {"\0" : 1}})):TypeError:('expected string without null bytes',)
+<<< Finished
+>>> Testing StringToChars using f(Mapping({"abcG" : Mapping({%s : 1})}))
+f(Mapping({"abcG" : Mapping({1 : 1})})):TypeError:('expected str() or unicode() instance, but got int',)
+f(Mapping({"abcG" : Mapping({u"\0" : 1})})):TypeError:('expected string without null bytes',)
+f(Mapping({"abcG" : Mapping({"\0" : 1})})):TypeError:('expected string without null bytes',)
+<<< Finished
+>>> Testing *Iter* using f(Mapping({"abcG" : %s}))
+f(Mapping({"abcG" : FailingIter()})):TypeError:('unable to convert FailingIter to vim structure',)
+f(Mapping({"abcG" : FailingIterNext()})):NotImplementedError:('next',)
+<<< Finished
+>>> Testing ConvertFromPyObject using f(Mapping({"abcG" : %s}))
+f(Mapping({"abcG" : None})):TypeError:('unable to convert NoneType to vim structure',)
+f(Mapping({"abcG" : {"": 1}})):ValueError:('empty keys are not allowed',)
+f(Mapping({"abcG" : {u"": 1}})):ValueError:('empty keys are not allowed',)
+f(Mapping({"abcG" : FailingMapping()})):NotImplementedError:('keys',)
+f(Mapping({"abcG" : FailingMappingKey()})):NotImplementedError:('getitem:mappingkey',)
+f(Mapping({"abcG" : FailingNumber()})):TypeError:('long() argument must be a string or a number',)
+<<< Finished
+>>> Testing *Iter* using f(%s)
+f(FailingIter()):TypeError:('unable to convert FailingIter to vim structure',)
+f(FailingIterNext()):NotImplementedError:('next',)
+<<< Finished
+>>> Testing ConvertFromPyObject using f(%s)
+f(None):TypeError:('unable to convert NoneType to vim structure',)
+f({"": 1}):ValueError:('empty keys are not allowed',)
+f({u"": 1}):ValueError:('empty keys are not allowed',)
+f(FailingMapping()):NotImplementedError:('keys',)
+f(FailingMappingKey()):NotImplementedError:('getitem:mappingkey',)
+f(FailingNumber()):TypeError:('long() argument must be a string or a number',)
+<<< Finished
+>>> Testing StringToChars using fd(self={%s : 1})
+fd(self={1 : 1}):TypeError:('expected str() or unicode() instance, but got int',)
+fd(self={u"\0" : 1}):TypeError:('expected string without null bytes',)
+fd(self={"\0" : 1}):TypeError:('expected string without null bytes',)
+<<< Finished
+>>> Testing StringToChars using fd(self={"abcF" : {%s : 1}})
+fd(self={"abcF" : {1 : 1}}):TypeError:('expected str() or unicode() instance, but got int',)
+fd(self={"abcF" : {u"\0" : 1}}):TypeError:('expected string without null bytes',)
+fd(self={"abcF" : {"\0" : 1}}):TypeError:('expected string without null bytes',)
+<<< Finished
+>>> Testing StringToChars using fd(self={"abcF" : Mapping({%s : 1})})
+fd(self={"abcF" : Mapping({1 : 1})}):TypeError:('expected str() or unicode() instance, but got int',)
+fd(self={"abcF" : Mapping({u"\0" : 1})}):TypeError:('expected string without null bytes',)
+fd(self={"abcF" : Mapping({"\0" : 1})}):TypeError:('expected string without null bytes',)
+<<< Finished
+>>> Testing *Iter* using fd(self={"abcF" : %s})
+fd(self={"abcF" : FailingIter()}):TypeError:('unable to convert FailingIter to vim structure',)
+fd(self={"abcF" : FailingIterNext()}):NotImplementedError:('next',)
+<<< Finished
+>>> Testing ConvertFromPyObject using fd(self={"abcF" : %s})
+fd(self={"abcF" : None}):TypeError:('unable to convert NoneType to vim structure',)
+fd(self={"abcF" : {"": 1}}):ValueError:('empty keys are not allowed',)
+fd(self={"abcF" : {u"": 1}}):ValueError:('empty keys are not allowed',)
+fd(self={"abcF" : FailingMapping()}):NotImplementedError:('keys',)
+fd(self={"abcF" : FailingMappingKey()}):NotImplementedError:('getitem:mappingkey',)
+fd(self={"abcF" : FailingNumber()}):TypeError:('long() argument must be a string or a number',)
+<<< Finished
+>>> Testing StringToChars using fd(self=Mapping({%s : 1}))
+fd(self=Mapping({1 : 1})):TypeError:('expected str() or unicode() instance, but got int',)
+fd(self=Mapping({u"\0" : 1})):TypeError:('expected string without null bytes',)
+fd(self=Mapping({"\0" : 1})):TypeError:('expected string without null bytes',)
+<<< Finished
+>>> Testing StringToChars using fd(self=Mapping({"abcG" : {%s : 1}}))
+fd(self=Mapping({"abcG" : {1 : 1}})):TypeError:('expected str() or unicode() instance, but got int',)
+fd(self=Mapping({"abcG" : {u"\0" : 1}})):TypeError:('expected string without null bytes',)
+fd(self=Mapping({"abcG" : {"\0" : 1}})):TypeError:('expected string without null bytes',)
+<<< Finished
+>>> Testing StringToChars using fd(self=Mapping({"abcG" : Mapping({%s : 1})}))
+fd(self=Mapping({"abcG" : Mapping({1 : 1})})):TypeError:('expected str() or unicode() instance, but got int',)
+fd(self=Mapping({"abcG" : Mapping({u"\0" : 1})})):TypeError:('expected string without null bytes',)
+fd(self=Mapping({"abcG" : Mapping({"\0" : 1})})):TypeError:('expected string without null bytes',)
+<<< Finished
+>>> Testing *Iter* using fd(self=Mapping({"abcG" : %s}))
+fd(self=Mapping({"abcG" : FailingIter()})):TypeError:('unable to convert FailingIter to vim structure',)
+fd(self=Mapping({"abcG" : FailingIterNext()})):NotImplementedError:('next',)
+<<< Finished
+>>> Testing ConvertFromPyObject using fd(self=Mapping({"abcG" : %s}))
+fd(self=Mapping({"abcG" : None})):TypeError:('unable to convert NoneType to vim structure',)
+fd(self=Mapping({"abcG" : {"": 1}})):ValueError:('empty keys are not allowed',)
+fd(self=Mapping({"abcG" : {u"": 1}})):ValueError:('empty keys are not allowed',)
+fd(self=Mapping({"abcG" : FailingMapping()})):NotImplementedError:('keys',)
+fd(self=Mapping({"abcG" : FailingMappingKey()})):NotImplementedError:('getitem:mappingkey',)
+fd(self=Mapping({"abcG" : FailingNumber()})):TypeError:('long() argument must be a string or a number',)
+<<< Finished
+>>> Testing *Iter* using fd(self=%s)
+fd(self=FailingIter()):TypeError:('unable to convert FailingIter to vim dictionary',)
+fd(self=FailingIterNext()):TypeError:('unable to convert FailingIterNext to vim dictionary',)
+<<< Finished
+>>> Testing ConvertFromPyObject using fd(self=%s)
+fd(self=None):TypeError:('unable to convert NoneType to vim dictionary',)
+fd(self={"": 1}):ValueError:('empty keys are not allowed',)
+fd(self={u"": 1}):ValueError:('empty keys are not allowed',)
+fd(self=FailingMapping()):NotImplementedError:('keys',)
+fd(self=FailingMappingKey()):NotImplementedError:('getitem:mappingkey',)
+fd(self=FailingNumber()):TypeError:('unable to convert FailingNumber to vim dictionary',)
+<<< Finished
+>>> Testing ConvertFromPyMapping using fd(self=%s)
+fd(self=[]):TypeError:('unable to convert list to vim dictionary',)
+<<< Finished
+> TabPage
+>> TabPageAttr
+vim.current.tabpage.xxx:AttributeError:('xxx',)
+> TabList
+>> TabListItem
+vim.tabpages[1000]:IndexError:('no such tab page',)
+> Window
+>> WindowAttr
+vim.current.window.xxx:AttributeError:('xxx',)
+>> WindowSetattr
+vim.current.window.buffer = 0:TypeError:('readonly attribute: buffer',)
+vim.current.window.cursor = (100000000, 100000000):error:('cursor position outside buffer',)
+vim.current.window.cursor = True:TypeError:('argument must be 2-item sequence, not bool',)
+>>> Testing NumberToLong using vim.current.window.height = %s
+vim.current.window.height = []:TypeError:('expected int(), long() or something supporting coercing to long(), but got list',)
+vim.current.window.height = None:TypeError:('expected int(), long() or something supporting coercing to long(), but got NoneType',)
+vim.current.window.height = -1:ValueError:('number must be greater or equal to zero',)
+<<< Finished
+>>> Testing NumberToLong using vim.current.window.width = %s
+vim.current.window.width = []:TypeError:('expected int(), long() or something supporting coercing to long(), but got list',)
+vim.current.window.width = None:TypeError:('expected int(), long() or something supporting coercing to long(), but got NoneType',)
+vim.current.window.width = -1:ValueError:('number must be greater or equal to zero',)
+<<< Finished
+vim.current.window.xxxxxx = True:AttributeError:('xxxxxx',)
+> WinList
+>> WinListItem
+vim.windows[1000]:IndexError:('no such window',)
+> Buffer
+>> StringToLine (indirect)
+vim.current.buffer[0] = u"\na":error:('string cannot contain newlines',)
+vim.current.buffer[0] = "\na":error:('string cannot contain newlines',)
+>> SetBufferLine (indirect)
+vim.current.buffer[0] = True:TypeError:('bad argument type for built-in operation',)
+>> SetBufferLineList (indirect)
+vim.current.buffer[:] = True:TypeError:('bad argument type for built-in operation',)
+vim.current.buffer[:] = ["\na", "bc"]:error:('string cannot contain newlines',)
+>> InsertBufferLines (indirect)
+vim.current.buffer.append(None):TypeError:('bad argument type for built-in operation',)
+vim.current.buffer.append(["\na", "bc"]):error:('string cannot contain newlines',)
+vim.current.buffer.append("\nbc"):error:('string cannot contain newlines',)
+>> RBItem
+vim.current.buffer[100000000]:IndexError:('line number out of range',)
+>> RBAsItem
+vim.current.buffer[100000000] = "":IndexError:('line number out of range',)
+>> BufferAttr
+vim.current.buffer.xxx:AttributeError:('xxx',)
+>> BufferSetattr
+vim.current.buffer.name = True:TypeError:('expected str() or unicode() instance, but got bool',)
+vim.current.buffer.xxx = True:AttributeError:('xxx',)
+>> BufferMark
+vim.current.buffer.mark(0):TypeError:('expected str() or unicode() instance, but got int',)
+vim.current.buffer.mark("abcM"):ValueError:('mark name must be a single character',)
+vim.current.buffer.mark("!"):error:('invalid mark name',)
+>> BufferRange
+vim.current.buffer.range(1, 2, 3):TypeError:('function takes exactly 2 arguments (3 given)',)
+> BufMap
+>> BufMapItem
+vim.buffers[100000000]:KeyError:(100000000,)
+>>> Testing NumberToLong using vim.buffers[%s]
+vim.buffers[[]]:TypeError:('expected int(), long() or something supporting coercing to long(), but got list',)
+vim.buffers[None]:TypeError:('expected int(), long() or something supporting coercing to long(), but got NoneType',)
+vim.buffers[-1]:ValueError:('number must be greater then zero',)
+vim.buffers[0]:ValueError:('number must be greater then zero',)
+<<< Finished
+> Current
+>> CurrentGetattr
+vim.current.xxx:AttributeError:('xxx',)
+>> CurrentSetattr
+vim.current.line = True:TypeError:('bad argument type for built-in operation',)
+vim.current.buffer = True:TypeError:('expected vim.Buffer object, but got bool',)
+vim.current.window = True:TypeError:('expected vim.Window object, but got bool',)
+vim.current.tabpage = True:TypeError:('expected vim.TabPage object, but got bool',)
+vim.current.xxx = True:AttributeError:('xxx',)
+['/testdir']
+'/testdir'
+2,xx
+before
+after
+pythonx/topmodule/__init__.py
+pythonx/topmodule/submodule/__init__.py
+pythonx/topmodule/submodule/subsubmodule/subsubsubmodule.py
+vim.command("throw 'abcN'"):error:('abcN',)
+Exe("throw 'def'"):error:('def',)
+vim.eval("Exe('throw ''ghi''')"):error:('ghi',)
+vim.eval("Exe('echoerr ''jkl''')"):error:('Vim(echoerr):jkl',)
+vim.eval("Exe('xxx_non_existent_command_xxx')"):error:('Vim:E492: Not an editor command: xxx_non_existent_command_xxx',)
+vim.eval("xxx_unknown_function_xxx()"):error:('Vim:E117: Unknown function: xxx_unknown_function_xxx',)
+vim.bindeval("Exe('xxx_non_existent_command_xxx')"):error:('Vim:E492: Not an editor command: xxx_non_existent_command_xxx',)
+Caught KeyboardInterrupt
+Running :put
+No exception
+
diff --git a/src/testdir/test87.in b/src/testdir/test87.in
new file mode 100644
index 0000000000..e45883b59d
--- /dev/null
+++ b/src/testdir/test87.in
@@ -0,0 +1,1406 @@
+Tests for various python features. vim: set ft=vim :
+
+STARTTEST
+:so small.vim
+:set noswapfile
+:if !has('python3') | e! test.ok | wq! test.out | endif
+:lang C
+:fun Test()
+:py3 import vim
+:let l = []
+:py3 l=vim.bindeval('l')
+:py3 f=vim.bindeval('function("strlen")')
+:" Extending List directly with different types
+:py3 l+=[1, "as'd", [1, 2, f, {'a': 1}]]
+:$put =string(l)
+:$put =string(l[-1])
+:try
+: $put =string(l[-4])
+:catch
+: $put =v:exception[:13]
+:endtry
+:" List assignment
+:py3 l[0]=0
+:$put =string(l)
+:py3 l[-2]=f
+:$put =string(l)
+:"
+:" Extending Dictionary directly with different types
+:let d = {}
+:fun d.f()
+: return 1
+:endfun
+py3 << EOF
+d=vim.bindeval('d')
+d['1']='asd'
+d.update(b=[1, 2, f])
+d.update((('-1', {'a': 1}),))
+d.update({'0': -1})
+dk = d.keys()
+dv = d.values()
+di = d.items()
+dk.sort(key=repr)
+dv.sort(key=repr)
+di.sort(key=repr)
+EOF
+:$put =py3eval('d[''f''](self={})')
+:$put =py3eval('repr(dk)')
+:$put =substitute(py3eval('repr(dv)'),'0x\x\+','','g')
+:$put =substitute(py3eval('repr(di)'),'0x\x\+','','g')
+:for [key, Val] in sort(items(d))
+: $put =string(key) . ' : ' . string(Val)
+: unlet key Val
+:endfor
+:py3 del dk
+:py3 del di
+:py3 del dv
+:"
+:" removing items with del
+:py3 del l[2]
+:$put =string(l)
+:let l = range(8)
+:py3 l=vim.bindeval('l')
+:try
+: py3 del l[:3]
+: py3 del l[1:]
+:catch
+: $put =v:exception
+:endtry
+:$put =string(l)
+:"
+:py3 del d['-1']
+:py3 del d['f']
+:$put =string(py3eval('d.get(''b'', 1)'))
+:$put =string(py3eval('d.pop(''b'')'))
+:$put =string(py3eval('d.get(''b'', 1)'))
+:$put =string(py3eval('d.pop(''1'', 2)'))
+:$put =string(py3eval('d.pop(''1'', 2)'))
+:$put =py3eval('repr(d.has_key(''0''))')
+:$put =py3eval('repr(d.has_key(''1''))')
+:$put =py3eval('repr(''0'' in d)')
+:$put =py3eval('repr(''1'' in d)')
+:$put =py3eval('repr(list(iter(d)))')
+:$put =string(d)
+:$put =py3eval('repr(d.popitem())')
+:$put =py3eval('repr(d.get(''0''))')
+:$put =py3eval('repr(list(iter(d)))')
+:"
+:" removing items out of range: silently skip items that don't exist
+:let l = [0, 1, 2, 3]
+:py3 l=vim.bindeval('l')
+:" The following two ranges delete nothing as they match empty list:
+:py3 del l[2:1]
+:$put =string(l)
+:py3 del l[2:2]
+:$put =string(l)
+:py3 del l[2:3]
+:$put =string(l)
+:let l = [0, 1, 2, 3]
+:py3 l=vim.bindeval('l')
+:py3 del l[2:4]
+:$put =string(l)
+:let l = [0, 1, 2, 3]
+:py3 l=vim.bindeval('l')
+:py3 del l[2:5]
+:$put =string(l)
+:let l = [0, 1, 2, 3]
+:py3 l=vim.bindeval('l')
+:py3 del l[2:6]
+:$put =string(l)
+:let l = [0, 1, 2, 3]
+:py3 l=vim.bindeval('l')
+:" The following two ranges delete nothing as they match empty list:
+:py3 del l[-1:2]
+:$put =string(l)
+:py3 del l[-2:2]
+:$put =string(l)
+:py3 del l[-3:2]
+:$put =string(l)
+:let l = [0, 1, 2, 3]
+:py3 l=vim.bindeval('l')
+:py3 del l[-4:2]
+:$put =string(l)
+:let l = [0, 1, 2, 3]
+:py3 l=vim.bindeval('l')
+:py3 del l[-5:2]
+:$put =string(l)
+:let l = [0, 1, 2, 3]
+:py3 l=vim.bindeval('l')
+:py3 del l[-6:2]
+:$put =string(l)
+:let l = [0, 1, 2, 3]
+:py3 l=vim.bindeval('l')
+:py3 del l[::2]
+:$put =string(l)
+:let l = [0, 1, 2, 3]
+:py3 l=vim.bindeval('l')
+:py3 del l[3:0:-2]
+:$put =string(l)
+:let l = [0, 1, 2, 3]
+:py3 l=vim.bindeval('l')
+:py3 del l[2:4:-2]
+:$put =string(l)
+:"
+:" Slice assignment to a list
+:let l = [0, 1, 2, 3]
+:py3 l=vim.bindeval('l')
+:py3 l[0:0]=['a']
+:$put =string(l)
+:let l = [0, 1, 2, 3]
+:py3 l=vim.bindeval('l')
+:py3 l[1:2]=['b']
+:$put =string(l)
+:let l = [0, 1, 2, 3]
+:py3 l=vim.bindeval('l')
+:py3 l[2:4]=['c']
+:$put =string(l)
+:let l = [0, 1, 2, 3]
+:py3 l=vim.bindeval('l')
+:py3 l[4:4]=['d']
+:$put =string(l)
+:let l = [0, 1, 2, 3]
+:py3 l=vim.bindeval('l')
+:py3 l[-1:2]=['e']
+:$put =string(l)
+:let l = [0, 1, 2, 3]
+:py3 l=vim.bindeval('l')
+:py3 l[-10:2]=['f']
+:$put =string(l)
+:let l = [0, 1, 2, 3]
+:py3 l=vim.bindeval('l')
+:py3 l[2:-10]=['g']
+:$put =string(l)
+:let l = []
+:py3 l=vim.bindeval('l')
+:py3 l[0:0]=['h']
+:$put =string(l)
+:let l = range(8)
+:py3 l=vim.bindeval('l')
+:py3 l[2:6:2] = [10, 20]
+:$put =string(l)
+:let l = range(8)
+:py3 l=vim.bindeval('l')
+:py3 l[6:2:-2] = [10, 20]
+:$put =string(l)
+:let l = range(8)
+:py3 l=vim.bindeval('l')
+:py3 l[6:2] = ()
+:$put =string(l)
+:let l = range(8)
+:py3 l=vim.bindeval('l')
+:py3 l[6:2:1] = ()
+:$put =string(l)
+:let l = range(8)
+:py3 l=vim.bindeval('l')
+:py3 l[2:2:1] = ()
+:$put =string(l)
+:"
+:" Locked variables
+:let l = [0, 1, 2, 3]
+:py3 l=vim.bindeval('l')
+:lockvar! l
+:py3 l[2]='i'
+:$put =string(l)
+:unlockvar! l
+:"
+:" Function calls
+py3 << EOF
+import sys
+import re
+
+py33_type_error_pattern = re.compile('^__call__\(\) takes (\d+) positional argument but (\d+) were given$')
+
+def ee(expr, g=globals(), l=locals()):
+ cb = vim.current.buffer
+ try:
+ try:
+ exec(expr, g, l)
+ except Exception as e:
+ if sys.version_info >= (3, 3) and e.__class__ is AttributeError and str(e).find('has no attribute')>=0 and not str(e).startswith("'vim."):
+ cb.append(expr + ':' + repr((e.__class__, AttributeError(str(e)[str(e).rfind(" '") + 2:-1]))))
+ elif sys.version_info >= (3, 3) and e.__class__ is ImportError and str(e).find('No module named \'') >= 0:
+ cb.append(expr + ':' + repr((e.__class__, ImportError(str(e).replace("'", '')))))
+ elif sys.version_info >= (3, 3) and e.__class__ is TypeError:
+ m = py33_type_error_pattern.search(str(e))
+ if m:
+ msg = '__call__() takes exactly {0} positional argument ({1} given)'.format(m.group(1), m.group(2))
+ cb.append(expr + ':' + repr((e.__class__, TypeError(msg))))
+ else:
+ cb.append(expr + ':' + repr((e.__class__, e)))
+ else:
+ cb.append(expr + ':' + repr((e.__class__, e)))
+ else:
+ cb.append(expr + ':NOT FAILED')
+ except Exception as e:
+ cb.append(expr + '::' + repr((e.__class__, e)))
+EOF
+:fun New(...)
+: return ['NewStart']+a:000+['NewEnd']
+:endfun
+:fun DictNew(...) dict
+: return ['DictNewStart']+a:000+['DictNewEnd', self]
+:endfun
+:let l=[function('New'), function('DictNew')]
+:py3 l=vim.bindeval('l')
+:py3 l.extend(list(l[0](1, 2, 3)))
+:$put =string(l)
+:py3 l.extend(list(l[1](1, 2, 3, self={'a': 'b'})))
+:$put =string(l)
+:py3 l+=[l[0].name]
+:$put =string(l)
+:py3 ee('l[1](1, 2, 3)')
+:py3 f=l[0]
+:delfunction New
+:py3 ee('f(1, 2, 3)')
+:if has('float')
+: let l=[0.0]
+: py3 l=vim.bindeval('l')
+: py3 l.extend([0.0])
+: $put =string(l)
+:else
+: $put ='[0.0, 0.0]'
+:endif
+:let messages=[]
+:delfunction DictNew
+py3 <<EOF
+d=vim.bindeval('{}')
+m=vim.bindeval('messages')
+def em(expr, g=globals(), l=locals()):
+ try:
+ exec(expr, g, l)
+ except Exception as e:
+ m.extend([e.__class__.__name__])
+
+em('d["abc1"]')
+em('d["abc1"]="\\0"')
+em('d["abc1"]=vim')
+em('d[""]=1')
+em('d["a\\0b"]=1')
+em('d[b"a\\0b"]=1')
+
+em('d.pop("abc1")')
+em('d.popitem()')
+del em
+del m
+EOF
+:$put =messages
+:unlet messages
+:" locked and scope attributes
+:let d={} | let dl={} | lockvar dl
+:for s in split("d dl v: g:")
+: let name=tr(s, ':', 's')
+: execute 'py3 '.name.'=vim.bindeval("'.s.'")'
+: let toput=s.' : '.join(map(['locked', 'scope'], 'v:val.":".py3eval(name.".".v:val)'), ';')
+: $put =toput
+:endfor
+:silent! let d.abc2=1
+:silent! let dl.abc3=1
+:py3 d.locked=True
+:py3 dl.locked=False
+:silent! let d.def=1
+:silent! let dl.def=1
+:put ='d:'.string(d)
+:put ='dl:'.string(dl)
+:unlet d dl
+:
+:let l=[] | let ll=[] | lockvar ll
+:for s in split("l ll")
+: let name=tr(s, ':', 's')
+: execute 'py3 '.name.'=vim.bindeval("'.s.'")'
+: let toput=s.' : locked:'.py3eval(name.'.locked')
+: $put =toput
+:endfor
+:silent! call extend(l, [0])
+:silent! call extend(ll, [0])
+:py3 l.locked=True
+:py3 ll.locked=False
+:silent! call extend(l, [1])
+:silent! call extend(ll, [1])
+:put ='l:'.string(l)
+:put ='ll:'.string(ll)
+:unlet l ll
+:"
+:" py3eval()
+:let l=py3eval('[0, 1, 2]')
+:$put =string(l)
+:let d=py3eval('{"a": "b", "c": 1, "d": ["e"]}')
+:$put =sort(items(d))
+:if has('float')
+: let f=py3eval('0.0')
+: $put =string(f)
+:else
+: $put ='0.0'
+:endif
+:" Invalid values:
+:for e in ['"\0"', '{"\0": 1}', 'undefined_name', 'vim']
+: try
+: let v=py3eval(e)
+: catch
+: let toput=e.":\t".v:exception[:13]
+: $put =toput
+: endtry
+:endfor
+:"
+:" threading
+:let l = [0]
+:py3 l=vim.bindeval('l')
+py3 <<EOF
+import threading
+import time
+
+class T(threading.Thread):
+ def __init__(self):
+ threading.Thread.__init__(self)
+ self.t = 0
+ self.running = True
+
+ def run(self):
+ while self.running:
+ self.t += 1
+ time.sleep(0.1)
+
+t = T()
+del T
+t.start()
+EOF
+:sleep 1
+:py3 t.running = False
+:py3 t.join()
+:py3 l[0] = t.t > 8 # check if the background thread is working
+:py3 del time
+:py3 del threading
+:py3 del t
+:$put =string(l)
+:"
+:" settrace
+:let l = []
+:py3 l=vim.bindeval('l')
+py3 <<EOF
+import sys
+
+def traceit(frame, event, arg):
+ global l
+ if event == "line":
+ l += [frame.f_lineno]
+ return traceit
+
+def trace_main():
+ for i in range(5):
+ pass
+EOF
+:py3 sys.settrace(traceit)
+:py3 trace_main()
+:py3 sys.settrace(None)
+:py3 del traceit
+:py3 del trace_main
+:$put =string(l)
+:"
+:" Slice
+:py3 ll = vim.bindeval('[0, 1, 2, 3, 4, 5]')
+:py3 l = ll[:4]
+:$put =string(py3eval('l'))
+:py3 l = ll[2:]
+:$put =string(py3eval('l'))
+:py3 l = ll[:-4]
+:$put =string(py3eval('l'))
+:py3 l = ll[-2:]
+:$put =string(py3eval('l'))
+:py3 l = ll[2:4]
+:$put =string(py3eval('l'))
+:py3 l = ll[4:2]
+:$put =string(py3eval('l'))
+:py3 l = ll[-4:-2]
+:$put =string(py3eval('l'))
+:py3 l = ll[-2:-4]
+:$put =string(py3eval('l'))
+:py3 l = ll[:]
+:$put =string(py3eval('l'))
+:py3 l = ll[0:6]
+:$put =string(py3eval('l'))
+:py3 l = ll[-10:10]
+:$put =string(py3eval('l'))
+:py3 l = ll[4:2:-1]
+:$put =string(py3eval('l'))
+:py3 l = ll[::2]
+:$put =string(py3eval('l'))
+:py3 l = ll[4:2:1]
+:$put =string(py3eval('l'))
+:py3 del l
+:"
+:" Vars
+:let g:foo = 'bac'
+:let w:abc3 = 'def'
+:let b:baz = 'bar'
+:let t:bar = 'jkl'
+:try
+: throw "Abc"
+:catch
+: put =py3eval('vim.vvars[''exception'']')
+:endtry
+:put =py3eval('vim.vars[''foo'']')
+:put =py3eval('vim.current.window.vars[''abc3'']')
+:put =py3eval('vim.current.buffer.vars[''baz'']')
+:put =py3eval('vim.current.tabpage.vars[''bar'']')
+:"
+:" Options
+:" paste: boolean, global
+:" previewheight number, global
+:" operatorfunc: string, global
+:" number: boolean, window-local
+:" numberwidth: number, window-local
+:" colorcolumn: string, window-local
+:" statusline: string, window-local/global
+:" autoindent: boolean, buffer-local
+:" shiftwidth: number, buffer-local
+:" omnifunc: string, buffer-local
+:" preserveindent: boolean, buffer-local/global
+:" path: string, buffer-local/global
+:let g:bufs=[bufnr('%')]
+:new
+:let g:bufs+=[bufnr('%')]
+:vnew
+:let g:bufs+=[bufnr('%')]
+:wincmd j
+:vnew
+:let g:bufs+=[bufnr('%')]
+:wincmd l
+:fun RecVars(opt)
+: let gval =string(eval('&g:'.a:opt))
+: let wvals=join(map(range(1, 4), 'v:val.":".string(getwinvar(v:val, "&".a:opt))'))
+: let bvals=join(map(copy(g:bufs), 'v:val.":".string(getbufvar(v:val, "&".a:opt))'))
+: put =' G: '.gval
+: put =' W: '.wvals
+: put =' B: '.wvals
+:endfun
+py3 << EOF
+def e(s, g=globals(), l=locals()):
+ try:
+ exec(s, g, l)
+ except Exception as e:
+ vim.command('return ' + repr(e.__class__.__name__))
+
+def ev(s, g=globals(), l=locals()):
+ try:
+ return eval(s, g, l)
+ except Exception as e:
+ vim.command('let exc=' + repr(e.__class__.__name__))
+ return 0
+EOF
+:fun E(s)
+: python3 e(vim.eval('a:s'))
+:endfun
+:fun Ev(s)
+: let r=py3eval('ev(vim.eval("a:s"))')
+: if exists('exc')
+: throw exc
+: endif
+: return r
+:endfun
+:py3 gopts1=vim.options
+:py3 wopts1=vim.windows[2].options
+:py3 wopts2=vim.windows[0].options
+:py3 wopts3=vim.windows[1].options
+:py3 bopts1=vim.buffers[vim.bindeval("g:bufs")[2]].options
+:py3 bopts2=vim.buffers[vim.bindeval("g:bufs")[1]].options
+:py3 bopts3=vim.buffers[vim.bindeval("g:bufs")[0]].options
+:$put ='wopts iters equal: '.py3eval('list(wopts1) == list(wopts2)')
+:$put ='bopts iters equal: '.py3eval('list(bopts1) == list(bopts2)')
+:py3 gset=set(iter(gopts1))
+:py3 wset=set(iter(wopts1))
+:py3 bset=set(iter(bopts1))
+:set path=.,..,,
+:let lst=[]
+:let lst+=[['paste', 1, 0, 1, 2, 1, 1, 0 ]]
+:let lst+=[['previewheight', 5, 1, 6, 'a', 0, 1, 0 ]]
+:let lst+=[['operatorfunc', 'A', 'B', 'C', 2, 0, 1, 0 ]]
+:let lst+=[['number', 0, 1, 1, 0, 1, 0, 1 ]]
+:let lst+=[['numberwidth', 2, 3, 5, -100, 0, 0, 1 ]]
+:let lst+=[['colorcolumn', '+1', '+2', '+3', 'abc4', 0, 0, 1 ]]
+:let lst+=[['statusline', '1', '2', '4', 0, 0, 1, 1 ]]
+:let lst+=[['autoindent', 0, 1, 1, 2, 1, 0, 2 ]]
+:let lst+=[['shiftwidth', 0, 2, 1, 3, 0, 0, 2 ]]
+:let lst+=[['omnifunc', 'A', 'B', 'C', 1, 0, 0, 2 ]]
+:let lst+=[['preserveindent', 0, 1, 1, 2, 1, 1, 2 ]]
+:let lst+=[['path', '.,,', ',,', '.', 0, 0, 1, 2 ]]
+:for [oname, oval1, oval2, oval3, invval, bool, global, local] in lst
+: py3 oname=vim.eval('oname')
+: py3 oval1=vim.bindeval('oval1')
+: py3 oval2=vim.bindeval('oval2')
+: py3 oval3=vim.bindeval('oval3')
+: if invval is 0 || invval is 1
+: py3 invval=bool(vim.bindeval('invval'))
+: else
+: py3 invval=vim.bindeval('invval')
+: endif
+: if bool
+: py3 oval1=bool(oval1)
+: py3 oval2=bool(oval2)
+: py3 oval3=bool(oval3)
+: endif
+: put ='>>> '.oname
+: $put =' g/w/b:'.py3eval('oname in gset').'/'.py3eval('oname in wset').'/'.py3eval('oname in bset')
+: $put =' g/w/b (in):'.py3eval('oname in gopts1').'/'.py3eval('oname in wopts1').'/'.py3eval('oname in bopts1')
+: for v in ['gopts1', 'wopts1', 'bopts1']
+: try
+: put =' p/'.v.': '.Ev('repr('.v.'['''.oname.'''])')
+: catch
+: put =' p/'.v.'! '.v:exception
+: endtry
+: let r=E(v.'['''.oname.''']=invval')
+: if r isnot 0
+: put =' inv: '.string(invval).'! '.r
+: endif
+: for vv in (v is# 'gopts1' ? [v] : [v, v[:-2].'2', v[:-2].'3'])
+: let val=substitute(vv, '^.opts', 'oval', '')
+: let r=E(vv.'['''.oname.''']='.val)
+: if r isnot 0
+: put =' '.vv.'! '.r
+: endif
+: endfor
+: endfor
+: call RecVars(oname)
+: for v in ['wopts3', 'bopts3']
+: let r=E('del '.v.'["'.oname.'"]')
+: if r isnot 0
+: put =' del '.v.'! '.r
+: endif
+: endfor
+: call RecVars(oname)
+:endfor
+:delfunction RecVars
+:delfunction E
+:delfunction Ev
+:py3 del ev
+:py3 del e
+:only
+:for buf in g:bufs[1:]
+: execute 'bwipeout!' buf
+:endfor
+:py3 del gopts1
+:py3 del wopts1
+:py3 del wopts2
+:py3 del wopts3
+:py3 del bopts1
+:py3 del bopts2
+:py3 del bopts3
+:py3 del oval1
+:py3 del oval2
+:py3 del oval3
+:py3 del oname
+:py3 del invval
+:"
+:" Test buffer object
+:vnew
+:put ='First line'
+:put ='Second line'
+:put ='Third line'
+:1 delete _
+:py3 b=vim.current.buffer
+:wincmd w
+:mark a
+:augroup BUFS
+: autocmd BufFilePost * python3 cb.append(vim.eval('expand("<abuf>")') + ':BufFilePost:' + vim.eval('bufnr("%")'))
+: autocmd BufFilePre * python3 cb.append(vim.eval('expand("<abuf>")') + ':BufFilePre:' + vim.eval('bufnr("%")'))
+:augroup END
+py3 << EOF
+cb = vim.current.buffer
+# Tests BufferAppend and BufferItem
+cb.append(b[0])
+# Tests BufferSlice and BufferAssSlice
+cb.append('abc5') # Will be overwritten
+cb[-1:] = b[:-2]
+# Test BufferLength and BufferAssSlice
+cb.append('def') # Will not be overwritten
+cb[len(cb):] = b[:]
+# Test BufferAssItem and BufferMark
+cb.append('ghi') # Will be overwritten
+cb[-1] = repr((len(cb) - cb.mark('a')[0], cb.mark('a')[1]))
+# Test BufferRepr
+cb.append(repr(cb) + repr(b))
+# Modify foreign buffer
+b.append('foo')
+b[0]='bar'
+b[0:0]=['baz']
+vim.command('call append("$", getbufline(%i, 1, "$"))' % b.number)
+# Test assigning to name property
+import os
+old_name = cb.name
+cb.name = 'foo'
+cb.append(cb.name[-11:].replace(os.path.sep, '/'))
+b.name = 'bar'
+cb.append(b.name[-11:].replace(os.path.sep, '/'))
+cb.name = old_name
+cb.append(cb.name[-17:].replace(os.path.sep, '/'))
+del old_name
+# Test CheckBuffer
+for _b in vim.buffers:
+ if _b is not cb:
+ vim.command('bwipeout! ' + str(_b.number))
+del _b
+cb.append('valid: b:%s, cb:%s' % (repr(b.valid), repr(cb.valid)))
+for expr in ('b[1]','b[:] = ["A", "B"]','b[:]','b.append("abc6")'):
+ try:
+ exec(expr)
+ except vim.error:
+ pass
+ else:
+ # Usually a SEGV here
+ # Should not happen in any case
+ cb.append('No exception for ' + expr)
+vim.command('cd .')
+del b
+EOF
+:"
+:" Test vim.buffers object
+:set hidden
+:edit a
+:buffer #
+:edit b
+:buffer #
+:edit c
+:buffer #
+py3 << EOF
+# Check GCing iterator that was not fully exhausted
+i = iter(vim.buffers)
+cb.append('i:' + str(next(i)))
+# and also check creating more then one iterator at a time
+i2 = iter(vim.buffers)
+cb.append('i2:' + str(next(i2)))
+cb.append('i:' + str(next(i)))
+# The following should trigger GC and not cause any problems
+del i
+del i2
+i3 = iter(vim.buffers)
+cb.append('i3:' + str(next(i3)))
+del i3
+
+prevnum = 0
+for b in vim.buffers:
+ # Check buffer order
+ if prevnum >= b.number:
+ cb.append('!!! Buffer numbers not in strictly ascending order')
+ # Check indexing: vim.buffers[number].number == number
+ cb.append(str(b.number) + ':' + repr(vim.buffers[b.number]) + '=' + repr(b))
+ prevnum = b.number
+del prevnum
+
+cb.append(str(len(vim.buffers)))
+
+bnums = list(map(lambda b: b.number, vim.buffers))[1:]
+
+# Test wiping out buffer with existing iterator
+i4 = iter(vim.buffers)
+cb.append('i4:' + str(next(i4)))
+vim.command('bwipeout! ' + str(bnums.pop(0)))
+try:
+ next(i4)
+except vim.error:
+ pass
+else:
+ cb.append('!!!! No vim.error')
+i4 = iter(vim.buffers)
+vim.command('bwipeout! ' + str(bnums.pop(-1)))
+vim.command('bwipeout! ' + str(bnums.pop(-1)))
+cb.append('i4:' + str(next(i4)))
+try:
+ next(i4)
+except StopIteration:
+ cb.append('StopIteration')
+del i4
+del bnums
+EOF
+:"
+:" Test vim.{tabpage,window}list and vim.{tabpage,window} objects
+:tabnew 0
+:tabnew 1
+:vnew a.1
+:tabnew 2
+:vnew a.2
+:vnew b.2
+:vnew c.2
+py3 << EOF
+cb.append('Number of tabs: ' + str(len(vim.tabpages)))
+cb.append('Current tab pages:')
+
+def W(w):
+ if '(unknown)' in repr(w):
+ return '<window object (unknown)>'
+ else:
+ return repr(w)
+
+def Cursor(w, start=len(cb)):
+ if w.buffer is cb:
+ return repr((start - w.cursor[0], w.cursor[1]))
+ else:
+ return repr(w.cursor)
+
+for t in vim.tabpages:
+ cb.append(' ' + repr(t) + '(' + str(t.number) + ')' + ': ' + str(len(t.windows)) + ' windows, current is ' + W(t.window))
+ cb.append(' Windows:')
+ for w in t.windows:
+ cb.append(' ' + W(w) + '(' + str(w.number) + ')' + ': displays buffer ' + repr(w.buffer) + '; cursor is at ' + Cursor(w))
+ # Other values depend on the size of the terminal, so they are checked partly:
+ for attr in ('height', 'row', 'width', 'col'):
+ try:
+ aval = getattr(w, attr)
+ if type(aval) is not int:
+ raise TypeError
+ if aval < 0:
+ raise ValueError
+ except Exception as e:
+ cb.append('!!!!!! Error while getting attribute ' + attr + ': ' + e.__class__.__name__)
+ del aval
+ del attr
+ w.cursor = (len(w.buffer), 0)
+del W
+del Cursor
+cb.append('Number of windows in current tab page: ' + str(len(vim.windows)))
+if list(vim.windows) != list(vim.current.tabpage.windows):
+ cb.append('!!!!!! Windows differ')
+EOF
+:"
+:" Test vim.current
+py3 << EOF
+def H(o):
+ return repr(o)
+cb.append('Current tab page: ' + repr(vim.current.tabpage))
+cb.append('Current window: ' + repr(vim.current.window) + ': ' + H(vim.current.window) + ' is ' + H(vim.current.tabpage.window))
+cb.append('Current buffer: ' + repr(vim.current.buffer) + ': ' + H(vim.current.buffer) + ' is ' + H(vim.current.window.buffer)+ ' is ' + H(vim.current.tabpage.window.buffer))
+del H
+# Assigning: fails
+try:
+ vim.current.window = vim.tabpages[0].window
+except ValueError:
+ cb.append('ValueError at assigning foreign tab window')
+
+for attr in ('window', 'tabpage', 'buffer'):
+ try:
+ setattr(vim.current, attr, None)
+ except TypeError:
+ cb.append('Type error at assigning None to vim.current.' + attr)
+del attr
+
+# Assigning: success
+vim.current.tabpage = vim.tabpages[-2]
+vim.current.buffer = cb
+vim.current.window = vim.windows[0]
+vim.current.window.cursor = (len(vim.current.buffer), 0)
+cb.append('Current tab page: ' + repr(vim.current.tabpage))
+cb.append('Current window: ' + repr(vim.current.window))
+cb.append('Current buffer: ' + repr(vim.current.buffer))
+cb.append('Current line: ' + repr(vim.current.line))
+ws = list(vim.windows)
+ts = list(vim.tabpages)
+for b in vim.buffers:
+ if b is not cb:
+ vim.command('bwipeout! ' + str(b.number))
+del b
+cb.append('w.valid: ' + repr([w.valid for w in ws]))
+cb.append('t.valid: ' + repr([t.valid for t in ts]))
+del w
+del t
+del ts
+del ws
+EOF
+:tabonly!
+:only!
+:"
+:" Test types
+py3 << EOF
+for expr, attr in (
+ ('vim.vars', 'Dictionary'),
+ ('vim.options', 'Options'),
+ ('vim.bindeval("{}")', 'Dictionary'),
+ ('vim.bindeval("[]")', 'List'),
+ ('vim.bindeval("function(\'tr\')")', 'Function'),
+ ('vim.current.buffer', 'Buffer'),
+ ('vim.current.range', 'Range'),
+ ('vim.current.window', 'Window'),
+ ('vim.current.tabpage', 'TabPage'),
+):
+ cb.append(expr + ':' + attr + ':' + repr(type(eval(expr)) is getattr(vim, attr)))
+del expr
+del attr
+EOF
+:"
+:" Test __dir__() method
+py3 << EOF
+for name, o in (
+ ('current', vim.current),
+ ('buffer', vim.current.buffer),
+ ('window', vim.current.window),
+ ('tabpage', vim.current.tabpage),
+ ('range', vim.current.range),
+ ('dictionary', vim.bindeval('{}')),
+ ('list', vim.bindeval('[]')),
+ ('function', vim.bindeval('function("tr")')),
+ ('output', sys.stdout),
+ ):
+ cb.append(name + ':' + ','.join(dir(o)))
+del name
+del o
+EOF
+:"
+:" Test vim.*.__new__
+:$put =string(py3eval('vim.Dictionary({})'))
+:$put =string(py3eval('vim.Dictionary(a=1)'))
+:$put =string(py3eval('vim.Dictionary(((''a'', 1),))'))
+:$put =string(py3eval('vim.List()'))
+:$put =string(py3eval('vim.List(iter(''abc7''))'))
+:$put =string(py3eval('vim.Function(''tr'')'))
+:"
+:" Test stdout/stderr
+:redir => messages
+:py3 sys.stdout.write('abc8') ; sys.stdout.write('def')
+:py3 sys.stderr.write('abc9') ; sys.stderr.write('def')
+:py3 sys.stdout.writelines(iter('abcA'))
+:py3 sys.stderr.writelines(iter('abcB'))
+:redir END
+:$put =string(substitute(messages, '\d\+', '', 'g'))
+:" Test subclassing
+:fun Put(...)
+: $put =string(a:000)
+: return a:000
+:endfun
+py3 << EOF
+class DupDict(vim.Dictionary):
+ def __setitem__(self, key, value):
+ super(DupDict, self).__setitem__(key, value)
+ super(DupDict, self).__setitem__('dup_' + key, value)
+dd = DupDict()
+dd['a'] = 'b'
+
+class DupList(vim.List):
+ def __getitem__(self, idx):
+ return [super(DupList, self).__getitem__(idx)] * 2
+
+dl = DupList()
+dl2 = DupList(iter('abcC'))
+dl.extend(dl2[0])
+
+class DupFun(vim.Function):
+ def __call__(self, arg):
+ return super(DupFun, self).__call__(arg, arg)
+
+df = DupFun('Put')
+EOF
+:$put =string(sort(keys(py3eval('dd'))))
+:$put =string(py3eval('dl'))
+:$put =string(py3eval('dl2'))
+:$put =string(py3eval('df(2)'))
+:$put =string(py3eval('dl') is# py3eval('dl'))
+:$put =string(py3eval('dd') is# py3eval('dd'))
+:$put =string(py3eval('df'))
+:delfunction Put
+py3 << EOF
+del DupDict
+del DupList
+del DupFun
+del dd
+del dl
+del dl2
+del df
+EOF
+:"
+:" Test chdir
+py3 << EOF
+import os
+fnamemodify = vim.Function('fnamemodify')
+cb.append(str(fnamemodify('.', ':p:h:t')))
+cb.append(vim.eval('@%'))
+os.chdir('..')
+cb.append(str(fnamemodify('.', ':p:h:t')))
+cb.append(vim.eval('@%').replace(os.path.sep, '/'))
+os.chdir('testdir')
+cb.append(str(fnamemodify('.', ':p:h:t')))
+cb.append(vim.eval('@%'))
+del fnamemodify
+EOF
+:"
+:" Test errors
+:fun F() dict
+:endfun
+:fun D()
+:endfun
+py3 << EOF
+d = vim.Dictionary()
+ned = vim.Dictionary(foo='bar', baz='abcD')
+dl = vim.Dictionary(a=1)
+dl.locked = True
+l = vim.List()
+ll = vim.List('abcE')
+ll.locked = True
+nel = vim.List('abcO')
+f = vim.Function('string')
+fd = vim.Function('F')
+fdel = vim.Function('D')
+vim.command('delfunction D')
+
+def subexpr_test(expr, name, subexprs):
+ cb.append('>>> Testing %s using %s' % (name, expr))
+ for subexpr in subexprs:
+ ee(expr % subexpr)
+ cb.append('<<< Finished')
+
+def stringtochars_test(expr):
+ return subexpr_test(expr, 'StringToChars', (
+ '1', # Fail type checks
+ 'b"\\0"', # Fail PyString_AsStringAndSize(object, , NULL) check
+ '"\\0"', # Fail PyString_AsStringAndSize(bytes, , NULL) check
+ ))
+
+class Mapping(object):
+ def __init__(self, d):
+ self.d = d
+
+ def __getitem__(self, key):
+ return self.d[key]
+
+ def keys(self):
+ return self.d.keys()
+
+ def items(self):
+ return self.d.items()
+
+def convertfrompyobject_test(expr, recurse=True):
+ # pydict_to_tv
+ stringtochars_test(expr % '{%s : 1}')
+ if recurse:
+ convertfrompyobject_test(expr % '{"abcF" : %s}', False)
+ # pymap_to_tv
+ stringtochars_test(expr % 'Mapping({%s : 1})')
+ if recurse:
+ convertfrompyobject_test(expr % 'Mapping({"abcG" : %s})', False)
+ # pyseq_to_tv
+ iter_test(expr)
+ return subexpr_test(expr, 'ConvertFromPyObject', (
+ 'None', # Not conversible
+ '{b"": 1}', # Empty key not allowed
+ '{"": 1}', # Same, but with unicode object
+ 'FailingMapping()', #
+ 'FailingMappingKey()', #
+ 'FailingNumber()', #
+ ))
+
+def convertfrompymapping_test(expr):
+ convertfrompyobject_test(expr)
+ return subexpr_test(expr, 'ConvertFromPyMapping', (
+ '[]',
+ ))
+
+def iter_test(expr):
+ return subexpr_test(expr, '*Iter*', (
+ 'FailingIter()',
+ 'FailingIterNext()',
+ ))
+
+def number_test(expr, natural=False, unsigned=False):
+ if natural:
+ unsigned = True
+ return subexpr_test(expr, 'NumberToLong', (
+ '[]',
+ 'None',
+ ) + (('-1',) if unsigned else ())
+ + (('0',) if natural else ()))
+
+class FailingTrue(object):
+ def __bool__(self):
+ raise NotImplementedError('bool')
+
+class FailingIter(object):
+ def __iter__(self):
+ raise NotImplementedError('iter')
+
+class FailingIterNext(object):
+ def __iter__(self):
+ return self
+
+ def __next__(self):
+ raise NotImplementedError('next')
+
+class FailingIterNextN(object):
+ def __init__(self, n):
+ self.n = n
+
+ def __iter__(self):
+ return self
+
+ def __next__(self):
+ if self.n:
+ self.n -= 1
+ return 1
+ else:
+ raise NotImplementedError('next N')
+
+class FailingMappingKey(object):
+ def __getitem__(self, item):
+ raise NotImplementedError('getitem:mappingkey')
+
+ def keys(self):
+ return list("abcH")
+
+class FailingMapping(object):
+ def __getitem__(self):
+ raise NotImplementedError('getitem:mapping')
+
+ def keys(self):
+ raise NotImplementedError('keys')
+
+class FailingList(list):
+ def __getitem__(self, idx):
+ if i == 2:
+ raise NotImplementedError('getitem:list')
+ else:
+ return super(FailingList, self).__getitem__(idx)
+
+class NoArgsCall(object):
+ def __call__(self):
+ pass
+
+class FailingCall(object):
+ def __call__(self, path):
+ raise NotImplementedError('call')
+
+class FailingNumber(object):
+ def __int__(self):
+ raise NotImplementedError('int')
+
+cb.append("> Output")
+cb.append(">> OutputSetattr")
+ee('del sys.stdout.softspace')
+number_test('sys.stdout.softspace = %s', unsigned=True)
+number_test('sys.stderr.softspace = %s', unsigned=True)
+ee('sys.stdout.attr = None')
+cb.append(">> OutputWrite")
+ee('sys.stdout.write(None)')
+cb.append(">> OutputWriteLines")
+ee('sys.stdout.writelines(None)')
+ee('sys.stdout.writelines([1])')
+iter_test('sys.stdout.writelines(%s)')
+cb.append("> VimCommand")
+stringtochars_test('vim.command(%s)')
+ee('vim.command("", 2)')
+#! Not checked: vim->python exceptions translating: checked later
+cb.append("> VimToPython")
+#! Not checked: everything: needs errors in internal python functions
+cb.append("> VimEval")
+stringtochars_test('vim.eval(%s)')
+ee('vim.eval("", FailingTrue())')
+#! Not checked: everything: needs errors in internal python functions
+cb.append("> VimEvalPy")
+stringtochars_test('vim.bindeval(%s)')
+ee('vim.eval("", 2)')
+#! Not checked: vim->python exceptions translating: checked later
+cb.append("> VimStrwidth")
+stringtochars_test('vim.strwidth(%s)')
+cb.append("> VimForeachRTP")
+ee('vim.foreach_rtp(None)')
+ee('vim.foreach_rtp(NoArgsCall())')
+ee('vim.foreach_rtp(FailingCall())')
+ee('vim.foreach_rtp(int, 2)')
+cb.append('> import')
+old_rtp = vim.options['rtp']
+vim.options['rtp'] = os.getcwd().replace(',', '\\,').replace('\\', '\\\\')
+ee('import xxx_no_such_module_xxx')
+ee('import failing_import')
+ee('import failing')
+vim.options['rtp'] = old_rtp
+del old_rtp
+cb.append("> Options")
+cb.append(">> OptionsItem")
+ee('vim.options["abcQ"]')
+ee('vim.options[""]')
+stringtochars_test('vim.options[%s]')
+cb.append(">> OptionsContains")
+stringtochars_test('%s in vim.options')
+cb.append("> Dictionary")
+cb.append(">> DictionaryConstructor")
+ee('vim.Dictionary("abcI")')
+##! Not checked: py_dict_alloc failure
+cb.append(">> DictionarySetattr")
+ee('del d.locked')
+ee('d.locked = FailingTrue()')
+ee('vim.vvars.locked = False')
+ee('d.scope = True')
+ee('d.xxx = True')
+cb.append(">> _DictionaryItem")
+ee('d.get("a", 2, 3)')
+stringtochars_test('d.get(%s)')
+ee('d.pop("a")')
+ee('dl.pop("a")')
+cb.append(">> DictionaryContains")
+ee('"" in d')
+ee('0 in d')
+cb.append(">> DictionaryIterNext")
+ee('for i in ned: ned["a"] = 1')
+del i
+cb.append(">> DictionaryAssItem")
+ee('dl["b"] = 1')
+stringtochars_test('d[%s] = 1')
+convertfrompyobject_test('d["a"] = %s')
+cb.append(">> DictionaryUpdate")
+cb.append(">>> kwargs")
+cb.append(">>> iter")
+ee('d.update(FailingMapping())')
+ee('d.update([FailingIterNext()])')
+ee('d.update([FailingIterNextN(1)])')
+iter_test('d.update(%s)')
+convertfrompyobject_test('d.update(%s)')
+stringtochars_test('d.update(((%s, 0),))')
+convertfrompyobject_test('d.update((("a", %s),))')
+cb.append(">> DictionaryPopItem")
+ee('d.popitem(1, 2)')
+cb.append(">> DictionaryHasKey")
+ee('d.has_key()')
+cb.append("> List")
+cb.append(">> ListConstructor")
+ee('vim.List(1, 2)')
+ee('vim.List(a=1)')
+iter_test('vim.List(%s)')
+convertfrompyobject_test('vim.List([%s])')
+cb.append(">> ListItem")
+ee('l[1000]')
+cb.append(">> ListAssItem")
+ee('ll[1] = 2')
+ee('l[1000] = 3')
+cb.append(">> ListAssSlice")
+ee('ll[1:100] = "abcJ"')
+iter_test('l[:] = %s')
+ee('nel[1:10:2] = "abcK"')
+cb.append(repr(tuple(nel)))
+ee('nel[1:10:2] = "a"')
+cb.append(repr(tuple(nel)))
+ee('nel[1:1:-1] = "a"')
+cb.append(repr(tuple(nel)))
+ee('nel[:] = FailingIterNextN(2)')
+cb.append(repr(tuple(nel)))
+convertfrompyobject_test('l[:] = [%s]')
+cb.append(">> ListConcatInPlace")
+iter_test('l.extend(%s)')
+convertfrompyobject_test('l.extend([%s])')
+cb.append(">> ListSetattr")
+ee('del l.locked')
+ee('l.locked = FailingTrue()')
+ee('l.xxx = True')
+cb.append("> Function")
+cb.append(">> FunctionConstructor")
+ee('vim.Function("123")')
+ee('vim.Function("xxx_non_existent_function_xxx")')
+ee('vim.Function("xxx#non#existent#function#xxx")')
+cb.append(">> FunctionCall")
+convertfrompyobject_test('f(%s)')
+convertfrompymapping_test('fd(self=%s)')
+cb.append("> TabPage")
+cb.append(">> TabPageAttr")
+ee('vim.current.tabpage.xxx')
+cb.append("> TabList")
+cb.append(">> TabListItem")
+ee('vim.tabpages[1000]')
+cb.append("> Window")
+cb.append(">> WindowAttr")
+ee('vim.current.window.xxx')
+cb.append(">> WindowSetattr")
+ee('vim.current.window.buffer = 0')
+ee('vim.current.window.cursor = (100000000, 100000000)')
+ee('vim.current.window.cursor = True')
+number_test('vim.current.window.height = %s', unsigned=True)
+number_test('vim.current.window.width = %s', unsigned=True)
+ee('vim.current.window.xxxxxx = True')
+cb.append("> WinList")
+cb.append(">> WinListItem")
+ee('vim.windows[1000]')
+cb.append("> Buffer")
+cb.append(">> StringToLine (indirect)")
+ee('vim.current.buffer[0] = "\\na"')
+ee('vim.current.buffer[0] = b"\\na"')
+cb.append(">> SetBufferLine (indirect)")
+ee('vim.current.buffer[0] = True')
+cb.append(">> SetBufferLineList (indirect)")
+ee('vim.current.buffer[:] = True')
+ee('vim.current.buffer[:] = ["\\na", "bc"]')
+cb.append(">> InsertBufferLines (indirect)")
+ee('vim.current.buffer.append(None)')
+ee('vim.current.buffer.append(["\\na", "bc"])')
+ee('vim.current.buffer.append("\\nbc")')
+cb.append(">> RBItem")
+ee('vim.current.buffer[100000000]')
+cb.append(">> RBAsItem")
+ee('vim.current.buffer[100000000] = ""')
+cb.append(">> BufferAttr")
+ee('vim.current.buffer.xxx')
+cb.append(">> BufferSetattr")
+ee('vim.current.buffer.name = True')
+ee('vim.current.buffer.xxx = True')
+cb.append(">> BufferMark")
+ee('vim.current.buffer.mark(0)')
+ee('vim.current.buffer.mark("abcM")')
+ee('vim.current.buffer.mark("!")')
+cb.append(">> BufferRange")
+ee('vim.current.buffer.range(1, 2, 3)')
+cb.append("> BufMap")
+cb.append(">> BufMapItem")
+ee('vim.buffers[100000000]')
+number_test('vim.buffers[%s]', natural=True)
+cb.append("> Current")
+cb.append(">> CurrentGetattr")
+ee('vim.current.xxx')
+cb.append(">> CurrentSetattr")
+ee('vim.current.line = True')
+ee('vim.current.buffer = True')
+ee('vim.current.window = True')
+ee('vim.current.tabpage = True')
+ee('vim.current.xxx = True')
+del d
+del ned
+del dl
+del l
+del ll
+del nel
+del f
+del fd
+del fdel
+del subexpr_test
+del stringtochars_test
+del Mapping
+del convertfrompyobject_test
+del convertfrompymapping_test
+del iter_test
+del number_test
+del FailingTrue
+del FailingIter
+del FailingIterNext
+del FailingIterNextN
+del FailingMapping
+del FailingMappingKey
+del FailingList
+del NoArgsCall
+del FailingCall
+del FailingNumber
+EOF
+:delfunction F
+:"
+:" Test import
+py3 << EOF
+sys.path.insert(0, os.path.join(os.getcwd(), 'python_before'))
+sys.path.append(os.path.join(os.getcwd(), 'python_after'))
+vim.options['rtp'] = os.getcwd().replace(',', '\\,').replace('\\', '\\\\')
+l = []
+def callback(path):
+ l.append(os.path.relpath(path))
+vim.foreach_rtp(callback)
+cb.append(repr(l))
+del l
+def callback(path):
+ return os.path.relpath(path)
+cb.append(repr(vim.foreach_rtp(callback)))
+del callback
+from module import dir as d
+from modulex import ddir
+cb.append(d + ',' + ddir)
+import before
+cb.append(before.dir)
+import after
+cb.append(after.dir)
+import topmodule as tm
+import topmodule.submodule as tms
+import topmodule.submodule.subsubmodule.subsubsubmodule as tmsss
+cb.append(tm.__file__.replace(os.path.sep, '/')[-len('modulex/topmodule/__init__.py'):])
+cb.append(tms.__file__.replace(os.path.sep, '/')[-len('modulex/topmodule/submodule/__init__.py'):])
+cb.append(tmsss.__file__.replace(os.path.sep, '/')[-len('modulex/topmodule/submodule/subsubmodule/subsubsubmodule.py'):])
+del before
+del after
+del d
+del ddir
+del tm
+del tms
+del tmsss
+EOF
+:"
+:" Test exceptions
+:fun Exe(e)
+: execute a:e
+:endfun
+py3 << EOF
+Exe = vim.bindeval('function("Exe")')
+ee('vim.command("throw \'abcN\'")')
+ee('Exe("throw \'def\'")')
+ee('vim.eval("Exe(\'throw \'\'ghi\'\'\')")')
+ee('vim.eval("Exe(\'echoerr \'\'jkl\'\'\')")')
+ee('vim.eval("Exe(\'xxx_non_existent_command_xxx\')")')
+ee('vim.eval("xxx_unknown_function_xxx()")')
+ee('vim.bindeval("Exe(\'xxx_non_existent_command_xxx\')")')
+del Exe
+EOF
+:delfunction Exe
+:"
+:" Regression: interrupting vim.command propagates to next vim.command
+py3 << EOF
+def test_keyboard_interrupt():
+ try:
+ vim.command('while 1 | endwhile')
+ except KeyboardInterrupt:
+ cb.append('Caught KeyboardInterrupt')
+ except Exception as e:
+ cb.append('!!!!!!!! Caught exception: ' + repr(e))
+ else:
+ cb.append('!!!!!!!! No exception')
+ try:
+ vim.command('$ put =\'Running :put\'')
+ except KeyboardInterrupt:
+ cb.append('!!!!!!!! Caught KeyboardInterrupt')
+ except Exception as e:
+ cb.append('!!!!!!!! Caught exception: ' + repr(e))
+ else:
+ cb.append('No exception')
+EOF
+:debuggreedy
+:call inputsave()
+:call feedkeys("s\ns\ns\ns\nq\n")
+:redir => output
+:debug silent! py3 test_keyboard_interrupt()
+:redir END
+:0 debuggreedy
+:silent $put =output
+:unlet output
+:py3 del test_keyboard_interrupt
+:"
+:" Cleanup
+py3 << EOF
+del cb
+del ee
+del sys
+del os
+del vim
+EOF
+:endfun
+:"
+:fun RunTest()
+:let checkrefs = !empty($PYTHONDUMPREFS)
+:let start = getline(1, '$')
+:for i in range(checkrefs ? 10 : 1)
+: if i != 0
+: %d _
+: call setline(1, start)
+: endif
+: call Test()
+: if i == 0
+: let result = getline(1, '$')
+: endif
+:endfor
+:if checkrefs
+: %d _
+: call setline(1, result)
+:endif
+:endfun
+:"
+:call RunTest()
+:delfunction RunTest
+:delfunction Test
+:call garbagecollect(1)
+:"
+:/^start:/,$wq! test.out
+:" vim: et ts=4 isk-=\:
+:call getchar()
+ENDTEST
+
+start:
diff --git a/src/testdir/test87.ok b/src/testdir/test87.ok
new file mode 100644
index 0000000000..d1ec84c6b8
--- /dev/null
+++ b/src/testdir/test87.ok
@@ -0,0 +1,1266 @@
+start:
+[1, 'as''d', [1, 2, function('strlen'), {'a': 1}]]
+[1, 2, function('strlen'), {'a': 1}]
+Vim(put):E684:
+[0, 'as''d', [1, 2, function('strlen'), {'a': 1}]]
+[0, function('strlen'), [1, 2, function('strlen'), {'a': 1}]]
+1
+[b'-1', b'0', b'1', b'b', b'f']
+[-1, <vim.Function '1'>, <vim.dictionary object at >, <vim.list object at >, b'asd']
+[(b'-1', <vim.dictionary object at >), (b'0', -1), (b'1', b'asd'), (b'b', <vim.list object at >), (b'f', <vim.Function '1'>)]
+'-1' : {'a': 1}
+'0' : -1
+'1' : 'asd'
+'b' : [1, 2, function('strlen')]
+'f' : function('1')
+[0, function('strlen')]
+[3]
+[1, 2, function('strlen')]
+[1, 2, function('strlen')]
+1
+'asd'
+2
+True
+False
+True
+False
+[b'0']
+{'0': -1}
+(b'0', -1)
+None
+[]
+[0, 1, 2, 3]
+[0, 1, 2, 3]
+[0, 1, 3]
+[0, 1]
+[0, 1]
+[0, 1]
+[0, 1, 2, 3]
+[0, 1, 2, 3]
+[0, 2, 3]
+[2, 3]
+[2, 3]
+[2, 3]
+[1, 3]
+[0, 2]
+[0, 1, 2, 3]
+['a', 0, 1, 2, 3]
+[0, 'b', 2, 3]
+[0, 1, 'c']
+[0, 1, 2, 3, 'd']
+[0, 1, 2, 'e', 3]
+['f', 2, 3]
+[0, 1, 'g', 2, 3]
+['h']
+[0, 1, 10, 3, 20, 5, 6, 7]
+[0, 1, 2, 3, 20, 5, 10, 7]
+[0, 1, 2, 3, 4, 5, 6, 7]
+[0, 1, 2, 3, 4, 5, 6, 7]
+[0, 1, 2, 3, 4, 5, 6, 7]
+[0, 1, 2, 3]
+[function('New'), function('DictNew'), 'NewStart', 1, 2, 3, 'NewEnd']
+[function('New'), function('DictNew'), 'NewStart', 1, 2, 3, 'NewEnd', 'DictNewStart', 1, 2, 3, 'DictNewEnd', {'a': 'b'}]
+[function('New'), function('DictNew'), 'NewStart', 1, 2, 3, 'NewEnd', 'DictNewStart', 1, 2, 3, 'DictNewEnd', {'a': 'b'}, 'New']
+l[1](1, 2, 3):(<class 'vim.error'>, error('Vim:E725: Calling dict function without Dictionary: DictNew',))
+f(1, 2, 3):(<class 'vim.error'>, error('Vim:E117: Unknown function: New',))
+[0.0, 0.0]
+KeyError
+TypeError
+TypeError
+ValueError
+TypeError
+TypeError
+KeyError
+KeyError
+d : locked:0;scope:0
+dl : locked:1;scope:0
+v: : locked:2;scope:1
+g: : locked:0;scope:2
+d:{'abc2': 1}
+dl:{'def': 1}
+l : locked:0
+ll : locked:1
+l:[0]
+ll:[1]
+[0, 1, 2]
+['a', 'b']
+['c', 1]
+['d', ['e']]
+0.0
+"\0": Vim(let):E859:
+{"\0": 1}: Vim(let):E859:
+undefined_name: Vim(let):Trace
+vim: Vim(let):E859:
+[1]
+[1, 10, 11, 10, 11, 10, 11, 10, 11, 10, 11, 10, 1]
+[0, 1, 2, 3]
+[2, 3, 4, 5]
+[0, 1]
+[4, 5]
+[2, 3]
+[]
+[2, 3]
+[]
+[0, 1, 2, 3, 4, 5]
+[0, 1, 2, 3, 4, 5]
+[0, 1, 2, 3, 4, 5]
+[4, 3]
+[0, 2, 4]
+[]
+Abc
+bac
+def
+bar
+jkl
+wopts iters equal: 1
+bopts iters equal: 1
+>>> paste
+ g/w/b:1/0/0
+ g/w/b (in):1/0/0
+ p/gopts1: False
+ p/wopts1! KeyError
+ inv: 2! KeyError
+ wopts1! KeyError
+ wopts2! KeyError
+ wopts3! KeyError
+ p/bopts1! KeyError
+ inv: 2! KeyError
+ bopts1! KeyError
+ bopts2! KeyError
+ bopts3! KeyError
+ G: 1
+ W: 1:1 2:1 3:1 4:1
+ B: 1:1 2:1 3:1 4:1
+ del wopts3! KeyError
+ del bopts3! KeyError
+ G: 1
+ W: 1:1 2:1 3:1 4:1
+ B: 1:1 2:1 3:1 4:1
+>>> previewheight
+ g/w/b:1/0/0
+ g/w/b (in):1/0/0
+ p/gopts1: 12
+ inv: 'a'! TypeError
+ p/wopts1! KeyError
+ inv: 'a'! KeyError
+ wopts1! KeyError
+ wopts2! KeyError
+ wopts3! KeyError
+ p/bopts1! KeyError
+ inv: 'a'! KeyError
+ bopts1! KeyError
+ bopts2! KeyError
+ bopts3! KeyError
+ G: 5
+ W: 1:5 2:5 3:5 4:5
+ B: 1:5 2:5 3:5 4:5
+ del wopts3! KeyError
+ del bopts3! KeyError
+ G: 5
+ W: 1:5 2:5 3:5 4:5
+ B: 1:5 2:5 3:5 4:5
+>>> operatorfunc
+ g/w/b:1/0/0
+ g/w/b (in):1/0/0
+ p/gopts1: b''
+ inv: 2! TypeError
+ p/wopts1! KeyError
+ inv: 2! KeyError
+ wopts1! KeyError
+ wopts2! KeyError
+ wopts3! KeyError
+ p/bopts1! KeyError
+ inv: 2! KeyError
+ bopts1! KeyError
+ bopts2! KeyError
+ bopts3! KeyError
+ G: 'A'
+ W: 1:'A' 2:'A' 3:'A' 4:'A'
+ B: 1:'A' 2:'A' 3:'A' 4:'A'
+ del wopts3! KeyError
+ del bopts3! KeyError
+ G: 'A'
+ W: 1:'A' 2:'A' 3:'A' 4:'A'
+ B: 1:'A' 2:'A' 3:'A' 4:'A'
+>>> number
+ g/w/b:0/1/0
+ g/w/b (in):0/1/0
+ p/gopts1! KeyError
+ inv: 0! KeyError
+ gopts1! KeyError
+ p/wopts1: False
+ p/bopts1! KeyError
+ inv: 0! KeyError
+ bopts1! KeyError
+ bopts2! KeyError
+ bopts3! KeyError
+ G: 0
+ W: 1:1 2:1 3:0 4:0
+ B: 1:1 2:1 3:0 4:0
+ del wopts3! ValueError
+ del bopts3! KeyError
+ G: 0
+ W: 1:1 2:1 3:0 4:0
+ B: 1:1 2:1 3:0 4:0
+>>> numberwidth
+ g/w/b:0/1/0
+ g/w/b (in):0/1/0
+ p/gopts1! KeyError
+ inv: -100! KeyError
+ gopts1! KeyError
+ p/wopts1: 8
+ inv: -100! error
+ p/bopts1! KeyError
+ inv: -100! KeyError
+ bopts1! KeyError
+ bopts2! KeyError
+ bopts3! KeyError
+ G: 8
+ W: 1:3 2:5 3:2 4:8
+ B: 1:3 2:5 3:2 4:8
+ del wopts3! ValueError
+ del bopts3! KeyError
+ G: 8
+ W: 1:3 2:5 3:2 4:8
+ B: 1:3 2:5 3:2 4:8
+>>> colorcolumn
+ g/w/b:0/1/0
+ g/w/b (in):0/1/0
+ p/gopts1! KeyError
+ inv: 'abc4'! KeyError
+ gopts1! KeyError
+ p/wopts1: b''
+ inv: 'abc4'! error
+ p/bopts1! KeyError
+ inv: 'abc4'! KeyError
+ bopts1! KeyError
+ bopts2! KeyError
+ bopts3! KeyError
+ G: ''
+ W: 1:'+2' 2:'+3' 3:'+1' 4:''
+ B: 1:'+2' 2:'+3' 3:'+1' 4:''
+ del wopts3! ValueError
+ del bopts3! KeyError
+ G: ''
+ W: 1:'+2' 2:'+3' 3:'+1' 4:''
+ B: 1:'+2' 2:'+3' 3:'+1' 4:''
+>>> statusline
+ g/w/b:1/1/0
+ g/w/b (in):1/1/0
+ p/gopts1: b''
+ inv: 0! TypeError
+ p/wopts1: None
+ inv: 0! TypeError
+ p/bopts1! KeyError
+ inv: 0! KeyError
+ bopts1! KeyError
+ bopts2! KeyError
+ bopts3! KeyError
+ G: '1'
+ W: 1:'2' 2:'4' 3:'1' 4:'1'
+ B: 1:'2' 2:'4' 3:'1' 4:'1'
+ del bopts3! KeyError
+ G: '1'
+ W: 1:'2' 2:'1' 3:'1' 4:'1'
+ B: 1:'2' 2:'1' 3:'1' 4:'1'
+>>> autoindent
+ g/w/b:0/0/1
+ g/w/b (in):0/0/1
+ p/gopts1! KeyError
+ inv: 2! KeyError
+ gopts1! KeyError
+ p/wopts1! KeyError
+ inv: 2! KeyError
+ wopts1! KeyError
+ wopts2! KeyError
+ wopts3! KeyError
+ p/bopts1: False
+ G: 0
+ W: 1:0 2:1 3:0 4:1
+ B: 1:0 2:1 3:0 4:1
+ del wopts3! KeyError
+ del bopts3! ValueError
+ G: 0
+ W: 1:0 2:1 3:0 4:1
+ B: 1:0 2:1 3:0 4:1
+>>> shiftwidth
+ g/w/b:0/0/1
+ g/w/b (in):0/0/1
+ p/gopts1! KeyError
+ inv: 3! KeyError
+ gopts1! KeyError
+ p/wopts1! KeyError
+ inv: 3! KeyError
+ wopts1! KeyError
+ wopts2! KeyError
+ wopts3! KeyError
+ p/bopts1: 8
+ G: 8
+ W: 1:0 2:2 3:8 4:1
+ B: 1:0 2:2 3:8 4:1
+ del wopts3! KeyError
+ del bopts3! ValueError
+ G: 8
+ W: 1:0 2:2 3:8 4:1
+ B: 1:0 2:2 3:8 4:1
+>>> omnifunc
+ g/w/b:0/0/1
+ g/w/b (in):0/0/1
+ p/gopts1! KeyError
+ inv: 1! KeyError
+ gopts1! KeyError
+ p/wopts1! KeyError
+ inv: 1! KeyError
+ wopts1! KeyError
+ wopts2! KeyError
+ wopts3! KeyError
+ p/bopts1: b''
+ inv: 1! TypeError
+ G: ''
+ W: 1:'A' 2:'B' 3:'' 4:'C'
+ B: 1:'A' 2:'B' 3:'' 4:'C'
+ del wopts3! KeyError
+ del bopts3! ValueError
+ G: ''
+ W: 1:'A' 2:'B' 3:'' 4:'C'
+ B: 1:'A' 2:'B' 3:'' 4:'C'
+>>> preserveindent
+ g/w/b:0/0/1
+ g/w/b (in):0/0/1
+ p/gopts1! KeyError
+ inv: 2! KeyError
+ gopts1! KeyError
+ p/wopts1! KeyError
+ inv: 2! KeyError
+ wopts1! KeyError
+ wopts2! KeyError
+ wopts3! KeyError
+ p/bopts1: False
+ G: 0
+ W: 1:0 2:1 3:0 4:1
+ B: 1:0 2:1 3:0 4:1
+ del wopts3! KeyError
+ del bopts3! ValueError
+ G: 0
+ W: 1:0 2:1 3:0 4:1
+ B: 1:0 2:1 3:0 4:1
+>>> path
+ g/w/b:1/0/1
+ g/w/b (in):1/0/1
+ p/gopts1: b'.,..,,'
+ inv: 0! TypeError
+ p/wopts1! KeyError
+ inv: 0! KeyError
+ wopts1! KeyError
+ wopts2! KeyError
+ wopts3! KeyError
+ p/bopts1: None
+ inv: 0! TypeError
+ G: '.,,'
+ W: 1:'.,,' 2:',,' 3:'.,,' 4:'.'
+ B: 1:'.,,' 2:',,' 3:'.,,' 4:'.'
+ del wopts3! KeyError
+ G: '.,,'
+ W: 1:'.,,' 2:',,' 3:'.,,' 4:'.,,'
+ B: 1:'.,,' 2:',,' 3:'.,,' 4:'.,,'
+First line
+First line
+def
+First line
+Second line
+Third line
+(7, 2)
+<buffer test87.in><buffer >
+baz
+bar
+Second line
+Third line
+foo
+1:BufFilePre:1
+1:BufFilePost:1
+testdir/foo
+5:BufFilePre:5
+5:BufFilePost:5
+testdir/bar
+1:BufFilePre:1
+1:BufFilePost:1
+testdir/test87.in
+valid: b:False, cb:True
+i:<buffer test87.in>
+i2:<buffer test87.in>
+i:<buffer a>
+i3:<buffer test87.in>
+1:<buffer test87.in>=<buffer test87.in>
+8:<buffer a>=<buffer a>
+9:<buffer b>=<buffer b>
+10:<buffer c>=<buffer c>
+4
+i4:<buffer test87.in>
+i4:<buffer test87.in>
+StopIteration
+Number of tabs: 4
+Current tab pages:
+ <tabpage 0>(1): 1 windows, current is <window object (unknown)>
+ Windows:
+ <window object (unknown)>(1): displays buffer <buffer test87.in>; cursor is at (37, 0)
+ <tabpage 1>(2): 1 windows, current is <window object (unknown)>
+ Windows:
+ <window object (unknown)>(1): displays buffer <buffer 0>; cursor is at (1, 0)
+ <tabpage 2>(3): 2 windows, current is <window object (unknown)>
+ Windows:
+ <window object (unknown)>(1): displays buffer <buffer a.1>; cursor is at (1, 0)
+ <window object (unknown)>(2): displays buffer <buffer 1>; cursor is at (1, 0)
+ <tabpage 3>(4): 4 windows, current is <window 0>
+ Windows:
+ <window 0>(1): displays buffer <buffer c.2>; cursor is at (1, 0)
+ <window 1>(2): displays buffer <buffer b.2>; cursor is at (1, 0)
+ <window 2>(3): displays buffer <buffer a.2>; cursor is at (1, 0)
+ <window 3>(4): displays buffer <buffer 2>; cursor is at (1, 0)
+Number of windows in current tab page: 4
+Current tab page: <tabpage 3>
+Current window: <window 0>: <window 0> is <window 0>
+Current buffer: <buffer c.2>: <buffer c.2> is <buffer c.2> is <buffer c.2>
+ValueError at assigning foreign tab window
+Type error at assigning None to vim.current.window
+Type error at assigning None to vim.current.tabpage
+Type error at assigning None to vim.current.buffer
+Current tab page: <tabpage 2>
+Current window: <window 0>
+Current buffer: <buffer test87.in>
+Current line: 'Type error at assigning None to vim.current.buffer'
+w.valid: [True, False]
+t.valid: [True, False, True, False]
+vim.vars:Dictionary:True
+vim.options:Options:True
+vim.bindeval("{}"):Dictionary:True
+vim.bindeval("[]"):List:True
+vim.bindeval("function('tr')"):Function:True
+vim.current.buffer:Buffer:True
+vim.current.range:Range:True
+vim.current.window:Window:True
+vim.current.tabpage:TabPage:True
+current:__dir__,buffer,line,range,tabpage,window
+buffer:__dir__,append,mark,name,number,options,range,valid,vars
+window:__dir__,buffer,col,cursor,height,number,options,row,tabpage,valid,vars
+tabpage:__dir__,number,valid,vars,window,windows
+range:__dir__,append,end,start
+dictionary:__dir__,get,has_key,items,keys,locked,pop,popitem,scope,update,values
+list:__dir__,extend,locked
+function:__dir__,softspace
+output:__dir__,flush,softspace,write,writelines
+{}
+{'a': 1}
+{'a': 1}
+[]
+['a', 'b', 'c', '7']
+function('tr')
+'
+abcdef
+line :
+abcdef
+abcA
+line :
+abcB'
+['a', 'dup_a']
+['a', 'a']
+['a', 'b', 'c', 'C']
+[2, 2]
+[2, 2]
+1
+1
+function('Put')
+b'testdir'
+test87.in
+b'src'
+testdir/test87.in
+b'testdir'
+test87.in
+> Output
+>> OutputSetattr
+del sys.stdout.softspace:(<class 'AttributeError'>, AttributeError("can't delete OutputObject attributes",))
+>>> Testing NumberToLong using sys.stdout.softspace = %s
+sys.stdout.softspace = []:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got list',))
+sys.stdout.softspace = None:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got NoneType',))
+sys.stdout.softspace = -1:(<class 'ValueError'>, ValueError('number must be greater or equal to zero',))
+<<< Finished
+>>> Testing NumberToLong using sys.stderr.softspace = %s
+sys.stderr.softspace = []:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got list',))
+sys.stderr.softspace = None:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got NoneType',))
+sys.stderr.softspace = -1:(<class 'ValueError'>, ValueError('number must be greater or equal to zero',))
+<<< Finished
+sys.stdout.attr = None:(<class 'AttributeError'>, AttributeError('invalid attribute: attr',))
+>> OutputWrite
+sys.stdout.write(None):(<class 'TypeError'>, TypeError("Can't convert 'NoneType' object to str implicitly",))
+>> OutputWriteLines
+sys.stdout.writelines(None):(<class 'TypeError'>, TypeError("'NoneType' object is not iterable",))
+sys.stdout.writelines([1]):(<class 'TypeError'>, TypeError("Can't convert 'int' object to str implicitly",))
+>>> Testing *Iter* using sys.stdout.writelines(%s)
+sys.stdout.writelines(FailingIter()):(<class 'NotImplementedError'>, NotImplementedError('iter',))
+sys.stdout.writelines(FailingIterNext()):(<class 'NotImplementedError'>, NotImplementedError('next',))
+<<< Finished
+> VimCommand
+>>> Testing StringToChars using vim.command(%s)
+vim.command(1):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
+vim.command(b"\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+vim.command("\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+<<< Finished
+vim.command("", 2):(<class 'TypeError'>, TypeError('command() takes exactly one argument (2 given)',))
+> VimToPython
+> VimEval
+>>> Testing StringToChars using vim.eval(%s)
+vim.eval(1):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
+vim.eval(b"\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+vim.eval("\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+<<< Finished
+vim.eval("", FailingTrue()):(<class 'TypeError'>, TypeError('function takes exactly 1 argument (2 given)',))
+> VimEvalPy
+>>> Testing StringToChars using vim.bindeval(%s)
+vim.bindeval(1):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
+vim.bindeval(b"\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+vim.bindeval("\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+<<< Finished
+vim.eval("", 2):(<class 'TypeError'>, TypeError('function takes exactly 1 argument (2 given)',))
+> VimStrwidth
+>>> Testing StringToChars using vim.strwidth(%s)
+vim.strwidth(1):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
+vim.strwidth(b"\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+vim.strwidth("\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+<<< Finished
+> VimForeachRTP
+vim.foreach_rtp(None):(<class 'TypeError'>, TypeError("'NoneType' object is not callable",))
+vim.foreach_rtp(NoArgsCall()):(<class 'TypeError'>, TypeError('__call__() takes exactly 1 positional argument (2 given)',))
+vim.foreach_rtp(FailingCall()):(<class 'NotImplementedError'>, NotImplementedError('call',))
+vim.foreach_rtp(int, 2):(<class 'TypeError'>, TypeError('foreach_rtp() takes exactly one argument (2 given)',))
+> import
+import xxx_no_such_module_xxx:(<class 'ImportError'>, ImportError('No module named xxx_no_such_module_xxx',))
+import failing_import:(<class 'ImportError'>, ImportError('No module named failing_import',))
+import failing:(<class 'NotImplementedError'>, NotImplementedError())
+> Options
+>> OptionsItem
+vim.options["abcQ"]:(<class 'KeyError'>, KeyError('abcQ',))
+vim.options[""]:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
+>>> Testing StringToChars using vim.options[%s]
+vim.options[1]:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
+vim.options[b"\0"]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
+vim.options["\0"]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
+<<< Finished
+>> OptionsContains
+>>> Testing StringToChars using %s in vim.options
+1 in vim.options:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
+b"\0" in vim.options:(<class 'TypeError'>, TypeError('expected bytes with no null',))
+"\0" in vim.options:(<class 'TypeError'>, TypeError('expected bytes with no null',))
+<<< Finished
+> Dictionary
+>> DictionaryConstructor
+vim.Dictionary("abcI"):(<class 'ValueError'>, ValueError('expected sequence element of size 2, but got sequence of size 1',))
+>> DictionarySetattr
+del d.locked:(<class 'AttributeError'>, AttributeError('cannot delete vim.Dictionary attributes',))
+d.locked = FailingTrue():(<class 'NotImplementedError'>, NotImplementedError('bool',))
+vim.vvars.locked = False:(<class 'TypeError'>, TypeError('cannot modify fixed dictionary',))
+d.scope = True:(<class 'AttributeError'>, AttributeError('cannot set attribute scope',))
+d.xxx = True:(<class 'AttributeError'>, AttributeError('cannot set attribute xxx',))
+>> _DictionaryItem
+d.get("a", 2, 3):(<class 'TypeError'>, TypeError('function takes at most 2 arguments (3 given)',))
+>>> Testing StringToChars using d.get(%s)
+d.get(1):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
+d.get(b"\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+d.get("\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+<<< Finished
+d.pop("a"):(<class 'KeyError'>, KeyError('a',))
+dl.pop("a"):(<class 'vim.error'>, error('dictionary is locked',))
+>> DictionaryContains
+"" in d:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
+0 in d:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
+>> DictionaryIterNext
+for i in ned: ned["a"] = 1:(<class 'RuntimeError'>, RuntimeError('hashtab changed during iteration',))
+>> DictionaryAssItem
+dl["b"] = 1:(<class 'vim.error'>, error('dictionary is locked',))
+>>> Testing StringToChars using d[%s] = 1
+d[1] = 1:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
+d[b"\0"] = 1:(<class 'TypeError'>, TypeError('expected bytes with no null',))
+d["\0"] = 1:(<class 'TypeError'>, TypeError('expected bytes with no null',))
+<<< Finished
+>>> Testing StringToChars using d["a"] = {%s : 1}
+d["a"] = {1 : 1}:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
+d["a"] = {b"\0" : 1}:(<class 'TypeError'>, TypeError('expected bytes with no null',))
+d["a"] = {"\0" : 1}:(<class 'TypeError'>, TypeError('expected bytes with no null',))
+<<< Finished
+>>> Testing StringToChars using d["a"] = {"abcF" : {%s : 1}}
+d["a"] = {"abcF" : {1 : 1}}:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
+d["a"] = {"abcF" : {b"\0" : 1}}:(<class 'TypeError'>, TypeError('expected bytes with no null',))
+d["a"] = {"abcF" : {"\0" : 1}}:(<class 'TypeError'>, TypeError('expected bytes with no null',))
+<<< Finished
+>>> Testing StringToChars using d["a"] = {"abcF" : Mapping({%s : 1})}
+d["a"] = {"abcF" : Mapping({1 : 1})}:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
+d["a"] = {"abcF" : Mapping({b"\0" : 1})}:(<class 'TypeError'>, TypeError('expected bytes with no null',))
+d["a"] = {"abcF" : Mapping({"\0" : 1})}:(<class 'TypeError'>, TypeError('expected bytes with no null',))
+<<< Finished
+>>> Testing *Iter* using d["a"] = {"abcF" : %s}
+d["a"] = {"abcF" : FailingIter()}:(<class 'TypeError'>, TypeError('unable to convert FailingIter to vim structure',))
+d["a"] = {"abcF" : FailingIterNext()}:(<class 'NotImplementedError'>, NotImplementedError('next',))
+<<< Finished
+>>> Testing ConvertFromPyObject using d["a"] = {"abcF" : %s}
+d["a"] = {"abcF" : None}:(<class 'TypeError'>, TypeError('unable to convert NoneType to vim structure',))
+d["a"] = {"abcF" : {b"": 1}}:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
+d["a"] = {"abcF" : {"": 1}}:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
+d["a"] = {"abcF" : FailingMapping()}:(<class 'NotImplementedError'>, NotImplementedError('keys',))
+d["a"] = {"abcF" : FailingMappingKey()}:(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
+d["a"] = {"abcF" : FailingNumber()}:(<class 'NotImplementedError'>, NotImplementedError('int',))
+<<< Finished
+>>> Testing StringToChars using d["a"] = Mapping({%s : 1})
+d["a"] = Mapping({1 : 1}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
+d["a"] = Mapping({b"\0" : 1}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+d["a"] = Mapping({"\0" : 1}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+<<< Finished
+>>> Testing StringToChars using d["a"] = Mapping({"abcG" : {%s : 1}})
+d["a"] = Mapping({"abcG" : {1 : 1}}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
+d["a"] = Mapping({"abcG" : {b"\0" : 1}}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+d["a"] = Mapping({"abcG" : {"\0" : 1}}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+<<< Finished
+>>> Testing StringToChars using d["a"] = Mapping({"abcG" : Mapping({%s : 1})})
+d["a"] = Mapping({"abcG" : Mapping({1 : 1})}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
+d["a"] = Mapping({"abcG" : Mapping({b"\0" : 1})}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+d["a"] = Mapping({"abcG" : Mapping({"\0" : 1})}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+<<< Finished
+>>> Testing *Iter* using d["a"] = Mapping({"abcG" : %s})
+d["a"] = Mapping({"abcG" : FailingIter()}):(<class 'TypeError'>, TypeError('unable to convert FailingIter to vim structure',))
+d["a"] = Mapping({"abcG" : FailingIterNext()}):(<class 'NotImplementedError'>, NotImplementedError('next',))
+<<< Finished
+>>> Testing ConvertFromPyObject using d["a"] = Mapping({"abcG" : %s})
+d["a"] = Mapping({"abcG" : None}):(<class 'TypeError'>, TypeError('unable to convert NoneType to vim structure',))
+d["a"] = Mapping({"abcG" : {b"": 1}}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
+d["a"] = Mapping({"abcG" : {"": 1}}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
+d["a"] = Mapping({"abcG" : FailingMapping()}):(<class 'NotImplementedError'>, NotImplementedError('keys',))
+d["a"] = Mapping({"abcG" : FailingMappingKey()}):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
+d["a"] = Mapping({"abcG" : FailingNumber()}):(<class 'NotImplementedError'>, NotImplementedError('int',))
+<<< Finished
+>>> Testing *Iter* using d["a"] = %s
+d["a"] = FailingIter():(<class 'TypeError'>, TypeError('unable to convert FailingIter to vim structure',))
+d["a"] = FailingIterNext():(<class 'NotImplementedError'>, NotImplementedError('next',))
+<<< Finished
+>>> Testing ConvertFromPyObject using d["a"] = %s
+d["a"] = None:(<class 'TypeError'>, TypeError('unable to convert NoneType to vim structure',))
+d["a"] = {b"": 1}:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
+d["a"] = {"": 1}:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
+d["a"] = FailingMapping():(<class 'NotImplementedError'>, NotImplementedError('keys',))
+d["a"] = FailingMappingKey():(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
+d["a"] = FailingNumber():(<class 'NotImplementedError'>, NotImplementedError('int',))
+<<< Finished
+>> DictionaryUpdate
+>>> kwargs
+>>> iter
+d.update(FailingMapping()):(<class 'NotImplementedError'>, NotImplementedError('keys',))
+d.update([FailingIterNext()]):(<class 'NotImplementedError'>, NotImplementedError('next',))
+d.update([FailingIterNextN(1)]):(<class 'NotImplementedError'>, NotImplementedError('next N',))
+>>> Testing *Iter* using d.update(%s)
+d.update(FailingIter()):(<class 'NotImplementedError'>, NotImplementedError('iter',))
+d.update(FailingIterNext()):(<class 'NotImplementedError'>, NotImplementedError('next',))
+<<< Finished
+>>> Testing StringToChars using d.update({%s : 1})
+d.update({1 : 1}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
+d.update({b"\0" : 1}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+d.update({"\0" : 1}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+<<< Finished
+>>> Testing StringToChars using d.update({"abcF" : {%s : 1}})
+d.update({"abcF" : {1 : 1}}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
+d.update({"abcF" : {b"\0" : 1}}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+d.update({"abcF" : {"\0" : 1}}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+<<< Finished
+>>> Testing StringToChars using d.update({"abcF" : Mapping({%s : 1})})
+d.update({"abcF" : Mapping({1 : 1})}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
+d.update({"abcF" : Mapping({b"\0" : 1})}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+d.update({"abcF" : Mapping({"\0" : 1})}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+<<< Finished
+>>> Testing *Iter* using d.update({"abcF" : %s})
+d.update({"abcF" : FailingIter()}):(<class 'TypeError'>, TypeError('unable to convert FailingIter to vim structure',))
+d.update({"abcF" : FailingIterNext()}):(<class 'NotImplementedError'>, NotImplementedError('next',))
+<<< Finished
+>>> Testing ConvertFromPyObject using d.update({"abcF" : %s})
+d.update({"abcF" : None}):(<class 'TypeError'>, TypeError('unable to convert NoneType to vim structure',))
+d.update({"abcF" : {b"": 1}}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
+d.update({"abcF" : {"": 1}}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
+d.update({"abcF" : FailingMapping()}):(<class 'NotImplementedError'>, NotImplementedError('keys',))
+d.update({"abcF" : FailingMappingKey()}):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
+d.update({"abcF" : FailingNumber()}):(<class 'NotImplementedError'>, NotImplementedError('int',))
+<<< Finished
+>>> Testing StringToChars using d.update(Mapping({%s : 1}))
+d.update(Mapping({1 : 1})):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
+d.update(Mapping({b"\0" : 1})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+d.update(Mapping({"\0" : 1})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+<<< Finished
+>>> Testing StringToChars using d.update(Mapping({"abcG" : {%s : 1}}))
+d.update(Mapping({"abcG" : {1 : 1}})):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
+d.update(Mapping({"abcG" : {b"\0" : 1}})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+d.update(Mapping({"abcG" : {"\0" : 1}})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+<<< Finished
+>>> Testing StringToChars using d.update(Mapping({"abcG" : Mapping({%s : 1})}))
+d.update(Mapping({"abcG" : Mapping({1 : 1})})):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
+d.update(Mapping({"abcG" : Mapping({b"\0" : 1})})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+d.update(Mapping({"abcG" : Mapping({"\0" : 1})})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+<<< Finished
+>>> Testing *Iter* using d.update(Mapping({"abcG" : %s}))
+d.update(Mapping({"abcG" : FailingIter()})):(<class 'TypeError'>, TypeError('unable to convert FailingIter to vim structure',))
+d.update(Mapping({"abcG" : FailingIterNext()})):(<class 'NotImplementedError'>, NotImplementedError('next',))
+<<< Finished
+>>> Testing ConvertFromPyObject using d.update(Mapping({"abcG" : %s}))
+d.update(Mapping({"abcG" : None})):(<class 'TypeError'>, TypeError('unable to convert NoneType to vim structure',))
+d.update(Mapping({"abcG" : {b"": 1}})):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
+d.update(Mapping({"abcG" : {"": 1}})):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
+d.update(Mapping({"abcG" : FailingMapping()})):(<class 'NotImplementedError'>, NotImplementedError('keys',))
+d.update(Mapping({"abcG" : FailingMappingKey()})):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
+d.update(Mapping({"abcG" : FailingNumber()})):(<class 'NotImplementedError'>, NotImplementedError('int',))
+<<< Finished
+>>> Testing *Iter* using d.update(%s)
+d.update(FailingIter()):(<class 'NotImplementedError'>, NotImplementedError('iter',))
+d.update(FailingIterNext()):(<class 'NotImplementedError'>, NotImplementedError('next',))
+<<< Finished
+>>> Testing ConvertFromPyObject using d.update(%s)
+d.update(None):(<class 'TypeError'>, TypeError("'NoneType' object is not iterable",))
+d.update({b"": 1}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
+d.update({"": 1}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
+d.update(FailingMapping()):(<class 'NotImplementedError'>, NotImplementedError('keys',))
+d.update(FailingMappingKey()):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
+d.update(FailingNumber()):(<class 'TypeError'>, TypeError("'FailingNumber' object is not iterable",))
+<<< Finished
+>>> Testing StringToChars using d.update(((%s, 0),))
+d.update(((1, 0),)):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
+d.update(((b"\0", 0),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+d.update((("\0", 0),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+<<< Finished
+>>> Testing StringToChars using d.update((("a", {%s : 1}),))
+d.update((("a", {1 : 1}),)):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
+d.update((("a", {b"\0" : 1}),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+d.update((("a", {"\0" : 1}),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+<<< Finished
+>>> Testing StringToChars using d.update((("a", {"abcF" : {%s : 1}}),))
+d.update((("a", {"abcF" : {1 : 1}}),)):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
+d.update((("a", {"abcF" : {b"\0" : 1}}),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+d.update((("a", {"abcF" : {"\0" : 1}}),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+<<< Finished
+>>> Testing StringToChars using d.update((("a", {"abcF" : Mapping({%s : 1})}),))
+d.update((("a", {"abcF" : Mapping({1 : 1})}),)):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
+d.update((("a", {"abcF" : Mapping({b"\0" : 1})}),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+d.update((("a", {"abcF" : Mapping({"\0" : 1})}),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+<<< Finished
+>>> Testing *Iter* using d.update((("a", {"abcF" : %s}),))
+d.update((("a", {"abcF" : FailingIter()}),)):(<class 'TypeError'>, TypeError('unable to convert FailingIter to vim structure',))
+d.update((("a", {"abcF" : FailingIterNext()}),)):(<class 'NotImplementedError'>, NotImplementedError('next',))
+<<< Finished
+>>> Testing ConvertFromPyObject using d.update((("a", {"abcF" : %s}),))
+d.update((("a", {"abcF" : None}),)):(<class 'TypeError'>, TypeError('unable to convert NoneType to vim structure',))
+d.update((("a", {"abcF" : {b"": 1}}),)):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
+d.update((("a", {"abcF" : {"": 1}}),)):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
+d.update((("a", {"abcF" : FailingMapping()}),)):(<class 'NotImplementedError'>, NotImplementedError('keys',))
+d.update((("a", {"abcF" : FailingMappingKey()}),)):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
+d.update((("a", {"abcF" : FailingNumber()}),)):(<class 'NotImplementedError'>, NotImplementedError('int',))
+<<< Finished
+>>> Testing StringToChars using d.update((("a", Mapping({%s : 1})),))
+d.update((("a", Mapping({1 : 1})),)):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
+d.update((("a", Mapping({b"\0" : 1})),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+d.update((("a", Mapping({"\0" : 1})),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+<<< Finished
+>>> Testing StringToChars using d.update((("a", Mapping({"abcG" : {%s : 1}})),))
+d.update((("a", Mapping({"abcG" : {1 : 1}})),)):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
+d.update((("a", Mapping({"abcG" : {b"\0" : 1}})),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+d.update((("a", Mapping({"abcG" : {"\0" : 1}})),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+<<< Finished
+>>> Testing StringToChars using d.update((("a", Mapping({"abcG" : Mapping({%s : 1})})),))
+d.update((("a", Mapping({"abcG" : Mapping({1 : 1})})),)):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
+d.update((("a", Mapping({"abcG" : Mapping({b"\0" : 1})})),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+d.update((("a", Mapping({"abcG" : Mapping({"\0" : 1})})),)):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+<<< Finished
+>>> Testing *Iter* using d.update((("a", Mapping({"abcG" : %s})),))
+d.update((("a", Mapping({"abcG" : FailingIter()})),)):(<class 'TypeError'>, TypeError('unable to convert FailingIter to vim structure',))
+d.update((("a", Mapping({"abcG" : FailingIterNext()})),)):(<class 'NotImplementedError'>, NotImplementedError('next',))
+<<< Finished
+>>> Testing ConvertFromPyObject using d.update((("a", Mapping({"abcG" : %s})),))
+d.update((("a", Mapping({"abcG" : None})),)):(<class 'TypeError'>, TypeError('unable to convert NoneType to vim structure',))
+d.update((("a", Mapping({"abcG" : {b"": 1}})),)):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
+d.update((("a", Mapping({"abcG" : {"": 1}})),)):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
+d.update((("a", Mapping({"abcG" : FailingMapping()})),)):(<class 'NotImplementedError'>, NotImplementedError('keys',))
+d.update((("a", Mapping({"abcG" : FailingMappingKey()})),)):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
+d.update((("a", Mapping({"abcG" : FailingNumber()})),)):(<class 'NotImplementedError'>, NotImplementedError('int',))
+<<< Finished
+>>> Testing *Iter* using d.update((("a", %s),))
+d.update((("a", FailingIter()),)):(<class 'TypeError'>, TypeError('unable to convert FailingIter to vim structure',))
+d.update((("a", FailingIterNext()),)):(<class 'NotImplementedError'>, NotImplementedError('next',))
+<<< Finished
+>>> Testing ConvertFromPyObject using d.update((("a", %s),))
+d.update((("a", None),)):(<class 'TypeError'>, TypeError('unable to convert NoneType to vim structure',))
+d.update((("a", {b"": 1}),)):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
+d.update((("a", {"": 1}),)):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
+d.update((("a", FailingMapping()),)):(<class 'NotImplementedError'>, NotImplementedError('keys',))
+d.update((("a", FailingMappingKey()),)):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
+d.update((("a", FailingNumber()),)):(<class 'NotImplementedError'>, NotImplementedError('int',))
+<<< Finished
+>> DictionaryPopItem
+d.popitem(1, 2):(<class 'TypeError'>, TypeError('popitem() takes no arguments (2 given)',))
+>> DictionaryHasKey
+d.has_key():(<class 'TypeError'>, TypeError('has_key() takes exactly one argument (0 given)',))
+> List
+>> ListConstructor
+vim.List(1, 2):(<class 'TypeError'>, TypeError('function takes at most 1 argument (2 given)',))
+vim.List(a=1):(<class 'TypeError'>, TypeError('list constructor does not accept keyword arguments',))
+>>> Testing *Iter* using vim.List(%s)
+vim.List(FailingIter()):(<class 'NotImplementedError'>, NotImplementedError('iter',))
+vim.List(FailingIterNext()):(<class 'NotImplementedError'>, NotImplementedError('next',))
+<<< Finished
+>>> Testing StringToChars using vim.List([{%s : 1}])
+vim.List([{1 : 1}]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
+vim.List([{b"\0" : 1}]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+vim.List([{"\0" : 1}]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+<<< Finished
+>>> Testing StringToChars using vim.List([{"abcF" : {%s : 1}}])
+vim.List([{"abcF" : {1 : 1}}]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
+vim.List([{"abcF" : {b"\0" : 1}}]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+vim.List([{"abcF" : {"\0" : 1}}]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+<<< Finished
+>>> Testing StringToChars using vim.List([{"abcF" : Mapping({%s : 1})}])
+vim.List([{"abcF" : Mapping({1 : 1})}]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
+vim.List([{"abcF" : Mapping({b"\0" : 1})}]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+vim.List([{"abcF" : Mapping({"\0" : 1})}]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+<<< Finished
+>>> Testing *Iter* using vim.List([{"abcF" : %s}])
+vim.List([{"abcF" : FailingIter()}]):(<class 'TypeError'>, TypeError('unable to convert FailingIter to vim structure',))
+vim.List([{"abcF" : FailingIterNext()}]):(<class 'NotImplementedError'>, NotImplementedError('next',))
+<<< Finished
+>>> Testing ConvertFromPyObject using vim.List([{"abcF" : %s}])
+vim.List([{"abcF" : None}]):(<class 'TypeError'>, TypeError('unable to convert NoneType to vim structure',))
+vim.List([{"abcF" : {b"": 1}}]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
+vim.List([{"abcF" : {"": 1}}]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
+vim.List([{"abcF" : FailingMapping()}]):(<class 'NotImplementedError'>, NotImplementedError('keys',))
+vim.List([{"abcF" : FailingMappingKey()}]):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
+vim.List([{"abcF" : FailingNumber()}]):(<class 'NotImplementedError'>, NotImplementedError('int',))
+<<< Finished
+>>> Testing StringToChars using vim.List([Mapping({%s : 1})])
+vim.List([Mapping({1 : 1})]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
+vim.List([Mapping({b"\0" : 1})]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+vim.List([Mapping({"\0" : 1})]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+<<< Finished
+>>> Testing StringToChars using vim.List([Mapping({"abcG" : {%s : 1}})])
+vim.List([Mapping({"abcG" : {1 : 1}})]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
+vim.List([Mapping({"abcG" : {b"\0" : 1}})]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+vim.List([Mapping({"abcG" : {"\0" : 1}})]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+<<< Finished
+>>> Testing StringToChars using vim.List([Mapping({"abcG" : Mapping({%s : 1})})])
+vim.List([Mapping({"abcG" : Mapping({1 : 1})})]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
+vim.List([Mapping({"abcG" : Mapping({b"\0" : 1})})]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+vim.List([Mapping({"abcG" : Mapping({"\0" : 1})})]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+<<< Finished
+>>> Testing *Iter* using vim.List([Mapping({"abcG" : %s})])
+vim.List([Mapping({"abcG" : FailingIter()})]):(<class 'TypeError'>, TypeError('unable to convert FailingIter to vim structure',))
+vim.List([Mapping({"abcG" : FailingIterNext()})]):(<class 'NotImplementedError'>, NotImplementedError('next',))
+<<< Finished
+>>> Testing ConvertFromPyObject using vim.List([Mapping({"abcG" : %s})])
+vim.List([Mapping({"abcG" : None})]):(<class 'TypeError'>, TypeError('unable to convert NoneType to vim structure',))
+vim.List([Mapping({"abcG" : {b"": 1}})]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
+vim.List([Mapping({"abcG" : {"": 1}})]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
+vim.List([Mapping({"abcG" : FailingMapping()})]):(<class 'NotImplementedError'>, NotImplementedError('keys',))
+vim.List([Mapping({"abcG" : FailingMappingKey()})]):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
+vim.List([Mapping({"abcG" : FailingNumber()})]):(<class 'NotImplementedError'>, NotImplementedError('int',))
+<<< Finished
+>>> Testing *Iter* using vim.List([%s])
+vim.List([FailingIter()]):(<class 'TypeError'>, TypeError('unable to convert FailingIter to vim structure',))
+vim.List([FailingIterNext()]):(<class 'NotImplementedError'>, NotImplementedError('next',))
+<<< Finished
+>>> Testing ConvertFromPyObject using vim.List([%s])
+vim.List([None]):(<class 'TypeError'>, TypeError('unable to convert NoneType to vim structure',))
+vim.List([{b"": 1}]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
+vim.List([{"": 1}]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
+vim.List([FailingMapping()]):(<class 'NotImplementedError'>, NotImplementedError('keys',))
+vim.List([FailingMappingKey()]):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
+vim.List([FailingNumber()]):(<class 'NotImplementedError'>, NotImplementedError('int',))
+<<< Finished
+>> ListItem
+l[1000]:(<class 'IndexError'>, IndexError('list index out of range',))
+>> ListAssItem
+ll[1] = 2:(<class 'vim.error'>, error('list is locked',))
+l[1000] = 3:(<class 'IndexError'>, IndexError('list index out of range',))
+>> ListAssSlice
+ll[1:100] = "abcJ":(<class 'vim.error'>, error('list is locked',))
+>>> Testing *Iter* using l[:] = %s
+l[:] = FailingIter():(<class 'NotImplementedError'>, NotImplementedError('iter',))
+l[:] = FailingIterNext():(<class 'NotImplementedError'>, NotImplementedError('next',))
+<<< Finished
+nel[1:10:2] = "abcK":(<class 'ValueError'>, ValueError('attempt to assign sequence of size greater then 2 to extended slice',))
+(b'a', b'b', b'c', b'O')
+nel[1:10:2] = "a":(<class 'ValueError'>, ValueError('attempt to assign sequence of size 1 to extended slice of size 2',))
+(b'a', b'b', b'c', b'O')
+nel[1:1:-1] = "a":(<class 'ValueError'>, ValueError('attempt to assign sequence of size greater then 0 to extended slice',))
+(b'a', b'b', b'c', b'O')
+nel[:] = FailingIterNextN(2):(<class 'NotImplementedError'>, NotImplementedError('next N',))
+(b'a', b'b', b'c', b'O')
+>>> Testing StringToChars using l[:] = [{%s : 1}]
+l[:] = [{1 : 1}]:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
+l[:] = [{b"\0" : 1}]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
+l[:] = [{"\0" : 1}]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
+<<< Finished
+>>> Testing StringToChars using l[:] = [{"abcF" : {%s : 1}}]
+l[:] = [{"abcF" : {1 : 1}}]:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
+l[:] = [{"abcF" : {b"\0" : 1}}]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
+l[:] = [{"abcF" : {"\0" : 1}}]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
+<<< Finished
+>>> Testing StringToChars using l[:] = [{"abcF" : Mapping({%s : 1})}]
+l[:] = [{"abcF" : Mapping({1 : 1})}]:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
+l[:] = [{"abcF" : Mapping({b"\0" : 1})}]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
+l[:] = [{"abcF" : Mapping({"\0" : 1})}]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
+<<< Finished
+>>> Testing *Iter* using l[:] = [{"abcF" : %s}]
+l[:] = [{"abcF" : FailingIter()}]:(<class 'TypeError'>, TypeError('unable to convert FailingIter to vim structure',))
+l[:] = [{"abcF" : FailingIterNext()}]:(<class 'NotImplementedError'>, NotImplementedError('next',))
+<<< Finished
+>>> Testing ConvertFromPyObject using l[:] = [{"abcF" : %s}]
+l[:] = [{"abcF" : None}]:(<class 'TypeError'>, TypeError('unable to convert NoneType to vim structure',))
+l[:] = [{"abcF" : {b"": 1}}]:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
+l[:] = [{"abcF" : {"": 1}}]:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
+l[:] = [{"abcF" : FailingMapping()}]:(<class 'NotImplementedError'>, NotImplementedError('keys',))
+l[:] = [{"abcF" : FailingMappingKey()}]:(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
+l[:] = [{"abcF" : FailingNumber()}]:(<class 'NotImplementedError'>, NotImplementedError('int',))
+<<< Finished
+>>> Testing StringToChars using l[:] = [Mapping({%s : 1})]
+l[:] = [Mapping({1 : 1})]:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
+l[:] = [Mapping({b"\0" : 1})]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
+l[:] = [Mapping({"\0" : 1})]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
+<<< Finished
+>>> Testing StringToChars using l[:] = [Mapping({"abcG" : {%s : 1}})]
+l[:] = [Mapping({"abcG" : {1 : 1}})]:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
+l[:] = [Mapping({"abcG" : {b"\0" : 1}})]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
+l[:] = [Mapping({"abcG" : {"\0" : 1}})]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
+<<< Finished
+>>> Testing StringToChars using l[:] = [Mapping({"abcG" : Mapping({%s : 1})})]
+l[:] = [Mapping({"abcG" : Mapping({1 : 1})})]:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
+l[:] = [Mapping({"abcG" : Mapping({b"\0" : 1})})]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
+l[:] = [Mapping({"abcG" : Mapping({"\0" : 1})})]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
+<<< Finished
+>>> Testing *Iter* using l[:] = [Mapping({"abcG" : %s})]
+l[:] = [Mapping({"abcG" : FailingIter()})]:(<class 'TypeError'>, TypeError('unable to convert FailingIter to vim structure',))
+l[:] = [Mapping({"abcG" : FailingIterNext()})]:(<class 'NotImplementedError'>, NotImplementedError('next',))
+<<< Finished
+>>> Testing ConvertFromPyObject using l[:] = [Mapping({"abcG" : %s})]
+l[:] = [Mapping({"abcG" : None})]:(<class 'TypeError'>, TypeError('unable to convert NoneType to vim structure',))
+l[:] = [Mapping({"abcG" : {b"": 1}})]:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
+l[:] = [Mapping({"abcG" : {"": 1}})]:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
+l[:] = [Mapping({"abcG" : FailingMapping()})]:(<class 'NotImplementedError'>, NotImplementedError('keys',))
+l[:] = [Mapping({"abcG" : FailingMappingKey()})]:(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
+l[:] = [Mapping({"abcG" : FailingNumber()})]:(<class 'NotImplementedError'>, NotImplementedError('int',))
+<<< Finished
+>>> Testing *Iter* using l[:] = [%s]
+l[:] = [FailingIter()]:(<class 'TypeError'>, TypeError('unable to convert FailingIter to vim structure',))
+l[:] = [FailingIterNext()]:(<class 'NotImplementedError'>, NotImplementedError('next',))
+<<< Finished
+>>> Testing ConvertFromPyObject using l[:] = [%s]
+l[:] = [None]:(<class 'TypeError'>, TypeError('unable to convert NoneType to vim structure',))
+l[:] = [{b"": 1}]:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
+l[:] = [{"": 1}]:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
+l[:] = [FailingMapping()]:(<class 'NotImplementedError'>, NotImplementedError('keys',))
+l[:] = [FailingMappingKey()]:(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
+l[:] = [FailingNumber()]:(<class 'NotImplementedError'>, NotImplementedError('int',))
+<<< Finished
+>> ListConcatInPlace
+>>> Testing *Iter* using l.extend(%s)
+l.extend(FailingIter()):(<class 'NotImplementedError'>, NotImplementedError('iter',))
+l.extend(FailingIterNext()):(<class 'NotImplementedError'>, NotImplementedError('next',))
+<<< Finished
+>>> Testing StringToChars using l.extend([{%s : 1}])
+l.extend([{1 : 1}]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
+l.extend([{b"\0" : 1}]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+l.extend([{"\0" : 1}]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+<<< Finished
+>>> Testing StringToChars using l.extend([{"abcF" : {%s : 1}}])
+l.extend([{"abcF" : {1 : 1}}]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
+l.extend([{"abcF" : {b"\0" : 1}}]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+l.extend([{"abcF" : {"\0" : 1}}]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+<<< Finished
+>>> Testing StringToChars using l.extend([{"abcF" : Mapping({%s : 1})}])
+l.extend([{"abcF" : Mapping({1 : 1})}]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
+l.extend([{"abcF" : Mapping({b"\0" : 1})}]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+l.extend([{"abcF" : Mapping({"\0" : 1})}]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+<<< Finished
+>>> Testing *Iter* using l.extend([{"abcF" : %s}])
+l.extend([{"abcF" : FailingIter()}]):(<class 'TypeError'>, TypeError('unable to convert FailingIter to vim structure',))
+l.extend([{"abcF" : FailingIterNext()}]):(<class 'NotImplementedError'>, NotImplementedError('next',))
+<<< Finished
+>>> Testing ConvertFromPyObject using l.extend([{"abcF" : %s}])
+l.extend([{"abcF" : None}]):(<class 'TypeError'>, TypeError('unable to convert NoneType to vim structure',))
+l.extend([{"abcF" : {b"": 1}}]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
+l.extend([{"abcF" : {"": 1}}]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
+l.extend([{"abcF" : FailingMapping()}]):(<class 'NotImplementedError'>, NotImplementedError('keys',))
+l.extend([{"abcF" : FailingMappingKey()}]):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
+l.extend([{"abcF" : FailingNumber()}]):(<class 'NotImplementedError'>, NotImplementedError('int',))
+<<< Finished
+>>> Testing StringToChars using l.extend([Mapping({%s : 1})])
+l.extend([Mapping({1 : 1})]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
+l.extend([Mapping({b"\0" : 1})]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+l.extend([Mapping({"\0" : 1})]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+<<< Finished
+>>> Testing StringToChars using l.extend([Mapping({"abcG" : {%s : 1}})])
+l.extend([Mapping({"abcG" : {1 : 1}})]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
+l.extend([Mapping({"abcG" : {b"\0" : 1}})]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+l.extend([Mapping({"abcG" : {"\0" : 1}})]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+<<< Finished
+>>> Testing StringToChars using l.extend([Mapping({"abcG" : Mapping({%s : 1})})])
+l.extend([Mapping({"abcG" : Mapping({1 : 1})})]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
+l.extend([Mapping({"abcG" : Mapping({b"\0" : 1})})]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+l.extend([Mapping({"abcG" : Mapping({"\0" : 1})})]):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+<<< Finished
+>>> Testing *Iter* using l.extend([Mapping({"abcG" : %s})])
+l.extend([Mapping({"abcG" : FailingIter()})]):(<class 'TypeError'>, TypeError('unable to convert FailingIter to vim structure',))
+l.extend([Mapping({"abcG" : FailingIterNext()})]):(<class 'NotImplementedError'>, NotImplementedError('next',))
+<<< Finished
+>>> Testing ConvertFromPyObject using l.extend([Mapping({"abcG" : %s})])
+l.extend([Mapping({"abcG" : None})]):(<class 'TypeError'>, TypeError('unable to convert NoneType to vim structure',))
+l.extend([Mapping({"abcG" : {b"": 1}})]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
+l.extend([Mapping({"abcG" : {"": 1}})]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
+l.extend([Mapping({"abcG" : FailingMapping()})]):(<class 'NotImplementedError'>, NotImplementedError('keys',))
+l.extend([Mapping({"abcG" : FailingMappingKey()})]):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
+l.extend([Mapping({"abcG" : FailingNumber()})]):(<class 'NotImplementedError'>, NotImplementedError('int',))
+<<< Finished
+>>> Testing *Iter* using l.extend([%s])
+l.extend([FailingIter()]):(<class 'TypeError'>, TypeError('unable to convert FailingIter to vim structure',))
+l.extend([FailingIterNext()]):(<class 'NotImplementedError'>, NotImplementedError('next',))
+<<< Finished
+>>> Testing ConvertFromPyObject using l.extend([%s])
+l.extend([None]):(<class 'TypeError'>, TypeError('unable to convert NoneType to vim structure',))
+l.extend([{b"": 1}]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
+l.extend([{"": 1}]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
+l.extend([FailingMapping()]):(<class 'NotImplementedError'>, NotImplementedError('keys',))
+l.extend([FailingMappingKey()]):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
+l.extend([FailingNumber()]):(<class 'NotImplementedError'>, NotImplementedError('int',))
+<<< Finished
+>> ListSetattr
+del l.locked:(<class 'AttributeError'>, AttributeError('cannot delete vim.List attributes',))
+l.locked = FailingTrue():(<class 'NotImplementedError'>, NotImplementedError('bool',))
+l.xxx = True:(<class 'AttributeError'>, AttributeError('cannot set attribute xxx',))
+> Function
+>> FunctionConstructor
+vim.Function("123"):(<class 'ValueError'>, ValueError('unnamed function 123 does not exist',))
+vim.Function("xxx_non_existent_function_xxx"):(<class 'ValueError'>, ValueError('function xxx_non_existent_function_xxx does not exist',))
+vim.Function("xxx#non#existent#function#xxx"):NOT FAILED
+>> FunctionCall
+>>> Testing StringToChars using f({%s : 1})
+f({1 : 1}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
+f({b"\0" : 1}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+f({"\0" : 1}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+<<< Finished
+>>> Testing StringToChars using f({"abcF" : {%s : 1}})
+f({"abcF" : {1 : 1}}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
+f({"abcF" : {b"\0" : 1}}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+f({"abcF" : {"\0" : 1}}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+<<< Finished
+>>> Testing StringToChars using f({"abcF" : Mapping({%s : 1})})
+f({"abcF" : Mapping({1 : 1})}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
+f({"abcF" : Mapping({b"\0" : 1})}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+f({"abcF" : Mapping({"\0" : 1})}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+<<< Finished
+>>> Testing *Iter* using f({"abcF" : %s})
+f({"abcF" : FailingIter()}):(<class 'TypeError'>, TypeError('unable to convert FailingIter to vim structure',))
+f({"abcF" : FailingIterNext()}):(<class 'NotImplementedError'>, NotImplementedError('next',))
+<<< Finished
+>>> Testing ConvertFromPyObject using f({"abcF" : %s})
+f({"abcF" : None}):(<class 'TypeError'>, TypeError('unable to convert NoneType to vim structure',))
+f({"abcF" : {b"": 1}}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
+f({"abcF" : {"": 1}}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
+f({"abcF" : FailingMapping()}):(<class 'NotImplementedError'>, NotImplementedError('keys',))
+f({"abcF" : FailingMappingKey()}):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
+f({"abcF" : FailingNumber()}):(<class 'NotImplementedError'>, NotImplementedError('int',))
+<<< Finished
+>>> Testing StringToChars using f(Mapping({%s : 1}))
+f(Mapping({1 : 1})):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
+f(Mapping({b"\0" : 1})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+f(Mapping({"\0" : 1})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+<<< Finished
+>>> Testing StringToChars using f(Mapping({"abcG" : {%s : 1}}))
+f(Mapping({"abcG" : {1 : 1}})):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
+f(Mapping({"abcG" : {b"\0" : 1}})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+f(Mapping({"abcG" : {"\0" : 1}})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+<<< Finished
+>>> Testing StringToChars using f(Mapping({"abcG" : Mapping({%s : 1})}))
+f(Mapping({"abcG" : Mapping({1 : 1})})):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
+f(Mapping({"abcG" : Mapping({b"\0" : 1})})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+f(Mapping({"abcG" : Mapping({"\0" : 1})})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+<<< Finished
+>>> Testing *Iter* using f(Mapping({"abcG" : %s}))
+f(Mapping({"abcG" : FailingIter()})):(<class 'TypeError'>, TypeError('unable to convert FailingIter to vim structure',))
+f(Mapping({"abcG" : FailingIterNext()})):(<class 'NotImplementedError'>, NotImplementedError('next',))
+<<< Finished
+>>> Testing ConvertFromPyObject using f(Mapping({"abcG" : %s}))
+f(Mapping({"abcG" : None})):(<class 'TypeError'>, TypeError('unable to convert NoneType to vim structure',))
+f(Mapping({"abcG" : {b"": 1}})):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
+f(Mapping({"abcG" : {"": 1}})):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
+f(Mapping({"abcG" : FailingMapping()})):(<class 'NotImplementedError'>, NotImplementedError('keys',))
+f(Mapping({"abcG" : FailingMappingKey()})):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
+f(Mapping({"abcG" : FailingNumber()})):(<class 'NotImplementedError'>, NotImplementedError('int',))
+<<< Finished
+>>> Testing *Iter* using f(%s)
+f(FailingIter()):(<class 'TypeError'>, TypeError('unable to convert FailingIter to vim structure',))
+f(FailingIterNext()):(<class 'NotImplementedError'>, NotImplementedError('next',))
+<<< Finished
+>>> Testing ConvertFromPyObject using f(%s)
+f(None):(<class 'TypeError'>, TypeError('unable to convert NoneType to vim structure',))
+f({b"": 1}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
+f({"": 1}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
+f(FailingMapping()):(<class 'NotImplementedError'>, NotImplementedError('keys',))
+f(FailingMappingKey()):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
+f(FailingNumber()):(<class 'NotImplementedError'>, NotImplementedError('int',))
+<<< Finished
+>>> Testing StringToChars using fd(self={%s : 1})
+fd(self={1 : 1}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
+fd(self={b"\0" : 1}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+fd(self={"\0" : 1}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+<<< Finished
+>>> Testing StringToChars using fd(self={"abcF" : {%s : 1}})
+fd(self={"abcF" : {1 : 1}}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
+fd(self={"abcF" : {b"\0" : 1}}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+fd(self={"abcF" : {"\0" : 1}}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+<<< Finished
+>>> Testing StringToChars using fd(self={"abcF" : Mapping({%s : 1})})
+fd(self={"abcF" : Mapping({1 : 1})}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
+fd(self={"abcF" : Mapping({b"\0" : 1})}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+fd(self={"abcF" : Mapping({"\0" : 1})}):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+<<< Finished
+>>> Testing *Iter* using fd(self={"abcF" : %s})
+fd(self={"abcF" : FailingIter()}):(<class 'TypeError'>, TypeError('unable to convert FailingIter to vim structure',))
+fd(self={"abcF" : FailingIterNext()}):(<class 'NotImplementedError'>, NotImplementedError('next',))
+<<< Finished
+>>> Testing ConvertFromPyObject using fd(self={"abcF" : %s})
+fd(self={"abcF" : None}):(<class 'TypeError'>, TypeError('unable to convert NoneType to vim structure',))
+fd(self={"abcF" : {b"": 1}}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
+fd(self={"abcF" : {"": 1}}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
+fd(self={"abcF" : FailingMapping()}):(<class 'NotImplementedError'>, NotImplementedError('keys',))
+fd(self={"abcF" : FailingMappingKey()}):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
+fd(self={"abcF" : FailingNumber()}):(<class 'NotImplementedError'>, NotImplementedError('int',))
+<<< Finished
+>>> Testing StringToChars using fd(self=Mapping({%s : 1}))
+fd(self=Mapping({1 : 1})):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
+fd(self=Mapping({b"\0" : 1})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+fd(self=Mapping({"\0" : 1})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+<<< Finished
+>>> Testing StringToChars using fd(self=Mapping({"abcG" : {%s : 1}}))
+fd(self=Mapping({"abcG" : {1 : 1}})):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
+fd(self=Mapping({"abcG" : {b"\0" : 1}})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+fd(self=Mapping({"abcG" : {"\0" : 1}})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+<<< Finished
+>>> Testing StringToChars using fd(self=Mapping({"abcG" : Mapping({%s : 1})}))
+fd(self=Mapping({"abcG" : Mapping({1 : 1})})):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
+fd(self=Mapping({"abcG" : Mapping({b"\0" : 1})})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+fd(self=Mapping({"abcG" : Mapping({"\0" : 1})})):(<class 'TypeError'>, TypeError('expected bytes with no null',))
+<<< Finished
+>>> Testing *Iter* using fd(self=Mapping({"abcG" : %s}))
+fd(self=Mapping({"abcG" : FailingIter()})):(<class 'TypeError'>, TypeError('unable to convert FailingIter to vim structure',))
+fd(self=Mapping({"abcG" : FailingIterNext()})):(<class 'NotImplementedError'>, NotImplementedError('next',))
+<<< Finished
+>>> Testing ConvertFromPyObject using fd(self=Mapping({"abcG" : %s}))
+fd(self=Mapping({"abcG" : None})):(<class 'TypeError'>, TypeError('unable to convert NoneType to vim structure',))
+fd(self=Mapping({"abcG" : {b"": 1}})):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
+fd(self=Mapping({"abcG" : {"": 1}})):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
+fd(self=Mapping({"abcG" : FailingMapping()})):(<class 'NotImplementedError'>, NotImplementedError('keys',))
+fd(self=Mapping({"abcG" : FailingMappingKey()})):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
+fd(self=Mapping({"abcG" : FailingNumber()})):(<class 'NotImplementedError'>, NotImplementedError('int',))
+<<< Finished
+>>> Testing *Iter* using fd(self=%s)
+fd(self=FailingIter()):(<class 'TypeError'>, TypeError('unable to convert FailingIter to vim dictionary',))
+fd(self=FailingIterNext()):(<class 'TypeError'>, TypeError('unable to convert FailingIterNext to vim dictionary',))
+<<< Finished
+>>> Testing ConvertFromPyObject using fd(self=%s)
+fd(self=None):(<class 'TypeError'>, TypeError('unable to convert NoneType to vim dictionary',))
+fd(self={b"": 1}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
+fd(self={"": 1}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
+fd(self=FailingMapping()):(<class 'NotImplementedError'>, NotImplementedError('keys',))
+fd(self=FailingMappingKey()):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
+fd(self=FailingNumber()):(<class 'TypeError'>, TypeError('unable to convert FailingNumber to vim dictionary',))
+<<< Finished
+>>> Testing ConvertFromPyMapping using fd(self=%s)
+fd(self=[]):(<class 'AttributeError'>, AttributeError('keys',))
+<<< Finished
+> TabPage
+>> TabPageAttr
+vim.current.tabpage.xxx:(<class 'AttributeError'>, AttributeError("'vim.tabpage' object has no attribute 'xxx'",))
+> TabList
+>> TabListItem
+vim.tabpages[1000]:(<class 'IndexError'>, IndexError('no such tab page',))
+> Window
+>> WindowAttr
+vim.current.window.xxx:(<class 'AttributeError'>, AttributeError("'vim.window' object has no attribute 'xxx'",))
+>> WindowSetattr
+vim.current.window.buffer = 0:(<class 'TypeError'>, TypeError('readonly attribute: buffer',))
+vim.current.window.cursor = (100000000, 100000000):(<class 'vim.error'>, error('cursor position outside buffer',))
+vim.current.window.cursor = True:(<class 'TypeError'>, TypeError('argument must be 2-item sequence, not bool',))
+>>> Testing NumberToLong using vim.current.window.height = %s
+vim.current.window.height = []:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got list',))
+vim.current.window.height = None:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got NoneType',))
+vim.current.window.height = -1:(<class 'ValueError'>, ValueError('number must be greater or equal to zero',))
+<<< Finished
+>>> Testing NumberToLong using vim.current.window.width = %s
+vim.current.window.width = []:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got list',))
+vim.current.window.width = None:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got NoneType',))
+vim.current.window.width = -1:(<class 'ValueError'>, ValueError('number must be greater or equal to zero',))
+<<< Finished
+vim.current.window.xxxxxx = True:(<class 'AttributeError'>, AttributeError('xxxxxx',))
+> WinList
+>> WinListItem
+vim.windows[1000]:(<class 'IndexError'>, IndexError('no such window',))
+> Buffer
+>> StringToLine (indirect)
+vim.current.buffer[0] = "\na":(<class 'vim.error'>, error('string cannot contain newlines',))
+vim.current.buffer[0] = b"\na":(<class 'vim.error'>, error('string cannot contain newlines',))
+>> SetBufferLine (indirect)
+vim.current.buffer[0] = True:(<class 'TypeError'>, TypeError('bad argument type for built-in operation',))
+>> SetBufferLineList (indirect)
+vim.current.buffer[:] = True:(<class 'TypeError'>, TypeError('bad argument type for built-in operation',))
+vim.current.buffer[:] = ["\na", "bc"]:(<class 'vim.error'>, error('string cannot contain newlines',))
+>> InsertBufferLines (indirect)
+vim.current.buffer.append(None):(<class 'TypeError'>, TypeError('bad argument type for built-in operation',))
+vim.current.buffer.append(["\na", "bc"]):(<class 'vim.error'>, error('string cannot contain newlines',))
+vim.current.buffer.append("\nbc"):(<class 'vim.error'>, error('string cannot contain newlines',))
+>> RBItem
+vim.current.buffer[100000000]:(<class 'IndexError'>, IndexError('line number out of range',))
+>> RBAsItem
+vim.current.buffer[100000000] = "":(<class 'IndexError'>, IndexError('line number out of range',))
+>> BufferAttr
+vim.current.buffer.xxx:(<class 'AttributeError'>, AttributeError("'vim.buffer' object has no attribute 'xxx'",))
+>> BufferSetattr
+vim.current.buffer.name = True:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got bool',))
+vim.current.buffer.xxx = True:(<class 'AttributeError'>, AttributeError('xxx',))
+>> BufferMark
+vim.current.buffer.mark(0):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
+vim.current.buffer.mark("abcM"):(<class 'ValueError'>, ValueError('mark name must be a single character',))
+vim.current.buffer.mark("!"):(<class 'vim.error'>, error('invalid mark name',))
+>> BufferRange
+vim.current.buffer.range(1, 2, 3):(<class 'TypeError'>, TypeError('function takes exactly 2 arguments (3 given)',))
+> BufMap
+>> BufMapItem
+vim.buffers[100000000]:(<class 'KeyError'>, KeyError(100000000,))
+>>> Testing NumberToLong using vim.buffers[%s]
+vim.buffers[[]]:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got list',))
+vim.buffers[None]:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got NoneType',))
+vim.buffers[-1]:(<class 'ValueError'>, ValueError('number must be greater then zero',))
+vim.buffers[0]:(<class 'ValueError'>, ValueError('number must be greater then zero',))
+<<< Finished
+> Current
+>> CurrentGetattr
+vim.current.xxx:(<class 'AttributeError'>, AttributeError("'vim.currentdata' object has no attribute 'xxx'",))
+>> CurrentSetattr
+vim.current.line = True:(<class 'TypeError'>, TypeError('bad argument type for built-in operation',))
+vim.current.buffer = True:(<class 'TypeError'>, TypeError('expected vim.Buffer object, but got bool',))
+vim.current.window = True:(<class 'TypeError'>, TypeError('expected vim.Window object, but got bool',))
+vim.current.tabpage = True:(<class 'TypeError'>, TypeError('expected vim.TabPage object, but got bool',))
+vim.current.xxx = True:(<class 'AttributeError'>, AttributeError('xxx',))
+['.']
+'.'
+3,xx
+before
+after
+pythonx/topmodule/__init__.py
+pythonx/topmodule/submodule/__init__.py
+pythonx/topmodule/submodule/subsubmodule/subsubsubmodule.py
+vim.command("throw 'abcN'"):(<class 'vim.error'>, error('abcN',))
+Exe("throw 'def'"):(<class 'vim.error'>, error('def',))
+vim.eval("Exe('throw ''ghi''')"):(<class 'vim.error'>, error('ghi',))
+vim.eval("Exe('echoerr ''jkl''')"):(<class 'vim.error'>, error('Vim(echoerr):jkl',))
+vim.eval("Exe('xxx_non_existent_command_xxx')"):(<class 'vim.error'>, error('Vim:E492: Not an editor command: xxx_non_existent_command_xxx',))
+vim.eval("xxx_unknown_function_xxx()"):(<class 'vim.error'>, error('Vim:E117: Unknown function: xxx_unknown_function_xxx',))
+vim.bindeval("Exe('xxx_non_existent_command_xxx')"):(<class 'vim.error'>, error('Vim:E492: Not an editor command: xxx_non_existent_command_xxx',))
+Caught KeyboardInterrupt
+Running :put
+No exception
+
diff --git a/src/testdir/test88.in b/src/testdir/test88.in
new file mode 100644
index 0000000000..c2e6a752fa
--- /dev/null
+++ b/src/testdir/test88.in
@@ -0,0 +1,88 @@
+vim: set ft=vim
+
+Tests for correct display (cursor column position) with +conceal and
+tabulators.
+
+STARTTEST
+:so small.vim
+:if !has('conceal')
+ e! test.ok
+ wq! test.out
+:endif
+:" Conceal settings.
+:set conceallevel=2
+:set concealcursor=nc
+:syntax match test /|/ conceal
+:" Save current cursor position. Only works in <expr> mode, can't be used
+:" with :normal because it moves the cursor to the command line. Thanks to ZyX
+:" <zyx.vim@gmail.com> for the idea to use an <expr> mapping.
+:let positions = []
+:nnoremap <expr> GG ":let positions += ['".screenrow().":".screencol()."']\n"
+:" Start test.
+/^start:
+:normal ztj
+GGk
+:" We should end up in the same column when running these commands on the two
+:" lines.
+:normal ft
+GGk
+:normal $
+GGk
+:normal 0j
+GGk
+:normal ft
+GGk
+:normal $
+GGk
+:normal 0j0j
+GGk
+:" Same for next test block.
+:normal ft
+GGk
+:normal $
+GGk
+:normal 0j
+GGk
+:normal ft
+GGk
+:normal $
+GGk
+:normal 0j0j
+GGk
+:" And check W with multiple tabs and conceals in a line.
+:normal W
+GGk
+:normal W
+GGk
+:normal W
+GGk
+:normal $
+GGk
+:normal 0j
+GGk
+:normal W
+GGk
+:normal W
+GGk
+:normal W
+GGk
+:normal $
+GGk
+:set lbr
+:normal $
+GGk
+:" Display result.
+:call append('$', 'end:')
+:call append('$', positions)
+:/^end/,$wq! test.out
+ENDTEST
+
+start:
+.concealed. text
+|concealed| text
+
+ .concealed. text
+ |concealed| text
+
+.a. .b. .c. .d.
+|a| |b| |c| |d|
diff --git a/src/testdir/test88.ok b/src/testdir/test88.ok
new file mode 100644
index 0000000000..e29698b7bd
--- /dev/null
+++ b/src/testdir/test88.ok
@@ -0,0 +1,24 @@
+end:
+2:1
+2:17
+2:20
+3:1
+3:17
+3:20
+5:8
+5:25
+5:28
+6:8
+6:25
+6:28
+8:1
+8:9
+8:17
+8:25
+8:27
+9:1
+9:9
+9:17
+9:25
+9:26
+9:26
diff --git a/src/testdir/test89.in b/src/testdir/test89.in
new file mode 100644
index 0000000000..1c3079f62f
--- /dev/null
+++ b/src/testdir/test89.in
@@ -0,0 +1,71 @@
+- Some tests for setting 'number' and 'relativenumber'
+ This is not all that useful now that the options are no longer reset when
+ setting the other.
+- Some tests for findfile() function
+
+STARTTEST
+:so small.vim
+:set hidden nocp nu rnu viminfo+=nviminfo
+:redir @a | set nu? rnu? | redir END
+:e! xx
+:redir @b | set nu? rnu? | redir END
+:e! #
+:$put ='results:'
+:$put a
+:$put b
+:"
+:set nonu nornu
+:setglobal nu
+:setlocal rnu
+:redir @c | setglobal nu? | redir END
+:set nonu nornu
+:setglobal rnu
+:setlocal nu
+:redir @d | setglobal rnu? | redir END
+:$put =':setlocal must NOT reset the other global value'
+:$put c
+:$put d
+:"
+:set nonu nornu
+:setglobal nu
+:setglobal rnu
+:redir @e | setglobal nu? | redir END
+:set nonu nornu
+:setglobal rnu
+:setglobal nu
+:redir @f | setglobal rnu? | redir END
+:$put =':setglobal MUST reset the other global value'
+:$put e
+:$put f
+:"
+:set nonu nornu
+:set nu
+:set rnu
+:redir @g | setglobal nu? | redir END
+:set nonu nornu
+:set rnu
+:set nu
+:redir @h | setglobal rnu? | redir END
+:$put =':set MUST reset the other global value'
+:$put g
+:$put h
+:"
+: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
+:$put =''
+:$put ='Testing findfile'
+:$put =''
+:set ssl
+:$put =findfile('test19.in','src/test*')
+:exe "cd" cwd
+:cd ..
+:$put =findfile('test19.in','test*')
+:$put =findfile('test19.in','testdir')
+:exe "cd" cwd
+:/^results/,$w! test.out
+:q!
+ENDTEST
+
diff --git a/src/testdir/test89.ok b/src/testdir/test89.ok
new file mode 100644
index 0000000000..90034758d9
--- /dev/null
+++ b/src/testdir/test89.ok
@@ -0,0 +1,28 @@
+results:
+
+ number
+ relativenumber
+
+ number
+ relativenumber
+:setlocal must NOT reset the other global value
+
+ number
+
+ relativenumber
+:setglobal MUST reset the other global value
+
+ number
+
+ relativenumber
+:set MUST reset the other global value
+
+ number
+
+ relativenumber
+
+Testing findfile
+
+src/testdir/test19.in
+testdir/test19.in
+testdir/test19.in
diff --git a/src/testdir/test9.in b/src/testdir/test9.in
new file mode 100644
index 0000000000..84e17943c7
--- /dev/null
+++ b/src/testdir/test9.in
@@ -0,0 +1,12 @@
+Test for Bufleave autocommand that deletes the buffer we are about to edit.
+
+STARTTEST
+:so small.vim
+:au BufLeave test9.in bwipe yy
+:e yy
+:/^start of/,$w! test.out " Write contents of this file
+:qa!
+ENDTEST
+
+start of test file xx
+end of test file xx
diff --git a/src/testdir/test9.ok b/src/testdir/test9.ok
new file mode 100644
index 0000000000..cccb5f3ef2
--- /dev/null
+++ b/src/testdir/test9.ok
@@ -0,0 +1,2 @@
+start of test file xx
+end of test file xx
diff --git a/src/testdir/test90.in b/src/testdir/test90.in
new file mode 100644
index 0000000000..6bac414f31
--- /dev/null
+++ b/src/testdir/test90.in
@@ -0,0 +1,53 @@
+Tests for sha256() function. vim: set ft=vim et ts=2 sw=2 :
+
+STARTTEST
+:so small.vim
+:if !has('cryptv') || !exists('*sha256')
+ e! test.ok
+ wq! test.out
+:endif
+:"
+:let testcase='test for empty string: '
+:if sha256("") ==# 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'
+: let res='ok'
+:else
+: let res='ng'
+:endif
+:$put =testcase.res
+:"
+:let testcase='test for 1 char: '
+:if sha256("a") ==# 'ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb'
+: let res='ok'
+:else
+: let res='ng'
+:endif
+:$put =testcase.res
+:"
+:let testcase='test for 3 chars: '
+:if sha256("abc") ==# 'ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad'
+: let res='ok'
+:else
+: let res='ng'
+:endif
+:$put =testcase.res
+:"
+:let testcase='test for contains meta char: '
+:if sha256("foo\nbar") ==# '807eff6267f3f926a21d234f7b0cf867a86f47e07a532f15e8cc39ed110ca776'
+: let res='ok'
+:else
+: let res='ng'
+:endif
+:$put =testcase.res
+:"
+:let testcase='test for contains non-ascii char: '
+:if sha256("\xde\xad\xbe\xef") ==# '5f78c33274e43fa9de5659265c1d917e25c03722dcb0b8d27db8d5feaa813953'
+: let res='ok'
+:else
+: let res='ng'
+:endif
+:$put =testcase.res
+"
+:/^start:/,$wq! test.out
+ENDTEST
+
+start:
diff --git a/src/testdir/test90.ok b/src/testdir/test90.ok
new file mode 100644
index 0000000000..9a8e7fe961
--- /dev/null
+++ b/src/testdir/test90.ok
@@ -0,0 +1,6 @@
+start:
+test for empty string: ok
+test for 1 char: ok
+test for 3 chars: ok
+test for contains meta char: ok
+test for contains non-ascii char: ok
diff --git a/src/testdir/test91.in b/src/testdir/test91.in
new file mode 100644
index 0000000000..e900a522df
--- /dev/null
+++ b/src/testdir/test91.in
@@ -0,0 +1,111 @@
+Tests for getbufvar(), getwinvar(), gettabvar() and gettabwinvar().
+vim: set ft=vim :
+
+STARTTEST
+:so small.vim
+:so mbyte.vim
+:"
+:" Test for getbufvar()
+:" Use strings to test for memory leaks.
+:let b:var_num = '1234'
+:let def_num = '5678'
+:$put =string(getbufvar(1, 'var_num'))
+:$put =string(getbufvar(1, 'var_num', def_num))
+:$put =string(getbufvar(1, ''))
+:$put =string(getbufvar(1, '', def_num))
+:unlet b:var_num
+:$put =string(getbufvar(1, 'var_num', def_num))
+:$put =string(getbufvar(1, ''))
+:$put =string(getbufvar(1, '', def_num))
+:$put =string(getbufvar(9, ''))
+:$put =string(getbufvar(9, '', def_num))
+:unlet def_num
+:$put =string(getbufvar(1, '&autoindent'))
+:$put =string(getbufvar(1, '&autoindent', 1))
+:"
+:" Open new window with forced option values
+:set fileformats=unix,dos
+:new ++ff=dos ++bin ++enc=iso-8859-2
+:let otherff = getbufvar(bufnr('%'), '&fileformat')
+:let otherbin = getbufvar(bufnr('%'), '&bin')
+:let otherfenc = getbufvar(bufnr('%'), '&fenc')
+:close
+:$put =otherff
+:$put =string(otherbin)
+:$put =otherfenc
+:unlet otherff otherbin otherfenc
+:" test for getwinvar()
+:let w:var_str = "Dance"
+:let def_str = "Chance"
+:$put =string(getwinvar(1, 'var_str'))
+:$put =string(getwinvar(1, 'var_str', def_str))
+:$put =string(getwinvar(1, ''))
+:$put =string(getwinvar(1, '', def_str))
+:unlet w:var_str
+:$put =string(getwinvar(1, 'var_str', def_str))
+:$put =string(getwinvar(1, ''))
+:$put =string(getwinvar(1, '', def_str))
+:$put =string(getwinvar(9, ''))
+:$put =string(getwinvar(9, '', def_str))
+:$put =string(getwinvar(1, '&nu'))
+:$put =string(getwinvar(1, '&nu', 1))
+:unlet def_str
+:"
+:" test for gettabvar()
+:tabnew
+:tabnew
+:let t:var_list = [1, 2, 3]
+:let def_list = [4, 5, 6, 7]
+:tabrewind
+:$put =string(gettabvar(3, 'var_list'))
+:$put =string(gettabvar(3, 'var_list', def_list))
+:$put =string(gettabvar(3, ''))
+:$put =string(gettabvar(3, '', def_list))
+:tablast
+:unlet t:var_list
+:tabrewind
+:$put =string(gettabvar(3, 'var_list', def_list))
+:$put =string(gettabvar(9, ''))
+:$put =string(gettabvar(9, '', def_list))
+:$put =string(gettabvar(3, '&nu'))
+:$put =string(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
+:$put =string(gettabwinvar(2, 3, 'var_dict'))
+:$put =string(gettabwinvar(2, 3, 'var_dict', def_dict))
+:$put =string(gettabwinvar(2, 3, ''))
+:$put =string(gettabwinvar(2, 3, '', def_dict))
+:tabnext
+:3wincmd w
+:unlet w:var_dict
+:tabrewind
+:$put =string(gettabwinvar(2, 3, 'var_dict', def_dict))
+:$put =string(gettabwinvar(2, 3, ''))
+:$put =string(gettabwinvar(2, 3, '', def_dict))
+:$put =string(gettabwinvar(2, 9, ''))
+:$put =string(gettabwinvar(2, 9, '', def_dict))
+:$put =string(gettabwinvar(9, 3, ''))
+:$put =string(gettabwinvar(9, 3, '', def_dict))
+:unlet def_dict
+:$put =string(gettabwinvar(2, 3, '&nux'))
+:$put =string(gettabwinvar(2, 3, '&nux', 1))
+:tabonly
+:"
+:/^start/,$wq! test.out
+ENDTEST
+
+start:
diff --git a/src/testdir/test91.ok b/src/testdir/test91.ok
new file mode 100644
index 0000000000..22e1572209
--- /dev/null
+++ b/src/testdir/test91.ok
@@ -0,0 +1,48 @@
+start:
+'1234'
+'1234'
+{'var_num': '1234'}
+{'var_num': '1234'}
+'5678'
+{}
+{}
+''
+'5678'
+0
+0
+dos
+1
+iso-8859-2
+'Dance'
+'Dance'
+{'var_str': 'Dance'}
+{'var_str': 'Dance'}
+'Chance'
+{}
+{}
+''
+'Chance'
+0
+0
+[1, 2, 3]
+[1, 2, 3]
+''
+[4, 5, 6, 7]
+[4, 5, 6, 7]
+''
+[4, 5, 6, 7]
+''
+[4, 5, 6, 7]
+{'dict': 'tabwin'}
+{'dict': 'tabwin'}
+{'var_dict': {'dict': 'tabwin'}}
+{'var_dict': {'dict': 'tabwin'}}
+{'dict2': 'newval'}
+{}
+{}
+''
+{'dict2': 'newval'}
+''
+{'dict2': 'newval'}
+''
+1
diff --git a/src/testdir/test92.in b/src/testdir/test92.in
new file mode 100644
index 0000000000..9593aec4c7
--- /dev/null
+++ b/src/testdir/test92.in
@@ -0,0 +1,48 @@
+vim: set ft=vim fenc=utf-8:
+
+Tests if :mksession saves cursor columns correctly in presence of tab and
+multibyte characters when fileencoding=utf-8.
+
+STARTTEST
+:so mbyte.vim
+:if !has('mksession')
+: e! test.ok
+: wq! test.out
+:endif
+:set sessionoptions=buffers splitbelow fileencoding=utf-8
+/^start:
+:vsplit
+j16|:split
+j16|:split
+j16|:split
+j8|:split
+j8|:split
+j16|:split
+j16|:split
+j16|:wincmd l
+/^start:
+:set nowrap
+j16|3zl:split
+j016|3zl:split
+j016|3zl:split
+j08|3zl:split
+j08|3zl:split
+j016|3zl:split
+j016|3zl:split
+j016|3zl:split
+:mksession! test.out
+:new test.out
+:v/\(^ *normal! 0\|^ *exe 'normal!\)/d
+:w! test.out
+:qa!
+ENDTEST
+
+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
diff --git a/src/testdir/test92.ok b/src/testdir/test92.ok
new file mode 100644
index 0000000000..cca5ec487c
--- /dev/null
+++ b/src/testdir/test92.ok
@@ -0,0 +1,26 @@
+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|
diff --git a/src/testdir/test93.in b/src/testdir/test93.in
new file mode 100644
index 0000000000..877838ce1b
--- /dev/null
+++ b/src/testdir/test93.in
@@ -0,0 +1,48 @@
+vim: set ft=vim fenc=latin1:
+
+Tests if :mksession saves cursor columns correctly in presence of tab and
+multibyte characters when fileencoding=latin1.
+
+STARTTEST
+:so mbyte.vim
+:if !has('mksession')
+: e! test.ok
+: wq! test.out
+:endif
+:set sessionoptions=buffers splitbelow fileencoding=latin1
+/^start:
+:vsplit
+j16|:split
+j16|:split
+j16|:split
+j8|:split
+j8|:split
+j16|:split
+j16|:split
+j16|:wincmd l
+/^start:
+:set nowrap
+j16|3zl:split
+j016|3zl:split
+j016|3zl:split
+j08|3zl:split
+j08|3zl:split
+j016|3zl:split
+j016|3zl:split
+j016|3zl:split
+:mksession! test.out
+:new test.out
+:v/\(^ *normal! 0\|^ *exe 'normal!\)/d
+:w! test.out
+:qa!
+ENDTEST
+
+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
diff --git a/src/testdir/test93.ok b/src/testdir/test93.ok
new file mode 100644
index 0000000000..cca5ec487c
--- /dev/null
+++ b/src/testdir/test93.ok
@@ -0,0 +1,26 @@
+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|
diff --git a/src/testdir/test94.in b/src/testdir/test94.in
new file mode 100644
index 0000000000..dfa91d8340
--- /dev/null
+++ b/src/testdir/test94.in
@@ -0,0 +1,95 @@
+Test for Visual mode and operators
+
+Tests for the two kinds of operations: Those executed with Visual mode
+followed by an operator and those executed via Operator-pending mode. Also
+part of the test are mappings, counts, and repetition with the . command.
+
+Test cases:
+- Visual modes (v V CTRL-V) followed by an operator; count; repeating
+- Visual mode maps; count; repeating
+ - Simple
+ - With an Ex command (custom text object)
+- Operator-pending mode maps
+ - Simple
+ - With Ex command moving the cursor
+ - With Ex command and Visual selection (custom text object)
+- Patch 7.3.879: Properly abort Ex command in Operator-pending mode
+
+STARTTEST
+:so small.vim
+:set nocp viminfo+=nviminfo
+:
+:" User functions
+:function MoveToCap()
+: call search('\u', 'W')
+:endfunction
+:function SelectInCaps()
+: let [line1, col1] = searchpos('\u', 'bcnW')
+: let [line2, col2] = searchpos('.\u', 'nW')
+: call setpos("'<", [0, line1, col1, 0])
+: call setpos("'>", [0, line2, col2, 0])
+: normal! gv
+:endfunction
+:
+:" Visual modes followed by operator
+/^apple
+lvld.l3vd.:
+/^line 1
+Vcnewlinej.j2Vd.:
+/^xxxx
+jlc l.l2c----l.:
+:
+:" Visual mode maps (movement and text object)
+:vnoremap W /\u/s-1<CR>
+:vnoremap iW :<C-U>call SelectInCaps()<CR>
+/^Kiwi
+vWcNol.fD2vd.:
+/^Jambu
+llviWc-l.l2vdl.:
+:
+:" Operator-pending mode maps (movement and text object)
+:onoremap W /\u/<CR>
+:onoremap <Leader>W :<C-U>call MoveToCap()<CR>
+:onoremap iW :<C-U>call SelectInCaps()<CR>
+/^Pineapple
+cW-l.l2.l.:
+/^Juniper
+g?\WfD.:
+/^Lemon
+yiWPlciWNewfr.:
+:
+:" Patch 7.3.879: Properly abort Operator-pending mode for "dv:<Esc>" etc.
+/^zzzz
+dV: dv: :set noma | let v:errmsg = ''
+d: :set ma | put = v:errmsg =~# '^E21' ? 'ok' : 'failed'
+dv:dV::set noma | let v:errmsg = ''
+d::set ma | put = v:errmsg =~# '^E21' ? 'failed' : 'ok'
+:/^start:/+2,$w! test.out
+:q!
+ENDTEST
+
+start:
+
+apple banana cherry
+
+line 1 line 1
+line 2 line 2
+line 3 line 3
+line 4 line 4
+line 5 line 5
+line 6 line 6
+
+xxxxxxxxxxxxx
+xxxxxxxxxxxxx
+xxxxxxxxxxxxx
+xxxxxxxxxxxxx
+
+KiwiRaspberryDateWatermelonPeach
+JambuRambutanBananaTangerineMango
+
+PineappleQuinceLoganberryOrangeGrapefruitKiwiZ
+JuniperDurianZ
+LemonNectarineZ
+
+zzzz
+zzzz
diff --git a/src/testdir/test94.ok b/src/testdir/test94.ok
new file mode 100644
index 0000000000..3996f2a3a4
--- /dev/null
+++ b/src/testdir/test94.ok
@@ -0,0 +1,20 @@
+a y
+
+newline
+newline
+
+ --------x
+ --------x
+xxxx--------x
+xxxx--------x
+
+NoNoberryach
+--ago
+
+----Z
+WhavcreQhevnaZ
+LemonNewNewZ
+
+zzz
+ok
+ok
diff --git a/src/testdir/test95.in b/src/testdir/test95.in
new file mode 100644
index 0000000000..90fa69945a
--- /dev/null
+++ b/src/testdir/test95.in
@@ -0,0 +1,135 @@
+Test for regexp patterns with multi-byte support, using utf-8.
+See test64 for the non-multi-byte tests.
+
+A pattern that gives the expected result produces OK, so that we know it was
+actually tried.
+
+STARTTEST
+:so small.vim
+:so mbyte.vim
+:set nocp encoding=utf-8 viminfo+=nviminfo nomore
+:" tl is a List of Lists with:
+:" 2: test auto/old/new 0: test auto/old 1: test auto/new
+:" regexp pattern
+:" text to test the pattern on
+:" expected match (optional)
+:" expected submatch 1 (optional)
+:" expected submatch 2 (optional)
+:" etc.
+:" When there is no match use only the first two items.
+:let tl = []
+
+:"""" Multi-byte character tests. These will fail unless vim is compiled
+:"""" with Multibyte (FEAT_MBYTE) or BIG/HUGE features.
+:call add(tl, [2, '[[:alpha:][=a=]]\+', '879 aiaãâaiuvna ', 'aiaãâaiuvna'])
+:call add(tl, [2, '[[=a=]]\+', 'ddaãâbcd', 'aãâ']) " equivalence classes
+:call add(tl, [2, '[^ม ]\+', 'มม oijasoifjos ifjoisj f osij j มมมมม abcd', 'oijasoifjos'])
+:call add(tl, [2, ' [^ ]\+', 'start มabcdม ', ' มabcdม'])
+:call add(tl, [2, '[ม[:alpha:][=a=]]\+', '879 aiaãมâมaiuvna ', 'aiaãมâมaiuvna'])
+
+:" this is not a normal "i" but 0xec
+:call add(tl, [2, '\p\+', 'ìa', 'ìa'])
+:call add(tl, [2, '\p*', 'aã‚', 'aã‚'])
+
+:"""" Test recognition of some character classes
+:call add(tl, [2, '\i\+', '&*¨xx ', 'xx'])
+:call add(tl, [2, '\f\+', '&*Ÿfname ', 'fname'])
+
+:"""" Test composing character matching
+:call add(tl, [2, '.ม', 'xม่x yมy', 'yม'])
+:call add(tl, [2, '.ม่', 'xม่x yมy', 'xม่'])
+:call add(tl, [2, "\u05b9", " x\u05b9 ", "x\u05b9"])
+:call add(tl, [2, ".\u05b9", " x\u05b9 ", "x\u05b9"])
+:call add(tl, [2, "\u05b9\u05bb", " x\u05b9\u05bb ", "x\u05b9\u05bb"])
+:call add(tl, [2, ".\u05b9\u05bb", " x\u05b9\u05bb ", "x\u05b9\u05bb"])
+:call add(tl, [2, "\u05bb\u05b9", " x\u05b9\u05bb ", "x\u05b9\u05bb"])
+:call add(tl, [2, ".\u05bb\u05b9", " x\u05b9\u05bb ", "x\u05b9\u05bb"])
+:call add(tl, [2, "\u05b9", " y\u05bb x\u05b9 ", "x\u05b9"])
+:call add(tl, [2, ".\u05b9", " y\u05bb x\u05b9 ", "x\u05b9"])
+:call add(tl, [2, "\u05b9", " y\u05bb\u05b9 x\u05b9 ", "y\u05bb\u05b9"])
+:call add(tl, [2, ".\u05b9", " y\u05bb\u05b9 x\u05b9 ", "y\u05bb\u05b9"])
+:call add(tl, [1, "\u05b9\u05bb", " y\u05b9 x\u05b9\u05bb ", "x\u05b9\u05bb"])
+:call add(tl, [2, ".\u05b9\u05bb", " y\u05bb x\u05b9\u05bb ", "x\u05b9\u05bb"])
+
+
+:"""" Test \Z
+:call add(tl, [2, 'ú\Z', 'x'])
+:call add(tl, [2, 'יהוה\Z', 'יהוה', 'יהוה'])
+:call add(tl, [2, 'יְהוָה\Z', 'יהוה', 'יהוה'])
+:call add(tl, [2, 'יהוה\Z', 'יְהוָה', 'יְהוָה'])
+:call add(tl, [2, 'יְהוָה\Z', 'יְהוָה', 'יְהוָה'])
+:call add(tl, [2, 'יְ\Z', 'וְיַ', 'יַ'])
+:call add(tl, [2, "×§\u200d\u05b9x\\Z", "x×§\u200d\u05b9xy", "×§\u200d\u05b9x"])
+:call add(tl, [2, "×§\u200d\u05b9x\\Z", "x×§\u200dxy", "×§\u200dx"])
+:call add(tl, [2, "×§\u200dx\\Z", "x×§\u200d\u05b9xy", "×§\u200d\u05b9x"])
+:call add(tl, [2, "×§\u200dx\\Z", "x×§\u200dxy", "×§\u200dx"])
+:call add(tl, [2, "\u05b9\\Z", "xyz"])
+:call add(tl, [2, "\\Z\u05b9", "xyz"])
+:call add(tl, [2, "\u05b9\\Z", "xy\u05b9z", "y\u05b9"])
+:call add(tl, [2, "\\Z\u05b9", "xy\u05b9z", "y\u05b9"])
+:call add(tl, [1, "\u05b9\\+\\Z", "xy\u05b9z\u05b9 ", "y\u05b9z\u05b9"])
+:call add(tl, [1, "\\Z\u05b9\\+", "xy\u05b9z\u05b9 ", "y\u05b9z\u05b9"])
+
+:"""" Combining different tests and features
+:call add(tl, [2, '[^[=a=]]\+', 'ddaãâbcd', 'dd'])
+
+:"""" Run the tests
+
+:"
+:for t in tl
+: let re = t[0]
+: let pat = t[1]
+: let text = t[2]
+: let matchidx = 3
+: for engine in [0, 1, 2]
+: if engine == 2 && re == 0 || engine == 1 && re == 1
+: continue
+: endif
+: let &regexpengine = engine
+: try
+: let l = matchlist(text, pat)
+: catch
+: $put ='ERROR: pat: \"' . pat . '\", text: \"' . text . '\", caused an exception: \"' . v:exception . '\"'
+: endtry
+:" check the match itself
+: if len(l) == 0 && len(t) > matchidx
+: $put ='ERROR: pat: \"' . pat . '\", text: \"' . text . '\", did not match, expected: \"' . t[matchidx] . '\"'
+: elseif len(l) > 0 && len(t) == matchidx
+: $put ='ERROR: pat: \"' . pat . '\", text: \"' . text . '\", match: \"' . l[0] . '\", expected no match'
+: elseif len(t) > matchidx && l[0] != t[matchidx]
+: $put ='ERROR: pat: \"' . pat . '\", text: \"' . text . '\", match: \"' . l[0] . '\", expected: \"' . t[matchidx] . '\"'
+: else
+: $put ='OK ' . engine . ' - ' . pat
+: endif
+: if len(l) > 0
+:" check all the nine submatches
+: for i in range(1, 9)
+: if len(t) <= matchidx + i
+: let e = ''
+: else
+: let e = t[matchidx + i]
+: endif
+: if l[i] != e
+: $put ='ERROR: pat: \"' . pat . '\", text: \"' . text . '\", submatch ' . i . ': \"' . l[i] . '\", expected: \"' . e . '\"'
+: endif
+: endfor
+: unlet i
+: endif
+: endfor
+:endfor
+:unlet t tl e l
+
+:" check that 'ambiwidth' does not change the meaning of \p
+:set regexpengine=1 ambiwidth=single
+:$put ='eng 1 ambi single: ' . match(\"\u00EC\", '\p')
+:set regexpengine=1 ambiwidth=double
+:$put ='eng 1 ambi double: ' . match(\"\u00EC\", '\p')
+:set regexpengine=2 ambiwidth=single
+:$put ='eng 2 ambi single: ' . match(\"\u00EC\", '\p')
+:set regexpengine=2 ambiwidth=double
+:$put ='eng 2 ambi double: ' . match(\"\u00EC\", '\p')
+
+:/\%#=1^Results/,$wq! test.out
+ENDTEST
+
+Results of test95:
diff --git a/src/testdir/test95.ok b/src/testdir/test95.ok
new file mode 100644
index 0000000000..c378221a70
--- /dev/null
+++ b/src/testdir/test95.ok
@@ -0,0 +1,122 @@
+Results of test95:
+OK 0 - [[:alpha:][=a=]]\+
+OK 1 - [[:alpha:][=a=]]\+
+OK 2 - [[:alpha:][=a=]]\+
+OK 0 - [[=a=]]\+
+OK 1 - [[=a=]]\+
+OK 2 - [[=a=]]\+
+OK 0 - [^ม ]\+
+OK 1 - [^ม ]\+
+OK 2 - [^ม ]\+
+OK 0 - [^ ]\+
+OK 1 - [^ ]\+
+OK 2 - [^ ]\+
+OK 0 - [ม[:alpha:][=a=]]\+
+OK 1 - [ม[:alpha:][=a=]]\+
+OK 2 - [ม[:alpha:][=a=]]\+
+OK 0 - \p\+
+OK 1 - \p\+
+OK 2 - \p\+
+OK 0 - \p*
+OK 1 - \p*
+OK 2 - \p*
+OK 0 - \i\+
+OK 1 - \i\+
+OK 2 - \i\+
+OK 0 - \f\+
+OK 1 - \f\+
+OK 2 - \f\+
+OK 0 - .ม
+OK 1 - .ม
+OK 2 - .ม
+OK 0 - .ม่
+OK 1 - .ม่
+OK 2 - .ม่
+OK 0 - Ö¹
+OK 1 - Ö¹
+OK 2 - Ö¹
+OK 0 - .Ö¹
+OK 1 - .Ö¹
+OK 2 - .Ö¹
+OK 0 - Ö¹Ö»
+OK 1 - Ö¹Ö»
+OK 2 - Ö¹Ö»
+OK 0 - .Ö¹Ö»
+OK 1 - .Ö¹Ö»
+OK 2 - .Ö¹Ö»
+OK 0 - Ö»Ö¹
+OK 1 - Ö»Ö¹
+OK 2 - Ö»Ö¹
+OK 0 - .Ö»Ö¹
+OK 1 - .Ö»Ö¹
+OK 2 - .Ö»Ö¹
+OK 0 - Ö¹
+OK 1 - Ö¹
+OK 2 - Ö¹
+OK 0 - .Ö¹
+OK 1 - .Ö¹
+OK 2 - .Ö¹
+OK 0 - Ö¹
+OK 1 - Ö¹
+OK 2 - Ö¹
+OK 0 - .Ö¹
+OK 1 - .Ö¹
+OK 2 - .Ö¹
+OK 0 - Ö¹Ö»
+OK 2 - Ö¹Ö»
+OK 0 - .Ö¹Ö»
+OK 1 - .Ö¹Ö»
+OK 2 - .Ö¹Ö»
+OK 0 - ú\Z
+OK 1 - ú\Z
+OK 2 - ú\Z
+OK 0 - יהוה\Z
+OK 1 - יהוה\Z
+OK 2 - יהוה\Z
+OK 0 - יְהוָה\Z
+OK 1 - יְהוָה\Z
+OK 2 - יְהוָה\Z
+OK 0 - יהוה\Z
+OK 1 - יהוה\Z
+OK 2 - יהוה\Z
+OK 0 - יְהוָה\Z
+OK 1 - יְהוָה\Z
+OK 2 - יְהוָה\Z
+OK 0 - ×™Ö°\Z
+OK 1 - ×™Ö°\Z
+OK 2 - ×™Ö°\Z
+OK 0 - ×§â€Ö¹x\Z
+OK 1 - ×§â€Ö¹x\Z
+OK 2 - ×§â€Ö¹x\Z
+OK 0 - ×§â€Ö¹x\Z
+OK 1 - ×§â€Ö¹x\Z
+OK 2 - ×§â€Ö¹x\Z
+OK 0 - ×§â€x\Z
+OK 1 - ×§â€x\Z
+OK 2 - ×§â€x\Z
+OK 0 - ×§â€x\Z
+OK 1 - ×§â€x\Z
+OK 2 - ×§â€x\Z
+OK 0 - Ö¹\Z
+OK 1 - Ö¹\Z
+OK 2 - Ö¹\Z
+OK 0 - \ZÖ¹
+OK 1 - \ZÖ¹
+OK 2 - \ZÖ¹
+OK 0 - Ö¹\Z
+OK 1 - Ö¹\Z
+OK 2 - Ö¹\Z
+OK 0 - \ZÖ¹
+OK 1 - \ZÖ¹
+OK 2 - \ZÖ¹
+OK 0 - Ö¹\+\Z
+OK 2 - Ö¹\+\Z
+OK 0 - \ZÖ¹\+
+OK 2 - \ZÖ¹\+
+OK 0 - [^[=a=]]\+
+OK 1 - [^[=a=]]\+
+OK 2 - [^[=a=]]\+
+eng 1 ambi single: 0
+eng 1 ambi double: 0
+eng 2 ambi single: 0
+eng 2 ambi double: 0
diff --git a/src/testdir/test96.in b/src/testdir/test96.in
new file mode 100644
index 0000000000..9d1a2c83a5
--- /dev/null
+++ b/src/testdir/test96.in
@@ -0,0 +1,142 @@
+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.
+
+Note: to debug a problem comment out the last ":b 1" in a test and testing will
+stop at this point.
+
+STARTTEST
+:so small.vim
+: enew
+: w! test.out
+: b 1
+: " Set up the test environment:
+: function! 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', '')
+: endfunction
+: 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
+ENDTEST
+
+Test A:
+STARTTEST
+:lrewind
+:enew
+:lopen
+:lnext
+:lnext
+:lnext
+:lnext
+:vert split
+:wincmd L
+:lopen
+:wincmd p
+:lnext
+:"b 1
+:let fileName = expand("%")
+:wincmd p
+:let locationListFileName = substitute(getline(line('.')), '\([^|]*\)|.*', '\1', '')
+:wincmd n
+:wincmd K
+:b test.out
+:let fileName = substitute(fileName, '\\', '/', 'g')
+:let locationListFileName = substitute(locationListFileName, '\\', '/', 'g')
+:call append(line('$'), "Test A:")
+:call append(line('$'), " - file name displayed: " . fileName)
+:call append(line('$'), " - quickfix claims that the file name displayed is: " . locationListFileName)
+:w
+:wincmd o
+:b 1
+ENDTEST
+
+Test B:
+STARTTEST
+:lrewind
+:lopen
+:2
+:exe "normal \<CR>"
+:wincmd p
+:3
+:exe "normal \<CR>"
+:wincmd p
+:4
+:exe "normal \<CR>"
+:let numberOfWindowsOpen = winnr('$')
+:wincmd n
+:wincmd K
+:b test.out
+:call append(line('$'), "Test B:")
+:call append(line('$'), " - number of window open: " . numberOfWindowsOpen)
+:w
+:wincmd o
+:b 1
+ENDTEST
+
+Test C:
+STARTTEST
+: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
+:let locationListWindowBufType = &buftype
+:2wincmd w
+:let bufferName = expand("%")
+:wincmd n
+:wincmd K
+:b test.out
+:let bufferName = substitute(bufferName, '\\', '/', 'g')
+:call append(line('$'), "Test C:")
+:call append(line('$'), " - 'buftype' of the location list window: " . locationListWindowBufType)
+:call append(line('$'), " - buffer displayed in the 2nd window: " . bufferName)
+:w
+:wincmd o
+:b 1
+ENDTEST
+
+STARTTEST
+:qa
+ENDTEST
+
diff --git a/src/testdir/test96.ok b/src/testdir/test96.ok
new file mode 100644
index 0000000000..3498e52f73
--- /dev/null
+++ b/src/testdir/test96.ok
@@ -0,0 +1,9 @@
+
+Test A:
+ - file name displayed: test://bar.txt
+ - quickfix claims that the file name displayed is: test://bar.txt
+Test B:
+ - number of window open: 2
+Test C:
+ - 'buftype' of the location list window: quickfix
+ - buffer displayed in the 2nd window: test://quux.txt
diff --git a/src/testdir/test97.in b/src/testdir/test97.in
new file mode 100644
index 0000000000..13e9dd5b6e
--- /dev/null
+++ b/src/testdir/test97.in
@@ -0,0 +1,17 @@
+Test whether glob()/globpath() return correct results with certain escaped
+characters.
+
+STARTTEST
+:so small.vim
+:set shell=doesnotexist
+:e test.out
+:put =glob('Xxx\{')
+:put =glob('Xxx\$')
+:w! Xxx{
+:w! Xxx\$
+:put =glob('Xxx\{')
+:put =glob('Xxx\$')
+:w
+:qa!
+ENDTEST
+
diff --git a/src/testdir/test97.ok b/src/testdir/test97.ok
new file mode 100644
index 0000000000..afa96a4de4
--- /dev/null
+++ b/src/testdir/test97.ok
@@ -0,0 +1,5 @@
+
+
+
+Xxx{
+Xxx$
diff --git a/src/testdir/test98.in b/src/testdir/test98.in
new file mode 100644
index 0000000000..83ccba09e9
--- /dev/null
+++ b/src/testdir/test98.in
@@ -0,0 +1,43 @@
+Test for 'scrollbind' causing an unexpected scroll of one of the windows.
+STARTTEST
+:so small.vim
+:" We don't want the status line to cause problems:
+:set laststatus=0
+:let g:totalLines = &lines * 20
+:let middle = g:totalLines / 2
+:wincmd n
+:wincmd o
+:for i in range(1, g:totalLines)
+: call setline(i, 'LINE ' . i)
+:endfor
+:exe string(middle)
+:normal zt
+:normal M
+:aboveleft vert new
+:for i in range(1, g:totalLines)
+: call setline(i, 'line ' . i)
+:endfor
+:exe string(middle)
+:normal zt
+:normal M
+:" Execute the following two command 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
+:q!
+:%del _
+:call setline(1, 'Difference between the top lines (left - right): ' . string(topLineLeft - topLineRight))
+:w! test.out
+:brewind
+ENDTEST
+
+STARTTEST
+:qa!
+ENDTEST
+
diff --git a/src/testdir/test98.ok b/src/testdir/test98.ok
new file mode 100644
index 0000000000..356ddd8eac
--- /dev/null
+++ b/src/testdir/test98.ok
@@ -0,0 +1 @@
+Difference between the top lines (left - right): 0
diff --git a/src/testdir/test99.in b/src/testdir/test99.in
new file mode 100644
index 0000000000..77828f4b68
--- /dev/null
+++ b/src/testdir/test99.in
@@ -0,0 +1,68 @@
+Tests for regexp with multi-byte encoding and various magic settings.
+Test matchstr() with a count and multi-byte chars.
+See test44 for exactly the same test with re=1.
+
+STARTTEST
+:so mbyte.vim
+:set nocompatible encoding=utf-8 termencoding=latin1 viminfo+=nviminfo
+:set re=2
+/^1
+/a*b\{2}c\+/e
+x/\Md\*e\{2}f\+/e
+x:set nomagic
+/g\*h\{2}i\+/e
+x/\mj*k\{2}l\+/e
+x/\vm*n{2}o+/e
+x/\V^aa$
+x:set magic
+/\v(a)(b)\2\1\1/e
+x/\V[ab]\(\[xy]\)\1
+x:" Now search for multi-byte without composing char
+/ม
+x:" Now search for multi-byte with composing char
+/ม่
+x:" find word by change of word class
+/ã¡\<カヨ\>ã¯
+x:" Test \%u, [\u] and friends
+/\%u20ac
+x/[\u4f7f\u5929]\+
+x/\%U12345678
+x/[\U1234abcd\u1234\uabcd]
+x/\%d21879b
+x/ [[=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=]]*/e
+x/ [[=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=]]*/e
+x:" Test backwards search from a multi-byte char
+/x
+x?.
+x:let @w=':%s#comb[i]nations#œ̄ṣÌm̥̄ᾱ̆Ì#g'
+:@w
+:?^1?,$w! test.out
+:e! test.out
+G:put =matchstr(\"×בגד\", \".\", 0, 2) " ב
+:put =matchstr(\"×בגד\", \"..\", 0, 2) " בג
+:put =matchstr(\"×בגד\", \".\", 0, 0) " ×
+:put =matchstr(\"×בגד\", \".\", 4, -1) " ×’
+:w!
+:qa!
+ENDTEST
+
+1 a aa abb abbccc
+2 d dd dee deefff
+3 g gg ghh ghhiii
+4 j jj jkk jkklll
+5 m mm mnn mnnooo
+6 x ^aa$ x
+7 (a)(b) abbaa
+8 axx [ab]xx
+9 หม่x อมx
+a อมx หม่x
+b ã¡ã‚«ãƒ¨ã¯
+c x ¬€x
+d 天使x
+e ü’…™¸y
+f ü’Нz
+g aå•·bb
+h 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ŹŻŽƵáºáº”
+i 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źżžƶẑẕ
+j 0123â¤x
+k combinations
diff --git a/src/testdir/test99.ok b/src/testdir/test99.ok
new file mode 100644
index 0000000000..0bd0b8ab73
--- /dev/null
+++ b/src/testdir/test99.ok
@@ -0,0 +1,24 @@
+1 a aa abb abbcc
+2 d dd dee deeff
+3 g gg ghh ghhii
+4 j jj jkk jkkll
+5 m mm mnn mnnoo
+6 x aa$ x
+7 (a)(b) abba
+8 axx ab]xx
+9 หม่x อx
+a อมx หx
+b カヨã¯
+c x ¬x
+d 使x
+e y
+f z
+g abb
+h 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ŹŻŽƵáº
+i 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źżžƶẑ
+j 012â¤
+k œ̄ṣÌm̥̄ᾱ̆Ì
+ב
+בג
+×’
diff --git a/src/testdir/unix.vim b/src/testdir/unix.vim
new file mode 100644
index 0000000000..f766e74c30
--- /dev/null
+++ b/src/testdir/unix.vim
@@ -0,0 +1,3 @@
+" Settings for test script execution
+" Always use "sh", don't use the value of "$SHELL".
+set shell=sh
diff --git a/src/ui.c b/src/ui.c
new file mode 100644
index 0000000000..7eebee6572
--- /dev/null
+++ b/src/ui.c
@@ -0,0 +1,1176 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * 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.
+ */
+
+/*
+ * ui.c: functions that handle the user interface.
+ * 1. Keyboard input stuff, and a bit of windowing stuff. These are called
+ * before the machine specific stuff (mch_*) so that we can call the GUI
+ * stuff instead if the GUI is running.
+ * 2. Clipboard stuff.
+ * 3. Input buffer stuff.
+ */
+
+#include "vim.h"
+
+
+void ui_write(s, len)
+char_u *s;
+int len;
+{
+#ifndef NO_CONSOLE
+ /* Don't output anything in silent mode ("ex -s") unless 'verbose' set */
+ if (!(silent_mode && p_verbose == 0)) {
+ char_u *tofree = NULL;
+
+ if (output_conv.vc_type != CONV_NONE) {
+ /* Convert characters from 'encoding' to 'termencoding'. */
+ tofree = string_convert(&output_conv, s, &len);
+ if (tofree != NULL)
+ s = tofree;
+ }
+
+ mch_write(s, len);
+
+ if (output_conv.vc_type != CONV_NONE)
+ vim_free(tofree);
+ }
+#endif
+}
+
+#if defined(UNIX) || defined(VMS) || defined(PROTO) || defined(WIN3264)
+/*
+ * When executing an external program, there may be some typed characters that
+ * are not consumed by it. Give them back to ui_inchar() and they are stored
+ * here for the next call.
+ */
+static char_u *ta_str = NULL;
+static int ta_off; /* offset for next char to use when ta_str != NULL */
+static int ta_len; /* length of ta_str when it's not NULL*/
+
+void ui_inchar_undo(s, len)
+char_u *s;
+int len;
+{
+ char_u *new;
+ int newlen;
+
+ newlen = len;
+ if (ta_str != NULL)
+ newlen += ta_len - ta_off;
+ new = alloc(newlen);
+ if (new != NULL) {
+ if (ta_str != NULL) {
+ mch_memmove(new, ta_str + ta_off, (size_t)(ta_len - ta_off));
+ mch_memmove(new + ta_len - ta_off, s, (size_t)len);
+ vim_free(ta_str);
+ } else
+ mch_memmove(new, s, (size_t)len);
+ ta_str = new;
+ ta_len = newlen;
+ ta_off = 0;
+ }
+}
+#endif
+
+/*
+ * ui_inchar(): low level input function.
+ * Get characters from the keyboard.
+ * Return the number of characters that are available.
+ * If "wtime" == 0 do not wait for characters.
+ * If "wtime" == -1 wait forever for characters.
+ * If "wtime" > 0 wait "wtime" milliseconds for a character.
+ *
+ * "tb_change_cnt" is the value of typebuf.tb_change_cnt if "buf" points into
+ * it. When typebuf.tb_change_cnt changes (e.g., when a message is received
+ * from a remote client) "buf" can no longer be used. "tb_change_cnt" is NULL
+ * otherwise.
+ */
+int ui_inchar(buf, maxlen, wtime, tb_change_cnt)
+char_u *buf;
+int maxlen;
+long wtime; /* don't use "time", MIPS cannot handle it */
+int tb_change_cnt;
+{
+ int retval = 0;
+
+
+ if (do_profiling == PROF_YES && wtime != 0)
+ prof_inchar_enter();
+
+#ifdef NO_CONSOLE_INPUT
+ /* Don't wait for character input when the window hasn't been opened yet.
+ * Do try reading, this works when redirecting stdin from a file.
+ * Must return something, otherwise we'll loop forever. If we run into
+ * this very often we probably got stuck, exit Vim. */
+ if (no_console_input()) {
+ static int count = 0;
+
+# ifndef NO_CONSOLE
+ retval = mch_inchar(buf, maxlen, (wtime >= 0 && wtime < 10)
+ ? 10L : wtime, tb_change_cnt);
+ if (retval > 0 || typebuf_changed(tb_change_cnt) || wtime >= 0)
+ goto theend;
+# endif
+ if (wtime == -1 && ++count == 1000)
+ read_error_exit();
+ buf[0] = CAR;
+ retval = 1;
+ goto theend;
+ }
+#endif
+
+ /* If we are going to wait for some time or block... */
+ if (wtime == -1 || wtime > 100L) {
+ /* ... allow signals to kill us. */
+ (void)vim_handle_signal(SIGNAL_UNBLOCK);
+
+ /* ... there is no need for CTRL-C to interrupt something, don't let
+ * it set got_int when it was mapped. */
+ if (mapped_ctrl_c)
+ ctrl_c_interrupts = FALSE;
+ }
+
+#ifndef NO_CONSOLE
+ {
+ retval = mch_inchar(buf, maxlen, wtime, tb_change_cnt);
+ }
+#endif
+
+ if (wtime == -1 || wtime > 100L)
+ /* block SIGHUP et al. */
+ (void)vim_handle_signal(SIGNAL_BLOCK);
+
+ ctrl_c_interrupts = TRUE;
+
+#ifdef NO_CONSOLE_INPUT
+theend:
+#endif
+ if (do_profiling == PROF_YES && wtime != 0)
+ prof_inchar_exit();
+ return retval;
+}
+
+/*
+ * return non-zero if a character is available
+ */
+int ui_char_avail() {
+#ifndef NO_CONSOLE
+# ifdef NO_CONSOLE_INPUT
+ if (no_console_input())
+ return 0;
+# endif
+ return mch_char_avail();
+#else
+ return 0;
+#endif
+}
+
+/*
+ * Delay for the given number of milliseconds. If ignoreinput is FALSE then we
+ * cancel the delay if a key is hit.
+ */
+void ui_delay(msec, ignoreinput)
+long msec;
+int ignoreinput;
+{
+ mch_delay(msec, ignoreinput);
+}
+
+/*
+ * If the machine has job control, use it to suspend the program,
+ * otherwise fake it by starting a new shell.
+ * When running the GUI iconify the window.
+ */
+void ui_suspend() {
+ mch_suspend();
+}
+
+#if !defined(UNIX) || !defined(SIGTSTP) || defined(PROTO) || defined(__BEOS__)
+/*
+ * When the OS can't really suspend, call this function to start a shell.
+ * This is never called in the GUI.
+ */
+void suspend_shell() {
+ if (*p_sh == NUL)
+ EMSG(_(e_shellempty));
+ else {
+ MSG_PUTS(_("new shell started\n"));
+ do_shell(NULL, 0);
+ }
+}
+
+#endif
+
+/*
+ * Try to get the current Vim shell size. Put the result in Rows and Columns.
+ * Use the new sizes as defaults for 'columns' and 'lines'.
+ * Return OK when size could be determined, FAIL otherwise.
+ */
+int ui_get_shellsize() {
+ int retval;
+
+ retval = mch_get_shellsize();
+
+ check_shellsize();
+
+ /* adjust the default for 'lines' and 'columns' */
+ if (retval == OK) {
+ set_number_default("lines", Rows);
+ set_number_default("columns", Columns);
+ }
+ return retval;
+}
+
+/*
+ * Set the size of the Vim shell according to Rows and Columns, if possible.
+ * The gui_set_shellsize() or mch_set_shellsize() function will try to set the
+ * new size. If this is not possible, it will adjust Rows and Columns.
+ */
+void ui_set_shellsize(mustset)
+int mustset UNUSED; /* set by the user */
+{
+ mch_set_shellsize();
+}
+
+/*
+ * Called when Rows and/or Columns changed. Adjust scroll region and mouse
+ * region.
+ */
+void ui_new_shellsize() {
+ if (full_screen && !exiting) {
+ mch_new_shellsize();
+ }
+}
+
+void ui_breakcheck() {
+ mch_breakcheck();
+}
+
+/*****************************************************************************
+ * Functions for copying and pasting text between applications.
+ * This is always included in a GUI version, but may also be included when the
+ * clipboard and mouse is available to a terminal version such as xterm.
+ * Note: there are some more functions in ops.c that handle selection stuff.
+ *
+ * Also note that the majority of functions here deal with the X 'primary'
+ * (visible - for Visual mode use) selection, and only that. There are no
+ * versions of these for the 'clipboard' selection, as Visual mode has no use
+ * for them.
+ */
+
+
+/*****************************************************************************
+ * Functions that handle the input buffer.
+ * This is used for any GUI version, and the unix terminal version.
+ *
+ * For Unix, the input characters are buffered to be able to check for a
+ * CTRL-C. This should be done with signals, but I don't know how to do that
+ * in a portable way for a tty in RAW mode.
+ *
+ * For the client-server code in the console the received keys are put in the
+ * input buffer.
+ */
+
+#if defined(USE_INPUT_BUF) || defined(PROTO)
+
+/*
+ * Internal typeahead buffer. Includes extra space for long key code
+ * descriptions which would otherwise overflow. The buffer is considered full
+ * when only this extra space (or part of it) remains.
+ */
+#if defined(FEAT_SUN_WORKSHOP) || defined(FEAT_NETBEANS_INTG) \
+ || defined(FEAT_CLIENTSERVER)
+/*
+ * Sun WorkShop and NetBeans stuff debugger commands into the input buffer.
+ * This requires a larger buffer...
+ * (Madsen) Go with this for remote input as well ...
+ */
+# define INBUFLEN 4096
+#else
+# define INBUFLEN 250
+#endif
+
+static char_u inbuf[INBUFLEN + MAX_KEY_CODE_LEN];
+static int inbufcount = 0; /* number of chars in inbuf[] */
+
+/*
+ * vim_is_input_buf_full(), vim_is_input_buf_empty(), add_to_input_buf(), and
+ * trash_input_buf() are functions for manipulating the input buffer. These
+ * are used by the gui_* calls when a GUI is used to handle keyboard input.
+ */
+
+int vim_is_input_buf_full() {
+ return inbufcount >= INBUFLEN;
+}
+
+int vim_is_input_buf_empty() {
+ return inbufcount == 0;
+}
+
+#if defined(FEAT_OLE) || defined(PROTO)
+int vim_free_in_input_buf() {
+ return INBUFLEN - inbufcount;
+}
+
+#endif
+
+
+/*
+ * Return the current contents of the input buffer and make it empty.
+ * The returned pointer must be passed to set_input_buf() later.
+ */
+char_u * get_input_buf() {
+ garray_T *gap;
+
+ /* We use a growarray to store the data pointer and the length. */
+ gap = (garray_T *)alloc((unsigned)sizeof(garray_T));
+ if (gap != NULL) {
+ /* Add one to avoid a zero size. */
+ gap->ga_data = alloc((unsigned)inbufcount + 1);
+ if (gap->ga_data != NULL)
+ mch_memmove(gap->ga_data, inbuf, (size_t)inbufcount);
+ gap->ga_len = inbufcount;
+ }
+ trash_input_buf();
+ return (char_u *)gap;
+}
+
+/*
+ * Restore the input buffer with a pointer returned from get_input_buf().
+ * The allocated memory is freed, this only works once!
+ */
+void set_input_buf(p)
+char_u *p;
+{
+ garray_T *gap = (garray_T *)p;
+
+ if (gap != NULL) {
+ if (gap->ga_data != NULL) {
+ mch_memmove(inbuf, gap->ga_data, gap->ga_len);
+ inbufcount = gap->ga_len;
+ vim_free(gap->ga_data);
+ }
+ vim_free(gap);
+ }
+}
+
+#if defined(FEAT_GUI) \
+ || defined(FEAT_MOUSE_GPM) || defined(FEAT_SYSMOUSE) \
+ || defined(FEAT_XCLIPBOARD) || defined(VMS) \
+ || defined(FEAT_SNIFF) || defined(FEAT_CLIENTSERVER) \
+ || defined(PROTO)
+/*
+ * Add the given bytes to the input buffer
+ * Special keys start with CSI. A real CSI must have been translated to
+ * CSI KS_EXTRA KE_CSI. K_SPECIAL doesn't require translation.
+ */
+void add_to_input_buf(s, len)
+char_u *s;
+int len;
+{
+ if (inbufcount + len > INBUFLEN + MAX_KEY_CODE_LEN)
+ return; /* Shouldn't ever happen! */
+
+ if ((State & (INSERT|CMDLINE)) && hangul_input_state_get())
+ if ((len = hangul_input_process(s, len)) == 0)
+ return;
+
+ while (len--)
+ inbuf[inbufcount++] = *s++;
+}
+#endif
+
+#if ((defined(FEAT_XIM) || defined(FEAT_DND)) && defined(FEAT_GUI_GTK)) \
+ || defined(FEAT_GUI_MSWIN) \
+ || defined(FEAT_GUI_MAC) \
+ || (defined(FEAT_MBYTE) && defined(FEAT_MBYTE_IME)) \
+ || (defined(FEAT_GUI) && (!defined(USE_ON_FLY_SCROLL) \
+ || defined(FEAT_MENU))) \
+ || defined(PROTO)
+/*
+ * Add "str[len]" to the input buffer while escaping CSI bytes.
+ */
+void add_to_input_buf_csi(char_u *str, int len) {
+ int i;
+ char_u buf[2];
+
+ for (i = 0; i < len; ++i) {
+ add_to_input_buf(str + i, 1);
+ if (str[i] == CSI) {
+ /* Turn CSI into K_CSI. */
+ buf[0] = KS_EXTRA;
+ buf[1] = (int)KE_CSI;
+ add_to_input_buf(buf, 2);
+ }
+ }
+}
+
+#endif
+
+void push_raw_key(s, len)
+char_u *s;
+int len;
+{
+ while (len--)
+ inbuf[inbufcount++] = *s++;
+}
+
+#if defined(FEAT_GUI) || defined(FEAT_EVAL) || defined(FEAT_EX_EXTRA) \
+ || defined(PROTO)
+/* Remove everything from the input buffer. Called when ^C is found */
+void trash_input_buf() {
+ inbufcount = 0;
+}
+
+#endif
+
+/*
+ * Read as much data from the input buffer as possible up to maxlen, and store
+ * it in buf.
+ * Note: this function used to be Read() in unix.c
+ */
+int read_from_input_buf(buf, maxlen)
+char_u *buf;
+long maxlen;
+{
+ if (inbufcount == 0) /* if the buffer is empty, fill it */
+ fill_input_buf(TRUE);
+ if (maxlen > inbufcount)
+ maxlen = inbufcount;
+ mch_memmove(buf, inbuf, (size_t)maxlen);
+ inbufcount -= maxlen;
+ if (inbufcount)
+ mch_memmove(inbuf, inbuf + maxlen, (size_t)inbufcount);
+ return (int)maxlen;
+}
+
+void fill_input_buf(exit_on_error)
+int exit_on_error UNUSED;
+{
+#if defined(UNIX) || defined(OS2) || defined(VMS) || defined(MACOS_X_UNIX)
+ int len;
+ int try;
+ static int did_read_something = FALSE;
+ static char_u *rest = NULL; /* unconverted rest of previous read */
+ static int restlen = 0;
+ int unconverted;
+#endif
+
+#if defined(UNIX) || defined(OS2) || defined(VMS) || defined(MACOS_X_UNIX)
+ if (vim_is_input_buf_full())
+ return;
+ /*
+ * Fill_input_buf() is only called when we really need a character.
+ * If we can't get any, but there is some in the buffer, just return.
+ * If we can't get any, and there isn't any in the buffer, we give up and
+ * exit Vim.
+ */
+
+
+ if (rest != NULL) {
+ /* Use remainder of previous call, starts with an invalid character
+ * that may become valid when reading more. */
+ if (restlen > INBUFLEN - inbufcount)
+ unconverted = INBUFLEN - inbufcount;
+ else
+ unconverted = restlen;
+ mch_memmove(inbuf + inbufcount, rest, unconverted);
+ if (unconverted == restlen) {
+ vim_free(rest);
+ rest = NULL;
+ } else {
+ restlen -= unconverted;
+ mch_memmove(rest, rest + unconverted, restlen);
+ }
+ inbufcount += unconverted;
+ } else
+ unconverted = 0;
+
+ len = 0; /* to avoid gcc warning */
+ for (try = 0; try < 100; ++try) {
+ len = read(read_cmd_fd,
+ (char *)inbuf + inbufcount, (size_t)((INBUFLEN - inbufcount)
+ / input_conv.vc_factor
+ ));
+
+ if (len > 0 || got_int)
+ break;
+ /*
+ * If reading stdin results in an error, continue reading stderr.
+ * This helps when using "foo | xargs vim".
+ */
+ if (!did_read_something && !isatty(read_cmd_fd) && read_cmd_fd == 0) {
+ int m = cur_tmode;
+
+ /* We probably set the wrong file descriptor to raw mode. Switch
+ * back to cooked mode, use another descriptor and set the mode to
+ * what it was. */
+ settmode(TMODE_COOK);
+#ifdef HAVE_DUP
+ /* Use stderr for stdin, also works for shell commands. */
+ close(0);
+ ignored = dup(2);
+#else
+ read_cmd_fd = 2; /* read from stderr instead of stdin */
+#endif
+ settmode(m);
+ }
+ if (!exit_on_error)
+ return;
+ }
+ if (len <= 0 && !got_int)
+ read_error_exit();
+ if (len > 0)
+ did_read_something = TRUE;
+ if (got_int) {
+ /* Interrupted, pretend a CTRL-C was typed. */
+ inbuf[0] = 3;
+ inbufcount = 1;
+ } else {
+ /*
+ * May perform conversion on the input characters.
+ * Include the unconverted rest of the previous call.
+ * If there is an incomplete char at the end it is kept for the next
+ * time, reading more bytes should make conversion possible.
+ * Don't do this in the unlikely event that the input buffer is too
+ * small ("rest" still contains more bytes).
+ */
+ if (input_conv.vc_type != CONV_NONE) {
+ inbufcount -= unconverted;
+ len = convert_input_safe(inbuf + inbufcount,
+ len + unconverted, INBUFLEN - inbufcount,
+ rest == NULL ? &rest : NULL, &restlen);
+ }
+ while (len-- > 0) {
+ /*
+ * if a CTRL-C was typed, remove it from the buffer and set got_int
+ */
+ if (inbuf[inbufcount] == 3 && ctrl_c_interrupts) {
+ /* remove everything typed before the CTRL-C */
+ mch_memmove(inbuf, inbuf + inbufcount, (size_t)(len + 1));
+ inbufcount = 0;
+ got_int = TRUE;
+ }
+ ++inbufcount;
+ }
+ }
+#endif /* UNIX or OS2 or VMS*/
+}
+#endif /* defined(UNIX) || defined(FEAT_GUI) || defined(OS2) || defined(VMS) */
+
+/*
+ * Exit because of an input read error.
+ */
+void read_error_exit() {
+ if (silent_mode) /* Normal way to exit for "ex -s" */
+ getout(0);
+ STRCPY(IObuff, _("Vim: Error reading input, exiting...\n"));
+ preserve_exit();
+}
+
+#if defined(CURSOR_SHAPE) || defined(PROTO)
+/*
+ * May update the shape of the cursor.
+ */
+void ui_cursor_shape() {
+ term_cursor_shape();
+
+
+ conceal_check_cursur_line();
+}
+
+#endif
+
+#if defined(FEAT_CLIPBOARD) || defined(FEAT_GUI) || defined(FEAT_RIGHTLEFT) \
+ || defined(FEAT_MBYTE) || defined(PROTO)
+/*
+ * Check bounds for column number
+ */
+int check_col(col)
+int col;
+{
+ if (col < 0)
+ return 0;
+ if (col >= (int)screen_Columns)
+ return (int)screen_Columns - 1;
+ return col;
+}
+
+/*
+ * Check bounds for row number
+ */
+int check_row(row)
+int row;
+{
+ if (row < 0)
+ return 0;
+ if (row >= (int)screen_Rows)
+ return (int)screen_Rows - 1;
+ return row;
+}
+#endif
+
+/*
+ * Stuff for the X clipboard. Shared between VMS and Unix.
+ */
+
+
+#if defined(FEAT_XCLIPBOARD) || defined(FEAT_GUI_X11) \
+ || defined(FEAT_GUI_GTK) || defined(PROTO)
+/*
+ * Get the contents of the X CUT_BUFFER0 and put it in "cbd".
+ */
+void yank_cut_buffer0(dpy, cbd)
+Display *dpy;
+VimClipboard *cbd;
+{
+ int nbytes = 0;
+ char_u *buffer = (char_u *)XFetchBuffer(dpy, &nbytes, 0);
+
+ if (nbytes > 0) {
+ int done = FALSE;
+
+ /* CUT_BUFFER0 is supposed to be always latin1. Convert to 'enc' when
+ * using a multi-byte encoding. Conversion between two 8-bit
+ * character sets usually fails and the text might actually be in
+ * 'enc' anyway. */
+ if (has_mbyte) {
+ char_u *conv_buf;
+ vimconv_T vc;
+
+ vc.vc_type = CONV_NONE;
+ if (convert_setup(&vc, (char_u *)"latin1", p_enc) == OK) {
+ conv_buf = string_convert(&vc, buffer, &nbytes);
+ if (conv_buf != NULL) {
+ clip_yank_selection(MCHAR, conv_buf, (long)nbytes, cbd);
+ vim_free(conv_buf);
+ done = TRUE;
+ }
+ convert_setup(&vc, NULL, NULL);
+ }
+ }
+ if (!done) /* use the text without conversion */
+ clip_yank_selection(MCHAR, buffer, (long)nbytes, cbd);
+ XFree((void *)buffer);
+ if (p_verbose > 0) {
+ verbose_enter();
+ verb_msg((char_u *)_("Used CUT_BUFFER0 instead of empty selection"));
+ verbose_leave();
+ }
+ }
+}
+#endif
+
+
+/*
+ * Move the cursor to the specified row and column on the screen.
+ * Change current window if necessary. Returns an integer with the
+ * CURSOR_MOVED bit set if the cursor has moved or unset otherwise.
+ *
+ * The MOUSE_FOLD_CLOSE bit is set when clicked on the '-' in a fold column.
+ * The MOUSE_FOLD_OPEN bit is set when clicked on the '+' in a fold column.
+ *
+ * If flags has MOUSE_FOCUS, then the current window will not be changed, and
+ * if the mouse is outside the window then the text will scroll, or if the
+ * mouse was previously on a status line, then the status line may be dragged.
+ *
+ * If flags has MOUSE_MAY_VIS, then VIsual mode will be started before the
+ * cursor is moved unless the cursor was on a status line.
+ * This function returns one of IN_UNKNOWN, IN_BUFFER, IN_STATUS_LINE or
+ * IN_SEP_LINE depending on where the cursor was clicked.
+ *
+ * If flags has MOUSE_MAY_STOP_VIS, then Visual mode will be stopped, unless
+ * the mouse is on the status line of the same window.
+ *
+ * If flags has MOUSE_DID_MOVE, nothing is done if the mouse didn't move since
+ * the last call.
+ *
+ * If flags has MOUSE_SETPOS, nothing is done, only the current position is
+ * remembered.
+ */
+int jump_to_mouse(flags, inclusive, which_button)
+int flags;
+int *inclusive; /* used for inclusive operator, can be NULL */
+int which_button; /* MOUSE_LEFT, MOUSE_RIGHT, MOUSE_MIDDLE */
+{
+ static int on_status_line = 0; /* #lines below bottom of window */
+ static int on_sep_line = 0; /* on separator right of window */
+ static int prev_row = -1;
+ static int prev_col = -1;
+ static win_T *dragwin = NULL; /* window being dragged */
+ static int did_drag = FALSE; /* drag was noticed */
+
+ win_T *wp, *old_curwin;
+ pos_T old_cursor;
+ int count;
+ int first;
+ int row = mouse_row;
+ int col = mouse_col;
+ int mouse_char;
+
+ mouse_past_bottom = FALSE;
+ mouse_past_eol = FALSE;
+
+ if (flags & MOUSE_RELEASED) {
+ /* On button release we may change window focus if positioned on a
+ * status line and no dragging happened. */
+ if (dragwin != NULL && !did_drag)
+ flags &= ~(MOUSE_FOCUS | MOUSE_DID_MOVE);
+ dragwin = NULL;
+ did_drag = FALSE;
+ }
+
+ if ((flags & MOUSE_DID_MOVE)
+ && prev_row == mouse_row
+ && prev_col == mouse_col) {
+retnomove:
+ /* before moving the cursor for a left click which is NOT in a status
+ * line, stop Visual mode */
+ if (on_status_line)
+ return IN_STATUS_LINE;
+ if (on_sep_line)
+ return IN_SEP_LINE;
+ if (flags & MOUSE_MAY_STOP_VIS) {
+ end_visual_mode();
+ redraw_curbuf_later(INVERTED); /* delete the inversion */
+ }
+ return IN_BUFFER;
+ }
+
+ prev_row = mouse_row;
+ prev_col = mouse_col;
+
+ if (flags & MOUSE_SETPOS)
+ goto retnomove; /* ugly goto... */
+
+ /* Remember the character under the mouse, it might be a '-' or '+' in the
+ * fold column. */
+ if (row >= 0 && row < Rows && col >= 0 && col <= Columns
+ && ScreenLines != NULL)
+ mouse_char = ScreenLines[LineOffset[row] + col];
+ else
+ mouse_char = ' ';
+
+ old_curwin = curwin;
+ old_cursor = curwin->w_cursor;
+
+ if (!(flags & MOUSE_FOCUS)) {
+ if (row < 0 || col < 0) /* check if it makes sense */
+ return IN_UNKNOWN;
+
+ /* find the window where the row is in */
+ wp = mouse_find_win(&row, &col);
+ dragwin = NULL;
+ /*
+ * winpos and height may change in win_enter()!
+ */
+ if (row >= wp->w_height) { /* In (or below) status line */
+ on_status_line = row - wp->w_height + 1;
+ dragwin = wp;
+ } else
+ on_status_line = 0;
+ if (col >= wp->w_width) { /* In separator line */
+ on_sep_line = col - wp->w_width + 1;
+ dragwin = wp;
+ } else
+ on_sep_line = 0;
+
+ /* The rightmost character of the status line might be a vertical
+ * separator character if there is no connecting window to the right. */
+ if (on_status_line && on_sep_line) {
+ if (stl_connected(wp))
+ on_sep_line = 0;
+ else
+ on_status_line = 0;
+ }
+
+ /* Before jumping to another buffer, or moving the cursor for a left
+ * click, stop Visual mode. */
+ if (VIsual_active
+ && (wp->w_buffer != curwin->w_buffer
+ || (!on_status_line
+ && !on_sep_line
+ && (
+ wp->w_p_rl ? col < W_WIDTH(wp) - wp->w_p_fdc :
+ col >= wp->w_p_fdc
+ + (cmdwin_type == 0 && wp ==
+ curwin ? 0 : 1)
+ )
+ && (flags & MOUSE_MAY_STOP_VIS)))) {
+ end_visual_mode();
+ redraw_curbuf_later(INVERTED); /* delete the inversion */
+ }
+ if (cmdwin_type != 0 && wp != curwin) {
+ /* A click outside the command-line window: Use modeless
+ * selection if possible. Allow dragging the status lines. */
+ on_sep_line = 0;
+ row = 0;
+ col += wp->w_wincol;
+ wp = curwin;
+ }
+ /* Only change window focus when not clicking on or dragging the
+ * status line. Do change focus when releasing the mouse button
+ * (MOUSE_FOCUS was set above if we dragged first). */
+ if (dragwin == NULL || (flags & MOUSE_RELEASED))
+ win_enter(wp, TRUE); /* can make wp invalid! */
+# ifdef CHECK_DOUBLE_CLICK
+ /* set topline, to be able to check for double click ourselves */
+ if (curwin != old_curwin)
+ set_mouse_topline(curwin);
+# endif
+ if (on_status_line) { /* In (or below) status line */
+ /* Don't use start_arrow() if we're in the same window */
+ if (curwin == old_curwin)
+ return IN_STATUS_LINE;
+ else
+ return IN_STATUS_LINE | CURSOR_MOVED;
+ }
+ if (on_sep_line) { /* In (or below) status line */
+ /* Don't use start_arrow() if we're in the same window */
+ if (curwin == old_curwin)
+ return IN_SEP_LINE;
+ else
+ return IN_SEP_LINE | CURSOR_MOVED;
+ }
+
+ curwin->w_cursor.lnum = curwin->w_topline;
+ } else if (on_status_line && which_button == MOUSE_LEFT) {
+ if (dragwin != NULL) {
+ /* Drag the status line */
+ count = row - dragwin->w_winrow - dragwin->w_height + 1
+ - on_status_line;
+ win_drag_status_line(dragwin, count);
+ did_drag |= count;
+ }
+ return IN_STATUS_LINE; /* Cursor didn't move */
+ } else if (on_sep_line && which_button == MOUSE_LEFT) {
+ if (dragwin != NULL) {
+ /* Drag the separator column */
+ count = col - dragwin->w_wincol - dragwin->w_width + 1
+ - on_sep_line;
+ win_drag_vsep_line(dragwin, count);
+ did_drag |= count;
+ }
+ return IN_SEP_LINE; /* Cursor didn't move */
+ } else { /* keep_window_focus must be TRUE */
+ /* before moving the cursor for a left click, stop Visual mode */
+ if (flags & MOUSE_MAY_STOP_VIS) {
+ end_visual_mode();
+ redraw_curbuf_later(INVERTED); /* delete the inversion */
+ }
+
+
+ row -= W_WINROW(curwin);
+ col -= W_WINCOL(curwin);
+
+ /*
+ * When clicking beyond the end of the window, scroll the screen.
+ * Scroll by however many rows outside the window we are.
+ */
+ if (row < 0) {
+ count = 0;
+ for (first = TRUE; curwin->w_topline > 1; ) {
+ if (curwin->w_topfill < diff_check(curwin, curwin->w_topline))
+ ++count;
+ else
+ count += plines(curwin->w_topline - 1);
+ if (!first && count > -row)
+ break;
+ first = FALSE;
+ hasFolding(curwin->w_topline, &curwin->w_topline, NULL);
+ if (curwin->w_topfill < diff_check(curwin, curwin->w_topline))
+ ++curwin->w_topfill;
+ else {
+ --curwin->w_topline;
+ curwin->w_topfill = 0;
+ }
+ }
+ check_topfill(curwin, FALSE);
+ curwin->w_valid &=
+ ~(VALID_WROW|VALID_CROW|VALID_BOTLINE|VALID_BOTLINE_AP);
+ redraw_later(VALID);
+ row = 0;
+ } else if (row >= curwin->w_height) {
+ count = 0;
+ for (first = TRUE; curwin->w_topline < curbuf->b_ml.ml_line_count; ) {
+ if (curwin->w_topfill > 0)
+ ++count;
+ else
+ count += plines(curwin->w_topline);
+ if (!first && count > row - curwin->w_height + 1)
+ break;
+ first = FALSE;
+ if (hasFolding(curwin->w_topline, NULL, &curwin->w_topline)
+ && curwin->w_topline == curbuf->b_ml.ml_line_count)
+ break;
+ if (curwin->w_topfill > 0)
+ --curwin->w_topfill;
+ else {
+ ++curwin->w_topline;
+ curwin->w_topfill =
+ diff_check_fill(curwin, curwin->w_topline);
+ }
+ }
+ check_topfill(curwin, FALSE);
+ redraw_later(VALID);
+ curwin->w_valid &=
+ ~(VALID_WROW|VALID_CROW|VALID_BOTLINE|VALID_BOTLINE_AP);
+ row = curwin->w_height - 1;
+ } else if (row == 0) {
+ /* When dragging the mouse, while the text has been scrolled up as
+ * far as it goes, moving the mouse in the top line should scroll
+ * the text down (done later when recomputing w_topline). */
+ if (mouse_dragging > 0
+ && curwin->w_cursor.lnum
+ == curwin->w_buffer->b_ml.ml_line_count
+ && curwin->w_cursor.lnum == curwin->w_topline)
+ curwin->w_valid &= ~(VALID_TOPLINE);
+ }
+ }
+
+ /* Check for position outside of the fold column. */
+ if (
+ curwin->w_p_rl ? col < W_WIDTH(curwin) - curwin->w_p_fdc :
+ col >= curwin->w_p_fdc
+ + (cmdwin_type == 0 ? 0 : 1)
+ )
+ mouse_char = ' ';
+
+ /* compute the position in the buffer line from the posn on the screen */
+ if (mouse_comp_pos(curwin, &row, &col, &curwin->w_cursor.lnum))
+ mouse_past_bottom = TRUE;
+
+ /* 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;
+ /* if 'selectmode' contains "mouse", start Select mode */
+ may_start_select('o');
+ setmouse();
+ if (p_smd && msg_silent == 0)
+ redraw_cmdline = TRUE; /* show visual mode later */
+ }
+
+ curwin->w_curswant = col;
+ curwin->w_set_curswant = FALSE; /* May still have been TRUE */
+ if (coladvance(col) == FAIL) { /* Mouse click beyond end of line */
+ if (inclusive != NULL)
+ *inclusive = TRUE;
+ mouse_past_eol = TRUE;
+ } else if (inclusive != NULL)
+ *inclusive = FALSE;
+
+ count = IN_BUFFER;
+ if (curwin != old_curwin || curwin->w_cursor.lnum != old_cursor.lnum
+ || curwin->w_cursor.col != old_cursor.col)
+ count |= CURSOR_MOVED; /* Cursor has moved */
+
+ if (mouse_char == '+')
+ count |= MOUSE_FOLD_OPEN;
+ else if (mouse_char != ' ')
+ count |= MOUSE_FOLD_CLOSE;
+
+ return count;
+}
+
+/*
+ * Compute the position in the buffer line from the posn on the screen in
+ * window "win".
+ * Returns TRUE if the position is below the last line.
+ */
+int mouse_comp_pos(win, rowp, colp, lnump)
+win_T *win;
+int *rowp;
+int *colp;
+linenr_T *lnump;
+{
+ int col = *colp;
+ int row = *rowp;
+ linenr_T lnum;
+ int retval = FALSE;
+ int off;
+ int count;
+
+ if (win->w_p_rl)
+ col = W_WIDTH(win) - 1 - col;
+
+ lnum = win->w_topline;
+
+ while (row > 0) {
+ /* Don't include filler lines in "count" */
+ if (win->w_p_diff
+ && !hasFoldingWin(win, lnum, NULL, NULL, TRUE, NULL)
+ ) {
+ if (lnum == win->w_topline)
+ row -= win->w_topfill;
+ else
+ row -= diff_check_fill(win, lnum);
+ count = plines_win_nofill(win, lnum, TRUE);
+ } else
+ count = plines_win(win, lnum, TRUE);
+ if (count > row)
+ break; /* Position is in this buffer line. */
+ (void)hasFoldingWin(win, lnum, NULL, &lnum, TRUE, NULL);
+ if (lnum == win->w_buffer->b_ml.ml_line_count) {
+ retval = TRUE;
+ break; /* past end of file */
+ }
+ row -= count;
+ ++lnum;
+ }
+
+ if (!retval) {
+ /* Compute the column without wrapping. */
+ off = win_col_off(win) - win_col_off2(win);
+ if (col < off)
+ col = off;
+ col += row * (W_WIDTH(win) - off);
+ /* add skip column (for long wrapping line) */
+ col += win->w_skipcol;
+ }
+
+ if (!win->w_p_wrap)
+ col += win->w_leftcol;
+
+ /* skip line number and fold column in front of the line */
+ col -= win_col_off(win);
+ if (col < 0) {
+ col = 0;
+ }
+
+ *colp = col;
+ *rowp = row;
+ *lnump = lnum;
+ return retval;
+}
+
+/*
+ * Find the window at screen position "*rowp" and "*colp". The positions are
+ * updated to become relative to the top-left of the window.
+ */
+win_T * mouse_find_win(rowp, colp)
+int *rowp;
+int *colp UNUSED;
+{
+ frame_T *fp;
+
+ fp = topframe;
+ *rowp -= firstwin->w_winrow;
+ for (;; ) {
+ if (fp->fr_layout == FR_LEAF)
+ break;
+ if (fp->fr_layout == FR_ROW) {
+ for (fp = fp->fr_child; fp->fr_next != NULL; fp = fp->fr_next) {
+ if (*colp < fp->fr_width)
+ break;
+ *colp -= fp->fr_width;
+ }
+ } else { /* fr_layout == FR_COL */
+ for (fp = fp->fr_child; fp->fr_next != NULL; fp = fp->fr_next) {
+ if (*rowp < fp->fr_height)
+ break;
+ *rowp -= fp->fr_height;
+ }
+ }
+ }
+ return fp->fr_win;
+}
+
+#if defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_GTK) || defined(FEAT_GUI_MAC) \
+ || defined(FEAT_GUI_ATHENA) || defined(FEAT_GUI_MSWIN) \
+ || defined(FEAT_GUI_PHOTON) || defined(PROTO)
+/*
+ * Translate window coordinates to buffer position without any side effects
+ */
+int get_fpos_of_mouse(mpos)
+pos_T *mpos;
+{
+ win_T *wp;
+ int row = mouse_row;
+ int col = mouse_col;
+
+ if (row < 0 || col < 0) /* check if it makes sense */
+ return IN_UNKNOWN;
+
+ /* find the window where the row is in */
+ wp = mouse_find_win(&row, &col);
+ /*
+ * winpos and height may change in win_enter()!
+ */
+ if (row >= wp->w_height) /* In (or below) status line */
+ return IN_STATUS_LINE;
+ if (col >= wp->w_width) /* In vertical separator line */
+ return IN_SEP_LINE;
+
+ if (wp != curwin)
+ return IN_UNKNOWN;
+
+ /* compute the position in the buffer line from the posn on the screen */
+ if (mouse_comp_pos(curwin, &row, &col, &mpos->lnum))
+ return IN_STATUS_LINE; /* past bottom */
+
+ mpos->col = vcol2col(wp, mpos->lnum, col);
+
+ if (mpos->col > 0)
+ --mpos->col;
+ mpos->coladd = 0;
+ return IN_BUFFER;
+}
+
+/*
+ * Convert a virtual (screen) column to a character column.
+ * The first column is one.
+ */
+int vcol2col(wp, lnum, vcol)
+win_T *wp;
+linenr_T lnum;
+int vcol;
+{
+ /* try to advance to the specified column */
+ int count = 0;
+ char_u *ptr;
+ char_u *start;
+
+ start = ptr = ml_get_buf(wp->w_buffer, lnum, FALSE);
+ while (count < vcol && *ptr != NUL) {
+ count += win_lbr_chartabsize(wp, ptr, count, NULL);
+ mb_ptr_adv(ptr);
+ }
+ return (int)(ptr - start);
+}
+#endif
+
+
+
+#if defined(USE_IM_CONTROL) || defined(PROTO)
+/*
+ * Save current Input Method status to specified place.
+ */
+void im_save_status(psave)
+long *psave;
+{
+ /* Don't save when 'imdisable' is set or "xic" is NULL, IM is always
+ * disabled then (but might start later).
+ * Also don't save when inside a mapping, vgetc_im_active has not been set
+ * then.
+ * And don't save when the keys were stuffed (e.g., for a "." command).
+ * And don't save when the GUI is running but our window doesn't have
+ * input focus (e.g., when a find dialog is open). */
+ if (!p_imdisable && KeyTyped && !KeyStuffed
+ ) {
+ /* Do save when IM is on, or IM is off and saved status is on. */
+ if (vgetc_im_active)
+ *psave = B_IMODE_IM;
+ else if (*psave == B_IMODE_IM)
+ *psave = B_IMODE_NONE;
+ }
+}
+#endif
diff --git a/src/undo.c b/src/undo.c
new file mode 100644
index 0000000000..9dfdcbe74c
--- /dev/null
+++ b/src/undo.c
@@ -0,0 +1,2973 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * 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.
+ */
+
+/*
+ * undo.c: multi level undo facility
+ *
+ * The saved lines are stored in a list of lists (one for each buffer):
+ *
+ * b_u_oldhead------------------------------------------------+
+ * |
+ * V
+ * +--------------+ +--------------+ +--------------+
+ * b_u_newhead--->| u_header | | u_header | | u_header |
+ * | uh_next------>| uh_next------>| uh_next---->NULL
+ * NULL<--------uh_prev |<---------uh_prev |<---------uh_prev |
+ * | uh_entry | | uh_entry | | uh_entry |
+ * +--------|-----+ +--------|-----+ +--------|-----+
+ * | | |
+ * V V V
+ * +--------------+ +--------------+ +--------------+
+ * | u_entry | | u_entry | | u_entry |
+ * | ue_next | | ue_next | | ue_next |
+ * +--------|-----+ +--------|-----+ +--------|-----+
+ * | | |
+ * V V V
+ * +--------------+ NULL NULL
+ * | u_entry |
+ * | ue_next |
+ * +--------|-----+
+ * |
+ * V
+ * etc.
+ *
+ * Each u_entry list contains the information for one undo or redo.
+ * curbuf->b_u_curhead points to the header of the last undo (the next redo),
+ * or is NULL if nothing has been undone (end of the branch).
+ *
+ * For keeping alternate undo/redo branches the uh_alt field is used. Thus at
+ * each point in the list a branch may appear for an alternate to redo. The
+ * uh_seq field is numbered sequentially to be able to find a newer or older
+ * branch.
+ *
+ * +---------------+ +---------------+
+ * b_u_oldhead --->| u_header | | u_header |
+ * | uh_alt_next ---->| uh_alt_next ----> NULL
+ * NULL <----- uh_alt_prev |<------ uh_alt_prev |
+ * | uh_prev | | uh_prev |
+ * +-----|---------+ +-----|---------+
+ * | |
+ * V V
+ * +---------------+ +---------------+
+ * | u_header | | u_header |
+ * | uh_alt_next | | uh_alt_next |
+ * b_u_newhead --->| uh_alt_prev | | uh_alt_prev |
+ * | uh_prev | | uh_prev |
+ * +-----|---------+ +-----|---------+
+ * | |
+ * V V
+ * NULL +---------------+ +---------------+
+ * | u_header | | u_header |
+ * | uh_alt_next ---->| uh_alt_next |
+ * | uh_alt_prev |<------ uh_alt_prev |
+ * | uh_prev | | uh_prev |
+ * +-----|---------+ +-----|---------+
+ * | |
+ * etc. etc.
+ *
+ *
+ * All data is allocated and will all be freed when the buffer is unloaded.
+ */
+
+/* Uncomment the next line for including the u_check() function. This warns
+ * for errors in the debug information. */
+/* #define U_DEBUG 1 */
+#define UH_MAGIC 0x18dade /* value for uh_magic when in use */
+#define UE_MAGIC 0xabc123 /* value for ue_magic when in use */
+
+#include "vim.h"
+
+static long get_undolevel __ARGS((void));
+static void u_unch_branch __ARGS((u_header_T *uhp));
+static u_entry_T *u_get_headentry __ARGS((void));
+static void u_getbot __ARGS((void));
+static void u_doit __ARGS((int count));
+static void u_undoredo __ARGS((int undo));
+static void u_undo_end __ARGS((int did_undo, int absolute));
+static void u_add_time __ARGS((char_u *buf, size_t buflen, time_t tt));
+static void u_freeheader __ARGS((buf_T *buf, u_header_T *uhp, u_header_T **uhpp));
+static void u_freebranch __ARGS((buf_T *buf, u_header_T *uhp, u_header_T **uhpp));
+static void u_freeentries __ARGS((buf_T *buf, u_header_T *uhp,
+ u_header_T **uhpp));
+static void u_freeentry __ARGS((u_entry_T *, long));
+static void corruption_error __ARGS((char *mesg, char_u *file_name));
+static void u_free_uhp __ARGS((u_header_T *uhp));
+static size_t fwrite_crypt __ARGS((buf_T *buf UNUSED, char_u *ptr, size_t len,
+ FILE *fp));
+static char_u *read_string_decrypt __ARGS((buf_T *buf UNUSED, FILE *fd, int len));
+static int serialize_header __ARGS((FILE *fp, buf_T *buf, char_u *hash));
+static int serialize_uhp __ARGS((FILE *fp, buf_T *buf, u_header_T *uhp));
+static u_header_T *unserialize_uhp __ARGS((FILE *fp, char_u *file_name));
+static int serialize_uep __ARGS((FILE *fp, buf_T *buf, u_entry_T *uep));
+static u_entry_T *unserialize_uep __ARGS((FILE *fp, int *error,
+ char_u *file_name));
+static void serialize_pos __ARGS((pos_T pos, FILE *fp));
+static void unserialize_pos __ARGS((pos_T *pos, FILE *fp));
+static void serialize_visualinfo __ARGS((visualinfo_T *info, FILE *fp));
+static void unserialize_visualinfo __ARGS((visualinfo_T *info, FILE *fp));
+static void put_header_ptr __ARGS((FILE *fp, u_header_T *uhp));
+
+#define U_ALLOC_LINE(size) lalloc((long_u)(size), FALSE)
+static char_u *u_save_line __ARGS((linenr_T));
+
+/* used in undo_end() to report number of added and deleted lines */
+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 int lastmark = 0;
+
+#if defined(U_DEBUG) || defined(PROTO)
+/*
+ * Check the undo structures for being valid. Print a warning when something
+ * looks wrong.
+ */
+static int seen_b_u_curhead;
+static int seen_b_u_newhead;
+static int header_count;
+
+static void u_check_tree(u_header_T *uhp,
+ u_header_T *exp_uh_next,
+ u_header_T *exp_uh_alt_prev) {
+ u_entry_T *uep;
+
+ if (uhp == NULL)
+ return;
+ ++header_count;
+ if (uhp == curbuf->b_u_curhead && ++seen_b_u_curhead > 1) {
+ EMSG("b_u_curhead found twice (looping?)");
+ return;
+ }
+ if (uhp == curbuf->b_u_newhead && ++seen_b_u_newhead > 1) {
+ EMSG("b_u_newhead found twice (looping?)");
+ return;
+ }
+
+ if (uhp->uh_magic != UH_MAGIC)
+ EMSG("uh_magic wrong (may be using freed memory)");
+ else {
+ /* Check pointers back are correct. */
+ if (uhp->uh_next.ptr != exp_uh_next) {
+ EMSG("uh_next wrong");
+ smsg((char_u *)"expected: 0x%x, actual: 0x%x",
+ exp_uh_next, uhp->uh_next.ptr);
+ }
+ if (uhp->uh_alt_prev.ptr != exp_uh_alt_prev) {
+ EMSG("uh_alt_prev wrong");
+ smsg((char_u *)"expected: 0x%x, actual: 0x%x",
+ exp_uh_alt_prev, uhp->uh_alt_prev.ptr);
+ }
+
+ /* Check the undo tree at this header. */
+ for (uep = uhp->uh_entry; uep != NULL; uep = uep->ue_next) {
+ if (uep->ue_magic != UE_MAGIC) {
+ EMSG("ue_magic wrong (may be using freed memory)");
+ break;
+ }
+ }
+
+ /* Check the next alt tree. */
+ u_check_tree(uhp->uh_alt_next.ptr, uhp->uh_next.ptr, uhp);
+
+ /* Check the next header in this branch. */
+ u_check_tree(uhp->uh_prev.ptr, uhp, NULL);
+ }
+}
+
+static void u_check(int newhead_may_be_NULL) {
+ seen_b_u_newhead = 0;
+ seen_b_u_curhead = 0;
+ header_count = 0;
+
+ u_check_tree(curbuf->b_u_oldhead, NULL, NULL);
+
+ if (seen_b_u_newhead == 0 && curbuf->b_u_oldhead != NULL
+ && !(newhead_may_be_NULL && curbuf->b_u_newhead == NULL))
+ EMSGN("b_u_newhead invalid: 0x%x", curbuf->b_u_newhead);
+ if (curbuf->b_u_curhead != NULL && seen_b_u_curhead == 0)
+ EMSGN("b_u_curhead invalid: 0x%x", curbuf->b_u_curhead);
+ if (header_count != curbuf->b_u_numhead) {
+ EMSG("b_u_numhead invalid");
+ smsg((char_u *)"expected: %ld, actual: %ld",
+ (long)header_count, (long)curbuf->b_u_numhead);
+ }
+}
+
+#endif
+
+/*
+ * Save the current line for both the "u" and "U" command.
+ * Careful: may trigger autocommands that reload the buffer.
+ * Returns OK or FAIL.
+ */
+int u_save_cursor() {
+ return u_save((linenr_T)(curwin->w_cursor.lnum - 1),
+ (linenr_T)(curwin->w_cursor.lnum + 1));
+}
+
+/*
+ * Save the lines between "top" and "bot" for both the "u" and "U" command.
+ * "top" may be 0 and bot may be curbuf->b_ml.ml_line_count + 1.
+ * Careful: may trigger autocommands that reload the buffer.
+ * Returns FAIL when lines could not be saved, OK otherwise.
+ */
+int u_save(top, bot)
+linenr_T top, bot;
+{
+ if (undo_off)
+ return OK;
+
+ if (top > curbuf->b_ml.ml_line_count
+ || top >= bot
+ || bot > curbuf->b_ml.ml_line_count + 1)
+ return FALSE; /* rely on caller to do error messages */
+
+ if (top + 2 == bot)
+ u_saveline((linenr_T)(top + 1));
+
+ return u_savecommon(top, bot, (linenr_T)0, FALSE);
+}
+
+/*
+ * Save the line "lnum" (used by ":s" and "~" command).
+ * The line is replaced, so the new bottom line is lnum + 1.
+ * Careful: may trigger autocommands that reload the buffer.
+ * Returns FAIL when lines could not be saved, OK otherwise.
+ */
+int u_savesub(lnum)
+linenr_T lnum;
+{
+ if (undo_off)
+ return OK;
+
+ return u_savecommon(lnum - 1, lnum + 1, lnum + 1, FALSE);
+}
+
+/*
+ * A new line is inserted before line "lnum" (used by :s command).
+ * The line is inserted, so the new bottom line is lnum + 1.
+ * Careful: may trigger autocommands that reload the buffer.
+ * Returns FAIL when lines could not be saved, OK otherwise.
+ */
+int u_inssub(lnum)
+linenr_T lnum;
+{
+ if (undo_off)
+ return OK;
+
+ return u_savecommon(lnum - 1, lnum, lnum + 1, FALSE);
+}
+
+/*
+ * Save the lines "lnum" - "lnum" + nlines (used by delete command).
+ * The lines are deleted, so the new bottom line is lnum, unless the buffer
+ * becomes empty.
+ * Careful: may trigger autocommands that reload the buffer.
+ * Returns FAIL when lines could not be saved, OK otherwise.
+ */
+int u_savedel(lnum, nlines)
+linenr_T lnum;
+long nlines;
+{
+ if (undo_off)
+ return OK;
+
+ return u_savecommon(lnum - 1, lnum + nlines,
+ nlines == curbuf->b_ml.ml_line_count ? 2 : lnum, FALSE);
+}
+
+/*
+ * Return TRUE when undo is allowed. Otherwise give an error message and
+ * return FALSE.
+ */
+int undo_allowed() {
+ /* Don't allow changes when 'modifiable' is off. */
+ if (!curbuf->b_p_ma) {
+ EMSG(_(e_modifiable));
+ return FALSE;
+ }
+
+#ifdef HAVE_SANDBOX
+ /* In the sandbox it's not allowed to change the text. */
+ if (sandbox != 0) {
+ EMSG(_(e_sandbox));
+ return FALSE;
+ }
+#endif
+
+ /* Don't allow changes in the buffer while editing the cmdline. The
+ * caller of getcmdline() may get confused. */
+ if (textlock != 0) {
+ EMSG(_(e_secure));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/*
+ * Get the undolevle value for the current buffer.
+ */
+static long get_undolevel() {
+ if (curbuf->b_p_ul == NO_LOCAL_UNDOLEVEL)
+ return p_ul;
+ return curbuf->b_p_ul;
+}
+
+/*
+ * Common code for various ways to save text before a change.
+ * "top" is the line above the first changed line.
+ * "bot" is the line below the last changed line.
+ * "newbot" is the new bottom line. Use zero when not known.
+ * "reload" is TRUE when saving for a buffer reload.
+ * Careful: may trigger autocommands that reload the buffer.
+ * Returns FAIL when lines could not be saved, OK otherwise.
+ */
+int u_savecommon(top, bot, newbot, reload)
+linenr_T top, bot;
+linenr_T newbot;
+int reload;
+{
+ linenr_T lnum;
+ long i;
+ u_header_T *uhp;
+ u_header_T *old_curhead;
+ u_entry_T *uep;
+ u_entry_T *prev_uep;
+ long size;
+
+ if (!reload) {
+ /* When making changes is not allowed return FAIL. It's a crude way
+ * to make all change commands fail. */
+ if (!undo_allowed())
+ return FAIL;
+
+
+ /*
+ * Saving text for undo means we are going to make a change. Give a
+ * warning for a read-only file before making the change, so that the
+ * FileChangedRO event can replace the buffer with a read-write version
+ * (e.g., obtained from a source control system).
+ */
+ change_warning(0);
+ if (bot > curbuf->b_ml.ml_line_count + 1) {
+ /* This happens when the FileChangedRO autocommand changes the
+ * file in a way it becomes shorter. */
+ EMSG(_("E881: Line count changed unexpectedly"));
+ return FAIL;
+ }
+ }
+
+#ifdef U_DEBUG
+ u_check(FALSE);
+#endif
+
+ size = bot - top - 1;
+
+ /*
+ * If curbuf->b_u_synced == TRUE make a new header.
+ */
+ if (curbuf->b_u_synced) {
+ /* Need to create new entry in b_changelist. */
+ curbuf->b_new_change = TRUE;
+
+ if (get_undolevel() >= 0) {
+ /*
+ * Make a new header entry. Do this first so that we don't mess
+ * up the undo info when out of memory.
+ */
+ uhp = (u_header_T *)U_ALLOC_LINE(sizeof(u_header_T));
+ if (uhp == NULL)
+ goto nomem;
+#ifdef U_DEBUG
+ uhp->uh_magic = UH_MAGIC;
+#endif
+ } else
+ uhp = NULL;
+
+ /*
+ * If we undid more than we redid, move the entry lists before and
+ * including curbuf->b_u_curhead to an alternate branch.
+ */
+ old_curhead = curbuf->b_u_curhead;
+ if (old_curhead != NULL) {
+ curbuf->b_u_newhead = old_curhead->uh_next.ptr;
+ curbuf->b_u_curhead = NULL;
+ }
+
+ /*
+ * free headers to keep the size right
+ */
+ while (curbuf->b_u_numhead > get_undolevel()
+ && curbuf->b_u_oldhead != NULL) {
+ u_header_T *uhfree = curbuf->b_u_oldhead;
+
+ if (uhfree == old_curhead)
+ /* Can't reconnect the branch, delete all of it. */
+ u_freebranch(curbuf, uhfree, &old_curhead);
+ else if (uhfree->uh_alt_next.ptr == NULL)
+ /* There is no branch, only free one header. */
+ u_freeheader(curbuf, uhfree, &old_curhead);
+ else {
+ /* Free the oldest alternate branch as a whole. */
+ while (uhfree->uh_alt_next.ptr != NULL)
+ uhfree = uhfree->uh_alt_next.ptr;
+ u_freebranch(curbuf, uhfree, &old_curhead);
+ }
+#ifdef U_DEBUG
+ u_check(TRUE);
+#endif
+ }
+
+ if (uhp == NULL) { /* no undo at all */
+ if (old_curhead != NULL)
+ u_freebranch(curbuf, old_curhead, NULL);
+ curbuf->b_u_synced = FALSE;
+ return OK;
+ }
+
+ uhp->uh_prev.ptr = NULL;
+ uhp->uh_next.ptr = curbuf->b_u_newhead;
+ uhp->uh_alt_next.ptr = old_curhead;
+ if (old_curhead != NULL) {
+ uhp->uh_alt_prev.ptr = old_curhead->uh_alt_prev.ptr;
+ if (uhp->uh_alt_prev.ptr != NULL)
+ uhp->uh_alt_prev.ptr->uh_alt_next.ptr = uhp;
+ old_curhead->uh_alt_prev.ptr = uhp;
+ if (curbuf->b_u_oldhead == old_curhead)
+ curbuf->b_u_oldhead = uhp;
+ } else
+ uhp->uh_alt_prev.ptr = NULL;
+ if (curbuf->b_u_newhead != NULL)
+ curbuf->b_u_newhead->uh_prev.ptr = uhp;
+
+ uhp->uh_seq = ++curbuf->b_u_seq_last;
+ curbuf->b_u_seq_cur = uhp->uh_seq;
+ uhp->uh_time = time(NULL);
+ uhp->uh_save_nr = 0;
+ curbuf->b_u_time_cur = uhp->uh_time + 1;
+
+ uhp->uh_walk = 0;
+ uhp->uh_entry = NULL;
+ uhp->uh_getbot_entry = NULL;
+ uhp->uh_cursor = curwin->w_cursor; /* save cursor pos. for undo */
+ if (virtual_active() && curwin->w_cursor.coladd > 0)
+ uhp->uh_cursor_vcol = getviscol();
+ else
+ uhp->uh_cursor_vcol = -1;
+
+ /* save changed and buffer empty flag for undo */
+ uhp->uh_flags = (curbuf->b_changed ? UH_CHANGED : 0) +
+ ((curbuf->b_ml.ml_flags & ML_EMPTY) ? UH_EMPTYBUF : 0);
+
+ /* save named marks and Visual marks for undo */
+ mch_memmove(uhp->uh_namedm, curbuf->b_namedm, sizeof(pos_T) * NMARKS);
+ uhp->uh_visual = curbuf->b_visual;
+
+ curbuf->b_u_newhead = uhp;
+ if (curbuf->b_u_oldhead == NULL)
+ curbuf->b_u_oldhead = uhp;
+ ++curbuf->b_u_numhead;
+ } else {
+ if (get_undolevel() < 0) /* no undo at all */
+ return OK;
+
+ /*
+ * When saving a single line, and it has been saved just before, it
+ * doesn't make sense saving it again. Saves a lot of memory when
+ * making lots of changes inside the same line.
+ * This is only possible if the previous change didn't increase or
+ * decrease the number of lines.
+ * Check the ten last changes. More doesn't make sense and takes too
+ * long.
+ */
+ if (size == 1) {
+ uep = u_get_headentry();
+ prev_uep = NULL;
+ for (i = 0; i < 10; ++i) {
+ if (uep == NULL)
+ break;
+
+ /* If lines have been inserted/deleted we give up.
+ * Also when the line was included in a multi-line save. */
+ if ((curbuf->b_u_newhead->uh_getbot_entry != uep
+ ? (uep->ue_top + uep->ue_size + 1
+ != (uep->ue_bot == 0
+ ? curbuf->b_ml.ml_line_count + 1
+ : uep->ue_bot))
+ : uep->ue_lcount != curbuf->b_ml.ml_line_count)
+ || (uep->ue_size > 1
+ && top >= uep->ue_top
+ && top + 2 <= uep->ue_top + uep->ue_size + 1))
+ break;
+
+ /* If it's the same line we can skip saving it again. */
+ if (uep->ue_size == 1 && uep->ue_top == top) {
+ if (i > 0) {
+ /* It's not the last entry: get ue_bot for the last
+ * entry now. Following deleted/inserted lines go to
+ * the re-used entry. */
+ u_getbot();
+ curbuf->b_u_synced = FALSE;
+
+ /* Move the found entry to become the last entry. The
+ * order of undo/redo doesn't matter for the entries
+ * we move it over, since they don't change the line
+ * count and don't include this line. It does matter
+ * for the found entry if the line count is changed by
+ * the executed command. */
+ prev_uep->ue_next = uep->ue_next;
+ uep->ue_next = curbuf->b_u_newhead->uh_entry;
+ curbuf->b_u_newhead->uh_entry = uep;
+ }
+
+ /* The executed command may change the line count. */
+ if (newbot != 0)
+ uep->ue_bot = newbot;
+ else if (bot > curbuf->b_ml.ml_line_count)
+ uep->ue_bot = 0;
+ else {
+ uep->ue_lcount = curbuf->b_ml.ml_line_count;
+ curbuf->b_u_newhead->uh_getbot_entry = uep;
+ }
+ return OK;
+ }
+ prev_uep = uep;
+ uep = uep->ue_next;
+ }
+ }
+
+ /* find line number for ue_bot for previous u_save() */
+ u_getbot();
+ }
+
+#if !defined(UNIX) && !defined(DJGPP) && !defined(WIN32) && !defined(__EMX__)
+ /*
+ * With Amiga and MSDOS 16 bit we can't handle big undo's, because
+ * then u_alloc_line would have to allocate a block larger than 32K
+ */
+ if (size >= 8000)
+ goto nomem;
+#endif
+
+ /*
+ * add lines in front of entry list
+ */
+ uep = (u_entry_T *)U_ALLOC_LINE(sizeof(u_entry_T));
+ if (uep == NULL)
+ goto nomem;
+ vim_memset(uep, 0, sizeof(u_entry_T));
+#ifdef U_DEBUG
+ uep->ue_magic = UE_MAGIC;
+#endif
+
+ uep->ue_size = size;
+ uep->ue_top = top;
+ if (newbot != 0)
+ uep->ue_bot = newbot;
+ /*
+ * Use 0 for ue_bot if bot is below last line.
+ * Otherwise we have to compute ue_bot later.
+ */
+ else if (bot > curbuf->b_ml.ml_line_count)
+ uep->ue_bot = 0;
+ else {
+ uep->ue_lcount = curbuf->b_ml.ml_line_count;
+ curbuf->b_u_newhead->uh_getbot_entry = uep;
+ }
+
+ if (size > 0) {
+ if ((uep->ue_array = (char_u **)U_ALLOC_LINE(
+ sizeof(char_u *) * size)) == NULL) {
+ u_freeentry(uep, 0L);
+ goto nomem;
+ }
+ for (i = 0, lnum = top + 1; i < size; ++i) {
+ fast_breakcheck();
+ if (got_int) {
+ u_freeentry(uep, i);
+ return FAIL;
+ }
+ if ((uep->ue_array[i] = u_save_line(lnum++)) == NULL) {
+ u_freeentry(uep, i);
+ goto nomem;
+ }
+ }
+ } else
+ uep->ue_array = NULL;
+ uep->ue_next = curbuf->b_u_newhead->uh_entry;
+ curbuf->b_u_newhead->uh_entry = uep;
+ curbuf->b_u_synced = FALSE;
+ undo_undoes = FALSE;
+
+#ifdef U_DEBUG
+ u_check(FALSE);
+#endif
+ return OK;
+
+nomem:
+ msg_silent = 0; /* must display the prompt */
+ if (ask_yesno((char_u *)_("No undo possible; continue anyway"), TRUE)
+ == 'y') {
+ undo_off = TRUE; /* will be reset when character typed */
+ return OK;
+ }
+ do_outofmem_msg((long_u)0);
+ return FAIL;
+}
+
+
+# define UF_START_MAGIC "Vim\237UnDo\345" /* magic at start of undofile */
+# define UF_START_MAGIC_LEN 9
+# define UF_HEADER_MAGIC 0x5fd0 /* magic at start of header */
+# define UF_HEADER_END_MAGIC 0xe7aa /* magic after last header */
+# define UF_ENTRY_MAGIC 0xf518 /* magic at start of entry */
+# define UF_ENTRY_END_MAGIC 0x3581 /* magic after last entry */
+# define UF_VERSION 2 /* 2-byte undofile version number */
+# define UF_VERSION_CRYPT 0x8002 /* idem, encrypted */
+
+/* extra fields for header */
+# define UF_LAST_SAVE_NR 1
+
+/* extra fields for uhp */
+# define UHP_SAVE_NR 1
+
+static char_u e_not_open[] = N_("E828: Cannot open undo file for writing: %s");
+
+/*
+ * Compute the hash for the current buffer text into hash[UNDO_HASH_SIZE].
+ */
+void u_compute_hash(hash)
+char_u *hash;
+{
+ context_sha256_T ctx;
+ linenr_T lnum;
+ char_u *p;
+
+ sha256_start(&ctx);
+ for (lnum = 1; lnum <= curbuf->b_ml.ml_line_count; ++lnum) {
+ p = ml_get(lnum);
+ sha256_update(&ctx, p, (UINT32_T)(STRLEN(p) + 1));
+ }
+ sha256_finish(&ctx, hash);
+}
+
+/*
+ * Return an allocated string of the full path of the target undofile.
+ * When "reading" is TRUE find the file to read, go over all directories in
+ * 'undodir'.
+ * When "reading" is FALSE use the first name where the directory exists.
+ * Returns NULL when there is no place to write or no file to read.
+ */
+char_u * u_get_undo_file_name(buf_ffname, reading)
+char_u *buf_ffname;
+int reading;
+{
+ char_u *dirp;
+ char_u dir_name[IOSIZE + 1];
+ char_u *munged_name = NULL;
+ char_u *undo_file_name = NULL;
+ int dir_len;
+ char_u *p;
+ struct stat st;
+ char_u *ffname = buf_ffname;
+#ifdef HAVE_READLINK
+ char_u fname_buf[MAXPATHL];
+#endif
+
+ if (ffname == NULL)
+ return NULL;
+
+#ifdef HAVE_READLINK
+ /* Expand symlink in the file name, so that we put the undo file with the
+ * actual file instead of with the symlink. */
+ if (resolve_symlink(ffname, fname_buf) == OK)
+ ffname = fname_buf;
+#endif
+
+ /* Loop over 'undodir'. When reading find the first file that exists.
+ * When not reading use the first directory that exists or ".". */
+ dirp = p_udir;
+ while (*dirp != NUL) {
+ dir_len = copy_option_part(&dirp, dir_name, IOSIZE, ",");
+ if (dir_len == 1 && dir_name[0] == '.') {
+ /* Use same directory as the ffname,
+ * "dir/name" -> "dir/.name.un~" */
+ undo_file_name = vim_strnsave(ffname, (int)(STRLEN(ffname) + 5));
+ if (undo_file_name == NULL)
+ break;
+ p = gettail(undo_file_name);
+ mch_memmove(p + 1, p, STRLEN(p) + 1);
+ *p = '.';
+ STRCAT(p, ".un~");
+ } else {
+ dir_name[dir_len] = NUL;
+ if (mch_isdir(dir_name)) {
+ if (munged_name == NULL) {
+ munged_name = vim_strsave(ffname);
+ if (munged_name == NULL)
+ return NULL;
+ for (p = munged_name; *p != NUL; mb_ptr_adv(p))
+ if (vim_ispathsep(*p))
+ *p = '%';
+ }
+ undo_file_name = concat_fnames(dir_name, munged_name, TRUE);
+ }
+ }
+
+ /* When reading check if the file exists. */
+ if (undo_file_name != NULL && (!reading
+ || mch_stat((char *)undo_file_name,
+ &st) >= 0))
+ break;
+ vim_free(undo_file_name);
+ undo_file_name = NULL;
+ }
+
+ vim_free(munged_name);
+ return undo_file_name;
+}
+
+static void corruption_error(mesg, file_name)
+char *mesg;
+char_u *file_name;
+{
+ EMSG3(_("E825: Corrupted undo file (%s): %s"), mesg, file_name);
+}
+
+static void u_free_uhp(uhp)
+u_header_T *uhp;
+{
+ u_entry_T *nuep;
+ u_entry_T *uep;
+
+ uep = uhp->uh_entry;
+ while (uep != NULL) {
+ nuep = uep->ue_next;
+ u_freeentry(uep, uep->ue_size);
+ uep = nuep;
+ }
+ vim_free(uhp);
+}
+
+/*
+ * Like fwrite() but crypt the bytes when 'key' is set.
+ * Returns 1 if successful.
+ */
+static size_t fwrite_crypt(buf, ptr, len, fp)
+buf_T *buf UNUSED;
+char_u *ptr;
+size_t len;
+FILE *fp;
+{
+ char_u *copy;
+ char_u small_buf[100];
+ size_t i;
+
+ if (*buf->b_p_key == NUL)
+ return fwrite(ptr, len, (size_t)1, fp);
+ if (len < 100)
+ copy = small_buf; /* no malloc()/free() for short strings */
+ else {
+ copy = lalloc(len, FALSE);
+ if (copy == NULL)
+ return 0;
+ }
+ crypt_encode(ptr, len, copy);
+ i = fwrite(copy, len, (size_t)1, fp);
+ if (copy != small_buf)
+ vim_free(copy);
+ return i;
+}
+
+/*
+ * Read a string of length "len" from "fd".
+ * When 'key' is set decrypt the bytes.
+ */
+static char_u * read_string_decrypt(buf, fd, len)
+buf_T *buf UNUSED;
+FILE *fd;
+int len;
+{
+ char_u *ptr;
+
+ ptr = read_string(fd, len);
+ if (ptr != NULL && *buf->b_p_key != NUL)
+ crypt_decode(ptr, len);
+ return ptr;
+}
+
+static int serialize_header(fp, buf, hash)
+FILE *fp;
+buf_T *buf;
+char_u *hash;
+{
+ int len;
+
+ /* Start writing, first the magic marker and undo info version. */
+ if (fwrite(UF_START_MAGIC, (size_t)UF_START_MAGIC_LEN, (size_t)1, fp) != 1)
+ return FAIL;
+
+ /* If the buffer is encrypted then all text bytes following will be
+ * encrypted. Numbers and other info is not crypted. */
+ if (*buf->b_p_key != NUL) {
+ char_u *header;
+ int header_len;
+
+ put_bytes(fp, (long_u)UF_VERSION_CRYPT, 2);
+ header = prepare_crypt_write(buf, &header_len);
+ if (header == NULL)
+ return FAIL;
+ len = (int)fwrite(header, (size_t)header_len, (size_t)1, fp);
+ vim_free(header);
+ if (len != 1) {
+ crypt_pop_state();
+ return FAIL;
+ }
+ } else
+ put_bytes(fp, (long_u)UF_VERSION, 2);
+
+
+ /* Write a hash of the buffer text, so that we can verify it is still the
+ * same when reading the buffer text. */
+ if (fwrite(hash, (size_t)UNDO_HASH_SIZE, (size_t)1, fp) != 1)
+ return FAIL;
+
+ /* buffer-specific data */
+ put_bytes(fp, (long_u)buf->b_ml.ml_line_count, 4);
+ len = buf->b_u_line_ptr != NULL ? (int)STRLEN(buf->b_u_line_ptr) : 0;
+ put_bytes(fp, (long_u)len, 4);
+ if (len > 0 && fwrite_crypt(buf, buf->b_u_line_ptr, (size_t)len, fp) != 1)
+ return FAIL;
+ put_bytes(fp, (long_u)buf->b_u_line_lnum, 4);
+ put_bytes(fp, (long_u)buf->b_u_line_colnr, 4);
+
+ /* Undo structures header data */
+ put_header_ptr(fp, buf->b_u_oldhead);
+ put_header_ptr(fp, buf->b_u_newhead);
+ put_header_ptr(fp, buf->b_u_curhead);
+
+ put_bytes(fp, (long_u)buf->b_u_numhead, 4);
+ put_bytes(fp, (long_u)buf->b_u_seq_last, 4);
+ put_bytes(fp, (long_u)buf->b_u_seq_cur, 4);
+ put_time(fp, buf->b_u_time_cur);
+
+ /* Optional fields. */
+ putc(4, fp);
+ putc(UF_LAST_SAVE_NR, fp);
+ put_bytes(fp, (long_u)buf->b_u_save_nr_last, 4);
+
+ putc(0, fp); /* end marker */
+
+ return OK;
+}
+
+static int serialize_uhp(fp, buf, uhp)
+FILE *fp;
+buf_T *buf;
+u_header_T *uhp;
+{
+ int i;
+ u_entry_T *uep;
+
+ if (put_bytes(fp, (long_u)UF_HEADER_MAGIC, 2) == FAIL)
+ return FAIL;
+
+ put_header_ptr(fp, uhp->uh_next.ptr);
+ put_header_ptr(fp, uhp->uh_prev.ptr);
+ put_header_ptr(fp, uhp->uh_alt_next.ptr);
+ put_header_ptr(fp, uhp->uh_alt_prev.ptr);
+ put_bytes(fp, uhp->uh_seq, 4);
+ serialize_pos(uhp->uh_cursor, fp);
+ put_bytes(fp, (long_u)uhp->uh_cursor_vcol, 4);
+ put_bytes(fp, (long_u)uhp->uh_flags, 2);
+ /* Assume NMARKS will stay the same. */
+ for (i = 0; i < NMARKS; ++i)
+ serialize_pos(uhp->uh_namedm[i], fp);
+ serialize_visualinfo(&uhp->uh_visual, fp);
+ put_time(fp, uhp->uh_time);
+
+ /* Optional fields. */
+ putc(4, fp);
+ putc(UHP_SAVE_NR, fp);
+ put_bytes(fp, (long_u)uhp->uh_save_nr, 4);
+
+ putc(0, fp); /* end marker */
+
+ /* Write all the entries. */
+ for (uep = uhp->uh_entry; uep != NULL; uep = uep->ue_next) {
+ put_bytes(fp, (long_u)UF_ENTRY_MAGIC, 2);
+ if (serialize_uep(fp, buf, uep) == FAIL)
+ return FAIL;
+ }
+ put_bytes(fp, (long_u)UF_ENTRY_END_MAGIC, 2);
+ return OK;
+}
+
+static u_header_T * unserialize_uhp(fp, file_name)
+FILE *fp;
+char_u *file_name;
+{
+ u_header_T *uhp;
+ int i;
+ u_entry_T *uep, *last_uep;
+ int c;
+ int error;
+
+ uhp = (u_header_T *)U_ALLOC_LINE(sizeof(u_header_T));
+ if (uhp == NULL)
+ return NULL;
+ vim_memset(uhp, 0, sizeof(u_header_T));
+#ifdef U_DEBUG
+ uhp->uh_magic = UH_MAGIC;
+#endif
+ uhp->uh_next.seq = get4c(fp);
+ uhp->uh_prev.seq = get4c(fp);
+ uhp->uh_alt_next.seq = get4c(fp);
+ uhp->uh_alt_prev.seq = get4c(fp);
+ uhp->uh_seq = get4c(fp);
+ if (uhp->uh_seq <= 0) {
+ corruption_error("uh_seq", file_name);
+ vim_free(uhp);
+ return NULL;
+ }
+ unserialize_pos(&uhp->uh_cursor, fp);
+ uhp->uh_cursor_vcol = get4c(fp);
+ uhp->uh_flags = get2c(fp);
+ for (i = 0; i < NMARKS; ++i)
+ unserialize_pos(&uhp->uh_namedm[i], fp);
+ unserialize_visualinfo(&uhp->uh_visual, fp);
+ uhp->uh_time = get8ctime(fp);
+
+ /* Optional fields. */
+ for (;; ) {
+ int len = getc(fp);
+ int what;
+
+ if (len == 0)
+ break;
+ what = getc(fp);
+ switch (what) {
+ case UHP_SAVE_NR:
+ uhp->uh_save_nr = get4c(fp);
+ break;
+ default:
+ /* field not supported, skip */
+ while (--len >= 0)
+ (void)getc(fp);
+ }
+ }
+
+ /* Unserialize the uep list. */
+ last_uep = NULL;
+ while ((c = get2c(fp)) == UF_ENTRY_MAGIC) {
+ error = FALSE;
+ uep = unserialize_uep(fp, &error, file_name);
+ if (last_uep == NULL)
+ uhp->uh_entry = uep;
+ else
+ last_uep->ue_next = uep;
+ last_uep = uep;
+ if (uep == NULL || error) {
+ u_free_uhp(uhp);
+ return NULL;
+ }
+ }
+ if (c != UF_ENTRY_END_MAGIC) {
+ corruption_error("entry end", file_name);
+ u_free_uhp(uhp);
+ return NULL;
+ }
+
+ return uhp;
+}
+
+/*
+ * Serialize "uep" to "fp".
+ */
+static int serialize_uep(fp, buf, uep)
+FILE *fp;
+buf_T *buf;
+u_entry_T *uep;
+{
+ int i;
+ size_t len;
+
+ put_bytes(fp, (long_u)uep->ue_top, 4);
+ put_bytes(fp, (long_u)uep->ue_bot, 4);
+ put_bytes(fp, (long_u)uep->ue_lcount, 4);
+ put_bytes(fp, (long_u)uep->ue_size, 4);
+ for (i = 0; i < uep->ue_size; ++i) {
+ len = STRLEN(uep->ue_array[i]);
+ if (put_bytes(fp, (long_u)len, 4) == FAIL)
+ return FAIL;
+ if (len > 0 && fwrite_crypt(buf, uep->ue_array[i], len, fp) != 1)
+ return FAIL;
+ }
+ return OK;
+}
+
+static u_entry_T * unserialize_uep(fp, error, file_name)
+FILE *fp;
+int *error;
+char_u *file_name;
+{
+ int i;
+ u_entry_T *uep;
+ char_u **array;
+ char_u *line;
+ int line_len;
+
+ uep = (u_entry_T *)U_ALLOC_LINE(sizeof(u_entry_T));
+ if (uep == NULL)
+ return NULL;
+ vim_memset(uep, 0, sizeof(u_entry_T));
+#ifdef U_DEBUG
+ uep->ue_magic = UE_MAGIC;
+#endif
+ uep->ue_top = get4c(fp);
+ uep->ue_bot = get4c(fp);
+ uep->ue_lcount = get4c(fp);
+ uep->ue_size = get4c(fp);
+ if (uep->ue_size > 0) {
+ array = (char_u **)U_ALLOC_LINE(sizeof(char_u *) * uep->ue_size);
+ if (array == NULL) {
+ *error = TRUE;
+ return uep;
+ }
+ vim_memset(array, 0, sizeof(char_u *) * uep->ue_size);
+ } else
+ array = NULL;
+ uep->ue_array = array;
+
+ for (i = 0; i < uep->ue_size; ++i) {
+ line_len = get4c(fp);
+ if (line_len >= 0)
+ line = read_string_decrypt(curbuf, fp, line_len);
+ else {
+ line = NULL;
+ corruption_error("line length", file_name);
+ }
+ if (line == NULL) {
+ *error = TRUE;
+ return uep;
+ }
+ array[i] = line;
+ }
+ return uep;
+}
+
+/*
+ * Serialize "pos" to "fp".
+ */
+static void serialize_pos(pos, fp)
+pos_T pos;
+FILE *fp;
+{
+ put_bytes(fp, (long_u)pos.lnum, 4);
+ put_bytes(fp, (long_u)pos.col, 4);
+ put_bytes(fp, (long_u)pos.coladd, 4);
+}
+
+/*
+ * Unserialize the pos_T at the current position in fp.
+ */
+static void unserialize_pos(pos, fp)
+pos_T *pos;
+FILE *fp;
+{
+ pos->lnum = get4c(fp);
+ if (pos->lnum < 0)
+ pos->lnum = 0;
+ pos->col = get4c(fp);
+ if (pos->col < 0)
+ pos->col = 0;
+ pos->coladd = get4c(fp);
+ if (pos->coladd < 0)
+ pos->coladd = 0;
+}
+
+/*
+ * Serialize "info" to "fp".
+ */
+static void serialize_visualinfo(info, fp)
+visualinfo_T *info;
+FILE *fp;
+{
+ serialize_pos(info->vi_start, fp);
+ serialize_pos(info->vi_end, fp);
+ put_bytes(fp, (long_u)info->vi_mode, 4);
+ put_bytes(fp, (long_u)info->vi_curswant, 4);
+}
+
+/*
+ * Unserialize the visualinfo_T at the current position in fp.
+ */
+static void unserialize_visualinfo(info, fp)
+visualinfo_T *info;
+FILE *fp;
+{
+ unserialize_pos(&info->vi_start, fp);
+ unserialize_pos(&info->vi_end, fp);
+ info->vi_mode = get4c(fp);
+ info->vi_curswant = get4c(fp);
+}
+
+/*
+ * Write the pointer to an undo header. Instead of writing the pointer itself
+ * we use the sequence number of the header. This is converted back to
+ * pointers when reading. */
+static void put_header_ptr(fp, uhp)
+FILE *fp;
+u_header_T *uhp;
+{
+ put_bytes(fp, (long_u)(uhp != NULL ? uhp->uh_seq : 0), 4);
+}
+
+/*
+ * Write the undo tree in an undo file.
+ * When "name" is not NULL, use it as the name of the undo file.
+ * Otherwise use buf->b_ffname to generate the undo file name.
+ * "buf" must never be null, buf->b_ffname is used to obtain the original file
+ * permissions.
+ * "forceit" is TRUE for ":wundo!", FALSE otherwise.
+ * "hash[UNDO_HASH_SIZE]" must be the hash value of the buffer text.
+ */
+void u_write_undo(name, forceit, buf, hash)
+char_u *name;
+int forceit;
+buf_T *buf;
+char_u *hash;
+{
+ u_header_T *uhp;
+ char_u *file_name;
+ int mark;
+#ifdef U_DEBUG
+ int headers_written = 0;
+#endif
+ int fd;
+ FILE *fp = NULL;
+ int perm;
+ int write_ok = FALSE;
+#ifdef UNIX
+ int st_old_valid = FALSE;
+ struct stat st_old;
+ struct stat st_new;
+#endif
+ int do_crypt = FALSE;
+
+ if (name == NULL) {
+ file_name = u_get_undo_file_name(buf->b_ffname, FALSE);
+ if (file_name == NULL) {
+ if (p_verbose > 0) {
+ verbose_enter();
+ smsg((char_u *)
+ _("Cannot write undo file in any directory in 'undodir'"));
+ verbose_leave();
+ }
+ return;
+ }
+ } else
+ file_name = name;
+
+ /*
+ * Decide about the permission to use for the undo file. If the buffer
+ * has a name use the permission of the original file. Otherwise only
+ * allow the user to access the undo file.
+ */
+ perm = 0600;
+ if (buf->b_ffname != NULL) {
+#ifdef UNIX
+ if (mch_stat((char *)buf->b_ffname, &st_old) >= 0) {
+ perm = st_old.st_mode;
+ st_old_valid = TRUE;
+ }
+#else
+ perm = mch_getperm(buf->b_ffname);
+ if (perm < 0)
+ perm = 0600;
+#endif
+ }
+
+ /* strip any s-bit */
+ perm = perm & 0777;
+
+ /* If the undo file already exists, verify that it actually is an undo
+ * file, and delete it. */
+ if (mch_getperm(file_name) >= 0) {
+ if (name == NULL || !forceit) {
+ /* Check we can read it and it's an undo file. */
+ fd = mch_open((char *)file_name, O_RDONLY|O_EXTRA, 0);
+ if (fd < 0) {
+ if (name != NULL || p_verbose > 0) {
+ if (name == NULL)
+ verbose_enter();
+ smsg((char_u *)
+ _("Will not overwrite with undo file, cannot read: %s"),
+ file_name);
+ if (name == NULL)
+ verbose_leave();
+ }
+ goto theend;
+ } else {
+ char_u mbuf[UF_START_MAGIC_LEN];
+ int len;
+
+ len = read_eintr(fd, mbuf, UF_START_MAGIC_LEN);
+ close(fd);
+ if (len < UF_START_MAGIC_LEN
+ || memcmp(mbuf, UF_START_MAGIC, UF_START_MAGIC_LEN) != 0) {
+ if (name != NULL || p_verbose > 0) {
+ if (name == NULL)
+ verbose_enter();
+ smsg((char_u *)
+ _("Will not overwrite, this is not an undo file: %s"),
+ file_name);
+ if (name == NULL)
+ verbose_leave();
+ }
+ goto theend;
+ }
+ }
+ }
+ mch_remove(file_name);
+ }
+
+ /* If there is no undo information at all, quit here after deleting any
+ * existing undo file. */
+ if (buf->b_u_numhead == 0 && buf->b_u_line_ptr == NULL) {
+ if (p_verbose > 0)
+ verb_msg((char_u *)_("Skipping undo file write, nothing to undo"));
+ goto theend;
+ }
+
+ fd = mch_open((char *)file_name,
+ O_CREAT|O_EXTRA|O_WRONLY|O_EXCL|O_NOFOLLOW, perm);
+ if (fd < 0) {
+ EMSG2(_(e_not_open), file_name);
+ goto theend;
+ }
+ (void)mch_setperm(file_name, perm);
+ if (p_verbose > 0) {
+ verbose_enter();
+ smsg((char_u *)_("Writing undo file: %s"), file_name);
+ verbose_leave();
+ }
+
+#ifdef U_DEBUG
+ /* Check there is no problem in undo info before writing. */
+ u_check(FALSE);
+#endif
+
+#ifdef UNIX
+ /*
+ * Try to set the group of the undo file same as the original file. If
+ * this fails, set the protection bits for the group same as the
+ * protection bits for others.
+ */
+ if (st_old_valid
+ && mch_stat((char *)file_name, &st_new) >= 0
+ && st_new.st_gid != st_old.st_gid
+# ifdef HAVE_FCHOWN /* sequent-ptx lacks fchown() */
+ && fchown(fd, (uid_t)-1, st_old.st_gid) != 0
+# endif
+ )
+ mch_setperm(file_name, (perm & 0707) | ((perm & 07) << 3));
+# ifdef HAVE_SELINUX
+ if (buf->b_ffname != NULL)
+ mch_copy_sec(buf->b_ffname, file_name);
+# endif
+#endif
+
+ fp = fdopen(fd, "w");
+ if (fp == NULL) {
+ EMSG2(_(e_not_open), file_name);
+ close(fd);
+ mch_remove(file_name);
+ goto theend;
+ }
+
+ /* Undo must be synced. */
+ u_sync(TRUE);
+
+ /*
+ * Write the header.
+ */
+ if (serialize_header(fp, buf, hash) == FAIL)
+ goto write_error;
+ if (*buf->b_p_key != NUL)
+ do_crypt = TRUE;
+
+ /*
+ * Iteratively serialize UHPs and their UEPs from the top down.
+ */
+ mark = ++lastmark;
+ uhp = buf->b_u_oldhead;
+ while (uhp != NULL) {
+ /* Serialize current UHP if we haven't seen it */
+ if (uhp->uh_walk != mark) {
+ uhp->uh_walk = mark;
+#ifdef U_DEBUG
+ ++headers_written;
+#endif
+ if (serialize_uhp(fp, buf, uhp) == FAIL)
+ goto write_error;
+ }
+
+ /* Now walk through the tree - algorithm from undo_time(). */
+ if (uhp->uh_prev.ptr != NULL && uhp->uh_prev.ptr->uh_walk != mark)
+ uhp = uhp->uh_prev.ptr;
+ else if (uhp->uh_alt_next.ptr != NULL
+ && uhp->uh_alt_next.ptr->uh_walk != mark)
+ uhp = uhp->uh_alt_next.ptr;
+ else if (uhp->uh_next.ptr != NULL && uhp->uh_alt_prev.ptr == NULL
+ && uhp->uh_next.ptr->uh_walk != mark)
+ uhp = uhp->uh_next.ptr;
+ else if (uhp->uh_alt_prev.ptr != NULL)
+ uhp = uhp->uh_alt_prev.ptr;
+ else
+ uhp = uhp->uh_next.ptr;
+ }
+
+ if (put_bytes(fp, (long_u)UF_HEADER_END_MAGIC, 2) == OK)
+ write_ok = TRUE;
+#ifdef U_DEBUG
+ if (headers_written != buf->b_u_numhead) {
+ EMSGN("Written %ld headers, ...", headers_written);
+ EMSGN("... but numhead is %ld", buf->b_u_numhead);
+ }
+#endif
+
+write_error:
+ fclose(fp);
+ if (!write_ok)
+ EMSG2(_("E829: write error in undo file: %s"), file_name);
+
+#ifdef HAVE_ACL
+ if (buf->b_ffname != NULL) {
+ vim_acl_T acl;
+
+ /* For systems that support ACL: get the ACL from the original file. */
+ acl = mch_get_acl(buf->b_ffname);
+ mch_set_acl(file_name, acl);
+ mch_free_acl(acl);
+ }
+#endif
+
+theend:
+ if (do_crypt)
+ crypt_pop_state();
+ if (file_name != name)
+ vim_free(file_name);
+}
+
+/*
+ * Load the undo tree from an undo file.
+ * If "name" is not NULL use it as the undo file name. This also means being
+ * a bit more verbose.
+ * Otherwise use curbuf->b_ffname to generate the undo file name.
+ * "hash[UNDO_HASH_SIZE]" must be the hash value of the buffer text.
+ */
+void u_read_undo(name, hash, orig_name)
+char_u *name;
+char_u *hash;
+char_u *orig_name;
+{
+ char_u *file_name;
+ FILE *fp;
+ long version, str_len;
+ char_u *line_ptr = NULL;
+ linenr_T line_lnum;
+ colnr_T line_colnr;
+ linenr_T line_count;
+ int num_head = 0;
+ long old_header_seq, new_header_seq, cur_header_seq;
+ long seq_last, seq_cur;
+ long last_save_nr = 0;
+ short old_idx = -1, new_idx = -1, cur_idx = -1;
+ long num_read_uhps = 0;
+ time_t seq_time;
+ int i, j;
+ int c;
+ u_header_T *uhp;
+ u_header_T **uhp_table = NULL;
+ char_u read_hash[UNDO_HASH_SIZE];
+ char_u magic_buf[UF_START_MAGIC_LEN];
+#ifdef U_DEBUG
+ int *uhp_table_used;
+#endif
+#ifdef UNIX
+ struct stat st_orig;
+ struct stat st_undo;
+#endif
+ int do_decrypt = FALSE;
+
+ if (name == NULL) {
+ file_name = u_get_undo_file_name(curbuf->b_ffname, TRUE);
+ if (file_name == NULL)
+ return;
+
+#ifdef UNIX
+ /* For safety we only read an undo file if the owner is equal to the
+ * owner of the text file or equal to the current user. */
+ if (mch_stat((char *)orig_name, &st_orig) >= 0
+ && mch_stat((char *)file_name, &st_undo) >= 0
+ && st_orig.st_uid != st_undo.st_uid
+ && st_undo.st_uid != getuid()) {
+ if (p_verbose > 0) {
+ verbose_enter();
+ smsg((char_u *)_("Not reading undo file, owner differs: %s"),
+ file_name);
+ verbose_leave();
+ }
+ return;
+ }
+#endif
+ } else
+ file_name = name;
+
+ if (p_verbose > 0) {
+ verbose_enter();
+ smsg((char_u *)_("Reading undo file: %s"), file_name);
+ verbose_leave();
+ }
+
+ fp = mch_fopen((char *)file_name, "r");
+ if (fp == NULL) {
+ if (name != NULL || p_verbose > 0)
+ EMSG2(_("E822: Cannot open undo file for reading: %s"), file_name);
+ goto error;
+ }
+
+ /*
+ * Read the undo file header.
+ */
+ if (fread(magic_buf, UF_START_MAGIC_LEN, 1, fp) != 1
+ || memcmp(magic_buf, UF_START_MAGIC, UF_START_MAGIC_LEN) != 0) {
+ EMSG2(_("E823: Not an undo file: %s"), file_name);
+ goto error;
+ }
+ version = get2c(fp);
+ if (version == UF_VERSION_CRYPT) {
+ if (*curbuf->b_p_key == NUL) {
+ EMSG2(_("E832: Non-encrypted file has encrypted undo file: %s"),
+ file_name);
+ goto error;
+ }
+ if (prepare_crypt_read(fp) == FAIL) {
+ EMSG2(_("E826: Undo file decryption failed: %s"), file_name);
+ goto error;
+ }
+ do_decrypt = TRUE;
+ } else if (version != UF_VERSION) {
+ EMSG2(_("E824: Incompatible undo file: %s"), file_name);
+ goto error;
+ }
+
+ if (fread(read_hash, UNDO_HASH_SIZE, 1, fp) != 1) {
+ corruption_error("hash", file_name);
+ goto error;
+ }
+ line_count = (linenr_T)get4c(fp);
+ if (memcmp(hash, read_hash, UNDO_HASH_SIZE) != 0
+ || line_count != curbuf->b_ml.ml_line_count) {
+ if (p_verbose > 0 || name != NULL) {
+ if (name == NULL)
+ verbose_enter();
+ give_warning((char_u *)
+ _("File contents changed, cannot use undo info"), TRUE);
+ if (name == NULL)
+ verbose_leave();
+ }
+ goto error;
+ }
+
+ /* Read undo data for "U" command. */
+ str_len = get4c(fp);
+ if (str_len < 0)
+ goto error;
+ if (str_len > 0)
+ line_ptr = read_string_decrypt(curbuf, fp, str_len);
+ line_lnum = (linenr_T)get4c(fp);
+ line_colnr = (colnr_T)get4c(fp);
+ if (line_lnum < 0 || line_colnr < 0) {
+ corruption_error("line lnum/col", file_name);
+ goto error;
+ }
+
+ /* Begin general undo data */
+ old_header_seq = get4c(fp);
+ new_header_seq = get4c(fp);
+ cur_header_seq = get4c(fp);
+ num_head = get4c(fp);
+ seq_last = get4c(fp);
+ seq_cur = get4c(fp);
+ seq_time = get8ctime(fp);
+
+ /* Optional header fields. */
+ for (;; ) {
+ int len = getc(fp);
+ int what;
+
+ if (len == 0 || len == EOF)
+ break;
+ what = getc(fp);
+ switch (what) {
+ case UF_LAST_SAVE_NR:
+ last_save_nr = get4c(fp);
+ break;
+ default:
+ /* field not supported, skip */
+ while (--len >= 0)
+ (void)getc(fp);
+ }
+ }
+
+ /* uhp_table will store the freshly created undo headers we allocate
+ * until we insert them into curbuf. The table remains sorted by the
+ * sequence numbers of the headers.
+ * When there are no headers uhp_table is NULL. */
+ if (num_head > 0) {
+ uhp_table = (u_header_T **)U_ALLOC_LINE(
+ num_head * sizeof(u_header_T *));
+ if (uhp_table == NULL)
+ goto error;
+ }
+
+ while ((c = get2c(fp)) == UF_HEADER_MAGIC) {
+ if (num_read_uhps >= num_head) {
+ corruption_error("num_head too small", file_name);
+ goto error;
+ }
+
+ uhp = unserialize_uhp(fp, file_name);
+ if (uhp == NULL)
+ goto error;
+ uhp_table[num_read_uhps++] = uhp;
+ }
+
+ if (num_read_uhps != num_head) {
+ corruption_error("num_head", file_name);
+ goto error;
+ }
+ if (c != UF_HEADER_END_MAGIC) {
+ corruption_error("end marker", file_name);
+ goto error;
+ }
+
+#ifdef U_DEBUG
+ uhp_table_used = (int *)alloc_clear(
+ (unsigned)(sizeof(int) * num_head + 1));
+# define SET_FLAG(j) ++ uhp_table_used[j]
+#else
+# define SET_FLAG(j)
+#endif
+
+ /* We have put all of the headers into a table. Now we iterate through the
+ * table and swizzle each sequence number we have stored in uh_*_seq into
+ * a pointer corresponding to the header with that sequence number. */
+ for (i = 0; i < num_head; i++) {
+ uhp = uhp_table[i];
+ if (uhp == NULL)
+ continue;
+ for (j = 0; j < num_head; j++)
+ if (uhp_table[j] != NULL && i != j
+ && uhp_table[i]->uh_seq == uhp_table[j]->uh_seq) {
+ corruption_error("duplicate uh_seq", file_name);
+ goto error;
+ }
+ for (j = 0; j < num_head; j++)
+ if (uhp_table[j] != NULL
+ && uhp_table[j]->uh_seq == uhp->uh_next.seq) {
+ uhp->uh_next.ptr = uhp_table[j];
+ SET_FLAG(j);
+ break;
+ }
+ for (j = 0; j < num_head; j++)
+ if (uhp_table[j] != NULL
+ && uhp_table[j]->uh_seq == uhp->uh_prev.seq) {
+ uhp->uh_prev.ptr = uhp_table[j];
+ SET_FLAG(j);
+ break;
+ }
+ for (j = 0; j < num_head; j++)
+ if (uhp_table[j] != NULL
+ && uhp_table[j]->uh_seq == uhp->uh_alt_next.seq) {
+ uhp->uh_alt_next.ptr = uhp_table[j];
+ SET_FLAG(j);
+ break;
+ }
+ for (j = 0; j < num_head; j++)
+ if (uhp_table[j] != NULL
+ && uhp_table[j]->uh_seq == uhp->uh_alt_prev.seq) {
+ uhp->uh_alt_prev.ptr = uhp_table[j];
+ SET_FLAG(j);
+ break;
+ }
+ if (old_header_seq > 0 && old_idx < 0 && uhp->uh_seq == old_header_seq) {
+ old_idx = i;
+ SET_FLAG(i);
+ }
+ if (new_header_seq > 0 && new_idx < 0 && uhp->uh_seq == new_header_seq) {
+ new_idx = i;
+ SET_FLAG(i);
+ }
+ if (cur_header_seq > 0 && cur_idx < 0 && uhp->uh_seq == cur_header_seq) {
+ cur_idx = i;
+ SET_FLAG(i);
+ }
+ }
+
+ /* Now that we have read the undo info successfully, free the current undo
+ * info and use the info from the file. */
+ u_blockfree(curbuf);
+ curbuf->b_u_oldhead = old_idx < 0 ? NULL : uhp_table[old_idx];
+ curbuf->b_u_newhead = new_idx < 0 ? NULL : uhp_table[new_idx];
+ curbuf->b_u_curhead = cur_idx < 0 ? NULL : uhp_table[cur_idx];
+ curbuf->b_u_line_ptr = line_ptr;
+ curbuf->b_u_line_lnum = line_lnum;
+ curbuf->b_u_line_colnr = line_colnr;
+ curbuf->b_u_numhead = num_head;
+ curbuf->b_u_seq_last = seq_last;
+ curbuf->b_u_seq_cur = seq_cur;
+ curbuf->b_u_time_cur = seq_time;
+ curbuf->b_u_save_nr_last = last_save_nr;
+ curbuf->b_u_save_nr_cur = last_save_nr;
+
+ curbuf->b_u_synced = TRUE;
+ vim_free(uhp_table);
+
+#ifdef U_DEBUG
+ for (i = 0; i < num_head; ++i)
+ if (uhp_table_used[i] == 0)
+ EMSGN("uhp_table entry %ld not used, leaking memory", i);
+ vim_free(uhp_table_used);
+ u_check(TRUE);
+#endif
+
+ if (name != NULL)
+ smsg((char_u *)_("Finished reading undo file %s"), file_name);
+ goto theend;
+
+error:
+ vim_free(line_ptr);
+ if (uhp_table != NULL) {
+ for (i = 0; i < num_read_uhps; i++)
+ if (uhp_table[i] != NULL)
+ u_free_uhp(uhp_table[i]);
+ vim_free(uhp_table);
+ }
+
+theend:
+ if (do_decrypt)
+ crypt_pop_state();
+ if (fp != NULL)
+ fclose(fp);
+ if (file_name != name)
+ vim_free(file_name);
+ return;
+}
+
+
+
+/*
+ * If 'cpoptions' contains 'u': Undo the previous undo or redo (vi compatible).
+ * If 'cpoptions' does not contain 'u': Always undo.
+ */
+void u_undo(count)
+int count;
+{
+ /*
+ * If we get an undo command while executing a macro, we behave like the
+ * original vi. If this happens twice in one macro the result will not
+ * be compatible.
+ */
+ if (curbuf->b_u_synced == FALSE) {
+ u_sync(TRUE);
+ count = 1;
+ }
+
+ if (vim_strchr(p_cpo, CPO_UNDO) == NULL)
+ undo_undoes = TRUE;
+ else
+ undo_undoes = !undo_undoes;
+ u_doit(count);
+}
+
+/*
+ * If 'cpoptions' contains 'u': Repeat the previous undo or redo.
+ * If 'cpoptions' does not contain 'u': Always redo.
+ */
+void u_redo(count)
+int count;
+{
+ if (vim_strchr(p_cpo, CPO_UNDO) == NULL)
+ undo_undoes = FALSE;
+ u_doit(count);
+}
+
+/*
+ * Undo or redo, depending on 'undo_undoes', 'count' times.
+ */
+static void u_doit(startcount)
+int startcount;
+{
+ int count = startcount;
+
+ if (!undo_allowed())
+ return;
+
+ u_newcount = 0;
+ u_oldcount = 0;
+ if (curbuf->b_ml.ml_flags & ML_EMPTY)
+ u_oldcount = -1;
+ while (count--) {
+ /* Do the change warning now, so that it triggers FileChangedRO when
+ * needed. This may cause the file to be reloaded, that must happen
+ * before we do anything, because it may change curbuf->b_u_curhead
+ * and more. */
+ change_warning(0);
+
+ if (undo_undoes) {
+ if (curbuf->b_u_curhead == NULL) /* first undo */
+ curbuf->b_u_curhead = curbuf->b_u_newhead;
+ else if (get_undolevel() > 0) /* multi level undo */
+ /* get next undo */
+ curbuf->b_u_curhead = curbuf->b_u_curhead->uh_next.ptr;
+ /* nothing to undo */
+ if (curbuf->b_u_numhead == 0 || curbuf->b_u_curhead == NULL) {
+ /* stick curbuf->b_u_curhead at end */
+ curbuf->b_u_curhead = curbuf->b_u_oldhead;
+ beep_flush();
+ if (count == startcount - 1) {
+ MSG(_("Already at oldest change"));
+ return;
+ }
+ break;
+ }
+
+ u_undoredo(TRUE);
+ } else {
+ if (curbuf->b_u_curhead == NULL || get_undolevel() <= 0) {
+ beep_flush(); /* nothing to redo */
+ if (count == startcount - 1) {
+ MSG(_("Already at newest change"));
+ return;
+ }
+ break;
+ }
+
+ u_undoredo(FALSE);
+
+ /* Advance for next redo. Set "newhead" when at the end of the
+ * redoable changes. */
+ if (curbuf->b_u_curhead->uh_prev.ptr == NULL)
+ curbuf->b_u_newhead = curbuf->b_u_curhead;
+ curbuf->b_u_curhead = curbuf->b_u_curhead->uh_prev.ptr;
+ }
+ }
+ u_undo_end(undo_undoes, FALSE);
+}
+
+/*
+ * 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(step, sec, file, absolute)
+long step;
+int sec;
+int file;
+int absolute;
+{
+ long target;
+ long closest;
+ long closest_start;
+ long closest_seq = 0;
+ long val;
+ u_header_T *uhp;
+ u_header_T *last;
+ int mark;
+ int nomark;
+ int round;
+ int dosec = sec;
+ int dofile = file;
+ int above = FALSE;
+ int did_undo = TRUE;
+
+ /* First make sure the current undoable change is synced. */
+ if (curbuf->b_u_synced == FALSE)
+ u_sync(TRUE);
+
+ u_newcount = 0;
+ u_oldcount = 0;
+ if (curbuf->b_ml.ml_flags & ML_EMPTY)
+ u_oldcount = -1;
+
+ /* "target" is the node below which we want to be.
+ * Init "closest" to a value we can't reach. */
+ if (absolute) {
+ 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 (step < 0) {
+ /* Going back to a previous write. If there were changes after
+ * the last write, count that as moving one file-write, so
+ * that ":earlier 1f" undoes all changes since the last save. */
+ uhp = curbuf->b_u_curhead;
+ if (uhp != NULL)
+ uhp = uhp->uh_next.ptr;
+ else
+ uhp = curbuf->b_u_newhead;
+ if (uhp != NULL && uhp->uh_save_nr != 0)
+ /* "uh_save_nr" was set in the last block, that means
+ * there were no changes since the last write */
+ target = curbuf->b_u_save_nr_cur + step;
+ else
+ /* count the changes since the last write as one step */
+ target = curbuf->b_u_save_nr_cur + step + 1;
+ if (target <= 0)
+ /* Go to before first write: before the oldest change. Use
+ * the sequence number for that. */
+ dofile = FALSE;
+ } else {
+ /* Moving forward to a newer write. */
+ target = curbuf->b_u_save_nr_cur + step;
+ if (target > curbuf->b_u_save_nr_last) {
+ /* Go to after last write: after the latest change. Use
+ * the sequence number for that. */
+ target = curbuf->b_u_seq_last + 1;
+ dofile = FALSE;
+ }
+ }
+ } else
+ target = curbuf->b_u_seq_cur + step;
+ if (step < 0) {
+ if (target < 0)
+ target = 0;
+ closest = -1;
+ } else {
+ if (dosec)
+ closest = (long)(time(NULL) - starttime + 1);
+ else if (dofile)
+ closest = curbuf->b_u_save_nr_last + 2;
+ else
+ closest = curbuf->b_u_seq_last + 2;
+ if (target >= closest)
+ target = closest - 1;
+ }
+ }
+ closest_start = closest;
+ closest_seq = curbuf->b_u_seq_cur;
+
+ /*
+ * May do this twice:
+ * 1. Search for "target", update "closest" to the best match found.
+ * 2. If "target" not found search for "closest".
+ *
+ * When using the closest time we use the sequence number in the second
+ * round, because there may be several entries with the same time.
+ */
+ for (round = 1; round <= 2; ++round) {
+ /* Find the path from the current state to where we want to go. The
+ * desired state can be anywhere in the undo tree, need to go all over
+ * it. We put "nomark" in uh_walk where we have been without success,
+ * "mark" where it could possibly be. */
+ mark = ++lastmark;
+ nomark = ++lastmark;
+
+ if (curbuf->b_u_curhead == NULL) /* at leaf of the tree */
+ uhp = curbuf->b_u_newhead;
+ else
+ uhp = curbuf->b_u_curhead;
+
+ while (uhp != NULL) {
+ uhp->uh_walk = mark;
+ if (dosec)
+ val = (long)(uhp->uh_time - starttime);
+ else if (dofile)
+ val = uhp->uh_save_nr;
+ else
+ val = uhp->uh_seq;
+
+ if (round == 1 && !(dofile && val == 0)) {
+ /* Remember the header that is closest to the target.
+ * It must be at least in the right direction (checked with
+ * "b_u_seq_cur"). When the timestamp is equal find the
+ * highest/lowest sequence number. */
+ if ((step < 0 ? uhp->uh_seq <= curbuf->b_u_seq_cur
+ : uhp->uh_seq > curbuf->b_u_seq_cur)
+ && ((dosec && val == closest)
+ ? (step < 0
+ ? uhp->uh_seq < closest_seq
+ : uhp->uh_seq > closest_seq)
+ : closest == closest_start
+ || (val > target
+ ? (closest > target
+ ? val - target <= closest - target
+ : val - target <= target - closest)
+ : (closest > target
+ ? target - val <= closest - target
+ : target - val <= target - closest)))) {
+ closest = val;
+ closest_seq = uhp->uh_seq;
+ }
+ }
+
+ /* Quit searching when we found a match. But when searching for a
+ * time we need to continue looking for the best uh_seq. */
+ if (target == val && !dosec) {
+ target = uhp->uh_seq;
+ break;
+ }
+
+ /* go down in the tree if we haven't been there */
+ if (uhp->uh_prev.ptr != NULL && uhp->uh_prev.ptr->uh_walk != nomark
+ && uhp->uh_prev.ptr->uh_walk != mark)
+ uhp = uhp->uh_prev.ptr;
+
+ /* go to alternate branch if we haven't been there */
+ else if (uhp->uh_alt_next.ptr != NULL
+ && uhp->uh_alt_next.ptr->uh_walk != nomark
+ && uhp->uh_alt_next.ptr->uh_walk != mark)
+ uhp = uhp->uh_alt_next.ptr;
+
+ /* go up in the tree if we haven't been there and we are at the
+ * start of alternate branches */
+ else if (uhp->uh_next.ptr != NULL && uhp->uh_alt_prev.ptr == NULL
+ && uhp->uh_next.ptr->uh_walk != nomark
+ && uhp->uh_next.ptr->uh_walk != mark) {
+ /* If still at the start we don't go through this change. */
+ if (uhp == curbuf->b_u_curhead)
+ uhp->uh_walk = nomark;
+ uhp = uhp->uh_next.ptr;
+ } else {
+ /* need to backtrack; mark this node as useless */
+ uhp->uh_walk = nomark;
+ if (uhp->uh_alt_prev.ptr != NULL)
+ uhp = uhp->uh_alt_prev.ptr;
+ else
+ uhp = uhp->uh_next.ptr;
+ }
+ }
+
+ if (uhp != NULL) /* found it */
+ break;
+
+ if (absolute) {
+ EMSGN(_("E830: Undo number %ld not found"), step);
+ return;
+ }
+
+ if (closest == closest_start) {
+ if (step < 0)
+ MSG(_("Already at oldest change"));
+ else
+ MSG(_("Already at newest change"));
+ return;
+ }
+
+ target = closest_seq;
+ 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.
+ */
+ 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)
+ uhp = curbuf->b_u_newhead;
+ else
+ uhp = uhp->uh_next.ptr;
+ if (uhp == NULL || 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 */
+ }
+
+ /*
+ * 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;
+
+ /* 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;
+
+ 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 */
+
+ /* 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;
+ }
+
+ u_undoredo(FALSE);
+
+ /* 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... */
+ EMSG2(_(e_intern2), "undo_time()");
+ break;
+ }
+ }
+ }
+ u_undo_end(did_undo, absolute);
+}
+
+/*
+ * 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(undo)
+int undo;
+{
+ char_u **newarray = NULL;
+ linenr_T oldsize;
+ linenr_T newsize;
+ linenr_T top, bot;
+ linenr_T lnum;
+ linenr_T newlnum = MAXLNUM;
+ long i;
+ u_entry_T *uep, *nuep;
+ u_entry_T *newlist = NULL;
+ int old_flags;
+ int new_flags;
+ pos_T namedm[NMARKS];
+ visualinfo_T visualinfo;
+ int empty_buffer; /* buffer became empty */
+ u_header_T *curhead = curbuf->b_u_curhead;
+
+ /* Don't want autocommands using the undo structures here, they are
+ * invalid till the end. */
+ block_autocmds();
+
+#ifdef U_DEBUG
+ u_check(FALSE);
+#endif
+ old_flags = curhead->uh_flags;
+ new_flags = (curbuf->b_changed ? UH_CHANGED : 0) +
+ ((curbuf->b_ml.ml_flags & ML_EMPTY) ? UH_EMPTYBUF : 0);
+ setpcmark();
+
+ /*
+ * save marks before undo/redo
+ */
+ mch_memmove(namedm, curbuf->b_namedm, sizeof(pos_T) * NMARKS);
+ visualinfo = curbuf->b_visual;
+ curbuf->b_op_start.lnum = curbuf->b_ml.ml_line_count;
+ curbuf->b_op_start.col = 0;
+ curbuf->b_op_end.lnum = 0;
+ curbuf->b_op_end.col = 0;
+
+ for (uep = curhead->uh_entry; uep != NULL; uep = nuep) {
+ top = uep->ue_top;
+ bot = uep->ue_bot;
+ if (bot == 0)
+ bot = curbuf->b_ml.ml_line_count + 1;
+ 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 */
+ return;
+ }
+
+ oldsize = bot - top - 1; /* number of lines before undo */
+ newsize = uep->ue_size; /* number of lines after undo */
+
+ if (top < newlnum) {
+ /* If the saved cursor is somewhere in this undo block, move it to
+ * the remembered position. Makes "gwap" put the cursor back
+ * where it was. */
+ lnum = curhead->uh_cursor.lnum;
+ if (lnum >= top && lnum <= top + newsize + 1) {
+ curwin->w_cursor = curhead->uh_cursor;
+ newlnum = curwin->w_cursor.lnum - 1;
+ } else {
+ /* Use the first line that actually changed. Avoids that
+ * undoing auto-formatting puts the cursor in the previous
+ * line. */
+ for (i = 0; i < newsize && i < oldsize; ++i)
+ if (STRCMP(uep->ue_array[i], ml_get(top + 1 + i)) != 0)
+ break;
+ if (i == newsize && newlnum == MAXLNUM && uep->ue_next == NULL) {
+ newlnum = top;
+ curwin->w_cursor.lnum = newlnum + 1;
+ } else if (i < newsize) {
+ newlnum = top + i;
+ curwin->w_cursor.lnum = newlnum + 1;
+ }
+ }
+ }
+
+ empty_buffer = FALSE;
+
+ /* delete the lines between top and bot and save them in newarray */
+ if (oldsize > 0) {
+ if ((newarray = (char_u **)U_ALLOC_LINE(
+ sizeof(char_u *) * oldsize)) == NULL) {
+ do_outofmem_msg((long_u)(sizeof(char_u *) * oldsize));
+ /*
+ * We have messed up the entry list, repair is impossible.
+ * we have to free the rest of the list.
+ */
+ while (uep != NULL) {
+ nuep = uep->ue_next;
+ u_freeentry(uep, uep->ue_size);
+ uep = nuep;
+ }
+ break;
+ }
+ /* delete backwards, it goes faster in most cases */
+ for (lnum = bot - 1, i = oldsize; --i >= 0; --lnum) {
+ /* what can we do when we run out of memory? */
+ if ((newarray[i] = u_save_line(lnum)) == NULL)
+ do_outofmem_msg((long_u)0);
+ /* remember we deleted the last line in the buffer, and a
+ * dummy empty line will be inserted */
+ if (curbuf->b_ml.ml_line_count == 1)
+ empty_buffer = TRUE;
+ ml_delete(lnum, FALSE);
+ }
+ } else
+ newarray = NULL;
+
+ /* insert the lines in u_array between top and bot */
+ if (newsize) {
+ for (lnum = top, i = 0; i < newsize; ++i, ++lnum) {
+ /*
+ * 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
+ ml_append(lnum, uep->ue_array[i], (colnr_T)0, FALSE);
+ vim_free(uep->ue_array[i]);
+ }
+ vim_free((char_u *)uep->ue_array);
+ }
+
+ /* 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)
+ curbuf->b_op_start.lnum += newsize - oldsize;
+ if (curbuf->b_op_end.lnum > top + oldsize)
+ curbuf->b_op_end.lnum += newsize - oldsize;
+ }
+
+ changed_lines(top + 1, 0, bot, newsize - oldsize);
+
+ /* set '[ and '] mark */
+ if (top + 1 < curbuf->b_op_start.lnum)
+ curbuf->b_op_start.lnum = top + 1;
+ if (newsize == 0 && top + 1 > curbuf->b_op_end.lnum)
+ curbuf->b_op_end.lnum = top + 1;
+ else if (top + newsize > curbuf->b_op_end.lnum)
+ curbuf->b_op_end.lnum = top + newsize;
+
+ u_newcount += newsize;
+ u_oldcount += oldsize;
+ uep->ue_size = oldsize;
+ uep->ue_array = newarray;
+ uep->ue_bot = top + newsize + 1;
+
+ /*
+ * insert this entry in front of the new entry list
+ */
+ nuep = uep->ue_next;
+ uep->ue_next = newlist;
+ newlist = uep;
+ }
+
+ curhead->uh_entry = newlist;
+ curhead->uh_flags = new_flags;
+ if ((old_flags & UH_EMPTYBUF) && bufempty())
+ curbuf->b_ml.ml_flags |= ML_EMPTY;
+ if (old_flags & UH_CHANGED)
+ changed();
+ else
+ unchanged(curbuf, FALSE);
+
+ /*
+ * restore marks from before undo/redo
+ */
+ for (i = 0; i < NMARKS; ++i)
+ if (curhead->uh_namedm[i].lnum != 0) {
+ curbuf->b_namedm[i] = curhead->uh_namedm[i];
+ curhead->uh_namedm[i] = namedm[i];
+ }
+ if (curhead->uh_visual.vi_start.lnum != 0) {
+ curbuf->b_visual = curhead->uh_visual;
+ curhead->uh_visual = visualinfo;
+ }
+
+ /*
+ * If the cursor is only off by one line, put it at the same position as
+ * before starting the change (for the "o" command).
+ * Otherwise the cursor should go to the first undone line.
+ */
+ if (curhead->uh_cursor.lnum + 1 == curwin->w_cursor.lnum
+ && curwin->w_cursor.lnum > 1)
+ --curwin->w_cursor.lnum;
+ if (curwin->w_cursor.lnum <= curbuf->b_ml.ml_line_count) {
+ if (curhead->uh_cursor.lnum == curwin->w_cursor.lnum) {
+ curwin->w_cursor.col = curhead->uh_cursor.col;
+ if (virtual_active() && curhead->uh_cursor_vcol >= 0)
+ coladvance((colnr_T)curhead->uh_cursor_vcol);
+ else
+ curwin->w_cursor.coladd = 0;
+ } else
+ beginline(BL_SOL | BL_FIX);
+ } else {
+ /* We get here with the current cursor line being past the end (eg
+ * after adding lines at the end of the file, and then undoing it).
+ * check_cursor() will move the cursor to the last line. Move it to
+ * the first column here. */
+ curwin->w_cursor.col = 0;
+ curwin->w_cursor.coladd = 0;
+ }
+
+ /* Make sure the cursor is on an existing line and column. */
+ check_cursor();
+
+ /* Remember where we are for "g-" and ":earlier 10s". */
+ curbuf->b_u_seq_cur = curhead->uh_seq;
+ 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;
+
+ /* Remember where we are for ":earlier 1f" and ":later 1f". */
+ if (curhead->uh_save_nr != 0) {
+ if (undo)
+ curbuf->b_u_save_nr_cur = curhead->uh_save_nr - 1;
+ else
+ curbuf->b_u_save_nr_cur = curhead->uh_save_nr;
+ }
+
+ /* The timestamp can be the same for multiple changes, just use the one of
+ * the undone/redone change. */
+ curbuf->b_u_time_cur = curhead->uh_time;
+
+ unblock_autocmds();
+#ifdef U_DEBUG
+ u_check(FALSE);
+#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(did_undo, absolute)
+int did_undo; /* just did an undo */
+int absolute; /* used ":undo N" */
+{
+ char *msgstr;
+ u_header_T *uhp;
+ char_u msgbuf[80];
+
+ 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 */
+ return;
+
+ if (curbuf->b_ml.ml_flags & ML_EMPTY)
+ --u_newcount;
+
+ u_oldcount -= u_newcount;
+ if (u_oldcount == -1)
+ msgstr = N_("more line");
+ else if (u_oldcount < 0)
+ msgstr = N_("more lines");
+ else if (u_oldcount == 1)
+ msgstr = N_("line less");
+ else if (u_oldcount > 1)
+ msgstr = N_("fewer lines");
+ else {
+ u_oldcount = u_newcount;
+ if (u_newcount == 1)
+ msgstr = N_("change");
+ else
+ msgstr = N_("changes");
+ }
+
+ if (curbuf->b_u_curhead != NULL) {
+ /* 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)
+ uhp = curbuf->b_u_curhead;
+ else
+ uhp = curbuf->b_u_curhead->uh_next.ptr;
+ } else
+ uhp = curbuf->b_u_newhead;
+
+ if (uhp == NULL)
+ *msgbuf = NUL;
+ else
+ u_add_time(msgbuf, sizeof(msgbuf), uhp->uh_time);
+
+ {
+ win_T *wp;
+
+ FOR_ALL_WINDOWS(wp)
+ {
+ if (wp->w_buffer == curbuf && wp->w_p_cole > 0)
+ redraw_win_later(wp, NOT_VALID);
+ }
+ }
+
+ smsg((char_u *)_("%ld %s; %s #%ld %s"),
+ u_oldcount < 0 ? -u_oldcount : u_oldcount,
+ _(msgstr),
+ did_undo ? _("before") : _("after"),
+ uhp == NULL ? 0L : uhp->uh_seq,
+ msgbuf);
+}
+
+/*
+ * u_sync: stop adding to the current entry list
+ */
+void u_sync(force)
+int force; /* Also sync when no_u_sync is set. */
+{
+ /* Skip it when already synced or syncing is disabled. */
+ if (curbuf->b_u_synced || (!force && no_u_sync > 0))
+ return;
+ if (get_undolevel() < 0)
+ curbuf->b_u_synced = TRUE; /* no entries, nothing to do */
+ else {
+ u_getbot(); /* compute ue_bot of previous u_save */
+ curbuf->b_u_curhead = NULL;
+ }
+}
+
+/*
+ * ":undolist": List the leafs of the undo tree
+ */
+void ex_undolist(eap)
+exarg_T *eap UNUSED;
+{
+ garray_T ga;
+ u_header_T *uhp;
+ int mark;
+ int nomark;
+ int changes = 1;
+ int i;
+
+ /*
+ * 1: walk the tree to find all leafs, put the info in "ga".
+ * 2: sort the lines
+ * 3: display the list
+ */
+ mark = ++lastmark;
+ nomark = ++lastmark;
+ ga_init2(&ga, (int)sizeof(char *), 20);
+
+ uhp = curbuf->b_u_oldhead;
+ while (uhp != NULL) {
+ if (uhp->uh_prev.ptr == NULL && uhp->uh_walk != nomark
+ && uhp->uh_walk != mark) {
+ if (ga_grow(&ga, 1) == FAIL)
+ break;
+ vim_snprintf((char *)IObuff, IOSIZE, "%6ld %7ld ",
+ uhp->uh_seq, changes);
+ u_add_time(IObuff + STRLEN(IObuff), IOSIZE - STRLEN(IObuff),
+ uhp->uh_time);
+ if (uhp->uh_save_nr > 0) {
+ while (STRLEN(IObuff) < 33)
+ STRCAT(IObuff, " ");
+ vim_snprintf_add((char *)IObuff, IOSIZE,
+ " %3ld", uhp->uh_save_nr);
+ }
+ ((char_u **)(ga.ga_data))[ga.ga_len++] = vim_strsave(IObuff);
+ }
+
+ uhp->uh_walk = mark;
+
+ /* go down in the tree if we haven't been there */
+ if (uhp->uh_prev.ptr != NULL && uhp->uh_prev.ptr->uh_walk != nomark
+ && uhp->uh_prev.ptr->uh_walk != mark) {
+ uhp = uhp->uh_prev.ptr;
+ ++changes;
+ }
+ /* go to alternate branch if we haven't been there */
+ else if (uhp->uh_alt_next.ptr != NULL
+ && uhp->uh_alt_next.ptr->uh_walk != nomark
+ && uhp->uh_alt_next.ptr->uh_walk != mark)
+ uhp = uhp->uh_alt_next.ptr;
+
+ /* go up in the tree if we haven't been there and we are at the
+ * start of alternate branches */
+ else if (uhp->uh_next.ptr != NULL && uhp->uh_alt_prev.ptr == NULL
+ && uhp->uh_next.ptr->uh_walk != nomark
+ && uhp->uh_next.ptr->uh_walk != mark) {
+ uhp = uhp->uh_next.ptr;
+ --changes;
+ } else {
+ /* need to backtrack; mark this node as done */
+ uhp->uh_walk = nomark;
+ if (uhp->uh_alt_prev.ptr != NULL)
+ uhp = uhp->uh_alt_prev.ptr;
+ else {
+ uhp = uhp->uh_next.ptr;
+ --changes;
+ }
+ }
+ }
+
+ if (ga.ga_len == 0)
+ MSG(_("Nothing to undo"));
+ else {
+ 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 (i = 0; i < ga.ga_len && !got_int; ++i) {
+ msg_putchar('\n');
+ if (got_int)
+ break;
+ msg_puts(((char_u **)ga.ga_data)[i]);
+ }
+ msg_end();
+
+ ga_clear_strings(&ga);
+ }
+}
+
+/*
+ * Put the timestamp of an undo header in "buf[buflen]" in a nice format.
+ */
+static void u_add_time(buf, buflen, tt)
+char_u *buf;
+size_t buflen;
+time_t tt;
+{
+#ifdef HAVE_STRFTIME
+ struct tm *curtime;
+
+ if (time(NULL) - tt >= 100) {
+ curtime = localtime(&tt);
+ if (time(NULL) - tt < (60L * 60L * 12L))
+ /* within 12 hours */
+ (void)strftime((char *)buf, buflen, "%H:%M:%S", curtime);
+ else
+ /* longer ago */
+ (void)strftime((char *)buf, buflen, "%Y/%m/%d %H:%M:%S", curtime);
+ } else
+#endif
+ vim_snprintf((char *)buf, buflen, _("%ld seconds ago"),
+ (long)(time(NULL) - tt));
+}
+
+/*
+ * ":undojoin": continue adding to the last entry list
+ */
+void ex_undojoin(eap)
+exarg_T *eap UNUSED;
+{
+ 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 */
+ }
+}
+
+/*
+ * Called after writing or reloading the file and setting b_changed to FALSE.
+ * Now an undo means that the buffer is modified.
+ */
+void u_unchanged(buf)
+buf_T *buf;
+{
+ u_unch_branch(buf->b_u_oldhead);
+ buf->b_did_warn = FALSE;
+}
+
+/*
+ * After reloading a buffer which was saved for 'undoreload': Find the first
+ * line that was changed and set the cursor there.
+ */
+void u_find_first_changed() {
+ u_header_T *uhp = curbuf->b_u_newhead;
+ u_entry_T *uep;
+ linenr_T lnum;
+
+ if (curbuf->b_u_curhead != NULL || uhp == NULL)
+ return; /* undid something in an autocmd? */
+
+ /* Check that the last undo block was for the whole file. */
+ uep = uhp->uh_entry;
+ if (uep->ue_top != 0 || uep->ue_bot != 0)
+ return;
+
+ for (lnum = 1; lnum < curbuf->b_ml.ml_line_count
+ && lnum <= uep->ue_size; ++lnum)
+ if (STRCMP(ml_get_buf(curbuf, lnum, FALSE),
+ uep->ue_array[lnum - 1]) != 0) {
+ clearpos(&(uhp->uh_cursor));
+ uhp->uh_cursor.lnum = lnum;
+ return;
+ }
+ if (curbuf->b_ml.ml_line_count != uep->ue_size) {
+ /* lines added or deleted at the end, put the cursor there */
+ clearpos(&(uhp->uh_cursor));
+ uhp->uh_cursor.lnum = lnum;
+ }
+}
+
+/*
+ * Increase the write count, store it in the last undo header, what would be
+ * used for "u".
+ */
+void u_update_save_nr(buf)
+buf_T *buf;
+{
+ u_header_T *uhp;
+
+ ++buf->b_u_save_nr_last;
+ buf->b_u_save_nr_cur = buf->b_u_save_nr_last;
+ uhp = buf->b_u_curhead;
+ if (uhp != NULL)
+ uhp = uhp->uh_next.ptr;
+ else
+ uhp = buf->b_u_newhead;
+ if (uhp != NULL)
+ uhp->uh_save_nr = buf->b_u_save_nr_last;
+}
+
+static void u_unch_branch(uhp)
+u_header_T *uhp;
+{
+ u_header_T *uh;
+
+ for (uh = uhp; uh != NULL; uh = uh->uh_prev.ptr) {
+ uh->uh_flags |= UH_CHANGED;
+ if (uh->uh_alt_next.ptr != NULL)
+ u_unch_branch(uh->uh_alt_next.ptr); /* recursive */
+ }
+}
+
+/*
+ * Get pointer to last added entry.
+ * If it's not valid, give an error message and return NULL.
+ */
+static u_entry_T * u_get_headentry() {
+ if (curbuf->b_u_newhead == NULL || curbuf->b_u_newhead->uh_entry == NULL) {
+ EMSG(_("E439: undo list corrupt"));
+ return NULL;
+ }
+ return curbuf->b_u_newhead->uh_entry;
+}
+
+/*
+ * u_getbot(): compute the line number of the previous u_save
+ * It is called only when b_u_synced is FALSE.
+ */
+static void u_getbot() {
+ u_entry_T *uep;
+ linenr_T extra;
+
+ uep = u_get_headentry(); /* check for corrupt undo list */
+ if (uep == NULL)
+ return;
+
+ uep = curbuf->b_u_newhead->uh_getbot_entry;
+ if (uep != NULL) {
+ /*
+ * the new ue_bot is computed from the number of lines that has been
+ * inserted (0 - deleted) since calling u_save. This is equal to the
+ * old line count subtracted from the current line count.
+ */
+ 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 */
+ }
+
+ curbuf->b_u_newhead->uh_getbot_entry = NULL;
+ }
+
+ curbuf->b_u_synced = TRUE;
+}
+
+/*
+ * Free one header "uhp" and its entry list and adjust the pointers.
+ */
+static void u_freeheader(buf, uhp, uhpp)
+buf_T *buf;
+u_header_T *uhp;
+u_header_T **uhpp; /* if not NULL reset when freeing this header */
+{
+ u_header_T *uhap;
+
+ /* When there is an alternate redo list free that branch completely,
+ * because we can never go there. */
+ if (uhp->uh_alt_next.ptr != NULL)
+ u_freebranch(buf, uhp->uh_alt_next.ptr, uhpp);
+
+ if (uhp->uh_alt_prev.ptr != NULL)
+ uhp->uh_alt_prev.ptr->uh_alt_next.ptr = NULL;
+
+ /* Update the links in the list to remove the header. */
+ if (uhp->uh_next.ptr == NULL)
+ buf->b_u_oldhead = uhp->uh_prev.ptr;
+ else
+ uhp->uh_next.ptr->uh_prev.ptr = uhp->uh_prev.ptr;
+
+ if (uhp->uh_prev.ptr == NULL)
+ buf->b_u_newhead = uhp->uh_next.ptr;
+ else
+ for (uhap = uhp->uh_prev.ptr; uhap != NULL;
+ uhap = uhap->uh_alt_next.ptr)
+ uhap->uh_next.ptr = uhp->uh_next.ptr;
+
+ u_freeentries(buf, uhp, uhpp);
+}
+
+/*
+ * Free an alternate branch and any following alternate branches.
+ */
+static void u_freebranch(buf, uhp, uhpp)
+buf_T *buf;
+u_header_T *uhp;
+u_header_T **uhpp; /* if not NULL reset when freeing this header */
+{
+ u_header_T *tofree, *next;
+
+ /* If this is the top branch we may need to use u_freeheader() to update
+ * all the pointers. */
+ if (uhp == buf->b_u_oldhead) {
+ while (buf->b_u_oldhead != NULL)
+ u_freeheader(buf, buf->b_u_oldhead, uhpp);
+ return;
+ }
+
+ if (uhp->uh_alt_prev.ptr != NULL)
+ uhp->uh_alt_prev.ptr->uh_alt_next.ptr = NULL;
+
+ next = uhp;
+ while (next != NULL) {
+ tofree = next;
+ if (tofree->uh_alt_next.ptr != NULL)
+ u_freebranch(buf, tofree->uh_alt_next.ptr, uhpp); /* recursive */
+ next = tofree->uh_prev.ptr;
+ u_freeentries(buf, tofree, uhpp);
+ }
+}
+
+/*
+ * Free all the undo entries for one header and the header itself.
+ * This means that "uhp" is invalid when returning.
+ */
+static void u_freeentries(buf, uhp, uhpp)
+buf_T *buf;
+u_header_T *uhp;
+u_header_T **uhpp; /* if not NULL reset when freeing this header */
+{
+ u_entry_T *uep, *nuep;
+
+ /* Check for pointers to the header that become invalid now. */
+ if (buf->b_u_curhead == uhp)
+ buf->b_u_curhead = NULL;
+ if (buf->b_u_newhead == uhp)
+ buf->b_u_newhead = NULL; /* freeing the newest entry */
+ if (uhpp != NULL && uhp == *uhpp)
+ *uhpp = NULL;
+
+ for (uep = uhp->uh_entry; uep != NULL; uep = nuep) {
+ nuep = uep->ue_next;
+ u_freeentry(uep, uep->ue_size);
+ }
+
+#ifdef U_DEBUG
+ uhp->uh_magic = 0;
+#endif
+ vim_free((char_u *)uhp);
+ --buf->b_u_numhead;
+}
+
+/*
+ * free entry 'uep' and 'n' lines in uep->ue_array[]
+ */
+static void u_freeentry(uep, n)
+u_entry_T *uep;
+long n;
+{
+ while (n > 0)
+ vim_free(uep->ue_array[--n]);
+ vim_free((char_u *)uep->ue_array);
+#ifdef U_DEBUG
+ uep->ue_magic = 0;
+#endif
+ vim_free((char_u *)uep);
+}
+
+/*
+ * invalidate the undo buffer; called when storage has already been released
+ */
+void u_clearall(buf)
+buf_T *buf;
+{
+ buf->b_u_newhead = buf->b_u_oldhead = buf->b_u_curhead = NULL;
+ buf->b_u_synced = TRUE;
+ buf->b_u_numhead = 0;
+ buf->b_u_line_ptr = NULL;
+ buf->b_u_line_lnum = 0;
+}
+
+/*
+ * save the line "lnum" for the "U" command
+ */
+void u_saveline(lnum)
+linenr_T lnum;
+{
+ if (lnum == curbuf->b_u_line_lnum) /* line is already saved */
+ return;
+ if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count) /* should never happen */
+ return;
+ u_clearline();
+ curbuf->b_u_line_lnum = lnum;
+ if (curwin->w_cursor.lnum == lnum)
+ curbuf->b_u_line_colnr = curwin->w_cursor.col;
+ else
+ curbuf->b_u_line_colnr = 0;
+ if ((curbuf->b_u_line_ptr = u_save_line(lnum)) == NULL)
+ do_outofmem_msg((long_u)0);
+}
+
+/*
+ * clear the line saved for the "U" command
+ * (this is used externally for crossing a line while in insert mode)
+ */
+void u_clearline() {
+ if (curbuf->b_u_line_ptr != NULL) {
+ vim_free(curbuf->b_u_line_ptr);
+ curbuf->b_u_line_ptr = NULL;
+ curbuf->b_u_line_lnum = 0;
+ }
+}
+
+/*
+ * Implementation of the "U" command.
+ * Differentiation from vi: "U" can be undone with the next "U".
+ * We also allow the cursor to be in another line.
+ * Careful: may trigger autocommands that reload the buffer.
+ */
+void u_undoline() {
+ colnr_T t;
+ char_u *oldp;
+
+ if (undo_off)
+ return;
+
+ if (curbuf->b_u_line_ptr == NULL
+ || curbuf->b_u_line_lnum > curbuf->b_ml.ml_line_count) {
+ beep_flush();
+ return;
+ }
+
+ /* first save the line for the 'u' command */
+ if (u_savecommon(curbuf->b_u_line_lnum - 1,
+ curbuf->b_u_line_lnum + 1, (linenr_T)0, FALSE) == FAIL)
+ return;
+ oldp = u_save_line(curbuf->b_u_line_lnum);
+ if (oldp == NULL) {
+ do_outofmem_msg((long_u)0);
+ return;
+ }
+ ml_replace(curbuf->b_u_line_lnum, curbuf->b_u_line_ptr, TRUE);
+ changed_bytes(curbuf->b_u_line_lnum, 0);
+ vim_free(curbuf->b_u_line_ptr);
+ curbuf->b_u_line_ptr = oldp;
+
+ t = curbuf->b_u_line_colnr;
+ if (curwin->w_cursor.lnum == curbuf->b_u_line_lnum)
+ curbuf->b_u_line_colnr = curwin->w_cursor.col;
+ curwin->w_cursor.col = t;
+ curwin->w_cursor.lnum = curbuf->b_u_line_lnum;
+ check_cursor_col();
+}
+
+/*
+ * Free all allocated memory blocks for the buffer 'buf'.
+ */
+void u_blockfree(buf)
+buf_T *buf;
+{
+ while (buf->b_u_oldhead != NULL)
+ u_freeheader(buf, buf->b_u_oldhead, NULL);
+ vim_free(buf->b_u_line_ptr);
+}
+
+/*
+ * u_save_line(): allocate memory and copy line 'lnum' into it.
+ * Returns NULL when out of memory.
+ */
+static char_u * u_save_line(lnum)
+linenr_T lnum;
+{
+ return vim_strsave(ml_get(lnum));
+}
+
+/*
+ * Check if the 'modified' flag is set, or 'ff' has changed (only need to
+ * check the first character, because it can only be "dos", "unix" or "mac").
+ * "nofile" and "scratch" type buffers are considered to always be unchanged.
+ */
+int bufIsChanged(buf)
+buf_T *buf;
+{
+ return
+ !bt_dontwrite(buf) &&
+ (buf->b_changed || file_ff_differs(buf, TRUE));
+}
+
+int curbufIsChanged() {
+ return
+ !bt_dontwrite(curbuf) &&
+ (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(first_uhp, list)
+u_header_T *first_uhp;
+list_T *list;
+{
+ u_header_T *uhp = first_uhp;
+ dict_T *dict;
+
+ while (uhp != NULL) {
+ dict = dict_alloc();
+ if (dict == NULL)
+ return;
+ 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);
+
+ if (uhp->uh_alt_next.ptr != NULL) {
+ list_T *alt_list = list_alloc();
+
+ if (alt_list != NULL) {
+ /* Recursive call to add alternate undo tree. */
+ u_eval_tree(uhp->uh_alt_next.ptr, alt_list);
+ dict_add_list(dict, "alt", alt_list);
+ }
+ }
+
+ list_append_dict(list, dict);
+ uhp = uhp->uh_prev.ptr;
+ }
+}
diff --git a/src/version.c b/src/version.c
index 0636348dae..62a7aa8bc8 100644
--- a/src/version.c
+++ b/src/version.c
@@ -1,63 +1,978 @@
-/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+/* vi:set ts=8 sts=4 sw=4:
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
+ * VIM - Vi IMproved by Bram Moolenaar
*
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
+ * 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.
*/
-#include "uv.h"
+#include "vim.h"
+
- /*
- * Versions with an even minor version (e.g. 0.6.1 or 1.0.4) are API and ABI
- * stable. When the minor version is odd, the API can change between patch
- * releases. Make sure you update the -soname directives in config-unix.mk
- * and uv.gyp whenever you bump UV_VERSION_MAJOR or UV_VERSION_MINOR (but
- * not UV_VERSION_PATCH.)
+/*
+ * Vim originated from Stevie version 3.6 (Fish disk 217) by GRWalter (Fred)
+ * It has been changed beyond recognition since then.
+ *
+ * Differences between version 6.x and 7.x can be found with ":help version7".
+ * Differences between version 5.x and 6.x can be found with ":help version6".
+ * Differences between version 4.x and 5.x can be found with ":help version5".
+ * Differences between version 3.0 and 4.x can be found with ":help version4".
+ * All the remarks about older versions have been removed, they are not very
+ * interesting.
*/
-#define UV_VERSION_MAJOR 0
-#define UV_VERSION_MINOR 11
-#define UV_VERSION_PATCH 19
-#define UV_VERSION_IS_RELEASE 1
+#include "version.h"
+
+char *Version = VIM_VERSION_SHORT;
+static char *mediumVersion = VIM_VERSION_MEDIUM;
+
+#if defined(HAVE_DATE_TIME) || defined(PROTO)
+char *longVersion = VIM_VERSION_LONG_DATE __DATE__ " " __TIME__ ")";
+#else
+char *longVersion = VIM_VERSION_LONG;
+#endif
+
+static void list_features __ARGS((void));
+static void version_msg __ARGS((char *s));
+static char *(features[]) =
+{
+#ifdef HAVE_ACL
+ "+acl",
+#else
+ "-acl",
+#endif
+ "+arabic",
+ "+autocmd",
+ "-balloon_eval",
+ "-browse",
+#ifdef NO_BUILTIN_TCAPS
+ "-builtin_terms",
+#endif
+#ifdef SOME_BUILTIN_TCAPS
+ "+builtin_terms",
+#endif
+#ifdef ALL_BUILTIN_TCAPS
+ "++builtin_terms",
+#endif
+ "+byte_offset",
+ "+cindent",
+ "-clientserver",
+ "-clipboard",
+ "+cmdline_compl",
+ "+cmdline_hist",
+ "+cmdline_info",
+ "+comments",
+ "+conceal",
+ "+cryptv",
+ "+cscope",
+ "+cursorbind",
+#ifdef CURSOR_SHAPE
+ "+cursorshape",
+#else
+ "-cursorshape",
+#endif
+ "+dialog_con",
+ "+diff",
+ "+digraphs",
+ "-dnd",
+ "-ebcdic",
+ "-emacs_tags",
+ "+eval",
+ "+ex_extra",
+ "+extra_search",
+ "+farsi",
+ "+file_in_path",
+ "+find_in_path",
+ "+float",
+ "+folding",
+ "-footer",
+ /* only interesting on Unix systems */
+#if !defined(USE_SYSTEM) && defined(UNIX)
+ "+fork()",
+#endif
+ "+gettext",
+ "+hangul_input",
+#if (defined(HAVE_ICONV_H) && defined(USE_ICONV)) || defined(DYNAMIC_ICONV)
+# ifdef DYNAMIC_ICONV
+ "+iconv/dyn",
+# else
+ "+iconv",
+# endif
+#else
+ "-iconv",
+#endif
+ "+insert_expand",
+ "+jumplist",
+ "+keymap",
+ "+langmap",
+#ifdef FEAT_LIBCALL
+ "+libcall",
+#else
+ "-libcall",
+#endif
+ "+linebreak",
+ "+lispindent",
+ "+listcmds",
+ "+localmap",
+ "-lua",
+ "+menu",
+ "+mksession",
+ "+modify_fname",
+ "+mouse",
+ "-mouseshape",
-#define UV_VERSION ((UV_VERSION_MAJOR << 16) | \
- (UV_VERSION_MINOR << 8) | \
- (UV_VERSION_PATCH))
+#if defined(UNIX) || defined(VMS)
+ "+mouse_dec",
+ "-mouse_gpm",
+# ifdef FEAT_MOUSE_JSB
+ "+mouse_jsbterm",
+# else
+ "-mouse_jsbterm",
+# endif
+ "+mouse_netterm",
+#endif
-#define UV_STRINGIFY(v) UV_STRINGIFY_HELPER(v)
-#define UV_STRINGIFY_HELPER(v) #v
-#define UV_VERSION_STRING_BASE UV_STRINGIFY(UV_VERSION_MAJOR) "." \
- UV_STRINGIFY(UV_VERSION_MINOR) "." \
- UV_STRINGIFY(UV_VERSION_PATCH)
+#if defined(UNIX) || defined(VMS)
+ "+mouse_sgr",
+ "-mouse_sysmouse",
+ "+mouse_urxvt",
+ "+mouse_xterm",
+#endif
-#if UV_VERSION_IS_RELEASE
-# define UV_VERSION_STRING UV_VERSION_STRING_BASE
+ "+multi_byte",
+ "+multi_lang",
+ "-mzscheme",
+ "-netbeans_intg",
+ "+path_extra",
+ "-perl",
+ "+persistent_undo",
+ "+postscript",
+ "+printer",
+ "+profile",
+ "-python",
+ "-python3",
+ "+quickfix",
+ "+reltime",
+ "+rightleft",
+ "-ruby",
+ "+scrollbind",
+ "-signs",
+ "+smartindent",
+ "-sniff",
+#ifdef STARTUPTIME
+ "+startuptime",
#else
-# define UV_VERSION_STRING UV_VERSION_STRING_BASE "-pre"
+ "-startuptime",
+#endif
+ "+statusline",
+ "-sun_workshop",
+ "+syntax",
+ /* only interesting on Unix systems */
+#if defined(USE_SYSTEM) && (defined(UNIX) || defined(__EMX__))
+ "+system()",
+#endif
+ "+tag_binary",
+ "+tag_old_static",
+#ifdef FEAT_TAG_ANYWHITE
+ "+tag_any_white",
+#else
+ "-tag_any_white",
+#endif
+ "-tcl",
+#if defined(UNIX) || defined(__EMX__)
+ /* only Unix (or OS/2 with EMX!) can have terminfo instead of termcap */
+# ifdef TERMINFO
+ "+terminfo",
+# else
+ "-terminfo",
+# endif
+#else /* unix always includes termcap support */
+# ifdef HAVE_TGETENT
+ "+tgetent",
+# else
+ "-tgetent",
+# endif
+#endif
+ "+termresponse",
+ "+textobjects",
+ "+title",
+ "-toolbar",
+ "+user_commands",
+ "+vertsplit",
+ "+virtualedit",
+ "+visual",
+ "+visualextra",
+ "+viminfo",
+ "+vreplace",
+ "+wildignore",
+ "+wildmenu",
+ "+windows",
+ "+writebackup",
+#if defined(UNIX) || defined(VMS)
+ "-X11",
+#endif
+ "-xfontset",
+ "-xim",
+#if defined(UNIX) || defined(VMS)
+ "-xsmp",
+ "-xterm_clipboard",
+#endif
+#ifdef FEAT_XTERM_SAVE
+ "+xterm_save",
+#else
+ "-xterm_save",
+#endif
+ "-xpm",
+ NULL
+};
+
+static int included_patches[] =
+{ /* Add new patch number below this line */
+ /**/
+ 160,
+ /**/
+ 159,
+ /**/
+ 158,
+ /**/
+ 157,
+ /**/
+ 156,
+ /**/
+ 155,
+ /**/
+ 154,
+ /**/
+ 153,
+ /**/
+ 152,
+ /**/
+ 151,
+ /**/
+ 150,
+ /**/
+ 149,
+ /**/
+ 148,
+ /**/
+ 147,
+ /**/
+ 146,
+ /**/
+ 145,
+ /**/
+ 144,
+ /**/
+ 143,
+ /**/
+ 142,
+ /**/
+ 141,
+ /**/
+ 140,
+ /**/
+ 139,
+ /**/
+ 138,
+ /**/
+ 137,
+ /**/
+ 136,
+ /**/
+ 135,
+ /**/
+ 134,
+ /**/
+ 133,
+ /**/
+ 132,
+ /**/
+ 131,
+ /**/
+ 130,
+ /**/
+ 129,
+ /**/
+ 128,
+ /**/
+ 127,
+ /**/
+ 126,
+ /**/
+ 125,
+ /**/
+ 124,
+ /**/
+ 123,
+ /**/
+ 122,
+ /**/
+ 121,
+ /**/
+ 120,
+ /**/
+ 119,
+ /**/
+ 118,
+ /**/
+ 117,
+ /**/
+ 116,
+ /**/
+ 115,
+ /**/
+ 114,
+ /**/
+ 113,
+ /**/
+ 112,
+ /**/
+ 111,
+ /**/
+ 110,
+ /**/
+ 109,
+ /**/
+ 108,
+ /**/
+ 107,
+ /**/
+ 106,
+ /**/
+ 105,
+ /**/
+ 104,
+ /**/
+ 103,
+ /**/
+ 102,
+ /**/
+ 101,
+ /**/
+ 100,
+ /**/
+ 99,
+ /**/
+ 98,
+ /**/
+ 97,
+ /**/
+ 96,
+ /**/
+ 95,
+ /**/
+ 94,
+ /**/
+ 93,
+ /**/
+ 92,
+ /**/
+ 91,
+ /**/
+ 90,
+ /**/
+ 89,
+ /**/
+ 88,
+ /**/
+ 87,
+ /**/
+ 86,
+ /**/
+ 85,
+ /**/
+ 84,
+ /**/
+ 83,
+ /**/
+ 82,
+ /**/
+ 81,
+ /**/
+ 80,
+ /**/
+ 79,
+ /**/
+ 78,
+ /**/
+ 77,
+ /**/
+ 76,
+ /**/
+ 75,
+ /**/
+ 74,
+ /**/
+ 73,
+ /**/
+ 72,
+ /**/
+ 71,
+ /**/
+ 70,
+ /**/
+ 69,
+ /**/
+ 68,
+ /**/
+ 67,
+ /**/
+ 66,
+ /**/
+ 65,
+ /**/
+ 64,
+ /**/
+ 63,
+ /**/
+ 62,
+ /**/
+ 61,
+ /**/
+ 60,
+ /**/
+ 59,
+ /**/
+ 58,
+ /**/
+ 57,
+ /**/
+ 56,
+ /**/
+ 55,
+ /**/
+ 54,
+ /**/
+ 53,
+ /**/
+ 52,
+ /**/
+ 51,
+ /**/
+ 50,
+ /**/
+ 49,
+ /**/
+ 48,
+ /**/
+ 47,
+ /**/
+ 46,
+ /**/
+ 45,
+ /**/
+ 44,
+ /**/
+ 43,
+ /**/
+ 42,
+ /**/
+ 41,
+ /**/
+ 40,
+ /**/
+ 39,
+ /**/
+ 38,
+ /**/
+ 37,
+ /**/
+ 36,
+ /**/
+ 35,
+ /**/
+ 34,
+ /**/
+ 33,
+ /**/
+ 32,
+ /**/
+ 31,
+ /**/
+ 30,
+ /**/
+ 29,
+ /**/
+ 28,
+ /**/
+ 27,
+ /**/
+ 26,
+ /**/
+ 25,
+ /**/
+ 24,
+ /**/
+ 23,
+ /**/
+ 22,
+ /**/
+ 21,
+ /**/
+ 20,
+ /**/
+ 19,
+ /**/
+ 18,
+ /**/
+ 17,
+ /**/
+ 16,
+ /**/
+ 15,
+ /**/
+ 14,
+ /**/
+ 13,
+ /**/
+ 12,
+ /**/
+ 11,
+ /**/
+ 10,
+ /**/
+ 9,
+ /**/
+ 8,
+ /**/
+ 7,
+ /**/
+ 6,
+ /**/
+ 5,
+ /**/
+ 4,
+ /**/
+ 3,
+ /**/
+ 2,
+ /**/
+ 1,
+ /**/
+ 0
+};
+
+/*
+ * 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
+};
+
+int highest_patch() {
+ int i;
+ int h = 0;
+
+ for (i = 0; included_patches[i] != 0; ++i)
+ if (included_patches[i] > h)
+ h = included_patches[i];
+ return h;
+}
+
+/*
+ * Return TRUE if patch "n" has been included.
+ */
+int has_patch(n)
+int n;
+{
+ int i;
+
+ for (i = 0; included_patches[i] != 0; ++i)
+ if (included_patches[i] == n)
+ return TRUE;
+ return FALSE;
+}
+
+void ex_version(eap)
+exarg_T *eap;
+{
+ /*
+ * Ignore a ":version 9.99" command.
+ */
+ if (*eap->arg == NUL) {
+ msg_putchar('\n');
+ list_version();
+ }
+}
+
+/*
+ * List all features aligned in columns, dictionary style.
+ */
+static void list_features() {
+ int i;
+ int ncol;
+ int nrow;
+ int nfeat = 0;
+ int width = 0;
+
+ /* Find the length of the longest feature name, use that + 1 as the column
+ * width */
+ for (i = 0; features[i] != NULL; ++i) {
+ int l = (int)STRLEN(features[i]);
+
+ if (l > width)
+ width = l;
+ ++nfeat;
+ }
+ width += 1;
+
+ if (Columns < width) {
+ /* Not enough screen columns - show one per line */
+ for (i = 0; features[i] != NULL; ++i) {
+ version_msg(features[i]);
+ if (msg_col > 0)
+ msg_putchar('\n');
+ }
+ return;
+ }
+
+ /* The rightmost column doesn't need a separator.
+ * Sacrifice it to fit in one more column if possible. */
+ ncol = (int) (Columns + 1) / width;
+ nrow = nfeat / ncol + (nfeat % ncol ? 1 : 0);
+
+ /* i counts columns then rows. idx counts rows then columns. */
+ for (i = 0; !got_int && i < nrow * ncol; ++i) {
+ int idx = (i / ncol) + (i % ncol) * nrow;
+
+ if (idx < nfeat) {
+ int last_col = (i + 1) % ncol == 0;
+
+ msg_puts((char_u *)features[idx]);
+ if (last_col) {
+ if (msg_col > 0)
+ msg_putchar('\n');
+ } else {
+ while (msg_col % width)
+ msg_putchar(' ');
+ }
+ } else {
+ if (msg_col > 0)
+ msg_putchar('\n');
+ }
+ }
+}
+
+void list_version() {
+ int i;
+ int first;
+ char *s = "";
+
+ /*
+ * When adding features here, don't forget to update the list of
+ * internal variables in eval.c!
+ */
+ MSG(longVersion);
+
+
+ /* Print the list of patch numbers if there is at least one. */
+ /* Print a range when patches are consecutive: "1-10, 12, 15-40, 42-45" */
+ if (included_patches[0] != 0) {
+ MSG_PUTS(_("\nIncluded patches: "));
+ first = -1;
+ /* find last one */
+ for (i = 0; included_patches[i] != 0; ++i)
+ ;
+ while (--i >= 0) {
+ if (first < 0)
+ first = included_patches[i];
+ if (i == 0 || included_patches[i - 1] != included_patches[i] + 1) {
+ MSG_PUTS(s);
+ s = ", ";
+ msg_outnum((long)first);
+ if (first != included_patches[i]) {
+ MSG_PUTS("-");
+ msg_outnum((long)included_patches[i]);
+ }
+ first = -1;
+ }
+ }
+ }
+
+ /* Print the list of extra patch descriptions if there is at least one. */
+ if (extra_patches[0] != NULL) {
+ MSG_PUTS(_("\nExtra patches: "));
+ s = "";
+ for (i = 0; extra_patches[i] != NULL; ++i) {
+ MSG_PUTS(s);
+ s = ", ";
+ MSG_PUTS(extra_patches[i]);
+ }
+ }
+
+#ifdef MODIFIED_BY
+ MSG_PUTS("\n");
+ MSG_PUTS(_("Modified by "));
+ MSG_PUTS(MODIFIED_BY);
#endif
+#ifdef HAVE_PATHDEF
+ if (*compiled_user != NUL || *compiled_sys != NUL) {
+ MSG_PUTS(_("\nCompiled "));
+ if (*compiled_user != NUL) {
+ MSG_PUTS(_("by "));
+ MSG_PUTS(compiled_user);
+ }
+ if (*compiled_sys != NUL) {
+ MSG_PUTS("@");
+ MSG_PUTS(compiled_sys);
+ }
+ }
+#endif
+
+ MSG_PUTS(_("\nHuge version "));
+ MSG_PUTS(_("without GUI."));
+ version_msg(_(" Features included (+) or not (-):\n"));
+
+ list_features();
-unsigned int uv_version(void) {
- return UV_VERSION;
+#ifdef SYS_VIMRC_FILE
+ version_msg(_(" system vimrc file: \""));
+ version_msg(SYS_VIMRC_FILE);
+ version_msg("\"\n");
+#endif
+#ifdef USR_VIMRC_FILE
+ version_msg(_(" user vimrc file: \""));
+ version_msg(USR_VIMRC_FILE);
+ version_msg("\"\n");
+#endif
+#ifdef USR_VIMRC_FILE2
+ version_msg(_(" 2nd user vimrc file: \""));
+ version_msg(USR_VIMRC_FILE2);
+ version_msg("\"\n");
+#endif
+#ifdef USR_VIMRC_FILE3
+ version_msg(_(" 3rd user vimrc file: \""));
+ version_msg(USR_VIMRC_FILE3);
+ version_msg("\"\n");
+#endif
+#ifdef USR_EXRC_FILE
+ version_msg(_(" user exrc file: \""));
+ version_msg(USR_EXRC_FILE);
+ version_msg("\"\n");
+#endif
+#ifdef USR_EXRC_FILE2
+ version_msg(_(" 2nd user exrc file: \""));
+ version_msg(USR_EXRC_FILE2);
+ version_msg("\"\n");
+#endif
+#ifdef HAVE_PATHDEF
+ if (*default_vim_dir != NUL) {
+ version_msg(_(" fall-back for $VIM: \""));
+ version_msg((char *)default_vim_dir);
+ version_msg("\"\n");
+ }
+ if (*default_vimruntime_dir != NUL) {
+ version_msg(_(" f-b for $VIMRUNTIME: \""));
+ version_msg((char *)default_vimruntime_dir);
+ version_msg("\"\n");
+ }
+ version_msg(_("Compilation: "));
+ version_msg((char *)all_cflags);
+ version_msg("\n");
+ version_msg(_("Linking: "));
+ version_msg((char *)all_lflags);
+#endif
+#ifdef DEBUG
+ version_msg("\n");
+ version_msg(_(" DEBUG BUILD"));
+#endif
}
+/*
+ * Output a string for the version message. If it's going to wrap, output a
+ * newline, unless the message is too long to fit on the screen anyway.
+ */
+static void version_msg(s)
+char *s;
+{
+ int len = (int)STRLEN(s);
-const char* uv_version_string(void) {
- return UV_VERSION_STRING;
+ if (!got_int && len < (int)Columns && msg_col + len >= (int)Columns
+ && *s != '\n')
+ msg_putchar('\n');
+ if (!got_int)
+ MSG_PUTS(s);
+}
+
+static void do_intro_line __ARGS((int row, char_u *mesg, int add_version,
+ int attr));
+
+/*
+ * Show the intro message when not editing a file.
+ */
+void maybe_intro_message() {
+ if (bufempty()
+ && curbuf->b_fname == NULL
+ && firstwin->w_next == NULL
+ && vim_strchr(p_shm, SHM_INTRO) == NULL)
+ intro_message(FALSE);
+}
+
+/*
+ * Give an introductory message about Vim.
+ * Only used when starting Vim on an empty file, without a file name.
+ * Or with the ":intro" command (for Sven :-).
+ */
+void intro_message(colon)
+int colon; /* TRUE for ":intro" */
+{
+ int i;
+ int row;
+ int blanklines;
+ int sponsor;
+ char *p;
+ static char *(lines[]) =
+ {
+ N_("VIM - Vi IMproved"),
+ "",
+ N_("version "),
+ N_("by Bram Moolenaar et al."),
+#ifdef MODIFIED_BY
+ " ",
+#endif
+ N_("Vim is open source and freely distributable"),
+ "",
+ N_("Help poor children in Uganda!"),
+ N_("type :help iccf<Enter> for information "),
+ "",
+ N_("type :q<Enter> to exit "),
+ N_("type :help<Enter> or <F1> for on-line help"),
+ N_("type :help version7<Enter> for version info"),
+ NULL,
+ "",
+ N_("Running in Vi compatible mode"),
+ N_("type :set nocp<Enter> for Vim defaults"),
+ N_("type :help cp-default<Enter> for info on this"),
+ };
+
+ /* blanklines = screen height - # message lines */
+ blanklines = (int)Rows - ((sizeof(lines) / sizeof(char *)) - 1);
+ if (!p_cp)
+ blanklines += 4; /* add 4 for not showing "Vi compatible" message */
+
+ /* Don't overwrite a statusline. Depends on 'cmdheight'. */
+ if (p_ls > 1)
+ blanklines -= Rows - topframe->fr_height;
+ if (blanklines < 0)
+ blanklines = 0;
+
+ /* Show the sponsor and register message one out of four times, the Uganda
+ * message two out of four times. */
+ sponsor = (int)time(NULL);
+ sponsor = ((sponsor & 2) == 0) - ((sponsor & 4) == 0);
+
+ /* start displaying the message lines after half of the blank lines */
+ row = blanklines / 2;
+ if ((row >= 2 && Columns >= 50) || colon) {
+ for (i = 0; i < (int)(sizeof(lines) / sizeof(char *)); ++i) {
+ p = lines[i];
+ if (p == NULL) {
+ if (!p_cp)
+ break;
+ continue;
+ }
+ if (sponsor != 0) {
+ if (strstr(p, "children") != NULL)
+ p = sponsor < 0
+ ? N_("Sponsor Vim development!")
+ : N_("Become a registered Vim user!");
+ else if (strstr(p, "iccf") != NULL)
+ p = sponsor < 0
+ ? N_("type :help sponsor<Enter> for information ")
+ : N_("type :help register<Enter> for information ");
+ else if (strstr(p, "Orphans") != NULL)
+ p = N_("menu Help->Sponsor/Register for information ");
+ }
+ if (*p != NUL)
+ do_intro_line(row, (char_u *)_(p), i == 2, 0);
+ ++row;
+ }
+ }
+
+ /* Make the wait-return message appear just below the text. */
+ if (colon)
+ msg_row = row;
+}
+
+static void do_intro_line(row, mesg, add_version, attr)
+int row;
+char_u *mesg;
+int add_version;
+int attr;
+{
+ char_u vers[20];
+ int col;
+ char_u *p;
+ int l;
+ int clen;
+#ifdef MODIFIED_BY
+# define MODBY_LEN 150
+ char_u modby[MODBY_LEN];
+
+ if (*mesg == ' ') {
+ vim_strncpy(modby, (char_u *)_("Modified by "), MODBY_LEN - 1);
+ l = STRLEN(modby);
+ vim_strncpy(modby + l, (char_u *)MODIFIED_BY, MODBY_LEN - l - 1);
+ mesg = modby;
+ }
+#endif
+
+ /* Center the message horizontally. */
+ col = vim_strsize(mesg);
+ if (add_version) {
+ STRCPY(vers, mediumVersion);
+ if (highest_patch()) {
+ /* Check for 9.9x or 9.9xx, alpha/beta version */
+ if (isalpha((int)vers[3])) {
+ int len = (isalpha((int)vers[4])) ? 5 : 4;
+ sprintf((char *)vers + len, ".%d%s", highest_patch(),
+ mediumVersion + len);
+ } else
+ sprintf((char *)vers + 3, ".%d", highest_patch());
+ }
+ col += (int)STRLEN(vers);
+ }
+ col = (Columns - col) / 2;
+ if (col < 0)
+ col = 0;
+
+ /* Split up in parts to highlight <> items differently. */
+ for (p = mesg; *p != NUL; p += l) {
+ clen = 0;
+ for (l = 0; p[l] != NUL
+ && (l == 0 || (p[l] != '<' && p[l - 1] != '>')); ++l) {
+ if (has_mbyte) {
+ clen += ptr2cells(p + l);
+ l += (*mb_ptr2len)(p + l) - 1;
+ } else
+ clen += byte2cells(p[l]);
+ }
+ screen_puts_len(p, l, row, col, *p == '<' ? hl_attr(HLF_8) : attr);
+ col += clen;
+ }
+
+ /* Add the version number to the version line. */
+ if (add_version)
+ screen_puts(vers, row, col, 0);
+}
+
+/*
+ * ":intro": clear screen, display intro screen and wait for return.
+ */
+void ex_intro(eap)
+exarg_T *eap UNUSED;
+{
+ screenclear();
+ intro_message(TRUE);
+ wait_return(TRUE);
}
diff --git a/src/version.h b/src/version.h
new file mode 100644
index 0000000000..ee49a6d97c
--- /dev/null
+++ b/src/version.h
@@ -0,0 +1,40 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * 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.
+ */
+
+/*
+ * Define the version number, name, etc.
+ * The patchlevel is in included_patches[], in version.c.
+ *
+ * This doesn't use string concatenation, some compilers don't support it.
+ */
+
+#define VIM_VERSION_MAJOR 7
+#define VIM_VERSION_MAJOR_STR "7"
+#define VIM_VERSION_MINOR 4
+#define VIM_VERSION_MINOR_STR "4"
+#define VIM_VERSION_100 (VIM_VERSION_MAJOR * 100 + VIM_VERSION_MINOR)
+
+#define VIM_VERSION_BUILD 280
+#define VIM_VERSION_BUILD_BCD 0x118
+#define VIM_VERSION_BUILD_STR "280"
+#define VIM_VERSION_PATCHLEVEL 0
+#define VIM_VERSION_PATCHLEVEL_STR "0"
+/* Used by MacOS port should be one of: development, alpha, beta, final */
+#define VIM_VERSION_RELEASE final
+
+/*
+ * VIM_VERSION_NODOT is used for the runtime directory name.
+ * VIM_VERSION_SHORT is copied into the swap file (max. length is 6 chars).
+ * VIM_VERSION_MEDIUM is used for the startup-screen.
+ * VIM_VERSION_LONG is used for the ":version" command and "Vim -h".
+ */
+#define VIM_VERSION_NODOT "vim74"
+#define VIM_VERSION_SHORT "7.4"
+#define VIM_VERSION_MEDIUM "7.4"
+#define VIM_VERSION_LONG "VIM - Vi IMproved 7.4 (2013 Aug 10)"
+#define VIM_VERSION_LONG_DATE "VIM - Vi IMproved 7.4 (2013 Aug 10, compiled "
diff --git a/src/vim.h b/src/vim.h
new file mode 100644
index 0000000000..53706da049
--- /dev/null
+++ b/src/vim.h
@@ -0,0 +1,1605 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * 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.
+ */
+
+#ifndef VIM__H
+# define VIM__H
+/* Included when ported to cmake */
+/* This is needed to replace TRUE/FALSE macros by true/false from c99 */
+#include <stdbool.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
+
+/*
+ * 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
+
+/*
+ * Cygwin may have fchdir() in a newer release, but in most versions it
+ * doesn't work well and avoiding it keeps the binary backward compatible.
+ */
+
+/* We may need to define the uint32_t on non-Unix system, but using the same
+ * identifier causes conflicts. Therefore use UINT32_T. */
+# define UINT32_TYPEDEF uint32_t
+#endif
+
+#if !defined(UINT32_TYPEDEF)
+# if defined(uint32_t) /* this doesn't catch typedefs, unfortunately */
+# define UINT32_TYPEDEF uint32_t
+# else
+/* Fall back to assuming unsigned int is 32 bit. If this is wrong then the
+ * test in blowfish.c will fail. */
+# define UINT32_TYPEDEF unsigned int
+# endif
+#endif
+
+/* user ID of root is usually zero, but not for everybody */
+# define ROOT_UID 0
+
+
+/* Can't use "PACKAGE" here, conflicts with a Perl include file. */
+#ifndef VIMPACKAGE
+# define VIMPACKAGE "vim"
+#endif
+
+#include "os_unix.h" /* bring lots of system header files */
+
+#ifndef __ARGS
+# if defined(__STDC__) || defined(__GNUC__) || defined(WIN3264)
+# define __ARGS(x) x
+# else
+# define __ARGS(x) ()
+# endif
+#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
+
+# ifdef HAVE_LOCALE_H
+# include <locale.h>
+# endif
+
+/*
+ * 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.
+ */
+#ifndef MAXPATHL
+# ifdef MAXPATHLEN
+# define MAXPATHL MAXPATHLEN
+# else
+# define MAXPATHL 256
+# endif
+#endif
+#ifdef BACKSLASH_IN_FILENAME
+# define PATH_ESC_CHARS ((char_u *)" \t\n*?[{`%#'\"|!<")
+#else
+# define PATH_ESC_CHARS ((char_u *)" \t\n*?[{`$\\%#'\"|!<")
+# define SHELL_ESC_CHARS ((char_u *)" \t\n*?[{`$\\%#'\"|!<>();&")
+#endif
+
+#define NUMBUFLEN 30 /* length of a buffer to store a number in ASCII */
+
+/*
+ * Shorthand for unsigned variables. Many systems, but not all, have u_char
+ * already defined, so we use char_u to avoid trouble.
+ */
+typedef unsigned char char_u;
+typedef unsigned short short_u;
+typedef unsigned int int_u;
+/* Make sure long_u is big enough to hold a pointer.
+ * On Win64, longs are 32 bits and pointers are 64 bits.
+ * For printf() and scanf(), we need to take care of long_u specifically. */
+/* Microsoft-specific. The __w64 keyword should be specified on any typedefs
+ * that change size between 32-bit and 64-bit platforms. For any such type,
+ * __w64 should appear only on the 32-bit definition of the typedef.
+ * Define __w64 as an empty token for everything but MSVC 7.x or later.
+ */
+# define __w64
+typedef unsigned long __w64 long_u;
+typedef long __w64 long_i;
+# define SCANF_HEX_LONG_U "%lx"
+# define SCANF_DECIMAL_LONG_U "%lu"
+# define PRINTF_HEX_LONG_U "0x%lx"
+#define PRINTF_DECIMAL_LONG_U SCANF_DECIMAL_LONG_U
+
+/*
+ * Only systems which use configure will have SIZEOF_OFF_T and SIZEOF_LONG
+ * defined, which is ok since those are the same systems which can have
+ * varying sizes for off_t. The other systems will continue to use "%ld" to
+ * print off_t since off_t is simply a typedef to long for them.
+ */
+#if defined(SIZEOF_OFF_T) && (SIZEOF_OFF_T > SIZEOF_LONG)
+# define LONG_LONG_OFF_T
+#endif
+
+/*
+ * The characters and attributes cached for the screen.
+ */
+typedef char_u schar_T;
+typedef unsigned short sattr_T;
+# define MAX_TYPENR 65535
+
+/*
+ * The u8char_T can hold one decoded UTF-8 character.
+ * We normally use 32 bits now, since some Asian characters don't fit in 16
+ * bits. u8char_T is only used for displaying, it could be 16 bits to save
+ * memory.
+ */
+# ifdef UNICODE16
+typedef unsigned short u8char_T; /* short should be 16 bits */
+# else
+# if SIZEOF_INT >= 4
+typedef unsigned int u8char_T; /* int is 32 bits */
+# else
+typedef unsigned long u8char_T; /* long should be 32 bits or more */
+# endif
+# endif
+
+#include "ascii.h"
+#include "keymap.h"
+#include "term.h"
+#include "macros.h"
+
+#include <errno.h>
+
+#include <assert.h>
+
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#ifdef HAVE_WCTYPE_H
+# include <wctype.h>
+#endif
+#ifdef HAVE_STDARG_H
+# include <stdarg.h>
+#endif
+
+#if defined(HAVE_SYS_SELECT_H) && \
+ (!defined(HAVE_SYS_TIME_H) || defined(SYS_SELECT_WITH_SYS_TIME))
+# include <sys/select.h>
+#endif
+
+/* ================ end of the header file puzzle =============== */
+
+#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
+
+/*
+ * flags for update_screen()
+ * The higher the value, the higher the priority
+ */
+#define VALID 10 /* buffer not changed, or changes marked
+ with b_mod_* */
+#define INVERTED 20 /* redisplay inverted part that changed */
+#define INVERTED_ALL 25 /* redisplay whole inverted part */
+#define REDRAW_TOP 30 /* display first w_upd_rows screen lines */
+#define SOME_VALID 35 /* like NOT_VALID but may scroll */
+#define NOT_VALID 40 /* buffer needs complete redraw */
+#define CLEAR 50 /* screen messed up, clear it */
+
+/*
+ * Flags for w_valid.
+ * These are set when something in a window structure becomes invalid, except
+ * when the cursor is moved. Call check_cursor_moved() before testing one of
+ * the flags.
+ * These are reset when that thing has been updated and is valid again.
+ *
+ * Every function that invalidates one of these must call one of the
+ * invalidate_* functions.
+ *
+ * w_valid is supposed to be used only in screen.c. From other files, use the
+ * 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
+ */
+#define VALID_WROW 0x01 /* w_wrow (window row) is valid */
+#define VALID_WCOL 0x02 /* w_wcol (window col) is valid */
+#define VALID_VIRTCOL 0x04 /* w_virtcol (file col) is valid */
+#define VALID_CHEIGHT 0x08 /* w_cline_height and w_cline_folded valid */
+#define VALID_CROW 0x10 /* w_cline_row is valid */
+#define VALID_BOTLINE 0x20 /* w_botine and w_empty_rows are valid */
+#define VALID_BOTLINE_AP 0x40 /* w_botine is approximated */
+#define VALID_TOPLINE 0x80 /* w_topline is valid (for cursor position) */
+
+/*
+ * 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
+#define HL_ALL 0x3f
+
+/* 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 (REPLACE_FLAG + INSERT)
+# 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 MAP_ALL_MODES (0x3f | SELECTMODE) /* all mode bits used for
+ * mapping */
+
+/* directions */
+#define FORWARD 1
+#define BACKWARD (-1)
+#define FORWARD_FILE 3
+#define BACKWARD_FILE (-3)
+
+/* return values for functions */
+#if !(defined(OK) && (OK == 1))
+/* 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 */
+
+/* flags for b_flags */
+#define BF_RECOVERED 0x01 /* buffer has been recovered */
+#define BF_CHECK_RO 0x02 /* need to check readonly when loading file
+ into buffer (set by ":e", may be reset by
+ ":buf" */
+#define BF_NEVERLOADED 0x04 /* file has never been loaded into buffer,
+ many variables still need to be set */
+#define BF_NOTEDITED 0x08 /* Set when file name is changed after
+ starting to edit, reset when file is
+ written out. */
+#define BF_NEW 0x10 /* file didn't exist when editing started */
+#define BF_NEW_W 0x20 /* Warned for BF_NEW and file created */
+#define BF_READERR 0x40 /* got errors while reading the file */
+#define BF_DUMMY 0x80 /* dummy buffer, only used internally */
+#define BF_PRESERVED 0x100 /* ":preserve" was used */
+
+/* Mask to check for flags that prevent normal writing */
+#define BF_WRITE_MASK (BF_NOTEDITED + BF_NEW + BF_READERR)
+
+/*
+ * values for xp_context when doing command line completion
+ */
+#define EXPAND_UNSUCCESSFUL (-2)
+#define EXPAND_OK (-1)
+#define EXPAND_NOTHING 0
+#define EXPAND_COMMANDS 1
+#define EXPAND_FILES 2
+#define EXPAND_DIRECTORIES 3
+#define EXPAND_SETTINGS 4
+#define EXPAND_BOOL_SETTINGS 5
+#define EXPAND_TAGS 6
+#define EXPAND_OLD_SETTING 7
+#define EXPAND_HELP 8
+#define EXPAND_BUFFERS 9
+#define EXPAND_EVENTS 10
+#define EXPAND_MENUS 11
+#define EXPAND_SYNTAX 12
+#define EXPAND_HIGHLIGHT 13
+#define EXPAND_AUGROUP 14
+#define EXPAND_USER_VARS 15
+#define EXPAND_MAPPINGS 16
+#define EXPAND_TAGS_LISTFILES 17
+#define EXPAND_FUNCTIONS 18
+#define EXPAND_USER_FUNC 19
+#define EXPAND_EXPRESSION 20
+#define EXPAND_MENUNAMES 21
+#define EXPAND_USER_COMMANDS 22
+#define EXPAND_USER_CMD_FLAGS 23
+#define EXPAND_USER_NARGS 24
+#define EXPAND_USER_COMPLETE 25
+#define EXPAND_ENV_VARS 26
+#define EXPAND_LANGUAGE 27
+#define EXPAND_COLORS 28
+#define EXPAND_COMPILER 29
+#define EXPAND_USER_DEFINED 30
+#define EXPAND_USER_LIST 31
+#define EXPAND_SHELLCMD 32
+#define EXPAND_CSCOPE 33
+#define EXPAND_SIGN 34
+#define EXPAND_PROFILE 35
+#define EXPAND_BEHAVE 36
+#define EXPAND_FILETYPE 37
+#define EXPAND_FILES_IN_PATH 38
+#define EXPAND_OWNSYNTAX 39
+#define EXPAND_LOCALES 40
+#define EXPAND_HISTORY 41
+#define EXPAND_USER 42
+#define EXPAND_SYNTIME 43
+
+/* Values for exmode_active (0 is no exmode) */
+#define EXMODE_NORMAL 1
+#define EXMODE_VIM 2
+
+/* Values for nextwild() and ExpandOne(). See ExpandOne() for meaning. */
+#define WILD_FREE 1
+#define WILD_EXPAND_FREE 2
+#define WILD_EXPAND_KEEP 3
+#define WILD_NEXT 4
+#define WILD_PREV 5
+#define WILD_ALL 6
+#define WILD_LONGEST 7
+#define WILD_ALL_KEEP 8
+
+#define WILD_LIST_NOTFOUND 1
+#define WILD_HOME_REPLACE 2
+#define WILD_USE_NL 4
+#define WILD_NO_BEEP 8
+#define WILD_ADD_SLASH 16
+#define WILD_KEEP_ALL 32
+#define WILD_SILENT 64
+#define WILD_ESCAPE 128
+#define WILD_ICASE 256
+
+/* Flags for expand_wildcards() */
+#define EW_DIR 0x01 /* include directory names */
+#define EW_FILE 0x02 /* include file names */
+#define EW_NOTFOUND 0x04 /* include not found names */
+#define EW_ADDSLASH 0x08 /* append slash to directory name */
+#define EW_KEEPALL 0x10 /* keep all matches */
+#define EW_SILENT 0x20 /* don't print "1 returned" from shell */
+#define EW_EXEC 0x40 /* executable files */
+#define EW_PATH 0x80 /* search in 'path' too */
+#define EW_ICASE 0x100 /* ignore case */
+#define EW_NOERROR 0x200 /* no error for bad regexp */
+#define EW_NOTWILD 0x400 /* add match with literal name if exists */
+/* Note: mostly EW_NOTFOUND and EW_SILENT are mutually exclusive: EW_NOTFOUND
+* is used when executing commands and EW_SILENT for interactive expanding. */
+
+/* Flags for find_file_*() functions. */
+#define FINDFILE_FILE 0 /* only files */
+#define FINDFILE_DIR 1 /* only directories */
+#define FINDFILE_BOTH 2 /* files and directories */
+
+# define W_WINCOL(wp) (wp->w_wincol)
+# define W_WIDTH(wp) (wp->w_width)
+# define W_ENDCOL(wp) (wp->w_wincol + wp->w_width)
+# define W_VSEP_WIDTH(wp) (wp->w_vsep_width)
+# define W_STATUS_HEIGHT(wp) (wp->w_status_height)
+# define W_WINROW(wp) (wp->w_winrow)
+
+#ifdef NO_EXPANDPATH
+# define gen_expand_wildcards mch_expand_wildcards
+#endif
+
+/* Values for the find_pattern_in_path() function args 'type' and 'action': */
+#define FIND_ANY 1
+#define FIND_DEFINE 2
+#define CHECK_PATH 3
+
+#define ACTION_SHOW 1
+#define ACTION_GOTO 2
+#define ACTION_SPLIT 3
+#define ACTION_SHOW_ALL 4
+# define ACTION_EXPAND 5
+
+# define SST_MIN_ENTRIES 150 /* minimal size for state stack array */
+# define SST_MAX_ENTRIES 1000 /* maximal size for state stack array */
+# define SST_FIX_STATES 7 /* size of sst_stack[]. */
+# define SST_DIST 16 /* normal distance between entries */
+# define SST_INVALID (synstate_T *)-1 /* invalid syn_state pointer */
+
+# define HL_CONTAINED 0x01 /* not used on toplevel */
+# define HL_TRANSP 0x02 /* has no highlighting */
+# define HL_ONELINE 0x04 /* match within one line only */
+# define HL_HAS_EOL 0x08 /* end pattern that matches with $ */
+# define HL_SYNC_HERE 0x10 /* sync point after this item (syncing only) */
+# define HL_SYNC_THERE 0x20 /* sync point at current line (syncing only) */
+# define HL_MATCH 0x40 /* use match ID instead of item ID */
+# define HL_SKIPNL 0x80 /* nextgroup can skip newlines */
+# define HL_SKIPWHITE 0x100 /* nextgroup can skip white space */
+# define HL_SKIPEMPTY 0x200 /* nextgroup can skip empty lines */
+# define HL_KEEPEND 0x400 /* end match always kept */
+# define HL_EXCLUDENL 0x800 /* exclude NL from match */
+# define HL_DISPLAY 0x1000 /* only used for displaying, not syncing */
+# define HL_FOLD 0x2000 /* define fold */
+# define HL_EXTEND 0x4000 /* ignore a keepend */
+# define HL_MATCHCONT 0x8000 /* match continued from previous line */
+# define HL_TRANS_CONT 0x10000 /* transparent item without contains arg */
+# define HL_CONCEAL 0x20000 /* can be concealed */
+# define HL_CONCEALENDS 0x40000 /* can be concealed */
+
+/* Values for 'options' argument in do_search() and searchit() */
+#define SEARCH_REV 0x01 /* go in reverse of previous dir. */
+#define SEARCH_ECHO 0x02 /* echo the search command and handle options */
+#define SEARCH_MSG 0x0c /* give messages (yes, it's not 0x04) */
+#define SEARCH_NFMSG 0x08 /* give all messages except not found */
+#define SEARCH_OPT 0x10 /* interpret optional flags */
+#define SEARCH_HIS 0x20 /* put search pattern in history */
+#define SEARCH_END 0x40 /* put cursor at end of match */
+#define SEARCH_NOOF 0x80 /* don't add offset to position */
+#define SEARCH_START 0x100 /* start search without col offset */
+#define SEARCH_MARK 0x200 /* set previous context mark */
+#define SEARCH_KEEP 0x400 /* keep previous search pattern */
+#define SEARCH_PEEK 0x800 /* peek for typed char, cancel search */
+
+/* Values for find_ident_under_cursor() */
+#define FIND_IDENT 1 /* find identifier (word) */
+#define FIND_STRING 2 /* find any string (WORD) */
+#define FIND_EVAL 4 /* include "->", "[]" and "." */
+
+/* Values for file_name_in_line() */
+#define FNAME_MESS 1 /* give error message */
+#define FNAME_EXP 2 /* expand to path */
+#define FNAME_HYP 4 /* check for hypertext link */
+#define FNAME_INCL 8 /* apply 'includeexpr' */
+#define FNAME_REL 16 /* ".." and "./" are relative to the (current)
+ file instead of the current directory */
+
+/* Values for buflist_getfile() */
+#define GETF_SETMARK 0x01 /* set pcmark before jumping */
+#define GETF_ALT 0x02 /* jumping to alternate file (not buf num) */
+#define GETF_SWITCH 0x04 /* respect 'switchbuf' settings when jumping */
+
+/* Values for buflist_new() flags */
+#define BLN_CURBUF 1 /* May re-use curbuf for new buffer */
+#define BLN_LISTED 2 /* Put new buffer in buffer list */
+#define BLN_DUMMY 4 /* Allocating dummy buffer */
+
+/* Values for in_cinkeys() */
+#define KEY_OPEN_FORW 0x101
+#define KEY_OPEN_BACK 0x102
+#define KEY_COMPLETE 0x103 /* end of completion */
+
+/* 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 */
+
+/* Values for mch_call_shell() second argument */
+#define SHELL_FILTER 1 /* filtering text */
+#define SHELL_EXPAND 2 /* expanding wildcards */
+#define SHELL_COOKED 4 /* set term to cooked mode */
+#define SHELL_DOOUT 8 /* redirecting output */
+#define SHELL_SILENT 16 /* don't print error returned by command */
+#define SHELL_READ 32 /* read lines and insert into buffer */
+#define SHELL_WRITE 64 /* write lines from buffer */
+
+/* Values returned by mch_nodetype() */
+#define NODE_NORMAL 0 /* file or directory, check with mch_isdir()*/
+#define NODE_WRITABLE 1 /* something we can write to (character
+ device, fifo, socket, ..) */
+#define NODE_OTHER 2 /* non-writable thing (e.g., block device) */
+
+/* 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 change_indent() */
+#define INDENT_SET 1 /* set indent */
+#define INDENT_INC 2 /* increase indent */
+#define INDENT_DEC 3 /* decrease indent */
+
+/* Values for flags argument for findmatchlimit() */
+#define FM_BACKWARD 0x01 /* search backwards */
+#define FM_FORWARD 0x02 /* search forwards */
+#define FM_BLOCKSTOP 0x04 /* stop at start/end of block */
+#define FM_SKIPCOMM 0x08 /* skip comments */
+
+/* Values for action argument for do_buffer() */
+#define DOBUF_GOTO 0 /* go to specified buffer */
+#define DOBUF_SPLIT 1 /* split window and go to specified buffer */
+#define DOBUF_UNLOAD 2 /* unload specified buffer(s) */
+#define DOBUF_DEL 3 /* delete specified buffer(s) from buflist */
+#define DOBUF_WIPE 4 /* delete specified buffer(s) really */
+
+/* Values for start argument for do_buffer() */
+#define DOBUF_CURRENT 0 /* "count" buffer from current buffer */
+#define DOBUF_FIRST 1 /* "count" buffer from first buffer */
+#define DOBUF_LAST 2 /* "count" buffer from last buffer */
+#define DOBUF_MOD 3 /* "count" mod. buffer from current buffer */
+
+/* Values for sub_cmd and which_pat argument for search_regcomp() */
+/* Also used for which_pat argument for searchit() */
+#define RE_SEARCH 0 /* save/use pat in/from search_pattern */
+#define RE_SUBST 1 /* save/use pat in/from subst_pattern */
+#define RE_BOTH 2 /* save pat in both patterns */
+#define RE_LAST 2 /* use last used pattern if "pat" is NULL */
+
+/* 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 ] */
+
+/* values for reg_do_extmatch */
+# define REX_SET 1 /* to allow \z\(...\), */
+# define REX_USE 2 /* to allow \z\1 et al. */
+
+/* Return values for fullpathcmp() */
+/* Note: can use (fullpathcmp() & FPC_SAME) to check for equal files */
+#define FPC_SAME 1 /* both exist and are the same file. */
+#define FPC_DIFF 2 /* both exist and are different files. */
+#define FPC_NOTX 4 /* both don't exist. */
+#define FPC_DIFFX 6 /* one of them doesn't exist. */
+#define FPC_SAMEX 7 /* both don't exist and file names are same. */
+
+/* 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 */
+#define ECMD_LAST (linenr_T)-1 /* use last position in all files */
+#define ECMD_ONE (linenr_T)1 /* use first line */
+
+/* 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 beginline() */
+#define BL_WHITE 1 /* cursor on first non-white in the line */
+#define BL_SOL 2 /* use 'sol' option */
+#define BL_FIX 4 /* don't leave cursor on a NUL */
+
+/* flags for mf_sync() */
+#define MFS_ALL 1 /* also sync blocks with negative numbers */
+#define MFS_STOP 2 /* stop syncing when a character is available */
+#define MFS_FLUSH 4 /* flushed file to disk */
+#define MFS_ZERO 8 /* only write block 0 */
+
+/* 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 for do_put() */
+#define PUT_FIXINDENT 1 /* make indent look nice */
+#define PUT_CURSEND 2 /* leave cursor after end of new text */
+#define PUT_CURSLINE 4 /* leave cursor on last line of new text */
+#define PUT_LINE 8 /* put register as lines */
+#define PUT_LINE_SPLIT 16 /* split line for linewise register */
+#define PUT_LINE_FORWARD 32 /* put linewise register below Visual sel. */
+
+/* flags for set_indent() */
+#define SIN_CHANGED 1 /* call changed_bytes() when line changed */
+#define SIN_INSERT 2 /* insert indent before existing text */
+#define SIN_UNDO 4 /* save line for undo before changing it */
+
+/* flags for insertchar() */
+#define INSCHAR_FORMAT 1 /* force formatting */
+#define INSCHAR_DO_COM 2 /* format comments */
+#define INSCHAR_CTRLV 4 /* char typed just after CTRL-V */
+#define INSCHAR_NO_FEX 8 /* don't use 'formatexpr' */
+#define INSCHAR_COM_LIST 16 /* format comments with list/2nd line indent */
+
+/* flags for open_line() */
+#define OPENLINE_DELSPACES 1 /* delete spaces after cursor */
+#define OPENLINE_DO_COM 2 /* format comments */
+#define OPENLINE_KEEPTRAIL 4 /* keep trailing spaces */
+#define OPENLINE_MARKFIX 8 /* fix mark positions */
+#define OPENLINE_COM_LIST 16 /* format comments with list/2nd line indent */
+
+/*
+ * There are four history tables:
+ */
+#define HIST_CMD 0 /* colon commands */
+#define HIST_SEARCH 1 /* search commands */
+#define HIST_EXPR 2 /* expressions (from entering = register) */
+#define HIST_INPUT 3 /* input() lines */
+#define HIST_DEBUG 4 /* debug commands */
+#define HIST_COUNT 5 /* number of history tables */
+
+/*
+ * 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 */
+
+/*
+ * Values for do_tag().
+ */
+#define DT_TAG 1 /* jump to newer position or same tag again */
+#define DT_POP 2 /* jump to older position */
+#define DT_NEXT 3 /* jump to next match of same tag */
+#define DT_PREV 4 /* jump to previous match of same tag */
+#define DT_FIRST 5 /* jump to first match of same tag */
+#define DT_LAST 6 /* jump to first match of same tag */
+#define DT_SELECT 7 /* jump to selection from list */
+#define DT_HELP 8 /* like DT_TAG, but no wildcards */
+#define DT_JUMP 9 /* jump to new tag or selection from list */
+#define DT_CSCOPE 10 /* cscope find command (like tjump) */
+#define DT_LTAG 11 /* tag using location list */
+#define DT_FREE 99 /* free cached matches */
+
+/*
+ * flags for find_tags().
+ */
+#define TAG_HELP 1 /* only search for help tags */
+#define TAG_NAMES 2 /* only return name of tag */
+#define TAG_REGEXP 4 /* use tag pattern as regexp */
+#define TAG_NOIC 8 /* don't always ignore case */
+# define TAG_CSCOPE 16 /* cscope tag */
+#define TAG_VERBOSE 32 /* message verbosity */
+#define TAG_INS_COMP 64 /* Currently doing insert completion */
+#define TAG_KEEP_LANG 128 /* keep current language */
+
+#define TAG_MANY 300 /* When finding many tags (for completion),
+ find up to this many tags */
+
+/*
+ * Types of dialogs passed to do_vim_dialog().
+ */
+#define VIM_GENERIC 0
+#define VIM_ERROR 1
+#define VIM_WARNING 2
+#define VIM_INFO 3
+#define VIM_QUESTION 4
+#define VIM_LAST_TYPE 4 /* sentinel value */
+
+/*
+ * Return values for functions like gui_yesnocancel()
+ */
+#define VIM_YES 2
+#define VIM_NO 3
+#define VIM_CANCEL 4
+#define VIM_ALL 5
+#define VIM_DISCARDALL 6
+
+/*
+ * arguments for win_split()
+ */
+#define WSP_ROOM 1 /* require enough room */
+#define WSP_VERT 2 /* split vertically */
+#define WSP_TOP 4 /* window at top-left of shell */
+#define WSP_BOT 8 /* window at bottom-right of shell */
+#define WSP_HELP 16 /* creating the help window */
+#define WSP_BELOW 32 /* put new window below/right */
+#define WSP_ABOVE 64 /* put new window above/left */
+#define WSP_NEWLOC 128 /* don't copy location list */
+
+/*
+ * arguments for gui_set_shellsize()
+ */
+#define RESIZE_VERT 1 /* resize vertically */
+#define RESIZE_HOR 2 /* resize horizontally */
+#define RESIZE_BOTH 15 /* resize in both directions */
+
+/*
+ * flags for check_changed()
+ */
+#define CCGD_AW 1 /* do autowrite if buffer was changed */
+#define CCGD_MULTWIN 2 /* check also when several wins for the buf */
+#define CCGD_FORCEIT 4 /* ! used */
+#define CCGD_ALLBUF 8 /* may write all buffers */
+#define CCGD_EXCMD 16 /* may suggest using ! */
+
+/*
+ * "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 */
+
+/* Magic chars used in confirm dialog strings */
+#define DLG_BUTTON_SEP '\n'
+#define DLG_HOTKEY_CHAR '&'
+
+/* Values for "starting" */
+#define NO_SCREEN 2 /* no screen updating yet */
+#define NO_BUFFERS 1 /* not all buffers loaded yet */
+/* 0 not starting anymore */
+
+/* Values for swap_exists_action: what to do when swap file already exists */
+#define SEA_NONE 0 /* don't use dialog */
+#define SEA_DIALOG 1 /* use dialog when possible */
+#define SEA_QUIT 2 /* quit editing the file */
+#define SEA_RECOVER 3 /* recover the file */
+
+/*
+ * 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
+
+/* 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 */
+
+/*
+ * Events for autocommands.
+ */
+enum auto_event {
+ EVENT_BUFADD = 0, /* after adding a buffer to the buffer list */
+ EVENT_BUFNEW, /* after creating any buffer */
+ EVENT_BUFDELETE, /* deleting a buffer from the buffer list */
+ EVENT_BUFWIPEOUT, /* just before really deleting a buffer */
+ EVENT_BUFENTER, /* after entering a buffer */
+ EVENT_BUFFILEPOST, /* after renaming a buffer */
+ EVENT_BUFFILEPRE, /* before renaming a buffer */
+ EVENT_BUFLEAVE, /* before leaving a buffer */
+ EVENT_BUFNEWFILE, /* when creating a buffer for a new file */
+ EVENT_BUFREADPOST, /* after reading a buffer */
+ EVENT_BUFREADPRE, /* before reading a buffer */
+ EVENT_BUFREADCMD, /* read buffer using command */
+ EVENT_BUFUNLOAD, /* just before unloading a buffer */
+ EVENT_BUFHIDDEN, /* just after buffer becomes hidden */
+ EVENT_BUFWINENTER, /* after showing a buffer in a window */
+ EVENT_BUFWINLEAVE, /* just after buffer removed from window */
+ EVENT_BUFWRITEPOST, /* after writing a buffer */
+ EVENT_BUFWRITEPRE, /* before writing a buffer */
+ EVENT_BUFWRITECMD, /* write buffer using command */
+ EVENT_CMDWINENTER, /* after entering the cmdline window */
+ EVENT_CMDWINLEAVE, /* before leaving the cmdline window */
+ EVENT_COLORSCHEME, /* after loading a colorscheme */
+ EVENT_COMPLETEDONE, /* after finishing insert complete */
+ EVENT_FILEAPPENDPOST, /* after appending to a file */
+ EVENT_FILEAPPENDPRE, /* before appending to a file */
+ EVENT_FILEAPPENDCMD, /* append to a file using command */
+ EVENT_FILECHANGEDSHELL, /* after shell command that changed file */
+ EVENT_FILECHANGEDSHELLPOST, /* after (not) reloading changed file */
+ EVENT_FILECHANGEDRO, /* before first change to read-only file */
+ EVENT_FILEREADPOST, /* after reading a file */
+ EVENT_FILEREADPRE, /* before reading a file */
+ EVENT_FILEREADCMD, /* read from a file using command */
+ EVENT_FILETYPE, /* new file type detected (user defined) */
+ EVENT_FILEWRITEPOST, /* after writing a file */
+ EVENT_FILEWRITEPRE, /* before writing a file */
+ EVENT_FILEWRITECMD, /* write to a file using command */
+ EVENT_FILTERREADPOST, /* after reading from a filter */
+ EVENT_FILTERREADPRE, /* before reading from a filter */
+ EVENT_FILTERWRITEPOST, /* after writing to a filter */
+ EVENT_FILTERWRITEPRE, /* before writing to a filter */
+ EVENT_FOCUSGAINED, /* got the focus */
+ EVENT_FOCUSLOST, /* lost the focus to another app */
+ EVENT_GUIENTER, /* after starting the GUI */
+ EVENT_GUIFAILED, /* after starting the GUI failed */
+ EVENT_INSERTCHANGE, /* when changing Insert/Replace mode */
+ EVENT_INSERTENTER, /* when entering Insert mode */
+ EVENT_INSERTLEAVE, /* when leaving Insert mode */
+ EVENT_MENUPOPUP, /* just before popup menu is displayed */
+ EVENT_QUICKFIXCMDPOST, /* after :make, :grep etc. */
+ EVENT_QUICKFIXCMDPRE, /* before :make, :grep etc. */
+ EVENT_QUITPRE, /* before :quit */
+ EVENT_SESSIONLOADPOST, /* after loading a session file */
+ EVENT_STDINREADPOST, /* after reading from stdin */
+ EVENT_STDINREADPRE, /* before reading from stdin */
+ EVENT_SYNTAX, /* syntax selected */
+ EVENT_TERMCHANGED, /* after changing 'term' */
+ EVENT_TERMRESPONSE, /* after setting "v:termresponse" */
+ EVENT_USER, /* user defined autocommand */
+ EVENT_VIMENTER, /* after starting Vim */
+ EVENT_VIMLEAVE, /* before exiting Vim */
+ EVENT_VIMLEAVEPRE, /* before exiting Vim and writing .viminfo */
+ EVENT_VIMRESIZED, /* after Vim window was resized */
+ EVENT_WINENTER, /* after entering a window */
+ EVENT_WINLEAVE, /* before leaving a window */
+ EVENT_ENCODINGCHANGED, /* after changing the 'encoding' option */
+ EVENT_INSERTCHARPRE, /* before inserting a char */
+ EVENT_CURSORHOLD, /* cursor in same position for a while */
+ EVENT_CURSORHOLDI, /* idem, in Insert mode */
+ EVENT_FUNCUNDEFINED, /* if calling a function which doesn't exist */
+ EVENT_REMOTEREPLY, /* upon string reception from a remote vim */
+ EVENT_SWAPEXISTS, /* found existing swap file */
+ EVENT_SOURCEPRE, /* before sourcing a Vim script */
+ EVENT_SOURCECMD, /* sourcing a Vim script using command */
+ EVENT_SPELLFILEMISSING, /* spell file missing */
+ EVENT_CURSORMOVED, /* cursor was moved */
+ EVENT_CURSORMOVEDI, /* cursor was moved in Insert mode */
+ EVENT_TABLEAVE, /* before leaving a tab page */
+ EVENT_TABENTER, /* after entering a tab page */
+ EVENT_SHELLCMDPOST, /* after ":!cmd" */
+ EVENT_SHELLFILTERPOST, /* after ":1,2!cmd", ":w !cmd", ":r !cmd". */
+ EVENT_TEXTCHANGED, /* text was modified */
+ EVENT_TEXTCHANGEDI, /* text was modified in Insert mode*/
+ NUM_EVENTS /* MUST be the last one */
+};
+
+typedef enum auto_event event_T;
+
+/*
+ * 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_AT /* @ and ~ 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_H /* obsolete, ignored */
+ , 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', '@', 'd', 'e', 'h', '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'}
+
+/*
+ * Boolean constants
+ */
+#ifndef TRUE
+# 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 */
+
+#ifndef UINT32_T
+typedef UINT32_TYPEDEF UINT32_T;
+#endif
+
+/*
+ * Operator IDs; The order must correspond to opchars[] in ops.c!
+ */
+#define OP_NOP 0 /* no pending operation */
+#define OP_DELETE 1 /* "d" delete operator */
+#define OP_YANK 2 /* "y" yank operator */
+#define OP_CHANGE 3 /* "c" change operator */
+#define OP_LSHIFT 4 /* "<" left shift operator */
+#define OP_RSHIFT 5 /* ">" right shift operator */
+#define OP_FILTER 6 /* "!" filter operator */
+#define OP_TILDE 7 /* "g~" switch case operator */
+#define OP_INDENT 8 /* "=" indent operator */
+#define OP_FORMAT 9 /* "gq" format operator */
+#define OP_COLON 10 /* ":" colon operator */
+#define OP_UPPER 11 /* "gU" make upper case operator */
+#define OP_LOWER 12 /* "gu" make lower case operator */
+#define OP_JOIN 13 /* "J" join operator, only for Visual mode */
+#define OP_JOIN_NS 14 /* "gJ" join operator, only for Visual mode */
+#define OP_ROT13 15 /* "g?" rot-13 encoding */
+#define OP_REPLACE 16 /* "r" replace chars, only for Visual mode */
+#define OP_INSERT 17 /* "I" Insert column, only for Visual mode */
+#define OP_APPEND 18 /* "A" Append column, only for Visual mode */
+#define OP_FOLD 19 /* "zf" define a fold */
+#define OP_FOLDOPEN 20 /* "zo" open folds */
+#define OP_FOLDOPENREC 21 /* "zO" open folds recursively */
+#define OP_FOLDCLOSE 22 /* "zc" close folds */
+#define OP_FOLDCLOSEREC 23 /* "zC" close folds recursively */
+#define OP_FOLDDEL 24 /* "zd" delete folds */
+#define OP_FOLDDELREC 25 /* "zD" delete folds recursively */
+#define OP_FORMAT2 26 /* "gw" format operator, keeps cursor pos */
+#define OP_FUNCTION 27 /* "g@" call 'operatorfunc' */
+
+/*
+ * Motion types, used for operators and for yank/delete registers.
+ */
+#define MCHAR 0 /* character-wise movement/register */
+#define MLINE 1 /* line-wise movement/register */
+#define MBLOCK 2 /* block-wise register */
+
+#define MAUTO 0xff /* Decide between MLINE/MCHAR */
+
+/*
+ * Minimum screen size
+ */
+#define MIN_COLUMNS 12 /* minimal columns for screen */
+#define MIN_LINES 2 /* minimal lines for screen */
+#define STATUS_HEIGHT 1 /* height of a status line under a window */
+#define QF_WINHEIGHT 10 /* default height for quickfix window */
+
+/*
+ * Buffer sizes
+ */
+#ifndef CMDBUFFSIZE
+# define CMDBUFFSIZE 256 /* size of the command processing buffer */
+#endif
+
+#define LSIZE 512 /* max. size of a line in the tags file */
+
+#define IOSIZE (1024+1) /* file i/o and sprintf buffer size */
+
+#define DIALOG_MSG_SIZE 1000 /* buffer size for dialog_msg() */
+
+# 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) */
+
+/* Size of the buffer used for tgetent(). Unfortunately this is largely
+ * undocumented, some systems use 1024. Using a buffer that is too small
+ * causes a buffer overrun and a crash. Use the maximum known value to stay
+ * on the safe side. */
+#define TBUFSZ 2048 /* buffer size for termcap entry */
+
+/*
+ * 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. */
+#define UNDO_HASH_SIZE 32
+
+#ifdef HAVE_FCNTL_H
+# include <fcntl.h>
+#endif
+
+#ifdef BINARY_FILE_IO
+# define WRITEBIN "wb" /* no CR-LF translation */
+# define READBIN "rb"
+# define APPENDBIN "ab"
+#else
+# define WRITEBIN "w"
+# define READBIN "r"
+# define APPENDBIN "a"
+#endif
+
+/*
+ * EMX doesn't have a global way of making open() use binary I/O.
+ * Use O_BINARY for all open() calls.
+ */
+# define O_EXTRA 0
+
+#ifndef O_NOFOLLOW
+# define O_NOFOLLOW 0
+#endif
+
+#ifndef W_OK
+# define W_OK 2 /* for systems that don't have W_OK in unistd.h */
+#endif
+#ifndef R_OK
+# define R_OK 4 /* for systems that don't have R_OK in unistd.h */
+#endif
+
+/*
+ * defines to avoid typecasts from (char_u *) to (char *) and back
+ * (vim_strchr() and vim_strrchr() are now in alloc.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))
+#define STRCMP(d, s) strcmp((char *)(d), (char *)(s))
+#define STRNCMP(d, s, n) strncmp((char *)(d), (char *)(s), (size_t)(n))
+#ifdef HAVE_STRCASECMP
+# define STRICMP(d, s) strcasecmp((char *)(d), (char *)(s))
+#else
+# ifdef HAVE_STRICMP
+# define STRICMP(d, s) stricmp((char *)(d), (char *)(s))
+# else
+# define STRICMP(d, s) vim_stricmp((char *)(d), (char *)(s))
+# endif
+#endif
+
+/* Like strcpy() but allows overlapped source and destination. */
+#define STRMOVE(d, s) mch_memmove((d), (s), STRLEN(s) + 1)
+
+#ifdef HAVE_STRNCASECMP
+# define STRNICMP(d, s, n) strncasecmp((char *)(d), (char *)(s), (size_t)(n))
+#else
+# ifdef HAVE_STRNICMP
+# define STRNICMP(d, s, n) strnicmp((char *)(d), (char *)(s), (size_t)(n))
+# else
+# define STRNICMP(d, s, n) vim_strnicmp((char *)(d), (char *)(s), (size_t)(n))
+# endif
+#endif
+
+/* 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. */
+
+# define MB_STRICMP(d, s) mb_strnicmp((char_u *)(d), (char_u *)(s), \
+ (int)MAXCOL)
+# define MB_STRNICMP(d, s, n) mb_strnicmp((char_u *)(d), (char_u *)(s), \
+ (int)(n))
+
+#define STRCAT(d, s) strcat((char *)(d), (char *)(s))
+#define STRNCAT(d, s, n) strncat((char *)(d), (char *)(s), (size_t)(n))
+
+#ifdef HAVE_STRPBRK
+# define vim_strpbrk(s, cs) (char_u *)strpbrk((char *)(s), (char *)(cs))
+#endif
+
+#define MSG(s) msg((char_u *)(s))
+#define MSG_ATTR(s, attr) msg_attr((char_u *)(s), (attr))
+#define EMSG(s) emsg((char_u *)(s))
+#define EMSG2(s, p) emsg2((char_u *)(s), (char_u *)(p))
+#define EMSG3(s, p, q) emsg3((char_u *)(s), (char_u *)(p), \
+ (char_u *)(q))
+#define EMSGN(s, n) emsgn((char_u *)(s), (long)(n))
+#define EMSGU(s, n) emsgu((char_u *)(s), (long_u)(n))
+#define OUT_STR(s) out_str((char_u *)(s))
+#define OUT_STR_NF(s) out_str_nf((char_u *)(s))
+#define MSG_PUTS(s) msg_puts((char_u *)(s))
+#define MSG_PUTS_ATTR(s, a) msg_puts_attr((char_u *)(s), (a))
+#define MSG_PUTS_TITLE(s) msg_puts_title((char_u *)(s))
+#define MSG_PUTS_LONG(s) msg_puts_long_attr((char_u *)(s), 0)
+#define MSG_PUTS_LONG_ATTR(s, a) msg_puts_long_attr((char_u *)(s), (a))
+
+/* Prefer using emsg3(), because perror() may send the output to the wrong
+ * destination and mess up the screen. */
+#ifdef HAVE_STRERROR
+# define PERROR(msg) (void)emsg3((char_u *)"%s: %s", \
+ (char_u *)msg, (char_u *)strerror( \
+ errno))
+#else
+# define PERROR(msg) perror(msg)
+#endif
+
+typedef long linenr_T; /* line number type */
+typedef int colnr_T; /* column number type */
+typedef unsigned short disptick_T; /* display tick type */
+
+#define MAXLNUM (0x7fffffffL) /* maximum (invalid) line number */
+
+/*
+ * Well, you won't believe it, but some S/390 machines ("host", now also known
+ * as zServer) use 31 bit pointers. There are also some newer machines, that
+ * use 64 bit pointers. I don't know how to distinguish between 31 and 64 bit
+ * machines, so the best way is to assume 31 bits whenever we detect OS/390
+ * Unix.
+ * With this we restrict the maximum line length to 1073741823. I guess this is
+ * not a real problem. BTW: Longer lines are split.
+ */
+#if SIZEOF_INT >= 4
+# ifdef __MVS__
+# define MAXCOL (0x3fffffffL) /* maximum column number, 30 bits */
+# else
+# define MAXCOL (0x7fffffffL) /* maximum column number, 31 bits */
+# endif
+#else
+# define MAXCOL (0x7fff) /* maximum column number, 15 bits */
+#endif
+
+#define SHOWCMD_COLS 10 /* columns needed by shown command */
+#define STL_MAX_ITEM 80 /* max nr of %<flag> in statusline */
+
+typedef void *vim_acl_T; /* dummy to pass an ACL to a function */
+
+/*
+ * Include a prototype for mch_memmove(), it may not be in alloc.pro.
+ */
+#ifdef VIM_MEMMOVE
+void mch_memmove __ARGS((void *, void *, size_t));
+#else
+# ifndef mch_memmove
+# define mch_memmove(to, from, len) memmove(to, from, len)
+# endif
+#endif
+
+/*
+ * 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))
+
+#ifdef HAVE_MEMSET
+# define vim_memset(ptr, c, size) memset((ptr), (c), (size))
+#else
+void *vim_memset __ARGS((void *, int, size_t));
+#endif
+
+#ifdef HAVE_MEMCMP
+# define vim_memcmp(p1, p2, len) memcmp((p1), (p2), (len))
+#else
+# ifdef HAVE_BCMP
+# define vim_memcmp(p1, p2, len) bcmp((p1), (p2), (len))
+# else
+int vim_memcmp __ARGS((void *, void *, size_t));
+# define VIM_MEMCMP
+# endif
+#endif
+
+#if defined(UNIX) || defined(FEAT_GUI) || defined(OS2) || defined(VMS) \
+ || defined(FEAT_CLIENTSERVER)
+# define USE_INPUT_BUF
+#endif
+
+#ifndef EINTR
+# define read_eintr(fd, buf, count) vim_read((fd), (buf), (count))
+# define write_eintr(fd, buf, count) vim_write((fd), (buf), (count))
+#endif
+
+# define vim_read(fd, buf, count) read((fd), (char *)(buf), (size_t) (count))
+# define vim_write(fd, buf, count) write((fd), (char *)(buf), (size_t) (count))
+
+/*
+ * 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)]
+
+/*
+ * vim_iswhite() is used for "^" and the like. It differs from isspace()
+ * because it doesn't include <CR> and <LF> and the like.
+ */
+#define vim_iswhite(x) ((x) == ' ' || (x) == '\t')
+
+/*
+ * EXTERN is only defined in main.c. That's where global variables are
+ * actually defined and initialized.
+ */
+#ifndef EXTERN
+# define EXTERN extern
+# define INIT(x)
+#else
+# ifndef INIT
+# define INIT(x) x
+# define DO_INIT
+# endif
+#endif
+
+# define MAX_MCO 6 /* maximum value for 'maxcombine' */
+
+/* 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
+
+typedef struct timeval proftime_T;
+
+/* Include option.h before structs.h, because the number of window-local and
+ * buffer-local options is used there. */
+#include "option.h" /* options and default values */
+
+/* Note that gui.h is included by structs.h */
+
+#include "structs.h" /* file that defines many structures */
+
+/* Values for "do_profiling". */
+#define PROF_NONE 0 /* profiling not started */
+#define PROF_YES 1 /* profiling busy */
+#define PROF_PAUSED 2 /* profiling paused */
+
+
+/* Codes for mouse button events in lower three bits: */
+# define MOUSE_LEFT 0x00
+# define MOUSE_MIDDLE 0x01
+# define MOUSE_RIGHT 0x02
+# define MOUSE_RELEASE 0x03
+
+/* bit masks for modifiers: */
+# define MOUSE_SHIFT 0x04
+# define MOUSE_ALT 0x08
+# define MOUSE_CTRL 0x10
+
+/* mouse buttons that are handled like a key press (GUI only) */
+/* Note that the scroll wheel keys are inverted: MOUSE_5 scrolls lines up but
+ * the result of this is that the window moves down, similarly MOUSE_6 scrolls
+ * columns left but the window moves right. */
+# define MOUSE_4 0x100 /* scroll wheel down */
+# define MOUSE_5 0x200 /* scroll wheel up */
+
+# define MOUSE_X1 0x300 /* Mouse-button X1 (6th) */
+# define MOUSE_X2 0x400 /* Mouse-button X2 */
+
+# define MOUSE_6 0x500 /* scroll wheel left */
+# define MOUSE_7 0x600 /* scroll wheel right */
+
+/* 0x20 is reserved by xterm */
+# define MOUSE_DRAG_XTERM 0x40
+
+# define MOUSE_DRAG (0x40 | MOUSE_RELEASE)
+
+/* Lowest button code for using the mouse wheel (xterm only) */
+# define MOUSEWHEEL_LOW 0x60
+
+# define MOUSE_CLICK_MASK 0x03
+
+# define NUM_MOUSE_CLICKS(code) \
+ (((unsigned)((code) & 0xC0) >> 6) + 1)
+
+# define SET_NUM_MOUSE_CLICKS(code, num) \
+ (code) = ((code) & 0x3f) | ((((num) - 1) & 3) << 6)
+
+/* Added to mouse column for GUI when 'mousefocus' wants to give focus to a
+ * window by simulating a click on its status line. We could use up to 128 *
+ * 128 = 16384 columns, now it's reduced to 10000. */
+# define MOUSE_COLOFF 10000
+
+/*
+ * jump_to_mouse() returns one of first four these values, possibly with
+ * some of the other three added.
+ */
+# define IN_UNKNOWN 0
+# define IN_BUFFER 1
+# define IN_STATUS_LINE 2 /* on status or command line */
+# define IN_SEP_LINE 4 /* on vertical separator line */
+# define IN_OTHER_WIN 8 /* in other window but can't go there */
+# define CURSOR_MOVED 0x100
+# define MOUSE_FOLD_CLOSE 0x200 /* clicked on '-' in fold column */
+# define MOUSE_FOLD_OPEN 0x400 /* clicked on '+' in fold column */
+
+/* flags for jump_to_mouse() */
+# define MOUSE_FOCUS 0x01 /* need to stay in this window */
+# define MOUSE_MAY_VIS 0x02 /* may start Visual mode */
+# define MOUSE_DID_MOVE 0x04 /* only act when mouse has moved */
+# define MOUSE_SETPOS 0x08 /* only set current mouse position */
+# define MOUSE_MAY_STOP_VIS 0x10 /* may stop Visual mode */
+# define MOUSE_RELEASED 0x20 /* button was released */
+
+# if defined(UNIX) && defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
+# define CHECK_DOUBLE_CLICK 1 /* Checking for double clicks ourselves. */
+# endif
+
+
+/* defines for eval_vars() */
+#define VALID_PATH 1
+#define VALID_HEAD 2
+
+/* Defines for Vim variables. These must match vimvars[] in eval.c! */
+#define VV_COUNT 0
+#define VV_COUNT1 1
+#define VV_PREVCOUNT 2
+#define VV_ERRMSG 3
+#define VV_WARNINGMSG 4
+#define VV_STATUSMSG 5
+#define VV_SHELL_ERROR 6
+#define VV_THIS_SESSION 7
+#define VV_VERSION 8
+#define VV_LNUM 9
+#define VV_TERMRESPONSE 10
+#define VV_FNAME 11
+#define VV_LANG 12
+#define VV_LC_TIME 13
+#define VV_CTYPE 14
+#define VV_CC_FROM 15
+#define VV_CC_TO 16
+#define VV_FNAME_IN 17
+#define VV_FNAME_OUT 18
+#define VV_FNAME_NEW 19
+#define VV_FNAME_DIFF 20
+#define VV_CMDARG 21
+#define VV_FOLDSTART 22
+#define VV_FOLDEND 23
+#define VV_FOLDDASHES 24
+#define VV_FOLDLEVEL 25
+#define VV_PROGNAME 26
+#define VV_SEND_SERVER 27
+#define VV_DYING 28
+#define VV_EXCEPTION 29
+#define VV_THROWPOINT 30
+#define VV_REG 31
+#define VV_CMDBANG 32
+#define VV_INSERTMODE 33
+#define VV_VAL 34
+#define VV_KEY 35
+#define VV_PROFILING 36
+#define VV_FCS_REASON 37
+#define VV_FCS_CHOICE 38
+#define VV_BEVAL_BUFNR 39
+#define VV_BEVAL_WINNR 40
+#define VV_BEVAL_LNUM 41
+#define VV_BEVAL_COL 42
+#define VV_BEVAL_TEXT 43
+#define VV_SCROLLSTART 44
+#define VV_SWAPNAME 45
+#define VV_SWAPCHOICE 46
+#define VV_SWAPCOMMAND 47
+#define VV_CHAR 48
+#define VV_MOUSE_WIN 49
+#define VV_MOUSE_LNUM 50
+#define VV_MOUSE_COL 51
+#define VV_OP 52
+#define VV_SEARCHFORWARD 53
+#define VV_HLSEARCH 54
+#define VV_OLDFILES 55
+#define VV_WINDOWID 56
+#define VV_LEN 57 /* number of v: vars */
+
+typedef int VimClipboard; /* This is required for the prototypes. */
+
+
+#include "ex_cmds.h" /* Ex command defines */
+#include "proto.h" /* function prototypes */
+
+/* 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. */
+#if !defined(FEAT_GUI_W32) && !defined(FEAT_GUI_X11) \
+ && !defined(FEAT_GUI_GTK) && !defined(FEAT_GUI_MAC)
+# define mch_errmsg(str) fprintf(stderr, "%s", (str))
+# define display_errors() fflush(stderr)
+# define mch_msg(str) printf("%s", (str))
+#else
+# define USE_MCH_ERRMSG
+#endif
+
+
+
+
+#include "globals.h" /* global variables and messages */
+
+
+
+/*
+ * If console dialog not supported, but GUI dialog is, use the GUI one.
+ */
+
+/*
+ * Default filters for gui_mch_browse().
+ * The filters are almost system independent. Except for the difference
+ * between "*" and "*.*" for MSDOS-like systems.
+ * NOTE: Motif only uses the very first pattern. Therefore
+ * BROWSE_FILTER_DEFAULT should start with a "*" pattern.
+ */
+
+/* stop using fastcall for Borland */
+
+
+/* Note: a NULL argument for vim_realloc() is not portable, don't use it. */
+#if defined(MEM_PROFILE)
+# define vim_realloc(ptr, size) mem_realloc((ptr), (size))
+#else
+# define vim_realloc(ptr, size) realloc((ptr), (size))
+#endif
+
+/*
+ * The following macros stop display/event loop nesting at the wrong time.
+ */
+
+/*
+ * Return byte length of character that starts with byte "b".
+ * Returns 1 for a single-byte character.
+ * 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])
+
+/* properties used in enc_canon_table[] (first three mutually exclusive) */
+# define ENC_8BIT 0x01
+# define ENC_DBCS 0x02
+# define ENC_UNICODE 0x04
+
+# define ENC_ENDIAN_B 0x10 /* Unicode: Big endian */
+# define ENC_ENDIAN_L 0x20 /* Unicode: Little endian */
+
+# define ENC_2BYTE 0x40 /* Unicode: UCS-2 */
+# define ENC_4BYTE 0x80 /* Unicode: UCS-4 */
+# define ENC_2WORD 0x100 /* Unicode: UTF-16 */
+
+# define ENC_LATIN1 0x200 /* Latin1 */
+# define ENC_LATIN9 0x400 /* Latin9 */
+# define ENC_MACROMAN 0x800 /* Mac Roman (not Macro Man! :-) */
+
+# ifdef USE_ICONV
+# ifndef EILSEQ
+# define EILSEQ 123
+# endif
+# ifdef DYNAMIC_ICONV
+/* On Win32 iconv.dll is dynamically loaded. */
+# define ICONV_ERRNO (*iconv_errno())
+# define ICONV_E2BIG 7
+# define ICONV_EINVAL 22
+# define ICONV_EILSEQ 42
+# else
+# define ICONV_ERRNO errno
+# define ICONV_E2BIG E2BIG
+# define ICONV_EINVAL EINVAL
+# define ICONV_EILSEQ EILSEQ
+# endif
+# endif
+
+
+/* ISSYMLINK(mode) tests if a file is a symbolic link. */
+#if (defined(S_IFMT) && defined(S_IFLNK)) || defined(S_ISLNK)
+# define HAVE_ISSYMLINK
+# if defined(S_IFMT) && defined(S_IFLNK)
+# define ISSYMLINK(mode) (((mode) & S_IFMT) == S_IFLNK)
+# else
+# define ISSYMLINK(mode) S_ISLNK(mode)
+# endif
+#endif
+
+#define SIGN_BYTE 1 /* byte value used where sign is displayed;
+ attribute value is sign type */
+
+
+# define X_DISPLAY xterm_dpy
+
+
+# undef NBDEBUG
+# define nbdebug(a)
+
+
+/* values for vim_handle_signal() that are not a signal */
+#define SIGNAL_BLOCK -1
+#define SIGNAL_UNBLOCK -2
+#if !defined(UNIX) && !defined(VMS) && !defined(OS2)
+# define vim_handle_signal(x) 0
+#endif
+
+/* flags for skip_vimgrep_pat() */
+#define VGR_GLOBAL 1
+#define VGR_NOJUMP 2
+
+/* behavior for bad character, "++bad=" argument */
+#define BAD_REPLACE '?' /* replace it with '?' (default) */
+#define BAD_KEEP -1 /* leave it */
+#define BAD_DROP -2 /* erase it */
+
+/* last argument for do_source() */
+#define DOSO_NONE 0
+#define DOSO_VIMRC 1 /* loading vimrc file */
+#define DOSO_GVIMRC 2 /* loading gvimrc file */
+
+/* flags for read_viminfo() and children */
+#define VIF_WANT_INFO 1 /* load non-mark info */
+#define VIF_WANT_MARKS 2 /* load file marks */
+#define VIF_FORCEIT 4 /* overwrite info already read */
+#define VIF_GET_OLDFILES 8 /* load v:oldfiles */
+
+/* flags for buf_freeall() */
+#define BFA_DEL 1 /* buffer is going to be deleted */
+#define BFA_WIPE 2 /* buffer is going to be wiped out */
+#define BFA_KEEP_UNDO 4 /* do not free undo information */
+
+/* direction for nv_mousescroll() and ins_mousescroll() */
+#define MSCR_DOWN 0 /* DOWN must be FALSE */
+#define MSCR_UP 1
+#define MSCR_LEFT -1
+#define MSCR_RIGHT -2
+
+#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 */
+
+/* Return values from win32_fileinfo(). */
+#define FILEINFO_OK 0
+#define FILEINFO_ENC_FAIL 1 /* enc_to_utf16() failed */
+#define FILEINFO_READ_FAIL 2 /* CreateFile() failed */
+#define FILEINFO_INFO_FAIL 3 /* GetFileInformationByHandle() failed */
+
+/* Return value from get_option_value_strict */
+#define SOPT_BOOL 0x01 /* Boolean option */
+#define SOPT_NUM 0x02 /* Number option */
+#define SOPT_STRING 0x04 /* String option */
+#define SOPT_GLOBAL 0x08 /* Option has global value */
+#define SOPT_WIN 0x10 /* Option has window-local value */
+#define SOPT_BUF 0x20 /* Option has buffer-local value */
+#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 */
+
+/* Character used as separated in autoload function/variable names. */
+#define AUTOLOAD_CHAR '#'
+
+# define SET_NO_HLSEARCH(flag) no_hlsearch = (flag); set_vim_var_nr( \
+ VV_HLSEARCH, !no_hlsearch)
+
+#endif /* VIM__H */
diff --git a/src/window.c b/src/window.c
new file mode 100644
index 0000000000..336f9dbcca
--- /dev/null
+++ b/src/window.c
@@ -0,0 +1,5640 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved by Bram Moolenaar
+ *
+ * Do ":help uganda" in Vim to read a list of people who contributed.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ * See README.txt for an overview of the Vim source code.
+ */
+
+#include "vim.h"
+
+static int path_is_url __ARGS((char_u *p));
+static void win_init __ARGS((win_T *newp, win_T *oldp, int flags));
+static void win_init_some __ARGS((win_T *newp, win_T *oldp));
+static void frame_comp_pos __ARGS((frame_T *topfrp, int *row, int *col));
+static void frame_setheight __ARGS((frame_T *curfrp, int height));
+static void frame_setwidth __ARGS((frame_T *curfrp, int width));
+static void win_exchange __ARGS((long));
+static void win_rotate __ARGS((int, int));
+static void win_totop __ARGS((int size, int flags));
+static void win_equal_rec __ARGS((win_T *next_curwin, int current, frame_T *
+ topfr, int dir, int col, int row, int width,
+ int height));
+static int last_window __ARGS((void));
+static int close_last_window_tabpage __ARGS((win_T *win, int free_buf,
+ tabpage_T *prev_curtab));
+static win_T *win_free_mem __ARGS((win_T *win, int *dirp, tabpage_T *tp));
+static frame_T *win_altframe __ARGS((win_T *win, tabpage_T *tp));
+static tabpage_T *alt_tabpage __ARGS((void));
+static win_T *frame2win __ARGS((frame_T *frp));
+static int frame_has_win __ARGS((frame_T *frp, win_T *wp));
+static void frame_new_height __ARGS((frame_T *topfrp, int height, int topfirst,
+ int wfh));
+static int frame_fixed_height __ARGS((frame_T *frp));
+static int frame_fixed_width __ARGS((frame_T *frp));
+static void frame_add_statusline __ARGS((frame_T *frp));
+static void frame_new_width __ARGS((frame_T *topfrp, int width, int leftfirst,
+ int wfw));
+static void frame_add_vsep __ARGS((frame_T *frp));
+static int frame_minwidth __ARGS((frame_T *topfrp, win_T *next_curwin));
+static void frame_fix_width __ARGS((win_T *wp));
+static int win_alloc_firstwin __ARGS((win_T *oldwin));
+static void new_frame __ARGS((win_T *wp));
+static tabpage_T *alloc_tabpage __ARGS((void));
+static int leave_tabpage __ARGS((buf_T *new_curbuf, int trigger_leave_autocmds));
+static void enter_tabpage __ARGS((tabpage_T *tp, buf_T *old_curbuf,
+ int trigger_enter_autocmds,
+ int trigger_leave_autocmds));
+static void frame_fix_height __ARGS((win_T *wp));
+static int frame_minheight __ARGS((frame_T *topfrp, win_T *next_curwin));
+static void win_enter_ext __ARGS((win_T *wp, int undo_sync, int no_curwin,
+ int trigger_enter_autocmds,
+ int trigger_leave_autocmds));
+static void win_free __ARGS((win_T *wp, tabpage_T *tp));
+static void frame_append __ARGS((frame_T *after, frame_T *frp));
+static void frame_insert __ARGS((frame_T *before, frame_T *frp));
+static void frame_remove __ARGS((frame_T *frp));
+static void win_goto_ver __ARGS((int up, long count));
+static void win_goto_hor __ARGS((int left, long count));
+static void frame_add_height __ARGS((frame_T *frp, int n));
+static void last_status_rec __ARGS((frame_T *fr, int statusline));
+
+static void make_snapshot_rec __ARGS((frame_T *fr, frame_T **frp));
+static void clear_snapshot __ARGS((tabpage_T *tp, int idx));
+static void clear_snapshot_rec __ARGS((frame_T *fr));
+static int check_snapshot_rec __ARGS((frame_T *sn, frame_T *fr));
+static win_T *restore_snapshot_rec __ARGS((frame_T *sn, frame_T *fr));
+
+static int frame_check_height __ARGS((frame_T *topfrp, int height));
+static int frame_check_width __ARGS((frame_T *topfrp, int width));
+
+
+static win_T *win_alloc __ARGS((win_T *after, int hidden));
+static void set_fraction __ARGS((win_T *wp));
+
+#define URL_SLASH 1 /* path_is_url() has found "://" */
+#define URL_BACKSLASH 2 /* path_is_url() has found ":\\" */
+
+#define NOWIN (win_T *)-1 /* non-existing window */
+
+# define ROWS_AVAIL (Rows - p_ch - tabline_height())
+
+
+static char *m_onlyone = N_("Already only one window");
+
+/*
+ * all CTRL-W window commands are handled here, called from normal_cmd().
+ */
+void do_window(nchar, Prenum, xchar)
+int nchar;
+long Prenum;
+int xchar; /* extra char from ":wincmd gx" or NUL */
+{
+ long Prenum1;
+ win_T *wp;
+ char_u *ptr;
+ linenr_T lnum = -1;
+ int type = FIND_DEFINE;
+ int len;
+ char_u cbuf[40];
+
+ if (Prenum == 0)
+ Prenum1 = 1;
+ else
+ Prenum1 = Prenum;
+
+# define CHECK_CMDWIN if (cmdwin_type != 0) { EMSG(_(e_cmdwin)); break; }
+
+ switch (nchar) {
+ /* split current window in two parts, horizontally */
+ case 'S':
+ case Ctrl_S:
+ case 's':
+ CHECK_CMDWIN reset_VIsual_and_resel(); /* stop Visual mode */
+ /* When splitting the quickfix window open a new buffer in it,
+ * don't replicate the quickfix buffer. */
+ if (bt_quickfix(curbuf))
+ goto newwindow;
+ win_split((int)Prenum, 0);
+ break;
+
+ /* split current window in two parts, vertically */
+ case Ctrl_V:
+ case 'v':
+ CHECK_CMDWIN reset_VIsual_and_resel(); /* stop Visual mode */
+ /* When splitting the quickfix window open a new buffer in it,
+ * don't replicate the quickfix buffer. */
+ if (bt_quickfix(curbuf))
+ goto newwindow;
+ win_split((int)Prenum, WSP_VERT);
+ break;
+
+ /* split current window and edit alternate file */
+ case Ctrl_HAT:
+ case '^':
+ CHECK_CMDWIN reset_VIsual_and_resel(); /* stop Visual mode */
+ STRCPY(cbuf, "split #");
+ if (Prenum)
+ vim_snprintf((char *)cbuf + 7, sizeof(cbuf) - 7,
+ "%ld", Prenum);
+ do_cmdline_cmd(cbuf);
+ break;
+
+ /* open new window */
+ case Ctrl_N:
+ case 'n':
+ CHECK_CMDWIN reset_VIsual_and_resel(); /* stop Visual mode */
+newwindow:
+ if (Prenum)
+ /* window height */
+ vim_snprintf((char *)cbuf, sizeof(cbuf) - 5, "%ld", Prenum);
+ else
+ cbuf[0] = NUL;
+ if (nchar == 'v' || nchar == Ctrl_V)
+ STRCAT(cbuf, "v");
+ STRCAT(cbuf, "new");
+ do_cmdline_cmd(cbuf);
+ break;
+
+ /* quit current window */
+ case Ctrl_Q:
+ case 'q':
+ reset_VIsual_and_resel(); /* stop Visual mode */
+ do_cmdline_cmd((char_u *)"quit");
+ break;
+
+ /* close current window */
+ case Ctrl_C:
+ case 'c':
+ reset_VIsual_and_resel(); /* stop Visual mode */
+ do_cmdline_cmd((char_u *)"close");
+ break;
+
+ /* close preview window */
+ case Ctrl_Z:
+ case 'z':
+ CHECK_CMDWIN reset_VIsual_and_resel(); /* stop Visual mode */
+ do_cmdline_cmd((char_u *)"pclose");
+ break;
+
+ /* cursor to preview window */
+ case 'P':
+ for (wp = firstwin; wp != NULL; wp = wp->w_next)
+ if (wp->w_p_pvw)
+ break;
+ if (wp == NULL)
+ EMSG(_("E441: There is no preview window"));
+ else
+ win_goto(wp);
+ break;
+
+ /* close all but current window */
+ case Ctrl_O:
+ case 'o':
+ CHECK_CMDWIN reset_VIsual_and_resel(); /* stop Visual mode */
+ do_cmdline_cmd((char_u *)"only");
+ break;
+
+ /* cursor to next window with wrap around */
+ case Ctrl_W:
+ case 'w':
+ /* cursor to previous window with wrap around */
+ case 'W':
+ CHECK_CMDWIN
+ if (firstwin == lastwin && Prenum != 1) /* just one window */
+ beep_flush();
+ else {
+ if (Prenum) { /* go to specified window */
+ for (wp = firstwin; --Prenum > 0; ) {
+ if (wp->w_next == NULL)
+ break;
+ else
+ wp = wp->w_next;
+ }
+ } else {
+ if (nchar == 'W') { /* go to previous window */
+ wp = curwin->w_prev;
+ if (wp == NULL)
+ wp = lastwin; /* wrap around */
+ } else { /* go to next window */
+ wp = curwin->w_next;
+ if (wp == NULL)
+ wp = firstwin; /* wrap around */
+ }
+ }
+ win_goto(wp);
+ }
+ break;
+
+ /* cursor to window below */
+ case 'j':
+ case K_DOWN:
+ case Ctrl_J:
+ CHECK_CMDWIN win_goto_ver(FALSE, Prenum1);
+ break;
+
+ /* cursor to window above */
+ case 'k':
+ case K_UP:
+ case Ctrl_K:
+ CHECK_CMDWIN win_goto_ver(TRUE, Prenum1);
+ break;
+
+ /* cursor to left window */
+ case 'h':
+ case K_LEFT:
+ case Ctrl_H:
+ case K_BS:
+ CHECK_CMDWIN win_goto_hor(TRUE, Prenum1);
+ break;
+
+ /* cursor to right window */
+ case 'l':
+ case K_RIGHT:
+ case Ctrl_L:
+ CHECK_CMDWIN win_goto_hor(FALSE, Prenum1);
+ break;
+
+ /* move window to new tab page */
+ case 'T':
+ if (one_window())
+ MSG(_(m_onlyone));
+ else {
+ tabpage_T *oldtab = curtab;
+ tabpage_T *newtab;
+
+ /* First create a new tab with the window, then go back to
+ * the old tab and close the window there. */
+ wp = curwin;
+ if (win_new_tabpage((int)Prenum) == OK
+ && valid_tabpage(oldtab)) {
+ newtab = curtab;
+ goto_tabpage_tp(oldtab, TRUE, TRUE);
+ if (curwin == wp)
+ win_close(curwin, FALSE);
+ if (valid_tabpage(newtab))
+ goto_tabpage_tp(newtab, TRUE, TRUE);
+ }
+ }
+ break;
+
+ /* cursor to top-left window */
+ case 't':
+ case Ctrl_T:
+ win_goto(firstwin);
+ break;
+
+ /* cursor to bottom-right window */
+ case 'b':
+ case Ctrl_B:
+ win_goto(lastwin);
+ break;
+
+ /* cursor to last accessed (previous) window */
+ case 'p':
+ case Ctrl_P:
+ if (prevwin == NULL)
+ beep_flush();
+ else
+ win_goto(prevwin);
+ break;
+
+ /* exchange current and next window */
+ case 'x':
+ case Ctrl_X:
+ CHECK_CMDWIN win_exchange(Prenum);
+ break;
+
+ /* rotate windows downwards */
+ case Ctrl_R:
+ case 'r':
+ CHECK_CMDWIN reset_VIsual_and_resel(); /* stop Visual mode */
+ win_rotate(FALSE, (int)Prenum1); /* downwards */
+ break;
+
+ /* rotate windows upwards */
+ case 'R':
+ CHECK_CMDWIN reset_VIsual_and_resel(); /* stop Visual mode */
+ win_rotate(TRUE, (int)Prenum1); /* upwards */
+ break;
+
+ /* move window to the very top/bottom/left/right */
+ case 'K':
+ case 'J':
+ case 'H':
+ case 'L':
+ CHECK_CMDWIN win_totop((int)Prenum,
+ ((nchar == 'H' || nchar == 'L') ? WSP_VERT : 0)
+ | ((nchar == 'H' || nchar == 'K') ? WSP_TOP : WSP_BOT));
+ break;
+
+ /* make all windows the same height */
+ case '=':
+ win_equal(NULL, FALSE, 'b');
+ break;
+
+ /* increase current window height */
+ case '+':
+ win_setheight(curwin->w_height + (int)Prenum1);
+ break;
+
+ /* decrease current window height */
+ case '-':
+ win_setheight(curwin->w_height - (int)Prenum1);
+ break;
+
+ /* set current window height */
+ case Ctrl__:
+ case '_':
+ win_setheight(Prenum ? (int)Prenum : 9999);
+ break;
+
+ /* increase current window width */
+ case '>':
+ win_setwidth(curwin->w_width + (int)Prenum1);
+ break;
+
+ /* decrease current window width */
+ case '<':
+ win_setwidth(curwin->w_width - (int)Prenum1);
+ break;
+
+ /* set current window width */
+ case '|':
+ win_setwidth(Prenum != 0 ? (int)Prenum : 9999);
+ break;
+
+ /* jump to tag and split window if tag exists (in preview window) */
+ case '}':
+ CHECK_CMDWIN
+ if (Prenum)
+ g_do_tagpreview = Prenum;
+ else
+ g_do_tagpreview = p_pvh;
+ /*FALLTHROUGH*/
+ case ']':
+ case Ctrl_RSB:
+ CHECK_CMDWIN reset_VIsual_and_resel(); /* stop Visual mode */
+ if (Prenum)
+ postponed_split = Prenum;
+ else
+ postponed_split = -1;
+
+ /* Execute the command right here, required when
+ * "wincmd ]" was used in a function. */
+ do_nv_ident(Ctrl_RSB, NUL);
+ break;
+
+ /* edit file name under cursor in a new window */
+ case 'f':
+ case 'F':
+ case Ctrl_F:
+wingotofile:
+ CHECK_CMDWIN
+
+ ptr = grab_file_name(Prenum1, &lnum);
+ if (ptr != NULL) {
+ 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) {
+ curwin->w_cursor.lnum = lnum;
+ check_cursor_lnum();
+ beginline(BL_SOL | BL_FIX);
+ }
+ }
+ vim_free(ptr);
+ }
+ break;
+
+ /* Go to the first occurrence of the identifier under cursor along path in a
+ * new window -- webb
+ */
+ case 'i': /* Go to any match */
+ case Ctrl_I:
+ type = FIND_ANY;
+ /* FALLTHROUGH */
+ case 'd': /* Go to definition, using 'define' */
+ case Ctrl_D:
+ CHECK_CMDWIN
+ if ((len = find_ident_under_cursor(&ptr, FIND_IDENT)) == 0)
+ break;
+ find_pattern_in_path(ptr, 0, len, TRUE,
+ Prenum == 0 ? TRUE : FALSE, type,
+ Prenum1, ACTION_SPLIT, (linenr_T)1, (linenr_T)MAXLNUM);
+ curwin->w_set_curswant = TRUE;
+ break;
+
+ case K_KENTER:
+ case CAR:
+ /*
+ * In a quickfix window a <CR> jumps to the error under the
+ * cursor in a new window.
+ */
+ if (bt_quickfix(curbuf)) {
+ sprintf((char *)cbuf, "split +%ld%s",
+ (long)curwin->w_cursor.lnum,
+ (curwin->w_llist_ref == NULL) ? "cc" : "ll");
+ do_cmdline_cmd(cbuf);
+ }
+ break;
+
+
+ /* CTRL-W g extended commands */
+ case 'g':
+ case Ctrl_G:
+ CHECK_CMDWIN
+#ifdef USE_ON_FLY_SCROLL
+ dont_scroll = TRUE; /* disallow scrolling here */
+#endif
+ ++ no_mapping;
+ ++allow_keys; /* no mapping for xchar, but allow key codes */
+ if (xchar == NUL)
+ xchar = plain_vgetc();
+ LANGMAP_ADJUST(xchar, TRUE);
+ --no_mapping;
+ --allow_keys;
+ (void)add_to_showcmd(xchar);
+ switch (xchar) {
+ case '}':
+ xchar = Ctrl_RSB;
+ if (Prenum)
+ g_do_tagpreview = Prenum;
+ else
+ g_do_tagpreview = p_pvh;
+ /*FALLTHROUGH*/
+ case ']':
+ case Ctrl_RSB:
+ reset_VIsual_and_resel(); /* stop Visual mode */
+ if (Prenum)
+ postponed_split = Prenum;
+ else
+ postponed_split = -1;
+
+ /* Execute the command right here, required when
+ * "wincmd g}" was used in a function. */
+ do_nv_ident('g', xchar);
+ break;
+
+ case 'f': /* CTRL-W gf: "gf" in a new tab page */
+ case 'F': /* CTRL-W gF: "gF" in a new tab page */
+ cmdmod.tab = tabpage_index(curtab) + 1;
+ nchar = xchar;
+ goto wingotofile;
+ default:
+ beep_flush();
+ break;
+ }
+ break;
+
+ default: beep_flush();
+ break;
+ }
+}
+
+/*
+ * split the current window, implements CTRL-W s and :split
+ *
+ * "size" is the height or width for the new window, 0 to use half of current
+ * height or width.
+ *
+ * "flags":
+ * WSP_ROOM: require enough room for new window
+ * WSP_VERT: vertical split.
+ * WSP_TOP: open window at the top-left of the shell (help window).
+ * WSP_BOT: open window at the bottom-right of the shell (quickfix window).
+ * WSP_HELP: creating the help window, keep layout snapshot
+ *
+ * return FAIL for failure, OK otherwise
+ */
+int win_split(size, flags)
+int size;
+int flags;
+{
+ /* When the ":tab" modifier was used open a new tab page instead. */
+ if (may_open_tabpage() == OK)
+ return OK;
+
+ /* Add flags from ":vertical", ":topleft" and ":botright". */
+ flags |= cmdmod.split;
+ if ((flags & WSP_TOP) && (flags & WSP_BOT)) {
+ EMSG(_("E442: Can't split topleft and botright at the same time"));
+ return FAIL;
+ }
+
+ /* When creating the help window make a snapshot of the window layout.
+ * Otherwise clear the snapshot, it's now invalid. */
+ if (flags & WSP_HELP)
+ make_snapshot(SNAP_HELP_IDX);
+ else
+ clear_snapshot(curtab, SNAP_HELP_IDX);
+
+ return win_split_ins(size, flags, NULL, 0);
+}
+
+/*
+ * When "new_wp" is NULL: split the current window in two.
+ * When "new_wp" is not NULL: insert this window at the far
+ * top/left/right/bottom.
+ * return FAIL for failure, OK otherwise
+ */
+int win_split_ins(size, flags, new_wp, dir)
+int size;
+int flags;
+win_T *new_wp;
+int dir;
+{
+ win_T *wp = new_wp;
+ win_T *oldwin;
+ int new_size = size;
+ int i;
+ int need_status = 0;
+ int do_equal = FALSE;
+ int needed;
+ int available;
+ int oldwin_height = 0;
+ int layout;
+ frame_T *frp, *curfrp;
+ int before;
+
+ if (flags & WSP_TOP)
+ oldwin = firstwin;
+ else if (flags & WSP_BOT)
+ oldwin = lastwin;
+ else
+ 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 (oldwin->w_height <= p_wmh && new_wp == NULL) {
+ EMSG(_(e_noroom));
+ return FAIL;
+ }
+ need_status = STATUS_HEIGHT;
+ }
+
+
+ if (flags & WSP_VERT) {
+ layout = FR_ROW;
+
+ /*
+ * Check if we are able to split the current window and compute its
+ * width.
+ */
+ needed = p_wmw + 1;
+ if (flags & WSP_ROOM)
+ needed += p_wiw - p_wmw;
+ if (p_ea || (flags & (WSP_BOT | WSP_TOP))) {
+ available = topframe->fr_width;
+ needed += frame_minwidth(topframe, NULL);
+ } else
+ available = oldwin->w_width;
+ if (available < needed && new_wp == NULL) {
+ EMSG(_(e_noroom));
+ return FAIL;
+ }
+ if (new_size == 0)
+ new_size = oldwin->w_width / 2;
+ if (new_size > oldwin->w_width - p_wmw - 1)
+ new_size = oldwin->w_width - p_wmw - 1;
+ if (new_size < p_wmw)
+ new_size = p_wmw;
+
+ /* if it doesn't fit in the current window, need win_equal() */
+ if (oldwin->w_width - new_size - 1 < p_wmw)
+ do_equal = TRUE;
+
+ /* We don't like to take lines for the new window from a
+ * 'winfixwidth' window. Take them from a window to the left or right
+ * instead, if possible. */
+ if (oldwin->w_p_wfw)
+ win_setwidth_win(oldwin->w_width + new_size, oldwin);
+
+ /* Only make all windows the same width if one of them (except oldwin)
+ * is wider than one of the split windows. */
+ if (!do_equal && p_ea && size == 0 && *p_ead != 'v'
+ && oldwin->w_frame->fr_parent != NULL) {
+ frp = oldwin->w_frame->fr_parent->fr_child;
+ while (frp != NULL) {
+ if (frp->fr_win != oldwin && frp->fr_win != NULL
+ && (frp->fr_win->w_width > new_size
+ || frp->fr_win->w_width > oldwin->w_width
+ - new_size - STATUS_HEIGHT)) {
+ do_equal = TRUE;
+ break;
+ }
+ frp = frp->fr_next;
+ }
+ }
+ } else {
+ layout = FR_COL;
+
+ /*
+ * Check if we are able to split the current window and compute its
+ * height.
+ */
+ needed = p_wmh + STATUS_HEIGHT + need_status;
+ if (flags & WSP_ROOM)
+ needed += p_wh - p_wmh;
+ if (p_ea || (flags & (WSP_BOT | WSP_TOP))) {
+ available = topframe->fr_height;
+ needed += frame_minheight(topframe, NULL);
+ } else {
+ available = oldwin->w_height;
+ needed += p_wmh;
+ }
+ if (available < needed && new_wp == NULL) {
+ EMSG(_(e_noroom));
+ return FAIL;
+ }
+ oldwin_height = oldwin->w_height;
+ if (need_status) {
+ oldwin->w_status_height = STATUS_HEIGHT;
+ oldwin_height -= STATUS_HEIGHT;
+ }
+ if (new_size == 0)
+ new_size = oldwin_height / 2;
+
+ if (new_size > oldwin_height - p_wmh - STATUS_HEIGHT)
+ new_size = oldwin_height - p_wmh - STATUS_HEIGHT;
+ if (new_size < p_wmh)
+ new_size = p_wmh;
+
+ /* if it doesn't fit in the current window, need win_equal() */
+ if (oldwin_height - new_size - STATUS_HEIGHT < p_wmh)
+ do_equal = TRUE;
+
+ /* We don't like to take lines for the new window from a
+ * 'winfixheight' window. Take them from a window above or below
+ * instead, if possible. */
+ if (oldwin->w_p_wfh) {
+ win_setheight_win(oldwin->w_height + new_size + STATUS_HEIGHT,
+ oldwin);
+ oldwin_height = oldwin->w_height;
+ if (need_status)
+ oldwin_height -= STATUS_HEIGHT;
+ }
+
+ /* Only make all windows the same height if one of them (except oldwin)
+ * is higher than one of the split windows. */
+ if (!do_equal && p_ea && size == 0
+ && *p_ead != 'h'
+ && oldwin->w_frame->fr_parent != NULL) {
+ frp = oldwin->w_frame->fr_parent->fr_child;
+ while (frp != NULL) {
+ if (frp->fr_win != oldwin && frp->fr_win != NULL
+ && (frp->fr_win->w_height > new_size
+ || frp->fr_win->w_height > oldwin_height - new_size
+ - STATUS_HEIGHT)) {
+ do_equal = TRUE;
+ break;
+ }
+ frp = frp->fr_next;
+ }
+ }
+ }
+
+ /*
+ * allocate new window structure and link it in the window list
+ */
+ if ((flags & WSP_TOP) == 0
+ && ((flags & WSP_BOT)
+ || (flags & WSP_BELOW)
+ || (!(flags & WSP_ABOVE)
+ && (
+ (flags & WSP_VERT) ? p_spr :
+ p_sb)))) {
+ /* new window below/right of current one */
+ if (new_wp == NULL)
+ wp = win_alloc(oldwin, FALSE);
+ else
+ win_append(oldwin, wp);
+ } else {
+ if (new_wp == NULL)
+ wp = win_alloc(oldwin->w_prev, FALSE);
+ else
+ win_append(oldwin->w_prev, wp);
+ }
+
+ if (new_wp == NULL) {
+ if (wp == NULL)
+ return FAIL;
+
+ new_frame(wp);
+ if (wp->w_frame == NULL) {
+ win_free(wp, NULL);
+ return FAIL;
+ }
+
+ /* make the contents of the new window the same as the current one */
+ win_init(wp, curwin, flags);
+ }
+
+ /*
+ * Reorganise the tree of frames to insert the new window.
+ */
+ if (flags & (WSP_TOP | WSP_BOT)) {
+ if ((topframe->fr_layout == FR_COL && (flags & WSP_VERT) == 0)
+ || (topframe->fr_layout == FR_ROW && (flags & WSP_VERT) != 0)) {
+ curfrp = topframe->fr_child;
+ if (flags & WSP_BOT)
+ while (curfrp->fr_next != NULL)
+ curfrp = curfrp->fr_next;
+ } else
+ curfrp = topframe;
+ before = (flags & WSP_TOP);
+ } else {
+ curfrp = oldwin->w_frame;
+ if (flags & WSP_BELOW)
+ before = FALSE;
+ else if (flags & WSP_ABOVE)
+ before = TRUE;
+ else if (flags & WSP_VERT)
+ before = !p_spr;
+ else
+ before = !p_sb;
+ }
+ if (curfrp->fr_parent == NULL || curfrp->fr_parent->fr_layout != layout) {
+ /* Need to create a new frame in the tree to make a branch. */
+ frp = (frame_T *)alloc_clear((unsigned)sizeof(frame_T));
+ *frp = *curfrp;
+ curfrp->fr_layout = layout;
+ frp->fr_parent = curfrp;
+ frp->fr_next = NULL;
+ frp->fr_prev = NULL;
+ curfrp->fr_child = frp;
+ curfrp->fr_win = NULL;
+ curfrp = frp;
+ if (frp->fr_win != NULL)
+ oldwin->w_frame = frp;
+ else
+ for (frp = frp->fr_child; frp != NULL; frp = frp->fr_next)
+ frp->fr_parent = curfrp;
+ }
+
+ if (new_wp == NULL)
+ frp = wp->w_frame;
+ else
+ frp = new_wp->w_frame;
+ frp->fr_parent = curfrp->fr_parent;
+
+ /* Insert the new frame at the right place in the frame list. */
+ if (before)
+ frame_insert(curfrp, frp);
+ else
+ frame_append(curfrp, frp);
+
+ /* Set w_fraction now so that the cursor keeps the same relative
+ * vertical position. */
+ if (oldwin->w_height > 0)
+ set_fraction(oldwin);
+ wp->w_fraction = oldwin->w_fraction;
+
+ if (flags & WSP_VERT) {
+ wp->w_p_scr = curwin->w_p_scr;
+
+ if (need_status) {
+ win_new_height(oldwin, oldwin->w_height - 1);
+ oldwin->w_status_height = need_status;
+ }
+ if (flags & (WSP_TOP | WSP_BOT)) {
+ /* set height and row of new window to full height */
+ wp->w_winrow = tabline_height();
+ win_new_height(wp, curfrp->fr_height - (p_ls > 0));
+ wp->w_status_height = (p_ls > 0);
+ } else {
+ /* height and row of new window is same as current window */
+ wp->w_winrow = oldwin->w_winrow;
+ win_new_height(wp, oldwin->w_height);
+ wp->w_status_height = oldwin->w_status_height;
+ }
+ frp->fr_height = curfrp->fr_height;
+
+ /* "new_size" of the current window goes to the new window, use
+ * one column for the vertical separator */
+ win_new_width(wp, new_size);
+ if (before)
+ wp->w_vsep_width = 1;
+ else {
+ wp->w_vsep_width = oldwin->w_vsep_width;
+ oldwin->w_vsep_width = 1;
+ }
+ if (flags & (WSP_TOP | WSP_BOT)) {
+ if (flags & WSP_BOT)
+ frame_add_vsep(curfrp);
+ /* Set width of neighbor frame */
+ frame_new_width(curfrp, curfrp->fr_width
+ - (new_size + ((flags & WSP_TOP) != 0)), flags & WSP_TOP,
+ FALSE);
+ } else
+ win_new_width(oldwin, oldwin->w_width - (new_size + 1));
+ if (before) { /* new window left of current one */
+ wp->w_wincol = oldwin->w_wincol;
+ oldwin->w_wincol += new_size + 1;
+ } else /* new window right of current one */
+ wp->w_wincol = oldwin->w_wincol + oldwin->w_width + 1;
+ frame_fix_width(oldwin);
+ frame_fix_width(wp);
+ } else {
+ /* width and column of new window is same as current window */
+ if (flags & (WSP_TOP | WSP_BOT)) {
+ wp->w_wincol = 0;
+ win_new_width(wp, Columns);
+ wp->w_vsep_width = 0;
+ } else {
+ wp->w_wincol = oldwin->w_wincol;
+ win_new_width(wp, oldwin->w_width);
+ wp->w_vsep_width = oldwin->w_vsep_width;
+ }
+ frp->fr_width = curfrp->fr_width;
+
+ /* "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
+ win_new_height(oldwin, oldwin_height - (new_size + STATUS_HEIGHT));
+ 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;
+ oldwin->w_status_height = STATUS_HEIGHT;
+ }
+ if (flags & WSP_BOT)
+ frame_add_statusline(curfrp);
+ frame_fix_height(wp);
+ frame_fix_height(oldwin);
+ }
+
+ if (flags & (WSP_TOP | WSP_BOT))
+ (void)win_comp_pos();
+
+ /*
+ * Both windows need redrawing
+ */
+ redraw_win_later(wp, NOT_VALID);
+ wp->w_redr_status = TRUE;
+ redraw_win_later(oldwin, NOT_VALID);
+ oldwin->w_redr_status = TRUE;
+
+ if (need_status) {
+ msg_row = Rows - 1;
+ msg_col = sc_col;
+ msg_clr_eos_force(); /* Old command/ruler may still be there */
+ comp_col();
+ msg_row = Rows - 1;
+ msg_col = 0; /* put position back at start of line */
+ }
+
+ /*
+ * equalize the window sizes.
+ */
+ if (do_equal || dir != 0)
+ win_equal(wp, TRUE,
+ (flags & WSP_VERT) ? (dir == 'v' ? 'b' : 'h')
+ : dir == 'h' ? 'b' :
+ 'v');
+
+ /* Don't change the window height/width to 'winheight' / 'winwidth' if a
+ * size was given. */
+ if (flags & WSP_VERT) {
+ i = p_wiw;
+ if (size != 0)
+ p_wiw = size;
+
+ } else {
+ i = p_wh;
+ if (size != 0)
+ p_wh = size;
+ }
+
+ /*
+ * make the new window the current window
+ */
+ win_enter(wp, FALSE);
+ if (flags & WSP_VERT)
+ p_wiw = i;
+ else
+ p_wh = i;
+
+ return OK;
+}
+
+
+/*
+ * Initialize window "newp" from window "oldp".
+ * Used when splitting a window and when creating a new tab page.
+ * The windows will both edit the same buffer.
+ * WSP_NEWLOC may be specified in flags to prevent the location list from
+ * being copied.
+ */
+static void win_init(newp, oldp, flags)
+win_T *newp;
+win_T *oldp;
+int flags UNUSED;
+{
+ int i;
+
+ newp->w_buffer = oldp->w_buffer;
+ newp->w_s = &(oldp->w_buffer->b_s);
+ oldp->w_buffer->b_nwindows++;
+ newp->w_cursor = oldp->w_cursor;
+ newp->w_valid = 0;
+ newp->w_curswant = oldp->w_curswant;
+ newp->w_set_curswant = oldp->w_set_curswant;
+ newp->w_topline = oldp->w_topline;
+ newp->w_topfill = oldp->w_topfill;
+ newp->w_leftcol = oldp->w_leftcol;
+ newp->w_pcmark = oldp->w_pcmark;
+ newp->w_prev_pcmark = oldp->w_prev_pcmark;
+ newp->w_alt_fnum = oldp->w_alt_fnum;
+ newp->w_wrow = oldp->w_wrow;
+ newp->w_fraction = oldp->w_fraction;
+ newp->w_prev_fraction_row = oldp->w_prev_fraction_row;
+ copy_jumplist(oldp, newp);
+ if (flags & WSP_NEWLOC) {
+ /* Don't copy the location list. */
+ newp->w_llist = NULL;
+ newp->w_llist_ref = NULL;
+ } else
+ copy_loclist(oldp, newp);
+ newp->w_localdir = (oldp->w_localdir == NULL)
+ ? NULL : vim_strsave(oldp->w_localdir);
+
+ /* copy tagstack and folds */
+ for (i = 0; i < oldp->w_tagstacklen; i++) {
+ newp->w_tagstack[i] = oldp->w_tagstack[i];
+ if (newp->w_tagstack[i].tagname != NULL)
+ newp->w_tagstack[i].tagname =
+ vim_strsave(newp->w_tagstack[i].tagname);
+ }
+ newp->w_tagstackidx = oldp->w_tagstackidx;
+ newp->w_tagstacklen = oldp->w_tagstacklen;
+ copyFoldingState(oldp, newp);
+
+ win_init_some(newp, oldp);
+
+ check_colorcolumn(newp);
+}
+
+/*
+ * Initialize window "newp" from window"old".
+ * Only the essential things are copied.
+ */
+static void win_init_some(newp, oldp)
+win_T *newp;
+win_T *oldp;
+{
+ /* Use the same argument list. */
+ newp->w_alist = oldp->w_alist;
+ ++newp->w_alist->al_refcount;
+ newp->w_arg_idx = oldp->w_arg_idx;
+
+ /* copy options from existing window */
+ win_copy_options(oldp, newp);
+}
+
+
+/*
+ * Check if "win" is a pointer to an existing window.
+ */
+int win_valid(win)
+win_T *win;
+{
+ win_T *wp;
+
+ if (win == NULL)
+ return FALSE;
+ for (wp = firstwin; wp != NULL; wp = wp->w_next)
+ if (wp == win)
+ return TRUE;
+ return FALSE;
+}
+
+/*
+ * Return the number of windows.
+ */
+int win_count() {
+ win_T *wp;
+ int count = 0;
+
+ for (wp = firstwin; wp != NULL; wp = wp->w_next)
+ ++count;
+ return count;
+}
+
+/*
+ * Make "count" windows on the screen.
+ * Return actual number of windows on the screen.
+ * Must be called when there is just one window, filling the whole screen
+ * (excluding the command line).
+ */
+int make_windows(count, vertical)
+int count;
+int vertical UNUSED; /* split windows vertically if TRUE */
+{
+ int maxcount;
+ int todo;
+
+ if (vertical) {
+ /* Each windows needs at least 'winminwidth' lines and a separator
+ * column. */
+ maxcount = (curwin->w_width + curwin->w_vsep_width
+ - (p_wiw - p_wmw)) / (p_wmw + 1);
+ } else {
+ /* Each window needs at least 'winminheight' lines and a status line. */
+ maxcount = (curwin->w_height + curwin->w_status_height
+ - (p_wh - p_wmh)) / (p_wmh + STATUS_HEIGHT);
+ }
+
+ if (maxcount < 2)
+ maxcount = 2;
+ if (count > maxcount)
+ count = maxcount;
+
+ /*
+ * add status line now, otherwise first window will be too big
+ */
+ if (count > 1)
+ last_status(TRUE);
+
+ /*
+ * Don't execute autocommands while creating the windows. Must do that
+ * when putting the buffers in the windows.
+ */
+ block_autocmds();
+
+ /* todo is number of windows left to create */
+ for (todo = count - 1; todo > 0; --todo)
+ if (vertical) {
+ if (win_split(curwin->w_width - (curwin->w_width - todo)
+ / (todo + 1) - 1, WSP_VERT | WSP_ABOVE) == FAIL)
+ break;
+ } else {
+ if (win_split(curwin->w_height - (curwin->w_height - todo
+ * STATUS_HEIGHT) / (todo + 1)
+ - STATUS_HEIGHT, WSP_ABOVE) == FAIL)
+ break;
+ }
+
+ unblock_autocmds();
+
+ /* return actual number of windows */
+ return count - todo;
+}
+
+/*
+ * Exchange current and next window
+ */
+static void win_exchange(Prenum)
+long Prenum;
+{
+ frame_T *frp;
+ frame_T *frp2;
+ win_T *wp;
+ win_T *wp2;
+ int temp;
+
+ if (lastwin == firstwin) { /* just one window */
+ beep_flush();
+ return;
+ }
+
+
+ /*
+ * find window to exchange with
+ */
+ if (Prenum) {
+ frp = curwin->w_frame->fr_parent->fr_child;
+ while (frp != NULL && --Prenum > 0)
+ frp = frp->fr_next;
+ } else if (curwin->w_frame->fr_next != NULL) /* Swap with next */
+ frp = curwin->w_frame->fr_next;
+ else /* Swap last window in row/col with previous */
+ frp = curwin->w_frame->fr_prev;
+
+ /* We can only exchange a window with another window, not with a frame
+ * containing windows. */
+ if (frp == NULL || frp->fr_win == NULL || frp->fr_win == curwin)
+ return;
+ wp = frp->fr_win;
+
+ /*
+ * 1. remove curwin from the list. Remember after which window it was in wp2
+ * 2. insert curwin before wp in the list
+ * if wp != wp2
+ * 3. remove wp from the list
+ * 4. insert wp after wp2
+ * 5. exchange the status line height and vsep width.
+ */
+ wp2 = curwin->w_prev;
+ frp2 = curwin->w_frame->fr_prev;
+ if (wp->w_prev != curwin) {
+ win_remove(curwin, NULL);
+ frame_remove(curwin->w_frame);
+ win_append(wp->w_prev, curwin);
+ frame_insert(frp, curwin->w_frame);
+ }
+ if (wp != wp2) {
+ win_remove(wp, NULL);
+ frame_remove(wp->w_frame);
+ win_append(wp2, wp);
+ if (frp2 == NULL)
+ frame_insert(wp->w_frame->fr_parent->fr_child, wp->w_frame);
+ else
+ frame_append(frp2, wp->w_frame);
+ }
+ temp = curwin->w_status_height;
+ curwin->w_status_height = wp->w_status_height;
+ wp->w_status_height = temp;
+ temp = curwin->w_vsep_width;
+ curwin->w_vsep_width = wp->w_vsep_width;
+ wp->w_vsep_width = temp;
+
+ /* If the windows are not in the same frame, exchange the sizes to avoid
+ * messing up the window layout. Otherwise fix the frame sizes. */
+ if (curwin->w_frame->fr_parent != wp->w_frame->fr_parent) {
+ temp = curwin->w_height;
+ curwin->w_height = wp->w_height;
+ wp->w_height = temp;
+ temp = curwin->w_width;
+ curwin->w_width = wp->w_width;
+ wp->w_width = temp;
+ } else {
+ frame_fix_height(curwin);
+ frame_fix_height(wp);
+ frame_fix_width(curwin);
+ frame_fix_width(wp);
+ }
+
+ (void)win_comp_pos(); /* recompute window positions */
+
+ win_enter(wp, TRUE);
+ redraw_later(CLEAR);
+}
+
+/*
+ * rotate windows: if upwards TRUE the second window becomes the first one
+ * if upwards FALSE the first window becomes the second one
+ */
+static void win_rotate(upwards, count)
+int upwards;
+int count;
+{
+ win_T *wp1;
+ win_T *wp2;
+ frame_T *frp;
+ int n;
+
+ if (firstwin == lastwin) { /* nothing to do */
+ beep_flush();
+ return;
+ }
+
+
+ /* Check if all frames in this row/col have one window. */
+ for (frp = curwin->w_frame->fr_parent->fr_child; frp != NULL;
+ frp = frp->fr_next)
+ if (frp->fr_win == NULL) {
+ EMSG(_("E443: Cannot rotate when another window is split"));
+ return;
+ }
+
+ while (count--) {
+ if (upwards) { /* first window becomes last window */
+ /* remove first window/frame from the list */
+ frp = curwin->w_frame->fr_parent->fr_child;
+ wp1 = frp->fr_win;
+ win_remove(wp1, NULL);
+ frame_remove(frp);
+
+ /* find last frame and append removed window/frame after it */
+ for (; frp->fr_next != NULL; frp = frp->fr_next)
+ ;
+ win_append(frp->fr_win, wp1);
+ frame_append(frp, wp1->w_frame);
+
+ wp2 = frp->fr_win; /* previously last window */
+ } else { /* last window becomes first window */
+ /* find last window/frame in the list and remove it */
+ for (frp = curwin->w_frame; frp->fr_next != NULL;
+ frp = frp->fr_next)
+ ;
+ wp1 = frp->fr_win;
+ wp2 = wp1->w_prev; /* will become last window */
+ win_remove(wp1, NULL);
+ frame_remove(frp);
+
+ /* append the removed window/frame before the first in the list */
+ win_append(frp->fr_parent->fr_child->fr_win->w_prev, wp1);
+ frame_insert(frp->fr_parent->fr_child, frp);
+ }
+
+ /* exchange status height and vsep width of old and new last window */
+ n = wp2->w_status_height;
+ wp2->w_status_height = wp1->w_status_height;
+ wp1->w_status_height = n;
+ frame_fix_height(wp1);
+ frame_fix_height(wp2);
+ n = wp2->w_vsep_width;
+ wp2->w_vsep_width = wp1->w_vsep_width;
+ wp1->w_vsep_width = n;
+ frame_fix_width(wp1);
+ frame_fix_width(wp2);
+
+ /* recompute w_winrow and w_wincol for all windows */
+ (void)win_comp_pos();
+ }
+
+ redraw_later(CLEAR);
+}
+
+/*
+ * Move the current window to the very top/bottom/left/right of the screen.
+ */
+static void win_totop(size, flags)
+int size;
+int flags;
+{
+ int dir;
+ int height = curwin->w_height;
+
+ if (lastwin == firstwin) {
+ beep_flush();
+ return;
+ }
+
+ /* Remove the window and frame from the tree of frames. */
+ (void)winframe_remove(curwin, &dir, NULL);
+ win_remove(curwin, NULL);
+ last_status(FALSE); /* may need to remove last status line */
+ (void)win_comp_pos(); /* recompute window positions */
+
+ /* Split a window on the desired side and put the window there. */
+ (void)win_split_ins(size, flags, curwin, dir);
+ if (!(flags & WSP_VERT)) {
+ win_setheight(height);
+ if (p_ea)
+ win_equal(curwin, TRUE, 'v');
+ }
+
+}
+
+/*
+ * Move window "win1" to below/right of "win2" and make "win1" the current
+ * window. Only works within the same frame!
+ */
+void win_move_after(win1, win2)
+win_T *win1, *win2;
+{
+ int height;
+
+ /* check if the arguments are reasonable */
+ if (win1 == win2)
+ return;
+
+ /* check if there is something to do */
+ if (win2->w_next != win1) {
+ /* may need move the status line/vertical separator of the last window
+ * */
+ if (win1 == lastwin) {
+ height = win1->w_prev->w_status_height;
+ win1->w_prev->w_status_height = win1->w_status_height;
+ win1->w_status_height = height;
+ if (win1->w_prev->w_vsep_width == 1) {
+ /* Remove the vertical separator from the last-but-one window,
+ * add it to the last window. Adjust the frame widths. */
+ win1->w_prev->w_vsep_width = 0;
+ win1->w_prev->w_frame->fr_width -= 1;
+ win1->w_vsep_width = 1;
+ win1->w_frame->fr_width += 1;
+ }
+ } else if (win2 == lastwin) {
+ height = win1->w_status_height;
+ win1->w_status_height = win2->w_status_height;
+ win2->w_status_height = height;
+ if (win1->w_vsep_width == 1) {
+ /* Remove the vertical separator from win1, add it to the last
+ * window, win2. Adjust the frame widths. */
+ win2->w_vsep_width = 1;
+ win2->w_frame->fr_width += 1;
+ win1->w_vsep_width = 0;
+ win1->w_frame->fr_width -= 1;
+ }
+ }
+ win_remove(win1, NULL);
+ frame_remove(win1->w_frame);
+ win_append(win2, win1);
+ frame_append(win2->w_frame, win1->w_frame);
+
+ (void)win_comp_pos(); /* recompute w_winrow for all windows */
+ redraw_later(NOT_VALID);
+ }
+ win_enter(win1, FALSE);
+}
+
+/*
+ * Make all windows the same height.
+ * 'next_curwin' will soon be the current window, make sure it has enough
+ * rows.
+ */
+void win_equal(next_curwin, current, dir)
+win_T *next_curwin; /* pointer to current window to be or NULL */
+int current; /* do only frame with current window */
+int dir; /* 'v' for vertically, 'h' for horizontally,
+ 'b' for both, 0 for using p_ead */
+{
+ if (dir == 0)
+ dir = *p_ead;
+ win_equal_rec(next_curwin == NULL ? curwin : next_curwin, current,
+ topframe, dir, 0, tabline_height(),
+ (int)Columns, topframe->fr_height);
+}
+
+/*
+ * Set a frame to a new position and height, spreading the available room
+ * equally over contained frames.
+ * The window "next_curwin" (if not NULL) should at least get the size from
+ * 'winheight' and 'winwidth' if possible.
+ */
+static void win_equal_rec(next_curwin, current, topfr, dir, col, row, width,
+ height)
+win_T *next_curwin; /* pointer to current window to be or NULL */
+int current; /* do only frame with current window */
+frame_T *topfr; /* frame to set size off */
+int dir; /* 'v', 'h' or 'b', see win_equal() */
+int col; /* horizontal position for frame */
+int row; /* vertical position for frame */
+int width; /* new width of frame */
+int height; /* new height of frame */
+{
+ int n, m;
+ int extra_sep = 0;
+ int wincount, totwincount = 0;
+ frame_T *fr;
+ int next_curwin_size = 0;
+ int room = 0;
+ int new_size;
+ int has_next_curwin = 0;
+ int hnc;
+
+ if (topfr->fr_layout == FR_LEAF) {
+ /* Set the width/height of this frame.
+ * Redraw when size or position changes */
+ if (topfr->fr_height != height || topfr->fr_win->w_winrow != row
+ || topfr->fr_width != width || topfr->fr_win->w_wincol != col
+ ) {
+ topfr->fr_win->w_winrow = row;
+ frame_new_height(topfr, height, FALSE, FALSE);
+ topfr->fr_win->w_wincol = col;
+ frame_new_width(topfr, width, FALSE, FALSE);
+ redraw_all_later(CLEAR);
+ }
+ } else if (topfr->fr_layout == FR_ROW) {
+ topfr->fr_width = width;
+ topfr->fr_height = height;
+
+ if (dir != 'v') { /* equalize frame widths */
+ /* Compute the maximum number of windows horizontally in this
+ * frame. */
+ n = frame_minwidth(topfr, NOWIN);
+ /* add one for the rightmost window, it doesn't have a separator */
+ if (col + width == Columns)
+ extra_sep = 1;
+ else
+ extra_sep = 0;
+ totwincount = (n + extra_sep) / (p_wmw + 1);
+ has_next_curwin = frame_has_win(topfr, next_curwin);
+
+ /*
+ * Compute width for "next_curwin" window and room available for
+ * other windows.
+ * "m" is the minimal width when counting p_wiw for "next_curwin".
+ */
+ m = frame_minwidth(topfr, next_curwin);
+ room = width - m;
+ if (room < 0) {
+ next_curwin_size = p_wiw + room;
+ room = 0;
+ } else {
+ next_curwin_size = -1;
+ for (fr = topfr->fr_child; fr != NULL; fr = fr->fr_next) {
+ /* If 'winfixwidth' set keep the window width if
+ * possible.
+ * Watch out for this window being the next_curwin. */
+ if (frame_fixed_width(fr)) {
+ n = frame_minwidth(fr, NOWIN);
+ new_size = fr->fr_width;
+ if (frame_has_win(fr, next_curwin)) {
+ room += p_wiw - p_wmw;
+ next_curwin_size = 0;
+ if (new_size < p_wiw)
+ new_size = p_wiw;
+ } else
+ /* These windows don't use up room. */
+ totwincount -= (n + (fr->fr_next == NULL
+ ? extra_sep : 0)) / (p_wmw + 1);
+ room -= new_size - n;
+ if (room < 0) {
+ new_size += room;
+ room = 0;
+ }
+ fr->fr_newwidth = new_size;
+ }
+ }
+ if (next_curwin_size == -1) {
+ if (!has_next_curwin)
+ next_curwin_size = 0;
+ else if (totwincount > 1
+ && (room + (totwincount - 2))
+ / (totwincount - 1) > p_wiw) {
+ /* Can make all windows wider than 'winwidth', spread
+ * the room equally. */
+ next_curwin_size = (room + p_wiw
+ + (totwincount - 1) * p_wmw
+ + (totwincount - 1)) / totwincount;
+ room -= next_curwin_size - p_wiw;
+ } else
+ next_curwin_size = p_wiw;
+ }
+ }
+
+ if (has_next_curwin)
+ --totwincount; /* don't count curwin */
+ }
+
+ for (fr = topfr->fr_child; fr != NULL; fr = fr->fr_next) {
+ n = m = 0;
+ wincount = 1;
+ if (fr->fr_next == NULL)
+ /* last frame gets all that remains (avoid roundoff error) */
+ new_size = width;
+ else if (dir == 'v')
+ new_size = fr->fr_width;
+ else if (frame_fixed_width(fr)) {
+ new_size = fr->fr_newwidth;
+ wincount = 0; /* doesn't count as a sizeable window */
+ } else {
+ /* Compute the maximum number of windows horiz. in "fr". */
+ n = frame_minwidth(fr, NOWIN);
+ wincount = (n + (fr->fr_next == NULL ? extra_sep : 0))
+ / (p_wmw + 1);
+ m = frame_minwidth(fr, next_curwin);
+ if (has_next_curwin)
+ hnc = frame_has_win(fr, next_curwin);
+ else
+ hnc = FALSE;
+ if (hnc) /* don't count next_curwin */
+ --wincount;
+ if (totwincount == 0)
+ new_size = room;
+ else
+ new_size = (wincount * room + ((unsigned)totwincount >> 1))
+ / totwincount;
+ if (hnc) { /* add next_curwin size */
+ next_curwin_size -= p_wiw - (m - n);
+ new_size += next_curwin_size;
+ room -= new_size - next_curwin_size;
+ } else
+ room -= new_size;
+ new_size += n;
+ }
+
+ /* Skip frame that is full width when splitting or closing a
+ * window, unless equalizing all frames. */
+ if (!current || dir != 'v' || topfr->fr_parent != NULL
+ || (new_size != fr->fr_width)
+ || frame_has_win(fr, next_curwin))
+ win_equal_rec(next_curwin, current, fr, dir, col, row,
+ new_size, height);
+ col += new_size;
+ width -= new_size;
+ totwincount -= wincount;
+ }
+ } else { /* topfr->fr_layout == FR_COL */
+ topfr->fr_width = width;
+ topfr->fr_height = height;
+
+ if (dir != 'h') { /* equalize frame heights */
+ /* Compute maximum number of windows vertically in this frame. */
+ n = frame_minheight(topfr, NOWIN);
+ /* add one for the bottom window if it doesn't have a statusline */
+ if (row + height == cmdline_row && p_ls == 0)
+ extra_sep = 1;
+ else
+ extra_sep = 0;
+ totwincount = (n + extra_sep) / (p_wmh + 1);
+ has_next_curwin = frame_has_win(topfr, next_curwin);
+
+ /*
+ * Compute height for "next_curwin" window and room available for
+ * other windows.
+ * "m" is the minimal height when counting p_wh for "next_curwin".
+ */
+ m = frame_minheight(topfr, next_curwin);
+ room = height - m;
+ if (room < 0) {
+ /* The room is less then 'winheight', use all space for the
+ * current window. */
+ next_curwin_size = p_wh + room;
+ room = 0;
+ } else {
+ next_curwin_size = -1;
+ for (fr = topfr->fr_child; fr != NULL; fr = fr->fr_next) {
+ /* If 'winfixheight' set keep the window height if
+ * possible.
+ * Watch out for this window being the next_curwin. */
+ if (frame_fixed_height(fr)) {
+ n = frame_minheight(fr, NOWIN);
+ new_size = fr->fr_height;
+ if (frame_has_win(fr, next_curwin)) {
+ room += p_wh - p_wmh;
+ next_curwin_size = 0;
+ if (new_size < p_wh)
+ new_size = p_wh;
+ } else
+ /* These windows don't use up room. */
+ totwincount -= (n + (fr->fr_next == NULL
+ ? extra_sep : 0)) / (p_wmh + 1);
+ room -= new_size - n;
+ if (room < 0) {
+ new_size += room;
+ room = 0;
+ }
+ fr->fr_newheight = new_size;
+ }
+ }
+ if (next_curwin_size == -1) {
+ if (!has_next_curwin)
+ next_curwin_size = 0;
+ else if (totwincount > 1
+ && (room + (totwincount - 2))
+ / (totwincount - 1) > p_wh) {
+ /* can make all windows higher than 'winheight',
+ * spread the room equally. */
+ next_curwin_size = (room + p_wh
+ + (totwincount - 1) * p_wmh
+ + (totwincount - 1)) / totwincount;
+ room -= next_curwin_size - p_wh;
+ } else
+ next_curwin_size = p_wh;
+ }
+ }
+
+ if (has_next_curwin)
+ --totwincount; /* don't count curwin */
+ }
+
+ for (fr = topfr->fr_child; fr != NULL; fr = fr->fr_next) {
+ n = m = 0;
+ wincount = 1;
+ if (fr->fr_next == NULL)
+ /* last frame gets all that remains (avoid roundoff error) */
+ new_size = height;
+ else if (dir == 'h')
+ new_size = fr->fr_height;
+ else if (frame_fixed_height(fr)) {
+ new_size = fr->fr_newheight;
+ wincount = 0; /* doesn't count as a sizeable window */
+ } else {
+ /* Compute the maximum number of windows vert. in "fr". */
+ n = frame_minheight(fr, NOWIN);
+ wincount = (n + (fr->fr_next == NULL ? extra_sep : 0))
+ / (p_wmh + 1);
+ m = frame_minheight(fr, next_curwin);
+ if (has_next_curwin)
+ hnc = frame_has_win(fr, next_curwin);
+ else
+ hnc = FALSE;
+ if (hnc) /* don't count next_curwin */
+ --wincount;
+ if (totwincount == 0)
+ new_size = room;
+ else
+ new_size = (wincount * room + ((unsigned)totwincount >> 1))
+ / totwincount;
+ if (hnc) { /* add next_curwin size */
+ next_curwin_size -= p_wh - (m - n);
+ new_size += next_curwin_size;
+ room -= new_size - next_curwin_size;
+ } else
+ room -= new_size;
+ new_size += n;
+ }
+ /* Skip frame that is full width when splitting or closing a
+ * window, unless equalizing all frames. */
+ if (!current || dir != 'h' || topfr->fr_parent != NULL
+ || (new_size != fr->fr_height)
+ || frame_has_win(fr, next_curwin))
+ win_equal_rec(next_curwin, current, fr, dir, col, row,
+ width, new_size);
+ row += new_size;
+ height -= new_size;
+ totwincount -= wincount;
+ }
+ }
+}
+
+/*
+ * close all windows for buffer 'buf'
+ */
+void close_windows(buf, keep_curwin)
+buf_T *buf;
+int keep_curwin; /* don't close "curwin" */
+{
+ win_T *wp;
+ tabpage_T *tp, *nexttp;
+ int h = tabline_height();
+
+ ++RedrawingDisabled;
+
+ for (wp = firstwin; wp != NULL && lastwin != firstwin; ) {
+ if (wp->w_buffer == buf && (!keep_curwin || wp != curwin)
+ && !(wp->w_closing || wp->w_buffer->b_closing)
+ ) {
+ win_close(wp, FALSE);
+
+ /* Start all over, autocommands may change the window layout. */
+ wp = firstwin;
+ } else
+ wp = wp->w_next;
+ }
+
+ /* Also check windows in other tab pages. */
+ for (tp = first_tabpage; tp != NULL; tp = nexttp) {
+ nexttp = tp->tp_next;
+ if (tp != curtab)
+ for (wp = tp->tp_firstwin; wp != NULL; wp = wp->w_next)
+ if (wp->w_buffer == buf
+ && !(wp->w_closing || wp->w_buffer->b_closing)
+ ) {
+ win_close_othertab(wp, FALSE, tp);
+
+ /* Start all over, the tab page may be closed and
+ * autocommands may change the window layout. */
+ nexttp = first_tabpage;
+ break;
+ }
+ }
+
+ --RedrawingDisabled;
+
+ redraw_tabline = TRUE;
+ if (h != tabline_height())
+ shell_new_rows();
+}
+
+/*
+ * Return TRUE if the current window is the only window that exists (ignoring
+ * "aucmd_win").
+ * Returns FALSE if there is a window, possibly in another tab page.
+ */
+static int last_window() {
+ return one_window() && first_tabpage->tp_next == NULL;
+}
+
+/*
+ * Return TRUE if there is only one window other than "aucmd_win" in the
+ * current tab page.
+ */
+int one_window() {
+ win_T *wp;
+ int seen_one = FALSE;
+
+ FOR_ALL_WINDOWS(wp)
+ {
+ if (wp != aucmd_win) {
+ if (seen_one)
+ return FALSE;
+ seen_one = TRUE;
+ }
+ }
+ return TRUE;
+}
+
+/*
+ * Close the possibly last window in a tab page.
+ * Returns TRUE when the window was closed already.
+ */
+static int close_last_window_tabpage(win, free_buf, prev_curtab)
+win_T *win;
+int free_buf;
+tabpage_T *prev_curtab;
+{
+ if (firstwin == lastwin) {
+ buf_T *old_curbuf = curbuf;
+
+ /*
+ * Closing the last window in a tab page. First go to another tab
+ * page and then close the window and the tab page. This avoids that
+ * curwin and curtab are invalid while we are freeing memory, they may
+ * be used in GUI events.
+ * Don't trigger autocommands yet, they may use wrong values, so do
+ * that below.
+ */
+ goto_tabpage_tp(alt_tabpage(), FALSE, TRUE);
+ redraw_tabline = TRUE;
+
+ /* Safety check: Autocommands may have closed the window when jumping
+ * to the other tab page. */
+ if (valid_tabpage(prev_curtab) && prev_curtab->tp_firstwin == win) {
+ int h = tabline_height();
+
+ win_close_othertab(win, free_buf, prev_curtab);
+ if (h != tabline_height())
+ shell_new_rows();
+ }
+ /* Since goto_tabpage_tp above did not trigger *Enter autocommands, do
+ * that now. */
+ apply_autocmds(EVENT_WINENTER, NULL, NULL, FALSE, curbuf);
+ apply_autocmds(EVENT_TABENTER, NULL, NULL, FALSE, curbuf);
+ if (old_curbuf != curbuf)
+ apply_autocmds(EVENT_BUFENTER, NULL, NULL, FALSE, curbuf);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*
+ * 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, free_buf)
+win_T *win;
+int free_buf;
+{
+ win_T *wp;
+ int other_buffer = FALSE;
+ int close_curwin = FALSE;
+ int dir;
+ int help_window = FALSE;
+ tabpage_T *prev_curtab = curtab;
+
+ 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 == aucmd_win) {
+ EMSG(_("E813: Cannot close autocmd window"));
+ return FAIL;
+ }
+ if ((firstwin == aucmd_win || lastwin == aucmd_win) && one_window()) {
+ EMSG(_("E814: Cannot close window, only autocmd window would remain"));
+ return FAIL;
+ }
+
+ /* When closing the last window in a tab page first go to another tab page
+ * and then close the window and the tab page to avoid that curwin and
+ * curtab are invalid while we are freeing memory. */
+ if (close_last_window_tabpage(win, free_buf, prev_curtab))
+ return FAIL;
+
+ /* 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
+ clear_snapshot(curtab, SNAP_HELP_IDX);
+
+ if (win == curwin) {
+ /*
+ * Guess which window is going to be the new current window.
+ * This may change because of the autocommands (sigh).
+ */
+ wp = frame2win(win_altframe(win, NULL));
+
+ /*
+ * Be careful: If autocommands delete the window or cause this window
+ * to be the last one left, return now.
+ */
+ if (wp->w_buffer != curbuf) {
+ other_buffer = TRUE;
+ win->w_closing = TRUE;
+ apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, FALSE, curbuf);
+ if (!win_valid(win))
+ return FAIL;
+ win->w_closing = FALSE;
+ if (last_window())
+ return FAIL;
+ }
+ win->w_closing = TRUE;
+ apply_autocmds(EVENT_WINLEAVE, NULL, NULL, FALSE, curbuf);
+ if (!win_valid(win))
+ return FAIL;
+ win->w_closing = FALSE;
+ if (last_window())
+ return FAIL;
+ /* autocmds may abort script processing */
+ if (aborting())
+ return FAIL;
+ }
+
+
+ /* Free independent synblock before the buffer is freed. */
+ if (win->w_buffer != NULL)
+ reset_synblock(win);
+
+ /*
+ * Close the link to the buffer.
+ */
+ if (win->w_buffer != NULL) {
+ win->w_closing = TRUE;
+ close_buffer(win, win->w_buffer, free_buf ? DOBUF_UNLOAD : 0, TRUE);
+ if (win_valid(win))
+ win->w_closing = FALSE;
+ }
+
+ 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 viminfo 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))
+ return FAIL;
+
+ /* Free the memory used for the window and get the window that received
+ * the screen space. */
+ wp = win_free_mem(win, &dir, NULL);
+
+ /* 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. */
+ if (win == curwin) {
+ curwin = wp;
+ if (wp->w_p_pvw || bt_quickfix(wp->w_buffer)) {
+ /*
+ * If the cursor goes to the preview or the quickfix window, try
+ * finding another window to go to.
+ */
+ for (;; ) {
+ if (wp->w_next == NULL)
+ wp = firstwin;
+ else
+ wp = wp->w_next;
+ if (wp == curwin)
+ break;
+ if (!wp->w_p_pvw && !bt_quickfix(wp->w_buffer)) {
+ curwin = wp;
+ break;
+ }
+ }
+ }
+ curbuf = curwin->w_buffer;
+ close_curwin = TRUE;
+ }
+ if (p_ea
+ && (*p_ead == 'b' || *p_ead == dir)
+ )
+ win_equal(curwin, TRUE,
+ 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);
+ }
+
+ /*
+ * If last window has a status line now and we don't want one,
+ * remove the status line.
+ */
+ last_status(FALSE);
+
+ /* After closing the help window, try restoring the window layout from
+ * before it was opened. */
+ if (help_window)
+ restore_snapshot(SNAP_HELP_IDX, close_curwin);
+
+
+ redraw_all_later(NOT_VALID);
+ return OK;
+}
+
+/*
+ * Close window "win" in tab page "tp", which is not the current tab page.
+ * This may be the last window in that tab page and result in closing the tab,
+ * thus "tp" may become invalid!
+ * Caller must check if buffer is hidden and whether the tabline needs to be
+ * updated.
+ */
+void win_close_othertab(win, free_buf, tp)
+win_T *win;
+int free_buf;
+tabpage_T *tp;
+{
+ win_T *wp;
+ int dir;
+ tabpage_T *ptp = NULL;
+ int free_tp = FALSE;
+
+ if (win->w_closing || win->w_buffer->b_closing)
+ return; /* window is already being closed */
+
+ /* 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. */
+ for (ptp = first_tabpage; ptp != NULL && ptp != tp; ptp = ptp->tp_next)
+ ;
+ if (ptp == NULL || tp == curtab)
+ return;
+
+ /* Autocommands may have closed the window already. */
+ for (wp = tp->tp_firstwin; wp != NULL && wp != win; wp = wp->w_next)
+ ;
+ if (wp == NULL)
+ return;
+
+ /* When closing the last window in a tab page remove the tab page. */
+ if (tp == NULL ? firstwin == lastwin : tp->tp_firstwin == tp->tp_lastwin) {
+ if (tp == first_tabpage)
+ first_tabpage = tp->tp_next;
+ else {
+ for (ptp = first_tabpage; ptp != NULL && ptp->tp_next != tp;
+ ptp = ptp->tp_next)
+ ;
+ if (ptp == NULL) {
+ EMSG2(_(e_intern2), "win_close_othertab()");
+ return;
+ }
+ ptp->tp_next = tp->tp_next;
+ }
+ free_tp = TRUE;
+ }
+
+ /* Free the memory used for the window. */
+ win_free_mem(win, &dir, tp);
+
+ if (free_tp)
+ free_tabpage(tp);
+}
+
+/*
+ * Free the memory used for a window.
+ * Returns a pointer to the window that got the freed up space.
+ */
+static win_T * win_free_mem(win, dirp, tp)
+win_T *win;
+int *dirp; /* set to 'v' or 'h' for direction if 'ea' */
+tabpage_T *tp; /* tab page "win" is in, NULL for current */
+{
+ frame_T *frp;
+ win_T *wp;
+
+ /* Remove the window and its frame from the tree of frames. */
+ frp = win->w_frame;
+ wp = winframe_remove(win, dirp, tp);
+ vim_free(frp);
+ win_free(win, tp);
+
+ /* When deleting the current window of another tab page select a new
+ * current window. */
+ if (tp != NULL && win == tp->tp_curwin)
+ tp->tp_curwin = wp;
+
+ return wp;
+}
+
+#if defined(EXITFREE) || defined(PROTO)
+void win_free_all() {
+ int dummy;
+
+ while (first_tabpage->tp_next != NULL)
+ tabpage_close(TRUE);
+
+ if (aucmd_win != NULL) {
+ (void)win_free_mem(aucmd_win, &dummy, NULL);
+ aucmd_win = NULL;
+ }
+
+ while (firstwin != NULL)
+ (void)win_free_mem(firstwin, &dummy, NULL);
+}
+
+#endif
+
+/*
+ * Remove a window and its frame from the tree of frames.
+ * Returns a pointer to the window that got the freed up space.
+ */
+win_T * winframe_remove(win, dirp, tp)
+win_T *win;
+int *dirp UNUSED; /* set to 'v' or 'h' for direction if 'ea' */
+tabpage_T *tp; /* tab page "win" is in, NULL for current */
+{
+ frame_T *frp, *frp2, *frp3;
+ frame_T *frp_close = win->w_frame;
+ win_T *wp;
+
+ /*
+ * If there is only one window there is nothing to remove.
+ */
+ if (tp == NULL ? firstwin == lastwin : tp->tp_firstwin == tp->tp_lastwin)
+ return NULL;
+
+ /*
+ * Remove the window from its frame.
+ */
+ frp2 = win_altframe(win, tp);
+ wp = frame2win(frp2);
+
+ /* Remove this frame from the list of frames. */
+ frame_remove(frp_close);
+
+ if (frp_close->fr_parent->fr_layout == FR_COL) {
+ /* When 'winfixheight' is set, try to find another frame in the column
+ * (as close to the closed frame as possible) to distribute the height
+ * to. */
+ if (frp2->fr_win != NULL && frp2->fr_win->w_p_wfh) {
+ frp = frp_close->fr_prev;
+ frp3 = frp_close->fr_next;
+ while (frp != NULL || frp3 != NULL) {
+ if (frp != NULL) {
+ if (frp->fr_win != NULL && !frp->fr_win->w_p_wfh) {
+ frp2 = frp;
+ wp = frp->fr_win;
+ break;
+ }
+ frp = frp->fr_prev;
+ }
+ if (frp3 != NULL) {
+ if (frp3->fr_win != NULL && !frp3->fr_win->w_p_wfh) {
+ frp2 = frp3;
+ wp = frp3->fr_win;
+ break;
+ }
+ frp3 = frp3->fr_next;
+ }
+ }
+ }
+ frame_new_height(frp2, frp2->fr_height + frp_close->fr_height,
+ frp2 == frp_close->fr_next ? TRUE : FALSE, FALSE);
+ *dirp = 'v';
+ } else {
+ /* When 'winfixwidth' is set, try to find another frame in the column
+ * (as close to the closed frame as possible) to distribute the width
+ * to. */
+ if (frp2->fr_win != NULL && frp2->fr_win->w_p_wfw) {
+ frp = frp_close->fr_prev;
+ frp3 = frp_close->fr_next;
+ while (frp != NULL || frp3 != NULL) {
+ if (frp != NULL) {
+ if (frp->fr_win != NULL && !frp->fr_win->w_p_wfw) {
+ frp2 = frp;
+ wp = frp->fr_win;
+ break;
+ }
+ frp = frp->fr_prev;
+ }
+ if (frp3 != NULL) {
+ if (frp3->fr_win != NULL && !frp3->fr_win->w_p_wfw) {
+ frp2 = frp3;
+ wp = frp3->fr_win;
+ break;
+ }
+ frp3 = frp3->fr_next;
+ }
+ }
+ }
+ frame_new_width(frp2, frp2->fr_width + frp_close->fr_width,
+ frp2 == frp_close->fr_next ? TRUE : FALSE, FALSE);
+ *dirp = 'h';
+ }
+
+ /* If rows/columns go to a window below/right its positions need to be
+ * updated. Can only be done after the sizes have been updated. */
+ if (frp2 == frp_close->fr_next) {
+ int row = win->w_winrow;
+ int col = W_WINCOL(win);
+
+ frame_comp_pos(frp2, &row, &col);
+ }
+
+ if (frp2->fr_next == NULL && frp2->fr_prev == NULL) {
+ /* There is no other frame in this list, move its info to the parent
+ * and remove it. */
+ frp2->fr_parent->fr_layout = frp2->fr_layout;
+ frp2->fr_parent->fr_child = frp2->fr_child;
+ for (frp = frp2->fr_child; frp != NULL; frp = frp->fr_next)
+ frp->fr_parent = frp2->fr_parent;
+ frp2->fr_parent->fr_win = frp2->fr_win;
+ if (frp2->fr_win != NULL)
+ frp2->fr_win->w_frame = frp2->fr_parent;
+ frp = frp2->fr_parent;
+ vim_free(frp2);
+
+ frp2 = frp->fr_parent;
+ if (frp2 != NULL && frp2->fr_layout == frp->fr_layout) {
+ /* The frame above the parent has the same layout, have to merge
+ * the frames into this list. */
+ if (frp2->fr_child == frp)
+ frp2->fr_child = frp->fr_child;
+ frp->fr_child->fr_prev = frp->fr_prev;
+ if (frp->fr_prev != NULL)
+ frp->fr_prev->fr_next = frp->fr_child;
+ for (frp3 = frp->fr_child;; frp3 = frp3->fr_next) {
+ frp3->fr_parent = frp2;
+ if (frp3->fr_next == NULL) {
+ frp3->fr_next = frp->fr_next;
+ if (frp->fr_next != NULL)
+ frp->fr_next->fr_prev = frp3;
+ break;
+ }
+ }
+ vim_free(frp);
+ }
+ }
+
+ 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.
+ */
+static frame_T * win_altframe(win, tp)
+win_T *win;
+tabpage_T *tp; /* tab page "win" is in, NULL for current */
+{
+ 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. */
+ 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)
+ return frp->fr_next;
+ return frp->fr_prev;
+}
+
+/*
+ * Return the tabpage that will be used if the current one is closed.
+ */
+static tabpage_T * alt_tabpage() {
+ tabpage_T *tp;
+
+ /* Use the next tab page if possible. */
+ if (curtab->tp_next != NULL)
+ return curtab->tp_next;
+
+ /* Find the last but one tab page. */
+ for (tp = first_tabpage; tp->tp_next != curtab; tp = tp->tp_next)
+ ;
+ return tp;
+}
+
+/*
+ * Find the left-upper window in frame "frp".
+ */
+static win_T * frame2win(frp)
+frame_T *frp;
+{
+ while (frp->fr_win == NULL)
+ frp = frp->fr_child;
+ return frp->fr_win;
+}
+
+/*
+ * Return TRUE if frame "frp" contains window "wp".
+ */
+static int frame_has_win(frp, wp)
+frame_T *frp;
+win_T *wp;
+{
+ frame_T *p;
+
+ if (frp->fr_layout == FR_LEAF)
+ return frp->fr_win == wp;
+
+ for (p = frp->fr_child; p != NULL; p = p->fr_next)
+ if (frame_has_win(p, wp))
+ return TRUE;
+ return FALSE;
+}
+
+/*
+ * Set a new height for a frame. Recursively sets the height for contained
+ * frames and windows. Caller must take care of positions.
+ */
+static void frame_new_height(topfrp, height, topfirst, wfh)
+frame_T *topfrp;
+int height;
+int topfirst; /* resize topmost contained frame first */
+int wfh; /* obey 'winfixheight' when there is a choice;
+ may cause the height not to be set */
+{
+ frame_T *frp;
+ int extra_lines;
+ int h;
+
+ if (topfrp->fr_win != NULL) {
+ /* Simple case: just one window. */
+ win_new_height(topfrp->fr_win,
+ height - topfrp->fr_win->w_status_height);
+ } else if (topfrp->fr_layout == FR_ROW) {
+ do {
+ /* All frames in this row get the same new height. */
+ for (frp = topfrp->fr_child; frp != NULL; frp = frp->fr_next) {
+ frame_new_height(frp, height, topfirst, wfh);
+ if (frp->fr_height > height) {
+ /* Could not fit the windows, make the whole row higher. */
+ height = frp->fr_height;
+ break;
+ }
+ }
+ } while (frp != NULL);
+ } else { /* fr_layout == FR_COL */
+ /* Complicated case: Resize a column of frames. Resize the bottom
+ * frame first, frames above that when needed. */
+
+ frp = topfrp->fr_child;
+ if (wfh)
+ /* Advance past frames with one window with 'wfh' set. */
+ while (frame_fixed_height(frp)) {
+ frp = frp->fr_next;
+ if (frp == NULL)
+ return; /* no frame without 'wfh', give up */
+ }
+ if (!topfirst) {
+ /* Find the bottom frame of this column */
+ while (frp->fr_next != NULL)
+ frp = frp->fr_next;
+ if (wfh)
+ /* Advance back for frames with one window with 'wfh' set. */
+ while (frame_fixed_height(frp))
+ frp = frp->fr_prev;
+ }
+
+ extra_lines = height - topfrp->fr_height;
+ if (extra_lines < 0) {
+ /* reduce height of contained frames, bottom or top frame first */
+ while (frp != NULL) {
+ h = frame_minheight(frp, NULL);
+ if (frp->fr_height + extra_lines < h) {
+ extra_lines += frp->fr_height - h;
+ frame_new_height(frp, h, topfirst, wfh);
+ } else {
+ frame_new_height(frp, frp->fr_height + extra_lines,
+ topfirst, wfh);
+ break;
+ }
+ if (topfirst) {
+ do
+ frp = frp->fr_next;
+ while (wfh && frp != NULL && frame_fixed_height(frp));
+ } else {
+ do
+ frp = frp->fr_prev;
+ while (wfh && frp != NULL && frame_fixed_height(frp));
+ }
+ /* Increase "height" if we could not reduce enough frames. */
+ if (frp == NULL)
+ height -= extra_lines;
+ }
+ } else if (extra_lines > 0) {
+ /* increase height of bottom or top frame */
+ frame_new_height(frp, frp->fr_height + extra_lines, topfirst, wfh);
+ }
+ }
+ topfrp->fr_height = height;
+}
+
+/*
+ * Return TRUE if height of frame "frp" should not be changed because of
+ * the 'winfixheight' option.
+ */
+static int frame_fixed_height(frp)
+frame_T *frp;
+{
+ /* frame with one window: fixed height if 'winfixheight' set. */
+ if (frp->fr_win != NULL)
+ return frp->fr_win->w_p_wfh;
+
+ if (frp->fr_layout == FR_ROW) {
+ /* The frame is fixed height if one of the frames in the row is fixed
+ * height. */
+ for (frp = frp->fr_child; frp != NULL; frp = frp->fr_next)
+ if (frame_fixed_height(frp))
+ return TRUE;
+ return FALSE;
+ }
+
+ /* frp->fr_layout == FR_COL: The frame is fixed height if all of the
+ * frames in the row are fixed height. */
+ for (frp = frp->fr_child; frp != NULL; frp = frp->fr_next)
+ if (!frame_fixed_height(frp))
+ return FALSE;
+ return TRUE;
+}
+
+/*
+ * Return TRUE if width of frame "frp" should not be changed because of
+ * the 'winfixwidth' option.
+ */
+static int frame_fixed_width(frp)
+frame_T *frp;
+{
+ /* frame with one window: fixed width if 'winfixwidth' set. */
+ if (frp->fr_win != NULL)
+ return frp->fr_win->w_p_wfw;
+
+ if (frp->fr_layout == FR_COL) {
+ /* The frame is fixed width if one of the frames in the row is fixed
+ * width. */
+ for (frp = frp->fr_child; frp != NULL; frp = frp->fr_next)
+ if (frame_fixed_width(frp))
+ return TRUE;
+ return FALSE;
+ }
+
+ /* frp->fr_layout == FR_ROW: The frame is fixed width if all of the
+ * frames in the row are fixed width. */
+ for (frp = frp->fr_child; frp != NULL; frp = frp->fr_next)
+ if (!frame_fixed_width(frp))
+ return FALSE;
+ return TRUE;
+}
+
+/*
+ * Add a status line to windows at the bottom of "frp".
+ * Note: Does not check if there is room!
+ */
+static void frame_add_statusline(frp)
+frame_T *frp;
+{
+ win_T *wp;
+
+ if (frp->fr_layout == FR_LEAF) {
+ wp = frp->fr_win;
+ if (wp->w_status_height == 0) {
+ if (wp->w_height > 0) /* don't make it negative */
+ --wp->w_height;
+ wp->w_status_height = STATUS_HEIGHT;
+ }
+ } else if (frp->fr_layout == FR_ROW) {
+ /* Handle all the frames in the row. */
+ for (frp = frp->fr_child; frp != NULL; frp = frp->fr_next)
+ frame_add_statusline(frp);
+ } else { /* frp->fr_layout == FR_COL */
+ /* Only need to handle the last frame in the column. */
+ for (frp = frp->fr_child; frp->fr_next != NULL; frp = frp->fr_next)
+ ;
+ frame_add_statusline(frp);
+ }
+}
+
+/*
+ * Set width of a frame. Handles recursively going through contained frames.
+ * May remove separator line for windows at the right side (for win_close()).
+ */
+static void frame_new_width(topfrp, width, leftfirst, wfw)
+frame_T *topfrp;
+int width;
+int leftfirst; /* resize leftmost contained frame first */
+int wfw; /* obey 'winfixwidth' when there is a choice;
+ may cause the width not to be set */
+{
+ frame_T *frp;
+ int extra_cols;
+ int w;
+ win_T *wp;
+
+ if (topfrp->fr_layout == FR_LEAF) {
+ /* Simple case: just one window. */
+ wp = topfrp->fr_win;
+ /* Find out if there are any windows right of this one. */
+ for (frp = topfrp; frp->fr_parent != NULL; frp = frp->fr_parent)
+ if (frp->fr_parent->fr_layout == FR_ROW && frp->fr_next != NULL)
+ break;
+ if (frp->fr_parent == NULL)
+ wp->w_vsep_width = 0;
+ win_new_width(wp, width - wp->w_vsep_width);
+ } else if (topfrp->fr_layout == FR_COL) {
+ do {
+ /* All frames in this column get the same new width. */
+ for (frp = topfrp->fr_child; frp != NULL; frp = frp->fr_next) {
+ frame_new_width(frp, width, leftfirst, wfw);
+ if (frp->fr_width > width) {
+ /* Could not fit the windows, make whole column wider. */
+ width = frp->fr_width;
+ break;
+ }
+ }
+ } while (frp != NULL);
+ } else { /* fr_layout == FR_ROW */
+ /* Complicated case: Resize a row of frames. Resize the rightmost
+ * frame first, frames left of it when needed. */
+
+ frp = topfrp->fr_child;
+ if (wfw)
+ /* Advance past frames with one window with 'wfw' set. */
+ while (frame_fixed_width(frp)) {
+ frp = frp->fr_next;
+ if (frp == NULL)
+ return; /* no frame without 'wfw', give up */
+ }
+ if (!leftfirst) {
+ /* Find the rightmost frame of this row */
+ while (frp->fr_next != NULL)
+ frp = frp->fr_next;
+ if (wfw)
+ /* Advance back for frames with one window with 'wfw' set. */
+ while (frame_fixed_width(frp))
+ frp = frp->fr_prev;
+ }
+
+ extra_cols = width - topfrp->fr_width;
+ if (extra_cols < 0) {
+ /* reduce frame width, rightmost frame first */
+ while (frp != NULL) {
+ w = frame_minwidth(frp, NULL);
+ if (frp->fr_width + extra_cols < w) {
+ extra_cols += frp->fr_width - w;
+ frame_new_width(frp, w, leftfirst, wfw);
+ } else {
+ frame_new_width(frp, frp->fr_width + extra_cols,
+ leftfirst, wfw);
+ break;
+ }
+ if (leftfirst) {
+ do
+ frp = frp->fr_next;
+ while (wfw && frp != NULL && frame_fixed_width(frp));
+ } else {
+ do
+ frp = frp->fr_prev;
+ while (wfw && frp != NULL && frame_fixed_width(frp));
+ }
+ /* Increase "width" if we could not reduce enough frames. */
+ if (frp == NULL)
+ width -= extra_cols;
+ }
+ } else if (extra_cols > 0) {
+ /* increase width of rightmost frame */
+ frame_new_width(frp, frp->fr_width + extra_cols, leftfirst, wfw);
+ }
+ }
+ topfrp->fr_width = width;
+}
+
+/*
+ * Add the vertical separator to windows at the right side of "frp".
+ * Note: Does not check if there is room!
+ */
+static void frame_add_vsep(frp)
+frame_T *frp;
+{
+ win_T *wp;
+
+ if (frp->fr_layout == FR_LEAF) {
+ wp = frp->fr_win;
+ if (wp->w_vsep_width == 0) {
+ if (wp->w_width > 0) /* don't make it negative */
+ --wp->w_width;
+ wp->w_vsep_width = 1;
+ }
+ } else if (frp->fr_layout == FR_COL) {
+ /* Handle all the frames in the column. */
+ for (frp = frp->fr_child; frp != NULL; frp = frp->fr_next)
+ frame_add_vsep(frp);
+ } else { /* frp->fr_layout == FR_ROW */
+ /* Only need to handle the last frame in the row. */
+ frp = frp->fr_child;
+ while (frp->fr_next != NULL)
+ frp = frp->fr_next;
+ frame_add_vsep(frp);
+ }
+}
+
+/*
+ * Set frame width from the window it contains.
+ */
+static void frame_fix_width(wp)
+win_T *wp;
+{
+ wp->w_frame->fr_width = wp->w_width + wp->w_vsep_width;
+}
+
+/*
+ * Set frame height from the window it contains.
+ */
+static void frame_fix_height(wp)
+win_T *wp;
+{
+ wp->w_frame->fr_height = wp->w_height + wp->w_status_height;
+}
+
+/*
+ * Compute the minimal height for frame "topfrp".
+ * Uses the 'winminheight' option.
+ * When "next_curwin" isn't NULL, use p_wh for this window.
+ * When "next_curwin" is NOWIN, don't use at least one line for the current
+ * window.
+ */
+static int frame_minheight(topfrp, next_curwin)
+frame_T *topfrp;
+win_T *next_curwin;
+{
+ frame_T *frp;
+ int m;
+ int n;
+
+ if (topfrp->fr_win != NULL) {
+ if (topfrp->fr_win == next_curwin)
+ m = p_wh + topfrp->fr_win->w_status_height;
+ else {
+ /* window: minimal height of the window plus status line */
+ m = p_wmh + topfrp->fr_win->w_status_height;
+ /* Current window is minimal one line high */
+ if (p_wmh == 0 && topfrp->fr_win == curwin && next_curwin == NULL)
+ ++m;
+ }
+ } else if (topfrp->fr_layout == FR_ROW) {
+ /* get the minimal height from each frame in this row */
+ m = 0;
+ for (frp = topfrp->fr_child; frp != NULL; frp = frp->fr_next) {
+ n = frame_minheight(frp, next_curwin);
+ if (n > m)
+ m = n;
+ }
+ } else {
+ /* Add up the minimal heights for all frames in this column. */
+ m = 0;
+ for (frp = topfrp->fr_child; frp != NULL; frp = frp->fr_next)
+ m += frame_minheight(frp, next_curwin);
+ }
+
+ return m;
+}
+
+/*
+ * Compute the minimal width for frame "topfrp".
+ * When "next_curwin" isn't NULL, use p_wiw for this window.
+ * When "next_curwin" is NOWIN, don't use at least one column for the current
+ * window.
+ */
+static int frame_minwidth(topfrp, next_curwin)
+frame_T *topfrp;
+win_T *next_curwin; /* use p_wh and p_wiw for next_curwin */
+{
+ frame_T *frp;
+ int m, n;
+
+ if (topfrp->fr_win != NULL) {
+ if (topfrp->fr_win == next_curwin)
+ m = p_wiw + topfrp->fr_win->w_vsep_width;
+ else {
+ /* window: minimal width of the window plus separator column */
+ m = p_wmw + topfrp->fr_win->w_vsep_width;
+ /* Current window is minimal one column wide */
+ if (p_wmw == 0 && topfrp->fr_win == curwin && next_curwin == NULL)
+ ++m;
+ }
+ } else if (topfrp->fr_layout == FR_COL) {
+ /* get the minimal width from each frame in this column */
+ m = 0;
+ for (frp = topfrp->fr_child; frp != NULL; frp = frp->fr_next) {
+ n = frame_minwidth(frp, next_curwin);
+ if (n > m)
+ m = n;
+ }
+ } else {
+ /* Add up the minimal widths for all frames in this row. */
+ m = 0;
+ for (frp = topfrp->fr_child; frp != NULL; frp = frp->fr_next)
+ m += frame_minwidth(frp, next_curwin);
+ }
+
+ return m;
+}
+
+
+/*
+ * Try to close all windows except current one.
+ * Buffers in the other windows become hidden if 'hidden' is set, or '!' is
+ * used and the buffer was modified.
+ *
+ * Used by ":bdel" and ":only".
+ */
+void close_others(message, forceit)
+int message;
+int forceit; /* always hide all other windows */
+{
+ win_T *wp;
+ win_T *nextwp;
+ int r;
+
+ if (one_window()) {
+ if (message
+ && !autocmd_busy
+ )
+ MSG(_(m_onlyone));
+ return;
+ }
+
+ /* Be very careful here: autocommands may change the window layout. */
+ for (wp = firstwin; win_valid(wp); wp = nextwp) {
+ nextwp = wp->w_next;
+ if (wp != curwin) { /* don't close current window */
+
+ /* Check if it's allowed to abandon this window */
+ r = can_abandon(wp->w_buffer, forceit);
+ if (!win_valid(wp)) { /* autocommands messed wp up */
+ nextwp = firstwin;
+ continue;
+ }
+ if (!r) {
+ if (message && (p_confirm || cmdmod.confirm) && p_write) {
+ dialog_changed(wp->w_buffer, FALSE);
+ if (!win_valid(wp)) { /* autocommands messed wp up */
+ nextwp = firstwin;
+ continue;
+ }
+ }
+ if (bufIsChanged(wp->w_buffer))
+ continue;
+ }
+ win_close(wp, !P_HID(wp->w_buffer) && !bufIsChanged(wp->w_buffer));
+ }
+ }
+
+ if (message && lastwin != firstwin)
+ EMSG(_("E445: Other window contains changes"));
+}
+
+
+/*
+ * Init the current window "curwin".
+ * Called when a new file is being edited.
+ */
+void curwin_init() {
+ win_init_empty(curwin);
+}
+
+void win_init_empty(wp)
+win_T *wp;
+{
+ redraw_win_later(wp, NOT_VALID);
+ wp->w_lines_valid = 0;
+ wp->w_cursor.lnum = 1;
+ wp->w_curswant = wp->w_cursor.col = 0;
+ wp->w_cursor.coladd = 0;
+ wp->w_pcmark.lnum = 1; /* pcmark not cleared but set to line 1 */
+ wp->w_pcmark.col = 0;
+ wp->w_prev_pcmark.lnum = 0;
+ wp->w_prev_pcmark.col = 0;
+ wp->w_topline = 1;
+ wp->w_topfill = 0;
+ wp->w_botline = 2;
+ if (wp->w_p_rl)
+ wp->w_farsi = W_CONV + W_R_L;
+ else
+ wp->w_farsi = W_CONV;
+ wp->w_s = &wp->w_buffer->b_s;
+}
+
+/*
+ * Allocate the first window and put an empty buffer in it.
+ * Called from main().
+ * Return FAIL when something goes wrong (out of memory).
+ */
+int win_alloc_first() {
+ if (win_alloc_firstwin(NULL) == FAIL)
+ return FAIL;
+
+ first_tabpage = alloc_tabpage();
+ if (first_tabpage == NULL)
+ return FAIL;
+ first_tabpage->tp_topframe = topframe;
+ curtab = first_tabpage;
+
+ return OK;
+}
+
+/*
+ * Init "aucmd_win". This can only be done after the first
+ * window is fully initialized, thus it can't be in win_alloc_first().
+ */
+void win_alloc_aucmd_win() {
+ aucmd_win = win_alloc(NULL, TRUE);
+ if (aucmd_win != NULL) {
+ win_init_some(aucmd_win, curwin);
+ RESET_BINDING(aucmd_win);
+ new_frame(aucmd_win);
+ }
+}
+
+/*
+ * Allocate the first window or the first window in a new tab page.
+ * When "oldwin" is NULL create an empty buffer for it.
+ * When "oldwin" is not NULL copy info from it to the new window (only with
+ * FEAT_WINDOWS).
+ * Return FAIL when something goes wrong (out of memory).
+ */
+static int win_alloc_firstwin(oldwin)
+win_T *oldwin;
+{
+ curwin = win_alloc(NULL, FALSE);
+ if (oldwin == NULL) {
+ /* Very first window, need to create an empty buffer for it and
+ * initialize from scratch. */
+ curbuf = buflist_new(NULL, NULL, 1L, BLN_LISTED);
+ if (curwin == NULL || curbuf == NULL)
+ return FAIL;
+ curwin->w_buffer = curbuf;
+ curwin->w_s = &(curbuf->b_s);
+ curbuf->b_nwindows = 1; /* there is one window */
+ curwin->w_alist = &global_alist;
+ curwin_init(); /* init current window */
+ } else {
+ /* First window in new tab page, initialize it from "oldwin". */
+ win_init(curwin, oldwin, 0);
+
+ /* We don't want cursor- and scroll-binding in the first window. */
+ RESET_BINDING(curwin);
+ }
+
+ new_frame(curwin);
+ if (curwin->w_frame == NULL)
+ return FAIL;
+ topframe = curwin->w_frame;
+ topframe->fr_width = Columns;
+ topframe->fr_height = Rows - p_ch;
+ topframe->fr_win = curwin;
+
+ return OK;
+}
+
+/*
+ * Create a frame for window "wp".
+ */
+static void new_frame(win_T *wp) {
+ frame_T *frp = (frame_T *)alloc_clear((unsigned)sizeof(frame_T));
+
+ wp->w_frame = frp;
+ if (frp != NULL) {
+ frp->fr_layout = FR_LEAF;
+ frp->fr_win = wp;
+ }
+}
+
+/*
+ * Initialize the window and frame size to the maximum.
+ */
+void win_init_size() {
+ firstwin->w_height = ROWS_AVAIL;
+ topframe->fr_height = ROWS_AVAIL;
+ firstwin->w_width = Columns;
+ topframe->fr_width = Columns;
+}
+
+/*
+ * Allocate a new tabpage_T and init the values.
+ * Returns NULL when out of memory.
+ */
+static tabpage_T * alloc_tabpage() {
+ tabpage_T *tp;
+
+
+ tp = (tabpage_T *)alloc_clear((unsigned)sizeof(tabpage_T));
+ if (tp == NULL)
+ return NULL;
+
+ /* init t: variables */
+ tp->tp_vars = dict_alloc();
+ if (tp->tp_vars == NULL) {
+ vim_free(tp);
+ return NULL;
+ }
+ init_var_dict(tp->tp_vars, &tp->tp_winvar, VAR_SCOPE);
+
+ tp->tp_diff_invalid = TRUE;
+ tp->tp_ch_used = p_ch;
+
+ return tp;
+}
+
+void free_tabpage(tp)
+tabpage_T *tp;
+{
+ int idx;
+
+ diff_clear(tp);
+ for (idx = 0; idx < SNAP_COUNT; ++idx)
+ clear_snapshot(tp, idx);
+ vars_clear(&tp->tp_vars->dv_hashtab); /* free all t: variables */
+ hash_init(&tp->tp_vars->dv_hashtab);
+ unref_var_dict(tp->tp_vars);
+
+
+
+ vim_free(tp);
+}
+
+/*
+ * Create a new Tab page with one window.
+ * It will edit the current buffer, like after ":split".
+ * When "after" is 0 put it just after the current Tab page.
+ * Otherwise put it just before tab page "after".
+ * Return FAIL or OK.
+ */
+int win_new_tabpage(after)
+int after;
+{
+ tabpage_T *tp = curtab;
+ tabpage_T *newtp;
+ int n;
+
+ newtp = alloc_tabpage();
+ if (newtp == NULL)
+ return FAIL;
+
+ /* Remember the current windows in this Tab page. */
+ if (leave_tabpage(curbuf, TRUE) == FAIL) {
+ vim_free(newtp);
+ return FAIL;
+ }
+ curtab = newtp;
+
+ /* Create a new empty window. */
+ if (win_alloc_firstwin(tp->tp_curwin) == OK) {
+ /* Make the new Tab page the new topframe. */
+ if (after == 1) {
+ /* New tab page becomes the first one. */
+ newtp->tp_next = first_tabpage;
+ first_tabpage = newtp;
+ } else {
+ if (after > 0) {
+ /* Put new tab page before tab page "after". */
+ n = 2;
+ for (tp = first_tabpage; tp->tp_next != NULL
+ && n < after; tp = tp->tp_next)
+ ++n;
+ }
+ newtp->tp_next = tp->tp_next;
+ tp->tp_next = newtp;
+ }
+ win_init_size();
+ firstwin->w_winrow = tabline_height();
+ win_comp_scroll(curwin);
+
+ newtp->tp_topframe = topframe;
+ last_status(FALSE);
+
+
+ redraw_all_later(CLEAR);
+ apply_autocmds(EVENT_WINENTER, NULL, NULL, FALSE, curbuf);
+ apply_autocmds(EVENT_TABENTER, NULL, NULL, FALSE, curbuf);
+ return OK;
+ }
+
+ /* Failed, get back the previous Tab page */
+ enter_tabpage(curtab, curbuf, TRUE, TRUE);
+ return FAIL;
+}
+
+/*
+ * Open a new tab page if ":tab cmd" was used. It will edit the same buffer,
+ * like with ":split".
+ * Returns OK if a new tab page was created, FAIL otherwise.
+ */
+int may_open_tabpage() {
+ int n = (cmdmod.tab == 0) ? postponed_split_tab : cmdmod.tab;
+
+ if (n != 0) {
+ cmdmod.tab = 0; /* reset it to avoid doing it twice */
+ postponed_split_tab = 0;
+ return win_new_tabpage(n);
+ }
+ return FAIL;
+}
+
+/*
+ * Create up to "maxcount" tabpages with empty windows.
+ * Returns the number of resulting tab pages.
+ */
+int make_tabpages(maxcount)
+int maxcount;
+{
+ int count = maxcount;
+ int todo;
+
+ /* Limit to 'tabpagemax' tabs. */
+ if (count > p_tpm)
+ count = p_tpm;
+
+ /*
+ * Don't execute autocommands while creating the tab pages. Must do that
+ * when putting the buffers in the windows.
+ */
+ block_autocmds();
+
+ for (todo = count - 1; todo > 0; --todo)
+ if (win_new_tabpage(0) == FAIL)
+ break;
+
+ unblock_autocmds();
+
+ /* return actual number of tab pages */
+ return count - todo;
+}
+
+/*
+ * Return TRUE when "tpc" points to a valid tab page.
+ */
+int valid_tabpage(tpc)
+tabpage_T *tpc;
+{
+ tabpage_T *tp;
+
+ for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
+ if (tp == tpc)
+ return TRUE;
+ return FALSE;
+}
+
+/*
+ * Find tab page "n" (first one is 1). Returns NULL when not found.
+ */
+tabpage_T * find_tabpage(n)
+int n;
+{
+ tabpage_T *tp;
+ int i = 1;
+
+ for (tp = first_tabpage; tp != NULL && i != n; tp = tp->tp_next)
+ ++i;
+ return tp;
+}
+
+/*
+ * Get index of tab page "tp". First one has index 1.
+ * When not found returns number of tab pages plus one.
+ */
+int tabpage_index(ftp)
+tabpage_T *ftp;
+{
+ int i = 1;
+ tabpage_T *tp;
+
+ for (tp = first_tabpage; tp != NULL && tp != ftp; tp = tp->tp_next)
+ ++i;
+ return i;
+}
+
+/*
+ * Prepare for leaving the current tab page.
+ * When autocommands change "curtab" we don't leave the tab page and return
+ * FAIL.
+ * Careful: When OK is returned need to get a new tab page very very soon!
+ */
+static int leave_tabpage(new_curbuf, trigger_leave_autocmds)
+buf_T *new_curbuf UNUSED; /* what is going to be the new curbuf,
+ NULL if unknown */
+int trigger_leave_autocmds UNUSED;
+{
+ tabpage_T *tp = curtab;
+
+ reset_VIsual_and_resel(); /* stop Visual mode */
+ if (trigger_leave_autocmds) {
+ if (new_curbuf != curbuf) {
+ apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, FALSE, curbuf);
+ if (curtab != tp)
+ return FAIL;
+ }
+ apply_autocmds(EVENT_WINLEAVE, NULL, NULL, FALSE, curbuf);
+ if (curtab != tp)
+ return FAIL;
+ apply_autocmds(EVENT_TABLEAVE, NULL, NULL, FALSE, curbuf);
+ if (curtab != tp)
+ return FAIL;
+ }
+ tp->tp_curwin = curwin;
+ tp->tp_prevwin = prevwin;
+ tp->tp_firstwin = firstwin;
+ tp->tp_lastwin = lastwin;
+ tp->tp_old_Rows = Rows;
+ tp->tp_old_Columns = Columns;
+ firstwin = NULL;
+ lastwin = NULL;
+ return OK;
+}
+
+/*
+ * Start using tab page "tp".
+ * Only to be used after leave_tabpage() or freeing the current tab page.
+ * Only trigger *Enter autocommands when trigger_enter_autocmds is TRUE.
+ * Only trigger *Leave autocommands when trigger_leave_autocmds is TRUE.
+ */
+static void enter_tabpage(tp, old_curbuf, trigger_enter_autocmds,
+ trigger_leave_autocmds)
+tabpage_T *tp;
+buf_T *old_curbuf UNUSED;
+int trigger_enter_autocmds UNUSED;
+int trigger_leave_autocmds UNUSED;
+{
+ int old_off = tp->tp_firstwin->w_winrow;
+ win_T *next_prevwin = tp->tp_prevwin;
+
+ curtab = tp;
+ firstwin = tp->tp_firstwin;
+ lastwin = tp->tp_lastwin;
+ topframe = tp->tp_topframe;
+
+ /* 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);
+ 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;
+
+ /* 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
+ * frame sizes too. Use the stored value of p_ch, so that it can be
+ * different for each tab page. */
+ p_ch = curtab->tp_ch_used;
+ if (curtab->tp_old_Rows != Rows || (old_off != firstwin->w_winrow
+ ))
+ shell_new_rows();
+ if (curtab->tp_old_Columns != Columns && starting == 0)
+ shell_new_columns(); /* update window widths */
+
+
+ /* Apply autocommands after updating the display, when 'rows' and
+ * 'columns' have been set correctly. */
+ if (trigger_enter_autocmds) {
+ apply_autocmds(EVENT_TABENTER, NULL, NULL, FALSE, curbuf);
+ if (old_curbuf != curbuf)
+ apply_autocmds(EVENT_BUFENTER, NULL, NULL, FALSE, curbuf);
+ }
+
+ redraw_all_later(CLEAR);
+}
+
+/*
+ * Go to tab page "n". For ":tab N" and "Ngt".
+ * When "n" is 9999 go to the last tab page.
+ */
+void goto_tabpage(n)
+int n;
+{
+ tabpage_T *tp;
+ tabpage_T *ttp;
+ int i;
+
+ if (text_locked()) {
+ /* Not allowed when editing the command line. */
+ if (cmdwin_type != 0)
+ EMSG(_(e_cmdwin));
+ else
+ EMSG(_(e_secure));
+ return;
+ }
+
+ /* If there is only one it can't work. */
+ if (first_tabpage->tp_next == NULL) {
+ if (n > 1)
+ beep_flush();
+ return;
+ }
+
+ if (n == 0) {
+ /* No count, go to next tab page, wrap around end. */
+ if (curtab->tp_next == NULL)
+ tp = first_tabpage;
+ else
+ tp = curtab->tp_next;
+ } else if (n < 0) {
+ /* "gT": go to previous tab page, wrap around end. "N gT" repeats
+ * this N times. */
+ ttp = curtab;
+ for (i = n; i < 0; ++i) {
+ for (tp = first_tabpage; tp->tp_next != ttp && tp->tp_next != NULL;
+ tp = tp->tp_next)
+ ;
+ ttp = tp;
+ }
+ } else if (n == 9999) {
+ /* Go to last tab page. */
+ for (tp = first_tabpage; tp->tp_next != NULL; tp = tp->tp_next)
+ ;
+ } else {
+ /* Go to tab page "n". */
+ tp = find_tabpage(n);
+ if (tp == NULL) {
+ beep_flush();
+ return;
+ }
+ }
+
+ goto_tabpage_tp(tp, TRUE, TRUE);
+
+}
+
+/*
+ * Go to tabpage "tp".
+ * Only trigger *Enter autocommands when trigger_enter_autocmds is TRUE.
+ * Only trigger *Leave autocommands when trigger_leave_autocmds is TRUE.
+ * Note: doesn't update the GUI tab.
+ */
+void goto_tabpage_tp(tp, trigger_enter_autocmds, trigger_leave_autocmds)
+tabpage_T *tp;
+int trigger_enter_autocmds;
+int trigger_leave_autocmds;
+{
+ /* Don't repeat a message in another tab page. */
+ set_keep_msg(NULL, 0);
+
+ if (tp != curtab && leave_tabpage(tp->tp_curwin->w_buffer,
+ trigger_leave_autocmds) == OK) {
+ if (valid_tabpage(tp))
+ enter_tabpage(tp, curbuf, trigger_enter_autocmds,
+ trigger_leave_autocmds);
+ else
+ enter_tabpage(curtab, curbuf, trigger_enter_autocmds,
+ trigger_leave_autocmds);
+ }
+}
+
+/*
+ * Enter window "wp" in tab page "tp".
+ * Also updates the GUI tab.
+ */
+void goto_tabpage_win(tp, wp)
+tabpage_T *tp;
+win_T *wp;
+{
+ goto_tabpage_tp(tp, TRUE, TRUE);
+ if (curtab == tp && win_valid(wp)) {
+ win_enter(wp, TRUE);
+ }
+}
+
+/*
+ * Move the current tab page to before tab page "nr".
+ */
+void tabpage_move(nr)
+int nr;
+{
+ int n = nr;
+ tabpage_T *tp;
+
+ if (first_tabpage->tp_next == NULL)
+ return;
+
+ /* 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)
+ break;
+ if (tp == NULL) /* "cannot happen" */
+ return;
+ tp->tp_next = curtab->tp_next;
+ }
+
+ /* Re-insert it at the specified position. */
+ if (n <= 0) {
+ curtab->tp_next = first_tabpage;
+ first_tabpage = curtab;
+ } else {
+ for (tp = first_tabpage; tp->tp_next != NULL && n > 1; tp = tp->tp_next)
+ --n;
+ curtab->tp_next = tp->tp_next;
+ tp->tp_next = curtab;
+ }
+
+ /* Need to redraw the tabline. Tab page contents doesn't change. */
+ redraw_tabline = TRUE;
+}
+
+
+/*
+ * Go to another window.
+ * When jumping to another buffer, stop Visual mode. Do this before
+ * changing windows so we can yank the selection into the '*' register.
+ * When jumping to another window on the same buffer, adjust its cursor
+ * position to keep the same Visual area.
+ */
+void win_goto(wp)
+win_T *wp;
+{
+ win_T *owp = curwin;
+
+ if (text_locked()) {
+ beep_flush();
+ text_locked_msg();
+ return;
+ }
+ if (curbuf_locked())
+ return;
+
+ if (wp->w_buffer != curbuf)
+ reset_VIsual_and_resel();
+ else if (VIsual_active)
+ wp->w_cursor = curwin->w_cursor;
+
+ 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;
+}
+
+
+#if (defined(FEAT_WINDOWS) && (defined(FEAT_PYTHON) || defined(FEAT_PYTHON3))) \
+ || defined(PROTO)
+/*
+ * Find the tabpage for window "win".
+ */
+tabpage_T * win_find_tabpage(win)
+win_T *win;
+{
+ win_T *wp;
+ tabpage_T *tp;
+
+ for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
+ for (wp = (tp == curtab ? firstwin : tp->tp_firstwin);
+ wp != NULL; wp = wp->w_next)
+ if (wp == win)
+ return tp;
+ return NULL;
+}
+#endif
+
+/*
+ * Move to window above or below "count" times.
+ */
+static void win_goto_ver(up, count)
+int up; /* TRUE to go to win above */
+long count;
+{
+ frame_T *fr;
+ frame_T *nfr;
+ frame_T *foundfr;
+
+ foundfr = curwin->w_frame;
+ while (count--) {
+ /*
+ * First go upwards in the tree of frames until we find a upwards or
+ * downwards neighbor.
+ */
+ fr = foundfr;
+ for (;; ) {
+ if (fr == topframe)
+ goto end;
+ if (up)
+ nfr = fr->fr_prev;
+ else
+ nfr = fr->fr_next;
+ if (fr->fr_parent->fr_layout == FR_COL && nfr != NULL)
+ break;
+ fr = fr->fr_parent;
+ }
+
+ /*
+ * Now go downwards to find the bottom or top frame in it.
+ */
+ for (;; ) {
+ if (nfr->fr_layout == FR_LEAF) {
+ foundfr = nfr;
+ break;
+ }
+ fr = nfr->fr_child;
+ if (nfr->fr_layout == FR_ROW) {
+ /* Find the frame at the cursor row. */
+ while (fr->fr_next != NULL
+ && frame2win(fr)->w_wincol + fr->fr_width
+ <= curwin->w_wincol + curwin->w_wcol)
+ fr = fr->fr_next;
+ }
+ if (nfr->fr_layout == FR_COL && up)
+ while (fr->fr_next != NULL)
+ fr = fr->fr_next;
+ nfr = fr;
+ }
+ }
+end:
+ if (foundfr != NULL)
+ win_goto(foundfr->fr_win);
+}
+
+/*
+ * Move to left or right window.
+ */
+static void win_goto_hor(left, count)
+int left; /* TRUE to go to left win */
+long count;
+{
+ frame_T *fr;
+ frame_T *nfr;
+ frame_T *foundfr;
+
+ foundfr = curwin->w_frame;
+ while (count--) {
+ /*
+ * First go upwards in the tree of frames until we find a left or
+ * right neighbor.
+ */
+ fr = foundfr;
+ for (;; ) {
+ if (fr == topframe)
+ goto end;
+ if (left)
+ nfr = fr->fr_prev;
+ else
+ nfr = fr->fr_next;
+ if (fr->fr_parent->fr_layout == FR_ROW && nfr != NULL)
+ break;
+ fr = fr->fr_parent;
+ }
+
+ /*
+ * Now go downwards to find the leftmost or rightmost frame in it.
+ */
+ for (;; ) {
+ if (nfr->fr_layout == FR_LEAF) {
+ foundfr = nfr;
+ break;
+ }
+ fr = nfr->fr_child;
+ if (nfr->fr_layout == FR_COL) {
+ /* Find the frame at the cursor row. */
+ while (fr->fr_next != NULL
+ && frame2win(fr)->w_winrow + fr->fr_height
+ <= curwin->w_winrow + curwin->w_wrow)
+ fr = fr->fr_next;
+ }
+ if (nfr->fr_layout == FR_ROW && left)
+ while (fr->fr_next != NULL)
+ fr = fr->fr_next;
+ nfr = fr;
+ }
+ }
+end:
+ if (foundfr != NULL)
+ win_goto(foundfr->fr_win);
+}
+
+/*
+ * Make window "wp" the current window.
+ */
+void win_enter(wp, undo_sync)
+win_T *wp;
+int undo_sync;
+{
+ win_enter_ext(wp, undo_sync, FALSE, TRUE, TRUE);
+}
+
+/*
+ * Make window wp the current window.
+ * Can be called with "curwin_invalid" TRUE, which means that curwin has just
+ * been closed and isn't valid.
+ */
+static void win_enter_ext(wp, undo_sync, curwin_invalid, trigger_enter_autocmds,
+ trigger_leave_autocmds)
+win_T *wp;
+int undo_sync;
+int curwin_invalid;
+int trigger_enter_autocmds UNUSED;
+int trigger_leave_autocmds UNUSED;
+{
+ int other_buffer = FALSE;
+
+ if (wp == curwin && !curwin_invalid) /* nothing to do */
+ return;
+
+ if (!curwin_invalid && trigger_leave_autocmds) {
+ /*
+ * Be careful: If autocommands delete the window, return now.
+ */
+ if (wp->w_buffer != curbuf) {
+ apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, FALSE, curbuf);
+ other_buffer = TRUE;
+ if (!win_valid(wp))
+ return;
+ }
+ apply_autocmds(EVENT_WINLEAVE, NULL, NULL, FALSE, curbuf);
+ if (!win_valid(wp))
+ return;
+ /* autocmds may abort script processing */
+ if (aborting())
+ return;
+ }
+
+ /* sync undo before leaving the current buffer */
+ if (undo_sync && curbuf != wp->w_buffer)
+ u_sync(FALSE);
+ /* may have to copy the buffer options when 'cpo' contains 'S' */
+ if (wp->w_buffer != curbuf)
+ buf_copy_options(wp->w_buffer, BCO_ENTER | BCO_NOHELP);
+ if (!curwin_invalid) {
+ prevwin = curwin; /* remember for CTRL-W p */
+ curwin->w_redr_status = TRUE;
+ }
+ curwin = wp;
+ curbuf = wp->w_buffer;
+ check_cursor();
+ if (!virtual_active())
+ curwin->w_cursor.coladd = 0;
+ changed_line_abv_curs(); /* assume cursor position needs updating */
+
+ if (curwin->w_localdir != NULL) {
+ /* Window has a local directory: Save current directory as global
+ * directory (unless that was done already) and change to the local
+ * directory. */
+ if (globaldir == NULL) {
+ char_u cwd[MAXPATHL];
+
+ if (mch_dirname(cwd, MAXPATHL) == OK)
+ globaldir = vim_strsave(cwd);
+ }
+ if (mch_chdir((char *)curwin->w_localdir) == 0)
+ 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 = mch_chdir((char *)globaldir);
+ vim_free(globaldir);
+ globaldir = NULL;
+ shorten_fnames(TRUE);
+ }
+
+ if (trigger_enter_autocmds) {
+ apply_autocmds(EVENT_WINENTER, NULL, NULL, FALSE, curbuf);
+ if (other_buffer)
+ apply_autocmds(EVENT_BUFENTER, NULL, NULL, FALSE, curbuf);
+ }
+
+ maketitle();
+ curwin->w_redr_status = TRUE;
+ redraw_tabline = TRUE;
+ if (restart_edit)
+ redraw_later(VALID); /* causes status line redraw */
+
+ /* set window height to desired minimal value */
+ if (curwin->w_height < p_wh && !curwin->w_p_wfh)
+ win_setheight((int)p_wh);
+ else if (curwin->w_height == 0)
+ win_setheight(1);
+
+ /* set window width to desired minimal value */
+ if (curwin->w_width < p_wiw && !curwin->w_p_wfw)
+ win_setwidth((int)p_wiw);
+
+ setmouse(); /* in case jumped to/from help buffer */
+
+ /* Change directories when the 'acd' option is set. */
+ DO_AUTOCHDIR
+}
+
+
+/*
+ * Jump to the first open window that contains buffer "buf", if one exists.
+ * Returns a pointer to the window found, otherwise NULL.
+ */
+win_T * buf_jump_open_win(buf)
+buf_T *buf;
+{
+ win_T *wp;
+
+ for (wp = firstwin; wp != NULL; wp = wp->w_next)
+ if (wp->w_buffer == buf)
+ break;
+ if (wp != NULL)
+ win_enter(wp, FALSE);
+ return wp;
+}
+
+/*
+ * Jump to the first open window in any tab page that contains buffer "buf",
+ * if one exists.
+ * Returns a pointer to the window found, otherwise NULL.
+ */
+win_T * buf_jump_open_tab(buf)
+buf_T *buf;
+{
+ win_T *wp;
+ tabpage_T *tp;
+
+ /* First try the current tab page. */
+ wp = buf_jump_open_win(buf);
+ if (wp != NULL)
+ return wp;
+
+ for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
+ if (tp != curtab) {
+ for (wp = tp->tp_firstwin; wp != NULL; wp = wp->w_next)
+ if (wp->w_buffer == buf)
+ break;
+ if (wp != NULL) {
+ goto_tabpage_win(tp, wp);
+ if (curwin != wp)
+ wp = NULL; /* something went wrong */
+ break;
+ }
+ }
+
+ return wp;
+}
+
+/*
+ * Allocate a window structure and link it in the window list when "hidden" is
+ * FALSE.
+ */
+static win_T * win_alloc(after, hidden)
+win_T *after UNUSED;
+int hidden UNUSED;
+{
+ win_T *new_wp;
+
+ /*
+ * allocate window structure and linesizes arrays
+ */
+ new_wp = (win_T *)alloc_clear((unsigned)sizeof(win_T));
+ if (new_wp == NULL)
+ return NULL;
+
+ if (win_alloc_lines(new_wp) == FAIL) {
+ vim_free(new_wp);
+ return NULL;
+ }
+
+ /* init w: variables */
+ new_wp->w_vars = dict_alloc();
+ if (new_wp->w_vars == NULL) {
+ win_free_lsize(new_wp);
+ vim_free(new_wp);
+ return NULL;
+ }
+ init_var_dict(new_wp->w_vars, &new_wp->w_winvar, VAR_SCOPE);
+
+ /* Don't execute autocommands while the window is not properly
+ * initialized yet. gui_create_scrollbar() may trigger a FocusGained
+ * event. */
+ block_autocmds();
+ /*
+ * link the window in the window list
+ */
+ if (!hidden)
+ win_append(after, new_wp);
+ new_wp->w_wincol = 0;
+ new_wp->w_width = Columns;
+
+ /* position the display and the cursor at the top of the file. */
+ new_wp->w_topline = 1;
+ new_wp->w_topfill = 0;
+ new_wp->w_botline = 2;
+ new_wp->w_cursor.lnum = 1;
+ new_wp->w_scbind_pos = 1;
+
+ /* We won't calculate w_fraction until resizing the window */
+ new_wp->w_fraction = 0;
+ new_wp->w_prev_fraction_row = -1;
+
+ foldInitWin(new_wp);
+ unblock_autocmds();
+ new_wp->w_match_head = NULL;
+ new_wp->w_next_match_id = 4;
+ return new_wp;
+}
+
+
+/*
+ * Remove window 'wp' from the window list and free the structure.
+ */
+static void win_free(wp, tp)
+win_T *wp;
+tabpage_T *tp; /* tab page "win" is in, NULL for current */
+{
+ int i;
+ buf_T *buf;
+ wininfo_T *wip;
+
+ clearFolding(wp);
+
+ /* reduce the reference count to the argument list. */
+ alist_unlink(wp->w_alist);
+
+ /* Don't execute autocommands while the window is halfway being deleted.
+ * gui_mch_destroy_scrollbar() may trigger a FocusGained event. */
+ block_autocmds();
+
+
+
+
+
+
+
+
+ clear_winopt(&wp->w_onebuf_opt);
+ clear_winopt(&wp->w_allbuf_opt);
+
+ vars_clear(&wp->w_vars->dv_hashtab); /* free all w: variables */
+ hash_init(&wp->w_vars->dv_hashtab);
+ unref_var_dict(wp->w_vars);
+
+ if (prevwin == wp)
+ prevwin = NULL;
+ win_free_lsize(wp);
+
+ for (i = 0; i < wp->w_tagstacklen; ++i)
+ vim_free(wp->w_tagstack[i].tagname);
+
+ vim_free(wp->w_localdir);
+
+ /* Remove the window from the b_wininfo lists, it may happen that the
+ * freed memory is re-used for another window. */
+ for (buf = firstbuf; buf != NULL; buf = buf->b_next)
+ for (wip = buf->b_wininfo; wip != NULL; wip = wip->wi_next)
+ if (wip->wi_win == wp)
+ wip->wi_win = NULL;
+
+ clear_matches(wp);
+
+ free_jumplist(wp);
+
+ qf_free_all(wp);
+
+
+ vim_free(wp->w_p_cc_cols);
+
+ if (wp != aucmd_win)
+ win_remove(wp, tp);
+ vim_free(wp);
+
+ unblock_autocmds();
+}
+
+/*
+ * Append window "wp" in the window list after window "after".
+ */
+void win_append(after, wp)
+win_T *after, *wp;
+{
+ win_T *before;
+
+ if (after == NULL) /* after NULL is in front of the first */
+ before = firstwin;
+ else
+ before = after->w_next;
+
+ wp->w_next = before;
+ wp->w_prev = after;
+ if (after == NULL)
+ firstwin = wp;
+ else
+ after->w_next = wp;
+ if (before == NULL)
+ lastwin = wp;
+ else
+ before->w_prev = wp;
+}
+
+/*
+ * Remove a window from the window list.
+ */
+void win_remove(wp, tp)
+win_T *wp;
+tabpage_T *tp; /* tab page "win" is in, NULL for current */
+{
+ if (wp->w_prev != NULL)
+ wp->w_prev->w_next = wp->w_next;
+ else if (tp == NULL)
+ firstwin = wp->w_next;
+ else
+ tp->tp_firstwin = wp->w_next;
+ if (wp->w_next != NULL)
+ wp->w_next->w_prev = wp->w_prev;
+ else if (tp == NULL)
+ lastwin = wp->w_prev;
+ else
+ tp->tp_lastwin = wp->w_prev;
+}
+
+/*
+ * Append frame "frp" in a frame list after frame "after".
+ */
+static void frame_append(after, frp)
+frame_T *after, *frp;
+{
+ frp->fr_next = after->fr_next;
+ after->fr_next = frp;
+ if (frp->fr_next != NULL)
+ frp->fr_next->fr_prev = frp;
+ frp->fr_prev = after;
+}
+
+/*
+ * Insert frame "frp" in a frame list before frame "before".
+ */
+static void frame_insert(before, frp)
+frame_T *before, *frp;
+{
+ frp->fr_next = before;
+ frp->fr_prev = before->fr_prev;
+ before->fr_prev = frp;
+ if (frp->fr_prev != NULL)
+ frp->fr_prev->fr_next = frp;
+ else
+ frp->fr_parent->fr_child = frp;
+}
+
+/*
+ * Remove a frame from a frame list.
+ */
+static void frame_remove(frp)
+frame_T *frp;
+{
+ if (frp->fr_prev != NULL)
+ frp->fr_prev->fr_next = frp->fr_next;
+ else
+ frp->fr_parent->fr_child = frp->fr_next;
+ if (frp->fr_next != NULL)
+ frp->fr_next->fr_prev = frp->fr_prev;
+}
+
+
+/*
+ * Allocate w_lines[] for window "wp".
+ * Return FAIL for failure, OK for success.
+ */
+int win_alloc_lines(wp)
+win_T *wp;
+{
+ wp->w_lines_valid = 0;
+ wp->w_lines = (wline_T *)alloc_clear((unsigned)(Rows * sizeof(wline_T)));
+ if (wp->w_lines == NULL)
+ return FAIL;
+ return OK;
+}
+
+/*
+ * free lsize arrays for a window
+ */
+void win_free_lsize(wp)
+win_T *wp;
+{
+ vim_free(wp->w_lines);
+ wp->w_lines = NULL;
+}
+
+/*
+ * Called from win_new_shellsize() after Rows changed.
+ * This only does the current tab page, others must be done when made active.
+ */
+void shell_new_rows() {
+ int h = (int)ROWS_AVAIL;
+
+ if (firstwin == NULL) /* not initialized yet */
+ return;
+ if (h < frame_minheight(topframe, NULL))
+ h = frame_minheight(topframe, NULL);
+
+ /* First try setting the heights of windows with 'winfixheight'. If
+ * that doesn't result in the right height, forget about that option. */
+ frame_new_height(topframe, h, FALSE, TRUE);
+ if (!frame_check_height(topframe, h))
+ frame_new_height(topframe, h, FALSE, FALSE);
+
+ (void)win_comp_pos(); /* recompute w_winrow and w_wincol */
+ compute_cmdrow();
+ curtab->tp_ch_used = p_ch;
+
+}
+
+/*
+ * Called from win_new_shellsize() after Columns changed.
+ */
+void shell_new_columns() {
+ if (firstwin == NULL) /* not initialized yet */
+ return;
+
+ /* First try setting the widths of windows with 'winfixwidth'. If that
+ * doesn't result in the right width, forget about that option. */
+ frame_new_width(topframe, (int)Columns, FALSE, TRUE);
+ if (!frame_check_width(topframe, Columns))
+ frame_new_width(topframe, (int)Columns, FALSE, FALSE);
+
+ (void)win_comp_pos(); /* recompute w_winrow and w_wincol */
+}
+
+/*
+ * Save the size of all windows in "gap".
+ */
+void win_size_save(gap)
+garray_T *gap;
+
+{
+ win_T *wp;
+
+ ga_init2(gap, (int)sizeof(int), 1);
+ if (ga_grow(gap, win_count() * 2) == OK)
+ for (wp = firstwin; wp != NULL; wp = wp->w_next) {
+ ((int *)gap->ga_data)[gap->ga_len++] =
+ wp->w_width + wp->w_vsep_width;
+ ((int *)gap->ga_data)[gap->ga_len++] = wp->w_height;
+ }
+}
+
+/*
+ * Restore window sizes, but only if the number of windows is still the same.
+ * Does not free the growarray.
+ */
+void win_size_restore(gap)
+garray_T *gap;
+{
+ win_T *wp;
+ int i;
+
+ if (win_count() * 2 == gap->ga_len) {
+ i = 0;
+ for (wp = firstwin; wp != NULL; wp = wp->w_next) {
+ frame_setwidth(wp->w_frame, ((int *)gap->ga_data)[i++]);
+ win_setheight_win(((int *)gap->ga_data)[i++], wp);
+ }
+ /* recompute the window positions */
+ (void)win_comp_pos();
+ }
+}
+
+/*
+ * Update the position for all windows, using the width and height of the
+ * frames.
+ * Returns the row just after the last window.
+ */
+int win_comp_pos() {
+ int row = tabline_height();
+ int col = 0;
+
+ frame_comp_pos(topframe, &row, &col);
+ return row;
+}
+
+/*
+ * Update the position of the windows in frame "topfrp", using the width and
+ * height of the frames.
+ * "*row" and "*col" are the top-left position of the frame. They are updated
+ * to the bottom-right position plus one.
+ */
+static void frame_comp_pos(topfrp, row, col)
+frame_T *topfrp;
+int *row;
+int *col;
+{
+ win_T *wp;
+ frame_T *frp;
+ int startcol;
+ int startrow;
+
+ wp = topfrp->fr_win;
+ if (wp != NULL) {
+ if (wp->w_winrow != *row
+ || wp->w_wincol != *col
+ ) {
+ /* position changed, redraw */
+ wp->w_winrow = *row;
+ wp->w_wincol = *col;
+ redraw_win_later(wp, NOT_VALID);
+ wp->w_redr_status = TRUE;
+ }
+ *row += wp->w_height + wp->w_status_height;
+ *col += wp->w_width + wp->w_vsep_width;
+ } else {
+ startrow = *row;
+ startcol = *col;
+ for (frp = topfrp->fr_child; frp != NULL; frp = frp->fr_next) {
+ if (topfrp->fr_layout == FR_ROW)
+ *row = startrow; /* all frames are at the same row */
+ else
+ *col = startcol; /* all frames are at the same col */
+ frame_comp_pos(frp, row, col);
+ }
+ }
+}
+
+
+/*
+ * Set current window height and take care of repositioning other windows to
+ * fit around it.
+ */
+void win_setheight(height)
+int height;
+{
+ win_setheight_win(height, curwin);
+}
+
+/*
+ * Set the window height of window "win" and take care of repositioning other
+ * windows to fit around it.
+ */
+void win_setheight_win(height, win)
+int height;
+win_T *win;
+{
+ int row;
+
+ if (win == curwin) {
+ /* Always keep current window at least one line high, even when
+ * 'winminheight' is zero. */
+ if (height < p_wmh)
+ height = p_wmh;
+ if (height == 0)
+ height = 1;
+ }
+
+ frame_setheight(win->w_frame, height + win->w_status_height);
+
+ /* recompute the window positions */
+ row = win_comp_pos();
+
+ /*
+ * 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);
+ cmdline_row = row;
+ msg_row = row;
+ msg_col = 0;
+
+ redraw_all_later(NOT_VALID);
+}
+
+
+/*
+ * Set the height of a frame to "height" and take care that all frames and
+ * windows inside it are resized. Also resize frames on the left and right if
+ * the are in the same FR_ROW frame.
+ *
+ * Strategy:
+ * If the frame is part of a FR_COL frame, try fitting the frame in that
+ * frame. If that doesn't work (the FR_COL frame is too small), recursively
+ * go to containing frames to resize them and make room.
+ * If the frame is part of a FR_ROW frame, all frames must be resized as well.
+ * Check for the minimal height of the FR_ROW frame.
+ * At the top level we can also use change the command line height.
+ */
+static void frame_setheight(curfrp, height)
+frame_T *curfrp;
+int height;
+{
+ int room; /* total number of lines available */
+ int take; /* number of lines taken from other windows */
+ int room_cmdline; /* lines available from cmdline */
+ int run;
+ frame_T *frp;
+ int h;
+ int room_reserved;
+
+ /* If the height already is the desired value, nothing to do. */
+ if (curfrp->fr_height == height)
+ return;
+
+ if (curfrp->fr_parent == NULL) {
+ /* topframe: can only change the command line */
+ if (height > ROWS_AVAIL)
+ height = ROWS_AVAIL;
+ if (height > 0)
+ frame_new_height(curfrp, height, FALSE, FALSE);
+ } else if (curfrp->fr_parent->fr_layout == FR_ROW) {
+ /* Row of frames: Also need to resize frames left and right of this
+ * one. First check for the minimal height of these. */
+ h = frame_minheight(curfrp->fr_parent, NULL);
+ if (height < h)
+ height = h;
+ frame_setheight(curfrp->fr_parent, height);
+ } else {
+ /*
+ * Column of frames: try to change only frames in this column.
+ */
+ /*
+ * Do this twice:
+ * 1: compute room available, if it's not enough try resizing the
+ * containing frame.
+ * 2: compute the room available and adjust the height to it.
+ * Try not to reduce the height of a window with 'winfixheight' set.
+ */
+ for (run = 1; run <= 2; ++run) {
+ room = 0;
+ room_reserved = 0;
+ for (frp = curfrp->fr_parent->fr_child; frp != NULL;
+ frp = frp->fr_next) {
+ if (frp != curfrp
+ && frp->fr_win != NULL
+ && frp->fr_win->w_p_wfh)
+ room_reserved += frp->fr_height;
+ room += frp->fr_height;
+ if (frp != curfrp)
+ room -= frame_minheight(frp, NULL);
+ }
+ if (curfrp->fr_width != Columns)
+ room_cmdline = 0;
+ else {
+ room_cmdline = Rows - p_ch - (lastwin->w_winrow
+ + lastwin->w_height +
+ lastwin->w_status_height);
+ if (room_cmdline < 0)
+ room_cmdline = 0;
+ }
+
+ if (height <= room + room_cmdline)
+ break;
+ if (run == 2 || curfrp->fr_width == Columns) {
+ if (height > room + room_cmdline)
+ height = room + room_cmdline;
+ break;
+ }
+ frame_setheight(curfrp->fr_parent, height
+ + frame_minheight(curfrp->fr_parent, NOWIN) - (int)p_wmh - 1);
+ /*NOTREACHED*/
+ }
+
+ /*
+ * Compute the number of lines we will take from others frames (can be
+ * negative!).
+ */
+ take = height - curfrp->fr_height;
+
+ /* If there is not enough room, also reduce the height of a window
+ * with 'winfixheight' set. */
+ if (height > room + room_cmdline - room_reserved)
+ room_reserved = room + room_cmdline - height;
+ /* If there is only a 'winfixheight' window and making the
+ * window smaller, need to make the other window taller. */
+ if (take < 0 && room - curfrp->fr_height < room_reserved)
+ room_reserved = 0;
+
+ if (take > 0 && room_cmdline > 0) {
+ /* use lines from cmdline first */
+ if (take < room_cmdline)
+ room_cmdline = take;
+ take -= room_cmdline;
+ topframe->fr_height += room_cmdline;
+ }
+
+ /*
+ * set the current frame to the new height
+ */
+ frame_new_height(curfrp, height, FALSE, FALSE);
+
+ /*
+ * First take lines from the frames after the current frame. If
+ * that is not enough, takes lines from frames above the current
+ * frame.
+ */
+ for (run = 0; run < 2; ++run) {
+ if (run == 0)
+ frp = curfrp->fr_next; /* 1st run: start with next window */
+ else
+ frp = curfrp->fr_prev; /* 2nd run: start with prev window */
+ while (frp != NULL && take != 0) {
+ h = frame_minheight(frp, NULL);
+ if (room_reserved > 0
+ && frp->fr_win != NULL
+ && frp->fr_win->w_p_wfh) {
+ if (room_reserved >= frp->fr_height)
+ room_reserved -= frp->fr_height;
+ else {
+ if (frp->fr_height - room_reserved > take)
+ room_reserved = frp->fr_height - take;
+ take -= frp->fr_height - room_reserved;
+ frame_new_height(frp, room_reserved, FALSE, FALSE);
+ room_reserved = 0;
+ }
+ } else {
+ if (frp->fr_height - take < h) {
+ take -= frp->fr_height - h;
+ frame_new_height(frp, h, FALSE, FALSE);
+ } else {
+ frame_new_height(frp, frp->fr_height - take,
+ FALSE, FALSE);
+ take = 0;
+ }
+ }
+ if (run == 0)
+ frp = frp->fr_next;
+ else
+ frp = frp->fr_prev;
+ }
+ }
+ }
+}
+
+/*
+ * Set current window width and take care of repositioning other windows to
+ * fit around it.
+ */
+void win_setwidth(width)
+int width;
+{
+ win_setwidth_win(width, curwin);
+}
+
+void win_setwidth_win(width, wp)
+int width;
+win_T *wp;
+{
+ /* Always keep current window at least one column wide, even when
+ * 'winminwidth' is zero. */
+ if (wp == curwin) {
+ if (width < p_wmw)
+ width = p_wmw;
+ if (width == 0)
+ width = 1;
+ }
+
+ frame_setwidth(wp->w_frame, width + wp->w_vsep_width);
+
+ /* recompute the window positions */
+ (void)win_comp_pos();
+
+ redraw_all_later(NOT_VALID);
+}
+
+/*
+ * Set the width of a frame to "width" and take care that all frames and
+ * windows inside it are resized. Also resize frames above and below if the
+ * are in the same FR_ROW frame.
+ *
+ * Strategy is similar to frame_setheight().
+ */
+static void frame_setwidth(curfrp, width)
+frame_T *curfrp;
+int width;
+{
+ int room; /* total number of lines available */
+ int take; /* number of lines taken from other windows */
+ int run;
+ frame_T *frp;
+ int w;
+ int room_reserved;
+
+ /* If the width already is the desired value, nothing to do. */
+ if (curfrp->fr_width == width)
+ return;
+
+ if (curfrp->fr_parent == NULL)
+ /* topframe: can't change width */
+ return;
+
+ if (curfrp->fr_parent->fr_layout == FR_COL) {
+ /* Column of frames: Also need to resize frames above and below of
+ * this one. First check for the minimal width of these. */
+ w = frame_minwidth(curfrp->fr_parent, NULL);
+ if (width < w)
+ width = w;
+ frame_setwidth(curfrp->fr_parent, width);
+ } else {
+ /*
+ * Row of frames: try to change only frames in this row.
+ *
+ * Do this twice:
+ * 1: compute room available, if it's not enough try resizing the
+ * containing frame.
+ * 2: compute the room available and adjust the width to it.
+ */
+ for (run = 1; run <= 2; ++run) {
+ room = 0;
+ room_reserved = 0;
+ for (frp = curfrp->fr_parent->fr_child; frp != NULL;
+ frp = frp->fr_next) {
+ if (frp != curfrp
+ && frp->fr_win != NULL
+ && frp->fr_win->w_p_wfw)
+ room_reserved += frp->fr_width;
+ room += frp->fr_width;
+ if (frp != curfrp)
+ room -= frame_minwidth(frp, NULL);
+ }
+
+ if (width <= room)
+ break;
+ if (run == 2 || curfrp->fr_height >= ROWS_AVAIL) {
+ if (width > room)
+ width = room;
+ break;
+ }
+ frame_setwidth(curfrp->fr_parent, width
+ + frame_minwidth(curfrp->fr_parent, NOWIN) - (int)p_wmw - 1);
+ }
+
+ /*
+ * Compute the number of lines we will take from others frames (can be
+ * negative!).
+ */
+ take = width - curfrp->fr_width;
+
+ /* If there is not enough room, also reduce the width of a window
+ * with 'winfixwidth' set. */
+ if (width > room - room_reserved)
+ room_reserved = room - width;
+ /* If there is only a 'winfixwidth' window and making the
+ * window smaller, need to make the other window narrower. */
+ if (take < 0 && room - curfrp->fr_width < room_reserved)
+ room_reserved = 0;
+
+ /*
+ * set the current frame to the new width
+ */
+ frame_new_width(curfrp, width, FALSE, FALSE);
+
+ /*
+ * First take lines from the frames right of the current frame. If
+ * that is not enough, takes lines from frames left of the current
+ * frame.
+ */
+ for (run = 0; run < 2; ++run) {
+ if (run == 0)
+ frp = curfrp->fr_next; /* 1st run: start with next window */
+ else
+ frp = curfrp->fr_prev; /* 2nd run: start with prev window */
+ while (frp != NULL && take != 0) {
+ w = frame_minwidth(frp, NULL);
+ if (room_reserved > 0
+ && frp->fr_win != NULL
+ && frp->fr_win->w_p_wfw) {
+ if (room_reserved >= frp->fr_width)
+ room_reserved -= frp->fr_width;
+ else {
+ if (frp->fr_width - room_reserved > take)
+ room_reserved = frp->fr_width - take;
+ take -= frp->fr_width - room_reserved;
+ frame_new_width(frp, room_reserved, FALSE, FALSE);
+ room_reserved = 0;
+ }
+ } else {
+ if (frp->fr_width - take < w) {
+ take -= frp->fr_width - w;
+ frame_new_width(frp, w, FALSE, FALSE);
+ } else {
+ frame_new_width(frp, frp->fr_width - take,
+ FALSE, FALSE);
+ take = 0;
+ }
+ }
+ if (run == 0)
+ frp = frp->fr_next;
+ else
+ frp = frp->fr_prev;
+ }
+ }
+ }
+}
+
+/*
+ * Check 'winminheight' for a valid value.
+ */
+void win_setminheight() {
+ int room;
+ int first = TRUE;
+ win_T *wp;
+
+ /* loop until there is a 'winminheight' that is possible */
+ while (p_wmh > 0) {
+ /* TODO: handle vertical splits */
+ room = -p_wh;
+ for (wp = firstwin; wp != NULL; wp = wp->w_next)
+ room += wp->w_height - p_wmh;
+ if (room >= 0)
+ break;
+ --p_wmh;
+ if (first) {
+ EMSG(_(e_noroom));
+ first = FALSE;
+ }
+ }
+}
+
+/*
+ * Status line of dragwin is dragged "offset" lines down (negative is up).
+ */
+void win_drag_status_line(dragwin, offset)
+win_T *dragwin;
+int offset;
+{
+ frame_T *curfr;
+ frame_T *fr;
+ int room;
+ int row;
+ int up; /* if TRUE, drag status line up, otherwise down */
+ int n;
+
+ fr = dragwin->w_frame;
+ curfr = fr;
+ if (fr != topframe) { /* more than one window */
+ fr = fr->fr_parent;
+ /* When the parent frame is not a column of frames, its parent should
+ * be. */
+ if (fr->fr_layout != FR_COL) {
+ curfr = fr;
+ if (fr != topframe) /* only a row of windows, may drag statusline */
+ fr = fr->fr_parent;
+ }
+ }
+
+ /* If this is the last frame in a column, may want to resize the parent
+ * frame instead (go two up to skip a row of frames). */
+ while (curfr != topframe && curfr->fr_next == NULL) {
+ if (fr != topframe)
+ fr = fr->fr_parent;
+ curfr = fr;
+ if (fr != topframe)
+ fr = fr->fr_parent;
+ }
+
+ if (offset < 0) { /* drag up */
+ up = TRUE;
+ offset = -offset;
+ /* sum up the room of the current frame and above it */
+ if (fr == curfr) {
+ /* only one window */
+ room = fr->fr_height - frame_minheight(fr, NULL);
+ } else {
+ room = 0;
+ for (fr = fr->fr_child;; fr = fr->fr_next) {
+ room += fr->fr_height - frame_minheight(fr, NULL);
+ if (fr == curfr)
+ break;
+ }
+ }
+ fr = curfr->fr_next; /* put fr at frame that grows */
+ } else { /* drag down */
+ up = FALSE;
+ /*
+ * Only dragging the last status line can reduce p_ch.
+ */
+ room = Rows - cmdline_row;
+ if (curfr->fr_next == NULL)
+ room -= 1;
+ else
+ room -= p_ch;
+ if (room < 0)
+ room = 0;
+ /* sum up the room of frames below of the current one */
+ for (fr = curfr->fr_next; fr != NULL; fr = fr->fr_next)
+ room += fr->fr_height - frame_minheight(fr, NULL);
+ fr = curfr; /* put fr at window that grows */
+ }
+
+ if (room < offset) /* Not enough room */
+ offset = room; /* Move as far as we can */
+ if (offset <= 0)
+ return;
+
+ /*
+ * Grow frame fr by "offset" lines.
+ * Doesn't happen when dragging the last status line up.
+ */
+ if (fr != NULL)
+ frame_new_height(fr, fr->fr_height + offset, up, FALSE);
+
+ if (up)
+ fr = curfr; /* current frame gets smaller */
+ else
+ fr = curfr->fr_next; /* next frame gets smaller */
+
+ /*
+ * Now make the other frames smaller.
+ */
+ while (fr != NULL && offset > 0) {
+ n = frame_minheight(fr, NULL);
+ if (fr->fr_height - offset <= n) {
+ offset -= fr->fr_height - n;
+ frame_new_height(fr, n, !up, FALSE);
+ } else {
+ frame_new_height(fr, fr->fr_height - offset, !up, FALSE);
+ break;
+ }
+ if (up)
+ fr = fr->fr_prev;
+ else
+ fr = fr->fr_next;
+ }
+ row = win_comp_pos();
+ screen_fill(row, cmdline_row, 0, (int)Columns, ' ', ' ', 0);
+ cmdline_row = row;
+ p_ch = Rows - cmdline_row;
+ if (p_ch < 1)
+ p_ch = 1;
+ curtab->tp_ch_used = p_ch;
+ redraw_all_later(SOME_VALID);
+ showmode();
+}
+
+/*
+ * Separator line of dragwin is dragged "offset" lines right (negative is left).
+ */
+void win_drag_vsep_line(dragwin, offset)
+win_T *dragwin;
+int offset;
+{
+ frame_T *curfr;
+ frame_T *fr;
+ int room;
+ int left; /* if TRUE, drag separator line left, otherwise right */
+ int n;
+
+ fr = dragwin->w_frame;
+ if (fr == topframe) /* only one window (cannot happen?) */
+ return;
+ curfr = fr;
+ fr = fr->fr_parent;
+ /* When the parent frame is not a row of frames, its parent should be. */
+ if (fr->fr_layout != FR_ROW) {
+ if (fr == topframe) /* only a column of windows (cannot happen?) */
+ return;
+ curfr = fr;
+ fr = fr->fr_parent;
+ }
+
+ /* If this is the last frame in a row, may want to resize a parent
+ * frame instead. */
+ while (curfr->fr_next == NULL) {
+ if (fr == topframe)
+ break;
+ curfr = fr;
+ fr = fr->fr_parent;
+ if (fr != topframe) {
+ curfr = fr;
+ fr = fr->fr_parent;
+ }
+ }
+
+ if (offset < 0) { /* drag left */
+ left = TRUE;
+ offset = -offset;
+ /* sum up the room of the current frame and left of it */
+ room = 0;
+ for (fr = fr->fr_child;; fr = fr->fr_next) {
+ room += fr->fr_width - frame_minwidth(fr, NULL);
+ if (fr == curfr)
+ break;
+ }
+ fr = curfr->fr_next; /* put fr at frame that grows */
+ } else { /* drag right */
+ left = FALSE;
+ /* sum up the room of frames right of the current one */
+ room = 0;
+ for (fr = curfr->fr_next; fr != NULL; fr = fr->fr_next)
+ room += fr->fr_width - frame_minwidth(fr, NULL);
+ fr = curfr; /* put fr at window that grows */
+ }
+
+ if (room < offset) /* Not enough room */
+ offset = room; /* Move as far as we can */
+ if (offset <= 0) /* No room at all, quit. */
+ return;
+
+ /* grow frame fr by offset lines */
+ frame_new_width(fr, fr->fr_width + offset, left, FALSE);
+
+ /* shrink other frames: current and at the left or at the right */
+ if (left)
+ fr = curfr; /* current frame gets smaller */
+ else
+ fr = curfr->fr_next; /* next frame gets smaller */
+
+ while (fr != NULL && offset > 0) {
+ n = frame_minwidth(fr, NULL);
+ if (fr->fr_width - offset <= n) {
+ offset -= fr->fr_width - n;
+ frame_new_width(fr, n, !left, FALSE);
+ } else {
+ frame_new_width(fr, fr->fr_width - offset, !left, FALSE);
+ break;
+ }
+ if (left)
+ fr = fr->fr_prev;
+ else
+ fr = fr->fr_next;
+ }
+ (void)win_comp_pos();
+ redraw_all_later(NOT_VALID);
+}
+
+
+#define FRACTION_MULT 16384L
+
+/*
+ * Set wp->w_fraction for the current w_wrow and w_height.
+ */
+static void set_fraction(wp)
+win_T *wp;
+{
+ wp->w_fraction = ((long)wp->w_wrow * FRACTION_MULT
+ + FRACTION_MULT / 2) / (long)wp->w_height;
+}
+
+/*
+ * Set the height of a window.
+ * This takes care of the things inside the window, not what happens to the
+ * window position, the frame or to other windows.
+ */
+void win_new_height(wp, height)
+win_T *wp;
+int height;
+{
+ linenr_T lnum;
+ int sline, line_size;
+
+ /* Don't want a negative height. Happens when splitting a tiny window.
+ * Will equalize heights soon to fix it. */
+ if (height < 0)
+ height = 0;
+ if (wp->w_height == height)
+ return; /* nothing to do */
+
+ if (wp->w_wrow != wp->w_prev_fraction_row && wp->w_height > 0)
+ set_fraction(wp);
+
+ wp->w_height = height;
+ wp->w_skipcol = 0;
+
+ /* 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
+ && (!wp->w_p_scb || wp == curwin)
+ ) {
+ /*
+ * Find a value for w_topline that shows the cursor at the same
+ * relative position in the window as before (more or less).
+ */
+ lnum = wp->w_cursor.lnum;
+ if (lnum < 1) /* can happen when starting up */
+ lnum = 1;
+ wp->w_wrow = ((long)wp->w_fraction * (long)height - 1L) / FRACTION_MULT;
+ line_size = plines_win_col(wp, lnum, (long)(wp->w_cursor.col)) - 1;
+ 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);
+
+ if (sline > wp->w_height - rows) {
+ sline = wp->w_height - rows;
+ wp->w_wrow -= rows - line_size;
+ }
+ }
+
+ if (sline < 0) {
+ /*
+ * Cursor line would go off top of screen if w_wrow was this high.
+ * Make cursor line the first line in the window. If not enough
+ * room use w_skipcol;
+ */
+ wp->w_wrow = line_size;
+ if (wp->w_wrow >= wp->w_height
+ && (W_WIDTH(wp) - win_col_off(wp)) > 0) {
+ wp->w_skipcol += W_WIDTH(wp) - win_col_off(wp);
+ --wp->w_wrow;
+ while (wp->w_wrow >= wp->w_height) {
+ wp->w_skipcol += W_WIDTH(wp) - win_col_off(wp)
+ + win_col_off2(wp);
+ --wp->w_wrow;
+ }
+ }
+ } else {
+ while (sline > 0 && lnum > 1) {
+ hasFoldingWin(wp, lnum, &lnum, NULL, TRUE, NULL);
+ if (lnum == 1) {
+ /* first line in buffer is folded */
+ line_size = 1;
+ --sline;
+ break;
+ }
+ --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);
+ sline -= line_size;
+ }
+
+ if (sline < 0) {
+ /*
+ * Line we want at top would go off top of screen. Use next
+ * line instead.
+ */
+ hasFoldingWin(wp, lnum, NULL, &lnum, TRUE, NULL);
+ lnum++;
+ wp->w_wrow -= line_size + sline;
+ } else if (sline > 0) {
+ /* First line of file reached, use that as topline. */
+ lnum = 1;
+ wp->w_wrow -= sline;
+ }
+ }
+ set_topline(wp, lnum);
+ }
+
+ if (wp == curwin) {
+ if (p_so)
+ update_topline();
+ curs_columns(FALSE); /* validate w_wrow */
+ }
+ wp->w_prev_fraction_row = wp->w_wrow;
+
+ win_comp_scroll(wp);
+ redraw_win_later(wp, SOME_VALID);
+ wp->w_redr_status = TRUE;
+ invalidate_botline_win(wp);
+}
+
+/*
+ * Set the width of a window.
+ */
+void win_new_width(wp, width)
+win_T *wp;
+int width;
+{
+ wp->w_width = width;
+ wp->w_lines_valid = 0;
+ changed_line_abv_curs_win(wp);
+ invalidate_botline_win(wp);
+ if (wp == curwin) {
+ update_topline();
+ curs_columns(TRUE); /* validate w_wrow */
+ }
+ redraw_win_later(wp, NOT_VALID);
+ wp->w_redr_status = TRUE;
+}
+
+void win_comp_scroll(wp)
+win_T *wp;
+{
+ wp->w_p_scr = ((unsigned)wp->w_height >> 1);
+ if (wp->w_p_scr == 0)
+ wp->w_p_scr = 1;
+}
+
+/*
+ * command_height: called whenever p_ch has been changed
+ */
+void command_height() {
+ int h;
+ frame_T *frp;
+ int old_p_ch = curtab->tp_ch_used;
+
+ /* Use the value of p_ch that we remembered. This is needed for when the
+ * GUI starts up, we can't be sure in what order things happen. And when
+ * p_ch was changed in another tab page. */
+ curtab->tp_ch_used = p_ch;
+
+ /* Find bottom frame with width of screen. */
+ frp = lastwin->w_frame;
+ while (frp->fr_width != Columns && frp->fr_parent != NULL)
+ frp = frp->fr_parent;
+
+ /* Avoid changing the height of a window with 'winfixheight' set. */
+ while (frp->fr_prev != NULL && frp->fr_layout == FR_LEAF
+ && frp->fr_win->w_p_wfh)
+ frp = frp->fr_prev;
+
+ if (starting != NO_SCREEN) {
+ cmdline_row = Rows - p_ch;
+
+ if (p_ch > old_p_ch) { /* p_ch got bigger */
+ while (p_ch > old_p_ch) {
+ if (frp == NULL) {
+ EMSG(_(e_noroom));
+ p_ch = old_p_ch;
+ curtab->tp_ch_used = p_ch;
+ cmdline_row = Rows - p_ch;
+ break;
+ }
+ h = frp->fr_height - frame_minheight(frp, NULL);
+ if (h > p_ch - old_p_ch)
+ h = p_ch - old_p_ch;
+ old_p_ch += h;
+ frame_add_height(frp, -h);
+ frp = frp->fr_prev;
+ }
+
+ /* Recompute window positions. */
+ (void)win_comp_pos();
+
+ /* clear the lines added to cmdline */
+ if (full_screen)
+ screen_fill((int)(cmdline_row), (int)Rows, 0,
+ (int)Columns, ' ', ' ', 0);
+ msg_row = cmdline_row;
+ redraw_cmdline = TRUE;
+ return;
+ }
+
+ if (msg_row < cmdline_row)
+ msg_row = cmdline_row;
+ redraw_cmdline = TRUE;
+ }
+ frame_add_height(frp, (int)(old_p_ch - p_ch));
+
+ /* Recompute window positions. */
+ if (frp != lastwin->w_frame)
+ (void)win_comp_pos();
+}
+
+/*
+ * Resize frame "frp" to be "n" lines higher (negative for less high).
+ * Also resize the frames it is contained in.
+ */
+static void frame_add_height(frp, n)
+frame_T *frp;
+int n;
+{
+ frame_new_height(frp, frp->fr_height + n, FALSE, FALSE);
+ for (;; ) {
+ frp = frp->fr_parent;
+ if (frp == NULL)
+ break;
+ frp->fr_height += n;
+ }
+}
+
+/*
+ * Add or remove a status line for the bottom window(s), according to the
+ * value of 'laststatus'.
+ */
+void last_status(morewin)
+int morewin; /* pretend there are two or more windows */
+{
+ /* Don't make a difference between horizontal or vertical split. */
+ last_status_rec(topframe, (p_ls == 2
+ || (p_ls == 1 && (morewin || lastwin != firstwin))));
+}
+
+static void last_status_rec(fr, statusline)
+frame_T *fr;
+int statusline;
+{
+ frame_T *fp;
+ win_T *wp;
+
+ if (fr->fr_layout == FR_LEAF) {
+ wp = fr->fr_win;
+ if (wp->w_status_height != 0 && !statusline) {
+ /* remove status line */
+ win_new_height(wp, wp->w_height + 1);
+ wp->w_status_height = 0;
+ comp_col();
+ } else if (wp->w_status_height == 0 && statusline) {
+ /* Find a frame to take a line from. */
+ fp = fr;
+ while (fp->fr_height <= frame_minheight(fp, NULL)) {
+ if (fp == topframe) {
+ EMSG(_(e_noroom));
+ return;
+ }
+ /* In a column of frames: go to frame above. If already at
+ * the top or in a row of frames: go to parent. */
+ if (fp->fr_parent->fr_layout == FR_COL && fp->fr_prev != NULL)
+ fp = fp->fr_prev;
+ else
+ fp = fp->fr_parent;
+ }
+ wp->w_status_height = 1;
+ if (fp != fr) {
+ frame_new_height(fp, fp->fr_height - 1, FALSE, FALSE);
+ frame_fix_height(wp);
+ (void)win_comp_pos();
+ } else
+ win_new_height(wp, wp->w_height - 1);
+ comp_col();
+ redraw_all_later(SOME_VALID);
+ }
+ } else if (fr->fr_layout == FR_ROW) {
+ /* vertically split windows, set status line for each one */
+ for (fp = fr->fr_child; fp != NULL; fp = fp->fr_next)
+ last_status_rec(fp, statusline);
+ } else {
+ /* horizontally split window, set status line for last one */
+ for (fp = fr->fr_child; fp->fr_next != NULL; fp = fp->fr_next)
+ ;
+ last_status_rec(fp, statusline);
+ }
+}
+
+/*
+ * Return the number of lines used by the tab page line.
+ */
+int tabline_height() {
+ switch (p_stal) {
+ case 0: return 0;
+ case 1: return (first_tabpage->tp_next == NULL) ? 0 : 1;
+ }
+ return 1;
+}
+
+/*
+ * Get the file name at the cursor.
+ * If Visual mode is active, use the selected text if it's in one line.
+ * Returns the name in allocated memory, NULL for failure.
+ */
+char_u * grab_file_name(count, file_lnum)
+long count;
+linenr_T *file_lnum;
+{
+ if (VIsual_active) {
+ int len;
+ char_u *ptr;
+
+ if (get_visual_text(NULL, &ptr, &len) == FAIL)
+ return NULL;
+ return find_file_name_in_path(ptr, len,
+ FNAME_MESS|FNAME_EXP|FNAME_REL, count, curbuf->b_ffname);
+ }
+ return file_name_at_cursor(FNAME_MESS|FNAME_HYP|FNAME_EXP|FNAME_REL, count,
+ file_lnum);
+
+}
+
+/*
+ * Return the file name under or after the cursor.
+ *
+ * The 'path' option is searched if the file name is not absolute.
+ * The string returned has been alloc'ed and should be freed by the caller.
+ * NULL is returned if the file name or file is not found.
+ *
+ * options:
+ * FNAME_MESS give error messages
+ * FNAME_EXP expand to path
+ * FNAME_HYP check for hypertext link
+ * FNAME_INCL apply "includeexpr"
+ */
+char_u * file_name_at_cursor(options, count, file_lnum)
+int options;
+long count;
+linenr_T *file_lnum;
+{
+ return file_name_in_line(ml_get_curline(),
+ curwin->w_cursor.col, options, count, curbuf->b_ffname,
+ file_lnum);
+}
+
+/*
+ * Return the name of the file under or after ptr[col].
+ * Otherwise like file_name_at_cursor().
+ */
+char_u * file_name_in_line(line, col, options, count, rel_fname, file_lnum)
+char_u *line;
+int col;
+int options;
+long count;
+char_u *rel_fname; /* file we are searching relative to */
+linenr_T *file_lnum; /* line number after the file name */
+{
+ char_u *ptr;
+ int len;
+
+ /*
+ * 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)
+ EMSG(_("E446: No file name under cursor"));
+ return NULL;
+ }
+
+ /*
+ * Search backward for first char of the file name.
+ * Go one char back to ":" before "//" even when ':' is not in 'isfname'.
+ */
+ while (ptr > line) {
+ if (has_mbyte && (len = (*mb_head_off)(line, ptr - 1)) > 0)
+ ptr -= len + 1;
+ else if (vim_isfilec(ptr[-1])
+ || ((options & FNAME_HYP) && path_is_url(ptr - 1)))
+ --ptr;
+ else
+ break;
+ }
+
+ /*
+ * Search forward for the last char of the file name.
+ * Also allow "://" when ':' is not in 'isfname'.
+ */
+ len = 0;
+ while (vim_isfilec(ptr[len])
+ || ((options & FNAME_HYP) && path_is_url(ptr + len)))
+ if (has_mbyte)
+ len += (*mb_ptr2len)(ptr + len);
+ else
+ ++len;
+
+ /*
+ * If there is trailing punctuation, remove it.
+ * But don't remove "..", could be a directory name.
+ */
+ if (len > 2 && vim_strchr((char_u *)".,:;!", ptr[len - 1]) != NULL
+ && ptr[len - 2] != '.')
+ --len;
+
+ if (file_lnum != NULL) {
+ char_u *p;
+
+ /* Get the number after the file name and a separator character */
+ p = ptr + len;
+ p = skipwhite(p);
+ if (*p != NUL) {
+ if (!isdigit(*p))
+ ++p; /* skip the separator */
+ p = skipwhite(p);
+ if (isdigit(*p))
+ *file_lnum = (int)getdigits(&p);
+ }
+ }
+
+ return find_file_name_in_path(ptr, len, options, count, rel_fname);
+}
+
+static char_u *eval_includeexpr __ARGS((char_u *ptr, int len));
+
+static char_u * eval_includeexpr(ptr, len)
+char_u *ptr;
+int len;
+{
+ char_u *res;
+
+ set_vim_var_string(VV_FNAME, ptr, len);
+ res = eval_to_string_safe(curbuf->b_p_inex, NULL,
+ was_set_insecurely((char_u *)"includeexpr", OPT_LOCAL));
+ set_vim_var_string(VV_FNAME, NULL, 0);
+ return res;
+}
+
+/*
+ * Return the name of the file ptr[len] in 'path'.
+ * Otherwise like file_name_at_cursor().
+ */
+char_u * find_file_name_in_path(ptr, len, options, count, rel_fname)
+char_u *ptr;
+int len;
+int options;
+long count;
+char_u *rel_fname; /* file we are searching relative to */
+{
+ char_u *file_name;
+ int c;
+ char_u *tofree = NULL;
+
+ if ((options & FNAME_INCL) && *curbuf->b_p_inex != NUL) {
+ tofree = eval_includeexpr(ptr, len);
+ if (tofree != NULL) {
+ ptr = tofree;
+ len = (int)STRLEN(ptr);
+ }
+ }
+
+ if (options & FNAME_EXP) {
+ file_name = find_file_in_path(ptr, len, options & ~FNAME_MESS,
+ TRUE, rel_fname);
+
+ /*
+ * If the file could not be found in a normal way, try applying
+ * 'includeexpr' (unless done already).
+ */
+ if (file_name == NULL
+ && !(options & FNAME_INCL) && *curbuf->b_p_inex != NUL) {
+ tofree = eval_includeexpr(ptr, len);
+ if (tofree != NULL) {
+ ptr = tofree;
+ len = (int)STRLEN(ptr);
+ file_name = find_file_in_path(ptr, len, options & ~FNAME_MESS,
+ TRUE, rel_fname);
+ }
+ }
+ if (file_name == NULL && (options & FNAME_MESS)) {
+ c = ptr[len];
+ ptr[len] = NUL;
+ EMSG2(_("E447: Can't find file \"%s\" in path"), ptr);
+ ptr[len] = c;
+ }
+
+ /* Repeat finding the file "count" times. This matters when it
+ * appears several times in the path. */
+ while (file_name != NULL && --count > 0) {
+ vim_free(file_name);
+ file_name = find_file_in_path(ptr, len, options, FALSE, rel_fname);
+ }
+ } else
+ file_name = vim_strnsave(ptr, len);
+
+ vim_free(tofree);
+
+ return file_name;
+}
+
+/*
+ * Check if the "://" of a URL is at the pointer, return URL_SLASH.
+ * Also check for ":\\", which MS Internet Explorer accepts, return
+ * URL_BACKSLASH.
+ */
+static int path_is_url(p)
+char_u *p;
+{
+ if (STRNCMP(p, "://", (size_t)3) == 0)
+ return URL_SLASH;
+ else if (STRNCMP(p, ":\\\\", (size_t)3) == 0)
+ return URL_BACKSLASH;
+ return 0;
+}
+
+/*
+ * Check if "fname" starts with "name://". Return URL_SLASH if it does.
+ * Return URL_BACKSLASH for "name:\\".
+ * Return zero otherwise.
+ */
+int path_with_url(fname)
+char_u *fname;
+{
+ char_u *p;
+
+ for (p = fname; isalpha(*p); ++p)
+ ;
+ return path_is_url(p);
+}
+
+/*
+ * Return TRUE if "name" is a full (absolute) path name or URL.
+ */
+int vim_isAbsName(name)
+char_u *name;
+{
+ return path_with_url(name) != 0 || mch_isFullName(name);
+}
+
+/*
+ * Get absolute file name into buffer "buf[len]".
+ *
+ * return FAIL for failure, OK otherwise
+ */
+int vim_FullName(fname, buf, len, force)
+char_u *fname, *buf;
+int len;
+int force; /* force expansion even when already absolute */
+{
+ int retval = OK;
+ int url;
+
+ *buf = NUL;
+ if (fname == NULL)
+ return FAIL;
+
+ url = path_with_url(fname);
+ if (!url)
+ retval = mch_FullName(fname, buf, len, force);
+ if (url || retval == FAIL) {
+ /* something failed; use the file name (truncate when too long) */
+ vim_strncpy(buf, fname, len - 1);
+ }
+ return retval;
+}
+
+/*
+ * Return the minimal number of rows that is needed on the screen to display
+ * the current number of windows.
+ */
+int min_rows() {
+ int total;
+ tabpage_T *tp;
+ int n;
+
+ if (firstwin == NULL) /* not initialized yet */
+ return MIN_LINES;
+
+ total = 0;
+ for (tp = first_tabpage; tp != NULL; tp = tp->tp_next) {
+ n = frame_minheight(tp->tp_topframe, NULL);
+ if (total < n)
+ total = n;
+ }
+ total += tabline_height();
+ total += 1; /* count the room for the command line */
+ return total;
+}
+
+/*
+ * Return TRUE if there is only one window (in the current tab page), not
+ * counting a help or preview window, unless it is the current window.
+ * Does not count "aucmd_win".
+ */
+int only_one_window() {
+ int count = 0;
+ win_T *wp;
+
+ /* If there is another tab page there always is another window. */
+ if (first_tabpage->tp_next != NULL)
+ return FALSE;
+
+ for (wp = firstwin; wp != NULL; wp = wp->w_next)
+ if (wp->w_buffer != NULL
+ && (!((wp->w_buffer->b_help && !curbuf->b_help)
+ || wp->w_p_pvw
+ ) || wp == curwin)
+ && wp != aucmd_win
+ )
+ ++count;
+ return count <= 1;
+}
+
+/*
+ * Correct the cursor line number in other windows. Used after changing the
+ * current buffer, and before applying autocommands.
+ * When "do_curwin" is TRUE, also check current window.
+ */
+void check_lnums(do_curwin)
+int do_curwin;
+{
+ win_T *wp;
+
+ tabpage_T *tp;
+
+ FOR_ALL_TAB_WINDOWS(tp, wp)
+ if ((do_curwin || wp != curwin) && wp->w_buffer == curbuf) {
+ if (wp->w_cursor.lnum > curbuf->b_ml.ml_line_count)
+ wp->w_cursor.lnum = curbuf->b_ml.ml_line_count;
+ if (wp->w_topline > curbuf->b_ml.ml_line_count)
+ wp->w_topline = curbuf->b_ml.ml_line_count;
+ }
+}
+
+
+/*
+ * A snapshot of the window sizes, to restore them after closing the help
+ * window.
+ * Only these fields are used:
+ * fr_layout
+ * fr_width
+ * fr_height
+ * fr_next
+ * fr_child
+ * fr_win (only valid for the old curwin, NULL otherwise)
+ */
+
+/*
+ * Create a snapshot of the current frame sizes.
+ */
+void make_snapshot(idx)
+int idx;
+{
+ clear_snapshot(curtab, idx);
+ make_snapshot_rec(topframe, &curtab->tp_snapshot[idx]);
+}
+
+static void make_snapshot_rec(fr, frp)
+frame_T *fr;
+frame_T **frp;
+{
+ *frp = (frame_T *)alloc_clear((unsigned)sizeof(frame_T));
+ if (*frp == NULL)
+ return;
+ (*frp)->fr_layout = fr->fr_layout;
+ (*frp)->fr_width = fr->fr_width;
+ (*frp)->fr_height = fr->fr_height;
+ if (fr->fr_next != NULL)
+ make_snapshot_rec(fr->fr_next, &((*frp)->fr_next));
+ if (fr->fr_child != NULL)
+ make_snapshot_rec(fr->fr_child, &((*frp)->fr_child));
+ if (fr->fr_layout == FR_LEAF && fr->fr_win == curwin)
+ (*frp)->fr_win = curwin;
+}
+
+/*
+ * Remove any existing snapshot.
+ */
+static void clear_snapshot(tp, idx)
+tabpage_T *tp;
+int idx;
+{
+ clear_snapshot_rec(tp->tp_snapshot[idx]);
+ tp->tp_snapshot[idx] = NULL;
+}
+
+static void clear_snapshot_rec(fr)
+frame_T *fr;
+{
+ if (fr != NULL) {
+ clear_snapshot_rec(fr->fr_next);
+ clear_snapshot_rec(fr->fr_child);
+ vim_free(fr);
+ }
+}
+
+/*
+ * Restore a previously created snapshot, if there is any.
+ * This is only done if the screen size didn't change and the window layout is
+ * still the same.
+ */
+void restore_snapshot(idx, close_curwin)
+int idx;
+int close_curwin; /* closing current window */
+{
+ win_T *wp;
+
+ if (curtab->tp_snapshot[idx] != NULL
+ && curtab->tp_snapshot[idx]->fr_width == topframe->fr_width
+ && curtab->tp_snapshot[idx]->fr_height == topframe->fr_height
+ && check_snapshot_rec(curtab->tp_snapshot[idx], topframe) == OK) {
+ wp = restore_snapshot_rec(curtab->tp_snapshot[idx], topframe);
+ win_comp_pos();
+ if (wp != NULL && close_curwin)
+ win_goto(wp);
+ redraw_all_later(CLEAR);
+ }
+ clear_snapshot(curtab, idx);
+}
+
+/*
+ * Check if frames "sn" and "fr" have the same layout, same following frames
+ * and same children.
+ */
+static int check_snapshot_rec(sn, fr)
+frame_T *sn;
+frame_T *fr;
+{
+ if (sn->fr_layout != fr->fr_layout
+ || (sn->fr_next == NULL) != (fr->fr_next == NULL)
+ || (sn->fr_child == NULL) != (fr->fr_child == NULL)
+ || (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))
+ return FAIL;
+ return OK;
+}
+
+/*
+ * Copy the size of snapshot frame "sn" to frame "fr". Do the same for all
+ * following frames and children.
+ * Returns a pointer to the old current window, or NULL.
+ */
+static win_T * restore_snapshot_rec(sn, fr)
+frame_T *sn;
+frame_T *fr;
+{
+ win_T *wp = NULL;
+ win_T *wp2;
+
+ fr->fr_height = sn->fr_height;
+ fr->fr_width = sn->fr_width;
+ if (fr->fr_layout == FR_LEAF) {
+ frame_new_height(fr, fr->fr_height, FALSE, FALSE);
+ frame_new_width(fr, fr->fr_width, FALSE, FALSE);
+ wp = sn->fr_win;
+ }
+ if (sn->fr_next != NULL) {
+ wp2 = restore_snapshot_rec(sn->fr_next, fr->fr_next);
+ if (wp2 != NULL)
+ wp = wp2;
+ }
+ if (sn->fr_child != NULL) {
+ wp2 = restore_snapshot_rec(sn->fr_child, fr->fr_child);
+ if (wp2 != NULL)
+ wp = wp2;
+ }
+ return wp;
+}
+
+
+#if defined(FEAT_EVAL) || defined(FEAT_PYTHON) || defined(FEAT_PYTHON3) \
+ || defined(PROTO)
+/*
+ * Set "win" to be the curwin and "tp" to be the current tab page.
+ * restore_win() MUST be called to undo.
+ * No autocommands will be executed.
+ * When "no_display" is TRUE the display won't be affected, no redraw is
+ * triggered, another tabpage access is limited.
+ * Returns FAIL if switching to "win" failed.
+ */
+int switch_win(save_curwin, save_curtab, win, tp, no_display)
+win_T **save_curwin UNUSED;
+tabpage_T **save_curtab UNUSED;
+win_T *win UNUSED;
+tabpage_T *tp UNUSED;
+int no_display UNUSED;
+{
+ block_autocmds();
+ *save_curwin = curwin;
+ if (tp != NULL) {
+ *save_curtab = curtab;
+ if (no_display) {
+ curtab->tp_firstwin = firstwin;
+ curtab->tp_lastwin = lastwin;
+ curtab = tp;
+ firstwin = curtab->tp_firstwin;
+ lastwin = curtab->tp_lastwin;
+ } else
+ goto_tabpage_tp(tp, FALSE, FALSE);
+ }
+ if (!win_valid(win)) {
+ unblock_autocmds();
+ return FAIL;
+ }
+ curwin = win;
+ curbuf = curwin->w_buffer;
+ 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(save_curwin, save_curtab, no_display)
+win_T *save_curwin UNUSED;
+tabpage_T *save_curtab UNUSED;
+int no_display UNUSED;
+{
+ if (save_curtab != NULL && valid_tabpage(save_curtab)) {
+ if (no_display) {
+ curtab->tp_firstwin = firstwin;
+ curtab->tp_lastwin = lastwin;
+ curtab = save_curtab;
+ firstwin = curtab->tp_firstwin;
+ lastwin = curtab->tp_lastwin;
+ } else
+ goto_tabpage_tp(save_curtab, FALSE, FALSE);
+ }
+ if (win_valid(save_curwin)) {
+ curwin = save_curwin;
+ curbuf = curwin->w_buffer;
+ }
+ 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(save_curbuf, buf)
+buf_T *buf;
+buf_T **save_curbuf;
+{
+ block_autocmds();
+ *save_curbuf = curbuf;
+ --curbuf->b_nwindows;
+ curbuf = buf;
+ curwin->w_buffer = buf;
+ ++curbuf->b_nwindows;
+}
+
+/*
+ * Restore the current buffer after using switch_buffer().
+ */
+void restore_buffer(save_curbuf)
+buf_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;
+ }
+}
+#endif
+
+
+/*
+ * 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(wp, grp, pat, prio, id)
+win_T *wp;
+char_u *grp;
+char_u *pat;
+int prio;
+int id;
+{
+ matchitem_T *cur;
+ matchitem_T *prev;
+ matchitem_T *m;
+ int hlg_id;
+ regprog_T *regprog;
+
+ if (*grp == NUL || *pat == NUL)
+ return -1;
+ if (id < -1 || id == 0) {
+ EMSGN("E799: Invalid ID: %ld (must be greater than or equal to 1)", id);
+ return -1;
+ }
+ if (id != -1) {
+ cur = wp->w_match_head;
+ while (cur != NULL) {
+ if (cur->id == id) {
+ EMSGN("E801: ID already taken: %ld", id);
+ return -1;
+ }
+ cur = cur->next;
+ }
+ }
+ if ((hlg_id = syn_namen2id(grp, (int)STRLEN(grp))) == 0) {
+ EMSG2(_(e_nogroup), grp);
+ return -1;
+ }
+ if ((regprog = vim_regcomp(pat, RE_MAGIC)) == NULL) {
+ EMSG2(_(e_invarg2), pat);
+ return -1;
+ }
+
+ /* Find available match ID. */
+ while (id == -1) {
+ cur = wp->w_match_head;
+ while (cur != NULL && cur->id != wp->w_next_match_id)
+ cur = cur->next;
+ if (cur == NULL)
+ id = wp->w_next_match_id;
+ wp->w_next_match_id++;
+ }
+
+ /* Build new match. */
+ m = (matchitem_T *)alloc(sizeof(matchitem_T));
+ m->id = id;
+ m->priority = prio;
+ m->pattern = vim_strsave(pat);
+ m->hlg_id = hlg_id;
+ m->match.regprog = regprog;
+ m->match.rmm_ic = FALSE;
+ m->match.rmm_maxcol = 0;
+
+ /* Insert new match. The match list is in ascending order with regard to
+ * the match priorities. */
+ cur = wp->w_match_head;
+ prev = cur;
+ while (cur != NULL && prio >= cur->priority) {
+ prev = cur;
+ cur = cur->next;
+ }
+ if (cur == prev)
+ wp->w_match_head = m;
+ else
+ prev->next = m;
+ m->next = cur;
+
+ redraw_later(SOME_VALID);
+ return id;
+}
+
+/*
+ * Delete match with ID 'id' in the match list of window 'wp'.
+ * Print error messages if 'perr' is TRUE.
+ */
+int match_delete(wp, id, perr)
+win_T *wp;
+int id;
+int perr;
+{
+ matchitem_T *cur = wp->w_match_head;
+ matchitem_T *prev = cur;
+
+ if (id < 1) {
+ if (perr == TRUE)
+ EMSGN("E802: Invalid ID: %ld (must be greater than or equal to 1)",
+ id);
+ return -1;
+ }
+ while (cur != NULL && cur->id != id) {
+ prev = cur;
+ cur = cur->next;
+ }
+ if (cur == NULL) {
+ if (perr == TRUE)
+ EMSGN("E803: ID not found: %ld", id);
+ return -1;
+ }
+ if (cur == prev)
+ wp->w_match_head = cur->next;
+ else
+ prev->next = cur->next;
+ vim_regfree(cur->match.regprog);
+ vim_free(cur->pattern);
+ vim_free(cur);
+ redraw_later(SOME_VALID);
+ return 0;
+}
+
+/*
+ * Delete all matches in the match list of window 'wp'.
+ */
+void clear_matches(wp)
+win_T *wp;
+{
+ matchitem_T *m;
+
+ while (wp->w_match_head != NULL) {
+ m = wp->w_match_head->next;
+ vim_regfree(wp->w_match_head->match.regprog);
+ vim_free(wp->w_match_head->pattern);
+ vim_free(wp->w_match_head);
+ wp->w_match_head = m;
+ }
+ redraw_later(SOME_VALID);
+}
+
+/*
+ * Get match from ID 'id' in window 'wp'.
+ * Return NULL if match not found.
+ */
+matchitem_T * get_match(wp, id)
+win_T *wp;
+int id;
+{
+ matchitem_T *cur = wp->w_match_head;
+
+ while (cur != NULL && cur->id != id)
+ cur = cur->next;
+ return cur;
+}
+
+
+/*
+ * Return TRUE if "topfrp" and its children are at the right height.
+ */
+static int frame_check_height(topfrp, height)
+frame_T *topfrp;
+int height;
+{
+ frame_T *frp;
+
+ if (topfrp->fr_height != height)
+ return FALSE;
+
+ if (topfrp->fr_layout == FR_ROW)
+ for (frp = topfrp->fr_child; frp != NULL; frp = frp->fr_next)
+ if (frp->fr_height != height)
+ return FALSE;
+
+ return TRUE;
+}
+
+/*
+ * Return TRUE if "topfrp" and its children are at the right width.
+ */
+static int frame_check_width(topfrp, width)
+frame_T *topfrp;
+int width;
+{
+ frame_T *frp;
+
+ if (topfrp->fr_width != width)
+ return FALSE;
+
+ if (topfrp->fr_layout == FR_COL)
+ for (frp = topfrp->fr_child; frp != NULL; frp = frp->fr_next)
+ if (frp->fr_width != width)
+ return FALSE;
+
+ return TRUE;
+}
+
diff --git a/third-party/libuv/.gitignore b/third-party/libuv/.gitignore
new file mode 100644
index 0000000000..d11c90bbf0
--- /dev/null
+++ b/third-party/libuv/.gitignore
@@ -0,0 +1,62 @@
+*.swp
+*.[oa]
+*.l[oa]
+*.opensdf
+*.orig
+*.pyc
+*.sdf
+*.suo
+core
+vgcore.*
+.buildstamp
+.dirstamp
+.deps/
+/.libs/
+/aclocal.m4
+/ar-lib
+/autom4te.cache/
+/compile
+/config.guess
+/config.log
+/config.status
+/config.sub
+/configure
+/depcomp
+/install-sh
+/libtool
+/libuv.a
+/libuv.dylib
+/libuv.pc
+/libuv.so
+/ltmain.sh
+/missing
+/test-driver
+Makefile
+Makefile.in
+
+# Generated by dtrace(1) when doing an in-tree build.
+/include/uv-dtrace.h
+
+# Generated by gyp for android
+*.target.mk
+
+/out/
+/build/gyp
+
+/run-tests
+/run-tests.exe
+/run-tests.dSYM
+/run-benchmarks
+/run-benchmarks.exe
+/run-benchmarks.dSYM
+
+*.sln
+*.vcproj
+*.vcxproj
+*.vcxproj.filters
+*.vcxproj.user
+_UpgradeReport_Files/
+UpgradeLog*.XML
+Debug
+Release
+ipch
diff --git a/.mailmap b/third-party/libuv/.mailmap
index 0f1d843ce8..0f1d843ce8 100644
--- a/.mailmap
+++ b/third-party/libuv/.mailmap
diff --git a/AUTHORS b/third-party/libuv/AUTHORS
index 6633f0651e..6633f0651e 100644
--- a/AUTHORS
+++ b/third-party/libuv/AUTHORS
diff --git a/CONTRIBUTING.md b/third-party/libuv/CONTRIBUTING.md
index 960a9450ae..960a9450ae 100644
--- a/CONTRIBUTING.md
+++ b/third-party/libuv/CONTRIBUTING.md
diff --git a/ChangeLog b/third-party/libuv/ChangeLog
index ad3cbb504c..ad3cbb504c 100644
--- a/ChangeLog
+++ b/third-party/libuv/ChangeLog
diff --git a/LICENSE b/third-party/libuv/LICENSE
index 8db13acf2c..8db13acf2c 100644
--- a/LICENSE
+++ b/third-party/libuv/LICENSE
diff --git a/Makefile.am b/third-party/libuv/Makefile.am
index c1eae8cea0..c1eae8cea0 100644
--- a/Makefile.am
+++ b/third-party/libuv/Makefile.am
diff --git a/Makefile.mingw b/third-party/libuv/Makefile.mingw
index 28a1e274d5..28a1e274d5 100644
--- a/Makefile.mingw
+++ b/third-party/libuv/Makefile.mingw
diff --git a/third-party/libuv/README.md b/third-party/libuv/README.md
new file mode 100644
index 0000000000..5704c39e27
--- /dev/null
+++ b/third-party/libuv/README.md
@@ -0,0 +1,143 @@
+# libuv
+
+libuv is a multi-platform support library with a focus on asynchronous I/O. It
+was primarily developed for use by [Node.js](http://nodejs.org), but it's also
+used by Mozilla's [Rust language](http://www.rust-lang.org/),
+[Luvit](http://luvit.io/), [Julia](http://julialang.org/),
+[pyuv](https://crate.io/packages/pyuv/), and [others](https://github.com/joyent/libuv/wiki/Projects-that-use-libuv).
+
+## Feature highlights
+
+ * Full-featured event loop backed by epoll, kqueue, IOCP, event ports.
+
+ * Asynchronous TCP and UDP sockets
+
+ * Asynchronous DNS resolution
+
+ * Asynchronous file and file system operations
+
+ * File system events
+
+ * ANSI escape code controlled TTY
+
+ * IPC with socket sharing, using Unix domain sockets or named pipes (Windows)
+
+ * Child processes
+
+ * Thread pool
+
+ * Signal handling
+
+ * High resolution clock
+
+ * Threading and synchronization primitives
+
+
+## Community
+
+ * [Mailing list](http://groups.google.com/group/libuv)
+
+## Documentation
+
+ * [include/uv.h](https://github.com/joyent/libuv/blob/master/include/uv.h)
+ &mdash; API documentation in the form of detailed header comments.
+ * [An Introduction to libuv](http://nikhilm.github.com/uvbook/)
+ &mdash; An overview of libuv with tutorials.
+ * [LXJS 2012 talk](http://www.youtube.com/watch?v=nGn60vDSxQ4)
+ &mdash; High-level introductory talk about libuv.
+ * [Tests and benchmarks](https://github.com/joyent/libuv/tree/master/test)
+ &mdash; API specification and usage examples.
+ * [libuv-dox](https://github.com/thlorenz/libuv-dox)
+ &mdash; Documenting types and methods of libuv, mostly by reading uv.h.
+
+## Build Instructions
+
+For GCC there are two methods building: via autotools or via [GYP][].
+GYP is a meta-build system which can generate MSVS, Makefile, and XCode
+backends. It is best used for integration into other projects.
+
+To build with autotools:
+
+ $ sh autogen.sh
+ $ ./configure
+ $ make
+ $ make check
+ $ make install
+
+### Windows
+
+First, Python 2.6 or 2.7 must be installed as it is required by [GYP][].
+
+Also, the directory for the preferred Python executable must be specified
+by the `PYTHON` or `Path` environment variables.
+
+To build with Visual Studio, launch a git shell (e.g. Cmd or PowerShell)
+and run vcbuild.bat which will checkout the GYP code into build/gyp and
+generate uv.sln as well as related project files.
+
+To have GYP generate build script for another system, checkout GYP into the
+project tree manually:
+
+ $ mkdir -p build
+ $ git clone https://git.chromium.org/external/gyp.git build/gyp
+
+### Unix
+
+Run:
+
+ $ ./gyp_uv.py -f make
+ $ make -C out
+
+### OS X
+
+Run:
+
+ $ ./gyp_uv.py -f xcode
+ $ xcodebuild -ARCHS="x86_64" -project uv.xcodeproj \
+ -configuration Release -target All
+
+Note to OS X users:
+
+Make sure that you specify the architecture you wish to build for in the
+"ARCHS" flag. You can specify more than one by delimiting with a space
+(e.g. "x86_64 i386").
+
+### Android
+
+Run:
+
+ $ source ./android-configure NDK_PATH gyp
+ $ make -C out
+
+Note for UNIX users: compile your project with `-D_LARGEFILE_SOURCE` and
+`-D_FILE_OFFSET_BITS=64`. GYP builds take care of that automatically.
+
+### Running tests
+
+Run:
+
+ $ ./gyp_uv.py -f make
+ $ make -C out
+ $ ./out/Debug/run-tests
+
+## Supported Platforms
+
+Microsoft Windows operating systems since Windows XP SP2. It can be built
+with either Visual Studio or MinGW. Consider using
+[Visual Studio Express 2010][] or later if you do not have a full Visual
+Studio license.
+
+Linux using the GCC toolchain.
+
+OS X using the GCC or XCode toolchain.
+
+Solaris 121 and later using GCC toolchain.
+
+## patches
+
+See the [guidelines for contributing][].
+
+[node.js]: http://nodejs.org/
+[GYP]: http://code.google.com/p/gyp/
+[Visual Studio Express 2010]: http://www.microsoft.com/visualstudio/eng/products/visual-studio-2010-express
+[guidelines for contributing]: https://github.com/joyent/libuv/blob/master/CONTRIBUTING.md
diff --git a/android-configure b/third-party/libuv/android-configure
index 56625761fd..56625761fd 100755
--- a/android-configure
+++ b/third-party/libuv/android-configure
diff --git a/autogen.sh b/third-party/libuv/autogen.sh
index 751b4f5562..751b4f5562 100755
--- a/autogen.sh
+++ b/third-party/libuv/autogen.sh
diff --git a/checksparse.sh b/third-party/libuv/checksparse.sh
index 54cd5805a8..54cd5805a8 100755
--- a/checksparse.sh
+++ b/third-party/libuv/checksparse.sh
diff --git a/common.gypi b/third-party/libuv/common.gypi
index 7adbbbdcc9..7adbbbdcc9 100644
--- a/common.gypi
+++ b/third-party/libuv/common.gypi
diff --git a/configure.ac b/third-party/libuv/configure.ac
index ffa09b45c2..ffa09b45c2 100644
--- a/configure.ac
+++ b/third-party/libuv/configure.ac
diff --git a/gyp_uv.py b/third-party/libuv/gyp_uv.py
index 4ba69167d9..4ba69167d9 100755
--- a/gyp_uv.py
+++ b/third-party/libuv/gyp_uv.py
diff --git a/include/pthread-fixes.h b/third-party/libuv/include/pthread-fixes.h
index 230ce3178d..230ce3178d 100644
--- a/include/pthread-fixes.h
+++ b/third-party/libuv/include/pthread-fixes.h
diff --git a/include/stdint-msvc2008.h b/third-party/libuv/include/stdint-msvc2008.h
index d02608a597..d02608a597 100644
--- a/include/stdint-msvc2008.h
+++ b/third-party/libuv/include/stdint-msvc2008.h
diff --git a/include/tree.h b/third-party/libuv/include/tree.h
index f936416e3d..f936416e3d 100644
--- a/include/tree.h
+++ b/third-party/libuv/include/tree.h
diff --git a/include/uv-bsd.h b/third-party/libuv/include/uv-bsd.h
index 2d72b3d771..2d72b3d771 100644
--- a/include/uv-bsd.h
+++ b/third-party/libuv/include/uv-bsd.h
diff --git a/include/uv-darwin.h b/third-party/libuv/include/uv-darwin.h
index 24bc35b581..24bc35b581 100644
--- a/include/uv-darwin.h
+++ b/third-party/libuv/include/uv-darwin.h
diff --git a/include/uv-errno.h b/third-party/libuv/include/uv-errno.h
index 797bcab93b..797bcab93b 100644
--- a/include/uv-errno.h
+++ b/third-party/libuv/include/uv-errno.h
diff --git a/include/uv-linux.h b/third-party/libuv/include/uv-linux.h
index 62ebfe2a02..62ebfe2a02 100644
--- a/include/uv-linux.h
+++ b/third-party/libuv/include/uv-linux.h
diff --git a/include/uv-sunos.h b/third-party/libuv/include/uv-sunos.h
index 042166424e..042166424e 100644
--- a/include/uv-sunos.h
+++ b/third-party/libuv/include/uv-sunos.h
diff --git a/include/uv-unix.h b/third-party/libuv/include/uv-unix.h
index 45006092be..45006092be 100644
--- a/include/uv-unix.h
+++ b/third-party/libuv/include/uv-unix.h
diff --git a/include/uv-win.h b/third-party/libuv/include/uv-win.h
index e4e1f839f0..e4e1f839f0 100644
--- a/include/uv-win.h
+++ b/third-party/libuv/include/uv-win.h
diff --git a/include/uv.h b/third-party/libuv/include/uv.h
index 4eeade74c4..4eeade74c4 100644
--- a/include/uv.h
+++ b/third-party/libuv/include/uv.h
diff --git a/libuv.pc.in b/third-party/libuv/libuv.pc.in
index 86c1a126cd..86c1a126cd 100644
--- a/libuv.pc.in
+++ b/third-party/libuv/libuv.pc.in
diff --git a/m4/.gitignore b/third-party/libuv/m4/.gitignore
index bde78f43f9..bde78f43f9 100644
--- a/m4/.gitignore
+++ b/third-party/libuv/m4/.gitignore
diff --git a/m4/dtrace.m4 b/third-party/libuv/m4/dtrace.m4
index 4060af3181..4060af3181 100644
--- a/m4/dtrace.m4
+++ b/third-party/libuv/m4/dtrace.m4
diff --git a/samples/.gitignore b/third-party/libuv/samples/.gitignore
index f868091ba3..f868091ba3 100644
--- a/samples/.gitignore
+++ b/third-party/libuv/samples/.gitignore
diff --git a/samples/socks5-proxy/.gitignore b/third-party/libuv/samples/socks5-proxy/.gitignore
index c177f37451..c177f37451 100644
--- a/samples/socks5-proxy/.gitignore
+++ b/third-party/libuv/samples/socks5-proxy/.gitignore
diff --git a/samples/socks5-proxy/LICENSE b/third-party/libuv/samples/socks5-proxy/LICENSE
index 63c1447fc5..63c1447fc5 100644
--- a/samples/socks5-proxy/LICENSE
+++ b/third-party/libuv/samples/socks5-proxy/LICENSE
diff --git a/samples/socks5-proxy/Makefile b/third-party/libuv/samples/socks5-proxy/Makefile
index 268dc55b1a..268dc55b1a 100644
--- a/samples/socks5-proxy/Makefile
+++ b/third-party/libuv/samples/socks5-proxy/Makefile
diff --git a/samples/socks5-proxy/build.gyp b/third-party/libuv/samples/socks5-proxy/build.gyp
index 771a1e146d..771a1e146d 100644
--- a/samples/socks5-proxy/build.gyp
+++ b/third-party/libuv/samples/socks5-proxy/build.gyp
diff --git a/samples/socks5-proxy/client.c b/third-party/libuv/samples/socks5-proxy/client.c
index ae9913a1c6..ae9913a1c6 100644
--- a/samples/socks5-proxy/client.c
+++ b/third-party/libuv/samples/socks5-proxy/client.c
diff --git a/samples/socks5-proxy/defs.h b/third-party/libuv/samples/socks5-proxy/defs.h
index 99ee8160c8..99ee8160c8 100644
--- a/samples/socks5-proxy/defs.h
+++ b/third-party/libuv/samples/socks5-proxy/defs.h
diff --git a/samples/socks5-proxy/getopt.c b/third-party/libuv/samples/socks5-proxy/getopt.c
index 8481b2264f..8481b2264f 100644
--- a/samples/socks5-proxy/getopt.c
+++ b/third-party/libuv/samples/socks5-proxy/getopt.c
diff --git a/samples/socks5-proxy/main.c b/third-party/libuv/samples/socks5-proxy/main.c
index 04020cbd3a..04020cbd3a 100644
--- a/samples/socks5-proxy/main.c
+++ b/third-party/libuv/samples/socks5-proxy/main.c
diff --git a/samples/socks5-proxy/s5.c b/third-party/libuv/samples/socks5-proxy/s5.c
index 4f08e34524..4f08e34524 100644
--- a/samples/socks5-proxy/s5.c
+++ b/third-party/libuv/samples/socks5-proxy/s5.c
diff --git a/samples/socks5-proxy/s5.h b/third-party/libuv/samples/socks5-proxy/s5.h
index 715f322287..715f322287 100644
--- a/samples/socks5-proxy/s5.h
+++ b/third-party/libuv/samples/socks5-proxy/s5.h
diff --git a/samples/socks5-proxy/server.c b/third-party/libuv/samples/socks5-proxy/server.c
index 3f1ba42c9e..3f1ba42c9e 100644
--- a/samples/socks5-proxy/server.c
+++ b/third-party/libuv/samples/socks5-proxy/server.c
diff --git a/samples/socks5-proxy/util.c b/third-party/libuv/samples/socks5-proxy/util.c
index af34f05593..af34f05593 100644
--- a/samples/socks5-proxy/util.c
+++ b/third-party/libuv/samples/socks5-proxy/util.c
diff --git a/src/fs-poll.c b/third-party/libuv/src/fs-poll.c
index 7fdaaeb17a..7fdaaeb17a 100644
--- a/src/fs-poll.c
+++ b/third-party/libuv/src/fs-poll.c
diff --git a/src/inet.c b/third-party/libuv/src/inet.c
index a30c0d1512..a30c0d1512 100644
--- a/src/inet.c
+++ b/third-party/libuv/src/inet.c
diff --git a/src/queue.h b/third-party/libuv/src/queue.h
index fe02b454ea..fe02b454ea 100644
--- a/src/queue.h
+++ b/third-party/libuv/src/queue.h
diff --git a/src/unix/aix.c b/third-party/libuv/src/unix/aix.c
index 2521681305..2521681305 100644
--- a/src/unix/aix.c
+++ b/third-party/libuv/src/unix/aix.c
diff --git a/src/unix/async.c b/third-party/libuv/src/unix/async.c
index 3c23e1d7fd..3c23e1d7fd 100644
--- a/src/unix/async.c
+++ b/third-party/libuv/src/unix/async.c
diff --git a/src/unix/atomic-ops.h b/third-party/libuv/src/unix/atomic-ops.h
index 7e4e64beda..7e4e64beda 100644
--- a/src/unix/atomic-ops.h
+++ b/third-party/libuv/src/unix/atomic-ops.h
diff --git a/src/unix/core.c b/third-party/libuv/src/unix/core.c
index df2a5f8042..df2a5f8042 100644
--- a/src/unix/core.c
+++ b/third-party/libuv/src/unix/core.c
diff --git a/src/unix/darwin-proctitle.c b/third-party/libuv/src/unix/darwin-proctitle.c
index 8cd358bcf0..8cd358bcf0 100644
--- a/src/unix/darwin-proctitle.c
+++ b/third-party/libuv/src/unix/darwin-proctitle.c
diff --git a/src/unix/darwin.c b/third-party/libuv/src/unix/darwin.c
index bc282e7912..bc282e7912 100644
--- a/src/unix/darwin.c
+++ b/third-party/libuv/src/unix/darwin.c
diff --git a/src/unix/dl.c b/third-party/libuv/src/unix/dl.c
index cbffe4aa26..cbffe4aa26 100644
--- a/src/unix/dl.c
+++ b/third-party/libuv/src/unix/dl.c
diff --git a/src/unix/freebsd.c b/third-party/libuv/src/unix/freebsd.c
index dcae244bb1..dcae244bb1 100644
--- a/src/unix/freebsd.c
+++ b/third-party/libuv/src/unix/freebsd.c
diff --git a/src/unix/fs.c b/third-party/libuv/src/unix/fs.c
index 1aa6539cb4..1aa6539cb4 100644
--- a/src/unix/fs.c
+++ b/third-party/libuv/src/unix/fs.c
diff --git a/src/unix/fsevents.c b/third-party/libuv/src/unix/fsevents.c
index 7faa1562a6..7faa1562a6 100644
--- a/src/unix/fsevents.c
+++ b/third-party/libuv/src/unix/fsevents.c
diff --git a/src/unix/getaddrinfo.c b/third-party/libuv/src/unix/getaddrinfo.c
index 1db00680d1..1db00680d1 100644
--- a/src/unix/getaddrinfo.c
+++ b/third-party/libuv/src/unix/getaddrinfo.c
diff --git a/src/unix/internal.h b/third-party/libuv/src/unix/internal.h
index 0ea82b51a0..0ea82b51a0 100644
--- a/src/unix/internal.h
+++ b/third-party/libuv/src/unix/internal.h
diff --git a/src/unix/kqueue.c b/third-party/libuv/src/unix/kqueue.c
index f86f291fc0..f86f291fc0 100644
--- a/src/unix/kqueue.c
+++ b/third-party/libuv/src/unix/kqueue.c
diff --git a/src/unix/linux-core.c b/third-party/libuv/src/unix/linux-core.c
index f71dd2d6b9..f71dd2d6b9 100644
--- a/src/unix/linux-core.c
+++ b/third-party/libuv/src/unix/linux-core.c
diff --git a/src/unix/linux-inotify.c b/third-party/libuv/src/unix/linux-inotify.c
index 7641f383c4..7641f383c4 100644
--- a/src/unix/linux-inotify.c
+++ b/third-party/libuv/src/unix/linux-inotify.c
diff --git a/src/unix/linux-syscalls.c b/third-party/libuv/src/unix/linux-syscalls.c
index 06cc5943cf..06cc5943cf 100644
--- a/src/unix/linux-syscalls.c
+++ b/third-party/libuv/src/unix/linux-syscalls.c
diff --git a/src/unix/linux-syscalls.h b/third-party/libuv/src/unix/linux-syscalls.h
index 1ad9518548..1ad9518548 100644
--- a/src/unix/linux-syscalls.h
+++ b/third-party/libuv/src/unix/linux-syscalls.h
diff --git a/src/unix/loop-watcher.c b/third-party/libuv/src/unix/loop-watcher.c
index dc03c206d2..dc03c206d2 100644
--- a/src/unix/loop-watcher.c
+++ b/third-party/libuv/src/unix/loop-watcher.c
diff --git a/src/unix/loop.c b/third-party/libuv/src/unix/loop.c
index 94a5c03819..94a5c03819 100644
--- a/src/unix/loop.c
+++ b/third-party/libuv/src/unix/loop.c
diff --git a/src/unix/netbsd.c b/third-party/libuv/src/unix/netbsd.c
index 7423a71078..7423a71078 100644
--- a/src/unix/netbsd.c
+++ b/third-party/libuv/src/unix/netbsd.c
diff --git a/src/unix/openbsd.c b/third-party/libuv/src/unix/openbsd.c
index f052d80c57..f052d80c57 100644
--- a/src/unix/openbsd.c
+++ b/third-party/libuv/src/unix/openbsd.c
diff --git a/src/unix/pipe.c b/third-party/libuv/src/unix/pipe.c
index fd4afb6370..fd4afb6370 100644
--- a/src/unix/pipe.c
+++ b/third-party/libuv/src/unix/pipe.c
diff --git a/src/unix/poll.c b/third-party/libuv/src/unix/poll.c
index a34a8d1e14..a34a8d1e14 100644
--- a/src/unix/poll.c
+++ b/third-party/libuv/src/unix/poll.c
diff --git a/src/unix/process.c b/third-party/libuv/src/unix/process.c
index 6f96b754d8..6f96b754d8 100644
--- a/src/unix/process.c
+++ b/third-party/libuv/src/unix/process.c
diff --git a/src/unix/proctitle.c b/third-party/libuv/src/unix/proctitle.c
index 16b0523731..16b0523731 100644
--- a/src/unix/proctitle.c
+++ b/third-party/libuv/src/unix/proctitle.c
diff --git a/src/unix/pthread-fixes.c b/third-party/libuv/src/unix/pthread-fixes.c
index 2e4c542bc2..2e4c542bc2 100644
--- a/src/unix/pthread-fixes.c
+++ b/third-party/libuv/src/unix/pthread-fixes.c
diff --git a/src/unix/signal.c b/third-party/libuv/src/unix/signal.c
index 0b7a405c15..0b7a405c15 100644
--- a/src/unix/signal.c
+++ b/third-party/libuv/src/unix/signal.c
diff --git a/src/unix/spinlock.h b/third-party/libuv/src/unix/spinlock.h
index a20c83cc60..a20c83cc60 100644
--- a/src/unix/spinlock.h
+++ b/third-party/libuv/src/unix/spinlock.h
diff --git a/src/unix/stream.c b/third-party/libuv/src/unix/stream.c
index 9f5d40cf4b..9f5d40cf4b 100644
--- a/src/unix/stream.c
+++ b/third-party/libuv/src/unix/stream.c
diff --git a/src/unix/sunos.c b/third-party/libuv/src/unix/sunos.c
index f31a23fb3c..f31a23fb3c 100644
--- a/src/unix/sunos.c
+++ b/third-party/libuv/src/unix/sunos.c
diff --git a/src/unix/tcp.c b/third-party/libuv/src/unix/tcp.c
index 2c36dc3ffc..2c36dc3ffc 100644
--- a/src/unix/tcp.c
+++ b/third-party/libuv/src/unix/tcp.c
diff --git a/src/unix/thread.c b/third-party/libuv/src/unix/thread.c
index f2ce082842..f2ce082842 100644
--- a/src/unix/thread.c
+++ b/third-party/libuv/src/unix/thread.c
diff --git a/src/unix/threadpool.c b/third-party/libuv/src/unix/threadpool.c
index 7923250a09..7923250a09 100644
--- a/src/unix/threadpool.c
+++ b/third-party/libuv/src/unix/threadpool.c
diff --git a/src/unix/timer.c b/third-party/libuv/src/unix/timer.c
index 240efad503..240efad503 100644
--- a/src/unix/timer.c
+++ b/third-party/libuv/src/unix/timer.c
diff --git a/src/unix/tty.c b/third-party/libuv/src/unix/tty.c
index ca9459dd0d..ca9459dd0d 100644
--- a/src/unix/tty.c
+++ b/third-party/libuv/src/unix/tty.c
diff --git a/src/unix/udp.c b/third-party/libuv/src/unix/udp.c
index a2b3dc3298..a2b3dc3298 100644
--- a/src/unix/udp.c
+++ b/third-party/libuv/src/unix/udp.c
diff --git a/src/unix/uv-dtrace.d b/third-party/libuv/src/unix/uv-dtrace.d
index 7848450c94..7848450c94 100644
--- a/src/unix/uv-dtrace.d
+++ b/third-party/libuv/src/unix/uv-dtrace.d
diff --git a/src/uv-common.c b/third-party/libuv/src/uv-common.c
index e5fc507756..e5fc507756 100644
--- a/src/uv-common.c
+++ b/third-party/libuv/src/uv-common.c
diff --git a/src/uv-common.h b/third-party/libuv/src/uv-common.h
index 3bcdcef3d4..3bcdcef3d4 100644
--- a/src/uv-common.h
+++ b/third-party/libuv/src/uv-common.h
diff --git a/third-party/libuv/src/version.c b/third-party/libuv/src/version.c
new file mode 100644
index 0000000000..0636348dae
--- /dev/null
+++ b/third-party/libuv/src/version.c
@@ -0,0 +1,63 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include "uv.h"
+
+ /*
+ * Versions with an even minor version (e.g. 0.6.1 or 1.0.4) are API and ABI
+ * stable. When the minor version is odd, the API can change between patch
+ * releases. Make sure you update the -soname directives in config-unix.mk
+ * and uv.gyp whenever you bump UV_VERSION_MAJOR or UV_VERSION_MINOR (but
+ * not UV_VERSION_PATCH.)
+ */
+
+#define UV_VERSION_MAJOR 0
+#define UV_VERSION_MINOR 11
+#define UV_VERSION_PATCH 19
+#define UV_VERSION_IS_RELEASE 1
+
+
+#define UV_VERSION ((UV_VERSION_MAJOR << 16) | \
+ (UV_VERSION_MINOR << 8) | \
+ (UV_VERSION_PATCH))
+
+#define UV_STRINGIFY(v) UV_STRINGIFY_HELPER(v)
+#define UV_STRINGIFY_HELPER(v) #v
+
+#define UV_VERSION_STRING_BASE UV_STRINGIFY(UV_VERSION_MAJOR) "." \
+ UV_STRINGIFY(UV_VERSION_MINOR) "." \
+ UV_STRINGIFY(UV_VERSION_PATCH)
+
+#if UV_VERSION_IS_RELEASE
+# define UV_VERSION_STRING UV_VERSION_STRING_BASE
+#else
+# define UV_VERSION_STRING UV_VERSION_STRING_BASE "-pre"
+#endif
+
+
+unsigned int uv_version(void) {
+ return UV_VERSION;
+}
+
+
+const char* uv_version_string(void) {
+ return UV_VERSION_STRING;
+}
diff --git a/src/win/async.c b/third-party/libuv/src/win/async.c
index e192ead90d..e192ead90d 100644
--- a/src/win/async.c
+++ b/third-party/libuv/src/win/async.c
diff --git a/src/win/atomicops-inl.h b/third-party/libuv/src/win/atomicops-inl.h
index 61e006026c..61e006026c 100644
--- a/src/win/atomicops-inl.h
+++ b/third-party/libuv/src/win/atomicops-inl.h
diff --git a/src/win/core.c b/third-party/libuv/src/win/core.c
index e1a77655ac..e1a77655ac 100644
--- a/src/win/core.c
+++ b/third-party/libuv/src/win/core.c
diff --git a/src/win/dl.c b/third-party/libuv/src/win/dl.c
index d5b8f7c7d3..d5b8f7c7d3 100644
--- a/src/win/dl.c
+++ b/third-party/libuv/src/win/dl.c
diff --git a/src/win/error.c b/third-party/libuv/src/win/error.c
index 3162bc787f..3162bc787f 100644
--- a/src/win/error.c
+++ b/third-party/libuv/src/win/error.c
diff --git a/src/win/fs-event.c b/third-party/libuv/src/win/fs-event.c
index 6132b79c82..6132b79c82 100644
--- a/src/win/fs-event.c
+++ b/third-party/libuv/src/win/fs-event.c
diff --git a/src/win/fs.c b/third-party/libuv/src/win/fs.c
index c4182758c7..c4182758c7 100644
--- a/src/win/fs.c
+++ b/third-party/libuv/src/win/fs.c
diff --git a/src/win/getaddrinfo.c b/third-party/libuv/src/win/getaddrinfo.c
index fb4ab0a602..fb4ab0a602 100644
--- a/src/win/getaddrinfo.c
+++ b/third-party/libuv/src/win/getaddrinfo.c
diff --git a/src/win/handle-inl.h b/third-party/libuv/src/win/handle-inl.h
index 5776eb7f76..5776eb7f76 100644
--- a/src/win/handle-inl.h
+++ b/third-party/libuv/src/win/handle-inl.h
diff --git a/src/win/handle.c b/third-party/libuv/src/win/handle.c
index 72b49d9790..72b49d9790 100644
--- a/src/win/handle.c
+++ b/third-party/libuv/src/win/handle.c
diff --git a/src/win/internal.h b/third-party/libuv/src/win/internal.h
index cf6c85846c..cf6c85846c 100644
--- a/src/win/internal.h
+++ b/third-party/libuv/src/win/internal.h
diff --git a/src/win/loop-watcher.c b/third-party/libuv/src/win/loop-watcher.c
index 6dbc861edd..6dbc861edd 100644
--- a/src/win/loop-watcher.c
+++ b/third-party/libuv/src/win/loop-watcher.c
diff --git a/src/win/pipe.c b/third-party/libuv/src/win/pipe.c
index f3d3110d31..f3d3110d31 100644
--- a/src/win/pipe.c
+++ b/third-party/libuv/src/win/pipe.c
diff --git a/src/win/poll.c b/third-party/libuv/src/win/poll.c
index 75351afd75..75351afd75 100644
--- a/src/win/poll.c
+++ b/third-party/libuv/src/win/poll.c
diff --git a/src/win/process-stdio.c b/third-party/libuv/src/win/process-stdio.c
index 5757764bfd..5757764bfd 100644
--- a/src/win/process-stdio.c
+++ b/third-party/libuv/src/win/process-stdio.c
diff --git a/src/win/process.c b/third-party/libuv/src/win/process.c
index 813e522f75..813e522f75 100644
--- a/src/win/process.c
+++ b/third-party/libuv/src/win/process.c
diff --git a/src/win/req-inl.h b/third-party/libuv/src/win/req-inl.h
index 353fe90b6d..353fe90b6d 100644
--- a/src/win/req-inl.h
+++ b/third-party/libuv/src/win/req-inl.h
diff --git a/src/win/req.c b/third-party/libuv/src/win/req.c
index 111cc5e289..111cc5e289 100644
--- a/src/win/req.c
+++ b/third-party/libuv/src/win/req.c
diff --git a/src/win/signal.c b/third-party/libuv/src/win/signal.c
index 9dc5fccc29..9dc5fccc29 100644
--- a/src/win/signal.c
+++ b/third-party/libuv/src/win/signal.c
diff --git a/src/win/stream-inl.h b/third-party/libuv/src/win/stream-inl.h
index e4bf086368..e4bf086368 100644
--- a/src/win/stream-inl.h
+++ b/third-party/libuv/src/win/stream-inl.h
diff --git a/src/win/stream.c b/third-party/libuv/src/win/stream.c
index 2eaa74e766..2eaa74e766 100644
--- a/src/win/stream.c
+++ b/third-party/libuv/src/win/stream.c
diff --git a/src/win/tcp.c b/third-party/libuv/src/win/tcp.c
index 8fa2146a06..8fa2146a06 100644
--- a/src/win/tcp.c
+++ b/third-party/libuv/src/win/tcp.c
diff --git a/src/win/thread.c b/third-party/libuv/src/win/thread.c
index 5178f8f9ab..5178f8f9ab 100644
--- a/src/win/thread.c
+++ b/third-party/libuv/src/win/thread.c
diff --git a/src/win/threadpool.c b/third-party/libuv/src/win/threadpool.c
index 9539844c66..9539844c66 100644
--- a/src/win/threadpool.c
+++ b/third-party/libuv/src/win/threadpool.c
diff --git a/src/win/timer.c b/third-party/libuv/src/win/timer.c
index 6c53ea37e0..6c53ea37e0 100644
--- a/src/win/timer.c
+++ b/third-party/libuv/src/win/timer.c
diff --git a/src/win/tty.c b/third-party/libuv/src/win/tty.c
index 8855af350e..8855af350e 100644
--- a/src/win/tty.c
+++ b/third-party/libuv/src/win/tty.c
diff --git a/src/win/udp.c b/third-party/libuv/src/win/udp.c
index 31812e4642..31812e4642 100644
--- a/src/win/udp.c
+++ b/third-party/libuv/src/win/udp.c
diff --git a/src/win/util.c b/third-party/libuv/src/win/util.c
index 266b881640..266b881640 100644
--- a/src/win/util.c
+++ b/third-party/libuv/src/win/util.c
diff --git a/src/win/winapi.c b/third-party/libuv/src/win/winapi.c
index 3e439ea5b2..3e439ea5b2 100644
--- a/src/win/winapi.c
+++ b/third-party/libuv/src/win/winapi.c
diff --git a/src/win/winapi.h b/third-party/libuv/src/win/winapi.h
index 21d7fe4ac3..21d7fe4ac3 100644
--- a/src/win/winapi.h
+++ b/third-party/libuv/src/win/winapi.h
diff --git a/src/win/winsock.c b/third-party/libuv/src/win/winsock.c
index 938b6d031a..938b6d031a 100644
--- a/src/win/winsock.c
+++ b/third-party/libuv/src/win/winsock.c
diff --git a/src/win/winsock.h b/third-party/libuv/src/win/winsock.h
index 957d08ec19..957d08ec19 100644
--- a/src/win/winsock.h
+++ b/third-party/libuv/src/win/winsock.h
diff --git a/test/benchmark-async-pummel.c b/third-party/libuv/test/benchmark-async-pummel.c
index 4761c1928e..4761c1928e 100644
--- a/test/benchmark-async-pummel.c
+++ b/third-party/libuv/test/benchmark-async-pummel.c
diff --git a/test/benchmark-async.c b/third-party/libuv/test/benchmark-async.c
index 33d9ab446a..33d9ab446a 100644
--- a/test/benchmark-async.c
+++ b/third-party/libuv/test/benchmark-async.c
diff --git a/test/benchmark-fs-stat.c b/third-party/libuv/test/benchmark-fs-stat.c
index 5c87de0043..5c87de0043 100644
--- a/test/benchmark-fs-stat.c
+++ b/third-party/libuv/test/benchmark-fs-stat.c
diff --git a/test/benchmark-getaddrinfo.c b/third-party/libuv/test/benchmark-getaddrinfo.c
index c7f99a2fcb..c7f99a2fcb 100644
--- a/test/benchmark-getaddrinfo.c
+++ b/third-party/libuv/test/benchmark-getaddrinfo.c
diff --git a/test/benchmark-list.h b/third-party/libuv/test/benchmark-list.h
index 1e843071c0..1e843071c0 100644
--- a/test/benchmark-list.h
+++ b/third-party/libuv/test/benchmark-list.h
diff --git a/test/benchmark-loop-count.c b/third-party/libuv/test/benchmark-loop-count.c
index b4ee0ed5ff..b4ee0ed5ff 100644
--- a/test/benchmark-loop-count.c
+++ b/third-party/libuv/test/benchmark-loop-count.c
diff --git a/test/benchmark-million-async.c b/third-party/libuv/test/benchmark-million-async.c
index 69cc803436..69cc803436 100644
--- a/test/benchmark-million-async.c
+++ b/third-party/libuv/test/benchmark-million-async.c
diff --git a/test/benchmark-million-timers.c b/third-party/libuv/test/benchmark-million-timers.c
index 64f4a1038e..64f4a1038e 100644
--- a/test/benchmark-million-timers.c
+++ b/third-party/libuv/test/benchmark-million-timers.c
diff --git a/test/benchmark-multi-accept.c b/third-party/libuv/test/benchmark-multi-accept.c
index d71235ef3b..d71235ef3b 100644
--- a/test/benchmark-multi-accept.c
+++ b/third-party/libuv/test/benchmark-multi-accept.c
diff --git a/test/benchmark-ping-pongs.c b/third-party/libuv/test/benchmark-ping-pongs.c
index bb560d7d21..bb560d7d21 100644
--- a/test/benchmark-ping-pongs.c
+++ b/third-party/libuv/test/benchmark-ping-pongs.c
diff --git a/test/benchmark-pound.c b/third-party/libuv/test/benchmark-pound.c
index 587928549e..587928549e 100644
--- a/test/benchmark-pound.c
+++ b/third-party/libuv/test/benchmark-pound.c
diff --git a/test/benchmark-pump.c b/third-party/libuv/test/benchmark-pump.c
index 678634ff71..678634ff71 100644
--- a/test/benchmark-pump.c
+++ b/third-party/libuv/test/benchmark-pump.c
diff --git a/test/benchmark-sizes.c b/third-party/libuv/test/benchmark-sizes.c
index 8ccf10ee47..8ccf10ee47 100644
--- a/test/benchmark-sizes.c
+++ b/third-party/libuv/test/benchmark-sizes.c
diff --git a/test/benchmark-spawn.c b/third-party/libuv/test/benchmark-spawn.c
index 9cae41a83a..9cae41a83a 100644
--- a/test/benchmark-spawn.c
+++ b/third-party/libuv/test/benchmark-spawn.c
diff --git a/test/benchmark-tcp-write-batch.c b/third-party/libuv/test/benchmark-tcp-write-batch.c
index 96921b70db..96921b70db 100644
--- a/test/benchmark-tcp-write-batch.c
+++ b/third-party/libuv/test/benchmark-tcp-write-batch.c
diff --git a/test/benchmark-thread.c b/third-party/libuv/test/benchmark-thread.c
index b37a7fd6d0..b37a7fd6d0 100644
--- a/test/benchmark-thread.c
+++ b/third-party/libuv/test/benchmark-thread.c
diff --git a/test/benchmark-udp-pummel.c b/third-party/libuv/test/benchmark-udp-pummel.c
index d99250affc..d99250affc 100644
--- a/test/benchmark-udp-pummel.c
+++ b/third-party/libuv/test/benchmark-udp-pummel.c
diff --git a/test/blackhole-server.c b/third-party/libuv/test/blackhole-server.c
index ad878b35c6..ad878b35c6 100644
--- a/test/blackhole-server.c
+++ b/third-party/libuv/test/blackhole-server.c
diff --git a/test/dns-server.c b/third-party/libuv/test/dns-server.c
index 80052c7039..80052c7039 100644
--- a/test/dns-server.c
+++ b/third-party/libuv/test/dns-server.c
diff --git a/test/echo-server.c b/third-party/libuv/test/echo-server.c
index e5201b9f4c..e5201b9f4c 100644
--- a/test/echo-server.c
+++ b/third-party/libuv/test/echo-server.c
diff --git a/test/fixtures/empty_file b/third-party/libuv/test/fixtures/empty_file
index e69de29bb2..e69de29bb2 100644
--- a/test/fixtures/empty_file
+++ b/third-party/libuv/test/fixtures/empty_file
diff --git a/test/fixtures/load_error.node b/third-party/libuv/test/fixtures/load_error.node
index 323fae03f4..323fae03f4 100644
--- a/test/fixtures/load_error.node
+++ b/third-party/libuv/test/fixtures/load_error.node
diff --git a/test/run-benchmarks.c b/third-party/libuv/test/run-benchmarks.c
index 06732b71d3..06732b71d3 100644
--- a/test/run-benchmarks.c
+++ b/third-party/libuv/test/run-benchmarks.c
diff --git a/test/run-tests.c b/third-party/libuv/test/run-tests.c
index d84be6a1a5..d84be6a1a5 100644
--- a/test/run-tests.c
+++ b/third-party/libuv/test/run-tests.c
diff --git a/test/runner-unix.c b/third-party/libuv/test/runner-unix.c
index 9afcd1e488..9afcd1e488 100644
--- a/test/runner-unix.c
+++ b/third-party/libuv/test/runner-unix.c
diff --git a/test/runner-unix.h b/third-party/libuv/test/runner-unix.h
index e21847f92c..e21847f92c 100644
--- a/test/runner-unix.h
+++ b/third-party/libuv/test/runner-unix.h
diff --git a/test/runner-win.c b/third-party/libuv/test/runner-win.c
index 83d76783f6..83d76783f6 100644
--- a/test/runner-win.c
+++ b/third-party/libuv/test/runner-win.c
diff --git a/test/runner-win.h b/third-party/libuv/test/runner-win.h
index c94b89bd5e..c94b89bd5e 100644
--- a/test/runner-win.h
+++ b/third-party/libuv/test/runner-win.h
diff --git a/test/runner.c b/third-party/libuv/test/runner.c
index f4d982c5b6..f4d982c5b6 100644
--- a/test/runner.c
+++ b/third-party/libuv/test/runner.c
diff --git a/test/runner.h b/third-party/libuv/test/runner.h
index aa7f205407..aa7f205407 100644
--- a/test/runner.h
+++ b/third-party/libuv/test/runner.h
diff --git a/test/task.h b/third-party/libuv/test/task.h
index b736c375c7..b736c375c7 100644
--- a/test/task.h
+++ b/third-party/libuv/test/task.h
diff --git a/test/test-active.c b/third-party/libuv/test/test-active.c
index 0fae23cdb1..0fae23cdb1 100644
--- a/test/test-active.c
+++ b/third-party/libuv/test/test-active.c
diff --git a/test/test-async-null-cb.c b/third-party/libuv/test/test-async-null-cb.c
index d654884268..d654884268 100644
--- a/test/test-async-null-cb.c
+++ b/third-party/libuv/test/test-async-null-cb.c
diff --git a/test/test-async.c b/third-party/libuv/test/test-async.c
index d4d94d5fa0..d4d94d5fa0 100644
--- a/test/test-async.c
+++ b/third-party/libuv/test/test-async.c
diff --git a/test/test-barrier.c b/third-party/libuv/test/test-barrier.c
index 97df704c0e..97df704c0e 100644
--- a/test/test-barrier.c
+++ b/third-party/libuv/test/test-barrier.c
diff --git a/test/test-callback-order.c b/third-party/libuv/test/test-callback-order.c
index 84231e1b6b..84231e1b6b 100644
--- a/test/test-callback-order.c
+++ b/third-party/libuv/test/test-callback-order.c
diff --git a/test/test-callback-stack.c b/third-party/libuv/test/test-callback-stack.c
index accd549697..accd549697 100644
--- a/test/test-callback-stack.c
+++ b/third-party/libuv/test/test-callback-stack.c
diff --git a/test/test-close-fd.c b/third-party/libuv/test/test-close-fd.c
index 0d17f07661..0d17f07661 100644
--- a/test/test-close-fd.c
+++ b/third-party/libuv/test/test-close-fd.c
diff --git a/test/test-close-order.c b/third-party/libuv/test/test-close-order.c
index e2f25f987d..e2f25f987d 100644
--- a/test/test-close-order.c
+++ b/third-party/libuv/test/test-close-order.c
diff --git a/test/test-condvar.c b/third-party/libuv/test/test-condvar.c
index dbacdba384..dbacdba384 100644
--- a/test/test-condvar.c
+++ b/third-party/libuv/test/test-condvar.c
diff --git a/test/test-connection-fail.c b/third-party/libuv/test/test-connection-fail.c
index 5700140130..5700140130 100644
--- a/test/test-connection-fail.c
+++ b/third-party/libuv/test/test-connection-fail.c
diff --git a/test/test-cwd-and-chdir.c b/third-party/libuv/test/test-cwd-and-chdir.c
index f1082ac47f..f1082ac47f 100644
--- a/test/test-cwd-and-chdir.c
+++ b/third-party/libuv/test/test-cwd-and-chdir.c
diff --git a/test/test-delayed-accept.c b/third-party/libuv/test/test-delayed-accept.c
index b45100d625..b45100d625 100644
--- a/test/test-delayed-accept.c
+++ b/third-party/libuv/test/test-delayed-accept.c
diff --git a/test/test-dlerror.c b/third-party/libuv/test/test-dlerror.c
index 877ebf3712..877ebf3712 100644
--- a/test/test-dlerror.c
+++ b/third-party/libuv/test/test-dlerror.c
diff --git a/test/test-embed.c b/third-party/libuv/test/test-embed.c
index ac1b3b6750..ac1b3b6750 100644
--- a/test/test-embed.c
+++ b/third-party/libuv/test/test-embed.c
diff --git a/test/test-emfile.c b/third-party/libuv/test/test-emfile.c
index 453bfe4cf5..453bfe4cf5 100644
--- a/test/test-emfile.c
+++ b/third-party/libuv/test/test-emfile.c
diff --git a/test/test-error.c b/third-party/libuv/test/test-error.c
index eb337e66f3..eb337e66f3 100644
--- a/test/test-error.c
+++ b/third-party/libuv/test/test-error.c
diff --git a/test/test-fail-always.c b/third-party/libuv/test/test-fail-always.c
index 0008459eac..0008459eac 100644
--- a/test/test-fail-always.c
+++ b/third-party/libuv/test/test-fail-always.c
diff --git a/test/test-fs-event.c b/third-party/libuv/test/test-fs-event.c
index 3286de51f9..3286de51f9 100644
--- a/test/test-fs-event.c
+++ b/third-party/libuv/test/test-fs-event.c
diff --git a/test/test-fs-poll.c b/third-party/libuv/test/test-fs-poll.c
index 9213f04b34..9213f04b34 100644
--- a/test/test-fs-poll.c
+++ b/third-party/libuv/test/test-fs-poll.c
diff --git a/test/test-fs.c b/third-party/libuv/test/test-fs.c
index f0ff824f40..f0ff824f40 100644
--- a/test/test-fs.c
+++ b/third-party/libuv/test/test-fs.c
diff --git a/test/test-get-currentexe.c b/third-party/libuv/test/test-get-currentexe.c
index be578db75d..be578db75d 100644
--- a/test/test-get-currentexe.c
+++ b/third-party/libuv/test/test-get-currentexe.c
diff --git a/test/test-get-loadavg.c b/third-party/libuv/test/test-get-loadavg.c
index 7465e18b91..7465e18b91 100644
--- a/test/test-get-loadavg.c
+++ b/third-party/libuv/test/test-get-loadavg.c
diff --git a/test/test-get-memory.c b/third-party/libuv/test/test-get-memory.c
index 2396939bcb..2396939bcb 100644
--- a/test/test-get-memory.c
+++ b/third-party/libuv/test/test-get-memory.c
diff --git a/test/test-getaddrinfo.c b/third-party/libuv/test/test-getaddrinfo.c
index bca2a6bd70..bca2a6bd70 100644
--- a/test/test-getaddrinfo.c
+++ b/third-party/libuv/test/test-getaddrinfo.c
diff --git a/test/test-getsockname.c b/third-party/libuv/test/test-getsockname.c
index a67d967f0b..a67d967f0b 100644
--- a/test/test-getsockname.c
+++ b/third-party/libuv/test/test-getsockname.c
diff --git a/test/test-hrtime.c b/third-party/libuv/test/test-hrtime.c
index 72a4d4b181..72a4d4b181 100644
--- a/test/test-hrtime.c
+++ b/third-party/libuv/test/test-hrtime.c
diff --git a/test/test-idle.c b/third-party/libuv/test/test-idle.c
index 7eea1b83b1..7eea1b83b1 100644
--- a/test/test-idle.c
+++ b/third-party/libuv/test/test-idle.c
diff --git a/test/test-ip4-addr.c b/third-party/libuv/test/test-ip4-addr.c
index 3d6e0cf286..3d6e0cf286 100644
--- a/test/test-ip4-addr.c
+++ b/third-party/libuv/test/test-ip4-addr.c
diff --git a/test/test-ip6-addr.c b/third-party/libuv/test/test-ip6-addr.c
index ddd0812285..ddd0812285 100644
--- a/test/test-ip6-addr.c
+++ b/third-party/libuv/test/test-ip6-addr.c
diff --git a/test/test-ipc-send-recv.c b/third-party/libuv/test/test-ipc-send-recv.c
index b2b5aa0e92..b2b5aa0e92 100644
--- a/test/test-ipc-send-recv.c
+++ b/third-party/libuv/test/test-ipc-send-recv.c
diff --git a/test/test-ipc.c b/third-party/libuv/test/test-ipc.c
index cc44d32e28..cc44d32e28 100644
--- a/test/test-ipc.c
+++ b/third-party/libuv/test/test-ipc.c
diff --git a/test/test-list.h b/third-party/libuv/test/test-list.h
index c3e15783b5..c3e15783b5 100644
--- a/test/test-list.h
+++ b/third-party/libuv/test/test-list.h
diff --git a/test/test-loop-alive.c b/third-party/libuv/test/test-loop-alive.c
index 89243357c3..89243357c3 100644
--- a/test/test-loop-alive.c
+++ b/third-party/libuv/test/test-loop-alive.c
diff --git a/test/test-loop-handles.c b/third-party/libuv/test/test-loop-handles.c
index fdf9281478..fdf9281478 100644
--- a/test/test-loop-handles.c
+++ b/third-party/libuv/test/test-loop-handles.c
diff --git a/test/test-loop-stop.c b/third-party/libuv/test/test-loop-stop.c
index c519644ed2..c519644ed2 100644
--- a/test/test-loop-stop.c
+++ b/third-party/libuv/test/test-loop-stop.c
diff --git a/test/test-loop-time.c b/third-party/libuv/test/test-loop-time.c
index 49dc79b2c3..49dc79b2c3 100644
--- a/test/test-loop-time.c
+++ b/third-party/libuv/test/test-loop-time.c
diff --git a/test/test-multiple-listen.c b/third-party/libuv/test/test-multiple-listen.c
index 4ae5fa67b3..4ae5fa67b3 100644
--- a/test/test-multiple-listen.c
+++ b/third-party/libuv/test/test-multiple-listen.c
diff --git a/test/test-mutexes.c b/third-party/libuv/test/test-mutexes.c
index 896f46bbed..896f46bbed 100644
--- a/test/test-mutexes.c
+++ b/third-party/libuv/test/test-mutexes.c
diff --git a/test/test-osx-select.c b/third-party/libuv/test/test-osx-select.c
index e5e1bf8b46..e5e1bf8b46 100644
--- a/test/test-osx-select.c
+++ b/third-party/libuv/test/test-osx-select.c
diff --git a/test/test-pass-always.c b/third-party/libuv/test/test-pass-always.c
index 4fb58ff94b..4fb58ff94b 100644
--- a/test/test-pass-always.c
+++ b/third-party/libuv/test/test-pass-always.c
diff --git a/test/test-ping-pong.c b/third-party/libuv/test/test-ping-pong.c
index c579fdd668..c579fdd668 100644
--- a/test/test-ping-pong.c
+++ b/third-party/libuv/test/test-ping-pong.c
diff --git a/test/test-pipe-bind-error.c b/third-party/libuv/test/test-pipe-bind-error.c
index 38b57db699..38b57db699 100644
--- a/test/test-pipe-bind-error.c
+++ b/third-party/libuv/test/test-pipe-bind-error.c
diff --git a/test/test-pipe-connect-error.c b/third-party/libuv/test/test-pipe-connect-error.c
index ebb2a6ca82..ebb2a6ca82 100644
--- a/test/test-pipe-connect-error.c
+++ b/third-party/libuv/test/test-pipe-connect-error.c
diff --git a/test/test-pipe-server-close.c b/third-party/libuv/test/test-pipe-server-close.c
index 1dcdfffaf7..1dcdfffaf7 100644
--- a/test/test-pipe-server-close.c
+++ b/third-party/libuv/test/test-pipe-server-close.c
diff --git a/test/test-platform-output.c b/third-party/libuv/test/test-platform-output.c
index d2104f40a1..d2104f40a1 100644
--- a/test/test-platform-output.c
+++ b/third-party/libuv/test/test-platform-output.c
diff --git a/test/test-poll-close.c b/third-party/libuv/test/test-poll-close.c
index 2eccddf5b0..2eccddf5b0 100644
--- a/test/test-poll-close.c
+++ b/third-party/libuv/test/test-poll-close.c
diff --git a/test/test-poll.c b/third-party/libuv/test/test-poll.c
index 0736b9b0bf..0736b9b0bf 100644
--- a/test/test-poll.c
+++ b/third-party/libuv/test/test-poll.c
diff --git a/test/test-process-title.c b/third-party/libuv/test/test-process-title.c
index 29be20749b..29be20749b 100644
--- a/test/test-process-title.c
+++ b/third-party/libuv/test/test-process-title.c
diff --git a/test/test-ref.c b/third-party/libuv/test/test-ref.c
index 7ff2e84e38..7ff2e84e38 100644
--- a/test/test-ref.c
+++ b/third-party/libuv/test/test-ref.c
diff --git a/test/test-run-nowait.c b/third-party/libuv/test/test-run-nowait.c
index ee4b36ff3b..ee4b36ff3b 100644
--- a/test/test-run-nowait.c
+++ b/third-party/libuv/test/test-run-nowait.c
diff --git a/test/test-run-once.c b/third-party/libuv/test/test-run-once.c
index e243de0ade..e243de0ade 100644
--- a/test/test-run-once.c
+++ b/third-party/libuv/test/test-run-once.c
diff --git a/test/test-semaphore.c b/third-party/libuv/test/test-semaphore.c
index ac03bb08f1..ac03bb08f1 100644
--- a/test/test-semaphore.c
+++ b/third-party/libuv/test/test-semaphore.c
diff --git a/test/test-shutdown-close.c b/third-party/libuv/test/test-shutdown-close.c
index 78c369be2d..78c369be2d 100644
--- a/test/test-shutdown-close.c
+++ b/third-party/libuv/test/test-shutdown-close.c
diff --git a/test/test-shutdown-eof.c b/third-party/libuv/test/test-shutdown-eof.c
index 58346361c7..58346361c7 100644
--- a/test/test-shutdown-eof.c
+++ b/third-party/libuv/test/test-shutdown-eof.c
diff --git a/test/test-signal-multiple-loops.c b/third-party/libuv/test/test-signal-multiple-loops.c
index e80154e3e8..e80154e3e8 100644
--- a/test/test-signal-multiple-loops.c
+++ b/third-party/libuv/test/test-signal-multiple-loops.c
diff --git a/test/test-signal.c b/third-party/libuv/test/test-signal.c
index 9fb1c7f916..9fb1c7f916 100644
--- a/test/test-signal.c
+++ b/third-party/libuv/test/test-signal.c
diff --git a/test/test-spawn.c b/third-party/libuv/test/test-spawn.c
index 5f71fce2c0..5f71fce2c0 100644
--- a/test/test-spawn.c
+++ b/third-party/libuv/test/test-spawn.c
diff --git a/test/test-stdio-over-pipes.c b/third-party/libuv/test/test-stdio-over-pipes.c
index 1574476104..1574476104 100644
--- a/test/test-stdio-over-pipes.c
+++ b/third-party/libuv/test/test-stdio-over-pipes.c
diff --git a/test/test-tcp-bind-error.c b/third-party/libuv/test/test-tcp-bind-error.c
index 96bfe11601..96bfe11601 100644
--- a/test/test-tcp-bind-error.c
+++ b/third-party/libuv/test/test-tcp-bind-error.c
diff --git a/test/test-tcp-bind6-error.c b/third-party/libuv/test/test-tcp-bind6-error.c
index 1d65f3de3e..1d65f3de3e 100644
--- a/test/test-tcp-bind6-error.c
+++ b/third-party/libuv/test/test-tcp-bind6-error.c
diff --git a/test/test-tcp-close-accept.c b/third-party/libuv/test/test-tcp-close-accept.c
index 10f9d91964..10f9d91964 100644
--- a/test/test-tcp-close-accept.c
+++ b/third-party/libuv/test/test-tcp-close-accept.c
diff --git a/test/test-tcp-close-while-connecting.c b/third-party/libuv/test/test-tcp-close-while-connecting.c
index b9f7f9661c..b9f7f9661c 100644
--- a/test/test-tcp-close-while-connecting.c
+++ b/third-party/libuv/test/test-tcp-close-while-connecting.c
diff --git a/test/test-tcp-close.c b/third-party/libuv/test/test-tcp-close.c
index e65885aa55..e65885aa55 100644
--- a/test/test-tcp-close.c
+++ b/third-party/libuv/test/test-tcp-close.c
diff --git a/test/test-tcp-connect-error-after-write.c b/third-party/libuv/test/test-tcp-connect-error-after-write.c
index 3f2e3572da..3f2e3572da 100644
--- a/test/test-tcp-connect-error-after-write.c
+++ b/third-party/libuv/test/test-tcp-connect-error-after-write.c
diff --git a/test/test-tcp-connect-error.c b/third-party/libuv/test/test-tcp-connect-error.c
index eab1eeb254..eab1eeb254 100644
--- a/test/test-tcp-connect-error.c
+++ b/third-party/libuv/test/test-tcp-connect-error.c
diff --git a/test/test-tcp-connect-timeout.c b/third-party/libuv/test/test-tcp-connect-timeout.c
index cc583cafb2..cc583cafb2 100644
--- a/test/test-tcp-connect-timeout.c
+++ b/third-party/libuv/test/test-tcp-connect-timeout.c
diff --git a/test/test-tcp-connect6-error.c b/third-party/libuv/test/test-tcp-connect6-error.c
index 91ac0a3a10..91ac0a3a10 100644
--- a/test/test-tcp-connect6-error.c
+++ b/third-party/libuv/test/test-tcp-connect6-error.c
diff --git a/test/test-tcp-flags.c b/third-party/libuv/test/test-tcp-flags.c
index 68afb39f45..68afb39f45 100644
--- a/test/test-tcp-flags.c
+++ b/third-party/libuv/test/test-tcp-flags.c
diff --git a/test/test-tcp-open.c b/third-party/libuv/test/test-tcp-open.c
index edeacc70e4..edeacc70e4 100644
--- a/test/test-tcp-open.c
+++ b/third-party/libuv/test/test-tcp-open.c
diff --git a/test/test-tcp-read-stop.c b/third-party/libuv/test/test-tcp-read-stop.c
index c8d9c0407e..c8d9c0407e 100644
--- a/test/test-tcp-read-stop.c
+++ b/third-party/libuv/test/test-tcp-read-stop.c
diff --git a/test/test-tcp-shutdown-after-write.c b/third-party/libuv/test/test-tcp-shutdown-after-write.c
index c59acc4020..c59acc4020 100644
--- a/test/test-tcp-shutdown-after-write.c
+++ b/third-party/libuv/test/test-tcp-shutdown-after-write.c
diff --git a/test/test-tcp-try-write.c b/third-party/libuv/test/test-tcp-try-write.c
index 00341e4169..00341e4169 100644
--- a/test/test-tcp-try-write.c
+++ b/third-party/libuv/test/test-tcp-try-write.c
diff --git a/test/test-tcp-unexpected-read.c b/third-party/libuv/test/test-tcp-unexpected-read.c
index 11fee8ba8e..11fee8ba8e 100644
--- a/test/test-tcp-unexpected-read.c
+++ b/third-party/libuv/test/test-tcp-unexpected-read.c
diff --git a/test/test-tcp-write-to-half-open-connection.c b/third-party/libuv/test/test-tcp-write-to-half-open-connection.c
index 2fa2ae7225..2fa2ae7225 100644
--- a/test/test-tcp-write-to-half-open-connection.c
+++ b/third-party/libuv/test/test-tcp-write-to-half-open-connection.c
diff --git a/test/test-tcp-writealot.c b/third-party/libuv/test/test-tcp-writealot.c
index 6cfe2ebb18..6cfe2ebb18 100644
--- a/test/test-tcp-writealot.c
+++ b/third-party/libuv/test/test-tcp-writealot.c
diff --git a/test/test-thread.c b/third-party/libuv/test/test-thread.c
index c396baa100..c396baa100 100644
--- a/test/test-thread.c
+++ b/third-party/libuv/test/test-thread.c
diff --git a/test/test-threadpool-cancel.c b/third-party/libuv/test/test-threadpool-cancel.c
index 1443773cc2..1443773cc2 100644
--- a/test/test-threadpool-cancel.c
+++ b/third-party/libuv/test/test-threadpool-cancel.c
diff --git a/test/test-threadpool.c b/third-party/libuv/test/test-threadpool.c
index e3d17d7546..e3d17d7546 100644
--- a/test/test-threadpool.c
+++ b/third-party/libuv/test/test-threadpool.c
diff --git a/test/test-timer-again.c b/third-party/libuv/test/test-timer-again.c
index 1638da2dfc..1638da2dfc 100644
--- a/test/test-timer-again.c
+++ b/third-party/libuv/test/test-timer-again.c
diff --git a/test/test-timer-from-check.c b/third-party/libuv/test/test-timer-from-check.c
index 2aa3fe4119..2aa3fe4119 100644
--- a/test/test-timer-from-check.c
+++ b/third-party/libuv/test/test-timer-from-check.c
diff --git a/test/test-timer.c b/third-party/libuv/test/test-timer.c
index bbe69f68be..bbe69f68be 100644
--- a/test/test-timer.c
+++ b/third-party/libuv/test/test-timer.c
diff --git a/test/test-tty.c b/third-party/libuv/test/test-tty.c
index fb69910732..fb69910732 100644
--- a/test/test-tty.c
+++ b/third-party/libuv/test/test-tty.c
diff --git a/test/test-udp-dgram-too-big.c b/third-party/libuv/test/test-udp-dgram-too-big.c
index bd44c42528..bd44c42528 100644
--- a/test/test-udp-dgram-too-big.c
+++ b/third-party/libuv/test/test-udp-dgram-too-big.c
diff --git a/test/test-udp-ipv6.c b/third-party/libuv/test/test-udp-ipv6.c
index 32cabf097c..32cabf097c 100644
--- a/test/test-udp-ipv6.c
+++ b/third-party/libuv/test/test-udp-ipv6.c
diff --git a/test/test-udp-multicast-join.c b/third-party/libuv/test/test-udp-multicast-join.c
index 686edf3d22..686edf3d22 100644
--- a/test/test-udp-multicast-join.c
+++ b/third-party/libuv/test/test-udp-multicast-join.c
diff --git a/test/test-udp-multicast-ttl.c b/third-party/libuv/test/test-udp-multicast-ttl.c
index bed0ea1342..bed0ea1342 100644
--- a/test/test-udp-multicast-ttl.c
+++ b/third-party/libuv/test/test-udp-multicast-ttl.c
diff --git a/test/test-udp-open.c b/third-party/libuv/test/test-udp-open.c
index 9a97303f12..9a97303f12 100644
--- a/test/test-udp-open.c
+++ b/third-party/libuv/test/test-udp-open.c
diff --git a/test/test-udp-options.c b/third-party/libuv/test/test-udp-options.c
index 5cc369878a..5cc369878a 100644
--- a/test/test-udp-options.c
+++ b/third-party/libuv/test/test-udp-options.c
diff --git a/test/test-udp-send-and-recv.c b/third-party/libuv/test/test-udp-send-and-recv.c
index 3020ded7bf..3020ded7bf 100644
--- a/test/test-udp-send-and-recv.c
+++ b/third-party/libuv/test/test-udp-send-and-recv.c
diff --git a/test/test-walk-handles.c b/third-party/libuv/test/test-walk-handles.c
index f2ae41564f..f2ae41564f 100644
--- a/test/test-walk-handles.c
+++ b/third-party/libuv/test/test-walk-handles.c
diff --git a/test/test-watcher-cross-stop.c b/third-party/libuv/test/test-watcher-cross-stop.c
index c701dd2f91..c701dd2f91 100644
--- a/test/test-watcher-cross-stop.c
+++ b/third-party/libuv/test/test-watcher-cross-stop.c
diff --git a/uv.gyp b/third-party/libuv/uv.gyp
index 50e19357de..50e19357de 100644
--- a/uv.gyp
+++ b/third-party/libuv/uv.gyp
diff --git a/vcbuild.bat b/third-party/libuv/vcbuild.bat
index 8545b2635b..8545b2635b 100644
--- a/vcbuild.bat
+++ b/third-party/libuv/vcbuild.bat
diff --git a/vim-license.txt b/vim-license.txt
new file mode 100644
index 0000000000..dd685292ba
--- /dev/null
+++ b/vim-license.txt
@@ -0,0 +1,78 @@
+VIM LICENSE
+
+I) There are no restrictions on distributing unmodified copies of Vim except
+ that they must include this license text. You can also distribute
+ unmodified parts of Vim, likewise unrestricted except that they must
+ include this license text. You are also allowed to include executables
+ that you made from the unmodified Vim sources, plus your own usage
+ examples and Vim scripts.
+
+II) It is allowed to distribute a modified (or extended) version of Vim,
+ including executables and/or source code, when the following four
+ conditions are met:
+ 1) This license text must be included unmodified.
+ 2) The modified Vim must be distributed in one of the following five ways:
+ a) If you make changes to Vim yourself, you must clearly describe in
+ the distribution how to contact you. When the maintainer asks you
+ (in any way) for a copy of the modified Vim you distributed, you
+ must make your changes, including source code, available to the
+ maintainer without fee. The maintainer reserves the right to
+ include your changes in the official version of Vim. What the
+ maintainer will do with your changes and under what license they
+ will be distributed is negotiable. If there has been no negotiation
+ then this license, or a later version, also applies to your changes.
+ The current maintainer is Bram Moolenaar <Bram@vim.org>. If this
+ changes it will be announced in appropriate places (most likely
+ vim.sf.net, www.vim.org and/or comp.editors). When it is completely
+ impossible to contact the maintainer, the obligation to send him
+ your changes ceases. Once the maintainer has confirmed that he has
+ received your changes they will not have to be sent again.
+ b) If you have received a modified Vim that was distributed as
+ mentioned under a) you are allowed to further distribute it
+ unmodified, as mentioned at I). If you make additional changes the
+ text under a) applies to those changes.
+ c) Provide all the changes, including source code, with every copy of
+ the modified Vim you distribute. This may be done in the form of a
+ context diff. You can choose what license to use for new code you
+ add. The changes and their license must not restrict others from
+ making their own changes to the official version of Vim.
+ d) When you have a modified Vim which includes changes as mentioned
+ under c), you can distribute it without the source code for the
+ changes if the following three conditions are met:
+ - The license that applies to the changes permits you to distribute
+ the changes to the Vim maintainer without fee or restriction, and
+ permits the Vim maintainer to include the changes in the official
+ version of Vim without fee or restriction.
+ - You keep the changes for at least three years after last
+ distributing the corresponding modified Vim. When the maintainer
+ or someone who you distributed the modified Vim to asks you (in
+ any way) for the changes within this period, you must make them
+ available to him.
+ - You clearly describe in the distribution how to contact you. This
+ contact information must remain valid for at least three years
+ after last distributing the corresponding modified Vim, or as long
+ as possible.
+ e) When the GNU General Public License (GPL) applies to the changes,
+ you can distribute the modified Vim under the GNU GPL version 2 or
+ any later version.
+ 3) A message must be added, at least in the output of the ":version"
+ command and in the intro screen, such that the user of the modified Vim
+ is able to see that it was modified. When distributing as mentioned
+ under 2)e) adding the message is only required for as far as this does
+ not conflict with the license used for the changes.
+ 4) The contact information as required under 2)a) and 2)d) must not be
+ removed or changed, except that the person himself can make
+ corrections.
+
+III) If you distribute a modified version of Vim, you are encouraged to use
+ the Vim license for your changes and make them available to the
+ maintainer, including the source code. The preferred way to do this is
+ by e-mail or by uploading the files to a server and e-mailing the URL.
+ If the number of changes is small (e.g., a modified Makefile) e-mailing a
+ context diff will do. The e-mail address to be used is
+ <maintainer@vim.org>
+
+IV) It is not allowed to remove this license from the distribution of the Vim
+ sources, parts of it or from a modified version. You may use this
+ license for previous Vim releases instead of the license that they came
+ with, at your option.